summaryrefslogtreecommitdiff
path: root/chromium/components
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-17 13:57:45 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-19 13:44:40 +0000
commit6ec7b8da05d21a3878bd21c691b41e675d74bb1c (patch)
treeb87f250bc19413750b9bb9cdbf2da20ef5014820 /chromium/components
parentec02ee4181c49b61fce1c8fb99292dbb8139cc90 (diff)
downloadqtwebengine-chromium-6ec7b8da05d21a3878bd21c691b41e675d74bb1c.tar.gz
BASELINE: Update Chromium to 60.0.3112.70
Change-Id: I9911c2280a014d4632f254857876a395d4baed2d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components')
-rw-r--r--chromium/components/BUILD.gn23
-rw-r--r--chromium/components/about_ui/OWNERS2
-rw-r--r--chromium/components/about_ui/PRESUBMIT.py25
-rw-r--r--chromium/components/about_ui/resources/about_credits.js18
-rw-r--r--chromium/components/about_ui/resources/about_credits.tmpl4
-rw-r--r--chromium/components/arc/BUILD.gn14
-rw-r--r--chromium/components/arc/DEPS12
-rw-r--r--chromium/components/arc/arc_bridge_host_impl.cc6
-rw-r--r--chromium/components/arc/arc_bridge_host_impl.h2
-rw-r--r--chromium/components/arc/arc_bridge_service.h7
-rw-r--r--chromium/components/arc/arc_session.cc67
-rw-r--r--chromium/components/arc/arc_session_runner_unittest.cc7
-rw-r--r--chromium/components/arc/arc_util.cc78
-rw-r--r--chromium/components/arc/arc_util.h26
-rw-r--r--chromium/components/arc/arc_util_unittest.cc118
-rw-r--r--chromium/components/arc/bitmap/bitmap_struct_traits.cc4
-rw-r--r--chromium/components/arc/bluetooth/arc_bluetooth_bridge.cc4
-rw-r--r--chromium/components/arc/common/accessibility_helper.mojom32
-rw-r--r--chromium/components/arc/common/app.mojom17
-rw-r--r--chromium/components/arc/common/arc_bridge.mojom9
-rw-r--r--chromium/components/arc/common/ime.mojom28
-rw-r--r--chromium/components/arc/common/ime.typemap20
-rw-r--r--chromium/components/arc/common/metrics.mojom21
-rw-r--r--chromium/components/arc/common/tracing.mojom9
-rw-r--r--chromium/components/arc/common/typemaps.gni1
-rw-r--r--chromium/components/arc/common/voice_interaction_arc_home.mojom69
-rw-r--r--chromium/components/arc/common/voice_interaction_framework.mojom24
-rw-r--r--chromium/components/arc/ime/OWNERS2
-rw-r--r--chromium/components/arc/ime/arc_ime_bridge.h6
-rw-r--r--chromium/components/arc/ime/arc_ime_bridge_impl.cc15
-rw-r--r--chromium/components/arc/ime/arc_ime_bridge_impl.h7
-rw-r--r--chromium/components/arc/ime/arc_ime_service.cc73
-rw-r--r--chromium/components/arc/ime/arc_ime_service.h18
-rw-r--r--chromium/components/arc/ime/arc_ime_service_unittest.cc25
-rw-r--r--chromium/components/arc/ime/arc_ime_struct_traits.cc27
-rw-r--r--chromium/components/arc/ime/arc_ime_struct_traits.h33
-rw-r--r--chromium/components/arc/metrics/arc_metrics_service.cc67
-rw-r--r--chromium/components/arc/metrics/arc_metrics_service.h4
-rw-r--r--chromium/components/autofill/android/java/res/values/colors.xml4
-rw-r--r--chromium/components/autofill/android/java/res/values/dimens.xml1
-rw-r--r--chromium/components/autofill/content/DEPS3
-rw-r--r--chromium/components/autofill/content/browser/DEPS1
-rw-r--r--chromium/components/autofill/content/browser/content_autofill_driver.cc6
-rw-r--r--chromium/components/autofill/content/browser/content_autofill_driver.h1
-rw-r--r--chromium/components/autofill/content/browser/content_autofill_driver_factory.cc3
-rw-r--r--chromium/components/autofill/content/browser/content_autofill_driver_factory.h7
-rw-r--r--chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc3
-rw-r--r--chromium/components/autofill/content/browser/payments/payments_client_unittest.cc20
-rw-r--r--chromium/components/autofill/content/common/BUILD.gn1
-rw-r--r--chromium/components/autofill/content/common/autofill_driver.mojom6
-rw-r--r--chromium/components/autofill/content/common/autofill_types.mojom16
-rw-r--r--chromium/components/autofill/content/common/autofill_types.typemap1
-rw-r--r--chromium/components/autofill/content/common/autofill_types_struct_traits.cc101
-rw-r--r--chromium/components/autofill/content/common/autofill_types_struct_traits.h15
-rw-r--r--chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc39
-rw-r--r--chromium/components/autofill/content/renderer/BUILD.gn1
-rw-r--r--chromium/components/autofill/content/renderer/DEPS3
-rw-r--r--chromium/components/autofill/content/renderer/autofill_agent.cc6
-rw-r--r--chromium/components/autofill/content/renderer/autofill_agent.h4
-rw-r--r--chromium/components/autofill/content/renderer/password_autofill_agent.cc306
-rw-r--r--chromium/components/autofill/content/renderer/password_autofill_agent.h37
-rw-r--r--chromium/components/autofill/content/renderer/password_form_conversion_utils.cc16
-rw-r--r--chromium/components/autofill/content/renderer/password_form_conversion_utils.h4
-rw-r--r--chromium/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc2
-rw-r--r--chromium/components/autofill/content/renderer/password_generation_agent.cc4
-rw-r--r--chromium/components/autofill/content/renderer/password_generation_agent.h4
-rw-r--r--chromium/components/autofill/content/renderer/provisionally_saved_password_form.cc8
-rw-r--r--chromium/components/autofill/content/renderer/provisionally_saved_password_form.h8
-rw-r--r--chromium/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc8
-rw-r--r--chromium/components/autofill/core/browser/BUILD.gn19
-rw-r--r--chromium/components/autofill/core/browser/address.cc8
-rw-r--r--chromium/components/autofill/core/browser/address_combobox_model.cc141
-rw-r--r--chromium/components/autofill/core/browser/address_combobox_model.h82
-rw-r--r--chromium/components/autofill/core/browser/address_combobox_model_unittest.cc93
-rw-r--r--chromium/components/autofill/core/browser/address_field.cc2
-rw-r--r--chromium/components/autofill/core/browser/autofill_address_util.cc25
-rw-r--r--chromium/components/autofill/core/browser/autofill_address_util.h7
-rw-r--r--chromium/components/autofill/core/browser/autofill_assistant_unittest.cc7
-rw-r--r--chromium/components/autofill/core/browser/autofill_client.h4
-rw-r--r--chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc4
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_util.cc79
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_util.h32
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_util_unittest.cc41
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_driver.h8
-rw-r--r--chromium/components/autofill/core/browser/autofill_experiments.cc29
-rw-r--r--chromium/components/autofill/core/browser/autofill_experiments.h19
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate.cc19
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/autofill_field.cc4
-rw-r--r--chromium/components/autofill/core/browser/autofill_field_unittest.cc13
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.cc374
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.h57
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager_unittest.cc1896
-rw-r--r--chromium/components/autofill/core/browser/autofill_merge_unittest.cc6
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.cc479
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.h284
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics_unittest.cc1659
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.cc8
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.h19
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_comparator.cc86
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_comparator.h28
-rw-r--r--chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc24
-rw-r--r--chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h8
-rw-r--r--chromium/components/autofill/core/browser/autofill_sync_constants.cc19
-rw-r--r--chromium/components/autofill/core/browser/autofill_sync_constants.h19
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.cc25
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.h8
-rw-r--r--chromium/components/autofill/core/browser/autofill_type.cc4
-rw-r--r--chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h1
-rw-r--r--chromium/components/autofill/core/browser/credit_card.cc399
-rw-r--r--chromium/components/autofill/core/browser/credit_card.h119
-rw-r--r--chromium/components/autofill/core/browser/credit_card_field.cc48
-rw-r--r--chromium/components/autofill/core/browser/credit_card_field_unittest.cc116
-rw-r--r--chromium/components/autofill/core/browser/credit_card_unittest.cc500
-rw-r--r--chromium/components/autofill/core/browser/data_driven_test.cc5
-rw-r--r--chromium/components/autofill/core/browser/email_field.cc2
-rw-r--r--chromium/components/autofill/core/browser/field_types.h7
-rw-r--r--chromium/components/autofill/core/browser/form_structure.cc183
-rw-r--r--chromium/components/autofill/core/browser/form_structure.h6
-rw-r--r--chromium/components/autofill/core/browser/name_field.cc2
-rw-r--r--chromium/components/autofill/core/browser/payments/full_card_request_unittest.cc24
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.cc38
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.h15
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.cc94
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.h37
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager_unittest.cc1714
-rw-r--r--chromium/components/autofill/core/browser/phone_field.cc2
-rw-r--r--chromium/components/autofill/core/browser/popup_item_ids.h1
-rw-r--r--chromium/components/autofill/core/browser/region_combobox_model.cc82
-rw-r--r--chromium/components/autofill/core/browser/region_combobox_model.h62
-rw-r--r--chromium/components/autofill/core/browser/region_combobox_model_unittest.cc107
-rw-r--r--chromium/components/autofill/core/browser/region_data_loader.h44
-rw-r--r--chromium/components/autofill/core/browser/region_data_loader_impl.cc72
-rw-r--r--chromium/components/autofill/core/browser/region_data_loader_impl.h68
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.cc4
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.h9
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_driver.cc11
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_driver.h9
-rw-r--r--chromium/components/autofill/core/browser/test_region_data_loader.cc55
-rw-r--r--chromium/components/autofill/core/browser/test_region_data_loader.h57
-rw-r--r--chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc12
-rw-r--r--chromium/components/autofill/core/browser/validation.cc89
-rw-r--r--chromium/components/autofill/core/browser/validation.h32
-rw-r--r--chromium/components/autofill/core/browser/validation_unittest.cc7
-rw-r--r--chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc23
-rw-r--r--chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc78
-rw-r--r--chromium/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc4
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_data_type_controller.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.cc75
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.h55
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc4
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table.cc509
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table.h53
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc30
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc4
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc13
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h4
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata.h3
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc17
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h4
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc7
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/web_data_service_unittest.cc9
-rw-r--r--chromium/components/autofill/core/common/BUILD.gn4
-rw-r--r--chromium/components/autofill/core/common/autofill_pref_names.cc11
-rw-r--r--chromium/components/autofill/core/common/autofill_pref_names.h10
-rw-r--r--chromium/components/autofill/core/common/autofill_regex_constants.cc (renamed from chromium/components/autofill/core/browser/autofill_regex_constants.cc)268
-rw-r--r--chromium/components/autofill/core/common/autofill_regex_constants.h (renamed from chromium/components/autofill/core/browser/autofill_regex_constants.h)0
-rw-r--r--chromium/components/autofill/core/common/autofill_regexes.cc5
-rw-r--r--chromium/components/autofill/core/common/autofill_regexes_unittest.cc2
-rw-r--r--chromium/components/autofill/core/common/autofill_switches.cc10
-rw-r--r--chromium/components/autofill/core/common/autofill_switches.h5
-rw-r--r--chromium/components/autofill/core/common/autofill_util.cc51
-rw-r--r--chromium/components/autofill/core/common/autofill_util.h20
-rw-r--r--chromium/components/autofill/core/common/password_form.cc50
-rw-r--r--chromium/components/autofill/core/common/password_form.h26
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger.cc2
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger.h1
-rw-r--r--chromium/components/autofill/ios/browser/BUILD.gn1
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios.h6
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios.mm14
-rw-r--r--chromium/components/autofill/ios/browser/credit_card_util.mm9
-rw-r--r--chromium/components/autofill/ios/browser/form_suggestion.mm37
-rw-r--r--chromium/components/autofill/ios/browser/js_autofill_manager.mm4
-rw-r--r--chromium/components/autofill/ios/browser/js_suggestion_manager.mm6
-rw-r--r--chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.h2
-rw-r--r--chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.mm4
-rw-r--r--chromium/components/autofill_strings.grdp35
-rw-r--r--chromium/components/background_task_scheduler/BUILD.gn25
-rw-r--r--chromium/components/bookmarks/browser/BUILD.gn1
-rw-r--r--chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc14
-rw-r--r--chromium/components/bookmarks/browser/bookmark_model_unittest.cc2
-rw-r--r--chromium/components/bookmarks/browser/bookmark_node_data_unittest.cc8
-rw-r--r--chromium/components/bookmarks/browser/bookmark_utils_unittest.cc17
-rw-r--r--chromium/components/browser_sync/profile_sync_components_factory_impl.cc13
-rw-r--r--chromium/components/browser_sync/profile_sync_service.cc105
-rw-r--r--chromium/components/browser_sync/profile_sync_service.h7
-rw-r--r--chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc25
-rw-r--r--chromium/components/browser_sync/profile_sync_service_startup_unittest.cc1
-rw-r--r--chromium/components/browser_sync/profile_sync_service_typed_url_unittest.cc87
-rw-r--r--chromium/components/browser_sync/profile_sync_service_unittest.cc29
-rw-r--r--chromium/components/browser_sync/profile_sync_test_util.cc1
-rw-r--r--chromium/components/browser_sync/test_profile_sync_service.cc2
-rw-r--r--chromium/components/browser_watcher/BUILD.gn91
-rw-r--r--chromium/components/browser_watcher/dump_stability_report_main_win.cc (renamed from chromium/components/browser_watcher/dump_postmortem_minidump_main_win.cc)41
-rw-r--r--chromium/components/browser_watcher/minidump_user_streams.h18
-rw-r--r--chromium/components/browser_watcher/postmortem_minidump_writer_win.cc8
-rw-r--r--chromium/components/browser_watcher/postmortem_report_collector.cc63
-rw-r--r--chromium/components/browser_watcher/postmortem_report_collector.h12
-rw-r--r--chromium/components/browser_watcher/postmortem_report_collector_unittest.cc71
-rw-r--r--chromium/components/browser_watcher/stability_data_names.cc2
-rw-r--r--chromium/components/browser_watcher/stability_data_names.h2
-rw-r--r--chromium/components/browser_watcher/stability_debugging.cc86
-rw-r--r--chromium/components/browser_watcher/stability_debugging.h23
-rw-r--r--chromium/components/browser_watcher/stability_debugging_win_unittest.cc8
-rw-r--r--chromium/components/browser_watcher/stability_paths.cc98
-rw-r--r--chromium/components/browser_watcher/stability_paths.h45
-rw-r--r--chromium/components/browser_watcher/stability_report.proto6
-rw-r--r--chromium/components/browser_watcher/stability_report_extractor.cc (renamed from chromium/components/browser_watcher/postmortem_report_extractor.cc)4
-rw-r--r--chromium/components/browser_watcher/stability_report_extractor.h (renamed from chromium/components/browser_watcher/postmortem_report_extractor.h)6
-rw-r--r--chromium/components/browser_watcher/stability_report_user_stream_data_source.cc125
-rw-r--r--chromium/components/browser_watcher/stability_report_user_stream_data_source.h40
-rw-r--r--chromium/components/browser_watcher/watcher_metrics_provider_win.cc2
-rw-r--r--chromium/components/browser_watcher/window_hang_monitor_win_unittest.cc1
-rw-r--r--chromium/components/browsing_data/content/conditional_cache_counting_helper.cc2
-rw-r--r--chromium/components/browsing_data/content/conditional_cache_counting_helper.h6
-rw-r--r--chromium/components/browsing_data/core/BUILD.gn5
-rw-r--r--chromium/components/browsing_data/core/DEPS1
-rw-r--r--chromium/components/browsing_data/core/browsing_data_utils.cc80
-rw-r--r--chromium/components/browsing_data/core/browsing_data_utils.h5
-rw-r--r--chromium/components/browsing_data/core/browsing_data_utils_unittest.cc60
-rw-r--r--chromium/components/browsing_data/core/counters/autofill_counter.cc42
-rw-r--r--chromium/components/browsing_data/core/counters/autofill_counter.h17
-rw-r--r--chromium/components/browsing_data/core/counters/browsing_data_counter.cc13
-rw-r--r--chromium/components/browsing_data/core/counters/browsing_data_counter.h20
-rw-r--r--chromium/components/browsing_data/core/counters/history_counter.cc23
-rw-r--r--chromium/components/browsing_data/core/counters/history_counter.h3
-rw-r--r--chromium/components/browsing_data/core/counters/passwords_counter.cc40
-rw-r--r--chromium/components/browsing_data/core/counters/passwords_counter.h12
-rw-r--r--chromium/components/browsing_data/core/counters/site_settings_counter.cc50
-rw-r--r--chromium/components/browsing_data/core/counters/site_settings_counter.h30
-rw-r--r--chromium/components/browsing_data/core/pref_names.cc8
-rw-r--r--chromium/components/browsing_data/core/pref_names.h1
-rw-r--r--chromium/components/browsing_data_strings.grdp48
-rw-r--r--chromium/components/captive_portal/captive_portal_detector.cc6
-rw-r--r--chromium/components/captive_portal/captive_portal_detector.h6
-rw-r--r--chromium/components/captive_portal/captive_portal_detector_unittest.cc13
-rw-r--r--chromium/components/cast_certificate/cast_cert_validator.cc4
-rw-r--r--chromium/components/cast_certificate/cast_cert_validator_test_helpers.cc4
-rw-r--r--chromium/components/cast_certificate/cast_cert_validator_unittest.cc12
-rw-r--r--chromium/components/cast_certificate/cast_crl.cc22
-rw-r--r--chromium/components/cdm/browser/cdm_message_filter_android.cc12
-rw-r--r--chromium/components/cdm/browser/media_drm_storage_impl.cc16
-rw-r--r--chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc2
-rw-r--r--chromium/components/certificate_reporting/error_report.cc5
-rw-r--r--chromium/components/certificate_reporting/error_report_unittest.cc26
-rw-r--r--chromium/components/certificate_reporting/error_reporter.cc46
-rw-r--r--chromium/components/certificate_reporting/error_reporter.h16
-rw-r--r--chromium/components/certificate_reporting/error_reporter_unittest.cc43
-rw-r--r--chromium/components/certificate_transparency/BUILD.gn3
-rw-r--r--chromium/components/certificate_transparency/ct_policy_manager_unittest.cc1
-rw-r--r--chromium/components/certificate_transparency/log_proof_fetcher.cc441
-rw-r--r--chromium/components/certificate_transparency/log_proof_fetcher.h129
-rw-r--r--chromium/components/certificate_transparency/log_proof_fetcher_unittest.cc441
-rw-r--r--chromium/components/certificate_transparency/single_tree_tracker.cc5
-rw-r--r--chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp42
-rw-r--r--chromium/components/chrome_apps/webstore_widget/cws_widget/compiled_resources.gypi19
-rw-r--r--chromium/components/chrome_cleaner/OWNERS1
-rw-r--r--chromium/components/chrome_cleaner/public/constants/BUILD.gn10
-rw-r--r--chromium/components/chrome_cleaner/public/constants/constants.cc46
-rw-r--r--chromium/components/chrome_cleaner/public/constants/constants.h133
-rw-r--r--chromium/components/chrome_cleaner/public/interfaces/BUILD.gn3
-rw-r--r--chromium/components/chrome_cleaner/public/interfaces/OWNERS1
-rw-r--r--chromium/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom4
-rw-r--r--chromium/components/component_updater/component_updater_service_unittest.cc26
-rw-r--r--chromium/components/component_updater/default_component_installer_unittest.cc28
-rw-r--r--chromium/components/component_updater/timer_unittest.cc8
-rw-r--r--chromium/components/components_chromium_strings.grd11
-rw-r--r--chromium/components/components_google_chrome_strings.grd11
-rw-r--r--chromium/components/components_strings.grd8
-rw-r--r--chromium/components/constrained_window/constrained_window_views_unittest.cc14
-rw-r--r--chromium/components/content_settings/core/browser/BUILD.gn1
-rw-r--r--chromium/components/content_settings/core/browser/DEPS1
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_default_provider.cc12
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_info.cc23
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_info.h1
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc34
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h29
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_policy_provider.cc24
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref.cc177
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref.h24
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref_provider.cc45
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref_provider.h19
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_registry.cc7
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc19
-rw-r--r--chromium/components/content_settings/core/browser/cookie_settings_unittest.cc3
-rw-r--r--chromium/components/content_settings/core/browser/host_content_settings_map.cc84
-rw-r--r--chromium/components/content_settings/core/browser/host_content_settings_map.h37
-rw-r--r--chromium/components/content_settings/core/browser/website_settings_registry.cc8
-rw-r--r--chromium/components/content_settings/core/common/content_settings.cc85
-rw-r--r--chromium/components/content_settings/core/common/content_settings_types.h4
-rw-r--r--chromium/components/contextual_search/OWNERS3
-rw-r--r--chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.cc3
-rw-r--r--chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.h7
-rw-r--r--chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.cc5
-rw-r--r--chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.h4
-rw-r--r--chromium/components/crash/android/BUILD.gn32
-rw-r--r--chromium/components/crash/android/DEPS (renamed from chromium/components/memory_pressure/DEPS)3
-rw-r--r--chromium/components/crash/android/OWNERS8
-rw-r--r--chromium/components/crash/content/app/BUILD.gn2
-rw-r--r--chromium/components/crash/content/app/DEPS1
-rw-r--r--chromium/components/crash/content/app/crashpad.cc10
-rw-r--r--chromium/components/crash/content/app/crashpad.h13
-rw-r--r--chromium/components/crash/content/app/crashpad_mac.mm8
-rw-r--r--chromium/components/crash/content/app/crashpad_win.cc12
-rw-r--r--chromium/components/crash/content/app/run_as_crashpad_handler_win.cc30
-rw-r--r--chromium/components/crash/content/app/run_as_crashpad_handler_win.h20
-rw-r--r--chromium/components/crash/content/browser/BUILD.gn4
-rw-r--r--chromium/components/crash/content/browser/DEPS1
-rw-r--r--chromium/components/crash/content/browser/crash_dump_manager_android.cc14
-rw-r--r--chromium/components/crash_strings.grdp4
-rw-r--r--chromium/components/cronet/android/BUILD.gn37
-rw-r--r--chromium/components/cronet/ios/BUILD.gn6
-rw-r--r--chromium/components/cronet/ios/cronet_consumer/BUILD.gn30
-rw-r--r--chromium/components/crx_file/BUILD.gn35
-rw-r--r--chromium/components/crx_file/OWNERS4
-rw-r--r--chromium/components/crx_file/crx2_file.cc79
-rw-r--r--chromium/components/crx_file/crx2_file.h76
-rw-r--r--chromium/components/crx_file/crx3.proto55
-rw-r--r--chromium/components/crx_file/crx_file.cc220
-rw-r--r--chromium/components/crx_file/crx_file.h118
-rw-r--r--chromium/components/crx_file/crx_verifier.cc308
-rw-r--r--chromium/components/crx_file/crx_verifier.h53
-rw-r--r--chromium/components/crx_file/crx_verifier_unittest.cc196
-rw-r--r--chromium/components/cryptauth/BUILD.gn22
-rw-r--r--chromium/components/cryptauth/background_eid_generator.cc96
-rw-r--r--chromium/components/cryptauth/background_eid_generator.h60
-rw-r--r--chromium/components/cryptauth/background_eid_generator_unittest.cc192
-rw-r--r--chromium/components/cryptauth/ble/BUILD.gn1
-rw-r--r--chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc48
-rw-r--r--chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h11
-rw-r--r--chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc77
-rw-r--r--chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.cc6
-rw-r--r--chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.h4
-rw-r--r--chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.cc6
-rw-r--r--chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.h4
-rw-r--r--chromium/components/cryptauth/bluetooth_throttler_impl.cc2
-rw-r--r--chromium/components/cryptauth/data_with_timestamp.cc63
-rw-r--r--chromium/components/cryptauth/data_with_timestamp.h43
-rw-r--r--chromium/components/cryptauth/device_to_device_authenticator.cc12
-rw-r--r--chromium/components/cryptauth/device_to_device_authenticator.h9
-rw-r--r--chromium/components/cryptauth/device_to_device_authenticator_unittest.cc3
-rw-r--r--chromium/components/cryptauth/device_to_device_initiator_operations.cc43
-rw-r--r--chromium/components/cryptauth/device_to_device_initiator_operations.h7
-rw-r--r--chromium/components/cryptauth/device_to_device_operations_unittest.cc51
-rw-r--r--chromium/components/cryptauth/device_to_device_responder_operations.cc19
-rw-r--r--chromium/components/cryptauth/device_to_device_responder_operations.h6
-rw-r--r--chromium/components/cryptauth/device_to_device_secure_context.cc32
-rw-r--r--chromium/components/cryptauth/device_to_device_secure_context.h17
-rw-r--r--chromium/components/cryptauth/device_to_device_secure_context_unittest.cc43
-rw-r--r--chromium/components/cryptauth/foreground_eid_generator.cc (renamed from chromium/components/cryptauth/eid_generator.cc)149
-rw-r--r--chromium/components/cryptauth/foreground_eid_generator.h (renamed from chromium/components/cryptauth/eid_generator.h)132
-rw-r--r--chromium/components/cryptauth/foreground_eid_generator_unittest.cc (renamed from chromium/components/cryptauth/eid_generator_unittest.cc)341
-rw-r--r--chromium/components/cryptauth/mock_foreground_eid_generator.cc (renamed from chromium/components/cryptauth/mock_eid_generator.cc)42
-rw-r--r--chromium/components/cryptauth/mock_foreground_eid_generator.h (renamed from chromium/components/cryptauth/mock_eid_generator.h)33
-rw-r--r--chromium/components/cryptauth/proto/securemessage.proto8
-rw-r--r--chromium/components/cryptauth/raw_eid_generator.h31
-rw-r--r--chromium/components/cryptauth/raw_eid_generator_impl.cc37
-rw-r--r--chromium/components/cryptauth/raw_eid_generator_impl.h33
-rw-r--r--chromium/components/cryptauth/raw_eid_generator_impl_unittest.cc138
-rw-r--r--chromium/components/cryptauth/remote_device.cc54
-rw-r--r--chromium/components/cryptauth/remote_device.h10
-rw-r--r--chromium/components/cryptauth/remote_device_loader.cc20
-rw-r--r--chromium/components/cryptauth/remote_device_loader.h8
-rw-r--r--chromium/components/cryptauth/remote_device_loader_unittest.cc80
-rw-r--r--chromium/components/cryptauth/session_keys.cc56
-rw-r--r--chromium/components/cryptauth/session_keys.h41
-rw-r--r--chromium/components/cryptauth/session_keys_unittest.cc56
-rw-r--r--chromium/components/cryptauth/wire_message.cc58
-rw-r--r--chromium/components/cryptauth/wire_message.h10
-rw-r--r--chromium/components/cryptauth/wire_message_unittest.cc5
-rw-r--r--chromium/components/data_reduction_proxy/DEPS1
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.cc32
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.h5
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc124
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc6
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc6
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/BUILD.gn7
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/DEPS1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc4
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc24
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc16
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc7
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h20
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc12
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc221
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h58
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc35
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc7
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h5
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc531
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc5
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h19
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc7
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc167
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h57
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc36
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h17
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc194
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc28
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc22
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h19
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc7
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc6
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc267
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h11
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc937
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc39
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc2
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc10
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc51
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc11
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h5
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc1
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.cc10
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.h1
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc12
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h10
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc27
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h10
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc23
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc4
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h3
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.cc8
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.h3
-rw-r--r--chromium/components/data_reduction_proxy/core/common/lofi_decider.h14
-rw-r--r--chromium/components/data_use_measurement/core/data_use.cc13
-rw-r--r--chromium/components/data_use_measurement/core/data_use.h36
-rw-r--r--chromium/components/data_use_measurement/core/data_use_ascriber.cc5
-rw-r--r--chromium/components/data_use_measurement/core/data_use_ascriber.h47
-rw-r--r--chromium/components/data_use_measurement/core/data_use_measurement.cc23
-rw-r--r--chromium/components/data_use_measurement/core/data_use_measurement.h4
-rw-r--r--chromium/components/data_use_measurement/core/data_use_measurement_unittest.cc52
-rw-r--r--chromium/components/data_use_measurement/core/data_use_network_delegate.cc1
-rw-r--r--chromium/components/data_use_measurement/core/data_use_network_delegate_unittest.cc5
-rw-r--r--chromium/components/data_use_measurement/core/data_use_recorder.cc4
-rw-r--r--chromium/components/data_use_measurement/core/data_use_recorder.h2
-rw-r--r--chromium/components/data_use_measurement/core/data_use_user_data.cc5
-rw-r--r--chromium/components/data_use_measurement/core/data_use_user_data.h6
-rw-r--r--chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc11
-rw-r--r--chromium/components/discardable_memory/service/discardable_shared_memory_manager.h7
-rw-r--r--chromium/components/display_compositor/display_compositor_export.h33
-rw-r--r--chromium/components/display_compositor/run_all_unittests.cc16
-rw-r--r--chromium/components/dom_distiller/content/browser/distillability_driver.cc5
-rw-r--r--chromium/components/dom_distiller/content/browser/distillability_driver.h4
-rw-r--r--chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc3
-rw-r--r--chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.h4
-rw-r--r--chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc14
-rw-r--r--chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.h6
-rw-r--r--chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc5
-rw-r--r--chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h4
-rw-r--r--chromium/components/dom_distiller/core/android/BUILD.gn4
-rw-r--r--chromium/components/dom_distiller/core/dom_distiller_store_unittest.cc2
-rw-r--r--chromium/components/dom_distiller/core/html/preview.html5
-rw-r--r--chromium/components/dom_distiller/core/task_tracker_unittest.cc1
-rw-r--r--chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc7
-rw-r--r--chromium/components/domain_reliability/google_configs.cc970
-rw-r--r--chromium/components/domain_reliability/quic_error_mapping.cc4
-rw-r--r--chromium/components/domain_reliability/uploader.cc37
-rw-r--r--chromium/components/domain_reliability/uploader_unittest.cc29
-rw-r--r--chromium/components/domain_reliability/util.cc2
-rw-r--r--chromium/components/doodle/BUILD.gn4
-rw-r--r--chromium/components/doodle/DEPS2
-rw-r--r--chromium/components/doodle/doodle_fetcher.h4
-rw-r--r--chromium/components/doodle/doodle_fetcher_impl.cc25
-rw-r--r--chromium/components/doodle/doodle_fetcher_impl.h10
-rw-r--r--chromium/components/doodle/doodle_service.cc101
-rw-r--r--chromium/components/doodle/doodle_service.h33
-rw-r--r--chromium/components/doodle/doodle_service_unittest.cc221
-rw-r--r--chromium/components/download/BUILD.gn26
-rw-r--r--chromium/components/download/OWNERS6
-rw-r--r--chromium/components/download/content/BUILD.gn42
-rw-r--r--chromium/components/download/content/DEPS6
-rw-r--r--chromium/components/download/content/download_driver_impl.cc188
-rw-r--r--chromium/components/download/content/download_driver_impl.h67
-rw-r--r--chromium/components/download/content/download_driver_impl_unittest.cc129
-rw-r--r--chromium/components/download/internal/BUILD.gn65
-rw-r--r--chromium/components/download/internal/DEPS6
-rw-r--r--chromium/components/download/internal/config.cc70
-rw-r--r--chromium/components/download/internal/config.h65
-rw-r--r--chromium/components/download/internal/download_driver.h76
-rw-r--r--chromium/components/download/internal/download_service_impl.cc30
-rw-r--r--chromium/components/download/internal/download_service_impl.h42
-rw-r--r--chromium/components/download/internal/driver_entry.cc21
-rw-r--r--chromium/components/download/internal/driver_entry.h61
-rw-r--r--chromium/components/download/internal/entry.cc13
-rw-r--r--chromium/components/download/internal/entry.h68
-rw-r--r--chromium/components/download/internal/model.h98
-rw-r--r--chromium/components/download/internal/model_impl.cc130
-rw-r--r--chromium/components/download/internal/model_impl.h73
-rw-r--r--chromium/components/download/internal/model_impl_unittest.cc274
-rw-r--r--chromium/components/download/internal/noop_store.cc53
-rw-r--r--chromium/components/download/internal/noop_store.h46
-rw-r--r--chromium/components/download/internal/scheduler/battery_listener.cc58
-rw-r--r--chromium/components/download/internal/scheduler/battery_listener.h59
-rw-r--r--chromium/components/download/internal/scheduler/battery_listener_unittest.cc74
-rw-r--r--chromium/components/download/internal/scheduler/network_listener.cc84
-rw-r--r--chromium/components/download/internal/scheduler/network_listener.h66
-rw-r--r--chromium/components/download/internal/scheduler/network_listener_unittest.cc100
-rw-r--r--chromium/components/download/internal/store.h54
-rw-r--r--chromium/components/download/internal/test/BUILD.gn27
-rw-r--r--chromium/components/download/public/BUILD.gn30
-rw-r--r--chromium/components/download/public/DEPS7
-rw-r--r--chromium/components/download/public/client.h81
-rw-r--r--chromium/components/download/public/clients.h33
-rw-r--r--chromium/components/download/public/download_params.cc24
-rw-r--r--chromium/components/download/public/download_params.h135
-rw-r--r--chromium/components/download/public/download_service.h72
-rw-r--r--chromium/components/download/public/features.cc12
-rw-r--r--chromium/components/download/public/features.h16
-rw-r--r--chromium/components/error_page/common/localized_error.cc1
-rw-r--r--chromium/components/exo/BUILD.gn4
-rw-r--r--chromium/components/exo/buffer.cc8
-rw-r--r--chromium/components/exo/buffer.h5
-rw-r--r--chromium/components/exo/buffer_unittest.cc25
-rw-r--r--chromium/components/exo/compositor_frame_sink.cc71
-rw-r--r--chromium/components/exo/compositor_frame_sink.h52
-rw-r--r--chromium/components/exo/compositor_frame_sink_holder.cc55
-rw-r--r--chromium/components/exo/compositor_frame_sink_holder.h59
-rw-r--r--chromium/components/exo/gaming_seat.cc14
-rw-r--r--chromium/components/exo/gaming_seat.h6
-rw-r--r--chromium/components/exo/gaming_seat_unittest.cc16
-rw-r--r--chromium/components/exo/notification_surface.cc2
-rw-r--r--chromium/components/exo/pointer.cc208
-rw-r--r--chromium/components/exo/pointer.h27
-rw-r--r--chromium/components/exo/pointer_unittest.cc3
-rw-r--r--chromium/components/exo/shell_surface.cc219
-rw-r--r--chromium/components/exo/shell_surface.h11
-rw-r--r--chromium/components/exo/shell_surface_unittest.cc122
-rw-r--r--chromium/components/exo/surface.cc92
-rw-r--r--chromium/components/exo/surface.h33
-rw-r--r--chromium/components/exo/wayland/BUILD.gn1
-rw-r--r--chromium/components/exo/wayland/clients/client_base.cc6
-rw-r--r--chromium/components/exo/wayland/server.cc116
-rw-r--r--chromium/components/exo/wm_helper.cc18
-rw-r--r--chromium/components/exo/wm_helper.h22
-rw-r--r--chromium/components/exo/wm_helper_ash.cc41
-rw-r--r--chromium/components/exo/wm_helper_ash.h14
-rw-r--r--chromium/components/exo/wm_helper_mus.cc24
-rw-r--r--chromium/components/exo/wm_helper_mus.h7
-rw-r--r--chromium/components/favicon/content/content_favicon_driver.cc59
-rw-r--r--chromium/components/favicon/content/content_favicon_driver.h18
-rw-r--r--chromium/components/favicon/core/BUILD.gn3
-rw-r--r--chromium/components/favicon/core/DEPS1
-rw-r--r--chromium/components/favicon/core/favicon_driver_impl.cc18
-rw-r--r--chromium/components/favicon/core/favicon_driver_impl.h5
-rw-r--r--chromium/components/favicon/core/favicon_handler.cc292
-rw-r--r--chromium/components/favicon/core/favicon_handler.h81
-rw-r--r--chromium/components/favicon/core/favicon_handler_unittest.cc1067
-rw-r--r--chromium/components/favicon/core/favicon_service.h40
-rw-r--r--chromium/components/favicon/core/favicon_service_impl.cc22
-rw-r--r--chromium/components/favicon/core/favicon_service_impl.h4
-rw-r--r--chromium/components/favicon/core/features.cc14
-rw-r--r--chromium/components/favicon/core/features.h18
-rw-r--r--chromium/components/favicon/core/large_icon_service.cc67
-rw-r--r--chromium/components/favicon/core/large_icon_service.h11
-rw-r--r--chromium/components/favicon/core/large_icon_service_unittest.cc118
-rw-r--r--chromium/components/favicon/ios/BUILD.gn1
-rw-r--r--chromium/components/favicon/ios/favicon_url_util.cc2
-rw-r--r--chromium/components/favicon/ios/web_favicon_driver.h5
-rw-r--r--chromium/components/favicon/ios/web_favicon_driver.mm19
-rw-r--r--chromium/components/favicon_base/favicon_types.h6
-rw-r--r--chromium/components/favicon_base/favicon_url_parser.cc37
-rw-r--r--chromium/components/favicon_base/favicon_url_parser.h10
-rw-r--r--chromium/components/favicon_base/favicon_url_parser_unittest.cc70
-rw-r--r--chromium/components/favicon_base/select_favicon_frames_unittest.cc2
-rw-r--r--chromium/components/feature_engagement_tracker/BUILD.gn12
-rw-r--r--chromium/components/feature_engagement_tracker/DEPS2
-rw-r--r--chromium/components/feature_engagement_tracker/README.md30
-rw-r--r--chromium/components/feature_engagement_tracker/components_unittests.filter21
-rw-r--r--chromium/components/feature_engagement_tracker/internal/BUILD.gn48
-rw-r--r--chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc27
-rw-r--r--chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h7
-rw-r--r--chromium/components/feature_engagement_tracker/internal/availability_model.h54
-rw-r--r--chromium/components/feature_engagement_tracker/internal/availability_model_impl.cc63
-rw-r--r--chromium/components/feature_engagement_tracker/internal/availability_model_impl.h69
-rw-r--r--chromium/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc138
-rw-r--r--chromium/components/feature_engagement_tracker/internal/availability_store.cc154
-rw-r--r--chromium/components/feature_engagement_tracker/internal/availability_store.h63
-rw-r--r--chromium/components/feature_engagement_tracker/internal/availability_store_unittest.cc288
-rw-r--r--chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc315
-rw-r--r--chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.h46
-rw-r--r--chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc622
-rw-r--r--chromium/components/feature_engagement_tracker/internal/condition_validator.cc40
-rw-r--r--chromium/components/feature_engagement_tracker/internal/condition_validator.h67
-rw-r--r--chromium/components/feature_engagement_tracker/internal/condition_validator_unittest.cc86
-rw-r--r--chromium/components/feature_engagement_tracker/internal/configuration.cc72
-rw-r--r--chromium/components/feature_engagement_tracker/internal/configuration.h88
-rw-r--r--chromium/components/feature_engagement_tracker/internal/configuration_unittest.cc81
-rw-r--r--chromium/components/feature_engagement_tracker/internal/editable_configuration.cc5
-rw-r--r--chromium/components/feature_engagement_tracker/internal/editable_configuration.h3
-rw-r--r--chromium/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc11
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.cc121
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.h56
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc538
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc87
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.h63
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator_unittest.cc294
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_constants.cc17
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc192
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h51
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc487
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_list.cc23
-rw-r--r--chromium/components/feature_engagement_tracker/internal/feature_list.h20
-rw-r--r--chromium/components/feature_engagement_tracker/internal/in_memory_store.cc4
-rw-r--r--chromium/components/feature_engagement_tracker/internal/in_memory_store.h1
-rw-r--r--chromium/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc3
-rw-r--r--chromium/components/feature_engagement_tracker/internal/init_aware_model.cc65
-rw-r--r--chromium/components/feature_engagement_tracker/internal/init_aware_model.h54
-rw-r--r--chromium/components/feature_engagement_tracker/internal/init_aware_model_unittest.cc170
-rw-r--r--chromium/components/feature_engagement_tracker/internal/model.h36
-rw-r--r--chromium/components/feature_engagement_tracker/internal/model_impl.cc80
-rw-r--r--chromium/components/feature_engagement_tracker/internal/model_impl.h34
-rw-r--r--chromium/components/feature_engagement_tracker/internal/model_impl_unittest.cc496
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_availability_model.cc45
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_availability_model.h43
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_availability_model_unittest.cc73
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_condition_validator.cc16
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_condition_validator.h16
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc45
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_storage_validator.cc23
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_storage_validator.h34
-rw-r--r--chromium/components/feature_engagement_tracker/internal/never_storage_validator_unittest.cc36
-rw-r--r--chromium/components/feature_engagement_tracker/internal/once_condition_validator.cc43
-rw-r--r--chromium/components/feature_engagement_tracker/internal/once_condition_validator.h18
-rw-r--r--chromium/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc143
-rw-r--r--chromium/components/feature_engagement_tracker/internal/persistent_store.cc91
-rw-r--r--chromium/components/feature_engagement_tracker/internal/persistent_store.h59
-rw-r--r--chromium/components/feature_engagement_tracker/internal/persistent_store_unittest.cc251
-rw-r--r--chromium/components/feature_engagement_tracker/internal/proto/BUILD.gn1
-rw-r--r--chromium/components/feature_engagement_tracker/internal/proto/availability.proto21
-rw-r--r--chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.cc7
-rw-r--r--chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.h6
-rw-r--r--chromium/components/feature_engagement_tracker/internal/single_invalid_configuration_unittest.cc5
-rw-r--r--chromium/components/feature_engagement_tracker/internal/stats.cc199
-rw-r--r--chromium/components/feature_engagement_tracker/internal/stats.h150
-rw-r--r--chromium/components/feature_engagement_tracker/internal/storage_validator.h40
-rw-r--r--chromium/components/feature_engagement_tracker/internal/store.h6
-rw-r--r--chromium/components/feature_engagement_tracker/internal/system_time_provider.cc24
-rw-r--r--chromium/components/feature_engagement_tracker/internal/system_time_provider.h34
-rw-r--r--chromium/components/feature_engagement_tracker/internal/system_time_provider_unittest.cc112
-rw-r--r--chromium/components/feature_engagement_tracker/internal/test/BUILD.gn19
-rw-r--r--chromium/components/feature_engagement_tracker/internal/time_provider.h31
-rw-r--r--chromium/components/feature_engagement_tracker/public/BUILD.gn4
-rw-r--r--chromium/components/feature_engagement_tracker/public/feature_constants.h16
-rw-r--r--chromium/components/feature_engagement_tracker/public/feature_engagement_tracker.h26
-rw-r--r--chromium/components/feature_engagement_tracker/public/feature_list.cc63
-rw-r--r--chromium/components/feature_engagement_tracker/public/feature_list.h37
-rw-r--r--chromium/components/feedback/BUILD.gn2
-rw-r--r--chromium/components/feedback/anonymizer_tool.cc31
-rw-r--r--chromium/components/feedback/anonymizer_tool_unittest.cc23
-rw-r--r--chromium/components/feedback/feedback_data.cc17
-rw-r--r--chromium/components/feedback/feedback_data_unittest.cc6
-rw-r--r--chromium/components/feedback/feedback_uploader.cc18
-rw-r--r--chromium/components/feedback/feedback_uploader.h6
-rw-r--r--chromium/components/feedback/feedback_uploader_chrome.cc10
-rw-r--r--chromium/components/feedback/feedback_uploader_delegate.h6
-rw-r--r--chromium/components/filesystem/BUILD.gn3
-rw-r--r--chromium/components/filesystem/DEPS1
-rw-r--r--chromium/components/filesystem/directory_impl.cc110
-rw-r--r--chromium/components/filesystem/directory_impl.h27
-rw-r--r--chromium/components/filesystem/file_impl.cc120
-rw-r--r--chromium/components/filesystem/file_impl.h26
-rw-r--r--chromium/components/filesystem/file_system_app.cc22
-rw-r--r--chromium/components/filesystem/file_system_app.h15
-rw-r--r--chromium/components/filesystem/file_system_impl.cc11
-rw-r--r--chromium/components/filesystem/file_system_impl.h4
-rw-r--r--chromium/components/flags_ui/OWNERS2
-rw-r--r--chromium/components/flags_ui/PRESUBMIT.py25
-rw-r--r--chromium/components/flags_ui/resources/flags.css5
-rw-r--r--chromium/components/font_service/BUILD.gn1
-rw-r--r--chromium/components/font_service/DEPS1
-rw-r--r--chromium/components/font_service/font_service_app.cc33
-rw-r--r--chromium/components/font_service/font_service_app.h24
-rw-r--r--chromium/components/gcm_driver/crypto/BUILD.gn3
-rw-r--r--chromium/components/google/core/browser/google_tld_list.h61
-rw-r--r--chromium/components/google/core/browser/google_url_tracker.h6
-rw-r--r--chromium/components/google/core/browser/google_util.cc42
-rw-r--r--chromium/components/google/core/browser/google_util_unittest.cc77
-rw-r--r--chromium/components/grpc_support/bidirectional_stream.cc2
-rw-r--r--chromium/components/grpc_support/bidirectional_stream_c.cc2
-rw-r--r--chromium/components/grpc_support/bidirectional_stream_unittest.cc2
-rw-r--r--chromium/components/guest_view/OWNERS1
-rw-r--r--chromium/components/guest_view/browser/BUILD.gn4
-rw-r--r--chromium/components/guest_view/browser/guest_view_base.cc137
-rw-r--r--chromium/components/guest_view/browser/guest_view_base.h19
-rw-r--r--chromium/components/guest_view/browser/guest_view_manager.cc32
-rw-r--r--chromium/components/guest_view/browser/guest_view_manager.h16
-rw-r--r--chromium/components/guest_view/browser/guest_view_message_filter.cc7
-rw-r--r--chromium/components/guest_view/browser/guest_view_message_filter.h3
-rw-r--r--chromium/components/guest_view/renderer/BUILD.gn4
-rw-r--r--chromium/components/guest_view/renderer/guest_view_container.cc7
-rw-r--r--chromium/components/history/content/browser/content_history_backend_db_unittest.cc2
-rw-r--r--chromium/components/history/content/browser/web_contents_top_sites_observer.cc6
-rw-r--r--chromium/components/history/content/browser/web_contents_top_sites_observer.h3
-rw-r--r--chromium/components/history/core/browser/history_backend.cc92
-rw-r--r--chromium/components/history/core/browser/history_backend.h31
-rw-r--r--chromium/components/history/core/browser/history_backend_unittest.cc201
-rw-r--r--chromium/components/history/core/browser/history_service.cc26
-rw-r--r--chromium/components/history/core/browser/history_service.h45
-rw-r--r--chromium/components/history/core/browser/history_service_unittest.cc8
-rw-r--r--chromium/components/history/core/browser/thumbnail_database.cc17
-rw-r--r--chromium/components/history/core/browser/thumbnail_database.h13
-rw-r--r--chromium/components/history/core/browser/thumbnail_database_unittest.cc91
-rw-r--r--chromium/components/history/core/browser/top_sites.h4
-rw-r--r--chromium/components/history/core/browser/top_sites_cache.h9
-rw-r--r--chromium/components/history/core/browser/top_sites_impl.cc89
-rw-r--r--chromium/components/history/core/browser/top_sites_impl.h29
-rw-r--r--chromium/components/history/core/browser/top_sites_impl_unittest.cc5
-rw-r--r--chromium/components/history/core/browser/typed_url_sync_bridge.cc18
-rw-r--r--chromium/components/history/core/browser/typed_url_sync_bridge.h14
-rw-r--r--chromium/components/history/core/browser/typed_url_sync_metadata_database.cc16
-rw-r--r--chromium/components/history/core/browser/typed_url_sync_metadata_database.h28
-rw-r--r--chromium/components/history/core/browser/typed_url_sync_metadata_database_unittest.cc16
-rw-r--r--chromium/components/history/core/browser/url_database.cc6
-rw-r--r--chromium/components/history/core/browser/url_database.h10
-rw-r--r--chromium/components/history/core/browser/url_database_unittest.cc50
-rw-r--r--chromium/components/history/core/test/BUILD.gn1
-rw-r--r--chromium/components/history/ios/browser/web_state_top_sites_observer.h3
-rw-r--r--chromium/components/history/ios/browser/web_state_top_sites_observer.mm6
-rw-r--r--chromium/components/history_strings.grdp64
-rw-r--r--chromium/components/image_fetcher/core/image_data_fetcher.cc14
-rw-r--r--chromium/components/image_fetcher/core/image_data_fetcher.h17
-rw-r--r--chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc40
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher.h4
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher_impl.cc11
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher_impl.h6
-rw-r--r--chromium/components/image_fetcher/ios/BUILD.gn1
-rw-r--r--chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm10
-rw-r--r--chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm1
-rw-r--r--chromium/components/image_fetcher/ios/ios_image_decoder_impl_unittest.mm1
-rw-r--r--chromium/components/infobars/core/infobar_delegate.h2
-rw-r--r--chromium/components/json_schema/json_schema_validator_unittest_base.cc10
-rw-r--r--chromium/components/leveldb/BUILD.gn3
-rw-r--r--chromium/components/leveldb/DEPS1
-rw-r--r--chromium/components/leveldb/OWNERS1
-rw-r--r--chromium/components/leveldb/env_mojo.cc171
-rw-r--r--chromium/components/leveldb/env_mojo.h12
-rw-r--r--chromium/components/leveldb/leveldb_app.cc13
-rw-r--r--chromium/components/leveldb/leveldb_app.h14
-rw-r--r--chromium/components/leveldb/leveldb_database_impl.cc107
-rw-r--r--chromium/components/leveldb/leveldb_database_impl.h36
-rw-r--r--chromium/components/leveldb/leveldb_mojo_proxy.cc6
-rw-r--r--chromium/components/leveldb/leveldb_service_impl.cc18
-rw-r--r--chromium/components/leveldb/leveldb_service_impl.h9
-rw-r--r--chromium/components/leveldb_proto/proto_database.h34
-rw-r--r--chromium/components/leveldb_proto/proto_database_impl.h110
-rw-r--r--chromium/components/leveldb_proto/proto_database_impl_unittest.cc1
-rw-r--r--chromium/components/leveldb_proto/testing/fake_db.h105
-rw-r--r--chromium/components/login/base_screen_handler_utils.cc3
-rw-r--r--chromium/components/login/secure_module_util_chromeos.cc4
-rw-r--r--chromium/components/memory_pressure/BUILD.gn46
-rw-r--r--chromium/components/memory_pressure/OWNERS3
-rw-r--r--chromium/components/memory_pressure/direct_memory_pressure_calculator.h14
-rw-r--r--chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.cc169
-rw-r--r--chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.h111
-rw-r--r--chromium/components/memory_pressure/direct_memory_pressure_calculator_linux_unittest.cc244
-rw-r--r--chromium/components/memory_pressure/direct_memory_pressure_calculator_win.cc116
-rw-r--r--chromium/components/memory_pressure/direct_memory_pressure_calculator_win.h72
-rw-r--r--chromium/components/memory_pressure/direct_memory_pressure_calculator_win_unittest.cc181
-rw-r--r--chromium/components/memory_pressure/filtered_memory_pressure_calculator.cc79
-rw-r--r--chromium/components/memory_pressure/filtered_memory_pressure_calculator.h84
-rw-r--r--chromium/components/memory_pressure/filtered_memory_pressure_calculator_unittest.cc249
-rw-r--r--chromium/components/memory_pressure/memory_pressure_calculator.h33
-rw-r--r--chromium/components/memory_pressure/memory_pressure_listener.cc61
-rw-r--r--chromium/components/memory_pressure/memory_pressure_listener.h92
-rw-r--r--chromium/components/memory_pressure/memory_pressure_monitor.cc283
-rw-r--r--chromium/components/memory_pressure/memory_pressure_monitor.h210
-rw-r--r--chromium/components/memory_pressure/memory_pressure_monitor_unittest.cc389
-rw-r--r--chromium/components/memory_pressure/memory_pressure_stats_collector.cc124
-rw-r--r--chromium/components/memory_pressure/memory_pressure_stats_collector.h94
-rw-r--r--chromium/components/memory_pressure/memory_pressure_stats_collector_unittest.cc130
-rw-r--r--chromium/components/memory_pressure/test_memory_pressure_calculator.cc46
-rw-r--r--chromium/components/memory_pressure/test_memory_pressure_calculator.h55
-rw-r--r--chromium/components/metrics/BUILD.gn31
-rw-r--r--chromium/components/metrics/call_stack_profile_collector.cc1
-rw-r--r--chromium/components/metrics/call_stack_profile_collector.h5
-rw-r--r--chromium/components/metrics/execution_phase.cc10
-rw-r--r--chromium/components/metrics/histogram_encoder.cc2
-rw-r--r--chromium/components/metrics/leak_detector/OWNERS2
-rw-r--r--chromium/components/metrics/metrics_log.cc5
-rw-r--r--chromium/components/metrics/metrics_log_unittest.cc2
-rw-r--r--chromium/components/metrics/metrics_service.h1
-rw-r--r--chromium/components/metrics/metrics_state_manager.h1
-rw-r--r--chromium/components/metrics/net/network_metrics_provider.h1
-rw-r--r--chromium/components/metrics/proto/translate_event.proto6
-rw-r--r--chromium/components/metrics/proto/ukm/entry.proto2
-rw-r--r--chromium/components/metrics/proto/ukm/source.proto2
-rw-r--r--chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc32
-rw-r--r--chromium/components/metrics/public/interfaces/BUILD.gn6
-rw-r--r--chromium/components/metrics/public/interfaces/single_sample_metrics.mojom24
-rw-r--r--chromium/components/metrics/single_sample_metrics.cc86
-rw-r--r--chromium/components/metrics/single_sample_metrics.h43
-rw-r--r--chromium/components/metrics/single_sample_metrics_factory_impl.cc90
-rw-r--r--chromium/components/metrics/single_sample_metrics_factory_impl.h71
-rw-r--r--chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc181
-rw-r--r--chromium/components/metrics_services_manager/BUILD.gn1
-rw-r--r--chromium/components/metrics_services_manager/metrics_services_manager.cc8
-rw-r--r--chromium/components/metrics_services_manager/metrics_services_manager_client.cc13
-rw-r--r--chromium/components/metrics_services_manager/metrics_services_manager_client.h6
-rw-r--r--chromium/components/minidump_uploader/BUILD.gn4
-rw-r--r--chromium/components/minidump_uploader/OWNERS1
-rw-r--r--chromium/components/nacl/browser/BUILD.gn1
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_delegate.cc2
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_throttle.cc4
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_throttle.h1
-rw-r--r--chromium/components/navigation_metrics/BUILD.gn3
-rw-r--r--chromium/components/navigation_metrics/OWNERS2
-rw-r--r--chromium/components/navigation_metrics/navigation_metrics.cc19
-rw-r--r--chromium/components/navigation_metrics/navigation_metrics.h5
-rw-r--r--chromium/components/navigation_metrics/navigation_metrics_unittest.cc8
-rw-r--r--chromium/components/navigation_metrics/origins_seen_service.cc22
-rw-r--r--chromium/components/navigation_metrics/origins_seen_service.h33
-rw-r--r--chromium/components/net_log/net_export_ui_constants.cc1
-rw-r--r--chromium/components/net_log/net_export_ui_constants.h1
-rw-r--r--chromium/components/net_log/net_log_file_writer.cc2
-rw-r--r--chromium/components/net_log/resources/net_export.css38
-rw-r--r--chromium/components/net_log/resources/net_export.html204
-rw-r--r--chromium/components/net_log/resources/net_export.js263
-rw-r--r--chromium/components/neterror/resources/neterror.html1
-rw-r--r--chromium/components/network_session_configurator/network_session_configurator.cc155
-rw-r--r--chromium/components/network_session_configurator/network_session_configurator_unittest.cc163
-rw-r--r--chromium/components/network_time/network_time_pref_names.cc4
-rw-r--r--chromium/components/network_time/network_time_pref_names.h2
-rw-r--r--chromium/components/network_time/network_time_tracker.cc12
-rw-r--r--chromium/components/network_time/network_time_tracker_unittest.cc1
-rw-r--r--chromium/components/new_or_sad_tab_strings.grdp20
-rw-r--r--chromium/components/ntp_snippets/BUILD.gn2
-rw-r--r--chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc21
-rw-r--r--chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h8
-rw-r--r--chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc7
-rw-r--r--chromium/components/ntp_snippets/category_rankers/category_ranker.h14
-rw-r--r--chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.cc49
-rw-r--r--chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.h2
-rw-r--r--chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc29
-rw-r--r--chromium/components/ntp_snippets/category_rankers/constant_category_ranker.h2
-rw-r--r--chromium/components/ntp_snippets/category_rankers/fake_category_ranker.cc5
-rw-r--r--chromium/components/ntp_snippets/category_rankers/fake_category_ranker.h1
-rw-r--r--chromium/components/ntp_snippets/category_rankers/mock_category_ranker.h1
-rw-r--r--chromium/components/ntp_snippets/content_suggestion.h8
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_metrics.cc21
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_metrics.h9
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_provider.h8
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_service.cc58
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_service.h10
-rw-r--r--chromium/components/ntp_snippets/features.cc28
-rw-r--r--chromium/components/ntp_snippets/features.h41
-rw-r--r--chromium/components/ntp_snippets/pref_names.cc21
-rw-r--r--chromium/components/ntp_snippets/pref_names.h30
-rw-r--r--chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.cc50
-rw-r--r--chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.h23
-rw-r--r--chromium/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc12
-rwxr-xr-xchromium/components/ntp_snippets/remote/fetch.py4
-rw-r--r--chromium/components/ntp_snippets/remote/json_request.cc5
-rw-r--r--chromium/components/ntp_snippets/remote/json_request_unittest.cc26
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_unittest.cc10
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc90
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.h5
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc202
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc183
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h13
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl_unittest.cc64
-rw-r--r--chromium/components/ntp_snippets/user_classifier.cc8
-rw-r--r--chromium/components/ntp_tiles/OWNERS2
-rw-r--r--chromium/components/ntp_tiles/constants.cc23
-rw-r--r--chromium/components/ntp_tiles/constants.h13
-rw-r--r--chromium/components/ntp_tiles/icon_cacher.h22
-rw-r--r--chromium/components/ntp_tiles/icon_cacher_impl.cc153
-rw-r--r--chromium/components/ntp_tiles/icon_cacher_impl.h43
-rw-r--r--chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc461
-rw-r--r--chromium/components/ntp_tiles/metrics.cc3
-rw-r--r--chromium/components/ntp_tiles/most_visited_sites.cc196
-rw-r--r--chromium/components/ntp_tiles/most_visited_sites.h59
-rw-r--r--chromium/components/ntp_tiles/most_visited_sites_unittest.cc314
-rw-r--r--chromium/components/ntp_tiles/popular_sites.h1
-rw-r--r--chromium/components/ntp_tiles/popular_sites_impl.cc38
-rw-r--r--chromium/components/ntp_tiles/popular_sites_impl.h1
-rw-r--r--chromium/components/ntp_tiles/popular_sites_impl_unittest.cc19
-rw-r--r--chromium/components/ntp_tiles/pref_names.cc4
-rw-r--r--chromium/components/ntp_tiles/pref_names.h1
-rw-r--r--chromium/components/ntp_tiles/resources/default_popular_sites.json2
-rw-r--r--chromium/components/ntp_tiles/switches.cc10
-rw-r--r--chromium/components/ntp_tiles/switches.h5
-rw-r--r--chromium/components/ntp_tiles/tile_source.h4
-rw-r--r--chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc13
-rw-r--r--chromium/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc18
-rw-r--r--chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html5
-rw-r--r--chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.js2
-rw-r--r--chromium/components/ntp_tiles/webui/resources/popular_sites_internals.html7
-rw-r--r--chromium/components/ntp_tiles/webui/resources/popular_sites_internals.js5
-rw-r--r--chromium/components/offline_items_collection/core/BUILD.gn16
-rw-r--r--chromium/components/offline_items_collection/core/DEPS1
-rw-r--r--chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc54
-rw-r--r--chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.h9
-rw-r--r--chromium/components/offline_items_collection/core/android/offline_item_bridge.cc3
-rw-r--r--chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.cc33
-rw-r--r--chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.h35
-rw-r--r--chromium/components/offline_items_collection/core/offline_content_aggregator.cc14
-rw-r--r--chromium/components/offline_items_collection/core/offline_content_aggregator.h2
-rw-r--r--chromium/components/offline_items_collection/core/offline_content_aggregator_unittest.cc4
-rw-r--r--chromium/components/offline_items_collection/core/offline_content_provider.h12
-rw-r--r--chromium/components/offline_items_collection/core/offline_item.cc20
-rw-r--r--chromium/components/offline_items_collection/core/offline_item.h57
-rw-r--r--chromium/components/offline_items_collection/core/test_support/mock_offline_content_provider.h2
-rw-r--r--chromium/components/offline_items_collection/core/throttled_offline_content_provider.cc27
-rw-r--r--chromium/components/offline_items_collection/core/throttled_offline_content_provider.h19
-rw-r--r--chromium/components/offline_items_collection/core/throttled_offline_content_provider_unittest.cc147
-rw-r--r--chromium/components/offline_pages/OWNERS1
-rw-r--r--chromium/components/offline_pages/content/BUILD.gn45
-rw-r--r--chromium/components/offline_pages/content/DEPS6
-rw-r--r--chromium/components/offline_pages/content/prefetch_service_factory.cc36
-rw-r--r--chromium/components/offline_pages/content/prefetch_service_factory.h43
-rw-r--r--chromium/components/offline_pages/content/suggested_articles_observer.cc170
-rw-r--r--chromium/components/offline_pages/content/suggested_articles_observer.h80
-rw-r--r--chromium/components/offline_pages/content/suggested_articles_observer_unittest.cc215
-rw-r--r--chromium/components/offline_pages/core/BUILD.gn5
-rw-r--r--chromium/components/offline_pages/core/background/BUILD.gn1
-rw-r--r--chromium/components/offline_pages/core/background/cleanup_task.cc53
-rw-r--r--chromium/components/offline_pages/core/background/cleanup_task.h12
-rw-r--r--chromium/components/offline_pages/core/background/load_termination_listener.h33
-rw-r--r--chromium/components/offline_pages/core/background/network_quality_provider_stub.cc4
-rw-r--r--chromium/components/offline_pages/core/background/network_quality_provider_stub.h2
-rw-r--r--chromium/components/offline_pages/core/background/offliner.h29
-rw-r--r--chromium/components/offline_pages/core/background/offliner_stub.cc28
-rw-r--r--chromium/components/offline_pages/core/background/offliner_stub.h13
-rw-r--r--chromium/components/offline_pages/core/background/remove_requests_task.cc3
-rw-r--r--chromium/components/offline_pages/core/background/remove_requests_task.h1
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator.cc151
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator.h24
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator_event_logger.cc10
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator_unittest.cc22
-rw-r--r--chromium/components/offline_pages/core/background/request_notifier.h2
-rw-r--r--chromium/components/offline_pages/core/background/request_queue_store_sql.cc1
-rw-r--r--chromium/components/offline_pages/core/client_namespace_constants.cc1
-rw-r--r--chromium/components/offline_pages/core/client_namespace_constants.h1
-rw-r--r--chromium/components/offline_pages/core/client_policy_controller.cc37
-rw-r--r--chromium/components/offline_pages/core/client_policy_controller.h6
-rw-r--r--chromium/components/offline_pages/core/client_policy_controller_unittest.cc91
-rw-r--r--chromium/components/offline_pages/core/downloads/download_notifying_observer.cc14
-rw-r--r--chromium/components/offline_pages/core/downloads/download_notifying_observer_unittest.cc4
-rw-r--r--chromium/components/offline_pages/core/downloads/download_ui_adapter.cc7
-rw-r--r--chromium/components/offline_pages/core/downloads/download_ui_adapter.h5
-rw-r--r--chromium/components/offline_pages/core/offline_page_archiver.h6
-rw-r--r--chromium/components/offline_pages/core/offline_page_client_policy.h13
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store.cc14
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store.h2
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store_sql.cc117
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store_sql.h5
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc (renamed from chromium/components/offline_pages/core/offline_page_metadata_store_impl_unittest.cc)8
-rw-r--r--chromium/components/offline_pages/core/offline_page_model.h3
-rw-r--r--chromium/components/offline_pages/core/offline_page_model_impl.cc67
-rw-r--r--chromium/components/offline_pages/core/offline_page_model_impl.h7
-rw-r--r--chromium/components/offline_pages/core/offline_page_model_impl_unittest.cc65
-rw-r--r--chromium/components/offline_pages/core/offline_page_model_query.cc32
-rw-r--r--chromium/components/offline_pages/core/offline_page_model_query.h13
-rw-r--r--chromium/components/offline_pages/core/offline_page_model_query_unittest.cc66
-rw-r--r--chromium/components/offline_pages/core/offline_page_storage_manager_unittest.cc59
-rw-r--r--chromium/components/offline_pages/core/offline_page_test_store.cc9
-rw-r--r--chromium/components/offline_pages/core/offline_page_test_store.h3
-rw-r--r--chromium/components/offline_pages/core/offline_page_types.h1
-rw-r--r--chromium/components/offline_pages/core/prefetch/BUILD.gn75
-rw-r--r--chromium/components/offline_pages/core/prefetch/README.md6
-rw-r--r--chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.cc71
-rw-r--r--chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.h44
-rw-r--r--chromium/components/offline_pages/core/prefetch/generate_page_bundle_request_unittest.cc98
-rw-r--r--chromium/components/offline_pages/core/prefetch/get_operation_request.cc54
-rw-r--r--chromium/components/offline_pages/core/prefetch/get_operation_request.h45
-rw-r--r--chromium/components/offline_pages/core/prefetch/get_operation_request_unittest.cc83
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_dispatcher.h78
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc38
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h32
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc24
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_item.cc32
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_item.h92
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_item_unittest.cc84
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.cc140
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.h22
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc142
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h64
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc140
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_operation_response_unittest.cc399
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.cc51
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.h41
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_service.h25
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc25
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h34
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_types.cc13
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_types.h110
-rw-r--r--chromium/components/offline_pages/core/prefetch/proto/any.proto13
-rw-r--r--chromium/components/offline_pages/core/prefetch/proto/offline_pages.proto98
-rw-r--r--chromium/components/offline_pages/core/prefetch/proto/operation.proto42
-rw-r--r--chromium/components/offline_pages/core/prefetch/proto/status.proto29
-rw-r--r--chromium/components/offline_pages/core/prefetch/proto/timestamp.proto21
-rw-r--r--chromium/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc3
-rw-r--r--chromium/components/offline_pages/features/BUILD.gn19
-rw-r--r--chromium/components/offline_pages/features/features.gni13
-rw-r--r--chromium/components/onc/docs/onc_spec.md73
-rw-r--r--chromium/components/onc/onc_constants.cc17
-rw-r--r--chromium/components/onc/onc_constants.h14
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content.cc22
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content.h3
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content_generic.cc25
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content_generic.h3
-rw-r--r--chromium/components/os_crypt/os_crypt.h7
-rw-r--r--chromium/components/os_crypt/os_crypt_linux.cc16
-rw-r--r--chromium/components/os_crypt/os_crypt_linux_unittest.cc13
-rw-r--r--chromium/components/os_crypt/os_crypt_mocker_linux.cc1
-rw-r--r--chromium/components/page_info_strings.grdp370
-rw-r--r--chromium/components/pairing/bluetooth_controller_pairing_controller.cc19
-rw-r--r--chromium/components/pairing/bluetooth_controller_pairing_controller.h1
-rw-r--r--chromium/components/pairing/bluetooth_host_pairing_controller.cc51
-rw-r--r--chromium/components/pairing/bluetooth_host_pairing_controller.h5
-rw-r--r--chromium/components/pairing/host_pairing_controller.h4
-rw-r--r--chromium/components/pairing/pairing_api.proto5
-rw-r--r--chromium/components/pairing/proto_decoder.cc17
-rw-r--r--chromium/components/pairing/proto_decoder.h4
-rw-r--r--chromium/components/password_manager/content/browser/PRESUBMIT.py2
-rw-r--r--chromium/components/password_manager/content/browser/content_password_manager_driver.cc18
-rw-r--r--chromium/components/password_manager/content/browser/content_password_manager_driver.h8
-rw-r--r--chromium/components/password_manager/content/browser/content_password_manager_driver_factory.cc4
-rw-r--r--chromium/components/password_manager/content/browser/content_password_manager_driver_factory.h3
-rw-r--r--chromium/components/password_manager/content/browser/content_password_manager_driver_unittest.cc19
-rw-r--r--chromium/components/password_manager/content/browser/credential_manager_impl.cc98
-rw-r--r--chromium/components/password_manager/content/browser/credential_manager_impl.h26
-rw-r--r--chromium/components/password_manager/content/browser/credential_manager_impl_unittest.cc184
-rw-r--r--chromium/components/password_manager/content/common/OWNERS2
-rw-r--r--chromium/components/password_manager/content/common/credential_manager.mojom12
-rw-r--r--chromium/components/password_manager/content/common/credential_manager.typemap1
-rw-r--r--chromium/components/password_manager/content/common/credential_manager_struct_traits.cc39
-rw-r--r--chromium/components/password_manager/content/common/credential_manager_struct_traits.h10
-rw-r--r--chromium/components/password_manager/content/renderer/credential_manager_client.cc39
-rw-r--r--chromium/components/password_manager/content/renderer/credential_manager_client.h8
-rw-r--r--chromium/components/password_manager/content/renderer/credential_manager_client_browsertest.cc56
-rw-r--r--chromium/components/password_manager/core/browser/BUILD.gn8
-rw-r--r--chromium/components/password_manager/core/browser/DEPS1
-rw-r--r--chromium/components/password_manager/core/browser/affiliation_fetcher.cc2
-rw-r--r--chromium/components/password_manager/core/browser/browser_save_password_progress_logger.cc10
-rw-r--r--chromium/components/password_manager/core/browser/browser_save_password_progress_logger.h5
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_logger.cc17
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_logger.h4
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_logger_unittest.cc7
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.cc (renamed from chromium/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc)19
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.h (renamed from chromium/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h)22
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_pending_request_task.cc28
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_pending_request_task.h6
-rw-r--r--chromium/components/password_manager/core/browser/fake_form_fetcher.cc19
-rw-r--r--chromium/components/password_manager/core/browser/fake_form_fetcher.h38
-rw-r--r--chromium/components/password_manager/core/browser/form_fetcher.h36
-rw-r--r--chromium/components/password_manager/core/browser/form_fetcher_impl.cc104
-rw-r--r--chromium/components/password_manager/core/browser/form_fetcher_impl.h45
-rw-r--r--chromium/components/password_manager/core/browser/form_fetcher_impl_unittest.cc373
-rw-r--r--chromium/components/password_manager/core/browser/login_database.cc49
-rw-r--r--chromium/components/password_manager/core/browser/login_database.h13
-rw-r--r--chromium/components/password_manager/core/browser/login_database_unittest.cc144
-rw-r--r--chromium/components/password_manager/core/browser/mock_password_store.h11
-rw-r--r--chromium/components/password_manager/core/browser/password_form_manager.cc152
-rw-r--r--chromium/components/password_manager/core/browser/password_form_manager.h50
-rw-r--r--chromium/components/password_manager/core/browser/password_form_manager_unittest.cc315
-rw-r--r--chromium/components/password_manager/core/browser/password_manager.cc33
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_client.h10
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_driver.h3
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_metrics_util.cc37
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_metrics_util.h34
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_test_utils.h2
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_unittest.cc6
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_util.cc15
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_util.h3
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_util_unittest.cc17
-rw-r--r--chromium/components/password_manager/core/browser/password_reuse_detection_manager.cc8
-rw-r--r--chromium/components/password_manager/core/browser/password_reuse_detection_manager.h2
-rw-r--r--chromium/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc2
-rw-r--r--chromium/components/password_manager/core/browser/password_reuse_detector.cc68
-rw-r--r--chromium/components/password_manager/core/browser/password_reuse_detector.h26
-rw-r--r--chromium/components/password_manager/core/browser/password_reuse_detector_consumer.h5
-rw-r--r--chromium/components/password_manager/core/browser/password_reuse_detector_unittest.cc70
-rw-r--r--chromium/components/password_manager/core/browser/password_store.cc40
-rw-r--r--chromium/components/password_manager/core/browser/password_store.h41
-rw-r--r--chromium/components/password_manager/core/browser/password_store_default.cc15
-rw-r--r--chromium/components/password_manager/core/browser/password_store_default.h8
-rw-r--r--chromium/components/password_manager/core/browser/password_store_default_unittest.cc13
-rw-r--r--chromium/components/password_manager/core/browser/password_store_unittest.cc128
-rw-r--r--chromium/components/password_manager/core/browser/psl_matching_helper.cc24
-rw-r--r--chromium/components/password_manager/core/browser/psl_matching_helper.h7
-rw-r--r--chromium/components/password_manager/core/browser/psl_matching_helper_unittest.cc101
-rw-r--r--chromium/components/password_manager/core/browser/stub_password_manager_client.cc7
-rw-r--r--chromium/components/password_manager/core/browser/stub_password_manager_client.h4
-rw-r--r--chromium/components/password_manager/core/browser/stub_password_manager_driver.cc4
-rw-r--r--chromium/components/password_manager/core/browser/stub_password_manager_driver.h1
-rw-r--r--chromium/components/password_manager/core/browser/suppressed_form_fetcher.cc41
-rw-r--r--chromium/components/password_manager/core/browser/suppressed_form_fetcher.h62
-rw-r--r--chromium/components/password_manager/core/browser/suppressed_form_fetcher_unittest.cc157
-rw-r--r--chromium/components/password_manager/core/browser/test_password_store.cc9
-rw-r--r--chromium/components/password_manager/core/browser/test_password_store.h2
-rw-r--r--chromium/components/password_manager/core/browser/webdata/password_web_data_service_win.cc1
-rw-r--r--chromium/components/password_manager/core/common/credential_manager_types.h2
-rw-r--r--chromium/components/password_manager/core/common/password_manager_pref_names.cc2
-rw-r--r--chromium/components/password_manager/core/common/password_manager_pref_names.h3
-rw-r--r--chromium/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc4
-rw-r--r--chromium/components/payments/android/BUILD.gn4
-rw-r--r--chromium/components/payments/android/DEPS2
-rw-r--r--chromium/components/payments/android/OWNERS3
-rw-r--r--chromium/components/payments/android/payment_manifest_web_data_service.cc110
-rw-r--r--chromium/components/payments/android/payment_manifest_web_data_service.h70
-rw-r--r--chromium/components/payments/android/payment_method_manifest_table.cc22
-rw-r--r--chromium/components/payments/android/payment_method_manifest_table.h6
-rw-r--r--chromium/components/payments/android/web_app_manifest_section_table.cc100
-rw-r--r--chromium/components/payments/android/web_app_manifest_section_table.h19
-rw-r--r--chromium/components/payments/android/web_app_manifest_section_table_unittest.cc89
-rw-r--r--chromium/components/payments/content/BUILD.gn47
-rw-r--r--chromium/components/payments/content/DEPS2
-rw-r--r--chromium/components/payments/content/OWNERS3
-rw-r--r--chromium/components/payments/content/android/BUILD.gn10
-rw-r--r--chromium/components/payments/content/android/OWNERS5
-rw-r--r--chromium/components/payments/content/android/origin_security_checker_android.cc49
-rw-r--r--chromium/components/payments/content/android/origin_security_checker_android.h16
-rw-r--r--chromium/components/payments/content/android/payment_details_validation_android.cc2
-rw-r--r--chromium/components/payments/content/can_make_payment_query_factory.cc36
-rw-r--r--chromium/components/payments/content/can_make_payment_query_factory.h46
-rw-r--r--chromium/components/payments/content/origin_security_checker.cc29
-rw-r--r--chromium/components/payments/content/origin_security_checker.h32
-rw-r--r--chromium/components/payments/content/payment_app.mojom57
-rw-r--r--chromium/components/payments/content/payment_details_validation.cc12
-rw-r--r--chromium/components/payments/content/payment_details_validation.h2
-rw-r--r--chromium/components/payments/content/payment_manifest_parser_host.h2
-rw-r--r--chromium/components/payments/content/payment_request.cc167
-rw-r--r--chromium/components/payments/content/payment_request.h30
-rw-r--r--chromium/components/payments/content/payment_request_spec.cc117
-rw-r--r--chromium/components/payments/content/payment_request_spec.h65
-rw-r--r--chromium/components/payments/content/payment_request_spec_unittest.cc164
-rw-r--r--chromium/components/payments/content/payment_request_state.cc185
-rw-r--r--chromium/components/payments/content/payment_request_state.h73
-rw-r--r--chromium/components/payments/content/payment_request_state_unittest.cc95
-rw-r--r--chromium/components/payments/content/payment_request_web_contents_manager.cc32
-rw-r--r--chromium/components/payments/content/payment_request_web_contents_manager.h33
-rw-r--r--chromium/components/payments/content/payment_response_helper.cc131
-rw-r--r--chromium/components/payments/content/payment_response_helper.h37
-rw-r--r--chromium/components/payments/content/payment_response_helper_unittest.cc76
-rw-r--r--chromium/components/payments/content/payments_validators.h2
-rw-r--r--chromium/components/payments/content/utility/BUILD.gn2
-rw-r--r--chromium/components/payments/content/utility/payment_manifest_parser.cc9
-rw-r--r--chromium/components/payments/content/utility/payment_manifest_parser.h13
-rw-r--r--chromium/components/payments/core/BUILD.gn42
-rw-r--r--chromium/components/payments/core/DEPS2
-rw-r--r--chromium/components/payments/core/OWNERS4
-rw-r--r--chromium/components/payments/core/address_normalization_manager.cc103
-rw-r--r--chromium/components/payments/core/address_normalization_manager.h107
-rw-r--r--chromium/components/payments/core/address_normalization_manager_unittest.cc65
-rw-r--r--chromium/components/payments/core/address_normalizer.h43
-rw-r--r--chromium/components/payments/core/address_normalizer_impl.cc (renamed from chromium/components/payments/core/address_normalizer.cc)16
-rw-r--r--chromium/components/payments/core/address_normalizer_impl.h62
-rw-r--r--chromium/components/payments/core/address_normalizer_impl_unittest.cc (renamed from chromium/components/payments/core/address_normalizer_unittest.cc)12
-rw-r--r--chromium/components/payments/core/autofill_payment_instrument.cc132
-rw-r--r--chromium/components/payments/core/autofill_payment_instrument.h28
-rw-r--r--chromium/components/payments/core/autofill_payment_instrument_unittest.cc250
-rw-r--r--chromium/components/payments/core/can_make_payment_query.cc44
-rw-r--r--chromium/components/payments/core/can_make_payment_query.h50
-rw-r--r--chromium/components/payments/core/currency_formatter.cc8
-rw-r--r--chromium/components/payments/core/currency_formatter_unittest.cc11
-rw-r--r--chromium/components/payments/core/journey_logger.cc119
-rw-r--r--chromium/components/payments/core/journey_logger.h146
-rw-r--r--chromium/components/payments/core/journey_logger_unittest.cc199
-rw-r--r--chromium/components/payments/core/payment_instrument.cc4
-rw-r--r--chromium/components/payments/core/payment_instrument.h14
-rw-r--r--chromium/components/payments/core/payment_prefs.cc18
-rw-r--r--chromium/components/payments/core/payment_prefs.h22
-rw-r--r--chromium/components/payments/core/payment_request_data_util.cc100
-rw-r--r--chromium/components/payments/core/payment_request_data_util.h20
-rw-r--r--chromium/components/payments/core/payment_request_data_util_unittest.cc170
-rw-r--r--chromium/components/payments/core/payment_request_delegate.h46
-rw-r--r--chromium/components/payments/core/payments_profile_comparator.cc286
-rw-r--r--chromium/components/payments/core/payments_profile_comparator.h124
-rw-r--r--chromium/components/payments/core/payments_profile_comparator_unittest.cc464
-rw-r--r--chromium/components/payments/core/profile_util.cc123
-rw-r--r--chromium/components/payments/core/profile_util.h69
-rw-r--r--chromium/components/payments/core/profile_util_unittest.cc231
-rw-r--r--chromium/components/payments/core/strings_util.cc41
-rw-r--r--chromium/components/payments/core/strings_util.h16
-rw-r--r--chromium/components/payments/core/subkey_requester.cc129
-rw-r--r--chromium/components/payments/core/subkey_requester.h73
-rw-r--r--chromium/components/payments/core/subkey_requester_unittest.cc194
-rw-r--r--chromium/components/payments/core/test_address_normalizer.cc38
-rw-r--r--chromium/components/payments/core/test_address_normalizer.h46
-rw-r--r--chromium/components/payments/core/test_payment_request_delegate.cc88
-rw-r--r--chromium/components/payments/core/test_payment_request_delegate.h59
-rw-r--r--chromium/components/payments/mojom/BUILD.gn33
-rw-r--r--chromium/components/payments/mojom/OWNERS4
-rw-r--r--chromium/components/payments/mojom/payment_app.mojom61
-rw-r--r--chromium/components/payments/mojom/payment_manifest_parser.mojom (renamed from chromium/components/payments/content/payment_manifest_parser.mojom)0
-rw-r--r--chromium/components/payments/mojom/payment_request.mojom (renamed from chromium/components/payments/content/payment_request.mojom)13
-rw-r--r--chromium/components/payments_strings.grdp64
-rw-r--r--chromium/components/pdf/browser/pdf_web_contents_helper.cc6
-rw-r--r--chromium/components/pdf/browser/pdf_web_contents_helper.h3
-rw-r--r--chromium/components/pdf/renderer/pdf_accessibility_tree.cc2
-rw-r--r--chromium/components/pdf_strings.grdp8
-rw-r--r--chromium/components/plugins/renderer/loadable_plugin_placeholder.cc7
-rw-r--r--chromium/components/plugins/renderer/loadable_plugin_placeholder.h3
-rw-r--r--chromium/components/plugins/renderer/plugin_placeholder.cc18
-rw-r--r--chromium/components/plugins/renderer/plugin_placeholder.h12
-rw-r--r--chromium/components/plugins/renderer/webview_plugin.cc37
-rw-r--r--chromium/components/plugins/renderer/webview_plugin.h11
-rw-r--r--chromium/components/policy/core/common/BUILD.gn22
-rw-r--r--chromium/components/policy/proto/BUILD.gn3
-rw-r--r--chromium/components/precache/content/precache_manager.cc4
-rw-r--r--chromium/components/precache/core/precache_database_unittest.cc9
-rw-r--r--chromium/components/precache/core/precache_fetcher_unittest.cc24
-rw-r--r--chromium/components/precache/core/precache_manifest_util.cc25
-rw-r--r--chromium/components/precache/core/proto/precache.proto14
-rw-r--r--chromium/components/prefs/BUILD.gn1
-rw-r--r--chromium/components/prefs/json_pref_store.cc10
-rw-r--r--chromium/components/prefs/json_pref_store.h21
-rw-r--r--chromium/components/prefs/overlay_user_pref_store.cc64
-rw-r--r--chromium/components/prefs/overlay_user_pref_store.h10
-rw-r--r--chromium/components/prefs/overlay_user_pref_store_unittest.cc88
-rw-r--r--chromium/components/prefs/pref_service.cc48
-rw-r--r--chromium/components/prefs/pref_service.h47
-rw-r--r--chromium/components/prefs/testing_pref_store.cc21
-rw-r--r--chromium/components/prefs/testing_pref_store.h3
-rw-r--r--chromium/components/prefs/writeable_pref_store.cc14
-rw-r--r--chromium/components/prefs/writeable_pref_store.h24
-rw-r--r--chromium/components/previews/core/BUILD.gn2
-rw-r--r--chromium/components/previews/core/previews_black_list.cc24
-rw-r--r--chromium/components/previews/core/previews_black_list.h4
-rw-r--r--chromium/components/previews/core/previews_black_list_unittest.cc665
-rw-r--r--chromium/components/previews/core/previews_decider.h16
-rw-r--r--chromium/components/previews/core/previews_experiments.cc52
-rw-r--r--chromium/components/previews/core/previews_experiments.h20
-rw-r--r--chromium/components/previews/core/previews_experiments_unittest.cc40
-rw-r--r--chromium/components/previews/core/previews_features.cc19
-rw-r--r--chromium/components/previews/core/previews_features.h19
-rw-r--r--chromium/components/previews/core/previews_io_data.cc62
-rw-r--r--chromium/components/previews/core/previews_io_data.h13
-rw-r--r--chromium/components/previews/core/previews_io_data_unittest.cc77
-rw-r--r--chromium/components/previews/core/previews_opt_out_store_sql.cc1
-rw-r--r--chromium/components/printing/browser/BUILD.gn5
-rw-r--r--chromium/components/printing/common/print_messages.h8
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper.cc61
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper.h9
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper_linux.cc6
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper_mac.mm24
-rw-r--r--chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc4
-rw-r--r--chromium/components/printing/service/BUILD.gn35
-rw-r--r--chromium/components/printing/service/DEPS10
-rw-r--r--chromium/components/printing/service/README.md4
-rw-r--r--chromium/components/printing/service/pdf_compositor_impl.cc86
-rw-r--r--chromium/components/printing/service/pdf_compositor_impl.h38
-rw-r--r--chromium/components/printing/service/pdf_compositor_manifest.json15
-rw-r--r--chromium/components/printing/service/pdf_compositor_service.cc73
-rw-r--r--chromium/components/printing/service/pdf_compositor_service.h54
-rw-r--r--chromium/components/printing/service/public/cpp/BUILD.gn35
-rw-r--r--chromium/components/printing/service/public/cpp/pdf_compositor_client.cc58
-rw-r--r--chromium/components/printing/service/public/cpp/pdf_compositor_client.h38
-rw-r--r--chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.cc23
-rw-r--r--chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.h20
-rw-r--r--chromium/components/printing/service/public/interfaces/BUILD.gn11
-rw-r--r--chromium/components/printing/service/public/interfaces/OWNERS2
-rw-r--r--chromium/components/printing/service/public/interfaces/pdf_compositor.mojom16
-rw-r--r--chromium/components/profile_metrics/OWNERS1
-rw-r--r--chromium/components/proximity_auth/BUILD.gn13
-rw-r--r--chromium/components/proximity_auth/ble/BUILD.gn65
-rw-r--r--chromium/components/proximity_auth/webui/BUILD.gn1
-rw-r--r--chromium/components/proxy_config/ios/BUILD.gn19
-rw-r--r--chromium/components/proxy_config/ios/DEPS5
-rw-r--r--chromium/components/proxy_config/ios/proxy_service_factory.cc57
-rw-r--r--chromium/components/proxy_config/ios/proxy_service_factory.h52
-rw-r--r--chromium/components/rappor/log_uploader_unittest.cc7
-rw-r--r--chromium/components/rappor/rappor_recorder_impl.cc6
-rw-r--r--chromium/components/rappor/rappor_recorder_impl.h5
-rw-r--r--chromium/components/reading_list/core/reading_list_entry.h2
-rw-r--r--chromium/components/reading_list/core/reading_list_model_impl.cc2
-rw-r--r--chromium/components/reading_list/core/reading_list_model_observer.h3
-rw-r--r--chromium/components/reading_list/core/reading_list_model_unittest.cc3
-rw-r--r--chromium/components/reading_list/ios/reading_list_model_bridge_observer.h2
-rw-r--r--chromium/components/reading_list/ios/reading_list_model_bridge_observer.mm8
-rw-r--r--chromium/components/renderer_context_menu/context_menu_delegate.cc6
-rw-r--r--chromium/components/renderer_context_menu/views/toolkit_delegate_views.cc11
-rw-r--r--chromium/components/resources/BUILD.gn5
-rw-r--r--chromium/components/resources/OWNERS4
-rw-r--r--chromium/components/resources/autofill_scaled_resources.grdp14
-rw-r--r--chromium/components/resources/default_100_percent/autofill/amex.pngbin1213 -> 597 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/elo.pngbin0 -> 402 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/mir.pngbin496 -> 729 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_amex.pngbin1187 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_dinersclub.pngbin1394 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_discover.pngbin883 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_generic.pngbin202 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_jcb.pngbin2146 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_mc.pngbin1425 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_mir.pngbin976 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_unionpay.pngbin2269 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/pr_visa.pngbin1159 -> 0 bytes
-rw-r--r--chromium/components/resources/default_100_percent/autofill/unionpay.pngbin0 -> 987 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/amex.pngbin2851 -> 1518 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/elo.pngbin0 -> 831 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/mir.pngbin1225 -> 1261 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_amex.pngbin3344 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_dinersclub.pngbin3074 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_discover.pngbin2228 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_generic.pngbin334 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_jcb.pngbin4371 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_mc.pngbin3303 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_mir.pngbin2877 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_unionpay.pngbin7284 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/pr_visa.pngbin2454 -> 0 bytes
-rw-r--r--chromium/components/resources/default_200_percent/autofill/unionpay.pngbin0 -> 2459 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_amex.pngbin9023 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_dinersclub.pngbin6742 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_discover.pngbin4991 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_generic.pngbin585 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_jcb.pngbin12846 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_mc.pngbin7067 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_mir.pngbin8597 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_unionpay.pngbin23032 -> 0 bytes
-rw-r--r--chromium/components/resources/default_300_percent/autofill/pr_visa.pngbin5699 -> 0 bytes
-rw-r--r--chromium/components/resources/printing_resources.grdp2
-rw-r--r--chromium/components/resources/security_interstitials_resources.grdp1
-rw-r--r--chromium/components/resources/sync_driver_resources.grdp15
-rw-r--r--chromium/components/safe_browsing/BUILD.gn3
-rw-r--r--chromium/components/safe_browsing/DEPS2
-rw-r--r--chromium/components/safe_browsing/base_blocking_page.cc64
-rw-r--r--chromium/components/safe_browsing/base_blocking_page.h27
-rw-r--r--chromium/components/safe_browsing/base_ping_manager.cc43
-rw-r--r--chromium/components/safe_browsing/base_resource_throttle.cc32
-rw-r--r--chromium/components/safe_browsing/base_ui_manager.cc12
-rw-r--r--chromium/components/safe_browsing/base_ui_manager.h6
-rw-r--r--chromium/components/safe_browsing/browser/BUILD.gn29
-rw-r--r--chromium/components/safe_browsing/browser/DEPS10
-rw-r--r--chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.cc134
-rw-r--r--chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.h67
-rw-r--r--chromium/components/safe_browsing/browser/threat_details.cc590
-rw-r--r--chromium/components/safe_browsing/browser/threat_details.h256
-rw-r--r--chromium/components/safe_browsing/browser/threat_details_cache.cc242
-rw-r--r--chromium/components/safe_browsing/browser/threat_details_cache.h107
-rw-r--r--chromium/components/safe_browsing/browser/threat_details_history.cc123
-rw-r--r--chromium/components/safe_browsing/browser/threat_details_history.h94
-rw-r--r--chromium/components/safe_browsing/common/BUILD.gn25
-rw-r--r--chromium/components/safe_browsing/common/DEPS1
-rw-r--r--chromium/components/safe_browsing/common/safe_browsing_prefs.cc (renamed from chromium/components/safe_browsing_db/safe_browsing_prefs.cc)3
-rw-r--r--chromium/components/safe_browsing/common/safe_browsing_prefs.h (renamed from chromium/components/safe_browsing_db/safe_browsing_prefs.h)6
-rw-r--r--chromium/components/safe_browsing/common/safe_browsing_prefs_unittest.cc (renamed from chromium/components/safe_browsing_db/safe_browsing_prefs_unittest.cc)2
-rw-r--r--chromium/components/safe_browsing/common/safebrowsing_constants.cc4
-rw-r--r--chromium/components/safe_browsing/common/safebrowsing_constants.h3
-rw-r--r--chromium/components/safe_browsing/common/safebrowsing_messages.h12
-rw-r--r--chromium/components/safe_browsing/csd.proto25
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_request.cc159
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_request.h98
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_service.cc255
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_service.h110
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc328
-rw-r--r--chromium/components/safe_browsing/renderer/threat_dom_details.cc9
-rw-r--r--chromium/components/safe_browsing/triggers/BUILD.gn22
-rw-r--r--chromium/components/safe_browsing/triggers/trigger_manager.cc29
-rw-r--r--chromium/components/safe_browsing/triggers/trigger_manager.h52
-rw-r--r--chromium/components/safe_browsing_db/BUILD.gn22
-rw-r--r--chromium/components/safe_browsing_db/DEPS2
-rw-r--r--chromium/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc14
-rw-r--r--chromium/components/safe_browsing_db/hit_report.h2
-rw-r--r--chromium/components/safe_browsing_db/remote_database_manager.cc45
-rw-r--r--chromium/components/safe_browsing_db/remote_database_manager.h3
-rw-r--r--chromium/components/safe_browsing_db/safe_browsing_api_handler_unittest.cc49
-rw-r--r--chromium/components/safe_browsing_db/safe_browsing_api_handler_util.cc57
-rw-r--r--chromium/components/safe_browsing_db/safe_browsing_api_handler_util.h7
-rw-r--r--chromium/components/safe_browsing_db/util.h2
-rw-r--r--chromium/components/safe_browsing_db/v4_database.cc36
-rw-r--r--chromium/components/safe_browsing_db/v4_database.h14
-rw-r--r--chromium/components/safe_browsing_db/v4_database_unittest.cc15
-rw-r--r--chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.cc38
-rw-r--r--chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.h9
-rw-r--r--chromium/components/safe_browsing_db/v4_local_database_manager.cc25
-rw-r--r--chromium/components/safe_browsing_db/v4_local_database_manager.h6
-rw-r--r--chromium/components/safe_browsing_db/v4_local_database_manager_unittest.cc9
-rw-r--r--chromium/components/safe_browsing_db/v4_protocol_manager_util.cc3
-rw-r--r--chromium/components/safe_browsing_db/v4_protocol_manager_util_unittest.cc24
-rw-r--r--chromium/components/safe_browsing_db/v4_update_protocol_manager.cc34
-rw-r--r--chromium/components/safe_browsing_db/v4_update_protocol_manager.h2
-rw-r--r--chromium/components/safe_json/utility/safe_json_parser_mojo_impl.cc9
-rw-r--r--chromium/components/safe_json/utility/safe_json_parser_mojo_impl.h9
-rw-r--r--chromium/components/search_engines/BUILD.gn24
-rw-r--r--chromium/components/search_engines/prepopulated_engines.json2
-rw-r--r--chromium/components/search_engines/search_engine_data_type_controller_unittest.cc2
-rw-r--r--chromium/components/search_engines/search_engine_type.h3
-rw-r--r--chromium/components/search_engines/search_terms_data.cc4
-rw-r--r--chromium/components/search_engines/search_terms_data.h4
-rw-r--r--chromium/components/search_engines/template_url.cc223
-rw-r--r--chromium/components/search_engines/template_url.h43
-rw-r--r--chromium/components/search_engines/template_url_service.cc87
-rw-r--r--chromium/components/search_engines/template_url_service.h18
-rw-r--r--chromium/components/search_engines/template_url_unittest.cc93
-rw-r--r--chromium/components/search_provider_logos/logo_tracker_unittest.cc1
-rw-r--r--chromium/components/security_interstitials/DEPS1
-rw-r--r--chromium/components/security_interstitials/content/BUILD.gn2
-rw-r--r--chromium/components/security_interstitials/content/DEPS1
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_controller_client.cc6
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_controller_client.h3
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_page.cc14
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_page.h7
-rw-r--r--chromium/components/security_interstitials/core/BUILD.gn9
-rw-r--r--chromium/components/security_interstitials/core/base_safe_browsing_error_ui.cc55
-rw-r--r--chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h (renamed from chromium/components/security_interstitials/core/safe_browsing_error_ui.h)103
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/extended_reporting.js6
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/blocked.svg11
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_common.css35
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_common.js46
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html134
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css201
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html11
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js67
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js7
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.css112
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.html31
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js10
-rw-r--r--chromium/components/security_interstitials/core/controller_client.h2
-rw-r--r--chromium/components/security_interstitials/core/safe_browsing_loud_error_ui.cc (renamed from chromium/components/security_interstitials/core/safe_browsing_error_ui.cc)151
-rw-r--r--chromium/components/security_interstitials/core/safe_browsing_loud_error_ui.h56
-rw-r--r--chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.cc100
-rw-r--r--chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.h57
-rw-r--r--chromium/components/security_interstitials/core/ssl_error_ui.cc3
-rw-r--r--chromium/components/security_interstitials_strings.grdp110
-rw-r--r--chromium/components/security_state/content/content_utils.cc9
-rw-r--r--chromium/components/security_state/content/content_utils_unittest.cc6
-rw-r--r--chromium/components/security_state/core/security_state.cc3
-rw-r--r--chromium/components/security_state/core/security_state.h6
-rw-r--r--chromium/components/security_state_strings.grdp23
-rw-r--r--chromium/components/sessions/content/content_live_tab.cc2
-rw-r--r--chromium/components/sessions/ios/ios_live_tab.mm3
-rw-r--r--chromium/components/signin/core/browser/account_tracker_service_unittest.cc3
-rw-r--r--chromium/components/signin/core/browser/android/BUILD.gn2
-rw-r--r--chromium/components/signin/core/browser/child_account_info_fetcher.cc6
-rw-r--r--chromium/components/signin/core/browser/child_account_info_fetcher.h2
-rw-r--r--chromium/components/signin/core/browser/child_account_info_fetcher_android.cc5
-rw-r--r--chromium/components/signin/core/browser/child_account_info_fetcher_android.h2
-rw-r--r--chromium/components/signin/core/browser/gaia_cookie_manager_service.cc42
-rw-r--r--chromium/components/signin/core/browser/signin_cookie_changed_subscription.cc1
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper_unittest.cc47
-rw-r--r--chromium/components/signin/core/browser/signin_manager.cc6
-rw-r--r--chromium/components/signin/core/browser/signin_metrics.cc58
-rw-r--r--chromium/components/signin/core/browser/signin_metrics.h16
-rw-r--r--chromium/components/signin/core/common/profile_management_switches.cc11
-rw-r--r--chromium/components/signin/core/common/profile_management_switches.h3
-rw-r--r--chromium/components/signin/core/common/signin_switches.cc8
-rw-r--r--chromium/components/signin/core/common/signin_switches.h7
-rw-r--r--chromium/components/signin/ios/browser/BUILD.gn1
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service_unittest.mm3
-rw-r--r--chromium/components/signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.mm10
-rw-r--r--chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm1
-rw-r--r--chromium/components/spellcheck/BUILD.gn1
-rw-r--r--chromium/components/spellcheck/common/BUILD.gn15
-rw-r--r--chromium/components/spellcheck/common/OWNERS2
-rw-r--r--chromium/components/spellcheck/common/spellcheck.mojom28
-rw-r--r--chromium/components/spellcheck/common/spellcheck_bdict_language.h17
-rw-r--r--chromium/components/spellcheck/common/spellcheck_messages.h50
-rw-r--r--chromium/components/spellcheck/renderer/BUILD.gn40
-rw-r--r--chromium/components/spellcheck/renderer/DEPS5
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck.cc97
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck.h32
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_panel.cc11
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_panel.h9
-rw-r--r--chromium/components/spellcheck/spellcheck_build_features.gni3
-rw-r--r--chromium/components/ssl_errors/error_info.cc15
-rw-r--r--chromium/components/ssl_errors_strings.grdp49
-rw-r--r--chromium/components/startup_metric_utils/browser/startup_metric_host_impl.cc4
-rw-r--r--chromium/components/startup_metric_utils/browser/startup_metric_host_impl.h7
-rw-r--r--chromium/components/startup_metric_utils/browser/startup_metric_utils.cc115
-rw-r--r--chromium/components/startup_metric_utils/browser/startup_metric_utils.h41
-rw-r--r--chromium/components/storage_monitor/media_storage_util.cc38
-rw-r--r--chromium/components/storage_monitor/media_storage_util.h7
-rw-r--r--chromium/components/storage_monitor/media_storage_util_unittest.cc1
-rw-r--r--chromium/components/storage_monitor/media_transfer_protocol_device_observer_chromeos.cc5
-rw-r--r--chromium/components/storage_monitor/portable_device_watcher_win.cc52
-rw-r--r--chromium/components/storage_monitor/storage_monitor_chromeos.cc15
-rw-r--r--chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc1
-rw-r--r--chromium/components/storage_monitor/storage_monitor_linux.cc34
-rw-r--r--chromium/components/storage_monitor/storage_monitor_linux_unittest.cc1
-rw-r--r--chromium/components/storage_monitor/storage_monitor_mac.mm2
-rw-r--r--chromium/components/storage_monitor/storage_monitor_win_unittest.cc46
-rw-r--r--chromium/components/storage_monitor/test_volume_mount_watcher_win.cc6
-rw-r--r--chromium/components/storage_monitor/test_volume_mount_watcher_win.h2
-rw-r--r--chromium/components/storage_monitor/volume_mount_watcher_win.cc30
-rw-r--r--chromium/components/storage_monitor/volume_mount_watcher_win.h2
-rw-r--r--chromium/components/strings/components_chromium_strings_am.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ar.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_bg.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_bn.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ca.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_cs.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_da.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_de.xtb3
-rw-r--r--chromium/components/strings/components_chromium_strings_el.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_en-GB.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_es-419.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_es.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_et.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_fa.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_fi.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_fil.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_fr.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_gu.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_hi.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_hr.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_hu.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_id.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_it.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_iw.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ja.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_kn.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ko.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_lt.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_lv.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ml.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_mr.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ms.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_nl.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_no.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_pl.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_pt-BR.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_pt-PT.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ro.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ru.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_sk.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_sl.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_sr.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_sv.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_sw.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_ta.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_te.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_th.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_tr.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_uk.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_vi.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_zh-CN.xtb1
-rw-r--r--chromium/components/strings/components_chromium_strings_zh-TW.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_am.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ar.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_bg.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_bn.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ca.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_cs.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_da.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_de.xtb3
-rw-r--r--chromium/components/strings/components_google_chrome_strings_el.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_en-GB.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_es-419.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_es.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_et.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fa.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fi.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fil.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_fr.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_gu.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_hi.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_hr.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_hu.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_id.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_it.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_iw.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ja.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_kn.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ko.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_lt.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_lv.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ml.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_mr.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ms.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_nl.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_no.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_pl.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_pt-BR.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_pt-PT.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ro.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ru.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sk.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sl.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sr.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sv.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_sw.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ta.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_te.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_th.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_tr.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_uk.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_vi.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_zh-CN.xtb1
-rw-r--r--chromium/components/strings/components_google_chrome_strings_zh-TW.xtb1
-rw-r--r--chromium/components/strings/components_strings_am.xtb223
-rw-r--r--chromium/components/strings/components_strings_ar.xtb223
-rw-r--r--chromium/components/strings/components_strings_bg.xtb223
-rw-r--r--chromium/components/strings/components_strings_bn.xtb223
-rw-r--r--chromium/components/strings/components_strings_ca.xtb227
-rw-r--r--chromium/components/strings/components_strings_cs.xtb223
-rw-r--r--chromium/components/strings/components_strings_da.xtb223
-rw-r--r--chromium/components/strings/components_strings_de.xtb223
-rw-r--r--chromium/components/strings/components_strings_el.xtb223
-rw-r--r--chromium/components/strings/components_strings_en-GB.xtb227
-rw-r--r--chromium/components/strings/components_strings_es-419.xtb223
-rw-r--r--chromium/components/strings/components_strings_es.xtb225
-rw-r--r--chromium/components/strings/components_strings_et.xtb225
-rw-r--r--chromium/components/strings/components_strings_fa.xtb223
-rw-r--r--chromium/components/strings/components_strings_fi.xtb223
-rw-r--r--chromium/components/strings/components_strings_fil.xtb223
-rw-r--r--chromium/components/strings/components_strings_fr.xtb223
-rw-r--r--chromium/components/strings/components_strings_gu.xtb223
-rw-r--r--chromium/components/strings/components_strings_hi.xtb223
-rw-r--r--chromium/components/strings/components_strings_hr.xtb223
-rw-r--r--chromium/components/strings/components_strings_hu.xtb223
-rw-r--r--chromium/components/strings/components_strings_id.xtb225
-rw-r--r--chromium/components/strings/components_strings_it.xtb223
-rw-r--r--chromium/components/strings/components_strings_iw.xtb223
-rw-r--r--chromium/components/strings/components_strings_ja.xtb223
-rw-r--r--chromium/components/strings/components_strings_kn.xtb221
-rw-r--r--chromium/components/strings/components_strings_ko.xtb225
-rw-r--r--chromium/components/strings/components_strings_lt.xtb223
-rw-r--r--chromium/components/strings/components_strings_lv.xtb223
-rw-r--r--chromium/components/strings/components_strings_ml.xtb223
-rw-r--r--chromium/components/strings/components_strings_mr.xtb223
-rw-r--r--chromium/components/strings/components_strings_ms.xtb223
-rw-r--r--chromium/components/strings/components_strings_nl.xtb223
-rw-r--r--chromium/components/strings/components_strings_no.xtb223
-rw-r--r--chromium/components/strings/components_strings_pl.xtb223
-rw-r--r--chromium/components/strings/components_strings_pt-BR.xtb231
-rw-r--r--chromium/components/strings/components_strings_pt-PT.xtb223
-rw-r--r--chromium/components/strings/components_strings_ro.xtb223
-rw-r--r--chromium/components/strings/components_strings_ru.xtb223
-rw-r--r--chromium/components/strings/components_strings_sk.xtb223
-rw-r--r--chromium/components/strings/components_strings_sl.xtb223
-rw-r--r--chromium/components/strings/components_strings_sr.xtb223
-rw-r--r--chromium/components/strings/components_strings_sv.xtb229
-rw-r--r--chromium/components/strings/components_strings_sw.xtb227
-rw-r--r--chromium/components/strings/components_strings_ta.xtb229
-rw-r--r--chromium/components/strings/components_strings_te.xtb223
-rw-r--r--chromium/components/strings/components_strings_th.xtb223
-rw-r--r--chromium/components/strings/components_strings_tr.xtb223
-rw-r--r--chromium/components/strings/components_strings_uk.xtb223
-rw-r--r--chromium/components/strings/components_strings_vi.xtb223
-rw-r--r--chromium/components/strings/components_strings_zh-CN.xtb223
-rw-r--r--chromium/components/strings/components_strings_zh-TW.xtb223
-rw-r--r--chromium/components/subresource_filter/OWNERS1
-rw-r--r--chromium/components/subresource_filter/content/browser/BUILD.gn18
-rw-r--r--chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc24
-rw-r--r--chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h4
-rw-r--r--chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc60
-rw-r--r--chromium/components/subresource_filter/content/browser/content_ruleset_service.cc1
-rw-r--r--chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc381
-rw-r--r--chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h180
-rw-r--r--chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc895
-rw-r--r--chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc147
-rw-r--r--chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h51
-rw-r--r--chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc148
-rw-r--r--chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc102
-rw-r--r--chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h61
-rw-r--r--chromium/components/subresource_filter/content/browser/page_load_statistics.cc71
-rw-r--r--chromium/components/subresource_filter/content/browser/page_load_statistics.h37
-rw-r--r--chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc45
-rw-r--r--chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h13
-rw-r--r--chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc61
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_client.h24
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_observer.h34
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.cc42
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.h49
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc355
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h65
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc1133
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc59
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h80
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc101
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h95
-rw-r--r--chromium/components/subresource_filter/content/common/subresource_filter_messages.h1
-rw-r--r--chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.cc4
-rw-r--r--chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.h1
-rw-r--r--chromium/components/subresource_filter/core/browser/BUILD.gn1
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_constants.cc4
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_constants.h3
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_features.cc319
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_features.h194
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc129
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.h66
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc429
-rw-r--r--chromium/components/subresource_filter/core/common/BUILD.gn8
-rw-r--r--chromium/components/subresource_filter/core/common/PRESUBMIT.py46
-rw-r--r--chromium/components/subresource_filter/core/common/activation_decision.h40
-rw-r--r--chromium/components/subresource_filter/core/common/activation_scope.h2
-rw-r--r--chromium/components/subresource_filter/core/common/activation_state.cc31
-rw-r--r--chromium/components/subresource_filter/core/common/activation_state.h16
-rw-r--r--chromium/components/subresource_filter/core/common/document_subresource_filter_unittest.cc4
-rw-r--r--chromium/components/subresource_filter/core/common/flat/BUILD.gn3
-rw-r--r--chromium/components/subresource_filter/core/common/flat/indexed_ruleset.fbs22
-rw-r--r--chromium/components/subresource_filter/core/common/flat/url_pattern_index.fbs (renamed from chromium/components/subresource_filter/core/common/flat/rules.fbs)18
-rw-r--r--chromium/components/subresource_filter/core/common/indexed_ruleset.cc574
-rw-r--r--chromium/components/subresource_filter/core/common/indexed_ruleset.h82
-rw-r--r--chromium/components/subresource_filter/core/common/indexed_ruleset_unittest.cc790
-rw-r--r--chromium/components/subresource_filter/core/common/test_ruleset_creator.cc20
-rw-r--r--chromium/components/subresource_filter/core/common/test_ruleset_creator.h2
-rw-r--r--chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc47
-rw-r--r--chromium/components/subresource_filter/core/common/url_pattern.cc2
-rw-r--r--chromium/components/subresource_filter/core/common/url_pattern_index.cc567
-rw-r--r--chromium/components/subresource_filter/core/common/url_pattern_index.h135
-rw-r--r--chromium/components/subresource_filter/core/common/url_pattern_index_unittest.cc707
-rw-r--r--chromium/components/subresource_filter/core/common/url_rule_test_support.cc56
-rw-r--r--chromium/components/subresource_filter/core/common/url_rule_test_support.h74
-rw-r--r--chromium/components/suggestions/BUILD.gn2
-rw-r--r--chromium/components/suggestions/features.cc12
-rw-r--r--chromium/components/suggestions/features.h18
-rw-r--r--chromium/components/suggestions/image_encoder.cc1
-rw-r--r--chromium/components/suggestions/image_manager.cc40
-rw-r--r--chromium/components/suggestions/image_manager_unittest.cc10
-rw-r--r--chromium/components/suggestions/suggestions_service.h2
-rw-r--r--chromium/components/suggestions/suggestions_service_impl.cc137
-rw-r--r--chromium/components/suggestions/suggestions_service_impl.h62
-rw-r--r--chromium/components/suggestions/suggestions_service_impl_unittest.cc867
-rw-r--r--chromium/components/sync/BUILD.gn22
-rw-r--r--chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc22
-rw-r--r--chromium/components/sync_bookmarks/bookmark_model_associator.cc16
-rw-r--r--chromium/components/sync_bookmarks/bookmark_model_associator.h19
-rw-r--r--chromium/components/sync_preferences/pref_model_associator.cc45
-rw-r--r--chromium/components/sync_preferences/pref_model_associator.h10
-rw-r--r--chromium/components/sync_preferences/pref_model_associator_unittest.cc14
-rw-r--r--chromium/components/sync_preferences/pref_service_syncable_factory.cc28
-rw-r--r--chromium/components/sync_sessions/BUILD.gn3
-rw-r--r--chromium/components/sync_sessions/favicon_cache_unittest.cc8
-rw-r--r--chromium/components/sync_sessions/sessions_sync_manager.cc423
-rw-r--r--chromium/components/sync_sessions/sessions_sync_manager.h27
-rw-r--r--chromium/components/sync_sessions/sessions_sync_manager_unittest.cc288
-rw-r--r--chromium/components/sync_sessions/synced_session_tracker.cc83
-rw-r--r--chromium/components/sync_sessions/synced_session_tracker.h12
-rw-r--r--chromium/components/sync_sessions/synced_session_tracker_unittest.cc272
-rw-r--r--chromium/components/sync_sessions/task_tracker.cc173
-rw-r--r--chromium/components/sync_sessions/task_tracker.h102
-rw-r--r--chromium/components/sync_sessions/task_tracker_unittest.cc198
-rw-r--r--chromium/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc3
-rw-r--r--chromium/components/test/BUILD.gn1
-rw-r--r--chromium/components/toolbar/BUILD.gn21
-rw-r--r--chromium/components/tracing/child/child_trace_message_filter.cc2
-rw-r--r--chromium/components/tracing/common/process_metrics_memory_dump_provider.cc87
-rw-r--r--chromium/components/tracing/common/process_metrics_memory_dump_provider.h2
-rw-r--r--chromium/components/translate/core/browser/BUILD.gn2
-rw-r--r--chromium/components/translate/core/common/BUILD.gn2
-rw-r--r--chromium/components/translate/ios/browser/BUILD.gn2
-rw-r--r--chromium/components/ui_devtools/devtools_server.cc8
-rw-r--r--chromium/components/ui_devtools/devtools_server.h1
-rw-r--r--chromium/components/ukm/BUILD.gn19
-rw-r--r--chromium/components/ukm/DEPS1
-rw-r--r--chromium/components/ukm/debug_page/BUILD.gn17
-rw-r--r--chromium/components/ukm/debug_page/DEPS3
-rw-r--r--chromium/components/ukm/debug_page/debug_page.cc84
-rw-r--r--chromium/components/ukm/debug_page/debug_page.h47
-rw-r--r--chromium/components/ukm/public/BUILD.gn27
-rw-r--r--chromium/components/ukm/public/interfaces/BUILD.gn15
-rw-r--r--chromium/components/ukm/public/interfaces/OWNERS2
-rw-r--r--chromium/components/ukm/public/interfaces/ukm_interface.mojom22
-rw-r--r--chromium/components/ukm/public/ukm_entry_builder.cc32
-rw-r--r--chromium/components/ukm/public/ukm_entry_builder.h (renamed from chromium/components/ukm/ukm_entry_builder.h)30
-rw-r--r--chromium/components/ukm/public/ukm_export.h29
-rw-r--r--chromium/components/ukm/public/ukm_recorder.cc47
-rw-r--r--chromium/components/ukm/public/ukm_recorder.h107
-rw-r--r--chromium/components/ukm/test_ukm_recorder.cc67
-rw-r--r--chromium/components/ukm/test_ukm_recorder.h43
-rw-r--r--chromium/components/ukm/test_ukm_service.cc73
-rw-r--r--chromium/components/ukm/test_ukm_service.h57
-rw-r--r--chromium/components/ukm/ukm_entry.cc31
-rw-r--r--chromium/components/ukm/ukm_entry.h50
-rw-r--r--chromium/components/ukm/ukm_entry_builder.cc28
-rw-r--r--chromium/components/ukm/ukm_recorder_impl.cc177
-rw-r--r--chromium/components/ukm/ukm_recorder_impl.h78
-rw-r--r--chromium/components/ukm/ukm_service.cc160
-rw-r--r--chromium/components/ukm/ukm_service.h90
-rw-r--r--chromium/components/ukm/ukm_service_unittest.cc106
-rw-r--r--chromium/components/ukm/ukm_source.h8
-rw-r--r--chromium/components/update_client/BUILD.gn30
-rw-r--r--chromium/components/update_client/action.cc191
-rw-r--r--chromium/components/update_client/action.h87
-rw-r--r--chromium/components/update_client/action_update.cc422
-rw-r--r--chromium/components/update_client/action_update.h167
-rw-r--r--chromium/components/update_client/action_update_check.cc242
-rw-r--r--chromium/components/update_client/action_update_check.h61
-rw-r--r--chromium/components/update_client/action_wait.cc59
-rw-r--r--chromium/components/update_client/action_wait.h36
-rw-r--r--chromium/components/update_client/background_downloader_win.cc70
-rw-r--r--chromium/components/update_client/component.cc716
-rw-r--r--chromium/components/update_client/component.h421
-rw-r--r--chromium/components/update_client/component_patcher.h1
-rw-r--r--chromium/components/update_client/component_patcher_operation.cc3
-rw-r--r--chromium/components/update_client/component_patcher_operation.h27
-rw-r--r--chromium/components/update_client/component_patcher_unittest.h1
-rw-r--r--chromium/components/update_client/component_unpacker.cc40
-rw-r--r--chromium/components/update_client/component_unpacker.h2
-rw-r--r--chromium/components/update_client/component_unpacker_unittest.cc23
-rw-r--r--chromium/components/update_client/crx_downloader_unittest.cc1
-rw-r--r--chromium/components/update_client/crx_update_item.h114
-rw-r--r--chromium/components/update_client/out_of_process_patcher.h40
-rw-r--r--chromium/components/update_client/ping_manager.cc169
-rw-r--r--chromium/components/update_client/ping_manager.h7
-rw-r--r--chromium/components/update_client/ping_manager_unittest.cc269
-rw-r--r--chromium/components/update_client/protocol_builder.cc356
-rw-r--r--chromium/components/update_client/protocol_builder.h111
-rw-r--r--chromium/components/update_client/protocol_builder_unittest.cc69
-rw-r--r--chromium/components/update_client/protocol_parser.cc (renamed from chromium/components/update_client/update_response.cc)94
-rw-r--r--chromium/components/update_client/protocol_parser.h (renamed from chromium/components/update_client/update_response.h)32
-rw-r--r--chromium/components/update_client/protocol_parser_unittest.cc (renamed from chromium/components/update_client/update_response_unittest.cc)108
-rw-r--r--chromium/components/update_client/request_sender_unittest.cc61
-rw-r--r--chromium/components/update_client/task_send_uninstall_ping.cc62
-rw-r--r--chromium/components/update_client/task_send_uninstall_ping.h66
-rw-r--r--chromium/components/update_client/task_update.h1
-rw-r--r--chromium/components/update_client/test_configurator.cc2
-rw-r--r--chromium/components/update_client/test_installer.cc16
-rw-r--r--chromium/components/update_client/test_installer.h4
-rw-r--r--chromium/components/update_client/update_checker.cc246
-rw-r--r--chromium/components/update_client/update_checker.h25
-rw-r--r--chromium/components/update_client/update_checker_unittest.cc228
-rw-r--r--chromium/components/update_client/update_client.cc70
-rw-r--r--chromium/components/update_client/update_client.h21
-rw-r--r--chromium/components/update_client/update_client_errors.h2
-rw-r--r--chromium/components/update_client/update_client_internal.h7
-rw-r--r--chromium/components/update_client/update_client_unittest.cc1351
-rw-r--r--chromium/components/update_client/update_engine.cc315
-rw-r--r--chromium/components/update_client/update_engine.h72
-rw-r--r--chromium/components/update_client/update_query_params.cc4
-rw-r--r--chromium/components/update_client/updater_state.cc8
-rw-r--r--chromium/components/update_client/updater_state.h3
-rw-r--r--chromium/components/update_client/updater_state_mac.mm181
-rw-r--r--chromium/components/update_client/updater_state_unittest.cc10
-rw-r--r--chromium/components/update_client/updater_state_win.cc31
-rw-r--r--chromium/components/update_client/url_fetcher_downloader.cc32
-rw-r--r--chromium/components/update_client/url_request_post_interceptor.cc10
-rw-r--r--chromium/components/update_client/utils.cc161
-rw-r--r--chromium/components/update_client/utils.h42
-rw-r--r--chromium/components/update_client/utils_unittest.cc53
-rw-r--r--chromium/components/url_formatter/BUILD.gn4
-rw-r--r--chromium/components/url_formatter/elide_url_unittest.cc1
-rw-r--r--chromium/components/url_formatter/idn_spoof_checker.cc400
-rw-r--r--chromium/components/url_formatter/idn_spoof_checker.h78
-rw-r--r--chromium/components/url_formatter/top_domains/BUILD.gn32
-rw-r--r--chromium/components/url_formatter/top_domains/README16
-rw-r--r--chromium/components/url_formatter/top_domains/alexa_domains.list9176
-rw-r--r--chromium/components/url_formatter/top_domains/alexa_skeletons.gperf9186
-rwxr-xr-xchromium/components/url_formatter/top_domains/make_alexa_top_list.py55
-rw-r--r--chromium/components/url_formatter/top_domains/make_top_domain_gperf.cc122
-rw-r--r--chromium/components/url_formatter/url_formatter.cc323
-rw-r--r--chromium/components/url_formatter/url_formatter_unittest.cc64
-rw-r--r--chromium/components/url_matcher/url_matcher_factory_unittest.cc5
-rw-r--r--chromium/components/user_manager/fake_user_manager.cc17
-rw-r--r--chromium/components/user_manager/fake_user_manager.h5
-rw-r--r--chromium/components/user_manager/user_image/user_image.cc1
-rw-r--r--chromium/components/user_manager/user_manager_base.cc23
-rw-r--r--chromium/components/user_prefs/user_prefs.cc3
-rw-r--r--chromium/components/user_prefs/user_prefs.h3
-rw-r--r--chromium/components/variations/BUILD.gn4
-rw-r--r--chromium/components/variations/android/variations_seed_bridge.cc24
-rw-r--r--chromium/components/variations/service/variations_service.cc47
-rw-r--r--chromium/components/variations/service/variations_service.h4
-rw-r--r--chromium/components/variations/variations_seed_simulator.cc2
-rw-r--r--chromium/components/variations/variations_switches.cc7
-rw-r--r--chromium/components/variations/variations_switches.h1
-rw-r--r--chromium/components/vector_icons/BUILD.gn25
-rw-r--r--chromium/components/vector_icons/OWNERS1
-rw-r--r--chromium/components/vector_icons/screen_share.1x.icon30
-rw-r--r--chromium/components/vector_icons/screen_share.icon30
-rw-r--r--chromium/components/vector_icons/vector_icons.cc.template25
-rw-r--r--chromium/components/vector_icons/vector_icons.h.template26
-rw-r--r--chromium/components/version_ui/OWNERS2
-rw-r--r--chromium/components/version_ui/PRESUBMIT.py25
-rw-r--r--chromium/components/visitedlink/renderer/visitedlink_slave.cc6
-rw-r--r--chromium/components/visitedlink/renderer/visitedlink_slave.h7
-rw-r--r--chromium/components/viz/display_compositor/BUILD.gn (renamed from chromium/components/display_compositor/BUILD.gn)3
-rw-r--r--chromium/components/viz/display_compositor/DEPS (renamed from chromium/components/display_compositor/DEPS)0
-rw-r--r--chromium/components/viz/display_compositor/OWNERS (renamed from chromium/components/display_compositor/OWNERS)0
-rw-r--r--chromium/components/viz/display_compositor/buffer_queue.cc (renamed from chromium/components/display_compositor/buffer_queue.cc)8
-rw-r--r--chromium/components/viz/display_compositor/buffer_queue.h (renamed from chromium/components/display_compositor/buffer_queue.h)16
-rw-r--r--chromium/components/viz/display_compositor/buffer_queue_unittest.cc (renamed from chromium/components/display_compositor/buffer_queue_unittest.cc)10
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator.h (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator.h)14
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_android.cc (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_android.cc)6
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_android.h (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_android.h)16
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_mac.h (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_mac.h)16
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_mac.mm (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_mac.mm)6
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_ozone.cc (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_ozone.cc)6
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_ozone.h (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_ozone.h)16
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_win.cc (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_win.cc)9
-rw-r--r--chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_win.h (renamed from chromium/components/display_compositor/compositor_overlay_candidate_validator_win.h)16
-rw-r--r--chromium/components/viz/display_compositor/display_compositor_test_suite.cc (renamed from chromium/components/display_compositor/display_compositor_test_suite.cc)6
-rw-r--r--chromium/components/viz/display_compositor/display_compositor_test_suite.h (renamed from chromium/components/display_compositor/display_compositor_test_suite.h)10
-rw-r--r--chromium/components/viz/display_compositor/gl_helper.cc (renamed from chromium/components/display_compositor/gl_helper.cc)61
-rw-r--r--chromium/components/viz/display_compositor/gl_helper.h (renamed from chromium/components/display_compositor/gl_helper.h)21
-rw-r--r--chromium/components/viz/display_compositor/gl_helper_benchmark.cc (renamed from chromium/components/display_compositor/gl_helper_benchmark.cc)29
-rw-r--r--chromium/components/viz/display_compositor/gl_helper_readback_support.cc (renamed from chromium/components/display_compositor/gl_helper_readback_support.cc)8
-rw-r--r--chromium/components/viz/display_compositor/gl_helper_readback_support.h (renamed from chromium/components/display_compositor/gl_helper_readback_support.h)18
-rw-r--r--chromium/components/viz/display_compositor/gl_helper_scaling.cc (renamed from chromium/components/display_compositor/gl_helper_scaling.cc)6
-rw-r--r--chromium/components/viz/display_compositor/gl_helper_scaling.h (renamed from chromium/components/display_compositor/gl_helper_scaling.h)18
-rw-r--r--chromium/components/viz/display_compositor/gl_helper_unittest.cc (renamed from chromium/components/display_compositor/gl_helper_unittest.cc)93
-rw-r--r--chromium/components/viz/display_compositor/host_shared_bitmap_manager.cc (renamed from chromium/components/display_compositor/host_shared_bitmap_manager.cc)56
-rw-r--r--chromium/components/viz/display_compositor/host_shared_bitmap_manager.h (renamed from chromium/components/display_compositor/host_shared_bitmap_manager.h)26
-rw-r--r--chromium/components/viz/display_compositor/host_shared_bitmap_manager_unittest.cc (renamed from chromium/components/display_compositor/host_shared_bitmap_manager_unittest.cc)40
-rw-r--r--chromium/components/viz/display_compositor/run_all_unittests.cc15
-rw-r--r--chromium/components/viz/display_compositor/yuv_readback_unittest.cc (renamed from chromium/components/display_compositor/yuv_readback_unittest.cc)21
-rw-r--r--chromium/components/viz/frame_sinks/BUILD.gn14
-rw-r--r--chromium/components/viz/frame_sinks/DEPS1
-rw-r--r--chromium/components/viz/frame_sinks/frame_eviction_manager.cc179
-rw-r--r--chromium/components/viz/frame_sinks/frame_eviction_manager.h82
-rw-r--r--chromium/components/viz/frame_sinks/frame_evictor.cc56
-rw-r--r--chromium/components/viz/frame_sinks/frame_evictor.h46
-rw-r--r--chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.cc13
-rw-r--r--chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.h4
-rw-r--r--chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc13
-rw-r--r--chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.h4
-rw-r--r--chromium/components/viz/frame_sinks/mojo_frame_sink_manager.cc36
-rw-r--r--chromium/components/viz/frame_sinks/mojo_frame_sink_manager.h21
-rw-r--r--chromium/components/viz/viz_export.h29
-rw-r--r--chromium/components/wallpaper/wallpaper_color_calculator_unittest.cc1
-rw-r--r--chromium/components/wallpaper/wallpaper_manager_base.cc12
-rw-r--r--chromium/components/wallpaper/wallpaper_resizer_unittest.cc4
-rw-r--r--chromium/components/web_cache/renderer/BUILD.gn1
-rw-r--r--chromium/components/web_cache/renderer/DEPS1
-rw-r--r--chromium/components/web_cache/renderer/web_cache_impl.cc20
-rw-r--r--chromium/components/web_cache/renderer/web_cache_impl.h7
-rw-r--r--chromium/components/web_contents_delegate_android/validation_message_bubble_android.cc12
-rw-r--r--chromium/components/web_contents_delegate_android/web_contents_delegate_android.cc3
-rw-r--r--chromium/components/web_contents_delegate_android/web_contents_delegate_android.h17
-rw-r--r--chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc1
-rw-r--r--chromium/components/web_restrictions/browser/web_restrictions_client.cc13
-rw-r--r--chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.cc21
-rw-r--r--chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.h12
-rw-r--r--chromium/components/web_restrictions/browser/web_restrictions_resource_throttle_unittest.cc10
-rw-r--r--chromium/components/webauth/BUILD.gn15
-rw-r--r--chromium/components/webauth/OWNERS2
-rw-r--r--chromium/components/webauth/authenticator.mojom89
-rw-r--r--chromium/components/webcrypto/algorithms/hkdf.cc6
-rw-r--r--chromium/components/webcrypto/status.cc5
-rw-r--r--chromium/components/webcrypto/status.h3
-rw-r--r--chromium/components/webdata/common/BUILD.gn1
-rw-r--r--chromium/components/webdata/common/web_data_request_manager.cc96
-rw-r--r--chromium/components/webdata/common/web_data_request_manager.h33
-rw-r--r--chromium/components/webdata/common/web_data_results.h5
-rw-r--r--chromium/components/webdata/common/web_data_service_base.h1
-rw-r--r--chromium/components/webdata/common/web_database.cc5
-rw-r--r--chromium/components/webdata/common/web_database.h1
-rw-r--r--chromium/components/webdata/common/web_database_migration_unittest.cc55
-rw-r--r--chromium/components/webdata/common/web_database_table.h5
-rw-r--r--chromium/components/webdata_services/web_data_service_wrapper.cc19
-rw-r--r--chromium/components/webdata_services/web_data_service_wrapper.h16
-rw-r--r--chromium/components/wifi/BUILD.gn2
-rw-r--r--chromium/components/wifi/fake_wifi_service.h1
-rw-r--r--chromium/components/wifi/wifi_service_mac.mm6
-rw-r--r--chromium/components/wifi/wifi_service_win.cc10
-rw-r--r--chromium/components/zoom/BUILD.gn2
-rw-r--r--chromium/components/zoom/zoom_controller.cc8
-rw-r--r--chromium/components/zoom/zoom_event_manager.cc7
1954 files changed, 91010 insertions, 32959 deletions
diff --git a/chromium/components/BUILD.gn b/chromium/components/BUILD.gn
index 42e7def6964..0c176a8e273 100644
--- a/chromium/components/BUILD.gn
+++ b/chromium/components/BUILD.gn
@@ -5,6 +5,7 @@
import("//build/config/chrome_build.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
+import("//extensions/features/features.gni")
import("//printing/features/features.gni")
import("//rlz/features/features.gni")
import("//testing/test.gni")
@@ -82,6 +83,7 @@ test("components_unittests") {
"//components/device_event_log:unit_tests",
"//components/dom_distiller/core:unit_tests",
"//components/doodle:unit_tests",
+ "//components/download:unit_tests",
"//components/favicon/core:unit_tests",
"//components/favicon_base:unit_tests",
"//components/flags_ui:unit_tests",
@@ -97,7 +99,6 @@ test("components_unittests") {
"//components/language_usage_metrics:unit_tests",
"//components/leveldb_proto:unit_tests",
"//components/login:unit_tests",
- "//components/memory_pressure:unit_tests",
"//components/metrics:unit_tests",
"//components/mime_util:unit_tests",
"//components/navigation_metrics:unit_tests",
@@ -107,10 +108,6 @@ test("components_unittests") {
"//components/ntp_snippets:unit_tests",
"//components/ntp_tiles:unit_tests",
"//components/offline_items_collection/core:unit_tests",
- "//components/offline_pages/core:unit_tests",
- "//components/offline_pages/core/background:unit_tests",
- "//components/offline_pages/core/downloads:unit_tests",
- "//components/offline_pages/core/request_header:unit_tests",
"//components/omnibox/browser:unit_tests",
"//components/open_from_clipboard:unit_tests",
"//components/os_crypt:unit_tests",
@@ -164,6 +161,10 @@ test("components_unittests") {
deps += [ "//components/nacl/browser:unit_tests" ]
}
+ if (enable_extensions) {
+ deps += [ "//components/guest_view/browser:unit_tests" ]
+ }
+
if (is_ios) {
deps += [
"//components/image_fetcher/ios:unit_tests",
@@ -187,20 +188,24 @@ test("components_unittests") {
"//components/data_use_measurement/core:unit_tests",
"//components/discardable_memory/common:unit_tests",
"//components/discardable_memory/service:unit_tests",
- "//components/display_compositor:unit_tests",
"//components/dom_distiller/content/browser:unit_tests",
"//components/domain_reliability:unit_tests",
+ "//components/download/content:unit_tests",
"//components/error_page/renderer:unit_tests",
"//components/favicon/content:unit_tests",
"//components/gcm_driver/instance_id:unit_tests",
- "//components/guest_view/browser:unit_tests",
"//components/history/content/browser:unit_tests",
"//components/invalidation/impl:unit_tests",
"//components/keyed_service/content:unit_tests",
"//components/link_header_util:unit_tests",
"//components/navigation_interception:unit_tests",
"//components/network_hints/renderer:unit_tests",
+ "//components/offline_pages/content:unit_tests",
"//components/offline_pages/content/background_loader:unit_tests",
+ "//components/offline_pages/core:unit_tests",
+ "//components/offline_pages/core/background:unit_tests",
+ "//components/offline_pages/core/downloads:unit_tests",
+ "//components/offline_pages/core/request_header:unit_tests",
"//components/packed_ct_ev_whitelist:unit_tests",
"//components/password_manager/content/browser:unit_tests",
"//components/payments/content:unit_tests",
@@ -208,6 +213,7 @@ test("components_unittests") {
"//components/policy/core/browser:unit_tests",
"//components/policy/core/common:unit_tests",
"//components/precache/content:unit_tests",
+ "//components/safe_browsing/common:unit_tests",
"//components/safe_browsing/password_protection:password_protection_unittest",
"//components/safe_browsing_db:unit_tests",
"//components/safe_json:unit_tests",
@@ -219,10 +225,10 @@ test("components_unittests") {
"//components/subresource_filter/content/renderer:unit_tests",
"//components/tracing:unit_tests",
"//components/visitedlink/test:unit_tests",
+ "//components/viz/display_compositor:unit_tests",
"//components/wallpaper:unit_tests",
"//components/web_cache/browser:unit_tests",
"//components/webcrypto:unit_tests",
- "//components/zoom:unit_tests",
]
data_deps = [
@@ -278,6 +284,7 @@ test("components_unittests") {
"//components/proximity_auth:unit_tests",
"//components/storage_monitor:unit_tests",
"//components/web_modal:unit_tests",
+ "//components/zoom:unit_tests",
]
}
diff --git a/chromium/components/about_ui/OWNERS b/chromium/components/about_ui/OWNERS
index e87625e132a..918baa1330f 100644
--- a/chromium/components/about_ui/OWNERS
+++ b/chromium/components/about_ui/OWNERS
@@ -1,3 +1,3 @@
-file://ui/webui/OWNERS
+file://ui/webui/PLATFORM_OWNERS
# COMPONENT: UI>Browser>WebUI
diff --git a/chromium/components/about_ui/PRESUBMIT.py b/chromium/components/about_ui/PRESUBMIT.py
new file mode 100644
index 00000000000..5b4c471b83b
--- /dev/null
+++ b/chromium/components/about_ui/PRESUBMIT.py
@@ -0,0 +1,25 @@
+# Copyright 2017 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.
+
+
+def _CommonChecks(input_api, output_api):
+ results = []
+ try:
+ import sys
+ old_sys_path = sys.path[:]
+ cwd = input_api.PresubmitLocalPath()
+ sys.path += [input_api.os_path.join(cwd, '..', '..', 'tools')]
+ import web_dev_style.presubmit_support
+ results += web_dev_style.presubmit_support.CheckStyle(input_api, output_api)
+ finally:
+ sys.path = old_sys_path
+ return results
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
diff --git a/chromium/components/about_ui/resources/about_credits.js b/chromium/components/about_ui/resources/about_credits.js
index 818ef5e77b2..d01ffb68514 100644
--- a/chromium/components/about_ui/resources/about_credits.js
+++ b/chromium/components/about_ui/resources/about_credits.js
@@ -23,6 +23,24 @@ function toggle(o) {
}
document.addEventListener('DOMContentLoaded', function() {
+ var licenseEls = [].slice.call(document.getElementsByClassName('product'));
+
+ licenseEls.sort(function(a, b) {
+ var nameA = a.getElementsByClassName('title')[0].textContent;
+ var nameB = b.getElementsByClassName('title')[0].textContent;
+ if (nameA < nameB) return -1;
+ if (nameA > nameB) return 1;
+ return 0;
+ });
+
+ var parentEl = licenseEls[0].parentNode;
+ parentEl.innerHTML = '';
+ for (var i = 0; i < licenseEls.length; i++) {
+ parentEl.appendChild(licenseEls[i]);
+ }
+
+ document.body.hidden = false;
+
if (cr.isChromeOS) {
var keyboardUtils = document.createElement('script');
keyboardUtils.src = 'chrome://credits/keyboard_utils.js';
diff --git a/chromium/components/about_ui/resources/about_credits.tmpl b/chromium/components/about_ui/resources/about_credits.tmpl
index e9f119d6777..fc4fc965ac9 100644
--- a/chromium/components/about_ui/resources/about_credits.tmpl
+++ b/chromium/components/about_ui/resources/about_credits.tmpl
@@ -59,7 +59,7 @@ body {
}
</style>
</head>
-<body>
+<body hidden>
<span class="page-title" style="float:left;">Credits</span>
<a id="print-link" href="#" style="float:right;">Print</a>
<div style="clear:both; overflow:auto;"><!-- Chromium <3s the following projects -->
@@ -68,4 +68,4 @@ body {
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://credits/credits.js"></script>
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/chromium/components/arc/BUILD.gn b/chromium/components/arc/BUILD.gn
index b0ac5a31e6f..c9443f48a14 100644
--- a/chromium/components/arc/BUILD.gn
+++ b/chromium/components/arc/BUILD.gn
@@ -9,6 +9,8 @@ static_library("arc") {
sources = [
"arc_service_manager.cc",
"arc_service_manager.h",
+ "arc_util.cc",
+ "arc_util.h",
"audio/arc_audio_bridge.cc",
"audio/arc_audio_bridge.h",
"bluetooth/arc_bluetooth_bridge.cc",
@@ -68,6 +70,7 @@ static_library("arc") {
deps = [
"//ash:ash",
"//ash/public/cpp:ash_public_cpp",
+ "//ash/shared:app_types",
"//base",
"//chromeos",
"//chromeos:power_manager_proto",
@@ -76,6 +79,7 @@ static_library("arc") {
"//components/onc",
"//components/prefs",
"//components/signin/core/account_id",
+ "//components/user_manager",
"//device/bluetooth",
"//google_apis",
"//mojo/edk/system",
@@ -110,8 +114,6 @@ static_library("arc_base") {
"arc_session_runner.h",
"arc_stop_reason.cc",
"arc_stop_reason.h",
- "arc_util.cc",
- "arc_util.h",
"instance_holder.h",
]
@@ -159,6 +161,7 @@ mojom("arc_bindings") {
"common/tts.mojom",
"common/video.mojom",
"common/video_accelerator.mojom",
+ "common/voice_interaction_arc_home.mojom",
"common/voice_interaction_framework.mojom",
"common/wallpaper.mojom",
]
@@ -167,6 +170,9 @@ mojom("arc_bindings") {
"//mojo/common:common_custom_types",
"//ui/gfx/geometry/mojo",
]
+
+ # TODO(crbug.com/714018): Convert the implementation to use OnceCallback.
+ use_once_callback = false
}
static_library("arc_test_support") {
@@ -221,9 +227,13 @@ source_set("unit_tests") {
deps = [
":arc_test_support",
+ "//ash/shared:app_types",
"//base",
"//base/test:test_support",
"//chromeos",
+ "//components/signin/core/account_id",
+ "//components/user_manager",
+ "//components/user_manager:test_support",
"//device/bluetooth",
"//mojo/public/cpp/system:system",
"//testing/gmock",
diff --git a/chromium/components/arc/DEPS b/chromium/components/arc/DEPS
index 25269a06a31..8c82be2ef4c 100644
--- a/chromium/components/arc/DEPS
+++ b/chromium/components/arc/DEPS
@@ -11,4 +11,16 @@ include_rules = [
"+third_party/re2",
"+third_party/skia",
"+ui/gfx/geometry/rect.h",
+ "+ui/gfx/range/range.h",
]
+
+specific_include_rules = {
+ "arc_util.cc": [
+ "+ash/shared",
+ "+ui/aura",
+ ],
+ "arc_util_unittest.cc": [
+ "+ash/shared",
+ "+ui/aura",
+ ],
+}
diff --git a/chromium/components/arc/arc_bridge_host_impl.cc b/chromium/components/arc/arc_bridge_host_impl.cc
index b08a7da0fd0..3f8638728fb 100644
--- a/chromium/components/arc/arc_bridge_host_impl.cc
+++ b/chromium/components/arc/arc_bridge_host_impl.cc
@@ -212,6 +212,12 @@ void ArcBridgeHostImpl::OnVideoInstanceReady(
OnInstanceReady(arc_bridge_service_->video(), std::move(video_ptr));
}
+void ArcBridgeHostImpl::OnVoiceInteractionArcHomeInstanceReady(
+ mojom::VoiceInteractionArcHomeInstancePtr home_ptr) {
+ OnInstanceReady(arc_bridge_service_->voice_interaction_arc_home(),
+ std::move(home_ptr));
+}
+
void ArcBridgeHostImpl::OnVoiceInteractionFrameworkInstanceReady(
mojom::VoiceInteractionFrameworkInstancePtr framework_ptr) {
OnInstanceReady(arc_bridge_service_->voice_interaction_framework(),
diff --git a/chromium/components/arc/arc_bridge_host_impl.h b/chromium/components/arc/arc_bridge_host_impl.h
index 6120a5db43f..935a7ef9199 100644
--- a/chromium/components/arc/arc_bridge_host_impl.h
+++ b/chromium/components/arc/arc_bridge_host_impl.h
@@ -74,6 +74,8 @@ class ArcBridgeHostImpl : public mojom::ArcBridgeHost {
void OnTracingInstanceReady(mojom::TracingInstancePtr trace_ptr) override;
void OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) override;
void OnVideoInstanceReady(mojom::VideoInstancePtr video_ptr) override;
+ void OnVoiceInteractionArcHomeInstanceReady(
+ mojom::VoiceInteractionArcHomeInstancePtr home_ptr) override;
void OnVoiceInteractionFrameworkInstanceReady(
mojom::VoiceInteractionFrameworkInstancePtr framework_ptr) override;
void OnWallpaperInstanceReady(
diff --git a/chromium/components/arc/arc_bridge_service.h b/chromium/components/arc/arc_bridge_service.h
index 48fca23f2e8..7d540135ad7 100644
--- a/chromium/components/arc/arc_bridge_service.h
+++ b/chromium/components/arc/arc_bridge_service.h
@@ -39,6 +39,7 @@ class StorageManagerInstance;
class TracingInstance;
class TtsInstance;
class VideoInstance;
+class VoiceInteractionArcHomeInstance;
class VoiceInteractionFrameworkInstance;
class WallpaperInstance;
@@ -94,6 +95,10 @@ class ArcBridgeService {
InstanceHolder<mojom::TracingInstance>* tracing() { return &tracing_; }
InstanceHolder<mojom::TtsInstance>* tts() { return &tts_; }
InstanceHolder<mojom::VideoInstance>* video() { return &video_; }
+ InstanceHolder<mojom::VoiceInteractionArcHomeInstance>*
+ voice_interaction_arc_home() {
+ return &voice_interaction_arc_home_;
+ }
InstanceHolder<mojom::VoiceInteractionFrameworkInstance>*
voice_interaction_framework() {
return &voice_interaction_framework_;
@@ -126,6 +131,8 @@ class ArcBridgeService {
InstanceHolder<mojom::TracingInstance> tracing_;
InstanceHolder<mojom::TtsInstance> tts_;
InstanceHolder<mojom::VideoInstance> video_;
+ InstanceHolder<mojom::VoiceInteractionArcHomeInstance>
+ voice_interaction_arc_home_;
InstanceHolder<mojom::VoiceInteractionFrameworkInstance>
voice_interaction_framework_;
InstanceHolder<mojom::WallpaperInstance> wallpaper_;
diff --git a/chromium/components/arc/arc_session.cc b/chromium/components/arc/arc_session.cc
index 5738ed67443..62c9e3325d9 100644
--- a/chromium/components/arc/arc_session.cc
+++ b/chromium/components/arc/arc_session.cc
@@ -22,6 +22,7 @@
#include "base/task_runner_util.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "chromeos/chromeos_switches.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/dbus/dbus_method_call_status.h"
#include "chromeos/dbus/dbus_thread_manager.h"
@@ -32,7 +33,7 @@
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
-#include "mojo/edk/embedder/pending_process_connection.h"
+#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/platform_channel_utils_posix.h"
#include "mojo/edk/embedder/platform_handle_vector.h"
@@ -218,7 +219,8 @@ class ArcSessionImpl : public ArcSession,
// DBus callback for StartArcInstance().
void OnInstanceStarted(mojo::edk::ScopedPlatformHandle socket_fd,
- StartArcInstanceResult result);
+ StartArcInstanceResult result,
+ const std::string& container_instance_id);
// Synchronously accepts a connection on |socket_fd| and then processes the
// connected socket's file descriptor.
@@ -231,7 +233,8 @@ class ArcSessionImpl : public ArcSession,
void StopArcInstance();
// chromeos::SessionManagerClient::Observer:
- void ArcInstanceStopped(bool clean) override;
+ void ArcInstanceStopped(bool clean,
+ const std::string& container_instance_id) override;
// Completes the termination procedure.
void OnStopped(ArcStopReason reason);
@@ -252,6 +255,10 @@ class ArcSessionImpl : public ArcSession,
// When Stop() is called, this flag is set.
bool stop_requested_ = false;
+ // Container instance id passed from session_manager.
+ // Should be available only after OnInstanceStarted().
+ std::string container_instance_id_;
+
// In CONNECTING_MOJO state, this is set to the write side of the pipe
// to notify cancelling of the procedure.
base::ScopedFD accept_cancel_pipe_;
@@ -365,26 +372,26 @@ void ArcSessionImpl::OnSocketCreated(
bool disable_boot_completed_broadcast =
!base::FeatureList::IsEnabled(arc::kBootCompletedBroadcastFeature);
+ // We only enable /vendor/priv-app when voice interaction is enabled because
+ // voice interaction service apk would be bundled in this location.
+ bool enable_vendor_privileged =
+ chromeos::switches::IsVoiceInteractionEnabled();
+
chromeos::SessionManagerClient* session_manager_client =
chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
session_manager_client->StartArcInstance(
- cryptohome_id, disable_boot_completed_broadcast,
+ cryptohome_id, disable_boot_completed_broadcast, enable_vendor_privileged,
base::Bind(&ArcSessionImpl::OnInstanceStarted, weak_factory_.GetWeakPtr(),
base::Passed(&socket_fd)));
}
void ArcSessionImpl::OnInstanceStarted(
mojo::edk::ScopedPlatformHandle socket_fd,
- StartArcInstanceResult result) {
+ StartArcInstanceResult result,
+ const std::string& container_instance_id) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (state_ == State::STOPPED) {
- // This is the case that error is notified via DBus before the
- // OnInstanceStarted() callback is invoked. The stopping procedure has
- // been run, so do nothing.
- return;
- }
-
DCHECK_EQ(state_, State::STARTING_INSTANCE);
+ container_instance_id_ = container_instance_id;
if (stop_requested_) {
if (result == StartArcInstanceResult::SUCCESS) {
@@ -441,17 +448,20 @@ mojo::ScopedMessagePipeHandle ArcSessionImpl::ConnectMojo(
// Hardcode pid 0 since it is unused in mojo.
const base::ProcessHandle kUnusedChildProcessHandle = 0;
mojo::edk::PlatformChannelPair channel_pair;
- mojo::edk::PendingProcessConnection process;
- process.Connect(kUnusedChildProcessHandle,
- mojo::edk::ConnectionParams(channel_pair.PassServerHandle()));
+ mojo::edk::OutgoingBrokerClientInvitation invitation;
+
+ std::string token = mojo::edk::GenerateRandomToken();
+ mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe(token);
+
+ invitation.Send(
+ kUnusedChildProcessHandle,
+ mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
+ channel_pair.PassServerHandle()));
mojo::edk::ScopedPlatformHandleVectorPtr handles(
new mojo::edk::PlatformHandleVector{
channel_pair.PassClientHandle().release()});
- std::string token;
- mojo::ScopedMessagePipeHandle pipe = process.CreateMessagePipe(&token);
-
// We need to send the length of the message as a single byte, so make sure it
// fits.
DCHECK_LT(token.size(), 256u);
@@ -472,14 +482,6 @@ mojo::ScopedMessagePipeHandle ArcSessionImpl::ConnectMojo(
void ArcSessionImpl::OnMojoConnected(
mojo::ScopedMessagePipeHandle server_pipe) {
DCHECK(thread_checker_.CalledOnValidThread());
-
- if (state_ == State::STOPPED) {
- // This is the case that error is notified via DBus before the
- // OnMojoConnected() callback is invoked. The stopping procedure has
- // been run, so do nothing.
- return;
- }
-
DCHECK_EQ(state_, State::CONNECTING_MOJO);
accept_cancel_pipe_.reset();
@@ -567,11 +569,22 @@ void ArcSessionImpl::StopArcInstance() {
base::Bind(&DoNothingInstanceStopped));
}
-void ArcSessionImpl::ArcInstanceStopped(bool clean) {
+void ArcSessionImpl::ArcInstanceStopped(
+ bool clean,
+ const std::string& container_instance_id) {
DCHECK(thread_checker_.CalledOnValidThread());
VLOG(1) << "Notified that ARC instance is stopped "
<< (clean ? "cleanly" : "uncleanly");
+ if (container_instance_id != container_instance_id_) {
+ VLOG(1) << "Container instance id mismatch. Do nothing."
+ << container_instance_id << " vs " << container_instance_id_;
+ return;
+ }
+
+ // Release |container_instance_id_| to avoid duplicate invocation situation.
+ container_instance_id_.clear();
+
// In case that crash happens during before the Mojo channel is connected,
// unlock the BlockingPool thread.
accept_cancel_pipe_.reset();
diff --git a/chromium/components/arc/arc_session_runner_unittest.cc b/chromium/components/arc/arc_session_runner_unittest.cc
index 7c8e41de8e6..c407a097661 100644
--- a/chromium/components/arc/arc_session_runner_unittest.cc
+++ b/chromium/components/arc/arc_session_runner_unittest.cc
@@ -12,6 +12,7 @@
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "components/arc/arc_session_runner.h"
#include "components/arc/test/fake_arc_session.h"
@@ -34,7 +35,9 @@ class DoNothingObserver : public ArcSessionRunner::Observer {
class ArcSessionRunnerTest : public testing::Test,
public ArcSessionRunner::Observer {
public:
- ArcSessionRunnerTest() = default;
+ ArcSessionRunnerTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
void SetUp() override {
chromeos::DBusThreadManager::Initialize();
@@ -97,7 +100,7 @@ class ArcSessionRunnerTest : public testing::Test,
ArcStopReason stop_reason_;
bool restarting_;
std::unique_ptr<ArcSessionRunner> arc_session_runner_;
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
DISALLOW_COPY_AND_ASSIGN(ArcSessionRunnerTest);
};
diff --git a/chromium/components/arc/arc_util.cc b/chromium/components/arc/arc_util.cc
index 7c3ee3f5a08..58133783c34 100644
--- a/chromium/components/arc/arc_util.cc
+++ b/chromium/components/arc/arc_util.cc
@@ -6,10 +6,15 @@
#include <string>
+#include "ash/shared/app_types.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "chromeos/chromeos_switches.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/session_manager_client.h"
#include "components/user_manager/user_manager.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/window.h"
namespace arc {
@@ -25,8 +30,18 @@ const base::Feature kEnableArcFeature{"EnableARC",
constexpr char kAvailabilityNone[] = "none";
constexpr char kAvailabilityInstalled[] = "installed";
constexpr char kAvailabilityOfficiallySupported[] = "officially-supported";
-constexpr char kAvailabilityOfficiallySupportedWithActiveDirectory[] =
- "officially-supported-with-active-directory";
+
+void SetArcCpuRestrictionCallback(
+ login_manager::ContainerCpuRestrictionState state,
+ bool success) {
+ if (success)
+ return;
+ const char* message =
+ (state == login_manager::CONTAINER_CPU_RESTRICTION_BACKGROUND)
+ ? "unprioritize"
+ : "prioritize";
+ LOG(ERROR) << "Failed to " << message << " ARC";
+}
} // namespace
@@ -36,13 +51,10 @@ bool IsArcAvailable() {
if (command_line->HasSwitch(chromeos::switches::kArcAvailability)) {
std::string value = command_line->GetSwitchValueASCII(
chromeos::switches::kArcAvailability);
- DCHECK(value == kAvailabilityNone ||
- value == kAvailabilityInstalled ||
- value == kAvailabilityOfficiallySupported ||
- value == kAvailabilityOfficiallySupportedWithActiveDirectory)
+ DCHECK(value == kAvailabilityNone || value == kAvailabilityInstalled ||
+ value == kAvailabilityOfficiallySupported)
<< "Unknown flag value: " << value;
return value == kAvailabilityOfficiallySupported ||
- value == kAvailabilityOfficiallySupportedWithActiveDirectory ||
(value == kAvailabilityInstalled &&
base::FeatureList::IsEnabled(kEnableArcFeature));
}
@@ -94,15 +106,34 @@ bool IsArcKioskMode() {
user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp();
}
-bool IsArcAllowedForActiveDirectoryUsers() {
- const auto* command_line = base::CommandLine::ForCurrentProcess();
+bool IsArcAllowedForUser(const user_manager::User* user) {
+ if (!user) {
+ VLOG(1) << "No ARC for nullptr user.";
+ return false;
+ }
- if (!command_line->HasSwitch(chromeos::switches::kArcAvailability))
+ // ARC is only supported for the following cases:
+ // - Users have Gaia accounts;
+ // - Active directory users;
+ // - ARC kiosk session;
+ // USER_TYPE_ARC_KIOSK_APP check is compatible with IsArcKioskMode()
+ // above because ARC kiosk user is always the primary/active user of a
+ // user session.
+ if (!user->HasGaiaAccount() && !user->IsActiveDirectoryUser() &&
+ user->GetType() != user_manager::USER_TYPE_ARC_KIOSK_APP) {
+ VLOG(1) << "Users without GAIA or AD accounts, or not ARC kiosk apps are "
+ "not supported in ARC.";
return false;
+ }
- return command_line->GetSwitchValueASCII(
- chromeos::switches::kArcAvailability) ==
- kAvailabilityOfficiallySupportedWithActiveDirectory;
+ // Do not allow for ephemeral data user. cf) b/26402681
+ if (user_manager::UserManager::Get()->IsUserCryptohomeDataEphemeral(
+ user->GetAccountId())) {
+ VLOG(1) << "Users with ephemeral data are not supported in ARC.";
+ return false;
+ }
+
+ return true;
}
bool IsArcOptInVerificationDisabled() {
@@ -111,4 +142,25 @@ bool IsArcOptInVerificationDisabled() {
chromeos::switches::kDisableArcOptInVerification);
}
+bool IsArcAppWindow(aura::Window* window) {
+ if (!window)
+ return false;
+ return window->GetProperty(aura::client::kAppType) ==
+ static_cast<int>(ash::AppType::ARC_APP);
+}
+
+void SetArcCpuRestriction(bool do_restrict) {
+ chromeos::SessionManagerClient* session_manager_client =
+ chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
+ if (!session_manager_client) {
+ LOG(WARNING) << "SessionManagerClient is not available";
+ return;
+ }
+ const login_manager::ContainerCpuRestrictionState state =
+ do_restrict ? login_manager::CONTAINER_CPU_RESTRICTION_BACKGROUND
+ : login_manager::CONTAINER_CPU_RESTRICTION_FOREGROUND;
+ session_manager_client->SetArcCpuRestriction(
+ state, base::Bind(SetArcCpuRestrictionCallback, state));
+}
+
} // namespace arc
diff --git a/chromium/components/arc/arc_util.h b/chromium/components/arc/arc_util.h
index a9e69d36878..d653b5ac43d 100644
--- a/chromium/components/arc/arc_util.h
+++ b/chromium/components/arc/arc_util.h
@@ -9,10 +9,18 @@
// outside of ARC, e.g. CommandLine flag, attribute of global data/state,
// users' preferences, and FeatureList.
+namespace aura {
+class Window;
+} // namespace aura
+
namespace base {
class CommandLine;
} // namespace base
+namespace user_manager {
+class User;
+} // namespace user_manager
+
namespace arc {
// Returns true if ARC is installed and the current device is officially
@@ -58,14 +66,26 @@ void SetArcAvailableCommandLineForTesting(base::CommandLine* command_line);
// should also return true in that case.
bool IsArcKioskMode();
-// Returns true if it is allowed to use ARC with Active Directory managed
-// devices.
-bool IsArcAllowedForActiveDirectoryUsers();
+// Returns true if ARC is allowed for the given user. Note this should not be
+// used as a signal of whether ARC is allowed alone because it only considers
+// user meta data. e.g. a user could be allowed for ARC but if the user signs in
+// as a secondary user or signs in to create a supervised user, ARC should be
+// disabled for such cases.
+bool IsArcAllowedForUser(const user_manager::User* user);
// Checks if opt-in verification was disabled by switch in command line.
// In most cases, it is disabled for testing purpose.
bool IsArcOptInVerificationDisabled();
+// Returns true if the |window|'s aura::client::kAppType is ARC_APP. When
+// |window| is nullptr, returns false.
+bool IsArcAppWindow(aura::Window* window);
+
+// Adjusts the amount of CPU the ARC instance is allowed to use. When
+// |do_restrict| is true, the limit is adjusted so ARC can only use tightly
+// restricted CPU resources.
+void SetArcCpuRestriction(bool do_restrict);
+
} // namespace arc
#endif // COMPONENTS_ARC_ARC_UTIL_H_
diff --git a/chromium/components/arc/arc_util_unittest.cc b/chromium/components/arc/arc_util_unittest.cc
index a39c92bbc15..0a52662a614 100644
--- a/chromium/components/arc/arc_util_unittest.cc
+++ b/chromium/components/arc/arc_util_unittest.cc
@@ -7,11 +7,18 @@
#include <memory>
#include <string>
+#include "ash/shared/app_types.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/test/scoped_feature_list.h"
+#include "components/signin/core/account_id/account_id.h"
+#include "components/user_manager/fake_user_manager.h"
+#include "components/user_manager/user.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/window.h"
namespace arc {
namespace {
@@ -35,6 +42,44 @@ class ScopedArcFeature {
DISALLOW_COPY_AND_ASSIGN(ScopedArcFeature);
};
+// Helper to enable user_manager::FakeUserManager while it is in scope.
+// TODO(xiyuan): Remove after ScopedUserManagerEnabler is moved to user_manager.
+class ScopedUserManager {
+ public:
+ explicit ScopedUserManager(user_manager::UserManager* user_manager)
+ : user_manager_(user_manager) {
+ DCHECK(!user_manager::UserManager::IsInitialized());
+ user_manager->Initialize();
+ }
+ ~ScopedUserManager() {
+ DCHECK_EQ(user_manager::UserManager::Get(), user_manager_);
+ user_manager_->Shutdown();
+ user_manager_->Destroy();
+ }
+
+ private:
+ user_manager::UserManager* const user_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedUserManager);
+};
+
+// Fake user that can be created with a specified type.
+class FakeUser : public user_manager::User {
+ public:
+ explicit FakeUser(user_manager::UserType user_type)
+ : User(AccountId::FromUserEmail("user@test.com")),
+ user_type_(user_type) {}
+ ~FakeUser() override = default;
+
+ // user_manager::User:
+ user_manager::UserType GetType() const override { return user_type_; }
+
+ private:
+ const user_manager::UserType user_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeUser);
+};
+
using ArcUtilTest = testing::Test;
TEST_F(ArcUtilTest, IsArcAvailable_None) {
@@ -129,27 +174,6 @@ TEST_F(ArcUtilTest, IsArcAvailable_OfficiallySupported) {
EXPECT_TRUE(IsArcKioskAvailable());
}
-TEST_F(ArcUtilTest, IsArcAvailable_OfficiallySupportedWithActiveDirectory) {
- // Regardless of FeatureList, IsArcAvailable() should return true.
- auto* command_line = base::CommandLine::ForCurrentProcess();
- command_line->InitFromArgv(
- {"", "--arc-availability=officially-supported-with-active-directory"});
- EXPECT_TRUE(IsArcAvailable());
-}
-
-TEST_F(ArcUtilTest, IsArcAllowedForActiveDirectoryUsers_Allowed) {
- auto* command_line = base::CommandLine::ForCurrentProcess();
- command_line->InitFromArgv(
- {"", "--arc-availability=officially-supported-with-active-directory"});
- EXPECT_TRUE(IsArcAllowedForActiveDirectoryUsers());
-}
-
-TEST_F(ArcUtilTest, IsArcAllowedForActiveDirectoryUsers_NotAllowed) {
- auto* command_line = base::CommandLine::ForCurrentProcess();
- command_line->InitFromArgv({"", "--arc-availability=officially-supported"});
- EXPECT_FALSE(IsArcAllowedForActiveDirectoryUsers());
-}
-
// TODO(hidehiko): Add test for IsArcKioskMode().
// It depends on UserManager, but a utility to inject fake instance is
// available only in chrome/. To use it in components/, refactoring is needed.
@@ -163,5 +187,57 @@ TEST_F(ArcUtilTest, IsArcOptInVerificationDisabled) {
EXPECT_TRUE(IsArcOptInVerificationDisabled());
}
+TEST_F(ArcUtilTest, IsArcAppWindow) {
+ std::unique_ptr<aura::Window> window(
+ aura::test::CreateTestWindowWithId(0, nullptr));
+ EXPECT_FALSE(IsArcAppWindow(window.get()));
+
+ window->SetProperty(aura::client::kAppType,
+ static_cast<int>(ash::AppType::CHROME_APP));
+ EXPECT_FALSE(IsArcAppWindow(window.get()));
+ window->SetProperty(aura::client::kAppType,
+ static_cast<int>(ash::AppType::ARC_APP));
+ EXPECT_TRUE(IsArcAppWindow(window.get()));
+
+ EXPECT_FALSE(IsArcAppWindow(nullptr));
+}
+
+TEST_F(ArcUtilTest, IsArcAllowedForUser) {
+ user_manager::FakeUserManager fake_user_manager;
+ ScopedUserManager scoped_user_manager(&fake_user_manager);
+
+ struct {
+ user_manager::UserType user_type;
+ bool expected_allowed;
+ } const kTestCases[] = {
+ {user_manager::USER_TYPE_REGULAR, true},
+ {user_manager::USER_TYPE_GUEST, false},
+ {user_manager::USER_TYPE_PUBLIC_ACCOUNT, false},
+ {user_manager::USER_TYPE_SUPERVISED, false},
+ {user_manager::USER_TYPE_KIOSK_APP, false},
+ {user_manager::USER_TYPE_CHILD, true},
+ {user_manager::USER_TYPE_ARC_KIOSK_APP, true},
+ {user_manager::USER_TYPE_ACTIVE_DIRECTORY, true},
+ };
+ for (const auto& test_case : kTestCases) {
+ const FakeUser user(test_case.user_type);
+ EXPECT_EQ(test_case.expected_allowed, IsArcAllowedForUser(&user))
+ << "User type=" << test_case.user_type;
+ }
+
+ // An ephemeral user is a logged in user but unknown to UserManager when
+ // ephemeral policy is set.
+ fake_user_manager.SetEphemeralUsersEnabled(true);
+ fake_user_manager.UserLoggedIn(AccountId::FromUserEmail("test@test.com"),
+ "test@test.com-hash", false);
+ const user_manager::User* ephemeral_user = fake_user_manager.GetActiveUser();
+ ASSERT_TRUE(ephemeral_user);
+ ASSERT_TRUE(fake_user_manager.IsUserCryptohomeDataEphemeral(
+ ephemeral_user->GetAccountId()));
+
+ // Ephemeral user is not allowed for ARC.
+ EXPECT_FALSE(IsArcAllowedForUser(ephemeral_user));
+}
+
} // namespace
} // namespace arc
diff --git a/chromium/components/arc/bitmap/bitmap_struct_traits.cc b/chromium/components/arc/bitmap/bitmap_struct_traits.cc
index 51aa30f44f0..c289a5cceca 100644
--- a/chromium/components/arc/bitmap/bitmap_struct_traits.cc
+++ b/chromium/components/arc/bitmap/bitmap_struct_traits.cc
@@ -30,7 +30,9 @@ bool StructTraits<arc::mojom::ArcBitmapDataView, SkBitmap>::
}
// Copy the pixels with converting color type.
- return bitmap.copyTo(out, kN32_SkColorType);
+ SkImageInfo image_info = info.makeColorType(kN32_SkColorType);
+ return out->tryAllocPixels(image_info) &&
+ bitmap.readPixels(image_info, out->getPixels(), out->rowBytes(), 0, 0);
}
} // namespace mojo
diff --git a/chromium/components/arc/bluetooth/arc_bluetooth_bridge.cc b/chromium/components/arc/bluetooth/arc_bluetooth_bridge.cc
index 97bca580d12..b63042df3eb 100644
--- a/chromium/components/arc/bluetooth/arc_bluetooth_bridge.cc
+++ b/chromium/components/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -251,12 +251,12 @@ namespace arc {
ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service)
: ArcService(bridge_service), binding_(this), weak_factory_(this) {
- if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
+ if (BluetoothAdapterFactory::IsBluetoothSupported()) {
VLOG(1) << "Registering bluetooth adapter.";
BluetoothAdapterFactory::GetAdapter(base::Bind(
&ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr()));
} else {
- VLOG(1) << "No bluetooth adapter available.";
+ VLOG(1) << "Bluetooth not supported.";
}
arc_bridge_service()->bluetooth()->AddObserver(this);
}
diff --git a/chromium/components/arc/common/accessibility_helper.mojom b/chromium/components/arc/common/accessibility_helper.mojom
index d80b7355993..f3651b2356a 100644
--- a/chromium/components/arc/common/accessibility_helper.mojom
+++ b/chromium/components/arc/common/accessibility_helper.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Next MinVersion: 2
+// Next MinVersion: 3
module arc.mojom;
@@ -137,12 +137,13 @@ enum AccessibilityIntListProperty {
// AccessibilityNodeInfo in Android.
// https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html
struct AccessibilityNodeInfoData {
- ScreenRect boundsInScreen;
+ ScreenRect bounds_in_screen;
[MinVersion=1]int32 id;
- [MinVersion=1]map<AccessibilityBooleanProperty, bool>? booleanProperties;
- [MinVersion=1]map<AccessibilityStringProperty, string>? stringProperties;
- [MinVersion=1]map<AccessibilityIntProperty, int32>? intProperties;
- [MinVersion=1]map<AccessibilityIntListProperty, array<int32>>? intListProperties;
+ [MinVersion=1]map<AccessibilityBooleanProperty, bool>? boolean_properties;
+ [MinVersion=1]map<AccessibilityStringProperty, string>? string_properties;
+ [MinVersion=1]map<AccessibilityIntProperty, int32>? int_properties;
+ [MinVersion=1]
+ map<AccessibilityIntListProperty, array<int32>>? int_list_properties;
};
// Filters the event type (and implicitly the data) sent by the ARC
@@ -156,26 +157,29 @@ enum AccessibilityFilterType {
FOCUS,
// Send a complete tree from the event source's root for every event.
- ALL
+ ALL,
+
+ // Send complete subtrees for root nodes with whitelisted package names.
+ [MinVersion=2]WHITELISTED_PACKAGE_NAME
};
// AccessibilityEventData is a struct to contain info of
// AccessibilityEvent in Android.
// https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html
struct AccessibilityEventData {
- AccessibilityEventType eventType;
- int32 sourceId;
- array<AccessibilityNodeInfoData> nodeData;
+ AccessibilityEventType event_type;
+ int32 source_id;
+ array<AccessibilityNodeInfoData> node_data;
};
// Next method ID: 2
interface AccessibilityHelperHost {
- OnAccessibilityEventDeprecated@0(AccessibilityEventType eventType,
- AccessibilityNodeInfoData? eventSource);
+ OnAccessibilityEventDeprecated@0(AccessibilityEventType event_type,
+ AccessibilityNodeInfoData? event_source);
// OnAccessibilityEvent is called when a converted Android accessibility event
// is sent from Android.
- OnAccessibilityEvent@1(AccessibilityEventData eventData);
+ OnAccessibilityEvent@1(AccessibilityEventData event_data);
};
// Next method ID: 3
@@ -186,5 +190,5 @@ interface AccessibilityHelperInstance {
PerformAction@1(int32 id, AccessibilityActionType action);
// Set a filter on the event types received.
- SetFilter@2(AccessibilityFilterType filterType);
+ SetFilter@2(AccessibilityFilterType filter_type);
};
diff --git a/chromium/components/arc/common/app.mojom b/chromium/components/arc/common/app.mojom
index 5d6045ba2cb..6348d52517e 100644
--- a/chromium/components/arc/common/app.mojom
+++ b/chromium/components/arc/common/app.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Next MinVersion: 19
+// Next MinVersion: 20
module arc.mojom;
@@ -75,7 +75,7 @@ enum ShowPackageInfoPage {
MANAGE_LINKS = 1,
};
-// Next method ID: 17
+// Next method ID: 18
interface AppHost {
// Sends newly added ARC app to Chrome. This message is sent when ARC receives
// package added notification. Multiple apps may be added in the one package.
@@ -122,9 +122,18 @@ interface AppHost {
[MinVersion=13] string? name@3,
[MinVersion=15] string? intent@4);
+ // Sends task label and icon.
+ [MinVersion=19] OnTaskDescriptionUpdated@17(int32 task_id,
+ string label,
+ array<uint8> icon_png_data);
+
// Notifies that task has been destroyed.
[MinVersion=4] OnTaskDestroyed@5(int32 task_id);
+ // Notifies that task requested orientation lock.
+ [MinVersion=12] OnTaskOrientationLockRequested@12(int32 task_id,
+ OrientationLock lock);
+
// Notifies that task has been activated.
[MinVersion=4] OnTaskSetActive@6(int32 task_id);
@@ -145,10 +154,6 @@ interface AppHost {
[MinVersion=16] OnInstallationFinished@15(
[MinVersion=17] InstallationResult? result@1);
- // Notifies that task requested orientation lock.
- [MinVersion=12] OnTaskOrientationLockRequested@12(int32 task_id,
- OrientationLock lock);
-
// Notifies that an application shortcut needs to be deleted. Shortcut is
// defined by its |intent_uri| and |package_name|.
[MinVersion=18] OnUninstallShortcut@16(string package_name,
diff --git a/chromium/components/arc/common/arc_bridge.mojom b/chromium/components/arc/common/arc_bridge.mojom
index c7b308f6094..64e1a1f6fe0 100644
--- a/chromium/components/arc/common/arc_bridge.mojom
+++ b/chromium/components/arc/common/arc_bridge.mojom
@@ -29,12 +29,13 @@ import "storage_manager.mojom";
import "tracing.mojom";
import "tts.mojom";
import "video.mojom";
+import "voice_interaction_arc_home.mojom";
import "voice_interaction_framework.mojom";
import "wallpaper.mojom";
-// Next MinVersion: 24
+// Next MinVersion: 25
// Deprecated method IDs: 101, 105
-// Next method ID: 130
+// Next method ID: 131
interface ArcBridgeHost {
// Keep the entries alphabetical. In order to do so without breaking
// compatibility with the ARC instance, explicitly assign each interface a
@@ -121,6 +122,10 @@ interface ArcBridgeHost {
// Notifies Chrome that the VideoInstance interface is ready.
[MinVersion=6] OnVideoInstanceReady@107(VideoInstance instance_ptr);
+ // Notifies Chrome that the VoiceInteractionArcHomeInstance is ready.
+ [MinVersion=24] OnVoiceInteractionArcHomeInstanceReady@130(
+ VoiceInteractionArcHomeInstance instance_ptr);
+
// Notifies Chrome that the VoiceInteractionFrameworkInstance is ready.
[MinVersion=23] OnVoiceInteractionFrameworkInstanceReady@129(
VoiceInteractionFrameworkInstance instance_ptr);
diff --git a/chromium/components/arc/common/ime.mojom b/chromium/components/arc/common/ime.mojom
index ae6d4e5bb9c..fd945302c3c 100644
--- a/chromium/components/arc/common/ime.mojom
+++ b/chromium/components/arc/common/ime.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Next MinVersion: 5
+// Next MinVersion: 6
module arc.mojom;
@@ -24,6 +24,7 @@ enum TextInputType {
DATETIME,
};
+// TODO(yhanada): Switch to use gfx.mojom.Rect. See crbug.com/723224.
// Represents the text insertion points in the container screen coordinates.
struct CursorRect {
int32 left;
@@ -32,6 +33,16 @@ struct CursorRect {
int32 bottom;
};
+// TODO(yhanada): Switch to use gfx.mojom.Range. See crbug.com/723224.
+// Represents the range in the text. It is an open interval [start, end).
+[MinVersion=5]
+struct TextRange {
+ // Start offset in UTF-16 index.
+ uint32 start;
+ // End offset in UTF-16 index.
+ uint32 end;
+};
+
// Represents a single segment of text currently composed by IME.
struct CompositionSegment {
// Start offset of the segment in UTF-16 index.
@@ -55,6 +66,21 @@ interface ImeHost {
// Show virtual keyboard of Chrome OS if needed.
[MinVersion=2] ShowImeIfNeeded@3();
+
+ // Notifies Chrome that the cursor position has changed and
+ // also sends surrounding text.
+ //
+ // |text_range|, |text_in_range| and |selection_range| are piggy-backed
+ // into this method because Chrome OS IME tries to retrieve these information
+ // synchronously, so we need to update them all at once to keep consistency.
+ [MinVersion=5] OnCursorRectChangedWithSurroundingText@4(
+ CursorRect rect, // The cursor position.
+ TextRange text_range, // The range of |text_in_range| in the current
+ // text in the editor.
+ string text_in_range, // The text around the cursor.
+ TextRange selection_range // The range of the selected text
+ // in the current text in the editor.
+ );
};
// Next method ID: 6
diff --git a/chromium/components/arc/common/ime.typemap b/chromium/components/arc/common/ime.typemap
new file mode 100644
index 00000000000..141f4ad18ce
--- /dev/null
+++ b/chromium/components/arc/common/ime.typemap
@@ -0,0 +1,20 @@
+# Copyright 2017 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.
+
+mojom = "//components/arc/common/ime.mojom"
+public_headers = [
+ "//ui/gfx/geometry/rect.h",
+ "//ui/gfx/range/range.h",
+]
+deps = [
+ "//ui/gfx",
+]
+traits_headers = [ "//components/arc/ime/arc_ime_struct_traits.h" ]
+sources = [
+ "//components/arc/ime/arc_ime_struct_traits.cc",
+]
+type_mappings = [
+ "arc.mojom.CursorRect=::gfx::Rect[move_only]",
+ "arc.mojom.TextRange=::gfx::Range[move_only]",
+]
diff --git a/chromium/components/arc/common/metrics.mojom b/chromium/components/arc/common/metrics.mojom
index cb2e93650e6..d1c997a52a1 100644
--- a/chromium/components/arc/common/metrics.mojom
+++ b/chromium/components/arc/common/metrics.mojom
@@ -1,9 +1,25 @@
// Copyright 2016 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.
+// Next MinVersion: 2
module arc.mojom;
+[Extensible]
+enum BootType {
+ // This is used only for backward compatibility reasons and the value has to
+ // be 0.
+ UNKNOWN = 0,
+
+ // This is for the very first (opt-in) boot.
+ FIRST_BOOT = 1,
+ // This is for the first boot after Chrome OS update which also updates the
+ // ARC image.
+ FIRST_BOOT_AFTER_UPDATE = 2,
+ // This is for a regular boot.
+ REGULAR_BOOT = 3,
+};
+
// Describes a boot progress event.
struct BootProgressEvent {
// Name of the boot progress event in Android. Currently there are
@@ -23,11 +39,14 @@ struct BootProgressEvent {
int64 uptimeMillis;
};
+// Next method ID: 1
interface MetricsHost {
// Report boot progress events from ARC instance.
- ReportBootProgress@0(array<BootProgressEvent> events);
+ ReportBootProgress@0(array<BootProgressEvent> events,
+ [MinVersion=1] BootType boot_type);
};
+// Next method ID: 1
interface MetricsInstance {
Init@0(MetricsHost host_ptr);
};
diff --git a/chromium/components/arc/common/tracing.mojom b/chromium/components/arc/common/tracing.mojom
index e27d89ba0b3..aa1f5a2f3bc 100644
--- a/chromium/components/arc/common/tracing.mojom
+++ b/chromium/components/arc/common/tracing.mojom
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Next MinVersion: 1
+// Next MinVersion: 2
module arc.mojom;
@@ -10,8 +10,11 @@ interface TracingInstance {
// Queries available tracing categories in the container.
QueryAvailableCategories@0() => (array<string> categories);
- // Starts tracing in the container with the given categories.
- StartTracing@1(array<string> categories) => (bool success);
+ // Starts tracing in the container with the given categories. A handle is
+ // passed to the client for sending trace events back to the host. The client
+ // should send trace event as a JSON object in each write.
+ StartTracing@1(array<string> categories,
+ [MinVersion=1] handle? socket) => (bool success);
// Stops tracing in the container.
StopTracing@2() => (bool success);
diff --git a/chromium/components/arc/common/typemaps.gni b/chromium/components/arc/common/typemaps.gni
index c130ddcd185..09a41ef8f28 100644
--- a/chromium/components/arc/common/typemaps.gni
+++ b/chromium/components/arc/common/typemaps.gni
@@ -7,6 +7,7 @@ typemaps = [
"//components/arc/common/bitmap.typemap",
"//components/arc/common/bluetooth.typemap",
"//components/arc/common/file_system.typemap",
+ "//components/arc/common/ime.typemap",
"//components/arc/common/intent_helper.typemap",
"//components/arc/common/video_accelerator.typemap",
]
diff --git a/chromium/components/arc/common/voice_interaction_arc_home.mojom b/chromium/components/arc/common/voice_interaction_arc_home.mojom
new file mode 100644
index 00000000000..37e7b372df8
--- /dev/null
+++ b/chromium/components/arc/common/voice_interaction_arc_home.mojom
@@ -0,0 +1,69 @@
+// Copyright 2017 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.
+//
+// Next MinVersion: 2
+
+module arc.mojom;
+
+import "mojo/common/string16.mojom";
+import "screen_rect.mojom";
+
+// Represents the start and end unicode char indices of the selected
+// portion of the text [start, end).
+struct TextSelection {
+ int32 start_selection;
+ int32 end_selection;
+};
+
+// Represents view structure to be passed to ARC. The view
+// structure is synthesized from the AXStructure, which
+// is a simplified representation of the DOM tree. We
+// map each node of the AXStructure into a view element.
+// The naming convention of the fields kept consistent with
+// AccessibilitySnapshotNode.java used in Android Chromium.
+struct VoiceInteractionStructure {
+ // Geometry of the view in pixels
+ ScreenRect rect;
+
+ // Text of the view.
+ mojo.common.mojom.String16 text;
+
+ // Text properties
+ float text_size;
+ int32 color;
+ int32 bgcolor;
+ bool bold;
+ bool italic;
+ bool underline;
+ bool line_through;
+
+ // Selected portion of the text.
+ TextSelection? selection;
+
+ // Fake Android view class name of the element. Each node is assigned
+ // a closest approximation of Android's views.
+ string class_name;
+
+ // Children of current node
+ array<VoiceInteractionStructure> children;
+};
+
+// Handles voice interaction queries from Android.
+// Next method ID: 3
+interface VoiceInteractionArcHomeHost {
+ // Returns view hierarchy of current window represented as
+ // VoiceInteractionStructure. Returns empty if the request
+ // fails.
+ GetVoiceInteractionStructure@1() => (VoiceInteractionStructure? structure);
+
+ // Notifies VoiceInteractionArcHomeHost that voice interaction OOBE setup
+ // is done.
+ [MinVersion=1] OnVoiceInteractionOobeSetupComplete@2();
+};
+
+// Connects with ArcHome.
+// Next method ID: 1
+interface VoiceInteractionArcHomeInstance {
+ Init@0(VoiceInteractionArcHomeHost host_ptr);
+};
diff --git a/chromium/components/arc/common/voice_interaction_framework.mojom b/chromium/components/arc/common/voice_interaction_framework.mojom
index adf25f4bd92..88ac74cfe4a 100644
--- a/chromium/components/arc/common/voice_interaction_framework.mojom
+++ b/chromium/components/arc/common/voice_interaction_framework.mojom
@@ -2,25 +2,33 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Next MinVersion: 2
+// Next MinVersion: 4
module arc.mojom;
import "screen_rect.mojom";
// Handles voice interaction queries from Android.
-// Next method ID: 2
+// Next method ID: 4
interface VoiceInteractionFrameworkHost {
// Returns a screenshot of currently focused window or empty array if
- // no window is focused.
- CaptureFocusedWindow@0() => (array<uint8> png_data);
+ // no window is focused. |data| represents the image encoded in JPEG
+ // format.
+ CaptureFocusedWindow@0() => (array<uint8> data);
// Returns a fullscreen screenshot of the primary display.
- [MinVersion=1]CaptureFullscreen@1() => (array<uint8> png_data);
+ // |data| represents the image encoded in JPEG format.
+ [MinVersion=1]CaptureFullscreen@1() => (array<uint8> data);
+
+ // Notifies the host that the metalayer has closed or could not open.
+ [MinVersion=2]OnMetalayerClosed@2();
+
+ // Enables/disables screenshot taking.
+ [MinVersion=3]SetMetalayerEnabled@3(bool enabled);
};
// Connects with Android system server.
-// Next method ID:4
+// Next method ID: 4
interface VoiceInteractionFrameworkInstance {
Init@0(VoiceInteractionFrameworkHost host_ptr);
@@ -31,6 +39,6 @@ interface VoiceInteractionFrameworkInstance {
// selected.
[MinVersion=1] StartVoiceInteractionSessionForRegion@2(ScreenRect region);
- // Toggles the metalayer.
- [MinVersion=1] ToggleMetalayer@3();
+ // Shows/hides the metalayer in the container.
+ [MinVersion=1] SetMetalayerVisibility@3([MinVersion=2] bool visible);
};
diff --git a/chromium/components/arc/ime/OWNERS b/chromium/components/arc/ime/OWNERS
new file mode 100644
index 00000000000..bb6511619b7
--- /dev/null
+++ b/chromium/components/arc/ime/OWNERS
@@ -0,0 +1,2 @@
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/arc/ime/arc_ime_bridge.h b/chromium/components/arc/ime/arc_ime_bridge.h
index 1ed11869fcd..cb8f220bd6f 100644
--- a/chromium/components/arc/ime/arc_ime_bridge.h
+++ b/chromium/components/arc/ime/arc_ime_bridge.h
@@ -10,6 +10,7 @@
#include "ui/base/ime/text_input_type.h"
namespace gfx {
+class Range;
class Rect;
} // namespace gfx
@@ -32,6 +33,11 @@ class ArcImeBridge {
virtual void OnCursorRectChanged(const gfx::Rect& rect) = 0;
virtual void OnCancelComposition() = 0;
virtual void ShowImeIfNeeded() = 0;
+ virtual void OnCursorRectChangedWithSurroundingText(
+ const gfx::Rect& rect,
+ const gfx::Range& text_range,
+ const base::string16& text_in_range,
+ const gfx::Range& selection_range) = 0;
};
// Serializes and sends IME related requests through IPCs.
diff --git a/chromium/components/arc/ime/arc_ime_bridge_impl.cc b/chromium/components/arc/ime/arc_ime_bridge_impl.cc
index 13d787ef5ec..99abcd0a14a 100644
--- a/chromium/components/arc/ime/arc_ime_bridge_impl.cc
+++ b/chromium/components/arc/ime/arc_ime_bridge_impl.cc
@@ -141,10 +141,8 @@ void ArcImeBridgeImpl::OnTextInputTypeChanged(mojom::TextInputType type) {
delegate_->OnTextInputTypeChanged(ConvertTextInputType(type));
}
-void ArcImeBridgeImpl::OnCursorRectChanged(mojom::CursorRectPtr rect) {
- delegate_->OnCursorRectChanged(gfx::Rect(rect->left, rect->top,
- rect->right - rect->left,
- rect->bottom - rect->top));
+void ArcImeBridgeImpl::OnCursorRectChanged(gfx::Rect rect) {
+ delegate_->OnCursorRectChanged(rect);
}
void ArcImeBridgeImpl::OnCancelComposition() {
@@ -155,4 +153,13 @@ void ArcImeBridgeImpl::ShowImeIfNeeded() {
delegate_->ShowImeIfNeeded();
}
+void ArcImeBridgeImpl::OnCursorRectChangedWithSurroundingText(
+ gfx::Rect rect,
+ gfx::Range text_range,
+ const std::string& text_in_range,
+ gfx::Range selection_range) {
+ delegate_->OnCursorRectChangedWithSurroundingText(
+ rect, text_range, base::UTF8ToUTF16(text_in_range), selection_range);
+}
+
} // namespace arc
diff --git a/chromium/components/arc/ime/arc_ime_bridge_impl.h b/chromium/components/arc/ime/arc_ime_bridge_impl.h
index 548a8dacf09..8ae063211e5 100644
--- a/chromium/components/arc/ime/arc_ime_bridge_impl.h
+++ b/chromium/components/arc/ime/arc_ime_bridge_impl.h
@@ -43,9 +43,14 @@ class ArcImeBridgeImpl : public ArcImeBridge,
// mojom::ImeHost overrides:
void OnTextInputTypeChanged(mojom::TextInputType type) override;
- void OnCursorRectChanged(mojom::CursorRectPtr rect) override;
+ void OnCursorRectChanged(gfx::Rect rect) override;
void OnCancelComposition() override;
void ShowImeIfNeeded() override;
+ void OnCursorRectChangedWithSurroundingText(
+ gfx::Rect rect,
+ gfx::Range text_range,
+ const std::string& text_in_range,
+ gfx::Range selection_range) override;
private:
mojo::Binding<mojom::ImeHost> binding_;
diff --git a/chromium/components/arc/ime/arc_ime_service.cc b/chromium/components/arc/ime/arc_ime_service.cc
index 9259f31aad2..3ce001364a9 100644
--- a/chromium/components/arc/ime/arc_ime_service.cc
+++ b/chromium/components/arc/ime/arc_ime_service.cc
@@ -18,6 +18,7 @@
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_codes.h"
+#include "ui/gfx/range/range.h"
namespace arc {
@@ -209,6 +210,7 @@ void ArcImeService::OnTextInputTypeChanged(ui::TextInputType type) {
}
void ArcImeService::OnCursorRectChanged(const gfx::Rect& rect) {
+ InvalidateSurroundingTextAndSelectionRange();
if (cursor_rect_ == rect)
return;
cursor_rect_ = rect;
@@ -219,6 +221,7 @@ void ArcImeService::OnCursorRectChanged(const gfx::Rect& rect) {
}
void ArcImeService::OnCancelComposition() {
+ InvalidateSurroundingTextAndSelectionRange();
ui::InputMethod* const input_method = GetInputMethod();
if (input_method)
input_method->CancelComposition(this);
@@ -231,6 +234,24 @@ void ArcImeService::ShowImeIfNeeded() {
}
}
+void ArcImeService::OnCursorRectChangedWithSurroundingText(
+ const gfx::Rect& rect,
+ const gfx::Range& text_range,
+ const base::string16& text_in_range,
+ const gfx::Range& selection_range) {
+ text_range_ = text_range;
+ text_in_range_ = text_in_range;
+ selection_range_ = selection_range;
+
+ if (cursor_rect_ == rect)
+ return;
+ cursor_rect_ = rect;
+
+ ui::InputMethod* const input_method = GetInputMethod();
+ if (input_method)
+ input_method->OnCaretBoundsChanged(this);
+}
+
////////////////////////////////////////////////////////////////////////////////
// Overridden from keyboard::KeyboardControllerObserver
void ArcImeService::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) {
@@ -250,16 +271,19 @@ void ArcImeService::OnKeyboardClosed() {}
void ArcImeService::SetCompositionText(
const ui::CompositionText& composition) {
+ InvalidateSurroundingTextAndSelectionRange();
has_composition_text_ = !composition.text.empty();
ime_bridge_->SendSetCompositionText(composition);
}
void ArcImeService::ConfirmCompositionText() {
+ InvalidateSurroundingTextAndSelectionRange();
has_composition_text_ = false;
ime_bridge_->SendConfirmCompositionText();
}
void ArcImeService::ClearCompositionText() {
+ InvalidateSurroundingTextAndSelectionRange();
if (has_composition_text_) {
has_composition_text_ = false;
ime_bridge_->SendInsertText(base::string16());
@@ -267,6 +291,7 @@ void ArcImeService::ClearCompositionText() {
}
void ArcImeService::InsertText(const base::string16& text) {
+ InvalidateSurroundingTextAndSelectionRange();
has_composition_text_ = false;
ime_bridge_->SendInsertText(text);
}
@@ -278,6 +303,8 @@ void ArcImeService::InsertChar(const ui::KeyEvent& event) {
if (ime_type_ == ui::TEXT_INPUT_TYPE_NONE)
return;
+ InvalidateSurroundingTextAndSelectionRange();
+
// For apps that doesn't handle hardware keyboard events well, keys that are
// typically on software keyboard and lack of them are fatal, namely,
// unmodified enter and backspace keys are sent through IME.
@@ -337,6 +364,32 @@ gfx::Rect ArcImeService::GetCaretBounds() const {
return converted;
}
+bool ArcImeService::GetTextRange(gfx::Range* range) const {
+ if (!text_range_.IsValid())
+ return false;
+ *range = text_range_;
+ return true;
+}
+
+bool ArcImeService::GetSelectionRange(gfx::Range* range) const {
+ if (!selection_range_.IsValid())
+ return false;
+ *range = selection_range_;
+ return true;
+}
+
+bool ArcImeService::GetTextFromRange(const gfx::Range& range,
+ base::string16* text) const {
+ // It's supposed that this method is called only from
+ // InputMethod::OnCaretBoundsChanged(). In that method, the range obtained
+ // from GetTextRange() is used as the argument of this method. To prevent an
+ // unexpected usage, the check, |range != text_range_|, is added.
+ if (!text_range_.IsValid() || range != text_range_)
+ return false;
+ *text = text_in_range_;
+ return true;
+}
+
ui::TextInputMode ArcImeService::GetTextInputMode() const {
return ui::TEXT_INPUT_MODE_DEFAULT;
}
@@ -346,6 +399,7 @@ base::i18n::TextDirection ArcImeService::GetTextDirection() const {
}
void ArcImeService::ExtendSelectionAndDelete(size_t before, size_t after) {
+ InvalidateSurroundingTextAndSelectionRange();
ime_bridge_->SendExtendSelectionAndDelete(before, after);
}
@@ -366,18 +420,10 @@ bool ArcImeService::HasCompositionText() const {
return has_composition_text_;
}
-bool ArcImeService::GetTextRange(gfx::Range* range) const {
- return false;
-}
-
bool ArcImeService::GetCompositionTextRange(gfx::Range* range) const {
return false;
}
-bool ArcImeService::GetSelectionRange(gfx::Range* range) const {
- return false;
-}
-
bool ArcImeService::SetSelectionRange(const gfx::Range& range) {
return false;
}
@@ -386,11 +432,6 @@ bool ArcImeService::DeleteRange(const gfx::Range& range) {
return false;
}
-bool ArcImeService::GetTextFromRange(
- const gfx::Range& range, base::string16* text) const {
- return false;
-}
-
bool ArcImeService::ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) {
return false;
@@ -401,4 +442,10 @@ bool ArcImeService::IsTextEditCommandEnabled(
return false;
}
+void ArcImeService::InvalidateSurroundingTextAndSelectionRange() {
+ text_range_ = gfx::Range::InvalidRange();
+ text_in_range_ = base::string16();
+ selection_range_ = gfx::Range::InvalidRange();
+}
+
} // namespace arc
diff --git a/chromium/components/arc/ime/arc_ime_service.h b/chromium/components/arc/ime/arc_ime_service.h
index 8fc29e38c04..8ffae1f0205 100644
--- a/chromium/components/arc/ime/arc_ime_service.h
+++ b/chromium/components/arc/ime/arc_ime_service.h
@@ -80,6 +80,11 @@ class ArcImeService : public ArcService,
void OnCursorRectChanged(const gfx::Rect& rect) override;
void OnCancelComposition() override;
void ShowImeIfNeeded() override;
+ void OnCursorRectChangedWithSurroundingText(
+ const gfx::Rect& rect,
+ const gfx::Range& text_range,
+ const base::string16& text_in_range,
+ const gfx::Range& selection_range) override;
// Overridden from keyboard::KeyboardControllerObserver.
void OnKeyboardBoundsChanging(const gfx::Rect& rect) override;
@@ -93,6 +98,10 @@ class ArcImeService : public ArcService,
void InsertChar(const ui::KeyEvent& event) override;
ui::TextInputType GetTextInputType() const override;
gfx::Rect GetCaretBounds() const override;
+ bool GetTextRange(gfx::Range* range) const override;
+ bool GetSelectionRange(gfx::Range* range) const override;
+ bool GetTextFromRange(const gfx::Range& range,
+ base::string16* text) const override;
// Overridden from ui::TextInputClient (with default implementation):
// TODO(kinaba): Support each of these methods to the extent possible in
@@ -104,13 +113,9 @@ class ArcImeService : public ArcService,
bool GetCompositionCharacterBounds(uint32_t index,
gfx::Rect* rect) const override;
bool HasCompositionText() const override;
- bool GetTextRange(gfx::Range* range) const override;
bool GetCompositionTextRange(gfx::Range* range) const override;
- bool GetSelectionRange(gfx::Range* range) const override;
bool SetSelectionRange(const gfx::Range& range) override;
bool DeleteRange(const gfx::Range& range) override;
- bool GetTextFromRange(const gfx::Range& range,
- base::string16* text) const override;
void OnInputMethodChanged() override {}
bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) override;
@@ -123,11 +128,16 @@ class ArcImeService : public ArcService,
private:
ui::InputMethod* GetInputMethod();
+ void InvalidateSurroundingTextAndSelectionRange();
+
std::unique_ptr<ArcImeBridge> ime_bridge_;
std::unique_ptr<ArcWindowDelegate> arc_window_delegate_;
ui::TextInputType ime_type_;
gfx::Rect cursor_rect_;
bool has_composition_text_;
+ gfx::Range text_range_;
+ base::string16 text_in_range_;
+ gfx::Range selection_range_;
aura::Window* focused_arc_window_ = nullptr;
diff --git a/chromium/components/arc/ime/arc_ime_service_unittest.cc b/chromium/components/arc/ime/arc_ime_service_unittest.cc
index ad1c52228d0..b141a3c3a4b 100644
--- a/chromium/components/arc/ime/arc_ime_service_unittest.cc
+++ b/chromium/components/arc/ime/arc_ime_service_unittest.cc
@@ -265,4 +265,29 @@ TEST_F(ArcImeServiceTest, WindowFocusTracking) {
EXPECT_EQ(2, fake_input_method_->count_set_focused_text_input_client());
}
+TEST_F(ArcImeServiceTest, GetTextFromRange) {
+ instance_->OnWindowFocused(arc_win_.get(), nullptr);
+
+ const base::string16 text = base::ASCIIToUTF16("abcdefghijklmn");
+ // Assume the cursor is between 'c' and 'd'.
+ const uint32_t cursor_pos = 3;
+ const gfx::Range text_range(cursor_pos - 1, cursor_pos + 1);
+ const base::string16 text_in_range = text.substr(cursor_pos - 1, 2);
+ const gfx::Range selection_range(cursor_pos, cursor_pos);
+
+ instance_->OnCursorRectChangedWithSurroundingText(
+ gfx::Rect(0, 0, 1, 1), text_range, text_in_range, selection_range);
+
+ gfx::Range temp;
+ instance_->GetTextRange(&temp);
+ EXPECT_EQ(text_range, temp);
+
+ base::string16 temp_str;
+ instance_->GetTextFromRange(text_range, &temp_str);
+ EXPECT_EQ(text_in_range, temp_str);
+
+ instance_->GetSelectionRange(&temp);
+ EXPECT_EQ(selection_range, temp);
+}
+
} // namespace arc
diff --git a/chromium/components/arc/ime/arc_ime_struct_traits.cc b/chromium/components/arc/ime/arc_ime_struct_traits.cc
new file mode 100644
index 00000000000..b3ca64ac47e
--- /dev/null
+++ b/chromium/components/arc/ime/arc_ime_struct_traits.cc
@@ -0,0 +1,27 @@
+// Copyright 2017 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/arc/ime/arc_ime_struct_traits.h"
+
+namespace mojo {
+
+bool StructTraits<arc::mojom::CursorRectDataView, gfx::Rect>::Read(
+ arc::mojom::CursorRectDataView data,
+ gfx::Rect* out) {
+ out->set_x(data.left());
+ out->set_y(data.top());
+ out->set_width(data.right() - out->x());
+ out->set_height(data.bottom() - out->y());
+ return true;
+}
+
+bool StructTraits<arc::mojom::TextRangeDataView, gfx::Range>::Read(
+ arc::mojom::TextRangeDataView data,
+ gfx::Range* out) {
+ out->set_start(data.start());
+ out->set_end(data.end());
+ return true;
+}
+
+} // namespace mojo
diff --git a/chromium/components/arc/ime/arc_ime_struct_traits.h b/chromium/components/arc/ime/arc_ime_struct_traits.h
new file mode 100644
index 00000000000..91a7addffde
--- /dev/null
+++ b/chromium/components/arc/ime/arc_ime_struct_traits.h
@@ -0,0 +1,33 @@
+// Copyright 2017 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_ARC_IME_ARC_IME_STRUCT_TRAITS_H_
+#define COMPONENTS_ARC_IME_ARC_IME_STRUCT_TRAITS_H_
+
+#include "components/arc/common/ime.mojom.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<arc::mojom::CursorRectDataView, gfx::Rect> {
+ static int32_t left(const gfx::Rect& r) { return r.x(); }
+ static int32_t top(const gfx::Rect& r) { return r.y(); }
+ static int32_t right(const gfx::Rect& r) { return r.right(); }
+ static int32_t bottom(const gfx::Rect& r) { return r.bottom(); }
+
+ static bool Read(arc::mojom::CursorRectDataView data, gfx::Rect* out);
+};
+
+template <>
+struct StructTraits<arc::mojom::TextRangeDataView, gfx::Range> {
+ static uint32_t start(const gfx::Range& r) { return r.start(); }
+ static uint32_t end(const gfx::Range& r) { return r.end(); }
+
+ static bool Read(arc::mojom::TextRangeDataView data, gfx::Range* out);
+};
+
+} // namespace mojo
+
+#endif // COMPONENTS_ARC_IME_ARC_IME_STRUCT_TRAITS_H_
diff --git a/chromium/components/arc/metrics/arc_metrics_service.cc b/chromium/components/arc/metrics/arc_metrics_service.cc
index 2f391c59838..52867ee63f3 100644
--- a/chromium/components/arc/metrics/arc_metrics_service.cc
+++ b/chromium/components/arc/metrics/arc_metrics_service.cc
@@ -8,23 +8,43 @@
#include <utility>
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "components/arc/arc_bridge_service.h"
+namespace arc {
+
namespace {
-const int kRequestProcessListPeriodInMinutes = 5;
-const char kArcProcessNamePrefix[] = "org.chromium.arc.";
-const char kGmsProcessNamePrefix[] = "com.google.android.gms";
-const char kBootProgressEnableScreen[] = "boot_progress_enable_screen";
+constexpr base::TimeDelta kUmaMinTime = base::TimeDelta::FromMilliseconds(1);
+constexpr int kUmaNumBuckets = 50;
+
+constexpr base::TimeDelta kRequestProcessListPeriod =
+ base::TimeDelta::FromMinutes(5);
+constexpr char kArcProcessNamePrefix[] = "org.chromium.arc.";
+constexpr char kGmsProcessNamePrefix[] = "com.google.android.gms";
+constexpr char kBootProgressEnableScreen[] = "boot_progress_enable_screen";
+
+std::string BootTypeToString(mojom::BootType boot_type) {
+ switch (boot_type) {
+ case mojom::BootType::UNKNOWN:
+ return ""; // for backward compatibility.
+ case mojom::BootType::FIRST_BOOT:
+ return ".FirstBoot";
+ case mojom::BootType::FIRST_BOOT_AFTER_UPDATE:
+ return ".FirstBootAfterUpdate";
+ case mojom::BootType::REGULAR_BOOT:
+ return ".RegularBoot";
+ }
+ NOTREACHED();
+ return "";
+}
} // namespace
-namespace arc {
-
ArcMetricsService::ArcMetricsService(ArcBridgeService* bridge_service)
: ArcService(bridge_service),
binding_(this),
@@ -64,9 +84,8 @@ void ArcMetricsService::OnInstanceClosed() {
void ArcMetricsService::OnProcessInstanceReady() {
VLOG(2) << "Start updating process list.";
- timer_.Start(FROM_HERE,
- base::TimeDelta::FromMinutes(kRequestProcessListPeriodInMinutes),
- this, &ArcMetricsService::RequestProcessList);
+ timer_.Start(FROM_HERE, kRequestProcessListPeriod, this,
+ &ArcMetricsService::RequestProcessList);
}
void ArcMetricsService::OnProcessInstanceClosed() {
@@ -136,26 +155,30 @@ void ArcMetricsService::OnArcStartTimeRetrieved(
}
void ArcMetricsService::ReportBootProgress(
- std::vector<mojom::BootProgressEventPtr> events) {
+ std::vector<mojom::BootProgressEventPtr> events,
+ mojom::BootType boot_type) {
DCHECK(CalledOnValidThread());
+ // TODO(yusukes): Return immediately with with LOG(ERROR) when |boot_type| is
+ // UNKNOWN. Once the container is updated, we'll never see the boot type.
int64_t arc_start_time_in_ms =
(arc_start_time_ - base::TimeTicks()).InMilliseconds();
+ const std::string suffix = BootTypeToString(boot_type);
+ // TODO(yusukes): Define kUmaMaxTime and always use 60s.
+ const base::TimeDelta max_time = base::TimeDelta::FromSeconds(
+ boot_type == mojom::BootType::UNKNOWN ? 30 : 60);
for (const auto& event : events) {
VLOG(2) << "Report boot progress event:" << event->event << "@"
<< event->uptimeMillis;
- std::string title = "Arc." + event->event;
- base::TimeDelta elapsed_time = base::TimeDelta::FromMilliseconds(
+ const std::string name = "Arc." + event->event + suffix;
+ const base::TimeDelta elapsed_time = base::TimeDelta::FromMilliseconds(
event->uptimeMillis - arc_start_time_in_ms);
- // Note: This leaks memory, which is expected behavior.
- base::HistogramBase* histogram = base::Histogram::FactoryTimeGet(
- title, base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromSeconds(30), 50,
- base::HistogramBase::kUmaTargetedHistogramFlag);
- histogram->AddTime(elapsed_time);
- if (event->event.compare(kBootProgressEnableScreen) == 0)
- UMA_HISTOGRAM_CUSTOM_TIMES("Arc.AndroidBootTime", elapsed_time,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromSeconds(30), 50);
+ base::UmaHistogramCustomTimes(name, elapsed_time, kUmaMinTime, max_time,
+ kUmaNumBuckets);
+ if (event->event.compare(kBootProgressEnableScreen) == 0) {
+ base::UmaHistogramCustomTimes("Arc.AndroidBootTime" + suffix,
+ elapsed_time, kUmaMinTime, max_time,
+ kUmaNumBuckets);
+ }
}
}
diff --git a/chromium/components/arc/metrics/arc_metrics_service.h b/chromium/components/arc/metrics/arc_metrics_service.h
index df591222c82..5395dddef87 100644
--- a/chromium/components/arc/metrics/arc_metrics_service.h
+++ b/chromium/components/arc/metrics/arc_metrics_service.h
@@ -39,8 +39,8 @@ class ArcMetricsService
void OnProcessInstanceClosed();
// MetricsHost overrides.
- void ReportBootProgress(
- std::vector<mojom::BootProgressEventPtr> events) override;
+ void ReportBootProgress(std::vector<mojom::BootProgressEventPtr> events,
+ mojom::BootType boot_type) override;
private:
bool CalledOnValidThread();
diff --git a/chromium/components/autofill/android/java/res/values/colors.xml b/chromium/components/autofill/android/java/res/values/colors.xml
index 8b10dd3af7b..cf4d73bd5a9 100644
--- a/chromium/components/autofill/android/java/res/values/colors.xml
+++ b/chromium/components/autofill/android/java/res/values/colors.xml
@@ -5,7 +5,9 @@
found in the LICENSE file.
-->
<resources>
- <!-- Text colors of warning messages for credit card and password forms. -->
+ <!-- Text colors of warning messages for credit card and password forms. -->
<color name="http_bad_warning_message_text">#C53929</color>
<color name="insecure_context_payment_disabled_message_text">#646464</color>
+
+ <color name="keyboard_accessory_hint_icon">#4285F4</color>
</resources>
diff --git a/chromium/components/autofill/android/java/res/values/dimens.xml b/chromium/components/autofill/android/java/res/values/dimens.xml
index 82d8c5e07c2..0dd6985bd4a 100644
--- a/chromium/components/autofill/android/java/res/values/dimens.xml
+++ b/chromium/components/autofill/android/java/res/values/dimens.xml
@@ -15,6 +15,7 @@
<dimen name="keyboard_accessory_height">48dp</dimen>
<dimen name="keyboard_accessory_padding">8dp</dimen>
<dimen name="keyboard_accessory_text_size">14sp</dimen>
+ <dimen name="keyboard_accessory_start_animation_translation">100dp</dimen>
<!--
Larger label and icon sizes for Form-Not-Secure experiment
diff --git a/chromium/components/autofill/content/DEPS b/chromium/components/autofill/content/DEPS
index 97138c92863..0baa569b70e 100644
--- a/chromium/components/autofill/content/DEPS
+++ b/chromium/components/autofill/content/DEPS
@@ -1,8 +1,5 @@
include_rules = [
"+content/public/common",
- # Allow inclusion of WebKit API files.
- "+third_party/WebKit/public/platform",
- "+third_party/WebKit/public/web",
"+mojo/common",
"+mojo/public",
"+services/service_manager/public/cpp",
diff --git a/chromium/components/autofill/content/browser/DEPS b/chromium/components/autofill/content/browser/DEPS
index b9cba252646..474cd74243e 100644
--- a/chromium/components/autofill/content/browser/DEPS
+++ b/chromium/components/autofill/content/browser/DEPS
@@ -8,6 +8,7 @@ include_rules = [
"+gpu/config/gpu_info.h",
"+sql",
"+third_party/libphonenumber", # For phone number i18n.
+ "+third_party/WebKit/public/platform/WebRect.h",
]
specific_include_rules = {
diff --git a/chromium/components/autofill/content/browser/content_autofill_driver.cc b/chromium/components/autofill/content/browser/content_autofill_driver.cc
index d7403b73d04..d897ff3cb7f 100644
--- a/chromium/components/autofill/content/browser/content_autofill_driver.cc
+++ b/chromium/components/autofill/content/browser/content_autofill_driver.cc
@@ -7,7 +7,6 @@
#include <utility>
#include "base/command_line.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "components/autofill/content/browser/content_autofill_driver_factory.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_external_delegate.h"
@@ -15,7 +14,6 @@
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
@@ -73,10 +71,6 @@ net::URLRequestContextGetter* ContentAutofillDriver::GetURLRequestContext() {
GetURLRequestContext();
}
-base::SequencedWorkerPool* ContentAutofillDriver::GetBlockingPool() {
- return content::BrowserThread::GetBlockingPool();
-}
-
bool ContentAutofillDriver::RendererIsAvailable() {
return render_frame_host_->GetRenderViewHost() != NULL;
}
diff --git a/chromium/components/autofill/content/browser/content_autofill_driver.h b/chromium/components/autofill/content/browser/content_autofill_driver.h
index 56a8f91fe94..f0ddceb63d9 100644
--- a/chromium/components/autofill/content/browser/content_autofill_driver.h
+++ b/chromium/components/autofill/content/browser/content_autofill_driver.h
@@ -49,7 +49,6 @@ class ContentAutofillDriver : public AutofillDriver,
// AutofillDriver:
bool IsIncognito() const override;
net::URLRequestContextGetter* GetURLRequestContext() override;
- base::SequencedWorkerPool* GetBlockingPool() override;
bool RendererIsAvailable() override;
void SendFormDataToRenderer(int query_id,
RendererFormDataAction action,
diff --git a/chromium/components/autofill/content/browser/content_autofill_driver_factory.cc b/chromium/components/autofill/content/browser/content_autofill_driver_factory.cc
index 3865c037ec6..eee03de0c2e 100644
--- a/chromium/components/autofill/content/browser/content_autofill_driver_factory.cc
+++ b/chromium/components/autofill/content/browser/content_autofill_driver_factory.cc
@@ -55,7 +55,7 @@ void ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
}
contents->SetUserData(kContentAutofillDriverFactoryWebContentsUserDataKey,
- new_factory.release());
+ std::move(new_factory));
}
// static
@@ -68,6 +68,7 @@ ContentAutofillDriverFactory* ContentAutofillDriverFactory::FromWebContents(
// static
void ContentAutofillDriverFactory::BindAutofillDriver(
content::RenderFrameHost* render_frame_host,
+ const service_manager::BindSourceInfo& source_info,
mojom::AutofillDriverRequest request) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
diff --git a/chromium/components/autofill/content/browser/content_autofill_driver_factory.h b/chromium/components/autofill/content/browser/content_autofill_driver_factory.h
index df2d8bcaf66..4a1156bb764 100644
--- a/chromium/components/autofill/content/browser/content_autofill_driver_factory.h
+++ b/chromium/components/autofill/content/browser/content_autofill_driver_factory.h
@@ -12,6 +12,7 @@
#include "components/autofill/core/browser/autofill_driver_factory.h"
#include "components/autofill/core/browser/autofill_manager.h"
#include "content/public/browser/web_contents_observer.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
namespace content {
class RenderFrameHost;
@@ -36,8 +37,10 @@ class ContentAutofillDriverFactory : public AutofillDriverFactory,
AutofillManager::AutofillDownloadManagerState enable_download_manager);
static ContentAutofillDriverFactory* FromWebContents(
content::WebContents* contents);
- static void BindAutofillDriver(content::RenderFrameHost* render_frame_host,
- mojom::AutofillDriverRequest request);
+ static void BindAutofillDriver(
+ content::RenderFrameHost* render_frame_host,
+ const service_manager::BindSourceInfo& source_info,
+ mojom::AutofillDriverRequest request);
// Gets the |ContentAutofillDriver| associated with |render_frame_host|.
// |render_frame_host| must be owned by |web_contents()|.
diff --git a/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc b/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
index 95227ba5997..c18bcbe9b7e 100644
--- a/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
+++ b/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -52,8 +52,7 @@ class FakeAutofillAgent : public mojom::AutofillAgent {
~FakeAutofillAgent() override {}
void BindRequest(mojo::ScopedMessagePipeHandle handle) {
- bindings_.AddBinding(
- this, mojo::MakeRequest<mojom::AutofillAgent>(std::move(handle)));
+ bindings_.AddBinding(this, mojom::AutofillAgentRequest(std::move(handle)));
}
void SetQuitLoopClosure(base::Closure closure) { quit_closure_ = closure; }
diff --git a/chromium/components/autofill/content/browser/payments/payments_client_unittest.cc b/chromium/components/autofill/content/browser/payments/payments_client_unittest.cc
index c825367b63b..f6e48e83064 100644
--- a/chromium/components/autofill/content/browser/payments/payments_client_unittest.cc
+++ b/chromium/components/autofill/content/browser/payments/payments_client_unittest.cc
@@ -34,6 +34,7 @@ class PaymentsClientTest : public testing::Test, public PaymentsClientDelegate {
switches::kWalletServiceUseSandbox, "0");
result_ = AutofillClient::NONE;
+ server_id_.clear();
real_pan_.clear();
legal_message_.reset();
@@ -66,8 +67,10 @@ class PaymentsClientTest : public testing::Test, public PaymentsClientDelegate {
legal_message_ = std::move(legal_message);
}
- void OnDidUploadCard(AutofillClient::PaymentsRpcResult result) override {
+ void OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
+ const std::string& server_id) override {
result_ = result;
+ server_id_ = server_id;
}
protected:
@@ -84,7 +87,8 @@ class PaymentsClientTest : public testing::Test, public PaymentsClientDelegate {
void StartGettingUploadDetails() {
token_service_->AddAccount("example@gmail.com");
identity_provider_->LogIn("example@gmail.com");
- client_->GetUploadDetails(BuildTestProfiles(), "language-LOCALE");
+ client_->GetUploadDetails(BuildTestProfiles(), std::vector<const char*>(),
+ "language-LOCALE");
}
void StartUploading() {
@@ -130,6 +134,7 @@ class PaymentsClientTest : public testing::Test, public PaymentsClientDelegate {
}
AutofillClient::PaymentsRpcResult result_;
+ std::string server_id_;
std::string real_pan_;
std::unique_ptr<base::DictionaryValue> legal_message_;
@@ -227,11 +232,20 @@ TEST_F(PaymentsClientTest, GetDetailsRemovesNonLocationData) {
EXPECT_TRUE(GetUploadData().find("0090") == std::string::npos);
}
-TEST_F(PaymentsClientTest, UploadSuccess) {
+TEST_F(PaymentsClientTest, UploadSuccessWithoutServerId) {
StartUploading();
IssueOAuthToken();
ReturnResponse(net::HTTP_OK, "{}");
EXPECT_EQ(AutofillClient::SUCCESS, result_);
+ EXPECT_TRUE(server_id_.empty());
+}
+
+TEST_F(PaymentsClientTest, UploadSuccessWithServerId) {
+ StartUploading();
+ IssueOAuthToken();
+ ReturnResponse(net::HTTP_OK, "{ \"credit_card_id\": \"InstrumentData:1\" }");
+ EXPECT_EQ(AutofillClient::SUCCESS, result_);
+ EXPECT_EQ("InstrumentData:1", server_id_);
}
TEST_F(PaymentsClientTest, UploadIncludesNonLocationData) {
diff --git a/chromium/components/autofill/content/common/BUILD.gn b/chromium/components/autofill/content/common/BUILD.gn
index 331de751527..9e84c353ffd 100644
--- a/chromium/components/autofill/content/common/BUILD.gn
+++ b/chromium/components/autofill/content/common/BUILD.gn
@@ -28,6 +28,7 @@ mojom("mojo_interfaces") {
":mojo_types",
"//mojo/common:common_custom_types",
"//ui/gfx/geometry/mojo",
+ "//url/mojo:url_mojom_gurl",
]
}
diff --git a/chromium/components/autofill/content/common/autofill_driver.mojom b/chromium/components/autofill/content/common/autofill_driver.mojom
index 1a8d5c2bb2f..01e878a246e 100644
--- a/chromium/components/autofill/content/common/autofill_driver.mojom
+++ b/chromium/components/autofill/content/common/autofill_driver.mojom
@@ -9,6 +9,7 @@ import "mojo/common/string16.mojom";
import "mojo/common/text_direction.mojom";
import "mojo/common/time.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
+import "url/mojo/url.mojom";
// There is one instance of this interface per render frame host in the browser
// process.
@@ -107,6 +108,11 @@ interface PasswordManagerDriver {
// forms where password generation should be available.
SaveGenerationFieldDetectedByClassifier(
PasswordForm password_form, mojo.common.mojom.String16 generation_field);
+
+ // Checks the safe browsing reputation of the website where the focused
+ // username/password field is on.
+ CheckSafeBrowsingReputation(
+ url.mojom.Url form_action, url.mojom.Url frame_url);
};
// There is one instance of this interface per web contents in the browser
diff --git a/chromium/components/autofill/content/common/autofill_types.mojom b/chromium/components/autofill/content/common/autofill_types.mojom
index 5e0c6ee9f3a..cb6ea750816 100644
--- a/chromium/components/autofill/content/common/autofill_types.mojom
+++ b/chromium/components/autofill/content/common/autofill_types.mojom
@@ -52,6 +52,21 @@ enum PasswordFormScheme {
SCHEME_USERNAME_ONLY
};
+// autofill::PasswordForm::SubmissionIndicatorEvent
+enum PasswordFormSubmissionIndicatorEvent {
+ NONE,
+ HTML_FORM_SUBMISSION,
+ SAME_DOCUMENT_NAVIGATION,
+ XHR_SUCCEEDED,
+ FRAME_DETACHED,
+ MANUAL_SAVE,
+ DOM_MUTATION_AFTER_XHR,
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD,
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD,
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD,
+ SUBMISSION_INDICATOR_EVENT_COUNT
+};
+
// autofill::PasswordFormFieldPredictionType
enum PasswordFormFieldPredictionType {
PREDICTION_USERNAME,
@@ -182,6 +197,7 @@ struct PasswordForm {
bool is_public_suffix_match;
bool is_affiliation_based_match;
bool does_look_like_signup_form;
+ PasswordFormSubmissionIndicatorEvent submission_event;
};
// TODO(leonhsl): Use map directly after http://crbug.com/628104 solved.
diff --git a/chromium/components/autofill/content/common/autofill_types.typemap b/chromium/components/autofill/content/common/autofill_types.typemap
index 22e639391d6..4b2a90b935e 100644
--- a/chromium/components/autofill/content/common/autofill_types.typemap
+++ b/chromium/components/autofill/content/common/autofill_types.typemap
@@ -43,4 +43,5 @@ type_mappings = [
"autofill.mojom.PasswordFormType=autofill::PasswordForm::Type",
"autofill.mojom.RoleAttribute=autofill::FormFieldData::RoleAttribute",
"autofill.mojom.PossibleUsernamePair=autofill::PossibleUsernamePair",
+ "autofill.mojom.PasswordFormSubmissionIndicatorEvent=autofill::PasswordForm::SubmissionIndicatorEvent",
]
diff --git a/chromium/components/autofill/content/common/autofill_types_struct_traits.cc b/chromium/components/autofill/content/common/autofill_types_struct_traits.cc
index d63283688a4..d76e5b05067 100644
--- a/chromium/components/autofill/content/common/autofill_types_struct_traits.cc
+++ b/chromium/components/autofill/content/common/autofill_types_struct_traits.cc
@@ -243,6 +243,104 @@ bool EnumTraits<mojom::PasswordFormScheme, PasswordForm::Scheme>::FromMojom(
}
// static
+mojom::PasswordFormSubmissionIndicatorEvent
+EnumTraits<mojom::PasswordFormSubmissionIndicatorEvent,
+ PasswordForm::SubmissionIndicatorEvent>::
+ ToMojom(PasswordForm::SubmissionIndicatorEvent input) {
+ switch (input) {
+ case PasswordForm::SubmissionIndicatorEvent::NONE:
+ return mojom::PasswordFormSubmissionIndicatorEvent::NONE;
+ case PasswordForm::SubmissionIndicatorEvent::HTML_FORM_SUBMISSION:
+ return mojom::PasswordFormSubmissionIndicatorEvent::HTML_FORM_SUBMISSION;
+ case PasswordForm::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION:
+ return mojom::PasswordFormSubmissionIndicatorEvent::
+ SAME_DOCUMENT_NAVIGATION;
+ case PasswordForm::SubmissionIndicatorEvent::XHR_SUCCEEDED:
+ return mojom::PasswordFormSubmissionIndicatorEvent::XHR_SUCCEEDED;
+ case PasswordForm::SubmissionIndicatorEvent::FRAME_DETACHED:
+ return mojom::PasswordFormSubmissionIndicatorEvent::FRAME_DETACHED;
+ case PasswordForm::SubmissionIndicatorEvent::MANUAL_SAVE:
+ return mojom::PasswordFormSubmissionIndicatorEvent::MANUAL_SAVE;
+ case PasswordForm::SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR:
+ return mojom::PasswordFormSubmissionIndicatorEvent::
+ DOM_MUTATION_AFTER_XHR;
+ case PasswordForm::SubmissionIndicatorEvent::
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD:
+ return mojom::PasswordFormSubmissionIndicatorEvent::
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD;
+ case PasswordForm::SubmissionIndicatorEvent::
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD:
+ return mojom::PasswordFormSubmissionIndicatorEvent::
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD;
+ case PasswordForm::SubmissionIndicatorEvent::
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD:
+ return mojom::PasswordFormSubmissionIndicatorEvent::
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD;
+ case PasswordForm::SubmissionIndicatorEvent::
+ SUBMISSION_INDICATOR_EVENT_COUNT:
+ return mojom::PasswordFormSubmissionIndicatorEvent::
+ SUBMISSION_INDICATOR_EVENT_COUNT;
+ }
+
+ NOTREACHED();
+ return mojom::PasswordFormSubmissionIndicatorEvent::NONE;
+}
+
+// static
+bool EnumTraits<mojom::PasswordFormSubmissionIndicatorEvent,
+ PasswordForm::SubmissionIndicatorEvent>::
+ FromMojom(mojom::PasswordFormSubmissionIndicatorEvent input,
+ PasswordForm::SubmissionIndicatorEvent* output) {
+ switch (input) {
+ case mojom::PasswordFormSubmissionIndicatorEvent::NONE:
+ *output = PasswordForm::SubmissionIndicatorEvent::NONE;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::HTML_FORM_SUBMISSION:
+ *output = PasswordForm::SubmissionIndicatorEvent::HTML_FORM_SUBMISSION;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION:
+ *output =
+ PasswordForm::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::XHR_SUCCEEDED:
+ *output = PasswordForm::SubmissionIndicatorEvent::XHR_SUCCEEDED;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::FRAME_DETACHED:
+ *output = PasswordForm::SubmissionIndicatorEvent::FRAME_DETACHED;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::MANUAL_SAVE:
+ *output = PasswordForm::SubmissionIndicatorEvent::MANUAL_SAVE;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR:
+ *output = PasswordForm::SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD:
+ *output = PasswordForm::SubmissionIndicatorEvent::
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD:
+ *output = PasswordForm::SubmissionIndicatorEvent::
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD:
+ *output = PasswordForm::SubmissionIndicatorEvent::
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD;
+ return true;
+ case mojom::PasswordFormSubmissionIndicatorEvent::
+ SUBMISSION_INDICATOR_EVENT_COUNT:
+ *output = PasswordForm::SubmissionIndicatorEvent::
+ SUBMISSION_INDICATOR_EVENT_COUNT;
+ return true;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+// static
mojom::PasswordFormFieldPredictionType EnumTraits<
mojom::PasswordFormFieldPredictionType,
PasswordFormFieldPredictionType>::ToMojom(PasswordFormFieldPredictionType
@@ -446,7 +544,8 @@ bool StructTraits<mojom::PasswordFormDataView, PasswordForm>::Read(
!data.ReadAction(&out->action) ||
!data.ReadAffiliatedWebRealm(&out->affiliated_web_realm) ||
!data.ReadSubmitElement(&out->submit_element) ||
- !data.ReadUsernameElement(&out->username_element))
+ !data.ReadUsernameElement(&out->username_element) ||
+ !data.ReadSubmissionEvent(&out->submission_event))
return false;
out->username_marked_by_site = data.username_marked_by_site();
diff --git a/chromium/components/autofill/content/common/autofill_types_struct_traits.h b/chromium/components/autofill/content/common/autofill_types_struct_traits.h
index 7d4c0303542..0c51ed527ab 100644
--- a/chromium/components/autofill/content/common/autofill_types_struct_traits.h
+++ b/chromium/components/autofill/content/common/autofill_types_struct_traits.h
@@ -86,6 +86,16 @@ struct EnumTraits<autofill::mojom::PasswordFormFieldPredictionType,
};
template <>
+struct EnumTraits<autofill::mojom::PasswordFormSubmissionIndicatorEvent,
+ autofill::PasswordForm::SubmissionIndicatorEvent> {
+ static autofill::mojom::PasswordFormSubmissionIndicatorEvent ToMojom(
+ autofill::PasswordForm::SubmissionIndicatorEvent input);
+ static bool FromMojom(
+ autofill::mojom::PasswordFormSubmissionIndicatorEvent input,
+ autofill::PasswordForm::SubmissionIndicatorEvent* output);
+};
+
+template <>
struct StructTraits<autofill::mojom::FormFieldDataDataView,
autofill::FormFieldData> {
static const base::string16& label(const autofill::FormFieldData& r) {
@@ -497,6 +507,11 @@ struct StructTraits<autofill::mojom::PasswordFormDataView,
return r.does_look_like_signup_form;
}
+ static autofill::PasswordForm::SubmissionIndicatorEvent submission_event(
+ const autofill::PasswordForm& r) {
+ return r.submission_event;
+ }
+
static bool Read(autofill::mojom::PasswordFormDataView data,
autofill::PasswordForm* out);
};
diff --git a/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc b/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
index b60bff05a7e..2fa52408cf1 100644
--- a/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
+++ b/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -93,13 +95,15 @@ void CreateTestPasswordForm(PasswordForm* form) {
form->icon_url = GURL("https://foo.com/icon.png");
form->federation_origin =
url::Origin::UnsafelyCreateOriginWithoutNormalization(
- "http", "www.google.com", 80);
+ "http", "www.google.com", 80, "");
form->skip_zero_click = false;
form->layout = PasswordForm::Layout::LAYOUT_LOGIN_AND_SIGNUP;
form->was_parsed_using_autofill_predictions = false;
form->is_public_suffix_match = true;
form->is_affiliation_based_match = true;
form->does_look_like_signup_form = true;
+ form->submission_event =
+ PasswordForm::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
}
void CreateTestFormsPredictionsMap(FormsPredictionsMap* predictions) {
@@ -206,49 +210,48 @@ class AutofillTypeTraitsTestImpl : public testing::Test,
}
// mojom::TypeTraitsTest:
- void PassFormData(const FormData& s,
- const PassFormDataCallback& callback) override {
- callback.Run(s);
+ void PassFormData(const FormData& s, PassFormDataCallback callback) override {
+ std::move(callback).Run(s);
}
void PassFormFieldData(const FormFieldData& s,
- const PassFormFieldDataCallback& callback) override {
- callback.Run(s);
+ PassFormFieldDataCallback callback) override {
+ std::move(callback).Run(s);
}
void PassFormDataPredictions(
const FormDataPredictions& s,
- const PassFormDataPredictionsCallback& callback) override {
- callback.Run(s);
+ PassFormDataPredictionsCallback callback) override {
+ std::move(callback).Run(s);
}
void PassFormFieldDataPredictions(
const FormFieldDataPredictions& s,
- const PassFormFieldDataPredictionsCallback& callback) override {
- callback.Run(s);
+ PassFormFieldDataPredictionsCallback callback) override {
+ std::move(callback).Run(s);
}
void PassPasswordFormFillData(
const PasswordFormFillData& s,
- const PassPasswordFormFillDataCallback& callback) override {
- callback.Run(s);
+ PassPasswordFormFillDataCallback callback) override {
+ std::move(callback).Run(s);
}
void PassPasswordFormGenerationData(
const PasswordFormGenerationData& s,
- const PassPasswordFormGenerationDataCallback& callback) override {
- callback.Run(s);
+ PassPasswordFormGenerationDataCallback callback) override {
+ std::move(callback).Run(s);
}
void PassPasswordForm(const PasswordForm& s,
- const PassPasswordFormCallback& callback) override {
- callback.Run(s);
+ PassPasswordFormCallback callback) override {
+ std::move(callback).Run(s);
}
void PassFormsPredictionsMap(
const FormsPredictionsMap& s,
- const PassFormsPredictionsMapCallback& callback) override {
- callback.Run(s);
+ PassFormsPredictionsMapCallback callback) override {
+ std::move(callback).Run(s);
}
private:
diff --git a/chromium/components/autofill/content/renderer/BUILD.gn b/chromium/components/autofill/content/renderer/BUILD.gn
index ce916440990..e87dc92035c 100644
--- a/chromium/components/autofill/content/renderer/BUILD.gn
+++ b/chromium/components/autofill/content/renderer/BUILD.gn
@@ -71,6 +71,7 @@ static_library("test_support") {
"//components/autofill/content/renderer",
"//ipc",
"//skia",
+ "//third_party/WebKit/public:blink",
]
}
diff --git a/chromium/components/autofill/content/renderer/DEPS b/chromium/components/autofill/content/renderer/DEPS
index 83ce085fa2a..e8db31c4a1a 100644
--- a/chromium/components/autofill/content/renderer/DEPS
+++ b/chromium/components/autofill/content/renderer/DEPS
@@ -2,6 +2,9 @@ include_rules = [
"+content/public/common",
"+content/public/renderer",
"+third_party/re2",
+ # Allow inclusion of WebKit API files.
+ "+third_party/WebKit/public/platform",
+ "+third_party/WebKit/public/web",
]
specific_include_rules = {
diff --git a/chromium/components/autofill/content/renderer/autofill_agent.cc b/chromium/components/autofill/content/renderer/autofill_agent.cc
index ef165ba059e..4da8a7a0149 100644
--- a/chromium/components/autofill/content/renderer/autofill_agent.cc
+++ b/chromium/components/autofill/content/renderer/autofill_agent.cc
@@ -41,8 +41,8 @@
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "net/cert/cert_status_flags.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/interface_provider.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
#include "third_party/WebKit/public/platform/WebKeyboardEvent.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
@@ -165,7 +165,9 @@ AutofillAgent::AutofillAgent(content::RenderFrame* render_frame,
AutofillAgent::~AutofillAgent() {}
-void AutofillAgent::BindRequest(mojom::AutofillAgentRequest request) {
+void AutofillAgent::BindRequest(
+ const service_manager::BindSourceInfo& source_info,
+ mojom::AutofillAgentRequest request) {
binding_.Bind(std::move(request));
}
diff --git a/chromium/components/autofill/content/renderer/autofill_agent.h b/chromium/components/autofill/content/renderer/autofill_agent.h
index ef1287b090d..e11e13e0469 100644
--- a/chromium/components/autofill/content/renderer/autofill_agent.h
+++ b/chromium/components/autofill/content/renderer/autofill_agent.h
@@ -20,6 +20,7 @@
#include "components/autofill/content/renderer/page_click_tracker.h"
#include "content/public/renderer/render_frame_observer.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
#include "third_party/WebKit/public/web/WebAutofillClient.h"
#include "third_party/WebKit/public/web/WebFormControlElement.h"
#include "third_party/WebKit/public/web/WebFormElement.h"
@@ -58,7 +59,8 @@ class AutofillAgent : public content::RenderFrameObserver,
PasswordGenerationAgent* password_generation_agent);
~AutofillAgent() override;
- void BindRequest(mojom::AutofillAgentRequest request);
+ void BindRequest(const service_manager::BindSourceInfo& source_info,
+ mojom::AutofillAgentRequest request);
const mojom::AutofillDriverPtr& GetAutofillDriver();
diff --git a/chromium/components/autofill/content/renderer/password_autofill_agent.cc b/chromium/components/autofill/content/renderer/password_autofill_agent.cc
index 26748925a77..893d84f30b0 100644
--- a/chromium/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/chromium/components/autofill/content/renderer/password_autofill_agent.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include <algorithm>
#include <memory>
#include <string>
#include <utility>
@@ -35,8 +36,8 @@
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/interface_provider.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebVector.h"
@@ -48,6 +49,8 @@
#include "third_party/WebKit/public/web/WebNode.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/WebView.h"
+#include "third_party/WebKit/public/web/modules/password_manager/WebFormElementObserver.h"
+#include "third_party/WebKit/public/web/modules/password_manager/WebFormElementObserverCallback.h"
#include "ui/base/page_transition_types.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "url/gurl.h"
@@ -123,35 +126,9 @@ base::string16 FieldName(const FormFieldData& field,
: field.name;
}
-bool IsUnownedPasswordFormVisible(blink::WebFrame* frame,
- const blink::WebInputElement& input_element,
- const GURL& action,
- const GURL& origin,
- const FormData& form_data,
- const FormsPredictionsMap& form_predictions) {
- if (!input_element.IsNull() && form_util::IsWebElementVisible(input_element))
- return true;
-
- std::unique_ptr<PasswordForm> unowned_password_form(
- CreatePasswordFormFromUnownedInputElements(*frame, nullptr,
- &form_predictions));
- if (!unowned_password_form)
- return false;
- std::vector<blink::WebFormControlElement> control_elements =
- form_util::GetUnownedAutofillableFormFieldElements(
- frame->GetDocument().All(), nullptr);
- if (!form_util::IsSomeControlElementVisible(control_elements))
- return false;
-
-#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
- const bool action_is_empty = action == origin;
- bool forms_are_same =
- action_is_empty ? form_data.SameFormAs(unowned_password_form->form_data)
- : action == unowned_password_form->action;
- return forms_are_same;
-#else // OS_MACOSX or OS_ANDROID
- return action == unowned_password_form->action;
-#endif
+bool IsUnownedPasswordFormVisible(const blink::WebInputElement& input_element) {
+ return !input_element.IsNull() &&
+ form_util::IsWebElementVisible(input_element);
}
// Utility function to find the unique entry of |control_elements| for the
@@ -300,11 +277,25 @@ bool DoUsernamesMatch(const base::string16& username1,
true);
}
-// Returns |true| if the given element is editable. Otherwise, returns |false|.
+// Returns whether the given |element| is editable.
bool IsElementAutocompletable(const blink::WebInputElement& element) {
return IsElementEditable(element);
}
+// Returns whether the |username_element| is allowed to be autofilled.
+//
+// Note that if the user interacts with the |password_field| and the
+// |username_element| is user-defined (i.e., non-empty and non-autofilled), then
+// this function returns false. This is a precaution, to not override the field
+// if it has been classified as username by accident.
+bool IsUsernameAmendable(const blink::WebInputElement& username_element,
+ bool is_password_field_selected) {
+ return !username_element.IsNull() &&
+ IsElementAutocompletable(username_element) &&
+ (!is_password_field_selected || username_element.IsAutofilled() ||
+ username_element.Value().IsEmpty());
+}
+
// Return true if either password_value or new_password_value is not empty and
// not default.
bool FormContainsNonDefaultPasswordValue(const PasswordForm& password_form) {
@@ -617,8 +608,61 @@ bool HasPasswordField(const blink::WebLocalFrame& frame) {
return false;
}
+// Returns the closest visible autocompletable non-password text element
+// preceding the |password_element| either in a form, if it belongs to one, or
+// in the |frame|.
+blink::WebInputElement FindUsernameElementPrecedingPasswordElement(
+ blink::WebFrame* frame,
+ const blink::WebInputElement& password_element) {
+ DCHECK(!password_element.IsNull());
+
+ std::vector<blink::WebFormControlElement> elements;
+ if (password_element.Form().IsNull()) {
+ elements = form_util::GetUnownedAutofillableFormFieldElements(
+ frame->GetDocument().All(), nullptr);
+ } else {
+ blink::WebVector<blink::WebFormControlElement> web_control_elements;
+ password_element.Form().GetFormControlElements(web_control_elements);
+ elements.assign(web_control_elements.begin(), web_control_elements.end());
+ }
+
+ auto iter = std::find(elements.begin(), elements.end(), password_element);
+ if (iter == elements.end())
+ return blink::WebInputElement();
+
+ for (auto begin = elements.begin(); iter != begin;) {
+ --iter;
+ const blink::WebInputElement* input = blink::ToWebInputElement(&*iter);
+ if (input && input->IsTextField() && !input->IsPasswordField() &&
+ IsElementAutocompletable(*input) &&
+ form_util::IsWebElementVisible(*input)) {
+ return *input;
+ }
+ }
+
+ return blink::WebInputElement();
+}
+
} // namespace
+class PasswordAutofillAgent::FormElementObserverCallback
+ : public blink::WebFormElementObserverCallback {
+ public:
+ explicit FormElementObserverCallback(PasswordAutofillAgent* agent)
+ : agent_(agent) {}
+ ~FormElementObserverCallback() override = default;
+
+ void ElementWasHiddenOrRemoved() override {
+ agent_->OnSameDocumentNavigationCompleted(
+ PasswordForm::SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR);
+ }
+
+ private:
+ PasswordAutofillAgent* agent_;
+
+ DISALLOW_COPY_AND_ASSIGN(FormElementObserverCallback);
+};
+
////////////////////////////////////////////////////////////////////////////////
// PasswordAutofillAgent, public:
@@ -628,16 +672,23 @@ PasswordAutofillAgent::PasswordAutofillAgent(content::RenderFrame* render_frame)
was_username_autofilled_(false),
was_password_autofilled_(false),
sent_request_to_store_(false),
- binding_(this) {
+ checked_safe_browsing_reputation_(false),
+ binding_(this),
+ form_element_observer_(nullptr) {
// PasswordAutofillAgent is guaranteed to outlive |render_frame|.
render_frame->GetInterfaceRegistry()->AddInterface(
base::Bind(&PasswordAutofillAgent::BindRequest, base::Unretained(this)));
}
PasswordAutofillAgent::~PasswordAutofillAgent() {
+ if (form_element_observer_) {
+ form_element_observer_->Disconnect();
+ form_element_observer_ = nullptr;
+ }
}
void PasswordAutofillAgent::BindRequest(
+ const service_manager::BindSourceInfo& source_info,
mojom::PasswordAutofillAgentRequest request) {
binding_.Bind(std::move(request));
}
@@ -760,7 +811,7 @@ bool PasswordAutofillAgent::FillSuggestion(
blink::WebInputElement username_element;
blink::WebInputElement password_element;
- PasswordInfo* password_info;
+ PasswordInfo* password_info = nullptr;
if (!FindPasswordInfoForElement(*element, &username_element,
&password_element, &password_info) ||
@@ -772,8 +823,9 @@ bool PasswordAutofillAgent::FillSuggestion(
if (element->IsPasswordField()) {
password_info->password_field_suggestion_was_accepted = true;
password_info->password_field = password_element;
- } else if (!username_element.IsNull() &&
- IsElementAutocompletable(username_element)) {
+ }
+
+ if (IsUsernameAmendable(username_element, element->IsPasswordField())) {
username_element.SetAutofillValue(blink::WebString::FromUTF16(username));
username_element.SetAutofilled(true);
UpdateFieldValueAndPropertiesMaskMap(username_element, &username,
@@ -813,8 +865,7 @@ bool PasswordAutofillAgent::PreviewSuggestion(
return false;
}
- if (!element->IsPasswordField() && !username_element.IsNull() &&
- IsElementAutocompletable(username_element)) {
+ if (IsUsernameAmendable(username_element, element->IsPasswordField())) {
if (username_query_prefix_.empty())
username_query_prefix_ = username_element.Value().Utf16();
@@ -842,8 +893,9 @@ bool PasswordAutofillAgent::DidClearAutofillSelection(
PasswordInfo* password_info;
if (!FindPasswordInfoForElement(*element, &username_element,
- &password_element, &password_info))
+ &password_element, &password_info)) {
return false;
+ }
ClearPreview(&username_element, &password_element);
return true;
@@ -860,33 +912,44 @@ bool PasswordAutofillAgent::FindPasswordInfoForElement(
if (!element.IsPasswordField()) {
*username_element = element;
} else {
+ // If there is a password field, but a request to the store hasn't been sent
+ // yet, then do fetch saved credentials now.
+ if (!sent_request_to_store_) {
+ SendPasswordForms(false);
+ return false;
+ }
+
+ *password_element = element;
+
WebInputToPasswordInfoMap::iterator iter =
web_input_to_password_info_.find(element);
+ if (iter == web_input_to_password_info_.end()) {
+ PasswordToLoginMap::const_iterator password_iter =
+ password_to_username_.find(element);
+ if (password_iter == password_to_username_.end()) {
+ if (web_input_to_password_info_.empty())
+ return false;
+ // Now all PasswordInfo items refer to the same set of credentials for
+ // fill, so it is ok to take any of them.
+ iter = web_input_to_password_info_.begin();
+ } else {
+ *username_element = password_iter->second;
+ }
+ }
+
if (iter != web_input_to_password_info_.end()) {
- // It's a password field without corresponding username field.
- *password_element = element;
+ // It's a password field without corresponding username field. Try to find
+ // the username field based on visibility.
+ *username_element = FindUsernameElementPrecedingPasswordElement(
+ render_frame()->GetWebFrame(), *password_element);
*password_info = &iter->second;
return true;
}
- PasswordToLoginMap::const_iterator password_iter =
- password_to_username_.find(element);
- if (password_iter == password_to_username_.end()) {
- if (web_input_to_password_info_.empty())
- return false;
-
- *password_element = element;
- // Now all PasswordInfo items refer to the same set of credentials for
- // fill, so it is ok to take any of them.
- *password_info = &web_input_to_password_info_.begin()->second;
- return true;
- }
- *username_element = password_iter->second;
- *password_element = element;
+ // Otherwise |username_element| has been set above.
}
WebInputToPasswordInfoMap::iterator iter =
web_input_to_password_info_.find(*username_element);
-
if (iter == web_input_to_password_info_.end())
return false;
@@ -900,13 +963,15 @@ bool PasswordAutofillAgent::FindPasswordInfoForElement(
bool PasswordAutofillAgent::ShouldShowNotSecureWarning(
const blink::WebInputElement& element) {
// Do not show a warning if the feature is disabled or the context is secure.
- if (!security_state::IsHttpWarningInFormEnabled() ||
- content::IsOriginSecure(
- url::Origin(render_frame()->GetWebFrame()->Top()->GetSecurityOrigin())
- .GetURL()))
- return false;
+ return security_state::IsHttpWarningInFormEnabled() &&
+ !content::IsOriginSecure(
+ url::Origin(
+ render_frame()->GetWebFrame()->Top()->GetSecurityOrigin())
+ .GetURL());
+}
- // Show the warning on all Password inputs.
+bool PasswordAutofillAgent::IsUsernameOrPasswordField(
+ const blink::WebInputElement& element) {
// Note: A site may use a Password field to collect a CVV or a Credit Card
// number, but showing a slightly misleading warning here is better than
// showing no warning at all.
@@ -947,9 +1012,24 @@ bool PasswordAutofillAgent::ShowSuggestions(
if (!FindPasswordInfoForElement(element, &username_element, &password_element,
&password_info)) {
- if (ShouldShowNotSecureWarning(element)) {
- autofill_agent_->ShowNotSecureWarning(element);
- return true;
+ if (IsUsernameOrPasswordField(element)) {
+#if defined(SAFE_BROWSING_DB_LOCAL)
+ if (!checked_safe_browsing_reputation_) {
+ checked_safe_browsing_reputation_ = true;
+ GURL action_url =
+ element.Form().IsNull()
+ ? GURL()
+ : form_util::GetCanonicalActionForForm(element.Form());
+ blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
+ GURL frame_url = GURL(frame->GetDocument().Url());
+ GetPasswordManagerDriver()->CheckSafeBrowsingReputation(action_url,
+ frame_url);
+ }
+#endif
+ if (ShouldShowNotSecureWarning(element)) {
+ autofill_agent_->ShowNotSecureWarning(element);
+ return true;
+ }
}
return false;
}
@@ -1014,10 +1094,12 @@ void PasswordAutofillAgent::OnDynamicFormsSeen() {
}
void PasswordAutofillAgent::AJAXSucceeded() {
- OnSameDocumentNavigationCompleted();
+ OnSameDocumentNavigationCompleted(
+ PasswordForm::SubmissionIndicatorEvent::XHR_SUCCEEDED);
}
-void PasswordAutofillAgent::OnSameDocumentNavigationCompleted() {
+void PasswordAutofillAgent::OnSameDocumentNavigationCompleted(
+ PasswordForm::SubmissionIndicatorEvent event) {
if (!provisionally_saved_form_.IsPasswordValid())
return;
@@ -1025,18 +1107,37 @@ void PasswordAutofillAgent::OnSameDocumentNavigationCompleted() {
// removed from the DOM.
blink::WebFrame* frame = render_frame()->GetWebFrame();
const auto& password_form = provisionally_saved_form_.password_form();
- if (form_util::IsFormVisible(frame, provisionally_saved_form_.form_element(),
- password_form.action, password_form.origin,
- password_form.form_data) ||
- (provisionally_saved_form_.form_element().IsNull() &&
- IsUnownedPasswordFormVisible(
- frame, provisionally_saved_form_.input_element(),
- password_form.action, password_form.origin, password_form.form_data,
- form_predictions_))) {
- return;
+ // TODO(crbug.com/720347): This method could be called often and checking form
+ // visibility could be expesive. Add performance metrics for this.
+ if (event != PasswordForm::SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR) {
+ if (form_util::IsFormVisible(frame,
+ provisionally_saved_form_.form_element(),
+ password_form.action, password_form.origin,
+ password_form.form_data) ||
+ (provisionally_saved_form_.form_element().IsNull() &&
+ IsUnownedPasswordFormVisible(
+ provisionally_saved_form_.input_element()))) {
+ if (!form_element_observer_) {
+ std::unique_ptr<FormElementObserverCallback> callback(
+ new FormElementObserverCallback(this));
+ if (!provisionally_saved_form_.form_element().IsNull()) {
+ form_element_observer_ = blink::WebFormElementObserver::Create(
+ provisionally_saved_form_.form_element(), std::move(callback));
+ } else if (!provisionally_saved_form_.input_element().IsNull()) {
+ form_element_observer_ = blink::WebFormElementObserver::Create(
+ provisionally_saved_form_.input_element(), std::move(callback));
+ }
+ }
+ return;
+ }
}
+ provisionally_saved_form_.SetSubmissionIndicatorEvent(event);
GetPasswordManagerDriver()->InPageNavigation(password_form);
+ if (form_element_observer_) {
+ form_element_observer_->Disconnect();
+ form_element_observer_ = nullptr;
+ }
provisionally_saved_form_.Reset();
}
@@ -1158,10 +1259,11 @@ void PasswordAutofillAgent::SendPasswordForms(bool only_visible) {
form_util::GetCanonicalOriginForDocument(frame->GetDocument());
password_forms.back().signon_realm =
GetSignOnRealm(password_forms.back().origin);
- sent_request_to_store_ = true;
}
- if (!password_forms.empty())
+ if (!password_forms.empty()) {
+ sent_request_to_store_ = true;
GetPasswordManagerDriver()->PasswordFormsParsed(password_forms);
+ }
}
}
@@ -1189,7 +1291,10 @@ void PasswordAutofillAgent::DidCommitProvisionalLoad(
bool is_new_navigation,
bool is_same_document_navigation) {
if (is_same_document_navigation) {
- OnSameDocumentNavigationCompleted();
+ OnSameDocumentNavigationCompleted(
+ PasswordForm::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION);
+ } else {
+ checked_safe_browsing_reputation_ = false;
}
}
@@ -1199,6 +1304,8 @@ void PasswordAutofillAgent::FrameDetached() {
// for examples of sites that perform login using this technique.
if (render_frame()->GetWebFrame()->Parent() &&
provisionally_saved_form_.IsPasswordValid()) {
+ provisionally_saved_form_.SetSubmissionIndicatorEvent(
+ PasswordForm::SubmissionIndicatorEvent::FRAME_DETACHED);
GetPasswordManagerDriver()->InPageNavigation(
provisionally_saved_form_.password_form());
}
@@ -1258,6 +1365,8 @@ void PasswordAutofillAgent::WillSubmitForm(const blink::WebFormElement& form) {
submitted_form->password_value = saved_form.password_value;
submitted_form->new_password_value = saved_form.new_password_value;
submitted_form->username_value = saved_form.username_value;
+ submitted_form->submission_event =
+ PasswordForm::SubmissionIndicatorEvent::HTML_FORM_SUBMISSION;
}
// Some observers depend on sending this information now instead of when
@@ -1265,6 +1374,10 @@ void PasswordAutofillAgent::WillSubmitForm(const blink::WebFormElement& form) {
// RenderView to be instantiated (such as redirects to the WebStore)
// we will never get to finish the load.
GetPasswordManagerDriver()->PasswordFormSubmitted(*submitted_form);
+ if (form_element_observer_) {
+ form_element_observer_->Disconnect();
+ form_element_observer_ = nullptr;
+ }
provisionally_saved_form_.Reset();
} else if (logger) {
logger->LogMessage(Logger::STRING_FORM_IS_NOT_PASSWORD);
@@ -1310,8 +1423,15 @@ void PasswordAutofillAgent::DidStartProvisionalLoad(
Logger::STRING_PROVISIONALLY_SAVED_FORM_FOR_FRAME,
provisionally_saved_form_.password_form());
}
+ provisionally_saved_form_.SetSubmissionIndicatorEvent(
+ PasswordForm::SubmissionIndicatorEvent::
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD);
GetPasswordManagerDriver()->PasswordFormSubmitted(
provisionally_saved_form_.password_form());
+ if (form_element_observer_) {
+ form_element_observer_->Disconnect();
+ form_element_observer_ = nullptr;
+ }
provisionally_saved_form_.Reset();
} else {
std::vector<std::unique_ptr<PasswordForm>> possible_submitted_forms;
@@ -1327,15 +1447,24 @@ void PasswordAutofillAgent::DidStartProvisionalLoad(
LogHTMLForm(logger.get(), Logger::STRING_FORM_FOUND_ON_PAGE,
form_element);
}
- possible_submitted_forms.push_back(CreatePasswordFormFromWebForm(
- form_element, &field_value_and_properties_map_,
- &form_predictions_));
+ std::unique_ptr<PasswordForm> form = CreatePasswordFormFromWebForm(
+ form_element, &field_value_and_properties_map_, &form_predictions_);
+ if (form) {
+ form->submission_event = PasswordForm::SubmissionIndicatorEvent::
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD;
+ possible_submitted_forms.push_back(std::move(form));
+ }
}
- possible_submitted_forms.push_back(
+ std::unique_ptr<PasswordForm> form =
CreatePasswordFormFromUnownedInputElements(
*render_frame()->GetWebFrame(), &field_value_and_properties_map_,
- &form_predictions_));
+ &form_predictions_);
+ if (form) {
+ form->submission_event = PasswordForm::SubmissionIndicatorEvent::
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD;
+ possible_submitted_forms.push_back(std::move(form));
+ }
for (const auto& password_form : possible_submitted_forms) {
if (password_form && !password_form->username_value.empty() &&
@@ -1512,7 +1641,7 @@ void PasswordAutofillAgent::AutofillUsernameAndPasswordDataReceived(
}
void PasswordAutofillAgent::FindFocusedPasswordForm(
- const FindFocusedPasswordFormCallback& callback) {
+ FindFocusedPasswordFormCallback callback) {
std::unique_ptr<PasswordForm> password_form;
blink::WebElement element =
@@ -1541,7 +1670,9 @@ void PasswordAutofillAgent::FindFocusedPasswordForm(
if (!password_form)
password_form.reset(new PasswordForm());
- callback.Run(*password_form);
+ password_form->submission_event =
+ PasswordForm::SubmissionIndicatorEvent::MANUAL_SAVE;
+ std::move(callback).Run(*password_form);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1593,9 +1724,14 @@ void PasswordAutofillAgent::FrameClosing() {
password_to_username_.erase(iter.second.password_field);
}
web_input_to_password_info_.clear();
+ if (form_element_observer_) {
+ form_element_observer_->Disconnect();
+ form_element_observer_ = nullptr;
+ }
provisionally_saved_form_.Reset();
field_value_and_properties_map_.clear();
sent_request_to_store_ = false;
+ checked_safe_browsing_reputation_ = false;
}
void PasswordAutofillAgent::ClearPreview(
diff --git a/chromium/components/autofill/content/renderer/password_autofill_agent.h b/chromium/components/autofill/content/renderer/password_autofill_agent.h
index 486e8eb34e3..b1ea39258e9 100644
--- a/chromium/components/autofill/content/renderer/password_autofill_agent.h
+++ b/chromium/components/autofill/content/renderer/password_autofill_agent.h
@@ -22,9 +22,11 @@
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_view_observer.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
namespace blink {
+class WebFormElementObserver;
class WebInputElement;
class WebSecurityOrigin;
}
@@ -44,7 +46,8 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
explicit PasswordAutofillAgent(content::RenderFrame* render_frame);
~PasswordAutofillAgent() override;
- void BindRequest(mojom::PasswordAutofillAgentRequest request);
+ void BindRequest(const service_manager::BindSourceInfo& source_info,
+ mojom::PasswordAutofillAgentRequest request);
void SetAutofillAgent(AutofillAgent* autofill_agent);
@@ -57,7 +60,7 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
void AutofillUsernameAndPasswordDataReceived(
const FormsPredictionsMap& predictions) override;
void FindFocusedPasswordForm(
- const FindFocusedPasswordFormCallback& callback) override;
+ FindFocusedPasswordFormCallback callback) override;
// WebFrameClient editor related calls forwarded by AutofillAgent.
// If they return true, it indicates the event was consumed and should not
@@ -88,10 +91,14 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
bool DidClearAutofillSelection(
const blink::WebFormControlElement& control_element);
- // If the form is non-secure, show the "Not Secure" warning on username and
- // password input fields.
+ // Returns whether a "Login not secure" warning should be shown on the input
+ // field. This is true if the feature is enabled and if the form is
+ // non-secure.
bool ShouldShowNotSecureWarning(const blink::WebInputElement& element);
+ // Returns whether the element is a username or password textfield.
+ bool IsUsernameOrPasswordField(const blink::WebInputElement& element);
+
// Shows an Autofill popup with username suggestions for |element|. If
// |show_all| is |true|, will show all possible suggestions for that element,
// otherwise shows suggestions based on current value of |element|.
@@ -141,6 +148,8 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
const blink::WebSecurityOrigin& origin);
private:
+ class FormElementObserverCallback;
+
// Ways to restrict which passwords are saved in ProvisionallySavePassword.
enum ProvisionallySaveRestriction {
RESTRICTION_NONE,
@@ -220,12 +229,12 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
bool show_all,
bool show_on_password_field);
- // Finds the PasswordInfo, username and password fields that corresponds to
- // the passed in |element|. |element| can refer either to a username element
- // or a password element. If a PasswordInfo was found, returns |true| and also
- // assigns the corresponding username, password elements and PasswordInfo into
+ // Finds the PasswordInfo, username and password fields corresponding to the
+ // passed in |element|, which can refer to either a username or a password
+ // element. If a PasswordInfo was found, returns |true| and assigns the
+ // corresponding username, password elements and PasswordInfo into
// |username_element|, |password_element| and |pasword_info|, respectively.
- // Note, that |username_element->isNull()| can be true if |element| is a
+ // Note, that |username_element->IsNull()| can be true if |element| is a
// password.
bool FindPasswordInfoForElement(const blink::WebInputElement& element,
blink::WebInputElement* username_element,
@@ -252,13 +261,14 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
ProvisionallySaveRestriction restriction);
// Helper function called when same-document navigation completed
- void OnSameDocumentNavigationCompleted();
+ void OnSameDocumentNavigationCompleted(
+ PasswordForm::SubmissionIndicatorEvent event);
const mojom::AutofillDriverPtr& GetAutofillDriver();
// The logins we have filled so far with their associated info.
WebInputToPasswordInfoMap web_input_to_password_info_;
- // A (sort-of) reverse map to |login_to_password_info_|.
+ // A (sort-of) reverse map to |web_input_to_password_info_|.
PasswordToLoginMap password_to_username_;
// Set if the user might be submitting a password form on the current page,
@@ -286,6 +296,9 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
// True indicates that a request for credentials has been sent to the store.
bool sent_request_to_store_;
+ // True indicates that a safe browsing reputation check has been triggered.
+ bool checked_safe_browsing_reputation_;
+
// Records the username typed before suggestions preview.
base::string16 username_query_prefix_;
@@ -299,6 +312,8 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
mojo::Binding<mojom::PasswordAutofillAgent> binding_;
+ blink::WebFormElementObserver* form_element_observer_;
+
DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgent);
};
diff --git a/chromium/components/autofill/content/renderer/password_form_conversion_utils.cc b/chromium/components/autofill/content/renderer/password_form_conversion_utils.cc
index aed99de7057..825f44621b9 100644
--- a/chromium/components/autofill/content/renderer/password_form_conversion_utils.cc
+++ b/chromium/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -19,6 +19,8 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/content/renderer/form_autofill_util.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"
#include "components/autofill/core/common/password_form.h"
#include "components/autofill/core/common/password_form_field_prediction_map.h"
@@ -429,6 +431,8 @@ bool GetPasswordForm(
if (HasCreditCardAutocompleteAttributes(*input_element))
continue;
+ if (IsCreditCardVerificationPasswordField(*input_element))
+ continue;
bool element_is_invisible = !form_util::IsWebElementVisible(*input_element);
if (input_element->IsTextField()) {
@@ -763,9 +767,21 @@ bool HasCreditCardAutocompleteAttributes(
return false;
}
+bool IsCreditCardVerificationPasswordField(
+ const blink::WebInputElement& field) {
+ if (!field.IsPasswordField())
+ return false;
+
+ static const base::string16 kCardCvcReCached = base::UTF8ToUTF16(kCardCvcRe);
+
+ return MatchesPattern(field.GetAttribute("id").Utf16(), kCardCvcReCached) ||
+ MatchesPattern(field.GetAttribute("name").Utf16(), kCardCvcReCached);
+}
+
std::string GetSignOnRealm(const GURL& origin) {
GURL::Replacements rep;
rep.SetPathStr("");
return origin.ReplaceComponents(rep).spec();
}
+
} // namespace autofill
diff --git a/chromium/components/autofill/content/renderer/password_form_conversion_utils.h b/chromium/components/autofill/content/renderer/password_form_conversion_utils.h
index 8029c16cb96..0cebba2f265 100644
--- a/chromium/components/autofill/content/renderer/password_form_conversion_utils.h
+++ b/chromium/components/autofill/content/renderer/password_form_conversion_utils.h
@@ -68,6 +68,10 @@ bool HasAutocompleteAttributeValue(const blink::WebInputElement& element,
// the given |element| are present.
bool HasCreditCardAutocompleteAttributes(const blink::WebInputElement& element);
+// Returns whether the form |field| has a "password" type, but looks like a
+// credit card verification field.
+bool IsCreditCardVerificationPasswordField(const blink::WebInputElement& field);
+
// The "Realm" for the sign-on. This is scheme, host, port.
std::string GetSignOnRealm(const GURL& origin);
diff --git a/chromium/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/chromium/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
index 2d3ceda9320..699caa9cb77 100644
--- a/chromium/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
+++ b/chromium/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -1291,7 +1291,7 @@ TEST_F(MAYBE_PasswordFormConversionUtilsTest,
std::unique_ptr<PasswordForm> password_form =
LoadHTMLAndConvertForm(html, &predictions, false);
- EXPECT_TRUE(password_form);
+ EXPECT_FALSE(password_form);
}
TEST_F(MAYBE_PasswordFormConversionUtilsTest, IsGaiaReauthFormIgnored) {
diff --git a/chromium/components/autofill/content/renderer/password_generation_agent.cc b/chromium/components/autofill/content/renderer/password_generation_agent.cc
index 020c5b383e8..bf50f220493 100644
--- a/chromium/components/autofill/content/renderer/password_generation_agent.cc
+++ b/chromium/components/autofill/content/renderer/password_generation_agent.cc
@@ -23,7 +23,7 @@
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "google_apis/gaia/gaia_urls.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebDocument.h"
@@ -152,6 +152,7 @@ PasswordGenerationAgent::PasswordGenerationAgent(
PasswordGenerationAgent::~PasswordGenerationAgent() {}
void PasswordGenerationAgent::BindRequest(
+ const service_manager::BindSourceInfo& source_info,
mojom::PasswordGenerationAgentRequest request) {
binding_.Bind(std::move(request));
}
@@ -353,6 +354,7 @@ PasswordGenerationAgent::CreatePasswordFormToPresave() {
*render_frame()->GetWebFrame(), nullptr, nullptr);
}
if (password_form) {
+ password_form->type = PasswordForm::TYPE_GENERATED;
// TODO(kolos): when we are good in username detection, save username
// as well.
password_form->username_value = base::string16();
diff --git a/chromium/components/autofill/content/renderer/password_generation_agent.h b/chromium/components/autofill/content/renderer/password_generation_agent.h
index 2af62823a76..035f98010ef 100644
--- a/chromium/components/autofill/content/renderer/password_generation_agent.h
+++ b/chromium/components/autofill/content/renderer/password_generation_agent.h
@@ -19,6 +19,7 @@
#include "components/autofill/content/renderer/renderer_save_password_progress_logger.h"
#include "content/public/renderer/render_frame_observer.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
#include "url/gurl.h"
@@ -38,7 +39,8 @@ class PasswordGenerationAgent : public content::RenderFrameObserver,
PasswordAutofillAgent* password_agent);
~PasswordGenerationAgent() override;
- void BindRequest(mojom::PasswordGenerationAgentRequest request);
+ void BindRequest(const service_manager::BindSourceInfo& source_info,
+ mojom::PasswordGenerationAgentRequest request);
// mojom::PasswordGenerationAgent:
void FormNotBlacklisted(const PasswordForm& form) override;
diff --git a/chromium/components/autofill/content/renderer/provisionally_saved_password_form.cc b/chromium/components/autofill/content/renderer/provisionally_saved_password_form.cc
index 34bbee19bf4..15b30c78745 100644
--- a/chromium/components/autofill/content/renderer/provisionally_saved_password_form.cc
+++ b/chromium/components/autofill/content/renderer/provisionally_saved_password_form.cc
@@ -6,8 +6,6 @@
#include <utility>
-#include "components/autofill/core/common/password_form.h"
-
namespace autofill {
ProvisionallySavedPasswordForm::ProvisionallySavedPasswordForm() = default;
@@ -38,4 +36,10 @@ bool ProvisionallySavedPasswordForm::IsPasswordValid() const {
password_form_->new_password_value.empty());
}
+void ProvisionallySavedPasswordForm::SetSubmissionIndicatorEvent(
+ PasswordForm::SubmissionIndicatorEvent event) {
+ if (password_form_)
+ password_form_->submission_event = event;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/content/renderer/provisionally_saved_password_form.h b/chromium/components/autofill/content/renderer/provisionally_saved_password_form.h
index 318eb189aed..68af7b4f693 100644
--- a/chromium/components/autofill/content/renderer/provisionally_saved_password_form.h
+++ b/chromium/components/autofill/content/renderer/provisionally_saved_password_form.h
@@ -8,6 +8,7 @@
#include <memory>
#include "base/macros.h"
+#include "components/autofill/core/common/password_form.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
namespace autofill {
@@ -38,8 +39,11 @@ class ProvisionallySavedPasswordForm {
DCHECK(IsSet());
return *password_form_;
}
- const blink::WebFormElement& form_element() const { return form_element_; }
- const blink::WebInputElement& input_element() const { return input_element_; }
+ blink::WebFormElement& form_element() { return form_element_; }
+ blink::WebInputElement& input_element() { return input_element_; }
+
+ void SetSubmissionIndicatorEvent(
+ PasswordForm::SubmissionIndicatorEvent event);
private:
std::unique_ptr<PasswordForm> password_form_;
diff --git a/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc b/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc
index 85958d4f696..558b7fcff18 100644
--- a/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc
+++ b/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger_unittest.cc
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "components/autofill/content/renderer/renderer_save_password_progress_logger.h"
+
+#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "components/autofill/content/common/autofill_driver.mojom.h"
-#include "components/autofill/content/renderer/renderer_save_password_progress_logger.h"
#include "mojo/public/cpp/bindings/binding.h"
-
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
@@ -73,6 +74,9 @@ class FakeContentPasswordManagerDriver : public mojom::PasswordManagerDriver {
const autofill::PasswordForm& password_form,
const base::string16& generation_field) override {}
+ void CheckSafeBrowsingReputation(const GURL& form_action,
+ const GURL& frame_url) override {}
+
// Records whether RecordSavePasswordProgress() gets called.
bool called_record_save_;
// Records data received via RecordSavePasswordProgress() call.
diff --git a/chromium/components/autofill/core/browser/BUILD.gn b/chromium/components/autofill/core/browser/BUILD.gn
index 87a22f6efa1..945549f3993 100644
--- a/chromium/components/autofill/core/browser/BUILD.gn
+++ b/chromium/components/autofill/core/browser/BUILD.gn
@@ -8,6 +8,8 @@ static_library("browser") {
sources = [
"address.cc",
"address.h",
+ "address_combobox_model.cc",
+ "address_combobox_model.h",
"address_field.cc",
"address_field.h",
"address_i18n.cc",
@@ -50,12 +52,8 @@ static_library("browser") {
"autofill_profile.h",
"autofill_profile_comparator.cc",
"autofill_profile_comparator.h",
- "autofill_regex_constants.cc",
- "autofill_regex_constants.h",
"autofill_scanner.cc",
"autofill_scanner.h",
- "autofill_sync_constants.cc",
- "autofill_sync_constants.h",
"autofill_type.cc",
"autofill_type.h",
"autofill_wallet_data_type_controller.cc",
@@ -113,6 +111,9 @@ static_library("browser") {
"popup_item_ids.h",
"region_combobox_model.cc",
"region_combobox_model.h",
+ "region_data_loader.h",
+ "region_data_loader_impl.cc",
+ "region_data_loader_impl.h",
"risk_data_loader.h",
"server_field_types_util.cc",
"server_field_types_util.h",
@@ -136,8 +137,6 @@ static_library("browser") {
"webdata/autofill_data_type_controller.h",
"webdata/autofill_entry.cc",
"webdata/autofill_entry.h",
- "webdata/autofill_metadata_change_list.cc",
- "webdata/autofill_metadata_change_list.h",
"webdata/autofill_profile_data_type_controller.cc",
"webdata/autofill_profile_data_type_controller.h",
"webdata/autofill_profile_syncable_service.cc",
@@ -184,9 +183,7 @@ static_library("browser") {
}
if (!is_android) {
- sources += [
- "ui/save_card_bubble_controller.h",
- ]
+ sources += [ "ui/save_card_bubble_controller.h" ]
}
configs += [ "//build/config:precompiled_headers" ]
@@ -256,6 +253,8 @@ static_library("test_support") {
"test_autofill_external_delegate.h",
"test_personal_data_manager.cc",
"test_personal_data_manager.h",
+ "test_region_data_loader.cc",
+ "test_region_data_loader.h",
]
if (!is_android) {
@@ -287,6 +286,7 @@ static_library("test_support") {
"//google_apis:test_support",
"//skia",
"//testing/gtest",
+ "//third_party/libaddressinput:util",
"//ui/gfx:test_support",
"//ui/gfx/geometry",
]
@@ -318,6 +318,7 @@ bundle_data("unit_tests_bundle_data") {
source_set("unit_tests") {
testonly = true
sources = [
+ "address_combobox_model_unittest.cc",
"address_field_unittest.cc",
"address_i18n_unittest.cc",
"address_rewriter_unittest.cc",
diff --git a/chromium/components/autofill/core/browser/address.cc b/chromium/components/autofill/core/browser/address.cc
index 813d6155691..3a44121606d 100644
--- a/chromium/components/autofill/core/browser/address.cc
+++ b/chromium/components/autofill/core/browser/address.cc
@@ -7,11 +7,13 @@
#include <stddef.h>
#include <algorithm>
+#include "base/i18n/case_conversion.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_country.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_comparator.h"
@@ -134,8 +136,8 @@ void Address::SetRawInfo(ServerFieldType type, const base::string16& value) {
case ADDRESS_HOME_COUNTRY:
DCHECK(value.empty() ||
- (value.length() == 2u && base::IsStringASCII(value)));
- country_code_ = base::UTF16ToASCII(value);
+ data_util::IsValidCountryCode(base::i18n::ToUpper(value)));
+ country_code_ = base::ToUpperASCII(base::UTF16ToASCII(value));
break;
case ADDRESS_HOME_ZIP:
@@ -173,7 +175,7 @@ bool Address::SetInfo(const AutofillType& type,
const base::string16& value,
const std::string& app_locale) {
if (type.html_type() == HTML_TYPE_COUNTRY_CODE) {
- if (!value.empty() && (value.size() != 2u || !base::IsStringASCII(value))) {
+ if (!data_util::IsValidCountryCode(base::i18n::ToUpper(value))) {
country_code_ = std::string();
return false;
}
diff --git a/chromium/components/autofill/core/browser/address_combobox_model.cc b/chromium/components/autofill/core/browser/address_combobox_model.cc
new file mode 100644
index 00000000000..fe6830cbe91
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_combobox_model.cc
@@ -0,0 +1,141 @@
+// Copyright 2017 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_combobox_model.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/combobox_model_observer.h"
+#include "ui/gfx/text_elider.h"
+
+namespace autofill {
+
+namespace {
+// There's one header entry to prompt the user to select an address, and a
+// separator.
+int kNbHeaderEntries = 2;
+} // namespace
+
+AddressComboboxModel::AddressComboboxModel(
+ const PersonalDataManager& personal_data_manager,
+ const std::string& app_locale,
+ const std::string& default_selected_guid)
+ : app_locale_(app_locale), default_selected_guid_(default_selected_guid) {
+ for (const auto* profile : personal_data_manager.GetProfilesToSuggest()) {
+ profiles_cache_.push_back(base::MakeUnique<AutofillProfile>(*profile));
+ }
+ UpdateAddresses();
+}
+
+AddressComboboxModel::~AddressComboboxModel() {}
+
+int AddressComboboxModel::GetItemCount() const {
+ // When there are not addresses, a special entry is shown to prompt the user
+ // to add addresses, but nothing else is shown, since there are no address to
+ // select from, and no need for a separator.
+ if (addresses_.size() == 0)
+ return 1;
+ // If there are addresses to choose from, but none is selected, add extra
+ // items for the "Select" entry and a separator.
+ return addresses_.size() + kNbHeaderEntries;
+}
+
+base::string16 AddressComboboxModel::GetItemAt(int index) {
+ DCHECK_GE(index, 0);
+ // A special entry is always added at index 0 and a separator at index 1.
+ DCHECK_LT(static_cast<size_t>(index), addresses_.size() + kNbHeaderEntries);
+
+ // Special entry when no profiles have been created yet.
+ if (addresses_.empty())
+ return l10n_util::GetStringUTF16(IDS_AUTOFILL_NO_SAVED_ADDRESS);
+
+ // Always show the "Select" entry at the top, default selection position.
+ if (index == 0)
+ return l10n_util::GetStringUTF16(IDS_AUTOFILL_SELECT);
+
+ // Always show the "Select" entry at the top, default selection position.
+ if (index == 1)
+ return base::ASCIIToUTF16("---");
+
+ return addresses_[index - kNbHeaderEntries].second;
+}
+
+bool AddressComboboxModel::IsItemSeparatorAt(int index) {
+ // The only separator is between the "Select" entry at 0 and the first address
+ // at index 2. So there must be at least one address for a separator to be
+ // shown.
+ DCHECK(index <= kNbHeaderEntries || !addresses_.empty());
+ return index == 1;
+}
+
+int AddressComboboxModel::GetDefaultIndex() const {
+ if (!default_selected_guid_.empty()) {
+ int address_index = GetIndexOfIdentifier(default_selected_guid_);
+ if (address_index != -1)
+ return address_index;
+ }
+ return ui::ComboboxModel::GetDefaultIndex();
+}
+
+void AddressComboboxModel::AddObserver(ui::ComboboxModelObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void AddressComboboxModel::RemoveObserver(ui::ComboboxModelObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+int AddressComboboxModel::AddNewProfile(const AutofillProfile& profile) {
+ profiles_cache_.push_back(base::MakeUnique<AutofillProfile>(profile));
+ UpdateAddresses();
+ DCHECK_GT(addresses_.size(), 0UL);
+ return addresses_.size() + kNbHeaderEntries - 1;
+}
+
+std::string AddressComboboxModel::GetItemIdentifierAt(int index) {
+ // The first two indices are special entries, with no addresses.
+ if (index < kNbHeaderEntries)
+ return std::string();
+ DCHECK_LT(static_cast<size_t>(index), addresses_.size() + kNbHeaderEntries);
+ return addresses_[index - kNbHeaderEntries].first;
+}
+
+int AddressComboboxModel::GetIndexOfIdentifier(
+ const std::string& identifier) const {
+ for (size_t i = 0; i < addresses_.size(); ++i) {
+ if (addresses_[i].first == identifier)
+ return i + kNbHeaderEntries;
+ }
+ return -1;
+}
+
+void AddressComboboxModel::UpdateAddresses() {
+ addresses_.clear();
+ std::vector<base::string16> labels;
+ // CreateDifferentiatingLabels is expecting a pointer vector and we keep
+ // profiles as unique_ptr.
+ std::vector<AutofillProfile*> profiles;
+ for (const auto& profile : profiles_cache_) {
+ profiles.push_back(profile.get());
+ }
+ AutofillProfile::CreateDifferentiatingLabels(profiles, app_locale_, &labels);
+ DCHECK_EQ(labels.size(), profiles_cache_.size());
+
+ for (size_t i = 0; i < profiles_cache_.size(); ++i) {
+ // Skip showing auxiliary profiles (e.g. Mac Contacts).
+ if (profiles_cache_[i]->record_type() == AutofillProfile::AUXILIARY_PROFILE)
+ continue;
+
+ addresses_.push_back(std::make_pair(profiles_cache_[i]->guid(), labels[i]));
+ }
+
+ for (auto& observer : observers_) {
+ observer.OnComboboxModelChanged(this);
+ }
+}
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_combobox_model.h b/chromium/components/autofill/core/browser/address_combobox_model.h
new file mode 100644
index 00000000000..f8b09f44977
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_combobox_model.h
@@ -0,0 +1,82 @@
+// Copyright 2017 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_COMBOBOX_MODEL_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_COMBOBOX_MODEL_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "base/strings/string16.h"
+#include "ui/base/models/combobox_model.h"
+
+namespace autofill {
+
+class AutofillProfile;
+class PersonalDataManager;
+
+// A combobox model for listing addresses by a generated user visible string and
+// have a unique id to identify the one selected by the user.
+class AddressComboboxModel : public ui::ComboboxModel {
+ public:
+ // Enumerate the profiles from |personal_data_manager| to expose them in a
+ // combobox using |app_locale| for proper format. |default_selected_guid| is
+ // an optional argument to specify which address should be selected by
+ // default.
+ AddressComboboxModel(const PersonalDataManager& personal_data_manager,
+ const std::string& app_locale,
+ const std::string& default_selected_guid);
+ ~AddressComboboxModel() override;
+
+ // ui::ComboboxModel implementation:
+ int GetItemCount() const override;
+ base::string16 GetItemAt(int index) override;
+ bool IsItemSeparatorAt(int index) override;
+ int GetDefaultIndex() const override;
+ void AddObserver(ui::ComboboxModelObserver* observer) override;
+ void RemoveObserver(ui::ComboboxModelObserver* observer) override;
+
+ // Adds |profile| to model and return its combobox index. The lifespan of
+ // |profile| beyond this call is undefined so a copy must be made.
+ int AddNewProfile(const AutofillProfile& profile);
+
+ // Returns the unique identifier of the profile at |index|, unless |index|
+ // refers to a special entry, in which case an empty string is returned.
+ std::string GetItemIdentifierAt(int index);
+
+ // Returns the combobox index of the item with the given id or -1 if it's not
+ // found.
+ int GetIndexOfIdentifier(const std::string& identifier) const;
+
+ private:
+ // Update |addresses_| based on |profiles_cache_| and notify observers.
+ void UpdateAddresses();
+
+ // List of <id, user visible string> pairs for the addresses extracted from
+ // the |personal_data_manager| passed in the constructor.
+ std::vector<std::pair<std::string, base::string16>> addresses_;
+
+ // A cached copy of all profiles to allow rebuilding the differentiating
+ // labels when new profiles are added.
+ std::vector<std::unique_ptr<AutofillProfile>> profiles_cache_;
+
+ // Application locale, also needed when a new profile is added.
+ std::string app_locale_;
+
+ // If non empty, the guid of the address that should be selected by default.
+ std::string default_selected_guid_;
+
+ // To be called when the data for the given country code was loaded.
+ base::ObserverList<ui::ComboboxModelObserver> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressComboboxModel);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_COMBOBOX_MODEL_H_
diff --git a/chromium/components/autofill/core/browser/address_combobox_model_unittest.cc b/chromium/components/autofill/core/browser/address_combobox_model_unittest.cc
new file mode 100644
index 00000000000..d05efb0fd0d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_combobox_model_unittest.cc
@@ -0,0 +1,93 @@
+// Copyright 2017 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_combobox_model.h"
+
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/test_personal_data_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
+
+namespace autofill {
+
+namespace {
+const char kAppLocale[] = "fr-CA";
+}
+
+TEST(AddressComboboxModelTest, Empty) {
+ TestPersonalDataManager test_personal_data_manager;
+
+ AddressComboboxModel model(test_personal_data_manager, kAppLocale, "");
+ EXPECT_EQ(1, model.GetItemCount());
+ EXPECT_FALSE(model.IsItemSeparatorAt(0));
+ EXPECT_TRUE(model.GetItemIdentifierAt(0).empty());
+ EXPECT_EQ(-1, model.GetIndexOfIdentifier("Anything"));
+}
+
+TEST(AddressComboboxModelTest, OneAddress) {
+ TestPersonalDataManager test_personal_data_manager;
+ AutofillProfile profile1(test::GetFullProfile());
+ test_personal_data_manager.AddTestingProfile(&profile1);
+
+ AddressComboboxModel model(test_personal_data_manager, kAppLocale,
+ profile1.guid());
+ EXPECT_EQ(3, model.GetItemCount());
+ EXPECT_FALSE(model.IsItemSeparatorAt(0));
+ EXPECT_TRUE(model.IsItemSeparatorAt(1));
+ EXPECT_TRUE(model.GetItemIdentifierAt(0).empty());
+ EXPECT_TRUE(model.GetItemIdentifierAt(1).empty());
+ EXPECT_EQ(-1, model.GetIndexOfIdentifier("Anything"));
+ EXPECT_EQ(profile1.guid(), model.GetItemIdentifierAt(2));
+ EXPECT_EQ(2, model.GetIndexOfIdentifier(profile1.guid()));
+ EXPECT_EQ(2, model.GetDefaultIndex());
+}
+
+TEST(AddressComboboxModelTest, TwoAddresses) {
+ TestPersonalDataManager test_personal_data_manager;
+ AutofillProfile profile1(test::GetFullProfile());
+ AutofillProfile profile2(test::GetFullProfile2());
+
+ // Force |profile1| to be shown first in the combobox.
+ profile1.set_use_count(100);
+ test_personal_data_manager.AddTestingProfile(&profile1);
+ test_personal_data_manager.AddTestingProfile(&profile2);
+
+ AddressComboboxModel model(test_personal_data_manager, kAppLocale,
+ profile2.guid());
+ EXPECT_EQ(4, model.GetItemCount());
+ EXPECT_FALSE(model.IsItemSeparatorAt(0));
+ EXPECT_TRUE(model.IsItemSeparatorAt(1));
+ EXPECT_TRUE(model.GetItemIdentifierAt(0).empty());
+ EXPECT_TRUE(model.GetItemIdentifierAt(1).empty());
+ EXPECT_EQ(-1, model.GetIndexOfIdentifier("Anything"));
+ EXPECT_EQ(profile1.guid(), model.GetItemIdentifierAt(2));
+ EXPECT_EQ(profile2.guid(), model.GetItemIdentifierAt(3));
+ EXPECT_EQ(2, model.GetIndexOfIdentifier(profile1.guid()));
+ EXPECT_EQ(3, model.GetIndexOfIdentifier(profile2.guid()));
+ EXPECT_EQ(3, model.GetDefaultIndex());
+}
+
+TEST(AddressComboboxModelTest, AddAnAddress) {
+ TestPersonalDataManager test_personal_data_manager;
+ AutofillProfile profile1(test::GetFullProfile());
+ test_personal_data_manager.AddTestingProfile(&profile1);
+
+ AddressComboboxModel model(test_personal_data_manager, kAppLocale, "");
+ EXPECT_EQ(3, model.GetItemCount());
+ EXPECT_EQ(profile1.guid(), model.GetItemIdentifierAt(2));
+ EXPECT_EQ(2, model.GetIndexOfIdentifier(profile1.guid()));
+
+ AutofillProfile profile2(test::GetFullProfile2());
+ int new_profile_index = model.AddNewProfile(profile2);
+ EXPECT_EQ(3, new_profile_index);
+ EXPECT_EQ(4, model.GetItemCount());
+ EXPECT_EQ(profile2.guid(), model.GetItemIdentifierAt(3));
+ EXPECT_EQ(3, model.GetIndexOfIdentifier(profile2.guid()));
+
+ // First profile shouldn't have changed, here the order is guaranteed.
+ EXPECT_EQ(profile1.guid(), model.GetItemIdentifierAt(2));
+ EXPECT_EQ(2, model.GetIndexOfIdentifier(profile1.guid()));
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_field.cc b/chromium/components/autofill/core/browser/address_field.cc
index 08fdd7c8938..c8d2c446f07 100644
--- a/chromium/components/autofill/core/browser/address_field.cc
+++ b/chromium/components/autofill/core/browser/address_field.cc
@@ -14,9 +14,9 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_field.h"
-#include "components/autofill/core/browser/autofill_regex_constants.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
using base::UTF8ToUTF16;
diff --git a/chromium/components/autofill/core/browser/autofill_address_util.cc b/chromium/components/autofill/core/browser/autofill_address_util.cc
index c232e002651..bdeea813bf5 100644
--- a/chromium/components/autofill/core/browser/autofill_address_util.cc
+++ b/chromium/components/autofill/core/browser/autofill_address_util.cc
@@ -7,11 +7,11 @@
#include <memory>
#include <utility>
+#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"
#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/country_combobox_model.h"
-#include "components/autofill/core/browser/field_types.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h"
@@ -43,6 +43,29 @@ const char kCountryField[] = "country";
const char kShortField[] = "short";
const char kLongField[] = "long";
+ServerFieldType GetFieldTypeFromString(const std::string& type) {
+ if (type == kFullNameField)
+ return NAME_FULL;
+ if (type == kCompanyNameField)
+ return COMPANY_NAME;
+ if (type == kAddressLineField)
+ return ADDRESS_HOME_STREET_ADDRESS;
+ if (type == kDependentLocalityField)
+ return ADDRESS_HOME_DEPENDENT_LOCALITY;
+ if (type == kCityField)
+ return ADDRESS_HOME_CITY;
+ if (type == kStateField)
+ return ADDRESS_HOME_STATE;
+ if (type == kPostalCodeField)
+ return ADDRESS_HOME_ZIP;
+ if (type == kSortingCodeField)
+ return ADDRESS_HOME_SORTING_CODE;
+ if (type == kCountryField)
+ return ADDRESS_HOME_COUNTRY;
+ NOTREACHED();
+ return UNKNOWN_TYPE;
+}
+
// Fills |components| with the address UI components that should be used to
// input an address for |country_code| when UI BCP 47 language code is
// |ui_language_code|. If |components_language_code| is not NULL, then sets it
diff --git a/chromium/components/autofill/core/browser/autofill_address_util.h b/chromium/components/autofill/core/browser/autofill_address_util.h
index e90ff5bfabe..83f3960e99e 100644
--- a/chromium/components/autofill/core/browser/autofill_address_util.h
+++ b/chromium/components/autofill/core/browser/autofill_address_util.h
@@ -7,6 +7,8 @@
#include <string>
+#include "components/autofill/core/browser/field_types.h"
+
namespace base {
class ListValue;
class DictionaryValue;
@@ -58,6 +60,11 @@ extern const char kShortField[];
// AddressUiComponent::HINT_LONG.
extern const char kLongField[];
+// Converts a field type in string format as returned by
+// autofill::GetAddressComponents into the appropriate autofill::ServerFieldType
+// enum.
+ServerFieldType GetFieldTypeFromString(const std::string& type);
+
// Fills |components| with the address UI components that should be used to
// input an address for |country_code| when UI BCP 47 language code is
// |ui_language_code|. If |components_language_code| is not NULL, then sets it
diff --git a/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc b/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc
index d5b27e105b2..d7fb2f020c8 100644
--- a/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc
@@ -5,6 +5,7 @@
#include "components/autofill/core/browser/autofill_assistant.h"
#include <memory>
+#include <utility>
#include "base/callback.h"
#include "base/feature_list.h"
@@ -231,7 +232,8 @@ TEST_F(AutofillAssistantTest, ShowAssistForCreditCard_ValidCard_CancelCvc) {
// Create a valid card for the assist.
CreditCard card;
- test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999");
+ test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999",
+ "1");
// FillCreditCardForm should not be called if the user cancelled the CVC.
EXPECT_CALL(autofill_manager_, FillCreditCardForm(_, _, _, _, _)).Times(0);
@@ -253,7 +255,8 @@ TEST_F(AutofillAssistantTest, ShowAssistForCreditCard_ValidCard_SubmitCvc) {
// Create a valid card for the assist.
CreditCard card;
- test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999");
+ test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999",
+ "1");
// FillCreditCardForm ends up being called after user has accepted the
// prompt.
diff --git a/chromium/components/autofill/core/browser/autofill_client.h b/chromium/components/autofill/core/browser/autofill_client.h
index f6ff075d059..9084f772daa 100644
--- a/chromium/components/autofill/core/browser/autofill_client.h
+++ b/chromium/components/autofill/core/browser/autofill_client.h
@@ -38,7 +38,7 @@ class SyncService;
}
namespace ukm {
-class UkmService;
+class UkmRecorder;
}
namespace autofill {
@@ -112,7 +112,7 @@ class AutofillClient : public RiskDataLoader {
virtual rappor::RapporServiceImpl* GetRapporServiceImpl() = 0;
// Gets the UKM service associated with this client (for metrics).
- virtual ukm::UkmService* GetUkmService() = 0;
+ virtual ukm::UkmRecorder* GetUkmRecorder() = 0;
// Gets the SaveCardBubbleController instance associated with the client.
// May return nullptr if the save card bubble has not been shown yet.
diff --git a/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc b/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc
index 5f0942c539e..2de1eae75f4 100644
--- a/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc
@@ -22,9 +22,9 @@ AutofillCreditCardFillingInfoBarDelegateMobile::
card_filling_callback_(card_filling_callback),
had_user_interaction_(false),
was_shown_(false),
- issuer_icon_id_(CreditCard::IconResourceId(card.type())),
+ issuer_icon_id_(CreditCard::IconResourceId(card.network())),
#if defined(OS_IOS)
- card_label_(card.TypeAndLastFourDigits()),
+ card_label_(card.NetworkAndLastFourDigits()),
#else
card_label_(base::string16(kMidlineEllipsis) + card.LastFourDigits()),
#endif
diff --git a/chromium/components/autofill/core/browser/autofill_data_util.cc b/chromium/components/autofill/core/browser/autofill_data_util.cc
index f55ec9068c5..0c06eed93bf 100644
--- a/chromium/components/autofill/core/browser/autofill_data_util.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_util.cc
@@ -8,32 +8,43 @@
#include <vector>
#include "base/i18n/char_iterator.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/grit/components_scaled_resources.h"
+#include "components/strings/grit/components_strings.h"
#include "third_party/icu/source/common/unicode/uscript.h"
+#include "third_party/re2/src/re2/re2.h"
namespace autofill {
namespace data_util {
namespace {
-// Mappings from Chrome card types to Payment Request API basic card payment
-// spec types and icons. Note that "generic" is not in the spec.
+// 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
const PaymentRequestData kPaymentRequestData[]{
- {"americanExpressCC", "amex", IDR_AUTOFILL_PR_AMEX},
- {"dinersCC", "diners", IDR_AUTOFILL_PR_DINERS},
- {"discoverCC", "discover", IDR_AUTOFILL_PR_DISCOVER},
- {"jcbCC", "jcb", IDR_AUTOFILL_PR_JCB},
- {"masterCardCC", "mastercard", IDR_AUTOFILL_PR_MASTERCARD},
- {"mirCC", "mir", IDR_AUTOFILL_PR_MIR},
- {"unionPayCC", "unionpay", IDR_AUTOFILL_PR_UNIONPAY},
- {"visaCC", "visa", IDR_AUTOFILL_PR_VISA},
+ {autofill::kAmericanExpressCard, "amex", IDR_AUTOFILL_CC_AMEX,
+ IDS_AUTOFILL_CC_AMEX},
+ {autofill::kDinersCard, "diners", IDR_AUTOFILL_CC_DINERS,
+ IDS_AUTOFILL_CC_DINERS},
+ {autofill::kDiscoverCard, "discover", IDR_AUTOFILL_CC_DISCOVER,
+ IDS_AUTOFILL_CC_DISCOVER},
+ {autofill::kEloCard, "elo", IDR_AUTOFILL_CC_ELO, IDS_AUTOFILL_CC_ELO},
+ {autofill::kJCBCard, "jcb", IDR_AUTOFILL_CC_JCB, IDS_AUTOFILL_CC_JCB},
+ {autofill::kMasterCard, "mastercard", IDR_AUTOFILL_CC_MASTERCARD,
+ IDS_AUTOFILL_CC_MASTERCARD},
+ {autofill::kMirCard, "mir", IDR_AUTOFILL_CC_MIR, IDS_AUTOFILL_CC_MIR},
+ {autofill::kUnionPay, "unionpay", IDR_AUTOFILL_CC_UNIONPAY,
+ IDS_AUTOFILL_CC_UNION_PAY},
+ {autofill::kVisaCard, "visa", IDR_AUTOFILL_CC_VISA, IDS_AUTOFILL_CC_VISA},
};
-const PaymentRequestData kGenericPaymentRequestData = {"genericCC", "generic",
- IDR_AUTOFILL_PR_GENERIC};
+const PaymentRequestData kGenericPaymentRequestData = {
+ autofill::kGenericCard, "generic", IDR_AUTOFILL_CC_GENERIC,
+ IDS_AUTOFILL_CC_GENERIC};
const char* const name_prefixes[] = {
"1lt", "1st", "2lt", "2nd", "3rd", "admiral", "capt",
@@ -121,15 +132,15 @@ void StripSuffixes(std::vector<base::StringPiece16>* name_tokens) {
// none is found.
size_t StartsWithAny(base::StringPiece16 name, const char** prefixes,
size_t prefix_count) {
- base::string16 buffer;
- for (size_t i = 0; i < prefix_count; i++) {
- buffer.clear();
- base::UTF8ToUTF16(prefixes[i], strlen(prefixes[i]), &buffer);
- if (base::StartsWith(name, buffer, base::CompareCase::SENSITIVE)) {
- return buffer.size();
- }
- }
- return 0;
+ base::string16 buffer;
+ for (size_t i = 0; i < prefix_count; i++) {
+ buffer.clear();
+ base::UTF8ToUTF16(prefixes[i], strlen(prefixes[i]), &buffer);
+ if (base::StartsWith(name, buffer, base::CompareCase::SENSITIVE)) {
+ return buffer.size();
+ }
+ }
+ return 0;
}
// Returns true if |c| is a CJK (Chinese, Japanese, Korean) character, for any
@@ -401,22 +412,34 @@ bool ProfileMatchesFullName(base::StringPiece16 full_name,
return false;
}
-const PaymentRequestData& GetPaymentRequestData(const std::string& type) {
+const PaymentRequestData& GetPaymentRequestData(
+ const std::string& issuer_network) {
for (const PaymentRequestData& data : kPaymentRequestData) {
- if (type == data.card_type)
+ if (issuer_network == data.issuer_network)
return data;
}
return kGenericPaymentRequestData;
}
-const char* GetCardTypeForBasicCardPaymentType(
- const std::string& basic_card_payment_type) {
+const char* GetIssuerNetworkForBasicCardIssuerNetwork(
+ const std::string& basic_card_issuer_network) {
for (const PaymentRequestData& data : kPaymentRequestData) {
- if (basic_card_payment_type == data.basic_card_payment_type) {
- return data.card_type;
+ if (basic_card_issuer_network == data.basic_card_issuer_network) {
+ return data.issuer_network;
}
}
- return kGenericPaymentRequestData.card_type;
+ return kGenericPaymentRequestData.issuer_network;
+}
+
+bool IsValidCountryCode(const std::string& country_code) {
+ if (country_code.size() != 2)
+ return false;
+
+ return re2::RE2::FullMatch(country_code, "^[A-Z]{2}$");
+}
+
+bool IsValidCountryCode(const base::string16& country_code) {
+ return IsValidCountryCode(base::UTF16ToUTF8(country_code));
}
} // namespace data_util
diff --git a/chromium/components/autofill/core/browser/autofill_data_util.h b/chromium/components/autofill/core/browser/autofill_data_util.h
index 2084c361594..2e3d6fcb1a5 100644
--- a/chromium/components/autofill/core/browser/autofill_data_util.h
+++ b/chromium/components/autofill/core/browser/autofill_data_util.h
@@ -5,8 +5,10 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_DATA_UTIL_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_DATA_UTIL_H_
+#include <string>
+
#include "base/strings/string16.h"
-#include "base/strings/string_piece.h"
+#include "base/strings/string_piece_forward.h"
#include "components/autofill/core/browser/autofill_profile.h"
namespace autofill {
@@ -18,12 +20,14 @@ struct NameParts {
base::string16 family;
};
-// Used to map Chrome card types to Payment Request API basic card payment spec
-// types and icons. https://w3c.github.io/webpayments-methods-card/#method-id
+// Used to map Chrome card issuer networks to Payment Request API basic card
+// payment spec issuer networks and icons.
+// https://w3c.github.io/webpayments-methods-card/#method-id
struct PaymentRequestData {
- const char* card_type;
- const char* basic_card_payment_type;
+ const char* issuer_network;
+ const char* basic_card_issuer_network;
const int icon_resource_id;
+ const int a11y_label_resource_id;
};
// Returns true if |name| looks like a CJK name (or some kind of mish-mash of
@@ -48,13 +52,19 @@ bool ProfileMatchesFullName(base::StringPiece16 full_name,
const autofill::AutofillProfile& profile);
// Returns the Payment Request API basic card payment spec data for the provided
-// autofill credit card |type|. Will set the type and the icon to "generic" for
-// any unrecognized type.
-const PaymentRequestData& GetPaymentRequestData(const std::string& type);
+// autofill credit card |network|. Will set the network and the icon to
+// "generic" for any unrecognized type.
+const PaymentRequestData& GetPaymentRequestData(
+ const std::string& issuer_network);
+
+// Returns the autofill credit card issuer network string for the provided
+// Payment Request API basic card payment spec |basic_card_card_issuer_network|.
+const char* GetIssuerNetworkForBasicCardIssuerNetwork(
+ const std::string& basic_card_issuer_network);
-// Returns the autofill credit card type string for the provided Payment Request
-// API basic card payment spec |type|.
-const char* GetCardTypeForBasicCardPaymentType(const std::string& type);
+// Returns whether the specified |country_code| is a valid country code.
+bool IsValidCountryCode(const std::string& country_code);
+bool IsValidCountryCode(const base::string16& country_code);
} // namespace data_util
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc b/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
index 9aadd58bf4f..1a66f8e59a4 100644
--- a/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
@@ -198,5 +198,46 @@ TEST(AutofillDataUtilTest, ProfileMatchesFullName) {
ProfileMatchesFullName(base::UTF8ToUTF16("Kirby Puckett"), profile));
}
+struct ValidCountryCodeTestCase {
+ std::string country_code;
+ bool expected_result;
+};
+
+class ValidCountryCodeTest
+ : public testing::TestWithParam<ValidCountryCodeTestCase> {};
+
+TEST_P(ValidCountryCodeTest, ValidCountryCode) {
+ auto test_case = GetParam();
+ EXPECT_EQ(test_case.expected_result,
+ IsValidCountryCode(test_case.country_code));
+}
+
+INSTANTIATE_TEST_CASE_P(
+ AutofillDataUtil,
+ ValidCountryCodeTest,
+ testing::Values(
+ // Valid country codes.
+ ValidCountryCodeTestCase{"US", true},
+ ValidCountryCodeTestCase{"CA", true},
+ ValidCountryCodeTestCase{"CN", true},
+
+ // Country names should not be considered valid.
+ ValidCountryCodeTestCase{"United States", false},
+ ValidCountryCodeTestCase{"Canada", false},
+ ValidCountryCodeTestCase{"China", false},
+
+ // Codes with numbers should not be considered valid.
+ ValidCountryCodeTestCase{"C2", false},
+
+ // Three letters abbreviations should not be considered valid.
+ ValidCountryCodeTestCase{"USA", false},
+ ValidCountryCodeTestCase{"CAN", false},
+ ValidCountryCodeTestCase{"CHN", false},
+
+ // Lowercase is invalid.
+ ValidCountryCodeTestCase{"us", false},
+ ValidCountryCodeTestCase{"Ca", false},
+ ValidCountryCodeTestCase{"cN", false}));
+
} // namespace data_util
} // namespace autofill
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 73768ad2ace..74ce62b4bde 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -12,6 +12,7 @@
#include <vector>
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
diff --git a/chromium/components/autofill/core/browser/autofill_driver.h b/chromium/components/autofill/core/browser/autofill_driver.h
index cc1a5fd38c1..5422060f529 100644
--- a/chromium/components/autofill/core/browser/autofill_driver.h
+++ b/chromium/components/autofill/core/browser/autofill_driver.h
@@ -9,10 +9,6 @@
#include "components/autofill/core/common/form_data.h"
-namespace base {
-class SequencedWorkerPool;
-}
-
namespace net {
class URLRequestContextGetter;
}
@@ -46,10 +42,6 @@ class AutofillDriver {
// Returns the URL request context information associated with this driver.
virtual net::URLRequestContextGetter* GetURLRequestContext() = 0;
- // Returns the SequencedWorkerPool on which core Autofill code should run
- // tasks that may block. This pool must live at least as long as the driver.
- virtual base::SequencedWorkerPool* GetBlockingPool() = 0;
-
// Returns true iff the renderer is available for communication.
virtual bool RendererIsAvailable() = 0;
diff --git a/chromium/components/autofill/core/browser/autofill_experiments.cc b/chromium/components/autofill/core/browser/autofill_experiments.cc
index ef37213e57a..e667d896369 100644
--- a/chromium/components/autofill/core/browser/autofill_experiments.cc
+++ b/chromium/components/autofill/core/browser/autofill_experiments.cc
@@ -11,6 +11,7 @@
#include "base/strings/string_number_conversions.h"
#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/suggestion.h"
#include "components/autofill/core/common/autofill_pref_names.h"
@@ -32,10 +33,17 @@ const base::Feature kAutofillCreditCardPopupLayout{
"AutofillCreditCardPopupLayout", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kAutofillCreditCardLastUsedDateDisplay{
"AutofillCreditCardLastUsedDateDisplay", base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kAutofillUkmLogging{"AutofillUkmLogging",
- base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kAutofillOfferLocalSaveIfServerCardManuallyEntered{
+ "AutofillOfferLocalSaveIfServerCardManuallyEntered",
+ base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kAutofillUpstreamRequestCvcIfMissing{
"AutofillUpstreamRequestCvcIfMissing", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kAutofillUpstreamUseAutofillProfileComparator{
+ "AutofillUpstreamUseAutofillProfileComparator",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kAutofillUpstreamUseNotRecentlyUsedAutofillProfile{
+ "AutofillUpstreamUseNotRecentlyUsedAutofillProfile",
+ base::FEATURE_DISABLED_BY_DEFAULT};
const char kCreditCardSigninPromoImpressionLimitParamKey[] = "impression_limit";
const char kAutofillCreditCardPopupBackgroundColorKey[] = "background_color";
const char kAutofillCreditCardPopupDividerColorKey[] = "dropdown_divider_color";
@@ -48,6 +56,8 @@ const char kAutofillCreditCardPopupIsIconAtStartKey[] =
const char kAutofillPopupMarginKey[] = "margin";
const char kAutofillCreditCardLastUsedDateShowExpirationDateKey[] =
"show_expiration_date";
+const char kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey[] =
+ "max_minutes_since_autofill_profile_use";
namespace {
@@ -227,8 +237,9 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
return !group_name.empty() && group_name != "Disabled";
}
-bool IsUkmLoggingEnabled() {
- return base::FeatureList::IsEnabled(kAutofillUkmLogging);
+bool IsAutofillOfferLocalSaveIfServerCardManuallyEnteredExperimentEnabled() {
+ return base::FeatureList::IsEnabled(
+ kAutofillOfferLocalSaveIfServerCardManuallyEntered);
}
bool IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled() {
@@ -239,4 +250,14 @@ bool IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled() {
#endif
}
+base::TimeDelta GetMaxTimeSinceAutofillProfileUseForCardUpload() {
+ int value;
+ const std::string param_value = variations::GetVariationParamValueByFeature(
+ kAutofillUpstreamUseNotRecentlyUsedAutofillProfile,
+ kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey);
+ if (!param_value.empty() && base::StringToInt(param_value, &value))
+ return base::TimeDelta::FromMinutes(value);
+ return base::TimeDelta();
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_experiments.h b/chromium/components/autofill/core/browser/autofill_experiments.h
index ba03ac21eb7..7ed13140bbf 100644
--- a/chromium/components/autofill/core/browser/autofill_experiments.h
+++ b/chromium/components/autofill/core/browser/autofill_experiments.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/strings/string16.h"
+#include "base/time/time.h"
#include "third_party/skia/include/core/SkColor.h"
class PrefService;
@@ -28,11 +29,13 @@ extern const base::Feature kAutofillCreditCardAssist;
extern const base::Feature kAutofillScanCardholderName;
extern const base::Feature kAutofillCreditCardPopupLayout;
extern const base::Feature kAutofillCreditCardLastUsedDateDisplay;
-extern const base::Feature kAutofillUkmLogging;
+extern const base::Feature kAutofillOfferLocalSaveIfServerCardManuallyEntered;
extern const base::Feature kAutofillUpstreamRequestCvcIfMissing;
+extern const base::Feature kAutofillUpstreamUseAutofillProfileComparator;
+extern const base::Feature kAutofillUpstreamUseNotRecentlyUsedAutofillProfile;
extern const char kCreditCardSigninPromoImpressionLimitParamKey[];
-extern const char kAutofillCreditCardPopupSettingsSuggestionValueKey[];
extern const char kAutofillCreditCardLastUsedDateShowExpirationDateKey[];
+extern const char kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey[];
// Returns true if autofill should be enabled. See also
// IsInAutofillSuggestionsDisabledExperiment below.
@@ -102,13 +105,21 @@ void ModifyAutofillCreditCardSuggestion(struct Suggestion* suggestion);
// layout.
unsigned int GetPopupMargin();
-// Returns whether the feature to log UKMs is enabled.
-bool IsUkmLoggingEnabled();
+// Returns whether the experiment is enabled where if Chrome Autofill has a
+// server card synced down from Payments but the user manually enters its card
+// number into a checkout form anyway, the option to locally save the card is
+// offered.
+bool IsAutofillOfferLocalSaveIfServerCardManuallyEnteredExperimentEnabled();
// Returns whether the experiment is enabled where Chrome Upstream requests CVC
// in the offer to save bubble if it was not detected during the checkout flow.
bool IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled();
+// Returns the maximum time that could have elapsed since an address profile's
+// most recent use for the adress profile to be included in the candidate set
+// for card upload. Returns 0 if the experiment is not enabled.
+base::TimeDelta GetMaxTimeSinceAutofillProfileUseForCardUpload();
+
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_
diff --git a/chromium/components/autofill/core/browser/autofill_external_delegate.cc b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
index 3db7f0fd00b..27e046d10b6 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
@@ -83,9 +83,8 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
if (query_id != query_id_)
return;
- // The suggestions and warnings are "above the fold" and are separated from
- // other menu items with a separator.
std::vector<Suggestion> suggestions(input_suggestions);
+
// Hide warnings as appropriate.
PossiblyRemoveAutofillWarnings(&suggestions);
@@ -339,19 +338,31 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
if (query_field_.is_autofilled) {
base::string16 value =
l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM);
+#if defined(OS_ANDROID)
if (IsKeyboardAccessoryEnabled())
value = base::i18n::ToUpper(value);
+#endif
suggestions->push_back(Suggestion(value));
suggestions->back().frontend_id = POPUP_ITEM_ID_CLEAR_FORM;
}
// Append the 'Chrome Autofill options' menu item, or the menu item specified
- // in the popup layout experiment.
+ // in the popup layout experiment. If we do not include
+ // |POPUP_ITEM_ID_CLEAR_FORM|, include a hint for keyboard accessory.
suggestions->push_back(Suggestion(GetSettingsSuggestionValue()));
suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS;
- if (IsKeyboardAccessoryEnabled())
+#if defined(OS_ANDROID)
+ if (IsKeyboardAccessoryEnabled()) {
suggestions->back().icon = base::ASCIIToUTF16("settings");
+ if (IsHintEnabledInKeyboardAccessory() && !query_field_.is_autofilled) {
+ Suggestion create_icon;
+ create_icon.icon = base::ASCIIToUTF16("create");
+ create_icon.frontend_id = POPUP_ITEM_ID_CREATE_HINT;
+ suggestions->push_back(create_icon);
+ }
+ }
+#endif
}
void AutofillExternalDelegate::InsertDataListValues(
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 97bd64b385c..11f7ce910e4 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -690,7 +690,7 @@ MATCHER_P(CreditCardMatches, card, "") {
// credit card.
TEST_F(AutofillExternalDelegateUnitTest, FillCreditCardForm) {
CreditCard card;
- test::SetCreditCardInfo(&card, "Alice", "4111", "1", "3000");
+ test::SetCreditCardInfo(&card, "Alice", "4111", "1", "3000", "1");
EXPECT_CALL(*autofill_manager_,
FillCreditCardForm(_, _, _, CreditCardMatches(card), base::string16()));
external_delegate_->OnCreditCardScanned(card);
diff --git a/chromium/components/autofill/core/browser/autofill_field.cc b/chromium/components/autofill/core/browser/autofill_field.cc
index 3704b10fd12..1f37285c510 100644
--- a/chromium/components/autofill/core/browser/autofill_field.cc
+++ b/chromium/components/autofill/core/browser/autofill_field.cc
@@ -289,9 +289,9 @@ bool FillYearSelectControl(const base::string16& value,
return false;
}
-// Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the
+// Try to fill a credit card type |value| (Visa, Mastercard, etc.) into the
// given |field|. We ignore whitespace when filling credit card types to
-// allow for cases such as "Master Card".
+// allow for cases such as "Master card".
bool FillCreditCardTypeSelectControl(const base::string16& value,
FormFieldData* field) {
diff --git a/chromium/components/autofill/core/browser/autofill_field_unittest.cc b/chromium/components/autofill/core/browser/autofill_field_unittest.cc
index 5731f376ace..ef6b2e87bea 100644
--- a/chromium/components/autofill/core/browser/autofill_field_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_field_unittest.cc
@@ -799,7 +799,7 @@ TEST_F(AutofillFieldTest, FillSelectControlWithTwoDigitCreditCardYear) {
}
TEST_F(AutofillFieldTest, FillSelectControlWithCreditCardType) {
- std::vector<const char*> kCreditCardTypes = {"Visa", "Master Card", "AmEx",
+ std::vector<const char*> kCreditCardTypes = {"Visa", "Mastercard", "AmEx",
"discover"};
AutofillField field;
test::CreateTestSelectField(kCreditCardTypes, &field);
@@ -812,8 +812,17 @@ TEST_F(AutofillFieldTest, FillSelectControlWithCreditCardType) {
// Filling should be able to handle intervening whitespace:
AutofillField::FillFormField(
+ field, ASCIIToUTF16("Master card"), "en-US", "en-US", &field);
+ EXPECT_EQ(ASCIIToUTF16("Mastercard"), field.value);
+
+ // Mastercard is sometimes shown as MasterCard or Master Card:
+ AutofillField::FillFormField(
field, ASCIIToUTF16("MasterCard"), "en-US", "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("Master Card"), field.value);
+ EXPECT_EQ(ASCIIToUTF16("Mastercard"), field.value);
+
+ AutofillField::FillFormField(
+ field, ASCIIToUTF16("Master Card"), "en-US", "en-US", &field);
+ EXPECT_EQ(ASCIIToUTF16("Mastercard"), field.value);
// American Express is sometimes abbreviated as AmEx:
AutofillField::FillFormField(
diff --git a/chromium/components/autofill/core/browser/autofill_manager.cc b/chromium/components/autofill/core/browser/autofill_manager.cc
index 933b7c5dd41..524f5293bfb 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager.cc
@@ -23,6 +23,7 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
@@ -30,8 +31,9 @@
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autocomplete_history_manager.h"
#include "components/autofill/core/browser/autofill_client.h"
@@ -42,6 +44,7 @@
#include "components/autofill/core/browser/autofill_manager_test_delegate.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/autofill_type.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/credit_card.h"
@@ -227,7 +230,7 @@ AutofillManager::AutofillManager(
base::MakeUnique<AutocompleteHistoryManager>(driver, client)),
form_interactions_ukm_logger_(
base::MakeUnique<AutofillMetrics::FormInteractionsUkmLogger>(
- client->GetUkmService())),
+ client->GetUkmRecorder())),
address_form_event_logger_(
base::MakeUnique<AutofillMetrics::FormEventLogger>(
false /* is_for_credit_card */,
@@ -244,6 +247,9 @@ AutofillManager::AutofillManager(
user_did_edit_autofilled_field_(false),
user_did_accept_upload_prompt_(false),
should_cvc_be_requested_(false),
+ found_cvc_field_(false),
+ found_value_in_cvc_field_(false),
+ found_cvc_value_in_non_cvc_field_(false),
external_delegate_(NULL),
test_delegate_(NULL),
#if defined(OS_ANDROID) || defined(OS_IOS)
@@ -284,6 +290,9 @@ void AutofillManager::RegisterProfilePrefs(
registry->RegisterBooleanPref(prefs::kAutofillWalletImportEnabled, true);
registry->RegisterBooleanPref(
prefs::kAutofillWalletImportStorageCheckboxState, true);
+ registry->RegisterIntegerPref(
+ prefs::kAutofillAcceptSaveCreditCardPromptState,
+ prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_NONE);
}
void AutofillManager::SetExternalDelegate(AutofillExternalDelegate* delegate) {
@@ -470,15 +479,16 @@ void AutofillManager::StartUploadProcess(
FormStructure* raw_form = form_structure.get();
TimeTicks loaded_timestamp =
forms_loaded_timestamps_[raw_form->ToFormData()];
- driver_->GetBlockingPool()->PostTaskAndReply(
- FROM_HERE,
- base::Bind(&AutofillManager::DeterminePossibleFieldTypesForUpload,
- copied_profiles, copied_credit_cards, app_locale_, raw_form),
- base::Bind(&AutofillManager::UploadFormDataAsyncCallback,
- weak_ptr_factory_.GetWeakPtr(),
- base::Owned(form_structure.release()), loaded_timestamp,
- initial_interaction_timestamp_, timestamp,
- observed_submission));
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
+ base::BindOnce(&AutofillManager::DeterminePossibleFieldTypesForUpload,
+ copied_profiles, copied_credit_cards, app_locale_,
+ raw_form),
+ base::BindOnce(&AutofillManager::UploadFormDataAsyncCallback,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Owned(form_structure.release()), loaded_timestamp,
+ initial_interaction_timestamp_, timestamp,
+ observed_submission));
}
}
@@ -855,9 +865,9 @@ void AutofillManager::DidShowSuggestions(bool is_new_popup,
}
if (autofill_field->Type().group() == CREDIT_CARD) {
- credit_card_form_event_logger_->OnDidShowSuggestions();
+ credit_card_form_event_logger_->OnDidShowSuggestions(*autofill_field);
} else {
- address_form_event_logger_->OnDidShowSuggestions();
+ address_form_event_logger_->OnDidShowSuggestions(*autofill_field);
}
}
}
@@ -895,7 +905,7 @@ bool AutofillManager::GetDeletionConfirmationText(const base::string16& value,
return false;
if (title)
- title->assign(credit_card->TypeAndLastFourDigits());
+ title->assign(credit_card->NetworkAndLastFourDigits());
if (body) {
body->assign(l10n_util::GetStringUTF16(
IDS_AUTOFILL_DELETE_CREDIT_CARD_SUGGESTION_CONFIRMATION_BODY));
@@ -1038,7 +1048,7 @@ void AutofillManager::OnDidGetUploadDetails(
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
std::unique_ptr<base::DictionaryValue> legal_message) {
- // TODO(jdonnelly): Log duration.
+ int upload_decision_metrics;
if (result == AutofillClient::SUCCESS) {
// Do *not* call payments_client_->Prepare() here. We shouldn't send
// credentials until the user has explicitly accepted a prompt to upload.
@@ -1051,11 +1061,7 @@ void AutofillManager::OnDidGetUploadDetails(
weak_ptr_factory_.GetWeakPtr()));
client_->LoadRiskData(base::Bind(&AutofillManager::OnDidGetUploadRiskData,
weak_ptr_factory_.GetWeakPtr()));
- AutofillMetrics::CardUploadDecisionMetric card_upload_decision_metric =
- should_cvc_be_requested_ ? AutofillMetrics::UPLOAD_OFFERED_NO_CVC
- : AutofillMetrics::UPLOAD_OFFERED;
- AutofillMetrics::LogCardUploadDecisionMetric(card_upload_decision_metric);
- LogCardUploadDecisionUkm(card_upload_decision_metric);
+ upload_decision_metrics = AutofillMetrics::UPLOAD_OFFERED;
} else {
// If the upload details request failed, fall back to a local save. The
// reasoning here is as follows:
@@ -1073,18 +1079,36 @@ void AutofillManager::OnDidGetUploadDetails(
base::Bind(
base::IgnoreResult(&PersonalDataManager::SaveImportedCreditCard),
base::Unretained(personal_data_), upload_request_.card));
- AutofillMetrics::LogCardUploadDecisionMetric(
- AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED);
- LogCardUploadDecisionUkm(
- AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED);
+ upload_decision_metrics =
+ AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED;
}
+
+ if (!found_cvc_field_ || !found_value_in_cvc_field_)
+ DCHECK(should_cvc_be_requested_);
+
+ if (should_cvc_be_requested_)
+ upload_decision_metrics |= GetCVCCardUploadDecisionMetric();
+ else
+ DCHECK(found_cvc_field_ && found_value_in_cvc_field_);
+
+ LogCardUploadDecisions(upload_decision_metrics);
pending_upload_request_url_ = GURL();
}
-void AutofillManager::OnDidUploadCard(
- AutofillClient::PaymentsRpcResult result) {
- // We don't do anything user-visible if the upload attempt fails.
- // TODO(jdonnelly): Log duration.
+void AutofillManager::OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
+ const std::string& server_id) {
+ // We don't do anything user-visible if the upload attempt fails. If the
+ // upload succeeds and we can store unmasked cards on this OS, we will keep a
+ // copy of the card as a full server card on the device.
+ if (result == AutofillClient::SUCCESS && !server_id.empty() &&
+ OfferStoreUnmaskedCards()) {
+ upload_request_.card.set_record_type(CreditCard::FULL_SERVER_CARD);
+ upload_request_.card.SetServerStatus(CreditCard::OK);
+ upload_request_.card.set_server_id(server_id);
+ DCHECK(personal_data_);
+ if (personal_data_)
+ personal_data_->AddFullServerCreditCard(upload_request_.card);
+ }
}
void AutofillManager::OnFullCardRequestSucceeded(const CreditCard& card,
@@ -1166,10 +1190,11 @@ bool AutofillManager::ShouldUploadForm(const FormStructure& form) {
void AutofillManager::ImportFormData(const FormStructure& submitted_form) {
std::unique_ptr<CreditCard> imported_credit_card;
+ bool imported_credit_card_matches_masked_server_credit_card;
if (!personal_data_->ImportFormData(
- submitted_form, IsCreditCardUploadEnabled(), &imported_credit_card)) {
+ submitted_form, IsCreditCardUploadEnabled(), &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card))
return;
- }
#ifdef ENABLE_FORM_DEBUG_DUMP
// Debug code for research on what autofill Chrome extracts from the last few
@@ -1205,10 +1230,13 @@ void AutofillManager::ImportFormData(const FormStructure& submitted_form) {
if (!imported_credit_card)
return;
- if (!IsCreditCardUploadEnabled()) {
- // This block will only be reached if we have observed a new card. In this
- // case, ImportFormData will return false if the card matches one already
- // stored.
+ if (!IsCreditCardUploadEnabled() ||
+ (IsAutofillOfferLocalSaveIfServerCardManuallyEnteredExperimentEnabled() &&
+ imported_credit_card_matches_masked_server_credit_card)) {
+ // This block will only be reached if we have observed a new card or a card
+ // whose |TypeAndLastFourDigits| matches a masked server card.
+ // |ImportFormData| will return false if the card matches a full card that
+ // we have already stored.
client_->ConfirmSaveCreditCardLocally(
*imported_credit_card,
base::Bind(
@@ -1217,7 +1245,8 @@ void AutofillManager::ImportFormData(const FormStructure& submitted_form) {
} else {
// Whereas, because we pass IsCreditCardUploadEnabled() to ImportFormData,
// this block can be reached on observing either a new card or one already
- // stored locally. We will offer to upload either kind.
+ // stored locally and whose |TypeAndLastFourDigits| do not match a masked
+ // server card. We will offer to upload either kind.
upload_request_ = payments::PaymentsClient::UploadRequestDetails();
upload_request_.card = *imported_credit_card;
@@ -1234,136 +1263,217 @@ void AutofillManager::ImportFormData(const FormStructure& submitted_form) {
// upload and sometimes offering local save is a confusing user experience.
// If no CVC and the experiment is on, request CVC from the user in the
// bubble and save using the provided value.
+ found_cvc_field_ = false;
+ found_value_in_cvc_field_ = false;
+ found_cvc_value_in_non_cvc_field_ = false;
+
for (const auto& field : submitted_form) {
- if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE &&
- IsValidCreditCardSecurityCode(field->value,
- upload_request_.card.type())) {
- upload_request_.cvc = field->value;
- break;
+ const bool is_valid_cvc = IsValidCreditCardSecurityCode(
+ field->value, upload_request_.card.network());
+ if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE) {
+ found_cvc_field_ = true;
+ if (!field->value.empty())
+ found_value_in_cvc_field_ = true;
+ if (is_valid_cvc) {
+ upload_request_.cvc = field->value;
+ break;
+ }
+ } else if (is_valid_cvc &&
+ field->Type().GetStorableType() == UNKNOWN_TYPE) {
+ found_cvc_value_in_non_cvc_field_ = true;
}
}
// Upload requires that recently used or modified addresses meet the
// client-side validation rules.
- autofill::AutofillMetrics::CardUploadDecisionMetric
- get_profiles_decision_metric = AutofillMetrics::UPLOAD_OFFERED;
std::string rappor_metric_name;
- bool get_profiles_succeeded =
- GetProfilesForCreditCardUpload(*imported_credit_card,
- &upload_request_.profiles,
- &get_profiles_decision_metric,
- &rappor_metric_name);
+ int upload_decision_metrics = SetProfilesForCreditCardUpload(
+ *imported_credit_card, &upload_request_, &rappor_metric_name);
pending_upload_request_url_ = GURL(submitted_form.source_url());
- // Both the CVC and address checks are done. Conform to the legacy order of
- // reporting on CVC then address.
should_cvc_be_requested_ = false;
if (upload_request_.cvc.empty()) {
- if (IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled()) {
- should_cvc_be_requested_ = true;
+ should_cvc_be_requested_ =
+ (!upload_decision_metrics &&
+ IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled());
+ if (should_cvc_be_requested_) {
+ upload_request_.active_experiments.push_back(
+ kAutofillUpstreamRequestCvcIfMissing.name);
} else {
- AutofillMetrics::LogCardUploadDecisionMetric(
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
- LogCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
- pending_upload_request_url_ = GURL();
- CollectRapportSample(submitted_form.source_url(),
- "Autofill.CardUploadNotOfferedNoCvc");
- return;
+ upload_decision_metrics |= GetCVCCardUploadDecisionMetric();
+ rappor_metric_name = "Autofill.CardUploadNotOfferedNoCvc";
}
}
- if (!get_profiles_succeeded) {
- DCHECK(get_profiles_decision_metric != AutofillMetrics::UPLOAD_OFFERED);
- AutofillMetrics::LogCardUploadDecisionMetric(
- get_profiles_decision_metric);
- LogCardUploadDecisionUkm(get_profiles_decision_metric);
+ if (upload_decision_metrics) {
+ LogCardUploadDecisions(upload_decision_metrics);
pending_upload_request_url_ = GURL();
if (!rappor_metric_name.empty()) {
- CollectRapportSample(submitted_form.source_url(), rappor_metric_name);
+ CollectRapporSample(submitted_form.source_url(), rappor_metric_name);
}
return;
}
// All required data is available, start the upload process.
- payments_client_->GetUploadDetails(upload_request_.profiles, app_locale_);
+ payments_client_->GetUploadDetails(upload_request_.profiles,
+ upload_request_.active_experiments,
+ app_locale_);
}
}
-bool AutofillManager::GetProfilesForCreditCardUpload(
+AutofillMetrics::CardUploadDecisionMetric
+AutofillManager::GetCVCCardUploadDecisionMetric() const {
+ if (found_cvc_field_)
+ return found_value_in_cvc_field_ ? AutofillMetrics::INVALID_CVC_VALUE
+ : AutofillMetrics::CVC_VALUE_NOT_FOUND;
+ else
+ return found_cvc_value_in_non_cvc_field_
+ ? AutofillMetrics::FOUND_POSSIBLE_CVC_VALUE_IN_NON_CVC_FIELD
+ : AutofillMetrics::CVC_FIELD_NOT_FOUND;
+}
+
+int AutofillManager::SetProfilesForCreditCardUpload(
const CreditCard& card,
- std::vector<AutofillProfile>* profiles,
- autofill::AutofillMetrics::CardUploadDecisionMetric*
- address_upload_decision_metric,
+ payments::PaymentsClient::UploadRequestDetails* upload_request,
std::string* rappor_metric_name) const {
std::vector<AutofillProfile> candidate_profiles;
const base::Time now = AutofillClock::Now();
const base::TimeDelta fifteen_minutes = base::TimeDelta::FromMinutes(15);
+ int upload_decision_metrics = 0;
+ bool has_profile = false;
+ bool has_modified_profile = false;
- // First, collect all of the addresses used recently.
+ // First, collect all of the addresses used or modified recently.
for (AutofillProfile* profile : personal_data_->GetProfiles()) {
- if ((now - profile->use_date()) < fifteen_minutes ||
- (now - profile->modification_date()) < fifteen_minutes) {
+ has_profile = true;
+ if ((now - profile->modification_date()) < fifteen_minutes) {
+ has_modified_profile = true;
+ candidate_profiles.push_back(*profile);
+ } else if ((now - profile->use_date()) < fifteen_minutes) {
candidate_profiles.push_back(*profile);
}
}
+
+ AutofillMetrics::LogHasModifiedProfileOnCreditCardFormSubmission(
+ has_modified_profile);
+
+ // If there are no recently used or modified profiles and experiment to use
+ // profiles that were not recently used is enabled, collect the profiles that
+ // used within the maximum time specified in the experiment.
if (candidate_profiles.empty()) {
- *address_upload_decision_metric =
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS;
+ const base::TimeDelta max_time_since_use =
+ GetMaxTimeSinceAutofillProfileUseForCardUpload();
+ if (!max_time_since_use.is_zero()) {
+ for (AutofillProfile* profile : personal_data_->GetProfiles())
+ if ((now - profile->modification_date()) < max_time_since_use ||
+ (now - profile->use_date()) < max_time_since_use)
+ candidate_profiles.push_back(*profile);
+ if (!candidate_profiles.empty())
+ upload_request->active_experiments.push_back(
+ kAutofillUpstreamUseNotRecentlyUsedAutofillProfile.name);
+ }
+ }
+
+ if (candidate_profiles.empty()) {
+ upload_decision_metrics |=
+ has_profile
+ ? AutofillMetrics::UPLOAD_NOT_OFFERED_NO_RECENTLY_USED_ADDRESS
+ : AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE;
*rappor_metric_name = "Autofill.CardUploadNotOfferedNoAddress";
- return false;
}
- // If any of the names on the card or the addresses don't match (where
- // matching is case insensitive and ignores middle initials if present), the
+ std::unique_ptr<AutofillProfileComparator> comparator;
+ if (!candidate_profiles.empty() &&
+ (base::FeatureList::IsEnabled(
+ kAutofillUpstreamUseAutofillProfileComparator)))
+ comparator = base::MakeUnique<AutofillProfileComparator>(app_locale_);
+
+ // If any of the names on the card or the addresses don't match the
// candidate set is invalid. This matches the rules for name matching applied
// server-side by Google Payments and ensures that we don't send upload
// requests that are guaranteed to fail.
- base::string16 verified_name;
- base::string16 card_name =
+ const base::string16 card_name =
card.GetInfo(AutofillType(CREDIT_CARD_NAME_FULL), app_locale_);
- if (!card_name.empty()) {
- verified_name = RemoveMiddleInitial(card_name);
- }
- for (const AutofillProfile& profile : candidate_profiles) {
- base::string16 address_name =
- profile.GetInfo(AutofillType(NAME_FULL), app_locale_);
- if (!address_name.empty()) {
- if (verified_name.empty()) {
- verified_name = RemoveMiddleInitial(address_name);
- } else {
- // TODO(crbug.com/590307): We only use ASCII case insensitivity here
- // because the feature is launching US-only and middle initials only
- // make sense for Western-style names anyway. As we launch in more
- // countries, we'll need to make the name comparison more sophisticated.
- if (!base::EqualsCaseInsensitiveASCII(
- verified_name, RemoveMiddleInitial(address_name))) {
- *address_upload_decision_metric =
- AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES;
- *rappor_metric_name = "Autofill.CardUploadNotOfferedConflictingNames";
- return false;
+ base::string16 verified_name;
+ if (candidate_profiles.empty()) {
+ verified_name = card_name;
+ } else {
+ bool found_conflicting_names = false;
+ if (comparator) {
+ upload_request->active_experiments.push_back(
+ kAutofillUpstreamUseAutofillProfileComparator.name);
+ verified_name = comparator->NormalizeForComparison(card_name);
+ for (const AutofillProfile& profile : candidate_profiles) {
+ const base::string16 address_name = comparator->NormalizeForComparison(
+ profile.GetInfo(AutofillType(NAME_FULL), app_locale_));
+ if (address_name.empty())
+ continue;
+ if (verified_name.empty() ||
+ comparator->IsNameVariantOf(address_name, verified_name)) {
+ verified_name = address_name;
+ } else if (!comparator->IsNameVariantOf(verified_name, address_name)) {
+ found_conflicting_names = true;
+ break;
+ }
+ }
+ } else {
+ verified_name = RemoveMiddleInitial(card_name);
+ for (const AutofillProfile& profile : candidate_profiles) {
+ const base::string16 address_name = RemoveMiddleInitial(
+ profile.GetInfo(AutofillType(NAME_FULL), app_locale_));
+ if (address_name.empty())
+ continue;
+ if (verified_name.empty()) {
+ verified_name = address_name;
+ } else if (!base::EqualsCaseInsensitiveASCII(verified_name,
+ address_name)) {
+ found_conflicting_names = true;
+ break;
}
}
}
+ if (found_conflicting_names) {
+ if (!upload_decision_metrics)
+ *rappor_metric_name = "Autofill.CardUploadNotOfferedConflictingNames";
+ upload_decision_metrics |=
+ AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES;
+ }
}
+
// If neither the card nor any of the addresses have a name associated with
// them, the candidate set is invalid.
if (verified_name.empty()) {
- *address_upload_decision_metric =
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME;
- *rappor_metric_name = "Autofill.CardUploadNotOfferedNoName";
- return false;
+ if (!upload_decision_metrics)
+ *rappor_metric_name = "Autofill.CardUploadNotOfferedNoName";
+ upload_decision_metrics |= AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME;
}
// If any of the candidate addresses have a non-empty zip that doesn't match
// any other non-empty zip, then the candidate set is invalid.
base::string16 verified_zip;
+ base::string16 normalized_verified_zip;
+ const AutofillType kZipCode(ADDRESS_HOME_ZIP);
for (const AutofillProfile& profile : candidate_profiles) {
- // TODO(jdonnelly): Use GetInfo instead of GetRawInfo once zip codes are
- // canonicalized. See http://crbug.com/587465.
- base::string16 zip = profile.GetRawInfo(ADDRESS_HOME_ZIP);
+ const base::string16 zip = comparator
+ ? profile.GetInfo(kZipCode, app_locale_)
+ : profile.GetRawInfo(ADDRESS_HOME_ZIP);
+ const base::string16 normalized_zip =
+ comparator ? comparator->NormalizeForComparison(
+ zip, AutofillProfileComparator::DISCARD_WHITESPACE)
+ : base::string16();
if (!zip.empty()) {
if (verified_zip.empty()) {
verified_zip = zip;
+ normalized_verified_zip = normalized_zip;
+ } else if (comparator) {
+ if (normalized_zip.find(normalized_verified_zip) ==
+ base::string16::npos &&
+ normalized_verified_zip.find(normalized_zip) ==
+ base::string16::npos) {
+ upload_decision_metrics |=
+ AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS;
+ break;
+ }
} else {
// To compare two zips, we check to see if either is a prefix of the
// other. This allows us to consider a 5-digit zip and a zip+4 to be a
@@ -1376,9 +1486,9 @@ bool AutofillManager::GetProfilesForCreditCardUpload(
// likely to fail.
if (!(StartsWith(verified_zip, zip, base::CompareCase::SENSITIVE) ||
StartsWith(zip, verified_zip, base::CompareCase::SENSITIVE))) {
- *address_upload_decision_metric =
+ upload_decision_metrics |=
AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS;
- return false;
+ break;
}
}
}
@@ -1386,19 +1496,24 @@ bool AutofillManager::GetProfilesForCreditCardUpload(
// If none of the candidate addresses have a zip, the candidate set is
// invalid.
- if (verified_zip.empty()) {
- *address_upload_decision_metric =
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE;
- return false;
- }
+ if (verified_zip.empty() && !candidate_profiles.empty())
+ upload_decision_metrics |= AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE;
- profiles->assign(candidate_profiles.begin(), candidate_profiles.end());
- return true;
+ if (!upload_decision_metrics) {
+ upload_request->profiles.assign(candidate_profiles.begin(),
+ candidate_profiles.end());
+ if (!has_modified_profile)
+ for (const AutofillProfile& profile : candidate_profiles)
+ UMA_HISTOGRAM_COUNTS_1000(
+ "Autofill.DaysSincePreviousUseAtSubmission.Profile",
+ (profile.use_date() - profile.previous_use_date()).InDays());
+ }
+ return upload_decision_metrics;
}
-void AutofillManager::CollectRapportSample(const GURL& source_url,
- const std::string& metric_name)
- const {
+void AutofillManager::CollectRapporSample(
+ const GURL& source_url,
+ const std::string& metric_name) const {
if (source_url.is_valid() && client_->GetRapporServiceImpl()) {
rappor::SampleDomainAndRegistryFromGURL(client_->GetRapporServiceImpl(),
metric_name, source_url);
@@ -1440,6 +1555,8 @@ void AutofillManager::UploadFormData(const FormStructure& submitted_form,
ServerFieldTypeSet non_empty_types;
personal_data_->GetNonEmptyTypes(&non_empty_types);
+ if (submitted_form.is_signin_upload())
+ non_empty_types.insert(PASSWORD);
download_manager_->StartUploadRequest(
submitted_form, was_autofilled, non_empty_types,
@@ -1453,7 +1570,8 @@ void AutofillManager::Reset() {
DCHECK(!pending_form_data_);
form_structures_.clear();
form_interactions_ukm_logger_.reset(
- new AutofillMetrics::FormInteractionsUkmLogger(client_->GetUkmService()));
+ new AutofillMetrics::FormInteractionsUkmLogger(
+ client_->GetUkmRecorder()));
address_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
false /* is_for_credit_card */, form_interactions_ukm_logger_.get()));
credit_card_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
@@ -1490,7 +1608,7 @@ AutofillManager::AutofillManager(AutofillDriver* driver,
base::MakeUnique<AutocompleteHistoryManager>(driver, client)),
form_interactions_ukm_logger_(
base::MakeUnique<AutofillMetrics::FormInteractionsUkmLogger>(
- client->GetUkmService())),
+ client->GetUkmRecorder())),
address_form_event_logger_(
base::MakeUnique<AutofillMetrics::FormEventLogger>(
false /* is_for_credit_card */,
@@ -1899,6 +2017,9 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
if (forms.empty())
return;
+ // Setup the url for metrics that we will collect for this form.
+ form_interactions_ukm_logger_->OnFormsParsed(forms[0].origin);
+
std::vector<FormStructure*> non_queryable_forms;
std::vector<FormStructure*> queryable_forms;
for (const FormData& form : forms) {
@@ -1927,8 +2048,6 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
if (!queryable_forms.empty() || !non_queryable_forms.empty()) {
AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED);
- // Setup the url for metrics that we will collect for this form.
- form_interactions_ukm_logger_->OnFormsLoaded(forms[0].origin);
#if defined(OS_IOS)
// Log this from same location as AutofillMetrics::FORMS_LOADED to ensure
@@ -1975,7 +2094,7 @@ bool AutofillManager::ParseForm(const FormData& form,
// as long as receivers don't take ownership.
form_structures_.push_back(std::move(form_structure));
*parsed_form_structure = form_structures_.back().get();
- (*parsed_form_structure)->DetermineHeuristicTypes(client_->GetUkmService());
+ (*parsed_form_structure)->DetermineHeuristicTypes(client_->GetUkmRecorder());
return true;
}
@@ -2248,10 +2367,11 @@ void AutofillManager::DumpAutofillData(bool imported_cc) const {
}
#endif // ENABLE_FORM_DEBUG_DUMP
-void AutofillManager::LogCardUploadDecisionUkm(
- AutofillMetrics::CardUploadDecisionMetric upload_decision) {
- AutofillMetrics::LogCardUploadDecisionUkm(
- client_->GetUkmService(), pending_upload_request_url_, upload_decision);
+void AutofillManager::LogCardUploadDecisions(int upload_decision_metrics) {
+ AutofillMetrics::LogCardUploadDecisionMetrics(upload_decision_metrics);
+ AutofillMetrics::LogCardUploadDecisionsUkm(client_->GetUkmRecorder(),
+ pending_upload_request_url_,
+ upload_decision_metrics);
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_manager.h b/chromium/components/autofill/core/browser/autofill_manager.h
index c8597275741..a0d7514073a 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.h
+++ b/chromium/components/autofill/core/browser/autofill_manager.h
@@ -272,6 +272,11 @@ class AutofillManager : public AutofillDownloadManager::Observer,
return form_interactions_ukm_logger_.get();
}
+ // payments::PaymentsClientDelegate:
+ // Exposed for testing.
+ void OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
+ const std::string& server_id) override;
+
// Exposed for testing.
AutofillExternalDelegate* external_delegate() {
return external_delegate_;
@@ -301,7 +306,6 @@ class AutofillManager : public AutofillDownloadManager::Observer,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
std::unique_ptr<base::DictionaryValue> legal_message) override;
- void OnDidUploadCard(AutofillClient::PaymentsRpcResult result) override;
// payments::FullCardRequest::ResultDelegate:
void OnFullCardRequestSucceeded(const CreditCard& card,
@@ -423,20 +427,26 @@ class AutofillManager : public AutofillDownloadManager::Observer,
void ImportFormData(const FormStructure& submitted_form);
// Logs |metric_name| with RAPPOR, for the specific form |source_url|.
- void CollectRapportSample(const GURL& source_url,
- const std::string& metric_name) const;
+ void CollectRapporSample(const GURL& source_url,
+ const std::string& metric_name) const;
// Examines |card| and the stored profiles and if a candidate set of profiles
// is found that matches the client-side validation rules, assigns the values
- // to |profiles|. If no valid set can be found, returns false, assigns the
- // failure reason to |address_upload_decision_metric|, and if applicable, the
- // RAPPOR metric to log to |rappor_metric_name|.
- bool GetProfilesForCreditCardUpload(const CreditCard& card,
- std::vector<AutofillProfile>* profiles,
- autofill::AutofillMetrics::
- CardUploadDecisionMetric*
- address_upload_decision_metric,
- std::string* rappor_metric_name) const;
+ // to |upload_request.profiles| and returns 0. If no valid set can be found,
+ // returns the failure reasons and, if applicable, the RAPPOR metric to log to
+ // |rappor_metric_name|. Appends any experiments that were triggered to
+ // |upload_request.active_experiments|. The return value is a bitmask of
+ // |AutofillMetrics::CardUploadDecisionMetric|.
+ int SetProfilesForCreditCardUpload(
+ const CreditCard& card,
+ payments::PaymentsClient::UploadRequestDetails* upload_request,
+ std::string* rappor_metric_name) const;
+
+ // Returns metric relevant to the CVC field based on values in
+ // |found_cvc_field_|, |found_value_in_cvc_field_| and
+ // |found_cvc_value_in_non_cvc_field_|.
+ AutofillMetrics::CardUploadDecisionMetric GetCVCCardUploadDecisionMetric()
+ const;
// If |initial_interaction_timestamp_| is unset or is set to a later time than
// |interaction_timestamp|, updates the cached timestamp. The latter check is
@@ -482,9 +492,10 @@ class AutofillManager : public AutofillDownloadManager::Observer,
void DumpAutofillData(bool imported_cc) const;
#endif
- // Logs the card upload decision UKM.
- void LogCardUploadDecisionUkm(
- AutofillMetrics::CardUploadDecisionMetric upload_decision);
+ // Logs the card upload decisions in UKM and UMA.
+ // |upload_decision_metrics| is a bitmask of
+ // |AutofillMetrics::CardUploadDecisionMetric|.
+ void LogCardUploadDecisions(int upload_decision_metrics);
// Provides driver-level context to the shared code of the component. Must
// outlive this object.
@@ -560,8 +571,22 @@ class AutofillManager : public AutofillDownloadManager::Observer,
// Collected information about a pending upload request.
payments::PaymentsClient::UploadRequestDetails upload_request_;
bool user_did_accept_upload_prompt_;
- GURL pending_upload_request_url_;
+
+ // |should_cvc_be_requested_| is |true| if we should request CVC from the user
+ // in the card upload dialog.
bool should_cvc_be_requested_;
+ // |found_cvc_field_| is |true| if there exists a field that is determined to
+ // be a CVC field via heuristics.
+ bool found_cvc_field_;
+ // |found_value_in_cvc_field_| is |true| if a field that is determined to
+ // be a CVC field via heuristics has non-empty |value|.
+ // |value| may or may not be a valid CVC.
+ bool found_value_in_cvc_field_;
+ // |found_cvc_value_in_non_cvc_field_| is |true| if a field that is not
+ // determined to be a CVC field via heuristics has a valid CVC |value|.
+ bool found_cvc_value_in_non_cvc_field_;
+
+ GURL pending_upload_request_url_;
#ifdef ENABLE_FORM_DEBUG_DUMP
// The last few autofilled forms (key/value pairs) submitted, for debugging.
diff --git a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
index e9d94a48d40..26121eaa252 100644
--- a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -41,10 +41,12 @@
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/popup_item_ids.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_external_delegate.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_pref_names.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -55,11 +57,12 @@
#include "components/rappor/test_rappor_service.h"
#include "components/security_state/core/security_state.h"
#include "components/strings/grit/components_strings.h"
-#include "components/ukm/test_ukm_service.h"
-#include "components/ukm/ukm_entry.h"
+#include "components/ukm/test_ukm_recorder.h"
#include "components/ukm/ukm_source.h"
#include "components/variations/variations_associated_data.h"
+#include "components/variations/variations_params_manager.h"
#include "net/base/url_util.h"
+#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -73,20 +76,23 @@ using testing::_;
using testing::AtLeast;
using testing::Return;
using testing::SaveArg;
+using testing::UnorderedElementsAre;
namespace autofill {
-
namespace {
const int kDefaultPageID = 137;
-const std::string kUTF8MidlineEllipsis =
+const char kUTF8MidlineEllipsis[] =
" "
"\xE2\x80\xA2\xE2\x80\x86"
"\xE2\x80\xA2\xE2\x80\x86"
"\xE2\x80\xA2\xE2\x80\x86"
"\xE2\x80\xA2\xE2\x80\x86";
+const base::Time kArbitraryTime = base::Time::FromDoubleT(25);
+const base::Time kMuchLaterTime = base::Time::FromDoubleT(5000);
+
class MockAutofillClient : public TestAutofillClient {
public:
MockAutofillClient() {}
@@ -111,7 +117,9 @@ class TestPaymentsClient : public payments::PaymentsClient {
~TestPaymentsClient() override {}
void GetUploadDetails(const std::vector<AutofillProfile>& addresses,
+ const std::vector<const char*>& active_experiments,
const std::string& app_locale) override {
+ active_experiments_ = active_experiments;
delegate_->OnDidGetUploadDetails(
app_locale == "en-US" ? AutofillClient::SUCCESS
: AutofillClient::PERMANENT_FAILURE,
@@ -121,9 +129,13 @@ class TestPaymentsClient : public payments::PaymentsClient {
void UploadCard(const payments::PaymentsClient::UploadRequestDetails&
request_details) override {
- delegate_->OnDidUploadCard(AutofillClient::SUCCESS);
+ active_experiments_ = request_details.active_experiments;
+ delegate_->OnDidUploadCard(AutofillClient::SUCCESS, server_id_);
}
+ std::string server_id_;
+ std::vector<const char*> active_experiments_;
+
private:
payments::PaymentsClientDelegate* const delegate_;
@@ -169,17 +181,21 @@ class TestPersonalDataManager : public PersonalDataManager {
}
void AddProfile(std::unique_ptr<AutofillProfile> profile) {
- profile->set_modification_date(base::Time::Now());
+ profile->set_modification_date(AutofillClock::Now());
web_profiles_.push_back(std::move(profile));
}
void AddCreditCard(const CreditCard& credit_card) override {
std::unique_ptr<CreditCard> local_credit_card =
base::MakeUnique<CreditCard>(credit_card);
- local_credit_card->set_modification_date(base::Time::Now());
+ local_credit_card->set_modification_date(AutofillClock::Now());
local_credit_cards_.push_back(std::move(local_credit_card));
}
+ void AddFullServerCreditCard(const CreditCard& credit_card) override {
+ AddServerCreditCard(credit_card);
+ }
+
void RecordUseOf(const AutofillDataModel& data_model) override {
CreditCard* credit_card = GetCreditCardWithGUID(data_model.guid().c_str());
if (credit_card)
@@ -210,12 +226,18 @@ class TestPersonalDataManager : public PersonalDataManager {
}
}
- void ClearAutofillProfiles() {
- web_profiles_.clear();
- }
+ void ClearAutofillProfiles() { web_profiles_.clear(); }
void ClearCreditCards() {
local_credit_cards_.clear();
+ server_credit_cards_.clear();
+ }
+
+ void AddServerCreditCard(const CreditCard& credit_card) {
+ std::unique_ptr<CreditCard> server_credit_card =
+ base::MakeUnique<CreditCard>(credit_card);
+ server_credit_card->set_modification_date(AutofillClock::Now());
+ server_credit_cards_.push_back(std::move(server_credit_card));
}
// Create Elvis card with whitespace in the credit card number.
@@ -224,7 +246,7 @@ class TestPersonalDataManager : public PersonalDataManager {
std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>();
test::SetCreditCardInfo(credit_card.get(), "Elvis Presley",
"4234 5678 9012 3456", // Visa
- "04", "2999");
+ "04", "2999", "1");
credit_card->set_guid("00000000-0000-0000-0000-000000000008");
local_credit_cards_.push_back(std::move(credit_card));
}
@@ -235,7 +257,7 @@ class TestPersonalDataManager : public PersonalDataManager {
std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>();
test::SetCreditCardInfo(credit_card.get(), "Elvis Presley",
"4234-5678-9012-3456", // Visa
- "04", "2999");
+ "04", "2999", "1");
credit_card->set_guid("00000000-0000-0000-0000-000000000009");
local_credit_cards_.push_back(std::move(credit_card));
}
@@ -245,7 +267,7 @@ class TestPersonalDataManager : public PersonalDataManager {
std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>();
test::SetCreditCardInfo(credit_card.get(), "Miku Hatsune",
"4234567890654321", // Visa
- month, year);
+ month, year, "1");
credit_card->set_guid("00000000-0000-0000-0000-000000000007");
local_credit_cards_.push_back(std::move(credit_card));
}
@@ -255,7 +277,7 @@ class TestPersonalDataManager : public PersonalDataManager {
std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>();
test::SetCreditCardInfo(credit_card.get(), "Homer Simpson",
"4234567890654321", // Visa
- "05", "2000");
+ "05", "2000", "1");
credit_card->set_guid("00000000-0000-0000-0000-000000000009");
local_credit_cards_.push_back(std::move(credit_card));
}
@@ -289,23 +311,25 @@ class TestPersonalDataManager : public PersonalDataManager {
std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>();
test::SetCreditCardInfo(credit_card.get(), "Elvis Presley",
"4234567890123456", // Visa
- "04", "2999");
+ "04", "2999", "1");
credit_card->set_guid("00000000-0000-0000-0000-000000000004");
credit_card->set_use_count(10);
- credit_card->set_use_date(base::Time::Now() - base::TimeDelta::FromDays(5));
+ credit_card->set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(5));
credit_cards->push_back(std::move(credit_card));
credit_card = base::MakeUnique<CreditCard>();
test::SetCreditCardInfo(credit_card.get(), "Buddy Holly",
"5187654321098765", // Mastercard
- "10", "2998");
+ "10", "2998", "1");
credit_card->set_guid("00000000-0000-0000-0000-000000000005");
credit_card->set_use_count(5);
- credit_card->set_use_date(base::Time::Now() - base::TimeDelta::FromDays(4));
+ credit_card->set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(4));
credit_cards->push_back(std::move(credit_card));
credit_card = base::MakeUnique<CreditCard>();
- test::SetCreditCardInfo(credit_card.get(), "", "", "", "");
+ test::SetCreditCardInfo(credit_card.get(), "", "", "", "", "");
credit_card->set_guid("00000000-0000-0000-0000-000000000006");
credit_cards->push_back(std::move(credit_card));
}
@@ -334,6 +358,13 @@ class TestAutofillDownloadManager : public AutofillDownloadManager {
}
}
+ MOCK_METHOD5(StartUploadRequest,
+ bool(const FormStructure&,
+ bool,
+ const ServerFieldTypeSet&,
+ const std::string&,
+ bool));
+
private:
std::vector<FormStructure*> last_queried_forms_;
@@ -409,22 +440,19 @@ void ExpectFilledForm(int page_id,
filled_form.fields[3]);
ExpectFilledField("Address Line 2", "addr2", address2, "text",
filled_form.fields[4]);
- ExpectFilledField("City", "city", city, "text",
- filled_form.fields[5]);
- ExpectFilledField("State", "state", state, "text",
- filled_form.fields[6]);
+ ExpectFilledField("City", "city", city, "text", filled_form.fields[5]);
+ ExpectFilledField("State", "state", state, "text", filled_form.fields[6]);
ExpectFilledField("Postal Code", "zipcode", postal_code, "text",
filled_form.fields[7]);
ExpectFilledField("Country", "country", country, "text",
filled_form.fields[8]);
ExpectFilledField("Phone Number", "phonenumber", phone, "tel",
filled_form.fields[9]);
- ExpectFilledField("Email", "email", email, "email",
- filled_form.fields[10]);
+ ExpectFilledField("Email", "email", email, "email", filled_form.fields[10]);
}
if (has_credit_card_fields) {
- size_t offset = has_address_fields? kAddressFormSize : 0;
+ size_t offset = has_address_fields ? kAddressFormSize : 0;
ExpectFilledField("Name on Card", "nameoncard", name_on_card, "text",
filled_form.fields[offset + 0]);
ExpectFilledField("Card Number", "cardnumber", card_number, "text",
@@ -483,11 +511,11 @@ class MockAutocompleteHistoryManager : public AutocompleteHistoryManager {
MockAutocompleteHistoryManager(AutofillDriver* driver, AutofillClient* client)
: AutocompleteHistoryManager(driver, client) {}
- MOCK_METHOD4(OnGetAutocompleteSuggestions, void(
- int query_id,
- const base::string16& name,
- const base::string16& prefix,
- const std::string& form_control_type));
+ MOCK_METHOD4(OnGetAutocompleteSuggestions,
+ void(int query_id,
+ const base::string16& name,
+ const base::string16& prefix,
+ const std::string& form_control_type));
MOCK_METHOD1(OnWillSubmitForm, void(const FormData& form));
private:
@@ -500,23 +528,22 @@ class MockAutofillDriver : public TestAutofillDriver {
: is_incognito_(false), did_interact_with_credit_card_form_(false) {}
// Mock methods to enable testability.
- MOCK_METHOD3(SendFormDataToRenderer, void(int query_id,
- RendererFormDataAction action,
- const FormData& data));
+ MOCK_METHOD3(SendFormDataToRenderer,
+ void(int query_id,
+ RendererFormDataAction action,
+ const FormData& data));
- void SetIsIncognito(bool is_incognito) {
- is_incognito_ = is_incognito;
- }
+ void SetIsIncognito(bool is_incognito) { is_incognito_ = is_incognito; }
bool IsIncognito() const override { return is_incognito_; }
void DidInteractWithCreditCardForm() override {
did_interact_with_credit_card_form_ = true;
- };
+ }
void ClearDidInteractWithCreditCardForm() {
did_interact_with_credit_card_form_ = false;
- };
+ }
bool did_interact_with_credit_card_form() const {
return did_interact_with_credit_card_form_;
@@ -535,12 +562,14 @@ class TestAutofillManager : public AutofillManager {
TestPersonalDataManager* personal_data)
: AutofillManager(driver, client, personal_data),
personal_data_(personal_data),
+ context_getter_(driver->GetURLRequestContext()),
+ test_payments_client_(new TestPaymentsClient(context_getter_, this)),
autofill_enabled_(true),
credit_card_upload_enabled_(false),
credit_card_was_uploaded_(false),
- expected_observed_submission_(true) {
- set_payments_client(
- new TestPaymentsClient(driver->GetURLRequestContext(), this));
+ expected_observed_submission_(true),
+ call_parent_upload_form_data_(false) {
+ set_payments_client(test_payments_client_);
}
~TestAutofillManager() override {}
@@ -569,6 +598,10 @@ class TestAutofillManager : public AutofillManager {
expected_observed_submission_ = expected;
}
+ void set_call_parent_upload_form_data(bool value) {
+ call_parent_upload_form_data_ = value;
+ }
+
void UploadFormDataAsyncCallback(const FormStructure* submitted_form,
const base::TimeTicks& load_time,
const base::TimeTicks& interaction_time,
@@ -583,10 +616,9 @@ class TestAutofillManager : public AutofillManager {
ASSERT_EQ(expected_submitted_field_types_.size(),
submitted_form->field_count());
for (size_t i = 0; i < expected_submitted_field_types_.size(); ++i) {
- SCOPED_TRACE(
- base::StringPrintf(
- "Field %d with value %s", static_cast<int>(i),
- base::UTF16ToUTF8(submitted_form->field(i)->value).c_str()));
+ SCOPED_TRACE(base::StringPrintf(
+ "Field %d with value %s", static_cast<int>(i),
+ base::UTF16ToUTF8(submitted_form->field(i)->value).c_str()));
const ServerFieldTypeSet& possible_types =
submitted_form->field(i)->possible_types();
EXPECT_EQ(expected_submitted_field_types_[i].size(),
@@ -615,6 +647,9 @@ class TestAutofillManager : public AutofillManager {
void UploadFormData(const FormStructure& submitted_form,
bool observed_submission) override {
submitted_form_signature_ = submitted_form.FormSignatureAsStr();
+
+ if (call_parent_upload_form_data_)
+ AutofillManager::UploadFormData(submitted_form, observed_submission);
}
const std::string GetSubmittedFormSignature() {
@@ -629,6 +664,14 @@ class TestAutofillManager : public AutofillManager {
return personal_data_->GetCreditCardWithGUID(guid);
}
+ std::vector<CreditCard*> GetLocalCreditCards() const {
+ return personal_data_->GetLocalCreditCards();
+ }
+
+ const std::vector<CreditCard*>& GetCreditCards() const {
+ return personal_data_->GetCreditCards();
+ }
+
void AddProfile(std::unique_ptr<AutofillProfile> profile) {
personal_data_->AddProfile(std::move(profile));
}
@@ -637,6 +680,10 @@ class TestAutofillManager : public AutofillManager {
personal_data_->AddCreditCard(credit_card);
}
+ const std::vector<const char*>& GetActiveExperiments() const {
+ return test_payments_client_->active_experiments_;
+ }
+
int GetPackedCreditCardID(int credit_card_id) {
std::string credit_card_guid =
base::StringPrintf("00000000-0000-0000-0000-%012d", credit_card_id);
@@ -648,22 +695,30 @@ class TestAutofillManager : public AutofillManager {
form_structures()->push_back(std::move(form));
}
- void ClearFormStructures() {
- form_structures()->clear();
+ void ClearFormStructures() { form_structures()->clear(); }
+
+ void ResetPaymentsClientForCardUpload(const char* server_id) {
+ TestPaymentsClient* payments_client =
+ new TestPaymentsClient(context_getter_, this);
+ payments_client->server_id_ = server_id;
+ set_payments_client(payments_client);
}
private:
- void OnDidUploadCard(AutofillClient::PaymentsRpcResult result) override {
+ void OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
+ const std::string& server_id) override {
credit_card_was_uploaded_ = true;
+ AutofillManager::OnDidUploadCard(result, server_id);
};
- // Weak reference.
- TestPersonalDataManager* personal_data_;
-
+ TestPersonalDataManager* personal_data_; // Weak reference.
+ net::URLRequestContextGetter* context_getter_; // Weak reference.
+ TestPaymentsClient* test_payments_client_; // Weak reference.
bool autofill_enabled_;
bool credit_card_upload_enabled_;
bool credit_card_was_uploaded_;
bool expected_observed_submission_;
+ bool call_parent_upload_form_data_;
std::unique_ptr<base::RunLoop> run_loop_;
@@ -719,8 +774,7 @@ class TestAutofillExternalDelegate : public AutofillExternalDelegate {
// Wrappers around the above GetSuggestions call that take a hardcoded number
// of expected results so callsites are cleaner.
- void CheckSuggestions(int expected_page_id,
- const Suggestion& suggestion0) {
+ void CheckSuggestions(int expected_page_id, const Suggestion& suggestion0) {
std::vector<Suggestion> suggestion_vector;
suggestion_vector.push_back(suggestion0);
CheckSuggestions(expected_page_id, 1, &suggestion_vector[0]);
@@ -759,9 +813,7 @@ class TestAutofillExternalDelegate : public AutofillExternalDelegate {
ASSERT_EQ(expected_num_suggestions, suggestions_.size());
}
- bool on_query_seen() const {
- return on_query_seen_;
- }
+ bool on_query_seen() const { return on_query_seen_; }
bool on_suggestions_returned_seen() const {
return on_suggestions_returned_seen_;
@@ -784,19 +836,9 @@ class TestAutofillExternalDelegate : public AutofillExternalDelegate {
DISALLOW_COPY_AND_ASSIGN(TestAutofillExternalDelegate);
};
-// Finds the specified UKM metric by |name| in the specified UKM |metrics|.
-const ukm::Entry_Metric* FindMetric(
- const char* name,
- const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) {
- for (const auto& metric : metrics) {
- if (metric.metric_hash() == base::HashMetricName(name))
- return &metric;
- }
- return nullptr;
-}
-
// Get Ukm sources from the Ukm service.
-std::vector<const ukm::UkmSource*> GetUkmSources(ukm::TestUkmService* service) {
+std::vector<const ukm::UkmSource*> GetUkmSources(
+ ukm::TestUkmRecorder* service) {
std::vector<const ukm::UkmSource*> sources;
for (const auto& kv : service->GetSources())
sources.push_back(kv.second.get());
@@ -808,7 +850,7 @@ std::vector<const ukm::UkmSource*> GetUkmSources(ukm::TestUkmService* service) {
class AutofillManagerTest : public testing::Test {
public:
- AutofillManagerTest() : field_trial_list_(nullptr) {}
+ AutofillManagerTest() {}
void SetUp() override {
autofill_client_.SetPrefs(test::PrefServiceForTesting());
@@ -825,12 +867,10 @@ class AutofillManagerTest : public testing::Test {
// AutofillManager takes ownership of |download_manager_|.
autofill_manager_->set_download_manager(download_manager_);
external_delegate_.reset(new TestAutofillExternalDelegate(
- autofill_manager_.get(),
- autofill_driver_.get()));
+ autofill_manager_.get(), autofill_driver_.get()));
autofill_manager_->SetExternalDelegate(external_delegate_.get());
- // Clear all the things.
- variations::testing::ClearAllVariationParams();
+ variation_params_.ClearAllVariationParams();
}
void TearDown() override {
@@ -843,6 +883,7 @@ class AutofillManagerTest : public testing::Test {
// need to care about removing self as an observer in destruction.
personal_data_.set_database(scoped_refptr<AutofillWebDataService>(NULL));
personal_data_.SetPrefService(NULL);
+ personal_data_.ClearCreditCards();
request_context_ = nullptr;
}
@@ -870,7 +911,9 @@ class AutofillManagerTest : public testing::Test {
void FormSubmitted(const FormData& form) {
autofill_manager_->ResetRunLoop();
- if (autofill_manager_->OnWillSubmitForm(form, base::TimeTicks::Now()))
+ if (autofill_manager_->OnWillSubmitForm(form, base::TimeTicks::Now()) &&
+ (!personal_data_.GetProfiles().empty() ||
+ !personal_data_.GetCreditCards().empty()))
autofill_manager_->WaitForAsyncUploadProcess();
autofill_manager_->OnFormSubmitted(form);
}
@@ -879,9 +922,8 @@ class AutofillManagerTest : public testing::Test {
const FormData& form,
const FormFieldData& field,
int unique_id) {
- autofill_manager_->FillOrPreviewForm(
- AutofillDriver::FORM_DATA_ACTION_FILL, query_id, form, field,
- unique_id);
+ autofill_manager_->FillOrPreviewForm(AutofillDriver::FORM_DATA_ACTION_FILL,
+ query_id, form, field, unique_id);
}
// Calls |autofill_manager_->OnFillAutofillFormData()| with the specified
@@ -895,9 +937,9 @@ class AutofillManagerTest : public testing::Test {
int unique_id,
int* response_query_id,
FormData* response_data) {
- EXPECT_CALL(*autofill_driver_, SendFormDataToRenderer(_, _, _)).
- WillOnce((DoAll(testing::SaveArg<0>(response_query_id),
- testing::SaveArg<2>(response_data))));
+ EXPECT_CALL(*autofill_driver_, SendFormDataToRenderer(_, _, _))
+ .WillOnce((DoAll(testing::SaveArg<0>(response_query_id),
+ testing::SaveArg<2>(response_data))));
FillAutofillFormData(input_query_id, input_form, input_field, unique_id);
}
@@ -932,8 +974,8 @@ class AutofillManagerTest : public testing::Test {
test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
form->fields.push_back(field);
if (use_month_type) {
- test::CreateTestFormField(
- "Expiration Date", "ccmonth", "", "month", &field);
+ test::CreateTestFormField("Expiration Date", "ccmonth", "", "month",
+ &field);
form->fields.push_back(field);
} else {
test::CreateTestFormField("Expiration Date", "ccmonth", "", "text",
@@ -996,8 +1038,8 @@ class AutofillManagerTest : public testing::Test {
FormsSeen(std::vector<FormData>(1, *form));
*card = CreditCard(CreditCard::MASKED_SERVER_CARD, "a123");
test::SetCreditCardInfo(card, "John Dillinger", "1881" /* Visa */, "01",
- "2017");
- card->SetTypeForMaskedCard(kVisaCard);
+ "2017", "1");
+ card->SetNetworkForMaskedCard(kVisaCard);
EXPECT_CALL(*autofill_driver_, SendFormDataToRenderer(_, _, _))
.Times(AtLeast(1));
@@ -1009,9 +1051,9 @@ class AutofillManagerTest : public testing::Test {
// Convenience method for using and retrieving a mock autocomplete history
// manager.
MockAutocompleteHistoryManager* RecreateMockAutocompleteHistoryManager() {
- MockAutocompleteHistoryManager* manager = new
- MockAutocompleteHistoryManager(autofill_driver_.get(),
- autofill_manager_->client());
+ MockAutocompleteHistoryManager* manager =
+ new MockAutocompleteHistoryManager(autofill_driver_.get(),
+ autofill_manager_->client());
autofill_manager_->autocomplete_history_manager_.reset(manager);
return manager;
}
@@ -1028,84 +1070,91 @@ class AutofillManagerTest : public testing::Test {
security_state::kHttpFormWarningFeature);
}
- void EnableUkmLogging() {
- scoped_feature_list_.InitAndEnableFeature(kAutofillUkmLogging);
+ void EnableAutofillOfferLocalSaveIfServerCardManuallyEnteredExperiment() {
+ scoped_feature_list_.InitAndEnableFeature(
+ kAutofillOfferLocalSaveIfServerCardManuallyEntered);
+ }
+
+ void EnableAutofillUpstreamRequestCvcIfMissingExperiment() {
+ scoped_feature_list_.InitAndEnableFeature(
+ kAutofillUpstreamRequestCvcIfMissing);
}
- void EnableAutofillUpstreamRequestCvcIfMissingExperimentAndUkmLogging() {
- scoped_feature_list_.InitWithFeatures(
- {kAutofillUpstreamRequestCvcIfMissing, kAutofillUkmLogging}, {});
+ void DisableAutofillUpstreamUseAutofillProfileComparator() {
+ scoped_feature_list_.InitAndDisableFeature(
+ kAutofillUpstreamUseAutofillProfileComparator);
}
void ExpectUniqueFillableFormParsedUkm() {
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
// Check that one source is logged.
- ASSERT_EQ(1U, ukm_service->sources_count());
- const ukm::UkmSource* source = GetUkmSources(ukm_service)[0];
+ ASSERT_EQ(1U, test_ukm_recorder_.sources_count());
+ const ukm::UkmSource* source = GetUkmSources(&test_ukm_recorder_)[0];
// Check that one entry is logged.
- EXPECT_EQ(1U, ukm_service->entries_count());
- const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
- EXPECT_EQ(source->id(), entry->source_id());
+ EXPECT_EQ(1U, test_ukm_recorder_.entries_count());
+ const ukm::mojom::UkmEntry* entry = test_ukm_recorder_.GetEntry(0);
+ EXPECT_EQ(source->id(), entry->source_id);
- ukm::Entry entry_proto;
- entry->PopulateProto(&entry_proto);
- EXPECT_EQ(source->id(), entry_proto.source_id());
+ EXPECT_EQ(source->id(), entry->source_id);
// Check if there is an entry for developer engagement decision.
EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
- entry_proto.event_hash());
- EXPECT_EQ(1, entry_proto.metrics_size());
+ entry->event_hash);
+ EXPECT_EQ(1U, entry->metrics.size());
// Check that the expected developer engagement metric is logged.
- const ukm::Entry_Metric* metric = FindMetric(
- internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics());
+ const ukm::mojom::UkmMetric* metric = ukm::TestUkmRecorder::FindMetric(
+ entry, internal::kUKMDeveloperEngagementMetricName);
ASSERT_NE(nullptr, metric);
- EXPECT_EQ(static_cast<int>(
- AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS),
- metric->value());
+ EXPECT_EQ(1 << AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS,
+ metric->value);
+ }
+
+ void ExpectUniqueCardUploadDecision(
+ const base::HistogramTester& histogram_tester,
+ AutofillMetrics::CardUploadDecisionMetric metric) {
+ histogram_tester.ExpectUniqueSample("Autofill.CardUploadDecisionMetric",
+ ToHistogramSample(metric), 1);
+ }
+
+ void ExpectCardUploadDecision(
+ const base::HistogramTester& histogram_tester,
+ AutofillMetrics::CardUploadDecisionMetric metric) {
+ histogram_tester.ExpectBucketCount("Autofill.CardUploadDecisionMetric",
+ ToHistogramSample(metric), 1);
}
void ExpectCardUploadDecisionUkm(
AutofillMetrics::CardUploadDecisionMetric upload_decision) {
+ int expected_metric_value = upload_decision;
ExpectMetric(internal::kUKMCardUploadDecisionMetricName,
internal::kUKMCardUploadDecisionEntryName,
- static_cast<int>(upload_decision),
- 1 /* expected_num_matching_entries */);
+ expected_metric_value, 1 /* expected_num_matching_entries */);
}
void ExpectFillableFormParsedUkm(int num_fillable_forms_parsed) {
ExpectMetric(internal::kUKMDeveloperEngagementMetricName,
internal::kUKMDeveloperEngagementEntryName,
- static_cast<int>(
- AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS),
+ 1 << AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS,
num_fillable_forms_parsed);
}
void ExpectMetric(const char* metric_name,
const char* entry_name,
- int metric_value,
+ int expected_metric_value,
int expected_num_matching_entries) {
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
int num_matching_entries = 0;
- for (size_t i = 0; i < ukm_service->entries_count(); ++i) {
- const ukm::UkmEntry* entry = ukm_service->GetEntry(i);
-
- ukm::Entry entry_proto;
- entry->PopulateProto(&entry_proto);
- EXPECT_EQ(entry->source_id(), entry_proto.source_id());
-
+ for (size_t i = 0; i < test_ukm_recorder_.entries_count(); ++i) {
+ const ukm::mojom::UkmEntry* entry = test_ukm_recorder_.GetEntry(i);
// Check if there is an entry for |entry_name|.
- if (entry_proto.event_hash() == base::HashMetricName(entry_name)) {
- EXPECT_EQ(1, entry_proto.metrics_size());
+ if (entry->event_hash == base::HashMetricName(entry_name)) {
+ EXPECT_EQ(1UL, entry->metrics.size());
// Check that the expected |metric_value| is logged.
- const ukm::Entry_Metric* metric =
- FindMetric(metric_name, entry_proto.metrics());
+ const ukm::mojom::UkmMetric* metric =
+ ukm::TestUkmRecorder::FindMetric(entry, metric_name);
ASSERT_NE(nullptr, metric);
- EXPECT_EQ(metric_value, metric->value());
+ EXPECT_EQ(expected_metric_value, metric->value);
++num_matching_entries;
}
}
@@ -1114,22 +1163,31 @@ class AutofillManagerTest : public testing::Test {
protected:
base::test::ScopedTaskEnvironment scoped_task_environment_;
+ ukm::TestUkmRecorder test_ukm_recorder_;
MockAutofillClient autofill_client_;
std::unique_ptr<MockAutofillDriver> autofill_driver_;
std::unique_ptr<TestAutofillManager> autofill_manager_;
std::unique_ptr<TestAutofillExternalDelegate> external_delegate_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_;
- TestPaymentsClient* payments_client_;
TestAutofillDownloadManager* download_manager_;
TestPersonalDataManager personal_data_;
- base::FieldTrialList field_trial_list_;
base::test::ScopedFeatureList scoped_feature_list_;
+ variations::testing::VariationParamsManager variation_params_;
+
+ private:
+ int ToHistogramSample(AutofillMetrics::CardUploadDecisionMetric metric) {
+ for (int sample = 0; sample < metric + 1; ++sample)
+ if (metric & (1 << sample))
+ return sample;
+
+ NOTREACHED();
+ return 0;
+ }
};
class TestFormStructure : public FormStructure {
public:
- explicit TestFormStructure(const FormData& form)
- : FormStructure(form) {}
+ explicit TestFormStructure(const FormData& form) : FormStructure(form) {}
~TestFormStructure() override {}
void SetFieldTypes(const std::vector<ServerFieldType>& heuristic_types,
@@ -1162,14 +1220,14 @@ TEST_F(AutofillManagerTest, OnFormsSeen_Empty) {
base::HistogramTester histogram_tester;
FormsSeen(forms);
- histogram_tester.ExpectUniqueSample(
- "Autofill.UserHappiness", 0 /* FORMS_LOADED */, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.UserHappiness",
+ 0 /* FORMS_LOADED */, 1);
// No more forms, metric is not logged.
forms.clear();
FormsSeen(forms);
- histogram_tester.ExpectUniqueSample(
- "Autofill.UserHappiness", 0 /* FORMS_LOADED */, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.UserHappiness",
+ 0 /* FORMS_LOADED */, 1);
}
// Test that calling OnFormsSeen consecutively with a different set of forms
@@ -1392,8 +1450,7 @@ TEST_F(AutofillManagerTest, GetProfileSuggestions_MatchCharacter) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID,
- Suggestion("Elvis", "3734 Elvis Presley Blvd.", "", 1));
+ kDefaultPageID, Suggestion("Elvis", "3734 Elvis Presley Blvd.", "", 1));
}
// Tests that we return address profile suggestions values when the section
@@ -1469,8 +1526,7 @@ TEST_F(AutofillManagerTest, GetProfileSuggestions_AlreadyAutofilledNoLabels) {
// Test that we sent the right values to the external delegate. No labels.
external_delegate_->CheckSuggestions(
- kDefaultPageID,
- Suggestion("Elvis", "" /* no label */, "", 1));
+ kDefaultPageID, Suggestion("Elvis", "" /* no label */, "", 1));
}
// Test that we return no suggestions when the form has no relevant fields.
@@ -1551,11 +1607,12 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_EmptyValue) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)));
}
// Test that we return all credit card profile suggestions when the triggering
@@ -1573,11 +1630,12 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_Whitespace) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)));
}
// Test that we return all credit card profile suggestions when the triggering
@@ -1595,11 +1653,12 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_StopCharsOnly) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)));
}
// Test that we return all credit card profile suggestions when the triggering
@@ -1609,7 +1668,7 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_StopCharsWithInput) {
CreditCard credit_card;
test::SetCreditCardInfo(&credit_card, "John Smith",
"5255667890123123", // Mastercard
- "08", "2017");
+ "08", "2017", "1");
credit_card.set_guid("00000000-0000-0000-0000-000000000007");
autofill_manager_->AddCreditCard(credit_card);
@@ -1626,9 +1685,10 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_StopCharsWithInput) {
// Test that we sent the right value to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("MasterCard" + kUTF8MidlineEllipsis + "3123",
- "08/17", kMasterCard,
- autofill_manager_->GetPackedCreditCardID(7)));
+ kDefaultPageID,
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "3123",
+ "08/17", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(7)));
}
// Test that we return only matching credit card profile suggestions when the
@@ -1646,9 +1706,9 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_MatchCharacter) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)));
}
// Test that we return credit card profile suggestions when the selected form
@@ -1665,9 +1725,9 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_NonCCNumber) {
#if defined(OS_ANDROID)
static const std::string kVisaSuggestion =
- "Visa" + kUTF8MidlineEllipsis + "3456";
+ std::string("Visa") + kUTF8MidlineEllipsis + "3456";
static const std::string kMcSuggestion =
- "MasterCard" + kUTF8MidlineEllipsis + "8765";
+ std::string("Mastercard") + kUTF8MidlineEllipsis + "8765";
#else
static const std::string kVisaSuggestion = "*3456";
static const std::string kMcSuggestion = "*8765";
@@ -1696,10 +1756,9 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_NonSecureContext) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID,
- Suggestion(
- l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
- "", "", -1));
+ kDefaultPageID, Suggestion(l10n_util::GetStringUTF8(
+ IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
+ "", "", -1));
// Clear the test credit cards and try again -- we shouldn't return a warning.
personal_data_.ClearCreditCards();
@@ -1767,18 +1826,18 @@ TEST_F(AutofillManagerTest,
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)));
}
// Test that we will eventually return the credit card signin promo when there
// are no credit card suggestions and the promo is active. See the tests in
// AutofillExternalDelegateTest that test whether the promo is added.
TEST_F(AutofillManagerTest, GetCreditCardSuggestions_OnlySigninPromo) {
- // Make sure there are no credit cards.
personal_data_.ClearCreditCards();
// Set up our form data.
@@ -1852,11 +1911,12 @@ TEST_F(AutofillManagerTest,
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)));
}
// Test that we return credit card suggestions for secure pages that have a
@@ -1876,11 +1936,12 @@ TEST_F(AutofillManagerTest,
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)));
}
// Test that we return all credit card suggestions in the case that two cards
@@ -1891,9 +1952,10 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_RepeatedObfuscatedNumber) {
CreditCard credit_card;
test::SetCreditCardInfo(&credit_card, "Elvis Presley",
"5231567890123456", // Mastercard
- "05", "2999");
+ "05", "2999", "1");
credit_card.set_guid("00000000-0000-0000-0000-000000000007");
- credit_card.set_use_date(base::Time::Now() - base::TimeDelta::FromDays(15));
+ credit_card.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(15));
autofill_manager_->AddCreditCard(credit_card);
// Set up our form data.
@@ -1907,13 +1969,15 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_RepeatedObfuscatedNumber) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "3456", "05/99",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(7)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "3456",
+ "05/99", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(7)));
}
// Test that we return profile and credit card suggestions for combined forms.
@@ -1939,11 +2003,12 @@ TEST_F(AutofillManagerTest, GetAddressAndCreditCardSuggestions) {
// Test that we sent the credit card suggestions to the external delegate.
external_delegate_->CheckSuggestions(
- kPageID2, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)),
- Suggestion("MasterCard" + kUTF8MidlineEllipsis + "8765", "10/98",
- kMasterCard, autofill_manager_->GetPackedCreditCardID(5)));
+ kPageID2,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)),
+ Suggestion(std::string("Mastercard") + kUTF8MidlineEllipsis + "8765",
+ "10/98", kMasterCard,
+ autofill_manager_->GetPackedCreditCardID(5)));
}
// Test that for non-https forms with both address and credit card fields, we
@@ -1972,10 +2037,9 @@ TEST_F(AutofillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
// Test that we sent the right values to the external delegate.
external_delegate_->CheckSuggestions(
- kPageID2,
- Suggestion(
- l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
- "", "", -1));
+ kPageID2, Suggestion(l10n_util::GetStringUTF8(
+ IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
+ "", "", -1));
// Clear the test credit cards and try again -- we shouldn't return a warning.
personal_data_.ClearCreditCards();
@@ -2025,10 +2089,9 @@ TEST_F(AutofillManagerTest, GetFieldSuggestionsForAutocompleteOnly) {
AutocompleteSuggestionsReturned(suggestions);
// Test that we sent the right values to the external delegate.
- external_delegate_->CheckSuggestions(
- kDefaultPageID,
- Suggestion("one", "", "", 0),
- Suggestion("two", "", "", 0));
+ external_delegate_->CheckSuggestions(kDefaultPageID,
+ Suggestion("one", "", "", 0),
+ Suggestion("two", "", "", 0));
}
// Test that we do not return duplicate values drawn from multiple profiles when
@@ -2054,9 +2117,8 @@ TEST_F(AutofillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
GetAutofillSuggestions(form, field);
// Test that we sent the right values to the external delegate.
- external_delegate_->CheckSuggestions(
- kDefaultPageID,
- Suggestion("Elvis", "", "", 1));
+ external_delegate_->CheckSuggestions(kDefaultPageID,
+ Suggestion("Elvis", "", "", 1));
}
TEST_F(AutofillManagerTest, GetProfileSuggestions_FancyPhone) {
@@ -2071,8 +2133,7 @@ TEST_F(AutofillManagerTest, GetProfileSuggestions_FancyPhone) {
profile->set_guid("00000000-0000-0000-0000-000000000103");
profile->SetInfo(AutofillType(NAME_FULL), ASCIIToUTF16("Natty Bumppo"),
"en-US");
- profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
- ASCIIToUTF16("1800PRAIRIE"));
+ profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("1800PRAIRIE"));
autofill_manager_->AddProfile(std::move(profile));
const FormFieldData& field = form.fields[9];
@@ -2107,8 +2168,8 @@ TEST_F(AutofillManagerTest, GetProfileSuggestions_ForPhonePrefixOrSuffix) {
FormFieldData field;
for (const auto& test_field : test_fields) {
- test::CreateTestFormField(
- test_field.label, test_field.name, "", "text", &field);
+ test::CreateTestFormField(test_field.label, test_field.name, "", "text",
+ &field);
field.max_length = test_field.max_length;
field.autocomplete_attribute = std::string();
form.fields.push_back(field);
@@ -2217,8 +2278,8 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_Simple) {
FillAutofillFormDataAndSaveResults(kDefaultPageID, form, *form.fields.begin(),
MakeFrontendID(guid, std::string()),
&response_page_id, &response_data);
- ExpectFilledCreditCardFormElvis(
- response_page_id, response_data, kDefaultPageID, false);
+ ExpectFilledCreditCardFormElvis(response_page_id, response_data,
+ kDefaultPageID, false);
}
// Test that whitespace is stripped from the credit card number.
@@ -2282,10 +2343,9 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_NoYearNoMonth) {
MakeFrontendID(guid, std::string()),
&response_page_id, &response_data);
ExpectFilledCreditCardYearMonthWithYearMonth(response_page_id, response_data,
- kDefaultPageID, false, "", "");
+ kDefaultPageID, false, "", "");
}
-
// Test that we correctly fill a credit card form with month input type.
// 2. year empty, month non-empty
TEST_F(AutofillManagerTest, FillCreditCardForm_NoYearMonth) {
@@ -2305,7 +2365,7 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_NoYearMonth) {
MakeFrontendID(guid, std::string()),
&response_page_id, &response_data);
ExpectFilledCreditCardYearMonthWithYearMonth(response_page_id, response_data,
- kDefaultPageID, false, "", "04");
+ kDefaultPageID, false, "", "04");
}
// Test that we correctly fill a credit card form with month input type.
@@ -2335,7 +2395,6 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_YearNoMonth) {
TEST_F(AutofillManagerTest, FillCreditCardForm_YearMonth) {
// Same as the SetUp(), but generate 4 credit cards with year month
// combination.
- personal_data_.ClearCreditCards();
personal_data_.CreateTestCreditCardsYearAndMonth("2999", "04");
// Set up our form data.
FormData form;
@@ -2420,8 +2479,8 @@ TEST_F(AutofillManagerTest, FillAddressAndCreditCardForm) {
MakeFrontendID(guid2, std::string()),
&response_page_id, &response_data);
SCOPED_TRACE("Credit card");
- ExpectFilledCreditCardFormElvis(
- response_page_id, response_data, kPageID2, true);
+ ExpectFilledCreditCardFormElvis(response_page_id, response_data, kPageID2,
+ true);
}
}
@@ -2648,7 +2707,7 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_ExpiredCard) {
test::CreateTestFormField("Name on Card", "nameoncard", "", "text", &field);
field.autocomplete_attribute = "cc-name";
form.fields.push_back(field);
- std::vector<const char*> kCreditCardTypes = {"Visa", "Master Card", "AmEx",
+ std::vector<const char*> kCreditCardTypes = {"Visa", "Mastercard", "AmEx",
"discover"};
test::CreateTestSelectField("Card Type", "cardtype", "", kCreditCardTypes,
kCreditCardTypes, 4, &field);
@@ -2734,8 +2793,7 @@ TEST_F(AutofillManagerTest, FillFormWithNonFocusableFields) {
ASSERT_EQ(6U, response_data.fields.size());
ExpectFilledField("First Name", "firstname", "Elvis", "text",
response_data.fields[0]);
- ExpectFilledField("", "lastname", "Presley", "text",
- response_data.fields[1]);
+ ExpectFilledField("", "lastname", "Presley", "text", response_data.fields[1]);
ExpectFilledField("", "email", "theking@gmail.com", "text",
response_data.fields[2]);
ExpectFilledField("Phone Number", "phonenumber", "12345678901", "tel",
@@ -2771,7 +2829,7 @@ TEST_F(AutofillManagerTest, FillFormWithMultipleSections) {
{
SCOPED_TRACE("Address 1");
// The second address section should be empty.
- ASSERT_EQ(response_data.fields.size(), 2*kAddressFormSize);
+ ASSERT_EQ(response_data.fields.size(), 2 * kAddressFormSize);
for (size_t i = kAddressFormSize; i < form.fields.size(); ++i) {
EXPECT_EQ(base::string16(), response_data.fields[i].value);
}
@@ -2796,7 +2854,7 @@ TEST_F(AutofillManagerTest, FillFormWithMultipleSections) {
ASSERT_EQ(response_data.fields.size(), form.fields.size());
// The first address section should be empty.
- ASSERT_EQ(response_data.fields.size(), 2*kAddressFormSize);
+ ASSERT_EQ(response_data.fields.size(), 2 * kAddressFormSize);
for (size_t i = 0; i < kAddressFormSize; ++i) {
EXPECT_EQ(base::string16(), response_data.fields[i].value);
}
@@ -2921,8 +2979,7 @@ TEST_F(AutofillManagerTest, FillFormWithAuthorSpecifiedSections) {
EXPECT_EQ(GURL("https://myform.com/submit.html"), response_data.action);
ASSERT_EQ(11U, response_data.fields.size());
- ExpectFilledField("", "country", "US", "text",
- response_data.fields[0]);
+ ExpectFilledField("", "country", "US", "text", response_data.fields[0]);
ExpectFilledField("", "firstname", "", "text", response_data.fields[1]);
ExpectFilledField("", "lastname", "", "text", response_data.fields[2]);
ExpectFilledField("", "address", "3734 Elvis Presley Blvd.", "text",
@@ -3033,15 +3090,14 @@ TEST_F(AutofillManagerTest, FillAutofilledForm) {
&response_page_id, &response_data);
{
SCOPED_TRACE("Credit card 1");
- ExpectFilledCreditCardFormElvis(
- response_page_id, response_data, kPageID2, true);
+ ExpectFilledCreditCardFormElvis(response_page_id, response_data, kPageID2,
+ true);
}
// Now set the credit card fields to also be auto-filled, and try again to
// fill the credit card data
for (std::vector<FormFieldData>::iterator iter = form.fields.begin();
- iter != form.fields.end();
- ++iter) {
+ iter != form.fields.end(); ++iter) {
iter->is_autofilled = true;
}
@@ -3076,19 +3132,17 @@ TEST_F(AutofillManagerTest, FillPhoneNumber) {
const char* name;
size_t max_length;
const char* autocomplete_attribute;
- } test_fields[] = {
- { "country code", "country_code", 1, "tel-country-code" },
- { "area code", "area_code", 3, "tel-area-code" },
- { "phone", "phone_prefix", 3, "tel-local-prefix" },
- { "-", "phone_suffix", 4, "tel-local-suffix" },
- { "Phone Extension", "ext", 3, "tel-extension" }
- };
+ } test_fields[] = {{"country code", "country_code", 1, "tel-country-code"},
+ {"area code", "area_code", 3, "tel-area-code"},
+ {"phone", "phone_prefix", 3, "tel-local-prefix"},
+ {"-", "phone_suffix", 4, "tel-local-suffix"},
+ {"Phone Extension", "ext", 3, "tel-extension"}};
FormFieldData field;
const size_t default_max_length = field.max_length;
for (const auto& test_field : test_fields) {
- test::CreateTestFormField(
- test_field.label, test_field.name, "", "text", &field);
+ test::CreateTestFormField(test_field.label, test_field.name, "", "text",
+ &field);
field.max_length = test_field.max_length;
field.autocomplete_attribute = std::string();
form_with_us_number_max_length.fields.push_back(field);
@@ -3510,7 +3564,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictions) {
// Simulate having seen this form on page load.
// |form_structure| will be owned by |autofill_manager_|.
TestFormStructure* form_structure = new TestFormStructure(form);
- form_structure->DetermineHeuristicTypes(nullptr /* ukm_service */);
+ form_structure->DetermineHeuristicTypes(nullptr /* ukm_recorder */);
autofill_manager_->AddSeenForm(base::WrapUnique(form_structure));
// Similarly, a second form.
@@ -3530,7 +3584,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictions) {
form2.fields.push_back(field);
TestFormStructure* form_structure2 = new TestFormStructure(form2);
- form_structure2->DetermineHeuristicTypes(nullptr /* ukm_service */);
+ form_structure2->DetermineHeuristicTypes(nullptr /* ukm_recorder */);
autofill_manager_->AddSeenForm(base::WrapUnique(form_structure2));
AutofillQueryResponseContents response;
@@ -3559,8 +3613,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictions) {
AutofillMetrics::QUERY_RESPONSE_RECEIVED,
1);
histogram_tester.ExpectBucketCount("Autofill.ServerQueryResponse",
- AutofillMetrics::QUERY_RESPONSE_PARSED,
- 1);
+ AutofillMetrics::QUERY_RESPONSE_PARSED, 1);
// We expect the server type to have been applied to the first field of the
// first form.
EXPECT_EQ(NAME_FIRST, form_structure->field(0)->Type().GetStorableType());
@@ -3583,7 +3636,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictions_ResetManager) {
// Simulate having seen this form on page load.
// |form_structure| will be owned by |autofill_manager_|.
TestFormStructure* form_structure = new TestFormStructure(form);
- form_structure->DetermineHeuristicTypes(nullptr /* ukm_service */);
+ form_structure->DetermineHeuristicTypes(nullptr /* ukm_recorder */);
autofill_manager_->AddSeenForm(base::WrapUnique(form_structure));
AutofillQueryResponseContents response;
@@ -3617,11 +3670,12 @@ TEST_F(AutofillManagerTest, FormSubmittedServerTypes) {
// Set up our form data.
FormData form;
test::CreateTestAddressFormData(&form);
+ FormsSeen(std::vector<FormData>(1, form));
// Simulate having seen this form on page load.
// |form_structure| will be owned by |autofill_manager_|.
TestFormStructure* form_structure = new TestFormStructure(form);
- form_structure->DetermineHeuristicTypes(nullptr /* ukm_service */);
+ form_structure->DetermineHeuristicTypes(nullptr /* ukm_recorder */);
// Clear the heuristic types, and instead set the appropriate server types.
std::vector<ServerFieldType> heuristic_types, server_types;
@@ -3656,6 +3710,7 @@ TEST_F(AutofillManagerTest, FormSubmittedPossibleTypesTwoSubmissions) {
FormData form;
std::vector<ServerFieldTypeSet> expected_types;
test::CreateTestAddressFormData(&form, &expected_types);
+ FormsSeen(std::vector<FormData>(1, form));
// Fill the form.
const char guid[] = "00000000-0000-0000-0000-000000000001";
@@ -3852,7 +3907,7 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesForUpload) {
std::vector<CreditCard> credit_cards;
CreditCard credit_card;
test::SetCreditCardInfo(&credit_card, "John Doe", "4234-5678-9012-3456", "04",
- "2999");
+ "2999", "1");
credit_card.set_guid("00000000-0000-0000-0000-000000000003");
credit_cards.push_back(credit_card);
@@ -3889,8 +3944,8 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesForUpload) {
// Test a European profile.
{"Paris", ADDRESS_HOME_CITY},
- {"ÃŽle de France", ADDRESS_HOME_STATE}, // Exact match
- {"Ile de France", ADDRESS_HOME_STATE}, // Missing accent.
+ {"ÃŽle de France", ADDRESS_HOME_STATE}, // Exact match
+ {"Ile de France", ADDRESS_HOME_STATE}, // Missing accent.
{"-Ile-de-France-", ADDRESS_HOME_STATE}, // Extra punctuation.
{"île dÉ FrÃÑÇË", ADDRESS_HOME_STATE}, // Other accents & case mismatch.
{"75008", ADDRESS_HOME_ZIP},
@@ -4039,7 +4094,7 @@ TEST_F(AutofillManagerTest, DisambiguateUploadTypes) {
std::vector<CreditCard> credit_cards;
CreditCard credit_card;
test::SetCreditCardInfo(&credit_card, "Elvis Presley", "4234-5678-9012-3456",
- "04", "2999");
+ "04", "2999", "1");
credit_card.set_guid("00000000-0000-0000-0000-000000000003");
credit_cards.push_back(credit_card);
@@ -4486,9 +4541,9 @@ TEST_F(AutofillManagerTest,
GetAutofillSuggestions(form, number_field);
external_delegate_->CheckSuggestions(
- kDefaultPageID, Suggestion("Visa" + kUTF8MidlineEllipsis + "3456",
- "04/99", kVisaCard,
- autofill_manager_->GetPackedCreditCardID(4)));
+ kDefaultPageID,
+ Suggestion(std::string("Visa") + kUTF8MidlineEllipsis + "3456", "04/99",
+ kVisaCard, autofill_manager_->GetPackedCreditCardID(4)));
}
// Test that inputs detected to be CVC inputs are forced to
@@ -4575,14 +4630,8 @@ TEST_F(AutofillManagerTest, FillInUpdatedExpirationDate) {
"4012888888881881");
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard DISABLED_UploadCreditCard
-#else
-#define MAYBE_UploadCreditCard UploadCreditCard
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard) {
+ personal_data_.ClearCreditCards();
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -4611,23 +4660,118 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard) {
base::HistogramTester histogram_tester;
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
FormSubmitted(credit_card_form);
EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ EXPECT_THAT(
+ autofill_manager_->GetActiveExperiments(),
+ UnorderedElementsAre(kAutofillUpstreamUseAutofillProfileComparator.name));
+ // Server did not send a server_id, expect copy of card is not stored.
+ EXPECT_TRUE(autofill_manager_->GetCreditCards().empty());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample("Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_OFFERED, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+ // Verify the histogram entry for recent profile modification.
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.HasModifiedProfile.CreditCardFormSubmission", true, 1);
+ // Verify that UMA for "DaysSincePreviousUse" was not logged because we
+ // modified the profile.
+ histogram_tester.ExpectTotalCount(
+ "Autofill.DaysSincePreviousUseAtSubmission.Profile", 0);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_FeatureNotEnabled DISABLED_UploadCreditCard_FeatureNotEnabled
+TEST_F(AutofillManagerTest, UploadCreditCard_RequestCVCEnabled_DoesNotTrigger) {
+ EnableAutofillUpstreamRequestCvcIfMissingExperiment();
+
+ personal_data_.ClearCreditCards();
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen({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, true, false);
+ FormsSeen({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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ // Submitted form included CVC, so user did not need to enter CVC.
+ EXPECT_THAT(
+ autofill_manager_->GetActiveExperiments(),
+ UnorderedElementsAre(kAutofillUpstreamUseAutofillProfileComparator.name));
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCardAndSaveCopy) {
+ personal_data_.ClearCreditCards();
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ const char* const server_id = "InstrumentData:1234";
+ autofill_manager_->ResetPaymentsClientForCardUpload(server_id);
+
+ // 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, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ const char* const card_number = "4111111111111111";
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16(card_number);
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ FormSubmitted(credit_card_form);
+
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ EXPECT_TRUE(autofill_manager_->GetLocalCreditCards().empty());
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ // See |OfferStoreUnmaskedCards|
+ EXPECT_TRUE(autofill_manager_->GetCreditCards().empty());
#else
-#define MAYBE_UploadCreditCard_FeatureNotEnabled UploadCreditCard_FeatureNotEnabled
+ ASSERT_EQ(1U, autofill_manager_->GetCreditCards().size());
+ const CreditCard* const saved_card = autofill_manager_->GetCreditCards()[0];
+ EXPECT_EQ(CreditCard::OK, saved_card->GetServerStatus());
+ EXPECT_EQ(base::ASCIIToUTF16("1111"), saved_card->LastFourDigits());
+ EXPECT_EQ(kVisaCard, saved_card->network());
+ EXPECT_EQ(11, saved_card->expiration_month());
+ EXPECT_EQ(2017, saved_card->expiration_year());
+ EXPECT_EQ(server_id, saved_card->server_id());
+ EXPECT_EQ(CreditCard::FULL_SERVER_CARD, saved_card->record_type());
+ EXPECT_EQ(base::ASCIIToUTF16(card_number), saved_card->number());
#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_FeatureNotEnabled) {
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_FeatureNotEnabled) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(false);
@@ -4658,18 +4802,11 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_FeatureNotEnabled) {
FormSubmitted(credit_card_form);
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
- // Verify that no histogram entry was logged called.
- histogram_tester.ExpectTotalCount("Autofill.CardUploadDecisionExpanded", 0);
+ // Verify that no histogram entry was logged.
+ histogram_tester.ExpectTotalCount("Autofill.CardUploadDecisionMetric", 0);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_CvcUnavailable DISABLED_UploadCreditCard_CvcUnavailable
-#else
-#define MAYBE_UploadCreditCard_CvcUnavailable UploadCreditCard_CvcUnavailable
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_CvcUnavailable) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_CvcUnavailable) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -4704,11 +4841,10 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_CvcUnavailable) {
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::CVC_VALUE_NOT_FOUND);
// Verify that the correct UKM was logged.
- ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+ ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_VALUE_NOT_FOUND);
rappor::TestRapporServiceImpl* rappor_service =
autofill_client_.test_rappor_service();
@@ -4721,14 +4857,7 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_CvcUnavailable) {
EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_CvcInvalidLength DISABLED_UploadCreditCard_CvcInvalidLength
-#else
-#define MAYBE_UploadCreditCard_CvcInvalidLength UploadCreditCard_CvcInvalidLength
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_CvcInvalidLength) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_CvcInvalidLength) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -4760,11 +4889,10 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_CvcInvalidLength) {
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::INVALID_CVC_VALUE);
// Verify that the correct UKM was logged.
- ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+ ExpectCardUploadDecisionUkm(AutofillMetrics::INVALID_CVC_VALUE);
rappor::TestRapporServiceImpl* rappor_service =
autofill_client_.test_rappor_service();
@@ -4777,14 +4905,7 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_CvcInvalidLength) {
EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_MultipleCvcFields DISABLED_UploadCreditCard_MultipleCvcFields
-#else
-#define MAYBE_UploadCreditCard_MultipleCvcFields UploadCreditCard_MultipleCvcFields
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_MultipleCvcFields) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_MultipleCvcFields) {
autofill_manager_->set_credit_card_upload_enabled(true);
// Remove the profiles that were created in the TestPersonalDataManager
@@ -4838,23 +4959,13 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_MultipleCvcFields) {
EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_OFFERED, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NoCvcFieldOnForm \
- DISABLED_UploadCreditCard_NoCvcFieldOnForm
-#else
-#define MAYBE_UploadCreditCard_NoCvcFieldOnForm \
- UploadCreditCard_NoCvcFieldOnForm
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoCvcFieldOnForm) {
- EnableAutofillUpstreamRequestCvcIfMissingExperimentAndUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_NoCvcFieldOnForm) {
autofill_manager_->set_credit_card_upload_enabled(true);
// Remove the profiles that were created in the TestPersonalDataManager
@@ -4896,30 +5007,268 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoCvcFieldOnForm) {
base::HistogramTester histogram_tester;
- // Upload should still happen as long as the user provides CVC in the bubble.
+ // Upload should not happen because user did not provide CVC.
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
FormSubmitted(credit_card_form);
- EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::CVC_FIELD_NOT_FOUND);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_FIELD_NOT_FOUND);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_NoCvcFieldOnForm_InvalidCvcInNonCvcField) {
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Remove the profiles that were created in the TestPersonalDataManager
+ // constructor because they would result in conflicting names that would
+ // prevent the upload.
+ personal_data_.ClearAutofillProfiles();
+
+ // 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({address_form});
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // 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.action = GURL("https://myform.com/submit.html");
+
+ FormFieldData field;
+ test::CreateTestFormField("Card Name", "cardname", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Month", "ccmonth", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Year", "ccyear", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Random Field", "random", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+
+ FormsSeen({credit_card_form});
+
+ // Enter an invalid cvc in "Random Field" 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("1234");
+
+ base::HistogramTester histogram_tester;
+
+ // Upload should not happen because user did not provide CVC.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::CVC_FIELD_NOT_FOUND);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_FIELD_NOT_FOUND);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_NoCvcFieldOnForm_CvcInNonCvcField) {
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Remove the profiles that were created in the TestPersonalDataManager
+ // constructor because they would result in conflicting names that would
+ // prevent the upload.
+ personal_data_.ClearAutofillProfiles();
+
+ // 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({address_form});
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // 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.action = GURL("https://myform.com/submit.html");
+
+ FormFieldData field;
+ test::CreateTestFormField("Card Name", "cardname", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Month", "ccmonth", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Year", "ccyear", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Random Field", "random", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+
+ FormsSeen({credit_card_form});
+
+ // Enter an invalid cvc in "Random Field" 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Upload should not happen because user did not provide CVC.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample("Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_OFFERED_NO_CVC,
- 1);
+ ExpectUniqueCardUploadDecision(
+ histogram_tester,
+ AutofillMetrics::FOUND_POSSIBLE_CVC_VALUE_IN_NON_CVC_FIELD);
// Verify that the correct UKM was logged.
- ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED_NO_CVC);
+ ExpectCardUploadDecisionUkm(
+ AutofillMetrics::FOUND_POSSIBLE_CVC_VALUE_IN_NON_CVC_FIELD);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_NoCvcFieldOnForm_CvcInAddressField) {
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Remove the profiles that were created in the TestPersonalDataManager
+ // constructor because they would result in conflicting names that would
+ // prevent the upload.
+ personal_data_.ClearAutofillProfiles();
+
+ // 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({address_form});
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // 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.action = GURL("https://myform.com/submit.html");
+
+ FormFieldData field;
+ test::CreateTestFormField("Card Name", "cardname", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Month", "ccmonth", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Year", "ccyear", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Address Line 1", "addr1", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+
+ FormsSeen({credit_card_form});
+
+ // Enter an invalid cvc in "Random Field" 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Upload should not happen because user did not provide CVC.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::CVC_FIELD_NOT_FOUND);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_FIELD_NOT_FOUND);
}
// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NoCvcFieldOnFormExperimentOff \
- DISABLED_UploadCreditCard_NoCvcFieldOnFormExperimentOff
+#define MAYBE_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc \
+ DISABLED_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc
#else
-#define MAYBE_UploadCreditCard_NoCvcFieldOnFormExperimentOff \
- UploadCreditCard_NoCvcFieldOnFormExperimentOff
+#define MAYBE_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc \
+ UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc
#endif
TEST_F(AutofillManagerTest,
- MAYBE_UploadCreditCard_NoCvcFieldOnFormExperimentOff) {
- EnableUkmLogging();
+ MAYBE_UploadCreditCard_NoCvcFieldOnForm_UserEntersCvc) {
+ EnableAutofillUpstreamRequestCvcIfMissingExperiment();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Remove the profiles that were created in the TestPersonalDataManager
+ // constructor because they would result in conflicting names that would
+ // prevent the upload.
+ personal_data_.ClearAutofillProfiles();
+
+ // 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. 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.action = GURL("https://myform.com/submit.html");
+
+ FormFieldData field;
+ test::CreateTestFormField("Card Name", "cardname", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Month", "ccmonth", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+ test::CreateTestFormField("Expiration Year", "ccyear", "", "text", &field);
+ credit_card_form.fields.push_back(field);
+
+ 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+
+ base::HistogramTester histogram_tester;
+
+ // Upload should still happen as long as the user provides CVC in the bubble.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ EXPECT_THAT(
+ autofill_manager_->GetActiveExperiments(),
+ UnorderedElementsAre(kAutofillUpstreamUseAutofillProfileComparator.name,
+ kAutofillUpstreamRequestCvcIfMissing.name));
+
+ // Verify that the correct histogram entries were logged.
+ ExpectCardUploadDecision(histogram_tester, AutofillMetrics::UPLOAD_OFFERED);
+ ExpectCardUploadDecision(histogram_tester,
+ AutofillMetrics::CVC_FIELD_NOT_FOUND);
+ // Verify that the correct UKM was logged.
+ ExpectMetric(
+ internal::kUKMCardUploadDecisionMetricName,
+ internal::kUKMCardUploadDecisionEntryName,
+ AutofillMetrics::UPLOAD_OFFERED | AutofillMetrics::CVC_FIELD_NOT_FOUND,
+ 1 /* expected_num_matching_entries */);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_NoCvcFieldOnFormExperimentOff) {
autofill_manager_->set_credit_card_upload_enabled(true);
// Remove the profiles that were created in the TestPersonalDataManager
@@ -4967,11 +5316,10 @@ TEST_F(AutofillManagerTest,
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::CVC_FIELD_NOT_FOUND);
// Verify that the correct UKM was logged.
- ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+ ExpectCardUploadDecisionUkm(AutofillMetrics::CVC_FIELD_NOT_FOUND);
rappor::TestRapporServiceImpl* rappor_service =
autofill_client_.test_rappor_service();
@@ -4984,14 +5332,7 @@ TEST_F(AutofillManagerTest,
EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NoProfileAvailable DISABLED_UploadCreditCard_NoProfileAvailable
-#else
-#define MAYBE_UploadCreditCard_NoProfileAvailable UploadCreditCard_NoProfileAvailable
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoProfileAvailable) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_NoProfileAvailable) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5016,12 +5357,12 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoProfileAvailable) {
FormSubmitted(credit_card_form);
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
- // Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS, 1);
+ // Verify that the correct histogram entries are logged.
+ ExpectUniqueCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE);
// Verify that the correct UKM was logged.
- ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS);
+ ExpectCardUploadDecisionUkm(
+ AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE);
rappor::TestRapporServiceImpl* rappor_service =
autofill_client_.test_rappor_service();
@@ -5034,15 +5375,115 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoProfileAvailable) {
EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_CvcUnavailableAndNoProfileAvailable DISABLED_UploadCreditCard_CvcUnavailableAndNoProfileAvailable
-#else
-#define MAYBE_UploadCreditCard_CvcUnavailableAndNoProfileAvailable UploadCreditCard_CvcUnavailableAndNoProfileAvailable
-#endif
+TEST_F(AutofillManagerTest, UploadCreditCard_NoRecentlyUsedProfile) {
+ // Create the test clock and set the time to a specific value.
+ TestAutofillClock test_clock;
+ test_clock.SetNow(kArbitraryTime);
+
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit an address form in order to establish a profile.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen({address_form});
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set the current time to another value.
+ test_clock.SetNow(kMuchLaterTime);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Neither a local save nor an upload should happen in this case.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(
+ histogram_tester,
+ AutofillMetrics::UPLOAD_NOT_OFFERED_NO_RECENTLY_USED_ADDRESS);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(
+ AutofillMetrics::UPLOAD_NOT_OFFERED_NO_RECENTLY_USED_ADDRESS);
+ // Verify the histogram entry for recent profile modification.
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.HasModifiedProfile.CreditCardFormSubmission", false, 1);
+}
+
TEST_F(AutofillManagerTest,
- MAYBE_UploadCreditCard_CvcUnavailableAndNoProfileAvailable) {
- EnableUkmLogging();
+ UploadCreditCard_NoRecentlyUsedProfile_CanUseOldProfile) {
+ variation_params_.SetVariationParamsWithFeatureAssociations(
+ kAutofillUpstreamUseNotRecentlyUsedAutofillProfile.name,
+ {{kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey,
+ base::IntToString((kMuchLaterTime - kArbitraryTime).InMinutes() + 1)}},
+ {kAutofillUpstreamUseNotRecentlyUsedAutofillProfile.name});
+
+ // Create the test clock and set the time to a specific value.
+ TestAutofillClock test_clock;
+ test_clock.SetNow(kArbitraryTime);
+
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit an address form in order to establish a profile.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen({address_form});
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Advance the current time. Although |address_form| is not a recently used
+ // address profile, we will include it in the candidate profiles because
+ // there are no recently used address profiles and the feature to use older
+ // profiles is enabled.
+ test_clock.SetNow(kMuchLaterTime);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Upload should be offered.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ EXPECT_THAT(autofill_manager_->GetActiveExperiments(),
+ UnorderedElementsAre(
+ kAutofillUpstreamUseAutofillProfileComparator.name,
+ kAutofillUpstreamUseNotRecentlyUsedAutofillProfile.name));
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_CvcUnavailableAndNoProfileAvailable) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5069,12 +5510,17 @@ TEST_F(AutofillManagerTest,
FormSubmitted(credit_card_form);
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
- // Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC, 1);
+ // Verify that the correct histogram entries were logged.
+ ExpectCardUploadDecision(histogram_tester,
+ AutofillMetrics::CVC_VALUE_NOT_FOUND);
+ ExpectCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE);
// Verify that the correct UKM was logged.
- ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+ ExpectMetric(internal::kUKMCardUploadDecisionMetricName,
+ internal::kUKMCardUploadDecisionEntryName,
+ AutofillMetrics::CVC_VALUE_NOT_FOUND |
+ AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE,
+ 1 /* expected_num_matching_entries */);
rappor::TestRapporServiceImpl* rappor_service =
autofill_client_.test_rappor_service();
@@ -5087,14 +5533,7 @@ TEST_F(AutofillManagerTest,
EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NoNameAvailable DISABLED_UploadCreditCard_NoNameAvailable
-#else
-#define MAYBE_UploadCreditCard_NoNameAvailable UploadCreditCard_NoNameAvailable
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoNameAvailable) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_NoNameAvailable) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5126,9 +5565,8 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoNameAvailable) {
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_NAME);
@@ -5143,14 +5581,7 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoNameAvailable) {
EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_ZipCodesConflict DISABLED_UploadCreditCard_ZipCodesConflict
-#else
-#define MAYBE_UploadCreditCard_ZipCodesConflict UploadCreditCard_ZipCodesConflict
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_ZipCodesConflict) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_ZipCodesConflict) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5192,22 +5623,98 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_ZipCodesConflict) {
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS, 1);
+ ExpectUniqueCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(
AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_ZipCodesHavePrefixMatch DISABLED_UploadCreditCard_ZipCodesHavePrefixMatch
-#else
-#define MAYBE_UploadCreditCard_ZipCodesHavePrefixMatch UploadCreditCard_ZipCodesHavePrefixMatch
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_ZipCodesHavePrefixMatch) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_ZipCodesDiscardWhitespace) {
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different zip codes.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+
+ FormsSeen({address_form1, address_form2});
+
+ ManuallyFillAddressForm("Flo", "Master", "H3B2Y5", "CA", &address_form1);
+ FormSubmitted(address_form1);
+
+ ManuallyFillAddressForm("Flo", "Master", "h3b 2y5", "CA", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the data, but don't include a name, 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Zips match because we discard whitespace before comparison.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_ZipCodesDiscardWhitespace_DisableComparator) {
+ DisableAutofillUpstreamUseAutofillProfileComparator();
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different zip codes.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+
+ FormsSeen({address_form1, address_form2});
+
+ ManuallyFillAddressForm("Flo", "Master", "H3B2Y5", "CA", &address_form1);
+ FormSubmitted(address_form1);
+
+ ManuallyFillAddressForm("Flo", "Master", "h3b 2y5", "CA", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the data, but don't include a name, 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Neither a local save nor an upload should happen in this case.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_ZipCodesHavePrefixMatch) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5247,21 +5754,13 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_ZipCodesHavePrefixMatch) {
EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_OFFERED, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NoZipCodeAvailable DISABLED_UploadCreditCard_NoZipCodeAvailable
-#else
-#define MAYBE_UploadCreditCard_NoZipCodeAvailable UploadCreditCard_NoZipCodeAvailable
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoZipCodeAvailable) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_NoZipCodeAvailable) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5300,21 +5799,13 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoZipCodeAvailable) {
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE, 1);
+ ExpectUniqueCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_ZIP_CODE);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NamesMatchLoosely DISABLED_UploadCreditCard_NamesMatchLoosely
-#else
-#define MAYBE_UploadCreditCard_NamesMatchLoosely UploadCreditCard_NamesMatchLoosely
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesMatchLoosely) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_CCFormHasMiddleInitial) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5322,11 +5813,54 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesMatchLoosely) {
FormData address_form1, address_form2;
test::CreateTestAddressFormData(&address_form1);
test::CreateTestAddressFormData(&address_form2);
+ FormsSeen({address_form1, address_form2});
- std::vector<FormData> address_forms;
- address_forms.push_back(address_form1);
- address_forms.push_back(address_form2);
- FormsSeen(address_forms);
+ // Names can be different case.
+ ManuallyFillAddressForm("flo", "master", "77401", "US", &address_form1);
+ FormSubmitted(address_form1);
+
+ // And they can have a middle initial even if the other names don't.
+ ManuallyFillAddressForm("Flo W", "Master", "77401", "US", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the data, but use the name with a middle initial *and* period, and
+ // submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo W. Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Names match loosely, upload should happen.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_CCFormHasMiddleInitial_DisableComparator) {
+ DisableAutofillUpstreamUseAutofillProfileComparator();
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different names.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+ FormsSeen({address_form1, address_form2});
// Names can be different case.
ManuallyFillAddressForm("flo", "master", "77401", "US", &address_form1);
@@ -5339,7 +5873,7 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesMatchLoosely) {
// 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));
+ FormsSeen({credit_card_form});
// Edit the data, but use the name with a middle initial *and* period, and
// submit.
@@ -5355,23 +5889,210 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesMatchLoosely) {
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
FormSubmitted(credit_card_form);
EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ EXPECT_TRUE(autofill_manager_->GetActiveExperiments().empty());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_OFFERED, 1);
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_NoMiddleInitialInCCForm) {
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different names.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+ FormsSeen({address_form1, address_form2});
+
+ // Names can have different variations of middle initials.
+ ManuallyFillAddressForm("flo w.", "master", "77401", "US", &address_form1);
+ FormSubmitted(address_form1);
+ ManuallyFillAddressForm("Flo W", "Master", "77401", "US", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the data, but do not use middle initial.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Names match loosely, upload should happen.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_NamesHaveToMatch DISABLED_UploadCreditCard_NamesHaveToMatch
-#else
-#define MAYBE_UploadCreditCard_NamesHaveToMatch UploadCreditCard_NamesHaveToMatch
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesHaveToMatch) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_NoMiddleInitialInCCForm_DisableComparator) {
+ DisableAutofillUpstreamUseAutofillProfileComparator();
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different names.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+ FormsSeen({address_form1, address_form2});
+
+ // Names can have different variations of middle initials.
+ ManuallyFillAddressForm("flo w.", "master", "77401", "US", &address_form1);
+ FormSubmitted(address_form1);
+ ManuallyFillAddressForm("Flo W", "Master", "77401", "US", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the data, but do not use middle initial.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Names match loosely, upload should happen.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_CCFormHasMiddleName) {
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit address form without middle name.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen({address_form});
+ ManuallyFillAddressForm("John", "Adams", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the name by adding a middle name.
+ credit_card_form.fields[0].value = ASCIIToUTF16("John Quincy Adams");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Names match loosely, upload should happen.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_CCFormHasMiddleName_DisableComparator) {
+ DisableAutofillUpstreamUseAutofillProfileComparator();
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit address form without middle name.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen({address_form});
+ ManuallyFillAddressForm("John", "Adams", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the name by adding a middle name.
+ credit_card_form.fields[0].value = ASCIIToUTF16("John Quincy Adams");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Names match loosely but we have disabled comparator. Upload should not
+ // happen.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_CCFormRemovesMiddleName) {
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit address form with middle name.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen({address_form});
+ ManuallyFillAddressForm("John Quincy", "Adams", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the name by removing middle name.
+ credit_card_form.fields[0].value = ASCIIToUTF16("John Adams");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Names match loosely, upload should happen.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_NamesHaveToMatch) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5411,9 +6132,8 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesHaveToMatch) {
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES, 1);
+ ExpectUniqueCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(
AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES);
@@ -5429,14 +6149,213 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NamesHaveToMatch) {
EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
}
-// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_UploadCreditCard_UploadDetailsFails DISABLED_UploadCreditCard_UploadDetailsFails
-#else
-#define MAYBE_UploadCreditCard_UploadDetailsFails UploadCreditCard_UploadDetailsFails
-#endif
-TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_UploadDetailsFails) {
- EnableUkmLogging();
+TEST_F(AutofillManagerTest, UploadCreditCard_IgnoreOldProfiles) {
+ // Create the test clock and set the time to a specific value.
+ TestAutofillClock test_clock;
+ test_clock.SetNow(kArbitraryTime);
+
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different names.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+ FormsSeen({address_form1, address_form2});
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form1);
+ FormSubmitted(address_form1);
+
+ // Advance the current time. Since |address_form1| will not be a recently
+ // used address profile, we will not include it in the candidate profiles.
+ test_clock.SetNow(kMuchLaterTime);
+
+ ManuallyFillAddressForm("Master", "Blaster", "77401", "US", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, but use yet another name, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Master Blaster");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Name matches recently used profile, should offer upload.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_IgnoreOldProfiles_CanUseOldProfiles) {
+ variation_params_.SetVariationParamsWithFeatureAssociations(
+ kAutofillUpstreamUseNotRecentlyUsedAutofillProfile.name,
+ {{kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey,
+ base::IntToString((kMuchLaterTime - kArbitraryTime).InMinutes() + 1)}},
+ {kAutofillUpstreamUseNotRecentlyUsedAutofillProfile.name});
+
+ // Create the test clock and set the time to a specific value.
+ TestAutofillClock test_clock;
+ test_clock.SetNow(kArbitraryTime);
+
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different names.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+ FormsSeen({address_form1, address_form2});
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form1);
+ FormSubmitted(address_form1);
+
+ // Advance the current time. Since |address_form1| will not be a recently
+ // used address profile, we will not include it in the candidate profiles
+ // because we have a recently used address.
+ test_clock.SetNow(kMuchLaterTime);
+
+ ManuallyFillAddressForm("Master", "Blaster", "77401", "US", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, but use yet another name, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Master Blaster");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Name matches recently used profile, should offer upload.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+ // Recently used profile was available, so did not need to use old profile.
+ EXPECT_THAT(
+ autofill_manager_->GetActiveExperiments(),
+ UnorderedElementsAre(kAutofillUpstreamUseAutofillProfileComparator.name));
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED);
+}
+
+TEST_F(AutofillManagerTest,
+ UploadCreditCard_NamesHaveToMatch_DisableComparator) {
+ DisableAutofillUpstreamUseAutofillProfileComparator();
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit two address forms with different names.
+ FormData address_form1, address_form2;
+ test::CreateTestAddressFormData(&address_form1);
+ test::CreateTestAddressFormData(&address_form2);
+
+ std::vector<FormData> address_forms;
+ address_forms.push_back(address_form1);
+ address_forms.push_back(address_form2);
+ FormsSeen(address_forms);
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form1);
+ FormSubmitted(address_form1);
+
+ ManuallyFillAddressForm("Master", "Blaster", "77401", "US", &address_form2);
+ FormSubmitted(address_form2);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the data, but use yet another name, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Bob Master");
+ FormsSeen({credit_card_form});
+
+ // Edit the credit card form 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ // Names are required to match, upload should not happen.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that the correct histogram entry (and only that) was logged.
+ ExpectUniqueCardUploadDecision(
+ histogram_tester, AutofillMetrics::UPLOAD_NOT_OFFERED_CONFLICTING_NAMES);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_LogPreviousUseDate) {
+ // Create the test clock and set the time to a specific value.
+ TestAutofillClock test_clock;
+ test_clock.SetNow(kArbitraryTime);
+
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen({address_form});
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+ const std::vector<AutofillProfile*>& profiles =
+ personal_data_.GetProfilesToSuggest();
+ ASSERT_EQ(1U, profiles.size());
+
+ // Advance the current time and simulate use of the address profile.
+ test_clock.SetNow(kMuchLaterTime);
+ profiles[0]->RecordAndLogUse();
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen({credit_card_form});
+
+ // Edit the credit card form 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("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+ // Verify that UMA for "DaysSincePreviousUse" is logged.
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.DaysSincePreviousUseAtSubmission.Profile",
+ (kMuchLaterTime - kArbitraryTime).InDays(),
+ /*expected_count=*/1);
+}
+
+TEST_F(AutofillManagerTest, UploadCreditCard_UploadDetailsFails) {
personal_data_.ClearAutofillProfiles();
autofill_manager_->set_credit_card_upload_enabled(true);
@@ -5472,14 +6391,94 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_UploadDetailsFails) {
EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
// Verify that the correct histogram entry (and only that) was logged.
- histogram_tester.ExpectUniqueSample(
- "Autofill.CardUploadDecisionExpanded",
- AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED, 1);
+ ExpectUniqueCardUploadDecision(
+ histogram_tester,
+ AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED);
// Verify that the correct UKM was logged.
ExpectCardUploadDecisionUkm(
AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED);
}
+TEST_F(AutofillManagerTest, DuplicateMaskedCreditCard) {
+ EnableAutofillOfferLocalSaveIfServerCardManuallyEnteredExperiment();
+
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+ autofill_manager_->set_app_locale("en-US");
+
+ // 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);
+
+ // Add a masked credit card whose |TypeAndLastFourDigits| matches what we will
+ // enter below.
+ CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
+ test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11", "2017",
+ "1");
+ credit_card.SetNetworkForMaskedCard(kVisaCard);
+ personal_data_.AddServerCreditCard(credit_card);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ // The local save prompt should be shown.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _));
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+}
+
+TEST_F(AutofillManagerTest, DuplicateMaskedCreditCard_ExperimentOff) {
+ personal_data_.ClearAutofillProfiles();
+ autofill_manager_->set_credit_card_upload_enabled(true);
+ autofill_manager_->set_app_locale("en-US");
+
+ // 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);
+
+ // Add a masked credit card whose |TypeAndLastFourDigits| matches what we will
+ // enter below.
+ CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
+ test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11", "2017",
+ "1");
+ credit_card.SetNetworkForMaskedCard(kVisaCard);
+ personal_data_.AddServerCreditCard(credit_card);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16("11");
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ // The local save prompt should not be shown because the experiment is off.
+ EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+}
+
// Verify that typing "gmail" will match "theking@gmail.com" and
// "buddy@gmail.com" when substring matching is enabled.
TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens) {
@@ -5563,7 +6562,7 @@ TEST_F(AutofillManagerTest, DisplayCreditCardSuggestionsWithMatchingTokens) {
#if defined(OS_ANDROID)
static const std::string kVisaSuggestion =
- "Visa" + kUTF8MidlineEllipsis + "3456";
+ std::string("Visa") + kUTF8MidlineEllipsis + "3456";
#else
static const std::string kVisaSuggestion = "*3456";
#endif
@@ -5969,7 +6968,7 @@ TEST_F(AutofillManagerTest, DisplaySuggestionsForUpdatedServerTypedForm) {
form.fields.push_back(field);
auto form_structure = base::MakeUnique<TestFormStructure>(form);
- form_structure->DetermineHeuristicTypes(nullptr /* ukm_service */);
+ form_structure->DetermineHeuristicTypes(nullptr /* ukm_recorder */);
// Make sure the form can not be autofilled now.
ASSERT_EQ(0u, form_structure->autofill_count());
for (size_t idx = 0; idx < form_structure->field_count(); ++idx) {
@@ -6063,14 +7062,18 @@ TEST_F(AutofillManagerTest, SignInFormSubmission_Upload) {
test::CreateTestFormField("Password", "pw", "secret", "password", &field);
form.fields.push_back(field);
+ FormsSeen(std::vector<FormData>(1, form));
types.clear();
types.insert(PASSWORD);
expected_types.push_back(types);
+ FormsSeen({form});
+
// We will expect these types in the upload and no observed submission. (the
// callback initiated by WaitForAsyncUploadProcess checks these expectations.)
autofill_manager_->set_expected_submitted_field_types(expected_types);
autofill_manager_->set_expected_observed_submission(true);
+ autofill_manager_->set_call_parent_upload_form_data(true);
autofill_manager_->ResetRunLoop();
std::unique_ptr<FormStructure> form_structure(new FormStructure(form));
@@ -6078,6 +7081,11 @@ TEST_F(AutofillManagerTest, SignInFormSubmission_Upload) {
form_structure->field(1)->set_possible_types({autofill::PASSWORD});
std::string signature = form_structure->FormSignatureAsStr();
+
+ ServerFieldTypeSet uploaded_available_types;
+ EXPECT_CALL(*download_manager_,
+ StartUploadRequest(_, false, _, std::string(), true))
+ .WillOnce(DoAll(SaveArg<2>(&uploaded_available_types), Return(true)));
autofill_manager_->StartUploadProcess(std::move(form_structure),
base::TimeTicks::Now(), true);
@@ -6085,6 +7093,8 @@ TEST_F(AutofillManagerTest, SignInFormSubmission_Upload) {
autofill_manager_->WaitForAsyncUploadProcess();
EXPECT_EQ(signature, autofill_manager_->GetSubmittedFormSignature());
+ EXPECT_NE(uploaded_available_types.end(),
+ uploaded_available_types.find(autofill::PASSWORD));
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
index a4aceaab132..d04acca02c4 100644
--- a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -271,8 +271,10 @@ void AutofillMergeTest::MergeProfiles(const std::string& profiles,
// Import the profile.
std::unique_ptr<CreditCard> imported_credit_card;
- personal_data_.ImportFormData(form_structure, false,
- &imported_credit_card);
+ bool imported_credit_card_matches_masked_server_credit_card;
+ personal_data_.ImportFormData(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card);
EXPECT_FALSE(imported_credit_card);
// Clear the |form| to start a new profile.
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.cc b/chromium/components/autofill/core/browser/autofill_metrics.cc
index 77442395f20..3039a0832fd 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics.cc
@@ -12,21 +12,23 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/metrics/user_metrics.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/common/form_data.h"
-#include "components/ukm/ukm_entry_builder.h"
+#include "components/ukm/public/ukm_entry_builder.h"
namespace internal {
const char kUKMCardUploadDecisionEntryName[] = "Autofill.CardUploadDecision";
const char kUKMCardUploadDecisionMetricName[] = "UploadDecision";
const char kUKMDeveloperEngagementEntryName[] = "Autofill.DeveloperEngagement";
const char kUKMDeveloperEngagementMetricName[] = "DeveloperEngagement";
-const char kUKMMillisecondsSinceFormLoadedMetricName[] =
- "MillisecondsSinceFormLoaded";
+const char kUKMMillisecondsSinceFormParsedMetricName[] =
+ "MillisecondsSinceFormParsed";
const char kUKMInteractedWithFormEntryName[] = "Autofill.InteractedWithForm";
const char kUKMIsForCreditCardMetricName[] = "IsForCreditCard";
const char kUKMLocalRecordTypeCountMetricName[] = "LocalRecordTypeCount";
@@ -80,6 +82,27 @@ enum FieldTypeGroupForMetrics {
NUM_FIELD_TYPE_GROUPS_FOR_METRICS
};
+const int KMaxFieldTypeGroupMetric =
+ (NUM_FIELD_TYPE_GROUPS_FOR_METRICS << 8) |
+ AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS;
+
+std::string PreviousSaveCreditCardPromptUserDecisionToString(
+ int previous_save_credit_card_prompt_user_decision) {
+ DCHECK_LT(previous_save_credit_card_prompt_user_decision,
+ prefs::NUM_PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISIONS);
+ std::string previous_response;
+ if (previous_save_credit_card_prompt_user_decision ==
+ prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_ACCEPTED)
+ previous_response = ".PreviouslyAccepted";
+ else if (previous_save_credit_card_prompt_user_decision ==
+ prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_DENIED)
+ previous_response = ".PreviouslyDenied";
+ else
+ DCHECK_EQ(previous_save_credit_card_prompt_user_decision,
+ prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_NONE);
+ return previous_response;
+}
+
} // namespace
// First, translates |field_type| to the corresponding logical |group| from
@@ -211,9 +234,12 @@ int GetFieldTypeGroupMetric(ServerFieldType field_type,
break;
}
- // Interpolate the |metric| with the |group|, so that all metrics for a given
- // |group| are adjacent.
- return (group * AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS) + metric;
+ // Use bits 8-15 for the group and bits 0-7 for the metric.
+ static_assert(AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS <= UINT8_MAX,
+ "maximum field type quality metric must fit into 8 bits");
+ static_assert(NUM_FIELD_TYPE_GROUPS_FOR_METRICS <= UINT8_MAX,
+ "number of field type groups must fit into 8 bits");
+ return (group << 8) | metric;
}
namespace {
@@ -251,63 +277,223 @@ void LogUMAHistogramLongTimes(const std::string& name,
histogram->AddTime(duration);
}
-// Logs a type quality metric. The primary histogram name is constructed based
-// on |base_name|. The field-specific histogram name also factors in the
-// |field_type|. Logs a sample of |metric|, which should be in the range
-// [0, |num_possible_metrics|). May log a suffixed version of the metric
-// depending on |metric_type|.
-void LogTypeQualityMetric(const std::string& base_name,
- AutofillMetrics::FieldTypeQualityMetric metric,
- ServerFieldType field_type,
- AutofillMetrics::QualityMetricType metric_type) {
- DCHECK_LT(metric, AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
-
- std::string suffix;
+const char* GetQualityMetricTypeSuffix(
+ AutofillMetrics::QualityMetricType metric_type) {
switch (metric_type) {
+ default:
+ NOTREACHED();
+ // Fall through...
+
case AutofillMetrics::TYPE_SUBMISSION:
- break;
+ return "";
case AutofillMetrics::TYPE_NO_SUBMISSION:
- suffix = ".NoSubmission";
- break;
+ return ".NoSubmission";
case AutofillMetrics::TYPE_AUTOCOMPLETE_BASED:
- suffix = ".BasedOnAutocomplete";
- break;
- default:
- NOTREACHED();
+ return ".BasedOnAutocomplete";
+ }
+}
+
+// Given a set of |possible_types| for a field, select the best type to use as
+// the "actual" field type when calculating metrics. If the |predicted_type| is
+// among the |possible_types] then use that as the best type (i.e., the
+// prediction is deemed to have been correct).
+ServerFieldType GetActualFieldType(const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type) {
+ DCHECK_NE(possible_types.size(), 0u);
+
+ if (possible_types.count(EMPTY_TYPE)) {
+ DCHECK_EQ(possible_types.size(), 1u);
+ return EMPTY_TYPE;
+ }
+
+ if (possible_types.count(UNKNOWN_TYPE)) {
+ DCHECK_EQ(possible_types.size(), 1u);
+ return UNKNOWN_TYPE;
+ }
+
+ if (possible_types.count(predicted_type))
+ return predicted_type;
+
+ // Collapse field types that Chrome treats as identical, e.g. home and
+ // billing address fields.
+ ServerFieldTypeSet collapsed_field_types;
+ for (const auto& type : possible_types) {
+ DCHECK_NE(type, EMPTY_TYPE);
+ DCHECK_NE(type, UNKNOWN_TYPE);
+
+ // A phone number that's only missing its country code is (for metrics
+ // purposes) the same as the whole phone number.
+ if (type == PHONE_HOME_CITY_AND_NUMBER)
+ collapsed_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
+ else
+ collapsed_field_types.insert(AutofillType(type).GetStorableType());
+ }
+
+ // Capture the field's type, if it is unambiguous.
+ ServerFieldType actual_type = AMBIGUOUS_TYPE;
+ if (collapsed_field_types.size() == 1)
+ actual_type = *collapsed_field_types.begin();
+
+ DVLOG(2) << "Inferred Type: " << AutofillType(actual_type).ToString();
+ return actual_type;
+}
+
+// Logs field type prediction quality metrics. The primary histogram name is
+// constructed based on |source| The field-specific histogram name also factors
+// possible and predicted field types (|possible_types| and |predicted_type|,
+// respectively). May log a suffixed version of the metric depending on
+// |metric_type|.
+void LogPredictionQualityMetrics(
+ const base::StringPiece& source,
+ const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type,
+ AutofillMetrics::QualityMetricType metric_type) {
+ // Generate histogram names.
+ const char* const suffix = GetQualityMetricTypeSuffix(metric_type);
+ std::string raw_data_histogram =
+ base::JoinString({"Autofill.FieldPrediction.", source, suffix}, "");
+ std::string aggregate_histogram = base::JoinString(
+ {"Autofill.FieldPredictionQuality.Aggregate.", source, suffix}, "");
+ std::string type_specific_histogram = base::JoinString(
+ {"Autofill.FieldPredictionQuality.ByFieldType.", source, suffix}, "");
+
+ // Get the best type classification we can for the field.
+ ServerFieldType actual_type =
+ GetActualFieldType(possible_types, predicted_type);
+
+ DVLOG(2) << "Predicted: " << AutofillType(predicted_type).ToString() << "; "
+ << "Actual: " << AutofillType(actual_type).ToString();
+
+ DCHECK_LE(predicted_type, UINT16_MAX);
+ DCHECK_LE(actual_type, UINT16_MAX);
+ UMA_HISTOGRAM_SPARSE_SLOWLY(raw_data_histogram,
+ (predicted_type << 16) | actual_type);
+
+ // NO_SERVER_DATA is the equivalent of predicting UNKNOWN.
+ if (predicted_type == NO_SERVER_DATA)
+ predicted_type = UNKNOWN_TYPE;
+
+ // The actual type being EMPTY_TYPE is the same as UNKNOWN_TYPE for comparison
+ // purposes, but remember whether or not it was empty for more precise logging
+ // later.
+ bool is_empty = (actual_type == EMPTY_TYPE);
+ bool is_ambiguous = (actual_type == AMBIGUOUS_TYPE);
+ if (is_empty || is_ambiguous)
+ actual_type = UNKNOWN_TYPE;
+
+ // If the predicted and actual types match then it's either a true positive
+ // or a true negative (if they are both unknown). Do not log type specific
+ // true negatives (instead log a true positive for the "Ambiguous" type).
+ if (predicted_type == actual_type) {
+ if (actual_type == UNKNOWN_TYPE) {
+ // Only log aggregate true negative; do not log type specific metrics
+ // for UNKNOWN/EMPTY.
+ DVLOG(2) << "TRUE NEGATIVE";
+ LogUMAHistogramEnumeration(
+ aggregate_histogram,
+ (is_empty ? AutofillMetrics::TRUE_NEGATIVE_EMPTY
+ : (is_ambiguous ? AutofillMetrics::TRUE_NEGATIVE_AMBIGUOUS
+ : AutofillMetrics::TRUE_NEGATIVE_UNKNOWN)),
+ AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
+ return;
+ }
+
+ DVLOG(2) << "TRUE POSITIVE";
+ // Log both aggregate and type specific true positive if we correctly
+ // predict that type with which the field was filled.
+ LogUMAHistogramEnumeration(aggregate_histogram,
+ AutofillMetrics::TRUE_POSITIVE,
+ AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
+ LogUMAHistogramEnumeration(
+ type_specific_histogram,
+ GetFieldTypeGroupMetric(actual_type, AutofillMetrics::TRUE_POSITIVE),
+ KMaxFieldTypeGroupMetric);
+ return;
+ }
+
+ // Note: At this point predicted_type != actual type
+ // If actual type is UNKNOWN_TYPE then the prediction is a false positive.
+ // Further specialize the type of false positive by whether the field was
+ // empty or contained an unknown value.
+ if (actual_type == UNKNOWN_TYPE) {
+ DVLOG(2) << "FALSE POSITIVE";
+ auto metric =
+ (is_empty ? AutofillMetrics::FALSE_POSITIVE_EMPTY
+ : (is_ambiguous ? AutofillMetrics::FALSE_POSITIVE_AMBIGUOUS
+ : AutofillMetrics::FALSE_POSITIVE_UNKNOWN));
+ LogUMAHistogramEnumeration(aggregate_histogram, metric,
+ AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
+ LogUMAHistogramEnumeration(type_specific_histogram,
+ GetFieldTypeGroupMetric(predicted_type, metric),
+ KMaxFieldTypeGroupMetric);
+ return;
+ }
+
+ // Note: At this point predicted_type != actual type, actual_type != UNKNOWN.
+ // If predicted type is UNKNOWN_TYPE then the prediction is a false negative
+ // unknown.
+ if (predicted_type == UNKNOWN_TYPE) {
+ DVLOG(2) << "FALSE NEGATIVE";
+ LogUMAHistogramEnumeration(aggregate_histogram,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN,
+ AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
+ LogUMAHistogramEnumeration(
+ type_specific_histogram,
+ GetFieldTypeGroupMetric(actual_type,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
+ KMaxFieldTypeGroupMetric);
+ return;
}
- LogUMAHistogramEnumeration(base_name + suffix, metric,
- AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
- int field_type_group_metric = GetFieldTypeGroupMetric(field_type, metric);
- int num_field_type_group_metrics =
- AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS *
- NUM_FIELD_TYPE_GROUPS_FOR_METRICS;
- LogUMAHistogramEnumeration(base_name + ".ByFieldType" + suffix,
- field_type_group_metric,
- num_field_type_group_metrics);
+ DVLOG(2) << "MISMATCH";
+
+ // Note: At this point predicted_type != actual type, actual_type != UNKNOWN,
+ // predicted_type != UNKNOWN.
+ // This is a mismatch. From the reference of the actual type, this is a false
+ // negative (it was T, but predicted U). From the reference of the prediction,
+ // this is a false positive (predicted it was T, but it was U).
+ LogUMAHistogramEnumeration(aggregate_histogram,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH,
+ AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
+ LogUMAHistogramEnumeration(
+ type_specific_histogram,
+ GetFieldTypeGroupMetric(actual_type,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH),
+ KMaxFieldTypeGroupMetric);
+ LogUMAHistogramEnumeration(
+ type_specific_histogram,
+ GetFieldTypeGroupMetric(predicted_type,
+ AutofillMetrics::FALSE_POSITIVE_MISMATCH),
+ KMaxFieldTypeGroupMetric);
}
} // namespace
// static
-void AutofillMetrics::LogCardUploadDecisionMetric(
- CardUploadDecisionMetric metric) {
- DCHECK_LT(metric, NUM_CARD_UPLOAD_DECISION_METRICS);
- UMA_HISTOGRAM_ENUMERATION("Autofill.CardUploadDecisionExpanded", metric,
- NUM_CARD_UPLOAD_DECISION_METRICS);
+void AutofillMetrics::LogCardUploadDecisionMetrics(
+ int upload_decision_metrics) {
+ DCHECK(upload_decision_metrics);
+ DCHECK_LT(upload_decision_metrics, 1 << kNumCardUploadDecisionMetrics);
+
+ for (int metric = 0; metric < kNumCardUploadDecisionMetrics; ++metric)
+ if (upload_decision_metrics & (1 << metric))
+ UMA_HISTOGRAM_ENUMERATION("Autofill.CardUploadDecisionMetric", metric,
+ kNumCardUploadDecisionMetrics);
}
// static
-void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric,
- bool is_uploading) {
+void AutofillMetrics::LogCreditCardInfoBarMetric(
+ InfoBarMetric metric,
+ bool is_uploading,
+ int previous_save_credit_card_prompt_user_decision) {
DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
- if (is_uploading) {
- UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar.Server", metric,
- NUM_INFO_BAR_METRICS);
- } else {
- UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar.Local", metric,
- NUM_INFO_BAR_METRICS);
- }
+
+ std::string destination = is_uploading ? ".Server" : ".Local";
+ LogUMAHistogramEnumeration(
+ "Autofill.CreditCardInfoBar" + destination +
+ PreviousSaveCreditCardPromptUserDecisionToString(
+ previous_save_credit_card_prompt_user_decision),
+ metric, NUM_INFO_BAR_METRICS);
}
// static
@@ -318,15 +504,19 @@ void AutofillMetrics::LogCreditCardFillingInfoBarMetric(InfoBarMetric metric) {
}
// static
-void AutofillMetrics::LogSaveCardPromptMetric(SaveCardPromptMetric metric,
- bool is_uploading,
- bool is_reshow) {
+void AutofillMetrics::LogSaveCardPromptMetric(
+ SaveCardPromptMetric metric,
+ bool is_uploading,
+ bool is_reshow,
+ int previous_save_credit_card_prompt_user_decision) {
DCHECK_LT(metric, NUM_SAVE_CARD_PROMPT_METRICS);
std::string destination = is_uploading ? ".Upload" : ".Local";
std::string show = is_reshow ? ".Reshows" : ".FirstShow";
LogUMAHistogramEnumeration(
- "Autofill.SaveCreditCardPrompt" + destination + show, metric,
- NUM_SAVE_CARD_PROMPT_METRICS);
+ "Autofill.SaveCreditCardPrompt" + destination + show +
+ PreviousSaveCreditCardPromptUserDecisionToString(
+ previous_save_credit_card_prompt_user_decision),
+ metric, NUM_SAVE_CARD_PROMPT_METRICS);
}
// static
@@ -473,29 +663,28 @@ void AutofillMetrics::LogDeveloperEngagementMetric(
NUM_DEVELOPER_ENGAGEMENT_METRICS);
}
-// static
-void AutofillMetrics::LogHeuristicTypePrediction(
- FieldTypeQualityMetric metric,
- ServerFieldType field_type,
- QualityMetricType metric_type) {
- LogTypeQualityMetric("Autofill.Quality.HeuristicType", metric, field_type,
- metric_type);
+void AutofillMetrics::LogHeuristicPredictionQualityMetrics(
+ const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type,
+ AutofillMetrics::QualityMetricType metric_type) {
+ LogPredictionQualityMetrics("Heuristic", possible_types, predicted_type,
+ metric_type);
}
-// static
-void AutofillMetrics::LogOverallTypePrediction(FieldTypeQualityMetric metric,
- ServerFieldType field_type,
- QualityMetricType metric_type) {
- LogTypeQualityMetric("Autofill.Quality.PredictedType", metric, field_type,
- metric_type);
+void AutofillMetrics::LogServerPredictionQualityMetrics(
+ const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type,
+ AutofillMetrics::QualityMetricType metric_type) {
+ LogPredictionQualityMetrics("Server", possible_types, predicted_type,
+ metric_type);
}
-// static
-void AutofillMetrics::LogServerTypePrediction(FieldTypeQualityMetric metric,
- ServerFieldType field_type,
- QualityMetricType metric_type) {
- LogTypeQualityMetric("Autofill.Quality.ServerType", metric, field_type,
- metric_type);
+void AutofillMetrics::LogOverallPredictionQualityMetrics(
+ const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type,
+ AutofillMetrics::QualityMetricType metric_type) {
+ LogPredictionQualityMetrics("Overall", possible_types, predicted_type,
+ metric_type);
}
// static
@@ -592,6 +781,13 @@ void AutofillMetrics::LogNumberOfProfilesAtAutofillableFormSubmission(
}
// static
+void AutofillMetrics::LogHasModifiedProfileOnCreditCardFormSubmission(
+ bool has_modified_profile) {
+ UMA_HISTOGRAM_BOOLEAN("Autofill.HasModifiedProfile.CreditCardFormSubmission",
+ has_modified_profile);
+}
+
+// static
void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) {
UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
}
@@ -726,48 +922,48 @@ void AutofillMetrics::LogShowedHttpNotSecureExplanation() {
}
// static
-void AutofillMetrics::LogCardUploadDecisionUkm(
- ukm::UkmService* ukm_service,
- const GURL& url,
- AutofillMetrics::CardUploadDecisionMetric upload_decision) {
- if (upload_decision >= AutofillMetrics::NUM_CARD_UPLOAD_DECISION_METRICS)
- return;
+void AutofillMetrics::LogCardUploadDecisionsUkm(ukm::UkmRecorder* ukm_recorder,
+ const GURL& url,
+ int upload_decision_metrics) {
+ DCHECK(upload_decision_metrics);
+ DCHECK_LT(upload_decision_metrics, 1 << kNumCardUploadDecisionMetrics);
const std::vector<std::pair<const char*, int>> metrics = {
- {internal::kUKMCardUploadDecisionMetricName,
- static_cast<int>(upload_decision)}};
- LogUkm(ukm_service, url, internal::kUKMCardUploadDecisionEntryName, metrics);
+ {internal::kUKMCardUploadDecisionMetricName, upload_decision_metrics}};
+ LogUkm(ukm_recorder, url, internal::kUKMCardUploadDecisionEntryName, metrics);
}
// static
void AutofillMetrics::LogDeveloperEngagementUkm(
- ukm::UkmService* ukm_service,
+ ukm::UkmRecorder* ukm_recorder,
const GURL& url,
- std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics) {
- std::vector<std::pair<const char*, int>> form_structure_metrics;
- for (const auto it : metrics)
- form_structure_metrics.push_back(
- {internal::kUKMDeveloperEngagementMetricName, static_cast<int>(it)});
+ int developer_engagement_metrics) {
+ DCHECK(developer_engagement_metrics);
+ DCHECK_LT(developer_engagement_metrics,
+ 1 << NUM_DEVELOPER_ENGAGEMENT_METRICS);
- LogUkm(ukm_service, url, internal::kUKMDeveloperEngagementEntryName,
- form_structure_metrics);
+ const std::vector<std::pair<const char*, int>> metrics = {
+ {internal::kUKMDeveloperEngagementMetricName,
+ developer_engagement_metrics}};
+
+ LogUkm(ukm_recorder, url, internal::kUKMDeveloperEngagementEntryName,
+ metrics);
}
// static
bool AutofillMetrics::LogUkm(
- ukm::UkmService* ukm_service,
+ ukm::UkmRecorder* ukm_recorder,
const GURL& url,
const std::string& ukm_entry_name,
const std::vector<std::pair<const char*, int>>& metrics) {
- if (!IsUkmLoggingEnabled() || !ukm_service || !url.is_valid() ||
- metrics.empty()) {
+ if (!ukm_recorder || !url.is_valid() || metrics.empty()) {
return false;
}
- int32_t source_id = ukm_service->GetNewSourceID();
- ukm_service->UpdateSourceURL(source_id, url);
+ ukm::SourceId source_id = ukm_recorder->GetNewSourceID();
+ ukm_recorder->UpdateSourceURL(source_id, url);
std::unique_ptr<ukm::UkmEntryBuilder> builder =
- ukm_service->GetEntryBuilder(source_id, ukm_entry_name.c_str());
+ ukm_recorder->GetEntryBuilder(source_id, ukm_entry_name.c_str());
for (auto it = metrics.begin(); it != metrics.end(); ++it) {
builder->AddMetric(it->first, it->second);
@@ -822,8 +1018,9 @@ void AutofillMetrics::FormEventLogger::OnDidPollSuggestions(
}
}
-void AutofillMetrics::FormEventLogger::OnDidShowSuggestions() {
- form_interactions_ukm_logger_->LogSuggestionsShown();
+void AutofillMetrics::FormEventLogger::OnDidShowSuggestions(
+ const AutofillField& field) {
+ form_interactions_ukm_logger_->LogSuggestionsShown(field);
Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN);
if (!has_logged_suggestions_shown_) {
@@ -996,16 +1193,16 @@ void AutofillMetrics::FormEventLogger::Log(FormEvent event) const {
}
AutofillMetrics::FormInteractionsUkmLogger::FormInteractionsUkmLogger(
- ukm::UkmService* ukm_service)
- : ukm_service_(ukm_service) {}
+ ukm::UkmRecorder* ukm_recorder)
+ : ukm_recorder_(ukm_recorder) {}
-void AutofillMetrics::FormInteractionsUkmLogger::OnFormsLoaded(
+void AutofillMetrics::FormInteractionsUkmLogger::OnFormsParsed(
const GURL& url) {
- if (!IsUkmLoggingEnabled() || ukm_service_ == nullptr)
+ if (ukm_recorder_ == nullptr)
return;
url_ = url;
- form_loaded_timestamp_ = base::TimeTicks::Now();
+ form_parsed_timestamp_ = base::TimeTicks::Now();
}
void AutofillMetrics::FormInteractionsUkmLogger::LogInteractedWithForm(
@@ -1018,8 +1215,9 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogInteractedWithForm(
if (source_id_ == -1)
GetNewSourceID();
- std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
- source_id_, internal::kUKMInteractedWithFormEntryName);
+ std::unique_ptr<ukm::UkmEntryBuilder> builder =
+ ukm_recorder_->GetEntryBuilder(source_id_,
+ internal::kUKMInteractedWithFormEntryName);
builder->AddMetric(internal::kUKMIsForCreditCardMetricName,
is_for_credit_card);
builder->AddMetric(internal::kUKMLocalRecordTypeCountMetricName,
@@ -1028,17 +1226,25 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogInteractedWithForm(
server_record_type_count);
}
-void AutofillMetrics::FormInteractionsUkmLogger::LogSuggestionsShown() {
+void AutofillMetrics::FormInteractionsUkmLogger::LogSuggestionsShown(
+ const AutofillField& field) {
if (!CanLog())
return;
if (source_id_ == -1)
GetNewSourceID();
- std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
- source_id_, internal::kUKMSuggestionsShownEntryName);
- builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
- MillisecondsSinceFormLoaded());
+ std::unique_ptr<ukm::UkmEntryBuilder> builder =
+ ukm_recorder_->GetEntryBuilder(source_id_,
+ internal::kUKMSuggestionsShownEntryName);
+ builder->AddMetric(internal::kUKMHeuristicTypeMetricName,
+ static_cast<int>(field.heuristic_type()));
+ builder->AddMetric(internal::kUKMHtmlFieldTypeMetricName,
+ static_cast<int>(field.html_type()));
+ builder->AddMetric(internal::kUKMServerTypeMetricName,
+ static_cast<int>(field.server_type()));
+ builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
+ MillisecondsSinceFormParsed());
}
void AutofillMetrics::FormInteractionsUkmLogger::LogSelectedMaskedServerCard() {
@@ -1048,10 +1254,11 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogSelectedMaskedServerCard() {
if (source_id_ == -1)
GetNewSourceID();
- std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
- source_id_, internal::kUKMSelectedMaskedServerCardEntryName);
- builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
- MillisecondsSinceFormLoaded());
+ std::unique_ptr<ukm::UkmEntryBuilder> builder =
+ ukm_recorder_->GetEntryBuilder(
+ source_id_, internal::kUKMSelectedMaskedServerCardEntryName);
+ builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
+ MillisecondsSinceFormParsed());
}
void AutofillMetrics::FormInteractionsUkmLogger::LogDidFillSuggestion(
@@ -1062,11 +1269,12 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogDidFillSuggestion(
if (source_id_ == -1)
GetNewSourceID();
- std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
- source_id_, internal::kUKMSuggestionFilledEntryName);
+ std::unique_ptr<ukm::UkmEntryBuilder> builder =
+ ukm_recorder_->GetEntryBuilder(source_id_,
+ internal::kUKMSuggestionFilledEntryName);
builder->AddMetric(internal::kUKMRecordTypeMetricName, record_type);
- builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
- MillisecondsSinceFormLoaded());
+ builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
+ MillisecondsSinceFormParsed());
}
void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange(
@@ -1077,8 +1285,9 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange(
if (source_id_ == -1)
GetNewSourceID();
- std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
- source_id_, internal::kUKMTextFieldDidChangeEntryName);
+ std::unique_ptr<ukm::UkmEntryBuilder> builder =
+ ukm_recorder_->GetEntryBuilder(source_id_,
+ internal::kUKMTextFieldDidChangeEntryName);
builder->AddMetric(internal::kUKMFieldTypeGroupMetricName,
static_cast<int>(field.Type().group()));
builder->AddMetric(internal::kUKMHeuristicTypeMetricName,
@@ -1091,8 +1300,8 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange(
static_cast<int>(field.html_mode()));
builder->AddMetric(internal::kUKMIsAutofilledMetricName, field.is_autofilled);
builder->AddMetric(internal::kUKMIsEmptyMetricName, field.IsEmpty());
- builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
- MillisecondsSinceFormLoaded());
+ builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
+ MillisecondsSinceFormParsed());
}
void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
@@ -1103,35 +1312,41 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
if (source_id_ == -1)
GetNewSourceID();
- std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
- source_id_, internal::kUKMFormSubmittedEntryName);
+ std::unique_ptr<ukm::UkmEntryBuilder> builder =
+ ukm_recorder_->GetEntryBuilder(source_id_,
+ internal::kUKMFormSubmittedEntryName);
builder->AddMetric(internal::kUKMAutofillFormSubmittedStateMetricName,
static_cast<int>(state));
- builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
- MillisecondsSinceFormLoaded());
+ if (form_parsed_timestamp_.is_null())
+ DCHECK(state == NON_FILLABLE_FORM_OR_NEW_DATA ||
+ state == FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS)
+ << state;
+ else
+ builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
+ MillisecondsSinceFormParsed());
}
void AutofillMetrics::FormInteractionsUkmLogger::UpdateSourceURL(
const GURL& url) {
url_ = url;
if (CanLog())
- ukm_service_->UpdateSourceURL(source_id_, url_);
+ ukm_recorder_->UpdateSourceURL(source_id_, url_);
}
bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const {
- return IsUkmLoggingEnabled() && ukm_service_ && url_.is_valid();
+ return ukm_recorder_ && url_.is_valid();
}
int64_t
-AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormLoaded()
+AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed()
const {
- DCHECK(!form_loaded_timestamp_.is_null());
- return (base::TimeTicks::Now() - form_loaded_timestamp_).InMilliseconds();
+ DCHECK(!form_parsed_timestamp_.is_null());
+ return (base::TimeTicks::Now() - form_parsed_timestamp_).InMilliseconds();
}
void AutofillMetrics::FormInteractionsUkmLogger::GetNewSourceID() {
- source_id_ = ukm_service_->GetNewSourceID();
- ukm_service_->UpdateSourceURL(source_id_, url_);
+ source_id_ = ukm_recorder_->GetNewSourceID();
+ ukm_recorder_->UpdateSourceURL(source_id_, url_);
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.h b/chromium/components/autofill/core/browser/autofill_metrics.h
index 58ab8d26aa0..d849ce143f8 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.h
+++ b/chromium/components/autofill/core/browser/autofill_metrics.h
@@ -11,16 +11,15 @@
#include <vector>
#include "base/macros.h"
+#include "base/strings/string_piece_forward.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/common/autofill_pref_names.h"
#include "components/autofill/core/common/form_field_data.h"
-
-namespace ukm {
-class UkmService;
-} // namespace ukm
+#include "components/ukm/public/ukm_recorder.h"
namespace internal {
// Name constants are exposed here so they can be referenced from tests.
@@ -38,15 +37,19 @@ extern const char kUKMIsForCreditCardMetricName[];
extern const char kUKMLocalRecordTypeCountMetricName[];
extern const char kUKMServerRecordTypeCountMetricName[];
-// |UkmEntry| when we show suggestions.
+// |UkmEntry| when we show suggestions and when user edits text field. See
+// |kUkmTextFieldDidChangeEntryName|.
extern const char kUKMSuggestionsShownEntryName[];
+extern const char kUKMHeuristicTypeMetricName[];
+extern const char kUKMHtmlFieldTypeMetricName[];
+extern const char kUKMServerTypeMetricName[];
// |UkmEntry| when user selects a masked server credit card.
extern const char kUKMSelectedMaskedServerCardEntryName[];
// Each |UkmEntry|, except the first interaction with the form, has a metric for
// time elapsed, in milliseconds, since we loaded the form.
-extern const char kUKMMillisecondsSinceFormLoadedMetricName[];
+extern const char kUKMMillisecondsSinceFormParsedMetricName[];
// |FormEvent| for FORM_EVENT_*_SUGGESTION_FILLED in credit card forms include a
// |CreditCard| |record_type()| to indicate if the suggestion was for a local
@@ -59,9 +62,6 @@ extern const char kUKMRecordTypeMetricName[];
// |UkmEntry| for user editing text field. Metrics contain field's attributes.
extern const char kUKMTextFieldDidChangeEntryName[];
extern const char kUKMFieldTypeGroupMetricName[];
-extern const char kUKMHeuristicTypeMetricName[];
-extern const char kUKMServerTypeMetricName[];
-extern const char kUKMHtmlFieldTypeMetricName[];
extern const char kUKMHtmlFieldModeMetricName[];
extern const char kUKMIsAutofilledMetricName[];
extern const char kUKMIsEmptyMetricName[];
@@ -94,40 +94,49 @@ class AutofillMetrics {
};
enum CardUploadDecisionMetric {
- // All the required conditions were satisfied and the card upload prompt was
- // triggered.
- UPLOAD_OFFERED,
- // No CVC was detected. We don't know whether any addresses were available
- // nor whether we would have been able to get upload details.
- UPLOAD_NOT_OFFERED_NO_CVC,
- // A CVC was detected but no recently created or used address was available.
+ // All the required conditions were satisfied using either the form fields
+ // or we prompted the user to fix one or more conditions in the card upload
+ // prompt.
+ UPLOAD_OFFERED = 1 << 0,
+ // CVC field was not found in the form.
+ CVC_FIELD_NOT_FOUND = 1 << 1,
+ // CVC field was found, but field did not have a value.
+ CVC_VALUE_NOT_FOUND = 1 << 2,
+ // CVC field had a value, but it was not valid for the card network.
+ INVALID_CVC_VALUE = 1 << 3,
+ // A field had a syntactically valid CVC value, but it was in a field that
+ // was not heuristically determined as |CREDIT_CARD_VERIFICATION_CODE|.
+ // Set only if |CVC_FIELD_NOT_FOUND| is not set.
+ FOUND_POSSIBLE_CVC_VALUE_IN_NON_CVC_FIELD = 1 << 4,
+ // No address profile was available.
// We don't know whether we would have been able to get upload details.
- UPLOAD_NOT_OFFERED_NO_ADDRESS,
- // A CVC and one or more addresses were available but no name was found on
- // either the card or the adress(es). We don't know whether the address(es)
- // were otherwise valid nor whether we would have been able to get upload
- // details.
- UPLOAD_NOT_OFFERED_NO_NAME,
- // A CVC, multiple addresses, and a name were available but the adresses had
- // conflicting zip codes. We don't know whether we would have been able to
- // get upload details.
- UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS,
- // A CVC, one or more addresses, and a name were available but no zip code
- // was found on any of the adress(es). We don't know whether we would have
+ UPLOAD_NOT_OFFERED_NO_ADDRESS_PROFILE = 1 << 5,
+ // Found one or more address profiles but none were recently modified or
+ // recently used -i.e. not used in expected duration of a checkout flow.
+ // We don't know whether we would have been able to get upload details.
+ UPLOAD_NOT_OFFERED_NO_RECENTLY_USED_ADDRESS = 1 << 6,
+ // One or more recently used addresses were available but no zip code was
+ // found on any of the address(es). We don't know whether we would have
// been able to get upload details.
- UPLOAD_NOT_OFFERED_NO_ZIP_CODE,
- // A CVC, one or more valid addresses, and a name were available but the
- // request to Payments for upload details failed.
- UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED,
- // A CVC and one or more addresses were available but the names on the card
- // and/or the addresses didn't match. We don't know whether the address(es)
- // were otherwise valid nor whether we would have been able to get upload
- // details.
- UPLOAD_NOT_OFFERED_CONFLICTING_NAMES,
- // No CVC was detected, but valid addresses and names were. Upload is still
- // possible if the user manually enters CVC, so upload was offered.
- UPLOAD_OFFERED_NO_CVC,
- NUM_CARD_UPLOAD_DECISION_METRICS,
+ UPLOAD_NOT_OFFERED_NO_ZIP_CODE = 1 << 7,
+ // Multiple recently used addresses were available but the addresses had
+ // conflicting zip codes.We don't know whether we would have been able to
+ // get upload details.
+ UPLOAD_NOT_OFFERED_CONFLICTING_ZIPS = 1 << 8,
+ // One or more recently used addresses were available but no name was found
+ // on either the card or the address(es). We don't know whether the
+ // address(es) were otherwise valid nor whether we would have been able to
+ // get upload details.
+ UPLOAD_NOT_OFFERED_NO_NAME = 1 << 9,
+ // One or more recently used addresses were available but the names on the
+ // card and/or the addresses didn't match. We don't know whether the
+ // address(es) were otherwise valid nor whether we would have been able to
+ // get upload details.
+ UPLOAD_NOT_OFFERED_CONFLICTING_NAMES = 1 << 10,
+ // One or more valid addresses, and a name were available but the request to
+ // Payments for upload details failed.
+ UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED = 1 << 11,
+ // Update |kNumCardUploadDecisionMetrics| when adding new enum here.
};
enum DeveloperEngagementMetric {
@@ -311,33 +320,92 @@ class AutofillMetrics {
NUM_SAVE_CARD_PROMPT_METRICS,
};
- // Metrics measuring how well we predict field types. Exactly three such
- // metrics are logged for each fillable field in a submitted form: for
- // the heuristic prediction, for the crowd-sourced prediction, and for the
- // overall prediction.
+ // Metrics measuring how well we predict field types. These metric values are
+ // logged for each field in a submitted form for:
+ // - the heuristic prediction
+ // - the crowd-sourced (server) prediction
+ // - for the overall prediction
+ //
+ // For each of these prediction types, these metrics are also logged by
+ // actual and predicted field type.
enum FieldTypeQualityMetric {
- // The field was found to be of type T, but autofill made no prediction.
- TYPE_UNKNOWN = 0,
// The field was found to be of type T, which matches the predicted type.
- TYPE_MATCH,
- // The field was found to be of type T, autofill predicted some other type.
- TYPE_MISMATCH,
- // The field was left empty and autofil predicted that the field type would
- // be UNKNOWN.
- TYPE_MATCH_EMPTY,
- // The field was populated with data that did not match any part of the
- // user's profile (it's type could not be determined). Autofill predicted
- // the field's type would be UNKNOWN.
- TYPE_MATCH_UNKNOWN,
- // The field was left empty, autofill predicted the user would populate it
- // with autofillable data.
- TYPE_MISMATCH_EMPTY,
- // The field was populated with data that did not match any part of the
- // user's profile (it's type could not be determined). Autofill predicted
- // the user would populate it with autofillable data.
- TYPE_MISMATCH_UNKNOWN,
- // This must be the last value.
- NUM_FIELD_TYPE_QUALITY_METRICS,
+ // i.e. actual_type == predicted type == T
+ //
+ // This is captured as a type-specific log entry for T. Is is also captured
+ // as an aggregate (non-type-specific) log entry.
+ TRUE_POSITIVE = 0,
+
+ // The field type is AMBIGUOUS and autofill made no prediction.
+ // i.e. actual_type == AMBIGUOUS,predicted type == UNKNOWN|NO_SERVER_DATA.
+ //
+ // This is captured as an aggregate (non-type-specific) log entry. It is
+ // NOT captured by type-specific logging.
+ TRUE_NEGATIVE_AMBIGUOUS,
+
+ // The field type is UNKNOWN and autofill made no prediction.
+ // i.e. actual_type == UNKNOWN and predicted type == UNKNOWN|NO_SERVER_DATA.
+ //
+ // This is captured as an aggregate (non-type-specific) log entry. It is
+ // NOT captured by type-specific logging.
+ TRUE_NEGATIVE_UNKNOWN,
+
+ // The field type is EMPTY and autofill predicted UNKNOWN
+ // i.e. actual_type == EMPTY and predicted type == UNKNOWN|NO_SERVER_DATA.
+ //
+ // This is captured as an aggregate (non-type-specific) log entry. It is
+ // NOT captured by type-specific logging.
+ TRUE_NEGATIVE_EMPTY,
+
+ // Autofill predicted type T, but the field actually had a different type.
+ // i.e., actual_type == T, predicted_type = U, T != U,
+ // UNKNOWN not in (T,U).
+ //
+ // This is captured as a type-specific log entry for U. It is NOT captured
+ // as an aggregate (non-type-specific) entry as this would double count with
+ // FALSE_NEGATIVE_MISMATCH logging captured for T.
+ FALSE_POSITIVE_MISMATCH,
+
+ // Autofill predicted type T, but the field actually matched multiple
+ // pieces of autofill data, none of which are T.
+ // i.e., predicted_type == T, actual_type = {U, V, ...),
+ // T not in {U, V, ...}.
+ //
+ // This is captured as a type-specific log entry for T. It is also captured
+ // as an aggregate (non-type-specific) log entry.
+ FALSE_POSITIVE_AMBIGUOUS,
+
+ // The field type is UNKNOWN, but autofill predicted it to be of type T.
+ // i.e., actual_type == UNKNOWN, predicted_type = T, T != UNKNOWN
+ //
+ // This is captured as a type-specific log entry for T. Is is also captured
+ // as an aggregate (non-type-specific) log entry.
+ FALSE_POSITIVE_UNKNOWN,
+
+ // The field type is EMPTY, but autofill predicted it to be of type T.
+ // i.e., actual_type == EMPTY, predicted_type = T, T != UNKNOWN
+ //
+ // This is captured as a type-specific log entry for T. Is is also captured
+ // as an aggregate (non-type-specific) log entry.
+ FALSE_POSITIVE_EMPTY,
+
+ // The field is of type T, but autofill did not make a type prediction.
+ // i.e., actual_type == T, predicted_type = UNKNOWN, T != UNKNOWN.
+ //
+ // This is captured as a type-specific log entry for T. Is is also captured
+ // as an aggregate (non-type-specific) log entry.
+ FALSE_NEGATIVE_UNKNOWN,
+
+ // The field is of type T, but autofill predicted it to be of type U.
+ // i.e., actual_type == T, predicted_type = U, T != U,
+ // UNKNOWN not in (T,U).
+ //
+ // This is captured as a type-specific log entry for T. Is is also captured
+ // as an aggregate (non-type-specific) log entry.
+ FALSE_NEGATIVE_MISMATCH,
+
+ // This must be last.
+ NUM_FIELD_TYPE_QUALITY_METRICS
};
enum QualityMetricType {
@@ -614,15 +682,15 @@ class AutofillMetrics {
// Utility to log URL keyed form interaction events.
class FormInteractionsUkmLogger {
public:
- explicit FormInteractionsUkmLogger(ukm::UkmService* ukm_service);
+ explicit FormInteractionsUkmLogger(ukm::UkmRecorder* ukm_recorder);
const GURL& url() const { return url_; }
- void OnFormsLoaded(const GURL& url);
+ void OnFormsParsed(const GURL& url);
void LogInteractedWithForm(bool is_for_credit_card,
size_t local_record_type_count,
size_t server_record_type_count);
- void LogSuggestionsShown();
+ void LogSuggestionsShown(const AutofillField& field);
void LogSelectedMaskedServerCard();
void LogDidFillSuggestion(int record_type);
void LogTextFieldDidChange(const AutofillField& field);
@@ -635,22 +703,27 @@ class AutofillMetrics {
private:
bool CanLog() const;
- int64_t MillisecondsSinceFormLoaded() const;
+ int64_t MillisecondsSinceFormParsed() const;
void GetNewSourceID();
- ukm::UkmService* ukm_service_; // Weak reference.
- int32_t source_id_ = -1;
+ ukm::UkmRecorder* ukm_recorder_; // Weak reference.
+ ukm::SourceId source_id_ = -1;
GURL url_;
- base::TimeTicks form_loaded_timestamp_;
+ base::TimeTicks form_parsed_timestamp_;
};
- static void LogCardUploadDecisionMetric(CardUploadDecisionMetric metric);
- static void LogCreditCardInfoBarMetric(InfoBarMetric metric,
- bool is_uploading);
+ // |upload_decision_metrics| is a bitmask of |CardUploadDecisionMetric|.
+ static void LogCardUploadDecisionMetrics(int upload_decision_metrics);
+ static void LogCreditCardInfoBarMetric(
+ InfoBarMetric metric,
+ bool is_uploading,
+ int previous_save_credit_card_prompt_user_decision);
static void LogCreditCardFillingInfoBarMetric(InfoBarMetric metric);
- static void LogSaveCardPromptMetric(SaveCardPromptMetric metric,
- bool is_uploading,
- bool is_reshow);
+ static void LogSaveCardPromptMetric(
+ SaveCardPromptMetric metric,
+ bool is_uploading,
+ bool is_reshow,
+ int previous_save_credit_card_prompt_user_decision);
static void LogScanCreditCardPromptMetric(ScanCreditCardPromptMetric metric);
// Should be called when credit card scan is finished. |duration| should be
@@ -662,15 +735,18 @@ class AutofillMetrics {
static void LogDeveloperEngagementMetric(DeveloperEngagementMetric metric);
- static void LogHeuristicTypePrediction(FieldTypeQualityMetric metric,
- ServerFieldType field_type,
- QualityMetricType metric_type);
- static void LogOverallTypePrediction(FieldTypeQualityMetric metric,
- ServerFieldType field_type,
- QualityMetricType metric_type);
- static void LogServerTypePrediction(FieldTypeQualityMetric metric,
- ServerFieldType field_type,
- QualityMetricType metric_type);
+ static void LogHeuristicPredictionQualityMetrics(
+ const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type,
+ QualityMetricType metric_type);
+ static void LogServerPredictionQualityMetrics(
+ const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type,
+ QualityMetricType metric_type);
+ static void LogOverallPredictionQualityMetrics(
+ const ServerFieldTypeSet& possible_types,
+ ServerFieldType predicted_type,
+ QualityMetricType metric_type);
static void LogServerQueryMetric(ServerQueryMetric metric);
@@ -744,6 +820,11 @@ class AutofillMetrics {
static void LogNumberOfProfilesAtAutofillableFormSubmission(
size_t num_profiles);
+ // Log whether user modified an address profile shortly before submitting
+ // credit card form.
+ static void LogHasModifiedProfileOnCreditCardFormSubmission(
+ bool has_modified_profile);
+
// Log the number of Autofill suggestions presented to the user when filling a
// form.
static void LogAddressSuggestionsCount(size_t num_suggestions);
@@ -799,23 +880,22 @@ class AutofillMetrics {
// suggestion to show an explanation of the warning.
static void LogShowedHttpNotSecureExplanation();
- // Logs the card upload decision ukm based on the specified |url| and
- // |upload_decision|.
- static void LogCardUploadDecisionUkm(
- ukm::UkmService* ukm_service,
- const GURL& url,
- AutofillMetrics::CardUploadDecisionMetric upload_decision);
+ // Logs the card upload decisions ukm for the specified |url|.
+ // |upload_decision_metrics| is a bitmask of |CardUploadDecisionMetric|.
+ static void LogCardUploadDecisionsUkm(ukm::UkmRecorder* ukm_recorder,
+ const GURL& url,
+ int upload_decision_metrics);
// Logs the developer engagement ukm for the specified |url| and autofill
- // fields in the form structure.
- static void LogDeveloperEngagementUkm(
- ukm::UkmService* ukm_service,
- const GURL& url,
- std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics);
+ // fields in the form structure. |developer_engagement_metrics| is a bitmask
+ // of |AutofillMetrics::DeveloperEngagementMetric|.
+ static void LogDeveloperEngagementUkm(ukm::UkmRecorder* ukm_recorder,
+ const GURL& url,
+ int developer_engagement_metrics);
// Logs the the |ukm_entry_name| with the specified |url| and the specified
// |metrics|. Returns whether the ukm was sucessfully logged.
- static bool LogUkm(ukm::UkmService* ukm_service,
+ static bool LogUkm(ukm::UkmRecorder* ukm_recorder,
const GURL& url,
const std::string& ukm_entry_name,
const std::vector<std::pair<const char*, int>>& metrics);
@@ -843,7 +923,7 @@ class AutofillMetrics {
void OnDidPollSuggestions(const FormFieldData& field);
- void OnDidShowSuggestions();
+ void OnDidShowSuggestions(const AutofillField& field);
void OnDidSelectMaskedServerCardSuggestion();
@@ -881,6 +961,8 @@ class AutofillMetrics {
};
private:
+ static const int kNumCardUploadDecisionMetrics = 12;
+
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 3372ee37884..65c3b283f59 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -34,15 +34,13 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
-#include "components/metrics/proto/ukm/entry.pb.h"
#include "components/prefs/pref_service.h"
#include "components/rappor/test_rappor_service.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/signin/core/common/signin_pref_names.h"
-#include "components/ukm/test_ukm_service.h"
-#include "components/ukm/ukm_entry.h"
+#include "components/ukm/test_ukm_recorder.h"
#include "components/ukm/ukm_source.h"
#include "components/webdata/common/web_data_results.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -170,14 +168,14 @@ class TestPersonalDataManager : public PersonalDataManager {
std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>(
"10000000-0000-0000-0000-000000000001", std::string());
test::SetCreditCardInfo(credit_card.get(), nullptr, "4111111111111111",
- "12", "24");
+ "12", "24", "1");
local_credit_cards_.push_back(std::move(credit_card));
}
if (include_masked_server_credit_card) {
std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>(
CreditCard::MASKED_SERVER_CARD, "server_id");
credit_card->set_guid("10000000-0000-0000-0000-000000000002");
- credit_card->SetTypeForMaskedCard(kDiscoverCard);
+ credit_card->SetNetworkForMaskedCard(kDiscoverCard);
server_credit_cards_.push_back(std::move(credit_card));
}
if (include_full_server_credit_card) {
@@ -191,6 +189,19 @@ class TestPersonalDataManager : public PersonalDataManager {
bool IsAutofillEnabled() const override { return autofill_enabled_; }
+ void CreateAmbiguousProfiles() {
+ web_profiles_.clear();
+ CreateTestAutofillProfiles(&web_profiles_);
+
+ auto profile = base::MakeUnique<AutofillProfile>();
+ test::SetProfileInfo(profile.get(), "John", "Decca", "Public",
+ "john@gmail.com", "Company", "123 Main St.", "unit 7",
+ "Springfield", "Texas", "79401", "US", "2345678901");
+ profile->set_guid("00000000-0000-0000-0000-000000000003");
+ web_profiles_.push_back(std::move(profile));
+ Refresh();
+ }
+
private:
void CreateTestAutofillProfiles(
std::vector<std::unique_ptr<AutofillProfile>>* profiles) {
@@ -267,7 +278,7 @@ class TestAutofillManager : public AutofillManager {
form_structure->SetFieldTypes(heuristic_types, server_types);
form_structures()->push_back(std::move(form_structure));
- form_interactions_ukm_logger()->OnFormsLoaded(form.origin);
+ form_interactions_ukm_logger()->OnFormsParsed(form.origin);
}
// Calls AutofillManager::OnWillSubmitForm and waits for it to complete.
@@ -310,92 +321,77 @@ class TestAutofillManager : public AutofillManager {
DISALLOW_COPY_AND_ASSIGN(TestAutofillManager);
};
-// Finds the specified UKM metric by |name| in the specified UKM |metrics|.
-const ukm::Entry_Metric* FindMetric(
- const char* name,
- const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) {
- for (const auto& metric : metrics) {
- if (metric.metric_hash() == base::HashMetricName(name))
- return &metric;
- }
- return nullptr;
-}
-
MATCHER(CompareMetrics, "") {
- const ukm::Entry_Metric& lhs = ::testing::get<0>(arg);
+ const ukm::mojom::UkmMetric* lhs = ::testing::get<0>(arg).get();
const std::pair<const char*, int64_t>& rhs = ::testing::get<1>(arg);
- return lhs.metric_hash() == base::HashMetricName(rhs.first) &&
- lhs.value() == rhs.second;
+ return lhs->metric_hash == base::HashMetricName(rhs.first) &&
+ lhs->value == rhs.second;
}
void VerifyDeveloperEngagementUkm(
const FormData& form,
- const ukm::TestUkmService* ukm_service,
+ const ukm::TestUkmRecorder* ukm_recorder,
const std::vector<int64_t>& expected_metric_values) {
- const ukm::UkmEntry* entry = ukm_service->GetEntryForEntryName(
+ const ukm::mojom::UkmEntry* entry = ukm_recorder->GetEntryForEntryName(
internal::kUKMDeveloperEngagementEntryName);
ASSERT_NE(nullptr, entry);
- ukm::Entry entry_proto;
- entry->PopulateProto(&entry_proto);
-
const ukm::UkmSource* source =
- ukm_service->GetSourceForSourceId(entry_proto.source_id());
+ ukm_recorder->GetSourceForSourceId(entry->source_id);
ASSERT_NE(nullptr, source);
EXPECT_EQ(form.origin, source->url());
- std::vector<std::pair<const char*, int64_t>> expected_metrics;
+ int expected_metric_value = 0;
for (const auto it : expected_metric_values)
- expected_metrics.push_back(
- {internal::kUKMDeveloperEngagementMetricName, it});
+ expected_metric_value |= 1 << it;
- EXPECT_THAT(entry_proto.metrics(),
+ const std::vector<std::pair<const char*, int64_t>> expected_metrics{
+ {internal::kUKMDeveloperEngagementMetricName, expected_metric_value}};
+
+ EXPECT_THAT(entry->metrics,
UnorderedPointwise(CompareMetrics(), expected_metrics));
}
-MATCHER(CompareMetricsIgnoringMillisecondsSinceFormLoaded, "") {
- const ukm::Entry_Metric& lhs = ::testing::get<0>(arg);
+MATCHER(CompareMetricsIgnoringMillisecondsSinceFormParsed, "") {
+ const ukm::mojom::UkmMetric* lhs = ::testing::get<0>(arg).get();
const std::pair<const char*, int64_t>& rhs = ::testing::get<1>(arg);
- return lhs.metric_hash() == base::HashMetricName(rhs.first) &&
- (lhs.value() == rhs.second ||
- (lhs.value() > 0 &&
- rhs.first == internal::kUKMMillisecondsSinceFormLoadedMetricName));
+ return lhs->metric_hash == base::HashMetricName(rhs.first) &&
+ (lhs->value == rhs.second ||
+ (lhs->value > 0 &&
+ rhs.first == internal::kUKMMillisecondsSinceFormParsedMetricName));
}
void VerifyFormInteractionUkm(
const FormData& form,
- const ukm::TestUkmService* ukm_service,
+ const ukm::TestUkmRecorder* ukm_recorder,
const char* event_name,
const std::vector<std::vector<std::pair<const char*, int64_t>>>&
expected_metrics) {
size_t expected_metrics_index = 0;
- for (size_t i = 0; i < ukm_service->entries_count(); ++i) {
- const ukm::UkmEntry* entry = ukm_service->GetEntry(i);
- if (entry->event_hash() != base::HashMetricName(event_name))
+ for (size_t i = 0; i < ukm_recorder->entries_count(); ++i) {
+ const ukm::mojom::UkmEntry* entry = ukm_recorder->GetEntry(i);
+ if (entry->event_hash != base::HashMetricName(event_name))
continue;
- ukm::Entry entry_proto;
- entry->PopulateProto(&entry_proto);
-
const ukm::UkmSource* source =
- ukm_service->GetSourceForSourceId(entry_proto.source_id());
+ ukm_recorder->GetSourceForSourceId(entry->source_id);
ASSERT_NE(nullptr, source);
EXPECT_EQ(form.origin, source->url());
ASSERT_LT(expected_metrics_index, expected_metrics.size());
EXPECT_THAT(
- entry_proto.metrics(),
- UnorderedPointwise(CompareMetricsIgnoringMillisecondsSinceFormLoaded(),
+ entry->metrics,
+ UnorderedPointwise(CompareMetricsIgnoringMillisecondsSinceFormParsed(),
expected_metrics[expected_metrics_index++]));
}
}
void VerifySubmitFormUkm(const FormData& form,
- const ukm::TestUkmService* ukm_service,
+ const ukm::TestUkmRecorder* ukm_recorder,
AutofillMetrics::AutofillFormSubmittedState state) {
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMFormSubmittedEntryName,
+ form, ukm_recorder, internal::kUKMFormSubmittedEntryName,
{{{internal::kUKMAutofillFormSubmittedStateMetricName, state},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
}
} // namespace
@@ -413,9 +409,9 @@ class AutofillMetricsTest : public testing::Test {
protected:
void EnableWalletSync();
- void EnableUkmLogging();
base::test::ScopedTaskEnvironment scoped_task_environment_;
+ ukm::TestUkmRecorder test_ukm_recorder_;
TestAutofillClient autofill_client_;
std::unique_ptr<AccountTrackerService> account_tracker_;
std::unique_ptr<FakeSigninManagerBase> signin_manager_;
@@ -475,17 +471,13 @@ void AutofillMetricsTest::TearDown() {
account_tracker_.reset();
signin_client_.reset();
test::ReenableSystemServices();
- autofill_client_.GetTestUkmService()->Purge();
+ test_ukm_recorder_.Purge();
}
void AutofillMetricsTest::EnableWalletSync() {
signin_manager_->SetAuthenticatedAccountInfo("12345", "syncuser@example.com");
}
-void AutofillMetricsTest::EnableUkmLogging() {
- scoped_feature_list_.InitAndEnableFeature(kAutofillUkmLogging);
-}
-
// Test that we log quality metrics appropriately.
TEST_F(AutofillMetricsTest, QualityMetrics) {
// Set up our form data.
@@ -543,111 +535,259 @@ TEST_F(AutofillMetricsTest, QualityMetrics) {
autofill_manager_->SubmitForm(form, TimeTicks::Now());
// Heuristic predictions.
- // Unknown:
- histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType",
- AutofillMetrics::TYPE_MATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(PHONE_HOME_CITY_AND_NUMBER,
- AutofillMetrics::TYPE_MATCH),
- 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH),
- 1);
-
- // Server predictions:
- // Unknown:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType",
- AutofillMetrics::TYPE_MATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_MATCH),
- 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1);
+ {
+ std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate.Heuristic";
+ std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType.Heuristic";
- // Overall predictions:
- // Unknown:
- histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType",
- AutofillMetrics::TYPE_MATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_MATCH),
- 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1);
+ // Unknown:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
+ 1);
+ // Match:
+ histogram_tester.ExpectBucketCount(aggregate_histogram,
+ AutofillMetrics::TRUE_POSITIVE, 2);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TRUE_POSITIVE), 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_CITY_AND_NUMBER,
+ AutofillMetrics::TRUE_POSITIVE),
+ 1);
+ // Mismatch:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_MISMATCH, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(EMAIL_ADDRESS,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_NUMBER,
+ AutofillMetrics::FALSE_POSITIVE_MISMATCH),
+ 1);
+ // False Positive Unknown:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_NUMBER,
+ AutofillMetrics::FALSE_POSITIVE_UNKNOWN),
+ 1);
+ // False Positive Empty:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_EMPTY, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FULL,
+ AutofillMetrics::FALSE_POSITIVE_EMPTY),
+ 1);
+
+ // Sanity Check:
+ histogram_tester.ExpectTotalCount(aggregate_histogram, 6);
+ histogram_tester.ExpectTotalCount(by_field_type_histogram, 7);
+ }
+
+ // Server overrides heuristic so Overall and Server are the same predictions
+ // (as there were no test fields where server == NO_SERVER_DATA and heuristic
+ // != UNKNOWN_TYPE).
+ for (const std::string source : {"Server", "Overall"}) {
+ std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate." + source;
+ std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType." + source;
+
+ // Unknown:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
+ 1);
+ // Match:
+ histogram_tester.ExpectBucketCount(aggregate_histogram,
+ AutofillMetrics::TRUE_POSITIVE, 2);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TRUE_POSITIVE),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
+ AutofillMetrics::TRUE_POSITIVE),
+ 1);
+ // Mismatch:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_MISMATCH, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FULL,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FIRST,
+ AutofillMetrics::FALSE_POSITIVE_MISMATCH),
+ 1);
+
+ // False Positive Unknown:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(EMAIL_ADDRESS,
+ AutofillMetrics::FALSE_POSITIVE_UNKNOWN),
+ 1);
+ // False Positive Empty:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_EMPTY, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FIRST,
+ AutofillMetrics::FALSE_POSITIVE_EMPTY),
+ 1);
+
+ // Sanity Check:
+ histogram_tester.ExpectTotalCount(aggregate_histogram, 6);
+ histogram_tester.ExpectTotalCount(by_field_type_histogram, 7);
+ }
}
// Tests the true negatives (empty + no prediction and unknown + no prediction)
// and false positives (empty + bad prediction and unknown + bad prediction)
// are counted correctly.
-struct UnrecognizedOrEmptyFieldsCase {
+struct QualityMetricsTestCase {
+ const ServerFieldType predicted_field_type;
const ServerFieldType actual_field_type;
- const bool make_prediction;
- const AutofillMetrics::FieldTypeQualityMetric metric_to_test;
};
-class UnrecognizedOrEmptyFieldsTest
+class QualityMetricsTest
: public AutofillMetricsTest,
- public testing::WithParamInterface<UnrecognizedOrEmptyFieldsCase> {};
+ public testing::WithParamInterface<QualityMetricsTestCase> {
+ public:
+ const char* ValueForType(ServerFieldType type) {
+ switch (type) {
+ case EMPTY_TYPE:
+ return "";
+ case UNKNOWN_TYPE:
+ return "unknown";
+ case COMPANY_NAME:
+ return "RCA";
+ case NAME_FIRST:
+ return "Elvis";
+ case NAME_MIDDLE:
+ return "Aaron";
+ case NAME_LAST:
+ return "Presley";
+ case NAME_FULL:
+ return "Elvis Aaron Presley";
+ case EMAIL_ADDRESS:
+ return "buddy@gmail.com";
+ case PHONE_HOME_NUMBER:
+ case PHONE_HOME_WHOLE_NUMBER:
+ case PHONE_HOME_CITY_AND_NUMBER:
+ return "2345678901";
+ case ADDRESS_HOME_STREET_ADDRESS:
+ return "123 Apple St.\nunit 6";
+ case ADDRESS_HOME_LINE1:
+ return "123 Apple St.";
+ case ADDRESS_HOME_LINE2:
+ return "unit 6";
+ case ADDRESS_HOME_CITY:
+ return "Lubbock";
+ case ADDRESS_HOME_STATE:
+ return "Texas";
+ case ADDRESS_HOME_ZIP:
+ return "79401";
+ case ADDRESS_HOME_COUNTRY:
+ return "US";
+ case AMBIGUOUS_TYPE:
+ // This occurs as both a company name and a middle name once ambiguous
+ // profiles are created.
+ personal_data_->CreateAmbiguousProfiles();
+ return "Decca";
+
+ default:
+ NOTREACHED(); // Fall through
+ return "unexpected!";
+ }
+ }
+
+ bool IsExampleOf(AutofillMetrics::FieldTypeQualityMetric metric,
+ ServerFieldType predicted_type,
+ ServerFieldType actual_type) {
+ switch (metric) {
+ case AutofillMetrics::TRUE_POSITIVE:
+ return unknown_equivalent_types_.count(actual_type) == 0 &&
+ predicted_type == actual_type;
+
+ case AutofillMetrics::TRUE_NEGATIVE_AMBIGUOUS:
+ return actual_type == AMBIGUOUS_TYPE && predicted_type == UNKNOWN_TYPE;
+
+ case AutofillMetrics::TRUE_NEGATIVE_UNKNOWN:
+ return actual_type == UNKNOWN_TYPE && predicted_type == UNKNOWN_TYPE;
+
+ case AutofillMetrics::TRUE_NEGATIVE_EMPTY:
+ return actual_type == EMPTY_TYPE && predicted_type == UNKNOWN_TYPE;
+
+ case AutofillMetrics::FALSE_POSITIVE_AMBIGUOUS:
+ return actual_type == AMBIGUOUS_TYPE && predicted_type != UNKNOWN_TYPE;
+
+ case AutofillMetrics::FALSE_POSITIVE_UNKNOWN:
+ return actual_type == UNKNOWN_TYPE && predicted_type != UNKNOWN_TYPE;
+
+ case AutofillMetrics::FALSE_POSITIVE_EMPTY:
+ return actual_type == EMPTY_TYPE && predicted_type != UNKNOWN_TYPE;
+
+ // False negative mismatch and false positive mismatch trigger on the same
+ // conditions:
+ // - False positive prediction of predicted type
+ // - False negative prediction of actual type
+ case AutofillMetrics::FALSE_POSITIVE_MISMATCH:
+ case AutofillMetrics::FALSE_NEGATIVE_MISMATCH:
+ return unknown_equivalent_types_.count(actual_type) == 0 &&
+ actual_type != predicted_type && predicted_type != UNKNOWN_TYPE;
-TEST_P(UnrecognizedOrEmptyFieldsTest, QualityMetrics) {
+ case AutofillMetrics::FALSE_NEGATIVE_UNKNOWN:
+ return unknown_equivalent_types_.count(actual_type) == 0 &&
+ actual_type != predicted_type && predicted_type == UNKNOWN_TYPE;
+
+ default:
+ NOTREACHED();
+ }
+ return false;
+ }
+
+ static int FieldTypeCross(ServerFieldType predicted_type,
+ ServerFieldType actual_type) {
+ EXPECT_LE(predicted_type, UINT16_MAX);
+ EXPECT_LE(actual_type, UINT16_MAX);
+ return (predicted_type << 16) | actual_type;
+ }
+
+ const ServerFieldTypeSet unknown_equivalent_types_{UNKNOWN_TYPE, EMPTY_TYPE,
+ AMBIGUOUS_TYPE};
+};
+
+TEST_P(QualityMetricsTest, Classification) {
+ const std::vector<std::string> prediction_sources{"Heuristic", "Server",
+ "Overall"};
// Setup the test parameters.
- const ServerFieldType actual_field_type = GetParam().actual_field_type;
- const ServerFieldType heuristic_type =
- GetParam().make_prediction ? EMAIL_ADDRESS : UNKNOWN_TYPE;
- const ServerFieldType server_type =
- GetParam().make_prediction ? EMAIL_ADDRESS : NO_SERVER_DATA;
- const AutofillMetrics::FieldTypeQualityMetric metric_to_test =
- GetParam().metric_to_test;
+ ServerFieldType actual_field_type = GetParam().actual_field_type;
+ ServerFieldType predicted_type = GetParam().predicted_field_type;
+
+ VLOG(2) << "Test Case = Predicted: "
+ << AutofillType(predicted_type).ToString() << "; "
+ << "Actual: " << AutofillType(actual_field_type).ToString();
// Set up our form data.
FormData form;
@@ -659,27 +799,26 @@ TEST_P(UnrecognizedOrEmptyFieldsTest, QualityMetrics) {
AutofillField field;
// Add a first name field, that is predicted correctly.
- test::CreateTestFormField("first", "first", "Elvis", "text", &field);
- field.set_possible_types({NAME_FIRST});
+ test::CreateTestFormField("first", "first", ValueForType(NAME_FIRST), "text",
+ &field);
form.fields.push_back(field);
heuristic_types.push_back(NAME_FIRST);
server_types.push_back(NAME_FIRST);
// Add a last name field, that is predicted correctly.
- test::CreateTestFormField("last", "last", "Presley", "test", &field);
- field.set_possible_types({NAME_LAST});
+ test::CreateTestFormField("last", "last", ValueForType(NAME_LAST), "test",
+ &field);
form.fields.push_back(field);
heuristic_types.push_back(NAME_LAST);
server_types.push_back(NAME_LAST);
// Add an empty or unknown field, that is predicted as per the test params.
test::CreateTestFormField("Unknown", "Unknown",
- (actual_field_type == EMPTY_TYPE ? "" : "unknown"),
- "text", &field);
- field.set_possible_types({actual_field_type});
+ ValueForType(actual_field_type), "text", &field);
form.fields.push_back(field);
- heuristic_types.push_back(heuristic_type);
- server_types.push_back(server_type);
+ heuristic_types.push_back(predicted_type);
+ server_types.push_back(predicted_type == UNKNOWN_TYPE ? NO_SERVER_DATA
+ : predicted_type);
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
@@ -688,65 +827,122 @@ TEST_P(UnrecognizedOrEmptyFieldsTest, QualityMetrics) {
base::HistogramTester histogram_tester;
autofill_manager_->SubmitForm(form, TimeTicks::Now());
- // Validate the histogram counter values.
+ // Resolve any field type ambiguity.
+ if (actual_field_type == AMBIGUOUS_TYPE) {
+ if (predicted_type == COMPANY_NAME || predicted_type == NAME_MIDDLE)
+ actual_field_type = predicted_type;
+ }
+
+ // Validate the total samples and the crossed (predicted-to-actual) samples.
+ for (const auto& source : prediction_sources) {
+ const std::string crossed_histogram = "Autofill.FieldPrediction." + source;
+ const std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate." + source;
+ const std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType." + source;
+
+ // Sanity Check:
+ histogram_tester.ExpectTotalCount(crossed_histogram, 3);
+ histogram_tester.ExpectTotalCount(aggregate_histogram, 3);
+ histogram_tester.ExpectTotalCount(
+ by_field_type_histogram,
+ 2 +
+ (predicted_type != UNKNOWN_TYPE &&
+ predicted_type != actual_field_type) +
+ (unknown_equivalent_types_.count(actual_field_type) == 0));
+
+ // The Crossed Histogram:
+ histogram_tester.ExpectBucketCount(
+ crossed_histogram, FieldTypeCross(NAME_FIRST, NAME_FIRST), 1);
+ histogram_tester.ExpectBucketCount(crossed_histogram,
+ FieldTypeCross(NAME_LAST, NAME_LAST), 1);
+ histogram_tester.ExpectBucketCount(
+ crossed_histogram,
+ FieldTypeCross((source == "Server" && predicted_type == UNKNOWN_TYPE
+ ? NO_SERVER_DATA
+ : predicted_type),
+ actual_field_type),
+ 1);
+ }
+
+ // Validate the individual histogram counter values.
for (int i = 0; i < AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS; ++i) {
// The metric enum value we're currently examining.
auto metric = static_cast<AutofillMetrics::FieldTypeQualityMetric>(i);
- // For the overall metric counts...
- // If the current metric is the metric we're testing, then we expect its
- // count to be 1. Otherwise, the metric's count should be zero (0) except
- // for the TYPE_MATCH metric which should be 2 (because of the matching
- // first and last name fields)
- int overall_expected_count =
- (metric == metric_to_test)
- ? 1
- : ((metric == AutofillMetrics::TYPE_MATCH) ? 2 : 0);
-
- histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType", metric,
- overall_expected_count);
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType", metric,
- overall_expected_count);
- histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType", metric,
- overall_expected_count);
-
- // For the ByFieldType metric counts...
- // We only examine the counter for the field_type being tested. If the
- // current metric is the metric we're testing, then we expect its
- // count to be 1 otherwise it should be 0.
- int field_type_expected_count = (metric == metric_to_test) ? 1 : 0;
-
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(actual_field_type, metric),
- field_type_expected_count);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(actual_field_type, metric),
- field_type_expected_count);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(actual_field_type, metric),
- field_type_expected_count);
+ // The type specific expected count is 1 if (predicted, actual) is an
+ // example
+ int basic_expected_count =
+ IsExampleOf(metric, predicted_type, actual_field_type) ? 1 : 0;
+
+ // For aggregate metrics don't capture aggregate FALSE_POSITIVE_MISMATCH.
+ // Note there are two true positive values (first and last name) hard-
+ // coded into the test.
+ int aggregate_expected_count =
+ (metric == AutofillMetrics::TRUE_POSITIVE ? 2 : 0) +
+ (metric == AutofillMetrics::FALSE_POSITIVE_MISMATCH
+ ? 0
+ : basic_expected_count);
+
+ // If this test exercises the ambiguous middle name match, then validation
+ // of the name-specific metrics must include the true-positives created by
+ // the first and last name fields.
+ if (metric == AutofillMetrics::TRUE_POSITIVE &&
+ predicted_type == NAME_MIDDLE && actual_field_type == NAME_MIDDLE) {
+ basic_expected_count += 2;
+ }
+
+ // For metrics keyed to the actual field type, we don't capture unknown,
+ // empty or ambiguous and we don't capture false positive mismatches.
+ int expected_count_for_actual_type =
+ (unknown_equivalent_types_.count(actual_field_type) == 0 &&
+ metric != AutofillMetrics::FALSE_POSITIVE_MISMATCH)
+ ? basic_expected_count
+ : 0;
+
+ // For metrics keyed to the predicted field type, we don't capture unknown
+ // (empty is not a predictable value) and we don't capture false negative
+ // mismatches.
+ int expected_count_for_predicted_type =
+ (predicted_type != UNKNOWN_TYPE &&
+ metric != AutofillMetrics::FALSE_NEGATIVE_MISMATCH)
+ ? basic_expected_count
+ : 0;
+
+ for (const auto& source : prediction_sources) {
+ std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate." + source;
+ std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType." + source;
+ histogram_tester.ExpectBucketCount(aggregate_histogram, metric,
+ aggregate_expected_count);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(actual_field_type, metric),
+ expected_count_for_actual_type);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(predicted_type, metric),
+ expected_count_for_predicted_type);
+ }
}
}
INSTANTIATE_TEST_CASE_P(
AutofillMetricsTest,
- UnrecognizedOrEmptyFieldsTest,
- testing::Values(
- UnrecognizedOrEmptyFieldsCase{EMPTY_TYPE,
- /* make_prediction = */ false,
- AutofillMetrics::TYPE_MATCH_EMPTY},
- UnrecognizedOrEmptyFieldsCase{UNKNOWN_TYPE,
- /* make_prediction = */ false,
- AutofillMetrics::TYPE_MATCH_UNKNOWN},
- UnrecognizedOrEmptyFieldsCase{EMPTY_TYPE,
- /* make_prediction = */ true,
- AutofillMetrics::TYPE_MISMATCH_EMPTY},
- UnrecognizedOrEmptyFieldsCase{UNKNOWN_TYPE,
- /* make_prediction = */ true,
- AutofillMetrics::TYPE_MISMATCH_UNKNOWN}));
+ QualityMetricsTest,
+ testing::Values(QualityMetricsTestCase{UNKNOWN_TYPE, EMPTY_TYPE},
+ QualityMetricsTestCase{UNKNOWN_TYPE, UNKNOWN_TYPE},
+ QualityMetricsTestCase{UNKNOWN_TYPE, AMBIGUOUS_TYPE},
+ QualityMetricsTestCase{UNKNOWN_TYPE, EMAIL_ADDRESS},
+ QualityMetricsTestCase{EMAIL_ADDRESS, EMPTY_TYPE},
+ QualityMetricsTestCase{EMAIL_ADDRESS, UNKNOWN_TYPE},
+ QualityMetricsTestCase{EMAIL_ADDRESS, AMBIGUOUS_TYPE},
+ QualityMetricsTestCase{EMAIL_ADDRESS, EMAIL_ADDRESS},
+ QualityMetricsTestCase{EMAIL_ADDRESS, COMPANY_NAME},
+ QualityMetricsTestCase{COMPANY_NAME, EMAIL_ADDRESS},
+ QualityMetricsTestCase{NAME_MIDDLE, AMBIGUOUS_TYPE},
+ QualityMetricsTestCase{COMPANY_NAME, AMBIGUOUS_TYPE}));
// Ensures that metrics that measure timing some important Autofill functions
// actually are recorded and retrieved.
@@ -852,92 +1048,127 @@ TEST_F(AutofillMetricsTest, QualityMetrics_NoSubmission) {
autofill_manager_->RunRunLoop();
// Heuristic predictions.
- // Unknown:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.NoSubmission",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.NoSubmission",
- AutofillMetrics::TYPE_MATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_MATCH),
- 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.NoSubmission",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH),
- 1);
-
- // Server predictions:
- // Unknown:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType.NoSubmission",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType.NoSubmission",
- AutofillMetrics::TYPE_MATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_MATCH),
- 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType.NoSubmission",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1);
+ {
+ std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate.Heuristic.NoSubmission";
+ std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType.Heuristic.NoSubmission";
+ // False Negative:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
+ 1);
+ // Match:
+ histogram_tester.ExpectBucketCount(aggregate_histogram,
+ AutofillMetrics::TRUE_POSITIVE, 2);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TRUE_POSITIVE), 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
+ AutofillMetrics::TRUE_POSITIVE),
+ 1);
+ // Mismatch:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_MISMATCH, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(EMAIL_ADDRESS,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_NUMBER,
+ AutofillMetrics::FALSE_POSITIVE_MISMATCH),
+ 1);
+ // False Positives:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_EMPTY, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FULL,
+ AutofillMetrics::FALSE_POSITIVE_EMPTY),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_NUMBER,
+ AutofillMetrics::FALSE_POSITIVE_UNKNOWN),
+ 1);
- // Overall predictions:
- // Unknown:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.NoSubmission",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.NoSubmission",
- AutofillMetrics::TYPE_MATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_MATCH),
- 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.NoSubmission",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType.NoSubmission",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1);
+ // Sanity Check:
+ histogram_tester.ExpectTotalCount(aggregate_histogram, 6);
+ histogram_tester.ExpectTotalCount(by_field_type_histogram, 7);
+ }
+
+ // Server predictions override heuristics, so server and overall will be the
+ // same.
+ for (const std::string source : {"Server", "Overall"}) {
+ std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate." + source + ".NoSubmission";
+ std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType." + source +
+ ".NoSubmission";
+
+ // Unknown.
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
+ 1);
+ // Match:
+ histogram_tester.ExpectBucketCount(aggregate_histogram,
+ AutofillMetrics::TRUE_POSITIVE, 2);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TRUE_POSITIVE),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
+ AutofillMetrics::TRUE_POSITIVE),
+ 1);
+ // Mismatch:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_MISMATCH, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FULL,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FIRST,
+ AutofillMetrics::FALSE_POSITIVE_MISMATCH),
+ 1);
+
+ // False Positives:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_EMPTY, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FIRST,
+ AutofillMetrics::FALSE_POSITIVE_EMPTY),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_POSITIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(EMAIL_ADDRESS,
+ AutofillMetrics::FALSE_POSITIVE_UNKNOWN),
+ 1);
+
+ // Sanity Check:
+ histogram_tester.ExpectTotalCount(aggregate_histogram, 6);
+ histogram_tester.ExpectTotalCount(by_field_type_histogram, 7);
+ }
}
// Test that we log quality metrics for heuristics and server predictions based
@@ -972,7 +1203,7 @@ TEST_F(AutofillMetricsTest, QualityMetrics_BasedOnAutocomplete) {
std::unique_ptr<TestFormStructure> form_structure =
base::MakeUnique<TestFormStructure>(form);
TestFormStructure* form_structure_ptr = form_structure.get();
- form_structure->DetermineHeuristicTypes(nullptr /* ukm_service */);
+ form_structure->DetermineHeuristicTypes(nullptr /* ukm_recorder */);
autofill_manager_->form_structures()->push_back(std::move(form_structure));
AutofillQueryResponseContents response;
@@ -1008,53 +1239,46 @@ TEST_F(AutofillMetricsTest, QualityMetrics_BasedOnAutocomplete) {
EXPECT_EQ(ADDRESS_HOME_ZIP,
form_structure_ptr->field(2)->Type().GetStorableType());
- // Heuristic predictions.
- // Unknown:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.BasedOnAutocomplete",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType.BasedOnAutocomplete",
- GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP, AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.BasedOnAutocomplete",
- AutofillMetrics::TYPE_MATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType.BasedOnAutocomplete",
- GetFieldTypeGroupMetric(NAME_LAST, AutofillMetrics::TYPE_MATCH), 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.BasedOnAutocomplete",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType.BasedOnAutocomplete",
- GetFieldTypeGroupMetric(NAME_MIDDLE, AutofillMetrics::TYPE_MISMATCH), 1);
+ for (const std::string source : {"Heuristic", "Server"}) {
+ std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate." + source +
+ ".BasedOnAutocomplete";
+ std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType." + source +
+ ".BasedOnAutocomplete";
- // Server predictions.
- // Unknown:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.BasedOnAutocomplete",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType.BasedOnAutocomplete",
- GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP, AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.BasedOnAutocomplete",
- AutofillMetrics::TYPE_MATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType.BasedOnAutocomplete",
- GetFieldTypeGroupMetric(NAME_LAST, AutofillMetrics::TYPE_MATCH), 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.BasedOnAutocomplete",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType.BasedOnAutocomplete",
- GetFieldTypeGroupMetric(NAME_MIDDLE, AutofillMetrics::TYPE_MISMATCH), 1);
+ // Unknown:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
+ 1);
+ // Match:
+ histogram_tester.ExpectBucketCount(aggregate_histogram,
+ AutofillMetrics::TRUE_POSITIVE, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_LAST, AutofillMetrics::TRUE_POSITIVE), 1);
+ // Mismatch:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_MISMATCH, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FIRST,
+ AutofillMetrics::FALSE_POSITIVE_MISMATCH),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_MIDDLE,
+ AutofillMetrics::FALSE_POSITIVE_MISMATCH),
+ 1);
+
+ // Sanity check.
+ histogram_tester.ExpectTotalCount(aggregate_histogram, 3);
+ histogram_tester.ExpectTotalCount(by_field_type_histogram, 4);
+ }
}
// Test that we log UPI Virtual Payment Address.
@@ -1098,195 +1322,6 @@ TEST_F(AutofillMetricsTest, UpiVirtualPaymentAddress) {
"Autofill.UserHappiness", AutofillMetrics::USER_DID_ENTER_UPI_VPA, 1);
}
-// Test that we do not log RAPPOR metrics when the number of mismatches is not
-// high enough.
-TEST_F(AutofillMetricsTest, Rappor_LowMismatchRate_NoMetricsReported) {
- // Set up our form data.
- FormData form;
- form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
- form.action = GURL("http://example.com/submit.html");
-
- std::vector<ServerFieldType> heuristic_types, server_types;
- FormFieldData field;
-
- test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley",
- "text", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(NAME_FULL);
- server_types.push_back(NAME_FULL);
-
- test::CreateTestFormField("Autofill Failed", "autofillfailed",
- "buddy@gmail.com", "text", &field);
- field.is_autofilled = false;
- form.fields.push_back(field);
- heuristic_types.push_back(EMAIL_ADDRESS);
- server_types.push_back(NAME_LAST);
-
- test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER);
- server_types.push_back(EMAIL_ADDRESS);
-
- // Simulate having seen this form on page load.
- autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
-
- // Simulate form submission.
- autofill_manager_->SubmitForm(form, TimeTicks::Now());
-
- // The number of mismatches did not trigger the RAPPOR metric logging.
- EXPECT_EQ(0, autofill_client_.test_rappor_service()->GetReportsCount());
-}
-
-// Test that we don't log RAPPOR metrics in the case heuristics and/or server
-// have no data.
-TEST_F(AutofillMetricsTest, Rappor_NoDataServerAndHeuristic_NoMetricsReported) {
- // Set up our form data.
- FormData form;
- form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
- form.action = GURL("http://example.com/submit.html");
-
- std::vector<ServerFieldType> heuristic_types, server_types;
- FormFieldData field;
-
- test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley",
- "text", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(UNKNOWN_TYPE);
- server_types.push_back(NO_SERVER_DATA);
-
- test::CreateTestFormField("Autofill Failed", "autofillfailed",
- "buddy@gmail.com", "text", &field);
- field.is_autofilled = false;
- form.fields.push_back(field);
- heuristic_types.push_back(UNKNOWN_TYPE);
- server_types.push_back(NO_SERVER_DATA);
-
- test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(UNKNOWN_TYPE);
- server_types.push_back(NO_SERVER_DATA);
-
- // Simulate having seen this form on page load.
- autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
-
- // Simulate form submission.
- autofill_manager_->SubmitForm(form, TimeTicks::Now());
-
- // No RAPPOR metrics are logged in the case of multiple UNKNOWN_TYPE and
- // NO_SERVER_DATA for heuristics and server predictions, respectively.
- EXPECT_EQ(0, autofill_client_.test_rappor_service()->GetReportsCount());
-}
-
-// Test that we log high number of mismatches for the server prediction.
-TEST_F(AutofillMetricsTest, Rappor_HighServerMismatchRate_MetricsReported) {
- // Set up our form data.
- FormData form;
- form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
- form.action = GURL("http://example.com/submit.html");
-
- std::vector<ServerFieldType> heuristic_types, server_types;
- FormFieldData field;
-
- test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley",
- "text", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(NAME_FULL);
- server_types.push_back(NAME_FIRST);
-
- test::CreateTestFormField("Autofill Failed", "autofillfailed",
- "buddy@gmail.com", "text", &field);
- field.is_autofilled = false;
- form.fields.push_back(field);
- heuristic_types.push_back(PHONE_HOME_NUMBER);
- server_types.push_back(NAME_LAST);
-
- test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER);
- server_types.push_back(EMAIL_ADDRESS);
-
- // Simulate having seen this form on page load.
- autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
-
- // Simulate form submission.
- autofill_manager_->SubmitForm(form, TimeTicks::Now());
-
- // The number of mismatches did trigger the RAPPOR metric logging for server
- // predictions.
- EXPECT_EQ(1, autofill_client_.test_rappor_service()->GetReportsCount());
- std::string sample;
- rappor::RapporType type;
- EXPECT_FALSE(
- autofill_client_.test_rappor_service()->GetRecordedSampleForMetric(
- "Autofill.HighNumberOfHeuristicMismatches", &sample, &type));
- EXPECT_TRUE(
- autofill_client_.test_rappor_service()->GetRecordedSampleForMetric(
- "Autofill.HighNumberOfServerMismatches", &sample, &type));
- EXPECT_EQ("example.com", sample);
- EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
-}
-
-// Test that we log high number of mismatches for the heuristic predictions.
-TEST_F(AutofillMetricsTest, Rappor_HighHeuristicMismatchRate_MetricsReported) {
- // Set up our form data.
- FormData form;
- form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
- form.action = GURL("http://example.com/submit.html");
-
- std::vector<ServerFieldType> heuristic_types, server_types;
- FormFieldData field;
-
- test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley",
- "text", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(NAME_FIRST);
- server_types.push_back(NAME_FULL);
-
- test::CreateTestFormField("Autofill Failed", "autofillfailed",
- "buddy@gmail.com", "text", &field);
- field.is_autofilled = false;
- form.fields.push_back(field);
- heuristic_types.push_back(PHONE_HOME_NUMBER);
- server_types.push_back(NAME_LAST);
-
- test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field);
- field.is_autofilled = true;
- form.fields.push_back(field);
- heuristic_types.push_back(EMAIL_ADDRESS);
- server_types.push_back(PHONE_HOME_WHOLE_NUMBER);
-
- // Simulate having seen this form on page load.
- autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
-
- // Simulate form submission.
- autofill_manager_->SubmitForm(form, TimeTicks::Now());
-
- // The number of mismatches did trigger the RAPPOR metric logging for
- // heuristic predictions.
- EXPECT_EQ(1, autofill_client_.test_rappor_service()->GetReportsCount());
- std::string sample;
- rappor::RapporType type;
- EXPECT_FALSE(
- autofill_client_.test_rappor_service()->GetRecordedSampleForMetric(
- "Autofill.HighNumberOfServerMismatches", &sample, &type));
- EXPECT_TRUE(
- autofill_client_.test_rappor_service()->GetRecordedSampleForMetric(
- "Autofill.HighNumberOfHeuristicMismatches", &sample, &type));
- EXPECT_EQ("example.com", sample);
- EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
-}
-
// Verify that when a field is annotated with the autocomplete attribute, its
// predicted type is remembered when quality metrics are logged.
TEST_F(AutofillMetricsTest, PredictedMetricsWithAutocomplete) {
@@ -1314,69 +1349,43 @@ TEST_F(AutofillMetricsTest, PredictedMetricsWithAutocomplete) {
std::vector<FormData> forms(1, form);
- {
- base::HistogramTester histogram_tester;
- autofill_manager_->OnFormsSeen(forms, TimeTicks());
- // We change the value of the text fields to change the default/seen values
- // (hence the values are not cleared in UpdateFromCache). The new values
- // match what is in the test profile.
- form.fields[1].value = base::ASCIIToUTF16("79401");
- form.fields[2].value = base::ASCIIToUTF16("2345678901");
- autofill_manager_->SubmitForm(form, TimeTicks::Now());
+ base::HistogramTester histogram_tester;
+ autofill_manager_->OnFormsSeen(forms, TimeTicks());
+
+ // We change the value of the text fields to change the default/seen values
+ // (hence the values are not cleared in UpdateFromCache). The new values
+ // match what is in the test profile.
+ form.fields[1].value = base::ASCIIToUTF16("79401");
+ form.fields[2].value = base::ASCIIToUTF16("2345678901");
+ autofill_manager_->SubmitForm(form, TimeTicks::Now());
+ for (const std::string source : {"Heuristic", "Server", "Overall"}) {
+ std::string histogram_name =
+ "Autofill.FieldPredictionQuality.ByFieldType." + source;
// First verify that country was not predicted by client or server.
histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
+ histogram_name,
GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // We expect a match for country because it had |autocomplete_attribute|.
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY,
- AutofillMetrics::TYPE_MATCH),
+ source == "Overall"
+ ? AutofillMetrics::TRUE_POSITIVE
+ : AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
1);
// We did not predict zip code or phone number, because they did not have
// |autocomplete_attribute|, nor client or server predictions.
histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
+ histogram_name,
GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP,
- AutofillMetrics::TYPE_UNKNOWN),
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
1);
histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
+ histogram_name,
GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER,
- AutofillMetrics::TYPE_UNKNOWN),
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
1);
// Sanity check.
- histogram_tester.ExpectTotalCount("Autofill.Quality.PredictedType", 3);
+ histogram_tester.ExpectTotalCount(histogram_name, 3);
}
}
@@ -1436,88 +1445,45 @@ TEST_F(AutofillMetricsTest, SaneMetricsWithCacheMismatch) {
base::HistogramTester histogram_tester;
autofill_manager_->SubmitForm(form, TimeTicks::Now());
- // Heuristic predictions.
- // Unknown:
- histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_STATE,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType",
- AutofillMetrics::TYPE_MATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_CITY, AutofillMetrics::TYPE_MATCH),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType",
- AutofillMetrics::TYPE_MISMATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.HeuristicType.ByFieldType",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH),
- 1);
-
- // Server predictions:
- // Unknown:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_STATE,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType",
- AutofillMetrics::TYPE_MATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType",
- AutofillMetrics::TYPE_MISMATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_CITY,
- AutofillMetrics::TYPE_MISMATCH),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.ServerType.ByFieldType",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH),
- 1);
-
- // Overall predictions:
- // Unknown:
- histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType",
- AutofillMetrics::TYPE_UNKNOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_STATE,
- AutofillMetrics::TYPE_UNKNOWN),
- 1);
- // Match:
- histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType",
- AutofillMetrics::TYPE_MATCH, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1);
- // Mismatch:
- histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType",
- AutofillMetrics::TYPE_MISMATCH, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(ADDRESS_HOME_CITY,
- AutofillMetrics::TYPE_MISMATCH),
- 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.Quality.PredictedType.ByFieldType",
- GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH),
- 1);
+ for (const std::string source : {"Heuristic", "Server", "Overall"}) {
+ std::string aggregate_histogram =
+ "Autofill.FieldPredictionQuality.Aggregate." + source;
+ std::string by_field_type_histogram =
+ "Autofill.FieldPredictionQuality.ByFieldType." + source;
+
+ // Unknown:
+ histogram_tester.ExpectBucketCount(
+ aggregate_histogram, AutofillMetrics::FALSE_NEGATIVE_UNKNOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(ADDRESS_HOME_STATE,
+ AutofillMetrics::FALSE_NEGATIVE_UNKNOWN),
+ 1);
+ // Match:
+ histogram_tester.ExpectBucketCount(aggregate_histogram,
+ AutofillMetrics::TRUE_POSITIVE,
+ source == "Heuristic" ? 2 : 1);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TRUE_POSITIVE), 1);
+ // Mismatch:
+ histogram_tester.ExpectBucketCount(aggregate_histogram,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH,
+ source == "Heuristic" ? 1 : 2);
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(EMAIL_ADDRESS,
+ AutofillMetrics::FALSE_NEGATIVE_MISMATCH),
+ 1);
+ // Source dependent:
+ histogram_tester.ExpectBucketCount(
+ by_field_type_histogram,
+ GetFieldTypeGroupMetric(ADDRESS_HOME_CITY,
+ source == "Heuristic"
+ ? AutofillMetrics::TRUE_POSITIVE
+ : AutofillMetrics::FALSE_NEGATIVE_MISMATCH),
+ 1);
+ }
}
// Verify that when submitting an autofillable form, the stored profile metric
@@ -1627,11 +1593,6 @@ TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields) {
// fields is logged.
histogram_tester.ExpectUniqueSample(
"Autofill.NumberOfEditedAutofilledFieldsAtSubmission", 2, 1);
-
- // UKM must not be logged unless enabled.
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
- EXPECT_EQ(0U, ukm_service->sources_count());
- EXPECT_EQ(0U, ukm_service->entries_count());
}
// Verify that when resetting the autofill manager (such as during a
@@ -1686,8 +1647,6 @@ TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields_NoSubmission) {
// Verify that we correctly log metrics regarding developer engagement.
TEST_F(AutofillMetricsTest, DeveloperEngagement) {
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
// Start with a non-fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -1708,10 +1667,6 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
autofill_manager_->OnFormsSeen(forms, TimeTicks());
autofill_manager_->Reset();
histogram_tester.ExpectTotalCount("Autofill.DeveloperEngagement", 0);
-
- // UKM must not be logged unless enabled.
- EXPECT_EQ(0U, ukm_service->sources_count());
- EXPECT_EQ(0U, ukm_service->entries_count());
}
// Add another field to the form, so that it becomes fillable.
@@ -1726,10 +1681,6 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
histogram_tester.ExpectUniqueSample(
"Autofill.DeveloperEngagement",
AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS, 1);
-
- // UKM must not be logged unless enabled.
- EXPECT_EQ(0U, ukm_service->sources_count());
- EXPECT_EQ(0U, ukm_service->entries_count());
}
// Add some fields with an author-specified field type to the form.
@@ -1756,10 +1707,6 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
"Autofill.DeveloperEngagement",
AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS, 1);
- // UKM must not be logged unless enabled.
- EXPECT_EQ(0U, ukm_service->sources_count());
- EXPECT_EQ(0U, ukm_service->entries_count());
-
histogram_tester.ExpectBucketCount(
"Autofill.DeveloperEngagement",
AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT, 0);
@@ -1789,9 +1736,6 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
// developer engagement.
TEST_F(AutofillMetricsTest,
UkmDeveloperEngagement_LogFillableFormParsedWithoutTypeHints) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
// Start with a non-fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -1811,8 +1755,8 @@ TEST_F(AutofillMetricsTest,
autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
autofill_manager_->Reset();
- EXPECT_EQ(0U, ukm_service->sources_count());
- EXPECT_EQ(0U, ukm_service->entries_count());
+ EXPECT_EQ(0U, test_ukm_recorder_.sources_count());
+ EXPECT_EQ(0U, test_ukm_recorder_.entries_count());
}
// Add another field to the form, so that it becomes fillable.
@@ -1825,10 +1769,10 @@ TEST_F(AutofillMetricsTest,
autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
autofill_manager_->Reset();
- ASSERT_EQ(1U, ukm_service->entries_count());
- ASSERT_EQ(1U, ukm_service->sources_count());
+ ASSERT_EQ(1U, test_ukm_recorder_.entries_count());
+ ASSERT_EQ(1U, test_ukm_recorder_.sources_count());
VerifyDeveloperEngagementUkm(
- form, ukm_service,
+ form, &test_ukm_recorder_,
{AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS});
}
}
@@ -1837,9 +1781,6 @@ TEST_F(AutofillMetricsTest,
// developer engagement.
TEST_F(AutofillMetricsTest,
UkmDeveloperEngagement_LogFillableFormParsedWithTypeHints) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
FormData form;
form.name = ASCIIToUTF16("TestForm");
form.origin = GURL("http://example.com/form.html");
@@ -1878,10 +1819,10 @@ TEST_F(AutofillMetricsTest,
autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
autofill_manager_->Reset();
- ASSERT_EQ(1U, ukm_service->entries_count());
- ASSERT_EQ(1U, ukm_service->sources_count());
+ ASSERT_EQ(1U, test_ukm_recorder_.entries_count());
+ ASSERT_EQ(1U, test_ukm_recorder_.sources_count());
VerifyDeveloperEngagementUkm(
- form, ukm_service,
+ form, &test_ukm_recorder_,
{AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS});
}
}
@@ -1889,9 +1830,6 @@ TEST_F(AutofillMetricsTest,
// Verify that we correctly log UKM for form parsed with type hints regarding
// developer engagement.
TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogUpiVpaTypeHint) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
FormData form;
form.name = ASCIIToUTF16("TestForm");
form.origin = GURL("http://example.com/form.html");
@@ -1914,11 +1852,11 @@ TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogUpiVpaTypeHint) {
autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
autofill_manager_->Reset();
- ASSERT_EQ(1U, ukm_service->entries_count());
- ASSERT_EQ(1U, ukm_service->sources_count());
- VerifyDeveloperEngagementUkm(form, ukm_service,
+ ASSERT_EQ(1U, test_ukm_recorder_.entries_count());
+ ASSERT_EQ(1U, test_ukm_recorder_.sources_count());
+ VerifyDeveloperEngagementUkm(form, &test_ukm_recorder_,
{AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT});
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
}
// Add another field with an author-specified field type to the form.
@@ -1931,7 +1869,7 @@ TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogUpiVpaTypeHint) {
autofill_manager_->Reset();
VerifyDeveloperEngagementUkm(
- form, ukm_service,
+ form, &test_ukm_recorder_,
{AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS,
AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT});
}
@@ -2116,9 +2054,6 @@ TEST_F(AutofillMetricsTest, AddressSuggestionsCount) {
// Test that the credit card checkout flow user actions are correctly logged.
TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
personal_data_->RecreateCreditCards(
true /* include_local_credit_card */,
false /* include_masked_server_credit_card */,
@@ -2154,10 +2089,21 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
"Autofill_PolledCreditCardSuggestions"));
}
- // Simulate showing a credit card suggestion.
+ // Simulate showing a credit card suggestion polled from "Name on card" field.
{
base::UserActionTester user_action_tester;
- autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
+ autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
+ form.fields[0]);
+ EXPECT_EQ(1, user_action_tester.GetActionCount(
+ "Autofill_ShowedCreditCardSuggestions"));
+ }
+
+ // Simulate showing a credit card suggestion polled from "Credit card number"
+ // field.
+ {
+ 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"));
}
@@ -2196,28 +2142,32 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
}
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionsShownEntryName,
- {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName,
+ {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, CREDIT_CARD_NAME_FULL},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, CREDIT_CARD_NAME_FULL}},
+ {{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, CREDIT_CARD_NUMBER},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, CREDIT_CARD_NUMBER}}});
// Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
// call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
// |autofill_manager_->FillOrPreviewForm|.
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName,
{{{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}},
{{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
// Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState|
// because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|.
- VerifySubmitFormUkm(form, ukm_service,
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
// Test that the profile checkout flow user actions are correctly logged.
TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
// Create a profile.
personal_data_->RecreateProfile();
@@ -2251,10 +2201,20 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
"Autofill_PolledProfileSuggestions"));
}
- // Simulate showing a profile suggestion.
+ // Simulate showing a profile suggestion polled from "State" field.
{
base::UserActionTester user_action_tester;
- autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
+ autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
+ form.fields[0]);
+ EXPECT_EQ(1, user_action_tester.GetActionCount(
+ "Autofill_ShowedProfileSuggestions"));
+ }
+
+ // Simulate showing a profile suggestion polled from "City" field.
+ {
+ base::UserActionTester user_action_tester;
+ autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
+ form.fields[1]);
EXPECT_EQ(1, user_action_tester.GetActionCount(
"Autofill_ShowedProfileSuggestions"));
}
@@ -2293,20 +2253,27 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
}
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionsShownEntryName,
- {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName,
+ {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, ADDRESS_HOME_STATE},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, ADDRESS_HOME_STATE}},
+ {{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, ADDRESS_HOME_CITY},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, ADDRESS_HOME_CITY}}});
// Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
// call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
// |autofill_manager_->FillOrPreviewForm|.
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName,
{{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}},
{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
// Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState|
// because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|.
- VerifySubmitFormUkm(form, ukm_service,
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
@@ -2597,11 +2564,6 @@ TEST_F(AutofillMetricsTest, CreditCardShownFormEvents) {
"Autofill.FormEvents.CreditCard",
AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
}
-
- // UKM must not be logged unless enabled.
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
- EXPECT_EQ(0U, ukm_service->sources_count());
- EXPECT_EQ(0U, ukm_service->entries_count());
}
// Test that we log selected form event for credit cards.
@@ -2868,9 +2830,6 @@ TEST_F(AutofillMetricsTest, CreditCardGetRealPanDuration) {
// Test that we log submitted form events for credit cards.
TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
EnableWalletSync();
// Creating all kinds of cards.
personal_data_->RecreateCreditCards(
@@ -2911,13 +2870,13 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
"Autofill.FormEvents.CreditCard",
AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- VerifySubmitFormUkm(form, ukm_service,
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
// Reset the autofill manager state and purge UKM logs.
autofill_manager_->Reset();
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
autofill_manager_->AddSeenForm(form, field_types, field_types);
@@ -2935,15 +2894,18 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionsShownEntryName,
- {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
- VerifySubmitFormUkm(form, ukm_service,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName,
+ {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, CREDIT_CARD_NUMBER},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, CREDIT_CARD_NUMBER}}});
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
// Reset the autofill manager state and purge UKM logs.
autofill_manager_->Reset();
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
autofill_manager_->AddSeenForm(form, field_types, field_types);
@@ -2964,16 +2926,16 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName,
{{{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
- VerifySubmitFormUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
// Reset the autofill manager state and purge UKM logs.
autofill_manager_->Reset();
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
autofill_manager_->AddSeenForm(form, field_types, field_types);
@@ -2995,16 +2957,16 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName,
{{{internal::kUKMRecordTypeMetricName, CreditCard::FULL_SERVER_CARD},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
- VerifySubmitFormUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
// Reset the autofill manager state and purge UKM logs.
autofill_manager_->Reset();
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
autofill_manager_->AddSeenForm(form, field_types, field_types);
@@ -3028,19 +2990,20 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
1);
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName,
{{{internal::kUKMRecordTypeMetricName, CreditCard::MASKED_SERVER_CARD},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSelectedMaskedServerCardEntryName,
- {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
- VerifySubmitFormUkm(form, ukm_service,
+ form, &test_ukm_recorder_,
+ internal::kUKMSelectedMaskedServerCardEntryName,
+ {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
// Reset the autofill manager state and purge UKM logs.
autofill_manager_->Reset();
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
// Recreating cards as the previous test should have upgraded the masked
// card to a full card.
@@ -3060,21 +3023,21 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
autofill_manager_->SubmitForm(form, TimeTicks::Now());
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMFormSubmittedEntryName,
+ form, &test_ukm_recorder_, internal::kUKMFormSubmittedEntryName,
{{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
autofill_manager_->SubmitForm(form, TimeTicks::Now());
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMFormSubmittedEntryName,
+ form, &test_ukm_recorder_, internal::kUKMFormSubmittedEntryName,
{{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}},
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
@@ -3114,7 +3077,7 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
// Reset the autofill manager state and purge UKM logs.
autofill_manager_->Reset();
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
autofill_manager_->AddSeenForm(form, field_types, field_types);
@@ -3160,9 +3123,12 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
0);
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionsShownEntryName,
- {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
- VerifySubmitFormUkm(form, ukm_service,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName,
+ {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, CREDIT_CARD_NUMBER},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, CREDIT_CARD_NUMBER}}});
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
}
@@ -3585,9 +3551,6 @@ TEST_F(AutofillMetricsTest, AddressFilledFormEvents) {
// Test that we log submitted form events for address.
TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
EnableWalletSync();
// Create a profile.
personal_data_->RecreateProfile();
@@ -3625,13 +3588,13 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
"Autofill.FormEvents.Address",
AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- VerifySubmitFormUkm(form, ukm_service,
+ VerifySubmitFormUkm(form, &test_ukm_recorder_,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
}
// Reset the autofill manager state and purge UKM logs.
autofill_manager_->Reset();
- ukm_service->Purge();
+ test_ukm_recorder_.Purge();
autofill_manager_->AddSeenForm(form, field_types, field_types);
@@ -4126,9 +4089,6 @@ TEST_F(AutofillMetricsTest, DaysSinceLastUse_Profile) {
// Verify that we correctly log the submitted form's state.
TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
// Start with a form with insufficiently many fields.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -4157,7 +4117,7 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
expected_form_submission_ukm_metrics = {
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}};
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}};
// No data entered in the form.
{
@@ -4172,12 +4132,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
// Expect an entry for |DeveloperEngagement| and an entry for form
// interactions. Both entries are for the same URL.
- ASSERT_EQ(2U, ukm_service->entries_count());
- ASSERT_EQ(2U, ukm_service->sources_count());
+ ASSERT_EQ(2U, test_ukm_recorder_.entries_count());
+ ASSERT_EQ(2U, test_ukm_recorder_.sources_count());
VerifyDeveloperEngagementUkm(
- form, ukm_service,
+ form, &test_ukm_recorder_,
{AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS});
- VerifyFormInteractionUkm(form, ukm_service,
+ VerifyFormInteractionUkm(form, &test_ukm_recorder_,
internal::kUKMFormSubmittedEntryName,
expected_form_submission_ukm_metrics);
}
@@ -4200,8 +4160,8 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
expected_form_submission_ukm_metrics.push_back(
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
- VerifyFormInteractionUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}});
+ VerifyFormInteractionUkm(form, &test_ukm_recorder_,
internal::kUKMFormSubmittedEntryName,
expected_form_submission_ukm_metrics);
}
@@ -4226,8 +4186,8 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::
FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
- VerifyFormInteractionUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}});
+ VerifyFormInteractionUkm(form, &test_ukm_recorder_,
internal::kUKMFormSubmittedEntryName,
expected_form_submission_ukm_metrics);
}
@@ -4245,13 +4205,16 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
"Autofill_FormSubmitted_FilledNone_SuggestionsShown"));
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionsShownEntryName,
- {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName,
+ {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, PHONE_HOME_WHOLE_NUMBER},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, NO_SERVER_DATA}}});
expected_form_submission_ukm_metrics.push_back(
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
- VerifyFormInteractionUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}});
+ VerifyFormInteractionUkm(form, &test_ukm_recorder_,
internal::kUKMFormSubmittedEntryName,
expected_form_submission_ukm_metrics);
}
@@ -4274,8 +4237,8 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
expected_form_submission_ukm_metrics.push_back(
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
- VerifyFormInteractionUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}});
+ VerifyFormInteractionUkm(form, &test_ukm_recorder_,
internal::kUKMFormSubmittedEntryName,
expected_form_submission_ukm_metrics);
}
@@ -4299,8 +4262,8 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
expected_form_submission_ukm_metrics.push_back(
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
- VerifyFormInteractionUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}});
+ VerifyFormInteractionUkm(form, &test_ukm_recorder_,
internal::kUKMFormSubmittedEntryName,
expected_form_submission_ukm_metrics);
}
@@ -4323,8 +4286,8 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
expected_form_submission_ukm_metrics.push_back(
{{internal::kUKMAutofillFormSubmittedStateMetricName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
- VerifyFormInteractionUkm(form, ukm_service,
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}});
+ VerifyFormInteractionUkm(form, &test_ukm_recorder_,
internal::kUKMFormSubmittedEntryName,
expected_form_submission_ukm_metrics);
}
@@ -4333,9 +4296,6 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
// Verify that we correctly log user happiness metrics dealing with form
// interaction.
TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) {
- EnableUkmLogging();
- ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
-
// Load a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -4439,22 +4399,28 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) {
autofill_manager_->Reset();
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMInteractedWithFormEntryName,
+ form, &test_ukm_recorder_, internal::kUKMInteractedWithFormEntryName,
{{{internal::kUKMIsForCreditCardMetricName, false},
{internal::kUKMLocalRecordTypeCountMetricName, 0},
{internal::kUKMServerRecordTypeCountMetricName, 0}}});
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionsShownEntryName,
- {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
- {{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ form, &test_ukm_recorder_, internal::kUKMSuggestionsShownEntryName,
+ {{{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, PHONE_HOME_WHOLE_NUMBER},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, NO_SERVER_DATA}},
+ {{internal::kUKMMillisecondsSinceFormParsedMetricName, 0},
+ {internal::kUKMHeuristicTypeMetricName, EMAIL_ADDRESS},
+ {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+ {internal::kUKMServerTypeMetricName, NO_SERVER_DATA}}});
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+ form, &test_ukm_recorder_, internal::kUKMSuggestionFilledEntryName,
{{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}},
{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
VerifyFormInteractionUkm(
- form, ukm_service, internal::kUKMTextFieldDidChangeEntryName,
+ form, &test_ukm_recorder_, internal::kUKMTextFieldDidChangeEntryName,
{{{internal::kUKMFieldTypeGroupMetricName, NAME},
{internal::kUKMHeuristicTypeMetricName, NAME_FULL},
{internal::kUKMServerTypeMetricName, NO_SERVER_DATA},
@@ -4462,7 +4428,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) {
{internal::kUKMHtmlFieldModeMetricName, HTML_MODE_NONE},
{internal::kUKMIsAutofilledMetricName, false},
{internal::kUKMIsEmptyMetricName, true},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}},
{{internal::kUKMFieldTypeGroupMetricName, NAME},
{internal::kUKMHeuristicTypeMetricName, NAME_FULL},
{internal::kUKMServerTypeMetricName, NO_SERVER_DATA},
@@ -4470,7 +4436,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) {
{internal::kUKMHtmlFieldModeMetricName, HTML_MODE_NONE},
{internal::kUKMIsAutofilledMetricName, true},
{internal::kUKMIsEmptyMetricName, true},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}},
{{internal::kUKMFieldTypeGroupMetricName, EMAIL},
{internal::kUKMHeuristicTypeMetricName, EMAIL_ADDRESS},
{internal::kUKMServerTypeMetricName, NO_SERVER_DATA},
@@ -4478,7 +4444,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) {
{internal::kUKMHtmlFieldModeMetricName, HTML_MODE_NONE},
{internal::kUKMIsAutofilledMetricName, true},
{internal::kUKMIsEmptyMetricName, true},
- {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+ {internal::kUKMMillisecondsSinceFormParsedMetricName, 0}}});
}
// Verify that we correctly log metrics tracking the duration of form fill.
@@ -5052,130 +5018,95 @@ TEST_F(AutofillMetricsTest,
// Tests that logging CardUploadDecision UKM works as expected.
TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric) {
- EnableUkmLogging();
- ukm::UkmServiceTestingHarness ukm_service_test_harness;
GURL url("https://www.google.com");
int upload_decision = 1;
std::vector<std::pair<const char*, int>> metrics = {
{internal::kUKMCardUploadDecisionMetricName, upload_decision}};
- EXPECT_TRUE(AutofillMetrics::LogUkm(
- ukm_service_test_harness.test_ukm_service(), url,
- internal::kUKMCardUploadDecisionEntryName, metrics));
+ EXPECT_TRUE(AutofillMetrics::LogUkm(&test_ukm_recorder_, url,
+ internal::kUKMCardUploadDecisionEntryName,
+ metrics));
- // Make sure that the UKM was logged correctly.
- ukm::TestUkmService* ukm_service =
- ukm_service_test_harness.test_ukm_service();
-
- ASSERT_EQ(1U, ukm_service->sources_count());
+ ASSERT_EQ(1U, test_ukm_recorder_.sources_count());
const ukm::UkmSource* source =
- ukm_service->GetSourceForUrl(url.spec().c_str());
+ test_ukm_recorder_.GetSourceForUrl(url.spec().c_str());
EXPECT_EQ(url.spec(), source->url().spec());
- ASSERT_EQ(1U, ukm_service->entries_count());
- const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
- EXPECT_EQ(source->id(), entry->source_id());
+ ASSERT_EQ(1U, test_ukm_recorder_.entries_count());
+ const ukm::mojom::UkmEntry* entry = test_ukm_recorder_.GetEntry(0);
// Make sure that a card upload decision entry was logged.
- ukm::Entry entry_proto;
- entry->PopulateProto(&entry_proto);
- EXPECT_EQ(source->id(), entry_proto.source_id());
+ EXPECT_EQ(source->id(), entry->source_id);
EXPECT_EQ(base::HashMetricName(internal::kUKMCardUploadDecisionEntryName),
- entry_proto.event_hash());
- EXPECT_EQ(1, entry_proto.metrics_size());
+ entry->event_hash);
+ EXPECT_EQ(1U, entry->metrics.size());
// Make sure that the correct upload decision was logged.
- const ukm::Entry_Metric* metric = FindMetric(
- internal::kUKMCardUploadDecisionMetricName, entry_proto.metrics());
+ const ukm::mojom::UkmMetric* metric = ukm::TestUkmRecorder::FindMetric(
+ entry, internal::kUKMCardUploadDecisionMetricName);
ASSERT_NE(nullptr, metric);
- EXPECT_EQ(upload_decision, metric->value());
+ EXPECT_EQ(upload_decision, metric->value);
}
// Tests that logging DeveloperEngagement UKM works as expected.
TEST_F(AutofillMetricsTest, RecordDeveloperEngagementMetric) {
- EnableUkmLogging();
- ukm::UkmServiceTestingHarness ukm_service_test_harness;
GURL url("https://www.google.com");
int form_structure_metric = 1;
std::vector<std::pair<const char*, int>> metrics = {
{internal::kUKMDeveloperEngagementMetricName, form_structure_metric}};
EXPECT_TRUE(AutofillMetrics::LogUkm(
- ukm_service_test_harness.test_ukm_service(), url,
- internal::kUKMDeveloperEngagementEntryName, metrics));
-
- // Make sure that the UKM was logged correctly.
- ukm::TestUkmService* ukm_service =
- ukm_service_test_harness.test_ukm_service();
+ &test_ukm_recorder_, url, internal::kUKMDeveloperEngagementEntryName,
+ metrics));
- ASSERT_EQ(1U, ukm_service->sources_count());
+ ASSERT_EQ(1U, test_ukm_recorder_.sources_count());
const ukm::UkmSource* source =
- ukm_service->GetSourceForUrl(url.spec().c_str());
+ test_ukm_recorder_.GetSourceForUrl(url.spec().c_str());
EXPECT_EQ(url.spec(), source->url().spec());
- ASSERT_EQ(1U, ukm_service->entries_count());
- const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
- EXPECT_EQ(source->id(), entry->source_id());
+ ASSERT_EQ(1U, test_ukm_recorder_.entries_count());
+ const ukm::mojom::UkmEntry* entry = test_ukm_recorder_.GetEntry(0);
// Make sure that a developer engagement entry was logged.
- ukm::Entry entry_proto;
- entry->PopulateProto(&entry_proto);
- EXPECT_EQ(source->id(), entry_proto.source_id());
+ EXPECT_EQ(source->id(), entry->source_id);
EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
- entry_proto.event_hash());
- EXPECT_EQ(1, entry_proto.metrics_size());
+ entry->event_hash);
+ EXPECT_EQ(1U, entry->metrics.size());
// Make sure that the correct developer engagement metric was logged.
- const ukm::Entry_Metric* metric = FindMetric(
- internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics());
+ const ukm::mojom::UkmMetric* metric = ukm::TestUkmRecorder::FindMetric(
+ entry, internal::kUKMDeveloperEngagementMetricName);
ASSERT_NE(nullptr, metric);
- EXPECT_EQ(form_structure_metric, metric->value());
+ EXPECT_EQ(form_structure_metric, metric->value);
}
// Tests that no UKM is logged when the URL is not valid.
TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_InvalidUrl) {
- EnableUkmLogging();
- ukm::UkmServiceTestingHarness ukm_service_test_harness;
GURL url("");
std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
- EXPECT_FALSE(AutofillMetrics::LogUkm(
- ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
- EXPECT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count());
+ EXPECT_FALSE(
+ AutofillMetrics::LogUkm(&test_ukm_recorder_, url, "test_ukm", metrics));
+ EXPECT_EQ(0U, test_ukm_recorder_.sources_count());
}
// Tests that no UKM is logged when the metrics map is empty.
TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoMetrics) {
- EnableUkmLogging();
- ukm::UkmServiceTestingHarness ukm_service_test_harness;
GURL url("https://www.google.com");
std::vector<std::pair<const char*, int>> metrics;
- EXPECT_FALSE(AutofillMetrics::LogUkm(
- ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
- EXPECT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count());
+ EXPECT_FALSE(
+ AutofillMetrics::LogUkm(&test_ukm_recorder_, url, "test_ukm", metrics));
+ EXPECT_EQ(0U, test_ukm_recorder_.sources_count());
}
// Tests that no UKM is logged when the ukm service is null.
TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoUkmService) {
- EnableUkmLogging();
- ukm::UkmServiceTestingHarness ukm_service_test_harness;
GURL url("https://www.google.com");
std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
EXPECT_FALSE(AutofillMetrics::LogUkm(nullptr, url, "test_ukm", metrics));
- ASSERT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count());
-}
-
-// Tests that no UKM is logged when the ukm logging feature is disabled.
-TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_FeatureDisabled) {
- ukm::UkmServiceTestingHarness ukm_service_test_harness;
- GURL url("https://www.google.com");
- std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
-
- EXPECT_FALSE(AutofillMetrics::LogUkm(
- ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
- EXPECT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count());
+ ASSERT_EQ(0U, test_ukm_recorder_.sources_count());
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_profile.cc b/chromium/components/autofill/core/browser/autofill_profile.cc
index 4ef1222b02a..e54c9fdab7d 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile.cc
@@ -195,23 +195,23 @@ void GetFieldsForDistinguishingProfiles(
AutofillProfile::AutofillProfile(const std::string& guid,
const std::string& origin)
: AutofillDataModel(guid, origin),
- record_type_(LOCAL_PROFILE),
phone_number_(this),
+ record_type_(LOCAL_PROFILE),
has_converted_(false) {}
AutofillProfile::AutofillProfile(RecordType type, const std::string& server_id)
: AutofillDataModel(base::GenerateGUID(), std::string()),
- record_type_(type),
phone_number_(this),
server_id_(server_id),
+ record_type_(type),
has_converted_(false) {
DCHECK(type == SERVER_PROFILE);
}
AutofillProfile::AutofillProfile()
: AutofillDataModel(base::GenerateGUID(), std::string()),
- record_type_(LOCAL_PROFILE),
phone_number_(this),
+ record_type_(LOCAL_PROFILE),
has_converted_(false) {}
AutofillProfile::AutofillProfile(const AutofillProfile& profile)
@@ -225,6 +225,7 @@ AutofillProfile::~AutofillProfile() {
AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) {
set_use_count(profile.use_count());
set_use_date(profile.use_date());
+ set_previous_use_date(profile.previous_use_date());
set_modification_date(profile.modification_date());
if (this == &profile)
@@ -702,6 +703,7 @@ void AutofillProfile::GenerateServerProfileIdentifier() {
}
void AutofillProfile::RecordAndLogUse() {
+ previous_use_date_ = use_date();
UMA_HISTOGRAM_COUNTS_1000("Autofill.DaysSinceLastUse.Profile",
(AutofillClock::Now() - use_date()).InDays());
RecordUse();
diff --git a/chromium/components/autofill/core/browser/autofill_profile.h b/chromium/components/autofill/core/browser/autofill_profile.h
index ae7b521385d..a420dbeac1b 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.h
+++ b/chromium/components/autofill/core/browser/autofill_profile.h
@@ -14,6 +14,7 @@
#include "base/compiler_specific.h"
#include "base/strings/string16.h"
+#include "base/time/time.h"
#include "components/autofill/core/browser/address.h"
#include "components/autofill/core/browser/autofill_data_model.h"
#include "components/autofill/core/browser/autofill_type.h"
@@ -174,11 +175,16 @@ class AutofillProfile : public AutofillDataModel {
// creates its own. The ID is a hash of the data contained in the profile.
void GenerateServerProfileIdentifier();
- // Logs the number of days since the profile was last used and records its
- // use.
+ // Logs the number of days since the profile was last used, records its
+ // use and updates |previous_use_date_| to the last value of |use_date_|.
void RecordAndLogUse();
- // Valid only when type() == SERVER_PROFILE.
+ const base::Time& previous_use_date() const { return previous_use_date_; }
+ void set_previous_use_date(const base::Time& time) {
+ previous_use_date_ = time;
+ }
+
+ // Valid only when |record_type()| == |SERVER_PROFILE|.
bool has_converted() const { return has_converted_; }
void set_has_converted(bool has_converted) { has_converted_ = has_converted; }
@@ -210,8 +216,6 @@ class AutofillProfile : public AutofillDataModel {
// Same as operator==, but ignores differences in GUID.
bool EqualsSansGuid(const AutofillProfile& profile) const;
- RecordType record_type_;
-
// Personal information for this profile.
NameInfo name_;
EmailInfo email_;
@@ -226,6 +230,11 @@ class AutofillProfile : public AutofillDataModel {
// a hash of the contents.
std::string server_id_;
+ // Penultimate time model was used, not persisted to database.
+ base::Time previous_use_date_;
+
+ RecordType record_type_;
+
// Only useful for SERVER_PROFILEs. Whether this server profile has been
// converted to a local profile.
bool has_converted_;
diff --git a/chromium/components/autofill/core/browser/autofill_profile_comparator.cc b/chromium/components/autofill/core/browser/autofill_profile_comparator.cc
index 8bfcd193dd5..9975f35a76f 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_comparator.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_comparator.cc
@@ -276,6 +276,49 @@ bool AutofillProfileComparator::MergeCJKNames(
return true;
}
+bool AutofillProfileComparator::IsNameVariantOf(
+ const base::string16& full_name_1,
+ const base::string16& full_name_2) const {
+ data_util::NameParts name_1_parts = data_util::SplitName(full_name_1);
+
+ // Build the variants of full_name_1`s given, middle and family names.
+ //
+ // TODO(rogerm): Figure out whether or not we should break apart a compound
+ // family name into variants (crbug/619051)
+ const std::set<base::string16> given_name_variants =
+ GetNamePartVariants(name_1_parts.given);
+ const std::set<base::string16> middle_name_variants =
+ GetNamePartVariants(name_1_parts.middle);
+ base::StringPiece16 family_name = name_1_parts.family;
+
+ // Iterate over all full name variants of profile 2 and see if any of them
+ // match the full name from profile 1.
+ for (const auto& given_name : given_name_variants) {
+ for (const auto& middle_name : middle_name_variants) {
+ base::string16 candidate = base::CollapseWhitespace(
+ base::JoinString({given_name, middle_name, family_name}, kSpace),
+ true);
+ if (candidate == full_name_2)
+ return true;
+ }
+ }
+
+ // Also check if the name is just composed of the user's initials. For
+ // example, "thomas jefferson miller" could be composed as "tj miller".
+ if (!name_1_parts.given.empty() && !name_1_parts.middle.empty()) {
+ base::string16 initials;
+ initials.push_back(name_1_parts.given[0]);
+ initials.push_back(name_1_parts.middle[0]);
+ base::string16 candidate = base::CollapseWhitespace(
+ base::JoinString({initials, family_name}, kSpace), true);
+ if (candidate == full_name_2)
+ return true;
+ }
+
+ // There was no match found.
+ return false;
+}
+
bool AutofillProfileComparator::MergeEmailAddresses(
const AutofillProfile& p1,
const AutofillProfile& p2,
@@ -707,49 +750,6 @@ std::set<base::string16> AutofillProfileComparator::GetNamePartVariants(
return variants;
}
-bool AutofillProfileComparator::IsNameVariantOf(
- const base::string16& full_name_1,
- const base::string16& full_name_2) const {
- data_util::NameParts name_1_parts = data_util::SplitName(full_name_1);
-
- // Build the variants of full_name_1`s given, middle and family names.
- //
- // TODO(rogerm): Figure out whether or not we should break apart a compound
- // family name into variants (crbug/619051)
- const std::set<base::string16> given_name_variants =
- GetNamePartVariants(name_1_parts.given);
- const std::set<base::string16> middle_name_variants =
- GetNamePartVariants(name_1_parts.middle);
- base::StringPiece16 family_name = name_1_parts.family;
-
- // Iterate over all full name variants of profile 2 and see if any of them
- // match the full name from profile 1.
- for (const auto& given_name : given_name_variants) {
- for (const auto& middle_name : middle_name_variants) {
- base::string16 candidate = base::CollapseWhitespace(
- base::JoinString({given_name, middle_name, family_name}, kSpace),
- true);
- if (candidate == full_name_2)
- return true;
- }
- }
-
- // Also check if the name is just composed of the user's initials. For
- // example, "thomas jefferson miller" could be composed as "tj miller".
- if (!name_1_parts.given.empty() && !name_1_parts.middle.empty()) {
- base::string16 initials;
- initials.push_back(name_1_parts.given[0]);
- initials.push_back(name_1_parts.middle[0]);
- base::string16 candidate = base::CollapseWhitespace(
- base::JoinString({initials, family_name}, kSpace), true);
- if (candidate == full_name_2)
- return true;
- }
-
- // There was no match found.
- return false;
-}
-
bool AutofillProfileComparator::HaveMergeableNames(
const AutofillProfile& p1,
const AutofillProfile& p2) const {
diff --git a/chromium/components/autofill/core/browser/autofill_profile_comparator.h b/chromium/components/autofill/core/browser/autofill_profile_comparator.h
index 4b69d184112..b71c4fb3d9f 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_comparator.h
+++ b/chromium/components/autofill/core/browser/autofill_profile_comparator.h
@@ -59,6 +59,19 @@ class AutofillProfileComparator {
const AutofillProfile& p2,
NameInfo* name_info) const;
+ // Returns true if |full_name_2| is a variant of |full_name_1|.
+ //
+ // This function generates all variations of |full_name_1| and returns true if
+ // one of these variants is equal to |full_name_2|. For example, this function
+ // will return true if |full_name_2| is "john q public" and |full_name_1| is
+ // "john quincy public" because |full_name_2| can be derived from
+ // |full_name_1| by using the middle initial. Note that the reverse is not
+ // true, "john quincy public" is not a name variant of "john q public".
+ //
+ // Note: Expects that |full_name| is already normalized for comparison.
+ bool IsNameVariantOf(const base::string16& full_name_1,
+ const base::string16& full_name_2) const;
+
// Populates |email_info| with the result of merging the email addresses in
// |p1| and |p2|. Returns true if successful. Expects that |p1| and |p2| have
// already been found to be mergeable.
@@ -137,19 +150,6 @@ class AutofillProfileComparator {
static std::set<base::string16> GetNamePartVariants(
const base::string16& name_part);
- // Returns true if |full_name_2| is a variant of |full_name_1|.
- //
- // This function generates all variations of |full_name_1| and returns true if
- // one of these variants is equal to |full_name_2|. For example, this function
- // will return true if |full_name_2| is "john q public" and |full_name_1| is
- // "john quincy public" because |full_name_2| can be derived from
- // |full_name_1| by using the middle initial. Note that the reverse is not
- // true, "john quincy public" is not a name variant of "john q public".
- //
- // Note: Expects that |full_name| is already normalized for comparison.
- bool IsNameVariantOf(const base::string16& full_name_1,
- const base::string16& full_name_2) const;
-
// Returns true if |p1| and |p2| have names which are equivalent for the
// purposes of merging the two profiles. This means one of the names is
// empty, the names are the same, or one name is a variation of the other.
@@ -215,6 +215,8 @@ class AutofillProfileComparator {
const AutofillProfile& p2,
NameInfo* info) const;
+ const std::string app_locale() const { return app_locale_; }
+
private:
l10n::CaseInsensitiveCompare case_insensitive_compare_;
std::unique_ptr<icu::Transliterator> transliterator_;
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
index 28f7aea7b07..626743179ee 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
@@ -11,9 +11,11 @@
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/legal_message_line.h"
#include "components/autofill/core/common/autofill_constants.h"
+#include "components/autofill/core/common/autofill_pref_names.h"
#include "components/grit/components_scaled_resources.h"
#include "components/infobars/core/infobar.h"
#include "components/infobars/core/infobar_manager.h"
+#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/window_open_disposition.h"
@@ -25,25 +27,29 @@ AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
bool upload,
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- const base::Closure& save_card_callback)
+ const base::Closure& save_card_callback,
+ PrefService* pref_service)
: ConfirmInfoBarDelegate(),
upload_(upload),
save_card_callback_(save_card_callback),
+ pref_service_(pref_service),
had_user_interaction_(false),
#if defined(OS_IOS)
// TODO(jdonnelly): Use credit card issuer images on iOS.
// http://crbug.com/535784
issuer_icon_id_(kNoIconID),
#else
- issuer_icon_id_(CreditCard::IconResourceId(card.type())),
+ issuer_icon_id_(CreditCard::IconResourceId(card.network())),
#endif
card_label_(base::string16(kMidlineEllipsis) + card.LastFourDigits()),
card_sub_label_(card.AbbreviatedExpirationDateForDisplay()) {
if (legal_message)
LegalMessageLine::Parse(*legal_message, &legal_messages_);
- AutofillMetrics::LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN,
- upload_);
+ AutofillMetrics::LogCreditCardInfoBarMetric(
+ AutofillMetrics::INFOBAR_SHOWN, upload_,
+ pref_service_->GetInteger(
+ prefs::kAutofillAcceptSaveCreditCardPromptState));
}
AutofillSaveCardInfoBarDelegateMobile::
@@ -120,7 +126,15 @@ void AutofillSaveCardInfoBarDelegateMobile::LogUserAction(
AutofillMetrics::InfoBarMetric user_action) {
DCHECK(!had_user_interaction_);
- AutofillMetrics::LogCreditCardInfoBarMetric(user_action, upload_);
+ AutofillMetrics::LogCreditCardInfoBarMetric(
+ user_action, upload_,
+ pref_service_->GetInteger(
+ prefs::kAutofillAcceptSaveCreditCardPromptState));
+ pref_service_->SetInteger(
+ prefs::kAutofillAcceptSaveCreditCardPromptState,
+ user_action == AutofillMetrics::INFOBAR_ACCEPTED
+ ? prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_ACCEPTED
+ : prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_DENIED);
had_user_interaction_ = true;
}
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
index d507696c737..d1a0d2297b8 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
+++ b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
@@ -14,6 +14,8 @@
#include "components/autofill/core/browser/legal_message_line.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
+class PrefService;
+
namespace base {
class DictionaryValue;
}
@@ -30,7 +32,8 @@ class AutofillSaveCardInfoBarDelegateMobile : public ConfirmInfoBarDelegate {
bool upload,
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- const base::Closure& save_card_callback);
+ const base::Closure& save_card_callback,
+ PrefService* pref_service);
~AutofillSaveCardInfoBarDelegateMobile() override;
@@ -64,6 +67,9 @@ class AutofillSaveCardInfoBarDelegateMobile : public ConfirmInfoBarDelegate {
// The callback to save credit card if the user accepts the infobar.
base::Closure save_card_callback_;
+ // Weak reference to read & write |kAutofillAcceptSaveCreditCardPromptState|,
+ PrefService* pref_service_;
+
// Did the user ever explicitly accept or dismiss this infobar?
bool had_user_interaction_;
diff --git a/chromium/components/autofill/core/browser/autofill_sync_constants.cc b/chromium/components/autofill/core/browser/autofill_sync_constants.cc
deleted file mode 100644
index b4ccf5fb738..00000000000
--- a/chromium/components/autofill/core/browser/autofill_sync_constants.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 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/autofill_sync_constants.h"
-
-namespace autofill {
-
-const char kSyncCardTypeAmex[] = "AMEX";
-const char kSyncCardTypeDiscover[] = "DISCOVER";
-const char kSyncCardTypeJCB[] = "JCB";
-const char kSyncCardTypeMaestro[] = "MAESTRO";
-const char kSyncCardTypeMasterCard[] = "MASTER_CARD";
-const char kSyncCardTypeSolo[] = "SOLO";
-const char kSyncCardTypeSwitch[] = "SWITCH";
-const char kSyncCardTypeUnknown[] = "UNKNOWN";
-const char kSyncCardTypeVisa[] = "VISA";
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_sync_constants.h b/chromium/components/autofill/core/browser/autofill_sync_constants.h
deleted file mode 100644
index 92aee93db50..00000000000
--- a/chromium/components/autofill/core/browser/autofill_sync_constants.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 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.
-
-namespace autofill {
-
-// These string constants are sent down from Wallet and synced cards and stored
-// in the database for these masked credit cards records.
-extern const char kSyncCardTypeAmex[];
-extern const char kSyncCardTypeDiscover[];
-extern const char kSyncCardTypeJCB[];
-extern const char kSyncCardTypeMaestro[];
-extern const char kSyncCardTypeMasterCard[];
-extern const char kSyncCardTypeSolo[];
-extern const char kSyncCardTypeSwitch[];
-extern const char kSyncCardTypeUnknown[];
-extern const char kSyncCardTypeVisa[];
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.cc b/chromium/components/autofill/core/browser/autofill_test_utils.cc
index 10a23dcb2c6..a851aebfcf2 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.cc
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.cc
@@ -227,14 +227,14 @@ AutofillProfile GetVerifiedProfile2() {
CreditCard GetCreditCard() {
CreditCard credit_card(base::GenerateGUID(), "http://www.example.com");
SetCreditCardInfo(&credit_card, "Test User", "4111111111111111" /* Visa */,
- "11", "2022");
+ "11", "2022", "1");
return credit_card;
}
CreditCard GetCreditCard2() {
CreditCard credit_card(base::GenerateGUID(), "https://www.example.com");
SetCreditCardInfo(&credit_card, "Someone Else", "378282246310005" /* AmEx */,
- "07", "2022");
+ "07", "2022", "1");
return credit_card;
}
@@ -253,16 +253,16 @@ CreditCard GetVerifiedCreditCard2() {
CreditCard GetMaskedServerCard() {
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
test::SetCreditCardInfo(&credit_card, "Bonnie Parker",
- "2109" /* Mastercard */, "12", "2020");
- credit_card.SetTypeForMaskedCard(kMasterCard);
+ "2109" /* Mastercard */, "12", "2020", "1");
+ credit_card.SetNetworkForMaskedCard(kMasterCard);
return credit_card;
}
CreditCard GetMaskedServerCardAmex() {
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "b456");
- test::SetCreditCardInfo(&credit_card, "Justin Thyme",
- "8431" /* Amex */, "9", "2020");
- credit_card.SetTypeForMaskedCard(kAmericanExpressCard);
+ test::SetCreditCardInfo(&credit_card, "Justin Thyme", "8431" /* Amex */, "9",
+ "2020", "1");
+ credit_card.SetNetworkForMaskedCard(kAmericanExpressCard);
return credit_card;
}
@@ -300,12 +300,16 @@ void SetProfileInfoWithGuid(AutofillProfile* profile,
}
void SetCreditCardInfo(CreditCard* credit_card,
- const char* name_on_card, const char* card_number,
- const char* expiration_month, const char* expiration_year) {
+ const char* name_on_card,
+ const char* card_number,
+ const char* expiration_month,
+ const char* expiration_year,
+ const std::string& billing_address_id) {
check_and_set(credit_card, CREDIT_CARD_NAME_FULL, name_on_card);
check_and_set(credit_card, CREDIT_CARD_NUMBER, card_number);
check_and_set(credit_card, CREDIT_CARD_EXP_MONTH, expiration_month);
check_and_set(credit_card, CREDIT_CARD_EXP_4_DIGIT_YEAR, expiration_year);
+ credit_card->set_billing_address_id(billing_address_id);
}
void DisableSystemServices(PrefService* prefs) {
@@ -322,9 +326,8 @@ void SetServerCreditCards(AutofillTable* table,
std::vector<CreditCard> as_masked_cards = cards;
for (CreditCard& card : as_masked_cards) {
card.set_record_type(CreditCard::MASKED_SERVER_CARD);
- std::string type = card.type();
card.SetNumber(card.LastFourDigits());
- card.SetTypeForMaskedCard(type.c_str());
+ card.SetNetworkForMaskedCard(card.network());
}
table->SetServerCreditCards(as_masked_cards);
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.h b/chromium/components/autofill/core/browser/autofill_test_utils.h
index 3e6be716ff4..6bd447e6ded 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.h
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.h
@@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_TEST_UTILS_H_
#include <memory>
+#include <string>
#include <vector>
#include "components/autofill/core/browser/field_types.h"
@@ -107,8 +108,11 @@ void SetProfileInfoWithGuid(AutofillProfile* profile,
// tests. |SetCreditCardInfo| provides a quick way to populate a credit card
// with c-strings.
void SetCreditCardInfo(CreditCard* credit_card,
- const char* name_on_card, const char* card_number,
- const char* expiration_month, const char* expiration_year);
+ const char* name_on_card,
+ const char* card_number,
+ const char* expiration_month,
+ const char* expiration_year,
+ const std::string& billing_address_id);
// TODO(isherman): We should do this automatically for all tests, not manually
// on a per-test basis: http://crbug.com/57221
diff --git a/chromium/components/autofill/core/browser/autofill_type.cc b/chromium/components/autofill/core/browser/autofill_type.cc
index 2b97a2f6eda..b58d1a131ba 100644
--- a/chromium/components/autofill/core/browser/autofill_type.cc
+++ b/chromium/components/autofill/core/browser/autofill_type.cc
@@ -131,6 +131,7 @@ FieldTypeGroup AutofillType::group() const {
case NO_SERVER_DATA:
case EMPTY_TYPE:
+ case AMBIGUOUS_TYPE:
case PHONE_FAX_NUMBER:
case PHONE_FAX_CITY_CODE:
case PHONE_FAX_COUNTRY_CODE:
@@ -771,6 +772,9 @@ std::string AutofillType::ServerFieldTypeToString(ServerFieldType type) {
case CONFIRMATION_PASSWORD:
return "CONFIRMATION_PASSWORD";
+ case AMBIGUOUS_TYPE:
+ return "AMBIGUOUS_TYPE";
+
case MAX_VALID_FIELD_TYPE:
return std::string();
}
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
index cffe8628f57..a08c951defe 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
+++ b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
@@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
#include "base/macros.h"
+#include "base/single_thread_task_runner.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync/driver/async_directory_type_controller.h"
diff --git a/chromium/components/autofill/core/browser/credit_card.cc b/chromium/components/autofill/core/browser/credit_card.cc
index 0e54c44176a..33dc123d3b6 100644
--- a/chromium/components/autofill/core/browser/credit_card.cc
+++ b/chromium/components/autofill/core/browser/credit_card.cc
@@ -19,6 +19,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -71,27 +72,29 @@ bool ConvertYear(const base::string16& year, int* num) {
return false;
}
-base::string16 TypeForFill(const std::string& type) {
- if (type == kAmericanExpressCard)
+base::string16 NetworkForFill(const std::string& network) {
+ if (network == kAmericanExpressCard)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX);
- if (type == kDinersCard)
+ if (network == kDinersCard)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DINERS);
- if (type == kDiscoverCard)
+ if (network == kDiscoverCard)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DISCOVER);
- if (type == kJCBCard)
+ if (network == kEloCard)
+ return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_ELO);
+ if (network == kJCBCard)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_JCB);
- if (type == kMasterCard)
+ if (network == kMasterCard)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD);
- if (type == kMirCard)
+ if (network == kMirCard)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MIR);
- if (type == kUnionPay)
+ if (network == kUnionPay)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_UNION_PAY);
- if (type == kVisaCard)
+ if (network == kVisaCard)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA);
// If you hit this DCHECK, the above list of cases needs to be updated to
// include a new card.
- DCHECK_EQ(kGenericCard, type);
+ DCHECK_EQ(kGenericCard, network);
return base::string16();
}
@@ -100,7 +103,7 @@ base::string16 TypeForFill(const std::string& type) {
CreditCard::CreditCard(const std::string& guid, const std::string& origin)
: AutofillDataModel(guid, origin),
record_type_(LOCAL_CARD),
- type_(kGenericCard),
+ network_(kGenericCard),
expiration_month_(0),
expiration_year_(0),
server_status_(OK) {}
@@ -128,64 +131,63 @@ const base::string16 CreditCard::StripSeparators(const base::string16& number) {
}
// static
-base::string16 CreditCard::TypeForDisplay(const std::string& type) {
- if (kGenericCard == type)
+base::string16 CreditCard::NetworkForDisplay(const std::string& network) {
+ if (kGenericCard == network)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_GENERIC);
- if (kAmericanExpressCard == type)
+ if (kAmericanExpressCard == network)
return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX_SHORT);
- return ::autofill::TypeForFill(type);
+ return ::autofill::NetworkForFill(network);
}
// static
-int CreditCard::IconResourceId(const std::string& type) {
- if (type == kAmericanExpressCard)
+int CreditCard::IconResourceId(const std::string& network) {
+ if (network == kAmericanExpressCard)
return IDR_AUTOFILL_CC_AMEX;
- if (type == kDinersCard)
+ if (network == kDinersCard)
return IDR_AUTOFILL_CC_DINERS;
- if (type == kDiscoverCard)
+ if (network == kDiscoverCard)
return IDR_AUTOFILL_CC_DISCOVER;
- if (type == kJCBCard)
+ if (network == kEloCard)
+ return IDR_AUTOFILL_CC_ELO;
+ if (network == kJCBCard)
return IDR_AUTOFILL_CC_JCB;
- if (type == kMasterCard)
+ if (network == kMasterCard)
return IDR_AUTOFILL_CC_MASTERCARD;
- if (type == kMirCard)
+ if (network == kMirCard)
return IDR_AUTOFILL_CC_MIR;
- if (type == kUnionPay)
- return IDR_AUTOFILL_CC_GENERIC;
- if (type == kVisaCard)
+ if (network == kUnionPay)
+ return IDR_AUTOFILL_CC_UNIONPAY;
+ if (network == kVisaCard)
return IDR_AUTOFILL_CC_VISA;
// If you hit this DCHECK, the above list of cases needs to be updated to
// include a new card.
- DCHECK_EQ(kGenericCard, type);
+ DCHECK_EQ(kGenericCard, network);
return IDR_AUTOFILL_CC_GENERIC;
}
// static
-const char* CreditCard::GetCreditCardType(const base::string16& number) {
+const char* CreditCard::GetCardNetwork(const base::string16& number) {
// Credit card number specifications taken from:
- // http://en.wikipedia.org/wiki/Credit_card_numbers,
- // http://en.wikipedia.org/wiki/List_of_Issuer_Identification_Numbers,
- // http://www.discovernetwork.com/merchants/images/Merchant_Marketing_PDF.pdf,
+ // https://en.wikipedia.org/wiki/Payment_card_number,
// http://www.regular-expressions.info/creditcard.html,
- // http://developer.ean.com/general_info/Valid_Credit_Card_Types,
- // http://www.bincodes.com/,
- // http://www.fraudpractice.com/FL-binCC.html, and
- // http://www.beachnet.com/~hstiles/cardtype.html
+ // https://developer.ean.com/general-info/valid-card-types,
+ // http://www.bincodes.com/, and
+ // http://www.fraudpractice.com/FL-binCC.html.
+ // (Last updated: May 29, 2017)
//
- // The last site is currently unavailable, but a cached version remains at
- // http://web.archive.org/web/20120923111349/http://www.beachnet.com/~hstiles/cardtype.html
- //
- // Card Type Prefix(es) Length
- // ---------------------------------------------------------------
- // Visa 4 13,16
- // American Express 34,37 15
- // Diners Club 300-305,3095,36,38-39 14
- // Discover Card 6011,644-649,65 16
- // JCB 3528-3589 16
- // MasterCard 51-55 16
- // UnionPay 62 16-19
+ // Card Type Prefix(es) Length
+ // --------------------------------------------------------------------------
+ // Visa 4 13,16,19
+ // American Express 34,37 15
+ // Diners Club 300-305,309,36,38-39 14
+ // Discover Card 6011,644-649,65 16
+ // Elo 431274,451416,5067,5090,627780,636297 16
+ // JCB 3528-3589 16
+ // Mastercard 2221-2720, 51-55 16
+ // MIR 2200-2204 16
+ // UnionPay 62 16-19
// Check for prefixes of length 1.
if (number.empty())
@@ -202,9 +204,6 @@ const char* CreditCard::GetCreditCardType(const base::string16& number) {
if (!base::StringToInt(number.substr(0, 2), &first_two_digits))
return kGenericCard;
- if (first_two_digits == 22)
- return kMirCard;
-
if (first_two_digits == 34 || first_two_digits == 37)
return kAmericanExpressCard;
@@ -230,7 +229,8 @@ const char* CreditCard::GetCreditCardType(const base::string16& number) {
if (!base::StringToInt(number.substr(0, 3), &first_three_digits))
return kGenericCard;
- if (first_three_digits >= 300 && first_three_digits <= 305)
+ if ((first_three_digits >= 300 && first_three_digits <= 305) ||
+ first_three_digits == 309)
return kDinersCard;
if (first_three_digits >= 644 && first_three_digits <= 649)
@@ -244,21 +244,41 @@ const char* CreditCard::GetCreditCardType(const base::string16& number) {
if (!base::StringToInt(number.substr(0, 4), &first_four_digits))
return kGenericCard;
- if (first_four_digits == 3095)
- return kDinersCard;
+ if (first_four_digits >= 2200 && first_four_digits <= 2204)
+ return kMirCard;
+
+ if (first_four_digits >= 2221 && first_four_digits <= 2720)
+ return kMasterCard;
if (first_four_digits >= 3528 && first_four_digits <= 3589)
return kJCBCard;
+ if (first_four_digits == 5067 || first_four_digits == 5090)
+ return kEloCard;
+
if (first_four_digits == 6011)
return kDiscoverCard;
+ // Check for prefixes of length 6.
+ if (number.size() < 6)
+ return kGenericCard;
+
+ int first_six_digits = 0;
+ if (!base::StringToInt(number.substr(0, 6), &first_six_digits))
+ return kGenericCard;
+
+ if (first_six_digits == 431274 ||
+ first_six_digits == 451416 ||
+ first_six_digits == 627780 ||
+ first_six_digits == 636297)
+ return kEloCard;
+
return kGenericCard;
}
-void CreditCard::SetTypeForMaskedCard(const char* type) {
+void CreditCard::SetNetworkForMaskedCard(base::StringPiece network) {
DCHECK_EQ(MASKED_SERVER_CARD, record_type());
- type_ = type;
+ network_ = network.as_string();
}
void CreditCard::SetServerStatus(ServerStatus status) {
@@ -309,7 +329,7 @@ base::string16 CreditCard::GetRawInfo(ServerFieldType type) const {
}
case CREDIT_CARD_TYPE:
- return TypeForFill();
+ return NetworkForFill();
case CREDIT_CARD_NUMBER:
return number_;
@@ -380,7 +400,7 @@ base::string16 CreditCard::GetInfo(const AutofillType& type,
// Web pages should never actually be filled by a masked server card,
// but this function is used at the preview stage.
if (record_type() == MASKED_SERVER_CARD)
- return TypeAndLastFourDigits();
+ return NetworkAndLastFourDigits();
return StripSeparators(number_);
}
@@ -419,32 +439,6 @@ void CreditCard::GetMatchingTypes(const base::string16& text,
}
}
-const base::string16 CreditCard::Label() const {
- std::pair<base::string16, base::string16> pieces = LabelPieces();
- return pieces.first + pieces.second;
-}
-
-const std::pair<base::string16, base::string16> CreditCard::LabelPieces()
- const {
- base::string16 label;
- // No CC number, return name only.
- if (number().empty())
- return std::make_pair(name_on_card_, base::string16());
-
- base::string16 obfuscated_cc_number = TypeAndLastFourDigits();
- // No expiration date set.
- if (!expiration_month_ || !expiration_year_)
- return std::make_pair(obfuscated_cc_number, base::string16());
-
- base::string16 formatted_date(ExpirationMonthAsString());
- formatted_date.append(ASCIIToUTF16("/"));
- formatted_date.append(Expiration4DigitYearAsString());
-
- base::string16 separator =
- l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
- return std::make_pair(obfuscated_cc_number, separator + formatted_date);
-}
-
void CreditCard::SetInfoForMonthInputType(const base::string16& value) {
// Check if |text| is "yyyy-mm" format first, and check normal month format.
if (!MatchesPattern(value, base::UTF8ToUTF16("^[0-9]{4}-[0-9]{1,2}$")))
@@ -487,40 +481,6 @@ void CreditCard::SetExpirationYear(int expiration_year) {
expiration_year_ = expiration_year;
}
-base::string16 CreditCard::LastFourDigits() const {
- static const size_t kNumLastDigits = 4;
-
- base::string16 number = StripSeparators(number_);
- if (number.size() <= kNumLastDigits)
- return number;
-
- return number.substr(number.size() - kNumLastDigits, kNumLastDigits);
-}
-
-base::string16 CreditCard::TypeForDisplay() const {
- return CreditCard::TypeForDisplay(type_);
-}
-
-base::string16 CreditCard::TypeAndLastFourDigits() const {
- base::string16 type = TypeForDisplay();
-
- base::string16 digits = LastFourDigits();
- if (digits.empty())
- return type;
-
- // TODO(estade): i18n?
- return type + base::string16(kMidlineEllipsis) + digits;
-}
-
-base::string16 CreditCard::AbbreviatedExpirationDateForDisplay() const {
- base::string16 month = ExpirationMonthAsString();
- base::string16 year = Expiration2DigitYearAsString();
- return month.empty() || year.empty()
- ? base::string16()
- : l10n_util::GetStringFUTF16(
- IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_ABBR, month, year);
-}
-
void CreditCard::operator=(const CreditCard& credit_card) {
set_use_count(credit_card.use_count());
set_use_date(credit_card.use_date());
@@ -532,7 +492,7 @@ void CreditCard::operator=(const CreditCard& credit_card) {
record_type_ = credit_card.record_type_;
number_ = credit_card.number_;
name_on_card_ = credit_card.name_on_card_;
- type_ = credit_card.type_;
+ network_ = credit_card.network_;
expiration_month_ = credit_card.expiration_month_;
expiration_year_ = credit_card.expiration_year_;
server_id_ = credit_card.server_id_;
@@ -543,55 +503,6 @@ void CreditCard::operator=(const CreditCard& credit_card) {
set_origin(credit_card.origin());
}
-base::string16 CreditCard::GetLastUsedDateForDisplay(
- const std::string& app_locale) const {
- bool show_expiration_date =
- ShowExpirationDateInAutofillCreditCardLastUsedDate();
-
- DCHECK(use_count() > 0);
- // use_count() is initialized as 1 when the card is just added.
- if (use_count() == 1) {
- return show_expiration_date
- ? l10n_util::GetStringFUTF16(
- IDS_AUTOFILL_CREDIT_CARD_EXP_AND_ADDED_DATE,
- GetInfo(AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR),
- app_locale),
- base::TimeFormatWithPattern(
- use_date(), kTimeFormatPatternNoYearShortMonthDate))
- : l10n_util::GetStringFUTF16(
- IDS_AUTOFILL_CREDIT_CARD_ADDED_DATE,
- base::TimeFormatWithPattern(
- use_date(), kTimeFormatPatternNoYearShortMonthDate));
- }
-
- // use_count() > 1 when the card has been used in autofill.
-
- // If the card was last used in autofill more than a year ago,
- // display "last used over a year ago" without showing date detail.
- if ((AutofillClock::Now() - use_date()).InDays() > 365) {
- return show_expiration_date
- ? l10n_util::GetStringFUTF16(
- IDS_AUTOFILL_CREDIT_CARD_EXP_AND_LAST_USED_YEAR_AGO,
- GetInfo(AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR),
- app_locale))
- : l10n_util::GetStringUTF16(
- IDS_AUTOFILL_CREDIT_CARD_LAST_USED_YEAR_AGO);
- }
-
- // If the card was last used in autofill within a year, show date information.
- return show_expiration_date
- ? l10n_util::GetStringFUTF16(
- IDS_AUTOFILL_CREDIT_CARD_EXP_AND_LAST_USED_DATE,
- GetInfo(AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR),
- app_locale),
- base::TimeFormatWithPattern(
- use_date(), kTimeFormatPatternNoYearShortMonthDate))
- : l10n_util::GetStringFUTF16(
- IDS_AUTOFILL_CREDIT_CARD_LAST_USED_DATE,
- base::TimeFormatWithPattern(
- use_date(), kTimeFormatPatternNoYearShortMonthDate));
-}
-
bool CreditCard::UpdateFromImportedCard(const CreditCard& imported_card,
const std::string& app_locale) {
if (this->GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale) !=
@@ -677,7 +588,9 @@ bool CreditCard::IsLocalDuplicateOfServerCard(const CreditCard& other) const {
if ((!name_on_card_.empty() && name_on_card_ != other.name_on_card_) ||
(expiration_month_ != 0 &&
expiration_month_ != other.expiration_month_) ||
- (expiration_year_ != 0 && expiration_year_ != other.expiration_year_)) {
+ (expiration_year_ != 0 && expiration_year_ != other.expiration_year_) ||
+ (!billing_address_id_.empty() &&
+ billing_address_id_ != other.billing_address_id_)) {
return false;
}
@@ -691,7 +604,7 @@ bool CreditCard::HasSameNumberAs(const CreditCard& other) const {
// For masked cards, this is the best we can do to compare card numbers.
if (record_type() == MASKED_SERVER_CARD ||
other.record_type() == MASKED_SERVER_CARD) {
- return TypeAndLastFourDigits() == other.TypeAndLastFourDigits();
+ return NetworkAndLastFourDigits() == other.NetworkAndLastFourDigits();
}
return StripSeparators(number_) == StripSeparators(other.number_);
@@ -786,17 +699,118 @@ void CreditCard::SetExpirationDateFromString(const base::string16& text) {
SetExpirationYear(num);
}
-void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
- supported_types->insert(CREDIT_CARD_NAME_FULL);
- supported_types->insert(CREDIT_CARD_NAME_FIRST);
- supported_types->insert(CREDIT_CARD_NAME_LAST);
- supported_types->insert(CREDIT_CARD_NUMBER);
- supported_types->insert(CREDIT_CARD_TYPE);
- supported_types->insert(CREDIT_CARD_EXP_MONTH);
- supported_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
- supported_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
- supported_types->insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
- supported_types->insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
+const std::pair<base::string16, base::string16> CreditCard::LabelPieces()
+ const {
+ base::string16 label;
+ // No CC number, return name only.
+ if (number().empty())
+ return std::make_pair(name_on_card_, base::string16());
+
+ base::string16 obfuscated_cc_number = NetworkAndLastFourDigits();
+ // No expiration date set.
+ if (!expiration_month_ || !expiration_year_)
+ return std::make_pair(obfuscated_cc_number, base::string16());
+
+ base::string16 formatted_date = ExpirationDateForDisplay();
+
+ base::string16 separator =
+ l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
+ return std::make_pair(obfuscated_cc_number, separator + formatted_date);
+}
+
+const base::string16 CreditCard::Label() const {
+ std::pair<base::string16, base::string16> pieces = LabelPieces();
+ return pieces.first + pieces.second;
+}
+
+base::string16 CreditCard::LastFourDigits() const {
+ static const size_t kNumLastDigits = 4;
+
+ base::string16 number = StripSeparators(number_);
+ if (number.size() <= kNumLastDigits)
+ return number;
+
+ return number.substr(number.size() - kNumLastDigits, kNumLastDigits);
+}
+
+base::string16 CreditCard::NetworkForDisplay() const {
+ return CreditCard::NetworkForDisplay(network_);
+}
+
+base::string16 CreditCard::NetworkAndLastFourDigits() const {
+ base::string16 network = NetworkForDisplay();
+
+ base::string16 digits = LastFourDigits();
+ if (digits.empty())
+ return network;
+
+ // TODO(estade): i18n?
+ return network + base::string16(kMidlineEllipsis) + digits;
+}
+
+base::string16 CreditCard::AbbreviatedExpirationDateForDisplay() const {
+ base::string16 month = ExpirationMonthAsString();
+ base::string16 year = Expiration2DigitYearAsString();
+ return month.empty() || year.empty()
+ ? base::string16()
+ : l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_ABBR, month, year);
+}
+
+base::string16 CreditCard::GetLastUsedDateForDisplay(
+ const std::string& app_locale) const {
+ bool show_expiration_date =
+ ShowExpirationDateInAutofillCreditCardLastUsedDate();
+
+ DCHECK_LT(0U, use_count());
+ // use_count() is initialized as 1 when the card is just added.
+ if (use_count() == 1U) {
+ return show_expiration_date
+ ? l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_CREDIT_CARD_EXP_AND_ADDED_DATE,
+ GetInfo(AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR),
+ app_locale),
+ base::TimeFormatWithPattern(
+ use_date(), kTimeFormatPatternNoYearShortMonthDate))
+ : l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_CREDIT_CARD_ADDED_DATE,
+ base::TimeFormatWithPattern(
+ use_date(), kTimeFormatPatternNoYearShortMonthDate));
+ }
+
+ // use_count() > 1 when the card has been used in autofill.
+
+ // If the card was last used in autofill more than a year ago,
+ // display "last used over a year ago" without showing date detail.
+ if ((AutofillClock::Now() - use_date()).InDays() > 365) {
+ return show_expiration_date
+ ? l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_CREDIT_CARD_EXP_AND_LAST_USED_YEAR_AGO,
+ GetInfo(AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR),
+ app_locale))
+ : l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_CREDIT_CARD_LAST_USED_YEAR_AGO);
+ }
+
+ // If the card was last used in autofill within a year, show date information.
+ return show_expiration_date
+ ? l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_CREDIT_CARD_EXP_AND_LAST_USED_DATE,
+ GetInfo(AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR),
+ app_locale),
+ base::TimeFormatWithPattern(
+ use_date(), kTimeFormatPatternNoYearShortMonthDate))
+ : l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_CREDIT_CARD_LAST_USED_DATE,
+ base::TimeFormatWithPattern(
+ use_date(), kTimeFormatPatternNoYearShortMonthDate));
+}
+
+base::string16 CreditCard::ExpirationDateForDisplay() const {
+ base::string16 formatted_date(ExpirationMonthAsString());
+ formatted_date.append(ASCIIToUTF16("/"));
+ formatted_date.append(Expiration4DigitYearAsString());
+ return formatted_date;
}
base::string16 CreditCard::ExpirationMonthAsString() const {
@@ -812,10 +826,6 @@ base::string16 CreditCard::ExpirationMonthAsString() const {
return zero;
}
-base::string16 CreditCard::TypeForFill() const {
- return ::autofill::TypeForFill(type_);
-}
-
base::string16 CreditCard::Expiration4DigitYearAsString() const {
if (expiration_year_ == 0)
return base::string16();
@@ -830,13 +840,30 @@ base::string16 CreditCard::Expiration2DigitYearAsString() const {
return base::IntToString16(Expiration2DigitYear());
}
+void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
+ supported_types->insert(CREDIT_CARD_NAME_FULL);
+ supported_types->insert(CREDIT_CARD_NAME_FIRST);
+ supported_types->insert(CREDIT_CARD_NAME_LAST);
+ supported_types->insert(CREDIT_CARD_NUMBER);
+ supported_types->insert(CREDIT_CARD_TYPE);
+ supported_types->insert(CREDIT_CARD_EXP_MONTH);
+ supported_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
+ supported_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
+ supported_types->insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
+ supported_types->insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
+}
+
+base::string16 CreditCard::NetworkForFill() const {
+ return ::autofill::NetworkForFill(network_);
+}
+
void CreditCard::SetNumber(const base::string16& number) {
number_ = number;
// Set the type based on the card number, but only for full numbers, not
// when we have masked cards from the server (last 4 digits).
if (record_type_ != MASKED_SERVER_CARD)
- type_ = GetCreditCardType(StripSeparators(number_));
+ network_ = GetCardNetwork(StripSeparators(number_));
}
void CreditCard::RecordAndLogUse() {
@@ -922,12 +949,10 @@ std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) {
credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
}
-// These values must match the values in WebKitPlatformSupportImpl in
-// webkit/glue. We send these strings to WebKit, which then asks
-// WebKitPlatformSupportImpl to load the image data.
const char kAmericanExpressCard[] = "americanExpressCC";
const char kDinersCard[] = "dinersCC";
const char kDiscoverCard[] = "discoverCC";
+const char kEloCard[] = "eloCC";
const char kGenericCard[] = "genericCC";
const char kJCBCard[] = "jcbCC";
const char kMasterCard[] = "masterCardCC";
diff --git a/chromium/components/autofill/core/browser/credit_card.h b/chromium/components/autofill/core/browser/credit_card.h
index 0fb251e9deb..4dc8bb9bc93 100644
--- a/chromium/components/autofill/core/browser/credit_card.h
+++ b/chromium/components/autofill/core/browser/credit_card.h
@@ -13,6 +13,7 @@
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/strings/string16.h"
+#include "base/strings/string_piece_forward.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_data_model.h"
@@ -21,7 +22,7 @@ namespace autofill {
// A midline horizontal ellipsis (U+22EF).
extern const base::char16 kMidlineEllipsis[];
-// A form group that stores credit card information.
+// A form group that stores card information.
class CreditCard : public AutofillDataModel {
public:
enum RecordType {
@@ -39,7 +40,7 @@ class CreditCard : public AutofillDataModel {
FULL_SERVER_CARD,
};
- // The status of this credit card. Only used for server cards.
+ // The status of this card. Only used for server cards.
enum ServerStatus {
EXPIRED,
OK,
@@ -59,23 +60,25 @@ class CreditCard : public AutofillDataModel {
// Returns a version of |number| that has any separator characters removed.
static const base::string16 StripSeparators(const base::string16& number);
- // The user-visible type of the card, e.g. 'Mastercard'.
- static base::string16 TypeForDisplay(const std::string& type);
+ // The user-visible issuer network of the card, e.g. 'Mastercard'.
+ static base::string16 NetworkForDisplay(const std::string& network);
- // The ResourceBundle ID for the appropriate credit card image.
- static int IconResourceId(const std::string& type);
+ // The ResourceBundle ID for the appropriate card issuer network image.
+ static int IconResourceId(const std::string& network);
- // Returns the internal representation of credit card type corresponding to
- // the given |number|. The credit card type is determined purely according to
- // the Issuer Identification Number (IIN), a.k.a. the "Bank Identification
+ // Returns the internal representation of card issuer network corresponding to
+ // the given |number|. The card issuer network is determined purely according
+ // to the Issuer Identification Number (IIN), a.k.a. the "Bank Identification
// Number (BIN)", which is parsed from the relevant prefix of the |number|.
// This function performs no additional validation checks on the |number|.
- // Hence, the returned type for both the valid card "4111-1111-1111-1111" and
- // the invalid card "4garbage" will be Visa, which has an IIN of 4.
- static const char* GetCreditCardType(const base::string16& number);
+ // Hence, the returned issuer network for both the valid card
+ // "4111-1111-1111-1111" and the invalid card "4garbage" will be Visa, which
+ // has an IIN of 4.
+ static const char* GetCardNetwork(const base::string16& number);
- // Type strings are defined at the bottom of this file, e.g. kVisaCard.
- void SetTypeForMaskedCard(const char* type);
+ // Network issuer strings are defined at the bottom of this file, e.g.
+ // kVisaCard.
+ void SetNetworkForMaskedCard(base::StringPiece network);
// Sets/gets the status of a server card.
void SetServerStatus(ServerStatus status);
@@ -93,27 +96,10 @@ class CreditCard : public AutofillDataModel {
const base::string16& value,
const std::string& app_locale) override;
- // Credit card preview summary, for example: "Visa - 1234", ", 01/2020".
- const std::pair<base::string16, base::string16> LabelPieces() const;
-
- // Like LabelPieces, but appends the two pieces together.
- const base::string16 Label() const;
-
// Special method to set value for HTML5 month input type.
void SetInfoForMonthInputType(const base::string16& value);
- // The last four digits of the credit card number (or possibly less if there
- // aren't enough characters).
- base::string16 LastFourDigits() const;
- // The user-visible type of the card, e.g. 'Mastercard'.
- base::string16 TypeForDisplay() const;
- // A label for this credit card formatted as 'Cardname - 2345'.
- base::string16 TypeAndLastFourDigits() const;
-
- // Localized expiration for this credit card formatted as 'Exp: 06/17'.
- base::string16 AbbreviatedExpirationDateForDisplay() const;
-
- const std::string& type() const { return type_; }
+ const std::string& network() const { return network_; }
int expiration_month() const { return expiration_month_; }
int expiration_year() const { return expiration_year_; }
@@ -132,17 +118,17 @@ class CreditCard : public AutofillDataModel {
// If the card numbers for |this| and |imported_card| match, and merging the
// two wouldn't result in unverified data overwriting verified data,
- // overwrites |this| card's data with the data in |credit_card|.
- // Returns true if the card numbers match, false otherwise.
+ // overwrites |this| card's data with the data in |imported_card|. Returns
+ // true if the card numbers match, false otherwise.
bool UpdateFromImportedCard(const CreditCard& imported_card,
const std::string& app_locale) WARN_UNUSED_RESULT;
- // Comparison for Sync. Returns 0 if the credit card is the same as |this|,
- // or < 0, or > 0 if it is different. The implied ordering can be used for
- // culling duplicates. The ordering is based on collation order of the
- // textual contents of the fields.
+ // Comparison for Sync. Returns 0 if the card is the same as |this|, or < 0,
+ // or > 0 if it is different. The implied ordering can be used for culling
+ // duplicates. The ordering is based on collation order of the textual
+ // contents of the fields.
// GUIDs, origins, labels, and unique IDs are not compared, only the values of
- // the credit cards themselves.
+ // the cards themselves.
int Compare(const CreditCard& credit_card) const;
// Determines if |this| is a local version of the server card |other|.
@@ -169,16 +155,13 @@ class CreditCard : public AutofillDataModel {
// not complete.
bool IsValid() const;
- // Returns the credit card number.
+ // Returns the card number.
const base::string16& number() const { return number_; }
- // Sets |number_| to |number| and computes the appropriate card |type_|.
+ // Sets |number_| to |number| and computes the appropriate card issuer
+ // |network_|.
void SetNumber(const base::string16& number);
- // Returns the date when the credit card was last used in autofill.
- base::string16 GetLastUsedDateForDisplay(const std::string& app_locale) const;
-
- // Logs the number of days since the credit card was last used and records its
- // use.
+ // Logs the number of days since the card was last used and records its use.
void RecordAndLogUse();
// Converts a string representation of a month (such as "February" or "feb."
@@ -188,7 +171,7 @@ class CreditCard : public AutofillDataModel {
const std::string& app_locale,
int* num);
- // Returns whether the credit card is expired based on |current_time|.
+ // Returns whether the card is expired based on |current_time|.
bool IsExpired(const base::Time& current_time) const;
// Whether the card expiration date should be updated.
@@ -213,35 +196,58 @@ class CreditCard : public AutofillDataModel {
// digit months, with various separators.
void SetExpirationDateFromString(const base::string16& text);
+ // Various display functions.
+
+ // Card preview summary, for example: "Visa - 1234", ", 01/2020".
+ const std::pair<base::string16, base::string16> LabelPieces() const;
+ // Like LabelPieces, but appends the two pieces together.
+ const base::string16 Label() const;
+ // The last four digits of the card number (or possibly less if there aren't
+ // enough characters).
+ base::string16 LastFourDigits() const;
+ // The user-visible issuer network of the card, e.g. 'Mastercard'.
+ base::string16 NetworkForDisplay() const;
+ // A label for this card formatted as 'IssuerNetwork - 2345'.
+ base::string16 NetworkAndLastFourDigits() const;
+ // Localized expiration for this card formatted as 'Exp: 06/17'.
+ base::string16 AbbreviatedExpirationDateForDisplay() const;
+ // Returns the date when the card was last used in autofill.
+ base::string16 GetLastUsedDateForDisplay(const std::string& app_locale) const;
+ // Formatted expiration date (e.g., 05/2020).
+ base::string16 ExpirationDateForDisplay() const;
+ // Expiration functions.
+ base::string16 ExpirationMonthAsString() const;
+ base::string16 Expiration4DigitYearAsString() const;
+
private:
FRIEND_TEST_ALL_PREFIXES(CreditCardTest, SetExpirationDateFromString);
FRIEND_TEST_ALL_PREFIXES(CreditCardTest, SetExpirationYearFromString);
+ base::string16 Expiration2DigitYearAsString() const;
+
// FormGroup:
void GetSupportedTypes(ServerFieldTypeSet* supported_types) const override;
- // The type of the card to fill in to the page, e.g. 'Mastercard'.
- base::string16 TypeForFill() const;
+ // The issuer network of the card to fill in to the page, e.g. 'Mastercard'.
+ base::string16 NetworkForFill() const;
// The month and year are zero if not present.
int Expiration4DigitYear() const { return expiration_year_; }
int Expiration2DigitYear() const { return expiration_year_ % 100; }
- base::string16 ExpirationMonthAsString() const;
- base::string16 Expiration4DigitYearAsString() const;
- base::string16 Expiration2DigitYearAsString() const;
// See enum definition above.
RecordType record_type_;
- // The credit card number. For MASKED_SERVER_CARDs, this number will
- // just contain the last four digits of the card number.
+ // The card number. For MASKED_SERVER_CARDs, this number will just contain the
+ // last four digits of the card number.
base::string16 number_;
// The cardholder's name. May be empty.
base::string16 name_on_card_;
- // The type of the card. This is one of the k...Card constants below.
- std::string type_;
+ // The network issuer of the card. This is one of the k...Card constants
+ // below.
+ std::string network_;
// These members are zero if not present.
int expiration_month_;
@@ -266,6 +272,7 @@ std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card);
extern const char kAmericanExpressCard[];
extern const char kDinersCard[];
extern const char kDiscoverCard[];
+extern const char kEloCard[];
extern const char kGenericCard[];
extern const char kJCBCard[];
extern const char kMasterCard[];
diff --git a/chromium/components/autofill/core/browser/credit_card_field.cc b/chromium/components/autofill/core/browser/credit_card_field.cc
index 1f23137e4df..44a2685bf1c 100644
--- a/chromium/components/autofill/core/browser/credit_card_field.cc
+++ b/chromium/components/autofill/core/browser/credit_card_field.cc
@@ -16,10 +16,10 @@
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_field.h"
-#include "components/autofill/core/browser/autofill_regex_constants.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/common/autofill_clock.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
#include "components/autofill/core/common/autofill_regexes.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
@@ -126,7 +126,7 @@ std::unique_ptr<FormField> CreditCardField::Parse(AutofillScanner* scanner) {
}
}
- // Check for a credit card type (Visa, MasterCard, etc.) field.
+ // Check for a credit card type (Visa, Mastercard, etc.) field.
// All CC type fields encountered so far have been of type select.
if (!credit_card_field->type_ && LikelyCardTypeSelectField(scanner)) {
credit_card_field->type_ = scanner->Cursor();
@@ -312,7 +312,7 @@ bool CreditCardField::LikelyCardTypeSelectField(AutofillScanner* scanner) {
return false;
// We set |ignore_whitespace| to true on these calls because this is actually
- // a pretty common mistake; e.g., "Master Card" instead of "MasterCard".
+ // a pretty common mistake; e.g., "Master card" instead of "Mastercard".
bool isSelect = (AutofillField::FindShortestSubstringMatchInSelect(
l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA), true,
field) >= 0) ||
@@ -425,28 +425,21 @@ bool CreditCardField::ParseExpirationDate(AutofillScanner* scanner) {
// If that fails, do a general regex search.
scanner->RewindTo(month_year_saved_cursor);
- const int kMatchTelAndSelect = MATCH_DEFAULT | MATCH_TELEPHONE | MATCH_SELECT;
- if (ParseFieldSpecifics(scanner,
- base::UTF8ToUTF16(kExpirationMonthRe),
- kMatchTelAndSelect,
- &expiration_month_) &&
- ParseFieldSpecifics(scanner,
- base::UTF8ToUTF16(kExpirationYearRe),
- kMatchTelAndSelect,
- &expiration_year_)) {
+ const int kMatchNumAndTelAndSelect =
+ MATCH_DEFAULT | MATCH_NUMBER | MATCH_TELEPHONE | MATCH_SELECT;
+ if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kExpirationMonthRe),
+ kMatchNumAndTelAndSelect, &expiration_month_) &&
+ ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kExpirationYearRe),
+ kMatchNumAndTelAndSelect, &expiration_year_)) {
return true;
}
// If that fails, look for just MM and/or YY(YY).
scanner->RewindTo(month_year_saved_cursor);
- if (ParseFieldSpecifics(scanner,
- base::ASCIIToUTF16("^mm$"),
- kMatchTelAndSelect,
- &expiration_month_) &&
- ParseFieldSpecifics(scanner,
- base::ASCIIToUTF16("^(yy|yyyy)$"),
- kMatchTelAndSelect,
- &expiration_year_)) {
+ if (ParseFieldSpecifics(scanner, base::ASCIIToUTF16("^mm$"),
+ kMatchNumAndTelAndSelect, &expiration_month_) &&
+ ParseFieldSpecifics(scanner, base::ASCIIToUTF16("^(yy|yyyy)$"),
+ kMatchNumAndTelAndSelect, &expiration_year_)) {
return true;
}
@@ -457,25 +450,21 @@ bool CreditCardField::ParseExpirationDate(AutofillScanner* scanner) {
// Bail out if the field cannot fit a 2-digit year expiration date.
const int current_field_max_length = scanner->Cursor()->max_length;
if (!FieldCanFitDataForFieldType(current_field_max_length,
- CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR)) {
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR))
return false;
- }
// Try to look for a 2-digit year expiration date.
if (ParseFieldSpecifics(scanner,
base::UTF8ToUTF16(kExpirationDate2DigitYearRe),
- kMatchTelAndSelect,
- &expiration_date_)) {
+ kMatchNumAndTelAndSelect, &expiration_date_)) {
exp_year_type_ = CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR;
expiration_month_ = nullptr;
return true;
}
// Try to look for a generic expiration date field. (2 or 4 digit year)
- if (ParseFieldSpecifics(scanner,
- base::UTF8ToUTF16(kExpirationDateRe),
- kMatchTelAndSelect,
- &expiration_date_)) {
+ if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kExpirationDateRe),
+ kMatchNumAndTelAndSelect, &expiration_date_)) {
// If such a field exists, but it cannot fit a 4-digit year expiration
// date, then the likely possibility is that it is a 2-digit year expiration
// date.
@@ -492,8 +481,7 @@ bool CreditCardField::ParseExpirationDate(AutofillScanner* scanner) {
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) &&
ParseFieldSpecifics(scanner,
base::UTF8ToUTF16(kExpirationDate4DigitYearRe),
- kMatchTelAndSelect,
- &expiration_date_)) {
+ kMatchNumAndTelAndSelect, &expiration_date_)) {
expiration_month_ = nullptr;
return true;
}
diff --git a/chromium/components/autofill/core/browser/credit_card_field_unittest.cc b/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
index bb7b6b252d1..89c08040abe 100644
--- a/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
@@ -302,6 +302,7 @@ TEST_F(CreditCardFieldTest, ParseExpMonthYear2) {
}
typedef struct {
+ const std::string cc_fields_form_control_type;
const std::string label;
const int max_length;
const ServerFieldType expected_prediction;
@@ -326,6 +327,7 @@ TEST_P(ParseExpFieldTest, ParseExpField) {
list_.push_back(
base::MakeUnique<AutofillField>(field, ASCIIToUTF16("name1")));
+ field.form_control_type = test_case.cc_fields_form_control_type;
field.label = ASCIIToUTF16("Card Number");
field.name = ASCIIToUTF16("card_number");
list_.push_back(base::MakeUnique<AutofillField>(field, ASCIIToUTF16("num2")));
@@ -375,68 +377,140 @@ INSTANTIATE_TEST_CASE_P(
CreditCardFieldTest,
ParseExpFieldTest,
testing::Values(
+ // CC fields input_type="text"
// General label, no maxlength.
- ParseExpFieldTestCase{"Expiration Date", 0,
+ ParseExpFieldTestCase{"text", "Expiration Date", 0,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// General label, maxlength 4.
- ParseExpFieldTestCase{"Expiration Date", 4,
+ ParseExpFieldTestCase{"text", "Expiration Date", 4,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// General label, maxlength 5.
- ParseExpFieldTestCase{"Expiration Date", 5,
+ ParseExpFieldTestCase{"text", "Expiration Date", 5,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// General label, maxlength 6.
- ParseExpFieldTestCase{"Expiration Date", 6,
+ ParseExpFieldTestCase{"text", "Expiration Date", 6,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// General label, maxlength 7.
- ParseExpFieldTestCase{"Expiration Date", 7,
+ ParseExpFieldTestCase{"text", "Expiration Date", 7,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// General label, large maxlength.
- ParseExpFieldTestCase{"Expiration Date", 12,
+ ParseExpFieldTestCase{"text", "Expiration Date", 12,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// Unsupported maxlength, general label.
- ParseExpFieldTestCase{"Expiration Date", 3, UNKNOWN_TYPE},
+ ParseExpFieldTestCase{"text", "Expiration Date", 3, UNKNOWN_TYPE},
// Unsupported maxlength, two digit year label.
- ParseExpFieldTestCase{"Expiration Date (MM/YY)", 3, UNKNOWN_TYPE},
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YY)", 3,
+ UNKNOWN_TYPE},
// Unsupported maxlength, four digit year label.
- ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 3, UNKNOWN_TYPE},
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YYYY)", 3,
+ UNKNOWN_TYPE},
// Two digit year, simple label.
- ParseExpFieldTestCase{"MM / YY", 0, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ ParseExpFieldTestCase{"text", "MM / YY", 0,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ // Two digit year, with slash (MM/YY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YY)", 0,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ // Two digit year, no slash (MMYY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MMYY)", 4,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ // Two digit year, with slash and maxlength (MM/YY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YY)", 5,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ // Two digit year, with slash and large maxlength (MM/YY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YY)", 12,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+
+ // Four digit year, simple label.
+ ParseExpFieldTestCase{"text", "MM / YYYY", 0,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+ // Four digit year, with slash (MM/YYYY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YYYY)", 0,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+ // Four digit year, no slash (MMYYYY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MMYYYY)", 6,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+ // Four digit year, with slash and maxlength (MM/YYYY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YYYY)", 7,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+ // Four digit year, with slash and large maxlength (MM/YYYY).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YYYY)", 12,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+
+ // Four digit year label with restrictive maxlength (4).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YYYY)", 4,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ // Four digit year label with restrictive maxlength (5).
+ ParseExpFieldTestCase{"text", "Expiration Date (MM/YYYY)", 5,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+
+ // CC fields input_type="number"
+ // General label, no maxlength.
+ ParseExpFieldTestCase{"number", "Expiration Date", 0,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+ // General label, maxlength 4.
+ ParseExpFieldTestCase{"number", "Expiration Date", 4,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ // General label, maxlength 5.
+ ParseExpFieldTestCase{"number", "Expiration Date", 5,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
+ // General label, maxlength 6.
+ ParseExpFieldTestCase{"number", "Expiration Date", 6,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+ // General label, maxlength 7.
+ ParseExpFieldTestCase{"number", "Expiration Date", 7,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+ // General label, large maxlength.
+ ParseExpFieldTestCase{"number", "Expiration Date", 12,
+ CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
+
+ // Unsupported maxlength, general label.
+ ParseExpFieldTestCase{"number", "Expiration Date", 3, UNKNOWN_TYPE},
+ // Unsupported maxlength, two digit year label.
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YY)", 3,
+ UNKNOWN_TYPE},
+ // Unsupported maxlength, four digit year label.
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YYYY)", 3,
+ UNKNOWN_TYPE},
+
+ // Two digit year, simple label.
+ ParseExpFieldTestCase{"number", "MM / YY", 0,
+ CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// Two digit year, with slash (MM/YY).
- ParseExpFieldTestCase{"Expiration Date (MM/YY)", 0,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YY)", 0,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// Two digit year, no slash (MMYY).
- ParseExpFieldTestCase{"Expiration Date (MMYY)", 4,
+ ParseExpFieldTestCase{"number", "Expiration Date (MMYY)", 4,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// Two digit year, with slash and maxlength (MM/YY).
- ParseExpFieldTestCase{"Expiration Date (MM/YY)", 5,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YY)", 5,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// Two digit year, with slash and large maxlength (MM/YY).
- ParseExpFieldTestCase{"Expiration Date (MM/YY)", 12,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YY)", 12,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// Four digit year, simple label.
- ParseExpFieldTestCase{"MM / YYYY", 0,
+ ParseExpFieldTestCase{"number", "MM / YYYY", 0,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// Four digit year, with slash (MM/YYYY).
- ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 0,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YYYY)", 0,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// Four digit year, no slash (MMYYYY).
- ParseExpFieldTestCase{"Expiration Date (MMYYYY)", 6,
+ ParseExpFieldTestCase{"number", "Expiration Date (MMYYYY)", 6,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// Four digit year, with slash and maxlength (MM/YYYY).
- ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 7,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YYYY)", 7,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// Four digit year, with slash and large maxlength (MM/YYYY).
- ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 12,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YYYY)", 12,
CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR},
// Four digit year label with restrictive maxlength (4).
- ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 4,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YYYY)", 4,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
// Four digit year label with restrictive maxlength (5).
- ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 5,
+ ParseExpFieldTestCase{"number", "Expiration Date (MM/YYYY)", 5,
CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}));
TEST_F(CreditCardFieldTest, ParseCreditCardHolderNameWithCCFullName) {
diff --git a/chromium/components/autofill/core/browser/credit_card_unittest.cc b/chromium/components/autofill/core/browser/credit_card_unittest.cc
index 4e371ec4656..3857613b21a 100644
--- a/chromium/components/autofill/core/browser/credit_card_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_unittest.cc
@@ -53,7 +53,10 @@ const char* const kValidNumbers[] = {
"5019717010103742",
"6331101999990016",
"6247130048162403",
+ "4532261615476013542",
+ "6362970000457013",
};
+
const char* const kInvalidNumbers[] = {
"4111 1111 112", /* too short */
"41111111111111111115", /* too long */
@@ -61,7 +64,7 @@ const char* const kInvalidNumbers[] = {
"3056 9309 0259 04aa", /* non-digit characters */
};
-const std::string kUTF8MidlineEllipsis =
+const char kUTF8MidlineEllipsis[] =
" "
"\xE2\x80\xA2\xE2\x80\x86"
"\xE2\x80\xA2\xE2\x80\x86"
@@ -73,80 +76,89 @@ const std::string kUTF8MidlineEllipsis =
// Tests credit card summary string generation. This test simulates a variety
// of different possible summary strings. Variations occur based on the
// existence of credit card number, month, and year fields.
-TEST(CreditCardTest, PreviewSummaryAndTypeAndLastFourDigitsStrings) {
+TEST(CreditCardTest, PreviewSummaryAndNetworkAndLastFourDigitsStrings) {
// Case 0: empty credit card.
CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com/");
base::string16 summary0 = credit_card0.Label();
EXPECT_EQ(base::string16(), summary0);
- base::string16 obfuscated0 = credit_card0.TypeAndLastFourDigits();
- EXPECT_EQ(ASCIIToUTF16("Card"), obfuscated0);
+ base::string16 obfuscated0 = credit_card0.NetworkAndLastFourDigits();
+ EXPECT_EQ(ASCIIToUTF16(std::string("Card")), obfuscated0);
// Case 00: Empty credit card with empty strings.
CreditCard credit_card00(base::GenerateGUID(), "https://www.example.com/");
- test::SetCreditCardInfo(&credit_card00,"John Dillinger", "", "", "");
+ test::SetCreditCardInfo(&credit_card00, "John Dillinger", "", "", "", "");
base::string16 summary00 = credit_card00.Label();
EXPECT_EQ(base::string16(ASCIIToUTF16("John Dillinger")), summary00);
- base::string16 obfuscated00 = credit_card00.TypeAndLastFourDigits();
- EXPECT_EQ(ASCIIToUTF16("Card"), obfuscated00);
+ base::string16 obfuscated00 = credit_card00.NetworkAndLastFourDigits();
+ EXPECT_EQ(ASCIIToUTF16(std::string("Card")), obfuscated00);
// Case 1: No credit card number.
CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com/");
- test::SetCreditCardInfo(&credit_card1,"John Dillinger", "", "01", "2010");
+ test::SetCreditCardInfo(&credit_card1, "John Dillinger", "", "01", "2010",
+ "1");
base::string16 summary1 = credit_card1.Label();
EXPECT_EQ(base::string16(ASCIIToUTF16("John Dillinger")), summary1);
- base::string16 obfuscated1 = credit_card1.TypeAndLastFourDigits();
- EXPECT_EQ(ASCIIToUTF16("Card"), obfuscated1);
+ base::string16 obfuscated1 = credit_card1.NetworkAndLastFourDigits();
+ EXPECT_EQ(ASCIIToUTF16(std::string("Card")), obfuscated1);
// Case 2: No month.
CreditCard credit_card2(base::GenerateGUID(), "https://www.example.com/");
- test::SetCreditCardInfo(
- &credit_card2, "John Dillinger", "5105 1051 0510 5100", "", "2010");
+ test::SetCreditCardInfo(&credit_card2, "John Dillinger",
+ "5105 1051 0510 5100", "", "2010", "1");
base::string16 summary2 = credit_card2.Label();
- EXPECT_EQ(UTF8ToUTF16("MasterCard" + kUTF8MidlineEllipsis + "5100"),
- summary2);
- base::string16 obfuscated2 = credit_card2.TypeAndLastFourDigits();
- EXPECT_EQ(UTF8ToUTF16("MasterCard" + kUTF8MidlineEllipsis + "5100"),
- obfuscated2);
+ EXPECT_EQ(
+ UTF8ToUTF16(std::string("Mastercard") + kUTF8MidlineEllipsis + "5100"),
+ summary2);
+ base::string16 obfuscated2 = credit_card2.NetworkAndLastFourDigits();
+ EXPECT_EQ(
+ UTF8ToUTF16(std::string("Mastercard") + kUTF8MidlineEllipsis + "5100"),
+ obfuscated2);
// Case 3: No year.
CreditCard credit_card3(base::GenerateGUID(), "https://www.example.com/");
- test::SetCreditCardInfo(
- &credit_card3, "John Dillinger", "5105 1051 0510 5100", "01", "");
+ test::SetCreditCardInfo(&credit_card3, "John Dillinger",
+ "5105 1051 0510 5100", "01", "", "1");
base::string16 summary3 = credit_card3.Label();
- EXPECT_EQ(UTF8ToUTF16("MasterCard" + kUTF8MidlineEllipsis + "5100"),
- summary3);
- base::string16 obfuscated3 = credit_card3.TypeAndLastFourDigits();
- EXPECT_EQ(UTF8ToUTF16("MasterCard" + kUTF8MidlineEllipsis + "5100"),
- obfuscated3);
+ EXPECT_EQ(
+ UTF8ToUTF16(std::string("Mastercard") + kUTF8MidlineEllipsis + "5100"),
+ summary3);
+ base::string16 obfuscated3 = credit_card3.NetworkAndLastFourDigits();
+ EXPECT_EQ(
+ UTF8ToUTF16(std::string("Mastercard") + kUTF8MidlineEllipsis + "5100"),
+ obfuscated3);
// Case 4: Have everything.
CreditCard credit_card4(base::GenerateGUID(), "https://www.example.com/");
- test::SetCreditCardInfo(
- &credit_card4, "John Dillinger", "5105 1051 0510 5100", "01", "2010");
+ test::SetCreditCardInfo(&credit_card4, "John Dillinger",
+ "5105 1051 0510 5100", "01", "2010", "1");
base::string16 summary4 = credit_card4.Label();
- EXPECT_EQ(UTF8ToUTF16("MasterCard" + kUTF8MidlineEllipsis + "5100, 01/2010"),
+ EXPECT_EQ(UTF8ToUTF16(std::string("Mastercard") + kUTF8MidlineEllipsis +
+ "5100, 01/2010"),
summary4);
- base::string16 obfuscated4 = credit_card4.TypeAndLastFourDigits();
- EXPECT_EQ(UTF8ToUTF16("MasterCard" + kUTF8MidlineEllipsis + "5100"),
- obfuscated4);
+ base::string16 obfuscated4 = credit_card4.NetworkAndLastFourDigits();
+ EXPECT_EQ(
+ UTF8ToUTF16(std::string("Mastercard") + kUTF8MidlineEllipsis + "5100"),
+ obfuscated4);
// Case 5: Very long credit card
CreditCard credit_card5(base::GenerateGUID(), "https://www.example.com/");
test::SetCreditCardInfo(
- &credit_card5,
- "John Dillinger",
- "0123456789 0123456789 0123456789 5105 1051 0510 5100", "01", "2010");
+ &credit_card5, "John Dillinger",
+ "0123456789 0123456789 0123456789 5105 1051 0510 5100", "01", "2010",
+ "1");
base::string16 summary5 = credit_card5.Label();
- EXPECT_EQ(UTF8ToUTF16("Card" + kUTF8MidlineEllipsis + "5100, 01/2010"),
- summary5);
- base::string16 obfuscated5 = credit_card5.TypeAndLastFourDigits();
- EXPECT_EQ(UTF8ToUTF16("Card" + kUTF8MidlineEllipsis + "5100"),
+ EXPECT_EQ(
+ UTF8ToUTF16(std::string("Card") + kUTF8MidlineEllipsis + "5100, 01/2010"),
+ summary5);
+ base::string16 obfuscated5 = credit_card5.NetworkAndLastFourDigits();
+ EXPECT_EQ(UTF8ToUTF16(std::string("Card") + kUTF8MidlineEllipsis + "5100"),
obfuscated5);
}
TEST(CreditCardTest, AssignmentOperator) {
CreditCard a(base::GenerateGUID(), "some origin");
- test::SetCreditCardInfo(&a, "John Dillinger", "123456789012", "01", "2010");
+ test::SetCreditCardInfo(&a, "John Dillinger", "123456789012", "01", "2010",
+ "1");
// Result of assignment should be logically equal to the original profile.
CreditCard b(base::GenerateGUID(), "some other origin");
@@ -244,7 +256,8 @@ INSTANTIATE_TEST_CASE_P(
TEST(CreditCardTest, Copy) {
CreditCard a(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&a, "John Dillinger", "123456789012", "01", "2010");
+ test::SetCreditCardInfo(&a, "John Dillinger", "123456789012", "01", "2010",
+ base::GenerateGUID());
// Clone should be logically equal to the original.
CreditCard b(a);
@@ -257,13 +270,15 @@ struct IsLocalDuplicateOfServerCardTestCase {
const char* first_card_number;
const char* first_card_exp_mo;
const char* first_card_exp_yr;
+ const char* first_billing_address_id;
CreditCard::RecordType second_card_record_type;
const char* second_card_name;
const char* second_card_number;
const char* second_card_exp_mo;
const char* second_card_exp_yr;
- const char* second_card_type;
+ const char* second_billing_address_id;
+ const char* second_card_issuer_network;
bool is_local_duplicate;
};
@@ -277,16 +292,18 @@ TEST_P(IsLocalDuplicateOfServerCardTest, IsLocalDuplicateOfServerCard) {
a.set_record_type(test_case.first_card_record_type);
test::SetCreditCardInfo(
&a, test_case.first_card_name, test_case.first_card_number,
- test_case.first_card_exp_mo, test_case.first_card_exp_yr);
+ test_case.first_card_exp_mo, test_case.first_card_exp_yr,
+ test_case.first_billing_address_id);
CreditCard b(base::GenerateGUID(), std::string());
b.set_record_type(test_case.second_card_record_type);
test::SetCreditCardInfo(
&b, test_case.second_card_name, test_case.second_card_number,
- test_case.second_card_exp_mo, test_case.second_card_exp_yr);
+ test_case.second_card_exp_mo, test_case.second_card_exp_yr,
+ test_case.second_billing_address_id);
if (test_case.second_card_record_type == CreditCard::MASKED_SERVER_CARD)
- b.SetTypeForMaskedCard(test_case.second_card_type);
+ b.SetNetworkForMaskedCard(test_case.second_card_issuer_network);
EXPECT_EQ(test_case.is_local_duplicate, a.IsLocalDuplicateOfServerCard(b))
<< " when comparing cards " << a.Label() << " and " << b.Label();
@@ -296,39 +313,43 @@ INSTANTIATE_TEST_CASE_P(
CreditCardTest,
IsLocalDuplicateOfServerCardTest,
testing::Values(
- IsLocalDuplicateOfServerCardTestCase{LOCAL_CARD, "", "", "", "",
- LOCAL_CARD, "", "", "", "",
+ IsLocalDuplicateOfServerCardTestCase{LOCAL_CARD, "", "", "", "", "",
+ LOCAL_CARD, "", "", "", "", "",
nullptr, false},
- IsLocalDuplicateOfServerCardTestCase{LOCAL_CARD, "", "", "", "",
+ IsLocalDuplicateOfServerCardTestCase{LOCAL_CARD, "", "", "", "", "",
FULL_SERVER_CARD, "", "", "", "",
- nullptr, true},
+ "", nullptr, true},
IsLocalDuplicateOfServerCardTestCase{FULL_SERVER_CARD, "", "", "", "",
- FULL_SERVER_CARD, "", "", "", "",
- nullptr, false},
+ "", FULL_SERVER_CARD, "", "", "",
+ "", "", nullptr, false},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "John Dillinger", "423456789012", "01", "2010",
+ LOCAL_CARD, "John Dillinger", "423456789012", "01", "2010", "1",
FULL_SERVER_CARD, "John Dillinger", "423456789012", "01", "2010",
- nullptr, true},
+ "1", nullptr, true},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "J Dillinger", "423456789012", "01", "2010",
+ LOCAL_CARD, "J Dillinger", "423456789012", "01", "2010", "1",
FULL_SERVER_CARD, "John Dillinger", "423456789012", "01", "2010",
- nullptr, false},
+ "1", nullptr, false},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "", "423456789012", "01", "2010", FULL_SERVER_CARD,
- "John Dillinger", "423456789012", "01", "2010", nullptr, true},
+ LOCAL_CARD, "", "423456789012", "01", "2010", "1", FULL_SERVER_CARD,
+ "John Dillinger", "423456789012", "01", "2010", "1", nullptr, true},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "", "423456789012", "", "", FULL_SERVER_CARD,
- "John Dillinger", "423456789012", "01", "2010", nullptr, true},
+ LOCAL_CARD, "", "423456789012", "", "", "1", FULL_SERVER_CARD,
+ "John Dillinger", "423456789012", "01", "2010", "1", nullptr, true},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "", "423456789012", "", "", MASKED_SERVER_CARD,
- "John Dillinger", "9012", "01", "2010", kVisaCard, true},
+ LOCAL_CARD, "", "423456789012", "", "", "1", MASKED_SERVER_CARD,
+ "John Dillinger", "9012", "01", "2010", "1", kVisaCard, true},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "", "423456789012", "", "", MASKED_SERVER_CARD,
- "John Dillinger", "9012", "01", "2010", kMasterCard, false},
+ LOCAL_CARD, "", "423456789012", "", "", "1", MASKED_SERVER_CARD,
+ "John Dillinger", "9012", "01", "2010", "1", kMasterCard, false},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "John Dillinger", "4234-5678-9012", "01", "2010",
+ LOCAL_CARD, "John Dillinger", "4234-5678-9012", "01", "2010", "1",
FULL_SERVER_CARD, "John Dillinger", "423456789012", "01", "2010",
- nullptr, true}));
+ "1", nullptr, true},
+ IsLocalDuplicateOfServerCardTestCase{
+ LOCAL_CARD, "John Dillinger", "4234-5678-9012", "01", "2010", "1",
+ FULL_SERVER_CARD, "John Dillinger", "423456789012", "01", "2010",
+ "2", nullptr, false}));
TEST(CreditCardTest, HasSameNumberAs) {
CreditCard a(base::GenerateGUID(), std::string());
@@ -383,15 +404,12 @@ TEST(CreditCardTest, Compare) {
EXPECT_EQ(0, a.Compare(b));
// Different values produce non-zero results.
- test::SetCreditCardInfo(&a, "Jimmy", NULL, NULL, NULL);
- test::SetCreditCardInfo(&b, "Ringo", NULL, NULL, NULL);
+ test::SetCreditCardInfo(&a, "Jimmy", NULL, NULL, NULL, "");
+ test::SetCreditCardInfo(&b, "Ringo", NULL, NULL, NULL, "");
EXPECT_GT(0, a.Compare(b));
EXPECT_LT(0, b.Compare(a));
}
-// This method is not compiled for iOS because these resources are not used and
-// should not be shipped.
-#if !defined(OS_IOS)
// Test we get the correct icon for each card type.
TEST(CreditCardTest, IconResourceId) {
EXPECT_EQ(IDR_AUTOFILL_CC_AMEX,
@@ -400,21 +418,24 @@ TEST(CreditCardTest, IconResourceId) {
CreditCard::IconResourceId(kDinersCard));
EXPECT_EQ(IDR_AUTOFILL_CC_DISCOVER,
CreditCard::IconResourceId(kDiscoverCard));
+ EXPECT_EQ(IDR_AUTOFILL_CC_ELO,
+ CreditCard::IconResourceId(kEloCard));
EXPECT_EQ(IDR_AUTOFILL_CC_JCB,
CreditCard::IconResourceId(kJCBCard));
EXPECT_EQ(IDR_AUTOFILL_CC_MASTERCARD,
CreditCard::IconResourceId(kMasterCard));
EXPECT_EQ(IDR_AUTOFILL_CC_MIR,
CreditCard::IconResourceId(kMirCard));
+ EXPECT_EQ(IDR_AUTOFILL_CC_UNIONPAY,
+ CreditCard::IconResourceId(kUnionPay));
EXPECT_EQ(IDR_AUTOFILL_CC_VISA,
CreditCard::IconResourceId(kVisaCard));
}
-#endif // #if !defined(OS_IOS)
TEST(CreditCardTest, UpdateFromImportedCard) {
CreditCard original_card(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(
- &original_card, "John Dillinger", "123456789012", "09", "2017");
+ test::SetCreditCardInfo(&original_card, "John Dillinger", "123456789012",
+ "09", "2017", "1");
CreditCard a = original_card;
@@ -569,8 +590,8 @@ TEST(CreditCardTest, IsValid) {
TEST(CreditCardTest, SetRawInfoCreditCardNumber) {
CreditCard card(base::GenerateGUID(), "https://www.example.com/");
- test::SetCreditCardInfo(&card, "Bob Dylan",
- "4321-5432-6543-xxxx", "07", "2013");
+ test::SetCreditCardInfo(&card, "Bob Dylan", "4321-5432-6543-xxxx", "07",
+ "2013", "1");
EXPECT_EQ(ASCIIToUTF16("4321-5432-6543-xxxx"),
card.GetRawInfo(CREDIT_CARD_NUMBER));
}
@@ -628,229 +649,231 @@ TEST(CreditCardTest, CreditCardVerificationCode) {
EXPECT_EQ(base::string16(), card.GetRawInfo(CREDIT_CARD_VERIFICATION_CODE));
}
-struct GetCreditCardTypeTestCase {
+struct GetCardNetworkTestCase {
std::string card_number;
- std::string type;
+ std::string issuer_network;
bool is_valid;
};
// We are doing batches here because INSTANTIATE_TEST_CASE_P has a
// 50 upper limit.
-class GetCreditCardTypeTestBatch1
- : public testing::TestWithParam<GetCreditCardTypeTestCase> {};
+class GetCardNetworkTestBatch1
+ : public testing::TestWithParam<GetCardNetworkTestCase> {};
-TEST_P(GetCreditCardTypeTestBatch1, GetCreditCardType) {
+TEST_P(GetCardNetworkTestBatch1, GetCardNetwork) {
auto test_case = GetParam();
base::string16 card_number = ASCIIToUTF16(test_case.card_number);
SCOPED_TRACE(card_number);
- EXPECT_EQ(test_case.type, CreditCard::GetCreditCardType(card_number));
+ EXPECT_EQ(test_case.issuer_network, CreditCard::GetCardNetwork(card_number));
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
INSTANTIATE_TEST_CASE_P(
CreditCardTest,
- GetCreditCardTypeTestBatch1,
+ GetCardNetworkTestBatch1,
testing::Values(
// The relevant sample numbers from
// http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
- GetCreditCardTypeTestCase{"378282246310005", kAmericanExpressCard,
- true},
- GetCreditCardTypeTestCase{"371449635398431", kAmericanExpressCard,
- true},
- GetCreditCardTypeTestCase{"378734493671000", kAmericanExpressCard,
- true},
- GetCreditCardTypeTestCase{"30569309025904", kDinersCard, true},
- GetCreditCardTypeTestCase{"38520000023237", kDinersCard, true},
- GetCreditCardTypeTestCase{"6011111111111117", kDiscoverCard, true},
- GetCreditCardTypeTestCase{"6011000990139424", kDiscoverCard, true},
- GetCreditCardTypeTestCase{"3530111333300000", kJCBCard, true},
- GetCreditCardTypeTestCase{"3566002020360505", kJCBCard, true},
- GetCreditCardTypeTestCase{"5555555555554444", kMasterCard, true},
- GetCreditCardTypeTestCase{"5105105105105100", kMasterCard, true},
- GetCreditCardTypeTestCase{"4111111111111111", kVisaCard, true},
- GetCreditCardTypeTestCase{"4012888888881881", kVisaCard, true},
- GetCreditCardTypeTestCase{"4222222222222", kVisaCard, true},
+ GetCardNetworkTestCase{"378282246310005", kAmericanExpressCard, true},
+ GetCardNetworkTestCase{"371449635398431", kAmericanExpressCard, true},
+ GetCardNetworkTestCase{"378734493671000", kAmericanExpressCard, true},
+ GetCardNetworkTestCase{"30569309025904", kDinersCard, true},
+ GetCardNetworkTestCase{"38520000023237", kDinersCard, true},
+ GetCardNetworkTestCase{"6011111111111117", kDiscoverCard, true},
+ GetCardNetworkTestCase{"6011000990139424", kDiscoverCard, true},
+ GetCardNetworkTestCase{"3530111333300000", kJCBCard, true},
+ GetCardNetworkTestCase{"3566002020360505", kJCBCard, true},
+ GetCardNetworkTestCase{"5555555555554444", kMasterCard, true},
+ GetCardNetworkTestCase{"5105105105105100", kMasterCard, true},
+ GetCardNetworkTestCase{"4111111111111111", kVisaCard, true},
+ GetCardNetworkTestCase{"4012888888881881", kVisaCard, true},
+ GetCardNetworkTestCase{"4222222222222", kVisaCard, true},
+ GetCardNetworkTestCase{"4532261615476013542", kVisaCard, true},
// The relevant sample numbers from
// https://www.auricsystems.com/sample-credit-card-numbers/
- GetCreditCardTypeTestCase{"343434343434343", kAmericanExpressCard,
- true},
- GetCreditCardTypeTestCase{"371144371144376", kAmericanExpressCard,
- true},
- GetCreditCardTypeTestCase{"341134113411347", kAmericanExpressCard,
- true},
- GetCreditCardTypeTestCase{"36438936438936", kDinersCard, true},
- GetCreditCardTypeTestCase{"36110361103612", kDinersCard, true},
- GetCreditCardTypeTestCase{"36111111111111", kDinersCard, true},
- GetCreditCardTypeTestCase{"6011016011016011", kDiscoverCard, true},
- GetCreditCardTypeTestCase{"6011000990139424", kDiscoverCard, true},
- GetCreditCardTypeTestCase{"6011000000000004", kDiscoverCard, true},
- GetCreditCardTypeTestCase{"6011000995500000", kDiscoverCard, true},
- GetCreditCardTypeTestCase{"6500000000000002", kDiscoverCard, true},
- GetCreditCardTypeTestCase{"3566002020360505", kJCBCard, true},
- GetCreditCardTypeTestCase{"3528000000000007", kJCBCard, true},
- GetCreditCardTypeTestCase{"5500005555555559", kMasterCard, true},
- GetCreditCardTypeTestCase{"5555555555555557", kMasterCard, true},
- GetCreditCardTypeTestCase{"5454545454545454", kMasterCard, true},
- GetCreditCardTypeTestCase{"5555515555555551", kMasterCard, true},
- GetCreditCardTypeTestCase{"5405222222222226", kMasterCard, true},
- GetCreditCardTypeTestCase{"5478050000000007", kMasterCard, true},
- GetCreditCardTypeTestCase{"5111005111051128", kMasterCard, true},
- GetCreditCardTypeTestCase{"5112345112345114", kMasterCard, true},
- GetCreditCardTypeTestCase{"5115915115915118", kMasterCard, true},
- GetCreditCardTypeTestCase{"6247130048162403", kUnionPay, true},
- GetCreditCardTypeTestCase{"6247130048162403", kUnionPay, true},
- GetCreditCardTypeTestCase{"622384452162063648", kUnionPay, true},
- GetCreditCardTypeTestCase{"2204883716636153", kMirCard, true},
- GetCreditCardTypeTestCase{"2200111234567898", kMirCard, true},
- GetCreditCardTypeTestCase{"2200481349288130", kMirCard, true},
+ GetCardNetworkTestCase{"343434343434343", kAmericanExpressCard, true},
+ GetCardNetworkTestCase{"371144371144376", kAmericanExpressCard, true},
+ GetCardNetworkTestCase{"341134113411347", kAmericanExpressCard, true},
+ GetCardNetworkTestCase{"36438936438936", kDinersCard, true},
+ GetCardNetworkTestCase{"36110361103612", kDinersCard, true},
+ GetCardNetworkTestCase{"36111111111111", kDinersCard, true},
+ GetCardNetworkTestCase{"6011016011016011", kDiscoverCard, true},
+ GetCardNetworkTestCase{"6011000990139424", kDiscoverCard, true},
+ GetCardNetworkTestCase{"6011000000000004", kDiscoverCard, true},
+ GetCardNetworkTestCase{"6011000995500000", kDiscoverCard, true},
+ GetCardNetworkTestCase{"6500000000000002", kDiscoverCard, true},
+ GetCardNetworkTestCase{"3566002020360505", kJCBCard, true},
+ GetCardNetworkTestCase{"3528000000000007", kJCBCard, true},
+ GetCardNetworkTestCase{"2222400061240016", kMasterCard, true},
+ GetCardNetworkTestCase{"2223000048400011", kMasterCard, true},
+ GetCardNetworkTestCase{"5500005555555559", kMasterCard, true},
+ GetCardNetworkTestCase{"5555555555555557", kMasterCard, true},
+ GetCardNetworkTestCase{"5454545454545454", kMasterCard, true},
+ GetCardNetworkTestCase{"5478050000000007", kMasterCard, true},
+ GetCardNetworkTestCase{"5112345112345114", kMasterCard, true},
+ GetCardNetworkTestCase{"5115915115915118", kMasterCard, true},
+ GetCardNetworkTestCase{"6247130048162403", kUnionPay, true},
+ GetCardNetworkTestCase{"6247130048162403", kUnionPay, true},
+ GetCardNetworkTestCase{"622384452162063648", kUnionPay, true},
+ GetCardNetworkTestCase{"2204883716636153", kMirCard, true},
+ GetCardNetworkTestCase{"2200111234567898", kMirCard, true},
+ GetCardNetworkTestCase{"2200481349288130", kMirCard, true},
+
+ // The relevant sample numbers from
+ // https://www.bincodes.com/bank-creditcard-generator/ and
+ // https://www.ebanx.com/business/en/developers/integrations/testing/credit-card-test-numbers
+ GetCardNetworkTestCase{"5067001446391275", kEloCard, true},
+ GetCardNetworkTestCase{"6362970000457013", kEloCard, true},
// Empty string
- GetCreditCardTypeTestCase{std::string(), kGenericCard, false},
+ GetCardNetworkTestCase{std::string(), kGenericCard, false},
// Non-numeric
- GetCreditCardTypeTestCase{"garbage", kGenericCard, false},
- GetCreditCardTypeTestCase{"4garbage", kVisaCard, false},
+ GetCardNetworkTestCase{"garbage", kGenericCard, false},
+ GetCardNetworkTestCase{"4garbage", kVisaCard, false},
// Fails Luhn check.
- GetCreditCardTypeTestCase{"4111111111111112", kVisaCard, false},
- GetCreditCardTypeTestCase{"6247130048162413", kUnionPay, false},
- GetCreditCardTypeTestCase{"2204883716636154", kMirCard, false}));
+ GetCardNetworkTestCase{"4111111111111112", kVisaCard, false},
+ GetCardNetworkTestCase{"6247130048162413", kUnionPay, false},
+ GetCardNetworkTestCase{"2204883716636154", kMirCard, false}));
-class GetCreditCardTypeTestBatch2
- : public testing::TestWithParam<GetCreditCardTypeTestCase> {};
+class GetCardNetworkTestBatch2
+ : public testing::TestWithParam<GetCardNetworkTestCase> {};
-TEST_P(GetCreditCardTypeTestBatch2, GetCreditCardType) {
+TEST_P(GetCardNetworkTestBatch2, GetCardNetwork) {
auto test_case = GetParam();
base::string16 card_number = ASCIIToUTF16(test_case.card_number);
SCOPED_TRACE(card_number);
- EXPECT_EQ(test_case.type, CreditCard::GetCreditCardType(card_number));
+ EXPECT_EQ(test_case.issuer_network, CreditCard::GetCardNetwork(card_number));
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
INSTANTIATE_TEST_CASE_P(
CreditCardTest,
- GetCreditCardTypeTestBatch2,
+ GetCardNetworkTestBatch2,
testing::Values(
// Invalid length.
- GetCreditCardTypeTestCase{"3434343434343434", kAmericanExpressCard,
- false},
- GetCreditCardTypeTestCase{"411111111111116", kVisaCard, false},
- GetCreditCardTypeTestCase{"220011123456783", kMirCard, false},
+ GetCardNetworkTestCase{"3434343434343434", kAmericanExpressCard, false},
+ GetCardNetworkTestCase{"411111111111116", kVisaCard, false},
+ GetCardNetworkTestCase{"220011123456783", kMirCard, false},
// Issuer Identification Numbers (IINs) that Chrome recognizes.
- GetCreditCardTypeTestCase{"4", kVisaCard, false},
- GetCreditCardTypeTestCase{"22", kMirCard, false},
- GetCreditCardTypeTestCase{"34", kAmericanExpressCard, false},
- GetCreditCardTypeTestCase{"37", kAmericanExpressCard, false},
- GetCreditCardTypeTestCase{"300", kDinersCard, false},
- GetCreditCardTypeTestCase{"301", kDinersCard, false},
- GetCreditCardTypeTestCase{"302", kDinersCard, false},
- GetCreditCardTypeTestCase{"303", kDinersCard, false},
- GetCreditCardTypeTestCase{"304", kDinersCard, false},
- GetCreditCardTypeTestCase{"305", kDinersCard, false},
- GetCreditCardTypeTestCase{"3095", kDinersCard, false},
- GetCreditCardTypeTestCase{"36", kDinersCard, false},
- GetCreditCardTypeTestCase{"38", kDinersCard, false},
- GetCreditCardTypeTestCase{"39", kDinersCard, false},
- GetCreditCardTypeTestCase{"6011", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"644", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"645", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"646", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"647", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"648", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"649", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"65", kDiscoverCard, false},
- GetCreditCardTypeTestCase{"3528", kJCBCard, false},
- GetCreditCardTypeTestCase{"3531", kJCBCard, false},
- GetCreditCardTypeTestCase{"3589", kJCBCard, false},
- GetCreditCardTypeTestCase{"51", kMasterCard, false},
- GetCreditCardTypeTestCase{"52", kMasterCard, false},
- GetCreditCardTypeTestCase{"53", kMasterCard, false},
- GetCreditCardTypeTestCase{"54", kMasterCard, false},
- GetCreditCardTypeTestCase{"55", kMasterCard, false},
- GetCreditCardTypeTestCase{"62", kUnionPay, false},
+ GetCardNetworkTestCase{"4", kVisaCard, false},
+ GetCardNetworkTestCase{"2200", kMirCard, false},
+ GetCardNetworkTestCase{"2202", kMirCard, false},
+ GetCardNetworkTestCase{"2204", kMirCard, false},
+ GetCardNetworkTestCase{"2221", kMasterCard, false},
+ GetCardNetworkTestCase{"2720", kMasterCard, false},
+ GetCardNetworkTestCase{"34", kAmericanExpressCard, false},
+ GetCardNetworkTestCase{"37", kAmericanExpressCard, false},
+ GetCardNetworkTestCase{"300", kDinersCard, false},
+ GetCardNetworkTestCase{"301", kDinersCard, false},
+ GetCardNetworkTestCase{"302", kDinersCard, false},
+ GetCardNetworkTestCase{"303", kDinersCard, false},
+ GetCardNetworkTestCase{"304", kDinersCard, false},
+ GetCardNetworkTestCase{"305", kDinersCard, false},
+ GetCardNetworkTestCase{"309", kDinersCard, false},
+ GetCardNetworkTestCase{"36", kDinersCard, false},
+ GetCardNetworkTestCase{"38", kDinersCard, false},
+ GetCardNetworkTestCase{"39", kDinersCard, false},
+ GetCardNetworkTestCase{"6011", kDiscoverCard, false},
+ GetCardNetworkTestCase{"644", kDiscoverCard, false},
+ GetCardNetworkTestCase{"645", kDiscoverCard, false},
+ GetCardNetworkTestCase{"646", kDiscoverCard, false},
+ GetCardNetworkTestCase{"647", kDiscoverCard, false},
+ GetCardNetworkTestCase{"648", kDiscoverCard, false},
+ GetCardNetworkTestCase{"649", kDiscoverCard, false},
+ GetCardNetworkTestCase{"65", kDiscoverCard, false},
+ GetCardNetworkTestCase{"5067", kEloCard, false},
+ GetCardNetworkTestCase{"5090", kEloCard, false},
+ GetCardNetworkTestCase{"636297", kEloCard, false},
+ GetCardNetworkTestCase{"3528", kJCBCard, false},
+ GetCardNetworkTestCase{"3531", kJCBCard, false},
+ GetCardNetworkTestCase{"3589", kJCBCard, false},
+ GetCardNetworkTestCase{"51", kMasterCard, false},
+ GetCardNetworkTestCase{"52", kMasterCard, false},
+ GetCardNetworkTestCase{"53", kMasterCard, false},
+ GetCardNetworkTestCase{"54", kMasterCard, false},
+ GetCardNetworkTestCase{"55", kMasterCard, false},
+ GetCardNetworkTestCase{"62", kUnionPay, false},
// Not enough data to determine an IIN uniquely.
- GetCreditCardTypeTestCase{"2", kGenericCard, false},
- GetCreditCardTypeTestCase{"3", kGenericCard, false},
- GetCreditCardTypeTestCase{"30", kGenericCard, false},
- GetCreditCardTypeTestCase{"309", kGenericCard, false},
- GetCreditCardTypeTestCase{"35", kGenericCard, false},
- GetCreditCardTypeTestCase{"5", kGenericCard, false},
- GetCreditCardTypeTestCase{"6", kGenericCard, false},
- GetCreditCardTypeTestCase{"60", kGenericCard, false},
- GetCreditCardTypeTestCase{"601", kGenericCard, false},
- GetCreditCardTypeTestCase{"64", kGenericCard, false}));
-
-class GetCreditCardTypeTestBatch3
- : public testing::TestWithParam<GetCreditCardTypeTestCase> {};
-
-TEST_P(GetCreditCardTypeTestBatch3, GetCreditCardType) {
+ GetCardNetworkTestCase{"2", kGenericCard, false},
+ GetCardNetworkTestCase{"3", kGenericCard, false},
+ GetCardNetworkTestCase{"30", kGenericCard, false},
+ GetCardNetworkTestCase{"35", kGenericCard, false},
+ GetCardNetworkTestCase{"5", kGenericCard, false},
+ GetCardNetworkTestCase{"6", kGenericCard, false},
+ GetCardNetworkTestCase{"60", kGenericCard, false},
+ GetCardNetworkTestCase{"601", kGenericCard, false},
+ GetCardNetworkTestCase{"64", kGenericCard, false}));
+
+class GetCardNetworkTestBatch3
+ : public testing::TestWithParam<GetCardNetworkTestCase> {};
+
+TEST_P(GetCardNetworkTestBatch3, GetCardNetwork) {
auto test_case = GetParam();
base::string16 card_number = ASCIIToUTF16(test_case.card_number);
SCOPED_TRACE(card_number);
- EXPECT_EQ(test_case.type, CreditCard::GetCreditCardType(card_number));
+ EXPECT_EQ(test_case.issuer_network, CreditCard::GetCardNetwork(card_number));
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
INSTANTIATE_TEST_CASE_P(
CreditCardTest,
- GetCreditCardTypeTestBatch3,
+ GetCardNetworkTestBatch3,
testing::Values(
// Unknown IINs.
- GetCreditCardTypeTestCase{"0", kGenericCard, false},
- GetCreditCardTypeTestCase{"1", kGenericCard, false},
- GetCreditCardTypeTestCase{"306", kGenericCard, false},
- GetCreditCardTypeTestCase{"307", kGenericCard, false},
- GetCreditCardTypeTestCase{"308", kGenericCard, false},
- GetCreditCardTypeTestCase{"3091", kGenericCard, false},
- GetCreditCardTypeTestCase{"3094", kGenericCard, false},
- GetCreditCardTypeTestCase{"3096", kGenericCard, false},
- GetCreditCardTypeTestCase{"31", kGenericCard, false},
- GetCreditCardTypeTestCase{"32", kGenericCard, false},
- GetCreditCardTypeTestCase{"33", kGenericCard, false},
- GetCreditCardTypeTestCase{"351", kGenericCard, false},
- GetCreditCardTypeTestCase{"3527", kGenericCard, false},
- GetCreditCardTypeTestCase{"359", kGenericCard, false},
- GetCreditCardTypeTestCase{"50", kGenericCard, false},
- GetCreditCardTypeTestCase{"56", kGenericCard, false},
- GetCreditCardTypeTestCase{"57", kGenericCard, false},
- GetCreditCardTypeTestCase{"58", kGenericCard, false},
- GetCreditCardTypeTestCase{"59", kGenericCard, false},
- GetCreditCardTypeTestCase{"600", kGenericCard, false},
- GetCreditCardTypeTestCase{"602", kGenericCard, false},
- GetCreditCardTypeTestCase{"603", kGenericCard, false},
- GetCreditCardTypeTestCase{"604", kGenericCard, false},
- GetCreditCardTypeTestCase{"605", kGenericCard, false},
- GetCreditCardTypeTestCase{"606", kGenericCard, false},
- GetCreditCardTypeTestCase{"607", kGenericCard, false},
- GetCreditCardTypeTestCase{"608", kGenericCard, false},
- GetCreditCardTypeTestCase{"609", kGenericCard, false},
- GetCreditCardTypeTestCase{"61", kGenericCard, false},
- GetCreditCardTypeTestCase{"63", kGenericCard, false},
- GetCreditCardTypeTestCase{"640", kGenericCard, false},
- GetCreditCardTypeTestCase{"641", kGenericCard, false},
- GetCreditCardTypeTestCase{"642", kGenericCard, false},
- GetCreditCardTypeTestCase{"643", kGenericCard, false},
- GetCreditCardTypeTestCase{"66", kGenericCard, false},
- GetCreditCardTypeTestCase{"67", kGenericCard, false},
- GetCreditCardTypeTestCase{"68", kGenericCard, false},
- GetCreditCardTypeTestCase{"69", kGenericCard, false},
- GetCreditCardTypeTestCase{"7", kGenericCard, false},
- GetCreditCardTypeTestCase{"8", kGenericCard, false},
- GetCreditCardTypeTestCase{"9", kGenericCard, false},
+ GetCardNetworkTestCase{"0", kGenericCard, false},
+ GetCardNetworkTestCase{"1", kGenericCard, false},
+ GetCardNetworkTestCase{"306", kGenericCard, false},
+ GetCardNetworkTestCase{"307", kGenericCard, false},
+ GetCardNetworkTestCase{"308", kGenericCard, false},
+ GetCardNetworkTestCase{"31", kGenericCard, false},
+ GetCardNetworkTestCase{"32", kGenericCard, false},
+ GetCardNetworkTestCase{"33", kGenericCard, false},
+ GetCardNetworkTestCase{"351", kGenericCard, false},
+ GetCardNetworkTestCase{"3527", kGenericCard, false},
+ GetCardNetworkTestCase{"359", kGenericCard, false},
+ GetCardNetworkTestCase{"50", kGenericCard, false},
+ GetCardNetworkTestCase{"56", kGenericCard, false},
+ GetCardNetworkTestCase{"57", kGenericCard, false},
+ GetCardNetworkTestCase{"58", kGenericCard, false},
+ GetCardNetworkTestCase{"59", kGenericCard, false},
+ GetCardNetworkTestCase{"600", kGenericCard, false},
+ GetCardNetworkTestCase{"602", kGenericCard, false},
+ GetCardNetworkTestCase{"603", kGenericCard, false},
+ GetCardNetworkTestCase{"604", kGenericCard, false},
+ GetCardNetworkTestCase{"605", kGenericCard, false},
+ GetCardNetworkTestCase{"606", kGenericCard, false},
+ GetCardNetworkTestCase{"607", kGenericCard, false},
+ GetCardNetworkTestCase{"608", kGenericCard, false},
+ GetCardNetworkTestCase{"609", kGenericCard, false},
+ GetCardNetworkTestCase{"61", kGenericCard, false},
+ GetCardNetworkTestCase{"63", kGenericCard, false},
+ GetCardNetworkTestCase{"640", kGenericCard, false},
+ GetCardNetworkTestCase{"641", kGenericCard, false},
+ GetCardNetworkTestCase{"642", kGenericCard, false},
+ GetCardNetworkTestCase{"643", kGenericCard, false},
+ GetCardNetworkTestCase{"66", kGenericCard, false},
+ GetCardNetworkTestCase{"67", kGenericCard, false},
+ GetCardNetworkTestCase{"68", kGenericCard, false},
+ GetCardNetworkTestCase{"69", kGenericCard, false},
+ GetCardNetworkTestCase{"7", kGenericCard, false},
+ GetCardNetworkTestCase{"8", kGenericCard, false},
+ GetCardNetworkTestCase{"9", kGenericCard, false},
// Oddball case: Unknown issuer, but valid Luhn check and plausible
// length.
- GetCreditCardTypeTestCase{"7000700070007000", kGenericCard, true}));
+ GetCardNetworkTestCase{"7000700070007000", kGenericCard, true}));
TEST(CreditCardTest, LastFourDigits) {
CreditCard card(base::GenerateGUID(), "https://www.example.com/");
ASSERT_EQ(base::string16(), card.LastFourDigits());
- test::SetCreditCardInfo(&card, "Baby Face Nelson",
- "5212341234123489", "01", "2010");
+ test::SetCreditCardInfo(&card, "Baby Face Nelson", "5212341234123489", "01",
+ "2010", "1");
ASSERT_EQ(base::ASCIIToUTF16("3489"), card.LastFourDigits());
card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("3489"));
@@ -1020,12 +1043,13 @@ TEST(CreditCardTest, GetLastUsedDateForDisplay) {
credit_card0.set_use_count(1);
credit_card0.set_use_date(kArbitraryTime - base::TimeDelta::FromDays(1));
test::SetCreditCardInfo(&credit_card0, "John Dillinger",
- "423456789012" /* Visa */, "01", "2021");
+ "423456789012" /* Visa */, "01", "2021", "1");
// Test for last used date.
CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card1, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2021");
+ "347666888555" /* American Express */, "04", "2021",
+ "1");
credit_card1.set_use_count(10);
credit_card1.set_use_date(kArbitraryTime - base::TimeDelta::FromDays(10));
@@ -1034,7 +1058,7 @@ TEST(CreditCardTest, GetLastUsedDateForDisplay) {
credit_card2.set_use_count(5);
credit_card2.set_use_date(kArbitraryTime - base::TimeDelta::FromDays(366));
test::SetCreditCardInfo(&credit_card2, "Bonnie Parker",
- "518765432109" /* Mastercard */, "12", "2021");
+ "518765432109" /* Mastercard */, "12", "2021", "1");
static const struct {
const char* show_expiration_date;
diff --git a/chromium/components/autofill/core/browser/data_driven_test.cc b/chromium/components/autofill/core/browser/data_driven_test.cc
index c3397587073..e778a8a744f 100644
--- a/chromium/components/autofill/core/browser/data_driven_test.cc
+++ b/chromium/components/autofill/core/browser/data_driven_test.cc
@@ -7,6 +7,7 @@
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
+#include "base/threading/thread_restrictions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
@@ -35,6 +36,7 @@ void DataDrivenTest::RunDataDrivenTest(
const base::FilePath& input_directory,
const base::FilePath& output_directory,
const base::FilePath::StringType& file_name_pattern) {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
ASSERT_TRUE(base::DirectoryExists(input_directory));
ASSERT_TRUE(base::DirectoryExists(output_directory));
base::FileEnumerator input_files(input_directory,
@@ -52,6 +54,7 @@ void DataDrivenTest::RunDataDrivenTest(
void DataDrivenTest::RunOneDataDrivenTest(
const base::FilePath& test_file_name,
const base::FilePath& output_directory) {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
// iOS doesn't get rid of removed test files. TODO(estade): remove this after
// all iOS bots are clobbered.
if (test_file_name.BaseName().value() == FILE_PATH_LITERAL("multimerge.in"))
@@ -64,7 +67,9 @@ void DataDrivenTest::RunOneDataDrivenTest(
ReadFile(test_file_name, &input);
std::string output;
+ base::ThreadRestrictions::SetIOAllowed(false);
GenerateResults(input, &output);
+ base::ThreadRestrictions::SetIOAllowed(true);
base::FilePath output_file = output_directory.Append(
test_file_name.BaseName().StripTrailingSeparators().ReplaceExtension(
diff --git a/chromium/components/autofill/core/browser/email_field.cc b/chromium/components/autofill/core/browser/email_field.cc
index a6b14bd68a6..33f0c91cab3 100644
--- a/chromium/components/autofill/core/browser/email_field.cc
+++ b/chromium/components/autofill/core/browser/email_field.cc
@@ -6,8 +6,8 @@
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/browser/autofill_regex_constants.h"
#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
namespace autofill {
diff --git a/chromium/components/autofill/core/browser/field_types.h b/chromium/components/autofill/core/browser/field_types.h
index cee305fcda5..1b1ab9941b9 100644
--- a/chromium/components/autofill/core/browser/field_types.h
+++ b/chromium/components/autofill/core/browser/field_types.h
@@ -163,9 +163,14 @@ enum ServerFieldType {
// forms.
CONFIRMATION_PASSWORD = 95,
+ // The data entered by the user matches multiple pieces of autofill data,
+ // none of which were predicted by autofill. This value is used for metrics
+ // only, it is not a predicted nor uploaded type.
+ AMBIGUOUS_TYPE = 96,
+
// No new types can be added without a corresponding change to the Autofill
// server.
- MAX_VALID_FIELD_TYPE = 96,
+ MAX_VALID_FIELD_TYPE = 97,
};
// The list of all HTML autocomplete field type hints supported by Chrome.
diff --git a/chromium/components/autofill/core/browser/form_structure.cc b/chromium/components/autofill/core/browser/form_structure.cc
index 9bff7e2f0bc..10a8380908c 100644
--- a/chromium/components/autofill/core/browser/form_structure.cc
+++ b/chromium/components/autofill/core/browser/form_structure.cc
@@ -38,7 +38,7 @@
#include "components/autofill/core/common/signatures_util.h"
#include "components/rappor/public/rappor_utils.h"
#include "components/rappor/rappor_service_impl.h"
-#include "components/ukm/ukm_service.h"
+#include "components/ukm/public/ukm_recorder.h"
namespace autofill {
namespace {
@@ -47,10 +47,6 @@ const char kClientVersion[] = "6.1.1715.1442/en (GGLL)";
const char kBillingMode[] = "billing";
const char kShippingMode[] = "shipping";
-// A form is considered to have a high prediction mismatch rate if the number of
-// mismatches exceeds this threshold.
-const int kNumberOfMismatchesThreshold = 3;
-
// Only removing common name prefixes if we have a minimum number of fields and
// a minimum prefix length. These values are chosen to avoid cases such as two
// fields with "address1" and "address2" and be effective against web frameworks
@@ -295,6 +291,19 @@ bool IsCreditCardExpirationType(ServerFieldType type) {
type == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR;
}
+// Returns true iff all form fields autofill types are in |contained_types|.
+bool AllTypesCaptured(const FormStructure& form,
+ const ServerFieldTypeSet& contained_types) {
+ for (const auto& field : form) {
+ for (const auto& type : field->possible_types()) {
+ if (type != UNKNOWN_TYPE && type != EMPTY_TYPE &&
+ !contained_types.count(type))
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace
FormStructure::FormStructure(const FormData& form)
@@ -340,7 +349,7 @@ FormStructure::FormStructure(const FormData& form)
FormStructure::~FormStructure() {}
-void FormStructure::DetermineHeuristicTypes(ukm::UkmService* ukm_service) {
+void FormStructure::DetermineHeuristicTypes(ukm::UkmRecorder* ukm_recorder) {
const auto determine_heuristic_types_start_time = base::TimeTicks::Now();
// First, try to detect field types based on each field's |autocomplete|
@@ -365,24 +374,26 @@ void FormStructure::DetermineHeuristicTypes(ukm::UkmService* ukm_service) {
UpdateAutofillCount();
IdentifySections(has_author_specified_sections_);
- std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics;
+ int developer_engagement_metrics = 0;
if (IsAutofillable()) {
AutofillMetrics::DeveloperEngagementMetric metric =
has_author_specified_types_
? AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS
: AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS;
- metrics.push_back(metric);
+ developer_engagement_metrics |= 1 << metric;
AutofillMetrics::LogDeveloperEngagementMetric(metric);
}
if (has_author_specified_upi_vpa_hint_) {
AutofillMetrics::LogDeveloperEngagementMetric(
AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT);
- metrics.push_back(AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT);
+ developer_engagement_metrics |=
+ 1 << AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT;
}
- AutofillMetrics::LogDeveloperEngagementUkm(ukm_service, source_url(),
- metrics);
+ if (developer_engagement_metrics)
+ AutofillMetrics::LogDeveloperEngagementUkm(ukm_recorder, source_url(),
+ developer_engagement_metrics);
AutofillMetrics::LogDetermineHeuristicTypesTiming(
base::TimeTicks::Now() - determine_heuristic_types_start_time);
@@ -395,15 +406,7 @@ bool FormStructure::EncodeUploadRequest(
bool observed_submission,
AutofillUploadContents* upload) const {
DCHECK(ShouldBeCrowdsourced());
-
- // Verify that |available_field_types| agrees with the possible field types we
- // are uploading.
- for (const auto& field : *this) {
- for (const auto& type : field->possible_types()) {
- DCHECK(type == UNKNOWN_TYPE || type == EMPTY_TYPE ||
- available_field_types.count(type));
- }
- }
+ DCHECK(AllTypesCaptured(*this, available_field_types));
upload->set_submission(observed_submission);
upload->set_client_version(kClientVersion);
@@ -694,8 +697,6 @@ void FormStructure::LogQualityMetrics(
bool did_show_suggestions,
bool observed_submission) const {
size_t num_detected_field_types = 0;
- size_t num_server_mismatches = 0;
- size_t num_heuristic_mismatches = 0;
size_t num_edited_autofilled_fields = 0;
bool did_autofill_all_possible_fields = true;
bool did_autofill_some_possible_fields = false;
@@ -734,93 +735,21 @@ void FormStructure::LogQualityMetrics(
const ServerFieldTypeSet& field_types = field->possible_types();
DCHECK(!field_types.empty());
- // If the field data is empty, or unrecognized, log whether or not autofill
- // predicted that it would be populated with an autofillable data type.
- bool has_empty_data = field_types.count(EMPTY_TYPE) != 0;
- bool has_unrecognized_data = field_types.count(UNKNOWN_TYPE) != 0;
- if (has_empty_data || has_unrecognized_data) {
- AutofillMetrics::FieldTypeQualityMetric match_empty_or_unknown =
- has_empty_data ? AutofillMetrics::TYPE_MATCH_EMPTY
- : AutofillMetrics::TYPE_MATCH_UNKNOWN;
- AutofillMetrics::FieldTypeQualityMetric mismatch_empty_or_unknown =
- has_empty_data ? AutofillMetrics::TYPE_MISMATCH_EMPTY
- : AutofillMetrics::TYPE_MISMATCH_UNKNOWN;
- ServerFieldType field_type = has_empty_data ? EMPTY_TYPE : UNKNOWN_TYPE;
- AutofillMetrics::LogHeuristicTypePrediction(
- (heuristic_type == UNKNOWN_TYPE ? match_empty_or_unknown
- : mismatch_empty_or_unknown),
- field_type, metric_type);
- AutofillMetrics::LogServerTypePrediction(
- (server_type == NO_SERVER_DATA ? match_empty_or_unknown
- : mismatch_empty_or_unknown),
- field_type, metric_type);
- AutofillMetrics::LogOverallTypePrediction(
- (predicted_type == UNKNOWN_TYPE ? match_empty_or_unknown
- : mismatch_empty_or_unknown),
- field_type, metric_type);
+ AutofillMetrics::LogHeuristicPredictionQualityMetrics(
+ field_types, heuristic_type, metric_type);
+ AutofillMetrics::LogServerPredictionQualityMetrics(field_types, server_type,
+ metric_type);
+ AutofillMetrics::LogOverallPredictionQualityMetrics(
+ field_types, predicted_type, metric_type);
+
+ if (field_types.count(EMPTY_TYPE) || field_types.count(UNKNOWN_TYPE))
continue;
- }
++num_detected_field_types;
if (field->is_autofilled)
did_autofill_some_possible_fields = true;
else
did_autofill_all_possible_fields = false;
-
- // Collapse field types that Chrome treats as identical, e.g. home and
- // billing address fields.
- ServerFieldTypeSet collapsed_field_types;
- for (const auto& it : field_types) {
- // Since we currently only support US phone numbers, the (city code + main
- // digits) number is almost always identical to the whole phone number.
- // TODO(isherman): Improve this logic once we add support for
- // international numbers.
- if (it == PHONE_HOME_CITY_AND_NUMBER)
- collapsed_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
- else
- collapsed_field_types.insert(AutofillType(it).GetStorableType());
- }
-
- // Capture the field's type, if it is unambiguous.
- ServerFieldType field_type = UNKNOWN_TYPE;
- if (collapsed_field_types.size() == 1)
- field_type = *collapsed_field_types.begin();
-
- // Log heuristic, server, and overall type quality metrics.
- if (heuristic_type == UNKNOWN_TYPE) {
- AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
- field_type, metric_type);
- } else if (field_types.count(heuristic_type)) {
- AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH,
- field_type, metric_type);
- } else {
- ++num_heuristic_mismatches;
- AutofillMetrics::LogHeuristicTypePrediction(
- AutofillMetrics::TYPE_MISMATCH, field_type, metric_type);
- }
-
- if (server_type == NO_SERVER_DATA) {
- AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
- field_type, metric_type);
- } else if (field_types.count(server_type)) {
- AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MATCH,
- field_type, metric_type);
- } else {
- ++num_server_mismatches;
- AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH,
- field_type, metric_type);
- }
-
- if (predicted_type == UNKNOWN_TYPE) {
- AutofillMetrics::LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
- field_type, metric_type);
- } else if (field_types.count(predicted_type)) {
- AutofillMetrics::LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH,
- field_type, metric_type);
- } else {
- AutofillMetrics::LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH,
- field_type, metric_type);
- }
}
AutofillMetrics::LogNumberOfEditedAutofilledFields(
@@ -845,18 +774,6 @@ void FormStructure::LogQualityMetrics(
AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS;
}
- // Log some RAPPOR metrics for problematic cases.
- if (num_server_mismatches >= kNumberOfMismatchesThreshold) {
- rappor::SampleDomainAndRegistryFromGURL(
- rappor_service, "Autofill.HighNumberOfServerMismatches",
- source_url_);
- }
- if (num_heuristic_mismatches >= kNumberOfMismatchesThreshold) {
- rappor::SampleDomainAndRegistryFromGURL(
- rappor_service, "Autofill.HighNumberOfHeuristicMismatches",
- source_url_);
- }
-
// Unlike the other times, the |submission_time| should always be
// available.
DCHECK(!submission_time.is_null());
@@ -897,38 +814,20 @@ void FormStructure::LogQualityMetrics(
}
void FormStructure::LogQualityMetricsBasedOnAutocomplete() const {
+ const AutofillMetrics::QualityMetricType metric_type =
+ AutofillMetrics::TYPE_AUTOCOMPLETE_BASED;
for (const auto& field : fields_) {
if (field->html_type() != HTML_TYPE_UNSPECIFIED &&
field->html_type() != HTML_TYPE_UNRECOGNIZED) {
// The type inferred by the autocomplete attribute.
- AutofillType type(field->html_type(), field->html_mode());
- ServerFieldType actual_field_type = type.GetStorableType();
-
- const AutofillMetrics::QualityMetricType metric_type =
- AutofillMetrics::TYPE_AUTOCOMPLETE_BASED;
- // Log the quality of our heuristics predictions.
- if (field->heuristic_type() == UNKNOWN_TYPE) {
- AutofillMetrics::LogHeuristicTypePrediction(
- AutofillMetrics::TYPE_UNKNOWN, actual_field_type, metric_type);
- } else if (field->heuristic_type() == actual_field_type) {
- AutofillMetrics::LogHeuristicTypePrediction(
- AutofillMetrics::TYPE_MATCH, actual_field_type, metric_type);
- } else {
- AutofillMetrics::LogHeuristicTypePrediction(
- AutofillMetrics::TYPE_MISMATCH, actual_field_type, metric_type);
- }
-
- // Log the quality of our server predictions.
- if (field->server_type() == NO_SERVER_DATA) {
- AutofillMetrics::LogServerTypePrediction(
- AutofillMetrics::TYPE_UNKNOWN, actual_field_type, metric_type);
- } else if (field->server_type() == actual_field_type) {
- AutofillMetrics::LogServerTypePrediction(
- AutofillMetrics::TYPE_MATCH, actual_field_type, metric_type);
- } else {
- AutofillMetrics::LogServerTypePrediction(
- AutofillMetrics::TYPE_MISMATCH, actual_field_type, metric_type);
- }
+ ServerFieldTypeSet actual_field_type_set{
+ AutofillType(field->html_type(), field->html_mode())
+ .GetStorableType()};
+
+ AutofillMetrics::LogHeuristicPredictionQualityMetrics(
+ actual_field_type_set, field->heuristic_type(), metric_type);
+ AutofillMetrics::LogServerPredictionQualityMetrics(
+ actual_field_type_set, field->server_type(), metric_type);
}
}
}
diff --git a/chromium/components/autofill/core/browser/form_structure.h b/chromium/components/autofill/core/browser/form_structure.h
index 5365ec17fff..52fd9fbfaf4 100644
--- a/chromium/components/autofill/core/browser/form_structure.h
+++ b/chromium/components/autofill/core/browser/form_structure.h
@@ -39,7 +39,7 @@ class RapporServiceImpl;
}
namespace ukm {
-class UkmService;
+class UkmRecorder;
}
namespace autofill {
@@ -55,9 +55,9 @@ class FormStructure {
virtual ~FormStructure();
// Runs several heuristics against the form fields to determine their possible
- // types. If |ukm_service| is specified, logs UKM for the form structure
+ // types. If |ukm_recorder| is specified, logs UKM for the form structure
// corresponding to |source_url_|.
- void DetermineHeuristicTypes(ukm::UkmService* ukm_service);
+ void DetermineHeuristicTypes(ukm::UkmRecorder* ukm_recorder);
// Encodes the proto |upload| request from this FormStructure.
// In some cases, a |login_form_signature| is included as part of the upload.
diff --git a/chromium/components/autofill/core/browser/name_field.cc b/chromium/components/autofill/core/browser/name_field.cc
index 25a9d47b03a..aa68ac29596 100644
--- a/chromium/components/autofill/core/browser/name_field.cc
+++ b/chromium/components/autofill/core/browser/name_field.cc
@@ -10,9 +10,9 @@
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/browser/autofill_regex_constants.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/browser/autofill_type.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
using base::UTF8ToUTF16;
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 76e3637540b..5d01e9b84e1 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
@@ -102,7 +102,8 @@ class FullCardRequestTest : public testing::Test,
std::unique_ptr<base::DictionaryValue> legal_message) override {
ASSERT_TRUE(false) << "No upload details in this test";
}
- void OnDidUploadCard(AutofillClient::PaymentsRpcResult result) override {
+ void OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
+ const std::string& server_id) override {
ASSERT_TRUE(false) << "No card uploads in this test.";
}
@@ -166,7 +167,7 @@ TEST_F(FullCardRequestTest, GetFullCardPanAndCvcForLocalCard) {
OnUnmaskVerificationResult(AutofillClient::SUCCESS));
CreditCard card;
- test::SetCreditCardInfo(&card, nullptr, "4111", "12", "2050");
+ test::SetCreditCardInfo(&card, nullptr, "4111", "12", "2050", "1");
request()->GetFullCard(card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
ui_delegate()->AsWeakPtr());
@@ -187,7 +188,8 @@ TEST_F(FullCardRequestTest, GetFullCardPanAndCvcForFullServerCard) {
OnUnmaskVerificationResult(AutofillClient::SUCCESS));
CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "server_id");
- test::SetCreditCardInfo(&full_server_card, nullptr, "4111", "12", "2050");
+ test::SetCreditCardInfo(&full_server_card, nullptr, "4111", "12", "2050",
+ "1");
request()->GetFullCard(full_server_card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
ui_delegate()->AsWeakPtr());
@@ -211,7 +213,8 @@ TEST_F(FullCardRequestTest,
OnUnmaskVerificationResult(AutofillClient::SUCCESS));
CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "server_id");
- test::SetCreditCardInfo(&full_server_card, nullptr, "4111", "12", "2050");
+ test::SetCreditCardInfo(&full_server_card, nullptr, "4111", "12", "2050",
+ "1");
full_server_card.SetServerStatus(CreditCard::EXPIRED);
request()->GetFullCard(full_server_card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
@@ -241,7 +244,8 @@ TEST_F(FullCardRequestTest, GetFullCardPanAndCvcForExpiredFullServerCard) {
base::Time::Now().LocalExplode(&today);
CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "server_id");
test::SetCreditCardInfo(&full_server_card, nullptr, "4111", "12",
- base::StringPrintf("%d", today.year - 1).c_str());
+ base::StringPrintf("%d", today.year - 1).c_str(),
+ "1");
full_server_card.SetServerStatus(CreditCard::OK);
request()->GetFullCard(full_server_card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
@@ -285,7 +289,7 @@ TEST_F(FullCardRequestTest, SecondRequestOkAfterFirstFinished) {
.Times(2);
CreditCard card;
- test::SetCreditCardInfo(&card, nullptr, "4111", "12", "2050");
+ test::SetCreditCardInfo(&card, nullptr, "4111", "12", "2050", "1");
request()->GetFullCard(card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
ui_delegate()->AsWeakPtr());
@@ -434,7 +438,8 @@ TEST_F(FullCardRequestTest, UpdateExpDateForFullServerCard) {
OnUnmaskVerificationResult(AutofillClient::SUCCESS));
CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "server_id");
- test::SetCreditCardInfo(&full_server_card, nullptr, "4111", "10", "2000");
+ test::SetCreditCardInfo(&full_server_card, nullptr, "4111", "10", "2000",
+ "1");
request()->GetFullCard(full_server_card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
ui_delegate()->AsWeakPtr());
@@ -464,7 +469,8 @@ TEST_F(FullCardRequestTest, UpdateExpDateForLocalCard) {
base::Time::Now().LocalExplode(&today);
CreditCard card;
test::SetCreditCardInfo(&card, nullptr, "4111", "10",
- base::StringPrintf("%d", today.year - 1).c_str());
+ base::StringPrintf("%d", today.year - 1).c_str(),
+ "1");
request()->GetFullCard(card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
ui_delegate()->AsWeakPtr());
@@ -573,7 +579,7 @@ TEST_F(FullCardRequestTest, IsGettingFullCardForLocalCard) {
EXPECT_FALSE(request()->IsGettingFullCard());
CreditCard card;
- test::SetCreditCardInfo(&card, nullptr, "4111", "12", "2050");
+ test::SetCreditCardInfo(&card, nullptr, "4111", "12", "2050", "1");
request()->GetFullCard(card, AutofillClient::UNMASK_FOR_AUTOFILL,
result_delegate()->AsWeakPtr(),
ui_delegate()->AsWeakPtr());
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.cc b/chromium/components/autofill/core/browser/payments/payments_client.cc
index 44e85c2e8d9..683a2f5449f 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_client.cc
@@ -161,6 +161,22 @@ std::unique_ptr<base::DictionaryValue> BuildAddressDictionary(
return address;
}
+// Populates the list of active experiments that affect either the data sent in
+// payments RPCs or whether the RPCs are sent or not.
+void SetActiveExperiments(const std::vector<const char*>& active_experiments,
+ base::DictionaryValue* request_dict) {
+ if (active_experiments.empty())
+ return;
+
+ std::unique_ptr<base::ListValue> active_chrome_experiments(
+ base::MakeUnique<base::ListValue>());
+ for (const char* it : active_experiments)
+ active_chrome_experiments->AppendString(it);
+
+ request_dict->Set("active_chrome_experiments",
+ std::move(active_chrome_experiments));
+}
+
class UnmaskCardRequest : public PaymentsRequest {
public:
UnmaskCardRequest(const PaymentsClient::UnmaskRequestDetails& request_details)
@@ -222,8 +238,11 @@ class UnmaskCardRequest : public PaymentsRequest {
class GetUploadDetailsRequest : public PaymentsRequest {
public:
GetUploadDetailsRequest(const std::vector<AutofillProfile>& addresses,
+ const std::vector<const char*>& active_experiments,
const std::string& app_locale)
- : addresses_(addresses), app_locale_(app_locale) {}
+ : addresses_(addresses),
+ active_experiments_(active_experiments),
+ app_locale_(app_locale) {}
~GetUploadDetailsRequest() override {}
std::string GetRequestUrlPath() override {
@@ -250,6 +269,8 @@ class GetUploadDetailsRequest : public PaymentsRequest {
}
request_dict.Set("address", std::move(addresses));
+ SetActiveExperiments(active_experiments_, &request_dict);
+
std::string request_content;
base::JSONWriter::Write(request_dict, &request_content);
VLOG(3) << "getdetailsforsavecard request body: " << request_content;
@@ -274,7 +295,8 @@ class GetUploadDetailsRequest : public PaymentsRequest {
}
private:
- std::vector<AutofillProfile> addresses_;
+ const std::vector<AutofillProfile> addresses_;
+ const std::vector<const char*> active_experiments_;
std::string app_locale_;
base::string16 context_token_;
std::unique_ptr<base::DictionaryValue> legal_message_;
@@ -325,6 +347,8 @@ class UploadCardRequest : public PaymentsRequest {
if (base::StringToInt(exp_year, &value))
request_dict.SetInteger("expiration_year", value);
+ SetActiveExperiments(request_details_.active_experiments, &request_dict);
+
const base::string16 pan = request_details_.card.GetInfo(
AutofillType(CREDIT_CARD_NUMBER), app_locale);
std::string json_request;
@@ -341,17 +365,19 @@ class UploadCardRequest : public PaymentsRequest {
}
void ParseResponse(std::unique_ptr<base::DictionaryValue> response) override {
+ response->GetString("credit_card_id", &server_id_);
}
bool IsResponseComplete() override { return true; }
void RespondToDelegate(PaymentsClientDelegate* delegate,
AutofillClient::PaymentsRpcResult result) override {
- delegate->OnDidUploadCard(result);
+ delegate->OnDidUploadCard(result, server_id_);
}
private:
- PaymentsClient::UploadRequestDetails request_details_;
+ const PaymentsClient::UploadRequestDetails request_details_;
+ std::string server_id_;
};
} // namespace
@@ -391,8 +417,10 @@ void PaymentsClient::UnmaskCard(
void PaymentsClient::GetUploadDetails(
const std::vector<AutofillProfile>& addresses,
+ const std::vector<const char*>& active_experiments,
const std::string& app_locale) {
- IssueRequest(base::MakeUnique<GetUploadDetailsRequest>(addresses, app_locale),
+ IssueRequest(base::MakeUnique<GetUploadDetailsRequest>(
+ addresses, active_experiments, app_locale),
false);
}
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.h b/chromium/components/autofill/core/browser/payments/payments_client.h
index 40fb7d1590c..467b44cc3cb 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.h
+++ b/chromium/components/autofill/core/browser/payments/payments_client.h
@@ -47,7 +47,10 @@ class PaymentsClientDelegate {
std::unique_ptr<base::DictionaryValue> legal_message) = 0;
// Returns the result of an upload request.
- virtual void OnDidUploadCard(AutofillClient::PaymentsRpcResult result) = 0;
+ // If |result| == |AutofillClient::SUCCESS|, |server_id| may, optionally,
+ // contain the opaque identifier for the card on the server.
+ virtual void OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
+ const std::string& server_id) = 0;
};
// PaymentsClient issues Payments RPCs and manages responses and failure
@@ -88,6 +91,7 @@ class PaymentsClient : public net::URLFetcherDelegate,
base::string16 context_token;
std::string risk_data;
std::string app_locale;
+ std::vector<const char*> active_experiments;
};
// |context_getter| is reference counted so it has no lifetime or ownership
@@ -112,9 +116,12 @@ class PaymentsClient : public net::URLFetcherDelegate,
// The service uses |addresses| (from which names and phone numbers are
// removed) and |app_locale| to determine which legal message to display. If
// the conditions are met, the legal message will be returned via
- // OnDidGetUploadDetails.
- virtual void GetUploadDetails(const std::vector<AutofillProfile>& addresses,
- const std::string& app_locale);
+ // OnDidGetUploadDetails. |active_experiments| is used by payments server to
+ // track requests that were triggered by enabled features.
+ virtual void GetUploadDetails(
+ const std::vector<AutofillProfile>& addresses,
+ const std::vector<const char*>& active_experiments,
+ const std::string& app_locale);
// The user has indicated that they would like to upload a card with the given
// cvc. This request will fail server-side if a successful call to
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.cc b/chromium/components/autofill/core/browser/personal_data_manager.cc
index e634110a718..8039bc4e601 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager.cc
@@ -442,13 +442,16 @@ void PersonalDataManager::RemoveObserver(
bool PersonalDataManager::ImportFormData(
const FormStructure& form,
bool should_return_local_card,
- std::unique_ptr<CreditCard>* imported_credit_card) {
+ std::unique_ptr<CreditCard>* imported_credit_card,
+ bool* imported_credit_card_matches_masked_server_credit_card) {
// We try the same |form| for both credit card and address import/update.
// - ImportCreditCard may update an existing card, or fill
// |imported_credit_card| with an extracted card. See .h for details of
- // |should_return_local_card|.
+ // |should_return_local_card| and
+ // |imported_credit_card_matches_masked_server_credit_card|.
bool cc_import =
- ImportCreditCard(form, should_return_local_card, imported_credit_card);
+ ImportCreditCard(form, should_return_local_card, imported_credit_card,
+ imported_credit_card_matches_masked_server_credit_card);
// - ImportAddressProfiles may eventually save or update one or more address
// profiles.
bool address_import = ImportAddressProfiles(form);
@@ -611,6 +614,27 @@ void PersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) {
Refresh();
}
+void PersonalDataManager::AddFullServerCreditCard(
+ const CreditCard& credit_card) {
+ DCHECK_EQ(CreditCard::FULL_SERVER_CARD, credit_card.record_type());
+ DCHECK(!credit_card.IsEmpty(app_locale_));
+ DCHECK(!credit_card.server_id().empty());
+
+ if (is_off_the_record_ || !database_.get())
+ return;
+
+ // Don't add a duplicate.
+ if (FindByGUID<CreditCard>(server_credit_cards_, credit_card.guid()) ||
+ FindByContents(server_credit_cards_, credit_card))
+ return;
+
+ // Add the new credit card to the web database.
+ database_->AddFullServerCreditCard(credit_card);
+
+ // Refresh our local cache and send notifications to observers.
+ Refresh();
+}
+
void PersonalDataManager::UpdateServerCreditCard(
const CreditCard& credit_card) {
DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type());
@@ -709,11 +733,24 @@ void PersonalDataManager::RemoveByGUID(const std::string& guid) {
if (!database_.get())
return;
- if (is_credit_card)
+ if (is_credit_card) {
database_->RemoveCreditCard(guid);
- else
+ } else {
database_->RemoveAutofillProfile(guid);
+ // Reset the billing_address_id of any card that refered to this profile.
+ for (CreditCard* credit_card : GetCreditCards()) {
+ if (credit_card->billing_address_id() == guid) {
+ credit_card->set_billing_address_id("");
+
+ if (credit_card->record_type() == CreditCard::LOCAL_CARD)
+ database_->UpdateCreditCard(*credit_card);
+ else
+ database_->UpdateServerCardMetadata(*credit_card);
+ }
+ }
+ }
+
// Refresh our local cache and send notifications to observers.
Refresh();
}
@@ -725,6 +762,18 @@ CreditCard* PersonalDataManager::GetCreditCardByGUID(const std::string& guid) {
return iter != credit_cards.end() ? *iter : nullptr;
}
+CreditCard* PersonalDataManager::GetCreditCardByNumber(
+ const std::string& number) {
+ CreditCard numbered_card;
+ numbered_card.SetNumber(base::ASCIIToUTF16(number));
+ for (CreditCard* credit_card : GetCreditCards()) {
+ DCHECK(credit_card);
+ if (credit_card->HasSameNumberAs(numbered_card))
+ return credit_card;
+ }
+ return nullptr;
+}
+
void PersonalDataManager::GetNonEmptyTypes(
ServerFieldTypeSet* non_empty_types) {
for (AutofillProfile* profile : GetProfiles())
@@ -1476,8 +1525,10 @@ bool PersonalDataManager::ImportAddressProfileForSection(
bool PersonalDataManager::ImportCreditCard(
const FormStructure& form,
bool should_return_local_card,
- std::unique_ptr<CreditCard>* imported_credit_card) {
+ std::unique_ptr<CreditCard>* imported_credit_card,
+ bool* imported_credit_card_matches_masked_server_credit_card) {
DCHECK(!imported_credit_card->get());
+ *imported_credit_card_matches_masked_server_credit_card = false;
// The candidate for credit card import. There are many ways for the candidate
// to be rejected (see everywhere this function returns false, below).
@@ -1540,7 +1591,8 @@ bool PersonalDataManager::ImportCreditCard(
// have already saved this card number, unless |should_return_local_card| is
// true which indicates that upload is enabled. In this case, it's useful to
// present the upload prompt to the user to promote the card from a local card
- // to a synced server card.
+ // to a synced server card, provided we don't have a masked server card with
+ // the same |TypeAndLastFourDigits|.
for (const auto& card : local_credit_cards_) {
// Make a local copy so that the data in |local_credit_cards_| isn't
// modified directly by the UpdateFromImportedCard() call.
@@ -1557,14 +1609,22 @@ bool PersonalDataManager::ImportCreditCard(
}
}
- // Also don't offer to save if we already have this stored as a server card.
- // We only check the number because if the new card has the same number as the
- // server card, upload is guaranteed to fail. There's no mechanism for entries
- // with the same number but different names or expiration dates as there is
- // for local cards.
+ // Also don't offer to save if we already have this stored as a full server
+ // card. We only check the number because if the new card has the same number
+ // as the server card, upload is guaranteed to fail. There's no mechanism for
+ // entries with the same number but different names or expiration dates as
+ // there is for local cards.
+ // We can offer to save locally even if we already have this stored another
+ // masked server card with the same |TypeAndLastFourDigits| so that the user
+ // can enter the full card number without having to unmask the card.
for (const auto& card : server_credit_cards_) {
- if (candidate_credit_card.HasSameNumberAs(*card))
- return false;
+ if (candidate_credit_card.HasSameNumberAs(*card)) {
+ if (card->record_type() == CreditCard::FULL_SERVER_CARD)
+ return false;
+ DCHECK_EQ(card->record_type(), CreditCard::MASKED_SERVER_CARD);
+ *imported_credit_card_matches_masked_server_credit_card = true;
+ break;
+ }
}
imported_credit_card->reset(new CreditCard(candidate_credit_card));
@@ -1604,7 +1664,7 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
Suggestion* suggestion = &suggestions.back();
suggestion->value = credit_card->GetInfo(type, app_locale_);
- suggestion->icon = base::UTF8ToUTF16(credit_card->type());
+ suggestion->icon = base::UTF8ToUTF16(credit_card->network());
suggestion->backend_id = credit_card->guid();
suggestion->match = prefix_matched_suggestion
? Suggestion::PREFIX_MATCH
@@ -1614,7 +1674,7 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
// Otherwise the label is the card number, or if that is empty the
// cardholder name. The label should never repeat the value.
if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
- suggestion->value = credit_card->TypeAndLastFourDigits();
+ suggestion->value = credit_card->NetworkAndLastFourDigits();
if (IsAutofillCreditCardLastUsedDateDisplayExperimentEnabled()) {
suggestion->label =
credit_card->GetLastUsedDateForDisplay(app_locale_);
@@ -1634,7 +1694,7 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
// Since Android places the label on its own row, there's more
// horizontal
// space to work with. Show "Amex - 1234" rather than desktop's "*1234".
- suggestion->label = credit_card->TypeAndLastFourDigits();
+ suggestion->label = credit_card->NetworkAndLastFourDigits();
#else
suggestion->label = base::ASCIIToUTF16("*");
suggestion->label.append(credit_card->LastFourDigits());
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.h b/chromium/components/autofill/core/browser/personal_data_manager.h
index d8247d526c0..ac29f283ac5 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.h
+++ b/chromium/components/autofill/core/browser/personal_data_manager.h
@@ -105,10 +105,15 @@ class PersonalDataManager : public KeyedService,
// a local credit card entry *and* |should_return_local_card| is true, the
// data is stored into |imported_credit_card| so that we can prompt the user
// whether to upload it.
- // Returns |true| if sufficient address or credit card data was found.
- bool ImportFormData(const FormStructure& form,
- bool should_return_local_card,
- std::unique_ptr<CreditCard>* imported_credit_card);
+ // |imported_credit_card_matches_masked_server_credit_card| is set to |true|
+ // if the |TypeAndLastFourDigits| in |imported_credit_card| matches the
+ // |TypeAndLastFourDigits| in a saved masked server card. Returns |true| if
+ // sufficient address or credit card data was found.
+ bool ImportFormData(
+ const FormStructure& form,
+ bool should_return_local_card,
+ std::unique_ptr<CreditCard>* imported_credit_card,
+ bool* imported_credit_card_matches_masked_server_credit_card);
// Called to indicate |data_model| was used (to fill in a form). Updates
// the database accordingly. Can invalidate |data_model|, particularly if
@@ -145,13 +150,16 @@ class PersonalDataManager : public KeyedService,
const std::string& guid,
const std::vector<AutofillProfile*>& profiles);
- // Adds |credit_card| to the web database.
+ // Adds |credit_card| to the web database as a local card.
virtual void AddCreditCard(const CreditCard& credit_card);
// Updates |credit_card| which already exists in the web database. This
// can only be used on local credit cards.
virtual void UpdateCreditCard(const CreditCard& credit_card);
+ // Adds |credit_card| to the web database as a full server card.
+ virtual void AddFullServerCreditCard(const CreditCard& credit_card);
+
// Update a server card. Only the full number and masked/unmasked
// status can be changed. Looks up the card by server ID.
virtual void UpdateServerCreditCard(const CreditCard& credit_card);
@@ -176,6 +184,10 @@ class PersonalDataManager : public KeyedService,
// no credit card with the specified |guid|.
virtual CreditCard* GetCreditCardByGUID(const std::string& guid);
+ // Returns the credit card with the specified |number|, or nullptr if there is
+ // no credit card with the specified |number|.
+ virtual CreditCard* GetCreditCardByNumber(const std::string& number);
+
// Gets the field types availabe in the stored address and credit card data.
void GetNonEmptyTypes(ServerFieldTypeSet* non_empty_types);
@@ -326,7 +338,7 @@ class PersonalDataManager : public KeyedService,
ConvertWalletAddressesAndUpdateWalletCards_MergedProfile);
FRIEND_TEST_ALL_PREFIXES(
PersonalDataManagerTest,
- ConvertWalletAddressesAndUpdateWalletCards_NewCard_AddressAlreadyConverted); // NOLINT
+ ConvertWalletAddressesAndUpdateWalletCards_NewCrd_AddressAlreadyConverted); // NOLINT
FRIEND_TEST_ALL_PREFIXES(
PersonalDataManagerTest,
ConvertWalletAddressesAndUpdateWalletCards_AlreadyConverted);
@@ -472,11 +484,16 @@ class PersonalDataManager : public KeyedService,
// Go through the |form| fields and attempt to extract a new credit card in
// |imported_credit_card|, or update an existing card.
// |should_return_local_card| will indicate whether |imported_credit_card| is
- // filled even if an existing card was updated. Success is defined as having a
+ // filled even if an existing card was updated.
+ // |imported_credit_card_matches_masked_server_credit_card| will indicate
+ // whether |imported_credit_card| is filled even if an existing masked server
+ // card as the same |TypeAndLastFourDigits|. Success is defined as having a
// new card to import, or having merged with an existing card.
- bool ImportCreditCard(const FormStructure& form,
- bool should_return_local_card,
- std::unique_ptr<CreditCard>* imported_credit_card);
+ bool ImportCreditCard(
+ const FormStructure& form,
+ bool should_return_local_card,
+ std::unique_ptr<CreditCard>* imported_credit_card,
+ bool* imported_credit_card_matches_masked_server_credit_card);
// Functionally equivalent to GetProfiles(), but also records metrics if
// |record_metrics| is true. Metrics should be recorded when the returned
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 f5b2aa6d4ce..2a1b23db52f 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -19,6 +19,7 @@
#include "base/guid.h"
#include "base/i18n/time_formatting.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
@@ -54,15 +55,12 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-using base::ASCIIToUTF16;
-using base::UTF8ToUTF16;
-
namespace autofill {
namespace {
enum UserMode { USER_MODE_NORMAL, USER_MODE_INCOGNITO };
-const std::string kUTF8MidlineEllipsis =
+const char kUTF8MidlineEllipsis[] =
" "
"\xE2\x80\xA2\xE2\x80\x86"
"\xE2\x80\xA2\xE2\x80\x86"
@@ -213,8 +211,8 @@ class PersonalDataManagerTestBase {
CreditCard credit_card0("287151C8-6AB1-487C-9095-28E80BE5DA15",
"https://www.example.com");
test::SetCreditCardInfo(&credit_card0, "Clyde Barrow",
- "347666888555" /* American Express */, "04",
- "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
credit_card0.set_use_count(3);
credit_card0.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
@@ -226,7 +224,7 @@ class PersonalDataManagerTestBase {
credit_card1.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(10));
test::SetCreditCardInfo(&credit_card1, "John Dillinger",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
personal_data_->AddCreditCard(credit_card1);
CreditCard credit_card2("002149C1-EE28-4213-A3B9-DA243FFF021B",
@@ -235,7 +233,7 @@ class PersonalDataManagerTestBase {
credit_card2.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
test::SetCreditCardInfo(&credit_card2, "Bonnie Parker",
- "518765432109" /* Mastercard */, "12", "2999");
+ "518765432109" /* Mastercard */, "12", "2999", "1");
personal_data_->AddCreditCard(credit_card2);
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -251,11 +249,14 @@ class PersonalDataManagerTestBase {
bool ImportAddressProfiles(const FormStructure& form) {
return personal_data_->ImportAddressProfiles(form);
}
- bool ImportCreditCard(const FormStructure& form,
- bool should_return_local_card,
- std::unique_ptr<CreditCard>* imported_credit_card) {
- return personal_data_->ImportCreditCard(form, should_return_local_card,
- imported_credit_card);
+ bool ImportCreditCard(
+ const FormStructure& form,
+ bool should_return_local_card,
+ std::unique_ptr<CreditCard>* imported_credit_card,
+ bool* imported_credit_card_matches_masked_server_credit_card) {
+ return personal_data_->ImportCreditCard(
+ form, should_return_local_card, imported_credit_card,
+ imported_credit_card_matches_masked_server_credit_card);
}
void SubmitFormAndExpectImportedCardWithData(const FormData& form,
@@ -266,8 +267,12 @@ class PersonalDataManagerTestBase {
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -277,7 +282,7 @@ class PersonalDataManagerTestBase {
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected, exp_name, exp_cc_num, exp_cc_month,
- exp_cc_year);
+ exp_cc_year, "");
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -357,7 +362,7 @@ class PersonalDataManagerTest : public PersonalDataManagerTestBase,
TEST_F(PersonalDataManagerTest, AddProfile) {
// Add profile0 to the database.
AutofillProfile profile0(test::GetFullProfile());
- profile0.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("j@s.com"));
+ profile0.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("j@s.com"));
personal_data_->AddProfile(profile0);
// Reload the database.
@@ -384,7 +389,7 @@ TEST_F(PersonalDataManagerTest, AddProfile) {
// New profile with different email.
AutofillProfile profile1 = profile0;
profile1.set_guid(base::GenerateGUID());
- profile1.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("john@smith.com"));
+ profile1.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("john@smith.com"));
// Add the different profile. This should save as a separate profile.
// Note that if this same profile was "merged" it would collapse to one
@@ -409,7 +414,7 @@ TEST_F(PersonalDataManagerTest, AddProfile_BasicInformation) {
// Add a profile to the database.
AutofillProfile profile(test::GetFullProfile());
- profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("j@s.com"));
+ profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("j@s.com"));
personal_data_->AddProfile(profile);
// Reload the database.
@@ -472,7 +477,7 @@ TEST_F(PersonalDataManagerTest, AddUpdateRemoveProfiles) {
ExpectSameElements(profiles, personal_data_->GetProfiles());
// Update, remove, and add.
- profile0.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
+ profile0.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("John"));
personal_data_->UpdateProfile(profile0);
personal_data_->RemoveByGUID(profile1.guid());
personal_data_->AddProfile(profile2);
@@ -497,17 +502,19 @@ TEST_F(PersonalDataManagerTest, AddUpdateRemoveProfiles) {
}
TEST_F(PersonalDataManagerTest, AddUpdateRemoveCreditCards) {
+ EnableWalletCardImport();
CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&credit_card0,
- "John Dillinger", "423456789012" /* Visa */, "01", "2999");
+ test::SetCreditCardInfo(&credit_card0, "John Dillinger",
+ "423456789012" /* Visa */, "01", "2999", "1");
CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card1, "Bonnie Parker",
- "518765432109" /* Mastercard */, "12", "2999");
+ "518765432109" /* Mastercard */, "12", "2999", "1");
CreditCard credit_card2(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card2, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
// Add two test credit cards to the database.
personal_data_->AddCreditCard(credit_card0);
@@ -524,7 +531,7 @@ TEST_F(PersonalDataManagerTest, AddUpdateRemoveCreditCards) {
ExpectSameElements(cards, personal_data_->GetCreditCards());
// Update, remove, and add.
- credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Joe"));
+ credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Joe"));
personal_data_->UpdateCreditCard(credit_card0);
personal_data_->RemoveByGUID(credit_card1.guid());
personal_data_->AddCreditCard(credit_card2);
@@ -549,6 +556,39 @@ TEST_F(PersonalDataManagerTest, AddUpdateRemoveCreditCards) {
cards.push_back(&credit_card0);
cards.push_back(&credit_card2);
ExpectSameElements(cards, personal_data_->GetCreditCards());
+
+ // Add a full server card.
+ CreditCard credit_card3(base::GenerateGUID(), "https://www.example.com");
+ test::SetCreditCardInfo(&credit_card3, "Jane Doe",
+ "4111111111111111" /* Visa */, "04", "2999", "1");
+ credit_card3.set_record_type(CreditCard::FULL_SERVER_CARD);
+ credit_card3.set_server_id("server_id");
+
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .WillOnce(QuitMainMessageLoop());
+
+ personal_data_->AddFullServerCreditCard(credit_card3);
+ base::RunLoop().Run();
+
+ cards.push_back(&credit_card3);
+ ExpectSameElements(cards, personal_data_->GetCreditCards());
+
+ // Must not add a duplicate server card with same GUID.
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
+
+ personal_data_->AddFullServerCreditCard(credit_card3);
+
+ ExpectSameElements(cards, personal_data_->GetCreditCards());
+
+ // Must not add a duplicate card with same contents as another server card.
+ CreditCard duplicate_server_card(credit_card3);
+ duplicate_server_card.set_guid(base::GenerateGUID());
+
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
+
+ personal_data_->AddFullServerCreditCard(duplicate_server_card);
+
+ ExpectSameElements(cards, personal_data_->GetCreditCards());
}
// Test that a new credit card has its basic information set.
@@ -557,10 +597,10 @@ TEST_F(PersonalDataManagerTest, AddCreditCard_BasicInformation) {
TestAutofillClock test_clock;
test_clock.SetNow(kArbitraryTime);
- // Add a credit to the database.
+ // Add a credit card to the database.
CreditCard credit_card(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card, "John Dillinger",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
personal_data_->AddCreditCard(credit_card);
// Reload the database.
@@ -587,8 +627,8 @@ TEST_F(PersonalDataManagerTest, UpdateUnverifiedProfilesAndCreditCards) {
EXPECT_FALSE(profile.IsVerified());
CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- test::SetCreditCardInfo(&credit_card,
- "John Dillinger", "423456789012" /* Visa */, "01", "2999");
+ test::SetCreditCardInfo(&credit_card, "John Dillinger",
+ "423456789012" /* Visa */, "01", "2999", "1");
EXPECT_FALSE(credit_card.IsVerified());
// Add the data to the database.
@@ -633,8 +673,8 @@ TEST_F(PersonalDataManagerTest, UpdateUnverifiedProfilesAndCreditCards) {
EXPECT_EQ(original_credit_card.origin(), cards2[0]->origin());
// Try to update with data changed as well.
- profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
- credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Joe"));
+ profile.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("John"));
+ credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Joe"));
personal_data_->UpdateProfile(profile);
personal_data_->UpdateCreditCard(credit_card);
@@ -670,7 +710,8 @@ TEST_F(PersonalDataManagerTest, RefuseToStoreFullCard) {
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
test::SetServerCreditCards(autofill_table_, server_cards);
personal_data_->Refresh();
@@ -683,6 +724,36 @@ TEST_F(PersonalDataManagerTest, RefuseToStoreFullCard) {
personal_data_->GetCreditCards()[0]->record_type());
}
+// Makes sure that full cards are only added as masked card when full PAN
+// storage is disabled.
+TEST_F(PersonalDataManagerTest, AddFullCardAsMaskedCard) {
+// On Linux this should be disabled automatically. Elsewhere, only if the
+// flag is passed.
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ EXPECT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableOfferStoreUnmaskedWalletCards));
+#else
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kDisableOfferStoreUnmaskedWalletCards);
+#endif
+
+ CreditCard server_card(CreditCard::FULL_SERVER_CARD, "c789");
+ test::SetCreditCardInfo(&server_card, "Clyde Barrow",
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
+
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .WillOnce(QuitMainMessageLoop());
+
+ personal_data_->AddFullServerCreditCard(server_card);
+
+ base::RunLoop().Run();
+
+ ASSERT_EQ(1U, personal_data_->GetCreditCards().size());
+ EXPECT_EQ(CreditCard::MASKED_SERVER_CARD,
+ personal_data_->GetCreditCards()[0]->record_type());
+}
+
TEST_F(PersonalDataManagerTest, OfferStoreUnmaskedCards) {
#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX) || \
defined(OS_IOS) || defined(OS_ANDROID)
@@ -700,17 +771,18 @@ TEST_F(PersonalDataManagerTest, UpdateServerCreditCards) {
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "9012" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "9012" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456"));
test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker",
- "2109" /* Mastercard */, "12", "2999");
- server_cards.back().SetTypeForMaskedCard(kMasterCard);
+ "2109" /* Mastercard */, "12", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kMasterCard);
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
test::SetServerCreditCards(autofill_table_, server_cards);
personal_data_->Refresh();
@@ -736,7 +808,7 @@ TEST_F(PersonalDataManagerTest, UpdateServerCreditCards) {
CreditCard* unmasked_card = &server_cards.front();
unmasked_card->set_record_type(CreditCard::FULL_SERVER_CARD);
- unmasked_card->SetNumber(ASCIIToUTF16("423456789012"));
+ unmasked_card->SetNumber(base::ASCIIToUTF16("423456789012"));
EXPECT_NE(0, server_cards.front().Compare(
*personal_data_->GetCreditCards().front()));
personal_data_->UpdateServerCreditCard(*unmasked_card);
@@ -750,7 +822,7 @@ TEST_F(PersonalDataManagerTest, UpdateServerCreditCards) {
CreditCard* remasked_card = &server_cards.back();
remasked_card->set_record_type(CreditCard::MASKED_SERVER_CARD);
- remasked_card->SetNumber(ASCIIToUTF16("8555"));
+ remasked_card->SetNumber(base::ASCIIToUTF16("8555"));
EXPECT_NE(
0, server_cards.back().Compare(*personal_data_->GetCreditCards().back()));
personal_data_->UpdateServerCreditCard(*remasked_card);
@@ -777,12 +849,12 @@ TEST_F(PersonalDataManagerTest, AddProfilesAndCreditCards) {
"US", "19482937549");
CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&credit_card0,
- "John Dillinger", "423456789012" /* Visa */, "01", "2999");
+ test::SetCreditCardInfo(&credit_card0, "John Dillinger",
+ "423456789012" /* Visa */, "01", "2999", "1");
CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card1, "Bonnie Parker",
- "518765432109" /* Mastercard */, "12", "2999");
+ "518765432109" /* Mastercard */, "12", "2999", "1");
// Add two test profiles to the database.
personal_data_->AddProfile(profile0);
@@ -863,17 +935,17 @@ TEST_F(PersonalDataManagerTest, PopulateUniqueIDsOnLoad) {
TEST_F(PersonalDataManagerTest, SetUniqueCreditCardLabels) {
CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com");
- credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("John"));
+ credit_card0.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("John"));
CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com");
- credit_card1.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Paul"));
+ credit_card1.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Paul"));
CreditCard credit_card2(base::GenerateGUID(), "https://www.example.com");
- credit_card2.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Ringo"));
+ credit_card2.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Ringo"));
CreditCard credit_card3(base::GenerateGUID(), "https://www.example.com");
- credit_card3.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Other"));
+ credit_card3.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Other"));
CreditCard credit_card4(base::GenerateGUID(), "https://www.example.com");
- credit_card4.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Ozzy"));
+ credit_card4.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Ozzy"));
CreditCard credit_card5(base::GenerateGUID(), "https://www.example.com");
- credit_card5.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Dio"));
+ credit_card5.SetRawInfo(CREDIT_CARD_NAME_FULL, base::ASCIIToUTF16("Dio"));
// Add the test credit cards to the database.
personal_data_->AddCreditCard(credit_card0);
@@ -920,7 +992,7 @@ TEST_F(PersonalDataManagerTest, SetEmptyProfile) {
TEST_F(PersonalDataManagerTest, SetEmptyCreditCard) {
CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&credit_card0, "", "", "", "");
+ test::SetCreditCardInfo(&credit_card0, "", "", "", "", "");
// Add the empty credit card to the database.
personal_data_->AddCreditCard(credit_card0);
@@ -993,8 +1065,8 @@ TEST_F(PersonalDataManagerTest, Refresh) {
// was open with a previous snapshot of the profiles, and something
// [e.g. sync] removed a profile from the browser. In this edge case, we will
// end up in a consistent state by dropping the write).
- profile0.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Mar"));
- profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jo"));
+ profile0.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Mar"));
+ profile2.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Jo"));
personal_data_->UpdateProfile(profile0);
personal_data_->AddProfile(profile1);
personal_data_->AddProfile(profile2);
@@ -1721,9 +1793,10 @@ TEST_F(PersonalDataManagerTest, ImportAddressProfiles_SameProfileWithConflict) {
const std::vector<AutofillProfile*>& results2 = personal_data_->GetProfiles();
// Full name, phone formatting and country are updated.
- expected.SetRawInfo(NAME_FULL, ASCIIToUTF16("George Washington"));
- expected.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("+1 650-555-6666"));
- expected.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US"));
+ expected.SetRawInfo(NAME_FULL, base::ASCIIToUTF16("George Washington"));
+ expected.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
+ base::ASCIIToUTF16("+1 650-555-6666"));
+ expected.SetRawInfo(ADDRESS_HOME_COUNTRY, base::ASCIIToUTF16("US"));
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected.Compare(*results2[0]));
}
@@ -1800,7 +1873,7 @@ TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MissingInfoInOld) {
test::SetProfileInfo(&expected2, "George", NULL,
"Washington", "theprez@gmail.com", NULL, "190 High Street", NULL,
"Philadelphia", "Pennsylvania", "19106", NULL, NULL);
- expected2.SetRawInfo(NAME_FULL, ASCIIToUTF16("George Washington"));
+ expected2.SetRawInfo(NAME_FULL, base::ASCIIToUTF16("George Washington"));
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected2.Compare(*results2[0]));
}
@@ -1881,7 +1954,7 @@ TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MissingInfoInNew) {
const std::vector<AutofillProfile*>& results2 = personal_data_->GetProfiles();
// The merge operation will populate the full name if it's empty.
- expected.SetRawInfo(NAME_FULL, ASCIIToUTF16("George Washington"));
+ expected.SetRawInfo(NAME_FULL, base::ASCIIToUTF16("George Washington"));
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected.Compare(*results2[0]));
}
@@ -2142,8 +2215,12 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_Valid) {
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2153,7 +2230,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_Valid) {
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
- "2999");
+ "2999", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -2168,7 +2245,10 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_Invalid) {
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_FALSE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_FALSE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_FALSE(imported_credit_card);
// Since no refresh is expected, reload the data from the database to make
@@ -2187,23 +2267,27 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MonthSelectInvalidText) {
AddFullCreditCardForm(&form, "Biggie Smalls", "4111-1111-1111-1111",
"Feb (2)", "2999");
// Add option values and contents to the expiration month field.
- ASSERT_EQ(ASCIIToUTF16("exp_month"), form.fields[2].name);
+ ASSERT_EQ(base::ASCIIToUTF16("exp_month"), form.fields[2].name);
std::vector<base::string16> values;
- values.push_back(ASCIIToUTF16("1"));
- values.push_back(ASCIIToUTF16("2"));
- values.push_back(ASCIIToUTF16("3"));
+ values.push_back(base::ASCIIToUTF16("1"));
+ values.push_back(base::ASCIIToUTF16("2"));
+ values.push_back(base::ASCIIToUTF16("3"));
std::vector<base::string16> contents;
- contents.push_back(ASCIIToUTF16("Jan (1)"));
- contents.push_back(ASCIIToUTF16("Feb (2)"));
- contents.push_back(ASCIIToUTF16("Mar (3)"));
+ contents.push_back(base::ASCIIToUTF16("Jan (1)"));
+ contents.push_back(base::ASCIIToUTF16("Feb (2)"));
+ contents.push_back(base::ASCIIToUTF16("Mar (3)"));
form.fields[2].option_values = values;
form.fields[2].option_contents = contents;
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2214,7 +2298,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MonthSelectInvalidText) {
// See that the invalid option text was converted to the right value.
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "02",
- "2999");
+ "2999", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -2229,8 +2313,12 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_TwoValidCards) {
FormStructure form_structure1(form1);
form_structure1.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure1, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure1, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2240,7 +2328,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_TwoValidCards) {
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
- "2999");
+ "2999", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -2252,8 +2340,11 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_TwoValidCards) {
FormStructure form_structure2(form2);
form_structure2.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card2;
- EXPECT_TRUE(ImportCreditCard(form_structure2, false, &imported_credit_card2));
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure2, false, &imported_credit_card2,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card2);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card2);
// Verify that the web database has been updated and the notification sent.
@@ -2262,7 +2353,8 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_TwoValidCards) {
base::RunLoop().Run();
CreditCard expected2(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&expected2, "", "5500000000000004", "02", "2999");
+ test::SetCreditCardInfo(&expected2, "", "5500000000000004", "02", "2999",
+ ""); // Imported cards have not billing info.
std::vector<CreditCard*> cards;
cards.push_back(&expected);
cards.push_back(&expected2);
@@ -2353,8 +2445,8 @@ TEST_F(PersonalDataManagerTest,
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "1111" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "1111" /* Visa */, "01", "2999", "");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
test::SetServerCreditCards(autofill_table_, server_cards);
// Type the same data as the masked card into a form.
@@ -2367,8 +2459,12 @@ TEST_F(PersonalDataManagerTest,
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2385,7 +2481,8 @@ TEST_F(PersonalDataManagerTest,
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ ""); // Imported cards have not billing info.
test::SetServerCreditCards(autofill_table_, server_cards);
// Type the same data as the unmasked card into a form.
@@ -2397,7 +2494,10 @@ TEST_F(PersonalDataManagerTest,
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_FALSE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_FALSE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_FALSE(imported_credit_card);
}
@@ -2410,8 +2510,12 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_SameCreditCardWithConflict) {
FormStructure form_structure1(form1);
form_structure1.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure1, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure1, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2421,7 +2525,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_SameCreditCardWithConflict) {
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
- "2998");
+ "2998", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -2435,7 +2539,9 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_SameCreditCardWithConflict) {
FormStructure form_structure2(form2);
form_structure2.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card2;
- EXPECT_TRUE(ImportCreditCard(form_structure2, false, &imported_credit_card2));
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure2, false, &imported_credit_card2,
+ &imported_credit_card_matches_masked_server_credit_card));
EXPECT_FALSE(imported_credit_card2);
// Verify that the web database has been updated and the notification sent.
@@ -2447,7 +2553,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_SameCreditCardWithConflict) {
// updated to "2999".
CreditCard expected2(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
- "2999");
+ "2999", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results2 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected2.Compare(*results2[0]));
@@ -2462,8 +2568,12 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_ShouldReturnLocalCard) {
FormStructure form_structure1(form1);
form_structure1.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure1, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure1, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2473,7 +2583,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_ShouldReturnLocalCard) {
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
- "2998");
+ "2998", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -2487,11 +2597,13 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_ShouldReturnLocalCard) {
FormStructure form_structure2(form2);
form_structure2.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card2;
- EXPECT_TRUE(ImportCreditCard(form_structure2,
- /* should_return_local_card= */ true,
- &imported_credit_card2));
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure2,
+ /* should_return_local_card= */ true, &imported_credit_card2,
+ &imported_credit_card_matches_masked_server_credit_card));
// The local card is returned after an update.
EXPECT_TRUE(imported_credit_card2);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
// Verify that the web database has been updated and the notification sent.
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -2502,7 +2614,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_ShouldReturnLocalCard) {
// updated to "2999".
CreditCard expected2(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
- "2999");
+ "2999", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results2 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected2.Compare(*results2[0]));
@@ -2517,8 +2629,12 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_EmptyCardWithConflict) {
FormStructure form_structure1(form1);
form_structure1.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure1, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure1, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2528,7 +2644,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_EmptyCardWithConflict) {
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
- "2998");
+ "2998", ""); // Imported cards have not billing info.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -2541,8 +2657,9 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_EmptyCardWithConflict) {
FormStructure form_structure2(form2);
form_structure2.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card2;
- EXPECT_FALSE(
- ImportCreditCard(form_structure2, false, &imported_credit_card2));
+ EXPECT_FALSE(ImportCreditCard(
+ form_structure2, false, &imported_credit_card2,
+ &imported_credit_card_matches_masked_server_credit_card));
EXPECT_FALSE(imported_credit_card2);
// Since no refresh is expected, reload the data from the database to make
@@ -2552,7 +2669,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_EmptyCardWithConflict) {
// No change is expected.
CreditCard expected2(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
- "2998");
+ "2998", "");
const std::vector<CreditCard*>& results2 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected2.Compare(*results2[0]));
@@ -2567,8 +2684,12 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInNew) {
FormStructure form_structure1(form1);
form_structure1.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure1, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure1, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2577,8 +2698,8 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInNew) {
base::RunLoop().Run();
CreditCard expected(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&expected,
- "Biggie Smalls", "4111111111111111", "01", "2999");
+ test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
+ "2999", "");
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected.Compare(*results[0]));
@@ -2592,7 +2713,9 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInNew) {
FormStructure form_structure2(form2);
form_structure2.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card2;
- EXPECT_TRUE(ImportCreditCard(form_structure2, false, &imported_credit_card2));
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure2, false, &imported_credit_card2,
+ &imported_credit_card_matches_masked_server_credit_card));
EXPECT_FALSE(imported_credit_card2);
// Since no refresh is expected, reload the data from the database to make
@@ -2601,8 +2724,8 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInNew) {
// No change is expected.
CreditCard expected2(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&expected2,
- "Biggie Smalls", "4111111111111111", "01", "2999");
+ test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
+ "2999", "");
const std::vector<CreditCard*>& results2 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected2.Compare(*results2[0]));
@@ -2616,8 +2739,9 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInNew) {
FormStructure form_structure3(form3);
form_structure3.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card3;
- EXPECT_FALSE(
- ImportCreditCard(form_structure3, false, &imported_credit_card3));
+ EXPECT_FALSE(ImportCreditCard(
+ form_structure3, false, &imported_credit_card3,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_FALSE(imported_credit_card3);
// Since no refresh is expected, reload the data from the database to make
@@ -2626,8 +2750,8 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInNew) {
// No change is expected.
CreditCard expected3(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&expected3,
- "Biggie Smalls", "4111111111111111", "01", "2999");
+ test::SetCreditCardInfo(&expected3, "Biggie Smalls", "4111111111111111", "01",
+ "2999", "");
const std::vector<CreditCard*>& results3 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results3.size());
EXPECT_EQ(0, expected3.Compare(*results3[0]));
@@ -2638,7 +2762,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInOld) {
// Note the empty name.
CreditCard saved_credit_card(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&saved_credit_card, "", "4111111111111111" /* Visa */,
- "01", "2998");
+ "01", "2998", "1");
personal_data_->AddCreditCard(saved_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2659,7 +2783,10 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInOld) {
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
EXPECT_FALSE(imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2671,7 +2798,7 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_MissingInfoInOld) {
// added to the existing credit card.
CreditCard expected2(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
- "2999");
+ "2999", "1");
const std::vector<CreditCard*>& results2 = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results2.size());
EXPECT_EQ(0, expected2.Compare(*results2[0]));
@@ -2683,8 +2810,8 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_SameCardWithSeparators) {
// Start with a single valid credit card stored via the preferences.
// Note the separators in the credit card number.
CreditCard saved_credit_card(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&saved_credit_card,
- "Biggie Smalls", "4111 1111 1111 1111" /* Visa */, "01", "2999");
+ test::SetCreditCardInfo(&saved_credit_card, "Biggie Smalls",
+ "4111 1111 1111 1111" /* Visa */, "01", "2999", "");
personal_data_->AddCreditCard(saved_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2704,7 +2831,10 @@ TEST_F(PersonalDataManagerTest, ImportCreditCard_SameCardWithSeparators) {
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
EXPECT_FALSE(imported_credit_card);
// Since no refresh is expected, reload the data from the database to make
@@ -2724,7 +2854,7 @@ TEST_F(PersonalDataManagerTest,
// Start with a verified credit card.
CreditCard credit_card(base::GenerateGUID(), kSettingsOrigin);
test::SetCreditCardInfo(&credit_card, "Biggie Smalls",
- "4111 1111 1111 1111" /* Visa */, "01", "2998");
+ "4111 1111 1111 1111" /* Visa */, "01", "2998", "");
EXPECT_TRUE(credit_card.IsVerified());
// Add the credit card to the database.
@@ -2743,7 +2873,10 @@ TEST_F(PersonalDataManagerTest,
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(ImportCreditCard(form_structure, false, &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(ImportCreditCard(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_FALSE(imported_credit_card);
// Since no refresh is expected, reload the data from the database to make
@@ -2790,9 +2923,12 @@ TEST_F(PersonalDataManagerTest, ImportFormData_OneAddressOneCreditCard) {
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_TRUE(personal_data_->ImportFormData(form_structure, false,
- &imported_credit_card));
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(personal_data_->ImportFormData(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2814,7 +2950,7 @@ TEST_F(PersonalDataManagerTest, ImportFormData_OneAddressOneCreditCard) {
// Test that the credit card has also been saved.
CreditCard expected_card(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected_card, "Biggie Smalls", "4111111111111111",
- "01", "2999");
+ "01", "2999", "");
const std::vector<CreditCard*>& results_cards =
personal_data_->GetCreditCards();
ASSERT_EQ(1U, results_cards.size());
@@ -2868,10 +3004,13 @@ TEST_F(PersonalDataManagerTest, ImportFormData_TwoAddressesOneCreditCard) {
FormStructure form_structure(form);
form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
+ bool imported_credit_card_matches_masked_server_credit_card;
// Still returns true because the credit card import was successful.
- EXPECT_TRUE(personal_data_->ImportFormData(form_structure, false,
- &imported_credit_card));
+ EXPECT_TRUE(personal_data_->ImportFormData(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
ASSERT_TRUE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
personal_data_->SaveImportedCreditCard(*imported_credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -2885,7 +3024,7 @@ TEST_F(PersonalDataManagerTest, ImportFormData_TwoAddressesOneCreditCard) {
// Test that the credit card has been saved.
CreditCard expected_card(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&expected_card, "Biggie Smalls", "4111111111111111",
- "01", "2999");
+ "01", "2999", "");
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
EXPECT_EQ(0, expected_card.Compare(*results[0]));
@@ -2914,7 +3053,7 @@ TEST_F(PersonalDataManagerTest, SaveImportedProfileWithVerifiedData) {
new_verified_profile.set_guid(base::GenerateGUID());
new_verified_profile.set_origin(kSettingsOrigin);
new_verified_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
- ASCIIToUTF16("1 234 567-8910"));
+ base::ASCIIToUTF16("1 234 567-8910"));
EXPECT_TRUE(new_verified_profile.IsVerified());
personal_data_->SaveImportedProfile(new_verified_profile);
@@ -2928,8 +3067,10 @@ TEST_F(PersonalDataManagerTest, SaveImportedProfileWithVerifiedData) {
const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
ASSERT_EQ(1U, results.size());
AutofillProfile expected(new_verified_profile);
- expected.SetRawInfo(NAME_FULL, ASCIIToUTF16("Marion Mitchell Morrison"));
- expected.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("+1 234-567-8910"));
+ expected.SetRawInfo(NAME_FULL,
+ base::ASCIIToUTF16("Marion Mitchell Morrison"));
+ expected.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
+ base::ASCIIToUTF16("+1 234-567-8910"));
EXPECT_EQ(0, expected.Compare(*results[0]))
<< "result = {" << *results[0] << "} | expected = {" << expected << "}";
}
@@ -2938,8 +3079,8 @@ TEST_F(PersonalDataManagerTest, SaveImportedProfileWithVerifiedData) {
TEST_F(PersonalDataManagerTest, SaveImportedCreditCardWithVerifiedData) {
// Start with a verified credit card.
CreditCard credit_card(base::GenerateGUID(), kSettingsOrigin);
- test::SetCreditCardInfo(&credit_card,
- "Biggie Smalls", "4111 1111 1111 1111" /* Visa */, "01", "2999");
+ test::SetCreditCardInfo(&credit_card, "Biggie Smalls",
+ "4111 1111 1111 1111" /* Visa */, "01", "2999", "");
EXPECT_TRUE(credit_card.IsVerified());
// Add the credit card to the database.
@@ -2952,7 +3093,8 @@ TEST_F(PersonalDataManagerTest, SaveImportedCreditCardWithVerifiedData) {
CreditCard new_verified_card = credit_card;
new_verified_card.set_guid(base::GenerateGUID());
- new_verified_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("B. Small"));
+ new_verified_card.SetRawInfo(CREDIT_CARD_NAME_FULL,
+ base::ASCIIToUTF16("B. Small"));
EXPECT_TRUE(new_verified_card.IsVerified());
personal_data_->SaveImportedCreditCard(new_verified_card);
@@ -2965,7 +3107,7 @@ TEST_F(PersonalDataManagerTest, SaveImportedCreditCardWithVerifiedData) {
// Expect that the saved credit card is updated.
const std::vector<CreditCard*>& results = personal_data_->GetCreditCards();
ASSERT_EQ(1U, results.size());
- EXPECT_EQ(ASCIIToUTF16("B. Small"),
+ EXPECT_EQ(base::ASCIIToUTF16("B. Small"),
results[0]->GetRawInfo(CREDIT_CARD_NAME_FULL));
}
@@ -3052,9 +3194,8 @@ TEST_F(PersonalDataManagerTest, GetNonEmptyTypes) {
// Test with credit card information also stored.
CreditCard credit_card(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(&credit_card,
- "John Dillinger", "423456789012" /* Visa */,
- "01", "2999");
+ test::SetCreditCardInfo(&credit_card, "John Dillinger",
+ "423456789012" /* Visa */, "01", "2999", "");
personal_data_->AddCreditCard(credit_card);
// Verify that the web database has been updated and the notification sent.
@@ -3106,8 +3247,8 @@ TEST_F(PersonalDataManagerTest, IncognitoReadOnly) {
personal_data_->AddProfile(steve_jobs);
CreditCard bill_gates(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(
- &bill_gates, "William H. Gates", "5555555555554444", "1", "2020");
+ test::SetCreditCardInfo(&bill_gates, "William H. Gates", "5555555555554444",
+ "1", "2020", "1");
personal_data_->AddCreditCard(bill_gates);
// The personal data manager should be able to read existing profiles in an
@@ -3123,8 +3264,8 @@ TEST_F(PersonalDataManagerTest, IncognitoReadOnly) {
personal_data_->AddProfile(test::GetFullProfile());
CreditCard larry_page(base::GenerateGUID(), "https://www.example.com");
- test::SetCreditCardInfo(
- &larry_page, "Lawrence Page", "4111111111111111", "10", "2025");
+ test::SetCreditCardInfo(&larry_page, "Lawrence Page", "4111111111111111",
+ "10", "2025", "1");
personal_data_->AddCreditCard(larry_page);
ResetPersonalDataManager(USER_MODE_INCOGNITO);
@@ -3132,31 +3273,33 @@ TEST_F(PersonalDataManagerTest, IncognitoReadOnly) {
EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
// Saving or creating profiles from imported profiles shouldn't work.
- steve_jobs.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Steve"));
+ steve_jobs.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Steve"));
personal_data_->SaveImportedProfile(steve_jobs);
- bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Bill Gates"));
+ bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL,
+ base::ASCIIToUTF16("Bill Gates"));
personal_data_->SaveImportedCreditCard(bill_gates);
ResetPersonalDataManager(USER_MODE_INCOGNITO);
- EXPECT_EQ(ASCIIToUTF16("Steven"),
+ EXPECT_EQ(base::ASCIIToUTF16("Steven"),
personal_data_->GetProfiles()[0]->GetRawInfo(NAME_FIRST));
EXPECT_EQ(
- ASCIIToUTF16("William H. Gates"),
+ base::ASCIIToUTF16("William H. Gates"),
personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME_FULL));
// Updating existing profiles shouldn't work.
- steve_jobs.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Steve"));
+ steve_jobs.SetRawInfo(NAME_FIRST, base::ASCIIToUTF16("Steve"));
personal_data_->UpdateProfile(steve_jobs);
- bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Bill Gates"));
+ bill_gates.SetRawInfo(CREDIT_CARD_NAME_FULL,
+ base::ASCIIToUTF16("Bill Gates"));
personal_data_->UpdateCreditCard(bill_gates);
ResetPersonalDataManager(USER_MODE_INCOGNITO);
- EXPECT_EQ(ASCIIToUTF16("Steven"),
+ EXPECT_EQ(base::ASCIIToUTF16("Steven"),
personal_data_->GetProfiles()[0]->GetRawInfo(NAME_FIRST));
EXPECT_EQ(
- ASCIIToUTF16("William H. Gates"),
+ base::ASCIIToUTF16("William H. Gates"),
personal_data_->GetCreditCards()[0]->GetRawInfo(CREDIT_CARD_NAME_FULL));
// Removing shouldn't work.
@@ -3482,8 +3625,8 @@ TEST_F(PersonalDataManagerTest,
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b459"));
test::SetCreditCardInfo(&server_cards.back(), "Emmet Dalton", "2110", "12",
- "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
test::SetServerCreditCards(autofill_table_, server_cards);
personal_data_->Refresh();
@@ -3493,7 +3636,7 @@ TEST_F(PersonalDataManagerTest,
std::vector<Suggestion> suggestions =
personal_data_->GetCreditCardSuggestions(AutofillType(CREDIT_CARD_NUMBER),
- ASCIIToUTF16("12345678"));
+ base::ASCIIToUTF16("12345678"));
// There should be no suggestions.
ASSERT_EQ(0U, suggestions.size());
@@ -3512,14 +3655,14 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_LocalCardsRanking) {
ASSERT_EQ(3U, suggestions.size());
// Ordered as expected.
- EXPECT_EQ(ASCIIToUTF16("John Dillinger"), suggestions[0].value);
- EXPECT_TRUE(suggestions[0].label.find(ASCIIToUTF16("9012")) !=
+ EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[0].value);
+ EXPECT_TRUE(suggestions[0].label.find(base::ASCIIToUTF16("9012")) !=
base::string16::npos);
- EXPECT_EQ(ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
- EXPECT_TRUE(suggestions[1].label.find(ASCIIToUTF16("8555")) !=
+ EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
+ EXPECT_TRUE(suggestions[1].label.find(base::ASCIIToUTF16("8555")) !=
base::string16::npos);
- EXPECT_EQ(ASCIIToUTF16("Bonnie Parker"), suggestions[2].value);
- EXPECT_TRUE(suggestions[2].label.find(ASCIIToUTF16("2109")) !=
+ EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[2].value);
+ EXPECT_TRUE(suggestions[2].label.find(base::ASCIIToUTF16("2109")) !=
base::string16::npos);
}
@@ -3533,15 +3676,15 @@ TEST_F(PersonalDataManagerTest,
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b459"));
test::SetCreditCardInfo(&server_cards.back(), "Emmet Dalton", "2110", "12",
- "2999");
+ "2999", "1");
server_cards.back().set_use_count(2);
server_cards.back().set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "b460"));
test::SetCreditCardInfo(&server_cards.back(), "Jesse James", "2109", "12",
- "2999");
+ "2999", "1");
server_cards.back().set_use_count(6);
server_cards.back().set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
@@ -3559,11 +3702,11 @@ TEST_F(PersonalDataManagerTest,
ASSERT_EQ(5U, suggestions.size());
// All cards should be ordered as expected.
- EXPECT_EQ(ASCIIToUTF16("Jesse James"), suggestions[0].value);
- EXPECT_EQ(ASCIIToUTF16("John Dillinger"), suggestions[1].value);
- EXPECT_EQ(ASCIIToUTF16("Clyde Barrow"), suggestions[2].value);
- EXPECT_EQ(ASCIIToUTF16("Emmet Dalton"), suggestions[3].value);
- EXPECT_EQ(ASCIIToUTF16("Bonnie Parker"), suggestions[4].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Jesse James"), suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[1].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[2].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Emmet Dalton"), suggestions[3].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[4].value);
}
// Test that expired cards are ordered by frecency and are always suggested
@@ -3575,14 +3718,15 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ExpiredCards) {
CreditCard credit_card0("002149C1-EE28-4213-A3B9-DA243FFF021B",
"https://www.example.com");
test::SetCreditCardInfo(&credit_card0, "Bonnie Parker",
- "518765432109" /* Mastercard */, "04", "2999");
+ "518765432109" /* Mastercard */, "04", "2999", "1");
personal_data_->AddCreditCard(credit_card0);
// Add an expired card with a higher frecency score.
CreditCard credit_card1("287151C8-6AB1-487C-9095-28E80BE5DA15",
"https://www.example.com");
test::SetCreditCardInfo(&credit_card1, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "1999");
+ "347666888555" /* American Express */, "04", "1999",
+ "1");
credit_card1.set_use_count(300);
credit_card1.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(10));
@@ -3595,7 +3739,7 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ExpiredCards) {
credit_card2.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
test::SetCreditCardInfo(&credit_card2, "John Dillinger",
- "423456789012" /* Visa */, "01", "1998");
+ "423456789012" /* Visa */, "01", "1998", "1");
personal_data_->AddCreditCard(credit_card2);
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -3611,11 +3755,11 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ExpiredCards) {
ASSERT_EQ(3U, suggestions.size());
// The never used non expired card should be suggested first.
- EXPECT_EQ(ASCIIToUTF16("Bonnie Parker"), suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[0].value);
// The expired cards should be sorted by frecency
- EXPECT_EQ(ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
- EXPECT_EQ(ASCIIToUTF16("John Dillinger"), suggestions[2].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
+ EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[2].value);
}
// Test that a card that doesn't have a number is not shown in the suggestions
@@ -3627,7 +3771,8 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_NumberMissing) {
CreditCard credit_card0("287151C8-6AB1-487C-9095-28E80BE5DA15",
"https://www.example.com");
test::SetCreditCardInfo(&credit_card0, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
credit_card0.set_use_count(3);
credit_card0.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
@@ -3638,7 +3783,8 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_NumberMissing) {
credit_card1.set_use_count(300);
credit_card1.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(10));
- test::SetCreditCardInfo(&credit_card1, "John Dillinger", "", "01", "2999");
+ test::SetCreditCardInfo(&credit_card1, "John Dillinger", "", "01", "2999",
+ "1");
personal_data_->AddCreditCard(credit_card1);
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -3654,9 +3800,10 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_NumberMissing) {
AutofillType(CREDIT_CARD_NUMBER),
/* field_contents= */ base::string16());
ASSERT_EQ(1U, suggestions.size());
- EXPECT_EQ(UTF8ToUTF16("Amex" + kUTF8MidlineEllipsis + "8555"),
- suggestions[0].value);
- EXPECT_EQ(ASCIIToUTF16("04/99"), suggestions[0].label);
+ EXPECT_EQ(
+ base::UTF8ToUTF16(std::string("Amex") + kUTF8MidlineEllipsis + "8555"),
+ suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("04/99"), suggestions[0].label);
}
// Tests the suggestions of duplicate local and server credit cards.
@@ -3672,28 +3819,29 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
// suggestions since the locally saved card takes precedence.
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "9012" /* Visa */, "01", "2999");
+ "9012" /* Visa */, "01", "2999", "1");
server_cards.back().set_use_count(2);
server_cards.back().set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
// This server card is identical to a local card, but has a different
// card type. Not a dupe and therefore both should appear in the suggestions.
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456"));
test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker", "2109", "12",
- "2999");
+ "2999", "1");
server_cards.back().set_use_count(3);
server_cards.back().set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
// This unmasked server card is an exact dupe of a local card. Therefore only
// this card should appear in the suggestions as full server cards have
// precedence over local cards.
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
server_cards.back().set_use_count(1);
server_cards.back().set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
@@ -3709,22 +3857,26 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
AutofillType(CREDIT_CARD_NAME_FULL),
/* field_contents= */ base::string16());
ASSERT_EQ(4U, suggestions.size());
- EXPECT_EQ(ASCIIToUTF16("John Dillinger"), suggestions[0].value);
- EXPECT_EQ(ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
- EXPECT_EQ(ASCIIToUTF16("Bonnie Parker"), suggestions[2].value);
- EXPECT_EQ(ASCIIToUTF16("Bonnie Parker"), suggestions[3].value);
+ EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[2].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[3].value);
suggestions = personal_data_->GetCreditCardSuggestions(
AutofillType(CREDIT_CARD_NUMBER), /* field_contents= */ base::string16());
ASSERT_EQ(4U, suggestions.size());
- EXPECT_EQ(UTF8ToUTF16("Visa" + kUTF8MidlineEllipsis + "9012"),
- suggestions[0].value);
- EXPECT_EQ(UTF8ToUTF16("Amex" + kUTF8MidlineEllipsis + "8555"),
- suggestions[1].value);
- EXPECT_EQ(UTF8ToUTF16("MasterCard" + kUTF8MidlineEllipsis + "2109"),
+ EXPECT_EQ(
+ base::UTF8ToUTF16(std::string("Visa") + kUTF8MidlineEllipsis + "9012"),
+ suggestions[0].value);
+ EXPECT_EQ(
+ base::UTF8ToUTF16(std::string("Amex") + kUTF8MidlineEllipsis + "8555"),
+ suggestions[1].value);
+ EXPECT_EQ(base::UTF8ToUTF16(std::string("Mastercard") + kUTF8MidlineEllipsis +
+ "2109"),
suggestions[2].value);
- EXPECT_EQ(UTF8ToUTF16("Visa" + kUTF8MidlineEllipsis + "2109"),
- suggestions[3].value);
+ EXPECT_EQ(
+ base::UTF8ToUTF16(std::string("Visa") + kUTF8MidlineEllipsis + "2109"),
+ suggestions[3].value);
}
// Tests that a full server card can be a dupe of more than one local card.
@@ -3739,7 +3891,8 @@ TEST_F(PersonalDataManagerTest,
// the local card should appear in the suggestions.
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
test::SetServerCreditCards(autofill_table_, server_cards);
personal_data_->Refresh();
@@ -3757,7 +3910,7 @@ TEST_F(PersonalDataManagerTest,
// of more than one local card.
CreditCard credit_card3("4141084B-72D7-4B73-90CF-3D6AC154673B",
"https://www.example.com");
- test::SetCreditCardInfo(&credit_card3, "Clyde Barrow", "", "04", "");
+ test::SetCreditCardInfo(&credit_card3, "Clyde Barrow", "", "04", "", "");
personal_data_->AddCreditCard(credit_card3);
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -3780,7 +3933,7 @@ TEST_F(PersonalDataManagerTest,
CreditCard local_card("287151C8-6AB1-487C-9095-28E80BE5DA15",
"https://www.example.com");
test::SetCreditCardInfo(&local_card, "Homer Simpson",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
local_card.set_use_count(3);
local_card.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
credit_cards.push_back(&local_card);
@@ -3788,7 +3941,7 @@ TEST_F(PersonalDataManagerTest,
// Create a full server card that is a duplicate of one of the local cards.
CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "c789");
test::SetCreditCardInfo(&full_server_card, "Homer Simpson",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
full_server_card.set_use_count(1);
full_server_card.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
@@ -3811,17 +3964,17 @@ TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_LocalShadowsMasked) {
local_card.set_use_count(300);
local_card.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(10));
test::SetCreditCardInfo(&local_card, "Homer Simpson",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
credit_cards.push_back(&local_card);
// Create a masked server card that is a duplicate of a local card.
CreditCard masked_card(CreditCard::MASKED_SERVER_CARD, "a123");
test::SetCreditCardInfo(&masked_card, "Homer Simpson", "9012" /* Visa */,
- "01", "2999");
+ "01", "2999", "1");
masked_card.set_use_count(2);
masked_card.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
- masked_card.SetTypeForMaskedCard(kVisaCard);
+ masked_card.SetNetworkForMaskedCard(kVisaCard);
credit_cards.push_back(&masked_card);
PersonalDataManager::DedupeCreditCardToSuggest(&credit_cards);
@@ -3838,7 +3991,7 @@ TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_FullServerAndMasked) {
// Create a full server card that is a duplicate of one of the local cards.
CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "c789");
test::SetCreditCardInfo(&full_server_card, "Homer Simpson",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
full_server_card.set_use_count(1);
full_server_card.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
@@ -3847,11 +4000,11 @@ TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_FullServerAndMasked) {
// Create a masked server card that is a duplicate of a local card.
CreditCard masked_card(CreditCard::MASKED_SERVER_CARD, "a123");
test::SetCreditCardInfo(&masked_card, "Homer Simpson", "9012" /* Visa */,
- "01", "2999");
+ "01", "2999", "1");
masked_card.set_use_count(2);
masked_card.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
- masked_card.SetTypeForMaskedCard(kVisaCard);
+ masked_card.SetNetworkForMaskedCard(kVisaCard);
credit_cards.push_back(&masked_card);
PersonalDataManager::DedupeCreditCardToSuggest(&credit_cards);
@@ -3869,23 +4022,25 @@ TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_DifferentCards) {
credit_card2.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(1));
test::SetCreditCardInfo(&credit_card2, "Homer Simpson",
- "518765432109" /* Mastercard */, "", "");
+ "518765432109" /* Mastercard */, "", "", "");
credit_cards.push_back(&credit_card2);
// Create a masked server card that is slightly different of the local card.
CreditCard credit_card4(CreditCard::MASKED_SERVER_CARD, "b456");
- test::SetCreditCardInfo(&credit_card4, "Homer Simpson", "2109", "12", "2999");
+ test::SetCreditCardInfo(&credit_card4, "Homer Simpson", "2109", "12", "2999",
+ "1");
credit_card4.set_use_count(3);
credit_card4.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
- credit_card4.SetTypeForMaskedCard(kVisaCard);
+ credit_card4.SetNetworkForMaskedCard(kVisaCard);
credit_cards.push_back(&credit_card4);
// Create a full server card that is slightly different of the two other
// cards.
CreditCard credit_card5(CreditCard::FULL_SERVER_CARD, "c789");
test::SetCreditCardInfo(&credit_card5, "Homer Simpson",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
credit_card5.set_use_count(1);
credit_card5.set_use_date(AutofillClock::Now() -
base::TimeDelta::FromDays(15));
@@ -3908,7 +4063,7 @@ TEST_F(PersonalDataManagerTest, RecordUseOf) {
CreditCard credit_card(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card, "John Dillinger",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
EXPECT_EQ(1U, credit_card.use_count());
EXPECT_EQ(kArbitraryTime, credit_card.use_date());
EXPECT_EQ(kArbitraryTime, credit_card.modification_date());
@@ -3964,17 +4119,18 @@ TEST_F(PersonalDataManagerTest, UpdateServerCreditCardUsageStats) {
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "9012" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "9012" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456"));
test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker",
- "4444" /* Mastercard */, "12", "2999");
- server_cards.back().SetTypeForMaskedCard(kMasterCard);
+ "4444" /* Mastercard */, "12", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kMasterCard);
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
// Create the test clock and set the time to a specific value.
TestAutofillClock test_clock;
@@ -4004,7 +4160,7 @@ TEST_F(PersonalDataManagerTest, UpdateServerCreditCardUsageStats) {
CreditCard* unmasked_card = &server_cards.front();
unmasked_card->set_record_type(CreditCard::FULL_SERVER_CARD);
- unmasked_card->SetNumber(ASCIIToUTF16("423456789012"));
+ unmasked_card->SetNumber(base::ASCIIToUTF16("423456789012"));
EXPECT_NE(0, unmasked_card->Compare(
*personal_data_->GetCreditCards().front()));
personal_data_->UpdateServerCreditCard(*unmasked_card);
@@ -4068,7 +4224,7 @@ TEST_F(PersonalDataManagerTest, UpdateServerCreditCardUsageStats) {
// Upgrading to unmasked retains the usage stats (and increments them).
CreditCard* unmasked_card2 = &server_cards[1];
unmasked_card2->set_record_type(CreditCard::FULL_SERVER_CARD);
- unmasked_card2->SetNumber(ASCIIToUTF16("5555555555554444"));
+ unmasked_card2->SetNumber(base::ASCIIToUTF16("5555555555554444"));
personal_data_->UpdateServerCreditCard(*unmasked_card2);
server_cards[1].set_guid(personal_data_->GetCreditCards()[1]->guid());
@@ -4086,8 +4242,8 @@ TEST_F(PersonalDataManagerTest, ClearAllServerData) {
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "9012" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "9012" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
test::SetServerCreditCards(autofill_table_, server_cards);
personal_data_->Refresh();
@@ -4105,18 +4261,19 @@ TEST_F(PersonalDataManagerTest, ClearAllServerData) {
EXPECT_TRUE(personal_data_->GetCreditCards().empty());
}
-TEST_F(PersonalDataManagerTest, DontDuplicateServerCard) {
+TEST_F(PersonalDataManagerTest, AllowDuplicateMaskedServerCard) {
EnableWalletCardImport();
std::vector<CreditCard> server_cards;
server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "1881" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "1881" /* Visa */, "01", "2999", "");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "");
test::SetServerCreditCards(autofill_table_, server_cards);
personal_data_->Refresh();
@@ -4125,50 +4282,92 @@ TEST_F(PersonalDataManagerTest, DontDuplicateServerCard) {
base::RunLoop().Run();
// A valid credit card form. A user re-enters one of their masked cards.
- // We shouldn't offer to save. It's possible this is actually a different card
- // but it's very unlikely. And these circumstances will also arise if the user
- // has the same card available locally and synced from payments.
- FormData form1;
+ // We should offer to save locally so that user can fill future credit card
+ // forms without unmasking.
+ FormData form;
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "John Dillinger",
"text", &field);
- form1.fields.push_back(field);
+ form.fields.push_back(field);
test::CreateTestFormField("Card Number:", "card_number", "4012888888881881",
"text", &field);
- form1.fields.push_back(field);
+ form.fields.push_back(field);
test::CreateTestFormField("Exp Month:", "exp_month", "01", "text", &field);
- form1.fields.push_back(field);
+ form.fields.push_back(field);
test::CreateTestFormField("Exp Year:", "exp_year", "2999", "text", &field);
- form1.fields.push_back(field);
+ form.fields.push_back(field);
- FormStructure form_structure1(form1);
- form_structure1.DetermineHeuristicTypes(nullptr /* ukm_service */);
+ FormStructure form_structure(form);
+ form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
std::unique_ptr<CreditCard> imported_credit_card;
- EXPECT_FALSE(personal_data_->ImportFormData(form_structure1, false,
- &imported_credit_card));
- EXPECT_FALSE(imported_credit_card);
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_TRUE(personal_data_->ImportFormData(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
+ ASSERT_TRUE(imported_credit_card);
+ EXPECT_TRUE(imported_credit_card_matches_masked_server_credit_card);
+ personal_data_->SaveImportedCreditCard(*imported_credit_card);
+
+ // Verify that the web database has been updated and the notification sent.
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .WillOnce(QuitMainMessageLoop());
+ base::RunLoop().Run();
+
+ CreditCard local_card(base::GenerateGUID(), "https://www.example.com");
+ test::SetCreditCardInfo(&local_card, "John Dillinger", "4012888888881881",
+ "01", "2999", "");
+ const std::vector<CreditCard*>& results =
+ personal_data_->GetLocalCreditCards();
+ ASSERT_EQ(1U, results.size());
+ EXPECT_EQ(0, local_card.Compare(*results[0]));
+ EXPECT_EQ(3U, personal_data_->GetCreditCards().size());
+}
+
+TEST_F(PersonalDataManagerTest, DontDuplicateFullServerCard) {
+ EnableWalletCardImport();
+
+ std::vector<CreditCard> server_cards;
+ server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
+ test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
+ "1881" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
+
+ server_cards.push_back(CreditCard(CreditCard::FULL_SERVER_CARD, "c789"));
+ test::SetCreditCardInfo(&server_cards.back(), "Clyde Barrow",
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
+
+ test::SetServerCreditCards(autofill_table_, server_cards);
+ personal_data_->Refresh();
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .WillOnce(QuitMainMessageLoop());
+ base::RunLoop().Run();
// A user re-types (or fills with) an unmasked card. Don't offer to save
// here, either. Since it's unmasked, we know for certain that it's the same
// card.
- FormData form2;
+ FormData form;
+ FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
"text", &field);
- form2.fields.push_back(field);
+ form.fields.push_back(field);
test::CreateTestFormField("Card Number:", "card_number", "347666888555",
"text", &field);
- form2.fields.push_back(field);
+ form.fields.push_back(field);
test::CreateTestFormField("Exp Month:", "exp_month", "04", "text", &field);
- form2.fields.push_back(field);
+ form.fields.push_back(field);
test::CreateTestFormField("Exp Year:", "exp_year", "2999", "text", &field);
- form2.fields.push_back(field);
+ form.fields.push_back(field);
- FormStructure form_structure2(form2);
- form_structure2.DetermineHeuristicTypes(nullptr /* ukm_service */);
- std::unique_ptr<CreditCard> imported_credit_card2;
- EXPECT_FALSE(personal_data_->ImportFormData(form_structure2, false,
- &imported_credit_card2));
- EXPECT_FALSE(imported_credit_card2);
+ FormStructure form_structure(form);
+ form_structure.DetermineHeuristicTypes(nullptr /* ukm_service */);
+ std::unique_ptr<CreditCard> imported_credit_card;
+ bool imported_credit_card_matches_masked_server_credit_card;
+ EXPECT_FALSE(personal_data_->ImportFormData(
+ form_structure, false, &imported_credit_card,
+ &imported_credit_card_matches_masked_server_credit_card));
+ EXPECT_FALSE(imported_credit_card);
+ EXPECT_FALSE(imported_credit_card_matches_masked_server_credit_card);
}
// Tests the SaveImportedProfile method with different profiles to make sure the
@@ -4176,456 +4375,448 @@ TEST_F(PersonalDataManagerTest, DontDuplicateServerCard) {
typedef struct {
autofill::ServerFieldType field_type;
std::string field_value;
- } ProfileField;
-
- typedef std::vector<ProfileField> ProfileFields;
-
- typedef struct {
- // Each test starts with a default pre-existing profile and applies these
- // changes to it.
- ProfileFields changes_to_original;
- // Each test saves a second profile. Applies these changes to the default
- // values before saving.
- ProfileFields changes_to_new;
- // For tests with profile merging, makes sure that these fields' values are
- // the ones we expect (depending on the test).
- ProfileFields changed_field_values;
- } SaveImportedProfileTestCase;
-
- class SaveImportedProfileTest
- : public PersonalDataManagerTestBase,
- public testing::TestWithParam<SaveImportedProfileTestCase> {
- public:
- SaveImportedProfileTest() {}
- ~SaveImportedProfileTest() override {}
-
- void SetUp() override {
- OSCryptMocker::SetUpWithSingleton();
- prefs_ = test::PrefServiceForTesting();
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- base::FilePath path = temp_dir_.GetPath().AppendASCII("TestWebDB");
- web_database_ =
- new WebDatabaseService(path, base::ThreadTaskRunnerHandle::Get(),
- base::ThreadTaskRunnerHandle::Get());
-
- // Setup account tracker.
- signin_client_.reset(new TestSigninClient(prefs_.get()));
- account_tracker_.reset(new AccountTrackerService());
- account_tracker_->Initialize(signin_client_.get());
- signin_manager_.reset(new FakeSigninManagerBase(signin_client_.get(),
- account_tracker_.get()));
- signin_manager_->Initialize(prefs_.get());
-
- // Hacky: hold onto a pointer but pass ownership.
- autofill_table_ = new AutofillTable;
- web_database_->AddTable(
- std::unique_ptr<WebDatabaseTable>(autofill_table_));
- web_database_->LoadDatabase();
- autofill_database_service_ = new AutofillWebDataService(
- web_database_, base::ThreadTaskRunnerHandle::Get(),
- base::ThreadTaskRunnerHandle::Get(),
- WebDataServiceBase::ProfileErrorCallback());
- autofill_database_service_->Init();
-
- test::DisableSystemServices(prefs_.get());
- ResetPersonalDataManager(USER_MODE_NORMAL);
-
- // Reset the deduping pref to its default value.
- personal_data_->pref_service_->SetInteger(
- prefs::kAutofillLastVersionDeduped, 0);
- personal_data_->pref_service_->SetBoolean(
- prefs::kAutofillProfileUseDatesFixed, false);
- }
+} ProfileField;
- void TearDown() override {
- // Order of destruction is important as AutofillManager relies on
- // PersonalDataManager to be around when it gets destroyed.
- signin_manager_->Shutdown();
- signin_manager_.reset();
+typedef std::vector<ProfileField> ProfileFields;
- account_tracker_->Shutdown();
- account_tracker_.reset();
- signin_client_.reset();
+typedef struct {
+ // Each test starts with a default pre-existing profile and applies these
+ // changes to it.
+ ProfileFields changes_to_original;
+ // Each test saves a second profile. Applies these changes to the default
+ // values before saving.
+ ProfileFields changes_to_new;
+ // For tests with profile merging, makes sure that these fields' values are
+ // the ones we expect (depending on the test).
+ ProfileFields changed_field_values;
+} SaveImportedProfileTestCase;
+
+class SaveImportedProfileTest
+ : public PersonalDataManagerTestBase,
+ public testing::TestWithParam<SaveImportedProfileTestCase> {
+ public:
+ SaveImportedProfileTest() {}
+ ~SaveImportedProfileTest() override {}
- test::DisableSystemServices(prefs_.get());
- OSCryptMocker::TearDown();
- }
- };
-
- TEST_P(SaveImportedProfileTest, SaveImportedProfile) {
- // Create the test clock.
- TestAutofillClock test_clock;
- auto test_case = GetParam();
- // Set the time to a specific value.
- test_clock.SetNow(kArbitraryTime);
-
- SetupReferenceProfile();
- const std::vector<AutofillProfile*>& initial_profiles =
- personal_data_->GetProfiles();
-
- // Apply changes to the original profile (if applicable).
- for (ProfileField change : test_case.changes_to_original) {
- initial_profiles.front()->SetRawInfo(
- change.field_type, base::UTF8ToUTF16(change.field_value));
- }
+ void SetUp() override {
+ OSCryptMocker::SetUpWithSingleton();
+ prefs_ = test::PrefServiceForTesting();
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ base::FilePath path = temp_dir_.GetPath().AppendASCII("TestWebDB");
+ web_database_ =
+ new WebDatabaseService(path, base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get());
- // Set the time to a bigger value.
- test_clock.SetNow(kSomeLaterTime);
+ // Setup account tracker.
+ signin_client_.reset(new TestSigninClient(prefs_.get()));
+ account_tracker_.reset(new AccountTrackerService());
+ account_tracker_->Initialize(signin_client_.get());
+ signin_manager_.reset(new FakeSigninManagerBase(signin_client_.get(),
+ account_tracker_.get()));
+ signin_manager_->Initialize(prefs_.get());
- AutofillProfile profile2(base::GenerateGUID(), "https://www.example.com");
- test::SetProfileInfo(&profile2, "Marion", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox", "123 Zoo St", "unit 5",
- "Hollywood", "CA", "91601", "US", "12345678910");
+ // Hacky: hold onto a pointer but pass ownership.
+ autofill_table_ = new AutofillTable;
+ web_database_->AddTable(std::unique_ptr<WebDatabaseTable>(autofill_table_));
+ web_database_->LoadDatabase();
+ autofill_database_service_ = new AutofillWebDataService(
+ web_database_, base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(),
+ WebDataServiceBase::ProfileErrorCallback());
+ autofill_database_service_->Init();
- // Apply changes to the second profile (if applicable).
- for (ProfileField change : test_case.changes_to_new) {
- profile2.SetRawInfo(change.field_type,
- base::UTF8ToUTF16(change.field_value));
- }
+ test::DisableSystemServices(prefs_.get());
+ ResetPersonalDataManager(USER_MODE_NORMAL);
+
+ // Reset the deduping pref to its default value.
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionDeduped, 0);
+ personal_data_->pref_service_->SetBoolean(
+ prefs::kAutofillProfileUseDatesFixed, false);
+ }
+
+ void TearDown() override {
+ // Order of destruction is important as AutofillManager relies on
+ // PersonalDataManager to be around when it gets destroyed.
+ signin_manager_->Shutdown();
+ signin_manager_.reset();
+
+ account_tracker_->Shutdown();
+ account_tracker_.reset();
+ signin_client_.reset();
+
+ test::DisableSystemServices(prefs_.get());
+ OSCryptMocker::TearDown();
+ }
+};
- personal_data_->SaveImportedProfile(profile2);
+TEST_P(SaveImportedProfileTest, SaveImportedProfile) {
+ // Create the test clock.
+ TestAutofillClock test_clock;
+ auto test_case = GetParam();
+ // Set the time to a specific value.
+ test_clock.SetNow(kArbitraryTime);
- const std::vector<AutofillProfile*>& saved_profiles =
- personal_data_->GetProfiles();
+ SetupReferenceProfile();
+ const std::vector<AutofillProfile*>& initial_profiles =
+ personal_data_->GetProfiles();
- // If there are no merge changes to verify, make sure that two profiles were
- // saved.
- if (test_case.changed_field_values.empty()) {
- EXPECT_EQ(2U, saved_profiles.size());
- } else {
- EXPECT_EQ(1U, saved_profiles.size());
-
- // Make sure the new information was merged correctly.
- for (ProfileField changed_field : test_case.changed_field_values) {
- EXPECT_EQ(base::UTF8ToUTF16(changed_field.field_value),
- saved_profiles.front()->GetRawInfo(changed_field.field_type));
- }
- // Verify that the merged profile's use count, use date and modification
- // date were properly updated.
- EXPECT_EQ(1U, saved_profiles.front()->use_count());
- EXPECT_EQ(kSomeLaterTime, saved_profiles.front()->use_date());
- EXPECT_EQ(kSomeLaterTime, saved_profiles.front()->modification_date());
- }
+ // Apply changes to the original profile (if applicable).
+ for (ProfileField change : test_case.changes_to_original) {
+ initial_profiles.front()->SetRawInfo(change.field_type,
+ base::UTF8ToUTF16(change.field_value));
+ }
+
+ // Set the time to a bigger value.
+ test_clock.SetNow(kSomeLaterTime);
+
+ AutofillProfile profile2(base::GenerateGUID(), "https://www.example.com");
+ test::SetProfileInfo(&profile2, "Marion", "Mitchell", "Morrison",
+ "johnwayne@me.xyz", "Fox", "123 Zoo St", "unit 5",
+ "Hollywood", "CA", "91601", "US", "12345678910");
+
+ // Apply changes to the second profile (if applicable).
+ for (ProfileField change : test_case.changes_to_new) {
+ profile2.SetRawInfo(change.field_type,
+ base::UTF8ToUTF16(change.field_value));
+ }
- // Erase the profiles for the next test.
- ResetProfiles();
+ personal_data_->SaveImportedProfile(profile2);
+
+ const std::vector<AutofillProfile*>& saved_profiles =
+ personal_data_->GetProfiles();
+
+ // If there are no merge changes to verify, make sure that two profiles were
+ // saved.
+ if (test_case.changed_field_values.empty()) {
+ EXPECT_EQ(2U, saved_profiles.size());
+ } else {
+ EXPECT_EQ(1U, saved_profiles.size());
+
+ // Make sure the new information was merged correctly.
+ for (ProfileField changed_field : test_case.changed_field_values) {
+ EXPECT_EQ(base::UTF8ToUTF16(changed_field.field_value),
+ saved_profiles.front()->GetRawInfo(changed_field.field_type));
+ }
+ // Verify that the merged profile's use count, use date and modification
+ // date were properly updated.
+ EXPECT_EQ(1U, saved_profiles.front()->use_count());
+ EXPECT_EQ(kSomeLaterTime, saved_profiles.front()->use_date());
+ EXPECT_EQ(kSomeLaterTime, saved_profiles.front()->modification_date());
}
- INSTANTIATE_TEST_CASE_P(
- PersonalDataManagerTest,
- SaveImportedProfileTest,
- testing::Values(
- // Test that saving an identical profile except for the name results
- // in two profiles being saved.
- SaveImportedProfileTestCase{ProfileFields(),
- {{NAME_FIRST, "Marionette"}}},
-
- // Test that saving an identical profile except with the middle name
- // initial instead of the full middle name results in the profiles
- // getting merged and the full middle name being kept.
- SaveImportedProfileTestCase{
- ProfileFields(),
- {{NAME_MIDDLE, "M"}},
- {{NAME_MIDDLE, "Mitchell"},
- {NAME_FULL, "Marion Mitchell Morrison"}}},
-
- // Test that saving an identical profile except with the full middle
- // name instead of the middle name initial results in the profiles
- // getting merged and the full middle name replacing the initial.
- SaveImportedProfileTestCase{{{NAME_MIDDLE, "M"}},
- {{NAME_MIDDLE, "Mitchell"}},
- {{NAME_MIDDLE, "Mitchell"}}},
-
- // Test that saving an identical profile except with no middle name
- // results in the profiles getting merged and the full middle name
- // being kept.
- SaveImportedProfileTestCase{ProfileFields(),
- {{NAME_MIDDLE, ""}},
- {{NAME_MIDDLE, "Mitchell"}}},
-
- // Test that saving an identical profile except with a middle name
- // initial results in the profiles getting merged and the middle name
- // initial being saved.
- SaveImportedProfileTestCase{{{NAME_MIDDLE, ""}},
- {{NAME_MIDDLE, "M"}},
- {{NAME_MIDDLE, "M"}}},
-
- // Test that saving an identical profile except with a middle name
- // results in the profiles getting merged and the full middle name
- // being saved.
- SaveImportedProfileTestCase{{{NAME_MIDDLE, ""}},
- {{NAME_MIDDLE, "Mitchell"}},
- {{NAME_MIDDLE, "Mitchell"}}},
-
- // Test that saving a identical profile except with the full name set
- // instead of the name parts results in the two profiles being merged
- // and all the name parts kept and the full name being added.
- SaveImportedProfileTestCase{
- {
- {NAME_FIRST, "Marion"},
- {NAME_MIDDLE, "Mitchell"},
- {NAME_LAST, "Morrison"},
- {NAME_FULL, ""},
- },
- {
- {NAME_FIRST, ""},
- {NAME_MIDDLE, ""},
- {NAME_LAST, ""},
- {NAME_FULL, "Marion Mitchell Morrison"},
- },
- {
- {NAME_FIRST, "Marion"},
- {NAME_MIDDLE, "Mitchell"},
- {NAME_LAST, "Morrison"},
- {NAME_FULL, "Marion Mitchell Morrison"},
- },
- },
-
- // Test that saving a identical profile except with the name parts set
- // instead of the full name results in the two profiles being merged
- // and the full name being kept and all the name parts being added.
- SaveImportedProfileTestCase{
- {
- {NAME_FIRST, ""},
- {NAME_MIDDLE, ""},
- {NAME_LAST, ""},
- {NAME_FULL, "Marion Mitchell Morrison"},
- },
- {
- {NAME_FIRST, "Marion"},
- {NAME_MIDDLE, "Mitchell"},
- {NAME_LAST, "Morrison"},
- {NAME_FULL, ""},
- },
- {
- {NAME_FIRST, "Marion"},
- {NAME_MIDDLE, "Mitchell"},
- {NAME_LAST, "Morrison"},
- {NAME_FULL, "Marion Mitchell Morrison"},
- },
- },
-
- // Test that saving a profile that has only a full name set does not
- // get merged with a profile with only the name parts set if the names
- // are different.
- SaveImportedProfileTestCase{
- {
- {NAME_FIRST, "Marion"},
- {NAME_MIDDLE, "Mitchell"},
- {NAME_LAST, "Morrison"},
- {NAME_FULL, ""},
- },
- {
- {NAME_FIRST, ""},
- {NAME_MIDDLE, ""},
- {NAME_LAST, ""},
- {NAME_FULL, "John Thompson Smith"},
- },
- },
-
- // Test that saving a profile that has only the name parts set does
- // not get merged with a profile with only the full name set if the
- // names are different.
- SaveImportedProfileTestCase{
- {
- {NAME_FIRST, ""},
- {NAME_MIDDLE, ""},
- {NAME_LAST, ""},
- {NAME_FULL, "John Thompson Smith"},
- },
- {
- {NAME_FIRST, "Marion"},
- {NAME_MIDDLE, "Mitchell"},
- {NAME_LAST, "Morrison"},
- {NAME_FULL, ""},
- },
- },
-
- // Test that saving an identical profile except for the first address
- // line results in two profiles being saved.
- SaveImportedProfileTestCase{
- ProfileFields(),
- {{ADDRESS_HOME_LINE1, "123 Aquarium St."}}},
-
- // Test that saving an identical profile except for the second address
- // line results in two profiles being saved.
- SaveImportedProfileTestCase{ProfileFields(),
- {{ADDRESS_HOME_LINE2, "unit 7"}}},
-
- // Tests that saving an identical profile that has a new piece of
- // information (company name) results in a merge and that the original
- // empty value gets overwritten by the new information.
- SaveImportedProfileTestCase{{{COMPANY_NAME, ""}},
- ProfileFields(),
- {{COMPANY_NAME, "Fox"}}},
-
- // Tests that saving an identical profile except a loss of information
- // results in a merge but the original value is not overwritten (no
- // information loss).
- SaveImportedProfileTestCase{ProfileFields(),
- {{COMPANY_NAME, ""}},
- {{COMPANY_NAME, "Fox"}}},
-
- // Tests that saving an identical profile except a slightly different
- // postal code results in a merge with the new value kept.
- SaveImportedProfileTestCase{{{ADDRESS_HOME_ZIP, "R2C 0A1"}},
- {{ADDRESS_HOME_ZIP, "R2C0A1"}},
- {{ADDRESS_HOME_ZIP, "R2C0A1"}}},
- SaveImportedProfileTestCase{{{ADDRESS_HOME_ZIP, "R2C0A1"}},
- {{ADDRESS_HOME_ZIP, "R2C 0A1"}},
- {{ADDRESS_HOME_ZIP, "R2C 0A1"}}},
- SaveImportedProfileTestCase{{{ADDRESS_HOME_ZIP, "r2c 0a1"}},
- {{ADDRESS_HOME_ZIP, "R2C0A1"}},
- {{ADDRESS_HOME_ZIP, "R2C0A1"}}},
-
- // Tests that saving an identical profile plus a new piece of
- // information on the address line 2 results in a merge and that the
- // original empty value gets overwritten by the new information.
- SaveImportedProfileTestCase{{{ADDRESS_HOME_LINE2, ""}},
- ProfileFields(),
- {{ADDRESS_HOME_LINE2, "unit 5"}}},
-
- // Tests that saving an identical profile except a loss of information
- // on the address line 2 results in a merge but that the original
- // value gets not overwritten (no information loss).
- SaveImportedProfileTestCase{ProfileFields(),
- {{ADDRESS_HOME_LINE2, ""}},
- {{ADDRESS_HOME_LINE2, "unit 5"}}},
-
- // Tests that saving an identical except with more punctuation in the
- // fist address line, while the second is empty, results in a merge
- // and that the original address gets overwritten.
- SaveImportedProfileTestCase{
- {{ADDRESS_HOME_LINE2, ""}},
- {{ADDRESS_HOME_LINE2, ""}, {ADDRESS_HOME_LINE1, "123, Zoo St."}},
- {{ADDRESS_HOME_LINE1, "123, Zoo St."}}},
-
- // Tests that saving an identical profile except with less punctuation
- // in the fist address line, while the second is empty, results in a
- // merge and that the longer address is retained.
- SaveImportedProfileTestCase{
- {{ADDRESS_HOME_LINE2, ""}, {ADDRESS_HOME_LINE1, "123, Zoo St."}},
- {{ADDRESS_HOME_LINE2, ""}},
- {{ADDRESS_HOME_LINE1, "123 Zoo St"}}},
-
- // Tests that saving an identical profile except additional
- // punctuation in the two address lines results in a merge and that
- // the newer address is retained.
- SaveImportedProfileTestCase{ProfileFields(),
- {{ADDRESS_HOME_LINE1, "123, Zoo St."},
- {ADDRESS_HOME_LINE2, "unit. 5"}},
- {{ADDRESS_HOME_LINE1, "123, Zoo St."},
- {ADDRESS_HOME_LINE2, "unit. 5"}}},
-
- // Tests that saving an identical profile except less punctuation in
- // the two address lines results in a merge and that the newer address
- // is retained.
- SaveImportedProfileTestCase{{{ADDRESS_HOME_LINE1, "123, Zoo St."},
- {ADDRESS_HOME_LINE2, "unit. 5"}},
- ProfileFields(),
- {{ADDRESS_HOME_LINE1, "123 Zoo St"},
- {ADDRESS_HOME_LINE2, "unit 5"}}},
-
- // Tests that saving an identical profile with accented characters in
- // the two address lines results in a merge and that the newer address
- // is retained.
- SaveImportedProfileTestCase{ProfileFields(),
- {{ADDRESS_HOME_LINE1, "123 Zôö St"},
- {ADDRESS_HOME_LINE2, "üñìt 5"}},
- {{ADDRESS_HOME_LINE1, "123 Zôö St"},
- {ADDRESS_HOME_LINE2, "üñìt 5"}}},
-
- // Tests that saving an identical profile without accented characters
- // in the two address lines results in a merge and that the newer
- // address is retained.
- SaveImportedProfileTestCase{{{ADDRESS_HOME_LINE1, "123 Zôö St"},
- {ADDRESS_HOME_LINE2, "üñìt 5"}},
- ProfileFields(),
- {{ADDRESS_HOME_LINE1, "123 Zoo St"},
- {ADDRESS_HOME_LINE2, "unit 5"}}},
-
- // Tests that saving an identical profile except that the address line
- // 1 is in the address line 2 results in a merge and that the
- // multi-lne address is retained.
- SaveImportedProfileTestCase{
- ProfileFields(),
- {{ADDRESS_HOME_LINE1, "123 Zoo St, unit 5"},
- {ADDRESS_HOME_LINE2, ""}},
- {{ADDRESS_HOME_LINE1, "123 Zoo St"},
- {ADDRESS_HOME_LINE2, "unit 5"}}},
-
- // Tests that saving an identical profile except that the address line
- // 2 contains part of the old address line 1 results in a merge and
- // that the original address lines of the reference profile get
- // overwritten.
- SaveImportedProfileTestCase{
- {{ADDRESS_HOME_LINE1, "123 Zoo St, unit 5"},
- {ADDRESS_HOME_LINE2, ""}},
- ProfileFields(),
- {{ADDRESS_HOME_LINE1, "123 Zoo St"},
- {ADDRESS_HOME_LINE2, "unit 5"}}},
-
- // Tests that saving an identical profile except that the state is the
- // abbreviation instead of the full form results in a merge and that
- // the original state gets overwritten.
- SaveImportedProfileTestCase{{{ADDRESS_HOME_STATE, "California"}},
- ProfileFields(),
- {{ADDRESS_HOME_STATE, "CA"}}},
-
- // Tests that saving an identical profile except that the state is the
- // full form instead of the abbreviation results in a merge and that
- // the abbreviated state is retained.
- SaveImportedProfileTestCase{ProfileFields(),
- {{ADDRESS_HOME_STATE, "California"}},
- {{ADDRESS_HOME_STATE, "CA"}}},
-
- // Tests that saving and identical profile except that the company
- // name has different punctuation and case results in a merge and that
- // the syntax of the new profile replaces the old one.
- SaveImportedProfileTestCase{{{COMPANY_NAME, "Stark inc"}},
- {{COMPANY_NAME, "Stark Inc."}},
- {{COMPANY_NAME, "Stark Inc."}}}));
-
- // Tests that MergeProfile tries to merge the imported profile into the
- // existing profile in decreasing order of frecency.
- TEST_F(PersonalDataManagerTest, MergeProfile_Frecency) {
- // Create two very similar profiles except with different company names.
- std::unique_ptr<AutofillProfile> profile1 =
- base::MakeUnique<AutofillProfile>(base::GenerateGUID(),
- "https://www.example.com");
- test::SetProfileInfo(profile1.get(), "Homer", "Jay", "Simpson",
- "homer.simpson@abc.com", "SNP",
- "742 Evergreen Terrace", "", "Springfield", "IL",
- "91601", "US", "12345678910");
- AutofillProfile* profile2 =
- new AutofillProfile(base::GenerateGUID(), "https://www.example.com");
- test::SetProfileInfo(profile2, "Homer", "Jay", "Simpson",
- "homer.simpson@abc.com", "Fox",
- "742 Evergreen Terrace", "", "Springfield", "IL",
- "91601", "US", "12345678910");
-
- // Give the "Fox" profile a bigger frecency score.
- profile2->set_use_count(15);
-
- // Create the |existing_profiles| vector.
- std::vector<std::unique_ptr<AutofillProfile>> existing_profiles;
- existing_profiles.push_back(std::move(profile1));
- existing_profiles.push_back(base::WrapUnique(profile2));
-
- // Create a new imported profile with no company name.
- AutofillProfile imported_profile(base::GenerateGUID(),
- "https://www.example.com");
- test::SetProfileInfo(&imported_profile, "Homer", "Jay", "Simpson",
- "homer.simpson@abc.com", "", "742 Evergreen Terrace",
- "", "Springfield", "IL", "91601", "US", "12345678910");
-
- // Merge the imported profile into the existing profiles.
- std::vector<AutofillProfile> profiles;
- std::string guid = personal_data_->MergeProfile(
- imported_profile, &existing_profiles, "US-EN", &profiles);
-
- // The new profile should be merged into the "fox" profile.
- EXPECT_EQ(profile2->guid(), guid);
+ // Erase the profiles for the next test.
+ ResetProfiles();
+}
+
+INSTANTIATE_TEST_CASE_P(
+ PersonalDataManagerTest,
+ SaveImportedProfileTest,
+ testing::Values(
+ // Test that saving an identical profile except for the name results
+ // in two profiles being saved.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{NAME_FIRST, "Marionette"}}},
+
+ // Test that saving an identical profile except with the middle name
+ // initial instead of the full middle name results in the profiles
+ // getting merged and the full middle name being kept.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{NAME_MIDDLE, "M"}},
+ {{NAME_MIDDLE, "Mitchell"},
+ {NAME_FULL, "Marion Mitchell Morrison"}}},
+
+ // Test that saving an identical profile except with the full middle
+ // name instead of the middle name initial results in the profiles
+ // getting merged and the full middle name replacing the initial.
+ SaveImportedProfileTestCase{{{NAME_MIDDLE, "M"}},
+ {{NAME_MIDDLE, "Mitchell"}},
+ {{NAME_MIDDLE, "Mitchell"}}},
+
+ // Test that saving an identical profile except with no middle name
+ // results in the profiles getting merged and the full middle name
+ // being kept.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{NAME_MIDDLE, ""}},
+ {{NAME_MIDDLE, "Mitchell"}}},
+
+ // Test that saving an identical profile except with a middle name
+ // initial results in the profiles getting merged and the middle name
+ // initial being saved.
+ SaveImportedProfileTestCase{{{NAME_MIDDLE, ""}},
+ {{NAME_MIDDLE, "M"}},
+ {{NAME_MIDDLE, "M"}}},
+
+ // Test that saving an identical profile except with a middle name
+ // results in the profiles getting merged and the full middle name
+ // being saved.
+ SaveImportedProfileTestCase{{{NAME_MIDDLE, ""}},
+ {{NAME_MIDDLE, "Mitchell"}},
+ {{NAME_MIDDLE, "Mitchell"}}},
+
+ // Test that saving a identical profile except with the full name set
+ // instead of the name parts results in the two profiles being merged
+ // and all the name parts kept and the full name being added.
+ SaveImportedProfileTestCase{
+ {
+ {NAME_FIRST, "Marion"},
+ {NAME_MIDDLE, "Mitchell"},
+ {NAME_LAST, "Morrison"},
+ {NAME_FULL, ""},
+ },
+ {
+ {NAME_FIRST, ""},
+ {NAME_MIDDLE, ""},
+ {NAME_LAST, ""},
+ {NAME_FULL, "Marion Mitchell Morrison"},
+ },
+ {
+ {NAME_FIRST, "Marion"},
+ {NAME_MIDDLE, "Mitchell"},
+ {NAME_LAST, "Morrison"},
+ {NAME_FULL, "Marion Mitchell Morrison"},
+ },
+ },
+
+ // Test that saving a identical profile except with the name parts set
+ // instead of the full name results in the two profiles being merged
+ // and the full name being kept and all the name parts being added.
+ SaveImportedProfileTestCase{
+ {
+ {NAME_FIRST, ""},
+ {NAME_MIDDLE, ""},
+ {NAME_LAST, ""},
+ {NAME_FULL, "Marion Mitchell Morrison"},
+ },
+ {
+ {NAME_FIRST, "Marion"},
+ {NAME_MIDDLE, "Mitchell"},
+ {NAME_LAST, "Morrison"},
+ {NAME_FULL, ""},
+ },
+ {
+ {NAME_FIRST, "Marion"},
+ {NAME_MIDDLE, "Mitchell"},
+ {NAME_LAST, "Morrison"},
+ {NAME_FULL, "Marion Mitchell Morrison"},
+ },
+ },
+
+ // Test that saving a profile that has only a full name set does not
+ // get merged with a profile with only the name parts set if the names
+ // are different.
+ SaveImportedProfileTestCase{
+ {
+ {NAME_FIRST, "Marion"},
+ {NAME_MIDDLE, "Mitchell"},
+ {NAME_LAST, "Morrison"},
+ {NAME_FULL, ""},
+ },
+ {
+ {NAME_FIRST, ""},
+ {NAME_MIDDLE, ""},
+ {NAME_LAST, ""},
+ {NAME_FULL, "John Thompson Smith"},
+ },
+ },
+
+ // Test that saving a profile that has only the name parts set does
+ // not get merged with a profile with only the full name set if the
+ // names are different.
+ SaveImportedProfileTestCase{
+ {
+ {NAME_FIRST, ""},
+ {NAME_MIDDLE, ""},
+ {NAME_LAST, ""},
+ {NAME_FULL, "John Thompson Smith"},
+ },
+ {
+ {NAME_FIRST, "Marion"},
+ {NAME_MIDDLE, "Mitchell"},
+ {NAME_LAST, "Morrison"},
+ {NAME_FULL, ""},
+ },
+ },
+
+ // Test that saving an identical profile except for the first address
+ // line results in two profiles being saved.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{ADDRESS_HOME_LINE1, "123 Aquarium St."}}},
+
+ // Test that saving an identical profile except for the second address
+ // line results in two profiles being saved.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{ADDRESS_HOME_LINE2, "unit 7"}}},
+
+ // Tests that saving an identical profile that has a new piece of
+ // information (company name) results in a merge and that the original
+ // empty value gets overwritten by the new information.
+ SaveImportedProfileTestCase{{{COMPANY_NAME, ""}},
+ ProfileFields(),
+ {{COMPANY_NAME, "Fox"}}},
+
+ // Tests that saving an identical profile except a loss of information
+ // results in a merge but the original value is not overwritten (no
+ // information loss).
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{COMPANY_NAME, ""}},
+ {{COMPANY_NAME, "Fox"}}},
+
+ // Tests that saving an identical profile except a slightly different
+ // postal code results in a merge with the new value kept.
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_ZIP, "R2C 0A1"}},
+ {{ADDRESS_HOME_ZIP, "R2C0A1"}},
+ {{ADDRESS_HOME_ZIP, "R2C0A1"}}},
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_ZIP, "R2C0A1"}},
+ {{ADDRESS_HOME_ZIP, "R2C 0A1"}},
+ {{ADDRESS_HOME_ZIP, "R2C 0A1"}}},
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_ZIP, "r2c 0a1"}},
+ {{ADDRESS_HOME_ZIP, "R2C0A1"}},
+ {{ADDRESS_HOME_ZIP, "R2C0A1"}}},
+
+ // Tests that saving an identical profile plus a new piece of
+ // information on the address line 2 results in a merge and that the
+ // original empty value gets overwritten by the new information.
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_LINE2, ""}},
+ ProfileFields(),
+ {{ADDRESS_HOME_LINE2, "unit 5"}}},
+
+ // Tests that saving an identical profile except a loss of information
+ // on the address line 2 results in a merge but that the original
+ // value gets not overwritten (no information loss).
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{ADDRESS_HOME_LINE2, ""}},
+ {{ADDRESS_HOME_LINE2, "unit 5"}}},
+
+ // Tests that saving an identical except with more punctuation in the
+ // fist address line, while the second is empty, results in a merge
+ // and that the original address gets overwritten.
+ SaveImportedProfileTestCase{
+ {{ADDRESS_HOME_LINE2, ""}},
+ {{ADDRESS_HOME_LINE2, ""}, {ADDRESS_HOME_LINE1, "123, Zoo St."}},
+ {{ADDRESS_HOME_LINE1, "123, Zoo St."}}},
+
+ // Tests that saving an identical profile except with less punctuation
+ // in the fist address line, while the second is empty, results in a
+ // merge and that the longer address is retained.
+ SaveImportedProfileTestCase{
+ {{ADDRESS_HOME_LINE2, ""}, {ADDRESS_HOME_LINE1, "123, Zoo St."}},
+ {{ADDRESS_HOME_LINE2, ""}},
+ {{ADDRESS_HOME_LINE1, "123 Zoo St"}}},
+
+ // Tests that saving an identical profile except additional
+ // punctuation in the two address lines results in a merge and that
+ // the newer address is retained.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{ADDRESS_HOME_LINE1, "123, Zoo St."},
+ {ADDRESS_HOME_LINE2, "unit. 5"}},
+ {{ADDRESS_HOME_LINE1, "123, Zoo St."},
+ {ADDRESS_HOME_LINE2, "unit. 5"}}},
+
+ // Tests that saving an identical profile except less punctuation in
+ // the two address lines results in a merge and that the newer address
+ // is retained.
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_LINE1, "123, Zoo St."},
+ {ADDRESS_HOME_LINE2, "unit. 5"}},
+ ProfileFields(),
+ {{ADDRESS_HOME_LINE1, "123 Zoo St"},
+ {ADDRESS_HOME_LINE2, "unit 5"}}},
+
+ // Tests that saving an identical profile with accented characters in
+ // the two address lines results in a merge and that the newer address
+ // is retained.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{ADDRESS_HOME_LINE1, "123 Zôö St"},
+ {ADDRESS_HOME_LINE2, "üñìt 5"}},
+ {{ADDRESS_HOME_LINE1, "123 Zôö St"},
+ {ADDRESS_HOME_LINE2, "üñìt 5"}}},
+
+ // Tests that saving an identical profile without accented characters
+ // in the two address lines results in a merge and that the newer
+ // address is retained.
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_LINE1, "123 Zôö St"},
+ {ADDRESS_HOME_LINE2, "üñìt 5"}},
+ ProfileFields(),
+ {{ADDRESS_HOME_LINE1, "123 Zoo St"},
+ {ADDRESS_HOME_LINE2, "unit 5"}}},
+
+ // Tests that saving an identical profile except that the address line
+ // 1 is in the address line 2 results in a merge and that the
+ // multi-lne address is retained.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{ADDRESS_HOME_LINE1, "123 Zoo St, unit 5"},
+ {ADDRESS_HOME_LINE2, ""}},
+ {{ADDRESS_HOME_LINE1, "123 Zoo St"},
+ {ADDRESS_HOME_LINE2, "unit 5"}}},
+
+ // Tests that saving an identical profile except that the address line
+ // 2 contains part of the old address line 1 results in a merge and
+ // that the original address lines of the reference profile get
+ // overwritten.
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_LINE1, "123 Zoo St, unit 5"},
+ {ADDRESS_HOME_LINE2, ""}},
+ ProfileFields(),
+ {{ADDRESS_HOME_LINE1, "123 Zoo St"},
+ {ADDRESS_HOME_LINE2, "unit 5"}}},
+
+ // Tests that saving an identical profile except that the state is the
+ // abbreviation instead of the full form results in a merge and that
+ // the original state gets overwritten.
+ SaveImportedProfileTestCase{{{ADDRESS_HOME_STATE, "California"}},
+ ProfileFields(),
+ {{ADDRESS_HOME_STATE, "CA"}}},
+
+ // Tests that saving an identical profile except that the state is the
+ // full form instead of the abbreviation results in a merge and that
+ // the abbreviated state is retained.
+ SaveImportedProfileTestCase{ProfileFields(),
+ {{ADDRESS_HOME_STATE, "California"}},
+ {{ADDRESS_HOME_STATE, "CA"}}},
+
+ // Tests that saving and identical profile except that the company
+ // name has different punctuation and case results in a merge and that
+ // the syntax of the new profile replaces the old one.
+ SaveImportedProfileTestCase{{{COMPANY_NAME, "Stark inc"}},
+ {{COMPANY_NAME, "Stark Inc."}},
+ {{COMPANY_NAME, "Stark Inc."}}}));
+
+// Tests that MergeProfile tries to merge the imported profile into the
+// existing profile in decreasing order of frecency.
+TEST_F(PersonalDataManagerTest, MergeProfile_Frecency) {
+ // Create two very similar profiles except with different company names.
+ std::unique_ptr<AutofillProfile> profile1 = base::MakeUnique<AutofillProfile>(
+ base::GenerateGUID(), "https://www.example.com");
+ test::SetProfileInfo(profile1.get(), "Homer", "Jay", "Simpson",
+ "homer.simpson@abc.com", "SNP", "742 Evergreen Terrace",
+ "", "Springfield", "IL", "91601", "US", "12345678910");
+ AutofillProfile* profile2 =
+ new AutofillProfile(base::GenerateGUID(), "https://www.example.com");
+ test::SetProfileInfo(profile2, "Homer", "Jay", "Simpson",
+ "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace",
+ "", "Springfield", "IL", "91601", "US", "12345678910");
+
+ // Give the "Fox" profile a bigger frecency score.
+ profile2->set_use_count(15);
+
+ // Create the |existing_profiles| vector.
+ std::vector<std::unique_ptr<AutofillProfile>> existing_profiles;
+ existing_profiles.push_back(std::move(profile1));
+ existing_profiles.push_back(base::WrapUnique(profile2));
+
+ // Create a new imported profile with no company name.
+ AutofillProfile imported_profile(base::GenerateGUID(),
+ "https://www.example.com");
+ test::SetProfileInfo(&imported_profile, "Homer", "Jay", "Simpson",
+ "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
+ "Springfield", "IL", "91601", "US", "12345678910");
+
+ // Merge the imported profile into the existing profiles.
+ std::vector<AutofillProfile> profiles;
+ std::string guid = personal_data_->MergeProfile(
+ imported_profile, &existing_profiles, "US-EN", &profiles);
+
+ // The new profile should be merged into the "fox" profile.
+ EXPECT_EQ(profile2->guid(), guid);
}
// Tests that MergeProfile produces a merged profile with the expected usage
@@ -4965,17 +5156,18 @@ TEST_F(PersonalDataManagerTest,
// verifying results.
CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card1, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
credit_card1.set_use_count(10);
CreditCard credit_card2(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card2, "John Dillinger",
- "423456789012" /* Visa */, "01", "2999");
+ "423456789012" /* Visa */, "01", "2999", "1");
credit_card2.set_use_count(5);
CreditCard credit_card3(base::GenerateGUID(), "https://www.example.com");
test::SetCreditCardInfo(&credit_card3, "Bonnie Parker",
- "518765432109" /* Mastercard */, "12", "2999");
+ "518765432109" /* Mastercard */, "12", "2999", "1");
credit_card3.set_use_count(1);
// Associate the first card with profile1.
@@ -5107,21 +5299,22 @@ TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_MergedProfileValues) {
EXPECT_EQ(profile3.guid(), profiles[0]->guid());
// The address syntax that results from the merge should be the one from the
// imported profile (highest frecency).
- EXPECT_EQ(UTF8ToUTF16("742. Evergreen Terrace"),
+ EXPECT_EQ(base::UTF8ToUTF16("742. Evergreen Terrace"),
profiles[0]->GetRawInfo(ADDRESS_HOME_LINE1));
// The middle name should be full, even if the profile with the higher
// frecency only had an initial (no loss of information).
- EXPECT_EQ(UTF8ToUTF16("Jay"), profiles[0]->GetRawInfo(NAME_MIDDLE));
+ EXPECT_EQ(base::UTF8ToUTF16("Jay"), profiles[0]->GetRawInfo(NAME_MIDDLE));
// The specified phone number from profile1 should be kept (no loss of
// information).
- EXPECT_EQ(UTF8ToUTF16("12345678910"),
+ EXPECT_EQ(base::UTF8ToUTF16("12345678910"),
profiles[0]->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
// The specified company name from profile2 should be kept (no loss of
// information).
- EXPECT_EQ(UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
+ EXPECT_EQ(base::UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
// The specified country from the imported profile shoudl be kept (no loss of
// information).
- EXPECT_EQ(UTF8ToUTF16("US"), profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
+ EXPECT_EQ(base::UTF8ToUTF16("US"),
+ profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
// The use count that results from the merge should be the max of all the
// profiles use counts.
EXPECT_EQ(10U, profiles[0]->use_count());
@@ -5566,17 +5759,18 @@ TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_MultipleDedupes) {
// |Homer3|'s data:
// The address should be saved with the syntax of |Homer1| since it has the
// highest frecency score.
- EXPECT_EQ(UTF8ToUTF16("742. Evergreen Terrace"),
+ EXPECT_EQ(base::UTF8ToUTF16("742. Evergreen Terrace"),
profiles[0]->GetRawInfo(ADDRESS_HOME_LINE1));
// The middle name should be the full version found in |Homer2|,
- EXPECT_EQ(UTF8ToUTF16("Jay"), profiles[0]->GetRawInfo(NAME_MIDDLE));
+ EXPECT_EQ(base::UTF8ToUTF16("Jay"), profiles[0]->GetRawInfo(NAME_MIDDLE));
// The phone number from |Homer2| should be kept (no loss of information).
- EXPECT_EQ(UTF8ToUTF16("12345678910"),
+ EXPECT_EQ(base::UTF8ToUTF16("12345678910"),
profiles[0]->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
// The company name from |Homer3| should be kept (no loss of information).
- EXPECT_EQ(UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
+ EXPECT_EQ(base::UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
// The country from |Homer1| profile should be kept (no loss of information).
- EXPECT_EQ(UTF8ToUTF16("US"), profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
+ EXPECT_EQ(base::UTF8ToUTF16("US"),
+ profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
// The use count that results from the merge should be the max of Homer 1, 2
// and 3's respective use counts.
EXPECT_EQ(10U, profiles[0]->use_count());
@@ -5650,7 +5844,6 @@ TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_NopIfOneProfile) {
EXPECT_FALSE(personal_data_->ApplyDedupingRoutine());
}
-
// Tests that ApplyDedupingRoutine is not run a second time on the same major
// version.
TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_OncePerVersion) {
@@ -5745,7 +5938,8 @@ TEST_F(PersonalDataManagerTest,
"77401", "US", "");
// Wallet only provides a full name, so the above first and last names
// will be ignored when the profile is written to the DB.
- GetServerProfiles.back().SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe"));
+ GetServerProfiles.back().SetRawInfo(NAME_FULL,
+ base::ASCIIToUTF16("John Doe"));
GetServerProfiles.back().set_use_count(100);
autofill_table_->SetServerProfiles(GetServerProfiles);
@@ -5754,7 +5948,8 @@ TEST_F(PersonalDataManagerTest,
CreditCard local_card("287151C8-6AB1-487C-9095-28E80BE5DA15",
"https://www.example.com");
test::SetCreditCardInfo(&local_card, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
local_card.set_billing_address_id(kServerAddressId);
personal_data_->AddCreditCard(local_card);
@@ -5762,8 +5957,8 @@ TEST_F(PersonalDataManagerTest,
server_cards.push_back(
CreditCard(CreditCard::MASKED_SERVER_CARD, "server_card1"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "1111" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "1111" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.back().set_billing_address_id(kServerAddressId);
test::SetServerCreditCards(autofill_table_, server_cards);
@@ -5804,7 +5999,7 @@ TEST_F(PersonalDataManagerTest,
// Make sure that the two profiles have not merged.
ASSERT_EQ(2U, profiles.size());
- EXPECT_EQ(UTF8ToUTF16("John"), profiles[0]->GetRawInfo(NAME_FIRST));
+ EXPECT_EQ(base::UTF8ToUTF16("John"), profiles[0]->GetRawInfo(NAME_FIRST));
EXPECT_EQ(local_profile, *profiles[1]);
// Make sure that the billing address id of the two cards now point to the
@@ -5816,7 +6011,7 @@ TEST_F(PersonalDataManagerTest,
// Make sure that the added address has the email address of the currently
// signed-in user.
- EXPECT_EQ(UTF8ToUTF16("syncuser@example.com"),
+ EXPECT_EQ(base::UTF8ToUTF16("syncuser@example.com"),
profiles[0]->GetRawInfo(EMAIL_ADDRESS));
}
@@ -5852,7 +6047,8 @@ TEST_F(PersonalDataManagerTest,
"1212 Center", "Bld. 5", "Orlando", "FL", "", "US", "");
// Wallet only provides a full name, so the above first and last names
// will be ignored when the profile is written to the DB.
- GetServerProfiles.back().SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe"));
+ GetServerProfiles.back().SetRawInfo(NAME_FULL,
+ base::ASCIIToUTF16("John Doe"));
GetServerProfiles.back().set_use_count(100);
autofill_table_->SetServerProfiles(GetServerProfiles);
@@ -5861,7 +6057,8 @@ TEST_F(PersonalDataManagerTest,
CreditCard local_card("287151C8-6AB1-487C-9095-28E80BE5DA15",
"https://www.example.com");
test::SetCreditCardInfo(&local_card, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
local_card.set_billing_address_id(kServerAddressId);
personal_data_->AddCreditCard(local_card);
@@ -5869,8 +6066,8 @@ TEST_F(PersonalDataManagerTest,
server_cards.push_back(
CreditCard(CreditCard::MASKED_SERVER_CARD, "server_card1"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "1111" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "1111" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.back().set_billing_address_id(kServerAddressId);
test::SetServerCreditCards(autofill_table_, server_cards);
@@ -5913,10 +6110,11 @@ TEST_F(PersonalDataManagerTest,
ASSERT_EQ(1U, profiles.size());
// Check that the values were merged.
- EXPECT_EQ(UTF8ToUTF16("john@doe.com"),
+ EXPECT_EQ(base::UTF8ToUTF16("john@doe.com"),
profiles[0]->GetRawInfo(EMAIL_ADDRESS));
- EXPECT_EQ(UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
- EXPECT_EQ(UTF8ToUTF16("32801"), profiles[0]->GetRawInfo(ADDRESS_HOME_ZIP));
+ EXPECT_EQ(base::UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
+ EXPECT_EQ(base::UTF8ToUTF16("32801"),
+ profiles[0]->GetRawInfo(ADDRESS_HOME_ZIP));
// Make sure that the billing address id of the two cards now point to the
// converted profile.
@@ -6013,7 +6211,8 @@ TEST_F(
"");
// Wallet only provides a full name, so the above first and last names
// will be ignored when the profile is written to the DB.
- GetServerProfiles.back().SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe"));
+ GetServerProfiles.back().SetRawInfo(NAME_FULL,
+ base::ASCIIToUTF16("John Doe"));
GetServerProfiles.back().set_use_count(100);
// Add a similar server profile.
@@ -6024,7 +6223,8 @@ TEST_F(
"Orlando", "FL", "", "US", "");
// Wallet only provides a full name, so the above first and last names
// will be ignored when the profile is written to the DB.
- GetServerProfiles.back().SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe"));
+ GetServerProfiles.back().SetRawInfo(NAME_FULL,
+ base::ASCIIToUTF16("John Doe"));
GetServerProfiles.back().set_use_count(200);
autofill_table_->SetServerProfiles(GetServerProfiles);
@@ -6033,7 +6233,8 @@ TEST_F(
CreditCard local_card("287151C8-6AB1-487C-9095-28E80BE5DA15",
"https://www.example.com");
test::SetCreditCardInfo(&local_card, "Clyde Barrow",
- "347666888555" /* American Express */, "04", "2999");
+ "347666888555" /* American Express */, "04", "2999",
+ "1");
local_card.set_billing_address_id(kServerAddressId);
personal_data_->AddCreditCard(local_card);
@@ -6041,8 +6242,8 @@ TEST_F(
server_cards.push_back(
CreditCard(CreditCard::MASKED_SERVER_CARD, "server_card1"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "1111" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "1111" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.back().set_billing_address_id(kServerAddressId2);
test::SetServerCreditCards(autofill_table_, server_cards);
@@ -6089,12 +6290,13 @@ TEST_F(
// Make sure that the two Wallet addresses merged together and were added as
// a new local profile.
ASSERT_EQ(2U, profiles.size());
- EXPECT_EQ(UTF8ToUTF16("John"), profiles[0]->GetRawInfo(NAME_FIRST));
+ EXPECT_EQ(base::UTF8ToUTF16("John"), profiles[0]->GetRawInfo(NAME_FIRST));
EXPECT_EQ(local_profile, *profiles[1]);
// Check that the values were merged.
- EXPECT_EQ(UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
- EXPECT_EQ(UTF8ToUTF16("32801"), profiles[0]->GetRawInfo(ADDRESS_HOME_ZIP));
+ EXPECT_EQ(base::UTF8ToUTF16("Fox"), profiles[0]->GetRawInfo(COMPANY_NAME));
+ EXPECT_EQ(base::UTF8ToUTF16("32801"),
+ profiles[0]->GetRawInfo(ADDRESS_HOME_ZIP));
// Make sure that the billing address id of the two cards now point to the
// converted profile.
@@ -6108,7 +6310,7 @@ TEST_F(
// address was already converted in the past.
TEST_F(
PersonalDataManagerTest,
- ConvertWalletAddressesAndUpdateWalletCards_NewCard_AddressAlreadyConverted) {
+ ConvertWalletAddressesAndUpdateWalletCards_NewCrd_AddressAlreadyConverted) {
///////////////////////////////////////////////////////////////////////
// Setup.
///////////////////////////////////////////////////////////////////////
@@ -6127,7 +6329,8 @@ TEST_F(
"1212 Center", "Bld. 5", "Orlando", "FL", "", "US", "");
// Wallet only provides a full name, so the above first and last names
// will be ignored when the profile is written to the DB.
- GetServerProfiles.back().SetRawInfo(NAME_FULL, ASCIIToUTF16("John Doe"));
+ GetServerProfiles.back().SetRawInfo(NAME_FULL,
+ base::ASCIIToUTF16("John Doe"));
GetServerProfiles.back().set_use_count(100);
autofill_table_->SetServerProfiles(GetServerProfiles);
@@ -6136,8 +6339,8 @@ TEST_F(
server_cards.push_back(
CreditCard(CreditCard::MASKED_SERVER_CARD, "server_card1"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "1111" /* Visa */, "01", "2999");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "1111" /* Visa */, "01", "2999", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.back().set_billing_address_id(kServerAddressId);
test::SetServerCreditCards(autofill_table_, server_cards);
@@ -6174,8 +6377,8 @@ TEST_F(
server_cards.push_back(
CreditCard(CreditCard::MASKED_SERVER_CARD, "server_card2"));
test::SetCreditCardInfo(&server_cards.back(), "John Dillinger",
- "1112" /* Visa */, "01", "2888");
- server_cards.back().SetTypeForMaskedCard(kVisaCard);
+ "1112" /* Visa */, "01", "2888", "1");
+ server_cards.back().SetNetworkForMaskedCard(kVisaCard);
server_cards.back().set_billing_address_id(kServerAddressId);
test::SetServerCreditCards(autofill_table_, server_cards);
@@ -6218,4 +6421,91 @@ TEST_F(
personal_data_->GetCreditCards()[1]->billing_address_id());
}
+TEST_F(PersonalDataManagerTest, RemoveByGUID_ResetsBillingAddress) {
+ ///////////////////////////////////////////////////////////////////////
+ // Setup.
+ ///////////////////////////////////////////////////////////////////////
+ EnableWalletCardImport();
+ std::vector<CreditCard> server_cards;
+
+ // Add two different profiles
+ AutofillProfile profile0(base::GenerateGUID(), "https://www.example.com");
+ test::SetProfileInfo(&profile0, "Bob", "", "Doe", "", "Fox", "1212 Center.",
+ "Bld. 5", "Orlando", "FL", "32801", "US", "19482937549");
+ AutofillProfile profile1(base::GenerateGUID(), "https://www.example.com");
+ test::SetProfileInfo(&profile1, "Seb", "", "Doe", "", "ACME",
+ "1234 Evergreen Terrace", "Bld. 5", "Springfield", "IL",
+ "32801", "US", "15151231234");
+
+ // Add a local and a server card that have profile0 as their billing address.
+ CreditCard local_card0(base::GenerateGUID(), "https://www.example.com");
+ test::SetCreditCardInfo(&local_card0, "John Dillinger",
+ "4111111111111111" /* Visa */, "01", "2999",
+ profile0.guid());
+ CreditCard server_card0(CreditCard::FULL_SERVER_CARD, "c789");
+ test::SetCreditCardInfo(&server_card0, "John Barrow",
+ "347666888555" /* American Express */, "04", "2999",
+ profile0.guid());
+ server_cards.push_back(server_card0);
+
+ // Do the same but for profile1.
+ CreditCard local_card1(base::GenerateGUID(), "https://www.example.com");
+ test::SetCreditCardInfo(&local_card1, "Seb Dillinger",
+ "4111111111111111" /* Visa */, "01", "2999",
+ profile1.guid());
+ CreditCard server_card1(CreditCard::FULL_SERVER_CARD, "c789");
+ test::SetCreditCardInfo(&server_card1, "John Barrow",
+ "347666888555" /* American Express */, "04", "2999",
+ profile1.guid());
+ server_cards.push_back(server_card1);
+
+ // Add the data to the database.
+ personal_data_->AddProfile(profile0);
+ personal_data_->AddProfile(profile1);
+ personal_data_->AddCreditCard(local_card0);
+ personal_data_->AddCreditCard(local_card1);
+ test::SetServerCreditCards(autofill_table_, server_cards);
+
+ personal_data_->Refresh();
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .WillOnce(QuitMainMessageLoop());
+ base::RunLoop().Run();
+
+ // Make sure everything was saved properly.
+ EXPECT_EQ(2U, personal_data_->GetProfiles().size());
+ EXPECT_EQ(4U, personal_data_->GetCreditCards().size());
+
+ ///////////////////////////////////////////////////////////////////////
+ // Tested method.
+ ///////////////////////////////////////////////////////////////////////
+ personal_data_->RemoveByGUID(profile0.guid());
+
+ ///////////////////////////////////////////////////////////////////////
+ // Validation.
+ ///////////////////////////////////////////////////////////////////////
+
+ // Wait for the data to be refreshed.
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .WillOnce(QuitMainMessageLoop());
+ base::RunLoop().Run();
+
+ // Make sure only profile0 was deleted.
+ ASSERT_EQ(1U, personal_data_->GetProfiles().size());
+ EXPECT_EQ(profile1.guid(), personal_data_->GetProfiles()[0]->guid());
+ EXPECT_EQ(4U, personal_data_->GetCreditCards().size());
+
+ for (CreditCard* card : personal_data_->GetCreditCards()) {
+ if (card->guid() == local_card0.guid() ||
+ card->guid() == server_card0.guid()) {
+ // The billing address id of local_card0 and server_card0 should have been
+ // reset.
+ EXPECT_EQ("", card->billing_address_id());
+ } else {
+ // The billing address of local_card1 and server_card1 should still refer
+ // to profile1.
+ EXPECT_EQ(profile1.guid(), card->billing_address_id());
+ }
+ }
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/phone_field.cc b/chromium/components/autofill/core/browser/phone_field.cc
index 68135df1187..07bf8e26185 100644
--- a/chromium/components/autofill/core/browser/phone_field.cc
+++ b/chromium/components/autofill/core/browser/phone_field.cc
@@ -15,8 +15,8 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_field.h"
-#include "components/autofill/core/browser/autofill_regex_constants.h"
#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
namespace autofill {
namespace {
diff --git a/chromium/components/autofill/core/browser/popup_item_ids.h b/chromium/components/autofill/core/browser/popup_item_ids.h
index 7821315f611..cbdd295c519 100644
--- a/chromium/components/autofill/core/browser/popup_item_ids.h
+++ b/chromium/components/autofill/core/browser/popup_item_ids.h
@@ -22,6 +22,7 @@ enum PopupItemId {
POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO = -9,
POPUP_ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE = -10,
POPUP_ITEM_ID_USERNAME_ENTRY = -11,
+ POPUP_ITEM_ID_CREATE_HINT = -12,
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/region_combobox_model.cc b/chromium/components/autofill/core/browser/region_combobox_model.cc
index 509bd596e31..977a692de5d 100644
--- a/chromium/components/autofill/core/browser/region_combobox_model.cc
+++ b/chromium/components/autofill/core/browser/region_combobox_model.cc
@@ -6,32 +6,38 @@
#include <utility>
-#include "base/callback.h"
-#include "base/logging.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/region_data_loader.h"
#include "components/strings/grit/components_strings.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/combobox_model_observer.h"
namespace autofill {
-RegionComboboxModel::RegionComboboxModel(
- std::unique_ptr<const ::i18n::addressinput::Source> source,
- std::unique_ptr<::i18n::addressinput::Storage> storage,
- const std::string& app_locale,
- const std::string& country_code)
- : failed_to_load_data_(false),
- pending_region_data_load_(false),
- app_locale_(app_locale),
- region_data_supplier_(source.release(), storage.release()) {
- region_data_supplier_callback_.reset(::i18n::addressinput::BuildCallback(
- this, &RegionComboboxModel::RegionDataLoaded));
- LoadRegionData(country_code);
+RegionComboboxModel::RegionComboboxModel()
+ : failed_to_load_data_(false), region_data_loader_(nullptr) {}
+
+RegionComboboxModel::~RegionComboboxModel() {
+ if (region_data_loader_)
+ region_data_loader_->ClearCallback();
+}
+
+void RegionComboboxModel::LoadRegionData(const std::string& country_code,
+ RegionDataLoader* region_data_loader,
+ int64_t timeout_ms) {
+ DCHECK(region_data_loader);
+ DCHECK(!region_data_loader_);
+ region_data_loader_ = region_data_loader;
+ region_data_loader_->LoadRegionData(
+ country_code,
+ base::Bind(&RegionComboboxModel::OnRegionDataLoaded,
+ base::Unretained(this)),
+ timeout_ms);
}
-RegionComboboxModel::~RegionComboboxModel() {}
int RegionComboboxModel::GetItemCount() const {
// The combobox view needs to always have at least one item. If the regions
@@ -71,37 +77,19 @@ void RegionComboboxModel::RemoveObserver(ui::ComboboxModelObserver* observer) {
observers_.RemoveObserver(observer);
}
-void RegionComboboxModel::SetFailureModeForTests(bool failed_to_load_data) {
- failed_to_load_data_ = failed_to_load_data;
- for (auto& observer : observers_) {
- observer.OnComboboxModelChanged(this);
- }
-}
-
-void RegionComboboxModel::LoadRegionData(const std::string& country_code) {
- pending_region_data_load_ = true;
- region_data_supplier_.LoadRules(country_code,
- *region_data_supplier_callback_.get());
-}
-
-void RegionComboboxModel::RegionDataLoaded(bool success,
- const std::string& country_code,
- int rule_count) {
- pending_region_data_load_ = false;
- if (success) {
- std::string best_region_tree_language_tag;
- ::i18n::addressinput::RegionDataBuilder builder(&region_data_supplier_);
- const std::vector<const ::i18n::addressinput::RegionData*>& regions =
- builder.Build(country_code, app_locale_, &best_region_tree_language_tag)
- .sub_regions();
- // Some countries expose a state field but have not region names available.
- if (regions.size() > 0) {
- failed_to_load_data_ = false;
- for (auto* const region : regions) {
- regions_.push_back(std::make_pair(region->key(), region->name()));
- }
- } else {
- failed_to_load_data_ = true;
+void RegionComboboxModel::OnRegionDataLoaded(
+ const std::vector<const ::i18n::addressinput::RegionData*>& regions) {
+ // The RegionDataLoader will eventually self destruct after this call.
+ DCHECK(region_data_loader_);
+ region_data_loader_ = nullptr;
+ regions_.clear();
+
+ // Some countries expose a state field but have no region names available.
+ if (regions.size() > 0) {
+ failed_to_load_data_ = false;
+ regions_.push_back(std::make_pair("", "---"));
+ for (auto* const region : regions) {
+ regions_.push_back(std::make_pair(region->key(), region->name()));
}
} else {
// TODO(mad): Maybe use a static list as is done for countries in
diff --git a/chromium/components/autofill/core/browser/region_combobox_model.h b/chromium/components/autofill/core/browser/region_combobox_model.h
index aa16bc88e5d..e6a89b29fe3 100644
--- a/chromium/components/autofill/core/browser/region_combobox_model.h
+++ b/chromium/components/autofill/core/browser/region_combobox_model.h
@@ -12,33 +12,41 @@
#include "base/macros.h"
#include "base/observer_list.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
#include "ui/base/models/combobox_model.h"
+namespace i18n {
+namespace addressinput {
+class RegionData;
+} // namespace addressinput
+} // namespace i18n
+
namespace autofill {
+class RegionDataLoader;
+
// A model for country regions (aka state/provinces) to be used to enter
// addresses. Note that loading these regions can happen asynchronously so a
// ui::ComboboxModelObserver should be attached to this model to be updated when
// the regions load is completed.
class RegionComboboxModel : public ui::ComboboxModel {
public:
- // |source| and |storage| are needed to initialize the
- // ::i18n::addressinput::PreloadSupplier, |app_locale| is needed for
- // ::i18n::addressinput::RegionDataBuilder and |country_code| identifies which
- // country's region to load into the model.
- RegionComboboxModel(
- std::unique_ptr<const ::i18n::addressinput::Source> source,
- std::unique_ptr<::i18n::addressinput::Storage> storage,
- const std::string& app_locale,
- const std::string& country_code);
+ RegionComboboxModel();
~RegionComboboxModel() override;
- bool pending_region_data_load() const { return pending_region_data_load_; }
+ void LoadRegionData(const std::string& country_code,
+ RegionDataLoader* region_data_loader,
+ int64_t timeout_ms);
+
+ bool IsPendingRegionDataLoad() const {
+ return region_data_loader_ != nullptr;
+ }
+
bool failed_to_load_data() const { return failed_to_load_data_; }
+ const std::vector<std::pair<std::string, std::string>>& GetRegions() const {
+ return regions_;
+ }
+
// ui::ComboboxModel implementation:
int GetItemCount() const override;
base::string16 GetItemAt(int index) override;
@@ -46,33 +54,17 @@ class RegionComboboxModel : public ui::ComboboxModel {
void AddObserver(ui::ComboboxModelObserver* observer) override;
void RemoveObserver(ui::ComboboxModelObserver* observer) override;
- // To allow testing failure states.
- void SetFailureModeForTests(bool failed_to_load_data);
-
private:
- // Start the potentially asynchronous process of loading region data.
- void LoadRegionData(const std::string& country_code);
-
- // Callback for ::i18n::addressinput::PreloadSupplier::LoadRules
- void RegionDataLoaded(bool success, const std::string&, int rule_count);
+ // Callback for the RegionDataLoader.
+ void OnRegionDataLoaded(
+ const std::vector<const ::i18n::addressinput::RegionData*>& regions);
// Whether the region data load failed or not.
bool failed_to_load_data_;
- // Set to true during region data load, and false otherwise. Whether the load
- // succeeded or not doesn't affect this value.
- bool pending_region_data_load_;
-
- // The application locale.
- const std::string app_locale_;
-
- // The callback to give to |region_data_supplier_| for async operations.
- ::i18n::addressinput::scoped_ptr<
- ::i18n::addressinput::PreloadSupplier::Callback>
- region_data_supplier_callback_;
-
- // A supplier of region data.
- ::i18n::addressinput::PreloadSupplier region_data_supplier_;
+ // Lifespan not owned by RegionComboboxModel, but guaranteed to be alive up to
+ // a call to OnRegionDataLoaded where soft ownership must be released.
+ RegionDataLoader* region_data_loader_;
// List of <code, name> pairs for ADDRESS_HOME_STATE combobox values;
std::vector<std::pair<std::string, std::string>> regions_;
diff --git a/chromium/components/autofill/core/browser/region_combobox_model_unittest.cc b/chromium/components/autofill/core/browser/region_combobox_model_unittest.cc
index 52878f0e921..a38ca400499 100644
--- a/chromium/components/autofill/core/browser/region_combobox_model_unittest.cc
+++ b/chromium/components/autofill/core/browser/region_combobox_model_unittest.cc
@@ -12,96 +12,47 @@
#include "base/values.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
-#include "components/prefs/pref_service.h"
+#include "components/autofill/core/browser/test_region_data_loader.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
namespace autofill {
// Strings used in more than one place and must be the same everywhere.
-const char kTestCountryCode[] = "CA";
const char kQuebec[] = "Quebec";
const char kOntario[] = "Ontario";
-class RegionComboboxModelTest : public testing::Test {
- public:
- RegionComboboxModelTest()
- : pref_service_(autofill::test::PrefServiceForTesting()) {
- manager_.SetTestingPrefService(pref_service_.get());
- manager_.set_timezone_country_code(kTestCountryCode);
- }
-
- void SetupCombobox(bool source_failure) {
- model_.reset(new RegionComboboxModel(
- base::MakeUnique<TestSource>(source_failure),
- base::MakeUnique<::i18n::addressinput::NullStorage>(),
- manager_.app_locale(), kTestCountryCode));
- }
-
- void TearDown() override { manager_.SetTestingPrefService(nullptr); }
-
- RegionComboboxModel* model() { return model_.get(); }
-
- private:
- // The source that returns the region data. Using
- // third_party/libaddressinput/src/cpp/test/testdata_source.h wouldn't help
- // much since it only implements the Get method overriden below anyway.
- class TestSource : public ::i18n::addressinput::Source {
- public:
- explicit TestSource(bool source_failure)
- : source_failure_(source_failure) {}
- ~TestSource() override {}
-
- void Get(const std::string& key,
- const ::i18n::addressinput::Source::Callback& data_ready)
- const override {
- if (source_failure_) {
- data_ready(false, key, nullptr);
- return;
- }
- // Only set the fields needed to fill the combobox, since only the
- // combobox code needs to be tested here.
- std::string* json = new std::string("{\"data/CA\":{");
- *json += "\"id\":\"data/CA\",";
- *json += "\"key\":\"CA\",";
- *json += "\"sub_keys\":\"QC~ON\"},";
-
- *json += "\"data/CA/ON\":{";
- *json += "\"id\":\"data/CA/ON\",";
- *json += "\"key\":\"ON\",";
- *json += "\"name\":\"Ontario\"},";
-
- *json += "\"data/CA/QC\":{";
- *json += "\"id\":\"data/CA/QC\",";
- *json += "\"key\":\"QC\",";
- *json += "\"name\":\"Quebec\"}}";
- data_ready(true, key, json);
- }
-
- private:
- bool source_failure_{false};
- };
- TestPersonalDataManager manager_;
- std::unique_ptr<PrefService> pref_service_;
- std::unique_ptr<RegionComboboxModel> model_;
-};
-
// Make sure the two regions returned by the source are properly set in the
// model.
-TEST_F(RegionComboboxModelTest, QuebecOntarioRegions) {
- SetupCombobox(false);
- EXPECT_EQ(2, model()->GetItemCount());
- EXPECT_EQ(base::ASCIIToUTF16(kQuebec), model()->GetItemAt(0));
- EXPECT_EQ(base::ASCIIToUTF16(kOntario), model()->GetItemAt(1));
- EXPECT_FALSE(model()->failed_to_load_data());
+TEST(RegionComboboxModelTest, QuebecOntarioRegions) {
+ TestRegionDataLoader test_region_data_loader;
+ RegionComboboxModel model;
+ model.LoadRegionData("", &test_region_data_loader, 0);
+
+ std::vector<std::pair<std::string, std::string>> regions;
+ regions.push_back(std::make_pair("QC", kQuebec));
+ regions.push_back(std::make_pair("ON", kOntario));
+
+ test_region_data_loader.SendAsynchronousData(regions);
+
+ EXPECT_EQ(3, model.GetItemCount());
+ EXPECT_EQ(base::ASCIIToUTF16("---"), model.GetItemAt(0));
+ EXPECT_EQ(base::ASCIIToUTF16(kQuebec), model.GetItemAt(1));
+ EXPECT_EQ(base::ASCIIToUTF16(kOntario), model.GetItemAt(2));
+ EXPECT_FALSE(model.failed_to_load_data());
}
-// Make sure the combo box properly support source failures.
-TEST_F(RegionComboboxModelTest, FailingSource) {
- SetupCombobox(true);
- EXPECT_EQ(1, model()->GetItemCount());
- EXPECT_TRUE(model()->failed_to_load_data());
+// Make sure the combo box properly support source emptyness/failures.
+TEST(RegionComboboxModelTest, FailingSource) {
+ TestRegionDataLoader test_region_data_loader;
+ RegionComboboxModel model;
+ model.LoadRegionData("", &test_region_data_loader, 0);
+ test_region_data_loader.SendAsynchronousData(
+ std::vector<std::pair<std::string, std::string>>());
+
+ // There's always 1 item, even in failure cases.
+ EXPECT_EQ(1, model.GetItemCount());
+ EXPECT_TRUE(model.failed_to_load_data());
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/region_data_loader.h b/chromium/components/autofill/core/browser/region_data_loader.h
new file mode 100644
index 00000000000..1e2fb87f68c
--- /dev/null
+++ b/chromium/components/autofill/core/browser/region_data_loader.h
@@ -0,0 +1,44 @@
+// Copyright 2017 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_REGION_DATA_LOADER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_REGION_DATA_LOADER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+
+namespace i18n {
+namespace addressinput {
+class RegionData;
+} // namespace addressinput
+} // namespace i18n
+
+namespace autofill {
+
+// An interface to wrap the loading of region data so it can be mocked in tests.
+class RegionDataLoader {
+ public:
+ // The signature of the function to be called when the region data is loaded.
+ // When the loading request times out or other failure occure, |regions| is
+ // empty.
+ typedef base::Callback<void(
+ const std::vector<const ::i18n::addressinput::RegionData*>& regions)>
+ RegionDataLoaded;
+
+ virtual ~RegionDataLoader() {}
+ // Calls |loaded_callback| when the region data for |country_code| is ready or
+ // when |timeout_ms| miliseconds have passed. This may happen synchronously.
+ virtual void LoadRegionData(const std::string& country_code,
+ RegionDataLoaded callback,
+ int64_t timeout_ms) = 0;
+ // To forget about the |callback| givent to LoadRegionData, in cases where
+ // callback owner is destroyed before loader.
+ virtual void ClearCallback() = 0;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_REGION_DATA_LOADER_H_
diff --git a/chromium/components/autofill/core/browser/region_data_loader_impl.cc b/chromium/components/autofill/core/browser/region_data_loader_impl.cc
new file mode 100644
index 00000000000..4dbe7a91ce9
--- /dev/null
+++ b/chromium/components/autofill/core/browser/region_data_loader_impl.cc
@@ -0,0 +1,72 @@
+// Copyright 2017 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/region_data_loader_impl.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+
+namespace autofill {
+
+RegionDataLoaderImpl::RegionDataLoaderImpl(
+ ::i18n::addressinput::Source* address_input_source,
+ ::i18n::addressinput::Storage* address_input_storage,
+ const std::string& app_locale)
+ // region_data_supplier_ takes ownership of source and storage.
+ : region_data_supplier_(address_input_source, address_input_storage),
+ app_locale_(app_locale) {
+ region_data_supplier_callback_.reset(::i18n::addressinput::BuildCallback(
+ this, &RegionDataLoaderImpl::OnRegionDataLoaded));
+}
+
+RegionDataLoaderImpl::~RegionDataLoaderImpl() {}
+
+void RegionDataLoaderImpl::LoadRegionData(
+ const std::string& country_code,
+ RegionDataLoaderImpl::RegionDataLoaded callback,
+ int64_t timeout_ms) {
+ callback_ = callback;
+ region_data_supplier_.LoadRules(country_code,
+ *region_data_supplier_callback_.get());
+
+ timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timeout_ms),
+ base::Bind(&RegionDataLoaderImpl::OnRegionDataLoaded,
+ base::Unretained(this), false, country_code, 0));
+}
+
+void RegionDataLoaderImpl::ClearCallback() {
+ callback_.Reset();
+}
+
+void RegionDataLoaderImpl::OnRegionDataLoaded(bool success,
+ const std::string& country_code,
+ int unused_rule_count) {
+ timer_.Stop();
+ if (!callback_.is_null()) {
+ if (success) {
+ std::string best_region_tree_language_tag;
+ ::i18n::addressinput::RegionDataBuilder builder(&region_data_supplier_);
+ callback_.Run(
+ builder
+ .Build(country_code, app_locale_, &best_region_tree_language_tag)
+ .sub_regions());
+ } else {
+ callback_.Run(std::vector<const ::i18n::addressinput::RegionData*>());
+ }
+ }
+ // The deletion must be asynchronous since the caller is not quite done with
+ // the preload supplier.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&RegionDataLoaderImpl::DeleteThis, base::Unretained(this)));
+}
+
+void RegionDataLoaderImpl::DeleteThis() {
+ delete this;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/region_data_loader_impl.h b/chromium/components/autofill/core/browser/region_data_loader_impl.h
new file mode 100644
index 00000000000..8113473e2db
--- /dev/null
+++ b/chromium/components/autofill/core/browser/region_data_loader_impl.h
@@ -0,0 +1,68 @@
+// Copyright 2017 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_REGION_DATA_LOADER_IMPL_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_REGION_DATA_LOADER_IMPL_H_
+
+#include "components/autofill/core/browser/region_data_loader.h"
+
+#include <string>
+
+#include "base/timer/timer.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/preload_supplier.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/util/scoped_ptr.h"
+
+namespace i18n {
+namespace addressinput {
+class PreloadSupplier;
+class Source;
+class Storage;
+} // namespace addressinput
+} // namespace i18n
+
+namespace autofill {
+
+// A wrapper for the PreloadSupplier to simplify testing. Until crbug.com/712832
+// is fixed, to avoid leaks instances of this class are left hanging until the
+// callback is Run. If the callback is never run, this class will leak. But even
+// if we would prevent this class from leaking, the preload supplier will leak
+// data anyway if the load never completes. This class gives us more opportunity
+// to prevent that preload supplier leak if the data load happens after the UI
+// timeout waiting for this data expires.
+class RegionDataLoaderImpl : public RegionDataLoader {
+ public:
+ RegionDataLoaderImpl(::i18n::addressinput::Source* address_input_source,
+ ::i18n::addressinput::Storage* address_input_storage,
+ const std::string& app_locale);
+
+ ~RegionDataLoaderImpl() override;
+
+ // autofill::RegionDataLoader.
+ void LoadRegionData(const std::string& country_code,
+ RegionDataLoader::RegionDataLoaded callback,
+ int64_t timeout_ms) override;
+ void ClearCallback() override;
+
+ private:
+ void OnRegionDataLoaded(bool success,
+ const std::string& country_code,
+ int unused_rule_count);
+ void DeleteThis();
+
+ // The callback to give to |region_data_supplier_| for async operations.
+ ::i18n::addressinput::scoped_ptr<
+ ::i18n::addressinput::PreloadSupplier::Callback>
+ region_data_supplier_callback_;
+
+ // A supplier of region data.
+ ::i18n::addressinput::PreloadSupplier region_data_supplier_;
+
+ std::string app_locale_;
+ RegionDataLoader::RegionDataLoaded callback_;
+ base::OneShotTimer timer_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_REGION_DATA_LOADER_IMPL_H_
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.cc b/chromium/components/autofill/core/browser/test_autofill_client.cc
index 1c67ac60f38..61d05df444a 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.cc
+++ b/chromium/components/autofill/core/browser/test_autofill_client.cc
@@ -47,8 +47,8 @@ rappor::RapporServiceImpl* TestAutofillClient::GetRapporServiceImpl() {
return rappor_service_.get();
}
-ukm::UkmService* TestAutofillClient::GetUkmService() {
- return ukm_service_test_harness_.test_ukm_service();
+ukm::UkmRecorder* TestAutofillClient::GetUkmRecorder() {
+ return ukm::UkmRecorder::Get();
}
SaveCardBubbleController* TestAutofillClient::GetSaveCardBubbleController() {
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.h b/chromium/components/autofill/core/browser/test_autofill_client.h
index a140c772665..965023d23f9 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.h
+++ b/chromium/components/autofill/core/browser/test_autofill_client.h
@@ -16,7 +16,7 @@
#include "components/autofill/core/browser/autofill_client.h"
#include "components/prefs/pref_service.h"
#include "components/rappor/test_rappor_service.h"
-#include "components/ukm/test_ukm_service.h"
+#include "components/ukm/test_ukm_recorder.h"
#include "google_apis/gaia/fake_identity_provider.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
@@ -35,7 +35,7 @@ class TestAutofillClient : public AutofillClient {
syncer::SyncService* GetSyncService() override;
IdentityProvider* GetIdentityProvider() override;
rappor::RapporServiceImpl* GetRapporServiceImpl() override;
- ukm::UkmService* GetUkmService() override;
+ ukm::UkmRecorder* GetUkmRecorder() override;
SaveCardBubbleController* GetSaveCardBubbleController() override;
void ShowAutofillSettings() override;
void ShowUnmaskPrompt(const CreditCard& card,
@@ -88,17 +88,12 @@ class TestAutofillClient : public AutofillClient {
void set_form_origin(const GURL& url) { form_origin_ = url; }
- ukm::TestUkmService* GetTestUkmService() {
- return ukm_service_test_harness_.test_ukm_service();
- }
-
private:
// NULL by default.
std::unique_ptr<PrefService> prefs_;
std::unique_ptr<FakeOAuth2TokenService> token_service_;
std::unique_ptr<FakeIdentityProvider> identity_provider_;
std::unique_ptr<rappor::TestRapporServiceImpl> rappor_service_;
- ukm::UkmServiceTestingHarness ukm_service_test_harness_;
#if !defined(OS_ANDROID)
std::unique_ptr<SaveCardBubbleController> save_card_bubble_controller_;
#endif
diff --git a/chromium/components/autofill/core/browser/test_autofill_driver.cc b/chromium/components/autofill/core/browser/test_autofill_driver.cc
index 51a61ce03d5..1ecec121c21 100644
--- a/chromium/components/autofill/core/browser/test_autofill_driver.cc
+++ b/chromium/components/autofill/core/browser/test_autofill_driver.cc
@@ -4,16 +4,11 @@
#include "components/autofill/core/browser/test_autofill_driver.h"
-#include "base/test/sequenced_worker_pool_owner.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "ui/gfx/geometry/rect_f.h"
namespace autofill {
-TestAutofillDriver::TestAutofillDriver()
- : blocking_pool_owner_(
- new base::SequencedWorkerPoolOwner(4, "TestAutofillDriver")),
- url_request_context_(NULL) {}
+TestAutofillDriver::TestAutofillDriver() : url_request_context_(NULL) {}
TestAutofillDriver::~TestAutofillDriver() {}
@@ -25,10 +20,6 @@ net::URLRequestContextGetter* TestAutofillDriver::GetURLRequestContext() {
return url_request_context_;
}
-base::SequencedWorkerPool* TestAutofillDriver::GetBlockingPool() {
- return blocking_pool_owner_->pool().get();
-}
-
bool TestAutofillDriver::RendererIsAvailable() {
return true;
}
diff --git a/chromium/components/autofill/core/browser/test_autofill_driver.h b/chromium/components/autofill/core/browser/test_autofill_driver.h
index c1839293b7f..bc4898b71f0 100644
--- a/chromium/components/autofill/core/browser/test_autofill_driver.h
+++ b/chromium/components/autofill/core/browser/test_autofill_driver.h
@@ -5,17 +5,10 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_DRIVER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_DRIVER_H_
-#include <memory>
-
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "components/autofill/core/browser/autofill_driver.h"
-namespace base {
-class SequencedWorkerPoolOwner;
-}
-
namespace autofill {
// This class is only for easier writing of tests.
@@ -29,7 +22,6 @@ class TestAutofillDriver : public AutofillDriver {
// Returns the value passed in to the last call to |SetURLRequestContext()|
// or NULL if that method has never been called.
net::URLRequestContextGetter* GetURLRequestContext() override;
- base::SequencedWorkerPool* GetBlockingPool() override;
bool RendererIsAvailable() override;
void SendFormDataToRenderer(int query_id,
RendererFormDataAction action,
@@ -57,7 +49,6 @@ class TestAutofillDriver : public AutofillDriver {
void SetURLRequestContext(net::URLRequestContextGetter* url_request_context);
private:
- std::unique_ptr<base::SequencedWorkerPoolOwner> blocking_pool_owner_;
net::URLRequestContextGetter* url_request_context_;
DISALLOW_COPY_AND_ASSIGN(TestAutofillDriver);
diff --git a/chromium/components/autofill/core/browser/test_region_data_loader.cc b/chromium/components/autofill/core/browser/test_region_data_loader.cc
new file mode 100644
index 00000000000..de8e3fd3ec7
--- /dev/null
+++ b/chromium/components/autofill/core/browser/test_region_data_loader.cc
@@ -0,0 +1,55 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/test_region_data_loader.h"
+
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
+
+namespace autofill {
+
+TestRegionDataLoader::TestRegionDataLoader() {}
+
+TestRegionDataLoader::~TestRegionDataLoader() {}
+
+void TestRegionDataLoader::LoadRegionData(
+ const std::string& country_code,
+ autofill::RegionDataLoader::RegionDataLoaded callback,
+ int64_t unused_timeout_ms) {
+ if (synchronous_callback_) {
+ SendRegionData(regions_, callback);
+ } else {
+ country_code_ = country_code;
+ callback_ = callback;
+ }
+}
+
+void TestRegionDataLoader::ClearCallback() {
+ callback_.Reset();
+}
+
+void TestRegionDataLoader::SendAsynchronousData(
+ const std::vector<std::pair<std::string, std::string>>& regions) {
+ // Can not be both synchronous and asynchronous.
+ DCHECK(!synchronous_callback_);
+
+ // Don't bother if the callback was cleared.
+ if (callback_.is_null())
+ return;
+
+ SendRegionData(regions, callback_);
+ callback_.Reset();
+}
+
+void TestRegionDataLoader::SendRegionData(
+ const std::vector<std::pair<std::string, std::string>>& regions,
+ autofill::RegionDataLoader::RegionDataLoaded callback) {
+ ::i18n::addressinput::RegionData root_region("");
+ for (const auto& region : regions) {
+ root_region.AddSubRegion(region.first, region.second);
+ }
+
+ callback.Run(root_region.sub_regions());
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/test_region_data_loader.h b/chromium/components/autofill/core/browser/test_region_data_loader.h
new file mode 100644
index 00000000000..cf4472e4234
--- /dev/null
+++ b/chromium/components/autofill/core/browser/test_region_data_loader.h
@@ -0,0 +1,57 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_REGION_DATA_LOADER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_REGION_DATA_LOADER_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/callback.h"
+#include "components/autofill/core/browser/region_data_loader.h"
+
+namespace autofill {
+
+class TestRegionDataLoader : public RegionDataLoader {
+ public:
+ TestRegionDataLoader();
+ ~TestRegionDataLoader() override;
+
+ // RegionDataLoader.
+ void LoadRegionData(const std::string& country_code,
+ autofill::RegionDataLoader::RegionDataLoaded callback,
+ int64_t timeout_ms) override;
+ void ClearCallback() override;
+
+ std::string country_code() { return country_code_; }
+ const autofill::RegionDataLoader::RegionDataLoaded& callback() {
+ return callback_;
+ }
+ void set_synchronous_callback(bool synchronous_callback) {
+ synchronous_callback_ = synchronous_callback;
+ }
+
+ void SetRegionData(
+ std::vector<std::pair<std::string, std::string>>& regions) {
+ regions_ = regions;
+ }
+
+ void SendAsynchronousData(
+ const std::vector<std::pair<std::string, std::string>>& regions);
+
+ private:
+ void SendRegionData(
+ const std::vector<std::pair<std::string, std::string>>& regions,
+ autofill::RegionDataLoader::RegionDataLoaded callback);
+
+ std::vector<std::pair<std::string, std::string>> regions_;
+ std::string country_code_;
+ autofill::RegionDataLoader::RegionDataLoaded callback_;
+ bool synchronous_callback_{false};
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_REGION_DATA_LOADER_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc b/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc
index 00c26f4c732..2fd1c6cf551 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc
+++ b/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc
@@ -225,7 +225,7 @@ base::string16 CardUnmaskPromptControllerImpl::GetWindowTitle() const {
ShouldRequestExpirationDate()
? IDS_AUTOFILL_CARD_UNMASK_PROMPT_EXPIRED_TITLE
: IDS_AUTOFILL_CARD_UNMASK_PROMPT_TITLE,
- card_.TypeAndLastFourDigits());
+ card_.NetworkAndLastFourDigits());
#endif
}
@@ -240,7 +240,7 @@ base::string16 CardUnmaskPromptControllerImpl::GetInstructionsMessage() const {
}
// The iOS UI shows the card details in the instructions text since they
// don't fit in the title.
- return l10n_util::GetStringFUTF16(ids, card_.TypeAndLastFourDigits());
+ return l10n_util::GetStringFUTF16(ids, card_.NetworkAndLastFourDigits());
#else
return l10n_util::GetStringUTF16(
IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS);
@@ -252,8 +252,8 @@ base::string16 CardUnmaskPromptControllerImpl::GetOkButtonLabel() const {
}
int CardUnmaskPromptControllerImpl::GetCvcImageRid() const {
- return card_.type() == kAmericanExpressCard ? IDR_CREDIT_CARD_CVC_HINT_AMEX
- : IDR_CREDIT_CARD_CVC_HINT;
+ return card_.network() == kAmericanExpressCard ? IDR_CREDIT_CARD_CVC_HINT_AMEX
+ : IDR_CREDIT_CARD_CVC_HINT;
}
bool CardUnmaskPromptControllerImpl::ShouldRequestExpirationDate() const {
@@ -281,7 +281,7 @@ bool CardUnmaskPromptControllerImpl::InputCvcIsValid(
const base::string16& input_text) const {
base::string16 trimmed_text;
base::TrimWhitespace(input_text, base::TRIM_ALL, &trimmed_text);
- return IsValidCreditCardSecurityCode(trimmed_text, card_.type());
+ return IsValidCreditCardSecurityCode(trimmed_text, card_.network());
}
bool CardUnmaskPromptControllerImpl::InputExpirationIsValid(
@@ -310,7 +310,7 @@ bool CardUnmaskPromptControllerImpl::InputExpirationIsValid(
}
int CardUnmaskPromptControllerImpl::GetExpectedCvcLength() const {
- return GetCvcLengthForCardType(card_.type());
+ return GetCvcLengthForCardType(card_.network());
}
base::TimeDelta CardUnmaskPromptControllerImpl::GetSuccessMessageDuration()
diff --git a/chromium/components/autofill/core/browser/validation.cc b/chromium/components/autofill/core/browser/validation.cc
index e7237f7b3b7..60726b8e610 100644
--- a/chromium/components/autofill/core/browser/validation.cc
+++ b/chromium/components/autofill/core/browser/validation.cc
@@ -13,13 +13,14 @@
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_data_util.h"
-#include "components/autofill/core/browser/autofill_regex_constants.h"
#include "components/autofill/core/browser/credit_card.h"
-#include "components/autofill/core/browser/phone_number_i18n.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/state_names.h"
#include "components/autofill/core/common/autofill_clock.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
#include "components/autofill/core/common/autofill_regexes.h"
#include "components/strings/grit/components_strings.h"
+#include "third_party/libphonenumber/phonenumber_api.h"
#include "ui/base/l10n/l10n_util.h"
namespace autofill {
@@ -45,19 +46,21 @@ bool IsValidCreditCardExpirationDate(int year,
bool IsValidCreditCardNumber(const base::string16& text) {
base::string16 number = CreditCard::StripSeparators(text);
- // Credit card numbers are at most 19 digits in length [1]. 12 digits seems to
- // be a fairly safe lower-bound [2]. Specific card issuers have more rigidly
- // defined sizes.
- // [1] http://www.merriampark.com/anatomycc.htm
- // [2] http://en.wikipedia.org/wiki/Bank_card_number
+ // Credit card numbers are at most 19 digits in length, 12 digits seems to
+ // be a fairly safe lower-bound [1]. Specific card issuers have more rigidly
+ // defined sizes.
+ // (Last updated: May 29, 2017)
+ // [1] https://en.wikipedia.org/wiki/Payment_card_number.
// CardEditor.isCardNumberLengthMaxium() needs to be kept in sync.
- const char* const type = CreditCard::GetCreditCardType(text);
+ const char* const type = CreditCard::GetCardNetwork(text);
if (type == kAmericanExpressCard && number.size() != 15)
return false;
if (type == kDinersCard && number.size() != 14)
return false;
if (type == kDiscoverCard && number.size() != 16)
return false;
+ if (type == kEloCard && number.size() != 16)
+ return false;
if (type == kJCBCard && number.size() != 16)
return false;
if (type == kMasterCard && number.size() != 16)
@@ -66,7 +69,8 @@ bool IsValidCreditCardNumber(const base::string16& text) {
return false;
if (type == kUnionPay && (number.size() < 16 || number.size() > 19))
return false;
- if (type == kVisaCard && number.size() != 13 && number.size() != 16)
+ if (type == kVisaCard && number.size() != 13 && number.size() != 16 &&
+ number.size() != 19)
return false;
if (type == kGenericCard && (number.size() < 12 || number.size() > 19))
return false;
@@ -107,11 +111,11 @@ bool IsValidCreditCardNumberForBasicCardNetworks(
DCHECK(error_message);
// The type check is cheaper than the credit card number check.
- const std::string basic_card_payment_type =
+ const std::string basic_card_issuer_network =
autofill::data_util::GetPaymentRequestData(
- CreditCard::GetCreditCardType(text))
- .basic_card_payment_type;
- if (!supported_basic_card_networks.count(basic_card_payment_type)) {
+ CreditCard::GetCardNetwork(text))
+ .basic_card_issuer_network;
+ if (!supported_basic_card_networks.count(basic_card_issuer_network)) {
*error_message = l10n_util::GetStringUTF16(
IDS_PAYMENTS_VALIDATION_UNSUPPORTED_CREDIT_CARD_TYPE);
return false;
@@ -125,6 +129,53 @@ bool IsValidCreditCardNumberForBasicCardNetworks(
return false;
}
+CreditCardCompletionStatus GetCompletionStatusForCard(
+ const CreditCard& card,
+ const std::string& app_locale,
+ const std::vector<AutofillProfile*> billing_addresses) {
+ CreditCardCompletionStatus status = CREDIT_CARD_COMPLETE;
+ if (card.IsExpired(autofill::AutofillClock::Now()))
+ status |= CREDIT_CARD_EXPIRED;
+
+ if (card.number().empty())
+ status |= CREDIT_CARD_NO_NUMBER;
+
+ if (card.GetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL),
+ app_locale)
+ .empty()) {
+ status |= CREDIT_CARD_NO_CARDHOLDER;
+ }
+
+ if (card.billing_address_id().empty() ||
+ !autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
+ card.billing_address_id(), billing_addresses)) {
+ status |= CREDIT_CARD_NO_BILLING_ADDRESS;
+ }
+
+ return status;
+}
+
+base::string16 GetCompletionMessageForCard(CreditCardCompletionStatus status) {
+ switch (status) {
+ // No message is shown for complete or expired card (which will be fixable)
+ // in the CVC screen.
+ case CREDIT_CARD_COMPLETE:
+ case CREDIT_CARD_EXPIRED:
+ return base::string16();
+ case CREDIT_CARD_NO_CARDHOLDER:
+ return l10n_util::GetStringUTF16(IDS_PAYMENTS_NAME_ON_CARD_REQUIRED);
+ case CREDIT_CARD_NO_NUMBER:
+ return l10n_util::GetStringUTF16(
+ IDS_PAYMENTS_CARD_NUMBER_INVALID_VALIDATION_MESSAGE);
+ case CREDIT_CARD_NO_BILLING_ADDRESS:
+ return l10n_util::GetStringUTF16(
+ IDS_PAYMENTS_CARD_BILLING_ADDRESS_REQUIRED);
+ default:
+ // Multiple things are missing
+ return l10n_util::GetStringUTF16(IDS_PAYMENTS_MORE_INFORMATION_REQUIRED);
+ }
+}
+
bool IsValidEmailAddress(const base::string16& text) {
// E-Mail pattern as defined by the WhatWG. (4.10.7.1.5 E-Mail state)
const base::string16 kEmailPattern = base::ASCIIToUTF16(
@@ -140,8 +191,16 @@ bool IsValidState(const base::string16& text) {
bool IsValidPhoneNumber(const base::string16& text,
const std::string& country_code) {
- i18n::PhoneObject phone_number(text, country_code);
- return phone_number.IsValidNumber();
+ ::i18n::phonenumbers::PhoneNumber parsed_number;
+ ::i18n::phonenumbers::PhoneNumberUtil* phone_number_util =
+ ::i18n::phonenumbers::PhoneNumberUtil::GetInstance();
+ if (phone_number_util->Parse(base::UTF16ToUTF8(text), country_code,
+ &parsed_number) !=
+ ::i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) {
+ return false;
+ }
+
+ return phone_number_util->IsValidNumber(parsed_number);
}
bool IsValidZip(const base::string16& text) {
diff --git a/chromium/components/autofill/core/browser/validation.h b/chromium/components/autofill/core/browser/validation.h
index 93a52e59b4f..531cf273d7c 100644
--- a/chromium/components/autofill/core/browser/validation.h
+++ b/chromium/components/autofill/core/browser/validation.h
@@ -5,8 +5,12 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_VALIDATION_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_VALIDATION_H_
+#include <set>
+#include <string>
+#include <vector>
+
#include "base/strings/string16.h"
-#include "base/strings/string_piece.h"
+#include "base/strings/string_piece_forward.h"
#include "components/autofill/core/browser/field_types.h"
namespace base {
@@ -15,10 +19,21 @@ class Time;
namespace autofill {
+class CreditCard;
+class AutofillProfile;
+
// Constants for the length of a CVC.
static const size_t GENERAL_CVC_LENGTH = 3;
static const size_t AMEX_CVC_LENGTH = 4;
+// Used to express the completion status of a credit card.
+typedef uint32_t CreditCardCompletionStatus;
+static const CreditCardCompletionStatus CREDIT_CARD_COMPLETE = 0;
+static const CreditCardCompletionStatus CREDIT_CARD_EXPIRED = 1 << 0;
+static const CreditCardCompletionStatus CREDIT_CARD_NO_CARDHOLDER = 1 << 1;
+static const CreditCardCompletionStatus CREDIT_CARD_NO_NUMBER = 1 << 2;
+static const CreditCardCompletionStatus CREDIT_CARD_NO_BILLING_ADDRESS = 1 << 3;
+
// Returns true if |year| and |month| describe a date later than |now|.
// |year| must have 4 digits.
bool IsValidCreditCardExpirationDate(int year,
@@ -42,6 +57,18 @@ bool IsValidCreditCardNumberForBasicCardNetworks(
const std::set<std::string>& supported_basic_card_networks,
base::string16* error_message);
+// Returns the credit card's completion status. If equal to
+// CREDIT_CARD_COMPLETE, then the card is ready to be used for Payment Request.
+CreditCardCompletionStatus GetCompletionStatusForCard(
+ const CreditCard& credit_card,
+ const std::string& app_locale,
+ const std::vector<AutofillProfile*> billing_addresses);
+
+// Return the message to be displayed to the user, indicating what's missing
+// to make the credit card complete for payment. If more than one thing is
+// missing, the message will be a generic "more information required".
+base::string16 GetCompletionMessageForCard(CreditCardCompletionStatus status);
+
// Returns true if |text| looks like a valid e-mail address.
bool IsValidEmailAddress(const base::string16& text);
@@ -49,7 +76,8 @@ bool IsValidEmailAddress(const base::string16& text);
// insensitive. Valid for US states only.
bool IsValidState(const base::string16& text);
-// Returns whether the number contained in |text| is valid for the specified
+// Returns whether the number contained in |text| is valid, either in
+// international format, or in the national format associated with
// |country_code|. Callers should cache the result as the parsing is expensive.
bool IsValidPhoneNumber(const base::string16& text,
const std::string& country_code);
diff --git a/chromium/components/autofill/core/browser/validation_unittest.cc b/chromium/components/autofill/core/browser/validation_unittest.cc
index ee36fbc4543..8c4b95cefff 100644
--- a/chromium/components/autofill/core/browser/validation_unittest.cc
+++ b/chromium/components/autofill/core/browser/validation_unittest.cc
@@ -56,6 +56,8 @@ const char* const kValidNumbers[] = {
"5019717010103742",
"6331101999990016",
"6247130048162403",
+ "4532261615476013542", // Visa, 19 digits.
+ "6362970000457013", // Elo
};
const char* const kInvalidNumbers[] = {
"4111 1111 112", /* too short */
@@ -346,7 +348,7 @@ TEST_P(AutofillCCNumberValidationTest, IsValidCreditCardNumber) {
}
const static std::set<std::string> kAllBasicCardNetworks{
- "amex", "discover", "diners", "jcb",
+ "amex", "discover", "diners", "elo", "jcb",
"mastercard", "mir", "unionpay", "visa"};
INSTANTIATE_TEST_CASE_P(
@@ -384,6 +386,8 @@ INSTANTIATE_TEST_CASE_P(
IDS_PAYMENTS_VALIDATION_UNSUPPORTED_CREDIT_CARD_TYPE),
CCNumberCase(kValidNumbers[17], kAllBasicCardNetworks, true, 0),
+ CCNumberCase(kValidNumbers[18], kAllBasicCardNetworks, true, 0),
+ CCNumberCase(kValidNumbers[19], kAllBasicCardNetworks, true, 0),
CCNumberCase(kInvalidNumbers[0],
kAllBasicCardNetworks,
@@ -436,6 +440,7 @@ INSTANTIATE_TEST_CASE_P(
GetCvcLengthForCardTypeCase{kAmericanExpressCard, AMEX_CVC_LENGTH},
GetCvcLengthForCardTypeCase{kDinersCard, GENERAL_CVC_LENGTH},
GetCvcLengthForCardTypeCase{kDiscoverCard, GENERAL_CVC_LENGTH},
+ GetCvcLengthForCardTypeCase{kEloCard, GENERAL_CVC_LENGTH},
GetCvcLengthForCardTypeCase{kGenericCard, GENERAL_CVC_LENGTH},
GetCvcLengthForCardTypeCase{kJCBCard, GENERAL_CVC_LENGTH},
GetCvcLengthForCardTypeCase{kMasterCard, GENERAL_CVC_LENGTH},
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 9ed91408190..7049f31ff17 100644
--- a/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
@@ -15,13 +15,13 @@
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/proto/autofill_sync.pb.h"
-#include "components/autofill/core/browser/webdata/autofill_metadata_change_list.h"
#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/sync/model/entity_data.h"
#include "components/sync/model/model_type_change_processor.h"
#include "components/sync/model/mutable_data_batch.h"
+#include "components/sync/model_impl/sync_metadata_store_change_list.h"
#include "net/base/escape.h"
using base::Optional;
@@ -216,7 +216,8 @@ class SyncDifferenceTracker {
metadata_change_list.get());
}
}
- return static_cast<AutofillMetadataChangeList*>(metadata_change_list.get())
+ return static_cast<syncer::SyncMetadataStoreChangeList*>(
+ metadata_change_list.get())
->TakeError();
}
@@ -284,7 +285,7 @@ void AutocompleteSyncBridge::CreateForWebDataServiceAndBackend(
AutofillWebDataBackend* web_data_backend) {
web_data_service->GetDBUserData()->SetUserData(
UserDataKey(),
- new AutocompleteSyncBridge(
+ base::MakeUnique<AutocompleteSyncBridge>(
web_data_backend,
base::BindRepeating(
&ModelTypeChangeProcessor::Create,
@@ -319,8 +320,8 @@ AutocompleteSyncBridge::~AutocompleteSyncBridge() {
std::unique_ptr<MetadataChangeList>
AutocompleteSyncBridge::CreateMetadataChangeList() {
DCHECK(thread_checker_.CalledOnValidThread());
- return base::MakeUnique<AutofillMetadataChangeList>(GetAutofillTable(),
- syncer::AUTOFILL);
+ return base::MakeUnique<syncer::SyncMetadataStoreChangeList>(
+ GetAutofillTable(), syncer::AUTOFILL);
}
Optional<syncer::ModelError> AutocompleteSyncBridge::MergeSyncData(
@@ -412,8 +413,9 @@ void AutocompleteSyncBridge::ActOnLocalChanges(
return;
}
- auto metadata_change_list = base::MakeUnique<AutofillMetadataChangeList>(
- GetAutofillTable(), syncer::AUTOFILL);
+ auto metadata_change_list =
+ base::MakeUnique<syncer::SyncMetadataStoreChangeList>(GetAutofillTable(),
+ syncer::AUTOFILL);
for (const auto& change : changes) {
const std::string storage_key = GetStorageKeyFromModel(change.key());
switch (change.type()) {
@@ -446,6 +448,13 @@ void AutocompleteSyncBridge::ActOnLocalChanges(
}
void AutocompleteSyncBridge::LoadMetadata() {
+ if (!web_data_backend_ || !web_data_backend_->GetDatabase() ||
+ !GetAutofillTable()) {
+ change_processor()->ReportError(FROM_HERE,
+ "Failed to load AutofillWebDatabase.");
+ return;
+ }
+
auto batch = base::MakeUnique<syncer::MetadataBatch>();
if (!GetAutofillTable()->GetAllSyncMetadata(syncer::AUTOFILL, batch.get())) {
change_processor()->ReportError(
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 bdb786daa6a..59506b1c911 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
@@ -50,6 +50,7 @@ using syncer::ModelError;
using syncer::ModelType;
using syncer::ModelTypeChangeProcessor;
using syncer::ModelTypeSyncBridge;
+using syncer::RecordingModelTypeChangeProcessor;
namespace autofill {
@@ -140,11 +141,10 @@ class AutocompleteSyncBridgeTest : public testing::Test {
}
~AutocompleteSyncBridgeTest() override {}
- void ResetBridge() {
+ void ResetBridge(bool expect_error = false) {
bridge_.reset(new AutocompleteSyncBridge(
- &backend_,
- base::Bind(&AutocompleteSyncBridgeTest::CreateModelTypeChangeProcessor,
- base::Unretained(this))));
+ &backend_, RecordingModelTypeChangeProcessor::FactoryForBridgeTest(
+ &processor_, expect_error)));
}
void SaveSpecificsToTable(
@@ -246,12 +246,12 @@ class AutocompleteSyncBridgeTest : public testing::Test {
int position = 0) {
const std::string storage_key = GetStorageKey(specifics);
auto recorded_specifics_iterator =
- processor()->put_multimap().find(storage_key);
+ processor().put_multimap().find(storage_key);
- EXPECT_NE(processor()->put_multimap().end(), recorded_specifics_iterator);
+ EXPECT_NE(processor().put_multimap().end(), recorded_specifics_iterator);
while (position > 0) {
recorded_specifics_iterator++;
- EXPECT_NE(processor()->put_multimap().end(), recorded_specifics_iterator);
+ EXPECT_NE(processor().put_multimap().end(), recorded_specifics_iterator);
position--;
}
@@ -262,20 +262,13 @@ class AutocompleteSyncBridgeTest : public testing::Test {
AutocompleteSyncBridge* bridge() { return bridge_.get(); }
- syncer::RecordingModelTypeChangeProcessor* processor() { return processor_; }
+ const RecordingModelTypeChangeProcessor& processor() { return *processor_; }
AutofillTable* table() { return &table_; }
- private:
- std::unique_ptr<syncer::ModelTypeChangeProcessor>
- CreateModelTypeChangeProcessor(syncer::ModelType type,
- syncer::ModelTypeSyncBridge* bridge) {
- auto processor =
- base::MakeUnique<syncer::RecordingModelTypeChangeProcessor>();
- processor_ = processor.get();
- return std::move(processor);
- }
+ FakeAutofillBackend* backend() { return &backend_; }
+ private:
ScopedTempDir temp_dir_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
FakeAutofillBackend backend_;
@@ -284,7 +277,7 @@ class AutocompleteSyncBridgeTest : public testing::Test {
std::unique_ptr<AutocompleteSyncBridge> bridge_;
// A non-owning pointer to the processor given to the bridge. Will be null
// before being given to the bridge, to make ownership easier.
- syncer::RecordingModelTypeChangeProcessor* processor_ = nullptr;
+ RecordingModelTypeChangeProcessor* processor_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AutocompleteSyncBridgeTest);
};
@@ -541,7 +534,7 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntriesAdded) {
{AutofillChange(AutofillChange::ADD, added_entry1.key()),
AutofillChange(AutofillChange::ADD, added_entry2.key())});
- EXPECT_EQ(2u, processor()->put_multimap().size());
+ EXPECT_EQ(2u, processor().put_multimap().size());
VerifyProcessorRecordedPut(added_specifics1);
VerifyProcessorRecordedPut(added_specifics2);
@@ -555,7 +548,7 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntryAddedThenUpdated) {
bridge()->AutofillEntriesChanged(
{AutofillChange(AutofillChange::ADD, added_entry.key())});
- EXPECT_EQ(1u, processor()->put_multimap().size());
+ EXPECT_EQ(1u, processor().put_multimap().size());
VerifyProcessorRecordedPut(added_specifics);
@@ -577,16 +570,15 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntryDeleted) {
bridge()->AutofillEntriesChanged(
{AutofillChange(AutofillChange::REMOVE, deleted_entry.key())});
- EXPECT_EQ(1u, processor()->delete_set().size());
- EXPECT_NE(processor()->delete_set().end(),
- processor()->delete_set().find(storage_key));
+ EXPECT_EQ(1u, processor().delete_set().size());
+ EXPECT_NE(processor().delete_set().end(),
+ processor().delete_set().find(storage_key));
}
TEST_F(AutocompleteSyncBridgeTest, LoadMetadataCalled) {
- EXPECT_NE(nullptr, processor()->metadata());
- EXPECT_FALSE(
- processor()->metadata()->GetModelTypeState().initial_sync_done());
- EXPECT_EQ(0u, processor()->metadata()->TakeAllMetadata().size());
+ EXPECT_NE(nullptr, processor().metadata());
+ EXPECT_FALSE(processor().metadata()->GetModelTypeState().initial_sync_done());
+ EXPECT_EQ(0u, processor().metadata()->TakeAllMetadata().size());
ModelTypeState model_type_state;
model_type_state.set_initial_sync_done(true);
@@ -597,17 +589,23 @@ TEST_F(AutocompleteSyncBridgeTest, LoadMetadataCalled) {
ResetBridge();
- EXPECT_NE(nullptr, processor()->metadata());
- EXPECT_TRUE(processor()->metadata()->GetModelTypeState().initial_sync_done());
- EXPECT_EQ(1u, processor()->metadata()->TakeAllMetadata().size());
+ EXPECT_NE(nullptr, processor().metadata());
+ EXPECT_TRUE(processor().metadata()->GetModelTypeState().initial_sync_done());
+ EXPECT_EQ(1u, processor().metadata()->TakeAllMetadata().size());
+}
+
+TEST_F(AutocompleteSyncBridgeTest, LoadMetadataReportsErrorForMissingDB) {
+ backend()->SetWebDatabase(nullptr);
+ // The processor's destructor will verify that an error has occured.
+ ResetBridge(/*expect_error=*/true);
}
TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataEmpty) {
VerifyMerge(std::vector<AutofillSpecifics>());
VerifyAllData(std::vector<AutofillSpecifics>());
- EXPECT_EQ(0u, processor()->delete_set().size());
- EXPECT_EQ(0u, processor()->put_multimap().size());
+ EXPECT_EQ(0u, processor().delete_set().size());
+ EXPECT_EQ(0u, processor().put_multimap().size());
}
TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataRemoteOnly) {
@@ -617,8 +615,8 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataRemoteOnly) {
VerifyMerge({specifics1, specifics2});
VerifyAllData({specifics1, specifics2});
- EXPECT_EQ(0u, processor()->delete_set().size());
- EXPECT_EQ(0u, processor()->put_multimap().size());
+ EXPECT_EQ(0u, processor().delete_set().size());
+ EXPECT_EQ(0u, processor().put_multimap().size());
}
TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataLocalOnly) {
@@ -630,10 +628,10 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataLocalOnly) {
VerifyMerge(std::vector<AutofillSpecifics>());
VerifyAllData({specifics1, specifics2});
- EXPECT_EQ(2u, processor()->put_multimap().size());
+ EXPECT_EQ(2u, processor().put_multimap().size());
VerifyProcessorRecordedPut(specifics1);
VerifyProcessorRecordedPut(specifics2);
- EXPECT_EQ(0u, processor()->delete_set().size());
+ EXPECT_EQ(0u, processor().delete_set().size());
}
TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataAllMerged) {
@@ -660,12 +658,12 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataAllMerged) {
VerifyMerge({remote1, remote2, remote3, remote4, remote5, remote6});
VerifyAllData({merged1, merged2, merged3, merged4, merged5, merged6});
- EXPECT_EQ(4u, processor()->put_multimap().size());
+ EXPECT_EQ(4u, processor().put_multimap().size());
VerifyProcessorRecordedPut(merged3);
VerifyProcessorRecordedPut(merged4);
VerifyProcessorRecordedPut(merged5);
VerifyProcessorRecordedPut(merged6);
- EXPECT_EQ(0u, processor()->delete_set().size());
+ EXPECT_EQ(0u, processor().delete_set().size());
}
TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataMixed) {
@@ -681,10 +679,10 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataMixed) {
VerifyMerge({remote2, specifics3, remote4});
VerifyAllData({local1, remote2, specifics3, merged4});
- EXPECT_EQ(2u, processor()->put_multimap().size());
+ EXPECT_EQ(2u, processor().put_multimap().size());
VerifyProcessorRecordedPut(local1);
VerifyProcessorRecordedPut(merged4);
- EXPECT_EQ(0u, processor()->delete_set().size());
+ EXPECT_EQ(0u, processor().delete_set().size());
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc b/chromium/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc
index d303d165ae5..816addcbf15 100644
--- a/chromium/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc
@@ -10,6 +10,7 @@
#include "base/location.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
@@ -80,7 +81,8 @@ void AutocompleteSyncableService::CreateForWebDataServiceAndBackend(
AutofillWebDataService* web_data_service,
AutofillWebDataBackend* web_data_backend) {
web_data_service->GetDBUserData()->SetUserData(
- UserDataKey(), new AutocompleteSyncableService(web_data_backend));
+ UserDataKey(),
+ base::WrapUnique(new AutocompleteSyncableService(web_data_backend)));
}
// static
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_data_type_controller.h b/chromium/components/autofill/core/browser/webdata/autofill_data_type_controller.h
index bccdbf7d9f7..b70f4143ba0 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_data_type_controller.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_data_type_controller.h
@@ -11,6 +11,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "components/sync/driver/async_directory_type_controller.h"
namespace autofill {
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.cc b/chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.cc
deleted file mode 100644
index 24876e4a0cf..00000000000
--- a/chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 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_metadata_change_list.h"
-
-#include "base/location.h"
-
-using base::Optional;
-using syncer::ModelError;
-
-namespace autofill {
-
-AutofillMetadataChangeList::AutofillMetadataChangeList(AutofillTable* table,
- syncer::ModelType type)
- : table_(table), type_(type) {
- DCHECK(table_);
- // This should be changed as new autofill types are converted to USS.
- DCHECK_EQ(syncer::AUTOFILL, type_);
-}
-
-AutofillMetadataChangeList::~AutofillMetadataChangeList() {
- DCHECK(!error_);
-}
-
-void AutofillMetadataChangeList::UpdateModelTypeState(
- const sync_pb::ModelTypeState& model_type_state) {
- if (error_) {
- return;
- }
-
- if (!table_->UpdateModelTypeState(type_, model_type_state)) {
- error_ = ModelError(FROM_HERE, "Failed to update ModelTypeState.");
- }
-}
-
-void AutofillMetadataChangeList::ClearModelTypeState() {
- if (error_) {
- return;
- }
-
- if (!table_->ClearModelTypeState(type_)) {
- error_ = ModelError(FROM_HERE, "Failed to clear ModelTypeState.");
- }
-}
-
-void AutofillMetadataChangeList::UpdateMetadata(
- const std::string& storage_key,
- const sync_pb::EntityMetadata& metadata) {
- if (error_) {
- return;
- }
-
- if (!table_->UpdateSyncMetadata(type_, storage_key, metadata)) {
- error_ = ModelError(FROM_HERE, "Failed to update entity metadata.");
- }
-}
-
-void AutofillMetadataChangeList::ClearMetadata(const std::string& storage_key) {
- if (error_) {
- return;
- }
-
- if (!table_->ClearSyncMetadata(type_, storage_key)) {
- error_ = ModelError(FROM_HERE, "Failed to clear entity metadata.");
- }
-}
-
-Optional<ModelError> AutofillMetadataChangeList::TakeError() {
- Optional<ModelError> temp = error_;
- error_.reset();
- return temp;
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.h b/chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.h
deleted file mode 100644
index e924e2070a6..00000000000
--- a/chromium/components/autofill/core/browser/webdata/autofill_metadata_change_list.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 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_METADATA_CHANGE_LIST_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_METADATA_CHANGE_LIST_H_
-
-#include <string>
-
-#include "base/optional.h"
-#include "components/autofill/core/browser/webdata/autofill_table.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/model/metadata_change_list.h"
-#include "components/sync/model/model_error.h"
-#include "components/sync/model/sync_error.h"
-#include "components/sync/protocol/entity_metadata.pb.h"
-#include "components/sync/protocol/model_type_state.pb.h"
-
-namespace autofill {
-
-// A thin wrapper around an AutofillTable that implements sync's
-// MetadataChangeList interface. Changes are passed directly into the table and
-// not stored inside this object. Since the table calls can fail, |TakeError()|
-// must be called before this object is destroyed to check whether any
-// operations failed.
-class AutofillMetadataChangeList : public syncer::MetadataChangeList {
- public:
- AutofillMetadataChangeList(AutofillTable* table, syncer::ModelType type);
- ~AutofillMetadataChangeList() override;
-
- // syncer::MetadataChangeList implementation.
- void UpdateModelTypeState(
- const sync_pb::ModelTypeState& model_type_state) override;
- void ClearModelTypeState() override;
- void UpdateMetadata(const std::string& storage_key,
- const sync_pb::EntityMetadata& metadata) override;
- void ClearMetadata(const std::string& storage_key) override;
-
- // Returns the value of |error_| and unsets it.
- base::Optional<syncer::ModelError> TakeError();
-
- private:
- // The autofill table to store metadata in; always outlives |this|.
- AutofillTable* table_;
-
- // The sync model type for this metadata.
- syncer::ModelType type_;
-
- // The first error encountered by this object, if any.
- base::Optional<syncer::ModelError> error_;
-};
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_METADATA_CHANGE_LIST_H_
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 6dd5fd55893..ac419b54305 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
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_observer.h"
+#include "base/single_thread_task_runner.h"
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "components/sync/driver/async_directory_type_controller.h"
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 0e5035111c2..1fa55f74027 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
@@ -72,8 +72,8 @@ void AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
AutofillWebDataBackend* webdata_backend,
const std::string& app_locale) {
web_data_service->GetDBUserData()->SetUserData(
- UserDataKey(),
- new AutofillProfileSyncableService(webdata_backend, app_locale));
+ UserDataKey(), base::WrapUnique(new AutofillProfileSyncableService(
+ webdata_backend, app_locale)));
}
// static
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_table.cc b/chromium/components/autofill/core/browser/webdata/autofill_table.cc
index 27d1c00d470..d98db894172 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table.cc
@@ -45,10 +45,6 @@
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
-using base::ASCIIToUTF16;
-using base::Time;
-using base::TimeDelta;
-
namespace autofill {
namespace {
@@ -83,7 +79,7 @@ base::string16 GetInfo(const AutofillDataModel& data_model,
}
void BindAutofillProfileToStatement(const AutofillProfile& profile,
- const Time& modification_date,
+ const base::Time& modification_date,
sql::Statement* s) {
DCHECK(base::IsValidGUID(profile.guid()));
int index = 0;
@@ -121,8 +117,8 @@ std::unique_ptr<AutofillProfile> AutofillProfileFromStatement(
profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE, s.ColumnString16(index++));
profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(index++));
profile->set_use_count(s.ColumnInt64(index++));
- profile->set_use_date(Time::FromTimeT(s.ColumnInt64(index++)));
- profile->set_modification_date(Time::FromTimeT(s.ColumnInt64(index++)));
+ profile->set_use_date(base::Time::FromTimeT(s.ColumnInt64(index++)));
+ profile->set_modification_date(base::Time::FromTimeT(s.ColumnInt64(index++)));
profile->set_origin(s.ColumnString(index++));
profile->set_language_code(s.ColumnString(index++));
@@ -140,7 +136,7 @@ void BindEncryptedCardToColumn(sql::Statement* s,
}
void BindCreditCardToStatement(const CreditCard& credit_card,
- const Time& modification_date,
+ const base::Time& modification_date,
sql::Statement* s,
const AutofillTableEncryptor& encryptor) {
DCHECK(base::IsValidGUID(credit_card.guid()));
@@ -192,8 +188,9 @@ std::unique_ptr<CreditCard> CreditCardFromStatement(
credit_card->SetRawInfo(CREDIT_CARD_NUMBER,
UnencryptedCardFromColumn(s, index++, encryptor));
credit_card->set_use_count(s.ColumnInt64(index++));
- credit_card->set_use_date(Time::FromTimeT(s.ColumnInt64(index++)));
- credit_card->set_modification_date(Time::FromTimeT(s.ColumnInt64(index++)));
+ credit_card->set_use_date(base::Time::FromTimeT(s.ColumnInt64(index++)));
+ credit_card->set_modification_date(
+ base::Time::FromTimeT(s.ColumnInt64(index++)));
credit_card->set_origin(s.ColumnString(index++));
credit_card->set_billing_address_id(s.ColumnString(index++));
@@ -229,10 +226,7 @@ bool AddAutofillProfileEmailsToProfile(sql::Connection* db,
// TODO(estade): update schema so that multiple emails are not associated per
// unique profile guid. Please refer https://crbug.com/497934.
sql::Statement s(db->GetUniqueStatement(
- "SELECT guid, email "
- "FROM autofill_profile_emails "
- "WHERE guid=?"
- "LIMIT 1"));
+ "SELECT guid, email FROM autofill_profile_emails WHERE guid=? LIMIT 1"));
s.BindString(0, profile->guid());
if (!s.is_valid())
@@ -250,10 +244,7 @@ bool AddAutofillProfilePhonesToProfile(sql::Connection* db,
// TODO(estade): update schema so that multiple phone numbers are not
// associated per unique profile guid. Please refer https://crbug.com/497934.
sql::Statement s(db->GetUniqueStatement(
- "SELECT guid, number "
- "FROM autofill_profile_phones "
- "WHERE guid=?"
- "LIMIT 1"));
+ "SELECT guid, number FROM autofill_profile_phones WHERE guid=? LIMIT 1"));
s.BindString(0, profile->guid());
if (!s.is_valid())
@@ -286,9 +277,7 @@ bool AddAutofillProfileEmails(const AutofillProfile& profile,
sql::Connection* db) {
// Add the new email.
sql::Statement s(db->GetUniqueStatement(
- "INSERT INTO autofill_profile_emails"
- " (guid, email) "
- "VALUES (?,?)"));
+ "INSERT INTO autofill_profile_emails (guid, email) VALUES (?,?)"));
s.BindString(0, profile.guid());
s.BindString16(1, profile.GetRawInfo(EMAIL_ADDRESS));
@@ -299,9 +288,7 @@ bool AddAutofillProfilePhones(const AutofillProfile& profile,
sql::Connection* db) {
// Add the new number.
sql::Statement s(db->GetUniqueStatement(
- "INSERT INTO autofill_profile_phones"
- " (guid, number) "
- "VALUES (?,?)"));
+ "INSERT INTO autofill_profile_phones (guid, number) VALUES (?,?)"));
s.BindString(0, profile.guid());
s.BindString16(1, profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
@@ -351,8 +338,8 @@ WebDatabaseTable::TypeKey GetKey() {
return reinterpret_cast<void*>(&table_key);
}
-time_t GetEndTime(const Time& end) {
- if (end.is_null() || end == Time::Max())
+time_t GetEndTime(const base::Time& end) {
+ if (end.is_null() || end == base::Time::Max())
return std::numeric_limits<time_t>::max();
return end.ToTimeT();
@@ -412,8 +399,7 @@ AutofillTable::AutofillTable()
DCHECK(autofill_table_encryptor_);
}
-AutofillTable::~AutofillTable() {
-}
+AutofillTable::~AutofillTable() {}
AutofillTable* AutofillTable::FromWebDatabase(WebDatabase* db) {
return static_cast<AutofillTable*>(db->GetTable(GetKey()));
@@ -483,6 +469,9 @@ bool AutofillTable::MigrateToVersion(int version,
case 71:
*update_compatible_version = true;
return MigrateToVersion71AddHasConvertedAndBillingAddressIdMetadata();
+ case 72:
+ *update_compatible_version = true;
+ return MigrateToVersion72RenameCardTypeToIssuerNetwork();
}
return true;
}
@@ -508,11 +497,9 @@ bool AutofillTable::GetFormValuesForElementName(
if (prefix.empty()) {
sql::Statement s;
- s.Assign(db_->GetUniqueStatement(
- "SELECT value FROM autofill "
- "WHERE name = ? "
- "ORDER BY count DESC "
- "LIMIT ?"));
+ s.Assign(
+ db_->GetUniqueStatement("SELECT value FROM autofill WHERE name = ? "
+ "ORDER BY count DESC LIMIT ?"));
s.BindString16(0, name);
s.BindInt(1, limit);
@@ -527,13 +514,13 @@ bool AutofillTable::GetFormValuesForElementName(
next_prefix.back()++;
sql::Statement s1;
- s1.Assign(db_->GetUniqueStatement(
- "SELECT value FROM autofill "
- "WHERE name = ? AND "
- "value_lower >= ? AND "
- "value_lower < ? "
- "ORDER BY count DESC "
- "LIMIT ?"));
+ s1.Assign(
+ db_->GetUniqueStatement("SELECT value FROM autofill "
+ "WHERE name = ? AND "
+ "value_lower >= ? AND "
+ "value_lower < ? "
+ "ORDER BY count DESC "
+ "LIMIT ?"));
s1.BindString16(0, name);
s1.BindString16(1, prefix_lower);
s1.BindString16(2, next_prefix);
@@ -561,7 +548,8 @@ bool AutofillTable::GetFormValuesForElementName(
s2.BindString16(0, name);
// escaper as L'!' -> 0x21.
- s2.BindString16(1, Substitute(prefix_lower, ASCIIToUTF16("_%"), 0x21));
+ s2.BindString16(1,
+ Substitute(prefix_lower, base::ASCIIToUTF16("_%"), 0x21));
s2.BindInt(2, limit);
while (s2.Step())
values->push_back(s2.ColumnString16(0));
@@ -574,8 +562,8 @@ bool AutofillTable::GetFormValuesForElementName(
}
bool AutofillTable::RemoveFormElementsAddedBetween(
- const Time& delete_begin,
- const Time& delete_end,
+ const base::Time& delete_begin,
+ const base::Time& delete_end,
std::vector<AutofillChange>* changes) {
const time_t delete_begin_time_t = delete_begin.ToTimeT();
const time_t delete_end_time_t = GetEndTime(delete_end);
@@ -629,14 +617,12 @@ bool AutofillTable::RemoveFormElementsAddedBetween(
AutofillUpdate updated_entry;
updated_entry.name = name;
updated_entry.value = value;
- updated_entry.date_created =
- date_created_time_t < delete_begin_time_t ?
- date_created_time_t :
- delete_end_time_t;
- updated_entry.date_last_used =
- date_last_used_time_t >= delete_end_time_t ?
- date_last_used_time_t :
- delete_begin_time_t - 1;
+ updated_entry.date_created = date_created_time_t < delete_begin_time_t
+ ? date_created_time_t
+ : delete_end_time_t;
+ updated_entry.date_last_used = date_last_used_time_t >= delete_end_time_t
+ ? date_last_used_time_t
+ : delete_begin_time_t - 1;
updated_entry.count =
1 +
Round(1.0 * (count - 1) *
@@ -663,8 +649,8 @@ bool AutofillTable::RemoveFormElementsAddedBetween(
return false;
for (size_t i = 0; i < updates.size(); ++i) {
sql::Statement s_update(db_->GetUniqueStatement(
- "UPDATE autofill SET date_created = ?, date_last_used = ?, count = ?"
- "WHERE name = ? AND value = ?"));
+ "UPDATE autofill SET date_created = ?, date_last_used = ?, count = ?"
+ "WHERE name = ? AND value = ?"));
s_update.BindInt64(0, updates[i].date_created);
s_update.BindInt64(1, updates[i].date_last_used);
s_update.BindInt(2, updates[i].count);
@@ -682,8 +668,8 @@ bool AutofillTable::RemoveFormElementsAddedBetween(
bool AutofillTable::RemoveExpiredFormElements(
std::vector<AutofillChange>* changes) {
- Time expiration_time =
- AutofillClock::Now() - TimeDelta::FromDays(kExpirationPeriodInDays);
+ base::Time expiration_time =
+ AutofillClock::Now() - base::TimeDelta::FromDays(kExpirationPeriodInDays);
// Query for the name and value of all form elements that were last used
// before the |expiration_time|.
@@ -701,8 +687,8 @@ bool AutofillTable::RemoveExpiredFormElements(
if (!select_for_delete.Succeeded())
return false;
- sql::Statement delete_data_statement(db_->GetUniqueStatement(
- "DELETE FROM autofill WHERE date_last_used < ?"));
+ sql::Statement delete_data_statement(
+ db_->GetUniqueStatement("DELETE FROM autofill WHERE date_last_used < ?"));
delete_data_statement.BindInt64(0, expiration_time.ToTimeT());
if (!delete_data_statement.Run())
return false;
@@ -714,7 +700,7 @@ bool AutofillTable::RemoveExpiredFormElements(
bool AutofillTable::AddFormFieldValuesTime(
const std::vector<FormFieldData>& elements,
std::vector<AutofillChange>* changes,
- Time time) {
+ base::Time time) {
// Only add one new entry for each unique element name. Use |seen_names| to
// track this. Add up to |kMaximumUniqueNames| unique entries per form.
const size_t kMaximumUniqueNames = 256;
@@ -731,9 +717,8 @@ bool AutofillTable::AddFormFieldValuesTime(
return result;
}
-int AutofillTable::GetCountOfValuesContainedBetween(
- const Time& begin,
- const Time& end) {
+int AutofillTable::GetCountOfValuesContainedBetween(const base::Time& begin,
+ const base::Time& end) {
const time_t begin_time_t = begin.ToTimeT();
const time_t end_time_t = GetEndTime(end);
@@ -761,8 +746,8 @@ bool AutofillTable::GetAllAutofillEntries(std::vector<AutofillEntry>* entries) {
while (s.Step()) {
base::string16 name = s.ColumnString16(0);
base::string16 value = s.ColumnString16(1);
- Time date_created = Time::FromTimeT(s.ColumnInt64(2));
- Time date_last_used = Time::FromTimeT(s.ColumnInt64(3));
+ base::Time date_created = base::Time::FromTimeT(s.ColumnInt64(2));
+ base::Time date_last_used = base::Time::FromTimeT(s.ColumnInt64(3));
entries->push_back(
AutofillEntry(AutofillKey(name, value), date_created, date_last_used));
}
@@ -772,8 +757,8 @@ bool AutofillTable::GetAllAutofillEntries(std::vector<AutofillEntry>* entries) {
bool AutofillTable::GetAutofillTimestamps(const base::string16& name,
const base::string16& value,
- Time* date_created,
- Time* date_last_used) {
+ base::Time* date_created,
+ base::Time* date_last_used) {
sql::Statement s(db_->GetUniqueStatement(
"SELECT date_created, date_last_used FROM autofill "
"WHERE name = ? AND value = ?"));
@@ -782,8 +767,8 @@ bool AutofillTable::GetAutofillTimestamps(const base::string16& name,
if (!s.Step())
return false;
- *date_created = Time::FromTimeT(s.ColumnInt64(0));
- *date_last_used = Time::FromTimeT(s.ColumnInt64(1));
+ *date_created = base::Time::FromTimeT(s.ColumnInt64(0));
+ *date_last_used = base::Time::FromTimeT(s.ColumnInt64(1));
DCHECK(!s.Step());
return true;
@@ -834,7 +819,7 @@ bool AutofillTable::InsertAutofillEntry(const AutofillEntry& entry) {
bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element,
std::vector<AutofillChange>* changes,
- Time time) {
+ base::Time time) {
sql::Statement s_exists(db_->GetUniqueStatement(
"SELECT COUNT(*) FROM autofill WHERE name = ? AND value = ?"));
s_exists.BindString16(0, element.name);
@@ -875,7 +860,6 @@ bool AutofillTable::AddFormFieldValueTime(const FormFieldData& element,
return true;
}
-
bool AutofillTable::RemoveFormElement(const base::string16& name,
const base::string16& value) {
sql::Statement s(db_->GetUniqueStatement(
@@ -938,9 +922,7 @@ bool AutofillTable::GetAutofillProfiles(
profiles->clear();
sql::Statement s(db_->GetUniqueStatement(
- "SELECT guid "
- "FROM autofill_profiles "
- "ORDER BY date_modified DESC, guid"));
+ "SELECT guid FROM autofill_profiles ORDER BY date_modified DESC, guid"));
while (s.Step()) {
std::string guid = s.ColumnString(0);
@@ -984,10 +966,11 @@ bool AutofillTable::GetServerProfiles(
base::MakeUnique<AutofillProfile>(AutofillProfile::SERVER_PROFILE,
s.ColumnString(index++));
profile->set_use_count(s.ColumnInt64(index++));
- profile->set_use_date(Time::FromInternalValue(s.ColumnInt64(index++)));
+ profile->set_use_date(
+ base::Time::FromInternalValue(s.ColumnInt64(index++)));
// Modification date is not tracked for server profiles. Explicitly set it
// here to override the default value of AutofillClock::Now().
- profile->set_modification_date(Time());
+ profile->set_modification_date(base::Time());
base::string16 recipient_name = s.ColumnString16(index++);
profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
@@ -1024,25 +1007,25 @@ void AutofillTable::SetServerProfiles(
return;
// Delete all old ones first.
- sql::Statement delete_old(db_->GetUniqueStatement(
- "DELETE FROM server_addresses"));
+ sql::Statement delete_old(
+ db_->GetUniqueStatement("DELETE FROM server_addresses"));
delete_old.Run();
sql::Statement insert(db_->GetUniqueStatement(
"INSERT INTO server_addresses("
- "id,"
- "recipient_name,"
- "company_name,"
- "street_address,"
- "address_1," // ADDRESS_HOME_STATE
- "address_2," // ADDRESS_HOME_CITY
- "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
- "address_4," // Not supported in AutofillProfile yet.
- "postal_code," // ADDRESS_HOME_ZIP
- "sorting_code," // ADDRESS_HOME_SORTING_CODE
- "country_code," // ADDRESS_HOME_COUNTRY
- "phone_number," // PHONE_HOME_WHOLE_NUMBER
- "language_code) "
+ "id,"
+ "recipient_name,"
+ "company_name,"
+ "street_address,"
+ "address_1," // ADDRESS_HOME_STATE
+ "address_2," // ADDRESS_HOME_CITY
+ "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
+ "address_4," // Not supported in AutofillProfile yet.
+ "postal_code," // ADDRESS_HOME_ZIP
+ "sorting_code," // ADDRESS_HOME_SORTING_CODE
+ "country_code," // ADDRESS_HOME_COUNTRY
+ "phone_number," // PHONE_HOME_WHOLE_NUMBER
+ "language_code) "
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
for (const auto& profile : profiles) {
DCHECK(profile.record_type() == AutofillProfile::SERVER_PROFILE);
@@ -1074,7 +1057,7 @@ void AutofillTable::SetServerProfiles(
// Delete metadata that's no longer relevant.
sql::Statement metadata_delete(db_->GetUniqueStatement(
"DELETE FROM server_address_metadata WHERE id NOT IN "
- "(SELECT id FROM server_addresses)"));
+ "(SELECT id FROM server_addresses)"));
metadata_delete.Run();
transaction.Commit();
@@ -1133,8 +1116,8 @@ bool AutofillTable::RemoveAutofillProfile(const std::string& guid) {
return success;
}
- sql::Statement s(db_->GetUniqueStatement(
- "DELETE FROM autofill_profiles WHERE guid = ?"));
+ sql::Statement s(
+ db_->GetUniqueStatement("DELETE FROM autofill_profiles WHERE guid = ?"));
s.BindString(0, guid);
if (!s.Run())
@@ -1144,26 +1127,25 @@ bool AutofillTable::RemoveAutofillProfile(const std::string& guid) {
}
bool AutofillTable::ClearAutofillProfiles() {
- sql::Statement s1(db_->GetUniqueStatement(
- "DELETE FROM autofill_profiles"));
+ sql::Statement s1(db_->GetUniqueStatement("DELETE FROM autofill_profiles"));
if (!s1.Run())
return false;
- sql::Statement s2(db_->GetUniqueStatement(
- "DELETE FROM autofill_profile_names"));
+ sql::Statement s2(
+ db_->GetUniqueStatement("DELETE FROM autofill_profile_names"));
if (!s2.Run())
return false;
- sql::Statement s3(db_->GetUniqueStatement(
- "DELETE FROM autofill_profile_emails"));
+ sql::Statement s3(
+ db_->GetUniqueStatement("DELETE FROM autofill_profile_emails"));
if (!s3.Run())
return false;
- sql::Statement s4(db_->GetUniqueStatement(
- "DELETE FROM autofill_profile_phones"));
+ sql::Statement s4(
+ db_->GetUniqueStatement("DELETE FROM autofill_profile_phones"));
return s4.Run();
}
@@ -1190,8 +1172,8 @@ std::unique_ptr<CreditCard> AutofillTable::GetCreditCard(
DCHECK(base::IsValidGUID(guid));
sql::Statement s(db_->GetUniqueStatement(
"SELECT guid, name_on_card, expiration_month, expiration_year, "
- "card_number_encrypted, use_count, use_date, date_modified, "
- "origin, billing_address_id "
+ "card_number_encrypted, use_count, use_date, date_modified, "
+ "origin, billing_address_id "
"FROM credit_cards "
"WHERE guid = ?"));
s.BindString(0, guid);
@@ -1208,9 +1190,7 @@ bool AutofillTable::GetCreditCards(
credit_cards->clear();
sql::Statement s(db_->GetUniqueStatement(
- "SELECT guid "
- "FROM credit_cards "
- "ORDER BY date_modified DESC, guid"));
+ "SELECT guid FROM credit_cards ORDER BY date_modified DESC, guid"));
while (s.Step()) {
std::string guid = s.ColumnString(0);
@@ -1234,7 +1214,7 @@ bool AutofillTable::GetServerCreditCards(
"masked.id," // 2
"metadata.use_count," // 3
"metadata.use_date," // 4
- "type," // 5
+ "network," // 5
"status," // 6
"name_on_card," // 7
"exp_month," // 8
@@ -1251,30 +1231,29 @@ bool AutofillTable::GetServerCreditCards(
base::string16 full_card_number =
UnencryptedCardFromColumn(s, index++, *autofill_table_encryptor_);
base::string16 last_four = s.ColumnString16(index++);
- CreditCard::RecordType record_type = full_card_number.empty() ?
- CreditCard::MASKED_SERVER_CARD :
- CreditCard::FULL_SERVER_CARD;
+ CreditCard::RecordType record_type = full_card_number.empty()
+ ? CreditCard::MASKED_SERVER_CARD
+ : CreditCard::FULL_SERVER_CARD;
std::string server_id = s.ColumnString(index++);
-
std::unique_ptr<CreditCard> card =
base::MakeUnique<CreditCard>(record_type, server_id);
- card->SetRawInfo(
- CREDIT_CARD_NUMBER,
- record_type == CreditCard::MASKED_SERVER_CARD ? last_four
- : full_card_number);
+ card->SetRawInfo(CREDIT_CARD_NUMBER,
+ record_type == CreditCard::MASKED_SERVER_CARD
+ ? last_four
+ : full_card_number);
card->set_use_count(s.ColumnInt64(index++));
- card->set_use_date(Time::FromInternalValue(s.ColumnInt64(index++)));
+ card->set_use_date(base::Time::FromInternalValue(s.ColumnInt64(index++)));
// Modification date is not tracked for server cards. Explicitly set it here
// to override the default value of AutofillClock::Now().
- card->set_modification_date(Time());
+ card->set_modification_date(base::Time());
- std::string card_type = s.ColumnString(index++);
+ std::string card_network = s.ColumnString(index++);
if (record_type == CreditCard::MASKED_SERVER_CARD) {
- // The type must be set after setting the number to override the
- // autodetected type.
- card->SetTypeForMaskedCard(card_type.c_str());
+ // The issuer network must be set after setting the number to override the
+ // autodetected issuer network.
+ card->SetNetworkForMaskedCard(card_network.c_str());
} else {
- DCHECK_EQ(CreditCard::GetCreditCardType(full_card_number), card_type);
+ DCHECK_EQ(CreditCard::GetCardNetwork(full_card_number), card_network);
}
card->SetServerStatus(ServerStatusStringToEnum(s.ColumnString(index++)));
@@ -1284,25 +1263,16 @@ bool AutofillTable::GetServerCreditCards(
card->set_billing_address_id(s.ColumnString(index++));
credit_cards->push_back(std::move(card));
}
-
return s.Succeeded();
}
-void AutofillTable::SetServerCreditCards(
+void AutofillTable::AddMaskedCreditCards(
const std::vector<CreditCard>& credit_cards) {
- sql::Transaction transaction(db_);
- if (!transaction.Begin())
- return;
-
- // Delete all old values.
- sql::Statement masked_delete(db_->GetUniqueStatement(
- "DELETE FROM masked_credit_cards"));
- masked_delete.Run();
-
+ DCHECK_GT(db_->transaction_nesting(), 0);
sql::Statement masked_insert(
db_->GetUniqueStatement("INSERT INTO masked_credit_cards("
"id," // 0
- "type," // 1
+ "network," // 1
"status," // 2
"name_on_card," // 3
"last_four," // 4
@@ -1311,9 +1281,8 @@ void AutofillTable::SetServerCreditCards(
"VALUES (?,?,?,?,?,?,?)"));
for (const CreditCard& card : credit_cards) {
DCHECK_EQ(CreditCard::MASKED_SERVER_CARD, card.record_type());
-
masked_insert.BindString(0, card.server_id());
- masked_insert.BindString(1, card.type());
+ masked_insert.BindString(1, card.network());
masked_insert.BindString(2,
ServerStatusEnumToString(card.GetServerStatus()));
masked_insert.BindString16(3, card.GetRawInfo(CREDIT_CARD_NAME_FULL));
@@ -1328,32 +1297,71 @@ void AutofillTable::SetServerCreditCards(
// Save the use count and use date of the card.
UpdateServerCardMetadata(card);
}
+}
+
+void AutofillTable::SetServerCreditCards(
+ const std::vector<CreditCard>& credit_cards) {
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return;
+
+ // Delete all old values.
+ sql::Statement masked_delete(
+ db_->GetUniqueStatement("DELETE FROM masked_credit_cards"));
+ masked_delete.Run();
+
+ AddMaskedCreditCards(credit_cards);
// Delete all items in the unmasked table that aren't in the new set.
sql::Statement unmasked_delete(db_->GetUniqueStatement(
"DELETE FROM unmasked_credit_cards WHERE id NOT IN "
- "(SELECT id FROM masked_credit_cards)"));
+ "(SELECT id FROM masked_credit_cards)"));
unmasked_delete.Run();
// Do the same for metadata.
sql::Statement metadata_delete(db_->GetUniqueStatement(
"DELETE FROM server_card_metadata WHERE id NOT IN "
- "(SELECT id FROM masked_credit_cards)"));
+ "(SELECT id FROM masked_credit_cards)"));
metadata_delete.Run();
transaction.Commit();
}
-bool AutofillTable::UnmaskServerCreditCard(const CreditCard& masked,
- const base::string16& full_number) {
+bool AutofillTable::AddFullServerCreditCard(const CreditCard& credit_card) {
+ DCHECK_EQ(CreditCard::FULL_SERVER_CARD, credit_card.record_type());
+ DCHECK(!credit_card.number().empty());
+ DCHECK(!credit_card.server_id().empty());
+
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
// Make sure there aren't duplicates for this card.
- MaskServerCreditCard(masked.server_id());
+ DeleteFromUnmaskedCreditCards(credit_card.server_id());
+ DeleteFromMaskedCreditCards(credit_card.server_id());
+
+ CreditCard masked(credit_card);
+ masked.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ masked.SetNumber(credit_card.LastFourDigits());
+ masked.RecordAndLogUse();
+ DCHECK(!masked.network().empty());
+ AddMaskedCreditCards({masked});
+
+ AddUnmaskedCreditCard(credit_card.server_id(), credit_card.number());
+
+ transaction.Commit();
+
+ return db_->GetLastChangeCount() > 0;
+}
+
+void AutofillTable::AddUnmaskedCreditCard(const std::string& id,
+ const base::string16& full_number) {
sql::Statement s(db_->GetUniqueStatement(
"INSERT INTO unmasked_credit_cards("
"id,"
"card_number_encrypted,"
"unmask_date)"
"VALUES (?,?,?)"));
- s.BindString(0, masked.server_id());
+ s.BindString(0, id);
std::string encrypted_data;
autofill_table_encryptor_->EncryptString16(full_number, &encrypted_data);
@@ -1362,6 +1370,18 @@ bool AutofillTable::UnmaskServerCreditCard(const CreditCard& masked,
s.BindInt64(2, AutofillClock::Now().ToInternalValue()); // unmask_date
s.Run();
+}
+
+bool AutofillTable::UnmaskServerCreditCard(const CreditCard& masked,
+ const base::string16& full_number) {
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
+ // Make sure there aren't duplicates for this card.
+ DeleteFromUnmaskedCreditCards(masked.server_id());
+
+ AddUnmaskedCreditCard(masked.server_id(), full_number);
CreditCard unmasked = masked;
unmasked.set_record_type(CreditCard::FULL_SERVER_CARD);
@@ -1369,10 +1389,20 @@ bool AutofillTable::UnmaskServerCreditCard(const CreditCard& masked,
unmasked.RecordAndLogUse();
UpdateServerCardMetadata(unmasked);
+ transaction.Commit();
+
return db_->GetLastChangeCount() > 0;
}
-bool AutofillTable::MaskServerCreditCard(const std::string& id) {
+bool AutofillTable::DeleteFromMaskedCreditCards(const std::string& id) {
+ sql::Statement s(
+ db_->GetUniqueStatement("DELETE FROM masked_credit_cards WHERE id = ?"));
+ s.BindString(0, id);
+ s.Run();
+ return db_->GetLastChangeCount() > 0;
+}
+
+bool AutofillTable::DeleteFromUnmaskedCreditCards(const std::string& id) {
sql::Statement s(db_->GetUniqueStatement(
"DELETE FROM unmasked_credit_cards WHERE id = ?"));
s.BindString(0, id);
@@ -1380,14 +1410,15 @@ bool AutofillTable::MaskServerCreditCard(const std::string& id) {
return db_->GetLastChangeCount() > 0;
}
+bool AutofillTable::MaskServerCreditCard(const std::string& id) {
+ return DeleteFromUnmaskedCreditCards(id);
+}
+
bool AutofillTable::UpdateServerCardMetadata(const CreditCard& credit_card) {
DCHECK_NE(CreditCard::LOCAL_CARD, credit_card.record_type());
- sql::Transaction transaction(db_);
- if (!transaction.Begin())
- return false;
- sql::Statement remove(db_->GetUniqueStatement(
- "DELETE FROM server_card_metadata WHERE id = ?"));
+ sql::Statement remove(
+ db_->GetUniqueStatement("DELETE FROM server_card_metadata WHERE id = ?"));
remove.BindString(0, credit_card.server_id());
remove.Run();
@@ -1401,8 +1432,6 @@ bool AutofillTable::UpdateServerCardMetadata(const CreditCard& credit_card) {
s.BindString(3, credit_card.server_id());
s.Run();
- transaction.Commit();
-
return db_->GetLastChangeCount() > 0;
}
@@ -1441,28 +1470,28 @@ bool AutofillTable::ClearAllServerData() {
if (!transaction.Begin())
return false; // Some error, nothing was changed.
- sql::Statement masked(db_->GetUniqueStatement(
- "DELETE FROM masked_credit_cards"));
+ sql::Statement masked(
+ db_->GetUniqueStatement("DELETE FROM masked_credit_cards"));
masked.Run();
bool changed = db_->GetLastChangeCount() > 0;
- sql::Statement unmasked(db_->GetUniqueStatement(
- "DELETE FROM unmasked_credit_cards"));
+ sql::Statement unmasked(
+ db_->GetUniqueStatement("DELETE FROM unmasked_credit_cards"));
unmasked.Run();
changed |= db_->GetLastChangeCount() > 0;
- sql::Statement addresses(db_->GetUniqueStatement(
- "DELETE FROM server_addresses"));
+ sql::Statement addresses(
+ db_->GetUniqueStatement("DELETE FROM server_addresses"));
addresses.Run();
changed |= db_->GetLastChangeCount() > 0;
- sql::Statement card_metadata(db_->GetUniqueStatement(
- "DELETE FROM server_card_metadata"));
+ sql::Statement card_metadata(
+ db_->GetUniqueStatement("DELETE FROM server_card_metadata"));
card_metadata.Run();
changed |= db_->GetLastChangeCount() > 0;
- sql::Statement address_metadata(db_->GetUniqueStatement(
- "DELETE FROM server_address_metadata"));
+ sql::Statement address_metadata(
+ db_->GetUniqueStatement("DELETE FROM server_address_metadata"));
address_metadata.Run();
changed |= db_->GetLastChangeCount() > 0;
@@ -1483,8 +1512,8 @@ bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) {
sql::Statement s(db_->GetUniqueStatement(
"UPDATE credit_cards "
"SET guid=?, name_on_card=?, expiration_month=?,"
- "expiration_year=?, card_number_encrypted=?, use_count=?, use_date=?,"
- "date_modified=?, origin=?, billing_address_id=?"
+ "expiration_year=?, card_number_encrypted=?, use_count=?, use_date=?,"
+ "date_modified=?, origin=?, billing_address_id=?"
"WHERE guid=?1"));
BindCreditCardToStatement(credit_card,
update_modification_date
@@ -1499,16 +1528,16 @@ bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) {
bool AutofillTable::RemoveCreditCard(const std::string& guid) {
DCHECK(base::IsValidGUID(guid));
- sql::Statement s(db_->GetUniqueStatement(
- "DELETE FROM credit_cards WHERE guid = ?"));
+ sql::Statement s(
+ db_->GetUniqueStatement("DELETE FROM credit_cards WHERE guid = ?"));
s.BindString(0, guid);
return s.Run();
}
bool AutofillTable::RemoveAutofillDataModifiedBetween(
- const Time& delete_begin,
- const Time& delete_end,
+ const base::Time& delete_begin,
+ const base::Time& delete_end,
std::vector<std::string>* profile_guids,
std::vector<std::string>* credit_card_guids) {
DCHECK(delete_end.is_null() || delete_begin < delete_end);
@@ -1566,17 +1595,17 @@ bool AutofillTable::RemoveAutofillDataModifiedBetween(
return false;
// Remove unmasked credit cards in the time range.
- sql::Statement s_unmasked_cards(db_->GetUniqueStatement(
- "DELETE FROM unmasked_credit_cards "
- "WHERE unmask_date >= ? AND unmask_date < ?"));
+ sql::Statement s_unmasked_cards(
+ db_->GetUniqueStatement("DELETE FROM unmasked_credit_cards "
+ "WHERE unmask_date >= ? AND unmask_date < ?"));
s_unmasked_cards.BindInt64(0, delete_begin.ToInternalValue());
s_unmasked_cards.BindInt64(1, delete_end.ToInternalValue());
return s_unmasked_cards.Run();
}
bool AutofillTable::RemoveOriginURLsModifiedBetween(
- const Time& delete_begin,
- const Time& delete_end,
+ const base::Time& delete_begin,
+ const base::Time& delete_end,
std::vector<std::unique_ptr<AutofillProfile>>* profiles) {
DCHECK(delete_end.is_null() || delete_begin < delete_end);
@@ -1648,9 +1677,8 @@ bool AutofillTable::GetAutofillProfilesInTrash(
std::vector<std::string>* guids) {
guids->clear();
- sql::Statement s(db_->GetUniqueStatement(
- "SELECT guid "
- "FROM autofill_profiles_trash"));
+ sql::Statement s(
+ db_->GetUniqueStatement("SELECT guid FROM autofill_profiles_trash"));
while (s.Step()) {
std::string guid = s.ColumnString(0);
@@ -1661,36 +1689,30 @@ bool AutofillTable::GetAutofillProfilesInTrash(
}
bool AutofillTable::EmptyAutofillProfilesTrash() {
- sql::Statement s(db_->GetUniqueStatement(
- "DELETE FROM autofill_profiles_trash"));
+ sql::Statement s(
+ db_->GetUniqueStatement("DELETE FROM autofill_profiles_trash"));
return s.Run();
}
-
bool AutofillTable::AddAutofillGUIDToTrash(const std::string& guid) {
sql::Statement s(db_->GetUniqueStatement(
- "INSERT INTO autofill_profiles_trash"
- " (guid) "
- "VALUES (?)"));
+ "INSERT INTO autofill_profiles_trash (guid) VALUES (?)"));
s.BindString(0, guid);
return s.Run();
}
bool AutofillTable::IsAutofillProfilesTrashEmpty() {
- sql::Statement s(db_->GetUniqueStatement(
- "SELECT guid "
- "FROM autofill_profiles_trash"));
+ sql::Statement s(
+ db_->GetUniqueStatement("SELECT guid FROM autofill_profiles_trash"));
return !s.Step();
}
bool AutofillTable::IsAutofillGUIDInTrash(const std::string& guid) {
sql::Statement s(db_->GetUniqueStatement(
- "SELECT guid "
- "FROM autofill_profiles_trash "
- "WHERE guid = ?"));
+ "SELECT guid FROM autofill_profiles_trash WHERE guid = ?"));
s.BindString(0, guid);
return s.Step();
@@ -1823,8 +1845,8 @@ bool AutofillTable::InitMainTable() {
!db_->Execute("CREATE INDEX autofill_name ON autofill (name)") ||
!db_->Execute("CREATE INDEX autofill_name_value_lower ON "
"autofill (name, value_lower)")) {
- NOTREACHED();
- return false;
+ NOTREACHED();
+ return false;
}
}
return true;
@@ -1931,7 +1953,7 @@ bool AutofillTable::InitMaskedCreditCardsTable() {
"id VARCHAR,"
"status VARCHAR,"
"name_on_card VARCHAR,"
- "type VARCHAR,"
+ "network VARCHAR,"
"last_four VARCHAR,"
"exp_month INTEGER DEFAULT 0,"
"exp_year INTEGER DEFAULT 0)")) {
@@ -1986,7 +2008,7 @@ bool AutofillTable::InitServerAddressesTable() {
"postal_code VARCHAR,"
"sorting_code VARCHAR,"
"country_code VARCHAR,"
- "language_code VARCHAR, " // Space required.
+ "language_code VARCHAR, " // Space required.
"recipient_name VARCHAR, " // Ditto.
"phone_number VARCHAR)")) {
NOTREACHED();
@@ -2194,18 +2216,17 @@ bool AutofillTable::MigrateToVersion55MergeAutofillDatesTable() {
return false;
}
-
return transaction.Commit();
}
bool AutofillTable::MigrateToVersion56AddProfileLanguageCodeForFormatting() {
- return db_->Execute("ALTER TABLE autofill_profiles "
- "ADD COLUMN language_code VARCHAR");
+ return db_->Execute(
+ "ALTER TABLE autofill_profiles ADD COLUMN language_code VARCHAR");
}
bool AutofillTable::MigrateToVersion57AddFullNameField() {
- return db_->Execute("ALTER TABLE autofill_profile_names "
- "ADD COLUMN full_name VARCHAR");
+ return db_->Execute(
+ "ALTER TABLE autofill_profile_names ADD COLUMN full_name VARCHAR");
}
bool AutofillTable::MigrateToVersion60AddServerCards() {
@@ -2369,25 +2390,25 @@ bool AutofillTable::MigrateToVersion65AddServerMetadataTables() {
// Get existing server addresses and generate IDs for them.
sql::Statement s(db_->GetUniqueStatement(
"SELECT "
- "id,"
- "recipient_name,"
- "company_name,"
- "street_address,"
- "address_1," // ADDRESS_HOME_STATE
- "address_2," // ADDRESS_HOME_CITY
- "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
- "address_4," // Not supported in AutofillProfile yet.
- "postal_code," // ADDRESS_HOME_ZIP
- "sorting_code," // ADDRESS_HOME_SORTING_CODE
- "country_code," // ADDRESS_HOME_COUNTRY
- "phone_number," // PHONE_HOME_WHOLE_NUMBER
- "language_code "
+ "id,"
+ "recipient_name,"
+ "company_name,"
+ "street_address,"
+ "address_1," // ADDRESS_HOME_STATE
+ "address_2," // ADDRESS_HOME_CITY
+ "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
+ "address_4," // Not supported in AutofillProfile yet.
+ "postal_code," // ADDRESS_HOME_ZIP
+ "sorting_code," // ADDRESS_HOME_SORTING_CODE
+ "country_code," // ADDRESS_HOME_COUNTRY
+ "phone_number," // PHONE_HOME_WHOLE_NUMBER
+ "language_code "
"FROM server_addresses addresses"));
std::vector<AutofillProfile> profiles;
while (s.Step()) {
int index = 0;
- AutofillProfile profile(
- AutofillProfile::SERVER_PROFILE, s.ColumnString(index++));
+ AutofillProfile profile(AutofillProfile::SERVER_PROFILE,
+ s.ColumnString(index++));
base::string16 recipient_name = s.ColumnString16(index++);
profile.SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
@@ -2411,25 +2432,25 @@ bool AutofillTable::MigrateToVersion65AddServerMetadataTables() {
}
// Reinsert with the generated IDs.
- sql::Statement delete_old(db_->GetUniqueStatement(
- "DELETE FROM server_addresses"));
+ sql::Statement delete_old(
+ db_->GetUniqueStatement("DELETE FROM server_addresses"));
delete_old.Run();
sql::Statement insert(db_->GetUniqueStatement(
"INSERT INTO server_addresses("
- "id,"
- "recipient_name,"
- "company_name,"
- "street_address,"
- "address_1," // ADDRESS_HOME_STATE
- "address_2," // ADDRESS_HOME_CITY
- "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
- "address_4," // Not supported in AutofillProfile yet.
- "postal_code," // ADDRESS_HOME_ZIP
- "sorting_code," // ADDRESS_HOME_SORTING_CODE
- "country_code," // ADDRESS_HOME_COUNTRY
- "phone_number," // PHONE_HOME_WHOLE_NUMBER
- "language_code) "
+ "id,"
+ "recipient_name,"
+ "company_name,"
+ "street_address,"
+ "address_1," // ADDRESS_HOME_STATE
+ "address_2," // ADDRESS_HOME_CITY
+ "address_3," // ADDRESS_HOME_DEPENDENT_LOCALITY
+ "address_4," // Not supported in AutofillProfile yet.
+ "postal_code," // ADDRESS_HOME_ZIP
+ "sorting_code," // ADDRESS_HOME_SORTING_CODE
+ "country_code," // ADDRESS_HOME_COUNTRY
+ "phone_number," // PHONE_HOME_WHOLE_NUMBER
+ "language_code) "
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"));
for (const AutofillProfile& profile : profiles) {
int index = 0;
@@ -2510,11 +2531,15 @@ bool AutofillTable::
return false;
}
+ if (db_->DoesTableExist("masked_credit_cards_temp") &&
+ !db_->Execute("DROP TABLE masked_credit_cards_temp")) {
+ return false;
+ }
+
// Remove the billing_address_id column from the masked_credit_cards table.
// Create a temporary table that is a copy of masked_credit_cards but without
// the billing_address_id column.
- if (db_->DoesTableExist("masked_credit_cards_temp") ||
- !db_->Execute("CREATE TABLE masked_credit_cards_temp ("
+ if (!db_->Execute("CREATE TABLE masked_credit_cards_temp ("
"id VARCHAR,"
"status VARCHAR,"
"name_on_card VARCHAR,"
@@ -2542,4 +2567,36 @@ bool AutofillTable::
return transaction.Commit();
}
+bool AutofillTable::MigrateToVersion72RenameCardTypeToIssuerNetwork() {
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
+ if (db_->DoesTableExist("masked_credit_cards_temp") &&
+ !db_->Execute("DROP TABLE masked_credit_cards_temp")) {
+ return false;
+ }
+
+ return db_->Execute(
+ "CREATE TABLE masked_credit_cards_temp ("
+ "id VARCHAR,"
+ "status VARCHAR,"
+ "name_on_card VARCHAR,"
+ "network VARCHAR,"
+ "last_four VARCHAR,"
+ "exp_month INTEGER DEFAULT 0,"
+ "exp_year INTEGER DEFAULT 0)") &&
+ db_->Execute(
+ "INSERT INTO masked_credit_cards_temp ("
+ "id, status, name_on_card, network, last_four, exp_month, exp_year"
+ ") SELECT "
+ "id, status, name_on_card, type, last_four, exp_month, exp_year"
+ " FROM masked_credit_cards") &&
+ db_->Execute("DROP TABLE masked_credit_cards") &&
+ db_->Execute(
+ "ALTER TABLE masked_credit_cards_temp "
+ "RENAME TO masked_credit_cards") &&
+ transaction.Commit();
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_table.h b/chromium/components/autofill/core/browser/webdata/autofill_table.h
index 872d127b393..161b033fe69 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table.h
@@ -16,6 +16,7 @@
#include "base/strings/string16.h"
#include "components/sync/base/model_type.h"
#include "components/sync/model/metadata_batch.h"
+#include "components/sync/model/sync_metadata_store.h"
#include "components/webdata/common/web_database_table.h"
class WebDatabase;
@@ -149,7 +150,8 @@ struct FormFieldData;
// This table contains "masked" credit card information
// about credit cards stored on the server. It consists
// of a short description and an ID, but not full payment
-// information. Writing to this table is only done by sync.
+// information. Writing to this table is done by sync and
+// on successful save of card to the server.
// When a server card is unmasked, it will stay here and
// will additionally be added in unmasked_credit_cards.
//
@@ -158,8 +160,8 @@ struct FormFieldData;
// status Server's status of this card.
// TODO(brettw) define constants for this.
// name_on_card
-// type Type of the credit card. This is one of the
-// kSyncCardType* strings.
+// network Issuer network of the card. For example, "VISA". Renamed
+// from "type" in version 72.
// last_four Last four digits of the card number. For de-duping
// with locally stored cards and generating descriptions.
// exp_month Expiration month: 1-12
@@ -167,7 +169,9 @@ struct FormFieldData;
//
// unmasked_credit_cards
// When a masked credit credit card is unmasked and the
-// full number is downloaded, it will be stored here.
+// full number is downloaded or when the full number is
+// available upon saving card to server, it will be stored
+// here.
//
// id Server ID. This can be joined with the id in the
// masked_credit_cards table to get the rest of the data.
@@ -249,7 +253,8 @@ struct FormFieldData;
//
// value The serialized ModelTypeState record.
-class AutofillTable : public WebDatabaseTable {
+class AutofillTable : public WebDatabaseTable,
+ public syncer::SyncMetadataStore {
public:
AutofillTable();
~AutofillTable() override;
@@ -326,7 +331,7 @@ class AutofillTable : public WebDatabaseTable {
// Records a single Autofill profile in the autofill_profiles table.
virtual bool AddAutofillProfile(const AutofillProfile& profile);
- // Updates the database values for the specified profile. Mulit-value aware.
+ // Updates the database values for the specified profile. Multi-value aware.
virtual bool UpdateAutofillProfile(const AutofillProfile& profile);
// Removes a row from the autofill_profiles table. |guid| is the identifier
@@ -356,6 +361,9 @@ class AutofillTable : public WebDatabaseTable {
// credit card to remove.
bool RemoveCreditCard(const std::string& guid);
+ // Adds to the masked_credit_cards and unmasked_credit_cards tables.
+ bool AddFullServerCreditCard(const CreditCard& credit_card);
+
// Retrieves a credit card with guid |guid|.
std::unique_ptr<CreditCard> GetCreditCard(const std::string& guid);
@@ -426,22 +434,16 @@ class AutofillTable : public WebDatabaseTable {
bool GetAllSyncMetadata(syncer::ModelType model_type,
syncer::MetadataBatch* metadata_batch);
- // Update the metadata row for |model_type|, keyed by |storage_key|, to
- // contain the contents of |metadata|.
+ // syncer::SyncMetadataStore implementation.
bool UpdateSyncMetadata(syncer::ModelType model_type,
const std::string& storage_key,
- const sync_pb::EntityMetadata& metadata);
-
- // Remove the metadata row of type |model_type| keyed by |storage|key|.
+ const sync_pb::EntityMetadata& metadata) override;
bool ClearSyncMetadata(syncer::ModelType model_type,
- const std::string& storage_key);
-
- // Update the stored sync state for the |model_type|.
- bool UpdateModelTypeState(syncer::ModelType model_type,
- const sync_pb::ModelTypeState& model_type_state);
-
- // Clear the stored sync state for |model_type|.
- bool ClearModelTypeState(syncer::ModelType model_type);
+ const std::string& storage_key) override;
+ bool UpdateModelTypeState(
+ syncer::ModelType model_type,
+ const sync_pb::ModelTypeState& model_type_state) override;
+ bool ClearModelTypeState(syncer::ModelType model_type) override;
// Table migration functions. NB: These do not and should not rely on other
// functions in this class. The implementation of a function such as
@@ -461,6 +463,7 @@ class AutofillTable : public WebDatabaseTable {
bool MigrateToVersion67AddMaskedCardBillingAddress();
bool MigrateToVersion70AddSyncMetadata();
bool MigrateToVersion71AddHasConvertedAndBillingAddressIdMetadata();
+ bool MigrateToVersion72RenameCardTypeToIssuerNetwork();
// Max data length saved in the table, AKA the maximum length allowed for
// form data.
@@ -531,6 +534,18 @@ class AutofillTable : public WebDatabaseTable {
// Checks if the guid is in the trash.
bool IsAutofillGUIDInTrash(const std::string& guid);
+ // Adds to |masked_credit_cards| and updates |server_card_metadata|.
+ // Must already be in a transaction.
+ void AddMaskedCreditCards(const std::vector<CreditCard>& credit_cards);
+
+ // Adds to |unmasked_credit_cards|.
+ void AddUnmaskedCreditCard(const std::string& id,
+ const base::string16& full_number);
+
+ // Deletes server credit cards by |id|. Returns true if a row was deleted.
+ bool DeleteFromMaskedCreditCards(const std::string& id);
+ bool DeleteFromUnmaskedCreditCards(const std::string& id);
+
bool InitMainTable();
bool InitCreditCardsTable();
bool InitDatesTable();
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 58439067907..193021652dd 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -1029,6 +1029,24 @@ TEST_F(AutofillTableTest, CreditCard) {
EXPECT_FALSE(db_creditcard);
}
+TEST_F(AutofillTableTest, AddFullServerCreditCard) {
+ CreditCard credit_card;
+ credit_card.set_record_type(CreditCard::FULL_SERVER_CARD);
+ credit_card.set_server_id("server_id");
+ credit_card.set_origin("https://www.example.com/");
+ credit_card.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Jack Torrance"));
+ credit_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1234567890123456"));
+ credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("04"));
+ credit_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2013"));
+
+ EXPECT_TRUE(table_->AddFullServerCreditCard(credit_card));
+
+ std::vector<std::unique_ptr<CreditCard>> outputs;
+ ASSERT_TRUE(table_->GetServerCreditCards(&outputs));
+ ASSERT_EQ(1U, outputs.size());
+ EXPECT_EQ(0, credit_card.Compare(*outputs[0]));
+}
+
TEST_F(AutofillTableTest, UpdateAutofillProfile) {
// Add a profile to the db.
AutofillProfile profile;
@@ -1609,7 +1627,7 @@ TEST_F(AutofillTableTest, SetGetServerCards) {
inputs[1].SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("12"));
inputs[1].SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("1997"));
inputs[1].SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111"));
- inputs[1].SetTypeForMaskedCard(kVisaCard);
+ inputs[1].SetNetworkForMaskedCard(kVisaCard);
inputs[1].SetServerStatus(CreditCard::EXPIRED);
test::SetServerCreditCards(table_.get(), inputs);
@@ -1645,7 +1663,7 @@ TEST_F(AutofillTableTest, MaskUnmaskServerCards) {
inputs[0].SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1"));
inputs[0].SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020"));
inputs[0].SetRawInfo(CREDIT_CARD_NUMBER, masked_number);
- inputs[0].SetTypeForMaskedCard(kVisaCard);
+ inputs[0].SetNetworkForMaskedCard(kVisaCard);
test::SetServerCreditCards(table_.get(), inputs);
// Unmask the number. The full number should be available.
@@ -1681,7 +1699,7 @@ TEST_F(AutofillTableTest, SetServerCardModify) {
masked_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1"));
masked_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020"));
masked_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111"));
- masked_card.SetTypeForMaskedCard(kVisaCard);
+ masked_card.SetNetworkForMaskedCard(kVisaCard);
std::vector<CreditCard> inputs;
inputs.push_back(masked_card);
@@ -1718,7 +1736,7 @@ TEST_F(AutofillTableTest, SetServerCardModify) {
random_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("12"));
random_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("1997"));
random_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("2222"));
- random_card.SetTypeForMaskedCard(kVisaCard);
+ random_card.SetNetworkForMaskedCard(kVisaCard);
inputs[0] = random_card;
test::SetServerCreditCards(table_.get(), inputs);
@@ -1753,7 +1771,7 @@ TEST_F(AutofillTableTest, SetServerCardUpdateUsageStatsAndBillingAddress) {
masked_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020"));
masked_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111"));
masked_card.set_billing_address_id("1");
- masked_card.SetTypeForMaskedCard(kVisaCard);
+ masked_card.SetNetworkForMaskedCard(kVisaCard);
std::vector<CreditCard> inputs;
inputs.push_back(masked_card);
@@ -1894,7 +1912,7 @@ TEST_F(AutofillTableTest, DeleteUnmaskedCard) {
masked_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1"));
masked_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2020"));
masked_card.SetRawInfo(CREDIT_CARD_NUMBER, masked_number);
- masked_card.SetTypeForMaskedCard(kVisaCard);
+ masked_card.SetNetworkForMaskedCard(kVisaCard);
std::vector<CreditCard> inputs;
inputs.push_back(masked_card);
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 021b91abd50..261f63bd6ca 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
@@ -500,8 +500,8 @@ void AutofillWalletMetadataSyncableService::CreateForWebDataServiceAndBackend(
AutofillWebDataBackend* web_data_backend,
const std::string& app_locale) {
web_data_service->GetDBUserData()->SetUserData(
- UserDataKey(),
- new AutofillWalletMetadataSyncableService(web_data_backend, app_locale));
+ UserDataKey(), base::WrapUnique(new AutofillWalletMetadataSyncableService(
+ web_data_backend, app_locale)));
}
// static
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 fc6948f1aef..54e8be78009 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
@@ -6,10 +6,11 @@
#include <stddef.h>
-#include <set>
+#include <map>
#include <utility>
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -45,6 +46,8 @@ const char* CardTypeFromWalletCardType(
return kJCBCard;
case sync_pb::WalletMaskedCreditCard::MASTER_CARD:
return kMasterCard;
+ case sync_pb::WalletMaskedCreditCard::UNIONPAY:
+ return kUnionPay;
case sync_pb::WalletMaskedCreditCard::VISA:
return kVisaCard;
@@ -73,7 +76,7 @@ CreditCard CardFromSpecifics(const sync_pb::WalletMaskedCreditCard& card) {
CreditCard result(CreditCard::MASKED_SERVER_CARD, card.id());
result.SetNumber(base::UTF8ToUTF16(card.last_four()));
result.SetServerStatus(ServerToLocalStatus(card.status()));
- result.SetTypeForMaskedCard(CardTypeFromWalletCardType(card.type()));
+ result.SetNetworkForMaskedCard(CardTypeFromWalletCardType(card.type()));
result.SetRawInfo(CREDIT_CARD_NAME_FULL,
base::UTF8ToUTF16(card.name_on_card()));
result.SetExpirationMonth(card.exp_month());
@@ -238,8 +241,8 @@ void AutofillWalletSyncableService::CreateForWebDataServiceAndBackend(
AutofillWebDataBackend* webdata_backend,
const std::string& app_locale) {
web_data_service->GetDBUserData()->SetUserData(
- UserDataKey(),
- new AutofillWalletSyncableService(webdata_backend, app_locale));
+ UserDataKey(), base::WrapUnique(new AutofillWalletSyncableService(
+ webdata_backend, app_locale)));
}
// static
@@ -359,4 +362,4 @@ syncer::SyncMergeResult AutofillWalletSyncableService::SetSyncData(
return merge_result;
}
-} // namespace autofil
+} // namespace autofill
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 ae8bae82f66..4156f6cd644 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
@@ -5,6 +5,10 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WALLET_SYNCABLE_SERVICE_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WALLET_SYNCABLE_SERVICE_H_
+#include <memory>
+#include <string>
+#include <vector>
+
#include "base/macros.h"
#include "base/supports_user_data.h"
#include "base/threading/thread_checker.h"
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata.h
index eb573874b12..07fe5002a2f 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata.h
@@ -94,6 +94,9 @@ class AutofillWebData {
// |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
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 2129da0abdd..85bc2f308de 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
@@ -329,6 +329,23 @@ WebDatabase::State AutofillWebDataBackendImpl::RemoveCreditCard(
return WebDatabase::COMMIT_NEEDED;
}
+WebDatabase::State AutofillWebDataBackendImpl::AddFullServerCreditCard(
+ const CreditCard& credit_card,
+ WebDatabase* db) {
+ DCHECK(db_thread_->BelongsToCurrentThread());
+ if (!AutofillTable::FromWebDatabase(db)->AddFullServerCreditCard(
+ credit_card)) {
+ NOTREACHED();
+ return WebDatabase::COMMIT_NOT_NEEDED;
+ }
+
+ for (auto& db_observer : db_observer_list_) {
+ db_observer.CreditCardChanged(CreditCardChange(
+ CreditCardChange::ADD, credit_card.guid(), &credit_card));
+ }
+ return WebDatabase::COMMIT_NEEDED;
+}
+
std::unique_ptr<WDTypedResult> AutofillWebDataBackendImpl::GetCreditCards(
WebDatabase* db) {
DCHECK(db_thread_->BelongsToCurrentThread());
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 9badefeb70c..4a995a4689c 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
@@ -140,6 +140,10 @@ class AutofillWebDataBackendImpl
WebDatabase::State RemoveCreditCard(const std::string& guid,
WebDatabase* db);
+ // Adds a full server credit card to the web database.
+ WebDatabase::State AddFullServerCreditCard(const CreditCard& credit_card,
+ WebDatabase* db);
+
// Returns a vector of local/server credit cards from the web database.
std::unique_ptr<WDTypedResult> GetCreditCards(WebDatabase* db);
std::unique_ptr<WDTypedResult> GetServerCreditCards(WebDatabase* db);
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 d8d072f0d43..dcb9c831216 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc
@@ -174,6 +174,13 @@ void AutofillWebDataService::RemoveCreditCard(const std::string& guid) {
autofill_backend_, guid));
}
+void AutofillWebDataService::AddFullServerCreditCard(
+ const CreditCard& credit_card) {
+ wdbs_->ScheduleDBTask(
+ FROM_HERE, Bind(&AutofillWebDataBackendImpl::AddFullServerCreditCard,
+ autofill_backend_, credit_card));
+}
+
WebDataServiceBase::Handle AutofillWebDataService::GetCreditCards(
WebDataServiceConsumer* consumer) {
return wdbs_->ScheduleDBTaskWithResult(FROM_HERE,
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 dfc35afca5f..810af1b7dd7 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h
@@ -85,6 +85,7 @@ class AutofillWebDataService : public AutofillWebData,
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;
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 349e5a13cb0..f0abd6f94fa 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
@@ -12,12 +12,14 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -92,7 +94,10 @@ class MockAutofillWebDataServiceObserver
class WebDataServiceTest : public testing::Test {
public:
- WebDataServiceTest() : db_thread_("DBThread") {}
+ WebDataServiceTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ db_thread_("DBThread") {}
protected:
void SetUp() override {
@@ -134,7 +139,7 @@ class WebDataServiceTest : public testing::Test {
done.Wait();
}
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
base::Thread db_thread_;
base::FilePath profile_dir_;
scoped_refptr<AutofillWebDataService> wds_;
diff --git a/chromium/components/autofill/core/common/BUILD.gn b/chromium/components/autofill/core/common/BUILD.gn
index f3b320f0827..e58160d0360 100644
--- a/chromium/components/autofill/core/common/BUILD.gn
+++ b/chromium/components/autofill/core/common/BUILD.gn
@@ -14,6 +14,8 @@ static_library("common") {
"autofill_l10n_util.h",
"autofill_pref_names.cc",
"autofill_pref_names.h",
+ "autofill_regex_constants.cc",
+ "autofill_regex_constants.h",
"autofill_regexes.cc",
"autofill_regexes.h",
"autofill_switches.cc",
@@ -46,6 +48,7 @@ static_library("common") {
deps = [
"//base",
"//base:i18n",
+ "//components/variations",
"//third_party/re2",
"//url",
]
@@ -74,7 +77,6 @@ source_set("unit_tests") {
"//base",
"//base:i18n",
"//base/test:test_support",
- "//components/autofill/core/browser",
"//testing/gmock",
"//testing/gtest",
"//url",
diff --git a/chromium/components/autofill/core/common/autofill_pref_names.cc b/chromium/components/autofill/core/common/autofill_pref_names.cc
index 1dc5b59116d..4f3b11dc6cf 100644
--- a/chromium/components/autofill/core/common/autofill_pref_names.cc
+++ b/chromium/components/autofill/core/common/autofill_pref_names.cc
@@ -26,10 +26,17 @@ const char kAutofillWalletImportEnabled[] = "autofill.wallet_import_enabled";
// was run. This routine will be run once per version.
const char kAutofillLastVersionDeduped[] = "autofill.last_version_deduped";
-// Boolean that allows the "Don't ask again for this card" checkbox to be
-// sticky.
+// Boolean that is set to the last choice user made when prompted for saving an
+// unmasked server card locally.
const char kAutofillWalletImportStorageCheckboxState[] =
"autofill.wallet_import_storage_checkbox_state";
+// Integer that is set to the last choice user made when prompted for saving a
+// credit card. The prompt is for user's consent in saving the card in the
+// server for signed in users and saving the card locally for non signed-in
+// users.
+const char kAutofillAcceptSaveCreditCardPromptState[] =
+ "autofill.accept_save_credit_card_prompt_state";
+
} // namespace prefs
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/autofill_pref_names.h b/chromium/components/autofill/core/common/autofill_pref_names.h
index cab272d6cb6..e18a77abdb8 100644
--- a/chromium/components/autofill/core/common/autofill_pref_names.h
+++ b/chromium/components/autofill/core/common/autofill_pref_names.h
@@ -11,6 +11,7 @@ namespace prefs {
// Alphabetical list of preference names specific to the Autofill
// component. Keep alphabetized, and document each in the .cc file.
+extern const char kAutofillAcceptSaveCreditCardPromptState[];
extern const char kAutofillCreditCardSigninPromoImpressionCount[];
extern const char kAutofillEnabled[];
extern const char kAutofillProfileUseDatesFixed[];
@@ -18,6 +19,15 @@ extern const char kAutofillLastVersionDeduped[];
extern const char kAutofillWalletImportEnabled[];
extern const char kAutofillWalletImportStorageCheckboxState[];
+// Possible values for previous user decision when we displayed a save credit
+// card prompt.
+enum PreviousSaveCreditCardPromptUserDecision {
+ PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_NONE,
+ PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_ACCEPTED,
+ PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_DENIED,
+ NUM_PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISIONS
+};
+
} // namespace prefs
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_regex_constants.cc b/chromium/components/autofill/core/common/autofill_regex_constants.cc
index 57b961df461..47c9883b857 100644
--- a/chromium/components/autofill/core/browser/autofill_regex_constants.cc
+++ b/chromium/components/autofill/core/common/autofill_regex_constants.cc
@@ -6,7 +6,7 @@
// different compilers, we use a script to convert the UTF8 strings into
// numeric literals (\x##).
-#include "components/autofill/core/browser/autofill_regex_constants.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
namespace autofill {
@@ -16,110 +16,108 @@ namespace autofill {
const char kAttentionIgnoredRe[] = "attention|attn";
const char kRegionIgnoredRe[] =
"province|region|other"
- "|provincia" // es
+ "|provincia" // es
"|bairro|suburb"; // pt-BR, pt-PT
const char kAddressNameIgnoredRe[] = "address.*nickname|address.*label";
const char kCompanyRe[] =
"company|business|organization|organisation"
- "|firma|firmenname" // de-DE
- "|empresa" // es
- "|societe|société" // fr-FR
- "|ragione.?sociale" // it-IT
- "|会社" // ja-JP
+ "|firma|firmenname" // de-DE
+ "|empresa" // es
+ "|societe|société" // fr-FR
+ "|ragione.?sociale" // it-IT
+ "|会社" // ja-JP
"|название.?компании" // ru
- "|å•ä½|å…¬å¸" // zh-CN
- "|회사|ì§ìž¥"; // ko-KR
+ "|å•ä½|å…¬å¸" // zh-CN
+ "|회사|ì§ìž¥"; // ko-KR
const char kAddressLine1Re[] =
"^address$|address[_-]?line(one)?|address1|addr1|street"
"|(?:shipping|billing)address$"
"|strasse|straße|hausnummer|housenumber" // de-DE
- "|house.?name" // en-GB
- "|direccion|dirección" // es
- "|adresse" // fr-FR
- "|indirizzo" // it-IT
- "|^ä½æ‰€$|ä½æ‰€1" // ja-JP
- "|morada|endereço" // pt-BR, pt-PT
- "|ÐдреÑ" // ru
- "|地å€" // zh-CN
- "|^주소.?$|주소.?1"; // ko-KR
+ "|house.?name" // en-GB
+ "|direccion|dirección" // es
+ "|adresse" // fr-FR
+ "|indirizzo" // it-IT
+ "|^ä½æ‰€$|ä½æ‰€1" // ja-JP
+ "|morada|endereço" // pt-BR, pt-PT
+ "|ÐдреÑ" // ru
+ "|地å€" // zh-CN
+ "|^주소.?$|주소.?1"; // ko-KR
const char kAddressLine1LabelRe[] =
"address"
- "|adresse" // fr-FR
+ "|adresse" // fr-FR
"|indirizzo" // it-IT
- "|ä½æ‰€" // ja-JP
- "|地å€" // zh-CN
- "|주소"; // ko-KR
+ "|ä½æ‰€" // ja-JP
+ "|地å€" // zh-CN
+ "|주소"; // ko-KR
const char kAddressLine2Re[] =
"address[_-]?line(2|two)|address2|addr2|street|suite|unit"
- "|adresszusatz|ergänzende.?angaben" // de-DE
- "|direccion2|colonia|adicional" // es
+ "|adresszusatz|ergänzende.?angaben" // de-DE
+ "|direccion2|colonia|adicional" // es
"|addresssuppl|complementnom|appartement" // fr-FR
- "|indirizzo2" // it-IT
- "|ä½æ‰€2" // ja-JP
- "|complemento|addrcomplement" // pt-BR, pt-PT
- "|Улица" // ru
- "|地å€2" // zh-CN
- "|주소.?2"; // ko-KR
+ "|indirizzo2" // it-IT
+ "|ä½æ‰€2" // ja-JP
+ "|complemento|addrcomplement" // pt-BR, pt-PT
+ "|Улица" // ru
+ "|地å€2" // zh-CN
+ "|주소.?2"; // ko-KR
const char kAddressLine2LabelRe[] =
"address|line"
- "|adresse" // fr-FR
+ "|adresse" // fr-FR
"|indirizzo" // it-IT
- "|地å€" // zh-CN
- "|주소"; // ko-KR
+ "|地å€" // zh-CN
+ "|주소"; // ko-KR
const char kAddressLinesExtraRe[] =
"address.*line[3-9]|address[3-9]|addr[3-9]|street|line[3-9]"
- "|municipio" // es
+ "|municipio" // es
"|batiment|residence" // fr-FR
- "|indirizzo[3-9]"; // it-IT
-const char kAddressLookupRe[] =
- "lookup";
+ "|indirizzo[3-9]"; // it-IT
+const char kAddressLookupRe[] = "lookup";
const char kCountryRe[] =
"country|countries"
- "|país|pais" // es
- "|国" // ja-JP
- "|国家" // zh-CN
+ "|país|pais" // es
+ "|国" // ja-JP
+ "|国家" // zh-CN
"|êµ­ê°€|나ë¼"; // ko-KR
-const char kCountryLocationRe[] =
- "location";
+const char kCountryLocationRe[] = "location";
const char kZipCodeRe[] =
"zip|postal|post.*code|pcode"
- "|pin.?code" // en-IN
- "|postleitzahl" // de-DE
- "|\\bcp\\b" // es
- "|\\bcdp\\b" // fr-FR
- "|\\bcap\\b" // it-IT
- "|郵便番å·" // ja-JP
+ "|pin.?code" // en-IN
+ "|postleitzahl" // de-DE
+ "|\\bcp\\b" // es
+ "|\\bcdp\\b" // fr-FR
+ "|\\bcap\\b" // it-IT
+ "|郵便番å·" // ja-JP
"|codigo|codpos|\\bcep\\b" // pt-BR, pt-PT
- "|Почтовый.?ИндекÑ" // ru
- "|邮政编ç |邮编" // zh-CN
- "|郵éžå€è™Ÿ" // zh-TW
- "|우편.?번호"; // ko-KR
+ "|Почтовый.?ИндекÑ" // ru
+ "|邮政编ç |邮编" // zh-CN
+ "|郵éžå€è™Ÿ" // zh-TW
+ "|우편.?번호"; // ko-KR
const char kZip4Re[] =
"zip|^-$|post2"
"|codpos2"; // pt-BR, pt-PT
const char kCityRe[] =
"city|town"
- "|\\bort\\b|stadt" // de-DE
- "|suburb" // en-AU
+ "|\\bort\\b|stadt" // de-DE
+ "|suburb" // en-AU
"|ciudad|provincia|localidad|poblacion" // es
- "|ville|commune" // fr-FR
- "|localita" // it-IT
- "|市区町æ‘" // ja-JP
- "|cidade" // pt-BR, pt-PT
- "|Город" // ru
- "|市" // zh-CN
- "|分å€" // zh-TW
- "|^ì‹œ[^ë„·・]|ì‹œ[·・]?êµ°[·・]?구"; // ko-KR
+ "|ville|commune" // fr-FR
+ "|localita" // it-IT
+ "|市区町æ‘" // ja-JP
+ "|cidade" // pt-BR, pt-PT
+ "|Город" // ru
+ "|市" // zh-CN
+ "|分å€" // zh-TW
+ "|^ì‹œ[^ë„·・]|ì‹œ[·・]?êµ°[·・]?구"; // ko-KR
const char kStateRe[] =
"(?<!united )state|county|region|province"
- "|land" // de-DE
+ "|land" // de-DE
"|county|principality" // en-UK
- "|都é“府県" // ja-JP
- "|estado|provincia" // pt-BR, pt-PT
- "|облаÑÑ‚ÑŒ" // ru
- "|çœ" // zh-CN
- "|地å€" // zh-TW
- "|^ì‹œ[·・]?ë„"; // ko-KR
+ "|都é“府県" // ja-JP
+ "|estado|provincia" // pt-BR, pt-PT
+ "|облаÑÑ‚ÑŒ" // ru
+ "|çœ" // zh-CN
+ "|地å€" // zh-TW
+ "|^ì‹œ[·・]?ë„"; // ko-KR
/////////////////////////////////////////////////////////////////////////////
// credit_card_field.cc
@@ -135,18 +133,17 @@ const char kNameOnCardRe[] =
"|ИмÑ.*карты" // ru
"|信用å¡å¼€æˆ·å|开户å|æŒå¡äººå§“å" // zh-CN
"|æŒå¡äººå§“å"; // zh-TW
-const char kNameOnCardContextualRe[] =
- "name";
+const char kNameOnCardContextualRe[] = "name";
const char kCardNumberRe[] =
"(add)?(?:card|cc|acct).?(?:number|#|no|num|field)"
- "|nummer" // de-DE
+ "|nummer" // de-DE
"|credito|numero|número" // es
- "|numéro" // fr-FR
- "|カード番å·" // ja-JP
- "|Ðомер.*карты" // ru
- "|信用å¡å·|信用å¡å·ç " // zh-CN
- "|信用å¡å¡è™Ÿ" // zh-TW
- "|카드"; // ko-KR
+ "|numéro" // fr-FR
+ "|カード番å·" // ja-JP
+ "|Ðомер.*карты" // ru
+ "|信用å¡å·|信用å¡å·ç " // zh-CN
+ "|信用å¡å¡è™Ÿ" // zh-TW
+ "|카드"; // ko-KR
const char kCardCvcRe[] =
"verification|card.?identification|security.?code|card.?code"
"|security.?number|card.?pin|c-v-v"
@@ -168,22 +165,22 @@ const char kCardCvcRe[] =
const char kExpirationMonthRe[] =
"expir|exp.*mo|exp.*date|ccmonth|cardmonth|addmonth"
"|gueltig|gültig|monat" // de-DE
- "|fecha" // es
- "|date.*exp" // fr-FR
- "|scadenza" // it-IT
- "|有効期é™" // ja-JP
- "|validade" // pt-BR, pt-PT
- "|Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹" // ru
- "|月"; // zh-CN
+ "|fecha" // es
+ "|date.*exp" // fr-FR
+ "|scadenza" // it-IT
+ "|有効期é™" // ja-JP
+ "|validade" // pt-BR, pt-PT
+ "|Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹" // ru
+ "|月"; // zh-CN
const char kExpirationYearRe[] =
"exp|^/|(add)?year"
"|ablaufdatum|gueltig|gültig|jahr" // de-DE
- "|fecha" // es
- "|scadenza" // it-IT
- "|有効期é™" // ja-JP
- "|validade" // pt-BR, pt-PT
- "|Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹" // ru
- "|年|有效期"; // zh-CN
+ "|fecha" // es
+ "|scadenza" // it-IT
+ "|有効期é™" // ja-JP
+ "|validade" // pt-BR, pt-PT
+ "|Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹" // ru
+ "|年|有效期"; // zh-CN
// Used to match a expiration date field with a two digit year.
// The following conditions must be met:
@@ -203,78 +200,74 @@ const char kExpirationDate4DigitYearRe[] =
// Used to match expiration date fields that do not specify a year length.
const char kExpirationDateRe[] =
"expir|exp.*date|^expfield$"
- "|gueltig|gültig" // de-DE
- "|fecha" // es
- "|date.*exp" // fr-FR
- "|scadenza" // it-IT
- "|有効期é™" // ja-JP
- "|validade" // pt-BR, pt-PT
+ "|gueltig|gültig" // de-DE
+ "|fecha" // es
+ "|date.*exp" // fr-FR
+ "|scadenza" // it-IT
+ "|有効期é™" // ja-JP
+ "|validade" // pt-BR, pt-PT
"|Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹"; // ru
-const char kGiftCardRe[] =
- "gift.?card";
+const char kGiftCardRe[] = "gift.?card";
const char kDebitGiftCardRe[] =
"(?:visa|mastercard|discover|amex|american express).*gift.?card";
-const char kDebitCardRe[] =
- "debit.*card";
-
+const char kDebitCardRe[] = "debit.*card";
/////////////////////////////////////////////////////////////////////////////
// email_field.cc
/////////////////////////////////////////////////////////////////////////////
const char kEmailRe[] =
"e.?mail"
- "|courriel" // fr
- "|メールアドレス" // ja-JP
- "|Электронной.?Почты" // ru
- "|邮件|邮箱" // zh-CN
- "|電郵地å€" // zh-TW
+ "|courriel" // fr
+ "|メールアドレス" // ja-JP
+ "|Электронной.?Почты" // ru
+ "|邮件|邮箱" // zh-CN
+ "|電郵地å€" // zh-TW
"|(?:ì´ë©”ì¼|ì „ìž.?우편|[Ee]-?mail)(.?주소)?"; // ko-KR
-
/////////////////////////////////////////////////////////////////////////////
// name_field.cc
/////////////////////////////////////////////////////////////////////////////
const char kNameIgnoredRe[] =
"user.?name|user.?id|nickname|maiden name|title|prefix|suffix"
- "|vollständiger.?name" // de-DE
- "|用户å" // zh-CN
+ "|vollständiger.?name" // de-DE
+ "|用户å" // zh-CN
"|(?:사용ìž.?)?ì•„ì´ë””|사용ìž.?ID"; // ko-KR
const char kNameRe[] =
"^name|full.?name|your.?name|customer.?name|bill.?name|ship.?name"
"|name.*first.*last|firstandlastname"
"|nombre.*y.*apellidos" // es
- "|^nom" // fr-FR
- "|ãŠåå‰|æ°å" // ja-JP
- "|^nome" // pt-BR, pt-PT
- "|姓å" // zh-CN
- "|성명"; // ko-KR
+ "|^nom" // fr-FR
+ "|ãŠåå‰|æ°å" // ja-JP
+ "|^nome" // pt-BR, pt-PT
+ "|姓å" // zh-CN
+ "|성명"; // ko-KR
const char kNameSpecificRe[] =
"^name"
- "|^nom" // fr-FR
+ "|^nom" // fr-FR
"|^nome"; // pt-BR, pt-PT
const char kFirstNameRe[] =
"first.*name|initials|fname|first$|given.*name"
- "|vorname" // de-DE
- "|nombre" // es
+ "|vorname" // de-DE
+ "|nombre" // es
"|forename|prénom|prenom" // fr-FR
- "|å" // ja-JP
- "|nome" // pt-BR, pt-PT
- "|ИмÑ" // ru
- "|ì´ë¦„"; // ko-KR
+ "|å" // ja-JP
+ "|nome" // pt-BR, pt-PT
+ "|ИмÑ" // ru
+ "|ì´ë¦„"; // ko-KR
const char kMiddleInitialRe[] = "middle.*initial|m\\.i\\.|mi$|\\bmi\\b";
const char kMiddleNameRe[] =
"middle.*name|mname|middle$"
"|apellido.?materno|lastlastname"; // es
const char kLastNameRe[] =
"last.*name|lname|surname|last$|secondname|family.*name"
- "|nachname" // de-DE
- "|apellido" // es
- "|famille|^nom" // fr-FR
- "|cognome" // it-IT
- "|姓" // ja-JP
+ "|nachname" // de-DE
+ "|apellido" // es
+ "|famille|^nom" // fr-FR
+ "|cognome" // it-IT
+ "|姓" // ja-JP
"|morada|apelidos|surename|sobrenome" // pt-BR, pt-PT
- "|ФамилиÑ" // ru
- "|\\b성(?:[^명]|\\b)"; // ko-KR
+ "|ФамилиÑ" // ru
+ "|\\b성(?:[^명]|\\b)"; // ko-KR
/////////////////////////////////////////////////////////////////////////////
// phone_field.cc
@@ -289,23 +282,18 @@ const char kPhoneRe[] =
"|телефон" // ru
"|电è¯" // zh-CN
"|(?:ì „í™”|핸드í°|휴대í°|휴대전화)(?:.?번호)?"; // ko-KR
-const char kCountryCodeRe[] =
- "country.*code|ccode|_cc";
-const char kAreaCodeNotextRe[] =
- "^\\($";
+const char kCountryCodeRe[] = "country.*code|ccode|_cc";
+const char kAreaCodeNotextRe[] = "^\\($";
const char kAreaCodeRe[] =
"area.*code|acode|area"
"|지역.?번호"; // ko-KR
-const char kPhonePrefixSeparatorRe[] =
- "^-$|^\\)$";
-const char kPhoneSuffixSeparatorRe[] =
- "^-$";
+const char kPhonePrefixSeparatorRe[] = "^-$|^\\)$";
+const char kPhoneSuffixSeparatorRe[] = "^-$";
const char kPhonePrefixRe[] =
"prefix|exchange"
"|preselection" // fr-FR
- "|ddd"; // pt-BR, pt-PT
-const char kPhoneSuffixRe[] =
- "suffix";
+ "|ddd"; // pt-BR, pt-PT
+const char kPhoneSuffixRe[] = "suffix";
const char kPhoneExtensionRe[] =
"\\bext|ext\\b|extension"
"|ramal"; // pt-BR, pt-PT
diff --git a/chromium/components/autofill/core/browser/autofill_regex_constants.h b/chromium/components/autofill/core/common/autofill_regex_constants.h
index 8be7b2c39a6..8be7b2c39a6 100644
--- a/chromium/components/autofill/core/browser/autofill_regex_constants.h
+++ b/chromium/components/autofill/core/common/autofill_regex_constants.h
diff --git a/chromium/components/autofill/core/common/autofill_regexes.cc b/chromium/components/autofill/core/common/autofill_regexes.cc
index c9fa5222ac1..cdaf68b5a03 100644
--- a/chromium/components/autofill/core/common/autofill_regexes.cc
+++ b/chromium/components/autofill/core/common/autofill_regexes.cc
@@ -50,7 +50,8 @@ AutofillRegexes::~AutofillRegexes() {
icu::RegexMatcher* AutofillRegexes::GetMatcher(const base::string16& pattern) {
auto it = matchers_.find(pattern);
if (it == matchers_.end()) {
- const icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
+ const icu::UnicodeString icu_pattern(FALSE, pattern.data(),
+ pattern.length());
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::RegexMatcher> matcher(
@@ -72,7 +73,7 @@ bool MatchesPattern(const base::string16& input,
const base::string16& pattern) {
icu::RegexMatcher* matcher =
AutofillRegexes::GetInstance()->GetMatcher(pattern);
- icu::UnicodeString icu_input(input.data(), input.length());
+ icu::UnicodeString icu_input(FALSE, input.data(), input.length());
matcher->reset(icu_input);
UErrorCode status = U_ZERO_ERROR;
diff --git a/chromium/components/autofill/core/common/autofill_regexes_unittest.cc b/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
index a267e414991..4b0820d5f2a 100644
--- a/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/browser/autofill_regex_constants.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
diff --git a/chromium/components/autofill/core/common/autofill_switches.cc b/chromium/components/autofill/core/common/autofill_switches.cc
index 217408a99d8..eac7a997fbc 100644
--- a/chromium/components/autofill/core/common/autofill_switches.cc
+++ b/chromium/components/autofill/core/common/autofill_switches.cc
@@ -62,15 +62,5 @@ const char kShowAutofillSignatures[] = "show-autofill-signatures";
// Use the sandbox Online Wallet service URL (for developer testing).
const char kWalletServiceUseSandbox[] = "wallet-service-use-sandbox";
-#if defined(OS_ANDROID)
-// Disables showing suggestions in a keyboard accessory view.
-const char kDisableAccessorySuggestionView[] =
- "disable-autofill-keyboard-accessory-view";
-
-// Enables showing suggestions in a keyboard accessory view.
-const char kEnableAccessorySuggestionView[] =
- "enable-autofill-keyboard-accessory-view";
-#endif // defined(OS_ANDROID)
-
} // namespace switches
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/autofill_switches.h b/chromium/components/autofill/core/common/autofill_switches.h
index b1c7d909c2b..d0ef9cc7687 100644
--- a/chromium/components/autofill/core/common/autofill_switches.h
+++ b/chromium/components/autofill/core/common/autofill_switches.h
@@ -27,11 +27,6 @@ extern const char kShowAutofillTypePredictions[];
extern const char kShowAutofillSignatures[];
extern const char kWalletServiceUseSandbox[];
-#if defined(OS_ANDROID)
-extern const char kDisableAccessorySuggestionView[];
-extern const char kEnableAccessorySuggestionView[];
-#endif // defined(OS_ANDROID)
-
} // namespace switches
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/autofill_util.cc b/chromium/components/autofill/core/common/autofill_util.cc
index c20ac562e43..50e50176d8c 100644
--- a/chromium/components/autofill/core/common/autofill_util.cc
+++ b/chromium/components/autofill/core/common/autofill_util.cc
@@ -7,8 +7,11 @@
#include <algorithm>
#include "base/command_line.h"
+#include "base/feature_list.h"
#include "base/i18n/case_conversion.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -18,6 +21,15 @@
namespace autofill {
+const base::Feature kAutofillKeyboardAccessory{
+ "AutofillKeyboardAccessory", base::FEATURE_DISABLED_BY_DEFAULT};
+const char kAutofillKeyboardAccessoryAnimationDurationKey[] =
+ "animation_duration_millis";
+const char kAutofillKeyboardAccessoryLimitLabelWidthKey[] =
+ "should_limit_label_width";
+const char kAutofillKeyboardAccessoryHintKey[] =
+ "is_hint_shown_before_suggestion";
+
namespace {
const char kSplitCharacters[] = " .,-_@";
@@ -49,13 +61,40 @@ bool IsShowAutofillSignaturesEnabled() {
bool IsKeyboardAccessoryEnabled() {
#if defined(OS_ANDROID)
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableAccessorySuggestionView) ||
- (base::FieldTrialList::FindFullName("AutofillKeyboardAccessory") ==
- "Enabled" &&
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableAccessorySuggestionView));
+ return base::FeatureList::IsEnabled(kAutofillKeyboardAccessory);
+#else // !defined(OS_ANDROID)
+ return false;
+#endif
+}
+
+unsigned int GetKeyboardAccessoryAnimationDuration() {
+#if defined(OS_ANDROID)
+ return base::GetFieldTrialParamByFeatureAsInt(
+ kAutofillKeyboardAccessory,
+ kAutofillKeyboardAccessoryAnimationDurationKey, 0);
+#else // !defined(OS_ANDROID)
+ NOTREACHED();
+ return 0;
+#endif
+}
+
+bool ShouldLimitKeyboardAccessorySuggestionLabelWidth() {
+#if defined(OS_ANDROID)
+ return base::GetFieldTrialParamByFeatureAsBool(
+ kAutofillKeyboardAccessory, kAutofillKeyboardAccessoryLimitLabelWidthKey,
+ false);
+#else // !defined(OS_ANDROID)
+ NOTREACHED();
+ return false;
+#endif
+}
+
+bool IsHintEnabledInKeyboardAccessory() {
+#if defined(OS_ANDROID)
+ return base::GetFieldTrialParamByFeatureAsBool(
+ kAutofillKeyboardAccessory, kAutofillKeyboardAccessoryHintKey, false);
#else // !defined(OS_ANDROID)
+ NOTREACHED();
return false;
#endif
}
diff --git a/chromium/components/autofill/core/common/autofill_util.h b/chromium/components/autofill/core/common/autofill_util.h
index a9738774580..6a67f3ef870 100644
--- a/chromium/components/autofill/core/common/autofill_util.h
+++ b/chromium/components/autofill/core/common/autofill_util.h
@@ -13,8 +13,17 @@
#include "base/strings/string16.h"
#include "components/autofill/core/common/form_field_data.h"
+namespace base {
+struct Feature;
+}
+
namespace autofill {
+extern const base::Feature kAutofillKeyboardAccessory;
+extern const char kAutofillKeyboardAccessoryAnimationDurationKey[];
+extern const char kAutofillKeyboardAccessoryLimitLabelWidthKey[];
+extern const char kAutofillKeyboardAccessoryHintKey[];
+
// Returns true when command line switch |kEnableSuggestionsWithSubstringMatch|
// is on.
bool IsFeatureSubstringMatchEnabled();
@@ -25,6 +34,17 @@ bool IsShowAutofillSignaturesEnabled();
// Returns true when keyboard accessory is enabled.
bool IsKeyboardAccessoryEnabled();
+// Returns animation duration for keyboard accessory. If 0, we do not animate.
+unsigned int GetKeyboardAccessoryAnimationDuration();
+
+// Returns true if we must limit width of keyboard accessory suggestion label to
+// half of device's pixel width.
+bool ShouldLimitKeyboardAccessorySuggestionLabelWidth();
+
+// Returns true if we show a hint in the keyboard accessory suggestions to call
+// attention to the availability of autofill suggestions.
+bool IsHintEnabledInKeyboardAccessory();
+
// A token is a sequences of contiguous characters separated by any of the
// characters that are part of delimiter set {' ', '.', ',', '-', '_', '@'}.
diff --git a/chromium/components/autofill/core/common/password_form.cc b/chromium/components/autofill/core/common/password_form.cc
index 17892915c65..3a7ffa5d321 100644
--- a/chromium/components/autofill/core/common/password_form.cc
+++ b/chromium/components/autofill/core/common/password_form.cc
@@ -66,6 +66,9 @@ void PasswordFormToJSON(const PasswordForm& form,
target->SetString("affiliated_web_realm", form.affiliated_web_realm);
target->SetBoolean("does_look_like_signup_form",
form.does_look_like_signup_form);
+ std::ostringstream submission_event_string_stream;
+ submission_event_string_stream << form.submission_event;
+ target->SetString("submission_event", submission_event_string_stream.str());
}
} // namespace
@@ -86,7 +89,8 @@ PasswordForm::PasswordForm()
was_parsed_using_autofill_predictions(false),
is_public_suffix_match(false),
is_affiliation_based_match(false),
- does_look_like_signup_form(false) {}
+ does_look_like_signup_form(false),
+ submission_event(SubmissionIndicatorEvent::NONE) {}
PasswordForm::PasswordForm(const PasswordForm& other) = default;
@@ -130,7 +134,8 @@ bool PasswordForm::operator==(const PasswordForm& form) const {
is_public_suffix_match == form.is_public_suffix_match &&
is_affiliation_based_match == form.is_affiliation_based_match &&
affiliated_web_realm == form.affiliated_web_realm &&
- does_look_like_signup_form == form.does_look_like_signup_form;
+ does_look_like_signup_form == form.does_look_like_signup_form &&
+ submission_event == form.submission_event;
}
bool PasswordForm::operator!=(const PasswordForm& form) const {
@@ -218,4 +223,45 @@ std::ostream& operator<<(std::ostream& os, PasswordForm* form) {
return os << "&" << *form;
}
+std::ostream& operator<<(
+ std::ostream& os,
+ PasswordForm::SubmissionIndicatorEvent submission_event) {
+ switch (submission_event) {
+ case PasswordForm::SubmissionIndicatorEvent::HTML_FORM_SUBMISSION:
+ os << "HTML_FORM_SUBMISSION";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION:
+ os << "SAME_DOCUMENT_NAVIGATION";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::XHR_SUCCEEDED:
+ os << "XHR_SUCCEEDED";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::FRAME_DETACHED:
+ os << "FRAME_DETACHED";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::MANUAL_SAVE:
+ os << "MANUAL_SAVE";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR:
+ os << "DOM_MUTATION_AFTER_XHR";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD:
+ os << "PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD:
+ os << "FILLED_FORM_ON_START_PROVISIONAL_LOAD";
+ break;
+ case PasswordForm::SubmissionIndicatorEvent::
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD:
+ os << "FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD";
+ break;
+ default:
+ os << "NO_SUBMISSION";
+ break;
+ }
+ return os;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/password_form.h b/chromium/components/autofill/core/common/password_form.h
index 8bcf44850a8..67c0090d1b2 100644
--- a/chromium/components/autofill/core/common/password_form.h
+++ b/chromium/components/autofill/core/common/password_form.h
@@ -84,6 +84,24 @@ struct PasswordForm {
LAYOUT_LAST = LAYOUT_LOGIN_AND_SIGNUP
};
+ // Events observed by the Password Manager that indicate either that a form is
+ // potentially being submitted, or that a form has already been successfully
+ // submitted. Recorded into a UMA histogram, so order of enumerators should
+ // not be changed.
+ enum class SubmissionIndicatorEvent {
+ NONE,
+ HTML_FORM_SUBMISSION,
+ SAME_DOCUMENT_NAVIGATION,
+ XHR_SUCCEEDED,
+ FRAME_DETACHED,
+ MANUAL_SAVE,
+ DOM_MUTATION_AFTER_XHR,
+ PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD,
+ FILLED_FORM_ON_START_PROVISIONAL_LOAD,
+ FILLED_INPUT_ELEMENTS_ON_START_PROVISIONAL_LOAD,
+ SUBMISSION_INDICATOR_EVENT_COUNT
+ };
+
// The "Realm" for the sign-on. This is scheme, host, port for SCHEME_HTML.
// Dialog based forms also contain the HTTP realm. Android based forms will
// contain a string of the form "android://<hash of cert>@<package name>"
@@ -278,6 +296,11 @@ struct PasswordForm {
// If true, this form looks like SignUp form according to local heuristics.
bool does_look_like_signup_form;
+ // The type of the event that was taken as an indication that this form is
+ // being or has already been submitted. This field is not persisted and filled
+ // out only for submitted forms.
+ SubmissionIndicatorEvent submission_event;
+
// Return true if we consider this form to be a change password form.
// We use only client heuristics, so it could include signup forms.
bool IsPossibleChangePasswordForm() const;
@@ -315,6 +338,9 @@ base::string16 OtherPossibleUsernamesToString(
std::ostream& operator<<(std::ostream& os, PasswordForm::Layout layout);
std::ostream& operator<<(std::ostream& os, const PasswordForm& form);
std::ostream& operator<<(std::ostream& os, PasswordForm* form);
+std::ostream& operator<<(
+ std::ostream& os,
+ PasswordForm::SubmissionIndicatorEvent submission_event);
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger.cc b/chromium/components/autofill/core/common/save_password_progress_logger.cc
index 8a55fdd2b36..19b46a8368d 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger.cc
+++ b/chromium/components/autofill/core/common/save_password_progress_logger.cc
@@ -423,6 +423,8 @@ std::string SavePasswordProgressLogger::GetStringFromID(
return "Show generation popup";
case STRING_GENERATION_RENDERER_GENERATED_PASSWORD_ACCEPTED:
return "Generated password accepted";
+ case STRING_SUCCESSFUL_SUBMISSION_INDICATOR_EVENT:
+ return "Successful submission indicator event";
case SavePasswordProgressLogger::STRING_INVALID:
return "INVALID";
// Intentionally no default: clause here -- all IDs need to get covered.
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger.h b/chromium/components/autofill/core/common/save_password_progress_logger.h
index 19c9e04c0dd..d55b04f5119 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger.h
+++ b/chromium/components/autofill/core/common/save_password_progress_logger.h
@@ -166,6 +166,7 @@ class SavePasswordProgressLogger {
STRING_GENERATION_RENDERER_NO_FIELD_FOUND,
STRING_GENERATION_RENDERER_SHOW_GENERATION_POPUP,
STRING_GENERATION_RENDERER_GENERATED_PASSWORD_ACCEPTED,
+ STRING_SUCCESSFUL_SUBMISSION_INDICATOR_EVENT,
STRING_INVALID, // Represents a string returned in a case of an error.
STRING_MAX = STRING_INVALID
};
diff --git a/chromium/components/autofill/ios/browser/BUILD.gn b/chromium/components/autofill/ios/browser/BUILD.gn
index c16d7d83090..33e9542c54c 100644
--- a/chromium/components/autofill/ios/browser/BUILD.gn
+++ b/chromium/components/autofill/ios/browser/BUILD.gn
@@ -5,6 +5,7 @@
import("//ios/web/js_compile.gni")
source_set("browser") {
+ configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"autofill_client_ios_bridge.h",
"autofill_driver_ios.h",
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios.h b/chromium/components/autofill/ios/browser/autofill_driver_ios.h
index cae6b8663e6..febf00c0a70 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios.h
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios.h
@@ -26,6 +26,8 @@ namespace autofill {
class AutofillDriverIOS : public AutofillDriver,
public web::WebStateUserData<AutofillDriverIOS> {
public:
+ ~AutofillDriverIOS() override;
+
static void CreateForWebStateAndDelegate(
web::WebState* web_state,
AutofillClient* client,
@@ -48,7 +50,6 @@ class AutofillDriverIOS : public AutofillDriver,
void RendererShouldClearPreviewedForm() override;
void RendererShouldAcceptDataListSuggestion(
const base::string16& value) override;
- base::SequencedWorkerPool* GetBlockingPool() override;
void DidInteractWithCreditCardForm() override;
AutofillManager* autofill_manager() { return &autofill_manager_; }
@@ -67,13 +68,12 @@ class AutofillDriverIOS : public AutofillDriver,
id<AutofillDriverIOSBridge> bridge,
const std::string& app_locale,
AutofillManager::AutofillDownloadManagerState enable_download_manager);
- ~AutofillDriverIOS() override;
// The WebState with which this object is associated.
web::WebState* web_state_;
// AutofillDriverIOSBridge instance that is passed in.
- id<AutofillDriverIOSBridge> bridge_;
+ __unsafe_unretained id<AutofillDriverIOSBridge> bridge_;
// AutofillManager instance via which this object drives the shared Autofill
// code.
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios.mm b/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
index 1f2deba8ef4..d7fb2dbc731 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
@@ -4,13 +4,17 @@
#include "components/autofill/ios/browser/autofill_driver_ios.h"
+#include "base/memory/ptr_util.h"
#include "components/autofill/ios/browser/autofill_driver_ios_bridge.h"
#include "ios/web/public/browser_state.h"
#import "ios/web/public/origin_util.h"
#include "ios/web/public/web_state/web_state.h"
-#include "ios/web/public/web_thread.h"
#include "ui/gfx/geometry/rect_f.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
DEFINE_WEB_STATE_USER_DATA_KEY(autofill::AutofillDriverIOS);
namespace autofill {
@@ -27,8 +31,8 @@ void AutofillDriverIOS::CreateForWebStateAndDelegate(
web_state->SetUserData(
UserDataKey(),
- new AutofillDriverIOS(web_state, client, bridge, app_locale,
- enable_download_manager));
+ base::WrapUnique(new AutofillDriverIOS(
+ web_state, client, bridge, app_locale, enable_download_manager)));
}
AutofillDriverIOS::AutofillDriverIOS(
@@ -54,10 +58,6 @@ net::URLRequestContextGetter* AutofillDriverIOS::GetURLRequestContext() {
return web_state_->GetBrowserState()->GetRequestContext();
}
-base::SequencedWorkerPool* AutofillDriverIOS::GetBlockingPool() {
- return web::WebThread::GetBlockingPool();
-}
-
bool AutofillDriverIOS::RendererIsAvailable() {
return true;
}
diff --git a/chromium/components/autofill/ios/browser/credit_card_util.mm b/chromium/components/autofill/ios/browser/credit_card_util.mm
index e62b9e82cd8..c7025e55423 100644
--- a/chromium/components/autofill/ios/browser/credit_card_util.mm
+++ b/chromium/components/autofill/ios/browser/credit_card_util.mm
@@ -8,6 +8,10 @@
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/credit_card.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
namespace autofill {
NSString* GetCreditCardName(const CreditCard& credit_card,
@@ -17,12 +21,11 @@ NSString* GetCreditCardName(const CreditCard& credit_card,
}
NSString* GetCreditCardObfuscatedNumber(const CreditCard& credit_card) {
- return base::SysUTF16ToNSString(credit_card.TypeAndLastFourDigits());
+ return base::SysUTF16ToNSString(credit_card.NetworkAndLastFourDigits());
}
NSDateComponents* GetCreditCardExpirationDate(const CreditCard& credit_card) {
- NSDateComponents* expiration_date =
- [[[NSDateComponents alloc] init] autorelease];
+ NSDateComponents* expiration_date = [[NSDateComponents alloc] init];
expiration_date.year = credit_card.expiration_year();
expiration_date.month = credit_card.expiration_month();
return expiration_date;
diff --git a/chromium/components/autofill/ios/browser/form_suggestion.mm b/chromium/components/autofill/ios/browser/form_suggestion.mm
index f4bb40c37c3..4074e8e9191 100644
--- a/chromium/components/autofill/ios/browser/form_suggestion.mm
+++ b/chromium/components/autofill/ios/browser/form_suggestion.mm
@@ -4,36 +4,31 @@
#import "components/autofill/ios/browser/form_suggestion.h"
-#include "base/mac/objc_property_releaser.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
@interface FormSuggestion ()
// Local initializer for a FormSuggestion.
-- (id)initWithValue:(NSString*)value
- displayDescription:(NSString*)displayDescription
- icon:(NSString*)icon
- identifier:(NSInteger)identifier;
+- (instancetype)initWithValue:(NSString*)value
+ displayDescription:(NSString*)displayDescription
+ icon:(NSString*)icon
+ identifier:(NSInteger)identifier;
@end
-@implementation FormSuggestion {
- NSString* _value;
- NSString* _displayDescription;
- NSString* _icon;
- NSInteger _identifier;
- base::mac::ObjCPropertyReleaser _propertyReleaser_FormSuggestion;
-}
+@implementation FormSuggestion
@synthesize value = _value;
@synthesize displayDescription = _displayDescription;
@synthesize icon = _icon;
@synthesize identifier = _identifier;
-- (id)initWithValue:(NSString*)value
- displayDescription:(NSString*)displayDescription
- icon:(NSString*)icon
- identifier:(NSInteger)identifier {
+- (instancetype)initWithValue:(NSString*)value
+ displayDescription:(NSString*)displayDescription
+ icon:(NSString*)icon
+ identifier:(NSInteger)identifier {
self = [super init];
if (self) {
- _propertyReleaser_FormSuggestion.Init(self, [FormSuggestion class]);
_value = [value copy];
_displayDescription = [displayDescription copy];
_icon = [icon copy];
@@ -46,10 +41,10 @@
displayDescription:(NSString*)displayDescription
icon:(NSString*)icon
identifier:(NSInteger)identifier {
- return [[[FormSuggestion alloc] initWithValue:value
- displayDescription:displayDescription
- icon:icon
- identifier:identifier] autorelease];
+ return [[FormSuggestion alloc] initWithValue:value
+ displayDescription:displayDescription
+ icon:icon
+ identifier:identifier];
}
@end
diff --git a/chromium/components/autofill/ios/browser/js_autofill_manager.mm b/chromium/components/autofill/ios/browser/js_autofill_manager.mm
index 96e15c90734..71315764659 100644
--- a/chromium/components/autofill/ios/browser/js_autofill_manager.mm
+++ b/chromium/components/autofill/ios/browser/js_autofill_manager.mm
@@ -9,6 +9,10 @@
#include "base/logging.h"
#include "base/mac/foundation_util.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
@implementation JsAutofillManager
- (void)fetchFormsWithMinimumRequiredFieldsCount:(NSUInteger)requiredFieldsCount
diff --git a/chromium/components/autofill/ios/browser/js_suggestion_manager.mm b/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
index 1d415ce1a49..80f5c11395e 100644
--- a/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
+++ b/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
@@ -9,6 +9,10 @@
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
namespace {
// Santizies |str| and wraps it in quotes so it can be injected safely in
// JavaScript.
@@ -76,8 +80,6 @@ NSString* JSONEscape(NSString* str) {
// 2) There is a race when the page is changing due to which
// JSSuggestionManager has not yet injected __gCrWeb.suggestion object
// Handle this case gracefully.
- // TODO(shreyasv): Figure out / narrow down further why this occurs.
- // crbug.com/432217.
// If a page has overridden Array.toString, the string returned may not
// contain a ",", hence this is a defensive measure to early return.
NSArray* components = [result componentsSeparatedByString:@","];
diff --git a/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.h b/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.h
index 2114a3dde42..d3c7cf1c1b0 100644
--- a/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.h
+++ b/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.h
@@ -40,7 +40,7 @@ class PersonalDataManagerObserverBridge : public PersonalDataManagerObserver {
void OnInsufficientFormData() override;
private:
- id<PersonalDataManagerObserverBridgeDelegate> delegate_; // Weak.
+ __unsafe_unretained id<PersonalDataManagerObserverBridgeDelegate> delegate_;
DISALLOW_COPY_AND_ASSIGN(PersonalDataManagerObserverBridge);
};
diff --git a/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.mm b/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.mm
index e03fe0ee5b0..bb3c48f63da 100644
--- a/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.mm
+++ b/chromium/components/autofill/ios/browser/personal_data_manager_observer_bridge.mm
@@ -6,6 +6,10 @@
#include "base/logging.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
namespace autofill {
PersonalDataManagerObserverBridge::PersonalDataManagerObserverBridge(
diff --git a/chromium/components/autofill_strings.grdp b/chromium/components/autofill_strings.grdp
index 2ab82162de1..bea84fef451 100644
--- a/chromium/components/autofill_strings.grdp
+++ b/chromium/components/autofill_strings.grdp
@@ -63,11 +63,14 @@
<message name="IDS_AUTOFILL_CC_DISCOVER" desc="Discover credit card name." formatter_data="android_java">
Discover
</message>
+ <message name="IDS_AUTOFILL_CC_ELO" desc="Elo credit card name." formatter_data="android_java">
+ Elo
+ </message>
<message name="IDS_AUTOFILL_CC_JCB" desc="JCB credit card name." formatter_data="android_java">
JCB
</message>
- <message name="IDS_AUTOFILL_CC_MASTERCARD" desc="MasterCard credit card name." formatter_data="android_java">
- MasterCard
+ <message name="IDS_AUTOFILL_CC_MASTERCARD" desc="Mastercard credit card name." formatter_data="android_java">
+ Mastercard
</message>
<message name="IDS_AUTOFILL_CC_MIR" desc="Mir credit card name." formatter_data="android_java">
Mir
@@ -204,10 +207,20 @@
Do you want Chromium to save this card?
</message>
</if>
- <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD" desc="Title text for the Autofill save card prompt when the card is to be saved by uploading it to Google Payments. The prompt can be either a bubble or an infobar.">
- Do you want to save this card to your Google Account?
- </message>
- <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments. The prompt can be either a bubble or an infobar.">
+ <if expr="is_linux and not is_chromeos">
+ <then>
+ <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD" desc="Title text for the Autofill save card prompt when the card is to be saved by uploading it to Google Payments and also saved locally. The prompt can be either a bubble or an infobar.">
+ Do you want to save this card to your Google Account?
+ </message>
+ </then>
+ <else>
+ <!-- TODO(crbug/714920): Rename IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD to IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD_AND_LOCAL -->
+ <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD" desc="Title text for the Autofill save card prompt when the card is to be saved by uploading it to Google Payments and also saved locally. The prompt can be either a bubble or an infobar.">
+ Do you want to save this card to your Google Account and on this device?
+ </message>
+ </else>
+ </if>
+ <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments and also saved locally. The prompt can be either a bubble or an infobar.">
Pay quickly on sites and apps across devices using cards you have saved with Google.
</message>
<message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC" desc="Text displayed in the Autofill save credit card prompt explaining that the card needs additional CVC information in order to be saved to Google Payments.">
@@ -284,7 +297,7 @@
Enter the expiration date and CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph>
</message>
<message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS" desc="Text explaining what the user should do in the card unmasking dialog.">
- Once you confirm, your card details will be shared with this site
+ Once you confirm, your card details will be shared with this site.
</message>
</if>
<if expr="is_ios">
@@ -346,10 +359,16 @@
<message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC" desc="The placeholder/label text for credit card verification code in the requestAutocomplete dialog.">
CVC
</message>
- <message name="IDS_AUTOFILL_LOADING_REGIONS" desc="The string to display in the regions combo box while loading the region data.">
+ <message name="IDS_AUTOFILL_LOADING_REGIONS" desc="The string to display in the regions combobox while loading the region data.">
Loading...
</message>
<message name="IDS_AUTOFILL_FAILED_LOADING_REGIONS" desc="The string to display in the regions combo box when loading the region data failed.">
Failed loading regions data
</message>
+ <message name="IDS_AUTOFILL_SELECT" desc="The string to display in comboboxes when nothing got selected yet.">
+ Select
+ </message>
+ <message name="IDS_AUTOFILL_NO_SAVED_ADDRESS" desc="The string to display in comboboxes when no addresses are available.">
+ No saved addresses
+ </message>
</grit-part>
diff --git a/chromium/components/background_task_scheduler/BUILD.gn b/chromium/components/background_task_scheduler/BUILD.gn
index 6bd4bacda46..e23f4837d71 100644
--- a/chromium/components/background_task_scheduler/BUILD.gn
+++ b/chromium/components/background_task_scheduler/BUILD.gn
@@ -23,11 +23,14 @@ if (is_android) {
android_library("background_task_scheduler_java") {
java_files = [
"android/java/src/org/chromium/components/background_task_scheduler/BackgroundTask.java",
+ "android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskGcmTaskService.java",
"android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskJobService.java",
"android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskScheduler.java",
"android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerDelegate.java",
"android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerFactory.java",
+ "android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManager.java",
"android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobService.java",
+ "android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerPrefs.java",
"android/java/src/org/chromium/components/background_task_scheduler/BundleToPersistableBundleConverter.java",
"android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java",
"android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java",
@@ -37,6 +40,7 @@ if (is_android) {
deps = [
"//base:base_java",
"//third_party/android_tools:android_support_annotations_java",
+ google_play_services_library,
]
}
@@ -54,6 +58,27 @@ if (is_android) {
"//base:base_java_test_support",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit",
+ google_play_services_library,
]
}
+
+ junit_binary("components_background_task_scheduler_junit_tests") {
+ java_files = [
+ "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManagerTest.java",
+ "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskGcmTaskServiceTest.java",
+ "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerPrefsTest.java",
+ "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerTest.java",
+ "android/junit/src/org/chromium/components/background_task_scheduler/ShadowGcmNetworkManager.java",
+ "android/junit/src/org/chromium/components/background_task_scheduler/TestBackgroundTask.java",
+ ]
+
+ deps = [
+ ":background_task_scheduler_java",
+ "//base:base_java",
+ "//base:base_java_test_support",
+ "//third_party/junit",
+ google_play_services_library,
+ ]
+ srcjar_deps = [ "//base:base_build_config_gen" ]
+ }
}
diff --git a/chromium/components/bookmarks/browser/BUILD.gn b/chromium/components/bookmarks/browser/BUILD.gn
index b606dc4b13d..8f3883400cb 100644
--- a/chromium/components/bookmarks/browser/BUILD.gn
+++ b/chromium/components/bookmarks/browser/BUILD.gn
@@ -112,6 +112,7 @@ source_set("unit_tests") {
deps = [
":browser",
":unit_tests_bundle_data",
+ "//base/test:test_support",
"//components/bookmarks/common",
"//components/bookmarks/test",
"//components/favicon_base",
diff --git a/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc b/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
index dd3070b039c..d0c6b4571de 100644
--- a/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
+++ b/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
@@ -6,6 +6,9 @@
#include <stdint.h>
+#include <utility>
+#include <vector>
+
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "components/bookmarks/browser/bookmark_model.h"
@@ -104,13 +107,14 @@ void BookmarkExpandedStateTracker::UpdatePrefs(const Nodes& nodes) {
if (!pref_service_)
return;
- base::ListValue values;
- for (Nodes::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
- values.Set(values.GetSize(),
- new base::Value(base::Int64ToString((*i)->id())));
+ std::vector<base::Value> values;
+ values.reserve(nodes.size());
+ for (const auto* node : nodes) {
+ values.emplace_back(base::Int64ToString(node->id()));
}
- pref_service_->Set(prefs::kBookmarkEditorExpandedNodes, values);
+ pref_service_->Set(prefs::kBookmarkEditorExpandedNodes,
+ base::Value(std::move(values)));
}
} // namespace bookmarks
diff --git a/chromium/components/bookmarks/browser/bookmark_model_unittest.cc b/chromium/components/bookmarks/browser/bookmark_model_unittest.cc
index 64a5bb40f69..551999a476c 100644
--- a/chromium/components/bookmarks/browser/bookmark_model_unittest.cc
+++ b/chromium/components/bookmarks/browser/bookmark_model_unittest.cc
@@ -1114,7 +1114,7 @@ TEST_F(BookmarkModelTest, NodeVisibility) {
EXPECT_TRUE(model_->mobile_node()->IsVisible());
}
-TEST_F(BookmarkModelTest, MobileNodeVisibileWithChildren) {
+TEST_F(BookmarkModelTest, MobileNodeVisibleWithChildren) {
const BookmarkNode* root = model_->mobile_node();
const base::string16 title(ASCIIToUTF16("foo"));
const GURL url("http://foo.com");
diff --git a/chromium/components/bookmarks/browser/bookmark_node_data_unittest.cc b/chromium/components/bookmarks/browser/bookmark_node_data_unittest.cc
index 881fa7bffab..127d96384c1 100644
--- a/chromium/components/bookmarks/browser/bookmark_node_data_unittest.cc
+++ b/chromium/components/bookmarks/browser/bookmark_node_data_unittest.cc
@@ -8,9 +8,9 @@
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/test/bookmark_test_helpers.h"
#include "components/bookmarks/test/test_bookmark_client.h"
@@ -25,7 +25,9 @@ namespace bookmarks {
class BookmarkNodeDataTest : public testing::Test {
public:
- BookmarkNodeDataTest() {}
+ BookmarkNodeDataTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
void SetUp() override {
model_ = TestBookmarkClient::CreateModel();
@@ -53,7 +55,7 @@ class BookmarkNodeDataTest : public testing::Test {
private:
base::ScopedTempDir profile_dir_;
std::unique_ptr<BookmarkModel> model_;
- base::MessageLoopForUI loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
DISALLOW_COPY_AND_ASSIGN(BookmarkNodeDataTest);
};
diff --git a/chromium/components/bookmarks/browser/bookmark_utils_unittest.cc b/chromium/components/bookmarks/browser/bookmark_utils_unittest.cc
index d78e9fcebed..102c14c01e7 100644
--- a/chromium/components/bookmarks/browser/bookmark_utils_unittest.cc
+++ b/chromium/components/bookmarks/browser/bookmark_utils_unittest.cc
@@ -10,8 +10,8 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/bookmarks/browser/base_bookmark_model_observer.h"
#include "components/bookmarks/browser/bookmark_model.h"
@@ -31,7 +31,10 @@ class BookmarkUtilsTest : public testing::Test,
public BaseBookmarkModelObserver {
public:
BookmarkUtilsTest()
- : grouped_changes_beginning_count_(0), grouped_changes_ended_count_(0) {}
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ grouped_changes_beginning_count_(0),
+ grouped_changes_ended_count_(0) {}
~BookmarkUtilsTest() override {}
@@ -69,12 +72,12 @@ class BookmarkUtilsTest : public testing::Test,
++grouped_changes_ended_count_;
}
+ // Clipboard requires a message loop.
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+
int grouped_changes_beginning_count_;
int grouped_changes_ended_count_;
- // Clipboard requires a message loop.
- base::MessageLoopForUI loop_;
-
DISALLOW_COPY_AND_ASSIGN(BookmarkUtilsTest);
};
@@ -242,7 +245,7 @@ TEST_F(BookmarkUtilsTest, GetBookmarksMatchingPropertiesConjunction) {
ASSERT_EQ(1U, nodes.size());
EXPECT_TRUE(nodes[0] == node1);
nodes.clear();
- fields[i]->reset(original_value.release());
+ *fields[i] = std::move(original_value);
}
// Test two fields matching with one non-matching field.
@@ -252,7 +255,7 @@ TEST_F(BookmarkUtilsTest, GetBookmarksMatchingPropertiesConjunction) {
GetBookmarksMatchingProperties(model.get(), query, 100, &nodes);
ASSERT_EQ(0U, nodes.size());
nodes.clear();
- fields[i]->reset(original_value.release());
+ *fields[i] = std::move(original_value);
}
}
diff --git a/chromium/components/browser_sync/profile_sync_components_factory_impl.cc b/chromium/components/browser_sync/profile_sync_components_factory_impl.cc
index 445b20bb221..5f47d6185b4 100644
--- a/chromium/components/browser_sync/profile_sync_components_factory_impl.cc
+++ b/chromium/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -9,6 +9,7 @@
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_wallet_data_type_controller.h"
#include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h"
@@ -49,6 +50,7 @@
#include "google_apis/gaia/oauth2_token_service_request.h"
#include "net/url_request/url_request_context_getter.h"
+using base::FeatureList;
using bookmarks::BookmarkModel;
using sync_bookmarks::BookmarkChangeProcessor;
using sync_bookmarks::BookmarkDataTypeController;
@@ -139,7 +141,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
base::Bind(&syncer::ReportUnrecoverableError, channel_);
// TODO(stanisc): can DEVICE_INFO be one of disabled datatypes?
- if (base::FeatureList::IsEnabled(switches::kSyncUSSDeviceInfo)) {
+ if (FeatureList::IsEnabled(switches::kSyncUSSDeviceInfo)) {
// Use an error callback that always uploads a stacktrace if it can to help
// get USS as stable as possible.
sync_service->RegisterDataTypeController(
@@ -155,7 +157,7 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
// Autocomplete sync is enabled by default. Register unless explicitly
// disabled.
if (!disabled_types.Has(syncer::AUTOFILL)) {
- if (base::FeatureList::IsEnabled(switches::kSyncUSSAutocomplete)) {
+ if (FeatureList::IsEnabled(switches::kSyncUSSAutocomplete)) {
sync_service->RegisterDataTypeController(
base::MakeUnique<autofill::WebDataModelTypeController>(
syncer::AUTOFILL, sync_client_, db_thread_, web_data_service_,
@@ -308,6 +310,13 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
base::MakeUnique<ModelTypeController>(syncer::READING_LIST,
sync_client_, ui_thread_));
}
+
+ if (!disabled_types.Has(syncer::USER_EVENTS) &&
+ FeatureList::IsEnabled(switches::kSyncUserEvents)) {
+ sync_service->RegisterDataTypeController(
+ base::MakeUnique<ModelTypeController>(syncer::USER_EVENTS, sync_client_,
+ ui_thread_));
+ }
}
DataTypeManager* ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
diff --git a/chromium/components/browser_sync/profile_sync_service.cc b/chromium/components/browser_sync/profile_sync_service.cc
index 5eb7949df19..cf5f2af870f 100644
--- a/chromium/components/browser_sync/profile_sync_service.cc
+++ b/chromium/components/browser_sync/profile_sync_service.cc
@@ -242,12 +242,8 @@ void ProfileSyncService::Initialize() {
syncer::ModelTypeSet(syncer::SESSIONS)));
if (base::FeatureList::IsEnabled(switches::kSyncUSSDeviceInfo)) {
- // TODO(skym): Stop creating leveldb files when signed out.
- // TODO(skym): Verify using AsUTF8Unsafe is okay here. Should work as long
- // as the Local State file is guaranteed to be UTF-8.
const syncer::ModelTypeStoreFactory& store_factory =
- GetModelTypeStoreFactory(syncer::DEVICE_INFO, base_directory_,
- sync_client_->GetBlockingPool());
+ GetModelTypeStoreFactory(syncer::DEVICE_INFO, base_directory_);
device_info_sync_bridge_ = base::MakeUnique<DeviceInfoSyncBridge>(
local_device_.get(), store_factory,
base::BindRepeating(
@@ -1681,18 +1677,12 @@ void ProfileSyncService::SetPlatformSyncAllowedProvider(
// static
syncer::ModelTypeStoreFactory ProfileSyncService::GetModelTypeStoreFactory(
ModelType type,
- const base::FilePath& base_path,
- base::SequencedWorkerPool* blocking_pool) {
+ const base::FilePath& base_path) {
// TODO(skym): Verify using AsUTF8Unsafe is okay here. Should work as long
// as the Local State file is guaranteed to be UTF-8.
- std::string path = FormatSharedModelTypeStorePath(base_path).AsUTF8Unsafe();
- base::SequencedWorkerPool::SequenceToken sequence_token =
- blocking_pool->GetNamedSequenceToken(path);
- scoped_refptr<base::SequencedTaskRunner> task_runner =
- blocking_pool->GetSequencedTaskRunnerWithShutdownBehavior(
- blocking_pool->GetNamedSequenceToken(path),
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
- return base::Bind(&ModelTypeStore::CreateStore, type, path, task_runner);
+ const std::string path =
+ FormatSharedModelTypeStorePath(base_path).AsUTF8Unsafe();
+ return base::Bind(&ModelTypeStore::CreateStore, type, path);
}
void ProfileSyncService::ConfigureDataTypeManager() {
@@ -1783,41 +1773,33 @@ std::unique_ptr<base::Value> ProfileSyncService::GetTypeStatusMap() {
return std::move(result);
}
- DataTypeStatusTable::TypeErrorMap error_map =
- data_type_status_table_.GetAllErrors();
- ModelTypeSet active_types;
- ModelTypeSet passive_types;
- ModelSafeRoutingInfo routing_info;
- engine_->GetModelSafeRoutingInfo(&routing_info);
- for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin();
- it != routing_info.end(); ++it) {
- if (it->second == syncer::GROUP_PASSIVE) {
- passive_types.Put(it->first);
- } else {
- active_types.Put(it->first);
- }
- }
-
SyncEngine::Status detailed_status = engine_->GetDetailedStatus();
- ModelTypeSet& throttled_types(detailed_status.throttled_types);
- ModelTypeSet& backed_off_types(detailed_status.backed_off_types);
- ModelTypeSet registered = GetRegisteredDataTypes();
+ const ModelTypeSet& throttled_types(detailed_status.throttled_types);
+ const ModelTypeSet& backed_off_types(detailed_status.backed_off_types);
+
std::unique_ptr<base::DictionaryValue> type_status_header(
new base::DictionaryValue());
-
- type_status_header->SetString("name", "Model Type");
type_status_header->SetString("status", "header");
- type_status_header->SetString("value", "Group Type");
+ type_status_header->SetString("name", "Model Type");
type_status_header->SetString("num_entries", "Total Entries");
type_status_header->SetString("num_live", "Live Entries");
+ type_status_header->SetString("message", "Message");
+ type_status_header->SetString("state", "State");
+ type_status_header->SetString("group_type", "Group Type");
result->Append(std::move(type_status_header));
- std::unique_ptr<base::DictionaryValue> type_status;
+ const DataTypeStatusTable::TypeErrorMap error_map =
+ data_type_status_table_.GetAllErrors();
+ ModelSafeRoutingInfo routing_info;
+ engine_->GetModelSafeRoutingInfo(&routing_info);
+ const ModelTypeSet registered = GetRegisteredDataTypes();
for (ModelTypeSet::Iterator it = registered.First(); it.Good(); it.Inc()) {
ModelType type = it.Get();
- type_status = base::MakeUnique<base::DictionaryValue>();
+ auto type_status = base::MakeUnique<base::DictionaryValue>();
type_status->SetString("name", ModelTypeToString(type));
+ type_status->SetString("group_type",
+ ModelSafeGroupToString(routing_info[type]));
if (error_map.find(type) != error_map.end()) {
const syncer::SyncError& error = error_map.find(type)->second;
@@ -1826,44 +1808,26 @@ std::unique_ptr<base::Value> ProfileSyncService::GetTypeStatusMap() {
case syncer::SyncError::SYNC_ERROR_SEVERITY_ERROR:
type_status->SetString("status", "error");
type_status->SetString(
- "value", "Error: " + error.location().ToString() + ", " +
- error.GetMessagePrefix() + error.message());
+ "message", "Error: " + error.location().ToString() + ", " +
+ error.GetMessagePrefix() + error.message());
break;
case syncer::SyncError::SYNC_ERROR_SEVERITY_INFO:
type_status->SetString("status", "disabled");
- type_status->SetString("value", error.message());
- break;
- default:
- NOTREACHED() << "Unexpected error severity.";
+ type_status->SetString("message", error.message());
break;
}
- } else if (syncer::IsProxyType(type) && passive_types.Has(type)) {
- // Show a proxy type in "ok" state unless it is disabled by user.
- DCHECK(!throttled_types.Has(type));
- type_status->SetString("status", "ok");
- type_status->SetString("value", "Passive");
- } else if (throttled_types.Has(type) && passive_types.Has(type)) {
- type_status->SetString("status", "warning");
- type_status->SetString("value", "Passive, Throttled");
- } else if (backed_off_types.Has(type) && passive_types.Has(type)) {
- type_status->SetString("status", "warning");
- type_status->SetString("value", "Passive, Backed off");
- } else if (passive_types.Has(type)) {
- type_status->SetString("status", "warning");
- type_status->SetString("value", "Passive");
} else if (throttled_types.Has(type)) {
type_status->SetString("status", "warning");
- type_status->SetString("value", "Throttled");
+ type_status->SetString("message", " Throttled");
} else if (backed_off_types.Has(type)) {
type_status->SetString("status", "warning");
- type_status->SetString("value", "Backed off");
- } else if (active_types.Has(type)) {
+ type_status->SetString("message", "Backed off");
+ } else if (routing_info.find(type) != routing_info.end()) {
type_status->SetString("status", "ok");
- type_status->SetString(
- "value", "Active: " + ModelSafeGroupToString(routing_info[type]));
+ type_status->SetString("message", "");
} else {
type_status->SetString("status", "warning");
- type_status->SetString("value", "Disabled by User");
+ type_status->SetString("message", "Disabled by User");
}
const auto& dtc_iter = data_type_controllers_.find(type);
@@ -1874,6 +1838,8 @@ std::unique_ptr<base::Value> ProfileSyncService::GetTypeStatusMap() {
dtc_iter->second->GetStatusCounters(BindToCurrentThread(
base::Bind(&ProfileSyncService::OnDatatypeStatusCounterUpdated,
base::Unretained(this))));
+ type_status->SetString("state", DataTypeController::StateToString(
+ dtc_iter->second->state()));
}
result->Append(std::move(type_status));
@@ -2223,14 +2189,9 @@ void ProfileSyncService::RequestStop(SyncStopDataFate data_fate) {
bool ProfileSyncService::IsSyncRequested() const {
DCHECK(thread_checker_.CalledOnValidThread());
- return sync_prefs_.IsSyncRequested();
-}
-
-SigninManagerBase* ProfileSyncService::signin() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!signin_)
- return nullptr;
- return signin_->GetOriginal();
+ // When local sync is on sync should be considered requsted or otherwise it
+ // will not resume after the policy or the flag has been removed.
+ return sync_prefs_.IsSyncRequested() || sync_prefs_.IsLocalSyncEnabled();
}
void ProfileSyncService::RequestStart() {
diff --git a/chromium/components/browser_sync/profile_sync_service.h b/chromium/components/browser_sync/profile_sync_service.h
index 88837d3b6ed..a713ca3c734 100644
--- a/chromium/components/browser_sync/profile_sync_service.h
+++ b/chromium/components/browser_sync/profile_sync_service.h
@@ -496,8 +496,6 @@ class ProfileSyncService : public syncer::SyncServiceBase,
// Returns true if the syncer is waiting for new datatypes to be encrypted.
virtual bool encryption_pending() const;
- SigninManagerBase* signin() const;
-
syncer::SyncErrorController* sync_error_controller() {
return sync_error_controller_.get();
}
@@ -559,12 +557,9 @@ class ProfileSyncService : public syncer::SyncServiceBase,
// Returns a function for |type| that will create a ModelTypeStore that shares
// the sync LevelDB backend. |base_path| should be set to profile path.
- // |sequenced_worker_pool| is obtained from content::BrowserThread or
- // web::WebThread depending on platform.
static syncer::ModelTypeStoreFactory GetModelTypeStoreFactory(
syncer::ModelType type,
- const base::FilePath& base_path,
- base::SequencedWorkerPool* sequenced_worker_pool);
+ const base::FilePath& base_path);
// Needed to test whether the directory is deleted properly.
base::FilePath GetDirectoryPathForTest() const;
diff --git a/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc b/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc
index f60c2afd61b..469864650b5 100644
--- a/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -19,6 +19,7 @@
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
+#include "base/sequenced_task_runner.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
@@ -90,7 +91,7 @@ using testing::_;
using testing::DoAll;
using testing::ElementsAre;
using testing::Not;
-using testing::SetArgumentPointee;
+using testing::SetArgPointee;
using testing::Return;
namespace browser_sync {
@@ -842,7 +843,7 @@ TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) {
std::vector<AutofillEntry> entries;
entries.push_back(MakeAutofillEntry("foo", "bar", 1));
EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true)));
SetIdleChangeProcessorExpectations();
CreateRootHelper create_root(this, AUTOFILL);
EXPECT_CALL(personal_data_manager(), Refresh());
@@ -889,7 +890,7 @@ TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
entries.push_back(MakeAutofillEntry("dup", "", 2));
entries.push_back(MakeAutofillEntry("dup", "", 3));
EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true)));
SetIdleChangeProcessorExpectations();
CreateRootHelper create_root(this, AUTOFILL);
EXPECT_CALL(personal_data_manager(), Refresh());
@@ -909,7 +910,7 @@ TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) {
native_entries.push_back(native_entry);
EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true)));
std::vector<AutofillEntry> sync_entries;
sync_entries.push_back(sync_entry);
@@ -951,7 +952,7 @@ TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge_NullTerminated) {
native_entries.push_back(native_entry1);
EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true)));
std::vector<AutofillEntry> sync_entries;
sync_entries.push_back(sync_entry0);
@@ -994,7 +995,7 @@ TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) {
std::vector<AutofillEntry> native_entries;
native_entries.push_back(native_entry);
EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true)));
std::vector<AutofillEntry> sync_entries;
sync_entries.push_back(sync_entry);
@@ -1364,8 +1365,8 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) {
AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1));
EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(added_entry.date_created()),
- SetArgumentPointee<3>(added_entry.date_last_used()),
+ .WillOnce(DoAll(SetArgPointee<2>(added_entry.date_created()),
+ SetArgPointee<3>(added_entry.date_last_used()),
Return(true)));
AutofillChangeList changes;
@@ -1412,7 +1413,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
original_entries.push_back(original_entry);
EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL(personal_data_manager(), Refresh());
CreateRootHelper create_root(this, AUTOFILL);
StartSyncService(create_root.callback(), false, AUTOFILL);
@@ -1421,8 +1422,8 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(updated_entry.date_created()),
- SetArgumentPointee<3>(updated_entry.date_last_used()),
+ .WillOnce(DoAll(SetArgPointee<2>(updated_entry.date_created()),
+ SetArgPointee<3>(updated_entry.date_last_used()),
Return(true)));
AutofillChangeList changes;
@@ -1444,7 +1445,7 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) {
original_entries.push_back(original_entry);
EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL(personal_data_manager(), Refresh());
CreateRootHelper create_root(this, AUTOFILL);
StartSyncService(create_root.callback(), false, AUTOFILL);
diff --git a/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc b/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc
index 3f63fc49247..9d3e951e6d1 100644
--- a/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc
@@ -6,6 +6,7 @@
#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/browser_sync/profile_sync_test_util.h"
diff --git a/chromium/components/browser_sync/profile_sync_service_typed_url_unittest.cc b/chromium/components/browser_sync/profile_sync_service_typed_url_unittest.cc
index db7db211a5e..50906f1460b 100644
--- a/chromium/components/browser_sync/profile_sync_service_typed_url_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_typed_url_unittest.cc
@@ -17,7 +17,9 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
@@ -48,7 +50,7 @@ using history::HistoryBackendNotifier;
using history::TypedUrlSyncableService;
using testing::DoAll;
using testing::Return;
-using testing::SetArgumentPointee;
+using testing::SetArgPointee;
using testing::_;
namespace browser_sync {
@@ -419,9 +421,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeEmptySync) {
MakeTypedUrlEntry("http://foo.com", "bar", 2, 15, false, &visits));
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(DoAll(SetArgumentPointee<2>(visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(visits), Return(true)));
SetIdleChangeProcessorExpectations();
CreateRootHelper create_root(this, syncer::TYPED_URLS);
TypedUrlSyncableService* syncable_service =
@@ -443,7 +445,7 @@ TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeErrorReadingVisits) {
entries.push_back(native_entry1);
entries.push_back(native_entry2);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true)));
// Return an error from GetMostRecentVisitsForURL() for the second URL.
EXPECT_CALL((history_backend()),
GetMostRecentVisitsForURL(native_entry1.id(), _, _))
@@ -468,9 +470,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeWithBlankEmptySync) {
entries.push_back(
MakeTypedUrlEntry("http://foo.com", "bar", 2, 15, false, &visits));
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(DoAll(SetArgumentPointee<2>(visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(visits), Return(true)));
SetIdleChangeProcessorExpectations();
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
@@ -492,10 +494,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeHasSyncNoMerge) {
history::URLRows native_entries;
native_entries.push_back(native_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(native_visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(native_visits), Return(true)));
EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
.WillRepeatedly(Return(true));
@@ -553,10 +554,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeHasSyncMerge) {
history::URLRows native_entries;
native_entries.push_back(native_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(native_visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(native_visits), Return(true)));
EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
.WillRepeatedly(Return(true));
@@ -585,12 +585,12 @@ TEST_F(ProfileSyncServiceTypedUrlTest, HasNativeWithErrorHasSyncMerge) {
history::URLRows native_entries;
native_entries.push_back(native_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true)));
// Return an error getting the visits for the native URL.
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
.WillRepeatedly(Return(false));
EXPECT_CALL((history_backend()), GetURL(_, _))
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(native_entry), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<1>(native_entry), Return(true)));
EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
.WillRepeatedly(Return(true));
@@ -615,7 +615,7 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeAdd) {
EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(added_visits), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<2>(added_visits), Return(true)));
SetIdleChangeProcessorExpectations();
CreateRootHelper create_root(this, syncer::TYPED_URLS);
@@ -640,7 +640,7 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeAddWithBlank) {
EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(DoAll(SetArgumentPointee<2>(added_visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(added_visits), Return(true)));
SetIdleChangeProcessorExpectations();
CreateRootHelper create_root(this, syncer::TYPED_URLS);
@@ -665,9 +665,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeUpdate) {
original_entries.push_back(original_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<2>(original_visits), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
@@ -675,7 +675,7 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeUpdate) {
history::URLRow updated_entry(MakeTypedUrlEntry("http://mine.com", "entry", 7,
17, false, &updated_visits));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(updated_visits), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<2>(updated_visits), Return(true)));
history::URLRows changed_urls;
changed_urls.push_back(updated_entry);
@@ -694,7 +694,7 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeAddFromVisit) {
EXPECT_CALL((history_backend()), GetAllTypedURLs(_)).WillOnce(Return(true));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(added_visits), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<2>(added_visits), Return(true)));
SetIdleChangeProcessorExpectations();
CreateRootHelper create_root(this, syncer::TYPED_URLS);
@@ -716,9 +716,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeUpdateFromVisit) {
original_entries.push_back(original_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<2>(original_visits), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
@@ -726,7 +726,7 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeUpdateFromVisit) {
history::URLRow updated_entry(MakeTypedUrlEntry("http://mine.com", "entry", 7,
17, false, &updated_visits));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillOnce(DoAll(SetArgumentPointee<2>(updated_visits), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<2>(updated_visits), Return(true)));
SendNotificationURLVisited(ui::PAGE_TRANSITION_TYPED, updated_entry);
@@ -744,10 +744,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserIgnoreChangeUpdateFromVisit) {
original_entries.push_back(original_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(original_visits), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
history::URLRows new_sync_entries;
@@ -801,10 +800,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeRemove) {
original_entries.push_back(original_entry2);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(original_visits1), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(original_visits1), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
@@ -829,10 +827,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeRemoveExpired) {
original_entries.push_back(original_entry2);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(original_visits1), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(original_visits1), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
@@ -858,10 +855,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, ProcessUserChangeRemoveAll) {
original_entries.push_back(original_entry2);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(original_visits1), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(original_visits1), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
@@ -887,12 +883,11 @@ TEST_F(ProfileSyncServiceTypedUrlTest, FailWriteToHistoryBackend) {
history::URLRows native_entries;
native_entries.push_back(native_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true)));
EXPECT_CALL((history_backend()), GetURL(_, _))
- .WillOnce(DoAll(SetArgumentPointee<1>(native_entry), Return(false)));
+ .WillOnce(DoAll(SetArgPointee<1>(native_entry), Return(false)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(native_visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(native_visits), Return(true)));
EXPECT_CALL((history_backend()), AddVisits(_, _, history::SOURCE_SYNCED))
.WillRepeatedly(Return(false));
@@ -924,7 +919,7 @@ TEST_F(ProfileSyncServiceTypedUrlTest, FailToGetTypedURLs) {
history::URLRows native_entries;
native_entries.push_back(native_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(false)));
+ .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(false)));
history::URLRows sync_entries;
sync_entries.push_back(sync_entry);
@@ -953,11 +948,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, IgnoreLocalFileURL) {
original_entries.push_back(file_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(original_visits), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
@@ -998,11 +991,9 @@ TEST_F(ProfileSyncServiceTypedUrlTest, IgnoreLocalhostURL) {
original_entries.push_back(localhost_entry);
EXPECT_CALL((history_backend()), GetAllTypedURLs(_))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<0>(original_entries), Return(true)));
EXPECT_CALL((history_backend()), GetMostRecentVisitsForURL(_, _, _))
- .WillRepeatedly(
- DoAll(SetArgumentPointee<2>(original_visits), Return(true)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(original_visits), Return(true)));
CreateRootHelper create_root(this, syncer::TYPED_URLS);
StartSyncService(create_root.callback());
diff --git a/chromium/components/browser_sync/profile_sync_service_unittest.cc b/chromium/components/browser_sync/profile_sync_service_unittest.cc
index fc0d17f4356..4dd3cb85a24 100644
--- a/chromium/components/browser_sync/profile_sync_service_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_unittest.cc
@@ -386,7 +386,6 @@ TEST_F(ProfileSyncServiceTest, SuccessfulInitialization) {
TEST_F(ProfileSyncServiceTest, SuccessfulLocalBackendInitialization) {
prefs()->SetManagedPref(syncer::prefs::kSyncManaged,
base::MakeUnique<base::Value>(false));
- IssueTestTokens();
CreateServiceWithLocalSyncBackend();
ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback());
ExpectSyncEngineCreation(1);
@@ -943,6 +942,34 @@ TEST_F(ProfileSyncServiceTest, DisableSyncOnClient) {
EXPECT_FALSE(service()->GetLocalDeviceInfoProvider()->GetLocalDeviceInfo());
}
+// Verify a that local sync mode resumes after the policy is lifted.
+TEST_F(ProfileSyncServiceTest, LocalBackendDisabledByPolicy) {
+ prefs()->SetManagedPref(syncer::prefs::kSyncManaged,
+ base::MakeUnique<base::Value>(false));
+ CreateServiceWithLocalSyncBackend();
+ ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback());
+ ExpectSyncEngineCreation(1);
+ InitializeForNthSync();
+ EXPECT_FALSE(service()->IsManaged());
+ EXPECT_TRUE(service()->IsSyncActive());
+
+ prefs()->SetManagedPref(syncer::prefs::kSyncManaged,
+ base::MakeUnique<base::Value>(true));
+
+ EXPECT_TRUE(service()->IsManaged());
+ EXPECT_FALSE(service()->IsSyncActive());
+
+ prefs()->SetManagedPref(syncer::prefs::kSyncManaged,
+ base::MakeUnique<base::Value>(false));
+
+ ExpectDataTypeManagerCreation(1, GetDefaultConfigureCalledCallback());
+ ExpectSyncEngineCreation(1);
+
+ service()->RequestStart();
+ EXPECT_FALSE(service()->IsManaged());
+ EXPECT_TRUE(service()->IsSyncActive());
+}
+
// Regression test for crbug/555434. The issue is that check for sessions DTC in
// OnSessionRestoreComplete was creating map entry with nullptr which later was
// dereferenced in OnSyncCycleCompleted. The fix is to use find() to check if
diff --git a/chromium/components/browser_sync/profile_sync_test_util.cc b/chromium/components/browser_sync/profile_sync_test_util.cc
index ee186d14d3c..575271243a2 100644
--- a/chromium/components/browser_sync/profile_sync_test_util.cc
+++ b/chromium/components/browser_sync/profile_sync_test_util.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/history/core/browser/history_model_worker.h"
diff --git a/chromium/components/browser_sync/test_profile_sync_service.cc b/chromium/components/browser_sync/test_profile_sync_service.cc
index a4bc8d080bd..9eab474c7b8 100644
--- a/chromium/components/browser_sync/test_profile_sync_service.cc
+++ b/chromium/components/browser_sync/test_profile_sync_service.cc
@@ -6,6 +6,8 @@
#include <utility>
+#include "base/message_loop/message_loop.h"
+
namespace browser_sync {
syncer::TestIdFactory* TestProfileSyncService::id_factory() {
diff --git a/chromium/components/browser_watcher/BUILD.gn b/chromium/components/browser_watcher/BUILD.gn
index ff857fe05ce..a45c0c83a1b 100644
--- a/chromium/components/browser_watcher/BUILD.gn
+++ b/chromium/components/browser_watcher/BUILD.gn
@@ -35,27 +35,26 @@ if (is_win) {
"watcher_metrics_provider_win.h",
]
deps = [
- ":postmortem_report_collector",
- ":stability",
+ ":postmortem_stability",
+ ":stability_client",
"//base",
"//components/metrics",
"//third_party/crashpad/crashpad/client",
]
}
- static_library("postmortem_report_collector") {
+ static_library("postmortem_stability") {
sources = [
"postmortem_minidump_writer.h",
"postmortem_minidump_writer_win.cc",
"postmortem_report_collector.cc",
"postmortem_report_collector.h",
- "postmortem_report_extractor.cc",
- "postmortem_report_extractor.h",
"system_session_analyzer_win.cc",
"system_session_analyzer_win.h",
]
deps = [
- ":stability_data",
+ ":stability_client",
+ ":stability_common",
":stability_report_proto",
"//base",
"//components/variations",
@@ -66,28 +65,57 @@ if (is_win) {
libs = [ "wevtapi.lib" ]
ldflags = [ "/DELAYLOAD:wevtapi.dll" ] # Only used after unclean shutdowns.
}
-}
-static_library("stability") {
- sources = [
- "features.cc",
- "features.h",
- "stability_debugging.cc",
- "stability_debugging.h",
- ]
- deps = [
- "//base",
- ]
-}
+ static_library("crash_stability") {
+ sources = [
+ "stability_report_user_stream_data_source.cc",
+ "stability_report_user_stream_data_source.h",
+ ]
+ deps = [
+ ":stability_client",
+ ":stability_common",
+ ":stability_report_proto",
+ "//base",
+ "//third_party/crashpad/crashpad/client",
+ "//third_party/crashpad/crashpad/compat",
+ "//third_party/crashpad/crashpad/handler:handler_lib",
+ "//third_party/crashpad/crashpad/minidump",
+ "//third_party/crashpad/crashpad/snapshot",
+ ]
+ }
-static_library("stability_data") {
- sources = [
- "stability_data_names.cc",
- "stability_data_names.h",
- ]
-}
+ static_library("stability_common") {
+ sources = [
+ "minidump_user_streams.h",
+ "stability_report_extractor.cc",
+ "stability_report_extractor.h",
+ ]
+ deps = [
+ ":stability_client",
+ ":stability_report_proto",
+ "//base",
+ "//components/variations",
+ "//third_party/crashpad/crashpad/util",
+ ]
+ }
+
+ static_library("stability_client") {
+ sources = [
+ "features.cc",
+ "features.h",
+ "stability_data_names.cc",
+ "stability_data_names.h",
+ "stability_debugging.cc",
+ "stability_debugging.h",
+ "stability_paths.cc",
+ "stability_paths.h",
+ ]
+ deps = [
+ "//base",
+ "//third_party/crashpad/crashpad/util",
+ ]
+ }
-if (is_win) {
source_set("unit_tests") {
testonly = true
sources = [
@@ -95,6 +123,7 @@ if (is_win) {
"exit_code_watcher_win_unittest.cc",
"postmortem_minidump_writer_win_unittest.cc",
"postmortem_report_collector_unittest.cc",
+ "stability_debugging_win_unittest.cc",
"system_session_analyzer_win_unittest.cc",
"watcher_client_win_unittest.cc",
"watcher_metrics_provider_win_unittest.cc",
@@ -104,8 +133,9 @@ if (is_win) {
deps = [
":browser_watcher",
":browser_watcher_client",
- ":postmortem_report_collector",
- ":stability_data",
+ ":postmortem_stability",
+ ":stability_client",
+ ":stability_common",
":stability_report_proto",
"//base",
"//base/test:test_support",
@@ -114,16 +144,15 @@ if (is_win) {
"//third_party/crashpad/crashpad/client",
# TODO(manzagop): remove this lib once Crashpad writes the minidumps.
- "//third_party/crashpad/crashpad/compat",
"//third_party/crashpad/crashpad/minidump",
"//third_party/crashpad/crashpad/snapshot",
"//third_party/crashpad/crashpad/util",
]
}
- executable("dump_postmortem") {
+ executable("dump_stability") {
sources = [
- "dump_postmortem_minidump_main_win.cc",
+ "dump_stability_report_main_win.cc",
]
deps = [
":stability_report_proto",
@@ -136,7 +165,7 @@ if (is_win) {
"fetch_system_session_events_main_win.cc",
]
deps = [
- ":postmortem_report_collector",
+ ":postmortem_stability",
"//base",
]
}
diff --git a/chromium/components/browser_watcher/dump_postmortem_minidump_main_win.cc b/chromium/components/browser_watcher/dump_stability_report_main_win.cc
index 7a4bdb1331a..2b3be12eb24 100644
--- a/chromium/components/browser_watcher/dump_postmortem_minidump_main_win.cc
+++ b/chromium/components/browser_watcher/dump_stability_report_main_win.cc
@@ -5,6 +5,7 @@
// A utility for printing the contents of a postmortem stability minidump.
#include <windows.h> // NOLINT
+
#include <dbghelp.h>
#include "base/command_line.h"
@@ -158,6 +159,30 @@ void PrintReport(FILE* out, const browser_watcher::StabilityReport& report) {
}
}
+bool GetStabilityStreamRvaAndSize(RVA directory_rva,
+ ULONG32 stream_count,
+ FILE* file,
+ RVA* report_rva,
+ ULONG32* report_size_bytes) {
+ std::vector<MINIDUMP_DIRECTORY> directory;
+ directory.resize(stream_count);
+
+ CHECK_EQ(0, fseek(file, directory_rva, SEEK_SET));
+ CHECK_EQ(stream_count, fread(directory.data(), sizeof(MINIDUMP_DIRECTORY),
+ stream_count, file));
+
+ for (const MINIDUMP_DIRECTORY& entry : directory) {
+ constexpr ULONG32 kStabilityStream = static_cast<ULONG32>(0x4B6B0002);
+ if (entry.StreamType == kStabilityStream) {
+ *report_rva = entry.Location.Rva;
+ *report_size_bytes = entry.Location.DataSize;
+ return true;
+ }
+ }
+
+ return false;
+}
+
int Main(int argc, char** argv) {
base::CommandLine::Init(argc, argv);
@@ -176,18 +201,14 @@ int Main(int argc, char** argv) {
MINIDUMP_HEADER header = {};
CHECK_EQ(1U, fread(&header, sizeof(header), 1U, minidump_file.get()));
CHECK_EQ(static_cast<ULONG32>(MINIDUMP_SIGNATURE), header.Signature);
- CHECK_EQ(2U, header.NumberOfStreams);
+ fprintf(stdout, "Number of streams: %u\n", header.NumberOfStreams);
RVA directory_rva = header.StreamDirectoryRva;
- // Read the directory entry for the stability report's stream.
- // Note: this hardcodes an expectation that the stability report is the first
- // encountered stream. This is acceptable for a debug tool.
- MINIDUMP_DIRECTORY directory = {};
- CHECK_EQ(0, fseek(minidump_file.get(), directory_rva, SEEK_SET));
- CHECK_EQ(1U, fread(&directory, sizeof(directory), 1U, minidump_file.get()));
- CHECK_EQ(static_cast<ULONG32>(0x4B6B0002), directory.StreamType);
- RVA report_rva = directory.Location.Rva;
- ULONG32 report_size_bytes = directory.Location.DataSize;
+ RVA report_rva;
+ ULONG32 report_size_bytes;
+ CHECK(GetStabilityStreamRvaAndSize(directory_rva, header.NumberOfStreams,
+ minidump_file.get(), &report_rva,
+ &report_size_bytes));
// Read the serialized stability report.
std::string serialized_report;
diff --git a/chromium/components/browser_watcher/minidump_user_streams.h b/chromium/components/browser_watcher/minidump_user_streams.h
new file mode 100644
index 00000000000..a6c6ecf3123
--- /dev/null
+++ b/chromium/components/browser_watcher/minidump_user_streams.h
@@ -0,0 +1,18 @@
+// Copyright 2017 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_BROWSER_WATCHER_MINIDUMP_USER_STREAMS_H_
+#define COMPONENTS_BROWSER_WATCHER_MINIDUMP_USER_STREAMS_H_
+
+namespace browser_watcher {
+
+// The stream type assigned to the minidump stream that holds the serialized
+// stability report.
+// Note: the value was obtained by adding 1 to the stream type used for holding
+// the SyzyAsan proto.
+constexpr uint32_t kStabilityReportStreamType = 0x4B6B0002;
+
+} // namespace browser_watcher
+
+#endif // COMPONENTS_BROWSER_WATCHER_MINIDUMP_USER_STREAMS_H_
diff --git a/chromium/components/browser_watcher/postmortem_minidump_writer_win.cc b/chromium/components/browser_watcher/postmortem_minidump_writer_win.cc
index f22827ff598..30222db2ce9 100644
--- a/chromium/components/browser_watcher/postmortem_minidump_writer_win.cc
+++ b/chromium/components/browser_watcher/postmortem_minidump_writer_win.cc
@@ -22,6 +22,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_math.h"
#include "base/strings/string_piece.h"
+#include "components/browser_watcher/minidump_user_streams.h"
#include "components/browser_watcher/stability_data_names.h"
#include "third_party/crashpad/crashpad/minidump/minidump_extensions.h"
@@ -29,13 +30,6 @@ namespace browser_watcher {
namespace {
-// The stream type assigned to the minidump stream that holds the serialized
-// stability report.
-// Note: the value was obtained by adding 1 to the stream type used for holding
-// the SyzyAsan proto.
-// TODO(manzagop): centralize the stream type definitions to avoid issues.
-const uint32_t kStabilityReportStreamType = 0x4B6B0002;
-
struct ProductDetails {
std::string product;
std::string channel;
diff --git a/chromium/components/browser_watcher/postmortem_report_collector.cc b/chromium/components/browser_watcher/postmortem_report_collector.cc
index 35cc7b455b3..8929fe46fc1 100644
--- a/chromium/components/browser_watcher/postmortem_report_collector.cc
+++ b/chromium/components/browser_watcher/postmortem_report_collector.cc
@@ -53,6 +53,11 @@ bool GetStartTimestamp(
return true;
}
+void LogCollectionStatus(CollectionStatus status) {
+ UMA_HISTOGRAM_ENUMERATION("ActivityTracker.Collect.Status", status,
+ COLLECTION_STATUS_MAX);
+}
+
} // namespace
PostmortemReportCollector::PostmortemReportCollector(
@@ -91,19 +96,31 @@ int PostmortemReportCollector::CollectAndSubmitAllPendingReports(
settings->GetClientID(&client_id);
}
+ // Number of unclean shutdowns based on successful collection of stability
+ // reports.
+ int unclean_cnt = 0;
+ // Number of unclean shutdowns that may be attributable to system instability
+ // based on successful collection of stability reports. This number should be
+ // smaller or equal to |unclean_cnt|.
+ int unclean_system_cnt = 0;
+
// Process each stability file.
- int success_cnt = 0;
for (const FilePath& file : debug_files) {
- CollectionStatus status =
- CollectAndSubmitOneReport(client_id, file, report_database);
- // TODO(manzagop): consider making this a stability metric.
- UMA_HISTOGRAM_ENUMERATION("ActivityTracker.Collect.Status", status,
- COLLECTION_STATUS_MAX);
- if (status == SUCCESS)
- ++success_cnt;
+ bool system_unclean = false;
+ if (CollectAndSubmitOneReport(client_id, file, report_database,
+ &system_unclean)) {
+ ++unclean_cnt;
+ if (system_unclean)
+ ++unclean_system_cnt;
+ }
}
- return success_cnt;
+ UMA_STABILITY_HISTOGRAM_COUNTS_100(
+ "ActivityTracker.Collect.UncleanShutdownCount", unclean_cnt);
+ UMA_STABILITY_HISTOGRAM_COUNTS_100(
+ "ActivityTracker.Collect.UncleanSystemCount", unclean_system_cnt);
+
+ return unclean_cnt;
}
std::vector<FilePath> PostmortemReportCollector::GetDebugStateFilePaths(
@@ -125,11 +142,14 @@ std::vector<FilePath> PostmortemReportCollector::GetDebugStateFilePaths(
return paths;
}
-CollectionStatus PostmortemReportCollector::CollectAndSubmitOneReport(
+bool PostmortemReportCollector::CollectAndSubmitOneReport(
const crashpad::UUID& client_id,
const FilePath& file,
- crashpad::CrashReportDatabase* report_database) {
+ crashpad::CrashReportDatabase* report_database,
+ bool* system_unclean) {
DCHECK_NE(nullptr, report_database);
+ DCHECK_NE(nullptr, system_unclean);
+ *system_unclean = false;
// Note: the code below involves two notions of report: chrome internal state
// reports and the crashpad reports they get wrapped into.
@@ -143,7 +163,8 @@ CollectionStatus PostmortemReportCollector::CollectAndSubmitOneReport(
// logging happens within the Collect function.
if (!base::DeleteFile(file, false))
DLOG(ERROR) << "Failed to delete " << file.value();
- return status;
+ LogCollectionStatus(status);
+ return false;
}
// Prepare a crashpad report.
@@ -153,7 +174,8 @@ CollectionStatus PostmortemReportCollector::CollectAndSubmitOneReport(
if (database_status != CrashReportDatabase::kNoError) {
// Assume this is recoverable: not deleting the file.
DLOG(ERROR) << "PrepareNewCrashReport failed";
- return PREPARE_NEW_CRASH_REPORT_FAILED;
+ LogCollectionStatus(PREPARE_NEW_CRASH_REPORT_FAILED);
+ return false;
}
CrashReportDatabase::CallErrorWritingCrashReport
call_error_writing_crash_report(report_database, new_report);
@@ -164,7 +186,8 @@ CollectionStatus PostmortemReportCollector::CollectAndSubmitOneReport(
// Assume this is not recoverable and delete the file.
if (!base::DeleteFile(file, false))
DLOG(ERROR) << "Failed to delete " << file.value();
- return WRITE_TO_MINIDUMP_FAILED;
+ LogCollectionStatus(WRITE_TO_MINIDUMP_FAILED);
+ return false;
}
// If the file cannot be deleted, do not report its contents. Note this can
@@ -174,7 +197,8 @@ CollectionStatus PostmortemReportCollector::CollectAndSubmitOneReport(
// TODO(manzagop): metrics for the number of non-deletable files.
if (!base::DeleteFile(file, false)) {
DLOG(ERROR) << "Failed to delete " << file.value();
- return DEBUG_FILE_DELETION_FAILED;
+ LogCollectionStatus(DEBUG_FILE_DELETION_FAILED);
+ return false;
}
// Finalize the report wrt the report database. Note that this doesn't trigger
@@ -186,10 +210,15 @@ CollectionStatus PostmortemReportCollector::CollectAndSubmitOneReport(
new_report, &unused_report_id);
if (database_status != CrashReportDatabase::kNoError) {
DLOG(ERROR) << "FinishedWritingCrashReport failed";
- return FINISHED_WRITING_CRASH_REPORT_FAILED;
+ LogCollectionStatus(FINISHED_WRITING_CRASH_REPORT_FAILED);
+ return false;
}
- return SUCCESS;
+ // Report collection is successful. We may increment |unclean_system_cnt|.
+ if (report_proto.system_state().session_state() == SystemState::UNCLEAN)
+ *system_unclean = true;
+
+ return true;
}
CollectionStatus PostmortemReportCollector::CollectOneReport(
diff --git a/chromium/components/browser_watcher/postmortem_report_collector.h b/chromium/components/browser_watcher/postmortem_report_collector.h
index 000b14ebbfb..01871812ede 100644
--- a/chromium/components/browser_watcher/postmortem_report_collector.h
+++ b/chromium/components/browser_watcher/postmortem_report_collector.h
@@ -21,8 +21,8 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/strings/string16.h"
-#include "components/browser_watcher/postmortem_report_extractor.h"
#include "components/browser_watcher/stability_report.pb.h"
+#include "components/browser_watcher/stability_report_extractor.h"
#include "components/browser_watcher/system_session_analyzer_win.h"
#include "third_party/crashpad/crashpad/client/crash_report_database.h"
@@ -87,10 +87,12 @@ class PostmortemReportCollector {
const base::FilePath::StringType& debug_file_pattern,
const std::set<base::FilePath>& excluded_debug_files);
- CollectionStatus CollectAndSubmitOneReport(
- const crashpad::UUID& client_id,
- const base::FilePath& file,
- crashpad::CrashReportDatabase* report_database);
+ // Collects a stability file, generates a report and registers it with the
+ // database. Returns true on success. False otherwise.
+ bool CollectAndSubmitOneReport(const crashpad::UUID& client_id,
+ const base::FilePath& file,
+ crashpad::CrashReportDatabase* report_database,
+ bool* system_unclean);
virtual CollectionStatus CollectOneReport(
const base::FilePath& stability_file,
diff --git a/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc b/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc
index a022c820e4b..791a6cb070b 100644
--- a/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc
+++ b/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc
@@ -24,9 +24,10 @@
#include "base/metrics/persistent_memory_allocator.h"
#include "base/process/process_handle.h"
#include "base/stl_util.h"
+#include "base/test/histogram_tester.h"
#include "base/threading/platform_thread.h"
-#include "components/browser_watcher/postmortem_report_extractor.h"
#include "components/browser_watcher/stability_data_names.h"
+#include "components/browser_watcher/stability_report_extractor.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/crashpad/crashpad/client/crash_report_database.h"
@@ -47,6 +48,7 @@ using crashpad::CrashReportDatabase;
using crashpad::Settings;
using crashpad::UUID;
using testing::_;
+using testing::DoAll;
using testing::Return;
using testing::SetArgPointee;
@@ -165,8 +167,7 @@ MATCHER_P(EqualsProto, message, "") {
class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest
: public testing::Test {
public:
- void SetUp() override {
- testing::Test::SetUp();
+ void SetUpTest(bool system_session_clean) {
// Create a dummy debug file.
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
debug_file_ = temp_dir_.GetPath().AppendASCII("foo-1.pma");
@@ -188,9 +189,12 @@ class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest
EXPECT_CALL(database_, GetSettings()).Times(1).WillOnce(Return(nullptr));
// Expect a single collection call.
+ StabilityReport report;
+ report.mutable_system_state()->set_session_state(
+ system_session_clean ? SystemState::CLEAN : SystemState::UNCLEAN);
EXPECT_CALL(collector_, CollectOneReport(debug_file_, _))
.Times(1)
- .WillOnce(Return(SUCCESS));
+ .WillOnce(DoAll(SetArgPointee<1>(report), Return(SUCCESS)));
// Expect the call to write the proto to a minidump. This involves
// requesting a report from the crashpad database, writing the report, then
@@ -212,8 +216,37 @@ class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest
.Times(1)
.WillOnce(Return(true));
}
+ void ValidateHistograms(int unclean_cnt, int unclean_system_cnt) {
+ histogram_tester_.ExpectTotalCount(
+ "ActivityTracker.Collect.StabilityFileCount", 1);
+ histogram_tester_.ExpectBucketCount(
+ "ActivityTracker.Collect.StabilityFileCount", 1, 1);
+ histogram_tester_.ExpectTotalCount(
+ "ActivityTracker.Collect.UncleanShutdownCount", 1);
+ histogram_tester_.ExpectBucketCount(
+ "ActivityTracker.Collect.UncleanShutdownCount", unclean_cnt, 1);
+ histogram_tester_.ExpectTotalCount(
+ "ActivityTracker.Collect.UncleanSystemCount", 1);
+ histogram_tester_.ExpectBucketCount(
+ "ActivityTracker.Collect.UncleanSystemCount", unclean_system_cnt, 1);
+ }
+ void CollectReports(bool is_session_clean) {
+ SetUpTest(is_session_clean);
+
+ EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _))
+ .Times(1)
+ .WillOnce(Return(CrashReportDatabase::kNoError));
+
+ // Run the test.
+ int success_cnt = collector_.CollectAndSubmitAllPendingReports(
+ debug_file_.DirName(), debug_file_pattern_, no_excluded_files_,
+ &database_);
+ ASSERT_EQ(1, success_cnt);
+ ASSERT_FALSE(base::PathExists(debug_file_));
+ }
protected:
+ base::HistogramTester histogram_tester_;
base::ScopedTempDir temp_dir_;
base::FilePath debug_file_;
MockCrashReportDatabase database_;
@@ -224,21 +257,25 @@ class PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest
};
TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
- CollectAndSubmitAllPendingReports) {
- EXPECT_CALL(database_, FinishedWritingCrashReport(&crashpad_report_, _))
- .Times(1)
- .WillOnce(Return(CrashReportDatabase::kNoError));
+ CollectAndSubmitAllPendingReportsCleanSession) {
+ CollectReports(true);
+ int expected_unclean = 1;
+ int expected_system_unclean = 0;
+ ValidateHistograms(expected_unclean, expected_system_unclean);
+}
- // Run the test.
- int success_cnt = collector_.CollectAndSubmitAllPendingReports(
- debug_file_.DirName(), debug_file_pattern_, no_excluded_files_,
- &database_);
- ASSERT_EQ(1, success_cnt);
- ASSERT_FALSE(base::PathExists(debug_file_));
+TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
+ CollectAndSubmitAllPendingReportsUncleanSession) {
+ CollectReports(false);
+ int expected_unclean = 1;
+ int expected_system_unclean = 1;
+ ValidateHistograms(expected_unclean, expected_system_unclean);
}
TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
CollectAndSubmitAllPendingReportsStuckFile) {
+ SetUpTest(true);
+
// Open the stability debug file to prevent its deletion.
base::ScopedFILE file(base::OpenFile(debug_file_, "w"));
ASSERT_NE(file.get(), nullptr);
@@ -254,6 +291,10 @@ TEST_F(PostmortemReportCollectorCollectAndSubmitAllPendingReportsTest,
&database_);
ASSERT_EQ(0, success_cnt);
ASSERT_TRUE(base::PathExists(debug_file_));
+
+ int expected_unclean = 0;
+ int expected_system_unclean = 0;
+ ValidateHistograms(expected_unclean, expected_system_unclean);
}
TEST(PostmortemReportCollectorTest, GetDebugStateFilePaths) {
@@ -338,7 +379,7 @@ TEST(PostmortemReportCollectorTest, CollectRandomFile) {
PostmortemReportCollector collector(kProductName, kVersionNumber,
kChannelName, nullptr);
StabilityReport report;
- ASSERT_EQ(DEBUG_FILE_NO_DATA, collector.CollectOneReport(file_path, &report));
+ ASSERT_NE(SUCCESS, collector.CollectOneReport(file_path, &report));
}
namespace {
diff --git a/chromium/components/browser_watcher/stability_data_names.cc b/chromium/components/browser_watcher/stability_data_names.cc
index 63341220516..98efb8cfa01 100644
--- a/chromium/components/browser_watcher/stability_data_names.cc
+++ b/chromium/components/browser_watcher/stability_data_names.cc
@@ -8,12 +8,14 @@ namespace browser_watcher {
const char kStabilityChannel[] = "channel";
const char kStabilityExecutionPhase[] = "stability-execution-phase";
+const char kStabilityKeepAlive[] = "keep-alive";
const char kStabilityPlatform[] = "platform";
const char kStabilityProduct[] = "product";
const char kStabilityReporterChannel[] = "reporter-channel";
const char kStabilityReporterPlatform[] = "reporter-platform";
const char kStabilityReporterProduct[] = "reporter-product";
const char kStabilityReporterVersion[] = "reporter-version";
+const char kStabilityRestartAllowed[] = "restart-allowed";
const char kStabilitySpecialBuild[] = "special-build";
const char kStabilityStartTimestamp[] = "start-timestamp";
const char kStabilityVersion[] = "version";
diff --git a/chromium/components/browser_watcher/stability_data_names.h b/chromium/components/browser_watcher/stability_data_names.h
index 4ee91012b67..9ea312f551b 100644
--- a/chromium/components/browser_watcher/stability_data_names.h
+++ b/chromium/components/browser_watcher/stability_data_names.h
@@ -10,12 +10,14 @@ namespace browser_watcher {
// Alphabetical list of stability data names.
extern const char kStabilityChannel[];
extern const char kStabilityExecutionPhase[];
+extern const char kStabilityKeepAlive[];
extern const char kStabilityPlatform[];
extern const char kStabilityProduct[];
extern const char kStabilityReporterChannel[];
extern const char kStabilityReporterPlatform[];
extern const char kStabilityReporterProduct[];
extern const char kStabilityReporterVersion[];
+extern const char kStabilityRestartAllowed[];
extern const char kStabilitySpecialBuild[];
extern const char kStabilityStartTimestamp[];
extern const char kStabilityVersion[];
diff --git a/chromium/components/browser_watcher/stability_debugging.cc b/chromium/components/browser_watcher/stability_debugging.cc
index c7919d2b773..3c8cc649292 100644
--- a/chromium/components/browser_watcher/stability_debugging.cc
+++ b/chromium/components/browser_watcher/stability_debugging.cc
@@ -4,92 +4,18 @@
#include "components/browser_watcher/stability_debugging.h"
-#include <string>
-
#include "base/debug/activity_tracker.h"
-#include "base/feature_list.h"
-#include "base/files/file.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/path_service.h"
-#include "base/process/process.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "components/browser_watcher/features.h"
namespace browser_watcher {
-namespace {
-
-#if defined(OS_WIN)
-bool GetCreationTime(const base::Process& process, base::Time* time) {
- DCHECK(time);
-
- FILETIME creation_time = {};
- FILETIME ignore1 = {};
- FILETIME ignore2 = {};
- FILETIME ignore3 = {};
- if (!::GetProcessTimes(process.Handle(), &creation_time, &ignore1, &ignore2,
- &ignore3)) {
- return false;
- }
- *time = base::Time::FromFileTime(creation_time);
- return true;
-}
-#endif // defined(OS_WIN)
-
-} // namespace
-
-#if defined(OS_WIN)
-
-base::FilePath GetStabilityDir(const base::FilePath& user_data_dir) {
- return user_data_dir.AppendASCII("Stability");
-}
-
-bool GetStabilityFileForProcess(const base::Process& process,
- const base::FilePath& user_data_dir,
- base::FilePath* file_path) {
- DCHECK(file_path);
- base::FilePath stability_dir = GetStabilityDir(user_data_dir);
-
- // Build the name using the pid and creation time. On windows, this is unique
- // even after the process exits.
- base::Time creation_time;
- if (!GetCreationTime(process, &creation_time))
- return false;
-
- std::string file_name =
- base::StringPrintf("%u-%llu", process.Pid(), creation_time.ToJavaTime());
- *file_path = stability_dir.AppendASCII(file_name).AddExtension(
- base::PersistentMemoryAllocator::kFileExtension);
- return true;
-}
-
-base::FilePath::StringType GetStabilityFilePattern() {
- return base::FilePath::StringType(FILE_PATH_LITERAL("*-*")) +
- base::PersistentMemoryAllocator::kFileExtension;
-}
-
-void MarkStabilityFileForDeletion(const base::FilePath& user_data_dir) {
- if (!base::FeatureList::IsEnabled(
- browser_watcher::kStabilityDebuggingFeature)) {
- return;
- }
-
- base::FilePath stability_file;
- if (!GetStabilityFileForProcess(base::Process::Current(), user_data_dir,
- &stability_file)) {
- // TODO(manzagop): add a metric for this.
- return;
- }
+void SetStabilityDataBool(base::StringPiece name, bool value) {
+ base::debug::GlobalActivityTracker* global_tracker =
+ base::debug::GlobalActivityTracker::Get();
+ if (!global_tracker)
+ return; // Activity tracking isn't enabled.
- // Open (with delete) and then immediately close the file by going out of
- // scope. This should cause the stability debugging file to be deleted prior
- // to the next execution.
- base::File file(stability_file, base::File::FLAG_OPEN |
- base::File::FLAG_READ |
- base::File::FLAG_DELETE_ON_CLOSE);
+ global_tracker->process_data().SetBool(name, value);
}
-#endif // defined(OS_WIN)
void SetStabilityDataInt(base::StringPiece name, int64_t value) {
base::debug::GlobalActivityTracker* global_tracker =
diff --git a/chromium/components/browser_watcher/stability_debugging.h b/chromium/components/browser_watcher/stability_debugging.h
index e8569417482..cc23f69f477 100644
--- a/chromium/components/browser_watcher/stability_debugging.h
+++ b/chromium/components/browser_watcher/stability_debugging.h
@@ -7,33 +7,12 @@
#include <stdint.h>
-#include "base/files/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "base/process/process.h"
#include "base/strings/string_piece.h"
namespace browser_watcher {
-#if defined(OS_WIN)
-
-// Returns the the stability debugging directory.
-base::FilePath GetStabilityDir(const base::FilePath& user_data_dir);
-
-// On success, |path| contains the path to the stability debugging information
-// file for |process|.
-bool GetStabilityFileForProcess(const base::Process& process,
- const base::FilePath& user_data_dir,
- base::FilePath* path);
-
-// Returns a pattern that matches file names returned by GetFileForProcess.
-base::FilePath::StringType GetStabilityFilePattern();
-
-// Marks the stability file for deletion.
-void MarkStabilityFileForDeletion(const base::FilePath& user_data_dir);
-
-#endif // defined(OS_WIN)
-
// Adds or updates the global stability user data.
+void SetStabilityDataBool(base::StringPiece name, bool value);
void SetStabilityDataInt(base::StringPiece name, int64_t value);
} // namespace browser_watcher
diff --git a/chromium/components/browser_watcher/stability_debugging_win_unittest.cc b/chromium/components/browser_watcher/stability_debugging_win_unittest.cc
index d1920109a06..785ab22be78 100644
--- a/chromium/components/browser_watcher/stability_debugging_win_unittest.cc
+++ b/chromium/components/browser_watcher/stability_debugging_win_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/browser_watcher/stability_debugging_win.h"
+#include "components/browser_watcher/stability_debugging.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
@@ -10,6 +10,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/process/process.h"
#include "base/test/multiprocess_test.h"
+#include "components/browser_watcher/stability_paths.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
@@ -36,8 +37,9 @@ TEST_F(StabilityDebuggingWinMultiProcTest, GetStabilityFileForProcessTest) {
EXPECT_EQ(stability_path, stability_path_two);
// Ensure a different process has a different stability path.
+ base::SpawnChildResult spawn_result = SpawnChild("DummyProcess");
base::FilePath stability_path_other;
- ASSERT_TRUE(GetStabilityFileForProcess(SpawnChild("DummyProcess"), empty_path,
+ ASSERT_TRUE(GetStabilityFileForProcess(spawn_result.process, empty_path,
&stability_path_other));
EXPECT_NE(stability_path, stability_path_other);
}
@@ -51,7 +53,7 @@ TEST(StabilityDebuggingWinTest,
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath user_data_dir = temp_dir.path();
+ base::FilePath user_data_dir = temp_dir.GetPath();
// Create the stability directory.
base::FilePath stability_dir = GetStabilityDir(user_data_dir);
diff --git a/chromium/components/browser_watcher/stability_paths.cc b/chromium/components/browser_watcher/stability_paths.cc
new file mode 100644
index 00000000000..66805fa67d1
--- /dev/null
+++ b/chromium/components/browser_watcher/stability_paths.cc
@@ -0,0 +1,98 @@
+// Copyright 2017 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/browser_watcher/stability_paths.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif // defined(OS_WIN)
+
+#include <string>
+
+#include "base/feature_list.h"
+#include "base/files/file.h"
+#include "base/metrics/persistent_memory_allocator.h"
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "components/browser_watcher/features.h"
+
+#if defined(OS_WIN)
+
+#include "third_party/crashpad/crashpad/util/win/time.h"
+
+namespace browser_watcher {
+namespace {
+
+bool GetCreationTime(const base::Process& process, FILETIME* creation_time) {
+ FILETIME ignore;
+ return ::GetProcessTimes(process.Handle(), creation_time, &ignore, &ignore,
+ &ignore) != 0;
+}
+
+} // namespace
+
+base::FilePath GetStabilityDir(const base::FilePath& user_data_dir) {
+ return user_data_dir.AppendASCII("Stability");
+}
+
+base::FilePath GetStabilityFileForProcess(base::ProcessId pid,
+ timeval creation_time,
+ const base::FilePath& user_data_dir) {
+ base::FilePath stability_dir = GetStabilityDir(user_data_dir);
+
+ constexpr uint64_t kMicrosecondsPerSecond = static_cast<uint64_t>(1E6);
+ int64_t creation_time_us =
+ creation_time.tv_sec * kMicrosecondsPerSecond + creation_time.tv_usec;
+
+ std::string file_name = base::StringPrintf("%u-%lld", pid, creation_time_us);
+ return stability_dir.AppendASCII(file_name).AddExtension(
+ base::PersistentMemoryAllocator::kFileExtension);
+}
+
+bool GetStabilityFileForProcess(const base::Process& process,
+ const base::FilePath& user_data_dir,
+ base::FilePath* file_path) {
+ DCHECK(file_path);
+
+ FILETIME creation_time;
+ if (!GetCreationTime(process, &creation_time))
+ return false;
+
+ // We rely on Crashpad's conversion to ensure the resulting filename is the
+ // same as on crash, when the creation time is obtained via Crashpad.
+ *file_path = GetStabilityFileForProcess(
+ process.Pid(), crashpad::FiletimeToTimevalEpoch(creation_time),
+ user_data_dir);
+ return true;
+}
+
+base::FilePath::StringType GetStabilityFilePattern() {
+ return base::FilePath::StringType(FILE_PATH_LITERAL("*-*")) +
+ base::PersistentMemoryAllocator::kFileExtension;
+}
+
+void MarkStabilityFileForDeletion(const base::FilePath& user_data_dir) {
+ if (!base::FeatureList::IsEnabled(
+ browser_watcher::kStabilityDebuggingFeature)) {
+ return;
+ }
+
+ base::FilePath stability_file;
+ if (!GetStabilityFileForProcess(base::Process::Current(), user_data_dir,
+ &stability_file)) {
+ // TODO(manzagop): add a metric for this.
+ return;
+ }
+
+ // Open (with delete) and then immediately close the file by going out of
+ // scope. This should cause the stability debugging file to be deleted prior
+ // to the next execution.
+ base::File file(stability_file, base::File::FLAG_OPEN |
+ base::File::FLAG_READ |
+ base::File::FLAG_DELETE_ON_CLOSE);
+}
+
+} // namespace browser_watcher
+
+#endif // defined(OS_WIN)
diff --git a/chromium/components/browser_watcher/stability_paths.h b/chromium/components/browser_watcher/stability_paths.h
new file mode 100644
index 00000000000..07216f1f75c
--- /dev/null
+++ b/chromium/components/browser_watcher/stability_paths.h
@@ -0,0 +1,45 @@
+// Copyright 2017 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_BROWSER_WATCHER_STABILITY_PATHS_H_
+#define COMPONENTS_BROWSER_WATCHER_STABILITY_PATHS_H_
+
+#include "base/files/file_path.h"
+#include "base/process/process.h"
+#include "build/build_config.h"
+
+#if defined(OS_WIN)
+#include <winsock2.h>
+#endif // defined(OS_WIN)
+
+namespace browser_watcher {
+
+#if defined(OS_WIN)
+
+// Returns the stability debugging directory.
+base::FilePath GetStabilityDir(const base::FilePath& user_data_dir);
+
+// Returns the stability debugging path, which is based on pid and creation time
+// to ensure uniqueness in the face of pid recycling.
+base::FilePath GetStabilityFileForProcess(base::ProcessId pid,
+ timeval creation_time,
+ const base::FilePath& user_data_dir);
+
+// On success, returns true and |path| contains the path to the stability file.
+// On failure, returns false.
+bool GetStabilityFileForProcess(const base::Process& process,
+ const base::FilePath& user_data_dir,
+ base::FilePath* path);
+
+// Returns a pattern that matches file names returned by GetFileForProcess.
+base::FilePath::StringType GetStabilityFilePattern();
+
+// Marks the stability file for deletion.
+void MarkStabilityFileForDeletion(const base::FilePath& user_data_dir);
+
+#endif // defined(OS_WIN)
+
+} // namespace browser_watcher
+
+#endif // COMPONENTS_BROWSER_WATCHER_STABILITY_PATHS_H_
diff --git a/chromium/components/browser_watcher/stability_report.proto b/chromium/components/browser_watcher/stability_report.proto
index 18ea17cd8dd..b1ca52e785c 100644
--- a/chromium/components/browser_watcher/stability_report.proto
+++ b/chromium/components/browser_watcher/stability_report.proto
@@ -187,8 +187,12 @@ message FieldTrial {
// A stability report contains information pertaining to the execution of a
// single logical instance of a "chrome browser". It is comprised of information
// about the system state and about the chrome browser's processes.
-// Next id: 6
+// Next id: 7
message StabilityReport {
+ // Whether the report is complete. Reports can be incomplete when the
+ // recording size quota is hit.
+ optional bool is_complete = 6;
+
optional SystemState system_state = 1;
// TODO(manzagop): revisit whether a single repeated field should contain all
// processes, or whether it's preferable to have separate fields per type.
diff --git a/chromium/components/browser_watcher/postmortem_report_extractor.cc b/chromium/components/browser_watcher/stability_report_extractor.cc
index d21abae3697..fd5c185efda 100644
--- a/chromium/components/browser_watcher/postmortem_report_extractor.cc
+++ b/chromium/components/browser_watcher/stability_report_extractor.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/browser_watcher/postmortem_report_extractor.h"
+#include "components/browser_watcher/stability_report_extractor.h"
#include <memory>
#include <string>
@@ -229,6 +229,8 @@ CollectionStatus Extract(const base::FilePath& stability_file,
return DEBUG_FILE_NO_DATA;
}
+ report->set_is_complete(global_analyzer->IsDataComplete());
+
// Collect log messages.
for (const std::string& message : log_messages) {
report->add_log_messages(message);
diff --git a/chromium/components/browser_watcher/postmortem_report_extractor.h b/chromium/components/browser_watcher/stability_report_extractor.h
index bc7186b191a..5ff90339e34 100644
--- a/chromium/components/browser_watcher/postmortem_report_extractor.h
+++ b/chromium/components/browser_watcher/stability_report_extractor.h
@@ -4,8 +4,8 @@
//
// Implementation of the collection of a stability file to a protocol buffer.
-#ifndef COMPONENTS_BROWSER_WATCHER_POSTMORTEM_REPORT_EXTRACTOR_H_
-#define COMPONENTS_BROWSER_WATCHER_POSTMORTEM_REPORT_EXTRACTOR_H_
+#ifndef COMPONENTS_BROWSER_WATCHER_STABILITY_REPORT_EXTRACTOR_H_
+#define COMPONENTS_BROWSER_WATCHER_STABILITY_REPORT_EXTRACTOR_H_
#include "base/files/file_path.h"
#include "components/browser_watcher/stability_report.pb.h"
@@ -33,4 +33,4 @@ CollectionStatus Extract(const base::FilePath& stability_file,
} // namespace browser_watcher
-#endif // COMPONENTS_BROWSER_WATCHER_POSTMORTEM_REPORT_EXTRACTOR_H_
+#endif // COMPONENTS_BROWSER_WATCHER_STABILITY_REPORT_EXTRACTOR_H_
diff --git a/chromium/components/browser_watcher/stability_report_user_stream_data_source.cc b/chromium/components/browser_watcher/stability_report_user_stream_data_source.cc
new file mode 100644
index 00000000000..62fdf2235ed
--- /dev/null
+++ b/chromium/components/browser_watcher/stability_report_user_stream_data_source.cc
@@ -0,0 +1,125 @@
+// Copyright 2017 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/browser_watcher/stability_report_user_stream_data_source.h"
+
+#include <string>
+#include <utility>
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/string16.h"
+#include "base/time/time.h"
+#include "components/browser_watcher/minidump_user_streams.h"
+#include "components/browser_watcher/stability_paths.h"
+#include "components/browser_watcher/stability_report_extractor.h"
+#include "third_party/crashpad/crashpad/minidump/minidump_user_extension_stream_data_source.h"
+#include "third_party/crashpad/crashpad/snapshot/process_snapshot.h"
+
+namespace browser_watcher {
+
+namespace {
+
+base::FilePath GetStabilityFileName(
+ const base::FilePath& user_data_dir,
+ crashpad::ProcessSnapshot* process_snapshot) {
+ DCHECK(process_snapshot);
+
+ timeval creation_time = {};
+ process_snapshot->ProcessStartTime(&creation_time);
+
+ return GetStabilityFileForProcess(process_snapshot->ProcessID(),
+ creation_time, user_data_dir);
+}
+
+class BufferExtensionStreamDataSource final
+ : public crashpad::MinidumpUserExtensionStreamDataSource {
+ public:
+ explicit BufferExtensionStreamDataSource(uint32_t stream_type);
+
+ bool Init(const StabilityReport& report);
+
+ size_t StreamDataSize() override;
+ bool ReadStreamData(Delegate* delegate) override;
+
+ private:
+ std::string data_;
+
+ DISALLOW_COPY_AND_ASSIGN(BufferExtensionStreamDataSource);
+};
+
+BufferExtensionStreamDataSource::BufferExtensionStreamDataSource(
+ uint32_t stream_type)
+ : crashpad::MinidumpUserExtensionStreamDataSource(stream_type) {}
+
+bool BufferExtensionStreamDataSource::Init(const StabilityReport& report) {
+ if (report.SerializeToString(&data_))
+ return true;
+ data_.clear();
+ return false;
+}
+
+size_t BufferExtensionStreamDataSource::StreamDataSize() {
+ DCHECK(!data_.empty());
+ return data_.size();
+}
+
+bool BufferExtensionStreamDataSource::ReadStreamData(Delegate* delegate) {
+ DCHECK(!data_.empty());
+ return delegate->ExtensionStreamDataSourceRead(
+ data_.size() ? data_.data() : nullptr, data_.size());
+}
+
+std::unique_ptr<BufferExtensionStreamDataSource> CollectReport(
+ const base::FilePath& path) {
+ StabilityReport report;
+ CollectionStatus status = Extract(path, &report);
+ UMA_HISTOGRAM_ENUMERATION("ActivityTracker.CollectCrash.Status", status,
+ COLLECTION_STATUS_MAX);
+ if (status != SUCCESS)
+ return nullptr;
+
+ // Open (with delete) and then immediately close the file by going out of
+ // scope. This should cause the stability debugging file to be deleted prior
+ // to the next execution.
+ // TODO(manzagop): set the persistent allocator file's state to deleted in
+ // case the file can't be deleted.
+ base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
+ base::File::FLAG_DELETE_ON_CLOSE);
+ UMA_HISTOGRAM_BOOLEAN("ActivityTracker.CollectCrash.OpenForDeleteSuccess",
+ file.IsValid());
+
+ std::unique_ptr<BufferExtensionStreamDataSource> source(
+ new BufferExtensionStreamDataSource(kStabilityReportStreamType));
+ return source->Init(report) ? std::move(source) : nullptr;
+}
+
+} // namespace
+
+StabilityReportUserStreamDataSource::StabilityReportUserStreamDataSource(
+ const base::FilePath& user_data_dir)
+ : user_data_dir_(user_data_dir) {}
+
+std::unique_ptr<crashpad::MinidumpUserExtensionStreamDataSource>
+StabilityReportUserStreamDataSource::ProduceStreamData(
+ crashpad::ProcessSnapshot* process_snapshot) {
+ DCHECK(process_snapshot);
+
+ if (user_data_dir_.empty())
+ return nullptr;
+
+ base::FilePath stability_file =
+ GetStabilityFileName(user_data_dir_, process_snapshot);
+ if (!PathExists(stability_file)) {
+ // Either this is not an instrumented process (currently only browser
+ // processes can be instrumented), or the stability file cannot be found.
+ return nullptr;
+ }
+
+ return CollectReport(stability_file);
+}
+
+} // namespace browser_watcher
diff --git a/chromium/components/browser_watcher/stability_report_user_stream_data_source.h b/chromium/components/browser_watcher/stability_report_user_stream_data_source.h
new file mode 100644
index 00000000000..e9036cdfe42
--- /dev/null
+++ b/chromium/components/browser_watcher/stability_report_user_stream_data_source.h
@@ -0,0 +1,40 @@
+// Copyright 2017 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_BROWSER_WATCHER_STABILITY_REPORT_USER_STREAM_DATA_SOURCE_H_
+#define COMPONENTS_BROWSER_WATCHER_STABILITY_REPORT_USER_STREAM_DATA_SOURCE_H_
+
+#include <memory>
+
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "third_party/crashpad/crashpad/handler/user_stream_data_source.h"
+
+namespace crashpad {
+class MinidumpUserExtensionStreamDataSource;
+class ProcessSnapshot;
+}
+
+namespace browser_watcher {
+
+// Collects stability instrumentation corresponding to a ProcessSnapshot and
+// makes it available to the crash handler.
+class StabilityReportUserStreamDataSource
+ : public crashpad::UserStreamDataSource {
+ public:
+ explicit StabilityReportUserStreamDataSource(
+ const base::FilePath& user_data_dir);
+
+ std::unique_ptr<crashpad::MinidumpUserExtensionStreamDataSource>
+ ProduceStreamData(crashpad::ProcessSnapshot* process_snapshot) override;
+
+ private:
+ base::FilePath user_data_dir_;
+
+ DISALLOW_COPY_AND_ASSIGN(StabilityReportUserStreamDataSource);
+};
+
+} // namespace browser_watcher
+
+#endif // COMPONENTS_BROWSER_WATCHER_STABILITY_REPORT_USER_STREAM_DATA_SOURCE_H_
diff --git a/chromium/components/browser_watcher/watcher_metrics_provider_win.cc b/chromium/components/browser_watcher/watcher_metrics_provider_win.cc
index 45617eb176c..6376079ba23 100644
--- a/chromium/components/browser_watcher/watcher_metrics_provider_win.cc
+++ b/chromium/components/browser_watcher/watcher_metrics_provider_win.cc
@@ -25,7 +25,7 @@
#include "base/win/registry.h"
#include "components/browser_watcher/features.h"
#include "components/browser_watcher/postmortem_report_collector.h"
-#include "components/browser_watcher/stability_debugging.h"
+#include "components/browser_watcher/stability_paths.h"
#include "components/browser_watcher/system_session_analyzer_win.h"
#include "third_party/crashpad/crashpad/client/crash_report_database.h"
diff --git a/chromium/components/browser_watcher/window_hang_monitor_win_unittest.cc b/chromium/components/browser_watcher/window_hang_monitor_win_unittest.cc
index a8ce37ad4b1..2df2a7b5a1c 100644
--- a/chromium/components/browser_watcher/window_hang_monitor_win_unittest.cc
+++ b/chromium/components/browser_watcher/window_hang_monitor_win_unittest.cc
@@ -9,6 +9,7 @@
#include "base/base_paths.h"
#include "base/base_switches.h"
#include "base/command_line.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
diff --git a/chromium/components/browsing_data/content/conditional_cache_counting_helper.cc b/chromium/components/browsing_data/content/conditional_cache_counting_helper.cc
index 05f4f17d493..3cbf8c7ac16 100644
--- a/chromium/components/browsing_data/content/conditional_cache_counting_helper.cc
+++ b/chromium/components/browsing_data/content/conditional_cache_counting_helper.cc
@@ -74,7 +74,7 @@ void ConditionalCacheCountingHelper::Finished() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!is_finished_);
is_finished_ = true;
- result_callback_.Run(calculation_result_, is_upper_limit_);
+ result_callback_.Run(is_upper_limit_, calculation_result_);
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
diff --git a/chromium/components/browsing_data/content/conditional_cache_counting_helper.h b/chromium/components/browsing_data/content/conditional_cache_counting_helper.h
index 5a071b78c6c..0bca3f36478 100644
--- a/chromium/components/browsing_data/content/conditional_cache_counting_helper.h
+++ b/chromium/components/browsing_data/content/conditional_cache_counting_helper.h
@@ -25,9 +25,9 @@ namespace browsing_data {
// Helper to count the size of the http cache data from a StoragePartition.
class ConditionalCacheCountingHelper {
public:
- // Returns the number bytes in the selected range and if this value is an
- // upper estimate.
- typedef base::Callback<void(int64_t, bool)> CacheCountCallback;
+ // Returns if this value is an upper estimate and the number bytes in the
+ // selected range.
+ typedef base::Callback<void(bool, int64_t)> CacheCountCallback;
static ConditionalCacheCountingHelper* CreateForRange(
content::StoragePartition* storage_partition,
diff --git a/chromium/components/browsing_data/core/BUILD.gn b/chromium/components/browsing_data/core/BUILD.gn
index dd140ce5012..c2761d75a39 100644
--- a/chromium/components/browsing_data/core/BUILD.gn
+++ b/chromium/components/browsing_data/core/BUILD.gn
@@ -19,6 +19,8 @@ static_library("core") {
"counters/history_counter.h",
"counters/passwords_counter.cc",
"counters/passwords_counter.h",
+ "counters/site_settings_counter.cc",
+ "counters/site_settings_counter.h",
"history_notice_utils.cc",
"history_notice_utils.h",
"pref_names.cc",
@@ -28,6 +30,8 @@ static_library("core") {
deps = [
"//base",
"//components/autofill/core/browser",
+ "//components/content_settings/core/browser:browser",
+ "//components/content_settings/core/common:common",
"//components/history/core/browser",
"//components/password_manager/core/browser",
"//components/pref_registry:pref_registry",
@@ -66,6 +70,7 @@ source_set("unit_tests") {
"//base",
"//components/autofill/core/browser:browser",
"//components/history/core/test:test",
+ "//components/password_manager/core/browser:test_support",
"//components/signin/core/browser:test_support",
"//components/sync",
"//components/sync:test_support_driver",
diff --git a/chromium/components/browsing_data/core/DEPS b/chromium/components/browsing_data/core/DEPS
index a28b230b9a2..c8a900dd7de 100644
--- a/chromium/components/browsing_data/core/DEPS
+++ b/chromium/components/browsing_data/core/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+components/autofill/core/browser",
"+components/browser_sync",
+ "+components/content_settings",
"+components/history/core/browser",
"+components/history/core/test",
"+components/password_manager/core/browser",
diff --git a/chromium/components/browsing_data/core/browsing_data_utils.cc b/chromium/components/browsing_data/core/browsing_data_utils.cc
index 9f1f34fb468..ea7e7bb5cb4 100644
--- a/chromium/components/browsing_data/core/browsing_data_utils.cc
+++ b/chromium/components/browsing_data/core/browsing_data_utils.cc
@@ -66,7 +66,7 @@ void RecordDeletionForPeriod(TimePeriod period) {
}
base::string16 GetCounterTextFromResult(
- const browsing_data::BrowsingDataCounter::Result* result) {
+ const BrowsingDataCounter::Result* result) {
base::string16 text;
std::string pref_name = result->source()->GetPrefName();
@@ -74,28 +74,35 @@ base::string16 GetCounterTextFromResult(
// The counter is still counting.
text = l10n_util::GetStringUTF16(IDS_CLEAR_BROWSING_DATA_CALCULATING);
- } else if (pref_name == browsing_data::prefs::kDeletePasswords ||
- pref_name == browsing_data::prefs::kDeleteDownloadHistory) {
- // Counters with trivially formatted result: passwords and downloads.
- browsing_data::BrowsingDataCounter::ResultInt count =
- static_cast<const browsing_data::BrowsingDataCounter::FinishedResult*>(
- result)
- ->Value();
+ } else if (pref_name == prefs::kDeletePasswords) {
+ const BrowsingDataCounter::SyncResult* password_result =
+ static_cast<const BrowsingDataCounter::SyncResult*>(result);
+
+ BrowsingDataCounter::ResultInt count = password_result->Value();
+
text = l10n_util::GetPluralStringFUTF16(
- pref_name == browsing_data::prefs::kDeletePasswords
- ? IDS_DEL_PASSWORDS_COUNTER
- : IDS_DEL_DOWNLOADS_COUNTER,
+ password_result->is_sync_enabled() ? IDS_DEL_PASSWORDS_COUNTER_SYNCED
+ : IDS_DEL_PASSWORDS_COUNTER,
count);
- } else if (pref_name == browsing_data::prefs::kDeleteBrowsingHistoryBasic) {
+ } else if (pref_name == prefs::kDeleteDownloadHistory) {
+ BrowsingDataCounter::ResultInt count =
+ static_cast<const BrowsingDataCounter::FinishedResult*>(result)
+ ->Value();
+ text = l10n_util::GetPluralStringFUTF16(IDS_DEL_DOWNLOADS_COUNTER, count);
+ } else if (pref_name == prefs::kDeleteSiteSettings) {
+ BrowsingDataCounter::ResultInt count =
+ static_cast<const BrowsingDataCounter::FinishedResult*>(result)
+ ->Value();
+ text =
+ l10n_util::GetPluralStringFUTF16(IDS_DEL_SITE_SETTINGS_COUNTER, count);
+ } else if (pref_name == prefs::kDeleteBrowsingHistoryBasic) {
// The basic tab doesn't show history counter results.
NOTREACHED();
- } else if (pref_name == browsing_data::prefs::kDeleteBrowsingHistory) {
+ } else if (pref_name == prefs::kDeleteBrowsingHistory) {
// History counter.
- const browsing_data::HistoryCounter::HistoryResult* history_result =
- static_cast<const browsing_data::HistoryCounter::HistoryResult*>(
- result);
- browsing_data::BrowsingDataCounter::ResultInt local_item_count =
- history_result->Value();
+ const HistoryCounter::HistoryResult* history_result =
+ static_cast<const HistoryCounter::HistoryResult*>(result);
+ BrowsingDataCounter::ResultInt local_item_count = history_result->Value();
bool has_synced_visits = history_result->has_synced_visits();
text = has_synced_visits
? l10n_util::GetPluralStringFUTF16(
@@ -103,17 +110,14 @@ base::string16 GetCounterTextFromResult(
: l10n_util::GetPluralStringFUTF16(
IDS_DEL_BROWSING_HISTORY_COUNTER, local_item_count);
- } else if (pref_name == browsing_data::prefs::kDeleteFormData) {
+ } else if (pref_name == prefs::kDeleteFormData) {
// Autofill counter.
- const browsing_data::AutofillCounter::AutofillResult* autofill_result =
- static_cast<const browsing_data::AutofillCounter::AutofillResult*>(
- result);
- browsing_data::AutofillCounter::ResultInt num_suggestions =
- autofill_result->Value();
- browsing_data::AutofillCounter::ResultInt num_credit_cards =
+ const AutofillCounter::AutofillResult* autofill_result =
+ static_cast<const AutofillCounter::AutofillResult*>(result);
+ AutofillCounter::ResultInt num_suggestions = autofill_result->Value();
+ AutofillCounter::ResultInt num_credit_cards =
autofill_result->num_credit_cards();
- browsing_data::AutofillCounter::ResultInt num_addresses =
- autofill_result->num_addresses();
+ AutofillCounter::ResultInt num_addresses = autofill_result->num_addresses();
std::vector<base::string16> displayed_strings;
@@ -146,23 +150,30 @@ base::string16 GetCounterTextFromResult(
}
}
+ bool synced = autofill_result->is_sync_enabled();
+
// Construct the resulting string from the sections in |displayed_strings|.
switch (displayed_strings.size()) {
case 0:
text = l10n_util::GetStringUTF16(IDS_DEL_AUTOFILL_COUNTER_EMPTY);
break;
case 1:
- text = displayed_strings[0];
+ text = synced ? l10n_util::GetStringFUTF16(
+ IDS_DEL_AUTOFILL_COUNTER_ONE_TYPE_SYNCED,
+ displayed_strings[0])
+ : displayed_strings[0];
break;
case 2:
- text = l10n_util::GetStringFUTF16(IDS_DEL_AUTOFILL_COUNTER_TWO_TYPES,
- displayed_strings[0],
- displayed_strings[1]);
+ text = l10n_util::GetStringFUTF16(
+ synced ? IDS_DEL_AUTOFILL_COUNTER_TWO_TYPES_SYNCED
+ : IDS_DEL_AUTOFILL_COUNTER_TWO_TYPES,
+ displayed_strings[0], displayed_strings[1]);
break;
case 3:
text = l10n_util::GetStringFUTF16(
- IDS_DEL_AUTOFILL_COUNTER_THREE_TYPES, displayed_strings[0],
- displayed_strings[1], displayed_strings[2]);
+ synced ? IDS_DEL_AUTOFILL_COUNTER_THREE_TYPES_SYNCED
+ : IDS_DEL_AUTOFILL_COUNTER_THREE_TYPES,
+ displayed_strings[0], displayed_strings[1], displayed_strings[2]);
break;
default:
NOTREACHED();
@@ -220,6 +231,9 @@ bool GetDeletionPreferenceFromDataType(
// Bookmarks are deleted on the Android side. No corresponding deletion
// preference.
return false;
+ case BrowsingDataType::SITE_SETTINGS:
+ *out_pref = prefs::kDeleteSiteSettings;
+ return true;
case BrowsingDataType::NUM_TYPES:
// This is not an actual type.
NOTREACHED();
diff --git a/chromium/components/browsing_data/core/browsing_data_utils.h b/chromium/components/browsing_data/core/browsing_data_utils.h
index 97cc7b1273e..3e087f8cf1e 100644
--- a/chromium/components/browsing_data/core/browsing_data_utils.h
+++ b/chromium/components/browsing_data/core/browsing_data_utils.h
@@ -25,6 +25,7 @@ enum class BrowsingDataType {
PASSWORDS,
FORM_DATA,
BOOKMARKS,
+ SITE_SETTINGS,
NUM_TYPES
};
@@ -51,8 +52,8 @@ base::Time CalculateEndDeleteTime(TimePeriod time_period);
void RecordDeletionForPeriod(TimePeriod time_period);
// Constructs the text to be displayed by a counter from the given |result|.
-// Currently this can only be used for counters for which the Result is defined
-// in components/browsing_data/core/counters.
+// Currently this can only be used for counters for which the Result is
+// defined in components/browsing_data/core/counters.
base::string16 GetCounterTextFromResult(
const BrowsingDataCounter::Result* result);
diff --git a/chromium/components/browsing_data/core/browsing_data_utils_unittest.cc b/chromium/components/browsing_data/core/browsing_data_utils_unittest.cc
index bd22d2867be..12a870ed8df 100644
--- a/chromium/components/browsing_data/core/browsing_data_utils_unittest.cc
+++ b/chromium/components/browsing_data/core/browsing_data_utils_unittest.cc
@@ -12,7 +12,9 @@
#include "base/threading/thread_task_runner_handle.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/browsing_data/core/counters/autofill_counter.h"
+#include "components/browsing_data/core/counters/passwords_counter.h"
#include "components/browsing_data/core/pref_names.h"
+#include "components/password_manager/core/browser/test_password_store.h"
#include "components/prefs/pref_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -50,7 +52,7 @@ class BrowsingDataUtilsTest : public testing::Test {
// Tests the complex output of the Autofill counter.
TEST_F(BrowsingDataUtilsTest, AutofillCounterResult) {
browsing_data::AutofillCounter counter(
- scoped_refptr<FakeWebDataService>(new FakeWebDataService()));
+ scoped_refptr<FakeWebDataService>(new FakeWebDataService()), nullptr);
// Test all configurations of zero and nonzero partial results for datatypes.
// Test singular and plural for each datatype.
@@ -58,24 +60,29 @@ TEST_F(BrowsingDataUtilsTest, AutofillCounterResult) {
int num_credit_cards;
int num_addresses;
int num_suggestions;
+ bool sync_enabled;
std::string expected_output;
} kTestCases[] = {
- {0, 0, 0, "none"},
- {1, 0, 0, "1 credit card"},
- {0, 5, 0, "5 addresses"},
- {0, 0, 1, "1 suggestion"},
- {0, 0, 2, "2 suggestions"},
- {4, 7, 0, "4 credit cards, 7 addresses"},
- {3, 0, 9, "3 credit cards, 9 other suggestions"},
- {0, 1, 1, "1 address, 1 other suggestion"},
- {9, 6, 3, "9 credit cards, 6 addresses, 3 others"},
- {4, 2, 1, "4 credit cards, 2 addresses, 1 other"},
+ {0, 0, 0, false, "None"},
+ {0, 0, 0, true, "None"},
+ {1, 0, 0, false, "1 credit card"},
+ {0, 5, 0, false, "5 addresses"},
+ {0, 0, 1, false, "1 suggestion"},
+ {0, 0, 2, false, "2 suggestions"},
+ {0, 0, 2, true, "2 suggestions (synced)"},
+ {4, 7, 0, false, "4 credit cards, 7 addresses"},
+ {4, 7, 0, true, "4 credit cards, 7 addresses (synced)"},
+ {3, 0, 9, false, "3 credit cards, 9 other suggestions"},
+ {0, 1, 1, false, "1 address, 1 other suggestion"},
+ {9, 6, 3, false, "9 credit cards, 6 addresses, 3 others"},
+ {4, 2, 1, false, "4 credit cards, 2 addresses, 1 other"},
+ {4, 2, 1, true, "4 credit cards, 2 addresses, 1 other (synced)"},
};
for (const TestCase& test_case : kTestCases) {
browsing_data::AutofillCounter::AutofillResult result(
&counter, test_case.num_suggestions, test_case.num_credit_cards,
- test_case.num_addresses);
+ test_case.num_addresses, test_case.sync_enabled);
SCOPED_TRACE(
base::StringPrintf("Test params: %d credit card(s), "
@@ -88,6 +95,35 @@ TEST_F(BrowsingDataUtilsTest, AutofillCounterResult) {
}
}
+// Tests the output of the Passwords counter.
+TEST_F(BrowsingDataUtilsTest, PasswordsCounterResult) {
+ scoped_refptr<password_manager::TestPasswordStore> store(
+ new password_manager::TestPasswordStore());
+ browsing_data::PasswordsCounter counter(
+ scoped_refptr<password_manager::PasswordStore>(store), nullptr);
+
+ const struct TestCase {
+ int num_passwords;
+ int is_synced;
+ std::string expected_output;
+ } kTestCases[] = {
+ {0, false, "None"}, {0, true, "None"},
+ {1, false, "1 password"}, {1, true, "1 password (synced)"},
+ {5, false, "5 passwords"}, {5, true, "5 passwords (synced)"},
+ };
+
+ for (const TestCase& test_case : kTestCases) {
+ browsing_data::BrowsingDataCounter::SyncResult result(
+ &counter, test_case.num_passwords, test_case.is_synced);
+ SCOPED_TRACE(base::StringPrintf("Test params: %d password(s), %d is_synced",
+ test_case.num_passwords,
+ test_case.is_synced));
+ base::string16 output = browsing_data::GetCounterTextFromResult(&result);
+ EXPECT_EQ(output, base::ASCIIToUTF16(test_case.expected_output));
+ }
+ store->ShutdownOnUIThread();
+}
+
TEST_F(BrowsingDataUtilsTest, MigratePreferencesToBasic) {
using namespace browsing_data::prefs;
diff --git a/chromium/components/browsing_data/core/counters/autofill_counter.cc b/chromium/components/browsing_data/core/counters/autofill_counter.cc
index 6e40f26cb13..0b9a7d8deaa 100644
--- a/chromium/components/browsing_data/core/counters/autofill_counter.cc
+++ b/chromium/components/browsing_data/core/counters/autofill_counter.cc
@@ -8,29 +8,49 @@
#include <utility>
#include <vector>
+#include "base/memory/ptr_util.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/browsing_data/core/pref_names.h"
+#include "components/sync/driver/sync_service.h"
+
+namespace {
+
+bool IsAutofillSyncEnabled(const syncer::SyncService* sync_service) {
+ return sync_service && sync_service->IsFirstSetupComplete() &&
+ sync_service->IsSyncActive() &&
+ sync_service->GetActiveDataTypes().Has(syncer::AUTOFILL);
+}
+
+} // namespace
namespace browsing_data {
AutofillCounter::AutofillCounter(
- scoped_refptr<autofill::AutofillWebDataService> web_data_service)
+ scoped_refptr<autofill::AutofillWebDataService> web_data_service,
+ syncer::SyncService* sync_service)
: web_data_service_(web_data_service),
+ sync_service_(sync_service),
suggestions_query_(0),
credit_cards_query_(0),
addresses_query_(0),
num_suggestions_(0),
num_credit_cards_(0),
- num_addresses_(0) {}
+ num_addresses_(0),
+ autofill_sync_enabled_() {}
AutofillCounter::~AutofillCounter() {
CancelAllRequests();
+ if (sync_service_)
+ sync_service_->RemoveObserver(this);
}
void AutofillCounter::OnInitialized() {
DCHECK(web_data_service_);
+ if (sync_service_)
+ sync_service_->AddObserver(this);
+ autofill_sync_enabled_ = IsAutofillSyncEnabled(sync_service_);
}
const char* AutofillCounter::GetPrefName() const {
@@ -150,8 +170,9 @@ void AutofillCounter::OnWebDataServiceRequestDone(
if (suggestions_query_ || credit_cards_query_ || addresses_query_)
return;
- std::unique_ptr<Result> reported_result(new AutofillResult(
- this, num_suggestions_, num_credit_cards_, num_addresses_));
+ auto reported_result = base::MakeUnique<AutofillResult>(
+ this, num_suggestions_, num_credit_cards_, num_addresses_,
+ autofill_sync_enabled_);
ReportResult(std::move(reported_result));
}
@@ -164,13 +185,22 @@ void AutofillCounter::CancelAllRequests() {
web_data_service_->CancelRequest(addresses_query_);
}
+void AutofillCounter::OnStateChanged(syncer::SyncService* sync) {
+ bool sync_enabled_new = IsAutofillSyncEnabled(sync);
+ if (autofill_sync_enabled_ != sync_enabled_new) {
+ autofill_sync_enabled_ = sync_enabled_new;
+ Restart();
+ }
+}
+
// AutofillCounter::AutofillResult ---------------------------------------------
AutofillCounter::AutofillResult::AutofillResult(const AutofillCounter* source,
ResultInt num_suggestions,
ResultInt num_credit_cards,
- ResultInt num_addresses)
- : FinishedResult(source, num_suggestions),
+ ResultInt num_addresses,
+ bool autofill_sync_enabled_)
+ : SyncResult(source, num_suggestions, autofill_sync_enabled_),
num_credit_cards_(num_credit_cards),
num_addresses_(num_addresses) {}
diff --git a/chromium/components/browsing_data/core/counters/autofill_counter.h b/chromium/components/browsing_data/core/counters/autofill_counter.h
index b732b1cbd9d..7352a0c4f68 100644
--- a/chromium/components/browsing_data/core/counters/autofill_counter.h
+++ b/chromium/components/browsing_data/core/counters/autofill_counter.h
@@ -10,6 +10,7 @@
#include "base/time/time.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/browsing_data/core/counters/browsing_data_counter.h"
+#include "components/sync/driver/sync_service_observer.h"
#include "components/webdata/common/web_data_service_consumer.h"
namespace autofill {
@@ -19,14 +20,16 @@ class AutofillWebDataService;
namespace browsing_data {
class AutofillCounter : public browsing_data::BrowsingDataCounter,
- public WebDataServiceConsumer {
+ public WebDataServiceConsumer,
+ public syncer::SyncServiceObserver {
public:
- class AutofillResult : public FinishedResult {
+ class AutofillResult : public SyncResult {
public:
AutofillResult(const AutofillCounter* source,
ResultInt num_suggestions,
ResultInt num_credit_cards,
- ResultInt num_addresses);
+ ResultInt num_addresses,
+ bool autofill_sync_enabled_);
~AutofillResult() override;
ResultInt num_credit_cards() const { return num_credit_cards_; }
@@ -40,7 +43,8 @@ class AutofillCounter : public browsing_data::BrowsingDataCounter,
};
explicit AutofillCounter(
- scoped_refptr<autofill::AutofillWebDataService> web_data_service);
+ scoped_refptr<autofill::AutofillWebDataService> web_data_service,
+ syncer::SyncService* sync_service);
~AutofillCounter() override;
// BrowsingDataCounter implementation.
@@ -64,12 +68,16 @@ class AutofillCounter : public browsing_data::BrowsingDataCounter,
WebDataServiceBase::Handle handle,
std::unique_ptr<WDTypedResult> result) override;
+ // SyncServiceObserver implementation.
+ void OnStateChanged(syncer::SyncService* sync) override;
+
// Cancel all pending requests to AutofillWebdataService.
void CancelAllRequests();
base::ThreadChecker thread_checker_;
scoped_refptr<autofill::AutofillWebDataService> web_data_service_;
+ syncer::SyncService* sync_service_;
WebDataServiceBase::Handle suggestions_query_;
WebDataServiceBase::Handle credit_cards_query_;
@@ -78,6 +86,7 @@ class AutofillCounter : public browsing_data::BrowsingDataCounter,
ResultInt num_suggestions_;
ResultInt num_credit_cards_;
ResultInt num_addresses_;
+ bool autofill_sync_enabled_;
base::Time period_start_for_testing_;
diff --git a/chromium/components/browsing_data/core/counters/browsing_data_counter.cc b/chromium/components/browsing_data/core/counters/browsing_data_counter.cc
index 48a80180c5b..bc26908d6b7 100644
--- a/chromium/components/browsing_data/core/counters/browsing_data_counter.cc
+++ b/chromium/components/browsing_data/core/counters/browsing_data_counter.cc
@@ -139,7 +139,9 @@ void BrowsingDataCounter::TransitionToReadyToReportResult() {
// BrowsingDataCounter::Result -------------------------------------------------
BrowsingDataCounter::Result::Result(const BrowsingDataCounter* source)
- : source_(source) {}
+ : source_(source) {
+ DCHECK(source);
+}
BrowsingDataCounter::Result::~Result() {}
@@ -165,4 +167,13 @@ BrowsingDataCounter::ResultInt BrowsingDataCounter::FinishedResult::Value()
return value_;
}
+// BrowsingDataCounter::SyncResult -----------------------------------------
+
+BrowsingDataCounter::SyncResult::SyncResult(const BrowsingDataCounter* source,
+ ResultInt value,
+ bool sync_enabled)
+ : FinishedResult(source, value), sync_enabled_(sync_enabled) {}
+
+BrowsingDataCounter::SyncResult::~SyncResult() {}
+
} // namespace browsing_data
diff --git a/chromium/components/browsing_data/core/counters/browsing_data_counter.h b/chromium/components/browsing_data/core/counters/browsing_data_counter.h
index d7fbb956dce..a6cb28804d0 100644
--- a/chromium/components/browsing_data/core/counters/browsing_data_counter.h
+++ b/chromium/components/browsing_data/core/counters/browsing_data_counter.h
@@ -60,6 +60,23 @@ class BrowsingDataCounter {
DISALLOW_COPY_AND_ASSIGN(FinishedResult);
};
+ // A subclass of FinishedResult that besides |Value()| also stores whether
+ // the datatype is synced.
+ class SyncResult : public FinishedResult {
+ public:
+ SyncResult(const BrowsingDataCounter* source,
+ ResultInt value,
+ bool sync_enabled);
+ ~SyncResult() override;
+
+ bool is_sync_enabled() const { return sync_enabled_; }
+
+ private:
+ bool sync_enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyncResult);
+ };
+
typedef base::Callback<void(std::unique_ptr<Result>)> Callback;
// Every calculation progresses through a state machine. At initialization,
@@ -128,7 +145,8 @@ class BrowsingDataCounter {
// Called after the class is initialized by calling |Init|.
virtual void OnInitialized();
- // Count the data.
+ // Count the data. Call ReportResult() when finished. Tasks that are still
+ // running should be cancelled to avoid reporting old results.
virtual void Count() = 0;
// State transition methods.
diff --git a/chromium/components/browsing_data/core/counters/history_counter.cc b/chromium/components/browsing_data/core/counters/history_counter.cc
index 6fcb1c17ea9..fd22f4a7c65 100644
--- a/chromium/components/browsing_data/core/counters/history_counter.cc
+++ b/chromium/components/browsing_data/core/counters/history_counter.cc
@@ -55,6 +55,8 @@ void HistoryCounter::Count() {
// Reset the state.
cancelable_task_tracker_.TryCancelAll();
web_history_request_.reset();
+ weak_ptr_factory_.InvalidateWeakPtrs();
+
has_synced_visits_ = false;
// Count the locally stored items.
@@ -100,7 +102,6 @@ void HistoryCounter::OnGetLocalHistoryCount(
DCHECK(thread_checker_.CalledOnValidThread());
if (!result.success) {
- LOG(ERROR) << "Failed to count the local history.";
return;
}
@@ -149,17 +150,10 @@ void HistoryCounter::MergeResults() {
if (!local_counting_finished_ || !web_counting_finished_)
return;
- ReportResult(
- base::MakeUnique<HistoryResult>(this, local_result_, has_synced_visits_));
+ ReportResult(base::MakeUnique<HistoryResult>(
+ this, local_result_, history_sync_enabled_, has_synced_visits_));
}
-HistoryCounter::HistoryResult::HistoryResult(const HistoryCounter* source,
- ResultInt value,
- bool has_synced_visits)
- : FinishedResult(source, value), has_synced_visits_(has_synced_visits) {}
-
-HistoryCounter::HistoryResult::~HistoryResult() {}
-
void HistoryCounter::OnStateChanged(syncer::SyncService* sync) {
bool history_sync_enabled_new_state = !!web_history_service_callback_.Run();
@@ -171,4 +165,13 @@ void HistoryCounter::OnStateChanged(syncer::SyncService* sync) {
}
}
+HistoryCounter::HistoryResult::HistoryResult(const HistoryCounter* source,
+ ResultInt value,
+ bool is_sync_enabled,
+ bool has_synced_visits)
+ : SyncResult(source, value, is_sync_enabled),
+ has_synced_visits_(has_synced_visits) {}
+
+HistoryCounter::HistoryResult::~HistoryResult() {}
+
} // namespace browsing_data
diff --git a/chromium/components/browsing_data/core/counters/history_counter.h b/chromium/components/browsing_data/core/counters/history_counter.h
index f06ca6154af..12e907d9d2b 100644
--- a/chromium/components/browsing_data/core/counters/history_counter.h
+++ b/chromium/components/browsing_data/core/counters/history_counter.h
@@ -23,10 +23,11 @@ class HistoryCounter : public browsing_data::BrowsingDataCounter,
typedef base::Callback<history::WebHistoryService*()>
GetUpdatedWebHistoryServiceCallback;
- class HistoryResult : public FinishedResult {
+ class HistoryResult : public SyncResult {
public:
HistoryResult(const HistoryCounter* source,
ResultInt value,
+ bool is_sync_enabled,
bool has_synced_visits);
~HistoryResult() override;
diff --git a/chromium/components/browsing_data/core/counters/passwords_counter.cc b/chromium/components/browsing_data/core/counters/passwords_counter.cc
index 8585158b839..b78cd06b8f2 100644
--- a/chromium/components/browsing_data/core/counters/passwords_counter.cc
+++ b/chromium/components/browsing_data/core/counters/passwords_counter.cc
@@ -5,20 +5,41 @@
#include "components/browsing_data/core/counters/passwords_counter.h"
#include "components/browsing_data/core/pref_names.h"
+#include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/browser/password_store.h"
+#include "components/sync/driver/sync_service.h"
+
+namespace {
+
+bool IsPasswordSyncEnabled(const syncer::SyncService* sync_service) {
+ if (!sync_service)
+ return false;
+ return password_manager_util::GetPasswordSyncState(sync_service) !=
+ password_manager::PasswordSyncState::NOT_SYNCING_PASSWORDS;
+}
+
+} // namespace
namespace browsing_data {
PasswordsCounter::PasswordsCounter(
- scoped_refptr<password_manager::PasswordStore> store) : store_(store) {}
+ scoped_refptr<password_manager::PasswordStore> store,
+ syncer::SyncService* sync_service)
+ : store_(store), sync_service_(sync_service), password_sync_enabled_() {
+ DCHECK(store_);
+}
PasswordsCounter::~PasswordsCounter() {
store_->RemoveObserver(this);
+ if (sync_service_)
+ sync_service_->RemoveObserver(this);
}
void PasswordsCounter::OnInitialized() {
- DCHECK(store_);
store_->AddObserver(this);
+ if (sync_service_)
+ sync_service_->AddObserver(this);
+ password_sync_enabled_ = IsPasswordSyncEnabled(sync_service_);
}
const char* PasswordsCounter::GetPrefName() const {
@@ -37,11 +58,13 @@ void PasswordsCounter::Count() {
void PasswordsCounter::OnGetPasswordStoreResults(
std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
base::Time start = GetPeriodStart();
- ReportResult(std::count_if(
+ int num_passwords = std::count_if(
results.begin(), results.end(),
[start](const std::unique_ptr<autofill::PasswordForm>& form) {
return form->date_created >= start;
- }));
+ });
+ ReportResult(base::MakeUnique<SyncResult>(this, num_passwords,
+ password_sync_enabled_));
}
void PasswordsCounter::OnLoginsChanged(
@@ -49,4 +72,13 @@ void PasswordsCounter::OnLoginsChanged(
Restart();
}
+void PasswordsCounter::OnStateChanged(syncer::SyncService* sync) {
+ bool sync_enabled_new = IsPasswordSyncEnabled(sync_service_);
+
+ if (password_sync_enabled_ != sync_enabled_new) {
+ password_sync_enabled_ = sync_enabled_new;
+ Restart();
+ }
+}
+
} // namespace browsing_data
diff --git a/chromium/components/browsing_data/core/counters/passwords_counter.h b/chromium/components/browsing_data/core/counters/passwords_counter.h
index dd69536393f..bb71ff30013 100644
--- a/chromium/components/browsing_data/core/counters/passwords_counter.h
+++ b/chromium/components/browsing_data/core/counters/passwords_counter.h
@@ -11,15 +11,18 @@
#include "components/browsing_data/core/counters/browsing_data_counter.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
+#include "components/sync/driver/sync_service_observer.h"
namespace browsing_data {
class PasswordsCounter : public browsing_data::BrowsingDataCounter,
public password_manager::PasswordStoreConsumer,
- public password_manager::PasswordStore::Observer {
+ public password_manager::PasswordStore::Observer,
+ public syncer::SyncServiceObserver {
public:
explicit PasswordsCounter(
- scoped_refptr<password_manager::PasswordStore> store);
+ scoped_refptr<password_manager::PasswordStore> store,
+ syncer::SyncService* sync_service);
~PasswordsCounter() override;
const char* GetPrefName() const override;
@@ -37,10 +40,15 @@ class PasswordsCounter : public browsing_data::BrowsingDataCounter,
void OnLoginsChanged(
const password_manager::PasswordStoreChangeList& changes) override;
+ // SyncServiceObserver implementation.
+ void OnStateChanged(syncer::SyncService* sync) override;
+
void Count() override;
base::CancelableTaskTracker cancelable_task_tracker_;
scoped_refptr<password_manager::PasswordStore> store_;
+ syncer::SyncService* sync_service_;
+ bool password_sync_enabled_;
};
} // namespace browsing_data
diff --git a/chromium/components/browsing_data/core/counters/site_settings_counter.cc b/chromium/components/browsing_data/core/counters/site_settings_counter.cc
new file mode 100644
index 00000000000..fc6ecd6cd7c
--- /dev/null
+++ b/chromium/components/browsing_data/core/counters/site_settings_counter.cc
@@ -0,0 +1,50 @@
+// Copyright 2017 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/browsing_data/core/counters/site_settings_counter.h"
+
+#include <set>
+#include "components/browsing_data/core/pref_names.h"
+#include "components/content_settings/core/browser/content_settings_registry.h"
+#include "components/content_settings/core/common/content_settings_pattern.h"
+
+namespace browsing_data {
+
+SiteSettingsCounter::SiteSettingsCounter(HostContentSettingsMap* map)
+ : map_(map) {
+ DCHECK(map_);
+}
+
+SiteSettingsCounter::~SiteSettingsCounter() {}
+
+void SiteSettingsCounter::OnInitialized() {}
+
+const char* SiteSettingsCounter::GetPrefName() const {
+ return browsing_data::prefs::kDeleteSiteSettings;
+}
+
+void SiteSettingsCounter::Count() {
+ std::set<ContentSettingsPattern> patterns;
+ base::Time period_start = GetPeriodStart();
+ auto* registry = content_settings::ContentSettingsRegistry::GetInstance();
+ for (const content_settings::ContentSettingsInfo* info : *registry) {
+ ContentSettingsType type = info->website_settings_info()->type();
+ ContentSettingsForOneType content_settings_list;
+ map_->GetSettingsForOneType(type, content_settings::ResourceIdentifier(),
+ &content_settings_list);
+ for (const auto& content_setting : content_settings_list) {
+ if (content_setting.source == "preference") {
+ base::Time last_modified = map_->GetSettingLastModifiedDate(
+ content_setting.primary_pattern, content_setting.secondary_pattern,
+ type);
+ if (last_modified >= period_start) {
+ patterns.insert(content_setting.primary_pattern);
+ }
+ }
+ }
+ }
+ ReportResult(patterns.size());
+}
+
+} // namespace browsing_data
diff --git a/chromium/components/browsing_data/core/counters/site_settings_counter.h b/chromium/components/browsing_data/core/counters/site_settings_counter.h
new file mode 100644
index 00000000000..bab835b4d4b
--- /dev/null
+++ b/chromium/components/browsing_data/core/counters/site_settings_counter.h
@@ -0,0 +1,30 @@
+// Copyright 2017 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_BROWSING_DATA_CORE_COUNTERS_SITE_SETTINGS_COUNTER_H_
+#define COMPONENTS_BROWSING_DATA_CORE_COUNTERS_SITE_SETTINGS_COUNTER_H_
+
+#include "components/browsing_data/core/counters/browsing_data_counter.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+
+namespace browsing_data {
+
+class SiteSettingsCounter : public browsing_data::BrowsingDataCounter {
+ public:
+ explicit SiteSettingsCounter(HostContentSettingsMap* hcsm);
+ ~SiteSettingsCounter() override;
+
+ const char* GetPrefName() const override;
+
+ private:
+ void OnInitialized() override;
+
+ void Count() override;
+
+ scoped_refptr<HostContentSettingsMap> map_;
+};
+
+} // namespace browsing_data
+
+#endif // COMPONENTS_BROWSING_DATA_CORE_COUNTERS_SITE_SETTINGS_COUNTER_H_
diff --git a/chromium/components/browsing_data/core/pref_names.cc b/chromium/components/browsing_data/core/pref_names.cc
index 59113a84cc6..ef88d87a282 100644
--- a/chromium/components/browsing_data/core/pref_names.cc
+++ b/chromium/components/browsing_data/core/pref_names.cc
@@ -27,6 +27,7 @@ const char kDeletePasswords[] = "browser.clear_data.passwords";
const char kDeleteFormData[] = "browser.clear_data.form_data";
const char kDeleteHostedAppsData[] = "browser.clear_data.hosted_apps_data";
const char kDeleteMediaLicenses[] = "browser.clear_data.media_licenses";
+const char kDeleteSiteSettings[] = "browser.clear_data.site_settings";
// Other Clear Browsing Data preferences.
const char kLastClearBrowsingDataTime[] =
@@ -76,13 +77,14 @@ void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(
kDeleteMediaLicenses, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+ registry->RegisterBooleanPref(
+ kDeleteSiteSettings, false,
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterInt64Pref(prefs::kLastClearBrowsingDataTime, 0);
#endif // !defined(OS_IOS)
#if defined(OS_ANDROID)
- registry->RegisterIntegerPref(
- kLastClearBrowsingDataTab, 0,
- user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+ registry->RegisterIntegerPref(kLastClearBrowsingDataTab, 0);
#endif
registry->RegisterBooleanPref(
diff --git a/chromium/components/browsing_data/core/pref_names.h b/chromium/components/browsing_data/core/pref_names.h
index a8af5664115..fd25225a208 100644
--- a/chromium/components/browsing_data/core/pref_names.h
+++ b/chromium/components/browsing_data/core/pref_names.h
@@ -27,6 +27,7 @@ extern const char kDeletePasswords[];
extern const char kDeleteFormData[];
extern const char kDeleteHostedAppsData[];
extern const char kDeleteMediaLicenses[];
+extern const char kDeleteSiteSettings[];
extern const char kLastClearBrowsingDataTime[];
extern const char kClearBrowsingDataHistoryNoticeShownTimes[];
diff --git a/chromium/components/browsing_data_strings.grdp b/chromium/components/browsing_data_strings.grdp
index 0b3f9b20869..993cd7f373e 100644
--- a/chromium/components/browsing_data_strings.grdp
+++ b/chromium/components/browsing_data_strings.grdp
@@ -6,20 +6,23 @@
</message>
<message name="IDS_DEL_BROWSING_HISTORY_COUNTER" desc="A counter showing how many items of browsing history the user has.">
{COUNT, plural,
- =0 {none}
+ =0 {None}
=1 {1 item}
other {# items}}
</message>
<message name="IDS_DEL_BROWSING_HISTORY_COUNTER_SYNCED" desc="A counter showing the user how many local items of browsing history they have, and informing them that more items might be synced. In the case when COUNT is zero, the counter only mentions existence of synced items.">
{COUNT, plural,
- =0 {at least 1 item on synced devices}
+ =0 {At least 1 item on synced devices}
=1 {1 item (and more on synced devices)}
other {# items (and more on synced devices)}}
</message>
<message name="IDS_DEL_CACHE_COUNTER_UPPER_ESTIMATE" desc="A counter showing that the user has less than X megabytes of cache. The value X will be substituted.">
- less than <ph name="UPPER_ESTIMATE">$1<ex>328 MB</ex></ph>
+ Less than <ph name="UPPER_ESTIMATE">$1<ex>328 MB</ex></ph>
</message>
<message name="IDS_DEL_CACHE_COUNTER_ALMOST_EMPTY" desc="A counter showing that the user's cache is almost empty, having less than 1 MB of data.">
+ Less than 1 MB
+ </message>
+ <message name="IDS_DEL_CACHE_COUNTER_ALMOST_EMPTY_BASIC" desc="Text showing that the user has less than 1 MB of data. It will be included in the sentence 'Frees up $1.'">
less than 1 MB
</message>
<message name="IDS_DEL_CACHE_COUNTER_BASIC" desc="A counter showing the size of the users's cache including either 'x MB' or 'less than x MB' as $1 and explaining that the cache is used to speed up the loading of websites.">
@@ -27,12 +30,24 @@
</message>
<message name="IDS_DEL_PASSWORDS_COUNTER" desc="A counter showing how many passwords the user has.">
{COUNT, plural,
- =0 {none}
- =1 {1}
- other {#}}
+ =0 {None}
+ =1 {1 password}
+ other {# passwords}}
+ </message>
+ <message name="IDS_DEL_PASSWORDS_COUNTER_SYNCED" desc="A counter showing how many passwords the user has and that they are synced.">
+ {COUNT, plural,
+ =0 {None}
+ =1 {1 password (synced)}
+ other {# passwords (synced)}}
+ </message>
+ <message name="IDS_DEL_SITE_SETTINGS_COUNTER" desc="A counter showing how many sites with site settings the user has.">
+ {COUNT, plural,
+ =0 {None}
+ =1 {1 site}
+ other {# sites}}
</message>
<message name="IDS_DEL_AUTOFILL_COUNTER_EMPTY" desc="A counter showing that the user has no form data stored.">
- none
+ None
</message>
<message name="IDS_DEL_AUTOFILL_COUNTER_CREDIT_CARDS" desc="A counter showing how many credit cards the user has.">
{COUNT, plural,
@@ -59,30 +74,39 @@
=1 {1 other}
other {# others}}
</message>
+ <message name="IDS_DEL_AUTOFILL_COUNTER_ONE_TYPE_SYNCED" desc="A counter showing that the user has one type of form data and that it is synced. The type will be substituted, this message only provides the (synced) part.">
+ <ph name="TYPE_1">$1<ex>2 credit cards</ex></ph> (synced)
+ </message>
<message name="IDS_DEL_AUTOFILL_COUNTER_TWO_TYPES" desc="A counter showing that the user has two types of form data. The types and their counts will be substituted, this message only provides the comma separator.">
<ph name="TYPE_1">$1<ex>2 credit cards</ex></ph>, <ph name="TYPE_2">$2<ex>1 address</ex></ph>
</message>
+ <message name="IDS_DEL_AUTOFILL_COUNTER_TWO_TYPES_SYNCED" desc="A counter showing that the user has two types of form data and that they are synced. The types and their counts will be substituted, this message only provides the comma separator.">
+ <ph name="TYPE_1">$1<ex>2 credit cards</ex></ph>, <ph name="TYPE_2">$2<ex>1 address</ex></ph> (synced)
+ </message>
<message name="IDS_DEL_AUTOFILL_COUNTER_THREE_TYPES" desc="A counter showing that the user has three types of form data. The types and their counts will be substituted, this message only provides the comma separators.">
<ph name="TYPE_1">$1<ex>2 credit cards</ex></ph>, <ph name="TYPE_2">$2<ex>1 address</ex></ph>, <ph name="TYPE_3">$3<ex>5 others</ex></ph>
</message>
+ <message name="IDS_DEL_AUTOFILL_COUNTER_THREE_TYPES_SYNCED" desc="A counter showing that the user has three types of form data and that they are synced. The types and their counts will be substituted, this message only provides the comma separators.">
+ <ph name="TYPE_1">$1<ex>2 credit cards</ex></ph>, <ph name="TYPE_2">$2<ex>1 address</ex></ph>, <ph name="TYPE_3">$3<ex>5 others</ex></ph> (synced)
+ </message>
<message name="IDS_DEL_COOKIES_COUNTER" desc="A static message shown in the Clear Browsing Data dialog explaining to the user that deleting cookies and site data will result in the user being signed out of most websites.">
This will sign you out of most websites.
</message>
<message name="IDS_DEL_COOKIES_COUNTER_ADVANCED" desc="A counter showing the number of sites that use cookies.">
{COUNT, plural,
- =0 {No cookies}
- =1 {1 site uses cookies. }
- other {# sites use cookies. }}
+ =0 {None}
+ =1 {From 1 site }
+ other {From # sites }}
</message>
<message name="IDS_DEL_DOWNLOADS_COUNTER" desc="A counter showing how many items of downloads history the user has.">
{COUNT, plural,
- =0 {none}
+ =0 {None}
=1 {1 item}
other {# items}}
</message>
<message name="IDS_DEL_HOSTED_APPS_COUNTER" desc="A counter showing how many hosted apps the user has. We show the number of apps, and in the cases where there is one or two apps, we will also give two example app names, denoted as placeholders $1 and $2. If there are more than two apps, we will give two examples and say 'and X more'. The 'and X more' string, denoted by the placeholder $3, will be supplied from another message.">
{COUNT, plural,
- =0 {none}
+ =0 {None}
=1 {1 app ($1)}
=2 {2 apps ($1, $2)}
other {# apps ($1, $2, $3)}}
diff --git a/chromium/components/captive_portal/captive_portal_detector.cc b/chromium/components/captive_portal/captive_portal_detector.cc
index 04eb566438a..6ec4df23d66 100644
--- a/chromium/components/captive_portal/captive_portal_detector.cc
+++ b/chromium/components/captive_portal/captive_portal_detector.cc
@@ -27,7 +27,8 @@ CaptivePortalDetector::~CaptivePortalDetector() {
void CaptivePortalDetector::DetectCaptivePortal(
const GURL& url,
- const DetectionCallback& detection_callback) {
+ const DetectionCallback& detection_callback,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(CalledOnValidThread());
DCHECK(!FetchingURL());
DCHECK(detection_callback_.is_null());
@@ -35,7 +36,8 @@ void CaptivePortalDetector::DetectCaptivePortal(
detection_callback_ = detection_callback;
// The first 0 means this can use a TestURLFetcherFactory in unit tests.
- url_fetcher_ = net::URLFetcher::Create(0, url, net::URLFetcher::GET, this);
+ url_fetcher_ = net::URLFetcher::Create(0, url, net::URLFetcher::GET, this,
+ traffic_annotation);
url_fetcher_->SetAutomaticallyRetryOn5xx(false);
url_fetcher_->SetRequestContext(request_context_.get());
data_use_measurement::DataUseUserData::AttachToFetcher(
diff --git a/chromium/components/captive_portal/captive_portal_detector.h b/chromium/components/captive_portal/captive_portal_detector.h
index 3cf10124542..e25cd443f4e 100644
--- a/chromium/components/captive_portal/captive_portal_detector.h
+++ b/chromium/components/captive_portal/captive_portal_detector.h
@@ -15,6 +15,7 @@
#include "base/time/time.h"
#include "components/captive_portal/captive_portal_export.h"
#include "components/captive_portal/captive_portal_types.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
@@ -54,7 +55,10 @@ class CAPTIVE_PORTAL_EXPORT CaptivePortalDetector
// Triggers a check for a captive portal. After completion, runs the
// |callback|.
- void DetectCaptivePortal(const GURL& url, const DetectionCallback& callback);
+ void DetectCaptivePortal(
+ const GURL& url,
+ const DetectionCallback& callback,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation);
// Cancels captive portal check.
void Cancel();
diff --git a/chromium/components/captive_portal/captive_portal_detector_unittest.cc b/chromium/components/captive_portal/captive_portal_detector_unittest.cc
index 7eaa099f298..1f9b1691b02 100644
--- a/chromium/components/captive_portal/captive_portal_detector_unittest.cc
+++ b/chromium/components/captive_portal/captive_portal_detector_unittest.cc
@@ -15,6 +15,7 @@
#include "base/time/time.h"
#include "components/captive_portal/captive_portal_testing_utils.h"
#include "net/base/net_errors.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -76,9 +77,11 @@ class CaptivePortalDetectorTest : public testing::Test,
GURL url(CaptivePortalDetector::kDefaultURL);
CaptivePortalClient client(detector());
- detector()->DetectCaptivePortal(url,
+ detector()->DetectCaptivePortal(
+ url,
base::Bind(&CaptivePortalClient::OnPortalDetectionCompleted,
- base::Unretained(&client)));
+ base::Unretained(&client)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
ASSERT_TRUE(FetchingURL());
base::RunLoop().RunUntilIdle();
@@ -100,9 +103,11 @@ class CaptivePortalDetectorTest : public testing::Test,
GURL url(CaptivePortalDetector::kDefaultURL);
CaptivePortalClient client(detector());
- detector()->DetectCaptivePortal(url,
+ detector()->DetectCaptivePortal(
+ url,
base::Bind(&CaptivePortalClient::OnPortalDetectionCompleted,
- base::Unretained(&client)));
+ base::Unretained(&client)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
ASSERT_TRUE(FetchingURL());
base::RunLoop().RunUntilIdle();
diff --git a/chromium/components/cast_certificate/cast_cert_validator.cc b/chromium/components/cast_certificate/cast_cert_validator.cc
index 18609aff085..afd7b644971 100644
--- a/chromium/components/cast_certificate/cast_cert_validator.cc
+++ b/chromium/components/cast_certificate/cast_cert_validator.cc
@@ -74,9 +74,7 @@ class CastTrustStore {
&errors);
CHECK(cert) << errors.ToDebugString();
// Enforce pathlen constraints and policies defined on the root certificate.
- scoped_refptr<net::TrustAnchor> anchor =
- net::TrustAnchor::CreateFromCertificateWithConstraints(std::move(cert));
- store_.AddTrustAnchor(std::move(anchor));
+ store_.AddTrustAnchorWithConstraints(std::move(cert));
}
net::TrustStoreInMemory store_;
diff --git a/chromium/components/cast_certificate/cast_cert_validator_test_helpers.cc b/chromium/components/cast_certificate/cast_cert_validator_test_helpers.cc
index d9ade267ccd..4a41ed2b0d3 100644
--- a/chromium/components/cast_certificate/cast_cert_validator_test_helpers.cc
+++ b/chromium/components/cast_certificate/cast_cert_validator_test_helpers.cc
@@ -93,9 +93,7 @@ std::unique_ptr<net::TrustStoreInMemory> CreateTrustStoreFromFile(
scoped_refptr<net::ParsedCertificate> cert(net::ParsedCertificate::Create(
net::x509_util::CreateCryptoBuffer(trusted_root), {}, &errors));
EXPECT_TRUE(cert) << errors.ToDebugString();
- scoped_refptr<net::TrustAnchor> anchor =
- net::TrustAnchor::CreateFromCertificateWithConstraints(std::move(cert));
- trust_store->AddTrustAnchor(std::move(anchor));
+ trust_store->AddTrustAnchorWithConstraints(cert);
}
return trust_store;
}
diff --git a/chromium/components/cast_certificate/cast_cert_validator_unittest.cc b/chromium/components/cast_certificate/cast_cert_validator_unittest.cc
index a32e728305a..43f9aeacc59 100644
--- a/chromium/components/cast_certificate/cast_cert_validator_unittest.cc
+++ b/chromium/components/cast_certificate/cast_cert_validator_unittest.cc
@@ -95,15 +95,11 @@ void RunTest(TestResult expected_result,
if (trust_store_dependency == TRUST_STORE_FROM_TEST_FILE_UNCONSTRAINED) {
// This is a test-only mode where anchor constraints are not enforced.
- trust_store->AddTrustAnchor(
- net::TrustAnchor::CreateFromCertificateNoConstraints(
- std::move(root)));
+ trust_store->AddTrustAnchor(std::move(root));
} else {
- // This is the regular mode used by the TrustAnchors for the built-in
- // Cast store.
- trust_store->AddTrustAnchor(
- net::TrustAnchor::CreateFromCertificateWithConstraints(
- std::move(root)));
+ // Add a trust anchor and enforce constraints on it (regular mode for
+ // built-in Cast roots).
+ trust_store->AddTrustAnchorWithConstraints(std::move(root));
}
}
}
diff --git a/chromium/components/cast_certificate/cast_crl.cc b/chromium/components/cast_certificate/cast_crl.cc
index 7d866e37088..e8e0595892d 100644
--- a/chromium/components/cast_certificate/cast_crl.cc
+++ b/chromium/components/cast_certificate/cast_crl.cc
@@ -70,10 +70,7 @@ class CastCRLTrustStore {
kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), {}, &errors);
CHECK(cert) << errors.ToDebugString();
// Enforce pathlen constraints and policies defined on the root certificate.
- scoped_refptr<net::TrustAnchor> anchor =
- net::TrustAnchor::CreateFromCertificateWithConstraints(std::move(cert));
- CHECK(anchor);
- store_.AddTrustAnchor(std::move(anchor));
+ store_.AddTrustAnchorWithConstraints(std::move(cert));
}
net::TrustStoreInMemory store_;
@@ -261,7 +258,7 @@ bool CastCRLImpl::CheckRevocation(const net::CertPath& trusted_chain,
if (trusted_chain.IsEmpty())
return false;
- DCHECK(trusted_chain.trust_anchor);
+ DCHECK(trusted_chain.last_cert_trust.IsTrustAnchor());
// Check the validity of the CRL at the specified time.
net::der::GeneralizedTime verification_time;
@@ -274,17 +271,10 @@ bool CastCRLImpl::CheckRevocation(const net::CertPath& trusted_chain,
return false;
}
- // Check revocation. Note that this loop has "+ 1" in order to also loop
- // over the trust anchor (which is treated specially).
- for (size_t i = 0; i < trusted_chain.certs.size() + 1; ++i) {
- // This loop iterates over both certificates AND then the trust
- // anchor after exhausing the certs.
- net::der::Input spki_tlv;
- if (i == trusted_chain.certs.size()) {
- spki_tlv = trusted_chain.trust_anchor->spki();
- } else {
- spki_tlv = trusted_chain.certs[i]->tbs().spki_tlv;
- }
+ // Check revocation. This loop iterates over both certificates AND then the
+ // trust anchor after exhausting the certs.
+ for (size_t i = 0; i < trusted_chain.certs.size(); ++i) {
+ const net::der::Input& spki_tlv = trusted_chain.certs[i]->tbs().spki_tlv;
// Calculate the public key's hash to check for revocation.
std::string spki_hash = crypto::SHA256HashString(spki_tlv.AsString());
diff --git a/chromium/components/cdm/browser/cdm_message_filter_android.cc b/chromium/components/cdm/browser/cdm_message_filter_android.cc
index 849b716a379..8adab716db1 100644
--- a/chromium/components/cdm/browser/cdm_message_filter_android.cc
+++ b/chromium/components/cdm/browser/cdm_message_filter_android.cc
@@ -41,14 +41,24 @@ const CodecInfo<media::VideoCodec> kVideoCodecsToQuery[] = {
#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
{media::EME_CODEC_MP4_HEVC, media::kCodecHEVC, "video/mp4"},
#endif
+#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
+ {media::EME_CODEC_MP4_DV_AVC, media::kCodecDolbyVision, "video/mp4"},
+#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
+ {media::EME_CODEC_MP4_DV_HEVC, media::kCodecDolbyVision, "video/mp4"},
+#endif
+#endif
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
};
const CodecInfo<media::AudioCodec> kAudioCodecsToQuery[] = {
+ // Vorbis is not supported. See http://crbug.com/710924 for details.
{media::EME_CODEC_WEBM_OPUS, media::kCodecOpus, "video/webm"},
- {media::EME_CODEC_WEBM_VORBIS, media::kCodecVorbis, "video/webm"},
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
{media::EME_CODEC_MP4_AAC, media::kCodecAAC, "video/mp4"},
+#if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
+ {media::EME_CODEC_MP4_AC3, media::kCodecAC3, "video/mp4"},
+ {media::EME_CODEC_MP4_EAC3, media::kCodecEAC3, "video/mp4"},
+#endif
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
};
diff --git a/chromium/components/cdm/browser/media_drm_storage_impl.cc b/chromium/components/cdm/browser/media_drm_storage_impl.cc
index bcebc5a348a..800c6275cde 100644
--- a/chromium/components/cdm/browser/media_drm_storage_impl.cc
+++ b/chromium/components/cdm/browser/media_drm_storage_impl.cc
@@ -167,12 +167,18 @@ void MediaDrmStorageImpl::SavePersistentSession(
base::DictionaryValue* origin_dict = nullptr;
// The origin string may contain dots. Do not use path expansion.
storage_dict->GetDictionaryWithoutPathExpansion(origin_string_, &origin_dict);
+
+ // This could happen if the profile is removed, but the device is still
+ // provisioned for the origin. In this case, just create a new entry.
if (!origin_dict) {
- DVLOG(1) << __func__
- << ": Failed to save persistent session data; entry for origin "
- << origin_string_ << " does not exist.";
- callback.Run(false);
- return;
+
+ DVLOG(1) << __func__ << ": Entry for origin " << origin_string_
+ << " does not exist; create a new one.";
+ storage_dict->SetWithoutPathExpansion(origin_string_,
+ CreateOriginDictionary());
+ storage_dict->GetDictionaryWithoutPathExpansion(origin_string_,
+ &origin_dict);
+ DCHECK(origin_dict);
}
base::DictionaryValue* sessions_dict = nullptr;
diff --git a/chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc b/chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc
index 6a1610ee5a3..daf0c8f6f86 100644
--- a/chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc
+++ b/chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc
@@ -143,7 +143,7 @@ TEST_F(MediaDrmStorageImplTest, OnProvisioned_Twice) {
}
TEST_F(MediaDrmStorageImplTest, SaveSession_Unprovisioned) {
- SavePersistentSession("session_id", {1, 0}, "mime/type", false);
+ SaveAndLoadPersistentSession("session_id", {1, 0}, "mime/type1");
base::RunLoop().RunUntilIdle();
}
diff --git a/chromium/components/certificate_reporting/error_report.cc b/chromium/components/certificate_reporting/error_report.cc
index dc3eb53cd08..a48e18c80f1 100644
--- a/chromium/components/certificate_reporting/error_report.cc
+++ b/chromium/components/certificate_reporting/error_report.cc
@@ -93,10 +93,7 @@ ErrorReport::ErrorReport(const std::string& hostname,
#if defined(OS_ANDROID)
CertLoggerFeaturesInfo* features_info = cert_report_->mutable_features_info();
features_info->set_android_aia_fetching_status(
- base::FeatureList::IsEnabled(
- net::CertVerifyProcAndroid::kAIAFetchingFeature)
- ? CertLoggerFeaturesInfo::ANDROID_AIA_FETCHING_ENABLED
- : CertLoggerFeaturesInfo::ANDROID_AIA_FETCHING_DISABLED);
+ CertLoggerFeaturesInfo::ANDROID_AIA_FETCHING_ENABLED);
#endif
}
diff --git a/chromium/components/certificate_reporting/error_report_unittest.cc b/chromium/components/certificate_reporting/error_report_unittest.cc
index d29fb91ffbf..18c548ca473 100644
--- a/chromium/components/certificate_reporting/error_report_unittest.cc
+++ b/chromium/components/certificate_reporting/error_report_unittest.cc
@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/threading/thread.h"
#include "base/time/default_clock.h"
@@ -241,31 +242,8 @@ TEST(ErrorReportTest, NetworkTimeQueryingFeatureInfo) {
#if defined(OS_ANDROID)
// Tests that information about the Android AIA fetching feature is included in
-// the report when the feature is disabled.
-TEST(ErrorReportTest, AndroidAIAFetchingFeatureDisabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndDisableFeature(
- net::CertVerifyProcAndroid::kAIAFetchingFeature);
-
- SSLInfo ssl_info;
- ASSERT_NO_FATAL_FAILURE(
- GetTestSSLInfo(INCLUDE_UNVERIFIED_CERT_CHAIN, &ssl_info, kCertStatus));
- ErrorReport report(kDummyHostname, ssl_info);
- std::string serialized_report;
- ASSERT_TRUE(report.Serialize(&serialized_report));
- CertLoggerRequest parsed;
- ASSERT_TRUE(parsed.ParseFromString(serialized_report));
- EXPECT_EQ(CertLoggerFeaturesInfo::ANDROID_AIA_FETCHING_DISABLED,
- parsed.features_info().android_aia_fetching_status());
-}
-
-// Tests that information about the Android AIA fetching feature is included in
-// the report when the feature is enabled.
+// the report.
TEST(ErrorReportTest, AndroidAIAFetchingFeatureEnabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(
- net::CertVerifyProcAndroid::kAIAFetchingFeature);
-
SSLInfo ssl_info;
ASSERT_NO_FATAL_FAILURE(
GetTestSSLInfo(INCLUDE_UNVERIFIED_CERT_CHAIN, &ssl_info, kCertStatus));
diff --git a/chromium/components/certificate_reporting/error_reporter.cc b/chromium/components/certificate_reporting/error_reporter.cc
index 3ab3a3c9cec..5065e45cbe2 100644
--- a/chromium/components/certificate_reporting/error_reporter.cc
+++ b/chromium/components/certificate_reporting/error_reporter.cc
@@ -15,6 +15,7 @@
#include "crypto/aead.h"
#include "crypto/hkdf.h"
#include "crypto/random.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/report_sender.h"
#include "third_party/boringssl/src/include/openssl/curve25519.h"
@@ -98,17 +99,50 @@ bool EncryptSerializedReport(const uint8_t* server_public_key,
return true;
}
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("safe_browsing_extended_reporting", R"(
+ semantics {
+ sender: "Safe Browsing Extended Reporting"
+ description:
+ "When a user has opted in to Safe Browsing Extended Reporting, "
+ "Chrome will send information about HTTPS certificate errors that "
+ "the user encounters to Google. This information includes the "
+ "certificate chain and the type of error encountered. The "
+ "information is used to understand and mitigate common causes of "
+ "spurious certificate errors."
+ trigger:
+ "When the user encounters an HTTPS certificate error and has opted "
+ "in to Safe Browsing Extended Reporting."
+ data:
+ "The hostname that was requested, the certificate chain, the time "
+ "of the request, information about the type of certificate error "
+ "that was encountered, and whether the user was opted in to a "
+ "limited set of field trials that affect certificate validation."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can control this feature via the 'Automatically report "
+ "details of possible security incidents to Google' setting under "
+ "'Privacy'. The feature is disabled by default."
+ chrome_policy {
+ SafeBrowsingExtendedReportingOptInAllowed {
+ policy_options {mode: MANDATORY}
+ SafeBrowsingExtendedReportingOptInAllowed: false
+ }
+ }
+ })");
+
} // namespace
-ErrorReporter::ErrorReporter(
- net::URLRequestContext* request_context,
- const GURL& upload_url,
- net::ReportSender::CookiesPreference cookies_preference)
+ErrorReporter::ErrorReporter(net::URLRequestContext* request_context,
+ const GURL& upload_url)
: ErrorReporter(upload_url,
kServerPublicKey,
kServerPublicKeyVersion,
base::MakeUnique<net::ReportSender>(request_context,
- cookies_preference)) {}
+ kTrafficAnnotation)) {}
ErrorReporter::ErrorReporter(
const GURL& upload_url,
@@ -128,7 +162,7 @@ ErrorReporter::~ErrorReporter() {}
void ErrorReporter::SendExtendedReportingReport(
const std::string& serialized_report,
const base::Callback<void()>& success_callback,
- const base::Callback<void(const GURL&, int)>& error_callback) {
+ const base::Callback<void(const GURL&, int, int)>& error_callback) {
if (upload_url_.SchemeIsCryptographic()) {
certificate_report_sender_->Send(upload_url_, "application/octet-stream",
serialized_report, success_callback,
diff --git a/chromium/components/certificate_reporting/error_reporter.h b/chromium/components/certificate_reporting/error_reporter.h
index a02610862e2..12ba6943d19 100644
--- a/chromium/components/certificate_reporting/error_reporter.h
+++ b/chromium/components/certificate_reporting/error_reporter.h
@@ -30,11 +30,9 @@ class ErrorReporter {
public:
// Creates a certificate error reporter that will send certificate
// error reports to |upload_url|, using |request_context| as the
- // context for the reports. |cookies_preference| controls whether
- // cookies will be sent along with the reports.
+ // context for the reports.
ErrorReporter(net::URLRequestContext* request_context,
- const GURL& upload_url,
- net::ReportSender::CookiesPreference cookies_preference);
+ const GURL& upload_url);
// Allows tests to use a server public key with known private key and
// a mock ReportSender. |server_public_key| must outlive
@@ -60,10 +58,18 @@ class ErrorReporter {
// an HTTP endpoint to send encrypted extended reporting reports. On
// unsupported platforms, callers must send extended reporting reports
// over SSL.
+ //
+ //
+ // Calls |success_callback| when the report is successfully sent and the
+ // server returns an HTTP 200 response.
+ // In all other cases, calls |error_callback| with the URL of the upload,
+ // net error and HTTP response code parameters.
virtual void SendExtendedReportingReport(
const std::string& serialized_report,
const base::Callback<void()>& success_callback,
- const base::Callback<void(const GURL&, int)>& error_callback);
+ const base::Callback<void(const GURL&,
+ int /* net_error */,
+ int /* http_response_code */)>& error_callback);
// Used by tests.
static bool DecryptErrorReport(
diff --git a/chromium/components/certificate_reporting/error_reporter_unittest.cc b/chromium/components/certificate_reporting/error_reporter_unittest.cc
index 076049dd916..8807ea1de03 100644
--- a/chromium/components/certificate_reporting/error_reporter_unittest.cc
+++ b/chromium/components/certificate_reporting/error_reporter_unittest.cc
@@ -17,8 +17,10 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "components/certificate_reporting/encrypted_cert_logger.pb.h"
+#include "net/http/http_status_code.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/test/url_request/url_request_mock_data_job.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/report_sender.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,8 +35,12 @@ const char kDummyHttpsReportUri[] = "https://example.test";
const char kDummyReport[] = "a dummy report";
const uint32_t kServerPublicKeyTestVersion = 16;
-void ErrorCallback(bool* called, const GURL& report_uri, int net_error) {
+void ErrorCallback(bool* called,
+ const GURL& report_uri,
+ int net_error,
+ int http_response_code) {
EXPECT_NE(net::OK, net_error);
+ EXPECT_EQ(-1, http_response_code);
*called = true;
}
@@ -47,15 +53,15 @@ void SuccessCallback(bool* called) {
class MockCertificateReportSender : public net::ReportSender {
public:
MockCertificateReportSender()
- : net::ReportSender(nullptr, DO_NOT_SEND_COOKIES) {}
+ : net::ReportSender(nullptr, TRAFFIC_ANNOTATION_FOR_TESTS) {}
~MockCertificateReportSender() override {}
- void Send(
- const GURL& report_uri,
- base::StringPiece content_type,
- base::StringPiece report,
- const base::Callback<void()>& success_callback,
- const base::Callback<void(const GURL&, int)>& error_callback) override {
+ void Send(const GURL& report_uri,
+ base::StringPiece content_type,
+ base::StringPiece report,
+ const base::Callback<void()>& success_callback,
+ const base::Callback<void(const GURL&, int, int)>& error_callback)
+ override {
latest_report_uri_ = report_uri;
report.CopyToString(&latest_report_);
content_type.CopyToString(&latest_content_type_);
@@ -127,19 +133,21 @@ TEST_F(ErrorReporterTest, ExtendedReportingSendReport) {
kServerPublicKeyTestVersion,
base::WrapUnique(mock_report_sender));
https_reporter.SendExtendedReportingReport(
- kDummyReport, base::Closure(), base::Callback<void(const GURL&, int)>());
+ kDummyReport, base::Callback<void()>(),
+ base::Callback<void(const GURL&, int, int)>());
EXPECT_EQ(mock_report_sender->latest_report_uri(), https_url);
EXPECT_EQ(mock_report_sender->latest_report(), kDummyReport);
// Data should be encrypted when sent to an HTTP URL.
MockCertificateReportSender* http_mock_report_sender =
new MockCertificateReportSender();
- GURL http_url(kDummyHttpReportUri);
+ const GURL http_url(kDummyHttpReportUri);
ErrorReporter http_reporter(http_url, server_public_key_,
kServerPublicKeyTestVersion,
base::WrapUnique(http_mock_report_sender));
http_reporter.SendExtendedReportingReport(
- kDummyReport, base::Closure(), base::Callback<void(const GURL&, int)>());
+ kDummyReport, base::Callback<void()>(),
+ base::Callback<void(const GURL&, int, int)>());
EXPECT_EQ(http_mock_report_sender->latest_report_uri(), http_url);
EXPECT_EQ("application/octet-stream",
@@ -170,10 +178,9 @@ TEST_F(ErrorReporterTest, ErroredRequestCallsCallback) {
context.set_network_delegate(&test_delegate);
context.Init();
- GURL report_uri(
+ const GURL report_uri(
net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_FAILED));
- ErrorReporter reporter(&context, report_uri,
- net::ReportSender::DO_NOT_SEND_COOKIES);
+ ErrorReporter reporter(&context, report_uri);
bool error_callback_called = false;
bool success_callback_called = false;
@@ -186,7 +193,7 @@ TEST_F(ErrorReporterTest, ErroredRequestCallsCallback) {
EXPECT_FALSE(success_callback_called);
}
-// Tests that an UMA histogram is recorded if a report fails to send.
+// Tests that an UMA histogram is recorded if a report is successfully sent.
TEST_F(ErrorReporterTest, SuccessfulRequestCallsCallback) {
net::URLRequestMockDataJob::AddUrlHandler();
@@ -197,9 +204,9 @@ TEST_F(ErrorReporterTest, SuccessfulRequestCallsCallback) {
context.set_network_delegate(&test_delegate);
context.Init();
- GURL report_uri(net::URLRequestMockDataJob::GetMockHttpUrl("some data", 1));
- ErrorReporter reporter(&context, report_uri,
- net::ReportSender::DO_NOT_SEND_COOKIES);
+ const GURL report_uri(
+ net::URLRequestMockDataJob::GetMockHttpUrl("some data", 1));
+ ErrorReporter reporter(&context, report_uri);
bool error_callback_called = false;
bool success_callback_called = false;
diff --git a/chromium/components/certificate_transparency/BUILD.gn b/chromium/components/certificate_transparency/BUILD.gn
index bf687c9c7cf..ef07c14a1f5 100644
--- a/chromium/components/certificate_transparency/BUILD.gn
+++ b/chromium/components/certificate_transparency/BUILD.gn
@@ -8,8 +8,6 @@ static_library("certificate_transparency") {
"ct_policy_manager.h",
"log_dns_client.cc",
"log_dns_client.h",
- "log_proof_fetcher.cc",
- "log_proof_fetcher.h",
"pref_names.cc",
"pref_names.h",
"single_tree_tracker.cc",
@@ -35,7 +33,6 @@ source_set("unit_tests") {
sources = [
"ct_policy_manager_unittest.cc",
"log_dns_client_unittest.cc",
- "log_proof_fetcher_unittest.cc",
"mock_log_dns_traffic.cc",
"mock_log_dns_traffic.h",
"single_tree_tracker_unittest.cc",
diff --git a/chromium/components/certificate_transparency/ct_policy_manager_unittest.cc b/chromium/components/certificate_transparency/ct_policy_manager_unittest.cc
index e535f98baa3..6a2d53b361f 100644
--- a/chromium/components/certificate_transparency/ct_policy_manager_unittest.cc
+++ b/chromium/components/certificate_transparency/ct_policy_manager_unittest.cc
@@ -6,6 +6,7 @@
#include <iterator>
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/components/certificate_transparency/log_proof_fetcher.cc b/chromium/components/certificate_transparency/log_proof_fetcher.cc
deleted file mode 100644
index 4a1a3902d0b..00000000000
--- a/chromium/components/certificate_transparency/log_proof_fetcher.cc
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright 2015 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/certificate_transparency/log_proof_fetcher.h"
-
-#include <iterator>
-#include <memory>
-
-#include "base/callback_helpers.h"
-#include "base/format_macros.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/values.h"
-#include "components/safe_json/safe_json_parser.h"
-#include "net/base/io_buffer.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/base/request_priority.h"
-#include "net/cert/ct_log_response_parser.h"
-#include "net/cert/signed_tree_head.h"
-#include "net/http/http_status_code.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-#include "url/gurl.h"
-
-namespace certificate_transparency {
-
-namespace {
-
-// Class for issuing a particular request from a CT log and assembling the
-// response.
-// Creates the URLRequest instance for fetching the URL from the log
-// (supplied as |request_url| in the c'tor) and implements the
-// URLRequest::Delegate interface for assembling the response.
-class LogFetcher : public net::URLRequest::Delegate {
- public:
- using FailureCallback = base::Callback<void(int, int)>;
-
- LogFetcher(net::URLRequestContext* request_context,
- const GURL& request_url,
- const base::Closure& success_callback,
- const FailureCallback& failure_callback);
- ~LogFetcher() override {}
-
- // net::URLRequest::Delegate
- void OnResponseStarted(net::URLRequest* request, int net_error) override;
- void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
-
- const std::string& assembled_response() const { return assembled_response_; }
-
- private:
- // Handles the final result of a URLRequest::Read call on the request.
- // Returns true if another read should be started, false if the read
- // failed completely or we have to wait for OnResponseStarted to
- // be called.
- bool HandleReadResult(int result);
-
- // Calls URLRequest::Read on |request| repeatedly, until HandleReadResult
- // indicates it should no longer be called. Usually this would be when there
- // is pending IO that requires waiting for OnResponseStarted to be called.
- void StartNextReadLoop();
-
- // Invokes the success callback. After this method is called, the LogFetcher
- // is deleted and no longer safe to call.
- void RequestComplete();
-
- // Invokes the failure callback with the supplied error information.
- // After this method the LogFetcher is deleted and no longer safe to call.
- void InvokeFailureCallback(int net_error, int http_response_code);
-
- std::unique_ptr<net::URLRequest> url_request_;
- const GURL request_url_;
- base::Closure success_callback_;
- FailureCallback failure_callback_;
- scoped_refptr<net::IOBufferWithSize> response_buffer_;
- std::string assembled_response_;
-
- DISALLOW_COPY_AND_ASSIGN(LogFetcher);
-};
-
-LogFetcher::LogFetcher(net::URLRequestContext* request_context,
- const GURL& request_url,
- const base::Closure& success_callback,
- const FailureCallback& failure_callback)
- : request_url_(request_url),
- success_callback_(success_callback),
- failure_callback_(failure_callback) {
- DCHECK(request_url_.SchemeIsHTTPOrHTTPS());
- url_request_ =
- request_context->CreateRequest(request_url_, net::DEFAULT_PRIORITY, this);
- // This request should not send any cookies or otherwise identifying data,
- // as CT logs are expected to be publicly-accessible and connections to them
- // stateless.
- url_request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
-
- url_request_->Start();
-}
-
-void LogFetcher::OnResponseStarted(net::URLRequest* request, int net_error) {
- DCHECK_NE(net::ERR_IO_PENDING, net_error);
- DCHECK_EQ(url_request_.get(), request);
- int http_response_code = request->GetResponseCode();
-
- if (net_error != net::OK) {
- InvokeFailureCallback(net_error, http_response_code);
- return;
- }
-
- if (http_response_code != net::HTTP_OK) {
- InvokeFailureCallback(net::OK, http_response_code);
- return;
- }
-
- // Lazily initialize |response_buffer_| to avoid consuming memory until an
- // actual response has been received.
- if (!response_buffer_) {
- response_buffer_ =
- new net::IOBufferWithSize(LogProofFetcher::kMaxLogResponseSizeInBytes);
- }
-
- StartNextReadLoop();
-}
-
-void LogFetcher::OnReadCompleted(net::URLRequest* request, int bytes_read) {
- DCHECK_EQ(url_request_.get(), request);
-
- if (HandleReadResult(bytes_read))
- StartNextReadLoop();
-}
-
-bool LogFetcher::HandleReadResult(int result) {
- if (result == net::ERR_IO_PENDING)
- return false;
-
- if (result < 0) {
- InvokeFailureCallback(result, net::HTTP_OK);
- return false;
- }
-
- // Nothing more to read from the stream - finish handling the response.
- if (result == 0) {
- RequestComplete();
- return false;
- }
-
- // Data is available, collect it and indicate another read is needed.
- DCHECK_GE(result, 0);
- // |result| is non-negative at this point, casting to size_t should be
- // safe.
- if (base::checked_cast<size_t>(result) >
- LogProofFetcher::kMaxLogResponseSizeInBytes ||
- LogProofFetcher::kMaxLogResponseSizeInBytes <
- (assembled_response_.size() + result)) {
- // Log response is too big, invoke the failure callback.
- InvokeFailureCallback(net::ERR_FILE_TOO_BIG, net::HTTP_OK);
- return false;
- }
-
- assembled_response_.append(response_buffer_->data(), result);
- return true;
-}
-
-void LogFetcher::StartNextReadLoop() {
- bool continue_reading = true;
- while (continue_reading) {
- int read_bytes =
- url_request_->Read(response_buffer_.get(), response_buffer_->size());
- continue_reading = HandleReadResult(read_bytes);
- }
-}
-
-void LogFetcher::RequestComplete() {
- // Get rid of the buffer as it really isn't necessary.
- response_buffer_ = nullptr;
- base::ResetAndReturn(&success_callback_).Run();
- // NOTE: |this| is not valid after invoking the callback, as the LogFetcher
- // instance will be deleted by the callback.
-}
-
-void LogFetcher::InvokeFailureCallback(int net_error, int http_response_code) {
- base::ResetAndReturn(&failure_callback_).Run(net_error, http_response_code);
- // NOTE: |this| is not valid after this callback, as the LogFetcher instance
- // invoking the callback will be deleted by the callback.
-}
-
-} // namespace
-
-// Interface for handling the response from a CT log for a particular
-// request.
-// All log responses are JSON and should be parsed; however the response
-// to each request should be parsed and validated differently.
-//
-// LogResponseHandler instances should be deleted by the |done_callback| when
-// it is invoked.
-class LogResponseHandler {
- public:
- using DoneCallback = base::Callback<void(const base::Closure&)>;
-
- // |log_id| will be passed to the |failure_callback| to indicate which log
- // failures pretain to.
- LogResponseHandler(
- const std::string& log_id,
- const LogProofFetcher::FetchFailedCallback& failure_callback);
- virtual ~LogResponseHandler();
-
- // Starts the actual fetching from the URL, storing |done_callback| for
- // invocation when fetching and parsing of the request finished.
- // It is safe, and expected, to delete this object in the |done_callback|.
- void StartFetch(net::URLRequestContext* request_context,
- const GURL& request_url,
- const DoneCallback& done_callback);
-
- // Handle successful fetch by the LogFetcher (by parsing the JSON and
- // handing the parsed JSON to HandleParsedJson, which is request-specific).
- void HandleFetchCompletion();
-
- // Handle network failure to complete the request to the log, by invoking
- // the |done_callback_|.
- virtual void HandleNetFailure(int net_error, int http_response_code);
-
- protected:
- // Handle successful parsing of JSON by invoking HandleParsedJson, then
- // invoking the |done_callback_| with the returned Closure.
- void OnJsonParseSuccess(std::unique_ptr<base::Value> parsed_json);
-
- // Handle failure to parse the JSON by invoking HandleJsonParseFailure, then
- // invoking the |done_callback_| with the returned Closure.
- void OnJsonParseError(const std::string& error);
-
- // Handle respones JSON that parsed successfully, usually by
- // returning the success callback bound to parsed values as a Closure.
- virtual base::Closure HandleParsedJson(const base::Value& parsed_json) = 0;
-
- // Handle failure to parse response JSON, usually by returning the failure
- // callback bound to a request-specific net error code.
- virtual base::Closure HandleJsonParseFailure(
- const std::string& json_error) = 0;
-
- const std::string log_id_;
- LogProofFetcher::FetchFailedCallback failure_callback_;
- std::unique_ptr<LogFetcher> fetcher_;
- DoneCallback done_callback_;
-
- base::WeakPtrFactory<LogResponseHandler> weak_factory_;
-};
-
-LogResponseHandler::LogResponseHandler(
- const std::string& log_id,
- const LogProofFetcher::FetchFailedCallback& failure_callback)
- : log_id_(log_id),
- failure_callback_(failure_callback),
- fetcher_(nullptr),
- weak_factory_(this) {
- DCHECK(!failure_callback_.is_null());
-}
-
-LogResponseHandler::~LogResponseHandler() {}
-
-void LogResponseHandler::StartFetch(net::URLRequestContext* request_context,
- const GURL& request_url,
- const DoneCallback& done_callback) {
- done_callback_ = done_callback;
- fetcher_.reset(
- new LogFetcher(request_context, request_url,
- base::Bind(&LogResponseHandler::HandleFetchCompletion,
- weak_factory_.GetWeakPtr()),
- base::Bind(&LogResponseHandler::HandleNetFailure,
- weak_factory_.GetWeakPtr())));
-}
-
-void LogResponseHandler::HandleFetchCompletion() {
- safe_json::SafeJsonParser::Parse(
- fetcher_->assembled_response(),
- base::Bind(&LogResponseHandler::OnJsonParseSuccess,
- weak_factory_.GetWeakPtr()),
- base::Bind(&LogResponseHandler::OnJsonParseError,
- weak_factory_.GetWeakPtr()));
-
- // The assembled_response string is copied into the SafeJsonParser so it
- // is safe to get rid of the object that owns it.
- fetcher_.reset();
-}
-
-void LogResponseHandler::HandleNetFailure(int net_error,
- int http_response_code) {
- fetcher_.reset();
- LogProofFetcher::FetchFailedCallback failure_callback =
- base::ResetAndReturn(&failure_callback_);
-
- base::ResetAndReturn(&done_callback_)
- .Run(
- base::Bind(failure_callback, log_id_, net_error, http_response_code));
- // NOTE: |this| is not valid after the |done_callback_| is invoked.
-}
-
-void LogResponseHandler::OnJsonParseSuccess(
- std::unique_ptr<base::Value> parsed_json) {
- base::ResetAndReturn(&done_callback_).Run(HandleParsedJson(*parsed_json));
- // NOTE: |this| is not valid after the |done_callback_| is invoked.
-}
-
-void LogResponseHandler::OnJsonParseError(const std::string& error) {
- base::ResetAndReturn(&done_callback_).Run(HandleJsonParseFailure(error));
- // NOTE: |this| is not valid after the |done_callback_| is invoked.
-}
-
-class GetSTHLogResponseHandler : public LogResponseHandler {
- public:
- GetSTHLogResponseHandler(
- const std::string& log_id,
- const LogProofFetcher::SignedTreeHeadFetchedCallback& sth_fetch_callback,
- const LogProofFetcher::FetchFailedCallback& failure_callback)
- : LogResponseHandler(log_id, failure_callback),
- sth_fetched_(sth_fetch_callback) {}
-
- // Parses the JSON into a net::ct::SignedTreeHead and, if successful,
- // invokes the success callback with it. Otherwise, invokes the failure
- // callback indicating the error that occurred.
- base::Closure HandleParsedJson(const base::Value& parsed_json) override {
- net::ct::SignedTreeHead signed_tree_head;
- if (!net::ct::FillSignedTreeHead(parsed_json, &signed_tree_head)) {
- return base::Bind(base::ResetAndReturn(&failure_callback_), log_id_,
- net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK);
- }
- // The log id is not a part of the response, fill in manually.
- signed_tree_head.log_id = log_id_;
-
- return base::Bind(base::ResetAndReturn(&sth_fetched_), log_id_,
- signed_tree_head);
- }
-
- // Invoke the error callback indicating that STH parsing failed.
- base::Closure HandleJsonParseFailure(const std::string& json_error) override {
- return base::Bind(base::ResetAndReturn(&failure_callback_), log_id_,
- net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK);
- }
-
- private:
- LogProofFetcher::SignedTreeHeadFetchedCallback sth_fetched_;
-};
-
-class GetConsistencyProofLogResponseHandler : public LogResponseHandler {
- public:
- GetConsistencyProofLogResponseHandler(
- const std::string& log_id,
- const LogProofFetcher::ConsistencyProofFetchedCallback&
- proof_fetch_callback,
- const LogProofFetcher::FetchFailedCallback& failure_callback)
- : LogResponseHandler(log_id, failure_callback),
- proof_fetched_(proof_fetch_callback) {}
-
- // Fills a vector of strings with nodes from the received consistency proof
- // in |parsed_json|, and, if successful, invokes the success callback with the
- // vector. Otherwise, invokes the failure callback indicating proof parsing
- // has failed.
- base::Closure HandleParsedJson(const base::Value& parsed_json) override {
- std::vector<std::string> consistency_proof;
- if (!net::ct::FillConsistencyProof(parsed_json, &consistency_proof)) {
- return base::Bind(base::ResetAndReturn(&failure_callback_), log_id_,
- net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
- net::HTTP_OK);
- }
-
- return base::Bind(base::ResetAndReturn(&proof_fetched_), log_id_,
- consistency_proof);
- }
-
- // Invoke the error callback indicating proof fetching failed.
- base::Closure HandleJsonParseFailure(const std::string& json_error) override {
- return base::Bind(base::ResetAndReturn(&failure_callback_), log_id_,
- net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
- net::HTTP_OK);
- }
-
- private:
- LogProofFetcher::ConsistencyProofFetchedCallback proof_fetched_;
-};
-
-LogProofFetcher::LogProofFetcher(net::URLRequestContext* request_context)
- : request_context_(request_context), weak_factory_(this) {
- DCHECK(request_context);
-}
-
-LogProofFetcher::~LogProofFetcher() {
-}
-
-void LogProofFetcher::FetchSignedTreeHead(
- const GURL& base_log_url,
- const std::string& log_id,
- const SignedTreeHeadFetchedCallback& fetched_callback,
- const FetchFailedCallback& failed_callback) {
- GURL request_url = base_log_url.Resolve("ct/v1/get-sth");
- StartFetch(request_url, base::MakeUnique<GetSTHLogResponseHandler>(
- log_id, fetched_callback, failed_callback));
-}
-
-void LogProofFetcher::FetchConsistencyProof(
- const GURL& base_log_url,
- const std::string& log_id,
- uint64_t old_tree_size,
- uint64_t new_tree_size,
- const ConsistencyProofFetchedCallback& fetched_callback,
- const FetchFailedCallback& failed_callback) {
- GURL request_url = base_log_url.Resolve(base::StringPrintf(
- "ct/v1/get-sth-consistency?first=%" PRIu64 "&second=%" PRIu64,
- old_tree_size, new_tree_size));
- StartFetch(request_url,
- base::MakeUnique<GetConsistencyProofLogResponseHandler>(
- log_id, fetched_callback, failed_callback));
-}
-
-void LogProofFetcher::StartFetch(
- const GURL& request_url,
- std::unique_ptr<LogResponseHandler> log_request) {
- log_request->StartFetch(
- request_context_, request_url,
- base::Bind(&LogProofFetcher::OnFetchDone, weak_factory_.GetWeakPtr(),
- log_request.get()));
- inflight_fetches_.insert(std::move(log_request));
-}
-
-void LogProofFetcher::OnFetchDone(LogResponseHandler* log_handler,
- const base::Closure& requestor_callback) {
- auto it = std::find_if(
- inflight_fetches_.begin(), inflight_fetches_.end(),
- [log_handler](const std::unique_ptr<LogResponseHandler>& ptr) {
- return ptr.get() == log_handler;
- });
- DCHECK(it != inflight_fetches_.end());
-
- inflight_fetches_.erase(it);
- requestor_callback.Run();
-}
-
-} // namespace certificate_transparency
diff --git a/chromium/components/certificate_transparency/log_proof_fetcher.h b/chromium/components/certificate_transparency/log_proof_fetcher.h
deleted file mode 100644
index 53a52af659f..00000000000
--- a/chromium/components/certificate_transparency/log_proof_fetcher.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2015 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_CERTIFICATE_TRANSPARENCY_LOG_PROOF_FETCHER_H_
-#define COMPONENTS_CERTIFICATE_TRANSPARENCY_LOG_PROOF_FETCHER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-
-namespace net {
-
-class URLRequestContext;
-
-namespace ct {
-struct SignedTreeHead;
-} // namespace ct
-
-} // namespace net
-
-class GURL;
-
-namespace certificate_transparency {
-
-class LogResponseHandler;
-
-// Fetches Signed Tree Heads (STHs) and consistency proofs from Certificate
-// Transparency logs using the URLRequestContext provided during the instance
-// construction.
-// Must outlive the provided URLRequestContext.
-class LogProofFetcher {
- public:
- // Buffer size for log replies - currently the reply to
- // get-consistency-proof is the biggest one this class handles. 1500 bytes
- // should be enough to accommodate 31 proof nodes + JSON overhead, supporting
- // trees with up to 100 million entries.
- static const size_t kMaxLogResponseSizeInBytes = 1500;
-
- // Callback for successful retrieval of Signed Tree Heads. Called
- // with the log_id of the log the STH belogs to (as supplied by the caller
- // to FetchSignedTreeHead) and the STH itself.
- using SignedTreeHeadFetchedCallback =
- base::Callback<void(const std::string& log_id,
- const net::ct::SignedTreeHead& signed_tree_head)>;
-
- // Callback for failure of Signed Tree Head retrieval. Called with the log_id
- // that the log fetching was requested for and a net error code of the
- // failure.
- // |http_response_code| is meaningful only if |net_error| is net::OK.
- using FetchFailedCallback = base::Callback<
- void(const std::string& log_id, int net_error, int http_response_code)>;
-
- // Callback for successful retrieval of consistency proofs between two
- // STHs. Called with the log_id of the log the consistency belongs to (as
- // supplied by the caller to FetchConsistencyProof) and the vector of
- // proof nodes.
- using ConsistencyProofFetchedCallback =
- base::Callback<void(const std::string& log_id,
- const std::vector<std::string>& consistency_proof)>;
-
- explicit LogProofFetcher(net::URLRequestContext* request_context);
- ~LogProofFetcher();
-
- // Fetch the latest Signed Tree Head from the log identified by |log_id|
- // from |base_log_url|. The |log_id| will be passed into the callbacks to
- // identify the log the retrieved Signed Tree Head belongs to.
- // The callbacks won't be invoked if the request is destroyed before
- // fetching is completed.
- // It is possible, but does not make a lot of sense, to have multiple
- // Signed Tree Head fetching requests going out to the same log, since
- // they are likely to return the same result.
- // TODO(eranm): Think further about whether multiple requests to the same
- // log imply cancellation of previous requests, should be coalesced or handled
- // independently.
- void FetchSignedTreeHead(
- const GURL& base_log_url,
- const std::string& log_id,
- const SignedTreeHeadFetchedCallback& fetched_callback,
- const FetchFailedCallback& failed_callback);
-
- // Fetch a consistency proof between the Merkle trees identified by
- // |old_tree_size| and |new_tree_size| of the log identified by |log_id|
- // from |base_log_url|.
- //
- // See the documentation of FetchSignedTreeHead regarding request destruction
- // and multiple requests to the same log.
- void FetchConsistencyProof(
- const GURL& base_log_url,
- const std::string& log_id,
- uint64_t old_tree_size,
- uint64_t new_tree_size,
- const ConsistencyProofFetchedCallback& fetched_callback,
- const FetchFailedCallback& failed_callback);
-
- private:
- // Starts the fetch (by delegating to the LogResponseHandler)
- // and stores the |log_handler| in |inflight_fetches_| for later
- // cleanup.
- void StartFetch(const GURL& request_url,
- std::unique_ptr<LogResponseHandler> log_request);
-
- // Callback for when the fetch was done (successfully or not).
- // Deletes, and removes, the |log_handler| from the |inflight_fetches_|.
- // Additionally, invokes |caller_callback| which is typically
- // one of the callbacks provided to the Fetch... method, bound to
- // success/failure parameters.
- void OnFetchDone(LogResponseHandler* log_handler,
- const base::Closure& caller_callback);
-
- net::URLRequestContext* const request_context_;
-
- std::set<std::unique_ptr<LogResponseHandler>> inflight_fetches_;
-
- base::WeakPtrFactory<LogProofFetcher> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(LogProofFetcher);
-};
-
-} // namespace certificate_transparency
-
-#endif // COMPONENTS_CERTIFICATE_TRANSPARENCY_LOG_PROOF_FETCHER_H_
diff --git a/chromium/components/certificate_transparency/log_proof_fetcher_unittest.cc b/chromium/components/certificate_transparency/log_proof_fetcher_unittest.cc
deleted file mode 100644
index c46039ebf47..00000000000
--- a/chromium/components/certificate_transparency/log_proof_fetcher_unittest.cc
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright 2015 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/certificate_transparency/log_proof_fetcher.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/format_macros.h"
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "components/safe_json/testing_json_parser.h"
-#include "net/base/net_errors.h"
-#include "net/base/network_delegate.h"
-#include "net/cert/signed_tree_head.h"
-#include "net/http/http_status_code.h"
-#include "net/test/ct_test_util.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_filter.h"
-#include "net/url_request/url_request_interceptor.h"
-#include "net/url_request/url_request_job.h"
-#include "net/url_request/url_request_test_job.h"
-#include "net/url_request/url_request_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace certificate_transparency {
-
-namespace {
-
-const char kGetResponseHeaders[] =
- "HTTP/1.1 200 OK\n"
- "Content-Type: application/json; charset=ISO-8859-1\n";
-
-const char kGetResponseNotFoundHeaders[] =
- "HTTP/1.1 404 Not Found\n"
- "Content-Type: text/html; charset=iso-8859-1\n";
-
-const char kLogSchema[] = "https";
-const char kLogHost[] = "ct.log.example.com";
-const char kLogPathPrefix[] = "somelog";
-const char kLogID[] = "some_id";
-
-// Gets a dummy consistency proof for the given |node_id|.
-std::string GetDummyConsistencyProofNode(uint64_t node_id) {
- // Take the low 8 bits and repeat them as a string. This
- // has no special meaning, other than making it easier to
- // debug which consistency proof was used.
- return std::string(32, static_cast<char>(node_id));
-}
-
-// Number of nodes in a dummy consistency proof.
-const size_t kDummyConsistencyProofNumNodes = 4;
-
-class LogFetchTestJob : public net::URLRequestTestJob {
- public:
- LogFetchTestJob(const std::string& get_log_data,
- const std::string& get_log_headers,
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate)
- : URLRequestTestJob(request,
- network_delegate,
- get_log_headers,
- get_log_data,
- true),
- async_io_(false) {}
-
- void set_async_io(bool async_io) { async_io_ = async_io; }
-
- private:
- ~LogFetchTestJob() override {}
-
- bool NextReadAsync() override {
- // Response with indication of async IO only once, otherwise the final
- // Read would (incorrectly) be classified as async, causing the
- // URLRequestJob to try reading another time and failing on a CHECK
- // that the raw_read_buffer_ is not null.
- // According to mmenke@, this is a bug in the URLRequestTestJob code.
- // TODO(eranm): Once said bug is fixed, switch most tests to using async
- // IO.
- if (async_io_) {
- async_io_ = false;
- return true;
- }
- return false;
- }
-
- bool async_io_;
-
- DISALLOW_COPY_AND_ASSIGN(LogFetchTestJob);
-};
-
-class LogGetResponseHandler : public net::URLRequestInterceptor {
- public:
- LogGetResponseHandler()
- : async_io_(false),
- response_headers_(
- std::string(kGetResponseHeaders, arraysize(kGetResponseHeaders))) {}
- ~LogGetResponseHandler() override {}
-
- // URLRequestInterceptor implementation:
- net::URLRequestJob* MaybeInterceptRequest(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override {
- EXPECT_EQ(expected_url_, request->url());
-
- LogFetchTestJob* job = new LogFetchTestJob(
- response_body_, response_headers_, request, network_delegate);
- job->set_async_io(async_io_);
- return job;
- }
-
- void set_response_body(const std::string& response_body) {
- response_body_ = response_body;
- }
-
- void set_response_headers(const std::string& response_headers) {
- response_headers_ = response_headers;
- }
-
- void set_async_io(bool async_io) { async_io_ = async_io; }
-
- void set_expected_url(const GURL& url) { expected_url_ = url; }
-
- private:
- bool async_io_;
- std::string response_body_;
- std::string response_headers_;
-
- // Stored for test body to assert on
- GURL expected_url_;
-
- DISALLOW_COPY_AND_ASSIGN(LogGetResponseHandler);
-};
-
-enum InterceptedResultType {
- NOTHING,
- FAILURE,
- STH_FETCH,
- CONSISTENCY_PROOF_FETCH
-};
-
-class RecordFetchCallbackInvocations {
- public:
- RecordFetchCallbackInvocations(bool expect_success)
- : expect_success_(expect_success),
- net_error_(net::OK),
- http_response_code_(-1),
- request_type_(NOTHING) {}
-
- void STHFetched(base::Closure quit_closure,
- const std::string& log_id,
- const net::ct::SignedTreeHead& sth) {
- ASSERT_TRUE(expect_success_);
- ASSERT_EQ(NOTHING, request_type_);
- request_type_ = STH_FETCH;
- sth_ = sth;
- log_id_ = log_id;
- quit_closure.Run();
- }
-
- void ConsistencyProofFetched(
- base::Closure quit_closure,
- const std::string& log_id,
- const std::vector<std::string>& consistency_proof) {
- ASSERT_TRUE(expect_success_);
- ASSERT_EQ(NOTHING, request_type_);
- request_type_ = CONSISTENCY_PROOF_FETCH;
- consistency_proof_.assign(consistency_proof.begin(),
- consistency_proof.end());
- log_id_ = log_id;
- quit_closure.Run();
- }
-
- void FetchingFailed(base::Closure quit_closure,
- const std::string& log_id,
- int net_error,
- int http_response_code) {
- ASSERT_FALSE(expect_success_);
- ASSERT_EQ(NOTHING, request_type_);
- request_type_ = FAILURE;
- net_error_ = net_error;
- http_response_code_ = http_response_code;
- if (net_error_ == net::OK) {
- EXPECT_NE(net::HTTP_OK, http_response_code_);
- }
-
- quit_closure.Run();
- }
-
- InterceptedResultType intercepted_result_type() const {
- return request_type_;
- }
-
- int net_error() const { return net_error_; }
-
- int http_response_code() const { return http_response_code_; }
-
- const net::ct::SignedTreeHead& intercepted_sth() const { return sth_; }
-
- const std::string& intercepted_log_id() const { return log_id_; }
-
- const std::vector<std::string>& intercepted_proof() const {
- return consistency_proof_;
- }
-
- private:
- const bool expect_success_;
- int net_error_;
- int http_response_code_;
- InterceptedResultType request_type_;
- net::ct::SignedTreeHead sth_;
- std::string log_id_;
- std::vector<std::string> consistency_proof_;
-};
-
-class LogProofFetcherTest : public ::testing::Test {
- public:
- LogProofFetcherTest()
- : log_url_(base::StringPrintf("%s://%s/%s/",
- kLogSchema,
- kLogHost,
- kLogPathPrefix)) {
- std::unique_ptr<LogGetResponseHandler> handler(new LogGetResponseHandler());
- handler_ = handler.get();
-
- net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
- kLogSchema, kLogHost, std::move(handler));
-
- fetcher_.reset(new LogProofFetcher(&context_));
- }
-
- ~LogProofFetcherTest() override {
- net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(kLogSchema,
- kLogHost);
- }
-
- protected:
- void SetValidSTHJSONResponse() {
- std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
- handler_->set_response_body(sth_json_reply_data);
- handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
- }
-
- void RunFetcherWithCallback(RecordFetchCallbackInvocations* callback) {
- fetcher_->FetchSignedTreeHead(
- log_url_, kLogID,
- base::Bind(&RecordFetchCallbackInvocations::STHFetched,
- base::Unretained(callback), run_loop_.QuitClosure()),
- base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
- base::Unretained(callback), run_loop_.QuitClosure()));
- run_loop_.Run();
- }
-
- void RunGetConsistencyFetcherWithCallback(
- RecordFetchCallbackInvocations* callback) {
- const uint64_t kOldTree = 5;
- const uint64_t kNewTree = 8;
- handler_->set_expected_url(log_url_.Resolve(base::StringPrintf(
- "ct/v1/get-sth-consistency?first=%" PRIu64 "&second=%" PRIu64, kOldTree,
- kNewTree)));
- fetcher_->FetchConsistencyProof(
- log_url_, kLogID, kOldTree, kNewTree,
- base::Bind(&RecordFetchCallbackInvocations::ConsistencyProofFetched,
- base::Unretained(callback), run_loop_.QuitClosure()),
- base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
- base::Unretained(callback), run_loop_.QuitClosure()));
- run_loop_.Run();
- }
-
- void VerifyReceivedSTH(const std::string& log_id,
- const net::ct::SignedTreeHead& sth) {
- net::ct::SignedTreeHead expected_sth;
- net::ct::GetSampleSignedTreeHead(&expected_sth);
-
- EXPECT_EQ(kLogID, log_id);
- EXPECT_EQ(expected_sth.version, sth.version);
- EXPECT_EQ(expected_sth.timestamp, sth.timestamp);
- EXPECT_EQ(expected_sth.tree_size, sth.tree_size);
- EXPECT_STREQ(expected_sth.sha256_root_hash, sth.sha256_root_hash);
- EXPECT_EQ(expected_sth.signature.hash_algorithm,
- sth.signature.hash_algorithm);
- EXPECT_EQ(expected_sth.signature.signature_algorithm,
- sth.signature.signature_algorithm);
- EXPECT_EQ(expected_sth.signature.signature_data,
- sth.signature.signature_data);
- EXPECT_EQ(kLogID, sth.log_id);
- }
-
- void VerifyConsistencyProof(
- const std::string& log_id,
- const std::vector<std::string>& consistency_proof) {
- EXPECT_EQ(kLogID, log_id);
- EXPECT_EQ(kDummyConsistencyProofNumNodes, consistency_proof.size());
- for (uint64_t i = 0; i < kDummyConsistencyProofNumNodes; ++i) {
- EXPECT_EQ(GetDummyConsistencyProofNode(i), consistency_proof[i])
- << " node: " << i;
- }
- }
-
- // The |message_loop_|, while seemingly unused, is necessary
- // for URL request interception. That is the message loop that
- // will be used by the RunLoop.
- base::MessageLoopForIO message_loop_;
- base::RunLoop run_loop_;
- net::TestURLRequestContext context_;
- safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_;
- std::unique_ptr<LogProofFetcher> fetcher_;
- const GURL log_url_;
- LogGetResponseHandler* handler_;
-};
-
-TEST_F(LogProofFetcherTest, TestValidGetReply) {
- SetValidSTHJSONResponse();
-
- RecordFetchCallbackInvocations callback(true);
-
- RunFetcherWithCallback(&callback);
-
- ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
- VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
-}
-
-TEST_F(LogProofFetcherTest, TestValidGetReplyAsyncIO) {
- SetValidSTHJSONResponse();
- handler_->set_async_io(true);
-
- RecordFetchCallbackInvocations callback(true);
- RunFetcherWithCallback(&callback);
-
- ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
- VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
-}
-
-TEST_F(LogProofFetcherTest, TestInvalidGetReplyIncompleteJSON) {
- std::string sth_json_reply_data = net::ct::CreateSignedTreeHeadJsonString(
- 21 /* tree_size */, 123456u /* timestamp */, std::string(),
- std::string());
- handler_->set_response_body(sth_json_reply_data);
- handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
-
- RecordFetchCallbackInvocations callback(false);
- RunFetcherWithCallback(&callback);
-
- ASSERT_EQ(FAILURE, callback.intercepted_result_type());
- EXPECT_EQ(net::ERR_CT_STH_INCOMPLETE, callback.net_error());
- EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
-}
-
-TEST_F(LogProofFetcherTest, TestInvalidGetReplyInvalidJSON) {
- std::string sth_json_reply_data = "{\"tree_size\":21,\"timestamp\":}";
- handler_->set_response_body(sth_json_reply_data);
- handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
-
- RecordFetchCallbackInvocations callback(false);
- RunFetcherWithCallback(&callback);
-
- ASSERT_EQ(FAILURE, callback.intercepted_result_type());
- EXPECT_EQ(net::ERR_CT_STH_PARSING_FAILED, callback.net_error());
- EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
-}
-
-TEST_F(LogProofFetcherTest, TestLogReplyIsTooLong) {
- std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
- // Add kMaxLogResponseSizeInBytes to make sure the response is too big.
- sth_json_reply_data.append(
- std::string(LogProofFetcher::kMaxLogResponseSizeInBytes, ' '));
- handler_->set_response_body(sth_json_reply_data);
- handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
-
- RecordFetchCallbackInvocations callback(false);
- RunFetcherWithCallback(&callback);
-
- ASSERT_EQ(FAILURE, callback.intercepted_result_type());
- EXPECT_EQ(net::ERR_FILE_TOO_BIG, callback.net_error());
- EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
-}
-
-TEST_F(LogProofFetcherTest, TestLogReplyIsExactlyMaxSize) {
- std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
- // Extend the reply to be exactly kMaxLogResponseSizeInBytes.
- sth_json_reply_data.append(std::string(
- LogProofFetcher::kMaxLogResponseSizeInBytes - sth_json_reply_data.size(),
- ' '));
- handler_->set_response_body(sth_json_reply_data);
- handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
-
- RecordFetchCallbackInvocations callback(true);
- RunFetcherWithCallback(&callback);
-
- ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
- VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
-}
-
-TEST_F(LogProofFetcherTest, TestLogRepliesWithHttpError) {
- handler_->set_response_headers(std::string(
- kGetResponseNotFoundHeaders, arraysize(kGetResponseNotFoundHeaders)));
- handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
-
- RecordFetchCallbackInvocations callback(false);
- RunFetcherWithCallback(&callback);
-
- ASSERT_EQ(FAILURE, callback.intercepted_result_type());
- EXPECT_EQ(net::OK, callback.net_error());
- EXPECT_EQ(net::HTTP_NOT_FOUND, callback.http_response_code());
-}
-
-TEST_F(LogProofFetcherTest, TestValidGetConsistencyValidReply) {
- std::vector<std::string> proof;
- for (uint64_t i = 0; i < kDummyConsistencyProofNumNodes; ++i)
- proof.push_back(GetDummyConsistencyProofNode(i));
-
- std::string consistency_proof_reply_data =
- net::ct::CreateConsistencyProofJsonString(proof);
- handler_->set_response_body(consistency_proof_reply_data);
-
- RecordFetchCallbackInvocations callback(true);
- RunGetConsistencyFetcherWithCallback(&callback);
-
- ASSERT_EQ(CONSISTENCY_PROOF_FETCH, callback.intercepted_result_type());
- VerifyConsistencyProof(callback.intercepted_log_id(),
- callback.intercepted_proof());
-}
-
-TEST_F(LogProofFetcherTest, TestInvalidGetConsistencyReplyInvalidJSON) {
- std::string consistency_proof_reply_data = "{\"consistency\": [1,2]}";
- handler_->set_response_body(consistency_proof_reply_data);
-
- RecordFetchCallbackInvocations callback(false);
- RunGetConsistencyFetcherWithCallback(&callback);
-
- ASSERT_EQ(FAILURE, callback.intercepted_result_type());
- EXPECT_EQ(net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED, callback.net_error());
- EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
-}
-
-} // namespace
-
-} // namespace certificate_transparency
diff --git a/chromium/components/certificate_transparency/single_tree_tracker.cc b/chromium/components/certificate_transparency/single_tree_tracker.cc
index f3d151e65b4..99fe13fc720 100644
--- a/chromium/components/certificate_transparency/single_tree_tracker.cc
+++ b/chromium/components/certificate_transparency/single_tree_tracker.cc
@@ -25,7 +25,6 @@
#include "net/log/net_log.h"
using net::SHA256HashValue;
-using net::ct::LogEntry;
using net::ct::MerkleAuditProof;
using net::ct::MerkleTreeLeaf;
using net::ct::SignedCertificateTimestamp;
@@ -33,10 +32,6 @@ using net::ct::SignedTreeHead;
// Overview of the process for auditing CT log entries
//
-// A CT log entry, represented by net::ct::LogEntry, is made up of the
-// end-entity certificate and the Signed Certificate Timestamp associated with
-// it.
-//
// In this file, obsered CT log entries are audited for inclusion in the CT log.
// A pre-requirement for auditing a log entry is having a Signed Tree Head (STH)
// from that log that is 24 hours (MMD period) after the timestamp in the SCT.
diff --git a/chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp b/chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp
deleted file mode 100644
index 2477d32bd06..00000000000
--- a/chromium/components/chrome_apps/webstore_widget/app/compiled_resources.gyp
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2015 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.
-{
- 'targets': [
- {
- 'target_name': 'main',
- 'variables': {
- 'depends': [
- '<@(cws_widget_container)',
- '../../../../third_party/jstemplate/compiled_resources.gyp:jstemplate',
- '../../../../ui/webui/resources/js/compiled_resources.gyp:i18n_template_no_process',
- '../../../../ui/webui/resources/js/load_time_data.js',
- ],
- 'externs': [
- '<(EXTERNS_DIR)/chrome_send.js',
- '<(EXTERNS_DIR)/chrome_extensions.js',
- '<(EXTERNS_DIR)/file_manager_private.js',
- '<(EXTERNS_DIR)/metrics_private.js',
- '../externs/chrome_webstore_widget_private.js',
- '../externs/webview_tag.js'
- ]
- },
- 'includes': [
- '../../../../third_party/closure_compiler/compile_js.gypi',
- '../cws_widget/compiled_resources.gypi'
- ]
- },
- {
- 'target_name': 'background',
- 'variables': {
- 'externs': [
- '<(EXTERNS_DIR)/chrome_extensions.js',
- '../externs/chrome_webstore_widget_private.js'
- ]
- },
- 'includes': [
- '../../../../third_party/closure_compiler/compile_js.gypi'
- ]
- }
- ]
-}
diff --git a/chromium/components/chrome_apps/webstore_widget/cws_widget/compiled_resources.gypi b/chromium/components/chrome_apps/webstore_widget/cws_widget/compiled_resources.gypi
deleted file mode 100644
index 7118a7b8edd..00000000000
--- a/chromium/components/chrome_apps/webstore_widget/cws_widget/compiled_resources.gypi
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2015 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.
-
-{
- 'variables': {
- 'WIDGET_ROOT': '<(DEPTH)/components/chrome_apps/webstore_widget/cws_widget',
- 'cws_widget_container': [
- '<(DEPTH)/ui/webui/resources/js/cr.js',
- '<(DEPTH)/ui/webui/resources/js/cr/event_target.js',
- '<(DEPTH)/ui/webui/resources/js/cr/ui/dialogs.js',
- '<(WIDGET_ROOT)/app_installer.js',
- '<(WIDGET_ROOT)/cws_webview_client.js',
- '<(WIDGET_ROOT)/cws_widget_container.js',
- '<(WIDGET_ROOT)/cws_widget_container_error_dialog.js',
- '<(WIDGET_ROOT)/cws_widget_container_platform_delegate.js',
- ]
- }
-}
diff --git a/chromium/components/chrome_cleaner/OWNERS b/chromium/components/chrome_cleaner/OWNERS
index e54e7edd113..c566d3401a2 100644
--- a/chromium/components/chrome_cleaner/OWNERS
+++ b/chromium/components/chrome_cleaner/OWNERS
@@ -2,4 +2,5 @@ csharp@chromium.org
joenotcharles@chromium.org
robertshield@chromium.org
+# TEAM: security-dev@chromium.org
# COMPONENT: UI>Browser>Preferences>Protector
diff --git a/chromium/components/chrome_cleaner/public/constants/BUILD.gn b/chromium/components/chrome_cleaner/public/constants/BUILD.gn
new file mode 100644
index 00000000000..826ffa6c879
--- /dev/null
+++ b/chromium/components/chrome_cleaner/public/constants/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2017 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.
+
+source_set("constants") {
+ sources = [
+ "constants.cc",
+ "constants.h",
+ ]
+}
diff --git a/chromium/components/chrome_cleaner/public/constants/constants.cc b/chromium/components/chrome_cleaner/public/constants/constants.cc
new file mode 100644
index 00000000000..89c10a267ba
--- /dev/null
+++ b/chromium/components/chrome_cleaner/public/constants/constants.cc
@@ -0,0 +1,46 @@
+// Copyright 2017 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/chrome_cleaner/public/constants/constants.h"
+
+namespace chrome_cleaner {
+
+// Command line switches.
+const char kChromeChannelSwitch[] = "chrome-channel";
+const char kChromeExePathSwitch[] = "chrome-exe-path";
+const char kChromeMojoPipeTokenSwitch[] = "chrome-mojo-pipe-token";
+const char kChromePromptSwitch[] = "chrome-prompt";
+const char kChromeSystemInstallSwitch[] = "chrome-system-install";
+const char kChromeVersionSwitch[] = "chrome-version";
+const char kEnableCleanerLoggingSwitch[] = "enable-cleaner-logging";
+const char kEnableCrashReportingSwitch[] = "enable-crash-reporting";
+const char kEngineExperimentGroupSwitch[] = "engine-experiment-group";
+const char kEngineSwitch[] = "engine";
+const char kExecutionModeSwitch[] = "execution-mode";
+const char kExtendedSafeBrowsingEnabledSwitch[] =
+ "extended-safebrowsing-enabled";
+const char kRegistrySuffixSwitch[] = "registry-suffix";
+const char kSessionIdSwitch[] = "session-id";
+const char kUmaUserSwitch[] = "uma-user";
+
+// Registry paths and subkeys.
+const wchar_t kSoftwareRemovalToolRegistryKey[] =
+ L"Software\\Google\\Software Removal Tool";
+const wchar_t kCleanerSubKey[] = L"Cleaner";
+const wchar_t kScanTimesSubKey[] = L"ScanTimes";
+
+// Registry value names.
+const wchar_t kEndTimeValueName[] = L"EndTime";
+const wchar_t kEngineErrorCodeValueName[] = L"EngineErrorCode";
+const wchar_t kExitCodeValueName[] = L"ExitCode";
+// Note: the lowercase "s" in "Uws" can't be fixed due to compatibility with
+// older versions.
+const wchar_t kFoundUwsValueName[] = L"FoundUws";
+const wchar_t kLogsUploadResultValueName[] = L"LogsUploadResult";
+const wchar_t kMemoryUsedValueName[] = L"MemoryUsed";
+const wchar_t kStartTimeValueName[] = L"StartTime";
+const wchar_t kUploadResultsValueName[] = L"UploadResults";
+const wchar_t kVersionValueName[] = L"Version";
+
+} // namespace chrome_cleaner
diff --git a/chromium/components/chrome_cleaner/public/constants/constants.h b/chromium/components/chrome_cleaner/public/constants/constants.h
new file mode 100644
index 00000000000..ad1b8af203b
--- /dev/null
+++ b/chromium/components/chrome_cleaner/public/constants/constants.h
@@ -0,0 +1,133 @@
+// Copyright 2017 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_CHROME_CLEANER_PUBLIC_CONSTANTS_CONSTANTS_H_
+#define COMPONENTS_CHROME_CLEANER_PUBLIC_CONSTANTS_CONSTANTS_H_
+
+// Constants shared by the Chromium and the Chrome Cleanaup tool repos.
+
+namespace chrome_cleaner {
+
+// Switches sent from Chrome to either the Software Reporter or the Chrome
+// Cleanup tool.
+
+// The current Chrome channel. The value of this flag is an integer with values
+// according to version_info::Channel enum.
+extern const char kChromeChannelSwitch[];
+
+// The path to Chrome's executable.
+extern const char kChromeExePathSwitch[];
+
+// The Mojo pipe token for IPC communication between the Software Reporter and
+// Chrome.
+extern const char kChromeMojoPipeTokenSwitch[];
+
+// Indicates that a cleaner run was started by Chrome.
+extern const char kChromePromptSwitch[];
+
+// Indicates that the current Chrome installation was a system-level
+// installation.
+extern const char kChromeSystemInstallSwitch[];
+
+// The Chrome version string.
+extern const char kChromeVersionSwitch[];
+
+// Indicates whether logs upload is enabled in the cleaner process. Should be
+// set by Chrome only be set if user has opted into Safe Browsing Extended
+// Reporting v2. Takes effect only if execution mode is not
+// ExecutionMode::kNone.
+extern const char kEnableCleanerLoggingSwitch[];
+
+// Indicates that crash reporting is enabled for the current user.
+extern const char kEnableCrashReportingSwitch[];
+
+// Specifies the name of experiment group in the alternate engine field trial
+// for a Software Reporter run.
+extern const char kEngineExperimentGroupSwitch[];
+
+// Specify the engine to use.
+extern const char kEngineSwitch[];
+
+// Indicates the execution mode for the Chrome Cleanup Tool. Possible values
+// defined in enum ExecutionMode.
+extern const char kExecutionModeSwitch[];
+
+// Indicates that the current user opted into Safe Browsing Extended Reporting.
+extern const char kExtendedSafeBrowsingEnabledSwitch[];
+
+// Specifies the suffix to the registry path where metrics data will be saved.
+extern const char kRegistrySuffixSwitch[];
+
+// Identifier used to group all reports generated during the same run of the
+// software reporter (which may include multiple invocations of the reporter
+/// binary, each generating a report). An ASCII, base-64 encoded random string.
+extern const char kSessionIdSwitch[];
+
+// Indicates that metrics reporting is enabled for the current user.
+extern const char kUmaUserSwitch[];
+
+// Registry paths where the reporter and the cleaner will write metrics data
+// to be reported by Chrome.
+
+// TODO(b/647763) Change the registry key to properly handle cases when the
+// user runs Google Chrome stable alongside Google Chrome SxS.
+extern const wchar_t kSoftwareRemovalToolRegistryKey[];
+
+// The suffix for the registry key where cleaner metrics are written to.
+extern const wchar_t kCleanerSubKey[];
+// The suffix for registry key paths where scan times will be written to.
+extern const wchar_t kScanTimesSubKey[];
+
+// Registry value names where metrics are written to.
+extern const wchar_t kEndTimeValueName[];
+extern const wchar_t kEngineErrorCodeValueName[];
+extern const wchar_t kExitCodeValueName[];
+extern const wchar_t kFoundUwsValueName[];
+extern const wchar_t kLogsUploadResultValueName[];
+extern const wchar_t kMemoryUsedValueName[];
+extern const wchar_t kStartTimeValueName[];
+extern const wchar_t kUploadResultsValueName[];
+extern const wchar_t kVersionValueName[];
+
+// Exit codes from the Software Reporter process identified by Chrome.
+constexpr int kSwReporterCleanupNeeded = 0;
+constexpr int kSwReporterNothingFound = 2;
+constexpr int kSwReporterPostRebootCleanupNeeded = 4;
+constexpr int kSwReporterDelayedPostRebootCleanupNeeded = 15;
+
+// Values to be passed to the kChromePromptSwitch of the Chrome Cleanup Tool to
+// indicate how the user interacted with the accept button.
+enum class ChromePromptValue {
+ // The user accepted the prompt when the prompt was first shown.
+ kPrompted = 3,
+ // The user accepted the prompt after navigating to it from the menu.
+ kShownFromMenu = 4
+};
+
+// Values to be passed to the kExecutionModeSwitch for the Chrome Cleanup Tool
+// to indicate the mode in which it should be executed.
+enum class ExecutionMode {
+ // No mode specified, which means the cleaner is running in legacy mode and
+ // will show its own UI and handle logs uploading permissions.
+ kNone = 0,
+ // The cleaner will run in scanning mode. No UI will be shown to the user
+ // (UI handled by Chrome) and logs will only be uploaded if the user opted
+ // into Extended Safe Browsing Reporting.
+ kScanning = 1,
+ // The cleaner will run in cleanup mode only. No UI will be shown to the
+ // user (UI handled by Chrome) and logs will only be uploaded if the user
+ // opted into Extended Safe Browsing Reporting v2.
+ kCleanup = 2,
+ // The cleaner will run in post-reboot validation mode. No UI will be shown
+ // to the user and logs will only be uploaded if the user opted into Extended
+ // Safe Browsing Reporting v2.
+ kPostRebootValidation = 3,
+
+ // Auxiliary enumerator for range checking.
+ kNumValues,
+};
+
+} // namespace chrome_cleaner
+
+#endif // COMPONENTS_CHROME_CLEANER_PUBLIC_CONSTANTS_CONSTANTS_H_
diff --git a/chromium/components/chrome_cleaner/public/interfaces/BUILD.gn b/chromium/components/chrome_cleaner/public/interfaces/BUILD.gn
index 039f1222a13..160898384a6 100644
--- a/chromium/components/chrome_cleaner/public/interfaces/BUILD.gn
+++ b/chromium/components/chrome_cleaner/public/interfaces/BUILD.gn
@@ -8,4 +8,7 @@ mojom("interfaces") {
sources = [
"chrome_prompt.mojom",
]
+ deps = [
+ "//mojo/common:common_custom_types",
+ ]
}
diff --git a/chromium/components/chrome_cleaner/public/interfaces/OWNERS b/chromium/components/chrome_cleaner/public/interfaces/OWNERS
index dd2568b89f3..7b93fe802a5 100644
--- a/chromium/components/chrome_cleaner/public/interfaces/OWNERS
+++ b/chromium/components/chrome_cleaner/public/interfaces/OWNERS
@@ -4,4 +4,5 @@ robertshield@chromium.org
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
+# TEAM: security-dev@chromium.org
# COMPONENT: UI>Browser>Preferences>Protector
diff --git a/chromium/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom b/chromium/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom
index 7458a8e3f67..b10a3a1db85 100644
--- a/chromium/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom
+++ b/chromium/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom
@@ -4,6 +4,8 @@
module chrome_cleaner.mojom;
+import "mojo/common/file_path.mojom";
+
// The behaviours that have been observed for a given UwS.
struct ObservedBehaviours {
bool ad_injector;
@@ -27,7 +29,7 @@ struct UwS {
// List of fully-qualified paths of the files that will be deleted by the
// Chrome Cleanup Tool for this unwanted software.
- array<string> files_to_delete;
+ array<mojo.common.mojom.FilePath> files_to_delete;
};
// Indicates if elevation will be required for cleanup.
diff --git a/chromium/components/component_updater/component_updater_service_unittest.cc b/chromium/components/component_updater/component_updater_service_unittest.cc
index c4e6199e88d..8cf31307d4d 100644
--- a/chromium/components/component_updater/component_updater_service_unittest.cc
+++ b/chromium/components/component_updater/component_updater_service_unittest.cc
@@ -17,8 +17,9 @@
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/task_scheduler/post_task.h"
#include "base/test/histogram_tester.h"
-#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "components/component_updater/component_updater_service_internal.h"
@@ -75,9 +76,11 @@ class MockUpdateClient : public UpdateClient {
bool(const std::string& id, CrxUpdateItem* update_item));
MOCK_CONST_METHOD1(IsUpdating, bool(const std::string& id));
MOCK_METHOD0(Stop, void());
- MOCK_METHOD3(
- SendUninstallPing,
- void(const std::string& id, const base::Version& version, int reason));
+ MOCK_METHOD4(SendUninstallPing,
+ void(const std::string& id,
+ const base::Version& version,
+ int reason,
+ const Callback& callback));
private:
~MockUpdateClient() override;
@@ -113,14 +116,10 @@ class ComponentUpdaterTest : public testing::Test {
void RunThreads();
private:
- static const int kNumWorkerThreads_ = 2;
-
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
base::RunLoop runloop_;
base::Closure quit_closure_;
- std::unique_ptr<base::SequencedWorkerPoolOwner> worker_pool_;
-
scoped_refptr<TestConfigurator> config_;
scoped_refptr<MockUpdateClient> update_client_;
std::unique_ptr<ComponentUpdateService> component_updater_;
@@ -175,14 +174,13 @@ std::unique_ptr<ComponentUpdateService> TestComponentUpdateServiceFactory(
}
ComponentUpdaterTest::ComponentUpdaterTest()
- : worker_pool_(
- new base::SequencedWorkerPoolOwner(kNumWorkerThreads_, "test")) {
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {
quit_closure_ = runloop_.QuitClosure();
- auto pool = worker_pool_->pool();
config_ = new TestConfigurator(
- pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
- message_loop_.task_runner());
+ base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
+ base::ThreadTaskRunnerHandle::Get());
update_client_ = new MockUpdateClient();
EXPECT_CALL(update_client(), AddObserver(_)).Times(1);
diff --git a/chromium/components/component_updater/default_component_installer_unittest.cc b/chromium/components/component_updater/default_component_installer_unittest.cc
index 60453322813..278e3aa36c2 100644
--- a/chromium/components/component_updater/default_component_installer_unittest.cc
+++ b/chromium/components/component_updater/default_component_installer_unittest.cc
@@ -10,9 +10,10 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
#include "components/component_updater/component_updater_service.h"
#include "components/component_updater/component_updater_service_internal.h"
@@ -59,9 +60,11 @@ class MockUpdateClient : public UpdateClient {
bool(const std::string& id, CrxUpdateItem* update_item));
MOCK_CONST_METHOD1(IsUpdating, bool(const std::string& id));
MOCK_METHOD0(Stop, void());
- MOCK_METHOD3(
- SendUninstallPing,
- void(const std::string& id, const base::Version& version, int reason));
+ MOCK_METHOD4(SendUninstallPing,
+ void(const std::string& id,
+ const base::Version& version,
+ int reason,
+ const Callback& callback));
private:
~MockUpdateClient() override {}
@@ -134,28 +137,23 @@ class DefaultComponentInstallerTest : public testing::Test {
void RunThreads();
private:
- static const int kNumWorkerThreads_ = 2;
-
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
base::RunLoop runloop_;
base::Closure quit_closure_;
- std::unique_ptr<base::SequencedWorkerPoolOwner> worker_pool_;
-
scoped_refptr<TestConfigurator> config_;
scoped_refptr<MockUpdateClient> update_client_;
std::unique_ptr<ComponentUpdateService> component_updater_;
};
DefaultComponentInstallerTest::DefaultComponentInstallerTest()
- : worker_pool_(
- new base::SequencedWorkerPoolOwner(kNumWorkerThreads_, "test")) {
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {
quit_closure_ = runloop_.QuitClosure();
- auto pool = worker_pool_->pool();
config_ = new TestConfigurator(
- pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
- message_loop_.task_runner());
+ base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
+ base::ThreadTaskRunnerHandle::Get());
update_client_ = new MockUpdateClient();
EXPECT_CALL(update_client(), AddObserver(_)).Times(1);
diff --git a/chromium/components/component_updater/timer_unittest.cc b/chromium/components/component_updater/timer_unittest.cc
index 2c80e84d2a2..c90ae025147 100644
--- a/chromium/components/component_updater/timer_unittest.cc
+++ b/chromium/components/component_updater/timer_unittest.cc
@@ -4,8 +4,8 @@
#include <string>
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "components/component_updater/timer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -16,11 +16,13 @@ namespace component_updater {
class ComponentUpdaterTimerTest : public testing::Test {
public:
- ComponentUpdaterTimerTest() {}
+ ComponentUpdaterTimerTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
~ComponentUpdaterTimerTest() override {}
private:
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
};
TEST_F(ComponentUpdaterTimerTest, Start) {
diff --git a/chromium/components/components_chromium_strings.grd b/chromium/components/components_chromium_strings.grd
index 7899407f17a..cb8023831f5 100644
--- a/chromium/components/components_chromium_strings.grd
+++ b/chromium/components/components_chromium_strings.grd
@@ -208,19 +208,18 @@
Chromium is made possible by the <ph name="BEGIN_LINK_CHROMIUM">&lt;a target="_blank" href="$1"&gt;</ph>Chromium<ph name="END_LINK_CHROMIUM">&lt;/a&gt;</ph> open source project and other <ph name="BEGIN_LINK_OSS">&lt;a target="_blank" href="$2"&gt;</ph>open source software<ph name="END_LINK_OSS">&lt;/a&gt;</ph>.
</message>
- <!-- Page Info bubble -->
+ <!-- Page Info -->
<message name="IDS_PAGE_INFO_INTERNAL_PAGE" desc="Message to display in the page info bubble when the page you are on is a chrome:// page or about:something.">
You're viewing a secure Chromium page
</message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_VERIFIED" desc="The text of the identity section when the page is secure and uses a valid certificate">
+ Chromium verified that <ph name="ISSUER">$1<ex>VeriSign</ex></ph> issued this website's certificate.
+ </message>
+ <!-- Session Crash -->
<message name="IDS_SESSION_CRASHED_VIEW_MESSAGE" desc="Message shown when the last session didn't exit cleanly.">
Chromium didn't shut down correctly.
</message>
-
- <!-- Strings describing Chromium security policy for DevTools security panel -->
- <message name="IDS_PRIVATE_USER_DATA_INPUT_DESCRIPTION" desc="Description of a security problem where the site collects private user data on an insecure page, which results in an omnibox warning." translateable="false">
- This page includes a password or credit card input over HTTP. A warning has been added to the URL bar.
- </message>
</messages>
</release>
</grit>
diff --git a/chromium/components/components_google_chrome_strings.grd b/chromium/components/components_google_chrome_strings.grd
index 34955ebc230..3c41235cc96 100644
--- a/chromium/components/components_google_chrome_strings.grd
+++ b/chromium/components/components_google_chrome_strings.grd
@@ -208,19 +208,18 @@
Google Chrome is made possible by the <ph name="BEGIN_LINK_CHROMIUM">&lt;a target="_blank" href="$1"&gt;</ph>Chromium<ph name="END_LINK_CHROMIUM">&lt;/a&gt;</ph> open source project and other <ph name="BEGIN_LINK_OSS">&lt;a target="_blank" href="$2"&gt;</ph>open source software<ph name="END_LINK_OSS">&lt;/a&gt;</ph>.
</message>
- <!-- Page Info bubble -->
+ <!-- Page Info -->
<message name="IDS_PAGE_INFO_INTERNAL_PAGE" desc="Message to display in the page info bubble when the page you are on is a chrome:// page or about:something.">
You're viewing a secure Google Chrome page
</message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_VERIFIED" desc="The text of the identity section when the page is secure and uses a valid certificate.">
+ Chrome verified that <ph name="ISSUER">$1<ex>VeriSign</ex></ph> issued this website's certificate.
+ </message>
+ <!-- Session Crash -->
<message name="IDS_SESSION_CRASHED_VIEW_MESSAGE" desc="Message shown when the last session didn't exit cleanly.">
Chrome didn't shut down correctly.
</message>
-
- <!-- Strings describing Chrome security policy for DevTools security panel -->
- <message name="IDS_PRIVATE_USER_DATA_INPUT_DESCRIPTION" desc="Description of a security problem where the site collects private user data on an insecure page, which results in an omnibox warning." translateable="false">
- This page includes a password or credit card input over HTTP. A warning has been added to the URL bar.
- </message>
</messages>
</release>
</grit>
diff --git a/chromium/components/components_strings.grd b/chromium/components/components_strings.grd
index 43c92320f6a..9b42f8965c7 100644
--- a/chromium/components/components_strings.grd
+++ b/chromium/components/components_strings.grd
@@ -277,6 +277,9 @@
Recently Closed
</message>
</if>
+ <message name="IDS_CHOOSE" desc="Label for a button to choose something, like a shipping address for a payment request. [CHAR-LIMIT=20]" formatter_data="android_java">
+ Choose
+ </message>
<!-- Accessibility labels for generic items -->
<message name="IDS_ACCNAME_BACK" desc="The accessible name for the back button.">
@@ -319,11 +322,6 @@
Open startup pages
</message>
- <!-- Page Info UI -->
- <message name="IDS_PAGE_INFO_NON_SECURE_TRANSPORT" desc="Text that is displayed in the header of the Website Settings popup if the website uses non-secure transport.">
- Your connection to this site is not private.
- </message>
-
<!-- Advanced Section Titles -->
<message name="IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY">
Privacy
diff --git a/chromium/components/constrained_window/constrained_window_views_unittest.cc b/chromium/components/constrained_window/constrained_window_views_unittest.cc
index b0c98d3f4d1..cf90bc88e88 100644
--- a/chromium/components/constrained_window/constrained_window_views_unittest.cc
+++ b/chromium/components/constrained_window/constrained_window_views_unittest.cc
@@ -32,22 +32,16 @@ class DialogContents : public views::DialogDelegateView {
DialogContents() {}
~DialogContents() override {}
- void set_preferred_size(const gfx::Size& preferred_size) {
- preferred_size_ = preferred_size;
- }
-
void set_modal_type(ui::ModalType modal_type) { modal_type_ = modal_type; }
// DialogDelegateView:
views::View* GetContentsView() override { return this; }
- gfx::Size GetPreferredSize() const override { return preferred_size_; }
gfx::Size GetMinimumSize() const override { return gfx::Size(); }
// WidgetDelegate:
ui::ModalType GetModalType() const override { return modal_type_; }
private:
- gfx::Size preferred_size_;
ui::ModalType modal_type_ = ui::MODAL_TYPE_NONE;
DISALLOW_COPY_AND_ASSIGN(DialogContents);
@@ -123,7 +117,7 @@ class ConstrainedWindowViewsTest : public views::ViewsTestBase {
// contents.
gfx::Size preferred_size = dialog()->GetRootView()->GetPreferredSize();
preferred_size.Enlarge(500, 500);
- contents()->set_preferred_size(preferred_size);
+ contents()->SetPreferredSize(preferred_size);
}
void TearDown() override {
@@ -161,7 +155,7 @@ TEST_F(ConstrainedWindowViewsTest, GrowModalDialogSize) {
gfx::Size preferred_size = contents()->GetPreferredSize();
expected_size.Enlarge(50, 50);
preferred_size.Enlarge(50, 50);
- contents()->set_preferred_size(preferred_size);
+ contents()->SetPreferredSize(preferred_size);
UpdateWidgetModalDialogPosition(dialog(), dialog_host());
EXPECT_EQ(expected_size.ToString(), GetDialogSize().ToString());
}
@@ -174,7 +168,7 @@ TEST_F(ConstrainedWindowViewsTest, ShrinkModalDialogSize) {
gfx::Size preferred_size = contents()->GetPreferredSize();
expected_size.Enlarge(-50, -50);
preferred_size.Enlarge(-50, -50);
- contents()->set_preferred_size(preferred_size);
+ contents()->SetPreferredSize(preferred_size);
UpdateWidgetModalDialogPosition(dialog(), dialog_host());
EXPECT_EQ(expected_size.ToString(), GetDialogSize().ToString());
}
@@ -236,7 +230,7 @@ TEST_F(ConstrainedWindowViewsTest, NullModalParent) {
// screen.
TEST_F(ConstrainedWindowViewsTest, ClampDialogToNearestDisplay) {
// Make sure the dialog will fit fully on the display
- contents()->set_preferred_size(gfx::Size(200, 100));
+ contents()->SetPreferredSize(gfx::Size(200, 100));
// First, make sure the host and dialog are sized and positioned.
UpdateWebContentsModalDialogPosition(dialog(), dialog_host());
diff --git a/chromium/components/content_settings/core/browser/BUILD.gn b/chromium/components/content_settings/core/browser/BUILD.gn
index 3e4fa6688f5..44e44e36352 100644
--- a/chromium/components/content_settings/core/browser/BUILD.gn
+++ b/chromium/components/content_settings/core/browser/BUILD.gn
@@ -54,6 +54,7 @@ static_library("browser") {
"//components/url_formatter",
"//extensions/features",
"//net",
+ "//services/preferences/public/cpp",
"//url",
]
diff --git a/chromium/components/content_settings/core/browser/DEPS b/chromium/components/content_settings/core/browser/DEPS
index eddae7bcb63..01dbe2ae6df 100644
--- a/chromium/components/content_settings/core/browser/DEPS
+++ b/chromium/components/content_settings/core/browser/DEPS
@@ -8,4 +8,5 @@ include_rules = [
"+extensions/features",
"+net/base",
"+net/cookies",
+ "+services/preferences/public",
]
diff --git a/chromium/components/content_settings/core/browser/content_settings_default_provider.cc b/chromium/components/content_settings/core/browser/content_settings_default_provider.cc
index 261fedb9d6b..ffa75aa7da7 100644
--- a/chromium/components/content_settings/core/browser/content_settings_default_provider.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_default_provider.cc
@@ -11,6 +11,8 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "components/content_settings/core/browser/content_settings_info.h"
+#include "components/content_settings/core/browser/content_settings_registry.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/website_settings_info.h"
@@ -186,6 +188,10 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito)
IntToContentSetting(prefs_->GetInteger(
GetPrefName(CONTENT_SETTINGS_TYPE_AUTOPLAY))),
CONTENT_SETTING_NUM_SETTINGS);
+ UMA_HISTOGRAM_ENUMERATION("ContentSettings.DefaultSubresourceFilterSetting",
+ IntToContentSetting(prefs_->GetInteger(GetPrefName(
+ CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER))),
+ CONTENT_SETTING_NUM_SETTINGS);
#endif
pref_change_registrar_.Init(prefs_);
PrefChangeRegistrar::NamedChangeCallback callback = base::Bind(
@@ -296,6 +302,10 @@ bool DefaultProvider::IsValueEmptyOrDefault(ContentSettingsType content_type,
void DefaultProvider::ChangeSetting(ContentSettingsType content_type,
base::Value* value) {
+ const ContentSettingsInfo* info =
+ ContentSettingsRegistry::GetInstance()->Get(content_type);
+ DCHECK(!info || !value ||
+ info->IsDefaultSettingValid(ValueToContentSetting(value)));
default_settings_[content_type] =
value ? base::WrapUnique(value->DeepCopy())
: ContentSettingToValue(GetDefaultValue(content_type));
@@ -363,6 +373,8 @@ std::unique_ptr<base::Value> DefaultProvider::ReadFromPref(
}
void DefaultProvider::DiscardObsoletePreferences() {
+ if (is_incognito_)
+ return;
// These prefs were never stored on iOS/Android so they don't need to be
// deleted.
#if !defined(OS_IOS)
diff --git a/chromium/components/content_settings/core/browser/content_settings_info.cc b/chromium/components/content_settings/core/browser/content_settings_info.cc
index c111944e286..41fd1375bb0 100644
--- a/chromium/components/content_settings/core/browser/content_settings_info.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_info.cc
@@ -5,6 +5,7 @@
#include "components/content_settings/core/browser/content_settings_info.h"
#include "base/stl_util.h"
+#include "components/content_settings/core/browser/website_settings_info.h"
namespace content_settings {
@@ -24,4 +25,26 @@ bool ContentSettingsInfo::IsSettingValid(ContentSetting setting) const {
return base::ContainsKey(valid_settings_, setting);
}
+// TODO(raymes): Find a better way to deal with the special-casing in
+// IsDefaultSettingValid.
+bool ContentSettingsInfo::IsDefaultSettingValid(ContentSetting setting) const {
+ ContentSettingsType type = website_settings_info_->type();
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ // Don't support ALLOW for protected media default setting until migration.
+ if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
+ setting == CONTENT_SETTING_ALLOW) {
+ return false;
+ }
+#endif
+
+ // Don't support ALLOW for the default media settings.
+ if ((type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
+ type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) &&
+ setting == CONTENT_SETTING_ALLOW) {
+ return false;
+ }
+
+ return base::ContainsKey(valid_settings_, setting);
+}
+
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/browser/content_settings_info.h b/chromium/components/content_settings/core/browser/content_settings_info.h
index d1eb3a58248..07a176741aa 100644
--- a/chromium/components/content_settings/core/browser/content_settings_info.h
+++ b/chromium/components/content_settings/core/browser/content_settings_info.h
@@ -46,6 +46,7 @@ class ContentSettingsInfo {
}
bool IsSettingValid(ContentSetting setting) const;
+ bool IsDefaultSettingValid(ContentSetting setting) const;
IncognitoBehavior incognito_behavior() const { return incognito_behavior_; }
diff --git a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc
index 3f6133b67a8..8bb2f98613c 100644
--- a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc
@@ -38,10 +38,10 @@ class RuleIteratorImpl : public RuleIterator {
Rule Next() override {
DCHECK(HasNext());
- DCHECK(current_rule_->second.get());
+ DCHECK(current_rule_->second.value.get());
Rule to_return(current_rule_->first.primary_pattern,
current_rule_->first.secondary_pattern,
- current_rule_->second.get()->DeepCopy());
+ current_rule_->second.value.get()->DeepCopy());
++current_rule_;
return to_return;
}
@@ -83,6 +83,10 @@ bool OriginIdentifierValueMap::PatternPair::operator<(
std::tie(other.primary_pattern, other.secondary_pattern);
}
+OriginIdentifierValueMap::ValueEntry::ValueEntry() : last_modified(), value(){};
+
+OriginIdentifierValueMap::ValueEntry::~ValueEntry(){};
+
std::unique_ptr<RuleIterator> OriginIdentifierValueMap::GetRuleIterator(
ContentSettingsType content_type,
const ResourceIdentifier& resource_identifier,
@@ -129,17 +133,37 @@ base::Value* OriginIdentifierValueMap::GetValue(
for (const auto& entry : it->second) {
if (entry.first.primary_pattern.Matches(primary_url) &&
entry.first.secondary_pattern.Matches(secondary_url)) {
- return entry.second.get();
+ return entry.second.value.get();
}
}
return nullptr;
}
+base::Time OriginIdentifierValueMap::GetLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) const {
+ DCHECK(primary_pattern.IsValid());
+ DCHECK(secondary_pattern.IsValid());
+
+ EntryMapKey key(content_type, resource_identifier);
+ PatternPair patterns(primary_pattern, secondary_pattern);
+ EntryMap::const_iterator it = entries_.find(key);
+ if (it == entries_.end())
+ return base::Time();
+ Rules::const_iterator r = it->second.find(patterns);
+ if (r == it->second.end())
+ return base::Time();
+ return r->second.last_modified;
+}
+
void OriginIdentifierValueMap::SetValue(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
const ResourceIdentifier& resource_identifier,
+ base::Time last_modified,
base::Value* value) {
DCHECK(primary_pattern.IsValid());
DCHECK(secondary_pattern.IsValid());
@@ -150,7 +174,9 @@ void OriginIdentifierValueMap::SetValue(
EntryMapKey key(content_type, resource_identifier);
PatternPair patterns(primary_pattern, secondary_pattern);
// This will create the entry and the linked_ptr if needed.
- entries_[key][patterns].reset(value);
+ ValueEntry* entry = &entries_[key][patterns];
+ entry->value.reset(value);
+ entry->last_modified = last_modified;
}
void OriginIdentifierValueMap::DeleteValue(
diff --git a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h
index 1ac2fe56bed..f27816b6574 100644
--- a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h
+++ b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
+#include "base/time/time.h"
#include "components/content_settings/core/common/content_settings.h"
class GURL;
@@ -44,7 +45,14 @@ class OriginIdentifierValueMap {
bool operator<(const OriginIdentifierValueMap::PatternPair& other) const;
};
- typedef std::map<PatternPair, linked_ptr<base::Value> > Rules;
+ struct ValueEntry {
+ base::Time last_modified;
+ linked_ptr<base::Value> value;
+ ValueEntry();
+ ~ValueEntry();
+ };
+
+ typedef std::map<PatternPair, ValueEntry> Rules;
typedef std::map<EntryMapKey, Rules> EntryMap;
EntryMap::iterator begin() {
@@ -92,15 +100,22 @@ class OriginIdentifierValueMap {
ContentSettingsType content_type,
const ResourceIdentifier& resource_identifier) const;
- // Sets the |value| for the given |primary_pattern|, |secondary_pattern|,
- // |content_type|, |resource_identifier| tuple. The method takes the ownership
- // of the passed |value|.
- void SetValue(
+ base::Time GetLastModified(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
- const ResourceIdentifier& resource_identifier,
- base::Value* value);
+ const ResourceIdentifier& resource_identifier) const;
+
+ // Sets the |value| for the given |primary_pattern|, |secondary_pattern|,
+ // |content_type|, |resource_identifier| tuple. The method takes the ownership
+ // of the passed |value|. The caller can also store a |last_modified| date
+ // for each value.
+ void SetValue(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ base::Time last_modified,
+ base::Value* value);
// Deletes the map entry for the given |primary_pattern|,
// |secondary_pattern|, |content_type|, |resource_identifier| tuple.
diff --git a/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc b/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc
index c2967aa41a6..d9b8cfa9806 100644
--- a/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc
@@ -13,6 +13,8 @@
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/values.h"
+#include "components/content_settings/core/browser/content_settings_info.h"
+#include "components/content_settings/core/browser/content_settings_registry.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
@@ -235,9 +237,10 @@ void PolicyProvider::GetContentSettingsFromPreferences(
VLOG_IF(2, !pattern_pair.second.IsValid())
<< "Replacing invalid secondary pattern '"
<< pattern_pair.second.ToString() << "' with wildcard";
+ // Don't set a timestamp for policy settings.
value_map->SetValue(
pattern_pair.first, secondary_pattern, content_type,
- ResourceIdentifier(),
+ ResourceIdentifier(), base::Time(),
new base::Value(kPrefsForManagedContentSettingsMap[i].setting));
}
}
@@ -319,11 +322,10 @@ void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
// Don't pass removed values from |value|, because base::Values read with
// JSONReader use a shared string buffer. Instead, DeepCopy here.
- value_map->SetValue(pattern,
- ContentSettingsPattern::Wildcard(),
+ // Don't set a timestamp for policy settings.
+ value_map->SetValue(pattern, ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
- std::string(),
- cert_filter->DeepCopy());
+ std::string(), base::Time(), cert_filter->DeepCopy());
}
}
@@ -334,6 +336,13 @@ void PolicyProvider::ReadManagedDefaultSettings() {
void PolicyProvider::UpdateManagedDefaultSetting(
const PrefsForManagedDefaultMapEntry& entry) {
+ // Not all managed default types are registered on every platform. If they're
+ // not registered, don't update them.
+ const ContentSettingsInfo* info =
+ ContentSettingsRegistry::GetInstance()->Get(entry.content_type);
+ if (!info)
+ return;
+
// If a pref to manage a default-content-setting was not set (NOTICE:
// "HasPrefPath" returns false if no value was set for a registered pref) then
// the default value of the preference is used. The default value of a
@@ -355,10 +364,11 @@ void PolicyProvider::UpdateManagedDefaultSetting(
value_map_.DeleteValue(ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
entry.content_type, std::string());
- } else {
+ } else if (info->IsSettingValid(IntToContentSetting(setting))) {
+ // Don't set a timestamp for policy settings.
value_map_.SetValue(ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(), entry.content_type,
- std::string(), new base::Value(setting));
+ std::string(), base::Time(), new base::Value(setting));
}
}
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref.cc b/chromium/components/content_settings/core/browser/content_settings_pref.cc
index f32e3018b4c..99e132b8151 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_pref.cc
@@ -8,7 +8,9 @@
#include "base/auto_reset.h"
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "components/content_settings/core/browser/content_settings_info.h"
#include "components/content_settings/core/browser/content_settings_registry.h"
@@ -19,11 +21,14 @@
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/prefs/scoped_user_pref_update.h"
+#include "services/preferences/public/cpp/dictionary_value_update.h"
+#include "services/preferences/public/cpp/scoped_pref_update.h"
#include "url/gurl.h"
namespace {
const char kSettingPath[] = "setting";
+const char kLastModifiedPath[] = "last_modified";
const char kPerResourceIdentifierPrefName[] = "per_resource";
// If the given content type supports resource identifiers in user preferences,
@@ -51,6 +56,17 @@ bool IsValueAllowedForType(const base::Value* value, ContentSettingsType type) {
return value->GetType() == base::Value::Type::DICTIONARY;
}
+// Extract a timestamp from |dictionary[kLastModifiedPath]|.
+// Will return base::Time() if no timestamp exists.
+base::Time GetTimeStamp(const base::DictionaryValue* dictionary) {
+ std::string timestamp_str;
+ dictionary->GetStringWithoutPathExpansion(kLastModifiedPath, &timestamp_str);
+ int64_t timestamp = 0;
+ base::StringToInt64(timestamp_str, &timestamp);
+ base::Time last_modified = base::Time::FromInternalValue(timestamp);
+ return last_modified;
+}
+
} // namespace
namespace content_settings {
@@ -95,6 +111,7 @@ bool ContentSettingsPref::SetWebsiteSetting(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
const ResourceIdentifier& resource_identifier,
+ base::Time modified_time,
base::Value* in_value) {
DCHECK(!in_value || IsValueAllowedForType(in_value, content_type_));
DCHECK(thread_checker_.CalledOnValidThread());
@@ -114,12 +131,9 @@ bool ContentSettingsPref::SetWebsiteSetting(
{
base::AutoLock auto_lock(lock_);
if (value.get()) {
- map_to_modify->SetValue(
- primary_pattern,
- secondary_pattern,
- content_type_,
- resource_identifier,
- value->DeepCopy());
+ map_to_modify->SetValue(primary_pattern, secondary_pattern, content_type_,
+ resource_identifier, modified_time,
+ value->DeepCopy());
} else {
map_to_modify->DeleteValue(
primary_pattern,
@@ -130,10 +144,8 @@ bool ContentSettingsPref::SetWebsiteSetting(
}
// Update the content settings preference.
if (!is_incognito_) {
- UpdatePref(primary_pattern,
- secondary_pattern,
- resource_identifier,
- value.get());
+ UpdatePref(primary_pattern, secondary_pattern, resource_identifier,
+ modified_time, value.get());
}
notify_callback_.Run(
@@ -142,6 +154,19 @@ bool ContentSettingsPref::SetWebsiteSetting(
return true;
}
+base::Time ContentSettingsPref::GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ const ResourceIdentifier& resource_identifier) {
+ OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
+ if (!is_incognito_)
+ map_to_modify = &value_map_;
+
+ base::Time last_modified = map_to_modify->GetLastModified(
+ primary_pattern, secondary_pattern, content_type_, resource_identifier);
+ return last_modified;
+}
+
void ContentSettingsPref::ClearPref() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(prefs_);
@@ -153,9 +178,8 @@ void ContentSettingsPref::ClearPref() {
{
base::AutoReset<bool> auto_reset(&updating_preferences_, true);
- DictionaryPrefUpdate update(prefs_, pref_name_);
- base::DictionaryValue* pattern_pairs_settings = update.Get();
- pattern_pairs_settings->Clear();
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, pref_name_);
+ update->Clear();
}
}
@@ -188,13 +212,13 @@ bool ContentSettingsPref::TryLockForTesting() const {
}
void ContentSettingsPref::ReadContentSettingsFromPref() {
- // |DictionaryPrefUpdate| sends out notifications when destructed. This
+ // |ScopedDictionaryPrefUpdate| sends out notifications when destructed. This
// construction order ensures |AutoLock| gets destroyed first and |lock_| is
// not held when the notifications are sent. Also, |auto_reset| must be still
// valid when the notifications are sent, so that |Observe| skips the
// notification.
base::AutoReset<bool> auto_reset(&updating_preferences_, true);
- DictionaryPrefUpdate update(prefs_, pref_name_);
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, pref_name_);
base::AutoLock auto_lock(lock_);
const base::DictionaryValue* all_settings_dictionary =
@@ -202,27 +226,31 @@ void ContentSettingsPref::ReadContentSettingsFromPref() {
value_map_.clear();
- // Careful: The returned value could be NULL if the pref has never been set.
+ // Careful: The returned value could be nullptr if the pref has never been
+ // set.
if (!all_settings_dictionary)
return;
- base::DictionaryValue* mutable_settings;
- std::unique_ptr<base::DictionaryValue> mutable_settings_scope;
+ const base::DictionaryValue* settings;
if (!is_incognito_) {
- mutable_settings = update.Get();
+ // Convert all Unicode patterns into punycode form, then read.
+ auto mutable_settings = update.Get();
+ CanonicalizeContentSettingsExceptions(mutable_settings.get());
+ settings = mutable_settings->AsConstDictionary();
} else {
- // Create copy as we do not want to persist anything in incognito prefs.
- mutable_settings = all_settings_dictionary->DeepCopy();
- mutable_settings_scope.reset(mutable_settings);
+ // Canonicalization is unnecessary when |is_incognito_|. Both incognito and
+ // non-incognito read from the same pref and non-incognito reads occur
+ // before incognito reads. Thus, by the time the incognito call to
+ // ReadContentSettingsFromPref() occurs, the non-incognito call will have
+ // canonicalized the stored pref data.
+ settings = all_settings_dictionary;
}
- // Convert all Unicode patterns into punycode form, then read.
- CanonicalizeContentSettingsExceptions(mutable_settings);
size_t cookies_block_exception_count = 0;
size_t cookies_allow_exception_count = 0;
size_t cookies_session_only_exception_count = 0;
- for (base::DictionaryValue::Iterator i(*mutable_settings); !i.IsAtEnd();
+ for (base::DictionaryValue::Iterator i(*settings); !i.IsAtEnd();
i.Advance()) {
const std::string& pattern_str(i.key());
std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
@@ -236,14 +264,15 @@ void ContentSettingsPref::ReadContentSettingsFromPref() {
// Get settings dictionary for the current pattern string, and read
// settings from the dictionary.
- const base::DictionaryValue* settings_dictionary = NULL;
+ const base::DictionaryValue* settings_dictionary = nullptr;
bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary);
DCHECK(is_dictionary);
if (SupportsResourceIdentifiers(content_type_)) {
- const base::DictionaryValue* resource_dictionary = NULL;
+ const base::DictionaryValue* resource_dictionary = nullptr;
if (settings_dictionary->GetDictionary(
kPerResourceIdentifierPrefName, &resource_dictionary)) {
+ base::Time last_modified = GetTimeStamp(settings_dictionary);
for (base::DictionaryValue::Iterator j(*resource_dictionary);
!j.IsAtEnd();
j.Advance()) {
@@ -253,10 +282,10 @@ void ContentSettingsPref::ReadContentSettingsFromPref() {
DCHECK(is_integer);
DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
std::unique_ptr<base::Value> setting_ptr(new base::Value(setting));
- value_map_.SetValue(pattern_pair.first,
- pattern_pair.second,
- content_type_,
- resource_identifier,
+ DCHECK(IsValueAllowedForType(setting_ptr.get(), content_type_));
+ // Per resource settings store a single timestamps for all resources.
+ value_map_.SetValue(pattern_pair.first, pattern_pair.second,
+ content_type_, resource_identifier, last_modified,
setting_ptr->DeepCopy());
}
}
@@ -264,13 +293,11 @@ void ContentSettingsPref::ReadContentSettingsFromPref() {
const base::Value* value = nullptr;
settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value);
-
if (value) {
+ base::Time last_modified = GetTimeStamp(settings_dictionary);
DCHECK(IsValueAllowedForType(value, content_type_));
- value_map_.SetValue(pattern_pair.first,
- pattern_pair.second,
- content_type_,
- ResourceIdentifier(),
+ value_map_.SetValue(pattern_pair.first, pattern_pair.second,
+ content_type_, ResourceIdentifier(), last_modified,
value->DeepCopy());
if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) {
ContentSetting s = ValueToContentSetting(value);
@@ -321,67 +348,82 @@ void ContentSettingsPref::UpdatePref(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
const ResourceIdentifier& resource_identifier,
+ const base::Time last_modified,
const base::Value* value) {
// Ensure that |lock_| is not held by this thread, since this function will
- // send out notifications (by |~DictionaryPrefUpdate|).
+ // send out notifications (by |~ScopedDictionaryPrefUpdate|).
AssertLockNotHeld();
base::AutoReset<bool> auto_reset(&updating_preferences_, true);
{
- DictionaryPrefUpdate update(prefs_, pref_name_);
- base::DictionaryValue* pattern_pairs_settings = update.Get();
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, pref_name_);
+ std::unique_ptr<prefs::DictionaryValueUpdate> pattern_pairs_settings =
+ update.Get();
// Get settings dictionary for the given patterns.
std::string pattern_str(CreatePatternString(primary_pattern,
secondary_pattern));
- base::DictionaryValue* settings_dictionary = NULL;
+ std::unique_ptr<prefs::DictionaryValueUpdate> settings_dictionary;
bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
pattern_str, &settings_dictionary);
if (!found && value) {
- settings_dictionary = new base::DictionaryValue;
- pattern_pairs_settings->SetWithoutPathExpansion(
- pattern_str, settings_dictionary);
+ settings_dictionary =
+ pattern_pairs_settings->SetDictionaryWithoutPathExpansion(
+ pattern_str, base::MakeUnique<base::DictionaryValue>());
}
if (settings_dictionary) {
if (SupportsResourceIdentifiers(content_type_) &&
!resource_identifier.empty()) {
- base::DictionaryValue* resource_dictionary = NULL;
+ std::unique_ptr<prefs::DictionaryValueUpdate> resource_dictionary;
found = settings_dictionary->GetDictionary(
kPerResourceIdentifierPrefName, &resource_dictionary);
if (!found) {
- if (value == NULL)
+ if (value == nullptr)
return; // Nothing to remove. Exit early.
- resource_dictionary = new base::DictionaryValue;
- settings_dictionary->Set(
- kPerResourceIdentifierPrefName, resource_dictionary);
+ resource_dictionary =
+ settings_dictionary->SetDictionaryWithoutPathExpansion(
+ kPerResourceIdentifierPrefName,
+ base::MakeUnique<base::DictionaryValue>());
}
// Update resource dictionary.
- if (value == NULL) {
+ if (value == nullptr) {
resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
- NULL);
+ nullptr);
if (resource_dictionary->empty()) {
settings_dictionary->RemoveWithoutPathExpansion(
- kPerResourceIdentifierPrefName, NULL);
+ kPerResourceIdentifierPrefName, nullptr);
+ settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath,
+ nullptr);
}
} else {
- resource_dictionary->SetWithoutPathExpansion(
- resource_identifier, value->DeepCopy());
+ resource_dictionary->SetWithoutPathExpansion(resource_identifier,
+ value->CreateDeepCopy());
+ // Update timestamp for whole resource dictionary.
+ settings_dictionary->SetStringWithoutPathExpansion(
+ kLastModifiedPath,
+ base::Int64ToString(last_modified.ToInternalValue()));
}
} else {
// Update settings dictionary.
- if (value == NULL) {
- settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL);
+ if (value == nullptr) {
+ settings_dictionary->RemoveWithoutPathExpansion(kSettingPath,
+ nullptr);
+ settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath,
+ nullptr);
} else {
- settings_dictionary->SetWithoutPathExpansion(
- kSettingPath, value->DeepCopy());
+ settings_dictionary->SetWithoutPathExpansion(kSettingPath,
+ value->CreateDeepCopy());
+ settings_dictionary->SetStringWithoutPathExpansion(
+ kLastModifiedPath,
+ base::Int64ToString(last_modified.ToInternalValue()));
}
}
// Remove the settings dictionary if it is empty.
if (settings_dictionary->empty()) {
- pattern_pairs_settings->RemoveWithoutPathExpansion(
- pattern_str, NULL);
+ pattern_pairs_settings->RemoveWithoutPathExpansion(pattern_str,
+ nullptr);
}
}
}
@@ -389,14 +431,14 @@ void ContentSettingsPref::UpdatePref(
// static
void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
- base::DictionaryValue* all_settings_dictionary) {
+ prefs::DictionaryValueUpdate* all_settings_dictionary) {
DCHECK(all_settings_dictionary);
std::vector<std::string> remove_items;
base::StringPairs move_items;
- for (base::DictionaryValue::Iterator i(*all_settings_dictionary);
- !i.IsAtEnd();
- i.Advance()) {
+ for (base::DictionaryValue::Iterator i(
+ *all_settings_dictionary->AsConstDictionary());
+ !i.IsAtEnd(); i.Advance()) {
const std::string& pattern_str(i.key());
std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
ParsePatternString(pattern_str);
@@ -415,7 +457,7 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
}
// Clear old pattern if prefs already have canonicalized pattern.
- const base::DictionaryValue* new_pattern_settings_dictionary = NULL;
+ const base::DictionaryValue* new_pattern_settings_dictionary = nullptr;
if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
canonicalized_pattern_str, &new_pattern_settings_dictionary)) {
remove_items.push_back(pattern_str);
@@ -423,7 +465,7 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
}
// Move old pattern to canonicalized pattern.
- const base::DictionaryValue* old_pattern_settings_dictionary = NULL;
+ const base::DictionaryValue* old_pattern_settings_dictionary = nullptr;
if (i.value().GetAsDictionary(&old_pattern_settings_dictionary)) {
move_items.push_back(
std::make_pair(pattern_str, canonicalized_pattern_str));
@@ -431,7 +473,8 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
}
for (size_t i = 0; i < remove_items.size(); ++i) {
- all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i], NULL);
+ all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i],
+ nullptr);
}
for (size_t i = 0; i < move_items.size(); ++i) {
@@ -439,7 +482,7 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
all_settings_dictionary->RemoveWithoutPathExpansion(
move_items[i].first, &pattern_settings_dictionary);
all_settings_dictionary->SetWithoutPathExpansion(
- move_items[i].second, pattern_settings_dictionary.release());
+ move_items[i].second, std::move(pattern_settings_dictionary));
}
}
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref.h b/chromium/components/content_settings/core/browser/content_settings_pref.h
index 77c6d031fb1..3139fc4aecb 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref.h
+++ b/chromium/components/content_settings/core/browser/content_settings_pref.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "components/content_settings/core/browser/content_settings_origin_identifier_value_map.h"
#include "components/content_settings/core/browser/content_settings_provider.h"
@@ -22,8 +23,8 @@
class PrefService;
class PrefChangeRegistrar;
-namespace base {
-class DictionaryValue;
+namespace prefs {
+class DictionaryValueUpdate;
}
namespace content_settings {
@@ -54,8 +55,15 @@ class ContentSettingsPref {
bool SetWebsiteSetting(const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
const ResourceIdentifier& resource_identifier,
+ base::Time modified_time,
base::Value* value);
+ // Returns the |last_modified| date of a setting.
+ base::Time GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ const ResourceIdentifier& resource_identifier);
+
void ClearPref();
void ClearAllContentSettingsRules();
@@ -77,14 +85,14 @@ class ContentSettingsPref {
// value to the obsolete preference. When calling this function, |lock_|
// should not be held, since this function will send out notifications of
// preference changes.
- void UpdatePref(
- const ContentSettingsPattern& primary_pattern,
- const ContentSettingsPattern& secondary_pattern,
- const ResourceIdentifier& resource_identifier,
- const base::Value* value);
+ void UpdatePref(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ const ResourceIdentifier& resource_identifier,
+ const base::Time last_modified,
+ const base::Value* value);
static void CanonicalizeContentSettingsExceptions(
- base::DictionaryValue* all_settings_dictionary);
+ prefs::DictionaryValueUpdate* all_settings_dictionary);
// In the debug mode, asserts that |lock_| is not held by this thread. It's
// ok if some other thread holds |lock_|, as long as it will eventually
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc b/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc
index 3bd173ebe0a..fc1d59bb35c 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc
@@ -15,6 +15,7 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/time/default_clock.h"
#include "components/content_settings/core/browser/content_settings_pref.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
@@ -28,6 +29,8 @@
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
+#include "services/preferences/public/cpp/dictionary_value_update.h"
+#include "services/preferences/public/cpp/scoped_pref_update.h"
namespace content_settings {
@@ -80,9 +83,13 @@ void PrefProvider::RegisterProfilePrefs(
#endif // !defined(OS_IOS)
}
-PrefProvider::PrefProvider(PrefService* prefs, bool incognito)
+PrefProvider::PrefProvider(PrefService* prefs,
+ bool incognito,
+ bool store_last_modified)
: prefs_(prefs),
- is_incognito_(incognito) {
+ is_incognito_(incognito),
+ store_last_modified_(store_last_modified),
+ clock_(new base::DefaultClock) {
DCHECK(prefs_);
// Verify preferences version.
if (!prefs_->HasPrefPath(prefs::kContentSettingsVersion)) {
@@ -150,9 +157,25 @@ bool PrefProvider::SetWebsiteSetting(
return false;
}
+ base::Time modified_time =
+ store_last_modified_ ? clock_->Now() : base::Time();
+
return GetPref(content_type)
->SetWebsiteSetting(primary_pattern, secondary_pattern,
- resource_identifier, in_value);
+ resource_identifier, modified_time, in_value);
+}
+
+base::Time PrefProvider::GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(prefs_);
+
+ return GetPref(content_type)
+ ->GetWebsiteSettingLastModified(primary_pattern, secondary_pattern,
+ resource_identifier);
}
void PrefProvider::ClearAllContentSettingsRules(
@@ -197,6 +220,8 @@ void PrefProvider::Notify(
}
void PrefProvider::DiscardObsoletePreferences() {
+ if (is_incognito_)
+ return;
// These prefs were never stored on iOS/Android so they don't need to be
// deleted.
#if !defined(OS_IOS)
@@ -236,11 +261,11 @@ void PrefProvider::DiscardObsoletePreferences() {
if (!prefs_->GetDictionary(info->pref_name()))
continue;
- DictionaryPrefUpdate update(prefs_, info->pref_name());
- base::DictionaryValue* all_settings = update.Get();
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, info->pref_name());
+ auto all_settings = update.Get();
std::vector<std::string> values_to_clean;
- for (base::DictionaryValue::Iterator i(*all_settings); !i.IsAtEnd();
- i.Advance()) {
+ for (base::DictionaryValue::Iterator i(*all_settings->AsConstDictionary());
+ !i.IsAtEnd(); i.Advance()) {
const base::DictionaryValue* pattern_settings = nullptr;
bool is_dictionary = i.value().GetAsDictionary(&pattern_settings);
DCHECK(is_dictionary);
@@ -249,7 +274,7 @@ void PrefProvider::DiscardObsoletePreferences() {
}
for (const std::string& key : values_to_clean) {
- base::DictionaryValue* pattern_settings = nullptr;
+ std::unique_ptr<prefs::DictionaryValueUpdate> pattern_settings;
all_settings->GetDictionaryWithoutPathExpansion(key, &pattern_settings);
pattern_settings->RemoveWithoutPathExpansion(kObsoleteLastUsed, nullptr);
if (pattern_settings->empty())
@@ -258,4 +283,8 @@ void PrefProvider::DiscardObsoletePreferences() {
}
}
+void PrefProvider::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
+ clock_ = std::move(clock);
+}
+
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref_provider.h b/chromium/components/content_settings/core/browser/content_settings_pref_provider.h
index 9f33e158f6e..124ac9b840f 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref_provider.h
+++ b/chromium/components/content_settings/core/browser/content_settings_pref_provider.h
@@ -18,6 +18,10 @@
class PrefService;
+namespace base {
+class Clock;
+}
+
namespace user_prefs {
class PrefRegistrySyncable;
}
@@ -32,7 +36,7 @@ class PrefProvider : public ObservableProvider {
public:
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
- PrefProvider(PrefService* prefs, bool incognito);
+ PrefProvider(PrefService* prefs, bool incognito, bool store_last_modified);
~PrefProvider() override;
// ProviderInterface implementations.
@@ -47,6 +51,13 @@ class PrefProvider : public ObservableProvider {
const ResourceIdentifier& resource_identifier,
base::Value* value) override;
+ // Returns the |last_modified| date of a setting.
+ base::Time GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier);
+
void ClearAllContentSettingsRules(ContentSettingsType content_type) override;
void ShutdownOnUIThread() override;
@@ -55,6 +66,8 @@ class PrefProvider : public ObservableProvider {
ContentSettingsPref* GetPref(ContentSettingsType type) const;
+ void SetClockForTesting(std::unique_ptr<base::Clock> clock);
+
private:
friend class DeadlockCheckerObserver; // For testing.
@@ -71,6 +84,8 @@ class PrefProvider : public ObservableProvider {
const bool is_incognito_;
+ bool store_last_modified_;
+
PrefChangeRegistrar pref_change_registrar_;
std::map<ContentSettingsType, std::unique_ptr<ContentSettingsPref>>
@@ -78,6 +93,8 @@ class PrefProvider : public ObservableProvider {
base::ThreadChecker thread_checker_;
+ std::unique_ptr<base::Clock> clock_;
+
DISALLOW_COPY_AND_ASSIGN(PrefProvider);
};
diff --git a/chromium/components/content_settings/core/browser/content_settings_registry.cc b/chromium/components/content_settings/core/browser/content_settings_registry.cc
index b782ec64617..6b18f449543 100644
--- a/chromium/components/content_settings/core/browser/content_settings_registry.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_registry.cc
@@ -250,7 +250,8 @@ void ContentSettingsRegistry::Init() {
Register(CONTENT_SETTINGS_TYPE_DURABLE_STORAGE, "durable-storage",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(),
- ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
+ ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
+ CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
WebsiteSettingsRegistry::DESKTOP |
WebsiteSettingsRegistry::PLATFORM_ANDROID,
@@ -274,8 +275,8 @@ void ContentSettingsRegistry::Init() {
ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE);
Register(CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER, "subresource-filter",
- CONTENT_SETTING_ALLOW,
- WebsiteSettingsInfo::UNSYNCABLE, WhitelistedSchemes(),
+ CONTENT_SETTING_BLOCK, WebsiteSettingsInfo::UNSYNCABLE,
+ WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
WebsiteSettingsRegistry::DESKTOP |
diff --git a/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc b/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc
index d63d180e0bf..db419b6e434 100644
--- a/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc
@@ -124,4 +124,23 @@ TEST_F(ContentSettingsRegistryTest, Iteration) {
EXPECT_TRUE(cookies_found);
}
+TEST_F(ContentSettingsRegistryTest, IsDefaultSettingValid) {
+ const ContentSettingsInfo* info =
+ registry()->Get(CONTENT_SETTINGS_TYPE_COOKIES);
+ EXPECT_TRUE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+
+#if !defined(OS_IOS)
+ info = registry()->Get(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
+ EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+
+ info = registry()->Get(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
+ EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+#endif
+
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ info = registry()->Get(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
+ EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+#endif
+}
+
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc b/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc
index 1d16b2fec5f..f606004be5e 100644
--- a/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc
+++ b/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -31,7 +31,8 @@ class CookieSettingsTest : public testing::Test {
CookieSettings::RegisterProfilePrefs(prefs_.registry());
HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry());
settings_map_ = new HostContentSettingsMap(
- &prefs_, false /* incognito_profile */, false /* guest_profile */);
+ &prefs_, false /* incognito_profile */, false /* guest_profile */,
+ false /* store_last_modified */);
cookie_settings_ =
new CookieSettings(settings_map_.get(), &prefs_, "chrome-extension");
}
diff --git a/chromium/components/content_settings/core/browser/host_content_settings_map.cc b/chromium/components/content_settings/core/browser/host_content_settings_map.cc
index 3879f3096c0..52a6708ea74 100644
--- a/chromium/components/content_settings/core/browser/host_content_settings_map.cc
+++ b/chromium/components/content_settings/core/browser/host_content_settings_map.cc
@@ -178,13 +178,15 @@ content_settings::PatternPair GetPatternsForContentSettingsType(
HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs,
bool is_incognito_profile,
- bool is_guest_profile)
+ bool is_guest_profile,
+ bool store_last_modified)
: RefcountedKeyedService(base::ThreadTaskRunnerHandle::Get()),
#ifndef NDEBUG
used_from_thread_id_(base::PlatformThread::CurrentId()),
#endif
prefs_(prefs),
is_incognito_(is_incognito_profile || is_guest_profile),
+ store_last_modified_(store_last_modified),
weak_ptr_factory_(this) {
DCHECK(!(is_incognito_profile && is_guest_profile));
@@ -194,8 +196,8 @@ HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs,
base::WrapUnique(policy_provider);
policy_provider->AddObserver(this);
- pref_provider_ =
- new content_settings::PrefProvider(prefs_, is_incognito_);
+ pref_provider_ = new content_settings::PrefProvider(prefs_, is_incognito_,
+ store_last_modified_);
content_settings_providers_[PREF_PROVIDER] = base::WrapUnique(pref_provider_);
pref_provider_->AddObserver(this);
@@ -347,7 +349,9 @@ void HostContentSettingsMap::SetDefaultContentSetting(
std::unique_ptr<base::Value> value;
// A value of CONTENT_SETTING_DEFAULT implies deleting the content setting.
if (setting != CONTENT_SETTING_DEFAULT) {
- DCHECK(IsDefaultSettingAllowedForType(setting, content_type));
+ DCHECK(content_settings::ContentSettingsRegistry::GetInstance()
+ ->Get(content_type)
+ ->IsDefaultSettingValid(setting));
value.reset(new base::Value(setting));
}
SetWebsiteSettingCustomScope(ContentSettingsPattern::Wildcard(),
@@ -656,57 +660,41 @@ void HostContentSettingsMap::ClearSettingsForOneType(
FlushLossyWebsiteSettings();
}
+base::Time HostContentSettingsMap::GetSettingLastModifiedDate(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type) const {
+ return pref_provider_->GetWebsiteSettingLastModified(
+ primary_pattern, secondary_pattern, content_type, std::string());
+}
+
void HostContentSettingsMap::ClearSettingsForOneTypeWithPredicate(
ContentSettingsType content_type,
- const base::Callback<bool(const ContentSettingsPattern& primary_pattern,
- const ContentSettingsPattern& secondary_pattern)>&
- pattern_predicate) {
- if (pattern_predicate.is_null()) {
+ base::Time begin_time,
+ const PatternSourcePredicate& pattern_predicate) {
+ if (pattern_predicate.is_null() && begin_time.is_null()) {
ClearSettingsForOneType(content_type);
return;
}
-
+ UsedContentSettingsProviders();
ContentSettingsForOneType settings;
GetSettingsForOneType(content_type, std::string(), &settings);
for (const ContentSettingPatternSource& setting : settings) {
- if (pattern_predicate.Run(setting.primary_pattern,
+ if (pattern_predicate.is_null() ||
+ pattern_predicate.Run(setting.primary_pattern,
setting.secondary_pattern)) {
- SetWebsiteSettingCustomScope(setting.primary_pattern,
- setting.secondary_pattern, content_type,
- std::string(), nullptr);
+ base::Time last_modified = pref_provider_->GetWebsiteSettingLastModified(
+ setting.primary_pattern, setting.secondary_pattern, content_type,
+ std::string());
+ if (last_modified >= begin_time) {
+ pref_provider_->SetWebsiteSetting(setting.primary_pattern,
+ setting.secondary_pattern,
+ content_type, std::string(), nullptr);
+ }
}
}
}
-// TODO(raymes): Remove this function. Consider making it a property of
-// ContentSettingsInfo or removing it altogether (it's unclear whether we should
-// be restricting allowed default values at this layer).
-// static
-bool HostContentSettingsMap::IsDefaultSettingAllowedForType(
- ContentSetting setting,
- ContentSettingsType content_type) {
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
- // Don't support ALLOW for protected media default setting until migration.
- if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
- setting == CONTENT_SETTING_ALLOW) {
- return false;
- }
-#endif
-
- // Don't support ALLOW for the default media settings.
- if ((content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
- content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) &&
- setting == CONTENT_SETTING_ALLOW) {
- return false;
- }
-
- const content_settings::ContentSettingsInfo* info =
- content_settings::ContentSettingsRegistry::GetInstance()->Get(
- content_type);
- DCHECK(info);
- return info->IsSettingValid(setting);
-}
-
void HostContentSettingsMap::OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
@@ -806,11 +794,8 @@ std::unique_ptr<base::Value> HostContentSettingsMap::GetWebsiteSetting(
}
}
- return GetWebsiteSettingInternal(primary_url,
- secondary_url,
- content_type,
- resource_identifier,
- info);
+ return GetWebsiteSettingInternal(primary_url, secondary_url, content_type,
+ resource_identifier, info);
}
// static
@@ -921,3 +906,8 @@ HostContentSettingsMap::GetContentSettingValueAndPatterns(
}
return std::unique_ptr<base::Value>();
}
+
+void HostContentSettingsMap::SetClockForTesting(
+ std::unique_ptr<base::Clock> clock) {
+ pref_provider_->SetClockForTesting(std::move(clock));
+} \ No newline at end of file
diff --git a/chromium/components/content_settings/core/browser/host_content_settings_map.h b/chromium/components/content_settings/core/browser/host_content_settings_map.h
index eadf365cfbd..b5c7798b02f 100644
--- a/chromium/components/content_settings/core/browser/host_content_settings_map.h
+++ b/chromium/components/content_settings/core/browser/host_content_settings_map.h
@@ -31,6 +31,7 @@ class PrefService;
namespace base {
class Value;
+class Clock;
}
namespace content_settings {
@@ -66,7 +67,8 @@ class HostContentSettingsMap : public content_settings::Observer,
// |is_incognito_profile| and |is_guest_profile| should be true.
HostContentSettingsMap(PrefService* prefs,
bool is_incognito_profile,
- bool is_guest_profile);
+ bool is_guest_profile,
+ bool store_last_modified);
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
@@ -217,16 +219,27 @@ class HostContentSettingsMap : public content_settings::Observer,
// This should only be called on the UI thread.
void ClearSettingsForOneType(ContentSettingsType content_type);
+ // Return the |last_modified| date of a content setting. This will only return
+ // valid values for settings from the PreferenceProvider. Settings from other
+ // providers will return base::Time().
+ //
+ // This may be called on any thread.
+ base::Time GetSettingLastModifiedDate(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type) const;
+
+ using PatternSourcePredicate =
+ base::Callback<bool(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern)>;
+
// If |pattern_predicate| is null, this method is equivalent to the above.
- // Otherwise, it only deletes exceptions matched by |pattern_predicate|.
+ // Otherwise, it only deletes exceptions matched by |pattern_predicate| that
+ // were modified at or after |begin_time|.
void ClearSettingsForOneTypeWithPredicate(
ContentSettingsType content_type,
- const base::Callback<bool(
- const ContentSettingsPattern& primary_pattern,
- const ContentSettingsPattern& secondary_pattern)>& pattern_predicate);
-
- static bool IsDefaultSettingAllowedForType(ContentSetting setting,
- ContentSettingsType content_type);
+ base::Time begin_time,
+ const PatternSourcePredicate& pattern_predicate);
// RefcountedKeyedService implementation.
void ShutdownOnUIThread() override;
@@ -267,6 +280,10 @@ class HostContentSettingsMap : public content_settings::Observer,
base::WeakPtr<HostContentSettingsMap> GetWeakPtr();
+ // Injects a clock into the PrefProvider to allow control over the
+ // |last_modified| timestamp.
+ void SetClockForTesting(std::unique_ptr<base::Clock> clock);
+
private:
friend class base::RefCountedThreadSafe<HostContentSettingsMap>;
@@ -358,6 +375,10 @@ class HostContentSettingsMap : public content_settings::Observer,
// Whether this settings map is for an incognito session.
bool is_incognito_;
+ // Whether ContentSettings in the PrefProvider will store a last_modified
+ // timestamp.
+ bool store_last_modified_;
+
// Content setting providers. This is only modified at construction
// time and by RegisterExtensionService, both of which should happen
// before any other uses of it.
diff --git a/chromium/components/content_settings/core/browser/website_settings_registry.cc b/chromium/components/content_settings/core/browser/website_settings_registry.cc
index 1cfb5441383..4d49cef938c 100644
--- a/chromium/components/content_settings/core/browser/website_settings_registry.cc
+++ b/chromium/components/content_settings/core/browser/website_settings_registry.cc
@@ -165,6 +165,14 @@ void WebsiteSettingsRegistry::Init() {
WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY,
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
DESKTOP | PLATFORM_ANDROID, WebsiteSettingsInfo::INHERIT_IN_INCOGNITO);
+ // Set when an origin is activated for subresource filtering and the
+ // associated UI is shown to the user. Cleared when a site is de-activated or
+ // the first URL matching the origin is removed from history.
+ Register(
+ CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, "subresource-filter-data",
+ nullptr, WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY,
+ WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
+ DESKTOP | PLATFORM_ANDROID, WebsiteSettingsInfo::INHERIT_IN_INCOGNITO);
}
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/common/content_settings.cc b/chromium/components/content_settings/core/common/content_settings.cc
index ec1621532d9..4cf2d132898 100644
--- a/chromium/components/content_settings/core/common/content_settings.cc
+++ b/chromium/components/content_settings/core/common/content_settings.cc
@@ -16,50 +16,47 @@ ContentSetting IntToContentSetting(int content_setting) {
CONTENT_SETTING_DEFAULT : static_cast<ContentSetting>(content_setting);
}
-// WARNING: This array should not be reordered or removed as it is used for
-// histogram values. If a ContentSettingsType value has been removed, the entry
-// must be replaced by a placeholder. It should correspond directly to the
-// ContentType enum in histograms.xml.
+struct HistogramValue {
+ ContentSettingsType type;
+ int value;
+};
+
+// WARNING: The value specified here for a type should match exactly the value
+// specified in the ContentType enum in histograms.xml. Since these values are
+// used for histograms, please do not reuse the same value for a different
+// content setting. Always append to the end and increment.
// TODO(raymes): We should use a sparse histogram here on the hash of the
// content settings type name instead.
-ContentSettingsType kHistogramOrder[] = {
- CONTENT_SETTINGS_TYPE_COOKIES,
- CONTENT_SETTINGS_TYPE_IMAGES,
- CONTENT_SETTINGS_TYPE_JAVASCRIPT,
- CONTENT_SETTINGS_TYPE_PLUGINS,
- CONTENT_SETTINGS_TYPE_POPUPS,
- CONTENT_SETTINGS_TYPE_GEOLOCATION,
- CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
- CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
- CONTENT_SETTINGS_TYPE_DEFAULT, // FULLSCREEN (removed).
- CONTENT_SETTINGS_TYPE_DEFAULT, // MOUSELOCK (removed).
- CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
- CONTENT_SETTINGS_TYPE_DEFAULT, // MEDIASTREAM (removed).
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
- CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS,
- CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
- CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
- CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
- CONTENT_SETTINGS_TYPE_DEFAULT, // PUSH_MESSAGING (removed).
- CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS,
- CONTENT_SETTINGS_TYPE_DEFAULT, // METRO_SWITCH_TO_DESKTOP (removed).
+HistogramValue kHistogramValue[] = {
+ {CONTENT_SETTINGS_TYPE_COOKIES, 0},
+ {CONTENT_SETTINGS_TYPE_IMAGES, 1},
+ {CONTENT_SETTINGS_TYPE_JAVASCRIPT, 2},
+ {CONTENT_SETTINGS_TYPE_PLUGINS, 3},
+ {CONTENT_SETTINGS_TYPE_POPUPS, 4},
+ {CONTENT_SETTINGS_TYPE_GEOLOCATION, 5},
+ {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 6},
+ {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, 7},
+ {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, 10},
+ {CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 12},
+ {CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 13},
+ {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, 14},
+ {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, 15},
+ {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, 16},
+ {CONTENT_SETTINGS_TYPE_MIDI_SYSEX, 17},
+ {CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, 19},
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
- CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
-#else
- CONTENT_SETTINGS_TYPE_DEFAULT, // PROTECTED_MEDIA_IDENTIFIER (mobile only).
+ {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, 21},
#endif
- CONTENT_SETTINGS_TYPE_APP_BANNER,
- CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT,
- CONTENT_SETTINGS_TYPE_DURABLE_STORAGE,
- CONTENT_SETTINGS_TYPE_DEFAULT, // KEYGEN (removed).
- CONTENT_SETTINGS_TYPE_BLUETOOTH_GUARD,
- CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC,
- CONTENT_SETTINGS_TYPE_AUTOPLAY,
- CONTENT_SETTINGS_TYPE_DEFAULT, // PROMPT_NO_DECISION_COUNT (migrated).
- CONTENT_SETTINGS_TYPE_IMPORTANT_SITE_INFO,
- CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA,
- CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER,
+ {CONTENT_SETTINGS_TYPE_APP_BANNER, 22},
+ {CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, 23},
+ {CONTENT_SETTINGS_TYPE_DURABLE_STORAGE, 24},
+ {CONTENT_SETTINGS_TYPE_BLUETOOTH_GUARD, 26},
+ {CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, 27},
+ {CONTENT_SETTINGS_TYPE_AUTOPLAY, 28},
+ {CONTENT_SETTINGS_TYPE_IMPORTANT_SITE_INFO, 30},
+ {CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, 31},
+ {CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER, 32},
+ {CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, 33},
};
int ContentSettingTypeToHistogramValue(ContentSettingsType content_setting,
@@ -68,14 +65,12 @@ int ContentSettingTypeToHistogramValue(ContentSettingsType content_setting,
typedef base::hash_map<int, int> Map;
CR_DEFINE_STATIC_LOCAL(Map, kMap, ());
if (kMap.empty()) {
- for (size_t i = 0; i < arraysize(kHistogramOrder); ++i) {
- if (kHistogramOrder[i] != CONTENT_SETTINGS_TYPE_DEFAULT)
- kMap[kHistogramOrder[i]] = static_cast<int>(i);
- }
+ for (const HistogramValue& histogram_value : kHistogramValue)
+ kMap[histogram_value.type] = histogram_value.value;
}
DCHECK(base::ContainsKey(kMap, content_setting));
- *num_values = arraysize(kHistogramOrder);
+ *num_values = arraysize(kHistogramValue);
return kMap[content_setting];
}
diff --git a/chromium/components/content_settings/core/common/content_settings_types.h b/chromium/components/content_settings/core/common/content_settings_types.h
index d7584141be5..580a94ac8c6 100644
--- a/chromium/components/content_settings/core/common/content_settings_types.h
+++ b/chromium/components/content_settings/core/common/content_settings_types.h
@@ -50,6 +50,10 @@ enum ContentSettingsType {
CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA,
CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER,
+ // Website setting which stores metadata for the subresource filter to aid in
+ // decisions for whether or not to show the UI.
+ CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA,
+
// This is special-cased in the permissions layer to always allow, and as
// such doesn't have associated prefs data.
CONTENT_SETTINGS_TYPE_MIDI,
diff --git a/chromium/components/contextual_search/OWNERS b/chromium/components/contextual_search/OWNERS
index 1ae3bf181ac..6ceed8d4aeb 100644
--- a/chromium/components/contextual_search/OWNERS
+++ b/chromium/components/contextual_search/OWNERS
@@ -3,3 +3,6 @@ twellington@chromium.org
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# TEAM: contextual-search-dev@chromium.org
+# COMPONENT: UI>Browser>Search>ContextualSearch
diff --git a/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.cc b/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.cc
index c724c2ecde9..5ebfd3ffd48 100644
--- a/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.cc
+++ b/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.cc
@@ -27,7 +27,8 @@ void ContextualSearchJsApiServiceImpl::HandleSetCaption(
// static
void CreateContextualSearchJsApiService(
ContextualSearchJsApiHandler* contextual_search_js_api_handler,
- mojo::InterfaceRequest<mojom::ContextualSearchJsApiService> request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::ContextualSearchJsApiServiceRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<ContextualSearchJsApiServiceImpl>(
contextual_search_js_api_handler),
std::move(request));
diff --git a/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.h b/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.h
index d9111382a0a..96d7c45736b 100644
--- a/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.h
+++ b/chromium/components/contextual_search/browser/contextual_search_js_api_service_impl.h
@@ -9,6 +9,10 @@
#include "components/contextual_search/browser/contextual_search_js_api_handler.h"
#include "components/contextual_search/common/contextual_search_js_api_service.mojom.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace contextual_search {
// This is the receiving end of Contextual Search JavaScript API calls.
@@ -32,7 +36,8 @@ class ContextualSearchJsApiServiceImpl
// static
void CreateContextualSearchJsApiService(
ContextualSearchJsApiHandler* contextual_search_js_api_handler,
- mojo::InterfaceRequest<mojom::ContextualSearchJsApiService> request);
+ const service_manager::BindSourceInfo& source_info,
+ mojom::ContextualSearchJsApiServiceRequest request);
} // namespace contextual_search
diff --git a/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.cc b/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.cc
index d5a2b7f8008..0464a82ce05 100644
--- a/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.cc
+++ b/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.cc
@@ -12,7 +12,7 @@
#include "components/contextual_search/renderer/overlay_page_notifier_service_impl.h"
#include "content/public/renderer/render_frame.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "v8/include/v8.h"
namespace contextual_search {
@@ -37,7 +37,8 @@ void OverlayJsRenderFrameObserver::RegisterMojoInterface() {
}
void OverlayJsRenderFrameObserver::CreateOverlayPageNotifierService(
- mojo::InterfaceRequest<mojom::OverlayPageNotifierService> request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::OverlayPageNotifierServiceRequest request) {
mojo::MakeStrongBinding(
base::MakeUnique<OverlayPageNotifierServiceImpl>(
weak_factory_.GetWeakPtr()),
diff --git a/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.h b/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.h
index 53a7c870be1..fdaf82222e9 100644
--- a/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.h
+++ b/chromium/components/contextual_search/renderer/overlay_js_render_frame_observer.h
@@ -10,6 +10,7 @@
#include "components/contextual_search/common/overlay_page_notifier_service.mojom.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "v8/include/v8.h"
@@ -42,7 +43,8 @@ class OverlayJsRenderFrameObserver : public content::RenderFrameObserver {
// Creates the OverlayPageNotifierService connecting the browser to this
// observer.
void CreateOverlayPageNotifierService(
- mojo::InterfaceRequest<mojom::OverlayPageNotifierService> request);
+ const service_manager::BindSourceInfo& source_info,
+ mojom::OverlayPageNotifierServiceRequest request);
// Destroys the OverlayPageNotifierService.
void DestroyOverlayPageNotifierService();
diff --git a/chromium/components/crash/android/BUILD.gn b/chromium/components/crash/android/BUILD.gn
new file mode 100644
index 00000000000..425e96dc66c
--- /dev/null
+++ b/chromium/components/crash/android/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2017 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.
+
+import("//build/config/android/rules.gni")
+
+_jni_sources =
+ [ "java/src/org/chromium/components/crash/browser/CrashDumpManager.java" ]
+
+generate_jni("jni_headers") {
+ sources = _jni_sources
+ jni_package = "crash"
+}
+
+android_library("java") {
+ deps = [
+ "//base:base_java",
+ ]
+ java_files = _jni_sources
+}
+
+android_library("javatests") {
+ testonly = true
+ deps = [
+ ":java",
+ "//base:base_java",
+ "//base:base_java_test_support",
+ "//third_party/android_support_test_runner:runner_java",
+ "//third_party/junit",
+ ]
+ java_files = [ "javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java" ]
+}
diff --git a/chromium/components/memory_pressure/DEPS b/chromium/components/crash/android/DEPS
index 48e88750d4a..1129c7b690d 100644
--- a/chromium/components/memory_pressure/DEPS
+++ b/chromium/components/crash/android/DEPS
@@ -1,2 +1,3 @@
include_rules = [
-]
+ "+jni",
+] \ No newline at end of file
diff --git a/chromium/components/crash/android/OWNERS b/chromium/components/crash/android/OWNERS
new file mode 100644
index 00000000000..6b952ef4a27
--- /dev/null
+++ b/chromium/components/crash/android/OWNERS
@@ -0,0 +1,8 @@
+# Java readability
+mariakhomenko@chromium.org
+
+# Crash uploading mechanism
+gsennton@chromium.org
+isherman@chromium.org
+
+# COMPONENT: Internals>CrashReporting
diff --git a/chromium/components/crash/content/app/BUILD.gn b/chromium/components/crash/content/app/BUILD.gn
index e035ac30cbf..2a3c8525929 100644
--- a/chromium/components/crash/content/app/BUILD.gn
+++ b/chromium/components/crash/content/app/BUILD.gn
@@ -78,6 +78,7 @@ if (is_win) {
deps = [
"//base",
"//chrome/install_static:install_static_util",
+ "//components/browser_watcher:crash_stability",
"//third_party/crashpad/crashpad/client",
"//third_party/crashpad/crashpad/handler:handler_lib",
"//third_party/crashpad/crashpad/minidump",
@@ -238,7 +239,6 @@ source_set("unit_tests") {
":run_as_crashpad_handler",
"//breakpad:client",
"//third_party/crashpad/crashpad/client:client",
- "//third_party/crashpad/crashpad/compat",
"//third_party/crashpad/crashpad/snapshot:snapshot",
"//third_party/crashpad/crashpad/util",
]
diff --git a/chromium/components/crash/content/app/DEPS b/chromium/components/crash/content/app/DEPS
index dc5e932073f..9f77331a15a 100644
--- a/chromium/components/crash/content/app/DEPS
+++ b/chromium/components/crash/content/app/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+sandbox",
+ "+components/browser_watcher/stability_report_user_stream_data_source.h",
"+content/public/common/content_descriptors.h",
"+content/public/common/result_codes.h",
"+third_party/crashpad",
diff --git a/chromium/components/crash/content/app/crashpad.cc b/chromium/components/crash/content/app/crashpad.cc
index dcec3468435..ba04da14fe4 100644
--- a/chromium/components/crash/content/app/crashpad.cc
+++ b/chromium/components/crash/content/app/crashpad.cc
@@ -96,6 +96,7 @@ void DumpWithoutCrashing() {
void InitializeCrashpadImpl(bool initial_client,
const std::string& process_type,
+ const std::string& user_data_dir,
bool embedded_handler) {
static bool initialized = false;
DCHECK(!initialized);
@@ -123,7 +124,7 @@ void InitializeCrashpadImpl(bool initial_client,
// database_path is only valid in the browser process.
base::FilePath database_path = internal::PlatformCrashpadInitialization(
- initial_client, browser_process, embedded_handler);
+ initial_client, browser_process, embedded_handler, user_data_dir);
crashpad::CrashpadInfo* crashpad_info =
crashpad::CrashpadInfo::GetCrashpadInfo();
@@ -194,13 +195,14 @@ void InitializeCrashpadImpl(bool initial_client,
} // namespace
void InitializeCrashpad(bool initial_client, const std::string& process_type) {
- InitializeCrashpadImpl(initial_client, process_type, false);
+ InitializeCrashpadImpl(initial_client, process_type, std::string(), false);
}
#if defined(OS_WIN)
void InitializeCrashpadWithEmbeddedHandler(bool initial_client,
- const std::string& process_type) {
- InitializeCrashpadImpl(initial_client, process_type, true);
+ const std::string& process_type,
+ const std::string& user_data_dir) {
+ InitializeCrashpadImpl(initial_client, process_type, user_data_dir, true);
}
#endif // OS_WIN
diff --git a/chromium/components/crash/content/app/crashpad.h b/chromium/components/crash/content/app/crashpad.h
index ada0eaec733..91f498557ab 100644
--- a/chromium/components/crash/content/app/crashpad.h
+++ b/chromium/components/crash/content/app/crashpad.h
@@ -59,9 +59,11 @@ void InitializeCrashpad(bool initial_client, const std::string& process_type);
#if defined(OS_WIN)
// This is the same as InitializeCrashpad(), but rather than launching a
// crashpad_handler executable, relaunches the current executable with a command
-// line argument of --type=crashpad-handler.
+// line argument of --type=crashpad-handler. If user_data_dir is non-empty, it
+// is added to the handler's command line for use by Chrome Crashpad extensions.
void InitializeCrashpadWithEmbeddedHandler(bool initial_client,
- const std::string& process_type);
+ const std::string& process_type,
+ const std::string& user_data_dir);
#endif // OS_WIN
// Returns the CrashpadClient for this process. This will lazily create it if
@@ -116,11 +118,14 @@ void GetPlatformCrashpadAnnotations(
std::map<std::string, std::string>* annotations);
#endif // defined(OS_WIN)
-// The platform-specific portion of InitializeCrashpad().
+// The platform-specific portion of InitializeCrashpad(). On windows, if
+// user_data_dir is non-empty, the user data directory will be passed to the
+// handler process for use by Chrome Crashpad extensions.
// Returns the database path, if initializing in the browser process.
base::FilePath PlatformCrashpadInitialization(bool initial_client,
bool browser_process,
- bool embedded_handler);
+ bool embedded_handler,
+ const std::string& user_data_dir);
} // namespace internal
diff --git a/chromium/components/crash/content/app/crashpad_mac.mm b/chromium/components/crash/content/app/crashpad_mac.mm
index 3bae07e14c6..485c2b4b3e9 100644
--- a/chromium/components/crash/content/app/crashpad_mac.mm
+++ b/chromium/components/crash/content/app/crashpad_mac.mm
@@ -31,9 +31,11 @@
namespace crash_reporter {
namespace internal {
-base::FilePath PlatformCrashpadInitialization(bool initial_client,
- bool browser_process,
- bool embedded_handler) {
+base::FilePath PlatformCrashpadInitialization(
+ bool initial_client,
+ bool browser_process,
+ bool embedded_handler,
+ const std::string& user_data_dir) {
base::FilePath database_path; // Only valid in the browser process.
base::FilePath metrics_path; // Only valid in the browser process.
DCHECK(!embedded_handler); // This is not used on Mac.
diff --git a/chromium/components/crash/content/app/crashpad_win.cc b/chromium/components/crash/content/app/crashpad_win.cc
index 94a350f4b5a..6fdfd83d163 100644
--- a/chromium/components/crash/content/app/crashpad_win.cc
+++ b/chromium/components/crash/content/app/crashpad_win.cc
@@ -52,9 +52,11 @@ void GetPlatformCrashpadAnnotations(
#endif
}
-base::FilePath PlatformCrashpadInitialization(bool initial_client,
- bool browser_process,
- bool embedded_handler) {
+base::FilePath PlatformCrashpadInitialization(
+ bool initial_client,
+ bool browser_process,
+ bool embedded_handler,
+ const std::string& user_data_dir) {
base::FilePath database_path; // Only valid in the browser process.
base::FilePath metrics_path; // Only valid in the browser process.
@@ -107,6 +109,10 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client,
if (embedded_handler) {
start_arguments.push_back(std::string("--type=") +
switches::kCrashpadHandler);
+ if (!user_data_dir.empty()) {
+ start_arguments.push_back(std::string("--user-data-dir=") +
+ user_data_dir);
+ }
// The prefetch argument added here has to be documented in
// chrome_switches.cc, below the kPrefetchArgument* constants. A constant
// can't be used here because crashpad can't depend on Chrome.
diff --git a/chromium/components/crash/content/app/run_as_crashpad_handler_win.cc b/chromium/components/crash/content/app/run_as_crashpad_handler_win.cc
index 6ea93489f1f..9e5b05b4a6d 100644
--- a/chromium/components/crash/content/app/run_as_crashpad_handler_win.cc
+++ b/chromium/components/crash/content/app/run_as_crashpad_handler_win.cc
@@ -10,18 +10,23 @@
#include <vector>
#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
#include "base/process/memory.h"
-#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/browser_watcher/stability_report_user_stream_data_source.h"
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
#include "third_party/crashpad/crashpad/client/simple_string_dictionary.h"
#include "third_party/crashpad/crashpad/handler/handler_main.h"
+#include "third_party/crashpad/crashpad/handler/user_stream_data_source.h"
namespace crash_reporter {
int RunAsCrashpadHandler(const base::CommandLine& command_line,
- const char* process_type_switch) {
+ const base::FilePath& user_data_dir,
+ const char* process_type_switch,
+ const char* user_data_dir_switch) {
// Make sure this process terminates on OOM in the same mode as other Chrome
// processes.
base::EnableTerminationOnOutOfMemory();
@@ -46,11 +51,16 @@ int RunAsCrashpadHandler(const base::CommandLine& command_line,
std::vector<base::string16> argv = command_line.argv();
const base::string16 process_type_arg_prefix =
base::string16(L"--") + base::UTF8ToUTF16(process_type_switch) + L"=";
+ const base::string16 user_data_dir_arg_prefix =
+ base::string16(L"--") + base::UTF8ToUTF16(user_data_dir_switch) + L"=";
argv.erase(
std::remove_if(argv.begin(), argv.end(),
- [&process_type_arg_prefix](const base::string16& str) {
+ [&process_type_arg_prefix,
+ &user_data_dir_arg_prefix](const base::string16& str) {
return base::StartsWith(str, process_type_arg_prefix,
base::CompareCase::SENSITIVE) ||
+ base::StartsWith(str, user_data_dir_arg_prefix,
+ base::CompareCase::SENSITIVE) ||
(!str.empty() && str[0] == L'/');
}),
argv.end());
@@ -64,8 +74,20 @@ int RunAsCrashpadHandler(const base::CommandLine& command_line,
}
argv_as_utf8[argv.size()] = nullptr;
argv.clear();
+
+ crashpad::UserStreamDataSources user_stream_data_sources;
+ // Interpret an empty user data directory as a missing value.
+ if (!user_data_dir.empty()) {
+ // Register an extension to collect stability information. The extension
+ // will be invoked for any registered process' crashes, but information only
+ // exists for instrumented browser processes.
+ user_stream_data_sources.push_back(
+ base::MakeUnique<browser_watcher::StabilityReportUserStreamDataSource>(
+ user_data_dir));
+ }
+
return crashpad::HandlerMain(static_cast<int>(storage.size()),
- argv_as_utf8.get(), nullptr);
+ argv_as_utf8.get(), &user_stream_data_sources);
}
} // namespace crash_reporter
diff --git a/chromium/components/crash/content/app/run_as_crashpad_handler_win.h b/chromium/components/crash/content/app/run_as_crashpad_handler_win.h
index ade72a01db9..2f2c090aa8f 100644
--- a/chromium/components/crash/content/app/run_as_crashpad_handler_win.h
+++ b/chromium/components/crash/content/app/run_as_crashpad_handler_win.h
@@ -7,20 +7,26 @@
namespace base {
class CommandLine;
+class FilePath;
}
namespace crash_reporter {
// Helper for running an embedded copy of crashpad_handler. Searches for and
-// removes --(process_type_switch)=xyz arguments in the command line, and all
-// options starting with '/' (for "/prefetch:N"), and then runs
-// crashpad::HandlerMain with the remaining arguments.
+// removes --(process_type_switch|user_data_dir_switch)=xyz arguments in the
+// command line, and all options starting with '/' (for "/prefetch:N"), and then
+// runs crashpad::HandlerMain with the remaining arguments. If user_data_dir is
+// non-empty, a Crashpad extension to collect stability instrumentation on crash
+// is used.
//
-// Normally, pass switches::kProcessType for process_type_switch. It's accepted
-// as a parameter because this component does not have access to content/, where
-// that variable lives.
+// Normally, pass switches::kProcessType and switches::kCrashpadHandler for
+// process_type_switch and user_data_dir_switch. These are accepted as
+// parameters because this component does not have access to content/, where
+// those variables live.
int RunAsCrashpadHandler(const base::CommandLine& command_line,
- const char* process_type_switch);
+ const base::FilePath& user_data_dir,
+ const char* process_type_switch,
+ const char* user_data_dir_switch);
} // namespace crash_reporter
diff --git a/chromium/components/crash/content/browser/BUILD.gn b/chromium/components/crash/content/browser/BUILD.gn
index 20da935224c..31fb1d1aeb0 100644
--- a/chromium/components/crash/content/browser/BUILD.gn
+++ b/chromium/components/crash/content/browser/BUILD.gn
@@ -42,4 +42,8 @@ source_set("browser") {
configs += [ "//breakpad:client_config" ]
public_configs = [ "//breakpad:client_config" ]
}
+
+ if (is_android) {
+ deps += [ "//components/crash/android:jni_headers" ]
+ }
}
diff --git a/chromium/components/crash/content/browser/DEPS b/chromium/components/crash/content/browser/DEPS
index c24130ef510..95a50305336 100644
--- a/chromium/components/crash/content/browser/DEPS
+++ b/chromium/components/crash/content/browser/DEPS
@@ -1,4 +1,5 @@
include_rules = [
"+content/public/browser",
"+content/public/common",
+ "+jni",
]
diff --git a/chromium/components/crash/content/browser/crash_dump_manager_android.cc b/chromium/components/crash/content/browser/crash_dump_manager_android.cc
index bec13bdd5f4..c7b7628c239 100644
--- a/chromium/components/crash/content/browser/crash_dump_manager_android.cc
+++ b/chromium/components/crash/content/browser/crash_dump_manager_android.cc
@@ -6,6 +6,8 @@
#include <stdint.h>
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
@@ -23,6 +25,7 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
+#include "jni/CrashDumpManager_jni.h"
using content::BrowserThread;
@@ -153,8 +156,15 @@ void CrashDumpManager::ProcessMinidump(
base::DeleteFile(minidump_path, false);
return;
}
- VLOG(1) << "Crash minidump successfully generated: "
- << crash_dump_dir.Append(filename).value();
+ VLOG(1) << "Crash minidump successfully generated: " << dest_path.value();
+
+ // Hop over to Java to attempt to attach the logcat to the crash. This may
+ // fail, which is ok -- if it does, the crash will still be uploaded on the
+ // next browser start.
+ JNIEnv* env = base::android::AttachCurrentThread();
+ base::android::ScopedJavaLocalRef<jstring> j_dest_path =
+ base::android::ConvertUTF8ToJavaString(env, dest_path.value());
+ Java_CrashDumpManager_tryToUploadMinidump(env, j_dest_path);
}
void CrashDumpManager::OnChildExit(int child_process_id,
diff --git a/chromium/components/crash_strings.grdp b/chromium/components/crash_strings.grdp
index ab130d69648..7dc94713ce1 100644
--- a/chromium/components/crash_strings.grdp
+++ b/chromium/components/crash_strings.grdp
@@ -8,10 +8,10 @@
Crashes (<ph name="CRASH_COUNT">$1<ex>3</ex></ph>)
</message>
<message name="IDS_CRASH_CRASH_HEADER_FORMAT" desc="Format for crash entry headings on chrome://crashes">
- Crash ID <ph name="CRASH_LOCAL_ID">$2<ex>123456-789789</ex></ph> (Server ID: <ph name="CRASH_ID">$1<ex>8fa95dbb6f2ec862</ex></ph>)
+ Uploaded Crash Report ID <ph name="CRASH_ID">$1<ex>8fa95dbb6f2ec862</ex></ph> (Local Crash ID: <ph name="CRASH_LOCAL_ID">$2<ex>123456-789789</ex></ph>)
</message>
<message name="IDS_CRASH_CRASH_HEADER_FORMAT_LOCAL_ONLY" desc="Format for crash entry headings on chrome://crashes that have not been uploaded">
- Crash ID <ph name="CRASH_LOCAL_ID">$1<ex>123456-789789</ex></ph>
+ Local Crash ID <ph name="CRASH_LOCAL_ID">$1<ex>123456-789789</ex></ph>
</message>
<message name="IDS_CRASH_UPLOAD_TIME_FORMAT" desc="Format for crash report upload time displayed on chrome://crashes">
Crash report uploaded on <ph name="UPLOAD_TIME">$1<ex>Tuesday, January 25, 2011 2:58:02 PM</ex></ph>
diff --git a/chromium/components/cronet/android/BUILD.gn b/chromium/components/cronet/android/BUILD.gn
index c11669e7b70..811f6306288 100644
--- a/chromium/components/cronet/android/BUILD.gn
+++ b/chromium/components/cronet/android/BUILD.gn
@@ -14,10 +14,6 @@ import("//url/features.gni")
assert(!is_component_build, "Cronet requires static library build.")
-declare_args() {
- cronet_enable_data_reduction_proxy_support = false
-}
-
generate_jni("cronet_jni_headers") {
sources = [
"java/src/org/chromium/net/impl/CronetBidirectionalStream.java",
@@ -72,7 +68,7 @@ java_cpp_template("load_states_list") {
inputs = [
"//net/base/load_states_list.h",
]
- package_name = "org/chromium/net/impl"
+ package_path = "org/chromium/net/impl"
}
_generated_api_version_java_dir =
@@ -181,8 +177,6 @@ template("cronet_static_tmpl") {
"//components/cronet/android/cert/cert_verifier_cache_serializer.h",
"//components/cronet/android/cronet_bidirectional_stream_adapter.cc",
"//components/cronet/android/cronet_bidirectional_stream_adapter.h",
- "//components/cronet/android/cronet_in_memory_pref_store.cc",
- "//components/cronet/android/cronet_in_memory_pref_store.h",
"//components/cronet/android/cronet_library_loader.cc",
"//components/cronet/android/cronet_library_loader.h",
"//components/cronet/android/cronet_upload_data_stream.cc",
@@ -219,14 +213,6 @@ template("cronet_static_tmpl") {
"log",
]
- if (cronet_enable_data_reduction_proxy_support) {
- defines += [ "DATA_REDUCTION_PROXY_SUPPORT" ]
- sources += [
- "//components/cronet/android/cronet_data_reduction_proxy.cc",
- "//components/cronet/android/cronet_data_reduction_proxy.h",
- ]
- }
-
if (defined(invoker.defines)) {
defines += invoker.defines
}
@@ -243,13 +229,6 @@ cronet_static_tmpl("cronet_static") {
"//url",
]
- if (cronet_enable_data_reduction_proxy_support) {
- deps += [
- "//components/data_reduction_proxy/core/browser:browser_small",
- "//components/data_reduction_proxy/core/common",
- ]
- }
-
if (!use_platform_icu_alternatives) {
deps += [ "//base:i18n" ]
}
@@ -548,10 +527,6 @@ shared_library("cronet_tests") {
]
include_dirs = [ _cronet_version_header_include_dir ]
-
- if (cronet_enable_data_reduction_proxy_support) {
- deps += [ "//components/data_reduction_proxy/core/browser:browser_small" ]
- }
}
android_resources("cronet_test_apk_resources") {
@@ -568,7 +543,6 @@ android_library("cronet_test_apk_java") {
java_files = [
"test/src/org/chromium/net/CronetTestApplication.java",
- "test/src/org/chromium/net/CronetTestFramework.java",
"test/src/org/chromium/net/CronetTestUtil.java",
"test/src/org/chromium/net/Http2TestHandler.java",
"test/src/org/chromium/net/Http2TestServer.java",
@@ -587,7 +561,6 @@ android_library("cronet_test_apk_java") {
"//base:base_java",
"//base:base_java_test_support",
"//net/android:net_java_test_support",
- "//third_party/netty-tcnative:netty-tcnative_java",
"//third_party/netty4:netty_all_java",
]
@@ -632,8 +605,6 @@ android_assets("cronet_test_apk_assets") {
"test/assets/test/cacheable.txt.mock-http-headers",
"test/assets/test/content_length_mismatch.html",
"test/assets/test/content_length_mismatch.html.mock-http-headers",
- "test/assets/test/datareductionproxysuccess.txt",
- "test/assets/test/datareductionproxysuccess.txt.mock-http-headers",
"test/assets/test/gzipped.html",
"test/assets/test/gzipped.html.mock-http-headers",
"test/assets/test/multiredirect.html",
@@ -698,9 +669,11 @@ android_library("cronet_javatests") {
java_files = [
"test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java",
"test/javatests/src/org/chromium/net/BidirectionalStreamTest.java",
+ "test/javatests/src/org/chromium/net/BrotliTest.java",
"test/javatests/src/org/chromium/net/Criteria.java",
"test/javatests/src/org/chromium/net/CronetEngineBuilderTest.java",
"test/javatests/src/org/chromium/net/CronetTestBase.java",
+ "test/javatests/src/org/chromium/net/CronetTestBaseTest.java",
"test/javatests/src/org/chromium/net/CronetUploadTest.java",
"test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java",
"test/javatests/src/org/chromium/net/CronetUrlRequestTest.java",
@@ -709,6 +682,7 @@ android_library("cronet_javatests") {
"test/javatests/src/org/chromium/net/GetStatusTest.java",
"test/javatests/src/org/chromium/net/MetricsTestUtil.java",
"test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java",
+ "test/javatests/src/org/chromium/net/NQETest.java",
"test/javatests/src/org/chromium/net/PkpTest.java",
"test/javatests/src/org/chromium/net/QuicTest.java",
"test/javatests/src/org/chromium/net/RequestFinishedInfoTest.java",
@@ -1023,7 +997,6 @@ action("extract_cronet_test_jars") {
"$root_out_dir/lib.java/components/cronet/android/cronet_test_apk_java.jar",
"$root_out_dir/lib.java/net/android/net_java.jar",
"$root_out_dir/lib.java/net/android/net_java_test_support.jar",
- "$root_out_dir/lib.java/third_party/netty-tcnative/netty-tcnative_java.jar",
"$root_out_dir/lib.java/url/url_java.jar",
NETTY4_JAR_FILE,
]
@@ -1052,7 +1025,6 @@ action("extract_cronet_test_jars") {
"//base:base_java_test_support",
"//net/android:net_java",
"//net/android:net_java_test_support",
- "//third_party/netty-tcnative:netty-tcnative_java",
"//third_party/netty4:netty_all_java",
"//url:url_java",
]
@@ -1372,6 +1344,7 @@ copy("cronet_package_copy_test_files") {
"//net/data/ssl/certificates/quic_test.example.com.crt",
"//net/data/ssl/certificates/quic_test.example.com.key",
"//net/data/ssl/certificates/quic_test.example.com.key.pkcs8",
+ "//net/data/ssl/certificates/quic_test.example.com.key.pkcs8.pem",
"//net/data/ssl/certificates/quic_test.example.com.key.sct",
]
outputs = [
diff --git a/chromium/components/cronet/ios/BUILD.gn b/chromium/components/cronet/ios/BUILD.gn
index ac1dfe06202..716fa0b47ef 100644
--- a/chromium/components/cronet/ios/BUILD.gn
+++ b/chromium/components/cronet/ios/BUILD.gn
@@ -14,8 +14,10 @@ import("//url/features.gni")
assert(!is_component_build, "Cronet requires static library build.")
-declare_args() {
- cronet_enable_data_reduction_proxy_support = false
+group("cronet_consumer_group") {
+ deps = [
+ "//components/cronet/ios/cronet_consumer",
+ ]
}
process_version("cronet_version_header") {
diff --git a/chromium/components/cronet/ios/cronet_consumer/BUILD.gn b/chromium/components/cronet/ios/cronet_consumer/BUILD.gn
new file mode 100644
index 00000000000..966057c455d
--- /dev/null
+++ b/chromium/components/cronet/ios/cronet_consumer/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2016 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.
+
+import("//build/config/ios/rules.gni")
+
+ios_app_bundle("cronet_consumer") {
+ info_plist = "cronet-consumer-Info.plist"
+
+ deps = [
+ "//base:base",
+ "//components/cronet/ios:cronet_framework+link",
+
+ # All shared libraries must have the sanitizer deps to properly link in
+ # asan mode (this target will be empty in other cases).
+ "//build/config:exe_and_shlib_deps",
+ ]
+
+ sources = [
+ "cronet_consumer_app_delegate.h",
+ "cronet_consumer_app_delegate.mm",
+ "cronet_consumer_view_controller.h",
+ "cronet_consumer_view_controller.m",
+ "main.mm",
+ ]
+
+ bundle_deps = [ "//components/cronet/ios:cronet_framework+bundle" ]
+
+ configs += [ "//build/config/compiler:enable_arc" ]
+}
diff --git a/chromium/components/crx_file/BUILD.gn b/chromium/components/crx_file/BUILD.gn
index 8c5cceb5db2..412528e188e 100644
--- a/chromium/components/crx_file/BUILD.gn
+++ b/chromium/components/crx_file/BUILD.gn
@@ -2,10 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//third_party/protobuf/proto_library.gni")
+
static_library("crx_file") {
sources = [
- "crx_file.cc",
- "crx_file.h",
+ "crx2_file.cc",
+ "crx2_file.h",
+ "crx_verifier.cc",
+ "crx_verifier.h",
"id_util.cc",
"id_util.h",
]
@@ -14,17 +18,44 @@ static_library("crx_file") {
"//base",
"//crypto",
]
+
+ public_deps = [
+ ":crx3_proto",
+ ]
+}
+
+bundle_data("unit_tests_bundle_data") {
+ visibility = [ ":unit_tests" ]
+ testonly = true
+ sources = [
+ "//components/test/data/crx_file/unsigned.crx3",
+ "//components/test/data/crx_file/valid.crx2",
+ "//components/test/data/crx_file/valid_no_publisher.crx3",
+ "//components/test/data/crx_file/valid_publisher.crx3",
+ ]
+ outputs = [
+ "{{bundle_resources_dir}}/" +
+ "{{source_root_relative_dir}}/{{source_file_part}}",
+ ]
}
source_set("unit_tests") {
testonly = true
sources = [
+ "crx_verifier_unittest.cc",
"id_util_unittest.cc",
]
deps = [
":crx_file",
+ ":unit_tests_bundle_data",
"//base",
"//testing/gtest",
]
}
+
+proto_library("crx3_proto") {
+ sources = [
+ "crx3.proto",
+ ]
+}
diff --git a/chromium/components/crx_file/OWNERS b/chromium/components/crx_file/OWNERS
index 5a014d15275..8c5a6dbd3ba 100644
--- a/chromium/components/crx_file/OWNERS
+++ b/chromium/components/crx_file/OWNERS
@@ -1,2 +1,2 @@
-asargent@chromium.org
-rockot@chromium.org
+file://extensions/OWNERS
+
diff --git a/chromium/components/crx_file/crx2_file.cc b/chromium/components/crx_file/crx2_file.cc
new file mode 100644
index 00000000000..2c37bfe7979
--- /dev/null
+++ b/chromium/components/crx_file/crx2_file.cc
@@ -0,0 +1,79 @@
+// Copyright 2017 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/crx_file/crx2_file.h"
+
+#include "base/base64.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/numerics/safe_math.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "components/crx_file/id_util.h"
+#include "crypto/secure_hash.h"
+#include "crypto/sha2.h"
+#include "crypto/signature_verifier.h"
+
+namespace crx_file {
+
+namespace {
+
+// The current version of the crx format.
+static const uint32_t kCurrentVersion = 2;
+
+// The current version of the crx diff format.
+static const uint32_t kCurrentDiffVersion = 0;
+
+// The maximum size the crx parser will tolerate for a public key.
+static const uint32_t kMaxPublicKeySize = 1 << 16;
+
+// The maximum size the crx parser will tolerate for a signature.
+static const uint32_t kMaxSignatureSize = 1 << 16;
+
+} // namespace
+
+std::unique_ptr<Crx2File> Crx2File::Create(const uint32_t key_size,
+ const uint32_t signature_size,
+ Crx2File::Error* error) {
+ Crx2File::Header header;
+ memcpy(&header.magic, kCrx2FileHeaderMagic, kCrx2FileHeaderMagicSize);
+ header.version = kCurrentVersion;
+ header.key_size = key_size;
+ header.signature_size = signature_size;
+ if (HeaderIsValid(header, error))
+ return base::WrapUnique(new Crx2File(header));
+ return nullptr;
+}
+
+Crx2File::Crx2File(const Header& header) : header_(header) {}
+
+bool Crx2File::HeaderIsValid(const Crx2File::Header& header,
+ Crx2File::Error* error) {
+ bool valid = false;
+ bool diffCrx = false;
+ if (!strncmp(kCrxDiffFileHeaderMagic, header.magic, sizeof(header.magic)))
+ diffCrx = true;
+ if (strncmp(kCrx2FileHeaderMagic, header.magic, sizeof(header.magic)) &&
+ !diffCrx)
+ *error = kWrongMagic;
+ else if (header.version != kCurrentVersion &&
+ !(diffCrx && header.version == kCurrentDiffVersion))
+ *error = kInvalidVersion;
+ else if (header.key_size > kMaxPublicKeySize)
+ *error = kInvalidKeyTooLarge;
+ else if (header.key_size == 0)
+ *error = kInvalidKeyTooSmall;
+ else if (header.signature_size > kMaxSignatureSize)
+ *error = kInvalidSignatureTooLarge;
+ else if (header.signature_size == 0)
+ *error = kInvalidSignatureTooSmall;
+ else
+ valid = true;
+ return valid;
+}
+
+} // namespace crx_file
diff --git a/chromium/components/crx_file/crx2_file.h b/chromium/components/crx_file/crx2_file.h
new file mode 100644
index 00000000000..6fe1584116f
--- /dev/null
+++ b/chromium/components/crx_file/crx2_file.h
@@ -0,0 +1,76 @@
+// Copyright 2017 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_CRX_FILE_CRX2_FILE_H_
+#define COMPONENTS_CRX_FILE_CRX2_FILE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace crx_file {
+
+// The magic string embedded in the header.
+constexpr char kCrx2FileHeaderMagic[] = "Cr24";
+constexpr char kCrxDiffFileHeaderMagic[] = "CrOD";
+constexpr int kCrx2FileHeaderMagicSize = 4;
+
+// CRX files have a header that includes a magic key, version number, and
+// some signature sizing information. Use Crx2File object to validate whether
+// the header is valid or not.
+class Crx2File {
+ public:
+ // This header is the first data at the beginning of an extension. Its
+ // contents are purposely 32-bit aligned so that it can just be slurped into
+ // a struct without manual parsing.
+ struct Header {
+ char magic[kCrx2FileHeaderMagicSize];
+ uint32_t version;
+ uint32_t key_size; // The size of the public key, in bytes.
+ uint32_t signature_size; // The size of the signature, in bytes.
+ // An ASN.1-encoded PublicKeyInfo structure follows.
+ // The signature follows.
+ };
+
+ enum Error {
+ kWrongMagic,
+ kInvalidVersion,
+ kInvalidKeyTooLarge,
+ kInvalidKeyTooSmall,
+ kInvalidSignatureTooLarge,
+ kInvalidSignatureTooSmall,
+ kMaxValue,
+ };
+
+ // Construct a new header for the given key and signature sizes.
+ // Returns null if erroneous values of |key_size| and/or
+ // |signature_size| are provided. |error| contains an error code with
+ // additional information.
+ // Use this constructor and then .header() to obtain the Header
+ // for writing out to a CRX file.
+ static std::unique_ptr<Crx2File> Create(const uint32_t key_size,
+ const uint32_t signature_size,
+ Error* error);
+
+ // Returns the header structure for writing out to a CRX file.
+ const Header& header() const { return header_; }
+
+ private:
+ Header header_;
+
+ // Constructor is private. Clients should use static factory methods above.
+ explicit Crx2File(const Header& header);
+
+ // Checks the |header| for validity and returns true if the values are valid.
+ // If false is returned, more detailed error code is returned in |error|.
+ static bool HeaderIsValid(const Header& header, Error* error);
+};
+
+} // namespace crx_file
+
+#endif // COMPONENTS_CRX_FILE_CRX2_FILE_H_
diff --git a/chromium/components/crx_file/crx3.proto b/chromium/components/crx_file/crx3.proto
new file mode 100644
index 00000000000..2ea91f1c937
--- /dev/null
+++ b/chromium/components/crx_file/crx3.proto
@@ -0,0 +1,55 @@
+// Copyright 2017 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
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package crx_file;
+
+// A CRX₃ file is a binary file of the following format:
+// [4 octets]: "Cr24", a magic number.
+// [4 octets]: The version of the *.crx file format used (currently 3).
+// [4 octets]: N, little-endian, the length of the header section.
+// [N octets]: The header (the binary encoding of a CrxFileHeader).
+// [M octets]: The ZIP archive.
+// Clients should reject CRX₃ files that contain an N that is too large for the
+// client to safely handle in memory.
+
+message CrxFileHeader {
+ // PSS signature with RSA public key. The public key is formatted as a
+ // X.509 SubjectPublicKeyInfo block, as in CRXâ‚‚. In the common case of a
+ // developer key proof, the first 128 bits of the SHA-256 hash of the
+ // public key must equal the crx_id.
+ repeated AsymmetricKeyProof sha256_with_rsa = 2;
+
+ // ECDSA signature, using the NIST P-256 curve. Public key appears in
+ // named-curve format.
+ // The pinned algorithm will be this, at least on 2017-01-01.
+ repeated AsymmetricKeyProof sha256_with_ecdsa = 3;
+
+ // The binary form of a SignedData message. We do not use a nested
+ // SignedData message, as handlers of this message must verify the proofs
+ // on exactly these bytes, so it is convenient to parse in two steps.
+ //
+ // All proofs in this CrxFile message are on the value
+ // "CRX3 SignedData\x00" + signed_header_size + signed_header_data +
+ // archive, where "\x00" indicates an octet with value 0, "CRX3 SignedData"
+ // is encoded using UTF-8, signed_header_size is the size in octets of the
+ // contents of this field and is encoded using 4 octets in little-endian
+ // order, signed_header_data is exactly the content of this field, and
+ // archive is the remaining contents of the file following the header.
+ optional bytes signed_header_data = 10000;
+}
+
+message AsymmetricKeyProof {
+ optional bytes public_key = 1;
+ optional bytes signature = 2;
+}
+
+message SignedData {
+ // This is simple binary, not UTF-8 encoded mpdecimal; i.e. it is exactly
+ // 16 bytes long.
+ optional bytes crx_id = 1;
+}
diff --git a/chromium/components/crx_file/crx_file.cc b/chromium/components/crx_file/crx_file.cc
deleted file mode 100644
index c2b05f8e80b..00000000000
--- a/chromium/components/crx_file/crx_file.cc
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2014 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/crx_file/crx_file.h"
-
-#include "base/base64.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/numerics/safe_math.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "components/crx_file/id_util.h"
-#include "crypto/secure_hash.h"
-#include "crypto/sha2.h"
-#include "crypto/signature_verifier.h"
-
-namespace crx_file {
-
-namespace {
-
-// The current version of the crx format.
-static const uint32_t kCurrentVersion = 2;
-
-// The current version of the crx diff format.
-static const uint32_t kCurrentDiffVersion = 0;
-
-// The maximum size the crx parser will tolerate for a public key.
-static const uint32_t kMaxPublicKeySize = 1 << 16;
-
-// The maximum size the crx parser will tolerate for a signature.
-static const uint32_t kMaxSignatureSize = 1 << 16;
-
-// Helper function to read bytes into a buffer while also updating a hash with
-// those bytes. Returns the number of bytes read.
-size_t ReadAndHash(void* ptr,
- size_t size,
- size_t nmemb,
- FILE* stream,
- crypto::SecureHash* hash) {
- size_t item_count = fread(ptr, size, nmemb, stream);
- base::CheckedNumeric<size_t> byte_count(item_count);
- byte_count *= size;
- if (!byte_count.IsValid())
- return 0;
- if (item_count > 0 && hash) {
- hash->Update(ptr, byte_count.ValueOrDie());
- }
- return byte_count.ValueOrDie();
-}
-
-// Helper function to finish computing a hash and return an error if the
-// result of the hash didn't meet an expected base64-encoded value.
-CrxFile::ValidateError FinalizeHash(const std::string& extension_id,
- crypto::SecureHash* hash,
- const std::string& expected_hash) {
- CHECK(hash != nullptr);
- uint8_t output[crypto::kSHA256Length] = {};
- hash->Finish(output, sizeof(output));
- std::string hash_base64 =
- base::ToLowerASCII(base::HexEncode(output, sizeof(output)));
- if (hash_base64 != expected_hash) {
- LOG(ERROR) << "Hash check failed for extension: " << extension_id
- << ", expected " << expected_hash << ", got " << hash_base64;
- return CrxFile::ValidateError::CRX_HASH_VERIFICATION_FAILED;
- } else {
- return CrxFile::ValidateError::NONE;
- }
-}
-
-} // namespace
-
-// The magic string embedded in the header.
-const char kCrxFileHeaderMagic[] = "Cr24";
-const char kCrxDiffFileHeaderMagic[] = "CrOD";
-
-std::unique_ptr<CrxFile> CrxFile::Parse(const CrxFile::Header& header,
- CrxFile::Error* error) {
- if (HeaderIsValid(header, error))
- return base::WrapUnique(new CrxFile(header));
- return nullptr;
-}
-
-std::unique_ptr<CrxFile> CrxFile::Create(const uint32_t key_size,
- const uint32_t signature_size,
- CrxFile::Error* error) {
- CrxFile::Header header;
- memcpy(&header.magic, kCrxFileHeaderMagic, kCrxFileHeaderMagicSize);
- header.version = kCurrentVersion;
- header.key_size = key_size;
- header.signature_size = signature_size;
- if (HeaderIsValid(header, error))
- return base::WrapUnique(new CrxFile(header));
- return nullptr;
-}
-
-bool CrxFile::HeaderIsDelta(const CrxFile::Header& header) {
- return !strncmp(kCrxDiffFileHeaderMagic, header.magic, sizeof(header.magic));
-}
-
-// static
-CrxFile::ValidateError CrxFile::ValidateSignature(
- const base::FilePath& crx_path,
- const std::string& expected_hash,
- std::string* public_key,
- std::string* extension_id,
- CrxFile::Header* header_out) {
- base::ScopedFILE file(base::OpenFile(crx_path, "rb"));
- std::unique_ptr<crypto::SecureHash> hash;
- if (!expected_hash.empty())
- hash = crypto::SecureHash::Create(crypto::SecureHash::SHA256);
-
- if (!file.get())
- return ValidateError::CRX_FILE_NOT_READABLE;
-
- CrxFile::Header header;
- size_t len = ReadAndHash(&header, sizeof(header), 1, file.get(), hash.get());
- if (len != sizeof(header))
- return ValidateError::CRX_HEADER_INVALID;
- if (header_out)
- *header_out = header;
-
- CrxFile::Error error;
- std::unique_ptr<CrxFile> crx(CrxFile::Parse(header, &error));
- if (!crx) {
- switch (error) {
- case CrxFile::kWrongMagic:
- return ValidateError::CRX_MAGIC_NUMBER_INVALID;
- case CrxFile::kInvalidVersion:
- return ValidateError::CRX_VERSION_NUMBER_INVALID;
-
- case CrxFile::kInvalidKeyTooLarge:
- case CrxFile::kInvalidSignatureTooLarge:
- return ValidateError::CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE;
-
- case CrxFile::kInvalidKeyTooSmall:
- return ValidateError::CRX_ZERO_KEY_LENGTH;
- case CrxFile::kInvalidSignatureTooSmall:
- return ValidateError::CRX_ZERO_SIGNATURE_LENGTH;
-
- default:
- return ValidateError::CRX_HEADER_INVALID;
- }
- }
-
- std::vector<uint8_t> key(header.key_size);
- len = ReadAndHash(&key.front(), sizeof(uint8_t), header.key_size, file.get(),
- hash.get());
- if (len != header.key_size)
- return ValidateError::CRX_PUBLIC_KEY_INVALID;
-
- std::vector<uint8_t> signature(header.signature_size);
- len = ReadAndHash(&signature.front(), sizeof(uint8_t), header.signature_size,
- file.get(), hash.get());
- if (len < header.signature_size)
- return ValidateError::CRX_SIGNATURE_INVALID;
-
- crypto::SignatureVerifier verifier;
- if (!verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
- signature.data(), signature.size(), key.data(),
- key.size())) {
- // Signature verification initialization failed. This is most likely
- // caused by a public key in the wrong format (should encode algorithm).
- return ValidateError::CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED;
- }
-
- uint8_t buf[1 << 12] = {};
- while ((len = ReadAndHash(buf, sizeof(buf[0]), arraysize(buf), file.get(),
- hash.get())) > 0)
- verifier.VerifyUpdate(buf, len);
-
- if (!verifier.VerifyFinal())
- return ValidateError::CRX_SIGNATURE_VERIFICATION_FAILED;
-
- std::string public_key_bytes =
- std::string(reinterpret_cast<char*>(&key.front()), key.size());
- if (public_key)
- base::Base64Encode(public_key_bytes, public_key);
-
- std::string id = id_util::GenerateId(public_key_bytes);
- if (extension_id)
- *extension_id = id;
-
- if (!expected_hash.empty())
- return FinalizeHash(id, hash.get(), expected_hash);
-
- return ValidateError::NONE;
-}
-
-CrxFile::CrxFile(const Header& header) : header_(header) {}
-
-bool CrxFile::HeaderIsValid(const CrxFile::Header& header,
- CrxFile::Error* error) {
- bool valid = false;
- bool diffCrx = false;
- if (!strncmp(kCrxDiffFileHeaderMagic, header.magic, sizeof(header.magic)))
- diffCrx = true;
- if (strncmp(kCrxFileHeaderMagic, header.magic, sizeof(header.magic)) &&
- !diffCrx)
- *error = kWrongMagic;
- else if (header.version != kCurrentVersion
- && !(diffCrx && header.version == kCurrentDiffVersion))
- *error = kInvalidVersion;
- else if (header.key_size > kMaxPublicKeySize)
- *error = kInvalidKeyTooLarge;
- else if (header.key_size == 0)
- *error = kInvalidKeyTooSmall;
- else if (header.signature_size > kMaxSignatureSize)
- *error = kInvalidSignatureTooLarge;
- else if (header.signature_size == 0)
- *error = kInvalidSignatureTooSmall;
- else
- valid = true;
- return valid;
-}
-
-} // namespace crx_file
diff --git a/chromium/components/crx_file/crx_file.h b/chromium/components/crx_file/crx_file.h
deleted file mode 100644
index cf9bce8a81c..00000000000
--- a/chromium/components/crx_file/crx_file.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2014 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_CRX_FILE_CRX_FILE_H_
-#define COMPONENTS_CRX_FILE_CRX_FILE_H_
-
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace base {
-class FilePath;
-}
-
-namespace crx_file {
-
-// CRX files have a header that includes a magic key, version number, and
-// some signature sizing information. Use CrxFile object to validate whether
-// the header is valid or not.
-class CrxFile {
- public:
- // The size of the magic character sequence at the beginning of each crx
- // file, in bytes. This should be a multiple of 4.
- static const size_t kCrxFileHeaderMagicSize = 4;
-
- // This header is the first data at the beginning of an extension. Its
- // contents are purposely 32-bit aligned so that it can just be slurped into
- // a struct without manual parsing.
- struct Header {
- char magic[kCrxFileHeaderMagicSize];
- uint32_t version;
- uint32_t key_size; // The size of the public key, in bytes.
- uint32_t signature_size; // The size of the signature, in bytes.
- // An ASN.1-encoded PublicKeyInfo structure follows.
- // The signature follows.
- };
-
- enum Error {
- kWrongMagic,
- kInvalidVersion,
- kInvalidKeyTooLarge,
- kInvalidKeyTooSmall,
- kInvalidSignatureTooLarge,
- kInvalidSignatureTooSmall,
- };
-
- // Construct a new CRX file header object with bytes of a header
- // read from a CRX file. If a null scoped_ptr is returned, |error|
- // contains an error code with additional information.
- static std::unique_ptr<CrxFile> Parse(const Header& header, Error* error);
-
- // Construct a new header for the given key and signature sizes.
- // Returns a null scoped_ptr if erroneous values of |key_size| and/or
- // |signature_size| are provided. |error| contains an error code with
- // additional information.
- // Use this constructor and then .header() to obtain the Header
- // for writing out to a CRX file.
- static std::unique_ptr<CrxFile> Create(const uint32_t key_size,
- const uint32_t signature_size,
- Error* error);
-
- // Returns the header structure for writing out to a CRX file.
- const Header& header() const { return header_; }
-
- // Checks a valid |header| to determine whether or not the CRX represents a
- // differential CRX.
- static bool HeaderIsDelta(const Header& header);
-
- enum class ValidateError {
- NONE,
- CRX_FILE_NOT_READABLE,
- CRX_HEADER_INVALID,
- CRX_MAGIC_NUMBER_INVALID,
- CRX_VERSION_NUMBER_INVALID,
- CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE,
- CRX_ZERO_KEY_LENGTH,
- CRX_ZERO_SIGNATURE_LENGTH,
- CRX_PUBLIC_KEY_INVALID,
- CRX_SIGNATURE_INVALID,
- CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED,
- CRX_SIGNATURE_VERIFICATION_FAILED,
- CRX_HASH_VERIFICATION_FAILED,
- };
-
- // Validates that the .crx file at |crx_path| is properly signed. If
- // |expected_hash| is non-empty, it should specify a hex-encoded SHA256 hash
- // for the entire .crx file which will be checked as we read it, and any
- // mismatch will cause a CRX_HASH_VERIFICATION_FAILED result. The
- // |public_key| argument can be provided to receive a copy of the
- // base64-encoded public key pem bytes extracted from the .crx. The
- // |extension_id| argument can be provided to receive the extension id (which
- // is computed as a hash of the public key provided in the .crx). The
- // |header| argument can be provided to receive a copy of the crx header.
- static ValidateError ValidateSignature(const base::FilePath& crx_path,
- const std::string& expected_hash,
- std::string* public_key,
- std::string* extension_id,
- CrxFile::Header* header);
-
- private:
- Header header_;
-
- // Constructor is private. Clients should use static factory methods above.
- explicit CrxFile(const Header& header);
-
- // Checks the |header| for validity and returns true if the values are valid.
- // If false is returned, more detailed error code is returned in |error|.
- static bool HeaderIsValid(const Header& header, Error* error);
-};
-
-} // namespace crx_file
-
-#endif // COMPONENTS_CRX_FILE_CRX_FILE_H_
diff --git a/chromium/components/crx_file/crx_verifier.cc b/chromium/components/crx_file/crx_verifier.cc
new file mode 100644
index 00000000000..0a26b77d6f9
--- /dev/null
+++ b/chromium/components/crx_file/crx_verifier.cc
@@ -0,0 +1,308 @@
+// Copyright 2017 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/crx_file/crx_verifier.h"
+
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <set>
+#include <utility>
+
+#include "base/base64.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "components/crx_file/crx2_file.h"
+#include "components/crx_file/crx3.pb.h"
+#include "components/crx_file/id_util.h"
+#include "crypto/secure_hash.h"
+#include "crypto/secure_util.h"
+#include "crypto/sha2.h"
+#include "crypto/signature_verifier.h"
+
+namespace crx_file {
+
+namespace {
+
+// The maximum size the Crx2 parser will tolerate for a public key.
+constexpr uint32_t kMaxPublicKeySize = 1 << 16;
+
+// The maximum size the Crx2 parser will tolerate for a signature.
+constexpr uint32_t kMaxSignatureSize = 1 << 16;
+
+// The maximum size the Crx3 parser will tolerate for a header.
+constexpr uint32_t kMaxHeaderSize = 1 << 18;
+
+// The context for Crx3 signing, encoded in UTF8.
+constexpr unsigned char kSignatureContext[] = u8"CRX3 SignedData";
+
+// The SHA256 hash of the "ecdsa_2017_public" Crx3 key.
+constexpr uint8_t kPublisherKeyHash[] = {
+ 0x61, 0xf7, 0xf2, 0xa6, 0xbf, 0xcf, 0x74, 0xcd, 0x0b, 0xc1, 0xfe,
+ 0x24, 0x97, 0xcc, 0x9b, 0x04, 0x25, 0x4c, 0x65, 0x8f, 0x79, 0xf2,
+ 0x14, 0x53, 0x92, 0x86, 0x7e, 0xa8, 0x36, 0x63, 0x67, 0xcf};
+
+using VerifierCollection =
+ std::vector<std::unique_ptr<crypto::SignatureVerifier>>;
+using RepeatedProof = google::protobuf::RepeatedPtrField<AsymmetricKeyProof>;
+
+int ReadAndHashBuffer(uint8_t* buffer,
+ int length,
+ base::File* file,
+ crypto::SecureHash* hash) {
+ static_assert(sizeof(char) == sizeof(uint8_t), "Unsupported char size.");
+ int read = file->ReadAtCurrentPos(reinterpret_cast<char*>(buffer), length);
+ hash->Update(buffer, read);
+ return read;
+}
+
+// Returns UINT32_MAX in the case of an unexpected EOF or read error, else
+// returns the read uint32.
+uint32_t ReadAndHashLittleEndianUInt32(base::File* file,
+ crypto::SecureHash* hash) {
+ uint8_t buffer[4] = {};
+ if (ReadAndHashBuffer(buffer, 4, file, hash) != 4)
+ return UINT32_MAX;
+ return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
+}
+
+// Read to the end of the file, updating the hash and all verifiers.
+bool ReadHashAndVerifyArchive(base::File* file,
+ crypto::SecureHash* hash,
+ const VerifierCollection& verifiers) {
+ uint8_t buffer[1 << 12] = {};
+ size_t len = 0;
+ while ((len = ReadAndHashBuffer(buffer, arraysize(buffer), file, hash)) > 0) {
+ for (auto& verifier : verifiers)
+ verifier->VerifyUpdate(buffer, len);
+ }
+ for (auto& verifier : verifiers) {
+ if (!verifier->VerifyFinal())
+ return false;
+ }
+ return true;
+}
+
+// The remaining contents of a Crx3 file are [header-size][header][archive].
+// [header] is an encoded protocol buffer and contains both a signed and
+// unsigned section. The unsigned section contains a set of key/signature pairs,
+// and the signed section is the encoding of another protocol buffer. All
+// signatures cover [prefix][signed-header-size][signed-header][archive].
+VerifierResult VerifyCrx3(
+ base::File* file,
+ crypto::SecureHash* hash,
+ const std::vector<std::vector<uint8_t>>& required_key_hashes,
+ std::string* public_key,
+ std::string* crx_id,
+ bool require_publisher_key) {
+ // Parse [header-size] and [header].
+ const uint32_t header_size = ReadAndHashLittleEndianUInt32(file, hash);
+ if (header_size > kMaxHeaderSize)
+ return VerifierResult::ERROR_HEADER_INVALID;
+ std::vector<uint8_t> header_bytes(header_size);
+ // Assuming kMaxHeaderSize can fit in an int, the following cast is safe.
+ if (ReadAndHashBuffer(header_bytes.data(), header_size, file, hash) !=
+ static_cast<int>(header_size))
+ return VerifierResult::ERROR_HEADER_INVALID;
+ CrxFileHeader header;
+ if (!header.ParseFromArray(header_bytes.data(), header_size))
+ return VerifierResult::ERROR_HEADER_INVALID;
+
+ // Parse [signed-header].
+ const std::string& signed_header_data_str = header.signed_header_data();
+ SignedData signed_header_data;
+ if (!signed_header_data.ParseFromString(signed_header_data_str))
+ return VerifierResult::ERROR_HEADER_INVALID;
+ const std::string& crx_id_encoded = signed_header_data.crx_id();
+ const std::string declared_crx_id = id_util::GenerateIdFromHex(
+ base::HexEncode(crx_id_encoded.data(), crx_id_encoded.size()));
+
+ // Create a little-endian representation of [signed-header-size].
+ const int signed_header_size = signed_header_data_str.size();
+ const uint8_t header_size_octets[] = {
+ signed_header_size, signed_header_size >> 8, signed_header_size >> 16,
+ signed_header_size >> 24};
+
+ // Create a set of all required key hashes.
+ std::set<std::vector<uint8_t>> required_key_set(required_key_hashes.begin(),
+ required_key_hashes.end());
+ if (require_publisher_key) {
+ required_key_set.emplace(std::begin(kPublisherKeyHash),
+ std::end(kPublisherKeyHash));
+ }
+
+ using ProofFetcher = const RepeatedProof& (CrxFileHeader::*)() const;
+ ProofFetcher rsa = &CrxFileHeader::sha256_with_rsa;
+ ProofFetcher ecdsa = &CrxFileHeader::sha256_with_ecdsa;
+
+ std::string public_key_bytes;
+ VerifierCollection verifiers;
+ verifiers.reserve(header.sha256_with_rsa_size() +
+ header.sha256_with_ecdsa_size());
+ const std::vector<
+ std::pair<ProofFetcher, crypto::SignatureVerifier::SignatureAlgorithm>>
+ proof_types = {
+ std::make_pair(rsa, crypto::SignatureVerifier::RSA_PKCS1_SHA256),
+ std::make_pair(ecdsa, crypto::SignatureVerifier::ECDSA_SHA256)};
+
+ // Initialize all verifiers and update them with
+ // [prefix][signed-header-size][signed-header].
+ // Clear any elements of required_key_set that are encountered, and watch for
+ // the developer key.
+ for (const auto& proof_type : proof_types) {
+ for (const auto& proof : (header.*proof_type.first)()) {
+ const std::string& key = proof.public_key();
+ const std::string& sig = proof.signature();
+ if (id_util::GenerateId(key) == declared_crx_id)
+ public_key_bytes = key;
+ std::vector<uint8_t> key_hash(crypto::kSHA256Length);
+ crypto::SHA256HashString(key, key_hash.data(), key_hash.size());
+ required_key_set.erase(key_hash);
+ auto v = base::MakeUnique<crypto::SignatureVerifier>();
+ static_assert(sizeof(unsigned char) == sizeof(uint8_t),
+ "Unsupported char size.");
+ if (!v->VerifyInit(
+ proof_type.second, reinterpret_cast<const uint8_t*>(sig.data()),
+ sig.size(), reinterpret_cast<const uint8_t*>(key.data()),
+ key.size()))
+ return VerifierResult::ERROR_SIGNATURE_INITIALIZATION_FAILED;
+ v->VerifyUpdate(kSignatureContext, arraysize(kSignatureContext));
+ v->VerifyUpdate(header_size_octets, arraysize(header_size_octets));
+ v->VerifyUpdate(
+ reinterpret_cast<const uint8_t*>(signed_header_data_str.data()),
+ signed_header_data_str.size());
+ verifiers.push_back(std::move(v));
+ }
+ }
+ if (public_key_bytes.empty() || !required_key_set.empty())
+ return VerifierResult::ERROR_REQUIRED_PROOF_MISSING;
+
+ // Update and finalize the verifiers with [archive].
+ if (!ReadHashAndVerifyArchive(file, hash, verifiers))
+ return VerifierResult::ERROR_SIGNATURE_VERIFICATION_FAILED;
+
+ base::Base64Encode(public_key_bytes, public_key);
+ *crx_id = declared_crx_id;
+ return VerifierResult::OK_FULL;
+}
+
+VerifierResult VerifyCrx2(
+ base::File* file,
+ crypto::SecureHash* hash,
+ const std::vector<std::vector<uint8_t>>& required_key_hashes,
+ std::string* public_key,
+ std::string* crx_id) {
+ const uint32_t key_size = ReadAndHashLittleEndianUInt32(file, hash);
+ if (key_size > kMaxPublicKeySize)
+ return VerifierResult::ERROR_HEADER_INVALID;
+ const uint32_t sig_size = ReadAndHashLittleEndianUInt32(file, hash);
+ if (sig_size > kMaxSignatureSize)
+ return VerifierResult::ERROR_HEADER_INVALID;
+ std::vector<uint8_t> key(key_size);
+ if (ReadAndHashBuffer(key.data(), key_size, file, hash) !=
+ static_cast<int>(key_size))
+ return VerifierResult::ERROR_HEADER_INVALID;
+ for (const auto& expected_hash : required_key_hashes) {
+ // In practice we expect zero or one key_hashes_ for Crx2 files.
+ std::vector<uint8_t> hash(crypto::kSHA256Length);
+ std::unique_ptr<crypto::SecureHash> sha256 =
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256);
+ sha256->Update(key.data(), key.size());
+ sha256->Finish(hash.data(), hash.size());
+ if (hash != expected_hash)
+ return VerifierResult::ERROR_REQUIRED_PROOF_MISSING;
+ }
+
+ std::vector<uint8_t> sig(sig_size);
+ if (ReadAndHashBuffer(sig.data(), sig_size, file, hash) !=
+ static_cast<int>(sig_size))
+ return VerifierResult::ERROR_HEADER_INVALID;
+ std::vector<std::unique_ptr<crypto::SignatureVerifier>> verifiers;
+ verifiers.push_back(base::MakeUnique<crypto::SignatureVerifier>());
+ if (!verifiers[0]->VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
+ sig.data(), sig.size(), key.data(),
+ key.size())) {
+ return VerifierResult::ERROR_SIGNATURE_INITIALIZATION_FAILED;
+ }
+
+ if (!ReadHashAndVerifyArchive(file, hash, verifiers))
+ return VerifierResult::ERROR_SIGNATURE_VERIFICATION_FAILED;
+
+ const std::string public_key_bytes(key.begin(), key.end());
+ base::Base64Encode(public_key_bytes, public_key);
+ *crx_id = id_util::GenerateId(public_key_bytes);
+ return VerifierResult::OK_FULL;
+}
+
+} // namespace
+
+VerifierResult Verify(
+ const base::FilePath& crx_path,
+ const VerifierFormat& format,
+ const std::vector<std::vector<uint8_t>>& required_key_hashes,
+ const std::vector<uint8_t>& required_file_hash,
+ std::string* public_key,
+ std::string* crx_id) {
+ std::string public_key_local;
+ std::string crx_id_local;
+ base::File file(crx_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ if (!file.IsValid())
+ return VerifierResult::ERROR_FILE_NOT_READABLE;
+
+ std::unique_ptr<crypto::SecureHash> file_hash =
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256);
+
+ // Magic number.
+ bool diff = false;
+ char buffer[kCrx2FileHeaderMagicSize] = {};
+ if (file.ReadAtCurrentPos(buffer, kCrx2FileHeaderMagicSize) !=
+ kCrx2FileHeaderMagicSize)
+ return VerifierResult::ERROR_HEADER_INVALID;
+ if (!strncmp(buffer, kCrxDiffFileHeaderMagic, kCrx2FileHeaderMagicSize))
+ diff = true;
+ else if (strncmp(buffer, kCrx2FileHeaderMagic, kCrx2FileHeaderMagicSize))
+ return VerifierResult::ERROR_HEADER_INVALID;
+ file_hash->Update(buffer, sizeof(buffer));
+
+ // Version number.
+ const uint32_t version =
+ ReadAndHashLittleEndianUInt32(&file, file_hash.get());
+ VerifierResult result;
+ if (format == VerifierFormat::CRX2_OR_CRX3 &&
+ (version == 2 || (diff && version == 0)))
+ result = VerifyCrx2(&file, file_hash.get(), required_key_hashes,
+ &public_key_local, &crx_id_local);
+ else if (version == 3)
+ result = VerifyCrx3(&file, file_hash.get(), required_key_hashes,
+ &public_key_local, &crx_id_local,
+ format == VerifierFormat::CRX3_WITH_PUBLISHER_PROOF);
+ else
+ result = VerifierResult::ERROR_HEADER_INVALID;
+ if (result != VerifierResult::OK_FULL)
+ return result;
+
+ // Finalize file hash.
+ uint8_t final_hash[crypto::kSHA256Length] = {};
+ file_hash->Finish(final_hash, sizeof(final_hash));
+ if (!required_file_hash.empty()) {
+ if (required_file_hash.size() != crypto::kSHA256Length)
+ return VerifierResult::ERROR_EXPECTED_HASH_INVALID;
+ if (!crypto::SecureMemEqual(final_hash, required_file_hash.data(),
+ crypto::kSHA256Length))
+ return VerifierResult::ERROR_FILE_HASH_FAILED;
+ }
+
+ // All is well. Set the out-params and return.
+ if (public_key)
+ *public_key = public_key_local;
+ if (crx_id)
+ *crx_id = crx_id_local;
+ return diff ? VerifierResult::OK_DELTA : VerifierResult::OK_FULL;
+}
+
+} // namespace crx_file
diff --git a/chromium/components/crx_file/crx_verifier.h b/chromium/components/crx_file/crx_verifier.h
new file mode 100644
index 00000000000..35cf1956a24
--- /dev/null
+++ b/chromium/components/crx_file/crx_verifier.h
@@ -0,0 +1,53 @@
+// Copyright 2017 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_CRX_FILE_CRX_VERIFIER_H_
+#define COMPONENTS_CRX_FILE_CRX_VERIFIER_H_
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace base {
+class FilePath;
+} // namespace base
+
+namespace crx_file {
+
+enum class VerifierFormat {
+ CRX2_OR_CRX3, // Accept Crx2 or Crx3.
+ CRX3, // Accept only Crx3.
+ CRX3_WITH_PUBLISHER_PROOF, // Accept only Crx3 with a publisher proof.
+};
+
+enum class VerifierResult {
+ OK_FULL, // The file verifies as a correct full CRX file.
+ OK_DELTA, // The file verifies as a correct differential CRX file.
+ ERROR_FILE_NOT_READABLE, // Cannot open the CRX file.
+ ERROR_HEADER_INVALID, // Failed to parse or understand CRX header.
+ ERROR_EXPECTED_HASH_INVALID, // Expected hash is not well-formed.
+ ERROR_FILE_HASH_FAILED, // The file's actual hash != the expected hash.
+ ERROR_SIGNATURE_INITIALIZATION_FAILED, // A signature or key is malformed.
+ ERROR_SIGNATURE_VERIFICATION_FAILED, // A signature doesn't match.
+ ERROR_REQUIRED_PROOF_MISSING, // RequireKeyProof was unsatisfied.
+};
+
+// Verify the file at |crx_path| as a valid Crx of |format|. The Crx must be
+// well-formed, contain no invalid proofs, match the |required_file_hash| (if
+// non-empty), and contain a proof with each of the |required_key_hashes|.
+// If and only if this function returns OK_FULL or OK_DELTA, and only if
+// |public_key| / |crx_id| are non-null, they will be updated to contain the
+// public key (PEM format, without the header/footer) and crx id (encoded in
+// base16 using the characters [a-p]).
+VerifierResult Verify(
+ const base::FilePath& crx_path,
+ const VerifierFormat& format,
+ const std::vector<std::vector<uint8_t>>& required_key_hashes,
+ const std::vector<uint8_t>& required_file_hash,
+ std::string* public_key,
+ std::string* crx_id);
+
+} // namespace crx_file
+
+#endif // COMPONENTS_CRX_FILE_CRX_VERIFIER_H_
diff --git a/chromium/components/crx_file/crx_verifier_unittest.cc b/chromium/components/crx_file/crx_verifier_unittest.cc
new file mode 100644
index 00000000000..d5bd5a88296
--- /dev/null
+++ b/chromium/components/crx_file/crx_verifier_unittest.cc
@@ -0,0 +1,196 @@
+// Copyright 2017 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/crx_file/crx_verifier.h"
+#include "base/base_paths.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+base::FilePath TestFile(const std::string& file) {
+ base::FilePath path;
+ PathService::Get(base::DIR_SOURCE_ROOT, &path);
+ return path.AppendASCII("components")
+ .AppendASCII("test")
+ .AppendASCII("data")
+ .AppendASCII("crx_file")
+ .AppendASCII(file);
+}
+
+constexpr char kOjjHash[] = "ojjgnpkioondelmggbekfhllhdaimnho";
+constexpr char kOjjKey[] =
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA230uN7vYDEhdDlb4/"
+ "+pg2pfL8p0FFzCF/O146NB3D5dPKuLbnNphn0OUzOrDzR/Z1XLVDlDyiA6xnb+qeRp7H8n7Wk/"
+ "/gvVDNArZyForlVqWdaHLhl4dyZoNJwPKsggf30p/"
+ "MxCbNfy2rzFujzn2nguOrJKzWvNt0BFqssrBpzOQl69blBezE2ZYGOnYW8mPgQV29ekIgOfJk2"
+ "GgXoJBQQRRsjoPmUY7GDuEKudEB/"
+ "CmWh3+"
+ "mCsHBHFWbqtGhSN4YCAw3DYQzwdTcIVaIA8f2Uo4AZ4INKkrEPRL8o9mZDYtO2YHIQg8pMSRMa"
+ "6AawBNYi9tZScnmgl5L1qE6z5oIwIDAQAB";
+
+} // namespace
+
+namespace crx_file {
+
+using CrxVerifierTest = testing::Test;
+
+TEST_F(CrxVerifierTest, ValidFullCrx2) {
+ const std::vector<std::vector<uint8_t>> keys;
+ const std::vector<uint8_t> hash;
+ std::string public_key;
+ std::string crx_id;
+
+ EXPECT_EQ(VerifierResult::OK_FULL,
+ Verify(TestFile("valid.crx2"), VerifierFormat::CRX2_OR_CRX3, keys,
+ hash, &public_key, &crx_id));
+ EXPECT_EQ(std::string(kOjjHash), crx_id);
+ EXPECT_EQ(std::string(kOjjKey), public_key);
+}
+
+TEST_F(CrxVerifierTest, ValidFullCrx3) {
+ const std::vector<std::vector<uint8_t>> keys;
+ const std::vector<uint8_t> hash;
+ std::string public_key = "UNSET";
+ std::string crx_id = "UNSET";
+
+ EXPECT_EQ(VerifierResult::OK_FULL, Verify(TestFile("valid_no_publisher.crx3"),
+ VerifierFormat::CRX2_OR_CRX3, keys,
+ hash, &public_key, &crx_id));
+ EXPECT_EQ(std::string(kOjjHash), crx_id);
+ EXPECT_EQ(std::string(kOjjKey), public_key);
+
+ public_key = "UNSET";
+ crx_id = "UNSET";
+ EXPECT_EQ(VerifierResult::OK_FULL,
+ Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
+ keys, hash, &public_key, &crx_id));
+ EXPECT_EQ(std::string(kOjjHash), crx_id);
+ EXPECT_EQ(std::string(kOjjKey), public_key);
+}
+
+TEST_F(CrxVerifierTest, Crx3RejectsCrx2) {
+ const std::vector<std::vector<uint8_t>> keys;
+ const std::vector<uint8_t> hash;
+ std::string public_key = "UNSET";
+ std::string crx_id = "UNSET";
+
+ EXPECT_EQ(VerifierResult::ERROR_HEADER_INVALID,
+ Verify(TestFile("valid.crx2"), VerifierFormat::CRX3, keys, hash,
+ &public_key, &crx_id));
+ EXPECT_EQ("UNSET", crx_id);
+ EXPECT_EQ("UNSET", public_key);
+}
+
+TEST_F(CrxVerifierTest, VerifiesFileHash) {
+ const std::vector<std::vector<uint8_t>> keys;
+ std::vector<uint8_t> hash;
+ EXPECT_TRUE(base::HexStringToBytes(
+ "d033c510f9e4ee081ccb60ea2bf530dc2e5cb0e71085b55503c8b13b74515fe4",
+ &hash));
+ std::string public_key = "UNSET";
+ std::string crx_id = "UNSET";
+
+ EXPECT_EQ(VerifierResult::OK_FULL, Verify(TestFile("valid_no_publisher.crx3"),
+ VerifierFormat::CRX2_OR_CRX3, keys,
+ hash, &public_key, &crx_id));
+ EXPECT_EQ(std::string(kOjjHash), crx_id);
+ EXPECT_EQ(std::string(kOjjKey), public_key);
+
+ hash.clear();
+ EXPECT_TRUE(base::HexStringToBytes(std::string(32, '0'), &hash));
+ public_key = "UNSET";
+ crx_id = "UNSET";
+ EXPECT_EQ(VerifierResult::ERROR_EXPECTED_HASH_INVALID,
+ Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
+ keys, hash, &public_key, &crx_id));
+ EXPECT_EQ("UNSET", crx_id);
+ EXPECT_EQ("UNSET", public_key);
+
+ hash.clear();
+ EXPECT_TRUE(base::HexStringToBytes(std::string(64, '0'), &hash));
+ public_key = "UNSET";
+ crx_id = "UNSET";
+ EXPECT_EQ(VerifierResult::ERROR_FILE_HASH_FAILED,
+ Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
+ keys, hash, &public_key, &crx_id));
+ EXPECT_EQ("UNSET", crx_id);
+ EXPECT_EQ("UNSET", public_key);
+}
+
+TEST_F(CrxVerifierTest, ChecksRequiredKeyHashes) {
+ const std::vector<uint8_t> hash;
+
+ std::vector<uint8_t> good_key;
+ EXPECT_TRUE(base::HexStringToBytes(
+ "e996dfa8eed34bc6614a57bb7308cd7e519bcc690841e1969f7cb173ef16800a",
+ &good_key));
+ const std::vector<std::vector<uint8_t>> good_keys = {good_key};
+ std::string public_key = "UNSET";
+ std::string crx_id = "UNSET";
+ EXPECT_EQ(
+ VerifierResult::OK_FULL,
+ Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX2_OR_CRX3,
+ good_keys, hash, &public_key, &crx_id));
+ EXPECT_EQ(std::string(kOjjHash), crx_id);
+ EXPECT_EQ(std::string(kOjjKey), public_key);
+
+ std::vector<uint8_t> bad_key;
+ EXPECT_TRUE(base::HexStringToBytes(std::string(64, '0'), &bad_key));
+ const std::vector<std::vector<uint8_t>> bad_keys = {bad_key};
+ public_key = "UNSET";
+ crx_id = "UNSET";
+ EXPECT_EQ(VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
+ Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
+ bad_keys, hash, &public_key, &crx_id));
+ EXPECT_EQ("UNSET", crx_id);
+ EXPECT_EQ("UNSET", public_key);
+}
+
+TEST_F(CrxVerifierTest, ChecksPinnedKey) {
+ const std::vector<uint8_t> hash;
+ const std::vector<std::vector<uint8_t>> keys;
+ std::string public_key = "UNSET";
+ std::string crx_id = "UNSET";
+ EXPECT_EQ(VerifierResult::OK_FULL,
+ Verify(TestFile("valid_publisher.crx3"),
+ VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, keys, hash,
+ &public_key, &crx_id));
+ EXPECT_EQ(std::string(kOjjHash), crx_id);
+ EXPECT_EQ(std::string(kOjjKey), public_key);
+
+ public_key = "UNSET";
+ crx_id = "UNSET";
+ EXPECT_EQ(VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
+ Verify(TestFile("valid_no_publisher.crx3"),
+ VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, keys, hash,
+ &public_key, &crx_id));
+ EXPECT_EQ("UNSET", crx_id);
+ EXPECT_EQ("UNSET", public_key);
+}
+
+TEST_F(CrxVerifierTest, NullptrSafe) {
+ const std::vector<uint8_t> hash;
+ const std::vector<std::vector<uint8_t>> keys;
+ EXPECT_EQ(VerifierResult::OK_FULL,
+ Verify(TestFile("valid_publisher.crx3"),
+ VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, keys, hash,
+ nullptr, nullptr));
+}
+
+TEST_F(CrxVerifierTest, RequiresDeveloperKey) {
+ const std::vector<uint8_t> hash;
+ const std::vector<std::vector<uint8_t>> keys;
+ std::string public_key = "UNSET";
+ std::string crx_id = "UNSET";
+ EXPECT_EQ(VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
+ Verify(TestFile("unsigned.crx3"), VerifierFormat::CRX2_OR_CRX3,
+ keys, hash, &public_key, &crx_id));
+ EXPECT_EQ("UNSET", crx_id);
+ EXPECT_EQ("UNSET", public_key);
+}
+
+} // namespace crx_file
diff --git a/chromium/components/cryptauth/BUILD.gn b/chromium/components/cryptauth/BUILD.gn
index 103beaa64e8..b89eaaa91ae 100644
--- a/chromium/components/cryptauth/BUILD.gn
+++ b/chromium/components/cryptauth/BUILD.gn
@@ -10,6 +10,8 @@ static_library("cryptauth") {
sources = [
"authenticator.cc",
"authenticator.h",
+ "background_eid_generator.cc",
+ "background_eid_generator.h",
"bluetooth_throttler.h",
"bluetooth_throttler_impl.cc",
"bluetooth_throttler_impl.h",
@@ -38,16 +40,21 @@ static_library("cryptauth") {
"cryptauth_gcm_manager_impl.h",
"cryptauth_service.cc",
"cryptauth_service.h",
+ "data_with_timestamp.cc",
+ "data_with_timestamp.h",
"device_to_device_authenticator.cc",
"device_to_device_authenticator.h",
"device_to_device_initiator_operations.cc",
"device_to_device_initiator_operations.h",
"device_to_device_secure_context.cc",
"device_to_device_secure_context.h",
- "eid_generator.cc",
- "eid_generator.h",
+ "foreground_eid_generator.cc",
+ "foreground_eid_generator.h",
"pref_names.cc",
"pref_names.h",
+ "raw_eid_generator.h",
+ "raw_eid_generator_impl.cc",
+ "raw_eid_generator_impl.h",
"remote_beacon_seed_fetcher.cc",
"remote_beacon_seed_fetcher.h",
"remote_device.cc",
@@ -59,6 +66,8 @@ static_library("cryptauth") {
"secure_context.h",
"secure_message_delegate.cc",
"secure_message_delegate.h",
+ "session_keys.cc",
+ "session_keys.h",
"switches.cc",
"switches.h",
"sync_scheduler.cc",
@@ -113,8 +122,8 @@ static_library("test_support") {
"fake_secure_message_delegate.h",
"mock_cryptauth_client.cc",
"mock_cryptauth_client.h",
- "mock_eid_generator.cc",
- "mock_eid_generator.h",
+ "mock_foreground_eid_generator.cc",
+ "mock_foreground_eid_generator.h",
"mock_remote_beacon_seed_fetcher.cc",
"mock_remote_beacon_seed_fetcher.h",
"mock_sync_scheduler.cc",
@@ -138,6 +147,7 @@ static_library("test_support") {
source_set("unit_tests") {
testonly = true
sources = [
+ "background_eid_generator_unittest.cc",
"bluetooth_throttler_impl_unittest.cc",
"connection_unittest.cc",
"cryptauth_access_token_fetcher_impl_unittest.cc",
@@ -150,11 +160,13 @@ source_set("unit_tests") {
"device_to_device_authenticator_unittest.cc",
"device_to_device_operations_unittest.cc",
"device_to_device_secure_context_unittest.cc",
- "eid_generator_unittest.cc",
"fake_secure_message_delegate_unittest.cc",
+ "foreground_eid_generator_unittest.cc",
+ "raw_eid_generator_impl_unittest.cc",
"remote_beacon_seed_fetcher_unittest.cc",
"remote_device_loader_unittest.cc",
"secure_channel_unittest.cc",
+ "session_keys_unittest.cc",
"sync_scheduler_impl_unittest.cc",
"wire_message_unittest.cc",
]
diff --git a/chromium/components/cryptauth/background_eid_generator.cc b/chromium/components/cryptauth/background_eid_generator.cc
new file mode 100644
index 00000000000..a8a1b7bc094
--- /dev/null
+++ b/chromium/components/cryptauth/background_eid_generator.cc
@@ -0,0 +1,96 @@
+// Copyright 2016 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/cryptauth/background_eid_generator.h"
+
+#include <cstring>
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_util.h"
+#include "base/time/default_clock.h"
+#include "base/time/time.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+#include "components/cryptauth/raw_eid_generator.h"
+#include "components/cryptauth/raw_eid_generator_impl.h"
+#include "components/proximity_auth/logging/logging.h"
+
+namespace cryptauth {
+
+namespace {
+
+// The duration of a EID period in milliseconds.
+const int64_t kEidPeriodMs = 15 * 60 * 1000; // 15 minutes
+
+// The number of periods to look forward and backwards when calculating the
+// neartest EIDs.
+const int kEidLookAhead = 2;
+
+// Returns the BeaconSeed valid for |timestamp_ms|, or nullptr if none can be
+// found.
+const BeaconSeed* GetBeaconSeedForTimestamp(
+ int64_t timestamp_ms,
+ const std::vector<BeaconSeed>& beacon_seeds) {
+ for (const BeaconSeed& seed : beacon_seeds) {
+ if (timestamp_ms >= seed.start_time_millis() &&
+ timestamp_ms <= seed.end_time_millis()) {
+ return &seed;
+ }
+ }
+ return nullptr;
+}
+
+} // namespace
+
+BackgroundEidGenerator::BackgroundEidGenerator()
+ : BackgroundEidGenerator(base::MakeUnique<RawEidGeneratorImpl>(),
+ base::MakeUnique<base::DefaultClock>()) {}
+
+BackgroundEidGenerator::~BackgroundEidGenerator() {}
+
+BackgroundEidGenerator::BackgroundEidGenerator(
+ std::unique_ptr<RawEidGenerator> raw_eid_generator,
+ std::unique_ptr<base::Clock> clock)
+ : raw_eid_generator_(std::move(raw_eid_generator)),
+ clock_(std::move(clock)) {}
+
+std::vector<DataWithTimestamp> BackgroundEidGenerator::GenerateNearestEids(
+ const std::vector<BeaconSeed>& beacon_seeds) const {
+ int64_t now_timestamp_ms = clock_->Now().ToJavaTime();
+ std::vector<DataWithTimestamp> eids;
+
+ for (int i = -kEidLookAhead; i <= kEidLookAhead; ++i) {
+ int64_t timestamp_ms = now_timestamp_ms + i * kEidPeriodMs;
+ std::unique_ptr<DataWithTimestamp> eid =
+ GenerateEid(timestamp_ms, beacon_seeds);
+ if (eid)
+ eids.push_back(*eid);
+ }
+
+ PA_LOG(INFO) << "Generated EIDs: " << DataWithTimestamp::ToDebugString(eids);
+ return eids;
+}
+
+std::unique_ptr<DataWithTimestamp> BackgroundEidGenerator::GenerateEid(
+ int64_t timestamp_ms,
+ const std::vector<BeaconSeed>& beacon_seeds) const {
+ const BeaconSeed* beacon_seed =
+ GetBeaconSeedForTimestamp(timestamp_ms, beacon_seeds);
+ if (!beacon_seed) {
+ PA_LOG(INFO) << " " << timestamp_ms << ": outside of BeaconSeed range.";
+ return nullptr;
+ }
+
+ int64_t seed_start_time_ms = beacon_seed->start_time_millis();
+ int64_t offset_time_ms = timestamp_ms - seed_start_time_ms;
+ int64_t start_of_period_ms =
+ seed_start_time_ms + (offset_time_ms / kEidPeriodMs) * kEidPeriodMs;
+
+ std::string eid = raw_eid_generator_->GenerateEid(
+ beacon_seed->data(), start_of_period_ms, nullptr);
+
+ return base::MakeUnique<DataWithTimestamp>(eid, start_of_period_ms,
+ start_of_period_ms + kEidPeriodMs);
+}
+
+} // cryptauth
diff --git a/chromium/components/cryptauth/background_eid_generator.h b/chromium/components/cryptauth/background_eid_generator.h
new file mode 100644
index 00000000000..3fc067422b2
--- /dev/null
+++ b/chromium/components/cryptauth/background_eid_generator.h
@@ -0,0 +1,60 @@
+// Copyright 2017 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_CRYPTAUTH_BLE_BACKGROUND_EID_GENERATOR_H_
+#define COMPONENTS_CRYPTAUTH_BLE_BACKGROUND_EID_GENERATOR_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/time/clock.h"
+#include "components/cryptauth/data_with_timestamp.h"
+
+namespace cryptauth {
+
+class BeaconSeed;
+class RawEidGenerator;
+
+// Generates ephemeral ID (EID) values that are broadcast for background BLE
+// advertisements in the ProximityAuth protocol.
+//
+// When advertising in background mode, we offload advertising to the hardware
+// in order to conserve battery. We assume, however, that the scanning side is
+// not bound by battery constraints.
+//
+// For the inverse of this model, in which advertising is battery-sensitive, see
+// ForegroundEidGenerator.
+class BackgroundEidGenerator {
+ public:
+ BackgroundEidGenerator();
+ virtual ~BackgroundEidGenerator();
+
+ // Returns a list of the nearest EIDs from the current time. Note that the
+ // list of EIDs is sorted from earliest timestamp to latest.
+ virtual std::vector<DataWithTimestamp> GenerateNearestEids(
+ const std::vector<BeaconSeed>& beacon_seed) const;
+
+ private:
+ friend class CryptAuthBackgroundEidGeneratorTest;
+ BackgroundEidGenerator(std::unique_ptr<RawEidGenerator> raw_eid_generator,
+ std::unique_ptr<base::Clock> clock);
+
+ // Helper function to generate the EID for any |timestamp_ms|, properly
+ // calculating the start of the period. Returns nullptr if |timestamp_ms| is
+ // outside of range of |beacon_seeds|.
+ std::unique_ptr<DataWithTimestamp> GenerateEid(
+ int64_t timestamp_ms,
+ const std::vector<BeaconSeed>& beacon_seeds) const;
+
+ std::unique_ptr<RawEidGenerator> raw_eid_generator_;
+ std::unique_ptr<base::Clock> clock_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundEidGenerator);
+};
+
+} // cryptauth
+
+#endif // COMPONENTS_CRYPTAUTH_BLE_BACKGROUND_EID_GENERATOR_H_
diff --git a/chromium/components/cryptauth/background_eid_generator_unittest.cc b/chromium/components/cryptauth/background_eid_generator_unittest.cc
new file mode 100644
index 00000000000..3f74a6c558f
--- /dev/null
+++ b/chromium/components/cryptauth/background_eid_generator_unittest.cc
@@ -0,0 +1,192 @@
+// Copyright 2017 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/cryptauth/background_eid_generator.h"
+
+#include <memory>
+#include <string>
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_util.h"
+#include "base/test/simple_test_clock.h"
+#include "base/time/time.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+#include "components/cryptauth/raw_eid_generator_impl.h"
+#include "components/cryptauth/remote_device.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cryptauth {
+
+namespace {
+const int64_t kEidPeriodMs = base::TimeDelta::FromMinutes(15).InMilliseconds();
+const int64_t kBeaconSeedDurationMs =
+ base::TimeDelta::FromDays(14).InMilliseconds();
+
+// The number of nearest EIDs returned by GenerateNearestEids().
+const size_t kEidCount = 5;
+
+// Midnight on 1/1/2020.
+const int64_t kStartPeriodMs = 1577836800000L;
+// 1:43am on 1/1/2020.
+const int64_t kCurrentTimeMs = 1577843000000L;
+
+const std::string kFirstSeed = "firstSeed";
+const std::string kSecondSeed = "secondSeed";
+const std::string kThirdSeed = "thirdSeed";
+const std::string kFourthSeed = "fourthSeed";
+
+BeaconSeed CreateBeaconSeed(const std::string& data,
+ const int64_t start_timestamp_ms,
+ const int64_t end_timestamp_ms) {
+ BeaconSeed seed;
+ seed.set_data(data);
+ seed.set_start_time_millis(start_timestamp_ms);
+ seed.set_end_time_millis(end_timestamp_ms);
+ return seed;
+}
+
+DataWithTimestamp CreateEid(const std::string& eid_seed,
+ int64_t start_of_period_timestamp_ms) {
+ std::string data =
+ eid_seed + "|" + std::to_string(start_of_period_timestamp_ms);
+ return DataWithTimestamp(data, start_of_period_timestamp_ms,
+ start_of_period_timestamp_ms + kEidPeriodMs);
+}
+
+class TestRawEidGenerator : public RawEidGenerator {
+ public:
+ TestRawEidGenerator() {}
+ ~TestRawEidGenerator() override {}
+
+ // RawEidGenerator:
+ std::string GenerateEid(const std::string& eid_seed,
+ int64_t start_of_period_timestamp_ms,
+ std::string const* extra_entropy) override {
+ EXPECT_FALSE(extra_entropy);
+ return CreateEid(eid_seed, start_of_period_timestamp_ms).data;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestRawEidGenerator);
+};
+
+} // namespace
+
+class CryptAuthBackgroundEidGeneratorTest : public testing::Test {
+ protected:
+ CryptAuthBackgroundEidGeneratorTest() {
+ beacon_seeds_.push_back(CreateBeaconSeed(
+ kFirstSeed, kStartPeriodMs - kBeaconSeedDurationMs, kStartPeriodMs));
+ beacon_seeds_.push_back(CreateBeaconSeed(
+ kSecondSeed, kStartPeriodMs, kStartPeriodMs + kBeaconSeedDurationMs));
+ beacon_seeds_.push_back(
+ CreateBeaconSeed(kThirdSeed, kStartPeriodMs + kBeaconSeedDurationMs,
+ kStartPeriodMs + 2 * kBeaconSeedDurationMs));
+ beacon_seeds_.push_back(CreateBeaconSeed(
+ kFourthSeed, kStartPeriodMs + 2 * kBeaconSeedDurationMs,
+ kStartPeriodMs + 3 * kBeaconSeedDurationMs));
+ }
+
+ void SetUp() override {
+ test_clock_ = new base::SimpleTestClock();
+
+ SetTestTime(kCurrentTimeMs);
+
+ eid_generator_.reset(
+ new BackgroundEidGenerator(base::MakeUnique<TestRawEidGenerator>(),
+ base::WrapUnique(test_clock_)));
+ }
+
+ void SetTestTime(int64_t timestamp_ms) {
+ base::Time time = base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(timestamp_ms);
+ test_clock_->SetNow(time);
+ }
+
+ std::unique_ptr<BackgroundEidGenerator> eid_generator_;
+ base::SimpleTestClock* test_clock_;
+ std::vector<BeaconSeed> beacon_seeds_;
+};
+
+TEST_F(CryptAuthBackgroundEidGeneratorTest, BeaconSeedsExpired) {
+ SetTestTime(beacon_seeds_[beacon_seeds_.size() - 1].end_time_millis() +
+ kEidCount * kEidPeriodMs);
+ std::vector<DataWithTimestamp> eids =
+ eid_generator_->GenerateNearestEids(beacon_seeds_);
+ EXPECT_EQ(0u, eids.size());
+}
+
+TEST_F(CryptAuthBackgroundEidGeneratorTest, BeaconSeedsValidInFuture) {
+ SetTestTime(beacon_seeds_[0].start_time_millis() - kEidCount * kEidPeriodMs);
+ std::vector<DataWithTimestamp> eids =
+ eid_generator_->GenerateNearestEids(beacon_seeds_);
+ EXPECT_EQ(0u, eids.size());
+}
+
+TEST_F(CryptAuthBackgroundEidGeneratorTest, EidsUseSameBeaconSeed) {
+ int64_t start_period_ms =
+ beacon_seeds_[0].start_time_millis() + kEidCount * kEidPeriodMs;
+ SetTestTime(start_period_ms + kEidPeriodMs / 2);
+
+ std::vector<DataWithTimestamp> eids =
+ eid_generator_->GenerateNearestEids(beacon_seeds_);
+
+ std::string seed = beacon_seeds_[0].data();
+ EXPECT_EQ(kEidCount, eids.size());
+ EXPECT_EQ(CreateEid(seed, start_period_ms - 2 * kEidPeriodMs), eids[0]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms - 1 * kEidPeriodMs), eids[1]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms + 0 * kEidPeriodMs), eids[2]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms + 1 * kEidPeriodMs), eids[3]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms + 2 * kEidPeriodMs), eids[4]);
+}
+
+TEST_F(CryptAuthBackgroundEidGeneratorTest, EidsAcrossBeaconSeeds) {
+ int64_t end_period_ms = beacon_seeds_[0].end_time_millis();
+ int64_t start_period_ms = beacon_seeds_[1].start_time_millis();
+ SetTestTime(start_period_ms + kEidPeriodMs / 2);
+
+ std::vector<DataWithTimestamp> eids =
+ eid_generator_->GenerateNearestEids(beacon_seeds_);
+
+ std::string seed0 = beacon_seeds_[0].data();
+ std::string seed1 = beacon_seeds_[1].data();
+ EXPECT_EQ(kEidCount, eids.size());
+ EXPECT_EQ(CreateEid(seed0, end_period_ms - 2 * kEidPeriodMs), eids[0]);
+ EXPECT_EQ(CreateEid(seed0, end_period_ms - 1 * kEidPeriodMs), eids[1]);
+ EXPECT_EQ(CreateEid(seed1, start_period_ms + 0 * kEidPeriodMs), eids[2]);
+ EXPECT_EQ(CreateEid(seed1, start_period_ms + 1 * kEidPeriodMs), eids[3]);
+ EXPECT_EQ(CreateEid(seed1, start_period_ms + 2 * kEidPeriodMs), eids[4]);
+}
+
+TEST_F(CryptAuthBackgroundEidGeneratorTest, CurrentTimeAtStartOfRange) {
+ int64_t start_period_ms = beacon_seeds_[0].start_time_millis();
+ SetTestTime(start_period_ms + kEidPeriodMs / 2);
+
+ std::vector<DataWithTimestamp> eids =
+ eid_generator_->GenerateNearestEids(beacon_seeds_);
+
+ std::string seed = beacon_seeds_[0].data();
+ EXPECT_EQ(3u, eids.size());
+ EXPECT_EQ(CreateEid(seed, start_period_ms + 0 * kEidPeriodMs), eids[0]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms + 1 * kEidPeriodMs), eids[1]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms + 2 * kEidPeriodMs), eids[2]);
+}
+
+TEST_F(CryptAuthBackgroundEidGeneratorTest, CurrentTimeAtEndOfRange) {
+ int64_t start_period_ms = beacon_seeds_[3].end_time_millis() - kEidPeriodMs;
+ SetTestTime(start_period_ms + kEidPeriodMs / 2);
+
+ std::vector<DataWithTimestamp> eids =
+ eid_generator_->GenerateNearestEids(beacon_seeds_);
+
+ std::string seed = beacon_seeds_[3].data();
+ EXPECT_EQ(3u, eids.size());
+ EXPECT_EQ(CreateEid(seed, start_period_ms - 2 * kEidPeriodMs), eids[0]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms - 1 * kEidPeriodMs), eids[1]);
+ EXPECT_EQ(CreateEid(seed, start_period_ms - 0 * kEidPeriodMs), eids[2]);
+}
+
+} // namespace cryptauth
diff --git a/chromium/components/cryptauth/ble/BUILD.gn b/chromium/components/cryptauth/ble/BUILD.gn
index a1de6a07ebf..3b241a8b811 100644
--- a/chromium/components/cryptauth/ble/BUILD.gn
+++ b/chromium/components/cryptauth/ble/BUILD.gn
@@ -54,6 +54,7 @@ source_set("unit_tests") {
"//components/cryptauth",
"//components/cryptauth:test_support",
"//components/prefs:test_support",
+ "//components/proximity_auth/logging",
"//device/bluetooth:mocks",
"//testing/gmock",
"//testing/gtest",
diff --git a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
index 42351b9e6a6..d9d959aee0a 100644
--- a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
+++ b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.cc
@@ -38,7 +38,7 @@ const int kMaxNumberOfRetryAttempts = 2;
} // namespace
// static
-std::shared_ptr<BluetoothLowEnergyWeaveClientConnection::Factory>
+BluetoothLowEnergyWeaveClientConnection::Factory*
BluetoothLowEnergyWeaveClientConnection::Factory::factory_instance_ =
nullptr;
@@ -51,7 +51,7 @@ BluetoothLowEnergyWeaveClientConnection::Factory::NewInstance(
const device::BluetoothUUID remote_service_uuid,
BluetoothThrottler* bluetooth_throttler) {
if (!factory_instance_) {
- factory_instance_.reset(new Factory());
+ factory_instance_ = new Factory();
}
return factory_instance_->BuildInstance(
remote_device,
@@ -63,7 +63,7 @@ BluetoothLowEnergyWeaveClientConnection::Factory::NewInstance(
// static
void BluetoothLowEnergyWeaveClientConnection::Factory::SetInstanceForTesting(
- std::shared_ptr<Factory> factory) {
+ Factory* factory) {
factory_instance_ = factory;
}
@@ -122,8 +122,8 @@ BluetoothLowEnergyWeaveClientConnection::
void BluetoothLowEnergyWeaveClientConnection::Connect() {
DCHECK(sub_status() == SubStatus::DISCONNECTED);
+ SetSubStatus(SubStatus::WAITING_CONNECTION_LATENCY);
- SetSubStatus(SubStatus::WAITING_GATT_CONNECTION);
base::TimeDelta throttler_delay = bluetooth_throttler_->GetDelay();
PA_LOG(INFO) << "Connecting in " << throttler_delay;
@@ -137,17 +137,40 @@ void BluetoothLowEnergyWeaveClientConnection::Connect() {
task_runner_->PostDelayedTask(
FROM_HERE,
base::Bind(
- &BluetoothLowEnergyWeaveClientConnection::CreateGattConnection,
+ &BluetoothLowEnergyWeaveClientConnection::SetConnectionLatency,
weak_ptr_factory_.GetWeakPtr()),
throttler_delay);
return;
}
- CreateGattConnection();
+ SetConnectionLatency();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::SetConnectionLatency() {
+ DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_LATENCY);
+
+ PA_LOG(INFO) << "Setting connection latency for " << device_address_;
+
+ device::BluetoothDevice* bluetooth_device = GetBluetoothDevice();
+ if (!bluetooth_device) {
+ PA_LOG(WARNING) << "Could not create GATT connection with "
+ << device_address_ << " because the device could not be "
+ << "found.";
+ return;
+ }
+
+ bluetooth_device->SetConnectionLatency(
+ device::BluetoothDevice::ConnectionLatency::CONNECTION_LATENCY_LOW,
+ base::Bind(&BluetoothLowEnergyWeaveClientConnection::CreateGattConnection,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(
+ &BluetoothLowEnergyWeaveClientConnection::OnSetConnectionLatencyError,
+ weak_ptr_factory_.GetWeakPtr()));
}
void BluetoothLowEnergyWeaveClientConnection::CreateGattConnection() {
- DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
+ DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_LATENCY);
+ SetSubStatus(SubStatus::WAITING_GATT_CONNECTION);
PA_LOG(INFO) << "Creating GATT connection with " << device_address_;
@@ -250,7 +273,8 @@ void BluetoothLowEnergyWeaveClientConnection::DeviceChanged(
device->GetAddress() != GetDeviceAddress())
return;
- if (sub_status() != SubStatus::WAITING_GATT_CONNECTION &&
+ if (sub_status() != SubStatus::WAITING_CONNECTION_LATENCY &&
+ sub_status() != SubStatus::WAITING_GATT_CONNECTION &&
!device->IsConnected()) {
PA_LOG(INFO) << "GATT connection dropped " << GetDeviceAddress()
<< "\ndevice connected: " << device->IsConnected()
@@ -325,6 +349,14 @@ void BluetoothLowEnergyWeaveClientConnection::CompleteConnection() {
SetSubStatus(SubStatus::CONNECTED);
}
+void BluetoothLowEnergyWeaveClientConnection::OnSetConnectionLatencyError() {
+ DCHECK(sub_status_ == SubStatus::WAITING_CONNECTION_LATENCY);
+ PA_LOG(WARNING) << "Error setting connection latency.";
+ // Even if setting the connection latency fails, we should continue with the
+ // connection anyways.
+ CreateGattConnection();
+}
+
void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError(
device::BluetoothDevice::ConnectErrorCode error_code) {
DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION);
diff --git a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
index c77c894ab53..e86990c4526 100644
--- a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
+++ b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h
@@ -63,7 +63,7 @@ class BluetoothLowEnergyWeaveClientConnection
BluetoothThrottler* bluetooth_throttler);
// Exposed for testing.
- static void SetInstanceForTesting(std::shared_ptr<Factory> factory);
+ static void SetInstanceForTesting(Factory* factory);
protected:
// Exposed for testing.
@@ -75,13 +75,14 @@ class BluetoothLowEnergyWeaveClientConnection
BluetoothThrottler* bluetooth_throttler);
private:
- static std::shared_ptr<Factory> factory_instance_;
+ static Factory* factory_instance_;
};
// The sub-state of a BluetoothLowEnergyWeaveClientConnection
// extends the IN_PROGRESS state of Connection::Status.
enum SubStatus {
DISCONNECTED,
+ WAITING_CONNECTION_LATENCY,
WAITING_GATT_CONNECTION,
WAITING_CHARACTERISTICS,
CHARACTERISTICS_FOUND,
@@ -170,6 +171,9 @@ class BluetoothLowEnergyWeaveClientConnection
void SetSubStatus(SubStatus status);
+ // Sets the connection interval before connecting.
+ void SetConnectionLatency();
+
// Creates the GATT connection with |remote_device|.
void CreateGattConnection();
@@ -177,6 +181,9 @@ class BluetoothLowEnergyWeaveClientConnection
void OnGattConnectionCreated(
std::unique_ptr<device::BluetoothGattConnection> gatt_connection);
+ // Callback when there is an error setting the connection interval.
+ void OnSetConnectionLatencyError();
+
// Callback called when there is an error creating the GATT connection.
void OnCreateGattConnectionError(
device::BluetoothDevice::ConnectErrorCode error_code);
diff --git a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
index cf84e960bc2..894860c383a 100644
--- a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
+++ b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
@@ -20,6 +20,7 @@
#include "components/cryptauth/cryptauth_test_util.h"
#include "components/cryptauth/remote_device.h"
#include "components/cryptauth/wire_message.h"
+#include "components/proximity_auth/logging/logging.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/mock_bluetooth_device.h"
@@ -368,9 +369,9 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
receiver_factory_(
new MockBluetoothLowEnergyWeavePacketReceiverFactory()) {
BluetoothLowEnergyWeavePacketGenerator::Factory::SetInstanceForTesting(
- generator_factory_);
+ generator_factory_.get());
BluetoothLowEnergyWeavePacketReceiver::Factory::SetInstanceForTesting(
- receiver_factory_);
+ receiver_factory_.get());
}
~CryptAuthBluetoothLowEnergyWeaveClientConnectionTest() override {
@@ -441,6 +442,12 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
// Transitions |connection| from DISCONNECTED to WAITING_CHARACTERISTICS
// state, without an existing GATT connection.
void ConnectGatt(TestBluetoothLowEnergyWeaveClientConnection* connection) {
+ EXPECT_CALL(*mock_bluetooth_device_,
+ SetConnectionLatency(
+ device::BluetoothDevice::CONNECTION_LATENCY_LOW, _, _))
+ .WillOnce(DoAll(SaveArg<1>(&connection_latency_callback_),
+ SaveArg<2>(&connection_latency_error_callback_)));
+
// Preparing |connection| for a CreateGattConnection call.
EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection(_, _))
.WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_),
@@ -452,6 +459,13 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
connection->Connect();
+ // Handle setting the connection latency.
+ EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_CONNECTION_LATENCY);
+ EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
+ ASSERT_FALSE(connection_latency_callback_.is_null());
+ ASSERT_FALSE(connection_latency_error_callback_.is_null());
+ connection_latency_callback_.Run();
+
EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_GATT_CONNECTION);
EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
@@ -613,13 +627,15 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
base::MessageLoop message_loop_;
bool last_wire_message_success_;
- std::shared_ptr<MockBluetoothLowEnergyWeavePacketGeneratorFactory>
+ std::unique_ptr<MockBluetoothLowEnergyWeavePacketGeneratorFactory>
generator_factory_;
- std::shared_ptr<MockBluetoothLowEnergyWeavePacketReceiverFactory>
+ std::unique_ptr<MockBluetoothLowEnergyWeavePacketReceiverFactory>
receiver_factory_;
MockConnectionObserver connection_observer_;
// Callbacks
+ base::Closure connection_latency_callback_;
+ device::BluetoothDevice::ErrorCallback connection_latency_error_callback_;
device::BluetoothDevice::GattConnectionCallback
create_gatt_connection_success_callback_;
device::BluetoothDevice::ConnectErrorCallback
@@ -638,6 +654,8 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
base::Closure write_remote_characteristic_success_callback_;
device::BluetoothRemoteGattCharacteristic::ErrorCallback
write_remote_characteristic_error_callback_;
+
+ proximity_auth::ScopedDisableLoggingForTesting disable_logging_;
};
TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
@@ -1065,19 +1083,66 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
EXPECT_CALL(*bluetooth_throttler_, GetDelay())
.WillOnce(Return(base::TimeDelta(base::TimeDelta::FromSeconds(1))));
+ EXPECT_CALL(*mock_bluetooth_device_,
+ SetConnectionLatency(
+ device::BluetoothDevice::CONNECTION_LATENCY_LOW, _, _))
+ .WillOnce(DoAll(SaveArg<1>(&connection_latency_callback_),
+ SaveArg<2>(&connection_latency_error_callback_)));
EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection(_, _))
.WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_),
SaveArg<1>(&create_gatt_connection_error_callback_)));
// No GATT connection should be created before the delay.
connection->Connect();
- EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_GATT_CONNECTION);
+ EXPECT_EQ(connection->sub_status(), SubStatus::WAITING_CONNECTION_LATENCY);
EXPECT_EQ(connection->status(), Connection::IN_PROGRESS);
EXPECT_TRUE(create_gatt_connection_error_callback_.is_null());
EXPECT_TRUE(create_gatt_connection_success_callback_.is_null());
- // A GATT connection should be created after the delay.
+ // A GATT connection should be created after the delay and after setting the
+ // connection latency.
task_runner_->RunUntilIdle();
+ ASSERT_FALSE(connection_latency_callback_.is_null());
+ connection_latency_callback_.Run();
+
+ EXPECT_FALSE(create_gatt_connection_error_callback_.is_null());
+ ASSERT_FALSE(create_gatt_connection_success_callback_.is_null());
+
+ // Preparing |connection| to run |create_gatt_connection_success_callback_|.
+ EXPECT_CALL(*connection, CreateCharacteristicsFinder(_, _))
+ .WillOnce(DoAll(
+ SaveArg<0>(&characteristics_finder_success_callback_),
+ SaveArg<1>(&characteristics_finder_error_callback_),
+ Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>)));
+
+ create_gatt_connection_success_callback_.Run(
+ base::MakeUnique<NiceMock<device::MockBluetoothGattConnection>>(
+ adapter_, kTestRemoteDeviceBluetoothAddress));
+
+ CharacteristicsFound(connection.get());
+ NotifySessionStarted(connection.get());
+ ConnectionResponseReceived(connection.get(), kDefaultMaxPacketSize);
+}
+
+TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
+ SetConnectionLatencyError) {
+ std::unique_ptr<TestBluetoothLowEnergyWeaveClientConnection> connection(
+ CreateConnection());
+
+ EXPECT_CALL(*mock_bluetooth_device_,
+ SetConnectionLatency(
+ device::BluetoothDevice::CONNECTION_LATENCY_LOW, _, _))
+ .WillOnce(DoAll(SaveArg<1>(&connection_latency_callback_),
+ SaveArg<2>(&connection_latency_error_callback_)));
+
+ // Even if setting the connection interval fails, we should still connect.
+ connection->Connect();
+ ASSERT_FALSE(connection_latency_error_callback_.is_null());
+
+ EXPECT_CALL(*mock_bluetooth_device_, CreateGattConnection(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_),
+ SaveArg<1>(&create_gatt_connection_error_callback_)));
+ connection_latency_error_callback_.Run();
EXPECT_FALSE(create_gatt_connection_error_callback_.is_null());
ASSERT_FALSE(create_gatt_connection_success_callback_.is_null());
diff --git a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.cc b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.cc
index 164a47b65de..cba14631aaf 100644
--- a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.cc
+++ b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.cc
@@ -20,7 +20,7 @@ namespace cryptauth {
namespace weave {
// static.
-std::shared_ptr<BluetoothLowEnergyWeavePacketGenerator::Factory>
+BluetoothLowEnergyWeavePacketGenerator::Factory*
BluetoothLowEnergyWeavePacketGenerator::Factory::factory_instance_ =
nullptr;
@@ -28,14 +28,14 @@ std::shared_ptr<BluetoothLowEnergyWeavePacketGenerator::Factory>
std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator>
BluetoothLowEnergyWeavePacketGenerator::Factory::NewInstance() {
if (!factory_instance_) {
- factory_instance_.reset(new Factory());
+ factory_instance_ = new Factory();
}
return factory_instance_->BuildInstance();
}
// static.
void BluetoothLowEnergyWeavePacketGenerator::Factory::SetInstanceForTesting(
- std::shared_ptr<Factory> factory) {
+ Factory* factory) {
factory_instance_ = factory;
}
diff --git a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.h b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.h
index b59cfa43187..2cee2b8f164 100644
--- a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.h
+++ b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_generator.h
@@ -27,7 +27,7 @@ class BluetoothLowEnergyWeavePacketGenerator {
NewInstance();
// Exposed for testing.
- static void SetInstanceForTesting(std::shared_ptr<Factory> factory);
+ static void SetInstanceForTesting(Factory* factory);
protected:
// Exposed for testing.
@@ -35,7 +35,7 @@ class BluetoothLowEnergyWeavePacketGenerator {
BuildInstance();
private:
- static std::shared_ptr<Factory> factory_instance_;
+ static Factory* factory_instance_;
};
virtual Packet CreateConnectionRequest();
diff --git a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.cc b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.cc
index c29bb1a393f..b1055e86ba3 100644
--- a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.cc
+++ b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.cc
@@ -21,7 +21,7 @@ const uint16_t kMaxPacketSizeLowerBound = 20;
} // namespace
-std::shared_ptr<BluetoothLowEnergyWeavePacketReceiver::Factory>
+BluetoothLowEnergyWeavePacketReceiver::Factory*
BluetoothLowEnergyWeavePacketReceiver::Factory::factory_instance_ = nullptr;
// static
@@ -29,14 +29,14 @@ std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver>
BluetoothLowEnergyWeavePacketReceiver::Factory::NewInstance(
ReceiverType receiver_type) {
if (!factory_instance_) {
- factory_instance_.reset(new Factory());
+ factory_instance_ = new Factory();
}
return factory_instance_->BuildInstance(receiver_type);
}
// static
void BluetoothLowEnergyWeavePacketReceiver::Factory::SetInstanceForTesting(
- std::shared_ptr<Factory> factory) {
+ Factory* factory) {
factory_instance_ = factory;
}
diff --git a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.h b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.h
index 147963f1ff7..e369f540366 100644
--- a/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.h
+++ b/chromium/components/cryptauth/ble/bluetooth_low_energy_weave_packet_receiver.h
@@ -114,7 +114,7 @@ class BluetoothLowEnergyWeavePacketReceiver {
ReceiverType receiver_type);
// Exposed for testing.
- static void SetInstanceForTesting(std::shared_ptr<Factory> factory);
+ static void SetInstanceForTesting(Factory* factory);
protected:
// Exposed for testing.
@@ -122,7 +122,7 @@ class BluetoothLowEnergyWeavePacketReceiver {
BuildInstance(ReceiverType receiver_type);
private:
- static std::shared_ptr<Factory> factory_instance_;
+ static Factory* factory_instance_;
};
~BluetoothLowEnergyWeavePacketReceiver();
diff --git a/chromium/components/cryptauth/bluetooth_throttler_impl.cc b/chromium/components/cryptauth/bluetooth_throttler_impl.cc
index 239528a8632..74e09192655 100644
--- a/chromium/components/cryptauth/bluetooth_throttler_impl.cc
+++ b/chromium/components/cryptauth/bluetooth_throttler_impl.cc
@@ -16,7 +16,7 @@ namespace cryptauth {
namespace {
// Time to wait after disconnect before reconnecting.
-const int kCooldownTimeSecs = 7;
+const int kCooldownTimeSecs = 1;
} // namespace
diff --git a/chromium/components/cryptauth/data_with_timestamp.cc b/chromium/components/cryptauth/data_with_timestamp.cc
new file mode 100644
index 00000000000..7fbc96c2753
--- /dev/null
+++ b/chromium/components/cryptauth/data_with_timestamp.cc
@@ -0,0 +1,63 @@
+// Copyright 2017 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/cryptauth/data_with_timestamp.h"
+
+#include <iomanip>
+
+#include "base/logging.h"
+
+namespace cryptauth {
+
+DataWithTimestamp::DataWithTimestamp(const std::string& data,
+ const int64_t start_timestamp_ms,
+ const int64_t end_timestamp_ms)
+ : data(data),
+ start_timestamp_ms(start_timestamp_ms),
+ end_timestamp_ms(end_timestamp_ms) {
+ DCHECK(start_timestamp_ms < end_timestamp_ms);
+ DCHECK(data.size());
+}
+
+DataWithTimestamp::DataWithTimestamp(const DataWithTimestamp& other)
+ : data(other.data),
+ start_timestamp_ms(other.start_timestamp_ms),
+ end_timestamp_ms(other.end_timestamp_ms) {
+ DCHECK(start_timestamp_ms < end_timestamp_ms);
+ DCHECK(data.size());
+}
+
+// static.
+std::string DataWithTimestamp::ToDebugString(
+ const std::vector<DataWithTimestamp>& data_with_timestamps) {
+ std::stringstream ss;
+ ss << "[";
+ for (const DataWithTimestamp& data : data_with_timestamps) {
+ ss << "\n (" << data.start_timestamp_ms << ": " << data.DataInHex()
+ << "),";
+ }
+ ss << "\n]";
+ return ss.str();
+}
+
+bool DataWithTimestamp::ContainsTime(const int64_t timestamp_ms) const {
+ return start_timestamp_ms <= timestamp_ms && timestamp_ms < end_timestamp_ms;
+}
+
+std::string DataWithTimestamp::DataInHex() const {
+ std::stringstream ss;
+ ss << "0x";
+ for (uint8_t byte : data) {
+ ss << std::hex << std::setfill('0') << std::setw(2)
+ << static_cast<uint64_t>(byte);
+ }
+ return ss.str();
+}
+
+bool DataWithTimestamp::operator==(const DataWithTimestamp& other) const {
+ return data == other.data && start_timestamp_ms == other.start_timestamp_ms &&
+ end_timestamp_ms == other.end_timestamp_ms;
+}
+
+} // namespace cryptauth
diff --git a/chromium/components/cryptauth/data_with_timestamp.h b/chromium/components/cryptauth/data_with_timestamp.h
new file mode 100644
index 00000000000..f4e36a671bc
--- /dev/null
+++ b/chromium/components/cryptauth/data_with_timestamp.h
@@ -0,0 +1,43 @@
+// Copyright 2017 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_CRYPTAUTH_BLE_DATA_WITH_TIMESTAMP_H_
+#define COMPONENTS_CRYPTAUTH_BLE_DATA_WITH_TIMESTAMP_H_
+
+#include <string>
+#include <vector>
+
+namespace cryptauth {
+
+// Stores EID-related data and timestamps at which time this data becomes
+// active or inactive.
+struct DataWithTimestamp {
+ DataWithTimestamp(const std::string& data,
+ const int64_t start_timestamp_ms,
+ const int64_t end_timestamp_ms);
+ DataWithTimestamp(const DataWithTimestamp& other);
+
+ // Helper function to convert a vector of DataWithTimestamp objects to a human
+ // readable debug string.
+ static std::string ToDebugString(
+ const std::vector<DataWithTimestamp>& data_with_timestamps);
+
+ bool ContainsTime(const int64_t timestamp_ms) const;
+ std::string DataInHex() const;
+
+ bool operator==(const DataWithTimestamp& other) const;
+
+ // The data valid for a given time period.
+ const std::string data;
+
+ // The start time for which the data is valid, inclusive.
+ const int64_t start_timestamp_ms;
+
+ // The end time for which the data is valid, exclusive.
+ const int64_t end_timestamp_ms;
+};
+
+} // namespace
+
+#endif // COMPONENTS_CRYPTAUTH_BLE_DATA_WITH_TIMESTAMP_H_
diff --git a/chromium/components/cryptauth/device_to_device_authenticator.cc b/chromium/components/cryptauth/device_to_device_authenticator.cc
index d80449ffaa0..75e19f2f304 100644
--- a/chromium/components/cryptauth/device_to_device_authenticator.cc
+++ b/chromium/components/cryptauth/device_to_device_authenticator.cc
@@ -154,7 +154,7 @@ void DeviceToDeviceAuthenticator::OnResponderAuthTimedOut() {
void DeviceToDeviceAuthenticator::OnResponderAuthValidated(
bool validated,
- const std::string& session_symmetric_key) {
+ const SessionKeys& session_keys) {
if (!validated) {
Fail("Unable to validated [Responder Auth]");
return;
@@ -163,12 +163,11 @@ void DeviceToDeviceAuthenticator::OnResponderAuthValidated(
PA_LOG(INFO) << "Successfully validated [Responder Auth]! "
<< "Sending [Initiator Auth]...";
state_ = State::VALIDATED_RESPONDER_AUTH;
- session_symmetric_key_ = session_symmetric_key;
+ session_keys_ = session_keys;
// Create the [Initiator Auth] message to send to the remote device.
DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(
- session_symmetric_key,
- connection_->remote_device().persistent_symmetric_key,
+ session_keys_, connection_->remote_device().persistent_symmetric_key,
responder_auth_message_, secure_message_delegate_.get(),
base::Bind(&DeviceToDeviceAuthenticator::OnInitiatorAuthCreated,
weak_ptr_factory_.GetWeakPtr()));
@@ -204,7 +203,8 @@ void DeviceToDeviceAuthenticator::Fail(const std::string& error_message,
void DeviceToDeviceAuthenticator::Succeed() {
DCHECK(state_ == State::SENT_INITIATOR_AUTH);
- DCHECK(!session_symmetric_key_.empty());
+ DCHECK(!session_keys_.initiator_encode_key().empty());
+ DCHECK(!session_keys_.responder_encode_key().empty());
PA_LOG(INFO) << "Authentication succeeded!";
state_ = State::AUTHENTICATION_SUCCESS;
@@ -212,7 +212,7 @@ void DeviceToDeviceAuthenticator::Succeed() {
callback_.Run(
Result::SUCCESS,
base::MakeUnique<DeviceToDeviceSecureContext>(
- std::move(secure_message_delegate_), session_symmetric_key_,
+ std::move(secure_message_delegate_), session_keys_,
responder_auth_message_, SecureContext::PROTOCOL_VERSION_THREE_ONE));
}
diff --git a/chromium/components/cryptauth/device_to_device_authenticator.h b/chromium/components/cryptauth/device_to_device_authenticator.h
index e398206b2ba..13ffa6c2226 100644
--- a/chromium/components/cryptauth/device_to_device_authenticator.h
+++ b/chromium/components/cryptauth/device_to_device_authenticator.h
@@ -5,12 +5,15 @@
#ifndef COMPONENTS_CRYPTAUTH_DEVICE_TO_DEVICE_AUTHENTICATOR_H_
#define COMPONENTS_CRYPTAUTH_DEVICE_TO_DEVICE_AUTHENTICATOR_H_
+#include <memory>
+
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/cryptauth/authenticator.h"
#include "components/cryptauth/connection.h"
#include "components/cryptauth/connection_observer.h"
+#include "components/cryptauth/session_keys.h"
namespace base {
class Timer;
@@ -110,7 +113,7 @@ class DeviceToDeviceAuthenticator : public Authenticator,
// Callback for validating the received [Remote Auth].
void OnResponderAuthValidated(bool validated,
- const std::string& session_symmetric_key);
+ const SessionKeys& session_keys);
// Callback when [Initiator Auth] is created.
void OnInitiatorAuthCreated(const std::string& message);
@@ -168,8 +171,8 @@ class DeviceToDeviceAuthenticator : public Authenticator,
// The private key generated for the session.
std::string local_session_private_key_;
- // The derived symmetric key for the session.
- std::string session_symmetric_key_;
+ // The derived symmetric keys for the session.
+ SessionKeys session_keys_;
base::WeakPtrFactory<DeviceToDeviceAuthenticator> weak_ptr_factory_;
diff --git a/chromium/components/cryptauth/device_to_device_authenticator_unittest.cc b/chromium/components/cryptauth/device_to_device_authenticator_unittest.cc
index 507bedb1b9b..362cd8ea205 100644
--- a/chromium/components/cryptauth/device_to_device_authenticator_unittest.cc
+++ b/chromium/components/cryptauth/device_to_device_authenticator_unittest.cc
@@ -19,6 +19,7 @@
#include "components/cryptauth/device_to_device_responder_operations.h"
#include "components/cryptauth/fake_secure_message_delegate.h"
#include "components/cryptauth/secure_context.h"
+#include "components/cryptauth/session_keys.h"
#include "components/cryptauth/wire_message.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -269,7 +270,7 @@ TEST_F(ProximityAuthDeviceToDeviceAuthenticatorTest, AuthenticateSucceeds) {
bool initiator_auth_validated = false;
DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
- initiator_auth, session_symmetric_key_,
+ initiator_auth, SessionKeys(session_symmetric_key_),
remote_device_.persistent_symmetric_key, responder_auth_message,
secure_message_delegate_,
base::Bind(&SaveBooleanResult, &initiator_auth_validated));
diff --git a/chromium/components/cryptauth/device_to_device_initiator_operations.cc b/chromium/components/cryptauth/device_to_device_initiator_operations.cc
index f941e2631f9..9df030f4888 100644
--- a/chromium/components/cryptauth/device_to_device_initiator_operations.cc
+++ b/chromium/components/cryptauth/device_to_device_initiator_operations.cc
@@ -6,9 +6,11 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/memory/ptr_util.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h"
#include "components/cryptauth/proto/securemessage.pb.h"
#include "components/cryptauth/secure_message_delegate.h"
+#include "components/cryptauth/session_keys.h"
#include "components/proximity_auth/logging/logging.h"
namespace cryptauth {
@@ -24,10 +26,13 @@ const char kPayloadFiller[] = "\xae";
// The version to put in the GcmMetadata field.
const int kGcmMetadataVersion = 1;
+// The D2D protocol version.
+const int kD2DProtocolVersion = 1;
+
// Callback for DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(),
// after the inner message is created.
void OnInnerMessageCreatedForInitiatorAuth(
- const std::string& session_symmetric_key,
+ const SessionKeys& session_keys,
SecureMessageDelegate* secure_message_delegate,
const DeviceToDeviceInitiatorOperations::MessageCallback& callback,
const std::string& inner_message) {
@@ -44,7 +49,7 @@ void OnInnerMessageCreatedForInitiatorAuth(
// Store the inner message inside a DeviceToDeviceMessage proto.
securemessage::DeviceToDeviceMessage device_to_device_message;
device_to_device_message.set_message(inner_message);
- device_to_device_message.set_sequence_number(2);
+ device_to_device_message.set_sequence_number(1);
// Create and return the outer message, which wraps the inner message.
SecureMessageDelegate::CreateOptions create_options;
@@ -52,8 +57,8 @@ void OnInnerMessageCreatedForInitiatorAuth(
create_options.signature_scheme = securemessage::HMAC_SHA256;
gcm_metadata.SerializeToString(&create_options.public_metadata);
secure_message_delegate->CreateSecureMessage(
- device_to_device_message.SerializeAsString(), session_symmetric_key,
- create_options, callback);
+ device_to_device_message.SerializeAsString(),
+ session_keys.initiator_encode_key(), create_options, callback);
}
// Helper struct containing all the context needed to validate the
@@ -101,7 +106,7 @@ void BeginResponderAuthValidation(ValidateResponderAuthMessageContext context) {
if (!encrypted_message.ParseFromString(context.responder_auth_message) ||
!header_and_body.ParseFromString(encrypted_message.header_and_body())) {
PA_LOG(WARNING) << "Failed to parse [Responder Hello] message";
- context.callback.Run(false, std::string());
+ context.callback.Run(false, SessionKeys());
return;
}
@@ -114,7 +119,7 @@ void BeginResponderAuthValidation(ValidateResponderAuthMessageContext context) {
gcm_metadata.version() != kGcmMetadataVersion) {
PA_LOG(WARNING) << "Failed to validate GcmMetadata in "
<< "[Responder Auth] header.";
- context.callback.Run(false, std::string());
+ context.callback.Run(false, SessionKeys());
return;
}
@@ -125,7 +130,7 @@ void BeginResponderAuthValidation(ValidateResponderAuthMessageContext context) {
&context.responder_session_public_key)) {
PA_LOG(INFO) << "Failed to extract responder session public key in "
<< "[Responder Auth] header.";
- context.callback.Run(false, std::string());
+ context.callback.Run(false, SessionKeys());
return;
}
@@ -146,7 +151,8 @@ void OnSessionSymmetricKeyDerived(ValidateResponderAuthMessageContext context,
unwrap_options.encryption_scheme = securemessage::AES_256_CBC;
unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
context.secure_message_delegate->UnwrapSecureMessage(
- context.responder_auth_message, session_symmetric_key, unwrap_options,
+ context.responder_auth_message,
+ SessionKeys(session_symmetric_key).responder_encode_key(), unwrap_options,
base::Bind(&OnOuterMessageUnwrappedForResponderAuth, context));
}
@@ -158,7 +164,7 @@ void OnOuterMessageUnwrappedForResponderAuth(
const securemessage::Header& header) {
if (!verified) {
PA_LOG(INFO) << "Failed to unwrap outer [Responder Auth] message.";
- context.callback.Run(false, std::string());
+ context.callback.Run(false, SessionKeys());
return;
}
@@ -167,7 +173,7 @@ void OnOuterMessageUnwrappedForResponderAuth(
if (!device_to_device_message.ParseFromString(payload) ||
device_to_device_message.sequence_number() != 1) {
PA_LOG(INFO) << "Failed to validate DeviceToDeviceMessage payload.";
- context.callback.Run(false, std::string());
+ context.callback.Run(false, SessionKeys());
return;
}
@@ -191,7 +197,7 @@ void OnMiddleMessageUnwrappedForResponderAuth(
const securemessage::Header& header) {
if (!verified) {
PA_LOG(INFO) << "Failed to unwrap middle [Responder Auth] message.";
- context.callback.Run(false, std::string());
+ context.callback.Run(false, SessionKeys());
return;
}
@@ -222,11 +228,11 @@ void OnInnerMessageUnwrappedForResponderAuth(
gcm_metadata.type() != UNLOCK_KEY_SIGNED_CHALLENGE) {
PA_LOG(WARNING) << "Failed to validate GcmMetadata in inner-most "
<< "[Responder Auth] message.";
- context.callback.Run(false, std::string());
+ context.callback.Run(false, SessionKeys());
return;
}
- context.callback.Run(verified, context.session_symmetric_key);
+ context.callback.Run(verified, SessionKeys(context.session_symmetric_key));
}
} // namespace
@@ -238,13 +244,14 @@ void DeviceToDeviceInitiatorOperations::CreateHelloMessage(
SecureMessageDelegate* secure_message_delegate,
const MessageCallback& callback) {
// Decode public key into the |initator_hello| proto.
- securemessage::InitiatorHello initator_hello;
- if (!initator_hello.mutable_public_dh_key()->ParseFromString(
+ securemessage::InitiatorHello initiator_hello;
+ if (!initiator_hello.mutable_public_dh_key()->ParseFromString(
session_public_key)) {
PA_LOG(ERROR) << "Unable to parse user's public key";
callback.Run(std::string());
return;
}
+ initiator_hello.set_protocol_version(kD2DProtocolVersion);
// The [Hello] message has the structure:
// {
@@ -255,7 +262,7 @@ void DeviceToDeviceInitiatorOperations::CreateHelloMessage(
SecureMessageDelegate::CreateOptions create_options;
create_options.encryption_scheme = securemessage::NONE;
create_options.signature_scheme = securemessage::HMAC_SHA256;
- initator_hello.SerializeToString(&create_options.public_metadata);
+ initiator_hello.SerializeToString(&create_options.public_metadata);
secure_message_delegate->CreateSecureMessage(
kPayloadFiller, persistent_symmetric_key, create_options, callback);
}
@@ -299,7 +306,7 @@ void DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage(
// static
void DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(
- const std::string& session_symmetric_key,
+ const SessionKeys& session_keys,
const std::string& persistent_symmetric_key,
const std::string& responder_auth_message,
SecureMessageDelegate* secure_message_delegate,
@@ -322,7 +329,7 @@ void DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(
create_options.associated_data = responder_auth_message;
secure_message_delegate->CreateSecureMessage(
kPayloadFiller, persistent_symmetric_key, create_options,
- base::Bind(&OnInnerMessageCreatedForInitiatorAuth, session_symmetric_key,
+ base::Bind(&OnInnerMessageCreatedForInitiatorAuth, session_keys,
secure_message_delegate, callback));
}
diff --git a/chromium/components/cryptauth/device_to_device_initiator_operations.h b/chromium/components/cryptauth/device_to_device_initiator_operations.h
index 543663dbf10..cdef8bc8040 100644
--- a/chromium/components/cryptauth/device_to_device_initiator_operations.h
+++ b/chromium/components/cryptauth/device_to_device_initiator_operations.h
@@ -5,10 +5,12 @@
#ifndef COMPONENTS_CRYPTAUTH_DEVICE_TO_DEVICE_INITIATOR_OPERATIONS_H_
#define COMPONENTS_CRYPTAUTH_DEVICE_TO_DEVICE_INITIATOR_OPERATIONS_H_
+#include <memory>
#include <string>
#include "base/callback_forward.h"
#include "base/macros.h"
+#include "components/cryptauth/session_keys.h"
namespace cryptauth {
@@ -43,7 +45,7 @@ class DeviceToDeviceInitiatorOperations {
// called with the validation outcome. If validation succeeded, then the
// second argument will contain the session symmetric key derived from the
// [Responder Auth] message.
- typedef base::Callback<void(bool, const std::string&)>
+ typedef base::Callback<void(bool, const SessionKeys&)>
ValidateResponderAuthCallback;
// Creates the [Hello] message, which is the first message that is sent:
@@ -89,6 +91,7 @@ class DeviceToDeviceInitiatorOperations {
// Creates the [Initiator Auth] message, which allows the responder to
// authenticate the initiator:
+ // |session_keys|: The session symmetric keys.
// |persistent_symmetric_key|: The long-term symmetric key that is shared by
// the initiator and responder.
// |responder_auth_message|: The [Responder Auth] message sent previously to
@@ -98,7 +101,7 @@ class DeviceToDeviceInitiatorOperations {
// |callback|: Invoked upon operation completion with the serialized message
// or an empty string.
static void CreateInitiatorAuthMessage(
- const std::string& session_symmetric_key,
+ const SessionKeys& session_keys,
const std::string& persistent_symmetric_key,
const std::string& responder_auth_message,
SecureMessageDelegate* secure_message_delegate,
diff --git a/chromium/components/cryptauth/device_to_device_operations_unittest.cc b/chromium/components/cryptauth/device_to_device_operations_unittest.cc
index 05a2f63d0c5..8cffab2c410 100644
--- a/chromium/components/cryptauth/device_to_device_operations_unittest.cc
+++ b/chromium/components/cryptauth/device_to_device_operations_unittest.cc
@@ -8,6 +8,7 @@
#include "components/cryptauth/device_to_device_initiator_operations.h"
#include "components/cryptauth/device_to_device_responder_operations.h"
#include "components/cryptauth/fake_secure_message_delegate.h"
+#include "components/cryptauth/session_keys.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cryptauth {
@@ -52,6 +53,14 @@ void SaveValidationResultWithKey(bool* out_success,
*out_key = key;
}
+void SaveValidationResultWithSessionKeys(bool* out_success,
+ SessionKeys* out_keys,
+ bool success,
+ const SessionKeys& keys) {
+ *out_success = success;
+ *out_keys = keys;
+}
+
} // namespace
class ProximityAuthDeviceToDeviceOperationsTest : public testing::Test {
@@ -80,6 +89,7 @@ class ProximityAuthDeviceToDeviceOperationsTest : public testing::Test {
secure_message_delegate_.DeriveKey(
local_session_private_key_, remote_session_public_key_,
base::Bind(&SaveMessageResult, &session_symmetric_key_));
+ session_keys_ = SessionKeys(session_symmetric_key_);
persistent_symmetric_key_ = "persistent symmetric key";
}
@@ -116,7 +126,7 @@ class ProximityAuthDeviceToDeviceOperationsTest : public testing::Test {
const std::string& remote_auth_message) {
std::string local_auth_message;
DeviceToDeviceInitiatorOperations::CreateInitiatorAuthMessage(
- session_symmetric_key_, persistent_symmetric_key_, remote_auth_message,
+ session_keys_, persistent_symmetric_key_, remote_auth_message,
&secure_message_delegate_,
base::Bind(&SaveMessageResult, &local_auth_message));
EXPECT_FALSE(local_auth_message.empty());
@@ -131,6 +141,7 @@ class ProximityAuthDeviceToDeviceOperationsTest : public testing::Test {
std::string remote_session_public_key_;
std::string remote_session_private_key_;
std::string session_symmetric_key_;
+ SessionKeys session_keys_;
DISALLOW_COPY_AND_ASSIGN(ProximityAuthDeviceToDeviceOperationsTest);
};
@@ -169,16 +180,19 @@ TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
bool validation_success = false;
- std::string session_symmetric_key;
+ SessionKeys session_keys;
DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage(
remote_auth_message, kResponderPersistentPublicKey,
persistent_symmetric_key_, local_session_private_key_, hello_message,
&secure_message_delegate_,
- base::Bind(&SaveValidationResultWithKey, &validation_success,
- &session_symmetric_key));
+ base::Bind(&SaveValidationResultWithSessionKeys, &validation_success,
+ &session_keys));
EXPECT_TRUE(validation_success);
- EXPECT_EQ(session_symmetric_key_, session_symmetric_key);
+ EXPECT_EQ(session_keys_.initiator_encode_key(),
+ session_keys.initiator_encode_key());
+ EXPECT_EQ(session_keys_.responder_encode_key(),
+ session_keys.responder_encode_key());
}
TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
@@ -187,16 +201,17 @@ TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
bool validation_success = true;
- std::string session_symmetric_key = "non empty";
+ SessionKeys session_keys("non empty");
DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage(
remote_auth_message, kResponderPersistentPublicKey,
persistent_symmetric_key_, local_session_private_key_,
"invalid hello message", &secure_message_delegate_,
- base::Bind(&SaveValidationResultWithKey, &validation_success,
- &session_symmetric_key));
+ base::Bind(&SaveValidationResultWithSessionKeys, &validation_success,
+ &session_keys));
EXPECT_FALSE(validation_success);
- EXPECT_TRUE(session_symmetric_key.empty());
+ EXPECT_TRUE(session_keys.initiator_encode_key().empty());
+ EXPECT_TRUE(session_keys.responder_encode_key().empty());
}
TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
@@ -205,16 +220,17 @@ TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
std::string remote_auth_message = CreateResponderAuthMessage(hello_message);
bool validation_success = true;
- std::string session_symmetric_key = "non empty";
+ SessionKeys session_keys("non empty");
DeviceToDeviceInitiatorOperations::ValidateResponderAuthMessage(
remote_auth_message, kResponderPersistentPublicKey,
"invalid persistent symmetric key", local_session_private_key_,
hello_message, &secure_message_delegate_,
- base::Bind(&SaveValidationResultWithKey, &validation_success,
- &session_symmetric_key));
+ base::Bind(&SaveValidationResultWithSessionKeys, &validation_success,
+ &session_keys));
EXPECT_FALSE(validation_success);
- EXPECT_TRUE(session_symmetric_key.empty());
+ EXPECT_TRUE(session_keys.initiator_encode_key().empty());
+ EXPECT_TRUE(session_keys.responder_encode_key().empty());
}
TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
@@ -226,7 +242,7 @@ TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
bool validation_success = false;
DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
- local_auth_message, session_symmetric_key_, persistent_symmetric_key_,
+ local_auth_message, session_keys_, persistent_symmetric_key_,
remote_auth_message, &secure_message_delegate_,
base::Bind(&SaveValidationResult, &validation_success));
@@ -242,7 +258,7 @@ TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
bool validation_success = true;
DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
- local_auth_message, session_symmetric_key_, persistent_symmetric_key_,
+ local_auth_message, session_keys_, persistent_symmetric_key_,
"invalid remote auth", &secure_message_delegate_,
base::Bind(&SaveValidationResult, &validation_success));
@@ -258,9 +274,8 @@ TEST_F(ProximityAuthDeviceToDeviceOperationsTest,
bool validation_success = true;
DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
- local_auth_message, session_symmetric_key_,
- "invalid persistent symmetric key", remote_auth_message,
- &secure_message_delegate_,
+ local_auth_message, session_keys_, "invalid persistent symmetric key",
+ remote_auth_message, &secure_message_delegate_,
base::Bind(&SaveValidationResult, &validation_success));
EXPECT_FALSE(validation_success);
diff --git a/chromium/components/cryptauth/device_to_device_responder_operations.cc b/chromium/components/cryptauth/device_to_device_responder_operations.cc
index 3eb2a7cfe3b..08ea152fcbf 100644
--- a/chromium/components/cryptauth/device_to_device_responder_operations.cc
+++ b/chromium/components/cryptauth/device_to_device_responder_operations.cc
@@ -24,6 +24,9 @@ const char kPayloadFiller[] = "\xae";
// The version to put in the GcmMetadata field.
const int kGcmMetadataVersion = 1;
+// The D2D protocol version.
+const int kD2DProtocolVersion = 1;
+
// Callback for DeviceToDeviceResponderOperations::ValidateHelloMessage(),
// after the [Hello] message is unwrapped.
void OnHelloMessageUnwrapped(
@@ -32,7 +35,8 @@ void OnHelloMessageUnwrapped(
const std::string& payload,
const securemessage::Header& header) {
securemessage::InitiatorHello initiator_hello;
- if (!verified || !initiator_hello.ParseFromString(header.public_metadata())) {
+ if (!verified || !initiator_hello.ParseFromString(header.public_metadata()) ||
+ initiator_hello.protocol_version() != kD2DProtocolVersion) {
callback.Run(false, std::string());
return;
}
@@ -161,6 +165,7 @@ void OnSessionSymmetricKeyDerivedForResponderAuth(
context.callback.Run(std::string());
return;
}
+ responder_hello.set_protocol_version(kD2DProtocolVersion);
// Create the outer most message, wrapping the other messages created
// previously.
@@ -175,8 +180,9 @@ void OnSessionSymmetricKeyDerivedForResponderAuth(
responder_hello.SerializeToString(&create_options.decryption_key_id);
context.secure_message_delegate->CreateSecureMessage(
- device_to_device_message.SerializeAsString(), session_symmetric_key,
- create_options, context.callback);
+ device_to_device_message.SerializeAsString(),
+ SessionKeys(session_symmetric_key).responder_encode_key(), create_options,
+ context.callback);
}
// Helper struct containing all the context needed to validate the [Initiator
@@ -214,7 +220,7 @@ void OnOuterMessageUnwrappedForInitiatorAuth(
// Parse the decrypted payload.
securemessage::DeviceToDeviceMessage device_to_device_message;
if (!device_to_device_message.ParseFromString(payload) ||
- device_to_device_message.sequence_number() != 2) {
+ device_to_device_message.sequence_number() != 1) {
PA_LOG(INFO) << "Failed to validate DeviceToDeviceMessage payload.";
context.callback.Run(false);
return;
@@ -297,7 +303,7 @@ void DeviceToDeviceResponderOperations::CreateResponderAuthMessage(
// static
void DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
const std::string& initiator_auth_message,
- const std::string& session_symmetric_key,
+ const SessionKeys& session_keys,
const std::string& persistent_symmetric_key,
const std::string& responder_auth_message,
SecureMessageDelegate* secure_message_delegate,
@@ -322,7 +328,8 @@ void DeviceToDeviceResponderOperations::ValidateInitiatorAuthMessage(
unwrap_options.encryption_scheme = securemessage::AES_256_CBC;
unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
secure_message_delegate->UnwrapSecureMessage(
- initiator_auth_message, session_symmetric_key, unwrap_options,
+ initiator_auth_message, session_keys.initiator_encode_key(),
+ unwrap_options,
base::Bind(&OnOuterMessageUnwrappedForInitiatorAuth, context));
}
diff --git a/chromium/components/cryptauth/device_to_device_responder_operations.h b/chromium/components/cryptauth/device_to_device_responder_operations.h
index 6e16db1787d..9aa9a230f80 100644
--- a/chromium/components/cryptauth/device_to_device_responder_operations.h
+++ b/chromium/components/cryptauth/device_to_device_responder_operations.h
@@ -9,6 +9,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
+#include "components/cryptauth/session_keys.h"
namespace cryptauth {
@@ -92,8 +93,7 @@ class DeviceToDeviceResponderOperations {
// is properly signed and encrypted.
// |initiator_auth_message|: The bytes of the [Local Auth] message to
// validate.
- // |session_symmetric_key|: The derived symmetric key used just for the
- // session.
+ // |session_keys|: The derived symmetric keys used just for the session.
// |persistent_symmetric_key|: The long-term symmetric key that is shared by
// the initiator and responder.
// |secure_message_delegate|: Delegate for SecureMessage operations. This
@@ -102,7 +102,7 @@ class DeviceToDeviceResponderOperations {
// |responder_auth_message| is validated successfully.
static void ValidateInitiatorAuthMessage(
const std::string& initiator_auth_message,
- const std::string& session_symmetric_key,
+ const SessionKeys& session_keys,
const std::string& persistent_symmetric_key,
const std::string& responder_auth_message,
SecureMessageDelegate* secure_message_delegate,
diff --git a/chromium/components/cryptauth/device_to_device_secure_context.cc b/chromium/components/cryptauth/device_to_device_secure_context.cc
index 69f415c7ee7..3a11a63b8e7 100644
--- a/chromium/components/cryptauth/device_to_device_secure_context.cc
+++ b/chromium/components/cryptauth/device_to_device_secure_context.cc
@@ -20,22 +20,28 @@ namespace {
// The version to put in the GcmMetadata field.
const int kGcmMetadataVersion = 1;
-// The sequence number of the last message used during authentication. These
+// The sequence number of the last message sent during authentication. These
// messages are sent and received before the SecureContext is created.
-const int kAuthenticationSequenceNumber = 2;
+const int kAuthenticationEncodeSequenceNumber = 1;
+
+// The sequence number of the last message received during authentication. These
+// messages are sent and received before the SecureContext is created.
+const int kAuthenticationDecodeSequenceNumber = 1;
} // namespace
DeviceToDeviceSecureContext::DeviceToDeviceSecureContext(
std::unique_ptr<SecureMessageDelegate> secure_message_delegate,
- const std::string& symmetric_key,
+ const SessionKeys& session_keys,
const std::string& responder_auth_message,
ProtocolVersion protocol_version)
: secure_message_delegate_(std::move(secure_message_delegate)),
- symmetric_key_(symmetric_key),
+ encryption_key_(session_keys.initiator_encode_key()),
+ decryption_key_(session_keys.responder_encode_key()),
responder_auth_message_(responder_auth_message),
protocol_version_(protocol_version),
- last_sequence_number_(kAuthenticationSequenceNumber),
+ last_encode_sequence_number_(kAuthenticationEncodeSequenceNumber),
+ last_decode_sequence_number_(kAuthenticationDecodeSequenceNumber),
weak_ptr_factory_(this) {}
DeviceToDeviceSecureContext::~DeviceToDeviceSecureContext() {}
@@ -47,7 +53,7 @@ void DeviceToDeviceSecureContext::Decode(const std::string& encoded_message,
unwrap_options.signature_scheme = securemessage::HMAC_SHA256;
secure_message_delegate_->UnwrapSecureMessage(
- encoded_message, symmetric_key_, unwrap_options,
+ encoded_message, decryption_key_, unwrap_options,
base::Bind(&DeviceToDeviceSecureContext::HandleUnwrapResult,
weak_ptr_factory_.GetWeakPtr(), callback));
}
@@ -61,7 +67,7 @@ void DeviceToDeviceSecureContext::Encode(const std::string& message,
// Wrap |message| inside a DeviceToDeviceMessage proto.
securemessage::DeviceToDeviceMessage device_to_device_message;
- device_to_device_message.set_sequence_number(++last_sequence_number_);
+ device_to_device_message.set_sequence_number(++last_encode_sequence_number_);
device_to_device_message.set_message(message);
SecureMessageDelegate::CreateOptions create_options;
@@ -70,7 +76,7 @@ void DeviceToDeviceSecureContext::Encode(const std::string& message,
gcm_metadata.SerializeToString(&create_options.public_metadata);
secure_message_delegate_->CreateSecureMessage(
- device_to_device_message.SerializeAsString(), symmetric_key_,
+ device_to_device_message.SerializeAsString(), encryption_key_,
create_options, callback);
}
@@ -97,9 +103,11 @@ void DeviceToDeviceSecureContext::HandleUnwrapResult(
}
// Check that the sequence number matches the expected sequence number.
- if (device_to_device_message.sequence_number() != last_sequence_number_ + 1) {
- PA_LOG(ERROR) << "Expected sequence_number=" << last_sequence_number_ + 1
- << ", but got " << device_to_device_message.sequence_number();
+ if (device_to_device_message.sequence_number() !=
+ last_decode_sequence_number_ + 1) {
+ PA_LOG(ERROR) << "Expected sequence_number="
+ << last_decode_sequence_number_ + 1 << ", but got "
+ << device_to_device_message.sequence_number();
callback.Run(std::string());
return;
}
@@ -114,7 +122,7 @@ void DeviceToDeviceSecureContext::HandleUnwrapResult(
return;
}
- last_sequence_number_++;
+ last_decode_sequence_number_++;
callback.Run(device_to_device_message.message());
}
diff --git a/chromium/components/cryptauth/device_to_device_secure_context.h b/chromium/components/cryptauth/device_to_device_secure_context.h
index 0b59033cdc4..70f1c352985 100644
--- a/chromium/components/cryptauth/device_to_device_secure_context.h
+++ b/chromium/components/cryptauth/device_to_device_secure_context.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/cryptauth/secure_context.h"
+#include "components/cryptauth/session_keys.h"
namespace securemessage {
class Header;
@@ -24,7 +25,7 @@ class DeviceToDeviceSecureContext : public SecureContext {
public:
DeviceToDeviceSecureContext(
std::unique_ptr<SecureMessageDelegate> secure_message_delegate,
- const std::string& symmetric_key,
+ const SessionKeys& session_keys,
const std::string& responder_auth_message_,
ProtocolVersion protocol_version);
@@ -51,8 +52,11 @@ class DeviceToDeviceSecureContext : public SecureContext {
// Delegate for handling the creation and unwrapping of SecureMessages.
std::unique_ptr<SecureMessageDelegate> secure_message_delegate_;
- // The symmetric key used to create and unwrap messages.
- const std::string symmetric_key_;
+ // The symmetric key used for encryption.
+ const std::string encryption_key_;
+
+ // The symmetric key used for decryption.
+ const std::string decryption_key_;
// The [Responder Auth] message received from the remote device during
// authentication.
@@ -61,8 +65,11 @@ class DeviceToDeviceSecureContext : public SecureContext {
// The protocol version supported by the remote device.
const ProtocolVersion protocol_version_;
- // The last sequence number of the message sent or received.
- int last_sequence_number_;
+ // The last sequence number of the message sent.
+ int last_encode_sequence_number_;
+
+ // The last sequence number of the message received.
+ int last_decode_sequence_number_;
base::WeakPtrFactory<DeviceToDeviceSecureContext> weak_ptr_factory_;
diff --git a/chromium/components/cryptauth/device_to_device_secure_context_unittest.cc b/chromium/components/cryptauth/device_to_device_secure_context_unittest.cc
index 12c1994fa20..f26749264a8 100644
--- a/chromium/components/cryptauth/device_to_device_secure_context_unittest.cc
+++ b/chromium/components/cryptauth/device_to_device_secure_context_unittest.cc
@@ -11,6 +11,7 @@
#include "components/cryptauth/fake_secure_message_delegate.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h"
#include "components/cryptauth/proto/securemessage.pb.h"
+#include "components/cryptauth/session_keys.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cryptauth {
@@ -27,16 +28,34 @@ void SaveResult(std::string* result_out, const std::string& result) {
*result_out = result;
}
+// The responder's secure context will have the encoding / decoding keys
+// inverted.
+class InvertedSessionKeys : public SessionKeys {
+ public:
+ explicit InvertedSessionKeys(const std::string& master_symmetric_key)
+ : SessionKeys(master_symmetric_key) {}
+
+ InvertedSessionKeys() : SessionKeys() {}
+
+ InvertedSessionKeys(const InvertedSessionKeys& other) : SessionKeys(other) {}
+
+ std::string initiator_encode_key() const override {
+ return SessionKeys::responder_encode_key();
+ }
+ std::string responder_encode_key() const override {
+ return SessionKeys::initiator_encode_key();
+ }
+};
+
} // namespace
class ProximityAuthDeviceToDeviceSecureContextTest : public testing::Test {
protected:
ProximityAuthDeviceToDeviceSecureContextTest()
- : secure_context_(
- base::MakeUnique<FakeSecureMessageDelegate>(),
- kSymmetricKey,
- kResponderAuthMessage,
- kProtocolVersion) {}
+ : secure_context_(base::MakeUnique<FakeSecureMessageDelegate>(),
+ SessionKeys(kSymmetricKey),
+ kResponderAuthMessage,
+ kProtocolVersion) {}
DeviceToDeviceSecureContext secure_context_;
};
@@ -74,11 +93,18 @@ TEST_F(ProximityAuthDeviceToDeviceSecureContextTest, DecodeInvalidMessage) {
TEST_F(ProximityAuthDeviceToDeviceSecureContextTest, EncodeAndDecode) {
// Initialize second secure channel with the same parameters as the first.
+ InvertedSessionKeys inverted_session_keys(kSymmetricKey);
DeviceToDeviceSecureContext secure_context2(
- base::MakeUnique<FakeSecureMessageDelegate>(), kSymmetricKey,
+ base::MakeUnique<FakeSecureMessageDelegate>(), inverted_session_keys,
kResponderAuthMessage, kProtocolVersion);
std::string message = "encrypt this message";
+ SessionKeys session_keys(kSymmetricKey);
+ EXPECT_EQ(session_keys.initiator_encode_key(),
+ inverted_session_keys.responder_encode_key());
+ EXPECT_EQ(session_keys.responder_encode_key(),
+ inverted_session_keys.initiator_encode_key());
+
// Pass some messages between the two secure contexts.
for (int i = 0; i < 3; ++i) {
std::string encoded_message;
@@ -96,8 +122,9 @@ TEST_F(ProximityAuthDeviceToDeviceSecureContextTest,
DecodeInvalidSequenceNumber) {
// Initialize second secure channel with the same parameters as the first.
DeviceToDeviceSecureContext secure_context2(
- base::MakeUnique<FakeSecureMessageDelegate>(), kSymmetricKey,
- kResponderAuthMessage, kProtocolVersion);
+ base::MakeUnique<FakeSecureMessageDelegate>(),
+ InvertedSessionKeys(kSymmetricKey), kResponderAuthMessage,
+ kProtocolVersion);
// Send a few messages over the first secure context.
std::string message = "encrypt this message";
diff --git a/chromium/components/cryptauth/eid_generator.cc b/chromium/components/cryptauth/foreground_eid_generator.cc
index ecbada9c545..01e269e717c 100644
--- a/chromium/components/cryptauth/eid_generator.cc
+++ b/chromium/components/cryptauth/foreground_eid_generator.cc
@@ -2,19 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/cryptauth/eid_generator.h"
+#include "components/cryptauth/foreground_eid_generator.h"
#include <cstring>
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
-#include "base/sys_byteorder.h"
#include "base/time/default_clock.h"
#include "base/time/time.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h"
+#include "components/cryptauth/raw_eid_generator.h"
+#include "components/cryptauth/raw_eid_generator_impl.h"
#include "components/cryptauth/remote_device.h"
#include "components/proximity_auth/logging/logging.h"
-#include "crypto/sha2.h"
namespace cryptauth {
@@ -23,45 +23,21 @@ const int64_t kNoTimestamp = 0;
const int64_t kMaxPositiveInt64TValue = 0x7FFFFFFF;
} // namespace
-const int64_t EidGenerator::kNumMsInEidPeriod =
+const int64_t ForegroundEidGenerator::kNumMsInEidPeriod =
base::TimeDelta::FromHours(8).InMilliseconds();
-const int64_t EidGenerator::kNumMsInBeginningOfEidPeriod =
+const int64_t ForegroundEidGenerator::kNumMsInBeginningOfEidPeriod =
base::TimeDelta::FromHours(2).InMilliseconds();
-const int32_t EidGenerator::kNumBytesInEidValue = 2;
-const int8_t EidGenerator::kBluetooth4Flag = 0x01;
+const int8_t ForegroundEidGenerator::kBluetooth4Flag = 0x01;
-// static
-EidGenerator* EidGenerator::GetInstance() {
- return base::Singleton<EidGenerator>::get();
-}
-
-std::string EidGenerator::EidComputationHelperImpl::GenerateEidDataForDevice(
- const std::string& eid_seed,
- const int64_t start_of_period_timestamp_ms,
- const std::string* extra_entropy) {
- // The data to hash is the eid seed, followed by the extra entropy (if it
- // exists), followed by the timestamp.
- std::string to_hash = eid_seed;
- if (extra_entropy) {
- to_hash += *extra_entropy;
- }
- uint64_t timestamp_data =
- base::HostToNet64(static_cast<uint64_t>(start_of_period_timestamp_ms));
- to_hash.append(reinterpret_cast<char*>(&timestamp_data), sizeof(uint64_t));
-
- std::string result = crypto::SHA256HashString(to_hash);
- result.resize(EidGenerator::kNumBytesInEidValue);
- return result;
-}
-
-EidGenerator::EidData::EidData(const DataWithTimestamp current_data,
- std::unique_ptr<DataWithTimestamp> adjacent_data)
+ForegroundEidGenerator::EidData::EidData(
+ const DataWithTimestamp current_data,
+ std::unique_ptr<DataWithTimestamp> adjacent_data)
: current_data(current_data), adjacent_data(std::move(adjacent_data)) {}
-EidGenerator::EidData::~EidData() {}
+ForegroundEidGenerator::EidData::~EidData() {}
-EidGenerator::EidData::AdjacentDataType
-EidGenerator::EidData::GetAdjacentDataType() const {
+ForegroundEidGenerator::EidData::AdjacentDataType
+ForegroundEidGenerator::EidData::GetAdjacentDataType() const {
if (!adjacent_data) {
return AdjacentDataType::NONE;
}
@@ -73,7 +49,7 @@ EidGenerator::EidData::GetAdjacentDataType() const {
return AdjacentDataType::FUTURE;
}
-std::string EidGenerator::EidData::DataInHex() const {
+std::string ForegroundEidGenerator::EidData::DataInHex() const {
std::string str = "[" + current_data.DataInHex();
if (adjacent_data) {
@@ -83,56 +59,20 @@ std::string EidGenerator::EidData::DataInHex() const {
return str + "]";
}
-EidGenerator::DataWithTimestamp::DataWithTimestamp(
- const std::string& data,
- const int64_t start_timestamp_ms,
- const int64_t end_timestamp_ms)
- : data(data),
- start_timestamp_ms(start_timestamp_ms),
- end_timestamp_ms(end_timestamp_ms) {
- DCHECK(start_timestamp_ms < end_timestamp_ms);
- DCHECK(data.size());
-}
-
-EidGenerator::DataWithTimestamp::DataWithTimestamp(
- const DataWithTimestamp& other)
- : data(other.data),
- start_timestamp_ms(other.start_timestamp_ms),
- end_timestamp_ms(other.end_timestamp_ms) {
- DCHECK(start_timestamp_ms < end_timestamp_ms);
- DCHECK(data.size());
-}
-
-bool EidGenerator::DataWithTimestamp::ContainsTime(
- const int64_t timestamp_ms) const {
- return start_timestamp_ms <= timestamp_ms && timestamp_ms < end_timestamp_ms;
-}
-
-std::string EidGenerator::DataWithTimestamp::DataInHex() const {
- std::stringstream ss;
- ss << "0x" << std::hex;
-
- for (size_t i = 0; i < data.size(); i++) {
- ss << static_cast<int>(data.data()[i]);
- }
-
- return ss.str();
-}
-
-EidGenerator::EidGenerator()
- : EidGenerator(base::WrapUnique(new EidComputationHelperImpl()),
- base::WrapUnique(new base::DefaultClock())) {}
+ForegroundEidGenerator::ForegroundEidGenerator()
+ : ForegroundEidGenerator(base::MakeUnique<RawEidGeneratorImpl>(),
+ base::MakeUnique<base::DefaultClock>()) {}
-EidGenerator::EidGenerator(
- std::unique_ptr<EidComputationHelper> computation_helper,
+ForegroundEidGenerator::ForegroundEidGenerator(
+ std::unique_ptr<RawEidGenerator> raw_eid_generator,
std::unique_ptr<base::Clock> clock)
: clock_(std::move(clock)),
- eid_computation_helper_(std::move(computation_helper)) {}
+ raw_eid_generator_(std::move(raw_eid_generator)) {}
-EidGenerator::~EidGenerator() {}
+ForegroundEidGenerator::~ForegroundEidGenerator() {}
-std::unique_ptr<EidGenerator::EidData>
-EidGenerator::GenerateBackgroundScanFilter(
+std::unique_ptr<ForegroundEidGenerator::EidData>
+ForegroundEidGenerator::GenerateBackgroundScanFilter(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
std::unique_ptr<EidPeriodTimestamps> timestamps =
GetEidPeriodTimestamps(scanning_device_beacon_seeds);
@@ -159,8 +99,8 @@ EidGenerator::GenerateBackgroundScanFilter(
return base::WrapUnique(new EidData(*current_eid, std::move(adjacent_eid)));
}
-std::unique_ptr<EidGenerator::DataWithTimestamp>
-EidGenerator::GenerateAdvertisement(
+std::unique_ptr<DataWithTimestamp>
+ForegroundEidGenerator::GenerateAdvertisement(
const std::string& advertising_device_public_key,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
std::unique_ptr<EidPeriodTimestamps> timestamps =
@@ -175,7 +115,7 @@ EidGenerator::GenerateAdvertisement(
timestamps->current_period_end_timestamp_ms);
}
-RemoteDevice const* EidGenerator::IdentifyRemoteDeviceByAdvertisement(
+RemoteDevice const* ForegroundEidGenerator::IdentifyRemoteDeviceByAdvertisement(
const std::string& advertisement_service_data,
const std::vector<RemoteDevice>& device_list,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
@@ -183,7 +123,7 @@ RemoteDevice const* EidGenerator::IdentifyRemoteDeviceByAdvertisement(
// bytes. The bytes following these are flags, so they are not needed to
// identify the device which sent a message.
std::string service_data_without_flags = advertisement_service_data;
- service_data_without_flags.resize(2 * kNumBytesInEidValue);
+ service_data_without_flags.resize(2 * RawEidGenerator::kNumBytesInEidValue);
for (const auto& remote_device : device_list) {
std::vector<std::string> possible_advertisements =
@@ -199,7 +139,7 @@ RemoteDevice const* EidGenerator::IdentifyRemoteDeviceByAdvertisement(
return nullptr;
}
-std::vector<std::string> EidGenerator::GeneratePossibleAdvertisements(
+std::vector<std::string> ForegroundEidGenerator::GeneratePossibleAdvertisements(
const std::string& advertising_device_public_key,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
std::vector<std::string> possible_advertisements;
@@ -235,8 +175,8 @@ std::vector<std::string> EidGenerator::GeneratePossibleAdvertisements(
return possible_advertisements;
}
-std::unique_ptr<EidGenerator::DataWithTimestamp>
-EidGenerator::GenerateAdvertisement(
+std::unique_ptr<DataWithTimestamp>
+ForegroundEidGenerator::GenerateAdvertisement(
const std::string& advertising_device_public_key,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const int64_t start_of_period_timestamp_ms,
@@ -261,8 +201,8 @@ EidGenerator::GenerateAdvertisement(
end_of_period_timestamp_ms));
}
-std::unique_ptr<EidGenerator::DataWithTimestamp>
-EidGenerator::GenerateEidDataWithTimestamp(
+std::unique_ptr<DataWithTimestamp>
+ForegroundEidGenerator::GenerateEidDataWithTimestamp(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const int64_t start_of_period_timestamp_ms,
const int64_t end_of_period_timestamp_ms) const {
@@ -271,26 +211,26 @@ EidGenerator::GenerateEidDataWithTimestamp(
end_of_period_timestamp_ms, nullptr);
}
-std::unique_ptr<EidGenerator::DataWithTimestamp>
-EidGenerator::GenerateEidDataWithTimestamp(
+std::unique_ptr<DataWithTimestamp>
+ForegroundEidGenerator::GenerateEidDataWithTimestamp(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const int64_t start_of_period_timestamp_ms,
const int64_t end_of_period_timestamp_ms,
- const std::string* extra_entropy) const {
+ std::string const* extra_entropy) const {
std::unique_ptr<std::string> eid_seed = GetEidSeedForPeriod(
scanning_device_beacon_seeds, start_of_period_timestamp_ms);
if (!eid_seed) {
return nullptr;
}
- std::string eid_data = eid_computation_helper_->GenerateEidDataForDevice(
+ std::string eid_data = raw_eid_generator_->GenerateEid(
*eid_seed, start_of_period_timestamp_ms, extra_entropy);
return base::WrapUnique(new DataWithTimestamp(
eid_data, start_of_period_timestamp_ms, end_of_period_timestamp_ms));
}
-std::unique_ptr<std::string> EidGenerator::GetEidSeedForPeriod(
+std::unique_ptr<std::string> ForegroundEidGenerator::GetEidSeedForPeriod(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const int64_t start_of_period_timestamp_ms) const {
for (auto seed : scanning_device_beacon_seeds) {
@@ -303,14 +243,14 @@ std::unique_ptr<std::string> EidGenerator::GetEidSeedForPeriod(
return nullptr;
}
-std::unique_ptr<EidGenerator::EidPeriodTimestamps>
-EidGenerator::GetEidPeriodTimestamps(
+std::unique_ptr<ForegroundEidGenerator::EidPeriodTimestamps>
+ForegroundEidGenerator::GetEidPeriodTimestamps(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
return GetEidPeriodTimestamps(scanning_device_beacon_seeds, false);
}
-std::unique_ptr<EidGenerator::EidPeriodTimestamps>
-EidGenerator::GetEidPeriodTimestamps(
+std::unique_ptr<ForegroundEidGenerator::EidPeriodTimestamps>
+ForegroundEidGenerator::GetEidPeriodTimestamps(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const bool allow_non_current_periods) const {
base::Time now = clock_->Now();
@@ -365,7 +305,8 @@ EidGenerator::GetEidPeriodTimestamps(
return nullptr;
}
-std::unique_ptr<BeaconSeed> EidGenerator::GetBeaconSeedForCurrentPeriod(
+std::unique_ptr<BeaconSeed>
+ForegroundEidGenerator::GetBeaconSeedForCurrentPeriod(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const int64_t current_time_ms) const {
for (auto seed : scanning_device_beacon_seeds) {
@@ -386,8 +327,8 @@ std::unique_ptr<BeaconSeed> EidGenerator::GetBeaconSeedForCurrentPeriod(
return nullptr;
}
-std::unique_ptr<EidGenerator::EidPeriodTimestamps>
-EidGenerator::GetClosestPeriod(
+std::unique_ptr<ForegroundEidGenerator::EidPeriodTimestamps>
+ForegroundEidGenerator::GetClosestPeriod(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const int64_t current_time_ms) const {
int64_t smallest_diff_so_far_ms = kMaxPositiveInt64TValue;
@@ -436,7 +377,7 @@ EidGenerator::GetClosestPeriod(
start_of_period_timestamp_ms, end_of_period_timestamp_ms});
}
-bool EidGenerator::IsCurrentTimeAtStartOfEidPeriod(
+bool ForegroundEidGenerator::IsCurrentTimeAtStartOfEidPeriod(
const int64_t start_of_period_timestamp_ms,
const int64_t end_of_period_timestamp_ms,
const int64_t current_timestamp_ms) {
diff --git a/chromium/components/cryptauth/eid_generator.h b/chromium/components/cryptauth/foreground_eid_generator.h
index 3fd706186f4..ec68de89920 100644
--- a/chromium/components/cryptauth/eid_generator.h
+++ b/chromium/components/cryptauth/foreground_eid_generator.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_CRYPTAUTH_BLE_EID_GENERATOR_H_
-#define COMPONENTS_CRYPTAUTH_BLE_EID_GENERATOR_H_
+#ifndef COMPONENTS_CRYPTAUTH_BLE_FOREGROUND_EID_GENERATOR_H_
+#define COMPONENTS_CRYPTAUTH_BLE_FOREGROUND_EID_GENERATOR_H_
#include <memory>
#include <string>
@@ -11,15 +11,24 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/memory/singleton.h"
#include "base/time/clock.h"
+#include "components/cryptauth/data_with_timestamp.h"
namespace cryptauth {
class BeaconSeed;
+class RawEidGenerator;
struct RemoteDevice;
-// Generates ephemeral ID (EID) values for BLE communication in ProximityAuth.
+// Generates ephemeral ID (EID) values that are broadcast for foreground BLE
+// advertisements in the ProximityAuth protocol.
+//
+// When advertising in foreground mode, we don't care about battery consumption
+// while advertising. We assume, however, that the scanning side is
+// battery-conscious, and is using hardware-based scanning.
+//
+// For the inverse of this model, in which advertising is battery-sensitive, see
+// BackgroundEidGenerator.
//
// A peripheral-role device advertises a 4-byte advertisement with two parts: a
// 2-byte EID which is specific to the central-role device with which it intends
@@ -30,24 +39,8 @@ struct RemoteDevice;
// EIDs.
//
// See go/proximity-auth-ble-advertising.
-class EidGenerator {
+class ForegroundEidGenerator {
public:
- // Stores EID-related data and timestamps at which time this data becomes
- // active or inactive.
- struct DataWithTimestamp {
- DataWithTimestamp(const std::string& data,
- const int64_t start_timestamp_ms,
- const int64_t end_timestamp_ms);
- DataWithTimestamp(const DataWithTimestamp& other);
-
- bool ContainsTime(const int64_t timestamp_ms) const;
- std::string DataInHex() const;
-
- const std::string data;
- const int64_t start_timestamp_ms;
- const int64_t end_timestamp_ms;
- };
-
// Data for both a current and adjacent EID. The current EID *must* be
// supplied, but adjacent data may be null. Each EID consists of a 2-byte EID
// value paired with the timestamp at which time this value becomes active or
@@ -72,8 +65,8 @@ class EidGenerator {
// recipient should advertise back instead of initializing a connection.
static const int8_t kBluetooth4Flag;
- static EidGenerator* GetInstance();
- virtual ~EidGenerator();
+ ForegroundEidGenerator();
+ virtual ~ForegroundEidGenerator();
// Generates EID data for the given EID seeds to be used as a background scan
// filter. In the normal case, two DataWithTimestamp values are returned, one
@@ -103,12 +96,7 @@ class EidGenerator {
const std::vector<RemoteDevice>& device_list,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const;
- protected:
- EidGenerator();
-
private:
- friend struct base::DefaultSingletonTraits<EidGenerator>;
-
struct EidPeriodTimestamps {
int64_t current_period_start_timestamp_ms;
int64_t current_period_end_timestamp_ms;
@@ -116,28 +104,11 @@ class EidGenerator {
int64_t adjacent_period_end_timestamp_ms;
};
- class EidComputationHelper {
- public:
- virtual std::string GenerateEidDataForDevice(
- const std::string& eid_seed,
- const int64_t start_of_period_timestamp_ms,
- const std::string* extra_entropy) = 0;
- };
-
- class EidComputationHelperImpl : public EidComputationHelper {
- public:
- std::string GenerateEidDataForDevice(
- const std::string& eid_seed,
- const int64_t start_of_period_timestamp_ms,
- const std::string* extra_entropy) override;
- };
-
static const int64_t kNumMsInEidPeriod;
static const int64_t kNumMsInBeginningOfEidPeriod;
- static const int32_t kNumBytesInEidValue;
- EidGenerator(std::unique_ptr<EidComputationHelper> computation_helper,
- std::unique_ptr<base::Clock> clock);
+ ForegroundEidGenerator(std::unique_ptr<RawEidGenerator> raw_eid_generator,
+ std::unique_ptr<base::Clock> clock);
std::unique_ptr<DataWithTimestamp> GenerateAdvertisement(
const std::string& advertising_device_public_key,
@@ -154,7 +125,7 @@ class EidGenerator {
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
const int64_t start_of_period_timestamp_ms,
const int64_t end_of_period_timestamp_ms,
- const std::string* extra_entropy) const;
+ std::string const* extra_entropy) const;
std::unique_ptr<std::string> GetEidSeedForPeriod(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds,
@@ -182,55 +153,36 @@ class EidGenerator {
std::unique_ptr<base::Clock> clock_;
- std::unique_ptr<EidComputationHelper> eid_computation_helper_;
+ std::unique_ptr<RawEidGenerator> raw_eid_generator_;
- DISALLOW_COPY_AND_ASSIGN(EidGenerator);
+ DISALLOW_COPY_AND_ASSIGN(ForegroundEidGenerator);
- friend class CryptAuthEidGeneratorTest;
- FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_UsingRealEidComputationHelper);
+ friend class CryptAuthForegroundEidGeneratorTest;
+ FRIEND_TEST_ALL_PREFIXES(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_UsingRealEids);
FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_CurrentAndPastAdjacentPeriods);
+ CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_CurrentAndPastAdjacentPeriods);
FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
+ CryptAuthForegroundEidGeneratorTest,
testGeneratePossibleAdvertisements_CurrentAndFutureAdjacentPeriods);
+ FRIEND_TEST_ALL_PREFIXES(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_OnlyCurrentPeriod);
+ FRIEND_TEST_ALL_PREFIXES(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_OnlyFuturePeriod);
FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_OnlyCurrentPeriod);
- FRIEND_TEST_ALL_PREFIXES(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_OnlyFuturePeriod);
- FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInFuture);
- FRIEND_TEST_ALL_PREFIXES(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_OnlyPastPeriod);
- FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInPast);
+ CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInFuture);
+ FRIEND_TEST_ALL_PREFIXES(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_OnlyPastPeriod);
FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_NoAdvertisements_EmptySeeds);
- FRIEND_TEST_ALL_PREFIXES(CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ProducesTwoByteValue);
- FRIEND_TEST_ALL_PREFIXES(CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_Deterministic);
+ CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInPast);
FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ChangingSeedChangesOutput);
- FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ChangingTimestampChangesOutput);
- FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ChangingExtraEntropyChangesOutput);
- FRIEND_TEST_ALL_PREFIXES(
- CryptAuthEidGeneratorTest,
- TestEidComputationHelper_ChangingTimestampWithLongExtraEntropy);
- FRIEND_TEST_ALL_PREFIXES(CryptAuthEidGeneratorTest,
- TestEidComputationHelper_EnsureTestVectorsPass);
+ CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_NoAdvertisements_EmptySeeds);
};
-}
-#endif // COMPONENTS_CRYPTAUTH_BLE_EID_GENERATOR_H_
+} // cryptauth
+
+#endif // COMPONENTS_CRYPTAUTH_BLE_FOREGROUND_EID_GENERATOR_H_
diff --git a/chromium/components/cryptauth/eid_generator_unittest.cc b/chromium/components/cryptauth/foreground_eid_generator_unittest.cc
index a0e35593b9b..97e90179685 100644
--- a/chromium/components/cryptauth/eid_generator_unittest.cc
+++ b/chromium/components/cryptauth/foreground_eid_generator_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/cryptauth/eid_generator.h"
+#include "components/cryptauth/foreground_eid_generator.h"
#include <memory>
@@ -12,6 +12,7 @@
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h"
+#include "components/cryptauth/raw_eid_generator_impl.h"
#include "components/cryptauth/remote_device.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -89,17 +90,16 @@ static std::string GenerateFakeAdvertisement(
return fake_advertisement;
}
-static RemoteDevice CreateRemoteDevice(
- const std::string& public_key) {
+static RemoteDevice CreateRemoteDevice(const std::string& public_key) {
RemoteDevice remote_device;
remote_device.public_key = public_key;
return remote_device;
}
} // namespace
-class CryptAuthEidGeneratorTest : public testing::Test {
+class CryptAuthForegroundEidGeneratorTest : public testing::Test {
protected:
- CryptAuthEidGeneratorTest() {
+ CryptAuthForegroundEidGeneratorTest() {
scanning_device_beacon_seeds_.push_back(CreateBeaconSeed(
kFirstSeed, kDefaultCurrentPeriodStart - kNumMsInEidSeedPeriod,
kDefaultCurrentPeriodStart));
@@ -114,14 +114,15 @@ class CryptAuthEidGeneratorTest : public testing::Test {
kDefaultCurrentPeriodStart + 3 * kNumMsInEidSeedPeriod));
}
- class TestEidComputationHelper : public EidGenerator::EidComputationHelper {
+ class TestRawEidGenerator : public RawEidGenerator {
public:
- TestEidComputationHelper() {}
+ TestRawEidGenerator() {}
+ ~TestRawEidGenerator() override {}
- std::string GenerateEidDataForDevice(
- const std::string& eid_seed,
- const int64_t start_of_period_timestamp_ms,
- const std::string* extra_entropy) override {
+ // RawEidGenerator:
+ std::string GenerateEid(const std::string& eid_seed,
+ int64_t start_of_period_timestamp_ms,
+ std::string const* extra_entropy) override {
return GenerateFakeEidData(eid_seed, start_of_period_timestamp_ms,
extra_entropy);
}
@@ -129,15 +130,12 @@ class CryptAuthEidGeneratorTest : public testing::Test {
void SetUp() override {
test_clock_ = new base::SimpleTestClock();
- test_computation_helper_ = new TestEidComputationHelper();
- real_computation_helper_.reset(
- new EidGenerator::EidComputationHelperImpl());
SetTestTime(kDefaultCurrentTime);
eid_generator_.reset(
- new EidGenerator(base::WrapUnique(test_computation_helper_),
- base::WrapUnique(test_clock_)));
+ new ForegroundEidGenerator(base::MakeUnique<TestRawEidGenerator>(),
+ base::WrapUnique(test_clock_)));
}
// TODO(khorimoto): Is there an easier way to do this?
@@ -147,23 +145,21 @@ class CryptAuthEidGeneratorTest : public testing::Test {
test_clock_->SetNow(time);
}
- std::unique_ptr<EidGenerator> eid_generator_;
+ std::unique_ptr<ForegroundEidGenerator> eid_generator_;
base::SimpleTestClock* test_clock_;
- TestEidComputationHelper* test_computation_helper_;
- std::unique_ptr<EidGenerator::EidComputationHelper> real_computation_helper_;
std::vector<BeaconSeed> scanning_device_beacon_seeds_;
};
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_StartOfPeriod_AnotherSeedInPreviousPeriod) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_StartOfPeriod_AnotherSeedInPreviousPeriod) {
SetTestTime(kDefaultCurrentTime);
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(
scanning_device_beacon_seeds_);
ASSERT_TRUE(data);
EXPECT_EQ(data->GetAdjacentDataType(),
- EidGenerator::EidData::AdjacentDataType::PAST);
+ ForegroundEidGenerator::EidData::AdjacentDataType::PAST);
EXPECT_EQ(kDefaultCurrentPeriodStart, data->current_data.start_timestamp_ms);
EXPECT_EQ(kDefaultCurrentPeriodStart + kNumMsInEidPeriod,
@@ -182,16 +178,16 @@ TEST_F(CryptAuthEidGeneratorTest,
data->adjacent_data->data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_StartOfPeriod_NoSeedBefore) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_StartOfPeriod_NoSeedBefore) {
SetTestTime(kDefaultCurrentTime - kNumMsInEidSeedPeriod);
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(
scanning_device_beacon_seeds_);
ASSERT_TRUE(data);
EXPECT_EQ(data->GetAdjacentDataType(),
- EidGenerator::EidData::AdjacentDataType::NONE);
+ ForegroundEidGenerator::EidData::AdjacentDataType::NONE);
EXPECT_EQ(kDefaultCurrentPeriodStart - kNumMsInEidSeedPeriod,
data->current_data.start_timestamp_ms);
@@ -206,17 +202,17 @@ TEST_F(CryptAuthEidGeneratorTest,
EXPECT_FALSE(data->adjacent_data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_PastStartOfPeriod) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_PastStartOfPeriod) {
SetTestTime(kDefaultCurrentTime +
base::TimeDelta::FromHours(3).InMilliseconds());
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(
scanning_device_beacon_seeds_);
ASSERT_TRUE(data);
EXPECT_EQ(data->GetAdjacentDataType(),
- EidGenerator::EidData::AdjacentDataType::FUTURE);
+ ForegroundEidGenerator::EidData::AdjacentDataType::FUTURE);
EXPECT_EQ(kDefaultCurrentPeriodStart, data->current_data.start_timestamp_ms);
EXPECT_EQ(kDefaultCurrentPeriodStart + kNumMsInEidPeriod,
@@ -236,15 +232,16 @@ TEST_F(CryptAuthEidGeneratorTest,
data->adjacent_data->data);
}
-TEST_F(CryptAuthEidGeneratorTest, TestGenerateEidDataForDevice_EndOfPeriod) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_EndOfPeriod) {
SetTestTime(kDefaultCurrentPeriodStart + kNumMsInEidSeedPeriod - 1);
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(
scanning_device_beacon_seeds_);
ASSERT_TRUE(data);
EXPECT_EQ(data->GetAdjacentDataType(),
- EidGenerator::EidData::AdjacentDataType::FUTURE);
+ ForegroundEidGenerator::EidData::AdjacentDataType::FUTURE);
EXPECT_EQ(
kDefaultCurrentPeriodStart + kNumMsInEidSeedPeriod - kNumMsInEidPeriod,
@@ -269,82 +266,84 @@ TEST_F(CryptAuthEidGeneratorTest, TestGenerateEidDataForDevice_EndOfPeriod) {
data->adjacent_data->data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_EndOfPeriod_NoSeedAfter) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_EndOfPeriod_NoSeedAfter) {
SetTestTime(kDefaultCurrentPeriodStart + 3 * kNumMsInEidSeedPeriod - 1);
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(
scanning_device_beacon_seeds_);
ASSERT_TRUE(data);
EXPECT_EQ(data->GetAdjacentDataType(),
- EidGenerator::EidData::AdjacentDataType::NONE);
+ ForegroundEidGenerator::EidData::AdjacentDataType::NONE);
EXPECT_EQ(kDefaultCurrentPeriodStart + 3 * kNumMsInEidSeedPeriod -
kNumMsInEidPeriod,
data->current_data.start_timestamp_ms);
EXPECT_EQ(kDefaultCurrentPeriodStart + 3 * kNumMsInEidSeedPeriod,
data->current_data.end_timestamp_ms);
- EXPECT_EQ(GenerateFakeEidData(kFourthSeed, kDefaultCurrentPeriodStart +
- 3 * kNumMsInEidSeedPeriod -
- kNumMsInEidPeriod,
- nullptr),
- data->current_data.data);
+ EXPECT_EQ(
+ GenerateFakeEidData(kFourthSeed,
+ kDefaultCurrentPeriodStart +
+ 3 * kNumMsInEidSeedPeriod - kNumMsInEidPeriod,
+ nullptr),
+ data->current_data.data);
EXPECT_FALSE(data->adjacent_data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_NoCurrentPeriodSeed) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_NoCurrentPeriodSeed) {
SetTestTime(kDefaultCurrentPeriodStart + 4 * kNumMsInEidSeedPeriod - 1);
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(
scanning_device_beacon_seeds_);
EXPECT_FALSE(data);
}
-TEST_F(CryptAuthEidGeneratorTest, testGenerateEidDataForDevice_EmptySeeds) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_EmptySeeds) {
SetTestTime(kDefaultCurrentTime);
std::vector<BeaconSeed> empty;
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(empty);
EXPECT_FALSE(data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_InvalidSeed_PeriodNotMultipleOf8Hours) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_InvalidSeed_PeriodNotMultipleOf8Hours) {
SetTestTime(kDefaultCurrentTime);
// Seed has a period of 1ms, but it should have a period of 8 hours.
std::vector<BeaconSeed> invalid_seed_vector = {CreateBeaconSeed(
kFirstSeed, kDefaultCurrentPeriodStart, kDefaultCurrentPeriodStart + 1)};
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(invalid_seed_vector);
EXPECT_FALSE(data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateEidDataForDevice_UsingRealEidComputationHelper) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateBackgroundScanFilter_UsingRealEids) {
test_clock_ = new base::SimpleTestClock();
SetTestTime(kDefaultCurrentTime);
- // Use real EidComputationHelper implementation instead of test version.
- eid_generator_.reset(new EidGenerator(std::move(real_computation_helper_),
- base::WrapUnique(test_clock_)));
+ // Use real RawEidGenerator implementation instead of test version.
+ eid_generator_.reset(new ForegroundEidGenerator(
+ base::MakeUnique<RawEidGeneratorImpl>(), base::WrapUnique(test_clock_)));
- std::unique_ptr<EidGenerator::EidData> data =
+ std::unique_ptr<ForegroundEidGenerator::EidData> data =
eid_generator_->GenerateBackgroundScanFilter(
scanning_device_beacon_seeds_);
ASSERT_TRUE(data);
EXPECT_EQ(data->GetAdjacentDataType(),
- EidGenerator::EidData::AdjacentDataType::PAST);
+ ForegroundEidGenerator::EidData::AdjacentDataType::PAST);
EXPECT_EQ(kDefaultCurrentPeriodStart, data->current_data.start_timestamp_ms);
EXPECT_EQ(kDefaultCurrentPeriodStart + kNumMsInEidPeriod,
data->current_data.end_timestamp_ms);
- // Since this uses the real EidComputationHelper, just make sure the data
+ // Since this uses the real RawEidGenerator, just make sure the data
// exists and has the proper length.
EXPECT_EQ((size_t)kNumBytesInEidValue, data->current_data.data.length());
@@ -352,15 +351,15 @@ TEST_F(CryptAuthEidGeneratorTest,
EXPECT_EQ(kDefaultCurrentPeriodStart - kNumMsInEidPeriod,
data->adjacent_data->start_timestamp_ms);
EXPECT_EQ(kDefaultCurrentPeriodStart, data->adjacent_data->end_timestamp_ms);
- // Since this uses the real EidComputationHelper, just make sure the data
+ // Since this uses the real RawEidGenerator, just make sure the data
// exists and has the proper length.
EXPECT_EQ((size_t)kNumBytesInEidValue, data->adjacent_data->data.length());
}
-TEST_F(CryptAuthEidGeneratorTest, TestGenerateAdvertisementData) {
+TEST_F(CryptAuthForegroundEidGeneratorTest, GenerateAdvertisementData) {
SetTestTime(kDefaultCurrentTime);
- std::unique_ptr<EidGenerator::DataWithTimestamp> data =
+ std::unique_ptr<DataWithTimestamp> data =
eid_generator_->GenerateAdvertisement(kDefaultAdvertisingDevicePublicKey,
scanning_device_beacon_seeds_);
ASSERT_TRUE(data);
@@ -373,28 +372,29 @@ TEST_F(CryptAuthEidGeneratorTest, TestGenerateAdvertisementData) {
data->data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGenerateAdvertisementData_NoSeedForPeriod) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateAdvertisementData_NoSeedForPeriod) {
SetTestTime(kDefaultCurrentTime + 4 * kNumMsInEidSeedPeriod);
- std::unique_ptr<EidGenerator::DataWithTimestamp> data =
+ std::unique_ptr<DataWithTimestamp> data =
eid_generator_->GenerateAdvertisement(kDefaultAdvertisingDevicePublicKey,
scanning_device_beacon_seeds_);
EXPECT_FALSE(data);
}
-TEST_F(CryptAuthEidGeneratorTest, TestGenerateAdvertisementData_EmptySeeds) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GenerateAdvertisementData_EmptySeeds) {
SetTestTime(kDefaultCurrentTime + 4 * kNumMsInEidSeedPeriod);
std::vector<BeaconSeed> empty;
- std::unique_ptr<EidGenerator::DataWithTimestamp> data =
+ std::unique_ptr<DataWithTimestamp> data =
eid_generator_->GenerateAdvertisement(kDefaultAdvertisingDevicePublicKey,
empty);
EXPECT_FALSE(data);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_CurrentAndPastAdjacentPeriods) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_CurrentAndPastAdjacentPeriods) {
SetTestTime(kDefaultCurrentPeriodStart);
std::vector<std::string> possible_advertisements =
@@ -411,7 +411,7 @@ TEST_F(CryptAuthEidGeneratorTest,
possible_advertisements[1]);
}
-TEST_F(CryptAuthEidGeneratorTest,
+TEST_F(CryptAuthForegroundEidGeneratorTest,
testGeneratePossibleAdvertisements_CurrentAndFutureAdjacentPeriods) {
SetTestTime(kDefaultCurrentPeriodStart +
base::TimeDelta::FromHours(3).InMilliseconds());
@@ -430,8 +430,8 @@ TEST_F(CryptAuthEidGeneratorTest,
possible_advertisements[1]);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_OnlyCurrentPeriod) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_OnlyCurrentPeriod) {
SetTestTime(kDefaultCurrentPeriodStart - kNumMsInEidSeedPeriod);
std::vector<std::string> possible_advertisements =
@@ -445,8 +445,8 @@ TEST_F(CryptAuthEidGeneratorTest,
possible_advertisements[0]);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_OnlyFuturePeriod) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_OnlyFuturePeriod) {
SetTestTime(kDefaultCurrentPeriodStart - kNumMsInEidSeedPeriod -
kNumMsInEidPeriod);
@@ -461,9 +461,8 @@ TEST_F(CryptAuthEidGeneratorTest,
possible_advertisements[0]);
}
-TEST_F(
- CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInFuture) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInFuture) {
SetTestTime(kDefaultCurrentPeriodStart - kNumMsInEidSeedPeriod -
kNumMsInEidPeriod - 1);
@@ -473,8 +472,8 @@ TEST_F(
EXPECT_TRUE(possible_advertisements.empty());
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_OnlyPastPeriod) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_OnlyPastPeriod) {
SetTestTime(kDefaultCurrentPeriodStart + 3 * kNumMsInEidSeedPeriod +
kNumMsInEidPeriod);
@@ -483,15 +482,16 @@ TEST_F(CryptAuthEidGeneratorTest,
kDefaultAdvertisingDevicePublicKey, scanning_device_beacon_seeds_);
EXPECT_EQ((size_t)1, possible_advertisements.size());
- EXPECT_EQ(GenerateFakeAdvertisement(
- kFourthSeed, kDefaultCurrentPeriodStart +
- 3 * kNumMsInEidSeedPeriod - kNumMsInEidPeriod,
- kDefaultAdvertisingDevicePublicKey),
+ EXPECT_EQ(GenerateFakeAdvertisement(kFourthSeed,
+ kDefaultCurrentPeriodStart +
+ 3 * kNumMsInEidSeedPeriod -
+ kNumMsInEidPeriod,
+ kDefaultAdvertisingDevicePublicKey),
possible_advertisements[0]);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInPast) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_NoAdvertisements_SeedsTooFarInPast) {
SetTestTime(kDefaultCurrentPeriodStart + 3 * kNumMsInEidSeedPeriod +
kNumMsInEidPeriod + 1);
@@ -501,8 +501,8 @@ TEST_F(CryptAuthEidGeneratorTest,
EXPECT_TRUE(possible_advertisements.empty());
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestGeneratePossibleAdvertisements_NoAdvertisements_EmptySeeds) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ GeneratePossibleAdvertisements_NoAdvertisements_EmptySeeds) {
SetTestTime(kDefaultCurrentPeriodStart);
std::vector<BeaconSeed> empty;
@@ -512,7 +512,7 @@ TEST_F(CryptAuthEidGeneratorTest,
EXPECT_TRUE(possible_advertisements.empty());
}
-TEST_F(CryptAuthEidGeneratorTest, TestIdentifyRemoteDevice_NoDevices) {
+TEST_F(CryptAuthForegroundEidGeneratorTest, IdentifyRemoteDevice_NoDevices) {
SetTestTime(kDefaultCurrentPeriodStart);
std::string service_data =
@@ -526,7 +526,8 @@ TEST_F(CryptAuthEidGeneratorTest, TestIdentifyRemoteDevice_NoDevices) {
EXPECT_FALSE(identified_device);
}
-TEST_F(CryptAuthEidGeneratorTest, TestIdentifyRemoteDevice_OneDevice_Success) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ IdentifyRemoteDevice_OneDevice_Success) {
SetTestTime(kDefaultCurrentPeriodStart);
std::string service_data =
@@ -542,8 +543,8 @@ TEST_F(CryptAuthEidGeneratorTest, TestIdentifyRemoteDevice_OneDevice_Success) {
EXPECT_EQ(correct_device.public_key, identified_device->public_key);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestIdentifyRemoteDevice_OneDevice_ServiceDataWithOneByteFlag_Success) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ IdentifyRemoteDevice_OneDevice_ServiceDataWithOneByteFlag_Success) {
SetTestTime(kDefaultCurrentPeriodStart);
std::string service_data =
@@ -552,7 +553,8 @@ TEST_F(CryptAuthEidGeneratorTest,
// Identifying device should still succeed if there is an extra "flag" byte
// after the first 4 bytes.
- service_data.append(1, static_cast<char>(EidGenerator::kBluetooth4Flag));
+ service_data.append(
+ 1, static_cast<char>(ForegroundEidGenerator::kBluetooth4Flag));
RemoteDevice correct_device =
CreateRemoteDevice(kDefaultAdvertisingDevicePublicKey);
@@ -563,8 +565,8 @@ TEST_F(CryptAuthEidGeneratorTest,
EXPECT_EQ(correct_device.public_key, identified_device->public_key);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestIdentifyRemoteDevice_OneDevice_ServiceDataWithLongerFlag_Success) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ IdentifyRemoteDevice_OneDevice_ServiceDataWithLongerFlag_Success) {
SetTestTime(kDefaultCurrentPeriodStart);
std::string service_data =
@@ -584,15 +586,15 @@ TEST_F(CryptAuthEidGeneratorTest,
EXPECT_EQ(correct_device.public_key, identified_device->public_key);
}
-TEST_F(CryptAuthEidGeneratorTest, TestIdentifyRemoteDevice_OneDevice_Failure) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ IdentifyRemoteDevice_OneDevice_Failure) {
SetTestTime(kDefaultCurrentPeriodStart);
std::string service_data =
GenerateFakeAdvertisement(kSecondSeed, kDefaultCurrentPeriodStart,
kDefaultAdvertisingDevicePublicKey);
- RemoteDevice wrong_device =
- CreateRemoteDevice("wrongPublicKey");
+ RemoteDevice wrong_device = CreateRemoteDevice("wrongPublicKey");
std::vector<RemoteDevice> device_list = {wrong_device};
const RemoteDevice* identified_device =
eid_generator_->IdentifyRemoteDeviceByAdvertisement(
@@ -600,8 +602,8 @@ TEST_F(CryptAuthEidGeneratorTest, TestIdentifyRemoteDevice_OneDevice_Failure) {
EXPECT_FALSE(identified_device);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestIdentifyRemoteDevice_MultipleDevices_Success) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ IdentifyRemoteDevice_MultipleDevices_Success) {
SetTestTime(kDefaultCurrentPeriodStart);
std::string service_data =
@@ -610,156 +612,33 @@ TEST_F(CryptAuthEidGeneratorTest,
RemoteDevice correct_device =
CreateRemoteDevice(kDefaultAdvertisingDevicePublicKey);
- RemoteDevice wrong_device =
- CreateRemoteDevice("wrongPublicKey");
- std::vector<RemoteDevice> device_list = {correct_device,
- wrong_device};
+ RemoteDevice wrong_device = CreateRemoteDevice("wrongPublicKey");
+ std::vector<RemoteDevice> device_list = {correct_device, wrong_device};
const RemoteDevice* identified_device =
eid_generator_->IdentifyRemoteDeviceByAdvertisement(
service_data, device_list, scanning_device_beacon_seeds_);
EXPECT_EQ(correct_device.public_key, identified_device->public_key);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestIdentifyRemoteDevice_MultipleDevices_Failure) {
+TEST_F(CryptAuthForegroundEidGeneratorTest,
+ IdentifyRemoteDevice_MultipleDevices_Failure) {
SetTestTime(kDefaultCurrentPeriodStart);
std::string service_data =
GenerateFakeAdvertisement(kSecondSeed, kDefaultCurrentPeriodStart,
kDefaultAdvertisingDevicePublicKey);
- RemoteDevice wrong_device =
- CreateRemoteDevice("wrongPublicKey");
- std::vector<RemoteDevice> device_list = {wrong_device,
- wrong_device};
+ RemoteDevice wrong_device = CreateRemoteDevice("wrongPublicKey");
+ std::vector<RemoteDevice> device_list = {wrong_device, wrong_device};
const RemoteDevice* identified_device =
eid_generator_->IdentifyRemoteDeviceByAdvertisement(
service_data, device_list, scanning_device_beacon_seeds_);
EXPECT_FALSE(identified_device);
}
-TEST_F(CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ProducesTwoByteValue) {
- EidGenerator::EidComputationHelperImpl helper;
- std::string eid = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart, nullptr);
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid.length());
-}
-
-TEST_F(CryptAuthEidGeneratorTest, TestEidComputationHelperImpl_Deterministic) {
- EidGenerator::EidComputationHelperImpl helper;
- std::string eid1 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart, nullptr);
- std::string eid2 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart, nullptr);
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
- EXPECT_EQ(eid1, eid2);
-}
-
-TEST_F(CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ChangingSeedChangesOutput) {
- EidGenerator::EidComputationHelperImpl helper;
- std::string eid1 = helper.GenerateEidDataForDevice(
- "eidSeed1", kDefaultCurrentPeriodStart, nullptr);
- std::string eid2 = helper.GenerateEidDataForDevice(
- "eidSeed2", kDefaultCurrentPeriodStart, nullptr);
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
- EXPECT_NE(eid1, eid2);
-}
-
-TEST_F(CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ChangingTimestampChangesOutput) {
- EidGenerator::EidComputationHelperImpl helper;
- std::string eid1 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart, nullptr);
- std::string eid2 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart + 1, nullptr);
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
- EXPECT_NE(eid1, eid2);
-}
-
-TEST_F(CryptAuthEidGeneratorTest,
- TestEidComputationHelperImpl_ChangingExtraEntropyChangesOutput) {
- EidGenerator::EidComputationHelperImpl helper;
- std::string eid1 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart, nullptr);
- std::string extra_entropy = "extraEntropy";
- std::string eid2 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart, &extra_entropy);
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
- EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
- EXPECT_NE(eid1, eid2);
-}
-
-TEST_F(CryptAuthEidGeneratorTest,
- TestEidComputationHelper_ChangingTimestampWithLongExtraEntropy) {
- EidGenerator::EidComputationHelperImpl helper;
- std::string long_extra_entropy =
- "reallyReallyReallyReallyReallyReallyReallyLongExtraEntropy";
- std::string eid1 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart, &long_extra_entropy);
- std::string extra_entropy = "extraEntropy";
- std::string eid2 = helper.GenerateEidDataForDevice(
- "eidSeed", kDefaultCurrentPeriodStart + 1, &long_extra_entropy);
- EXPECT_NE(eid1, eid2);
-}
-
-// Tests that "known test vectors" are correct. This ensures that the same test
-// vectors produce the same outputs on other platforms.
-TEST_F(CryptAuthEidGeneratorTest,
- TestEidComputationHelper_EnsureTestVectorsPass) {
- const int8_t test_eid_seed1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
- const int64_t test_timestamp1 = 2468101214L;
- const int8_t test_entropy1[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33};
-
- std::string test_eid_seed1_str(reinterpret_cast<const char*>(test_eid_seed1),
- sizeof(test_eid_seed1));
- std::string test_entropy1_str(reinterpret_cast<const char*>(test_entropy1),
- sizeof(test_entropy1));
-
- const int8_t test_eid_seed2[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34};
- const int64_t test_timestamp2 = 51015202530L;
- const int8_t test_entropy2[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35};
-
- std::string test_eid_seed2_str(reinterpret_cast<const char*>(test_eid_seed2),
- sizeof(test_eid_seed2));
- std::string test_entropy2_str(reinterpret_cast<const char*>(test_entropy2),
- sizeof(test_entropy2));
-
- EidGenerator::EidComputationHelperImpl helper;
-
- std::string test_eid_without_entropy1 = helper.GenerateEidDataForDevice(
- test_eid_seed1_str, test_timestamp1, nullptr);
- EXPECT_EQ("\x7d\x2c", test_eid_without_entropy1);
-
- std::string test_eid_with_entropy1 = helper.GenerateEidDataForDevice(
- test_eid_seed1_str, test_timestamp1, &test_entropy1_str);
- EXPECT_EQ("\xdc\xf3", test_eid_with_entropy1);
-
- std::string test_eid_without_entropy2 = helper.GenerateEidDataForDevice(
- test_eid_seed2_str, test_timestamp2, nullptr);
- EXPECT_EQ("\x02\xdd", test_eid_without_entropy2);
-
- std::string test_eid_with_entropy2 = helper.GenerateEidDataForDevice(
- test_eid_seed2_str, test_timestamp2, &test_entropy2_str);
- EXPECT_EQ("\xee\xcc", test_eid_with_entropy2);
-}
-
-TEST_F(CryptAuthEidGeneratorTest,
- TestDataWithTimestamp_ContainsTime) {
- EidGenerator::DataWithTimestamp data_with_timestamp(
- "data", /* start */ 1000L, /* end */ 2000L);
+TEST_F(CryptAuthForegroundEidGeneratorTest, DataWithTimestamp_ContainsTime) {
+ DataWithTimestamp data_with_timestamp("data", /* start */ 1000L,
+ /* end */ 2000L);
EXPECT_FALSE(data_with_timestamp.ContainsTime(999L));
EXPECT_TRUE(data_with_timestamp.ContainsTime(1000L));
EXPECT_TRUE(data_with_timestamp.ContainsTime(1500L));
diff --git a/chromium/components/cryptauth/mock_eid_generator.cc b/chromium/components/cryptauth/mock_foreground_eid_generator.cc
index c9515a74086..0dc949cd522 100644
--- a/chromium/components/cryptauth/mock_eid_generator.cc
+++ b/chromium/components/cryptauth/mock_foreground_eid_generator.cc
@@ -2,28 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/cryptauth/mock_eid_generator.h"
+#include "components/cryptauth/mock_foreground_eid_generator.h"
#include "base/memory/ptr_util.h"
namespace cryptauth {
-MockEidGenerator::MockEidGenerator() : background_scan_filter_(nullptr),
- advertisement_(nullptr),
- possible_advertisements_(nullptr),
- identified_device_(nullptr),
- num_identify_calls_(0) {}
+MockForegroundEidGenerator::MockForegroundEidGenerator()
+ : background_scan_filter_(nullptr),
+ advertisement_(nullptr),
+ possible_advertisements_(nullptr),
+ identified_device_(nullptr),
+ num_identify_calls_(0) {}
-MockEidGenerator::~MockEidGenerator() {}
+MockForegroundEidGenerator::~MockForegroundEidGenerator() {}
-std::unique_ptr<EidGenerator::EidData>
-MockEidGenerator::GenerateBackgroundScanFilter(
+std::unique_ptr<ForegroundEidGenerator::EidData>
+MockForegroundEidGenerator::GenerateBackgroundScanFilter(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
if (!background_scan_filter_) {
return nullptr;
}
- std::unique_ptr<EidGenerator::DataWithTimestamp> adjacent_data;
+ std::unique_ptr<DataWithTimestamp> adjacent_data;
if (background_scan_filter_->adjacent_data) {
adjacent_data = base::MakeUnique<DataWithTimestamp>(
background_scan_filter_->adjacent_data->data,
@@ -31,25 +32,25 @@ MockEidGenerator::GenerateBackgroundScanFilter(
background_scan_filter_->adjacent_data->end_timestamp_ms);
}
- return base::MakeUnique<EidData>(
- background_scan_filter_->current_data, std::move(adjacent_data));
+ return base::MakeUnique<EidData>(background_scan_filter_->current_data,
+ std::move(adjacent_data));
}
-std::unique_ptr<EidGenerator::DataWithTimestamp>
-MockEidGenerator::GenerateAdvertisement(
+std::unique_ptr<DataWithTimestamp>
+MockForegroundEidGenerator::GenerateAdvertisement(
const std::string& advertising_device_public_key,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
if (!advertisement_) {
return nullptr;
}
- return base::MakeUnique<DataWithTimestamp>(
- advertisement_->data,
- advertisement_->start_timestamp_ms,
- advertisement_->end_timestamp_ms);
+ return base::MakeUnique<DataWithTimestamp>(advertisement_->data,
+ advertisement_->start_timestamp_ms,
+ advertisement_->end_timestamp_ms);
}
-std::vector<std::string> MockEidGenerator::GeneratePossibleAdvertisements(
+std::vector<std::string>
+MockForegroundEidGenerator::GeneratePossibleAdvertisements(
const std::string& advertising_device_public_key,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
if (!possible_advertisements_) {
@@ -59,7 +60,8 @@ std::vector<std::string> MockEidGenerator::GeneratePossibleAdvertisements(
return *possible_advertisements_;
}
-RemoteDevice const* MockEidGenerator::IdentifyRemoteDeviceByAdvertisement(
+RemoteDevice const*
+MockForegroundEidGenerator::IdentifyRemoteDeviceByAdvertisement(
const std::string& advertisement_service_data,
const std::vector<RemoteDevice>& device_list,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds) const {
diff --git a/chromium/components/cryptauth/mock_eid_generator.h b/chromium/components/cryptauth/mock_foreground_eid_generator.h
index 4f624a22fe8..c9b328d041e 100644
--- a/chromium/components/cryptauth/mock_eid_generator.h
+++ b/chromium/components/cryptauth/mock_foreground_eid_generator.h
@@ -2,26 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_CRYPTAUTH_BLE_MOCK_EID_GENERATOR_H_
-#define COMPONENTS_CRYPTAUTH_BLE_MOCK_EID_GENERATOR_H_
+#ifndef COMPONENTS_CRYPTAUTH_BLE_MOCK_FOREGROUND_EID_GENERATOR_H_
+#define COMPONENTS_CRYPTAUTH_BLE_MOCK_FOREGROUND_EID_GENERATOR_H_
#include <memory>
#include <string>
#include <vector>
-#include "components/cryptauth/eid_generator.h"
+#include "components/cryptauth/foreground_eid_generator.h"
namespace cryptauth {
class BeaconSeed;
struct RemoteDevice;
-// Mock class for EidGenerator. Note that GoogleMock cannot be used to mock this
-// class because GoogleMock's mock functions cannot return a |std::unique_ptr|.
-class MockEidGenerator : public EidGenerator {
+// Mock class for ForegroundEidGenerator. Note that GoogleMock cannot be used to
+// mock this class because GoogleMock's mock functions cannot return a
+// |std::unique_ptr|.
+class MockForegroundEidGenerator : public ForegroundEidGenerator {
public:
- MockEidGenerator();
- ~MockEidGenerator() override;
+ MockForegroundEidGenerator();
+ ~MockForegroundEidGenerator() override;
// Setters for the return values of the overridden functions below.
void set_background_scan_filter(
@@ -42,27 +43,25 @@ class MockEidGenerator : public EidGenerator {
identified_device_ = identified_device;
}
- // EidGenerator:
+ // ForegroundEidGenerator:
std::unique_ptr<EidData> GenerateBackgroundScanFilter(
const std::vector<BeaconSeed>& scanning_device_beacon_seeds)
- const override;
+ const override;
std::unique_ptr<DataWithTimestamp> GenerateAdvertisement(
const std::string& advertising_device_public_key,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds)
- const override;
+ const override;
std::vector<std::string> GeneratePossibleAdvertisements(
const std::string& advertising_device_public_key,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds)
- const override;
+ const override;
RemoteDevice const* IdentifyRemoteDeviceByAdvertisement(
const std::string& advertisement_service_data,
const std::vector<RemoteDevice>& device_list,
const std::vector<BeaconSeed>& scanning_device_beacon_seeds)
- const override;
+ const override;
- int num_identify_calls() {
- return num_identify_calls_;
- }
+ int num_identify_calls() { return num_identify_calls_; }
private:
std::unique_ptr<EidData> background_scan_filter_;
@@ -75,4 +74,4 @@ class MockEidGenerator : public EidGenerator {
} // namespace cryptauth
-#endif // COMPONENTS_CRYPTAUTH_BLE_MOCK_EID_GENERATOR_H_
+#endif // COMPONENTS_CRYPTAUTH_BLE_MOCK_FOREGROUND_EID_GENERATOR_H_
diff --git a/chromium/components/cryptauth/proto/securemessage.proto b/chromium/components/cryptauth/proto/securemessage.proto
index c086145a06a..58ec3bd37c7 100644
--- a/chromium/components/cryptauth/proto/securemessage.proto
+++ b/chromium/components/cryptauth/proto/securemessage.proto
@@ -106,11 +106,19 @@ message DeviceToDeviceMessage {
// Sent as the first message from initiator to responder in an unauthenticated
// Diffie-Hellman Key Exchange.
message InitiatorHello {
+ // The session public key to send to the responder.
optional GenericPublicKey public_dh_key = 1;
+
+ // The protocol version.
+ optional int32 protocol_version = 2 [default = 0];
}
// Sent inside the header of the first message from the responder to the
// initiator in an unauthenticated Diffie-Hellman Key Exchange.
message ResponderHello {
+ // The session public key to send to the initiator.
optional GenericPublicKey public_dh_key = 1;
+
+ // The protocol version.
+ optional int32 protocol_version = 2 [default = 0];
}
diff --git a/chromium/components/cryptauth/raw_eid_generator.h b/chromium/components/cryptauth/raw_eid_generator.h
new file mode 100644
index 00000000000..cab18b6a4d7
--- /dev/null
+++ b/chromium/components/cryptauth/raw_eid_generator.h
@@ -0,0 +1,31 @@
+// Copyright 2017 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_CRYPTAUTH_BLE_RAW_EID_GENERATOR_H_
+#define COMPONENTS_CRYPTAUTH_BLE_RAW_EID_GENERATOR_H_
+
+#include <string>
+
+namespace cryptauth {
+
+// Generates raw ephemeral ID (EID) values that are used by the
+// ForegroundEidGenerator and BackgroundEidGenerator classes.
+class RawEidGenerator {
+ public:
+ virtual ~RawEidGenerator() {}
+
+ // The size of an EID in bytes.
+ static const int32_t kNumBytesInEidValue;
+
+ // Generates the EID at |start_of_period_timestamp_ms| using the given
+ // |eid_seed|. If |extra_entropy| is not null, then it will be used in the EID
+ // calculation.
+ virtual std::string GenerateEid(const std::string& eid_seed,
+ int64_t start_of_period_timestamp_ms,
+ std::string const* extra_entropy) = 0;
+};
+
+} // cryptauth
+
+#endif // COMPONENTS_CRYPTAUTH_BLE_RAW_EID_GENERATOR_H_
diff --git a/chromium/components/cryptauth/raw_eid_generator_impl.cc b/chromium/components/cryptauth/raw_eid_generator_impl.cc
new file mode 100644
index 00000000000..4273a422f52
--- /dev/null
+++ b/chromium/components/cryptauth/raw_eid_generator_impl.cc
@@ -0,0 +1,37 @@
+// Copyright 2017 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/cryptauth/raw_eid_generator_impl.h"
+
+#include "base/sys_byteorder.h"
+#include "crypto/sha2.h"
+
+namespace cryptauth {
+
+const int32_t RawEidGenerator::kNumBytesInEidValue = 2;
+
+RawEidGeneratorImpl::RawEidGeneratorImpl() {}
+
+RawEidGeneratorImpl::~RawEidGeneratorImpl() {}
+
+std::string RawEidGeneratorImpl::GenerateEid(
+ const std::string& eid_seed,
+ int64_t start_of_period_timestamp_ms,
+ std::string const* extra_entropy) {
+ // The data to hash is the eid seed, followed by the extra entropy (if it
+ // exists), followed by the timestamp.
+ std::string to_hash = eid_seed;
+ if (extra_entropy) {
+ to_hash += *extra_entropy;
+ }
+ uint64_t timestamp_data =
+ base::HostToNet64(static_cast<uint64_t>(start_of_period_timestamp_ms));
+ to_hash.append(reinterpret_cast<char*>(&timestamp_data), sizeof(uint64_t));
+
+ std::string result = crypto::SHA256HashString(to_hash);
+ result.resize(RawEidGenerator::kNumBytesInEidValue);
+ return result;
+}
+
+} // namespace cryptauth
diff --git a/chromium/components/cryptauth/raw_eid_generator_impl.h b/chromium/components/cryptauth/raw_eid_generator_impl.h
new file mode 100644
index 00000000000..2dd459ad957
--- /dev/null
+++ b/chromium/components/cryptauth/raw_eid_generator_impl.h
@@ -0,0 +1,33 @@
+// Copyright 2017 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_CRYPTAUTH_BLE_RAW_EID_GENERATOR_IMPL_H_
+#define COMPONENTS_CRYPTAUTH_BLE_RAW_EID_GENERATOR_IMPL_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "components/cryptauth/raw_eid_generator.h"
+
+namespace cryptauth {
+
+// Generates raw ephemeral ID (EID) values that are used by the
+// ForegroundEidGenerator and BackgroundEidGenerator classes.
+class RawEidGeneratorImpl : public RawEidGenerator {
+ public:
+ RawEidGeneratorImpl();
+ ~RawEidGeneratorImpl() override;
+
+ // RawEidGenerator:
+ std::string GenerateEid(const std::string& eid_seed,
+ int64_t start_of_period_timestamp_ms,
+ std::string const* extra_entropy) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RawEidGeneratorImpl);
+};
+
+} // cryptauth
+
+#endif // COMPONENTS_CRYPTAUTH_BLE_RAW_EID_GENERATOR_IMPL_H_
diff --git a/chromium/components/cryptauth/raw_eid_generator_impl_unittest.cc b/chromium/components/cryptauth/raw_eid_generator_impl_unittest.cc
new file mode 100644
index 00000000000..2e434007e41
--- /dev/null
+++ b/chromium/components/cryptauth/raw_eid_generator_impl_unittest.cc
@@ -0,0 +1,138 @@
+// Copyright 2017 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/cryptauth/raw_eid_generator_impl.h"
+
+#include "base/strings/string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cryptauth {
+
+namespace {
+const int32_t kNumBytesInEidValue = 2;
+
+// Midnight on 1/1/2020.
+const int64_t kPeriodStartTimestampMs = 1577836800000L;
+
+} // namespace
+
+class CryptAuthRawEidGeneratorImplTest : public testing::Test {
+ protected:
+ CryptAuthRawEidGeneratorImplTest() {}
+};
+
+TEST_F(CryptAuthRawEidGeneratorImplTest, ProducesTwoByteValue) {
+ RawEidGeneratorImpl generator;
+ std::string eid =
+ generator.GenerateEid("eidSeed", kPeriodStartTimestampMs, nullptr);
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid.length());
+}
+
+TEST_F(CryptAuthRawEidGeneratorImplTest, Deterministic) {
+ RawEidGeneratorImpl generator;
+ std::string eid1 =
+ generator.GenerateEid("eidSeed", kPeriodStartTimestampMs, nullptr);
+ std::string eid2 =
+ generator.GenerateEid("eidSeed", kPeriodStartTimestampMs, nullptr);
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
+ EXPECT_EQ(eid1, eid2);
+}
+
+TEST_F(CryptAuthRawEidGeneratorImplTest, ChangingSeedChangesOutput) {
+ RawEidGeneratorImpl generator;
+ std::string eid1 =
+ generator.GenerateEid("eidSeed1", kPeriodStartTimestampMs, nullptr);
+ std::string eid2 =
+ generator.GenerateEid("eidSeed2", kPeriodStartTimestampMs, nullptr);
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
+ EXPECT_NE(eid1, eid2);
+}
+
+TEST_F(CryptAuthRawEidGeneratorImplTest, ChangingTimestampChangesOutput) {
+ RawEidGeneratorImpl generator;
+ std::string eid1 =
+ generator.GenerateEid("eidSeed", kPeriodStartTimestampMs, nullptr);
+ std::string eid2 =
+ generator.GenerateEid("eidSeed", kPeriodStartTimestampMs + 1, nullptr);
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
+ EXPECT_NE(eid1, eid2);
+}
+
+TEST_F(CryptAuthRawEidGeneratorImplTest, ChangingExtraEntropyChangesOutput) {
+ RawEidGeneratorImpl generator;
+ std::string eid1 =
+ generator.GenerateEid("eidSeed", kPeriodStartTimestampMs, nullptr);
+ std::string extra_entropy = "extraEntropy";
+ std::string eid2 =
+ generator.GenerateEid("eidSeed", kPeriodStartTimestampMs, &extra_entropy);
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid1.length());
+ EXPECT_EQ((size_t)kNumBytesInEidValue, eid2.length());
+ EXPECT_NE(eid1, eid2);
+}
+
+TEST_F(CryptAuthRawEidGeneratorImplTest,
+ ChangingTimestampWithLongExtraEntropy) {
+ RawEidGeneratorImpl generator;
+ std::string long_extra_entropy =
+ "reallyReallyReallyReallyReallyReallyReallyLongExtraEntropy";
+ std::string eid1 = generator.GenerateEid("eidSeed", kPeriodStartTimestampMs,
+ &long_extra_entropy);
+ std::string extra_entropy = "extraEntropy";
+ std::string eid2 = generator.GenerateEid(
+ "eidSeed", kPeriodStartTimestampMs + 1, &long_extra_entropy);
+ EXPECT_NE(eid1, eid2);
+}
+
+// Tests that "known test vectors" are correct. This ensures that the same test
+// vectors produce the same outputs on other platforms.
+TEST_F(CryptAuthRawEidGeneratorImplTest, EnsureTestVectorsPass) {
+ const int8_t test_eid_seed1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
+ const int64_t test_timestamp1 = 2468101214L;
+ const int8_t test_entropy1[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33};
+
+ std::string test_eid_seed1_str(reinterpret_cast<const char*>(test_eid_seed1),
+ sizeof(test_eid_seed1));
+ std::string test_entropy1_str(reinterpret_cast<const char*>(test_entropy1),
+ sizeof(test_entropy1));
+
+ const int8_t test_eid_seed2[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34};
+ const int64_t test_timestamp2 = 51015202530L;
+ const int8_t test_entropy2[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35};
+
+ std::string test_eid_seed2_str(reinterpret_cast<const char*>(test_eid_seed2),
+ sizeof(test_eid_seed2));
+ std::string test_entropy2_str(reinterpret_cast<const char*>(test_entropy2),
+ sizeof(test_entropy2));
+
+ RawEidGeneratorImpl generator;
+
+ std::string test_eid_without_entropy1 =
+ generator.GenerateEid(test_eid_seed1_str, test_timestamp1, nullptr);
+ EXPECT_EQ("\x7d\x2c", test_eid_without_entropy1);
+
+ std::string test_eid_with_entropy1 = generator.GenerateEid(
+ test_eid_seed1_str, test_timestamp1, &test_entropy1_str);
+ EXPECT_EQ("\xdc\xf3", test_eid_with_entropy1);
+
+ std::string test_eid_without_entropy2 =
+ generator.GenerateEid(test_eid_seed2_str, test_timestamp2, nullptr);
+ EXPECT_EQ("\x02\xdd", test_eid_without_entropy2);
+
+ std::string test_eid_with_entropy2 = generator.GenerateEid(
+ test_eid_seed2_str, test_timestamp2, &test_entropy2_str);
+ EXPECT_EQ("\xee\xcc", test_eid_with_entropy2);
+}
+
+} // namespace cryptauth
diff --git a/chromium/components/cryptauth/remote_device.cc b/chromium/components/cryptauth/remote_device.cc
index 19665df742a..e3d26d0b646 100644
--- a/chromium/components/cryptauth/remote_device.cc
+++ b/chromium/components/cryptauth/remote_device.cc
@@ -8,6 +8,30 @@
namespace cryptauth {
+namespace {
+
+// Returns true if both vectors are BeaconSeeds are equal.
+bool AreBeaconSeedsEqual(const std::vector<BeaconSeed> beacon_seeds1,
+ const std::vector<BeaconSeed> beacon_seeds2) {
+ if (beacon_seeds1.size() != beacon_seeds2.size()) {
+ return false;
+ }
+
+ for (size_t i = 0; i < beacon_seeds1.size(); ++i) {
+ const BeaconSeed& seed1 = beacon_seeds1[i];
+ const BeaconSeed& seed2 = beacon_seeds2[i];
+ if (seed1.start_time_millis() != seed2.start_time_millis() ||
+ seed1.end_time_millis() != seed2.end_time_millis() ||
+ seed1.data() != seed2.data()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace
+
RemoteDevice::RemoteDevice() {}
RemoteDevice::RemoteDevice(const std::string& user_id,
@@ -21,12 +45,19 @@ RemoteDevice::RemoteDevice(const std::string& user_id,
public_key(public_key),
bluetooth_address(bluetooth_address),
persistent_symmetric_key(persistent_symmetric_key),
- sign_in_challenge(sign_in_challenge) {}
+ sign_in_challenge(sign_in_challenge),
+ are_beacon_seeds_loaded(false) {}
RemoteDevice::RemoteDevice(const RemoteDevice& other) = default;
RemoteDevice::~RemoteDevice() {}
+void RemoteDevice::LoadBeaconSeeds(
+ const std::vector<BeaconSeed>& beacon_seeds) {
+ this->are_beacon_seeds_loaded = true;
+ this->beacon_seeds = beacon_seeds;
+}
+
std::string RemoteDevice::GetDeviceId() const {
std::string to_return;
base::Base64Encode(public_key, &to_return);
@@ -38,12 +69,21 @@ std::string RemoteDevice::GetTruncatedDeviceIdForLogs() const {
}
bool RemoteDevice::operator==(const RemoteDevice& other) const {
- return user_id == other.user_id
- && name == other.name
- && public_key == other.public_key
- && bluetooth_address == other.bluetooth_address
- && persistent_symmetric_key == other.persistent_symmetric_key
- && sign_in_challenge == other.sign_in_challenge;
+ // Only compare |beacon_seeds| if they are loaded.
+ bool are_beacon_seeds_equal = false;
+ if (are_beacon_seeds_loaded) {
+ are_beacon_seeds_equal =
+ other.are_beacon_seeds_loaded &&
+ AreBeaconSeedsEqual(beacon_seeds, other.beacon_seeds);
+ } else {
+ are_beacon_seeds_equal = !other.are_beacon_seeds_loaded;
+ }
+
+ return user_id == other.user_id && name == other.name &&
+ public_key == other.public_key &&
+ bluetooth_address == other.bluetooth_address &&
+ persistent_symmetric_key == other.persistent_symmetric_key &&
+ sign_in_challenge == other.sign_in_challenge && are_beacon_seeds_equal;
}
bool RemoteDevice::operator<(const RemoteDevice& other) const {
diff --git a/chromium/components/cryptauth/remote_device.h b/chromium/components/cryptauth/remote_device.h
index b3f2b51eb18..cd4085f8d21 100644
--- a/chromium/components/cryptauth/remote_device.h
+++ b/chromium/components/cryptauth/remote_device.h
@@ -8,6 +8,8 @@
#include <string>
#include <vector>
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+
namespace cryptauth {
struct RemoteDevice {
@@ -19,6 +21,11 @@ struct RemoteDevice {
std::string persistent_symmetric_key;
std::string sign_in_challenge;
+ // Note: To save space, the BeaconSeeds may not necessarily be included in
+ // this object.
+ bool are_beacon_seeds_loaded;
+ std::vector<BeaconSeed> beacon_seeds;
+
RemoteDevice();
RemoteDevice(const std::string& user_id,
const std::string& name,
@@ -29,6 +36,9 @@ struct RemoteDevice {
RemoteDevice(const RemoteDevice& other);
~RemoteDevice();
+ // Loads a vector of BeaconSeeds for the RemoteDevice.
+ void LoadBeaconSeeds(const std::vector<BeaconSeed>& beacon_seeds);
+
// Returns a unique ID for the device.
std::string GetDeviceId() const;
diff --git a/chromium/components/cryptauth/remote_device_loader.cc b/chromium/components/cryptauth/remote_device_loader.cc
index d673309b0c3..705a1262d84 100644
--- a/chromium/components/cryptauth/remote_device_loader.cc
+++ b/chromium/components/cryptauth/remote_device_loader.cc
@@ -56,7 +56,8 @@ RemoteDeviceLoader::RemoteDeviceLoader(
const std::string& user_id,
const std::string& user_private_key,
std::unique_ptr<cryptauth::SecureMessageDelegate> secure_message_delegate)
- : remaining_devices_(device_info_list),
+ : should_load_beacon_seeds_(false),
+ remaining_devices_(device_info_list),
user_id_(user_id),
user_private_key_(user_private_key),
secure_message_delegate_(std::move(secure_message_delegate)),
@@ -64,8 +65,10 @@ RemoteDeviceLoader::RemoteDeviceLoader(
RemoteDeviceLoader::~RemoteDeviceLoader() {}
-void RemoteDeviceLoader::Load(const RemoteDeviceCallback& callback) {
+void RemoteDeviceLoader::Load(bool should_load_beacon_seeds,
+ const RemoteDeviceCallback& callback) {
DCHECK(callback_.is_null());
+ should_load_beacon_seeds_ = should_load_beacon_seeds;
callback_ = callback;
PA_LOG(INFO) << "Loading " << remaining_devices_.size()
<< " remote devices";
@@ -101,9 +104,18 @@ void RemoteDeviceLoader::OnPSKDerived(
PA_LOG(INFO) << "Derived PSK for " << device.friendly_device_name()
<< ", " << remaining_devices_.size() << " keys remaining.";
- remote_devices_.push_back(cryptauth::RemoteDevice(
+ cryptauth::RemoteDevice remote_device(
user_id_, device.friendly_device_name(), device.public_key(),
- device.bluetooth_address(), psk, std::string()));
+ device.bluetooth_address(), psk, std::string());
+
+ if (should_load_beacon_seeds_) {
+ std::vector<BeaconSeed> beacon_seeds;
+ for (const BeaconSeed& beacon_seed : device.beacon_seeds()) {
+ beacon_seeds.push_back(beacon_seed);
+ }
+ remote_device.LoadBeaconSeeds(beacon_seeds);
+ }
+ remote_devices_.push_back(remote_device);
if (remaining_devices_.empty())
callback_.Run(remote_devices_);
diff --git a/chromium/components/cryptauth/remote_device_loader.h b/chromium/components/cryptauth/remote_device_loader.h
index 5ef63945eec..155645dd85b 100644
--- a/chromium/components/cryptauth/remote_device_loader.h
+++ b/chromium/components/cryptauth/remote_device_loader.h
@@ -62,9 +62,12 @@ class RemoteDeviceLoader {
virtual ~RemoteDeviceLoader();
// Loads the RemoteDevice objects. |callback| will be invoked upon completion.
+ // For space considerations, BeaconSeeds will only be loaded if
+ // |should_load_beacon_seeds| is true.
typedef base::Callback<void(const cryptauth::RemoteDeviceList&)>
RemoteDeviceCallback;
- virtual void Load(const RemoteDeviceCallback& callback);
+ virtual void Load(bool should_load_beacon_seeds,
+ const RemoteDeviceCallback& callback);
private:
// Called when the PSK is derived for each device. If the PSKs for all devices
@@ -72,6 +75,9 @@ class RemoteDeviceLoader {
void OnPSKDerived(const cryptauth::ExternalDeviceInfo& device,
const std::string& psk);
+ // True if the loader should include BeaconSeeds in the loaded RemoteDevices.
+ bool should_load_beacon_seeds_;
+
// The remaining devices whose PSK we're waiting on.
std::vector<cryptauth::ExternalDeviceInfo> remaining_devices_;
diff --git a/chromium/components/cryptauth/remote_device_loader_unittest.cc b/chromium/components/cryptauth/remote_device_loader_unittest.cc
index a164542b9a8..3f538d383aa 100644
--- a/chromium/components/cryptauth/remote_device_loader_unittest.cc
+++ b/chromium/components/cryptauth/remote_device_loader_unittest.cc
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "components/cryptauth/fake_secure_message_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,6 +30,11 @@ const char kUserId[] = "example@gmail.com";
// The public key of the user's local device.
const char kUserPublicKey[] = "User public key";
+// BeaconSeed values.
+const int64_t kBeaconSeedStartTimeMs = 1000;
+const int64_t kBeaconSeedEndTimeMs = 2000;
+const char kBeaconSeedData[] = "Beacon Seed Data";
+
// Creates and returns an ExternalDeviceInfo proto with the fields appended with
// |suffix|.
cryptauth::ExternalDeviceInfo CreateDeviceInfo(const std::string& suffix) {
@@ -37,6 +43,11 @@ cryptauth::ExternalDeviceInfo CreateDeviceInfo(const std::string& suffix) {
device_info.set_public_key(std::string(kPublicKeyPrefix) + suffix);
device_info.set_bluetooth_address(std::string(kBluetoothAddressPrefix) +
suffix);
+ device_info.add_beacon_seeds();
+ BeaconSeed* beacon_seed = device_info.mutable_beacon_seeds(0);
+ beacon_seed->set_start_time_millis(kBeaconSeedStartTimeMs);
+ beacon_seed->set_end_time_millis(kBeaconSeedEndTimeMs);
+ beacon_seed->set_data(kBeaconSeedData);
return device_info;
}
@@ -82,10 +93,64 @@ TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadZeroDevices) {
std::vector<cryptauth::RemoteDevice> result;
EXPECT_CALL(*this, LoadCompleted());
loader.Load(
+ false, base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
+ base::Unretained(this)));
+
+ EXPECT_EQ(0u, remote_devices_.size());
+}
+
+TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadOneDeviceWithBeaconSeeds) {
+ std::vector<cryptauth::ExternalDeviceInfo> device_infos(
+ 1, CreateDeviceInfo("0"));
+ RemoteDeviceLoader loader(device_infos, user_private_key_, kUserId,
+ std::move(secure_message_delegate_));
+
+ std::vector<cryptauth::RemoteDevice> result;
+ EXPECT_CALL(*this, LoadCompleted());
+ loader.Load(
+ true, base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
+ base::Unretained(this)));
+
+ EXPECT_EQ(1u, remote_devices_.size());
+ EXPECT_FALSE(remote_devices_[0].persistent_symmetric_key.empty());
+ EXPECT_EQ(device_infos[0].friendly_device_name(), remote_devices_[0].name);
+ EXPECT_EQ(device_infos[0].public_key(), remote_devices_[0].public_key);
+ EXPECT_TRUE(remote_devices_[0].are_beacon_seeds_loaded);
+ ASSERT_EQ(1u, remote_devices_[0].beacon_seeds.size());
+
+ const BeaconSeed& beacon_seed = remote_devices_[0].beacon_seeds[0];
+ EXPECT_EQ(kBeaconSeedData, beacon_seed.data());
+ EXPECT_EQ(kBeaconSeedStartTimeMs, beacon_seed.start_time_millis());
+ EXPECT_EQ(kBeaconSeedEndTimeMs, beacon_seed.end_time_millis());
+}
+
+TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadDevicesWithAndWithoutBeaconSeeds) {
+ std::vector<cryptauth::ExternalDeviceInfo> device_infos(
+ 1, CreateDeviceInfo("0"));
+
+ RemoteDeviceLoader loader1(device_infos, user_private_key_, kUserId,
+ base::MakeUnique<FakeSecureMessageDelegate>());
+ EXPECT_CALL(*this, LoadCompleted());
+ loader1.Load(
+ false /* should_load_beacon_seeds */,
base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
base::Unretained(this)));
+ RemoteDevice remote_device_without_beacon_seed = remote_devices_[0];
- EXPECT_EQ(0u, remote_devices_.size());
+ RemoteDeviceLoader loader2(device_infos, user_private_key_, kUserId,
+ base::MakeUnique<FakeSecureMessageDelegate>());
+ EXPECT_CALL(*this, LoadCompleted());
+ loader2.Load(
+ true /* should_load_beacon_seeds */,
+ base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
+ base::Unretained(this)));
+ RemoteDevice remote_device_with_beacon_seed = remote_devices_[0];
+
+ EXPECT_EQ(remote_device_without_beacon_seed,
+ remote_device_without_beacon_seed);
+ EXPECT_EQ(remote_device_with_beacon_seed, remote_device_with_beacon_seed);
+ EXPECT_FALSE(remote_device_with_beacon_seed ==
+ remote_device_without_beacon_seed);
}
TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadOneDeviceWithAddress) {
@@ -97,8 +162,8 @@ TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadOneDeviceWithAddress) {
std::vector<cryptauth::RemoteDevice> result;
EXPECT_CALL(*this, LoadCompleted());
loader.Load(
- base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
- base::Unretained(this)));
+ false, base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
+ base::Unretained(this)));
EXPECT_EQ(1u, remote_devices_.size());
EXPECT_FALSE(remote_devices_[0].persistent_symmetric_key.empty());
@@ -106,6 +171,7 @@ TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadOneDeviceWithAddress) {
EXPECT_EQ(device_infos[0].public_key(), remote_devices_[0].public_key);
EXPECT_EQ(device_infos[0].bluetooth_address(),
remote_devices_[0].bluetooth_address);
+ EXPECT_EQ(0u, remote_devices_[0].beacon_seeds.size());
}
TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadOneDeviceWithoutAddress) {
@@ -118,8 +184,8 @@ TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadOneDeviceWithoutAddress) {
std::vector<cryptauth::RemoteDevice> result;
EXPECT_CALL(*this, LoadCompleted());
loader.Load(
- base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
- base::Unretained(this)));
+ false, base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
+ base::Unretained(this)));
EXPECT_EQ(1u, remote_devices_.size());
EXPECT_FALSE(remote_devices_[0].persistent_symmetric_key.empty());
@@ -143,8 +209,8 @@ TEST_F(CryptAuthRemoteDeviceLoaderTest, LoadThreeRemoteDevices) {
EXPECT_CALL(*this, LoadCompleted());
loader.Load(
- base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
- base::Unretained(this)));
+ false, base::Bind(&CryptAuthRemoteDeviceLoaderTest::OnRemoteDevicesLoaded,
+ base::Unretained(this)));
EXPECT_EQ(3u, remote_devices_.size());
for (size_t i = 0; i < 3; ++i) {
diff --git a/chromium/components/cryptauth/session_keys.cc b/chromium/components/cryptauth/session_keys.cc
new file mode 100644
index 00000000000..74783a2d30b
--- /dev/null
+++ b/chromium/components/cryptauth/session_keys.cc
@@ -0,0 +1,56 @@
+// Copyright 2017 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/cryptauth/session_keys.h"
+
+#include "base/strings/string_piece.h"
+#include "crypto/hkdf.h"
+
+namespace cryptauth {
+namespace {
+
+// The salt used to compute the devired keys. SHA256 of "D2D".
+const uint8_t kSalt[] = {0x82, 0xAA, 0x55, 0xA0, 0xD3, 0x97, 0xF8, 0x83,
+ 0x46, 0xCA, 0x1C, 0xEE, 0x8D, 0x39, 0x09, 0xB9,
+ 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D, 0x4A, 0xB3,
+ 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10};
+
+// The number of bytes in the derived keys.
+const int kKeySize = 32;
+
+// String used in the derivation of the inititor encoding key.
+const char kInitiatorPurpose[] = "initiator";
+
+// String used in the derivation of the responder encoding key.
+const char kResponderPurpose[] = "responder";
+
+} // namespace
+
+SessionKeys::SessionKeys(const std::string& master_symmetric_key) {
+ std::string salt(reinterpret_cast<const char*>(&kSalt[0]), sizeof(kSalt));
+
+ // We set the key_length to the length of the expected output and then take
+ // the result from the first key, which is the client write key.
+ crypto::HKDF initiator_encode(master_symmetric_key, salt, kInitiatorPurpose,
+ kKeySize, 0, 0);
+ initiator_encode_key_ = initiator_encode.client_write_key().as_string();
+
+ crypto::HKDF responder_encode(master_symmetric_key, salt, kResponderPurpose,
+ kKeySize, 0, 0);
+ responder_encode_key_ = responder_encode.client_write_key().as_string();
+}
+
+SessionKeys::SessionKeys() {}
+
+SessionKeys::~SessionKeys() {}
+
+std::string SessionKeys::initiator_encode_key() const {
+ return initiator_encode_key_;
+}
+
+std::string SessionKeys::responder_encode_key() const {
+ return responder_encode_key_;
+}
+
+} // namespace cryptauth
diff --git a/chromium/components/cryptauth/session_keys.h b/chromium/components/cryptauth/session_keys.h
new file mode 100644
index 00000000000..c9d0e394de7
--- /dev/null
+++ b/chromium/components/cryptauth/session_keys.h
@@ -0,0 +1,41 @@
+// Copyright 2014 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_CRYPTAUTH_SESSION_KEYS_H_
+#define COMPONENTS_CRYPTAUTH_SESSION_KEYS_H_
+
+#include <string>
+
+#include "base/macros.h"
+
+namespace cryptauth {
+
+// This class contains the secure channel (secure context) session keys. This
+// class derives (from the master symmetric key) different keys for encryption
+// and decryption. The protocol initiator (i.e. the Chromebook) should use
+// |initiator_encode_key()| to encrypt the messages, and the responder should
+// use |responder_encode_key()|. This is reversed for decryption.
+class SessionKeys {
+ public:
+ // Create session keys derived from the |master_symmetric_key|.
+ explicit SessionKeys(const std::string& master_symmetric_key);
+
+ SessionKeys();
+
+ virtual ~SessionKeys();
+
+ virtual std::string initiator_encode_key() const;
+ virtual std::string responder_encode_key() const;
+
+ private:
+ // The initiator encoding key.
+ std::string initiator_encode_key_;
+
+ // The responder encoding key.
+ std::string responder_encode_key_;
+};
+
+} // namespace cryptauth
+
+#endif // COMPONENTS_CRYPTAUTH_SESSION_KEYS_H_
diff --git a/chromium/components/cryptauth/session_keys_unittest.cc b/chromium/components/cryptauth/session_keys_unittest.cc
new file mode 100644
index 00000000000..e11b8c6b738
--- /dev/null
+++ b/chromium/components/cryptauth/session_keys_unittest.cc
@@ -0,0 +1,56 @@
+// Copyright 2017 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/cryptauth/session_keys.h"
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/strings/string_number_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cryptauth {
+namespace {
+
+// Values generated using the Android implementation.
+const char kMasterKeyHex[] =
+ "f611126a04302551ac1e8ed512952ee287a1d2561e2a2c72e7bf1ebe4bdc74ce";
+const char kInitiatorKeyHex[] =
+ "787ec48783f0a1f9fb9c5bc0230c2e7f45b8783acf8c9bd1c63242df9da31999";
+const char kResponderKeyHex[] =
+ "a366ec1f9cf327b69c341211216545cc302379078229eae78b43d60c110a6fba";
+
+} // namespace
+
+class CryptAuthSessionKeysTest : public testing::Test {
+ protected:
+ CryptAuthSessionKeysTest() {}
+
+ DISALLOW_COPY_AND_ASSIGN(CryptAuthSessionKeysTest);
+};
+
+TEST_F(CryptAuthSessionKeysTest, GenerateKeys) {
+ std::vector<uint8_t> data;
+
+ std::string master_key(kMasterKeyHex);
+ ASSERT_TRUE(base::HexStringToBytes(master_key, &data));
+ master_key.assign(reinterpret_cast<char*>(&data[0]), data.size());
+
+ data.clear();
+ std::string initiator_key(kInitiatorKeyHex);
+ ASSERT_TRUE(base::HexStringToBytes(initiator_key, &data));
+ initiator_key.assign(reinterpret_cast<char*>(&data[0]), data.size());
+
+ data.clear();
+ std::string responder_key(kResponderKeyHex);
+ ASSERT_TRUE(base::HexStringToBytes(responder_key, &data));
+ responder_key.assign(reinterpret_cast<char*>(&data[0]), data.size());
+
+ SessionKeys session_keys(master_key);
+ EXPECT_EQ(initiator_key, session_keys.initiator_encode_key());
+ EXPECT_EQ(responder_key, session_keys.responder_encode_key());
+}
+
+} // namespace cryptauth
diff --git a/chromium/components/cryptauth/wire_message.cc b/chromium/components/cryptauth/wire_message.cc
index b91b9435589..0e29872e58d 100644
--- a/chromium/components/cryptauth/wire_message.cc
+++ b/chromium/components/cryptauth/wire_message.cc
@@ -20,8 +20,11 @@
// The wire messages have a simple format:
// [ message version ] [ body length ] [ JSON body ]
// 1 byte 2 bytes body length
-// The JSON body contains two fields: an optional permit_id field and a required
-// data field.
+// When sending encrypted messages, the JSON body contains two fields: an
+// optional |permit_id| field and a required |payload| field.
+//
+// For non-encrypted messages, the message itself is the JSON body, and it
+// doesn't have a |payload| field.
namespace cryptauth {
namespace {
@@ -104,8 +107,14 @@ std::unique_ptr<WireMessage> WireMessage::Deserialize(
DCHECK(success);
std::string payload_base64;
- if (!body->GetString(kPayloadKey, &payload_base64) ||
- payload_base64.empty()) {
+ if (!body->GetString(kPayloadKey, &payload_base64)) {
+ // The body is a valid JSON, but it doesn't contain a |payload| field. It
+ // must be a non-encrypted message.
+ return base::WrapUnique(
+ new WireMessage(serialized_message.substr(kHeaderLength)));
+ }
+
+ if (payload_base64.empty()) {
PA_LOG(WARNING) << "Error: Missing payload.";
return nullptr;
}
@@ -127,24 +136,29 @@ std::unique_ptr<WireMessage> WireMessage::Deserialize(
}
std::string WireMessage::Serialize() const {
- if (payload_.empty()) {
- PA_LOG(ERROR) << "Failed to serialize empty wire message.";
- return std::string();
- }
-
- // Create JSON body containing permit id and payload.
- base::DictionaryValue body;
-
- std::string base64_payload;
- base::Base64UrlEncode(payload_, base::Base64UrlEncodePolicy::INCLUDE_PADDING,
- &base64_payload);
- body.SetString(kPayloadKey, base64_payload);
- body.SetString(kFeatureKey, feature_);
-
std::string json_body;
- if (!base::JSONWriter::Write(body, &json_body)) {
- PA_LOG(ERROR) << "Failed to convert WireMessage body to JSON: " << body;
- return std::string();
+ if (body_.empty()) {
+ if (payload_.empty()) {
+ PA_LOG(ERROR) << "Failed to serialize empty wire message.";
+ return std::string();
+ }
+
+ // Create JSON body containing permit id and payload.
+ base::DictionaryValue body;
+
+ std::string base64_payload;
+ base::Base64UrlEncode(payload_,
+ base::Base64UrlEncodePolicy::INCLUDE_PADDING,
+ &base64_payload);
+ body.SetString(kPayloadKey, base64_payload);
+ body.SetString(kFeatureKey, feature_);
+
+ if (!base::JSONWriter::Write(body, &json_body)) {
+ PA_LOG(ERROR) << "Failed to convert WireMessage body to JSON: " << body;
+ return std::string();
+ }
+ } else {
+ json_body = body_;
}
// Create header containing version and payload size.
@@ -170,4 +184,6 @@ std::string WireMessage::Serialize() const {
WireMessage::WireMessage(const std::string& payload, const std::string& feature)
: payload_(payload), feature_(feature) {}
+WireMessage::WireMessage(const std::string& body) : body_(body) {}
+
} // namespace cryptauth
diff --git a/chromium/components/cryptauth/wire_message.h b/chromium/components/cryptauth/wire_message.h
index 2ab1db9a179..5aed96d970c 100644
--- a/chromium/components/cryptauth/wire_message.h
+++ b/chromium/components/cryptauth/wire_message.h
@@ -16,6 +16,11 @@ class WireMessage {
public:
// Creates a WireMessage containing |payload| for feature |feature|.
explicit WireMessage(const std::string& payload, const std::string& feature);
+
+ // Creates a WireMessage containing |body| (a serialized JSON) as the message
+ // body.
+ explicit WireMessage(const std::string& body);
+
virtual ~WireMessage();
// Returns the deserialized message from |serialized_message|, or nullptr if
@@ -32,6 +37,7 @@ class WireMessage {
const std::string& payload() const { return payload_; }
const std::string& feature() const { return feature_; }
+ const std::string& body() const { return body_; }
private:
// The message payload.
@@ -41,6 +47,10 @@ class WireMessage {
// EasyUnlock).
const std::string feature_;
+ // The message body. When this is set |payload_| and |feature_| are empty, and
+ // vice-versa.
+ const std::string body_;
+
DISALLOW_COPY_AND_ASSIGN(WireMessage);
};
diff --git a/chromium/components/cryptauth/wire_message_unittest.cc b/chromium/components/cryptauth/wire_message_unittest.cc
index 7c7caca3524..582c5a3562e 100644
--- a/chromium/components/cryptauth/wire_message_unittest.cc
+++ b/chromium/components/cryptauth/wire_message_unittest.cc
@@ -88,14 +88,15 @@ TEST(CryptAuthWireMessageTest, Deserialize_BodyIsNotADictionary) {
EXPECT_FALSE(message);
}
-TEST(CryptAuthWireMessageTest, Deserialize_BodyLacksPayload) {
+TEST(CryptAuthWireMessageTest, Deserialize_NonEncryptedMessage) {
bool is_incomplete;
std::string header("\3\0\x02", 3);
std::string bytes = header + "{}";
std::unique_ptr<WireMessage> message =
WireMessage::Deserialize(bytes, &is_incomplete);
EXPECT_FALSE(is_incomplete);
- EXPECT_FALSE(message);
+ ASSERT_TRUE(message);
+ EXPECT_EQ("{}", message->body());
}
TEST(CryptAuthWireMessageTest, Deserialize_BodyHasEmptyPayload) {
diff --git a/chromium/components/data_reduction_proxy/DEPS b/chromium/components/data_reduction_proxy/DEPS
index 20847ff1716..d2649794511 100644
--- a/chromium/components/data_reduction_proxy/DEPS
+++ b/chromium/components/data_reduction_proxy/DEPS
@@ -2,6 +2,7 @@ include_rules = [
"+components/data_use_measurement/core",
"+components/pref_registry",
"+components/prefs",
+ "+components/previews",
"+components/variations",
"+crypto",
"+google_apis",
diff --git a/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.cc b/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.cc
index f600474209e..ac945240865 100644
--- a/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.cc
@@ -180,22 +180,6 @@ void ContentLoFiDecider::RemoveAcceptTransformHeader(
headers->RemoveHeader(chrome_proxy_accept_transform_header());
}
-void ContentLoFiDecider::MaybeSetIgnorePreviewsBlacklistDirective(
- net::HttpRequestHeaders* headers) const {
- if (!headers || !params::AreLitePagesEnabledViaFlags() ||
- !IsLitePagePreviewRequested(*headers)) {
- return;
- }
- std::string chrome_proxy_header_value;
- headers->GetHeader(chrome_proxy_header(), &chrome_proxy_header_value);
- headers->RemoveHeader(chrome_proxy_header());
- if (!chrome_proxy_header_value.empty())
- chrome_proxy_header_value += ", ";
- chrome_proxy_header_value +=
- chrome_proxy_lite_page_ignore_blacklist_directive();
- headers->SetHeader(chrome_proxy_header(), chrome_proxy_header_value);
-}
-
bool ContentLoFiDecider::ShouldRecordLoFiUMA(
const net::URLRequest& request) const {
const content::ResourceRequestInfo* request_info =
@@ -212,4 +196,20 @@ bool ContentLoFiDecider::ShouldRecordLoFiUMA(
params::IsIncludedInLoFiControlFieldTrial();
}
+bool ContentLoFiDecider::IsClientLoFiImageRequest(
+ const net::URLRequest& request) const {
+ const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo::ForRequest(&request);
+ return request_info &&
+ request_info->GetResourceType() == content::RESOURCE_TYPE_IMAGE &&
+ (request_info->GetPreviewsState() & content::CLIENT_LOFI_ON);
+}
+
+bool ContentLoFiDecider::IsClientLoFiAutoReloadRequest(
+ const net::URLRequest& request) const {
+ const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo::ForRequest(&request);
+ return request_info &&
+ (request_info->GetPreviewsState() & content::CLIENT_LOFI_AUTO_RELOAD);
+}
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.h b/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.h
index 40f6dc32814..327278e9548 100644
--- a/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.h
+++ b/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.h
@@ -38,9 +38,10 @@ class ContentLoFiDecider : public LoFiDecider {
const net::HttpRequestHeaders& headers) const override;
void RemoveAcceptTransformHeader(
net::HttpRequestHeaders* headers) const override;
- void MaybeSetIgnorePreviewsBlacklistDirective(
- net::HttpRequestHeaders* headers) const override;
bool ShouldRecordLoFiUMA(const net::URLRequest& request) const override;
+ bool IsClientLoFiImageRequest(const net::URLRequest& request) const override;
+ bool IsClientLoFiAutoReloadRequest(
+ const net::URLRequest& request) const override;
private:
DISALLOW_COPY_AND_ASSIGN(ContentLoFiDecider);
diff --git a/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc b/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
index 4e5dcf9cd6a..d033a521d8f 100644
--- a/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc
@@ -33,6 +33,7 @@
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_retry_info.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_test_util.h"
@@ -110,8 +111,9 @@ class ContentLoFiDeciderTest : public testing::Test {
std::unique_ptr<net::URLRequest> CreateRequest(
bool is_main_frame,
content::PreviewsState previews_state) {
- std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
- GURL("http://www.google.com/"), net::IDLE, &delegate_);
+ std::unique_ptr<net::URLRequest> request =
+ context_.CreateRequest(GURL("http://www.google.com/"), net::IDLE,
+ &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
AllocateRequestInfoForTesting(
request.get(),
(is_main_frame ? content::RESOURCE_TYPE_MAIN_FRAME
@@ -124,10 +126,10 @@ class ContentLoFiDeciderTest : public testing::Test {
content::ResourceType resource_type,
bool scheme_is_https,
content::PreviewsState previews_state) {
- std::unique_ptr<net::URLRequest> request =
- context_.CreateRequest(GURL(scheme_is_https ? "https://www.google.com/"
- : "http://www.google.com/"),
- net::IDLE, &delegate_);
+ std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+ GURL(scheme_is_https ? "https://www.google.com/"
+ : "http://www.google.com/"),
+ net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
AllocateRequestInfoForTesting(request.get(), resource_type, previews_state);
return request;
}
@@ -201,18 +203,6 @@ class ContentLoFiDeciderTest : public testing::Test {
header_value.find(compressed_video_directive()) != std::string::npos);
}
- static void VerifyLitePageIgnoreBlacklistHeader(
- bool expected_blacklist_directive_added,
- const net::HttpRequestHeaders& headers) {
- EXPECT_TRUE(headers.HasHeader(chrome_proxy_header()));
- std::string header_value;
- headers.GetHeader(chrome_proxy_header(), &header_value);
- EXPECT_EQ(expected_blacklist_directive_added,
- header_value.find(
- chrome_proxy_lite_page_ignore_blacklist_directive()) !=
- std::string::npos);
- }
-
protected:
base::MessageLoopForIO message_loop_;
net::TestURLRequestContext context_;
@@ -256,8 +246,6 @@ TEST_F(ContentLoFiDeciderTest, LoFiFlags) {
NotifyBeforeSendHeaders(&headers, request.get(), true);
VerifyLoFiHeader(false, false, headers);
VerifyLitePageHeader(false, false, headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
-
// The Lo-Fi flag is "always-on", Lo-Fi is being used, and it's a main frame
// request. Lo-Fi or lite page header should be added.
command_line->AppendSwitchASCII(
@@ -271,8 +259,6 @@ TEST_F(ContentLoFiDeciderTest, LoFiFlags) {
headers);
VerifyLitePageHeader(tests[i].is_using_lite_page && tests[i].is_main_frame,
false, headers);
- VerifyLitePageIgnoreBlacklistHeader(
- tests[i].is_using_lite_page && tests[i].is_main_frame, headers);
DataReductionProxyData* data = DataReductionProxyData::GetData(*request);
// |lofi_requested| should be set to false when Lo-Fi is enabled using
// flags.
@@ -287,7 +273,6 @@ TEST_F(ContentLoFiDeciderTest, LoFiFlags) {
VerifyLoFiHeader(!tests[i].is_using_lite_page, !tests[i].is_using_lofi,
headers);
VerifyLitePageHeader(false, false, headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
// The Lo-Fi flag is "cellular-only" and Lo-Fi is being used. Lo-Fi header
// should be added.
@@ -299,7 +284,6 @@ TEST_F(ContentLoFiDeciderTest, LoFiFlags) {
VerifyLoFiHeader(!tests[i].is_using_lite_page, !tests[i].is_using_lofi,
headers);
VerifyLitePageHeader(false, false, headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
data = DataReductionProxyData::GetData(*request);
// |lofi_requested| should be set to false when Lo-Fi is enabled using
// flags.
@@ -315,7 +299,6 @@ TEST_F(ContentLoFiDeciderTest, LoFiFlags) {
VerifyLoFiHeader(!tests[i].is_using_lite_page, !tests[i].is_using_lofi,
headers);
VerifyLitePageHeader(false, false, headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
data = DataReductionProxyData::GetData(*request);
// |lofi_requested| should be set to false when Lo-Fi is enabled using
// flags.
@@ -391,7 +374,6 @@ TEST_F(ContentLoFiDeciderTest, LoFiEnabledFieldTrial) {
VerifyLoFiHeader(is_lofi_resource_type, !tests[i].is_using_lofi, headers);
VerifyLitePageHeader(false, false, headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
DataReductionProxyData* data = DataReductionProxyData::GetData(*request);
EXPECT_EQ(tests[i].is_using_lofi, data->lofi_requested()) << i;
}
@@ -415,7 +397,6 @@ TEST_F(ContentLoFiDeciderTest, LoFiControlFieldTrial) {
NotifyBeforeSendHeaders(&headers, request.get(), true);
VerifyLoFiHeader(false, false, headers);
VerifyLitePageHeader(false, false, headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
DataReductionProxyData* data = DataReductionProxyData::GetData(*request);
EXPECT_EQ(tests[i].is_using_lofi, data->lofi_requested()) << i;
}
@@ -443,7 +424,6 @@ TEST_F(ContentLoFiDeciderTest, LitePageFieldTrial) {
VerifyLoFiHeader(false, false, headers);
VerifyLitePageHeader(tests[i].is_main_frame, !tests[i].is_using_lite_page,
headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
DataReductionProxyData* data = DataReductionProxyData::GetData(*request);
EXPECT_EQ(tests[i].is_using_lite_page, data->lofi_requested()) << i;
}
@@ -487,7 +467,6 @@ TEST_F(ContentLoFiDeciderTest, LitePageFieldTrialFallbackEnabled) {
VerifyLitePageHeader(tests[i].is_main_frame,
tests[i].is_main_frame && !tests[i].is_using_lite_page,
headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
DataReductionProxyData* data = DataReductionProxyData::GetData(*request);
EXPECT_EQ(tests[i].is_using_lofi || tests[i].is_using_lite_page,
data->lofi_requested())
@@ -527,7 +506,6 @@ TEST_F(ContentLoFiDeciderTest, LitePageFieldTrialFallbackDisabled) {
VerifyLitePageHeader(tests[i].is_main_frame,
tests[i].is_main_frame && !tests[i].is_using_lite_page,
headers);
- VerifyLitePageIgnoreBlacklistHeader(false, headers);
DataReductionProxyData* data = DataReductionProxyData::GetData(*request);
EXPECT_EQ(tests[i].is_using_lofi || tests[i].is_using_lite_page,
data->lofi_requested())
@@ -747,40 +725,6 @@ TEST_F(ContentLoFiDeciderTest, RemoveAcceptTransformHeader) {
EXPECT_FALSE(headers.HasHeader(chrome_proxy_accept_transform_header()));
}
-TEST_F(ContentLoFiDeciderTest, MaybeIgnoreBlacklist) {
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- command_line->InitFromArgv(command_line->argv());
- std::unique_ptr<data_reduction_proxy::ContentLoFiDecider> lofi_decider(
- new data_reduction_proxy::ContentLoFiDecider());
- net::HttpRequestHeaders headers;
- lofi_decider->MaybeSetIgnorePreviewsBlacklistDirective(&headers);
- EXPECT_FALSE(headers.HasHeader(chrome_proxy_header()));
-
- headers.SetHeader(chrome_proxy_header(), "Foo");
- lofi_decider->MaybeSetIgnorePreviewsBlacklistDirective(&headers);
- std::string header_value;
- headers.GetHeader(chrome_proxy_header(), &header_value);
- EXPECT_EQ("Foo", header_value);
-
- headers.RemoveHeader(chrome_proxy_header());
- command_line->AppendSwitch(switches::kEnableDataReductionProxyLitePage);
- headers.SetHeader(chrome_proxy_accept_transform_header(), "empty-image");
- lofi_decider->MaybeSetIgnorePreviewsBlacklistDirective(&headers);
- EXPECT_FALSE(headers.HasHeader(chrome_proxy_header()));
-
- headers.SetHeader(chrome_proxy_accept_transform_header(), "lite-page");
- lofi_decider->MaybeSetIgnorePreviewsBlacklistDirective(&headers);
- EXPECT_TRUE(headers.HasHeader(chrome_proxy_header()));
- headers.GetHeader(chrome_proxy_header(), &header_value);
- EXPECT_EQ("exp=ignore_preview_blacklist", header_value);
-
- headers.SetHeader(chrome_proxy_header(), "Foo");
- lofi_decider->MaybeSetIgnorePreviewsBlacklistDirective(&headers);
- EXPECT_TRUE(headers.HasHeader(chrome_proxy_header()));
- headers.GetHeader(chrome_proxy_header(), &header_value);
- EXPECT_EQ("Foo, exp=ignore_preview_blacklist", header_value);
-}
-
TEST_F(ContentLoFiDeciderTest, NoTransformDoesNotAddHeader) {
base::FieldTrialList field_trial_list(nullptr);
base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
@@ -792,4 +736,56 @@ TEST_F(ContentLoFiDeciderTest, NoTransformDoesNotAddHeader) {
EXPECT_FALSE(headers.HasHeader(chrome_proxy_accept_transform_header()));
}
+TEST_F(ContentLoFiDeciderTest, RequestIsClientSideLoFiMainFrameTest) {
+ std::unique_ptr<net::URLRequest> request = CreateRequestByType(
+ content::RESOURCE_TYPE_MAIN_FRAME, true, content::CLIENT_LOFI_ON);
+ std::unique_ptr<data_reduction_proxy::ContentLoFiDecider> lofi_decider(
+ new data_reduction_proxy::ContentLoFiDecider());
+ EXPECT_FALSE(lofi_decider->IsClientLoFiImageRequest(*request));
+}
+
+TEST_F(ContentLoFiDeciderTest, RequestIsNotClientSideLoFiImageTest) {
+ std::unique_ptr<net::URLRequest> request = CreateRequestByType(
+ content::RESOURCE_TYPE_IMAGE, true, content::PREVIEWS_NO_TRANSFORM);
+ std::unique_ptr<data_reduction_proxy::ContentLoFiDecider> lofi_decider(
+ new data_reduction_proxy::ContentLoFiDecider());
+ EXPECT_FALSE(lofi_decider->IsClientLoFiImageRequest(*request));
+}
+
+TEST_F(ContentLoFiDeciderTest, RequestIsClientSideLoFiImageTest) {
+ std::unique_ptr<net::URLRequest> request = CreateRequestByType(
+ content::RESOURCE_TYPE_IMAGE, true, content::CLIENT_LOFI_ON);
+ std::unique_ptr<data_reduction_proxy::ContentLoFiDecider> lofi_decider(
+ new data_reduction_proxy::ContentLoFiDecider());
+ EXPECT_TRUE(lofi_decider->IsClientLoFiImageRequest(*request));
+}
+
+TEST_F(ContentLoFiDeciderTest, RequestIsClientLoFiAutoReload) {
+ // IsClientLoFiAutoReloadRequest() should return true for any request with the
+ // CLIENT_LOFI_AUTO_RELOAD bit set.
+
+ EXPECT_TRUE(ContentLoFiDecider().IsClientLoFiAutoReloadRequest(
+ *CreateRequestByType(content::RESOURCE_TYPE_IMAGE, false,
+ content::CLIENT_LOFI_AUTO_RELOAD)));
+
+ EXPECT_TRUE(
+ ContentLoFiDecider().IsClientLoFiAutoReloadRequest(*CreateRequestByType(
+ content::RESOURCE_TYPE_IMAGE, true,
+ content::CLIENT_LOFI_AUTO_RELOAD | content::PREVIEWS_NO_TRANSFORM)));
+
+ EXPECT_TRUE(ContentLoFiDecider().IsClientLoFiAutoReloadRequest(
+ *CreateRequestByType(content::RESOURCE_TYPE_MAIN_FRAME, true,
+ content::CLIENT_LOFI_AUTO_RELOAD)));
+
+ EXPECT_TRUE(ContentLoFiDecider().IsClientLoFiAutoReloadRequest(
+ *CreateRequestByType(content::RESOURCE_TYPE_SCRIPT, true,
+ content::CLIENT_LOFI_AUTO_RELOAD)));
+
+ // IsClientLoFiAutoReloadRequest() should return false for any request without
+ // the CLIENT_LOFI_AUTO_RELOAD bit set.
+ EXPECT_FALSE(ContentLoFiDecider().IsClientLoFiAutoReloadRequest(
+ *CreateRequestByType(content::RESOURCE_TYPE_IMAGE, false,
+ content::PREVIEWS_NO_TRANSFORM)));
+}
+
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc b/chromium/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
index e42be3df3d4..52d6503347e 100644
--- a/chromium/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
@@ -20,6 +20,7 @@
#include "content/public/common/previews_state.h"
#include "content/public/test/test_renderer_host.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -66,8 +67,9 @@ class ContentLoFiUIServiceTest : public content::RenderViewHostTestHarness {
EXPECT_TRUE(
content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- std::unique_ptr<net::URLRequest> request = context.CreateRequest(
- GURL("http://www.google.com/"), net::IDLE, delegate);
+ std::unique_ptr<net::URLRequest> request =
+ context.CreateRequest(GURL("http://www.google.com/"), net::IDLE,
+ delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
content::ResourceRequestInfo::AllocateForTesting(
request.get(), content::RESOURCE_TYPE_SUB_FRAME, NULL,
diff --git a/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc b/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc
index 099aab54a4f..44429e35613 100644
--- a/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
@@ -19,6 +20,7 @@
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/previews_state.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_test_util.h"
@@ -109,8 +111,8 @@ class ContentResourceProviderTest : public testing::Test {
std::unique_ptr<net::URLRequest> CreateRequestByType(
const GURL& gurl,
content::ResourceType resource_type) {
- std::unique_ptr<net::URLRequest> request =
- context_.CreateRequest(gurl, net::IDLE, &delegate_);
+ std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+ gurl, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
AllocateRequestInfoForTesting(request.get(), resource_type);
return request;
}
diff --git a/chromium/components/data_reduction_proxy/core/browser/BUILD.gn b/chromium/components/data_reduction_proxy/core/browser/BUILD.gn
index 6b6c428c388..dc9c93e0631 100644
--- a/chromium/components/data_reduction_proxy/core/browser/BUILD.gn
+++ b/chromium/components/data_reduction_proxy/core/browser/BUILD.gn
@@ -17,6 +17,8 @@ browser_sources = [
"data_reduction_proxy_configurator.h",
"data_reduction_proxy_data.cc",
"data_reduction_proxy_data.h",
+ "data_reduction_proxy_data_use_observer.cc",
+ "data_reduction_proxy_data_use_observer.h",
"data_reduction_proxy_delegate.cc",
"data_reduction_proxy_delegate.h",
"data_reduction_proxy_interceptor.cc",
@@ -59,8 +61,10 @@ if (is_android) {
"//components/data_reduction_proxy/core/common",
"//components/data_reduction_proxy/proto:data_reduction_proxy_proto",
"//components/data_use_measurement/core",
+ "//components/data_use_measurement/core:ascriber",
"//components/pref_registry",
"//components/prefs",
+ "//components/previews/core",
"//components/variations",
"//crypto",
"//google_apis",
@@ -84,8 +88,10 @@ static_library("browser") {
deps = [
"//base",
"//components/data_use_measurement/core",
+ "//components/data_use_measurement/core:ascriber",
"//components/pref_registry",
"//components/prefs",
+ "//components/previews/core",
"//components/variations",
"//crypto",
"//google_apis",
@@ -182,6 +188,7 @@ source_set("unit_tests") {
"//components/data_reduction_proxy/core/common:test_support",
"//components/data_reduction_proxy/proto:data_reduction_proxy_proto",
"//components/prefs:test_support",
+ "//components/previews/core",
"//components/variations",
"//net:test_support",
"//testing/gmock",
diff --git a/chromium/components/data_reduction_proxy/core/browser/DEPS b/chromium/components/data_reduction_proxy/core/browser/DEPS
index 743a2f3baec..16b7cb2bd4b 100644
--- a/chromium/components/data_reduction_proxy/core/browser/DEPS
+++ b/chromium/components/data_reduction_proxy/core/browser/DEPS
@@ -1,3 +1,4 @@
include_rules = [
+ "+components/data_use_measurement/core",
"+third_party/leveldatabase",
]
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc
index 10f161ec10d..c20c7ea1128 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.cc
@@ -13,9 +13,9 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_list.h"
@@ -176,7 +176,7 @@ bool DataReductionProxyBypassProtocol::MaybeBypassProxyAndPrepareToRetry(
// Retry if block-once was specified or if method is idempotent.
return bypass_type == BYPASS_EVENT_TYPE_CURRENT ||
- util::IsMethodIdempotent(request->method());
+ net::HttpUtil::IsMethodIdempotent(request->method());
}
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
index e44a9c2143f..ef62c610e40 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc
@@ -25,7 +25,6 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
#include "net/base/completion_callback.h"
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
@@ -34,9 +33,11 @@
#include "net/base/proxy_delegate.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_transaction_test_util.h"
+#include "net/http/http_util.h"
#include "net/proxy/proxy_server.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
@@ -237,7 +238,8 @@ class DataReductionProxyProtocolTest : public testing::Test {
network_delegate_->headers_received_count();
TestDelegate d;
std::unique_ptr<URLRequest> r(context_->CreateRequest(
- GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d));
+ GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
r->set_method(method);
r->SetLoadFlags(net::LOAD_NORMAL);
@@ -340,10 +342,11 @@ TEST_F(DataReductionProxyProtocolTest, TestIdempotency) {
};
for (size_t i = 0; i < arraysize(tests); ++i) {
std::unique_ptr<net::URLRequest> request(context.CreateRequest(
- GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, NULL));
+ GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, NULL,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
request->set_method(tests[i].method);
EXPECT_EQ(tests[i].expected_result,
- util::IsMethodIdempotent(request->method()));
+ net::HttpUtil::IsMethodIdempotent(request->method()));
}
}
@@ -876,8 +879,9 @@ TEST_F(DataReductionProxyBypassProtocolEndToEndTest,
mock_socket_factory()->AddSocketDataProvider(&retry_socket);
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> url_request(context()->CreateRequest(
- GURL("http://www.google.com"), net::IDLE, &delegate));
+ std::unique_ptr<net::URLRequest> url_request(
+ context()->CreateRequest(GURL("http://www.google.com"), net::IDLE,
+ &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
url_request->Start();
drp_test_context()->RunUntilIdle();
@@ -935,8 +939,9 @@ TEST_F(DataReductionProxyBypassProtocolEndToEndTest,
base::HistogramTester histogram_tester;
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request(context()->CreateRequest(
- GURL("http://google.com"), net::IDLE, &delegate));
+ std::unique_ptr<net::URLRequest> request(
+ context()->CreateRequest(GURL("http://google.com"), net::IDLE,
+ &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
request->Start();
drp_test_context()->RunUntilIdle();
@@ -971,7 +976,8 @@ TEST_F(DataReductionProxyProtocolTest,
TestDelegate d;
std::unique_ptr<URLRequest> r(context_->CreateRequest(
- GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d));
+ GURL("http://www.google.com/"), net::DEFAULT_PRIORITY, &d,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
r->set_method("GET");
r->SetLoadFlags(net::LOAD_NORMAL);
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
index cd7ddb4139b..7aa01480080 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
@@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/test/histogram_tester.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
@@ -40,6 +41,7 @@
#include "net/http/http_util.h"
#include "net/proxy/proxy_server.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_context_storage.h"
@@ -80,14 +82,15 @@ class DataReductionProxyBypassStatsTest : public testing::Test {
test_context_ =
DataReductionProxyTestContext::Builder().WithMockConfig().Build();
- mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_);
+ mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
}
std::unique_ptr<net::URLRequest> CreateURLRequestWithResponseHeaders(
const GURL& url,
const std::string& response_headers) {
- std::unique_ptr<net::URLRequest> fake_request =
- context_.CreateRequest(url, net::IDLE, &delegate_);
+ std::unique_ptr<net::URLRequest> fake_request = context_.CreateRequest(
+ url, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
// Create a test job that will fill in the given response headers for the
// |fake_request|.
@@ -326,8 +329,8 @@ class DataReductionProxyBypassStatsEndToEndTest : public testing::Test {
retry_socket_data_provider.get());
}
- std::unique_ptr<net::URLRequest> request(
- context_.CreateRequest(url, net::IDLE, &delegate_));
+ std::unique_ptr<net::URLRequest> request(context_.CreateRequest(
+ url, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS));
request->set_method("GET");
request->SetLoadFlags(load_flags);
request->Start();
@@ -385,7 +388,8 @@ class DataReductionProxyBypassStatsEndToEndTest : public testing::Test {
mock_socket_factory_.AddSocketDataProvider(&response_socket_data_provider);
std::unique_ptr<net::URLRequest> request(
- context_.CreateRequest(GURL("http://foo.com"), net::IDLE, &delegate_));
+ context_.CreateRequest(GURL("http://foo.com"), net::IDLE, &delegate_,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
request->set_method("GET");
request->Start();
drp_test_context_->RunUntilIdle();
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
index 04280b08bc7..662892a0087 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -78,7 +78,8 @@ void AddInt64ToListPref(size_t index,
int64_t length,
base::ListValue* list_update) {
int64_t value = GetInt64PrefValue(*list_update, index) + length;
- list_update->Set(index, new base::Value(base::Int64ToString(value)));
+ list_update->Set(index,
+ base::MakeUnique<base::Value>(base::Int64ToString(value)));
}
// DailyContentLengthUpdate maintains a data saving pref. The pref is a list
@@ -470,6 +471,8 @@ void DataReductionProxyCompressionStats::RecordData(
IncreaseInt64Pref(data_reduction_proxy::prefs::kHttpOriginalContentLength,
original_size);
+ // TODO(rajendrant): Remove RecordDataUsage once data use ascriber based per
+ // domain data usage recording is enabled.
RecordDataUsage(data_use_host, data_used, original_size, base::Time::Now());
RecordRequestSizePrefs(data_used, original_size, data_saver_enabled,
request_type, mime_type, base::Time::Now());
@@ -1189,7 +1192,7 @@ void DataReductionProxyCompressionStats::RecordDataUsage(
const std::string& data_usage_host,
int64_t data_used,
int64_t original_size,
- const base::Time& time) {
+ const base::Time time) {
if (current_data_usage_load_status_ != LOADED)
return;
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
index b3cf152cc31..324a1da2a28 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
@@ -64,6 +64,9 @@ class DataReductionProxyCompressionStats {
// Records detailed data usage broken down by connection type and domain. Also
// records daily data savings statistics to prefs and reports data savings
// UMA. |compressed_size| and |original_size| are measured in bytes.
+ // TODO(rajendrant): This can be changed to RecordRequestMimeType and
+ // |data_use_group| param removed. It records daily data savings statistics to
+ // prefs and reports data savings UMA.
void UpdateContentLengths(int64_t compressed_size,
int64_t original_size,
bool data_reduction_proxy_enabled,
@@ -71,6 +74,15 @@ class DataReductionProxyCompressionStats {
const scoped_refptr<DataUseGroup>& data_use_group,
const std::string& mime_type);
+ // Record data usage and original size of request broken down by host.
+ // |original_request_size| and |data_used| are in bytes. |time| is the time at
+ // which the data usage occurred. This method should be called in real time,
+ // so |time| is expected to be |Time::Now()|.
+ void RecordDataUsage(const std::string& data_usage_host,
+ int64_t original_request_size,
+ int64_t data_used,
+ const base::Time time);
+
// Creates a |Value| summary of the persistent state of the network
// statistics.
// Must be called on the UI thread.
@@ -203,14 +215,6 @@ class DataReductionProxyCompressionStats {
const char* original_size_via_proxy_pref,
const char* received_size_via_proxy_pref);
- // Record data usage and original size of request broken down by host. |time|
- // is the time at which the data usage occurred. This method should be called
- // in real time, so |time| is expected to be |Time::Now()|.
- void RecordDataUsage(const std::string& data_usage_host,
- int64_t original_request_size,
- int64_t data_used,
- const base::Time& time);
-
// Persists the in memory data usage information to storage and clears all
// in-memory data usage. Do not call this method unless |data_usage_loaded_|
// is |LOADED|.
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
index e9a5338c84c..d05f679441f 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -15,6 +15,7 @@
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
@@ -112,7 +113,9 @@ const char kLastUpdateTime[] = "Wed, 18 Sep 2013 03:45:26";
class DataReductionProxyCompressionStatsTest : public testing::Test {
protected:
- DataReductionProxyCompressionStatsTest() {
+ DataReductionProxyCompressionStatsTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {
EXPECT_TRUE(base::Time::FromString(kLastUpdateTime, &now_));
}
@@ -163,13 +166,12 @@ class DataReductionProxyCompressionStatsTest : public testing::Test {
for (size_t i = 0; i < kNumDaysInHistory; ++i) {
original_daily_content_length_list->Set(
- i, new base::Value(base::SizeTToString(i)));
+ i, base::MakeUnique<base::Value>(base::SizeTToString(i)));
}
received_daily_content_length_list->Clear();
for (size_t i = 0; i < kNumDaysInHistory / 2; ++i) {
- received_daily_content_length_list->Set(
- i, new base::Value(base::SizeTToString(i)));
+ received_daily_content_length_list->AppendString(base::SizeTToString(i));
}
}
@@ -474,7 +476,7 @@ class DataReductionProxyCompressionStatsTest : public testing::Test {
}
private:
- base::MessageLoopForUI loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<DataReductionProxyTestContext> drp_test_context_;
std::unique_ptr<DataReductionProxyCompressionStats> compression_stats_;
base::Time now_;
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index 9ffb7f87fd1..16cf8fef44f 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -27,14 +27,18 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/previews/core/previews_decider.h"
#include "components/variations/variations_associated_data.h"
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/network_change_notifier.h"
#include "net/log/net_log_source_type.h"
+#include "net/nqe/effective_connection_type.h"
#include "net/proxy/proxy_server.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request.h"
@@ -244,12 +248,38 @@ class SecureProxyChecker : public net::URLFetcherDelegate {
void CheckIfSecureProxyIsAllowed(const GURL& secure_proxy_check_url,
FetcherResponseCallback fetcher_callback) {
- fetcher_ = net::URLFetcher::Create(secure_proxy_check_url,
- net::URLFetcher::GET, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation(
+ "data_reduction_proxy_secure_proxy_check", R"(
+ semantics {
+ sender: "Data Reduction Proxy"
+ description:
+ "Sends a request to the Data Reduction Proxy server. Proceeds "
+ "with using a secure connection to the proxy only if the "
+ "response is not blocked or modified by an intermediary."
+ trigger:
+ "A request can be sent whenever the browser is determining how "
+ "to configure its connection to the data reduction proxy. This "
+ "happens on startup and network changes."
+ data: "A specific URL, not related to user data."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can control Data Saver on Android via the 'Data Saver' "
+ "setting. Data Saver is not available on iOS, and on desktop "
+ "it is enabled by installing the Data Saver extension."
+ policy_exception_justification: "Not implemented."
+ })");
+ fetcher_ = net::URLFetcher::Create(
+ secure_proxy_check_url, net::URLFetcher::GET, this, traffic_annotation);
data_use_measurement::DataUseUserData::AttachToFetcher(
fetcher_.get(),
data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY);
- fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY);
+ fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY |
+ net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
fetcher_->SetRequestContext(url_request_context_getter_.get());
// Configure max retries to be at most kMaxRetries times for 5xx errors.
static const int kMaxRetries = 5;
@@ -298,17 +328,42 @@ class WarmupURLFetcher : public net::URLFetcherDelegate {
void FetchWarmupURL() {
UMA_HISTOGRAM_EXACT_LINEAR("DataReductionProxy.WarmupURL.FetchInitiated", 1,
2);
-
- fetcher_ = net::URLFetcher::Create(params::GetWarmupURL(),
- net::URLFetcher::GET, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("data_reduction_proxy_warmup", R"(
+ semantics {
+ sender: "Data Reduction Proxy"
+ description:
+ "Sends a request to the Data Reduction Proxy server to warm up "
+ "the connection to the proxy."
+ trigger:
+ "A network change while the data reduction proxy is enabled will "
+ "trigger this request."
+ data: "A specific URL, not related to user data."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can control Data Saver on Android via the 'Data Saver' "
+ "setting. Data Saver is not available on iOS, and on desktop it "
+ "is enabled by installing the Data Saver extension."
+ policy_exception_justification: "Not implemented."
+ })");
+ fetcher_ = net::URLFetcher::Create(
+ params::GetWarmupURL(), net::URLFetcher::GET, this, traffic_annotation);
data_use_measurement::DataUseUserData::AttachToFetcher(
fetcher_.get(),
data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY);
+ // Do not disable cookies. This allows the warmup connection to be reused
+ // for fetching user initiated requests.
fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE);
fetcher_->SetRequestContext(url_request_context_getter_.get());
- // |fetcher| should not retry on 5xx errors.
+ // |fetcher| should not retry on 5xx errors. |fetcher_| should retry on
+ // network changes since the network stack may receive the connection change
+ // event later than |this|.
+ static const int kMaxRetries = 5;
fetcher_->SetAutomaticallyRetryOn5xx(false);
- fetcher_->SetAutomaticallyRetryOnNetworkChanges(0);
+ fetcher_->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries);
fetcher_->Start();
}
@@ -951,17 +1006,18 @@ bool DataReductionProxyConfig::IsEffectiveConnectionTypeSlowerThanThreshold(
}
bool DataReductionProxyConfig::ShouldEnableLoFi(
- const net::URLRequest& request) {
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK((request.load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) != 0);
DCHECK(!request.url().SchemeIsCryptographic());
- net::NetworkQualityEstimator* network_quality_estimator;
- network_quality_estimator =
- request.context() ? request.context()->network_quality_estimator()
- : nullptr;
+ if (base::FeatureList::IsEnabled(
+ features::kDataReductionProxyDecidesTransform)) {
+ return ShouldAcceptServerLoFi(request, previews_decider);
+ }
- bool enable_lofi = ShouldEnableLoFiInternal(network_quality_estimator);
+ bool enable_lofi = ShouldEnableLoFiInternal(request, previews_decider);
if (params::IsLoFiSlowConnectionsOnlyViaFlags() ||
params::IsIncludedInLoFiEnabledFieldTrial()) {
@@ -974,14 +1030,18 @@ bool DataReductionProxyConfig::ShouldEnableLoFi(
}
bool DataReductionProxyConfig::ShouldEnableLitePages(
- const net::URLRequest& request) {
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK((request.load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) != 0);
DCHECK(!request.url().SchemeIsCryptographic());
- return ShouldEnableLitePagesInternal(
- request.context() ? request.context()->network_quality_estimator()
- : nullptr);
+ if (base::FeatureList::IsEnabled(
+ features::kDataReductionProxyDecidesTransform)) {
+ return ShouldAcceptLitePages(request, previews_decider);
+ }
+
+ return ShouldEnableLitePagesInternal(request, previews_decider);
}
bool DataReductionProxyConfig::enabled_by_user_and_reachable() const {
@@ -989,16 +1049,111 @@ bool DataReductionProxyConfig::enabled_by_user_and_reachable() const {
return enabled_by_user_ && !unreachable_;
}
+bool DataReductionProxyConfig::IsBlackListedOrDisabled(
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider,
+ previews::PreviewsType previews_type) const {
+ // Make sure request is not locally blacklisted.
+ if (params::IsBlackListEnabledForServerPreviews()) {
+ // Pass in net::EFFECTIVE_CONNECTION_TYPE_4G as the thresold as network
+ // speed is checked in IsNetworkQualityProhibitivelySlow().
+ // TODO(ryansturm): Use the correct ECT value (or add new method to
+ // just check blacklist). crbug.com/720102
+ return !previews_decider.ShouldAllowPreviewAtECT(
+ request, previews_type, net::EFFECTIVE_CONNECTION_TYPE_4G);
+ } else {
+ // If Lo-Fi has been turned off, its status can't change. This Lo-Fi bit
+ // will be removed when Lo-Fi and Lite Pages are moved over to using the
+ // PreviewsBlackList.
+ return lofi_off_;
+ }
+}
+
+bool DataReductionProxyConfig::ShouldAcceptServerLoFi(
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(base::FeatureList::IsEnabled(
+ features::kDataReductionProxyDecidesTransform));
+
+ if (IsBlackListedOrDisabled(request, previews_decider,
+ previews::PreviewsType::LOFI)) {
+ return false;
+ }
+
+ if (params::IsLoFiAlwaysOnViaFlags()) {
+ return true;
+ }
+
+ if (params::IsLoFiCellularOnlyViaFlags()) {
+ return net::NetworkChangeNotifier::IsConnectionCellular(connection_type_);
+ }
+
+ if (params::IsLoFiSlowConnectionsOnlyViaFlags() ||
+ params::IsIncludedInLoFiEnabledFieldTrial()) {
+ // Accept Lo-Fi from the data reduction proxy (it will handle the effective
+ // connection type check).
+ return true;
+ }
+
+ return false;
+}
+
+bool DataReductionProxyConfig::ShouldAcceptLitePages(
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(base::FeatureList::IsEnabled(
+ features::kDataReductionProxyDecidesTransform));
+
+ if (IsBlackListedOrDisabled(request, previews_decider,
+ previews::PreviewsType::LITE_PAGE)) {
+ return false;
+ }
+
+ if (params::IsLoFiAlwaysOnViaFlags() &&
+ params::AreLitePagesEnabledViaFlags()) {
+ return true;
+ }
+
+ if (params::IsLoFiCellularOnlyViaFlags() &&
+ params::AreLitePagesEnabledViaFlags()) {
+ return net::NetworkChangeNotifier::IsConnectionCellular(connection_type_);
+ }
+
+ if ((params::IsLoFiSlowConnectionsOnlyViaFlags() &&
+ params::AreLitePagesEnabledViaFlags()) ||
+ params::IsIncludedInLitePageFieldTrial()) {
+ // Accept LitePages from the data reduction proxy (it will handle the
+ // effective connection type check).
+ return true;
+ }
+
+ return false;
+}
+
bool DataReductionProxyConfig::ShouldEnableLoFiInternal(
- const net::NetworkQualityEstimator* network_quality_estimator) {
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!base::FeatureList::IsEnabled(
+ features::kDataReductionProxyDecidesTransform));
last_query_ = GetTicksNow();
network_quality_at_last_query_ = NETWORK_QUALITY_AT_LAST_QUERY_UNKNOWN;
- // If Lo-Fi has been turned off, its status can't change.
- if (lofi_off_)
+ // LitePages overrides Server Lo-Fi. No fallback to Lo-Fi supported
+ // on this code path (not using DataReductionProxyDecidesTransform feature).
+ // TODO(dougarnett): Delete this surrounding method and related code once the
+ // DataReductionProxyDecidesTransform feature is launched to stable [725645].
+ if (ShouldEnableLitePages(request, previews_decider)) {
+ return false;
+ }
+
+ if (IsBlackListedOrDisabled(request, previews_decider,
+ previews::PreviewsType::LOFI)) {
return false;
+ }
if (params::IsLoFiAlwaysOnViaFlags())
return true;
@@ -1007,27 +1162,31 @@ bool DataReductionProxyConfig::ShouldEnableLoFiInternal(
return net::NetworkChangeNotifier::IsConnectionCellular(connection_type_);
}
+ net::NetworkQualityEstimator* network_quality_estimator;
+ network_quality_estimator =
+ request.context() ? request.context()->network_quality_estimator()
+ : nullptr;
+
if (params::IsLoFiSlowConnectionsOnlyViaFlags() ||
params::IsIncludedInLoFiEnabledFieldTrial() ||
params::IsIncludedInLoFiControlFieldTrial()) {
return IsNetworkQualityProhibitivelySlow(network_quality_estimator);
}
- // If Lo-Fi is not enabled through command line and the user is not in
- // Lo-Fi field trials, set Lo-Fi to off.
- lofi_off_ = true;
return false;
}
bool DataReductionProxyConfig::ShouldEnableLitePagesInternal(
- const net::NetworkQualityEstimator* network_quality_estimator) {
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!base::FeatureList::IsEnabled(
+ features::kDataReductionProxyDecidesTransform));
- // If Lo-Fi has been turned off, its status can't change. This Lo-Fi bit will
- // be removed when Lo-Fi and Lite Pages are moved over to using the Previews
- // blacklist.
- if (lofi_off_)
+ if (IsBlackListedOrDisabled(request, previews_decider,
+ previews::PreviewsType::LITE_PAGE)) {
return false;
+ }
if (params::IsLoFiAlwaysOnViaFlags() && params::AreLitePagesEnabledViaFlags())
return true;
@@ -1037,6 +1196,10 @@ bool DataReductionProxyConfig::ShouldEnableLitePagesInternal(
return net::NetworkChangeNotifier::IsConnectionCellular(
net::NetworkChangeNotifier::GetConnectionType());
}
+ net::NetworkQualityEstimator* network_quality_estimator;
+ network_quality_estimator =
+ request.context() ? request.context()->network_quality_estimator()
+ : nullptr;
if ((params::IsLoFiSlowConnectionsOnlyViaFlags() &&
params::AreLitePagesEnabledViaFlags()) ||
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
index 5bc7b57a8b9..e4529cbf34f 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -19,6 +19,7 @@
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
+#include "components/previews/core/previews_experiments.h"
#include "net/base/net_errors.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_interfaces.h"
@@ -42,6 +43,10 @@ class URLRequestContextGetter;
class URLRequestStatus;
}
+namespace previews {
+class PreviewsDecider;
+}
+
namespace data_reduction_proxy {
typedef base::Callback<void(const std::string&,
@@ -193,12 +198,16 @@ class DataReductionProxyConfig
// Returns true when Lo-Fi Previews should be activated. Records metrics for
// Lo-Fi state changes. |request| is used to get the network quality estimator
- // from the URLRequestContext.
- bool ShouldEnableLoFi(const net::URLRequest& request);
+ // from the URLRequestContext. |previews_decider| is used to check if
+ // |request| is locally blacklisted.
+ bool ShouldEnableLoFi(const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider);
// Returns true when Lite Page Previews should be activated. |request| is used
// to get the network quality estimator from the URLRequestContext.
- bool ShouldEnableLitePages(const net::URLRequest& request);
+ // |previews_decider| is used to check if |request| is locally blacklisted.
+ bool ShouldEnableLitePages(const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider);
// Returns true if the data saver has been enabled by the user, and the data
// saver proxy is reachable.
@@ -245,6 +254,9 @@ class DataReductionProxyConfig
FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest,
LoFiAccuracyNonZeroDelay);
FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest, WarmupURL);
+ FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest,
+ ShouldAcceptServerLoFi);
+ FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest, ShouldAcceptLitePages);
// Values of the estimated network quality at the beginning of the most
// recent query of the Network Quality Estimator.
@@ -291,18 +303,52 @@ class DataReductionProxyConfig
bool is_https,
base::TimeDelta* min_retry_delay) const;
+ // Returns whether the request is blacklisted (or if Lo-Fi is disabled).
+ bool IsBlackListedOrDisabled(
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider,
+ previews::PreviewsType previews_type) const;
+
+ // Returns whether the client should report to the data reduction proxy that
+ // it is willing to accept the Server Lo-Fi optimization for |request|.
+ // |previews_decider| is used to check if |request| is locally blacklisted.
+ // Should only be used if the kDataReductionProxyDecidesTransform feature is
+ // enabled.
+ bool ShouldAcceptServerLoFi(
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) const;
+
+ // Returns whether the client should report to the data reduction proxy that
+ // it is willing to accept a LitePage optimization for |request|.
+ // |previews_decider| is used to check if |request| is locally blacklisted.
+ // Should only be used if the kDataReductionProxyDecidesTransform feature is
+ // enabled.
+ bool ShouldAcceptLitePages(
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider) const;
+
// Returns true when Lo-Fi Previews should be activated. Determines if Lo-Fi
// Previews should be activated by checking the Lo-Fi flags and if the network
// quality is prohibitively slow. |network_quality_estimator| may be NULL.
+ // |previews_decider| is a non-null object that determines eligibility of the
+ // showing the preview based on past opt outs.
+ // Should NOT be used if the kDataReductionProxyDecidesTransform feature is
+ // enabled.
bool ShouldEnableLoFiInternal(
- const net::NetworkQualityEstimator* network_quality_estimator);
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider);
// Returns true when Lite Page Previews should be activated. Determines if
// Lite Page Previewsmode should be activated by checking the Lite Page
// Previews flags and if the network quality is prohibitively slow.
- // |network_quality_estimator| may be NULL.
+ // |network_quality_estimator| may be NULL. |previews_decider| is a non-null
+ // object that determines eligibility of showing the preview based on past opt
+ // outs.
+ // Should NOT be used if the kDataReductionProxyDecidesTransform feature is
+ // enabled.
bool ShouldEnableLitePagesInternal(
- const net::NetworkQualityEstimator* network_quality_estimator);
+ const net::URLRequest& request,
+ const previews::PreviewsDecider& previews_decider);
// Returns true if the network quality is at least as poor as the one
// specified in the Auto Lo-Fi field trial parameters.
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
index 2b58c6b14f5..ef0b077e08c 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
@@ -38,6 +38,7 @@
#include "net/http/http_status_code.h"
#include "net/log/net_log_source_type.h"
#include "net/proxy/proxy_server.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_status.h"
@@ -407,20 +408,44 @@ DataReductionProxyConfigServiceClient::GetURLFetcherForConfig(
const GURL& secure_proxy_check_url,
const std::string& request_body) {
DCHECK(thread_checker_.CalledOnValidThread());
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("data_reduction_proxy_config", R"(
+ semantics {
+ sender: "Data Reduction Proxy"
+ description:
+ "Requests a configuration that specifies how to connect to the "
+ "data reduction proxy."
+ trigger:
+ "Requested when Data Saver is enabled and the browser does not "
+ "have a configuration that is not older than a threshold set by "
+ "the server."
+ data: "None."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can control Data Saver on Android via 'Data Saver' setting. "
+ "Data Saver is not available on iOS, and on desktop it is enabled "
+ "by insalling the Data Saver extension."
+ policy_exception_justification: "Not implemented."
+ })");
std::unique_ptr<net::URLFetcher> fetcher(net::URLFetcher::Create(
- secure_proxy_check_url, net::URLFetcher::POST, this));
+ secure_proxy_check_url, net::URLFetcher::POST, this, traffic_annotation));
data_use_measurement::DataUseUserData::AttachToFetcher(
fetcher.get(),
data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY);
- fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY);
+ fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY | net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
fetcher->SetUploadData("application/x-protobuf", request_body);
DCHECK(url_request_context_getter_);
fetcher->SetRequestContext(url_request_context_getter_);
// |fetcher| should not retry on 5xx errors since the server may already be
// overloaded. Spurious 5xx errors are still retried on exponential backoff.
- // |fetcher| should not retry on network changes since a new fetch will be
- // initiated.
- fetcher->SetAutomaticallyRetryOnNetworkChanges(0);
+ // |fetcher| should retry on network changes since the network stack may
+ // receive the connection change event later than |this|.
+ static const int kMaxRetries = 5;
+ fetcher->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries);
return fetcher;
}
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
index 1a5cffc1935..2c798fa7c3b 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
@@ -14,6 +14,7 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
@@ -35,6 +36,7 @@
#include "net/http/http_response_headers.h"
#include "net/proxy/proxy_server.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -1091,8 +1093,9 @@ TEST_F(DataReductionProxyConfigServiceClientTest, HTTPRequests) {
net::TestDelegate test_delegate;
std::unique_ptr<net::URLRequest> request(
- test_url_request_context()->CreateRequest(GURL(tests[i].url), net::IDLE,
- &test_delegate));
+ test_url_request_context()->CreateRequest(
+ GURL(tests[i].url), net::IDLE, &test_delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
request->Start();
RunUntilIdle();
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
index 05b59b391e3..9a96c341552 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
@@ -117,6 +117,11 @@ class TestDataReductionProxyConfig : public DataReductionProxyConfig {
// Sets if the captive portal probe has been blocked for the current network.
void SetIsCaptivePortal(bool is_captive_portal);
+ void SetConnectionTypeForTesting(
+ net::NetworkChangeNotifier::ConnectionType connection_type) {
+ connection_type_ = connection_type;
+ }
+
using DataReductionProxyConfig::UpdateConfigForTesting;
private:
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index f70b5e700b8..ed3784b1b06 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -19,12 +19,14 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/strings/safe_sprintf.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
@@ -34,10 +36,13 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
+#include "components/previews/core/previews_decider.h"
+#include "components/previews/core/previews_experiments.h"
#include "components/variations/variations_associated_data.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
@@ -49,6 +54,7 @@
#include "net/nqe/network_quality_estimator_test_util.h"
#include "net/proxy/proxy_server.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request.h"
@@ -78,6 +84,28 @@ std::string GetRetryMapKeyFromOrigin(const std::string& origin) {
return origin;
}
+class TestPreviewsDecider : public previews::PreviewsDecider {
+ public:
+ TestPreviewsDecider(bool allow_previews) : allow_previews_(allow_previews) {}
+ ~TestPreviewsDecider() override {}
+
+ // previews::PreviewsDecider:
+ bool ShouldAllowPreviewAtECT(
+ const net::URLRequest& request,
+ previews::PreviewsType type,
+ net::EffectiveConnectionType effective_connection_type_threshold)
+ const override {
+ return allow_previews_;
+ }
+ bool ShouldAllowPreview(const net::URLRequest& request,
+ previews::PreviewsType type) const override {
+ return allow_previews_;
+ }
+
+ private:
+ bool allow_previews_;
+};
+
} // namespace
class DataReductionProxyConfigTest : public testing::Test {
@@ -811,90 +839,199 @@ TEST_F(DataReductionProxyConfigTest, IsDataReductionProxyWithMutableConfig) {
TEST_F(DataReductionProxyConfigTest, LoFiOn) {
const struct {
- bool lofi_switch_enabled;
+ bool lofi_enabled;
+ bool previews_black_list_used;
const std::string lofi_field_trial_group_name;
bool network_prohibitively_slow;
bool expect_lofi_header;
int bucket_to_check_for_auto_lofi_uma;
int expect_bucket_count;
+ bool is_opted_out;
} tests[] = {
{
// The Lo-Fi switch is off and the user is not in the enabled field
// trial group. Lo-Fi should not be used.
- false, std::string(), false, false, 0,
+ false, false, std::string(), false, false, 0,
0, // not in enabled field trial, UMA is not recorded
+ false,
},
{
// The Lo-Fi switch is off and the user is not in enabled field trial
// group and the network quality is bad. Lo-Fi should not be used.
- false, std::string(), true, false, 0,
+ false, false, std::string(), true, false, 0,
+ 0, // not in enabled field trial, UMA is not recorded
+ false,
+
+ },
+ {
+ // Lo-Fi is enabled through command line switch, but opted out. LoFi
+ // should not be used.
+ true, false, std::string(), false, false, 0,
0, // not in enabled field trial, UMA is not recorded
+ true,
},
{
// Lo-Fi is enabled through command line switch. LoFi should be used.
- true, std::string(), false, true, 0,
+ true, false, std::string(), false, true, 0,
0, // not in enabled field trial, UMA is not recorded
+ false,
},
{
// The user is in the enabled field trial group but the network
// quality is not bad. Lo-Fi should not be used.
- false, "Enabled", false, false,
+ false, false, "Enabled", false, false,
0, // Lo-Fi request header is not used (state change: empty to empty)
- 1,
+ 1, false,
},
{
// The user is in the enabled field trial group but the network
// quality is not bad. Lo-Fi should not be used.
- false, "Enabled_Control", false, false,
+ false, false, "Enabled_Control", false, false,
0, // Lo-Fi request header is not used (state change: empty to empty)
- 1,
+ 1, false,
},
{
// The user is in the enabled field trial group and the network
// quality is bad. Lo-Fi should be used.
- false, "Enabled", true, true,
+ false, false, "Enabled", true, true,
1, // Lo-Fi request header is now used (state change: empty to low)
- 1,
+ 1, false,
},
{
// The user is in the enabled field trial group and the network
// quality is bad. Lo-Fi should be used.
- false, "Enabled_Control", true, true,
+ false, false, "Enabled_Control", true, true,
3, // Lo-Fi request header is now used (state change: low to low)
- 1,
+ 1, false,
},
{
// The user is in the enabled field trial group and the network
// quality is bad. Lo-Fi should be used again.
- false, "Enabled", true, true,
+ false, false, "Enabled", true, true,
3, // Lo-Fi request header is now used (state change: low to low)
- 1,
+ 1, false,
},
{
// The user is in the enabled field trial group and the network
// quality is bad. Lo-Fi should be used again.
- false, "Enabled_Control", true, true,
+ false, false, "Enabled_Control", true, true,
3, // Lo-Fi request header is now used (state change: low to low)
- 1,
+ 1, false,
},
{
// The user is in the enabled field trial group but the network
// quality is not bad. Lo-Fi should not be used.
- false, "Enabled", false, false,
+ false, false, "Enabled", false, false,
2, // Lo-Fi request header is not used (state change: low to empty)
- 1,
+ 1, false,
},
{
// The user is in the enabled field trial group but the network
// quality is not bad. Lo-Fi should not be used.
- false, "Enabled_Control", false, false,
+ false, false, "Enabled_Control", false, false,
0, // Lo-Fi request header is not used (state change: empty to empty)
- 1,
+ 1, false,
+ },
+ {
+ // The Lo-Fi switch is off and the user is not in the enabled field
+ // trial group. Lo-Fi should not be used.
+ false, true, std::string(), false, false, 0,
+ 0, // not in enabled field trial, UMA is not recorded
+ false,
+ },
+ {
+ // The Lo-Fi switch is off and the user is not in enabled field trial
+ // group and the network quality is bad. Lo-Fi should not be used.
+ false, true, std::string(), true, false, 0,
+ 0, // not in enabled field trial, UMA is not recorded
+ false,
+ },
+ {
+ // Lo-Fi is enabled through command line switch. LoFi should be used.
+ true, true, std::string(), false, true, 0,
+ 0, // not in enabled field trial, UMA is not recorded
+ false,
+ },
+ {
+ // Lo-Fi is enabled through command line switch, but opted out. LoFi
+ // should not be used.
+ true, true, std::string(), false, false, 0,
+ 0, // not in enabled field trial, UMA is not recorded
+ true,
+ },
+ {
+ // The user is in the enabled field trial group but the network
+ // quality is not bad. Lo-Fi should not be used.
+ false, true, "Enabled", false, false,
+ 0, // Lo-Fi request header is not used (state change: empty to empty)
+ 1, false,
+ },
+ {
+ // The user is in the enabled field trial group but the network
+ // quality is not bad. Lo-Fi should not be used.
+ false, true, "Enabled_Control", false, false,
+ 0, // Lo-Fi request header is not used (state change: empty to empty)
+ 1, false,
+ },
+ {
+ // The user is in the enabled field trial group and the network
+ // quality is bad. Lo-Fi should be used.
+ false, true, "Enabled", true, true,
+ 1, // Lo-Fi request header is now used (state change: empty to low)
+ 1, false,
+ },
+ {
+ // The user is in the enabled field trial group and the network
+ // quality is bad. Lo-Fi should be used.
+ false, true, "Enabled_Control", true, true,
+ 3, // Lo-Fi request header is now used (state change: low to low)
+ 1, false,
+ },
+ {
+ // The user is in the enabled field trial group and the network
+ // quality is bad. Lo-Fi should be used again.
+ false, true, "Enabled", true, true,
+ 3, // Lo-Fi request header is now used (state change: low to low)
+ 1, false,
+ },
+ {
+ // The user is in the enabled field trial group and the network
+ // quality is bad. Lo-Fi should be used again.
+ false, true, "Enabled_Control", true, true,
+ 3, // Lo-Fi request header is now used (state change: low to low)
+ 1, false,
+ },
+ {
+ // The user is in the enabled field trial group but the network
+ // quality is not bad. Lo-Fi should not be used.
+ false, true, "Enabled", false, false,
+ 2, // Lo-Fi request header is not used (state change: low to empty)
+ 1, false,
+ },
+ {
+ // The user is in the enabled field trial group but the network
+ // quality is not bad. Lo-Fi should not be used.
+ false, true, "Enabled_Control", false, false,
+ 0, // Lo-Fi request header is not used (state change: empty to empty)
+ 1, false,
},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
config()->ResetLoFiStatusForTest();
- if (tests[i].lofi_switch_enabled) {
+
+ // Ensure not using proxy-decides-transform feature.
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ base::FieldTrialList field_trial_list(nullptr);
+ if (tests[i].previews_black_list_used) {
+ base::FieldTrialList::CreateFieldTrial(
+ "DataReductionProxyPreviewsBlackListTransition", "Enabled_");
+ } else if (tests[i].is_opted_out) {
+ config()->SetLoFiModeOff();
+ }
+ if (tests[i].lofi_enabled) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kDataReductionProxyLoFi,
switches::kDataReductionProxyLoFiValueAlwaysOn);
@@ -903,7 +1040,6 @@ TEST_F(DataReductionProxyConfigTest, LoFiOn) {
switches::kDataReductionProxyLoFi, std::string());
}
- base::FieldTrialList field_trial_list(nullptr);
if (!tests[i].lofi_field_trial_group_name.empty()) {
base::FieldTrialList::CreateFieldTrial(
params::GetLoFiFieldTrialName(),
@@ -916,11 +1052,14 @@ TEST_F(DataReductionProxyConfigTest, LoFiOn) {
base::HistogramTester histogram_tester;
net::TestURLRequestContext context_;
net::TestDelegate delegate_;
- std::unique_ptr<net::URLRequest> request =
- context_.CreateRequest(GURL(), net::IDLE, &delegate_);
+ std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+ GURL(), net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
request->SetLoadFlags(request->load_flags() |
net::LOAD_MAIN_FRAME_DEPRECATED);
- bool should_enable_lofi = config()->ShouldEnableLoFi(*request.get());
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(!tests[i].is_opted_out);
+ bool should_enable_lofi =
+ config()->ShouldEnableLoFi(*request.get(), *previews_decider.get());
if (tests[i].expect_bucket_count != 0) {
histogram_tester.ExpectBucketCount(
"DataReductionProxy.AutoLoFiRequestHeaderState.Unknown",
@@ -1262,4 +1401,346 @@ TEST_F(DataReductionProxyConfigTest, LoFiAccuracyNonZeroDelay) {
"DataReductionProxy.LoFi.Accuracy.1.Unknown", 0, 1);
}
+TEST_F(DataReductionProxyConfigTest, ShouldEnableLoFiDoesNotFallback) {
+ // Turn off proxy-decides-transform feature (path for client ECT check).
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ // Enable Server Lo-Fi.
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueAlwaysOn);
+
+ // Also enable LitePages
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableDataReductionProxyLitePage);
+
+ net::TestURLRequestContext context;
+ net::TestDelegate delegate;
+ std::unique_ptr<net::URLRequest> request = context.CreateRequest(
+ GURL(), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->SetLoadFlags(request->load_flags() |
+ net::LOAD_MAIN_FRAME_DEPRECATED);
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(false);
+
+ EXPECT_TRUE(
+ config()->ShouldEnableLitePages(*request.get(), *previews_decider.get()));
+ EXPECT_FALSE(
+ config()->ShouldEnableLoFi(*request.get(), *previews_decider.get()));
+}
+
+TEST_F(DataReductionProxyConfigTest, ShouldEnableLoFiWithECTCheck) {
+ // Turn off proxy-decides-transform feature (so will locally check ECT).
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ // Enable Server Lo-Fi field trial.
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+ "Enabled");
+
+ EXPECT_CALL(*config(), IsNetworkQualityProhibitivelySlow(_))
+ .WillRepeatedly(testing::Return(true));
+
+ net::TestURLRequestContext context;
+ net::TestDelegate delegate;
+ std::unique_ptr<net::URLRequest> request = context.CreateRequest(
+ GURL(), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->SetLoadFlags(request->load_flags() |
+ net::LOAD_MAIN_FRAME_DEPRECATED);
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(false);
+
+ EXPECT_TRUE(
+ config()->ShouldEnableLoFi(*request.get(), *previews_decider.get()));
+
+ // Now verify should not enable with good network connection.
+ EXPECT_CALL(*config(), IsNetworkQualityProhibitivelySlow(_))
+ .WillRepeatedly(testing::Return(false));
+
+ EXPECT_FALSE(
+ config()->ShouldEnableLoFi(*request.get(), *previews_decider.get()));
+}
+
+TEST_F(DataReductionProxyConfigTest, ShouldEnableLoFiWithoutECTCheck) {
+ // Turn on proxy-decides-transform feature (so will not locally check ECT).
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ // Enable Server Lo-Fi field trial.
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+ "Enabled");
+
+ // Expect network quality check is never called.
+ EXPECT_CALL(*config(), IsNetworkQualityProhibitivelySlow(_)).Times(0);
+
+ net::TestURLRequestContext context;
+ net::TestDelegate delegate;
+ std::unique_ptr<net::URLRequest> request = context.CreateRequest(
+ GURL(), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->SetLoadFlags(request->load_flags() |
+ net::LOAD_MAIN_FRAME_DEPRECATED);
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(false);
+
+ EXPECT_TRUE(
+ config()->ShouldEnableLoFi(*request.get(), *previews_decider.get()));
+}
+
+TEST_F(DataReductionProxyConfigTest, ShouldEnableLitePagesWithECTCheck) {
+ // Turn off proxy-decides-transform feature (so will locally check ECT).
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ // Enable Server Lo-Fi field trial.
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+ "Enabled_Preview");
+
+ EXPECT_CALL(*config(), IsNetworkQualityProhibitivelySlow(_))
+ .WillRepeatedly(testing::Return(true));
+
+ net::TestURLRequestContext context;
+ net::TestDelegate delegate;
+ std::unique_ptr<net::URLRequest> request = context.CreateRequest(
+ GURL(), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->SetLoadFlags(request->load_flags() |
+ net::LOAD_MAIN_FRAME_DEPRECATED);
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(false);
+
+ EXPECT_TRUE(
+ config()->ShouldEnableLitePages(*request.get(), *previews_decider.get()));
+
+ // Now verify should not enable with good network connection.
+ EXPECT_CALL(*config(), IsNetworkQualityProhibitivelySlow(_))
+ .WillRepeatedly(testing::Return(false));
+
+ EXPECT_FALSE(
+ config()->ShouldEnableLitePages(*request.get(), *previews_decider.get()));
+}
+
+TEST_F(DataReductionProxyConfigTest, ShouldEnableLitePagesWithoutECTCheck) {
+ // Turn on proxy-decides-transform feature (so will not locally check ECT).
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ // Enable Server Lo-Fi field trial.
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+ "Enabled_Preview");
+
+ // Expect network quality check is never called.
+ EXPECT_CALL(*config(), IsNetworkQualityProhibitivelySlow(_)).Times(0);
+
+ net::TestURLRequestContext context_;
+ net::TestDelegate delegate_;
+ std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+ GURL(), net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->SetLoadFlags(request->load_flags() |
+ net::LOAD_MAIN_FRAME_DEPRECATED);
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(false);
+
+ EXPECT_TRUE(
+ config()->ShouldEnableLitePages(*request.get(), *previews_decider.get()));
+}
+
+TEST_F(DataReductionProxyConfigTest, ShouldAcceptServerLoFi) {
+ // Turn on proxy-decides-transform feature to satisfy DCHECK.
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ net::TestURLRequestContext context_;
+ net::TestDelegate delegate_;
+ std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+ GURL(), net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->SetLoadFlags(request->load_flags() |
+ net::LOAD_MAIN_FRAME_DEPRECATED);
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(false);
+
+ // Verify false for no flags.
+ EXPECT_FALSE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+
+ // Verify true for Always-On flag.
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueAlwaysOn);
+ EXPECT_TRUE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+
+ // Verify true for Always-On with LitePages enabled too.
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueAlwaysOn);
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableDataReductionProxyLitePage);
+ EXPECT_TRUE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+
+ // Verify true for Slow Connection flag.
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueSlowConnectionsOnly);
+ EXPECT_TRUE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+
+ // Verify false for Cellular Only flag and WIFI connection.
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueCellularOnly);
+ config()->SetConnectionTypeForTesting(
+ net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI);
+ EXPECT_FALSE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+
+ // Verify true for Cellular Only flag and 3G connection.
+ config()->SetConnectionTypeForTesting(
+ net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G);
+ EXPECT_TRUE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+
+ // Verify true for field trial.
+ {
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+ "Enabled");
+ EXPECT_TRUE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+ }
+
+ // Verify false for control field trial.
+ {
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+ "Control");
+ EXPECT_FALSE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+ }
+
+ // Verify PreviewsDecider check.
+ {
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueAlwaysOn);
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(
+ "DataReductionProxyPreviewsBlackListTransition", "Enabled");
+ EXPECT_FALSE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+ previews_decider = base::MakeUnique<TestPreviewsDecider>(true);
+ EXPECT_TRUE(config()->ShouldAcceptServerLoFi(*request.get(),
+ *previews_decider.get()));
+ }
+}
+
+TEST_F(DataReductionProxyConfigTest, ShouldAcceptLitePages) {
+ // Turn on proxy-decides-transform feature to satisfy DCHECK.
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(
+ features::kDataReductionProxyDecidesTransform);
+
+ net::TestURLRequestContext context_;
+ net::TestDelegate delegate_;
+ std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+ GURL(), net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->SetLoadFlags(request->load_flags() |
+ net::LOAD_MAIN_FRAME_DEPRECATED);
+ std::unique_ptr<TestPreviewsDecider> previews_decider =
+ base::MakeUnique<TestPreviewsDecider>(false);
+
+ // Verify false for no flags.
+ EXPECT_FALSE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+
+ // Verify true for Always-On flag and LitePage flag.
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueAlwaysOn);
+ EXPECT_FALSE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableDataReductionProxyLitePage);
+ EXPECT_TRUE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+
+ // Verify true for Slow Connection flag and LitePage flag.
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueSlowConnectionsOnly);
+ EXPECT_FALSE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableDataReductionProxyLitePage);
+ EXPECT_TRUE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+
+ // Verify true for Cellular Only flag and 3G connection.
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueCellularOnly);
+ config()->SetConnectionTypeForTesting(
+ net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G);
+ EXPECT_FALSE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableDataReductionProxyLitePage);
+ EXPECT_TRUE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+
+ // Verify false for Cellular Only flag and WIFI connection.
+ config()->SetConnectionTypeForTesting(
+ net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI);
+ EXPECT_FALSE(
+ config()->ShouldAcceptLitePages(*request.get(), *previews_decider.get()));
+
+ // Verify true for field trial.
+ {
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(params::GetLoFiFieldTrialName(),
+ "Enabled_Preview");
+ EXPECT_TRUE(config()->ShouldAcceptLitePages(*request.get(),
+ *previews_decider.get()));
+ }
+
+ // Verify PreviewsDecider check.
+ {
+ base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueAlwaysOn);
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableDataReductionProxyLitePage);
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(
+ "DataReductionProxyPreviewsBlackListTransition", "Enabled");
+ EXPECT_FALSE(config()->ShouldAcceptLitePages(*request.get(),
+ *previews_decider.get()));
+ previews_decider = base::MakeUnique<TestPreviewsDecider>(true);
+ EXPECT_TRUE(config()->ShouldAcceptLitePages(*request.get(),
+ *previews_decider.get()));
+ }
+}
+
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc
index 425d1be797f..8d134ee644e 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc
@@ -4,6 +4,7 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
+#include "base/memory/ptr_util.h"
#include "net/url_request/url_request.h"
namespace data_reduction_proxy {
@@ -14,6 +15,7 @@ const void* const kDataReductionProxyUserDataKey =
DataReductionProxyData::DataReductionProxyData()
: used_data_reduction_proxy_(false),
lofi_requested_(false),
+ client_lofi_requested_(false),
lite_page_received_(false),
lofi_received_(false),
effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {}
@@ -25,6 +27,7 @@ std::unique_ptr<DataReductionProxyData> DataReductionProxyData::DeepCopy()
std::unique_ptr<DataReductionProxyData> copy(new DataReductionProxyData());
copy->used_data_reduction_proxy_ = used_data_reduction_proxy_;
copy->lofi_requested_ = lofi_requested_;
+ copy->client_lofi_requested_ = client_lofi_requested_;
copy->lite_page_received_ = lite_page_received_;
copy->lofi_received_ = lofi_received_;
copy->session_key_ = session_key_;
@@ -49,7 +52,7 @@ DataReductionProxyData* DataReductionProxyData::GetDataAndCreateIfNecessary(
if (data)
return data;
data = new DataReductionProxyData();
- request->SetUserData(kDataReductionProxyUserDataKey, data);
+ request->SetUserData(kDataReductionProxyUserDataKey, base::WrapUnique(data));
return data;
}
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h
index 1f12d47e502..55b792b0239 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h
@@ -53,6 +53,14 @@ class DataReductionProxyData : public base::SupportsUserData::Data {
bool lofi_received() const { return lofi_received_; }
void set_lofi_received(bool lofi_received) { lofi_received_ = lofi_received; }
+ // Whether client Lo-Fi was requested for this request. This is only set on
+ // image requests that have added a range header to attempt to get a smaller
+ // file size image.
+ bool client_lofi_requested() const { return client_lofi_requested_; }
+ void set_client_lofi_requested(bool client_lofi_requested) {
+ client_lofi_requested_ = client_lofi_requested;
+ }
+
// The session key used for this request. Only set for main frame requests.
std::string session_key() const { return session_key_; }
void set_session_key(const std::string& session_key) {
@@ -99,11 +107,16 @@ class DataReductionProxyData : public base::SupportsUserData::Data {
// Whether the DataReductionProxy was used for this request or navigation.
bool used_data_reduction_proxy_;
- // Whether Lo-Fi was requested for this request or navigation. True if the
- // session is in Lo-Fi control or enabled group, and the network quality is
- // slow.
+ // Whether server Lo-Fi was requested for this request or navigation. True if
+ // the session is in Lo-Fi control or enabled group, and the network quality
+ // is slow.
bool lofi_requested_;
+ // Whether client Lo-Fi was requested for this request. This is only set on
+ // image requests that have added a range header to attempt to get a smaller
+ // file size image.
+ bool client_lofi_requested_;
+
// Whether a lite page response was seen for the request or navigation.
bool lite_page_received_;
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc
index 8ba21079bf2..a7deafb2582 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc
@@ -13,6 +13,7 @@
#include "base/message_loop/message_loop.h"
#include "net/base/request_priority.h"
#include "net/nqe/effective_connection_type.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -81,7 +82,8 @@ TEST_F(DataReductionProxyDataTest, BasicSettersAndGetters) {
TEST_F(DataReductionProxyDataTest, AddToURLRequest) {
std::unique_ptr<net::URLRequestContext> context(new net::URLRequestContext());
std::unique_ptr<net::URLRequest> fake_request(context->CreateRequest(
- GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr));
+ GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
DataReductionProxyData* data =
DataReductionProxyData::GetData(*fake_request.get());
EXPECT_FALSE(data);
@@ -142,7 +144,8 @@ TEST_F(DataReductionProxyDataTest, DeepCopy) {
TEST_F(DataReductionProxyDataTest, ClearData) {
std::unique_ptr<net::URLRequestContext> context(new net::URLRequestContext());
std::unique_ptr<net::URLRequest> fake_request(context->CreateRequest(
- GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr));
+ GURL("http://www.google.com"), net::RequestPriority::IDLE, nullptr,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
DataReductionProxyData* data =
DataReductionProxyData::GetDataAndCreateIfNecessary(fake_request.get());
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc
new file mode 100644
index 00000000000..8d433aefdbc
--- /dev/null
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc
@@ -0,0 +1,167 @@
+// Copyright 2017 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/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h"
+
+#include "base/memory/ptr_util.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
+#include "components/data_reduction_proxy/core/common/lofi_decider.h"
+#include "components/data_use_measurement/core/data_use.h"
+#include "components/data_use_measurement/core/data_use_ascriber.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request.h"
+#include "url/gurl.h"
+
+namespace {
+
+class DataUseUserDataBytes : public base::SupportsUserData::Data {
+ public:
+ // Key used to store data usage in userdata until the page URL is available.
+ static const void* kUserDataKey;
+
+ DataUseUserDataBytes(int64_t network_bytes, int64_t original_bytes)
+ : network_bytes_(network_bytes), original_bytes_(original_bytes) {}
+
+ int64_t network_bytes() const { return network_bytes_; }
+ int64_t original_bytes() const { return original_bytes_; }
+
+ void IncrementBytes(int64_t network_bytes, int64_t original_bytes) {
+ network_bytes_ += network_bytes;
+ original_bytes_ += original_bytes;
+ }
+
+ private:
+ int64_t network_bytes_;
+ int64_t original_bytes_;
+};
+
+// static
+const void* DataUseUserDataBytes::kUserDataKey =
+ &DataUseUserDataBytes::kUserDataKey;
+
+// Estimate the size of the original headers of |request|. If |used_drp| is
+// true, then it's assumed that the original request would have used HTTP/1.1,
+// otherwise it assumes that the original request would have used the same
+// protocol as |request| did. This is to account for stuff like HTTP/2 header
+// compression.
+int64_t EstimateOriginalHeaderBytes(const net::URLRequest& request,
+ bool used_drp) {
+ if (used_drp) {
+ // TODO(sclittle): Remove headers added by Data Reduction Proxy when
+ // computing original size. https://crbug.com/535701.
+ return request.response_headers()->raw_headers().size();
+ }
+ return std::max<int64_t>(0, request.GetTotalReceivedBytes() -
+ request.received_response_content_length());
+}
+
+// Given a |request| that went through the Data Reduction Proxy if |used_drp| is
+// true, this function estimates how many bytes would have been received if the
+// response had been received directly from the origin without any data saver
+// optimizations.
+int64_t EstimateOriginalReceivedBytes(
+ const net::URLRequest& request,
+ bool used_drp,
+ const data_reduction_proxy::LoFiDecider* lofi_decider) {
+ if (request.was_cached() || !request.response_headers())
+ return request.GetTotalReceivedBytes();
+
+ if (lofi_decider) {
+ if (lofi_decider->IsClientLoFiAutoReloadRequest(request))
+ return 0;
+
+ int64_t first, last, length;
+ if (lofi_decider->IsClientLoFiImageRequest(request) &&
+ request.response_headers()->GetContentRangeFor206(&first, &last,
+ &length) &&
+ length > request.received_response_content_length()) {
+ return EstimateOriginalHeaderBytes(request, used_drp) + length;
+ }
+ }
+
+ return used_drp
+ ? EstimateOriginalHeaderBytes(request, used_drp) +
+ data_reduction_proxy::util::CalculateEffectiveOCL(request)
+ : request.GetTotalReceivedBytes();
+}
+
+} // namespace
+
+namespace data_reduction_proxy {
+
+DataReductionProxyDataUseObserver::DataReductionProxyDataUseObserver(
+ DataReductionProxyIOData* data_reduction_proxy_io_data,
+ data_use_measurement::DataUseAscriber* data_use_ascriber)
+ : data_reduction_proxy_io_data_(data_reduction_proxy_io_data),
+ data_use_ascriber_(data_use_ascriber) {
+ DCHECK(data_reduction_proxy_io_data_);
+ data_use_ascriber_->AddObserver(this);
+}
+
+DataReductionProxyDataUseObserver::~DataReductionProxyDataUseObserver() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ data_use_ascriber_->RemoveObserver(this);
+}
+
+void DataReductionProxyDataUseObserver::OnPageLoadCommit(
+ data_use_measurement::DataUse* data_use) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (!data_use->url().is_valid())
+ return;
+ DataUseUserDataBytes* bytes = reinterpret_cast<DataUseUserDataBytes*>(
+ data_use->GetUserData(DataUseUserDataBytes::kUserDataKey));
+ if (bytes) {
+ // Record the data use bytes saved in user data to database.
+ data_reduction_proxy_io_data_->UpdateDataUseForHost(
+ bytes->network_bytes(), bytes->original_bytes(),
+ data_use->url().HostNoBrackets());
+ data_use->RemoveUserData(DataUseUserDataBytes::kUserDataKey);
+ }
+}
+
+void DataReductionProxyDataUseObserver::OnPageResourceLoad(
+ const net::URLRequest& request,
+ data_use_measurement::DataUse* data_use) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (data_use->traffic_type() !=
+ data_use_measurement::DataUse::TrafficType::USER_TRAFFIC)
+ return;
+
+ int64_t network_bytes = request.GetTotalReceivedBytes();
+ DataReductionProxyRequestType request_type = GetDataReductionProxyRequestType(
+ request, data_reduction_proxy_io_data_->configurator()->GetProxyConfig(),
+ *data_reduction_proxy_io_data_->config());
+
+ // Estimate how many bytes would have been used if the DataReductionProxy was
+ // not used, and record the data usage.
+ int64_t original_bytes = EstimateOriginalReceivedBytes(
+ request, request_type == VIA_DATA_REDUCTION_PROXY,
+ data_reduction_proxy_io_data_->lofi_decider());
+
+ if (!data_use->url().is_valid()) {
+ // URL will be empty until pageload navigation commits. Save the data use of
+ // these mainframe, subresource, redirected requests in user data until
+ // then.
+ DataUseUserDataBytes* bytes = reinterpret_cast<DataUseUserDataBytes*>(
+ data_use->GetUserData(DataUseUserDataBytes::kUserDataKey));
+ if (bytes) {
+ bytes->IncrementBytes(network_bytes, original_bytes);
+ } else {
+ data_use->SetUserData(DataUseUserDataBytes::kUserDataKey,
+ base::MakeUnique<DataUseUserDataBytes>(
+ network_bytes, original_bytes));
+ }
+ } else {
+ data_reduction_proxy_io_data_->UpdateDataUseForHost(
+ network_bytes, original_bytes, data_use->url().HostNoBrackets());
+ }
+}
+
+} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h
new file mode 100644
index 00000000000..aec49c3ec62
--- /dev/null
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h
@@ -0,0 +1,57 @@
+// Copyright 2017 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_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_DATA_USE_OBSERVER_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_DATA_USE_OBSERVER_H_
+
+#include "base/macros.h"
+#include "base/threading/thread_checker.h"
+#include "components/data_use_measurement/core/data_use.h"
+#include "components/data_use_measurement/core/data_use_ascriber.h"
+
+namespace net {
+class URLRequest;
+}
+
+namespace data_reduction_proxy {
+
+class DataReductionProxyIOData;
+
+// Observers the page load events from DataUseAscriber and records the data
+// usage per site to database.
+class DataReductionProxyDataUseObserver
+ : public data_use_measurement::DataUseAscriber::PageLoadObserver {
+ public:
+ // |data_reduction_proxy_io_data| is used to record the bytes to database.
+ // |data_use_ascriber| is used to listen for events.
+ // |this| is owned by |data_reduction_proxy_io_data|.
+ DataReductionProxyDataUseObserver(
+ DataReductionProxyIOData* data_reduction_proxy_io_data,
+ data_use_measurement::DataUseAscriber* data_use_ascriber);
+
+ ~DataReductionProxyDataUseObserver() override;
+
+ private:
+ // PageLoadObserver methods.
+ void OnPageLoadCommit(data_use_measurement::DataUse* data_use) override;
+ void OnPageResourceLoad(const net::URLRequest& request,
+ data_use_measurement::DataUse* data_use) override;
+ void OnPageLoadComplete(data_use_measurement::DataUse* data_use) override {}
+
+ // |data_reduction_proxy_io_data_| owns |this| and is destroyed only after
+ // |this| is destroyed in the IO thread.
+ DataReductionProxyIOData* data_reduction_proxy_io_data_;
+
+ // Used to register for pageload events. |data_use_ascriber_| is owned by IO
+ // thread globals, and is destroyed after |this|.
+ data_use_measurement::DataUseAscriber* data_use_ascriber_;
+
+ THREAD_CHECKER(thread_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(DataReductionProxyDataUseObserver);
+};
+
+} // namespace data_reduction_proxy
+
+#endif // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_DATA_USE_OBSERVER_H_
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
index 12c809f54e4..4985301b706 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc
@@ -24,6 +24,7 @@
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_server.h"
#include "net/proxy/proxy_service.h"
namespace data_reduction_proxy {
@@ -85,7 +86,9 @@ void DataReductionProxyDelegate::OnResolveProxy(
}
std::vector<DataReductionProxyServer> proxies_for_http =
- config_->GetProxiesForHttp();
+ params::IsIncludedInHoldbackFieldTrial()
+ ? std::vector<DataReductionProxyServer>()
+ : config_->GetProxiesForHttp();
// Remove the proxies that are unsupported for this request.
proxies_for_http.erase(
@@ -216,30 +219,6 @@ void DataReductionProxyDelegate::OnAlternativeProxyBroken(
1);
}
-net::ProxyServer DataReductionProxyDelegate::GetDefaultAlternativeProxy()
- const {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!params::IsZeroRttQuicEnabled())
- return net::ProxyServer();
-
- if (alternative_proxies_broken_) {
- RecordGetDefaultAlternativeProxy(DEFAULT_ALTERNATIVE_PROXY_STATUS_BROKEN);
- return net::ProxyServer();
- }
-
- net::ProxyServer proxy_server(
- net::ProxyServer::SCHEME_QUIC,
- net::HostPortPair(kDataReductionCoreProxy, 443));
- if (!config_ || !config_->IsDataReductionProxy(proxy_server, NULL)) {
- RecordGetDefaultAlternativeProxy(
- DEFAULT_ALTERNATIVE_PROXY_STATUS_UNAVAILABLE);
- return net::ProxyServer();
- }
-
- RecordGetDefaultAlternativeProxy(DEFAULT_ALTERNATIVE_PROXY_STATUS_AVAILABLE);
- return proxy_server;
-}
-
bool DataReductionProxyDelegate::SupportsQUIC(
const net::ProxyServer& proxy_server) const {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -257,13 +236,6 @@ void DataReductionProxyDelegate::RecordQuicProxyStatus(
QUIC_PROXY_STATUS_BOUNDARY);
}
-void DataReductionProxyDelegate::RecordGetDefaultAlternativeProxy(
- DefaultAlternativeProxyStatus status) const {
- DCHECK(thread_checker_.CalledOnValidThread());
- UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.Quic.DefaultAlternativeProxy",
- status, DEFAULT_ALTERNATIVE_PROXY_STATUS_BOUNDARY);
-}
-
void DataReductionProxyDelegate::OnIPAddressChanged() {
DCHECK(thread_checker_.CalledOnValidThread());
first_data_saver_request_recorded_ = false;
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h
index d412dc3b1cc..7179998df49 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h
@@ -12,7 +12,6 @@
#include "net/base/network_change_notifier.h"
#include "net/base/proxy_delegate.h"
#include "net/proxy/proxy_retry_info.h"
-#include "net/proxy/proxy_server.h"
#include "url/gurl.h"
namespace base {
@@ -26,6 +25,7 @@ class HttpResponseHeaders;
class NetLog;
class ProxyConfig;
class ProxyInfo;
+class ProxyServer;
class ProxyService;
}
@@ -82,7 +82,6 @@ class DataReductionProxyDelegate
net::ProxyServer* alternative_proxy_server) const override;
void OnAlternativeProxyBroken(
const net::ProxyServer& alternative_proxy_server) override;
- net::ProxyServer GetDefaultAlternativeProxy() const override;
// Protected so that it can be overridden during testing.
// Returns true if |proxy_server| supports QUIC.
@@ -97,24 +96,10 @@ class DataReductionProxyDelegate
QUIC_PROXY_STATUS_BOUNDARY
};
- // Availability status of data reduction proxy that supports 0-RTT QUIC.
- // Protected so that the enum values are accessible for testing.
- enum DefaultAlternativeProxyStatus {
- DEFAULT_ALTERNATIVE_PROXY_STATUS_AVAILABLE,
- DEFAULT_ALTERNATIVE_PROXY_STATUS_BROKEN,
- DEFAULT_ALTERNATIVE_PROXY_STATUS_UNAVAILABLE,
- DEFAULT_ALTERNATIVE_PROXY_STATUS_BOUNDARY,
- };
-
private:
// Records the availability status of data reduction proxy.
void RecordQuicProxyStatus(QuicProxyStatus status) const;
- // Records the availability status of data reduction proxy that supports 0-RTT
- // QUIC.
- void RecordGetDefaultAlternativeProxy(
- DefaultAlternativeProxyStatus status) const;
-
// NetworkChangeNotifier::IPAddressObserver:
void OnIPAddressChanged() override;
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
index f7a2306fd34..5c4f2c15a4a 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
@@ -40,7 +40,6 @@
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
-#include "components/variations/variations_associated_data.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/base/network_change_notifier.h"
@@ -51,6 +50,7 @@
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_server.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -132,49 +132,9 @@ class TestDataReductionProxyDelegate : public DataReductionProxyDelegate {
}
}
- void VerifyGetDefaultAlternativeProxyHistogram(
- const base::HistogramTester& histogram_tester,
- bool is_in_quic_field_trial,
- bool use_proxyzip_proxy_as_first_proxy,
- bool alternative_proxy_broken) {
- static const char kHistogram[] =
- "DataReductionProxy.Quic.DefaultAlternativeProxy";
- if (is_in_quic_field_trial && use_proxyzip_proxy_as_first_proxy &&
- !alternative_proxy_broken) {
- histogram_tester.ExpectUniqueSample(
- kHistogram,
- TestDataReductionProxyDelegate::DefaultAlternativeProxyStatus::
- DEFAULT_ALTERNATIVE_PROXY_STATUS_AVAILABLE,
- 1);
- return;
- }
-
- if (is_in_quic_field_trial && alternative_proxy_broken) {
- histogram_tester.ExpectUniqueSample(
- kHistogram,
- TestDataReductionProxyDelegate::DefaultAlternativeProxyStatus::
- DEFAULT_ALTERNATIVE_PROXY_STATUS_BROKEN,
- 1);
- return;
- }
-
- if (is_in_quic_field_trial && !use_proxyzip_proxy_as_first_proxy) {
- histogram_tester.ExpectUniqueSample(
- kHistogram,
- TestDataReductionProxyDelegate::DefaultAlternativeProxyStatus::
- DEFAULT_ALTERNATIVE_PROXY_STATUS_UNAVAILABLE,
- 1);
- return;
- }
-
- histogram_tester.ExpectTotalCount(kHistogram, 0);
- }
-
using DataReductionProxyDelegate::GetAlternativeProxy;
using DataReductionProxyDelegate::OnAlternativeProxyBroken;
- using DataReductionProxyDelegate::GetDefaultAlternativeProxy;
using DataReductionProxyDelegate::QuicProxyStatus;
- using DataReductionProxyDelegate::DefaultAlternativeProxyStatus;
private:
const bool proxy_supports_quic_;
@@ -474,109 +434,6 @@ TEST(DataReductionProxyDelegate, AlternativeProxy) {
}
}
-// Verifies that DataReductionProxyDelegate correctly returns the proxy server
-// that supports 0-RTT.
-TEST(DataReductionProxyDelegate, DefaultAlternativeProxyStatus) {
- base::MessageLoopForIO message_loop_;
- std::unique_ptr<DataReductionProxyTestContext> test_context =
- DataReductionProxyTestContext::Builder()
- .WithConfigClient()
- .WithMockDataReductionProxyService()
- .Build();
-
- const struct {
- bool is_in_quic_field_trial;
- bool zero_rtt_param_set;
- bool use_proxyzip_proxy_as_first_proxy;
- } tests[] = {{false, false, false},
- {false, false, true},
- {true, false, false},
- {true, false, true},
- {true, true, true}};
- for (const auto test : tests) {
- std::vector<DataReductionProxyServer> proxies_for_http;
- net::ProxyServer first_proxy;
- net::ProxyServer second_proxy =
- GetProxyWithScheme(net::ProxyServer::SCHEME_HTTP);
-
- if (test.use_proxyzip_proxy_as_first_proxy) {
- first_proxy =
- net::ProxyServer(net::ProxyServer::SCHEME_QUIC,
- net::HostPortPair("proxy.googlezip.net", 443));
- } else {
- first_proxy = GetProxyWithScheme(net::ProxyServer::SCHEME_HTTPS);
- }
-
- proxies_for_http.push_back(
- DataReductionProxyServer(first_proxy, ProxyServer::CORE));
- proxies_for_http.push_back(
- DataReductionProxyServer(second_proxy, ProxyServer::UNSPECIFIED_TYPE));
-
- std::unique_ptr<DataReductionProxyMutableConfigValues> config_values =
- DataReductionProxyMutableConfigValues::CreateFromParams(
- test_context->test_params());
- config_values->UpdateValues(proxies_for_http);
-
- std::unique_ptr<DataReductionProxyConfig> config(
- new DataReductionProxyConfig(
- message_loop_.task_runner(), test_context->net_log(),
- std::move(config_values), test_context->configurator(),
- test_context->event_creator()));
-
- TestDataReductionProxyDelegate delegate(
- config.get(), test_context->io_data()->configurator(),
- test_context->io_data()->event_creator(),
- test_context->io_data()->bypass_stats(), true,
- test_context->io_data()->net_log());
-
- variations::testing::ClearAllVariationParams();
- std::map<std::string, std::string> variation_params;
- if (test.zero_rtt_param_set)
- variation_params["enable_zero_rtt"] = "true";
- ASSERT_TRUE(variations::AssociateVariationParams(
- params::GetQuicFieldTrialName(),
- test.is_in_quic_field_trial ? "Enabled" : "Control", variation_params));
- base::FieldTrialList field_trial_list(nullptr);
- base::FieldTrialList::CreateFieldTrial(
- params::GetQuicFieldTrialName(),
- test.is_in_quic_field_trial ? "Enabled" : "Control");
-
- {
- // Test if the QUIC supporting proxy is correctly set.
- base::HistogramTester histogram_tester;
- if (test.is_in_quic_field_trial && test.zero_rtt_param_set &&
- test.use_proxyzip_proxy_as_first_proxy) {
- EXPECT_EQ(delegate.GetDefaultAlternativeProxy(), first_proxy);
- EXPECT_TRUE(first_proxy.is_quic());
-
- } else {
- EXPECT_FALSE(delegate.GetDefaultAlternativeProxy().is_valid());
- }
-
- delegate.VerifyGetDefaultAlternativeProxyHistogram(
- histogram_tester,
- test.is_in_quic_field_trial && test.zero_rtt_param_set,
- test.use_proxyzip_proxy_as_first_proxy, false);
- }
-
- {
- // Test if the QUIC supporting proxy is correctly set if the proxy is
- // marked as broken.
- base::HistogramTester histogram_tester;
-
- if (test.is_in_quic_field_trial && test.zero_rtt_param_set &&
- test.use_proxyzip_proxy_as_first_proxy) {
- delegate.OnAlternativeProxyBroken(first_proxy);
- EXPECT_FALSE(delegate.GetDefaultAlternativeProxy().is_quic());
- delegate.VerifyGetDefaultAlternativeProxyHistogram(
- histogram_tester,
- test.is_in_quic_field_trial && test.zero_rtt_param_set,
- test.use_proxyzip_proxy_as_first_proxy, true);
- }
- }
- }
-}
-
#if defined(OS_ANDROID)
const Client kClient = Client::CHROME_ANDROID;
#elif defined(OS_IOS)
@@ -658,8 +515,8 @@ class DataReductionProxyDelegateTest : public testing::Test {
mock_socket_factory_.AddSocketDataProvider(&socket);
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request =
- context_.CreateRequest(url, net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
+ url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
if (request_headers)
request->SetExtraRequestHeaders(*request_headers);
@@ -1003,6 +860,36 @@ TEST_F(DataReductionProxyDelegateTest, TimeToFirstHttpDataSaverRequest) {
}
}
+TEST_F(DataReductionProxyDelegateTest, Holdback) {
+ const char kResponseHeaders[] =
+ "HTTP/1.1 200 OK\r\n"
+ "Via: 1.1 Chrome-Compression-Proxy-Suffix\r\n"
+ "Content-Length: 10\r\n\r\n";
+
+ const struct {
+ bool holdback;
+ } tests[] = {
+ {
+ true,
+ },
+ {
+ false,
+ },
+ };
+ for (const auto& test : tests) {
+ base::FieldTrialList field_trial_list(nullptr);
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+ "DataCompressionProxyHoldback", test.holdback ? "Enabled" : "Control"));
+
+ base::HistogramTester histogram_tester;
+ FetchURLRequest(GURL("http://example.com/path/"), nullptr, kResponseHeaders,
+ 10);
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.SuccessfulRequestCompletionCounts",
+ test.holdback ? 0 : 1);
+ }
+}
+
TEST_F(DataReductionProxyDelegateTest, OnCompletedSizeFor304) {
int64_t baseline_received_bytes = total_received_bytes();
int64_t baseline_original_received_bytes = total_original_received_bytes();
@@ -1037,8 +924,9 @@ TEST_F(DataReductionProxyDelegateTest, OnCompletedSizeForWriteError) {
mock_socket_factory()->AddSocketDataProvider(&socket);
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
- GURL("http://example.com/path/"), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> request =
+ context()->CreateRequest(GURL("http://example.com/path/"), net::IDLE,
+ &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
request->Start();
base::RunLoop().RunUntilIdle();
@@ -1058,8 +946,9 @@ TEST_F(DataReductionProxyDelegateTest, OnCompletedSizeForReadError) {
mock_socket_factory()->AddSocketDataProvider(&socket);
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
- GURL("http://example.com/path/"), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> request =
+ context()->CreateRequest(GURL("http://example.com/path/"), net::IDLE,
+ &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
request->Start();
base::RunLoop().RunUntilIdle();
@@ -1150,8 +1039,9 @@ TEST_F(DataReductionProxyDelegateTest, PartialRangeSavings) {
mock_socket_factory()->AddSocketDataProvider(&socket);
net::TestDelegate test_delegate;
- std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
- GURL("http://example.com"), net::IDLE, &test_delegate);
+ std::unique_ptr<net::URLRequest> request =
+ context()->CreateRequest(GURL("http://example.com"), net::IDLE,
+ &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
request->Start();
base::RunLoop().RunUntilIdle();
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
index 4d8f08897a2..5790d4403d4 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
@@ -25,6 +25,7 @@
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
#include "components/prefs/pref_service.h"
+#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
@@ -32,6 +33,7 @@
#include "net/proxy/proxy_server.h"
#include "net/socket/socket_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
@@ -172,8 +174,9 @@ TEST_F(DataReductionProxyInterceptorTest, MAYBE_TestJobFactoryChaining) {
Init(std::move(factory1));
net::TestDelegate d;
- std::unique_ptr<net::URLRequest> req(default_context_->CreateRequest(
- GURL("http://foo"), net::DEFAULT_PRIORITY, &d));
+ std::unique_ptr<net::URLRequest> req(
+ default_context_->CreateRequest(GURL("http://foo"), net::DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
req->Start();
base::RunLoop().Run();
@@ -262,7 +265,8 @@ TEST_F(DataReductionProxyInterceptorWithServerTest, TestBypass) {
// DataReductionProxyProtocolTest.
net::TestDelegate delegate;
std::unique_ptr<net::URLRequest> request(context().CreateRequest(
- direct().GetURL("/block10.html"), net::DEFAULT_PRIORITY, &delegate));
+ direct().GetURL("/block10.html"), net::DEFAULT_PRIORITY, &delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
request->Start();
EXPECT_TRUE(request->is_pending());
base::RunLoop().Run();
@@ -274,7 +278,8 @@ TEST_F(DataReductionProxyInterceptorWithServerTest, TestBypass) {
TEST_F(DataReductionProxyInterceptorWithServerTest, TestNoBypass) {
net::TestDelegate delegate;
std::unique_ptr<net::URLRequest> request(context().CreateRequest(
- direct().GetURL("/noblock.html"), net::DEFAULT_PRIORITY, &delegate));
+ direct().GetURL("/noblock.html"), net::DEFAULT_PRIORITY, &delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
request->Start();
EXPECT_TRUE(request->is_pending());
base::RunLoop().Run();
@@ -312,8 +317,8 @@ class DataReductionProxyInterceptorEndToEndTest : public testing::Test {
// Creates a URLRequest using the test's TestURLRequestContext and executes
// it. Returns the created URLRequest.
std::unique_ptr<net::URLRequest> CreateAndExecuteRequest(const GURL& url) {
- std::unique_ptr<net::URLRequest> request(
- context_.CreateRequest(url, net::IDLE, &delegate_));
+ std::unique_ptr<net::URLRequest> request(context_.CreateRequest(
+ url, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS));
request->Start();
drp_test_context_->RunUntilIdle();
return request;
@@ -541,13 +546,7 @@ TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectWithBypassAndRetry) {
EXPECT_EQ(std::vector<GURL>(1, GURL("http://foo.com")), request->url_chain());
}
-// https://crbug.com/668197: Flaky on android_n5x_swarming_rel bot.
-#if defined(OS_ANDROID)
-#define MAYBE_RedirectChainToHttps DISABLED_RedirectChainToHttps
-#else
-#define MAYBE_RedirectChainToHttps RedirectChainToHttps
-#endif
-TEST_F(DataReductionProxyInterceptorEndToEndTest, MAYBE_RedirectChainToHttps) {
+TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectChainToHttps) {
// First, a redirect is successfully received through the Data Reduction
// Proxy. HSTS is forced for play.google.com and prebaked into Chrome, so
// http://play.google.com will automatically be redirected to
@@ -579,6 +578,9 @@ TEST_F(DataReductionProxyInterceptorEndToEndTest, MAYBE_RedirectChainToHttps) {
std::unique_ptr<net::URLRequest> request =
CreateAndExecuteRequest(GURL("http://music.google.com"));
+ request->SetLoadFlags(net::LOAD_DISABLE_CACHE |
+ net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
EXPECT_FALSE(delegate().request_failed());
EXPECT_EQ(kBody, delegate().data_received());
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
index bdfbb43b48f..90318bc3eea 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -291,29 +291,43 @@ void DataReductionProxyIOData::SetDataReductionProxyConfiguration(
}
bool DataReductionProxyIOData::ShouldEnableLoFi(
- const net::URLRequest& request) {
+ const net::URLRequest& request,
+ previews::PreviewsDecider* previews_decider) {
+ DCHECK(previews_decider);
DCHECK((request.load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) != 0);
if (!config_ || (config_->IsBypassedByDataReductionProxyLocalRules(
request, configurator_->GetProxyConfig()))) {
return false;
}
- return config_->ShouldEnableLoFi(request);
+ return config_->ShouldEnableLoFi(request, *previews_decider);
}
bool DataReductionProxyIOData::ShouldEnableLitePages(
- const net::URLRequest& request) {
+ const net::URLRequest& request,
+ previews::PreviewsDecider* previews_decider) {
+ DCHECK(previews_decider);
DCHECK((request.load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) != 0);
if (!config_ || (config_->IsBypassedByDataReductionProxyLocalRules(
request, configurator_->GetProxyConfig()))) {
return false;
}
- return config_->ShouldEnableLitePages(request);
+ return config_->ShouldEnableLitePages(request, *previews_decider);
}
void DataReductionProxyIOData::SetLoFiModeOff() {
config_->SetLoFiModeOff();
}
+void DataReductionProxyIOData::UpdateDataUseForHost(int64_t network_bytes,
+ int64_t original_bytes,
+ const std::string& host) {
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
+
+ ui_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DataReductionProxyService::UpdateDataUseForHost,
+ service_, network_bytes, original_bytes, host));
+}
+
void DataReductionProxyIOData::UpdateContentLengths(
int64_t data_used,
int64_t original_size,
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
index 22a90a8397e..951a32bfc92 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -36,6 +36,10 @@ class URLRequestContextGetter;
class URLRequestInterceptor;
}
+namespace previews {
+class PreviewsDecider;
+}
+
namespace data_reduction_proxy {
class DataReductionProxyBypassStats;
@@ -98,17 +102,26 @@ class DataReductionProxyIOData : public DataReductionProxyEventStorageDelegate {
// Returns true when Lo-Fi Previews should be activated. When Lo-Fi is
// active, URL requests are modified to request low fidelity versions of the
// resources, except when the user is in the Lo-Fi control group.
- bool ShouldEnableLoFi(const net::URLRequest& request);
+ // |previews_decider| is a non-null object that determines eligibility of
+ // showing the preview based on past opt outs.
+ bool ShouldEnableLoFi(const net::URLRequest& request,
+ previews::PreviewsDecider* previews_decider);
// Returns true when Lite Page Previews should be activated. When Lite Pages
// are active, a low fidelity transcoded page is requested on the main frame
- // resource, except when the user is in the control group.
- bool ShouldEnableLitePages(const net::URLRequest& request);
+ // resource, except when the user is in the control group. |previews_decider|
+ // is a non-null object that determines eligibility of showing the preview
+ // based on past opt outs.
+ bool ShouldEnableLitePages(const net::URLRequest& request,
+ previews::PreviewsDecider* previews_decider);
// Sets Lo-Fi mode off in |config_|.
void SetLoFiModeOff();
// Bridge methods to safely call to the UI thread objects.
+ void UpdateDataUseForHost(int64_t network_bytes,
+ int64_t original_bytes,
+ const std::string& host);
void UpdateContentLengths(
int64_t data_used,
int64_t original_size,
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
index 7b09403fd4c..fb75ff2e24e 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -8,6 +8,7 @@
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -27,6 +28,7 @@
#include "net/log/net_log_with_source.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_service.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_interceptor.h"
@@ -123,8 +125,9 @@ TEST_F(DataReductionProxyIODataTest, TestConstruction) {
// When creating a network delegate, expect that it properly wraps a
// network delegate. Such a network delegate is thoroughly tested by
// DataReductionProxyNetworkDelegateTest.
- std::unique_ptr<net::URLRequest> fake_request = context().CreateRequest(
- GURL("http://www.foo.com/"), net::IDLE, delegate());
+ std::unique_ptr<net::URLRequest> fake_request =
+ context().CreateRequest(GURL("http://www.foo.com/"), net::IDLE,
+ delegate(), TRAFFIC_ANNOTATION_FOR_TESTS);
CountingNetworkDelegate* wrapped_network_delegate =
new CountingNetworkDelegate();
std::unique_ptr<DataReductionProxyNetworkDelegate> network_delegate =
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
index da8d668cad6..59f6f3d8825 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
@@ -20,6 +21,7 @@
#include "net/proxy/proxy_server.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -176,8 +178,8 @@ TEST(ChromeNetworkDailyDataSavingMetricsTest,
mock_socket_factory.AddSocketDataProvider(&socket_data_provider);
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request =
- context.CreateRequest(test_case.url, net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> request = context.CreateRequest(
+ test_case.url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
request->SetLoadFlags(test_case.load_flags);
request->Start();
test_context->RunUntilIdle();
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
index 12d8b56770d..97fbec5be1c 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -4,12 +4,16 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h"
+#include <algorithm>
#include <limits>
#include <utility>
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
@@ -19,6 +23,7 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
#include "components/data_reduction_proxy/core/browser/data_use_group.h"
#include "components/data_reduction_proxy/core/browser/data_use_group_provider.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
#include "components/data_reduction_proxy/core/common/lofi_decider.h"
@@ -26,6 +31,7 @@
#include "net/base/mime_util.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
+#include "net/nqe/effective_connection_type.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_server.h"
@@ -39,19 +45,69 @@ namespace data_reduction_proxy {
namespace {
-// |lofi_low_header_added| is set to true iff Lo-Fi "q=low" request header can
-// be added to the Chrome proxy headers.
-// |received_content_length| is the number of prefilter bytes received.
-// |original_content_length| is the length of resource if accessed directly
-// without data saver proxy.
-// |freshness_lifetime| contains information on how long the resource will be
-// fresh for and how long is the usability.
+// Records the occurrence of |sample| in |name| histogram. UMA macros are not
+// used because the |name| is not static.
+void RecordNewContentLengthHistogram(const std::string& name, int64_t sample) {
+ base::UmaHistogramCustomCounts(
+ name, sample,
+ 1, // Minimum sample size in bytes.
+ 128 << 20, // Maximum sample size in bytes. 128MB is chosen because some
+ // video requests can be very large.
+ 50 // Bucket count.
+ );
+}
+
+void RecordNewContentLengthHistograms(
+ const char* prefix,
+ bool is_https,
+ bool is_video,
+ DataReductionProxyRequestType request_type,
+ int64_t content_length) {
+ const char* connection_type = is_https ? ".Https" : ".Http";
+ const char* suffix = ".Other";
+ // TODO(crbug.com/726411): Differentiate between a bypass and a disabled
+ // proxy config.
+ switch (request_type) {
+ case VIA_DATA_REDUCTION_PROXY:
+ suffix = ".ViaDRP";
+ break;
+ case HTTPS:
+ suffix = ".Direct";
+ break;
+ case SHORT_BYPASS:
+ case LONG_BYPASS:
+ suffix = ".BypassedDRP";
+ break;
+ case UPDATE:
+ case UNKNOWN_TYPE:
+ default:
+ // Value already properly initialized to ".Other"
+ break;
+ }
+ // Record a histogram for all traffic, including video.
+ RecordNewContentLengthHistogram(
+ base::StringPrintf("%s%s%s", prefix, connection_type, suffix),
+ content_length);
+ if (is_video) {
+ RecordNewContentLengthHistogram(
+ base::StringPrintf("%s%s%s.Video", prefix, connection_type, suffix),
+ content_length);
+ }
+}
+
+// |lofi_low_header_added| is set to true iff Lo-Fi request header
+// can be added to the Chrome proxy header. |received_content_length| is
+// the number of prefilter bytes received. |original_content_length| is the
+// length of resource if accessed directly without data saver proxy.
+// |freshness_lifetime| specifies how long the resource will
+// be fresh for.
void RecordContentLengthHistograms(bool lofi_low_header_added,
bool is_https,
bool is_video,
int64_t received_content_length,
int64_t original_content_length,
- const base::TimeDelta& freshness_lifetime) {
+ const base::TimeDelta& freshness_lifetime,
+ DataReductionProxyRequestType request_type) {
// Add the current resource to these histograms only when a valid
// X-Original-Content-Length header is present.
if (original_content_length >= 0) {
@@ -80,17 +136,14 @@ void RecordContentLengthHistograms(bool lofi_low_header_added,
original_content_length = received_content_length;
}
UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLength", received_content_length);
- if (is_https) {
- UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLength.Https",
- received_content_length);
- } else {
- UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLength.Http",
- received_content_length);
- }
- if (is_video) {
- UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLength.Video",
- received_content_length);
- }
+
+ // Record the new histograms broken down by HTTP/HTTPS and video/non-video
+ RecordNewContentLengthHistograms("Net.HttpContentLength", is_https, is_video,
+ request_type, received_content_length);
+ RecordNewContentLengthHistograms("Net.HttpOriginalContentLength", is_https,
+ is_video, request_type,
+ original_content_length);
+
UMA_HISTOGRAM_COUNTS_1M("Net.HttpOriginalContentLength",
original_content_length);
UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLengthDifference",
@@ -98,8 +151,7 @@ void RecordContentLengthHistograms(bool lofi_low_header_added,
UMA_HISTOGRAM_CUSTOM_COUNTS("Net.HttpContentFreshnessLifetime",
freshness_lifetime.InSeconds(),
base::TimeDelta::FromHours(1).InSeconds(),
- base::TimeDelta::FromDays(30).InSeconds(),
- 100);
+ base::TimeDelta::FromDays(30).InSeconds(), 100);
if (freshness_lifetime.InSeconds() <= 0)
return;
UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLengthCacheable",
@@ -115,18 +167,52 @@ void RecordContentLengthHistograms(bool lofi_low_header_added,
received_content_length);
}
-// Given a |request| that went through the Data Reduction Proxy, this function
-// estimates how many bytes would have been received if the response had been
-// received directly from the origin using HTTP/1.1 with a content length of
-// |adjusted_original_content_length|.
-int64_t EstimateOriginalReceivedBytes(const net::URLRequest& request) {
+// Estimate the size of the original headers of |request|. If |used_drp| is
+// true, then it's assumed that the original request would have used HTTP/1.1,
+// otherwise it assumes that the original request would have used the same
+// protocol as |request| did. This is to account for stuff like HTTP/2 header
+// compression.
+// TODO(rajendrant): Remove this method when data use ascriber observers are
+// used to record the per-site data usage.
+int64_t EstimateOriginalHeaderBytes(const net::URLRequest& request,
+ bool used_drp) {
+ if (used_drp) {
+ // TODO(sclittle): Remove headers added by Data Reduction Proxy when
+ // computing original size. https://crbug.com/535701.
+ return request.response_headers()->raw_headers().size();
+ }
+ return std::max<int64_t>(0, request.GetTotalReceivedBytes() -
+ request.received_response_content_length());
+}
+
+// Given a |request| that went through the Data Reduction Proxy if |used_drp| is
+// true, this function estimates how many bytes would have been received if the
+// response had been received directly from the origin without any data saver
+// optimizations.
+// TODO(rajendrant): Remove this method when data use ascriber observers are
+// used to record the per-site data usage.
+int64_t EstimateOriginalReceivedBytes(const net::URLRequest& request,
+ bool used_drp,
+ const LoFiDecider* lofi_decider) {
if (request.was_cached() || !request.response_headers())
return request.GetTotalReceivedBytes();
- // TODO(sclittle): Remove headers added by Data Reduction Proxy when computing
- // original size. http://crbug/535701.
- return request.response_headers()->raw_headers().size() +
- util::CalculateEffectiveOCL(request);
+ if (lofi_decider) {
+ if (lofi_decider->IsClientLoFiAutoReloadRequest(request))
+ return 0;
+
+ int64_t first, last, length;
+ if (lofi_decider->IsClientLoFiImageRequest(request) &&
+ request.response_headers()->GetContentRangeFor206(&first, &last,
+ &length) &&
+ length > request.received_response_content_length()) {
+ return EstimateOriginalHeaderBytes(request, used_drp) + length;
+ }
+ }
+
+ return used_drp ? EstimateOriginalHeaderBytes(request, used_drp) +
+ util::CalculateEffectiveOCL(request)
+ : request.GetTotalReceivedBytes();
}
// Verifies that the chrome proxy related request headers are set correctly.
@@ -134,11 +220,25 @@ int64_t EstimateOriginalReceivedBytes(const net::URLRequest& request) {
// Saver proxy.
void VerifyHttpRequestHeaders(bool via_chrome_proxy,
const net::HttpRequestHeaders& headers) {
+ // If holdback is enabled, then |via_chrome_proxy| should be false.
+ DCHECK(!params::IsIncludedInHoldbackFieldTrial() || !via_chrome_proxy);
+
if (via_chrome_proxy) {
- DCHECK(headers.HasHeader(chrome_proxy_header()));
+ DCHECK(headers.HasHeader(chrome_proxy_ect_header()));
+ std::string chrome_proxy_header_value;
+ DCHECK(
+ headers.GetHeader(chrome_proxy_header(), &chrome_proxy_header_value));
+ // Check that only 1 "exp" directive is sent.
+ DCHECK_GT(3u, base::SplitStringUsingSubstr(chrome_proxy_header_value,
+ "exp=", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_ALL)
+ .size());
+ // Silence unused variable warning in release builds.
+ (void)chrome_proxy_header_value;
} else {
DCHECK(!headers.HasHeader(chrome_proxy_header()));
DCHECK(!headers.HasHeader(chrome_proxy_accept_transform_header()));
+ DCHECK(!headers.HasHeader(chrome_proxy_ect_header()));
}
}
@@ -223,6 +323,8 @@ void DataReductionProxyNetworkDelegate::OnBeforeStartTransactionInternal(
->MaybeSetAcceptTransformHeader(
*request, data_reduction_proxy_config_->lofi_off(), headers);
}
+
+ MaybeAddChromeProxyECTHeader(headers, *request);
}
void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal(
@@ -249,14 +351,17 @@ void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal(
DataReductionProxyData::ClearData(request);
if (params::IsIncludedInHoldbackFieldTrial()) {
- if (!WasEligibleWithoutHoldback(*request, proxy_info, proxy_retry_info))
- return;
- // For the holdback field trial, still log UMA as if the proxy was used.
- data = DataReductionProxyData::GetDataAndCreateIfNecessary(request);
- if (data)
- data->set_used_data_reduction_proxy(true);
- VerifyHttpRequestHeaders(false, *headers);
- return;
+ if (WasEligibleWithoutHoldback(*request, proxy_info, proxy_retry_info)) {
+ // For the holdback field trial, still log UMA as if the proxy was used.
+ data = DataReductionProxyData::GetDataAndCreateIfNecessary(request);
+ if (data)
+ data->set_used_data_reduction_proxy(true);
+ }
+ // If holdback is enabled, |proxy_info| must not contain a data reduction
+ // proxy.
+ DCHECK(proxy_info.is_empty() ||
+ !data_reduction_proxy_config_->IsDataReductionProxy(
+ proxy_info.proxy_server(), nullptr));
}
bool using_data_reduction_proxy = true;
@@ -270,6 +375,9 @@ void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal(
proxy_info.proxy_server(), nullptr)) {
using_data_reduction_proxy = false;
}
+ // If holdback is enabled, |using_data_reduction_proxy| must be false.
+ DCHECK(!params::IsIncludedInHoldbackFieldTrial() ||
+ !using_data_reduction_proxy);
LoFiDecider* lofi_decider = nullptr;
if (data_reduction_proxy_io_data_)
@@ -281,6 +389,8 @@ void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal(
// Chrome-Proxy-Accept-Transform header.
lofi_decider->RemoveAcceptTransformHeader(headers);
}
+ RemoveChromeProxyECTHeader(headers);
+ headers->RemoveHeader(chrome_proxy_header());
VerifyHttpRequestHeaders(false, *headers);
return;
}
@@ -329,8 +439,6 @@ void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal(
data_reduction_proxy_request_options_->AddRequestHeader(headers, page_id);
- if (lofi_decider)
- lofi_decider->MaybeSetIgnorePreviewsBlacklistDirective(headers);
VerifyHttpRequestHeaders(true, *headers);
}
@@ -373,8 +481,15 @@ void DataReductionProxyNetworkDelegate::OnCompletedInternal(
net_error);
net::HttpRequestHeaders request_headers;
- if (data_reduction_proxy_io_data_ && request->response_headers() &&
- IsEmptyImagePreview(*(request->response_headers()))) {
+ bool server_lofi = request->response_headers() &&
+ IsEmptyImagePreview(*(request->response_headers()));
+ bool client_lofi =
+ data_reduction_proxy_io_data_ &&
+ data_reduction_proxy_io_data_->lofi_decider() &&
+ data_reduction_proxy_io_data_->lofi_decider()->IsClientLoFiImageRequest(
+ *request);
+ if ((server_lofi || client_lofi) && data_reduction_proxy_io_data_ &&
+ data_reduction_proxy_io_data_->lofi_ui_service()) {
data_reduction_proxy_io_data_->lofi_ui_service()->OnLoFiReponseReceived(
*request);
} else if (data_reduction_proxy_io_data_ && request->response_headers() &&
@@ -416,7 +531,8 @@ void DataReductionProxyNetworkDelegate::OnHeadersReceivedInternal(
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) {
- if (!original_response_headers)
+ if (!original_response_headers ||
+ original_response_headers->IsRedirect(nullptr))
return;
if (IsEmptyImagePreview(*original_response_headers)) {
DataReductionProxyData* data =
@@ -427,6 +543,14 @@ void DataReductionProxyNetworkDelegate::OnHeadersReceivedInternal(
DataReductionProxyData::GetDataAndCreateIfNecessary(request);
data->set_lite_page_received(true);
}
+ if (data_reduction_proxy_io_data_ &&
+ data_reduction_proxy_io_data_->lofi_decider() &&
+ data_reduction_proxy_io_data_->lofi_decider()->IsClientLoFiImageRequest(
+ *request)) {
+ DataReductionProxyData* data =
+ DataReductionProxyData::GetDataAndCreateIfNecessary(request);
+ data->set_client_lofi_requested(true);
+ }
}
void DataReductionProxyNetworkDelegate::CalculateAndRecordDataUsage(
@@ -437,10 +561,11 @@ void DataReductionProxyNetworkDelegate::CalculateAndRecordDataUsage(
// Estimate how many bytes would have been used if the DataReductionProxy was
// not used, and record the data usage.
- int64_t original_size = data_used;
-
- if (request_type == VIA_DATA_REDUCTION_PROXY)
- original_size = EstimateOriginalReceivedBytes(request);
+ int64_t original_size = EstimateOriginalReceivedBytes(
+ request, request_type == VIA_DATA_REDUCTION_PROXY,
+ data_reduction_proxy_io_data_
+ ? data_reduction_proxy_io_data_->lofi_decider()
+ : nullptr);
std::string mime_type;
if (request.response_headers())
@@ -500,7 +625,7 @@ void DataReductionProxyNetworkDelegate::RecordContentLength(
data_reduction_proxy_io_data_->lofi_decider() &&
data_reduction_proxy_io_data_->lofi_decider()->IsUsingLoFi(request),
is_https, is_video, request.received_response_content_length(),
- original_content_length, freshness_lifetime);
+ original_content_length, freshness_lifetime, request_type);
if (data_reduction_proxy_io_data_ && data_reduction_proxy_bypass_stats_) {
// Record BypassedBytes histograms for the request.
@@ -596,4 +721,48 @@ void DataReductionProxyNetworkDelegate::MaybeAddBrotliToAcceptEncodingHeader(
header_value);
}
+void DataReductionProxyNetworkDelegate::MaybeAddChromeProxyECTHeader(
+ net::HttpRequestHeaders* request_headers,
+ const net::URLRequest& request) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // This method should be called only when the resolved proxy was a data
+ // saver proxy.
+ DCHECK(request.url().is_valid());
+ DCHECK(!request.url().SchemeIsCryptographic());
+ DCHECK(request.url().SchemeIsHTTPOrHTTPS());
+
+ if (request_headers->HasHeader(chrome_proxy_ect_header()))
+ request_headers->RemoveHeader(chrome_proxy_ect_header());
+
+ if (request.context()->network_quality_estimator()) {
+ net::EffectiveConnectionType type = request.context()
+ ->network_quality_estimator()
+ ->GetEffectiveConnectionType();
+ if (type > net::EFFECTIVE_CONNECTION_TYPE_OFFLINE) {
+ DCHECK_NE(net::EFFECTIVE_CONNECTION_TYPE_LAST, type);
+ request_headers->SetHeader(chrome_proxy_ect_header(),
+ net::GetNameForEffectiveConnectionType(type));
+ return;
+ }
+ }
+ request_headers->SetHeader(chrome_proxy_ect_header(),
+ net::GetNameForEffectiveConnectionType(
+ net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN));
+
+ static_assert(net::EFFECTIVE_CONNECTION_TYPE_OFFLINE + 1 ==
+ net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
+ "ECT enum value is not handled.");
+ static_assert(net::EFFECTIVE_CONNECTION_TYPE_4G + 1 ==
+ net::EFFECTIVE_CONNECTION_TYPE_LAST,
+ "ECT enum value is not handled.");
+}
+
+void DataReductionProxyNetworkDelegate::RemoveChromeProxyECTHeader(
+ net::HttpRequestHeaders* request_headers) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ request_headers->RemoveHeader(chrome_proxy_ect_header());
+}
+
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
index 33c717f128e..600445d9eb1 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
@@ -166,6 +166,17 @@ class DataReductionProxyNetworkDelegate : public net::LayeredNetworkDelegate {
net::HttpRequestHeaders* request_headers,
const net::URLRequest& request) const;
+ // May add chrome-proxy-ect header to |request_headers| if adding of
+ // chrome-proxy-ect is enabled via field trial and a valid estimate of
+ // network quality is available. This method should be called only when the
+ // resolved proxy for |request| is a data saver proxy.
+ void MaybeAddChromeProxyECTHeader(net::HttpRequestHeaders* request_headers,
+ const net::URLRequest& request) const;
+
+ // Removes the chrome-proxy-ect header from |request_headers|.
+ void RemoveChromeProxyECTHeader(
+ net::HttpRequestHeaders* request_headers) const;
+
// All raw Data Reduction Proxy pointers must outlive |this|.
DataReductionProxyConfig* data_reduction_proxy_config_;
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
index 5c3886d257a..fe69c111390 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -40,6 +40,8 @@
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
#include "components/data_reduction_proxy/core/common/lofi_decider.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
+#include "components/previews/core/previews_decider.h"
+#include "components/previews/core/previews_experiments.h"
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
@@ -57,6 +59,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_status.h"
@@ -74,33 +77,99 @@ const char kOtherProxy[] = "testproxy:17";
const char kTestURL[] = "http://www.google.com/";
const char kSecureTestURL[] = "https://www.google.com/";
-const std::string kReceivedValidOCLHistogramName =
+const char kReceivedValidOCLHistogramName[] =
"Net.HttpContentLengthWithValidOCL";
-const std::string kOriginalValidOCLHistogramName =
+const char kOriginalValidOCLHistogramName[] =
"Net.HttpOriginalContentLengthWithValidOCL";
-const std::string kDifferenceValidOCLHistogramName =
+const char kDifferenceValidOCLHistogramName[] =
"Net.HttpContentLengthDifferenceWithValidOCL";
+// HTTP original content length
+const char kOriginalInsecureDirectHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.Direct";
+const char kOriginalInsecureViaDRPHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.ViaDRP";
+const char kOriginalInsecureBypassedHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.BypassedDRP";
+const char kOriginalInsecureOtherHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.Other";
+// HTTP video original content length
+const char kOriginalVideoInsecureDirectHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.Direct.Video";
+const char kOriginalVideoInsecureViaDRPHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.ViaDRP.Video";
+const char kOriginalVideoInsecureBypassedHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.BypassedDRP.Video";
+const char kOriginalVideoInsecureOtherHistogramName[] =
+ "Net.HttpOriginalContentLength.Http.Other.Video";
+// HTTPS original content length
+const char kOriginalSecureDirectHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.Direct";
+const char kOriginalSecureViaDRPHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.ViaDRP";
+const char kOriginalSecureBypassedHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.BypassedDRP";
+const char kOriginalSecureOtherHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.Other";
+// HTTPS video original content length
+const char kOriginalVideoSecureDirectHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.Direct.Video";
+const char kOriginalVideoSecureViaDRPHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.ViaDRP.Video";
+const char kOriginalVideoSecureBypassedHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.BypassedDRP.Video";
+const char kOriginalVideoSecureOtherHistogramName[] =
+ "Net.HttpOriginalContentLength.Https.Other.Video";
+
// Lo-Fi histograms.
-const std::string kReceivedValidOCLLoFiOnHistogramName =
+const char kReceivedValidOCLLoFiOnHistogramName[] =
"Net.HttpContentLengthWithValidOCL.LoFiOn";
-const std::string kOriginalValidOCLLoFiOnHistogramName =
+const char kOriginalValidOCLLoFiOnHistogramName[] =
"Net.HttpOriginalContentLengthWithValidOCL.LoFiOn";
-const std::string kDifferenceValidOCLLoFiOnHistogramName =
+const char kDifferenceValidOCLLoFiOnHistogramName[] =
"Net.HttpContentLengthDifferenceWithValidOCL.LoFiOn";
-const std::string kReceivedHistogramName = "Net.HttpContentLength";
-const std::string kReceivedInsecureHistogramName = "Net.HttpContentLength.Http";
-const std::string kReceivedSecureHistogramName = "Net.HttpContentLength.Https";
-const std::string kReceivedVideoHistogramName = "Net.HttpContentLength.Video";
-const std::string kOriginalHistogramName = "Net.HttpOriginalContentLength";
-const std::string kDifferenceHistogramName = "Net.HttpContentLengthDifference";
-const std::string kFreshnessLifetimeHistogramName =
+const char kReceivedHistogramName[] = "Net.HttpContentLength";
+const char kReceivedInsecureDirectHistogramName[] =
+ "Net.HttpContentLength.Http.Direct";
+const char kReceivedInsecureViaDRPHistogramName[] =
+ "Net.HttpContentLength.Http.ViaDRP";
+const char kReceivedInsecureBypassedHistogramName[] =
+ "Net.HttpContentLength.Http.BypassedDRP";
+const char kReceivedInsecureOtherHistogramName[] =
+ "Net.HttpContentLength.Http.Other";
+const char kReceivedSecureDirectHistogramName[] =
+ "Net.HttpContentLength.Https.Direct";
+const char kReceivedSecureViaDRPHistogramName[] =
+ "Net.HttpContentLength.Https.ViaDRP";
+const char kReceivedSecureBypassedHistogramName[] =
+ "Net.HttpContentLength.Https.BypassedDRP";
+const char kReceivedSecureOtherHistogramName[] =
+ "Net.HttpContentLength.Https.Other";
+const char kReceivedVideoInsecureDirectHistogramName[] =
+ "Net.HttpContentLength.Http.Direct.Video";
+const char kReceivedVideoInsecureViaDRPHistogramName[] =
+ "Net.HttpContentLength.Http.ViaDRP.Video";
+const char kReceivedVideoInsecureBypassedHistogramName[] =
+ "Net.HttpContentLength.Http.BypassedDRP.Video";
+const char kReceivedVideoInsecureOtherHistogramName[] =
+ "Net.HttpContentLength.Http.Other.Video";
+const char kReceivedVideoSecureDirectHistogramName[] =
+ "Net.HttpContentLength.Https.Direct.Video";
+const char kReceivedVideoSecureViaDRPHistogramName[] =
+ "Net.HttpContentLength.Https.ViaDRP.Video";
+const char kReceivedVideoSecureBypassedHistogramName[] =
+ "Net.HttpContentLength.Https.BypassedDRP.Video";
+const char kReceivedVideoSecureOtherHistogramName[] =
+ "Net.HttpContentLength.Https.Other.Video";
+const char kOriginalHistogramName[] = "Net.HttpOriginalContentLength";
+const char kDifferenceHistogramName[] = "Net.HttpContentLengthDifference";
+const char kFreshnessLifetimeHistogramName[] =
"Net.HttpContentFreshnessLifetime";
-const std::string kCacheableHistogramName = "Net.HttpContentLengthCacheable";
-const std::string kCacheable4HoursHistogramName =
+const char kCacheableHistogramName[] = "Net.HttpContentLengthCacheable";
+const char kCacheable4HoursHistogramName[] =
"Net.HttpContentLengthCacheable4Hours";
-const std::string kCacheable24HoursHistogramName =
+const char kCacheable24HoursHistogramName[] =
"Net.HttpContentLengthCacheable24Hours";
const int64_t kResponseContentLength = 100;
const int64_t kOriginalContentLength = 200;
@@ -132,7 +201,9 @@ const Client kClient = Client::UNKNOWN;
class TestLoFiDecider : public LoFiDecider {
public:
TestLoFiDecider()
- : should_request_lofi_resource_(false),
+ : should_be_client_lofi_(false),
+ should_be_client_lofi_auto_reload_(false),
+ should_request_lofi_resource_(false),
ignore_is_using_data_reduction_proxy_check_(false) {}
~TestLoFiDecider() override {}
@@ -144,6 +215,14 @@ class TestLoFiDecider : public LoFiDecider {
should_request_lofi_resource_ = should_request_lofi_resource;
}
+ void SetIsUsingClientLoFi(bool should_be_client_lofi) {
+ should_be_client_lofi_ = should_be_client_lofi;
+ }
+
+ void SetIsClientLoFiAutoReload(bool should_be_client_lofi_auto_reload) {
+ should_be_client_lofi_auto_reload_ = should_be_client_lofi_auto_reload;
+ }
+
void MaybeSetAcceptTransformHeader(
const net::URLRequest& request,
bool is_previews_disabled,
@@ -181,18 +260,26 @@ class TestLoFiDecider : public LoFiDecider {
headers->RemoveHeader(chrome_proxy_accept_transform_header());
}
- void MaybeSetIgnorePreviewsBlacklistDirective(
- net::HttpRequestHeaders* headers) const override {}
-
bool ShouldRecordLoFiUMA(const net::URLRequest& request) const override {
return should_request_lofi_resource_;
}
+ bool IsClientLoFiImageRequest(const net::URLRequest& request) const override {
+ return should_be_client_lofi_;
+ }
+
+ bool IsClientLoFiAutoReloadRequest(
+ const net::URLRequest& request) const override {
+ return should_be_client_lofi_auto_reload_;
+ }
+
void ignore_is_using_data_reduction_proxy_check() {
ignore_is_using_data_reduction_proxy_check_ = true;
}
private:
+ bool should_be_client_lofi_;
+ bool should_be_client_lofi_auto_reload_;
bool should_request_lofi_resource_;
bool ignore_is_using_data_reduction_proxy_check_;
};
@@ -208,17 +295,40 @@ class TestLoFiUIService : public LoFiUIService {
on_lofi_response_ = true;
}
+ void ClearResponse() { on_lofi_response_ = false; }
+
private:
bool on_lofi_response_;
};
+class TestPreviewsDecider : public previews::PreviewsDecider {
+ public:
+ TestPreviewsDecider() {}
+ ~TestPreviewsDecider() override {}
+ // previews::PreviewsDecider:
+ bool ShouldAllowPreviewAtECT(
+ const net::URLRequest& request,
+ previews::PreviewsType type,
+ net::EffectiveConnectionType effective_connection_type_threshold)
+ const override {
+ return true;
+ }
+
+ // Same as ShouldAllowPreviewAtECT, but uses the previews default
+ // EffectiveConnectionType.
+ bool ShouldAllowPreview(const net::URLRequest& request,
+ previews::PreviewsType type) const override {
+ return true;
+ }
+};
+
enum ProxyTestConfig { USE_SECURE_PROXY, USE_INSECURE_PROXY, BYPASS_PROXY };
class DataReductionProxyNetworkDelegateTest : public testing::Test {
public:
DataReductionProxyNetworkDelegateTest()
- : context_(true),
- context_storage_(&context_),
+ : lofi_decider_(nullptr),
+ lofi_ui_service_(nullptr),
ssl_socket_data_provider_(net::ASYNC, net::OK) {
ssl_socket_data_provider_.next_proto = net::kProtoHTTP11;
ssl_socket_data_provider_.cert = net::ImportCertFromFile(
@@ -240,13 +350,18 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
net::ProxyServer::SCHEME_HTTP);
break;
}
+ context_.reset(new net::TestURLRequestContext(true));
+ context_storage_.reset(new net::URLRequestContextStorage(context_.get()));
proxy_service_ =
net::ProxyService::CreateFixedFromPacResult(proxy_server.ToPacString());
- context_.set_proxy_service(proxy_service_.get());
+ context_->set_proxy_service(proxy_service_.get());
+
+ mock_socket_factory_.reset(new net::MockClientSocketFactory());
+
DataReductionProxyTestContext::Builder builder;
builder = builder.WithClient(kClient)
- .WithMockClientSocketFactory(&mock_socket_factory_)
- .WithURLRequestContext(&context_);
+ .WithMockClientSocketFactory(mock_socket_factory_.get())
+ .WithURLRequestContext(context_.get());
if (proxy_config != BYPASS_PROXY) {
builder = builder.WithProxiesForHttp({DataReductionProxyServer(
@@ -255,8 +370,8 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
test_context_ = builder.Build();
- context_.set_client_socket_factory(&mock_socket_factory_);
- test_context_->AttachToURLRequestContext(&context_storage_);
+ context_->set_client_socket_factory(mock_socket_factory_.get());
+ test_context_->AttachToURLRequestContext(context_storage_.get());
std::unique_ptr<TestLoFiDecider> lofi_decider(new TestLoFiDecider());
lofi_decider_ = lofi_decider.get();
@@ -266,13 +381,86 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
lofi_ui_service_ = lofi_ui_service.get();
test_context_->io_data()->set_lofi_ui_service(std::move(lofi_ui_service));
- context_.set_enable_brotli(enable_brotli_globally);
- context_.set_network_quality_estimator(&test_network_quality_estimator_);
- context_.Init();
+ context_->set_enable_brotli(enable_brotli_globally);
+ context_->set_network_quality_estimator(&test_network_quality_estimator_);
+ context_->Init();
test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();
}
+ // Build the sockets by adding appropriate mock data for
+ // |effective_connection_types.size()| number of requests. Data for
+ // chrome-Proxy-ect header is added to the mock data if |expect_ect_header|
+ // is true. |reads_list|, |mock_writes| and |writes_list| should be empty, and
+ // are owned by the caller.
+ void BuildSocket(const std::string& response_headers,
+ const std::string& response_body,
+ bool expect_ect_header,
+ const std::vector<net::EffectiveConnectionType>&
+ effective_connection_types,
+ std::vector<net::MockRead>* reads_list,
+ std::vector<std::string>* mock_writes,
+ std::vector<net::MockWrite>* writes_list) {
+ EXPECT_LT(0u, effective_connection_types.size());
+ EXPECT_TRUE(reads_list->empty());
+ EXPECT_TRUE(mock_writes->empty());
+ EXPECT_TRUE(writes_list->empty());
+
+ for (size_t i = 0; i < effective_connection_types.size(); ++i) {
+ reads_list->push_back(net::MockRead(response_headers.c_str()));
+ reads_list->push_back(net::MockRead(response_body.c_str()));
+ }
+ reads_list->push_back(net::MockRead(net::SYNCHRONOUS, net::OK));
+
+ std::string prefix = std::string("GET ")
+ .append(kTestURL)
+ .append(" HTTP/1.1\r\n")
+ .append("Host: ")
+ .append(GURL(kTestURL).host())
+ .append(
+ "\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "User-Agent:\r\n"
+ "Accept-Encoding: gzip, deflate\r\n"
+ "Accept-Language: en-us,fr\r\n");
+
+ if (io_data()->test_request_options()->GetHeaderValueForTesting().empty()) {
+ // Force regeneration of Chrome-Proxy header.
+ io_data()->test_request_options()->SetSecureSession("123");
+ }
+
+ EXPECT_FALSE(
+ io_data()->test_request_options()->GetHeaderValueForTesting().empty());
+
+ std::string suffix =
+ std::string("Chrome-Proxy: ") +
+ io_data()->test_request_options()->GetHeaderValueForTesting() +
+ std::string("\r\n\r\n");
+
+ mock_socket_factory_->AddSSLSocketDataProvider(&ssl_socket_data_provider_);
+
+ for (net::EffectiveConnectionType effective_connection_type :
+ effective_connection_types) {
+ std::string ect_header;
+ if (expect_ect_header) {
+ ect_header = "chrome-proxy-ect: " +
+ std::string(net::GetNameForEffectiveConnectionType(
+ effective_connection_type)) +
+ "\r\n";
+ }
+
+ std::string mock_write = prefix + ect_header + suffix;
+ mock_writes->push_back(mock_write);
+ writes_list->push_back(net::MockWrite(mock_writes->back().c_str()));
+ }
+
+ EXPECT_FALSE(socket_);
+ socket_ = base::MakeUnique<net::StaticSocketDataProvider>(
+ reads_list->data(), reads_list->size(), writes_list->data(),
+ writes_list->size());
+ mock_socket_factory_->AddSocketDataProvider(socket_.get());
+ }
+
static void VerifyHeaders(bool expected_data_reduction_proxy_used,
bool expected_lofi_used,
const net::HttpRequestHeaders& headers) {
@@ -288,6 +476,8 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
EXPECT_EQ(lofi_response, lofi_ui_service_->DidNotifyLoFiResponse());
}
+ void ClearLoFiUIService() { lofi_ui_service_->ClearResponse(); }
+
void VerifyDataReductionProxyData(const net::URLRequest& request,
bool data_reduction_proxy_used,
bool lofi_used) {
@@ -317,11 +507,11 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
net::MockRead(response_body.c_str()),
net::MockRead(net::SYNCHRONOUS, net::OK)};
net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0);
- mock_socket_factory_.AddSocketDataProvider(&socket);
+ mock_socket_factory_->AddSocketDataProvider(&socket);
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request =
- context_.CreateRequest(url, net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> request = context_->CreateRequest(
+ url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
if (request_headers)
request->SetExtraRequestHeaders(*request_headers);
request->SetLoadFlags(request->load_flags() | load_flags);
@@ -373,7 +563,7 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
std::string(base::checked_cast<size_t>(response_body_size), ' ');
}
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider_);
+ mock_socket_factory_->AddSSLSocketDataProvider(&ssl_socket_data_provider_);
net::MockRead reads[] = {net::MockRead(response_headers.c_str()),
net::MockRead(response_body.c_str()),
@@ -399,6 +589,10 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
"User-Agent:\r\n");
std::string accept_language_header("Accept-Language: en-us,fr\r\n");
+ std::string ect_header = "chrome-proxy-ect: " +
+ std::string(net::GetNameForEffectiveConnectionType(
+ net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)) +
+ "\r\n";
// Brotli is included in accept-encoding header only if the request went
// to the network (i.e., it was not a cached response), and if data
@@ -414,23 +608,24 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
std::string("\r\n\r\n");
std::string mock_write = prefix_headers + accept_language_header +
- accept_encoding_header + suffix_headers;
+ ect_header + accept_encoding_header +
+ suffix_headers;
if (expect_cached || !expect_brotli) {
// Order of headers is different if the headers were modified by data
// reduction proxy network delegate.
mock_write = prefix_headers + accept_encoding_header +
- accept_language_header + suffix_headers;
+ accept_language_header + ect_header + suffix_headers;
}
net::MockWrite writes[] = {net::MockWrite(mock_write.c_str())};
net::StaticSocketDataProvider socket(reads, arraysize(reads), writes,
arraysize(writes));
- mock_socket_factory_.AddSocketDataProvider(&socket);
+ mock_socket_factory_->AddSocketDataProvider(&socket);
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request =
- context_.CreateRequest(url, net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> request = context_->CreateRequest(
+ url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
if (request_headers)
request->SetExtraRequestHeaders(*request_headers);
@@ -493,7 +688,7 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
std::string response_body =
std::string(base::checked_cast<size_t>(response_body_size), ' ');
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider_);
+ mock_socket_factory_->AddSSLSocketDataProvider(&ssl_socket_data_provider_);
net::MockRead redirect_reads[] = {
net::MockRead("HTTP/1.1 302 Redirect\r\n"),
@@ -516,6 +711,7 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
"www.google.com\r\nProxy-Connection: "
"keep-alive\r\nUser-Agent:\r\nAccept-Encoding: gzip, "
"deflate\r\nAccept-Language: en-us,fr\r\n"
+ "chrome-proxy-ect: 4G\r\n"
"Chrome-Proxy: " +
io_data()->test_request_options()->GetHeaderValueForTesting() +
(page_id_value.empty() ? "" : (", " + page_id_value)) + "\r\n\r\n";
@@ -535,11 +731,11 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
arraysize(redirect_writes));
}
- mock_socket_factory_.AddSocketDataProvider(socket.get());
+ mock_socket_factory_->AddSocketDataProvider(socket.get());
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> request =
- context_.CreateRequest(url, net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> request = context_->CreateRequest(
+ url, net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
if (!page_id_value.empty()) {
request->SetLoadFlags(request->load_flags() |
net::LOAD_MAIN_FRAME_DEPRECATED);
@@ -549,6 +745,51 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
base::RunLoop().RunUntilIdle();
}
+ // Fetches a request while the effective connection type is set to
+ // |effective_connection_type|. Verifies that the request headers include the
+ // chrome-proxy-ect header only if |expect_ect_header| is true. The response
+ // must be served from the cache if |expect_cached| is true.
+ void FetchURLRequestAndVerifyECTHeader(
+ net::EffectiveConnectionType effective_connection_type,
+ bool expect_ect_header,
+ bool expect_cached) {
+ test_network_quality_estimator()->set_effective_connection_type(
+ effective_connection_type);
+
+ net::TestDelegate delegate;
+ std::unique_ptr<net::URLRequest> request = context_->CreateRequest(
+ GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(140, request->received_response_content_length());
+ EXPECT_EQ(expect_cached, request->was_cached());
+ EXPECT_EQ(expect_cached, request->GetTotalSentBytes() == 0);
+ EXPECT_EQ(expect_cached, request->GetTotalReceivedBytes() == 0);
+
+ net::HttpRequestHeaders sent_request_headers;
+ EXPECT_NE(expect_cached,
+ request->GetFullRequestHeaders(&sent_request_headers));
+
+ if (expect_cached) {
+ // Request headers are missing. Return since there is nothing left to
+ // check.
+ return;
+ }
+
+ // Verify that chrome-proxy-ect header is present in the request headers
+ // only if |expect_ect_header| is true.
+ std::string ect_value;
+ EXPECT_EQ(expect_ect_header, sent_request_headers.GetHeader(
+ chrome_proxy_ect_header(), &ect_value));
+
+ if (!expect_ect_header)
+ return;
+ EXPECT_EQ(net::GetNameForEffectiveConnectionType(effective_connection_type),
+ ect_value);
+ }
+
void DelegateStageDone(int result) {}
void NotifyNetworkDelegate(net::URLRequest* request,
@@ -570,13 +811,13 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
}
net::MockClientSocketFactory* mock_socket_factory() {
- return &mock_socket_factory_;
+ return mock_socket_factory_.get();
}
- net::TestURLRequestContext* context() { return &context_; }
+ net::TestURLRequestContext* context() { return context_.get(); }
net::NetworkDelegate* network_delegate() const {
- return context_.network_delegate();
+ return context_->network_delegate();
}
TestDataReductionProxyParams* params() const {
@@ -603,10 +844,10 @@ class DataReductionProxyNetworkDelegateTest : public testing::Test {
private:
base::MessageLoopForIO message_loop_;
- net::MockClientSocketFactory mock_socket_factory_;
+ std::unique_ptr<net::MockClientSocketFactory> mock_socket_factory_;
std::unique_ptr<net::ProxyService> proxy_service_;
- net::TestURLRequestContext context_;
- net::URLRequestContextStorage context_storage_;
+ std::unique_ptr<net::TestURLRequestContext> context_;
+ std::unique_ptr<net::URLRequestContextStorage> context_storage_;
TestLoFiDecider* lofi_decider_;
TestLoFiUIService* lofi_ui_service_;
@@ -700,24 +941,28 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
base::TrimString(kOtherProxy, "/", &proxy);
data_reduction_proxy_info.UseNamedProxy(proxy);
+ // Needed as a parameter, but functionality is not tested.
+ TestPreviewsDecider test_previews_decider;
+
{
// Main frame loaded. Lo-Fi should be used.
net::HttpRequestHeaders headers;
net::ProxyRetryInfoMap proxy_retry_info;
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> fake_request =
- context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest(
+ GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED);
- lofi_decider()->SetIsUsingLoFi(
- config()->ShouldEnableLoFi(*fake_request.get()));
+ lofi_decider()->SetIsUsingLoFi(config()->ShouldEnableLoFi(
+ *fake_request.get(), test_previews_decider));
NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info,
proxy_retry_info, &headers);
VerifyHeaders(tests[i].is_data_reduction_proxy, true, headers);
VerifyDataReductionProxyData(
*fake_request, tests[i].is_data_reduction_proxy,
- config()->ShouldEnableLoFi(*fake_request.get()));
+ config()->ShouldEnableLoFi(*fake_request.get(),
+ test_previews_decider));
}
{
@@ -725,8 +970,8 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
net::HttpRequestHeaders headers;
net::ProxyRetryInfoMap proxy_retry_info;
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> fake_request =
- context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest(
+ GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
lofi_decider()->SetIsUsingLoFi(false);
NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info,
proxy_retry_info, &headers);
@@ -740,8 +985,8 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
net::HttpRequestHeaders headers;
net::ProxyRetryInfoMap proxy_retry_info;
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> fake_request =
- context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest(
+ GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
lofi_decider()->SetIsUsingLoFi(true);
NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info,
@@ -757,8 +1002,8 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
net::HttpRequestHeaders headers;
net::ProxyRetryInfoMap proxy_retry_info;
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> fake_request =
- context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest(
+ GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED);
lofi_decider()->SetIsUsingLoFi(false);
NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info,
@@ -773,8 +1018,8 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
net::HttpRequestHeaders headers;
net::ProxyRetryInfoMap proxy_retry_info;
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> fake_request =
- context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest(
+ GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
lofi_decider()->SetIsUsingLoFi(false);
NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info,
proxy_retry_info, &headers);
@@ -788,16 +1033,17 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
net::HttpRequestHeaders headers;
net::ProxyRetryInfoMap proxy_retry_info;
net::TestDelegate delegate;
- std::unique_ptr<net::URLRequest> fake_request =
- context()->CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest(
+ GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED);
- lofi_decider()->SetIsUsingLoFi(
- config()->ShouldEnableLoFi(*fake_request.get()));
+ lofi_decider()->SetIsUsingLoFi(config()->ShouldEnableLoFi(
+ *fake_request.get(), test_previews_decider));
NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info,
proxy_retry_info, &headers);
VerifyDataReductionProxyData(
*fake_request, tests[i].is_data_reduction_proxy,
- config()->ShouldEnableLoFi(*fake_request.get()));
+ config()->ShouldEnableLoFi(*fake_request.get(),
+ test_previews_decider));
}
}
}
@@ -844,8 +1090,9 @@ TEST_F(DataReductionProxyNetworkDelegateTest, RequestDataConfigurations) {
test_network_quality_estimator()->set_effective_connection_type(
net::EFFECTIVE_CONNECTION_TYPE_OFFLINE);
- std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
- GURL(kTestURL), net::RequestPriority::IDLE, nullptr);
+ std::unique_ptr<net::URLRequest> request =
+ context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE,
+ nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
request->SetLoadFlags(test.main_frame ? net::LOAD_MAIN_FRAME_DEPRECATED
: 0);
lofi_decider()->SetIsUsingLoFi(test.lofi_on);
@@ -907,8 +1154,9 @@ TEST_F(DataReductionProxyNetworkDelegateTest,
else
data_reduction_proxy_info.UseNamedProxy("some.other.proxy");
config()->UpdateConfigForTesting(test.data_reduction_proxy_enabled, true);
- std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
- GURL(kTestURL), net::RequestPriority::IDLE, nullptr);
+ std::unique_ptr<net::URLRequest> request =
+ context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE,
+ nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
request->set_method("GET");
net::HttpRequestHeaders headers;
net::ProxyRetryInfoMap proxy_retry_info;
@@ -939,8 +1187,9 @@ TEST_F(DataReductionProxyNetworkDelegateTest, RedirectRequestDataCleared) {
test_network_quality_estimator()->set_effective_connection_type(
net::EFFECTIVE_CONNECTION_TYPE_OFFLINE);
- std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
- GURL(kTestURL), net::RequestPriority::IDLE, nullptr);
+ std::unique_ptr<net::URLRequest> request =
+ context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE,
+ nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED);
lofi_decider()->SetIsUsingLoFi(true);
io_data()->request_options()->SetSecureSession("fake-session");
@@ -1018,16 +1267,20 @@ TEST_F(DataReductionProxyNetworkDelegateTest, NetHistograms) {
kResponseContentLength, 1);
histogram_tester.ExpectUniqueSample(kOriginalValidOCLHistogramName,
kOriginalContentLength, 1);
+ histogram_tester.ExpectUniqueSample(kOriginalInsecureViaDRPHistogramName,
+ kOriginalContentLength, 1);
histogram_tester.ExpectUniqueSample(
kDifferenceValidOCLHistogramName,
kOriginalContentLength - kResponseContentLength, 1);
histogram_tester.ExpectUniqueSample(kReceivedHistogramName,
kResponseContentLength, 1);
- histogram_tester.ExpectUniqueSample(kReceivedInsecureHistogramName,
+ histogram_tester.ExpectUniqueSample(kReceivedInsecureViaDRPHistogramName,
kResponseContentLength, 1);
- histogram_tester.ExpectTotalCount(kReceivedSecureHistogramName, 0);
- histogram_tester.ExpectTotalCount(kReceivedVideoHistogramName, 0);
- histogram_tester.ExpectUniqueSample(kReceivedInsecureHistogramName,
+ histogram_tester.ExpectTotalCount(kReceivedInsecureDirectHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedSecureDirectHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedVideoInsecureViaDRPHistogramName,
+ 0);
+ histogram_tester.ExpectUniqueSample(kReceivedInsecureViaDRPHistogramName,
kResponseContentLength, 1);
histogram_tester.ExpectUniqueSample(kOriginalHistogramName,
kOriginalContentLength, 1);
@@ -1085,8 +1338,10 @@ TEST_F(DataReductionProxyNetworkDelegateTest, NetHistograms) {
switches::kDataReductionProxyLoFiValueAlwaysOn);
}
+ // Needed as a parameter, but functionality is not tested.
+ TestPreviewsDecider test_previews_decider;
lofi_decider()->SetIsUsingLoFi(
- config()->ShouldEnableLoFi(*fake_request.get()));
+ config()->ShouldEnableLoFi(*fake_request.get(), test_previews_decider));
fake_request = (FetchURLRequest(GURL(kTestURL), nullptr, response_headers,
kResponseContentLength, 0));
@@ -1137,35 +1392,216 @@ TEST_F(DataReductionProxyNetworkDelegateTest, NetVideoHistograms) {
FetchURLRequest(GURL(kTestURL), nullptr, video_response_headers,
kResponseContentLength, 0);
- histogram_tester.ExpectUniqueSample(kReceivedInsecureHistogramName,
+ histogram_tester.ExpectUniqueSample(kReceivedInsecureViaDRPHistogramName,
kResponseContentLength, 1);
- histogram_tester.ExpectTotalCount(kReceivedSecureHistogramName, 0);
- histogram_tester.ExpectUniqueSample(kReceivedVideoHistogramName,
+ histogram_tester.ExpectTotalCount(kReceivedInsecureDirectHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedInsecureBypassedHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedInsecureOtherHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedSecureViaDRPHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedSecureDirectHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedSecureBypassedHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedSecureOtherHistogramName, 0);
+ histogram_tester.ExpectUniqueSample(kReceivedVideoInsecureViaDRPHistogramName,
kResponseContentLength, 1);
+ histogram_tester.ExpectTotalCount(kReceivedVideoInsecureDirectHistogramName,
+ 0);
+ histogram_tester.ExpectTotalCount(kReceivedVideoInsecureBypassedHistogramName,
+ 0);
+ histogram_tester.ExpectTotalCount(kReceivedVideoInsecureOtherHistogramName,
+ 0);
+ histogram_tester.ExpectTotalCount(kReceivedVideoSecureViaDRPHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedVideoSecureDirectHistogramName, 0);
+ histogram_tester.ExpectTotalCount(kReceivedVideoSecureBypassedHistogramName,
+ 0);
+ histogram_tester.ExpectTotalCount(kReceivedVideoSecureOtherHistogramName, 0);
}
-TEST_F(DataReductionProxyNetworkDelegateTest, NetSSLHistograms) {
- Init(BYPASS_PROXY, false);
+struct ExpectedHistogram {
+ const std::string name;
+ int64_t value;
+};
- base::HistogramTester histogram_tester;
+bool operator<(const ExpectedHistogram& hist1, const ExpectedHistogram& hist2) {
+ return hist1.name < hist2.name;
+}
- // Check https
- std::string secure_response_headers =
- "HTTP/1.1 200 OK\r\n"
- "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n"
- "Expires: Mon, 24 Nov 2014 12:45:26 GMT\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n"
- "x-original-content-length: " +
- base::Int64ToString(kOriginalContentLength) + "\r\n\r\n";
+TEST_F(DataReductionProxyNetworkDelegateTest, DetailedNetHistograms) {
+ // List of all the histograms we're concerned with.
+ // Each test case can define interesting histograms from this list.
+ // Any histogram not called out in an invidual test will have an expected
+ // count of 0 samples.
+ const std::set<std::string> all_new_net_histograms{
+ // HTTP received content length
+ kReceivedInsecureDirectHistogramName,
+ kReceivedInsecureViaDRPHistogramName,
+ kReceivedInsecureBypassedHistogramName,
+ kReceivedInsecureOtherHistogramName,
+ // HTTP video received content length
+ kReceivedVideoInsecureDirectHistogramName,
+ kReceivedVideoInsecureViaDRPHistogramName,
+ kReceivedVideoInsecureBypassedHistogramName,
+ kReceivedVideoInsecureOtherHistogramName,
+ // HTTPS received content length
+ kReceivedSecureDirectHistogramName, kReceivedSecureViaDRPHistogramName,
+ kReceivedSecureBypassedHistogramName, kReceivedSecureOtherHistogramName,
+ // HTTPS video received content length
+ kReceivedVideoSecureDirectHistogramName,
+ kReceivedVideoSecureViaDRPHistogramName,
+ kReceivedVideoSecureBypassedHistogramName,
+ kReceivedVideoSecureOtherHistogramName,
+ // HTTP Original content length
+ kOriginalInsecureDirectHistogramName,
+ kOriginalInsecureViaDRPHistogramName,
+ kOriginalInsecureBypassedHistogramName,
+ kOriginalInsecureOtherHistogramName,
+ // HTTP video Original content length
+ kOriginalVideoInsecureDirectHistogramName,
+ kOriginalVideoInsecureViaDRPHistogramName,
+ kOriginalVideoInsecureBypassedHistogramName,
+ kOriginalVideoInsecureOtherHistogramName,
+ // HTTPS Original content length
+ kOriginalSecureDirectHistogramName, kOriginalSecureViaDRPHistogramName,
+ kOriginalSecureBypassedHistogramName, kOriginalSecureOtherHistogramName,
+ // HTTPS video Original content length
+ kOriginalVideoSecureDirectHistogramName,
+ kOriginalVideoSecureViaDRPHistogramName,
+ kOriginalVideoSecureBypassedHistogramName,
+ kOriginalVideoSecureOtherHistogramName,
+ };
- mock_socket_factory()->AddSSLSocketDataProvider(ssl_socket_data_provider());
- FetchURLRequest(GURL(kSecureTestURL), nullptr, secure_response_headers,
- kResponseContentLength, 0);
+ const struct {
+ const std::string name;
+ bool is_video;
+ bool is_https;
+ ProxyTestConfig proxy_config;
+ int64_t original_content_length;
+ int64_t content_length;
+ // Any histogram listed in all_new_net_histograms but not here should have
+ // no samples.
+ const std::set<ExpectedHistogram> expected_histograms;
+ } tests[] = {
+ {"HTTP nonvideo request via DRP",
+ false,
+ false,
+ USE_INSECURE_PROXY,
+ kOriginalContentLength,
+ kResponseContentLength,
+ {
+ {kReceivedInsecureViaDRPHistogramName, kResponseContentLength},
+ {kOriginalInsecureViaDRPHistogramName, kOriginalContentLength},
+ }},
+ {"HTTP video request via DRP",
+ true,
+ false,
+ USE_INSECURE_PROXY,
+ kOriginalContentLength,
+ kResponseContentLength,
+ {
+ {kReceivedInsecureViaDRPHistogramName, kResponseContentLength},
+ {kOriginalInsecureViaDRPHistogramName, kOriginalContentLength},
+ {kReceivedVideoInsecureViaDRPHistogramName, kResponseContentLength},
+ {kOriginalVideoInsecureViaDRPHistogramName, kOriginalContentLength},
+ }},
+ {"DRP not configured for http",
+ false,
+ false,
+ BYPASS_PROXY,
+ kOriginalContentLength,
+ kResponseContentLength,
+ {
+ {kReceivedInsecureOtherHistogramName, kResponseContentLength},
+ {kOriginalInsecureOtherHistogramName, kResponseContentLength},
+ }},
+ {"DRP not configured for http video",
+ true,
+ false,
+ BYPASS_PROXY,
+ kOriginalContentLength,
+ kResponseContentLength,
+ {
+ {kReceivedInsecureOtherHistogramName, kResponseContentLength},
+ {kOriginalInsecureOtherHistogramName, kResponseContentLength},
+ {kReceivedVideoInsecureOtherHistogramName, kResponseContentLength},
+ {kOriginalVideoInsecureOtherHistogramName, kResponseContentLength},
+ }},
+ {"nonvideo over https",
+ false,
+ true,
+ BYPASS_PROXY,
+ kOriginalContentLength,
+ kResponseContentLength,
+ {
+ {kReceivedSecureDirectHistogramName, kResponseContentLength},
+ {kOriginalSecureDirectHistogramName, kResponseContentLength},
+ }},
+ {"video over https",
+ true,
+ true,
+ BYPASS_PROXY,
+ kOriginalContentLength,
+ kResponseContentLength,
+ {
+ {kReceivedSecureDirectHistogramName, kResponseContentLength},
+ {kOriginalSecureDirectHistogramName, kResponseContentLength},
+ {kReceivedVideoSecureDirectHistogramName, kResponseContentLength},
+ {kOriginalVideoSecureDirectHistogramName, kResponseContentLength},
+ }},
+ };
- histogram_tester.ExpectTotalCount(kReceivedInsecureHistogramName, 0);
- histogram_tester.ExpectUniqueSample(kReceivedSecureHistogramName,
- kResponseContentLength, 1);
- histogram_tester.ExpectTotalCount(kReceivedVideoHistogramName, 0);
+ for (const auto& test : tests) {
+ LOG(INFO) << "NetHistograms: " << test.name;
+ Init(test.proxy_config, false);
+ base::HistogramTester histogram_tester;
+
+ GURL test_url = GURL(kTestURL);
+
+ if (test.is_https) {
+ test_url = GURL(kSecureTestURL);
+ mock_socket_factory()->AddSSLSocketDataProvider(
+ ssl_socket_data_provider());
+ }
+
+ std::string via_header = "";
+ std::string ocl_header = "";
+
+ if (test.proxy_config == USE_INSECURE_PROXY) {
+ via_header = "Via: 1.1 Chrome-Compression-Proxy\r\n";
+ ocl_header = "x-original-content-length: " +
+ base::Int64ToString(kOriginalContentLength) + "\r\n";
+ }
+ if (test.is_video) {
+ // Check video
+ std::string video_response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n"
+ "Expires: Mon, 24 Nov 2014 12:45:26 GMT\r\n"
+ "Content-Type: video/mp4\r\n" +
+ via_header + ocl_header + "\r\n";
+
+ FetchURLRequest(test_url, nullptr, video_response_headers,
+ kResponseContentLength, 0);
+ } else {
+ // Check https
+ std::string response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n"
+ "Expires: Mon, 24 Nov 2014 12:45:26 GMT\r\n" +
+ via_header + ocl_header + "\r\n\r\n";
+
+ FetchURLRequest(test_url, nullptr, response_headers,
+ kResponseContentLength, 0);
+ }
+
+ for (const auto& histogram : all_new_net_histograms) {
+ auto expected_it = test.expected_histograms.find({histogram, 0});
+ if (expected_it == test.expected_histograms.end()) {
+ histogram_tester.ExpectTotalCount(histogram, 0);
+ } else {
+ histogram_tester.ExpectUniqueSample(expected_it->name,
+ expected_it->value, 1);
+ }
+ }
+ }
}
TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedInternalLoFi) {
@@ -1173,11 +1609,12 @@ TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedInternalLoFi) {
// Enable Lo-Fi.
const struct {
bool lofi_response;
- } tests[] = {
- {false}, {true},
- };
+ bool was_server;
+ } tests[] = {{false, false}, {true, true}, {true, false}};
- for (size_t i = 0; i < arraysize(tests); ++i) {
+ for (const auto& test : tests) {
+ lofi_decider()->SetIsUsingClientLoFi(false);
+ ClearLoFiUIService();
std::string response_headers =
"HTTP/1.1 200 OK\r\n"
"Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n"
@@ -1185,15 +1622,19 @@ TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedInternalLoFi) {
"Via: 1.1 Chrome-Compression-Proxy\r\n"
"x-original-content-length: 200\r\n";
- if (tests[i].lofi_response)
- response_headers += "Chrome-Proxy-Content-Transform: empty-image\r\n";
+ if (test.lofi_response) {
+ if (test.was_server)
+ response_headers += "Chrome-Proxy-Content-Transform: empty-image\r\n";
+ else
+ lofi_decider()->SetIsUsingClientLoFi(true);
+ }
response_headers += "\r\n";
auto request =
FetchURLRequest(GURL(kTestURL), nullptr, response_headers, 140, 0);
- EXPECT_EQ(tests[i].lofi_response,
+ EXPECT_EQ(test.was_server,
DataReductionProxyData::GetData(*request)->lofi_received());
- VerifyDidNotifyLoFiResponse(tests[i].lofi_response);
+ VerifyDidNotifyLoFiResponse(test.lofi_response);
}
}
@@ -1371,8 +1812,9 @@ TEST_F(DataReductionProxyNetworkDelegateTest,
base::TrimString(params()->DefaultOrigin(), "/", &data_reduction_proxy);
data_reduction_proxy_info.UseNamedProxy(data_reduction_proxy);
- std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
- GURL(kTestURL), net::RequestPriority::IDLE, nullptr);
+ std::unique_ptr<net::URLRequest> request =
+ context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE,
+ nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED);
io_data()->request_options()->SetSecureSession("fake-session");
@@ -1380,6 +1822,11 @@ TEST_F(DataReductionProxyNetworkDelegateTest,
net::ProxyRetryInfoMap proxy_retry_info;
// Send a request and verify the page ID is 1.
+ network_delegate()->NotifyBeforeStartTransaction(
+ request.get(),
+ base::Bind(&DataReductionProxyNetworkDelegateTest::DelegateStageDone,
+ base::Unretained(this)),
+ &headers);
network_delegate()->NotifyBeforeSendHeaders(
request.get(), data_reduction_proxy_info, proxy_retry_info, &headers);
DataReductionProxyData* data =
@@ -1389,9 +1836,14 @@ TEST_F(DataReductionProxyNetworkDelegateTest,
// Send a second request and verify the page ID incremements.
request = context()->CreateRequest(GURL(kTestURL), net::RequestPriority::IDLE,
- nullptr);
+ nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED);
+ network_delegate()->NotifyBeforeStartTransaction(
+ request.get(),
+ base::Bind(&DataReductionProxyNetworkDelegateTest::DelegateStageDone,
+ base::Unretained(this)),
+ &headers);
network_delegate()->NotifyBeforeSendHeaders(
request.get(), data_reduction_proxy_info, proxy_retry_info, &headers);
data = DataReductionProxyData::GetData(*request.get());
@@ -1413,6 +1865,271 @@ TEST_F(DataReductionProxyNetworkDelegateTest,
EXPECT_EQ(1u, data->page_id().value());
}
+// Test that effective connection type is correctly added to the request
+// headers when it is enabled using field trial. The server is varying on the
+// effective connection type (ECT).
+TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithVary) {
+ Init(USE_SECURE_PROXY, false /* enable_brotli_globally */);
+
+ std::string response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 140\r\n"
+ "Via: 1.1 Chrome-Compression-Proxy\r\n"
+ "Cache-Control: max-age=1200\r\n"
+ "Vary: chrome-proxy-ect\r\n"
+ "x-original-content-length: 200\r\n\r\n";
+
+ int response_body_size = 140;
+ std::string response_body(base::checked_cast<size_t>(response_body_size),
+ ' ');
+
+ std::vector<net::MockRead> reads_list;
+ std::vector<std::string> mock_writes;
+ std::vector<net::MockWrite> writes_list;
+
+ std::vector<net::EffectiveConnectionType> effective_connection_types;
+ effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+ effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G);
+
+ BuildSocket(response_headers, response_body, true, effective_connection_types,
+ &reads_list, &mock_writes, &writes_list);
+
+ // Add 2 socket providers since 2 requests in this test are fetched from the
+ // network.
+ FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false);
+
+ // When the ECT is set to the same value, fetching the same resource should
+ // result in a cache hit.
+ FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true);
+
+ // When the ECT is set to a different value, the response should not be
+ // served from the cache.
+ FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, false);
+}
+
+// Test that effective connection type is correctly added to the request
+// headers when it is enabled using field trial. The server is not varying on
+// the effective connection type (ECT).
+TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithoutVary) {
+ Init(USE_SECURE_PROXY, false /* enable_brotli_globally */);
+
+ std::string response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 140\r\n"
+ "Via: 1.1 Chrome-Compression-Proxy\r\n"
+ "Cache-Control: max-age=1200\r\n"
+ "x-original-content-length: 200\r\n\r\n";
+
+ int response_body_size = 140;
+ std::string response_body(base::checked_cast<size_t>(response_body_size),
+ ' ');
+
+ std::vector<net::MockRead> reads_list;
+ std::vector<std::string> mock_writes;
+ std::vector<net::MockWrite> writes_list;
+
+ std::vector<net::EffectiveConnectionType> effective_connection_types;
+ effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+ effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G);
+
+ BuildSocket(response_headers, response_body, true, effective_connection_types,
+ &reads_list, &mock_writes, &writes_list);
+
+ // Add 1 socket provider since 1 request in this test is fetched from the
+ // network.
+ FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false);
+
+ // When the ECT is set to the same value, fetching the same resource should
+ // result in a cache hit.
+ FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true);
+
+ // When the ECT is set to a different value, the response should still be
+ // served from the cache.
+ FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true);
+}
+
+class DataReductionProxyNetworkDelegateClientLoFiTest : public testing::Test {
+ public:
+ DataReductionProxyNetworkDelegateClientLoFiTest() : baseline_savings_(0) {}
+ ~DataReductionProxyNetworkDelegateClientLoFiTest() override;
+
+ void Reset() {
+ drp_test_context_.reset();
+ mock_socket_factory_.reset();
+ context_storage_.reset();
+
+ context_.reset(new net::TestURLRequestContext(true));
+ context_storage_.reset(new net::URLRequestContextStorage(context_.get()));
+ mock_socket_factory_.reset(new net::MockClientSocketFactory());
+ context_->set_client_socket_factory(mock_socket_factory_.get());
+
+ drp_test_context_ =
+ DataReductionProxyTestContext::Builder()
+ .WithURLRequestContext(context_.get())
+ .WithMockClientSocketFactory(mock_socket_factory_.get())
+ .Build();
+
+ drp_test_context_->AttachToURLRequestContext(context_storage_.get());
+ context_->Init();
+ base::RunLoop().RunUntilIdle();
+
+ baseline_savings_ =
+ drp_test_context()->settings()->GetTotalHttpContentLengthSaved();
+ }
+
+ void SetUpLoFiDecider(bool is_client_lofi_image,
+ bool is_client_lofi_auto_reload) const {
+ std::unique_ptr<TestLoFiDecider> lofi_decider(new TestLoFiDecider());
+ lofi_decider->SetIsUsingClientLoFi(is_client_lofi_image);
+ lofi_decider->SetIsClientLoFiAutoReload(is_client_lofi_auto_reload);
+ drp_test_context_->io_data()->set_lofi_decider(
+ std::unique_ptr<LoFiDecider>(std::move(lofi_decider)));
+ }
+
+ int64_t GetSavings() const {
+ return drp_test_context()->settings()->GetTotalHttpContentLengthSaved() -
+ baseline_savings_;
+ }
+
+ net::TestURLRequestContext* context() const { return context_.get(); }
+ net::MockClientSocketFactory* mock_socket_factory() const {
+ return mock_socket_factory_.get();
+ }
+ DataReductionProxyTestContext* drp_test_context() const {
+ return drp_test_context_.get();
+ }
+
+ private:
+ base::MessageLoopForIO loop;
+ std::unique_ptr<net::TestURLRequestContext> context_;
+ std::unique_ptr<net::URLRequestContextStorage> context_storage_;
+ std::unique_ptr<net::MockClientSocketFactory> mock_socket_factory_;
+ std::unique_ptr<DataReductionProxyTestContext> drp_test_context_;
+ int64_t baseline_savings_;
+};
+
+DataReductionProxyNetworkDelegateClientLoFiTest::
+ ~DataReductionProxyNetworkDelegateClientLoFiTest() {}
+
+TEST_F(DataReductionProxyNetworkDelegateClientLoFiTest, DataSavingsNonDRP) {
+ const char kSimple200ResponseHeaders[] =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 140\r\n\r\n";
+
+ const struct {
+ const char* headers;
+ size_t response_length;
+ bool is_client_lofi_image;
+ bool is_client_lofi_auto_reload;
+ int64_t expected_savings;
+ } tests[] = {
+ // 200 responses shouldn't see any savings.
+ {kSimple200ResponseHeaders, 140, false, false, 0},
+ {kSimple200ResponseHeaders, 140, true, false, 0},
+
+ // Client Lo-Fi Auto-reload responses should see negative savings.
+ {kSimple200ResponseHeaders, 140, false, true,
+ -(static_cast<int64_t>(sizeof(kSimple200ResponseHeaders) - 1) + 140)},
+ {kSimple200ResponseHeaders, 140, true, true,
+ -(static_cast<int64_t>(sizeof(kSimple200ResponseHeaders) - 1) + 140)},
+
+ // A range response that doesn't use Client Lo-Fi shouldn't see any
+ // savings.
+ {"HTTP/1.1 206 Partial Content\r\n"
+ "Content-Range: bytes 0-2047/10000\r\n"
+ "Content-Length: 2048\r\n\r\n",
+ 2048, false, false, 0},
+
+ // A Client Lo-Fi range response should see savings based on the
+ // Content-Range header.
+ {"HTTP/1.1 206 Partial Content\r\n"
+ "Content-Range: bytes 0-2047/10000\r\n"
+ "Content-Length: 2048\r\n\r\n",
+ 2048, true, false, 10000 - 2048},
+
+ // A Client Lo-Fi range response should see savings based on the
+ // Content-Range header, which in this case is 0 savings because the range
+ // response contained the entire resource.
+ {"HTTP/1.1 206 Partial Content\r\n"
+ "Content-Range: bytes 0-999/1000\r\n"
+ "Content-Length: 1000\r\n\r\n",
+ 1000, true, false, 0},
+
+ // Client Lo-Fi range responses that don't have a Content-Range with the
+ // full resource length shouldn't see any savings.
+ {"HTTP/1.1 206 Partial Content\r\n"
+ "Content-Length: 2048\r\n\r\n",
+ 2048, true, false, 0},
+ {"HTTP/1.1 206 Partial Content\r\n"
+ "Content-Range: bytes 0-2047/*\r\n"
+ "Content-Length: 2048\r\n\r\n",
+ 2048, true, false, 0},
+ {"HTTP/1.1 206 Partial Content\r\n"
+ "Content-Range: invalid_content_range\r\n"
+ "Content-Length: 2048\r\n\r\n",
+ 2048, true, false, 0},
+ };
+
+ for (const auto& test : tests) {
+ Reset();
+ SetUpLoFiDecider(test.is_client_lofi_image,
+ test.is_client_lofi_auto_reload);
+
+ std::string response_body(test.response_length, 'a');
+ net::MockRead reads[] = {net::MockRead(test.headers),
+ net::MockRead(response_body.c_str()),
+ net::MockRead(net::ASYNC, net::OK)};
+ net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0);
+ mock_socket_factory()->AddSocketDataProvider(&socket);
+
+ net::TestDelegate test_delegate;
+ std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
+ GURL("http://example.com"), net::RequestPriority::IDLE, &test_delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(test.expected_savings, GetSavings()) << (&test - tests);
+ }
+}
+
+TEST_F(DataReductionProxyNetworkDelegateClientLoFiTest, DataSavingsThroughDRP) {
+ Reset();
+ drp_test_context()->EnableDataReductionProxyWithSecureProxyCheckSuccess();
+ SetUpLoFiDecider(true, false);
+
+ const char kHeaders[] =
+ "HTTP/1.1 206 Partial Content\r\n"
+ "Content-Range: bytes 0-2047/10000\r\n"
+ "Content-Length: 2048\r\n"
+ "Via: 1.1 Chrome-Compression-Proxy\r\n"
+ "X-Original-Content-Length: 3000\r\n\r\n";
+
+ std::string response_body(2048, 'a');
+ net::MockRead reads[] = {net::MockRead(kHeaders),
+ net::MockRead(response_body.c_str()),
+ net::MockRead(net::ASYNC, net::OK)};
+ net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0);
+ mock_socket_factory()->AddSocketDataProvider(&socket);
+
+ net::TestDelegate test_delegate;
+ std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
+ GURL("http://example.com"), net::RequestPriority::IDLE, &test_delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ // Since the Data Reduction Proxy is enabled, the length of the raw headers
+ // should be used in the estimated original size. The X-OCL should be ignored.
+ EXPECT_EQ(static_cast<int64_t>(net::HttpUtil::AssembleRawHeaders(
+ kHeaders, sizeof(kHeaders) - 1)
+ .size() +
+ 10000 - request->GetTotalReceivedBytes()),
+ GetSavings());
+}
+
} // namespace
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
index 4d21e6666ed..24aa6a384bc 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.cc
@@ -20,6 +20,7 @@
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "net/base/load_flags.h"
#include "net/nqe/effective_connection_type.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"
@@ -111,6 +112,11 @@ void AddDataToPageloadMetrics(const DataReductionProxyData& request_data,
request->set_previews_type(PageloadMetrics_PreviewsType_NONE);
}
+ // Only report opt out information if a server preview was shown (otherwise,
+ // report opt out unknown). Similarly, if app background (Android) caused this
+ // report to be sent before the page load is terminated, do not report opt out
+ // information as the user could reload the original preview after this report
+ // is sent.
if (!was_preview_shown || timing.app_background_occurred) {
request->set_previews_opt_out(PageloadMetrics_PreviewsOptOut_UNKNOWN);
return;
@@ -191,12 +197,39 @@ void DataReductionProxyPingbackClient::CreateFetcherForDataAndStart() {
std::string serialized_request =
AddTimeAndSerializeRequest(&metrics_request_, CurrentTime());
metrics_request_.Clear();
- current_fetcher_ =
- net::URLFetcher::Create(pingback_url_, net::URLFetcher::POST, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("data_reduction_proxy_pingback", R"(
+ semantics {
+ sender: "Data Reduction Proxy"
+ description:
+ "Sends page performance and data efficiency metrics to the data "
+ "reduction proxy."
+ trigger:
+ "Sent after a page load, if the page was loaded via the data "
+ "reduction proxy."
+ data:
+ "URL, request time, response time, page size, connection type, and "
+ "performance measures. See the following for details: "
+ "components/data_reduction_proxy/proto/pageload_metrics.proto"
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can control Data Saver on Android via 'Data Saver' setting. "
+ "Data Saver is not available on iOS, and on desktop it is enabled "
+ "by insalling the Data Saver extension. While Data Saver is "
+ "enabled, this feature cannot be disabled by settings."
+ policy_exception_justification: "Not implemented."
+ })");
+ current_fetcher_ = net::URLFetcher::Create(
+ pingback_url_, net::URLFetcher::POST, this, traffic_annotation);
data_use_measurement::DataUseUserData::AttachToFetcher(
current_fetcher_.get(),
data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY);
- current_fetcher_->SetLoadFlags(net::LOAD_BYPASS_PROXY);
+ current_fetcher_->SetLoadFlags(net::LOAD_BYPASS_PROXY |
+ net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
current_fetcher_->SetUploadData("application/x-protobuf", serialized_request);
current_fetcher_->SetRequestContext(url_request_context_);
// |current_fetcher_| should not retry on 5xx errors since the server may
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
index 85671575bb3..8d241701f34 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
@@ -39,7 +39,7 @@ class DataReductionProxyPrefsTest : public testing::Test {
PrefService* pref_service) {
ListPrefUpdate list(local_state_prefs(), pref_name);
for (int64_t i = 0; i < 10L; ++i) {
- list->Set(i, new base::Value(base::Int64ToString(i + starting_value)));
+ list->AppendString(base::Int64ToString(i + starting_value));
}
}
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc
index 470a67597e5..2dc55ff8b81 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc
@@ -17,6 +17,7 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
@@ -100,12 +101,13 @@ std::string DataReductionProxyRequestOptions::GetHeaderValueForTesting() const {
}
void DataReductionProxyRequestOptions::UpdateExperiments() {
- // TODO(bengr): Simplify this so there's only one way to set experiment via
- // flags. See crbug.com/656195.
+ experiments_.clear();
std::string experiments =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
data_reduction_proxy::switches::kDataReductionProxyExperiment);
+ // The command line override takes precedence over field trial "exp"
+ // directives.
if (!experiments.empty()) {
base::StringTokenizer experiment_tokenizer(experiments, ", ");
experiment_tokenizer.set_quote_chars("\"");
@@ -113,7 +115,11 @@ void DataReductionProxyRequestOptions::UpdateExperiments() {
if (!experiment_tokenizer.token().empty())
experiments_.push_back(experiment_tokenizer.token());
}
+ } else if (params::AreLitePagesEnabledViaFlags()) {
+ experiments_.push_back(chrome_proxy_force_lite_page_experiment());
} else {
+ // If no other "exp" directive is forced by flags, add the field trial
+ // value.
AddServerExperimentFromFieldTrial();
}
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
index 1e58b8a5452..fa8df6aff62 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
@@ -11,6 +11,7 @@
#include "base/command_line.h"
#include "base/md5.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
@@ -330,6 +331,56 @@ TEST_F(DataReductionProxyRequestOptionsTest, ParseExperimentsFromFieldTrial) {
}
}
+TEST_F(DataReductionProxyRequestOptionsTest, TestExperimentPrecedence) {
+ // Tests that combinations of configurations that trigger "exp=" directive in
+ // the Chrome-Proxy header have the right precendence, and only append a value
+ // for the highest priority value.
+
+ // Field trial has the lowest priority.
+ std::map<std::string, std::string> server_experiment;
+ server_experiment["exp"] = "foo";
+ ASSERT_TRUE(variations::AssociateVariationParams(
+ params::GetServerExperimentsFieldTrialName(), "enabled",
+ server_experiment));
+
+ base::FieldTrialList field_trial_list(nullptr);
+ base::FieldTrialList::CreateFieldTrial(
+ params::GetServerExperimentsFieldTrialName(), "enabled");
+ std::vector<std::string> expected_experiments;
+ expected_experiments.push_back("foo");
+ std::string expected_header;
+ SetHeaderExpectations(kExpectedSession, kExpectedCredentials, std::string(),
+ kClientStr, kExpectedBuild, kExpectedPatch, kPageId,
+ expected_experiments, &expected_header);
+ CreateRequestOptions(kVersion);
+ VerifyExpectedHeader(expected_header, kPageIdValue);
+
+ // "force_lite_page" has the next lowest priority.
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kDataReductionProxyLoFi,
+ switches::kDataReductionProxyLoFiValueAlwaysOn);
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableDataReductionProxyLitePage);
+ expected_experiments.clear();
+ expected_experiments.push_back(chrome_proxy_force_lite_page_experiment());
+ SetHeaderExpectations(kExpectedSession, kExpectedCredentials, std::string(),
+ kClientStr, kExpectedBuild, kExpectedPatch, kPageId,
+ expected_experiments, &expected_header);
+ CreateRequestOptions(kVersion);
+ VerifyExpectedHeader(expected_header, kPageIdValue);
+
+ // Setting the experiment explicitly has the highest priority.
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ data_reduction_proxy::switches::kDataReductionProxyExperiment, "bar");
+ expected_experiments.clear();
+ expected_experiments.push_back("bar");
+ SetHeaderExpectations(kExpectedSession, kExpectedCredentials, std::string(),
+ kClientStr, kExpectedBuild, kExpectedPatch, kPageId,
+ expected_experiments, &expected_header);
+ CreateRequestOptions(kVersion);
+ VerifyExpectedHeader(expected_header, kPageIdValue);
+}
+
TEST_F(DataReductionProxyRequestOptionsTest, GetSessionKeyFromRequestHeaders) {
const struct {
std::string chrome_proxy_header_key;
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
index e0abfe8769e..970be81f2ab 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
@@ -13,6 +13,7 @@
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner_util.h"
+#include "base/time/time.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h"
@@ -91,6 +92,16 @@ void DataReductionProxyService::Shutdown() {
weak_factory_.InvalidateWeakPtrs();
}
+void DataReductionProxyService::UpdateDataUseForHost(int64_t network_bytes,
+ int64_t original_bytes,
+ const std::string& host) {
+ DCHECK(CalledOnValidThread());
+ if (compression_stats_) {
+ compression_stats_->RecordDataUsage(host, original_bytes, network_bytes,
+ base::Time::Now());
+ }
+}
+
void DataReductionProxyService::UpdateContentLengths(
int64_t data_used,
int64_t original_size,
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
index b1d8fc167ae..077f0d20a1c 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
@@ -77,6 +77,11 @@ class DataReductionProxyService
// final step in initialization.
bool Initialized() const;
+ // Records data usage per host.
+ void UpdateDataUseForHost(int64_t network_bytes,
+ int64_t original_bytes,
+ const std::string& host);
+
// Records daily data savings statistics in |compression_stats_|.
void UpdateContentLengths(int64_t data_used,
int64_t original_size,
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
index 8af34b7db5c..e111c5a745c 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -12,6 +12,7 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/md5.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_samples.h"
#include "base/test/histogram_tester.h"
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.cc b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.cc
index 6e09db8dc84..f2547d74569 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.cc
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.cc
@@ -7,8 +7,7 @@
namespace data_reduction_proxy {
namespace features {
-// Enables the Data Reduction Proxy menu item in the main menu rather than under
-// Settings on Android.
+// Enables the Data Reduction Proxy footer in the main menu on Android.
const base::Feature kDataReductionMainMenu{"DataReductionProxyMainMenu",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -16,5 +15,12 @@ const base::Feature kDataReductionMainMenu{"DataReductionProxyMainMenu",
const base::Feature kDataReductionSiteBreakdown{
"DataReductionProxySiteBreakdown", base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables a new version of the data reduction proxy protocol where the server
+// decides if a server-generated preview should be served. The previous
+// version required the client to make this decision. The new protocol relies
+// on updates primarily to the Chrome-Proxy-Accept-Transform header.
+const base::Feature kDataReductionProxyDecidesTransform{
+ "DataReductionProxyDecidesTransform", base::FEATURE_DISABLED_BY_DEFAULT};
+
} // namespace features
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.h b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.h
index 9913b055a51..af951c894ae 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.h
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.h
@@ -12,6 +12,7 @@ namespace features {
extern const base::Feature kDataReductionMainMenu;
extern const base::Feature kDataReductionSiteBreakdown;
+extern const base::Feature kDataReductionProxyDecidesTransform;
} // namespace features
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
index 3a697aecaf8..8961f1b7afb 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -29,6 +29,7 @@ using base::TimeDelta;
namespace {
const char kChromeProxyHeader[] = "chrome-proxy";
+const char kChromeProxyECTHeader[] = "chrome-proxy-ect";
const char kChromeProxyAcceptTransformHeader[] =
"chrome-proxy-accept-transform";
const char kChromeProxyContentTransformHeader[] =
@@ -45,8 +46,7 @@ const char kIdentityDirective[] = "identity";
// The legacy Chrome-Proxy response header directive for LoFi images.
const char kLegacyChromeProxyLoFiResponseDirective[] = "q=low";
-const char kChromeProxyLitePageIngoreBlacklistDirective[] =
- "exp=ignore_preview_blacklist";
+const char kChromeProxyForceLitePageExperiment[] = "force_lite_page";
const char kIfHeavyQualifier[] = "if-heavy";
@@ -126,6 +126,10 @@ const char* chrome_proxy_header() {
return kChromeProxyHeader;
}
+const char* chrome_proxy_ect_header() {
+ return kChromeProxyECTHeader;
+}
+
const char* chrome_proxy_accept_transform_header() {
return kChromeProxyAcceptTransformHeader;
}
@@ -150,8 +154,8 @@ const char* identity_directive() {
return kIdentityDirective;
}
-const char* chrome_proxy_lite_page_ignore_blacklist_directive() {
- return kChromeProxyLitePageIngoreBlacklistDirective;
+const char* chrome_proxy_force_lite_page_experiment() {
+ return kChromeProxyForceLitePageExperiment;
}
const char* if_heavy_qualifier() {
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
index e059d641d74..83202075cf1 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
@@ -68,6 +68,10 @@ struct DataReductionProxyInfo {
// Gets the header used for data reduction proxy requests and responses.
const char* chrome_proxy_header();
+// Gets the chrome-proxy-ect request header that includes the effective
+// connection type.
+const char* chrome_proxy_ect_header();
+
// Gets the ChromeProxyAcceptTransform header name.
const char* chrome_proxy_accept_transform_header();
@@ -94,9 +98,9 @@ const char* identity_directive();
// preview requests and responses.
const char* chrome_proxy_lite_page_directive();
-// Gets the Chrome-Proxy directive used by data reduction proxy lite page
-// preview experiment to ignore the blacklist.
-const char* chrome_proxy_lite_page_ignore_blacklist_directive();
+// Gets the Chrome-Proxy experiment ("exp") value to force a lite page preview
+// for requests that accept lite pages.
+const char* chrome_proxy_force_lite_page_experiment();
// Requests a transformation only if the server determines that the page is
// otherwise heavy (i.e., the associated page load ordinarily requires the
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
index 44bb16c9f56..f0a2d3d0831 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -45,6 +45,9 @@ const char kLitePageFallbackFieldTrial[] =
"DataCompressionProxyLitePageFallback";
const char kLoFiFlagFieldTrial[] = "DataCompressionProxyLoFiFlag";
+const char kBlackListTransitionFieldTrial[] =
+ "DataReductionProxyPreviewsBlackListTransition";
+
const char kTrustedSpdyProxyFieldTrialName[] = "DataReductionTrustedSpdyProxy";
// Default URL for retrieving the Data Reduction Proxy configuration.
@@ -59,6 +62,9 @@ const char kPingbackURL[] =
const char kServerExperimentsFieldTrial[] =
"DataReductionProxyServerExperiments";
+// LitePage black list version.
+const char kLitePageBlackListVersion[] = "lite-page-blacklist-version";
+
bool IsIncludedInFieldTrial(const std::string& name) {
return base::StartsWith(FieldTrialList::FindFullName(name), kEnabled,
base::CompareCase::SENSITIVE);
@@ -249,15 +255,6 @@ const char* GetQuicFieldTrialName() {
return kQuicFieldTrial;
}
-bool IsZeroRttQuicEnabled() {
- if (!IsIncludedInQuicFieldTrial())
- return false;
- std::map<std::string, std::string> params;
- variations::GetVariationParams(GetQuicFieldTrialName(), &params);
- return GetStringValueForVariationParamWithDefaultValue(
- params, "enable_zero_rtt", "false") == "true";
-}
-
bool IsBrotliAcceptEncodingEnabled() {
// Brotli encoding is enabled by default since the data reduction proxy server
// controls when to serve Brotli encoded content. It can be disabled in
@@ -276,6 +273,12 @@ bool IsConfigClientEnabled() {
kDisabled, base::CompareCase::SENSITIVE);
}
+bool IsBlackListEnabledForServerPreviews() {
+ return base::StartsWith(
+ base::FieldTrialList::FindFullName(kBlackListTransitionFieldTrial),
+ kEnabled, base::CompareCase::SENSITIVE);
+}
+
GURL GetConfigServiceURL() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::string url;
@@ -321,6 +324,12 @@ bool ShouldForceEnableDataReductionProxy() {
data_reduction_proxy::switches::kEnableDataReductionProxy);
}
+int LitePageVersion() {
+ return GetFieldTrialParameterAsInteger(
+ data_reduction_proxy::params::GetLoFiFieldTrialName(),
+ kLitePageBlackListVersion, 0, 0);
+}
+
int GetFieldTrialParameterAsInteger(const std::string& group,
const std::string& param_name,
int default_value,
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
index eab391b026e..badc927146f 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -127,9 +127,6 @@ bool IsQuicEnabledForNonCoreProxies();
const char* GetQuicFieldTrialName();
-// Returns true if zero RTT for QUIC is enabled.
-bool IsZeroRttQuicEnabled();
-
// Returns true if Brotli should be added to the accept-encoding header.
bool IsBrotliAcceptEncodingEnabled();
@@ -148,6 +145,13 @@ GURL GetConfigServiceURL();
// command line.
bool ShouldForceEnableDataReductionProxy();
+// Whether the blacklist should be used for server Lo-Fi and server Lite Page
+// instead of the prefs-based rules.
+bool IsBlackListEnabledForServerPreviews();
+
+// The current LitePage experiment blacklist version.
+int LitePageVersion();
+
// Retrieves the int stored in |param_name| from the field trial group
// |group|. If the value is not present, cannot be parsed, or is less than
// |min_value|, returns |default_value|.
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
index b045ae0ddd9..0c983328807 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -408,29 +408,23 @@ TEST_F(DataReductionProxyParamsTest, QuicFieldTrial) {
const struct {
std::string trial_group_name;
bool expected_enabled;
- std::string zero_rtt_param;
- bool expected_zero_rtt;
bool enable_warmup_url;
bool expect_warmup_url_enabled;
std::string warmup_url;
} tests[] = {
- {"Enabled", true, "true", true, true, true, std::string()},
- {"Enabled", true, "true", true, false, false, std::string()},
- {"Enabled_Control", true, "true", true, true, true, std::string()},
- {"Enabled_Control", true, "false", false, true, true, std::string()},
- {"Enabled_Control", true, std::string(), false, true, true,
- std::string()},
- {"Control", false, "true", false, true, true, std::string()},
- {"Disabled", false, "false", false, true, false, std::string()},
- {"enabled", true, "false", false, true, true, std::string()},
- {"Enabled", true, "true", true, true, true, "example.com/test.html"},
- {std::string(), true, "true", false, false, false, std::string()},
+ {"Enabled", true, true, true, std::string()},
+ {"Enabled", true, false, false, std::string()},
+ {"Enabled_Control", true, true, true, std::string()},
+ {"Control", false, true, true, std::string()},
+ {"Disabled", false, true, false, std::string()},
+ {"enabled", true, true, true, std::string()},
+ {"Enabled", true, true, true, "example.com/test.html"},
+ {std::string(), true, false, false, std::string()},
};
for (const auto& test : tests) {
variations::testing::ClearAllVariationParams();
std::map<std::string, std::string> variation_params;
- variation_params["enable_zero_rtt"] = test.zero_rtt_param;
if (test.enable_warmup_url)
variation_params["enable_warmup"] = "true";
@@ -445,7 +439,6 @@ TEST_F(DataReductionProxyParamsTest, QuicFieldTrial) {
test.trial_group_name);
EXPECT_EQ(test.expected_enabled, params::IsIncludedInQuicFieldTrial());
- EXPECT_EQ(test.expected_zero_rtt, params::IsZeroRttQuicEnabled());
if (!test.warmup_url.empty()) {
EXPECT_EQ(GURL(test.warmup_url), params::GetWarmupURL());
} else {
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
index 82dc96a2074..4877facd493 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
@@ -18,6 +18,10 @@ const char kDataReductionProxyConfigURL[] = "data-reduction-proxy-config-url";
// Proxy field trials.
const char kDataReductionProxyExperiment[] = "data-reduction-proxy-experiment";
+// The Chrome-Proxy "exp" directive value used by data reduction proxy to
+// receive an alternative back end implementation.
+const char kDataReductionProxyServerAlternative[] = "alternative";
+
// The origin of the data reduction proxy fallback.
const char kDataReductionProxyFallback[] = "spdy-proxy-auth-fallback";
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
index cbc063d6836..0773ba8d281 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
@@ -11,6 +11,7 @@ namespace switches {
// All switches in alphabetical order. The switches should be documented
// alongside the definition of their values in the .cc file.
+extern const char kDataReductionPingbackURL[];
extern const char kDataReductionProxy[];
extern const char kDataReductionProxyConfigURL[];
extern const char kDataReductionProxyExperiment[];
@@ -22,9 +23,9 @@ extern const char kDataReductionProxyLoFiValueAlwaysOn[];
extern const char kDataReductionProxyLoFiValueCellularOnly[];
extern const char kDataReductionProxyLoFiValueDisabled[];
extern const char kDataReductionProxyLoFiValueSlowConnectionsOnly[];
-extern const char kDataReductionPingbackURL[];
extern const char kDataReductionProxySecureProxyCheckURL[];
extern const char kDataReductionProxyServerExperimentsDisabled[];
+extern const char kDataReductionProxyServerAlternative[];
extern const char kDataReductionProxyWarmupURL[];
extern const char kEnableDataReductionProxy[];
extern const char kEnableDataReductionProxyBypassWarning[];
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.cc b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.cc
index 9af46dd61df..ed6759db08d 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.cc
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.cc
@@ -13,6 +13,7 @@
#include "net/base/net_errors.h"
#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_info.h"
#include "net/url_request/url_request.h"
@@ -131,11 +132,6 @@ const char* GetStringForClient(Client client) {
}
}
-bool IsMethodIdempotent(const std::string& method) {
- return method == "GET" || method == "OPTIONS" || method == "HEAD" ||
- method == "PUT" || method == "DELETE" || method == "TRACE";
-}
-
GURL AddApiKeyToUrl(const GURL& url) {
GURL new_url = url;
#if defined(USE_GOOGLE_API_KEYS)
@@ -151,7 +147,7 @@ bool EligibleForDataReductionProxy(const net::ProxyInfo& proxy_info,
const GURL& url,
const std::string& method) {
return proxy_info.is_direct() && proxy_info.proxy_list().size() == 1 &&
- !url.SchemeIsWSOrWSS() && IsMethodIdempotent(method);
+ !url.SchemeIsWSOrWSS() && net::HttpUtil::IsMethodIdempotent(method);
}
bool ApplyProxyConfigToProxyInfo(const net::ProxyConfig& proxy_config,
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.h b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.h
index be0a16dabff..811faa9025f 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.h
+++ b/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_util.h
@@ -66,9 +66,6 @@ void GetChromiumBuildAndPatchAsInts(const std::string& version_string,
// Get the human-readable version of |client|.
const char* GetStringForClient(Client client);
-// Returns true if the request method is idempotent.
-bool IsMethodIdempotent(const std::string& method);
-
GURL AddApiKeyToUrl(const GURL& url);
// Returns whether this is valid for data reduction proxy use. |proxy_info|
diff --git a/chromium/components/data_reduction_proxy/core/common/lofi_decider.h b/chromium/components/data_reduction_proxy/core/common/lofi_decider.h
index 2eca7590fdb..61ce4668d6d 100644
--- a/chromium/components/data_reduction_proxy/core/common/lofi_decider.h
+++ b/chromium/components/data_reduction_proxy/core/common/lofi_decider.h
@@ -54,15 +54,19 @@ class LoFiDecider {
virtual void RemoveAcceptTransformHeader(
net::HttpRequestHeaders* headers) const = 0;
- // Adds a directive to tell the server to ignore blacklists when a Lite Page
- // preview is being requested due to command line flags being set.
- virtual void MaybeSetIgnorePreviewsBlacklistDirective(
- net::HttpRequestHeaders* headers) const = 0;
-
// Returns true if the Lo-Fi specific UMA should be recorded. It is set to
// true if Lo-Fi is enabled for |request|, Chrome session is in Lo-Fi
// Enabled or Control field trial, and the network quality was slow.
virtual bool ShouldRecordLoFiUMA(const net::URLRequest& request) const = 0;
+
+ // Returns whether the request was a client-side Lo-Fi image request.
+ virtual bool IsClientLoFiImageRequest(
+ const net::URLRequest& request) const = 0;
+
+ // Returns true if the request is for a client-side Lo-Fi image that is being
+ // automatically reloaded because of a decoding error.
+ virtual bool IsClientLoFiAutoReloadRequest(
+ const net::URLRequest& request) const = 0;
};
} // namespace data_reduction_proxy
diff --git a/chromium/components/data_use_measurement/core/data_use.cc b/chromium/components/data_use_measurement/core/data_use.cc
index c84da07f1fa..99fb8cb2f95 100644
--- a/chromium/components/data_use_measurement/core/data_use.cc
+++ b/chromium/components/data_use_measurement/core/data_use.cc
@@ -6,15 +6,18 @@
namespace data_use_measurement {
-DataUse::DataUse() : total_bytes_sent_(0), total_bytes_received_(0) {}
-
-DataUse::DataUse(const DataUse& other) :
- total_bytes_sent_(other.total_bytes_sent_),
- total_bytes_received_(other.total_bytes_received_) {}
+DataUse::DataUse(TrafficType traffic_type)
+ : traffic_type_(traffic_type),
+ total_bytes_sent_(0),
+ total_bytes_received_(0) {}
DataUse::~DataUse() {}
void DataUse::MergeFrom(const DataUse& other) {
+ // Traffic type need not be same while merging. One of the data use created
+ // when mainframe is created could have UNKNOWN traffic type, and later merged
+ // with the data use created for its mainframe request which could be
+ // USER_TRAFFIC.
total_bytes_sent_ += other.total_bytes_sent_;
total_bytes_received_ += other.total_bytes_received_;
}
diff --git a/chromium/components/data_use_measurement/core/data_use.h b/chromium/components/data_use_measurement/core/data_use.h
index 18e706dc6d4..d2b789706fd 100644
--- a/chromium/components/data_use_measurement/core/data_use.h
+++ b/chromium/components/data_use_measurement/core/data_use.h
@@ -10,21 +10,42 @@
#include <string>
#include "base/macros.h"
+#include "base/supports_user_data.h"
#include "base/time/time.h"
#include "url/gurl.h"
namespace data_use_measurement {
// Class to store total network data used by some entity.
-class DataUse {
+class DataUse : public base::SupportsUserData {
public:
- DataUse();
- DataUse(const DataUse& other);
- ~DataUse();
+ enum class TrafficType {
+ // Unknown type. URLRequests for arbitrary scheme such as blob, file,
+ // extensions, chrome URLs fall under this bucket - url/url_constants.cc
+ // TODO(rajendrant): Record metrics on the distribution of these type. It is
+ // also possible to remove this UNKNOWN type altogether by skipping the URL
+ // schemes that do not make use of network.
+ UNKNOWN,
+
+ // User initiated traffic.
+ USER_TRAFFIC,
+
+ // Chrome services.
+ SERVICES,
+
+ // Fetch from ServiceWorker.
+ SERVICE_WORKER,
+ };
+
+ explicit DataUse(TrafficType traffic_type);
+ ~DataUse() override;
// Merge data use from another instance.
+ // TODO(rajendrant): Check if the merge can be removed. Otherwise user data
+ // needs to support mergeability.
void MergeFrom(const DataUse& other);
+ // Returns the page URL.
const GURL& url() const { return url_; }
void set_url(const GURL& url) { url_ = url; }
@@ -39,14 +60,21 @@ class DataUse {
int64_t total_bytes_sent() const { return total_bytes_sent_; }
+ TrafficType traffic_type() const { return traffic_type_; }
+
private:
+ // TODO(rajendrant): Remove this friend after adding member function to
+ // increment total sent/received bytes.
friend class DataUseRecorder;
GURL url_;
std::string description_;
+ const TrafficType traffic_type_;
int64_t total_bytes_sent_;
int64_t total_bytes_received_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataUse);
};
} // namespace data_use_measurement
diff --git a/chromium/components/data_use_measurement/core/data_use_ascriber.cc b/chromium/components/data_use_measurement/core/data_use_ascriber.cc
index c7c9d49052e..7270859f6bf 100644
--- a/chromium/components/data_use_measurement/core/data_use_ascriber.cc
+++ b/chromium/components/data_use_measurement/core/data_use_ascriber.cc
@@ -14,6 +14,9 @@
namespace data_use_measurement {
+DataUseAscriber::DataUseAscriber() {}
+DataUseAscriber::~DataUseAscriber() {}
+
std::unique_ptr<net::NetworkDelegate> DataUseAscriber::CreateNetworkDelegate(
std::unique_ptr<net::NetworkDelegate> wrapped_network_delegate,
const metrics::UpdateUsagePrefCallbackType& metrics_data_use_forwarder) {
@@ -42,7 +45,7 @@ void DataUseAscriber::OnNetworkBytesReceived(net::URLRequest* request,
recorder->OnNetworkBytesReceived(request, bytes_received);
}
-void DataUseAscriber::OnUrlRequestCompleted(net::URLRequest* request,
+void DataUseAscriber::OnUrlRequestCompleted(const net::URLRequest& request,
bool started) {}
void DataUseAscriber::OnUrlRequestDestroyed(net::URLRequest* request) {
diff --git a/chromium/components/data_use_measurement/core/data_use_ascriber.h b/chromium/components/data_use_measurement/core/data_use_ascriber.h
index 78f2b3813aa..4c38b5c1f9b 100644
--- a/chromium/components/data_use_measurement/core/data_use_ascriber.h
+++ b/chromium/components/data_use_measurement/core/data_use_ascriber.h
@@ -9,6 +9,8 @@
#include <memory>
+#include "base/observer_list.h"
+#include "base/threading/thread_checker.h"
#include "components/data_use_measurement/core/data_use_measurement.h"
#include "components/metrics/data_use_tracker.h"
#include "url/gurl.h"
@@ -20,6 +22,7 @@ class URLRequest;
namespace data_use_measurement {
+class DataUse;
class DataUseRecorder;
class URLRequestClassifier;
@@ -30,7 +33,28 @@ class URLRequestClassifier;
// together and reported as a single use.
class DataUseAscriber {
public:
- virtual ~DataUseAscriber() {}
+ // Provides the interface for observing data use of a pageload.
+ class PageLoadObserver {
+ public:
+ virtual ~PageLoadObserver() {}
+
+ // The page load committed. |data_use| contains the currently committed URL,
+ // and the network data used by the page so far.
+ virtual void OnPageLoadCommit(DataUse* data_use) = 0;
+
+ // A resource of a page loaded. This includes main frame, sub frame
+ // resource, subresource. |data_use| contains the network data used by the
+ // page so far. URL in |data_use| may not be available until OnCommit.
+ virtual void OnPageResourceLoad(const net::URLRequest& request,
+ DataUse* data_use) = 0;
+
+ // The page load completed. This is when the tab is closed or another
+ // navigation starts due to omnibox search, link clicks, page reload, etc.
+ virtual void OnPageLoadComplete(DataUse* data_use) = 0;
+ };
+
+ DataUseAscriber();
+ virtual ~DataUseAscriber();
// Creates a network delegate that will be used to track data use.
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate(
@@ -53,13 +77,32 @@ class DataUseAscriber {
virtual std::unique_ptr<URLRequestClassifier> CreateURLRequestClassifier()
const = 0;
+ // Observers should be added or removed in IO thread. The notifications will
+ // be called in the same thread.
+ void AddObserver(PageLoadObserver* observer) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ observers_.AddObserver(observer);
+ }
+
+ void RemoveObserver(PageLoadObserver* observer) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ observers_.RemoveObserver(observer);
+ }
+
// Methods called by DataUseNetworkDelegate to propagate data use information:
virtual void OnBeforeUrlRequest(net::URLRequest* request);
virtual void OnNetworkBytesSent(net::URLRequest* request, int64_t bytes_sent);
virtual void OnNetworkBytesReceived(net::URLRequest* request,
int64_t bytes_received);
- virtual void OnUrlRequestCompleted(net::URLRequest* request, bool started);
+ virtual void OnUrlRequestCompleted(const net::URLRequest& request,
+ bool started);
virtual void OnUrlRequestDestroyed(net::URLRequest* request);
+
+ protected:
+ base::ObserverList<PageLoadObserver> observers_;
+
+ private:
+ THREAD_CHECKER(thread_checker_);
};
} // namespace data_use_measurement
diff --git a/chromium/components/data_use_measurement/core/data_use_measurement.cc b/chromium/components/data_use_measurement/core/data_use_measurement.cc
index fcebeb8d070..51971c72569 100644
--- a/chromium/components/data_use_measurement/core/data_use_measurement.cc
+++ b/chromium/components/data_use_measurement/core/data_use_measurement.cc
@@ -4,6 +4,7 @@
#include "components/data_use_measurement/core/data_use_measurement.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/stringprintf.h"
@@ -100,6 +101,8 @@ DataUseMeasurement::DataUseMeasurement(
{
DCHECK(ascriber_);
DCHECK(url_request_classifier_);
+ memset(user_traffic_content_type_bytes_, 0,
+ sizeof(user_traffic_content_type_bytes_));
#if defined(OS_ANDROID)
int64_t bytes = 0;
@@ -132,7 +135,8 @@ void DataUseMeasurement::OnBeforeURLRequest(net::URLRequest* request) {
}
data_use_user_data = new DataUseUserData(service_name, CurrentAppState());
- request->SetUserData(DataUseUserData::kUserDataKey, data_use_user_data);
+ request->SetUserData(DataUseUserData::kUserDataKey,
+ base::WrapUnique(data_use_user_data));
} else {
data_use_user_data->set_app_state(CurrentAppState());
}
@@ -445,12 +449,17 @@ void DataUseMeasurement::RecordContentTypeHistogram(
// Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the
// simple UMA_HISTOGRAM_ENUMERATION macros don't expose 'AddCount'.
if (is_user_traffic) {
- STATIC_HISTOGRAM_POINTER_BLOCK(
- "DataUse.ContentType.UserTraffic", AddCount(content_type, bytes),
- base::LinearHistogram::FactoryGet(
- "DataUse.ContentType.UserTraffic", 1, DataUseUserData::TYPE_MAX,
- DataUseUserData::TYPE_MAX + 1,
- base::HistogramBase::kUmaTargetedHistogramFlag));
+ bytes += user_traffic_content_type_bytes_[content_type];
+ if (bytes >= 1024) {
+ STATIC_HISTOGRAM_POINTER_BLOCK(
+ "DataUse.ContentType.UserTrafficKB",
+ AddCount(content_type, bytes / 1024),
+ base::LinearHistogram::FactoryGet(
+ "DataUse.ContentType.UserTrafficKB", 1, DataUseUserData::TYPE_MAX,
+ DataUseUserData::TYPE_MAX + 1,
+ base::HistogramBase::kUmaTargetedHistogramFlag));
+ }
+ user_traffic_content_type_bytes_[content_type] = bytes % 1024;
} else {
STATIC_HISTOGRAM_POINTER_BLOCK(
"DataUse.ContentType.Services", AddCount(content_type, bytes),
diff --git a/chromium/components/data_use_measurement/core/data_use_measurement.h b/chromium/components/data_use_measurement/core/data_use_measurement.h
index 931d6f1033d..d0e37c1ffb7 100644
--- a/chromium/components/data_use_measurement/core/data_use_measurement.h
+++ b/chromium/components/data_use_measurement/core/data_use_measurement.h
@@ -194,6 +194,10 @@ class DataUseMeasurement {
bool no_reads_since_background_;
#endif
+ // User traffic data use by content type is logged in 1KB increments. The
+ // remaining bytes are saved in this array until logged next time.
+ int16_t user_traffic_content_type_bytes_[DataUseUserData::TYPE_MAX];
+
DISALLOW_COPY_AND_ASSIGN(DataUseMeasurement);
};
diff --git a/chromium/components/data_use_measurement/core/data_use_measurement_unittest.cc b/chromium/components/data_use_measurement/core/data_use_measurement_unittest.cc
index 87ce637a5e4..c2aed267010 100644
--- a/chromium/components/data_use_measurement/core/data_use_measurement_unittest.cc
+++ b/chromium/components/data_use_measurement/core/data_use_measurement_unittest.cc
@@ -43,7 +43,8 @@ class TestURLRequestClassifier : public base::SupportsUserData::Data,
}
static void MarkAsUserRequest(net::URLRequest* request) {
- request->SetUserData(kUserDataKey, new TestURLRequestClassifier());
+ request->SetUserData(kUserDataKey,
+ base::MakeUnique<TestURLRequestClassifier>());
}
DataUseUserData::DataUseContentType GetContentType(
@@ -69,7 +70,7 @@ class TestURLRequestClassifier : public base::SupportsUserData::Data,
class TestDataUseAscriber : public DataUseAscriber {
public:
- TestDataUseAscriber() {}
+ TestDataUseAscriber() : recorder_(DataUse::TrafficType::USER_TRAFFIC) {}
DataUseRecorder* GetOrCreateDataUseRecorder(
net::URLRequest* request) override {
@@ -142,7 +143,7 @@ class DataUseMeasurementTest : public testing::Test {
} else {
request->SetUserData(
data_use_measurement::DataUseUserData::kUserDataKey,
- new data_use_measurement::DataUseUserData(
+ base::MakeUnique<data_use_measurement::DataUseUserData>(
data_use_measurement::DataUseUserData::SUGGESTIONS,
data_use_measurement_.CurrentAppState()));
}
@@ -446,9 +447,9 @@ TEST_F(DataUseMeasurementTest, ContentType) {
base::HistogramTester histogram_tester;
std::unique_ptr<net::URLRequest> request = CreateTestRequest(kUserRequest);
data_use_measurement_.OnBeforeURLRequest(request.get());
- data_use_measurement_.OnNetworkBytesReceived(*request, 1000);
- histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic",
- DataUseUserData::OTHER, 1000);
+ data_use_measurement_.OnNetworkBytesReceived(*request, 10 * 1024);
+ histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTrafficKB",
+ DataUseUserData::OTHER, 10);
}
{
@@ -470,10 +471,10 @@ TEST_F(DataUseMeasurementTest, ContentType) {
url_request_classifier_->set_content_type(DataUseUserData::VIDEO);
data_use_measurement_.OnBeforeURLRequest(request.get());
data_use_measurement_.OnHeadersReceived(request.get(), nullptr);
- data_use_measurement_.OnNetworkBytesReceived(*request, 1000);
+ data_use_measurement_.OnNetworkBytesReceived(*request, 10 * 1024);
- histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic",
- DataUseUserData::VIDEO, 1000);
+ histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTrafficKB",
+ DataUseUserData::VIDEO, 10);
}
// Audio request from background tab.
@@ -484,11 +485,11 @@ TEST_F(DataUseMeasurementTest, ContentType) {
url_request_classifier_->set_content_type(DataUseUserData::AUDIO);
data_use_measurement_.OnBeforeURLRequest(request.get());
data_use_measurement_.OnHeadersReceived(request.get(), nullptr);
- data_use_measurement_.OnNetworkBytesReceived(*request, 1000);
+ data_use_measurement_.OnNetworkBytesReceived(*request, 10 * 1024);
- histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic",
+ histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTrafficKB",
DataUseUserData::AUDIO_TABBACKGROUND,
- 1000);
+ 10);
}
// Video request from background app.
@@ -501,14 +502,35 @@ TEST_F(DataUseMeasurementTest, ContentType) {
ascriber_.SetTabVisibility(false);
data_use_measurement_.OnBeforeURLRequest(request.get());
data_use_measurement_.OnHeadersReceived(request.get(), nullptr);
- data_use_measurement_.OnNetworkBytesReceived(*request, 1000);
+ data_use_measurement_.OnNetworkBytesReceived(*request, 10 * 1024);
- histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTraffic",
+ histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTrafficKB",
DataUseUserData::VIDEO_APPBACKGROUND,
- 1000);
+ 10);
}
}
+TEST_F(DataUseMeasurementTest, ContentTypeInKB) {
+ base::HistogramTester histogram_tester;
+ std::unique_ptr<net::URLRequest> request = CreateTestRequest(kUserRequest);
+ url_request_classifier_->set_content_type(DataUseUserData::VIDEO);
+ data_use_measurement()->OnApplicationStateChangeForTesting(
+ base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES);
+ ascriber_.SetTabVisibility(false);
+ data_use_measurement_.OnBeforeURLRequest(request.get());
+ data_use_measurement_.OnHeadersReceived(request.get(), nullptr);
+ data_use_measurement_.OnNetworkBytesReceived(*request, 600);
+
+ // UserTrafficKB metric is not recorded for the first 600 bytes of data use.
+ histogram_tester.ExpectTotalCount("DataUse.ContentType.UserTrafficKB", 0);
+
+ data_use_measurement_.OnNetworkBytesReceived(*request, 600);
+
+ // UserTrafficKB recorded for 1KB.
+ histogram_tester.ExpectUniqueSample("DataUse.ContentType.UserTrafficKB",
+ DataUseUserData::VIDEO_APPBACKGROUND, 1);
+}
+
#endif
} // namespace data_use_measurement
diff --git a/chromium/components/data_use_measurement/core/data_use_network_delegate.cc b/chromium/components/data_use_measurement/core/data_use_network_delegate.cc
index 0229787ffa2..c296a80ba12 100644
--- a/chromium/components/data_use_measurement/core/data_use_network_delegate.cc
+++ b/chromium/components/data_use_measurement/core/data_use_network_delegate.cc
@@ -66,6 +66,7 @@ void DataUseNetworkDelegate::OnNetworkBytesSentInternal(
void DataUseNetworkDelegate::OnCompletedInternal(net::URLRequest* request,
bool started) {
+ ascriber_->OnUrlRequestCompleted(*request, started);
data_use_measurement_.OnCompleted(*request, started);
}
diff --git a/chromium/components/data_use_measurement/core/data_use_network_delegate_unittest.cc b/chromium/components/data_use_measurement/core/data_use_network_delegate_unittest.cc
index 1a259bb01a1..fda5be088d1 100644
--- a/chromium/components/data_use_measurement/core/data_use_network_delegate_unittest.cc
+++ b/chromium/components/data_use_measurement/core/data_use_network_delegate_unittest.cc
@@ -32,7 +32,8 @@ class TestURLRequestClassifier : public base::SupportsUserData::Data,
}
static void MarkAsUserRequest(net::URLRequest* request) {
- request->SetUserData(kUserDataKey, new TestURLRequestClassifier());
+ request->SetUserData(kUserDataKey,
+ base::MakeUnique<TestURLRequestClassifier>());
}
DataUseUserData::DataUseContentType GetContentType(
@@ -111,7 +112,7 @@ std::unique_ptr<net::URLRequest> RequestURL(
} else {
request->SetUserData(
data_use_measurement::DataUseUserData::kUserDataKey,
- new data_use_measurement::DataUseUserData(
+ base::MakeUnique<data_use_measurement::DataUseUserData>(
data_use_measurement::DataUseUserData::SUGGESTIONS,
data_use_measurement::DataUseUserData::FOREGROUND));
}
diff --git a/chromium/components/data_use_measurement/core/data_use_recorder.cc b/chromium/components/data_use_measurement/core/data_use_recorder.cc
index 4ba402c9502..f9a387043b6 100644
--- a/chromium/components/data_use_measurement/core/data_use_recorder.cc
+++ b/chromium/components/data_use_measurement/core/data_use_recorder.cc
@@ -8,8 +8,8 @@
namespace data_use_measurement {
-DataUseRecorder::DataUseRecorder()
- : main_url_request_(nullptr), is_visible_(false) {}
+DataUseRecorder::DataUseRecorder(DataUse::TrafficType traffic_type)
+ : main_url_request_(nullptr), data_use_(traffic_type), is_visible_(false) {}
DataUseRecorder::~DataUseRecorder() {}
diff --git a/chromium/components/data_use_measurement/core/data_use_recorder.h b/chromium/components/data_use_measurement/core/data_use_recorder.h
index 7a279512f8f..2fee7bf043b 100644
--- a/chromium/components/data_use_measurement/core/data_use_recorder.h
+++ b/chromium/components/data_use_measurement/core/data_use_recorder.h
@@ -25,7 +25,7 @@ namespace data_use_measurement {
// tracked by exactly one DataUseRecorder.
class DataUseRecorder {
public:
- DataUseRecorder();
+ explicit DataUseRecorder(DataUse::TrafficType traffic_type);
virtual ~DataUseRecorder();
// Returns the actual data used by the entity being tracked.
diff --git a/chromium/components/data_use_measurement/core/data_use_user_data.cc b/chromium/components/data_use_measurement/core/data_use_user_data.cc
index ebae0e3d205..4cb0f12cdd0 100644
--- a/chromium/components/data_use_measurement/core/data_use_user_data.cc
+++ b/chromium/components/data_use_measurement/core/data_use_user_data.cc
@@ -8,6 +8,7 @@
#include "base/android/application_status_listener.h"
#endif
+#include "base/memory/ptr_util.h"
#include "net/url_request/url_fetcher.h"
namespace data_use_measurement {
@@ -40,9 +41,9 @@ const void* const DataUseUserData::kUserDataKey =
&DataUseUserData::kUserDataKey;
// static
-base::SupportsUserData::Data* DataUseUserData::Create(
+std::unique_ptr<base::SupportsUserData::Data> DataUseUserData::Create(
ServiceName service_name) {
- return new DataUseUserData(service_name, GetCurrentAppState());
+ return base::MakeUnique<DataUseUserData>(service_name, GetCurrentAppState());
}
// static
diff --git a/chromium/components/data_use_measurement/core/data_use_user_data.h b/chromium/components/data_use_measurement/core/data_use_user_data.h
index 584e7a52bd1..0ea0ae8d437 100644
--- a/chromium/components/data_use_measurement/core/data_use_user_data.h
+++ b/chromium/components/data_use_measurement/core/data_use_user_data.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_USER_DATA_H_
#define COMPONENTS_DATA_USE_MEASUREMENT_CORE_DATA_USE_USER_DATA_H_
+#include <memory>
#include <string>
#include "base/macros.h"
@@ -96,9 +97,8 @@ class DataUseUserData : public base::SupportsUserData::Data {
DataUseUserData(ServiceName service_name, AppState app_state);
~DataUseUserData() override;
- // Helper function to create DataUseUserData. The caller takes the ownership
- // of the returned object.
- static base::SupportsUserData::Data* Create(
+ // Helper function to create DataUseUserData.
+ static std::unique_ptr<base::SupportsUserData::Data> Create(
DataUseUserData::ServiceName service);
// Return the service name of the ServiceName enum.
diff --git a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc
index e2966c798c7..0913399d492 100644
--- a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc
+++ b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc
@@ -80,13 +80,13 @@ class MojoDiscardableSharedMemoryManagerImpl
void AllocateLockedDiscardableSharedMemory(
uint32_t size,
int32_t id,
- const AllocateLockedDiscardableSharedMemoryCallback& callback) override {
+ AllocateLockedDiscardableSharedMemoryCallback callback) override {
base::SharedMemoryHandle handle;
manager_->AllocateLockedDiscardableSharedMemoryForClient(client_id_, size,
id, &handle);
mojo::ScopedSharedBufferHandle memory =
mojo::WrapSharedMemoryHandle(handle, size, false /* read_only */);
- return callback.Run(std::move(memory));
+ std::move(callback).Run(std::move(memory));
}
void DeletedDiscardableSharedMemory(int32_t id) override {
@@ -247,6 +247,7 @@ DiscardableSharedMemoryManager::~DiscardableSharedMemoryManager() {
}
void DiscardableSharedMemoryManager::Bind(
+ const service_manager::BindSourceInfo& source_info,
mojom::DiscardableSharedMemoryManagerRequest request) {
mojo::MakeStrongBinding(
base::MakeUnique<MojoDiscardableSharedMemoryManagerImpl>(
@@ -440,7 +441,7 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
MemorySegmentMap& client_segments = clients_[client_id];
if (client_segments.find(id) != client_segments.end()) {
LOG(ERROR) << "Invalid discardable shared memory ID";
- *shared_memory_handle = base::SharedMemory::NULLHandle();
+ *shared_memory_handle = base::SharedMemoryHandle();
return;
}
@@ -461,14 +462,14 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
std::unique_ptr<base::DiscardableSharedMemory> memory(
new base::DiscardableSharedMemory);
if (!memory->CreateAndMap(size)) {
- *shared_memory_handle = base::SharedMemory::NULLHandle();
+ *shared_memory_handle = base::SharedMemoryHandle();
return;
}
base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_;
checked_bytes_allocated += memory->mapped_size();
if (!checked_bytes_allocated.IsValid()) {
- *shared_memory_handle = base::SharedMemory::NULLHandle();
+ *shared_memory_handle = base::SharedMemoryHandle();
return;
}
diff --git a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h
index 3c65f049825..be03456e690 100644
--- a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h
+++ b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h
@@ -29,6 +29,10 @@
#include "components/discardable_memory/common/discardable_memory_export.h"
#include "components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace discardable_memory {
// Implementation of DiscardableMemoryAllocator that allocates and manages
@@ -45,7 +49,8 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager
~DiscardableSharedMemoryManager() override;
// Bind the manager to a mojo interface request.
- void Bind(mojom::DiscardableSharedMemoryManagerRequest request);
+ void Bind(const service_manager::BindSourceInfo& source_info,
+ mojom::DiscardableSharedMemoryManagerRequest request);
// Overridden from base::DiscardableMemoryAllocator:
std::unique_ptr<base::DiscardableMemory> AllocateLockedDiscardableMemory(
diff --git a/chromium/components/display_compositor/display_compositor_export.h b/chromium/components/display_compositor/display_compositor_export.h
deleted file mode 100644
index 031e93984c1..00000000000
--- a/chromium/components/display_compositor/display_compositor_export.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 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_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_EXPORT_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_EXPORT_H_
-
-#if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(DISPLAY_COMPOSITOR_IMPLEMENTATION)
-#define DISPLAY_COMPOSITOR_EXPORT __declspec(dllexport)
-#else
-#define DISPLAY_COMPOSITOR_EXPORT __declspec(dllimport)
-#endif // defined(DISPLAY_COMPOSITOR_IMPLEMENTATION)
-
-#else // !defined(WIN32)
-
-#if defined(DISPLAY_COMPOSITOR_IMPLEMENTATION)
-#define DISPLAY_COMPOSITOR_EXPORT __attribute__((visibility("default")))
-#else
-#define DISPLAY_COMPOSITOR_EXPORT
-#endif // defined(DISPLAY_COMPOSITOR_IMPLEMENTATION)
-
-#endif // defined(WIN32)
-
-#else // !defined(COMPONENT_BUILD)
-
-#define DISPLAY_COMPOSITOR_EXPORT
-
-#endif // define(COMPONENT_BUILD)
-
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_EXPORT_H_
diff --git a/chromium/components/display_compositor/run_all_unittests.cc b/chromium/components/display_compositor/run_all_unittests.cc
deleted file mode 100644
index 5cd65a14021..00000000000
--- a/chromium/components/display_compositor/run_all_unittests.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2012 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 "base/bind.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "components/display_compositor/display_compositor_test_suite.h"
-
-int main(int argc, char** argv) {
- display_compositor::DisplayCompositorTestSuite test_suite(argc, argv);
-
- return base::LaunchUnitTests(
- argc, argv,
- base::Bind(&display_compositor::DisplayCompositorTestSuite::Run,
- base::Unretained(&test_suite)));
-}
diff --git a/chromium/components/dom_distiller/content/browser/distillability_driver.cc b/chromium/components/dom_distiller/content/browser/distillability_driver.cc
index ce19a465041..88d4ccf21f6 100644
--- a/chromium/components/dom_distiller/content/browser/distillability_driver.cc
+++ b/chromium/components/dom_distiller/content/browser/distillability_driver.cc
@@ -11,7 +11,7 @@
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
DEFINE_WEB_CONTENTS_USER_DATA_KEY(
dom_distiller::DistillabilityDriver);
@@ -54,7 +54,8 @@ DistillabilityDriver::~DistillabilityDriver() {
}
void DistillabilityDriver::CreateDistillabilityService(
- mojo::InterfaceRequest<mojom::DistillabilityService> request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::DistillabilityServiceRequest request) {
mojo::MakeStrongBinding(
base::MakeUnique<DistillabilityServiceImpl>(weak_factory_.GetWeakPtr()),
std::move(request));
diff --git a/chromium/components/dom_distiller/content/browser/distillability_driver.h b/chromium/components/dom_distiller/content/browser/distillability_driver.h
index 68d98ea09e2..bf2f0477e07 100644
--- a/chromium/components/dom_distiller/content/browser/distillability_driver.h
+++ b/chromium/components/dom_distiller/content/browser/distillability_driver.h
@@ -11,6 +11,7 @@
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
namespace dom_distiller {
@@ -21,7 +22,8 @@ class DistillabilityDriver
public:
~DistillabilityDriver() override;
void CreateDistillabilityService(
- mojo::InterfaceRequest<mojom::DistillabilityService> request);
+ const service_manager::BindSourceInfo& source_info,
+ mojom::DistillabilityServiceRequest request);
void SetDelegate(const base::Callback<void(bool, bool)>& delegate);
diff --git a/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc b/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc
index 79183c2e540..2dea5f1be2e 100644
--- a/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc
+++ b/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc
@@ -43,7 +43,8 @@ void DistillerJavaScriptServiceImpl::HandleDistillerOpenSettingsCall() {
void CreateDistillerJavaScriptService(
content::RenderFrameHost* render_frame_host,
DistillerUIHandle* distiller_ui_handle,
- mojo::InterfaceRequest<mojom::DistillerJavaScriptService> request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::DistillerJavaScriptServiceRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<DistillerJavaScriptServiceImpl>(
render_frame_host, distiller_ui_handle),
std::move(request));
diff --git a/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.h b/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.h
index 829df278081..d9a1048f81f 100644
--- a/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.h
+++ b/chromium/components/dom_distiller/content/browser/distiller_javascript_service_impl.h
@@ -9,6 +9,7 @@
#include "components/dom_distiller/content/browser/distiller_ui_handle.h"
#include "components/dom_distiller/content/common/distiller_javascript_service.mojom.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
namespace dom_distiller {
@@ -39,7 +40,8 @@ class DistillerJavaScriptServiceImpl
void CreateDistillerJavaScriptService(
content::RenderFrameHost* render_frame_host,
DistillerUIHandle* distiller_ui_handle,
- mojo::InterfaceRequest<mojom::DistillerJavaScriptService> request);
+ const service_manager::BindSourceInfo& source_info,
+ mojom::DistillerJavaScriptServiceRequest request);
} // namespace dom_distiller
diff --git a/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc b/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc
index c9273e10fc0..212145b3c66 100644
--- a/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc
+++ b/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc
@@ -40,8 +40,8 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/base/url_util.h"
#include "net/url_request/url_request.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/interface_provider.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
#include "ui/base/l10n/l10n_util.h"
namespace dom_distiller {
@@ -290,14 +290,10 @@ std::string DomDistillerViewerSource::GetMimeType(
}
bool DomDistillerViewerSource::ShouldServiceRequest(
- const net::URLRequest* request) const {
- return request->url().SchemeIs(scheme_);
-}
-
-// TODO(nyquist): Start tracking requests using this method.
-void DomDistillerViewerSource::WillServiceRequest(
- const net::URLRequest* request,
- std::string* path) const {
+ const GURL& url,
+ content::ResourceContext* resource_context,
+ int render_process_id) const {
+ return url.SchemeIs(scheme_);
}
std::string DomDistillerViewerSource::GetContentSecurityPolicyStyleSrc()
diff --git a/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.h b/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.h
index 2ed7a3f19df..6b91b1ed9ea 100644
--- a/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.h
+++ b/chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.h
@@ -35,9 +35,9 @@ class DomDistillerViewerSource : public content::URLDataSource {
const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
const content::URLDataSource::GotDataCallback& callback) override;
std::string GetMimeType(const std::string& path) const override;
- bool ShouldServiceRequest(const net::URLRequest* request) const override;
- void WillServiceRequest(const net::URLRequest* request,
- std::string* path) const override;
+ bool ShouldServiceRequest(const GURL& url,
+ content::ResourceContext* resource_context,
+ int render_process_id) const override;
std::string GetContentSecurityPolicyStyleSrc() const override;
std::string GetContentSecurityPolicyChildSrc() const override;
diff --git a/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc b/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc
index 46131fd7028..b3ae09b0648 100644
--- a/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc
+++ b/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc
@@ -12,7 +12,7 @@
#include "components/dom_distiller/content/renderer/distiller_page_notifier_service_impl.h"
#include "content/public/renderer/render_frame.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "v8/include/v8.h"
namespace dom_distiller {
@@ -60,7 +60,8 @@ void DistillerJsRenderFrameObserver::RegisterMojoInterface() {
}
void DistillerJsRenderFrameObserver::CreateDistillerPageNotifierService(
- mojo::InterfaceRequest<mojom::DistillerPageNotifierService> request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::DistillerPageNotifierServiceRequest request) {
mojo::MakeStrongBinding(
base::MakeUnique<DistillerPageNotifierServiceImpl>(this),
std::move(request));
diff --git a/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h b/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h
index 6ace08d3ab3..f3ad5557d07 100644
--- a/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h
+++ b/chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h
@@ -11,6 +11,7 @@
#include "components/dom_distiller/content/renderer/distiller_page_notifier_service_impl.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "v8/include/v8.h"
@@ -40,7 +41,8 @@ class DistillerJsRenderFrameObserver : public content::RenderFrameObserver {
private:
void CreateDistillerPageNotifierService(
- mojo::InterfaceRequest<mojom::DistillerPageNotifierService> request);
+ const service_manager::BindSourceInfo& source_info,
+ mojom::DistillerPageNotifierServiceRequest request);
// RenderFrameObserver implementation.
void OnDestruct() override;
diff --git a/chromium/components/dom_distiller/core/android/BUILD.gn b/chromium/components/dom_distiller/core/android/BUILD.gn
index 658408dd87a..534a3bf5f02 100644
--- a/chromium/components/dom_distiller/core/android/BUILD.gn
+++ b/chromium/components/dom_distiller/core/android/BUILD.gn
@@ -21,7 +21,7 @@ android_library("dom_distiller_core_java") {
}
java_cpp_template("dom_distiller_core_font_family_javagen") {
- package_name = "org/chromium/components/dom_distiller/core"
+ package_path = "org/chromium/components/dom_distiller/core"
sources = [
"java/src/org/chromium/components/dom_distiller/core/FontFamily.template",
]
@@ -31,7 +31,7 @@ java_cpp_template("dom_distiller_core_font_family_javagen") {
}
java_cpp_template("dom_distiller_core_theme_javagen") {
- package_name = "org/chromium/components/dom_distiller/core"
+ package_path = "org/chromium/components/dom_distiller/core"
sources = [
"java/src/org/chromium/components/dom_distiller/core/Theme.template",
]
diff --git a/chromium/components/dom_distiller/core/dom_distiller_store_unittest.cc b/chromium/components/dom_distiller/core/dom_distiller_store_unittest.cc
index 79c87b6f9e5..c8dfacfce5f 100644
--- a/chromium/components/dom_distiller/core/dom_distiller_store_unittest.cc
+++ b/chromium/components/dom_distiller/core/dom_distiller_store_unittest.cc
@@ -47,7 +47,7 @@ namespace {
const ModelType kDomDistillerModelType = syncer::ARTICLES;
-typedef base::hash_map<std::string, ArticleEntry> EntryMap;
+typedef std::map<std::string, ArticleEntry> EntryMap;
void AddEntry(const ArticleEntry& e, EntryMap* map) {
(*map)[e.entry_id()] = e;
diff --git a/chromium/components/dom_distiller/core/html/preview.html b/chromium/components/dom_distiller/core/html/preview.html
index 55581f686d7..a4c07c52278 100644
--- a/chromium/components/dom_distiller/core/html/preview.html
+++ b/chromium/components/dom_distiller/core/html/preview.html
@@ -296,6 +296,11 @@ eleifend sagittis tortor turpis.</code></pre>
Ipsum aliquam placerat odio turpis, est lacinia, risus aenean
adipiscing integer, semper wisi tortor.
</p>
+ <figure>
+ <img
+ src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Ara-Zoo-Muenster-2013-02.jpg/800px-Ara-Zoo-Muenster-2013-02.jpg">
+ <figcaption>Figure with caption</figcaption>
+ </figure>
<h4>Fermentum ligula mauris cras h4</h4>
<p>
Quia in elementum senectus,
diff --git a/chromium/components/dom_distiller/core/task_tracker_unittest.cc b/chromium/components/dom_distiller/core/task_tracker_unittest.cc
index b760b4abf82..4f317e5a5d8 100644
--- a/chromium/components/dom_distiller/core/task_tracker_unittest.cc
+++ b/chromium/components/dom_distiller/core/task_tracker_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "components/dom_distiller/core/article_distillation_update.h"
#include "components/dom_distiller/core/article_entry.h"
diff --git a/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc b/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc
index 9047ce71b03..c81a6530786 100644
--- a/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc
+++ b/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc
@@ -11,11 +11,13 @@
#include "base/id_map.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/dom_distiller/content/browser/distiller_javascript_utils.h"
#include "components/dom_distiller/content/browser/distiller_page_web_contents.h"
@@ -31,7 +33,6 @@
#include "components/leveldb_proto/proto_database_impl.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/test/content_browser_test.h"
@@ -126,10 +127,8 @@ std::unique_ptr<DomDistillerService> CreateDomDistillerService(
content::BrowserContext* context,
const base::FilePath& db_path,
const FileToUrlMap& file_to_url_map) {
- base::SequencedWorkerPool* blocking_pool =
- content::BrowserThread::GetBlockingPool();
scoped_refptr<base::SequencedTaskRunner> background_task_runner =
- blocking_pool->GetSequencedTaskRunner(blocking_pool->GetSequenceToken());
+ base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()});
// TODO(cjhopman): use an in-memory database instead of an on-disk one with
// temporary directory.
diff --git a/chromium/components/domain_reliability/google_configs.cc b/chromium/components/domain_reliability/google_configs.cc
index a18710649da..a28a0b6e0c8 100644
--- a/chromium/components/domain_reliability/google_configs.cc
+++ b/chromium/components/domain_reliability/google_configs.cc
@@ -31,493 +31,497 @@ struct GoogleConfigParams {
};
const GoogleConfigParams kGoogleConfigs[] = {
- // Origins with subdomains and same-origin collectors. Currently, all
- // origins with same-origin collectors also run collectors on their www
- // subdomain. (e.g., both foo.com and www.foo.com.)
- { "google.ac", true, true, true },
- { "google.ad", true, true, true },
- { "google.ae", true, true, true },
- { "google.af", true, true, true },
- { "google.ag", true, true, true },
- { "google.al", true, true, true },
- { "google.am", true, true, true },
- { "google.as", true, true, true },
- { "google.at", true, true, true },
- { "google.az", true, true, true },
- { "google.ba", true, true, true },
- { "google.be", true, true, true },
- { "google.bf", true, true, true },
- { "google.bg", true, true, true },
- { "google.bi", true, true, true },
- { "google.bj", true, true, true },
- { "google.bs", true, true, true },
- { "google.bt", true, true, true },
- { "google.by", true, true, true },
- { "google.ca", true, true, true },
- { "google.cc", true, true, true },
- { "google.cd", true, true, true },
- { "google.cf", true, true, true },
- { "google.cg", true, true, true },
- { "google.ch", true, true, true },
- { "google.ci", true, true, true },
- { "google.cl", true, true, true },
- { "google.cm", true, true, true },
- { "google.cn", true, true, true },
- { "google.co.ao", true, true, true },
- { "google.co.bw", true, true, true },
- { "google.co.ck", true, true, true },
- { "google.co.cr", true, true, true },
- { "google.co.hu", true, true, true },
- { "google.co.id", true, true, true },
- { "google.co.il", true, true, true },
- { "google.co.im", true, true, true },
- { "google.co.in", true, true, true },
- { "google.co.je", true, true, true },
- { "google.co.jp", true, true, true },
- { "google.co.ke", true, true, true },
- { "google.co.kr", true, true, true },
- { "google.co.ls", true, true, true },
- { "google.co.ma", true, true, true },
- { "google.co.mz", true, true, true },
- { "google.co.nz", true, true, true },
- { "google.co.th", true, true, true },
- { "google.co.tz", true, true, true },
- { "google.co.ug", true, true, true },
- { "google.co.uk", true, true, true },
- { "google.co.uz", true, true, true },
- { "google.co.ve", true, true, true },
- { "google.co.vi", true, true, true },
- { "google.co.za", true, true, true },
- { "google.co.zm", true, true, true },
- { "google.co.zw", true, true, true },
- { "google.com.af", true, true, true },
- { "google.com.ag", true, true, true },
- { "google.com.ai", true, true, true },
- { "google.com.ar", true, true, true },
- { "google.com.au", true, true, true },
- { "google.com.bd", true, true, true },
- { "google.com.bh", true, true, true },
- { "google.com.bn", true, true, true },
- { "google.com.bo", true, true, true },
- { "google.com.br", true, true, true },
- { "google.com.by", true, true, true },
- { "google.com.bz", true, true, true },
- { "google.com.cn", true, true, true },
- { "google.com.co", true, true, true },
- { "google.com.cu", true, true, true },
- { "google.com.cy", true, true, true },
- { "google.com.do", true, true, true },
- { "google.com.ec", true, true, true },
- { "google.com.eg", true, true, true },
- { "google.com.et", true, true, true },
- { "google.com.fj", true, true, true },
- { "google.com.ge", true, true, true },
- { "google.com.gh", true, true, true },
- { "google.com.gi", true, true, true },
- { "google.com.gr", true, true, true },
- { "google.com.gt", true, true, true },
- { "google.com.hk", true, true, true },
- { "google.com.iq", true, true, true },
- { "google.com.jm", true, true, true },
- { "google.com.jo", true, true, true },
- { "google.com.kh", true, true, true },
- { "google.com.kw", true, true, true },
- { "google.com.lb", true, true, true },
- { "google.com.ly", true, true, true },
- { "google.com.mm", true, true, true },
- { "google.com.mt", true, true, true },
- { "google.com.mx", true, true, true },
- { "google.com.my", true, true, true },
- { "google.com.na", true, true, true },
- { "google.com.nf", true, true, true },
- { "google.com.ng", true, true, true },
- { "google.com.ni", true, true, true },
- { "google.com.np", true, true, true },
- { "google.com.nr", true, true, true },
- { "google.com.om", true, true, true },
- { "google.com.pa", true, true, true },
- { "google.com.pe", true, true, true },
- { "google.com.pg", true, true, true },
- { "google.com.ph", true, true, true },
- { "google.com.pk", true, true, true },
- { "google.com.pl", true, true, true },
- { "google.com.pr", true, true, true },
- { "google.com.py", true, true, true },
- { "google.com.qa", true, true, true },
- { "google.com.ru", true, true, true },
- { "google.com.sa", true, true, true },
- { "google.com.sb", true, true, true },
- { "google.com.sg", true, true, true },
- { "google.com.sl", true, true, true },
- { "google.com.sv", true, true, true },
- { "google.com.tj", true, true, true },
- { "google.com.tn", true, true, true },
- { "google.com.tr", true, true, true },
- { "google.com.tw", true, true, true },
- { "google.com.ua", true, true, true },
- { "google.com.uy", true, true, true },
- { "google.com.vc", true, true, true },
- { "google.com.ve", true, true, true },
- { "google.com.vn", true, true, true },
- { "google.cv", true, true, true },
- { "google.cz", true, true, true },
- { "google.de", true, true, true },
- { "google.dj", true, true, true },
- { "google.dk", true, true, true },
- { "google.dm", true, true, true },
- { "google.dz", true, true, true },
- { "google.ee", true, true, true },
- { "google.es", true, true, true },
- { "google.fi", true, true, true },
- { "google.fm", true, true, true },
- { "google.fr", true, true, true },
- { "google.ga", true, true, true },
- { "google.ge", true, true, true },
- { "google.gg", true, true, true },
- { "google.gl", true, true, true },
- { "google.gm", true, true, true },
- { "google.gp", true, true, true },
- { "google.gr", true, true, true },
- { "google.gy", true, true, true },
- { "google.hk", true, true, true },
- { "google.hn", true, true, true },
- { "google.hr", true, true, true },
- { "google.ht", true, true, true },
- { "google.hu", true, true, true },
- { "google.ie", true, true, true },
- { "google.im", true, true, true },
- { "google.iq", true, true, true },
- { "google.ir", true, true, true },
- { "google.is", true, true, true },
- { "google.it", true, true, true },
- { "google.it.ao", true, true, true },
- { "google.je", true, true, true },
- { "google.jo", true, true, true },
- { "google.jp", true, true, true },
- { "google.kg", true, true, true },
- { "google.ki", true, true, true },
- { "google.kz", true, true, true },
- { "google.la", true, true, true },
- { "google.li", true, true, true },
- { "google.lk", true, true, true },
- { "google.lt", true, true, true },
- { "google.lu", true, true, true },
- { "google.lv", true, true, true },
- { "google.md", true, true, true },
- { "google.me", true, true, true },
- { "google.mg", true, true, true },
- { "google.mk", true, true, true },
- { "google.ml", true, true, true },
- { "google.mn", true, true, true },
- { "google.ms", true, true, true },
- { "google.mu", true, true, true },
- { "google.mv", true, true, true },
- { "google.mw", true, true, true },
- { "google.ne", true, true, true },
- { "google.ne.jp", true, true, true },
- { "google.ng", true, true, true },
- { "google.nl", true, true, true },
- { "google.no", true, true, true },
- { "google.nr", true, true, true },
- { "google.nu", true, true, true },
- { "google.off.ai", true, true, true },
- { "google.pk", true, true, true },
- { "google.pl", true, true, true },
- { "google.pn", true, true, true },
- { "google.ps", true, true, true },
- { "google.pt", true, true, true },
- { "google.ro", true, true, true },
- { "google.rs", true, true, true },
- { "google.ru", true, true, true },
- { "google.rw", true, true, true },
- { "google.sc", true, true, true },
- { "google.se", true, true, true },
- { "google.sh", true, true, true },
- { "google.si", true, true, true },
- { "google.sk", true, true, true },
- { "google.sm", true, true, true },
- { "google.sn", true, true, true },
- { "google.so", true, true, true },
- { "google.sr", true, true, true },
- { "google.st", true, true, true },
- { "google.td", true, true, true },
- { "google.tg", true, true, true },
- { "google.tk", true, true, true },
- { "google.tl", true, true, true },
- { "google.tm", true, true, true },
- { "google.tn", true, true, true },
- { "google.to", true, true, true },
- { "google.tt", true, true, true },
- { "google.us", true, true, true },
- { "google.uz", true, true, true },
- { "google.vg", true, true, true },
- { "google.vu", true, true, true },
- { "google.ws", true, true, true },
- { "l.google.com", true, true, true },
+ // Origins with subdomains and same-origin collectors. Currently, all
+ // origins with same-origin collectors also run collectors on their www
+ // subdomain. (e.g., both foo.com and www.foo.com.)
+ {"google.ac", true, true, true},
+ {"google.ad", true, true, true},
+ {"google.ae", true, true, true},
+ {"google.af", true, true, true},
+ {"google.ag", true, true, true},
+ {"google.al", true, true, true},
+ {"google.am", true, true, true},
+ {"google.as", true, true, true},
+ {"google.at", true, true, true},
+ {"google.az", true, true, true},
+ {"google.ba", true, true, true},
+ {"google.be", true, true, true},
+ {"google.bf", true, true, true},
+ {"google.bg", true, true, true},
+ {"google.bi", true, true, true},
+ {"google.bj", true, true, true},
+ {"google.bs", true, true, true},
+ {"google.bt", true, true, true},
+ {"google.by", true, true, true},
+ {"google.ca", true, true, true},
+ {"google.cc", true, true, true},
+ {"google.cd", true, true, true},
+ {"google.cf", true, true, true},
+ {"google.cg", true, true, true},
+ {"google.ch", true, true, true},
+ {"google.ci", true, true, true},
+ {"google.cl", true, true, true},
+ {"google.cm", true, true, true},
+ {"google.cn", true, true, true},
+ {"google.co.ao", true, true, true},
+ {"google.co.bw", true, true, true},
+ {"google.co.ck", true, true, true},
+ {"google.co.cr", true, true, true},
+ {"google.co.hu", true, true, true},
+ {"google.co.id", true, true, true},
+ {"google.co.il", true, true, true},
+ {"google.co.im", true, true, true},
+ {"google.co.in", true, true, true},
+ {"google.co.je", true, true, true},
+ {"google.co.jp", true, true, true},
+ {"google.co.ke", true, true, true},
+ {"google.co.kr", true, true, true},
+ {"google.co.ls", true, true, true},
+ {"google.co.ma", true, true, true},
+ {"google.co.mz", true, true, true},
+ {"google.co.nz", true, true, true},
+ {"google.co.th", true, true, true},
+ {"google.co.tz", true, true, true},
+ {"google.co.ug", true, true, true},
+ {"google.co.uk", true, true, true},
+ {"google.co.uz", true, true, true},
+ {"google.co.ve", true, true, true},
+ {"google.co.vi", true, true, true},
+ {"google.co.za", true, true, true},
+ {"google.co.zm", true, true, true},
+ {"google.co.zw", true, true, true},
+ {"google.com.af", true, true, true},
+ {"google.com.ag", true, true, true},
+ {"google.com.ai", true, true, true},
+ {"google.com.ar", true, true, true},
+ {"google.com.au", true, true, true},
+ {"google.com.bd", true, true, true},
+ {"google.com.bh", true, true, true},
+ {"google.com.bn", true, true, true},
+ {"google.com.bo", true, true, true},
+ {"google.com.br", true, true, true},
+ {"google.com.by", true, true, true},
+ {"google.com.bz", true, true, true},
+ {"google.com.cn", true, true, true},
+ {"google.com.co", true, true, true},
+ {"google.com.cu", true, true, true},
+ {"google.com.cy", true, true, true},
+ {"google.com.do", true, true, true},
+ {"google.com.ec", true, true, true},
+ {"google.com.eg", true, true, true},
+ {"google.com.et", true, true, true},
+ {"google.com.fj", true, true, true},
+ {"google.com.ge", true, true, true},
+ {"google.com.gh", true, true, true},
+ {"google.com.gi", true, true, true},
+ {"google.com.gr", true, true, true},
+ {"google.com.gt", true, true, true},
+ {"google.com.hk", true, true, true},
+ {"google.com.iq", true, true, true},
+ {"google.com.jm", true, true, true},
+ {"google.com.jo", true, true, true},
+ {"google.com.kh", true, true, true},
+ {"google.com.kw", true, true, true},
+ {"google.com.lb", true, true, true},
+ {"google.com.ly", true, true, true},
+ {"google.com.mm", true, true, true},
+ {"google.com.mt", true, true, true},
+ {"google.com.mx", true, true, true},
+ {"google.com.my", true, true, true},
+ {"google.com.na", true, true, true},
+ {"google.com.nf", true, true, true},
+ {"google.com.ng", true, true, true},
+ {"google.com.ni", true, true, true},
+ {"google.com.np", true, true, true},
+ {"google.com.nr", true, true, true},
+ {"google.com.om", true, true, true},
+ {"google.com.pa", true, true, true},
+ {"google.com.pe", true, true, true},
+ {"google.com.pg", true, true, true},
+ {"google.com.ph", true, true, true},
+ {"google.com.pk", true, true, true},
+ {"google.com.pl", true, true, true},
+ {"google.com.pr", true, true, true},
+ {"google.com.py", true, true, true},
+ {"google.com.qa", true, true, true},
+ {"google.com.ru", true, true, true},
+ {"google.com.sa", true, true, true},
+ {"google.com.sb", true, true, true},
+ {"google.com.sg", true, true, true},
+ {"google.com.sl", true, true, true},
+ {"google.com.sv", true, true, true},
+ {"google.com.tj", true, true, true},
+ {"google.com.tn", true, true, true},
+ {"google.com.tr", true, true, true},
+ {"google.com.tw", true, true, true},
+ {"google.com.ua", true, true, true},
+ {"google.com.uy", true, true, true},
+ {"google.com.vc", true, true, true},
+ {"google.com.ve", true, true, true},
+ {"google.com.vn", true, true, true},
+ {"google.cv", true, true, true},
+ {"google.cz", true, true, true},
+ {"google.de", true, true, true},
+ {"google.dj", true, true, true},
+ {"google.dk", true, true, true},
+ {"google.dm", true, true, true},
+ {"google.dz", true, true, true},
+ {"google.ee", true, true, true},
+ {"google.es", true, true, true},
+ {"google.fi", true, true, true},
+ {"google.fm", true, true, true},
+ {"google.fr", true, true, true},
+ {"google.ga", true, true, true},
+ {"google.ge", true, true, true},
+ {"google.gg", true, true, true},
+ {"google.gl", true, true, true},
+ {"google.gm", true, true, true},
+ {"google.gp", true, true, true},
+ {"google.gr", true, true, true},
+ {"google.gy", true, true, true},
+ {"google.hk", true, true, true},
+ {"google.hn", true, true, true},
+ {"google.hr", true, true, true},
+ {"google.ht", true, true, true},
+ {"google.hu", true, true, true},
+ {"google.ie", true, true, true},
+ {"google.im", true, true, true},
+ {"google.iq", true, true, true},
+ {"google.ir", true, true, true},
+ {"google.is", true, true, true},
+ {"google.it", true, true, true},
+ {"google.it.ao", true, true, true},
+ {"google.je", true, true, true},
+ {"google.jo", true, true, true},
+ {"google.jp", true, true, true},
+ {"google.kg", true, true, true},
+ {"google.ki", true, true, true},
+ {"google.kz", true, true, true},
+ {"google.la", true, true, true},
+ {"google.li", true, true, true},
+ {"google.lk", true, true, true},
+ {"google.lt", true, true, true},
+ {"google.lu", true, true, true},
+ {"google.lv", true, true, true},
+ {"google.md", true, true, true},
+ {"google.me", true, true, true},
+ {"google.mg", true, true, true},
+ {"google.mk", true, true, true},
+ {"google.ml", true, true, true},
+ {"google.mn", true, true, true},
+ {"google.ms", true, true, true},
+ {"google.mu", true, true, true},
+ {"google.mv", true, true, true},
+ {"google.mw", true, true, true},
+ {"google.ne", true, true, true},
+ {"google.ne.jp", true, true, true},
+ {"google.ng", true, true, true},
+ {"google.nl", true, true, true},
+ {"google.no", true, true, true},
+ {"google.nr", true, true, true},
+ {"google.nu", true, true, true},
+ {"google.off.ai", true, true, true},
+ {"google.pk", true, true, true},
+ {"google.pl", true, true, true},
+ {"google.pn", true, true, true},
+ {"google.ps", true, true, true},
+ {"google.pt", true, true, true},
+ {"google.ro", true, true, true},
+ {"google.rs", true, true, true},
+ {"google.ru", true, true, true},
+ {"google.rw", true, true, true},
+ {"google.sc", true, true, true},
+ {"google.se", true, true, true},
+ {"google.sh", true, true, true},
+ {"google.si", true, true, true},
+ {"google.sk", true, true, true},
+ {"google.sm", true, true, true},
+ {"google.sn", true, true, true},
+ {"google.so", true, true, true},
+ {"google.sr", true, true, true},
+ {"google.st", true, true, true},
+ {"google.td", true, true, true},
+ {"google.tg", true, true, true},
+ {"google.tk", true, true, true},
+ {"google.tl", true, true, true},
+ {"google.tm", true, true, true},
+ {"google.tn", true, true, true},
+ {"google.to", true, true, true},
+ {"google.tt", true, true, true},
+ {"google.us", true, true, true},
+ {"google.uz", true, true, true},
+ {"google.vg", true, true, true},
+ {"google.vu", true, true, true},
+ {"google.ws", true, true, true},
+ {"l.google.com", true, true, true},
- // google.com is a special case. We have a custom config for www.google.com,
- // so set generate_config_for_www_subdomain = false.
- { "google.com", true, true, false },
+ // google.com is a special case. We have a custom config for www.google.com,
+ // so set generate_config_for_www_subdomain = false.
+ {"google.com", true, true, false},
- // Origins with subdomains and without same-origin collectors.
- { "2mdn.net", true, false, false },
- { "adgoogle.net", true, false, false },
- { "admeld.com", true, false, false },
- { "admob.biz", true, false, false },
- { "admob.co.in", true, false, false },
- { "admob.co.kr", true, false, false },
- { "admob.co.nz", true, false, false },
- { "admob.co.uk", true, false, false },
- { "admob.co.za", true, false, false },
- { "admob.com", true, false, false },
- { "admob.com.br", true, false, false },
- { "admob.com.es", true, false, false },
- { "admob.com.fr", true, false, false },
- { "admob.com.mx", true, false, false },
- { "admob.com.pt", true, false, false },
- { "admob.de", true, false, false },
- { "admob.dk", true, false, false },
- { "admob.es", true, false, false },
- { "admob.fi", true, false, false },
- { "admob.fr", true, false, false },
- { "admob.gr", true, false, false },
- { "admob.hk", true, false, false },
- { "admob.ie", true, false, false },
- { "admob.in", true, false, false },
- { "admob.it", true, false, false },
- { "admob.jp", true, false, false },
- { "admob.kr", true, false, false },
- { "admob.mobi", true, false, false },
- { "admob.no", true, false, false },
- { "admob.ph", true, false, false },
- { "admob.pt", true, false, false },
- { "admob.sg", true, false, false },
- { "admob.tw", true, false, false },
- { "admob.us", true, false, false },
- { "admob.vn", true, false, false },
- { "adwhirl.com", true, false, false },
- { "android.com", true, false, false },
- { "anycast-edge.metric.gstatic.com", true, false, false },
- { "anycast-stb.metric.gstatic.com", true, false, false },
- { "anycast.metric.gstatic.com", true, false, false },
- { "chromecast.com", true, false, false },
- { "chromeexperiments.com", true, false, false },
- { "chromestatus.com", true, false, false },
- { "chromium.org", true, false, false },
- { "cloudendpointsapis.com", true, false, false },
- { "dartmotif.com", true, false, false },
- { "dartsearch.net", true, false, false },
- { "doubleclick.com", true, false, false },
- { "doubleclick.ne.jp", true, false, false },
- { "doubleclick.net", true, false, false },
- { "doubleclickusercontent.com", true, false, false },
- { "fls.doubleclick.net", true, false, false },
- { "g.co", true, false, false },
- { "g.doubleclick.net", true, false, false },
- { "ggpht.com", true, false, false },
- { "gmodules.com", true, false, false },
- { "goo.gl", true, false, false },
- { "google-syndication.com", true, false, false },
- { "google.cat", true, false, false },
- { "google.info", true, false, false },
- { "google.jobs", true, false, false },
- { "google.net", true, false, false },
- { "google.org", true, false, false },
- { "google.stackdriver.com", true, false, false },
- { "googleadapis.com", true, false, false },
- { "googleadservices.com", true, false, false },
- { "googleadsserving.cn", true, false, false },
- { "googlealumni.com", true, false, false },
- { "googleapis.cn", true, false, false },
- { "googleapis.com", true, false, false },
- { "googleapps.com", true, false, false },
- { "googlecbs.com", true, false, false },
- { "googlecode.com", true, false, false },
- { "googlecommerce.com", true, false, false },
- { "googledrive.com", true, false, false },
- { "googleenterprise.com", true, false, false },
- { "googlefiber.com", true, false, false },
- { "googlefiber.net", true, false, false },
- { "googlegoro.com", true, false, false },
- { "googlehosted.com", true, false, false },
- { "googlepayments.com", true, false, false },
- { "googlesource.com", true, false, false },
- { "googlesyndication.com", true, false, false },
- { "googletagmanager.com", true, false, false },
- { "googletagservices.com", true, false, false },
- { "googleusercontent.com", true, false, false },
- { "gstatic.cn", true, false, false },
- { "gstatic.com", true, false, false },
- { "gvt3.com", true, false, false },
- { "gvt9.com", true, false, false },
- { "picasa.com", true, false, false },
- { "recaptcha.net", true, false, false },
- { "stackdriver.com", true, false, false },
- { "stbcast-stb.metric.gstatic.com", true, false, false },
- { "stbcast.metric.gstatic.com", true, false, false },
- { "stbcast2-stb.metric.gstatic.com", true, false, false },
- { "stbcast2.metric.gstatic.com", true, false, false },
- { "stbcast3-stb.metric.gstatic.com", true, false, false },
- { "stbcast3.metric.gstatic.com", true, false, false },
- { "stbcast4-stb.metric.gstatic.com", true, false, false },
- { "stbcast4.metric.gstatic.com", true, false, false },
- { "unicast-edge.metric.gstatic.com", true, false, false },
- { "unicast-stb.metric.gstatic.com", true, false, false },
- { "unicast.metric.gstatic.com", true, false, false },
- { "unicast2-stb.metric.gstatic.com", true, false, false },
- { "unicast2.metric.gstatic.com", true, false, false },
- { "waze.com", true, false, false },
- { "withgoogle.com", true, false, false },
- { "youtu.be", true, false, false },
- { "youtube-3rd-party.com", true, false, false },
- { "youtube-nocookie.com", true, false, false },
- { "youtube.ae", true, false, false },
- { "youtube.al", true, false, false },
- { "youtube.am", true, false, false },
- { "youtube.at", true, false, false },
- { "youtube.az", true, false, false },
- { "youtube.ba", true, false, false },
- { "youtube.be", true, false, false },
- { "youtube.bg", true, false, false },
- { "youtube.bh", true, false, false },
- { "youtube.bo", true, false, false },
- { "youtube.ca", true, false, false },
- { "youtube.cat", true, false, false },
- { "youtube.ch", true, false, false },
- { "youtube.cl", true, false, false },
- { "youtube.co", true, false, false },
- { "youtube.co.ae", true, false, false },
- { "youtube.co.at", true, false, false },
- { "youtube.co.hu", true, false, false },
- { "youtube.co.id", true, false, false },
- { "youtube.co.il", true, false, false },
- { "youtube.co.in", true, false, false },
- { "youtube.co.jp", true, false, false },
- { "youtube.co.ke", true, false, false },
- { "youtube.co.kr", true, false, false },
- { "youtube.co.ma", true, false, false },
- { "youtube.co.nz", true, false, false },
- { "youtube.co.th", true, false, false },
- { "youtube.co.ug", true, false, false },
- { "youtube.co.uk", true, false, false },
- { "youtube.co.ve", true, false, false },
- { "youtube.co.za", true, false, false },
- { "youtube.com", true, false, false },
- { "youtube.com.ar", true, false, false },
- { "youtube.com.au", true, false, false },
- { "youtube.com.az", true, false, false },
- { "youtube.com.bh", true, false, false },
- { "youtube.com.bo", true, false, false },
- { "youtube.com.br", true, false, false },
- { "youtube.com.by", true, false, false },
- { "youtube.com.co", true, false, false },
- { "youtube.com.do", true, false, false },
- { "youtube.com.ee", true, false, false },
- { "youtube.com.eg", true, false, false },
- { "youtube.com.es", true, false, false },
- { "youtube.com.gh", true, false, false },
- { "youtube.com.gr", true, false, false },
- { "youtube.com.gt", true, false, false },
- { "youtube.com.hk", true, false, false },
- { "youtube.com.hr", true, false, false },
- { "youtube.com.jm", true, false, false },
- { "youtube.com.jo", true, false, false },
- { "youtube.com.kw", true, false, false },
- { "youtube.com.lb", true, false, false },
- { "youtube.com.lv", true, false, false },
- { "youtube.com.mk", true, false, false },
- { "youtube.com.mt", true, false, false },
- { "youtube.com.mx", true, false, false },
- { "youtube.com.my", true, false, false },
- { "youtube.com.ng", true, false, false },
- { "youtube.com.om", true, false, false },
- { "youtube.com.pe", true, false, false },
- { "youtube.com.ph", true, false, false },
- { "youtube.com.pk", true, false, false },
- { "youtube.com.pt", true, false, false },
- { "youtube.com.qa", true, false, false },
- { "youtube.com.ro", true, false, false },
- { "youtube.com.sa", true, false, false },
- { "youtube.com.sg", true, false, false },
- { "youtube.com.tn", true, false, false },
- { "youtube.com.tr", true, false, false },
- { "youtube.com.tw", true, false, false },
- { "youtube.com.ua", true, false, false },
- { "youtube.com.uy", true, false, false },
- { "youtube.com.ve", true, false, false },
- { "youtube.cz", true, false, false },
- { "youtube.de", true, false, false },
- { "youtube.dk", true, false, false },
- { "youtube.ee", true, false, false },
- { "youtube.es", true, false, false },
- { "youtube.fi", true, false, false },
- { "youtube.fr", true, false, false },
- { "youtube.ge", true, false, false },
- { "youtube.gr", true, false, false },
- { "youtube.gt", true, false, false },
- { "youtube.hk", true, false, false },
- { "youtube.hr", true, false, false },
- { "youtube.hu", true, false, false },
- { "youtube.ie", true, false, false },
- { "youtube.in", true, false, false },
- { "youtube.is", true, false, false },
- { "youtube.it", true, false, false },
- { "youtube.jo", true, false, false },
- { "youtube.jp", true, false, false },
- { "youtube.kr", true, false, false },
- { "youtube.lk", true, false, false },
- { "youtube.lt", true, false, false },
- { "youtube.lv", true, false, false },
- { "youtube.ma", true, false, false },
- { "youtube.md", true, false, false },
- { "youtube.me", true, false, false },
- { "youtube.mk", true, false, false },
- { "youtube.mx", true, false, false },
- { "youtube.my", true, false, false },
- { "youtube.ng", true, false, false },
- { "youtube.nl", true, false, false },
- { "youtube.no", true, false, false },
- { "youtube.pe", true, false, false },
- { "youtube.ph", true, false, false },
- { "youtube.pk", true, false, false },
- { "youtube.pl", true, false, false },
- { "youtube.pr", true, false, false },
- { "youtube.pt", true, false, false },
- { "youtube.qa", true, false, false },
- { "youtube.ro", true, false, false },
- { "youtube.rs", true, false, false },
- { "youtube.ru", true, false, false },
- { "youtube.sa", true, false, false },
- { "youtube.se", true, false, false },
- { "youtube.sg", true, false, false },
- { "youtube.si", true, false, false },
- { "youtube.sk", true, false, false },
- { "youtube.sn", true, false, false },
- { "youtube.tn", true, false, false },
- { "youtube.ua", true, false, false },
- { "youtube.ug", true, false, false },
- { "youtube.uy", true, false, false },
- { "youtube.vn", true, false, false },
- { "youtubeeducation.com", true, false, false },
- { "youtubemobilesupport.com", true, false, false },
- { "ytimg.com", true, false, false },
+ // Origins with subdomains and without same-origin collectors.
+ {"2mdn.net", true, false, false},
+ {"adgoogle.net", true, false, false},
+ {"admeld.com", true, false, false},
+ {"admob.biz", true, false, false},
+ {"admob.co.in", true, false, false},
+ {"admob.co.kr", true, false, false},
+ {"admob.co.nz", true, false, false},
+ {"admob.co.uk", true, false, false},
+ {"admob.co.za", true, false, false},
+ {"admob.com", true, false, false},
+ {"admob.com.br", true, false, false},
+ {"admob.com.es", true, false, false},
+ {"admob.com.fr", true, false, false},
+ {"admob.com.mx", true, false, false},
+ {"admob.com.pt", true, false, false},
+ {"admob.de", true, false, false},
+ {"admob.dk", true, false, false},
+ {"admob.es", true, false, false},
+ {"admob.fi", true, false, false},
+ {"admob.fr", true, false, false},
+ {"admob.gr", true, false, false},
+ {"admob.hk", true, false, false},
+ {"admob.ie", true, false, false},
+ {"admob.in", true, false, false},
+ {"admob.it", true, false, false},
+ {"admob.jp", true, false, false},
+ {"admob.kr", true, false, false},
+ {"admob.mobi", true, false, false},
+ {"admob.no", true, false, false},
+ {"admob.ph", true, false, false},
+ {"admob.pt", true, false, false},
+ {"admob.sg", true, false, false},
+ {"admob.tw", true, false, false},
+ {"admob.us", true, false, false},
+ {"admob.vn", true, false, false},
+ {"adwhirl.com", true, false, false},
+ {"ampproject.com", true, false, false},
+ {"ampproject.net", true, false, false},
+ {"ampproject.org", true, false, false},
+ {"android.com", true, false, false},
+ {"anycast-edge.metric.gstatic.com", true, false, false},
+ {"anycast-stb.metric.gstatic.com", true, false, false},
+ {"anycast.metric.gstatic.com", true, false, false},
+ {"cdn.ampproject.org", true, false, false},
+ {"chromecast.com", true, false, false},
+ {"chromeexperiments.com", true, false, false},
+ {"chromestatus.com", true, false, false},
+ {"chromium.org", true, false, false},
+ {"cloudendpointsapis.com", true, false, false},
+ {"dartmotif.com", true, false, false},
+ {"dartsearch.net", true, false, false},
+ {"doubleclick.com", true, false, false},
+ {"doubleclick.ne.jp", true, false, false},
+ {"doubleclick.net", true, false, false},
+ {"doubleclickusercontent.com", true, false, false},
+ {"fls.doubleclick.net", true, false, false},
+ {"g.co", true, false, false},
+ {"g.doubleclick.net", true, false, false},
+ {"ggpht.com", true, false, false},
+ {"gmodules.com", true, false, false},
+ {"goo.gl", true, false, false},
+ {"google-syndication.com", true, false, false},
+ {"google.cat", true, false, false},
+ {"google.info", true, false, false},
+ {"google.jobs", true, false, false},
+ {"google.net", true, false, false},
+ {"google.org", true, false, false},
+ {"google.stackdriver.com", true, false, false},
+ {"googleadapis.com", true, false, false},
+ {"googleadservices.com", true, false, false},
+ {"googleadsserving.cn", true, false, false},
+ {"googlealumni.com", true, false, false},
+ {"googleapis.cn", true, false, false},
+ {"googleapis.com", true, false, false},
+ {"googleapps.com", true, false, false},
+ {"googlecbs.com", true, false, false},
+ {"googlecode.com", true, false, false},
+ {"googlecommerce.com", true, false, false},
+ {"googledrive.com", true, false, false},
+ {"googleenterprise.com", true, false, false},
+ {"googlefiber.com", true, false, false},
+ {"googlefiber.net", true, false, false},
+ {"googlegoro.com", true, false, false},
+ {"googlehosted.com", true, false, false},
+ {"googlepayments.com", true, false, false},
+ {"googlesource.com", true, false, false},
+ {"googlesyndication.com", true, false, false},
+ {"googletagmanager.com", true, false, false},
+ {"googletagservices.com", true, false, false},
+ {"googleusercontent.com", true, false, false},
+ {"gstatic.cn", true, false, false},
+ {"gstatic.com", true, false, false},
+ {"gvt3.com", true, false, false},
+ {"gvt9.com", true, false, false},
+ {"picasa.com", true, false, false},
+ {"recaptcha.net", true, false, false},
+ {"stackdriver.com", true, false, false},
+ {"stbcast-stb.metric.gstatic.com", true, false, false},
+ {"stbcast.metric.gstatic.com", true, false, false},
+ {"stbcast2-stb.metric.gstatic.com", true, false, false},
+ {"stbcast2.metric.gstatic.com", true, false, false},
+ {"stbcast3-stb.metric.gstatic.com", true, false, false},
+ {"stbcast3.metric.gstatic.com", true, false, false},
+ {"stbcast4-stb.metric.gstatic.com", true, false, false},
+ {"stbcast4.metric.gstatic.com", true, false, false},
+ {"unicast-edge.metric.gstatic.com", true, false, false},
+ {"unicast-stb.metric.gstatic.com", true, false, false},
+ {"unicast.metric.gstatic.com", true, false, false},
+ {"unicast2-stb.metric.gstatic.com", true, false, false},
+ {"unicast2.metric.gstatic.com", true, false, false},
+ {"waze.com", true, false, false},
+ {"withgoogle.com", true, false, false},
+ {"youtu.be", true, false, false},
+ {"youtube-3rd-party.com", true, false, false},
+ {"youtube-nocookie.com", true, false, false},
+ {"youtube.ae", true, false, false},
+ {"youtube.al", true, false, false},
+ {"youtube.am", true, false, false},
+ {"youtube.at", true, false, false},
+ {"youtube.az", true, false, false},
+ {"youtube.ba", true, false, false},
+ {"youtube.be", true, false, false},
+ {"youtube.bg", true, false, false},
+ {"youtube.bh", true, false, false},
+ {"youtube.bo", true, false, false},
+ {"youtube.ca", true, false, false},
+ {"youtube.cat", true, false, false},
+ {"youtube.ch", true, false, false},
+ {"youtube.cl", true, false, false},
+ {"youtube.co", true, false, false},
+ {"youtube.co.ae", true, false, false},
+ {"youtube.co.at", true, false, false},
+ {"youtube.co.hu", true, false, false},
+ {"youtube.co.id", true, false, false},
+ {"youtube.co.il", true, false, false},
+ {"youtube.co.in", true, false, false},
+ {"youtube.co.jp", true, false, false},
+ {"youtube.co.ke", true, false, false},
+ {"youtube.co.kr", true, false, false},
+ {"youtube.co.ma", true, false, false},
+ {"youtube.co.nz", true, false, false},
+ {"youtube.co.th", true, false, false},
+ {"youtube.co.ug", true, false, false},
+ {"youtube.co.uk", true, false, false},
+ {"youtube.co.ve", true, false, false},
+ {"youtube.co.za", true, false, false},
+ {"youtube.com", true, false, false},
+ {"youtube.com.ar", true, false, false},
+ {"youtube.com.au", true, false, false},
+ {"youtube.com.az", true, false, false},
+ {"youtube.com.bh", true, false, false},
+ {"youtube.com.bo", true, false, false},
+ {"youtube.com.br", true, false, false},
+ {"youtube.com.by", true, false, false},
+ {"youtube.com.co", true, false, false},
+ {"youtube.com.do", true, false, false},
+ {"youtube.com.ee", true, false, false},
+ {"youtube.com.eg", true, false, false},
+ {"youtube.com.es", true, false, false},
+ {"youtube.com.gh", true, false, false},
+ {"youtube.com.gr", true, false, false},
+ {"youtube.com.gt", true, false, false},
+ {"youtube.com.hk", true, false, false},
+ {"youtube.com.hr", true, false, false},
+ {"youtube.com.jm", true, false, false},
+ {"youtube.com.jo", true, false, false},
+ {"youtube.com.kw", true, false, false},
+ {"youtube.com.lb", true, false, false},
+ {"youtube.com.lv", true, false, false},
+ {"youtube.com.mk", true, false, false},
+ {"youtube.com.mt", true, false, false},
+ {"youtube.com.mx", true, false, false},
+ {"youtube.com.my", true, false, false},
+ {"youtube.com.ng", true, false, false},
+ {"youtube.com.om", true, false, false},
+ {"youtube.com.pe", true, false, false},
+ {"youtube.com.ph", true, false, false},
+ {"youtube.com.pk", true, false, false},
+ {"youtube.com.pt", true, false, false},
+ {"youtube.com.qa", true, false, false},
+ {"youtube.com.ro", true, false, false},
+ {"youtube.com.sa", true, false, false},
+ {"youtube.com.sg", true, false, false},
+ {"youtube.com.tn", true, false, false},
+ {"youtube.com.tr", true, false, false},
+ {"youtube.com.tw", true, false, false},
+ {"youtube.com.ua", true, false, false},
+ {"youtube.com.uy", true, false, false},
+ {"youtube.com.ve", true, false, false},
+ {"youtube.cz", true, false, false},
+ {"youtube.de", true, false, false},
+ {"youtube.dk", true, false, false},
+ {"youtube.ee", true, false, false},
+ {"youtube.es", true, false, false},
+ {"youtube.fi", true, false, false},
+ {"youtube.fr", true, false, false},
+ {"youtube.ge", true, false, false},
+ {"youtube.gr", true, false, false},
+ {"youtube.gt", true, false, false},
+ {"youtube.hk", true, false, false},
+ {"youtube.hr", true, false, false},
+ {"youtube.hu", true, false, false},
+ {"youtube.ie", true, false, false},
+ {"youtube.in", true, false, false},
+ {"youtube.is", true, false, false},
+ {"youtube.it", true, false, false},
+ {"youtube.jo", true, false, false},
+ {"youtube.jp", true, false, false},
+ {"youtube.kr", true, false, false},
+ {"youtube.lk", true, false, false},
+ {"youtube.lt", true, false, false},
+ {"youtube.lv", true, false, false},
+ {"youtube.ma", true, false, false},
+ {"youtube.md", true, false, false},
+ {"youtube.me", true, false, false},
+ {"youtube.mk", true, false, false},
+ {"youtube.mx", true, false, false},
+ {"youtube.my", true, false, false},
+ {"youtube.ng", true, false, false},
+ {"youtube.nl", true, false, false},
+ {"youtube.no", true, false, false},
+ {"youtube.pe", true, false, false},
+ {"youtube.ph", true, false, false},
+ {"youtube.pk", true, false, false},
+ {"youtube.pl", true, false, false},
+ {"youtube.pr", true, false, false},
+ {"youtube.pt", true, false, false},
+ {"youtube.qa", true, false, false},
+ {"youtube.ro", true, false, false},
+ {"youtube.rs", true, false, false},
+ {"youtube.ru", true, false, false},
+ {"youtube.sa", true, false, false},
+ {"youtube.se", true, false, false},
+ {"youtube.sg", true, false, false},
+ {"youtube.si", true, false, false},
+ {"youtube.sk", true, false, false},
+ {"youtube.sn", true, false, false},
+ {"youtube.tn", true, false, false},
+ {"youtube.ua", true, false, false},
+ {"youtube.ug", true, false, false},
+ {"youtube.uy", true, false, false},
+ {"youtube.vn", true, false, false},
+ {"youtubeeducation.com", true, false, false},
+ {"youtubemobilesupport.com", true, false, false},
+ {"ytimg.com", true, false, false},
- // Origins without subdomains and with same-origin collectors.
- { "accounts.google.com", false, true, false },
- { "apis.google.com", false, true, false },
- { "b.mail.google.com", false, true, false },
- { "chatenabled.mail.google.com", false, true, false },
- { "ddm.google.com", false, true, false },
- { "gmail.com", false, true, false },
- { "gmail.google.com", false, true, false },
- { "mail-attachment.googleusercontent.com", false, true, false },
- { "mail.google.com", false, true, false },
- { "www.gmail.com", false, true, false },
+ // Origins without subdomains and with same-origin collectors.
+ {"accounts.google.com", false, true, false},
+ {"apis.google.com", false, true, false},
+ {"b.mail.google.com", false, true, false},
+ {"chatenabled.mail.google.com", false, true, false},
+ {"ddm.google.com", false, true, false},
+ {"gmail.com", false, true, false},
+ {"gmail.google.com", false, true, false},
+ {"mail-attachment.googleusercontent.com", false, true, false},
+ {"mail.google.com", false, true, false},
+ {"www.gmail.com", false, true, false},
- // Origins without subdomains or same-origin collectors.
- { "ad.doubleclick.net", false, false, false },
- { "drive.google.com", false, false, false },
- { "redirector.googlevideo.com", false, false, false },
+ // Origins without subdomains or same-origin collectors.
+ {"ad.doubleclick.net", false, false, false},
+ {"drive.google.com", false, false, false},
+ {"redirector.googlevideo.com", false, false, false},
};
const char* kGoogleStandardCollectors[] = {
diff --git a/chromium/components/domain_reliability/quic_error_mapping.cc b/chromium/components/domain_reliability/quic_error_mapping.cc
index 56d3c76591a..41283a567f8 100644
--- a/chromium/components/domain_reliability/quic_error_mapping.cc
+++ b/chromium/components/domain_reliability/quic_error_mapping.cc
@@ -126,8 +126,6 @@ const struct QuicErrorMapping {
// Disabled QUIC because of too many PUBLIC_RESETs post handshake.
{net::QUIC_PUBLIC_RESETS_POST_HANDSHAKE,
"quic.public_resets_post_handshake"},
- // Disabled QUIC because of too many timeouts with streams open.
- {net::QUIC_TIMEOUTS_WITH_OPEN_STREAMS, "quic.timeouts_with_open_streams"},
// Closed because we failed to serialize a packet.
{net::QUIC_FAILED_TO_SERIALIZE_PACKET, "quic.failed_to_serialize_packet"},
// QUIC timed out after too many RTOs.
@@ -253,7 +251,7 @@ const struct QuicErrorMapping {
// Must be updated any time a net::QuicErrorCode is deprecated in
// net/quic/core/quic_packets.h.
-const int kDeprecatedQuicErrorCount = 4;
+const int kDeprecatedQuicErrorCount = 5;
const int kActiveQuicErrorCount =
net::QUIC_LAST_ERROR - kDeprecatedQuicErrorCount;
diff --git a/chromium/components/domain_reliability/uploader.cc b/chromium/components/domain_reliability/uploader.cc
index 19dd56d4902..92bea3c394d 100644
--- a/chromium/components/domain_reliability/uploader.cc
+++ b/chromium/components/domain_reliability/uploader.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/supports_user_data.h"
#include "components/domain_reliability/util.h"
@@ -16,6 +17,7 @@
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
@@ -40,8 +42,9 @@ class UploadUserData : public base::SupportsUserData::Data {
private:
UploadUserData(int depth) : depth_(depth) {}
- static base::SupportsUserData::Data* CreateUploadUserData(int depth) {
- return new UploadUserData(depth);
+ static std::unique_ptr<base::SupportsUserData::Data> CreateUploadUserData(
+ int depth) {
+ return base::WrapUnique(new UploadUserData(depth));
}
int depth_;
@@ -83,8 +86,34 @@ class DomainReliabilityUploaderImpl
return;
}
- std::unique_ptr<net::URLFetcher> owned_fetcher =
- net::URLFetcher::Create(0, upload_url, net::URLFetcher::POST, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("domain_reliability_report_upload",
+ R"(
+ semantics {
+ sender: "Domain Reliability"
+ description:
+ "If Chromium has trouble reaching certain Google sites or "
+ "services, Domain Reliability may report the problems back to "
+ "Google."
+ trigger: "Failure to load certain Google sites or services."
+ data:
+ "Details of the failed request, including the URL, any IP "
+ "addresses the browser tried to connect to, error(s) "
+ "encountered loading the resource, and other connection details."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can enable or disable Domain Reliability on desktop, via "
+ "toggling 'Automatically send usage statistics and crash reports "
+ "to Google' in Chromium's settings under Privacy. On ChromeOS, "
+ "the setting is named 'Automatically send diagnostic and usage "
+ "data to Google'."
+ policy_exception_justification: "Not implemented."
+ })");
+ std::unique_ptr<net::URLFetcher> owned_fetcher = net::URLFetcher::Create(
+ 0, upload_url, net::URLFetcher::POST, this, traffic_annotation);
net::URLFetcher* fetcher = owned_fetcher.get();
fetcher->SetRequestContext(url_request_context_getter_.get());
fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
diff --git a/chromium/components/domain_reliability/uploader_unittest.cc b/chromium/components/domain_reliability/uploader_unittest.cc
index 0b99fc0655d..ae037e9b035 100644
--- a/chromium/components/domain_reliability/uploader_unittest.cc
+++ b/chromium/components/domain_reliability/uploader_unittest.cc
@@ -33,7 +33,6 @@ const char kUploadURL[] = "https://example/upload";
struct MockUploadResult {
int net_error;
- int response_code;
scoped_refptr<net::HttpResponseHeaders> response_headers;
};
@@ -95,10 +94,6 @@ class UploadMockURLRequestJob : public net::URLRequestJob {
NotifyStartError(net::URLRequestStatus::FromError(result_.net_error));
}
- int GetResponseCode() const override {
- return result_.response_code;
- }
-
void GetResponseInfo(net::HttpResponseInfo* info) override {
info->headers = result_.response_headers;
}
@@ -135,23 +130,12 @@ class UploadInterceptor : public net::URLRequestInterceptor {
void ExpectRequestAndReturnError(int net_error) {
MockUploadResult result;
result.net_error = net_error;
- result.response_code = -1;
- results_.push_back(result);
- }
-
- void ExpectRequestAndReturnResponseCode(int response_code) {
- MockUploadResult result;
- result.net_error = net::OK;
- result.response_code = response_code;
results_.push_back(result);
}
- void ExpectRequestAndReturnResponseCodeAndHeaders(
- int response_code,
- const char* headers) {
+ void ExpectRequestAndReturnResponseHeaders(const char* headers) {
MockUploadResult result;
result.net_error = net::OK;
- result.response_code = response_code;
result.response_headers = new net::HttpResponseHeaders(
net::HttpUtil::AssembleRawHeaders(headers, strlen(headers)));
results_.push_back(result);
@@ -226,7 +210,7 @@ TEST_F(DomainReliabilityUploaderTest, Null) {
}
TEST_F(DomainReliabilityUploaderTest, SuccessfulUpload) {
- interceptor()->ExpectRequestAndReturnResponseCode(200);
+ interceptor()->ExpectRequestAndReturnResponseHeaders("HTTP/1.1 200\r\n\r\n");
TestUploadCallback c;
uploader()->UploadReport("{}", 0, GURL(kUploadURL), c.callback());
@@ -250,7 +234,7 @@ TEST_F(DomainReliabilityUploaderTest, NetworkErrorUpload) {
}
TEST_F(DomainReliabilityUploaderTest, ServerErrorUpload) {
- interceptor()->ExpectRequestAndReturnResponseCode(500);
+ interceptor()->ExpectRequestAndReturnResponseHeaders("HTTP/1.1 500\r\n\r\n");
TestUploadCallback c;
uploader()->UploadReport("{}", 0, GURL(kUploadURL), c.callback());
@@ -262,8 +246,7 @@ TEST_F(DomainReliabilityUploaderTest, ServerErrorUpload) {
}
TEST_F(DomainReliabilityUploaderTest, RetryAfterUpload) {
- interceptor()->ExpectRequestAndReturnResponseCodeAndHeaders(
- 503,
+ interceptor()->ExpectRequestAndReturnResponseHeaders(
"HTTP/1.1 503 Ugh\nRetry-After: 3600\n\n");
TestUploadCallback c;
@@ -276,7 +259,7 @@ TEST_F(DomainReliabilityUploaderTest, RetryAfterUpload) {
}
TEST_F(DomainReliabilityUploaderTest, UploadDepth1) {
- interceptor()->ExpectRequestAndReturnResponseCode(200);
+ interceptor()->ExpectRequestAndReturnResponseHeaders("HTTP/1.1 200\r\n\r\n");
TestUploadCallback c;
uploader()->UploadReport("{}", 0, GURL(kUploadURL), c.callback());
@@ -289,7 +272,7 @@ TEST_F(DomainReliabilityUploaderTest, UploadDepth1) {
}
TEST_F(DomainReliabilityUploaderTest, UploadDepth2) {
- interceptor()->ExpectRequestAndReturnResponseCode(200);
+ interceptor()->ExpectRequestAndReturnResponseHeaders("HTTP/1.1 200\r\n\r\n");
TestUploadCallback c;
uploader()->UploadReport("{}", 1, GURL(kUploadURL), c.callback());
diff --git a/chromium/components/domain_reliability/util.cc b/chromium/components/domain_reliability/util.cc
index 517b304dfa0..9c4406fe9a4 100644
--- a/chromium/components/domain_reliability/util.cc
+++ b/chromium/components/domain_reliability/util.cc
@@ -126,6 +126,8 @@ std::string GetDomainReliabilityProtocol(
case net::HttpResponseInfo::CONNECTION_INFO_QUIC_36:
case net::HttpResponseInfo::CONNECTION_INFO_QUIC_37:
case net::HttpResponseInfo::CONNECTION_INFO_QUIC_38:
+ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_39:
+ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_40:
return "QUIC";
case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS:
NOTREACHED();
diff --git a/chromium/components/doodle/BUILD.gn b/chromium/components/doodle/BUILD.gn
index e53b617ee7c..0588d1738e6 100644
--- a/chromium/components/doodle/BUILD.gn
+++ b/chromium/components/doodle/BUILD.gn
@@ -19,9 +19,11 @@ static_library("doodle") {
"//base",
"//components/data_use_measurement/core",
"//components/google/core/browser",
+ "//components/image_fetcher/core",
"//components/keyed_service/core",
"//components/prefs",
"//net",
+ "//ui/gfx",
]
}
@@ -36,8 +38,10 @@ source_set("unit_tests") {
deps = [
":doodle",
"//components/google/core/browser",
+ "//components/image_fetcher/core",
"//components/prefs:test_support",
"//net:test_support",
"//ui/base",
+ "//ui/gfx:test_support",
]
}
diff --git a/chromium/components/doodle/DEPS b/chromium/components/doodle/DEPS
index b41c6c92580..f5fa82b871a 100644
--- a/chromium/components/doodle/DEPS
+++ b/chromium/components/doodle/DEPS
@@ -1,10 +1,12 @@
include_rules = [
"+components/data_use_measurement/core",
"+components/google/core/browser",
+ "+components/image_fetcher/core",
"+components/keyed_service/core",
"+components/prefs",
"+net/base",
"+net/http/http_status_code.h",
"+net/traffic_annotation",
"+net/url_request",
+ "+ui/gfx",
]
diff --git a/chromium/components/doodle/doodle_fetcher.h b/chromium/components/doodle/doodle_fetcher.h
index e7a5d2636b9..5418bd97f57 100644
--- a/chromium/components/doodle/doodle_fetcher.h
+++ b/chromium/components/doodle/doodle_fetcher.h
@@ -37,6 +37,10 @@ class DoodleFetcher {
// If a fetch is already running, the callback will be queued and invoked with
// the result from the next completed request.
virtual void FetchDoodle(FinishedCallback callback) = 0;
+
+ // Returns whether a fetch is currently in progress, i.e. whether any callback
+ // passed to FetchDoodle hasn't been called yet.
+ virtual bool IsFetchInProgress() const = 0;
};
} // namespace doodle
diff --git a/chromium/components/doodle/doodle_fetcher_impl.cc b/chromium/components/doodle/doodle_fetcher_impl.cc
index b1c8188b88c..c673745533e 100644
--- a/chromium/components/doodle/doodle_fetcher_impl.cc
+++ b/chromium/components/doodle/doodle_fetcher_impl.cc
@@ -87,31 +87,40 @@ void DoodleFetcherImpl::FetchDoodle(FinishedCallback callback) {
"currently running Doodle."
trigger:
"Displaying the new tab page on Android."
- data: "None."
+ data:
+ "The user's Google cookies. Used for example to show birthday "
+ "doodles at appropriate times."
destination: GOOGLE_OWNED_SERVICE
}
policy {
- cookies_allowed: false
+ cookies_allowed: true
+ cookies_store: "user"
setting:
"Choosing a non-Google search engine in Chromium settings under "
"'Search Engine' will disable this feature."
- policy_exception_justification:
- "Not implemented, considered not useful as it does not upload any "
- "data."
+ chrome_policy {
+ DefaultSearchProviderEnabled {
+ policy_options {mode: MANDATORY}
+ DefaultSearchProviderEnabled: false
+ }
+ }
})");
fetcher_ = URLFetcher::Create(
BuildDoodleURL(GetGoogleBaseUrl(), gray_background_, override_url_),
URLFetcher::GET, this, traffic_annotation);
fetcher_->SetRequestContext(download_context_.get());
- fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
+ // TODO(treib): Use OAuth2 authentication instead of cookies. crbug.com/711314
+ fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_AUTH_DATA);
fetcher_->SetAutomaticallyRetryOnNetworkChanges(1);
data_use_measurement::DataUseUserData::AttachToFetcher(
fetcher_.get(), data_use_measurement::DataUseUserData::DOODLE);
fetcher_->Start();
}
+bool DoodleFetcherImpl::IsFetchInProgress() const {
+ return !callbacks_.empty();
+}
+
void DoodleFetcherImpl::OnURLFetchComplete(const URLFetcher* source) {
DCHECK_EQ(fetcher_.get(), source);
std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_);
diff --git a/chromium/components/doodle/doodle_fetcher_impl.h b/chromium/components/doodle/doodle_fetcher_impl.h
index 07f4f0129eb..f8eb6fd9949 100644
--- a/chromium/components/doodle/doodle_fetcher_impl.h
+++ b/chromium/components/doodle/doodle_fetcher_impl.h
@@ -50,11 +50,9 @@ class DoodleFetcherImpl : public DoodleFetcher, public net::URLFetcherDelegate {
const base::Optional<std::string>& override_url);
~DoodleFetcherImpl() override;
- // Fetches a doodle asynchronously. The |callback| is called with a
- // DoodleState indicating whether the request succeded in fetching a doodle.
- // If a fetch is already running, the callback will be queued and invoked with
- // result from the next completed request.
+ // DoodleFetcher implementation.
void FetchDoodle(FinishedCallback callback) override;
+ bool IsFetchInProgress() const override;
private:
// net::URLFetcherDelegate implementation.
@@ -75,10 +73,6 @@ class DoodleFetcherImpl : public DoodleFetcher, public net::URLFetcherDelegate {
GURL GetGoogleBaseUrl() const;
- // Returns whether a fetch is still in progress. A fetch begins when a
- // callback is added and ends when the last callback was called.
- bool IsFetchInProgress() const { return !callbacks_.empty(); }
-
// Parameters set from constructor.
scoped_refptr<net::URLRequestContextGetter> const download_context_;
GoogleURLTracker* google_url_tracker_;
diff --git a/chromium/components/doodle/doodle_service.cc b/chromium/components/doodle/doodle_service.cc
index cd4b053edf1..ce3ab4d73a2 100644
--- a/chromium/components/doodle/doodle_service.cc
+++ b/chromium/components/doodle/doodle_service.cc
@@ -10,10 +10,15 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/values.h"
+#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/doodle/pref_names.h"
+#include "components/image_fetcher/core/image_fetcher.h"
+#include "components/image_fetcher/core/request_metadata.h"
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "ui/gfx/image/image.h"
namespace doodle {
@@ -26,6 +31,11 @@ const int64_t kMaxTimeToLiveSecs = 30 * 24 * 60 * 60; // 30 days
// The default value for DoodleService::min_refresh_interval_.
const int64_t kDefaultMinRefreshIntervalSecs = 15 * 60; // 15 minutes
+// The maximum number of bytes to allow in a doodle image. This limits the
+// downloaded data to an amount that real images are unlikely to exceed. It is a
+// safeguard against server-side errors.
+const int64_t kMaxImageDownloadBytes = 1024 * 1024;
+
} // namespace
// static
@@ -43,7 +53,8 @@ DoodleService::DoodleService(
std::unique_ptr<base::OneShotTimer> expiry_timer,
std::unique_ptr<base::Clock> clock,
std::unique_ptr<base::TickClock> tick_clock,
- base::Optional<base::TimeDelta> override_min_refresh_interval)
+ base::Optional<base::TimeDelta> override_min_refresh_interval,
+ std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher)
: pref_service_(pref_service),
fetcher_(std::move(fetcher)),
expiry_timer_(std::move(expiry_timer)),
@@ -52,12 +63,18 @@ DoodleService::DoodleService(
min_refresh_interval_(
override_min_refresh_interval.has_value()
? override_min_refresh_interval.value()
- : base::TimeDelta::FromSeconds(kDefaultMinRefreshIntervalSecs)) {
+ : base::TimeDelta::FromSeconds(kDefaultMinRefreshIntervalSecs)),
+ image_fetcher_(std::move(image_fetcher)) {
DCHECK(pref_service_);
DCHECK(fetcher_);
DCHECK(expiry_timer_);
DCHECK(clock_);
DCHECK(tick_clock_);
+ DCHECK(image_fetcher_);
+
+ image_fetcher_->SetImageDownloadLimit(kMaxImageDownloadBytes);
+ image_fetcher_->SetDataUseServiceName(
+ data_use_measurement::DataUseUserData::DOODLE);
base::Time expiry_date = base::Time::FromInternalValue(
pref_service_->GetInt64(prefs::kCachedConfigExpiry));
@@ -66,12 +83,60 @@ DoodleService::DoodleService(
DoodleState state =
config.has_value() ? DoodleState::AVAILABLE : DoodleState::NO_DOODLE;
HandleNewConfig(state, expiry_date - clock_->Now(), config);
+
+ // If we don't have a cached doodle, immediately start a fetch, so that the
+ // first NTP will get it quicker.
+ if (state == DoodleState::NO_DOODLE) {
+ Refresh();
+ }
}
DoodleService::~DoodleService() = default;
void DoodleService::Shutdown() {}
+void DoodleService::GetImage(const ImageCallback& callback) {
+ if (!cached_config_.has_value()) {
+ callback.Run(gfx::Image());
+ return;
+ }
+
+ // If there is a CTA image, that means the main image is animated. Show the
+ // non-animated CTA image first, and load the animated one only when the
+ // user requests it.
+ bool has_cta = cached_config_->large_cta_image.has_value();
+ const GURL& image_url = has_cta ? cached_config_->large_cta_image->url
+ : cached_config_->large_image.url;
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("doodle_service", R"(
+ semantics {
+ sender: "Doodle Service"
+ description:
+ "Downloads the Doodle image if Google is the configured search "
+ "provider."
+ trigger: "Displaying the new tab page on Android."
+ data: "None."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Choosing a non-Google search engine in Chromium settings under "
+ "'Search Engine' disables this feature."
+ chrome_policy {
+ DefaultSearchProviderEnabled {
+ policy_options {mode: MANDATORY}
+ DefaultSearchProviderEnabled: false
+ }
+ }
+ })");
+ image_fetcher_->StartOrQueueNetworkRequest(
+ image_url.spec(), image_url,
+ base::Bind(&DoodleService::ImageFetched, base::Unretained(this),
+ callback),
+ traffic_annotation);
+}
+
void DoodleService::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
@@ -81,14 +146,24 @@ void DoodleService::RemoveObserver(Observer* observer) {
}
void DoodleService::Refresh() {
+ // If we're already waiting for a fetch, don't start another one. The
+ // observers will get notified when the ongoing fetch returns.
+ if (fetcher_->IsFetchInProgress()) {
+ return;
+ }
+
base::TimeTicks now_ticks = tick_clock_->NowTicks();
// Check if we have passed the minimum refresh interval.
base::TimeDelta time_since_fetch = now_ticks - last_successful_fetch_;
if (time_since_fetch < min_refresh_interval_) {
RecordDownloadMetrics(OUTCOME_REFRESH_INTERVAL_NOT_PASSED,
base::TimeDelta());
+ for (auto& observer : observers_) {
+ observer.OnDoodleConfigRevalidated(/*from_cache=*/true);
+ }
return;
}
+
fetcher_->FetchDoodle(base::BindOnce(&DoodleService::DoodleFetched,
base::Unretained(this), now_ticks));
}
@@ -192,7 +267,6 @@ DoodleService::DownloadOutcome DoodleService::HandleNewConfig(
DownloadOutcome outcome =
DetermineDownloadOutcome(cached_config_, new_config, state, expired);
- // If the config changed, update our cache and notify observers.
// Note that this checks both for existence changes as well as changes of the
// configs themselves.
if (cached_config_ != new_config) {
@@ -201,6 +275,10 @@ DoodleService::DownloadOutcome DoodleService::HandleNewConfig(
for (auto& observer : observers_) {
observer.OnDoodleConfigUpdated(cached_config_);
}
+ } else {
+ for (auto& observer : observers_) {
+ observer.OnDoodleConfigRevalidated(/*from_cache=*/false);
+ }
}
// Even if the configs are identical, the time-to-live might have changed.
@@ -239,4 +317,21 @@ void DoodleService::DoodleExpired() {
HandleNewConfig(DoodleState::NO_DOODLE, base::TimeDelta(), base::nullopt);
}
+void DoodleService::ImageFetched(
+ const ImageCallback& callback,
+ const std::string& id,
+ const gfx::Image& image,
+ const image_fetcher::RequestMetadata& metadata) {
+ if (image.IsEmpty()) {
+ DLOG(WARNING) << "Failed to download doodle image";
+ } else {
+ // TODO(treib): Rename this to "Doodle.*" after we've decided what to do
+ // about crbug.com/719513.
+ UMA_HISTOGRAM_BOOLEAN("NewTabPage.LogoImageDownloaded",
+ metadata.from_http_cache);
+ }
+
+ callback.Run(image);
+}
+
} // namespace doodle
diff --git a/chromium/components/doodle/doodle_service.h b/chromium/components/doodle/doodle_service.h
index e4a9792a991..a1d574aac88 100644
--- a/chromium/components/doodle/doodle_service.h
+++ b/chromium/components/doodle/doodle_service.h
@@ -6,7 +6,9 @@
#define COMPONENTS_DOODLE_DOODLE_SERVICE_H_
#include <memory>
+#include <string>
+#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/optional.h"
@@ -21,15 +23,27 @@
class PrefRegistrySimple;
class PrefService;
+namespace gfx {
+class Image;
+}
+
+namespace image_fetcher {
+class ImageFetcher;
+struct RequestMetadata;
+}
+
namespace doodle {
class DoodleService : public KeyedService {
public:
class Observer {
public:
+ virtual void OnDoodleConfigRevalidated(bool from_cache) = 0;
virtual void OnDoodleConfigUpdated(const base::Optional<DoodleConfig>&) = 0;
};
+ using ImageCallback = base::Callback<void(const gfx::Image& image)>;
+
static void RegisterProfilePrefs(PrefRegistrySimple* pref_registry);
// All pointer parameters must be non-null. If |min_refresh_interval| doesn't
@@ -39,7 +53,8 @@ class DoodleService : public KeyedService {
std::unique_ptr<base::OneShotTimer> expiry_timer,
std::unique_ptr<base::Clock> clock,
std::unique_ptr<base::TickClock> tick_clock,
- base::Optional<base::TimeDelta> override_min_refresh_interval);
+ base::Optional<base::TimeDelta> override_min_refresh_interval,
+ std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher);
~DoodleService() override;
// KeyedService implementation.
@@ -48,6 +63,11 @@ class DoodleService : public KeyedService {
// Returns the current (cached) config, if any.
const base::Optional<DoodleConfig>& config() const { return cached_config_; }
+ // Returns the image for the currently-cached doodle config via |callback|,
+ // which may be run synchronously or asynchronously. If the doodle is
+ // animated, this returns the static CTA image.
+ void GetImage(const ImageCallback& callback);
+
// Adds a new observer to the service. It'll only be called when the config
// changes; to get the current (cached) config, call |config()|.
void AddObserver(Observer* observer);
@@ -57,8 +77,8 @@ class DoodleService : public KeyedService {
void RemoveObserver(Observer* observer);
// Requests an asynchronous refresh of the DoodleConfig from the network.
- // After the update completes, the observers will be notified only if the
- // config changed.
+ // After the update completes, the observers will be notified whether the
+ // config changed or active config remains valid.
void Refresh();
private:
@@ -104,6 +124,11 @@ class DoodleService : public KeyedService {
// Callback for the expiry timer.
void DoodleExpired();
+ void ImageFetched(const ImageCallback& callback,
+ const std::string& id,
+ const gfx::Image& image,
+ const image_fetcher::RequestMetadata& metadata);
+
PrefService* pref_service_;
// The fetcher for getting fresh DoodleConfigs from the network.
@@ -117,6 +142,8 @@ class DoodleService : public KeyedService {
// refresh requests are ignored for this period.
const base::TimeDelta min_refresh_interval_;
+ std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
+
// The result of the last network fetch.
base::Optional<DoodleConfig> cached_config_;
diff --git a/chromium/components/doodle/doodle_service_unittest.cc b/chromium/components/doodle/doodle_service_unittest.cc
index 8f6fc7e1011..6698df02fd7 100644
--- a/chromium/components/doodle/doodle_service_unittest.cc
+++ b/chromium/components/doodle/doodle_service_unittest.cc
@@ -12,16 +12,27 @@
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/test/histogram_tester.h"
+#include "base/test/mock_callback.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "components/image_fetcher/core/image_fetcher.h"
+#include "components/image_fetcher/core/request_metadata.h"
#include "components/prefs/testing_pref_service.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_unittest_util.h"
+using image_fetcher::ImageFetcher;
+using image_fetcher::RequestMetadata;
+using testing::_;
using testing::Eq;
using testing::StrictMock;
+using testing::Not;
namespace doodle {
@@ -36,6 +47,8 @@ class FakeDoodleFetcher : public DoodleFetcher {
callbacks_.push_back(std::move(callback));
}
+ bool IsFetchInProgress() const override { return !callbacks_.empty(); }
+
size_t num_pending_callbacks() const { return callbacks_.size(); }
void ServeAllCallbacks(DoodleState state,
@@ -55,12 +68,78 @@ class MockDoodleObserver : public DoodleService::Observer {
public:
MOCK_METHOD1(OnDoodleConfigUpdated,
void(const base::Optional<DoodleConfig>&));
+ MOCK_METHOD1(OnDoodleConfigRevalidated, void(bool));
+};
+
+class FakeImageFetcher : public ImageFetcher {
+ public:
+ FakeImageFetcher() = default;
+ ~FakeImageFetcher() override = default;
+
+ void SetImageFetcherDelegate(image_fetcher::ImageFetcherDelegate*) override {
+ NOTREACHED();
+ }
+
+ void SetDataUseServiceName(DataUseServiceName) override {
+ // Ignored.
+ }
+
+ void SetImageDownloadLimit(base::Optional<int64_t>) override {
+ // Ignored.
+ }
+
+ void SetDesiredImageFrameSize(const gfx::Size&) override {
+ // Ignored.
+ }
+
+ void StartOrQueueNetworkRequest(
+ const std::string& id,
+ const GURL& url,
+ const ImageFetcherCallback& callback,
+ const net::NetworkTrafficAnnotationTag&) override {
+ // For simplicity, the fake doesn't support multiple concurrent requests.
+ DCHECK(!HasPendingRequest());
+
+ pending_id_ = id;
+ pending_url_ = url;
+ pending_callback_ = callback;
+ }
+
+ image_fetcher::ImageDecoder* GetImageDecoder() override {
+ NOTREACHED();
+ return nullptr;
+ }
+
+ bool HasPendingRequest() const { return !pending_callback_.is_null(); }
+
+ const GURL& pending_url() const { return pending_url_; }
+
+ void RespondToPendingRequest(const gfx::Image& image) {
+ DCHECK(HasPendingRequest());
+
+ RequestMetadata metadata;
+ metadata.http_response_code = 200;
+ pending_callback_.Run(pending_id_, image, metadata);
+
+ pending_id_.clear();
+ pending_url_ = GURL();
+ pending_callback_.Reset();
+ }
+
+ private:
+ std::string pending_id_;
+ GURL pending_url_;
+ ImageFetcherCallback pending_callback_;
};
DoodleConfig CreateConfig(DoodleType type) {
return DoodleConfig(type, DoodleImage(GURL("https://doodle.com/image.jpg")));
}
+MATCHER(IsEmptyImage, "") {
+ return arg.IsEmpty();
+}
+
} // namespace
class DoodleServiceTest : public testing::Test {
@@ -80,7 +159,20 @@ class DoodleServiceTest : public testing::Test {
RecreateServiceWithZeroRefreshInterval();
}
- void DestroyService() { service_ = nullptr; }
+ void TearDown() override { DestroyService(); }
+
+ void DestroyService() {
+ if (image_fetcher_) {
+ // Make sure we didn't receive an unexpected image request.
+ ASSERT_FALSE(image_fetcher_->HasPendingRequest());
+ }
+
+ fetcher_ = nullptr;
+ expiry_timer_ = nullptr;
+ image_fetcher_ = nullptr;
+
+ service_ = nullptr;
+ }
void RecreateServiceWithZeroRefreshInterval() {
RecreateService(/*min_refresh_interval=*/base::TimeDelta());
@@ -94,14 +186,18 @@ class DoodleServiceTest : public testing::Test {
auto fetcher = base::MakeUnique<FakeDoodleFetcher>();
fetcher_ = fetcher.get();
+ auto image_fetcher = base::MakeUnique<FakeImageFetcher>();
+ image_fetcher_ = image_fetcher.get();
+
service_ = base::MakeUnique<DoodleService>(
&pref_service_, std::move(fetcher), std::move(expiry_timer),
task_runner_->GetMockClock(), task_runner_->GetMockTickClock(),
- refresh_interval);
+ refresh_interval, std::move(image_fetcher));
}
DoodleService* service() { return service_.get(); }
FakeDoodleFetcher* fetcher() { return fetcher_; }
+ FakeImageFetcher* image_fetcher() { return image_fetcher_; }
base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
@@ -117,6 +213,7 @@ class DoodleServiceTest : public testing::Test {
// Weak, owned by the service.
FakeDoodleFetcher* fetcher_;
base::OneShotTimer* expiry_timer_;
+ FakeImageFetcher* image_fetcher_;
};
TEST_F(DoodleServiceTest, FetchesConfigOnRefresh) {
@@ -150,6 +247,16 @@ TEST_F(DoodleServiceTest, FetchesConfigOnRefresh) {
EXPECT_THAT(service()->config(), Eq(other_config));
}
+TEST_F(DoodleServiceTest, CoalescesRefreshCalls) {
+ ASSERT_THAT(service()->config(), Eq(base::nullopt));
+
+ // Request a refresh of the doodle config, twice.
+ service()->Refresh();
+ service()->Refresh();
+ // Only one request should have arrived at the fetcher.
+ EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
+}
+
TEST_F(DoodleServiceTest, PersistsConfig) {
// Load some doodle config.
service()->Refresh();
@@ -165,6 +272,27 @@ TEST_F(DoodleServiceTest, PersistsConfig) {
EXPECT_THAT(service()->config(), Eq(config));
}
+TEST_F(DoodleServiceTest, FetchesOnCreationIfEmpty) {
+ ASSERT_THAT(service()->config(), Eq(base::nullopt));
+
+ // Since there was no cached config, the service should have sent a request.
+ EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
+}
+
+TEST_F(DoodleServiceTest, DoesNotFetchOnCreationWithCachedConfig) {
+ // Load some doodle config.
+ service()->Refresh();
+ DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
+ fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
+ base::TimeDelta::FromHours(1), config);
+ ASSERT_THAT(service()->config(), Eq(config));
+
+ RecreateServiceWithZeroRefreshInterval();
+
+ // Since there was a cached config, there should be no refresh request.
+ EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(0u));
+}
+
TEST_F(DoodleServiceTest, PersistsExpiryDate) {
// Load some doodle config.
service()->Refresh();
@@ -309,7 +437,7 @@ TEST_F(DoodleServiceTest, CallsObserverOnConfigUpdated) {
service()->RemoveObserver(&observer);
}
-TEST_F(DoodleServiceTest, DoesNotCallObserverIfConfigEquivalent) {
+TEST_F(DoodleServiceTest, CallsObserverIfConfigRevalidatedByNetworkRequest) {
// Load some doodle config.
service()->Refresh();
DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
@@ -317,14 +445,18 @@ TEST_F(DoodleServiceTest, DoesNotCallObserverIfConfigEquivalent) {
base::TimeDelta::FromHours(1), config);
ASSERT_THAT(service()->config(), Eq(config));
- // Register an observer and request a refresh.
+ // Let some time pass (more than the refresh interval).
+ task_runner()->FastForwardBy(base::TimeDelta::FromMinutes(16));
+
+ // Register an observer and request a refresh after refresh intervall passed.
StrictMock<MockDoodleObserver> observer;
+ EXPECT_CALL(observer, OnDoodleConfigRevalidated(Eq(/*from_cache=*/false)));
service()->AddObserver(&observer);
service()->Refresh();
ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
// Serve the request with an equivalent doodle config. The observer should
- // *not* get notified.
+ // get notified about a (non-cached) revalidation.
DoodleConfig equivalent_config = CreateConfig(DoodleType::SIMPLE);
DCHECK(config == equivalent_config);
fetcher()->ServeAllCallbacks(
@@ -334,6 +466,28 @@ TEST_F(DoodleServiceTest, DoesNotCallObserverIfConfigEquivalent) {
service()->RemoveObserver(&observer);
}
+TEST_F(DoodleServiceTest, CallsObserverIfConfigRevalidatedByCache) {
+ // Create a service with the default refresh interval.
+ RecreateService(/*min_refresh_interval=*/base::nullopt);
+
+ // Load some doodle config.
+ service()->Refresh();
+ DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
+ fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
+ base::TimeDelta::FromHours(1), config);
+ ASSERT_THAT(service()->config(), Eq(config));
+
+ // Register an observer and request a refresh within refresh intervall.
+ StrictMock<MockDoodleObserver> observer;
+ EXPECT_CALL(observer, OnDoodleConfigRevalidated(Eq(/*from_cache=*/true)));
+ service()->AddObserver(&observer);
+ service()->Refresh();
+ ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(0u));
+
+ // Remove the observer before the service gets destroyed.
+ service()->RemoveObserver(&observer);
+}
+
TEST_F(DoodleServiceTest, CallsObserverWhenConfigExpires) {
// Load some doodle config.
service()->Refresh();
@@ -364,12 +518,14 @@ TEST_F(DoodleServiceTest, DisregardsAlreadyExpiredConfigs) {
StrictMock<MockDoodleObserver> observer;
service()->AddObserver(&observer);
+ // If there was no config and an expired config is loaded, not having a config
+ // must be revalidated.
ASSERT_THAT(service()->config(), Eq(base::nullopt));
- // Load an already-expired config. This should have no effect; in particular
- // no call to the observer.
+ // Load an already-expired config.
service()->Refresh();
DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
+ EXPECT_CALL(observer, OnDoodleConfigRevalidated(Eq(/*from_cache=*/false)));
fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
base::TimeDelta::FromSeconds(0), config);
EXPECT_THAT(service()->config(), Eq(base::nullopt));
@@ -535,4 +691,55 @@ TEST_F(DoodleServiceTest, DoesNotRecordMetricsWhenConfigExpires) {
histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0);
}
+TEST_F(DoodleServiceTest, GetImageWithEmptyConfigReturnsImmediately) {
+ ASSERT_THAT(service()->config(), Eq(base::nullopt));
+
+ base::MockCallback<DoodleService::ImageCallback> callback;
+ EXPECT_CALL(callback, Run(IsEmptyImage()));
+
+ service()->GetImage(callback.Get());
+}
+
+TEST_F(DoodleServiceTest, GetImageFetchesLargeImage) {
+ service()->Refresh();
+ DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
+ fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
+ base::TimeDelta::FromHours(1), config);
+ ASSERT_THAT(service()->config(), Eq(config));
+
+ base::MockCallback<DoodleService::ImageCallback> callback;
+ service()->GetImage(callback.Get());
+
+ EXPECT_EQ(config.large_image.url, image_fetcher()->pending_url());
+
+ EXPECT_CALL(callback, Run(Not(IsEmptyImage())));
+ gfx::Image image = gfx::test::CreateImage(1, 1);
+ ASSERT_TRUE(image_fetcher()->HasPendingRequest());
+ image_fetcher()->RespondToPendingRequest(image);
+}
+
+TEST_F(DoodleServiceTest, GetImageFetchesCTAImage) {
+ service()->Refresh();
+ DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
+ // Set a CTA image, which should take precedence over the regular image.
+ config.large_image.is_animated_gif = true;
+ config.large_cta_image = DoodleImage(GURL("https://doodle.com/cta.jpg"));
+ config.large_cta_image->is_cta = true;
+ fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
+ base::TimeDelta::FromHours(1), config);
+ ASSERT_THAT(service()->config(), Eq(config));
+
+ base::MockCallback<DoodleService::ImageCallback> callback;
+ service()->GetImage(callback.Get());
+
+ // If the doodle has a CTA image, that should loaded instead of the regular
+ // large image.
+ EXPECT_EQ(config.large_cta_image->url, image_fetcher()->pending_url());
+
+ EXPECT_CALL(callback, Run(Not(IsEmptyImage())));
+ gfx::Image image = gfx::test::CreateImage(1, 1);
+ ASSERT_TRUE(image_fetcher()->HasPendingRequest());
+ image_fetcher()->RespondToPendingRequest(image);
+}
+
} // namespace doodle
diff --git a/chromium/components/download/BUILD.gn b/chromium/components/download/BUILD.gn
new file mode 100644
index 00000000000..618a7055c8b
--- /dev/null
+++ b/chromium/components/download/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2017 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.
+
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+group("download") {
+ public_deps = [
+ "//components/download/public",
+ ]
+
+ deps = [
+ "//components/download/internal",
+ ]
+}
+
+group("unit_tests") {
+ testonly = true
+
+ deps = [
+ "//components/download/internal:unit_tests",
+ ]
+}
diff --git a/chromium/components/download/OWNERS b/chromium/components/download/OWNERS
new file mode 100644
index 00000000000..866d43d7f42
--- /dev/null
+++ b/chromium/components/download/OWNERS
@@ -0,0 +1,6 @@
+dtrainor@chromium.org
+qinmin@chromium.org
+shaktisahu@chromium.org
+xingliu@chromium.org
+
+# COMPONENT: UI>Browser>Downloads \ No newline at end of file
diff --git a/chromium/components/download/content/BUILD.gn b/chromium/components/download/content/BUILD.gn
new file mode 100644
index 00000000000..7ca79f683b1
--- /dev/null
+++ b/chromium/components/download/content/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2017 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.
+
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+source_set("content") {
+ sources = [
+ "download_driver_impl.cc",
+ "download_driver_impl.h",
+ ]
+
+ public_deps = [
+ "//components/download/internal",
+ "//components/download/public",
+ ]
+
+ deps = [
+ "//base",
+ "//content/public/browser",
+ "//net",
+ "//url",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+
+ sources = [
+ "download_driver_impl_unittest.cc",
+ ]
+
+ deps = [
+ ":content",
+ "//content/test:test_support",
+ "//testing/gmock",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/download/content/DEPS b/chromium/components/download/content/DEPS
new file mode 100644
index 00000000000..ea159c83af6
--- /dev/null
+++ b/chromium/components/download/content/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+content/public/browser",
+ "+content/public/test",
+ "+base",
+ "+net",
+]
diff --git a/chromium/components/download/content/download_driver_impl.cc b/chromium/components/download/content/download_driver_impl.cc
new file mode 100644
index 00000000000..0d1d2811430
--- /dev/null
+++ b/chromium/components/download/content/download_driver_impl.cc
@@ -0,0 +1,188 @@
+// Copyright 2017 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/download/content/download_driver_impl.h"
+
+#include "components/download/internal/driver_entry.h"
+#include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_url_parameters.h"
+#include "content/public/browser/storage_partition.h"
+#include "net/http/http_response_headers.h"
+
+namespace download {
+
+namespace {
+
+// Converts a content::DownloadItem::DownloadState to DriverEntry::State.
+DriverEntry::State ToDriverEntryState(
+ content::DownloadItem::DownloadState state) {
+ switch (state) {
+ case content::DownloadItem::IN_PROGRESS:
+ return DriverEntry::State::IN_PROGRESS;
+ case content::DownloadItem::COMPLETE:
+ return DriverEntry::State::COMPLETE;
+ case content::DownloadItem::CANCELLED:
+ return DriverEntry::State::CANCELLED;
+ case content::DownloadItem::INTERRUPTED:
+ return DriverEntry::State::INTERRUPTED;
+ case content::DownloadItem::MAX_DOWNLOAD_STATE:
+ return DriverEntry::State::UNKNOWN;
+ default:
+ NOTREACHED();
+ return DriverEntry::State::UNKNOWN;
+ }
+}
+
+} // namespace
+
+// static
+DriverEntry DownloadDriverImpl::CreateDriverEntry(
+ const content::DownloadItem* item) {
+ DCHECK(item);
+ DriverEntry entry;
+ entry.guid = item->GetGuid();
+ entry.state = ToDriverEntryState(item->GetState());
+ entry.paused = item->IsPaused();
+ entry.bytes_downloaded = item->GetReceivedBytes();
+ entry.expected_total_size = item->GetTotalBytes();
+ entry.response_headers = item->GetResponseHeaders();
+ return entry;
+}
+
+DownloadDriverImpl::DownloadDriverImpl(content::DownloadManager* manager,
+ const base::FilePath& dir)
+ : download_manager_(manager), file_dir_(dir), client_(nullptr) {
+ DCHECK(download_manager_);
+}
+
+DownloadDriverImpl::~DownloadDriverImpl() {
+ if (download_manager_)
+ download_manager_->RemoveObserver(this);
+}
+
+void DownloadDriverImpl::Initialize(DownloadDriver::Client* client) {
+ DCHECK(!client_);
+ client_ = client;
+ DCHECK(client_);
+
+ // |download_manager_| may be shut down. Informs the client.
+ if (!download_manager_) {
+ client_->OnDriverReady(false);
+ return;
+ }
+
+ download_manager_->AddObserver(this);
+ if (download_manager_->IsManagerInitialized())
+ client_->OnDriverReady(true);
+}
+
+bool DownloadDriverImpl::IsReady() const {
+ return client_ && download_manager_;
+}
+
+void DownloadDriverImpl::Start(const DownloadParams& params) {
+ DCHECK(!params.request_params.url.is_empty());
+ DCHECK(!params.guid.empty());
+ if (!download_manager_)
+ return;
+
+ content::StoragePartition* storage_partition =
+ content::BrowserContext::GetStoragePartitionForSite(
+ download_manager_->GetBrowserContext(), params.request_params.url);
+ DCHECK(storage_partition);
+
+ std::unique_ptr<content::DownloadUrlParameters> download_url_params(
+ new content::DownloadUrlParameters(
+ params.request_params.url,
+ storage_partition->GetURLRequestContext()));
+
+ // TODO(xingliu): Handle the request headers from |params|, need to tweak
+ // download network stack.
+ // Make content::DownloadManager handle potential guid collision and return
+ // an error to fail the download cleanly.
+ download_url_params->set_guid(params.guid);
+ download_url_params->set_transient(true);
+ download_url_params->set_method(params.request_params.method);
+ download_url_params->set_file_path(file_dir_.AppendASCII(params.guid));
+
+ download_manager_->DownloadUrl(std::move(download_url_params));
+}
+
+void DownloadDriverImpl::Cancel(const std::string& guid) {
+ if (!download_manager_)
+ return;
+ content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid);
+ // Cancels the download and removes the persisted records in content layer.
+ if (item) {
+ item->RemoveObserver(this);
+ item->Remove();
+ }
+}
+
+void DownloadDriverImpl::Pause(const std::string& guid) {
+ if (!download_manager_)
+ return;
+ content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid);
+ if (item)
+ item->Pause();
+}
+
+void DownloadDriverImpl::Resume(const std::string& guid) {
+ if (!download_manager_)
+ return;
+ content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid);
+ if (item)
+ item->Resume();
+}
+
+base::Optional<DriverEntry> DownloadDriverImpl::Find(const std::string& guid) {
+ if (!download_manager_)
+ return base::nullopt;
+ content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid);
+ if (item)
+ return CreateDriverEntry(item);
+ return base::nullopt;
+}
+
+void DownloadDriverImpl::OnDownloadUpdated(content::DownloadItem* item) {
+ DCHECK(client_);
+
+ using DownloadState = content::DownloadItem::DownloadState;
+ DownloadState state = item->GetState();
+ content::DownloadInterruptReason reason = item->GetLastReason();
+ DriverEntry entry = CreateDriverEntry(item);
+
+ if (state == DownloadState::COMPLETE) {
+ client_->OnDownloadSucceeded(entry, item->GetTargetFilePath());
+ item->RemoveObserver(this);
+ } else if (state == DownloadState::IN_PROGRESS) {
+ client_->OnDownloadUpdated(entry);
+ } else if (reason !=
+ content::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE) {
+ client_->OnDownloadFailed(entry, static_cast<int>(reason));
+ item->RemoveObserver(this);
+ }
+}
+
+void DownloadDriverImpl::OnDownloadCreated(content::DownloadManager* manager,
+ content::DownloadItem* item) {
+ // Listens to all downloads.
+ item->AddObserver(this);
+ DCHECK(client_);
+ DriverEntry entry = CreateDriverEntry(item);
+ client_->OnDownloadCreated(entry);
+}
+
+void DownloadDriverImpl::OnManagerInitialized() {
+ DCHECK(client_);
+ DCHECK(download_manager_);
+ client_->OnDriverReady(true);
+}
+
+void DownloadDriverImpl::ManagerGoingDown(content::DownloadManager* manager) {
+ DCHECK_EQ(download_manager_, manager);
+ download_manager_ = nullptr;
+}
+
+} // namespace download
diff --git a/chromium/components/download/content/download_driver_impl.h b/chromium/components/download/content/download_driver_impl.h
new file mode 100644
index 00000000000..c7c5b1ce1b2
--- /dev/null
+++ b/chromium/components/download/content/download_driver_impl.h
@@ -0,0 +1,67 @@
+// Copyright 2017 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_DOWNLOAD_CONTENT_DOWNLOAD_DRIVER_IMPL_H_
+#define COMPONENTS_DOWNLOAD_CONTENT_DOWNLOAD_DRIVER_IMPL_H_
+
+#include <string>
+
+#include "base/files/file_path.h"
+#include "components/download/internal/download_driver.h"
+#include "components/download/public/download_params.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/download_manager.h"
+
+namespace download {
+
+struct DriverEntry;
+
+// Aggregates and handles all interaction between download service and content
+// download logic.
+class DownloadDriverImpl : public DownloadDriver,
+ public content::DownloadManager::Observer,
+ public content::DownloadItem::Observer {
+ public:
+ // Creates a driver entry based on a download item.
+ static DriverEntry CreateDriverEntry(const content::DownloadItem* item);
+
+ // Create the driver. All files downloaded will be saved to |dir|.
+ DownloadDriverImpl(content::DownloadManager* manager,
+ const base::FilePath& dir);
+ ~DownloadDriverImpl() override;
+
+ // DownloadDriver implementation.
+ void Initialize(DownloadDriver::Client* client) override;
+ bool IsReady() const override;
+ void Start(const DownloadParams& params) override;
+ void Cancel(const std::string& guid) override;
+ void Pause(const std::string& guid) override;
+ void Resume(const std::string& guid) override;
+ base::Optional<DriverEntry> Find(const std::string& guid) override;
+
+ private:
+ // content::DownloadItem::Observer implementation.
+ void OnDownloadUpdated(content::DownloadItem* item) override;
+
+ // content::DownloadManager::Observer implementation.
+ void OnDownloadCreated(content::DownloadManager* manager,
+ content::DownloadItem* item) override;
+ void OnManagerInitialized() override;
+ void ManagerGoingDown(content::DownloadManager* manager) override;
+
+ // Low level download handle.
+ content::DownloadManager* download_manager_;
+
+ // Target directory of download files.
+ base::FilePath file_dir_;
+
+ // The client that receives updates from low level download logic.
+ DownloadDriver::Client* client_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadDriverImpl);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_CONTENT_DOWNLOAD_DRIVER_IMPL_H_
diff --git a/chromium/components/download/content/download_driver_impl_unittest.cc b/chromium/components/download/content/download_driver_impl_unittest.cc
new file mode 100644
index 00000000000..c53b490fac4
--- /dev/null
+++ b/chromium/components/download/content/download_driver_impl_unittest.cc
@@ -0,0 +1,129 @@
+// Copyright 2017 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/download/content/download_driver_impl.h"
+
+#include <memory>
+#include <string>
+
+#include "base/memory/ptr_util.h"
+#include "content/public/test/fake_download_item.h"
+#include "content/public/test/mock_download_manager.h"
+#include "net/http/http_response_headers.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::NiceMock;
+using testing::Return;
+
+namespace download {
+
+namespace {
+
+const char kFakeGuid[] = "fake_guid";
+
+// Matcher to compare driver entries. Not all the memeber fields are compared.
+// Currently no comparison in non test code, so no operator== override for
+// driver entry.
+MATCHER_P(DriverEntryEuqual, entry, "") {
+ return entry.guid == arg.guid && entry.state == arg.state &&
+ entry.bytes_downloaded == arg.bytes_downloaded;
+}
+
+} // namespace
+
+class MockDriverClient : public DownloadDriver::Client {
+ public:
+ MOCK_METHOD1(OnDriverReady, void(bool));
+ MOCK_METHOD1(OnDownloadCreated, void(const DriverEntry&));
+ MOCK_METHOD2(OnDownloadFailed, void(const DriverEntry&, int));
+ MOCK_METHOD2(OnDownloadSucceeded,
+ void(const DriverEntry&, const base::FilePath&));
+ MOCK_METHOD1(OnDownloadUpdated, void(const DriverEntry&));
+};
+
+class DownloadDriverImplTest : public testing::Test {
+ public:
+ DownloadDriverImplTest() = default;
+ ~DownloadDriverImplTest() override = default;
+
+ void SetUp() override {
+ driver_ =
+ base::MakeUnique<DownloadDriverImpl>(&mock_manager_, base::FilePath());
+ }
+
+ // TODO(xingliu): implements test download manager for embedders to test.
+ NiceMock<content::MockDownloadManager> mock_manager_;
+ MockDriverClient mock_client_;
+ std::unique_ptr<DownloadDriverImpl> driver_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DownloadDriverImplTest);
+};
+
+// Ensure the download manager can be initialized after the download driver.
+TEST_F(DownloadDriverImplTest, ManagerLateInitialization) {
+ EXPECT_CALL(mock_manager_, IsManagerInitialized())
+ .Times(1)
+ .WillOnce(Return(false));
+ driver_->Initialize(&mock_client_);
+
+ EXPECT_CALL(mock_client_, OnDriverReady(true));
+ static_cast<content::DownloadManager::Observer*>(driver_.get())
+ ->OnManagerInitialized();
+}
+
+// Ensures download updates from download items are propagated correctly.
+TEST_F(DownloadDriverImplTest, DownloadItemUpdateEvents) {
+ using DownloadState = content::DownloadItem::DownloadState;
+ using DownloadInterruptReason = content::DownloadInterruptReason;
+
+ EXPECT_CALL(mock_manager_, IsManagerInitialized())
+ .Times(1)
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_client_, OnDriverReady(true)).Times(1);
+ driver_->Initialize(&mock_client_);
+
+ content::FakeDownloadItem fake_item;
+ fake_item.SetState(DownloadState::IN_PROGRESS);
+ fake_item.SetGuid(kFakeGuid);
+ fake_item.SetReceivedBytes(0);
+ fake_item.SetTotalBytes(1024);
+ DriverEntry entry = DownloadDriverImpl::CreateDriverEntry(&fake_item);
+
+ EXPECT_CALL(mock_client_, OnDownloadUpdated(DriverEntryEuqual(entry)))
+ .Times(1)
+ .RetiresOnSaturation();
+ static_cast<content::DownloadItem::Observer*>(driver_.get())
+ ->OnDownloadUpdated(&fake_item);
+
+ // Nothing happens for cancelled state.
+ fake_item.SetState(DownloadState::CANCELLED);
+ static_cast<content::DownloadItem::Observer*>(driver_.get())
+ ->OnDownloadUpdated(&fake_item);
+
+ fake_item.SetReceivedBytes(1024);
+ fake_item.SetState(DownloadState::COMPLETE);
+ entry = DownloadDriverImpl::CreateDriverEntry(&fake_item);
+ EXPECT_CALL(mock_client_, OnDownloadSucceeded(DriverEntryEuqual(entry), _))
+ .Times(1)
+ .RetiresOnSaturation();
+ static_cast<content::DownloadItem::Observer*>(driver_.get())
+ ->OnDownloadUpdated(&fake_item);
+
+ fake_item.SetState(DownloadState::INTERRUPTED);
+ fake_item.SetLastReason(
+ DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT);
+ entry = DownloadDriverImpl::CreateDriverEntry(&fake_item);
+ int reason = static_cast<int>(
+ DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT);
+ EXPECT_CALL(mock_client_, OnDownloadFailed(DriverEntryEuqual(entry), reason))
+ .Times(1)
+ .RetiresOnSaturation();
+ static_cast<content::DownloadItem::Observer*>(driver_.get())
+ ->OnDownloadUpdated(&fake_item);
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/BUILD.gn b/chromium/components/download/internal/BUILD.gn
new file mode 100644
index 00000000000..d1e1e43b885
--- /dev/null
+++ b/chromium/components/download/internal/BUILD.gn
@@ -0,0 +1,65 @@
+# Copyright 2017 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.
+
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+static_library("internal") {
+ visibility = [
+ ":*",
+ "//components/download",
+ "//components/download/content",
+ "//components/download/internal/test:test_support",
+ ]
+
+ sources = [
+ "config.cc",
+ "config.h",
+ "download_driver.h",
+ "download_service_impl.cc",
+ "download_service_impl.h",
+ "driver_entry.cc",
+ "driver_entry.h",
+ "entry.cc",
+ "entry.h",
+ "model.h",
+ "model_impl.cc",
+ "model_impl.h",
+ "noop_store.cc",
+ "noop_store.h",
+ "scheduler/battery_listener.cc",
+ "scheduler/battery_listener.h",
+ "scheduler/network_listener.cc",
+ "scheduler/network_listener.h",
+ "store.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/download/public",
+ "//net",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+
+ visibility = [ "//components/download:unit_tests" ]
+
+ sources = [
+ "model_impl_unittest.cc",
+ "scheduler/battery_listener_unittest.cc",
+ "scheduler/network_listener_unittest.cc",
+ ]
+
+ deps = [
+ ":internal",
+ "//base/test:test_support",
+ "//components/download/internal/test:test_support",
+ "//testing/gmock",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/download/internal/DEPS b/chromium/components/download/internal/DEPS
new file mode 100644
index 00000000000..4ca86d9b1fe
--- /dev/null
+++ b/chromium/components/download/internal/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "-components/download/content",
+ "-content",
+ "+base",
+ "+net",
+]
diff --git a/chromium/components/download/internal/config.cc b/chromium/components/download/internal/config.cc
new file mode 100644
index 00000000000..564da91b881
--- /dev/null
+++ b/chromium/components/download/internal/config.cc
@@ -0,0 +1,70 @@
+// Copyright 2017 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/download/internal/config.h"
+
+#include <string>
+
+#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_number_conversions.h"
+#include "components/download/public/features.h"
+
+namespace download {
+
+namespace {
+
+// Default value for max concurrent downloads configuration.
+const int kDefaultMaxConcurrentDownloads = 4;
+
+// Default value for maximum running downloads of the download service.
+const int kDefaultMaxRunningDownloads = 1;
+
+// Default value for maximum scheduled downloads.
+const int kDefaultMaxScheduledDownloads = 15;
+
+// Default value for maximum retry count.
+const int kDefaultMaxRetryCount = 5;
+
+// Default value for file keep alive time in minutes, keep the file alive for
+// 12 hours by default.
+const int kDefaultFileKeepAliveTimeMinutes = 12 * 60;
+
+// Helper routine to get Finch experiment parameter. If no Finch seed was found,
+// use the |default_value|. The |name| should match an experiment
+// parameter in Finch server configuration.
+int GetFinchConfigInt(const std::string& name, int default_value) {
+ std::string finch_value =
+ base::GetFieldTrialParamValueByFeature(kDownloadServiceFeature, name);
+ int result;
+ return base::StringToInt(finch_value, &result) ? result : default_value;
+}
+
+} // namespace
+
+// static
+std::unique_ptr<Configuration> Configuration::CreateFromFinch() {
+ std::unique_ptr<Configuration> config(new Configuration());
+ config->max_concurrent_downloads = GetFinchConfigInt(
+ kMaxConcurrentDownloadsConfig, kDefaultMaxConcurrentDownloads);
+ config->max_running_downloads = GetFinchConfigInt(
+ kMaxRunningDownloadsConfig, kDefaultMaxRunningDownloads);
+ config->max_scheduled_downloads = GetFinchConfigInt(
+ kMaxScheduledDownloadsConfig, kDefaultMaxScheduledDownloads);
+ config->max_retry_count =
+ GetFinchConfigInt(kMaxRetryCountConfig, kDefaultMaxRetryCount);
+ config->file_keep_alive_time = base::TimeDelta::FromMinutes(GetFinchConfigInt(
+ kFileKeepAliveTimeMinutesConfig, kDefaultFileKeepAliveTimeMinutes));
+ return config;
+}
+
+Configuration::Configuration()
+ : max_concurrent_downloads(kDefaultMaxConcurrentDownloads),
+ max_running_downloads(kDefaultMaxRunningDownloads),
+ max_scheduled_downloads(kDefaultMaxScheduledDownloads),
+ max_retry_count(kDefaultMaxRetryCount),
+ file_keep_alive_time(
+ base::TimeDelta::FromMinutes(kDefaultFileKeepAliveTimeMinutes)) {}
+
+} // namespace download
diff --git a/chromium/components/download/internal/config.h b/chromium/components/download/internal/config.h
new file mode 100644
index 00000000000..c5b3b0d44d3
--- /dev/null
+++ b/chromium/components/download/internal/config.h
@@ -0,0 +1,65 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_CONFIG_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_CONFIG_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+
+namespace download {
+
+// Configuration name for max concurrent downloads.
+constexpr char kMaxConcurrentDownloadsConfig[] = "max_concurrent_downloads";
+
+// Configuration name for maximum running downloads.
+constexpr char kMaxRunningDownloadsConfig[] = "max_running_downloads";
+
+// Configuration name for maximum scheduled downloads.
+constexpr char kMaxScheduledDownloadsConfig[] = "max_scheduled_downloads";
+
+// Configuration name for maximum retry count.
+constexpr char kMaxRetryCountConfig[] = "max_retry_count";
+
+// Configuration name for file keep alive time.
+constexpr char kFileKeepAliveTimeMinutesConfig[] = "file_keep_alive_time";
+
+// Download service configuration.
+//
+// Loaded based on experiment parameters from the server. Use default values if
+// no server configuration was detected.
+struct Configuration {
+ public:
+ // Create the configuration.
+ static std::unique_ptr<Configuration> CreateFromFinch();
+ Configuration();
+
+ // The maximum number of downloads the DownloadService can have currently in
+ // Active or Paused states.
+ int max_concurrent_downloads;
+
+ // The maximum number of downloads the DownloadService can have currently in
+ // only Active state.
+ int max_running_downloads;
+
+ // The maximum number of downloads that are scheduled but not yet in Active
+ // state, for each client using the download service.
+ int max_scheduled_downloads;
+
+ // The maximum number of retries before the download is aborted.
+ int max_retry_count;
+
+ // The time that the download service will keep the files around before
+ // deleting them if the client hasn't handle the files.
+ base::TimeDelta file_keep_alive_time;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Configuration);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_CONFIG_H_
diff --git a/chromium/components/download/internal/download_driver.h b/chromium/components/download/internal/download_driver.h
new file mode 100644
index 00000000000..88247d18d5d
--- /dev/null
+++ b/chromium/components/download/internal/download_driver.h
@@ -0,0 +1,76 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_DOWNLOAD_DRIVER_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_DOWNLOAD_DRIVER_H_
+
+#include <string>
+
+#include "base/optional.h"
+#include "components/download/internal/driver_entry.h"
+
+namespace base {
+class FilePath;
+} // namespace base
+
+namespace download {
+
+struct DownloadParams;
+
+// The interface that includes all the operations to interact with low level
+// download library functionalities.
+class DownloadDriver {
+ public:
+ // The client to receive updates from content download library.
+ // The update events for all downloads will pass through, so it's the
+ // client's responsibility to filter the events it needs to handle.
+ class Client {
+ public:
+ // Called when the low level download library is ready. |success| is true
+ // when the low level download library is ready.
+ virtual void OnDriverReady(bool success) = 0;
+
+ // Called when any download is created.
+ virtual void OnDownloadCreated(const DriverEntry& download) = 0;
+
+ // Called when any download is failed. |reason| is propagated from low level
+ // download library.
+ virtual void OnDownloadFailed(const DriverEntry& download, int reason) = 0;
+
+ // Called when any download is successfully completed.
+ virtual void OnDownloadSucceeded(const DriverEntry& download,
+ const base::FilePath& path) = 0;
+
+ // Called when any download is updated.
+ virtual void OnDownloadUpdated(const DriverEntry& download) = 0;
+ };
+
+ // Initialize the driver to receive download updates.
+ virtual void Initialize(Client* client) = 0;
+
+ // Returns if the driver is ready. Returns false when the driver is not
+ // initialized by the client, or low level download library has been shut
+ // down.
+ virtual bool IsReady() const = 0;
+
+ // Starts a new download.
+ virtual void Start(const DownloadParams& params) = 0;
+
+ // Cancels an existing download, all data associated with this download should
+ // be removed.
+ virtual void Cancel(const std::string& guid) = 0;
+
+ // Pauses the download.
+ virtual void Pause(const std::string& guid) = 0;
+
+ // Resumes the download
+ virtual void Resume(const std::string& guid) = 0;
+
+ // Find a download record from low level download library.
+ virtual base::Optional<DriverEntry> Find(const std::string& guid) = 0;
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_DOWNLOAD_DRIVER_H_
diff --git a/chromium/components/download/internal/download_service_impl.cc b/chromium/components/download/internal/download_service_impl.cc
new file mode 100644
index 00000000000..44610a9a208
--- /dev/null
+++ b/chromium/components/download/internal/download_service_impl.cc
@@ -0,0 +1,30 @@
+// Copyright 2017 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/download/internal/download_service_impl.h"
+
+namespace download {
+
+// static
+DownloadService* DownloadService::Create(
+ const base::FilePath& storage_dir,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner) {
+ return new DownloadServiceImpl(Configuration::CreateFromFinch());
+}
+
+DownloadServiceImpl::DownloadServiceImpl(std::unique_ptr<Configuration> config)
+ : config_(std::move(config)) {}
+
+DownloadServiceImpl::~DownloadServiceImpl() = default;
+
+void DownloadServiceImpl::StartDownload(const DownloadParams& download_params) {
+}
+void DownloadServiceImpl::PauseDownload(const std::string& guid) {}
+void DownloadServiceImpl::ResumeDownload(const std::string& guid) {}
+void DownloadServiceImpl::CancelDownload(const std::string& guid) {}
+void DownloadServiceImpl::ChangeDownloadCriteria(
+ const std::string& guid,
+ const SchedulingParams& params) {}
+
+} // namespace download
diff --git a/chromium/components/download/internal/download_service_impl.h b/chromium/components/download/internal/download_service_impl.h
new file mode 100644
index 00000000000..319aea1976b
--- /dev/null
+++ b/chromium/components/download/internal/download_service_impl.h
@@ -0,0 +1,42 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_DOWNLOAD_SERVICE_IMPL_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_DOWNLOAD_SERVICE_IMPL_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "components/download/internal/config.h"
+#include "components/download/public/download_service.h"
+
+namespace download {
+
+struct DownloadParams;
+struct SchedulingParams;
+
+// The internal implementation of the DownloadService.
+class DownloadServiceImpl : public DownloadService {
+ public:
+ DownloadServiceImpl(std::unique_ptr<Configuration> config);
+ ~DownloadServiceImpl() override;
+
+ // DownloadService implementation.
+ void StartDownload(const DownloadParams& download_params) override;
+ void PauseDownload(const std::string& guid) override;
+ void ResumeDownload(const std::string& guid) override;
+ void CancelDownload(const std::string& guid) override;
+ void ChangeDownloadCriteria(const std::string& guid,
+ const SchedulingParams& params) override;
+
+ private:
+ std::unique_ptr<Configuration> config_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadServiceImpl);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_DOWNLOAD_SERVICE_IMPL_H_
diff --git a/chromium/components/download/internal/driver_entry.cc b/chromium/components/download/internal/driver_entry.cc
new file mode 100644
index 00000000000..88ab03df240
--- /dev/null
+++ b/chromium/components/download/internal/driver_entry.cc
@@ -0,0 +1,21 @@
+// Copyright 2017 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/download/internal/driver_entry.h"
+
+#include "net/http/http_response_headers.h"
+
+namespace download {
+
+DriverEntry::DriverEntry()
+ : state(State::UNKNOWN),
+ paused(false),
+ bytes_downloaded(0u),
+ expected_total_size(0u) {}
+
+DriverEntry::DriverEntry(const DriverEntry& other) = default;
+
+DriverEntry::~DriverEntry() = default;
+
+} // namespace download
diff --git a/chromium/components/download/internal/driver_entry.h b/chromium/components/download/internal/driver_entry.h
new file mode 100644
index 00000000000..a21a4312c9e
--- /dev/null
+++ b/chromium/components/download/internal/driver_entry.h
@@ -0,0 +1,61 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_DRIVER_ENTRY_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_DRIVER_ENTRY_H_
+
+#include <string>
+
+#include "base/memory/ref_counted.h"
+
+namespace net {
+class HttpResponseHeaders;
+} // namespace net
+
+namespace content {
+class DownloadItem;
+} // namespace content
+
+namespace download {
+
+// A snapshot of the states of a download. It's preferred to use the data on the
+// fly and query new ones from download driver, instead of caching the states.
+struct DriverEntry {
+ // States of the download. Mostly maps to
+ // content::DownloadItem::DownloadState.
+ enum class State {
+ IN_PROGRESS = 0,
+ COMPLETE = 1,
+ CANCELLED = 2,
+ INTERRUPTED = 3,
+ UNKNOWN = 4, /* Not created from a download item object. */
+ };
+
+ DriverEntry();
+ DriverEntry(const DriverEntry& other);
+ ~DriverEntry();
+
+ // The unique identifier of the download.
+ std::string guid;
+
+ // The current state of the download.
+ State state;
+
+ // If the download is paused.
+ bool paused;
+
+ // The number of bytes downloaded.
+ uint64_t bytes_downloaded;
+
+ // The expected total size of the download, set to 0 if the Content-Length
+ // http header is not presented.
+ uint64_t expected_total_size;
+
+ // The response headers for the most recent download request.
+ scoped_refptr<const net::HttpResponseHeaders> response_headers;
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_DRIVER_ENTRY_H_
diff --git a/chromium/components/download/internal/entry.cc b/chromium/components/download/internal/entry.cc
new file mode 100644
index 00000000000..56d819c39d8
--- /dev/null
+++ b/chromium/components/download/internal/entry.cc
@@ -0,0 +1,13 @@
+// Copyright 2017 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/download/internal/entry.h"
+
+namespace download {
+
+Entry::Entry() = default;
+Entry::Entry(const Entry& other) = default;
+Entry::~Entry() = default;
+
+} // namespace download
diff --git a/chromium/components/download/internal/entry.h b/chromium/components/download/internal/entry.h
new file mode 100644
index 00000000000..9ba0c427527
--- /dev/null
+++ b/chromium/components/download/internal/entry.h
@@ -0,0 +1,68 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_ENTRY_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_ENTRY_H_
+
+#include "components/download/public/client.h"
+#include "components/download/public/clients.h"
+#include "components/download/public/download_params.h"
+
+namespace download {
+
+// An entry in the Model that represents a scheduled download.
+struct Entry {
+ public:
+ enum class State {
+ // A newly added download. The Entry is not guaranteed to be persisted in
+ // the model yet.
+ NEW = 0,
+
+ // The download has been persisted and is available to start, pending
+ // scheduler criteria.
+ AVAILABLE = 1,
+
+ // The download is active. The DownloadDriver is aware of it and it is
+ // either being downloaded or suspended by the scheduler due to device
+ // characteristics or throttling.
+ ACTIVE = 2,
+
+ // The download has been paused by the owning Client. The download will not
+ // be run until it is resumed by the Client.
+ PAUSED = 3,
+
+ // The download is 'complete' by some definition of that term (could have
+ // failed, could have succeeded, etc.). It is ready to have UMA logs saved.
+ COMPLETE = 4,
+
+ // The download is finished. We are leaving this entry around to make sure
+ // the files on disk are cleaned up.
+ WATCHDOG = 5,
+ };
+
+ Entry();
+ Entry(const Entry& other);
+ ~Entry();
+
+ // The feature that is requesting this download.
+ DownloadClient client = DownloadClient::INVALID;
+
+ // A unique GUID that represents this download. See | base::GenerateGUID()|.
+ std::string guid;
+
+ // The parameters that determine under what device conditions this download
+ // will occur.
+ SchedulingParams scheduling_params;
+
+ // The parameters that define the actual download request to make.
+ RequestParams request_params;
+
+ // The state of the download to help the scheduler and loggers make the right
+ // decisions about the download object.
+ State state = State::NEW;
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_ENTRY_H_
diff --git a/chromium/components/download/internal/model.h b/chromium/components/download/internal/model.h
new file mode 100644
index 00000000000..ce5de88e450
--- /dev/null
+++ b/chromium/components/download/internal/model.h
@@ -0,0 +1,98 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_MODEL_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_MODEL_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "components/download/public/clients.h"
+
+namespace download {
+
+struct Entry;
+class Store;
+
+// The model that contains a runtime representation of Entry entries. Any
+// updates to the model will be persisted to a backing |Store| as necessary.
+class Model {
+ public:
+ // The Client which is responsible for handling all relevant messages from the
+ // model.
+ class Client {
+ public:
+ virtual ~Client() = default;
+
+ // Called asynchronously in response to a Model::Initialize call. If
+ // |success| is |false|, initialization of the Model and/or the underlying
+ // Store failed. Initialization of the Model is complete after this
+ // callback. If |success| is true it can be accessed now.
+ virtual void OnInitialized(bool success) = 0;
+
+ // Called asynchronously in response to a Model::Destroy call. If |success|
+ // is |false|, destruction of the Model and/or the underlying Store failed.
+ // Destruction of the Model is effectively complete after this callback.
+ virtual void OnDestroyed(bool success) = 0;
+
+ // Called when an Entry addition is complete. |success| determines whether
+ // or not the entry has been successfully persisted to the Store.
+ virtual void OnItemAdded(bool success,
+ DownloadClient client,
+ const std::string& guid) = 0;
+
+ // Called when an Entry update is complete. |success| determines whether or
+ // not the update has been successfully persisted to the Store.
+ virtual void OnItemUpdated(bool success,
+ DownloadClient client,
+ const std::string& guid) = 0;
+
+ // Called when an Entry removal is complete. |success| determines whether
+ // or not the entry has been successfully removed from the Store.
+ virtual void OnItemRemoved(bool success,
+ DownloadClient client,
+ const std::string& guid) = 0;
+ };
+
+ using EntryList = std::vector<Entry*>;
+
+ virtual ~Model() = default;
+
+ // Initializes the Model. Client::OnInitialized() will be called in response.
+ // The Model can be used after that call.
+ virtual void Initialize() = 0;
+
+ // Destroys the Model. Client::OnDestroyed() will be called in response.
+ virtual void Destroy() = 0;
+
+ // Adds |entry| to this Model and attempts to write |entry| to the Store.
+ // Client::OnItemAdded() will be called in response asynchronously.
+ virtual void Add(const Entry& entry) = 0;
+
+ // Updates |entry| in this Model and attempts to write |entry| to the Store.
+ // Client::OnItemUpdated() will be called in response asynchronously.
+ virtual void Update(const Entry& entry) = 0;
+
+ // Removes the Entry specified by |guid| from this Model and attempts to
+ // remove that entry from the Store. Client::OnItemRemoved() will be called
+ // in response asynchronously.
+ virtual void Remove(const std::string& guid) = 0;
+
+ // Retrieves an Entry identified by |guid| or |nullptr| if no entry exists.
+ // IMPORTANT NOTE: The result of this method should be used immediately and
+ // NOT stored. The underlying data may get updated or removed by any other
+ // modifications to this model.
+ virtual Entry* Get(const std::string& guid) = 0;
+
+ // Returns a temporary list of Entry objects that this Model stores.
+ // IMPORTANT NOTE: Like Get(), the result of this method should be used
+ // immediately and NOT stored. The underlying data may get updated or removed
+ // by any other modifications to this model.
+ virtual EntryList PeekEntries() = 0;
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_MODEL_H_
diff --git a/chromium/components/download/internal/model_impl.cc b/chromium/components/download/internal/model_impl.cc
new file mode 100644
index 00000000000..f061b5de07d
--- /dev/null
+++ b/chromium/components/download/internal/model_impl.cc
@@ -0,0 +1,130 @@
+// Copyright 2017 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/download/internal/model_impl.h"
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "components/download/internal/entry.h"
+
+namespace download {
+
+ModelImpl::ModelImpl(Client* client, std::unique_ptr<Store> store)
+ : client_(client), store_(std::move(store)), weak_ptr_factory_(this) {
+ DCHECK(client_);
+ DCHECK(store_);
+}
+
+ModelImpl::~ModelImpl() = default;
+
+void ModelImpl::Initialize() {
+ DCHECK(!store_->IsInitialized());
+ store_->Initialize(base::Bind(&ModelImpl::OnInitializedFinished,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ModelImpl::Destroy() {
+ store_->Destroy(base::Bind(&ModelImpl::OnDestroyFinished,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ModelImpl::Add(const Entry& entry) {
+ DCHECK(store_->IsInitialized());
+ DCHECK(entries_.find(entry.guid) == entries_.end());
+
+ entries_.emplace(entry.guid, base::MakeUnique<Entry>(entry));
+
+ store_->Update(entry, base::Bind(&ModelImpl::OnAddFinished,
+ weak_ptr_factory_.GetWeakPtr(), entry.client,
+ entry.guid));
+}
+
+void ModelImpl::Update(const Entry& entry) {
+ DCHECK(store_->IsInitialized());
+ DCHECK(entries_.find(entry.guid) != entries_.end());
+
+ entries_[entry.guid] = base::MakeUnique<Entry>(entry);
+ store_->Update(entry, base::Bind(&ModelImpl::OnUpdateFinished,
+ weak_ptr_factory_.GetWeakPtr(), entry.client,
+ entry.guid));
+}
+
+void ModelImpl::Remove(const std::string& guid) {
+ DCHECK(store_->IsInitialized());
+
+ const auto& it = entries_.find(guid);
+ DCHECK(it != entries_.end());
+
+ DownloadClient client = it->second->client;
+ entries_.erase(it);
+ store_->Remove(guid,
+ base::Bind(&ModelImpl::OnRemoveFinished,
+ weak_ptr_factory_.GetWeakPtr(), client, guid));
+}
+
+Entry* ModelImpl::Get(const std::string& guid) {
+ const auto& it = entries_.find(guid);
+ return it == entries_.end() ? nullptr : it->second.get();
+}
+
+Model::EntryList ModelImpl::PeekEntries() {
+ EntryList entries;
+ for (const auto& it : entries_)
+ entries.push_back(it.second.get());
+
+ return entries;
+}
+
+void ModelImpl::OnInitializedFinished(
+ bool success,
+ std::unique_ptr<std::vector<Entry>> entries) {
+ if (!success) {
+ client_->OnInitialized(false);
+ return;
+ }
+
+ for (const auto& entry : *entries)
+ entries_.emplace(entry.guid, base::MakeUnique<Entry>(entry));
+
+ client_->OnInitialized(true);
+}
+
+void ModelImpl::OnDestroyFinished(bool success) {
+ store_.reset();
+ entries_.clear();
+ client_->OnDestroyed(success);
+}
+
+void ModelImpl::OnAddFinished(DownloadClient client,
+ const std::string& guid,
+ bool success) {
+ // Don't notify the Client if the entry was already removed.
+ if (entries_.find(guid) == entries_.end())
+ return;
+
+ // Remove the entry from the map if the add failed.
+ if (!success)
+ entries_.erase(guid);
+
+ client_->OnItemAdded(success, client, guid);
+}
+
+void ModelImpl::OnUpdateFinished(DownloadClient client,
+ const std::string& guid,
+ bool success) {
+ // Don't notify the Client if the entry was already removed.
+ if (entries_.find(guid) == entries_.end())
+ return;
+
+ client_->OnItemUpdated(success, client, guid);
+}
+
+void ModelImpl::OnRemoveFinished(DownloadClient client,
+ const std::string& guid,
+ bool success) {
+ DCHECK(entries_.find(guid) == entries_.end());
+ client_->OnItemRemoved(success, client, guid);
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/model_impl.h b/chromium/components/download/internal/model_impl.h
new file mode 100644
index 00000000000..8c785019566
--- /dev/null
+++ b/chromium/components/download/internal/model_impl.h
@@ -0,0 +1,73 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_MODEL_IMPL_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_MODEL_IMPL_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/download/internal/model.h"
+#include "components/download/internal/store.h"
+#include "components/download/public/clients.h"
+
+namespace download {
+
+struct Entry;
+
+// The internal implementation of Model.
+class ModelImpl : public Model {
+ public:
+ ModelImpl(Client* client, std::unique_ptr<Store> store);
+ ~ModelImpl() override;
+
+ // Model implementation.
+ void Initialize() override;
+ void Destroy() override;
+ void Add(const Entry& entry) override;
+ void Update(const Entry& entry) override;
+ void Remove(const std::string& guid) override;
+ Entry* Get(const std::string& guid) override;
+ EntryList PeekEntries() override;
+
+ private:
+ using OwnedEntryMap = std::map<std::string, std::unique_ptr<Entry>>;
+
+ void OnInitializedFinished(bool success,
+ std::unique_ptr<std::vector<Entry>> entries);
+ void OnDestroyFinished(bool success);
+ void OnAddFinished(DownloadClient client,
+ const std::string& guid,
+ bool success);
+ void OnUpdateFinished(DownloadClient client,
+ const std::string& guid,
+ bool success);
+ void OnRemoveFinished(DownloadClient client,
+ const std::string& guid,
+ bool success);
+
+ // The external Model::Client reference that will receive all interesting
+ // Model notifications.
+ Client* const client_;
+
+ // The backing Store that is responsible for saving and loading the
+ // persisted entries.
+ std::unique_ptr<Store> store_;
+
+ // A map of [guid] -> [std::unique_ptr<Entry>]. Effectively the cache of the
+ // entries saved in Store.
+ OwnedEntryMap entries_;
+
+ base::WeakPtrFactory<ModelImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ModelImpl);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_MODEL_IMPL_H_
diff --git a/chromium/components/download/internal/model_impl_unittest.cc b/chromium/components/download/internal/model_impl_unittest.cc
new file mode 100644
index 00000000000..19a78391702
--- /dev/null
+++ b/chromium/components/download/internal/model_impl_unittest.cc
@@ -0,0 +1,274 @@
+// Copyright 2017 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/download/internal/model_impl.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "base/bind.h"
+#include "base/guid.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "components/download/internal/entry.h"
+#include "components/download/internal/test/entry_utils.h"
+#include "components/download/internal/test/mock_model_client.h"
+#include "components/download/internal/test/test_store.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::InSequence;
+using ::testing::Return;
+using ::testing::_;
+
+namespace download {
+
+namespace {
+
+class DownloadServiceModelImplTest : public testing::Test {
+ public:
+ DownloadServiceModelImplTest() : store_(nullptr) {}
+
+ ~DownloadServiceModelImplTest() override = default;
+
+ void SetUp() override {
+ auto store = base::MakeUnique<test::TestStore>();
+ store_ = store.get();
+ model_ = base::MakeUnique<ModelImpl>(&client_, std::move(store));
+ }
+
+ protected:
+ test::MockModelClient client_;
+ test::TestStore* store_;
+ std::unique_ptr<ModelImpl> model_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DownloadServiceModelImplTest);
+};
+
+} // namespace
+
+TEST_F(DownloadServiceModelImplTest, SuccessfulLifecycle) {
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+ EXPECT_CALL(client_, OnDestroyed(true)).Times(1);
+
+ model_->Initialize();
+ EXPECT_TRUE(store_->init_called());
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
+
+ model_->Destroy();
+ EXPECT_TRUE(store_->destroy_called());
+ store_->TriggerDestroy(true);
+}
+
+TEST_F(DownloadServiceModelImplTest, SuccessfulInitWithEntries) {
+ Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+ Entry entry2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+ std::vector<Entry> entries = {entry1, entry2};
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+
+ model_->Initialize();
+ EXPECT_TRUE(store_->init_called());
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
+
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry1, model_->Get(entry1.guid)));
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid)));
+}
+
+TEST_F(DownloadServiceModelImplTest, BadInit) {
+ EXPECT_CALL(client_, OnInitialized(false)).Times(1);
+
+ model_->Initialize();
+ EXPECT_TRUE(store_->init_called());
+ store_->TriggerInit(false, base::MakeUnique<std::vector<Entry>>());
+}
+
+TEST_F(DownloadServiceModelImplTest, BadDestroy) {
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+ EXPECT_CALL(client_, OnDestroyed(false)).Times(1);
+
+ model_->Initialize();
+ EXPECT_TRUE(store_->init_called());
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
+
+ model_->Destroy();
+ EXPECT_TRUE(store_->destroy_called());
+ store_->TriggerDestroy(false);
+}
+
+TEST_F(DownloadServiceModelImplTest, Add) {
+ Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+ Entry entry2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+ EXPECT_CALL(client_, OnItemAdded(true, entry1.client, entry1.guid)).Times(1);
+ EXPECT_CALL(client_, OnItemAdded(false, entry2.client, entry2.guid)).Times(1);
+
+ model_->Initialize();
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
+
+ model_->Add(entry1);
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry1, model_->Get(entry1.guid)));
+ EXPECT_TRUE(
+ test::SuperficialEntryCompare(&entry1, store_->LastUpdatedEntry()));
+ store_->TriggerUpdate(true);
+
+ model_->Add(entry2);
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid)));
+ EXPECT_TRUE(
+ test::SuperficialEntryCompare(&entry2, store_->LastUpdatedEntry()));
+
+ store_->TriggerUpdate(false);
+ EXPECT_EQ(nullptr, model_->Get(entry2.guid));
+}
+
+TEST_F(DownloadServiceModelImplTest, Update) {
+ Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+
+ Entry entry2(entry1);
+ entry2.state = Entry::State::AVAILABLE;
+
+ Entry entry3(entry1);
+ entry3.state = Entry::State::ACTIVE;
+
+ std::vector<Entry> entries = {entry1};
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+ EXPECT_CALL(client_, OnItemUpdated(true, entry1.client, entry1.guid))
+ .Times(1);
+ EXPECT_CALL(client_, OnItemUpdated(false, entry1.client, entry1.guid))
+ .Times(1);
+
+ model_->Initialize();
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
+
+ model_->Update(entry2);
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid)));
+ EXPECT_TRUE(
+ test::SuperficialEntryCompare(&entry2, store_->LastUpdatedEntry()));
+ store_->TriggerUpdate(true);
+
+ model_->Update(entry3);
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry3, model_->Get(entry3.guid)));
+ EXPECT_TRUE(
+ test::SuperficialEntryCompare(&entry3, store_->LastUpdatedEntry()));
+
+ store_->TriggerUpdate(false);
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry3, model_->Get(entry3.guid)));
+}
+
+TEST_F(DownloadServiceModelImplTest, Remove) {
+ Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+ Entry entry2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+ std::vector<Entry> entries = {entry1, entry2};
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+ EXPECT_CALL(client_, OnItemRemoved(true, entry1.client, entry1.guid))
+ .Times(1);
+ EXPECT_CALL(client_, OnItemRemoved(false, entry2.client, entry2.guid))
+ .Times(1);
+
+ model_->Initialize();
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
+
+ model_->Remove(entry1.guid);
+ EXPECT_EQ(entry1.guid, store_->LastRemovedEntry());
+ EXPECT_EQ(nullptr, model_->Get(entry1.guid));
+ store_->TriggerRemove(true);
+
+ model_->Remove(entry2.guid);
+ EXPECT_EQ(entry2.guid, store_->LastRemovedEntry());
+ EXPECT_EQ(nullptr, model_->Get(entry2.guid));
+ store_->TriggerRemove(false);
+}
+
+TEST_F(DownloadServiceModelImplTest, Get) {
+ Entry entry = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+
+ std::vector<Entry> entries = {entry};
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+
+ model_->Initialize();
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
+
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry, model_->Get(entry.guid)));
+ EXPECT_EQ(nullptr, model_->Get(base::GenerateGUID()));
+}
+
+TEST_F(DownloadServiceModelImplTest, PeekEntries) {
+ Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+ Entry entry2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+ std::vector<Entry> entries = {entry1, entry2};
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+
+ model_->Initialize();
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
+
+ std::vector<Entry*> expected_peek = {&entry1, &entry2};
+
+ EXPECT_TRUE(
+ test::SuperficialEntryListCompare(expected_peek, model_->PeekEntries()));
+}
+
+TEST_F(DownloadServiceModelImplTest, TestRemoveAfterAdd) {
+ Entry entry = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+ EXPECT_CALL(client_, OnItemAdded(_, _, _)).Times(0);
+ EXPECT_CALL(client_, OnItemRemoved(true, entry.client, entry.guid)).Times(1);
+
+ model_->Initialize();
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
+
+ model_->Add(entry);
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry, model_->Get(entry.guid)));
+
+ model_->Remove(entry.guid);
+ EXPECT_EQ(nullptr, model_->Get(entry.guid));
+
+ store_->TriggerUpdate(true);
+ store_->TriggerRemove(true);
+}
+
+TEST_F(DownloadServiceModelImplTest, TestRemoveAfterUpdate) {
+ Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
+
+ Entry entry2(entry1);
+ entry2.state = Entry::State::AVAILABLE;
+
+ std::vector<Entry> entries = {entry1};
+
+ InSequence sequence;
+ EXPECT_CALL(client_, OnInitialized(true)).Times(1);
+ EXPECT_CALL(client_, OnItemUpdated(_, _, _)).Times(0);
+ EXPECT_CALL(client_, OnItemRemoved(true, entry1.client, entry1.guid))
+ .Times(1);
+
+ model_->Initialize();
+ store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry1, model_->Get(entry1.guid)));
+
+ model_->Update(entry2);
+ EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid)));
+
+ model_->Remove(entry2.guid);
+ EXPECT_EQ(nullptr, model_->Get(entry2.guid));
+
+ store_->TriggerUpdate(true);
+ store_->TriggerRemove(true);
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/noop_store.cc b/chromium/components/download/internal/noop_store.cc
new file mode 100644
index 00000000000..42785cbc5b1
--- /dev/null
+++ b/chromium/components/download/internal/noop_store.cc
@@ -0,0 +1,53 @@
+// Copyright 2017 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/download/internal/noop_store.h"
+
+#include "base/bind.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/download/internal/entry.h"
+
+namespace download {
+
+NoopStore::NoopStore() : initialized_(false), weak_ptr_factory_(this) {}
+
+NoopStore::~NoopStore() = default;
+
+bool NoopStore::IsInitialized() {
+ return initialized_;
+}
+
+void NoopStore::Initialize(InitCallback callback) {
+ DCHECK(!IsInitialized());
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&NoopStore::OnInitFinished, weak_ptr_factory_.GetWeakPtr(),
+ std::move(callback)));
+}
+
+void NoopStore::Destroy(StoreCallback callback) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), true /** success */));
+}
+
+void NoopStore::Update(const Entry& entry, StoreCallback callback) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), true /** success */));
+}
+
+void NoopStore::Remove(const std::string& guid, StoreCallback callback) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), true /** success */));
+}
+
+void NoopStore::OnInitFinished(InitCallback callback) {
+ initialized_ = true;
+
+ std::unique_ptr<std::vector<Entry>> entries =
+ base::MakeUnique<std::vector<Entry>>();
+ std::move(callback).Run(true /** success */, std::move(entries));
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/noop_store.h b/chromium/components/download/internal/noop_store.h
new file mode 100644
index 00000000000..4bad9ed2e13
--- /dev/null
+++ b/chromium/components/download/internal/noop_store.h
@@ -0,0 +1,46 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_NOOP_STORE_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_NOOP_STORE_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/download/internal/store.h"
+
+namespace download {
+
+struct Entry;
+
+// A Store implementation that doesn't do anything but honors the interface
+// requirements.
+// TODO(dtrainor, shaktisahu): Remove this if it's no longer necessary after the
+// real Store implementation is added.
+class NoopStore : public Store {
+ public:
+ NoopStore();
+ ~NoopStore() override;
+
+ // Store implementation.
+ bool IsInitialized() override;
+ void Initialize(InitCallback callback) override;
+ void Destroy(StoreCallback callback) override;
+ void Update(const Entry& entry, StoreCallback callback) override;
+ void Remove(const std::string& guid, StoreCallback callback) override;
+
+ private:
+ void OnInitFinished(InitCallback callback);
+
+ // Whether or not this Store is 'initialized.' Just gets set to |true| once
+ // Initialize() is called.
+ bool initialized_;
+
+ base::WeakPtrFactory<NoopStore> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NoopStore);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_NOOP_STORE_H_
diff --git a/chromium/components/download/internal/scheduler/battery_listener.cc b/chromium/components/download/internal/scheduler/battery_listener.cc
new file mode 100644
index 00000000000..b015ca15ffd
--- /dev/null
+++ b/chromium/components/download/internal/scheduler/battery_listener.cc
@@ -0,0 +1,58 @@
+// Copyright 2017 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/download/internal/scheduler/battery_listener.h"
+
+#include "base/power_monitor/power_monitor.h"
+
+namespace download {
+
+// Helper function that converts the battery status to battery requirement.
+SchedulingParams::BatteryRequirements ToBatteryRequirement(
+ bool on_battery_power) {
+ return on_battery_power
+ ? SchedulingParams::BatteryRequirements::BATTERY_INSENSITIVE
+ : SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE;
+}
+
+BatteryListener::BatteryListener() = default;
+
+BatteryListener::~BatteryListener() {
+ Stop();
+}
+
+SchedulingParams::BatteryRequirements BatteryListener::CurrentBatteryStatus()
+ const {
+ return ToBatteryRequirement(base::PowerMonitor::Get()->IsOnBatteryPower());
+}
+
+void BatteryListener::Start() {
+ base::PowerMonitor* monitor = base::PowerMonitor::Get();
+ DCHECK(monitor);
+ monitor->AddObserver(this);
+}
+
+void BatteryListener::Stop() {
+ base::PowerMonitor::Get()->RemoveObserver(this);
+}
+
+void BatteryListener::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void BatteryListener::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void BatteryListener::OnPowerStateChange(bool on_battery_power) {
+ NotifyBatteryChange(ToBatteryRequirement(on_battery_power));
+}
+
+void BatteryListener::NotifyBatteryChange(
+ SchedulingParams::BatteryRequirements current_battery) {
+ for (auto& observer : observers_)
+ observer.OnBatteryChange(current_battery);
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/scheduler/battery_listener.h b/chromium/components/download/internal/scheduler/battery_listener.h
new file mode 100644
index 00000000000..2ddc6109b55
--- /dev/null
+++ b/chromium/components/download/internal/scheduler/battery_listener.h
@@ -0,0 +1,59 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_SCHEDULER_BATTERY_LISTENER_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_SCHEDULER_BATTERY_LISTENER_H_
+
+#include <memory>
+
+#include "base/observer_list.h"
+#include "base/power_monitor/power_observer.h"
+#include "components/download/public/download_params.h"
+
+namespace download {
+
+// Listen to battery charing state changes and notify observers in download
+// service.
+// TODO(xingliu): Converts to device service when it's fully done.
+class BatteryListener : public base::PowerObserver {
+ public:
+ class Observer {
+ public:
+ // Called when certain battery requirements are meet.
+ virtual void OnBatteryChange(
+ SchedulingParams::BatteryRequirements battery_status) = 0;
+ };
+
+ BatteryListener();
+ ~BatteryListener() override;
+
+ // Retrieves the current minimum battery requirement.
+ SchedulingParams::BatteryRequirements CurrentBatteryStatus() const;
+
+ // Start to listen to battery change.
+ void Start();
+
+ // Stop to listen to battery change.
+ void Stop();
+
+ // Adds/Removes observers.
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ private:
+ // base::PowerObserver implementation.
+ void OnPowerStateChange(bool on_battery_power) override;
+
+ // Notifies |observers_| about battery requirement change.
+ void NotifyBatteryChange(SchedulingParams::BatteryRequirements);
+
+ // Observers to monitor battery change in download service.
+ base::ObserverList<Observer> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(BatteryListener);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_SCHEDULER_BATTERY_LISTENER_H_
diff --git a/chromium/components/download/internal/scheduler/battery_listener_unittest.cc b/chromium/components/download/internal/scheduler/battery_listener_unittest.cc
new file mode 100644
index 00000000000..3ddacffbf10
--- /dev/null
+++ b/chromium/components/download/internal/scheduler/battery_listener_unittest.cc
@@ -0,0 +1,74 @@
+// Copyright 2017 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/download/internal/scheduler/battery_listener.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/test/power_monitor_test_base.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace download {
+namespace {
+
+using BatteryRequirements = SchedulingParams::BatteryRequirements;
+
+class MockObserver : public BatteryListener::Observer {
+ public:
+ MOCK_METHOD1(OnBatteryChange, void(SchedulingParams::BatteryRequirements));
+};
+
+class BatteryListenerTest : public testing::Test {
+ public:
+ BatteryListenerTest() {}
+ ~BatteryListenerTest() override = default;
+
+ void CallBatteryChange(bool on_battery_power) {
+ DCHECK(listener_);
+ static_cast<base::PowerObserver*>(listener_.get())
+ ->OnPowerStateChange(on_battery_power);
+ }
+
+ void SetUp() override {
+ power_monitor_ = base::MakeUnique<base::PowerMonitor>(
+ base::MakeUnique<base::PowerMonitorTestSource>());
+
+ observer_ = base::MakeUnique<MockObserver>();
+ listener_ = base::MakeUnique<BatteryListener>();
+ listener_->AddObserver(observer_.get());
+ }
+
+ void TearDown() override {
+ listener_.reset();
+ observer_.reset();
+ }
+
+ std::unique_ptr<BatteryListener> listener_;
+ std::unique_ptr<MockObserver> observer_;
+
+ base::MessageLoop message_loop_;
+ std::unique_ptr<base::PowerMonitor> power_monitor_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BatteryListenerTest);
+};
+
+// Ensures observer methods are corrected called.
+TEST_F(BatteryListenerTest, NotifyObservers) {
+ listener_->Start();
+ EXPECT_CALL(*observer_.get(),
+ OnBatteryChange(BatteryRequirements::BATTERY_INSENSITIVE))
+ .RetiresOnSaturation();
+ CallBatteryChange(true);
+
+ EXPECT_CALL(*observer_.get(),
+ OnBatteryChange(BatteryRequirements::BATTERY_SENSITIVE))
+ .RetiresOnSaturation();
+ CallBatteryChange(false);
+ listener_->Stop();
+};
+
+} // namespace
+} // namespace download
diff --git a/chromium/components/download/internal/scheduler/network_listener.cc b/chromium/components/download/internal/scheduler/network_listener.cc
new file mode 100644
index 00000000000..d09d52773ee
--- /dev/null
+++ b/chromium/components/download/internal/scheduler/network_listener.cc
@@ -0,0 +1,84 @@
+// Copyright 2017 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/download/internal/scheduler/network_listener.h"
+
+namespace download {
+
+namespace {
+
+// Converts a ConnectionType to NetworkListener::NetworkStatus.
+NetworkListener::NetworkStatus ToNetworkStatus(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ switch (type) {
+ case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
+ case net::NetworkChangeNotifier::CONNECTION_WIFI:
+ return NetworkListener::NetworkStatus::UNMETERED;
+ case net::NetworkChangeNotifier::CONNECTION_2G:
+ case net::NetworkChangeNotifier::CONNECTION_3G:
+ case net::NetworkChangeNotifier::CONNECTION_4G:
+ return NetworkListener::NetworkStatus::METERED;
+ case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
+ case net::NetworkChangeNotifier::CONNECTION_NONE:
+ case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
+ return NetworkListener::NetworkStatus::DISCONNECTED;
+ }
+ NOTREACHED();
+ return NetworkListener::NetworkStatus::DISCONNECTED;
+}
+
+} // namespace
+
+NetworkListener::NetworkListener()
+ : status_(NetworkStatus::DISCONNECTED), listening_(false) {}
+
+NetworkListener::~NetworkListener() {
+ Stop();
+}
+
+NetworkListener::NetworkStatus NetworkListener::CurrentNetworkStatus() const {
+ return ToNetworkStatus(net::NetworkChangeNotifier::GetConnectionType());
+}
+
+void NetworkListener::Start() {
+ if (listening_)
+ return;
+
+ net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
+ status_ = ToNetworkStatus(net::NetworkChangeNotifier::GetConnectionType());
+ listening_ = true;
+}
+
+void NetworkListener::Stop() {
+ if (!listening_)
+ return;
+
+ net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
+ status_ = ToNetworkStatus(net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
+ listening_ = false;
+}
+
+void NetworkListener::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void NetworkListener::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void NetworkListener::OnConnectionTypeChanged(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ NetworkStatus new_status = ToNetworkStatus(type);
+ if (status_ != new_status) {
+ status_ = new_status;
+ NotifyNetworkChange(status_);
+ }
+}
+
+void NetworkListener::NotifyNetworkChange(NetworkStatus network_status) {
+ for (auto& observer : observers_)
+ observer.OnNetworkChange(network_status);
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/scheduler/network_listener.h b/chromium/components/download/internal/scheduler/network_listener.h
new file mode 100644
index 00000000000..6b05ffb16b0
--- /dev/null
+++ b/chromium/components/download/internal/scheduler/network_listener.h
@@ -0,0 +1,66 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_SCHEDULER_NETWORK_LISTENER_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_SCHEDULER_NETWORK_LISTENER_H_
+
+#include "net/base/network_change_notifier.h"
+
+namespace download {
+
+// Listens to network status change and notifies observers in download service.
+class NetworkListener
+ : public net::NetworkChangeNotifier::ConnectionTypeObserver {
+ public:
+ // NetworkStatus should mostly one to one map to
+ // SchedulingParams::NetworkRequirements. Has coarser granularity than
+ // network connection type.
+ enum class NetworkStatus {
+ DISCONNECTED = 0,
+ UNMETERED = 1, // WIFI or Ethernet.
+ METERED = 2, // Mobile networks.
+ };
+
+ class Observer {
+ public:
+ // Called when network status is changed.
+ virtual void OnNetworkChange(NetworkStatus network_status) = 0;
+ };
+
+ NetworkListener();
+ ~NetworkListener() override;
+
+ // Returns the current network status for download scheduling.
+ NetworkStatus CurrentNetworkStatus() const;
+
+ // Starts/stops to listen network change events.
+ void Start();
+ void Stop();
+
+ // Adds/Removes observers.
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ private:
+ // net::NetworkChangeNotifier implementation.
+ void OnConnectionTypeChanged(
+ net::NetworkChangeNotifier::ConnectionType type) override;
+
+ // Notifies |observers_| about network status change. See |NetworkStatus|.
+ void NotifyNetworkChange(NetworkStatus network_status);
+
+ // The current network status.
+ NetworkStatus status_;
+
+ // If we are actively listening to network change events.
+ bool listening_;
+
+ base::ObserverList<Observer> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkListener);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_SCHEDULER_NETWORK_LISTENER_H_
diff --git a/chromium/components/download/internal/scheduler/network_listener_unittest.cc b/chromium/components/download/internal/scheduler/network_listener_unittest.cc
new file mode 100644
index 00000000000..4b8165dcef1
--- /dev/null
+++ b/chromium/components/download/internal/scheduler/network_listener_unittest.cc
@@ -0,0 +1,100 @@
+// Copyright 2017 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/download/internal/scheduler/network_listener.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ConnectionTypeObserver =
+ net::NetworkChangeNotifier::ConnectionTypeObserver;
+using ConnectionType = net::NetworkChangeNotifier::ConnectionType;
+
+namespace download {
+namespace {
+
+// NetworkChangeNotifier that can change network type in tests.
+class TestNetworkChangeNotifier : public net::NetworkChangeNotifier {
+ public:
+ TestNetworkChangeNotifier()
+ : net::NetworkChangeNotifier(),
+ conn_type_(ConnectionType::CONNECTION_UNKNOWN) {}
+
+ // net::NetworkChangeNotifier implementation.
+ ConnectionType GetCurrentConnectionType() const override {
+ return conn_type_;
+ }
+
+ // Change the network type.
+ void ChangeNetworkType(ConnectionType type) {
+ conn_type_ = type;
+ net::NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests(
+ type);
+ base::RunLoop().RunUntilIdle();
+ }
+
+ private:
+ ConnectionType conn_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifier);
+};
+
+class MockObserver : public NetworkListener::Observer {
+ public:
+ MOCK_METHOD1(OnNetworkChange, void(NetworkListener::NetworkStatus));
+};
+
+class NetworkListenerTest : public testing::Test {
+ public:
+ // Simulates a network change call.
+ void ChangeNetworkType(ConnectionType type) {
+ test_network_notifier_.ChangeNetworkType(type);
+ }
+
+ protected:
+ NetworkListener network_listener_;
+ MockObserver mock_observer_;
+
+ // Needed for network change notifier.
+ base::MessageLoop message_loop_;
+ TestNetworkChangeNotifier test_network_notifier_;
+};
+
+TEST_F(NetworkListenerTest, NotifyObserverNetworkChange) {
+ network_listener_.Start();
+ network_listener_.AddObserver(&mock_observer_);
+
+ // Initial states check.
+ EXPECT_EQ(NetworkListener::NetworkStatus::DISCONNECTED,
+ network_listener_.CurrentNetworkStatus());
+
+ // Network switch between mobile networks, the observer should be notified
+ // only once.
+ EXPECT_CALL(mock_observer_,
+ OnNetworkChange(NetworkListener::NetworkStatus::METERED))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ ChangeNetworkType(ConnectionType::CONNECTION_4G);
+ ChangeNetworkType(ConnectionType::CONNECTION_3G);
+ ChangeNetworkType(ConnectionType::CONNECTION_2G);
+ EXPECT_EQ(NetworkListener::NetworkStatus::METERED,
+ network_listener_.CurrentNetworkStatus());
+
+ // Network is switched between wifi and ethernet, the observer should be
+ // notified only once.
+ EXPECT_CALL(mock_observer_,
+ OnNetworkChange(NetworkListener::NetworkStatus::UNMETERED))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ ChangeNetworkType(ConnectionType::CONNECTION_WIFI);
+ ChangeNetworkType(ConnectionType::CONNECTION_ETHERNET);
+}
+
+} // namespace
+} // namespace download
diff --git a/chromium/components/download/internal/store.h b/chromium/components/download/internal/store.h
new file mode 100644
index 00000000000..04a39bffcc6
--- /dev/null
+++ b/chromium/components/download/internal/store.h
@@ -0,0 +1,54 @@
+// Copyright 2017 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_DOWNLOAD_INTERNAL_STORE_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_STORE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+
+namespace download {
+
+struct Entry;
+
+// A backing storage interface responsible for persisting Entry objects.
+class Store {
+ public:
+ using InitCallback =
+ base::OnceCallback<void(bool success,
+ std::unique_ptr<std::vector<Entry>> entries)>;
+ using StoreCallback = base::OnceCallback<void(bool success)>;
+
+ virtual ~Store() = default;
+
+ // Returns whether or not this Store is initialized and can be interracted
+ // with.
+ virtual bool IsInitialized() = 0;
+
+ // Initializes this Store and asynchronously returns whether or not that
+ // initialization was successful as well as a list of Entry objects from the
+ // Store.
+ virtual void Initialize(InitCallback callback) = 0;
+
+ // Destroyes the store and asynchronously returns whether or not that
+ // destruction was successful.
+ virtual void Destroy(StoreCallback callback) = 0;
+
+ // Adds or updates |entry| in this Store asynchronously and returns whether or
+ // not that was successful.
+ virtual void Update(const Entry& entry, StoreCallback callback) = 0;
+
+ // Removes the Entry associated with |guid| from this Store asynchronously and
+ // returns whether or not that was successful.
+ virtual void Remove(const std::string& guid, StoreCallback callback) = 0;
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_STORE_H_
diff --git a/chromium/components/download/internal/test/BUILD.gn b/chromium/components/download/internal/test/BUILD.gn
new file mode 100644
index 00000000000..87032dcfd7d
--- /dev/null
+++ b/chromium/components/download/internal/test/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2017 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.
+
+source_set("test_support") {
+ visibility = [ "//components/download/internal:unit_tests" ]
+
+ testonly = true
+
+ sources = [
+ "entry_utils.cc",
+ "entry_utils.h",
+ "mock_model_client.cc",
+ "mock_model_client.h",
+ "test_download_driver.cc",
+ "test_download_driver.h",
+ "test_store.cc",
+ "test_store.h",
+ ]
+
+ public_deps = [
+ "//base",
+ "//components/download/internal",
+ "//components/download/public",
+ "//testing/gmock",
+ ]
+}
diff --git a/chromium/components/download/public/BUILD.gn b/chromium/components/download/public/BUILD.gn
new file mode 100644
index 00000000000..5f013fd35b6
--- /dev/null
+++ b/chromium/components/download/public/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2017 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.
+
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+source_set("public") {
+ sources = [
+ "client.h",
+ "clients.h",
+ "download_params.cc",
+ "download_params.h",
+ "download_service.h",
+ "features.cc",
+ "features.h",
+ ]
+
+ deps = [
+ "//components/keyed_service/core",
+ ]
+
+ public_deps = [
+ "//base",
+ "//net",
+ "//url",
+ ]
+}
diff --git a/chromium/components/download/public/DEPS b/chromium/components/download/public/DEPS
new file mode 100644
index 00000000000..5171a85caa1
--- /dev/null
+++ b/chromium/components/download/public/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+ "-content",
+ "+base",
+ "+components/keyed_service",
+ "+net/http",
+ "+url",
+]
diff --git a/chromium/components/download/public/client.h b/chromium/components/download/public/client.h
new file mode 100644
index 00000000000..28264e7b97c
--- /dev/null
+++ b/chromium/components/download/public/client.h
@@ -0,0 +1,81 @@
+// Copyright 2017 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_DOWNLOAD_PUBLIC_CLIENT_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_CLIENT_H_
+
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "net/http/http_response_headers.h"
+#include "url/gurl.h"
+
+namespace download {
+
+// The Client interface required by any feature that wants to start a download
+// through the DownloadService. Should be registered immediately at startup
+// when the DownloadService is created (see the factory).
+class Client {
+ public:
+ // Used by OnDownloadStarted to determine whether or not the DownloadService
+ // should continue downloading the file or abort the attempt.
+ enum class ShouldDownload {
+ CONTINUE,
+ ABORT,
+ };
+
+ virtual ~Client() = default;
+
+ // Called when the DownloadService is initialized and ready to be interacted
+ // with. |outstanding_download_guids| is a list of all downloads the
+ // DownloadService is aware of that are associated with this Client.
+ virtual void OnServiceInitialized(
+ const std::vector<std::string>& outstanding_download_guids) = 0;
+
+ // Return whether or not the download should be aborted (potentially in
+ // response to |headers|). The download will be downloading at the time this
+ // call is made.
+ virtual ShouldDownload OnDownloadStarted(
+ const std::string& guid,
+ const std::vector<GURL>& url_chain,
+ const scoped_refptr<const net::HttpResponseHeaders>& headers) = 0;
+
+ // Will be called when there is an update to the current progress state of the
+ // underlying download. Note that |bytes_downloaded| may go backwards if the
+ // download had to be started over from the beginning due to an interruption.
+ // This will be called frequently if the download is actively downloading,
+ // with byte updates coming in as they are processed by the internal download
+ // driver.
+ virtual void OnDownloadUpdated(const std::string& guid,
+ uint64_t bytes_downloaded) = 0;
+
+ // TODO(dtrainor): Expose a useful error message with the failed download.
+ virtual void OnDownloadFailed(const std::string& guid) = 0;
+
+ // Called when the download was not completed before the
+ // DownloadParams::cancel_after timeout.
+ virtual void OnDownloadTimedOut(const std::string& guid) = 0;
+
+ // Called when the download has been aborted after reaching a treshold where
+ // we decide it is not worth attempting to start again. This could be either
+ // due to a specific number of failed retry attempts or a specific number of
+ // wasted bytes due to the download restarting.
+ virtual void OnDownloadAborted(const std::string& guid) = 0;
+
+ // Called when a download has been successfully completed. After this call
+ // the download entry will be purged from the database. The file will be
+ // automatically removed if it is not renamed or deleted after a window of
+ // time (12 hours, but finch configurable). The timeout is meant to be a
+ // failsafe to ensure that we clean up properly.
+ // TODO(dtrainor): Investigate alternate output formats.
+ // TODO(dtrainor): Point to finch configurable timeout when it is added.
+ virtual void OnDownloadSucceeded(const std::string& guid,
+ const base::FilePath& path,
+ uint64_t size) = 0;
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_PUBLIC_CLIENT_H_
diff --git a/chromium/components/download/public/clients.h b/chromium/components/download/public/clients.h
new file mode 100644
index 00000000000..a464d212017
--- /dev/null
+++ b/chromium/components/download/public/clients.h
@@ -0,0 +1,33 @@
+// Copyright 2017 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_DOWNLOAD_PUBLIC_CLIENTS_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_CLIENTS_H_
+
+namespace download {
+
+// A list of all clients that are able to make download requests through the
+// DownloadService.
+// To add a new client, update the metric DownloadService.DownloadClients in
+// histograms.xml and make sure to keep this list in sync. Additions should be
+// treated as APPEND ONLY to make sure to keep both UMA metric semantics correct
+// but also to make sure the underlying database properly associates each
+// download with the right client.
+enum class DownloadClient {
+ // Represents an uninitialized DownloadClient variable.
+ INVALID = 0,
+
+ // Test client values. Meant to be used by the testing framework and not
+ // production code. Callers will be unable to access the DownloadService with
+ // these test APIs.
+ TEST = 1,
+
+ OFFLINE_PAGE_PREFETCH = 2,
+
+ BOUNDARY = 3,
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_PUBLIC_CLIENTS_H_
diff --git a/chromium/components/download/public/download_params.cc b/chromium/components/download/public/download_params.cc
new file mode 100644
index 00000000000..f24d467b763
--- /dev/null
+++ b/chromium/components/download/public/download_params.cc
@@ -0,0 +1,24 @@
+// Copyright 2017 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/download/public/download_params.h"
+
+#include "components/download/public/clients.h"
+
+namespace download {
+
+SchedulingParams::SchedulingParams()
+ : priority(Priority::DEFAULT),
+ network_requirements(NetworkRequirements::NONE),
+ battery_requirements(BatteryRequirements::BATTERY_INSENSITIVE) {}
+
+RequestParams::RequestParams() : method("GET") {}
+
+DownloadParams::DownloadParams() : client(DownloadClient::INVALID) {}
+
+DownloadParams::DownloadParams(const DownloadParams& other) = default;
+
+DownloadParams::~DownloadParams() = default;
+
+} // namespace download
diff --git a/chromium/components/download/public/download_params.h b/chromium/components/download/public/download_params.h
new file mode 100644
index 00000000000..dcf25b41986
--- /dev/null
+++ b/chromium/components/download/public/download_params.h
@@ -0,0 +1,135 @@
+// Copyright 2017 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_DOWNLOAD_PUBLIC_DOWNLOAD_PARAMS_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_DOWNLOAD_PARAMS_H_
+
+#include "base/callback.h"
+#include "base/time/time.h"
+#include "components/download/public/clients.h"
+#include "net/http/http_request_headers.h"
+#include "url/gurl.h"
+
+namespace download {
+
+// The parameters describing when to run a download. This allows the caller to
+// specify restrictions on what impact this download will have on the device
+// (battery, network conditions, priority, etc.).
+struct SchedulingParams {
+ public:
+ enum class NetworkRequirements {
+ // The download can occur under all network conditions.
+ NONE = 0,
+
+ // The download should occur when the network isn't metered. However if the
+ // device does not provide that opportunity over a long period of time, the
+ // DownloadService may start allowing these downloads to run on metered
+ // networks as well.
+ OPTIMISTIC = 1,
+
+ // The download can occur only if the network isn't metered.
+ UNMETERED = 2,
+ };
+
+ enum class BatteryRequirements {
+ // The download can occur under all battery scenarios. Note that the
+ // DownloadService may still not run this download under extremely low
+ // battery conditions.
+ BATTERY_INSENSITIVE = 0,
+
+ // The download can only occur when charging or in optimal battery
+ // conditions.
+ BATTERY_SENSITIVE = 1,
+ };
+
+ enum class Priority {
+ // The lowest priority. Requires that the device is idle or Chrome is
+ // running.
+ LOW = 0,
+
+ // The normal priority. Requires that the device is idle or Chrome is
+ // running.
+ NORMAL = 1,
+
+ // The highest background priority. Does not require the device to be idle.
+ HIGH = 2,
+
+ // The highest priority. This will act (scheduling requirements aside) as a
+ // user-initiated download.
+ UI = 3,
+
+ // The default priority for all tasks unless overridden.
+ DEFAULT = NORMAL,
+ };
+
+ SchedulingParams();
+ SchedulingParams(const SchedulingParams& other) = default;
+ ~SchedulingParams() = default;
+
+ // Cancel the download after this time. Will cancel in-progress downloads.
+ base::Time cancel_time;
+
+ // The suggested priority. Non-UI priorities may not be honored by the
+ // DownloadService based on internal criteria and settings.
+ Priority priority;
+ NetworkRequirements network_requirements;
+ BatteryRequirements battery_requirements;
+};
+
+// The parameters describing how to build the request when starting a download.
+struct RequestParams {
+ public:
+ RequestParams();
+ RequestParams(const RequestParams& other) = default;
+ ~RequestParams() = default;
+
+ GURL url;
+
+ // The request method ("GET" is the default value).
+ std::string method;
+ net::HttpRequestHeaders request_headers;
+};
+
+// The parameters that describe a download request made to the DownloadService.
+// The |client| needs to be properly created and registered for this service for
+// the download to be accepted.
+struct DownloadParams {
+ enum StartResult {
+ // The download is accepted and persisted.
+ ACCEPTED,
+
+ // The DownloadService has too many downloads. Backoff and retry.
+ BACKOFF,
+
+ // Failed to create the download. Invalid input parameters.
+ BAD_PARAMETERS,
+
+ // TODO(dtrainor): Add more error codes.
+ };
+
+ DownloadParams();
+ DownloadParams(const DownloadParams& other);
+ ~DownloadParams();
+
+ // The feature that is requesting this download.
+ DownloadClient client;
+
+ // A unique GUID that represents this download. See |base::GenerateGUID()|.
+ std::string guid;
+
+ // A callback that will be notified if this download has been accepted and
+ // persisted by the DownloadService.
+ base::Callback<void(const DownloadParams&, StartResult)> callback;
+
+ // The parameters that determine under what device conditions this download
+ // will occur.
+ SchedulingParams scheduling_params;
+
+ // The parameters that define the actual download request to make.
+ RequestParams request_params;
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_PUBLIC_DOWNLOAD_PARAMS_H_
diff --git a/chromium/components/download/public/download_service.h b/chromium/components/download/public/download_service.h
new file mode 100644
index 00000000000..f0733de6ff4
--- /dev/null
+++ b/chromium/components/download/public/download_service.h
@@ -0,0 +1,72 @@
+// Copyright 2017 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_DOWNLOAD_PUBLIC_DOWNLOAD_SERVICE_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_DOWNLOAD_SERVICE_H_
+
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace download {
+
+struct DownloadParams;
+struct SchedulingParams;
+
+// A service responsible for helping facilitate the scheduling and downloading
+// of file content from the web. See |DownloadParams| for more details on the
+// types of scheduling that can be achieved and the required input parameters
+// for starting a download. Note that DownloadServices with a valid storage
+// directory will persist the requests across restarts. This means that any
+// feature requesting a download will have to implement a download::Client
+// interface so this class knows who to contact when a download completes after
+// a process restart.
+class DownloadService : public KeyedService {
+ public:
+ // |storage_dir| is a path to where all the local storage will be. This will
+ // hold the internal database as well as any temporary files on disk. If this
+ // is an empty path, the service will not persist any information to disk and
+ // will act as an in-memory only service (this means no auto-retries after
+ // restarts, no files written on completion, etc.).
+ // |background_task_runner| will be used for all disk reads and writes.
+ static DownloadService* Create(
+ const base::FilePath& storage_dir,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner);
+
+ // Sends the download to the service. A callback to
+ // |DownloadParams::callback| will be triggered once the download has been
+ // persisted and saved in the service
+ virtual void StartDownload(const DownloadParams& download_params) = 0;
+
+ // Allows any feature to pause or resume downloads at will. Paused downloads
+ // will not start or stop based on scheduling criteria. They will be
+ // effectively frozen.
+ virtual void PauseDownload(const std::string& guid) = 0;
+ virtual void ResumeDownload(const std::string& guid) = 0;
+
+ // Cancels a download in this service. The canceled download will be
+ // interrupted if it is running.
+ virtual void CancelDownload(const std::string& guid) = 0;
+
+ // Changes the current scheduling criteria for a download. This is useful if
+ // a user action might constrain or loosen the device state during which this
+ // download can run.
+ virtual void ChangeDownloadCriteria(const std::string& guid,
+ const SchedulingParams& params) = 0;
+
+ protected:
+ DownloadService() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DownloadService);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_PUBLIC_DOWNLOAD_SERVICE_H_
diff --git a/chromium/components/download/public/features.cc b/chromium/components/download/public/features.cc
new file mode 100644
index 00000000000..f254f230c99
--- /dev/null
+++ b/chromium/components/download/public/features.cc
@@ -0,0 +1,12 @@
+// Copyright 2017 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/download/public/features.h"
+
+namespace download {
+
+const base::Feature kDownloadServiceFeature{"DownloadService",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+} // namespace download
diff --git a/chromium/components/download/public/features.h b/chromium/components/download/public/features.h
new file mode 100644
index 00000000000..13117191bc8
--- /dev/null
+++ b/chromium/components/download/public/features.h
@@ -0,0 +1,16 @@
+// Copyright 2017 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_DOWNLOAD_PUBLIC_FEATURES_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace download {
+
+extern const base::Feature kDownloadServiceFeature;
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_PUBLIC_FEATURES_H_
diff --git a/chromium/components/error_page/common/localized_error.cc b/chromium/components/error_page/common/localized_error.cc
index 32cb9e9b40b..580d3d746b0 100644
--- a/chromium/components/error_page/common/localized_error.cc
+++ b/chromium/components/error_page/common/localized_error.cc
@@ -1049,6 +1049,7 @@ void LocalizedError::GetStrings(
if (!is_post && !reload_visible && !show_saved_copy_visible &&
!is_incognito && failed_url.is_valid() &&
failed_url.SchemeIsHTTPOrHTTPS() &&
+ IsSuggested(options.suggestions, SUGGEST_OFFLINE_CHECKS) &&
offline_pages::IsOfflinePagesAsyncDownloadEnabled()) {
std::unique_ptr<base::DictionaryValue> download_button =
base::MakeUnique<base::DictionaryValue>();
diff --git a/chromium/components/exo/BUILD.gn b/chromium/components/exo/BUILD.gn
index 3edaf861812..1b48931fed8 100644
--- a/chromium/components/exo/BUILD.gn
+++ b/chromium/components/exo/BUILD.gn
@@ -9,8 +9,6 @@ source_set("exo") {
sources = [
"buffer.cc",
"buffer.h",
- "compositor_frame_sink.cc",
- "compositor_frame_sink.h",
"compositor_frame_sink_holder.cc",
"compositor_frame_sink_holder.h",
"display.cc",
@@ -56,6 +54,7 @@ source_set("exo") {
"//cc/ipc:interfaces",
"//cc/surfaces",
"//device/gamepad",
+ "//device/gamepad/public/cpp:shared_with_blink",
"//gpu",
"//gpu/command_buffer/client:gles2_interface",
"//skia",
@@ -127,6 +126,7 @@ source_set("unit_tests") {
":test_support",
"//ash",
"//ash/public/cpp:ash_public_cpp",
+ "//ash/test:test_support_without_content",
"//base",
"//base/test:test_support",
"//cc",
diff --git a/chromium/components/exo/buffer.cc b/chromium/components/exo/buffer.cc
index 0588175c463..d2141c9d050 100644
--- a/chromium/components/exo/buffer.cc
+++ b/chromium/components/exo/buffer.cc
@@ -428,10 +428,6 @@ bool Buffer::ProduceTransferableResource(
return false;
}
- // The reference to the CompositorFrameSinkHolder keeps it alive until a
- // release callback is received.
- compositor_frame_sink_holder_ = compositor_frame_sink_holder;
-
resource->id = resource_id;
resource->format = cc::RGBA_8888;
resource->filter = GL_LINEAR;
@@ -462,7 +458,7 @@ bool Buffer::ProduceTransferableResource(
// The contents texture will be released when no longer used by the
// compositor.
- compositor_frame_sink_holder_->SetResourceReleaseCallback(
+ compositor_frame_sink_holder->SetResourceReleaseCallback(
resource_id,
base::Bind(&Buffer::Texture::ReleaseTexImage,
base::Unretained(contents_texture),
@@ -492,7 +488,7 @@ bool Buffer::ProduceTransferableResource(
// The mailbox texture will be released when no longer used by the
// compositor.
- compositor_frame_sink_holder_->SetResourceReleaseCallback(
+ compositor_frame_sink_holder->SetResourceReleaseCallback(
resource_id,
base::Bind(&Buffer::Texture::Release, base::Unretained(texture),
base::Bind(&Buffer::ReleaseTexture, AsWeakPtr(),
diff --git a/chromium/components/exo/buffer.h b/chromium/components/exo/buffer.h
index b97011e99fa..54097d315fb 100644
--- a/chromium/components/exo/buffer.h
+++ b/chromium/components/exo/buffer.h
@@ -124,11 +124,6 @@ class Buffer : public base::SupportsWeakPtr<Buffer> {
// The client release callback.
base::Closure release_callback_;
- // CompositorFrameSinkHolder instance that needs to be kept alive to receive
- // a release callback when the last produced transferable resource is no
- // longer in use.
- scoped_refptr<CompositorFrameSinkHolder> compositor_frame_sink_holder_;
-
// Cancelable release contents callback. This is set when a release callback
// is pending.
base::CancelableClosure release_contents_callback_;
diff --git a/chromium/components/exo/buffer_unittest.cc b/chromium/components/exo/buffer_unittest.cc
index 4f34c960011..9fa73791f3e 100644
--- a/chromium/components/exo/buffer_unittest.cc
+++ b/chromium/components/exo/buffer_unittest.cc
@@ -33,11 +33,8 @@ TEST_F(BufferTest, ReleaseCallback) {
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
std::unique_ptr<Surface> surface(new Surface);
const cc::FrameSinkId arbitrary_frame_sink_id(1, 1);
- scoped_refptr<CompositorFrameSinkHolder> compositor_frame_sink_holder =
- new CompositorFrameSinkHolder(surface.get(), arbitrary_frame_sink_id,
- aura::Env::GetInstance()
- ->context_factory_private()
- ->GetSurfaceManager());
+ CompositorFrameSinkHolder* compositor_frame_sink_holder =
+ surface->compositor_frame_sink_holder();
// Set the release callback.
int release_call_count = 0;
@@ -47,8 +44,8 @@ TEST_F(BufferTest, ReleaseCallback) {
buffer->OnAttach();
cc::TransferableResource resource;
// Produce a transferable resource for the contents of the buffer.
- bool rv = buffer->ProduceTransferableResource(
- compositor_frame_sink_holder.get(), 0, false, true, &resource);
+ bool rv = buffer->ProduceTransferableResource(compositor_frame_sink_holder, 0,
+ false, true, &resource);
ASSERT_TRUE(rv);
// Release buffer.
@@ -74,18 +71,15 @@ TEST_F(BufferTest, IsLost) {
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
const cc::FrameSinkId arbitrary_frame_sink_id(1, 1);
std::unique_ptr<Surface> surface(new Surface);
- scoped_refptr<CompositorFrameSinkHolder> compositor_frame_sink_holder =
- new CompositorFrameSinkHolder(surface.get(), arbitrary_frame_sink_id,
- aura::Env::GetInstance()
- ->context_factory_private()
- ->GetSurfaceManager());
+ CompositorFrameSinkHolder* compositor_frame_sink_holder =
+ surface->compositor_frame_sink_holder();
cc::ResourceId resource_id = 0;
buffer->OnAttach();
// Acquire a texture transferable resource for the contents of the buffer.
cc::TransferableResource resource;
bool rv = buffer->ProduceTransferableResource(
- compositor_frame_sink_holder.get(), resource_id, false, true, &resource);
+ compositor_frame_sink_holder, resource_id, false, true, &resource);
ASSERT_TRUE(rv);
scoped_refptr<cc::ContextProvider> context_provider =
@@ -112,9 +106,8 @@ TEST_F(BufferTest, IsLost) {
// buffer.
++resource_id;
cc::TransferableResource new_resource;
- rv = buffer->ProduceTransferableResource(compositor_frame_sink_holder.get(),
- resource_id, false, false,
- &new_resource);
+ rv = buffer->ProduceTransferableResource(
+ compositor_frame_sink_holder, resource_id, false, false, &new_resource);
ASSERT_TRUE(rv);
buffer->OnDetach();
diff --git a/chromium/components/exo/compositor_frame_sink.cc b/chromium/components/exo/compositor_frame_sink.cc
deleted file mode 100644
index cee2955b41b..00000000000
--- a/chromium/components/exo/compositor_frame_sink.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 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/exo/compositor_frame_sink.h"
-
-#include "base/memory/ptr_util.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_manager.h"
-#include "components/exo/compositor_frame_sink_holder.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace exo {
-
-////////////////////////////////////////////////////////////////////////////////
-// ExoComopositorFrameSink, public:
-
-CompositorFrameSink::CompositorFrameSink(const cc::FrameSinkId& frame_sink_id,
- cc::SurfaceManager* surface_manager,
- CompositorFrameSinkHolder* client)
- : support_(cc::CompositorFrameSinkSupport::Create(
- this,
- surface_manager,
- frame_sink_id,
- false /* is_root */,
- true /* handles_frame_sink_id_invalidation */,
- true /* needs_sync_points */)),
- client_(client) {}
-
-CompositorFrameSink::~CompositorFrameSink() {}
-
-////////////////////////////////////////////////////////////////////////////////
-// cc::mojom::MojoCompositorFrameSink overrides:
-
-void CompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) {
- support_->SetNeedsBeginFrame(needs_begin_frame);
-}
-
-void CompositorFrameSink::SubmitCompositorFrame(
- const cc::LocalSurfaceId& local_surface_id,
- cc::CompositorFrame frame) {
- support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
-}
-
-void CompositorFrameSink::BeginFrameDidNotSwap(
- const cc::BeginFrameAck& begin_frame_ack) {
- support_->BeginFrameDidNotSwap(begin_frame_ack);
-}
-
-void CompositorFrameSink::EvictFrame() {
- support_->EvictFrame();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// cc::CompositorFrameSinkSupportClient overrides:
-
-void CompositorFrameSink::DidReceiveCompositorFrameAck(
- const cc::ReturnedResourceArray& resources) {
- client_->DidReceiveCompositorFrameAck(resources);
-}
-
-void CompositorFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) {
- client_->OnBeginFrame(args);
-}
-
-void CompositorFrameSink::ReclaimResources(
- const cc::ReturnedResourceArray& resources) {
- client_->ReclaimResources(resources);
-}
-
-} // namespace exo
diff --git a/chromium/components/exo/compositor_frame_sink.h b/chromium/components/exo/compositor_frame_sink.h
deleted file mode 100644
index 7da2b6b2a38..00000000000
--- a/chromium/components/exo/compositor_frame_sink.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 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_EXO_EXO_COMPOSITOR_FRAME_SINK_H_
-#define COMPONENTS_EXO_EXO_COMPOSITOR_FRAME_SINK_H_
-
-#include "cc/ipc/compositor_frame.mojom.h"
-#include "cc/ipc/mojo_compositor_frame_sink.mojom.h"
-#include "cc/resources/transferable_resource.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace exo {
-
-class CompositorFrameSinkHolder;
-
-class CompositorFrameSink : public cc::CompositorFrameSinkSupportClient,
- public cc::mojom::MojoCompositorFrameSink {
- public:
- CompositorFrameSink(const cc::FrameSinkId& frame_sink_id,
- cc::SurfaceManager* surface_manager,
- CompositorFrameSinkHolder* client);
-
- ~CompositorFrameSink() override;
-
- // Overridden from cc::mojom::MojoCompositorFrameSink:
- void SetNeedsBeginFrame(bool needs_begin_frame) override;
- void SubmitCompositorFrame(const cc::LocalSurfaceId& local_surface_id,
- cc::CompositorFrame frame) override;
- void BeginFrameDidNotSwap(const cc::BeginFrameAck& begin_frame_ack) override;
- void EvictFrame() override;
-
- // Overridden from cc::CompositorFrameSinkSupportClient:
- void DidReceiveCompositorFrameAck(
- const cc::ReturnedResourceArray& resources) override;
- void OnBeginFrame(const cc::BeginFrameArgs& args) override;
- void ReclaimResources(const cc::ReturnedResourceArray& resources) override;
- void WillDrawSurface(const cc::LocalSurfaceId& local_surface_id,
- const gfx::Rect& damage_rect) override {}
-
- private:
- std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
- CompositorFrameSinkHolder* const client_;
-
- DISALLOW_COPY_AND_ASSIGN(CompositorFrameSink);
-};
-
-} // namespace exo
-
-#endif // COMPONENTS_EXO_EXO_COMPOSITOR_FRAME_SINK_H_
diff --git a/chromium/components/exo/compositor_frame_sink_holder.cc b/chromium/components/exo/compositor_frame_sink_holder.cc
index b516b842a52..f63c358bce8 100644
--- a/chromium/components/exo/compositor_frame_sink_holder.cc
+++ b/chromium/components/exo/compositor_frame_sink_holder.cc
@@ -4,6 +4,7 @@
#include "components/exo/compositor_frame_sink_holder.h"
+#include "cc/output/compositor_frame_sink.h"
#include "cc/resources/returned_resource.h"
#include "components/exo/surface.h"
@@ -14,15 +15,22 @@ namespace exo {
CompositorFrameSinkHolder::CompositorFrameSinkHolder(
Surface* surface,
- const cc::FrameSinkId& frame_sink_id,
- cc::SurfaceManager* surface_manager)
+ std::unique_ptr<cc::CompositorFrameSink> frame_sink)
: surface_(surface),
- frame_sink_(
- new CompositorFrameSink(frame_sink_id, surface_manager, this)),
- begin_frame_source_(base::MakeUnique<cc::ExternalBeginFrameSource>(this)),
+ frame_sink_(std::move(frame_sink)),
weak_factory_(this) {
surface_->AddSurfaceObserver(this);
- surface_->SetBeginFrameSource(begin_frame_source_.get());
+ frame_sink_->BindToClient(this);
+}
+
+CompositorFrameSinkHolder::~CompositorFrameSinkHolder() {
+ frame_sink_->DetachFromClient();
+ if (surface_)
+ surface_->RemoveSurfaceObserver(this);
+
+ // Release all resources which aren't returned from CompositorFrameSink.
+ for (auto& callback : release_callbacks_)
+ callback.second.Run(gpu::SyncToken(), false);
}
bool CompositorFrameSinkHolder::HasReleaseCallbackForResource(
@@ -38,17 +46,12 @@ void CompositorFrameSinkHolder::SetResourceReleaseCallback(
}
////////////////////////////////////////////////////////////////////////////////
-// cc::mojom::MojoCompositorFrameSinkClient overrides:
+// cc::CompositorFrameSinkClient overrides:
-void CompositorFrameSinkHolder::DidReceiveCompositorFrameAck(
- const cc::ReturnedResourceArray& resources) {
- ReclaimResources(resources);
+void CompositorFrameSinkHolder::SetBeginFrameSource(
+ cc::BeginFrameSource* source) {
if (surface_)
- surface_->DidReceiveCompositorFrameAck();
-}
-
-void CompositorFrameSinkHolder::OnBeginFrame(const cc::BeginFrameArgs& args) {
- begin_frame_source_->OnBeginFrame(args);
+ surface_->SetBeginFrameSource(source);
}
void CompositorFrameSinkHolder::ReclaimResources(
@@ -63,17 +66,9 @@ void CompositorFrameSinkHolder::ReclaimResources(
}
}
-////////////////////////////////////////////////////////////////////////////////
-// cc::ExternalBeginFrameSourceClient overrides:
-
-void CompositorFrameSinkHolder::OnNeedsBeginFrames(bool needs_begin_frames) {
- frame_sink_->SetNeedsBeginFrame(needs_begin_frames);
-}
-
-void CompositorFrameSinkHolder::OnDidFinishFrame(const cc::BeginFrameAck& ack) {
- // If there was damage, the submitted CompositorFrame includes the ack.
- if (!ack.has_damage)
- frame_sink_->BeginFrameDidNotSwap(ack);
+void CompositorFrameSinkHolder::DidReceiveCompositorFrameAck() {
+ if (surface_)
+ surface_->DidReceiveCompositorFrameAck();
}
////////////////////////////////////////////////////////////////////////////////
@@ -84,12 +79,4 @@ void CompositorFrameSinkHolder::OnSurfaceDestroying(Surface* surface) {
surface_ = nullptr;
}
-////////////////////////////////////////////////////////////////////////////////
-// ExoComopositorFrameSink, private:
-
-CompositorFrameSinkHolder::~CompositorFrameSinkHolder() {
- if (surface_)
- surface_->RemoveSurfaceObserver(this);
-}
-
} // namespace exo
diff --git a/chromium/components/exo/compositor_frame_sink_holder.h b/chromium/components/exo/compositor_frame_sink_holder.h
index a469929e4b7..53255618d15 100644
--- a/chromium/components/exo/compositor_frame_sink_holder.h
+++ b/chromium/components/exo/compositor_frame_sink_holder.h
@@ -5,17 +5,16 @@
#ifndef COMPONENTS_EXO_COMPOSITOR_FRAME_SINK_HOLDER_H_
#define COMPONENTS_EXO_COMPOSITOR_FRAME_SINK_HOLDER_H_
-#include <list>
-#include <map>
#include <memory>
-#include "cc/ipc/mojo_compositor_frame_sink.mojom.h"
+#include "base/containers/flat_map.h"
+#include "cc/output/compositor_frame_sink_client.h"
#include "cc/resources/release_callback.h"
-#include "cc/resources/transferable_resource.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "components/exo/compositor_frame_sink.h"
#include "components/exo/surface_observer.h"
-#include "mojo/public/cpp/bindings/binding.h"
+
+namespace cc {
+class CompositorFrameSink;
+}
namespace exo {
class Surface;
@@ -24,51 +23,51 @@ class Surface;
// the contents of Buffers. It's keeped alive by references from
// release_callbacks_. It's destroyed when its owning Surface is destroyed and
// the last outstanding release callback is called.
-class CompositorFrameSinkHolder
- : public base::RefCounted<CompositorFrameSinkHolder>,
- public cc::ExternalBeginFrameSourceClient,
- public cc::mojom::MojoCompositorFrameSinkClient,
- public SurfaceObserver {
+class CompositorFrameSinkHolder : public cc::CompositorFrameSinkClient,
+ public SurfaceObserver {
public:
- CompositorFrameSinkHolder(Surface* surface,
- const cc::FrameSinkId& frame_sink_id,
- cc::SurfaceManager* surface_manager);
+ CompositorFrameSinkHolder(
+ Surface* surface,
+ std::unique_ptr<cc::CompositorFrameSink> frame_sink);
+ ~CompositorFrameSinkHolder() override;
bool HasReleaseCallbackForResource(cc::ResourceId id);
void SetResourceReleaseCallback(cc::ResourceId id,
const cc::ReleaseCallback& callback);
- CompositorFrameSink* GetCompositorFrameSink() { return frame_sink_.get(); }
+ cc::CompositorFrameSink* GetCompositorFrameSink() {
+ return frame_sink_.get();
+ }
base::WeakPtr<CompositorFrameSinkHolder> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
- // Overridden from cc::mojom::MojoCompositorFrameSinkClient:
- void DidReceiveCompositorFrameAck(
- const cc::ReturnedResourceArray& resources) override;
- void OnBeginFrame(const cc::BeginFrameArgs& args) override;
+ // Overridden from cc::CompositorFrameSinkClient:
+ void SetBeginFrameSource(cc::BeginFrameSource* source) override;
void ReclaimResources(const cc::ReturnedResourceArray& resources) override;
-
- // Overridden from cc::ExternalBeginFrameSourceClient:
- void OnNeedsBeginFrames(bool needs_begin_frames) override;
- void OnDidFinishFrame(const cc::BeginFrameAck& ack) override;
+ void SetTreeActivationCallback(const base::Closure& callback) override {}
+ void DidReceiveCompositorFrameAck() override;
+ void DidLoseCompositorFrameSink() override {}
+ void OnDraw(const gfx::Transform& transform,
+ const gfx::Rect& viewport,
+ bool resourceless_software_draw) override {}
+ void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {}
+ void SetExternalTilePriorityConstraints(
+ const gfx::Rect& viewport_rect,
+ const gfx::Transform& transform) override {}
// Overridden from SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override;
private:
- friend class base::RefCounted<CompositorFrameSinkHolder>;
-
- ~CompositorFrameSinkHolder() override;
// A collection of callbacks used to release resources.
- using ResourceReleaseCallbackMap = std::map<int, cc::ReleaseCallback>;
+ using ResourceReleaseCallbackMap = base::flat_map<int, cc::ReleaseCallback>;
ResourceReleaseCallbackMap release_callbacks_;
Surface* surface_;
- std::unique_ptr<CompositorFrameSink> frame_sink_;
- std::unique_ptr<cc::ExternalBeginFrameSource> begin_frame_source_;
+ std::unique_ptr<cc::CompositorFrameSink> frame_sink_;
base::WeakPtrFactory<CompositorFrameSinkHolder> weak_factory_;
diff --git a/chromium/components/exo/gaming_seat.cc b/chromium/components/exo/gaming_seat.cc
index eed466c7bf5..016be145bb9 100644
--- a/chromium/components/exo/gaming_seat.cc
+++ b/chromium/components/exo/gaming_seat.cc
@@ -50,7 +50,7 @@ class GamingSeat::ThreadSafeGamepadChangeFetcher
GamingSeat::ThreadSafeGamepadChangeFetcher> {
public:
using ProcessGamepadChangesCallback =
- base::Callback<void(int index, const blink::WebGamepad)>;
+ base::Callback<void(int index, const device::Gamepad)>;
ThreadSafeGamepadChangeFetcher(
const ProcessGamepadChangesCallback& post_gamepad_changes,
@@ -120,11 +120,11 @@ class GamingSeat::ThreadSafeGamepadChangeFetcher
DCHECK(fetcher_);
- blink::WebGamepads new_state = state_;
+ device::Gamepads new_state = state_;
fetcher_->GetGamepadData(
false /* No hardware changed notification from the system */);
- for (size_t i = 0; i < blink::WebGamepads::kItemsLengthCap; ++i) {
+ for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
device::PadState& pad_state = pad_states_.get()[i];
// After querying the gamepad clear the state if it did not have it's
@@ -171,7 +171,7 @@ class GamingSeat::ThreadSafeGamepadChangeFetcher
std::unique_ptr<device::GamepadDataFetcher> fetcher_;
// The current state of all gamepads.
- blink::WebGamepads state_;
+ device::Gamepads state_;
// True if a poll has been scheduled.
bool has_poll_scheduled_ = false;
@@ -216,7 +216,7 @@ GamingSeat::~GamingSeat() {
gamepad_change_fetcher_->EnablePolling(false);
delegate_->OnGamingSeatDestroying(this);
- for (size_t i = 0; i < blink::WebGamepads::kItemsLengthCap; ++i) {
+ for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
if (gamepad_delegates_[i]) {
gamepad_delegates_[i]->OnRemoved();
}
@@ -249,11 +249,11 @@ void GamingSeat::OnWindowFocused(aura::Window* gained_focus,
// GamingSeat, private:
void GamingSeat::ProcessGamepadChanges(int index,
- const blink::WebGamepad new_pad) {
+ const device::Gamepad new_pad) {
DCHECK(thread_checker_.CalledOnValidThread());
bool send_frame = false;
- blink::WebGamepad& pad_state = pad_state_.items[index];
+ device::Gamepad& pad_state = pad_state_.items[index];
// Update connection state.
GamepadDelegate* delegate = gamepad_delegates_[index];
if (new_pad.connected != pad_state.connected) {
diff --git a/chromium/components/exo/gaming_seat.h b/chromium/components/exo/gaming_seat.h
index d8fcf119a2f..40e44ae3335 100644
--- a/chromium/components/exo/gaming_seat.h
+++ b/chromium/components/exo/gaming_seat.h
@@ -50,7 +50,7 @@ class GamingSeat : public WMHelper::FocusObserver {
class ThreadSafeGamepadChangeFetcher;
// Processes updates of gamepad data and passes changes on to delegate.
- void ProcessGamepadChanges(int index, const blink::WebGamepad new_pad);
+ void ProcessGamepadChanges(int index, const device::Gamepad new_pad);
// Private implementation of methods and resources that are used on the
// polling thread.
@@ -60,10 +60,10 @@ class GamingSeat : public WMHelper::FocusObserver {
GamingSeatDelegate* const delegate_;
// The delegate instances that all other events are dispatched to.
- GamepadDelegate* gamepad_delegates_[blink::WebGamepads::kItemsLengthCap];
+ GamepadDelegate* gamepad_delegates_[device::Gamepads::kItemsLengthCap];
// The current state of the gamepad represented by this instance.
- blink::WebGamepads pad_state_;
+ device::Gamepads pad_state_;
// ThreadChecker for the origin thread.
base::ThreadChecker thread_checker_;
diff --git a/chromium/components/exo/gaming_seat_unittest.cc b/chromium/components/exo/gaming_seat_unittest.cc
index 8b94ca0a5f1..5a7893deb61 100644
--- a/chromium/components/exo/gaming_seat_unittest.cc
+++ b/chromium/components/exo/gaming_seat_unittest.cc
@@ -47,7 +47,7 @@ class GamingSeatTest : public test::ExoTestBase {
GamingSeatTest() {}
std::unique_ptr<device::GamepadDataFetcher> MockDataFetcherFactory() {
- blink::WebGamepads initial_data;
+ device::Gamepads initial_data;
std::unique_ptr<device::MockGamepadDataFetcher> fetcher(
new device::MockGamepadDataFetcher(initial_data));
mock_data_fetcher_ = fetcher.get();
@@ -73,7 +73,7 @@ class GamingSeatTest : public test::ExoTestBase {
polling_task_runner_ = nullptr;
}
- void SetDataAndPostToDelegate(const blink::WebGamepads& new_data) {
+ void SetDataAndPostToDelegate(const device::Gamepads& new_data) {
ASSERT_TRUE(mock_data_fetcher_ != nullptr);
mock_data_fetcher_->SetTestData(new_data);
// Run one polling cycle, which will post a task to the origin task runner.
@@ -132,7 +132,7 @@ TEST_F(GamingSeatTest, ConnectionChange) {
EXPECT_CALL(gamepad_delegate2, OnRemoved()).Times(1);
}
// Gamepad connected.
- blink::WebGamepads gamepad_connected;
+ device::Gamepads gamepad_connected;
gamepad_connected.items[0].connected = true;
gamepad_connected.items[0].timestamp = 1;
SetDataAndPostToDelegate(gamepad_connected);
@@ -152,7 +152,7 @@ TEST_F(GamingSeatTest, ConnectionChange) {
SetDataAndPostToDelegate(gamepad_connected);
// Gamepad disconnected.
- blink::WebGamepads all_disconnected;
+ device::Gamepads all_disconnected;
SetDataAndPostToDelegate(all_disconnected);
DestroyGamingSeat(gaming_seat_delegate);
@@ -182,7 +182,7 @@ TEST_F(GamingSeatTest, OnAxis) {
.WillOnce(testing::Return(&gamepad_delegate0))
.WillOnce(testing::Return(&gamepad_delegate2));
- blink::WebGamepads gamepad_connected;
+ device::Gamepads gamepad_connected;
gamepad_connected.items[0].connected = true;
gamepad_connected.items[0].timestamp = 1;
SetDataAndPostToDelegate(gamepad_connected);
@@ -192,7 +192,7 @@ TEST_F(GamingSeatTest, OnAxis) {
SetDataAndPostToDelegate(gamepad_connected);
// send axis event to 2 and then 0
- blink::WebGamepads axis_moved;
+ device::Gamepads axis_moved;
axis_moved.items[0].connected = true;
axis_moved.items[0].timestamp = 1;
axis_moved.items[2].connected = true;
@@ -241,7 +241,7 @@ TEST_F(GamingSeatTest, OnButton) {
.WillOnce(testing::Return(&gamepad_delegate0))
.WillOnce(testing::Return(&gamepad_delegate2));
- blink::WebGamepads gamepad_connected;
+ device::Gamepads gamepad_connected;
gamepad_connected.items[0].connected = true;
gamepad_connected.items[0].timestamp = 1;
SetDataAndPostToDelegate(gamepad_connected);
@@ -251,7 +251,7 @@ TEST_F(GamingSeatTest, OnButton) {
SetDataAndPostToDelegate(gamepad_connected);
// send axis event to 2 and then 0
- blink::WebGamepads axis_moved;
+ device::Gamepads axis_moved;
axis_moved.items[0].connected = true;
axis_moved.items[0].timestamp = 1;
axis_moved.items[2].connected = true;
diff --git a/chromium/components/exo/notification_surface.cc b/chromium/components/exo/notification_surface.cc
index 2b66eddec42..5f42548ddd9 100644
--- a/chromium/components/exo/notification_surface.cc
+++ b/chromium/components/exo/notification_surface.cc
@@ -77,7 +77,7 @@ NotificationSurface::NotificationSurface(NotificationSurfaceManager* manager,
surface_->SetSurfaceDelegate(this);
surface_->AddSurfaceObserver(this);
- window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
+ window_->SetType(aura::client::WINDOW_TYPE_CONTROL);
window_->SetName("ExoNotificationSurface");
window_->Init(ui::LAYER_NOT_DRAWN);
window_->set_owned_by_parent(false);
diff --git a/chromium/components/exo/pointer.cc b/chromium/components/exo/pointer.cc
index 1cc32a42637..fa05f35e0eb 100644
--- a/chromium/components/exo/pointer.cc
+++ b/chromium/components/exo/pointer.cc
@@ -4,6 +4,8 @@
#include "components/exo/pointer.h"
+#include <utility>
+
#include "ash/public/cpp/shell_window_ids.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
@@ -14,6 +16,7 @@
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
+#include "ui/base/cursor/cursor_util.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/managed_display_info.h"
#include "ui/display/screen.h"
@@ -32,8 +35,14 @@
namespace exo {
namespace {
+// TODO(oshima): Some accessibility features, including large cursors, disable
+// hardware cursors. Ash does not support compositing for custom cursors, so it
+// replaces them with the default cursor. As a result, this scale has no effect
+// for now. See crbug.com/708378.
const float kLargeCursorScale = 2.8f;
+const double kLocatedEventEpsilonSquared = 1.0 / (2000.0 * 2000.0);
+
// Synthesized events typically lack floating point precision so to avoid
// generating mouse event jitter we consider the location of these events
// to be the same as |location| if floored values match.
@@ -41,7 +50,25 @@ bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) {
if (event->flags() & ui::EF_IS_SYNTHESIZED)
return event->location() == gfx::ToFlooredPoint(location);
- return event->location_f() == location;
+ // In general, it is good practice to compare floats using an epsilon.
+ // In particular, the mouse location_f() could differ between the
+ // MOUSE_PRESSED and MOUSE_RELEASED events. At MOUSE_RELEASED, it will have a
+ // targeter() already cached, while at MOUSE_PRESSED, it will have to
+ // calculate it passing through all the hierarchy of windows, and that could
+ // generate rounding error. std::numeric_limits<float>::epsilon() is not big
+ // enough to catch this rounding error.
+ gfx::Vector2dF offset = event->location_f() - location;
+ return offset.LengthSquared() < (2 * kLocatedEventEpsilonSquared);
+}
+
+display::ManagedDisplayInfo GetCaptureDisplayInfo() {
+ display::ManagedDisplayInfo capture_info;
+ for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
+ const auto& info = WMHelper::GetInstance()->GetDisplayInfo(display.id());
+ if (info.device_scale_factor() >= capture_info.device_scale_factor())
+ capture_info = info;
+ }
+ return capture_info;
}
} // namespace
@@ -51,12 +78,15 @@ bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) {
Pointer::Pointer(PointerDelegate* delegate)
: delegate_(delegate),
- cursor_(ui::kCursorNull),
+ cursor_(ui::CursorType::kNull),
+ capture_scale_(GetCaptureDisplayInfo().device_scale_factor()),
+ capture_ratio_(GetCaptureDisplayInfo().GetDensityRatio()),
cursor_capture_source_id_(base::UnguessableToken::Create()),
cursor_capture_weak_ptr_factory_(this) {
auto* helper = WMHelper::GetInstance();
helper->AddPreTargetHandler(this);
helper->AddCursorObserver(this);
+ helper->AddDisplayConfigurationObserver(this);
}
Pointer::~Pointer() {
@@ -68,6 +98,7 @@ Pointer::~Pointer() {
focus_->UnregisterCursorProvider(this);
}
auto* helper = WMHelper::GetInstance();
+ helper->RemoveDisplayConfigurationObserver(this);
helper->RemoveCursorObserver(this);
helper->RemovePreTargetHandler(this);
}
@@ -87,44 +118,27 @@ void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) {
DLOG(ERROR) << "Surface has already been assigned a role";
return;
}
- if (surface_) {
- surface_->window()->SetTransform(gfx::Transform());
- if (surface_->window()->parent())
- surface_->window()->parent()->RemoveChild(surface_->window());
- surface_->SetSurfaceDelegate(nullptr);
- surface_->RemoveSurfaceObserver(this);
- }
- surface_ = surface;
- if (surface_) {
- surface_->SetSurfaceDelegate(this);
- surface_->AddSurfaceObserver(this);
- // Note: Surface window needs to be added to the tree so we can take a
- // snapshot. Where in the tree is not important but we might as well use
- // the cursor container.
- WMHelper::GetInstance()
- ->GetContainer(ash::kShellWindowId_MouseCursorContainer)
- ->AddChild(surface_->window());
- }
+ UpdatePointerSurface(surface);
cursor_changed = true;
}
- // Update hotspot.
- if (hotspot != hotspot_) {
- hotspot_ = hotspot;
+ if (hotspot != hotspot_)
cursor_changed = true;
- }
// Early out if cursor did not change.
- if (!cursor_changed)
+ if (!cursor_changed) {
+ // Cursor scale or rotation may have changed.
+ UpdateCursor();
return;
+ }
// If |surface_| is set then asynchronously capture a snapshot of cursor,
// otherwise cancel pending capture and immediately set the cursor to "none".
if (surface_) {
- CaptureCursor();
+ CaptureCursor(hotspot);
} else {
+ cursor_bitmap_.reset();
cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs();
- cursor_ = ui::kCursorNone;
UpdateCursor();
}
}
@@ -150,7 +164,7 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
// response to each OnPointerEnter() call.
focus_->UnregisterCursorProvider(this);
focus_ = nullptr;
- cursor_ = ui::kCursorNull;
+ cursor_ = ui::CursorType::kNull;
cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs();
}
// Second generate an enter event if focus moved to a new target.
@@ -240,7 +254,6 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
}
last_event_type_ = event->type();
- UpdateCursorScale();
}
void Pointer::OnScrollEvent(ui::ScrollEvent* event) {
@@ -252,7 +265,22 @@ void Pointer::OnScrollEvent(ui::ScrollEvent* event) {
void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) {
if (focus_)
- UpdateCursorScale();
+ UpdateCursor();
+}
+
+void Pointer::OnCursorDisplayChanged(const display::Display& display) {
+ if (focus_)
+ UpdateCursor();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WMHelper::DisplayConfigurationObserver overrides:
+
+void Pointer::OnDisplayConfigurationChanged() {
+ UpdatePointerSurface(surface_);
+ auto info = GetCaptureDisplayInfo();
+ capture_scale_ = info.device_scale_factor();
+ capture_ratio_ = info.GetDensityRatio();
}
////////////////////////////////////////////////////////////////////////////////
@@ -264,7 +292,7 @@ void Pointer::OnSurfaceCommit() {
// Capture new cursor to reflect result of commit.
if (focus_)
- CaptureCursor();
+ CaptureCursor(hotspot_);
}
bool Pointer::IsSurfaceSynchronized() const {
@@ -296,62 +324,46 @@ Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const {
return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr;
}
-void Pointer::UpdateCursorScale() {
- DCHECK(focus_);
-
- display::Screen* screen = display::Screen::GetScreen();
- WMHelper* helper = WMHelper::GetInstance();
-
- // Update cursor scale if the effective UI scale has changed.
- display::Display display = screen->GetDisplayNearestWindow(focus_->window());
- float scale = helper->GetDisplayInfo(display.id()).GetEffectiveUIScale();
-
- if (display::Display::HasInternalDisplay()) {
- float primary_device_scale_factor =
- screen->GetPrimaryDisplay().device_scale_factor();
- // The size of the cursor surface is the quotient of its physical size and
- // the DSF of the primary display. The physical size is proportional to the
- // DSF of the internal display. For external displays (and the internal
- // display when secondary to a display with a different DSF), scale the
- // cursor so its physical size matches with the single display case.
- if (!display.IsInternal() ||
- display.device_scale_factor() != primary_device_scale_factor) {
- scale *= primary_device_scale_factor /
- helper->GetDisplayInfo(display::Display::InternalDisplayId())
- .device_scale_factor();
- }
+void Pointer::UpdatePointerSurface(Surface* surface) {
+ if (surface_) {
+ surface_->window()->SetTransform(gfx::Transform());
+ if (surface_->window()->parent())
+ surface_->window()->parent()->RemoveChild(surface_->window());
+ surface_->SetSurfaceDelegate(nullptr);
+ surface_->RemoveSurfaceObserver(this);
}
-
- if (helper->GetCursorSet() == ui::CURSOR_SET_LARGE)
- scale *= kLargeCursorScale;
-
- if (scale != cursor_scale_) {
- cursor_scale_ = scale;
- if (surface_)
- CaptureCursor();
+ surface_ = surface;
+ if (surface_) {
+ surface_->SetSurfaceDelegate(this);
+ surface_->AddSurfaceObserver(this);
+ // Note: Surface window needs to be added to the tree so we can take a
+ // snapshot. Where in the tree is not important but we might as well use
+ // the cursor container.
+ WMHelper::GetInstance()
+ ->GetPrimaryDisplayContainer(ash::kShellWindowId_MouseCursorContainer)
+ ->AddChild(surface_->window());
}
}
-void Pointer::CaptureCursor() {
+void Pointer::CaptureCursor(const gfx::Point& hotspot) {
DCHECK(surface_);
DCHECK(focus_);
- // Set UI scale before submitting capture request.
- surface_->window()->layer()->SetTransform(
- gfx::GetScaleTransform(gfx::Point(), cursor_scale_));
-
- float primary_device_scale_factor =
- display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+ // Surface size is in DIPs, while layer size is in pseudo-DIP units that
+ // depend on the DSF of the display mode. Scale the layer to capture the
+ // surface at a constant pixel size, regardless of the primary display's
+ // UI scale and display mode DSF.
+ display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
+ auto* helper = WMHelper::GetInstance();
+ float scale = helper->GetDisplayInfo(display.id()).GetEffectiveUIScale() *
+ capture_scale_ / display.device_scale_factor();
+ surface_->window()->SetTransform(gfx::GetScaleTransform(gfx::Point(), scale));
std::unique_ptr<cc::CopyOutputRequest> request =
cc::CopyOutputRequest::CreateBitmapRequest(
base::Bind(&Pointer::OnCursorCaptured,
- cursor_capture_weak_ptr_factory_.GetWeakPtr(),
- gfx::ScaleToFlooredPoint(
- hotspot_,
- // |hotspot_| is in surface coordinate space so apply
- // both device scale and UI scale.
- cursor_scale_ * primary_device_scale_factor)));
+ cursor_capture_weak_ptr_factory_.GetWeakPtr(), hotspot));
+
request->set_source(cursor_capture_source_id_);
surface_->window()->layer()->RequestCopyOfOutput(std::move(request));
}
@@ -361,22 +373,48 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot,
if (!focus_)
return;
- cursor_ = ui::kCursorNone;
- if (!result->IsEmpty()) {
+ if (result->IsEmpty()) {
+ cursor_bitmap_.reset();
+ } else {
DCHECK(result->HasBitmap());
- std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap();
+ cursor_bitmap_ = *result->TakeBitmap();
+ hotspot_ = hotspot;
+ }
+
+ UpdateCursor();
+}
+
+void Pointer::UpdateCursor() {
+ DCHECK(focus_);
+
+ if (cursor_bitmap_.drawsNothing()) {
+ cursor_ = ui::CursorType::kNone;
+ } else {
+ SkBitmap bitmap = cursor_bitmap_;
+ gfx::Point hotspot = gfx::ScaleToFlooredPoint(hotspot_, capture_ratio_);
+
+ auto* helper = WMHelper::GetInstance();
+ const display::Display& display = helper->GetCursorDisplay();
+ float scale =
+ helper->GetDisplayInfo(display.id()).GetDensityRatio() / capture_ratio_;
+
+ if (helper->GetCursorSet() == ui::CURSOR_SET_LARGE)
+ scale *= kLargeCursorScale;
+
+ ui::ScaleAndRotateCursorBitmapAndHotpoint(scale, display.rotation(),
+ &bitmap, &hotspot);
ui::PlatformCursor platform_cursor;
#if defined(USE_OZONE)
// TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers
// and use that here instead of the current bitmap API. crbug.com/686600
platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor(
- *bitmap.get(), hotspot);
+ bitmap, hotspot, 0);
#elif defined(USE_X11)
- XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot);
+ XcursorImage* image = ui::SkBitmapToXcursorImage(&bitmap, hotspot);
platform_cursor = ui::CreateReffedCustomXCursor(image);
#endif
- cursor_ = ui::kCursorCustom;
+ cursor_ = ui::CursorType::kCustom;
cursor_.SetPlatformCursor(platform_cursor);
#if defined(USE_OZONE)
ui::CursorFactoryOzone::GetInstance()->UnrefImageCursor(platform_cursor);
@@ -385,12 +423,6 @@ void Pointer::OnCursorCaptured(const gfx::Point& hotspot,
#endif
}
- UpdateCursor();
-}
-
-void Pointer::UpdateCursor() {
- DCHECK(focus_);
-
aura::Window* root_window = focus_->window()->GetRootWindow();
if (!root_window)
return;
diff --git a/chromium/components/exo/pointer.h b/chromium/components/exo/pointer.h
index 07cf6bdc026..b39988381f8 100644
--- a/chromium/components/exo/pointer.h
+++ b/chromium/components/exo/pointer.h
@@ -13,6 +13,7 @@
#include "components/exo/surface_delegate.h"
#include "components/exo/surface_observer.h"
#include "components/exo/wm_helper.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/cursor/cursor.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
@@ -37,6 +38,7 @@ class Surface;
// devices, such as mice, which control the pointer location and pointer focus.
class Pointer : public ui::EventHandler,
public WMHelper::CursorObserver,
+ public WMHelper::DisplayConfigurationObserver,
public SurfaceDelegate,
public SurfaceObserver {
public:
@@ -59,6 +61,10 @@ class Pointer : public ui::EventHandler,
// Overridden from WMHelper::CursorObserver:
void OnCursorSetChanged(ui::CursorSetType cursor_set) override;
+ void OnCursorDisplayChanged(const display::Display& display) override;
+
+ // Overridden from WMHelper::DisplayConfigurationObserver:
+ void OnDisplayConfigurationChanged() override;
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
@@ -71,17 +77,17 @@ class Pointer : public ui::EventHandler,
// Returns the effective target for |event|.
Surface* GetEffectiveTargetForEvent(ui::Event* event) const;
- // Recompute cursor scale and update cursor if scale changed.
- void UpdateCursorScale();
+ // Updates the |surface_| from which the cursor is captured.
+ void UpdatePointerSurface(Surface* surface);
// Asynchronously update the cursor by capturing a snapshot of |surface_|.
- void CaptureCursor();
+ void CaptureCursor(const gfx::Point& hotspot);
// Called when cursor snapshot has been captured.
void OnCursorCaptured(const gfx::Point& hotspot,
std::unique_ptr<cc::CopyOutputResult> result);
- // Update cursor to reflect the current value of |cursor_|.
+ // Update |cursor_| to |cursor_bitmap_| transformed for the current display.
void UpdateCursor();
// The delegate instance that all events are dispatched to.
@@ -96,15 +102,22 @@ class Pointer : public ui::EventHandler,
// The location of the pointer in the current focus surface.
gfx::PointF location_;
- // The scale applied to the cursor to compensate for the UI scale.
- float cursor_scale_ = 1.0f;
-
// The position of the pointer surface relative to the pointer location.
gfx::Point hotspot_;
+ // Latest cursor snapshot.
+ SkBitmap cursor_bitmap_;
+
// The current cursor.
ui::Cursor cursor_;
+ // Scale at which cursor snapshot is captured.
+ float capture_scale_;
+
+ // Density ratio of the cursor snapshot. The bitmap is scaled on displays with
+ // a different ratio.
+ float capture_ratio_;
+
// Source used for cursor capture copy output requests.
const base::UnguessableToken cursor_capture_source_id_;
diff --git a/chromium/components/exo/pointer_unittest.cc b/chromium/components/exo/pointer_unittest.cc
index 0a6118b36de..6df66bcce6c 100644
--- a/chromium/components/exo/pointer_unittest.cc
+++ b/chromium/components/exo/pointer_unittest.cc
@@ -8,7 +8,6 @@
#include "ash/shell.h"
#include "ash/shell_port.h"
#include "ash/wm/window_positioning_utils.h"
-#include "ash/wm_window.h"
#include "components/exo/buffer.h"
#include "components/exo/pointer_delegate.h"
#include "components/exo/shell_surface.h"
@@ -313,7 +312,7 @@ TEST_F(PointerTest, IgnorePointerEventDuringModal) {
new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(5, 5))));
surface2->Attach(buffer2.get());
surface2->Commit();
- ash::wm::CenterWindow(ash::WmWindow::Get(surface2->window()));
+ ash::wm::CenterWindow(surface2->window());
gfx::Point location2 = surface2->window()->GetBoundsInScreen().origin();
// Make the window modal.
diff --git a/chromium/components/exo/shell_surface.cc b/chromium/components/exo/shell_surface.cc
index 48a58e7c211..4259d841c31 100644
--- a/chromium/components/exo/shell_surface.cc
+++ b/chromium/components/exo/shell_surface.cc
@@ -7,17 +7,14 @@
#include <algorithm>
#include "ash/frame/custom_frame_view_ash.h"
+#include "ash/public/cpp/shelf_types.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/public/interfaces/window_pin_type.mojom.h"
-#include "ash/shelf/wm_shelf.h"
-#include "ash/shell_port.h"
#include "ash/wm/drag_window_resizer.h"
#include "ash/wm/window_resizer.h"
#include "ash/wm/window_state.h"
-#include "ash/wm/window_state_aura.h"
#include "ash/wm/window_util.h"
-#include "ash/wm_window.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
@@ -44,10 +41,6 @@
#include "ui/wm/core/window_animations.h"
#include "ui/wm/core/window_util.h"
-#if defined(OS_CHROMEOS)
-#include "chromeos/audio/chromeos_sounds.h"
-#endif
-
namespace exo {
namespace {
@@ -109,17 +102,23 @@ class CustomWindowTargeter : public aura::WindowTargeter {
if (component != HTNOWHERE && component != HTCLIENT)
return true;
- // If there is an underlay, test against it's bounds instead since it will
- // be equal or larger than the surface's bounds.
+ // If there is an underlay, test against it first as it's bounds may be
+ // larger than the surface's bounds.
aura::Window* shadow_underlay =
static_cast<ShellSurface*>(
widget_->widget_delegate()->GetContentsView())
->shadow_underlay();
if (shadow_underlay) {
- aura::Window::ConvertPointToTarget(window, shadow_underlay, &local_point);
- return gfx::Rect(shadow_underlay->layer()->size()).Contains(local_point);
+ gfx::Point local_point_in_shadow_underlay = local_point;
+ aura::Window::ConvertPointToTarget(window, shadow_underlay,
+ &local_point_in_shadow_underlay);
+ if (gfx::Rect(shadow_underlay->layer()->size())
+ .Contains(local_point_in_shadow_underlay)) {
+ return true;
+ }
}
+ // Otherwise, fallback to hit test on the surface.
aura::Window::ConvertPointToTarget(window, surface->window(), &local_point);
return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1)));
}
@@ -129,7 +128,8 @@ class CustomWindowTargeter : public aura::WindowTargeter {
aura::Window* window = static_cast<aura::Window*>(root);
Surface* surface = ShellSurface::GetMainSurface(window);
- // Send events which are outside of the surface's bounds to the underlay.
+ // Send events which wouldn't be handled by the surface, to the shadow
+ // underlay.
aura::Window* shadow_underlay =
static_cast<ShellSurface*>(
widget_->widget_delegate()->GetContentsView())
@@ -137,8 +137,12 @@ class CustomWindowTargeter : public aura::WindowTargeter {
if (surface && event->IsLocatedEvent() && shadow_underlay) {
gfx::Point local_point = event->AsLocatedEvent()->location();
int component = widget_->non_client_view()->NonClientHitTest(local_point);
- if (component == HTNOWHERE)
- return shadow_underlay;
+ if (component == HTNOWHERE) {
+ aura::Window::ConvertPointToTarget(window, surface->window(),
+ &local_point);
+ if (!surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))))
+ return shadow_underlay;
+ }
}
return aura::WindowTargeter::FindTargetForEvent(root, event);
}
@@ -154,10 +158,7 @@ class CustomWindowTargeter : public aura::WindowTargeter {
class CustomWindowResizer : public ash::WindowResizer {
public:
explicit CustomWindowResizer(ash::wm::WindowState* window_state)
- : WindowResizer(window_state) {
- ash::ShellPort::Get()->LockCursor();
- }
- ~CustomWindowResizer() override { ash::ShellPort::Get()->UnlockCursor(); }
+ : WindowResizer(window_state) {}
// Overridden from ash::WindowResizer:
void Drag(const gfx::Point& location, int event_flags) override {}
@@ -190,41 +191,6 @@ class ShellSurfaceWidget : public views::Widget {
DISALLOW_COPY_AND_ASSIGN(ShellSurfaceWidget);
};
-class ShadowUnderlayEventHandler : public ui::EventHandler {
- public:
- ShadowUnderlayEventHandler() {}
- ~ShadowUnderlayEventHandler() override {}
-
- // Overridden from ui::EventHandler:
- void OnEvent(ui::Event* event) override {
- // If the event is targeted at the underlay, it means the user has made an
- // interaction that is outside the surface's bounds and we want to capture
- // it (usually when in spoken feedback mode). Handle the event (to prevent
- // behind-windows from receiving it) and play an earcon to notify the user.
- if (event->IsLocatedEvent()) {
-#if defined(OS_CHROMEOS)
- const ui::EventType kEarconEventTypes[] = {ui::ET_MOUSE_PRESSED,
- ui::ET_MOUSEWHEEL,
- ui::ET_TOUCH_PRESSED,
- ui::ET_POINTER_DOWN,
- ui::ET_POINTER_WHEEL_CHANGED,
- ui::ET_GESTURE_BEGIN,
- ui::ET_SCROLL,
- ui::ET_SCROLL_FLING_START};
- bool is_earcon_event_type =
- std::find(std::begin(kEarconEventTypes), std::end(kEarconEventTypes),
- event->type()) != std::end(kEarconEventTypes);
- if (is_earcon_event_type)
- WMHelper::GetInstance()->PlayEarcon(chromeos::SOUND_VOLUME_ADJUST);
-#endif
- event->SetHandled();
- }
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ShadowUnderlayEventHandler);
-};
-
} // namespace
// Helper class used to coalesce a number of changes into one "configure"
@@ -373,7 +339,6 @@ ShellSurface::~ShellSurface() {
surface_->SetSurfaceDelegate(nullptr);
surface_->RemoveSurfaceObserver(this);
}
- WMHelper::GetInstance()->RemoveAccessibilityObserver(this);
}
void ShellSurface::AcknowledgeConfigure(uint32_t serial) {
@@ -501,6 +466,17 @@ void ShellSurface::SetSystemUiVisibility(bool autohide) {
ash::wm::SetAutoHideShelf(widget_->GetNativeWindow(), autohide);
}
+void ShellSurface::SetAlwaysOnTop(bool always_on_top) {
+ TRACE_EVENT1("exo", "ShellSurface::SetAlwaysOnTop", "always_on_top",
+ always_on_top);
+
+ if (!widget_)
+ CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL);
+
+ widget_->GetNativeWindow()->SetProperty(aura::client::kAlwaysOnTopKey,
+ always_on_top);
+}
+
void ShellSurface::SetTitle(const base::string16& title) {
TRACE_EVENT1("exo", "ShellSurface::SetTitle", "title",
base::UTF16ToUTF8(title));
@@ -544,13 +520,14 @@ void ShellSurface::UpdateSystemModal() {
void ShellSurface::SetApplicationId(aura::Window* window,
const std::string& id) {
TRACE_EVENT1("exo", "ShellSurface::SetApplicationId", "application_id", id);
- window->SetProperty(aura::client::kAppIdKey, new std::string(id));
+ const ash::ShelfID shelf_id(id);
+ window->SetProperty(ash::kShelfIDKey, new std::string(shelf_id.Serialize()));
}
// static
const std::string ShellSurface::GetApplicationId(aura::Window* window) {
- std::string* string_ptr = window->GetProperty(aura::client::kAppIdKey);
- return string_ptr ? *string_ptr : std::string();
+ return ash::ShelfID::Deserialize(window->GetProperty(ash::kShelfIDKey))
+ .app_id;
}
void ShellSurface::SetApplicationId(const std::string& application_id) {
@@ -904,7 +881,7 @@ void ShellSurface::GetWidgetHitTestMask(gfx::Path* mask) const {
////////////////////////////////////////////////////////////////////////////////
// views::Views overrides:
-gfx::Size ShellSurface::GetPreferredSize() const {
+gfx::Size ShellSurface::CalculatePreferredSize() const {
if (!geometry_.IsEmpty())
return geometry_.size();
@@ -1027,13 +1004,6 @@ void ShellSurface::OnWindowActivated(
}
////////////////////////////////////////////////////////////////////////////////
-// WMHelper::AccessibilityObserver overrides:
-
-void ShellSurface::OnAccessibilityModeChanged() {
- UpdateShadow();
-}
-
-////////////////////////////////////////////////////////////////////////////////
// WMHelper::DisplayConfigurationObserver overrides:
void ShellSurface::OnDisplayConfigurationChanged() {
@@ -1137,6 +1107,50 @@ void ShellSurface::OnMouseEvent(ui::MouseEvent* event) {
}
}
+void ShellSurface::OnGestureEvent(ui::GestureEvent* event) {
+ if (!resizer_) {
+ views::View::OnGestureEvent(event);
+ return;
+ }
+
+ if (event->handled())
+ return;
+
+ // TODO(domlaskowski): Handle touch dragging/resizing for BoundsMode::SHELL.
+ // See crbug.com/738606.
+ switch (event->type()) {
+ case ui::ET_GESTURE_END: {
+ ScopedConfigure scoped_configure(this, false);
+ EndDrag(false /* revert */);
+ break;
+ }
+ case ui::ET_GESTURE_SCROLL_BEGIN:
+ case ui::ET_GESTURE_SCROLL_END:
+ case ui::ET_GESTURE_SCROLL_UPDATE:
+ case ui::ET_GESTURE_TAP:
+ case ui::ET_GESTURE_TAP_DOWN:
+ case ui::ET_GESTURE_TAP_CANCEL:
+ case ui::ET_GESTURE_TAP_UNCONFIRMED:
+ case ui::ET_GESTURE_DOUBLE_TAP:
+ case ui::ET_GESTURE_BEGIN:
+ case ui::ET_GESTURE_TWO_FINGER_TAP:
+ case ui::ET_GESTURE_PINCH_BEGIN:
+ case ui::ET_GESTURE_PINCH_END:
+ case ui::ET_GESTURE_PINCH_UPDATE:
+ case ui::ET_GESTURE_LONG_PRESS:
+ case ui::ET_GESTURE_LONG_TAP:
+ case ui::ET_GESTURE_SWIPE:
+ case ui::ET_GESTURE_SHOW_PRESS:
+ case ui::ET_SCROLL:
+ case ui::ET_SCROLL_FLING_START:
+ case ui::ET_SCROLL_FLING_CANCEL:
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// ui::AcceleratorTarget overrides:
@@ -1167,7 +1181,8 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
params.show_state = show_state;
// Make shell surface a transient child if |parent_| has been set.
params.parent =
- parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_);
+ parent_ ? parent_
+ : WMHelper::GetInstance()->GetPrimaryDisplayContainer(container_);
params.bounds = gfx::Rect(origin_, gfx::Size());
bool activatable = activatable_;
// ShellSurfaces in system modal container are only activatable if input
@@ -1228,9 +1243,6 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
ui::AcceleratorManager::kNormalPriority, this);
}
- // Receive accessibility changes to update shadow underlay.
- WMHelper::GetInstance()->AddAccessibilityObserver(this);
-
// Show widget next time Commit() is called.
pending_show_widget_ = true;
}
@@ -1321,39 +1333,38 @@ void ShellSurface::AttemptToStartDrag(int component) {
switch (component) {
case HTCAPTION:
- cursor_client->SetCursor(ui::kCursorPointer);
+ cursor_client->SetCursor(ui::CursorType::kPointer);
break;
case HTTOP:
- cursor_client->SetCursor(ui::kCursorNorthResize);
+ cursor_client->SetCursor(ui::CursorType::kNorthResize);
break;
case HTTOPRIGHT:
- cursor_client->SetCursor(ui::kCursorNorthEastResize);
+ cursor_client->SetCursor(ui::CursorType::kNorthEastResize);
break;
case HTRIGHT:
- cursor_client->SetCursor(ui::kCursorEastResize);
+ cursor_client->SetCursor(ui::CursorType::kEastResize);
break;
case HTBOTTOMRIGHT:
- cursor_client->SetCursor(ui::kCursorSouthEastResize);
+ cursor_client->SetCursor(ui::CursorType::kSouthEastResize);
break;
case HTBOTTOM:
- cursor_client->SetCursor(ui::kCursorSouthResize);
+ cursor_client->SetCursor(ui::CursorType::kSouthResize);
break;
case HTBOTTOMLEFT:
- cursor_client->SetCursor(ui::kCursorSouthWestResize);
+ cursor_client->SetCursor(ui::CursorType::kSouthWestResize);
break;
case HTLEFT:
- cursor_client->SetCursor(ui::kCursorWestResize);
+ cursor_client->SetCursor(ui::CursorType::kWestResize);
break;
case HTTOPLEFT:
- cursor_client->SetCursor(ui::kCursorNorthWestResize);
+ cursor_client->SetCursor(ui::CursorType::kNorthWestResize);
break;
default:
NOTREACHED();
break;
}
- resizer_ = ash::CreateWindowResizer(ash::WmWindow::Get(window),
- GetMouseLocation(), component,
+ resizer_ = ash::CreateWindowResizer(window, GetMouseLocation(), component,
aura::client::WINDOW_MOVE_SOURCE_MOUSE);
if (!resizer_)
return;
@@ -1521,9 +1532,7 @@ void ShellSurface::UpdateWidgetBounds() {
const gfx::Rect widget_bounds = widget_->GetWindowBoundsInScreen();
if (widget_bounds != new_widget_bounds) {
if (bounds_mode_ != BoundsMode::CLIENT || !resizer_) {
- // TODO(domlaskowski): Use screen coordinates once multi-display support
- // lands in ARC. See crbug.com/718627.
- widget_->GetNativeWindow()->SetBounds(new_widget_bounds);
+ widget_->SetBounds(new_widget_bounds);
UpdateSurfaceBounds();
} else {
// TODO(domlaskowski): Synchronize window state transitions with the
@@ -1569,15 +1578,17 @@ void ShellSurface::UpdateShadow() {
aura::Window* window = widget_->GetNativeWindow();
- bool underlay_capture_events =
- WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && widget_->IsActive();
- bool black_background_enabled =
- ((widget_->IsFullscreen() || widget_->IsMaximized()) ||
- underlay_capture_events) &&
- ash::wm::GetWindowState(window)->allow_set_bounds_direct() &&
- window->layer()->GetTargetTransform().IsIdentity();
-
- if (!shadow_enabled_ && !black_background_enabled) {
+ // Enable the black backdrop layer behind the window if the window
+ // is in immersive fullscreen, maximized, yet the window can control
+ // the bounds of the window in fullscreen/maximize mode (thus the
+ // background can be visible).
+ bool enable_backdrop =
+ (widget_->IsFullscreen() || widget_->IsMaximized()) &&
+ ash::wm::GetWindowState(window)->allow_set_bounds_direct();
+ if (window->GetProperty(aura::client::kHasBackdrop) != enable_backdrop)
+ window->SetProperty(aura::client::kHasBackdrop, enable_backdrop);
+
+ if (!shadow_enabled_) {
wm::SetShadowElevation(window, wm::ShadowElevation::NONE);
if (shadow_underlay_)
shadow_underlay_->Hide();
@@ -1626,9 +1637,6 @@ void ShellSurface::UpdateShadow() {
if (!shadow_underlay_) {
shadow_underlay_ = base::MakeUnique<aura::Window>(nullptr);
shadow_underlay_->set_owned_by_parent(false);
- shadow_underlay_event_handler_ =
- base::MakeUnique<ShadowUnderlayEventHandler>();
- shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get());
DCHECK(!shadow_underlay_->owned_by_parent());
// Ensure the background area inside the shadow is solid black.
// Clients that provide translucent contents should not be using
@@ -1648,25 +1656,6 @@ void ShellSurface::UpdateShadow() {
float shadow_underlay_opacity = shadow_background_opacity_;
- // Put the black background layer behind the window if
- // 1) the window is in immersive fullscreen, maximized or is active with
- // spoken feedback enabled.
- // 2) the window can control the bounds of the window in fullscreen (
- // thus the background can be visible).
- // 3) the window has no transform (the transformed background may
- // not cover the entire background, e.g. overview mode).
- if (black_background_enabled) {
- if (shadow_underlay_in_surface_) {
- shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size());
- } else {
- gfx::Point origin;
- origin -= window->bounds().origin().OffsetFromOrigin();
- shadow_bounds.set_origin(origin);
- shadow_bounds.set_size(window->parent()->bounds().size());
- }
- shadow_underlay_opacity = 1.0f;
- }
-
if (!shadow_underlay_in_surface_)
shadow_underlay_bounds = shadow_bounds;
diff --git a/chromium/components/exo/shell_surface.h b/chromium/components/exo/shell_surface.h
index 536f41763d5..46348790e55 100644
--- a/chromium/components/exo/shell_surface.h
+++ b/chromium/components/exo/shell_surface.h
@@ -49,7 +49,6 @@ class ShellSurface : public SurfaceDelegate,
public ash::wm::WindowStateObserver,
public aura::WindowObserver,
public WMHelper::ActivationObserver,
- public WMHelper::AccessibilityObserver,
public WMHelper::DisplayConfigurationObserver {
public:
enum class BoundsMode { SHELL, CLIENT, FIXED };
@@ -138,6 +137,9 @@ class ShellSurface : public SurfaceDelegate,
// Sets whether or not the shell surface should autohide the system UI.
void SetSystemUiVisibility(bool autohide);
+ // Set whether the surface is always on top.
+ void SetAlwaysOnTop(bool always_on_top);
+
// Set title for surface.
void SetTitle(const base::string16& title);
@@ -240,7 +242,7 @@ class ShellSurface : public SurfaceDelegate,
void GetWidgetHitTestMask(gfx::Path* mask) const override;
// Overridden from views::View:
- gfx::Size GetPreferredSize() const override;
+ gfx::Size CalculatePreferredSize() const override;
gfx::Size GetMinimumSize() const override;
// Overridden from ash::wm::WindowStateObserver:
@@ -260,15 +262,13 @@ class ShellSurface : public SurfaceDelegate,
aura::Window* gained_active,
aura::Window* lost_active) override;
- // Overridden from WMHelper::AccessibilityObserver:
- void OnAccessibilityModeChanged() override;
-
// Overridden from WMHelper::DisplayConfigurationObserver:
void OnDisplayConfigurationChanged() override;
// Overridden from ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
+ void OnGestureEvent(ui::GestureEvent* event) override;
// Overridden from ui::AcceleratorTarget:
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
@@ -364,7 +364,6 @@ class ShellSurface : public SurfaceDelegate,
int pending_resize_component_ = HTCAPTION;
std::unique_ptr<aura::Window> shadow_overlay_;
std::unique_ptr<aura::Window> shadow_underlay_;
- std::unique_ptr<ui::EventHandler> shadow_underlay_event_handler_;
gfx::Rect shadow_content_bounds_;
float shadow_background_opacity_ = 1.0;
std::deque<Config> pending_configs_;
diff --git a/chromium/components/exo/shell_surface_unittest.cc b/chromium/components/exo/shell_surface_unittest.cc
index d92a731337d..ab7cc8176d8 100644
--- a/chromium/components/exo/shell_surface_unittest.cc
+++ b/chromium/components/exo/shell_surface_unittest.cc
@@ -10,9 +10,11 @@
#include "ash/public/interfaces/window_pin_type.mojom.h"
#include "ash/shell.h"
#include "ash/shell_port.h"
+#include "ash/test/shell_test_api.h"
+#include "ash/test/workspace_controller_test_api.h"
#include "ash/wm/window_state.h"
-#include "ash/wm/window_state_aura.h"
#include "ash/wm/wm_event.h"
+#include "ash/wm/workspace/workspace_window_resizer.h"
#include "ash/wm_window.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -25,11 +27,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
-#include "ui/aura/window_targeter.h"
#include "ui/base/hit_test.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
-#include "ui/events/base_event_utils.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/shadow.h"
#include "ui/wm/core/shadow_controller.h"
@@ -838,9 +838,8 @@ TEST_F(ShellSurfaceTest, ShadowStartMaximized) {
EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible());
shell_surface->SetRectangularShadowEnabled(false);
surface->Commit();
- // Underlay should be created even without shadow.
- ASSERT_TRUE(shell_surface->shadow_underlay());
- EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible());
+ // No underlay if there is no shadow.
+ EXPECT_FALSE(shell_surface->shadow_underlay());
shell_surface->SetRectangularShadowEnabled(true);
shell_surface->SetRectangularSurfaceShadow(gfx::Rect(10, 10, 100, 100));
@@ -890,7 +889,11 @@ TEST_F(ShellSurfaceTest, ToggleFullscreen) {
shell_surface->GetWidget()->GetWindowBoundsInScreen().width());
}
-TEST_F(ShellSurfaceTest, MaximizedAndImmersiveFullscreenBackground) {
+TEST_F(ShellSurfaceTest, MaximizedAndImmersiveFullscreenBackdrop) {
+ ash::WorkspaceController* wc =
+ ash::test::ShellTestApi(ash::Shell::Get()).workspace_controller();
+ ash::test::WorkspaceControllerTestApi test_helper(wc);
+
const gfx::Size display_size =
display::Screen::GetScreen()->GetPrimaryDisplay().size();
const gfx::Size buffer_size(display_size);
@@ -913,6 +916,8 @@ TEST_F(ShellSurfaceTest, MaximizedAndImmersiveFullscreenBackground) {
EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().size(),
shell_surface->surface_for_testing()->window()->bounds().size());
+ EXPECT_FALSE(test_helper.GetBackdropWindow());
+
ash::wm::WMEvent fullscreen_event(ash::wm::WM_EVENT_TOGGLE_FULLSCREEN);
ash::WmWindow* window =
ash::WmWindow::Get(shell_surface->GetWidget()->GetNativeWindow());
@@ -920,112 +925,21 @@ TEST_F(ShellSurfaceTest, MaximizedAndImmersiveFullscreenBackground) {
// Enter immersive fullscreen mode. Shadow underlay is fullscreen.
window->GetWindowState()->OnWMEvent(&fullscreen_event);
- EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible());
- EXPECT_EQ(1.f, shell_surface->shadow_underlay()->layer()->opacity());
- EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().size(),
- shell_surface->shadow_underlay()->bounds().size());
+ EXPECT_TRUE(test_helper.GetBackdropWindow());
// Leave fullscreen mode. Shadow underlay is restored.
window->GetWindowState()->OnWMEvent(&fullscreen_event);
- EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible());
- EXPECT_EQ(shadow_bounds, shell_surface->shadow_underlay()->bounds());
+ EXPECT_FALSE(test_helper.GetBackdropWindow());
ash::wm::WMEvent maximize_event(ash::wm::WM_EVENT_TOGGLE_MAXIMIZE);
- // Enter maximized mode. Shadow underlay is fullscreen.
+ // Enter maximized mode.
window->GetWindowState()->OnWMEvent(&maximize_event);
- EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible());
- EXPECT_EQ(1.f, shell_surface->shadow_underlay()->layer()->opacity());
- EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().size(),
- shell_surface->shadow_underlay()->bounds().size());
+ EXPECT_TRUE(test_helper.GetBackdropWindow());
- // Leave maximized mode. Shadow underlay is fullscreen.
+ // Leave maximized mode.
window->GetWindowState()->OnWMEvent(&maximize_event);
- EXPECT_TRUE(shell_surface->shadow_underlay()->IsVisible());
- EXPECT_EQ(1.f, shell_surface->shadow_underlay()->layer()->opacity());
- EXPECT_EQ(shadow_bounds, shell_surface->shadow_underlay()->bounds());
-}
-
-TEST_F(ShellSurfaceTest, SpokenFeedbackFullscreenBackground) {
- const gfx::Size display_size =
- display::Screen::GetScreen()->GetPrimaryDisplay().size();
- const gfx::Size buffer_size(display_size);
- Buffer buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
- Surface surface;
- ShellSurface shell_surface(&surface, nullptr,
- ShellSurface::BoundsMode::CLIENT, gfx::Point(),
- true, false, ash::kShellWindowId_DefaultContainer);
- surface.Attach(&buffer);
-
- gfx::Rect shadow_bounds(10, 10, 100, 100);
- shell_surface.SetGeometry(shadow_bounds);
- shell_surface.SetRectangularSurfaceShadow(shadow_bounds);
- surface.Commit();
- EXPECT_EQ(shadow_bounds,
- shell_surface.GetWidget()->GetWindowBoundsInScreen());
- ASSERT_EQ(shadow_bounds, shell_surface.shadow_underlay()->bounds());
-
- aura::Window* shell_window = shell_surface.GetWidget()->GetNativeWindow();
- aura::WindowTargeter* targeter = static_cast<aura::WindowTargeter*>(
- static_cast<ui::EventTarget*>(shell_window)->GetEventTargeter());
-
- gfx::Point pt_out(300, 300);
- ui::MouseEvent ev_out(ui::ET_MOUSE_PRESSED, pt_out, pt_out,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- gfx::Point pt_in(70, 70);
- ui::MouseEvent ev_in(ui::ET_MOUSE_PRESSED, pt_in, pt_in,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
-
- EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(shell_window, ev_out));
-
- // Enable spoken feedback.
- ash::Shell::Get()->accessibility_delegate()->ToggleSpokenFeedback(
- ash::A11Y_NOTIFICATION_NONE);
- shell_surface.OnAccessibilityModeChanged();
-
- EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().bounds(),
- shell_surface.shadow_underlay()->bounds());
- EXPECT_TRUE(shell_surface.shadow_underlay()->IsVisible());
- EXPECT_NE(shell_surface.GetWidget()->GetWindowBoundsInScreen(),
- shell_surface.shadow_underlay()->bounds());
-
- // Test event capture
- EXPECT_TRUE(targeter->SubtreeShouldBeExploredForEvent(shell_window, ev_out));
- EXPECT_EQ(shell_surface.shadow_underlay(),
- static_cast<ui::EventTargeter*>(targeter)->FindTargetForEvent(
- shell_window, &ev_out));
- EXPECT_NE(shell_surface.shadow_underlay(),
- static_cast<ui::EventTargeter*>(targeter)->FindTargetForEvent(
- shell_window, &ev_in));
-
- // Create a new surface
- Buffer buffer2(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
- Surface surface2;
- ShellSurface shell_surface2(
- &surface2, nullptr, ShellSurface::BoundsMode::CLIENT, gfx::Point(), true,
- false, ash::kShellWindowId_DefaultContainer);
- surface2.Attach(&buffer2);
- shell_surface2.SetRectangularSurfaceShadow(shadow_bounds);
- surface2.Commit();
-
- // spoken-feedback was already on, so underlay should fill screen
- EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().bounds(),
- shell_surface2.shadow_underlay()->bounds());
-
- // De-activated shell-surface should NOT have fullscreen underlay
- EXPECT_EQ(shadow_bounds, shell_surface.shadow_underlay()->bounds());
-
- // Disable spoken feedback. Shadow underlay is restored.
- ash::Shell::Get()->accessibility_delegate()->ToggleSpokenFeedback(
- ash::A11Y_NOTIFICATION_NONE);
- shell_surface.OnAccessibilityModeChanged();
- shell_surface2.OnAccessibilityModeChanged();
-
- EXPECT_TRUE(shell_surface.shadow_underlay()->IsVisible());
- EXPECT_EQ(shadow_bounds, shell_surface.shadow_underlay()->bounds());
- EXPECT_EQ(shadow_bounds, shell_surface2.shadow_underlay()->bounds());
+ EXPECT_FALSE(test_helper.GetBackdropWindow());
}
// Make sure that a surface shell started in maximize creates deprecated
diff --git a/chromium/components/exo/surface.cc b/chromium/components/exo/surface.cc
index ab863b1e3ef..7649a08b9f0 100644
--- a/chromium/components/exo/surface.cc
+++ b/chromium/components/exo/surface.cc
@@ -12,12 +12,12 @@
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "cc/output/compositor_frame_sink.h"
#include "cc/quads/render_pass.h"
#include "cc/quads/shared_quad_state.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/resources/single_release_callback.h"
-#include "cc/surfaces/local_surface_id_allocator.h"
#include "cc/surfaces/sequence_surface_reference_factory.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_manager.h"
@@ -26,6 +26,7 @@
#include "components/exo/surface_delegate.h"
#include "components/exo/surface_observer.h"
#include "third_party/khronos/GLES2/gl2.h"
+#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_targeter.h"
@@ -52,6 +53,10 @@ namespace {
// window. If unset, no surface is associated with window.
DEFINE_UI_CLASS_PROPERTY_KEY(Surface*, kSurfaceKey, nullptr);
+// A property key to store whether the surface should only consume
+// stylus input events.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kStylusOnlyKey, false);
+
// Helper function that returns an iterator to the first entry in |list|
// with |key|.
template <typename T, typename U>
@@ -108,7 +113,9 @@ class CustomWindowDelegate : public aura::WindowDelegate {
bool CanFocus() override { return true; }
void OnCaptureLost() override {}
void OnPaint(const ui::PaintContext& context) override {}
- void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
+ void OnDeviceScaleFactorChanged(float device_scale_factor) override {
+ surface_->SetDeviceScaleFactor(device_scale_factor);
+ }
void OnWindowDestroying(aura::Window* window) override {}
void OnWindowDestroyed(aura::Window* window) override { delete this; }
void OnWindowTargetVisibilityChanged(bool visible) override {}
@@ -164,21 +171,8 @@ class CustomWindowTargeter : public aura::WindowTargeter {
// request a CompositorFrameSink from the aura::Window. Setting up the
// BeginFrame hierarchy should be an internal implementation detail of aura or
// mus in aura-mus.
-Surface::Surface()
- : window_(new aura::Window(new CustomWindowDelegate(this))),
- frame_sink_id_(aura::Env::GetInstance()
- ->context_factory_private()
- ->AllocateFrameSinkId()) {
- compositor_frame_sink_holder_ = new CompositorFrameSinkHolder(
- this, frame_sink_id_,
- aura::Env::GetInstance()->context_factory_private()->GetSurfaceManager());
- // TODO(samans): exo::Surface should not be using
- // DirectSurfaceReferenceFactory (crbug.com/688573).
- surface_reference_factory_ = aura::Env::GetInstance()
- ->context_factory_private()
- ->GetSurfaceManager()
- ->reference_factory();
- window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
+Surface::Surface() : window_(new aura::Window(new CustomWindowDelegate(this))) {
+ window_->SetType(aura::client::WINDOW_TYPE_CONTROL);
window_->SetName("ExoSurface");
window_->SetProperty(kSurfaceKey, this);
window_->Init(ui::LAYER_SOLID_COLOR);
@@ -186,6 +180,8 @@ Surface::Surface()
window_->set_owned_by_parent(false);
window_->AddObserver(this);
aura::Env::GetInstance()->context_factory()->AddObserver(this);
+ compositor_frame_sink_holder_ = base::MakeUnique<CompositorFrameSinkHolder>(
+ this, window_->CreateCompositorFrameSink());
}
Surface::~Surface() {
@@ -216,8 +212,6 @@ Surface::~Surface() {
// that they have been cancelled.
for (const auto& presentation_callback : swapped_presentation_callbacks_)
presentation_callback.Run(base::TimeTicks(), base::TimeDelta());
-
- compositor_frame_sink_holder_->GetCompositorFrameSink()->EvictFrame();
}
// static
@@ -226,7 +220,7 @@ Surface* Surface::AsSurface(const aura::Window* window) {
}
cc::SurfaceId Surface::GetSurfaceId() const {
- return cc::SurfaceId(frame_sink_id_, local_surface_id_);
+ return window_->GetSurfaceId();
}
void Surface::Attach(Buffer* buffer) {
@@ -405,6 +399,10 @@ void Surface::SetAlpha(float alpha) {
pending_state_.alpha = alpha;
}
+void Surface::SetDeviceScaleFactor(float device_scale_factor) {
+ device_scale_factor_ = device_scale_factor;
+}
+
void Surface::Commit() {
TRACE_EVENT0("exo", "Surface::Commit");
@@ -433,9 +431,14 @@ void Surface::Commit() {
CommitSurfaceHierarchy();
}
- if (begin_frame_source_ && current_begin_frame_ack_.sequence_number !=
- cc::BeginFrameArgs::kInvalidFrameNumber) {
- begin_frame_source_->DidFinishFrame(this, current_begin_frame_ack_);
+ if (current_begin_frame_ack_.sequence_number !=
+ cc::BeginFrameArgs::kInvalidFrameNumber) {
+ if (begin_frame_source_)
+ begin_frame_source_->DidFinishFrame(this, current_begin_frame_ack_);
+ if (!current_begin_frame_ack_.has_damage) {
+ compositor_frame_sink_holder_->GetCompositorFrameSink()
+ ->DidNotProduceFrame(current_begin_frame_ack_);
+ }
current_begin_frame_ack_.sequence_number =
cc::BeginFrameArgs::kInvalidFrameNumber;
}
@@ -458,12 +461,6 @@ void Surface::CommitSurfaceHierarchy() {
UpdateResource(true);
}
- cc::LocalSurfaceId old_local_surface_id = local_surface_id_;
- if (needs_commit_to_new_surface_ || !local_surface_id_.is_valid()) {
- needs_commit_to_new_surface_ = false;
- local_surface_id_ = id_allocator_.GenerateId();
- }
-
// Move pending frame callbacks to the end of frame_callbacks_.
frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
@@ -473,18 +470,8 @@ void Surface::CommitSurfaceHierarchy() {
UpdateSurface(false);
- if (old_local_surface_id != local_surface_id_) {
- float contents_surface_to_layer_scale = 1.0;
- // The bounds must be updated before switching to the new surface, because
- // the layer may be mirrored, in which case a surface change causes the
- // mirror layer to update its surface using the latest bounds.
- window_->layer()->SetBounds(
- gfx::Rect(window_->layer()->bounds().origin(), content_size_));
- cc::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
- window_->layer()->SetShowPrimarySurface(
- cc::SurfaceInfo(surface_id, contents_surface_to_layer_scale,
- content_size_),
- surface_reference_factory_);
+ if (needs_commit_to_new_surface_) {
+ needs_commit_to_new_surface_ = false;
window_->layer()->SetFillsBoundsOpaquely(
!current_resource_has_alpha_ ||
state_.blend_mode == SkBlendMode::kSrc ||
@@ -494,7 +481,6 @@ void Surface::CommitSurfaceHierarchy() {
// Reset damage.
pending_damage_.setEmpty();
-
DCHECK(!current_resource_.id ||
compositor_frame_sink_holder_->HasReleaseCallbackForResource(
current_resource_.id));
@@ -571,10 +557,10 @@ gfx::NativeCursor Surface::GetCursor() {
// important. Return the first non-null cursor.
for (auto* cursor_provider : cursor_providers_) {
gfx::NativeCursor cursor = cursor_provider->GetCursor();
- if (cursor != ui::kCursorNull)
+ if (cursor != ui::CursorType::kNull)
return cursor;
}
- return ui::kCursorNull;
+ return ui::CursorType::kNull;
}
void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) {
@@ -653,13 +639,20 @@ void Surface::CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces() {
SetSurfaceHierarchyNeedsCommitToNewSurfaces();
}
+bool Surface::IsStylusOnly() {
+ return window_->GetProperty(kStylusOnlyKey);
+}
+
+void Surface::SetStylusOnly() {
+ window_->SetProperty(kStylusOnlyKey, true);
+}
+
////////////////////////////////////////////////////////////////////////////////
// ui::ContextFactoryObserver overrides:
void Surface::OnLostResources() {
- if (!local_surface_id_.is_valid())
+ if (!window_->GetSurfaceId().is_valid())
return;
-
UpdateResource(false);
UpdateSurface(true);
}
@@ -668,13 +661,11 @@ void Surface::OnLostResources() {
// aura::WindowObserver overrides:
void Surface::OnWindowAddedToRootWindow(aura::Window* window) {
- window->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
window->layer()->GetCompositor()->vsync_manager()->AddObserver(this);
}
void Surface::OnWindowRemovingFromRootWindow(aura::Window* window,
aura::Window* new_root) {
- window->layer()->GetCompositor()->RemoveFrameSink(frame_sink_id_);
window->layer()->GetCompositor()->vsync_manager()->RemoveObserver(this);
}
@@ -833,7 +824,7 @@ void Surface::UpdateSurface(bool full_damage) {
gfx::Rect quad_rect = output_rect;
cc::SharedQuadState* quad_state =
render_pass->CreateAndAppendSharedQuadState();
- quad_state->quad_layer_bounds = contents_surface_size;
+ quad_state->quad_layer_rect = gfx::Rect(contents_surface_size);
quad_state->visible_quad_layer_rect = quad_rect;
quad_state->opacity = state_.alpha;
@@ -847,6 +838,7 @@ void Surface::UpdateSurface(bool full_damage) {
current_begin_frame_ack_.has_damage = true;
}
frame.metadata.begin_frame_ack = current_begin_frame_ack_;
+ frame.metadata.device_scale_factor = device_scale_factor_;
if (current_resource_.id) {
// Texture quad is only needed if buffer is not fully transparent.
@@ -879,7 +871,7 @@ void Surface::UpdateSurface(bool full_damage) {
frame.render_pass_list.push_back(std::move(render_pass));
compositor_frame_sink_holder_->GetCompositorFrameSink()
- ->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+ ->SubmitCompositorFrame(std::move(frame));
}
} // namespace exo
diff --git a/chromium/components/exo/surface.h b/chromium/components/exo/surface.h
index 9c633b63691..0abd5113788 100644
--- a/chromium/components/exo/surface.h
+++ b/chromium/components/exo/surface.h
@@ -6,7 +6,6 @@
#define COMPONENTS_EXO_SURFACE_H_
#include <list>
-#include <memory>
#include <set>
#include <utility>
@@ -15,11 +14,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
-#include "cc/output/begin_frame_args.h"
#include "cc/resources/transferable_resource.h"
#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/local_surface_id_allocator.h"
-#include "components/exo/compositor_frame_sink.h"
#include "components/exo/compositor_frame_sink_holder.h"
#include "third_party/skia/include/core/SkBlendMode.h"
#include "third_party/skia/include/core/SkRegion.h"
@@ -35,10 +31,6 @@ class TracedValue;
}
}
-namespace cc {
-class LocalSurfaceIdAllocator;
-}
-
namespace gfx {
class Path;
}
@@ -140,6 +132,9 @@ class Surface : public ui::ContextFactoryObserver,
// This sets the alpha value that will be applied to the whole surface.
void SetAlpha(float alpha);
+ // This sets the device scale factor sent in CompositorFrames.
+ void SetDeviceScaleFactor(float device_scale_factor);
+
// Surface state (damage regions, attached buffers, etc.) is double-buffered.
// A Commit() call atomically applies all pending state, replacing the
// current state. Commit() is not guaranteed to be synchronous. See
@@ -173,7 +168,7 @@ class Surface : public ui::ContextFactoryObserver,
void UnregisterCursorProvider(CursorProvider* provider);
// Returns the cursor for the surface. If no cursor provider is registered
- // then kCursorNull is returned.
+ // then CursorType::kNull is returned.
gfx::NativeCursor GetCursor();
// Set the surface delegate.
@@ -205,6 +200,12 @@ class Surface : public ui::ContextFactoryObserver,
// Returns the active contents size.
gfx::Size content_size() const { return content_size_; }
+ // Returns true if the associated window is in 'stylus-only' mode.
+ bool IsStylusOnly();
+
+ // Enables 'stylus-only' mode for the associated window.
+ void SetStylusOnly();
+
// Overridden from ui::ContextFactoryObserver:
void OnLostResources() override;
@@ -314,12 +315,10 @@ class Surface : public ui::ContextFactoryObserver,
// The buffer that will become the content of surface when Commit() is called.
BufferAttachment pending_buffer_;
- const cc::FrameSinkId frame_sink_id_;
- cc::LocalSurfaceId local_surface_id_;
-
- scoped_refptr<CompositorFrameSinkHolder> compositor_frame_sink_holder_;
+ // The device scale factor sent in CompositorFrames.
+ float device_scale_factor_ = 1.0f;
- cc::LocalSurfaceIdAllocator id_allocator_;
+ std::unique_ptr<CompositorFrameSinkHolder> compositor_frame_sink_holder_;
// The next resource id the buffer will be attached to.
int next_resource_id_ = 1;
@@ -389,12 +388,6 @@ class Surface : public ui::ContextFactoryObserver,
// Surface observer list. Surface does not own the observers.
base::ObserverList<SurfaceObserver, true> observers_;
- // A reference factory that uses the compositor frame sink holder provided
- // to this class to construct surface references. This object is passed to
- // ui::Layer::SetShowSurface because the layer needs to know how to add
- // references to surfaces.
- scoped_refptr<cc::SurfaceReferenceFactory> surface_reference_factory_;
-
// The begin frame source being observed.
cc::BeginFrameSource* begin_frame_source_ = nullptr;
bool needs_begin_frame_ = false;
diff --git a/chromium/components/exo/wayland/BUILD.gn b/chromium/components/exo/wayland/BUILD.gn
index 2b0910474fa..e93a23483d7 100644
--- a/chromium/components/exo/wayland/BUILD.gn
+++ b/chromium/components/exo/wayland/BUILD.gn
@@ -44,6 +44,7 @@ source_set("wayland") {
"//third_party/wayland-protocols:remote_shell_protocol",
"//third_party/wayland-protocols:secure_output_protocol",
"//third_party/wayland-protocols:stylus_protocol",
+ "//third_party/wayland-protocols:stylus_tools_protocol",
"//third_party/wayland-protocols:viewporter_protocol",
"//third_party/wayland-protocols:vsync_feedback_protocol",
"//third_party/wayland-protocols:xdg_shell_protocol",
diff --git a/chromium/components/exo/wayland/clients/client_base.cc b/chromium/components/exo/wayland/clients/client_base.cc
index 8c17ba56ed5..e604367854d 100644
--- a/chromium/components/exo/wayland/clients/client_base.cc
+++ b/chromium/components/exo/wayland/clients/client_base.cc
@@ -450,9 +450,9 @@ std::unique_ptr<ClientBase::Buffer> ClientBase::CreateBuffer(
size_t stride = width_ * kBytesPerPixel;
buffer->shared_memory.reset(new base::SharedMemory());
buffer->shared_memory->CreateAndMapAnonymous(stride * height_);
- buffer->shm_pool.reset(
- wl_shm_create_pool(globals_.shm.get(), buffer->shared_memory->handle().fd,
- buffer->shared_memory->requested_size()));
+ buffer->shm_pool.reset(wl_shm_create_pool(
+ globals_.shm.get(), buffer->shared_memory->handle().GetHandle(),
+ buffer->shared_memory->requested_size()));
buffer->buffer.reset(static_cast<wl_buffer*>(wl_shm_pool_create_buffer(
buffer->shm_pool.get(), 0, width_, height_, stride, kShmFormat)));
diff --git a/chromium/components/exo/wayland/server.cc b/chromium/components/exo/wayland/server.cc
index 45295ff70a5..36441f2ee63 100644
--- a/chromium/components/exo/wayland/server.cc
+++ b/chromium/components/exo/wayland/server.cc
@@ -15,6 +15,7 @@
#include <secure-output-unstable-v1-server-protocol.h>
#include <stddef.h>
#include <stdint.h>
+#include <stylus-tools-unstable-v1-server-protocol.h>
#include <stylus-unstable-v1-server-protocol.h>
#include <stylus-unstable-v2-server-protocol.h>
#include <viewporter-server-protocol.h>
@@ -40,6 +41,7 @@
#include "base/memory/free_deleter.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
@@ -163,6 +165,10 @@ DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasBlendingKey, false);
// to ignore the activation event originated by creation.
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIgnoreWindowActivated, true);
+// A property key containing a boolean set to true if the stylus_tool
+// object is associated with a window.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasStylusToolKey, false);
+
wl_resource* GetSurfaceResource(Surface* surface) {
return surface->GetProperty(kSurfaceResourceKey);
}
@@ -444,7 +450,7 @@ void shm_create_pool(wl_client* client,
int32_t size) {
std::unique_ptr<SharedMemory> shared_memory =
GetUserDataAs<Display>(resource)->CreateSharedMemory(
- base::FileDescriptor(fd, true), size);
+ base::SharedMemoryHandle::ImportHandle(fd, size), size);
if (!shared_memory) {
wl_resource_post_no_memory(resource);
return;
@@ -2001,6 +2007,16 @@ void remote_surface_set_systemui_visibility(wl_client* client,
visibility != ZCR_REMOTE_SURFACE_V1_SYSTEMUI_VISIBILITY_STATE_VISIBLE);
}
+void remote_surface_set_always_on_top(wl_client* client,
+ wl_resource* resource) {
+ GetUserDataAs<ShellSurface>(resource)->SetAlwaysOnTop(true);
+}
+
+void remote_surface_unset_always_on_top(wl_client* client,
+ wl_resource* resource) {
+ GetUserDataAs<ShellSurface>(resource)->SetAlwaysOnTop(false);
+}
+
void remote_surface_ack_configure(wl_client* client,
wl_resource* resource,
uint32_t serial) {
@@ -2032,6 +2048,8 @@ const struct zcr_remote_surface_v1_interface remote_surface_implementation = {
remote_surface_unset_system_modal,
remote_surface_set_rectangular_surface_shadow,
remote_surface_set_systemui_visibility,
+ remote_surface_set_always_on_top,
+ remote_surface_unset_always_on_top,
remote_surface_ack_configure,
remote_surface_move};
@@ -2078,7 +2096,7 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
}
bool IsMultiDisplaySupported() const {
- return wl_resource_get_version(remote_shell_resource_) >= 4;
+ return wl_resource_get_version(remote_shell_resource_) >= 5;
}
std::unique_ptr<ShellSurface> CreateShellSurface(Surface* surface,
@@ -2167,6 +2185,10 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
const gfx::Rect& bounds = display.bounds();
const gfx::Insets& insets = display.GetWorkAreaInsets();
+ double device_scale_factor =
+ WMHelper::GetInstance()->GetDisplayInfo(display.id())
+ .device_scale_factor();
+
zcr_remote_shell_v1_send_workspace(
remote_shell_resource_,
static_cast<uint32_t>(display.id() >> 32),
@@ -2174,7 +2196,8 @@ class WaylandRemoteShell : public WMHelper::MaximizeModeObserver,
bounds.x(), bounds.y(), bounds.width(), bounds.height(),
insets.left(), insets.top(), insets.right(), insets.bottom(),
OutputTransform(display.rotation()),
- wl_fixed_from_double(display.device_scale_factor()));
+ wl_fixed_from_double(device_scale_factor),
+ display.IsInternal());
}
zcr_remote_shell_v1_send_configure(remote_shell_resource_, layout_mode_);
@@ -2381,7 +2404,7 @@ const struct zcr_remote_shell_v1_interface remote_shell_implementation = {
remote_shell_destroy, remote_shell_get_remote_surface,
remote_shell_get_notification_surface};
-const uint32_t remote_shell_version = 4;
+const uint32_t remote_shell_version = 5;
void bind_remote_shell(wl_client* client,
void* data,
@@ -2735,7 +2758,7 @@ class WaylandKeyboardDelegate : public KeyboardDelegate {
memcpy(shared_keymap.memory(), keymap_string.get(), keymap_size);
wl_keyboard_send_keymap(keyboard_resource_,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
- shared_keymap.handle().fd, keymap_size);
+ shared_keymap.handle().GetHandle(), keymap_size);
}
// Overridden from KeyboardDelegate:
@@ -3826,6 +3849,87 @@ void bind_keyboard_configuration(wl_client* client,
resource, &keyboard_configuration_implementation, data, nullptr);
}
+////////////////////////////////////////////////////////////////////////////////
+// stylus_tool interface:
+
+class StylusTool : public SurfaceObserver {
+ public:
+ explicit StylusTool(Surface* surface) : surface_(surface) {
+ surface_->AddSurfaceObserver(this);
+ surface_->SetProperty(kSurfaceHasStylusToolKey, true);
+ }
+ ~StylusTool() override {
+ if (surface_) {
+ surface_->RemoveSurfaceObserver(this);
+ surface_->SetProperty(kSurfaceHasStylusToolKey, false);
+ }
+ }
+
+ void SetStylusOnly() { surface_->SetStylusOnly(); }
+
+ // Overridden from SurfaceObserver:
+ void OnSurfaceDestroying(Surface* surface) override {
+ surface->RemoveSurfaceObserver(this);
+ surface_ = nullptr;
+ }
+
+ private:
+ Surface* surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(StylusTool);
+};
+
+void stylus_tool_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void stylus_tool_set_stylus_only(wl_client* client, wl_resource* resource) {
+ GetUserDataAs<StylusTool>(resource)->SetStylusOnly();
+}
+
+const struct zcr_stylus_tool_v1_interface stylus_tool_implementation = {
+ stylus_tool_destroy, stylus_tool_set_stylus_only};
+
+////////////////////////////////////////////////////////////////////////////////
+// stylus_tools interface:
+
+void stylus_tools_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void stylus_tools_get_stylus_tool(wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* surface_resource) {
+ Surface* surface = GetUserDataAs<Surface>(surface_resource);
+ if (surface->GetProperty(kSurfaceHasStylusToolKey)) {
+ wl_resource_post_error(
+ resource, ZCR_STYLUS_TOOLS_V1_ERROR_STYLUS_TOOL_EXISTS,
+ "a stylus_tool object for that surface already exists");
+ return;
+ }
+
+ wl_resource* stylus_tool_resource =
+ wl_resource_create(client, &zcr_stylus_tool_v1_interface, 1, id);
+
+ SetImplementation(stylus_tool_resource, &stylus_tool_implementation,
+ base::MakeUnique<StylusTool>(surface));
+}
+
+const struct zcr_stylus_tools_v1_interface stylus_tools_implementation = {
+ stylus_tools_destroy, stylus_tools_get_stylus_tool};
+
+void bind_stylus_tools(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &zcr_stylus_tools_v1_interface, 1, id);
+
+ wl_resource_set_implementation(resource, &stylus_tools_implementation, data,
+ nullptr);
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -3878,6 +3982,8 @@ Server::Server(Display* display)
bind_stylus_v2);
wl_global_create(wl_display_.get(), &zcr_keyboard_configuration_v1_interface,
2, display_, bind_keyboard_configuration);
+ wl_global_create(wl_display_.get(), &zcr_stylus_tools_v1_interface, 1,
+ display_, bind_stylus_tools);
}
Server::~Server() {}
diff --git a/chromium/components/exo/wm_helper.cc b/chromium/components/exo/wm_helper.cc
index 7f0cfcffe72..a24aa2f837e 100644
--- a/chromium/components/exo/wm_helper.cc
+++ b/chromium/components/exo/wm_helper.cc
@@ -62,14 +62,6 @@ void WMHelper::RemoveMaximizeModeObserver(MaximizeModeObserver* observer) {
maximize_mode_observers_.RemoveObserver(observer);
}
-void WMHelper::AddAccessibilityObserver(AccessibilityObserver* observer) {
- accessibility_observers_.AddObserver(observer);
-}
-
-void WMHelper::RemoveAccessibilityObserver(AccessibilityObserver* observer) {
- accessibility_observers_.RemoveObserver(observer);
-}
-
void WMHelper::AddInputDeviceEventObserver(InputDeviceEventObserver* observer) {
input_device_event_observers_.AddObserver(observer);
}
@@ -111,6 +103,11 @@ void WMHelper::NotifyCursorSetChanged(ui::CursorSetType cursor_set) {
observer.OnCursorSetChanged(cursor_set);
}
+void WMHelper::NotifyCursorDisplayChanged(const display::Display& display) {
+ for (CursorObserver& observer : cursor_observers_)
+ observer.OnCursorDisplayChanged(display);
+}
+
void WMHelper::NotifyMaximizeModeStarted() {
for (MaximizeModeObserver& observer : maximize_mode_observers_)
observer.OnMaximizeModeStarted();
@@ -126,11 +123,6 @@ void WMHelper::NotifyMaximizeModeEnded() {
observer.OnMaximizeModeEnded();
}
-void WMHelper::NotifyAccessibilityModeChanged() {
- for (AccessibilityObserver& observer : accessibility_observers_)
- observer.OnAccessibilityModeChanged();
-}
-
void WMHelper::NotifyKeyboardDeviceConfigurationChanged() {
for (InputDeviceEventObserver& observer : input_device_event_observers_)
observer.OnKeyboardDeviceConfigurationChanged();
diff --git a/chromium/components/exo/wm_helper.h b/chromium/components/exo/wm_helper.h
index ad0aeb6ac5a..d68237c54cc 100644
--- a/chromium/components/exo/wm_helper.h
+++ b/chromium/components/exo/wm_helper.h
@@ -14,6 +14,7 @@ class Window;
}
namespace display {
+class Display;
class ManagedDisplayInfo;
}
@@ -48,6 +49,7 @@ class WMHelper {
public:
virtual void OnCursorVisibilityChanged(bool is_visible) {}
virtual void OnCursorSetChanged(ui::CursorSetType cursor_set) {}
+ virtual void OnCursorDisplayChanged(const display::Display& display) {}
protected:
virtual ~CursorObserver() {}
@@ -63,14 +65,6 @@ class WMHelper {
virtual ~MaximizeModeObserver() {}
};
- class AccessibilityObserver {
- public:
- virtual void OnAccessibilityModeChanged() = 0;
-
- protected:
- virtual ~AccessibilityObserver() {}
- };
-
class InputDeviceEventObserver {
public:
virtual void OnKeyboardDeviceConfigurationChanged() = 0;
@@ -100,28 +94,25 @@ class WMHelper {
void RemoveCursorObserver(CursorObserver* observer);
void AddMaximizeModeObserver(MaximizeModeObserver* observer);
void RemoveMaximizeModeObserver(MaximizeModeObserver* observer);
- void AddAccessibilityObserver(AccessibilityObserver* observer);
- void RemoveAccessibilityObserver(AccessibilityObserver* observer);
void AddInputDeviceEventObserver(InputDeviceEventObserver* observer);
void RemoveInputDeviceEventObserver(InputDeviceEventObserver* observer);
void AddDisplayConfigurationObserver(DisplayConfigurationObserver* observer);
void RemoveDisplayConfigurationObserver(
DisplayConfigurationObserver* observer);
- virtual const display::ManagedDisplayInfo GetDisplayInfo(
+ virtual const display::ManagedDisplayInfo& GetDisplayInfo(
int64_t display_id) const = 0;
- virtual aura::Window* GetContainer(int container_id) = 0;
+ virtual aura::Window* GetPrimaryDisplayContainer(int container_id) = 0;
virtual aura::Window* GetActiveWindow() const = 0;
virtual aura::Window* GetFocusedWindow() const = 0;
virtual ui::CursorSetType GetCursorSet() const = 0;
+ virtual const display::Display& GetCursorDisplay() const = 0;
virtual void AddPreTargetHandler(ui::EventHandler* handler) = 0;
virtual void PrependPreTargetHandler(ui::EventHandler* handler) = 0;
virtual void RemovePreTargetHandler(ui::EventHandler* handler) = 0;
virtual void AddPostTargetHandler(ui::EventHandler* handler) = 0;
virtual void RemovePostTargetHandler(ui::EventHandler* handler) = 0;
virtual bool IsMaximizeModeWindowManagerEnabled() const = 0;
- virtual bool IsSpokenFeedbackEnabled() const = 0;
- virtual void PlayEarcon(int sound_key) const = 0;
protected:
WMHelper();
@@ -132,10 +123,10 @@ class WMHelper {
aura::Window* lost_focus);
void NotifyCursorVisibilityChanged(bool is_visible);
void NotifyCursorSetChanged(ui::CursorSetType cursor_set);
+ void NotifyCursorDisplayChanged(const display::Display& display);
void NotifyMaximizeModeStarted();
void NotifyMaximizeModeEnding();
void NotifyMaximizeModeEnded();
- void NotifyAccessibilityModeChanged();
void NotifyKeyboardDeviceConfigurationChanged();
void NotifyDisplayConfigurationChanged();
@@ -144,7 +135,6 @@ class WMHelper {
base::ObserverList<FocusObserver> focus_observers_;
base::ObserverList<CursorObserver> cursor_observers_;
base::ObserverList<MaximizeModeObserver> maximize_mode_observers_;
- base::ObserverList<AccessibilityObserver> accessibility_observers_;
base::ObserverList<InputDeviceEventObserver> input_device_event_observers_;
base::ObserverList<DisplayConfigurationObserver> display_config_observers_;
diff --git a/chromium/components/exo/wm_helper_ash.cc b/chromium/components/exo/wm_helper_ash.cc
index 3fbec935039..23beac2a1e1 100644
--- a/chromium/components/exo/wm_helper_ash.cc
+++ b/chromium/components/exo/wm_helper_ash.cc
@@ -4,7 +4,6 @@
#include "components/exo/wm_helper_ash.h"
-#include "ash/accessibility_delegate.h"
#include "ash/public/cpp/config.h"
#include "ash/shell.h"
#include "ash/shell_port.h"
@@ -13,7 +12,7 @@
#include "base/memory/singleton.h"
#include "ui/aura/client/focus_client.h"
#include "ui/display/manager/display_manager.h"
-#include "ui/events/devices/device_data_manager.h"
+#include "ui/events/devices/input_device_manager.h"
#include "ui/wm/public/activation_client.h"
namespace exo {
@@ -31,10 +30,7 @@ WMHelperAsh::WMHelperAsh() {
aura::client::FocusClient* focus_client =
aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
focus_client->AddObserver(this);
- // TODO(crbug.com/709225): Mushrome doesn't have a DeviceDataManager.
- if (ash::ShellPort::Get()->GetAshConfig() != ash::Config::MUS)
- ui::DeviceDataManager::GetInstance()->AddObserver(this);
- ash::Shell::Get()->system_tray_notifier()->AddAccessibilityObserver(this);
+ ui::InputDeviceManager::GetInstance()->AddObserver(this);
}
WMHelperAsh::~WMHelperAsh() {
@@ -49,23 +45,18 @@ WMHelperAsh::~WMHelperAsh() {
ash::Shell::Get()->cursor_manager()->RemoveObserver(this);
ash::Shell::Get()->activation_client()->RemoveObserver(this);
ash::Shell::Get()->RemoveShellObserver(this);
- // TODO(crbug.com/709225): Mushrome doesn't have a DeviceDataManager.
- if (ash::ShellPort::Get()->GetAshConfig() != ash::Config::MUS)
- ui::DeviceDataManager::GetInstance()->RemoveObserver(this);
- ash::Shell::Get()->system_tray_notifier()->RemoveAccessibilityObserver(this);
+ ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
}
////////////////////////////////////////////////////////////////////////////////
// WMHelperAsh, private:
-const display::ManagedDisplayInfo WMHelperAsh::GetDisplayInfo(
+const display::ManagedDisplayInfo& WMHelperAsh::GetDisplayInfo(
int64_t display_id) const {
return ash::Shell::Get()->display_manager()->GetDisplayInfo(display_id);
}
-aura::Window* WMHelperAsh::GetContainer(int container_id) {
- // TODO(domlaskowski): Use target root window once multi-display support lands
- // in ARC. See crbug.com/718627.
+aura::Window* WMHelperAsh::GetPrimaryDisplayContainer(int container_id) {
return ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
container_id);
}
@@ -87,6 +78,15 @@ ui::CursorSetType WMHelperAsh::GetCursorSet() const {
return ash::Shell::Get()->cursor_manager()->GetCursorSet();
}
+const display::Display& WMHelperAsh::GetCursorDisplay() const {
+ // TODO(crbug.com/631103): Mushrome doesn't have a cursor manager yet.
+ if (ash::ShellPort::Get()->GetAshConfig() == ash::Config::MUS) {
+ static const display::Display display;
+ return display;
+ }
+ return ash::Shell::Get()->cursor_manager()->GetDisplay();
+}
+
void WMHelperAsh::AddPreTargetHandler(ui::EventHandler* handler) {
ash::Shell::Get()->AddPreTargetHandler(handler);
}
@@ -113,14 +113,6 @@ bool WMHelperAsh::IsMaximizeModeWindowManagerEnabled() const {
->IsMaximizeModeWindowManagerEnabled();
}
-bool WMHelperAsh::IsSpokenFeedbackEnabled() const {
- return ash::Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
-}
-
-void WMHelperAsh::PlayEarcon(int sound_key) const {
- return ash::Shell::Get()->accessibility_delegate()->PlayEarcon(sound_key);
-}
-
void WMHelperAsh::OnWindowActivated(
aura::client::ActivationChangeObserver::ActivationReason reason,
aura::Window* gained_active,
@@ -141,9 +133,8 @@ void WMHelperAsh::OnCursorSetChanged(ui::CursorSetType cursor_set) {
NotifyCursorSetChanged(cursor_set);
}
-void WMHelperAsh::OnAccessibilityModeChanged(
- ash::AccessibilityNotificationVisibility notify) {
- NotifyAccessibilityModeChanged();
+void WMHelperAsh::OnCursorDisplayChanged(const display::Display& display) {
+ NotifyCursorDisplayChanged(display);
}
void WMHelperAsh::OnMaximizeModeStarted() {
diff --git a/chromium/components/exo/wm_helper_ash.h b/chromium/components/exo/wm_helper_ash.h
index dc39a292e3b..53f4cb7ff35 100644
--- a/chromium/components/exo/wm_helper_ash.h
+++ b/chromium/components/exo/wm_helper_ash.h
@@ -6,7 +6,6 @@
#define COMPONENTS_EXO_WM_HELPER_ASH_H_
#include "ash/shell_observer.h"
-#include "ash/system/accessibility_observer.h"
#include "ash/wm_display_observer.h"
#include "base/macros.h"
#include "components/exo/wm_helper.h"
@@ -22,7 +21,6 @@ class WMHelperAsh : public WMHelper,
public aura::client::ActivationChangeObserver,
public aura::client::FocusChangeObserver,
public aura::client::CursorClientObserver,
- public ash::AccessibilityObserver,
public ash::ShellObserver,
public ash::WmDisplayObserver,
public ui::InputDeviceEventObserver {
@@ -31,20 +29,19 @@ class WMHelperAsh : public WMHelper,
~WMHelperAsh() override;
// Overridden from WMHelper:
- const display::ManagedDisplayInfo GetDisplayInfo(
+ const display::ManagedDisplayInfo& GetDisplayInfo(
int64_t display_id) const override;
- aura::Window* GetContainer(int container_id) override;
+ aura::Window* GetPrimaryDisplayContainer(int container_id) override;
aura::Window* GetActiveWindow() const override;
aura::Window* GetFocusedWindow() const override;
ui::CursorSetType GetCursorSet() const override;
+ const display::Display& GetCursorDisplay() const override;
void AddPreTargetHandler(ui::EventHandler* handler) override;
void PrependPreTargetHandler(ui::EventHandler* handler) override;
void RemovePreTargetHandler(ui::EventHandler* handler) override;
void AddPostTargetHandler(ui::EventHandler* handler) override;
void RemovePostTargetHandler(ui::EventHandler* handler) override;
bool IsMaximizeModeWindowManagerEnabled() const override;
- bool IsSpokenFeedbackEnabled() const override;
- void PlayEarcon(int sound_key) const override;
// Overridden from aura::client::ActivationChangeObserver:
void OnWindowActivated(
@@ -59,10 +56,7 @@ class WMHelperAsh : public WMHelper,
// Overridden from aura::client::CursorClientObserver:
void OnCursorVisibilityChanged(bool is_visible) override;
void OnCursorSetChanged(ui::CursorSetType cursor_set) override;
-
- // Overridden from ash::AccessibilityObserver:
- void OnAccessibilityModeChanged(
- ash::AccessibilityNotificationVisibility notify) override;
+ void OnCursorDisplayChanged(const display::Display& display) override;
// Overridden from ash::ShellObserver:
void OnMaximizeModeStarted() override;
diff --git a/chromium/components/exo/wm_helper_mus.cc b/chromium/components/exo/wm_helper_mus.cc
index a13d09ff997..89543f3f908 100644
--- a/chromium/components/exo/wm_helper_mus.cc
+++ b/chromium/components/exo/wm_helper_mus.cc
@@ -9,6 +9,7 @@
#include "ui/aura/mus/focus_synchronizer.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/window.h"
+#include "ui/display/display.h"
#include "ui/display/manager/managed_display_info.h"
#include "ui/views/mus/mus_client.h"
#include "ui/wm/public/activation_client.h"
@@ -37,13 +38,14 @@ WMHelperMus::~WMHelperMus() {
////////////////////////////////////////////////////////////////////////////////
// WMHelperMus, private:
-const display::ManagedDisplayInfo WMHelperMus::GetDisplayInfo(
+const display::ManagedDisplayInfo& WMHelperMus::GetDisplayInfo(
int64_t display_id) const {
// TODO(penghuang): Return real display info when it is supported in mus.
- return display::ManagedDisplayInfo(display_id, "", false);
+ static const display::ManagedDisplayInfo info;
+ return info;
}
-aura::Window* WMHelperMus::GetContainer(int container_id) {
+aura::Window* WMHelperMus::GetPrimaryDisplayContainer(int container_id) {
NOTIMPLEMENTED();
return nullptr;
}
@@ -61,6 +63,13 @@ ui::CursorSetType WMHelperMus::GetCursorSet() const {
return ui::CursorSetType::CURSOR_SET_NORMAL;
}
+const display::Display& WMHelperMus::GetCursorDisplay() const {
+ NOTIMPLEMENTED();
+ // TODO(penghuang): Return real display when supported in mus.
+ static const display::Display display;
+ return display;
+}
+
void WMHelperMus::AddPreTargetHandler(ui::EventHandler* handler) {
aura::Env::GetInstance()->AddPreTargetHandler(handler);
}
@@ -86,15 +95,6 @@ bool WMHelperMus::IsMaximizeModeWindowManagerEnabled() const {
return false;
}
-bool WMHelperMus::IsSpokenFeedbackEnabled() const {
- NOTIMPLEMENTED();
- return false;
-}
-
-void WMHelperMus::PlayEarcon(int sound_key) const {
- NOTIMPLEMENTED();
-}
-
void WMHelperMus::OnActiveFocusClientChanged(
aura::client::FocusClient* focus_client,
aura::Window* focus_client_root) {
diff --git a/chromium/components/exo/wm_helper_mus.h b/chromium/components/exo/wm_helper_mus.h
index c1d955834e7..6fda7388396 100644
--- a/chromium/components/exo/wm_helper_mus.h
+++ b/chromium/components/exo/wm_helper_mus.h
@@ -30,20 +30,19 @@ class WMHelperMus : public WMHelper,
~WMHelperMus() override;
// Overridden from WMHelper:
- const display::ManagedDisplayInfo GetDisplayInfo(
+ const display::ManagedDisplayInfo& GetDisplayInfo(
int64_t display_id) const override;
- aura::Window* GetContainer(int container_id) override;
+ aura::Window* GetPrimaryDisplayContainer(int container_id) override;
aura::Window* GetActiveWindow() const override;
aura::Window* GetFocusedWindow() const override;
ui::CursorSetType GetCursorSet() const override;
+ const display::Display& GetCursorDisplay() const override;
void AddPreTargetHandler(ui::EventHandler* handler) override;
void PrependPreTargetHandler(ui::EventHandler* handler) override;
void RemovePreTargetHandler(ui::EventHandler* handler) override;
void AddPostTargetHandler(ui::EventHandler* handler) override;
void RemovePostTargetHandler(ui::EventHandler* handler) override;
bool IsMaximizeModeWindowManagerEnabled() const override;
- bool IsSpokenFeedbackEnabled() const override;
- void PlayEarcon(int sound_key) const override;
// Overridden from aura::FocusSynchronizerObserver:
void OnActiveFocusClientChanged(aura::client::FocusClient* focus_client,
diff --git a/chromium/components/favicon/content/content_favicon_driver.cc b/chromium/components/favicon/content/content_favicon_driver.cc
index d6bbcac5d8f..ece84e5ddac 100644
--- a/chromium/components/favicon/content/content_favicon_driver.cc
+++ b/chromium/components/favicon/content/content_favicon_driver.cc
@@ -5,6 +5,7 @@
#include "components/favicon/content/content_favicon_driver.h"
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "components/favicon/content/favicon_url_util.h"
#include "components/favicon/core/favicon_service.h"
#include "components/favicon/core/favicon_url.h"
@@ -16,11 +17,27 @@
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/common/favicon_url.h"
+#include "content/public/common/manifest.h"
#include "ui/gfx/image/image.h"
DEFINE_WEB_CONTENTS_USER_DATA_KEY(favicon::ContentFaviconDriver);
namespace favicon {
+namespace {
+
+void ExtractManifestIcons(
+ const ContentFaviconDriver::ManifestDownloadCallback& callback,
+ const GURL& manifest_url,
+ const content::Manifest& manifest) {
+ std::vector<FaviconURL> candidates;
+ for (const content::Manifest::Icon& icon : manifest.icons) {
+ candidates.emplace_back(icon.src, favicon_base::WEB_MANIFEST_ICON,
+ icon.sizes);
+ }
+ callback.Run(candidates);
+}
+
+} // namespace
// static
void ContentFaviconDriver::CreateForWebContents(
@@ -32,8 +49,9 @@ void ContentFaviconDriver::CreateForWebContents(
return;
web_contents->SetUserData(
- UserDataKey(), new ContentFaviconDriver(web_contents, favicon_service,
- history_service, bookmark_model));
+ UserDataKey(),
+ base::WrapUnique(new ContentFaviconDriver(
+ web_contents, favicon_service, history_service, bookmark_model)));
}
void ContentFaviconDriver::SaveFavicon() {
@@ -116,6 +134,11 @@ int ContentFaviconDriver::DownloadImage(const GURL& url,
callback);
}
+void ContentFaviconDriver::DownloadManifest(const GURL& url,
+ ManifestDownloadCallback callback) {
+ web_contents()->GetManifest(base::Bind(&ExtractManifestIcons, callback));
+}
+
bool ContentFaviconDriver::IsOffTheRecord() {
DCHECK(web_contents());
return web_contents()->GetBrowserContext()->IsOffTheRecord();
@@ -154,8 +177,31 @@ void ContentFaviconDriver::DidUpdateFaviconURL(
return;
favicon_urls_ = candidates;
- OnUpdateFaviconURL(entry->GetURL(),
- FaviconURLsFromContentFaviconURLs(candidates));
+
+ OnUpdateCandidates(entry->GetURL(),
+ FaviconURLsFromContentFaviconURLs(candidates),
+ manifest_url_);
+}
+
+void ContentFaviconDriver::DidUpdateWebManifestURL(
+ const base::Optional<GURL>& manifest_url) {
+ // Ignore the update if there is no last committed navigation entry. This can
+ // occur when loading an initially blank page.
+ content::NavigationEntry* entry =
+ web_contents()->GetController().GetLastCommittedEntry();
+ if (!entry)
+ return;
+
+ manifest_url_ = manifest_url.value_or(GURL());
+
+ // On regular page loads, DidUpdateManifestURL() is guaranteed to be called
+ // before DidUpdateFaviconURL(). However, a page can update the favicons via
+ // javascript.
+ if (favicon_urls_.has_value()) {
+ OnUpdateCandidates(entry->GetURL(),
+ FaviconURLsFromContentFaviconURLs(*favicon_urls_),
+ manifest_url_);
+ }
}
void ContentFaviconDriver::DidStartNavigation(
@@ -163,6 +209,9 @@ void ContentFaviconDriver::DidStartNavigation(
if (!navigation_handle->IsInMainFrame())
return;
+ favicon_urls_.reset();
+ manifest_url_ = GURL();
+
content::ReloadType reload_type = navigation_handle->GetReloadType();
if (reload_type == content::ReloadType::NONE || IsOffTheRecord())
return;
@@ -181,8 +230,6 @@ void ContentFaviconDriver::DidFinishNavigation(
return;
}
- favicon_urls_.clear();
-
// Wait till the user navigates to a new URL to start checking the cache
// again. The cache may be ignored for non-reload navigations (e.g.
// history.replace() in-page navigation). This is allowed to increase the
diff --git a/chromium/components/favicon/content/content_favicon_driver.h b/chromium/components/favicon/content/content_favicon_driver.h
index 4b1b79b65ad..b768e033ed6 100644
--- a/chromium/components/favicon/content/content_favicon_driver.h
+++ b/chromium/components/favicon/content/content_favicon_driver.h
@@ -6,10 +6,12 @@
#define COMPONENTS_FAVICON_CONTENT_CONTENT_FAVICON_DRIVER_H_
#include "base/macros.h"
+#include "base/optional.h"
#include "components/favicon/core/favicon_driver_impl.h"
#include "content/public/browser/reload_type.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
+#include "content/public/common/favicon_url.h"
#include "url/gurl.h"
namespace content {
@@ -27,6 +29,8 @@ class ContentFaviconDriver
public content::WebContentsUserData<ContentFaviconDriver>,
public FaviconDriverImpl {
public:
+ ~ContentFaviconDriver() override;
+
static void CreateForWebContents(content::WebContents* web_contents,
FaviconService* favicon_service,
history::HistoryService* history_service,
@@ -34,8 +38,8 @@ class ContentFaviconDriver
// Returns the current tab's favicon URLs. If this is empty,
// DidUpdateFaviconURL has not yet been called for the current navigation.
- const std::vector<content::FaviconURL>& favicon_urls() const {
- return favicon_urls_;
+ std::vector<content::FaviconURL> favicon_urls() const {
+ return favicon_urls_.value_or(std::vector<content::FaviconURL>());
}
// Saves the favicon for the last committed navigation entry to the thumbnail
@@ -52,7 +56,6 @@ class ContentFaviconDriver
FaviconService* favicon_service,
history::HistoryService* history_service,
bookmarks::BookmarkModel* bookmark_model);
- ~ContentFaviconDriver() override;
private:
friend class content::WebContentsUserData<ContentFaviconDriver>;
@@ -61,6 +64,8 @@ class ContentFaviconDriver
int DownloadImage(const GURL& url,
int max_image_size,
ImageDownloadCallback callback) override;
+ void DownloadManifest(const GURL& url,
+ ManifestDownloadCallback callback) override;
bool IsOffTheRecord() override;
void OnFaviconUpdated(const GURL& page_url,
FaviconDriverObserver::NotificationIconType icon_type,
@@ -71,13 +76,18 @@ class ContentFaviconDriver
// content::WebContentsObserver implementation.
void DidUpdateFaviconURL(
const std::vector<content::FaviconURL>& candidates) override;
+ void DidUpdateWebManifestURL(
+ const base::Optional<GURL>& manifest_url) override;
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
GURL bypass_cache_page_url_;
- std::vector<content::FaviconURL> favicon_urls_;
+ // nullopt until the actual list is reported via DidUpdateFaviconURL().
+ base::Optional<std::vector<content::FaviconURL>> favicon_urls_;
+ // Web Manifest URL or empty URL if none.
+ GURL manifest_url_;
DISALLOW_COPY_AND_ASSIGN(ContentFaviconDriver);
};
diff --git a/chromium/components/favicon/core/BUILD.gn b/chromium/components/favicon/core/BUILD.gn
index 09b113a7f80..b4d4a79ec5f 100644
--- a/chromium/components/favicon/core/BUILD.gn
+++ b/chromium/components/favicon/core/BUILD.gn
@@ -22,6 +22,8 @@ static_library("core") {
"favicon_url.h",
"favicon_util.cc",
"favicon_util.h",
+ "features.cc",
+ "features.h",
"large_icon_service.cc",
"large_icon_service.h",
]
@@ -69,6 +71,7 @@ source_set("unit_tests") {
"//components/history/core/browser:browser",
"//components/history/core/test:test",
"//components/image_fetcher/core",
+ "//components/variations:test_support",
"//skia",
"//testing/gmock",
"//testing/gtest",
diff --git a/chromium/components/favicon/core/DEPS b/chromium/components/favicon/core/DEPS
index 47c9ad06444..07a7e022c46 100644
--- a/chromium/components/favicon/core/DEPS
+++ b/chromium/components/favicon/core/DEPS
@@ -6,6 +6,7 @@ include_rules = [
"+components/history/core/test",
"+components/image_fetcher/core",
"+components/keyed_service/core",
+ "+components/variations",
"+net/base",
"+skia",
"+third_party/skia",
diff --git a/chromium/components/favicon/core/favicon_driver_impl.cc b/chromium/components/favicon/core/favicon_driver_impl.cc
index f77d11b54a5..891772eaab9 100644
--- a/chromium/components/favicon/core/favicon_driver_impl.cc
+++ b/chromium/components/favicon/core/favicon_driver_impl.cc
@@ -96,13 +96,21 @@ void FaviconDriverImpl::SetFaviconOutOfDateForPage(const GURL& url,
}
}
-void FaviconDriverImpl::OnUpdateFaviconURL(
+void FaviconDriverImpl::OnUpdateCandidates(
const GURL& page_url,
- const std::vector<FaviconURL>& candidates) {
- DCHECK(!candidates.empty());
+ const std::vector<FaviconURL>& candidates,
+ const GURL& manifest_url) {
RecordCandidateMetrics(candidates);
- for (const std::unique_ptr<FaviconHandler>& handler : handlers_)
- handler->OnUpdateFaviconURL(page_url, candidates);
+ for (const std::unique_ptr<FaviconHandler>& handler : handlers_) {
+ // We feed in the Web Manifest URL (if any) to the instance handling type
+ // WEB_MANIFEST_ICON, because those compete which each other (i.e. manifest
+ // icons override inline touch icons).
+ handler->OnUpdateCandidates(
+ page_url, candidates,
+ handler->icon_types() & favicon_base::WEB_MANIFEST_ICON
+ ? manifest_url
+ : GURL::EmptyGURL());
+ }
}
} // namespace favicon
diff --git a/chromium/components/favicon/core/favicon_driver_impl.h b/chromium/components/favicon/core/favicon_driver_impl.h
index 2faa6f3fa9b..a64a9f313f2 100644
--- a/chromium/components/favicon/core/favicon_driver_impl.h
+++ b/chromium/components/favicon/core/favicon_driver_impl.h
@@ -59,8 +59,9 @@ class FaviconDriverImpl : public FaviconDriver,
void SetFaviconOutOfDateForPage(const GURL& url, bool force_reload);
// Broadcasts new favicon URL candidates to FaviconHandlers.
- void OnUpdateFaviconURL(const GURL& page_url,
- const std::vector<FaviconURL>& candidates);
+ void OnUpdateCandidates(const GURL& page_url,
+ const std::vector<FaviconURL>& candidates,
+ const GURL& manifest_url);
protected:
history::HistoryService* history_service() { return history_service_; }
diff --git a/chromium/components/favicon/core/favicon_handler.cc b/chromium/components/favicon/core/favicon_handler.cc
index 738fa28cd48..aa57bfcd22f 100644
--- a/chromium/components/favicon/core/favicon_handler.cc
+++ b/chromium/components/favicon/core/favicon_handler.cc
@@ -11,10 +11,12 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/feature_list.h"
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "components/favicon/core/favicon_service.h"
+#include "components/favicon/core/features.h"
#include "components/favicon_base/favicon_util.h"
#include "components/favicon_base/select_favicon_frames.h"
#include "skia/ext/image_operations.h"
@@ -31,25 +33,6 @@ const int kNonTouchLargestIconSize = 192;
// the apple touch icon for iPad.
const int kTouchIconSize = 144;
-// Returns true if all of the icon URLs and icon types in |bitmap_results| are
-// identical and if they match |icon_url| and |icon_type|. Returns false if
-// |bitmap_results| is empty.
-bool DoUrlsAndIconsMatch(
- const GURL& icon_url,
- favicon_base::IconType icon_type,
- const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) {
- if (bitmap_results.empty())
- return false;
-
- for (const auto& bitmap_result : bitmap_results) {
- if (icon_url != bitmap_result.icon_url ||
- icon_type != bitmap_result.icon_type) {
- return false;
- }
- }
- return true;
-}
-
// Return true if |bitmap_result| is expired.
bool IsExpired(const favicon_base::FaviconRawBitmapResult& bitmap_result) {
return bitmap_result.expired;
@@ -160,6 +143,11 @@ std::vector<int> GetDesiredPixelSizes(
return std::vector<int>();
}
+bool FaviconURLEquals(const FaviconURL& lhs, const FaviconURL& rhs) {
+ return lhs.icon_url == rhs.icon_url && lhs.icon_type == rhs.icon_type &&
+ lhs.icon_sizes == rhs.icon_sizes;
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -198,7 +186,7 @@ FaviconHandler::FaviconHandler(
notification_icon_type_(favicon_base::INVALID_ICON),
service_(service),
delegate_(delegate),
- num_download_requests_(0),
+ num_image_download_requests_(0),
current_candidate_index_(0u) {
DCHECK(delegate_);
}
@@ -214,24 +202,29 @@ int FaviconHandler::GetIconTypesFromHandlerType(
case FaviconDriverObserver::NON_TOUCH_LARGEST:
return favicon_base::FAVICON;
case FaviconDriverObserver::TOUCH_LARGEST:
- return favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON;
+ return favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON |
+ favicon_base::WEB_MANIFEST_ICON;
}
return 0;
}
void FaviconHandler::FetchFavicon(const GURL& url) {
- cancelable_task_tracker_.TryCancelAll();
+ cancelable_task_tracker_for_page_url_.TryCancelAll();
+ cancelable_task_tracker_for_candidates_.TryCancelAll();
url_ = url;
initial_history_result_expired_or_incomplete_ = false;
redownload_icons_ = false;
got_favicon_from_history_ = false;
- download_request_.Cancel();
+ manifest_download_request_.Cancel();
+ image_download_request_.Cancel();
+ manifest_url_ = GURL();
+ non_manifest_original_candidates_.clear();
candidates_.clear();
notification_icon_url_ = GURL();
notification_icon_type_ = favicon_base::INVALID_ICON;
- num_download_requests_ = 0;
+ num_image_download_requests_ = 0;
current_candidate_index_ = 0u;
best_favicon_ = DownloadedFavicon();
@@ -242,7 +235,7 @@ void FaviconHandler::FetchFavicon(const GURL& url) {
url_, icon_types_, preferred_icon_size(),
base::Bind(&FaviconHandler::OnFaviconDataForInitialURLFromFaviconService,
base::Unretained(this)),
- &cancelable_task_tracker_);
+ &cancelable_task_tracker_for_page_url_);
}
bool FaviconHandler::UpdateFaviconCandidate(
@@ -282,8 +275,7 @@ void FaviconHandler::SetFavicon(const GURL& icon_url,
void FaviconHandler::NotifyFaviconUpdated(
const std::vector<favicon_base::FaviconRawBitmapResult>&
favicon_bitmap_results) {
- if (favicon_bitmap_results.empty())
- return;
+ DCHECK(!favicon_bitmap_results.empty());
gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs(
favicon_bitmap_results,
@@ -314,12 +306,114 @@ void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url,
notification_icon_type_ = icon_type;
}
-void FaviconHandler::OnUpdateFaviconURL(
+void FaviconHandler::OnUpdateCandidates(
const GURL& page_url,
- const std::vector<FaviconURL>& candidates) {
+ const std::vector<FaviconURL>& candidates,
+ const GURL& manifest_url) {
if (page_url != url_)
return;
+ bool manifests_feature_enabled =
+ base::FeatureList::IsEnabled(kFaviconsFromWebManifest);
+
+ // |candidates| or |manifest_url| could have been modified via Javascript. If
+ // neither changed, ignore the call.
+ if ((!manifests_feature_enabled || manifest_url_ == manifest_url) &&
+ non_manifest_original_candidates_.size() == candidates.size() &&
+ std::equal(candidates.begin(), candidates.end(),
+ non_manifest_original_candidates_.begin(),
+ &FaviconURLEquals)) {
+ return;
+ }
+
+ non_manifest_original_candidates_ = candidates;
+ cancelable_task_tracker_for_candidates_.TryCancelAll();
+ manifest_download_request_.Cancel();
+ image_download_request_.Cancel();
+ num_image_download_requests_ = 0;
+ current_candidate_index_ = 0u;
+ best_favicon_ = DownloadedFavicon();
+
+ if (manifests_feature_enabled)
+ manifest_url_ = manifest_url;
+
+ // Check if the manifest was previously blacklisted (e.g. returned a 404) and
+ // ignore the manifest URL if that's the case.
+ if (!manifest_url_.is_empty() &&
+ service_->WasUnableToDownloadFavicon(manifest_url_)) {
+ DVLOG(1) << "Skip failed Manifest: " << manifest_url;
+ manifest_url_ = GURL();
+ }
+
+ // If no manifest available, proceed with the regular candidates only.
+ if (manifest_url_.is_empty()) {
+ OnGotFinalIconURLCandidates(candidates);
+ return;
+ }
+
+ // See if there is a cached favicon for the manifest. This will update the DB
+ // mappings only if the manifest URL is cached.
+ GetFaviconAndUpdateMappingsUnlessIncognito(
+ /*icon_url=*/manifest_url_, favicon_base::WEB_MANIFEST_ICON,
+ base::Bind(&FaviconHandler::OnFaviconDataForManifestFromFaviconService,
+ base::Unretained(this)));
+}
+
+void FaviconHandler::OnFaviconDataForManifestFromFaviconService(
+ const std::vector<favicon_base::FaviconRawBitmapResult>&
+ favicon_bitmap_results) {
+ // The database lookup for the page URL is guaranteed to be completed because
+ // the HistoryBackend uses a SequencedTaskRunner, and we also know that
+ // FetchFavicon() was called before OnUpdateCandidates().
+ DCHECK(got_favicon_from_history_);
+
+ bool has_valid_result = HasValidResult(favicon_bitmap_results);
+ bool has_expired_or_incomplete_result =
+ !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(),
+ favicon_bitmap_results);
+
+ if (has_valid_result &&
+ (notification_icon_url_ != manifest_url_ ||
+ notification_icon_type_ != favicon_base::WEB_MANIFEST_ICON)) {
+ // There is a valid favicon. Notify any observers. It is useful to notify
+ // the observers even if the favicon is expired or incomplete (incorrect
+ // size) because temporarily showing the user an expired favicon or
+ // streched favicon is preferable to showing the user the default favicon.
+ NotifyFaviconUpdated(favicon_bitmap_results);
+ }
+
+ if (has_expired_or_incomplete_result) {
+ manifest_download_request_.Reset(base::Bind(
+ &FaviconHandler::OnDidDownloadManifest, base::Unretained(this)));
+ delegate_->DownloadManifest(manifest_url_,
+ manifest_download_request_.callback());
+ }
+}
+
+void FaviconHandler::OnDidDownloadManifest(
+ const std::vector<FaviconURL>& candidates) {
+ // Mark manifest download as finished.
+ manifest_download_request_.Cancel();
+
+ if (!candidates.empty()) {
+ OnGotFinalIconURLCandidates(candidates);
+ return;
+ }
+
+ // If either the downloading of the manifest failed, OR the manifest contains
+ // no icons, proceed with the list of icons listed in the HTML.
+ DVLOG(1) << "Could not fetch Manifest icons from " << manifest_url_
+ << ", falling back to inlined ones, which are "
+ << non_manifest_original_candidates_.size();
+
+ service_->UnableToDownloadFavicon(manifest_url_);
+ manifest_url_ = GURL();
+
+ OnGotFinalIconURLCandidates(non_manifest_original_candidates_);
+}
+
+void FaviconHandler::OnGotFinalIconURLCandidates(
+ const std::vector<FaviconURL>& candidates) {
std::vector<FaviconCandidate> sorted_candidates;
const std::vector<int> desired_pixel_sizes =
GetDesiredPixelSizes(handler_type_);
@@ -333,17 +427,7 @@ void FaviconHandler::OnUpdateFaviconURL(
std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(),
&FaviconCandidate::CompareScore);
- if (candidates_.size() == sorted_candidates.size() &&
- std::equal(sorted_candidates.begin(), sorted_candidates.end(),
- candidates_.begin())) {
- return;
- }
-
- download_request_.Cancel();
candidates_ = std::move(sorted_candidates);
- num_download_requests_ = 0;
- current_candidate_index_ = 0u;
- best_favicon_ = DownloadedFavicon();
// TODO(davemoore) Should clear on empty url. Currently we ignore it.
// This appears to be what FF does as well.
@@ -386,7 +470,7 @@ void FaviconHandler::OnDidDownloadFavicon(
const std::vector<SkBitmap>& bitmaps,
const std::vector<gfx::Size>& original_bitmap_sizes) {
// Mark download as finished.
- download_request_.Cancel();
+ image_download_request_.Cancel();
if (bitmaps.empty() && http_status_code == 404) {
DVLOG(1) << "Failed to Download Favicon:" << image_url;
@@ -432,17 +516,22 @@ void FaviconHandler::OnDidDownloadFavicon(
DownloadCurrentCandidateOrAskFaviconService();
} else {
// OnDidDownloadFavicon() can only be called after requesting a download, so
- // |num_download_requests_| can never be 0.
- RecordDownloadAttemptsForHandlerType(handler_type_, num_download_requests_);
+ // |num_image_download_requests_| can never be 0.
+ RecordDownloadAttemptsForHandlerType(handler_type_,
+ num_image_download_requests_);
// We have either found the ideal candidate or run out of candidates.
if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) {
- // No more icons to request, set the favicon from the candidate.
- SetFavicon(best_favicon_.candidate.icon_url, best_favicon_.image,
- best_favicon_.candidate.icon_type);
+ // No more icons to request, set the favicon from the candidate. The
+ // manifest URL, if available, is used instead of the icon URL.
+ SetFavicon(manifest_url_.is_empty() ? best_favicon_.candidate.icon_url
+ : manifest_url_,
+ best_favicon_.image,
+ manifest_url_.is_empty() ? best_favicon_.candidate.icon_type
+ : favicon_base::WEB_MANIFEST_ICON);
}
// Clear download related state.
current_candidate_index_ = candidates_.size();
- num_download_requests_ = 0;
+ num_image_download_requests_ = 0;
best_favicon_ = DownloadedFavicon();
}
}
@@ -455,8 +544,10 @@ const std::vector<GURL> FaviconHandler::GetIconURLs() const {
}
bool FaviconHandler::HasPendingTasksForTest() {
- return !download_request_.IsCancelled() ||
- cancelable_task_tracker_.HasTrackedTasks();
+ return !image_download_request_.IsCancelled() ||
+ !manifest_download_request_.IsCancelled() ||
+ cancelable_task_tracker_for_page_url_.HasTrackedTasks() ||
+ cancelable_task_tracker_for_candidates_.HasTrackedTasks();
}
bool FaviconHandler::ShouldSaveFavicon() {
@@ -479,14 +570,11 @@ void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService(
redownload_icons_ = initial_history_result_expired_or_incomplete_ &&
!favicon_bitmap_results.empty();
- if (has_valid_result && (!current_candidate() ||
- DoUrlsAndIconsMatch(current_candidate()->icon_url,
- current_candidate()->icon_type,
- favicon_bitmap_results))) {
- // The db knows the favicon (although it may be out of date) and the entry
- // doesn't have an icon. Set the favicon now, and if the favicon turns out
- // to be expired (or the wrong url) we'll fetch later on. This way the
- // user doesn't see a flash of the default favicon.
+ if (has_valid_result) {
+ // The db knows the favicon (although it may be out of date). Set the
+ // favicon now, and if the favicon turns out to be expired (or the wrong
+ // url) we'll fetch later on. This way the user doesn't see a flash of the
+ // default favicon.
NotifyFaviconUpdated(favicon_bitmap_results);
}
@@ -495,40 +583,45 @@ void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService(
}
void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() {
- GURL icon_url = current_candidate()->icon_url;
- favicon_base::IconType icon_type = current_candidate()->icon_type;
-
- if (redownload_icons_) {
+ const GURL icon_url = current_candidate()->icon_url;
+ const favicon_base::IconType icon_type = current_candidate()->icon_type;
+ // If the icons listed in a manifest are being processed, skip the cache
+ // lookup for |icon_url| since the manifest's URL is used for caching, not the
+ // icon URL, and this lookup has happened earlier.
+ if (redownload_icons_ || !manifest_url_.is_empty()) {
// We have the mapping, but the favicon is out of date. Download it now.
- ScheduleDownload(icon_url, icon_type);
+ ScheduleImageDownload(icon_url, icon_type);
} else {
- // We don't know the favicon, but we may have previously downloaded the
- // favicon for another page that shares the same favicon. Ask for the
- // favicon given the favicon URL.
- if (delegate_->IsOffTheRecord()) {
- service_->GetFavicon(
- icon_url, icon_type, preferred_icon_size(),
- base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
- &cancelable_task_tracker_);
- } else {
- // Ask the history service for the icon. This does two things:
- // 1. Attempts to fetch the favicon data from the database.
- // 2. If the favicon exists in the database, this updates the database to
- // include the mapping between the page url and the favicon url.
- // This is asynchronous. The history service will call back when done.
- // TODO(pkotwicz): pass in all of |image_urls_| to
- // UpdateFaviconMappingsAndFetch().
- service_->UpdateFaviconMappingsAndFetch(
- url_, {icon_url}, icon_type, preferred_icon_size(),
- base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
- &cancelable_task_tracker_);
- }
+ GetFaviconAndUpdateMappingsUnlessIncognito(
+ icon_url, icon_type,
+ base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)));
+ }
+}
+
+void FaviconHandler::GetFaviconAndUpdateMappingsUnlessIncognito(
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
+ const favicon_base::FaviconResultsCallback& callback) {
+ // We don't know the favicon, but we may have previously downloaded the
+ // favicon for another page that shares the same favicon. Ask for the
+ // favicon given the favicon URL.
+ if (delegate_->IsOffTheRecord()) {
+ service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback,
+ &cancelable_task_tracker_for_candidates_);
+ } else {
+ // Ask the history service for the icon. This does two things:
+ // 1. Attempts to fetch the favicon data from the database.
+ // 2. If the favicon exists in the database, this updates the database to
+ // include the mapping between the page url and the favicon url.
+ // This is asynchronous. The history service will call back when done.
+ service_->UpdateFaviconMappingsAndFetch(
+ url_, icon_url, icon_type, preferred_icon_size(), callback,
+ &cancelable_task_tracker_for_candidates_);
}
}
void FaviconHandler::OnFaviconData(const std::vector<
favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) {
- bool has_results = !favicon_bitmap_results.empty();
bool has_valid_result = HasValidResult(favicon_bitmap_results);
bool has_expired_or_incomplete_result =
!has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(),
@@ -542,27 +635,21 @@ void FaviconHandler::OnFaviconData(const std::vector<
NotifyFaviconUpdated(favicon_bitmap_results);
}
- if (!current_candidate() ||
- (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url,
- current_candidate()->icon_type,
- favicon_bitmap_results))) {
- // The icon URLs have been updated since the favicon data was requested.
- return;
- }
-
if (has_expired_or_incomplete_result) {
- ScheduleDownload(current_candidate()->icon_url,
- current_candidate()->icon_type);
- } else if (num_download_requests_ > 0) {
- RecordDownloadAttemptsForHandlerType(handler_type_, num_download_requests_);
+ ScheduleImageDownload(current_candidate()->icon_url,
+ current_candidate()->icon_type);
+ } else if (num_image_download_requests_ > 0) {
+ RecordDownloadAttemptsForHandlerType(handler_type_,
+ num_image_download_requests_);
}
}
-void FaviconHandler::ScheduleDownload(const GURL& image_url,
- favicon_base::IconType icon_type) {
+void FaviconHandler::ScheduleImageDownload(const GURL& image_url,
+ favicon_base::IconType icon_type) {
DCHECK(image_url.is_valid());
// Note that CancelableCallback starts cancelled.
- DCHECK(download_request_.IsCancelled()) << "More than one ongoing download";
+ DCHECK(image_download_request_.IsCancelled())
+ << "More than one ongoing download";
if (service_->WasUnableToDownloadFavicon(image_url)) {
DVLOG(1) << "Skip Failed FavIcon: " << image_url;
RecordDownloadOutcome(DownloadOutcome::SKIPPED);
@@ -570,15 +657,16 @@ void FaviconHandler::ScheduleDownload(const GURL& image_url,
std::vector<gfx::Size>());
return;
}
- ++num_download_requests_;
- download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon,
- base::Unretained(this), icon_type));
+ ++num_image_download_requests_;
+ image_download_request_.Reset(
+ base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this),
+ icon_type));
// A max bitmap size is specified to avoid receiving huge bitmaps in
// OnDidDownloadFavicon(). See FaviconDriver::StartDownload()
// for more details about the max bitmap size.
const int download_id =
delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_),
- download_request_.callback());
+ image_download_request_.callback());
DCHECK_NE(download_id, 0);
}
diff --git a/chromium/components/favicon/core/favicon_handler.h b/chromium/components/favicon/core/favicon_handler.h
index 30c0b1df498..5b4c7aa3bab 100644
--- a/chromium/components/favicon/core/favicon_handler.h
+++ b/chromium/components/favicon/core/favicon_handler.h
@@ -99,6 +99,10 @@ class FaviconHandler {
const std::vector<gfx::Size>& original_bitmap_sizes)>
ImageDownloadCallback;
+ typedef base::Callback<void(
+ const std::vector<favicon::FaviconURL>& favicons)>
+ ManifestDownloadCallback;
+
// Starts the download for the given favicon. When finished, the callback
// is called with the results. Returns the unique id of the download
// request, which will also be passed to the callback. In case of error, 0
@@ -111,6 +115,10 @@ class FaviconHandler {
int max_image_size,
ImageDownloadCallback callback) = 0;
+ // Downloads a WebManifest and returns the favicons listed there.
+ virtual void DownloadManifest(const GURL& url,
+ ManifestDownloadCallback callback) = 0;
+
// Returns whether the user is operating in an off-the-record context.
virtual bool IsOffTheRecord() = 0;
@@ -137,10 +145,15 @@ class FaviconHandler {
// Initiates loading the favicon for the specified url.
void FetchFavicon(const GURL& url);
- // Message Handler. Must be public, because also called from
- // PrerenderContents. Collects the |image_urls| list.
- void OnUpdateFaviconURL(const GURL& page_url,
- const std::vector<favicon::FaviconURL>& candidates);
+ // Collects the candidate favicons as listed in the HTML head, as well as
+ // the WebManifest URL if available (or empty URL otherwise).
+ void OnUpdateCandidates(const GURL& page_url,
+ const std::vector<favicon::FaviconURL>& candidates,
+ const GURL& manifest_url);
+
+ // Returns the supported icon types, inferred from the handler type as passed
+ // in the constructor.
+ int icon_types() const { return icon_types_; }
// For testing.
const std::vector<GURL> GetIconURLs() const;
@@ -161,12 +174,6 @@ class FaviconHandler {
const favicon::FaviconURL& favicon_url,
const std::vector<int>& desired_pixel_sizes);
- friend bool operator==(const FaviconCandidate& lhs,
- const FaviconCandidate& rhs) {
- return lhs.icon_url == rhs.icon_url && lhs.icon_type == rhs.icon_type &&
- lhs.score == rhs.score;
- }
-
// Compare function used for std::stable_sort to sort in descending order.
static bool CompareScore(const FaviconCandidate& lhs,
const FaviconCandidate& rhs) {
@@ -187,6 +194,20 @@ class FaviconHandler {
static int GetIconTypesFromHandlerType(
FaviconDriverObserver::NotificationIconType handler_type);
+ // Called with the result of looking up cached icon data for the manifest's
+ // URL, which is used as icon URL.
+ void OnFaviconDataForManifestFromFaviconService(
+ const std::vector<favicon_base::FaviconRawBitmapResult>&
+ favicon_bitmap_results);
+
+ // Called when the dowloading of a manifest completes.
+ void OnDidDownloadManifest(const std::vector<FaviconURL>& candidates);
+
+ // Called when the actual list of favicon candidates to be processed is
+ // available, which can be either icon URLs listed in the HTML head instead
+ // or, if a Web Manifest was provided, the list of icons there.
+ void OnGotFinalIconURLCandidates(const std::vector<FaviconURL>& candidates);
+
// Called when the history request for favicon data mapped to |url_| has
// completed and the renderer has told us the icon URLs used by |url_|
void OnGotInitialHistoryDataAndIconURLCandidates();
@@ -201,14 +222,21 @@ class FaviconHandler {
// OnFaviconData() is called with the history data once it has been retrieved.
void DownloadCurrentCandidateOrAskFaviconService();
+ // Requests the favicon for |icon_url| from the favicon service. Unless in
+ // incognito, it also updates the page URL (url_) to |icon_url| mappings.
+ void GetFaviconAndUpdateMappingsUnlessIncognito(
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
+ const favicon_base::FaviconResultsCallback& callback);
+
// See description above class for details.
void OnFaviconData(const std::vector<favicon_base::FaviconRawBitmapResult>&
favicon_bitmap_results);
// Schedules a download for the specified entry. This adds the request to
- // download_requests_.
- void ScheduleDownload(const GURL& image_url,
- favicon_base::IconType icon_type);
+ // image_download_requests_.
+ void ScheduleImageDownload(const GURL& image_url,
+ favicon_base::IconType icon_type);
// Triggered when a download of an image has finished.
void OnDidDownloadFavicon(
@@ -255,10 +283,15 @@ class FaviconHandler {
return download_largest_icon_ ? 0 : gfx::kFaviconSize;
}
- // Used for FaviconService requests.
- base::CancelableTaskTracker cancelable_task_tracker_;
+ // Used for the GetFaviconForPageURL() request looking up the page URL,
+ // triggered in FetchFavicon().
+ base::CancelableTaskTracker cancelable_task_tracker_for_page_url_;
- FaviconDriverObserver::NotificationIconType handler_type_;
+ // Used for various FaviconService methods triggered while processing
+ // candidates.
+ base::CancelableTaskTracker cancelable_task_tracker_for_candidates_;
+
+ const FaviconDriverObserver::NotificationIconType handler_type_;
// URL of the page we're requesting the favicon for.
GURL url_;
@@ -278,9 +311,13 @@ class FaviconHandler {
// |image_urls_| one by one.
bool redownload_icons_;
+ // Requests to the renderer to download a manifest.
+ base::CancelableCallback<Delegate::ManifestDownloadCallback::RunType>
+ manifest_download_request_;
+
// Requests to the renderer to download favicons.
base::CancelableCallback<Delegate::ImageDownloadCallback::RunType>
- download_request_;
+ image_download_request_;
// The combination of the supported icon types.
const int icon_types_;
@@ -288,6 +325,14 @@ class FaviconHandler {
// Whether the largest icon should be downloaded.
const bool download_largest_icon_;
+ // The manifest URL from the renderer (or empty URL if none).
+ GURL manifest_url_;
+
+ // Original list of candidates provided to OnUpdateCandidates(), stored to
+ // be able to fall back to, in case a manifest was provided and downloading it
+ // failed (or provided no icons).
+ std::vector<FaviconURL> non_manifest_original_candidates_;
+
// The prioritized favicon candidates from the page back from the renderer.
std::vector<FaviconCandidate> candidates_;
@@ -305,7 +350,7 @@ class FaviconHandler {
// Captures the number of download requests that were initiated for the
// current url_.
- int num_download_requests_;
+ int num_image_download_requests_;
// The index of the favicon URL in |image_urls_| which is currently being
// requested from history or downloaded.
diff --git a/chromium/components/favicon/core/favicon_handler_unittest.cc b/chromium/components/favicon/core/favicon_handler_unittest.cc
index 4a997f38247..be6a075c140 100644
--- a/chromium/components/favicon/core/favicon_handler_unittest.cc
+++ b/chromium/components/favicon/core/favicon_handler_unittest.cc
@@ -13,15 +13,19 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/test/test_simple_task_runner.h"
#include "components/favicon/core/favicon_driver.h"
+#include "components/favicon/core/features.h"
#include "components/favicon/core/test/mock_favicon_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/layout.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/favicon_size.h"
@@ -34,11 +38,15 @@ using favicon_base::FAVICON;
using favicon_base::FaviconRawBitmapResult;
using favicon_base::TOUCH_ICON;
using favicon_base::TOUCH_PRECOMPOSED_ICON;
+using favicon_base::WEB_MANIFEST_ICON;
+using testing::AnyNumber;
using testing::Assign;
+using testing::Contains;
using testing::ElementsAre;
using testing::InSequence;
using testing::Invoke;
using testing::IsEmpty;
+using testing::Not;
using testing::Return;
using testing::_;
@@ -53,25 +61,35 @@ MATCHER_P2(ImageSizeIs, width, height, "") {
return arg.Size() == gfx::Size(width, height);
}
-// Fill the given bmp with some test data.
-SkBitmap CreateBitmapWithEdgeSize(int size) {
- SkBitmap bmp;
- bmp.allocN32Pixels(size, size);
+// |arg| is a gfx::Image.
+MATCHER_P(ImageColorIs, expected_color, "") {
+ SkBitmap bitmap = arg.AsBitmap();
+ if (bitmap.empty()) {
+ *result_listener << "expected color but no bitmap data available";
+ return false;
+ }
- unsigned char* src_data =
- reinterpret_cast<unsigned char*>(bmp.getAddr32(0, 0));
- for (int i = 0; i < size * size; i++) {
- src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255);
- src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255);
- src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255);
- src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255);
+ SkColor actual_color = bitmap.getColor(1, 1);
+ if (actual_color != expected_color) {
+ *result_listener << "expected color "
+ << base::StringPrintf("%08X", expected_color)
+ << " but actual color is "
+ << base::StringPrintf("%08X", actual_color);
+ return false;
}
+ return true;
+}
+
+SkBitmap CreateBitmapWithEdgeSize(int size, SkColor color) {
+ SkBitmap bmp;
+ bmp.allocN32Pixels(size, size);
+ bmp.eraseColor(color);
return bmp;
}
// Fill the given data buffer with valid png data.
-std::vector<unsigned char> FillBitmapWithEdgeSize(int size) {
- SkBitmap bitmap = CreateBitmapWithEdgeSize(size);
+std::vector<unsigned char> FillBitmapWithEdgeSize(int size, SkColor color) {
+ SkBitmap bitmap = CreateBitmapWithEdgeSize(size, color);
std::vector<unsigned char> output;
gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &output);
return output;
@@ -81,9 +99,10 @@ std::vector<FaviconRawBitmapResult> CreateRawBitmapResult(
const GURL& icon_url,
favicon_base::IconType icon_type = FAVICON,
bool expired = false,
- int edge_size = gfx::kFaviconSize) {
+ int edge_size = gfx::kFaviconSize,
+ SkColor color = SK_ColorRED) {
scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
- data->data() = FillBitmapWithEdgeSize(edge_size);
+ data->data() = FillBitmapWithEdgeSize(edge_size, color);
FaviconRawBitmapResult bitmap_result;
bitmap_result.expired = expired;
bitmap_result.bitmap_data = data;
@@ -104,14 +123,16 @@ class FakeImageDownloader {
SizeVector original_bitmap_sizes;
};
- FakeImageDownloader() : next_download_id_(1) {}
+ // |downloads| must not be nullptr and must outlive this object.
+ FakeImageDownloader(URLVector* downloads)
+ : downloads_(downloads), next_download_id_(1) {}
// Implementation of FaviconHalder::Delegate's DownloadImage(). If a given
// URL is not known (i.e. not previously added via Add()), it produces 404s.
int DownloadImage(const GURL& url,
int max_image_size,
FaviconHandler::Delegate::ImageDownloadCallback callback) {
- downloads_.push_back(url);
+ downloads_->push_back(url);
const Response& response = responses_[url];
int download_id = next_download_id_++;
@@ -119,29 +140,31 @@ class FakeImageDownloader {
base::Bind(callback, download_id, response.http_status_code, url,
response.bitmaps, response.original_bitmap_sizes);
if (url == manual_callback_url_)
- manual_callback_ = bound_callback;
+ manual_callbacks_.push_back(bound_callback);
else
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, bound_callback);
return download_id;
}
- void Add(const GURL& icon_url, const IntVector& sizes) {
- AddWithOriginalSizes(icon_url, sizes, sizes);
- }
-
- void AddWithOriginalSizes(const GURL& icon_url,
- const IntVector& sizes,
- const IntVector& original_sizes) {
+ void Add(const GURL& icon_url,
+ const IntVector& sizes,
+ const IntVector& original_sizes,
+ SkColor color) {
DCHECK_EQ(sizes.size(), original_sizes.size());
Response response;
response.http_status_code = 200;
for (int size : sizes) {
response.original_bitmap_sizes.push_back(gfx::Size(size, size));
- response.bitmaps.push_back(CreateBitmapWithEdgeSize(size));
+ response.bitmaps.push_back(CreateBitmapWithEdgeSize(size, color));
}
responses_[icon_url] = response;
}
+ // Simpler overload of the function above.
+ void Add(const GURL& icon_url, const IntVector& sizes) {
+ Add(icon_url, sizes, sizes, SK_ColorRED);
+ }
+
void AddError(const GURL& icon_url, int http_status_code) {
Response response;
response.http_status_code = http_status_code;
@@ -150,41 +173,34 @@ class FakeImageDownloader {
// Disables automatic callback for |url|. This is useful for emulating a
// download taking a long time. The callback for DownloadImage() will be
- // stored in |manual_callback_|.
+ // stored in |manual_callbacks_|.
void SetRunCallbackManuallyForUrl(const GURL& url) {
manual_callback_url_ = url;
}
// Returns whether an ongoing download exists for a url previously selected
// via SetRunCallbackManuallyForUrl().
- bool HasPendingManualCallback() { return !manual_callback_.is_null(); }
+ bool HasPendingManualCallback() { return !manual_callbacks_.empty(); }
- // Triggers the response for a download previously selected for manual
- // triggering via SetRunCallbackManuallyForUrl().
+ // Triggers responses for downloads previously selected for manual triggering
+ // via SetRunCallbackManuallyForUrl().
bool RunCallbackManually() {
if (!HasPendingManualCallback())
return false;
- manual_callback_.Run();
- manual_callback_.Reset();
+ for (base::Closure& callback : std::move(manual_callbacks_))
+ callback.Run();
return true;
}
- // Returns pending and completed download URLs.
- const URLVector& downloads() const { return downloads_; }
-
- void ClearDownloads() { downloads_.clear(); }
-
private:
+ URLVector* downloads_;
int next_download_id_;
- // Pending and completed download URLs.
- URLVector downloads_;
-
// URL to disable automatic callbacks for.
GURL manual_callback_url_;
// Callback for DownloadImage() request for |manual_callback_url_|.
- base::Closure manual_callback_;
+ std::vector<base::Closure> manual_callbacks_;
// Registered responses.
std::map<GURL, Response> responses_;
@@ -192,19 +208,100 @@ class FakeImageDownloader {
DISALLOW_COPY_AND_ASSIGN(FakeImageDownloader);
};
+// Fake that implements the calls to FaviconHandler::Delegate's
+// DownloadManifest(), delegated to this class through MockDelegate.
+class FakeManifestDownloader {
+ public:
+ struct Response {
+ std::vector<favicon::FaviconURL> favicon_urls;
+ };
+
+ // |downloads| must not be nullptr and must outlive this object.
+ FakeManifestDownloader(URLVector* downloads) : downloads_(downloads) {}
+
+ // Implementation of FaviconHalder::Delegate's DownloadManifest(). If a given
+ // URL is not known (i.e. not previously added via Add()), it produces 404s.
+ void DownloadManifest(
+ const GURL& url,
+ FaviconHandler::Delegate::ManifestDownloadCallback callback) {
+ downloads_->push_back(url);
+
+ const Response& response = responses_[url];
+ base::Closure bound_callback = base::Bind(callback, response.favicon_urls);
+ if (url == manual_callback_url_)
+ manual_callbacks_.push_back(bound_callback);
+ else
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, bound_callback);
+ }
+
+ void Add(const GURL& manifest_url,
+ const std::vector<favicon::FaviconURL>& favicon_urls) {
+ Response response;
+ response.favicon_urls = favicon_urls;
+ responses_[manifest_url] = response;
+ }
+
+ void AddError(const GURL& manifest_url) {
+ responses_[manifest_url] = Response();
+ }
+
+ // Disables automatic callback for |url|. This is useful for emulating a
+ // download taking a long time. The callback for DownloadManifest() will be
+ // stored in |manual_callback_|.
+ void SetRunCallbackManuallyForUrl(const GURL& url) {
+ manual_callback_url_ = url;
+ }
+
+ // Returns whether an ongoing download exists for a url previously selected
+ // via SetRunCallbackManuallyForUrl().
+ bool HasPendingManualCallback() { return !manual_callbacks_.empty(); }
+
+ // Triggers responses for downloads previously selected for manual triggering
+ // via SetRunCallbackManuallyForUrl().
+ bool RunCallbackManually() {
+ if (!HasPendingManualCallback())
+ return false;
+ for (base::Closure& callback : std::move(manual_callbacks_))
+ callback.Run();
+ return true;
+ }
+
+ private:
+ URLVector* downloads_;
+
+ // URL to disable automatic callbacks for.
+ GURL manual_callback_url_;
+
+ // Callback for DownloadManifest() request for |manual_callback_url_|.
+ std::vector<base::Closure> manual_callbacks_;
+
+ // Registered responses.
+ std::map<GURL, Response> responses_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeManifestDownloader);
+};
+
class MockDelegate : public FaviconHandler::Delegate {
public:
- MockDelegate() {
+ MockDelegate()
+ : fake_image_downloader_(&downloads_),
+ fake_manifest_downloader_(&downloads_) {
// Delegate image downloading to FakeImageDownloader.
ON_CALL(*this, DownloadImage(_, _, _))
- .WillByDefault(
- Invoke(&fake_downloader_, &FakeImageDownloader::DownloadImage));
+ .WillByDefault(Invoke(&fake_image_downloader_,
+ &FakeImageDownloader::DownloadImage));
+ // Delegate manifest downloading to FakeManifestDownloader.
+ ON_CALL(*this, DownloadManifest(_, _))
+ .WillByDefault(Invoke(&fake_manifest_downloader_,
+ &FakeManifestDownloader::DownloadManifest));
}
MOCK_METHOD3(DownloadImage,
int(const GURL& url,
int max_image_size,
ImageDownloadCallback callback));
+ MOCK_METHOD2(DownloadManifest,
+ void(const GURL& url, ManifestDownloadCallback callback));
MOCK_METHOD0(IsOffTheRecord, bool());
MOCK_METHOD1(IsBookmarked, bool(const GURL& url));
MOCK_METHOD5(OnFaviconUpdated,
@@ -214,14 +311,24 @@ class MockDelegate : public FaviconHandler::Delegate {
bool icon_url_changed,
const gfx::Image& image));
- FakeImageDownloader& fake_downloader() { return fake_downloader_; }
+ FakeImageDownloader& fake_image_downloader() {
+ return fake_image_downloader_;
+ }
+
+ FakeManifestDownloader& fake_manifest_downloader() {
+ return fake_manifest_downloader_;
+ }
+
+ // Returns pending and completed download URLs.
+ const URLVector& downloads() const { return downloads_; }
- // Convenience getter for test readability. Returns pending and completed
- // download URLs.
- const URLVector& downloads() const { return fake_downloader_.downloads(); }
+ void ClearDownloads() { downloads_.clear(); }
private:
- FakeImageDownloader fake_downloader_;
+ // Pending and completed download URLs.
+ URLVector downloads_;
+ FakeImageDownloader fake_image_downloader_;
+ FakeManifestDownloader fake_manifest_downloader_;
};
// FakeFaviconService mimics a FaviconService backend that allows setting up
@@ -229,7 +336,8 @@ class MockDelegate : public FaviconHandler::Delegate {
// particular URL, the callback is called with empty database results.
class FakeFaviconService {
public:
- FakeFaviconService() = default;
+ FakeFaviconService()
+ : manual_callback_task_runner_(new base::TestSimpleTaskRunner()) {}
// Stores favicon with bitmap data in |results| at |page_url| and |icon_url|.
void Store(const GURL& page_url,
@@ -264,13 +372,34 @@ class FakeFaviconService {
base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
int desired_size_in_dip,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker) {
- CHECK_EQ(1U, icon_urls.size()) << "Multi-icon lookup not implemented";
- return GetFaviconForPageOrIconURL(icon_urls.front(), callback, tracker);
+ return GetFaviconForPageOrIconURL(icon_url, callback, tracker);
+ }
+
+ // Disables automatic callback for |url|. This is useful for emulating a
+ // DB lookup taking a long time. The callback for
+ // GetFaviconForPageOrIconURL() will be stored in |manual_callback_|.
+ void SetRunCallbackManuallyForUrl(const GURL& url) {
+ manual_callback_url_ = url;
+ }
+
+ // Returns whether an ongoing lookup exists for a url previously selected
+ // via SetRunCallbackManuallyForUrl().
+ bool HasPendingManualCallback() {
+ return manual_callback_task_runner_->HasPendingTask();
+ }
+
+ // Triggers the response for a lookup previously selected for manual
+ // triggering via SetRunCallbackManuallyForUrl().
+ bool RunCallbackManually() {
+ if (!HasPendingManualCallback())
+ return false;
+ manual_callback_task_runner_->RunPendingTasks();
+ return true;
}
private:
@@ -280,14 +409,31 @@ class FakeFaviconService {
base::CancelableTaskTracker* tracker) {
db_requests_.push_back(page_or_icon_url);
- return tracker->PostTask(base::ThreadTaskRunnerHandle::Get().get(),
- FROM_HERE,
- base::Bind(callback, results_[page_or_icon_url]));
+ base::Closure bound_callback =
+ base::Bind(callback, results_[page_or_icon_url]);
+
+ if (page_or_icon_url != manual_callback_url_) {
+ return tracker->PostTask(base::ThreadTaskRunnerHandle::Get().get(),
+ FROM_HERE, bound_callback);
+ }
+
+ // We use PostTaskAndReply() to cause |callback| being run in the current
+ // TaskRunner.
+ return tracker->PostTaskAndReply(manual_callback_task_runner_.get(),
+ FROM_HERE, base::Bind(&base::DoNothing),
+ bound_callback);
}
std::map<GURL, std::vector<favicon_base::FaviconRawBitmapResult>> results_;
URLVector db_requests_;
+ // URL to disable automatic callbacks for.
+ GURL manual_callback_url_;
+
+ // Callback for GetFaviconForPageOrIconURL() request for
+ // |manual_callback_url_|.
+ scoped_refptr<base::TestSimpleTaskRunner> manual_callback_task_runner_;
+
DISALLOW_COPY_AND_ASSIGN(FakeFaviconService);
};
@@ -325,12 +471,14 @@ class FaviconHandlerTest : public testing::Test {
const GURL kIconURL16x16 = GURL("http://www.google.com/favicon16x16");
const GURL kIconURL64x64 = GURL("http://www.google.com/favicon64x64");
- FaviconHandlerTest() {
+ FaviconHandlerTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {
// Register various known icon URLs.
- delegate_.fake_downloader().Add(kIconURL10x10, IntVector{10});
- delegate_.fake_downloader().Add(kIconURL12x12, IntVector{12});
- delegate_.fake_downloader().Add(kIconURL16x16, IntVector{16});
- delegate_.fake_downloader().Add(kIconURL64x64, IntVector{64});
+ delegate_.fake_image_downloader().Add(kIconURL10x10, IntVector{10});
+ delegate_.fake_image_downloader().Add(kIconURL12x12, IntVector{12});
+ delegate_.fake_image_downloader().Add(kIconURL16x16, IntVector{16});
+ delegate_.fake_image_downloader().Add(kIconURL64x64, IntVector{64});
// The score computed by SelectFaviconFrames() is dependent on the supported
// scale factors of the platform. It is used for determining the goodness of
@@ -344,7 +492,7 @@ class FaviconHandlerTest : public testing::Test {
bool VerifyAndClearExpectations() {
base::RunLoop().RunUntilIdle();
favicon_service_.fake()->ClearDbRequests();
- delegate_.fake_downloader().ClearDownloads();
+ delegate_.ClearDownloads();
return testing::Mock::VerifyAndClearExpectations(&favicon_service_) &&
testing::Mock::VerifyAndClearExpectations(&delegate_);
}
@@ -353,14 +501,15 @@ class FaviconHandlerTest : public testing::Test {
// Returns the handler in case tests want to exercise further steps.
std::unique_ptr<FaviconHandler> RunHandlerWithCandidates(
FaviconDriverObserver::NotificationIconType handler_type,
- const std::vector<favicon::FaviconURL>& candidates) {
+ const std::vector<favicon::FaviconURL>& candidates,
+ const GURL& manifest_url = GURL()) {
auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_,
&delegate_, handler_type);
handler->FetchFavicon(kPageURL);
// The first RunUntilIdle() causes the FaviconService lookups be faster than
- // OnUpdateFaviconURL(), which is the most likely scenario.
+ // OnUpdateCandidates(), which is the most likely scenario.
base::RunLoop().RunUntilIdle();
- handler->OnUpdateFaviconURL(kPageURL, candidates);
+ handler->OnUpdateCandidates(kPageURL, candidates, manifest_url);
base::RunLoop().RunUntilIdle();
return handler;
}
@@ -368,16 +517,17 @@ class FaviconHandlerTest : public testing::Test {
// Same as above, but for the simplest case where all types are FAVICON and
// no sizes are provided, using a FaviconHandler of type NON_TOUCH_16_DIP.
std::unique_ptr<FaviconHandler> RunHandlerWithSimpleFaviconCandidates(
- const std::vector<GURL>& urls) {
+ const std::vector<GURL>& urls,
+ const GURL& manifest_url = GURL()) {
std::vector<favicon::FaviconURL> candidates;
for (const GURL& url : urls) {
candidates.emplace_back(url, FAVICON, kEmptySizes);
}
return RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP,
- candidates);
+ candidates, manifest_url);
}
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors>
scoped_set_supported_scale_factors_;
testing::NiceMock<MockFaviconServiceWithFake> favicon_service_;
@@ -408,9 +558,9 @@ TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
// Test that UpdateFaviconsAndFetch() is called with the appropriate parameters
// when there is data in the database for neither the page URL nor the icon URL.
TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetch) {
- EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch(
- kPageURL, URLVector{kIconURL16x16}, FAVICON,
- /*desired_size_in_dip=*/16, _, _));
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(kPageURL, kIconURL16x16, FAVICON,
+ /*desired_size_in_dip=*/16, _, _));
RunHandlerWithSimpleFaviconCandidates({kIconURL16x16});
}
@@ -419,48 +569,73 @@ TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetch) {
// - There is data in the database for neither the page URL nor the icon URL.
// AND
// - FaviconService::GetFaviconForPageURL() callback returns before
-// FaviconHandler::OnUpdateFaviconURL() is called.
+// FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesSlower) {
- EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
- ImageSizeIs(16, 16)));
- EXPECT_CALL(delegate_, OnFaviconUpdated(
- kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP,
- kIconURL16x16, /*icon_url_changed=*/true, _));
+ // Defer the database lookup completion to control the exact timing.
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL);
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
FaviconHandler handler(&favicon_service_, &delegate_,
FaviconDriverObserver::NON_TOUCH_16_DIP);
handler.FetchFavicon(kPageURL);
- // Causes FaviconService lookups be faster than OnUpdateFaviconURL().
base::RunLoop().RunUntilIdle();
- handler.OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)});
+ // Database lookup for |kPageURL| is ongoing.
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+ // Causes FaviconService lookups be faster than OnUpdateCandidates().
+ ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ ASSERT_TRUE(VerifyAndClearExpectations());
+
+ EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
+ ImageSizeIs(16, 16)));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(
+ kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP,
+ kIconURL16x16, /*icon_url_changed=*/true, _));
+ // Feed in favicons now that the database lookup is completed.
+ handler.OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}, GURL());
base::RunLoop().RunUntilIdle();
- EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
EXPECT_THAT(favicon_service_.fake()->db_requests(),
- ElementsAre(kPageURL, kIconURL16x16));
+ ElementsAre(kIconURL16x16));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
}
// Test that the FaviconHandler process finishes when:
// - There is data in the database for neither the page URL nor the icon URL.
// AND
// - FaviconService::GetFaviconForPageURL() callback returns after
-// FaviconHandler::OnUpdateFaviconURL() is called.
+// FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) {
- EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
- ImageSizeIs(16, 16)));
- EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _));
+ // Defer the database lookup completion to control the exact timing.
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL);
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
FaviconHandler handler(&favicon_service_, &delegate_,
FaviconDriverObserver::NON_TOUCH_16_DIP);
handler.FetchFavicon(kPageURL);
- ASSERT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL));
+ base::RunLoop().RunUntilIdle();
+ // Feed in favicons before completing the database lookup.
+ handler.OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}, GURL());
+
+ ASSERT_TRUE(VerifyAndClearExpectations());
+ // Database lookup for |kPageURL| is ongoing.
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+ EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
+ ImageSizeIs(16, 16)));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _));
- // Feed in favicons without processing posted tasks (RunUntilIdle()).
- handler.OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)});
+ // Complete the lookup for |kPageURL|.
+ ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually());
base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kIconURL16x16));
EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
}
@@ -500,22 +675,34 @@ TEST_F(FaviconHandlerTest, DownloadBookmarkedFaviconInIncognito) {
// Test that the icon is redownloaded if the icon cached for the page URL
// expired.
TEST_F(FaviconHandlerTest, RedownloadExpiredPageUrlFavicon) {
+ const GURL kIconURL("http://www.google.com/favicon");
+ const SkColor kOldColor = SK_ColorBLUE;
+ const SkColor kNewColor = SK_ColorGREEN;
+
favicon_service_.fake()->Store(
- kPageURL, kIconURL16x16,
- CreateRawBitmapResult(kIconURL16x16, FAVICON, /*expired=*/true));
+ kPageURL, kIconURL,
+ CreateRawBitmapResult(kIconURL, FAVICON, /*expired=*/true,
+ gfx::kFaviconSize, kOldColor));
- // TODO(crbug.com/700811): It would be nice if we could check whether the two
- // OnFaviconUpdated() calls are called with different gfx::Images (as opposed
- // to calling OnFaviconUpdated() with the expired gfx::Image both times).
- EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _)).Times(2);
- EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL16x16, _, _));
+ delegate_.fake_image_downloader().Add(kIconURL, IntVector{gfx::kFaviconSize},
+ IntVector{gfx::kFaviconSize},
+ kNewColor);
- RunHandlerWithSimpleFaviconCandidates({kIconURL16x16});
- // We know from the |kPageUrl| database request that |kIconURL16x16| has
- // expired. A second request for |kIconURL16x16| should not have been made
- // because it is redundant.
+ EXPECT_CALL(favicon_service_,
+ SetFavicons(_, kIconURL, _, ImageColorIs(kNewColor)));
+
+ InSequence seq;
+ EXPECT_CALL(delegate_,
+ OnFaviconUpdated(_, _, kIconURL, _, ImageColorIs(kOldColor)));
+ EXPECT_CALL(delegate_,
+ OnFaviconUpdated(_, _, kIconURL, _, ImageColorIs(kNewColor)));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL});
+ // We know from the |kPageUrl| database request that |kIconURL| has expired. A
+ // second request for |kIconURL| should not have been made because it is
+ // redundant.
EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL));
- EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL));
}
// Test that FaviconHandler requests the new data when:
@@ -544,22 +731,27 @@ TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) {
// - The invalid data is not sent to the UI.
// - The icon is redownloaded.
TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {
- // Set non empty but invalid data.
+ const GURL kIconURL("http://www.google.com/favicon");
+
+ delegate_.fake_image_downloader().Add(kIconURL, IntVector{gfx::kFaviconSize},
+ IntVector{gfx::kFaviconSize},
+ SK_ColorBLUE);
+
+ // Set non-empty but invalid data.
std::vector<FaviconRawBitmapResult> bitmap_result =
- CreateRawBitmapResult(kIconURL16x16);
+ CreateRawBitmapResult(kIconURL);
// Empty bitmap data is invalid.
bitmap_result[0].bitmap_data = new base::RefCountedBytes();
- favicon_service_.fake()->Store(kPageURL, kIconURL16x16, bitmap_result);
+ favicon_service_.fake()->Store(kPageURL, kIconURL, bitmap_result);
- // TODO(crbug.com/700811): It would be nice if we could check the image
- // being published to rule out invalid data.
- EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _));
+ EXPECT_CALL(delegate_,
+ OnFaviconUpdated(_, _, kIconURL, _, ImageColorIs(SK_ColorBLUE)));
- RunHandlerWithSimpleFaviconCandidates({kIconURL16x16});
+ RunHandlerWithSimpleFaviconCandidates({kIconURL});
EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL));
- EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL));
}
// Test that no downloads are done if a user visits a page which changed its
@@ -589,7 +781,7 @@ TEST_F(FaviconHandlerTest, UpdateFavicon) {
TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
const GURL kIconURLReturning500("http://www.google.com/500.png");
- delegate_.fake_downloader().AddError(kIconURLReturning500, 500);
+ delegate_.fake_image_downloader().AddError(kIconURLReturning500, 500);
favicon_service_.fake()->Store(
kPageURL, kIconURL64x64,
@@ -616,7 +808,7 @@ TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
// Test that download data for icon URLs other than the current favicon
// candidate URLs is ignored. This test tests the scenario where a download is
-// in flight when FaviconHandler::OnUpdateFaviconURL() is called.
+// in flight when FaviconHandler::OnUpdateCandidates() is called.
// TODO(mastiz): Make this test deal with FaviconURLs of type
// favicon_base::FAVICON and add new ones like OnlyDownloadMatchingIconType and
// CallSetFaviconsWithCorrectIconType.
@@ -627,36 +819,73 @@ TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {
// Defer the download completion such that RunUntilIdle() doesn't complete
// the download.
- delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kIconURL1);
+ delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(kIconURL1);
- delegate_.fake_downloader().Add(kIconURL1, IntVector{16});
- delegate_.fake_downloader().Add(kIconURL3, IntVector{64});
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{16});
+ delegate_.fake_image_downloader().Add(kIconURL3, IntVector{64});
std::unique_ptr<FaviconHandler> handler =
RunHandlerWithSimpleFaviconCandidates({kIconURL1, kIconURL2});
ASSERT_TRUE(VerifyAndClearExpectations());
- ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
+ ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
// Favicon update should invalidate the ongoing download.
EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL3, _, _));
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL3, _, _));
- handler->OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL3, FAVICON, kEmptySizes)});
+ handler->OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL3, FAVICON, kEmptySizes)}, GURL());
// Finalizes download, which should be thrown away as the favicon URLs were
// updated.
- EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually());
+ EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
base::RunLoop().RunUntilIdle();
EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL3));
EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL3));
}
+// Test that sending an icon URL update different to the previous icon URL
+// update during a database lookup ignores the first icon URL and processes the
+// second.
+TEST_F(FaviconHandlerTest, UpdateDuringDatabaseLookup) {
+ const GURL kIconURL1 = kIconURL16x16;
+ const GURL kIconURL2 = kIconURL64x64;
+
+ // Defer the lookup completion such that RunUntilIdle() doesn't complete the
+ // lookup.
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kIconURL1);
+
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{16});
+ delegate_.fake_image_downloader().Add(kIconURL2, IntVector{64});
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates(URLVector{kIconURL1});
+
+ ASSERT_TRUE(VerifyAndClearExpectations());
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+ // SetFavicons() and OnFaviconUpdated() should be called for the new icon URL
+ // and not |kIconURL1|.
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL2, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
+
+ handler->OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}, GURL());
+
+ // Finalizes the DB lookup, which should be thrown away as the favicon URLs
+ // were updated.
+ EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL2));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL2));
+}
+
// Test that sending an icon URL update identical to the previous icon URL
-// update is a no-op.
-TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileProcessingShouldBeNoop) {
+// update during image download is a no-op.
+TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileDownloadingShouldBeNoop) {
const GURL kSlowLoadingIconURL("http://www.google.com/slow_favicon");
const std::vector<FaviconURL> favicon_urls = {
@@ -666,8 +895,9 @@ TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileProcessingShouldBeNoop) {
// Defer the download completion such that RunUntilIdle() doesn't complete
// the download.
- delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kSlowLoadingIconURL);
- delegate_.fake_downloader().Add(kSlowLoadingIconURL, IntVector{16});
+ delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(
+ kSlowLoadingIconURL);
+ delegate_.fake_image_downloader().Add(kSlowLoadingIconURL, IntVector{16});
std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
@@ -675,21 +905,57 @@ TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileProcessingShouldBeNoop) {
ASSERT_THAT(favicon_service_.fake()->db_requests(),
ElementsAre(kPageURL, kIconURL64x64, kSlowLoadingIconURL));
ASSERT_TRUE(VerifyAndClearExpectations());
- ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
+ ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
- // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect,
+ // Calling OnUpdateCandidates() with the same icon URLs should have no effect,
// despite the ongoing download.
- handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
+ handler->OnUpdateCandidates(kPageURL, favicon_urls, GURL());
base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
+ EXPECT_THAT(delegate_.downloads(), IsEmpty());
// Complete the download.
EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _));
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _));
- EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually());
+ EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
base::RunLoop().RunUntilIdle();
EXPECT_THAT(delegate_.downloads(), IsEmpty());
}
+// Test that sending an icon URL update identical to the previous icon URL
+// update during a database lookup is a no-op.
+TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileDatabaseLookupShouldBeNoop) {
+ const std::vector<FaviconURL> favicon_urls = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kIconURL64x64);
+
+ std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
+ FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
+
+ // Ongoing database lookup.
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kIconURL64x64));
+ ASSERT_THAT(delegate_.downloads(), IsEmpty());
+ ASSERT_TRUE(VerifyAndClearExpectations());
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+ // Calling OnUpdateCandidates() with the same icon URLs should have no effect,
+ // despite the ongoing DB lookup.
+ handler->OnUpdateCandidates(kPageURL, favicon_urls, GURL());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
+ EXPECT_THAT(delegate_.downloads(), IsEmpty());
+
+ // Complete the lookup.
+ EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _));
+ EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL64x64));
+}
+
// Test that calling OnUpdateFaviconUrl() with the same icon URLs as before is a
// no-op. This is important because OnUpdateFaviconUrl() is called when the page
// finishes loading. This can occur several times for pages with iframes.
@@ -704,11 +970,11 @@ TEST_F(FaviconHandlerTest, UpdateSameIconURLsAfterFinishedShouldBeNoop) {
ASSERT_TRUE(VerifyAndClearExpectations());
- // Calling OnUpdateFaviconURL() with identical data should be a no-op.
+ // Calling OnUpdateCandidates() with identical data should be a no-op.
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
- handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
+ handler->OnUpdateCandidates(kPageURL, favicon_urls, GURL());
base::RunLoop().RunUntilIdle();
EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
EXPECT_THAT(delegate_.downloads(), IsEmpty());
@@ -729,8 +995,8 @@ TEST_F(FaviconHandlerTest,
"http://wwww.page_which_animates_favicon.com/frame2.png");
// |kIconURL1| is the better match.
- delegate_.fake_downloader().Add(kIconURL1, IntVector{15});
- delegate_.fake_downloader().Add(kIconURL2, IntVector{10});
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{15});
+ delegate_.fake_image_downloader().Add(kIconURL2, IntVector{10});
// Two FaviconDriver::OnFaviconUpdated() notifications should be sent for
// |kIconURL1|, one before and one after the download.
@@ -750,8 +1016,8 @@ TEST_F(FaviconHandlerTest,
// Simulate the page changing it's icon URL to just |kIconURL2| via
// Javascript.
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
- handler->OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL2, FAVICON, kEmptySizes)});
+ handler->OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}, GURL());
base::RunLoop().RunUntilIdle();
}
@@ -788,7 +1054,7 @@ class FaviconHandlerMultipleFaviconsTest : public FaviconHandlerTest {
const GURL icon_url(base::StringPrintf(
"https://www.google.com/generated/%dx%d", icon_size, icon_size));
// Set up 200 responses for all images, and the corresponding size.
- delegate_.fake_downloader().Add(icon_url, IntVector{icon_size});
+ delegate_.fake_image_downloader().Add(icon_url, IntVector{icon_size});
// Create test candidates of type FAVICON and a fake URL.
candidate_icons.emplace_back(icon_url, FAVICON, kEmptySizes);
@@ -844,7 +1110,7 @@ TEST_F(FaviconHandlerTest, Report404) {
TEST_F(FaviconHandlerTest, NotReport503) {
const GURL k503IconURL("http://www.google.com/503.png");
- delegate_.fake_downloader().AddError(k503IconURL, 503);
+ delegate_.fake_image_downloader().AddError(k503IconURL, 503);
EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
@@ -977,8 +1243,8 @@ TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {
const GURL kIconURL1("http://www.google.com/b");
const GURL kIconURL2("http://www.google.com/c");
- delegate_.fake_downloader().Add(kIconURL1, IntVector{15});
- delegate_.fake_downloader().Add(kIconURL2, IntVector{14, 16});
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{15});
+ delegate_.fake_image_downloader().Add(kIconURL2, IntVector{14, 16});
// Verify NotifyFaviconAvailable().
EXPECT_CALL(delegate_,
@@ -1003,10 +1269,12 @@ TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) {
const int kOriginalSize1 = kMaximalSize + 1;
const int kOriginalSize2 = kMaximalSize + 2;
- delegate_.fake_downloader().AddWithOriginalSizes(
- kIconURL1, IntVector{kMaximalSize}, IntVector{kOriginalSize1});
- delegate_.fake_downloader().AddWithOriginalSizes(
- kIconURL2, IntVector{kMaximalSize}, IntVector{kOriginalSize2});
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{kMaximalSize},
+ IntVector{kOriginalSize1},
+ SK_ColorBLUE);
+ delegate_.fake_image_downloader().Add(kIconURL2, IntVector{kMaximalSize},
+ IntVector{kOriginalSize2},
+ SK_ColorBLUE);
// Verify the best bitmap was selected (although smaller than |kIconURL2|)
// and that it was scaled down to |kMaximalSize|.
@@ -1165,7 +1433,7 @@ TEST_F(FaviconHandlerTest, TestRecordFailingDownloadAttempt) {
base::HistogramTester histogram_tester;
const GURL k404IconURL("http://www.google.com/404.png");
- delegate_.fake_downloader().AddError(k404IconURL, 404);
+ delegate_.fake_image_downloader().AddError(k404IconURL, 404);
EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(k404IconURL));
@@ -1192,5 +1460,516 @@ TEST_F(FaviconHandlerTest, TestRecordSkippedDownloadForKnownFailingUrl) {
/*expected_count=*/1)));
}
+// Test that the support for Web Manifest is disabled by default, unless the
+// feature is enabled.
+TEST_F(FaviconHandlerTest, IgnoreWebManifestByDefault) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ Not(Contains(kManifestURL)));
+ EXPECT_THAT(delegate_.downloads(), Not(Contains(kManifestURL)));
+}
+
+class FaviconHandlerManifestsEnabledTest : public FaviconHandlerTest {
+ protected:
+ const GURL kManifestURL = GURL("http://www.google.com/manifest.json");
+
+ FaviconHandlerManifestsEnabledTest() {
+ override_features_.InitAndEnableFeature(kFaviconsFromWebManifest);
+ }
+
+ private:
+ base::test::ScopedFeatureList override_features_;
+
+ DISALLOW_COPY_AND_ASSIGN(FaviconHandlerManifestsEnabledTest);
+};
+
+// Test that a favicon corresponding to a web manifest is reported when:
+// - There is data in the favicon database for the manifest URL.
+// AND
+// - FaviconService::OnFaviconDataForManifestFromFaviconService() runs before
+// FaviconHandler::OnUpdateCandidates() is called.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ GetFaviconFromManifestInHistoryIfCandidatesSlower) {
+ favicon_service_.fake()->Store(
+ kPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL, WEB_MANIFEST_ICON));
+
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(_, kManifestURL, WEB_MANIFEST_ICON,
+ /*desired_size_in_dip=*/16, _, _));
+ EXPECT_CALL(delegate_,
+ OnFaviconUpdated(_, FaviconDriverObserver::NON_TOUCH_16_DIP,
+ kManifestURL, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), IsEmpty());
+}
+
+// Test that a favicon corresponding to a web manifest is reported when:
+// - There is data in the favicon database for the manifest URL.
+// AND
+// - FaviconHandler::OnUpdateCandidates() is called before
+// FaviconService::OnFaviconDataForManifestFromFaviconService() runs.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ GetFaviconFromManifestInHistoryIfCandidatesFaster) {
+ favicon_service_.fake()->Store(
+ kPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL, WEB_MANIFEST_ICON));
+ // Defer the database lookup completion to control the exact timing.
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kManifestURL);
+
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(_, kManifestURL, WEB_MANIFEST_ICON,
+ /*desired_size_in_dip=*/16, _, _));
+ EXPECT_CALL(delegate_,
+ OnFaviconUpdated(_, FaviconDriverObserver::NON_TOUCH_16_DIP,
+ kManifestURL, _, _));
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+ // Complete the lookup.
+ EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), IsEmpty());
+}
+
+// Test that a favicon corresponding to a web manifest is reported when there is
+// data in the database for neither the page URL nor the manifest URL.
+TEST_F(FaviconHandlerManifestsEnabledTest, GetFaviconFromUnknownManifest) {
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL16x16, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ EXPECT_CALL(favicon_service_,
+ SetFavicons(_, kManifestURL, WEB_MANIFEST_ICON, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL16x16));
+}
+
+// Test that the manifest and icon are redownloaded if the icon cached for the
+// page URL expired.
+TEST_F(FaviconHandlerManifestsEnabledTest, GetFaviconFromExpiredManifest) {
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ favicon_service_.fake()->Store(
+ kPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL, WEB_MANIFEST_ICON,
+ /*expired=*/true));
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _)).Times(2);
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
+}
+
+// Test that the manifest and icon are redownloaded if the icon cached for the
+// manifest URL expired, which was observed during a visit to a different page
+// URL.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ GetFaviconFromExpiredManifestLinkedFromOtherPage) {
+ const GURL kSomePreviousPageURL("https://www.google.com/previous");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ favicon_service_.fake()->Store(
+ kSomePreviousPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL, WEB_MANIFEST_ICON,
+ /*expired=*/true));
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _)).Times(2);
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
+}
+
+// Test that a favicon corresponding to a web manifest is reported when:
+// - There is data in the database for neither the page URL nor the manifest
+// URL.
+// - There is data in the database for the icon URL listed in the manifest.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ GetFaviconFromUnknownManifestButKnownIcon) {
+ const GURL kSomePreviousPageURL("https://www.google.com/previous");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL16x16, FAVICON, kEmptySizes),
+ };
+
+ favicon_service_.fake()->Store(kSomePreviousPageURL, kIconURL16x16,
+ CreateRawBitmapResult(kIconURL16x16));
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates(URLVector(), kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ // This is because, in the current implementation, FaviconHandler only checks
+ // whether there is an icon cached with the manifest URL as the "icon URL"
+ // when a page has a non-empty Web Manifest.
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL16x16));
+}
+
+// Test a manifest that returns a 404 gets blacklisted via
+// UnableToDownloadFavicon() AND that the regular favicon is selected as
+// fallback.
+TEST_F(FaviconHandlerManifestsEnabledTest, UnknownManifestReturning404) {
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL12x12, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL12x12));
+}
+
+// Test that a manifest that was previously blacklisted via
+// UnableToDownloadFavicon() is ignored and that the regular favicon is selected
+// as fallback.
+TEST_F(FaviconHandlerManifestsEnabledTest, IgnoreManifestWithPrior404) {
+ ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kManifestURL))
+ .WillByDefault(Return(true));
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL12x12, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL12x12));
+}
+
+// Test that the regular favicon is selected when:
+// - The page links to a Web Manifest.
+// - The Web Manifest does not contain any icon URLs (it is not a 404).
+// - The page has an icon URL provided via a <link rel="icon"> tag.
+// - The database does not know about the page URL, manifest URL or icon URL.
+TEST_F(FaviconHandlerManifestsEnabledTest, UnknownManifestWithoutIcons) {
+ delegate_.fake_manifest_downloader().Add(kManifestURL,
+ std::vector<favicon::FaviconURL>());
+
+ // UnableToDownloadFavicon() is expected to prevent repeated downloads of the
+ // same manifest (which is not otherwise cached, since it doesn't contain
+ // icons).
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL12x12, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL12x12));
+}
+
+// Test that the regular favicon is selected when:
+// - The page links to a Web Manifest.
+// - The Web Manifest does not contain any icon URLs (it is not a 404).
+// - The page has an icon URL provided via a <link rel="icon"> tag.
+// - The database does not know about the page URL.
+// - The database does not know about the manifest URL.
+// - The database knows about the icon URL.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ UnknownManifestWithoutIconsAndKnownRegularIcons) {
+ const GURL kSomePreviousPageURL("https://www.google.com/previous");
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL,
+ std::vector<favicon::FaviconURL>());
+ favicon_service_.fake()->Store(kSomePreviousPageURL, kIconURL12x12,
+ CreateRawBitmapResult(kIconURL12x12));
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
+
+ // UnableToDownloadFavicon() is expected to prevent repeated downloads of the
+ // same manifest (which is not otherwise cached, since it doesn't contain
+ // icons).
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(_, kManifestURL, _, _, _, _));
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(_, kIconURL12x12, _, _, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL12x12, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL));
+}
+
+// Test that the database remains unmodified when:
+// - The page links to a Web Manifest.
+// - The Web Manifest does not contain any icon URLs (it is not a 404).
+// - The page has an icon URL provided via a <link rel="icon"> tag.
+// - The database has a mapping between the page URL to the favicon URL.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ UnknownManifestWithoutIconsAndRegularIconInHistory) {
+ delegate_.fake_manifest_downloader().Add(kManifestURL,
+ std::vector<favicon::FaviconURL>());
+ favicon_service_.fake()->Store(kPageURL, kIconURL16x16,
+ CreateRawBitmapResult(kIconURL16x16));
+
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _));
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(_, kManifestURL, _, _, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}, kManifestURL);
+
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL));
+}
+
+// Test that Delegate::OnFaviconUpdated() is called if a page uses Javascript to
+// modify the page's <link rel="manifest"> tag to point to a different manifest.
+TEST_F(FaviconHandlerManifestsEnabledTest, ManifestUpdateViaJavascript) {
+ const GURL kManifestURL1("http://www.google.com/manifest1.json");
+ const GURL kManifestURL2("http://www.google.com/manifest2.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons1 = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+ const std::vector<favicon::FaviconURL> kManifestIcons2 = {
+ FaviconURL(kIconURL10x10, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL1, kManifestIcons1);
+ delegate_.fake_manifest_downloader().Add(kManifestURL2, kManifestIcons2);
+
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL1, _, _));
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL1);
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL1));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL1, kIconURL64x64));
+ ASSERT_TRUE(VerifyAndClearExpectations());
+
+ // Simulate the page changing it's manifest URL via Javascript.
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL2, _, _));
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ kManifestURL2);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kManifestURL2));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL2, kIconURL10x10));
+}
+
+// Test that Delegate::OnFaviconUpdated() is called if a page uses Javascript to
+// remove the page's <link rel="manifest"> tag (i.e. no web manifest) WHILE a
+// lookup to the history database is ongoing for the manifest URL.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ RemoveManifestViaJavascriptWhileDatabaseLookup) {
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+ // Defer the database lookup completion to control the exact timing.
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kManifestURL);
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ // Database lookup for |kManifestURL| is ongoing.
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+ // Simulate the page changing it's manifest URL to empty via Javascript.
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL12x12, _, _));
+ handler->OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)}, GURL());
+ // Complete the lookup.
+ EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL12x12));
+}
+
+// Test that Delegate::OnFaviconUpdated() is called a page without manifest uses
+// Javascript to add a <link rel="manifest"> tag (i.e. a new web manifest) WHILE
+// a lookup to the history database is ongoing for the icon URL.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ AddManifestViaJavascriptWhileDatabaseLookup) {
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+ // Defer the database lookup completion to control the exact timing.
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kIconURL12x12);
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12});
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kIconURL12x12));
+ // Database lookup for |kIconURL12x12| is ongoing.
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+ // Simulate the page changing it's manifest URL to |kManifestURL| via
+ // Javascript.
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ kManifestURL);
+ // Complete the lookup.
+ EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kIconURL12x12, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
+}
+
+// Test that SetFavicons() is not called when:
+// - The page doesn't initially link to a Web Manifest.
+// - The page has an icon URL provided via a <link rel="icon"> tag.
+// - The database does not know about the page URL or icon URL.
+// - While the icon is being downloaded, the page uses Javascript to add a
+// <link rel="manifest"> tag.
+// - The database has bitmap data for the manifest URL.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ AddKnownManifestViaJavascriptWhileImageDownload) {
+ const GURL kSomePreviousPageURL("https://www.google.com/previous");
+
+ favicon_service_.fake()->Store(
+ kSomePreviousPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL, WEB_MANIFEST_ICON));
+
+ // Defer the image download completion to control the exact timing.
+ delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(kIconURL16x16);
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates({kIconURL16x16});
+
+ ASSERT_TRUE(VerifyAndClearExpectations());
+ ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
+
+ // Simulate the page changing it's manifest URL to |kManifestURL| via
+ // Javascript. Should invalidate the ongoing image download.
+ EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
+
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)},
+ kManifestURL);
+
+ // Finalizes download, which should be thrown away as the manifest URL was
+ // provided.
+ EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+}
+
+// Test that SetFavicons() is called with the icon URL when:
+// - The page doesn't initially link to a Web Manifest.
+// - The page has an icon URL provided via a <link rel="icon"> tag.
+// - The database does not know about the page URL or icon URL.
+// - During the database lookup, the page uses Javascript to add a
+// <link rel="manifest"> tag.
+// - The database does not know about the manifest URL.
+// - The manifest contains no icons.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ AddManifestWithoutIconsViaJavascriptWhileDatabaseLookup) {
+ delegate_.fake_manifest_downloader().Add(kManifestURL,
+ std::vector<favicon::FaviconURL>());
+
+ // Defer the database lookup completion to control the exact timing.
+ favicon_service_.fake()->SetRunCallbackManuallyForUrl(kIconURL16x16);
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates({kIconURL16x16});
+
+ ASSERT_TRUE(VerifyAndClearExpectations());
+ ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL16x16, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _));
+
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)},
+ kManifestURL);
+
+ // Finalizes lookup, which should be thrown away as the manifest URLs was
+ // provided.
+ EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+
+ // The manifest URL interrupted the original processing of kIconURL16x16, but
+ // a second one should have been started.
+ EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+}
+
+// Test that SetFavicons() is called when:
+// - The page links to one Web Manifest, which contains one icon.
+// - The database does not know about the page URL, icon URL or manifest URL.
+// - During image download, the page updates the manifest URL to point to
+// another manifest.
+// - The second manifest contains the same icons as the first.
+TEST_F(FaviconHandlerManifestsEnabledTest,
+ UpdateManifestWithSameIconURLsWhileDownloading) {
+ const GURL kManifestURL1("http://www.google.com/manifest1.json");
+ const GURL kManifestURL2("http://www.google.com/manifest2.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL1, kManifestIcons);
+ delegate_.fake_manifest_downloader().Add(kManifestURL2, kManifestIcons);
+
+ // Defer the download completion to control the exact timing.
+ delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(kIconURL64x64);
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates(URLVector(), kManifestURL1);
+
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL1, kIconURL64x64));
+ ASSERT_TRUE(VerifyAndClearExpectations());
+ ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
+
+ // Calling OnUpdateCandidates() with a different manifest URL should trigger
+ // its download.
+ handler->OnUpdateCandidates(kPageURL, std::vector<favicon::FaviconURL>(),
+ kManifestURL2);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL2, kIconURL64x64));
+
+ // Complete the download.
+ EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL2, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL2, _, _));
+ EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
+ base::RunLoop().RunUntilIdle();
+}
+
} // namespace
} // namespace favicon
diff --git a/chromium/components/favicon/core/favicon_service.h b/chromium/components/favicon/core/favicon_service.h
index 8ac749f8419..d3618009349 100644
--- a/chromium/components/favicon/core/favicon_service.h
+++ b/chromium/components/favicon/core/favicon_service.h
@@ -88,13 +88,9 @@ class FaviconService : public KeyedService {
// Requests the favicon for the page at |page_url| with one of |icon_types|
// and with |desired_size_in_pixel|. |icon_types| can be any combination of
- // IconTypes. If favicon bitmaps for several IconTypes are available, the
- // favicon bitmap is chosen in the priority of TOUCH_PRECOMPOSED_ICON,
- // TOUCH_ICON and FAVICON. If there is no favicon bitmap of size
- // |desired_size_in_pixel|, the favicon bitmap which best matches
- // |desired_size_in_pixel| is resized. If |desired_size_in_pixel| is 0,
- // the largest favicon bitmap is returned. Results with a higher priority
- // IconType are preferred over an exact match of the favicon bitmap size.
+ // IconTypes. If there is no favicon bitmap of size |desired_size_in_pixel|,
+ // the favicon bitmap which best matches |desired_size_in_pixel| is resized.
+ // If |desired_size_in_pixel| is 0, the largest favicon bitmap is returned.
virtual base::CancelableTaskTracker::TaskId GetRawFaviconForPageURL(
const GURL& page_url,
int icon_types,
@@ -117,30 +113,16 @@ class FaviconService : public KeyedService {
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker) = 0;
- // Set the favicon mappings to |page_url| for |icon_types| in the history
- // database.
- // Sample |icon_urls|:
- // { ICON_URL1 -> TOUCH_ICON, known to the database,
- // ICON_URL2 -> TOUCH_ICON, not known to the database,
- // ICON_URL3 -> TOUCH_PRECOMPOSED_ICON, known to the database }
- // The new mappings are computed from |icon_urls| with these rules:
- // 1) Any urls in |icon_urls| which are not already known to the database are
- // rejected.
- // Sample new mappings to |page_url|: { ICON_URL1, ICON_URL3 }
- // 2) If |icon_types| has multiple types, the mappings are only set for the
- // largest icon type.
- // Sample new mappings to |page_url|: { ICON_URL3 }
- // |icon_types| can only have multiple IconTypes if
- // |icon_types| == TOUCH_ICON | TOUCH_PRECOMPOSED_ICON.
- // The favicon bitmaps which most closely match |desired_size_in_dip|
- // at the reosurce scale factors supported by the current platform (eg MacOS)
- // in addition to 1x from the favicons which were just mapped to |page_url|
- // are returned. If |desired_size_in_dip| is 0, the largest favicon bitmap is
- // returned.
+ // Maps |page_url| to the favicon at |icon_url| if there is an entry in the
+ // database for |icon_url| and |icon_type|. This occurs when there is a
+ // mapping from a different page URL to |icon_url|. The favicon bitmaps whose
+ // edge sizes most closely match |desired_size_in_dip| from the favicons which
+ // were just mapped to |page_url| are returned. If |desired_size_in_dip| has a
+ // '0' entry, the largest favicon bitmap is returned.
virtual base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
int desired_size_in_dip,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker) = 0;
diff --git a/chromium/components/favicon/core/favicon_service_impl.cc b/chromium/components/favicon/core/favicon_service_impl.cc
index 98557b24766..55ac6b22ef3 100644
--- a/chromium/components/favicon/core/favicon_service_impl.cc
+++ b/chromium/components/favicon/core/favicon_service_impl.cc
@@ -73,10 +73,8 @@ base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconImage(
favicon_base::FaviconResultsCallback callback_runner =
base::Bind(&FaviconServiceImpl::RunFaviconImageCallbackWithBitmapResults,
base::Unretained(this), callback, gfx::kFaviconSize);
- std::vector<GURL> icon_urls;
- icon_urls.push_back(icon_url);
- return history_service_->GetFavicons(
- icon_urls, favicon_base::FAVICON,
+ return history_service_->GetFavicon(
+ icon_url, favicon_base::FAVICON,
GetPixelSizesForFaviconScales(gfx::kFaviconSize), callback_runner,
tracker);
}
@@ -92,13 +90,11 @@ base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetRawFavicon(
&FaviconServiceImpl::RunFaviconRawBitmapCallbackWithBitmapResults,
base::Unretained(this), callback, desired_size_in_pixel);
- std::vector<GURL> icon_urls;
- icon_urls.push_back(icon_url);
std::vector<int> desired_sizes_in_pixel;
desired_sizes_in_pixel.push_back(desired_size_in_pixel);
- return history_service_->GetFavicons(
- icon_urls, icon_type, desired_sizes_in_pixel, callback_runner, tracker);
+ return history_service_->GetFavicon(
+ icon_url, icon_type, desired_sizes_in_pixel, callback_runner, tracker);
}
base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFavicon(
@@ -110,8 +106,8 @@ base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFavicon(
TRACE_EVENT0("browser", "FaviconServiceImpl::GetFavicon");
std::vector<GURL> icon_urls;
icon_urls.push_back(icon_url);
- return history_service_->GetFavicons(
- icon_urls, icon_type, GetPixelSizesForFaviconScales(desired_size_in_dip),
+ return history_service_->GetFavicon(
+ icon_url, icon_type, GetPixelSizesForFaviconScales(desired_size_in_dip),
callback, tracker);
}
@@ -182,13 +178,13 @@ base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageURL(
base::CancelableTaskTracker::TaskId
FaviconServiceImpl::UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
int desired_size_in_dip,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker) {
return history_service_->UpdateFaviconMappingsAndFetch(
- page_url, icon_urls, icon_types,
+ page_url, icon_url, icon_type,
GetPixelSizesForFaviconScales(desired_size_in_dip), callback, tracker);
}
diff --git a/chromium/components/favicon/core/favicon_service_impl.h b/chromium/components/favicon/core/favicon_service_impl.h
index d7e5c308823..e1cb63c4b08 100644
--- a/chromium/components/favicon/core/favicon_service_impl.h
+++ b/chromium/components/favicon/core/favicon_service_impl.h
@@ -81,8 +81,8 @@ class FaviconServiceImpl : public FaviconService {
base::CancelableTaskTracker* tracker) override;
base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
int desired_size_in_dip,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker) override;
diff --git a/chromium/components/favicon/core/features.cc b/chromium/components/favicon/core/features.cc
new file mode 100644
index 00000000000..e69e139dd10
--- /dev/null
+++ b/chromium/components/favicon/core/features.cc
@@ -0,0 +1,14 @@
+// Copyright (c) 2017 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/favicon/core/features.h"
+
+#include "base/feature_list.h"
+
+namespace favicon {
+
+const base::Feature kFaviconsFromWebManifest{"FaviconsFromWebManifest",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+} // namespace favicon
diff --git a/chromium/components/favicon/core/features.h b/chromium/components/favicon/core/features.h
new file mode 100644
index 00000000000..a7edb21d35b
--- /dev/null
+++ b/chromium/components/favicon/core/features.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2017 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_FAVICON_CORE_FEATURES_H_
+#define COMPONENTS_FAVICON_CORE_FEATURES_H_
+
+namespace base {
+struct Feature;
+}
+
+namespace favicon {
+
+extern const base::Feature kFaviconsFromWebManifest;
+
+} // namespace favicon
+
+#endif // COMPONENTS_FAVICON_CORE_FEATURES_H_
diff --git a/chromium/components/favicon/core/large_icon_service.cc b/chromium/components/favicon/core/large_icon_service.cc
index bf94e5b38ea..a6587e9d381 100644
--- a/chromium/components/favicon/core/large_icon_service.cc
+++ b/chromium/components/favicon/core/large_icon_service.cc
@@ -40,10 +40,20 @@ const base::Feature kLargeIconServiceFetchingFeature{
const char kGoogleServerV2RequestFormat[] =
"https://t0.gstatic.com/faviconV2?"
- "client=chrome&drop_404_icon=true&size=32&min_size=%d&max_size=64&"
- "fallback_opts=TYPE,SIZE,URL&url=%s";
+ "client=chrome&drop_404_icon=true&%s"
+ "size=%d&min_size=%d&max_size=%d&fallback_opts=TYPE,SIZE,URL&url=%s";
const char kGoogleServerV2RequestFormatParam[] = "request_format";
+const char kCheckSeenParam[] = "check_seen=true&";
+
+const int kGoogleServerV2EnforcedMinSizeInPixel = 16;
+const char kGoogleServerV2EnforcedMinSizeInPixelParam[] =
+ "enforced_min_size_in_pixel";
+
+const double kGoogleServerV2DesiredToMaxSizeFactor = 2.0;
+const char kGoogleServerV2DesiredToMaxSizeFactorParam[] =
+ "desired_to_max_size_factor";
+
GURL TrimPageUrlForGoogleServer(const GURL& page_url) {
if (!page_url.SchemeIsHTTPOrHTTPS() || page_url.HostIsIPAddress())
return GURL();
@@ -57,13 +67,30 @@ GURL TrimPageUrlForGoogleServer(const GURL& page_url) {
}
GURL GetRequestUrlForGoogleServerV2(const GURL& page_url,
- int min_source_size_in_pixel) {
+ int min_source_size_in_pixel,
+ int desired_size_in_pixel,
+ bool may_page_url_be_private) {
std::string url_format = base::GetFieldTrialParamValueByFeature(
kLargeIconServiceFetchingFeature, kGoogleServerV2RequestFormatParam);
+ double desired_to_max_size_factor = base::GetFieldTrialParamByFeatureAsDouble(
+ kLargeIconServiceFetchingFeature,
+ kGoogleServerV2DesiredToMaxSizeFactorParam,
+ kGoogleServerV2DesiredToMaxSizeFactor);
+
+ min_source_size_in_pixel = std::max(
+ min_source_size_in_pixel, base::GetFieldTrialParamByFeatureAsInt(
+ kLargeIconServiceFetchingFeature,
+ kGoogleServerV2EnforcedMinSizeInPixelParam,
+ kGoogleServerV2EnforcedMinSizeInPixel));
+ desired_size_in_pixel =
+ std::max(desired_size_in_pixel, min_source_size_in_pixel);
+ int max_size_in_pixel =
+ static_cast<int>(desired_size_in_pixel * desired_to_max_size_factor);
return GURL(base::StringPrintf(
url_format.empty() ? kGoogleServerV2RequestFormat : url_format.c_str(),
- min_source_size_in_pixel, page_url.spec().c_str()));
+ may_page_url_be_private ? kCheckSeenParam : "", desired_size_in_pixel,
+ min_source_size_in_pixel, max_size_in_pixel, page_url.spec().c_str()));
}
bool IsDbResultAdequate(const favicon_base::FaviconRawBitmapResult& db_result,
@@ -284,6 +311,7 @@ LargeIconService::LargeIconService(
: favicon_service_(favicon_service),
background_task_runner_(background_task_runner),
image_fetcher_(std::move(image_fetcher)) {
+ large_icon_types_.push_back(favicon_base::IconType::WEB_MANIFEST_ICON);
large_icon_types_.push_back(favicon_base::IconType::FAVICON);
large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON);
large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON);
@@ -320,12 +348,15 @@ void LargeIconService::
GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
const GURL& page_url,
int min_source_size_in_pixel,
+ int desired_size_in_pixel,
+ bool may_page_url_be_private,
const base::Callback<void(bool success)>& callback) {
DCHECK_LE(0, min_source_size_in_pixel);
const GURL trimmed_page_url = TrimPageUrlForGoogleServer(page_url);
const GURL server_request_url = GetRequestUrlForGoogleServerV2(
- trimmed_page_url, min_source_size_in_pixel);
+ trimmed_page_url, min_source_size_in_pixel, desired_size_in_pixel,
+ may_page_url_be_private);
// Do not download if the URL is invalid after trimming, or there is a
// previous cache miss recorded for |server_request_url|.
@@ -339,10 +370,34 @@ void LargeIconService::
image_fetcher_->SetDataUseServiceName(
data_use_measurement::DataUseUserData::LARGE_ICON_SERVICE);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("favicon_component", R"(
+ semantics {
+ sender: "Favicon Component"
+ description:
+ "Sends a request to a Google server to retrieve the favicon bitmap "
+ "for a page URL."
+ trigger:
+ "A request can be sent if Chrome does not have a favicon for a "
+ "particular page. This is done in two scenarios:\n"
+ " 1- For articles suggestions on the new tab page (URLs are public "
+ " and provided by Google).\n"
+ " 2- For server-suggested most visited tiles on the new tab page "
+ " (User gets these URLs from Google, only if history sync is "
+ " enabled)."
+ data: "Page URL and desired icon size."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting: "This feature cannot be disabled by settings."
+ policy_exception_justification: "Not implemented."
+ })");
image_fetcher_->StartOrQueueNetworkRequest(
server_request_url.spec(), server_request_url,
base::Bind(&OnFetchIconFromGoogleServerComplete, favicon_service_,
- page_url, callback));
+ page_url, callback),
+ traffic_annotation);
}
base::CancelableTaskTracker::TaskId
diff --git a/chromium/components/favicon/core/large_icon_service.h b/chromium/components/favicon/core/large_icon_service.h
index 7207e605ac3..b25ab3e3018 100644
--- a/chromium/components/favicon/core/large_icon_service.h
+++ b/chromium/components/favicon/core/large_icon_service.h
@@ -72,6 +72,13 @@ class LargeIconService : public KeyedService {
// encouraged to use GetLargeIconOrFallbackStyle() first.
//
// A minimum size |min_source_size_in_pixel| can be specified as a constraint.
+ // |desired_size_in_pixel| serves only as a hint to the service, no guarantees
+ // on the fetched size are provided.
+ //
+ // Unless you are sure |page_url| is a public URL (known to Google Search),
+ // set |may_page_url_be_private| to true. This slighty increases the chance of
+ // a failure (e.g. if the URL _is_ private) but it makes sure Google servers
+ // do not crawl a private URL as a result of this call.
//
// The callback is triggered when the operation finishes, where |success|
// tells whether the fetch actually managed to database a new icon in the
@@ -80,9 +87,13 @@ class LargeIconService : public KeyedService {
// WARNING: This function will share the |page_url| with a Google server. This
// Can be used only for urls that are not privacy sensitive or for users that
// sync their history with Google servers.
+ // TODO(jkrcal): It is not clear from the name of this function, that it
+ // actually adds the icon to the local cache. Maybe "StoreLargeIcon..."?
void GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
const GURL& page_url,
int min_source_size_in_pixel,
+ int desired_size_in_pixel,
+ bool may_page_url_be_private,
const base::Callback<void(bool success)>& callback);
private:
diff --git a/chromium/components/favicon/core/large_icon_service_unittest.cc b/chromium/components/favicon/core/large_icon_service_unittest.cc
index ef463077010..79f9a6bca87 100644
--- a/chromium/components/favicon/core/large_icon_service_unittest.cc
+++ b/chromium/components/favicon/core/large_icon_service_unittest.cc
@@ -23,6 +23,7 @@
#include "components/favicon_base/favicon_types.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/image_fetcher/core/request_metadata.h"
+#include "components/variations/variations_params_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -39,7 +40,10 @@ namespace {
using testing::IsEmpty;
using testing::IsNull;
using testing::Eq;
+using testing::HasSubstr;
using testing::NiceMock;
+using testing::Not;
+using testing::Property;
using testing::Return;
using testing::SaveArg;
using testing::_;
@@ -107,13 +111,15 @@ class MockImageFetcher : public image_fetcher::ImageFetcher {
MOCK_METHOD1(SetImageDownloadLimit,
void(base::Optional<int64_t> max_download_bytes));
MOCK_METHOD1(SetDesiredImageFrameSize, void(const gfx::Size& size));
- MOCK_METHOD3(StartOrQueueNetworkRequest,
+ MOCK_METHOD4(StartOrQueueNetworkRequest,
void(const std::string&,
const GURL&,
- const ImageFetcherCallback&));
+ const ImageFetcherCallback&,
+ const net::NetworkTrafficAnnotationTag&));
MOCK_METHOD0(GetImageDecoder, image_fetcher::ImageDecoder*());
};
+// TODO(jkrcal): Make the tests a bit crisper, see crbug.com/725822.
class LargeIconServiceTest : public testing::Test {
public:
LargeIconServiceTest()
@@ -139,14 +145,14 @@ class LargeIconServiceTest : public testing::Test {
TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServer) {
const GURL kExpectedServerUrl(
"https://t0.gstatic.com/faviconV2?client=chrome&drop_404_icon=true"
- "&size=32&min_size=42&max_size=64&fallback_opts=TYPE,SIZE,URL"
- "&url=http://www.example.com/");
+ "&check_seen=true&size=61&min_size=42&max_size=122"
+ "&fallback_opts=TYPE,SIZE,URL&url=http://www.example.com/");
EXPECT_CALL(mock_favicon_service_, UnableToDownloadFavicon(_)).Times(0);
base::MockCallback<base::Callback<void(bool success)>> callback;
EXPECT_CALL(*mock_image_fetcher_,
- StartOrQueueNetworkRequest(_, kExpectedServerUrl, _))
+ StartOrQueueNetworkRequest(_, kExpectedServerUrl, _, _))
.WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(64, 64, kTestColor))));
EXPECT_CALL(mock_favicon_service_,
@@ -156,7 +162,9 @@ TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServer) {
large_icon_service_
.GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
- GURL(kDummyUrl), /*min_source_size_in_pixel=*/42, callback.Get());
+ GURL(kDummyUrl), /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/true,
+ callback.Get());
EXPECT_CALL(callback, Run(true));
base::RunLoop().RunUntilIdle();
@@ -164,17 +172,52 @@ TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServer) {
"Favicons.LargeIconService.DownloadedSize", 64, /*expected_count=*/1);
}
+TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServerWithCustomUrl) {
+ variations::testing::VariationParamsManager variation_params(
+ "LargeIconServiceFetching",
+ {{"request_format",
+ "https://t0.gstatic.com/"
+ "faviconV2?%ssize=%d&min_size=%d&max_size=%d&url=%s"},
+ {"enforced_min_size_in_pixel", "43"},
+ {"desired_to_max_size_factor", "1.5"}},
+ {"LargeIconServiceFetching"});
+ const GURL kExpectedServerUrl(
+ "https://t0.gstatic.com/faviconV2?check_seen=true&"
+ "size=61&min_size=43&max_size=91&url=http://www.example.com/");
+
+ EXPECT_CALL(mock_favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ base::MockCallback<base::Callback<void(bool success)>> callback;
+ EXPECT_CALL(*mock_image_fetcher_,
+ StartOrQueueNetworkRequest(_, kExpectedServerUrl, _, _))
+ .WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
+ CreateTestSkBitmap(64, 64, kTestColor))));
+ EXPECT_CALL(mock_favicon_service_,
+ SetLastResortFavicons(GURL(kDummyUrl), kExpectedServerUrl,
+ favicon_base::IconType::TOUCH_ICON, _, _))
+ .WillOnce(PostBoolReply(true));
+
+ large_icon_service_
+ .GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
+ GURL(kDummyUrl), /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/true,
+ callback.Get());
+
+ EXPECT_CALL(callback, Run(true));
+ base::RunLoop().RunUntilIdle();
+}
+
TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServerWithOriginalUrl) {
const GURL kExpectedServerUrl(
"https://t0.gstatic.com/faviconV2?client=chrome&drop_404_icon=true"
- "&size=32&min_size=42&max_size=64&fallback_opts=TYPE,SIZE,URL"
- "&url=http://www.example.com/");
+ "&check_seen=true&size=61&min_size=42&max_size=122"
+ "&fallback_opts=TYPE,SIZE,URL&url=http://www.example.com/");
const GURL kExpectedOriginalUrl("http://www.example.com/favicon.png");
image_fetcher::RequestMetadata expected_metadata;
expected_metadata.content_location_header = kExpectedOriginalUrl.spec();
EXPECT_CALL(*mock_image_fetcher_,
- StartOrQueueNetworkRequest(_, kExpectedServerUrl, _))
+ StartOrQueueNetworkRequest(_, kExpectedServerUrl, _, _))
.WillOnce(PostFetchReplyWithMetadata(
gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(64, 64, kTestColor)),
@@ -187,7 +230,9 @@ TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServerWithOriginalUrl) {
base::MockCallback<base::Callback<void(bool success)>> callback;
large_icon_service_
.GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
- GURL(kDummyUrl), /*min_source_size_in_pixel=*/42, callback.Get());
+ GURL(kDummyUrl), /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/true,
+ callback.Get());
EXPECT_CALL(callback, Run(true));
base::RunLoop().RunUntilIdle();
@@ -197,11 +242,11 @@ TEST_F(LargeIconServiceTest, ShouldTrimQueryParametersForGoogleServer) {
const GURL kDummyUrlWithQuery("http://www.example.com?foo=1");
const GURL kExpectedServerUrl(
"https://t0.gstatic.com/faviconV2?client=chrome&drop_404_icon=true"
- "&size=32&min_size=42&max_size=64&fallback_opts=TYPE,SIZE,URL"
- "&url=http://www.example.com/");
+ "&check_seen=true&size=61&min_size=42&max_size=122"
+ "&fallback_opts=TYPE,SIZE,URL&url=http://www.example.com/");
EXPECT_CALL(*mock_image_fetcher_,
- StartOrQueueNetworkRequest(_, kExpectedServerUrl, _))
+ StartOrQueueNetworkRequest(_, kExpectedServerUrl, _, _))
.WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(64, 64, kTestColor))));
// Verify that the non-trimmed page URL is used when writing to the database.
@@ -211,22 +256,45 @@ TEST_F(LargeIconServiceTest, ShouldTrimQueryParametersForGoogleServer) {
large_icon_service_
.GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
GURL(kDummyUrlWithQuery), /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/true,
base::Callback<void(bool success)>());
base::RunLoop().RunUntilIdle();
}
+TEST_F(LargeIconServiceTest, ShouldNotCheckOnPublicUrls) {
+ // The request has no "check_seen=true"; full URL is tested elsewhere.
+ EXPECT_CALL(
+ *mock_image_fetcher_,
+ StartOrQueueNetworkRequest(
+ _, Property(&GURL::query, Not(HasSubstr("check_seen=true"))), _, _))
+ .WillOnce(PostFetchReply(gfx::Image()));
+
+ base::MockCallback<base::Callback<void(bool success)>> callback;
+
+ large_icon_service_
+ .GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
+ GURL(kDummyUrl), /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/false,
+ callback.Get());
+
+ EXPECT_CALL(callback, Run(false));
+ base::RunLoop().RunUntilIdle();
+}
+
TEST_F(LargeIconServiceTest, ShouldNotQueryGoogleServerIfInvalidScheme) {
const GURL kDummyFtpUrl("ftp://www.example.com");
- EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _))
+ EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _, _))
.Times(0);
base::MockCallback<base::Callback<void(bool success)>> callback;
large_icon_service_
.GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
- GURL(kDummyFtpUrl), /*min_source_size_in_pixel=*/42, callback.Get());
+ GURL(kDummyFtpUrl), /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/true,
+ callback.Get());
EXPECT_CALL(callback, Run(false));
base::RunLoop().RunUntilIdle();
@@ -239,22 +307,24 @@ TEST_F(LargeIconServiceTest, ShouldReportUnavailableIfFetchFromServerFails) {
const GURL kDummyUrlWithQuery("http://www.example.com?foo=1");
const GURL kExpectedServerUrl(
"https://t0.gstatic.com/faviconV2?client=chrome&drop_404_icon=true"
- "&size=32&min_size=42&max_size=64&fallback_opts=TYPE,SIZE,URL"
- "&url=http://www.example.com/");
+ "&check_seen=true&size=61&min_size=42&max_size=122"
+ "&fallback_opts=TYPE,SIZE,URL&url=http://www.example.com/");
EXPECT_CALL(mock_favicon_service_, SetLastResortFavicons(_, _, _, _, _))
.Times(0);
base::MockCallback<base::Callback<void(bool success)>> callback;
EXPECT_CALL(*mock_image_fetcher_,
- StartOrQueueNetworkRequest(_, kExpectedServerUrl, _))
+ StartOrQueueNetworkRequest(_, kExpectedServerUrl, _, _))
.WillOnce(PostFetchReply(gfx::Image()));
EXPECT_CALL(mock_favicon_service_,
UnableToDownloadFavicon(kExpectedServerUrl));
large_icon_service_
.GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
- kDummyUrlWithQuery, /*min_source_size_in_pixel=*/42, callback.Get());
+ kDummyUrlWithQuery, /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/true,
+ callback.Get());
EXPECT_CALL(callback, Run(false));
base::RunLoop().RunUntilIdle();
@@ -268,12 +338,12 @@ TEST_F(LargeIconServiceTest, ShouldNotGetFromGoogleServerIfUnavailable) {
mock_favicon_service_,
WasUnableToDownloadFavicon(GURL(
"https://t0.gstatic.com/faviconV2?client=chrome&drop_404_icon=true"
- "&size=32&min_size=42&max_size=64&fallback_opts=TYPE,SIZE,URL"
- "&url=http://www.example.com/")))
+ "&check_seen=true&size=61&min_size=42&max_size=122"
+ "&fallback_opts=TYPE,SIZE,URL&url=http://www.example.com/")))
.WillByDefault(Return(true));
EXPECT_CALL(mock_favicon_service_, UnableToDownloadFavicon(_)).Times(0);
- EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _))
+ EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _, _))
.Times(0);
EXPECT_CALL(mock_favicon_service_, SetLastResortFavicons(_, _, _, _, _))
.Times(0);
@@ -281,7 +351,9 @@ TEST_F(LargeIconServiceTest, ShouldNotGetFromGoogleServerIfUnavailable) {
base::MockCallback<base::Callback<void(bool success)>> callback;
large_icon_service_
.GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
- GURL(kDummyUrl), /*min_source_size_in_pixel=*/42, callback.Get());
+ GURL(kDummyUrl), /*min_source_size_in_pixel=*/42,
+ /*desired_size_in_pixel=*/61, /*may_page_url_be_private=*/true,
+ callback.Get());
EXPECT_CALL(callback, Run(false));
base::RunLoop().RunUntilIdle();
diff --git a/chromium/components/favicon/ios/BUILD.gn b/chromium/components/favicon/ios/BUILD.gn
index 37ef0fbb7e8..5014a92e55b 100644
--- a/chromium/components/favicon/ios/BUILD.gn
+++ b/chromium/components/favicon/ios/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
source_set("ios") {
+ configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"favicon_url_util.cc",
"favicon_url_util.h",
diff --git a/chromium/components/favicon/ios/favicon_url_util.cc b/chromium/components/favicon/ios/favicon_url_util.cc
index 95bcfda262b..54b072c5065 100644
--- a/chromium/components/favicon/ios/favicon_url_util.cc
+++ b/chromium/components/favicon/ios/favicon_url_util.cc
@@ -23,6 +23,8 @@ favicon_base::IconType IconTypeFromWebIconType(
return favicon_base::TOUCH_ICON;
case web::FaviconURL::TOUCH_PRECOMPOSED_ICON:
return favicon_base::TOUCH_PRECOMPOSED_ICON;
+ case web::FaviconURL::WEB_MANIFEST_ICON:
+ return favicon_base::WEB_MANIFEST_ICON;
case web::FaviconURL::INVALID_ICON:
return favicon_base::INVALID_ICON;
}
diff --git a/chromium/components/favicon/ios/web_favicon_driver.h b/chromium/components/favicon/ios/web_favicon_driver.h
index 9b9e7d004da..5006975b335 100644
--- a/chromium/components/favicon/ios/web_favicon_driver.h
+++ b/chromium/components/favicon/ios/web_favicon_driver.h
@@ -24,6 +24,8 @@ class WebFaviconDriver : public web::WebStateObserver,
public web::WebStateUserData<WebFaviconDriver>,
public FaviconDriverImpl {
public:
+ ~WebFaviconDriver() override;
+
static void CreateForWebState(web::WebState* web_state,
FaviconService* favicon_service,
history::HistoryService* history_service,
@@ -39,6 +41,8 @@ class WebFaviconDriver : public web::WebStateObserver,
int DownloadImage(const GURL& url,
int max_image_size,
ImageDownloadCallback callback) override;
+ void DownloadManifest(const GURL& url,
+ ManifestDownloadCallback callback) override;
bool IsOffTheRecord() override;
void OnFaviconUpdated(
const GURL& page_url,
@@ -54,7 +58,6 @@ class WebFaviconDriver : public web::WebStateObserver,
FaviconService* favicon_service,
history::HistoryService* history_service,
bookmarks::BookmarkModel* bookmark_model);
- ~WebFaviconDriver() override;
// web::WebStateObserver implementation.
void FaviconUrlUpdated(
diff --git a/chromium/components/favicon/ios/web_favicon_driver.mm b/chromium/components/favicon/ios/web_favicon_driver.mm
index 500a5f4c435..0025341b757 100644
--- a/chromium/components/favicon/ios/web_favicon_driver.mm
+++ b/chromium/components/favicon/ios/web_favicon_driver.mm
@@ -5,6 +5,7 @@
#include "components/favicon/ios/web_favicon_driver.h"
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "components/favicon/core/favicon_url.h"
#include "components/favicon/ios/favicon_url_util.h"
@@ -18,6 +19,10 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
DEFINE_WEB_STATE_USER_DATA_KEY(favicon::WebFaviconDriver);
// Callback for the download of favicon.
@@ -39,9 +44,9 @@ void WebFaviconDriver::CreateForWebState(
if (FromWebState(web_state))
return;
- web_state->SetUserData(UserDataKey(),
- new WebFaviconDriver(web_state, favicon_service,
- history_service, bookmark_model));
+ web_state->SetUserData(UserDataKey(), base::WrapUnique(new WebFaviconDriver(
+ web_state, favicon_service,
+ history_service, bookmark_model)));
}
void WebFaviconDriver::FetchFavicon(const GURL& url) {
@@ -97,6 +102,11 @@ int WebFaviconDriver::DownloadImage(const GURL& url,
return downloaded_image_count;
}
+void WebFaviconDriver::DownloadManifest(const GURL& url,
+ ManifestDownloadCallback callback) {
+ NOTREACHED();
+}
+
bool WebFaviconDriver::IsOffTheRecord() {
DCHECK(web_state());
return web_state()->GetBrowserState()->IsOffTheRecord();
@@ -136,7 +146,8 @@ WebFaviconDriver::~WebFaviconDriver() {
void WebFaviconDriver::FaviconUrlUpdated(
const std::vector<web::FaviconURL>& candidates) {
DCHECK(!candidates.empty());
- OnUpdateFaviconURL(GetActiveURL(), FaviconURLsFromWebFaviconURLs(candidates));
+ OnUpdateCandidates(GetActiveURL(), FaviconURLsFromWebFaviconURLs(candidates),
+ GURL());
}
} // namespace favicon
diff --git a/chromium/components/favicon_base/favicon_types.h b/chromium/components/favicon_base/favicon_types.h
index 47c63aeb6fa..7ad22ff0b3b 100644
--- a/chromium/components/favicon_base/favicon_types.h
+++ b/chromium/components/favicon_base/favicon_types.h
@@ -23,13 +23,13 @@ typedef int64_t FaviconID;
// Defines the icon types. They are also stored in icon_type field of favicons
// table.
// The values of the IconTypes are used to select the priority in which favicon
-// data is returned in HistoryBackend and ThumbnailDatabase. Data for the
-// largest IconType takes priority if data for multiple IconTypes is available.
+// data is returned in HistoryBackend and ThumbnailDatabase.
enum IconType {
INVALID_ICON = 0x0,
FAVICON = 1 << 0,
TOUCH_ICON = 1 << 1,
- TOUCH_PRECOMPOSED_ICON = 1 << 2
+ TOUCH_PRECOMPOSED_ICON = 1 << 2,
+ WEB_MANIFEST_ICON = 1 << 3,
};
// Defines a gfx::Image of size desired_size_in_dip composed of image
diff --git a/chromium/components/favicon_base/favicon_url_parser.cc b/chromium/components/favicon_base/favicon_url_parser.cc
index 27ee8e1c726..f7de8100808 100644
--- a/chromium/components/favicon_base/favicon_url_parser.cc
+++ b/chromium/components/favicon_base/favicon_url_parser.cc
@@ -16,8 +16,6 @@ namespace {
// "chrome/browser/ui/webui/favicon_source.h" for a description of
// what each does.
const char kIconURLParameter[] = "iconurl/";
-const char kLargestParameter[] = "largest/";
-const char kOriginParameter[] = "origin/";
const char kSizeParameter[] = "size/";
// Returns true if |search| is a substring of |path| which starts at
@@ -33,7 +31,6 @@ bool HasSubstringAt(const std::string& path,
namespace chrome {
bool ParseFaviconPath(const std::string& path,
- int icon_types,
ParsedFaviconPath* parsed) {
parsed->is_icon_url = false;
parsed->url = "";
@@ -45,10 +42,7 @@ bool ParseFaviconPath(const std::string& path,
return false;
size_t parsed_index = 0;
- if (HasSubstringAt(path, parsed_index, kLargestParameter)) {
- parsed_index += strlen(kLargestParameter);
- parsed->size_in_dip = 0;
- } else if (HasSubstringAt(path, parsed_index, kSizeParameter)) {
+ if (HasSubstringAt(path, parsed_index, kSizeParameter)) {
parsed_index += strlen(kSizeParameter);
size_t slash = path.find("/", parsed_index);
@@ -71,24 +65,9 @@ bool ParseFaviconPath(const std::string& path,
if (!base::StringToInt(size_str, &parsed->size_in_dip))
return false;
- if (parsed->size_in_dip != (gfx::kFaviconSize * 4) &&
- parsed->size_in_dip != (gfx::kFaviconSize * 2)) {
- // Only 64x64, 32x32 and 16x16 icons are supported.
- parsed->size_in_dip = gfx::kFaviconSize;
- }
if (!scale_str.empty())
webui::ParseScaleFactor(scale_str, &parsed->device_scale_factor);
- // Return the default favicon (as opposed to a resized favicon) for
- // favicon sizes which are not cached by the favicon service.
- // Currently the favicon service caches:
- // - favicons of sizes "gfx::kFaviconSize * scale factor" px of type FAVICON
- // where scale factor is one of FaviconUtil::GetFaviconScales().
- // - the largest TOUCH_ICON / TOUCH_PRECOMPOSED_ICON
- if (parsed->size_in_dip != gfx::kFaviconSize &&
- icon_types == favicon_base::FAVICON)
- return false;
-
parsed_index = slash + 1;
}
@@ -96,20 +75,6 @@ bool ParseFaviconPath(const std::string& path,
parsed_index += strlen(kIconURLParameter);
parsed->is_icon_url = true;
parsed->url = path.substr(parsed_index);
- } else if (HasSubstringAt(path, parsed_index, kOriginParameter)) {
- // URL requests prefixed with "origin/" are converted to a form with an
- // empty path and a valid scheme. (e.g., example.com -->
- // http://example.com/ or http://example.com/a --> http://example.com/)
- parsed_index += strlen(kOriginParameter);
- std::string possibly_invalid_url = path.substr(parsed_index);
-
- // If the URL does not specify a scheme (e.g., example.com instead of
- // http://example.com), add "http://" as a default.
- if (!GURL(possibly_invalid_url).has_scheme())
- possibly_invalid_url = "http://" + possibly_invalid_url;
-
- // Strip the path beyond the top-level domain.
- parsed->url = GURL(possibly_invalid_url).GetOrigin().spec();
} else {
parsed->url = path.substr(parsed_index);
}
diff --git a/chromium/components/favicon_base/favicon_url_parser.h b/chromium/components/favicon_base/favicon_url_parser.h
index 3e4339262f0..fdedc0ca5f5 100644
--- a/chromium/components/favicon_base/favicon_url_parser.h
+++ b/chromium/components/favicon_base/favicon_url_parser.h
@@ -30,12 +30,10 @@ struct ParsedFaviconPath {
};
// Parses |path|, which should be in the format described at the top of the
-// file "chrome/browser/ui/webui/favicon_source.h". |icon_types| indicates
-// which icon types are supported. Returns true if |path| could be parsed.
-// The result of the parsing will be stored in a ParsedFaviconPath struct.
-bool ParseFaviconPath(const std::string& path,
- int icon_types,
- ParsedFaviconPath* parsed);
+// file "chrome/browser/ui/webui/favicon_source.h". Returns true if |path| could
+// be parsed. The result of the parsing will be stored in a ParsedFaviconPath
+// struct.
+bool ParseFaviconPath(const std::string& path, ParsedFaviconPath* parsed);
} // namespace chrome
diff --git a/chromium/components/favicon_base/favicon_url_parser_unittest.cc b/chromium/components/favicon_base/favicon_url_parser_unittest.cc
index 5220adcb625..48eae908486 100644
--- a/chromium/components/favicon_base/favicon_url_parser_unittest.cc
+++ b/chromium/components/favicon_base/favicon_url_parser_unittest.cc
@@ -36,11 +36,10 @@ class FaviconUrlParserTest : public testing::Test {
// Test parsing path with no extra parameters.
TEST_F(FaviconUrlParserTest, ParsingNoExtraParams) {
const std::string url("https://www.google.ca/imghp?hl=en&tab=wi");
- int icon_types = favicon_base::TOUCH_PRECOMPOSED_ICON;
chrome::ParsedFaviconPath parsed;
const std::string path1 = url;
- EXPECT_TRUE(chrome::ParseFaviconPath(path1, icon_types, &parsed));
+ EXPECT_TRUE(chrome::ParseFaviconPath(path1, &parsed));
EXPECT_FALSE(parsed.is_icon_url);
EXPECT_EQ(url, parsed.url);
EXPECT_EQ(16, parsed.size_in_dip);
@@ -50,12 +49,11 @@ TEST_F(FaviconUrlParserTest, ParsingNoExtraParams) {
// Test parsing path with a 'size' parameter.
TEST_F(FaviconUrlParserTest, ParsingSizeParam) {
const std::string url("https://www.google.ca/imghp?hl=en&tab=wi");
- int icon_types = favicon_base::TOUCH_PRECOMPOSED_ICON;
chrome::ParsedFaviconPath parsed;
// Test that we can still parse the legacy 'size' parameter format.
const std::string path2 = "size/32/" + url;
- EXPECT_TRUE(chrome::ParseFaviconPath(path2, icon_types, &parsed));
+ EXPECT_TRUE(chrome::ParseFaviconPath(path2, &parsed));
EXPECT_FALSE(parsed.is_icon_url);
EXPECT_EQ(url, parsed.url);
EXPECT_EQ(32, parsed.size_in_dip);
@@ -63,7 +61,7 @@ TEST_F(FaviconUrlParserTest, ParsingSizeParam) {
// Test parsing current 'size' parameter format.
const std::string path3 = "size/32@1.4x/" + url;
- EXPECT_TRUE(chrome::ParseFaviconPath(path3, icon_types, &parsed));
+ EXPECT_TRUE(chrome::ParseFaviconPath(path3, &parsed));
EXPECT_FALSE(parsed.is_icon_url);
EXPECT_EQ(url, parsed.url);
EXPECT_EQ(32, parsed.size_in_dip);
@@ -72,7 +70,7 @@ TEST_F(FaviconUrlParserTest, ParsingSizeParam) {
// Test that we pick the ui::ScaleFactor which is closest to the passed in
// scale factor.
const std::string path4 = "size/16@1.41x/" + url;
- EXPECT_TRUE(chrome::ParseFaviconPath(path4, icon_types, &parsed));
+ EXPECT_TRUE(chrome::ParseFaviconPath(path4, &parsed));
EXPECT_FALSE(parsed.is_icon_url);
EXPECT_EQ(url, parsed.url);
EXPECT_EQ(16, parsed.size_in_dip);
@@ -80,88 +78,44 @@ TEST_F(FaviconUrlParserTest, ParsingSizeParam) {
// Invalid cases.
const std::string path5 = "size/" + url;
- EXPECT_FALSE(chrome::ParseFaviconPath(path5, icon_types, &parsed));
+ EXPECT_FALSE(chrome::ParseFaviconPath(path5, &parsed));
const std::string path6 = "size/@1x/" + url;
- EXPECT_FALSE(chrome::ParseFaviconPath(path6, icon_types, &parsed));
+ EXPECT_FALSE(chrome::ParseFaviconPath(path6, &parsed));
const std::string path7 = "size/abc@1x/" + url;
- EXPECT_FALSE(chrome::ParseFaviconPath(path7, icon_types, &parsed));
+ EXPECT_FALSE(chrome::ParseFaviconPath(path7, &parsed));
// Part of url looks like 'size' parameter.
const std::string path8 = "http://www.google.com/size/32@1.4x";
- EXPECT_TRUE(chrome::ParseFaviconPath(path8, icon_types, &parsed));
+ EXPECT_TRUE(chrome::ParseFaviconPath(path8, &parsed));
EXPECT_FALSE(parsed.is_icon_url);
EXPECT_EQ(path8, parsed.url);
EXPECT_EQ(16, parsed.size_in_dip);
EXPECT_EQ(1.0f, parsed.device_scale_factor);
}
-// Test parsing path with the 'largest' parameter.
-TEST_F(FaviconUrlParserTest, ParsingLargestParam) {
- const std::string url("https://www.google.ca/imghp?hl=en&tab=wi");
- int icon_types = favicon_base::TOUCH_PRECOMPOSED_ICON;
- chrome::ParsedFaviconPath parsed;
-
- const std::string path9 = "largest/" + url;
- EXPECT_TRUE(chrome::ParseFaviconPath(path9, icon_types, &parsed));
- EXPECT_FALSE(parsed.is_icon_url);
- EXPECT_EQ(url, parsed.url);
- EXPECT_EQ(0, parsed.size_in_dip);
- // The scale factor is meaningless when requesting the largest favicon.
-}
-
// Test parsing path with 'iconurl' parameter.
TEST_F(FaviconUrlParserTest, ParsingIconUrlParam) {
const std::string url("https://www.google.ca/imghp?hl=en&tab=wi");
- int icon_types = favicon_base::TOUCH_PRECOMPOSED_ICON;
chrome::ParsedFaviconPath parsed;
const std::string path10 = "iconurl/http://www.google.com/favicon.ico";
- EXPECT_TRUE(chrome::ParseFaviconPath(path10, icon_types, &parsed));
+ EXPECT_TRUE(chrome::ParseFaviconPath(path10, &parsed));
EXPECT_TRUE(parsed.is_icon_url);
EXPECT_EQ("http://www.google.com/favicon.ico", parsed.url);
EXPECT_EQ(16, parsed.size_in_dip);
EXPECT_EQ(1.0f, parsed.device_scale_factor);
}
-// Test parsing path with 'origin' parameter.
-TEST_F(FaviconUrlParserTest, ParsingOriginParam) {
- const std::string url("https://www.google.ca/imghp?hl=en&tab=wi");
- int icon_types = favicon_base::TOUCH_PRECOMPOSED_ICON;
- chrome::ParsedFaviconPath parsed;
-
- const std::string path11 = "origin/" + url;
- EXPECT_TRUE(chrome::ParseFaviconPath(path11, icon_types, &parsed));
- EXPECT_FALSE(parsed.is_icon_url);
- EXPECT_EQ("https://www.google.ca/", parsed.url);
- EXPECT_EQ(16, parsed.size_in_dip);
- EXPECT_EQ(1.0f, parsed.device_scale_factor);
-
- const std::string path12 = "origin/google.com";
- EXPECT_TRUE(chrome::ParseFaviconPath(path12, icon_types, &parsed));
- EXPECT_FALSE(parsed.is_icon_url);
- EXPECT_EQ("http://google.com/", parsed.url);
- EXPECT_EQ(16, parsed.size_in_dip);
- EXPECT_EQ(1.0f, parsed.device_scale_factor);
-}
-
// Test parsing paths with both a 'size' parameter and a 'url modifier'
// parameter.
TEST_F(FaviconUrlParserTest, ParsingSizeParamAndUrlModifier) {
const std::string url("https://www.google.ca/imghp?hl=en&tab=wi");
- int icon_types = favicon_base::TOUCH_PRECOMPOSED_ICON;
chrome::ParsedFaviconPath parsed;
- const std::string path13 = "size/32@1.4x/origin/" + url;
- EXPECT_TRUE(chrome::ParseFaviconPath(path13, icon_types, &parsed));
- EXPECT_FALSE(parsed.is_icon_url);
- EXPECT_EQ("https://www.google.ca/", parsed.url);
- EXPECT_EQ(32, parsed.size_in_dip);
- EXPECT_EQ(1.4f, parsed.device_scale_factor);
-
const std::string path14 =
- "largest/iconurl/http://www.google.com/favicon.ico";
- EXPECT_TRUE(chrome::ParseFaviconPath(path14, icon_types, &parsed));
+ "size/32/iconurl/http://www.google.com/favicon.ico";
+ EXPECT_TRUE(chrome::ParseFaviconPath(path14, &parsed));
EXPECT_TRUE(parsed.is_icon_url);
EXPECT_EQ("http://www.google.com/favicon.ico", parsed.url);
- EXPECT_EQ(0, parsed.size_in_dip);
+ EXPECT_EQ(32, parsed.size_in_dip);
}
diff --git a/chromium/components/favicon_base/select_favicon_frames_unittest.cc b/chromium/components/favicon_base/select_favicon_frames_unittest.cc
index 4fe404459c1..f2a6f542754 100644
--- a/chromium/components/favicon_base/select_favicon_frames_unittest.cc
+++ b/chromium/components/favicon_base/select_favicon_frames_unittest.cc
@@ -59,9 +59,7 @@ SkColor GetColor(const gfx::ImageSkia& image, float scale,
x = bitmap.width() / 2;
if (y == -1)
y = bitmap.width() / 2;
- bitmap.lockPixels();
SkColor color = bitmap.getColor(x, y);
- bitmap.unlockPixels();
return color;
}
diff --git a/chromium/components/feature_engagement_tracker/BUILD.gn b/chromium/components/feature_engagement_tracker/BUILD.gn
index 454c5105ea7..cb24ce6c0c9 100644
--- a/chromium/components/feature_engagement_tracker/BUILD.gn
+++ b/chromium/components/feature_engagement_tracker/BUILD.gn
@@ -23,6 +23,18 @@ group("unit_tests") {
deps = [
"//components/feature_engagement_tracker/internal:unit_tests",
]
+
+ data_deps = [
+ ":components_unittests_gtest_filter",
+ ]
+}
+
+source_set("components_unittests_gtest_filter") {
+ testonly = true
+
+ data = [
+ "components_unittests.filter",
+ ]
}
if (is_android) {
diff --git a/chromium/components/feature_engagement_tracker/DEPS b/chromium/components/feature_engagement_tracker/DEPS
index 1347398646b..48edfa45a2c 100644
--- a/chromium/components/feature_engagement_tracker/DEPS
+++ b/chromium/components/feature_engagement_tracker/DEPS
@@ -1,5 +1,7 @@
include_rules = [
"-content",
"+jni",
+ "+components/flags_ui",
"+components/keyed_service",
+ "+components/leveldb_proto",
]
diff --git a/chromium/components/feature_engagement_tracker/README.md b/chromium/components/feature_engagement_tracker/README.md
index d55b95aa074..e912703aa72 100644
--- a/chromium/components/feature_engagement_tracker/README.md
+++ b/chromium/components/feature_engagement_tracker/README.md
@@ -12,3 +12,33 @@ feature enlightenment or in-product help itself.
The backend is feature agnostic and have no special logic for any specific
features, but instead provides a generic API.
+
+## Compiling for platforms other than Android
+
+For now the code for the Feature Engagement Tracker is only compiled in
+for Android, but only a shim layer is really dependent on Android to provide a
+JNI bridge. The goal is to keep all the business logic in the cross-platform
+part of the code.
+
+For local development, it is therefore possible to compile and run tests for
+the core of the tracker on other platforms. To do this, simply add the
+following line to the `//components:components_unittests` target:
+
+```python
+deps += [ "//components/feature_engagement_tracker:unit_tests" ]
+```
+
+## Testing
+
+To compile and run tests, assuming the product out directory is `out/Debug`,
+use:
+
+```bash
+ninja -C out/Debug components_unittests ;
+./out/Debug/components_unittests \
+ --test-launcher-filter-file=components/feature_engagement_tracker/components_unittests.filter
+```
+
+When adding new test suites, also remember to add the suite to the filter file:
+`//components/feature_engagement_tracker/components_unittests.filter`.
+
diff --git a/chromium/components/feature_engagement_tracker/components_unittests.filter b/chromium/components/feature_engagement_tracker/components_unittests.filter
new file mode 100644
index 00000000000..aa34f4a6045
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/components_unittests.filter
@@ -0,0 +1,21 @@
+AvailabilityModelImplTest.*
+AvailabilityStoreTest.*
+ChromeVariationsConfigurationTest.*
+ComparatorTest.*
+ConditionValidatorResultTest.*
+EditableConfigurationTest.*
+FailingStoreInitFeatureEngagementTrackerImplTest.*
+FailingAvailabilityModelInitFeatureEngagementTrackerImplTest.*
+FeatureConfigConditionValidatorTest.*
+FeatureConfigStorageValidatorTest.*
+FeatureEngagementTrackerImplTest.*
+InitAwareModelTest.*
+InMemoryStoreTest.*
+LoadFailingModelImplTest.*
+ModelImplTest.*
+NeverAvailabilityModelTest.*
+NeverConditionValidatorTest.*
+OnceConditionValidatorTest.*
+PersistentStoreTest.*
+SingleInvalidConfigurationTest.*
+SystemTimeProviderTest.*
diff --git a/chromium/components/feature_engagement_tracker/internal/BUILD.gn b/chromium/components/feature_engagement_tracker/internal/BUILD.gn
index 00badef306e..5f7122165b4 100644
--- a/chromium/components/feature_engagement_tracker/internal/BUILD.gn
+++ b/chromium/components/feature_engagement_tracker/internal/BUILD.gn
@@ -14,28 +14,51 @@ static_library("internal") {
]
sources = [
+ "availability_model.h",
+ "availability_model_impl.cc",
+ "availability_model_impl.h",
+ "availability_store.cc",
+ "availability_store.h",
+ "chrome_variations_configuration.cc",
+ "chrome_variations_configuration.h",
+ "condition_validator.cc",
"condition_validator.h",
"configuration.cc",
"configuration.h",
"editable_configuration.cc",
"editable_configuration.h",
- "feature_constants.cc",
+ "feature_config_condition_validator.cc",
+ "feature_config_condition_validator.h",
+ "feature_config_storage_validator.cc",
+ "feature_config_storage_validator.h",
"feature_engagement_tracker_impl.cc",
"feature_engagement_tracker_impl.h",
- "feature_list.cc",
- "feature_list.h",
"in_memory_store.cc",
"in_memory_store.h",
+ "init_aware_model.cc",
+ "init_aware_model.h",
"model.h",
"model_impl.cc",
"model_impl.h",
+ "never_availability_model.cc",
+ "never_availability_model.h",
"never_condition_validator.cc",
"never_condition_validator.h",
+ "never_storage_validator.cc",
+ "never_storage_validator.h",
"once_condition_validator.cc",
"once_condition_validator.h",
+ "persistent_store.cc",
+ "persistent_store.h",
"single_invalid_configuration.cc",
"single_invalid_configuration.h",
+ "stats.cc",
+ "stats.h",
+ "storage_validator.h",
"store.h",
+ "system_time_provider.cc",
+ "system_time_provider.h",
+ "time_provider.h",
]
public_deps = [
@@ -46,6 +69,7 @@ static_library("internal") {
"//base",
"//components/feature_engagement_tracker/public",
"//components/keyed_service/core",
+ "//components/leveldb_proto",
]
if (is_android) {
@@ -64,19 +88,37 @@ source_set("unit_tests") {
visibility = [ "//components/feature_engagement_tracker:unit_tests" ]
+ # IMPORTANT NOTE: When adding new tests, also remember to update the list of
+ # tests in //components/feature_engagement_tracker/components_unittests.filter
sources = [
+ "availability_model_impl_unittest.cc",
+ "availability_store_unittest.cc",
+ "chrome_variations_configuration_unittest.cc",
+ "condition_validator_unittest.cc",
+ "configuration_unittest.cc",
"editable_configuration_unittest.cc",
+ "feature_config_condition_validator_unittest.cc",
+ "feature_config_storage_validator_unittest.cc",
"feature_engagement_tracker_impl_unittest.cc",
"in_memory_store_unittest.cc",
+ "init_aware_model_unittest.cc",
"model_impl_unittest.cc",
+ "never_availability_model_unittest.cc",
"never_condition_validator_unittest.cc",
+ "never_storage_validator_unittest.cc",
"once_condition_validator_unittest.cc",
+ "persistent_store_unittest.cc",
"single_invalid_configuration_unittest.cc",
+ "system_time_provider_unittest.cc",
]
deps = [
":internal",
"//base/test:test_support",
+ "//components/feature_engagement_tracker/internal/test:test_support",
+ "//components/feature_engagement_tracker/public",
+ "//components/leveldb_proto:test_support",
+ "//testing/gmock",
"//testing/gtest",
]
}
diff --git a/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc b/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc
index 9d8a362b803..c2dd33f74c3 100644
--- a/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc
+++ b/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc
@@ -6,12 +6,15 @@
#include <vector>
+#include "base/android/callback_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
#include "base/feature_list.h"
-#include "components/feature_engagement_tracker/internal/feature_list.h"
+#include "base/memory/ptr_util.h"
#include "components/feature_engagement_tracker/public/feature_engagement_tracker.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
#include "jni/FeatureEngagementTrackerImpl_jni.h"
namespace feature_engagement_tracker {
@@ -41,7 +44,8 @@ FeatureEngagementTrackerImplAndroid* FromFeatureEngagementTrackerImpl(
if (!impl_android) {
impl_android =
new FeatureEngagementTrackerImplAndroid(impl, GetAllFeatures());
- impl->SetUserData(kFeatureEngagementTrackerImplAndroidKey, impl_android);
+ impl->SetUserData(kFeatureEngagementTrackerImplAndroidKey,
+ base::WrapUnique(impl_android));
}
return impl_android;
}
@@ -117,15 +121,30 @@ bool FeatureEngagementTrackerImplAndroid::ShouldTriggerHelpUI(
void FeatureEngagementTrackerImplAndroid::Dismissed(
JNIEnv* env,
+ const base::android::JavaRef<jobject>& jobj,
+ const base::android::JavaParamRef<jstring>& jfeature) {
+ std::string feature = ConvertJavaStringToUTF8(env, jfeature);
+ DCHECK(features_.find(feature) != features_.end());
+
+ feature_engagement_tracker_impl_->Dismissed(*features_[feature]);
+}
+
+bool FeatureEngagementTrackerImplAndroid::IsInitialized(
+ JNIEnv* env,
const base::android::JavaRef<jobject>& jobj) {
- feature_engagement_tracker_impl_->Dismissed();
+ return feature_engagement_tracker_impl_->IsInitialized();
}
void FeatureEngagementTrackerImplAndroid::AddOnInitializedCallback(
JNIEnv* env,
const base::android::JavaRef<jobject>& jobj,
const base::android::JavaParamRef<jobject>& j_callback_obj) {
- // TODO(nyquist): Implement support for the wrapped base::Callback.
+ // Disambiguate RunCallbackAndroid to get the reference to the bool version.
+ void (*runBoolCallback)(const base::android::JavaRef<jobject>&, bool) =
+ &base::android::RunCallbackAndroid;
+ feature_engagement_tracker_impl_->AddOnInitializedCallback(
+ base::Bind(runBoolCallback,
+ base::android::ScopedJavaGlobalRef<jobject>(j_callback_obj)));
}
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h b/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h
index 1234ae82724..88184741ae8 100644
--- a/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h
+++ b/chromium/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h
@@ -14,7 +14,7 @@
#include "base/macros.h"
#include "base/supports_user_data.h"
#include "components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h"
-#include "components/feature_engagement_tracker/internal/feature_list.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
namespace base {
struct Feature;
@@ -53,7 +53,10 @@ class FeatureEngagementTrackerImplAndroid
const base::android::JavaRef<jobject>& jobj,
const base::android::JavaParamRef<jstring>& jfeature);
virtual void Dismissed(JNIEnv* env,
- const base::android::JavaRef<jobject>& jobj);
+ const base::android::JavaRef<jobject>& jobj,
+ const base::android::JavaParamRef<jstring>& jfeature);
+ virtual bool IsInitialized(JNIEnv* env,
+ const base::android::JavaRef<jobject>& jobj);
virtual void AddOnInitializedCallback(
JNIEnv* env,
const base::android::JavaRef<jobject>& jobj,
diff --git a/chromium/components/feature_engagement_tracker/internal/availability_model.h b/chromium/components/feature_engagement_tracker/internal/availability_model.h
new file mode 100644
index 00000000000..55011825431
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/availability_model.h
@@ -0,0 +1,54 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_MODEL_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_MODEL_H_
+
+#include <stdint.h>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/optional.h"
+
+namespace base {
+struct Feature;
+} // namespace base
+
+namespace feature_engagement_tracker {
+
+// An AvailabilityModel tracks when each feature was made available to an
+// end user.
+class AvailabilityModel {
+ public:
+ // Invoked when the availability data has finished loading, and whether the
+ // load was a success. In the case of a failure, it is invalid to ever call
+ // GetAvailability(...).
+ using OnInitializedCallback = base::OnceCallback<void(bool success)>;
+
+ virtual ~AvailabilityModel() = default;
+
+ // Starts initialization of the AvailabilityModel.
+ virtual void Initialize(OnInitializedCallback callback,
+ uint32_t current_day) = 0;
+
+ // Returns whether the model is ready, i.e. whether it has been successfully
+ // initialized.
+ virtual bool IsReady() const = 0;
+
+ // Returns the day number since epoch (1970-01-01) in the local timezone for
+ // when the particular |feature| was made available.
+ // See TimeProvider::GetCurrentDay().
+ virtual base::Optional<uint32_t> GetAvailability(
+ const base::Feature& feature) const = 0;
+
+ protected:
+ AvailabilityModel() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AvailabilityModel);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_MODEL_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/availability_model_impl.cc b/chromium/components/feature_engagement_tracker/internal/availability_model_impl.cc
new file mode 100644
index 00000000000..fb00d8495b4
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/availability_model_impl.cc
@@ -0,0 +1,63 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/availability_model_impl.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "components/feature_engagement_tracker/internal/availability_store.h"
+
+namespace feature_engagement_tracker {
+
+AvailabilityModelImpl::AvailabilityModelImpl(
+ StoreLoadCallback store_load_callback)
+ : ready_(false),
+ store_load_callback_(std::move(store_load_callback)),
+ weak_ptr_factory_(this) {}
+
+AvailabilityModelImpl::~AvailabilityModelImpl() = default;
+
+void AvailabilityModelImpl::Initialize(OnInitializedCallback callback,
+ uint32_t current_day) {
+ DCHECK(store_load_callback_);
+ std::move(store_load_callback_)
+ .Run(base::BindOnce(&AvailabilityModelImpl::OnStoreLoadComplete,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
+ current_day);
+}
+
+bool AvailabilityModelImpl::IsReady() const {
+ return ready_;
+}
+
+base::Optional<uint32_t> AvailabilityModelImpl::GetAvailability(
+ const base::Feature& feature) const {
+ auto search = feature_availabilities_.find(&feature);
+ if (search == feature_availabilities_.end())
+ return base::nullopt;
+
+ return search->second;
+}
+
+void AvailabilityModelImpl::OnStoreLoadComplete(
+ OnInitializedCallback on_initialized_callback,
+ bool success,
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>>
+ feature_availabilities) {
+ if (!success) {
+ std::move(on_initialized_callback).Run(false);
+ return;
+ }
+
+ feature_availabilities_ = std::move(*feature_availabilities);
+
+ ready_ = true;
+ std::move(on_initialized_callback).Run(true);
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/availability_model_impl.h b/chromium/components/feature_engagement_tracker/internal/availability_model_impl.h
new file mode 100644
index 00000000000..f32b12f0b3d
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/availability_model_impl.h
@@ -0,0 +1,69 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_MODEL_IMPL_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_MODEL_IMPL_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/feature_engagement_tracker/internal/availability_model.h"
+#include "components/feature_engagement_tracker/internal/availability_store.h"
+
+namespace base {
+struct Feature;
+} // namespace base
+
+namespace feature_engagement_tracker {
+class AvailabilityStore;
+
+// An AvailabilityModel which supports loading data from an AvailabilityStore.
+class AvailabilityModelImpl : public AvailabilityModel {
+ public:
+ using StoreLoadCallback =
+ base::OnceCallback<void(AvailabilityStore::OnLoadedCallback,
+ uint32_t current_day)>;
+
+ explicit AvailabilityModelImpl(StoreLoadCallback load_callback);
+ ~AvailabilityModelImpl() override;
+
+ // AvailabilityModel implementation.
+ void Initialize(OnInitializedCallback callback,
+ uint32_t current_day) override;
+ bool IsReady() const override;
+ base::Optional<uint32_t> GetAvailability(
+ const base::Feature& feature) const override;
+
+ private:
+ // This is invoked when the store has completed loading.
+ void OnStoreLoadComplete(
+ OnInitializedCallback on_initialized_callback,
+ bool success,
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>>
+ feature_availabilities);
+
+ // Stores the day number since epoch (1970-01-01) in the local timezone for
+ // when the particular |feature| was made available.
+ std::map<const base::Feature*, uint32_t> feature_availabilities_;
+
+ // Whether the model has successfully initialied.
+ bool ready_;
+
+ // A callback for loading availability data from the store. This is reset
+ // as soon as it is invoked.
+ StoreLoadCallback store_load_callback_;
+
+ base::WeakPtrFactory<AvailabilityModelImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AvailabilityModelImpl);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_MODEL_IMPL_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc b/chromium/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc
new file mode 100644
index 00000000000..490955cc3a7
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc
@@ -0,0 +1,138 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/availability_model_impl.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/optional.h"
+#include "components/feature_engagement_tracker/internal/availability_store.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+const base::Feature kTestFeatureFoo{"test_foo",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureBar{"test_bar",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureQux{"test_qux",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureNop{"test_nop",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+class AvailabilityModelImplTest : public testing::Test {
+ public:
+ AvailabilityModelImplTest() {
+ initialized_callback_ = base::BindOnce(
+ &AvailabilityModelImplTest::OnInitialized, base::Unretained(this));
+ }
+
+ ~AvailabilityModelImplTest() override = default;
+
+ // SetUpModel exists so that the filter can be changed for any test.
+ void SetUpModel(
+ bool success,
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>> store_content) {
+ auto store_loader = base::BindOnce(&AvailabilityModelImplTest::StoreLoader,
+ base::Unretained(this), success,
+ std::move(store_content));
+ availability_model_ =
+ base::MakeUnique<AvailabilityModelImpl>(std::move(store_loader));
+ }
+
+ void OnInitialized(bool success) { success_ = success; }
+
+ void StoreLoader(
+ bool success,
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>> store_content,
+ AvailabilityStore::OnLoadedCallback callback,
+ uint32_t current_day) {
+ current_day_ = current_day;
+ std::move(callback).Run(success, std::move(store_content));
+ }
+
+ protected:
+ std::unique_ptr<AvailabilityModelImpl> availability_model_;
+
+ AvailabilityModel::OnInitializedCallback initialized_callback_;
+ base::Optional<bool> success_;
+ base::Optional<uint32_t> current_day_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AvailabilityModelImplTest);
+};
+
+} // namespace
+
+TEST_F(AvailabilityModelImplTest, InitializationSuccess) {
+ SetUpModel(true,
+ base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+ EXPECT_FALSE(availability_model_->IsReady());
+ availability_model_->Initialize(std::move(initialized_callback_), 14u);
+ EXPECT_TRUE(availability_model_->IsReady());
+ EXPECT_TRUE(success_.has_value());
+ EXPECT_TRUE(success_.value());
+ EXPECT_EQ(14u, current_day_);
+}
+
+TEST_F(AvailabilityModelImplTest, InitializationFailed) {
+ SetUpModel(false,
+ base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+ EXPECT_FALSE(availability_model_->IsReady());
+ availability_model_->Initialize(std::move(initialized_callback_), 14u);
+ EXPECT_FALSE(availability_model_->IsReady());
+ EXPECT_TRUE(success_.has_value());
+ EXPECT_FALSE(success_.value());
+ EXPECT_EQ(14u, current_day_);
+}
+
+TEST_F(AvailabilityModelImplTest, SuccessfullyLoadThreeFeatures) {
+ auto availabilities =
+ base::MakeUnique<std::map<const base::Feature*, uint32_t>>();
+ availabilities->insert(std::make_pair(&kTestFeatureFoo, 100u));
+ availabilities->insert(std::make_pair(&kTestFeatureBar, 200u));
+ availabilities->insert(std::make_pair(&kTestFeatureNop, 300u));
+
+ SetUpModel(true, std::move(availabilities));
+ availability_model_->Initialize(std::move(initialized_callback_), 14u);
+ EXPECT_TRUE(availability_model_->IsReady());
+
+ EXPECT_EQ(100u, availability_model_->GetAvailability(kTestFeatureFoo));
+ EXPECT_EQ(200u, availability_model_->GetAvailability(kTestFeatureBar));
+ EXPECT_EQ(300u, availability_model_->GetAvailability(kTestFeatureNop));
+ EXPECT_EQ(base::nullopt,
+ availability_model_->GetAvailability(kTestFeatureQux));
+}
+
+TEST_F(AvailabilityModelImplTest, FailToLoadThreeFeatures) {
+ auto availabilities =
+ base::MakeUnique<std::map<const base::Feature*, uint32_t>>();
+ availabilities->insert(std::make_pair(&kTestFeatureFoo, 100u));
+ availabilities->insert(std::make_pair(&kTestFeatureBar, 200u));
+ availabilities->insert(std::make_pair(&kTestFeatureNop, 300u));
+
+ SetUpModel(false, std::move(availabilities));
+ availability_model_->Initialize(std::move(initialized_callback_), 14u);
+ EXPECT_FALSE(availability_model_->IsReady());
+
+ // Load failed, so all results should be ignored.
+ EXPECT_EQ(base::nullopt,
+ availability_model_->GetAvailability(kTestFeatureFoo));
+ EXPECT_EQ(base::nullopt,
+ availability_model_->GetAvailability(kTestFeatureBar));
+ EXPECT_EQ(base::nullopt,
+ availability_model_->GetAvailability(kTestFeatureNop));
+ EXPECT_EQ(base::nullopt,
+ availability_model_->GetAvailability(kTestFeatureQux));
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/availability_store.cc b/chromium/components/feature_engagement_tracker/internal/availability_store.cc
new file mode 100644
index 00000000000..887781826d7
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/availability_store.cc
@@ -0,0 +1,154 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/availability_store.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
+#include "components/feature_engagement_tracker/internal/proto/availability.pb.h"
+#include "components/feature_engagement_tracker/internal/stats.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+#include "components/leveldb_proto/proto_database.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+using KeyAvailabilityPair = std::pair<std::string, Availability>;
+using KeyAvailabilityList = std::vector<KeyAvailabilityPair>;
+
+// Corresponds to a UMA suffix "LevelDBOpenResults" in histograms.xml.
+// Please do not change.
+const char kDatabaseUMAName[] = "FeatureEngagementTrackerAvailabilityStore";
+
+void OnDBUpdateComplete(
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Availability>> db,
+ AvailabilityStore::OnLoadedCallback on_loaded_callback,
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>>
+ feature_availabilities,
+ bool success) {
+ stats::RecordDbUpdate(success, stats::StoreType::AVAILABILITY_STORE);
+ std::move(on_loaded_callback).Run(success, std::move(feature_availabilities));
+}
+
+void OnDBLoadComplete(
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Availability>> db,
+ FeatureVector feature_filter,
+ AvailabilityStore::OnLoadedCallback on_loaded_callback,
+ uint32_t current_day,
+ bool success,
+ std::unique_ptr<std::vector<Availability>> availabilities) {
+ stats::RecordAvailabilityDbLoadEvent(success);
+ if (!success) {
+ std::move(on_loaded_callback)
+ .Run(false,
+ base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+ return;
+ }
+
+ // Create map from feature name to Feature.
+ std::map<std::string, const base::Feature*> feature_mapping;
+ for (const base::Feature* feature : feature_filter) {
+ DCHECK(feature_mapping.find(feature->name) == feature_mapping.end());
+ feature_mapping[feature->name] = feature;
+ }
+
+ // Find all availabilities from DB and find out what should be deleted.
+ auto feature_availabilities =
+ base::MakeUnique<std::map<const base::Feature*, uint32_t>>();
+ auto deletes = base::MakeUnique<std::vector<std::string>>();
+ for (auto& availability : *availabilities) {
+ // Check if in |feature_filter|.
+ if (feature_mapping.find(availability.feature_name()) ==
+ feature_mapping.end()) {
+ deletes->push_back(availability.feature_name());
+ continue;
+ }
+
+ // Check if enabled.
+ const base::Feature* feature = feature_mapping[availability.feature_name()];
+ if (!base::FeatureList::IsEnabled(*feature)) {
+ deletes->push_back(availability.feature_name());
+ continue;
+ }
+
+ // Both in |feature_filter| and is enabled, so keep around.
+ feature_availabilities->insert(std::make_pair(feature, availability.day()));
+ }
+
+ // Find features from |feature_filter| that are enabled, but not in DB yet.
+ auto additions = base::MakeUnique<KeyAvailabilityList>();
+ for (const base::Feature* feature : feature_filter) {
+ // Check if already in DB.
+ if (feature_availabilities->find(feature) != feature_availabilities->end())
+ continue;
+
+ // Check if enabled.
+ if (!base::FeatureList::IsEnabled(*feature))
+ continue;
+
+ // Both in feature filter, and is enabled, but not in DB, so add to DB.
+ Availability availability;
+ availability.set_feature_name(feature->name);
+ availability.set_day(current_day);
+ additions->push_back(
+ std::make_pair(availability.feature_name(), std::move(availability)));
+
+ // Since it will be written to the DB, also add to the callback result.
+ feature_availabilities->insert(std::make_pair(feature, availability.day()));
+ }
+
+ // Write all changes to the DB.
+ auto* db_ptr = db.get();
+ db_ptr->UpdateEntries(std::move(additions), std::move(deletes),
+ base::BindOnce(&OnDBUpdateComplete, std::move(db),
+ std::move(on_loaded_callback),
+ std::move(feature_availabilities)));
+}
+
+void OnDBInitComplete(
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Availability>> db,
+ FeatureVector feature_filter,
+ AvailabilityStore::OnLoadedCallback on_loaded_callback,
+ uint32_t current_day,
+ bool success) {
+ stats::RecordDbInitEvent(success, stats::StoreType::AVAILABILITY_STORE);
+
+ if (!success) {
+ std::move(on_loaded_callback)
+ .Run(false,
+ base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+ return;
+ }
+
+ auto* db_ptr = db.get();
+ db_ptr->LoadEntries(base::BindOnce(
+ &OnDBLoadComplete, std::move(db), std::move(feature_filter),
+ std::move(on_loaded_callback), current_day));
+}
+
+} // namespace
+
+// static
+void AvailabilityStore::LoadAndUpdateStore(
+ const base::FilePath& storage_dir,
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Availability>> db,
+ FeatureVector feature_filter,
+ AvailabilityStore::OnLoadedCallback on_loaded_callback,
+ uint32_t current_day) {
+ auto* db_ptr = db.get();
+ db_ptr->Init(kDatabaseUMAName, storage_dir,
+ base::BindOnce(&OnDBInitComplete, std::move(db),
+ std::move(feature_filter),
+ std::move(on_loaded_callback), current_day));
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/availability_store.h b/chromium/components/feature_engagement_tracker/internal/availability_store.h
new file mode 100644
index 00000000000..891b07c3248
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/availability_store.h
@@ -0,0 +1,63 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_STORE_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_STORE_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "components/feature_engagement_tracker/internal/proto/availability.pb.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+#include "components/leveldb_proto/proto_database.h"
+
+namespace base {
+struct Feature;
+class FilePath;
+} // namespace base
+
+namespace feature_engagement_tracker {
+
+// An AvailabilityStore provides a way to load and update the availability date
+// for all registered features.
+class AvailabilityStore {
+ public:
+ // Invoked when the availability data has finished loading, and whether the
+ // load was a success. In the case of a failure, the map argument will be
+ // empty. The value for each entry in the map is the day number since epoch
+ // (1970-01-01) in the local timezone for when the particular feature was made
+ // available.
+ using OnLoadedCallback = base::OnceCallback<void(
+ bool success,
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>>)>;
+
+ // Loads the availability data, updates the DB with newly enabled features,
+ // deletes features that are not enabled anymore, and asynchronously invokes
+ // |on_loaded_callback| with the result. The result will mirror the content
+ // of the database.
+ // The |feature_filter| is used to filter the data from the DB and ensure
+ // that only enabled features listed in this filter are tracked. For enabled
+ // features that are in the |feature_filter|, but not in the DB, they are
+ // tracked as new entries with the |current_day| as the availability day.
+ static void LoadAndUpdateStore(
+ const base::FilePath& storage_dir,
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Availability>> db,
+ FeatureVector feature_filter,
+ OnLoadedCallback on_loaded_callback,
+ uint32_t current_day);
+
+ private:
+ AvailabilityStore() = default;
+ ~AvailabilityStore() = default;
+
+ DISALLOW_COPY_AND_ASSIGN(AvailabilityStore);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_AVAILABILITY_STORE_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/availability_store_unittest.cc b/chromium/components/feature_engagement_tracker/internal/availability_store_unittest.cc
new file mode 100644
index 00000000000..a65f574458d
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/availability_store_unittest.cc
@@ -0,0 +1,288 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/availability_store.h"
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/optional.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/feature_engagement_tracker/internal/proto/availability.pb.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+#include "components/leveldb_proto/proto_database.h"
+#include "components/leveldb_proto/testing/fake_db.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+const base::Feature kTestFeatureFoo{"test_foo",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureBar{"test_bar",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureQux{"test_qux",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureNop{"test_nop",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+Availability CreateAvailability(const base::Feature& feature, uint32_t day) {
+ Availability availability;
+ availability.set_feature_name(feature.name);
+ availability.set_day(day);
+ return availability;
+}
+
+class AvailabilityStoreTest : public testing::Test {
+ public:
+ AvailabilityStoreTest()
+ : db_(nullptr),
+ storage_dir_(FILE_PATH_LITERAL("/persistent/store/lalala")) {
+ load_callback_ = base::Bind(&AvailabilityStoreTest::LoadCallback,
+ base::Unretained(this));
+ }
+
+ ~AvailabilityStoreTest() override = default;
+
+ // Creates a DB and stores off a pointer to it as a member.
+ std::unique_ptr<leveldb_proto::test::FakeDB<Availability>> CreateDB() {
+ auto db = base::MakeUnique<leveldb_proto::test::FakeDB<Availability>>(
+ &db_availabilities_);
+ db_ = db.get();
+ return db;
+ }
+
+ void LoadCallback(bool success,
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>>
+ availabilities) {
+ load_successful_ = success;
+ load_results_ = std::move(availabilities);
+ }
+
+ protected:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ // The end result of the store pipeline.
+ AvailabilityStore::OnLoadedCallback load_callback_;
+
+ // Callback results.
+ base::Optional<bool> load_successful_;
+ std::unique_ptr<std::map<const base::Feature*, uint32_t>> load_results_;
+
+ // |db_availabilities_| is used during creation of the FakeDB in CreateDB(),
+ // to simplify what the DB has stored.
+ std::map<std::string, Availability> db_availabilities_;
+
+ // The database that is in use.
+ leveldb_proto::test::FakeDB<Availability>* db_;
+
+ // Constant test data.
+ base::FilePath storage_dir_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AvailabilityStoreTest);
+};
+
+} // namespace
+
+TEST_F(AvailabilityStoreTest, StorageDirectory) {
+ AvailabilityStore::LoadAndUpdateStore(storage_dir_, CreateDB(),
+ FeatureVector(),
+ std::move(load_callback_), 14u);
+ db_->InitCallback(true);
+ EXPECT_EQ(storage_dir_, db_->GetDirectory());
+}
+
+TEST_F(AvailabilityStoreTest, InitFail) {
+ AvailabilityStore::LoadAndUpdateStore(storage_dir_, CreateDB(),
+ FeatureVector(),
+ std::move(load_callback_), 14u);
+
+ db_->InitCallback(false);
+
+ EXPECT_TRUE(load_successful_.has_value());
+ EXPECT_FALSE(load_successful_.value());
+ EXPECT_EQ(0u, load_results_->size());
+ EXPECT_EQ(0u, db_availabilities_.size());
+}
+
+TEST_F(AvailabilityStoreTest, LoadFail) {
+ AvailabilityStore::LoadAndUpdateStore(storage_dir_, CreateDB(),
+ FeatureVector(),
+ std::move(load_callback_), 14u);
+
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->LoadCallback(false);
+
+ EXPECT_TRUE(load_successful_.has_value());
+ EXPECT_FALSE(load_successful_.value());
+ EXPECT_EQ(0u, load_results_->size());
+ EXPECT_EQ(0u, db_availabilities_.size());
+}
+
+TEST_F(AvailabilityStoreTest, EmptyDBEmptyFeatureFilterUpdateFailed) {
+ AvailabilityStore::LoadAndUpdateStore(storage_dir_, CreateDB(),
+ FeatureVector(),
+ std::move(load_callback_), 14u);
+
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->LoadCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->UpdateCallback(false);
+
+ EXPECT_TRUE(load_successful_.has_value());
+ EXPECT_FALSE(load_successful_.value());
+ EXPECT_EQ(0u, load_results_->size());
+ EXPECT_EQ(0u, db_availabilities_.size());
+}
+
+TEST_F(AvailabilityStoreTest, EmptyDBEmptyFeatureFilterUpdateOK) {
+ AvailabilityStore::LoadAndUpdateStore(storage_dir_, CreateDB(),
+ FeatureVector(),
+ std::move(load_callback_), 14u);
+
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->LoadCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->UpdateCallback(true);
+
+ EXPECT_TRUE(load_successful_.has_value());
+ EXPECT_TRUE(load_successful_.value());
+ EXPECT_EQ(0u, load_results_->size());
+ EXPECT_EQ(0u, db_availabilities_.size());
+}
+
+TEST_F(AvailabilityStoreTest, AllNewFeatures) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar},
+ {kTestFeatureQux});
+
+ FeatureVector feature_filter;
+ feature_filter.push_back(&kTestFeatureFoo); // Enabled. Not in DB.
+ feature_filter.push_back(&kTestFeatureBar); // Enabled. Not in DB.
+ feature_filter.push_back(&kTestFeatureQux); // Disabled. Not in DB.
+
+ AvailabilityStore::LoadAndUpdateStore(
+ storage_dir_, CreateDB(), feature_filter, std::move(load_callback_), 14u);
+
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->LoadCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->UpdateCallback(true);
+
+ EXPECT_TRUE(load_successful_.has_value());
+ EXPECT_TRUE(load_successful_.value());
+ ASSERT_EQ(2u, load_results_->size());
+ ASSERT_EQ(2u, db_availabilities_.size());
+
+ ASSERT_TRUE(load_results_->find(&kTestFeatureFoo) != load_results_->end());
+ EXPECT_EQ(14u, (*load_results_)[&kTestFeatureFoo]);
+ ASSERT_TRUE(db_availabilities_.find(kTestFeatureFoo.name) !=
+ db_availabilities_.end());
+ EXPECT_EQ(14u, db_availabilities_[kTestFeatureFoo.name].day());
+
+ ASSERT_TRUE(load_results_->find(&kTestFeatureBar) != load_results_->end());
+ EXPECT_EQ(14u, (*load_results_)[&kTestFeatureBar]);
+ ASSERT_TRUE(db_availabilities_.find(kTestFeatureBar.name) !=
+ db_availabilities_.end());
+ EXPECT_EQ(14u, db_availabilities_[kTestFeatureBar.name].day());
+}
+
+TEST_F(AvailabilityStoreTest, TestAllFilterCombinations) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar},
+ {kTestFeatureQux, kTestFeatureNop});
+
+ FeatureVector feature_filter;
+ feature_filter.push_back(&kTestFeatureFoo); // Enabled. Not in DB.
+ feature_filter.push_back(&kTestFeatureBar); // Enabled. In DB.
+ feature_filter.push_back(&kTestFeatureQux); // Disabled. Not in DB.
+ feature_filter.push_back(&kTestFeatureNop); // Disabled. In DB.
+
+ db_availabilities_[kTestFeatureBar.name] =
+ CreateAvailability(kTestFeatureBar, 10u);
+ db_availabilities_[kTestFeatureNop.name] =
+ CreateAvailability(kTestFeatureNop, 8u);
+
+ AvailabilityStore::LoadAndUpdateStore(
+ storage_dir_, CreateDB(), feature_filter, std::move(load_callback_), 14u);
+
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->LoadCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->UpdateCallback(true);
+
+ EXPECT_TRUE(load_successful_.has_value());
+ EXPECT_TRUE(load_successful_.value());
+ ASSERT_EQ(2u, load_results_->size());
+ ASSERT_EQ(2u, db_availabilities_.size());
+
+ ASSERT_TRUE(load_results_->find(&kTestFeatureFoo) != load_results_->end());
+ EXPECT_EQ(14u, (*load_results_)[&kTestFeatureFoo]);
+ ASSERT_TRUE(db_availabilities_.find(kTestFeatureFoo.name) !=
+ db_availabilities_.end());
+ EXPECT_EQ(14u, db_availabilities_[kTestFeatureFoo.name].day());
+
+ ASSERT_TRUE(load_results_->find(&kTestFeatureBar) != load_results_->end());
+ EXPECT_EQ(10u, (*load_results_)[&kTestFeatureBar]);
+ ASSERT_TRUE(db_availabilities_.find(kTestFeatureBar.name) !=
+ db_availabilities_.end());
+ EXPECT_EQ(10u, db_availabilities_[kTestFeatureBar.name].day());
+}
+
+TEST_F(AvailabilityStoreTest, TestAllCombinationsEmptyFilter) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar},
+ {kTestFeatureQux, kTestFeatureNop});
+
+ // Empty filter, but the following setup:
+ // kTestFeatureFoo: Enabled. Not in DB.
+ // kTestFeatureBar: Enabled. In DB.
+ // kTestFeatureQux: Disabled. Not in DB.
+ // kTestFeatureNop: Disabled. In DB.
+
+ db_availabilities_[kTestFeatureBar.name] =
+ CreateAvailability(kTestFeatureBar, 10u);
+ db_availabilities_[kTestFeatureNop.name] =
+ CreateAvailability(kTestFeatureNop, 8u);
+
+ AvailabilityStore::LoadAndUpdateStore(storage_dir_, CreateDB(),
+ FeatureVector(),
+ std::move(load_callback_), 14u);
+
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->LoadCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ db_->UpdateCallback(true);
+
+ EXPECT_TRUE(load_successful_.has_value());
+ EXPECT_TRUE(load_successful_.value());
+ EXPECT_EQ(0u, load_results_->size());
+ EXPECT_EQ(0u, db_availabilities_.size());
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc b/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
new file mode 100644
index 00000000000..90d79b3a23a
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
@@ -0,0 +1,315 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/chrome_variations_configuration.h"
+
+#include <map>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/stats.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+
+namespace {
+
+const char kComparatorTypeAny[] = "any";
+const char kComparatorTypeLessThan[] = "<";
+const char kComparatorTypeGreaterThan[] = ">";
+const char kComparatorTypeLessThanOrEqual[] = "<=";
+const char kComparatorTypeGreaterThanOrEqual[] = ">=";
+const char kComparatorTypeEqual[] = "==";
+const char kComparatorTypeNotEqual[] = "!=";
+
+const char kEventConfigUsedKey[] = "event_used";
+const char kEventConfigTriggerKey[] = "event_trigger";
+const char kEventConfigKeyPrefix[] = "event_";
+const char kSessionRateKey[] = "session_rate";
+const char kAvailabilityKey[] = "availability";
+
+const char kEventConfigDataNameKey[] = "name";
+const char kEventConfigDataComparatorKey[] = "comparator";
+const char kEventConfigDataWindowKey[] = "window";
+const char kEventConfigDataStorageKey[] = "storage";
+
+} // namespace
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+bool ParseComparatorSubstring(base::StringPiece definition,
+ Comparator* comparator,
+ ComparatorType type,
+ uint32_t type_len) {
+ base::StringPiece number_string =
+ base::TrimWhitespaceASCII(definition.substr(type_len), base::TRIM_ALL);
+ uint32_t value;
+ if (!base::StringToUint(number_string, &value))
+ return false;
+
+ comparator->type = type;
+ comparator->value = value;
+ return true;
+}
+
+bool ParseComparator(base::StringPiece definition, Comparator* comparator) {
+ if (base::LowerCaseEqualsASCII(definition, kComparatorTypeAny)) {
+ comparator->type = ANY;
+ comparator->value = 0;
+ return true;
+ }
+
+ if (base::StartsWith(definition, kComparatorTypeLessThanOrEqual,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return ParseComparatorSubstring(definition, comparator, LESS_THAN_OR_EQUAL,
+ 2);
+ }
+
+ if (base::StartsWith(definition, kComparatorTypeGreaterThanOrEqual,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return ParseComparatorSubstring(definition, comparator,
+ GREATER_THAN_OR_EQUAL, 2);
+ }
+
+ if (base::StartsWith(definition, kComparatorTypeEqual,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return ParseComparatorSubstring(definition, comparator, EQUAL, 2);
+ }
+
+ if (base::StartsWith(definition, kComparatorTypeNotEqual,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return ParseComparatorSubstring(definition, comparator, NOT_EQUAL, 2);
+ }
+
+ if (base::StartsWith(definition, kComparatorTypeLessThan,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return ParseComparatorSubstring(definition, comparator, LESS_THAN, 1);
+ }
+
+ if (base::StartsWith(definition, kComparatorTypeGreaterThan,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return ParseComparatorSubstring(definition, comparator, GREATER_THAN, 1);
+ }
+
+ return false;
+}
+
+bool ParseEventConfig(base::StringPiece definition, EventConfig* event_config) {
+ // Support definitions with at least 4 tokens.
+ auto tokens = base::SplitStringPiece(definition, ";", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_ALL);
+ if (tokens.size() < 4) {
+ *event_config = EventConfig();
+ return false;
+ }
+
+ // Parse tokens in any order.
+ bool has_name = false;
+ bool has_comparator = false;
+ bool has_window = false;
+ bool has_storage = false;
+ for (const auto& token : tokens) {
+ auto pair = base::SplitStringPiece(token, ":", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_ALL);
+ if (pair.size() != 2) {
+ *event_config = EventConfig();
+ return false;
+ }
+
+ const base::StringPiece& key = pair[0];
+ const base::StringPiece& value = pair[1];
+ // TODO(nyquist): Ensure that key matches regex /^[a-zA-Z0-9-_]+$/.
+
+ if (base::LowerCaseEqualsASCII(key, kEventConfigDataNameKey)) {
+ if (has_name) {
+ *event_config = EventConfig();
+ return false;
+ }
+ has_name = true;
+
+ event_config->name = value.as_string();
+ } else if (base::LowerCaseEqualsASCII(key, kEventConfigDataComparatorKey)) {
+ if (has_comparator) {
+ *event_config = EventConfig();
+ return false;
+ }
+ has_comparator = true;
+
+ Comparator comparator;
+ if (!ParseComparator(value, &comparator)) {
+ *event_config = EventConfig();
+ return false;
+ }
+
+ event_config->comparator = comparator;
+ } else if (base::LowerCaseEqualsASCII(key, kEventConfigDataWindowKey)) {
+ if (has_window) {
+ *event_config = EventConfig();
+ return false;
+ }
+ has_window = true;
+
+ uint32_t parsed_value;
+ if (!base::StringToUint(value, &parsed_value)) {
+ *event_config = EventConfig();
+ return false;
+ }
+
+ event_config->window = parsed_value;
+ } else if (base::LowerCaseEqualsASCII(key, kEventConfigDataStorageKey)) {
+ if (has_storage) {
+ *event_config = EventConfig();
+ return false;
+ }
+ has_storage = true;
+
+ uint32_t parsed_value;
+ if (!base::StringToUint(value, &parsed_value)) {
+ *event_config = EventConfig();
+ return false;
+ }
+
+ event_config->storage = parsed_value;
+ }
+ }
+
+ return has_name && has_comparator && has_window && has_storage;
+}
+
+} // namespace
+
+ChromeVariationsConfiguration::ChromeVariationsConfiguration() = default;
+
+ChromeVariationsConfiguration::~ChromeVariationsConfiguration() = default;
+
+void ChromeVariationsConfiguration::ParseFeatureConfigs(
+ FeatureVector features) {
+ for (auto* feature : features) {
+ ParseFeatureConfig(feature);
+ }
+}
+
+void ChromeVariationsConfiguration::ParseFeatureConfig(
+ const base::Feature* feature) {
+ DCHECK(feature);
+ DCHECK(configs_.find(feature) == configs_.end());
+
+ // Initially all new configurations are considered invalid.
+ FeatureConfig& config = configs_[feature];
+ config.valid = false;
+ uint32_t parse_errors = 0;
+
+ std::map<std::string, std::string> params;
+ bool result = base::GetFieldTrialParamsByFeature(*feature, &params);
+ if (!result) {
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL);
+ // Returns early. If no field trial, ConfigParsingEvent::FAILURE will not be
+ // recorded.
+ return;
+ }
+
+ for (const auto& it : params) {
+ const std::string& key = it.first;
+ if (key == kEventConfigUsedKey) {
+ EventConfig event_config;
+ if (!ParseEventConfig(params[key], &event_config)) {
+ ++parse_errors;
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_USED_EVENT_PARSE);
+ continue;
+ }
+ config.used = event_config;
+ } else if (key == kEventConfigTriggerKey) {
+ EventConfig event_config;
+ if (!ParseEventConfig(params[key], &event_config)) {
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_PARSE);
+ ++parse_errors;
+ continue;
+ }
+ config.trigger = event_config;
+ } else if (key == kSessionRateKey) {
+ Comparator comparator;
+ if (!ParseComparator(params[key], &comparator)) {
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_SESSION_RATE_PARSE);
+ ++parse_errors;
+ continue;
+ }
+ config.session_rate = comparator;
+ } else if (key == kAvailabilityKey) {
+ Comparator comparator;
+ if (!ParseComparator(params[key], &comparator)) {
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_AVAILABILITY_PARSE);
+ ++parse_errors;
+ continue;
+ }
+ config.availability = comparator;
+ } else if (base::StartsWith(key, kEventConfigKeyPrefix,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ EventConfig event_config;
+ if (!ParseEventConfig(params[key], &event_config)) {
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_OTHER_EVENT_PARSE);
+ ++parse_errors;
+ continue;
+ }
+ config.event_configs.insert(event_config);
+ } else {
+ DVLOG(1) << "Ignoring unknown key when parsing config for feature "
+ << feature->name << ": " << key;
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_UNKNOWN_KEY);
+ }
+ }
+
+ // The |used| and |trigger| members are required, so should not be the
+ // default values.
+ bool has_used_event = config.used != EventConfig();
+ bool has_trigger_event = config.trigger != EventConfig();
+ config.valid = has_used_event && has_trigger_event && parse_errors == 0;
+
+ if (config.valid) {
+ stats::RecordConfigParsingEvent(stats::ConfigParsingEvent::SUCCESS);
+ } else {
+ stats::RecordConfigParsingEvent(stats::ConfigParsingEvent::FAILURE);
+ }
+
+ // Notice parse errors for used and trigger events will also cause the
+ // following histograms being recorded.
+ if (!has_used_event) {
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_USED_EVENT_MISSING);
+ }
+ if (!has_trigger_event) {
+ stats::RecordConfigParsingEvent(
+ stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_MISSING);
+ }
+}
+
+const FeatureConfig& ChromeVariationsConfiguration::GetFeatureConfig(
+ const base::Feature& feature) const {
+ auto it = configs_.find(&feature);
+ DCHECK(it != configs_.end());
+ return it->second;
+}
+
+const Configuration::ConfigMap&
+ChromeVariationsConfiguration::GetRegisteredFeatures() const {
+ return configs_;
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.h b/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
new file mode 100644
index 00000000000..526e7281eba
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
@@ -0,0 +1,46 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CHROME_VARIATIONS_CONFIGURATION_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CHROME_VARIATIONS_CONFIGURATION_H_
+
+#include "base/macros.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+
+namespace base {
+struct Feature;
+} // namespace base
+
+namespace feature_engagement_tracker {
+
+// A ChromeVariationsConfiguration provides a configuration that is parsed from
+// Chrome variations feature params. It is required to call
+// ParseFeatureConfigs(...) with all the features that should be parsed.
+class ChromeVariationsConfiguration : public Configuration {
+ public:
+ ChromeVariationsConfiguration();
+ ~ChromeVariationsConfiguration() override;
+
+ // Configuration implementation.
+ const FeatureConfig& GetFeatureConfig(
+ const base::Feature& feature) const override;
+ const Configuration::ConfigMap& GetRegisteredFeatures() const override;
+
+ // Parses the variations configuration for all of the given |features| and
+ // stores the result. It is only valid to call ParseFeatureConfig once.
+ void ParseFeatureConfigs(FeatureVector features);
+
+ private:
+ void ParseFeatureConfig(const base::Feature* feature);
+
+ // The current configurations.
+ ConfigMap configs_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeVariationsConfiguration);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CHROME_VARIATIONS_CONFIGURATION_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc b/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc
new file mode 100644
index 00000000000..9b6e1ea5f8b
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc
@@ -0,0 +1,622 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/chrome_variations_configuration.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_param_associator.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/stats.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+const base::Feature kTestFeatureFoo{"test_foo",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureBar{"test_bar",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureQux{"test_qux",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+const char kFooTrialName[] = "FooTrial";
+const char kBarTrialName[] = "BarTrial";
+const char kQuxTrialName[] = "QuxTrial";
+const char kGroupName[] = "Group1";
+const char kConfigParseEventName[] = "InProductHelp.Config.ParsingEvent";
+
+class ChromeVariationsConfigurationTest : public ::testing::Test {
+ public:
+ ChromeVariationsConfigurationTest() : field_trials_(nullptr) {
+ base::FieldTrial* foo_trial =
+ base::FieldTrialList::CreateFieldTrial(kFooTrialName, kGroupName);
+ base::FieldTrial* bar_trial =
+ base::FieldTrialList::CreateFieldTrial(kBarTrialName, kGroupName);
+ base::FieldTrial* qux_trial =
+ base::FieldTrialList::CreateFieldTrial(kQuxTrialName, kGroupName);
+ trials_[&kTestFeatureFoo] = foo_trial;
+ trials_[&kTestFeatureBar] = bar_trial;
+ trials_[&kTestFeatureQux] = qux_trial;
+
+ std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
+ feature_list->RegisterFieldTrialOverride(
+ kTestFeatureFoo.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+ foo_trial);
+ feature_list->RegisterFieldTrialOverride(
+ kTestFeatureBar.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+ bar_trial);
+ feature_list->RegisterFieldTrialOverride(
+ kTestFeatureQux.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+ qux_trial);
+
+ scoped_feature_list.InitWithFeatureList(std::move(feature_list));
+ EXPECT_EQ(foo_trial, base::FeatureList::GetFieldTrial(kTestFeatureFoo));
+ EXPECT_EQ(bar_trial, base::FeatureList::GetFieldTrial(kTestFeatureBar));
+ EXPECT_EQ(qux_trial, base::FeatureList::GetFieldTrial(kTestFeatureQux));
+ }
+
+ void TearDown() override {
+ // This is required to ensure each test can define its own params.
+ base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
+ }
+
+ protected:
+ void SetFeatureParams(const base::Feature& feature,
+ std::map<std::string, std::string> params) {
+ ASSERT_TRUE(base::FieldTrialParamAssociator::GetInstance()
+ ->AssociateFieldTrialParams(trials_[&feature]->trial_name(),
+ kGroupName, params));
+
+ std::map<std::string, std::string> actualParams;
+ EXPECT_TRUE(base::GetFieldTrialParamsByFeature(feature, &actualParams));
+ EXPECT_EQ(params, actualParams);
+ }
+
+ void VerifyInvalid(const std::string& event_config) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:u;comparator:any;window:0;storage:1";
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ foo_params["event_0"] = event_config;
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+ }
+
+ ChromeVariationsConfiguration configuration_;
+
+ private:
+ base::FieldTrialList field_trials_;
+ std::map<const base::Feature*, base::FieldTrial*> trials_;
+ base::test::ScopedFeatureList scoped_feature_list;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeVariationsConfigurationTest);
+};
+
+} // namespace
+
+TEST_F(ChromeVariationsConfigurationTest,
+ DisabledFeatureShouldHaveInvalidConfig) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({}, {kTestFeatureFoo});
+
+ FeatureVector features;
+ features.push_back(&kTestFeatureFoo);
+ base::HistogramTester histogram_tester;
+
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo_config = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo_config.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, ParseSingleFeature) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] =
+ "name:page_download_started;comparator:any;window:0;storage:360";
+ foo_params["event_trigger"] =
+ "name:opened_chrome_home;comparator:any;window:0;storage:360";
+ foo_params["event_1"] =
+ "name:user_has_seen_dino;comparator:>=1;window:120;storage:180";
+ foo_params["event_2"] =
+ "name:user_opened_app_menu;comparator:<=0;window:120;storage:180";
+ foo_params["event_3"] =
+ "name:user_opened_downloads_home;comparator:any;window:0;storage:360";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
+
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used =
+ EventConfig("page_download_started", Comparator(ANY, 0), 0, 360);
+ expected_foo.trigger =
+ EventConfig("opened_chrome_home", Comparator(ANY, 0), 0, 360);
+ expected_foo.event_configs.insert(EventConfig(
+ "user_has_seen_dino", Comparator(GREATER_THAN_OR_EQUAL, 1), 120, 180));
+ expected_foo.event_configs.insert(EventConfig(
+ "user_opened_app_menu", Comparator(LESS_THAN_OR_EQUAL, 0), 120, 180));
+ expected_foo.event_configs.insert(
+ EventConfig("user_opened_downloads_home", Comparator(ANY, 0), 0, 360));
+ EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, MissingUsedIsInvalid) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE_USED_EVENT_MISSING),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, MissingTriggerIsInvalid) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(
+ stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_MISSING),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, OnlyTriggerAndUsedIsValid) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
+ expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
+ EXPECT_EQ(expected_foo, foo);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, WhitespaceIsValid) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] =
+ " name : eu ; comparator : any ; window : 1 ; storage : 320 ";
+ foo_params["event_trigger"] =
+ " name:et;comparator : any ;window: 2;storage:330 ";
+ foo_params["event_0"] = "name:e0;comparator: <1 ;window:3\n;storage:340";
+ foo_params["event_1"] = "name:e1;comparator: > 2 ;window:4;\rstorage:350";
+ foo_params["event_2"] = "name:e2;comparator: <= 3 ;window:5;\tstorage:360";
+ foo_params["event_3"] = "name:e3;comparator: <\n4 ;window:6;storage:370";
+ foo_params["event_4"] = "name:e4;comparator: >\t5 ;window:7;storage:380";
+ foo_params["event_5"] = "name:e5;comparator: <=\r6 ;window:8;storage:390";
+ foo_params["event_6"] = "name:e6;comparator:\n<=7;window:9;storage:400";
+ foo_params["event_7"] = "name:e7;comparator:<=8\n;window:10;storage:410";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 1, 320);
+ expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 2, 330);
+ expected_foo.event_configs.insert(
+ EventConfig("e0", Comparator(LESS_THAN, 1), 3, 340));
+ expected_foo.event_configs.insert(
+ EventConfig("e1", Comparator(GREATER_THAN, 2), 4, 350));
+ expected_foo.event_configs.insert(
+ EventConfig("e2", Comparator(LESS_THAN_OR_EQUAL, 3), 5, 360));
+ expected_foo.event_configs.insert(
+ EventConfig("e3", Comparator(LESS_THAN, 4), 6, 370));
+ expected_foo.event_configs.insert(
+ EventConfig("e4", Comparator(GREATER_THAN, 5), 7, 380));
+ expected_foo.event_configs.insert(
+ EventConfig("e5", Comparator(LESS_THAN_OR_EQUAL, 6), 8, 390));
+ expected_foo.event_configs.insert(
+ EventConfig("e6", Comparator(LESS_THAN_OR_EQUAL, 7), 9, 400));
+ expected_foo.event_configs.insert(
+ EventConfig("e7", Comparator(LESS_THAN_OR_EQUAL, 8), 10, 410));
+ EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, IgnoresInvalidConfigKeys) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ foo_params["not_there_yet"] = "bogus value";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
+ expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
+ EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, IgnoresInvalidEventConfigTokens) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] =
+ "name:eu;comparator:any;window:0;storage:360;somethingelse:1";
+ foo_params["event_trigger"] =
+ "yesway:0;noway:1;name:et;comparator:any;window:0;storage:360";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
+ expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
+ EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ MissingAllEventConfigParamsIsInvalid) {
+ VerifyInvalid("a:1;b:2;c:3;d:4");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ MissingEventEventConfigParamIsInvalid) {
+ VerifyInvalid("foobar:eu;comparator:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ MissingComparatorEventConfigParamIsInvalid) {
+ VerifyInvalid("name:eu;foobar:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ MissingWindowEventConfigParamIsInvalid) {
+ VerifyInvalid("name:eu;comparator:any;foobar:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ MissingStorageEventConfigParamIsInvalid) {
+ VerifyInvalid("name:eu;comparator:any;window:1;foobar:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ EventSpecifiedMultipleTimesIsInvalid) {
+ VerifyInvalid("name:eu;name:eu;comparator:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ ComparatorSpecifiedMultipleTimesIsInvalid) {
+ VerifyInvalid("name:eu;comparator:any;comparator:any;window:1;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ WindowSpecifiedMultipleTimesIsInvalid) {
+ VerifyInvalid("name:eu;comparator:any;window:1;window:2;storage:360");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ StorageSpecifiedMultipleTimesIsInvalid) {
+ VerifyInvalid("name:eu;comparator:any;window:1;storage:360;storage:10");
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ InvalidSessionRateCausesInvalidConfig) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:eu;comparator:any;window:1;storage:360";
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ foo_params["session_rate"] = "bogus value";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE_SESSION_RATE_PARSE),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ InvalidAvailabilityCausesInvalidConfig) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ foo_params["availability"] = "bogus value";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE_AVAILABILITY_PARSE),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, InvalidUsedCausesInvalidConfig) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "bogus value";
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE_USED_EVENT_PARSE), 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE_USED_EVENT_MISSING),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, InvalidTriggerCausesInvalidConfig) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+ foo_params["event_trigger"] = "bogus value";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ base::HistogramTester histogram_tester;
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_PARSE),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(
+ stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_MISSING),
+ 1);
+ histogram_tester.ExpectBucketCount(
+ kConfigParseEventName,
+ static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
+ histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
+}
+
+TEST_F(ChromeVariationsConfigurationTest,
+ InvalidEventConfigCausesInvalidConfig) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
+ foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
+ foo_params["event_used_0"] = "bogus value";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_FALSE(foo.valid);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, AllComparatorTypesWork) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:e0;comparator:any;window:20;storage:30";
+ foo_params["event_trigger"] = "name:e1;comparator:<1;window:21;storage:31";
+ foo_params["event_2"] = "name:e2;comparator:>2;window:22;storage:32";
+ foo_params["event_3"] = "name:e3;comparator:<=3;window:23;storage:33";
+ foo_params["event_4"] = "name:e4;comparator:>=4;window:24;storage:34";
+ foo_params["event_5"] = "name:e5;comparator:==5;window:25;storage:35";
+ foo_params["event_6"] = "name:e6;comparator:!=6;window:26;storage:36";
+ foo_params["session_rate"] = "!=6";
+ foo_params["availability"] = ">=1";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used = EventConfig("e0", Comparator(ANY, 0), 20, 30);
+ expected_foo.trigger = EventConfig("e1", Comparator(LESS_THAN, 1), 21, 31);
+ expected_foo.event_configs.insert(
+ EventConfig("e2", Comparator(GREATER_THAN, 2), 22, 32));
+ expected_foo.event_configs.insert(
+ EventConfig("e3", Comparator(LESS_THAN_OR_EQUAL, 3), 23, 33));
+ expected_foo.event_configs.insert(
+ EventConfig("e4", Comparator(GREATER_THAN_OR_EQUAL, 4), 24, 34));
+ expected_foo.event_configs.insert(
+ EventConfig("e5", Comparator(EQUAL, 5), 25, 35));
+ expected_foo.event_configs.insert(
+ EventConfig("e6", Comparator(NOT_EQUAL, 6), 26, 36));
+ expected_foo.session_rate = Comparator(NOT_EQUAL, 6);
+ expected_foo.availability = Comparator(GREATER_THAN_OR_EQUAL, 1);
+ EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, MultipleEventsWithSameName) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] = "name:foo;comparator:any;window:20;storage:30";
+ foo_params["event_trigger"] = "name:foo;comparator:<1;window:21;storage:31";
+ foo_params["event_2"] = "name:foo;comparator:>2;window:22;storage:32";
+ foo_params["event_3"] = "name:foo;comparator:<=3;window:23;storage:33";
+ foo_params["session_rate"] = "any";
+ foo_params["availability"] = ">1";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::vector<const base::Feature*> features = {&kTestFeatureFoo};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used = EventConfig("foo", Comparator(ANY, 0), 20, 30);
+ expected_foo.trigger = EventConfig("foo", Comparator(LESS_THAN, 1), 21, 31);
+ expected_foo.event_configs.insert(
+ EventConfig("foo", Comparator(GREATER_THAN, 2), 22, 32));
+ expected_foo.event_configs.insert(
+ EventConfig("foo", Comparator(LESS_THAN_OR_EQUAL, 3), 23, 33));
+ expected_foo.session_rate = Comparator(ANY, 0);
+ expected_foo.availability = Comparator(GREATER_THAN, 1);
+ EXPECT_EQ(expected_foo, foo);
+}
+
+TEST_F(ChromeVariationsConfigurationTest, ParseMultipleFeatures) {
+ std::map<std::string, std::string> foo_params;
+ foo_params["event_used"] =
+ "name:foo_used;comparator:any;window:20;storage:30";
+ foo_params["event_trigger"] =
+ "name:foo_trigger;comparator:<1;window:21;storage:31";
+ foo_params["session_rate"] = "==10";
+ foo_params["availability"] = "<0";
+ SetFeatureParams(kTestFeatureFoo, foo_params);
+
+ std::map<std::string, std::string> bar_params;
+ bar_params["event_used"] = "name:bar_used;comparator:ANY;window:0;storage:0";
+ SetFeatureParams(kTestFeatureBar, bar_params);
+
+ std::map<std::string, std::string> qux_params;
+ qux_params["event_used"] =
+ "name:qux_used;comparator:>=2;window:99;storage:42";
+ qux_params["event_trigger"] =
+ "name:qux_trigger;comparator:ANY;window:103;storage:104";
+ qux_params["event_0"] = "name:q0;comparator:<10;window:20;storage:30";
+ qux_params["event_1"] = "name:q1;comparator:>11;window:21;storage:31";
+ qux_params["event_2"] = "name:q2;comparator:<=12;window:22;storage:32";
+ qux_params["event_3"] = "name:q3;comparator:>=13;window:23;storage:33";
+ qux_params["event_4"] = "name:q4;comparator:==14;window:24;storage:34";
+ qux_params["event_5"] = "name:q5;comparator:!=15;window:25;storage:35";
+ qux_params["session_rate"] = "!=13";
+ qux_params["availability"] = "==0";
+ SetFeatureParams(kTestFeatureQux, qux_params);
+
+ std::vector<const base::Feature*> features = {
+ &kTestFeatureFoo, &kTestFeatureBar, &kTestFeatureQux};
+ configuration_.ParseFeatureConfigs(features);
+
+ FeatureConfig foo = configuration_.GetFeatureConfig(kTestFeatureFoo);
+ EXPECT_TRUE(foo.valid);
+ FeatureConfig expected_foo;
+ expected_foo.valid = true;
+ expected_foo.used = EventConfig("foo_used", Comparator(ANY, 0), 20, 30);
+ expected_foo.trigger =
+ EventConfig("foo_trigger", Comparator(LESS_THAN, 1), 21, 31);
+ expected_foo.session_rate = Comparator(EQUAL, 10);
+ expected_foo.availability = Comparator(LESS_THAN, 0);
+ EXPECT_EQ(expected_foo, foo);
+
+ FeatureConfig bar = configuration_.GetFeatureConfig(kTestFeatureBar);
+ EXPECT_FALSE(bar.valid);
+
+ FeatureConfig qux = configuration_.GetFeatureConfig(kTestFeatureQux);
+ EXPECT_TRUE(qux.valid);
+ FeatureConfig expected_qux;
+ expected_qux.valid = true;
+ expected_qux.used =
+ EventConfig("qux_used", Comparator(GREATER_THAN_OR_EQUAL, 2), 99, 42);
+ expected_qux.trigger =
+ EventConfig("qux_trigger", Comparator(ANY, 0), 103, 104);
+ expected_qux.event_configs.insert(
+ EventConfig("q0", Comparator(LESS_THAN, 10), 20, 30));
+ expected_qux.event_configs.insert(
+ EventConfig("q1", Comparator(GREATER_THAN, 11), 21, 31));
+ expected_qux.event_configs.insert(
+ EventConfig("q2", Comparator(LESS_THAN_OR_EQUAL, 12), 22, 32));
+ expected_qux.event_configs.insert(
+ EventConfig("q3", Comparator(GREATER_THAN_OR_EQUAL, 13), 23, 33));
+ expected_qux.event_configs.insert(
+ EventConfig("q4", Comparator(EQUAL, 14), 24, 34));
+ expected_qux.event_configs.insert(
+ EventConfig("q5", Comparator(NOT_EQUAL, 15), 25, 35));
+ expected_qux.session_rate = Comparator(NOT_EQUAL, 13);
+ expected_qux.availability = Comparator(EQUAL, 0);
+ EXPECT_EQ(expected_qux, qux);
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/condition_validator.cc b/chromium/components/feature_engagement_tracker/internal/condition_validator.cc
new file mode 100644
index 00000000000..90113483c74
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/condition_validator.cc
@@ -0,0 +1,40 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/condition_validator.h"
+
+namespace feature_engagement_tracker {
+
+ConditionValidator::Result::Result(bool initial_values)
+ : event_model_ready_ok(initial_values),
+ currently_showing_ok(initial_values),
+ feature_enabled_ok(initial_values),
+ config_ok(initial_values),
+ used_ok(initial_values),
+ trigger_ok(initial_values),
+ preconditions_ok(initial_values),
+ session_rate_ok(initial_values),
+ availability_model_ready_ok(initial_values),
+ availability_ok(initial_values) {}
+
+ConditionValidator::Result::Result(const Result& other) {
+ event_model_ready_ok = other.event_model_ready_ok;
+ currently_showing_ok = other.currently_showing_ok;
+ feature_enabled_ok = other.feature_enabled_ok;
+ config_ok = other.config_ok;
+ used_ok = other.used_ok;
+ trigger_ok = other.trigger_ok;
+ preconditions_ok = other.preconditions_ok;
+ session_rate_ok = other.session_rate_ok;
+ availability_model_ready_ok = other.availability_model_ready_ok;
+ availability_ok = other.availability_ok;
+}
+
+bool ConditionValidator::Result::NoErrors() const {
+ return event_model_ready_ok && currently_showing_ok && feature_enabled_ok &&
+ config_ok && used_ok && trigger_ok && preconditions_ok &&
+ session_rate_ok && availability_model_ready_ok && availability_ok;
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/condition_validator.h b/chromium/components/feature_engagement_tracker/internal/condition_validator.h
index 295a6a08af6..a4686e03616 100644
--- a/chromium/components/feature_engagement_tracker/internal/condition_validator.h
+++ b/chromium/components/feature_engagement_tracker/internal/condition_validator.h
@@ -5,24 +5,83 @@
#ifndef COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CONDITION_VALIDATOR_H_
#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CONDITION_VALIDATOR_H_
+#include <stdint.h>
+
+#include <string>
+
#include "base/macros.h"
-#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
namespace base {
struct Feature;
} // namespace base
namespace feature_engagement_tracker {
+struct FeatureConfig;
+class AvailabilityModel;
+class Model;
// A ConditionValidator checks the requred conditions for a given feature,
// and checks if all conditions are met.
class ConditionValidator {
public:
+ // The Result struct is used to categorize everything that could have the
+ // wrong state. By returning an instance of this where every value is true
+ // from MeetsConditions(...), it can be assumed that in-product help will
+ // be displayed.
+ struct Result {
+ explicit Result(bool initial_values);
+ Result(const Result& other);
+
+ // Whether the event model was ready.
+ bool event_model_ready_ok;
+
+ // Whether no other in-product helps were shown at the time.
+ bool currently_showing_ok;
+
+ // Whether the feature is enabled.
+ bool feature_enabled_ok;
+
+ // Whether the feature configuration was valid.
+ bool config_ok;
+
+ // Whether the used precondition was met.
+ bool used_ok;
+
+ // Whether the trigger precondition was met.
+ bool trigger_ok;
+
+ // Whether the other preconditions were met.
+ bool preconditions_ok;
+
+ // Whether the session rate precondition was met.
+ bool session_rate_ok;
+
+ // Whether the availability model was ready.
+ bool availability_model_ready_ok;
+
+ // Whether the availability precondition was met.
+ bool availability_ok;
+
+ // Returns true if this result object has no errors, i.e. no values that
+ // are false.
+ bool NoErrors() const;
+ };
+
virtual ~ConditionValidator() = default;
- // Returns true iff all conditions for the given feature have been met.
- virtual bool MeetsConditions(const base::Feature& feature,
- const Model& model) = 0;
+ // Returns a Result object that describes whether each condition has been met.
+ virtual Result MeetsConditions(const base::Feature& feature,
+ const FeatureConfig& config,
+ const Model& model,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const = 0;
+
+ // Must be called to notify that the |feature| is currently showing.
+ virtual void NotifyIsShowing(const base::Feature& feature) = 0;
+
+ // Must be called to notify that the |feature| is no longer showing.
+ virtual void NotifyDismissed(const base::Feature& feature) = 0;
protected:
ConditionValidator() = default;
diff --git a/chromium/components/feature_engagement_tracker/internal/condition_validator_unittest.cc b/chromium/components/feature_engagement_tracker/internal/condition_validator_unittest.cc
new file mode 100644
index 00000000000..a6f8cb59994
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/condition_validator_unittest.cc
@@ -0,0 +1,86 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/condition_validator.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+TEST(ConditionValidatorResultTest, TestAllOK) {
+ EXPECT_TRUE(ConditionValidator::Result(true).NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestAllErrors) {
+ EXPECT_FALSE(ConditionValidator::Result(false).NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestModelNotReady) {
+ ConditionValidator::Result result(true);
+ result.event_model_ready_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestCurrentlyShowing) {
+ ConditionValidator::Result result(true);
+ result.currently_showing_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestFeatureEnabled) {
+ ConditionValidator::Result result(true);
+ result.feature_enabled_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestInvalidConfig) {
+ ConditionValidator::Result result(true);
+ result.config_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestUsedFailed) {
+ ConditionValidator::Result result(true);
+ result.used_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestTriggerFailed) {
+ ConditionValidator::Result result(true);
+ result.trigger_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestPreconditionsFailed) {
+ ConditionValidator::Result result(true);
+ result.preconditions_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestSessionRateFailed) {
+ ConditionValidator::Result result(true);
+ result.session_rate_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestAvailabilityModelNotReady) {
+ ConditionValidator::Result result(true);
+ result.availability_model_ready_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestAvailabilityFailed) {
+ ConditionValidator::Result result(true);
+ result.availability_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+TEST(ConditionValidatorResultTest, TestMultipleErrors) {
+ ConditionValidator::Result result(true);
+ result.preconditions_ok = false;
+ result.session_rate_ok = false;
+ EXPECT_FALSE(result.NoErrors());
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/configuration.cc b/chromium/components/feature_engagement_tracker/internal/configuration.cc
index 6e7b904bf20..79870078cf6 100644
--- a/chromium/components/feature_engagement_tracker/internal/configuration.cc
+++ b/chromium/components/feature_engagement_tracker/internal/configuration.cc
@@ -6,15 +6,83 @@
#include <string>
+#include "base/logging.h"
+
namespace feature_engagement_tracker {
+Comparator::Comparator() : type(ANY), value(0) {}
+
+Comparator::Comparator(ComparatorType type, uint32_t value)
+ : type(type), value(value) {}
+
+Comparator::~Comparator() = default;
+
+bool Comparator::MeetsCriteria(uint32_t v) const {
+ switch (type) {
+ case ANY:
+ return true;
+ case LESS_THAN:
+ return v < value;
+ case GREATER_THAN:
+ return v > value;
+ case LESS_THAN_OR_EQUAL:
+ return v <= value;
+ case GREATER_THAN_OR_EQUAL:
+ return v >= value;
+ case EQUAL:
+ return v == value;
+ case NOT_EQUAL:
+ return v != value;
+ default:
+ // All cases should be covered.
+ NOTREACHED();
+ return false;
+ }
+}
+
+EventConfig::EventConfig() : window(0), storage(0) {}
+
+EventConfig::EventConfig(const std::string& name,
+ Comparator comparator,
+ uint32_t window,
+ uint32_t storage)
+ : name(name), comparator(comparator), window(window), storage(storage) {}
+
+EventConfig::~EventConfig() = default;
+
FeatureConfig::FeatureConfig() : valid(false) {}
+FeatureConfig::FeatureConfig(const FeatureConfig& other) = default;
+
FeatureConfig::~FeatureConfig() = default;
+bool operator==(const Comparator& lhs, const Comparator& rhs) {
+ return std::tie(lhs.type, lhs.value) == std::tie(rhs.type, rhs.value);
+}
+
+bool operator<(const Comparator& lhs, const Comparator& rhs) {
+ return std::tie(lhs.type, lhs.value) < std::tie(rhs.type, rhs.value);
+}
+
+bool operator==(const EventConfig& lhs, const EventConfig& rhs) {
+ return std::tie(lhs.name, lhs.comparator, lhs.window, lhs.storage) ==
+ std::tie(rhs.name, rhs.comparator, rhs.window, rhs.storage);
+}
+
+bool operator!=(const EventConfig& lhs, const EventConfig& rhs) {
+ return !(lhs == rhs);
+}
+
+bool operator<(const EventConfig& lhs, const EventConfig& rhs) {
+ return std::tie(lhs.name, lhs.comparator, lhs.window, lhs.storage) <
+ std::tie(rhs.name, rhs.comparator, rhs.window, rhs.storage);
+}
+
bool operator==(const FeatureConfig& lhs, const FeatureConfig& rhs) {
- return lhs.valid == rhs.valid &&
- lhs.feature_used_event == rhs.feature_used_event;
+ return std::tie(lhs.valid, lhs.used, lhs.trigger, lhs.event_configs,
+ lhs.session_rate, lhs.availability) ==
+ std::tie(rhs.valid, rhs.used, rhs.trigger, rhs.event_configs,
+ rhs.session_rate, rhs.availability);
}
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/configuration.h b/chromium/components/feature_engagement_tracker/internal/configuration.h
index 2e470cb7446..c942e5b9c90 100644
--- a/chromium/components/feature_engagement_tracker/internal/configuration.h
+++ b/chromium/components/feature_engagement_tracker/internal/configuration.h
@@ -6,7 +6,9 @@
#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_CONFIGURATION_H_
#include <map>
+#include <set>
#include <string>
+#include <vector>
#include "base/macros.h"
@@ -16,28 +18,103 @@ struct Feature;
namespace feature_engagement_tracker {
+// A ComparatorType describes the relationship between two numbers.
+enum ComparatorType {
+ ANY = 0, // Will always yield true.
+ LESS_THAN = 1,
+ GREATER_THAN = 2,
+ LESS_THAN_OR_EQUAL = 3,
+ GREATER_THAN_OR_EQUAL = 4,
+ EQUAL = 5,
+ NOT_EQUAL = 6,
+};
+
+// A Comparator provides a way of comparing a uint32_t another uint32_t and
+// verifying their relationship.
+struct Comparator {
+ public:
+ Comparator();
+ Comparator(ComparatorType type, uint32_t value);
+ ~Comparator();
+
+ // Returns true if the |v| meets the this criteria based on the current
+ // |type| and |value|.
+ bool MeetsCriteria(uint32_t v) const;
+
+ ComparatorType type;
+ uint32_t value;
+};
+
+bool operator==(const Comparator& lhs, const Comparator& rhs);
+bool operator<(const Comparator& lhs, const Comparator& rhs);
+
+// A EventConfig contains all the information about how many times
+// a particular event should or should not have triggered, for which window
+// to search in and for how long to store it.
+struct EventConfig {
+ public:
+ EventConfig();
+ EventConfig(const std::string& name,
+ Comparator comparator,
+ uint32_t window,
+ uint32_t storage);
+ ~EventConfig();
+
+ // The identifier of the event.
+ std::string name;
+
+ // The number of events it is required to find within the search window.
+ Comparator comparator;
+
+ // Search for this event within this window.
+ uint32_t window;
+
+ // Store client side data related to events for this minimum this long.
+ uint32_t storage;
+};
+
+bool operator==(const EventConfig& lhs, const EventConfig& rhs);
+bool operator!=(const EventConfig& lhs, const EventConfig& rhs);
+bool operator<(const EventConfig& lhs, const EventConfig& rhs);
+
// A FeatureConfig contains all the configuration for a given feature.
struct FeatureConfig {
public:
FeatureConfig();
+ FeatureConfig(const FeatureConfig& other);
~FeatureConfig();
// Whether the configuration has been successfully parsed.
bool valid;
- // The identifier for a particular event that will be searched for when
+ // The configuration for a particular event that will be searched for when
// counting how many times a particular feature has been used.
- std::string feature_used_event;
+ EventConfig used;
+
+ // The configuration for a particular event that will be searched for when
+ // counting how many times in-product help has been triggered for a particular
+ // feature.
+ EventConfig trigger;
+
+ // A set of all event configurations.
+ std::set<EventConfig> event_configs;
+
+ // Number of in-product help triggered within this session must fit this
+ // comparison.
+ Comparator session_rate;
+
+ // Number of days the in-product help has been available must fit this
+ // comparison.
+ Comparator availability;
};
bool operator==(const FeatureConfig& lhs, const FeatureConfig& rhs);
-
// A Configuration contains the current set of runtime configurations.
// It is up to each implementation of Configuration to provide a way to
// register features and their configurations.
class Configuration {
public:
- // Convenience alias for typical implementatinos of Configuration.
+ // Convenience alias for typical implementations of Configuration.
using ConfigMap = std::map<const base::Feature*, FeatureConfig>;
virtual ~Configuration() = default;
@@ -47,6 +124,9 @@ class Configuration {
virtual const FeatureConfig& GetFeatureConfig(
const base::Feature& feature) const = 0;
+ // Returns the immutable ConfigMap that contains all registered features.
+ virtual const ConfigMap& GetRegisteredFeatures() const = 0;
+
protected:
Configuration() = default;
diff --git a/chromium/components/feature_engagement_tracker/internal/configuration_unittest.cc b/chromium/components/feature_engagement_tracker/internal/configuration_unittest.cc
new file mode 100644
index 00000000000..20be6474803
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/configuration_unittest.cc
@@ -0,0 +1,81 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/configuration.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+TEST(ComparatorTest, Any) {
+ EXPECT_TRUE(Comparator(ANY, 0).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(ANY, 1).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(ANY, 1).MeetsCriteria(1));
+ EXPECT_TRUE(Comparator(ANY, 1).MeetsCriteria(2));
+ EXPECT_TRUE(Comparator(ANY, 10).MeetsCriteria(9));
+ EXPECT_TRUE(Comparator(ANY, 10).MeetsCriteria(10));
+ EXPECT_TRUE(Comparator(ANY, 10).MeetsCriteria(11));
+}
+
+TEST(ComparatorTest, LessThan) {
+ EXPECT_FALSE(Comparator(LESS_THAN, 0).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(LESS_THAN, 1).MeetsCriteria(0));
+ EXPECT_FALSE(Comparator(LESS_THAN, 1).MeetsCriteria(1));
+ EXPECT_FALSE(Comparator(LESS_THAN, 1).MeetsCriteria(2));
+ EXPECT_TRUE(Comparator(LESS_THAN, 10).MeetsCriteria(9));
+ EXPECT_FALSE(Comparator(LESS_THAN, 10).MeetsCriteria(10));
+ EXPECT_FALSE(Comparator(LESS_THAN, 10).MeetsCriteria(11));
+}
+
+TEST(ComparatorTest, GreaterThan) {
+ EXPECT_FALSE(Comparator(GREATER_THAN, 0).MeetsCriteria(0));
+ EXPECT_FALSE(Comparator(GREATER_THAN, 1).MeetsCriteria(0));
+ EXPECT_FALSE(Comparator(GREATER_THAN, 1).MeetsCriteria(1));
+ EXPECT_TRUE(Comparator(GREATER_THAN, 1).MeetsCriteria(2));
+ EXPECT_FALSE(Comparator(GREATER_THAN, 10).MeetsCriteria(9));
+ EXPECT_FALSE(Comparator(GREATER_THAN, 10).MeetsCriteria(10));
+ EXPECT_TRUE(Comparator(GREATER_THAN, 10).MeetsCriteria(11));
+}
+
+TEST(ComparatorTest, LessThanOrEqual) {
+ EXPECT_TRUE(Comparator(LESS_THAN_OR_EQUAL, 0).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(LESS_THAN_OR_EQUAL, 1).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(LESS_THAN_OR_EQUAL, 1).MeetsCriteria(1));
+ EXPECT_FALSE(Comparator(LESS_THAN_OR_EQUAL, 1).MeetsCriteria(2));
+ EXPECT_TRUE(Comparator(LESS_THAN_OR_EQUAL, 10).MeetsCriteria(9));
+ EXPECT_TRUE(Comparator(LESS_THAN_OR_EQUAL, 10).MeetsCriteria(10));
+ EXPECT_FALSE(Comparator(LESS_THAN_OR_EQUAL, 10).MeetsCriteria(11));
+}
+
+TEST(ComparatorTest, GreaterThanOrEqual) {
+ EXPECT_TRUE(Comparator(GREATER_THAN_OR_EQUAL, 0).MeetsCriteria(0));
+ EXPECT_FALSE(Comparator(GREATER_THAN_OR_EQUAL, 1).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(GREATER_THAN_OR_EQUAL, 1).MeetsCriteria(1));
+ EXPECT_TRUE(Comparator(GREATER_THAN_OR_EQUAL, 1).MeetsCriteria(2));
+ EXPECT_FALSE(Comparator(GREATER_THAN_OR_EQUAL, 10).MeetsCriteria(9));
+ EXPECT_TRUE(Comparator(GREATER_THAN_OR_EQUAL, 10).MeetsCriteria(10));
+ EXPECT_TRUE(Comparator(GREATER_THAN_OR_EQUAL, 10).MeetsCriteria(11));
+}
+
+TEST(ComparatorTest, Equal) {
+ EXPECT_TRUE(Comparator(EQUAL, 0).MeetsCriteria(0));
+ EXPECT_FALSE(Comparator(EQUAL, 1).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(EQUAL, 1).MeetsCriteria(1));
+ EXPECT_FALSE(Comparator(EQUAL, 1).MeetsCriteria(2));
+ EXPECT_FALSE(Comparator(EQUAL, 10).MeetsCriteria(9));
+ EXPECT_TRUE(Comparator(EQUAL, 10).MeetsCriteria(10));
+ EXPECT_FALSE(Comparator(EQUAL, 10).MeetsCriteria(11));
+}
+
+TEST(ComparatorTest, NotEqual) {
+ EXPECT_FALSE(Comparator(NOT_EQUAL, 0).MeetsCriteria(0));
+ EXPECT_TRUE(Comparator(NOT_EQUAL, 1).MeetsCriteria(0));
+ EXPECT_FALSE(Comparator(NOT_EQUAL, 1).MeetsCriteria(1));
+ EXPECT_TRUE(Comparator(NOT_EQUAL, 1).MeetsCriteria(2));
+ EXPECT_TRUE(Comparator(NOT_EQUAL, 10).MeetsCriteria(9));
+ EXPECT_FALSE(Comparator(NOT_EQUAL, 10).MeetsCriteria(10));
+ EXPECT_TRUE(Comparator(NOT_EQUAL, 10).MeetsCriteria(11));
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/editable_configuration.cc b/chromium/components/feature_engagement_tracker/internal/editable_configuration.cc
index f7a4cba5c5c..9559f1ea973 100644
--- a/chromium/components/feature_engagement_tracker/internal/editable_configuration.cc
+++ b/chromium/components/feature_engagement_tracker/internal/editable_configuration.cc
@@ -28,4 +28,9 @@ const FeatureConfig& EditableConfiguration::GetFeatureConfig(
return it->second;
}
+const Configuration::ConfigMap& EditableConfiguration::GetRegisteredFeatures()
+ const {
+ return configs_;
+}
+
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/editable_configuration.h b/chromium/components/feature_engagement_tracker/internal/editable_configuration.h
index 2e01b72118f..7d26122bcee 100644
--- a/chromium/components/feature_engagement_tracker/internal/editable_configuration.h
+++ b/chromium/components/feature_engagement_tracker/internal/editable_configuration.h
@@ -22,9 +22,10 @@ class EditableConfiguration : public Configuration {
EditableConfiguration();
~EditableConfiguration() override;
- // Configuration implementaiton.
+ // Configuration implementation.
const FeatureConfig& GetFeatureConfig(
const base::Feature& feature) const override;
+ const Configuration::ConfigMap& GetRegisteredFeatures() const override;
// Adds a new FeatureConfig to the current configurations. If it already
// exists, the contents are replaced.
diff --git a/chromium/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc b/chromium/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc
index 896e0381734..ee347bdd40f 100644
--- a/chromium/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc
+++ b/chromium/components/feature_engagement_tracker/internal/editable_configuration_unittest.cc
@@ -7,8 +7,6 @@
#include <string>
#include "base/feature_list.h"
-#include "base/metrics/field_trial.h"
-#include "base/test/scoped_feature_list.h"
#include "components/feature_engagement_tracker/internal/configuration.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,20 +25,17 @@ class EditableConfigurationTest : public ::testing::Test {
bool valid) {
FeatureConfig feature_config;
feature_config.valid = valid;
- feature_config.feature_used_event = feature_used_event;
+ feature_config.used.name = feature_used_event;
return feature_config;
}
protected:
- base::test::ScopedFeatureList scoped_feature_list_;
EditableConfiguration configuration_;
};
} // namespace
TEST_F(EditableConfigurationTest, SingleConfigAddAndGet) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
-
FeatureConfig foo_config = CreateFeatureConfig("foo", true);
configuration_.SetConfiguration(&kTestFeatureFoo, foo_config);
const FeatureConfig& foo_config_result =
@@ -50,8 +45,6 @@ TEST_F(EditableConfigurationTest, SingleConfigAddAndGet) {
}
TEST_F(EditableConfigurationTest, TwoConfigAddAndGet) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
-
FeatureConfig foo_config = CreateFeatureConfig("foo", true);
configuration_.SetConfiguration(&kTestFeatureFoo, foo_config);
FeatureConfig bar_config = CreateFeatureConfig("bar", true);
@@ -67,8 +60,6 @@ TEST_F(EditableConfigurationTest, TwoConfigAddAndGet) {
}
TEST_F(EditableConfigurationTest, ConfigShouldBeEditable) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
-
FeatureConfig valid_foo_config = CreateFeatureConfig("foo", true);
configuration_.SetConfiguration(&kTestFeatureFoo, valid_foo_config);
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.cc b/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.cc
new file mode 100644
index 00000000000..ff6e1ad5ef1
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.cc
@@ -0,0 +1,121 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/feature_config_condition_validator.h"
+
+#include "base/feature_list.h"
+#include "components/feature_engagement_tracker/internal/availability_model.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+
+namespace feature_engagement_tracker {
+
+FeatureConfigConditionValidator::FeatureConfigConditionValidator()
+ : currently_showing_(false), times_shown_(0u) {}
+
+FeatureConfigConditionValidator::~FeatureConfigConditionValidator() = default;
+
+ConditionValidator::Result FeatureConfigConditionValidator::MeetsConditions(
+ const base::Feature& feature,
+ const FeatureConfig& config,
+ const Model& model,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const {
+ ConditionValidator::Result result(true);
+ result.event_model_ready_ok = model.IsReady();
+ result.currently_showing_ok = !currently_showing_;
+ result.feature_enabled_ok = base::FeatureList::IsEnabled(feature);
+ result.config_ok = config.valid;
+ result.used_ok = EventConfigMeetsConditions(config.used, model, current_day);
+ result.trigger_ok =
+ EventConfigMeetsConditions(config.trigger, model, current_day);
+
+ for (const auto& event_config : config.event_configs) {
+ result.preconditions_ok &=
+ EventConfigMeetsConditions(event_config, model, current_day);
+ }
+
+ result.session_rate_ok = config.session_rate.MeetsCriteria(times_shown_);
+
+ result.availability_model_ready_ok = availability_model.IsReady();
+
+ result.availability_ok = AvailabilityMeetsConditions(
+ feature, config.availability, availability_model, current_day);
+
+ return result;
+}
+
+void FeatureConfigConditionValidator::NotifyIsShowing(
+ const base::Feature& feature) {
+ DCHECK(!currently_showing_);
+ DCHECK(base::FeatureList::IsEnabled(feature));
+
+ currently_showing_ = true;
+ ++times_shown_;
+}
+
+void FeatureConfigConditionValidator::NotifyDismissed(
+ const base::Feature& feature) {
+ currently_showing_ = false;
+}
+
+bool FeatureConfigConditionValidator::EventConfigMeetsConditions(
+ const EventConfig& event_config,
+ const Model& model,
+ uint32_t current_day) const {
+ const Event* event = model.GetEvent(event_config.name);
+
+ // If no events are found, the requirement must be met with 0 elements.
+ // Also, if the window is 0 days, there will never be any events.
+ if (event == nullptr || event_config.window == 0u)
+ return event_config.comparator.MeetsCriteria(0u);
+
+ DCHECK(event_config.window >= 0);
+
+ // A window of N=0: Nothing should be counted.
+ // A window of N=1: |current_day| should be counted.
+ // A window of N=2+: |current_day| plus |N-1| more days should be counted.
+ uint32_t oldest_accepted_day = current_day - event_config.window + 1;
+
+ // Cap |oldest_accepted_day| to UNIX epoch.
+ if (event_config.window > current_day)
+ oldest_accepted_day = 0u;
+
+ // Calculate the number of events within the window.
+ uint32_t event_count = 0;
+ for (const auto& event_day : event->events()) {
+ if (event_day.day() < oldest_accepted_day)
+ continue;
+
+ event_count += event_day.count();
+ }
+
+ return event_config.comparator.MeetsCriteria(event_count);
+}
+
+bool FeatureConfigConditionValidator::AvailabilityMeetsConditions(
+ const base::Feature& feature,
+ Comparator comparator,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const {
+ if (comparator.type == ANY)
+ return true;
+
+ base::Optional<uint32_t> availability_day =
+ availability_model.GetAvailability(feature);
+ if (!availability_day.has_value())
+ return false;
+
+ uint32_t days_available = current_day - availability_day.value();
+
+ // Ensure that availability days never wrap around.
+ if (availability_day.value() > current_day)
+ days_available = 0u;
+
+ return comparator.MeetsCriteria(days_available);
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.h b/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.h
new file mode 100644
index 00000000000..02f719597bb
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator.h
@@ -0,0 +1,56 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_CONFIG_CONDITION_VALIDATOR_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_CONFIG_CONDITION_VALIDATOR_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "components/feature_engagement_tracker/internal/condition_validator.h"
+
+namespace feature_engagement_tracker {
+class AvailabilityModel;
+struct Comparator;
+struct EventConfig;
+class Model;
+
+// A ConditionValidator that uses the FeatureConfigs as the source of truth.
+class FeatureConfigConditionValidator : public ConditionValidator {
+ public:
+ FeatureConfigConditionValidator();
+ ~FeatureConfigConditionValidator() override;
+
+ // ConditionValidator implementation.
+ ConditionValidator::Result MeetsConditions(
+ const base::Feature& feature,
+ const FeatureConfig& config,
+ const Model& model,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const override;
+ void NotifyIsShowing(const base::Feature& feature) override;
+ void NotifyDismissed(const base::Feature& feature) override;
+
+ private:
+ bool EventConfigMeetsConditions(const EventConfig& event_config,
+ const Model& model,
+ uint32_t current_day) const;
+
+ bool AvailabilityMeetsConditions(const base::Feature& feature,
+ Comparator comparator,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const;
+
+ // Whether in-product help is currently being shown.
+ bool currently_showing_;
+
+ // Number of times in-product help has been shown within the current session.
+ uint32_t times_shown_;
+
+ DISALLOW_COPY_AND_ASSIGN(FeatureConfigConditionValidator);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_CONFIG_CONDITION_VALIDATOR_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc b/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc
new file mode 100644
index 00000000000..3853f39f5b9
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc
@@ -0,0 +1,538 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/feature_config_condition_validator.h"
+
+#include <map>
+#include <string>
+
+#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/feature_engagement_tracker/internal/availability_model.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+#include "components/feature_engagement_tracker/internal/test/event_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+const base::Feature kTestFeatureFoo{"test_foo",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureBar{"test_bar",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+FeatureConfig GetValidFeatureConfig() {
+ FeatureConfig config;
+ config.valid = true;
+ return config;
+}
+
+FeatureConfig GetAcceptingFeatureConfig() {
+ FeatureConfig config;
+ config.valid = true;
+ config.used = EventConfig("used", Comparator(ANY, 0), 0, 0);
+ config.trigger = EventConfig("trigger", Comparator(ANY, 0), 0, 0);
+ config.session_rate = Comparator(ANY, 0);
+ config.availability = Comparator(ANY, 0);
+ return config;
+}
+
+class TestModel : public Model {
+ public:
+ TestModel() : ready_(true) {}
+
+ void Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) override {}
+
+ bool IsReady() const override { return ready_; }
+
+ void SetIsReady(bool ready) { ready_ = ready; }
+
+ const Event* GetEvent(const std::string& event_name) const override {
+ auto search = events_.find(event_name);
+ if (search == events_.end())
+ return nullptr;
+
+ return &search->second;
+ }
+
+ void SetEvent(const Event& event) { events_[event.name()] = event; }
+
+ void IncrementEvent(const std::string& event_name, uint32_t day) override {}
+
+ private:
+ std::map<std::string, Event> events_;
+ bool ready_;
+};
+
+class TestAvailabilityModel : public AvailabilityModel {
+ public:
+ TestAvailabilityModel() : ready_(true) {}
+ ~TestAvailabilityModel() override = default;
+
+ void Initialize(AvailabilityModel::OnInitializedCallback callback,
+ uint32_t current_day) override {}
+
+ bool IsReady() const override { return ready_; }
+
+ void SetIsReady(bool ready) { ready_ = ready; }
+
+ base::Optional<uint32_t> GetAvailability(
+ const base::Feature& feature) const override {
+ auto search = availabilities_.find(&feature);
+ if (search == availabilities_.end())
+ return base::nullopt;
+
+ return search->second;
+ }
+
+ void SetAvailability(const base::Feature* feature,
+ base::Optional<uint32_t> availability) {
+ availabilities_[feature] = availability;
+ }
+
+ private:
+ bool ready_;
+
+ std::map<const base::Feature*, base::Optional<uint32_t>> availabilities_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestAvailabilityModel);
+};
+
+class FeatureConfigConditionValidatorTest : public ::testing::Test {
+ public:
+ FeatureConfigConditionValidatorTest() = default;
+
+ protected:
+ ConditionValidator::Result GetResultForDayAndEventWindow(
+ Comparator comparator,
+ uint32_t window,
+ uint32_t current_day) {
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(EventConfig("event1", comparator, window, 0));
+ return validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, current_day);
+ }
+
+ ConditionValidator::Result GetResultForDay(const FeatureConfig& config,
+ uint32_t current_day) {
+ return validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, current_day);
+ }
+
+ ConditionValidator::Result GetResultForDayZero(const FeatureConfig& config) {
+ return validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, 0);
+ }
+
+ TestModel model_;
+ TestAvailabilityModel availability_model_;
+ FeatureConfigConditionValidator validator_;
+ uint32_t current_day_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FeatureConfigConditionValidatorTest);
+};
+
+} // namespace
+
+TEST_F(FeatureConfigConditionValidatorTest, ModelNotReadyShouldFail) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ model_.SetIsReady(false);
+
+ ConditionValidator::Result result =
+ GetResultForDayZero(GetValidFeatureConfig());
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.event_model_ready_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, ConfigInvalidShouldFail) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ ConditionValidator::Result result = GetResultForDayZero(FeatureConfig());
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.config_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, MultipleErrorsShouldBeSet) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ model_.SetIsReady(false);
+
+ ConditionValidator::Result result = GetResultForDayZero(FeatureConfig());
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.event_model_ready_ok);
+ EXPECT_FALSE(result.config_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, ReadyModelEmptyConfig) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ EXPECT_TRUE(GetResultForDayZero(GetValidFeatureConfig()).NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, ReadyModelAcceptingConfig) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ EXPECT_TRUE(GetResultForDayZero(GetAcceptingFeatureConfig()).NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, CurrentlyShowing) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
+
+ validator_.NotifyIsShowing(kTestFeatureBar);
+ ConditionValidator::Result result =
+ GetResultForDayZero(GetAcceptingFeatureConfig());
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.currently_showing_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, Used) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.used = EventConfig("used", Comparator(LESS_THAN, 0), 0, 0);
+
+ ConditionValidator::Result result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.used_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, Trigger) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.trigger = EventConfig("trigger", Comparator(LESS_THAN, 0), 0, 0);
+
+ ConditionValidator::Result result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.trigger_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, SingleOKPrecondition) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(EventConfig("event1", Comparator(ANY, 0), 0, 0));
+
+ EXPECT_TRUE(GetResultForDayZero(config).NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, MultipleOKPreconditions) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(EventConfig("event1", Comparator(ANY, 0), 0, 0));
+ config.event_configs.insert(EventConfig("event2", Comparator(ANY, 0), 0, 0));
+
+ EXPECT_TRUE(GetResultForDayZero(config).NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, OneOKThenOneFailingPrecondition) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(EventConfig("event1", Comparator(ANY, 0), 0, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(LESS_THAN, 0), 0, 0));
+
+ ConditionValidator::Result result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.preconditions_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, OneFailingThenOneOKPrecondition) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(EventConfig("event1", Comparator(ANY, 0), 0, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(LESS_THAN, 0), 0, 0));
+
+ ConditionValidator::Result result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.preconditions_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, TwoFailingPreconditions) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(
+ EventConfig("event1", Comparator(LESS_THAN, 0), 0, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(LESS_THAN, 0), 0, 0));
+
+ ConditionValidator::Result result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.preconditions_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, SessionRate) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.session_rate = Comparator(LESS_THAN, 2u);
+
+ EXPECT_TRUE(GetResultForDayZero(config).NoErrors());
+
+ validator_.NotifyIsShowing(kTestFeatureBar);
+ validator_.NotifyDismissed(kTestFeatureBar);
+ EXPECT_TRUE(GetResultForDayZero(config).NoErrors());
+
+ validator_.NotifyIsShowing(kTestFeatureBar);
+ validator_.NotifyDismissed(kTestFeatureBar);
+ ConditionValidator::Result result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.session_rate_ok);
+
+ validator_.NotifyIsShowing(kTestFeatureBar);
+ validator_.NotifyDismissed(kTestFeatureBar);
+ result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.session_rate_ok);
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, Availability) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
+
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ EXPECT_TRUE(GetResultForDayZero(config).NoErrors());
+ EXPECT_TRUE(GetResultForDay(config, 100u).NoErrors());
+
+ // When the AvailabilityModel is not ready, it should fail.
+ availability_model_.SetIsReady(false);
+ ConditionValidator::Result result = GetResultForDayZero(config);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.availability_model_ready_ok);
+ result = GetResultForDay(config, 100u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.availability_model_ready_ok);
+
+ // Reset state back to ready.
+ availability_model_.SetIsReady(true);
+
+ // For a feature that became available on day 2 that has to have been
+ // available for at least 1 day, it should start being accepted on day 3.
+ availability_model_.SetAvailability(&kTestFeatureFoo, 2u);
+ config.availability = Comparator(GREATER_THAN_OR_EQUAL, 1u);
+ result = GetResultForDay(config, 1u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.availability_ok);
+ result = GetResultForDay(config, 2u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.availability_ok);
+ EXPECT_TRUE(GetResultForDay(config, 3u).NoErrors());
+ EXPECT_TRUE(GetResultForDay(config, 4u).NoErrors());
+
+ // For a feature that became available on day 10 that has to have been
+ // available for at least 3 days, it should start being accepted on day 13.
+ availability_model_.SetAvailability(&kTestFeatureFoo, 10u);
+ config.availability = Comparator(GREATER_THAN_OR_EQUAL, 3u);
+ result = GetResultForDay(config, 11u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.availability_ok);
+ result = GetResultForDay(config, 12u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.availability_ok);
+ EXPECT_TRUE(GetResultForDay(config, 13u).NoErrors());
+ EXPECT_TRUE(GetResultForDay(config, 14u).NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, SingleEventChangingComparator) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ uint32_t current_day = 102u;
+ uint32_t window = 10u;
+
+ // Create event with 10 events per day for three days.
+ Event event1;
+ event1.set_name("event1");
+ test::SetEventCountForDay(&event1, 100u, 10u);
+ test::SetEventCountForDay(&event1, 101u, 10u);
+ test::SetEventCountForDay(&event1, 102u, 10u);
+ model_.SetEvent(event1);
+
+ EXPECT_TRUE(GetResultForDayAndEventWindow(Comparator(LESS_THAN, 50u), window,
+ current_day)
+ .NoErrors());
+ EXPECT_TRUE(
+ GetResultForDayAndEventWindow(Comparator(EQUAL, 30u), window, current_day)
+ .NoErrors());
+ EXPECT_FALSE(GetResultForDayAndEventWindow(Comparator(LESS_THAN, 30u), window,
+ current_day)
+ .NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, SingleEventChangingWindow) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ Event event1;
+ event1.set_name("event1");
+ test::SetEventCountForDay(&event1, 100u, 10u);
+ test::SetEventCountForDay(&event1, 101u, 10u);
+ test::SetEventCountForDay(&event1, 102u, 10u);
+ test::SetEventCountForDay(&event1, 103u, 10u);
+ test::SetEventCountForDay(&event1, 104u, 10u);
+ model_.SetEvent(event1);
+
+ uint32_t current_day = 104u;
+
+ EXPECT_FALSE(GetResultForDayAndEventWindow(Comparator(GREATER_THAN, 30u), 0,
+ current_day)
+ .NoErrors());
+ EXPECT_FALSE(GetResultForDayAndEventWindow(Comparator(GREATER_THAN, 30u), 1u,
+ current_day)
+ .NoErrors());
+ EXPECT_FALSE(GetResultForDayAndEventWindow(Comparator(GREATER_THAN, 30u), 2u,
+ current_day)
+ .NoErrors());
+ EXPECT_FALSE(GetResultForDayAndEventWindow(Comparator(GREATER_THAN, 30u), 3u,
+ current_day)
+ .NoErrors());
+ EXPECT_TRUE(GetResultForDayAndEventWindow(Comparator(GREATER_THAN, 30u), 4u,
+ current_day)
+ .NoErrors());
+ EXPECT_TRUE(GetResultForDayAndEventWindow(Comparator(GREATER_THAN, 30u), 5u,
+ current_day)
+ .NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, CapEarliestAcceptedDayAtEpoch) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ Event event1;
+ event1.set_name("event1");
+ test::SetEventCountForDay(&event1, 0, 10u);
+ test::SetEventCountForDay(&event1, 1u, 10u);
+ test::SetEventCountForDay(&event1, 2u, 10u);
+ model_.SetEvent(event1);
+
+ uint32_t current_day = 100u;
+
+ EXPECT_TRUE(
+ GetResultForDayAndEventWindow(Comparator(EQUAL, 10u), 99u, current_day)
+ .NoErrors());
+ EXPECT_TRUE(
+ GetResultForDayAndEventWindow(Comparator(EQUAL, 20u), 100u, current_day)
+ .NoErrors());
+ EXPECT_TRUE(
+ GetResultForDayAndEventWindow(Comparator(EQUAL, 30u), 101u, current_day)
+ .NoErrors());
+ EXPECT_TRUE(
+ GetResultForDayAndEventWindow(Comparator(EQUAL, 30u), 1000u, current_day)
+ .NoErrors());
+}
+
+TEST_F(FeatureConfigConditionValidatorTest, TestMultipleEvents) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({kTestFeatureFoo}, {});
+
+ Event event1;
+ event1.set_name("event1");
+ test::SetEventCountForDay(&event1, 0, 10u);
+ test::SetEventCountForDay(&event1, 1u, 10u);
+ test::SetEventCountForDay(&event1, 2u, 10u);
+ model_.SetEvent(event1);
+
+ Event event2;
+ event2.set_name("event2");
+ test::SetEventCountForDay(&event2, 0, 5u);
+ test::SetEventCountForDay(&event2, 1u, 5u);
+ test::SetEventCountForDay(&event2, 2u, 5u);
+ model_.SetEvent(event2);
+
+ uint32_t current_day = 100u;
+
+ // Verify validator counts correctly for two events last 99 days.
+ FeatureConfig config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(
+ EventConfig("event1", Comparator(EQUAL, 10u), 99u, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(EQUAL, 5u), 99u, 0));
+ ConditionValidator::Result result = validator_.MeetsConditions(
+ kTestFeatureFoo, config, model_, availability_model_, current_day);
+ EXPECT_TRUE(result.NoErrors());
+
+ // Verify validator counts correctly for two events last 100 days.
+ config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(
+ EventConfig("event1", Comparator(EQUAL, 20u), 100u, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(EQUAL, 10u), 100u, 0));
+ result = validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, current_day);
+ EXPECT_TRUE(result.NoErrors());
+
+ // Verify validator counts correctly for two events last 101 days.
+ config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(
+ EventConfig("event1", Comparator(EQUAL, 30u), 101u, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(EQUAL, 15u), 101u, 0));
+ result = validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, current_day);
+ EXPECT_TRUE(result.NoErrors());
+
+ // Verify validator counts correctly for two events last 101 days, and returns
+ // error when first event fails.
+ config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(
+ EventConfig("event1", Comparator(EQUAL, 0), 101u, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(EQUAL, 15u), 101u, 0));
+ result = validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, current_day);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.preconditions_ok);
+
+ // Verify validator counts correctly for two events last 101 days, and returns
+ // error when second event fails.
+ config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(
+ EventConfig("event1", Comparator(EQUAL, 30u), 101u, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(EQUAL, 0), 101u, 0));
+ result = validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, current_day);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.preconditions_ok);
+
+ // Verify validator counts correctly for two events last 101 days, and returns
+ // error when both events fail.
+ config = GetAcceptingFeatureConfig();
+ config.event_configs.insert(
+ EventConfig("event1", Comparator(EQUAL, 0), 101u, 0));
+ config.event_configs.insert(
+ EventConfig("event2", Comparator(EQUAL, 0), 101u, 0));
+ result = validator_.MeetsConditions(kTestFeatureFoo, config, model_,
+ availability_model_, current_day);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.preconditions_ok);
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc b/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc
new file mode 100644
index 00000000000..5dc27e3289b
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc
@@ -0,0 +1,87 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/feature_config_storage_validator.h"
+
+#include <unordered_map>
+#include <unordered_set>
+
+#include "base/feature_list.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+
+namespace feature_engagement_tracker {
+
+FeatureConfigStorageValidator::FeatureConfigStorageValidator() = default;
+
+FeatureConfigStorageValidator::~FeatureConfigStorageValidator() = default;
+
+bool FeatureConfigStorageValidator::ShouldStore(
+ const std::string& event_name) const {
+ return should_store_event_names_.find(event_name) !=
+ should_store_event_names_.end();
+}
+
+bool FeatureConfigStorageValidator::ShouldKeep(const std::string& event_name,
+ uint32_t event_day,
+ uint32_t current_day) const {
+ // Should not keep events that will happen in the future.
+ if (event_day > current_day)
+ return false;
+
+ // If no feature configuration mentioned the event, it should not be kept.
+ auto it = longest_storage_times_.find(event_name);
+ if (it == longest_storage_times_.end())
+ return false;
+
+ // Too old events should not be kept.
+ uint32_t longest_storage_time = it->second;
+ uint32_t age = current_day - event_day;
+ if (longest_storage_time <= age)
+ return false;
+
+ return true;
+}
+
+void FeatureConfigStorageValidator::InitializeFeatures(
+ FeatureVector features,
+ const Configuration& configuration) {
+ for (const auto* feature : features) {
+ if (!base::FeatureList::IsEnabled(*feature))
+ continue;
+
+ InitializeFeatureConfig(configuration.GetFeatureConfig(*feature));
+ }
+}
+
+void FeatureConfigStorageValidator::ClearForTesting() {
+ should_store_event_names_.clear();
+ longest_storage_times_.clear();
+}
+
+void FeatureConfigStorageValidator::InitializeFeatureConfig(
+ const FeatureConfig& feature_config) {
+ InitializeEventConfig(feature_config.used);
+ InitializeEventConfig(feature_config.trigger);
+
+ for (const auto& event_config : feature_config.event_configs)
+ InitializeEventConfig(event_config);
+}
+
+void FeatureConfigStorageValidator::InitializeEventConfig(
+ const EventConfig& event_config) {
+ // Minimum storage time is 1 day.
+ if (event_config.storage < 1u)
+ return;
+
+ // When minimum storage time is met, new events should always be stored.
+ should_store_event_names_.insert(event_config.name);
+
+ // Track the longest time any configuration wants to store a particular event.
+ uint32_t current_longest_time = longest_storage_times_[event_config.name];
+ if (event_config.storage > current_longest_time)
+ longest_storage_times_[event_config.name] = event_config.storage;
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.h b/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.h
new file mode 100644
index 00000000000..c4a4fc555f1
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator.h
@@ -0,0 +1,63 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_CONFIG_STORAGE_VALIDATOR_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_CONFIG_STORAGE_VALIDATOR_H_
+
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "base/macros.h"
+#include "components/feature_engagement_tracker/internal/storage_validator.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+
+namespace feature_engagement_tracker {
+class Configuration;
+struct EventConfig;
+struct FeatureConfig;
+
+// A StorageValidator that uses the FeatureConfig as the source of truth.
+class FeatureConfigStorageValidator : public StorageValidator {
+ public:
+ FeatureConfigStorageValidator();
+ ~FeatureConfigStorageValidator() override;
+
+ // StorageValidator implementation.
+ bool ShouldStore(const std::string& event_name) const override;
+ bool ShouldKeep(const std::string& event_name,
+ uint32_t event_day,
+ uint32_t current_day) const override;
+
+ // Set up internal configuration required for the given |features|.
+ void InitializeFeatures(FeatureVector features,
+ const Configuration& configuration);
+
+ // Resets the full state of this StorageValidator. After calling this method
+ // it is valid to call InitializeFeatures() again.
+ void ClearForTesting();
+
+ private:
+ // Updates the internal configuration with conditions from the given
+ // |feature_config|.
+ void InitializeFeatureConfig(const FeatureConfig& feature_config);
+
+ // Updates the internal configuration with conditions from the given
+ // |event_config|.
+ void InitializeEventConfig(const EventConfig& event_config);
+
+ // Contains an entry for each of the events that any EventConfig required to
+ // be stored.
+ std::unordered_set<std::string> should_store_event_names_;
+
+ // Contains the longest time to store each event across all EventConfigs,
+ // as a number of days.
+ std::unordered_map<std::string, uint32_t> longest_storage_times_;
+
+ DISALLOW_COPY_AND_ASSIGN(FeatureConfigStorageValidator);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_CONFIG_STORAGE_VALIDATOR_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator_unittest.cc b/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator_unittest.cc
new file mode 100644
index 00000000000..3e7f8024b27
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/feature_config_storage_validator_unittest.cc
@@ -0,0 +1,294 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/feature_config_storage_validator.h"
+
+#include <string>
+
+#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/editable_configuration.h"
+#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+const base::Feature kTestFeatureFoo{"test_foo",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureBar{"test_bar",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+FeatureConfig kNeverStored;
+FeatureConfig kStoredInUsed1Day;
+FeatureConfig kStoredInUsed2Days;
+FeatureConfig kStoredInUsed10Days;
+FeatureConfig kStoredInTrigger1Day;
+FeatureConfig kStoredInTrigger2Days;
+FeatureConfig kStoredInTrigger10Days;
+FeatureConfig kStoredInEventConfigs1Day;
+FeatureConfig kStoredInEventConfigs2Days;
+FeatureConfig kStoredInEventConfigs10Days;
+
+void InitializeStorageFeatureConfigs() {
+ FeatureConfig default_config;
+ default_config.valid = true;
+ default_config.used = EventConfig("myevent", Comparator(ANY, 0), 0, 0);
+ default_config.trigger = EventConfig("myevent", Comparator(ANY, 0), 0, 0);
+ default_config.event_configs.insert(
+ EventConfig("myevent", Comparator(ANY, 0), 0, 0));
+ default_config.event_configs.insert(
+ EventConfig("unrelated_event", Comparator(ANY, 0), 0, 100));
+ default_config.session_rate = Comparator(ANY, 0);
+ default_config.availability = Comparator(ANY, 0);
+
+ kNeverStored = default_config;
+
+ kStoredInUsed1Day = default_config;
+ kStoredInUsed1Day.used = EventConfig("myevent", Comparator(ANY, 0), 0, 1);
+
+ kStoredInUsed2Days = default_config;
+ kStoredInUsed2Days.used = EventConfig("myevent", Comparator(ANY, 0), 0, 2);
+
+ kStoredInUsed10Days = default_config;
+ kStoredInUsed10Days.used = EventConfig("myevent", Comparator(ANY, 0), 0, 10);
+
+ kStoredInTrigger1Day = default_config;
+ kStoredInTrigger1Day.trigger =
+ EventConfig("myevent", Comparator(ANY, 0), 0, 1);
+
+ kStoredInTrigger2Days = default_config;
+ kStoredInTrigger2Days.trigger =
+ EventConfig("myevent", Comparator(ANY, 0), 0, 2);
+
+ kStoredInTrigger10Days = default_config;
+ kStoredInTrigger10Days.trigger =
+ EventConfig("myevent", Comparator(ANY, 0), 0, 10);
+
+ kStoredInEventConfigs1Day = default_config;
+ kStoredInEventConfigs1Day.event_configs.clear();
+ kStoredInEventConfigs1Day.event_configs.insert(
+ EventConfig("myevent", Comparator(ANY, 0), 0, 0));
+ kStoredInEventConfigs1Day.event_configs.insert(
+ EventConfig("myevent", Comparator(ANY, 0), 0, 1));
+ kStoredInEventConfigs1Day.event_configs.insert(
+ EventConfig("unrelated_event", Comparator(ANY, 0), 0, 100));
+
+ kStoredInEventConfigs2Days = default_config;
+ kStoredInEventConfigs2Days.event_configs.clear();
+ kStoredInEventConfigs2Days.event_configs.insert(
+ EventConfig("myevent", Comparator(ANY, 0), 0, 0));
+ kStoredInEventConfigs2Days.event_configs.insert(
+ EventConfig("myevent", Comparator(ANY, 0), 0, 2));
+ kStoredInEventConfigs2Days.event_configs.insert(
+ EventConfig("unrelated_event", Comparator(ANY, 0), 0, 100));
+
+ kStoredInEventConfigs10Days = default_config;
+ kStoredInEventConfigs10Days.event_configs.clear();
+ kStoredInEventConfigs10Days.event_configs.insert(
+ EventConfig("myevent", Comparator(ANY, 0), 0, 0));
+ kStoredInEventConfigs10Days.event_configs.insert(
+ EventConfig("myevent", Comparator(ANY, 0), 0, 10));
+ kStoredInEventConfigs10Days.event_configs.insert(
+ EventConfig("unrelated_event", Comparator(ANY, 0), 0, 100));
+}
+
+class FeatureConfigStorageValidatorTest : public ::testing::Test {
+ public:
+ FeatureConfigStorageValidatorTest() : current_day_(100) {
+ InitializeStorageFeatureConfigs();
+ }
+
+ void UseConfig(const FeatureConfig& foo_config) {
+ FeatureVector features = {&kTestFeatureFoo};
+
+ validator_.ClearForTesting();
+ EditableConfiguration configuration;
+ configuration.SetConfiguration(&kTestFeatureFoo, foo_config);
+ validator_.InitializeFeatures(features, configuration);
+ }
+
+ void UseConfigs(const FeatureConfig& foo_config,
+ const FeatureConfig& bar_config) {
+ FeatureVector features = {&kTestFeatureFoo, &kTestFeatureBar};
+
+ validator_.ClearForTesting();
+ EditableConfiguration configuration;
+ configuration.SetConfiguration(&kTestFeatureFoo, foo_config);
+ configuration.SetConfiguration(&kTestFeatureBar, bar_config);
+ validator_.InitializeFeatures(features, configuration);
+ }
+
+ void VerifyNeverKeep() {
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 89, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 90, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 91, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 98, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 99, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 100, current_day_));
+ // This is trying to store data in the future, which should never happen.
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 101, current_day_));
+ }
+
+ void VerifyKeep1Day() {
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 89, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 90, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 91, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 98, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 99, current_day_));
+ EXPECT_TRUE(validator_.ShouldKeep("myevent", 100, current_day_));
+ // This is trying to store data in the future, which should never happen.
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 101, current_day_));
+ }
+
+ void VerifyKeep2Days() {
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 89, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 90, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 91, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 98, current_day_));
+ EXPECT_TRUE(validator_.ShouldKeep("myevent", 99, current_day_));
+ EXPECT_TRUE(validator_.ShouldKeep("myevent", 100, current_day_));
+ // This is trying to store data in the future, which should never happen.
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 101, current_day_));
+ }
+
+ void VerifyKeep10Days() {
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 89, current_day_));
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 90, current_day_));
+ EXPECT_TRUE(validator_.ShouldKeep("myevent", 91, current_day_));
+ EXPECT_TRUE(validator_.ShouldKeep("myevent", 98, current_day_));
+ EXPECT_TRUE(validator_.ShouldKeep("myevent", 99, current_day_));
+ EXPECT_TRUE(validator_.ShouldKeep("myevent", 100, current_day_));
+ // This is trying to store data in the future, which should never happen.
+ EXPECT_FALSE(validator_.ShouldKeep("myevent", 101, current_day_));
+ }
+
+ protected:
+ FeatureConfigStorageValidator validator_;
+ uint32_t current_day_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FeatureConfigStorageValidatorTest);
+};
+
+} // namespace
+
+TEST_F(FeatureConfigStorageValidatorTest,
+ ShouldOnlyUseConfigFromEnabledFeatures) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {kTestFeatureBar});
+
+ FeatureConfig foo_config = kNeverStored;
+ foo_config.used = EventConfig("fooevent", Comparator(ANY, 0), 0, 1);
+ FeatureConfig bar_config = kNeverStored;
+ bar_config.used = EventConfig("barevent", Comparator(ANY, 0), 0, 1);
+ UseConfigs(foo_config, bar_config);
+
+ EXPECT_FALSE(validator_.ShouldStore("myevent"));
+ EXPECT_TRUE(validator_.ShouldStore("fooevent"));
+ EXPECT_FALSE(validator_.ShouldStore("barevent"));
+}
+
+TEST_F(FeatureConfigStorageValidatorTest,
+ ShouldStoreIfSingleConfigHasMinimum1DayStorage) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
+
+ UseConfig(kNeverStored);
+ EXPECT_FALSE(validator_.ShouldStore("myevent"));
+
+ const FeatureConfig* should_store_configs[] = {
+ &kStoredInUsed1Day, &kStoredInUsed2Days,
+ &kStoredInUsed10Days, &kStoredInTrigger1Day,
+ &kStoredInTrigger2Days, &kStoredInTrigger10Days,
+ &kStoredInEventConfigs1Day, &kStoredInEventConfigs2Days,
+ &kStoredInEventConfigs10Days};
+ for (const FeatureConfig* config : should_store_configs) {
+ UseConfig(*config);
+ EXPECT_TRUE(validator_.ShouldStore("myevent"));
+ }
+}
+
+TEST_F(FeatureConfigStorageValidatorTest,
+ ShouldStoreIfAnyConfigHasMinimum1DayStorage) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
+
+ UseConfigs(kNeverStored, kNeverStored);
+ EXPECT_FALSE(validator_.ShouldStore("myevent"));
+
+ const FeatureConfig* should_store_configs[] = {
+ &kStoredInUsed1Day, &kStoredInUsed2Days,
+ &kStoredInUsed10Days, &kStoredInTrigger1Day,
+ &kStoredInTrigger2Days, &kStoredInTrigger10Days,
+ &kStoredInEventConfigs1Day, &kStoredInEventConfigs2Days,
+ &kStoredInEventConfigs10Days};
+ for (const FeatureConfig* config : should_store_configs) {
+ UseConfigs(kNeverStored, *config);
+ EXPECT_TRUE(validator_.ShouldStore("myevent"));
+ }
+}
+
+TEST_F(FeatureConfigStorageValidatorTest,
+ ShouldKeepIfSingleConfigMeetsEventAge) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
+
+ UseConfig(kNeverStored);
+ VerifyNeverKeep();
+
+ const FeatureConfig* one_day_storage_configs[] = {
+ &kStoredInUsed1Day, &kStoredInTrigger1Day, &kStoredInEventConfigs1Day};
+ for (const FeatureConfig* config : one_day_storage_configs) {
+ UseConfig(*config);
+ VerifyKeep1Day();
+ }
+
+ const FeatureConfig* two_days_storage_configs[] = {
+ &kStoredInUsed2Days, &kStoredInTrigger2Days, &kStoredInEventConfigs2Days};
+ for (const FeatureConfig* config : two_days_storage_configs) {
+ UseConfig(*config);
+ VerifyKeep2Days();
+ }
+
+ const FeatureConfig* ten_days_storage_configs[] = {
+ &kStoredInUsed10Days, &kStoredInTrigger10Days,
+ &kStoredInEventConfigs10Days};
+ for (const FeatureConfig* config : ten_days_storage_configs) {
+ UseConfig(*config);
+ VerifyKeep10Days();
+ }
+}
+
+TEST_F(FeatureConfigStorageValidatorTest, ShouldKeepIfAnyConfigMeetsEventAge) {
+ scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
+
+ UseConfigs(kNeverStored, kNeverStored);
+ VerifyNeverKeep();
+
+ const FeatureConfig* one_day_storage_configs[] = {
+ &kStoredInUsed1Day, &kStoredInTrigger1Day, &kStoredInEventConfigs1Day};
+ for (const FeatureConfig* config : one_day_storage_configs) {
+ UseConfigs(kNeverStored, *config);
+ VerifyKeep1Day();
+ }
+
+ const FeatureConfig* two_days_storage_configs[] = {
+ &kStoredInUsed2Days, &kStoredInTrigger2Days, &kStoredInEventConfigs2Days};
+ for (const FeatureConfig* config : two_days_storage_configs) {
+ UseConfigs(kNeverStored, *config);
+ VerifyKeep2Days();
+ }
+
+ const FeatureConfig* ten_days_storage_configs[] = {
+ &kStoredInUsed10Days, &kStoredInTrigger10Days,
+ &kStoredInEventConfigs10Days};
+ for (const FeatureConfig* config : ten_days_storage_configs) {
+ UseConfigs(kNeverStored, *config);
+ VerifyKeep10Days();
+ }
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_constants.cc b/chromium/components/feature_engagement_tracker/internal/feature_constants.cc
deleted file mode 100644
index 570ff1077d5..00000000000
--- a/chromium/components/feature_engagement_tracker/internal/feature_constants.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-/// Copyright 2017 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/feature_engagement_tracker/public/feature_constants.h"
-
-#include "base/feature_list.h"
-
-namespace feature_engagement_tracker {
-
-const base::Feature kIPHDemoMode{"IPH_DemoMode",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-const base::Feature kIPHDummyFeature{"IPH_DummyFeature",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc b/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc
index 24c499d8545..9d92884481c 100644
--- a/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc
+++ b/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc
@@ -4,25 +4,48 @@
#include "components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h"
+#include <memory>
+#include <utility>
+
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/metrics/user_metrics.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/feature_engagement_tracker/internal/availability_model_impl.h"
+#include "components/feature_engagement_tracker/internal/chrome_variations_configuration.h"
#include "components/feature_engagement_tracker/internal/editable_configuration.h"
-#include "components/feature_engagement_tracker/internal/feature_list.h"
+#include "components/feature_engagement_tracker/internal/feature_config_condition_validator.h"
+#include "components/feature_engagement_tracker/internal/feature_config_storage_validator.h"
#include "components/feature_engagement_tracker/internal/in_memory_store.h"
+#include "components/feature_engagement_tracker/internal/init_aware_model.h"
#include "components/feature_engagement_tracker/internal/model_impl.h"
-#include "components/feature_engagement_tracker/internal/never_condition_validator.h"
+#include "components/feature_engagement_tracker/internal/never_availability_model.h"
+#include "components/feature_engagement_tracker/internal/never_storage_validator.h"
#include "components/feature_engagement_tracker/internal/once_condition_validator.h"
-#include "components/feature_engagement_tracker/internal/single_invalid_configuration.h"
+#include "components/feature_engagement_tracker/internal/persistent_store.h"
+#include "components/feature_engagement_tracker/internal/proto/availability.pb.h"
+#include "components/feature_engagement_tracker/internal/stats.h"
+#include "components/feature_engagement_tracker/internal/system_time_provider.h"
#include "components/feature_engagement_tracker/public/feature_constants.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+#include "components/leveldb_proto/proto_database_impl.h"
namespace feature_engagement_tracker {
namespace {
+const char kEventDBStorageDir[] = "EventDB";
+const char kAvailabilityDBStorageDir[] = "AvailabilityDB";
// Creates a FeatureEngagementTrackerImpl that is usable for a demo mode.
std::unique_ptr<FeatureEngagementTracker>
CreateDemoModeFeatureEngagementTracker() {
+ // GetFieldTrialParamValueByFeature returns an empty string if the param is
+ // not set.
+ std::string chosen_feature_name = base::GetFieldTrialParamValueByFeature(
+ kIPHDemoMode, kIPHDemoModeFeatureChoiceParam);
+
std::unique_ptr<EditableConfiguration> configuration =
base::MakeUnique<EditableConfiguration>();
@@ -30,14 +53,27 @@ CreateDemoModeFeatureEngagementTracker() {
// OnceConditionValidator acknowledges that thet meet conditions once.
std::vector<const base::Feature*> features = GetAllFeatures();
for (auto* feature : features) {
+ // If a particular feature has been chosen to use with demo mode, only
+ // mark that feature with a valid configuration.
+ bool valid_config = chosen_feature_name.empty()
+ ? true
+ : chosen_feature_name == feature->name;
+
FeatureConfig feature_config;
- feature_config.valid = true;
+ feature_config.valid = valid_config;
+ feature_config.trigger.name = feature->name + std::string("_trigger");
configuration->SetConfiguration(feature, feature_config);
}
+ auto raw_model =
+ base::MakeUnique<ModelImpl>(base::MakeUnique<InMemoryStore>(),
+ base::MakeUnique<NeverStorageValidator>());
+
return base::MakeUnique<FeatureEngagementTrackerImpl>(
- base::MakeUnique<InMemoryStore>(), std::move(configuration),
- base::MakeUnique<OnceConditionValidator>());
+ base::MakeUnique<InitAwareModel>(std::move(raw_model)),
+ base::MakeUnique<NeverAvailabilityModel>(), std::move(configuration),
+ base::MakeUnique<OnceConditionValidator>(),
+ base::MakeUnique<SystemTimeProvider>());
}
} // namespace
@@ -48,61 +84,151 @@ CreateDemoModeFeatureEngagementTracker() {
// static
FeatureEngagementTracker* FeatureEngagementTracker::Create(
const base::FilePath& storage_dir,
- const scoped_refptr<base::SequencedTaskRunner>& background__task_runner) {
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner) {
if (base::FeatureList::IsEnabled(kIPHDemoMode))
return CreateDemoModeFeatureEngagementTracker().release();
- std::unique_ptr<Store> store = base::MakeUnique<InMemoryStore>();
- // TODO(nyquist): Create FinchConfiguration to parse configuration.
- std::unique_ptr<Configuration> configuration =
- base::MakeUnique<SingleInvalidConfiguration>();
- std::unique_ptr<ConditionValidator> validator =
- base::MakeUnique<NeverConditionValidator>();
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db =
+ base::MakeUnique<leveldb_proto::ProtoDatabaseImpl<Event>>(
+ background_task_runner);
+
+ base::FilePath event_storage_dir = storage_dir.Append(kEventDBStorageDir);
+ auto store =
+ base::MakeUnique<PersistentStore>(event_storage_dir, std::move(db));
+
+ auto configuration = base::MakeUnique<ChromeVariationsConfiguration>();
+ configuration->ParseFeatureConfigs(GetAllFeatures());
+
+ auto storage_validator = base::MakeUnique<FeatureConfigStorageValidator>();
+ storage_validator->InitializeFeatures(GetAllFeatures(), *configuration);
+
+ auto raw_model = base::MakeUnique<ModelImpl>(std::move(store),
+ std::move(storage_validator));
+
+ auto model = base::MakeUnique<InitAwareModel>(std::move(raw_model));
+ auto condition_validator =
+ base::MakeUnique<FeatureConfigConditionValidator>();
+ auto time_provider = base::MakeUnique<SystemTimeProvider>();
+
+ base::FilePath availability_storage_dir =
+ storage_dir.Append(kAvailabilityDBStorageDir);
+ auto availability_db =
+ base::MakeUnique<leveldb_proto::ProtoDatabaseImpl<Availability>>(
+ background_task_runner);
+ auto availability_store_loader = base::BindOnce(
+ &AvailabilityStore::LoadAndUpdateStore, availability_storage_dir,
+ std::move(availability_db), GetAllFeatures());
+
+ auto availability_model = base::MakeUnique<AvailabilityModelImpl>(
+ std::move(availability_store_loader));
return new FeatureEngagementTrackerImpl(
- std::move(store), std::move(configuration), std::move(validator));
+ std::move(model), std::move(availability_model), std::move(configuration),
+ std::move(condition_validator), std::move(time_provider));
}
FeatureEngagementTrackerImpl::FeatureEngagementTrackerImpl(
- std::unique_ptr<Store> store,
+ std::unique_ptr<Model> model,
+ std::unique_ptr<AvailabilityModel> availability_model,
std::unique_ptr<Configuration> configuration,
- std::unique_ptr<ConditionValidator> condition_validator)
- : condition_validator_(std::move(condition_validator)),
+ std::unique_ptr<ConditionValidator> condition_validator,
+ std::unique_ptr<TimeProvider> time_provider)
+ : model_(std::move(model)),
+ availability_model_(std::move(availability_model)),
+ configuration_(std::move(configuration)),
+ condition_validator_(std::move(condition_validator)),
+ time_provider_(std::move(time_provider)),
+ event_model_initialization_finished_(false),
+ availability_model_initialization_finished_(false),
weak_ptr_factory_(this) {
- model_ =
- base::MakeUnique<ModelImpl>(std::move(store), std::move(configuration));
model_->Initialize(
- base::Bind(&FeatureEngagementTrackerImpl::OnModelInitializationFinished,
- weak_ptr_factory_.GetWeakPtr()));
+ base::Bind(
+ &FeatureEngagementTrackerImpl::OnEventModelInitializationFinished,
+ weak_ptr_factory_.GetWeakPtr()),
+ time_provider_->GetCurrentDay());
+
+ availability_model_->Initialize(
+ base::Bind(&FeatureEngagementTrackerImpl::
+ OnAvailabilityModelInitializationFinished,
+ weak_ptr_factory_.GetWeakPtr()),
+ time_provider_->GetCurrentDay());
}
FeatureEngagementTrackerImpl::~FeatureEngagementTrackerImpl() = default;
void FeatureEngagementTrackerImpl::NotifyEvent(const std::string& event) {
- // TODO(nyquist): Track this event.
+ model_->IncrementEvent(event, time_provider_->GetCurrentDay());
+ stats::RecordNotifyEvent(event, configuration_.get(), model_->IsReady());
}
bool FeatureEngagementTrackerImpl::ShouldTriggerHelpUI(
const base::Feature& feature) {
- // TODO(nyquist): Track this event.
- bool result = condition_validator_->MeetsConditions(feature, *model_);
- if (result)
- model_->SetIsCurrentlyShowing(true);
- return result;
+ ConditionValidator::Result result = condition_validator_->MeetsConditions(
+ feature, configuration_->GetFeatureConfig(feature), *model_,
+ *availability_model_, time_provider_->GetCurrentDay());
+ if (result.NoErrors()) {
+ condition_validator_->NotifyIsShowing(feature);
+ FeatureConfig feature_config = configuration_->GetFeatureConfig(feature);
+ DCHECK_NE("", feature_config.trigger.name);
+ model_->IncrementEvent(feature_config.trigger.name,
+ time_provider_->GetCurrentDay());
+ }
+
+ stats::RecordShouldTriggerHelpUI(feature, result);
+ return result.NoErrors();
+}
+
+void FeatureEngagementTrackerImpl::Dismissed(const base::Feature& feature) {
+ condition_validator_->NotifyDismissed(feature);
+ stats::RecordUserDismiss();
}
-void FeatureEngagementTrackerImpl::Dismissed() {
- // TODO(nyquist): Track this event.
- model_->SetIsCurrentlyShowing(false);
+bool FeatureEngagementTrackerImpl::IsInitialized() {
+ return model_->IsReady() && availability_model_->IsReady();
}
void FeatureEngagementTrackerImpl::AddOnInitializedCallback(
OnInitializedCallback callback) {
- // TODO(nyquist): Add support for this.
+ if (IsInitializationFinished()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, IsInitialized()));
+ return;
+ }
+
+ on_initialized_callbacks_.push_back(callback);
+}
+
+void FeatureEngagementTrackerImpl::OnEventModelInitializationFinished(
+ bool success) {
+ DCHECK_EQ(success, model_->IsReady());
+ event_model_initialization_finished_ = true;
+
+ MaybePostInitializedCallbacks();
+}
+
+void FeatureEngagementTrackerImpl::OnAvailabilityModelInitializationFinished(
+ bool success) {
+ DCHECK_EQ(success, availability_model_->IsReady());
+ availability_model_initialization_finished_ = true;
+
+ MaybePostInitializedCallbacks();
+}
+
+bool FeatureEngagementTrackerImpl::IsInitializationFinished() const {
+ return event_model_initialization_finished_ &&
+ availability_model_initialization_finished_;
}
-void FeatureEngagementTrackerImpl::OnModelInitializationFinished(bool result) {
- // TODO(nyquist): Ensure that all OnInitializedCallbacks are invoked.
+void FeatureEngagementTrackerImpl::MaybePostInitializedCallbacks() {
+ if (!IsInitializationFinished())
+ return;
+
+ for (auto& callback : on_initialized_callbacks_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, IsInitialized()));
+ }
+
+ on_initialized_callbacks_.clear();
}
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h b/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h
index b008894138e..3b0abcee50a 100644
--- a/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h
+++ b/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h
@@ -12,40 +12,77 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
-#include "components/feature_engagement_tracker/internal/condition_validator.h"
-#include "components/feature_engagement_tracker/internal/model.h"
#include "components/feature_engagement_tracker/public/feature_engagement_tracker.h"
namespace feature_engagement_tracker {
-class Store;
+class AvailabilityModel;
+class Configuration;
+class ConditionValidator;
+class Model;
+class TimeProvider;
// The internal implementation of the FeatureEngagementTracker.
class FeatureEngagementTrackerImpl : public FeatureEngagementTracker,
public base::SupportsUserData {
public:
FeatureEngagementTrackerImpl(
- std::unique_ptr<Store> store,
+ std::unique_ptr<Model> store,
+ std::unique_ptr<AvailabilityModel> availability_model,
std::unique_ptr<Configuration> configuration,
- std::unique_ptr<ConditionValidator> condition_validator);
+ std::unique_ptr<ConditionValidator> condition_validator,
+ std::unique_ptr<TimeProvider> time_provider);
~FeatureEngagementTrackerImpl() override;
// FeatureEngagementTracker implementation.
void NotifyEvent(const std::string& event) override;
bool ShouldTriggerHelpUI(const base::Feature& feature) override;
- void Dismissed() override;
+ void Dismissed(const base::Feature& feature) override;
+ bool IsInitialized() override;
void AddOnInitializedCallback(OnInitializedCallback callback) override;
private:
// Invoked by the Model when it has been initialized.
- void OnModelInitializationFinished(bool result);
+ void OnEventModelInitializationFinished(bool success);
+
+ // Invoked by the AvailabilityModel when it has been initialized.
+ void OnAvailabilityModelInitializationFinished(bool success);
+
+ // Returns whether both underlying models have finished initializing.
+ // This returning true does not mean the initialization was a success, just
+ // that it is finished.
+ bool IsInitializationFinished() const;
+
+ // Posts the results to the OnInitializedCallbacks if
+ // IsInitializationFinished() returns true.
+ void MaybePostInitializedCallbacks();
// The current model.
std::unique_ptr<Model> model_;
+ // The current model for when particular features were enabled.
+ std::unique_ptr<AvailabilityModel> availability_model_;
+
+ // The current configuration for all features.
+ std::unique_ptr<Configuration> configuration_;
+
// The ConditionValidator provides functionality for knowing when to trigger
// help UI.
std::unique_ptr<ConditionValidator> condition_validator_;
+ // A utility for retriving time-related information.
+ std::unique_ptr<TimeProvider> time_provider_;
+
+ // Whether the initialization of the underlying event model has finished.
+ bool event_model_initialization_finished_;
+
+ // Whether the initialization of the underlying availability model has
+ // finished.
+ bool availability_model_initialization_finished_;
+
+ // The list of callbacks to invoke when initialization has finished. This
+ // is cleared after the initialization has happened.
+ std::vector<OnInitializedCallback> on_initialized_callbacks_;
+
base::WeakPtrFactory<FeatureEngagementTrackerImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(FeatureEngagementTrackerImpl);
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc b/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
index daa58c307fa..74f3454dbc6 100644
--- a/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
+++ b/chromium/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
@@ -6,15 +6,24 @@
#include <memory>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
-#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
-#include "base/test/scoped_feature_list.h"
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
+#include "base/test/user_action_tester.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/feature_engagement_tracker/internal/availability_model_impl.h"
#include "components/feature_engagement_tracker/internal/editable_configuration.h"
#include "components/feature_engagement_tracker/internal/in_memory_store.h"
+#include "components/feature_engagement_tracker/internal/model_impl.h"
+#include "components/feature_engagement_tracker/internal/never_availability_model.h"
+#include "components/feature_engagement_tracker/internal/never_storage_validator.h"
#include "components/feature_engagement_tracker/internal/once_condition_validator.h"
+#include "components/feature_engagement_tracker/internal/stats.h"
+#include "components/feature_engagement_tracker/internal/time_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace feature_engagement_tracker {
@@ -32,64 +41,512 @@ void RegisterFeatureConfig(EditableConfiguration* configuration,
bool valid) {
FeatureConfig config;
config.valid = valid;
- config.feature_used_event = feature.name;
+ config.used.name = feature.name + std::string("_used");
+ config.trigger.name = feature.name + std::string("_trigger");
configuration->SetConfiguration(&feature, config);
}
+// An OnInitializedCallback that stores whether it has been invoked and what
+// the result was.
+class StoringInitializedCallback {
+ public:
+ StoringInitializedCallback() : invoked_(false), success_(false) {}
+
+ void OnInitialized(bool success) {
+ DCHECK(!invoked_);
+ invoked_ = true;
+ success_ = success;
+ }
+
+ bool invoked() { return invoked_; }
+
+ bool success() { return success_; }
+
+ private:
+ bool invoked_;
+ bool success_;
+
+ DISALLOW_COPY_AND_ASSIGN(StoringInitializedCallback);
+};
+
+// An InMemoryStore that is able to fake successful and unsuccessful
+// loading of state.
+class TestInMemoryStore : public InMemoryStore {
+ public:
+ explicit TestInMemoryStore(bool load_should_succeed)
+ : InMemoryStore(), load_should_succeed_(load_should_succeed) {}
+
+ void Load(const OnLoadedCallback& callback) override {
+ HandleLoadResult(callback, load_should_succeed_);
+ }
+
+ void WriteEvent(const Event& event) override {
+ events_[event.name()] = event;
+ }
+
+ Event GetEvent(const std::string& event_name) { return events_[event_name]; }
+
+ private:
+ // Denotes whether the call to Load(...) should succeed or not. This impacts
+ // both the ready-state and the result for the OnLoadedCallback.
+ bool load_should_succeed_;
+
+ std::map<std::string, Event> events_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestInMemoryStore);
+};
+
+class StoreEverythingStorageValidator : public StorageValidator {
+ public:
+ StoreEverythingStorageValidator() = default;
+ ~StoreEverythingStorageValidator() override = default;
+
+ bool ShouldStore(const std::string& event_name) const override {
+ return true;
+ }
+
+ bool ShouldKeep(const std::string& event_name,
+ uint32_t event_day,
+ uint32_t current_day) const override {
+ return true;
+ };
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StoreEverythingStorageValidator);
+};
+
+class TestTimeProvider : public TimeProvider {
+ public:
+ TestTimeProvider() = default;
+ ~TestTimeProvider() override = default;
+
+ // TimeProvider implementation.
+ uint32_t GetCurrentDay() const override { return 1u; };
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestTimeProvider);
+};
+
+class TestAvailabilityModel : public AvailabilityModel {
+ public:
+ TestAvailabilityModel() : ready_(true) {}
+ ~TestAvailabilityModel() override = default;
+
+ void Initialize(AvailabilityModel::OnInitializedCallback callback,
+ uint32_t current_day) override {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), ready_));
+ }
+
+ bool IsReady() const override { return ready_; }
+
+ void SetIsReady(bool ready) { ready_ = ready; }
+
+ base::Optional<uint32_t> GetAvailability(
+ const base::Feature& feature) const override {
+ return base::nullopt;
+ }
+
+ private:
+ bool ready_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestAvailabilityModel);
+};
+
class FeatureEngagementTrackerImplTest : public ::testing::Test {
public:
- FeatureEngagementTrackerImplTest() {
- std::unique_ptr<Store> store = base::MakeUnique<InMemoryStore>();
+ FeatureEngagementTrackerImplTest() = default;
+
+ void SetUp() override {
std::unique_ptr<EditableConfiguration> configuration =
base::MakeUnique<EditableConfiguration>();
- std::unique_ptr<ConditionValidator> validator =
- base::MakeUnique<OnceConditionValidator>();
+ configuration_ = configuration.get();
RegisterFeatureConfig(configuration.get(), kTestFeatureFoo, true);
RegisterFeatureConfig(configuration.get(), kTestFeatureBar, true);
RegisterFeatureConfig(configuration.get(), kTestFeatureQux, false);
- scoped_feature_list_.InitWithFeatures(
- {kTestFeatureFoo, kTestFeatureBar, kTestFeatureQux}, {});
+ std::unique_ptr<TestInMemoryStore> store = CreateStore();
+ store_ = store.get();
+
+ auto model = base::MakeUnique<ModelImpl>(
+ std::move(store), base::MakeUnique<StoreEverythingStorageValidator>());
+
+ auto availability_model = base::MakeUnique<TestAvailabilityModel>();
+ availability_model_ = availability_model.get();
+ availability_model_->SetIsReady(ShouldAvailabilityStoreBeReady());
tracker_.reset(new FeatureEngagementTrackerImpl(
- std::move(store), std::move(configuration), std::move(validator)));
- // Ensure all initialization is finished.
- base::RunLoop().RunUntilIdle();
+ std::move(model), std::move(availability_model),
+ std::move(configuration), base::MakeUnique<OnceConditionValidator>(),
+ base::MakeUnique<TestTimeProvider>()));
+ }
+
+ void VerifyEventTriggerEvents(const base::Feature& feature, uint32_t count) {
+ Event trigger_event = store_->GetEvent(
+ configuration_->GetFeatureConfig(feature).trigger.name);
+ if (count == 0) {
+ EXPECT_EQ(0, trigger_event.events_size());
+ return;
+ }
+
+ EXPECT_EQ(1, trigger_event.events_size());
+ EXPECT_EQ(1u, trigger_event.events(0).day());
+ EXPECT_EQ(count, trigger_event.events(0).count());
+ }
+
+ void VerifyUserActionsTriggerChecks(
+ const base::UserActionTester& user_action_tester,
+ int expected_foo_count,
+ int expected_bar_count,
+ int expected_qux_count) {
+ EXPECT_EQ(expected_foo_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUI.test_foo"));
+ EXPECT_EQ(expected_bar_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUI.test_bar"));
+ EXPECT_EQ(expected_qux_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUI.test_qux"));
+ }
+
+ void VerifyUserActionsTriggered(
+ const base::UserActionTester& user_action_tester,
+ int expected_foo_count,
+ int expected_bar_count,
+ int expected_qux_count) {
+ EXPECT_EQ(
+ expected_foo_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUIResult.Triggered.test_foo"));
+ EXPECT_EQ(
+ expected_bar_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUIResult.Triggered.test_bar"));
+ EXPECT_EQ(
+ expected_qux_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUIResult.Triggered.test_qux"));
+ }
+
+ void VerifyUserActionsNotTriggered(
+ const base::UserActionTester& user_action_tester,
+ int expected_foo_count,
+ int expected_bar_count,
+ int expected_qux_count) {
+ EXPECT_EQ(
+ expected_foo_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.test_foo"));
+ EXPECT_EQ(
+ expected_bar_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.test_bar"));
+ EXPECT_EQ(
+ expected_qux_count,
+ user_action_tester.GetActionCount(
+ "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.test_qux"));
+ }
+
+ void VerifyUserActionsDismissed(
+ const base::UserActionTester& user_action_tester,
+ int expected_dismissed_count) {
+ EXPECT_EQ(expected_dismissed_count,
+ user_action_tester.GetActionCount("InProductHelp.Dismissed"));
}
protected:
+ virtual std::unique_ptr<TestInMemoryStore> CreateStore() {
+ // Returns a Store that will successfully initialize.
+ return base::MakeUnique<TestInMemoryStore>(true);
+ }
+
+ virtual bool ShouldAvailabilityStoreBeReady() { return true; }
+
base::MessageLoop message_loop_;
std::unique_ptr<FeatureEngagementTrackerImpl> tracker_;
- base::test::ScopedFeatureList scoped_feature_list_;
+ TestInMemoryStore* store_;
+ TestAvailabilityModel* availability_model_;
+ Configuration* configuration_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FeatureEngagementTrackerImplTest);
+};
+
+// A top-level test class where the store fails to initialize.
+class FailingStoreInitFeatureEngagementTrackerImplTest
+ : public FeatureEngagementTrackerImplTest {
+ public:
+ FailingStoreInitFeatureEngagementTrackerImplTest() = default;
+
+ protected:
+ std::unique_ptr<TestInMemoryStore> CreateStore() override {
+ // Returns a Store that will fail to initialize.
+ return base::MakeUnique<TestInMemoryStore>(false);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FailingStoreInitFeatureEngagementTrackerImplTest);
+};
+
+// A top-level test class where the AvailabilityModel fails to initialize.
+class FailingAvailabilityModelInitFeatureEngagementTrackerImplTest
+ : public FeatureEngagementTrackerImplTest {
+ public:
+ FailingAvailabilityModelInitFeatureEngagementTrackerImplTest() = default;
+
+ protected:
+ bool ShouldAvailabilityStoreBeReady() override { return false; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(
+ FailingAvailabilityModelInitFeatureEngagementTrackerImplTest);
};
} // namespace
+TEST_F(FeatureEngagementTrackerImplTest, TestInitialization) {
+ EXPECT_FALSE(tracker_->IsInitialized());
+
+ StoringInitializedCallback callback;
+ tracker_->AddOnInitializedCallback(base::Bind(
+ &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
+ EXPECT_FALSE(callback.invoked());
+
+ // Ensure all initialization is finished.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(tracker_->IsInitialized());
+ EXPECT_TRUE(callback.invoked());
+ EXPECT_TRUE(callback.success());
+}
+
+TEST_F(FeatureEngagementTrackerImplTest, TestInitializationMultipleCallbacks) {
+ EXPECT_FALSE(tracker_->IsInitialized());
+
+ StoringInitializedCallback callback1;
+ StoringInitializedCallback callback2;
+
+ tracker_->AddOnInitializedCallback(
+ base::Bind(&StoringInitializedCallback::OnInitialized,
+ base::Unretained(&callback1)));
+ tracker_->AddOnInitializedCallback(
+ base::Bind(&StoringInitializedCallback::OnInitialized,
+ base::Unretained(&callback2)));
+ EXPECT_FALSE(callback1.invoked());
+ EXPECT_FALSE(callback2.invoked());
+
+ // Ensure all initialization is finished.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(tracker_->IsInitialized());
+ EXPECT_TRUE(callback1.invoked());
+ EXPECT_TRUE(callback2.invoked());
+ EXPECT_TRUE(callback1.success());
+ EXPECT_TRUE(callback2.success());
+}
+
+TEST_F(FeatureEngagementTrackerImplTest, TestAddingCallbackAfterInitFinished) {
+ EXPECT_FALSE(tracker_->IsInitialized());
+
+ // Ensure all initialization is finished.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(tracker_->IsInitialized());
+
+ StoringInitializedCallback callback;
+ tracker_->AddOnInitializedCallback(base::Bind(
+ &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
+ EXPECT_FALSE(callback.invoked());
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(callback.invoked());
+}
+
+TEST_F(FeatureEngagementTrackerImplTest,
+ TestAddingCallbackBeforeAndAfterInitFinished) {
+ EXPECT_FALSE(tracker_->IsInitialized());
+
+ // Ensure all initialization is finished.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(tracker_->IsInitialized());
+
+ StoringInitializedCallback callback_before;
+ tracker_->AddOnInitializedCallback(
+ base::Bind(&StoringInitializedCallback::OnInitialized,
+ base::Unretained(&callback_before)));
+ EXPECT_FALSE(callback_before.invoked());
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(callback_before.invoked());
+
+ StoringInitializedCallback callback_after;
+ tracker_->AddOnInitializedCallback(
+ base::Bind(&StoringInitializedCallback::OnInitialized,
+ base::Unretained(&callback_after)));
+ EXPECT_FALSE(callback_after.invoked());
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(callback_after.invoked());
+}
+
+TEST_F(FailingStoreInitFeatureEngagementTrackerImplTest,
+ TestFailingInitialization) {
+ EXPECT_FALSE(tracker_->IsInitialized());
+
+ StoringInitializedCallback callback;
+ tracker_->AddOnInitializedCallback(base::Bind(
+ &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
+ EXPECT_FALSE(callback.invoked());
+
+ // Ensure all initialization is finished.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(tracker_->IsInitialized());
+ EXPECT_TRUE(callback.invoked());
+ EXPECT_FALSE(callback.success());
+}
+
+TEST_F(FailingStoreInitFeatureEngagementTrackerImplTest,
+ TestFailingInitializationMultipleCallbacks) {
+ EXPECT_FALSE(tracker_->IsInitialized());
+
+ StoringInitializedCallback callback1;
+ StoringInitializedCallback callback2;
+ tracker_->AddOnInitializedCallback(
+ base::Bind(&StoringInitializedCallback::OnInitialized,
+ base::Unretained(&callback1)));
+ tracker_->AddOnInitializedCallback(
+ base::Bind(&StoringInitializedCallback::OnInitialized,
+ base::Unretained(&callback2)));
+ EXPECT_FALSE(callback1.invoked());
+ EXPECT_FALSE(callback2.invoked());
+
+ // Ensure all initialization is finished.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(tracker_->IsInitialized());
+ EXPECT_TRUE(callback1.invoked());
+ EXPECT_TRUE(callback2.invoked());
+ EXPECT_FALSE(callback1.success());
+ EXPECT_FALSE(callback2.success());
+}
+
+TEST_F(FailingAvailabilityModelInitFeatureEngagementTrackerImplTest,
+ AvailabilityModelNotReady) {
+ EXPECT_FALSE(tracker_->IsInitialized());
+
+ StoringInitializedCallback callback;
+ tracker_->AddOnInitializedCallback(base::Bind(
+ &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
+ EXPECT_FALSE(callback.invoked());
+
+ // Ensure all initialization is finished.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(tracker_->IsInitialized());
+ EXPECT_TRUE(callback.invoked());
+ EXPECT_FALSE(callback.success());
+}
+
TEST_F(FeatureEngagementTrackerImplTest, TestTriggering) {
+ // Ensure all initialization is finished.
+ StoringInitializedCallback callback;
+ tracker_->AddOnInitializedCallback(base::Bind(
+ &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
+ base::RunLoop().RunUntilIdle();
+ base::UserActionTester user_action_tester;
+
// The first time a feature triggers it should be shown.
EXPECT_TRUE(tracker_->ShouldTriggerHelpUI(kTestFeatureFoo));
+ VerifyEventTriggerEvents(kTestFeatureFoo, 1u);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureFoo));
+ VerifyEventTriggerEvents(kTestFeatureFoo, 1u);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux));
+ VerifyEventTriggerEvents(kTestFeatureQux, 0);
+ VerifyUserActionsTriggerChecks(user_action_tester, 2, 0, 1);
+ VerifyUserActionsTriggered(user_action_tester, 1, 0, 0);
+ VerifyUserActionsNotTriggered(user_action_tester, 1, 0, 1);
+ VerifyUserActionsDismissed(user_action_tester, 0);
// While in-product help is currently showing, no other features should be
// shown.
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureBar));
+ VerifyEventTriggerEvents(kTestFeatureBar, 0);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux));
+ VerifyEventTriggerEvents(kTestFeatureQux, 0);
+ VerifyUserActionsTriggerChecks(user_action_tester, 2, 1, 2);
+ VerifyUserActionsTriggered(user_action_tester, 1, 0, 0);
+ VerifyUserActionsNotTriggered(user_action_tester, 1, 1, 2);
+ VerifyUserActionsDismissed(user_action_tester, 0);
// After dismissing the current in-product help, that feature can not be shown
// again, but a different feature should.
- tracker_->Dismissed();
+ tracker_->Dismissed(kTestFeatureFoo);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureFoo));
+ VerifyEventTriggerEvents(kTestFeatureFoo, 1u);
EXPECT_TRUE(tracker_->ShouldTriggerHelpUI(kTestFeatureBar));
+ VerifyEventTriggerEvents(kTestFeatureBar, 1u);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux));
+ VerifyEventTriggerEvents(kTestFeatureQux, 0);
+ VerifyUserActionsTriggerChecks(user_action_tester, 3, 2, 3);
+ VerifyUserActionsTriggered(user_action_tester, 1, 1, 0);
+ VerifyUserActionsNotTriggered(user_action_tester, 2, 1, 3);
+ VerifyUserActionsDismissed(user_action_tester, 1);
// After dismissing the second registered feature, no more in-product help
// should be shown, since kTestFeatureQux is invalid.
- tracker_->Dismissed();
+ tracker_->Dismissed(kTestFeatureBar);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureFoo));
+ VerifyEventTriggerEvents(kTestFeatureFoo, 1u);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureBar));
+ VerifyEventTriggerEvents(kTestFeatureBar, 1u);
EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux));
+ VerifyEventTriggerEvents(kTestFeatureQux, 0);
+ VerifyUserActionsTriggerChecks(user_action_tester, 4, 3, 4);
+ VerifyUserActionsTriggered(user_action_tester, 1, 1, 0);
+ VerifyUserActionsNotTriggered(user_action_tester, 3, 2, 4);
+ VerifyUserActionsDismissed(user_action_tester, 2);
+}
+
+TEST_F(FeatureEngagementTrackerImplTest, TestNotifyEvent) {
+ StoringInitializedCallback callback;
+ tracker_->AddOnInitializedCallback(base::Bind(
+ &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
+ base::RunLoop().RunUntilIdle();
+ base::UserActionTester user_action_tester;
+
+ tracker_->NotifyEvent("foo");
+ tracker_->NotifyEvent("foo");
+ tracker_->NotifyEvent("bar");
+ tracker_->NotifyEvent(kTestFeatureFoo.name + std::string("_used"));
+ tracker_->NotifyEvent(kTestFeatureFoo.name + std::string("_trigger"));
+
+ // Used event will record both NotifyEvent and NotifyUsedEvent. Explicitly
+ // specify the whole user action string here.
+ EXPECT_EQ(1, user_action_tester.GetActionCount(
+ "InProductHelp.NotifyUsedEvent.test_foo"));
+ EXPECT_EQ(2, user_action_tester.GetActionCount(
+ "InProductHelp.NotifyEvent.test_foo"));
+ EXPECT_EQ(0, user_action_tester.GetActionCount(
+ "InProductHelp.NotifyUsedEvent.test_bar"));
+ EXPECT_EQ(0, user_action_tester.GetActionCount(
+ "InProductHelp.NotifyEvent.test_bar"));
+
+ Event foo_event = store_->GetEvent("foo");
+ ASSERT_EQ(1, foo_event.events_size());
+ EXPECT_EQ(1u, foo_event.events(0).day());
+ EXPECT_EQ(2u, foo_event.events(0).count());
+
+ Event bar_event = store_->GetEvent("bar");
+ ASSERT_EQ(1, bar_event.events_size());
+ EXPECT_EQ(1u, bar_event.events(0).day());
+ EXPECT_EQ(1u, bar_event.events(0).count());
}
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_list.cc b/chromium/components/feature_engagement_tracker/internal/feature_list.cc
deleted file mode 100644
index ebdef0a0cf3..00000000000
--- a/chromium/components/feature_engagement_tracker/internal/feature_list.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-/// Copyright 2017 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/feature_engagement_tracker/internal/feature_list.h"
-
-#include "base/feature_list.h"
-#include "components/feature_engagement_tracker/public/feature_constants.h"
-
-namespace feature_engagement_tracker {
-
-namespace {
-
-const base::Feature* kAllFeatures[] = {&kIPHDummyFeature};
-
-} // namespace
-
-std::vector<const base::Feature*> GetAllFeatures() {
- return std::vector<const base::Feature*>(
- kAllFeatures, kAllFeatures + arraysize(kAllFeatures));
-}
-
-} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/feature_list.h b/chromium/components/feature_engagement_tracker/internal/feature_list.h
deleted file mode 100644
index ba4a5786239..00000000000
--- a/chromium/components/feature_engagement_tracker/internal/feature_list.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_LIST_H_
-#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_LIST_H_
-
-#include <vector>
-
-#include "base/feature_list.h"
-
-namespace feature_engagement_tracker {
-using FeatureVector = std::vector<const base::Feature*>;
-
-// Returns all the features that are in use for engagement tracking.
-FeatureVector GetAllFeatures();
-
-} // namespace feature_engagement_tracker
-
-#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_LIST_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/in_memory_store.cc b/chromium/components/feature_engagement_tracker/internal/in_memory_store.cc
index 0c9fa6e4c5b..2e78551d117 100644
--- a/chromium/components/feature_engagement_tracker/internal/in_memory_store.cc
+++ b/chromium/components/feature_engagement_tracker/internal/in_memory_store.cc
@@ -36,6 +36,10 @@ void InMemoryStore::WriteEvent(const Event& event) {
// Intentionally ignore all writes.
}
+void InMemoryStore::DeleteEvent(const std::string& event_name) {
+ // Intentionally ignore all deletes.
+}
+
void InMemoryStore::HandleLoadResult(const OnLoadedCallback& callback,
bool success) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chromium/components/feature_engagement_tracker/internal/in_memory_store.h b/chromium/components/feature_engagement_tracker/internal/in_memory_store.h
index 939037c64b8..45652d63a0a 100644
--- a/chromium/components/feature_engagement_tracker/internal/in_memory_store.h
+++ b/chromium/components/feature_engagement_tracker/internal/in_memory_store.h
@@ -24,6 +24,7 @@ class InMemoryStore : public Store {
void Load(const OnLoadedCallback& callback) override;
bool IsReady() const override;
void WriteEvent(const Event& event) override;
+ void DeleteEvent(const std::string& event_name) override;
protected:
// Posts the result of loading and sets up the ready state.
diff --git a/chromium/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc b/chromium/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc
index be3f0ad2910..593f866113d 100644
--- a/chromium/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc
+++ b/chromium/components/feature_engagement_tracker/internal/in_memory_store_unittest.cc
@@ -5,6 +5,7 @@
#include "components/feature_engagement_tracker/internal/in_memory_store.h"
#include <memory>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -26,7 +27,7 @@ class InMemoryStoreTest : public ::testing::Test {
void LoadCallback(bool success, std::unique_ptr<std::vector<Event>> events) {
load_callback_has_been_invoked_ = true;
last_result_ = success;
- loaded_events_.reset(events.release());
+ loaded_events_ = std::move(events);
}
protected:
diff --git a/chromium/components/feature_engagement_tracker/internal/init_aware_model.cc b/chromium/components/feature_engagement_tracker/internal/init_aware_model.cc
new file mode 100644
index 00000000000..c514a705f05
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/init_aware_model.cc
@@ -0,0 +1,65 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/init_aware_model.h"
+
+#include "base/bind.h"
+
+namespace feature_engagement_tracker {
+
+InitAwareModel::InitAwareModel(std::unique_ptr<Model> model)
+ : model_(std::move(model)),
+ initialization_complete_(false),
+ weak_ptr_factory_(this) {
+ DCHECK(model_);
+}
+
+InitAwareModel::~InitAwareModel() = default;
+
+void InitAwareModel::Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) {
+ model_->Initialize(base::Bind(&InitAwareModel::OnInitializeComplete,
+ weak_ptr_factory_.GetWeakPtr(), callback),
+ current_day);
+}
+
+bool InitAwareModel::IsReady() const {
+ return model_->IsReady();
+}
+
+const Event* InitAwareModel::GetEvent(const std::string& event_name) const {
+ return model_->GetEvent(event_name);
+}
+
+void InitAwareModel::IncrementEvent(const std::string& event_name,
+ uint32_t current_day) {
+ if (IsReady()) {
+ model_->IncrementEvent(event_name, current_day);
+ return;
+ }
+
+ if (initialization_complete_)
+ return;
+
+ queued_events_.push_back(std::tie(event_name, current_day));
+}
+
+void InitAwareModel::OnInitializeComplete(
+ const OnModelInitializationFinished& callback,
+ bool success) {
+ initialization_complete_ = true;
+ if (success) {
+ for (auto& event : queued_events_)
+ model_->IncrementEvent(std::get<0>(event), std::get<1>(event));
+ }
+ queued_events_.clear();
+
+ callback.Run(success);
+}
+
+size_t InitAwareModel::GetQueuedEventCountForTesting() {
+ return queued_events_.size();
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/init_aware_model.h b/chromium/components/feature_engagement_tracker/internal/init_aware_model.h
new file mode 100644
index 00000000000..89b0e4513fc
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/init_aware_model.h
@@ -0,0 +1,54 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_INIT_AWARE_MODEL_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_INIT_AWARE_MODEL_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "components/feature_engagement_tracker/internal/model.h"
+
+namespace feature_engagement_tracker {
+
+class InitAwareModel : public Model {
+ public:
+ InitAwareModel(std::unique_ptr<Model> model);
+ ~InitAwareModel() override;
+
+ // Model implementation.
+ void Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) override;
+ bool IsReady() const override;
+ const Event* GetEvent(const std::string& event_name) const override;
+ void IncrementEvent(const std::string& event_name,
+ uint32_t current_day) override;
+
+ size_t GetQueuedEventCountForTesting();
+
+ private:
+ void OnInitializeComplete(const OnModelInitializationFinished& callback,
+ bool success);
+
+ std::unique_ptr<Model> model_;
+ std::vector<std::tuple<std::string, uint32_t>> queued_events_;
+
+ // Whether the initialization has completed. This will be set to true once
+ // the underlying model has been initialized, regardless of whether the
+ // result was a success or not.
+ bool initialization_complete_;
+
+ base::WeakPtrFactory<InitAwareModel> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(InitAwareModel);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_INIT_AWARE_MODEL_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/init_aware_model_unittest.cc b/chromium/components/feature_engagement_tracker/internal/init_aware_model_unittest.cc
new file mode 100644
index 00000000000..00f38943f14
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/init_aware_model_unittest.cc
@@ -0,0 +1,170 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/init_aware_model.h"
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/optional.h"
+#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+#include "components/feature_engagement_tracker/internal/test/event_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Return;
+using testing::SaveArg;
+using testing::Sequence;
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+class MockModel : public Model {
+ public:
+ MockModel() = default;
+ ~MockModel() override = default;
+
+ // Model implementation.
+ MOCK_METHOD2(Initialize,
+ void(const OnModelInitializationFinished&, uint32_t));
+ MOCK_CONST_METHOD0(IsReady, bool());
+ MOCK_CONST_METHOD1(GetEvent, Event*(const std::string&));
+ MOCK_METHOD2(IncrementEvent, void(const std::string&, uint32_t));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockModel);
+};
+
+class InitAwareModelTest : public testing::Test {
+ public:
+ InitAwareModelTest() : mocked_model_(nullptr) {
+ load_callback_ = base::Bind(&InitAwareModelTest::OnModelInitialized,
+ base::Unretained(this));
+ }
+
+ ~InitAwareModelTest() override = default;
+
+ void SetUp() override {
+ auto mocked_model = base::MakeUnique<MockModel>();
+ mocked_model_ = mocked_model.get();
+ model_ = base::MakeUnique<InitAwareModel>(std::move(mocked_model));
+ }
+
+ protected:
+ void OnModelInitialized(bool success) { load_success_ = success; }
+
+ std::unique_ptr<InitAwareModel> model_;
+ MockModel* mocked_model_;
+
+ // Load callback tracking.
+ base::Optional<bool> load_success_;
+ Model::OnModelInitializationFinished load_callback_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InitAwareModelTest);
+};
+
+} // namespace
+
+TEST_F(InitAwareModelTest, PassThroughIsReady) {
+ EXPECT_CALL(*mocked_model_, IsReady()).Times(1);
+ model_->IsReady();
+}
+
+TEST_F(InitAwareModelTest, PassThroughGetEvent) {
+ Event foo;
+ foo.set_name("foo");
+ test::SetEventCountForDay(&foo, 1, 1);
+
+ EXPECT_CALL(*mocked_model_, GetEvent(foo.name()))
+ .WillRepeatedly(Return(&foo));
+ EXPECT_CALL(*mocked_model_, GetEvent("bar")).WillRepeatedly(Return(nullptr));
+
+ test::VerifyEventsEqual(&foo, model_->GetEvent(foo.name()));
+ EXPECT_EQ(nullptr, model_->GetEvent("bar"));
+}
+
+TEST_F(InitAwareModelTest, PassThroughIncrementEvent) {
+ EXPECT_CALL(*mocked_model_, IsReady()).WillRepeatedly(Return(true));
+
+ Sequence sequence;
+ EXPECT_CALL(*mocked_model_, IncrementEvent("foo", 0U)).InSequence(sequence);
+ EXPECT_CALL(*mocked_model_, IncrementEvent("bar", 1U)).InSequence(sequence);
+
+ model_->IncrementEvent("foo", 0U);
+ model_->IncrementEvent("bar", 1U);
+ EXPECT_EQ(0U, model_->GetQueuedEventCountForTesting());
+}
+
+TEST_F(InitAwareModelTest, QueuedIncrementEvent) {
+ {
+ EXPECT_CALL(*mocked_model_, IsReady()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mocked_model_, IncrementEvent(_, _)).Times(0);
+
+ model_->IncrementEvent("foo", 0U);
+ model_->IncrementEvent("bar", 1U);
+ }
+
+ Model::OnModelInitializationFinished callback;
+ EXPECT_CALL(*mocked_model_, Initialize(_, 2U))
+ .WillOnce(SaveArg<0>(&callback));
+ model_->Initialize(load_callback_, 2U);
+
+ {
+ Sequence sequence;
+ EXPECT_CALL(*mocked_model_, IncrementEvent("foo", 0U))
+ .Times(1)
+ .InSequence(sequence);
+ EXPECT_CALL(*mocked_model_, IncrementEvent("bar", 1U))
+ .Times(1)
+ .InSequence(sequence);
+
+ callback.Run(true);
+ EXPECT_TRUE(load_success_.value());
+ }
+
+ EXPECT_CALL(*mocked_model_, IsReady()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mocked_model_, IncrementEvent("qux", 3U)).Times(1);
+ model_->IncrementEvent("qux", 3U);
+ EXPECT_EQ(0U, model_->GetQueuedEventCountForTesting());
+}
+
+TEST_F(InitAwareModelTest, QueuedIncrementEventWithUnsuccessfulInit) {
+ {
+ EXPECT_CALL(*mocked_model_, IsReady()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mocked_model_, IncrementEvent(_, _)).Times(0);
+
+ model_->IncrementEvent("foo", 0U);
+ model_->IncrementEvent("bar", 1U);
+ }
+
+ Model::OnModelInitializationFinished callback;
+ EXPECT_CALL(*mocked_model_, Initialize(_, 2U))
+ .WillOnce(SaveArg<0>(&callback));
+ model_->Initialize(load_callback_, 2U);
+
+ {
+ Sequence sequence;
+ EXPECT_CALL(*mocked_model_, IncrementEvent("foo", 0U))
+ .Times(0)
+ .InSequence(sequence);
+ EXPECT_CALL(*mocked_model_, IncrementEvent("bar", 1U))
+ .Times(0)
+ .InSequence(sequence);
+
+ callback.Run(false);
+ EXPECT_FALSE(load_success_.value());
+ EXPECT_EQ(0U, model_->GetQueuedEventCountForTesting());
+ }
+
+ EXPECT_CALL(*mocked_model_, IncrementEvent("qux", 3U)).Times(0);
+ model_->IncrementEvent("qux", 3U);
+ EXPECT_EQ(0U, model_->GetQueuedEventCountForTesting());
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/model.h b/chromium/components/feature_engagement_tracker/internal/model.h
index 3011066367e..f122b9a976e 100644
--- a/chromium/components/feature_engagement_tracker/internal/model.h
+++ b/chromium/components/feature_engagement_tracker/internal/model.h
@@ -10,50 +10,40 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "components/feature_engagement_tracker/internal/configuration.h"
-
-namespace base {
-struct Feature;
-} // namespace base
namespace feature_engagement_tracker {
class Event;
// A Model provides all necessary runtime state.
+// TODO(nyquist): Rename to EventModel.
class Model {
public:
- // Callback for when model initialization has finished. The bool argument
- // denotes whether the model was successfully initialized.
- using OnModelInitializationFinished = base::Callback<void(bool)>;
+ // Callback for when model initialization has finished. The |success|
+ // argument denotes whether the model was successfully initialized.
+ using OnModelInitializationFinished = base::Callback<void(bool success)>;
virtual ~Model() = default;
// Initialize the model, including all underlying sub systems. When all
// required operations have been finished, a callback is posted.
- virtual void Initialize(const OnModelInitializationFinished& callback) = 0;
+ virtual void Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) = 0;
- // Returns whether the model is ready, i.e. whether it has been fully
+ // Returns whether the model is ready, i.e. whether it has been successfully
// initialized.
virtual bool IsReady() const = 0;
- // Returns the FeatureConfig for the given |feature|.
- virtual const FeatureConfig& GetFeatureConfig(
- const base::Feature& feature) const = 0;
-
- // Update the state of whether any in-product help is currently showing.
- virtual void SetIsCurrentlyShowing(bool is_showing) = 0;
-
- // Returns whether any in-product help is currently showing.
- virtual bool IsCurrentlyShowing() const = 0;
-
// Retrieves the Event object for the event with the given name. If the event
- // is not found, an empty event will be returned. Calling this before the
+ // is not found, a nullptr will be returned. Calling this before the
// Model has finished initializing will result in undefined behavior.
- virtual const Event& GetEvent(const std::string& event_name) = 0;
+ virtual const Event* GetEvent(const std::string& event_name) const = 0;
// Increments the counter for today for how many times the event has happened.
// If the event has never happened before, the Event object will be created.
- virtual void IncrementEvent(const std::string& event_name) = 0;
+ // The |current_day| should be the number of days since UNIX epoch (see
+ // TimeProvider::GetCurrentDay()).
+ virtual void IncrementEvent(const std::string& event_name,
+ uint32_t current_day) = 0;
protected:
Model() = default;
diff --git a/chromium/components/feature_engagement_tracker/internal/model_impl.cc b/chromium/components/feature_engagement_tracker/internal/model_impl.cc
index 26d6e21fc3d..d1032f52a0c 100644
--- a/chromium/components/feature_engagement_tracker/internal/model_impl.cc
+++ b/chromium/components/feature_engagement_tracker/internal/model_impl.cc
@@ -14,55 +14,48 @@
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "components/feature_engagement_tracker/internal/configuration.h"
#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/internal/storage_validator.h"
#include "components/feature_engagement_tracker/internal/store.h"
namespace feature_engagement_tracker {
ModelImpl::ModelImpl(std::unique_ptr<Store> store,
- std::unique_ptr<Configuration> configuration)
+ std::unique_ptr<StorageValidator> storage_validator)
: Model(),
store_(std::move(store)),
- configuration_(std::move(configuration)),
+ storage_validator_(std::move(storage_validator)),
ready_(false),
- currently_showing_(false),
weak_factory_(this) {}
ModelImpl::~ModelImpl() = default;
-void ModelImpl::Initialize(const OnModelInitializationFinished& callback) {
+void ModelImpl::Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) {
store_->Load(base::Bind(&ModelImpl::OnStoreLoaded, weak_factory_.GetWeakPtr(),
- callback));
+ callback, current_day));
}
bool ModelImpl::IsReady() const {
return ready_;
}
-const FeatureConfig& ModelImpl::GetFeatureConfig(
- const base::Feature& feature) const {
- return configuration_->GetFeatureConfig(feature);
-}
-
-void ModelImpl::SetIsCurrentlyShowing(bool is_showing) {
- currently_showing_ = is_showing;
-}
-
-bool ModelImpl::IsCurrentlyShowing() const {
- return currently_showing_;
-}
+const Event* ModelImpl::GetEvent(const std::string& event_name) const {
+ auto search = events_.find(event_name);
+ if (search == events_.end())
+ return nullptr;
-const Event& ModelImpl::GetEvent(const std::string& event_name) {
- return GetNonConstEvent(event_name);
+ return &search->second;
}
-void ModelImpl::IncrementEvent(const std::string& event_name) {
- // TODO(nyquist): Add support for pending events, and also add UMA.
+void ModelImpl::IncrementEvent(const std::string& event_name,
+ uint32_t current_day) {
DCHECK(ready_);
+ if (!storage_validator_->ShouldStore(event_name))
+ return;
+
Event& event = GetNonConstEvent(event_name);
- uint32_t current_day = GetCurrentDay();
for (int i = 0; i < event.events_size(); ++i) {
Event_Count* event_count = event.mutable_events(i);
DCHECK(event_count->has_day());
@@ -81,31 +74,46 @@ void ModelImpl::IncrementEvent(const std::string& event_name) {
store_->WriteEvent(event);
}
-uint32_t ModelImpl::GetCurrentDay() {
- // TODO(nyquist): Implement this according to specification.
- return 1u;
-}
-
void ModelImpl::OnStoreLoaded(const OnModelInitializationFinished& callback,
+ uint32_t current_day,
bool success,
std::unique_ptr<std::vector<Event>> events) {
if (!success) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback, false));
+ callback.Run(false);
return;
}
for (auto& event : *events) {
DCHECK_NE("", event.name());
- events_[event.name()] = event;
- }
- // TODO(nyquist): Clear expired data.
+ Event new_event;
+ for (const auto& event_count : event.events()) {
+ if (!storage_validator_->ShouldKeep(event.name(), event_count.day(),
+ current_day)) {
+ continue;
+ }
- ready_ = true;
+ Event_Count* new_event_count = new_event.add_events();
+ new_event_count->set_day(event_count.day());
+ new_event_count->set_count(event_count.count());
+ }
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback, true));
+ // Only keep Event object that have days with activity.
+ if (new_event.events_size() > 0) {
+ new_event.set_name(event.name());
+ events_[event.name()] = new_event;
+
+ // If the number of events is not the same, overwrite DB entry.
+ if (new_event.events_size() != event.events_size())
+ store_->WriteEvent(new_event);
+ } else {
+ // If there are no more activity for an Event, delete the whole event.
+ store_->DeleteEvent(event.name());
+ }
+ }
+
+ ready_ = true;
+ callback.Run(true);
}
Event& ModelImpl::GetNonConstEvent(const std::string& event_name) {
diff --git a/chromium/components/feature_engagement_tracker/internal/model_impl.h b/chromium/components/feature_engagement_tracker/internal/model_impl.h
index ff456e13ee0..adef3e04302 100644
--- a/chromium/components/feature_engagement_tracker/internal/model_impl.h
+++ b/chromium/components/feature_engagement_tracker/internal/model_impl.h
@@ -12,42 +12,32 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "components/feature_engagement_tracker/internal/configuration.h"
#include "components/feature_engagement_tracker/internal/model.h"
#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
-namespace base {
-struct Feature;
-}
-
namespace feature_engagement_tracker {
+class StorageValidator;
class Store;
// A ModelImpl provides the default implementation of the Model.
class ModelImpl : public Model {
public:
ModelImpl(std::unique_ptr<Store> store,
- std::unique_ptr<Configuration> configuration);
+ std::unique_ptr<StorageValidator> storage_validator);
~ModelImpl() override;
// Model implementation.
- void Initialize(const OnModelInitializationFinished& callback) override;
+ void Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) override;
bool IsReady() const override;
- const FeatureConfig& GetFeatureConfig(
- const base::Feature& feature) const override;
- void SetIsCurrentlyShowing(bool is_showing) override;
- bool IsCurrentlyShowing() const override;
- const Event& GetEvent(const std::string& event_name) override;
- void IncrementEvent(const std::string& event_name) override;
-
- protected:
- // Returns the number of days since epoch (1970-01-01) in the local timezone.
- // Protected and virtual for testing.
- virtual uint32_t GetCurrentDay();
+ const Event* GetEvent(const std::string& event_name) const override;
+ void IncrementEvent(const std::string& event_name,
+ uint32_t current_day) override;
private:
// Callback for loading the underlying store.
void OnStoreLoaded(const OnModelInitializationFinished& callback,
+ uint32_t current_day,
bool success,
std::unique_ptr<std::vector<Event>> events);
@@ -58,8 +48,9 @@ class ModelImpl : public Model {
// The underlying store for all events.
std::unique_ptr<Store> store_;
- // The current configuration for all features.
- std::unique_ptr<Configuration> configuration_;
+ // A utility for checking whether new events should be stored and for whether
+ // old events should be kept.
+ std::unique_ptr<StorageValidator> storage_validator_;
// An in-memory representation of all events.
std::map<std::string, Event> events_;
@@ -67,9 +58,6 @@ class ModelImpl : public Model {
// Whether the model has been fully initialized.
bool ready_;
- // Whether the model is currently showing an in-product help.
- bool currently_showing_;
-
base::WeakPtrFactory<ModelImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ModelImpl);
diff --git a/chromium/components/feature_engagement_tracker/internal/model_impl_unittest.cc b/chromium/components/feature_engagement_tracker/internal/model_impl_unittest.cc
index ef57d2a5758..43bae9a4ee7 100644
--- a/chromium/components/feature_engagement_tracker/internal/model_impl_unittest.cc
+++ b/chromium/components/feature_engagement_tracker/internal/model_impl_unittest.cc
@@ -10,88 +10,95 @@
#include "base/callback.h"
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
-#include "base/metrics/field_trial.h"
-#include "base/run_loop.h"
-#include "base/test/scoped_feature_list.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "components/feature_engagement_tracker/internal/editable_configuration.h"
#include "components/feature_engagement_tracker/internal/in_memory_store.h"
+#include "components/feature_engagement_tracker/internal/never_storage_validator.h"
#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+#include "components/feature_engagement_tracker/internal/test/event_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace feature_engagement_tracker {
namespace {
-const base::Feature kTestFeatureFoo{"test_foo",
- base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kTestFeatureBar{"test_bar",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-void RegisterFeatureConfig(EditableConfiguration* configuration,
- const base::Feature& feature,
- bool valid) {
- FeatureConfig config;
- config.valid = valid;
- config.feature_used_event = feature.name;
- configuration->SetConfiguration(&feature, config);
-}
-
-void SetEventCountForDay(Event* event, uint32_t day, uint32_t count) {
- Event_Count* event_count = event->add_events();
- event_count->set_day(day);
- event_count->set_count(count);
-}
-
-// Verifies that the given |event| contains a |day| with the correct |count|,
-// and that the day only exists a single time.
-void VerifyEventCount(const Event& event, uint32_t day, uint32_t count) {
- bool found_day = false;
- for (int i = 0; i < event.events_size(); ++i) {
- Event_Count event_count = event.events(i);
- if (event_count.day() == day) {
- EXPECT_FALSE(found_day);
- found_day = true;
- EXPECT_EQ(count, event_count.count());
- }
- }
- EXPECT_TRUE(found_day);
-}
-
-// Verifies that the event |a| and |b| contain the exact same data.
-void VerifyEqual(const Event& a, const Event& b) {
- EXPECT_EQ(a.name(), b.name());
- EXPECT_EQ(a.events_size(), b.events_size());
- for (int i = 0; i < a.events_size(); ++i) {
- VerifyEventCount(b, a.events(i).day(), a.events(i).count());
- }
-}
// A test-only implementation of InMemoryStore that tracks calls to
// WriteEvent(...).
class TestInMemoryStore : public InMemoryStore {
public:
- explicit TestInMemoryStore(std::unique_ptr<std::vector<Event>> events,
- bool load_should_succeed)
+ TestInMemoryStore(std::unique_ptr<std::vector<Event>> events,
+ bool load_should_succeed)
: InMemoryStore(std::move(events)),
+ store_operation_count_(0),
load_should_succeed_(load_should_succeed) {}
void Load(const OnLoadedCallback& callback) override {
HandleLoadResult(callback, load_should_succeed_);
}
- void WriteEvent(const Event& event) override { last_written_event_ = event; }
+ void WriteEvent(const Event& event) override {
+ ++store_operation_count_;
+ last_written_event_.reset(new Event(event));
+ }
+
+ void DeleteEvent(const std::string& event_name) override {
+ ++store_operation_count_;
+ last_deleted_event_ = event_name;
+ }
+
+ const Event* GetLastWrittenEvent() { return last_written_event_.get(); }
+
+ const std::string GetLastDeletedEvent() { return last_deleted_event_; }
- Event GetLastWrittenEvent() { return last_written_event_; }
+ uint32_t GetStoreOperationCount() { return store_operation_count_; }
private:
// Temporary store the last written event.
- Event last_written_event_;
+ std::unique_ptr<Event> last_written_event_;
+
+ // Temporary store the last deleted event.
+ std::string last_deleted_event_;
+
+ // Tracks the number of operations performed on the store.
+ uint32_t store_operation_count_;
// Denotes whether the call to Load(...) should succeed or not. This impacts
// both the ready-state and the result for the OnLoadedCallback.
bool load_should_succeed_;
};
+class TestStorageValidator : public StorageValidator {
+ public:
+ TestStorageValidator() : should_store_(true) {}
+
+ bool ShouldStore(const std::string& event_name) const override {
+ return should_store_;
+ }
+
+ bool ShouldKeep(const std::string& event_name,
+ uint32_t event_day,
+ uint32_t current_day) const override {
+ auto search = max_keep_ages_.find(event_name);
+ if (search == max_keep_ages_.end())
+ return false;
+
+ return (current_day - event_day) < search->second;
+ }
+
+ void SetShouldStore(bool should_store) { should_store_ = should_store; }
+
+ void SetMaxKeepAge(const std::string& event_name, uint32_t age) {
+ max_keep_ages_[event_name] = age;
+ }
+
+ private:
+ bool should_store_;
+ std::map<std::string, uint32_t> max_keep_ages_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestStorageValidator);
+};
+
// Creates a TestInMemoryStore containing three hard coded events.
std::unique_ptr<TestInMemoryStore> CreatePrefilledStore() {
std::unique_ptr<std::vector<Event>> events =
@@ -99,63 +106,47 @@ std::unique_ptr<TestInMemoryStore> CreatePrefilledStore() {
Event foo;
foo.set_name("foo");
- SetEventCountForDay(&foo, 1, 1);
+ test::SetEventCountForDay(&foo, 1, 1);
events->push_back(foo);
Event bar;
bar.set_name("bar");
- SetEventCountForDay(&bar, 1, 3);
- SetEventCountForDay(&bar, 2, 3);
- SetEventCountForDay(&bar, 5, 5);
+ test::SetEventCountForDay(&bar, 1, 3);
+ test::SetEventCountForDay(&bar, 2, 3);
+ test::SetEventCountForDay(&bar, 5, 5);
events->push_back(bar);
Event qux;
qux.set_name("qux");
- SetEventCountForDay(&qux, 1, 5);
- SetEventCountForDay(&qux, 2, 1);
- SetEventCountForDay(&qux, 3, 2);
+ test::SetEventCountForDay(&qux, 1, 5);
+ test::SetEventCountForDay(&qux, 2, 1);
+ test::SetEventCountForDay(&qux, 3, 2);
events->push_back(qux);
return base::MakeUnique<TestInMemoryStore>(std::move(events), true);
}
-// A test-only implementation of ModelImpl to be able to change the current
-// day while a test is running.
-class TestModelImpl : public ModelImpl {
- public:
- TestModelImpl(std::unique_ptr<Store> store,
- std::unique_ptr<Configuration> configuration)
- : ModelImpl(std::move(store), std::move(configuration)),
- current_day_(0) {}
- ~TestModelImpl() override {}
-
- uint32_t GetCurrentDay() override { return current_day_; }
-
- void SetCurrentDay(uint32_t current_day) { current_day_ = current_day; }
-
- private:
- uint32_t current_day_;
-};
-
class ModelImplTest : public ::testing::Test {
public:
ModelImplTest()
- : got_initialize_callback_(false), initialize_callback_result_(false) {}
+ : task_runner_(new base::TestSimpleTaskRunner),
+ handle_(task_runner_),
+ got_initialize_callback_(false),
+ initialize_callback_result_(false) {}
void SetUp() override {
- std::unique_ptr<EditableConfiguration> configuration =
- base::MakeUnique<EditableConfiguration>();
-
- RegisterFeatureConfig(configuration.get(), kTestFeatureFoo, true);
- RegisterFeatureConfig(configuration.get(), kTestFeatureBar, true);
-
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar},
- {});
-
std::unique_ptr<TestInMemoryStore> store = CreateStore();
store_ = store.get();
- model_.reset(new TestModelImpl(std::move(store), std::move(configuration)));
+ auto storage_validator = base::MakeUnique<TestStorageValidator>();
+ storage_validator_ = storage_validator.get();
+
+ model_.reset(new ModelImpl(std::move(store), std::move(storage_validator)));
+
+ // By default store all events for a very long time.
+ storage_validator_->SetMaxKeepAge("foo", 10000u);
+ storage_validator_->SetMaxKeepAge("bar", 10000u);
+ storage_validator_->SetMaxKeepAge("qux", 10000u);
}
virtual std::unique_ptr<TestInMemoryStore> CreateStore() {
@@ -168,14 +159,14 @@ class ModelImplTest : public ::testing::Test {
}
protected:
- std::unique_ptr<TestModelImpl> model_;
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+ base::ThreadTaskRunnerHandle handle_;
+
+ std::unique_ptr<ModelImpl> model_;
TestInMemoryStore* store_;
+ TestStorageValidator* storage_validator_;
bool got_initialize_callback_;
bool initialize_callback_result_;
-
- private:
- base::MessageLoop message_loop_;
- base::test::ScopedFeatureList scoped_feature_list_;
};
class LoadFailingModelImplTest : public ModelImplTest {
@@ -190,193 +181,270 @@ class LoadFailingModelImplTest : public ModelImplTest {
} // namespace
+TEST_F(ModelImplTest, InitializeShouldBeReadyImmediatelyAfterCallback) {
+ model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
+ base::Unretained(this)),
+ 1000u);
+
+ // Only run pending tasks on the queue. Do not run any subsequently queued
+ // tasks that result from running the current pending tasks.
+ task_runner_->RunPendingTasks();
+
+ EXPECT_TRUE(got_initialize_callback_);
+ EXPECT_TRUE(model_->IsReady());
+}
+
TEST_F(ModelImplTest, InitializeShouldLoadEntries) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
EXPECT_TRUE(got_initialize_callback_);
EXPECT_TRUE(initialize_callback_result_);
// Verify that all the data matches what was put into the store in
// CreateStore().
- Event foo_event = model_->GetEvent("foo");
- EXPECT_EQ("foo", foo_event.name());
- EXPECT_EQ(1, foo_event.events_size());
- VerifyEventCount(foo_event, 1u, 1u);
-
- Event bar_event = model_->GetEvent("bar");
- EXPECT_EQ("bar", bar_event.name());
- EXPECT_EQ(3, bar_event.events_size());
- VerifyEventCount(bar_event, 1u, 3u);
- VerifyEventCount(bar_event, 2u, 3u);
- VerifyEventCount(bar_event, 5u, 5u);
-
- Event qux_event = model_->GetEvent("qux");
- EXPECT_EQ("qux", qux_event.name());
- EXPECT_EQ(3, qux_event.events_size());
- VerifyEventCount(qux_event, 1u, 5u);
- VerifyEventCount(qux_event, 2u, 1u);
- VerifyEventCount(qux_event, 3u, 2u);
+ const Event* foo_event = model_->GetEvent("foo");
+ EXPECT_EQ("foo", foo_event->name());
+ EXPECT_EQ(1, foo_event->events_size());
+ test::VerifyEventCount(foo_event, 1u, 1u);
+
+ const Event* bar_event = model_->GetEvent("bar");
+ EXPECT_EQ("bar", bar_event->name());
+ EXPECT_EQ(3, bar_event->events_size());
+ test::VerifyEventCount(bar_event, 1u, 3u);
+ test::VerifyEventCount(bar_event, 2u, 3u);
+ test::VerifyEventCount(bar_event, 5u, 5u);
+
+ const Event* qux_event = model_->GetEvent("qux");
+ EXPECT_EQ("qux", qux_event->name());
+ EXPECT_EQ(3, qux_event->events_size());
+ test::VerifyEventCount(qux_event, 1u, 5u);
+ test::VerifyEventCount(qux_event, 2u, 1u);
+ test::VerifyEventCount(qux_event, 3u, 2u);
+}
+
+TEST_F(ModelImplTest, InitializeShouldOnlyLoadEntriesThatShouldBeKept) {
+ // Back to day 5, i.e. no entries.
+ storage_validator_->SetMaxKeepAge("foo", 1u);
+
+ // Back to day 2, i.e. 2 events.
+ storage_validator_->SetMaxKeepAge("bar", 4u);
+
+ // Back to day epoch, i.e. all events.
+ storage_validator_->SetMaxKeepAge("qux", 10u);
+
+ model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
+ base::Unretained(this)),
+ 5u);
+ task_runner_->RunUntilIdle();
+ EXPECT_TRUE(model_->IsReady());
+ EXPECT_TRUE(got_initialize_callback_);
+ EXPECT_TRUE(initialize_callback_result_);
+
+ // Verify that all the data matches what was put into the store in
+ // CreateStore(), minus the events that should no longer exist.
+ const Event* foo_event = model_->GetEvent("foo");
+ EXPECT_EQ(nullptr, foo_event);
+ EXPECT_EQ("foo", store_->GetLastDeletedEvent());
+
+ const Event* bar_event = model_->GetEvent("bar");
+ EXPECT_EQ("bar", bar_event->name());
+ EXPECT_EQ(2, bar_event->events_size());
+ test::VerifyEventCount(bar_event, 2u, 3u);
+ test::VerifyEventCount(bar_event, 5u, 5u);
+ test::VerifyEventsEqual(bar_event, store_->GetLastWrittenEvent());
+
+ // Nothing has changed for 'qux', so nothing will be written to Store.
+ const Event* qux_event = model_->GetEvent("qux");
+ EXPECT_EQ("qux", qux_event->name());
+ EXPECT_EQ(3, qux_event->events_size());
+ test::VerifyEventCount(qux_event, 1u, 5u);
+ test::VerifyEventCount(qux_event, 2u, 1u);
+ test::VerifyEventCount(qux_event, 3u, 2u);
+
+ // In total, only two operations should have happened, the update of "bar",
+ // and the delete of "foo".
+ EXPECT_EQ(2u, store_->GetStoreOperationCount());
}
-TEST_F(ModelImplTest, RetrievingNewEventsShouldYieldEmpty) {
+TEST_F(ModelImplTest, RetrievingNewEventsShouldYieldNullptr) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
- Event no_event = model_->GetEvent("no");
- EXPECT_EQ("no", no_event.name());
- EXPECT_EQ(0, no_event.events_size());
- VerifyEqual(no_event, store_->GetLastWrittenEvent());
+ const Event* no_event = model_->GetEvent("no");
+ EXPECT_EQ(nullptr, no_event);
+ test::VerifyEventsEqual(nullptr, store_->GetLastWrittenEvent());
}
TEST_F(ModelImplTest, IncrementingNonExistingEvent) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
- model_->SetCurrentDay(1u);
-
// Incrementing the event should work even if it does not exist.
- model_->IncrementEvent("nonexisting");
- Event event1 = model_->GetEvent("nonexisting");
- EXPECT_EQ("nonexisting", event1.name());
- EXPECT_EQ(1, event1.events_size());
- VerifyEventCount(event1, 1u, 1u);
- VerifyEqual(event1, store_->GetLastWrittenEvent());
+ model_->IncrementEvent("nonexisting", 1u);
+ const Event* event1 = model_->GetEvent("nonexisting");
+ ASSERT_NE(nullptr, event1);
+ EXPECT_EQ("nonexisting", event1->name());
+ EXPECT_EQ(1, event1->events_size());
+ test::VerifyEventCount(event1, 1u, 1u);
+ test::VerifyEventsEqual(event1, store_->GetLastWrittenEvent());
// Incrementing the event after it has been initialized to 1, it should now
// have a count of 2 for the given day.
- model_->IncrementEvent("nonexisting");
- Event event2 = model_->GetEvent("nonexisting");
- Event_Count event2_count = event2.events(0);
- EXPECT_EQ(1, event2.events_size());
- VerifyEventCount(event2, 1u, 2u);
- VerifyEqual(event2, store_->GetLastWrittenEvent());
+ model_->IncrementEvent("nonexisting", 1u);
+ const Event* event2 = model_->GetEvent("nonexisting");
+ ASSERT_NE(nullptr, event2);
+ Event_Count event2_count = event2->events(0);
+ EXPECT_EQ(1, event2->events_size());
+ test::VerifyEventCount(event2, 1u, 2u);
+ test::VerifyEventsEqual(event2, store_->GetLastWrittenEvent());
}
TEST_F(ModelImplTest, IncrementingNonExistingEventMultipleDays) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
- model_->SetCurrentDay(1u);
- model_->IncrementEvent("nonexisting");
- model_->SetCurrentDay(2u);
- model_->IncrementEvent("nonexisting");
- model_->IncrementEvent("nonexisting");
- model_->SetCurrentDay(3u);
- model_->IncrementEvent("nonexisting");
- Event event = model_->GetEvent("nonexisting");
- EXPECT_EQ(3, event.events_size());
- VerifyEventCount(event, 1u, 1u);
- VerifyEventCount(event, 2u, 2u);
- VerifyEventCount(event, 3u, 1u);
- VerifyEqual(event, store_->GetLastWrittenEvent());
+ model_->IncrementEvent("nonexisting", 1u);
+ model_->IncrementEvent("nonexisting", 2u);
+ model_->IncrementEvent("nonexisting", 2u);
+ model_->IncrementEvent("nonexisting", 3u);
+ const Event* event = model_->GetEvent("nonexisting");
+ ASSERT_NE(nullptr, event);
+ EXPECT_EQ(3, event->events_size());
+ test::VerifyEventCount(event, 1u, 1u);
+ test::VerifyEventCount(event, 2u, 2u);
+ test::VerifyEventCount(event, 3u, 1u);
+ test::VerifyEventsEqual(event, store_->GetLastWrittenEvent());
}
-TEST_F(ModelImplTest, IncrementingSingleDayExistingEvent) {
+TEST_F(ModelImplTest, IncrementingNonExistingEventWithoutStoring) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
- model_->SetCurrentDay(1u);
+ storage_validator_->SetShouldStore(false);
+
+ // Incrementing the event should not be written or stored in-memory.
+ model_->IncrementEvent("nonexisting", 1u);
+ const Event* event1 = model_->GetEvent("nonexisting");
+ EXPECT_EQ(nullptr, event1);
+ test::VerifyEventsEqual(nullptr, store_->GetLastWrittenEvent());
+}
+
+TEST_F(ModelImplTest, IncrementingExistingEventWithoutStoring) {
+ model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
+ EXPECT_TRUE(model_->IsReady());
+
+ // Write one event before turning off storage.
+ model_->IncrementEvent("nonexisting", 1u);
+ const Event* first_event = model_->GetEvent("nonexisting");
+ ASSERT_NE(nullptr, first_event);
+ test::VerifyEventsEqual(first_event, store_->GetLastWrittenEvent());
+
+ storage_validator_->SetShouldStore(false);
+
+ // Incrementing the event should no longer be written or stored in-memory.
+ model_->IncrementEvent("nonexisting", 1u);
+ const Event* second_event = model_->GetEvent("nonexisting");
+ EXPECT_EQ(first_event, second_event);
+ test::VerifyEventsEqual(first_event, store_->GetLastWrittenEvent());
+}
+
+TEST_F(ModelImplTest, IncrementingSingleDayExistingEvent) {
+ model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
+ EXPECT_TRUE(model_->IsReady());
// |foo| is inserted into the store with a count of 1 at day 1.
- Event foo_event = model_->GetEvent("foo");
- EXPECT_EQ("foo", foo_event.name());
- EXPECT_EQ(1, foo_event.events_size());
- VerifyEventCount(foo_event, 1u, 1u);
+ const Event* foo_event = model_->GetEvent("foo");
+ EXPECT_EQ("foo", foo_event->name());
+ EXPECT_EQ(1, foo_event->events_size());
+ test::VerifyEventCount(foo_event, 1u, 1u);
// Incrementing |foo| should change count to 2.
- model_->IncrementEvent("foo");
- Event foo_event2 = model_->GetEvent("foo");
- EXPECT_EQ(1, foo_event2.events_size());
- VerifyEventCount(foo_event2, 1u, 2u);
- VerifyEqual(foo_event2, store_->GetLastWrittenEvent());
+ model_->IncrementEvent("foo", 1u);
+ const Event* foo_event2 = model_->GetEvent("foo");
+ EXPECT_EQ(1, foo_event2->events_size());
+ test::VerifyEventCount(foo_event2, 1u, 2u);
+ test::VerifyEventsEqual(foo_event2, store_->GetLastWrittenEvent());
}
TEST_F(ModelImplTest, IncrementingSingleDayExistingEventTwice) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
- model_->SetCurrentDay(1u);
-
// |foo| is inserted into the store with a count of 1 at day 1, so
// incrementing twice should lead to 3.
- model_->IncrementEvent("foo");
- model_->IncrementEvent("foo");
- Event foo_event = model_->GetEvent("foo");
- EXPECT_EQ(1, foo_event.events_size());
- VerifyEventCount(foo_event, 1u, 3u);
- VerifyEqual(foo_event, store_->GetLastWrittenEvent());
+ model_->IncrementEvent("foo", 1u);
+ model_->IncrementEvent("foo", 1u);
+ const Event* foo_event = model_->GetEvent("foo");
+ EXPECT_EQ(1, foo_event->events_size());
+ test::VerifyEventCount(foo_event, 1u, 3u);
+ test::VerifyEventsEqual(foo_event, store_->GetLastWrittenEvent());
}
TEST_F(ModelImplTest, IncrementingExistingMultiDayEvent) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
// |bar| is inserted into the store with a count of 3 at day 2. Incrementing
// that day should lead to a count of 4.
- model_->SetCurrentDay(2u);
- Event bar_event = model_->GetEvent("bar");
- VerifyEventCount(bar_event, 2u, 3u);
- model_->IncrementEvent("bar");
- Event bar_event2 = model_->GetEvent("bar");
- VerifyEventCount(bar_event2, 2u, 4u);
- VerifyEqual(bar_event2, store_->GetLastWrittenEvent());
+ const Event* bar_event = model_->GetEvent("bar");
+ test::VerifyEventCount(bar_event, 2u, 3u);
+ model_->IncrementEvent("bar", 2u);
+ const Event* bar_event2 = model_->GetEvent("bar");
+ test::VerifyEventCount(bar_event2, 2u, 4u);
+ test::VerifyEventsEqual(bar_event2, store_->GetLastWrittenEvent());
}
TEST_F(ModelImplTest, IncrementingExistingMultiDayEventNewDay) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_TRUE(model_->IsReady());
// |bar| does not contain entries for day 10, so incrementing should create
// the day.
- model_->SetCurrentDay(10u);
- model_->IncrementEvent("bar");
- Event bar_event = model_->GetEvent("bar");
- VerifyEventCount(bar_event, 10u, 1u);
- VerifyEqual(bar_event, store_->GetLastWrittenEvent());
- model_->IncrementEvent("bar");
- Event bar_event2 = model_->GetEvent("bar");
- VerifyEventCount(bar_event2, 10u, 2u);
- VerifyEqual(bar_event2, store_->GetLastWrittenEvent());
-}
-
-TEST_F(ModelImplTest, ShowState) {
- model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(model_->IsReady());
-
- EXPECT_FALSE(model_->IsCurrentlyShowing());
-
- model_->SetIsCurrentlyShowing(false);
- EXPECT_FALSE(model_->IsCurrentlyShowing());
-
- model_->SetIsCurrentlyShowing(true);
- EXPECT_TRUE(model_->IsCurrentlyShowing());
-
- model_->SetIsCurrentlyShowing(false);
- EXPECT_FALSE(model_->IsCurrentlyShowing());
+ model_->IncrementEvent("bar", 10u);
+ const Event* bar_event = model_->GetEvent("bar");
+ test::VerifyEventCount(bar_event, 10u, 1u);
+ test::VerifyEventsEqual(bar_event, store_->GetLastWrittenEvent());
+ model_->IncrementEvent("bar", 10u);
+ const Event* bar_event2 = model_->GetEvent("bar");
+ test::VerifyEventCount(bar_event2, 10u, 2u);
+ test::VerifyEventsEqual(bar_event2, store_->GetLastWrittenEvent());
}
TEST_F(LoadFailingModelImplTest, FailedInitializeInformsCaller) {
model_->Initialize(base::Bind(&ModelImplTest::OnModelInitializationFinished,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
+ base::Unretained(this)),
+ 1000u);
+ task_runner_->RunUntilIdle();
EXPECT_FALSE(model_->IsReady());
EXPECT_TRUE(got_initialize_callback_);
EXPECT_FALSE(initialize_callback_result_);
diff --git a/chromium/components/feature_engagement_tracker/internal/never_availability_model.cc b/chromium/components/feature_engagement_tracker/internal/never_availability_model.cc
new file mode 100644
index 00000000000..55ecbe545dd
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/never_availability_model.cc
@@ -0,0 +1,45 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/never_availability_model.h"
+
+#include <utility>
+
+#include "base/callback.h"
+#include "base/optional.h"
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+
+namespace feature_engagement_tracker {
+
+NeverAvailabilityModel::NeverAvailabilityModel() : ready_(false) {}
+
+NeverAvailabilityModel::~NeverAvailabilityModel() = default;
+
+void NeverAvailabilityModel::Initialize(OnInitializedCallback callback,
+ uint32_t current_day) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&NeverAvailabilityModel::ForwardedOnInitializedCallback,
+ base::Unretained(this), std::move(callback)));
+}
+
+bool NeverAvailabilityModel::IsReady() const {
+ return ready_;
+}
+
+base::Optional<uint32_t> NeverAvailabilityModel::GetAvailability(
+ const base::Feature& feature) const {
+ return base::nullopt;
+}
+
+void NeverAvailabilityModel::ForwardedOnInitializedCallback(
+ OnInitializedCallback callback) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), true));
+ ready_ = true;
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/never_availability_model.h b/chromium/components/feature_engagement_tracker/internal/never_availability_model.h
new file mode 100644
index 00000000000..1a64a5deb81
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/never_availability_model.h
@@ -0,0 +1,43 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_AVAILABILITY_MODEL_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_AVAILABILITY_MODEL_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "components/feature_engagement_tracker/internal/availability_model.h"
+
+namespace feature_engagement_tracker {
+
+// An AvailabilityModel that never has any data, and is ready after having been
+// initialized.
+class NeverAvailabilityModel : public AvailabilityModel {
+ public:
+ NeverAvailabilityModel();
+ ~NeverAvailabilityModel() override;
+
+ // AvailabilityModel implementation.
+ void Initialize(AvailabilityModel::OnInitializedCallback callback,
+ uint32_t current_day) override;
+ bool IsReady() const override;
+ base::Optional<uint32_t> GetAvailability(
+ const base::Feature& feature) const override;
+
+ private:
+ // Sets |ready_| to true and posts the result to |callback|. This method
+ // exists to ensure that |ready_| is not updated directly in the
+ // Initialize(...) method.
+ void ForwardedOnInitializedCallback(OnInitializedCallback callback);
+
+ // Whether the model has been successfully initialized.
+ bool ready_;
+
+ DISALLOW_COPY_AND_ASSIGN(NeverAvailabilityModel);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_AVAILABILITY_MODEL_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/never_availability_model_unittest.cc b/chromium/components/feature_engagement_tracker/internal/never_availability_model_unittest.cc
new file mode 100644
index 00000000000..a1c143c3ab6
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/never_availability_model_unittest.cc
@@ -0,0 +1,73 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/never_availability_model.h"
+
+#include "base/bind.h"
+#include "base/feature_list.h"
+#include "base/message_loop/message_loop.h"
+#include "base/optional.h"
+#include "base/run_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+const base::Feature kTestFeatureFoo{"test_foo",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTestFeatureBar{"test_bar",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+class NeverAvailabilityModelTest : public ::testing::Test {
+ public:
+ NeverAvailabilityModelTest() = default;
+
+ void OnInitializedCallback(bool success) { success_ = success; }
+
+ protected:
+ NeverAvailabilityModel availability_model_;
+ base::Optional<bool> success_;
+
+ private:
+ base::MessageLoop message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(NeverAvailabilityModelTest);
+};
+
+} // namespace
+
+TEST_F(NeverAvailabilityModelTest, ShouldNeverHaveData) {
+ EXPECT_EQ(base::nullopt,
+ availability_model_.GetAvailability(kTestFeatureFoo));
+ EXPECT_EQ(base::nullopt,
+ availability_model_.GetAvailability(kTestFeatureBar));
+
+ availability_model_.Initialize(
+ base::BindOnce(&NeverAvailabilityModelTest::OnInitializedCallback,
+ base::Unretained(this)),
+ 14u);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(base::nullopt,
+ availability_model_.GetAvailability(kTestFeatureFoo));
+ EXPECT_EQ(base::nullopt,
+ availability_model_.GetAvailability(kTestFeatureBar));
+}
+
+TEST_F(NeverAvailabilityModelTest, ShouldBeReadyAfterInitialization) {
+ EXPECT_FALSE(availability_model_.IsReady());
+ availability_model_.Initialize(
+ base::BindOnce(&NeverAvailabilityModelTest::OnInitializedCallback,
+ base::Unretained(this)),
+ 14u);
+ EXPECT_FALSE(availability_model_.IsReady());
+ EXPECT_FALSE(success_.has_value());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(availability_model_.IsReady());
+ ASSERT_TRUE(success_.has_value());
+ EXPECT_TRUE(success_.value());
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/never_condition_validator.cc b/chromium/components/feature_engagement_tracker/internal/never_condition_validator.cc
index 317c66c0618..535a51717e7 100644
--- a/chromium/components/feature_engagement_tracker/internal/never_condition_validator.cc
+++ b/chromium/components/feature_engagement_tracker/internal/never_condition_validator.cc
@@ -4,17 +4,23 @@
#include "components/feature_engagement_tracker/internal/never_condition_validator.h"
-#include "components/feature_engagement_tracker/internal/model.h"
-
namespace feature_engagement_tracker {
NeverConditionValidator::NeverConditionValidator() = default;
NeverConditionValidator::~NeverConditionValidator() = default;
-bool NeverConditionValidator::MeetsConditions(const base::Feature& feature,
- const Model& model) {
- return false;
+ConditionValidator::Result NeverConditionValidator::MeetsConditions(
+ const base::Feature& feature,
+ const FeatureConfig& config,
+ const Model& model,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const {
+ return ConditionValidator::Result(false);
}
+void NeverConditionValidator::NotifyIsShowing(const base::Feature& feature) {}
+
+void NeverConditionValidator::NotifyDismissed(const base::Feature& feature) {}
+
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/never_condition_validator.h b/chromium/components/feature_engagement_tracker/internal/never_condition_validator.h
index b9fca6483ad..bf4dc18ff89 100644
--- a/chromium/components/feature_engagement_tracker/internal/never_condition_validator.h
+++ b/chromium/components/feature_engagement_tracker/internal/never_condition_validator.h
@@ -5,17 +5,17 @@
#ifndef COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_CONDITION_VALIDATOR_H_
#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_CONDITION_VALIDATOR_H_
-#include <unordered_set>
-
#include "base/macros.h"
#include "components/feature_engagement_tracker/internal/condition_validator.h"
-#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
namespace base {
struct Feature;
} // namespace base
namespace feature_engagement_tracker {
+class AvailabilityModel;
+class Model;
// An ConditionValidator that never acknowledges that a feature has met its
// conditions.
@@ -25,8 +25,14 @@ class NeverConditionValidator : public ConditionValidator {
~NeverConditionValidator() override;
// ConditionValidator implementation.
- bool MeetsConditions(const base::Feature& feature,
- const Model& model) override;
+ ConditionValidator::Result MeetsConditions(
+ const base::Feature& feature,
+ const FeatureConfig& config,
+ const Model& model,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const override;
+ void NotifyIsShowing(const base::Feature& feature) override;
+ void NotifyDismissed(const base::Feature& feature) override;
private:
DISALLOW_COPY_AND_ASSIGN(NeverConditionValidator);
diff --git a/chromium/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc b/chromium/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc
index d39f1220af2..956998f92cc 100644
--- a/chromium/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc
+++ b/chromium/components/feature_engagement_tracker/internal/never_condition_validator_unittest.cc
@@ -4,10 +4,12 @@
#include "components/feature_engagement_tracker/internal/never_condition_validator.h"
+#include <string>
+
#include "base/feature_list.h"
-#include "base/metrics/field_trial.h"
-#include "base/test/scoped_feature_list.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/internal/never_availability_model.h"
#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,34 +25,20 @@ const base::Feature kTestFeatureBar{"test_bar",
// A Model that is always postive to show in-product help.
class TestModel : public Model {
public:
- TestModel() {
- feature_config_.valid = true;
- feature_config_.feature_used_event = "foobar";
- }
+ TestModel() = default;
- void Initialize(const OnModelInitializationFinished& callback) override {}
+ void Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) override {}
bool IsReady() const override { return true; }
- const FeatureConfig& GetFeatureConfig(
- const base::Feature& feature) const override {
- return feature_config_;
+ const Event* GetEvent(const std::string& event_name) const override {
+ return nullptr;
}
- void SetIsCurrentlyShowing(bool is_showing) override {}
-
- bool IsCurrentlyShowing() const override { return false; }
-
- const Event& GetEvent(const std::string& event_name) override {
- return empty_event_;
- }
-
- void IncrementEvent(const std::string& event_name) override {}
+ void IncrementEvent(const std::string& event_name, uint32_t day) override {}
private:
- FeatureConfig feature_config_;
- Event empty_event_;
-
DISALLOW_COPY_AND_ASSIGN(TestModel);
};
@@ -59,8 +47,8 @@ class NeverConditionValidatorTest : public ::testing::Test {
NeverConditionValidatorTest() = default;
protected:
- base::test::ScopedFeatureList scoped_feature_list_;
TestModel model_;
+ NeverAvailabilityModel availability_model_;
NeverConditionValidator validator_;
private:
@@ -70,9 +58,14 @@ class NeverConditionValidatorTest : public ::testing::Test {
} // namespace
TEST_F(NeverConditionValidatorTest, ShouldNeverMeetConditions) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
- EXPECT_FALSE(validator_.MeetsConditions(kTestFeatureFoo, model_));
- EXPECT_FALSE(validator_.MeetsConditions(kTestFeatureBar, model_));
+ EXPECT_FALSE(validator_
+ .MeetsConditions(kTestFeatureFoo, FeatureConfig(), model_,
+ availability_model_, 0u)
+ .NoErrors());
+ EXPECT_FALSE(validator_
+ .MeetsConditions(kTestFeatureBar, FeatureConfig(), model_,
+ availability_model_, 0u)
+ .NoErrors());
}
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/never_storage_validator.cc b/chromium/components/feature_engagement_tracker/internal/never_storage_validator.cc
new file mode 100644
index 00000000000..c919dbc6cdd
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/never_storage_validator.cc
@@ -0,0 +1,23 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/never_storage_validator.h"
+
+namespace feature_engagement_tracker {
+
+NeverStorageValidator::NeverStorageValidator() = default;
+
+NeverStorageValidator::~NeverStorageValidator() = default;
+
+bool NeverStorageValidator::ShouldStore(const std::string& event_name) const {
+ return false;
+}
+
+bool NeverStorageValidator::ShouldKeep(const std::string& event_name,
+ uint32_t event_day,
+ uint32_t current_day) const {
+ return false;
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/never_storage_validator.h b/chromium/components/feature_engagement_tracker/internal/never_storage_validator.h
new file mode 100644
index 00000000000..0194bf29608
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/never_storage_validator.h
@@ -0,0 +1,34 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_STORAGE_VALIDATOR_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_STORAGE_VALIDATOR_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "components/feature_engagement_tracker/internal/storage_validator.h"
+
+namespace feature_engagement_tracker {
+
+// A StorageValidator that never acknowledges that an event should be kept or
+// stored.
+class NeverStorageValidator : public StorageValidator {
+ public:
+ NeverStorageValidator();
+ ~NeverStorageValidator() override;
+
+ // StorageValidator implementation.
+ bool ShouldStore(const std::string& event_name) const override;
+ bool ShouldKeep(const std::string& event_name,
+ uint32_t event_day,
+ uint32_t current_day) const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NeverStorageValidator);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_NEVER_STORAGE_VALIDATOR_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/never_storage_validator_unittest.cc b/chromium/components/feature_engagement_tracker/internal/never_storage_validator_unittest.cc
new file mode 100644
index 00000000000..a2d77281ae7
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/never_storage_validator_unittest.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/never_storage_validator.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+class NeverStorageValidatorTest : public ::testing::Test {
+ public:
+ NeverStorageValidatorTest() = default;
+
+ protected:
+ NeverStorageValidator validator_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NeverStorageValidatorTest);
+};
+
+} // namespace
+
+TEST_F(NeverStorageValidatorTest, ShouldNeverKeep) {
+ EXPECT_FALSE(validator_.ShouldStore("dummy event"));
+}
+
+TEST_F(NeverStorageValidatorTest, ShouldNeverStore) {
+ EXPECT_FALSE(validator_.ShouldKeep("dummy event", 99, 100));
+ EXPECT_FALSE(validator_.ShouldKeep("dummy event", 100, 100));
+ EXPECT_FALSE(validator_.ShouldKeep("dummy event", 101, 100));
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/once_condition_validator.cc b/chromium/components/feature_engagement_tracker/internal/once_condition_validator.cc
index 1240766927b..4451e2cedcc 100644
--- a/chromium/components/feature_engagement_tracker/internal/once_condition_validator.cc
+++ b/chromium/components/feature_engagement_tracker/internal/once_condition_validator.cc
@@ -4,34 +4,45 @@
#include "components/feature_engagement_tracker/internal/once_condition_validator.h"
-#include "base/feature_list.h"
#include "components/feature_engagement_tracker/internal/configuration.h"
#include "components/feature_engagement_tracker/internal/model.h"
namespace feature_engagement_tracker {
-OnceConditionValidator::OnceConditionValidator() = default;
+OnceConditionValidator::OnceConditionValidator()
+ : currently_showing_feature_(nullptr) {}
OnceConditionValidator::~OnceConditionValidator() = default;
-bool OnceConditionValidator::MeetsConditions(const base::Feature& feature,
- const Model& model) {
- if (!model.IsReady())
- return false;
+ConditionValidator::Result OnceConditionValidator::MeetsConditions(
+ const base::Feature& feature,
+ const FeatureConfig& config,
+ const Model& model,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const {
+ ConditionValidator::Result result(true);
+ result.event_model_ready_ok = model.IsReady();
- if (model.IsCurrentlyShowing())
- return false;
+ result.currently_showing_ok = currently_showing_feature_ == nullptr;
- const FeatureConfig& config = model.GetFeatureConfig(feature);
- if (!config.valid)
- return false;
+ result.config_ok = config.valid;
- if (shown_features_.find(&feature) == shown_features_.end()) {
- shown_features_.insert(&feature);
- return true;
- }
+ result.session_rate_ok =
+ shown_features_.find(&feature) == shown_features_.end();
- return false;
+ return result;
+}
+
+void OnceConditionValidator::NotifyIsShowing(const base::Feature& feature) {
+ DCHECK(currently_showing_feature_ == nullptr);
+ DCHECK(shown_features_.find(&feature) == shown_features_.end());
+ shown_features_.insert(&feature);
+ currently_showing_feature_ = &feature;
+}
+
+void OnceConditionValidator::NotifyDismissed(const base::Feature& feature) {
+ DCHECK(&feature == currently_showing_feature_);
+ currently_showing_feature_ = nullptr;
}
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/once_condition_validator.h b/chromium/components/feature_engagement_tracker/internal/once_condition_validator.h
index 83b265edf51..57ea648d316 100644
--- a/chromium/components/feature_engagement_tracker/internal/once_condition_validator.h
+++ b/chromium/components/feature_engagement_tracker/internal/once_condition_validator.h
@@ -9,13 +9,15 @@
#include "base/macros.h"
#include "components/feature_engagement_tracker/internal/condition_validator.h"
-#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
namespace base {
struct Feature;
} // namespace base
namespace feature_engagement_tracker {
+class AvailabilityModel;
+class Model;
// An ConditionValidator that will ensure that each base::Feature will meet
// conditions maximum one time for any given session.
@@ -36,13 +38,23 @@ class OnceConditionValidator : public ConditionValidator {
~OnceConditionValidator() override;
// ConditionValidator implementation.
- bool MeetsConditions(const base::Feature& feature,
- const Model& model) override;
+ ConditionValidator::Result MeetsConditions(
+ const base::Feature& feature,
+ const FeatureConfig& config,
+ const Model& model,
+ const AvailabilityModel& availability_model,
+ uint32_t current_day) const override;
+ void NotifyIsShowing(const base::Feature& feature) override;
+ void NotifyDismissed(const base::Feature& feature) override;
private:
// Contains all features that have met conditions within the current session.
std::unordered_set<const base::Feature*> shown_features_;
+ // Which feature that is currently being shown, or nullptr if nothing is
+ // currently showing.
+ const base::Feature* currently_showing_feature_;
+
DISALLOW_COPY_AND_ASSIGN(OnceConditionValidator);
};
diff --git a/chromium/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc b/chromium/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc
index c8ee8c7b333..a60f6a6ed66 100644
--- a/chromium/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc
+++ b/chromium/components/feature_engagement_tracker/internal/once_condition_validator_unittest.cc
@@ -7,10 +7,9 @@
#include <string>
#include "base/feature_list.h"
-#include "base/metrics/field_trial.h"
-#include "base/test/scoped_feature_list.h"
#include "components/feature_engagement_tracker/internal/editable_configuration.h"
#include "components/feature_engagement_tracker/internal/model.h"
+#include "components/feature_engagement_tracker/internal/never_availability_model.h"
#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,41 +22,29 @@ const base::Feature kTestFeatureFoo{"test_foo",
const base::Feature kTestFeatureBar{"test_bar",
base::FEATURE_DISABLED_BY_DEFAULT};
+FeatureConfig kValidFeatureConfig;
+FeatureConfig kInvalidFeatureConfig;
+
// A Model that is easily configurable at runtime.
class TestModel : public Model {
public:
- TestModel() : ready_(false), is_showing_(false) {}
+ TestModel() : ready_(false) { kValidFeatureConfig.valid = true; }
- void Initialize(const OnModelInitializationFinished& callback) override {}
+ void Initialize(const OnModelInitializationFinished& callback,
+ uint32_t current_day) override {}
bool IsReady() const override { return ready_; }
void SetIsReady(bool ready) { ready_ = ready; }
- const FeatureConfig& GetFeatureConfig(
- const base::Feature& feature) const override {
- return configuration_.GetFeatureConfig(feature);
- }
-
- void SetIsCurrentlyShowing(bool is_showing) override {
- is_showing_ = is_showing;
- }
-
- bool IsCurrentlyShowing() const override { return is_showing_; }
-
- EditableConfiguration& GetConfiguration() { return configuration_; }
-
- const Event& GetEvent(const std::string& event_name) override {
- return empty_event_;
+ const Event* GetEvent(const std::string& event_name) const override {
+ return nullptr;
}
- void IncrementEvent(const std::string& event_name) override {}
+ void IncrementEvent(const std::string& event_name, uint32_t day) override {}
private:
- EditableConfiguration configuration_;
- Event empty_event_;
bool ready_;
- bool is_showing_;
};
class OnceConditionValidatorTest : public ::testing::Test {
@@ -67,15 +54,10 @@ class OnceConditionValidatorTest : public ::testing::Test {
model_.SetIsReady(true);
}
- void AddFeature(const base::Feature& feature, bool valid) {
- FeatureConfig feature_config;
- feature_config.valid = valid;
- model_.GetConfiguration().SetConfiguration(&feature, feature_config);
- }
-
protected:
- base::test::ScopedFeatureList scoped_feature_list_;
+ EditableConfiguration configuration_;
TestModel model_;
+ NeverAvailabilityModel availability_model_;
OnceConditionValidator validator_;
private:
@@ -85,79 +67,84 @@ class OnceConditionValidatorTest : public ::testing::Test {
} // namespace
TEST_F(OnceConditionValidatorTest, EnabledFeatureShouldTriggerOnce) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
-
- // Initialize validator with one enabled and valid feature.
- AddFeature(kTestFeatureFoo, true);
-
// Only the first call to MeetsConditions() should lead to enlightenment.
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureFoo, model_));
- EXPECT_FALSE(validator_.MeetsConditions(kTestFeatureFoo, model_));
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureFoo, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
+ validator_.NotifyIsShowing(kTestFeatureFoo);
+ ConditionValidator::Result result = validator_.MeetsConditions(
+ kTestFeatureFoo, kValidFeatureConfig, model_, availability_model_, 0u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.session_rate_ok);
}
TEST_F(OnceConditionValidatorTest,
BothEnabledAndDisabledFeaturesShouldTrigger) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {kTestFeatureBar});
-
- // Initialize validator with one enabled and one disabled feature, both valid.
- AddFeature(kTestFeatureFoo, true);
- AddFeature(kTestFeatureBar, true);
-
// Only the kTestFeatureFoo feature should lead to enlightenment, since
// kTestFeatureBar is disabled. Ordering disabled feature first to ensure this
// captures a different behavior than the
// OnlyOneFeatureShouldTriggerPerSession test below.
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureBar, model_));
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureFoo, model_));
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureBar, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureFoo, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
}
TEST_F(OnceConditionValidatorTest, StillTriggerWhenAllFeaturesDisabled) {
- scoped_feature_list_.InitWithFeatures({}, {kTestFeatureFoo, kTestFeatureBar});
-
- // Initialize validator with two enabled features, both valid.
- AddFeature(kTestFeatureFoo, true);
- AddFeature(kTestFeatureBar, true);
-
// No features should get to show enlightenment.
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureFoo, model_));
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureBar, model_));
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureFoo, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureBar, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
}
TEST_F(OnceConditionValidatorTest, OnlyTriggerWhenModelIsReady) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
-
- // Initialize validator with a single valid feature.
- AddFeature(kTestFeatureFoo, true);
-
model_.SetIsReady(false);
- EXPECT_FALSE(validator_.MeetsConditions(kTestFeatureFoo, model_));
+ ConditionValidator::Result result = validator_.MeetsConditions(
+ kTestFeatureFoo, kValidFeatureConfig, model_, availability_model_, 0u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.event_model_ready_ok);
model_.SetIsReady(true);
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureFoo, model_));
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureFoo, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
}
TEST_F(OnceConditionValidatorTest, OnlyTriggerIfNothingElseIsShowing) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
-
- // Initialize validator with a single valid feature.
- AddFeature(kTestFeatureFoo, true);
-
- model_.SetIsCurrentlyShowing(true);
- EXPECT_FALSE(validator_.MeetsConditions(kTestFeatureFoo, model_));
-
- model_.SetIsCurrentlyShowing(false);
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureFoo, model_));
+ validator_.NotifyIsShowing(kTestFeatureBar);
+ ConditionValidator::Result result = validator_.MeetsConditions(
+ kTestFeatureFoo, kValidFeatureConfig, model_, availability_model_, 0u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.currently_showing_ok);
+
+ validator_.NotifyDismissed(kTestFeatureBar);
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureFoo, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
}
TEST_F(OnceConditionValidatorTest, DoNotTriggerForInvalidConfig) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo}, {});
-
- AddFeature(kTestFeatureFoo, false);
- EXPECT_FALSE(validator_.MeetsConditions(kTestFeatureFoo, model_));
-
- // Override config to be valid.
- AddFeature(kTestFeatureFoo, true);
- EXPECT_TRUE(validator_.MeetsConditions(kTestFeatureFoo, model_));
+ ConditionValidator::Result result = validator_.MeetsConditions(
+ kTestFeatureFoo, kInvalidFeatureConfig, model_, availability_model_, 0u);
+ EXPECT_FALSE(result.NoErrors());
+ EXPECT_FALSE(result.config_ok);
+
+ EXPECT_TRUE(validator_
+ .MeetsConditions(kTestFeatureFoo, kValidFeatureConfig, model_,
+ availability_model_, 0u)
+ .NoErrors());
}
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/persistent_store.cc b/chromium/components/feature_engagement_tracker/internal/persistent_store.cc
new file mode 100644
index 00000000000..9be61087b9c
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/persistent_store.cc
@@ -0,0 +1,91 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/persistent_store.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "components/feature_engagement_tracker/internal/stats.h"
+
+namespace feature_engagement_tracker {
+namespace {
+// Corresponds to a UMA suffix "LevelDBOpenResults" in histograms.xml.
+// Please do not change.
+const char kDatabaseUMAName[] = "FeatureEngagementTrackerEventStore";
+
+using KeyEventPair = std::pair<std::string, Event>;
+using KeyEventList = std::vector<KeyEventPair>;
+
+void NoopUpdateCallback(bool success) {
+ stats::RecordDbUpdate(success, stats::StoreType::EVENTS_STORE);
+}
+
+} // namespace
+
+PersistentStore::PersistentStore(
+ const base::FilePath& storage_dir,
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db)
+ : storage_dir_(storage_dir),
+ db_(std::move(db)),
+ ready_(false),
+ weak_ptr_factory_(this) {}
+
+PersistentStore::~PersistentStore() = default;
+
+void PersistentStore::Load(const OnLoadedCallback& callback) {
+ DCHECK(!ready_);
+
+ db_->Init(kDatabaseUMAName, storage_dir_,
+ base::Bind(&PersistentStore::OnInitComplete,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+bool PersistentStore::IsReady() const {
+ return ready_;
+}
+
+void PersistentStore::WriteEvent(const Event& event) {
+ DCHECK(IsReady());
+ std::unique_ptr<KeyEventList> entries = base::MakeUnique<KeyEventList>();
+ entries->push_back(KeyEventPair(event.name(), event));
+
+ db_->UpdateEntries(std::move(entries),
+ base::MakeUnique<std::vector<std::string>>(),
+ base::Bind(&NoopUpdateCallback));
+}
+
+void PersistentStore::DeleteEvent(const std::string& event_name) {
+ DCHECK(IsReady());
+ auto deletes = base::MakeUnique<std::vector<std::string>>();
+ deletes->push_back(event_name);
+
+ db_->UpdateEntries(base::MakeUnique<KeyEventList>(), std::move(deletes),
+ base::Bind(&NoopUpdateCallback));
+}
+
+void PersistentStore::OnInitComplete(const OnLoadedCallback& callback,
+ bool success) {
+ stats::RecordDbInitEvent(success, stats::StoreType::EVENTS_STORE);
+
+ if (!success) {
+ callback.Run(false, base::MakeUnique<std::vector<Event>>());
+ return;
+ }
+
+ db_->LoadEntries(base::Bind(&PersistentStore::OnLoadComplete,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void PersistentStore::OnLoadComplete(
+ const OnLoadedCallback& callback,
+ bool success,
+ std::unique_ptr<std::vector<Event>> entries) {
+ stats::RecordEventDbLoadEvent(success, *entries.get());
+ ready_ = success;
+ callback.Run(success, std::move(entries));
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/persistent_store.h b/chromium/components/feature_engagement_tracker/internal/persistent_store.h
new file mode 100644
index 00000000000..bbbf0fc8b17
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/persistent_store.h
@@ -0,0 +1,59 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_PERSISTENT_STORE_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_PERSISTENT_STORE_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+#include "components/feature_engagement_tracker/internal/store.h"
+#include "components/leveldb_proto/proto_database.h"
+
+namespace feature_engagement_tracker {
+
+// A PersistentStore provides a DB layer that persists the data to disk. The
+// data is retrieved once during the load process and after that this store is
+// write only. Data will be persisted asynchronously so it is not guaranteed to
+// always save every write during shutdown.
+class PersistentStore : public Store {
+ public:
+ // Builds a PersistentStore backed by the ProtoDatabase |db|. The database
+ // will be loaded and/or created at |storage_dir|.
+ PersistentStore(const base::FilePath& storage_dir,
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db);
+ ~PersistentStore() override;
+
+ // Store implementation.
+ void Load(const OnLoadedCallback& callback) override;
+ bool IsReady() const override;
+ void WriteEvent(const Event& event) override;
+ void DeleteEvent(const std::string& event_name) override;
+
+ private:
+ void OnInitComplete(const OnLoadedCallback& callback, bool success);
+ void OnLoadComplete(const OnLoadedCallback& callback,
+ bool success,
+ std::unique_ptr<std::vector<Event>> entries);
+
+ const base::FilePath storage_dir_;
+ std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db_;
+
+ // Whether or not the underlying ProtoDatabase is ready. This will be false
+ // until the OnLoadedCallback is broadcast. It will also be false if loading
+ // fails.
+ bool ready_;
+
+ base::WeakPtrFactory<PersistentStore> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PersistentStore);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_PERSISTENT_STORE_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/persistent_store_unittest.cc b/chromium/components/feature_engagement_tracker/internal/persistent_store_unittest.cc
new file mode 100644
index 00000000000..290d2b5fc42
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/persistent_store_unittest.cc
@@ -0,0 +1,251 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/persistent_store.h"
+
+#include <map>
+
+#include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
+#include "base/optional.h"
+#include "base/test/histogram_tester.h"
+#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+#include "components/feature_engagement_tracker/internal/stats.h"
+#include "components/feature_engagement_tracker/internal/test/event_util.h"
+#include "components/leveldb_proto/proto_database.h"
+#include "components/leveldb_proto/testing/fake_db.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+void VerifyEventsInListAndMap(const std::map<std::string, Event>& map,
+ const std::vector<Event>& list) {
+ ASSERT_EQ(map.size(), list.size());
+
+ for (const auto& event : list) {
+ const auto& it = map.find(event.name());
+ ASSERT_NE(map.end(), it);
+ test::VerifyEventsEqual(&event, &it->second);
+ }
+}
+
+class PersistentStoreTest : public ::testing::Test {
+ public:
+ PersistentStoreTest()
+ : db_(nullptr),
+ storage_dir_(FILE_PATH_LITERAL("/persistent/store/lalala")) {
+ load_callback_ =
+ base::Bind(&PersistentStoreTest::LoadCallback, base::Unretained(this));
+ }
+
+ void TearDown() override {
+ db_events_.clear();
+ db_ = nullptr;
+ store_.reset();
+ }
+
+ protected:
+ void SetUpDB() {
+ DCHECK(!db_);
+ DCHECK(!store_);
+
+ auto db = base::MakeUnique<leveldb_proto::test::FakeDB<Event>>(&db_events_);
+ db_ = db.get();
+ store_.reset(new PersistentStore(storage_dir_, std::move(db)));
+ }
+
+ void LoadCallback(bool success, std::unique_ptr<std::vector<Event>> events) {
+ load_successful_ = success;
+ load_results_ = std::move(events);
+ }
+
+ // Callback results.
+ base::Optional<bool> load_successful_;
+ std::unique_ptr<std::vector<Event>> load_results_;
+
+ Store::OnLoadedCallback load_callback_;
+ std::map<std::string, Event> db_events_;
+ leveldb_proto::test::FakeDB<Event>* db_;
+ std::unique_ptr<Store> store_;
+
+ // Constant test data.
+ base::FilePath storage_dir_;
+};
+
+} // namespace
+
+TEST_F(PersistentStoreTest, StorageDirectory) {
+ SetUpDB();
+ store_->Load(load_callback_);
+ EXPECT_EQ(storage_dir_, db_->GetDirectory());
+}
+
+TEST_F(PersistentStoreTest, SuccessfulInitAndLoadEmptyStore) {
+ SetUpDB();
+
+ base::HistogramTester histogram_tester;
+
+ store_->Load(load_callback_);
+ // The initialize should not trigger a response to the callback.
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ // The load should trigger a response to the callback.
+ db_->LoadCallback(true);
+ EXPECT_TRUE(load_successful_.value());
+
+ // Validate that we have no entries.
+ EXPECT_NE(nullptr, load_results_);
+ EXPECT_TRUE(load_results_->empty());
+
+ // Verify histograms.
+ std::string suffix =
+ stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 1, 1);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.Load." + suffix, 1, 1);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.TotalEvents", 0, 1);
+}
+
+TEST_F(PersistentStoreTest, SuccessfulInitAndLoadWithEvents) {
+ // Populate fake Event entries.
+ Event event1;
+ event1.set_name("event1");
+ test::SetEventCountForDay(&event1, 1, 1);
+
+ Event event2;
+ event2.set_name("event2");
+ test::SetEventCountForDay(&event2, 1, 3);
+ test::SetEventCountForDay(&event2, 2, 5);
+
+ db_events_.insert(std::pair<std::string, Event>(event1.name(), event1));
+ db_events_.insert(std::pair<std::string, Event>(event2.name(), event2));
+
+ SetUpDB();
+
+ base::HistogramTester histogram_tester;
+
+ // The initialize should not trigger a response to the callback.
+ store_->Load(load_callback_);
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ // The load should trigger a response to the callback.
+ db_->LoadCallback(true);
+ EXPECT_TRUE(load_successful_.value());
+ EXPECT_NE(nullptr, load_results_);
+
+ // Validate that we have the two events that we expect.
+ VerifyEventsInListAndMap(db_events_, *load_results_);
+
+ // Verify histograms.
+ std::string suffix =
+ stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 1, 1);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.Load." + suffix, 1, 1);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.TotalEvents", 3, 1);
+}
+
+TEST_F(PersistentStoreTest, SuccessfulInitBadLoad) {
+ base::HistogramTester histogram_tester;
+ SetUpDB();
+
+ store_->Load(load_callback_);
+
+ // The initialize should not trigger a response to the callback.
+ db_->InitCallback(true);
+ EXPECT_FALSE(load_successful_.has_value());
+
+ // The load will fail and should trigger the callback.
+ db_->LoadCallback(false);
+ EXPECT_FALSE(load_successful_.value());
+ EXPECT_FALSE(store_->IsReady());
+
+ // Histograms.
+ std::string suffix =
+ stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 1, 1);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.Load." + suffix, 0, 1);
+ histogram_tester.ExpectTotalCount("InProductHelp.Db.TotalEvents", 0);
+}
+
+TEST_F(PersistentStoreTest, BadInit) {
+ base::HistogramTester histogram_tester;
+ SetUpDB();
+
+ store_->Load(load_callback_);
+
+ // The initialize will fail and should trigger the callback.
+ db_->InitCallback(false);
+ EXPECT_FALSE(load_successful_.value());
+ EXPECT_FALSE(store_->IsReady());
+
+ // Histograms.
+ std::string suffix =
+ stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
+ histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 0, 1);
+ histogram_tester.ExpectTotalCount("InProductHelp.Db.Load." + suffix, 0);
+ histogram_tester.ExpectTotalCount("InProductHelp.Db.TotalEvents", 0);
+}
+
+TEST_F(PersistentStoreTest, IsReady) {
+ SetUpDB();
+ EXPECT_FALSE(store_->IsReady());
+
+ store_->Load(load_callback_);
+ EXPECT_FALSE(store_->IsReady());
+
+ db_->InitCallback(true);
+ EXPECT_FALSE(store_->IsReady());
+
+ db_->LoadCallback(true);
+ EXPECT_TRUE(store_->IsReady());
+}
+
+TEST_F(PersistentStoreTest, WriteEvent) {
+ SetUpDB();
+
+ store_->Load(load_callback_);
+ db_->InitCallback(true);
+ db_->LoadCallback(true);
+
+ Event event;
+ event.set_name("event");
+ test::SetEventCountForDay(&event, 1, 2);
+
+ store_->WriteEvent(event);
+ db_->UpdateCallback(true);
+
+ EXPECT_EQ(1U, db_events_.size());
+
+ const auto& it = db_events_.find("event");
+ EXPECT_NE(db_events_.end(), it);
+ test::VerifyEventsEqual(&event, &it->second);
+}
+
+TEST_F(PersistentStoreTest, WriteAndDeleteEvent) {
+ SetUpDB();
+
+ store_->Load(load_callback_);
+ db_->InitCallback(true);
+ db_->LoadCallback(true);
+
+ Event event;
+ event.set_name("event");
+ test::SetEventCountForDay(&event, 1, 2);
+
+ store_->WriteEvent(event);
+ db_->UpdateCallback(true);
+
+ EXPECT_EQ(1U, db_events_.size());
+
+ store_->DeleteEvent("event");
+ db_->UpdateCallback(true);
+
+ const auto& it = db_events_.find("event");
+ EXPECT_EQ(db_events_.end(), it);
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/proto/BUILD.gn b/chromium/components/feature_engagement_tracker/internal/proto/BUILD.gn
index 686f184a97f..e4063482e90 100644
--- a/chromium/components/feature_engagement_tracker/internal/proto/BUILD.gn
+++ b/chromium/components/feature_engagement_tracker/internal/proto/BUILD.gn
@@ -6,6 +6,7 @@ import("//third_party/protobuf/proto_library.gni")
proto_library("proto") {
sources = [
+ "availability.proto",
"event.proto",
]
}
diff --git a/chromium/components/feature_engagement_tracker/internal/proto/availability.proto b/chromium/components/feature_engagement_tracker/internal/proto/availability.proto
new file mode 100644
index 00000000000..97dfd4b3c84
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/proto/availability.proto
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+//
+// FeatureEngagementTracker content.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package feature_engagement_tracker;
+
+// Availability stores state for the availability of a particular feature.
+message Availability {
+ // The name of the feature. Must match base::Feature::name.
+ optional string feature_name = 1;
+
+ // The day number since epoch (1970-01-01) in the local timezone for when the
+ // particular |feature| was made available.
+ optional uint32 day = 2;
+}
diff --git a/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.cc b/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
index ed20e661431..5b82515d505 100644
--- a/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
+++ b/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
@@ -10,7 +10,7 @@ namespace feature_engagement_tracker {
SingleInvalidConfiguration::SingleInvalidConfiguration() {
invalid_feature_config_.valid = false;
- invalid_feature_config_.feature_used_event = "nothing_to_see_here";
+ invalid_feature_config_.used.name = "nothing_to_see_here";
};
SingleInvalidConfiguration::~SingleInvalidConfiguration() = default;
@@ -20,4 +20,9 @@ const FeatureConfig& SingleInvalidConfiguration::GetFeatureConfig(
return invalid_feature_config_;
}
+const Configuration::ConfigMap&
+SingleInvalidConfiguration::GetRegisteredFeatures() const {
+ return configs_;
+}
+
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.h b/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.h
index 449cee97bbe..dd0ea1ff7d9 100644
--- a/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.h
+++ b/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration.h
@@ -17,7 +17,7 @@ struct Feature;
namespace feature_engagement_tracker {
// An Configuration that always returns the same single invalid configuration,
-// regardless of which feature.
+// regardless of which feature. Also holds an empty ConfigMap.
class SingleInvalidConfiguration : public Configuration {
public:
SingleInvalidConfiguration();
@@ -26,11 +26,15 @@ class SingleInvalidConfiguration : public Configuration {
// Configuration implementation.
const FeatureConfig& GetFeatureConfig(
const base::Feature& feature) const override;
+ const Configuration::ConfigMap& GetRegisteredFeatures() const override;
private:
// The invalid configuration to always return.
FeatureConfig invalid_feature_config_;
+ // An empty map.
+ ConfigMap configs_;
+
DISALLOW_COPY_AND_ASSIGN(SingleInvalidConfiguration);
};
diff --git a/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration_unittest.cc b/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration_unittest.cc
index d4c2666b563..ed6ebba3b47 100644
--- a/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration_unittest.cc
+++ b/chromium/components/feature_engagement_tracker/internal/single_invalid_configuration_unittest.cc
@@ -5,8 +5,6 @@
#include "components/feature_engagement_tracker/internal/single_invalid_configuration.h"
#include "base/feature_list.h"
-#include "base/metrics/field_trial.h"
-#include "base/test/scoped_feature_list.h"
#include "components/feature_engagement_tracker/internal/configuration.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -24,7 +22,6 @@ class SingleInvalidConfigurationTest : public ::testing::Test {
SingleInvalidConfigurationTest() = default;
protected:
- base::test::ScopedFeatureList scoped_feature_list_;
SingleInvalidConfiguration configuration_;
private:
@@ -34,8 +31,6 @@ class SingleInvalidConfigurationTest : public ::testing::Test {
} // namespace
TEST_F(SingleInvalidConfigurationTest, AllConfigurationsAreInvalid) {
- scoped_feature_list_.InitWithFeatures({kTestFeatureFoo, kTestFeatureBar}, {});
-
FeatureConfig foo_config = configuration_.GetFeatureConfig(kTestFeatureFoo);
EXPECT_FALSE(foo_config.valid);
diff --git a/chromium/components/feature_engagement_tracker/internal/stats.cc b/chromium/components/feature_engagement_tracker/internal/stats.cc
new file mode 100644
index 00000000000..9593f0319e1
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/stats.cc
@@ -0,0 +1,199 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/stats.h"
+
+#include <string>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/user_metrics.h"
+#include "components/feature_engagement_tracker/public/feature_list.h"
+
+namespace feature_engagement_tracker {
+namespace stats {
+namespace {
+
+// Histogram suffixes for database metrics, must match the ones in
+// histograms.xml.
+const char kEventStoreSuffix[] = "EventStore";
+const char kAvailabilityStoreSuffix[] = "AvailabilityStore";
+
+// Helper function to log a TriggerHelpUIResult.
+void LogTriggerHelpUIResult(const std::string& name,
+ TriggerHelpUIResult result) {
+ // Must not use histograms macros here because we pass in the histogram name.
+ base::UmaHistogramEnumeration(name, result, TriggerHelpUIResult::COUNT);
+}
+
+} // namespace
+
+std::string ToDbHistogramSuffix(StoreType type) {
+ switch (type) {
+ case StoreType::EVENTS_STORE:
+ return std::string(kEventStoreSuffix);
+ case StoreType::AVAILABILITY_STORE:
+ return std::string(kAvailabilityStoreSuffix);
+ default:
+ NOTREACHED();
+ return std::string();
+ }
+}
+
+void RecordNotifyEvent(const std::string& event_name,
+ const Configuration* config,
+ bool is_model_ready) {
+ DCHECK(!event_name.empty());
+ DCHECK(config);
+
+ // Find which feature this event belongs to.
+ const Configuration::ConfigMap& features = config->GetRegisteredFeatures();
+ std::string feature_name;
+ for (const auto& element : features) {
+ const base::Feature* feature = element.first;
+ const FeatureConfig& feature_config = element.second;
+
+ // Track used event separately.
+ if (feature_config.used.name == event_name) {
+ feature_name = feature->name;
+ DCHECK(!feature_name.empty());
+ std::string used_event_action = "InProductHelp.NotifyUsedEvent.";
+ used_event_action.append(feature_name);
+ base::RecordComputedAction(used_event_action);
+ break;
+ }
+
+ // Find if the |event_name| matches any configuration.
+ for (const auto& event : feature_config.event_configs) {
+ if (event.name == event_name) {
+ feature_name = feature->name;
+ break;
+ }
+ }
+ if (feature_config.trigger.name == event_name) {
+ feature_name = feature->name;
+ break;
+ }
+ }
+
+ // Do nothing if no events in the configuration matches the |event_name|.
+ if (feature_name.empty())
+ return;
+
+ std::string event_action = "InProductHelp.NotifyEvent.";
+ event_action.append(feature_name);
+ base::RecordComputedAction(event_action);
+
+ std::string event_histogram = "InProductHelp.NotifyEventReadyState.";
+ event_histogram.append(feature_name);
+ base::UmaHistogramBoolean(event_histogram, is_model_ready);
+}
+
+void RecordShouldTriggerHelpUI(const base::Feature& feature,
+ const ConditionValidator::Result& result) {
+ // Records the user action.
+ std::string name = "InProductHelp.ShouldTriggerHelpUI.";
+ name.append(feature.name);
+ base::RecordComputedAction(name);
+
+ // Total count histogram, used to compute the percentage of each failure type,
+ // in addition to a user action for whether the result was to trigger or not.
+ if (result.NoErrors()) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::SUCCESS);
+ std::string name = "InProductHelp.ShouldTriggerHelpUIResult.Triggered.";
+ name.append(feature.name);
+ base::RecordComputedAction(name);
+ } else {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE);
+ std::string name = "InProductHelp.ShouldTriggerHelpUIResult.NotTriggered.";
+ name.append(feature.name);
+ base::RecordComputedAction(name);
+ }
+
+ // Histogram about the failure reasons.
+ if (!result.event_model_ready_ok)
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_MODEL_NOT_READY);
+ if (!result.currently_showing_ok) {
+ LogTriggerHelpUIResult(name,
+ TriggerHelpUIResult::FAILURE_CURRENTLY_SHOWING);
+ }
+ if (!result.feature_enabled_ok) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_FEATURE_DISABLED);
+ }
+ if (!result.config_ok) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_CONFIG_INVALID);
+ }
+ if (!result.used_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_USED_PRECONDITION_UNMET);
+ }
+ if (!result.trigger_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_TRIGGER_PRECONDITION_UNMET);
+ }
+ if (!result.preconditions_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_OTHER_PRECONDITION_UNMET);
+ }
+ if (!result.session_rate_ok) {
+ LogTriggerHelpUIResult(name, TriggerHelpUIResult::FAILURE_SESSION_RATE);
+ }
+ if (!result.availability_model_ready_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_AVAILABILITY_MODEL_NOT_READY);
+ }
+ if (!result.availability_ok) {
+ LogTriggerHelpUIResult(
+ name, TriggerHelpUIResult::FAILURE_AVAILABILITY_PRECONDITION_UNMET);
+ }
+}
+
+void RecordUserDismiss() {
+ base::RecordAction(base::UserMetricsAction("InProductHelp.Dismissed"));
+}
+
+void RecordDbUpdate(bool success, StoreType type) {
+ std::string histogram_name =
+ "InProductHelp.Db.Update." + ToDbHistogramSuffix(type);
+ base::UmaHistogramBoolean(histogram_name, success);
+}
+
+void RecordDbInitEvent(bool success, StoreType type) {
+ std::string histogram_name =
+ "InProductHelp.Db.Init." + ToDbHistogramSuffix(type);
+ base::UmaHistogramBoolean(histogram_name, success);
+}
+
+void RecordEventDbLoadEvent(bool success, const std::vector<Event>& events) {
+ std::string histogram_name =
+ "InProductHelp.Db.Load." + ToDbHistogramSuffix(StoreType::EVENTS_STORE);
+ base::UmaHistogramBoolean(histogram_name, success);
+ UMA_HISTOGRAM_BOOLEAN("InProductHelp.Db.Load", success);
+
+ if (!success)
+ return;
+
+ // Tracks total number of events records when the database is successfully
+ // loaded.
+ int event_count = 0;
+ for (const auto& event : events)
+ event_count += event.events_size();
+ UMA_HISTOGRAM_COUNTS_1000("InProductHelp.Db.TotalEvents", event_count);
+}
+
+void RecordAvailabilityDbLoadEvent(bool success) {
+ std::string histogram_name =
+ "InProductHelp.Db.Load." +
+ ToDbHistogramSuffix(StoreType::AVAILABILITY_STORE);
+ base::UmaHistogramBoolean(histogram_name, success);
+ UMA_HISTOGRAM_BOOLEAN("InProductHelp.Db.Load", success);
+}
+
+void RecordConfigParsingEvent(ConfigParsingEvent event) {
+ UMA_HISTOGRAM_ENUMERATION("InProductHelp.Config.ParsingEvent", event,
+ ConfigParsingEvent::COUNT);
+}
+
+} // namespace stats
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/stats.h b/chromium/components/feature_engagement_tracker/internal/stats.h
new file mode 100644
index 00000000000..7171a3201f2
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/stats.h
@@ -0,0 +1,150 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STATS_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STATS_H_
+
+#include <string>
+#include <vector>
+
+#include "components/feature_engagement_tracker/internal/condition_validator.h"
+#include "components/feature_engagement_tracker/internal/configuration.h"
+#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
+
+namespace feature_engagement_tracker {
+namespace stats {
+
+// Enum used in the metrics to record the result when in-product help UI is
+// going to be triggered.
+// Most of the fields maps to |ConditionValidator::Result|.
+// The failure reasons are not mutually exclusive.
+// Out-dated entries shouldn't be deleted but marked as obselete.
+enum class TriggerHelpUIResult {
+ // The help UI is triggered.
+ SUCCESS = 0,
+
+ // The help UI is not triggered.
+ FAILURE = 1,
+
+ // Data layer is not ready.
+ FAILURE_MODEL_NOT_READY = 2,
+
+ // Some other help UI is currently showing.
+ FAILURE_CURRENTLY_SHOWING = 3,
+
+ // The feature is disabled.
+ FAILURE_FEATURE_DISABLED = 4,
+
+ // Configuration can not be parsed.
+ FAILURE_CONFIG_INVALID = 5,
+
+ // Used event precondition is not satisfied.
+ FAILURE_USED_PRECONDITION_UNMET = 6,
+
+ // Trigger event precondition is not satisfied.
+ FAILURE_TRIGGER_PRECONDITION_UNMET = 7,
+
+ // Other event precondition is not satisfied.
+ FAILURE_OTHER_PRECONDITION_UNMET = 8,
+
+ // Session rate does not meet the requirement.
+ FAILURE_SESSION_RATE = 9,
+
+ // Availability mode is not ready.
+ FAILURE_AVAILABILITY_MODEL_NOT_READY = 10,
+
+ // Availability precondition is not satisfied.
+ FAILURE_AVAILABILITY_PRECONDITION_UNMET = 11,
+
+ // Last entry for the enum.
+ COUNT = 12,
+};
+
+// Used in the metrics to track the configuration parsing event.
+// The failure reasons are not mutually exclusive.
+// Out-dated entries shouldn't be deleted but marked as obsolete.
+enum class ConfigParsingEvent {
+ // The configuration is parsed correctly.
+ SUCCESS = 0,
+
+ // The configuration is invalid after parsing.
+ FAILURE = 1,
+
+ // Fails to parse the feature config because no field trial is found.
+ FAILURE_NO_FIELD_TRIAL = 2,
+
+ // Fails to parse the used event.
+ FAILURE_USED_EVENT_PARSE = 3,
+
+ // Used event is missing.
+ FAILURE_USED_EVENT_MISSING = 4,
+
+ // Fails to parse the trigger event.
+ FAILURE_TRIGGER_EVENT_PARSE = 5,
+
+ // Trigger event is missing.
+ FAILURE_TRIGGER_EVENT_MISSING = 6,
+
+ // Fails to parse other events.
+ FAILURE_OTHER_EVENT_PARSE = 7,
+
+ // Fails to parse the session rate comparator.
+ FAILURE_SESSION_RATE_PARSE = 8,
+
+ // Fails to parse the availability comparator.
+ FAILURE_AVAILABILITY_PARSE = 9,
+
+ // UnKnown key in configuration parameters.
+ FAILURE_UNKNOWN_KEY = 10,
+
+ // Last entry for the enum.
+ COUNT = 11,
+};
+
+// Used in metrics to track database states. Each type will match to a suffix
+// in the histograms to identify the database.
+enum class StoreType {
+ // Events store.
+ EVENTS_STORE = 0,
+
+ // Availability store.
+ AVAILABILITY_STORE = 1,
+};
+
+// Helper function that converts a store type to histogram suffix string.
+std::string ToDbHistogramSuffix(StoreType type);
+
+// Records the feature engagement events. Used event will be tracked
+// separately.
+void RecordNotifyEvent(const std::string& event,
+ const Configuration* config,
+ bool is_model_ready);
+
+// Records user action and the result histogram when in-product help will be
+// shown to the user.
+void RecordShouldTriggerHelpUI(const base::Feature& feature,
+ const ConditionValidator::Result& result);
+
+// Records when the user dismisses the in-product help UI.
+void RecordUserDismiss();
+
+// Records the result of database updates.
+void RecordDbUpdate(bool success, StoreType type);
+
+// Record database init.
+void RecordDbInitEvent(bool success, StoreType type);
+
+// Records events database load event.
+void RecordEventDbLoadEvent(bool success, const std::vector<Event>& events);
+
+// Records availability database load event.
+void RecordAvailabilityDbLoadEvent(bool success);
+
+// Records configuration parsing event.
+void RecordConfigParsingEvent(ConfigParsingEvent event);
+
+} // namespace stats
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STATS_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/storage_validator.h b/chromium/components/feature_engagement_tracker/internal/storage_validator.h
new file mode 100644
index 00000000000..15d2d3dc62b
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/storage_validator.h
@@ -0,0 +1,40 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STORAGE_VALIDATOR_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STORAGE_VALIDATOR_H_
+
+#include <string>
+
+#include "base/macros.h"
+
+namespace feature_engagement_tracker {
+
+// A StorageValidator checks the required storage conditions for a given event,
+// and checks if all conditions are met for storing it.
+class StorageValidator {
+ public:
+ virtual ~StorageValidator() = default;
+
+ // Returns true iff new events of this type should be stored.
+ // This is typically called before storing each incoming event.
+ virtual bool ShouldStore(const std::string& event_name) const = 0;
+
+ // Returns true iff events of this type should be kept for the given day.
+ // This is typically called during load of the internal database state, to
+ // possibly throw away old data.
+ virtual bool ShouldKeep(const std::string& event_name,
+ uint32_t event_day,
+ uint32_t current_day) const = 0;
+
+ protected:
+ StorageValidator() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StorageValidator);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STORAGE_VALIDATOR_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/store.h b/chromium/components/feature_engagement_tracker/internal/store.h
index cef9b460a21..cc546ad3e61 100644
--- a/chromium/components/feature_engagement_tracker/internal/store.h
+++ b/chromium/components/feature_engagement_tracker/internal/store.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STORE_H_
#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_STORE_H_
+#include <string>
+
#include "base/callback.h"
#include "base/macros.h"
#include "components/feature_engagement_tracker/internal/proto/event.pb.h"
@@ -14,7 +16,6 @@ namespace feature_engagement_tracker {
// Store represents the storage engine behind the FeatureEngagementTracker.
class Store {
public:
- // TODO(nyquist): Add vector of all events to result callback.
using OnLoadedCallback =
base::Callback<void(bool success, std::unique_ptr<std::vector<Event>>)>;
@@ -32,6 +33,9 @@ class Store {
// Stores the given event to persistent storage.
virtual void WriteEvent(const Event& event) = 0;
+ // Deletes the event with the given name.
+ virtual void DeleteEvent(const std::string& event_name) = 0;
+
protected:
Store() = default;
diff --git a/chromium/components/feature_engagement_tracker/internal/system_time_provider.cc b/chromium/components/feature_engagement_tracker/internal/system_time_provider.cc
new file mode 100644
index 00000000000..6e00ee98129
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/system_time_provider.cc
@@ -0,0 +1,24 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/system_time_provider.h"
+
+#include "base/time/time.h"
+
+namespace feature_engagement_tracker {
+
+SystemTimeProvider::SystemTimeProvider() = default;
+
+SystemTimeProvider::~SystemTimeProvider() = default;
+
+uint32_t SystemTimeProvider::GetCurrentDay() const {
+ base::TimeDelta delta = Now() - base::Time::UnixEpoch();
+ return base::saturated_cast<uint32_t>(delta.InDays());
+}
+
+base::Time SystemTimeProvider::Now() const {
+ return base::Time::Now();
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/system_time_provider.h b/chromium/components/feature_engagement_tracker/internal/system_time_provider.h
new file mode 100644
index 00000000000..9f6a849867c
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/system_time_provider.h
@@ -0,0 +1,34 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_SYSTEM_TIME_PROVIDER_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_SYSTEM_TIME_PROVIDER_H_
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "components/feature_engagement_tracker/internal/time_provider.h"
+
+namespace feature_engagement_tracker {
+
+// A TimeProvider that uses the system time.
+class SystemTimeProvider : public TimeProvider {
+ public:
+ SystemTimeProvider();
+ ~SystemTimeProvider() override;
+
+ // TimeProvider implementation.
+ uint32_t GetCurrentDay() const override;
+
+ protected:
+ // Return the current time.
+ // virtual for testing.
+ virtual base::Time Now() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SystemTimeProvider);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_SYSTEM_TIME_PROVIDER_H_
diff --git a/chromium/components/feature_engagement_tracker/internal/system_time_provider_unittest.cc b/chromium/components/feature_engagement_tracker/internal/system_time_provider_unittest.cc
new file mode 100644
index 00000000000..6bcf53c77c4
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/system_time_provider_unittest.cc
@@ -0,0 +1,112 @@
+// Copyright 2017 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/feature_engagement_tracker/internal/system_time_provider.h"
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+base::Time GetTime(int year, int month, int day) {
+ base::Time::Exploded exploded_time;
+ exploded_time.year = year;
+ exploded_time.month = month;
+ exploded_time.day_of_month = day;
+ exploded_time.hour = 0;
+ exploded_time.minute = 0;
+ exploded_time.second = 0;
+ exploded_time.millisecond = 0;
+
+ base::Time out_time;
+ EXPECT_TRUE(base::Time::FromUTCExploded(exploded_time, &out_time));
+ return out_time;
+}
+
+// A SystemTimeProvider where the current time can be defined at runtime.
+class TestSystemTimeProvider : public SystemTimeProvider {
+ public:
+ TestSystemTimeProvider() = default;
+
+ // SystemTimeProvider implementation.
+ base::Time Now() const override { return current_time_; }
+
+ void SetCurrentTime(base::Time time) { current_time_ = time; }
+
+ private:
+ base::Time current_time_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestSystemTimeProvider);
+};
+
+class SystemTimeProviderTest : public ::testing::Test {
+ public:
+ SystemTimeProviderTest() = default;
+
+ protected:
+ TestSystemTimeProvider time_provider_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SystemTimeProviderTest);
+};
+
+} // namespace
+
+TEST_F(SystemTimeProviderTest, EpochIs0Days) {
+ time_provider_.SetCurrentTime(base::Time::UnixEpoch());
+ EXPECT_EQ(0u, time_provider_.GetCurrentDay());
+}
+
+TEST_F(SystemTimeProviderTest, TestDeltasFromEpoch) {
+ base::Time epoch = base::Time::UnixEpoch();
+
+ time_provider_.SetCurrentTime(epoch + base::TimeDelta::FromDays(1));
+ EXPECT_EQ(1u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(epoch + base::TimeDelta::FromDays(2));
+ EXPECT_EQ(2u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(epoch + base::TimeDelta::FromDays(100));
+ EXPECT_EQ(100u, time_provider_.GetCurrentDay());
+}
+
+TEST_F(SystemTimeProviderTest, TestNegativeDeltasFromEpoch) {
+ base::Time epoch = base::Time::UnixEpoch();
+
+ time_provider_.SetCurrentTime(epoch - base::TimeDelta::FromDays(1));
+ EXPECT_EQ(0u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(epoch - base::TimeDelta::FromDays(2));
+ EXPECT_EQ(0u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(epoch - base::TimeDelta::FromDays(100));
+ EXPECT_EQ(0u, time_provider_.GetCurrentDay());
+}
+
+TEST_F(SystemTimeProviderTest, TestManualDatesAroundEpoch) {
+ time_provider_.SetCurrentTime(GetTime(1970, 1, 1));
+ EXPECT_EQ(0u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(GetTime(1970, 1, 2));
+ EXPECT_EQ(1u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(GetTime(1970, 4, 11));
+ EXPECT_EQ(100u, time_provider_.GetCurrentDay());
+}
+
+TEST_F(SystemTimeProviderTest, TestManualDatesAroundGoogleIO2017) {
+ time_provider_.SetCurrentTime(GetTime(2017, 5, 17));
+ EXPECT_EQ(17303u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(GetTime(2017, 5, 18));
+ EXPECT_EQ(17304u, time_provider_.GetCurrentDay());
+
+ time_provider_.SetCurrentTime(GetTime(2017, 5, 19));
+ EXPECT_EQ(17305u, time_provider_.GetCurrentDay());
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/internal/test/BUILD.gn b/chromium/components/feature_engagement_tracker/internal/test/BUILD.gn
new file mode 100644
index 00000000000..83001382c22
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/test/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2017 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.
+
+source_set("test_support") {
+ testonly = true
+
+ visibility = [ "//components/feature_engagement_tracker/internal:unit_tests" ]
+
+ sources = [
+ "event_util.cc",
+ "event_util.h",
+ ]
+
+ deps = [
+ "//components/feature_engagement_tracker/internal/proto",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/feature_engagement_tracker/internal/time_provider.h b/chromium/components/feature_engagement_tracker/internal/time_provider.h
new file mode 100644
index 00000000000..da3b61da3bc
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/internal/time_provider.h
@@ -0,0 +1,31 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_TIME_PROVIDER_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_TIME_PROVIDER_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+
+namespace feature_engagement_tracker {
+
+// A TimeProvider provides functionality related to time.
+class TimeProvider {
+ public:
+ virtual ~TimeProvider() = default;
+
+ // Returns the number of days since epoch (1970-01-01) in the local timezone.
+ virtual uint32_t GetCurrentDay() const = 0;
+
+ protected:
+ TimeProvider() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TimeProvider);
+};
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_TIME_PROVIDER_H_
diff --git a/chromium/components/feature_engagement_tracker/public/BUILD.gn b/chromium/components/feature_engagement_tracker/public/BUILD.gn
index 62a0f4ae869..6d431bf09d1 100644
--- a/chromium/components/feature_engagement_tracker/public/BUILD.gn
+++ b/chromium/components/feature_engagement_tracker/public/BUILD.gn
@@ -11,10 +11,13 @@ source_set("public") {
sources = [
"feature_constants.h",
"feature_engagement_tracker.h",
+ "feature_list.cc",
+ "feature_list.h",
]
deps = [
"//base",
+ "//components/flags_ui",
"//components/keyed_service/core",
]
@@ -26,6 +29,7 @@ source_set("public") {
if (is_android) {
android_library("public_java") {
java_files = [
+ "android/java/src/org/chromium/components/feature_engagement_tracker/EventConstants.java",
"android/java/src/org/chromium/components/feature_engagement_tracker/FeatureConstants.java",
"android/java/src/org/chromium/components/feature_engagement_tracker/FeatureEngagementTracker.java",
]
diff --git a/chromium/components/feature_engagement_tracker/public/feature_constants.h b/chromium/components/feature_engagement_tracker/public/feature_constants.h
index c26608a4247..007a6c6e5e1 100644
--- a/chromium/components/feature_engagement_tracker/public/feature_constants.h
+++ b/chromium/components/feature_engagement_tracker/public/feature_constants.h
@@ -10,13 +10,21 @@
namespace feature_engagement_tracker {
// A feature for enabling a demonstration mode for In-Product Help.
-extern const base::Feature kIPHDemoMode;
+// This needs to be constexpr because of how it is used in
+// //chrome/browser/about_flags.cc.
+constexpr base::Feature kIPHDemoMode = {"IPH_DemoMode",
+ base::FEATURE_DISABLED_BY_DEFAULT};
// All the features declared below should also be declared in the Java
// version: org.chromium.components.feature_engagement_tracker.FeatureConstants.
-
-// A dummy feature until real features start using the backend.
-extern const base::Feature kIPHDummyFeature;
+// These need to be constexpr, because they are used as
+// flags_ui::FeatureEntry::FeatureParams in feature_list.h.
+constexpr base::Feature kIPHDataSaverPreview = {
+ "IPH_DataSaverPreview", base::FEATURE_DISABLED_BY_DEFAULT};
+constexpr base::Feature kIPHDownloadPageFeature = {
+ "IPH_DownloadPage", base::FEATURE_DISABLED_BY_DEFAULT};
+constexpr base::Feature kIPHDownloadHomeFeature = {
+ "IPH_DownloadHome", base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/public/feature_engagement_tracker.h b/chromium/components/feature_engagement_tracker/public/feature_engagement_tracker.h
index b151dda4e70..53f82b2cbba 100644
--- a/chromium/components/feature_engagement_tracker/public/feature_engagement_tracker.h
+++ b/chromium/components/feature_engagement_tracker/public/feature_engagement_tracker.h
@@ -37,8 +37,8 @@ class FeatureEngagementTracker : public KeyedService {
#endif // defined(OS_ANDROID)
// Invoked when the tracker has been initialized. The |success| parameter
- // indicates that the initialization was a success and it it ready to receive
- // calls.
+ // indicates that the initialization was a success and the tracker is ready to
+ // receive calls.
using OnInitializedCallback = base::Callback<void(bool success)>;
// The |storage_dir| is the path to where all local storage will be.
@@ -58,11 +58,23 @@ class FeatureEngagementTracker : public KeyedService {
virtual bool ShouldTriggerHelpUI(const base::Feature& feature)
WARN_UNUSED_RESULT = 0;
- // Must be called after display of feature enlightenment finishes.
- virtual void Dismissed() = 0;
-
- // For features that trigger on startup, they register a callback to ensure
- // that they are told when the tracker has been initialized.
+ // Must be called after display of feature enlightenment finishes for a
+ // particular |feature|.
+ virtual void Dismissed(const base::Feature& feature) = 0;
+
+ // Returns whether the tracker has been successfully initialized. During
+ // startup, this will be false until the internal model has been loaded at
+ // which point it is set to true if the initialization was successful. The
+ // state will never change from initialized to uninitialized.
+ // Callers can invoke AddOnInitializedCallback(...) to be notified when the
+ // result of the initialization is ready.
+ virtual bool IsInitialized() = 0;
+
+ // For features that trigger on startup, they can register a callback to
+ // ensure that they are informed when the tracker has finished the
+ // initialization. If the tracker has already been initialized, the callback
+ // will still be invoked with the result. The callback is guaranteed to be
+ // invoked exactly one time.
virtual void AddOnInitializedCallback(OnInitializedCallback callback) = 0;
protected:
diff --git a/chromium/components/feature_engagement_tracker/public/feature_list.cc b/chromium/components/feature_engagement_tracker/public/feature_list.cc
new file mode 100644
index 00000000000..e64aaf5a33c
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/public/feature_list.cc
@@ -0,0 +1,63 @@
+/// Copyright 2017 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/feature_engagement_tracker/public/feature_list.h"
+
+#include "base/feature_list.h"
+#include "components/feature_engagement_tracker/public/feature_constants.h"
+#include "components/flags_ui/feature_entry.h"
+
+namespace feature_engagement_tracker {
+
+namespace {
+
+// Defines a const flags_ui::FeatureEntry::FeatureParam for the given
+// base::Feature. The constant name will be on the form
+// kFooFeature --> kFooFeatureVariation. This is intended to be used with
+// VARIATION_ENTRY below to be able to insert it into an array of
+// flags_ui::FeatureEntry::FeatureVariation.
+#define DEFINE_VARIATION_PARAM(base_feature) \
+ constexpr flags_ui::FeatureEntry::FeatureParam base_feature##Variation[] = { \
+ {kIPHDemoModeFeatureChoiceParam, base_feature.name}}
+
+// Defines a single flags_ui::FeatureEntry::FeatureVariation entry, fully
+// enclosed. This is intended to be used with the declaration of
+// |kIPHDemoModeChoiceVariations| below.
+#define VARIATION_ENTRY(base_feature) \
+ { \
+ base_feature##Variation[0].param_value, base_feature##Variation, \
+ arraysize(base_feature##Variation), nullptr \
+ }
+
+// Whenever a feature is added to |kAllFeatures|, it should also be added as
+// DEFINE_VARIATION_PARAM below, and also added to the
+// |kIPHDemoModeChoiceVariations| array.
+const base::Feature* kAllFeatures[] = {
+ &kIPHDataSaverPreview, &kIPHDownloadPageFeature, &kIPHDownloadHomeFeature};
+
+// Defines a flags_ui::FeatureEntry::FeatureParam for each feature.
+DEFINE_VARIATION_PARAM(kIPHDataSaverPreview);
+DEFINE_VARIATION_PARAM(kIPHDownloadPageFeature);
+DEFINE_VARIATION_PARAM(kIPHDownloadHomeFeature);
+
+} // namespace
+
+const char kIPHDemoModeFeatureChoiceParam[] = "chosen_feature";
+
+constexpr flags_ui::FeatureEntry::FeatureVariation
+ kIPHDemoModeChoiceVariations[] = {
+ VARIATION_ENTRY(kIPHDataSaverPreview),
+ VARIATION_ENTRY(kIPHDownloadPageFeature),
+ VARIATION_ENTRY(kIPHDownloadHomeFeature),
+ // Note: When changing the number of entries in this array, the constant
+ // kIPHDemoModeChoiceVariationsLen in feature_list.h must also be
+ // updated to reflect the real size.
+};
+
+std::vector<const base::Feature*> GetAllFeatures() {
+ return std::vector<const base::Feature*>(
+ kAllFeatures, kAllFeatures + arraysize(kAllFeatures));
+}
+
+} // namespace feature_engagement_tracker
diff --git a/chromium/components/feature_engagement_tracker/public/feature_list.h b/chromium/components/feature_engagement_tracker/public/feature_list.h
new file mode 100644
index 00000000000..0cb72bd288e
--- /dev/null
+++ b/chromium/components/feature_engagement_tracker/public/feature_list.h
@@ -0,0 +1,37 @@
+// Copyright 2017 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_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_LIST_H_
+#define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_LIST_H_
+
+#include <vector>
+
+#include "base/feature_list.h"
+#include "components/flags_ui/feature_entry.h"
+
+namespace feature_engagement_tracker {
+using FeatureVector = std::vector<const base::Feature*>;
+
+// The param name for the FeatureVariation configuration, which is used by
+// chrome://flags to set the variable name for the selected feature. The
+// FeatureEngagementTracker backend will then read this to figure out which
+// feature (if any) was selected by the end user.
+extern const char kIPHDemoModeFeatureChoiceParam[];
+
+// The length of kIPHDemoModeChoiceVariations. This must be updated whenever
+// new features are added to the demo mode selection.
+constexpr size_t kIPHDemoModeChoiceVariationsLen = 3;
+
+// Defines the array of which features should be listed in the chrome://flags
+// UI to be able to select them alone for demo-mode. The features listed here
+// are possible to enable on their own in demo mode.
+extern const flags_ui::FeatureEntry::FeatureVariation
+ kIPHDemoModeChoiceVariations[kIPHDemoModeChoiceVariationsLen];
+
+// Returns all the features that are in use for engagement tracking.
+FeatureVector GetAllFeatures();
+
+} // namespace feature_engagement_tracker
+
+#endif // COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_FEATURE_LIST_H_
diff --git a/chromium/components/feedback/BUILD.gn b/chromium/components/feedback/BUILD.gn
index adb30bcd3c1..28cae94debc 100644
--- a/chromium/components/feedback/BUILD.gn
+++ b/chromium/components/feedback/BUILD.gn
@@ -39,7 +39,7 @@ static_library("feedback") {
"//content/public/common",
"//net",
"//third_party/re2",
- "//third_party/zlib:zip",
+ "//third_party/zlib/google:zip",
]
}
diff --git a/chromium/components/feedback/anonymizer_tool.cc b/chromium/components/feedback/anonymizer_tool.cc
index bc8a223cada..198f979a0ab 100644
--- a/chromium/components/feedback/anonymizer_tool.cc
+++ b/chromium/components/feedback/anonymizer_tool.cc
@@ -41,11 +41,12 @@ namespace {
// (?-s) turns off "dot matches newline" for the remainder of the regex.
// (?:regex) denotes non-capturing parentheses group.
const char* kCustomPatternsWithContext[] = {
- "(\\bCell ID: ')([0-9a-fA-F]+)(')", // ModemManager
- "(\\bLocation area code: ')([0-9a-fA-F]+)(')", // ModemManager
- "(?i-s)(\\bssid[= ]')(.+)(')", // wpa_supplicant
- "(?-s)(\\bSSID - hexdump\\(len=[0-9]+\\): )(.+)()", // wpa_supplicant
- "(?-s)(\\[SSID=)(.+?)(\\])", // shill
+ "(\\bCell ID: ')([0-9a-fA-F]+)(')", // ModemManager
+ "(\\bLocation area code: ')([0-9a-fA-F]+)(')", // ModemManager
+ "(?i-s)(\\bssid[= ]')(.+)(')", // wpa_supplicant
+ "(?-s)(\\bSSID - hexdump\\(len=[0-9]+\\): )(.+)()", // wpa_supplicant
+ "(?-s)(\\[SSID=)(.+?)(\\])", // shill
+ "(?i-s)(serial\\s*number\\s*:\\s*)([0-9a-zA-Z\\-]+)()", // Serial numbers
};
// Helper macro: Non capturing group
@@ -164,14 +165,18 @@ const char* kCustomPatternsWithContext[] = {
// The |kCustomPatternWithoutContext| array defines further patterns to match
// and anonymize. Each pattern consists of a single capturing group.
CustomPatternWithoutContext kCustomPatternsWithoutContext[] = {
- {"URL", "(?i)(" IRI ")"},
- // Email Addresses need to come after URLs because they can be part
- // of a query parameter.
- {"email", "(?i)([0-9a-z._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6})"},
- // IP filter rules need to come after URLs so that they don't disturb the
- // URL pattern in case the IP address is part of a URL.
- {"IPv4", "(?i)(" IPV4ADDRESS ")"},
- {"IPv6", "(?i)(" IPV6ADDRESS ")"},
+ {"URL", "(?i)(" IRI ")"},
+ // Email Addresses need to come after URLs because they can be part
+ // of a query parameter.
+ {"email", "(?i)([0-9a-z._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6})"},
+ // IP filter rules need to come after URLs so that they don't disturb the
+ // URL pattern in case the IP address is part of a URL.
+ {"IPv4", "(?i)(" IPV4ADDRESS ")"},
+ {"IPv6", "(?i)(" IPV6ADDRESS ")"},
+ // Universal Unique Identifiers (UUIDs).
+ {"UUID",
+ "(?i)([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-"
+ "[0-9a-zA-Z]{12})"},
};
// Like RE2's FindAndConsume, searches for the first occurrence of |pattern| in
diff --git a/chromium/components/feedback/anonymizer_tool_unittest.cc b/chromium/components/feedback/anonymizer_tool_unittest.cc
index 5c9aae99d97..c0b87540be0 100644
--- a/chromium/components/feedback/anonymizer_tool_unittest.cc
+++ b/chromium/components/feedback/anonymizer_tool_unittest.cc
@@ -47,6 +47,22 @@ TEST_F(AnonymizerToolTest, Anonymize) {
// Make sure custom pattern anonymization is invoked.
EXPECT_EQ("Cell ID: '1'", AnonymizeCustomPatterns("Cell ID: 'A1B2'"));
+
+ // Make sure UUIDs are anonymized.
+ EXPECT_EQ(
+ "REQUEST localhost - - \"POST /printers/<UUID: 1> HTTP/1.1\" 200 291 "
+ "Create-Job successful-ok",
+ anonymizer_.Anonymize(
+ "REQUEST localhost - - \"POST /printers/"
+ "cb738a9f-6433-4d95-a81e-94e4ae0ed30b HTTP/1.1\" 200 291 Create-Job "
+ "successful-ok"));
+ EXPECT_EQ(
+ "REQUEST localhost - - \"POST /printers/<UUID: 2> HTTP/1.1\" 200 286 "
+ "Create-Job successful-ok",
+ anonymizer_.Anonymize(
+ "REQUEST localhost - - \"POST /printers/"
+ "d17188da-9cd3-44f4-b148-3e1d748a3b0f HTTP/1.1\" 200 286 Create-Job "
+ "successful-ok"));
}
TEST_F(AnonymizerToolTest, AnonymizeMACAddresses) {
@@ -95,6 +111,13 @@ TEST_F(AnonymizerToolTest, AnonymizeCustomPatterns) {
"a\nb [SSID=1] [SSID=2] [SSID=foo\nbar] b",
AnonymizeCustomPatterns("a\nb [SSID=foo] [SSID=bar] [SSID=foo\nbar] b"));
+ EXPECT_EQ("SerialNumber: 1",
+ AnonymizeCustomPatterns("SerialNumber: 1217D7EF"));
+ EXPECT_EQ("serial number: 2",
+ AnonymizeCustomPatterns("serial number: 50C971FEE7F3x010900"));
+ EXPECT_EQ("SerialNumber: 3",
+ AnonymizeCustomPatterns("SerialNumber: EVT23-17BA01-004"));
+
EXPECT_EQ("<email: 1>",
AnonymizeCustomPatterns("foo@bar.com"));
EXPECT_EQ("Email: <email: 1>.",
diff --git a/chromium/components/feedback/feedback_data.cc b/chromium/components/feedback/feedback_data.cc
index 215e07dce6c..d46b8b182b1 100644
--- a/chromium/components/feedback/feedback_data.cc
+++ b/chromium/components/feedback/feedback_data.cc
@@ -12,6 +12,7 @@
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
#include "base/values.h"
#include "components/feedback/feedback_util.h"
#include "components/feedback/tracing_manager.h"
@@ -63,8 +64,9 @@ void FeedbackData::SetAndCompressSystemInfo(
if (sys_info) {
++pending_op_count_;
AddLogs(std::move(sys_info));
- BrowserThread::PostBlockingPoolTaskAndReply(
- FROM_HERE, base::Bind(&FeedbackData::CompressLogs, this),
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
+ base::Bind(&FeedbackData::CompressLogs, this),
base::Bind(&FeedbackData::OnCompressComplete, this));
}
}
@@ -76,8 +78,8 @@ void FeedbackData::SetAndCompressHistograms(
if (!histograms)
return;
++pending_op_count_;
- BrowserThread::PostBlockingPoolTaskAndReply(
- FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
base::Bind(&FeedbackData::CompressFile, this,
base::FilePath(kHistogramsFilename), kHistogramsAttachmentName,
base::Passed(&histograms)),
@@ -93,9 +95,10 @@ void FeedbackData::AttachAndCompressFileData(
++pending_op_count_;
base::FilePath attached_file =
base::FilePath::FromUTF8Unsafe(attached_filename_);
- BrowserThread::PostBlockingPoolTaskAndReply(
- FROM_HERE, base::Bind(&FeedbackData::CompressFile, this, attached_file,
- std::string(), base::Passed(&attached_filedata)),
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
+ base::Bind(&FeedbackData::CompressFile, this, attached_file,
+ std::string(), base::Passed(&attached_filedata)),
base::Bind(&FeedbackData::OnCompressComplete, this));
}
diff --git a/chromium/components/feedback/feedback_data_unittest.cc b/chromium/components/feedback/feedback_data_unittest.cc
index d6e353b398e..443d3b53044 100644
--- a/chromium/components/feedback/feedback_data_unittest.cc
+++ b/chromium/components/feedback/feedback_data_unittest.cc
@@ -16,7 +16,6 @@
#include "components/prefs/testing_pref_service.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/test/test_browser_context.h"
-#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,13 +26,10 @@ const char kHistograms[] = "";
const char kImageData[] = "";
const char kFileData[] = "";
-using content::BrowserThread;
-
class MockUploader : public feedback::FeedbackUploader, public KeyedService {
public:
MockUploader(content::BrowserContext* context)
- : FeedbackUploader(context ? context->GetPath() : base::FilePath(),
- BrowserThread::GetBlockingPool()) {}
+ : FeedbackUploader(context ? context->GetPath() : base::FilePath()) {}
MOCK_METHOD1(DispatchReport, void(const std::string&));
};
diff --git a/chromium/components/feedback/feedback_uploader.cc b/chromium/components/feedback/feedback_uploader.cc
index e2781771699..7f8b79672ba 100644
--- a/chromium/components/feedback/feedback_uploader.cc
+++ b/chromium/components/feedback/feedback_uploader.cc
@@ -11,7 +11,7 @@
#include "base/files/file_path.h"
#include "base/sequenced_task_runner.h"
#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
#include "components/feedback/feedback_report.h"
namespace feedback {
@@ -33,22 +33,18 @@ bool FeedbackUploader::ReportsUploadTimeComparator::operator()(
return a->upload_at() > b->upload_at();
}
-FeedbackUploader::FeedbackUploader(const base::FilePath& path,
- base::SequencedWorkerPool* pool)
+FeedbackUploader::FeedbackUploader(const base::FilePath& path)
: report_path_(path.Append(kFeedbackReportPath)),
retry_delay_(base::TimeDelta::FromMinutes(kRetryDelayMinutes)),
- url_(kFeedbackPostUrl),
- pool_(pool) {
+ url_(kFeedbackPostUrl) {
Init();
}
FeedbackUploader::FeedbackUploader(const base::FilePath& path,
- base::SequencedWorkerPool* pool,
const std::string& url)
: report_path_(path.Append(kFeedbackReportPath)),
retry_delay_(base::TimeDelta::FromMinutes(kRetryDelayMinutes)),
- url_(url),
- pool_(pool) {
+ url_(url) {
Init();
}
@@ -92,9 +88,9 @@ void FeedbackUploader::QueueReportWithDelay(const std::string& data,
// Uses a BLOCK_SHUTDOWN file task runner because we really don't want to
// lose reports.
scoped_refptr<base::SequencedTaskRunner> task_runner =
- pool_->GetSequencedTaskRunnerWithShutdownBehavior(
- pool_->GetSequenceToken(),
- base::SequencedWorkerPool::BLOCK_SHUTDOWN);
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
reports_queue_.push(new FeedbackReport(report_path_,
base::Time::Now() + delay,
diff --git a/chromium/components/feedback/feedback_uploader.h b/chromium/components/feedback/feedback_uploader.h
index 2d8e2564e14..1b05727327b 100644
--- a/chromium/components/feedback/feedback_uploader.h
+++ b/chromium/components/feedback/feedback_uploader.h
@@ -11,7 +11,6 @@
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
@@ -26,10 +25,8 @@ class FeedbackReport;
// tried again when it's turn comes up next in the queue.
class FeedbackUploader : public base::SupportsWeakPtr<FeedbackUploader> {
public:
+ FeedbackUploader(const base::FilePath& path);
FeedbackUploader(const base::FilePath& path,
- base::SequencedWorkerPool* pool);
- FeedbackUploader(const base::FilePath& path,
- base::SequencedWorkerPool* pool,
const std::string& url);
virtual ~FeedbackUploader();
@@ -76,7 +73,6 @@ class FeedbackUploader : public base::SupportsWeakPtr<FeedbackUploader> {
ReportDataCallback dispatch_callback_;
base::TimeDelta retry_delay_;
std::string url_;
- base::SequencedWorkerPool* pool_;
DISALLOW_COPY_AND_ASSIGN(FeedbackUploader);
};
diff --git a/chromium/components/feedback/feedback_uploader_chrome.cc b/chromium/components/feedback/feedback_uploader_chrome.cc
index fe99da76a8c..7587e5950d3 100644
--- a/chromium/components/feedback/feedback_uploader_chrome.cc
+++ b/chromium/components/feedback/feedback_uploader_chrome.cc
@@ -10,22 +10,18 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/feedback/feedback_report.h"
#include "components/feedback/feedback_switches.h"
#include "components/feedback/feedback_uploader_delegate.h"
#include "components/variations/net/variations_http_headers.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/load_flags.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "url/gurl.h"
-using content::BrowserThread;
-
namespace feedback {
namespace {
@@ -33,10 +29,8 @@ const char kProtoBufMimeType[] = "application/x-protobuf";
} // namespace
-FeedbackUploaderChrome::FeedbackUploaderChrome(
- content::BrowserContext* context)
- : FeedbackUploader(context ? context->GetPath() : base::FilePath(),
- BrowserThread::GetBlockingPool()),
+FeedbackUploaderChrome::FeedbackUploaderChrome(content::BrowserContext* context)
+ : FeedbackUploader(context ? context->GetPath() : base::FilePath()),
context_(context) {
CHECK(context_);
const base::CommandLine& command_line =
diff --git a/chromium/components/feedback/feedback_uploader_delegate.h b/chromium/components/feedback/feedback_uploader_delegate.h
index 26d74210cf9..b51de3945e9 100644
--- a/chromium/components/feedback/feedback_uploader_delegate.h
+++ b/chromium/components/feedback/feedback_uploader_delegate.h
@@ -14,9 +14,9 @@
namespace feedback {
-// FeedbackUploaderDelegate is a simple http uploader for a feedback report. On
-// succes or failure, it deletes itself, but on failure it also notifies the
-// error callback specified when constructing the class instance.
+// FeedbackUploaderDelegate is a simple HTTP uploader for a feedback report.
+// When finished, it runs the appropriate callback passed in via the
+// constructor, and then deletes itself.
class FeedbackUploaderDelegate : public net::URLFetcherDelegate {
public:
FeedbackUploaderDelegate(const std::string& post_body,
diff --git a/chromium/components/filesystem/BUILD.gn b/chromium/components/filesystem/BUILD.gn
index 65dad2d200c..dc3bc4157d7 100644
--- a/chromium/components/filesystem/BUILD.gn
+++ b/chromium/components/filesystem/BUILD.gn
@@ -51,7 +51,6 @@ service("filesystem") {
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
"//services/service_manager/public/cpp",
- "//services/tracing/public/cpp",
]
}
@@ -76,8 +75,8 @@ service_test("filesystem_service_unittests") {
"//mojo/common",
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
+ "//services/service_manager/public/cpp",
"//services/service_manager/public/cpp:service_test_support",
- "//services/service_manager/public/cpp:sources",
]
data_deps = [
diff --git a/chromium/components/filesystem/DEPS b/chromium/components/filesystem/DEPS
index 26e542410ce..776080079ba 100644
--- a/chromium/components/filesystem/DEPS
+++ b/chromium/components/filesystem/DEPS
@@ -4,5 +4,4 @@ include_rules = [
"+mojo/public",
"+mojo/util",
"+services/service_manager",
- "+services/tracing/public/cpp",
]
diff --git a/chromium/components/filesystem/directory_impl.cc b/chromium/components/filesystem/directory_impl.cc
index 64114de9348..f2f71e60368 100644
--- a/chromium/components/filesystem/directory_impl.cc
+++ b/chromium/components/filesystem/directory_impl.cc
@@ -29,7 +29,7 @@ DirectoryImpl::DirectoryImpl(base::FilePath directory_path,
DirectoryImpl::~DirectoryImpl() {}
-void DirectoryImpl::Read(const ReadCallback& callback) {
+void DirectoryImpl::Read(ReadCallback callback) {
std::vector<mojom::DirectoryEntryPtr> entries;
base::FileEnumerator directory_enumerator(
directory_path_, false,
@@ -44,9 +44,10 @@ void DirectoryImpl::Read(const ReadCallback& callback) {
entries.push_back(std::move(entry));
}
- callback.Run(mojom::FileError::OK,
- entries.empty() ? base::nullopt
- : base::make_optional(std::move(entries)));
+ std::move(callback).Run(mojom::FileError::OK,
+ entries.empty()
+ ? base::nullopt
+ : base::make_optional(std::move(entries)));
}
// TODO(erg): Consider adding an implementation of Stat()/Touch() to the
@@ -57,11 +58,11 @@ void DirectoryImpl::Read(const ReadCallback& callback) {
void DirectoryImpl::OpenFile(const std::string& raw_path,
mojom::FileRequest file,
uint32_t open_flags,
- const OpenFileCallback& callback) {
+ OpenFileCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error);
+ std::move(callback).Run(error);
return;
}
@@ -69,13 +70,13 @@ void DirectoryImpl::OpenFile(const std::string& raw_path,
// We must not return directories as files. In the file abstraction, we can
// fetch raw file descriptors over mojo pipes, and passing a file
// descriptor to a directory is a sandbox escape on Windows.
- callback.Run(mojom::FileError::NOT_A_FILE);
+ std::move(callback).Run(mojom::FileError::NOT_A_FILE);
return;
}
base::File base_file(path, open_flags);
if (!base_file.IsValid()) {
- callback.Run(GetError(base_file));
+ std::move(callback).Run(GetError(base_file));
return;
}
@@ -85,20 +86,20 @@ void DirectoryImpl::OpenFile(const std::string& raw_path,
lock_table_),
std::move(file));
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
void DirectoryImpl::OpenFileHandle(const std::string& raw_path,
uint32_t open_flags,
- const OpenFileHandleCallback& callback) {
+ OpenFileHandleCallback callback) {
base::File file = OpenFileHandleImpl(raw_path, open_flags);
mojom::FileError error = GetError(file);
- callback.Run(error, std::move(file));
+ std::move(callback).Run(error, std::move(file));
}
void DirectoryImpl::OpenFileHandles(
std::vector<mojom::FileOpenDetailsPtr> details,
- const OpenFileHandlesCallback& callback) {
+ OpenFileHandlesCallback callback) {
std::vector<mojom::FileOpenResultPtr> results(details.size());
size_t i = 0;
for (const auto& detail : details) {
@@ -108,23 +109,23 @@ void DirectoryImpl::OpenFileHandles(
result->error = GetError(result->file_handle);
results[i++] = std::move(result);
}
- callback.Run(std::move(results));
+ std::move(callback).Run(std::move(results));
}
void DirectoryImpl::OpenDirectory(const std::string& raw_path,
mojom::DirectoryRequest directory,
uint32_t open_flags,
- const OpenDirectoryCallback& callback) {
+ OpenDirectoryCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error);
+ std::move(callback).Run(error);
return;
}
if (!base::DirectoryExists(path)) {
if (base::PathExists(path)) {
- callback.Run(mojom::FileError::NOT_A_DIRECTORY);
+ std::move(callback).Run(mojom::FileError::NOT_A_DIRECTORY);
return;
}
@@ -132,13 +133,13 @@ void DirectoryImpl::OpenDirectory(const std::string& raw_path,
open_flags & mojom::kFlagCreate)) {
// The directory doesn't exist, and we weren't passed parameters to
// create it.
- callback.Run(mojom::FileError::NOT_FOUND);
+ std::move(callback).Run(mojom::FileError::NOT_FOUND);
return;
}
base::File::Error error;
if (!base::CreateDirectoryAndGetError(path, &error)) {
- callback.Run(static_cast<filesystem::mojom::FileError>(error));
+ std::move(callback).Run(static_cast<filesystem::mojom::FileError>(error));
return;
}
}
@@ -149,117 +150,117 @@ void DirectoryImpl::OpenDirectory(const std::string& raw_path,
std::move(directory));
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
void DirectoryImpl::Rename(const std::string& raw_old_path,
const std::string& raw_new_path,
- const RenameCallback& callback) {
+ RenameCallback callback) {
base::FilePath old_path;
mojom::FileError error =
ValidatePath(raw_old_path, directory_path_, &old_path);
if (error != mojom::FileError::OK) {
- callback.Run(error);
+ std::move(callback).Run(error);
return;
}
base::FilePath new_path;
error = ValidatePath(raw_new_path, directory_path_, &new_path);
if (error != mojom::FileError::OK) {
- callback.Run(error);
+ std::move(callback).Run(error);
return;
}
if (!base::Move(old_path, new_path)) {
- callback.Run(mojom::FileError::FAILED);
+ std::move(callback).Run(mojom::FileError::FAILED);
return;
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
void DirectoryImpl::Delete(const std::string& raw_path,
uint32_t delete_flags,
- const DeleteCallback& callback) {
+ DeleteCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error);
+ std::move(callback).Run(error);
return;
}
bool recursive = delete_flags & mojom::kDeleteFlagRecursive;
if (!base::DeleteFile(path, recursive)) {
- callback.Run(mojom::FileError::FAILED);
+ std::move(callback).Run(mojom::FileError::FAILED);
return;
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
void DirectoryImpl::Exists(const std::string& raw_path,
- const ExistsCallback& callback) {
+ ExistsCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error, false);
+ std::move(callback).Run(error, false);
return;
}
bool exists = base::PathExists(path);
- callback.Run(mojom::FileError::OK, exists);
+ std::move(callback).Run(mojom::FileError::OK, exists);
}
void DirectoryImpl::IsWritable(const std::string& raw_path,
- const IsWritableCallback& callback) {
+ IsWritableCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error, false);
+ std::move(callback).Run(error, false);
return;
}
- callback.Run(mojom::FileError::OK, base::PathIsWritable(path));
+ std::move(callback).Run(mojom::FileError::OK, base::PathIsWritable(path));
}
-void DirectoryImpl::Flush(const FlushCallback& callback) {
+void DirectoryImpl::Flush(FlushCallback callback) {
base::File file(directory_path_,
base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) {
- callback.Run(GetError(file));
+ std::move(callback).Run(GetError(file));
return;
}
if (!file.Flush()) {
- callback.Run(mojom::FileError::FAILED);
+ std::move(callback).Run(mojom::FileError::FAILED);
return;
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
void DirectoryImpl::StatFile(const std::string& raw_path,
- const StatFileCallback& callback) {
+ StatFileCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error, nullptr);
+ std::move(callback).Run(error, nullptr);
return;
}
base::File base_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!base_file.IsValid()) {
- callback.Run(GetError(base_file), nullptr);
+ std::move(callback).Run(GetError(base_file), nullptr);
return;
}
base::File::Info info;
if (!base_file.GetInfo(&info)) {
- callback.Run(mojom::FileError::FAILED, nullptr);
+ std::move(callback).Run(mojom::FileError::FAILED, nullptr);
return;
}
- callback.Run(mojom::FileError::OK, MakeFileInformation(info));
+ std::move(callback).Run(mojom::FileError::OK, MakeFileInformation(info));
}
void DirectoryImpl::Clone(mojom::DirectoryRequest directory) {
@@ -271,22 +272,23 @@ void DirectoryImpl::Clone(mojom::DirectoryRequest directory) {
}
void DirectoryImpl::ReadEntireFile(const std::string& raw_path,
- const ReadEntireFileCallback& callback) {
+ ReadEntireFileCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error, std::vector<uint8_t>());
+ std::move(callback).Run(error, std::vector<uint8_t>());
return;
}
if (base::DirectoryExists(path)) {
- callback.Run(mojom::FileError::NOT_A_FILE, std::vector<uint8_t>());
+ std::move(callback).Run(mojom::FileError::NOT_A_FILE,
+ std::vector<uint8_t>());
return;
}
base::File base_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!base_file.IsValid()) {
- callback.Run(GetError(base_file), std::vector<uint8_t>());
+ std::move(callback).Run(GetError(base_file), std::vector<uint8_t>());
return;
}
@@ -297,28 +299,28 @@ void DirectoryImpl::ReadEntireFile(const std::string& raw_path,
while ((len = base_file.ReadAtCurrentPos(buf.get(), kBufferSize)) > 0)
contents.insert(contents.end(), buf.get(), buf.get() + len);
- callback.Run(mojom::FileError::OK, contents);
+ std::move(callback).Run(mojom::FileError::OK, contents);
}
void DirectoryImpl::WriteFile(const std::string& raw_path,
const std::vector<uint8_t>& data,
- const WriteFileCallback& callback) {
+ WriteFileCallback callback) {
base::FilePath path;
mojom::FileError error = ValidatePath(raw_path, directory_path_, &path);
if (error != mojom::FileError::OK) {
- callback.Run(error);
+ std::move(callback).Run(error);
return;
}
if (base::DirectoryExists(path)) {
- callback.Run(mojom::FileError::NOT_A_FILE);
+ std::move(callback).Run(mojom::FileError::NOT_A_FILE);
return;
}
base::File base_file(path,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
if (!base_file.IsValid()) {
- callback.Run(GetError(base_file));
+ std::move(callback).Run(GetError(base_file));
return;
}
@@ -327,12 +329,12 @@ void DirectoryImpl::WriteFile(const std::string& raw_path,
const int data_size = static_cast<int>(data.size());
if (base_file.Write(0, reinterpret_cast<const char*>(&data.front()),
data_size) == -1) {
- callback.Run(GetError(base_file));
+ std::move(callback).Run(GetError(base_file));
return;
}
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
base::File DirectoryImpl::OpenFileHandleImpl(const std::string& raw_path,
diff --git a/chromium/components/filesystem/directory_impl.h b/chromium/components/filesystem/directory_impl.h
index e226b78508e..755c42cfcb7 100644
--- a/chromium/components/filesystem/directory_impl.h
+++ b/chromium/components/filesystem/directory_impl.h
@@ -30,38 +30,37 @@ class DirectoryImpl : public mojom::Directory {
~DirectoryImpl() override;
// |Directory| implementation:
- void Read(const ReadCallback& callback) override;
+ void Read(ReadCallback callback) override;
void OpenFile(const std::string& path,
mojom::FileRequest file,
uint32_t open_flags,
- const OpenFileCallback& callback) override;
+ OpenFileCallback callback) override;
void OpenFileHandle(const std::string& path,
uint32_t open_flags,
- const OpenFileHandleCallback& callback) override;
+ OpenFileHandleCallback callback) override;
void OpenFileHandles(std::vector<mojom::FileOpenDetailsPtr> details,
- const OpenFileHandlesCallback& callback) override;
+ OpenFileHandlesCallback callback) override;
void OpenDirectory(const std::string& path,
mojom::DirectoryRequest directory,
uint32_t open_flags,
- const OpenDirectoryCallback& callback) override;
+ OpenDirectoryCallback callback) override;
void Rename(const std::string& path,
const std::string& new_path,
- const RenameCallback& callback) override;
+ RenameCallback callback) override;
void Delete(const std::string& path,
uint32_t delete_flags,
- const DeleteCallback& callback) override;
- void Exists(const std::string& path, const ExistsCallback& callback) override;
+ DeleteCallback callback) override;
+ void Exists(const std::string& path, ExistsCallback callback) override;
void IsWritable(const std::string& path,
- const IsWritableCallback& callback) override;
- void Flush(const FlushCallback& callback) override;
- void StatFile(const std::string& path,
- const StatFileCallback& callback) override;
+ IsWritableCallback callback) override;
+ void Flush(FlushCallback callback) override;
+ void StatFile(const std::string& path, StatFileCallback callback) override;
void Clone(mojom::DirectoryRequest directory) override;
void ReadEntireFile(const std::string& path,
- const ReadEntireFileCallback& callback) override;
+ ReadEntireFileCallback callback) override;
void WriteFile(const std::string& path,
const std::vector<uint8_t>& data,
- const WriteFileCallback& callback) override;
+ WriteFileCallback callback) override;
private:
base::File OpenFileHandleImpl(const std::string& raw_path,
diff --git a/chromium/components/filesystem/file_impl.cc b/chromium/components/filesystem/file_impl.cc
index a2c024f3922..12ddb8a8be1 100644
--- a/chromium/components/filesystem/file_impl.cc
+++ b/chromium/components/filesystem/file_impl.cc
@@ -70,43 +70,43 @@ base::File::Error FileImpl::RawUnlockFile() {
return file_.Unlock();
}
-void FileImpl::Close(const CloseCallback& callback) {
+void FileImpl::Close(CloseCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_));
+ std::move(callback).Run(GetError(file_));
return;
}
lock_table_->RemoveFromLockTable(path_);
file_.Close();
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
// TODO(vtl): Move the implementation to a thread pool.
void FileImpl::Read(uint32_t num_bytes_to_read,
int64_t offset,
mojom::Whence whence,
- const ReadCallback& callback) {
+ ReadCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_), base::nullopt);
+ std::move(callback).Run(GetError(file_), base::nullopt);
return;
}
if (num_bytes_to_read > kMaxReadSize) {
- callback.Run(mojom::FileError::INVALID_OPERATION, base::nullopt);
+ std::move(callback).Run(mojom::FileError::INVALID_OPERATION, base::nullopt);
return;
}
mojom::FileError error = IsOffsetValid(offset);
if (error != mojom::FileError::OK) {
- callback.Run(error, base::nullopt);
+ std::move(callback).Run(error, base::nullopt);
return;
}
error = IsWhenceValid(whence);
if (error != mojom::FileError::OK) {
- callback.Run(error, base::nullopt);
+ std::move(callback).Run(error, base::nullopt);
return;
}
if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
- callback.Run(mojom::FileError::FAILED, base::nullopt);
+ std::move(callback).Run(mojom::FileError::FAILED, base::nullopt);
return;
}
@@ -114,22 +114,22 @@ void FileImpl::Read(uint32_t num_bytes_to_read,
int num_bytes_read = file_.ReadAtCurrentPos(
reinterpret_cast<char*>(&bytes_read.front()), num_bytes_to_read);
if (num_bytes_read < 0) {
- callback.Run(mojom::FileError::FAILED, base::nullopt);
+ std::move(callback).Run(mojom::FileError::FAILED, base::nullopt);
return;
}
DCHECK_LE(static_cast<size_t>(num_bytes_read), num_bytes_to_read);
bytes_read.resize(static_cast<size_t>(num_bytes_read));
- callback.Run(mojom::FileError::OK, std::move(bytes_read));
+ std::move(callback).Run(mojom::FileError::OK, std::move(bytes_read));
}
// TODO(vtl): Move the implementation to a thread pool.
void FileImpl::Write(const std::vector<uint8_t>& bytes_to_write,
int64_t offset,
mojom::Whence whence,
- const WriteCallback& callback) {
+ WriteCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_), 0);
+ std::move(callback).Run(GetError(file_), 0);
return;
}
// Who knows what |write()| would return if the size is that big (and it
@@ -140,22 +140,22 @@ void FileImpl::Write(const std::vector<uint8_t>& bytes_to_write,
#else
static_cast<size_t>(std::numeric_limits<ssize_t>::max())) {
#endif
- callback.Run(mojom::FileError::INVALID_OPERATION, 0);
+ std::move(callback).Run(mojom::FileError::INVALID_OPERATION, 0);
return;
}
mojom::FileError error = IsOffsetValid(offset);
if (error != mojom::FileError::OK) {
- callback.Run(error, 0);
+ std::move(callback).Run(error, 0);
return;
}
error = IsWhenceValid(whence);
if (error != mojom::FileError::OK) {
- callback.Run(error, 0);
+ std::move(callback).Run(error, 0);
return;
}
if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
- callback.Run(mojom::FileError::FAILED, 0);
+ std::move(callback).Run(mojom::FileError::FAILED, 0);
return;
}
@@ -165,90 +165,91 @@ void FileImpl::Write(const std::vector<uint8_t>& bytes_to_write,
int num_bytes_written = file_.WriteAtCurrentPos(
buf, static_cast<int>(bytes_to_write.size()));
if (num_bytes_written < 0) {
- callback.Run(mojom::FileError::FAILED, 0);
+ std::move(callback).Run(mojom::FileError::FAILED, 0);
return;
}
DCHECK_LE(static_cast<size_t>(num_bytes_written),
std::numeric_limits<uint32_t>::max());
- callback.Run(mojom::FileError::OK, static_cast<uint32_t>(num_bytes_written));
+ std::move(callback).Run(mojom::FileError::OK,
+ static_cast<uint32_t>(num_bytes_written));
}
-void FileImpl::Tell(const TellCallback& callback) {
- Seek(0, mojom::Whence::FROM_CURRENT, callback);
+void FileImpl::Tell(TellCallback callback) {
+ Seek(0, mojom::Whence::FROM_CURRENT, std::move(callback));
}
void FileImpl::Seek(int64_t offset,
mojom::Whence whence,
- const SeekCallback& callback) {
+ SeekCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_), 0);
+ std::move(callback).Run(GetError(file_), 0);
return;
}
mojom::FileError error = IsOffsetValid(offset);
if (error != mojom::FileError::OK) {
- callback.Run(error, 0);
+ std::move(callback).Run(error, 0);
return;
}
error = IsWhenceValid(whence);
if (error != mojom::FileError::OK) {
- callback.Run(error, 0);
+ std::move(callback).Run(error, 0);
return;
}
int64_t position =
file_.Seek(static_cast<base::File::Whence>(whence), offset);
if (position < 0) {
- callback.Run(mojom::FileError::FAILED, 0);
+ std::move(callback).Run(mojom::FileError::FAILED, 0);
return;
}
- callback.Run(mojom::FileError::OK, static_cast<int64_t>(position));
+ std::move(callback).Run(mojom::FileError::OK, static_cast<int64_t>(position));
}
-void FileImpl::Stat(const StatCallback& callback) {
+void FileImpl::Stat(StatCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_), nullptr);
+ std::move(callback).Run(GetError(file_), nullptr);
return;
}
base::File::Info info;
if (!file_.GetInfo(&info)) {
- callback.Run(mojom::FileError::FAILED, nullptr);
+ std::move(callback).Run(mojom::FileError::FAILED, nullptr);
return;
}
- callback.Run(mojom::FileError::OK, MakeFileInformation(info));
+ std::move(callback).Run(mojom::FileError::OK, MakeFileInformation(info));
}
-void FileImpl::Truncate(int64_t size, const TruncateCallback& callback) {
+void FileImpl::Truncate(int64_t size, TruncateCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_));
+ std::move(callback).Run(GetError(file_));
return;
}
if (size < 0) {
- callback.Run(mojom::FileError::INVALID_OPERATION);
+ std::move(callback).Run(mojom::FileError::INVALID_OPERATION);
return;
}
mojom::FileError error = IsOffsetValid(size);
if (error != mojom::FileError::OK) {
- callback.Run(error);
+ std::move(callback).Run(error);
return;
}
if (!file_.SetLength(size)) {
- callback.Run(mojom::FileError::NOT_FOUND);
+ std::move(callback).Run(mojom::FileError::NOT_FOUND);
return;
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
void FileImpl::Touch(mojom::TimespecOrNowPtr atime,
mojom::TimespecOrNowPtr mtime,
- const TouchCallback& callback) {
+ TouchCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_));
+ std::move(callback).Run(GetError(file_));
return;
}
@@ -256,7 +257,7 @@ void FileImpl::Touch(mojom::TimespecOrNowPtr atime,
if (!atime) {
base::File::Info info;
if (!file_.GetInfo(&info)) {
- callback.Run(mojom::FileError::FAILED);
+ std::move(callback).Run(mojom::FileError::FAILED);
return;
}
@@ -269,7 +270,7 @@ void FileImpl::Touch(mojom::TimespecOrNowPtr atime,
if (!mtime) {
base::File::Info info;
if (!file_.GetInfo(&info)) {
- callback.Run(mojom::FileError::FAILED);
+ std::move(callback).Run(mojom::FileError::FAILED);
return;
}
@@ -279,18 +280,18 @@ void FileImpl::Touch(mojom::TimespecOrNowPtr atime,
}
file_.SetTimes(base_atime, base_mtime);
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
-void FileImpl::Dup(mojom::FileRequest file, const DupCallback& callback) {
+void FileImpl::Dup(mojom::FileRequest file, DupCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_));
+ std::move(callback).Run(GetError(file_));
return;
}
base::File new_file = file_.Duplicate();
if (!new_file.IsValid()) {
- callback.Run(GetError(new_file));
+ std::move(callback).Run(GetError(new_file));
return;
}
@@ -300,44 +301,45 @@ void FileImpl::Dup(mojom::FileRequest file, const DupCallback& callback) {
lock_table_),
std::move(file));
}
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
-void FileImpl::Flush(const FlushCallback& callback) {
+void FileImpl::Flush(FlushCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_));
+ std::move(callback).Run(GetError(file_));
return;
}
bool ret = file_.Flush();
- callback.Run(ret ? mojom::FileError::OK : mojom::FileError::FAILED);
+ std::move(callback).Run(ret ? mojom::FileError::OK
+ : mojom::FileError::FAILED);
}
-void FileImpl::Lock(const LockCallback& callback) {
- callback.Run(
+void FileImpl::Lock(LockCallback callback) {
+ std::move(callback).Run(
static_cast<filesystem::mojom::FileError>(lock_table_->LockFile(this)));
}
-void FileImpl::Unlock(const UnlockCallback& callback) {
- callback.Run(
+void FileImpl::Unlock(UnlockCallback callback) {
+ std::move(callback).Run(
static_cast<filesystem::mojom::FileError>(lock_table_->UnlockFile(this)));
}
-void FileImpl::AsHandle(const AsHandleCallback& callback) {
+void FileImpl::AsHandle(AsHandleCallback callback) {
if (!file_.IsValid()) {
- callback.Run(GetError(file_), base::File());
+ std::move(callback).Run(GetError(file_), base::File());
return;
}
base::File new_file = file_.Duplicate();
if (!new_file.IsValid()) {
- callback.Run(GetError(new_file), base::File());
+ std::move(callback).Run(GetError(new_file), base::File());
return;
}
base::File::Info info;
if (!new_file.GetInfo(&info)) {
- callback.Run(mojom::FileError::FAILED, base::File());
+ std::move(callback).Run(mojom::FileError::FAILED, base::File());
return;
}
@@ -346,11 +348,11 @@ void FileImpl::AsHandle(const AsHandleCallback& callback) {
// passing a file descriptor to a directory is a sandbox escape on Windows,
// we should be absolutely paranoid.
if (info.is_directory) {
- callback.Run(mojom::FileError::NOT_A_FILE, base::File());
+ std::move(callback).Run(mojom::FileError::NOT_A_FILE, base::File());
return;
}
- callback.Run(mojom::FileError::OK, std::move(new_file));
+ std::move(callback).Run(mojom::FileError::OK, std::move(new_file));
}
} // namespace filesystem
diff --git a/chromium/components/filesystem/file_impl.h b/chromium/components/filesystem/file_impl.h
index fdcb5c3d54e..550f43b22a7 100644
--- a/chromium/components/filesystem/file_impl.h
+++ b/chromium/components/filesystem/file_impl.h
@@ -45,29 +45,29 @@ class FileImpl : public mojom::File {
const base::FilePath& path() const { return path_; }
// |File| implementation:
- void Close(const CloseCallback& callback) override;
+ void Close(CloseCallback callback) override;
void Read(uint32_t num_bytes_to_read,
int64_t offset,
mojom::Whence whence,
- const ReadCallback& callback) override;
+ ReadCallback callback) override;
void Write(const std::vector<uint8_t>& bytes_to_write,
int64_t offset,
mojom::Whence whence,
- const WriteCallback& callback) override;
- void Tell(const TellCallback& callback) override;
+ WriteCallback callback) override;
+ void Tell(TellCallback callback) override;
void Seek(int64_t offset,
mojom::Whence whence,
- const SeekCallback& callback) override;
- void Stat(const StatCallback& callback) override;
- void Truncate(int64_t size, const TruncateCallback& callback) override;
+ SeekCallback callback) override;
+ void Stat(StatCallback callback) override;
+ void Truncate(int64_t size, TruncateCallback callback) override;
void Touch(mojom::TimespecOrNowPtr atime,
mojom::TimespecOrNowPtr mtime,
- const TouchCallback& callback) override;
- void Dup(mojom::FileRequest file, const DupCallback& callback) override;
- void Flush(const FlushCallback& callback) override;
- void Lock(const LockCallback& callback) override;
- void Unlock(const UnlockCallback& callback) override;
- void AsHandle(const AsHandleCallback& callback) override;
+ TouchCallback callback) override;
+ void Dup(mojom::FileRequest file, DupCallback callback) override;
+ void Flush(FlushCallback callback) override;
+ void Lock(LockCallback callback) override;
+ void Unlock(UnlockCallback callback) override;
+ void AsHandle(AsHandleCallback callback) override;
private:
base::File file_;
diff --git a/chromium/components/filesystem/file_system_app.cc b/chromium/components/filesystem/file_system_app.cc
index c54639cea37..fc89c115e08 100644
--- a/chromium/components/filesystem/file_system_app.cc
+++ b/chromium/components/filesystem/file_system_app.cc
@@ -12,7 +12,6 @@
#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
#include "services/service_manager/public/cpp/service_context.h"
#if defined(OS_WIN)
@@ -39,29 +38,28 @@ const char kUserDataDir[] = "user-data-dir";
} // namespace filesystem
FileSystemApp::FileSystemApp() : lock_table_(new LockTable) {
- registry_.AddInterface<mojom::FileSystem>(this);
+ registry_.AddInterface<mojom::FileSystem>(
+ base::Bind(&FileSystemApp::Create, base::Unretained(this)));
}
FileSystemApp::~FileSystemApp() {}
-void FileSystemApp::OnStart() {
- tracing_.Initialize(context()->connector(), context()->identity().name());
-}
+void FileSystemApp::OnStart() {}
void FileSystemApp::OnBindInterface(
- const service_manager::ServiceInfo& source_info,
+ const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
- registry_.BindInterface(source_info.identity, interface_name,
+ registry_.BindInterface(source_info, interface_name,
std::move(interface_pipe));
}
-// |InterfaceFactory<Files>| implementation:
-void FileSystemApp::Create(const service_manager::Identity& remote_identity,
+void FileSystemApp::Create(const service_manager::BindSourceInfo& source_info,
mojom::FileSystemRequest request) {
- mojo::MakeStrongBinding(base::MakeUnique<FileSystemImpl>(
- remote_identity, GetUserDataDir(), lock_table_),
- std::move(request));
+ mojo::MakeStrongBinding(
+ base::MakeUnique<FileSystemImpl>(source_info.identity, GetUserDataDir(),
+ lock_table_),
+ std::move(request));
}
//static
diff --git a/chromium/components/filesystem/file_system_app.h b/chromium/components/filesystem/file_system_app.h
index 7035393eda1..b4a70f73740 100644
--- a/chromium/components/filesystem/file_system_app.h
+++ b/chromium/components/filesystem/file_system_app.h
@@ -11,15 +11,11 @@
#include "components/filesystem/lock_table.h"
#include "components/filesystem/public/interfaces/file_system.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
-#include "services/service_manager/public/cpp/interface_factory.h"
#include "services/service_manager/public/cpp/service.h"
-#include "services/tracing/public/cpp/provider.h"
namespace filesystem {
-class FileSystemApp
- : public service_manager::Service,
- public service_manager::InterfaceFactory<mojom::FileSystem> {
+class FileSystemApp : public service_manager::Service {
public:
FileSystemApp();
~FileSystemApp() override;
@@ -30,15 +26,12 @@ class FileSystemApp
// |service_manager::Service| override:
void OnStart() override;
- void OnBindInterface(const service_manager::ServiceInfo& source_info,
+ void OnBindInterface(const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
- // |InterfaceFactory<Files>| implementation:
- void Create(const service_manager::Identity& remote_identity,
- mojo::InterfaceRequest<mojom::FileSystem> request) override;
-
- tracing::Provider tracing_;
+ void Create(const service_manager::BindSourceInfo& source_info,
+ mojom::FileSystemRequest request);
service_manager::BinderRegistry registry_;
diff --git a/chromium/components/filesystem/file_system_impl.cc b/chromium/components/filesystem/file_system_impl.cc
index 138524d5394..59e84de2451 100644
--- a/chromium/components/filesystem/file_system_impl.cc
+++ b/chromium/components/filesystem/file_system_impl.cc
@@ -34,9 +34,8 @@ FileSystemImpl::FileSystemImpl(const service_manager::Identity& remote_identity,
FileSystemImpl::~FileSystemImpl() {
}
-void FileSystemImpl::OpenTempDirectory(
- mojom::DirectoryRequest directory,
- const OpenTempDirectoryCallback& callback) {
+void FileSystemImpl::OpenTempDirectory(mojom::DirectoryRequest directory,
+ OpenTempDirectoryCallback callback) {
// Set only if the |DirectoryImpl| will own a temporary directory.
std::unique_ptr<base::ScopedTempDir> temp_dir(new base::ScopedTempDir);
CHECK(temp_dir->CreateUniqueTempDir());
@@ -47,12 +46,12 @@ void FileSystemImpl::OpenTempDirectory(
mojo::MakeStrongBinding(base::MakeUnique<DirectoryImpl>(
path, std::move(shared_temp_dir), lock_table_),
std::move(directory));
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
void FileSystemImpl::OpenPersistentFileSystem(
mojo::InterfaceRequest<mojom::Directory> directory,
- const OpenPersistentFileSystemCallback& callback) {
+ OpenPersistentFileSystemCallback callback) {
std::unique_ptr<base::ScopedTempDir> temp_dir;
base::FilePath path = persistent_dir_;
if (!base::PathExists(path))
@@ -64,7 +63,7 @@ void FileSystemImpl::OpenPersistentFileSystem(
mojo::MakeStrongBinding(base::MakeUnique<DirectoryImpl>(
path, std::move(shared_temp_dir), lock_table_),
std::move(directory));
- callback.Run(mojom::FileError::OK);
+ std::move(callback).Run(mojom::FileError::OK);
}
} // namespace filesystem
diff --git a/chromium/components/filesystem/file_system_impl.h b/chromium/components/filesystem/file_system_impl.h
index 7f41b357804..6538077a862 100644
--- a/chromium/components/filesystem/file_system_impl.h
+++ b/chromium/components/filesystem/file_system_impl.h
@@ -35,10 +35,10 @@ class FileSystemImpl : public mojom::FileSystem {
// |Files| implementation:
void OpenTempDirectory(mojom::DirectoryRequest directory,
- const OpenTempDirectoryCallback& callback) override;
+ OpenTempDirectoryCallback callback) override;
void OpenPersistentFileSystem(
mojom::DirectoryRequest directory,
- const OpenPersistentFileSystemCallback& callback) override;
+ OpenPersistentFileSystemCallback callback) override;
private:
const std::string remote_application_name_;
diff --git a/chromium/components/flags_ui/OWNERS b/chromium/components/flags_ui/OWNERS
index 506ff92d665..6fc413e5b5a 100644
--- a/chromium/components/flags_ui/OWNERS
+++ b/chromium/components/flags_ui/OWNERS
@@ -1,4 +1,4 @@
-file://ui/webui/OWNERS
+file://ui/webui/PLATFORM_OWNERS
asvitkine@chromium.org
diff --git a/chromium/components/flags_ui/PRESUBMIT.py b/chromium/components/flags_ui/PRESUBMIT.py
new file mode 100644
index 00000000000..5b4c471b83b
--- /dev/null
+++ b/chromium/components/flags_ui/PRESUBMIT.py
@@ -0,0 +1,25 @@
+# Copyright 2017 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.
+
+
+def _CommonChecks(input_api, output_api):
+ results = []
+ try:
+ import sys
+ old_sys_path = sys.path[:]
+ cwd = input_api.PresubmitLocalPath()
+ sys.path += [input_api.os_path.join(cwd, '..', '..', 'tools')]
+ import web_dev_style.presubmit_support
+ results += web_dev_style.presubmit_support.CheckStyle(input_api, output_api)
+ finally:
+ sys.path = old_sys_path
+ return results
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
diff --git a/chromium/components/flags_ui/resources/flags.css b/chromium/components/flags_ui/resources/flags.css
index d73b13ca457..f4eabeccb6b 100644
--- a/chromium/components/flags_ui/resources/flags.css
+++ b/chromium/components/flags_ui/resources/flags.css
@@ -163,10 +163,7 @@ div.needs-restart {
box-shadow: 0 -2px 2px #ddd;
box-sizing: border-box;
left: 0;
- padding-bottom: 15px;
- padding-left: 15px;
- padding-right: 15px;
- padding-top: 15px;
+ padding: 15px;
position: fixed;
width: 100%;
}
diff --git a/chromium/components/font_service/BUILD.gn b/chromium/components/font_service/BUILD.gn
index 3da22f6b5c1..250b3aba256 100644
--- a/chromium/components/font_service/BUILD.gn
+++ b/chromium/components/font_service/BUILD.gn
@@ -18,7 +18,6 @@ source_set("lib") {
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
"//services/service_manager/public/cpp",
- "//services/tracing/public/cpp",
]
public_deps = [
diff --git a/chromium/components/font_service/DEPS b/chromium/components/font_service/DEPS
index a32f59c6a0f..5504d41f9a2 100644
--- a/chromium/components/font_service/DEPS
+++ b/chromium/components/font_service/DEPS
@@ -2,7 +2,6 @@ include_rules = [
"+services/service_manager",
"+mojo/common",
"+mojo/public",
- "+services/tracing/public/cpp",
"+skia",
"+third_party/skia/include",
]
diff --git a/chromium/components/font_service/font_service_app.cc b/chromium/components/font_service/font_service_app.cc
index 5dfe5f919ee..7a78c81af4f 100644
--- a/chromium/components/font_service/font_service_app.cc
+++ b/chromium/components/font_service/font_service_app.cc
@@ -40,32 +40,25 @@ base::File GetFileForPath(const base::FilePath& path) {
namespace font_service {
FontServiceApp::FontServiceApp() {
- registry_.AddInterface(this);
+ registry_.AddInterface(
+ base::Bind(&FontServiceApp::Create, base::Unretained(this)));
}
FontServiceApp::~FontServiceApp() {}
-void FontServiceApp::OnStart() {
- tracing_.Initialize(context()->connector(), context()->identity().name());
-}
+void FontServiceApp::OnStart() {}
void FontServiceApp::OnBindInterface(
- const service_manager::ServiceInfo& source_info,
+ const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
- registry_.BindInterface(source_info.identity, interface_name,
+ registry_.BindInterface(source_info, interface_name,
std::move(interface_pipe));
}
-void FontServiceApp::Create(
- const service_manager::Identity& remote_identity,
- mojo::InterfaceRequest<mojom::FontService> request) {
- bindings_.AddBinding(this, std::move(request));
-}
-
void FontServiceApp::MatchFamilyName(const std::string& family_name,
mojom::TypefaceStylePtr requested_style,
- const MatchFamilyNameCallback& callback) {
+ MatchFamilyNameCallback callback) {
SkFontConfigInterface::FontIdentity result_identity;
SkString result_family;
SkFontStyle result_style;
@@ -83,7 +76,7 @@ void FontServiceApp::MatchFamilyName(const std::string& family_name,
style->weight = SkFontStyle().weight();
style->width = SkFontStyle().width();
style->slant = static_cast<mojom::TypefaceSlant>(SkFontStyle().slant());
- callback.Run(nullptr, "", std::move(style));
+ std::move(callback).Run(nullptr, "", std::move(style));
return;
}
@@ -101,17 +94,23 @@ void FontServiceApp::MatchFamilyName(const std::string& family_name,
style->width = result_style.width();
style->slant = static_cast<mojom::TypefaceSlant>(result_style.slant());
- callback.Run(std::move(identity), result_family.c_str(), std::move(style));
+ std::move(callback).Run(std::move(identity), result_family.c_str(),
+ std::move(style));
}
void FontServiceApp::OpenStream(uint32_t id_number,
- const OpenStreamCallback& callback) {
+ OpenStreamCallback callback) {
base::File file;
if (id_number < static_cast<uint32_t>(paths_.size())) {
file = GetFileForPath(base::FilePath(paths_[id_number].c_str()));
}
- callback.Run(std::move(file));
+ std::move(callback).Run(std::move(file));
+}
+
+void FontServiceApp::Create(const service_manager::BindSourceInfo& source_info,
+ mojom::FontServiceRequest request) {
+ bindings_.AddBinding(this, std::move(request));
}
int FontServiceApp::FindOrAddPath(const SkString& path) {
diff --git a/chromium/components/font_service/font_service_app.h b/chromium/components/font_service/font_service_app.h
index ddad2541748..c60c315d8f6 100644
--- a/chromium/components/font_service/font_service_app.h
+++ b/chromium/components/font_service/font_service_app.h
@@ -12,17 +12,13 @@
#include "components/font_service/public/interfaces/font_service.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/binder_registry.h"
-#include "services/service_manager/public/cpp/interface_factory.h"
#include "services/service_manager/public/cpp/service.h"
-#include "services/tracing/public/cpp/provider.h"
#include "skia/ext/skia_utils_base.h"
namespace font_service {
-class FontServiceApp
- : public service_manager::Service,
- public service_manager::InterfaceFactory<mojom::FontService>,
- public mojom::FontService {
+class FontServiceApp : public service_manager::Service,
+ public mojom::FontService {
public:
FontServiceApp();
~FontServiceApp() override;
@@ -30,28 +26,24 @@ class FontServiceApp
private:
// service_manager::Service:
void OnStart() override;
- void OnBindInterface(const service_manager::ServiceInfo& source_info,
+ void OnBindInterface(const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
- // service_manager::InterfaceFactory<mojom::FontService>:
- void Create(const service_manager::Identity& remote_identity,
- mojo::InterfaceRequest<mojom::FontService> request) override;
-
// FontService:
void MatchFamilyName(const std::string& family_name,
mojom::TypefaceStylePtr requested_style,
- const MatchFamilyNameCallback& callback) override;
- void OpenStream(uint32_t id_number,
- const OpenStreamCallback& callback) override;
+ MatchFamilyNameCallback callback) override;
+ void OpenStream(uint32_t id_number, OpenStreamCallback callback) override;
+
+ void Create(const service_manager::BindSourceInfo& source_info,
+ mojom::FontServiceRequest request);
int FindOrAddPath(const SkString& path);
service_manager::BinderRegistry registry_;
mojo::BindingSet<mojom::FontService> bindings_;
- tracing::Provider tracing_;
-
// We don't want to leak paths to our callers; we thus enumerate the paths of
// fonts.
std::vector<SkString> paths_;
diff --git a/chromium/components/gcm_driver/crypto/BUILD.gn b/chromium/components/gcm_driver/crypto/BUILD.gn
index 62aa7179312..20d24ee5f85 100644
--- a/chromium/components/gcm_driver/crypto/BUILD.gn
+++ b/chromium/components/gcm_driver/crypto/BUILD.gn
@@ -14,6 +14,8 @@ static_library("crypto") {
"gcm_key_store.h",
"gcm_message_cryptographer.cc",
"gcm_message_cryptographer.h",
+ "message_payload_parser.cc",
+ "message_payload_parser.h",
"p256_key_util.cc",
"p256_key_util.h",
]
@@ -52,6 +54,7 @@ source_set("unit_tests") {
"gcm_encryption_provider_unittest.cc",
"gcm_key_store_unittest.cc",
"gcm_message_cryptographer_unittest.cc",
+ "message_payload_parser_unittest.cc",
"p256_key_util_unittest.cc",
]
diff --git a/chromium/components/google/core/browser/google_tld_list.h b/chromium/components/google/core/browser/google_tld_list.h
index 6a246cf38ec..b6961828849 100644
--- a/chromium/components/google/core/browser/google_tld_list.h
+++ b/chromium/components/google/core/browser/google_tld_list.h
@@ -10,39 +10,34 @@
#define GOOGLE_TLD_LIST "ac", "ad", "ae", "af", "ag", "al", "am", "as", "at", \
"aw", "az", "ba", "be", "bf", "bg", "bi", "biz", "bj", "bm", "bn", "bo", "bs", \
-"bt", "by", "bz", "ca", "cat", "cc", "cd", "cf", "cg", "ch", "ci", "cl", "cm", \
-"cn", "co", "co.ao", "co.at", "co.ba", "co.bi", "co.bw", "co.ci", "co.ck", \
-"co.cr", "co.gg", "co.gl", "co.gy", "co.hu", "co.id", "co.il", "co.im", \
-"co.in", "co.it", "co.je", "co.jp", "co.ke", "co.kr", "co.ls", "co.ma", \
-"co.mu", "co.mw", "co.mz", "co.nz", "co.pn", "co.rs", "co.th", "co.tt", \
-"co.tz", "co.ua", "co.ug", "co.uk", "co.uz", "co.ve", "co.vi", "co.za", \
-"co.zm", "co.zw", "com", "com.af", "com.ag", "com.ai", "com.ar", "com.au", \
-"com.az", "com.bd", "com.bh", "com.bi", "com.bn", "com.bo", "com.br", \
-"com.bs", "com.by", "com.bz", "com.cn", "com.co", "com.cu", "com.cy", \
-"com.do", "com.dz", "com.ec", "com.eg", "com.er", "com.et", "com.fj", \
-"com.ge", "com.gh", "com.gi", "com.gl", "com.gp", "com.gr", "com.gt", \
-"com.gy", "com.hk", "com.hn", "com.hr", "com.ht", "com.iq", "com.jm", \
-"com.jo", "com.kg", "com.kh", "com.ki", "com.kw", "com.kz", "com.lb", \
-"com.lc", "com.lk", "com.lv", "com.ly", "com.mk", "com.mm", "com.mt", \
-"com.mu", "com.mw", "com.mx", "com.my", "com.na", "com.nc", "com.nf", \
-"com.ng", "com.ni", "com.np", "com.nr", "com.om", "com.pa", "com.pe", \
-"com.pg", "com.ph", "com.pk", "com.pl", "com.pr", "com.ps", "com.pt", \
-"com.py", "com.qa", "com.ru", "com.sa", "com.sb", "com.sc", "com.sg", \
-"com.sl", "com.sv", "com.tj", "com.tm", "com.tn", "com.tr", "com.tt", \
-"com.tw", "com.ua", "com.uy", "com.uz", "com.vc", "com.ve", "com.vi", \
-"com.vn", "com.ws", "cv", "cx", "cz", "de", "dj", "dk", "dm", "do", "dz", \
-"ec", "ee", "es", "eu", "fi", "fm", "fr", "ga", "gd", "ge", "gf", "gg", "gl", \
-"gm", "gp", "gr", "gw", "gy", "hk", "hn", "hr", "ht", "hu", "ie", "im", "in", \
-"in.rs", "info", "io", "iq", "is", "it", "it.ao", "je", "jo", "jobs", "jp", \
-"kg", "ki", "kids.us", "km", "kn", "kr", "kz", "la", "li", "lk", "lt", "lu", \
-"lv", "ma", "md", "me", "mg", "mh", "mk", "ml", "mn", "mobi", "mr", "ms", \
-"mu", "mv", "mw", "mx", "name", "ne", "ne.jp", "net", "net.in", "net.nz", \
-"nf", "ng", "nl", "no", "nom.es", "nr", "nu", "off.ai", "org", "org.af", \
-"org.es", "org.in", "org.nz", "org.uk", "pf", "ph", "pk", "pl", "pn", "pr", \
-"pro", "ps", "pt", "qa", "re", "ro", "rs", "ru", "rw", "sc", "se", "sg", "sh", \
-"si", "sk", "sl", "sm", "sn", "so", "sr", "st", "sz", "td", "tel", "tg", "tk", \
-"tl", "tm", "tn", "to", "tt", "tv", "tw", "ua", "ug", "us", "uz", "vc", "vg", \
-"vn", "vu", "ws", "yt"
+"bt", "by", "ca", "cat", "cc", "cd", "cf", "cg", "ch", "ci", "cl", "cm", "cn", \
+"co", "co.ao", "co.at", "co.bw", "co.ck", "co.cr", "co.gg", "co.gy", "co.hu", \
+"co.id", "co.il", "co.im", "co.in", "co.je", "co.jp", "co.ke", "co.kr", \
+"co.ls", "co.ma", "co.mz", "co.nz", "co.rs", "co.th", "co.tz", "co.ua", \
+"co.ug", "co.uk", "co.uz", "co.ve", "co.vi", "co.za", "co.zm", "co.zw", "com", \
+"com.af", "com.ag", "com.ai", "com.ar", "com.au", "com.az", "com.bd", \
+"com.bh", "com.bi", "com.bn", "com.bo", "com.br", "com.by", "com.bz", \
+"com.cn", "com.co", "com.cu", "com.cy", "com.do", "com.dz", "com.ec", \
+"com.eg", "com.er", "com.et", "com.fj", "com.ge", "com.gh", "com.gi", \
+"com.gp", "com.gr", "com.gt", "com.gy", "com.hk", "com.ht", "com.iq", \
+"com.jm", "com.jo", "com.kh", "com.kw", "com.kz", "com.lb", "com.lv", \
+"com.ly", "com.mm", "com.mt", "com.mx", "com.my", "com.na", "com.nc", \
+"com.nf", "com.ng", "com.ni", "com.np", "com.nr", "com.om", "com.pa", \
+"com.pe", "com.pg", "com.ph", "com.pk", "com.pl", "com.pr", "com.ps", \
+"com.pt", "com.py", "com.qa", "com.ru", "com.sa", "com.sb", "com.sg", \
+"com.sl", "com.sv", "com.tj", "com.tm", "com.tn", "com.tr", "com.tw", \
+"com.ua", "com.uy", "com.vc", "com.ve", "com.vn", "cv", "cz", "de", "dj", \
+"dk", "dm", "do", "dz", "ec", "ee", "es", "eu", "fi", "fm", "fr", "ga", "gd", \
+"ge", "gf", "gg", "gl", "gm", "gp", "gr", "gw", "gy", "hk", "hn", "hr", "ht", \
+"hu", "ie", "im", "in", "info", "io", "iq", "is", "it", "it.ao", "je", "jo", \
+"jobs", "jp", "kg", "ki", "km", "kr", "kz", "la", "li", "lk", "lt", "lu", \
+"lv", "ma", "md", "me", "mg", "mh", "mk", "ml", "mn", "mr", "ms", "mu", "mv", \
+"mw", "mx", "name", "ne", "ne.jp", "net", "net.nz", "ng", "nl", "no", \
+"nom.es", "nr", "nu", "off.ai", "org", "org.es", "org.nz", "org.uk", "pf", \
+"ph", "pk", "pl", "pn", "pro", "ps", "pt", "qa", "re", "ro", "rs", "ru", "rw", \
+"sc", "se", "sg", "sh", "si", "sk", "sl", "sm", "sn", "so", "sr", "st", "sz", \
+"td", "tel", "tg", "tk", "tl", "tm", "tn", "to", "tt", "tv", "tw", "ua", "us", \
+"uz", "vg", "vn", "vu", "ws", "yt"
#endif // COMPONENTS_GOOGLE_CORE_BROWSER_GOOGLE_TLD_LIST_H_
diff --git a/chromium/components/google/core/browser/google_url_tracker.h b/chromium/components/google/core/browser/google_url_tracker.h
index 5d0ba62a4e3..e98af1376e2 100644
--- a/chromium/components/google/core/browser/google_url_tracker.h
+++ b/chromium/components/google/core/browser/google_url_tracker.h
@@ -26,8 +26,7 @@ class PrefRegistrySyncable;
// change. The current value is saved to prefs.
//
// Most consumers should only call google_url(). Consumers who need to be
-// notified when things change should register a callback that provides the
-// original and updated values via RegisterCallback().
+// notified when things change should use RegisterCallback().
//
// To protect users' privacy and reduce server load, no updates will be
// performed (ever) unless at least one consumer registers interest by calling
@@ -37,8 +36,7 @@ class GoogleURLTracker
public net::NetworkChangeNotifier::NetworkChangeObserver,
public KeyedService {
public:
- // Callback that is called when the Google URL is updated. The arguments are
- // the old and new URLs.
+ // Callback that is called when the Google URL is updated.
typedef base::Callback<void()> OnGoogleURLUpdatedCallback;
typedef base::CallbackList<void()> CallbackList;
typedef CallbackList::Subscription Subscription;
diff --git a/chromium/components/google/core/browser/google_util.cc b/chromium/components/google/core/browser/google_util.cc
index a16d55eaafd..b8f8c1daa9e 100644
--- a/chromium/components/google/core/browser/google_util.cc
+++ b/chromium/components/google/core/browser/google_util.cc
@@ -45,6 +45,12 @@ bool IsPathHomePageBase(base::StringPiece path) {
return (path == "/") || (path == "/webhp");
}
+// Removes a single trailing dot if present in |host|.
+void StripTrailingDot(base::StringPiece* host) {
+ if (host->ends_with("."))
+ host->remove_suffix(1);
+}
+
// True if the given canonical |host| is "[www.]<domain_in_lower_case>.<TLD>"
// with a valid TLD. If |subdomain_permission| is ALLOW_SUBDOMAIN, we check
// against host "*.<domain_in_lower_case>.<TLD>" instead. Will return the TLD
@@ -104,11 +110,31 @@ bool IsCanonicalHostGoogleHostname(base::StringPiece canonical_host,
if (!IsValidHostName(canonical_host, "google", subdomain_permission, &tld))
return false;
+ // Remove the trailing dot from tld if present, as for google domain it's the
+ // same page.
+ StripTrailingDot(&tld);
+
CR_DEFINE_STATIC_LOCAL(std::set<std::string>, google_tlds,
({GOOGLE_TLD_LIST}));
return base::ContainsKey(google_tlds, tld.as_string());
}
+// True if |url| is a valid URL with a host that is in the static list of
+// Google subdomains for google search, and an HTTP or HTTPS scheme. Requires
+// |url| to use the standard port for its scheme (80 for HTTP, 443 for HTTPS).
+bool IsGoogleSearchSubdomainUrl(const GURL& url) {
+ if (!IsValidURL(url, PortPermission::DISALLOW_NON_STANDARD_PORTS))
+ return false;
+
+ base::StringPiece host(url.host_piece());
+ StripTrailingDot(&host);
+
+ CR_DEFINE_STATIC_LOCAL(std::set<std::string>, google_subdomains,
+ ({"ipv4.google.com", "ipv6.google.com"}));
+
+ return base::ContainsKey(google_subdomains, host.as_string());
+}
+
} // namespace
// Global functions -----------------------------------------------------------
@@ -148,10 +174,10 @@ GURL AppendGoogleLocaleParam(const GURL& url,
std::string GetGoogleCountryCode(const GURL& google_homepage_url) {
base::StringPiece google_hostname = google_homepage_url.host_piece();
+ // TODO(igorcov): This needs a fix for case when the host has a trailing dot,
+ // like "google.com./". https://crbug.com/720295.
const size_t last_dot = google_hostname.find_last_of('.');
- if (last_dot == std::string::npos) {
- NOTREACHED();
- }
+ DCHECK_NE(std::string::npos, last_dot);
base::StringPiece country_code = google_hostname.substr(last_dot + 1);
// Assume the com TLD implies the US.
if (country_code == "com")
@@ -217,8 +243,11 @@ bool IsGoogleDomainUrl(const GURL& url,
bool IsGoogleHomePageUrl(const GURL& url) {
// First check to see if this has a Google domain.
- if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN, DISALLOW_NON_STANDARD_PORTS))
+ if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN,
+ DISALLOW_NON_STANDARD_PORTS) &&
+ !IsGoogleSearchSubdomainUrl(url)) {
return false;
+ }
// Make sure the path is a known home page path.
base::StringPiece path(url.path_piece());
@@ -228,8 +257,11 @@ bool IsGoogleHomePageUrl(const GURL& url) {
bool IsGoogleSearchUrl(const GURL& url) {
// First check to see if this has a Google domain.
- if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN, DISALLOW_NON_STANDARD_PORTS))
+ if (!IsGoogleDomainUrl(url, DISALLOW_SUBDOMAIN,
+ DISALLOW_NON_STANDARD_PORTS) &&
+ !IsGoogleSearchSubdomainUrl(url)) {
return false;
+ }
// Make sure the path is a known search path.
base::StringPiece path(url.path_piece());
diff --git a/chromium/components/google/core/browser/google_util_unittest.cc b/chromium/components/google/core/browser/google_util_unittest.cc
index d30d03b56a5..46072bf5703 100644
--- a/chromium/components/google/core/browser/google_util_unittest.cc
+++ b/chromium/components/google/core/browser/google_util_unittest.cc
@@ -64,6 +64,14 @@ TEST(GoogleUtilTest, GoodHomePagesNonSecure) {
EXPECT_TRUE(IsHomePage("http://www.google.com/ig/foo"));
EXPECT_TRUE(IsHomePage("http://www.google.com/ig?rlz=TEST"));
EXPECT_TRUE(IsHomePage("http://www.google.com/ig/foo?rlz=TEST"));
+
+ // Accepted subdomains.
+ EXPECT_TRUE(IsHomePage("http://ipv4.google.com/"));
+ EXPECT_TRUE(IsHomePage("http://ipv6.google.com/"));
+
+ // Trailing dots.
+ EXPECT_TRUE(IsHomePage("http://ipv4.google.com./"));
+ EXPECT_TRUE(IsHomePage("http://google.com./"));
}
TEST(GoogleUtilTest, GoodHomePagesSecure) {
@@ -121,37 +129,52 @@ TEST(GoogleUtilTest, BadHomePages) {
// Path is case sensitive.
EXPECT_FALSE(IsHomePage("https://www.google.com/WEBHP"));
+
+ // Only .com subdomain and no www.
+ EXPECT_FALSE(IsHomePage("http://ipv4.google.co.uk"));
+ EXPECT_FALSE(IsHomePage("http://www.ipv4.google.com"));
}
TEST(GoogleUtilTest, GoodSearches) {
const std::string patterns[] = {
- // Queries with path "/search" need to have the query parameter in either
- // the url parameter or the hash fragment.
- "%s://www.google.com/search?%s=something",
- "%s://www.google.com/search#%s=something",
- "%s://www.google.com/search?name=bob&%s=something",
- "%s://www.google.com/search?name=bob#%s=something",
- "%s://www.google.com/search?name=bob#age=24&%s=thng",
- "%s://www.google.co.uk/search?%s=something",
- // It's actually valid for both to have the query parameter.
- "%s://www.google.com/search?%s=something#q=other",
-
- // Queries with path "/webhp", "/" or "" need to have the query parameter in
- // the hash fragment.
- "%s://www.google.com/webhp#%s=something",
- "%s://www.google.com/webhp#name=bob&%s=something",
- "%s://www.google.com/webhp?name=bob#%s=something",
- "%s://www.google.com/webhp?name=bob#age=24&%s=thing",
-
- "%s://www.google.com/#%s=something",
- "%s://www.google.com/#name=bob&%s=something",
- "%s://www.google.com/?name=bob#%s=something",
- "%s://www.google.com/?name=bob#age=24&%s=something",
-
- "%s://www.google.com#%s=something",
- "%s://www.google.com#name=bob&%s=something",
- "%s://www.google.com?name=bob#%s=something",
- "%s://www.google.com?name=bob#age=24&%s=something"
+ // Queries with path "/search" need to have the query parameter in either
+ // the url parameter or the hash fragment.
+ "%s://www.google.com/search?%s=something",
+ "%s://www.google.com/search#%s=something",
+ "%s://www.google.com/search?name=bob&%s=something",
+ "%s://www.google.com/search?name=bob#%s=something",
+ "%s://www.google.com/search?name=bob#age=24&%s=thng",
+ "%s://www.google.co.uk/search?%s=something",
+ // It's actually valid for both to have the query parameter.
+ "%s://www.google.com/search?%s=something#q=other",
+
+ // Queries with path "/webhp", "/" or "" need to have the query parameter
+ // in the hash fragment.
+ "%s://www.google.com/webhp#%s=something",
+ "%s://www.google.com/webhp#name=bob&%s=something",
+ "%s://www.google.com/webhp?name=bob#%s=something",
+ "%s://www.google.com/webhp?name=bob#age=24&%s=thing",
+
+ "%s://www.google.com/#%s=something",
+ "%s://www.google.com/#name=bob&%s=something",
+ "%s://www.google.com/?name=bob#%s=something",
+ "%s://www.google.com/?name=bob#age=24&%s=something",
+
+ "%s://www.google.com#%s=something",
+ "%s://www.google.com#name=bob&%s=something",
+ "%s://www.google.com?name=bob#%s=something",
+ "%s://www.google.com?name=bob#age=24&%s=something",
+
+ // Google subdomain queries.
+ "%s://ipv4.google.com/search?%s=something",
+ "%s://ipv4.google.com#name=bob&%s=something",
+ "%s://ipv6.google.com?name=bob#%s=something",
+ "%s://ipv6.google.com?name=bob#age=24&%s=something",
+
+ // Trailing dots in the hosts.
+ "%s://www.google.com./#%s=something", "%s://www.google.de./#%s=something",
+ "%s://ipv4.google.com./#%s=something",
+ "%s://ipv6.google.com./#%s=something",
};
for (const std::string& pattern : patterns) {
diff --git a/chromium/components/grpc_support/bidirectional_stream.cc b/chromium/components/grpc_support/bidirectional_stream.cc
index c17a4f64dea..79712bfedbb 100644
--- a/chromium/components/grpc_support/bidirectional_stream.cc
+++ b/chromium/components/grpc_support/bidirectional_stream.cc
@@ -23,7 +23,7 @@
#include "net/http/http_status_code.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/http_util.h"
-#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/core/spdy_header_block.h"
#include "net/ssl/ssl_info.h"
#include "net/url_request/http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
diff --git a/chromium/components/grpc_support/bidirectional_stream_c.cc b/chromium/components/grpc_support/bidirectional_stream_c.cc
index 7ab1af857a3..05b9aa46cb6 100644
--- a/chromium/components/grpc_support/bidirectional_stream_c.cc
+++ b/chromium/components/grpc_support/bidirectional_stream_c.cc
@@ -29,7 +29,7 @@
#include "net/http/http_status_code.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/http_util.h"
-#include "net/spdy/spdy_header_block.h"
+#include "net/spdy/core/spdy_header_block.h"
#include "net/ssl/ssl_info.h"
#include "net/url_request/http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
diff --git a/chromium/components/grpc_support/bidirectional_stream_unittest.cc b/chromium/components/grpc_support/bidirectional_stream_unittest.cc
index 84e5cb6c50c..589f8027500 100644
--- a/chromium/components/grpc_support/bidirectional_stream_unittest.cc
+++ b/chromium/components/grpc_support/bidirectional_stream_unittest.cc
@@ -36,9 +36,11 @@ class BidirectionalStreamTest : public ::testing::TestWithParam<bool> {
protected:
void SetUp() override {
StartQuicTestServer();
+ StartTestStreamEngine(GetQuicTestServerPort());
}
void TearDown() override {
+ ShutdownTestStreamEngine();
ShutdownQuicTestServer();
}
diff --git a/chromium/components/guest_view/OWNERS b/chromium/components/guest_view/OWNERS
index 5af20a0270b..728baf50245 100644
--- a/chromium/components/guest_view/OWNERS
+++ b/chromium/components/guest_view/OWNERS
@@ -4,5 +4,6 @@ lazyboy@chromium.org
lfg@chromium.org
wjmaclean@chromium.org
paulmeyer@chromium.org
+ekaramad@chromium.org
# COMPONENT: Platform>Apps>BrowserTag
diff --git a/chromium/components/guest_view/browser/BUILD.gn b/chromium/components/guest_view/browser/BUILD.gn
index a0668fc7782..6430459a7f0 100644
--- a/chromium/components/guest_view/browser/BUILD.gn
+++ b/chromium/components/guest_view/browser/BUILD.gn
@@ -2,6 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//extensions/features/features.gni")
+
+assert(enable_extensions)
+
static_library("browser") {
output_name = "guest_view_browser"
sources = [
diff --git a/chromium/components/guest_view/browser/guest_view_base.cc b/chromium/components/guest_view/browser/guest_view_base.cc
index 4a260c65b66..27570202e8e 100644
--- a/chromium/components/guest_view/browser/guest_view_base.cc
+++ b/chromium/components/guest_view/browser/guest_view_base.cc
@@ -30,17 +30,13 @@
using content::WebContents;
-namespace content {
-struct FrameNavigateParams;
-}
-
namespace guest_view {
namespace {
using WebContentsGuestViewMap = std::map<const WebContents*, GuestViewBase*>;
-static base::LazyInstance<WebContentsGuestViewMap>::DestructorAtExit
- webcontents_guestview_map = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<WebContentsGuestViewMap>::Leaky g_webcontents_guestview_map =
+ LAZY_INSTANCE_INITIALIZER;
} // namespace
@@ -149,7 +145,7 @@ class GuestViewBase::OwnerContentsObserver : public WebContentsObserver {
// WebContents goes away before the GuestViewBase is attached.
class GuestViewBase::OpenerLifetimeObserver : public WebContentsObserver {
public:
- OpenerLifetimeObserver(GuestViewBase* guest)
+ explicit OpenerLifetimeObserver(GuestViewBase* guest)
: WebContentsObserver(guest->GetOpener()->web_contents()),
guest_(guest) {}
@@ -173,8 +169,7 @@ class GuestViewBase::OpenerLifetimeObserver : public WebContentsObserver {
GuestViewBase::GuestViewBase(WebContents* owner_web_contents)
: owner_web_contents_(owner_web_contents),
browser_context_(owner_web_contents->GetBrowserContext()),
- guest_instance_id_(GuestViewManager::FromBrowserContext(browser_context_)
- ->GetNextInstanceID()),
+ guest_instance_id_(GetGuestViewManager()->GetNextInstanceID()),
view_instance_id_(kInstanceIDNone),
element_instance_id_(kInstanceIDNone),
initialized_(false),
@@ -184,9 +179,7 @@ GuestViewBase::GuestViewBase(WebContents* owner_web_contents)
is_full_page_plugin_(false),
guest_proxy_routing_id_(MSG_ROUTING_NONE),
weak_ptr_factory_(this) {
- owner_host_ = GuestViewManager::FromBrowserContext(browser_context_)->
- IsOwnedByExtension(this) ?
- owner_web_contents->GetLastCommittedURL().host() : std::string();
+ SetOwnerHost();
}
GuestViewBase::~GuestViewBase() {}
@@ -197,8 +190,7 @@ void GuestViewBase::Init(const base::DictionaryValue& create_params,
return;
initialized_ = true;
- if (!GuestViewManager::FromBrowserContext(browser_context_)->
- IsGuestAvailableToContext(this)) {
+ if (!GetGuestViewManager()->IsGuestAvailableToContext(this)) {
// The derived class did not create a WebContents so this class serves no
// purpose. Let's self-destruct.
delete this;
@@ -233,15 +225,14 @@ void GuestViewBase::InitWithWebContents(
// At this point, we have just created the guest WebContents, we need to add
// an observer to the owner WebContents. This observer will be responsible
// for destroying the guest WebContents if the owner goes away.
- owner_contents_observer_.reset(
- new OwnerContentsObserver(this, owner_web_contents_));
+ owner_contents_observer_ =
+ base::MakeUnique<OwnerContentsObserver>(this, owner_web_contents_);
WebContentsObserver::Observe(guest_web_contents);
guest_web_contents->SetDelegate(this);
- webcontents_guestview_map.Get().insert(
+ g_webcontents_guestview_map.Get().insert(
std::make_pair(guest_web_contents, this));
- GuestViewManager::FromBrowserContext(browser_context_)->
- AddGuest(guest_instance_id_, guest_web_contents);
+ GetGuestViewManager()->AddGuest(guest_instance_id_, guest_web_contents);
// Populate the view instance ID if we have it on creation.
create_params.GetInteger(kParameterInstanceId, &view_instance_id_);
@@ -271,7 +262,7 @@ void GuestViewBase::DispatchOnResizeEvent(const gfx::Size& old_size,
return;
// Dispatch the onResize event.
- std::unique_ptr<base::DictionaryValue> args(new base::DictionaryValue());
+ auto args = base::MakeUnique<base::DictionaryValue>();
args->SetInteger(kOldWidth, old_size.width());
args->SetInteger(kOldHeight, old_size.height());
args->SetInteger(kNewWidth, new_size.width());
@@ -281,14 +272,13 @@ void GuestViewBase::DispatchOnResizeEvent(const gfx::Size& old_size,
}
gfx::Size GuestViewBase::GetDefaultSize() const {
- if (is_full_page_plugin()) {
- // Full page plugins default to the size of the owner's viewport.
- return owner_web_contents()
- ->GetRenderWidgetHostView()
- ->GetVisibleViewportSize();
- } else {
+ if (!is_full_page_plugin())
return gfx::Size(kDefaultWidth, kDefaultHeight);
- }
+
+ // Full page plugins default to the size of the owner's viewport.
+ return owner_web_contents()
+ ->GetRenderWidgetHostView()
+ ->GetVisibleViewportSize();
}
void GuestViewBase::SetSize(const SetSizeParams& params) {
@@ -355,7 +345,7 @@ void GuestViewBase::CleanUp(content::BrowserContext* browser_context,
// static
GuestViewBase* GuestViewBase::FromWebContents(const WebContents* web_contents) {
- WebContentsGuestViewMap* guest_map = webcontents_guestview_map.Pointer();
+ WebContentsGuestViewMap* guest_map = g_webcontents_guestview_map.Pointer();
auto it = guest_map->find(web_contents);
return it == guest_map->end() ? nullptr : it->second;
}
@@ -402,13 +392,14 @@ bool GuestViewBase::ZoomPropagatesFromEmbedderToGuest() const {
void GuestViewBase::SetContextMenuPosition(const gfx::Point& position) {}
+GuestViewManager* GuestViewBase::GetGuestViewManager() {
+ return GuestViewManager::FromBrowserContext(browser_context());
+}
+
WebContents* GuestViewBase::CreateNewGuestWindow(
const WebContents::CreateParams& create_params) {
- auto* guest_manager = GuestViewManager::FromBrowserContext(browser_context());
- return guest_manager->CreateGuestWithWebContentsParams(
- GetViewType(),
- owner_web_contents(),
- create_params);
+ return GetGuestViewManager()->CreateGuestWithWebContentsParams(
+ GetViewType(), owner_web_contents(), create_params);
}
void GuestViewBase::OnRenderFrameHostDeleted(int process_id, int routing_id) {}
@@ -445,26 +436,6 @@ void GuestViewBase::DidDetach() {
Destroy(true);
}
-bool GuestViewBase::HandleFindForEmbedder(
- int request_id,
- const base::string16& search_text,
- const blink::WebFindOptions& options) {
- if (ShouldHandleFindRequestsForEmbedder()) {
- web_contents()->Find(request_id, search_text, options);
- return true;
- }
- return false;
-}
-
-bool GuestViewBase::HandleStopFindingForEmbedder(
- content::StopFindAction action) {
- if (ShouldHandleFindRequestsForEmbedder()) {
- web_contents()->StopFinding(action);
- return true;
- }
- return false;
-}
-
WebContents* GuestViewBase::GetOwnerWebContents() const {
return owner_web_contents_;
}
@@ -505,9 +476,8 @@ void GuestViewBase::Destroy(bool also_delete) {
guest_host_->WillDestroy();
guest_host_ = nullptr;
- webcontents_guestview_map.Get().erase(web_contents());
- GuestViewManager::FromBrowserContext(browser_context_)->
- RemoveGuest(guest_instance_id_);
+ g_webcontents_guestview_map.Get().erase(web_contents());
+ GetGuestViewManager()->RemoveGuest(guest_instance_id_);
pending_events_.clear();
if (also_delete)
@@ -522,8 +492,10 @@ void GuestViewBase::SetAttachParams(const base::DictionaryValue& params) {
void GuestViewBase::SetOpener(GuestViewBase* guest) {
if (guest && guest->IsViewType(GetViewType())) {
opener_ = guest->weak_ptr_factory_.GetWeakPtr();
- if (!attached())
- opener_lifetime_observer_.reset(new OpenerLifetimeObserver(this));
+ if (!attached()) {
+ opener_lifetime_observer_ =
+ base::MakeUnique<OpenerLifetimeObserver>(this);
+ }
return;
}
opener_ = base::WeakPtr<GuestViewBase>();
@@ -545,11 +517,9 @@ void GuestViewBase::WillAttach(WebContents* embedder_web_contents,
if (owner_web_contents_ != embedder_web_contents) {
DCHECK_EQ(owner_contents_observer_->web_contents(), owner_web_contents_);
owner_web_contents_ = embedder_web_contents;
- owner_contents_observer_.reset(
- new OwnerContentsObserver(this, embedder_web_contents));
- owner_host_ = GuestViewManager::FromBrowserContext(browser_context_)->
- IsOwnedByExtension(this) ?
- owner_web_contents()->GetLastCommittedURL().host() : std::string();
+ owner_contents_observer_ =
+ base::MakeUnique<OwnerContentsObserver>(this, embedder_web_contents);
+ SetOwnerHost();
}
// Start tracking the new embedder's zoom level.
@@ -570,10 +540,6 @@ void GuestViewBase::SignalWhenReady(const base::Closure& callback) {
callback.Run();
}
-bool GuestViewBase::ShouldHandleFindRequestsForEmbedder() const {
- return false;
-}
-
int GuestViewBase::LogicalPixelsToPhysicalPixels(double logical_pixels) const {
DCHECK(logical_pixels >= 0);
double zoom_factor = GetEmbedderZoomFactor();
@@ -698,9 +664,7 @@ bool GuestViewBase::ShouldFocusPageAfterCrash() {
bool GuestViewBase::PreHandleGestureEvent(WebContents* source,
const blink::WebGestureEvent& event) {
- return event.GetType() == blink::WebGestureEvent::kGesturePinchBegin ||
- event.GetType() == blink::WebGestureEvent::kGesturePinchUpdate ||
- event.GetType() == blink::WebGestureEvent::kGesturePinchEnd;
+ return blink::WebInputEvent::IsPinchGestureEventType(event.GetType());
}
void GuestViewBase::UpdatePreferredSize(WebContents* target_web_contents,
@@ -726,35 +690,15 @@ bool GuestViewBase::ShouldResumeRequestsForCreatedWindow() {
return false;
}
-void GuestViewBase::FindReply(WebContents* source,
- int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update) {
- if (ShouldHandleFindRequestsForEmbedder() &&
- attached() && embedder_web_contents()->GetDelegate()) {
- embedder_web_contents()->GetDelegate()->FindReply(embedder_web_contents(),
- request_id,
- number_of_matches,
- selection_rect,
- active_match_ordinal,
- final_update);
- }
-}
-
content::RenderWidgetHost* GuestViewBase::GetOwnerRenderWidgetHost() {
// We assume guests live inside an owner RenderFrame but the RenderFrame may
// not be cross-process. In case a type of guest should be allowed to be
// embedded in a cross-process frame, this method should be overrode for that
// specific guest type. For all other guests, the owner RenderWidgetHost is
// that of the owner WebContents.
- if (GetOwnerWebContents() &&
- GetOwnerWebContents()->GetRenderWidgetHostView()) {
- return GetOwnerWebContents()
- ->GetRenderWidgetHostView()
- ->GetRenderWidgetHost();
- }
+ auto* owner = GetOwnerWebContents();
+ if (owner && owner->GetRenderWidgetHostView())
+ return owner->GetRenderWidgetHostView()->GetRenderWidgetHost();
return nullptr;
}
@@ -935,4 +879,11 @@ void GuestViewBase::UpdateGuestSize(const gfx::Size& new_size,
guest_size_ = new_size;
}
+void GuestViewBase::SetOwnerHost() {
+ auto* manager = GuestViewManager::FromBrowserContext(browser_context_);
+ owner_host_ = manager->IsOwnedByExtension(this)
+ ? owner_web_contents()->GetLastCommittedURL().host()
+ : std::string();
+}
+
} // namespace guest_view
diff --git a/chromium/components/guest_view/browser/guest_view_base.h b/chromium/components/guest_view/browser/guest_view_base.h
index c900a11b01f..67fdaf0e373 100644
--- a/chromium/components/guest_view/browser/guest_view_base.h
+++ b/chromium/components/guest_view/browser/guest_view_base.h
@@ -23,6 +23,7 @@
namespace guest_view {
class GuestViewEvent;
+class GuestViewManager;
// A struct of parameters for SetSize(). The parameters are all declared as
// scoped pointers since they are all optional. Null pointers indicate that the
@@ -222,12 +223,6 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
const content::NativeWebKeyboardEvent& event) override;
bool PreHandleGestureEvent(content::WebContents* source,
const blink::WebGestureEvent& event) override;
- void FindReply(content::WebContents* source,
- int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update) override;
// WebContentsObserver implementation.
void DidFinishNavigation(
@@ -296,11 +291,6 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
// asynchronous setup.
virtual void SignalWhenReady(const base::Closure& callback);
- // Returns true if this guest should handle find requests for its
- // embedder. This should generally be true for guests that make up the
- // entirety of the embedder's content.
- virtual bool ShouldHandleFindRequestsForEmbedder() const;
-
// This method is called immediately before suspended resource loads have been
// resumed on attachment to an embedder.
//
@@ -345,10 +335,6 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
void DidAttach(int guest_proxy_routing_id) final;
void DidDetach() final;
content::WebContents* GetOwnerWebContents() const final;
- bool HandleFindForEmbedder(int request_id,
- const base::string16& search_text,
- const blink::WebFindOptions& options) final;
- bool HandleStopFindingForEmbedder(content::StopFindAction action) final;
void GuestSizeChanged(const gfx::Size& new_size) final;
void SetGuestHost(content::GuestHost* guest_host) final;
void WillAttach(content::WebContents* embedder_web_contents,
@@ -411,6 +397,9 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
void UpdateGuestSize(const gfx::Size& new_size, bool due_to_auto_resize);
+ GuestViewManager* GetGuestViewManager();
+ void SetOwnerHost();
+
// This guest tracks the lifetime of the WebContents specified by
// |owner_web_contents_|. If |owner_web_contents_| is destroyed then this
// guest will also self-destruct.
diff --git a/chromium/components/guest_view/browser/guest_view_manager.cc b/chromium/components/guest_view/browser/guest_view_manager.cc
index 1c68e13912c..bc36a92f4ad 100644
--- a/chromium/components/guest_view/browser/guest_view_manager.cc
+++ b/chromium/components/guest_view/browser/guest_view_manager.cc
@@ -8,8 +8,8 @@
#include <utility>
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/user_metrics.h"
-#include "base/strings/stringprintf.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "components/guest_view/browser/guest_view_manager_delegate.h"
#include "components/guest_view/browser/guest_view_manager_factory.h"
@@ -17,7 +17,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/result_codes.h"
@@ -31,6 +31,13 @@ using content::WebContents;
namespace guest_view {
+namespace {
+
+// Static factory instance (always NULL for non-test).
+GuestViewManagerFactory* g_factory;
+
+} // namespace
+
// This observer observes the RenderProcessHosts of GuestView embedders, and
// notifies the GuestViewManager when they are destroyed.
class GuestViewManager::EmbedderRenderProcessHostObserver
@@ -61,9 +68,6 @@ class GuestViewManager::EmbedderRenderProcessHostObserver
int id_;
};
-// static
-GuestViewManagerFactory* GuestViewManager::factory_ = nullptr;
-
GuestViewManager::GuestViewManager(
content::BrowserContext* context,
std::unique_ptr<GuestViewManagerDelegate> delegate)
@@ -81,13 +85,14 @@ GuestViewManager* GuestViewManager::CreateWithDelegate(
std::unique_ptr<GuestViewManagerDelegate> delegate) {
GuestViewManager* guest_manager = FromBrowserContext(context);
if (!guest_manager) {
- if (factory_) {
+ if (g_factory) {
guest_manager =
- factory_->CreateGuestViewManager(context, std::move(delegate));
+ g_factory->CreateGuestViewManager(context, std::move(delegate));
} else {
guest_manager = new GuestViewManager(context, std::move(delegate));
}
- context->SetUserData(kGuestViewManagerKeyName, guest_manager);
+ context->SetUserData(kGuestViewManagerKeyName,
+ base::WrapUnique(guest_manager));
}
return guest_manager;
}
@@ -99,6 +104,12 @@ GuestViewManager* GuestViewManager::FromBrowserContext(
kGuestViewManagerKeyName));
}
+// static
+void GuestViewManager::set_factory_for_testing(
+ GuestViewManagerFactory* factory) {
+ g_factory = factory;
+}
+
content::WebContents* GuestViewManager::GetGuestByInstanceIDSafely(
int guest_instance_id,
int embedder_render_process_id) {
@@ -321,7 +332,7 @@ void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id,
// If |view_instance_id| is guest_view::kInstanceIDNone, then all callbacks
// for this embedder should be called.
- if (view_instance_id == guest_view::kInstanceIDNone) {
+ if (view_instance_id == kInstanceIDNone) {
// Call all callbacks for the embedder with ID |embedder_process_id|.
for (auto& view_pair : callbacks_for_embedder) {
Callbacks& callbacks_for_view = view_pair.second;
@@ -344,8 +355,7 @@ void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id,
}
void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id) {
- CallViewDestructionCallbacks(embedder_process_id,
- guest_view::kInstanceIDNone);
+ CallViewDestructionCallbacks(embedder_process_id, kInstanceIDNone);
}
GuestViewBase* GuestViewManager::CreateGuestInternal(
diff --git a/chromium/components/guest_view/browser/guest_view_manager.h b/chromium/components/guest_view/browser/guest_view_manager.h
index 74e177d3fbf..4c1ad70b451 100644
--- a/chromium/components/guest_view/browser/guest_view_manager.h
+++ b/chromium/components/guest_view/browser/guest_view_manager.h
@@ -11,11 +11,9 @@
#include <vector>
#include "base/bind.h"
-#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
-#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
class GURL;
@@ -26,8 +24,8 @@ class DictionaryValue;
namespace content {
class BrowserContext;
-class WebContents;
-} // namespace content
+class SiteInstance;
+}
namespace guest_view {
@@ -54,9 +52,8 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
// Overrides factory for testing. Default (NULL) value indicates regular
// (non-test) environment.
- static void set_factory_for_testing(GuestViewManagerFactory* factory) {
- GuestViewManager::factory_ = factory;
- }
+ static void set_factory_for_testing(GuestViewManagerFactory* factory);
+
// Returns the guest WebContents associated with the given |guest_instance_id|
// if the provided |embedder_render_process_id| is allowed to access it.
// If the embedder is not allowed access, the embedder will be killed, and
@@ -204,9 +201,6 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
static bool GetFullPageGuestHelper(content::WebContents** result,
content::WebContents* guest_web_contents);
- // Static factory instance (always NULL for non-test).
- static GuestViewManagerFactory* factory_;
-
// Contains guests' WebContents, mapping from their instance ids.
using GuestInstanceMap = std::map<int, content::WebContents*>;
GuestInstanceMap guest_web_contents_by_instance_id_;
@@ -256,7 +250,7 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
// |last_instance_id_removed_| are kept here.
std::set<int> removed_instance_ids_;
- content::BrowserContext* context_;
+ content::BrowserContext* const context_;
std::unique_ptr<GuestViewManagerDelegate> delegate_;
diff --git a/chromium/components/guest_view/browser/guest_view_message_filter.cc b/chromium/components/guest_view/browser/guest_view_message_filter.cc
index 03aefe803a3..c2124ed258f 100644
--- a/chromium/components/guest_view/browser/guest_view_message_filter.cc
+++ b/chromium/components/guest_view/browser/guest_view_message_filter.cc
@@ -144,7 +144,8 @@ void GuestViewMessageFilter::OnAttachToEmbedderFrame(
guest->WillAttach(
owner_web_contents, element_instance_id, false,
- base::Bind(&GuestViewMessageFilter::WillAttachCallback, this, guest));
+ base::Bind(&GuestViewBase::DidAttach,
+ guest->weak_ptr_factory_.GetWeakPtr(), MSG_ROUTING_NONE));
// Attach this inner WebContents |guest_web_contents| to the outer
// WebContents |owner_web_contents|. The outer WebContents's
@@ -155,8 +156,4 @@ void GuestViewMessageFilter::OnAttachToEmbedderFrame(
embedder_frame);
}
-void GuestViewMessageFilter::WillAttachCallback(GuestViewBase* guest) {
- guest->DidAttach(MSG_ROUTING_NONE);
-}
-
} // namespace guest_view
diff --git a/chromium/components/guest_view/browser/guest_view_message_filter.h b/chromium/components/guest_view/browser/guest_view_message_filter.h
index 7c271d8a98c..1a24bf2cacd 100644
--- a/chromium/components/guest_view/browser/guest_view_message_filter.h
+++ b/chromium/components/guest_view/browser/guest_view_message_filter.h
@@ -23,7 +23,6 @@ class BrowserContext;
}
namespace guest_view {
-class GuestViewBase;
class GuestViewManager;
// This class filters out incoming GuestView-specific IPC messages from the
@@ -75,8 +74,6 @@ class GuestViewMessageFilter : public content::BrowserMessageFilter {
void OnViewCreated(int view_instance_id, const std::string& view_type);
void OnViewGarbageCollected(int view_instance_id);
- void WillAttachCallback(GuestViewBase* guest);
-
DISALLOW_COPY_AND_ASSIGN(GuestViewMessageFilter);
};
diff --git a/chromium/components/guest_view/renderer/BUILD.gn b/chromium/components/guest_view/renderer/BUILD.gn
index c78feedc49e..479bdef0feb 100644
--- a/chromium/components/guest_view/renderer/BUILD.gn
+++ b/chromium/components/guest_view/renderer/BUILD.gn
@@ -2,6 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//extensions/features/features.gni")
+
+assert(enable_extensions)
+
static_library("renderer") {
sources = [
"guest_view_container.cc",
diff --git a/chromium/components/guest_view/renderer/guest_view_container.cc b/chromium/components/guest_view/renderer/guest_view_container.cc
index cc01a13e096..4d1e7a65079 100644
--- a/chromium/components/guest_view/renderer/guest_view_container.cc
+++ b/chromium/components/guest_view/renderer/guest_view_container.cc
@@ -186,8 +186,15 @@ void GuestViewContainer::RunDestructionCallback(bool embedder_frame_destroyed) {
}
void GuestViewContainer::OnHandleCallback(const IPC::Message& message) {
+ base::WeakPtr<content::BrowserPluginDelegate> weak_ptr(GetWeakPtr());
+
// Handle the callback for the current request with a pending response.
HandlePendingResponseCallback(message);
+
+ // Check that this container has not been deleted (crbug.com/718292).
+ if (!weak_ptr)
+ return;
+
// Perform the subsequent request if one exists.
PerformPendingRequest();
}
diff --git a/chromium/components/history/content/browser/content_history_backend_db_unittest.cc b/chromium/components/history/content/browser/content_history_backend_db_unittest.cc
index 623e9ec4351..f364b846fc5 100644
--- a/chromium/components/history/content/browser/content_history_backend_db_unittest.cc
+++ b/chromium/components/history/content/browser/content_history_backend_db_unittest.cc
@@ -62,6 +62,7 @@ const InterruptReasonAssociation historical_reasons[] = {
{"FILE_SECURITY_CHECK_FAILED", 12},
{"FILE_TOO_SHORT", 13},
{"FILE_HASH_MISMATCH", 14},
+ {"FILE_SAME_AS_SOURCE", 15},
{"NETWORK_FAILED", 20},
{"NETWORK_TIMEOUT", 21},
{"NETWORK_DISCONNECTED", 22},
@@ -75,6 +76,7 @@ const InterruptReasonAssociation historical_reasons[] = {
{"SERVER_CERT_PROBLEM", 35},
{"SERVER_FORBIDDEN", 36},
{"SERVER_UNREACHABLE", 37},
+ {"SERVER_CONTENT_LENGTH_MISMATCH", 38},
{"USER_CANCELED", 40},
{"USER_SHUTDOWN", 41},
{"CRASH", 50},
diff --git a/chromium/components/history/content/browser/web_contents_top_sites_observer.cc b/chromium/components/history/content/browser/web_contents_top_sites_observer.cc
index 83ab57e9bad..2e7f10bc91c 100644
--- a/chromium/components/history/content/browser/web_contents_top_sites_observer.cc
+++ b/chromium/components/history/content/browser/web_contents_top_sites_observer.cc
@@ -5,6 +5,7 @@
#include "components/history/content/browser/web_contents_top_sites_observer.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "components/history/core/browser/top_sites.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
@@ -19,8 +20,9 @@ void WebContentsTopSitesObserver::CreateForWebContents(
TopSites* top_sites) {
DCHECK(web_contents);
if (!FromWebContents(web_contents)) {
- web_contents->SetUserData(UserDataKey(), new WebContentsTopSitesObserver(
- web_contents, top_sites));
+ web_contents->SetUserData(UserDataKey(),
+ base::WrapUnique(new WebContentsTopSitesObserver(
+ web_contents, top_sites)));
}
}
diff --git a/chromium/components/history/content/browser/web_contents_top_sites_observer.h b/chromium/components/history/content/browser/web_contents_top_sites_observer.h
index 6d920b96b08..32d22be9f6d 100644
--- a/chromium/components/history/content/browser/web_contents_top_sites_observer.h
+++ b/chromium/components/history/content/browser/web_contents_top_sites_observer.h
@@ -19,6 +19,8 @@ class WebContentsTopSitesObserver
: public content::WebContentsObserver,
public content::WebContentsUserData<WebContentsTopSitesObserver> {
public:
+ ~WebContentsTopSitesObserver() override;
+
static void CreateForWebContents(content::WebContents* web_contents,
TopSites* top_sites);
@@ -27,7 +29,6 @@ class WebContentsTopSitesObserver
WebContentsTopSitesObserver(content::WebContents* web_contents,
TopSites* top_sites);
- ~WebContentsTopSitesObserver() override;
// content::WebContentsObserver implementation.
void NavigationEntryCommitted(
diff --git a/chromium/components/history/core/browser/history_backend.cc b/chromium/components/history/core/browser/history_backend.cc
index dd82dc44197..14855781aac 100644
--- a/chromium/components/history/core/browser/history_backend.cc
+++ b/chromium/components/history/core/browser/history_backend.cc
@@ -219,7 +219,7 @@ void HistoryBackend::Init(
delegate_->DBLoaded();
if (base::FeatureList::IsEnabled(switches::kSyncUSSTypedURL)) {
typed_url_sync_bridge_ = base::MakeUnique<TypedURLSyncBridge>(
- this,
+ this, db_.get(),
base::BindRepeating(
&ModelTypeChangeProcessor::Create,
// TODO(gangwu): use ReportUnrecoverableError before launch.
@@ -1424,13 +1424,13 @@ void HistoryBackend::DeleteFTSIndexDatabases() {
num_databases_deleted);
}
-void HistoryBackend::GetFavicons(
- const std::vector<GURL>& icon_urls,
- int icon_types,
+void HistoryBackend::GetFavicon(
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) {
- UpdateFaviconMappingsAndFetchImpl(nullptr, icon_urls, icon_types,
- desired_sizes, bitmap_results);
+ UpdateFaviconMappingsAndFetchImpl(nullptr, icon_url, icon_type, desired_sizes,
+ bitmap_results);
}
void HistoryBackend::GetLargestFaviconForURL(
@@ -1562,11 +1562,11 @@ void HistoryBackend::GetFaviconForID(
void HistoryBackend::UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) {
- UpdateFaviconMappingsAndFetchImpl(&page_url, icon_urls, icon_types,
+ UpdateFaviconMappingsAndFetchImpl(&page_url, icon_url, icon_type,
desired_sizes, bitmap_results);
}
@@ -1580,7 +1580,7 @@ void HistoryBackend::MergeFavicon(
return;
favicon_base::FaviconID favicon_id =
- thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr);
+ thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type);
bool favicon_created = false;
if (!favicon_id) {
@@ -1780,8 +1780,8 @@ void HistoryBackend::SetImportedFavicons(
for (size_t i = 0; i < favicon_usage.size(); i++) {
favicon_base::FaviconID favicon_id =
- thumbnail_db_->GetFaviconIDForFaviconURL(
- favicon_usage[i].favicon_url, favicon_base::FAVICON, nullptr);
+ thumbnail_db_->GetFaviconIDForFaviconURL(favicon_usage[i].favicon_url,
+ favicon_base::FAVICON);
if (!favicon_id) {
// This favicon doesn't exist yet, so we create it using the given data.
// TODO(pkotwicz): Pass in real pixel size.
@@ -1840,7 +1840,7 @@ bool HistoryBackend::SetFaviconsImpl(const GURL& page_url,
DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size());
favicon_base::FaviconID icon_id =
- thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr);
+ thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type);
bool favicon_created = false;
if (!icon_id) {
@@ -1876,17 +1876,10 @@ bool HistoryBackend::SetFaviconsImpl(const GURL& page_url,
void HistoryBackend::UpdateFaviconMappingsAndFetchImpl(
const GURL* page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) {
- // If |page_url| is specified, |icon_types| must be either a single icon
- // type or icon types which are equivalent.
- DCHECK(!page_url || icon_types == favicon_base::FAVICON ||
- icon_types == favicon_base::TOUCH_ICON ||
- icon_types == favicon_base::TOUCH_PRECOMPOSED_ICON ||
- icon_types ==
- (favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON));
bitmap_results->clear();
if (!thumbnail_db_) {
@@ -1895,33 +1888,14 @@ void HistoryBackend::UpdateFaviconMappingsAndFetchImpl(
std::vector<favicon_base::FaviconID> favicon_ids;
- // The icon type for which the mappings will the updated and data will be
- // returned.
- favicon_base::IconType selected_icon_type = favicon_base::INVALID_ICON;
-
- for (size_t i = 0; i < icon_urls.size(); ++i) {
- const GURL& icon_url = icon_urls[i];
- favicon_base::IconType icon_type_out;
- const favicon_base::FaviconID favicon_id =
- thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_types,
- &icon_type_out);
-
- if (favicon_id) {
- // Return and update icon mappings only for the largest icon type. As
- // |icon_urls| is not sorted in terms of icon type, clear |favicon_ids|
- // if an |icon_url| with a larger icon type is found.
- if (icon_type_out > selected_icon_type) {
- selected_icon_type = icon_type_out;
- favicon_ids.clear();
- }
- if (icon_type_out == selected_icon_type)
- favicon_ids.push_back(favicon_id);
- }
- }
+ const favicon_base::FaviconID favicon_id =
+ thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type);
+ if (favicon_id)
+ favicon_ids.push_back(favicon_id);
if (page_url && !favicon_ids.empty()) {
bool mappings_updated = SetFaviconMappingsForPageAndRedirects(
- *page_url, selected_icon_type, favicon_ids);
+ *page_url, icon_type, favicon_ids);
if (mappings_updated) {
SendFaviconChangedNotificationForPageAndRedirects(*page_url);
ScheduleCommit();
@@ -2064,7 +2038,8 @@ bool HistoryBackend::GetFaviconBitmapResultsForBestMatch(
&score);
if (score > highest_score) {
highest_score = score;
- best_favicon_id = candidate_favicon_ids[i], best_bitmap_ids.clear();
+ best_favicon_id = candidate_favicon_ids[i];
+ best_bitmap_ids.clear();
for (size_t j = 0; j < candidate_bitmap_indices.size(); ++j) {
size_t candidate_index = candidate_bitmap_indices[j];
best_bitmap_ids.push_back(bitmap_id_sizes[candidate_index].bitmap_id);
@@ -2145,9 +2120,12 @@ bool HistoryBackend::SetFaviconMappingsForPage(
DCHECK_LE(icon_ids.size(), kMaxFaviconsPerPage);
bool mappings_changed = false;
- // Two icon types are considered 'equivalent' if one of the icon types is
- // TOUCH_ICON and the other is TOUCH_PRECOMPOSED_ICON.
- //
+ // Two icon types are considered 'equivalent' if both types are one of
+ // TOUCH_ICON, TOUCH_PRECOMPOSED_ICON or WEB_MANIFEST_ICON.
+ const int equivalent_types = favicon_base::TOUCH_ICON |
+ favicon_base::TOUCH_PRECOMPOSED_ICON |
+ favicon_base::WEB_MANIFEST_ICON;
+
// Sets the icon mappings from |page_url| for |icon_type| to the favicons
// with |icon_ids|. Mappings for |page_url| to favicons of type |icon_type|
// whose FaviconID is not in |icon_ids| are removed. All icon mappings for
@@ -2171,11 +2149,8 @@ bool HistoryBackend::SetFaviconMappingsForPage(
continue;
}
- if ((icon_type == favicon_base::TOUCH_ICON &&
- m->icon_type == favicon_base::TOUCH_PRECOMPOSED_ICON) ||
- (icon_type == favicon_base::TOUCH_PRECOMPOSED_ICON &&
- m->icon_type == favicon_base::TOUCH_ICON) ||
- (icon_type == m->icon_type)) {
+ if (icon_type == m->icon_type || ((icon_type & equivalent_types) != 0 &&
+ (m->icon_type & equivalent_types) != 0)) {
thumbnail_db_->DeleteIconMapping(m->mapping_id);
// Removing the icon mapping may have orphaned the associated favicon so
@@ -2487,10 +2462,11 @@ base::SupportsUserData::Data* HistoryBackend::GetUserData(
return supports_user_data_helper_->GetUserData(key);
}
-void HistoryBackend::SetUserData(const void* key,
- base::SupportsUserData::Data* data) {
+void HistoryBackend::SetUserData(
+ const void* key,
+ std::unique_ptr<base::SupportsUserData::Data> data) {
DCHECK(supports_user_data_helper_);
- supports_user_data_helper_->SetUserData(key, data);
+ supports_user_data_helper_->SetUserData(key, std::move(data));
}
void HistoryBackend::ProcessDBTask(
diff --git a/chromium/components/history/core/browser/history_backend.h b/chromium/components/history/core/browser/history_backend.h
index f96d2182c87..59c58389c12 100644
--- a/chromium/components/history/core/browser/history_backend.h
+++ b/chromium/components/history/core/browser/history_backend.h
@@ -285,9 +285,9 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
// Favicon -------------------------------------------------------------------
- void GetFavicons(
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ void GetFavicon(
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results);
@@ -310,8 +310,8 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
void UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results);
@@ -453,10 +453,9 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
// The user data allows the clients to associate data with this object.
// Multiple user data values can be stored under different keys.
- // This object will TAKE OWNERSHIP of the given data pointer, and will
- // delete the object if it is changed or the object is destroyed.
base::SupportsUserData::Data* GetUserData(const void* key) const;
- void SetUserData(const void* key, base::SupportsUserData::Data* data);
+ void SetUserData(const void* key,
+ std::unique_ptr<base::SupportsUserData::Data> data);
// Testing -------------------------------------------------------------------
@@ -684,18 +683,14 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
const std::vector<SkBitmap>& bitmaps,
bool bitmaps_are_expired);
- // Used by both UpdateFaviconMappingsAndFetch and GetFavicons.
- // If |page_url| is non-null, the icon urls for |page_url| (and all
- // redirects) are set to the subset of |icon_urls| for which icons are
- // already stored in the database.
- // If |page_url| is non-null, |icon_types| can be multiple icon types
- // only if |icon_types| == TOUCH_ICON | TOUCH_PRECOMPOSED_ICON.
- // If multiple icon types are specified, |page_url| will be mapped to the
- // icon URLs of the largest type available in the database.
+ // Used by both UpdateFaviconMappingsAndFetch() and GetFavicon().
+ // If |page_url| is non-null and there is a favicon stored in the database
+ // for |icon_url|, a mapping is added to the database from |page_url| (and all
+ // redirects) to |icon_url|.
void UpdateFaviconMappingsAndFetchImpl(
const GURL* page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
std::vector<favicon_base::FaviconRawBitmapResult>* results);
diff --git a/chromium/components/history/core/browser/history_backend_unittest.cc b/chromium/components/history/core/browser/history_backend_unittest.cc
index 16455290909..63dfe4b7309 100644
--- a/chromium/components/history/core/browser/history_backend_unittest.cc
+++ b/chromium/components/history/core/browser/history_backend_unittest.cc
@@ -485,7 +485,6 @@ class HistoryBackendTest : public HistoryBackendTestBase {
if (!gfx::PNGCodec::Decode(bitmap_data->front(), bitmap_data->size(),
&bitmap))
return false;
- SkAutoLockPixels bitmap_lock(bitmap);
return expected_color == bitmap.getColor(0, 0);
}
@@ -669,8 +668,8 @@ TEST_F(HistoryBackendTest, DeleteAll) {
// We should have a favicon and favicon bitmaps for the first URL only. We
// look them up by favicon URL since the IDs may have changed.
favicon_base::FaviconID out_favicon1 =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- favicon_url1, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url1,
+ favicon_base::FAVICON);
EXPECT_TRUE(out_favicon1);
std::vector<FaviconBitmap> favicon_bitmaps;
@@ -695,8 +694,8 @@ TEST_F(HistoryBackendTest, DeleteAll) {
EXPECT_EQ(kLargeSize, favicon_bitmap2.pixel_size);
favicon_base::FaviconID out_favicon2 =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- favicon_url2, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url2,
+ favicon_base::FAVICON);
EXPECT_FALSE(out_favicon2) << "Favicon not deleted";
// The remaining URL should still reference the same favicon, even if its
@@ -868,9 +867,8 @@ TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) {
backend_->db_->GetVisitsForURL(row2_id, &visits);
EXPECT_EQ(0U, visits.size());
// The favicon should still be valid.
- EXPECT_EQ(favicon2,
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- favicon_url2, favicon_base::FAVICON, NULL));
+ EXPECT_EQ(favicon2, backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
+ favicon_url2, favicon_base::FAVICON));
// Unstar row2.
history_client_.DelBookmark(row2.url());
@@ -884,9 +882,8 @@ TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) {
// The URL should still not exist.
EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), NULL));
// And the favicon should be deleted.
- EXPECT_EQ(0,
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- favicon_url2, favicon_base::FAVICON, NULL));
+ EXPECT_EQ(0, backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
+ favicon_url2, favicon_base::FAVICON));
// Unstar row 1.
history_client_.DelBookmark(row1.url());
@@ -906,9 +903,8 @@ TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) {
EXPECT_EQ(1U, visits.size());
// The favicon should still be valid.
- EXPECT_EQ(favicon1,
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- favicon_url1, favicon_base::FAVICON, NULL));
+ EXPECT_EQ(favicon1, backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
+ favicon_url1, favicon_base::FAVICON));
}
// Tests a handful of assertions for a navigation with a type of
@@ -1795,9 +1791,23 @@ TEST_F(HistoryBackendTest, SetFaviconMappingsForPageAndRedirects) {
0u,
NumIconMappingsForPageURL(url1, favicon_base::TOUCH_PRECOMPOSED_ICON));
+ // Add a web manifest_icon.
+ backend_->SetFavicons(url1, favicon_base::WEB_MANIFEST_ICON, icon_url2,
+ bitmaps);
+ EXPECT_EQ(1u,
+ NumIconMappingsForPageURL(url1, favicon_base::WEB_MANIFEST_ICON));
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, favicon_base::FAVICON));
+ // The TOUCH_ICON_ICON was replaced.
+ EXPECT_EQ(0u, NumIconMappingsForPageURL(url1, favicon_base::TOUCH_ICON));
+
+ // The TOUCH_PRECOMPOSED_ICON was replaced.
+ EXPECT_EQ(0u, NumIconMappingsForPageURL(
+ url1, favicon_base::TOUCH_PRECOMPOSED_ICON));
+
// Add a different favicon.
backend_->SetFavicons(url1, favicon_base::FAVICON, icon_url2, bitmaps);
- EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, favicon_base::TOUCH_ICON));
+ EXPECT_EQ(1u,
+ NumIconMappingsForPageURL(url1, favicon_base::WEB_MANIFEST_ICON));
EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, favicon_base::FAVICON));
EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, favicon_base::FAVICON));
}
@@ -1957,8 +1967,8 @@ TEST_F(HistoryBackendTest, SetFaviconsReplaceBitmapData) {
backend_->SetFavicons(page_url, favicon_base::FAVICON, icon_url, bitmaps);
favicon_base::FaviconID original_favicon_id =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(icon_url,
+ favicon_base::FAVICON);
EXPECT_NE(0, original_favicon_id);
FaviconBitmap original_favicon_bitmap;
EXPECT_TRUE(
@@ -1972,8 +1982,8 @@ TEST_F(HistoryBackendTest, SetFaviconsReplaceBitmapData) {
backend_->SetFavicons(page_url, favicon_base::FAVICON, icon_url, bitmaps);
favicon_base::FaviconID updated_favicon_id =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(icon_url,
+ favicon_base::FAVICON);
EXPECT_NE(0, updated_favicon_id);
FaviconBitmap updated_favicon_bitmap;
EXPECT_TRUE(
@@ -1987,7 +1997,7 @@ TEST_F(HistoryBackendTest, SetFaviconsReplaceBitmapData) {
backend_->SetFavicons(page_url, favicon_base::FAVICON, icon_url, bitmaps);
updated_favicon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL);
+ icon_url, favicon_base::FAVICON);
EXPECT_NE(0, updated_favicon_id);
EXPECT_TRUE(
GetOnlyFaviconBitmap(updated_favicon_id, &updated_favicon_bitmap));
@@ -2014,15 +2024,10 @@ TEST_F(HistoryBackendTest, SetFaviconsSameFaviconURLForTwoPages) {
backend_->SetFavicons(page_url1, favicon_base::FAVICON, icon_url, bitmaps);
- std::vector<GURL> icon_urls;
- icon_urls.push_back(icon_url);
-
std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
- backend_->UpdateFaviconMappingsAndFetch(page_url2,
- icon_urls,
- favicon_base::FAVICON,
- GetEdgeSizesSmallAndLarge(),
- &bitmap_results);
+ backend_->UpdateFaviconMappingsAndFetch(
+ page_url2, icon_url, favicon_base::FAVICON, GetEdgeSizesSmallAndLarge(),
+ &bitmap_results);
// Check that the same FaviconID is mapped to both page URLs.
std::vector<IconMapping> icon_mappings;
@@ -2085,8 +2090,8 @@ TEST_F(HistoryBackendTest, SetLastResortFaviconsForEmptyDB) {
icon_url, bitmaps));
favicon_base::FaviconID favicon_id =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(icon_url,
+ favicon_base::FAVICON);
EXPECT_NE(0, favicon_id);
FaviconBitmap favicon_bitmap;
@@ -2109,8 +2114,8 @@ TEST_F(HistoryBackendTest, SetLastResortFaviconsForPageInDB) {
// Add bitmap to the database.
backend_->SetFavicons(page_url, favicon_base::FAVICON, icon_url1, bitmaps);
favicon_base::FaviconID original_favicon_id =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url1, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(icon_url1,
+ favicon_base::FAVICON);
ASSERT_NE(0, original_favicon_id);
// Call SetLastResortFavicons() with a different icon URL and bitmap data.
@@ -2118,7 +2123,7 @@ TEST_F(HistoryBackendTest, SetLastResortFaviconsForPageInDB) {
EXPECT_FALSE(backend_->SetLastResortFavicons(page_url, favicon_base::FAVICON,
icon_url2, bitmaps));
EXPECT_EQ(0, backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url2, favicon_base::FAVICON, NULL));
+ icon_url2, favicon_base::FAVICON));
FaviconBitmap favicon_bitmap;
ASSERT_TRUE(GetOnlyFaviconBitmap(original_favicon_id, &favicon_bitmap));
@@ -2140,8 +2145,8 @@ TEST_F(HistoryBackendTest, SetLastResortFaviconsForIconInDB) {
// Add bitmap to the database.
backend_->SetFavicons(old_page_url, favicon_base::FAVICON, icon_url, bitmaps);
favicon_base::FaviconID original_favicon_id =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(icon_url,
+ favicon_base::FAVICON);
ASSERT_NE(0, original_favicon_id);
// Call SetLastResortFavicons() with a different bitmap.
@@ -2151,7 +2156,7 @@ TEST_F(HistoryBackendTest, SetLastResortFaviconsForIconInDB) {
EXPECT_EQ(original_favicon_id,
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL));
+ icon_url, favicon_base::FAVICON));
FaviconBitmap favicon_bitmap;
ASSERT_TRUE(GetOnlyFaviconBitmap(original_favicon_id, &favicon_bitmap));
@@ -2359,8 +2364,8 @@ TEST_F(HistoryBackendTest, MergeFaviconIconURLMappedToDifferentPageURL) {
page_url2, icon_url, favicon_base::FAVICON, bitmap_data, kSmallSize);
favicon_base::FaviconID favicon_id =
- backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL);
+ backend_->thumbnail_db_->GetFaviconIDForFaviconURL(icon_url,
+ favicon_base::FAVICON);
EXPECT_NE(0, favicon_id);
EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
@@ -2377,7 +2382,7 @@ TEST_F(HistoryBackendTest, MergeFaviconIconURLMappedToDifferentPageURL) {
page_url3, icon_url, favicon_base::FAVICON, bitmap_data, kSmallSize);
favicon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, favicon_base::FAVICON, NULL);
+ icon_url, favicon_base::FAVICON);
EXPECT_NE(0, favicon_id);
EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
@@ -2585,11 +2590,9 @@ TEST_F(HistoryBackendTest, FaviconChangedNotificationIconMappingChanged) {
// Map |page_url3| to |icon_url1| so that the test does not delete the
// favicon at |icon_url1|.
std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
- backend_->UpdateFaviconMappingsAndFetch(page_url3,
- std::vector<GURL>(1u, icon_url1),
- favicon_base::FAVICON,
- GetEdgeSizesSmallAndLarge(),
- &bitmap_results);
+ backend_->UpdateFaviconMappingsAndFetch(
+ page_url3, icon_url1, favicon_base::FAVICON,
+ GetEdgeSizesSmallAndLarge(), &bitmap_results);
ClearBroadcastedNotifications();
}
@@ -2612,11 +2615,8 @@ TEST_F(HistoryBackendTest, FaviconChangedNotificationIconMappingChanged) {
{
std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
backend_->UpdateFaviconMappingsAndFetch(
- page_url1,
- std::vector<GURL>(1u, icon_url2),
- favicon_base::FAVICON,
- GetEdgeSizesSmallAndLarge(),
- &bitmap_results);
+ page_url1, icon_url2, favicon_base::FAVICON,
+ GetEdgeSizesSmallAndLarge(), &bitmap_results);
ASSERT_EQ(1u, favicon_changed_notifications_page_urls().size());
EXPECT_EQ(page_url1, favicon_changed_notifications_page_urls()[0]);
EXPECT_EQ(0u, favicon_changed_notifications_icon_urls().size());
@@ -2646,11 +2646,9 @@ TEST_F(HistoryBackendTest,
// Map |page_url3| to |icon_url1| so that the test does not delete the
// favicon at |icon_url1|.
std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
- backend_->UpdateFaviconMappingsAndFetch(page_url3,
- std::vector<GURL>(1u, icon_url1),
- favicon_base::FAVICON,
- GetEdgeSizesSmallAndLarge(),
- &bitmap_results);
+ backend_->UpdateFaviconMappingsAndFetch(
+ page_url3, icon_url1, favicon_base::FAVICON,
+ GetEdgeSizesSmallAndLarge(), &bitmap_results);
ClearBroadcastedNotifications();
}
@@ -2795,11 +2793,9 @@ TEST_F(HistoryBackendTest, NoFaviconChangedNotifications) {
// UpdateFaviconMappingsAndFetch()
{
std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
- backend_->UpdateFaviconMappingsAndFetch(page_url,
- std::vector<GURL>(1u, icon_url),
- favicon_base::FAVICON,
- GetEdgeSizesSmallAndLarge(),
- &bitmap_results);
+ backend_->UpdateFaviconMappingsAndFetch(
+ page_url, icon_url, favicon_base::FAVICON, GetEdgeSizesSmallAndLarge(),
+ &bitmap_results);
}
EXPECT_EQ(0u, favicon_changed_notifications_page_urls().size());
@@ -2904,60 +2900,6 @@ TEST_F(HistoryBackendTest, TestGetFaviconsForURLReturnFaviconEvenItSmaller) {
EXPECT_EQ(favicon_base::FAVICON, result.icon_type);
}
-// Test UpdateFaviconMappingsAndFetch() when multiple icon types are passed in.
-TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchMultipleIconTypes) {
- GURL page_url1("http://www.google.com");
- GURL page_url2("http://news.google.com");
- GURL page_url3("http://mail.google.com");
- GURL icon_urla("http://www.google.com/favicon1.ico");
- GURL icon_urlb("http://www.google.com/favicon2.ico");
- std::vector<SkBitmap> bitmaps;
- bitmaps.push_back(CreateBitmap(SK_ColorBLUE, kSmallEdgeSize));
-
- // |page_url1| is mapped to |icon_urla| which if of type TOUCH_ICON.
- backend_->SetFavicons(
- page_url1, favicon_base::TOUCH_ICON, icon_urla, bitmaps);
-
- // |page_url2| is mapped to |icon_urlb| which is of type
- // TOUCH_PRECOMPOSED_ICON.
- backend_->SetFavicons(
- page_url2, favicon_base::TOUCH_PRECOMPOSED_ICON, icon_urlb, bitmaps);
-
- std::vector<GURL> icon_urls;
- icon_urls.push_back(icon_urla);
- icon_urls.push_back(icon_urlb);
-
- std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
- backend_->UpdateFaviconMappingsAndFetch(
- page_url3,
- icon_urls,
- (favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON),
- GetEdgeSizesSmallAndLarge(),
- &bitmap_results);
-
- // |page_url1| and |page_url2| should still be mapped to the same icon URLs.
- std::vector<IconMapping> icon_mappings;
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
- &icon_mappings));
- EXPECT_EQ(1u, icon_mappings.size());
- EXPECT_EQ(icon_urla, icon_mappings[0].icon_url);
- EXPECT_EQ(favicon_base::TOUCH_ICON, icon_mappings[0].icon_type);
-
- icon_mappings.clear();
- EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url2, &icon_mappings));
- EXPECT_EQ(1u, icon_mappings.size());
- EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
- EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
-
- // |page_url3| should be mapped only to |icon_urlb| as TOUCH_PRECOMPOSED_ICON
- // is the largest IconType.
- icon_mappings.clear();
- EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url3, &icon_mappings));
- EXPECT_EQ(1u, icon_mappings.size());
- EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
- EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
-}
-
// Test the results of GetFaviconsFromDB() when there are no found favicons.
TEST_F(HistoryBackendTest, GetFaviconsFromDBEmpty) {
const GURL page_url("http://www.google.com/");
@@ -3065,6 +3007,35 @@ TEST_F(HistoryBackendTest, GetFaviconsFromDBIconType) {
EXPECT_EQ(icon_url2, bitmap_results_out[0].icon_url);
}
+// Test that when GetFaviconsFromDB() is called with multiple icon types that
+// the best favicon bitmap is selected from among all of the icon types.
+TEST_F(HistoryBackendTest, GetFaviconsFromDBMultipleIconTypes) {
+ const GURL page_url("http://www.google.com/");
+ const GURL icon_url1("http://www.google.com/icon1.png");
+ const GURL icon_url2("http://www.google.com/icon2.png");
+
+ std::vector<favicon_base::FaviconRawBitmapData> favicon_bitmap_data;
+ backend_->SetFavicons(page_url, favicon_base::FAVICON, icon_url1,
+ {CreateBitmap(SK_ColorBLUE, kSmallEdgeSize)});
+ backend_->SetFavicons(page_url, favicon_base::TOUCH_ICON, icon_url2,
+ {CreateBitmap(SK_ColorBLUE, kLargeEdgeSize)});
+
+ struct TestCase {
+ int desired_edge_size;
+ GURL expected_icon_url;
+ } kTestCases[]{{kSmallEdgeSize, icon_url1}, {kLargeEdgeSize, icon_url2}};
+
+ for (const TestCase& test_case : kTestCases) {
+ std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results_out;
+ backend_->GetFaviconsForURL(
+ page_url, favicon_base::FAVICON | favicon_base::TOUCH_ICON,
+ {test_case.desired_edge_size}, &bitmap_results_out);
+
+ ASSERT_EQ(1u, bitmap_results_out.size());
+ EXPECT_EQ(test_case.expected_icon_url, bitmap_results_out[0].icon_url);
+ }
+}
+
// Test that GetFaviconsFromDB() correctly sets the expired flag for bitmap
// reults.
TEST_F(HistoryBackendTest, GetFaviconsFromDBExpired) {
@@ -3099,9 +3070,7 @@ TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoDB) {
std::vector<favicon_base::FaviconRawBitmapResult> bitmap_results;
- backend_->UpdateFaviconMappingsAndFetch(GURL(),
- std::vector<GURL>(),
- favicon_base::FAVICON,
+ backend_->UpdateFaviconMappingsAndFetch(GURL(), GURL(), favicon_base::FAVICON,
GetEdgeSizesSmallAndLarge(),
&bitmap_results);
diff --git a/chromium/components/history/core/browser/history_service.cc b/chromium/components/history/core/browser/history_service.cc
index b9ebe00521a..788c90da089 100644
--- a/chromium/components/history/core/browser/history_service.cc
+++ b/chromium/components/history/core/browser/history_service.cc
@@ -502,9 +502,9 @@ void HistoryService::AddPagesWithDetails(const URLRows& info,
history_backend_, info, visit_source));
}
-base::CancelableTaskTracker::TaskId HistoryService::GetFavicons(
- const std::vector<GURL>& icon_urls,
- int icon_types,
+base::CancelableTaskTracker::TaskId HistoryService::GetFavicon(
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker) {
@@ -515,8 +515,8 @@ base::CancelableTaskTracker::TaskId HistoryService::GetFavicons(
new std::vector<favicon_base::FaviconRawBitmapResult>();
return tracker->PostTaskAndReply(
backend_task_runner_.get(), FROM_HERE,
- base::Bind(&HistoryBackend::GetFavicons, history_backend_, icon_urls,
- icon_types, desired_sizes, results),
+ base::Bind(&HistoryBackend::GetFavicon, history_backend_, icon_url,
+ icon_type, desired_sizes, results),
base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
}
@@ -575,8 +575,8 @@ base::CancelableTaskTracker::TaskId HistoryService::GetFaviconForID(
base::CancelableTaskTracker::TaskId
HistoryService::UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker) {
@@ -588,8 +588,8 @@ HistoryService::UpdateFaviconMappingsAndFetch(
return tracker->PostTaskAndReply(
backend_task_runner_.get(), FROM_HERE,
base::Bind(&HistoryBackend::UpdateFaviconMappingsAndFetch,
- history_backend_, page_url, icon_urls, icon_types,
- desired_sizes, results),
+ history_backend_, page_url, icon_url, icon_type, desired_sizes,
+ results),
base::Bind(&RunWithFaviconResults, callback, base::Owned(results)));
}
@@ -901,11 +901,9 @@ bool HistoryService::Init(
backend_task_runner_ = thread_->task_runner();
} else {
backend_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
- base::TaskTraits()
- .WithPriority(base::TaskPriority::USER_BLOCKING)
- .WithShutdownBehavior(base::TaskShutdownBehavior::BLOCK_SHUTDOWN)
- .MayBlock()
- .WithBaseSyncPrimitives());
+ {base::MayBlock(), base::WithBaseSyncPrimitives(),
+ base::TaskPriority::USER_BLOCKING,
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
}
// Create the history backend.
diff --git a/chromium/components/history/core/browser/history_service.h b/chromium/components/history/core/browser/history_service.h
index c89868c9b4f..b1aedcdf655 100644
--- a/chromium/components/history/core/browser/history_service.h
+++ b/chromium/components/history/core/browser/history_service.h
@@ -644,18 +644,15 @@ class HistoryService : public syncer::SyncableService, public KeyedService {
// FaviconService.
// Used by FaviconService to get the favicon bitmaps from the history backend
- // whose edge sizes most closely match |desired_sizes| for |icon_types|. If
+ // whose edge sizes most closely match |desired_sizes| for |icon_type|. If
// |desired_sizes| has a '0' entry, the largest favicon bitmap for
- // |icon_types| is returned. The returned FaviconBitmapResults will have at
+ // |icon_type| is returned. The returned FaviconBitmapResults will have at
// most one result for each entry in |desired_sizes|. If a favicon bitmap is
// determined to be the best candidate for multiple |desired_sizes| there will
// be fewer results.
- // If |icon_types| has several types, results for only a single type will be
- // returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON, and
- // FAVICON.
- base::CancelableTaskTracker::TaskId GetFavicons(
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ base::CancelableTaskTracker::TaskId GetFavicon(
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker);
@@ -666,9 +663,7 @@ class HistoryService : public syncer::SyncableService, public KeyedService {
// |icon_types| is returned. The returned FaviconBitmapResults will have at
// most one result for each entry in |desired_sizes|. If a favicon bitmap is
// determined to be the best candidate for multiple |desired_sizes| there
- // will be fewer results. If |icon_types| has several types, results for only
- // a single type will be returned in the priority of TOUCH_PRECOMPOSED_ICON,
- // TOUCH_ICON, and FAVICON.
+ // will be fewer results.
base::CancelableTaskTracker::TaskId GetFaviconsForURL(
const GURL& page_url,
int icon_types,
@@ -704,28 +699,16 @@ class HistoryService : public syncer::SyncableService, public KeyedService {
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker);
- // Used by the FaviconService to replace the favicon mappings to |page_url|
- // for |icon_types| on the history backend.
- // Sample |icon_urls|:
- // { ICON_URL1 -> TOUCH_ICON, known to the database,
- // ICON_URL2 -> TOUCH_ICON, not known to the database,
- // ICON_URL3 -> TOUCH_PRECOMPOSED_ICON, known to the database }
- // The new mappings are computed from |icon_urls| with these rules:
- // 1) Any urls in |icon_urls| which are not already known to the database are
- // rejected.
- // Sample new mappings to |page_url|: { ICON_URL1, ICON_URL3 }
- // 2) If |icon_types| has multiple types, the mappings are only set for the
- // largest icon type.
- // Sample new mappings to |page_url|: { ICON_URL3 }
- // |icon_types| can only have multiple IconTypes if
- // |icon_types| == TOUCH_ICON | TOUCH_PRECOMPOSED_ICON.
- // The favicon bitmaps whose edge sizes most closely match |desired_sizes|
- // from the favicons which were just mapped to |page_url| are returned. If
- // |desired_sizes| has a '0' entry, the largest favicon bitmap is returned.
+ // Maps |page_url| to the favicon at |icon_url| if there is an entry in the
+ // database for |icon_url| and |icon_type|. This occurs when there is a
+ // mapping from a different page URL to |icon_url|. The favicon bitmaps whose
+ // edge sizes most closely match |desired_sizes| from the favicons which were
+ // just mapped to |page_url| are returned. If |desired_sizes| has a '0' entry,
+ // the largest favicon bitmap is returned.
base::CancelableTaskTracker::TaskId UpdateFaviconMappingsAndFetch(
const GURL& page_url,
- const std::vector<GURL>& icon_urls,
- int icon_types,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type,
const std::vector<int>& desired_sizes,
const favicon_base::FaviconResultsCallback& callback,
base::CancelableTaskTracker* tracker);
diff --git a/chromium/components/history/core/browser/history_service_unittest.cc b/chromium/components/history/core/browser/history_service_unittest.cc
index b26d83adbbb..29ac63f24d0 100644
--- a/chromium/components/history/core/browser/history_service_unittest.cc
+++ b/chromium/components/history/core/browser/history_service_unittest.cc
@@ -29,6 +29,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/history/core/browser/history_database_params.h"
#include "components/history/core/browser/history_db_task.h"
@@ -51,7 +52,10 @@ namespace history {
class HistoryServiceTest : public testing::Test {
public:
- HistoryServiceTest() : query_url_success_(false) {}
+ HistoryServiceTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ query_url_success_(false) {}
~HistoryServiceTest() override {}
@@ -154,7 +158,7 @@ class HistoryServiceTest : public testing::Test {
base::ScopedTempDir temp_dir_;
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
MostVisitedURLList most_visited_urls_;
diff --git a/chromium/components/history/core/browser/thumbnail_database.cc b/chromium/components/history/core/browser/thumbnail_database.cc
index d9bc22defb1..60445eb48f0 100644
--- a/chromium/components/history/core/browser/thumbnail_database.cc
+++ b/chromium/components/history/core/browser/thumbnail_database.cc
@@ -584,19 +584,15 @@ bool ThumbnailDatabase::SetFaviconOutOfDate(favicon_base::FaviconID icon_id) {
favicon_base::FaviconID ThumbnailDatabase::GetFaviconIDForFaviconURL(
const GURL& icon_url,
- int required_icon_type,
- favicon_base::IconType* icon_type) {
- sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
- "SELECT id, icon_type FROM favicons WHERE url=? AND (icon_type & ? > 0) "
- "ORDER BY icon_type DESC"));
+ favicon_base::IconType icon_type) {
+ sql::Statement statement(db_.GetCachedStatement(
+ SQL_FROM_HERE, "SELECT id FROM favicons WHERE url=? AND icon_type=?"));
statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url));
- statement.BindInt(1, required_icon_type);
+ statement.BindInt(1, icon_type);
if (!statement.Step())
return 0; // not cached
- if (icon_type)
- *icon_type = static_cast<favicon_base::IconType>(statement.ColumnInt(1));
return statement.ColumnInt64(0);
}
@@ -677,11 +673,6 @@ bool ThumbnailDatabase::GetIconMappingsForPageURL(
if (!filtered_mapping_data)
return result;
- // Restrict icon type of subsequent matches to |m->icon_type|.
- // |m->icon_type| is the largest IconType in |mapping_data| because
- // |mapping_data| is sorted in descending order of IconType.
- required_icon_types = m->icon_type;
-
filtered_mapping_data->push_back(*m);
}
}
diff --git a/chromium/components/history/core/browser/thumbnail_database.h b/chromium/components/history/core/browser/thumbnail_database.h
index 9f81d41f46d..ec21369d438 100644
--- a/chromium/components/history/core/browser/thumbnail_database.h
+++ b/chromium/components/history/core/browser/thumbnail_database.h
@@ -129,16 +129,11 @@ class ThumbnailDatabase {
bool SetFaviconOutOfDate(favicon_base::FaviconID icon_id);
// Returns the id of the entry in the favicon database with the specified url
- // and icon type. If |required_icon_type| contains multiple icon types and
- // there are more than one matched icon in database, only one icon will be
- // returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON, and
- // FAVICON, and the icon type is returned in icon_type parameter if it is not
- // NULL.
+ // and icon type.
// Returns 0 if no entry exists for the specified url.
favicon_base::FaviconID GetFaviconIDForFaviconURL(
const GURL& icon_url,
- int required_icon_type,
- favicon_base::IconType* icon_type);
+ favicon_base::IconType icon_type);
// Gets the icon_url, icon_type and sizes for the specified |icon_id|.
bool GetFaviconHeader(favicon_base::FaviconID icon_id,
@@ -170,10 +165,6 @@ class ThumbnailDatabase {
// not NULL.
// Returns true if there are icon mappings for the given page and icon types.
- // If |required_icon_types| contains multiple icon types and there is more
- // than one matched icon type in the database, icons of only a single type
- // will be returned in the priority of TOUCH_PRECOMPOSED_ICON, TOUCH_ICON,
- // and FAVICON.
// The matched icon mappings are returned in the |mapping_data| parameter if
// it is not NULL.
bool GetIconMappingsForPageURL(const GURL& page_url,
diff --git a/chromium/components/history/core/browser/thumbnail_database_unittest.cc b/chromium/components/history/core/browser/thumbnail_database_unittest.cc
index b20bbaf3f78..0ece892cfe4 100644
--- a/chromium/components/history/core/browser/thumbnail_database_unittest.cc
+++ b/chromium/components/history/core/browser/thumbnail_database_unittest.cc
@@ -76,6 +76,19 @@ void VerifyTablesAndColumns(sql::Connection* db) {
EXPECT_EQ(3u, sql::test::CountTableColumns(db, "icon_mapping"));
}
+// Adds a favicon at |icon_url| with |icon_type| with default bitmap data and
+// maps |page_url| to |icon_url|.
+void AddAndMapFaviconSimple(ThumbnailDatabase* db,
+ const GURL& page_url,
+ const GURL& icon_url,
+ favicon_base::IconType icon_type) {
+ scoped_refptr<base::RefCountedStaticMemory> data(
+ new base::RefCountedStaticMemory(kBlob1, sizeof(kBlob1)));
+ favicon_base::FaviconID favicon_id =
+ db->AddFavicon(icon_url, icon_type, data, base::Time::Now(), gfx::Size());
+ db->AddIconMapping(page_url, favicon_id);
+}
+
void VerifyDatabaseEmpty(sql::Connection* db) {
size_t rows = 0;
EXPECT_TRUE(sql::test::CountTableRows(db, "favicons", &rows));
@@ -147,6 +160,14 @@ WARN_UNUSED_RESULT bool CheckPageHasIcon(
return true;
}
+bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) {
+ return a.icon_url < b.icon_url;
+}
+
+void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) {
+ std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl);
+}
+
} // namespace
class ThumbnailDatabaseTest : public testing::Test {
@@ -369,8 +390,8 @@ TEST_F(ThumbnailDatabaseTest, RetainDataForPageUrls) {
kBlob2));
// The ones not retained should be missing.
- EXPECT_FALSE(db.GetFaviconIDForFaviconURL(kPageUrl2, false, NULL));
- EXPECT_FALSE(db.GetFaviconIDForFaviconURL(kPageUrl4, false, NULL));
+ EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
+ EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl4, nullptr));
// Schema should be the same.
EXPECT_EQ(original_schema, db.db_.GetSchema());
@@ -391,8 +412,8 @@ TEST_F(ThumbnailDatabaseTest, RetainDataForPageUrlsExpiresRetainedFavicons) {
EXPECT_TRUE(db.RetainDataForPageUrls(std::vector<GURL>(1u, kPageUrl1)));
- favicon_base::FaviconID new_favicon_id = db.GetFaviconIDForFaviconURL(
- kIconUrl1, favicon_base::FAVICON, nullptr);
+ favicon_base::FaviconID new_favicon_id =
+ db.GetFaviconIDForFaviconURL(kIconUrl1, favicon_base::FAVICON);
ASSERT_NE(0, new_favicon_id);
std::vector<FaviconBitmap> new_favicon_bitmaps;
db.GetFaviconBitmaps(new_favicon_id, &new_favicon_bitmaps);
@@ -490,61 +511,31 @@ TEST_F(ThumbnailDatabaseTest, GetIconMappingsForPageURLForReturnOrder) {
EXPECT_EQ(icon_url, icon_mappings.front().icon_url);
}
-// Test result of GetIconMappingsForPageURL when an icon type is passed in.
-TEST_F(ThumbnailDatabaseTest, GetIconMappingsForPageURLWithIconType) {
+// Test that when multiple icon types are passed to GetIconMappingsForPageURL()
+// that the results are filtered according to the passed in types.
+TEST_F(ThumbnailDatabaseTest, GetIconMappingsForPageURLWithIconTypes) {
ThumbnailDatabase db(NULL);
ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
db.BeginTransaction();
- GURL url("http://google.com");
- std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1));
- scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data));
- base::Time time = base::Time::Now();
-
- favicon_base::FaviconID id1 =
- db.AddFavicon(url, favicon_base::FAVICON, favicon, time, gfx::Size());
- EXPECT_NE(0, db.AddIconMapping(url, id1));
-
- favicon_base::FaviconID id2 =
- db.AddFavicon(url, favicon_base::TOUCH_ICON, favicon, time, gfx::Size());
- EXPECT_NE(0, db.AddIconMapping(url, id2));
-
- favicon_base::FaviconID id3 =
- db.AddFavicon(url, favicon_base::TOUCH_ICON, favicon, time, gfx::Size());
- EXPECT_NE(0, db.AddIconMapping(url, id3));
+ const GURL kPageUrl("http://www.google.com");
+ AddAndMapFaviconSimple(&db, kPageUrl, kIconUrl1, favicon_base::FAVICON);
+ AddAndMapFaviconSimple(&db, kPageUrl, kIconUrl2, favicon_base::TOUCH_ICON);
+ AddAndMapFaviconSimple(&db, kPageUrl, kIconUrl3, favicon_base::TOUCH_ICON);
+ AddAndMapFaviconSimple(&db, kPageUrl, kIconUrl5,
+ favicon_base::TOUCH_PRECOMPOSED_ICON);
- // Only the mappings for favicons of type TOUCH_ICON should be returned as
- // TOUCH_ICON is a larger icon type than FAVICON.
+ // Only the mappings for FAVICON and TOUCH_ICON should be returned.
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(db.GetIconMappingsForPageURL(
- url,
- favicon_base::FAVICON | favicon_base::TOUCH_ICON |
- favicon_base::TOUCH_PRECOMPOSED_ICON,
+ kPageUrl, favicon_base::FAVICON | favicon_base::TOUCH_ICON,
&icon_mappings));
+ SortMappingsByIconUrl(&icon_mappings);
- EXPECT_EQ(2u, icon_mappings.size());
- if (id2 == icon_mappings[0].icon_id) {
- EXPECT_EQ(id3, icon_mappings[1].icon_id);
- } else {
- EXPECT_EQ(id3, icon_mappings[0].icon_id);
- EXPECT_EQ(id2, icon_mappings[1].icon_id);
- }
-
- icon_mappings.clear();
- EXPECT_TRUE(db.GetIconMappingsForPageURL(
- url, favicon_base::TOUCH_ICON, &icon_mappings));
- if (id2 == icon_mappings[0].icon_id) {
- EXPECT_EQ(id3, icon_mappings[1].icon_id);
- } else {
- EXPECT_EQ(id3, icon_mappings[0].icon_id);
- EXPECT_EQ(id2, icon_mappings[1].icon_id);
- }
-
- icon_mappings.clear();
- EXPECT_TRUE(
- db.GetIconMappingsForPageURL(url, favicon_base::FAVICON, &icon_mappings));
- EXPECT_EQ(1u, icon_mappings.size());
- EXPECT_EQ(id1, icon_mappings[0].icon_id);
+ ASSERT_EQ(3u, icon_mappings.size());
+ EXPECT_EQ(kIconUrl1, icon_mappings[0].icon_url);
+ EXPECT_EQ(kIconUrl3, icon_mappings[1].icon_url);
+ EXPECT_EQ(kIconUrl2, icon_mappings[2].icon_url);
}
TEST_F(ThumbnailDatabaseTest, HasMappingFor) {
diff --git a/chromium/components/history/core/browser/top_sites.h b/chromium/components/history/core/browser/top_sites.h
index 2b5e080f4b5..458899b753b 100644
--- a/chromium/components/history/core/browser/top_sites.h
+++ b/chromium/components/history/core/browser/top_sites.h
@@ -25,8 +25,6 @@ class RefCountedMemory;
namespace history {
-class TopSitesObserver;
-
// PrepopulatedPage stores information for prepopulated page for the
// initial run.
struct PrepopulatedPage {
@@ -142,7 +140,7 @@ class TopSites : public RefcountedKeyedService {
// Adds or updates a |url| for which we should force the capture of a
// thumbnail next time it's visited. If there is already a non-forced URL
- // matching this |url| this call has no effect. Indicate this URL was laste
+ // matching this |url| this call has no effect. Indicate this URL was last
// forced at |time| so we can evict the older URLs when needed. Should be
// called from the UI thread.
virtual bool AddForcedURL(const GURL& url, const base::Time& time) = 0;
diff --git a/chromium/components/history/core/browser/top_sites_cache.h b/chromium/components/history/core/browser/top_sites_cache.h
index b7e10b99bcd..37c94826cbb 100644
--- a/chromium/components/history/core/browser/top_sites_cache.h
+++ b/chromium/components/history/core/browser/top_sites_cache.h
@@ -16,12 +16,11 @@
#include "components/history/core/browser/url_utils.h"
#include "url/gurl.h"
-class GURL;
-
namespace history {
-// TopSiteCache caches thumbnails for visited pages. Retrieving thumbnails from
-// a given input URL is a two-stage process:
+// TopSitesCache caches the top sites and thumbnails for TopSites.
+//
+// Retrieving thumbnails from a given input URL is a two-stage process:
//
// input URL --(map 1)--> canonical URL --(map 2)--> image.
//
@@ -38,8 +37,6 @@ namespace history {
// ignoring "?query#ref".
// For the latter two "URL prefix matches", we prefer the match that is closest
// to input URL, w.r.t. path hierarchy.
-
-// TopSitesCache caches the top sites and thumbnails for TopSites.
class TopSitesCache {
public:
TopSitesCache();
diff --git a/chromium/components/history/core/browser/top_sites_impl.cc b/chromium/components/history/core/browser/top_sites_impl.cc
index 72378e2940c..53171ff079e 100644
--- a/chromium/components/history/core/browser/top_sites_impl.cc
+++ b/chromium/components/history/core/browser/top_sites_impl.cc
@@ -27,6 +27,7 @@
#include "components/history/core/browser/history_backend.h"
#include "components/history/core/browser/history_constants.h"
#include "components/history/core/browser/history_db_task.h"
+#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/page_usage_data.h"
#include "components/history/core/browser/top_sites_cache.h"
#include "components/history/core/browser/top_sites_observer.h"
@@ -35,13 +36,10 @@
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
-#include "ui/base/l10n/l10n_util.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_util.h"
-using base::DictionaryValue;
-
namespace history {
namespace {
@@ -51,12 +49,12 @@ void RunOrPostGetMostVisitedURLsCallback(
const TopSitesImpl::GetMostVisitedURLsCallback& callback,
const MostVisitedURLList& all_urls,
const MostVisitedURLList& nonforced_urls) {
- const MostVisitedURLList* urls =
- include_forced_urls ? &all_urls : &nonforced_urls;
+ const MostVisitedURLList& urls =
+ include_forced_urls ? all_urls : nonforced_urls;
if (task_runner->RunsTasksOnCurrentThread())
- callback.Run(*urls);
+ callback.Run(urls);
else
- task_runner->PostTask(FROM_HERE, base::Bind(callback, *urls));
+ task_runner->PostTask(FROM_HERE, base::Bind(callback, urls));
}
// Compares two MostVisitedURL having a non-null |last_forced_time|.
@@ -109,8 +107,8 @@ TopSitesImpl::TopSitesImpl(PrefService* pref_service,
const PrepopulatedPageList& prepopulated_pages,
const CanAddURLToHistoryFn& can_add_url_to_history)
: backend_(nullptr),
- cache_(new TopSitesCache()),
- thread_safe_cache_(new TopSitesCache()),
+ cache_(base::MakeUnique<TopSitesCache>()),
+ thread_safe_cache_(base::MakeUnique<TopSitesCache>()),
last_num_urls_changed_(0),
prepopulated_pages_(prepopulated_pages),
pref_service_(pref_service),
@@ -148,11 +146,10 @@ bool TopSitesImpl::SetPageThumbnail(const GURL& url,
bool add_temp_thumbnail = false;
if (!IsKnownURL(url)) {
- if (!IsNonForcedFull()) {
- add_temp_thumbnail = true;
- } else {
- return false; // This URL is not known to us.
- }
+ if (IsNonForcedFull())
+ return false; // We're full, and this URL is not known to us.
+
+ add_temp_thumbnail = true;
}
if (!can_add_url_to_history_.Run(url))
@@ -229,13 +226,11 @@ bool TopSitesImpl::GetPageThumbnail(
if (url.SchemeIsHTTPOrHTTPS())
url_list.push_back(ToggleHTTPAndHTTPS(url));
- for (std::vector<GURL>::iterator it = url_list.begin();
- it != url_list.end(); ++it) {
+ for (const GURL& url : url_list) {
base::AutoLock lock(lock_);
- GURL canonical_url;
// Test whether any stored URL is a prefix of |url|.
- canonical_url = thread_safe_cache_->GetGeneralizedCanonicalURL(*it);
+ GURL canonical_url = thread_safe_cache_->GetGeneralizedCanonicalURL(url);
if (!canonical_url.is_empty() &&
thread_safe_cache_->GetPageThumbnail(canonical_url, bytes)) {
return true;
@@ -255,10 +250,9 @@ bool TopSitesImpl::GetPageThumbnailScore(const GURL& url,
bool TopSitesImpl::GetTemporaryPageThumbnailScore(const GURL& url,
ThumbnailScore* score) {
- for (TempImages::iterator i = temp_images_.begin(); i != temp_images_.end();
- ++i) {
- if (i->first == url) {
- *score = i->second.thumbnail_score;
+ for (const TempImage& temp_image : temp_images_) {
+ if (temp_image.first == url) {
+ *score = temp_image.second.thumbnail_score;
return true;
}
}
@@ -386,8 +380,7 @@ bool TopSitesImpl::AddForcedURL(const GURL& url, const base::Time& time) {
// since this is almost always where it needs to go, unless the user's local
// clock is fiddled with.
MostVisitedURLList::iterator mid = new_list.begin() + num_forced;
- new_list.insert(mid, new_url);
- mid = new_list.begin() + num_forced; // Mid was invalidated.
+ mid = new_list.insert(mid, new_url);
std::inplace_merge(new_list.begin(), mid, mid + 1, ForcedURLComparator);
SetTopSites(new_list, CALL_LOCATION_FROM_FORCED_URLS);
return true;
@@ -490,10 +483,9 @@ void TopSitesImpl::DiffMostVisited(const MostVisitedURLList& old_list,
// Any member without the special marker in the all_old_urls list means that
// there wasn't a "new" URL that mapped to it, so it was deleted.
- for (std::map<GURL, size_t>::const_iterator i = all_old_urls.begin();
- i != all_old_urls.end(); ++i) {
- if (i->second != kAlreadyFoundMarker)
- delta->deleted.push_back(old_list[i->second]);
+ for (const std::pair<GURL, size_t>& old_url : all_old_urls) {
+ if (old_url.second != kAlreadyFoundMarker)
+ delta->deleted.push_back(old_list[old_url.second]);
}
}
@@ -515,10 +507,11 @@ bool TopSitesImpl::SetPageThumbnailNoDB(
new_score_with_redirects.redirect_hops_from_dest =
GetRedirectDistanceForURL(most_visited, url);
- if (!ShouldReplaceThumbnailWith(image->thumbnail_score,
- new_score_with_redirects) &&
- image->thumbnail.get())
+ if (image->thumbnail.get() &&
+ !ShouldReplaceThumbnailWith(image->thumbnail_score,
+ new_score_with_redirects)) {
return false; // The one we already have is better.
+ }
image->thumbnail = const_cast<base::RefCountedMemory*>(thumbnail_data);
image->thumbnail_score = new_score_with_redirects;
@@ -553,14 +546,14 @@ bool TopSitesImpl::EncodeBitmap(const gfx::Image& bitmap,
if (bitmap.IsEmpty())
return false;
*bytes = new base::RefCountedBytes();
- std::vector<unsigned char> data;
- if (!gfx::JPEG1xEncodedDataFromImage(bitmap, kTopSitesImageQuality, &data))
+ if (!gfx::JPEG1xEncodedDataFromImage(bitmap, kTopSitesImageQuality,
+ &(*bytes)->data())) {
return false;
+ }
// As we're going to cache this data, make sure the vector is only as big as
// it needs to be, as JPEGCodec::Encode() over-allocates data.capacity().
- // (In a C++0x future, we can just call shrink_to_fit() in Encode())
- (*bytes)->data() = data;
+ (*bytes)->data().shrink_to_fit();
return true;
}
@@ -574,16 +567,15 @@ void TopSitesImpl::RemoveTemporaryThumbnailByURL(const GURL& url) {
}
}
-void TopSitesImpl::AddTemporaryThumbnail(
- const GURL& url,
- const base::RefCountedMemory* thumbnail,
- const ThumbnailScore& score) {
+void TopSitesImpl::AddTemporaryThumbnail(const GURL& url,
+ base::RefCountedMemory* thumbnail,
+ const ThumbnailScore& score) {
if (temp_images_.size() == kMaxTempTopImages)
- temp_images_.erase(temp_images_.begin());
+ temp_images_.pop_front();
TempImage image;
image.first = url;
- image.second.thumbnail = const_cast<base::RefCountedMemory*>(thumbnail);
+ image.second.thumbnail = thumbnail;
image.second.thumbnail_score = score;
temp_images_.push_back(image);
}
@@ -604,7 +596,7 @@ int TopSitesImpl::GetRedirectDistanceForURL(const MostVisitedURL& most_visited,
}
bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls,
- size_t num_forced_urls) {
+ size_t num_forced_urls) const {
bool added = false;
for (const auto& prepopulated_page : prepopulated_pages_) {
if (urls->size() - num_forced_urls < kNonForcedTopSitesNumber &&
@@ -616,7 +608,7 @@ bool TopSitesImpl::AddPrepopulatedPages(MostVisitedURLList* urls,
return added;
}
-size_t TopSitesImpl::MergeCachedForcedURLs(MostVisitedURLList* new_list) {
+size_t TopSitesImpl::MergeCachedForcedURLs(MostVisitedURLList* new_list) const {
DCHECK(thread_checker_.CalledOnValidThread());
// Add all the new URLs for quick lookup. Take that opportunity to count the
// number of forced URLs in |new_list|.
@@ -685,13 +677,14 @@ void TopSitesImpl::ApplyBlacklist(const MostVisitedURLList& urls,
}
}
+// static
std::string TopSitesImpl::GetURLHash(const GURL& url) {
// We don't use canonical URLs here to be able to blacklist only one of
// the two 'duplicate' sites, e.g. 'gmail.com' and 'mail.google.com'.
return base::MD5String(url.spec());
}
-base::TimeDelta TopSitesImpl::GetUpdateDelay() {
+base::TimeDelta TopSitesImpl::GetUpdateDelay() const {
if (cache_->top_sites().size() <= prepopulated_pages_.size())
return base::TimeDelta::FromSeconds(30);
@@ -740,11 +733,11 @@ void TopSitesImpl::SetTopSites(const MostVisitedURLList& new_top_sites,
// point the caches haven't been updated yet.
cache_->SetTopSites(top_sites);
- // See if we have any tmp thumbnails for the new sites.
+ // See if we have any temp thumbnails for the new sites, and promote them to
+ // proper thumbnails.
if (!temp_images_.empty()) {
- for (size_t i = 0; i < top_sites.size(); ++i) {
- const MostVisitedURL& mv = top_sites[i];
- GURL canonical_url = cache_->GetCanonicalURL(mv.url);
+ for (const MostVisitedURL& mv : top_sites) {
+ const GURL& canonical_url = cache_->GetCanonicalURL(mv.url);
// At the time we get the thumbnail redirects aren't known, so we have to
// iterate through all the images.
for (TempImages::iterator it = temp_images_.begin();
diff --git a/chromium/components/history/core/browser/top_sites_impl.h b/chromium/components/history/core/browser/top_sites_impl.h
index c83cb0a883a..3024d448a4c 100644
--- a/chromium/components/history/core/browser/top_sites_impl.h
+++ b/chromium/components/history/core/browser/top_sites_impl.h
@@ -23,10 +23,8 @@
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
-#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/history/core/browser/history_types.h"
-#include "components/history/core/browser/page_usage_data.h"
#include "components/history/core/browser/top_sites.h"
#include "components/history/core/browser/top_sites_backend.h"
#include "components/history/core/common/thumbnail_score.h"
@@ -148,8 +146,7 @@ class TopSitesImpl : public TopSites, public HistoryServiceObserver {
const MostVisitedURLList& new_list,
TopSitesDelta* delta);
- // Sets the thumbnail without writing to the database. Useful when
- // reading last known top sites from the DB.
+ // Sets the thumbnail without writing to the database.
// Returns true if the thumbnail was set, false if the existing one is better.
bool SetPageThumbnailNoDB(const GURL& url,
const base::RefCountedMemory* thumbnail_data,
@@ -166,13 +163,13 @@ class TopSitesImpl : public TopSites, public HistoryServiceObserver {
static bool EncodeBitmap(const gfx::Image& bitmap,
scoped_refptr<base::RefCountedBytes>* bytes);
- // Removes the cached thumbnail for url. Does nothing if |url| if not cached
+ // Removes the cached thumbnail for |url|. Does nothing if |url| is not cached
// in |temp_images_|.
void RemoveTemporaryThumbnailByURL(const GURL& url);
- // Add a thumbnail for an unknown url. See temp_thumbnails_map_.
+ // Add a thumbnail for an unknown url. See |temp_images_|.
void AddTemporaryThumbnail(const GURL& url,
- const base::RefCountedMemory* thumbnail,
+ base::RefCountedMemory* thumbnail,
const ThumbnailScore& score);
// Called by our timer. Starts the query for the most visited sites.
@@ -187,7 +184,7 @@ class TopSitesImpl : public TopSites, public HistoryServiceObserver {
// Add prepopulated pages: 'welcome to Chrome' and themes gallery to |urls|.
// Returns true if any pages were added.
bool AddPrepopulatedPages(MostVisitedURLList* urls,
- size_t num_forced_urls);
+ size_t num_forced_urls) const;
// Add all the forced URLs from |cache_| into |new_list|, making sure not to
// add any URL that's already in |new_list|'s non-forced URLs. The forced URLs
@@ -195,7 +192,7 @@ class TopSitesImpl : public TopSites, public HistoryServiceObserver {
// and be sorted in increasing |last_forced_time|. This will still be true
// after the call. If the list of forced URLs overflows the older ones are
// dropped. Returns the number of forced URLs after the merge.
- size_t MergeCachedForcedURLs(MostVisitedURLList* new_list);
+ size_t MergeCachedForcedURLs(MostVisitedURLList* new_list) const;
// Takes |urls|, produces it's copy in |out| after removing blacklisted URLs.
// Also ensures we respect the maximum number of forced URLs and non-forced
@@ -203,11 +200,11 @@ class TopSitesImpl : public TopSites, public HistoryServiceObserver {
void ApplyBlacklist(const MostVisitedURLList& urls, MostVisitedURLList* out);
// Returns an MD5 hash of the URL. Hashing is required for blacklisted URLs.
- std::string GetURLHash(const GURL& url);
+ static std::string GetURLHash(const GURL& url);
// Returns the delay until the next update of history is needed.
- // Uses num_urls_changed
- base::TimeDelta GetUpdateDelay();
+ // Uses |last_num_urls_changed_|.
+ base::TimeDelta GetUpdateDelay() const;
// Updates URLs in |cache_| and the db (in the background).
// The non-forced URLs in |new_top_sites| replace those in |cache_|.
@@ -258,8 +255,8 @@ class TopSitesImpl : public TopSites, public HistoryServiceObserver {
std::unique_ptr<TopSitesCache> cache_;
// Copy of the top sites data that may be accessed on any thread (assuming
- // you hold |lock_|). The data in |thread_safe_cache_| has blacklisted and
- // pinned urls applied (|cache_| does not).
+ // you hold |lock_|). The data in |thread_safe_cache_| has blacklisted urls
+ // applied (|cache_| does not).
std::unique_ptr<TopSitesCache> thread_safe_cache_;
// Lock used to access |thread_safe_cache_|.
@@ -286,11 +283,11 @@ class TopSitesImpl : public TopSites, public HistoryServiceObserver {
// Stores thumbnails for unknown pages. When SetPageThumbnail is
// called, if we don't know about that URL yet and we don't have
// enough Top Sites (new profile), we store it until the next
- // SetNonForcedTopSites call.
+ // SetTopSites call.
TempImages temp_images_;
// URL List of prepopulated page.
- PrepopulatedPageList prepopulated_pages_;
+ const PrepopulatedPageList prepopulated_pages_;
// PrefService holding the NTP URL blacklist dictionary. Must outlive
// TopSitesImpl.
diff --git a/chromium/components/history/core/browser/top_sites_impl_unittest.cc b/chromium/components/history/core/browser/top_sites_impl_unittest.cc
index aaacb7352af..25c83ff3cf0 100644
--- a/chromium/components/history/core/browser/top_sites_impl_unittest.cc
+++ b/chromium/components/history/core/browser/top_sites_impl_unittest.cc
@@ -20,6 +20,7 @@
#include "components/history/core/browser/history_constants.h"
#include "components/history/core/browser/history_database_params.h"
#include "components/history/core/browser/history_db_task.h"
+#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_types.h"
#include "components/history/core/browser/top_sites.h"
#include "components/history/core/browser/top_sites_cache.h"
@@ -52,14 +53,14 @@ bool MockCanAddURLToHistory(const GURL& url) {
}
// Used for querying top sites. Either runs sequentially, or runs a nested
-// nested message loop until the response is complete. The later is used when
+// nested run loop until the response is complete. The later is used when
// TopSites is queried before it finishes loading.
class TopSitesQuerier {
public:
TopSitesQuerier()
: number_of_callbacks_(0), waiting_(false), weak_ptr_factory_(this) {}
- // Queries top sites. If |wait| is true a nested message loop is run until the
+ // Queries top sites. If |wait| is true a nested run loop is run until the
// callback is notified.
void QueryTopSites(TopSitesImpl* top_sites, bool wait) {
QueryAllTopSites(top_sites, wait, false);
diff --git a/chromium/components/history/core/browser/typed_url_sync_bridge.cc b/chromium/components/history/core/browser/typed_url_sync_bridge.cc
index 55712c82cb7..40d57d67272 100644
--- a/chromium/components/history/core/browser/typed_url_sync_bridge.cc
+++ b/chromium/components/history/core/browser/typed_url_sync_bridge.cc
@@ -4,15 +4,21 @@
#include "components/history/core/browser/typed_url_sync_bridge.h"
+#include "base/memory/ptr_util.h"
+#include "components/sync/model_impl/sync_metadata_store_change_list.h"
+
namespace history {
TypedURLSyncBridge::TypedURLSyncBridge(
HistoryBackend* history_backend,
+ syncer::SyncMetadataStore* sync_metadata_store,
const ChangeProcessorFactory& change_processor_factory)
: ModelTypeSyncBridge(change_processor_factory, syncer::TYPED_URLS),
- history_backend_(history_backend) {
+ history_backend_(history_backend),
+ sync_metadata_store_(sync_metadata_store) {
DCHECK(history_backend_);
DCHECK(sequence_checker_.CalledOnValidSequence());
+ DCHECK(sync_metadata_store_);
NOTIMPLEMENTED();
}
@@ -24,8 +30,8 @@ TypedURLSyncBridge::~TypedURLSyncBridge() {
std::unique_ptr<syncer::MetadataChangeList>
TypedURLSyncBridge::CreateMetadataChangeList() {
DCHECK(sequence_checker_.CalledOnValidSequence());
- NOTIMPLEMENTED();
- return {};
+ return base::MakeUnique<syncer::SyncMetadataStoreChangeList>(
+ sync_metadata_store_, syncer::TYPED_URLS);
}
base::Optional<syncer::ModelError> TypedURLSyncBridge::MergeSyncData(
@@ -62,8 +68,10 @@ void TypedURLSyncBridge::GetAllData(DataCallback callback) {
std::string TypedURLSyncBridge::GetClientTag(
const syncer::EntityData& entity_data) {
DCHECK(sequence_checker_.CalledOnValidSequence());
- NOTIMPLEMENTED();
- return std::string();
+ DCHECK(entity_data.specifics.has_typed_url())
+ << "EntityData does not have typed urls specifics.";
+
+ return entity_data.specifics.typed_url().url();
}
// Prefer to use URLRow::id() to uniquely identify entities when coordinating
diff --git a/chromium/components/history/core/browser/typed_url_sync_bridge.h b/chromium/components/history/core/browser/typed_url_sync_bridge.h
index 9dd05415a35..59eb0756af9 100644
--- a/chromium/components/history/core/browser/typed_url_sync_bridge.h
+++ b/chromium/components/history/core/browser/typed_url_sync_bridge.h
@@ -10,12 +10,19 @@
#include "components/sync/model/model_type_sync_bridge.h"
#include "components/sync/model/sync_error.h"
+namespace syncer {
+class SyncMetadataStore;
+}
+
namespace history {
class TypedURLSyncBridge : public syncer::ModelTypeSyncBridge,
public history::HistoryBackendObserver {
public:
+ // |sync_metadata_store| is owned by |history_backend|, and must outlive
+ // TypedURLSyncBridge.
TypedURLSyncBridge(HistoryBackend* history_backend,
+ syncer::SyncMetadataStore* sync_metadata_store,
const ChangeProcessorFactory& change_processor_factory);
~TypedURLSyncBridge() override;
@@ -48,9 +55,14 @@ class TypedURLSyncBridge : public syncer::ModelTypeSyncBridge,
const std::set<GURL>& favicon_urls) override;
private:
- // The backend we're syncing local changes from and sync changes to.
+ // A non-owning pointer to the backend, which we're syncing local changes from
+ // and sync changes to.
HistoryBackend* const history_backend_;
+ // A non-owning pointer to the database, which is for storing typed urls sync
+ // metadata and state.
+ syncer::SyncMetadataStore* const sync_metadata_store_;
+
// Since HistoryBackend use SequencedTaskRunner, so should use SequenceChecker
// here.
base::SequenceChecker sequence_checker_;
diff --git a/chromium/components/history/core/browser/typed_url_sync_metadata_database.cc b/chromium/components/history/core/browser/typed_url_sync_metadata_database.cc
index 6cc6d157746..f0b2ce6ddf3 100644
--- a/chromium/components/history/core/browser/typed_url_sync_metadata_database.cc
+++ b/chromium/components/history/core/browser/typed_url_sync_metadata_database.cc
@@ -48,8 +48,12 @@ bool TypedURLSyncMetadataDatabase::GetAllSyncMetadata(
}
bool TypedURLSyncMetadataDatabase::UpdateSyncMetadata(
+ syncer::ModelType model_type,
const std::string& storage_key,
const sync_pb::EntityMetadata& metadata) {
+ DCHECK_EQ(model_type, syncer::TYPED_URLS)
+ << "Only the TYPED_URLS model type is supported";
+
int64_t storage_key_int = 0;
if (!base::StringToInt64(storage_key, &storage_key_int)) {
return false;
@@ -64,7 +68,11 @@ bool TypedURLSyncMetadataDatabase::UpdateSyncMetadata(
}
bool TypedURLSyncMetadataDatabase::ClearSyncMetadata(
+ syncer::ModelType model_type,
const std::string& storage_key) {
+ DCHECK_EQ(model_type, syncer::TYPED_URLS)
+ << "Only the TYPED_URLS model type is supported";
+
int64_t storage_key_int = 0;
if (!base::StringToInt64(storage_key, &storage_key_int)) {
return false;
@@ -77,14 +85,20 @@ bool TypedURLSyncMetadataDatabase::ClearSyncMetadata(
}
bool TypedURLSyncMetadataDatabase::UpdateModelTypeState(
+ syncer::ModelType model_type,
const sync_pb::ModelTypeState& model_type_state) {
+ DCHECK_EQ(model_type, syncer::TYPED_URLS)
+ << "Only the TYPED_URLS model type is supported";
DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);
std::string serialized_state = model_type_state.SerializeAsString();
return GetMetaTable().SetValue(kTypedURLModelTypeStateKey, serialized_state);
}
-bool TypedURLSyncMetadataDatabase::ClearModelTypeState() {
+bool TypedURLSyncMetadataDatabase::ClearModelTypeState(
+ syncer::ModelType model_type) {
+ DCHECK_EQ(model_type, syncer::TYPED_URLS)
+ << "Only the TYPED_URLS model type is supported";
DCHECK_GT(GetMetaTable().GetVersionNumber(), 0);
return GetMetaTable().DeleteKey(kTypedURLModelTypeStateKey);
}
diff --git a/chromium/components/history/core/browser/typed_url_sync_metadata_database.h b/chromium/components/history/core/browser/typed_url_sync_metadata_database.h
index 0b687539c28..6967f48642d 100644
--- a/chromium/components/history/core/browser/typed_url_sync_metadata_database.h
+++ b/chromium/components/history/core/browser/typed_url_sync_metadata_database.h
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "components/sync/base/model_type.h"
#include "components/sync/model/metadata_batch.h"
+#include "components/sync/model/sync_metadata_store.h"
#include "sql/meta_table.h"
namespace sql {
@@ -20,30 +21,27 @@ namespace history {
// and datatype state table. Entity metadata table contains metadata(sync
// states) for each url. Datatype state table contains the state of typed url
// datatype.
-class TypedURLSyncMetadataDatabase {
+class TypedURLSyncMetadataDatabase : public syncer::SyncMetadataStore {
public:
// Must call InitVisitTable() before using to make sure the database is
// initialized.
TypedURLSyncMetadataDatabase();
- virtual ~TypedURLSyncMetadataDatabase();
+ ~TypedURLSyncMetadataDatabase() override;
// Read all the stored metadata for typed URL and fill |metadata_batch|
// with it.
bool GetAllSyncMetadata(syncer::MetadataBatch* metadata_batch);
- // Update the metadata row for typed URL, keyed by |storage_key|, to
- // contain the contents of |metadata|.
- bool UpdateSyncMetadata(const std::string& storage_key,
- const sync_pb::EntityMetadata& metadata);
-
- // Remove the metadata row of typed URL keyed by |storage_key|.
- bool ClearSyncMetadata(const std::string& storage_key);
-
- // Update the stored sync state for the typed URL.
- bool UpdateModelTypeState(const sync_pb::ModelTypeState& model_type_state);
-
- // Clear the stored sync state for typed URL.
- bool ClearModelTypeState();
+ // syncer::SyncMetadataStore implementation.
+ bool UpdateSyncMetadata(syncer::ModelType model_type,
+ const std::string& storage_key,
+ const sync_pb::EntityMetadata& metadata) override;
+ bool ClearSyncMetadata(syncer::ModelType model_type,
+ const std::string& storage_key) override;
+ bool UpdateModelTypeState(
+ syncer::ModelType model_type,
+ const sync_pb::ModelTypeState& model_type_state) override;
+ bool ClearModelTypeState(syncer::ModelType model_type) override;
protected:
// Returns the database for the functions in this interface.
diff --git a/chromium/components/history/core/browser/typed_url_sync_metadata_database_unittest.cc b/chromium/components/history/core/browser/typed_url_sync_metadata_database_unittest.cc
index 31810c615ea..c37bf3eeb7e 100644
--- a/chromium/components/history/core/browser/typed_url_sync_metadata_database_unittest.cc
+++ b/chromium/components/history/core/browser/typed_url_sync_metadata_database_unittest.cc
@@ -64,15 +64,15 @@ TEST_F(TypedURLSyncMetadataDatabaseTest, TypedURLGetAllSyncMetadata) {
std::string storage_key2 = "2";
metadata.set_sequence_number(1);
- EXPECT_TRUE(UpdateSyncMetadata(storage_key, metadata));
+ EXPECT_TRUE(UpdateSyncMetadata(syncer::TYPED_URLS, storage_key, metadata));
ModelTypeState model_type_state;
model_type_state.set_initial_sync_done(true);
- EXPECT_TRUE(UpdateModelTypeState(model_type_state));
+ EXPECT_TRUE(UpdateModelTypeState(syncer::TYPED_URLS, model_type_state));
metadata.set_sequence_number(2);
- EXPECT_TRUE(UpdateSyncMetadata(storage_key2, metadata));
+ EXPECT_TRUE(UpdateSyncMetadata(syncer::TYPED_URLS, storage_key2, metadata));
MetadataBatch metadata_batch;
EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch));
@@ -87,7 +87,7 @@ TEST_F(TypedURLSyncMetadataDatabaseTest, TypedURLGetAllSyncMetadata) {
// Now check that a model type state update replaces the old value
model_type_state.set_initial_sync_done(false);
- EXPECT_TRUE(UpdateModelTypeState(model_type_state));
+ EXPECT_TRUE(UpdateModelTypeState(syncer::TYPED_URLS, model_type_state));
EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch));
EXPECT_FALSE(metadata_batch.GetModelTypeState().initial_sync_done());
@@ -104,10 +104,10 @@ TEST_F(TypedURLSyncMetadataDatabaseTest, TypedURLWriteThenDeleteSyncMetadata) {
metadata.set_client_tag_hash("client_hash");
// Write the data into the store.
- EXPECT_TRUE(UpdateSyncMetadata(storage_key, metadata));
- EXPECT_TRUE(UpdateModelTypeState(model_type_state));
+ EXPECT_TRUE(UpdateSyncMetadata(syncer::TYPED_URLS, storage_key, metadata));
+ EXPECT_TRUE(UpdateModelTypeState(syncer::TYPED_URLS, model_type_state));
// Delete the data we just wrote.
- EXPECT_TRUE(ClearSyncMetadata(storage_key));
+ EXPECT_TRUE(ClearSyncMetadata(syncer::TYPED_URLS, storage_key));
// It shouldn't be there any more.
EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch));
@@ -115,7 +115,7 @@ TEST_F(TypedURLSyncMetadataDatabaseTest, TypedURLWriteThenDeleteSyncMetadata) {
EXPECT_EQ(metadata_records.size(), 0u);
// Now delete the model type state.
- EXPECT_TRUE(ClearModelTypeState());
+ EXPECT_TRUE(ClearModelTypeState(syncer::TYPED_URLS));
EXPECT_TRUE(GetAllSyncMetadata(&metadata_batch));
EXPECT_EQ(ModelTypeState().SerializeAsString(),
metadata_batch.GetModelTypeState().SerializeAsString());
diff --git a/chromium/components/history/core/browser/url_database.cc b/chromium/components/history/core/browser/url_database.cc
index 4a976a94aa3..4d8c5df4172 100644
--- a/chromium/components/history/core/browser/url_database.cc
+++ b/chromium/components/history/core/browser/url_database.cc
@@ -248,6 +248,9 @@ bool URLDatabase::InitURLEnumeratorForSignificant(URLEnumerator* enumerator) {
sql.append(kURLRowFields);
sql.append(" FROM urls WHERE last_visit_time >= ? OR visit_count >= ? OR "
"typed_count >= ?");
+ sql.append(
+ " ORDER BY typed_count DESC, last_visit_time DESC, visit_count "
+ "DESC");
enumerator->statement_.Assign(GetDB().GetUniqueStatement(sql.c_str()));
enumerator->statement_.BindInt64(
0, AutocompleteAgeThreshold().ToInternalValue());
@@ -652,6 +655,9 @@ base::Time AutocompleteAgeThreshold() {
bool RowQualifiesAsSignificant(const URLRow& row,
const base::Time& threshold) {
+ if (row.hidden())
+ return false;
+
const base::Time& real_threshold =
threshold.is_null() ? AutocompleteAgeThreshold() : threshold;
return (row.typed_count() >= kLowQualityMatchTypedLimit) ||
diff --git a/chromium/components/history/core/browser/url_database.h b/chromium/components/history/core/browser/url_database.h
index 1b8a5d71ee6..087e7864d68 100644
--- a/chromium/components/history/core/browser/url_database.h
+++ b/chromium/components/history/core/browser/url_database.h
@@ -150,9 +150,9 @@ class URLDatabase {
bool InitURLEnumeratorForEverything(URLEnumerator* enumerator);
// Initializes the given enumerator to enumerator all URLs in the database
- // that are historically significant: ones having been visited within 3 days,
- // having their URL manually typed more than once, or having been visited
- // more than 3 times.
+ // that are historically significant: ones having their URL manually typed
+ // more than once, having been visited within 3 days, or having been visited
+ // more than 3 times in the order of the most significant ones first.
bool InitURLEnumeratorForSignificant(URLEnumerator* enumerator);
// Autocomplete --------------------------------------------------------------
@@ -325,11 +325,11 @@ extern const int kLowQualityMatchAgeLimitInDays;
// Returns the date threshold for considering an history item as significant.
base::Time AutocompleteAgeThreshold();
-// Return true if |row| qualifies as an autocomplete candidate. If |time_cache|
+// Return true if |row| qualifies as an autocomplete candidate. If |threshold|
// is_null() then this function determines a new time threshold each time it is
// called. Since getting system time can be costly (such as for cases where
// this function will be called in a loop over many history items), you can
-// provide a non-null |time_cache| by simply initializing |time_cache| with
+// provide a non-null |threshold| by simply initializing |threshold| with
// AutocompleteAgeThreshold() (or any other desired time in the past).
bool RowQualifiesAsSignificant(const URLRow& row, const base::Time& threshold);
diff --git a/chromium/components/history/core/browser/url_database_unittest.cc b/chromium/components/history/core/browser/url_database_unittest.cc
index c9466aed55d..5b5c33c1a63 100644
--- a/chromium/components/history/core/browser/url_database_unittest.cc
+++ b/chromium/components/history/core/browser/url_database_unittest.cc
@@ -235,26 +235,35 @@ TEST_F(URLDatabaseTest, DeleteURLDeletesKeywordSearchTermVisit) {
}
TEST_F(URLDatabaseTest, EnumeratorForSignificant) {
- std::set<std::string> good_urls;
// Add URLs which do and don't meet the criteria.
URLRow url_no_match(GURL("http://www.url_no_match.com/"));
EXPECT_TRUE(AddURL(url_no_match));
- std::string url_string2("http://www.url_match_visit_count.com/");
- good_urls.insert("http://www.url_match_visit_count.com/");
- URLRow url_match_visit_count(GURL("http://www.url_match_visit_count.com/"));
- url_match_visit_count.set_visit_count(kLowQualityMatchVisitLimit);
- EXPECT_TRUE(AddURL(url_match_visit_count));
+ URLRow url_match_visit_count2(GURL("http://www.url_match_visit_count.com/"));
+ url_match_visit_count2.set_visit_count(kLowQualityMatchVisitLimit);
+ EXPECT_TRUE(AddURL(url_match_visit_count2));
- good_urls.insert("http://www.url_match_typed_count.com/");
- URLRow url_match_typed_count(GURL("http://www.url_match_typed_count.com/"));
- url_match_typed_count.set_typed_count(kLowQualityMatchTypedLimit);
- EXPECT_TRUE(AddURL(url_match_typed_count));
+ URLRow url_match_typed_count2(GURL("http://www.url_match_typed_count.com/"));
+ url_match_typed_count2.set_typed_count(kLowQualityMatchTypedLimit);
+ EXPECT_TRUE(AddURL(url_match_typed_count2));
- good_urls.insert("http://www.url_match_last_visit.com/");
- URLRow url_match_last_visit(GURL("http://www.url_match_last_visit.com/"));
- url_match_last_visit.set_last_visit(Time::Now() - TimeDelta::FromDays(1));
- EXPECT_TRUE(AddURL(url_match_last_visit));
+ URLRow url_match_last_visit2(GURL("http://www.url_match_last_visit2.com/"));
+ url_match_last_visit2.set_last_visit(Time::Now() - TimeDelta::FromDays(2));
+ EXPECT_TRUE(AddURL(url_match_last_visit2));
+
+ URLRow url_match_typed_count1(
+ GURL("http://www.url_match_higher_typed_count.com/"));
+ url_match_typed_count1.set_typed_count(kLowQualityMatchTypedLimit + 1);
+ EXPECT_TRUE(AddURL(url_match_typed_count1));
+
+ URLRow url_match_visit_count1(
+ GURL("http://www.url_match_higher_visit_count.com/"));
+ url_match_visit_count1.set_visit_count(kLowQualityMatchVisitLimit + 1);
+ EXPECT_TRUE(AddURL(url_match_visit_count1));
+
+ URLRow url_match_last_visit1(GURL("http://www.url_match_last_visit.com/"));
+ url_match_last_visit1.set_last_visit(Time::Now() - TimeDelta::FromDays(1));
+ EXPECT_TRUE(AddURL(url_match_last_visit1));
URLRow url_no_match_last_visit(GURL(
"http://www.url_no_match_last_visit.com/"));
@@ -264,11 +273,20 @@ TEST_F(URLDatabaseTest, EnumeratorForSignificant) {
URLDatabase::URLEnumerator history_enum;
EXPECT_TRUE(InitURLEnumeratorForSignificant(&history_enum));
+
+ // Vector contains urls in order of significance.
+ std::vector<std::string> good_urls;
+ good_urls.push_back("http://www.url_match_higher_typed_count.com/");
+ good_urls.push_back("http://www.url_match_typed_count.com/");
+ good_urls.push_back("http://www.url_match_last_visit.com/");
+ good_urls.push_back("http://www.url_match_last_visit2.com/");
+ good_urls.push_back("http://www.url_match_higher_visit_count.com/");
+ good_urls.push_back("http://www.url_match_visit_count.com/");
URLRow row;
int row_count = 0;
for (; history_enum.GetNextURL(&row); ++row_count)
- EXPECT_EQ(1U, good_urls.count(row.url().spec()));
- EXPECT_EQ(3, row_count);
+ EXPECT_EQ(good_urls[row_count], row.url().spec());
+ EXPECT_EQ(6, row_count);
}
// Test GetKeywordSearchTermRows and DeleteSearchTerm
diff --git a/chromium/components/history/core/test/BUILD.gn b/chromium/components/history/core/test/BUILD.gn
index 70c02fe0a55..2fd38cf2284 100644
--- a/chromium/components/history/core/test/BUILD.gn
+++ b/chromium/components/history/core/test/BUILD.gn
@@ -29,6 +29,7 @@ static_library("test") {
deps = [
"//base",
+ "//base/test:test_support",
"//components/history/core/browser",
"//components/sync/protocol:protocol",
"//net",
diff --git a/chromium/components/history/ios/browser/web_state_top_sites_observer.h b/chromium/components/history/ios/browser/web_state_top_sites_observer.h
index 1081fd221a8..367fe1fcd2f 100644
--- a/chromium/components/history/ios/browser/web_state_top_sites_observer.h
+++ b/chromium/components/history/ios/browser/web_state_top_sites_observer.h
@@ -19,13 +19,14 @@ class WebStateTopSitesObserver
: public web::WebStateObserver,
public web::WebStateUserData<WebStateTopSitesObserver> {
public:
+ ~WebStateTopSitesObserver() override;
+
static void CreateForWebState(web::WebState* web_state, TopSites* top_sites);
private:
friend class web::WebStateUserData<WebStateTopSitesObserver>;
WebStateTopSitesObserver(web::WebState* web_state, TopSites* top_sites);
- ~WebStateTopSitesObserver() override;
// web::WebStateObserver implementation.
void NavigationItemCommitted(
diff --git a/chromium/components/history/ios/browser/web_state_top_sites_observer.mm b/chromium/components/history/ios/browser/web_state_top_sites_observer.mm
index cdddbd9a240..d414a52a8dc 100644
--- a/chromium/components/history/ios/browser/web_state_top_sites_observer.mm
+++ b/chromium/components/history/ios/browser/web_state_top_sites_observer.mm
@@ -5,6 +5,7 @@
#include "components/history/ios/browser/web_state_top_sites_observer.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "components/history/core/browser/top_sites.h"
#include "ios/web/public/load_committed_details.h"
#include "ios/web/public/navigation_item.h"
@@ -22,8 +23,9 @@ void WebStateTopSitesObserver::CreateForWebState(web::WebState* web_state,
TopSites* top_sites) {
DCHECK(web_state);
if (!FromWebState(web_state)) {
- web_state->SetUserData(UserDataKey(),
- new WebStateTopSitesObserver(web_state, top_sites));
+ web_state->SetUserData(
+ UserDataKey(),
+ base::WrapUnique(new WebStateTopSitesObserver(web_state, top_sites)));
}
}
diff --git a/chromium/components/history_strings.grdp b/chromium/components/history_strings.grdp
index 46504804b80..f7da1b48b42 100644
--- a/chromium/components/history_strings.grdp
+++ b/chromium/components/history_strings.grdp
@@ -5,30 +5,16 @@
<message name="IDS_HISTORY_ACTION_MENU_DESCRIPTION" desc="Text used to identify the history entry drop-down menu for screen readers">
Actions
</message>
- <message name="IDS_HISTORY_BLOCKED_VISIT_TEXT" desc="Text that describes an attempted visit.">
- Blocked attempt <ph name="BEGIN_LINK">&lt;a target="_top" href="$1" id="$2"&gt;</ph> to visit a page on <ph name="DOMAIN">$3<ex>google.com</ex></ph><ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
- </message>
- <message name="IDS_HISTORY_BROWSERESULTS" desc="Title of browsing results page">
- History
- </message>
<message name="IDS_HISTORY_CANCEL_EDITING_BUTTON" desc="Text for the button to exit editing mode [Length: 7em].">
Cancel
</message>
- <message name="IDS_HISTORY_CONTINUED" desc="Shown after the date if the data is continued from the previous page">
- (Cont.)
- </message>
<message name="IDS_HISTORY_DATE_WITH_RELATIVE_TIME" desc="In the history view, some dates are formatted as 'Today - Wednesday, Nov 7, 2007">
<ph name="RELATIVE_DATE">$1<ex>Today</ex></ph> - <ph name="FULL_DATE">$2<ex>Wednesday, Nov 7, 2007</ex></ph>
</message>
<message name="IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON" desc="Text for the button used to confirm the dialog asking if they would like to proceed with deletion.">
Remove
</message>
- <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING" desc="Warning shown before deleting visits from the history page (reminding the user they can also use incognito mode, which doesn't store history)">
- Are you sure you want to delete these pages from your history?
-
-Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may come in handy next time.
- </message>
- <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING_NO_INCOGNITO" desc="Warning shown before deleting from the history page">
+ <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING" desc="Warning shown before deleting from the history page">
Are you sure you want to delete these pages from your history?
</message>
<message name="IDS_HISTORY_DELETE_SELECTED_ENTRIES_BUTTON" desc="Text for the button to delete selected history entries [Length: 16em].">
@@ -46,15 +32,9 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may
<message name="IDS_HISTORY_ENTRY_SUMMARY" desc="Summary of all the fields in a history entry (time, whether the entry is bookmarked, title, and domain).">
<ph name="TIME"><ex>3:14</ex>$1</ph> <ph name="BOOKMARKED"><ex>bookmarked</ex>$2</ph> <ph name="TITLE"><ex>PI: The Magical Number</ex>$3</ph> <ph name="DOMAIN"><ex>pi.com</ex>$4</ph>
</message>
- <message name="IDS_HISTORY_FILTER_BLOCKED" desc="Text that shows that an entry is blocked.">
- Blocked
- </message>
<message name="IDS_HISTORY_FOUND_SEARCH_RESULTS" desc="Message shown when zero or multiple search results are found.">
Found <ph name="NUMBER_OF_RESULTS">$1</ph> <ph name="SEARCH_RESULTS"><ex>search results</ex>$2</ph> for '<ph name="SEARCH_STRING">$3</ph>'
</message>
- <message name="IDS_HISTORY_HAS_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it is showing visits synced from other devices.">
- Showing history from your signed-in devices. <ph name="BEGIN_LINK">&lt;a href="https://support.google.com/chrome/?p=sync_history&amp;hl=[GRITLANGCODE]"&gt;</ph>Learn more<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
- </message>
<message name="IDS_HISTORY_OTHER_FORMS_OF_HISTORY" desc="The notification at the top of the history page indicating that deleting Chrome browsing history will not delete other forms of history stored at Google My Activity.">
Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>history.google.com<ph name="END_LINK">&lt;/a&gt;</ph>
</message>
@@ -64,27 +44,12 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may
<message name="IDS_HISTORY_MORE_FROM_SITE" desc="Command in the history entry drop-down menu. Shows more history entries from the same site.">
More from this site
</message>
- <message name="IDS_HISTORY_NEWER" desc="HTML text shown as page navigation tool to take the user back to the more recent page">
- Newer
- </message>
- <message name="IDS_HISTORY_NEWEST" desc="HTML text shown as page navigation tool to take the user to the top of their history">
- Newest
- </message>
<message name="IDS_HISTORY_NO_RESULTS" desc="Text shown when no history entries are found.">
No history entries found
</message>
<message name="IDS_HISTORY_NO_SEARCH_RESULTS" desc="Text shown when no history search results have been found">
No search results found
</message>
- <message name="IDS_HISTORY_NO_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it does not include visits from other devices.">
- Showing history from this device. <ph name="BEGIN_LINK">&lt;a href="https://support.google.com/chrome/?p=sync_history&amp;hl=[GRITLANGCODE]"&gt;</ph>Learn more<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
- </message>
- <message name="IDS_HISTORY_NUMBER_VISITS" desc="Format string for the number of visits of a site.">
- (<ph name="NUMBER_VISITS">$1<ex>3</ex></ph>)
- </message>
- <message name="IDS_HISTORY_OLDER" desc="HTML text shown as page navigation tool to take the user forward to their older history">
- Older
- </message>
<if expr="not use_titlecase">
<message name="IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG" desc="Title of the button that will open the clear browsing data dialog.">
Clear browsing data...
@@ -95,9 +60,6 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may
Clear Browsing Data...
</message>
</if>
- <message name="IDS_HISTORY_OTHER_DEVICES_X_MORE" desc="In the 'Other Sessions' section of the history page, the label for showing that X more tabs are available for a session.">
- <ph name="NUM_TABS_MORE">$1<ex>42</ex></ph> more...
- </message>
<if expr="not is_android">
<message name="IDS_HISTORY_OTHER_SESSIONS_COLLAPSE_SESSION" desc="In the 'Other Sessions' menu on the history page, the label for the command to collapse (hide) the list of windows and tabs in a session.">
Collapse list
@@ -112,27 +74,6 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may
Open all
</message>
</if>
- <message name="IDS_HISTORY_RANGE_ALL_TIME" desc="Option in the history range button group. Shows results a page at a time, without grouping them by domain.">
- All
- </message>
- <message name="IDS_HISTORY_RANGE_LABEL" desc="Label for the combo box that selects the time range.">
- Show
- </message>
- <message name="IDS_HISTORY_RANGE_MONTH" desc="Option in the history range button group. Shows results grouped by month.">
- Month
- </message>
- <message name="IDS_HISTORY_RANGE_NEXT" desc="The alt text on the button that moves the current time range forward.">
- Next
- </message>
- <message name="IDS_HISTORY_RANGE_PREVIOUS" desc="The alt text on the button that moves the current time range backwards.">
- Previous
- </message>
- <message name="IDS_HISTORY_RANGE_TODAY" desc="The text on the button that sets the current time range back to today.">
- Today
- </message>
- <message name="IDS_HISTORY_RANGE_WEEK" desc="Option in the history range button group. Shows results grouped by week.">
- Week
- </message>
<message name="IDS_HISTORY_REMOVE_BOOKMARK" desc="Tooltip shown when hovered over a history entry's bookmark star. When clicked, removes the bookmark.">
Remove bookmark
</message>
@@ -151,9 +92,6 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may
<message name="IDS_HISTORY_SEARCH_RESULTS" desc="Used when plural/multiple results are found.">
search results
</message>
- <message name="IDS_HISTORY_SEARCHRESULTSFOR" desc="Format string for search results">
- Search results for '<ph name="SEARCH_STRING">$1</ph>'
- </message>
<if expr="not use_titlecase">
<message name="IDS_HISTORY_SHOW_HISTORY" desc="The show history menu in the app menu">
&amp;History
diff --git a/chromium/components/image_fetcher/core/image_data_fetcher.cc b/chromium/components/image_fetcher/core/image_data_fetcher.cc
index 3eac4508d21..a58fc4ac596 100644
--- a/chromium/components/image_fetcher/core/image_data_fetcher.cc
+++ b/chromium/components/image_fetcher/core/image_data_fetcher.cc
@@ -60,19 +60,23 @@ void ImageDataFetcher::SetImageDownloadLimit(
void ImageDataFetcher::FetchImageData(
const GURL& image_url,
- const ImageDataFetcherCallback& callback) {
+ const ImageDataFetcherCallback& callback,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation) {
FetchImageData(
image_url, callback, /*referrer=*/std::string(),
- net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE);
+ net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ traffic_annotation);
}
void ImageDataFetcher::FetchImageData(
const GURL& image_url,
const ImageDataFetcherCallback& callback,
const std::string& referrer,
- net::URLRequest::ReferrerPolicy referrer_policy) {
- std::unique_ptr<net::URLFetcher> url_fetcher = net::URLFetcher::Create(
- next_url_fetcher_id_++, image_url, net::URLFetcher::GET, this);
+ net::URLRequest::ReferrerPolicy referrer_policy,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation) {
+ std::unique_ptr<net::URLFetcher> url_fetcher =
+ net::URLFetcher::Create(next_url_fetcher_id_++, image_url,
+ net::URLFetcher::GET, this, traffic_annotation);
DataUseUserData::AttachToFetcher(url_fetcher.get(), data_use_service_name_);
diff --git a/chromium/components/image_fetcher/core/image_data_fetcher.h b/chromium/components/image_fetcher/core/image_data_fetcher.h
index 169ad54d2ce..503487da2b9 100644
--- a/chromium/components/image_fetcher/core/image_data_fetcher.h
+++ b/chromium/components/image_fetcher/core/image_data_fetcher.h
@@ -15,6 +15,7 @@
#include "base/optional.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/image_fetcher/core/request_metadata.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"
@@ -52,14 +53,18 @@ class ImageDataFetcher : public net::URLFetcherDelegate {
// Fetches the raw image bytes from the given |image_url| and calls the given
// |callback|. The callback is run even if fetching the URL fails. In case
// of an error an empty string is passed to the callback.
- void FetchImageData(const GURL& image_url,
- const ImageDataFetcherCallback& callback);
+ void FetchImageData(
+ const GURL& image_url,
+ const ImageDataFetcherCallback& callback,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation);
// Like above, but lets the caller set a referrer.
- void FetchImageData(const GURL& image_url,
- const ImageDataFetcherCallback& callback,
- const std::string& referrer,
- net::URLRequest::ReferrerPolicy referrer_policy);
+ void FetchImageData(
+ const GURL& image_url,
+ const ImageDataFetcherCallback& callback,
+ const std::string& referrer,
+ net::URLRequest::ReferrerPolicy referrer_policy,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation);
private:
struct ImageDataFetcherRequest;
diff --git a/chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc b/chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc
index de47936940e..99c45a318c6 100644
--- a/chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc
+++ b/chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc
@@ -13,6 +13,7 @@
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
@@ -60,8 +61,10 @@ class ImageDataFetcherTest : public testing::Test {
TEST_F(ImageDataFetcherTest, FetchImageData) {
image_data_fetcher_.FetchImageData(
- GURL(kImageURL), base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
- base::Unretained(this)));
+ GURL(kImageURL),
+ base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
+ base::Unretained(this)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
RequestMetadata expected_metadata;
expected_metadata.mime_type = std::string("image/png");
@@ -95,8 +98,10 @@ TEST_F(ImageDataFetcherTest, FetchImageData) {
TEST_F(ImageDataFetcherTest, FetchImageData_FromCache) {
image_data_fetcher_.FetchImageData(
- GURL(kImageURL), base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
- base::Unretained(this)));
+ GURL(kImageURL),
+ base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
+ base::Unretained(this)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
RequestMetadata expected_metadata;
expected_metadata.mime_type = std::string("image/png");
@@ -128,8 +133,10 @@ TEST_F(ImageDataFetcherTest, FetchImageData_FromCache) {
TEST_F(ImageDataFetcherTest, FetchImageData_NotFound) {
image_data_fetcher_.FetchImageData(
- GURL(kImageURL), base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
- base::Unretained(this)));
+ GURL(kImageURL),
+ base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
+ base::Unretained(this)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
RequestMetadata expected_metadata;
expected_metadata.mime_type = std::string("image/png");
@@ -158,8 +165,10 @@ TEST_F(ImageDataFetcherTest, FetchImageData_NotFound) {
TEST_F(ImageDataFetcherTest, FetchImageData_WithContentLocation) {
image_data_fetcher_.FetchImageData(
- GURL(kImageURL), base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
- base::Unretained(this)));
+ GURL(kImageURL),
+ base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
+ base::Unretained(this)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
RequestMetadata expected_metadata;
expected_metadata.mime_type = std::string("image/png");
@@ -192,7 +201,8 @@ TEST_F(ImageDataFetcherTest, FetchImageData_FailedRequest) {
image_data_fetcher_.FetchImageData(
GURL(kImageURL),
base::Bind(&ImageDataFetcherTest::OnImageDataFetchedFailedRequest,
- base::Unretained(this)));
+ base::Unretained(this)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
RequestMetadata expected_metadata;
expected_metadata.http_response_code = net::URLFetcher::RESPONSE_CODE_INVALID;
@@ -216,8 +226,10 @@ TEST_F(ImageDataFetcherTest, FetchImageData_MultipleRequests) {
EXPECT_CALL(*this, OnImageDataFetchedMultipleRequests(testing::_, testing::_))
.Times(2);
- image_data_fetcher_.FetchImageData(GURL(kImageURL), callback);
- image_data_fetcher_.FetchImageData(GURL(kImageURL), callback);
+ image_data_fetcher_.FetchImageData(GURL(kImageURL), callback,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ image_data_fetcher_.FetchImageData(GURL(kImageURL), callback,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
// Multiple calls to FetchImageData for the same URL will result in
// multiple URLFetchers being created.
@@ -238,8 +250,10 @@ TEST_F(ImageDataFetcherTest, FetchImageData_CancelFetchIfImageExceedsMaxSize) {
const int64_t kMaxDownloadBytes = 1024 * 1024;
image_data_fetcher_.SetImageDownloadLimit(kMaxDownloadBytes);
image_data_fetcher_.FetchImageData(
- GURL(kImageURL), base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
- base::Unretained(this)));
+ GURL(kImageURL),
+ base::Bind(&ImageDataFetcherTest::OnImageDataFetched,
+ base::Unretained(this)),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
// Fetching an oversized image will behave like any other failed request.
// There will be exactly one call to OnImageDataFetched containing a response
diff --git a/chromium/components/image_fetcher/core/image_fetcher.h b/chromium/components/image_fetcher/core/image_fetcher.h
index 0284aee9f25..5cb084ed2df 100644
--- a/chromium/components/image_fetcher/core/image_fetcher.h
+++ b/chromium/components/image_fetcher/core/image_fetcher.h
@@ -12,6 +12,7 @@
#include "base/optional.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/image_fetcher/core/image_fetcher_delegate.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace gfx {
@@ -64,7 +65,8 @@ class ImageFetcher {
virtual void StartOrQueueNetworkRequest(
const std::string& id,
const GURL& image_url,
- const ImageFetcherCallback& callback) = 0;
+ const ImageFetcherCallback& callback,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation) = 0;
virtual ImageDecoder* GetImageDecoder() = 0;
diff --git a/chromium/components/image_fetcher/core/image_fetcher_impl.cc b/chromium/components/image_fetcher/core/image_fetcher_impl.cc
index 567928c9a6d..ccbc25cf8d7 100644
--- a/chromium/components/image_fetcher/core/image_fetcher_impl.cc
+++ b/chromium/components/image_fetcher/core/image_fetcher_impl.cc
@@ -51,7 +51,8 @@ void ImageFetcherImpl::SetImageDownloadLimit(
void ImageFetcherImpl::StartOrQueueNetworkRequest(
const std::string& id,
const GURL& image_url,
- const ImageFetcherCallback& callback) {
+ const ImageFetcherCallback& callback,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation) {
// Before starting to fetch the image. Look for a request in progress for
// |image_url|, and queue if appropriate.
ImageRequestMap::iterator it = pending_net_requests_.find(image_url);
@@ -62,10 +63,14 @@ void ImageFetcherImpl::StartOrQueueNetworkRequest(
pending_net_requests_[image_url].swap(&request);
image_data_fetcher_->FetchImageData(
- image_url, base::Bind(&ImageFetcherImpl::OnImageURLFetched,
- base::Unretained(this), image_url));
+ image_url,
+ base::Bind(&ImageFetcherImpl::OnImageURLFetched, base::Unretained(this),
+ image_url),
+ traffic_annotation);
} else {
// Request in progress. Register as an interested callback.
+ // TODO(treib,markusheintz): We're not guaranteed that the ID also matches.
+ // We probably have to store them all.
it->second.callbacks.push_back(callback);
}
}
diff --git a/chromium/components/image_fetcher/core/image_fetcher_impl.h b/chromium/components/image_fetcher/core/image_fetcher_impl.h
index 697217c7f79..d71ce20667c 100644
--- a/chromium/components/image_fetcher/core/image_fetcher_impl.h
+++ b/chromium/components/image_fetcher/core/image_fetcher_impl.h
@@ -16,6 +16,7 @@
#include "components/image_fetcher/core/image_data_fetcher.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/image_fetcher/core/image_fetcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
@@ -30,7 +31,7 @@ class URLRequestContextGetter;
namespace image_fetcher {
// The standard (non-test) implementation of ImageFetcher.
-class ImageFetcherImpl : public image_fetcher::ImageFetcher {
+class ImageFetcherImpl : public ImageFetcher {
public:
ImageFetcherImpl(std::unique_ptr<ImageDecoder> image_decoder,
net::URLRequestContextGetter* url_request_context);
@@ -52,7 +53,8 @@ class ImageFetcherImpl : public image_fetcher::ImageFetcher {
void StartOrQueueNetworkRequest(
const std::string& id,
const GURL& image_url,
- const ImageFetcherCallback& callback) override;
+ const ImageFetcherCallback& callback,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation) override;
ImageDecoder* GetImageDecoder() override;
diff --git a/chromium/components/image_fetcher/ios/BUILD.gn b/chromium/components/image_fetcher/ios/BUILD.gn
index 9ad5c7edc70..99ab37a4171 100644
--- a/chromium/components/image_fetcher/ios/BUILD.gn
+++ b/chromium/components/image_fetcher/ios/BUILD.gn
@@ -17,6 +17,7 @@ source_set("ios") {
"//ios/web",
"//net",
"//third_party/libwebp:libwebp_dec",
+ "//third_party/libwebp:libwebp_webp",
"//ui/gfx",
]
configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm b/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm
index 2d20ff0b92a..973abb755d6 100644
--- a/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm
+++ b/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm
@@ -11,6 +11,7 @@
#import "components/image_fetcher/ios/webp_decoder.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "url/url_constants.h"
@@ -36,7 +37,8 @@ void IOSImageDataFetcherWrapper::FetchImageDataWebpDecoded(
const GURL& image_url,
IOSImageDataFetcherCallback callback) {
image_data_fetcher_.FetchImageData(image_url,
- CallbackForImageDataFetcher(callback));
+ CallbackForImageDataFetcher(callback),
+ NO_TRAFFIC_ANNOTATION_YET);
}
void IOSImageDataFetcherWrapper::FetchImageDataWebpDecoded(
@@ -46,9 +48,9 @@ void IOSImageDataFetcherWrapper::FetchImageDataWebpDecoded(
net::URLRequest::ReferrerPolicy referrer_policy) {
DCHECK(callback);
- image_data_fetcher_.FetchImageData(image_url,
- CallbackForImageDataFetcher(callback),
- referrer, referrer_policy);
+ image_data_fetcher_.FetchImageData(
+ image_url, CallbackForImageDataFetcher(callback), referrer,
+ referrer_policy, NO_TRAFFIC_ANNOTATION_YET);
}
void IOSImageDataFetcherWrapper::SetDataUseServiceName(
diff --git a/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm b/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm
index b54eaf9e0e2..27224a2aeef 100644
--- a/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm
+++ b/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/image_fetcher/ios/ios_image_decoder_impl_unittest.mm b/chromium/components/image_fetcher/ios/ios_image_decoder_impl_unittest.mm
index b83a127b3aa..29da4e9ecdf 100644
--- a/chromium/components/image_fetcher/ios/ios_image_decoder_impl_unittest.mm
+++ b/chromium/components/image_fetcher/ios/ios_image_decoder_impl_unittest.mm
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/infobars/core/infobar_delegate.h b/chromium/components/infobars/core/infobar_delegate.h
index c041844b9d4..4de05e5c7b0 100644
--- a/chromium/components/infobars/core/infobar_delegate.h
+++ b/chromium/components/infobars/core/infobar_delegate.h
@@ -145,6 +145,8 @@ class InfoBarDelegate {
SEARCH_GEOLOCATION_DISCLOSURE_INFOBAR_DELEGATE = 72,
AUTOMATION_INFOBAR_DELEGATE = 73,
VR_SERVICES_UPGRADE_ANDROID = 74,
+ READER_MODE_INFOBAR_ANDROID = 75,
+ VR_FEEDBACK_INFOBAR_ANDROID = 76,
};
// Describes navigation events, used to decide whether infobars should be
diff --git a/chromium/components/json_schema/json_schema_validator_unittest_base.cc b/chromium/components/json_schema/json_schema_validator_unittest_base.cc
index d96544c31d2..d49bb0679c3 100644
--- a/chromium/components/json_schema/json_schema_validator_unittest_base.cc
+++ b/chromium/components/json_schema/json_schema_validator_unittest_base.cc
@@ -398,7 +398,7 @@ void JSONSchemaValidatorTestBase::TestArrayTuple() {
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
JSONSchemaValidator::kArrayItemRequired);
- instance->Set(0, new base::Value(42));
+ instance->Set(0, base::MakeUnique<base::Value>(42));
instance->AppendInteger(42);
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
JSONSchemaValidator::FormatErrorMessage(
@@ -409,10 +409,10 @@ void JSONSchemaValidatorTestBase::TestArrayTuple() {
base::DictionaryValue* additional_properties = new base::DictionaryValue();
additional_properties->SetString(schema::kType, schema::kAny);
schema->Set(schema::kAdditionalProperties, additional_properties);
- instance->Set(0, new base::Value("42"));
+ instance->Set(0, base::MakeUnique<base::Value>("42"));
instance->AppendString("anything");
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
- instance->Set(2, new base::ListValue());
+ instance->Set(2, base::MakeUnique<base::ListValue>());
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
additional_properties->SetString(schema::kType, schema::kBoolean);
@@ -421,7 +421,7 @@ void JSONSchemaValidatorTestBase::TestArrayTuple() {
JSONSchemaValidator::kInvalidType,
schema::kBoolean,
schema::kArray));
- instance->Set(2, new base::Value(false));
+ instance->Set(2, base::MakeUnique<base::Value>(false));
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
base::ListValue* items_schema = NULL;
@@ -435,7 +435,7 @@ void JSONSchemaValidatorTestBase::TestArrayTuple() {
// for objects.
instance->Set(0, base::MakeUnique<base::Value>());
ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
- instance->Set(0, new base::Value(42));
+ instance->Set(0, base::MakeUnique<base::Value>(42));
ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
JSONSchemaValidator::FormatErrorMessage(
JSONSchemaValidator::kInvalidType,
diff --git a/chromium/components/leveldb/BUILD.gn b/chromium/components/leveldb/BUILD.gn
index 68eb41947d6..6c343f4a77e 100644
--- a/chromium/components/leveldb/BUILD.gn
+++ b/chromium/components/leveldb/BUILD.gn
@@ -48,7 +48,6 @@ service("leveldb") {
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
"//services/service_manager/public/cpp",
- "//services/tracing/public/cpp",
]
}
@@ -73,8 +72,8 @@ service_test("leveldb_service_unittests") {
"//mojo/common",
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
+ "//services/service_manager/public/cpp",
"//services/service_manager/public/cpp:service_test_support",
- "//services/service_manager/public/cpp:sources",
"//third_party/leveldatabase",
]
diff --git a/chromium/components/leveldb/DEPS b/chromium/components/leveldb/DEPS
index af1a7ae3aaa..659b133e9d5 100644
--- a/chromium/components/leveldb/DEPS
+++ b/chromium/components/leveldb/DEPS
@@ -4,6 +4,5 @@ include_rules = [
"+mojo/public",
"+mojo/util",
"+services/service_manager",
- "+services/tracing/public/cpp",
"+third_party/leveldatabase",
]
diff --git a/chromium/components/leveldb/OWNERS b/chromium/components/leveldb/OWNERS
index 4733a4f06bf..0b74fef95fe 100644
--- a/chromium/components/leveldb/OWNERS
+++ b/chromium/components/leveldb/OWNERS
@@ -1 +1,2 @@
erg@chromium.org
+mek@chromium.org
diff --git a/chromium/components/leveldb/env_mojo.cc b/chromium/components/leveldb/env_mojo.cc
index 4f82181a5a3..9b98405d125 100644
--- a/chromium/components/leveldb/env_mojo.cc
+++ b/chromium/components/leveldb/env_mojo.cc
@@ -8,13 +8,17 @@
#include <memory>
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/trace_event/trace_event.h"
#include "third_party/leveldatabase/chromium_logger.h"
-#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
+using filesystem::mojom::FileError;
+using leveldb_env::UMALogger;
+
namespace leveldb {
namespace {
@@ -29,10 +33,10 @@ base::File::Error LastFileError() {
#endif
}
-Status FilesystemErrorToStatus(filesystem::mojom::FileError error,
+Status FilesystemErrorToStatus(FileError error,
const std::string& filename,
leveldb_env::MethodID method) {
- if (error == filesystem::mojom::FileError::OK)
+ if (error == FileError::OK)
return Status::OK();
std::string err_str =
@@ -65,8 +69,10 @@ class MojoFileLock : public FileLock {
class MojoSequentialFile : public leveldb::SequentialFile {
public:
- MojoSequentialFile(const std::string& fname, base::File f)
- : filename_(fname), file_(std::move(f)) {}
+ MojoSequentialFile(const std::string& fname,
+ base::File f,
+ const UMALogger* uma_logger)
+ : filename_(fname), file_(std::move(f)), uma_logger_(uma_logger) {}
~MojoSequentialFile() override {}
Status Read(size_t n, Slice* result, char* scratch) override {
@@ -75,17 +81,20 @@ class MojoSequentialFile : public leveldb::SequentialFile {
static_cast<int>(n));
if (bytes_read == -1) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kSequentialFileRead, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kSequentialFileRead, error);
- } else {
- *result = Slice(scratch, bytes_read);
- return Status::OK();
}
+ if (bytes_read > 0)
+ uma_logger_->RecordBytesRead(bytes_read);
+ *result = Slice(scratch, bytes_read);
+ return Status::OK();
}
Status Skip(uint64_t n) override {
if (file_.Seek(base::File::FROM_CURRENT, n) == -1) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kSequentialFileSkip, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kSequentialFileSkip, error);
} else {
@@ -96,34 +105,40 @@ class MojoSequentialFile : public leveldb::SequentialFile {
private:
std::string filename_;
base::File file_;
+ const UMALogger* uma_logger_;
DISALLOW_COPY_AND_ASSIGN(MojoSequentialFile);
};
class MojoRandomAccessFile : public leveldb::RandomAccessFile {
public:
- MojoRandomAccessFile(const std::string& fname, base::File file)
- : filename_(fname), file_(std::move(file)) {}
+ MojoRandomAccessFile(const std::string& fname,
+ base::File file,
+ const UMALogger* uma_logger)
+ : filename_(fname), file_(std::move(file)), uma_logger_(uma_logger) {}
~MojoRandomAccessFile() override {}
Status Read(uint64_t offset,
size_t n,
Slice* result,
char* scratch) const override {
- Status s;
- int r = file_.Read(offset, scratch, static_cast<int>(n));
- *result = Slice(scratch, (r < 0) ? 0 : r);
- if (r < 0) {
- // An error: return a non-ok status
- s = MakeIOError(filename_, "Could not perform read",
- leveldb_env::kRandomAccessFileRead);
+ int bytes_read = file_.Read(offset, scratch, static_cast<int>(n));
+ *result = Slice(scratch, (bytes_read < 0) ? 0 : bytes_read);
+ if (bytes_read < 0) {
+ uma_logger_->RecordOSError(leveldb_env::kRandomAccessFileRead,
+ LastFileError());
+ return MakeIOError(filename_, "Could not perform read",
+ leveldb_env::kRandomAccessFileRead);
}
- return s;
+ if (bytes_read > 0)
+ uma_logger_->RecordBytesRead(bytes_read);
+ return Status::OK();
}
private:
std::string filename_;
mutable base::File file_;
+ const UMALogger* uma_logger_;
DISALLOW_COPY_AND_ASSIGN(MojoRandomAccessFile);
};
@@ -133,12 +148,14 @@ class MojoWritableFile : public leveldb::WritableFile {
MojoWritableFile(LevelDBMojoProxy::OpaqueDir* dir,
const std::string& fname,
base::File f,
- scoped_refptr<LevelDBMojoProxy> thread)
+ scoped_refptr<LevelDBMojoProxy> thread,
+ const UMALogger* uma_logger)
: filename_(fname),
file_(std::move(f)),
file_type_(kOther),
dir_(dir),
- thread_(thread) {
+ thread_(thread),
+ uma_logger_(uma_logger) {
base::FilePath path = base::FilePath::FromUTF8Unsafe(fname);
if (base::StartsWith(path.BaseName().AsUTF8Unsafe(), "MANIFEST",
base::CompareCase::SENSITIVE)) {
@@ -153,14 +170,16 @@ class MojoWritableFile : public leveldb::WritableFile {
~MojoWritableFile() override {}
leveldb::Status Append(const leveldb::Slice& data) override {
- size_t bytes_written = file_.WriteAtCurrentPos(
- data.data(), static_cast<int>(data.size()));
- if (bytes_written != data.size()) {
+ int bytes_written =
+ file_.WriteAtCurrentPos(data.data(), static_cast<int>(data.size()));
+ if (bytes_written != static_cast<int>(data.size())) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kWritableFileAppend, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kWritableFileAppend, error);
}
-
+ if (bytes_written > 0)
+ uma_logger_->RecordBytesWritten(bytes_written);
return Status::OK();
}
@@ -171,8 +190,7 @@ class MojoWritableFile : public leveldb::WritableFile {
leveldb::Status Flush() override {
// base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing
- // to
- // flush.
+ // to flush.
return Status::OK();
}
@@ -181,6 +199,7 @@ class MojoWritableFile : public leveldb::WritableFile {
if (!file_.Flush()) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kWritableFileSync, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kWritableFileSync, error);
}
@@ -198,9 +217,8 @@ class MojoWritableFile : public leveldb::WritableFile {
enum Type { kManifest, kTable, kOther };
leveldb::Status SyncParent() {
- filesystem::mojom::FileError error =
- thread_->SyncDirectory(dir_, parent_dir_);
- return error == filesystem::mojom::FileError::OK
+ FileError error = thread_->SyncDirectory(dir_, parent_dir_);
+ return error == FileError::OK
? Status::OK()
: Status::IOError(filename_,
base::File::ErrorToString(base::File::Error(
@@ -213,6 +231,7 @@ class MojoWritableFile : public leveldb::WritableFile {
LevelDBMojoProxy::OpaqueDir* dir_;
std::string parent_dir_;
scoped_refptr<LevelDBMojoProxy> thread_;
+ const UMALogger* uma_logger_;
DISALLOW_COPY_AND_ASSIGN(MojoWritableFile);
};
@@ -255,11 +274,12 @@ Status MojoEnv::NewSequentialFile(const std::string& fname,
dir_, fname, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead);
if (!f.IsValid()) {
*result = nullptr;
+ RecordOSError(leveldb_env::kNewSequentialFile, f.error_details());
return MakeIOError(fname, "Unable to create sequential file",
leveldb_env::kNewSequentialFile, f.error_details());
}
- *result = new MojoSequentialFile(fname, std::move(f));
+ *result = new MojoSequentialFile(fname, std::move(f), this);
return Status::OK();
}
@@ -271,11 +291,12 @@ Status MojoEnv::NewRandomAccessFile(const std::string& fname,
if (!f.IsValid()) {
*result = nullptr;
base::File::Error error_code = f.error_details();
+ RecordOSError(leveldb_env::kNewRandomAccessFile, error_code);
return MakeIOError(fname, base::File::ErrorToString(error_code),
leveldb_env::kNewRandomAccessFile, error_code);
}
- *result = new MojoRandomAccessFile(fname, std::move(f));
+ *result = new MojoRandomAccessFile(fname, std::move(f), this);
return Status::OK();
}
@@ -287,11 +308,12 @@ Status MojoEnv::NewWritableFile(const std::string& fname,
filesystem::mojom::kFlagWrite);
if (!f.IsValid()) {
*result = nullptr;
+ RecordOSError(leveldb_env::kNewWritableFile, f.error_details());
return MakeIOError(fname, "Unable to create writable file",
leveldb_env::kNewWritableFile, f.error_details());
}
- *result = new MojoWritableFile(dir_, fname, std::move(f), thread_);
+ *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
return Status::OK();
}
@@ -303,11 +325,12 @@ Status MojoEnv::NewAppendableFile(const std::string& fname,
filesystem::mojom::kFlagAppend);
if (!f.IsValid()) {
*result = nullptr;
+ RecordOSError(leveldb_env::kNewAppendableFile, f.error_details());
return MakeIOError(fname, "Unable to create appendable file",
leveldb_env::kNewAppendableFile, f.error_details());
}
- *result = new MojoWritableFile(dir_, fname, std::move(f), thread_);
+ *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
return Status::OK();
}
@@ -319,48 +342,62 @@ bool MojoEnv::FileExists(const std::string& fname) {
Status MojoEnv::GetChildren(const std::string& path,
std::vector<std::string>* result) {
TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path);
- return FilesystemErrorToStatus(thread_->GetChildren(dir_, path, result), path,
- leveldb_env::kGetChildren);
+ FileError error = thread_->GetChildren(dir_, path, result);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kGetChildren, error);
+ return FilesystemErrorToStatus(error, path, leveldb_env::kGetChildren);
}
Status MojoEnv::DeleteFile(const std::string& fname) {
TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname);
- return FilesystemErrorToStatus(thread_->Delete(dir_, fname, 0), fname,
- leveldb_env::kDeleteFile);
+ FileError error = thread_->Delete(dir_, fname, 0);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kDeleteFile, error);
+ return FilesystemErrorToStatus(error, fname, leveldb_env::kDeleteFile);
}
Status MojoEnv::CreateDir(const std::string& dirname) {
TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname);
- return FilesystemErrorToStatus(thread_->CreateDir(dir_, dirname), dirname,
- leveldb_env::kCreateDir);
+ FileError error = thread_->CreateDir(dir_, dirname);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kCreateDir, error);
+ return FilesystemErrorToStatus(error, dirname, leveldb_env::kCreateDir);
}
Status MojoEnv::DeleteDir(const std::string& dirname) {
TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname);
- return FilesystemErrorToStatus(
- thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive),
- dirname, leveldb_env::kDeleteDir);
+ FileError error =
+ thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kDeleteDir, error);
+ return FilesystemErrorToStatus(error, dirname, leveldb_env::kDeleteDir);
}
Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) {
TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname);
- return FilesystemErrorToStatus(thread_->GetFileSize(dir_, fname, file_size),
- fname,
- leveldb_env::kGetFileSize);
+ FileError error = thread_->GetFileSize(dir_, fname, file_size);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kGetFileSize, error);
+ return FilesystemErrorToStatus(error, fname, leveldb_env::kGetFileSize);
}
Status MojoEnv::RenameFile(const std::string& src, const std::string& target) {
TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target);
- return FilesystemErrorToStatus(thread_->RenameFile(dir_, src, target), src,
- leveldb_env::kRenameFile);
+ FileError error = thread_->RenameFile(dir_, src, target);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kRenameFile, error);
+ return FilesystemErrorToStatus(error, src, leveldb_env::kRenameFile);
}
Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) {
TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname);
- std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*> p =
+ std::pair<FileError, LevelDBMojoProxy::OpaqueLock*> p =
thread_->LockFile(dir_, fname);
+ if (p.first != FileError::OK)
+ RecordFileError(leveldb_env::kLockFile, p.first);
+
if (p.second)
*lock = new MojoFileLock(p.second, fname);
@@ -373,9 +410,11 @@ Status MojoEnv::UnlockFile(FileLock* lock) {
std::string fname = my_lock ? my_lock->name() : "(invalid)";
TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname);
- filesystem::mojom::FileError err = thread_->UnlockFile(my_lock->TakeLock());
+ FileError error = thread_->UnlockFile(my_lock->TakeLock());
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kUnlockFile, error);
delete my_lock;
- return FilesystemErrorToStatus(err, fname, leveldb_env::kUnlockFile);
+ return FilesystemErrorToStatus(error, fname, leveldb_env::kUnlockFile);
}
Status MojoEnv::GetTestDirectory(std::string* path) {
@@ -395,6 +434,7 @@ Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite));
if (!f.IsValid()) {
*result = NULL;
+ RecordOSError(leveldb_env::kNewLogger, f.error_details());
return MakeIOError(fname, "Unable to create log file",
leveldb_env::kNewLogger, f.error_details());
} else {
@@ -403,6 +443,32 @@ Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
}
}
+void MojoEnv::RecordErrorAt(leveldb_env::MethodID method) const {
+ UMA_HISTOGRAM_ENUMERATION("MojoLevelDBEnv.IOError", method,
+ leveldb_env::kNumEntries);
+}
+
+void MojoEnv::RecordOSError(leveldb_env::MethodID method,
+ base::File::Error error) const {
+ RecordErrorAt(method);
+ std::string uma_name =
+ std::string("MojoLevelDBEnv.IOError.BFE.") + MethodIDToString(method);
+ base::UmaHistogramExactLinear(uma_name, -error, -base::File::FILE_ERROR_MAX);
+}
+
+void MojoEnv::RecordBytesRead(int amount) const {
+ UMA_HISTOGRAM_COUNTS_10M("Storage.BytesRead.MojoLevelDBEnv", amount);
+}
+
+void MojoEnv::RecordBytesWritten(int amount) const {
+ UMA_HISTOGRAM_COUNTS_10M("Storage.BytesWritten.MojoLevelDBEnv", amount);
+}
+
+void MojoEnv::RecordFileError(leveldb_env::MethodID method,
+ FileError error) const {
+ RecordOSError(method, static_cast<base::File::Error>(error));
+}
+
uint64_t MojoEnv::NowMicros() {
return base::TimeTicks::Now().ToInternalValue();
}
@@ -413,7 +479,10 @@ void MojoEnv::SleepForMicroseconds(int micros) {
}
void MojoEnv::Schedule(void (*function)(void* arg), void* arg) {
- base::PostTask(FROM_HERE, base::Bind(function, arg));
+ base::PostTaskWithTraits(FROM_HERE,
+ {base::MayBlock(), base::WithBaseSyncPrimitives(),
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+ base::Bind(function, arg));
}
void MojoEnv::StartThread(void (*function)(void* arg), void* arg) {
diff --git a/chromium/components/leveldb/env_mojo.h b/chromium/components/leveldb/env_mojo.h
index 8af9ef4aebc..ca0f683902e 100644
--- a/chromium/components/leveldb/env_mojo.h
+++ b/chromium/components/leveldb/env_mojo.h
@@ -7,6 +7,7 @@
#include "components/filesystem/public/interfaces/directory.mojom.h"
#include "components/leveldb/leveldb_mojo_proxy.h"
+#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/env.h"
namespace leveldb {
@@ -16,7 +17,7 @@ namespace leveldb {
// synchronous and block on responses from the filesystem service. That's fine
// since, for the most part, they merely open files or check for a file's
// existence.
-class MojoEnv : public leveldb::Env {
+class MojoEnv : public Env, public leveldb_env::UMALogger {
public:
MojoEnv(scoped_refptr<LevelDBMojoProxy> file_thread,
LevelDBMojoProxy::OpaqueDir* dir);
@@ -50,6 +51,15 @@ class MojoEnv : public leveldb::Env {
void StartThread(void (*function)(void* arg), void* arg) override;
private:
+ void RecordErrorAt(leveldb_env::MethodID method) const override;
+ void RecordOSError(leveldb_env::MethodID method,
+ base::File::Error error) const override;
+ void RecordBytesRead(int amount) const override;
+ void RecordBytesWritten(int amount) const override;
+
+ void RecordFileError(leveldb_env::MethodID method,
+ filesystem::mojom::FileError error) const;
+
scoped_refptr<LevelDBMojoProxy> thread_;
LevelDBMojoProxy::OpaqueDir* dir_;
diff --git a/chromium/components/leveldb/leveldb_app.cc b/chromium/components/leveldb/leveldb_app.cc
index 93086f77aa5..cd5447ea05e 100644
--- a/chromium/components/leveldb/leveldb_app.cc
+++ b/chromium/components/leveldb/leveldb_app.cc
@@ -10,24 +10,23 @@
namespace leveldb {
LevelDBApp::LevelDBApp() : file_thread_("LevelDBFile") {
- registry_.AddInterface<mojom::LevelDBService>(this);
+ registry_.AddInterface<mojom::LevelDBService>(
+ base::Bind(&LevelDBApp::Create, base::Unretained(this)));
}
LevelDBApp::~LevelDBApp() {}
-void LevelDBApp::OnStart() {
- tracing_.Initialize(context()->connector(), context()->identity().name());
-}
+void LevelDBApp::OnStart() {}
void LevelDBApp::OnBindInterface(
- const service_manager::ServiceInfo& source_info,
+ const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
- registry_.BindInterface(source_info.identity, interface_name,
+ registry_.BindInterface(source_info, interface_name,
std::move(interface_pipe));
}
-void LevelDBApp::Create(const service_manager::Identity& remote_identity,
+void LevelDBApp::Create(const service_manager::BindSourceInfo& source_info,
leveldb::mojom::LevelDBServiceRequest request) {
if (!service_) {
if (!file_thread_.IsRunning())
diff --git a/chromium/components/leveldb/leveldb_app.h b/chromium/components/leveldb/leveldb_app.h
index 1898f525984..78d542b3437 100644
--- a/chromium/components/leveldb/leveldb_app.h
+++ b/chromium/components/leveldb/leveldb_app.h
@@ -11,15 +11,11 @@
#include "components/leveldb/public/interfaces/leveldb.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/binder_registry.h"
-#include "services/service_manager/public/cpp/interface_factory.h"
#include "services/service_manager/public/cpp/service.h"
-#include "services/tracing/public/cpp/provider.h"
namespace leveldb {
-class LevelDBApp
- : public service_manager::Service,
- public service_manager::InterfaceFactory<mojom::LevelDBService> {
+class LevelDBApp : public service_manager::Service {
public:
LevelDBApp();
~LevelDBApp() override;
@@ -27,15 +23,13 @@ class LevelDBApp
private:
// |Service| override:
void OnStart() override;
- void OnBindInterface(const service_manager::ServiceInfo& source_info,
+ void OnBindInterface(const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
- // |InterfaceFactory<mojom::LevelDBService>| implementation:
- void Create(const service_manager::Identity& remote_identity,
- leveldb::mojom::LevelDBServiceRequest request) override;
+ void Create(const service_manager::BindSourceInfo& source_info,
+ leveldb::mojom::LevelDBServiceRequest request);
- tracing::Provider tracing_;
std::unique_ptr<mojom::LevelDBService> service_;
service_manager::BinderRegistry registry_;
mojo::BindingSet<mojom::LevelDBService> bindings_;
diff --git a/chromium/components/leveldb/leveldb_database_impl.cc b/chromium/components/leveldb/leveldb_database_impl.cc
index 5387409d2d4..59ab0787066 100644
--- a/chromium/components/leveldb/leveldb_database_impl.cc
+++ b/chromium/components/leveldb/leveldb_database_impl.cc
@@ -6,6 +6,7 @@
#include <map>
#include <string>
+#include <utility>
#include "base/optional.h"
#include "base/rand_util.h"
@@ -48,33 +49,32 @@ LevelDBDatabaseImpl::~LevelDBDatabaseImpl() {
void LevelDBDatabaseImpl::Put(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
- const PutCallback& callback) {
+ PutCallback callback) {
leveldb::Status status =
db_->Put(leveldb::WriteOptions(), GetSliceFor(key), GetSliceFor(value));
- callback.Run(LeveldbStatusToError(status));
+ std::move(callback).Run(LeveldbStatusToError(status));
}
void LevelDBDatabaseImpl::Delete(const std::vector<uint8_t>& key,
- const DeleteCallback& callback) {
+ DeleteCallback callback) {
leveldb::Status status =
db_->Delete(leveldb::WriteOptions(), GetSliceFor(key));
- callback.Run(LeveldbStatusToError(status));
+ std::move(callback).Run(LeveldbStatusToError(status));
}
-void LevelDBDatabaseImpl::DeletePrefixed(
- const std::vector<uint8_t>& key_prefix,
- const DeletePrefixedCallback& callback) {
+void LevelDBDatabaseImpl::DeletePrefixed(const std::vector<uint8_t>& key_prefix,
+ DeletePrefixedCallback callback) {
leveldb::WriteBatch batch;
leveldb::Status status = DeletePrefixedHelper(
GetSliceFor(key_prefix), &batch);
if (status.ok())
status = db_->Write(leveldb::WriteOptions(), &batch);
- callback.Run(LeveldbStatusToError(status));
+ std::move(callback).Run(LeveldbStatusToError(status));
}
void LevelDBDatabaseImpl::Write(
std::vector<mojom::BatchedOperationPtr> operations,
- const WriteCallback& callback) {
+ WriteCallback callback) {
leveldb::WriteBatch batch;
for (size_t i = 0; i < operations.size(); ++i) {
@@ -100,19 +100,20 @@ void LevelDBDatabaseImpl::Write(
}
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
- callback.Run(LeveldbStatusToError(status));
+ std::move(callback).Run(LeveldbStatusToError(status));
}
void LevelDBDatabaseImpl::Get(const std::vector<uint8_t>& key,
- const GetCallback& callback) {
+ GetCallback callback) {
std::string value;
leveldb::Status status =
db_->Get(leveldb::ReadOptions(), GetSliceFor(key), &value);
- callback.Run(LeveldbStatusToError(status), StdStringToUint8Vector(value));
+ std::move(callback).Run(LeveldbStatusToError(status),
+ StdStringToUint8Vector(value));
}
void LevelDBDatabaseImpl::GetPrefixed(const std::vector<uint8_t>& key_prefix,
- const GetPrefixedCallback& callback) {
+ GetPrefixedCallback callback) {
std::vector<mojom::KeyValuePtr> data;
leveldb::Status status = ForEachWithPrefix(
db_.get(), GetSliceFor(key_prefix),
@@ -122,14 +123,14 @@ void LevelDBDatabaseImpl::GetPrefixed(const std::vector<uint8_t>& key_prefix,
kv->value = GetVectorFor(value);
data.push_back(std::move(kv));
});
- callback.Run(LeveldbStatusToError(status), std::move(data));
+ std::move(callback).Run(LeveldbStatusToError(status), std::move(data));
}
-void LevelDBDatabaseImpl::GetSnapshot(const GetSnapshotCallback& callback) {
+void LevelDBDatabaseImpl::GetSnapshot(GetSnapshotCallback callback) {
const Snapshot* s = db_->GetSnapshot();
base::UnguessableToken token = base::UnguessableToken::Create();
snapshot_map_.insert(std::make_pair(token, s));
- callback.Run(token);
+ std::move(callback).Run(token);
}
void LevelDBDatabaseImpl::ReleaseSnapshot(
@@ -144,12 +145,12 @@ void LevelDBDatabaseImpl::ReleaseSnapshot(
void LevelDBDatabaseImpl::GetFromSnapshot(
const base::UnguessableToken& snapshot,
const std::vector<uint8_t>& key,
- const GetCallback& callback) {
+ GetCallback callback) {
// If the snapshot id is invalid, send back invalid argument
auto it = snapshot_map_.find(snapshot);
if (it == snapshot_map_.end()) {
- callback.Run(mojom::DatabaseError::INVALID_ARGUMENT,
- std::vector<uint8_t>());
+ std::move(callback).Run(mojom::DatabaseError::INVALID_ARGUMENT,
+ std::vector<uint8_t>());
return;
}
@@ -157,23 +158,24 @@ void LevelDBDatabaseImpl::GetFromSnapshot(
leveldb::ReadOptions options;
options.snapshot = it->second;
leveldb::Status status = db_->Get(options, GetSliceFor(key), &value);
- callback.Run(LeveldbStatusToError(status), StdStringToUint8Vector(value));
+ std::move(callback).Run(LeveldbStatusToError(status),
+ StdStringToUint8Vector(value));
}
-void LevelDBDatabaseImpl::NewIterator(const NewIteratorCallback& callback) {
+void LevelDBDatabaseImpl::NewIterator(NewIteratorCallback callback) {
Iterator* iterator = db_->NewIterator(leveldb::ReadOptions());
base::UnguessableToken token = base::UnguessableToken::Create();
iterator_map_.insert(std::make_pair(token, iterator));
- callback.Run(token);
+ std::move(callback).Run(token);
}
void LevelDBDatabaseImpl::NewIteratorFromSnapshot(
const base::UnguessableToken& snapshot,
- const NewIteratorFromSnapshotCallback& callback) {
+ NewIteratorFromSnapshotCallback callback) {
// If the snapshot id is invalid, send back invalid argument
auto it = snapshot_map_.find(snapshot);
if (it == snapshot_map_.end()) {
- callback.Run(base::Optional<base::UnguessableToken>());
+ std::move(callback).Run(base::Optional<base::UnguessableToken>());
return;
}
@@ -183,7 +185,7 @@ void LevelDBDatabaseImpl::NewIteratorFromSnapshot(
Iterator* iterator = db_->NewIterator(options);
base::UnguessableToken new_token = base::UnguessableToken::Create();
iterator_map_.insert(std::make_pair(new_token, iterator));
- callback.Run(new_token);
+ std::move(callback).Run(new_token);
}
void LevelDBDatabaseImpl::ReleaseIterator(
@@ -197,89 +199,88 @@ void LevelDBDatabaseImpl::ReleaseIterator(
void LevelDBDatabaseImpl::IteratorSeekToFirst(
const base::UnguessableToken& iterator,
- const IteratorSeekToFirstCallback& callback) {
+ IteratorSeekToFirstCallback callback) {
auto it = iterator_map_.find(iterator);
if (it == iterator_map_.end()) {
- callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt,
- base::nullopt);
+ std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
+ base::nullopt, base::nullopt);
return;
}
it->second->SeekToFirst();
- ReplyToIteratorMessage(it->second, callback);
+ ReplyToIteratorMessage(it->second, std::move(callback));
}
void LevelDBDatabaseImpl::IteratorSeekToLast(
const base::UnguessableToken& iterator,
- const IteratorSeekToLastCallback& callback) {
+ IteratorSeekToLastCallback callback) {
auto it = iterator_map_.find(iterator);
if (it == iterator_map_.end()) {
- callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt,
- base::nullopt);
+ std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
+ base::nullopt, base::nullopt);
return;
}
it->second->SeekToLast();
- ReplyToIteratorMessage(it->second, callback);
+ ReplyToIteratorMessage(it->second, std::move(callback));
}
-void LevelDBDatabaseImpl::IteratorSeek(
- const base::UnguessableToken& iterator,
- const std::vector<uint8_t>& target,
- const IteratorSeekToLastCallback& callback) {
+void LevelDBDatabaseImpl::IteratorSeek(const base::UnguessableToken& iterator,
+ const std::vector<uint8_t>& target,
+ IteratorSeekToLastCallback callback) {
auto it = iterator_map_.find(iterator);
if (it == iterator_map_.end()) {
- callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt,
- base::nullopt);
+ std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
+ base::nullopt, base::nullopt);
return;
}
it->second->Seek(GetSliceFor(target));
- ReplyToIteratorMessage(it->second, callback);
+ ReplyToIteratorMessage(it->second, std::move(callback));
}
void LevelDBDatabaseImpl::IteratorNext(const base::UnguessableToken& iterator,
- const IteratorNextCallback& callback) {
+ IteratorNextCallback callback) {
auto it = iterator_map_.find(iterator);
if (it == iterator_map_.end()) {
- callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt,
- base::nullopt);
+ std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
+ base::nullopt, base::nullopt);
return;
}
it->second->Next();
- ReplyToIteratorMessage(it->second, callback);
+ ReplyToIteratorMessage(it->second, std::move(callback));
}
void LevelDBDatabaseImpl::IteratorPrev(const base::UnguessableToken& iterator,
- const IteratorPrevCallback& callback) {
+ IteratorPrevCallback callback) {
auto it = iterator_map_.find(iterator);
if (it == iterator_map_.end()) {
- callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt,
- base::nullopt);
+ std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
+ base::nullopt, base::nullopt);
return;
}
it->second->Prev();
- ReplyToIteratorMessage(it->second, callback);
+ ReplyToIteratorMessage(it->second, std::move(callback));
}
void LevelDBDatabaseImpl::ReplyToIteratorMessage(
leveldb::Iterator* it,
- const IteratorSeekToFirstCallback& callback) {
+ IteratorSeekToFirstCallback callback) {
if (!it->Valid()) {
- callback.Run(false, LeveldbStatusToError(it->status()), base::nullopt,
- base::nullopt);
+ std::move(callback).Run(false, LeveldbStatusToError(it->status()),
+ base::nullopt, base::nullopt);
return;
}
- callback.Run(true, LeveldbStatusToError(it->status()),
- GetVectorFor(it->key()), GetVectorFor(it->value()));
+ std::move(callback).Run(true, LeveldbStatusToError(it->status()),
+ GetVectorFor(it->key()), GetVectorFor(it->value()));
}
leveldb::Status LevelDBDatabaseImpl::DeletePrefixedHelper(
diff --git a/chromium/components/leveldb/leveldb_database_impl.h b/chromium/components/leveldb/leveldb_database_impl.h
index f621c5f5057..277748d49ef 100644
--- a/chromium/components/leveldb/leveldb_database_impl.h
+++ b/chromium/components/leveldb/leveldb_database_impl.h
@@ -24,46 +24,44 @@ class LevelDBDatabaseImpl : public mojom::LevelDBDatabase {
// Overridden from LevelDBDatabase:
void Put(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
- const PutCallback& callback) override;
+ PutCallback callback) override;
void Delete(const std::vector<uint8_t>& key,
- const DeleteCallback& callback) override;
+ DeleteCallback callback) override;
void DeletePrefixed(const std::vector<uint8_t>& key_prefix,
- const DeletePrefixedCallback& callback) override;
+ DeletePrefixedCallback callback) override;
void Write(std::vector<mojom::BatchedOperationPtr> operations,
- const WriteCallback& callback) override;
- void Get(const std::vector<uint8_t>& key,
- const GetCallback& callback) override;
+ WriteCallback callback) override;
+ void Get(const std::vector<uint8_t>& key, GetCallback callback) override;
void GetPrefixed(const std::vector<uint8_t>& key_prefix,
- const GetPrefixedCallback& callback) override;
- void GetSnapshot(const GetSnapshotCallback& callback) override;
+ GetPrefixedCallback callback) override;
+ void GetSnapshot(GetSnapshotCallback callback) override;
void ReleaseSnapshot(const base::UnguessableToken& snapshot) override;
void GetFromSnapshot(const base::UnguessableToken& snapshot,
const std::vector<uint8_t>& key,
- const GetCallback& callback) override;
- void NewIterator(const NewIteratorCallback& callback) override;
+ GetCallback callback) override;
+ void NewIterator(NewIteratorCallback callback) override;
void NewIteratorFromSnapshot(
const base::UnguessableToken& snapshot,
- const NewIteratorFromSnapshotCallback& callback) override;
+ NewIteratorFromSnapshotCallback callback) override;
void ReleaseIterator(const base::UnguessableToken& iterator) override;
- void IteratorSeekToFirst(
- const base::UnguessableToken& iterator,
- const IteratorSeekToFirstCallback& callback) override;
+ void IteratorSeekToFirst(const base::UnguessableToken& iterator,
+ IteratorSeekToFirstCallback callback) override;
void IteratorSeekToLast(const base::UnguessableToken& iterator,
- const IteratorSeekToLastCallback& callback) override;
+ IteratorSeekToLastCallback callback) override;
void IteratorSeek(const base::UnguessableToken& iterator,
const std::vector<uint8_t>& target,
- const IteratorSeekToLastCallback& callback) override;
+ IteratorSeekToLastCallback callback) override;
void IteratorNext(const base::UnguessableToken& iterator,
- const IteratorNextCallback& callback) override;
+ IteratorNextCallback callback) override;
void IteratorPrev(const base::UnguessableToken& iterator,
- const IteratorPrevCallback& callback) override;
+ IteratorPrevCallback callback) override;
private:
// Returns the state of |it| to a caller. Note: This assumes that all the
// iterator movement methods have the same callback signature. We don't
// directly reference the underlying type in case of bindings change.
void ReplyToIteratorMessage(leveldb::Iterator* it,
- const IteratorSeekToFirstCallback& callback);
+ IteratorSeekToFirstCallback callback);
leveldb::Status DeletePrefixedHelper(const leveldb::Slice& key_prefix,
leveldb::WriteBatch* batch);
diff --git a/chromium/components/leveldb/leveldb_mojo_proxy.cc b/chromium/components/leveldb/leveldb_mojo_proxy.cc
index c3c9943cc84..523859c3762 100644
--- a/chromium/components/leveldb/leveldb_mojo_proxy.cc
+++ b/chromium/components/leveldb/leveldb_mojo_proxy.cc
@@ -233,9 +233,8 @@ void LevelDBMojoProxy::GetChildrenImpl(
filesystem::mojom::FileError* out_error) {
mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
filesystem::mojom::DirectoryPtr target;
- filesystem::mojom::DirectoryRequest proxy(&target);
bool completed = dir->directory->OpenDirectory(
- name, std::move(proxy),
+ name, mojo::MakeRequest(&target),
filesystem::mojom::kFlagRead | filesystem::mojom::kFlagWrite, out_error);
DCHECK(completed);
@@ -304,8 +303,7 @@ void LevelDBMojoProxy::LockFileImpl(OpaqueDir* dir,
// Since a lock is associated with a file descriptor, we need to open and
// have a persistent file on the other side of the connection.
filesystem::mojom::FilePtr target;
- filesystem::mojom::FileRequest proxy(&target);
- bool completed = dir->directory->OpenFile(path, std::move(proxy),
+ bool completed = dir->directory->OpenFile(path, mojo::MakeRequest(&target),
filesystem::mojom::kFlagOpenAlways |
filesystem::mojom::kFlagRead |
filesystem::mojom::kFlagWrite,
diff --git a/chromium/components/leveldb/leveldb_service_impl.cc b/chromium/components/leveldb/leveldb_service_impl.cc
index 2f754112c52..f2e4eb8597d 100644
--- a/chromium/components/leveldb/leveldb_service_impl.cc
+++ b/chromium/components/leveldb/leveldb_service_impl.cc
@@ -5,6 +5,7 @@
#include "components/leveldb/leveldb_service_impl.h"
#include <memory>
+#include <utility>
#include "base/memory/ptr_util.h"
#include "components/leveldb/env_mojo.h"
@@ -30,9 +31,9 @@ void LevelDBServiceImpl::Open(
filesystem::mojom::DirectoryPtr directory,
const std::string& dbname,
leveldb::mojom::LevelDBDatabaseAssociatedRequest database,
- const OpenCallback& callback) {
+ OpenCallback callback) {
OpenWithOptions(leveldb::mojom::OpenOptions::New(), std::move(directory),
- dbname, std::move(database), callback);
+ dbname, std::move(database), std::move(callback));
}
void LevelDBServiceImpl::OpenWithOptions(
@@ -40,7 +41,7 @@ void LevelDBServiceImpl::OpenWithOptions(
filesystem::mojom::DirectoryPtr directory,
const std::string& dbname,
leveldb::mojom::LevelDBDatabaseAssociatedRequest database,
- const OpenCallback& callback) {
+ OpenCallback callback) {
leveldb::Options options;
options.create_if_missing = open_options->create_if_missing;
options.error_if_exists = open_options->error_if_exists;
@@ -68,12 +69,12 @@ void LevelDBServiceImpl::OpenWithOptions(
std::move(database));
}
- callback.Run(LeveldbStatusToError(s));
+ std::move(callback).Run(LeveldbStatusToError(s));
}
void LevelDBServiceImpl::OpenInMemory(
leveldb::mojom::LevelDBDatabaseAssociatedRequest database,
- const OpenCallback& callback) {
+ OpenCallback callback) {
leveldb::Options options;
options.create_if_missing = true;
options.max_open_files = 0; // Use minimum.
@@ -91,19 +92,20 @@ void LevelDBServiceImpl::OpenInMemory(
std::move(database));
}
- callback.Run(LeveldbStatusToError(s));
+ std::move(callback).Run(LeveldbStatusToError(s));
}
void LevelDBServiceImpl::Destroy(filesystem::mojom::DirectoryPtr directory,
const std::string& dbname,
- const DestroyCallback& callback) {
+ DestroyCallback callback) {
leveldb::Options options;
// Register our directory with the file thread.
LevelDBMojoProxy::OpaqueDir* dir =
thread_->RegisterDirectory(std::move(directory));
std::unique_ptr<MojoEnv> env_mojo(new MojoEnv(thread_, dir));
options.env = env_mojo.get();
- callback.Run(LeveldbStatusToError(leveldb::DestroyDB(dbname, options)));
+ std::move(callback).Run(
+ LeveldbStatusToError(leveldb::DestroyDB(dbname, options)));
}
} // namespace leveldb
diff --git a/chromium/components/leveldb/leveldb_service_impl.h b/chromium/components/leveldb/leveldb_service_impl.h
index 3cc1210d2c1..9a5beed6d99 100644
--- a/chromium/components/leveldb/leveldb_service_impl.h
+++ b/chromium/components/leveldb/leveldb_service_impl.h
@@ -6,6 +6,7 @@
#define COMPONENTS_LEVELDB_LEVELDB_SERVICE_IMPL_H_
#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "components/leveldb/leveldb_mojo_proxy.h"
#include "components/leveldb/public/interfaces/leveldb.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
@@ -26,18 +27,18 @@ class LevelDBServiceImpl : public mojom::LevelDBService {
void Open(filesystem::mojom::DirectoryPtr directory,
const std::string& dbname,
leveldb::mojom::LevelDBDatabaseAssociatedRequest database,
- const OpenCallback& callback) override;
+ OpenCallback callback) override;
void OpenWithOptions(
leveldb::mojom::OpenOptionsPtr open_options,
filesystem::mojom::DirectoryPtr directory,
const std::string& dbname,
leveldb::mojom::LevelDBDatabaseAssociatedRequest database,
- const OpenCallback& callback) override;
+ OpenCallback callback) override;
void OpenInMemory(leveldb::mojom::LevelDBDatabaseAssociatedRequest database,
- const OpenInMemoryCallback& callback) override;
+ OpenInMemoryCallback callback) override;
void Destroy(filesystem::mojom::DirectoryPtr directory,
const std::string& dbname,
- const DestroyCallback& callback) override;
+ DestroyCallback callback) override;
private:
// Thread to own the mojo message pipe. Because leveldb spawns multiple
diff --git a/chromium/components/leveldb_proto/proto_database.h b/chromium/components/leveldb_proto/proto_database.h
index d2a7c29fdfa..a43b20deaa8 100644
--- a/chromium/components/leveldb_proto/proto_database.h
+++ b/chromium/components/leveldb_proto/proto_database.h
@@ -10,7 +10,7 @@
#include <utility>
#include <vector>
-#include "base/callback_forward.h"
+#include "base/callback.h"
#include "components/leveldb_proto/options.h"
namespace base {
@@ -24,15 +24,16 @@ namespace leveldb_proto {
template <typename T>
class ProtoDatabase {
public:
- using InitCallback = base::Callback<void(bool success)>;
- using UpdateCallback = base::Callback<void(bool success)>;
+ using InitCallback = base::OnceCallback<void(bool success)>;
+ using UpdateCallback = base::OnceCallback<void(bool success)>;
using LoadCallback =
- base::Callback<void(bool success, std::unique_ptr<std::vector<T>>)>;
+ base::OnceCallback<void(bool success, std::unique_ptr<std::vector<T>>)>;
using LoadKeysCallback =
- base::Callback<void(bool success,
- std::unique_ptr<std::vector<std::string>>)>;
- using GetCallback = base::Callback<void(bool success, std::unique_ptr<T>)>;
- using DestroyCallback = base::Callback<void(bool success)>;
+ base::OnceCallback<void(bool success,
+ std::unique_ptr<std::vector<std::string>>)>;
+ using GetCallback =
+ base::OnceCallback<void(bool success, std::unique_ptr<T>)>;
+ using DestroyCallback = base::OnceCallback<void(bool success)>;
// A list of key-value (string, T) tuples.
using KeyEntryVector = std::vector<std::pair<std::string, T>>;
@@ -43,14 +44,14 @@ class ProtoDatabase {
// be invoked on the calling thread when complete.
void Init(const char* client_name,
const base::FilePath& database_dir,
- const InitCallback& callback) {
- InitWithOptions(client_name, Options(database_dir), callback);
+ InitCallback callback) {
+ InitWithOptions(client_name, Options(database_dir), std::move(callback));
}
// Similar to Init, but takes additional options.
virtual void InitWithOptions(const char* client_name,
const Options& options,
- const InitCallback& callback) = 0;
+ InitCallback callback) = 0;
// Asynchronously saves |entries_to_save| and deletes entries from
// |keys_to_remove| from the database. |callback| will be invoked on the
@@ -58,24 +59,23 @@ class ProtoDatabase {
virtual void UpdateEntries(
std::unique_ptr<KeyEntryVector> entries_to_save,
std::unique_ptr<std::vector<std::string>> keys_to_remove,
- const UpdateCallback& callback) = 0;
+ UpdateCallback callback) = 0;
// Asynchronously loads all entries from the database and invokes |callback|
// when complete.
- virtual void LoadEntries(const LoadCallback& callback) = 0;
+ virtual void LoadEntries(LoadCallback callback) = 0;
// Asynchronously loads all keys from the database and invokes |callback| with
// those keys when complete.
- virtual void LoadKeys(const LoadKeysCallback& callback) = 0;
+ virtual void LoadKeys(LoadKeysCallback callback) = 0;
// Asynchronously loads a single entry, identified by |key|, from the database
// and invokes |callback| when complete. If no entry with |key| is found,
// a nullptr is passed to the callback, but the success flag is still true.
- virtual void GetEntry(const std::string& key,
- const GetCallback& callback) = 0;
+ virtual void GetEntry(const std::string& key, GetCallback callback) = 0;
// Asynchronously destroys the database.
- virtual void Destroy(const DestroyCallback& callback) = 0;
+ virtual void Destroy(DestroyCallback callback) = 0;
};
} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/proto_database_impl.h b/chromium/components/leveldb_proto/proto_database_impl.h
index d5db97b9cfe..ff22d8d6492 100644
--- a/chromium/components/leveldb_proto/proto_database_impl.h
+++ b/chromium/components/leveldb_proto/proto_database_impl.h
@@ -46,27 +46,22 @@ class ProtoDatabaseImpl : public ProtoDatabase<T> {
void InitWithOptions(
const char* client_name,
const Options& options,
- const typename ProtoDatabase<T>::InitCallback& callback) override;
+ typename ProtoDatabase<T>::InitCallback callback) override;
void UpdateEntries(
std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
entries_to_save,
std::unique_ptr<KeyVector> keys_to_remove,
- const typename ProtoDatabase<T>::UpdateCallback& callback) override;
- void LoadEntries(
- const typename ProtoDatabase<T>::LoadCallback& callback) override;
- void LoadKeys(
- const typename ProtoDatabase<T>::LoadKeysCallback& callback) override;
- void GetEntry(
- const std::string& key,
- const typename ProtoDatabase<T>::GetCallback& callback) override;
- void Destroy(
- const typename ProtoDatabase<T>::DestroyCallback& callback) override;
+ typename ProtoDatabase<T>::UpdateCallback callback) override;
+ void LoadEntries(typename ProtoDatabase<T>::LoadCallback callback) override;
+ void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override;
+ void GetEntry(const std::string& key,
+ typename ProtoDatabase<T>::GetCallback callback) override;
+ void Destroy(typename ProtoDatabase<T>::DestroyCallback callback) override;
// Allow callers to provide their own Database implementation.
- void InitWithDatabase(
- std::unique_ptr<LevelDB> database,
- const Options& options,
- const typename ProtoDatabase<T>::InitCallback& callback);
+ void InitWithDatabase(std::unique_ptr<LevelDB> database,
+ const Options& options,
+ typename ProtoDatabase<T>::InitCallback callback);
private:
base::ThreadChecker thread_checker_;
@@ -83,46 +78,43 @@ class ProtoDatabaseImpl : public ProtoDatabase<T> {
namespace {
template <typename T>
-void RunInitCallback(const typename ProtoDatabase<T>::InitCallback& callback,
+void RunInitCallback(typename ProtoDatabase<T>::InitCallback callback,
const bool* success) {
- callback.Run(*success);
+ std::move(callback).Run(*success);
}
template <typename T>
-void RunUpdateCallback(
- const typename ProtoDatabase<T>::UpdateCallback& callback,
- const bool* success) {
- callback.Run(*success);
+void RunUpdateCallback(typename ProtoDatabase<T>::UpdateCallback callback,
+ const bool* success) {
+ std::move(callback).Run(*success);
}
template <typename T>
-void RunLoadCallback(const typename ProtoDatabase<T>::LoadCallback& callback,
+void RunLoadCallback(typename ProtoDatabase<T>::LoadCallback callback,
bool* success,
std::unique_ptr<std::vector<T>> entries) {
- callback.Run(*success, std::move(entries));
+ std::move(callback).Run(*success, std::move(entries));
}
template <typename T>
-void RunLoadKeysCallback(
- const typename ProtoDatabase<T>::LoadKeysCallback& callback,
- std::unique_ptr<bool> success,
- std::unique_ptr<std::vector<std::string>> keys) {
- callback.Run(*success, std::move(keys));
+void RunLoadKeysCallback(typename ProtoDatabase<T>::LoadKeysCallback callback,
+ std::unique_ptr<bool> success,
+ std::unique_ptr<std::vector<std::string>> keys) {
+ std::move(callback).Run(*success, std::move(keys));
}
template <typename T>
-void RunGetCallback(const typename ProtoDatabase<T>::GetCallback& callback,
+void RunGetCallback(typename ProtoDatabase<T>::GetCallback callback,
const bool* success,
const bool* found,
std::unique_ptr<T> entry) {
- callback.Run(*success, *found ? std::move(entry) : nullptr);
+ std::move(callback).Run(*success, *found ? std::move(entry) : nullptr);
}
template <typename T>
-void RunDestroyCallback(
- const typename ProtoDatabase<T>::DestroyCallback& callback,
- const bool* success) {
- callback.Run(*success);
+void RunDestroyCallback(typename ProtoDatabase<T>::DestroyCallback callback,
+ const bool* success) {
+ std::move(callback).Run(*success);
}
inline void InitFromTaskRunner(LevelDB* database,
@@ -229,16 +221,16 @@ template <typename T>
void ProtoDatabaseImpl<T>::InitWithOptions(
const char* client_name,
const Options& options,
- const typename ProtoDatabase<T>::InitCallback& callback) {
+ typename ProtoDatabase<T>::InitCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
database_dir_ = options.database_dir;
InitWithDatabase(base::WrapUnique(new LevelDB(client_name)), options,
- callback);
+ std::move(callback));
}
template <typename T>
void ProtoDatabaseImpl<T>::Destroy(
- const typename ProtoDatabase<T>::DestroyCallback& callback) {
+ typename ProtoDatabase<T>::DestroyCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(db_);
DCHECK(!database_dir_.empty());
@@ -246,7 +238,7 @@ void ProtoDatabaseImpl<T>::Destroy(
// Note that |db_| should be released from task runner.
if (!task_runner_->DeleteSoon(FROM_HERE, db_.release())) {
DLOG(WARNING) << "Proto database will not be deleted.";
- callback.Run(false);
+ std::move(callback).Run(false);
return;
}
@@ -254,30 +246,33 @@ void ProtoDatabaseImpl<T>::Destroy(
bool* success = new bool(false);
task_runner_->PostTaskAndReply(
FROM_HERE, base::Bind(DestroyFromTaskRunner, database_dir_, success),
- base::Bind(RunDestroyCallback<T>, callback, base::Owned(success)));
+ base::BindOnce(RunDestroyCallback<T>, std::move(callback),
+ base::Owned(success)));
}
template <typename T>
void ProtoDatabaseImpl<T>::InitWithDatabase(
std::unique_ptr<LevelDB> database,
const Options& options,
- const typename ProtoDatabase<T>::InitCallback& callback) {
+ typename ProtoDatabase<T>::InitCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!db_);
DCHECK(database);
db_ = std::move(database);
bool* success = new bool(false);
task_runner_->PostTaskAndReply(
- FROM_HERE, base::Bind(InitFromTaskRunner, base::Unretained(db_.get()),
- options, success),
- base::Bind(RunInitCallback<T>, callback, base::Owned(success)));
+ FROM_HERE,
+ base::Bind(InitFromTaskRunner, base::Unretained(db_.get()), options,
+ success),
+ base::BindOnce(RunInitCallback<T>, std::move(callback),
+ base::Owned(success)));
}
template <typename T>
void ProtoDatabaseImpl<T>::UpdateEntries(
std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
std::unique_ptr<KeyVector> keys_to_remove,
- const typename ProtoDatabase<T>::UpdateCallback& callback) {
+ typename ProtoDatabase<T>::UpdateCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
bool* success = new bool(false);
task_runner_->PostTaskAndReply(
@@ -285,12 +280,13 @@ void ProtoDatabaseImpl<T>::UpdateEntries(
base::Bind(UpdateEntriesFromTaskRunner<T>, base::Unretained(db_.get()),
base::Passed(&entries_to_save), base::Passed(&keys_to_remove),
success),
- base::Bind(RunUpdateCallback<T>, callback, base::Owned(success)));
+ base::BindOnce(RunUpdateCallback<T>, std::move(callback),
+ base::Owned(success)));
}
template <typename T>
void ProtoDatabaseImpl<T>::LoadEntries(
- const typename ProtoDatabase<T>::LoadCallback& callback) {
+ typename ProtoDatabase<T>::LoadCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
bool* success = new bool(false);
@@ -299,15 +295,16 @@ void ProtoDatabaseImpl<T>::LoadEntries(
std::vector<T>* entries_ptr = entries.get();
task_runner_->PostTaskAndReply(
- FROM_HERE, base::Bind(LoadEntriesFromTaskRunner<T>,
- base::Unretained(db_.get()), entries_ptr, success),
- base::Bind(RunLoadCallback<T>, callback, base::Owned(success),
- base::Passed(&entries)));
+ FROM_HERE,
+ base::Bind(LoadEntriesFromTaskRunner<T>, base::Unretained(db_.get()),
+ entries_ptr, success),
+ base::BindOnce(RunLoadCallback<T>, std::move(callback),
+ base::Owned(success), base::Passed(&entries)));
}
template <typename T>
void ProtoDatabaseImpl<T>::LoadKeys(
- const typename ProtoDatabase<T>::LoadKeysCallback& callback) {
+ typename ProtoDatabase<T>::LoadKeysCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
auto success = base::MakeUnique<bool>(false);
auto keys = base::MakeUnique<std::vector<std::string>>();
@@ -316,14 +313,14 @@ void ProtoDatabaseImpl<T>::LoadKeys(
keys.get(), success.get());
task_runner_->PostTaskAndReply(
FROM_HERE, load_task,
- base::Bind(RunLoadKeysCallback<T>, callback, base::Passed(&success),
- base::Passed(&keys)));
+ base::BindOnce(RunLoadKeysCallback<T>, std::move(callback),
+ base::Passed(&success), base::Passed(&keys)));
}
template <typename T>
void ProtoDatabaseImpl<T>::GetEntry(
const std::string& key,
- const typename ProtoDatabase<T>::GetCallback& callback) {
+ typename ProtoDatabase<T>::GetCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
bool* success = new bool(false);
bool* found = new bool(false);
@@ -336,8 +333,9 @@ void ProtoDatabaseImpl<T>::GetEntry(
FROM_HERE,
base::Bind(GetEntryFromTaskRunner<T>, base::Unretained(db_.get()), key,
entry_ptr, found, success),
- base::Bind(RunGetCallback<T>, callback, base::Owned(success),
- base::Owned(found), base::Passed(&entry)));
+ base::BindOnce(RunGetCallback<T>, std::move(callback),
+ base::Owned(success), base::Owned(found),
+ base::Passed(&entry)));
}
} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/proto_database_impl_unittest.cc b/chromium/components/leveldb_proto/proto_database_impl_unittest.cc
index 50f81677389..c198b50c821 100644
--- a/chromium/components/leveldb_proto/proto_database_impl_unittest.cc
+++ b/chromium/components/leveldb_proto/proto_database_impl_unittest.cc
@@ -15,6 +15,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "base/trace_event/memory_dump_manager.h"
diff --git a/chromium/components/leveldb_proto/testing/fake_db.h b/chromium/components/leveldb_proto/testing/fake_db.h
index 7a5e5dd4901..bb2cb1be929 100644
--- a/chromium/components/leveldb_proto/testing/fake_db.h
+++ b/chromium/components/leveldb_proto/testing/fake_db.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_LEVELDB_PROTO_TESTING_FAKE_DB_H_
#define COMPONENTS_LEVELDB_PROTO_TESTING_FAKE_DB_H_
+#include <map>
#include <memory>
#include <string>
#include <utility>
@@ -20,10 +21,10 @@ namespace test {
template <typename T>
class FakeDB : public ProtoDatabase<T> {
- using Callback = base::Callback<void(bool)>;
+ using Callback = base::OnceCallback<void(bool)>;
public:
- using EntryMap = typename base::hash_map<std::string, T>;
+ using EntryMap = std::map<std::string, T>;
explicit FakeDB(EntryMap* db);
~FakeDB() override;
@@ -32,21 +33,17 @@ class FakeDB : public ProtoDatabase<T> {
void InitWithOptions(
const char* client_name,
const Options& options,
- const typename ProtoDatabase<T>::InitCallback& callback) override;
+ typename ProtoDatabase<T>::InitCallback callback) override;
void UpdateEntries(
std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
entries_to_save,
std::unique_ptr<std::vector<std::string>> keys_to_remove,
- const typename ProtoDatabase<T>::UpdateCallback& callback) override;
- void LoadEntries(
- const typename ProtoDatabase<T>::LoadCallback& callback) override;
- void LoadKeys(
- const typename ProtoDatabase<T>::LoadKeysCallback& callback) override;
- void GetEntry(
- const std::string& key,
- const typename ProtoDatabase<T>::GetCallback& callback) override;
- void Destroy(
- const typename ProtoDatabase<T>::DestroyCallback& callback) override;
+ typename ProtoDatabase<T>::UpdateCallback callback) override;
+ void LoadEntries(typename ProtoDatabase<T>::LoadCallback callback) override;
+ void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override;
+ void GetEntry(const std::string& key,
+ typename ProtoDatabase<T>::GetCallback callback) override;
+ void Destroy(typename ProtoDatabase<T>::DestroyCallback callback) override;
base::FilePath& GetDirectory();
@@ -63,20 +60,18 @@ class FakeDB : public ProtoDatabase<T> {
static base::FilePath DirectoryForTestDB();
private:
- static void RunLoadCallback(
- const typename ProtoDatabase<T>::LoadCallback& callback,
- std::unique_ptr<typename std::vector<T>> entries,
- bool success);
+ static void RunLoadCallback(typename ProtoDatabase<T>::LoadCallback callback,
+ std::unique_ptr<typename std::vector<T>> entries,
+ bool success);
static void RunLoadKeysCallback(
- const typename ProtoDatabase<T>::LoadKeysCallback& callback,
+ typename ProtoDatabase<T>::LoadKeysCallback callback,
std::unique_ptr<std::vector<std::string>> keys,
bool success);
- static void RunGetCallback(
- const typename ProtoDatabase<T>::GetCallback& callback,
- std::unique_ptr<T> entry,
- bool success);
+ static void RunGetCallback(typename ProtoDatabase<T>::GetCallback callback,
+ std::unique_ptr<T> entry,
+ bool success);
base::FilePath dir_;
EntryMap* db_;
@@ -99,64 +94,60 @@ template <typename T>
void FakeDB<T>::InitWithOptions(
const char* client_name,
const Options& options,
- const typename ProtoDatabase<T>::InitCallback& callback) {
+ typename ProtoDatabase<T>::InitCallback callback) {
dir_ = options.database_dir;
- init_callback_ = callback;
+ init_callback_ = std::move(callback);
}
template <typename T>
void FakeDB<T>::UpdateEntries(
std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
std::unique_ptr<std::vector<std::string>> keys_to_remove,
- const typename ProtoDatabase<T>::UpdateCallback& callback) {
+ typename ProtoDatabase<T>::UpdateCallback callback) {
for (const auto& pair : *entries_to_save)
(*db_)[pair.first] = pair.second;
for (const auto& key : *keys_to_remove)
db_->erase(key);
- update_callback_ = callback;
+ update_callback_ = std::move(callback);
}
template <typename T>
-void FakeDB<T>::LoadEntries(
- const typename ProtoDatabase<T>::LoadCallback& callback) {
+void FakeDB<T>::LoadEntries(typename ProtoDatabase<T>::LoadCallback callback) {
std::unique_ptr<std::vector<T>> entries(new std::vector<T>());
for (const auto& pair : *db_)
entries->push_back(pair.second);
- load_callback_ =
- base::Bind(RunLoadCallback, callback, base::Passed(&entries));
+ load_callback_ = base::BindOnce(RunLoadCallback, std::move(callback),
+ base::Passed(&entries));
}
template <typename T>
-void FakeDB<T>::LoadKeys(
- const typename ProtoDatabase<T>::LoadKeysCallback& callback) {
+void FakeDB<T>::LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) {
std::unique_ptr<std::vector<std::string>> keys(
new std::vector<std::string>());
for (const auto& pair : *db_)
keys->push_back(pair.first);
- load_keys_callback_ =
- base::Bind(RunLoadKeysCallback, callback, base::Passed(&keys));
+ load_keys_callback_ = base::BindOnce(RunLoadKeysCallback, std::move(callback),
+ base::Passed(&keys));
}
template <typename T>
-void FakeDB<T>::GetEntry(
- const std::string& key,
- const typename ProtoDatabase<T>::GetCallback& callback) {
+void FakeDB<T>::GetEntry(const std::string& key,
+ typename ProtoDatabase<T>::GetCallback callback) {
std::unique_ptr<T> entry;
auto it = db_->find(key);
if (it != db_->end())
entry.reset(new T(it->second));
- get_callback_ = base::Bind(RunGetCallback, callback, base::Passed(&entry));
+ get_callback_ =
+ base::BindOnce(RunGetCallback, std::move(callback), base::Passed(&entry));
}
template <typename T>
-void FakeDB<T>::Destroy(
- const typename ProtoDatabase<T>::DestroyCallback& callback) {
-}
+void FakeDB<T>::Destroy(typename ProtoDatabase<T>::DestroyCallback callback) {}
template <typename T>
base::FilePath& FakeDB<T>::GetDirectory() {
@@ -165,59 +156,53 @@ base::FilePath& FakeDB<T>::GetDirectory() {
template <typename T>
void FakeDB<T>::InitCallback(bool success) {
- init_callback_.Run(success);
- init_callback_.Reset();
+ std::move(init_callback_).Run(success);
}
template <typename T>
void FakeDB<T>::LoadCallback(bool success) {
- load_callback_.Run(success);
- load_callback_.Reset();
+ std::move(load_callback_).Run(success);
}
template <typename T>
void FakeDB<T>::LoadKeysCallback(bool success) {
- load_keys_callback_.Run(success);
- load_keys_callback_.Reset();
+ std::move(load_keys_callback_).Run(success);
}
template <typename T>
void FakeDB<T>::GetCallback(bool success) {
- get_callback_.Run(success);
- get_callback_.Reset();
+ std::move(get_callback_).Run(success);
}
template <typename T>
void FakeDB<T>::UpdateCallback(bool success) {
- update_callback_.Run(success);
- update_callback_.Reset();
+ std::move(update_callback_).Run(success);
}
// static
template <typename T>
void FakeDB<T>::RunLoadCallback(
- const typename ProtoDatabase<T>::LoadCallback& callback,
+ typename ProtoDatabase<T>::LoadCallback callback,
std::unique_ptr<typename std::vector<T>> entries,
bool success) {
- callback.Run(success, std::move(entries));
+ std::move(callback).Run(success, std::move(entries));
}
// static
template <typename T>
void FakeDB<T>::RunLoadKeysCallback(
- const typename ProtoDatabase<T>::LoadKeysCallback& callback,
+ typename ProtoDatabase<T>::LoadKeysCallback callback,
std::unique_ptr<std::vector<std::string>> keys,
bool success) {
- callback.Run(success, std::move(keys));
+ std::move(callback).Run(success, std::move(keys));
}
// static
template <typename T>
-void FakeDB<T>::RunGetCallback(
- const typename ProtoDatabase<T>::GetCallback& callback,
- std::unique_ptr<T> entry,
- bool success) {
- callback.Run(success, std::move(entry));
+void FakeDB<T>::RunGetCallback(typename ProtoDatabase<T>::GetCallback callback,
+ std::unique_ptr<T> entry,
+ bool success) {
+ std::move(callback).Run(success, std::move(entry));
}
// static
diff --git a/chromium/components/login/base_screen_handler_utils.cc b/chromium/components/login/base_screen_handler_utils.cc
index fe1851bdffc..a96e2cb6cd5 100644
--- a/chromium/components/login/base_screen_handler_utils.cc
+++ b/chromium/components/login/base_screen_handler_utils.cc
@@ -67,8 +67,9 @@ bool ParseValue(const base::Value* value, AccountId* out_value) {
if (AccountId::Deserialize(serialized, out_value))
return true;
- LOG(ERROR) << "Failed to deserialize '" << serialized << "'";
*out_value = AccountId::FromUserEmail(serialized);
+ LOG(ERROR) << "Failed to deserialize, parse as email, valid="
+ << out_value->is_valid();
return true;
}
diff --git a/chromium/components/login/secure_module_util_chromeos.cc b/chromium/components/login/secure_module_util_chromeos.cc
index 9e9d57a2f4d..b33ef168cff 100644
--- a/chromium/components/login/secure_module_util_chromeos.cc
+++ b/chromium/components/login/secure_module_util_chromeos.cc
@@ -40,9 +40,7 @@ void GetSecureModuleUsed(GetSecureModuleUsedCallback callback) {
}
base::PostTaskWithTraitsAndReplyWithResult(
- FROM_HERE,
- base::TaskTraits().MayBlock().WithPriority(
- base::TaskPriority::BACKGROUND),
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
base::BindOnce(&GetSecureModuleInfoFromFilesAndCacheIt),
std::move(callback));
}
diff --git a/chromium/components/memory_pressure/BUILD.gn b/chromium/components/memory_pressure/BUILD.gn
deleted file mode 100644
index 0f6af8519e2..00000000000
--- a/chromium/components/memory_pressure/BUILD.gn
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2015 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.
-
-static_library("memory_pressure") {
- sources = [
- "direct_memory_pressure_calculator.h",
- "direct_memory_pressure_calculator_linux.cc",
- "direct_memory_pressure_calculator_linux.h",
- "direct_memory_pressure_calculator_win.cc",
- "direct_memory_pressure_calculator_win.h",
- "filtered_memory_pressure_calculator.cc",
- "filtered_memory_pressure_calculator.h",
- "memory_pressure_calculator.h",
- "memory_pressure_listener.cc",
- "memory_pressure_listener.h",
- "memory_pressure_monitor.cc",
- "memory_pressure_monitor.h",
- "memory_pressure_stats_collector.cc",
- "memory_pressure_stats_collector.h",
- ]
-
- deps = [
- "//base",
- ]
-}
-
-source_set("unit_tests") {
- testonly = true
- sources = [
- "direct_memory_pressure_calculator_linux_unittest.cc",
- "direct_memory_pressure_calculator_win_unittest.cc",
- "filtered_memory_pressure_calculator_unittest.cc",
- "memory_pressure_monitor_unittest.cc",
- "memory_pressure_stats_collector_unittest.cc",
- "test_memory_pressure_calculator.cc",
- "test_memory_pressure_calculator.h",
- ]
-
- deps = [
- ":memory_pressure",
- "//base/test:test_support",
- "//testing/gmock",
- "//testing/gtest",
- ]
-}
diff --git a/chromium/components/memory_pressure/OWNERS b/chromium/components/memory_pressure/OWNERS
deleted file mode 100644
index 1f457502286..00000000000
--- a/chromium/components/memory_pressure/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-chrisha@chromium.org
-shrike@chromium.org
-skuhne@chromium.org
diff --git a/chromium/components/memory_pressure/direct_memory_pressure_calculator.h b/chromium/components/memory_pressure/direct_memory_pressure_calculator.h
deleted file mode 100644
index 98ca61770ea..00000000000
--- a/chromium/components/memory_pressure/direct_memory_pressure_calculator.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 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_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_H_
-#define COMPONENTS_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_H_
-
-#if defined(OS_LINUX)
-#include "components/memory_pressure/direct_memory_pressure_calculator_linux.h"
-#elsif defined(OS_WIN)
-#include "components/memory_pressure/direct_memory_pressure_calculator_win.h"
-#endif // OS_LINUX
-
-#endif // COMPONENTS_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_H_
diff --git a/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.cc b/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.cc
deleted file mode 100644
index 358d655c1e6..00000000000
--- a/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2016 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/memory_pressure/direct_memory_pressure_calculator_linux.h"
-
-#include "base/files/file_util.h"
-#include "base/process/process_metrics.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/sys_info.h"
-#include "base/threading/thread_restrictions.h"
-
-namespace memory_pressure {
-
-namespace {
-
-const int kKiBperMiB = 1024;
-
-// Used to calculate a moving average of faults/sec. Our sample times are
-// inconsistent because MemoryPressureMonitor calls
-// CalculateCurrentPressureLevel more frequently when memory pressure is high,
-// and because we're measuring CPU time instead of real time. So our
-// exponentially weighted moving average is generalized to a low-pass filter.
-//
-// Represents the amount of CPU time, in seconds, for a sample to be 50%
-// forgotten in our moving average. Systems with more CPUs that are under high
-// load will have a moving average that changes more quickly than a system with
-// fewer CPUs under the same load. Do not normalize based on the number of CPUs
-// because this behavior is accurate: if a system with a large number of CPUs
-// is getting lots of work done without page faulting, it must not be under
-// memory pressure.
-//
-// TODO(thomasanderson): Experimentally determine the correct value for this
-// constant.
-const double kLowPassHalfLife = 30.0;
-
-// Returns the amount of memory that is available for use right now, or that can
-// be easily reclaimed by the OS, in MBs.
-int GetAvailableSystemMemoryMiB(const base::SystemMemoryInfoKB* mem_info) {
- return mem_info->available
- ? mem_info->available / kKiBperMiB
- : (mem_info->free + mem_info->buffers + mem_info->cached) /
- kKiBperMiB;
-}
-
-} // namespace
-
-// Thresholds at which we consider the system being under moderate/critical
-// memory pressure. They represent the percentage of system memory in use.
-const int DirectMemoryPressureCalculator::kDefaultModerateThresholdPc = 70;
-const int DirectMemoryPressureCalculator::kDefaultCriticalThresholdPc = 90;
-
-DirectMemoryPressureCalculator::DirectMemoryPressureCalculator()
- : moderate_threshold_mb_(0),
- critical_threshold_mb_(0) {
- InferThresholds();
- InitPageFaultMonitor();
-}
-
-DirectMemoryPressureCalculator::DirectMemoryPressureCalculator(
- int moderate_threshold_mb,
- int critical_threshold_mb)
- : moderate_threshold_mb_(moderate_threshold_mb),
- critical_threshold_mb_(critical_threshold_mb) {
- DCHECK_GE(moderate_threshold_mb_, critical_threshold_mb_);
- DCHECK_LE(0, critical_threshold_mb_);
- InitPageFaultMonitor();
-}
-
-DirectMemoryPressureCalculator::MemoryPressureLevel
-DirectMemoryPressureCalculator::PressureCausedByThrashing(
- const base::SystemMemoryInfoKB& mem_info) {
- base::TimeDelta new_user_exec_time = GetUserCpuTimeSinceBoot();
- if (new_user_exec_time == base::TimeDelta())
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
- uint64_t new_major_page_faults = mem_info.pgmajfault;
- if (new_user_exec_time != base::TimeDelta() && new_major_page_faults &&
- (new_user_exec_time - last_user_exec_time_) != base::TimeDelta()) {
- double delta_user_exec_time =
- (new_user_exec_time - last_user_exec_time_).InSecondsF();
- double delta_major_page_faults =
- new_major_page_faults - last_major_page_faults_;
-
- double sampled_faults_per_second =
- delta_major_page_faults / delta_user_exec_time;
-
- double adjusted_ewma_coefficient =
- 1 - exp2(-delta_user_exec_time / low_pass_half_life_seconds_);
-
- current_faults_per_second_ =
- adjusted_ewma_coefficient * sampled_faults_per_second +
- (1 - adjusted_ewma_coefficient) * current_faults_per_second_;
-
- last_user_exec_time_ = new_user_exec_time;
- last_major_page_faults_ = new_major_page_faults;
- }
-
- if (current_faults_per_second_ >
- critical_multiplier_ * AverageFaultsPerSecond()) {
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
- }
- if (current_faults_per_second_ >
- moderate_multiplier_ * AverageFaultsPerSecond()) {
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
- }
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-DirectMemoryPressureCalculator::MemoryPressureLevel
-DirectMemoryPressureCalculator::PressureCausedByOOM(
- const base::SystemMemoryInfoKB& mem_info) {
- int phys_free = GetAvailableSystemMemoryMiB(&mem_info);
-
- if (phys_free <= critical_threshold_mb_)
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
- if (phys_free <= moderate_threshold_mb_)
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-DirectMemoryPressureCalculator::MemoryPressureLevel
-DirectMemoryPressureCalculator::CalculateCurrentPressureLevel() {
- base::SystemMemoryInfoKB mem_info = {};
- if (!GetSystemMemoryInfo(&mem_info))
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-
- return std::max(PressureCausedByThrashing(mem_info),
- PressureCausedByOOM(mem_info));
-}
-
-bool DirectMemoryPressureCalculator::GetSystemMemoryInfo(
- base::SystemMemoryInfoKB* mem_info) const {
- return base::GetSystemMemoryInfo(mem_info);
-}
-
-base::TimeDelta DirectMemoryPressureCalculator::GetUserCpuTimeSinceBoot()
- const {
- return base::GetUserCpuTimeSinceBoot();
-}
-
-void DirectMemoryPressureCalculator::InferThresholds() {
- base::SystemMemoryInfoKB mem_info = {};
- if (!GetSystemMemoryInfo(&mem_info))
- return;
-
- moderate_threshold_mb_ =
- mem_info.total * (100 - kDefaultModerateThresholdPc) / 100 / kKiBperMiB;
- critical_threshold_mb_ =
- mem_info.total * (100 - kDefaultCriticalThresholdPc) / 100 / kKiBperMiB;
-}
-
-void DirectMemoryPressureCalculator::InitPageFaultMonitor() {
- low_pass_half_life_seconds_ = kLowPassHalfLife;
- last_user_exec_time_ = GetUserCpuTimeSinceBoot();
- base::SystemMemoryInfoKB mem_info = {};
- last_major_page_faults_ =
- GetSystemMemoryInfo(&mem_info) ? mem_info.pgmajfault : 0;
- current_faults_per_second_ = AverageFaultsPerSecond();
-}
-
-double DirectMemoryPressureCalculator::AverageFaultsPerSecond() const {
- return last_major_page_faults_ == 0
- ? last_user_exec_time_.InSecondsF() / last_major_page_faults_
- : 0;
-}
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.h b/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.h
deleted file mode 100644
index 315b8d93f19..00000000000
--- a/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2016 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_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_LINUX_H_
-#define COMPONENTS_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_LINUX_H_
-
-#include "base/macros.h"
-#include "base/process/process_metrics.h"
-#include "components/memory_pressure/memory_pressure_calculator.h"
-
-namespace base {
-class TimeDelta;
-}
-
-namespace memory_pressure {
-
-// OS-specific implementation of MemoryPressureCalculator. This is only defined
-// and used on platforms that do not have native memory pressure signals
-// (ChromeOS, Linux, Windows). OSes that do have native signals simply hook into
-// the appropriate subsystem (Android, Mac OS X).
-class DirectMemoryPressureCalculator : public MemoryPressureCalculator {
- public:
- // Exposed for unittesting. See .cc file for detailed discussion of these
- // constants.
- static const int kDefaultModerateThresholdPc;
- static const int kDefaultCriticalThresholdPc;
-
- // Default constructor. Will choose thresholds automatically based on the
- // actual amount of system memory installed.
- DirectMemoryPressureCalculator();
-
- // Constructor with explicit memory thresholds. These represent the amount of
- // free memory below which the applicable memory pressure state applies.
- DirectMemoryPressureCalculator(int moderate_threshold_mb,
- int critical_threshold_mb);
-
- ~DirectMemoryPressureCalculator() override {}
-
- // Calculates the current pressure level.
- MemoryPressureLevel CalculateCurrentPressureLevel() override;
-
- int moderate_threshold_mb() const { return moderate_threshold_mb_; }
- int critical_threshold_mb() const { return critical_threshold_mb_; }
-
- private:
- friend class TestDirectMemoryPressureCalculator;
-
- MemoryPressureLevel PressureCausedByThrashing(
- const base::SystemMemoryInfoKB& mem_info);
- MemoryPressureLevel PressureCausedByOOM(
- const base::SystemMemoryInfoKB& mem_info);
-
- // Gets system memory status. This is virtual as a unittesting hook and by
- // default this invokes base::GetSystemMemoryInfo.
- virtual bool GetSystemMemoryInfo(base::SystemMemoryInfoKB* mem_info) const;
-
- // We use CPU time instead of real time because this eliminates the variable
- // of average system load. Consumer machines are idle most of the time, so if
- // we used real time, the average faults/sec would be very low. As soon as
- // the user loads anything, the instantaneous faults/sec would increase, and
- // we would overreport the memory pressure.
- //
- // We also ignore system time because we don't want to include the time the OS
- // takes to swap pages in/out on behalf of processes.
- //
- // Virtual as a unittesting hook.
- virtual base::TimeDelta GetUserCpuTimeSinceBoot() const;
-
- // Uses GetSystemMemoryInfo to automatically infer appropriate values for
- // moderate_threshold_mb_ and critical_threshold_mb_.
- void InferThresholds();
-
- // Initialize the page fault monitor state so CalculateCurrentPressureLevel
- // will have a delta to analyze.
- virtual void InitPageFaultMonitor();
-
- // Computes last_major_page_faults_/last_user_exec_time_ with some
- // protection.
- double AverageFaultsPerSecond() const;
-
- // Threshold amounts of available memory that trigger pressure levels. See
- // memory_pressure_monitor_win.cc for a discussion of reasonable values for
- // these.
- int moderate_threshold_mb_;
- int critical_threshold_mb_;
-
- // State needed by the hard page fault monitor. These values are assumed
- // not to overflow.
- base::TimeDelta last_user_exec_time_;
- uint64_t last_major_page_faults_;
- // An exponentially weighted moving average of the sampled faults/sec.
- double current_faults_per_second_;
-
- double low_pass_half_life_seconds_;
-
- // |current_faults_per_second_| must be at least |kModerateMultiplier| *
- // AverageFaultsPerSecond() to report moderate pressure, and similarly for
- // critical pressure. Non-const members for unit testing.
- //
- // TODO(thomasanderson): Experimentally determine the correct value for these
- // constants.
- double moderate_multiplier_ = 5.0;
- double critical_multiplier_ = 10.0;
-
- DISALLOW_COPY_AND_ASSIGN(DirectMemoryPressureCalculator);
-};
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_LINUX_H_
diff --git a/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux_unittest.cc b/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux_unittest.cc
deleted file mode 100644
index 591f973915e..00000000000
--- a/chromium/components/memory_pressure/direct_memory_pressure_calculator_linux_unittest.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2015 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/memory_pressure/direct_memory_pressure_calculator_linux.h"
-
-#include "base/process/process_metrics.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace memory_pressure {
-
-namespace {
-
-const int kKBperMB = 1024;
-const int kTotalMemoryInMB = 4096;
-
-} // namespace
-
-// This is out of the anonymous namespace space because it is a friend of
-// DirectMemoryPressureCalculator.
-class TestDirectMemoryPressureCalculator
- : public DirectMemoryPressureCalculator {
- public:
- TestDirectMemoryPressureCalculator()
- : DirectMemoryPressureCalculator(20, 10) {
- // The values passed to the MemoryPressureCalculator constructor are dummy
- // values that are immediately overwritten by InferTresholds.
-
- // Simulate 4GB of RAM.
- mem_info_.total = kTotalMemoryInMB * kKBperMB;
-
- // Run InferThresholds using the test fixture's GetSystemMemoryStatus.
- InferThresholds();
- }
-
- TestDirectMemoryPressureCalculator(int total_memory_mb,
- int moderate_threshold_mb,
- int critical_threshold_mb)
- : DirectMemoryPressureCalculator(moderate_threshold_mb,
- critical_threshold_mb) {
- mem_info_.total = total_memory_mb * kKBperMB;
- mem_info_.pgmajfault = 0;
- }
-
- void InitPageFaultMonitor() override {}
-
- // Sets up the memory status to reflect the provided absolute memory left.
- void SetMemoryFree(int phys_left_mb) {
- // |total| is set in the constructor and not modified.
-
- // Set the amount of free memory.
- mem_info_.free = phys_left_mb * kKBperMB;
- DCHECK_LT(mem_info_.free, mem_info_.total);
- }
-
- void SetNone() { SetMemoryFree(moderate_threshold_mb() + 1); }
- void SetModerate() { SetMemoryFree(moderate_threshold_mb() - 1); }
- void SetCritical() { SetMemoryFree(critical_threshold_mb() - 1); }
-
- double GetEwma() { return current_faults_per_second_; }
-
- // Set the next CPU time to be read.
- void SetCpuTime(double cpu_time) {
- user_cpu_time_ = base::TimeDelta::FromSecondsD(cpu_time);
- }
- // Set the next page faults value to be read.
- void SetPageFaults(uint64_t page_faults) {
- mem_info_.pgmajfault = page_faults;
- }
-
- void SetPageFaultMonitorState(double user_exec_time,
- uint64_t major_page_faults,
- double current_faults,
- double low_pass_half_life,
- double moderate_multiplier,
- double critical_multiplier) {
- last_user_exec_time_ = base::TimeDelta::FromSecondsD(user_exec_time);
- last_major_page_faults_ = major_page_faults;
- current_faults_per_second_ = current_faults;
- low_pass_half_life_seconds_ = low_pass_half_life;
- moderate_multiplier_ = moderate_multiplier;
- critical_multiplier_ = critical_multiplier;
- }
-
- private:
- bool GetSystemMemoryInfo(base::SystemMemoryInfoKB* mem_info) const override {
- // Simply copy the memory information set by the test fixture.
- *mem_info = mem_info_;
- return true;
- }
-
- base::TimeDelta GetUserCpuTimeSinceBoot() const override {
- return user_cpu_time_;
- }
-
- base::TimeDelta user_cpu_time_;
- base::SystemMemoryInfoKB mem_info_;
-};
-
-class DirectMemoryPressureCalculatorTest : public testing::Test {
- public:
- void CalculateCurrentPressureLevelTest(
- TestDirectMemoryPressureCalculator* calc) {
- int mod = calc->moderate_threshold_mb();
- calc->SetMemoryFree(mod + 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetNone();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(mod);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(mod - 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- int crit = calc->critical_threshold_mb();
- calc->SetMemoryFree(crit + 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(crit);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(crit - 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetCritical();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- calc->CalculateCurrentPressureLevel());
- }
-};
-
-// Tests the fundamental direct calculation of memory pressure with automatic
-// small-memory thresholds.
-TEST_F(DirectMemoryPressureCalculatorTest,
- CalculateCurrentMemoryPressureLevel) {
- TestDirectMemoryPressureCalculator calc;
-
- static const int kModerateMb =
- (100 - DirectMemoryPressureCalculator::kDefaultModerateThresholdPc) *
- kTotalMemoryInMB / 100;
- static const int kCriticalMb =
- (100 - DirectMemoryPressureCalculator::kDefaultCriticalThresholdPc) *
- kTotalMemoryInMB / 100;
-
- EXPECT_EQ(kModerateMb, calc.moderate_threshold_mb());
- EXPECT_EQ(kCriticalMb, calc.critical_threshold_mb());
-
- ASSERT_NO_FATAL_FAILURE(CalculateCurrentPressureLevelTest(&calc));
-}
-
-// Tests the fundamental direct calculation of memory pressure with manually
-// specified threshold levels.
-TEST_F(DirectMemoryPressureCalculatorTest,
- CalculateCurrentMemoryPressureLevelCustom) {
- static const int kSystemMb = 512;
- static const int kModerateMb = 256;
- static const int kCriticalMb = 128;
-
- TestDirectMemoryPressureCalculator calc(kSystemMb, kModerateMb, kCriticalMb);
-
- EXPECT_EQ(kModerateMb, calc.moderate_threshold_mb());
- EXPECT_EQ(kCriticalMb, calc.critical_threshold_mb());
-
- ASSERT_NO_FATAL_FAILURE(CalculateCurrentPressureLevelTest(&calc));
-}
-
-// Double-check the math of the Ewma portion of the page fault monitor.
-TEST_F(DirectMemoryPressureCalculatorTest, Ewma) {
- double half_life = 100.0;
-
- double cpu_time = 0;
- uint64_t page_faults = 1;
-
- double ewma = 100.0;
-
- TestDirectMemoryPressureCalculator calc;
- calc.SetPageFaultMonitorState(cpu_time, page_faults, ewma, half_life, 0, 0);
- // Advance by one half-life. The ewma should be cut in half.
- calc.SetCpuTime(half_life);
- calc.SetPageFaults(page_faults);
- calc.CalculateCurrentPressureLevel();
- ewma /= 2;
- EXPECT_DOUBLE_EQ(ewma, calc.GetEwma());
-
- // We should get the same result if we advance by increments of 10 up to 100.
- ewma = 100.0;
- calc.SetPageFaultMonitorState(cpu_time, page_faults, ewma, half_life, 0, 0);
- static const int kIncrements = 10;
- for(int i = 1; i <= kIncrements; i++) {
- calc.SetCpuTime(i * half_life / kIncrements);
- calc.SetPageFaults(page_faults);
- calc.CalculateCurrentPressureLevel();
- }
- ewma /= 2;
- EXPECT_DOUBLE_EQ(ewma, calc.GetEwma());
-
- static const struct {
- uint64_t delta_time;
- uint64_t delta_faults;
- double expected_ewma;
- } kSamples[] = {
- // 0.5*0.0 + 0.5*10 = 5.0
- { 1, 10, 5.0 },
- // 0.5*5.0 + 0.5*10 = 7.5
- { 1, 10, 7.5 },
- // 0.25*7.5 + 0.75*(0/2) = 1.875
- { 2, 0, 1.875 },
- // 0.125*1.875 + 0.875*(420/3) = 122.734375
- { 3, 420, 122.734375 },
- // 0.5*122.734375 + 0.5*24 = 73.3671875
- { 1, 24, 73.3671875 },
- };
-
- cpu_time = 1;
- page_faults = 1;
- ewma = 0.0;
- half_life = 1.0;
- calc.SetPageFaultMonitorState(cpu_time, page_faults, ewma, half_life, 0, 0);
- for (size_t i = 0 ; i < arraysize(kSamples); i++) {
- cpu_time += kSamples[i].delta_time;
- page_faults += kSamples[i].delta_faults;
- calc.SetCpuTime(cpu_time);
- calc.SetPageFaults(page_faults);
- calc.CalculateCurrentPressureLevel();
- EXPECT_DOUBLE_EQ(kSamples[i].expected_ewma, calc.GetEwma());
- }
-}
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/direct_memory_pressure_calculator_win.cc b/chromium/components/memory_pressure/direct_memory_pressure_calculator_win.cc
deleted file mode 100644
index 48ae41e6477..00000000000
--- a/chromium/components/memory_pressure/direct_memory_pressure_calculator_win.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2015 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/memory_pressure/direct_memory_pressure_calculator_win.h"
-
-#include "base/logging.h"
-#include "base/process/process_metrics.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-namespace {
-
-const int kKBperMB = 1024;
-
-} // namespace
-
-// A system is considered 'high memory' if it has more than 1.5GB of system
-// memory available for use by the memory manager (not reserved for hardware
-// and drivers). This is a fuzzy version of the ~2GB discussed below.
-const int DirectMemoryPressureCalculator::kLargeMemoryThresholdMb = 1536;
-
-// These are the default thresholds used for systems with < ~2GB of physical
-// memory. Such systems have been observed to always maintain ~100MB of
-// available memory, paging until that is the case. To try to avoid paging a
-// threshold slightly above this is chosen. The moderate threshold is slightly
-// less grounded in reality and chosen as 2.5x critical.
-const int
- DirectMemoryPressureCalculator::kSmallMemoryDefaultModerateThresholdMb =
- 500;
-const int
- DirectMemoryPressureCalculator::kSmallMemoryDefaultCriticalThresholdMb =
- 200;
-
-// These are the default thresholds used for systems with >= ~2GB of physical
-// memory. Such systems have been observed to always maintain ~300MB of
-// available memory, paging until that is the case.
-const int
- DirectMemoryPressureCalculator::kLargeMemoryDefaultModerateThresholdMb =
- 1000;
-const int
- DirectMemoryPressureCalculator::kLargeMemoryDefaultCriticalThresholdMb =
- 400;
-
-DirectMemoryPressureCalculator::DirectMemoryPressureCalculator()
- : moderate_threshold_mb_(0), critical_threshold_mb_(0) {
- InferThresholds();
-}
-
-DirectMemoryPressureCalculator::DirectMemoryPressureCalculator(
- int moderate_threshold_mb,
- int critical_threshold_mb)
- : moderate_threshold_mb_(moderate_threshold_mb),
- critical_threshold_mb_(critical_threshold_mb) {
- DCHECK_GE(moderate_threshold_mb_, critical_threshold_mb_);
- DCHECK_LE(0, critical_threshold_mb_);
-}
-
-DirectMemoryPressureCalculator::MemoryPressureLevel
-DirectMemoryPressureCalculator::CalculateCurrentPressureLevel() {
- base::SystemMemoryInfoKB mem_info = {};
- if (!GetSystemMemoryInfo(&mem_info))
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-
- // How much system memory is actively available for use right now, in MBs.
- int phys_free = mem_info.avail_phys / kKBperMB;
-
- // TODO(chrisha): This should eventually care about address space pressure,
- // but the browser process (where this is running) effectively never runs out
- // of address space. Renderers occasionally do, but it does them no good to
- // have the browser process monitor address space pressure. Long term,
- // renderers should run their own address space pressure monitors and act
- // accordingly, with the browser making cross-process decisions based on
- // system memory pressure.
-
- // Determine if the physical memory is under critical memory pressure.
- if (phys_free <= critical_threshold_mb_)
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
-
- // Determine if the physical memory is under moderate memory pressure.
- if (phys_free <= moderate_threshold_mb_)
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
-
- // No memory pressure was detected.
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-bool DirectMemoryPressureCalculator::GetSystemMemoryInfo(
- base::SystemMemoryInfoKB* mem_info) const {
- return base::GetSystemMemoryInfo(mem_info);
-}
-
-void DirectMemoryPressureCalculator::InferThresholds() {
- // Determine if the memory installed is 'large' or 'small'. Default to 'large'
- // on failure, which uses more conservative thresholds.
- bool large_memory = true;
- base::SystemMemoryInfoKB mem_info = {};
- if (GetSystemMemoryInfo(&mem_info)) {
- large_memory = mem_info.total / kKBperMB >=
- DirectMemoryPressureCalculator::kLargeMemoryThresholdMb;
- }
-
- if (large_memory) {
- moderate_threshold_mb_ = kLargeMemoryDefaultModerateThresholdMb;
- critical_threshold_mb_ = kLargeMemoryDefaultCriticalThresholdMb;
- } else {
- moderate_threshold_mb_ = kSmallMemoryDefaultModerateThresholdMb;
- critical_threshold_mb_ = kSmallMemoryDefaultCriticalThresholdMb;
- }
-}
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/direct_memory_pressure_calculator_win.h b/chromium/components/memory_pressure/direct_memory_pressure_calculator_win.h
deleted file mode 100644
index 648dc74a8d8..00000000000
--- a/chromium/components/memory_pressure/direct_memory_pressure_calculator_win.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2015 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_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_WIN_H_
-#define COMPONENTS_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_WIN_H_
-
-#include "base/macros.h"
-#include "base/process/process_metrics.h"
-#include "build/build_config.h"
-#include "components/memory_pressure/memory_pressure_calculator.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-// OS-specific implementation of MemoryPressureCalculator. This is only defined
-// and used on platforms that do not have native memory pressure signals
-// (ChromeOS, Linux, Windows). OSes that do have native signals simply hook into
-// the appropriate subsystem (Android, Mac OS X).
-class DirectMemoryPressureCalculator : public MemoryPressureCalculator {
- public:
- // Exposed for unittesting. See .cc file for detailed discussion of these
- // constants.
- static const int kLargeMemoryThresholdMb;
- static const int kSmallMemoryDefaultModerateThresholdMb;
- static const int kSmallMemoryDefaultCriticalThresholdMb;
- static const int kLargeMemoryDefaultModerateThresholdMb;
- static const int kLargeMemoryDefaultCriticalThresholdMb;
-
- // Default constructor. Will choose thresholds automatically based on the
- // actual amount of system memory installed.
- DirectMemoryPressureCalculator();
-
- // Constructor with explicit memory thresholds. These represent the amount of
- // free memory below which the applicable memory pressure state applies.
- DirectMemoryPressureCalculator(int moderate_threshold_mb,
- int critical_threshold_mb);
-
- ~DirectMemoryPressureCalculator() override {}
-
- // Calculates the current pressure level.
- MemoryPressureLevel CalculateCurrentPressureLevel() override;
-
- int moderate_threshold_mb() const { return moderate_threshold_mb_; }
- int critical_threshold_mb() const { return critical_threshold_mb_; }
-
- private:
- friend class TestDirectMemoryPressureCalculator;
-
- // Gets system memory status. This is virtual as a unittesting hook and by
- // default this invokes base::GetSystemMemoryInfo.
- virtual bool GetSystemMemoryInfo(base::SystemMemoryInfoKB* mem_info) const;
-
- // Uses GetSystemMemoryInfo to automatically infer appropriate values for
- // moderate_threshold_mb_ and critical_threshold_mb_.
- void InferThresholds();
-
- // Threshold amounts of available memory that trigger pressure levels. See
- // memory_pressure_monitor_win.cc for a discussion of reasonable values for
- // these.
- int moderate_threshold_mb_;
- int critical_threshold_mb_;
-
- DISALLOW_COPY_AND_ASSIGN(DirectMemoryPressureCalculator);
-};
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_DIRECT_MEMORY_PRESSURE_CALCULATOR_WIN_H_
diff --git a/chromium/components/memory_pressure/direct_memory_pressure_calculator_win_unittest.cc b/chromium/components/memory_pressure/direct_memory_pressure_calculator_win_unittest.cc
deleted file mode 100644
index a8f0ec5aafc..00000000000
--- a/chromium/components/memory_pressure/direct_memory_pressure_calculator_win_unittest.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2015 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/memory_pressure/direct_memory_pressure_calculator_win.h"
-
-#include "base/logging.h"
-#include "base/process/process_metrics.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-namespace {
-
-const int kKBperMB = 1024;
-
-} // namespace
-
-// This is out of the anonymous namespace space because it is a friend of
-// DirectMemoryPressureCalculator.
-class TestDirectMemoryPressureCalculator
- : public DirectMemoryPressureCalculator {
- public:
- explicit TestDirectMemoryPressureCalculator(bool large_memory)
- : DirectMemoryPressureCalculator(20, 10) {
- // The values passed to the MemoryPressureCalculator constructor are dummy
- // values that are immediately overwritten by InferTresholds.
-
- // Generate a plausible amount of memory.
- mem_info_.total = GenerateTotalMemoryMb(large_memory) * kKBperMB;
-
- // Run InferThresholds using the test fixture's GetSystemMemoryStatus.
- InferThresholds();
- }
-
- TestDirectMemoryPressureCalculator(int total_memory_mb,
- int moderate_threshold_mb,
- int critical_threshold_mb)
- : DirectMemoryPressureCalculator(moderate_threshold_mb,
- critical_threshold_mb) {
- mem_info_.total = total_memory_mb * kKBperMB;
- }
-
- // Generates an amount of total memory that is consistent with the requested
- // memory model.
- static int GenerateTotalMemoryMb(bool large_memory) {
- int total_mb = 64;
- while (total_mb < kLargeMemoryThresholdMb)
- total_mb *= 2;
- if (large_memory)
- return total_mb * 2;
- return total_mb / 2;
- }
-
- // Sets up the memory status to reflect the provided absolute memory left.
- void SetMemoryFree(int phys_left_mb) {
- // |total| is set in the constructor and not modified.
-
- // Set the amount of free memory.
- mem_info_.avail_phys = phys_left_mb * kKBperMB;
- DCHECK_LT(mem_info_.avail_phys, mem_info_.total);
- }
-
- void SetNone() { SetMemoryFree(moderate_threshold_mb() + 1); }
-
- void SetModerate() { SetMemoryFree(moderate_threshold_mb() - 1); }
-
- void SetCritical() { SetMemoryFree(critical_threshold_mb() - 1); }
-
- private:
- bool GetSystemMemoryInfo(base::SystemMemoryInfoKB* mem_info) const override {
- // Simply copy the memory information set by the test fixture.
- *mem_info = mem_info_;
- return true;
- }
-
- base::SystemMemoryInfoKB mem_info_;
-};
-
-class DirectMemoryPressureCalculatorTest : public testing::Test {
- public:
- void CalculateCurrentPressureLevelTest(
- TestDirectMemoryPressureCalculator* calc) {
- int mod = calc->moderate_threshold_mb();
- calc->SetMemoryFree(mod + 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetNone();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(mod);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(mod - 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- int crit = calc->critical_threshold_mb();
- calc->SetMemoryFree(crit + 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(crit);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetMemoryFree(crit - 1);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- calc->CalculateCurrentPressureLevel());
-
- calc->SetCritical();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- calc->CalculateCurrentPressureLevel());
- }
-};
-
-// Tests the fundamental direct calculation of memory pressure with automatic
-// small-memory thresholds.
-TEST_F(DirectMemoryPressureCalculatorTest,
- CalculateCurrentMemoryPressureLevelSmall) {
- static const int kModerateMb =
- DirectMemoryPressureCalculator::kSmallMemoryDefaultModerateThresholdMb;
- static const int kCriticalMb =
- DirectMemoryPressureCalculator::kSmallMemoryDefaultCriticalThresholdMb;
-
- TestDirectMemoryPressureCalculator calc(false); // Small-memory model.
-
- EXPECT_EQ(kModerateMb, calc.moderate_threshold_mb());
- EXPECT_EQ(kCriticalMb, calc.critical_threshold_mb());
-
- ASSERT_NO_FATAL_FAILURE(CalculateCurrentPressureLevelTest(&calc));
-}
-
-// Tests the fundamental direct calculation of memory pressure with automatic
-// large-memory thresholds.
-TEST_F(DirectMemoryPressureCalculatorTest,
- CalculateCurrentMemoryPressureLevelLarge) {
- static const int kModerateMb =
- DirectMemoryPressureCalculator::kLargeMemoryDefaultModerateThresholdMb;
- static const int kCriticalMb =
- DirectMemoryPressureCalculator::kLargeMemoryDefaultCriticalThresholdMb;
-
- TestDirectMemoryPressureCalculator calc(true); // Large-memory model.
-
- EXPECT_EQ(kModerateMb, calc.moderate_threshold_mb());
- EXPECT_EQ(kCriticalMb, calc.critical_threshold_mb());
-
- ASSERT_NO_FATAL_FAILURE(CalculateCurrentPressureLevelTest(&calc));
-}
-
-// Tests the fundamental direct calculation of memory pressure with manually
-// specified threshold levels.
-TEST_F(DirectMemoryPressureCalculatorTest,
- CalculateCurrentMemoryPressureLevelCustom) {
- static const int kSystemMb = 512;
- static const int kModerateMb = 256;
- static const int kCriticalMb = 128;
-
- TestDirectMemoryPressureCalculator calc(kSystemMb, kModerateMb, kCriticalMb);
-
- EXPECT_EQ(kModerateMb, calc.moderate_threshold_mb());
- EXPECT_EQ(kCriticalMb, calc.critical_threshold_mb());
-
- ASSERT_NO_FATAL_FAILURE(CalculateCurrentPressureLevelTest(&calc));
-}
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/filtered_memory_pressure_calculator.cc b/chromium/components/memory_pressure/filtered_memory_pressure_calculator.cc
deleted file mode 100644
index 3965196ae17..00000000000
--- a/chromium/components/memory_pressure/filtered_memory_pressure_calculator.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2015 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/memory_pressure/filtered_memory_pressure_calculator.h"
-
-#include <algorithm>
-#include "base/time/tick_clock.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-FilteredMemoryPressureCalculator::FilteredMemoryPressureCalculator(
- MemoryPressureCalculator* pressure_calculator,
- base::TickClock* tick_clock)
- : pressure_calculator_(pressure_calculator),
- tick_clock_(tick_clock),
- current_pressure_level_(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
- samples_taken_(false),
- cooldown_in_progress_(false) {
- DCHECK(pressure_calculator);
- DCHECK(tick_clock);
-}
-
-FilteredMemoryPressureCalculator::~FilteredMemoryPressureCalculator() {
-}
-
-FilteredMemoryPressureCalculator::MemoryPressureLevel
-FilteredMemoryPressureCalculator::CalculateCurrentPressureLevel() {
- base::TimeTicks now = tick_clock_->NowTicks();
-
- // Take a sample.
- samples_taken_ = true;
- last_sample_time_ = now;
- MemoryPressureLevel level =
- pressure_calculator_->CalculateCurrentPressureLevel();
-
- // The pressure hasn't changed or has gone up. In either case this is the end
- // of a cooldown period if one was in progress.
- if (level >= current_pressure_level_) {
- cooldown_in_progress_ = false;
- current_pressure_level_ = level;
- return level;
- }
-
- // The pressure has gone down, so apply cooldown hysteresis.
- if (cooldown_in_progress_) {
- cooldown_high_tide_ = std::max(cooldown_high_tide_, level);
-
- // Get the cooldown period for the current level.
- int cooldown_ms = kCriticalPressureCooldownPeriodMs;
- if (current_pressure_level_ ==
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE) {
- cooldown_ms = kModeratePressureCooldownPeriodMs;
- }
- base::TimeDelta cooldown_period =
- base::TimeDelta::FromMilliseconds(cooldown_ms);
-
- if (now - cooldown_start_time_ >= cooldown_period) {
- // The cooldown has completed successfully, so transition the pressure
- // level.
- cooldown_in_progress_ = false;
- current_pressure_level_ = cooldown_high_tide_;
- }
- } else {
- // Start a new cooldown period.
- cooldown_in_progress_ = true;
- cooldown_start_time_ = now;
- cooldown_high_tide_ = level;
- }
-
- return current_pressure_level_;
-}
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/filtered_memory_pressure_calculator.h b/chromium/components/memory_pressure/filtered_memory_pressure_calculator.h
deleted file mode 100644
index 722f491cf68..00000000000
--- a/chromium/components/memory_pressure/filtered_memory_pressure_calculator.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2015 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_MEMORY_PRESSURE_FILTERED_MEMORY_PRESSURE_CALCULATOR_H_
-#define COMPONENTS_MEMORY_PRESSURE_FILTERED_MEMORY_PRESSURE_CALCULATOR_H_
-
-#include "components/memory_pressure/memory_pressure_calculator.h"
-
-#include "base/macros.h"
-#include "base/time/time.h"
-
-namespace base {
-class TickClock;
-} // namespace base
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-// A utility class that provides rate-limiting and hysteresis on raw memory
-// pressure calculations. This is identical across all platforms, but only used
-// on those that do not have native memory pressure signals.
-class FilteredMemoryPressureCalculator : public MemoryPressureCalculator {
- public:
- // The cooldown period when transitioning from critical to moderate/no memory
- // pressure, or from moderate to none.
- //
- // These values were experimentally obtained during the initial ChromeOS only
- // implementation of this feature. By spending a significant cooldown period
- // at a higher pressure level more time is dedicated to freeing resources and
- // less churn occurs in the MemoryPressureListener event stream.
- enum : int { kCriticalPressureCooldownPeriodMs = 5000 };
- enum : int { kModeratePressureCooldownPeriodMs = 5000 };
-
- // The provided |pressure_calculator| and |tick_clock| must outlive this
- // object.
- FilteredMemoryPressureCalculator(
- MemoryPressureCalculator* pressure_calculator,
- base::TickClock* tick_clock);
- ~FilteredMemoryPressureCalculator() override;
-
- // Calculates the current pressure level.
- MemoryPressureLevel CalculateCurrentPressureLevel() override;
-
- // Accessors for unittesting.
- bool cooldown_in_progress() const { return cooldown_in_progress_; }
- base::TimeTicks cooldown_start_time() const { return cooldown_start_time_; }
- MemoryPressureLevel cooldown_high_tide() const { return cooldown_high_tide_; }
-
- private:
- friend class TestFilteredMemoryPressureCalculator;
-
- // The delegate pressure calculator. Provided by the constructor.
- MemoryPressureCalculator* pressure_calculator_;
-
- // The delegate tick clock. Provided by the constructor.
- base::TickClock* tick_clock_;
-
- // The memory pressure currently being reported.
- MemoryPressureLevel current_pressure_level_;
-
- // The last time a sample was taken.
- bool samples_taken_;
- base::TimeTicks last_sample_time_;
-
- // State of an ongoing cooldown period, if any. The high-tide line indicates
- // the highest memory pressure level (*below* the current one) that was
- // encountered during the cooldown period. This allows a cooldown to
- // transition directly from critical to none if *no* moderate pressure signals
- // were seen during the period, otherwise it forces it to pass through a
- // moderate cooldown as well.
- bool cooldown_in_progress_;
- base::TimeTicks cooldown_start_time_;
- MemoryPressureLevel cooldown_high_tide_;
-
- DISALLOW_COPY_AND_ASSIGN(FilteredMemoryPressureCalculator);
-};
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_FILTERED_MEMORY_PRESSURE_CALCULATOR_H_
diff --git a/chromium/components/memory_pressure/filtered_memory_pressure_calculator_unittest.cc b/chromium/components/memory_pressure/filtered_memory_pressure_calculator_unittest.cc
deleted file mode 100644
index dc7278322fc..00000000000
--- a/chromium/components/memory_pressure/filtered_memory_pressure_calculator_unittest.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2015 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/memory_pressure/filtered_memory_pressure_calculator.h"
-
-#include "base/macros.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "components/memory_pressure/test_memory_pressure_calculator.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-class FilteredMemoryPressureCalculatorTest : public testing::Test {
- public:
- FilteredMemoryPressureCalculatorTest()
- : filter_(&calculator_, &tick_clock_) {}
-
- // Advances the tick clock by the given number of milliseconds.
- void Tick(int ms) {
- tick_clock_.Advance(base::TimeDelta::FromMilliseconds(ms));
- }
-
- // Delegates that are injected into the object under test.
- TestMemoryPressureCalculator calculator_;
- base::SimpleTestTickClock tick_clock_;
-
- // The object under test.
- FilteredMemoryPressureCalculator filter_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FilteredMemoryPressureCalculatorTest);
-};
-
-TEST_F(FilteredMemoryPressureCalculatorTest, FirstCallInvokesCalculator) {
- calculator_.SetCritical();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(1, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-}
-
-TEST_F(FilteredMemoryPressureCalculatorTest, CooldownCriticalToModerate) {
- calculator_.SetCritical();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(1, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-
- // Initiate a cooldown period by stepping forward and taking another sample.
- Tick(100);
- calculator_.SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(2, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(tick_clock_.NowTicks(), filter_.cooldown_start_time());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.cooldown_high_tide());
-
- // Take another sample and it should still not have changed.
- Tick(100);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(3, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.cooldown_high_tide());
-
- // Step the cooldown period and it should change state.
- Tick(FilteredMemoryPressureCalculator::kCriticalPressureCooldownPeriodMs);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(4, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-}
-
-TEST_F(FilteredMemoryPressureCalculatorTest,
- CooldownCriticalToModerateViaNone) {
- calculator_.SetCritical();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(1, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-
- // Initiate a cooldown period by stepping forward and taking another sample.
- // First go directly to no memory pressure before passing back through
- // moderate. The final result should be a moderate memory pressure.
- Tick(100);
- calculator_.SetNone();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(2, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(tick_clock_.NowTicks(), filter_.cooldown_start_time());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.cooldown_high_tide());
-
- // Take another sample and it should still not have changed.
- Tick(100);
- calculator_.SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(3, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.cooldown_high_tide());
-
- // Step the cooldown period and it should change state.
- Tick(FilteredMemoryPressureCalculator::kCriticalPressureCooldownPeriodMs);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(4, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-}
-
-TEST_F(FilteredMemoryPressureCalculatorTest, CooldownCriticalToNone) {
- calculator_.SetCritical();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(1, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-
- // Initiate a cooldown period by stepping forward and taking another sample.
- Tick(100);
- calculator_.SetNone();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(2, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(tick_clock_.NowTicks(), filter_.cooldown_start_time());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.cooldown_high_tide());
-
- // Take another sample and it should still not have changed.
- Tick(100);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(3, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.cooldown_high_tide());
-
- // Step the cooldown period and it should change state.
- Tick(FilteredMemoryPressureCalculator::kModeratePressureCooldownPeriodMs);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(4, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-}
-
-TEST_F(FilteredMemoryPressureCalculatorTest, CooldownModerateToNone) {
- calculator_.SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(1, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-
- // Initiate a cooldown period by stepping forward and taking another sample.
- Tick(100);
- calculator_.SetNone();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(2, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(tick_clock_.NowTicks(), filter_.cooldown_start_time());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.cooldown_high_tide());
-
- // Take another sample and it should still not have changed.
- Tick(100);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(3, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.cooldown_high_tide());
-
- // Step the cooldown period and it should change state.
- Tick(FilteredMemoryPressureCalculator::kModeratePressureCooldownPeriodMs);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(4, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-}
-
-TEST_F(FilteredMemoryPressureCalculatorTest, InterruptedCooldownModerate) {
- calculator_.SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(1, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-
- // Initiate a cooldown period by stepping forward and taking another sample.
- Tick(100);
- calculator_.SetNone();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(2, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(tick_clock_.NowTicks(), filter_.cooldown_start_time());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.cooldown_high_tide());
-
- // Take another sample and it should still not have changed. Since the
- // pressure level has increased back to moderate it should also end the
- // cooldown period.
- Tick(100);
- calculator_.SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(3, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-}
-
-TEST_F(FilteredMemoryPressureCalculatorTest, InterruptedCooldownCritical) {
- calculator_.SetModerate();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(1, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-
- // Initiate a cooldown period by stepping forward and taking another sample.
- Tick(100);
- calculator_.SetNone();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(2, calculator_.calls());
- EXPECT_TRUE(filter_.cooldown_in_progress());
- EXPECT_EQ(tick_clock_.NowTicks(), filter_.cooldown_start_time());
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- filter_.cooldown_high_tide());
-
- // Take another sample and it should still not have changed. Since the
- // pressure level has increased to critical it ends the cooldown period and
- // immediately reports the critical memory pressure.
- Tick(100);
- calculator_.SetCritical();
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- filter_.CalculateCurrentPressureLevel());
- EXPECT_EQ(3, calculator_.calls());
- EXPECT_FALSE(filter_.cooldown_in_progress());
-}
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/memory_pressure_calculator.h b/chromium/components/memory_pressure/memory_pressure_calculator.h
deleted file mode 100644
index f55939b9b8a..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_calculator.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2015 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_MEMORY_PRESSURE_MEMORY_PRESSURE_CALCULATOR_H_
-#define COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_CALCULATOR_H_
-
-#include "base/macros.h"
-#include "components/memory_pressure/memory_pressure_listener.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-// Interface for a utility class that calculates memory pressure. Only used on
-// platforms without native memory pressure signals.
-class MemoryPressureCalculator {
- public:
- using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
-
- MemoryPressureCalculator() {}
- virtual ~MemoryPressureCalculator() {}
- virtual MemoryPressureLevel CalculateCurrentPressureLevel() = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureCalculator);
-};
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_CALCULATOR_H_
diff --git a/chromium/components/memory_pressure/memory_pressure_listener.cc b/chromium/components/memory_pressure/memory_pressure_listener.cc
deleted file mode 100644
index 3d2fe1a9b3c..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_listener.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 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/memory_pressure/memory_pressure_listener.h"
-
-#include "base/lazy_instance.h"
-#include "base/observer_list_threadsafe.h"
-#include "base/trace_event/trace_event.h"
-
-namespace memory_pressure {
-
-namespace {
-
-// ObserverListThreadSafe is RefCountedThreadSafe, this traits is needed
-// to ensure the LazyInstance will hold a reference to it.
-struct LeakyLazyObserverListTraits
- : base::internal::LeakyLazyInstanceTraits<
- base::ObserverListThreadSafe<MemoryPressureListener>> {
- static base::ObserverListThreadSafe<MemoryPressureListener>* New(
- void* instance) {
- base::ObserverListThreadSafe<MemoryPressureListener>* ret =
- base::internal::LeakyLazyInstanceTraits<base::ObserverListThreadSafe<
- MemoryPressureListener>>::New(instance);
- // Leaky.
- ret->AddRef();
- return ret;
- }
-};
-
-base::LazyInstance<base::ObserverListThreadSafe<MemoryPressureListener>,
- LeakyLazyObserverListTraits> g_observers =
- LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
-MemoryPressureListener::MemoryPressureListener(
- const MemoryPressureListener::MemoryPressureCallback& callback)
- : callback_(callback) {
- g_observers.Get().AddObserver(this);
-}
-
-MemoryPressureListener::~MemoryPressureListener() {
- g_observers.Get().RemoveObserver(this);
-}
-
-void MemoryPressureListener::Notify(MemoryPressureLevel memory_pressure_level) {
- callback_.Run(memory_pressure_level);
-}
-
-// static
-void MemoryPressureListener::NotifyMemoryPressure(
- MemoryPressureLevel memory_pressure_level) {
- DCHECK_NE(memory_pressure_level, MEMORY_PRESSURE_LEVEL_NONE);
- TRACE_EVENT1("memory", "MemoryPressureListener::NotifyMemoryPressure",
- "level", memory_pressure_level);
- g_observers.Get().Notify(FROM_HERE, &MemoryPressureListener::Notify,
- memory_pressure_level);
-}
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/memory_pressure_listener.h b/chromium/components/memory_pressure/memory_pressure_listener.h
deleted file mode 100644
index d0efd3b7b8f..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_listener.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2015 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.
-
-// MemoryPressureListener provides static APIs for handling memory pressure on
-// platforms that have such signals (Android, ChromeOS, Mac and Windows). When
-// such signals are received the app will try to discard buffers that aren't
-// deemed essential (individual modules will implement their own policy).
-
-#ifndef COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_LISTENER_H_
-#define COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_LISTENER_H_
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/macros.h"
-#include "build/build_config.h"
-
-// Other operating systems will be added to this as they are implemented.
-#if defined(OS_WIN) || defined(OS_LINUX)
-#define MEMORY_PRESSURE_IS_POLLING
-#endif
-
-namespace memory_pressure {
-
-// To start listening, create a new instance, passing a callback to a
-// function that takes a MemoryPressureLevel parameter. To stop listening,
-// simply delete the listener object. The implementation guarantees
-// that the callback will always be called on the thread that created
-// the listener.
-//
-// Note that even on the same thread, the callback is not guaranteed to be
-// called synchronously within the system memory pressure broadcast.
-// Please see notes in MemoryPressureLevel enum below: some levels are
-// absolutely critical, and if not enough memory is returned to the system,
-// it'll potentially kill the app, and then later the app will have to be
-// cold-started.
-//
-// Example:
-//
-// void OnMemoryPressure(MemoryPressureLevel memory_pressure_level) {
-// ...
-// }
-//
-// // Start listening.
-// MemoryPressureListener* my_listener =
-// new MemoryPressureListener(base::Bind(&OnMemoryPressure));
-//
-// ...
-//
-// // Stop listening.
-// delete my_listener;
-//
-class MemoryPressureListener {
- public:
- // A Java counterpart will be generated for this enum.
- // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
- enum MemoryPressureLevel {
- // No problems, there is enough memory to use. This event is not sent via
- // callback, but the enum is used in other places to find out the current
- // state of the system.
- MEMORY_PRESSURE_LEVEL_NONE = -1,
-
- // Modules are advised to free buffers that are cheap to re-allocate and not
- // immediately needed.
- MEMORY_PRESSURE_LEVEL_MODERATE = 0,
-
- // At this level, modules are advised to free all possible memory. The
- // alternative is to be killed by the system, which means all memory will
- // have to be re-created, plus the cost of a cold start.
- MEMORY_PRESSURE_LEVEL_CRITICAL = 2,
- };
-
- typedef base::Callback<void(MemoryPressureLevel)> MemoryPressureCallback;
-
- explicit MemoryPressureListener(
- const MemoryPressureCallback& memory_pressure_callback);
- ~MemoryPressureListener();
-
- // Intended for use by the platform specific implementation.
- static void NotifyMemoryPressure(MemoryPressureLevel memory_pressure_level);
-
- private:
- void Notify(MemoryPressureLevel memory_pressure_level);
-
- MemoryPressureCallback callback_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureListener);
-};
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_LISTENER_H_
diff --git a/chromium/components/memory_pressure/memory_pressure_monitor.cc b/chromium/components/memory_pressure/memory_pressure_monitor.cc
deleted file mode 100644
index a0f67a8fa31..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_monitor.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2016 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/memory_pressure/memory_pressure_monitor.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/task_runner.h"
-#include "base/time/tick_clock.h"
-#include "components/memory_pressure/memory_pressure_calculator.h"
-#include "components/memory_pressure/memory_pressure_stats_collector.h"
-
-namespace memory_pressure {
-
-namespace {
-
-using MemoryPressureLevel = MemoryPressureMonitor::MemoryPressureLevel;
-const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_NONE =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_MODERATE =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
-const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_CRITICAL =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
-
-// Returns the polling/notification interval for the given pressure level.
-int GetPollingIntervalMs(MemoryPressureLevel level) {
- switch (level) {
- case MEMORY_PRESSURE_LEVEL_NONE:
- return MemoryPressureMonitor::kDefaultPollingIntervalMs;
-
- case MEMORY_PRESSURE_LEVEL_MODERATE:
- return MemoryPressureMonitor::kNotificationIntervalPressureModerateMs;
-
- case MEMORY_PRESSURE_LEVEL_CRITICAL:
- return MemoryPressureMonitor::kNotificationIntervalPressureCriticalMs;
- }
-
- NOTREACHED();
- return 0;
-}
-
-base::TimeDelta GetPollingInterval(MemoryPressureLevel level) {
- return base::TimeDelta::FromMilliseconds(GetPollingIntervalMs(level));
-}
-
-// Serial number reserved for unscheduled checks as a result of external calls
-// to the monitor.
-const int kUnscheduledCheckSerial = 0;
-
-} // namespace
-
-#if !defined(MEMORY_PRESSURE_IS_POLLING)
-// Default definition of this class.
-// TODO(chrisha): Implement useful versions of this for affected platforms.
-class MemoryPressureMonitorImpl {};
-#endif
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-MemoryPressureMonitor::MemoryPressureMonitor(
- const scoped_refptr<base::TaskRunner>& task_runner,
- base::TickClock* tick_clock,
- MemoryPressureStatsCollector* stats_collector,
- MemoryPressureCalculator* calculator,
- const DispatchCallback& dispatch_callback)
- : task_runner_(task_runner),
- tick_clock_(tick_clock),
- stats_collector_(stats_collector),
- calculator_(calculator),
- dispatch_callback_(dispatch_callback),
- current_memory_pressure_level_(MEMORY_PRESSURE_LEVEL_NONE),
- serial_number_(kUnscheduledCheckSerial),
- weak_ptr_factory_(this) {
- DCHECK(task_runner_.get());
- DCHECK(tick_clock_);
- DCHECK(stats_collector_);
- DCHECK(calculator_);
- DCHECK(!dispatch_callback_.is_null());
-
- Start();
-}
-#else // MEMORY_PRESSURE_IS_POLLING
-MemoryPressureMonitor::MemoryPressureMonitor(
- const scoped_refptr<base::TaskRunner>& task_runner,
- base::TickClock* tick_clock,
- MemoryPressureStatsCollector* stats_collector,
- const DispatchCallback& dispatch_callback,
- MemoryPressureLevel initial_pressure_level)
- : task_runner_(task_runner),
- tick_clock_(tick_clock),
- stats_collector_(stats_collector),
- dispatch_callback_(dispatch_callback),
- current_memory_pressure_level_(initial_pressure_level),
- serial_number_(kUnscheduledCheckSerial),
- weak_ptr_factory_(this) {
- DCHECK(task_runner_.get());
- DCHECK(tick_clock_);
- DCHECK(stats_collector_);
- DCHECK(!dispatch_callback_.is_null());
-
- Start();
-}
-#endif // !MEMORY_PRESSURE_IS_POLLING
-
-MemoryPressureMonitor::~MemoryPressureMonitor() {}
-
-MemoryPressureLevel MemoryPressureMonitor::GetCurrentPressureLevel() {
- base::AutoLock lock(lock_);
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- // Force an immediate pressure check on polling platforms. On non-polling
- // platforms the current memory pressure is always valid.
- CheckPressureAndUpdateStatsLocked(kUnscheduledCheckSerial);
-#endif
-
- return current_memory_pressure_level_;
-}
-
-void MemoryPressureMonitor::CheckMemoryPressureSoon() {
- // This function is a nop on non-polling platforms.
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- // Schedule a check to run as soon as possible.
- base::AutoLock lock(lock_);
- base::TimeTicks now = tick_clock_->NowTicks();
- ScheduleTaskLocked(now);
-#endif
-}
-
-#if !defined(MEMORY_PRESSURE_IS_POLLING)
-// This is the entry point for OS notifications of pressure level changes.
-void MemoryPressureMonitor::OnMemoryPressureChanged(
- MemoryPressureLevel level) {
- base::AutoLock lock(lock_);
-
- // Do nothing if the level hasn't changed.
- if (level == current_memory_pressure_level_)
- return;
-
- // Update the level and the stats.
- current_memory_pressure_level_ = level;
- stats_collector_->UpdateStatistics(current_memory_pressure_level_);
-
- // Only dispatch notifications if there is memory pressure.
- if (current_memory_pressure_level_ > MEMORY_PRESSURE_LEVEL_NONE) {
- last_notification_ = tick_clock_->NowTicks();
- dispatch_callback_.Run(current_memory_pressure_level_);
- }
-
- ScheduleTaskIfNeededLocked(kUnscheduledCheckSerial);
-}
-#endif
-
-void MemoryPressureMonitor::Start() {
- base::AutoLock lock(lock_);
-
- base::TimeTicks now = tick_clock_->NowTicks();
-
- // Get the statistics collector warmed up by measuring the pressure level.
- // Don't immediately fire a signal if already under memory pressure as the
- // system is quite busy with startup right now. Wait until the first
- // renotification is required, allowing the browser time to get started.
- // Non-polling implementations set the initial memory pressure level in the
- // constructor.
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- current_memory_pressure_level_ = calculator_->CalculateCurrentPressureLevel();
- last_check_ = now;
-#endif
-
- last_notification_ = now;
- stats_collector_->UpdateStatistics(current_memory_pressure_level_);
- ScheduleTaskIfNeededLocked(kUnscheduledCheckSerial);
-}
-
-void MemoryPressureMonitor::CheckPressureAndUpdateStats(int serial) {
- // This should only ever be used by scheduled checks.
- DCHECK_NE(kUnscheduledCheckSerial, serial);
- base::AutoLock lock(lock_);
- CheckPressureAndUpdateStatsLocked(serial);
-}
-
-void MemoryPressureMonitor::CheckPressureAndUpdateStatsLocked(int serial) {
- lock_.AssertAcquired();
-
- base::TimeTicks now = tick_clock_->NowTicks();
- MemoryPressureLevel old_level = current_memory_pressure_level_;
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- // Don't check again if pressure was calculated too recently.
- DCHECK(!last_check_.is_null());
- if ((now - last_check_) >=
- base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenSamplesMs)) {
- // Calculate the current pressure level and update statistics.
- last_check_ = now;
- current_memory_pressure_level_ =
- calculator_->CalculateCurrentPressureLevel();
- stats_collector_->UpdateStatistics(current_memory_pressure_level_);
- }
-#else // MEMORY_PRESSURE_IS_POLLING
- // On non-polling platforms this function can only be invoked by scheduled
- // callbacks for updating statistics and sending renotifications. Simply
- // update the statistics and move on.
- DCHECK_NE(kUnscheduledCheckSerial, serial);
- stats_collector_->UpdateStatistics(current_memory_pressure_level_);
-#endif // !MEMORY_PRESSURE_IS_POLLING
-
- // Check if the level has changed or a renotification is required.
- DCHECK(!last_notification_.is_null());
- if (current_memory_pressure_level_ != old_level ||
- now - last_notification_ >=
- GetPollingInterval(current_memory_pressure_level_)) {
- last_notification_ = now;
-
- // Only dispatch notifications if there is memory pressure.
- if (current_memory_pressure_level_ > MEMORY_PRESSURE_LEVEL_NONE)
- dispatch_callback_.Run(current_memory_pressure_level_);
- }
-
- ScheduleTaskIfNeededLocked(serial);
-}
-
-void MemoryPressureMonitor::ScheduleTaskIfNeededLocked(int serial) {
- lock_.AssertAcquired();
-
- // Remove this check from the set of scheduled checks.
- if (serial != kUnscheduledCheckSerial) {
- size_t erased = scheduled_checks_.erase(serial);
- DCHECK_EQ(1u, erased);
- }
-
- // Get the time of the soonest scheduled check. This linear scan is quick
- // because the map will contain at most 1 entry per pressure level, and most
- // commonly only 1 entry.
- base::TimeTicks next_check;
- for (const auto& check : scheduled_checks_) {
- if (next_check.is_null() || check.second < next_check)
- next_check = check.second;
- }
-
- // Get the time of the required next check.
- base::TimeTicks required_check =
- last_notification_ + GetPollingInterval(current_memory_pressure_level_);
-
- // If there's already a check scheduled in time then don't schedule
- // another. This lets the number of scheduled checks shrink back down to 1
- // as pressure changes occur.
- if (!next_check.is_null() && next_check <= required_check)
- return;
-
- ScheduleTaskLocked(required_check);
-}
-
-void MemoryPressureMonitor::ScheduleTaskLocked(base::TimeTicks when) {
- lock_.AssertAcquired();
- int serial = ++serial_number_;
-
- // Handle overflow. For simplicity keep serial numbers positive. 2^31 leaves
- // room for 20 years of uptime in the worst case scenario (poll every second,
- // constantly swinging through all the pressure levels). But you know...
- // better safe the sorry!
- if (serial < 0) {
- serial_number_ = 1;
- serial = 1;
- }
-
- // It's entirely possible for |when| to be in the past relative to |now|, so
- // bound |delay| from below.
- base::TimeTicks now = tick_clock_->NowTicks();
- base::TimeDelta delay; // Initializes to zero.
- if (when > now)
- delay = when - now;
-
- // Schedule another check.
- if (task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&MemoryPressureMonitor::CheckPressureAndUpdateStats,
- weak_ptr_factory_.GetWeakPtr(), serial),
- delay)) {
- // If the task will run then add it to the map of scheduled checks.
- scheduled_checks_[serial] = when;
- }
-}
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/memory_pressure_monitor.h b/chromium/components/memory_pressure/memory_pressure_monitor.h
deleted file mode 100644
index 68ad09cc0ee..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_monitor.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2016 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.
-//
-// Declares the MemoryPressureMonitor class. This is responsible for monitoring
-// system-wide memory pressure and dispatching memory pressure signals to
-// MemoryPressureListener. It is also responsible for rate limiting calls to the
-// memory pressure subsytem and gathering statistics for UMA.
-//
-// The class has a few compile time differences depending on if
-// MEMORY_PRESSURE_IS_POLLING is defined. For Windows, ChromeOS and Linux
-// the implementation is polling so MEMORY_PRESSURE_IS_POLLING is defined. For
-// Mac, iOS and Android it is not defined.
-//
-// The difference is that "polling" platforms have no native OS signals
-// indicating memory pressure. These platforms implement
-// DirectMemoryPressureCalculator, which is polled on a schedule to check for
-// memory pressure changes. On non-polling platforms the OS provides a native
-// signal. This signal is observed by the platform-specific implementation of
-// MemoryPressureMonitorImpl.
-//
-// The memory pressure system periodically repeats memory pressure signals while
-// under memory pressure (the interval varying depending on the pressure level).
-// As such, even non-polling platforms require a scheduling mechanism for
-// repeating notifications. Both implementations share this basic scheduling
-// subsystem, and also leverage it to make timely UMA reports.
-
-#ifndef COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_MONITOR_H_
-#define COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_MONITOR_H_
-
-#include <map>
-#include <memory>
-
-#include "base/callback.h"
-#include "base/memory/weak_ptr.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
-#include "components/memory_pressure/memory_pressure_listener.h"
-
-namespace base {
-class TaskRunner;
-class TickClock;
-} // namespace
-
-namespace memory_pressure {
-
-class MemoryPressureCalculator;
-class MemoryPressureStatsCollector;
-
-#if !defined(MEMORY_PRESSURE_IS_POLLING)
-// For non-polling platform specific implementation details. An instance of
-// this class will be encapsulated in the monitor. It will received an injected
-// callback that routes messages to OnMemoryPressureChanged.
-class MemoryPressureMonitorImpl;
-#endif
-
-// A thread-safe class for directly querying and automatically monitoring
-// memory pressure. When system memory pressure levels change this class is
-// responsible for notifying MemoryPressureListeners, and periodically
-// renotifying them as conditions persist. This class will do its periodic work
-// on the thread on which it was created. However, it is safe to call
-// GetCurrentPressureLevel from any thread.
-//
-// This class doesn't make use of base::RepeatingTimer as it leaves an orphaned
-// scheduled task every time it is canceled. This can occur every time a memory
-// pressure level transition occurs, which has no strict upper bound. Instead
-// a collection of at most "number of memory pressure level" scheduled tasks
-// is used, with these tasks being reused as transition levels are crossed and
-// polling requirements change. See |scheduled_checks_| and
-// "ScheduleTaskIfNeededLocked" for details.
-class MemoryPressureMonitor {
- public:
- using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
-
- // A simple dispatch delegate as a testing seam. Makes unittests much simpler
- // as they don't need to setup a multithreaded environment.
- using DispatchCallback = base::Callback<void(MemoryPressureLevel)>;
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- // The minimum time that must pass between successive polls. This enforces an
- // upper bound on the rate of calls to the contained MemoryPressureCalculator.
- // 100ms (10Hz) allows a relatively fast respsonse time for rapidly increasing
- // memory usage, but limits the amount of work done in the calculator and
- // stats collection.
- enum : int { kMinimumTimeBetweenSamplesMs = 100 };
- // On polling platforms this is required to be somewhat short in order to
- // observe memory pressure changes as they occur.
- enum : int { kDefaultPollingIntervalMs = 5000 };
-#else
- // On non-polling platforms this is only required for keeping statistics up to
- // date so can be quite a long period.
- enum : int { kDefaultPollingIntervalMs = 60000 };
-#endif
-
- // Renotification intervals, per pressure level. These are the same on all
- // platforms. These act as an upper bound on the polling interval when under
- // the corresponding memory pressure.
- enum : int { kNotificationIntervalPressureModerateMs = 5000 };
- enum : int { kNotificationIntervalPressureCriticalMs = 1000 };
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- // Fully configurable constructor for polling platforms.
- MemoryPressureMonitor(const scoped_refptr<base::TaskRunner>& task_runner,
- base::TickClock* tick_clock,
- MemoryPressureStatsCollector* stats_collector,
- MemoryPressureCalculator* calculator,
- const DispatchCallback& dispatch_callback);
-#else
- // Constructor for non-polling platforms.
- MemoryPressureMonitor(const scoped_refptr<base::TaskRunner>& task_runner,
- base::TickClock* tick_clock,
- MemoryPressureStatsCollector* stats_collector,
- const DispatchCallback& dispatch_callback,
- MemoryPressureLevel initial_pressure_level);
-#endif
-
- ~MemoryPressureMonitor();
-
- // Returns the current memory pressure level. On polling platforms this may
- // result in a forced calculation of the current pressure level (a cheap
- // operation). Can be called from any thread.
- MemoryPressureLevel GetCurrentPressureLevel();
-
- // Schedules a memory pressure check to run soon. This can be called from any
- // thread.
- void CheckMemoryPressureSoon();
-
- private:
- // For unittesting.
- friend class TestMemoryPressureMonitor;
-
-#if !defined(MEMORY_PRESSURE_IS_POLLING)
- // Notifications from the OS will be routed here by the contained
- // MemoryPressureMonitorImpl instance. For statistics and renotification to
- // work properly this must be notified of all pressure level changes, even
- // those indicating a return to a state of no pressure.
- void OnMemoryPressureChanged(MemoryPressureLevel level);
-#endif
-
- // Starts the memory pressure monitor. To be called in the constructor.
- void Start();
-
- // Checks memory pressure and updates stats. This is the entry point for all
- // scheduled checks. Each scheduled check is assigned a |serial| id
- // (monotonically increasing) which is used to tie the task to the time at
- // which it was scheduled via the |scheduled_checks_| map.
- void CheckPressureAndUpdateStats(int serial);
- void CheckPressureAndUpdateStatsLocked(int serial);
-
- // Ensures that a task is scheduled for renotification/recalculation/stats
- // updating. Uses the |serial| id of the current task to determine the time at
- // which the next scheduled check should run. Assumes |lock_| is held.
- void ScheduleTaskIfNeededLocked(int serial);
-
- // Schedules a task.
- void ScheduleTaskLocked(base::TimeTicks when);
-
- // A lock for synchronization.
- base::Lock lock_;
-
- // Injected dependencies.
- // The task runner on which periodic pressure checks and statistics uploading
- // are run.
- scoped_refptr<base::TaskRunner> task_runner_;
- // The tick clock in use. Used under |lock_|.
- base::TickClock* tick_clock_;
- // The stats collector in use. Used under |lock_|.
- MemoryPressureStatsCollector* stats_collector_;
- // The memory pressure calculator in use. Used under |lock_|.
- MemoryPressureCalculator* calculator_;
- // The dispatch callback to use.
- DispatchCallback dispatch_callback_;
-
-#if !defined(MEMORY_PRESSURE_IS_POLLING)
- // On non-polling platforms this object is responsible for routing OS
- // notifications to OnMemoryPressureChanged, and setting the initial pressure
- // value. The OS specific implementation is responsible for allocating this
- // object.
- std::unique_ptr<MemoryPressureMonitorImpl> monitor_impl_;
-#endif
-
- // Object state.
- // The pressure level as of the most recent poll or notification. Under
- // |lock_|.
- MemoryPressureLevel current_memory_pressure_level_;
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- // Time of the last pressure check. Under |lock_|. Only needed for polling
- // implementations.
- base::TimeTicks last_check_;
-#endif
- // Time of the last pressure notification. Under |lock_|.
- base::TimeTicks last_notification_;
- // A map of scheduled pressure checks/statistics updates and their serial
- // numbers. Under |lock_|.
- std::map<int, base::TimeTicks> scheduled_checks_;
- // The most recently assigned serial number for a pressure check. The number
- // 0 will never be assigned but will instead be reserved for unscheduled
- // checks initiated externally. Under |lock_|.
- int serial_number_;
-
- // Weak pointer factory to ourself used for posting delayed tasks to
- // task_runner_.
- base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
-};
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_MONITOR_H_
diff --git a/chromium/components/memory_pressure/memory_pressure_monitor_unittest.cc b/chromium/components/memory_pressure/memory_pressure_monitor_unittest.cc
deleted file mode 100644
index ac608bf7923..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_monitor_unittest.cc
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright 2016 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/memory_pressure/memory_pressure_monitor.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/task_runner.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/tracked_objects.h"
-#include "components/memory_pressure/memory_pressure_stats_collector.h"
-#include "components/memory_pressure/test_memory_pressure_calculator.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace memory_pressure {
-
-namespace {
-
-using MemoryPressureLevel = MemoryPressureMonitor::MemoryPressureLevel;
-const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_NONE =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_MODERATE =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
-const MemoryPressureLevel MEMORY_PRESSURE_LEVEL_CRITICAL =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
-
-using testing::_;
-
-} // namespace
-
-// A mock task runner. This isn't directly a TaskRunner as the reference
-// counting confuses gmock.
-class LenientMockTaskRunner {
- public:
- MOCK_METHOD2(PostDelayedTask,
- bool(const tracked_objects::Location&, base::TimeDelta));
-};
-using MockTaskRunner = testing::StrictMock<LenientMockTaskRunner>;
-
-// A TaskRunner implementation that wraps a MockTaskRunner.
-class TaskRunnerProxy : public base::TaskRunner {
- public:
- // The provided |mock| must outlive this object.
- explicit TaskRunnerProxy(MockTaskRunner* mock) : mock_(mock) {}
- bool RunsTasksOnCurrentThread() const override { return true; }
- bool PostDelayedTask(const tracked_objects::Location& location,
- base::OnceClosure closure,
- base::TimeDelta delta) override {
- return mock_->PostDelayedTask(location, delta);
- }
-
- private:
- MockTaskRunner* mock_;
- ~TaskRunnerProxy() override {}
-};
-
-class TestMemoryPressureMonitor : public MemoryPressureMonitor {
- public:
- // Expose the callback that is used for scheduled checks.
- using MemoryPressureMonitor::CheckPressureAndUpdateStats;
-
-#if !defined(MEMORY_PRESSURE_IS_POLLING)
- using MemoryPressureMonitor::OnMemoryPressureChanged;
-#endif
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- TestMemoryPressureMonitor(scoped_refptr<base::TaskRunner> task_runner,
- base::TickClock* tick_clock,
- MemoryPressureStatsCollector* stats_collector,
- MemoryPressureCalculator* calculator,
- DispatchCallback dispatch_callback)
- : MemoryPressureMonitor(task_runner,
- tick_clock,
- stats_collector,
- calculator,
- dispatch_callback) {}
-#else // MEMORY_PRESSURE_IS_POLLING
- TestMemoryPressureMonitor(scoped_refptr<base::TaskRunner> task_runner,
- base::TickClock* tick_clock,
- MemoryPressureStatsCollector* stats_collector,
- DispatchCallback dispatch_callback,
- MemoryPressureLevel initial_level)
- : MemoryPressureMonitor(task_runner,
- tick_clock,
- stats_collector,
- dispatch_callback,
- initial_level) {}
-#endif // !MEMORY_PRESSURE_IS_POLLING
-
- // A handful of accessors for unittesting.
- MemoryPressureLevel current_memory_pressure_level() const {
- return current_memory_pressure_level_;
- }
- const std::map<int, base::TimeTicks>& scheduled_checks() const {
- return scheduled_checks_;
- }
- int serial_number() const { return serial_number_; }
-};
-
-// A mock dispatch class.
-class LenientMockDispatch {
- public:
- MOCK_METHOD1(Dispatch, void(MemoryPressureLevel));
-};
-using MockDispatch = testing::StrictMock<LenientMockDispatch>;
-
-class MemoryPressureMonitorTest : public testing::Test {
- public:
- MemoryPressureMonitorTest()
- : task_runner_proxy_(new TaskRunnerProxy(&mock_task_runner_)),
- stats_collector_(&tick_clock_) {}
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- // Creates a monitor in the given initial pressure level and validates its
- // state.
- void CreateMonitor(MemoryPressureLevel initial_level) {
- calculator_.SetLevel(initial_level);
- Tick(1); // Advance the clock so it doesn't return zero.
-
- // Determine the delay with which we expect the task to be posted.
- int delay = MemoryPressureMonitor::kDefaultPollingIntervalMs;
- if (initial_level == MEMORY_PRESSURE_LEVEL_MODERATE)
- delay = MemoryPressureMonitor::kNotificationIntervalPressureModerateMs;
- else if (initial_level == MEMORY_PRESSURE_LEVEL_CRITICAL)
- delay = MemoryPressureMonitor::kNotificationIntervalPressureCriticalMs;
-
- // The monitor will make one call to the task runner during construction.
- ExpectTaskPosted(delay);
- monitor_.reset(new TestMemoryPressureMonitor(
- task_runner_proxy_, &tick_clock_, &stats_collector_, &calculator_,
- base::Bind(&MockDispatch::Dispatch,
- base::Unretained(&mock_dispatch_))));
- VerifyAndClearExpectations();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-
- // The monitor should have made one call immediately to the calculator_.
- EXPECT_EQ(1, calculator_.calls());
- ExpectPressure(initial_level);
- calculator_.ResetCalls();
- }
-#else // MEMORY_PRESSURE_IS_POLLING
- void CreateMonitor(MemoryPressureLevel initial_level) {
- Tick(1); // Advance the clock so it doesn't return zero.
-
- // The monitor will make one call to the task runner during construction.
- ExpectTaskPosted(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- monitor_.reset(new TestMemoryPressureMonitor(
- task_runner_proxy_, &tick_clock_, &stats_collector_,
- base::Bind(&MockDispatch::Dispatch, base::Unretained(&mock_dispatch_)),
- initial_level));
- VerifyAndClearExpectations();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-
- // The monitor should have made one call immediately to the calculator_.
- ExpectPressure(initial_level);
- }
-#endif // !MEMORY_PRESSURE_IS_POLLING
-
- // Advances the tick clock by the given number of milliseconds.
- void Tick(int ms) {
- tick_clock_.Advance(base::TimeDelta::FromMilliseconds(ms));
- }
-
- // Sets expectations for tasks scheduled via |mock_task_runner_|.
- void ExpectTaskPosted(int delay_ms) {
- base::TimeDelta delay = base::TimeDelta::FromMilliseconds(delay_ms);
- EXPECT_CALL(mock_task_runner_, PostDelayedTask(_, delay))
- .WillOnce(testing::Return(true));
- }
-
- // Sets up expectations for calls to |mock_dispatch_|.
- void ExpectDispatch(MemoryPressureLevel level) {
- EXPECT_CALL(mock_dispatch_, Dispatch(level));
- }
- void ExpectDispatchModerate() {
- EXPECT_CALL(mock_dispatch_, Dispatch(MEMORY_PRESSURE_LEVEL_MODERATE));
- }
- void ExpectDispatchCritical() {
- EXPECT_CALL(mock_dispatch_, Dispatch(MEMORY_PRESSURE_LEVEL_CRITICAL));
- }
-
- // Verifies and clears expectations for both |mock_task_runner_| and
- // |mock_dispatch_|.
- void VerifyAndClearExpectations() {
- testing::Mock::VerifyAndClearExpectations(&mock_task_runner_);
- testing::Mock::VerifyAndClearExpectations(&mock_dispatch_);
- }
-
- // Checks expectations on |monitor_->current_memory_pressure_level()|.
- void ExpectPressure(MemoryPressureLevel level) {
- EXPECT_EQ(level, monitor_->current_memory_pressure_level());
- }
- void ExpectNone() {
- EXPECT_EQ(MEMORY_PRESSURE_LEVEL_NONE,
- monitor_->current_memory_pressure_level());
- }
- void ExpectModerate() {
- EXPECT_EQ(MEMORY_PRESSURE_LEVEL_MODERATE,
- monitor_->current_memory_pressure_level());
- }
- void ExpectCritical() {
- EXPECT_EQ(MEMORY_PRESSURE_LEVEL_CRITICAL,
- monitor_->current_memory_pressure_level());
- }
-
- MockTaskRunner mock_task_runner_;
- scoped_refptr<TaskRunnerProxy> task_runner_proxy_;
- base::SimpleTestTickClock tick_clock_;
- MemoryPressureStatsCollector stats_collector_;
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
- TestMemoryPressureCalculator calculator_;
-#endif
-
- MockDispatch mock_dispatch_;
- std::unique_ptr<TestMemoryPressureMonitor> monitor_;
-};
-
-TEST_F(MemoryPressureMonitorTest, NormalScheduling) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- Tick(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- ExpectTaskPosted(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- monitor_->CheckPressureAndUpdateStats(monitor_->serial_number());
- VerifyAndClearExpectations();
-
- Tick(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- ExpectTaskPosted(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- monitor_->CheckPressureAndUpdateStats(monitor_->serial_number());
- VerifyAndClearExpectations();
-}
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-TEST_F(MemoryPressureMonitorTest, CalculatorNotAlwaysInvoked) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // Callback into the monitor too soon and expect nothing to happen.
- Tick(1);
- EXPECT_EQ(MEMORY_PRESSURE_LEVEL_NONE, monitor_->GetCurrentPressureLevel());
- VerifyAndClearExpectations();
- EXPECT_EQ(0, calculator_.calls());
- ExpectNone();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-
- // Pass sufficient time that the rate limiter will allow another calculation.
- // Don't expect another scheduled call because there's already one pending.
- Tick(MemoryPressureMonitor::kMinimumTimeBetweenSamplesMs);
- EXPECT_EQ(MEMORY_PRESSURE_LEVEL_NONE, monitor_->GetCurrentPressureLevel());
- VerifyAndClearExpectations();
- EXPECT_EQ(1, calculator_.calls());
- ExpectNone();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-}
-
-TEST_F(MemoryPressureMonitorTest, NoPressureScheduling) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // Step forward by a polling interval. This should cause another scheduled
- // check to be posted.
- Tick(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- ExpectTaskPosted(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- monitor_->CheckPressureAndUpdateStats(monitor_->serial_number());
- VerifyAndClearExpectations();
- ExpectNone();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-}
-
-TEST_F(MemoryPressureMonitorTest, NoPressureToModerateViaScheduling) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // Step forward by a polling interval. This should cause another scheduled
- // check to be posted.
- calculator_.SetModerate();
- Tick(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- ExpectTaskPosted(
- MemoryPressureMonitor::kNotificationIntervalPressureModerateMs);
- ExpectDispatchModerate();
- monitor_->CheckPressureAndUpdateStats(monitor_->serial_number());
- VerifyAndClearExpectations();
- ExpectModerate();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-}
-
-TEST_F(MemoryPressureMonitorTest, NoPressureToCriticalViaScheduling) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // Step forward by a polling interval. This should cause another scheduled
- // check to be posted.
- calculator_.SetCritical();
- Tick(MemoryPressureMonitor::kDefaultPollingIntervalMs);
- ExpectTaskPosted(
- MemoryPressureMonitor::kNotificationIntervalPressureCriticalMs);
- ExpectDispatchCritical();
- monitor_->CheckPressureAndUpdateStats(monitor_->serial_number());
- VerifyAndClearExpectations();
- ExpectCritical();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-}
-
-TEST_F(MemoryPressureMonitorTest, ModeratePressureToCriticalViaScheduling) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_MODERATE);
-
- // Step forward by a polling interval. This should cause another scheduled
- // check to be posted.
- calculator_.SetCritical();
- Tick(MemoryPressureMonitor::kNotificationIntervalPressureModerateMs);
- ExpectTaskPosted(
- MemoryPressureMonitor::kNotificationIntervalPressureCriticalMs);
- ExpectDispatchCritical();
- monitor_->CheckPressureAndUpdateStats(monitor_->serial_number());
- VerifyAndClearExpectations();
- ExpectCritical();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-}
-
-TEST_F(MemoryPressureMonitorTest, UnscheduledStateChange) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // Callback into the monitor directly. This will change the memory pressure
- // and cause a new call to be scheduled as the higher memory pressure has a
- // higher renotification frequency.
- // NOTE: This test relies implicitly on the following facts:
- // kMinimumTimeBetweenSamplesMs < kDefaultPollingIntervalMs / 2
- // kNotificationIntervalPressureCriticalMs < kDefaultPollingIntervalMs / 2
- calculator_.SetCritical();
- Tick(MemoryPressureMonitor::kDefaultPollingIntervalMs / 2);
- ExpectTaskPosted(
- MemoryPressureMonitor::kNotificationIntervalPressureCriticalMs);
- ExpectDispatchCritical();
- EXPECT_EQ(MEMORY_PRESSURE_LEVEL_CRITICAL,
- monitor_->GetCurrentPressureLevel());
- VerifyAndClearExpectations();
- EXPECT_EQ(1, calculator_.calls());
- ExpectCritical();
- EXPECT_EQ(2u, monitor_->scheduled_checks().size());
-}
-
-#else // MEMORY_PRESSURE_IS_POLLING
-
-TEST_F(MemoryPressureMonitorTest, PressureChangeNop) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // The pressure hasn't changed so this should be a nop.
- Tick(1);
- monitor_->OnMemoryPressureChanged(MEMORY_PRESSURE_LEVEL_NONE);
- VerifyAndClearExpectations();
- ExpectNone();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-}
-
-TEST_F(MemoryPressureMonitorTest, PressureChangeNoNewScheduledTask) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // The pressure is increasing and the renotification frequency has changed.
- // However, a pending event is already scheduled soon enough so no new one
- // should be scheduled.
- Tick(MemoryPressureMonitor::kDefaultPollingIntervalMs -
- MemoryPressureMonitor::kNotificationIntervalPressureModerateMs / 2);
- ExpectDispatchModerate();
- monitor_->OnMemoryPressureChanged(MEMORY_PRESSURE_LEVEL_MODERATE);
- VerifyAndClearExpectations();
- ExpectModerate();
- EXPECT_EQ(1u, monitor_->scheduled_checks().size());
-}
-
-TEST_F(MemoryPressureMonitorTest, PressureChangeNewScheduledTask) {
- CreateMonitor(MEMORY_PRESSURE_LEVEL_NONE);
-
- // The pressure is increasing and the renotification frequency has changed.
- // The already scheduled event is too far in the future so a new event should
- // be scheduled.
- Tick(1);
- ExpectTaskPosted(
- MemoryPressureMonitor::kNotificationIntervalPressureCriticalMs);
- ExpectDispatchCritical();
- monitor_->OnMemoryPressureChanged(MEMORY_PRESSURE_LEVEL_CRITICAL);
- VerifyAndClearExpectations();
- ExpectCritical();
- EXPECT_EQ(2u, monitor_->scheduled_checks().size());
-}
-
-#endif // !MEMORY_PRESSURE_IS_POLLING
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/memory_pressure_stats_collector.cc b/chromium/components/memory_pressure/memory_pressure_stats_collector.cc
deleted file mode 100644
index b4ff482bd4e..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_stats_collector.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2015 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/memory_pressure/memory_pressure_stats_collector.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/time/tick_clock.h"
-
-namespace memory_pressure {
-
-namespace {
-
-using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
-
-// Converts a memory pressure level to an UMA enumeration value.
-MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue(
- MemoryPressureLevel level) {
- switch (level) {
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
- return UMA_MEMORY_PRESSURE_LEVEL_NONE;
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
- return UMA_MEMORY_PRESSURE_LEVEL_MODERATE;
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
- return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL;
- }
- NOTREACHED();
- return UMA_MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-// Converts an UMA enumeration value to a memory pressure level.
-MemoryPressureLevel MemoryPressureLevelFromUmaEnumValue(
- MemoryPressureLevelUMA level) {
- switch (level) {
- case UMA_MEMORY_PRESSURE_LEVEL_NONE:
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
- case UMA_MEMORY_PRESSURE_LEVEL_MODERATE:
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
- case UMA_MEMORY_PRESSURE_LEVEL_CRITICAL:
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
- case UMA_MEMORY_PRESSURE_LEVEL_COUNT:
- NOTREACHED();
- break;
- }
- NOTREACHED();
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-} // namespace
-
-MemoryPressureStatsCollector::MemoryPressureStatsCollector(
- base::TickClock* tick_clock)
- : tick_clock_(tick_clock),
- last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
-}
-
-void MemoryPressureStatsCollector::UpdateStatistics(
- MemoryPressureLevel current_pressure_level) {
- base::TimeTicks now = tick_clock_->NowTicks();
-
- // Special case: first call to the collector. Observations have just started
- // so there's nothing to report.
- if (last_update_time_.is_null()) {
- last_pressure_level_ = current_pressure_level;
- last_update_time_ = now;
- return;
- }
-
- // If the pressure level has transitioned then report this.
- if (last_pressure_level_ != current_pressure_level)
- ReportLevelChange(last_pressure_level_, current_pressure_level);
-
- // Increment the appropriate cumulative bucket.
- int index = MemoryPressureLevelToUmaEnumValue(current_pressure_level);
- unreported_cumulative_time_[index] += now - last_update_time_;
-
- // Update last pressure related state.
- last_pressure_level_ = current_pressure_level;
- last_update_time_ = now;
-
- // Make reports about the amount of time spent cumulatively at each level.
- for (size_t i = 0; i < arraysize(unreported_cumulative_time_); ++i) {
- // Report the largest number of whole seconds possible at this moment and
- // carry around the rest for a future report.
- if (unreported_cumulative_time_[i].is_zero())
- continue;
- int64_t seconds = unreported_cumulative_time_[i].InSeconds();
- if (seconds == 0)
- continue;
- unreported_cumulative_time_[i] -= base::TimeDelta::FromSeconds(seconds);
-
- ReportCumulativeTime(MemoryPressureLevelFromUmaEnumValue(
- static_cast<MemoryPressureLevelUMA>(i)),
- static_cast<int>(seconds));
- }
-}
-
-// static
-void MemoryPressureStatsCollector::ReportCumulativeTime(
- MemoryPressureLevel pressure_level,
- int seconds) {
- // Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the
- // simple UMA_HISTOGRAM macros don't expose 'AddCount' functionality.
- STATIC_HISTOGRAM_POINTER_BLOCK(
- "Memory.PressureLevel",
- AddCount(MemoryPressureLevelToUmaEnumValue(pressure_level), seconds),
- base::LinearHistogram::FactoryGet(
- "Memory.PressureLevel", 1, UMA_MEMORY_PRESSURE_LEVEL_COUNT,
- UMA_MEMORY_PRESSURE_LEVEL_COUNT + 1,
- base::HistogramBase::kUmaTargetedHistogramFlag));
-}
-
-// static
-void MemoryPressureStatsCollector::ReportLevelChange(
- MemoryPressureLevel old_pressure_level,
- MemoryPressureLevel new_pressure_level) {
- // TODO(chrisha): Report Memory.PressureLevelChange when this code is in use.
-}
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/memory_pressure_stats_collector.h b/chromium/components/memory_pressure/memory_pressure_stats_collector.h
deleted file mode 100644
index 2b84bc4da14..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_stats_collector.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2015 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_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_
-#define COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_
-
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "components/memory_pressure/memory_pressure_listener.h"
-
-namespace base {
-class TickClock;
-}
-
-namespace memory_pressure {
-
-// Enumeration of UMA memory pressure levels. The pressure level enum defined in
-// MemoryPressureListener is non-contiguous. This enum is a contiguous version
-// of that for use with UMA. Both it and histograms.xml must be kept in sync
-// with the MemoryPressureListener enum. Included in the header so that
-// UMA_MEMORY_PRESSURE_LEVEL_COUNT is available.
-enum MemoryPressureLevelUMA {
- UMA_MEMORY_PRESSURE_LEVEL_NONE = 0,
- UMA_MEMORY_PRESSURE_LEVEL_MODERATE = 1,
- UMA_MEMORY_PRESSURE_LEVEL_CRITICAL = 2,
- // This must be the last value in the enum.
- UMA_MEMORY_PRESSURE_LEVEL_COUNT,
-};
-
-// Enumeration of UMA pressure level changes. This needs to be kept in sync
-// with histograms.xml and the memory pressure levels defined in
-// MemoryPressureListener. Exposed for unittesting.
-enum MemoryPressureLevelChangeUMA {
- UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE = 0,
- UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL = 1,
- UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL = 2,
- UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE = 3,
- UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_NONE = 4,
- UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE = 5,
- // This must be the last value in the enum.
- UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT
-};
-
-// Class that is responsible for collecting and eventually reporting memory
-// pressure statistics. Contributes to the "Memory.PressureLevel" and
-// "Memory.PressureLevelChanges" histograms.
-//
-// On platforms with a polling memory pressure implementation the
-// UpdateStatistics function will be invoked every time the pressure is polled.
-// On non-polling platforms (Mac, Android) it will be invoked on a periodic
-// timer, and at the moment of pressure level changes.
-class MemoryPressureStatsCollector {
- public:
- using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel;
-
- // The provided |tick_clock| must outlive this class.
- MemoryPressureStatsCollector(base::TickClock* tick_clock);
-
- // This is to be called periodically to ensure that up to date statistics
- // have been reported.
- void UpdateStatistics(MemoryPressureLevel current_pressure_level);
-
- private:
- friend class TestMemoryPressureStatsCollector;
-
- // Helper functions for delivering collected statistics.
- static void ReportCumulativeTime(MemoryPressureLevel pressure_level,
- int seconds);
- static void ReportLevelChange(MemoryPressureLevel old_pressure_level,
- MemoryPressureLevel new_pressure_level);
-
- // The tick clock in use. This class is intended to be owned by a class with
- // a tick clock, and ownership remains there. Also intended as a test seam.
- base::TickClock* tick_clock_;
-
- // Buckets of time that have been spent in different pressure levels, but
- // not yet reported. At every call to UpdateStatistics these buckets will be
- // drained of as many 'full' seconds of time as possible and reported via
- // UMA. The remaining time (< 1000 ms) will be left in the bucket to be rolled
- // into a later UMA report.
- base::TimeDelta unreported_cumulative_time_[UMA_MEMORY_PRESSURE_LEVEL_COUNT];
-
- // The last observed pressure level and the time at which it was observed, and
- // the time when this pressure level started.
- MemoryPressureLevel last_pressure_level_;
- base::TimeTicks last_update_time_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureStatsCollector);
-};
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_
diff --git a/chromium/components/memory_pressure/memory_pressure_stats_collector_unittest.cc b/chromium/components/memory_pressure/memory_pressure_stats_collector_unittest.cc
deleted file mode 100644
index cc7788bac38..00000000000
--- a/chromium/components/memory_pressure/memory_pressure_stats_collector_unittest.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2015 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/memory_pressure/memory_pressure_stats_collector.h"
-
-#include "base/test/histogram_tester.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace memory_pressure {
-
-namespace {
-
-// Histogram names.
-const char kPressureLevel[] = "Memory.PressureLevel";
-
-} // namespace
-
-// Test version of the stats collector with a few extra accessors.
-class TestMemoryPressureStatsCollector : public MemoryPressureStatsCollector {
- public:
- TestMemoryPressureStatsCollector(base::TickClock* tick_clock)
- : MemoryPressureStatsCollector(tick_clock) {}
-
- // Accessors.
- base::TimeDelta unreported_cumulative_time(int i) const {
- return unreported_cumulative_time_[i];
- }
- MemoryPressureLevel last_pressure_level() const {
- return last_pressure_level_;
- }
- base::TimeTicks last_update_time() const { return last_update_time_; }
-};
-
-// Test fixture.
-class MemoryPressureStatsCollectorTest : public testing::Test {
- public:
- MemoryPressureStatsCollectorTest() : collector_(&tick_clock_) {}
-
- void Tick(int ms) {
- tick_clock_.Advance(base::TimeDelta::FromMilliseconds(ms));
- }
-
- // Validates expectations on the amount of accumulated (and unreported)
- // time (milliseconds) per pressure level.
- void ExpectAccumulated(int none_ms, int moderate_ms, int critical_ms) {
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(none_ms),
- collector_.unreported_cumulative_time(0)); // None.
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(moderate_ms),
- collector_.unreported_cumulative_time(1)); // Moderate.
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(critical_ms),
- collector_.unreported_cumulative_time(2)); // Critical.
- }
-
- // Validates expectations on the amount of reported time (seconds) per
- // pressure level.
- void ExpectReported(int none_s, int moderate_s, int critical_s) {
- int total_s = none_s + moderate_s + critical_s;
-
- // If the histogram should be empty then simply confirm that it doesn't
- // yet exist.
- if (total_s == 0) {
- EXPECT_TRUE(histograms_.GetTotalCountsForPrefix(kPressureLevel).empty());
- return;
- }
-
- histograms_.ExpectBucketCount(kPressureLevel, 0, none_s); // None.
- histograms_.ExpectBucketCount(kPressureLevel, 1, moderate_s); // Moderate.
- histograms_.ExpectBucketCount(kPressureLevel, 2, critical_s); // Critical.
- histograms_.ExpectTotalCount(kPressureLevel, total_s);
- }
-
- base::SimpleTestTickClock tick_clock_;
- TestMemoryPressureStatsCollector collector_;
- base::HistogramTester histograms_;
-};
-
-TEST_F(MemoryPressureStatsCollectorTest, EndToEnd) {
- // Upon construction no statistics should yet have been reported.
- ExpectAccumulated(0, 0, 0);
- ExpectReported(0, 0, 0);
-
- // A first call should not invoke any reporting functions, but it should
- // modify member variables.
- Tick(500);
- collector_.UpdateStatistics(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- collector_.last_pressure_level());
- EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
- ExpectAccumulated(0, 0, 0);
- ExpectReported(0, 0, 0);
-
- // A subsequent call with the same pressure level should increment the
- // cumulative time but not make a report, as less than one second of time
- // has been accumulated.
- Tick(500);
- collector_.UpdateStatistics(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- collector_.last_pressure_level());
- EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
- ExpectAccumulated(500, 0, 0);
- ExpectReported(0, 0, 0);
-
- // Yet another call and this time a report should be made, as one second
- // of time has been accumulated. 500ms should remain unreported.
- Tick(1000);
- collector_.UpdateStatistics(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- collector_.last_pressure_level());
- EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
- ExpectAccumulated(500, 0, 0);
- ExpectReported(1, 0, 0);
-
- // A subsequent call with a different pressure level should increment the
- // cumulative time and make several reports.
- Tick(2250);
- collector_.UpdateStatistics(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
- EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- collector_.last_pressure_level());
- EXPECT_EQ(tick_clock_.NowTicks(), collector_.last_update_time());
- ExpectAccumulated(500, 250, 0);
- ExpectReported(1, 2, 0);
-}
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/test_memory_pressure_calculator.cc b/chromium/components/memory_pressure/test_memory_pressure_calculator.cc
deleted file mode 100644
index a9d6d5543d7..00000000000
--- a/chromium/components/memory_pressure/test_memory_pressure_calculator.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 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/memory_pressure/test_memory_pressure_calculator.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-TestMemoryPressureCalculator::TestMemoryPressureCalculator()
- : level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE), calls_(0) {}
-
-TestMemoryPressureCalculator::TestMemoryPressureCalculator(
- MemoryPressureLevel level)
- : level_(level), calls_(0) {}
-
-TestMemoryPressureCalculator::MemoryPressureLevel
-TestMemoryPressureCalculator::CalculateCurrentPressureLevel() {
- ++calls_;
- return level_;
-}
-
-void TestMemoryPressureCalculator::SetLevel(MemoryPressureLevel level) {
- level_ = level;
-}
-
-void TestMemoryPressureCalculator::SetNone() {
- level_ = MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-void TestMemoryPressureCalculator::SetModerate() {
- level_ = MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
-}
-
-void TestMemoryPressureCalculator::SetCritical() {
- level_ = MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
-}
-
-void TestMemoryPressureCalculator::ResetCalls() {
- calls_ = 0;
-}
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
diff --git a/chromium/components/memory_pressure/test_memory_pressure_calculator.h b/chromium/components/memory_pressure/test_memory_pressure_calculator.h
deleted file mode 100644
index 4eae886d493..00000000000
--- a/chromium/components/memory_pressure/test_memory_pressure_calculator.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2015 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_MEMORY_PRESSURE_TEST_MEMORY_PRESSURE_CALCULATOR_H_
-#define COMPONENTS_MEMORY_PRESSURE_TEST_MEMORY_PRESSURE_CALCULATOR_H_
-
-#include "base/macros.h"
-#include "components/memory_pressure/memory_pressure_calculator.h"
-
-namespace memory_pressure {
-
-#if defined(MEMORY_PRESSURE_IS_POLLING)
-
-// A mock memory pressure calculator for unittesting.
-class TestMemoryPressureCalculator : public MemoryPressureCalculator {
- public:
- // Defaults to no pressure.
- TestMemoryPressureCalculator();
- explicit TestMemoryPressureCalculator(MemoryPressureLevel level);
- ~TestMemoryPressureCalculator() override {}
-
- // MemoryPressureCalculator implementation.
- MemoryPressureLevel CalculateCurrentPressureLevel() override;
-
- // Sets the mock calculator to return the given pressure level.
- void SetLevel(MemoryPressureLevel level);
-
- // Sets the mock calculator to return no pressure.
- void SetNone();
-
- // Sets the mock calculator to return moderate pressure.
- void SetModerate();
-
- // Sets the mock calculator to return critical pressure.
- void SetCritical();
-
- // Resets the call counter to 'CalculateCurrentPressureLevel'.
- void ResetCalls();
-
- // Returns the number of calls to 'CalculateCurrentPressureLevel'.
- int calls() const { return calls_; }
-
- private:
- MemoryPressureLevel level_;
- int calls_;
-
- DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureCalculator);
-};
-
-#endif // defined(MEMORY_PRESSURE_IS_POLLING)
-
-} // namespace memory_pressure
-
-#endif // COMPONENTS_MEMORY_PRESSURE_TEST_MEMORY_PRESSURE_CALCULATOR_H_
diff --git a/chromium/components/metrics/BUILD.gn b/chromium/components/metrics/BUILD.gn
index 3852c12e5dd..1d03801d2c9 100644
--- a/chromium/components/metrics/BUILD.gn
+++ b/chromium/components/metrics/BUILD.gn
@@ -93,15 +93,14 @@ static_library("metrics") {
public_deps = [
"//components/metrics/proto",
]
+
deps = [
":call_stack_profile_params",
"//base",
"//base:base_static",
- "//components/browser_watcher:stability",
- "//components/browser_watcher:stability_data",
"//components/prefs",
"//components/variations",
- "//third_party/zlib:compression_utils",
+ "//third_party/zlib/google:compression_utils",
]
if (is_chromeos) {
@@ -120,6 +119,7 @@ static_library("metrics") {
if (is_win) {
sources -= [ "machine_id_provider_stub.cc" ]
+ deps += [ "//components/browser_watcher:stability_client" ]
}
}
@@ -248,6 +248,25 @@ if (!is_ios) {
}
}
+static_library("single_sample_metrics") {
+ sources = [
+ "single_sample_metrics.cc",
+ "single_sample_metrics.h",
+ "single_sample_metrics_factory_impl.cc",
+ "single_sample_metrics_factory_impl.h",
+ ]
+
+ deps = [
+ "//mojo/public/cpp/bindings",
+ "//services/service_manager/public/cpp",
+ "//services/service_manager/public/interfaces",
+ ]
+
+ public_deps = [
+ "//components/metrics/public/interfaces:single_sample_metrics_mojo_bindings",
+ ]
+}
+
source_set("call_stack_profile_params") {
sources = [
"call_stack_profile_params.cc",
@@ -335,6 +354,7 @@ source_set("unit_tests") {
"persisted_logs_unittest.cc",
"profiler/profiler_metrics_provider_unittest.cc",
"profiler/tracking_synchronizer_unittest.cc",
+ "single_sample_metrics_factory_impl_unittest.cc",
"stability_metrics_helper_unittest.cc",
"stability_metrics_provider_unittest.cc",
"ui/screen_info_metrics_provider_unittest.cc",
@@ -346,6 +366,7 @@ source_set("unit_tests") {
":metrics",
":net",
":profiler",
+ ":single_sample_metrics",
":test_support",
":ui",
"//base/test:test_support",
@@ -354,9 +375,9 @@ source_set("unit_tests") {
"//components/variations",
"//mojo/public/cpp/bindings",
"//net:test_support",
- "//services/service_manager/public/cpp:sources",
+ "//services/service_manager/public/cpp",
"//testing/gtest",
- "//third_party/zlib:compression_utils",
+ "//third_party/zlib/google:compression_utils",
"//ui/gfx/geometry",
]
diff --git a/chromium/components/metrics/call_stack_profile_collector.cc b/chromium/components/metrics/call_stack_profile_collector.cc
index 71f45df0790..4cdd9ec8348 100644
--- a/chromium/components/metrics/call_stack_profile_collector.cc
+++ b/chromium/components/metrics/call_stack_profile_collector.cc
@@ -22,6 +22,7 @@ CallStackProfileCollector::~CallStackProfileCollector() {}
// static
void CallStackProfileCollector::Create(
CallStackProfileParams::Process expected_process,
+ const service_manager::BindSourceInfo& source_info,
mojom::CallStackProfileCollectorRequest request) {
mojo::MakeStrongBinding(
base::MakeUnique<CallStackProfileCollector>(expected_process),
diff --git a/chromium/components/metrics/call_stack_profile_collector.h b/chromium/components/metrics/call_stack_profile_collector.h
index 6eeb6a87b44..80f391742be 100644
--- a/chromium/components/metrics/call_stack_profile_collector.h
+++ b/chromium/components/metrics/call_stack_profile_collector.h
@@ -8,6 +8,10 @@
#include "base/macros.h"
#include "components/metrics/public/interfaces/call_stack_profile_collector.mojom.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace metrics {
class CallStackProfileCollector : public mojom::CallStackProfileCollector {
@@ -20,6 +24,7 @@ class CallStackProfileCollector : public mojom::CallStackProfileCollector {
// Create a collector to receive profiles from |expected_process|.
static void Create(CallStackProfileParams::Process expected_process,
+ const service_manager::BindSourceInfo& source_info,
mojom::CallStackProfileCollectorRequest request);
// mojom::CallStackProfileCollector:
diff --git a/chromium/components/metrics/execution_phase.cc b/chromium/components/metrics/execution_phase.cc
index c37f05c594f..992ef820e77 100644
--- a/chromium/components/metrics/execution_phase.cc
+++ b/chromium/components/metrics/execution_phase.cc
@@ -4,12 +4,16 @@
#include "components/metrics/execution_phase.h"
-#include "components/browser_watcher/stability_data_names.h"
-#include "components/browser_watcher/stability_debugging.h"
+#include "build/build_config.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
+#if defined(OS_WIN)
+#include "components/browser_watcher/stability_data_names.h"
+#include "components/browser_watcher/stability_debugging.h"
+#endif // defined(OS_WIN)
+
namespace metrics {
ExecutionPhaseManager::ExecutionPhaseManager(PrefService* local_state)
@@ -34,9 +38,11 @@ void ExecutionPhaseManager::SetExecutionPhase(ExecutionPhase execution_phase) {
execution_phase_ = execution_phase;
local_state_->SetInteger(prefs::kStabilityExecutionPhase,
static_cast<int>(execution_phase_));
+#if defined(OS_WIN)
browser_watcher::SetStabilityDataInt(
browser_watcher::kStabilityExecutionPhase,
static_cast<int>(execution_phase_));
+#endif // defined(OS_WIN)
}
ExecutionPhase ExecutionPhaseManager::GetExecutionPhase() {
diff --git a/chromium/components/metrics/histogram_encoder.cc b/chromium/components/metrics/histogram_encoder.cc
index 61f1d4a86b6..4d7d9453141 100644
--- a/chromium/components/metrics/histogram_encoder.cc
+++ b/chromium/components/metrics/histogram_encoder.cc
@@ -31,7 +31,7 @@ void EncodeHistogramDelta(const std::string& histogram_name,
for (std::unique_ptr<SampleCountIterator> it = snapshot.Iterator();
!it->Done(); it->Next()) {
base::Histogram::Sample min;
- base::Histogram::Sample max;
+ int64_t max;
base::Histogram::Count count;
it->Get(&min, &max, &count);
HistogramEventProto::Bucket* bucket = histogram_proto->add_bucket();
diff --git a/chromium/components/metrics/leak_detector/OWNERS b/chromium/components/metrics/leak_detector/OWNERS
index cde5a71325c..36706c0586a 100644
--- a/chromium/components/metrics/leak_detector/OWNERS
+++ b/chromium/components/metrics/leak_detector/OWNERS
@@ -5,3 +5,5 @@ wfh@chromium.org
# introducing new sandbox escapes.
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# COMPONENT: Internals>Metrics
diff --git a/chromium/components/metrics/metrics_log.cc b/chromium/components/metrics/metrics_log.cc
index 42331e3f15b..ac35ce396a3 100644
--- a/chromium/components/metrics/metrics_log.cc
+++ b/chromium/components/metrics/metrics_log.cc
@@ -151,7 +151,12 @@ void MetricsLog::RecordCoreSystemProfile(MetricsServiceClient* client,
metrics::SystemProfileProto::Hardware* hardware =
system_profile->mutable_hardware();
+#if !defined(OS_IOS)
+ // On iOS, OperatingSystemArchitecture() returns values like iPad4,4 which is
+ // not the actual CPU architecture. Don't set it until the API is fixed. See
+ // crbug.com/370104 for details.
hardware->set_cpu_architecture(base::SysInfo::OperatingSystemArchitecture());
+#endif
hardware->set_system_ram_mb(base::SysInfo::AmountOfPhysicalMemoryMB());
hardware->set_hardware_class(base::SysInfo::HardwareModelName());
#if defined(OS_WIN)
diff --git a/chromium/components/metrics/metrics_log_unittest.cc b/chromium/components/metrics/metrics_log_unittest.cc
index 63152c68ea9..f1a7792f85d 100644
--- a/chromium/components/metrics/metrics_log_unittest.cc
+++ b/chromium/components/metrics/metrics_log_unittest.cc
@@ -196,7 +196,9 @@ TEST_F(MetricsLogTest, BasicRecord) {
#endif
metrics::SystemProfileProto::Hardware* hardware =
system_profile->mutable_hardware();
+#if !defined(OS_IOS)
hardware->set_cpu_architecture(base::SysInfo::OperatingSystemArchitecture());
+#endif
hardware->set_system_ram_mb(base::SysInfo::AmountOfPhysicalMemoryMB());
hardware->set_hardware_class(base::SysInfo::HardwareModelName());
#if defined(OS_WIN)
diff --git a/chromium/components/metrics/metrics_service.h b/chromium/components/metrics/metrics_service.h
index 12c86aa1fba..f1e6349eb2e 100644
--- a/chromium/components/metrics/metrics_service.h
+++ b/chromium/components/metrics/metrics_service.h
@@ -23,6 +23,7 @@
#include "base/metrics/histogram_snapshot_manager.h"
#include "base/metrics/user_metrics.h"
#include "base/observer_list.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "build/build_config.h"
diff --git a/chromium/components/metrics/metrics_state_manager.h b/chromium/components/metrics/metrics_state_manager.h
index ca60fd41930..99c0f628d66 100644
--- a/chromium/components/metrics/metrics_state_manager.h
+++ b/chromium/components/metrics/metrics_state_manager.h
@@ -12,6 +12,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
+#include "base/single_thread_task_runner.h"
#include "components/metrics/client_info.h"
class PrefService;
diff --git a/chromium/components/metrics/net/network_metrics_provider.h b/chromium/components/metrics/net/network_metrics_provider.h
index 1c23bea907e..afa488f6393 100644
--- a/chromium/components/metrics/net/network_metrics_provider.h
+++ b/chromium/components/metrics/net/network_metrics_provider.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_base.h"
+#include "base/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "components/metrics/metrics_provider.h"
#include "components/metrics/net/wifi_access_point_info_provider.h"
diff --git a/chromium/components/metrics/proto/translate_event.proto b/chromium/components/metrics/proto/translate_event.proto
index ad19742cfd4..fb9717372c8 100644
--- a/chromium/components/metrics/proto/translate_event.proto
+++ b/chromium/components/metrics/proto/translate_event.proto
@@ -16,7 +16,7 @@ package metrics;
// the Translate UI. Contains features used by Translate Ranker for
// inference, information about the ranker model and its decision, as
// well as user or automated feedback from the Translate UI.
-// Next tag: 15
+// Next tag: 16
message TranslateEventProto {
// Language strings are two or three letter codes, with sometimes an extra
// suffix (for e.g. chinese zh-TW or zh-CN). See
@@ -139,6 +139,10 @@ message TranslateEventProto {
// Event received from translate UI.
optional EventType event_type = 10;
+ // Decisions that have been overriden by translate ranker (e.g.
+ // LANGUAGE_DISABLED_BY_AUTO_BLACKLIST).
+ repeated EventType decision_overrides = 15;
+
// The timestamp for the event, in seconds.
// This value comes from Chromium's TimeTicks::Now(), which is an abstract
// time value that is guaranteed to always be increasing (regardless of
diff --git a/chromium/components/metrics/proto/ukm/entry.proto b/chromium/components/metrics/proto/ukm/entry.proto
index 22385c89bd0..b046c739290 100644
--- a/chromium/components/metrics/proto/ukm/entry.proto
+++ b/chromium/components/metrics/proto/ukm/entry.proto
@@ -20,7 +20,7 @@ message Entry {
optional int32 parent_id = 2;
// The id of the Source this Event is associated with.
- optional int32 source_id = 3;
+ optional int64 source_id = 3;
// Type of the Event. This is a hash of the name (as a string).
optional fixed64 event_hash = 4;
diff --git a/chromium/components/metrics/proto/ukm/source.proto b/chromium/components/metrics/proto/ukm/source.proto
index 2fe543e789c..d4a00605a98 100644
--- a/chromium/components/metrics/proto/ukm/source.proto
+++ b/chromium/components/metrics/proto/ukm/source.proto
@@ -12,7 +12,7 @@ option optimize_for = LITE_RUNTIME;
// Next tag: 7
message Source {
// An identifier for the source. This should be unique within a session.
- optional int32 id = 1;
+ optional int64 id = 1;
// The URL of the source, as recorded in history. If this URL has not been
// discovered by Google's crawler, it should not be recorded.
diff --git a/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc b/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
index c7c99c982cf..b6802d3e0ac 100644
--- a/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
+++ b/chromium/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
@@ -40,45 +40,45 @@ class CallStackProfileCollectorTestImpl
// CallStackProfileCollectorTest:
void BounceFrame(const base::StackSamplingProfiler::Frame& in,
- const BounceFrameCallback& callback) override {
- callback.Run(in);
+ BounceFrameCallback callback) override {
+ std::move(callback).Run(in);
}
void BounceModule(const base::StackSamplingProfiler::Module& in,
- const BounceModuleCallback& callback) override {
- callback.Run(in);
+ BounceModuleCallback callback) override {
+ std::move(callback).Run(in);
}
void BounceProfile(base::StackSamplingProfiler::CallStackProfile in,
- const BounceProfileCallback& callback) override {
- callback.Run(std::move(in));
+ BounceProfileCallback callback) override {
+ std::move(callback).Run(std::move(in));
}
void BounceTrigger(CallStackProfileParams::Trigger in,
- const BounceTriggerCallback& callback) override {
- callback.Run(in);
+ BounceTriggerCallback callback) override {
+ std::move(callback).Run(in);
}
void BounceProcess(CallStackProfileParams::Process in,
- const BounceProcessCallback& callback) override {
- callback.Run(in);
+ BounceProcessCallback callback) override {
+ std::move(callback).Run(in);
}
void BounceThread(CallStackProfileParams::Thread in,
- const BounceThreadCallback& callback) override {
- callback.Run(in);
+ BounceThreadCallback callback) override {
+ std::move(callback).Run(in);
}
void BounceSampleOrderingSpec(
CallStackProfileParams::SampleOrderingSpec in,
- const BounceSampleOrderingSpecCallback& callback) override {
- callback.Run(in);
+ BounceSampleOrderingSpecCallback callback) override {
+ std::move(callback).Run(in);
}
void BounceCallStackProfileParams(
const CallStackProfileParams& in,
- const BounceCallStackProfileParamsCallback& callback) override {
- callback.Run(in);
+ BounceCallStackProfileParamsCallback callback) override {
+ std::move(callback).Run(in);
}
private:
diff --git a/chromium/components/metrics/public/interfaces/BUILD.gn b/chromium/components/metrics/public/interfaces/BUILD.gn
index c6db51a6cf5..cfe96615855 100644
--- a/chromium/components/metrics/public/interfaces/BUILD.gn
+++ b/chromium/components/metrics/public/interfaces/BUILD.gn
@@ -24,3 +24,9 @@ mojom("call_stack_mojo_test_bindings") {
"//mojo/common:common_custom_types",
]
}
+
+mojom("single_sample_metrics_mojo_bindings") {
+ sources = [
+ "single_sample_metrics.mojom",
+ ]
+}
diff --git a/chromium/components/metrics/public/interfaces/single_sample_metrics.mojom b/chromium/components/metrics/public/interfaces/single_sample_metrics.mojom
new file mode 100644
index 00000000000..788150c0188
--- /dev/null
+++ b/chromium/components/metrics/public/interfaces/single_sample_metrics.mojom
@@ -0,0 +1,24 @@
+// Copyright 2017 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.
+
+module metrics.mojom;
+
+// See components/metrics/single_sample_metrics_factory_impl.h for details.
+interface SingleSampleMetricsProvider {
+ // Returns a SingleSampleMetric.
+ //
+ // A single sample metric only reports its sample once at destruction time.
+ // The sample may be changed prior to destruction using the SetSample() method
+ // as many times as desired.
+ //
+ // See base/metrics/histograms.h for parameter definitions. |request| is the
+ // returned histogram.
+ AcquireSingleSampleMetric(string histogram_name, int32 min, int32 max,
+ uint32 bucket_count, int32 flags,
+ SingleSampleMetric& request);
+};
+
+interface SingleSampleMetric {
+ SetSample(int32 sample);
+};
diff --git a/chromium/components/metrics/single_sample_metrics.cc b/chromium/components/metrics/single_sample_metrics.cc
new file mode 100644
index 00000000000..0472dc8aa5f
--- /dev/null
+++ b/chromium/components/metrics/single_sample_metrics.cc
@@ -0,0 +1,86 @@
+// Copyright 2017 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/metrics/single_sample_metrics.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "base/metrics/single_sample_metrics.h"
+#include "base/threading/thread_checker.h"
+#include "components/metrics/single_sample_metrics_factory_impl.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace metrics {
+
+namespace {
+
+class MojoSingleSampleMetric : public mojom::SingleSampleMetric {
+ public:
+ MojoSingleSampleMetric(const std::string& histogram_name,
+ base::HistogramBase::Sample min,
+ base::HistogramBase::Sample max,
+ uint32_t bucket_count,
+ int32_t flags)
+ : metric_(histogram_name, min, max, bucket_count, flags) {}
+ ~MojoSingleSampleMetric() override {}
+
+ private:
+ // mojom::SingleSampleMetric:
+ void SetSample(base::HistogramBase::Sample sample) override {
+ metric_.SetSample(sample);
+ }
+
+ base::DefaultSingleSampleMetric metric_;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoSingleSampleMetric);
+};
+
+class MojoSingleSampleMetricsProvider
+ : public mojom::SingleSampleMetricsProvider {
+ public:
+ MojoSingleSampleMetricsProvider() {}
+ ~MojoSingleSampleMetricsProvider() override {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ }
+
+ private:
+ // mojom::SingleSampleMetricsProvider:
+ void AcquireSingleSampleMetric(
+ const std::string& histogram_name,
+ base::HistogramBase::Sample min,
+ base::HistogramBase::Sample max,
+ uint32_t bucket_count,
+ int32_t flags,
+ mojom::SingleSampleMetricRequest request) override {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ mojo::MakeStrongBinding(base::MakeUnique<MojoSingleSampleMetric>(
+ histogram_name, min, max, bucket_count, flags),
+ std::move(request));
+ }
+
+ // Providers must be created, used on, and destroyed on the same thread.
+ base::ThreadChecker thread_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoSingleSampleMetricsProvider);
+};
+
+} // namespace
+
+// static
+void InitializeSingleSampleMetricsFactory(CreateProviderCB create_provider_cb) {
+ base::SingleSampleMetricsFactory::SetFactory(
+ base::MakeUnique<SingleSampleMetricsFactoryImpl>(
+ std::move(create_provider_cb)));
+}
+
+// static
+void CreateSingleSampleMetricsProvider(
+ const service_manager::BindSourceInfo& source_info,
+ mojom::SingleSampleMetricsProviderRequest request) {
+ mojo::MakeStrongBinding(base::MakeUnique<MojoSingleSampleMetricsProvider>(),
+ std::move(request));
+}
+
+} // namespace metrics
diff --git a/chromium/components/metrics/single_sample_metrics.h b/chromium/components/metrics/single_sample_metrics.h
new file mode 100644
index 00000000000..cd7ab33f927
--- /dev/null
+++ b/chromium/components/metrics/single_sample_metrics.h
@@ -0,0 +1,43 @@
+// Copyright 2017 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_METRICS_SINGLE_SAMPLE_METRICS_H_
+#define COMPONENTS_METRICS_SINGLE_SAMPLE_METRICS_H_
+
+#include "base/callback.h"
+#include "components/metrics/public/interfaces/single_sample_metrics.mojom.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
+
+namespace metrics {
+
+using CreateProviderCB =
+ base::RepeatingCallback<void(mojom::SingleSampleMetricsProviderRequest)>;
+
+// Initializes and sets the base::SingleSampleMetricsFactory for the current
+// process. |create_provider_cb| is used to create provider instances per each
+// thread that the factory is used on; this is necessary since the underlying
+// providers must only be used on the same thread as construction.
+//
+// We use a callback here to avoid taking additional DEPS on content and a
+// service_manager::Connector() for simplicity and to avoid the need for
+// using the service test harness in metrics unittests.
+//
+// Typically this is called in the process where termination may occur without
+// warning; e.g. perhaps a renderer process.
+extern void InitializeSingleSampleMetricsFactory(
+ CreateProviderCB create_provider_cb);
+
+// Creates a mojom::SingleSampleMetricsProvider capable of vending single sample
+// metrics attached to a mojo pipe.
+//
+// Typically this is given to a service_manager::BinderRegistry in the process
+// that has a deterministic shutdown path and which serves as a stable endpoint
+// for the factory created by the above initialize method in another process.
+extern void CreateSingleSampleMetricsProvider(
+ const service_manager::BindSourceInfo& source_info,
+ mojom::SingleSampleMetricsProviderRequest request);
+
+} // namespace metrics
+
+#endif // COMPONENTS_METRICS_SINGLE_SAMPLE_METRICS_H_
diff --git a/chromium/components/metrics/single_sample_metrics_factory_impl.cc b/chromium/components/metrics/single_sample_metrics_factory_impl.cc
new file mode 100644
index 00000000000..677fa8bc1bd
--- /dev/null
+++ b/chromium/components/metrics/single_sample_metrics_factory_impl.cc
@@ -0,0 +1,90 @@
+// Copyright 2017 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/metrics/single_sample_metrics_factory_impl.h"
+
+#include "base/threading/thread_checker.h"
+
+namespace metrics {
+
+namespace {
+
+class SingleSampleMetricImpl : public base::SingleSampleMetric {
+ public:
+ SingleSampleMetricImpl(mojom::SingleSampleMetricPtr metric)
+ : metric_(std::move(metric)) {}
+
+ ~SingleSampleMetricImpl() override {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ }
+
+ void SetSample(base::HistogramBase::Sample sample) override {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ metric_->SetSample(sample);
+ }
+
+ private:
+ base::ThreadChecker thread_checker_;
+ mojom::SingleSampleMetricPtr metric_;
+
+ DISALLOW_COPY_AND_ASSIGN(SingleSampleMetricImpl);
+};
+
+} // namespace
+
+SingleSampleMetricsFactoryImpl::SingleSampleMetricsFactoryImpl(
+ CreateProviderCB create_provider_cb)
+ : create_provider_cb_(std::move(create_provider_cb)) {}
+
+SingleSampleMetricsFactoryImpl::~SingleSampleMetricsFactoryImpl() {}
+
+std::unique_ptr<base::SingleSampleMetric>
+SingleSampleMetricsFactoryImpl::CreateCustomCountsMetric(
+ const std::string& histogram_name,
+ base::HistogramBase::Sample min,
+ base::HistogramBase::Sample max,
+ uint32_t bucket_count) {
+ return CreateMetric(histogram_name, min, max, bucket_count,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+}
+
+void SingleSampleMetricsFactoryImpl::DestroyProviderForTesting() {
+ if (auto* provider = provider_tls_.Get())
+ delete provider;
+ provider_tls_.Set(nullptr);
+}
+
+std::unique_ptr<base::SingleSampleMetric>
+SingleSampleMetricsFactoryImpl::CreateMetric(const std::string& histogram_name,
+ base::HistogramBase::Sample min,
+ base::HistogramBase::Sample max,
+ uint32_t bucket_count,
+ int32_t flags) {
+ mojom::SingleSampleMetricPtr metric;
+ GetProvider()->AcquireSingleSampleMetric(histogram_name, min, max,
+ bucket_count, flags,
+ mojo::MakeRequest(&metric));
+ return base::MakeUnique<SingleSampleMetricImpl>(std::move(metric));
+}
+
+mojom::SingleSampleMetricsProvider*
+SingleSampleMetricsFactoryImpl::GetProvider() {
+ // Check the current TLS slot to see if we have created a provider already for
+ // this thread.
+ if (auto* provider = provider_tls_.Get())
+ return provider->get();
+
+ // If not, create a new one which will persist until process shutdown and put
+ // it in the TLS slot for the current thread.
+ mojom::SingleSampleMetricsProviderPtr* provider =
+ new mojom::SingleSampleMetricsProviderPtr();
+ provider_tls_.Set(provider);
+
+ // Start the provider connection and return it; it won't be fully connected
+ // until later, but mojo will buffer all calls prior to completion.
+ create_provider_cb_.Run(mojo::MakeRequest(provider));
+ return provider->get();
+}
+
+} // namespace metrics
diff --git a/chromium/components/metrics/single_sample_metrics_factory_impl.h b/chromium/components/metrics/single_sample_metrics_factory_impl.h
new file mode 100644
index 00000000000..297324f97b7
--- /dev/null
+++ b/chromium/components/metrics/single_sample_metrics_factory_impl.h
@@ -0,0 +1,71 @@
+// Copyright 2017 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_METRICS_SINGLE_VALUE_HISTOGRAM_FACTORY_IMPL_H_
+#define COMPONENTS_METRICS_SINGLE_VALUE_HISTOGRAM_FACTORY_IMPL_H_
+
+#include <string>
+
+#include "base/metrics/single_sample_metrics.h"
+#include "base/threading/thread_local.h"
+#include "components/metrics/public/interfaces/single_sample_metrics.mojom.h"
+#include "components/metrics/single_sample_metrics.h"
+
+namespace metrics {
+
+// SingleSampleMetricsFactory implementation for creating SingleSampleMetric
+// instances that communicate over mojo to instances in another process.
+//
+// Persistance outside of the current process allows these metrics to record a
+// sample even in the event of sudden process termination. As an example, this
+// is useful for garbage collected objects which may never get a chance to run
+// their destructors in the event of a fast shutdown event (process kill).
+class SingleSampleMetricsFactoryImpl : public base::SingleSampleMetricsFactory {
+ public:
+ // Constructs a factory capable of vending single sample metrics from any
+ // thread. |create_provider_cb| will be called from arbitrary threads to
+ // create providers as necessary; the callback must handle thread safety.
+ //
+ // We use a callback here to avoid taking additional DEPS on content and a
+ // service_manager::Connector() for simplicitly and to avoid the need for
+ // using the service test harness just for instantiating this class.
+ explicit SingleSampleMetricsFactoryImpl(CreateProviderCB create_provider_cb);
+ ~SingleSampleMetricsFactoryImpl() override;
+
+ // base::SingleSampleMetricsFactory:
+ std::unique_ptr<base::SingleSampleMetric> CreateCustomCountsMetric(
+ const std::string& histogram_name,
+ base::HistogramBase::Sample min,
+ base::HistogramBase::Sample max,
+ uint32_t bucket_count) override;
+
+ // Providers live forever in production, but tests should be kind and clean up
+ // after themselves to avoid tests trampling on one another. Destroys the
+ // provider in the TLS slot for the calling thread.
+ void DestroyProviderForTesting();
+
+ private:
+ // Creates a single sample metric.
+ std::unique_ptr<base::SingleSampleMetric> CreateMetric(
+ const std::string& histogram_name,
+ base::HistogramBase::Sample min,
+ base::HistogramBase::Sample max,
+ uint32_t bucket_count,
+ int32_t flags);
+
+ // Gets the SingleSampleMetricsProvider for the current thread. If none
+ // exists, then a new instance is created and set in the TLS slot.
+ mojom::SingleSampleMetricsProvider* GetProvider();
+
+ CreateProviderCB create_provider_cb_;
+
+ // Per thread storage slot for the mojo provider.
+ base::ThreadLocalPointer<mojom::SingleSampleMetricsProviderPtr> provider_tls_;
+
+ DISALLOW_COPY_AND_ASSIGN(SingleSampleMetricsFactoryImpl);
+};
+
+} // namespace metrics
+
+#endif // COMPONENTS_METRICS_SINGLE_VALUE_HISTOGRAM_FACTORY_IMPL_H_
diff --git a/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc b/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
new file mode 100644
index 00000000000..a649b5df789
--- /dev/null
+++ b/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
@@ -0,0 +1,181 @@
+// Copyright 2017 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/metrics/single_sample_metrics_factory_impl.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/test/gtest_util.h"
+#include "base/test/histogram_tester.h"
+#include "base/threading/thread.h"
+#include "components/metrics/single_sample_metrics.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace metrics {
+
+namespace {
+
+const base::HistogramBase::Sample kMin = 1;
+const base::HistogramBase::Sample kMax = 10;
+const uint32_t kBucketCount = 10;
+const char kMetricName[] = "Single.Sample.Metric";
+
+class SingleSampleMetricsFactoryImplTest : public testing::Test {
+ public:
+ SingleSampleMetricsFactoryImplTest() : thread_("TestThread") {
+ InitializeSingleSampleMetricsFactory(
+ base::BindRepeating(&SingleSampleMetricsFactoryImplTest::CreateProvider,
+ base::Unretained(this)));
+ factory_ = static_cast<SingleSampleMetricsFactoryImpl*>(
+ base::SingleSampleMetricsFactory::Get());
+ }
+
+ ~SingleSampleMetricsFactoryImplTest() override {
+ factory_->DestroyProviderForTesting();
+ if (thread_.IsRunning())
+ ShutdownThread();
+ base::SingleSampleMetricsFactory::DeleteFactoryForTesting();
+ }
+
+ protected:
+ void StartThread() { ASSERT_TRUE(thread_.Start()); }
+
+ void ShutdownThread() {
+ thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&SingleSampleMetricsFactoryImpl::DestroyProviderForTesting,
+ base::Unretained(factory_)));
+ thread_.Stop();
+ }
+
+ void CreateProvider(mojom::SingleSampleMetricsProviderRequest request) {
+ CreateSingleSampleMetricsProvider(service_manager::BindSourceInfo(),
+ std::move(request));
+ provider_count_++;
+ }
+
+ std::unique_ptr<base::SingleSampleMetric> CreateMetricOnThread() {
+ std::unique_ptr<base::SingleSampleMetric> metric;
+ base::RunLoop run_loop;
+ thread_.task_runner()->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&SingleSampleMetricsFactoryImplTest::CreateAndStoreMetric,
+ base::Unretained(this), &metric),
+ run_loop.QuitClosure());
+ run_loop.Run();
+ return metric;
+ }
+
+ void CreateAndStoreMetric(std::unique_ptr<base::SingleSampleMetric>* metric) {
+ *metric = factory_->CreateCustomCountsMetric(kMetricName, kMin, kMax,
+ kBucketCount);
+ }
+
+ base::MessageLoop message_looqp_;
+ SingleSampleMetricsFactoryImpl* factory_;
+ base::Thread thread_;
+ size_t provider_count_ = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SingleSampleMetricsFactoryImplTest);
+};
+
+} // namespace
+
+TEST_F(SingleSampleMetricsFactoryImplTest, SingleProvider) {
+ std::unique_ptr<base::SingleSampleMetric> metric1 =
+ factory_->CreateCustomCountsMetric(kMetricName, kMin, kMax, kBucketCount);
+
+ std::unique_ptr<base::SingleSampleMetric> metric2 =
+ factory_->CreateCustomCountsMetric(kMetricName, kMin, kMax, kBucketCount);
+
+ // Verify that only a single provider is created for multiple metrics.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, provider_count_);
+}
+
+TEST_F(SingleSampleMetricsFactoryImplTest, DoesNothing) {
+ base::HistogramTester tester;
+
+ std::unique_ptr<base::SingleSampleMetric> metric =
+ factory_->CreateCustomCountsMetric(kMetricName, kMin, kMax, kBucketCount);
+ metric.reset();
+
+ // Verify that no sample is recorded if SetSample() is never called.
+ base::RunLoop().RunUntilIdle();
+ tester.ExpectTotalCount(kMetricName, 0);
+}
+
+TEST_F(SingleSampleMetricsFactoryImplTest, DefaultSingleSampleMetricWithValue) {
+ base::HistogramTester tester;
+ std::unique_ptr<base::SingleSampleMetric> metric =
+ factory_->CreateCustomCountsMetric(kMetricName, kMin, kMax, kBucketCount);
+
+ const base::HistogramBase::Sample kLastSample = 9;
+ metric->SetSample(1);
+ metric->SetSample(3);
+ metric->SetSample(5);
+ metric->SetSample(kLastSample);
+ metric.reset();
+
+ // Verify only the last sample sent to SetSample() is recorded.
+ base::RunLoop().RunUntilIdle();
+ tester.ExpectUniqueSample(kMetricName, kLastSample, 1);
+
+ // Verify construction implicitly by requesting a histogram with the same
+ // parameters; this test relies on the fact that histogram objects are unique
+ // per name. Different parameters will result in a nullptr being returned.
+ EXPECT_FALSE(base::Histogram::FactoryGet(kMetricName, 1, 3, 3,
+ base::HistogramBase::kNoFlags));
+ EXPECT_TRUE(base::Histogram::FactoryGet(
+ kMetricName, kMin, kMax, kBucketCount,
+ base::HistogramBase::kUmaTargetedHistogramFlag));
+}
+
+TEST_F(SingleSampleMetricsFactoryImplTest, MultithreadedMetrics) {
+ base::HistogramTester tester;
+ std::unique_ptr<base::SingleSampleMetric> metric =
+ factory_->CreateCustomCountsMetric(kMetricName, kMin, kMax, kBucketCount);
+ EXPECT_EQ(1u, provider_count_);
+
+ StartThread();
+
+ std::unique_ptr<base::SingleSampleMetric> threaded_metric =
+ CreateMetricOnThread();
+ ASSERT_TRUE(threaded_metric);
+
+ // A second provider should be created to handle requests on our new thread.
+ EXPECT_EQ(2u, provider_count_);
+
+ // Calls from the wrong thread should DCHECK.
+ EXPECT_DCHECK_DEATH(threaded_metric->SetSample(5));
+ EXPECT_DCHECK_DEATH(threaded_metric.reset());
+
+ // Test that samples are set on each thread correctly.
+ const base::HistogramBase::Sample kSample = 7;
+
+ {
+ metric->SetSample(kSample);
+
+ base::RunLoop run_loop;
+ thread_.task_runner()->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&base::SingleSampleMetric::SetSample,
+ base::Unretained(threaded_metric.get()), kSample),
+ run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ // Release metrics and shutdown thread to ensure destruction completes.
+ thread_.task_runner()->DeleteSoon(FROM_HERE, threaded_metric.release());
+ ShutdownThread();
+
+ metric.reset();
+ base::RunLoop().RunUntilIdle();
+
+ tester.ExpectUniqueSample(kMetricName, kSample, 2);
+}
+
+} // namespace metrics
diff --git a/chromium/components/metrics_services_manager/BUILD.gn b/chromium/components/metrics_services_manager/BUILD.gn
index 6c433266a22..a09ffde8fda 100644
--- a/chromium/components/metrics_services_manager/BUILD.gn
+++ b/chromium/components/metrics_services_manager/BUILD.gn
@@ -6,6 +6,7 @@ static_library("metrics_services_manager") {
sources = [
"metrics_services_manager.cc",
"metrics_services_manager.h",
+ "metrics_services_manager_client.cc",
"metrics_services_manager_client.h",
]
diff --git a/chromium/components/metrics_services_manager/metrics_services_manager.cc b/chromium/components/metrics_services_manager/metrics_services_manager.cc
index 5987635fbac..4659d8c30aa 100644
--- a/chromium/components/metrics_services_manager/metrics_services_manager.cc
+++ b/chromium/components/metrics_services_manager/metrics_services_manager.cc
@@ -132,8 +132,10 @@ void MetricsServicesManager::UpdateUkmService() {
if (!ukm)
return;
bool sync_enabled =
+ client_->IsMetricsReportingForceEnabled() ||
metrics_service_client_->IsHistorySyncEnabledOnAllProfiles();
- if (may_record_ && sync_enabled) {
+ bool is_incognito = client_->IsIncognitoSessionActive();
+ if (may_record_ && sync_enabled & !is_incognito) {
ukm->EnableRecording();
if (may_upload_)
ukm->EnableReporting();
@@ -146,7 +148,9 @@ void MetricsServicesManager::UpdateUkmService() {
}
void MetricsServicesManager::UpdateUploadPermissions(bool may_upload) {
- UpdatePermissions(client_->IsMetricsReportingEnabled(), may_upload);
+ UpdatePermissions((client_->IsMetricsReportingForceEnabled() ||
+ client_->IsMetricsReportingEnabled()),
+ client_->IsMetricsReportingForceEnabled() || may_upload);
}
} // namespace metrics_services_manager
diff --git a/chromium/components/metrics_services_manager/metrics_services_manager_client.cc b/chromium/components/metrics_services_manager/metrics_services_manager_client.cc
new file mode 100644
index 00000000000..05c68697e12
--- /dev/null
+++ b/chromium/components/metrics_services_manager/metrics_services_manager_client.cc
@@ -0,0 +1,13 @@
+// Copyright 2014 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/metrics_services_manager/metrics_services_manager_client.h"
+
+namespace metrics_services_manager {
+
+bool MetricsServicesManagerClient::IsMetricsReportingForceEnabled() {
+ return false;
+}
+
+} // namespace metrics_services_manager
diff --git a/chromium/components/metrics_services_manager/metrics_services_manager_client.h b/chromium/components/metrics_services_manager/metrics_services_manager_client.h
index 1490ff984f8..1b4e9a81907 100644
--- a/chromium/components/metrics_services_manager/metrics_services_manager_client.h
+++ b/chromium/components/metrics_services_manager/metrics_services_manager_client.h
@@ -54,9 +54,15 @@ class MetricsServicesManagerClient {
// Whether the metrics services should record but not report metrics.
virtual bool OnlyDoMetricsRecording() = 0;
+ // Returns whether there are any Incognito browsers/tabs open.
+ virtual bool IsIncognitoSessionActive() = 0;
+
// Update the running state of metrics services managed by the embedder, for
// example, crash reporting.
virtual void UpdateRunningServices(bool may_record, bool may_upload) {}
+
+ // If the user has forced metrics collection on via the override flag.
+ virtual bool IsMetricsReportingForceEnabled();
};
} // namespace metrics_services_manager
diff --git a/chromium/components/minidump_uploader/BUILD.gn b/chromium/components/minidump_uploader/BUILD.gn
index c017ccd3abe..056ce6a6305 100644
--- a/chromium/components/minidump_uploader/BUILD.gn
+++ b/chromium/components/minidump_uploader/BUILD.gn
@@ -37,5 +37,9 @@ android_library("minidump_uploader_javatests") {
"android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java",
"android/javatests/src/org/chromium/components/minidump_uploader/CrashTestCase.java",
"android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadCallableTest.java",
+ "android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadTestUtility.java",
+ "android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploaderImplTest.java",
+ "android/javatests/src/org/chromium/components/minidump_uploader/TestMinidumpUploaderDelegate.java",
+ "android/javatests/src/org/chromium/components/minidump_uploader/TestMinidumpUploaderImpl.java",
]
}
diff --git a/chromium/components/minidump_uploader/OWNERS b/chromium/components/minidump_uploader/OWNERS
index af66982db09..6b952ef4a27 100644
--- a/chromium/components/minidump_uploader/OWNERS
+++ b/chromium/components/minidump_uploader/OWNERS
@@ -2,6 +2,7 @@
mariakhomenko@chromium.org
# Crash uploading mechanism
+gsennton@chromium.org
isherman@chromium.org
# COMPONENT: Internals>CrashReporting
diff --git a/chromium/components/nacl/browser/BUILD.gn b/chromium/components/nacl/browser/BUILD.gn
index a9bfe4d9917..62d57f2409f 100644
--- a/chromium/components/nacl/browser/BUILD.gn
+++ b/chromium/components/nacl/browser/BUILD.gn
@@ -48,6 +48,7 @@ static_library("browser") {
public_deps = [
"//ipc",
+ "//services/service_manager/public/interfaces",
]
data_deps = []
diff --git a/chromium/components/navigation_interception/intercept_navigation_delegate.cc b/chromium/components/navigation_interception/intercept_navigation_delegate.cc
index 710c0c782b1..b8cd316f64b 100644
--- a/chromium/components/navigation_interception/intercept_navigation_delegate.cc
+++ b/chromium/components/navigation_interception/intercept_navigation_delegate.cc
@@ -74,7 +74,7 @@ void InterceptNavigationDelegate::Associate(
WebContents* web_contents,
std::unique_ptr<InterceptNavigationDelegate> delegate) {
web_contents->SetUserData(kInterceptNavigationDelegateUserDataKey,
- delegate.release());
+ std::move(delegate));
}
// static
diff --git a/chromium/components/navigation_interception/intercept_navigation_throttle.cc b/chromium/components/navigation_interception/intercept_navigation_throttle.cc
index c66a302286e..25875f0ae70 100644
--- a/chromium/components/navigation_interception/intercept_navigation_throttle.cc
+++ b/chromium/components/navigation_interception/intercept_navigation_throttle.cc
@@ -62,6 +62,10 @@ InterceptNavigationThrottle::WillRedirectRequest() {
return CheckIfShouldIgnoreNavigation(true);
}
+const char* InterceptNavigationThrottle::GetNameForLogging() {
+ return "InterceptNavigationThrottle";
+}
+
content::NavigationThrottle::ThrottleCheckResult
InterceptNavigationThrottle::CheckIfShouldIgnoreNavigation(bool is_redirect) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chromium/components/navigation_interception/intercept_navigation_throttle.h b/chromium/components/navigation_interception/intercept_navigation_throttle.h
index b70c007e0d6..d8aee3458f8 100644
--- a/chromium/components/navigation_interception/intercept_navigation_throttle.h
+++ b/chromium/components/navigation_interception/intercept_navigation_throttle.h
@@ -37,6 +37,7 @@ class InterceptNavigationThrottle : public content::NavigationThrottle {
// content::NavigationThrottle implementation:
ThrottleCheckResult WillStartRequest() override;
ThrottleCheckResult WillRedirectRequest() override;
+ const char* GetNameForLogging() override;
private:
ThrottleCheckResult CheckIfShouldIgnoreNavigation(bool is_redirect);
diff --git a/chromium/components/navigation_metrics/BUILD.gn b/chromium/components/navigation_metrics/BUILD.gn
index 231ff611a2d..3908ff129a7 100644
--- a/chromium/components/navigation_metrics/BUILD.gn
+++ b/chromium/components/navigation_metrics/BUILD.gn
@@ -6,13 +6,10 @@ static_library("navigation_metrics") {
sources = [
"navigation_metrics.cc",
"navigation_metrics.h",
- "origins_seen_service.cc",
- "origins_seen_service.h",
]
deps = [
"//base",
- "//components/keyed_service/core",
"//url",
]
}
diff --git a/chromium/components/navigation_metrics/OWNERS b/chromium/components/navigation_metrics/OWNERS
index e9db99ed04e..06f6dae274c 100644
--- a/chromium/components/navigation_metrics/OWNERS
+++ b/chromium/components/navigation_metrics/OWNERS
@@ -1,4 +1,6 @@
cbentzel@chromium.org
davidben@chromium.org
+elawrence@chromium.org
+estark@chromium.org
# COMPONENT: Internals>Network
diff --git a/chromium/components/navigation_metrics/navigation_metrics.cc b/chromium/components/navigation_metrics/navigation_metrics.cc
index bf7d81bbee2..78df32462d8 100644
--- a/chromium/components/navigation_metrics/navigation_metrics.cc
+++ b/chromium/components/navigation_metrics/navigation_metrics.cc
@@ -50,9 +50,8 @@ static_assert(arraysize(kSchemeNames) == SCHEME_MAX + 1,
namespace navigation_metrics {
void RecordMainFrameNavigation(const GURL& url,
- bool is_in_page,
- bool is_off_the_record,
- bool have_already_seen_origin) {
+ bool is_same_document,
+ bool is_off_the_record) {
Scheme scheme = SCHEME_UNKNOWN;
for (int i = 1; i < SCHEME_MAX; ++i) {
if (url.SchemeIs(kSchemeNames[i])) {
@@ -61,18 +60,8 @@ void RecordMainFrameNavigation(const GURL& url,
}
}
- if (!have_already_seen_origin) {
- if (is_off_the_record) {
- UMA_HISTOGRAM_ENUMERATION("Navigation.SchemePerUniqueOriginOTR", scheme,
- SCHEME_MAX);
- } else {
- UMA_HISTOGRAM_ENUMERATION("Navigation.SchemePerUniqueOrigin", scheme,
- SCHEME_MAX);
- }
- }
-
UMA_HISTOGRAM_ENUMERATION("Navigation.MainFrameScheme", scheme, SCHEME_MAX);
- if (!is_in_page) {
+ if (!is_same_document) {
UMA_HISTOGRAM_ENUMERATION("Navigation.MainFrameSchemeDifferentPage", scheme,
SCHEME_MAX);
}
@@ -80,7 +69,7 @@ void RecordMainFrameNavigation(const GURL& url,
if (is_off_the_record) {
UMA_HISTOGRAM_ENUMERATION("Navigation.MainFrameSchemeOTR", scheme,
SCHEME_MAX);
- if (!is_in_page) {
+ if (!is_same_document) {
UMA_HISTOGRAM_ENUMERATION("Navigation.MainFrameSchemeDifferentPageOTR",
scheme, SCHEME_MAX);
}
diff --git a/chromium/components/navigation_metrics/navigation_metrics.h b/chromium/components/navigation_metrics/navigation_metrics.h
index 05176b7ed16..1475d6e1801 100644
--- a/chromium/components/navigation_metrics/navigation_metrics.h
+++ b/chromium/components/navigation_metrics/navigation_metrics.h
@@ -10,9 +10,8 @@ class GURL;
namespace navigation_metrics {
void RecordMainFrameNavigation(const GURL& url,
- bool is_in_page,
- bool is_off_the_record,
- bool have_already_seen_origin);
+ bool is_same_document,
+ bool is_off_the_record);
} // namespace navigation_metrics
diff --git a/chromium/components/navigation_metrics/navigation_metrics_unittest.cc b/chromium/components/navigation_metrics/navigation_metrics_unittest.cc
index fc3ac335ba3..0ff3b1803fa 100644
--- a/chromium/components/navigation_metrics/navigation_metrics_unittest.cc
+++ b/chromium/components/navigation_metrics/navigation_metrics_unittest.cc
@@ -24,7 +24,7 @@ namespace navigation_metrics {
TEST(NavigationMetrics, MainFrameSchemeDifferentDocument) {
base::HistogramTester test;
- RecordMainFrameNavigation(GURL(kTestUrl), false, false, false);
+ RecordMainFrameNavigation(GURL(kTestUrl), false, false);
test.ExpectTotalCount(kMainFrameScheme, 1);
test.ExpectUniqueSample(kMainFrameScheme, 1 /* http */, 1);
@@ -37,7 +37,7 @@ TEST(NavigationMetrics, MainFrameSchemeDifferentDocument) {
TEST(NavigationMetrics, MainFrameSchemeSameDocument) {
base::HistogramTester test;
- RecordMainFrameNavigation(GURL(kTestUrl), true, false, false);
+ RecordMainFrameNavigation(GURL(kTestUrl), true, false);
test.ExpectTotalCount(kMainFrameScheme, 1);
test.ExpectUniqueSample(kMainFrameScheme, 1 /* http */, 1);
@@ -49,7 +49,7 @@ TEST(NavigationMetrics, MainFrameSchemeSameDocument) {
TEST(NavigationMetrics, MainFrameSchemeDifferentDocumentOTR) {
base::HistogramTester test;
- RecordMainFrameNavigation(GURL(kTestUrl), false, true, false);
+ RecordMainFrameNavigation(GURL(kTestUrl), false, true);
test.ExpectTotalCount(kMainFrameScheme, 1);
test.ExpectUniqueSample(kMainFrameScheme, 1 /* http */, 1);
@@ -64,7 +64,7 @@ TEST(NavigationMetrics, MainFrameSchemeDifferentDocumentOTR) {
TEST(NavigationMetrics, MainFrameSchemeSameDocumentOTR) {
base::HistogramTester test;
- RecordMainFrameNavigation(GURL(kTestUrl), true, true, false);
+ RecordMainFrameNavigation(GURL(kTestUrl), true, true);
test.ExpectTotalCount(kMainFrameScheme, 1);
test.ExpectUniqueSample(kMainFrameScheme, 1 /* http */, 1);
diff --git a/chromium/components/navigation_metrics/origins_seen_service.cc b/chromium/components/navigation_metrics/origins_seen_service.cc
deleted file mode 100644
index b6bab64f225..00000000000
--- a/chromium/components/navigation_metrics/origins_seen_service.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 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/navigation_metrics/origins_seen_service.h"
-
-namespace navigation_metrics {
-namespace {
-const size_t kDefaultMRUCacheSize = 1000;
-} // namespace
-
-OriginsSeenService::OriginsSeenService()
- : origins_seen_(kDefaultMRUCacheSize) {}
-
-OriginsSeenService::~OriginsSeenService() {}
-
-bool OriginsSeenService::Insert(const url::Origin& origin) {
- bool seen = origins_seen_.Peek(origin) != origins_seen_.end();
- origins_seen_.Put(origin, true);
- return seen;
-}
-} // namespace navigation_metrics
diff --git a/chromium/components/navigation_metrics/origins_seen_service.h b/chromium/components/navigation_metrics/origins_seen_service.h
deleted file mode 100644
index 94e43305a1d..00000000000
--- a/chromium/components/navigation_metrics/origins_seen_service.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 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_NAVIGATION_METRICS_ORIGINS_SEEN_SERVICE_H_
-#define COMPONENTS_NAVIGATION_METRICS_ORIGINS_SEEN_SERVICE_H_
-
-#include "base/containers/mru_cache.h"
-#include "components/keyed_service/core/keyed_service.h"
-#include "url/origin.h"
-
-namespace navigation_metrics {
-
-class OriginsSeenService : public KeyedService {
- public:
- OriginsSeenService();
- ~OriginsSeenService() override;
-
- // Used when deciding whether or not to record
- // Navigation.SchemePerUniqueOrigin[OTR]. Inserts a copy of |origin| into the
- // set |origins_seen_|, and returns whether or not |origin| was already in the
- // set.
- bool Insert(const url::Origin& origin);
-
- private:
- // Used by |HaveAlreadySeenOrigin|. This cache is in volatile storage because
- // Off The Record Profiles also use this Service.
- base::MRUCache<url::Origin, bool> origins_seen_;
-};
-
-} // namespace navigation_metrics
-
-#endif // COMPONENTS_NAVIGATION_METRICS_ORIGINS_SEEN_SERVICE_H_
diff --git a/chromium/components/net_log/net_export_ui_constants.cc b/chromium/components/net_log/net_export_ui_constants.cc
index ce6c1f7a623..3d367bb931d 100644
--- a/chromium/components/net_log/net_export_ui_constants.cc
+++ b/chromium/components/net_log/net_export_ui_constants.cc
@@ -12,6 +12,7 @@ const char kNetExportUIJS[] = "net_export.js";
// Message handlers.
const char kEnableNotifyUIWithStateHandler[] = "enableNotifyUIWithState";
const char kSendNetLogHandler[] = "sendNetLog";
+const char kShowFile[] = "showFile";
const char kStartNetLogHandler[] = "startNetLog";
const char kStopNetLogHandler[] = "stopNetLog";
diff --git a/chromium/components/net_log/net_export_ui_constants.h b/chromium/components/net_log/net_export_ui_constants.h
index 06ff1f162d4..ab9119eb4b9 100644
--- a/chromium/components/net_log/net_export_ui_constants.h
+++ b/chromium/components/net_log/net_export_ui_constants.h
@@ -15,6 +15,7 @@ extern const char kNetExportUIJS[];
// Must match the constants used in the resource files.
extern const char kEnableNotifyUIWithStateHandler[];
extern const char kSendNetLogHandler[];
+extern const char kShowFile[];
extern const char kStartNetLogHandler[];
extern const char kStopNetLogHandler[];
diff --git a/chromium/components/net_log/net_log_file_writer.cc b/chromium/components/net_log/net_log_file_writer.cc
index 3fb3833419b..8be69a73e1a 100644
--- a/chromium/components/net_log/net_log_file_writer.cc
+++ b/chromium/components/net_log/net_log_file_writer.cc
@@ -244,9 +244,7 @@ std::unique_ptr<base::DictionaryValue> NetLogFileWriter::GetState() const {
auto dict = base::MakeUnique<base::DictionaryValue>();
-#ifndef NDEBUG
dict->SetString("file", log_path_.LossyDisplayName());
-#endif // NDEBUG
base::StringPiece state_string;
switch (state_) {
diff --git a/chromium/components/net_log/resources/net_export.css b/chromium/components/net_log/resources/net_export.css
index 8d7783039a8..322df333726 100644
--- a/chromium/components/net_log/resources/net_export.css
+++ b/chromium/components/net_log/resources/net_export.css
@@ -5,6 +5,13 @@
body {
font-size: 80%;
+ margin: 1em;
+}
+
+#main-container {
+ max-width: 60em;
+ margin-left: auto;
+ margin-right: auto;
}
button {
@@ -12,14 +19,15 @@ button {
font-size: 110%;
font-weight: bold;
margin: 10px auto;
- min-height: 48px;
- width: 200px;
+ padding: 1em;
+ width: 14em;
}
-button:disabled > .export-view-logging-enabled,
-button:enabled > .export-view-logging-disabled
-{
- display: none;
+h2 {
+ color: #546E7A;
+ font-weight: normal;
+ font-size: 170%;
+ margin-bottom: 1.5em;
}
.radio-button-div {
@@ -29,14 +37,20 @@ button:enabled > .export-view-logging-disabled
.warning {
color: red;
font-size: 90%;
- font-weight: normal;
}
-#net-export-main {
- margin: 8px;
+.section-container {
+ margin-top: 2em;
+}
+
+#file-path-logging,
+#file-path-stopped {
+ font-family: monospace;
}
-#export-view-file-path-text {
- white-space: pre-wrap;
- word-wrap: break-word;
+.outline-box {
+ margin-top: 2em;
+ border: 1px solid #ababab;
+ padding: 0.5em;
+ line-height: 1.5em;
}
diff --git a/chromium/components/net_log/resources/net_export.html b/chromium/components/net_log/resources/net_export.html
index 48d13725070..b612b7ea30e 100644
--- a/chromium/components/net_log/resources/net_export.html
+++ b/chromium/components/net_log/resources/net_export.html
@@ -19,87 +19,151 @@
<title>Network Log Export</title>
</head>
<body>
- <h2>Network Log Export</h2>
- <div id="net-export-main">
- <div>
- <button id="export-view-start-data" disabled>
- <span class="export-view-logging-enabled">Start Logging to Disk</span>
- <span class="export-view-logging-disabled">Logging to Disk...</span>
- <if expr="is_ios or is_android">
- <div class="warning" id="export-view-mobile-deletes-log-text" hidden>
- Deletes old log
- </div>
- </if>
- </button>
+ <div id="main-container">
+ <!--
+ =========================================================================
+ View for "unitialized" state.
+ * Only visible briefly, if at all
+ =========================================================================
+ -->
+ <div id="state-uninitialized">
+ <h2>Network Log Export</h2>
+ Loading...
</div>
- <div>
- <button id="export-view-stop-data" disabled>Stop Logging</button>
+
+ <!--
+ =========================================================================
+ View for "initial" state.
+ * Has controls to start logging.
+ =========================================================================
+ -->
+ <div id="state-initial">
+ <h2>Capture Network Log</h2>
+ <button id="start-logging">Start Logging to Disk</button>
+
+ <div class="section-container">
+ Click the button to start logging future network activity to a file on
+ disk.
+ </div>
+
+ <div class="outline-box">
+ <b>OPTIONS</b>:
+ <span class="warning">This section should normally be left alone.</span>
+ <div class="radio-button-div">
+ <label>
+ <input id="strip-private-data-button" type="radio"
+ name="log-mode" value="STRIP_PRIVATE_DATA" checked>
+ Strip private information
+ </label>
+ </div>
+ <div class="radio-button-div">
+ <label>
+ <input id="include-private-data-button" type="radio"
+ name="log-mode" value="NORMAL">
+ Include cookies and credentials
+ </label>
+ </div>
+ <div class="radio-button-div">
+ <label>
+ <input id="log-bytes-button" type="radio"
+ name="log-mode" value="LOG_BYTES">
+ Include raw bytes (will include cookies and credentials)
+ </label>
+ </div>
+ </div>
</div>
- <div>
- <if expr="is_ios or is_android">
- <button id="export-view-mobile-send-data" disabled>
- Email Log
- <div class="warning" id="export-view-mobile-private-data-text" hidden>
- Log contains private information
- </div>
- <div class="warning" id="export-view-mobile-send-old-log-text" hidden>
- Log file from previous session
- </div>
- </button>
- </if>
+
+ <!--
+ =========================================================================
+ View for "logging" state.
+ * Shows that logging is in progress
+ * Has controls to stop logging
+ =========================================================================
+ -->
+ <div id="state-logging">
+ <h2>Saving network events to disk...</h2>
+
+ <button id="stop-logging">Stop Logging</button>
+
+ <div class="section-container">
+ <p>Reproduce the network problem now using another tab. When you are
+ done, return to this page and click the Stop button.</p>
+
+ <p>All of your browser's networking activity will be written to the log
+ file until you either click the Stop button, or close this tab.</p>
+ </div>
+
+ <div class="outline-box">
+ <b>FILE:</b> <span id="file-path-logging"></span> <br/>
+ <b>OPTIONS:</b> <span id="capture-mode-logging"></span>
+ </div>
</div>
- <p>
- <b>INSTRUCTIONS</b>: Start logging, reproduce the problem,
- and then stop logging.
-
+
+ <!--
+ =========================================================================
+ View for "stopped" state.
+ * Shows where the log file was saved to
+ * Has controls to email the log (mobile)
+ =========================================================================
+ -->
+ <div id="state-stopped">
+ <h2>Log file written</h2>
+
<if expr="is_ios or is_android">
- Once logging has stopped, click the "Email Log" button to save the
- file. Starting a new log will overwrite the old one.
+ <button id="mobile-email">Email Log</button>
</if>
<if expr="not(is_ios or is_android)">
- Once logging has stopped, attach the log file to the bug report.
+ <button id="show-file">Show File</button>
</if>
- </p>
- <p>
- <!-- TODO(rayraymond): Change link to that of new standalone webapp.
- See http://crbug.com/472699 -->
- Log files can be loaded using
- <a href="chrome://net-internals#import" target="_blank">net-internals</a>.
- </p>
- <p>
- <b><span class="warning">WARNING</span></b>: Logs contain a list of sites
- visited from when logging started to when logging stopped. They may also
- contain general network configuration information, such as DNS and proxy
- configuration. If private information is not stripped, the logs also
- contain cookies and credentials.
- </p>
- <p>
- <b>ADVANCED</b>:
- <span class="warning">This section should normally be left alone.</span>
- <div class="radio-button-div">
- <label>
- <input id="export-view-strip-private-data-button" type="radio"
- name="log-mode" value="STRIP_PRIVATE_DATA" checked disabled>
- Strip private information
- </label>
+
+ <button id="startover">
+ Start Over
+ </button>
+
+ <div class="section-container">
+ <if expr="is_ios or is_android">
+ Share the log by emailing it, and you are done!
+ </if>
+
+ <if expr="not(is_ios or is_android)">
+ Attach the log file to your bug report, and you are done!
+ </if>
+ </div>
+
+ <!-- TODO(eroman): This is duplicated with the logging state -->
+ <div class="outline-box">
+ <b>FILE:</b> <span id="file-path-stopped"></span> <br/>
+ <b>OPTIONS:</b> <span id="capture-mode-stopped"></span>
</div>
- <div class="radio-button-div">
- <label>
- <input id="export-view-include-private-data-button" type="radio"
- name="log-mode" value="NORMAL" disabled>
- Include cookies and credentials
- </label>
+
+ <div class="section-container">
+ <!-- TODO(rayraymond): Change link to that of new standalone webapp.
+ See http://crbug.com/472699 -->
+ The log file can also be loaded using
+ <a href="chrome://net-internals#import"
+ target="_blank">net-internals</a>.
</div>
- <div class="radio-button-div">
- <label>
- <input id="export-view-log-bytes-button" type="radio"
- name="log-mode" value="LOG_BYTES" disabled>
- Include raw bytes (will include cookies and credentials)
- </label>
+
+ <div class="section-container">
+ <b><span class="warning">PRIVACY</span></b>: Be aware when
+ sharing your network logs that they may contain private information. At
+ a minimum, they list the URLs and hostnames of sites visited while
+ logging was enabled.
+ <a href="#" id="privacy-read-more-link">Read more...</a>
+
+ <div id="privacy-read-more">
+ <ul>
+ <li>There may be some cached hostnames/URLs from sites visited prior
+ to enabling logging.</li>
+ <li>Logs may contain information about your networking environment,
+ such as the proxy configuration used.</li>
+ <li>The default logging options do a <i>best-effort</i> stripping of
+ any cookies/credentials in the logged requests.</li>
+ </ul>
+ </div>
</div>
- </p>
+ </div>
</div>
- <pre id="export-view-file-path-text"></pre>
</body>
</html>
diff --git a/chromium/components/net_log/resources/net_export.js b/chromium/components/net_log/resources/net_export.js
index 3ea73c575b6..be7c8e24f51 100644
--- a/chromium/components/net_log/resources/net_export.js
+++ b/chromium/components/net_log/resources/net_export.js
@@ -12,7 +12,7 @@ function onLoad() {
document.addEventListener('DOMContentLoaded', onLoad);
/**
- * This class handles the presentation of our profiler view. Used as a
+ * This class handles the presentation of the net-export view. Used as a
* singleton.
*/
var NetExportView = (function() {
@@ -20,18 +20,31 @@ var NetExportView = (function() {
// --------------------------------------------------------------------------
+ var kIdStateDivUninitialized = 'state-uninitialized';
+ var kIdStateDivInitial = 'state-initial';
+ var kIdStateDivLogging = 'state-logging';
+ var kIdStateDivStopped = 'state-stopped';
+ var kIdStartLoggingButton = 'start-logging';
+ var kIdStopLoggingButton = 'stop-logging';
+ var kIdEmailLogButton = 'mobile-email';
+ var kIdShowFileButton = 'show-file';
+ var kIdCaptureModeLogging = 'capture-mode-logging';
+ var kIdFilePathLogging = 'file-path-logging';
+ var kIdCaptureModeStopped = 'capture-mode-stopped';
+ var kIdFilePathStoppedLogging = 'file-path-stopped';
+ var kIdStartOverButton = 'startover';
+ var kIdReadMoreLink = 'privacy-read-more-link';
+ var kIdReadMoreDiv = 'privacy-read-more'
+
/**
* @constructor
*/
function NetExportView() {
- $('export-view-start-data').onclick = this.onStartData_.bind(this);
- $('export-view-stop-data').onclick = this.onStopData_.bind(this);
- if (this.useMobileUI_())
- $('export-view-mobile-send-data').onclick = this.onSendData_.bind(this);
-
// Tell NetExportMessageHandler to notify the UI of future state changes
// from this point on (through onExportNetLogInfoChanged()).
chrome.send('enableNotifyUIWithState');
+
+ this.infoForLoggedFile_ = null;
}
cr.addSingletonGetter(NetExportView);
@@ -40,7 +53,7 @@ var NetExportView = (function() {
/**
* Starts saving NetLog data to a file.
*/
- onStartData_: function() {
+ onStartLogging_: function() {
var logMode =
document.querySelector('input[name="log-mode"]:checked').value;
chrome.send('startNetLog', [logMode]);
@@ -49,85 +62,201 @@ var NetExportView = (function() {
/**
* Stops saving NetLog data to a file.
*/
- onStopData_: function() {
+ onStopLogging_: function() {
chrome.send('stopNetLog');
},
/**
- * Sends NetLog data via email from browser.
+ * Sends NetLog data via email from browser (mobile only).
*/
- onSendData_: function() {
+ onSendEmail_: function() {
chrome.send('sendNetLog');
},
/**
- * Updates the UI to reflect the current state. Displays the path name of
- * the file where NetLog data is collected.
+ * Reveals the log file in the shell (i.e. selects it in the Finder on
+ * Mac).
*/
- onExportNetLogInfoChanged: function(exportNetLogInfo) {
- if (exportNetLogInfo.file) {
- var message = '';
- if (exportNetLogInfo.state == 'LOGGING')
- message = 'NetLog data is collected in: ';
- else if (exportNetLogInfo.logType != 'NONE')
- message = 'NetLog data to send is in: ';
- $('export-view-file-path-text').textContent =
- message + exportNetLogInfo.file;
- } else {
- $('export-view-file-path-text').textContent = '';
- }
+ onShowFile_: function() {
+ chrome.send('showFile');
+ },
- // Disable all controls. Useable controls are enabled below.
- var controls = document.querySelectorAll('button, input');
- for (var i = 0; i < controls.length; ++i) {
- controls[i].disabled = true;
- }
+ /**
+ * Transitions back to the "Start logging to disk" state.
+ */
+ onStartOver_: function() {
+ this.infoForLoggedFile_ = null;
+ this.renderInitial_();
+ },
- if (this.useMobileUI_()) {
- $('export-view-mobile-deletes-log-text').hidden = true;
- $('export-view-mobile-private-data-text').hidden = true;
- $('export-view-mobile-send-old-log-text').hidden = true;
- }
+ /**
+ * Updates the UI to reflect the current state. The state transitions are
+ * sent by the browser controller (NetLogFileWriter):
+ *
+ * * UNINITIALIZED - This is the initial state when net-export is opened
+ * for the first time, or there was an error during initialization.
+ * This state is short-lived and likely not observed; will
+ * immediately transition to INITIALIZING).
+ *
+ * * INITIALIZING - On desktop UI this is pretty much a no-op. On the
+ * mobile UI, this state is when the controller checks the disk for
+ * a previous net-log file (from past run of the browser). After
+ * success will transition to NOT_LOGGING. On failure will
+ * transition to UNINITIALIZED (rare).
+ *
+ * * NOT_LOGGING - This is the steady-state. It means initialization
+ * completed and we are not currently logging. Being in this state
+ * either means:
+ * (1) We were logging and then the user stopped (earlier states
+ * were STATE_LOGGING / STATE_STOPPING_LOG).
+ * (2) We have never started logging (previous state was
+ * INITIALIZING).
+ *
+ * * STARTING_LOG - This state means the user has clicked the "Start log"
+ * button and logging is about to get started (files may not have
+ * been created yet).
+ *
+ * * LOGGING - This state means that logging is currently in progress.
+ * The destination path of the log, and the capture mode are known
+ * and will be reflected in the parameters.
+ *
+ * * STOPPING_LOG - This state means the user has clicked the "Stop
+ * logging" button, and the log file is in the process of being
+ * finalized. Once the state transitions to NOT_LOGGING then the log
+ * is complete, and can safely be copied/emailed.
+ */
+ onExportNetLogInfoChanged: function(info) {
+ switch (info.state) {
+ case 'UNINITIALIZED':
+ case 'INITIALIZING':
+ this.renderUninitialized_();
+ break;
- if (exportNetLogInfo.state == 'NOT_LOGGING') {
- // Allow making a new log.
- $('export-view-strip-private-data-button').disabled = false;
- $('export-view-include-private-data-button').disabled = false;
- $('export-view-log-bytes-button').disabled = false;
- $('export-view-start-data').disabled = false;
-
- // If there's a pre-existing log, allow sending it (this only
- // applies to the mobile UI).
- if (this.useMobileUI_() && exportNetLogInfo.logExists) {
- $('export-view-mobile-deletes-log-text').hidden = false;
- $('export-view-mobile-send-data').disabled = false;
- if (!exportNetLogInfo.logCaptureModeKnown) {
- $('export-view-mobile-send-old-log-text').hidden = false;
- } else if (exportNetLogInfo.captureMode != 'STRIP_PRIVATE_DATA') {
- $('export-view-mobile-private-data-text').hidden = false;
+ case 'NOT_LOGGING':
+ if (this.infoForLoggedFile_) {
+ // There is no "stopped logging" state. We manufacture that in the
+ // UI in response to a transition from LOGGING --> NOT_LOGGING.
+ this.renderStoppedLogging_(this.infoForLoggedFile_);
+
+ // TODO(eroman): prevent future state transitions. In desktop UI
+ // could start logging in a new tab, and it would reset this one.
+ } else if (info.logExists) {
+ // In the mobile UI, initialization may have found a
+ // pre-existing log file.
+ this.renderStoppedLogging_(info);
+ } else {
+ this.renderInitial_();
}
- }
- } else if (exportNetLogInfo.state == 'LOGGING') {
- // Only possible to stop logging. Radio buttons reflects current state.
- document
- .querySelector(
- 'input[name="log-mode"][value="' +
- exportNetLogInfo.captureMode + '"]')
- .checked = true;
- $('export-view-stop-data').disabled = false;
- } else if (exportNetLogInfo.state == 'UNINITIALIZED') {
- $('export-view-file-path-text').textContent =
- 'Unable to initialize NetLog data file.';
+ break;
+
+ case 'STARTING_LOG':
+ // This is a short-lived state, no need to do anything special.
+ // Disabling the buttons would be nice, however it is not crucial as
+ // the controller will reject commands while in this state anyway.
+ this.renderInitial_();
+ break;
+
+ case 'LOGGING':
+ // Cache the last information for this logging session, so once
+ // logging is stopped will know what path information to display.
+ this.infoForLoggedFile_ = info;
+ this.renderLogging_(info);
+ break;
+
+ case 'STOPPING_LOG':
+ // This is a short-lived state, no need to do anything special.
+ this.renderLogging_(info);
+ break;
}
},
+ /**
+ * Updates the UI to display the "uninitialized" state. This is only
+ * visible for a short period of time, or longer if initialization failed
+ * (and didn't transition to a different state).
+ */
+ renderUninitialized_: function() {
+ this.showStateDiv_(kIdStateDivUninitialized);
+ },
+
+ /**
+ * Updates the UI to display the "initial" state. This is the state when
+ * logging has not been started yet, and there are controls to start
+ * logging.
+ */
+ renderInitial_: function() {
+ this.showStateDiv_(kIdStateDivInitial);
+ $(kIdStartLoggingButton).onclick = this.onStartLogging_.bind(this);
+ },
+
+ /**
+ * Updates the UI to display the "logging" state. This is the state while
+ * capturing is in progress and being written to disk.
+ */
+ renderLogging_: function(info) {
+ this.showStateDiv_(kIdStateDivLogging);
+
+ $(kIdStopLoggingButton).onclick = this.onStopLogging_.bind(this);
+ $(kIdCaptureModeLogging).textContent = this.getCaptureModeText_(info);
+ $(kIdFilePathLogging).textContent = info.file;
+ },
+
/*
- * Returns true if the UI is being displayed for mobile, otherwise false
- * for desktop. This is controlled by the HTML template.
+ * Updates the UI to display the state when logging has stopped.
+ */
+ renderStoppedLogging_: function(info) {
+ this.showStateDiv_(kIdStateDivStopped);
+
+ // The email button is only available in the mobile UI.
+ if ($(kIdEmailLogButton))
+ $(kIdEmailLogButton).onclick = this.onSendEmail_.bind(this);
+ // The show file button is only available in the desktop UI.
+ if ($(kIdShowFileButton))
+ $(kIdShowFileButton).onclick = this.onShowFile_.bind(this);
+ $(kIdStartOverButton).onclick = this.onStartOver_.bind(this);
+
+ $(kIdFilePathStoppedLogging).textContent = info.file;
+
+ $(kIdCaptureModeStopped).textContent = this.getCaptureModeText_(info);
+
+ // Hook up the "read more..." link for privacy information.
+ $(kIdReadMoreLink).onclick = this.showPrivacyReadMore_.bind(this, true);
+ this.showPrivacyReadMore_(false);
+ },
+
+ /**
+ * Gets the textual label for a capture mode from the HTML.
*/
- useMobileUI_: function() {
- return !!document.getElementById('export-view-mobile-send-data');
- }
+ getCaptureModeText_: function(info) {
+ // TODO(eroman): Should not hardcode "Unknown" (will not work properly if
+ // the HTML is internationalized).
+ if (!info.logCaptureModeKnown)
+ return "Unknown";
+
+ var radioButton = document.querySelector(
+ 'input[name="log-mode"][value="' + info.captureMode + '"]');
+ if (!radioButton)
+ return 'Unknown';
+ return radioButton.parentElement.textContent;
+ },
+
+ showPrivacyReadMore_: function(show) {
+ $(kIdReadMoreDiv).hidden = !show;
+ $(kIdReadMoreLink).hidden = show;
+ },
+
+ showStateDiv_: function(divId) {
+ var kAllDivIds = [
+ kIdStateDivUninitialized,
+ kIdStateDivInitial,
+ kIdStateDivLogging,
+ kIdStateDivStopped
+ ];
+
+ for (var curDivId of kAllDivIds) {
+ $(curDivId).hidden = divId != curDivId;
+ }
+ },
};
return NetExportView;
diff --git a/chromium/components/neterror/resources/neterror.html b/chromium/components/neterror/resources/neterror.html
index e3c30325b36..3851e4fee73 100644
--- a/chromium/components/neterror/resources/neterror.html
+++ b/chromium/components/neterror/resources/neterror.html
@@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no">
<title i18n-content="title"></title>
+ <link rel="stylesheet" href="../../../components/security_interstitials/core/browser/resources/interstitial_common.css">
<link rel="stylesheet" href="../../../components/security_interstitials/core/browser/resources/interstitial_v2.css">
<link rel="stylesheet" href="neterror.css">
<script src="../../../components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js"></script>
diff --git a/chromium/components/network_session_configurator/network_session_configurator.cc b/chromium/components/network_session_configurator/network_session_configurator.cc
index 00ab3d3c34f..e885f4ae809 100644
--- a/chromium/components/network_session_configurator/network_session_configurator.cc
+++ b/chromium/components/network_session_configurator/network_session_configurator.cc
@@ -18,7 +18,7 @@
#include "net/http/http_stream_factory.h"
#include "net/quic/chromium/quic_utils_chromium.h"
#include "net/quic/core/quic_packets.h"
-#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/core/spdy_protocol.h"
#include "net/url_request/url_fetcher.h"
namespace {
@@ -123,21 +123,6 @@ bool ShouldRetryWithoutAltSvcOnQuicErrors(
"true");
}
-bool ShouldQuicDisableConnectionPooling(
- const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "disable_connection_pooling"),
- "true");
-}
-
-bool ShouldQuicEnableAlternativeServicesForDifferentHost(
- const VariationParameters& quic_trial_params) {
- return !base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params,
- "enable_alternative_service_with_different_host"),
- "false");
-}
-
net::QuicTagVector GetQuicConnectionOptions(
const VariationParameters& quic_trial_params) {
VariationParameters::const_iterator it =
@@ -149,68 +134,11 @@ net::QuicTagVector GetQuicConnectionOptions(
return net::ParseQuicConnectionOptions(it->second);
}
-bool ShouldQuicAlwaysRequireHandshakeConfirmation(
- const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params,
- "always_require_handshake_confirmation"),
- "true");
-}
-
-float GetQuicLoadServerInfoTimeoutSrttMultiplier(
- const VariationParameters& quic_trial_params) {
- double value;
- if (base::StringToDouble(
- GetVariationParam(quic_trial_params, "load_server_info_time_to_srtt"),
- &value)) {
- return static_cast<float>(value);
- }
- return 0.0f;
-}
-
-bool ShouldQuicEnableConnectionRacing(
- const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "enable_connection_racing"), "true");
-}
-
-bool ShouldQuicEnableNonBlockingIO(
- const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "enable_non_blocking_io"), "true");
-}
-
-bool ShouldQuicDisableDiskCache(const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "disable_disk_cache"), "true");
-}
-
-bool ShouldQuicPreferAes(const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "prefer_aes"), "true");
-}
-
bool ShouldForceHolBlocking(const VariationParameters& quic_trial_params) {
return base::LowerCaseEqualsASCII(
GetVariationParam(quic_trial_params, "force_hol_blocking"), "true");
}
-int GetQuicSocketReceiveBufferSize(
- const VariationParameters& quic_trial_params) {
- int value;
- if (base::StringToInt(
- GetVariationParam(quic_trial_params, "receive_buffer_size"),
- &value)) {
- return value;
- }
- return 0;
-}
-
-bool ShouldQuicDelayTcpRace(const VariationParameters& quic_trial_params) {
- return !base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "disable_delay_tcp_race"), "true");
-}
-
bool ShouldQuicCloseSessionsOnIpChange(
const VariationParameters& quic_trial_params) {
return base::LowerCaseEqualsASCII(
@@ -269,25 +197,6 @@ bool ShouldQuicEstimateInitialRtt(
GetVariationParam(quic_trial_params, "estimate_initial_rtt"), "true");
}
-bool ShouldQuicDisablePreConnectIfZeroRtt(
- const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "disable_preconnect_if_0rtt"),
- "true");
-}
-
-std::unordered_set<std::string> GetQuicHostWhitelist(
- const VariationParameters& quic_trial_params) {
- std::string whitelist =
- GetVariationParam(quic_trial_params, "quic_host_whitelist");
- std::unordered_set<std::string> hosts;
- for (const std::string& host : base::SplitString(
- whitelist, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
- hosts.insert(host);
- }
- return hosts;
-}
-
bool ShouldQuicMigrateSessionsOnNetworkChange(
const VariationParameters& quic_trial_params) {
return base::LowerCaseEqualsASCII(
@@ -310,14 +219,6 @@ bool ShouldQuicAllowServerMigration(
"true");
}
-bool ShouldQuicDoNotMarkAsBrokenOnNetworkChange(
- const VariationParameters& quic_trial_params) {
- return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params,
- "do_not_mark_as_broken_on_network_change"),
- "true");
-}
-
size_t GetQuicMaxPacketLength(const VariationParameters& quic_trial_params) {
unsigned value;
if (base::StringToUint(
@@ -332,6 +233,13 @@ net::QuicVersion GetQuicVersion(const VariationParameters& quic_trial_params) {
GetVariationParam(quic_trial_params, "quic_version"));
}
+bool ShouldEnableServerPushCancelation(
+ const VariationParameters& quic_trial_params) {
+ return base::LowerCaseEqualsASCII(
+ GetVariationParam(quic_trial_params, "enable_server_push_cancellation"),
+ "true");
+}
+
void ConfigureQuicParams(base::StringPiece quic_trial_group,
const VariationParameters& quic_trial_params,
bool is_quic_force_disabled,
@@ -343,34 +251,14 @@ void ConfigureQuicParams(base::StringPiece quic_trial_group,
is_quic_force_enabled);
params->mark_quic_broken_when_network_blackholes =
ShouldMarkQuicBrokenWhenNetworkBlackholes(quic_trial_params);
+
+ params->enable_server_push_cancellation =
+ ShouldEnableServerPushCancelation(quic_trial_params);
+
params->retry_without_alt_svc_on_quic_errors =
ShouldRetryWithoutAltSvcOnQuicErrors(quic_trial_params);
- params->enable_quic_alternative_service_with_different_host =
- ShouldQuicEnableAlternativeServicesForDifferentHost(quic_trial_params);
if (params->enable_quic) {
- params->quic_always_require_handshake_confirmation =
- ShouldQuicAlwaysRequireHandshakeConfirmation(quic_trial_params);
- params->quic_disable_connection_pooling =
- ShouldQuicDisableConnectionPooling(quic_trial_params);
- int receive_buffer_size = GetQuicSocketReceiveBufferSize(quic_trial_params);
- if (receive_buffer_size != 0) {
- params->quic_socket_receive_buffer_size = receive_buffer_size;
- }
- params->quic_delay_tcp_race = ShouldQuicDelayTcpRace(quic_trial_params);
- float load_server_info_timeout_srtt_multiplier =
- GetQuicLoadServerInfoTimeoutSrttMultiplier(quic_trial_params);
- if (load_server_info_timeout_srtt_multiplier != 0) {
- params->quic_load_server_info_timeout_srtt_multiplier =
- load_server_info_timeout_srtt_multiplier;
- }
- params->quic_enable_connection_racing =
- ShouldQuicEnableConnectionRacing(quic_trial_params);
- params->quic_enable_non_blocking_io =
- ShouldQuicEnableNonBlockingIO(quic_trial_params);
- params->quic_disable_disk_cache =
- ShouldQuicDisableDiskCache(quic_trial_params);
- params->quic_prefer_aes = ShouldQuicPreferAes(quic_trial_params);
params->quic_force_hol_blocking = ShouldForceHolBlocking(quic_trial_params);
params->quic_connection_options =
GetQuicConnectionOptions(quic_trial_params);
@@ -400,17 +288,12 @@ void ConfigureQuicParams(base::StringPiece quic_trial_group,
ShouldQuicDoNotFragment(quic_trial_params);
params->quic_estimate_initial_rtt =
ShouldQuicEstimateInitialRtt(quic_trial_params);
- params->quic_disable_preconnect_if_0rtt =
- ShouldQuicDisablePreConnectIfZeroRtt(quic_trial_params);
- params->quic_host_whitelist = GetQuicHostWhitelist(quic_trial_params);
params->quic_migrate_sessions_on_network_change =
ShouldQuicMigrateSessionsOnNetworkChange(quic_trial_params);
params->quic_migrate_sessions_early =
ShouldQuicMigrateSessionsEarly(quic_trial_params);
params->quic_allow_server_migration =
ShouldQuicAllowServerMigration(quic_trial_params);
- params->quic_do_not_mark_as_broken_on_network_change =
- ShouldQuicDoNotMarkAsBrokenOnNetworkChange(quic_trial_params);
}
size_t max_packet_length = GetQuicMaxPacketLength(quic_trial_params);
@@ -428,14 +311,6 @@ void ConfigureQuicParams(base::StringPiece quic_trial_group,
}
}
-void ConfigureOptimizePreconnectsToProxiesParams(
- const std::map<std::string, std::string>& proxy_preconnects_trial_params,
- net::HttpNetworkSession::Params* params) {
- params->restrict_to_one_preconnect_for_proxies =
- GetVariationParam(proxy_preconnects_trial_params,
- "restrict_to_one_preconnect_for_proxies") == "true";
-}
-
} // anonymous namespace
namespace network_session_configurator {
@@ -476,12 +351,6 @@ void ParseFieldTrials(bool is_quic_force_disabled,
const std::string tfo_trial_group =
base::FieldTrialList::FindFullName(kTCPFastOpenFieldTrialName);
ConfigureTCPFastOpenParams(tfo_trial_group, params);
-
- std::map<std::string, std::string> proxy_preconnects_trial_params;
- variations::GetVariationParams("NetProxyPreconnects",
- &proxy_preconnects_trial_params);
- ConfigureOptimizePreconnectsToProxiesParams(proxy_preconnects_trial_params,
- params);
}
} // namespace network_session_configurator
diff --git a/chromium/components/network_session_configurator/network_session_configurator_unittest.cc b/chromium/components/network_session_configurator/network_session_configurator_unittest.cc
index 799f9ca4023..4fe02d241f0 100644
--- a/chromium/components/network_session_configurator/network_session_configurator_unittest.cc
+++ b/chromium/components/network_session_configurator/network_session_configurator_unittest.cc
@@ -13,7 +13,7 @@
#include "components/variations/variations_associated_data.h"
#include "net/http/http_stream_factory.h"
#include "net/quic/core/quic_packets.h"
-#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/core/spdy_protocol.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace test {
@@ -49,7 +49,6 @@ TEST_F(NetworkSessionConfiguratorTest, Defaults) {
EXPECT_TRUE(params_.enable_http2);
EXPECT_TRUE(params_.http2_settings.empty());
EXPECT_FALSE(params_.enable_tcp_fast_open_for_ssl);
- EXPECT_TRUE(params_.enable_quic_alternative_service_with_different_host);
EXPECT_FALSE(params_.enable_quic);
}
@@ -71,15 +70,7 @@ TEST_F(NetworkSessionConfiguratorTest, EnableQuicFromFieldTrialGroup) {
EXPECT_FALSE(params_.retry_without_alt_svc_on_quic_errors);
EXPECT_EQ(1350u, params_.quic_max_packet_length);
EXPECT_EQ(net::QuicTagVector(), params_.quic_connection_options);
- EXPECT_FALSE(params_.quic_always_require_handshake_confirmation);
- EXPECT_FALSE(params_.quic_disable_connection_pooling);
- EXPECT_EQ(0.25f, params_.quic_load_server_info_timeout_srtt_multiplier);
- EXPECT_FALSE(params_.quic_enable_connection_racing);
- EXPECT_FALSE(params_.quic_enable_non_blocking_io);
- EXPECT_FALSE(params_.quic_disable_disk_cache);
- EXPECT_FALSE(params_.quic_prefer_aes);
- EXPECT_TRUE(params_.enable_quic_alternative_service_with_different_host);
- EXPECT_TRUE(params_.quic_delay_tcp_race);
+ EXPECT_FALSE(params_.enable_server_push_cancellation);
EXPECT_FALSE(params_.quic_close_sessions_on_ip_change);
EXPECT_EQ(net::kIdleConnectionTimeoutSeconds,
params_.quic_idle_connection_timeout_seconds);
@@ -89,11 +80,9 @@ TEST_F(NetworkSessionConfiguratorTest, EnableQuicFromFieldTrialGroup) {
EXPECT_FALSE(params_.quic_race_cert_verification);
EXPECT_FALSE(params_.quic_do_not_fragment);
EXPECT_FALSE(params_.quic_estimate_initial_rtt);
- EXPECT_FALSE(params_.quic_disable_preconnect_if_0rtt);
EXPECT_FALSE(params_.quic_migrate_sessions_on_network_change);
EXPECT_FALSE(params_.quic_migrate_sessions_early);
EXPECT_FALSE(params_.quic_allow_server_migration);
- EXPECT_TRUE(params_.quic_host_whitelist.empty());
EXPECT_FALSE(params_.quic_force_hol_blocking);
net::HttpNetworkSession::Params default_params;
@@ -222,37 +211,37 @@ TEST_F(NetworkSessionConfiguratorTest, QuicRaceCertVerification) {
EXPECT_TRUE(params_.quic_race_cert_verification);
}
-TEST_F(NetworkSessionConfiguratorTest, QuicDoNotFragment) {
+TEST_F(NetworkSessionConfiguratorTest, EnableServerPushCancellation) {
std::map<std::string, std::string> field_trial_params;
- field_trial_params["do_not_fragment"] = "true";
+ field_trial_params["enable_server_push_cancellation"] = "true";
variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
ParseFieldTrials();
- EXPECT_TRUE(params_.quic_do_not_fragment);
+ EXPECT_TRUE(params_.enable_server_push_cancellation);
}
-TEST_F(NetworkSessionConfiguratorTest, QuicEstimateInitialRtt) {
+TEST_F(NetworkSessionConfiguratorTest, QuicDoNotFragment) {
std::map<std::string, std::string> field_trial_params;
- field_trial_params["estimate_initial_rtt"] = "true";
+ field_trial_params["do_not_fragment"] = "true";
variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
ParseFieldTrials();
- EXPECT_TRUE(params_.quic_estimate_initial_rtt);
+ EXPECT_TRUE(params_.quic_do_not_fragment);
}
-TEST_F(NetworkSessionConfiguratorTest, QuicDisablePreConnectIfZeroRtt) {
+TEST_F(NetworkSessionConfiguratorTest, QuicEstimateInitialRtt) {
std::map<std::string, std::string> field_trial_params;
- field_trial_params["disable_preconnect_if_0rtt"] = "true";
+ field_trial_params["estimate_initial_rtt"] = "true";
variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
ParseFieldTrials();
- EXPECT_TRUE(params_.quic_disable_preconnect_if_0rtt);
+ EXPECT_TRUE(params_.quic_estimate_initial_rtt);
}
TEST_F(NetworkSessionConfiguratorTest,
@@ -346,136 +335,6 @@ TEST_F(NetworkSessionConfiguratorTest, Http2SettingsFromFieldTrialParams) {
EXPECT_EQ(expected_settings, params_.http2_settings);
}
-TEST_F(NetworkSessionConfiguratorTest,
- QuicAlwaysRequireHandshakeConfirmationFromFieldTrialParams) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["always_require_handshake_confirmation"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_TRUE(params_.quic_always_require_handshake_confirmation);
-}
-
-TEST_F(NetworkSessionConfiguratorTest,
- QuicDisableConnectionPoolingFromFieldTrialParams) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["disable_connection_pooling"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_TRUE(params_.quic_disable_connection_pooling);
-}
-
-TEST_F(NetworkSessionConfiguratorTest,
- QuicLoadServerInfoTimeToSmoothedRttFromFieldTrialParams) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["load_server_info_time_to_srtt"] = "0.5";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_EQ(0.5f, params_.quic_load_server_info_timeout_srtt_multiplier);
-}
-
-TEST_F(NetworkSessionConfiguratorTest, QuicEnableConnectionRacing) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["enable_connection_racing"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_TRUE(params_.quic_enable_connection_racing);
-}
-
-TEST_F(NetworkSessionConfiguratorTest, QuicEnableNonBlockingIO) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["enable_non_blocking_io"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_TRUE(params_.quic_enable_non_blocking_io);
-}
-
-TEST_F(NetworkSessionConfiguratorTest, QuicDisableDiskCache) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["disable_disk_cache"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_TRUE(params_.quic_disable_disk_cache);
-}
-
-TEST_F(NetworkSessionConfiguratorTest, QuicPreferAes) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["prefer_aes"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_TRUE(params_.quic_prefer_aes);
-}
-
-TEST_F(NetworkSessionConfiguratorTest,
- QuicEnableAlternativeServicesFromFieldTrialParams) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["enable_alternative_service_with_different_host"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_TRUE(params_.enable_quic_alternative_service_with_different_host);
-}
-
-TEST_F(NetworkSessionConfiguratorTest, QuicReceiveBufferSize) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["receive_buffer_size"] = "2097152";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_EQ(2097152, params_.quic_socket_receive_buffer_size);
-}
-
-TEST_F(NetworkSessionConfiguratorTest, QuicDisableDelayTcpRace) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["disable_delay_tcp_race"] = "true";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_FALSE(params_.quic_delay_tcp_race);
-}
-
-TEST_F(NetworkSessionConfiguratorTest, QuicWhitelistFromParams) {
- std::map<std::string, std::string> field_trial_params;
- field_trial_params["quic_host_whitelist"] =
- "www.example.org, www.example.com";
- variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
- base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
- ParseFieldTrials();
-
- EXPECT_EQ(2u, params_.quic_host_whitelist.size());
- EXPECT_TRUE(
- base::ContainsKey(params_.quic_host_whitelist, "www.example.org"));
- EXPECT_TRUE(
- base::ContainsKey(params_.quic_host_whitelist, "www.example.com"));
-}
-
TEST_F(NetworkSessionConfiguratorTest, TCPFastOpenHttpsEnabled) {
base::FieldTrialList::CreateFieldTrial("TCPFastOpen", "HttpsEnabled");
diff --git a/chromium/components/network_time/network_time_pref_names.cc b/chromium/components/network_time/network_time_pref_names.cc
index a1160e232ef..14e20471186 100644
--- a/chromium/components/network_time/network_time_pref_names.cc
+++ b/chromium/components/network_time/network_time_pref_names.cc
@@ -11,5 +11,9 @@ namespace prefs {
// network time tracker when browser starts.
const char kNetworkTimeMapping[] = "network_time.network_time_mapping";
+// Stores a boolean indicating whether network time queries should be enabled.
+const char kNetworkTimeQueriesEnabled[] =
+ "network_time.network_time_queries_enabled";
+
} // namespace prefs
} // namespace network_time
diff --git a/chromium/components/network_time/network_time_pref_names.h b/chromium/components/network_time/network_time_pref_names.h
index 3476c53109e..9f15b1c20a2 100644
--- a/chromium/components/network_time/network_time_pref_names.h
+++ b/chromium/components/network_time/network_time_pref_names.h
@@ -10,6 +10,8 @@ namespace prefs {
extern const char kNetworkTimeMapping[];
+extern const char kNetworkTimeQueriesEnabled[];
+
} // namespace prefs
} // namespace network_time
diff --git a/chromium/components/network_time/network_time_tracker.cc b/chromium/components/network_time/network_time_tracker.cc
index b5d8ccb8538..56331529789 100644
--- a/chromium/components/network_time/network_time_tracker.cc
+++ b/chromium/components/network_time/network_time_tracker.cc
@@ -191,6 +191,7 @@ void RecordFetchValidHistogram(bool valid) {
void NetworkTimeTracker::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(prefs::kNetworkTimeMapping,
base::MakeUnique<base::DictionaryValue>());
+ registry->RegisterBooleanPref(prefs::kNetworkTimeQueriesEnabled, true);
}
NetworkTimeTracker::NetworkTimeTracker(
@@ -478,7 +479,11 @@ void NetworkTimeTracker::CheckTime() {
policy {
cookies_allowed: false
setting: "This feature cannot be disabled by settings."
- policy_exception_justification: "Not implemented."
+ chrome_policy {
+ NetworkTimeQueriesEnabled {
+ NetworkTimeQueriesEnabled: false
+ }
+ }
})");
// This cancels any outstanding fetch.
time_fetcher_ = net::URLFetcher::Create(url, net::URLFetcher::GET, this,
@@ -621,6 +626,11 @@ bool NetworkTimeTracker::ShouldIssueTimeQuery() {
return false;
}
+ // Do not query the time service if queries are disabled by policy.
+ if (!pref_service_->GetBoolean(prefs::kNetworkTimeQueriesEnabled)) {
+ return false;
+ }
+
// If GetNetworkTime() does not return NETWORK_TIME_AVAILABLE,
// synchronization has been lost and a query is needed.
base::Time network_time;
diff --git a/chromium/components/network_time/network_time_tracker_unittest.cc b/chromium/components/network_time/network_time_tracker_unittest.cc
index 899d190ec9f..07b52060e37 100644
--- a/chromium/components/network_time/network_time_tracker_unittest.cc
+++ b/chromium/components/network_time/network_time_tracker_unittest.cc
@@ -10,6 +10,7 @@
#include "base/compiler_specific.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/histogram_tester.h"
diff --git a/chromium/components/new_or_sad_tab_strings.grdp b/chromium/components/new_or_sad_tab_strings.grdp
index 03b87efbe7a..ca8f3c6db3d 100644
--- a/chromium/components/new_or_sad_tab_strings.grdp
+++ b/chromium/components/new_or_sad_tab_strings.grdp
@@ -25,13 +25,13 @@
<message name="IDS_SAD_TAB_HELP_MESSAGE" desc="The help message displayed on the sad tab page, with IDS_SAD_TAB_HELP_LINK embedded as a link to help.">
If you're seeing this frequently, try these <ph name="HELP_LINK">$1<ex>suggestions</ex></ph>.
</message>
- <message name="IDS_SAD_TAB_HELP_LINK" desc="The link text displayed on the sad tab page pointing the users to a help article.">
+ <message name="IDS_SAD_TAB_HELP_LINK" desc="The link text displayed on the sad tab page linking the user to a help article.">
suggestions
</message>
<message name="IDS_SAD_TAB_RELOAD_LABEL" desc="Button label in the sad tab page for reloading a page." formatter_data="android_java">
Reload
</message>
- <if expr="is_android">
+ <if expr="is_android or is_ios">
<message name="IDS_SAD_TAB_SEND_FEEDBACK_LABEL" desc="Button label in the sad tab page for sending feedback. This label replaces the reload button after a crash happens twice in a row." formatter_data="android_java">
Send Feedback
</message>
@@ -98,7 +98,7 @@
Restart Chromium
</message>
</if>
- <if expr="is_win or is_linux or is_maxosx or chromeos">
+ <if expr="is_win or is_linux or is_macosx or chromeos">
<message name="IDS_SAD_TAB_RELOAD_RESTART_DEVICE" desc="One of the bullet points displayed on the web page if a reload failed to fix the issue, advising the user to restart their computer." formatter_data="android_java">
Restart your computer
</message>
@@ -108,6 +108,11 @@
Restart your device
</message>
</if>
+ <if expr="is_android or is_ios">
+ <message name="IDS_SAD_TAB_RELOAD_LEARN_MORE" desc="The link text displayed on the sad tab page pointing the users to a help article if a reload failed to fix the issue." meaning="Learn more about web pages that fail to load" formatter_data="android_java">
+ Learn more
+ </message>
+ </if>
<message name="IDS_SAD_TAB_UMA_OPTIN" desc="Text that appears next to a checkbox, allowing the user to opt-in to sending statistics about their Chrome browser usage and reports of crashes to Google." formatter_data="android_java">
Automatically send usage statistics and crash reports to Google
</message>
@@ -143,20 +148,21 @@
<!-- Incognito Tab redesign strings -->
<!-- TODO(msramek): Merge with the above section once this is fully launched. -->
- <message name="IDS_NEW_TAB_OTR_TITLE" desc="Title of the Incognito new tab page. The Incognito mode provides private browsing experience by hiding browsing activity from other people using the same device. However, it does not make the user completely invisible or anonymous; please don't translate it as such." formatter_data="android_java" translateable="false">
+ <message name="IDS_NEW_TAB_OTR_TITLE" desc="Title of the Incognito new tab page. The Incognito mode provides private browsing experience by hiding browsing activity from other people using the same device. However, it does not make the user completely invisible or anonymous; please don't translate it as such." formatter_data="android_java">
You’ve gone incognito
</message>
- <message name="IDS_NEW_TAB_OTR_SUBTITLE" desc="Subtitle of the Incognito new tab page, explaining to the user that the Incognito mode hides their browsing activity from other people using the same device. The second sentence clarifies that there are two important exceptions from this rule - downloaded files and added bookmarks will be persisted even after the Incognito session is closed." formatter_data="android_java" translateable="false">
+ <message name="IDS_NEW_TAB_OTR_SUBTITLE" desc="Subtitle of the Incognito new tab page, explaining to the user that the Incognito mode hides their browsing activity from other people using the same device. The second sentence clarifies that there are two important exceptions from this rule - downloaded files and added bookmarks will be persisted even after the Incognito session is closed." formatter_data="android_java">
Now you can browse privately, and other people who use this device won’t see your activity. However, downloads and bookmarks will be saved.
</message>
- <message name="IDS_NEW_TAB_OTR_NOT_SAVED" desc="Bullet points listing data that are not saved in the Incognito mode. 'Browsing history' means a history of visited websites. 'Cookies and site data' refers to data saved by websites on the user's device (e.g. sign-in state, preferences, etc.)." formatter_data="android_java" translateable="false">
+ <message name="IDS_NEW_TAB_OTR_NOT_SAVED" desc="Bullet points listing data that are not saved in the Incognito mode. 'Browsing history' means a history of visited websites. 'Cookies and site data' refers to data saved by websites on the user's device (e.g. sign-in state, preferences, etc.). 'Information entered in forms' refers to names, addresses, passwords etc. that users enter into forms on the web." formatter_data="android_java">
Chrome <ph name="BEGIN_EMPHASIS">&lt;em&gt;</ph>won’t save<ph name="END_EMPHASIS">&lt;/em&gt;</ph> the following information:
<ph name="BEGIN_LIST">&lt;ul&gt;</ph>
<ph name="LIST_ITEM">&lt;li&gt;</ph>Your browsing history
<ph name="LIST_ITEM">&lt;li&gt;</ph>Cookies and site data
+ <ph name="LIST_ITEM">&lt;li&gt;</ph>Information entered in forms
<ph name="END_LIST">&lt;/ul&gt;</ph>
</message>
- <message name="IDS_NEW_TAB_OTR_VISIBLE" desc="Bullet points listing entities that might be able to see the user's Incognito activity. The bullet points elaborate on the fact that Incognito only provides privacy with respect to other users on the same device. Websites you visit still know that you visited them. Your employer, school, and/or internet service provider can still monitor network traffic, even if it comes from the Incognito mode." formatter_data="android_java" translateable="false">
+ <message name="IDS_NEW_TAB_OTR_VISIBLE" desc="Bullet points listing entities that might be able to see the user's Incognito activity. The bullet points elaborate on the fact that Incognito only provides privacy with respect to other users on the same device. Websites you visit still know that you visited them. Your employer, school, and/or internet service provider can still monitor network traffic, even if it comes from the Incognito mode." formatter_data="android_java">
Your activity <ph name="BEGIN_EMPHASIS">&lt;em&gt;</ph>might still be visible<ph name="END_EMPHASIS">&lt;/em&gt;</ph> to:
<ph name="BEGIN_LIST">&lt;ul&gt;</ph>
<ph name="LIST_ITEM">&lt;li&gt;</ph>Websites you visit
diff --git a/chromium/components/ntp_snippets/BUILD.gn b/chromium/components/ntp_snippets/BUILD.gn
index 0cf1874adc8..54a66cf3d0e 100644
--- a/chromium/components/ntp_snippets/BUILD.gn
+++ b/chromium/components/ntp_snippets/BUILD.gn
@@ -47,8 +47,6 @@ static_library("ntp_snippets") {
"pref_names.h",
"pref_util.cc",
"pref_util.h",
- "reading_list/reading_list_distillation_state_util.cc",
- "reading_list/reading_list_distillation_state_util.h",
"reading_list/reading_list_suggestions_provider.cc",
"reading_list/reading_list_suggestions_provider.h",
"remote/json_request.cc",
diff --git a/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc b/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
index 436e8bcee05..9b0e2df80d3 100644
--- a/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
+++ b/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
@@ -18,9 +18,6 @@
#include "components/ntp_snippets/category.h"
#include "components/ntp_snippets/content_suggestion.h"
#include "components/ntp_snippets/features.h"
-#include "components/ntp_snippets/pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/variations/variations_associated_data.h"
#include "ui/base/l10n/l10n_util.h"
@@ -34,17 +31,13 @@ namespace ntp_snippets {
namespace {
const int kMaxBookmarks = 10;
-const int kMaxBookmarkAgeInDays = 42;
+const int kMaxBookmarkAgeInDays = 7;
const char* kMaxBookmarksParamName = "bookmarks_max_count";
const char* kMaxBookmarkAgeInDaysParamName = "bookmarks_max_age_in_days";
const char* kConsiderDesktopVisitsParamName =
"bookmarks_consider_desktop_visits";
-// TODO(treib,jkrcal): Remove this after M57.
-const char kDeprecatedBookmarksFirstM54StartPref[] =
- "ntp_suggestions.bookmarks.first_M54_start";
-
// Any bookmark created or visited after this time will be considered recent.
// Note that bookmarks can be shown that do not meet this threshold.
base::Time GetThresholdTime() {
@@ -64,15 +57,14 @@ int GetMaxCount() {
bool AreDesktopVisitsConsidered() {
return variations::GetVariationParamByFeatureAsBool(
ntp_snippets::kBookmarkSuggestionsFeature,
- kConsiderDesktopVisitsParamName, false);
+ kConsiderDesktopVisitsParamName, true);
}
} // namespace
BookmarkSuggestionsProvider::BookmarkSuggestionsProvider(
ContentSuggestionsProvider::Observer* observer,
- bookmarks::BookmarkModel* bookmark_model,
- PrefService* pref_service)
+ bookmarks::BookmarkModel* bookmark_model)
: ContentSuggestionsProvider(observer),
category_status_(CategoryStatus::AVAILABLE_LOADING),
provided_category_(
@@ -82,7 +74,6 @@ BookmarkSuggestionsProvider::BookmarkSuggestionsProvider(
end_of_list_last_visit_date_(GetThresholdTime()),
consider_bookmark_visits_from_desktop_(AreDesktopVisitsConsidered()) {
observer->OnCategoryStatusChanged(this, provided_category_, category_status_);
- pref_service->ClearPref(kDeprecatedBookmarksFirstM54StartPref);
bookmark_model_->AddObserver(this);
FetchBookmarks();
}
@@ -91,12 +82,6 @@ BookmarkSuggestionsProvider::~BookmarkSuggestionsProvider() {
bookmark_model_->RemoveObserver(this);
}
-// static
-void BookmarkSuggestionsProvider::RegisterProfilePrefs(
- PrefRegistrySimple* registry) {
- registry->RegisterInt64Pref(kDeprecatedBookmarksFirstM54StartPref, 0);
-}
-
////////////////////////////////////////////////////////////////////////////////
// Private methods
diff --git a/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h b/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h
index 64cd6e25d1a..404c8d6ada2 100644
--- a/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h
+++ b/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h
@@ -15,9 +15,6 @@
#include "components/ntp_snippets/category_status.h"
#include "components/ntp_snippets/content_suggestions_provider.h"
-class PrefRegistrySimple;
-class PrefService;
-
namespace ntp_snippets {
// Provides content suggestions from the bookmarks model.
@@ -25,12 +22,9 @@ class BookmarkSuggestionsProvider : public ContentSuggestionsProvider,
public bookmarks::BookmarkModelObserver {
public:
BookmarkSuggestionsProvider(ContentSuggestionsProvider::Observer* observer,
- bookmarks::BookmarkModel* bookmark_model,
- PrefService* pref_service);
+ bookmarks::BookmarkModel* bookmark_model);
~BookmarkSuggestionsProvider() override;
- static void RegisterProfilePrefs(PrefRegistrySimple* registry);
-
private:
// ContentSuggestionsProvider implementation.
CategoryStatus GetCategoryStatus(Category category) override;
diff --git a/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc b/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc
index 92682d579b7..fda7b18c941 100644
--- a/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc
+++ b/chromium/components/ntp_snippets/bookmarks/bookmark_suggestions_provider_unittest.cc
@@ -18,7 +18,6 @@
#include "components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h"
#include "components/ntp_snippets/category.h"
#include "components/ntp_snippets/mock_content_suggestions_provider_observer.h"
-#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -53,15 +52,13 @@ class BookmarkSuggestionsProviderTest : public ::testing::Test {
_, Category::FromKnownCategory(KnownCategories::BOOKMARKS),
CategoryStatus::AVAILABLE))
.RetiresOnSaturation();
- BookmarkSuggestionsProvider::RegisterProfilePrefs(test_prefs_.registry());
- provider_ = base::MakeUnique<BookmarkSuggestionsProvider>(
- &observer_, model_.get(), &test_prefs_);
+ provider_ =
+ base::MakeUnique<BookmarkSuggestionsProvider>(&observer_, model_.get());
}
protected:
std::unique_ptr<bookmarks::BookmarkModel> model_;
StrictMock<MockContentSuggestionsProviderObserver> observer_;
- TestingPrefServiceSimple test_prefs_;
std::unique_ptr<BookmarkSuggestionsProvider> provider_;
};
diff --git a/chromium/components/ntp_snippets/category_rankers/category_ranker.h b/chromium/components/ntp_snippets/category_rankers/category_ranker.h
index aa19c57d668..89b01246f64 100644
--- a/chromium/components/ntp_snippets/category_rankers/category_ranker.h
+++ b/chromium/components/ntp_snippets/category_rankers/category_ranker.h
@@ -5,6 +5,9 @@
#ifndef COMPONENTS_NTP_SNIPPETS_CATEGORY_RANKERS_CATEGORY_RANKER_H_
#define COMPONENTS_NTP_SNIPPETS_CATEGORY_RANKERS_CATEGORY_RANKER_H_
+#include <string>
+#include <vector>
+
#include "base/time/time.h"
#include "components/ntp_snippets/category.h"
@@ -39,6 +42,17 @@ class CategoryRanker {
virtual void InsertCategoryAfterIfNecessary(Category category_to_insert,
Category anchor) = 0;
+ struct DebugDataItem {
+ std::string label;
+ std::string content;
+ DebugDataItem(const std::string& label, const std::string& content)
+ : label(label), content(content) {}
+ };
+
+ // Returns DebugData in form of pairs of strings (label; content),
+ // e.g. describing internal state or parameter values.
+ virtual std::vector<DebugDataItem> GetDebugData() = 0;
+
// Feedback data from the user to update the ranking.
// Called whenever a suggestion is opened by the user.
diff --git a/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.cc b/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.cc
index 62e2ad711b5..1b060e63eb6 100644
--- a/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.cc
+++ b/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.cc
@@ -10,6 +10,7 @@
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "base/values.h"
#include "components/ntp_snippets/category_rankers/constant_category_ranker.h"
#include "components/ntp_snippets/content_suggestions_metrics.h"
@@ -131,6 +132,14 @@ base::Optional<Category> GetPromotedCategoryFromVariations() {
return Category::FromIDValue(category_id);
}
+std::string GetOptionalCategoryAsString(
+ const base::Optional<Category>& optional_category) {
+ if (optional_category.has_value()) {
+ return base::IntToString(optional_category->id());
+ }
+ return "None";
+}
+
} // namespace
ClickBasedCategoryRanker::ClickBasedCategoryRanker(
@@ -264,6 +273,46 @@ void ClickBasedCategoryRanker::InsertCategoryAfterIfNecessary(
/*after=*/true);
}
+std::vector<CategoryRanker::DebugDataItem>
+ClickBasedCategoryRanker::GetDebugData() {
+ std::vector<CategoryRanker::DebugDataItem> result;
+ result.push_back(
+ CategoryRanker::DebugDataItem("Type", "ClickBasedCategoryRanker"));
+
+ std::string initial_order_type;
+ CategoryOrderChoice choice = GetSelectedCategoryOrder();
+ if (choice == CategoryOrderChoice::GENERAL) {
+ initial_order_type = "GENERAL";
+ }
+ if (choice == CategoryOrderChoice::EMERGING_MARKETS_ORIENTED) {
+ initial_order_type = "EMERGING_MARKETS_ORIENTED;";
+ }
+ result.push_back(
+ CategoryRanker::DebugDataItem("Initial order type", initial_order_type));
+
+ std::vector<std::string> category_strings;
+ for (const auto& ranked_category : ordered_categories_) {
+ category_strings.push_back(base::ReplaceStringPlaceholders(
+ "($1; $2)",
+ {base::IntToString(ranked_category.category.id()),
+ base::IntToString(ranked_category.clicks)},
+ /*offsets=*/nullptr));
+ }
+ result.push_back(
+ CategoryRanker::DebugDataItem("Current order (with click counts)",
+ base::JoinString(category_strings, ", ")));
+
+ result.push_back(CategoryRanker::DebugDataItem(
+ "Actual promoted category",
+ GetOptionalCategoryAsString(promoted_category_)));
+
+ result.push_back(CategoryRanker::DebugDataItem(
+ "Raw promoted category from variations",
+ GetOptionalCategoryAsString(GetPromotedCategoryFromVariations())));
+
+ return result;
+}
+
void ClickBasedCategoryRanker::OnSuggestionOpened(Category category) {
if (!ContainsCategory(category)) {
LOG(DFATAL) << "The category with ID " << category.id()
diff --git a/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.h b/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.h
index 06bd846107f..1c69ec913d7 100644
--- a/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.h
+++ b/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.h
@@ -6,6 +6,7 @@
#define COMPONENTS_NTP_SNIPPETS_CATEGORY_RANKERS_CLICK_BASED_CATEGORY_RANKER_H_
#include <memory>
+#include <string>
#include <vector>
#include "base/optional.h"
@@ -40,6 +41,7 @@ class ClickBasedCategoryRanker : public CategoryRanker {
Category anchor) override;
void InsertCategoryAfterIfNecessary(Category category_to_insert,
Category anchor) override;
+ std::vector<CategoryRanker::DebugDataItem> GetDebugData() override;
void OnSuggestionOpened(Category category) override;
void OnCategoryDismissed(Category category) override;
diff --git a/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc b/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc
index 828cd317e5d..d68fe9104d4 100644
--- a/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc
+++ b/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc
@@ -5,6 +5,8 @@
#include "components/ntp_snippets/category_rankers/constant_category_ranker.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "components/ntp_snippets/features.h"
namespace ntp_snippets {
@@ -75,6 +77,33 @@ void ConstantCategoryRanker::InsertCategoryAfterIfNecessary(
AppendCategoryIfNecessary(category_to_insert);
}
+std::vector<CategoryRanker::DebugDataItem>
+ConstantCategoryRanker::GetDebugData() {
+ std::vector<CategoryRanker::DebugDataItem> result;
+ result.push_back(
+ CategoryRanker::DebugDataItem("Type", "ConstantCategoryRanker"));
+
+ std::string initial_order_type;
+ CategoryOrderChoice choice = GetSelectedCategoryOrder();
+ if (choice == CategoryOrderChoice::GENERAL) {
+ initial_order_type = "GENERAL";
+ }
+ if (choice == CategoryOrderChoice::EMERGING_MARKETS_ORIENTED) {
+ initial_order_type = "EMERGING_MARKETS_ORIENTED;";
+ }
+ result.push_back(
+ CategoryRanker::DebugDataItem("Initial order type", initial_order_type));
+
+ std::vector<std::string> category_strings;
+ for (Category category : ordered_categories_) {
+ category_strings.push_back(base::IntToString(category.id()));
+ }
+ result.push_back(CategoryRanker::DebugDataItem(
+ "Current order", base::JoinString(category_strings, ", ")));
+
+ return result;
+}
+
void ConstantCategoryRanker::OnSuggestionOpened(Category category) {
// Ignored. The order is constant.
}
diff --git a/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.h b/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.h
index 8e4417e859a..b3a129ec4e7 100644
--- a/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.h
+++ b/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_NTP_SNIPPETS_SECTION_RANKERS_CONSTANT_SECTION_RANKER_H_
#define COMPONENTS_NTP_SNIPPETS_SECTION_RANKERS_CONSTANT_SECTION_RANKER_H_
+#include <string>
#include <vector>
#include "base/time/time.h"
@@ -31,6 +32,7 @@ class ConstantCategoryRanker : public CategoryRanker {
Category anchor) override;
void InsertCategoryAfterIfNecessary(Category category_to_insert,
Category anchor) override;
+ std::vector<CategoryRanker::DebugDataItem> GetDebugData() override;
void OnSuggestionOpened(Category category) override;
void OnCategoryDismissed(Category category) override;
diff --git a/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.cc b/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.cc
index 94739a7b525..42ce8bc9dab 100644
--- a/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.cc
+++ b/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.cc
@@ -42,6 +42,11 @@ void FakeCategoryRanker::InsertCategoryAfterIfNecessary(
// Ignored.
}
+std::vector<CategoryRanker::DebugDataItem> FakeCategoryRanker::GetDebugData() {
+ // Ignored.
+ return std::vector<CategoryRanker::DebugDataItem>();
+}
+
void FakeCategoryRanker::OnSuggestionOpened(Category category) {
// Ignored.
}
diff --git a/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.h b/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.h
index 9b5e37659ff..dedba15bf66 100644
--- a/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.h
+++ b/chromium/components/ntp_snippets/category_rankers/fake_category_ranker.h
@@ -31,6 +31,7 @@ class FakeCategoryRanker : public CategoryRanker {
Category anchor) override;
void InsertCategoryAfterIfNecessary(Category category_to_insert,
Category anchor) override;
+ std::vector<CategoryRanker::DebugDataItem> GetDebugData() override;
void OnSuggestionOpened(Category category) override;
void OnCategoryDismissed(Category category) override;
diff --git a/chromium/components/ntp_snippets/category_rankers/mock_category_ranker.h b/chromium/components/ntp_snippets/category_rankers/mock_category_ranker.h
index 2238aeea7e7..6dbed913c8e 100644
--- a/chromium/components/ntp_snippets/category_rankers/mock_category_ranker.h
+++ b/chromium/components/ntp_snippets/category_rankers/mock_category_ranker.h
@@ -24,6 +24,7 @@ class MockCategoryRanker : public CategoryRanker {
void(Category category_to_insert, Category anchor));
MOCK_METHOD2(InsertCategoryAfterIfNecessary,
void(Category category_to_insert, Category anchor));
+ MOCK_METHOD0(GetDebugData, std::vector<CategoryRanker::DebugDataItem>());
MOCK_METHOD1(OnSuggestionOpened, void(Category category));
MOCK_METHOD1(OnCategoryDismissed, void(Category Category));
};
diff --git a/chromium/components/ntp_snippets/content_suggestion.h b/chromium/components/ntp_snippets/content_suggestion.h
index 5bc647e4cda..1b70c38fbd1 100644
--- a/chromium/components/ntp_snippets/content_suggestion.h
+++ b/chromium/components/ntp_snippets/content_suggestion.h
@@ -49,14 +49,8 @@ struct RecentTabSuggestionExtra {
// ReadingListSuggestionExtra contains additional data which is only available
// for Reading List suggestions.
struct ReadingListSuggestionExtra {
- // State of the distillation a suggestion. This is the meaningful extract of
- // ReadingListEntry::DistillationState for the suggestions. It is duplicated
- // here to avoid a dependence on ReadingList.
- enum class ReadingListSuggestionDistilledState { PENDING, SUCCESS, FAILURE };
-
// State of the distillation of the suggestion.
- ReadingListSuggestionDistilledState distilled_state =
- ReadingListSuggestionDistilledState::PENDING;
+ bool distilled = false;
// URL of the page whose favicon should be displayed for this suggestion.
GURL favicon_page_url;
};
diff --git a/chromium/components/ntp_snippets/content_suggestions_metrics.cc b/chromium/components/ntp_snippets/content_suggestions_metrics.cc
index 5d2d4afe9af..348a555694e 100644
--- a/chromium/components/ntp_snippets/content_suggestions_metrics.cc
+++ b/chromium/components/ntp_snippets/content_suggestions_metrics.cc
@@ -25,6 +25,8 @@ const int kMaxCategories = 10;
const char kHistogramCountOnNtpOpened[] =
"NewTabPage.ContentSuggestions.CountOnNtpOpened";
+const char kHistogramSectionCountOnNtpOpened[] =
+ "NewTabPage.ContentSuggestions.SectionCountOnNtpOpened";
const char kHistogramShown[] = "NewTabPage.ContentSuggestions.Shown";
const char kHistogramShownAge[] = "NewTabPage.ContentSuggestions.ShownAge";
const char kHistogramShownScore[] =
@@ -212,7 +214,8 @@ void RecordContentSuggestionsUsage() {
} // namespace
void OnPageShown(
- const std::vector<std::pair<Category, int>>& suggestions_per_category) {
+ const std::vector<std::pair<Category, int>>& suggestions_per_category,
+ int visible_categories_count) {
int suggestions_total = 0;
for (const std::pair<Category, int>& item : suggestions_per_category) {
LogCategoryHistogramPosition(kHistogramCountOnNtpOpened, item.first,
@@ -221,6 +224,8 @@ void OnPageShown(
}
UMA_HISTOGRAM_EXACT_LINEAR(kHistogramCountOnNtpOpened, suggestions_total,
kMaxSuggestionsTotal);
+ UMA_HISTOGRAM_EXACT_LINEAR(kHistogramSectionCountOnNtpOpened,
+ visible_categories_count, kMaxCategories);
}
void OnSuggestionShown(int global_position,
@@ -292,6 +297,8 @@ void OnSuggestionOpened(int global_position,
if (category.IsKnownCategory(KnownCategories::ARTICLES)) {
RecordContentSuggestionsUsage();
}
+
+ base::RecordAction(base::UserMetricsAction("Suggestions.Content.Opened"));
}
void OnSuggestionMenuOpened(int global_position,
@@ -366,5 +373,17 @@ void RecordRemoteSuggestionsProviderState(bool enabled) {
"NewTabPage.ContentSuggestions.Preferences.RemoteSuggestions", enabled);
}
+void RecordContentSuggestionDismissed() {
+ base::RecordAction(base::UserMetricsAction("Suggestions.Content.Dismissed"));
+}
+
+void RecordCategoryDismissed() {
+ base::RecordAction(base::UserMetricsAction("Suggestions.Category.Dismissed"));
+}
+
+void RecordFetchAction() {
+ base::RecordAction(base::UserMetricsAction("Suggestions.Category.Fetch"));
+}
+
} // namespace metrics
} // namespace ntp_snippets
diff --git a/chromium/components/ntp_snippets/content_suggestions_metrics.h b/chromium/components/ntp_snippets/content_suggestions_metrics.h
index a2f04e5668d..e31b7713633 100644
--- a/chromium/components/ntp_snippets/content_suggestions_metrics.h
+++ b/chromium/components/ntp_snippets/content_suggestions_metrics.h
@@ -16,7 +16,8 @@ namespace ntp_snippets {
namespace metrics {
void OnPageShown(
- const std::vector<std::pair<Category, int>>& suggestions_per_category);
+ const std::vector<std::pair<Category, int>>& suggestions_per_category,
+ int visible_categories_count);
// Should only be called once per NTP for each suggestion.
void OnSuggestionShown(int global_position,
@@ -60,6 +61,12 @@ void OnCategoryDismissed(Category category);
void RecordRemoteSuggestionsProviderState(bool enabled);
+void RecordContentSuggestionDismissed();
+
+void RecordCategoryDismissed();
+
+void RecordFetchAction();
+
} // namespace metrics
} // namespace ntp_snippets
diff --git a/chromium/components/ntp_snippets/content_suggestions_provider.h b/chromium/components/ntp_snippets/content_suggestions_provider.h
index 8c485dfd5a0..3fc37b01525 100644
--- a/chromium/components/ntp_snippets/content_suggestions_provider.h
+++ b/chromium/components/ntp_snippets/content_suggestions_provider.h
@@ -97,9 +97,11 @@ class ContentSuggestionsProvider {
// Fetches more suggestions for the given category. The new suggestions
// will not include any suggestion of the |known_suggestion_ids| sets.
- // The given |callback| is called with these suggestions, along with all
- // existing suggestions. It has to be invoked exactly once as the front-end
- // might wait for its completion.
+ // As a result of this call, the provider:
+ // - should call the |callback| with these additional suggestions (exactly
+ // once as the front-end might wait for its completion);
+ // - should *not* notify its Observer by OnNewSuggestions() with these
+ // additional suggestions.
virtual void Fetch(const Category& category,
const std::set<std::string>& known_suggestion_ids,
const FetchDoneCallback& callback) = 0;
diff --git a/chromium/components/ntp_snippets/content_suggestions_service.cc b/chromium/components/ntp_snippets/content_suggestions_service.cc
index de7ab3ff14f..71f323594d2 100644
--- a/chromium/components/ntp_snippets/content_suggestions_service.cc
+++ b/chromium/components/ntp_snippets/content_suggestions_service.cc
@@ -20,6 +20,7 @@
#include "components/favicon/core/large_icon_service.h"
#include "components/favicon_base/fallback_icon_style.h"
#include "components/favicon_base/favicon_types.h"
+#include "components/ntp_snippets/content_suggestions_metrics.h"
#include "components/ntp_snippets/pref_names.h"
#include "components/ntp_snippets/remote/remote_suggestions_provider.h"
#include "components/prefs/pref_registry_simple.h"
@@ -169,16 +170,9 @@ void ContentSuggestionsService::FetchSuggestionFavicon(
return;
}
- // TODO(jkrcal): Create a general wrapper function in LargeIconService that
- // does handle the get-from-cache-and-fallback-to-google-server functionality
- // in one shot (for all clients that do not need to react in between).
- large_icon_service_->GetLargeIconImageOrFallbackStyle(
- domain_with_favicon, minimum_size_in_pixel, desired_size_in_pixel,
- base::Bind(&ContentSuggestionsService::OnGetFaviconFromCacheFinished,
- base::Unretained(this), domain_with_favicon,
- minimum_size_in_pixel, desired_size_in_pixel, callback,
- /*continue_to_google_server=*/true),
- &favicons_task_tracker_);
+ GetFaviconFromCache(domain_with_favicon, minimum_size_in_pixel,
+ desired_size_in_pixel, callback,
+ /*continue_to_google_server=*/true);
}
GURL ContentSuggestionsService::GetFaviconDomain(
@@ -204,6 +198,26 @@ GURL ContentSuggestionsService::GetFaviconDomain(
return GURL();
}
+void ContentSuggestionsService::GetFaviconFromCache(
+ const GURL& publisher_url,
+ int minimum_size_in_pixel,
+ int desired_size_in_pixel,
+ const ImageFetchedCallback& callback,
+ bool continue_to_google_server) {
+ // TODO(jkrcal): Create a general wrapper function in LargeIconService that
+ // does handle the get-from-cache-and-fallback-to-google-server functionality
+ // in one shot (for all clients that do not need to react in between).
+
+ // Use desired_size = 0 for getting the icon from the cache (so that the icon
+ // is not poorly rescaled by LargeIconService).
+ large_icon_service_->GetLargeIconImageOrFallbackStyle(
+ publisher_url, minimum_size_in_pixel, /*desired_size_in_pixel=*/0,
+ base::Bind(&ContentSuggestionsService::OnGetFaviconFromCacheFinished,
+ base::Unretained(this), publisher_url, minimum_size_in_pixel,
+ desired_size_in_pixel, callback, continue_to_google_server),
+ &favicons_task_tracker_);
+}
+
void ContentSuggestionsService::OnGetFaviconFromCacheFinished(
const GURL& publisher_url,
int minimum_size_in_pixel,
@@ -233,9 +247,13 @@ void ContentSuggestionsService::OnGetFaviconFromCacheFinished(
}
// Try to fetch the favicon from a Google favicon server.
+ // TODO(jkrcal): Currently used only for Articles for you which have public
+ // URLs. Let the provider decide whether |publisher_url| may be private or
+ // not.
large_icon_service_
->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
- publisher_url, minimum_size_in_pixel,
+ publisher_url, minimum_size_in_pixel, desired_size_in_pixel,
+ /*may_page_url_be_private=*/false,
base::Bind(
&ContentSuggestionsService::OnGetFaviconFromGoogleServerFinished,
base::Unretained(this), publisher_url, minimum_size_in_pixel,
@@ -254,14 +272,9 @@ void ContentSuggestionsService::OnGetFaviconFromGoogleServerFinished(
return;
}
- // Get the freshly downloaded icon from the cache.
- large_icon_service_->GetLargeIconImageOrFallbackStyle(
- publisher_url, minimum_size_in_pixel, desired_size_in_pixel,
- base::Bind(&ContentSuggestionsService::OnGetFaviconFromCacheFinished,
- base::Unretained(this), publisher_url, minimum_size_in_pixel,
- desired_size_in_pixel, callback,
- /*continue_to_google_server=*/false),
- &favicons_task_tracker_);
+ GetFaviconFromCache(publisher_url, minimum_size_in_pixel,
+ desired_size_in_pixel, callback,
+ /*continue_to_google_server=*/false);
}
void ContentSuggestionsService::ClearHistory(
@@ -324,6 +337,9 @@ void ContentSuggestionsService::DismissSuggestion(
<< " for unavailable category " << suggestion_id.category();
return;
}
+
+ metrics::RecordContentSuggestionDismissed();
+
providers_by_category_[suggestion_id.category()]->DismissSuggestion(
suggestion_id);
@@ -339,6 +355,8 @@ void ContentSuggestionsService::DismissCategory(Category category) {
return;
}
+ metrics::RecordCategoryDismissed();
+
ContentSuggestionsProvider* provider = providers_it->second;
UnregisterCategory(category, provider);
@@ -382,6 +400,8 @@ void ContentSuggestionsService::Fetch(
return;
}
+ metrics::RecordFetchAction();
+
providers_it->second->Fetch(category, known_suggestion_ids, callback);
}
diff --git a/chromium/components/ntp_snippets/content_suggestions_service.h b/chromium/components/ntp_snippets/content_suggestions_service.h
index 308e4dbe69d..40c442bc6bb 100644
--- a/chromium/components/ntp_snippets/content_suggestions_service.h
+++ b/chromium/components/ntp_snippets/content_suggestions_service.h
@@ -15,6 +15,7 @@
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
+#include "base/supports_user_data.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/time/time.h"
#include "components/history/core/browser/history_service.h"
@@ -47,6 +48,7 @@ class RemoteSuggestionsProvider;
// Retrieves suggestions from a number of ContentSuggestionsProviders and serves
// them grouped into categories. There can be at most one provider per category.
class ContentSuggestionsService : public KeyedService,
+ public base::SupportsUserData,
public ContentSuggestionsProvider::Observer,
public SigninManagerBase::Observer,
public history::HistoryServiceObserver {
@@ -330,6 +332,14 @@ class ContentSuggestionsService : public KeyedService,
// Get the domain of the suggestion suitable for fetching the favicon.
GURL GetFaviconDomain(const ContentSuggestion::ID& suggestion_id);
+
+ // Initiate the fetch of a favicon from the local cache.
+ void GetFaviconFromCache(const GURL& publisher_url,
+ int minimum_size_in_pixel,
+ int desired_size_in_pixel,
+ const ImageFetchedCallback& callback,
+ bool continue_to_google_server);
+
// Callbacks for fetching favicons.
void OnGetFaviconFromCacheFinished(
const GURL& publisher_url,
diff --git a/chromium/components/ntp_snippets/features.cc b/chromium/components/ntp_snippets/features.cc
index 0b90a4271f1..6910f402873 100644
--- a/chromium/components/ntp_snippets/features.cc
+++ b/chromium/components/ntp_snippets/features.cc
@@ -13,6 +13,20 @@
namespace ntp_snippets {
+// Keep sorted, and keep nullptr at the end.
+const base::Feature*(kAllFeatures[]) = {&kArticleSuggestionsFeature,
+ &kBookmarkSuggestionsFeature,
+ &kCategoryOrder,
+ &kCategoryRanker,
+ &kForeignSessionsSuggestionsFeature,
+ &kIncreasedVisibility,
+ &kNotificationsFeature,
+ &kPhysicalWebPageSuggestionsFeature,
+ &kPreferAmpUrlsFeature,
+ &kPublisherFaviconsFromNewServerFeature,
+ &kRecentOfflineTabSuggestionsFeature,
+ nullptr};
+
const base::Feature kArticleSuggestionsFeature{
"NTPArticleSuggestions", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -113,4 +127,18 @@ CategoryOrderChoice GetSelectedCategoryOrder() {
return CategoryOrderChoice::GENERAL;
}
+const base::Feature kNotificationsFeature = {"ContentSuggestionsNotifications",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+const char kNotificationsPriorityParam[] = "priority";
+const char kNotificationsTextParam[] = "text";
+const char kNotificationsTextValuePublisher[] = "publisher";
+const char kNotificationsTextValueSnippet[] = "snippet";
+const char kNotificationsTextValueAndMore[] = "and_more";
+const char kNotificationsKeepWhenFrontmostParam[] =
+ "keep_notification_when_frontmost";
+const char kNotificationsOpenToNTPParam[] = "open_to_ntp";
+const char kNotificationsDailyLimit[] = "daily_limit";
+const char kNotificationsIgnoredLimitParam[] = "ignored_limit";
+
} // namespace ntp_snippets
diff --git a/chromium/components/ntp_snippets/features.h b/chromium/components/ntp_snippets/features.h
index 8832aed5502..9946e7c2d0a 100644
--- a/chromium/components/ntp_snippets/features.h
+++ b/chromium/components/ntp_snippets/features.h
@@ -18,6 +18,14 @@ class Clock;
namespace ntp_snippets {
+//
+// Null-terminated list of all features related to content suggestions.
+//
+// If you add a base::Feature below, you must add it to this list. It is used in
+// internal pages to list relevant parameters and settings.
+//
+extern const base::Feature*(kAllFeatures[]);
+
// Features to turn individual providers/categories on/off.
// TODO(jkrcal): Rename to kRemoteSuggestionsFeature.
extern const base::Feature kArticleSuggestionsFeature;
@@ -72,6 +80,39 @@ enum class CategoryOrderChoice {
// Returns which category order to use according to kCategoryOrder feature.
CategoryOrderChoice GetSelectedCategoryOrder();
+// Enables and configures notifications for content suggestions on Android.
+extern const base::Feature kNotificationsFeature;
+
+// An integer. The priority of the notification, ranging from -2 (PRIORITY_MIN)
+// to 2 (PRIORITY_MAX). Vibrates and makes sound if >= 0.
+extern const char kNotificationsPriorityParam[];
+constexpr int kNotificationsDefaultPriority = -1;
+
+// "publisher": use article's publisher as notification's text (default).
+// "snippet": use article's snippet as notification's text.
+// "and_more": use "From $1. Read this article and $2 more." as text.
+extern const char kNotificationsTextParam[];
+extern const char kNotificationsTextValuePublisher[];
+extern const char kNotificationsTextValueSnippet[];
+extern const char kNotificationsTextValueAndMore[];
+
+// "true": when Chrome becomes frontmost, leave notifications open.
+// "false": automatically dismiss notification when Chrome becomes frontmost.
+extern const char kNotificationsKeepWhenFrontmostParam[];
+
+// "true": notifications link to chrome://newtab, with appropriate text.
+// "false": notifications link to URL of notifying article.
+extern const char kNotificationsOpenToNTPParam[];
+
+// An integer. The maximum number of notifications that will be shown in 1 day.
+extern const char kNotificationsDailyLimit[];
+constexpr int kNotificationsDefaultDailyLimit = 1;
+
+// An integer. The number of notifications that can be ignored. If the user
+// ignores this many notifications or more, we stop sending them.
+extern const char kNotificationsIgnoredLimitParam[];
+constexpr int kNotificationsIgnoredDefaultLimit = 3;
+
} // namespace ntp_snippets
#endif // COMPONENTS_NTP_SNIPPETS_FEATURES_H_
diff --git a/chromium/components/ntp_snippets/pref_names.cc b/chromium/components/ntp_snippets/pref_names.cc
index fb5582a6725..bea67c36392 100644
--- a/chromium/components/ntp_snippets/pref_names.cc
+++ b/chromium/components/ntp_snippets/pref_names.cc
@@ -13,18 +13,25 @@ const char kRemoteSuggestionCategories[] = "ntp_snippets.remote_categories";
const char kSnippetLastFetchAttempt[] = "ntp_snippets.last_fetch_attempt";
-const char kSnippetSoftFetchingIntervalWifi[] =
- "ntp_snippets.soft_fetching_interval_wifi";
-
-const char kSnippetSoftFetchingIntervalFallback[] =
- "ntp_snippets.soft_fetching_interval_fallback";
-
+// For backwards compatibility, we do not rename the "fetching_" prefs (should
+// be "persistent_fetching_").
const char kSnippetPersistentFetchingIntervalWifi[] =
"ntp_snippets.fetching_interval_wifi";
-
const char kSnippetPersistentFetchingIntervalFallback[] =
"ntp_snippets.fetching_interval_fallback";
+const char kSnippetStartupFetchingIntervalWifi[] =
+ "ntp_snippets.startup_fetching_interval_wifi";
+const char kSnippetStartupFetchingIntervalFallback[] =
+ "ntp_snippets.startup_fetching_interval_fallback";
+
+// For backwards compatibility, we do not rename the "soft_fetching_" prefs
+// (should be "shown_fetching_").
+const char kSnippetShownFetchingIntervalWifi[] =
+ "ntp_snippets.soft_fetching_interval_wifi";
+const char kSnippetShownFetchingIntervalFallback[] =
+ "ntp_snippets.soft_fetching_interval_fallback";
+
const char kSnippetFetcherRequestCount[] =
"ntp.request_throttler.suggestion_fetcher.count";
const char kSnippetFetcherInteractiveRequestCount[] =
diff --git a/chromium/components/ntp_snippets/pref_names.h b/chromium/components/ntp_snippets/pref_names.h
index 9826eb9e9ca..fe3e198c83e 100644
--- a/chromium/components/ntp_snippets/pref_names.h
+++ b/chromium/components/ntp_snippets/pref_names.h
@@ -18,21 +18,25 @@ extern const char kRemoteSuggestionCategories[];
// The pref name for the last time when a background fetch was attempted.
extern const char kSnippetLastFetchAttempt[];
-// The pref name for the currently applied minimal interval between two
-// successive soft background fetches that react to user activity (such as
-// opening Chrome) when there is a WiFi connectivity.
-extern const char kSnippetSoftFetchingIntervalWifi[];
-// The pref name for the currently applied minimal interval between two
-// successive soft background fetches that react to user activity (such as
-// opening Chrome) when there is no WiFi connectivity.
-extern const char kSnippetSoftFetchingIntervalFallback[];
-
-// The pref name for the currently-scheduled background fetching interval when
-// there is WiFi connectivity.
+
+// Pref names for minimal intervals between two successive background fetches.
+//
+// The prefs store *currently applied* minimal intervals. For each trigger type
+// there are two intervals stored in prefs:
+// - "Wifi" for situations with Wifi / unmetered network connectivity, and
+// - "Fallback" for situations with only non-Wifi / metered network.
+// We check "meteredness" of the current network only on platforms that support
+// that, notably Android; we use WiFi as the proxy of being unmetered elsewhere.
+//
+// Intervals for trigger type 1: wake-up of the persistent scheduler.
extern const char kSnippetPersistentFetchingIntervalWifi[];
-// The pref name for the currently-scheduled background fetching interval when
-// there is no WiFi connectivity.
extern const char kSnippetPersistentFetchingIntervalFallback[];
+// Intervals for trigger type 2: browser started-up (both cold and warm start).
+extern const char kSnippetStartupFetchingIntervalWifi[];
+extern const char kSnippetStartupFetchingIntervalFallback[];
+// Intervals for trigger type 3: suggestions shown to the user.
+extern const char kSnippetShownFetchingIntervalWifi[];
+extern const char kSnippetShownFetchingIntervalFallback[];
// The pref name for today's count of RemoteSuggestionsFetcher requests, so far.
extern const char kSnippetFetcherRequestCount[];
diff --git a/chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.cc b/chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.cc
deleted file mode 100644
index e7361ad1300..00000000000
--- a/chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 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/ntp_snippets/reading_list/reading_list_distillation_state_util.h"
-
-#include "base/logging.h"
-
-namespace ntp_snippets {
-
-ReadingListEntry::DistillationState ReadingListStateFromSuggestionState(
- ReadingListSuggestionExtra::ReadingListSuggestionDistilledState
- distilled_state) {
- switch (distilled_state) {
- case ReadingListSuggestionExtra::ReadingListSuggestionDistilledState::
- PENDING:
- return ReadingListEntry::WAITING;
- case ReadingListSuggestionExtra::ReadingListSuggestionDistilledState::
- SUCCESS:
- return ReadingListEntry::PROCESSED;
- case ReadingListSuggestionExtra::ReadingListSuggestionDistilledState::
- FAILURE:
- return ReadingListEntry::DISTILLATION_ERROR;
- }
- NOTREACHED();
- return ReadingListEntry::PROCESSING;
-}
-
-ReadingListSuggestionExtra::ReadingListSuggestionDistilledState
-SuggestionStateFromReadingListState(
- ReadingListEntry::DistillationState distilled_state) {
- switch (distilled_state) {
- case ReadingListEntry::WILL_RETRY:
- case ReadingListEntry::PROCESSING:
- case ReadingListEntry::WAITING:
- return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState::
- PENDING;
- case ReadingListEntry::PROCESSED:
- return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState::
- SUCCESS;
- case ReadingListEntry::DISTILLATION_ERROR:
- return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState::
- FAILURE;
- }
- NOTREACHED();
- return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState::
- PENDING;
-}
-
-} // namespace ntp_snippets
diff --git a/chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.h b/chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.h
deleted file mode 100644
index a00553fc98a..00000000000
--- a/chromium/components/ntp_snippets/reading_list/reading_list_distillation_state_util.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 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_NTP_SNIPPETS_READING_LIST_READING_LIST_DISTILLATION_STATE_UTIL_H_
-#define COMPONENTS_NTP_SNIPPETS_READING_LIST_READING_LIST_DISTILLATION_STATE_UTIL_H_
-
-#include "components/ntp_snippets/content_suggestion.h"
-#include "components/reading_list/core/reading_list_entry.h"
-
-namespace ntp_snippets {
-
-ReadingListEntry::DistillationState ReadingListStateFromSuggestionState(
- ReadingListSuggestionExtra::ReadingListSuggestionDistilledState
- distilled_state);
-
-ReadingListSuggestionExtra::ReadingListSuggestionDistilledState
-SuggestionStateFromReadingListState(
- ReadingListEntry::DistillationState distilled_state);
-
-} // namespace ntp_snippets
-
-#endif // COMPONENTS_NTP_SNIPPETS_READING_LIST_READING_LIST_DISTILLATION_STATE_UTIL_H_
diff --git a/chromium/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc b/chromium/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc
index ed11ed83fda..9bf791c4857 100644
--- a/chromium/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc
+++ b/chromium/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc
@@ -11,8 +11,8 @@
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "components/ntp_snippets/category.h"
-#include "components/ntp_snippets/reading_list/reading_list_distillation_state_util.h"
#include "components/reading_list/core/reading_list_entry.h"
#include "components/reading_list/core/reading_list_model.h"
#include "components/strings/grit/components_strings.h"
@@ -218,10 +218,16 @@ ContentSuggestion ReadingListSuggestionsProvider::ConvertEntry(
}
suggestion.set_publisher_name(
url_formatter::FormatUrl(entry->URL().GetOrigin()));
+ int64_t entry_time = entry->DistillationTime();
+ if (entry_time == 0) {
+ entry_time = entry->CreationTime();
+ }
+
+ suggestion.set_publish_date(
+ base::Time::FromDoubleT(entry_time / base::Time::kMicrosecondsPerSecond));
auto extra = base::MakeUnique<ReadingListSuggestionExtra>();
- extra->distilled_state =
- SuggestionStateFromReadingListState(entry->DistilledState());
+ extra->distilled = entry->DistilledState() == ReadingListEntry::PROCESSED;
extra->favicon_page_url =
entry->DistilledURL().is_valid() ? entry->DistilledURL() : entry->URL();
suggestion.set_reading_list_suggestion_extra(std::move(extra));
diff --git a/chromium/components/ntp_snippets/remote/fetch.py b/chromium/components/ntp_snippets/remote/fetch.py
index 48f448a3ec7..aa753f3e7e4 100755
--- a/chromium/components/ntp_snippets/remote/fetch.py
+++ b/chromium/components/ntp_snippets/remote/fetch.py
@@ -195,9 +195,9 @@ def Authenticate(args, headers, client_id, client_secret):
creds.apply(headers)
-def PrintShortResponse(r):
+def PrintShortResponse(j):
now = datetime.datetime.now()
- for category in r.json()["categories"]:
+ for category in j["categories"]:
print("%s: " % category["localizedTitle"])
for suggestion in category["suggestions"]:
attribution = suggestion["attribution"]
diff --git a/chromium/components/ntp_snippets/remote/json_request.cc b/chromium/components/ntp_snippets/remote/json_request.cc
index 3f7af6e8b2b..2ea9f4f7d57 100644
--- a/chromium/components/ntp_snippets/remote/json_request.cc
+++ b/chromium/components/ntp_snippets/remote/json_request.cc
@@ -52,8 +52,6 @@ namespace {
// Variation parameter for disabling the retry.
const char kBackground5xxRetriesName[] = "background_5xx_retries_count";
-const int kMaxExcludedIds = 100;
-
// Variation parameter for sending LanguageModel info to the server.
const char kSendTopLanguagesName[] = "send_top_languages";
@@ -321,9 +319,6 @@ std::string JsonRequest::Builder::BuildBody() const {
auto excluded = base::MakeUnique<base::ListValue>();
for (const auto& id : params_.excluded_ids) {
excluded->AppendString(id);
- if (excluded->GetSize() >= kMaxExcludedIds) {
- break;
- }
}
request->Set("excludedSuggestionIds", std::move(excluded));
diff --git a/chromium/components/ntp_snippets/remote/json_request_unittest.cc b/chromium/components/ntp_snippets/remote/json_request_unittest.cc
index d19f2c8b812..3791ccd5059 100644
--- a/chromium/components/ntp_snippets/remote/json_request_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/json_request_unittest.cc
@@ -148,7 +148,7 @@ TEST_F(JsonRequestTest, BuildRequestUnauthenticated) {
"}"));
}
-TEST_F(JsonRequestTest, BuildRequestExcludedIds) {
+TEST_F(JsonRequestTest, ShouldNotTruncateExcludedIdsList) {
JsonRequest::Builder builder;
RequestParams params;
params.interactive_request = false;
@@ -180,9 +180,27 @@ TEST_F(JsonRequestTest, BuildRequestExcludedIds) {
" \"080\", \"081\", \"082\", \"083\", \"084\","
" \"085\", \"086\", \"087\", \"088\", \"089\","
" \"090\", \"091\", \"092\", \"093\", \"094\","
- " \"095\", \"096\", \"097\", \"098\", \"099\""
- // Truncated to 100 entries. Currently, they happen to
- // be those lexically first.
+ " \"095\", \"096\", \"097\", \"098\", \"099\","
+ " \"100\", \"101\", \"102\", \"103\", \"104\","
+ " \"105\", \"106\", \"107\", \"108\", \"109\","
+ " \"110\", \"111\", \"112\", \"113\", \"114\","
+ " \"115\", \"116\", \"117\", \"118\", \"119\","
+ " \"120\", \"121\", \"122\", \"123\", \"124\","
+ " \"125\", \"126\", \"127\", \"128\", \"129\","
+ " \"130\", \"131\", \"132\", \"133\", \"134\","
+ " \"135\", \"136\", \"137\", \"138\", \"139\","
+ " \"140\", \"141\", \"142\", \"143\", \"144\","
+ " \"145\", \"146\", \"147\", \"148\", \"149\","
+ " \"150\", \"151\", \"152\", \"153\", \"154\","
+ " \"155\", \"156\", \"157\", \"158\", \"159\","
+ " \"160\", \"161\", \"162\", \"163\", \"164\","
+ " \"165\", \"166\", \"167\", \"168\", \"169\","
+ " \"170\", \"171\", \"172\", \"173\", \"174\","
+ " \"175\", \"176\", \"177\", \"178\", \"179\","
+ " \"180\", \"181\", \"182\", \"183\", \"184\","
+ " \"185\", \"186\", \"187\", \"188\", \"189\","
+ " \"190\", \"191\", \"192\", \"193\", \"194\","
+ " \"195\", \"196\", \"197\", \"198\", \"199\""
" ],"
" \"userActivenessClass\": \"ACTIVE_NTP_USER\""
"}"));
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_unittest.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_unittest.cc
index 7607efe00ca..e5ffb4d0821 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_unittest.cc
@@ -30,6 +30,7 @@
#include "components/variations/entropy_provider.h"
#include "components/variations/variations_params_manager.h"
#include "google_apis/gaia/fake_oauth2_token_service_delegate.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -182,14 +183,16 @@ class DelegateCallingTestURLFetcherFactory
int id,
const GURL& url,
net::URLFetcher::RequestType request_type,
- net::URLFetcherDelegate* d) override {
+ net::URLFetcherDelegate* d,
+ net::NetworkTrafficAnnotationTag traffic_annotation) override {
if (GetFetcherByID(id)) {
LOG(WARNING) << "The ID " << id << " was already assigned to a fetcher."
<< "Its delegate will thereforde be called right now.";
DropAndCallDelegate(id);
}
fetchers_.push_back(id);
- return TestURLFetcherFactory::CreateURLFetcher(id, url, request_type, d);
+ return TestURLFetcherFactory::CreateURLFetcher(id, url, request_type, d,
+ traffic_annotation);
}
// Returns the raw pointer of the last created URL fetcher.
@@ -235,7 +238,8 @@ class FailingFakeURLFetcherFactory : public net::URLFetcherFactory {
int id,
const GURL& url,
net::URLFetcher::RequestType request_type,
- net::URLFetcherDelegate* d) override {
+ net::URLFetcherDelegate* d,
+ net::NetworkTrafficAnnotationTag traffic_annotation) override {
return base::MakeUnique<net::FakeURLFetcher>(
url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND,
net::URLRequestStatus::FAILED);
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc
index 2c637e3a57a..a3a8b9f6873 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc
@@ -33,6 +33,7 @@
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/variations/variations_associated_data.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
@@ -47,6 +48,10 @@ const int kMaxSuggestionCount = 10;
// Number of archived suggestions we keep around in memory.
const int kMaxArchivedSuggestionCount = 200;
+// Maximal number of dismissed suggestions to exclude when fetching new
+// suggestions from the server. This limit exists to decrease data usage.
+const int kMaxExcludedDismissedIds = 100;
+
// Keys for storing CategoryContent info in prefs.
const char kCategoryContentId[] = "id";
const char kCategoryContentTitle[] = "title";
@@ -192,6 +197,17 @@ void CallWithEmptyResults(const FetchDoneCallback& callback,
callback.Run(status, std::vector<ContentSuggestion>());
}
+void AddDismissedIdsToRequest(const RemoteSuggestion::PtrVector& dismissed,
+ RequestParams* request_params) {
+ // The latest ids are added first, because they are more relevant.
+ for (auto it = dismissed.rbegin(); it != dismissed.rend(); ++it) {
+ if (request_params->excluded_ids.size() == kMaxExcludedDismissedIds) {
+ break;
+ }
+ request_params->excluded_ids.insert((*it)->id());
+ }
+}
+
} // namespace
CachedImageFetcher::CachedImageFetcher(
@@ -288,10 +304,34 @@ void CachedImageFetcher::FetchImageFromNetwork(
return;
}
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("remote_suggestions_provider", R"(
+ semantics {
+ sender: "Content Suggestion Thumbnail Fetch"
+ description:
+ "Retrieves thumbnails for content suggestions, for display on the "
+ "New Tab page or Chrome Home."
+ trigger:
+ "Triggered when the user looks at a content suggestion (and its "
+ "thumbnail isn't cached yet)."
+ data: "None."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting: "Currently not available, but in progress: crbug.com/703684"
+ chrome_policy {
+ NTPContentSuggestionsEnabled {
+ policy_options {mode: MANDATORY}
+ NTPContentSuggestionsEnabled: false
+ }
+ }
+ })");
image_fetcher_->StartOrQueueNetworkRequest(
suggestion_id.id_within_category(), url,
base::Bind(&CachedImageFetcher::OnImageDecodingDone,
- base::Unretained(this), callback));
+ base::Unretained(this), callback),
+ traffic_annotation);
}
RemoteSuggestionsProviderImpl::RemoteSuggestionsProviderImpl(
@@ -408,7 +448,7 @@ void RemoteSuggestionsProviderImpl::FetchSuggestions(
MarkEmptyCategoriesAsLoading();
- RequestParams params = BuildFetchParams();
+ RequestParams params = BuildFetchParams(/*fetched_category=*/base::nullopt);
params.interactive_request = interactive_request;
suggestions_fetcher_->FetchSnippets(
params,
@@ -441,7 +481,7 @@ void RemoteSuggestionsProviderImpl::Fetch(
},
base::Unretained(remote_suggestions_scheduler_), callback);
- RequestParams params = BuildFetchParams();
+ RequestParams params = BuildFetchParams(category);
params.excluded_ids.insert(known_suggestion_ids.begin(),
known_suggestion_ids.end());
params.interactive_request = true;
@@ -454,15 +494,23 @@ void RemoteSuggestionsProviderImpl::Fetch(
}
// Builds default fetcher params.
-RequestParams RemoteSuggestionsProviderImpl::BuildFetchParams() const {
+RequestParams RemoteSuggestionsProviderImpl::BuildFetchParams(
+ base::Optional<Category> fetched_category) const {
RequestParams result;
result.language_code = application_language_code_;
result.count_to_fetch = kMaxSuggestionCount;
+ // If this is a fetch for a specific category, its dismissed suggestions are
+ // added first to truncate them less.
+ if (fetched_category.has_value()) {
+ DCHECK(category_contents_.count(*fetched_category));
+ AddDismissedIdsToRequest(
+ category_contents_.find(*fetched_category)->second.dismissed, &result);
+ }
for (const auto& map_entry : category_contents_) {
- const CategoryContent& content = map_entry.second;
- for (const auto& dismissed_suggestion : content.dismissed) {
- result.excluded_ids.insert(dismissed_suggestion->id());
+ if (fetched_category.has_value() && map_entry.first == *fetched_category) {
+ continue;
}
+ AddDismissedIdsToRequest(map_entry.second.dismissed, &result);
}
return result;
}
@@ -684,31 +732,12 @@ void RemoteSuggestionsProviderImpl::OnFetchMoreFinished(
UpdateCategoryInfo(category, fetched_category.info);
SanitizeReceivedSuggestions(existing_content->dismissed,
&fetched_category.suggestions);
- // We compute the result now before modifying |fetched_category.suggestions|.
- // However, we wait with notifying the caller until the end of the method when
- // all state is updated.
std::vector<ContentSuggestion> result =
ConvertToContentSuggestions(category, fetched_category.suggestions);
-
- // Fill up the newly fetched suggestions with existing ones, store them, and
- // notify observers about new data.
- while (fetched_category.suggestions.size() <
- static_cast<size_t>(kMaxSuggestionCount) &&
- !existing_content->suggestions.empty()) {
- fetched_category.suggestions.emplace(
- fetched_category.suggestions.begin(),
- std::move(existing_content->suggestions.back()));
- existing_content->suggestions.pop_back();
- }
- std::vector<std::string> to_dismiss =
- *GetSuggestionIDVector(existing_content->suggestions);
- for (const auto& id : to_dismiss) {
- DismissSuggestionFromCategoryContent(existing_content, id);
- }
- DCHECK(existing_content->suggestions.empty());
-
- IntegrateSuggestions(existing_content,
- std::move(fetched_category.suggestions));
+ // Store the additional suggestions into the archive to be able to fetch
+ // images and favicons for them. Note that ArchiveSuggestions clears
+ // |fetched_category.suggestions|.
+ ArchiveSuggestions(existing_content, &fetched_category.suggestions);
// TODO(tschumann): We should properly honor the existing category state,
// e.g. to make sure we don't serve results after the sign-out. Revisit this:
@@ -716,7 +745,6 @@ void RemoteSuggestionsProviderImpl::OnFetchMoreFinished(
// status?
UpdateCategoryStatus(category, CategoryStatus::AVAILABLE);
fetching_callback.Run(Status::Success(), std::move(result));
- NotifyNewSuggestions(category, *existing_content);
}
void RemoteSuggestionsProviderImpl::OnFetchFinished(
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.h b/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.h
index 2540c3abae3..d84d00d4548 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.h
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl.h
@@ -17,6 +17,7 @@
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "components/image_fetcher/core/image_fetcher_delegate.h"
@@ -409,7 +410,9 @@ class RemoteSuggestionsProviderImpl final : public RemoteSuggestionsProvider {
void RestoreCategoriesFromPrefs();
void StoreCategoriesToPrefs();
- RequestParams BuildFetchParams() const;
+ // Absence of fetched category corresponds to fetching all categories.
+ RequestParams BuildFetchParams(
+ base::Optional<Category> fetched_category) const;
void MarkEmptyCategoriesAsLoading();
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc
index ee6175526de..0759b4f1cb6 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc
@@ -16,6 +16,7 @@
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -48,6 +49,7 @@
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "components/variations/variations_params_manager.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -336,7 +338,8 @@ class FailingFakeURLFetcherFactory : public net::URLFetcherFactory {
int id,
const GURL& url,
net::URLFetcher::RequestType request_type,
- net::URLFetcherDelegate* d) override {
+ net::URLFetcherDelegate* d,
+ net::NetworkTrafficAnnotationTag traffic_annotation) override {
return base::MakeUnique<net::FakeURLFetcher>(
url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND,
net::URLRequestStatus::FAILED);
@@ -350,10 +353,11 @@ class MockImageFetcher : public ImageFetcher {
MOCK_METHOD1(SetImageDownloadLimit,
void(base::Optional<int64_t> max_download_bytes));
MOCK_METHOD1(SetDesiredImageFrameSize, void(const gfx::Size&));
- MOCK_METHOD3(StartOrQueueNetworkRequest,
+ MOCK_METHOD4(StartOrQueueNetworkRequest,
void(const std::string&,
const GURL&,
- const ImageFetcherCallback&));
+ const ImageFetcherCallback&,
+ const net::NetworkTrafficAnnotationTag&));
MOCK_METHOD0(GetImageDecoder, image_fetcher::ImageDecoder*());
};
@@ -1001,7 +1005,7 @@ TEST_F(RemoteSuggestionsProviderImplTest, LoadsAdditionalSuggestions) {
// Verify we can resolve the image of the new suggestions.
ServeImageCallback cb =
base::Bind(&ServeOneByOneImage, &service->GetImageFetcherForTesting());
- EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _))
+ EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _, _))
.Times(2)
.WillRepeatedly(WithArgs<0, 2>(Invoke(CreateFunctor(cb))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
@@ -1012,12 +1016,6 @@ TEST_F(RemoteSuggestionsProviderImplTest, LoadsAdditionalSuggestions) {
image = FetchImage(service.get(), MakeArticleID("http://second"));
EXPECT_FALSE(image.IsEmpty());
EXPECT_EQ(1, image.Width());
-
- // Verify that the observer received the update as well. We should see the
- // newly-fetched items filled up with existing ones.
- EXPECT_THAT(observer().SuggestionsForCategory(articles_category()),
- ElementsAre(IdWithinCategoryEq("http://first"),
- IdWithinCategoryEq("http://second")));
}
// The tests TestMergingFetchedMoreSuggestionsFillup and
@@ -1025,14 +1023,14 @@ TEST_F(RemoteSuggestionsProviderImplTest, LoadsAdditionalSuggestions) {
// story:
// 1) fetch suggestions in NTP A
// 2) fetch more suggestions in NTP A.
-// 3) open new NTP B: See the last 10 results visible in step 2).
-// 4) fetch more suggestions in NTP B. Make sure no results from step 1) which
-// were superseded in step 2) get merged back in again.
+// 3) open new NTP B: See the first 10 results from step 1).
+// 4) fetch more suggestions in NTP B. Make sure the results are independent
+// from step 2)
// TODO(tschumann): Test step 4) on a higher level instead of peeking into the
// internal 'dismissed' data. The proper check is to make sure we tell the
// backend to exclude these suggestions.
TEST_F(RemoteSuggestionsProviderImplTest,
- TestMergingFetchedMoreSuggestionsFillup) {
+ FewMoreFetchedSuggestionsShouldNotInterfere) {
auto service = MakeSuggestionsProvider(/*set_empty_response=*/false);
LoadFromJSONString(service.get(),
GetTestJson({GetSuggestionWithUrl("http://id-1"),
@@ -1071,65 +1069,37 @@ TEST_F(RemoteSuggestionsProviderImplTest,
"http://id-9", "http://id-10"},
expect_receiving_two_new_suggestions);
- // Verify that the observer received the update as well. We should see the
- // newly-fetched items filled up with existing ones. The merging is done
- // mimicking a scrolling behavior.
+ // Verify that the observer still has the old set.
EXPECT_THAT(
observer().SuggestionsForCategory(articles_category()),
ElementsAre(
+ IdWithinCategoryEq("http://id-1"), IdWithinCategoryEq("http://id-2"),
IdWithinCategoryEq("http://id-3"), IdWithinCategoryEq("http://id-4"),
IdWithinCategoryEq("http://id-5"), IdWithinCategoryEq("http://id-6"),
IdWithinCategoryEq("http://id-7"), IdWithinCategoryEq("http://id-8"),
- IdWithinCategoryEq("http://id-9"), IdWithinCategoryEq("http://id-10"),
- IdWithinCategoryEq("http://more-id-1"),
- IdWithinCategoryEq("http://more-id-2")));
- // Verify the superseded suggestions got marked as dismissed.
- EXPECT_THAT(service->GetDismissedSuggestionsForTesting(articles_category()),
- ElementsAre(IdEq("http://id-1"), IdEq("http://id-2")));
-}
-
-TEST_F(RemoteSuggestionsProviderImplTest,
- ClearHistoryShouldDeleteArchivedSuggestions) {
- auto service = MakeSuggestionsProvider(/*set_empty_response=*/false);
- // First get suggestions into the archived state which happens through
- // subsequent fetches. Then we verify the entries are gone from the 'archived'
- // state by trying to load their images (and we shouldn't even know the URLs
- // anymore).
- LoadFromJSONString(service.get(),
- GetTestJson({GetSuggestionWithUrl("http://id-1"),
- GetSuggestionWithUrl("http://id-2")}));
- LoadFromJSONString(service.get(),
- GetTestJson({GetSuggestionWithUrl("http://new-id-1"),
- GetSuggestionWithUrl("http://new-id-2")}));
- // Make sure images of both batches are available. This is to sanity check our
- // assumptions for the test are right.
- ServeImageCallback cb =
- base::Bind(&ServeOneByOneImage, &service->GetImageFetcherForTesting());
- EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _))
- .Times(2)
- .WillRepeatedly(WithArgs<0, 2>(Invoke(CreateFunctor(cb))));
- image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
- gfx::Image image = FetchImage(service.get(), MakeArticleID("http://id-1"));
- ASSERT_FALSE(image.IsEmpty());
- ASSERT_EQ(1, image.Width());
- image = FetchImage(service.get(), MakeArticleID("http://new-id-1"));
- ASSERT_FALSE(image.IsEmpty());
- ASSERT_EQ(1, image.Width());
-
- service->ClearHistory(base::Time::UnixEpoch(), base::Time::Max(),
- base::Callback<bool(const GURL& url)>());
+ IdWithinCategoryEq("http://id-9"),
+ IdWithinCategoryEq("http://id-10")));
- // Make sure images of both batches are gone.
- // Verify we cannot resolve the image of the new suggestions.
- image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
- EXPECT_TRUE(
- FetchImage(service.get(), MakeArticleID("http://id-1")).IsEmpty());
- EXPECT_TRUE(
- FetchImage(service.get(), MakeArticleID("http://new-id-1")).IsEmpty());
+ // No interference from previous Fetch more: we can receive two other ones.
+ expect_receiving_two_new_suggestions =
+ base::Bind([](Status status, std::vector<ContentSuggestion> suggestions) {
+ ASSERT_THAT(suggestions, SizeIs(2));
+ EXPECT_THAT(suggestions[0], IdWithinCategoryEq("http://more-id-3"));
+ EXPECT_THAT(suggestions[1], IdWithinCategoryEq("http://more-id-4"));
+ });
+ LoadMoreFromJSONString(
+ service.get(), articles_category(),
+ GetTestJson({GetSuggestionWithUrl("http://more-id-3"),
+ GetSuggestionWithUrl("http://more-id-4")}),
+ /*known_ids=*/
+ {"http://id-1", "http://id-2", "http://id-3", "http://id-4",
+ "http://id-5", "http://id-6", "http://id-7", "http://id-8",
+ "http://id-9", "http://id-10"},
+ expect_receiving_two_new_suggestions);
}
TEST_F(RemoteSuggestionsProviderImplTest,
- TestMergingFetchedMoreSuggestionsReplaceAll) {
+ TenMoreFetchedSuggestionsShouldNotInterfere) {
auto service = MakeSuggestionsProvider(/*set_empty_response=*/false);
LoadFromJSONString(service.get(),
GetTestJson({GetSuggestionWithUrl("http://id-1"),
@@ -1183,24 +1153,88 @@ TEST_F(RemoteSuggestionsProviderImplTest,
"http://id-5", "http://id-6", "http://id-7", "http://id-8",
"http://id-9", "http://id-10"},
expect_receiving_ten_new_suggestions);
- EXPECT_THAT(observer().SuggestionsForCategory(articles_category()),
- ElementsAre(IdWithinCategoryEq("http://more-id-1"),
- IdWithinCategoryEq("http://more-id-2"),
- IdWithinCategoryEq("http://more-id-3"),
- IdWithinCategoryEq("http://more-id-4"),
- IdWithinCategoryEq("http://more-id-5"),
- IdWithinCategoryEq("http://more-id-6"),
- IdWithinCategoryEq("http://more-id-7"),
- IdWithinCategoryEq("http://more-id-8"),
- IdWithinCategoryEq("http://more-id-9"),
- IdWithinCategoryEq("http://more-id-10")));
- // Verify the superseded suggestions got marked as dismissed.
EXPECT_THAT(
- service->GetDismissedSuggestionsForTesting(articles_category()),
- ElementsAre(IdEq("http://id-1"), IdEq("http://id-2"), IdEq("http://id-3"),
- IdEq("http://id-4"), IdEq("http://id-5"), IdEq("http://id-6"),
- IdEq("http://id-7"), IdEq("http://id-8"), IdEq("http://id-9"),
- IdEq("http://id-10")));
+ observer().SuggestionsForCategory(articles_category()),
+ ElementsAre(
+ IdWithinCategoryEq("http://id-1"), IdWithinCategoryEq("http://id-2"),
+ IdWithinCategoryEq("http://id-3"), IdWithinCategoryEq("http://id-4"),
+ IdWithinCategoryEq("http://id-5"), IdWithinCategoryEq("http://id-6"),
+ IdWithinCategoryEq("http://id-7"), IdWithinCategoryEq("http://id-8"),
+ IdWithinCategoryEq("http://id-9"),
+ IdWithinCategoryEq("http://id-10")));
+
+ // This time, test receiving the same set.
+ expect_receiving_ten_new_suggestions =
+ base::Bind([](Status status, std::vector<ContentSuggestion> suggestions) {
+ EXPECT_THAT(suggestions,
+ ElementsAre(IdWithinCategoryEq("http://more-id-1"),
+ IdWithinCategoryEq("http://more-id-2"),
+ IdWithinCategoryEq("http://more-id-3"),
+ IdWithinCategoryEq("http://more-id-4"),
+ IdWithinCategoryEq("http://more-id-5"),
+ IdWithinCategoryEq("http://more-id-6"),
+ IdWithinCategoryEq("http://more-id-7"),
+ IdWithinCategoryEq("http://more-id-8"),
+ IdWithinCategoryEq("http://more-id-9"),
+ IdWithinCategoryEq("http://more-id-10")));
+ });
+ LoadMoreFromJSONString(
+ service.get(), articles_category(),
+ GetTestJson({GetSuggestionWithUrl("http://more-id-1"),
+ GetSuggestionWithUrl("http://more-id-2"),
+ GetSuggestionWithUrl("http://more-id-3"),
+ GetSuggestionWithUrl("http://more-id-4"),
+ GetSuggestionWithUrl("http://more-id-5"),
+ GetSuggestionWithUrl("http://more-id-6"),
+ GetSuggestionWithUrl("http://more-id-7"),
+ GetSuggestionWithUrl("http://more-id-8"),
+ GetSuggestionWithUrl("http://more-id-9"),
+ GetSuggestionWithUrl("http://more-id-10")}),
+ /*known_ids=*/
+ {"http://id-1", "http://id-2", "http://id-3", "http://id-4",
+ "http://id-5", "http://id-6", "http://id-7", "http://id-8",
+ "http://id-9", "http://id-10"},
+ expect_receiving_ten_new_suggestions);
+}
+
+TEST_F(RemoteSuggestionsProviderImplTest,
+ ClearHistoryShouldDeleteArchivedSuggestions) {
+ auto service = MakeSuggestionsProvider(/*set_empty_response=*/false);
+ // First get suggestions into the archived state which happens through
+ // subsequent fetches. Then we verify the entries are gone from the 'archived'
+ // state by trying to load their images (and we shouldn't even know the URLs
+ // anymore).
+ LoadFromJSONString(service.get(),
+ GetTestJson({GetSuggestionWithUrl("http://id-1"),
+ GetSuggestionWithUrl("http://id-2")}));
+ LoadFromJSONString(service.get(),
+ GetTestJson({GetSuggestionWithUrl("http://new-id-1"),
+ GetSuggestionWithUrl("http://new-id-2")}));
+ // Make sure images of both batches are available. This is to sanity check our
+ // assumptions for the test are right.
+ ServeImageCallback cb =
+ base::Bind(&ServeOneByOneImage, &service->GetImageFetcherForTesting());
+ EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _, _))
+ .Times(2)
+ .WillRepeatedly(WithArgs<0, 2>(Invoke(CreateFunctor(cb))));
+ image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
+ gfx::Image image = FetchImage(service.get(), MakeArticleID("http://id-1"));
+ ASSERT_FALSE(image.IsEmpty());
+ ASSERT_EQ(1, image.Width());
+ image = FetchImage(service.get(), MakeArticleID("http://new-id-1"));
+ ASSERT_FALSE(image.IsEmpty());
+ ASSERT_EQ(1, image.Width());
+
+ service->ClearHistory(base::Time::UnixEpoch(), base::Time::Max(),
+ base::Callback<bool(const GURL& url)>());
+
+ // Make sure images of both batches are gone.
+ // Verify we cannot resolve the image of the new suggestions.
+ image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
+ EXPECT_TRUE(
+ FetchImage(service.get(), MakeArticleID("http://id-1")).IsEmpty());
+ EXPECT_TRUE(
+ FetchImage(service.get(), MakeArticleID("http://new-id-1")).IsEmpty());
}
// TODO(tschumann): We don't have test making sure the RemoteSuggestionsFetcher
@@ -1345,7 +1379,7 @@ TEST_F(RemoteSuggestionsProviderImplTest, Dismiss) {
// Load the image to store it in the database.
ServeImageCallback cb =
base::Bind(&ServeOneByOneImage, &service->GetImageFetcherForTesting());
- EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _))
+ EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _, _))
.WillOnce(WithArgs<0, 2>(Invoke(CreateFunctor(cb))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
gfx::Image image = FetchImage(service.get(), MakeArticleID(kSuggestionUrl));
@@ -1450,7 +1484,7 @@ TEST_F(RemoteSuggestionsProviderImplTest, RemoveExpiredDismissedContent) {
// fetching expectations.
ServeImageCallback cb =
base::Bind(&ServeOneByOneImage, &service->GetImageFetcherForTesting());
- EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _))
+ EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _, _))
.WillOnce(WithArgs<0, 2>(Invoke(CreateFunctor(cb))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
gfx::Image image = FetchImage(service.get(), MakeArticleID(kSuggestionUrl));
@@ -1624,7 +1658,7 @@ TEST_F(RemoteSuggestionsProviderImplTest, ImageReturnedWithTheSameId) {
base::Bind(&ServeOneByOneImage, &service->GetImageFetcherForTesting());
{
InSequence s;
- EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _))
+ EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _, _))
.WillOnce(WithArgs<0, 2>(Invoke(CreateFunctor(cb))));
EXPECT_CALL(image_fetched, Call(_)).WillOnce(SaveArg<0>(&image));
}
@@ -1731,7 +1765,7 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldClearOrphanedImagesOnRestart) {
ServeImageCallback cb =
base::Bind(&ServeOneByOneImage, &service->GetImageFetcherForTesting());
- EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _))
+ EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _, _))
.WillOnce(WithArgs<0, 2>(Invoke(CreateFunctor(cb))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc
index 4b5a0e10b42..193628a55e4 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc
@@ -31,23 +31,27 @@ namespace {
// The FetchingInterval enum specifies overlapping time intervals that are used
// for scheduling the next remote suggestion fetch. Therefore a timer is created
// for each interval. Initially all the timers are started at the same time.
-// Fetches are only performed when conditions associated with the intervals are
-// met:
-// - A "soft" fetch is performed only at a moment when the user actively uses
-// Chrome after the interval has elapsed and causes a trigger that is currently
-// enabled while
-// - a "persistent" fetch is initiated automatically by the OS after the
-// interval elapses.
-// - A "wifi" fetch is performed only when the user is on a connection that
-// the OS classifies as unmetered while
-// - a "fallback" fetch happens on any connection.
+// A fetch for a given interval is only performed at the moment (after the
+// interval has elapsed) when the combination of two conditions associated with
+// the interval is met.
+// 1. Trigger contidion:
+// - STARTUP_*: the user starts / switches to Chrome;
+// - SHOWN_*: the suggestions surface is shown to the user;
+// - PERSISTENT_*: the OS initiates the scheduled fetching task (which has
+// been scheduled according to this interval).
+// 2. Connectivity condition:
+// - *_WIFI: the user is on a connection that the OS classifies as unmetered;
+// - *_FALLBACK: holds for any functional internet connection.
+//
// If a fetch failed, then only the corresponding timer is reset. The other
// timers are not touched.
enum class FetchingInterval {
PERSISTENT_FALLBACK,
PERSISTENT_WIFI,
- SOFT_FALLBACK,
- SOFT_WIFI,
+ STARTUP_FALLBACK,
+ STARTUP_WIFI,
+ SHOWN_FALLBACK,
+ SHOWN_WIFI,
COUNT
};
@@ -57,28 +61,36 @@ enum class FetchingInterval {
// The values of each array specify a default time interval for the intervals
// defined by the enum FetchingInterval. The default time intervals defined in
// the arrays can be overridden using different variation parameters.
-const double kDefaultFetchingIntervalHoursRareNtpUser[] = {48.0, 24.0, 8.0,
- 4.0};
-const double kDefaultFetchingIntervalHoursActiveNtpUser[] = {24.0, 8.0, 6.0,
- 3.0};
+const double kDefaultFetchingIntervalHoursRareNtpUser[] = {192.0, 96.0, 48.0,
+ 24.0, 12.0, 8.0};
+const double kDefaultFetchingIntervalHoursActiveNtpUser[] = {96.0, 48.0, 48.0,
+ 24.0, 12.0, 8.0};
const double kDefaultFetchingIntervalHoursActiveSuggestionsConsumer[] = {
- 24.0, 6.0, 2.0, 1.0};
+ 48.0, 24.0, 24.0, 6.0, 2.0, 1.0};
// Variation parameters than can be used to override the default fetching
-// intervals.
+// intervals. For backwards compatibility, we do not rename
+// - the "fetching_" params (should be "persistent_fetching_");
+// - the "soft_" params (should be "shown_").
const char* kFetchingIntervalParamNameRareNtpUser[] = {
"fetching_interval_hours-fallback-rare_ntp_user",
"fetching_interval_hours-wifi-rare_ntp_user",
+ "startup_fetching_interval_hours-fallback-rare_ntp_user",
+ "startup_fetching_interval_hours-wifi-rare_ntp_user",
"soft_fetching_interval_hours-fallback-rare_ntp_user",
"soft_fetching_interval_hours-wifi-rare_ntp_user"};
const char* kFetchingIntervalParamNameActiveNtpUser[] = {
"fetching_interval_hours-fallback-active_ntp_user",
"fetching_interval_hours-wifi-active_ntp_user",
+ "startup_fetching_interval_hours-fallback-active_ntp_user",
+ "startup_fetching_interval_hours-wifi-active_ntp_user",
"soft_fetching_interval_hours-fallback-active_ntp_user",
"soft_fetching_interval_hours-wifi-active_ntp_user"};
const char* kFetchingIntervalParamNameActiveSuggestionsConsumer[] = {
"fetching_interval_hours-fallback-active_suggestions_consumer",
"fetching_interval_hours-wifi-active_suggestions_consumer",
+ "startup_fetching_interval_hours-fallback-active_suggestions_consumer",
+ "startup_fetching_interval_hours-wifi-active_suggestions_consumer",
"soft_fetching_interval_hours-fallback-active_suggestions_consumer",
"soft_fetching_interval_hours-wifi-active_suggestions_consumer"};
@@ -174,14 +186,14 @@ void ReportTimeUntilFirstSoftTrigger(UserClassifier::UserClass user_class,
}
}
-void ReportTimeUntilSoftFetch(UserClassifier::UserClass user_class,
- base::TimeDelta time_until_soft_fetch) {
+void ReportTimeUntilShownFetch(UserClassifier::UserClass user_class,
+ base::TimeDelta time_until_shown_fetch) {
switch (user_class) {
case UserClassifier::UserClass::RARE_NTP_USER:
UMA_HISTOGRAM_CUSTOM_TIMES(
"NewTabPage.ContentSuggestions.TimeUntilSoftFetch."
"RareNTPUser",
- time_until_soft_fetch, base::TimeDelta::FromSeconds(1),
+ time_until_shown_fetch, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(7),
/*bucket_count=*/50);
break;
@@ -189,7 +201,7 @@ void ReportTimeUntilSoftFetch(UserClassifier::UserClass user_class,
UMA_HISTOGRAM_CUSTOM_TIMES(
"NewTabPage.ContentSuggestions.TimeUntilSoftFetch."
"ActiveNTPUser",
- time_until_soft_fetch, base::TimeDelta::FromSeconds(1),
+ time_until_shown_fetch, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(7),
/*bucket_count=*/50);
break;
@@ -197,7 +209,37 @@ void ReportTimeUntilSoftFetch(UserClassifier::UserClass user_class,
UMA_HISTOGRAM_CUSTOM_TIMES(
"NewTabPage.ContentSuggestions.TimeUntilSoftFetch."
"ActiveSuggestionsConsumer",
- time_until_soft_fetch, base::TimeDelta::FromSeconds(1),
+ time_until_shown_fetch, base::TimeDelta::FromSeconds(1),
+ base::TimeDelta::FromDays(7),
+ /*bucket_count=*/50);
+ break;
+ }
+}
+
+void ReportTimeUntilStartupFetch(UserClassifier::UserClass user_class,
+ base::TimeDelta time_until_startup_fetch) {
+ switch (user_class) {
+ case UserClassifier::UserClass::RARE_NTP_USER:
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "NewTabPage.ContentSuggestions.TimeUntilStartupFetch."
+ "RareNTPUser",
+ time_until_startup_fetch, base::TimeDelta::FromSeconds(1),
+ base::TimeDelta::FromDays(7),
+ /*bucket_count=*/50);
+ break;
+ case UserClassifier::UserClass::ACTIVE_NTP_USER:
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "NewTabPage.ContentSuggestions.TimeUntilStartupFetch."
+ "ActiveNTPUser",
+ time_until_startup_fetch, base::TimeDelta::FromSeconds(1),
+ base::TimeDelta::FromDays(7),
+ /*bucket_count=*/50);
+ break;
+ case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "NewTabPage.ContentSuggestions.TimeUntilStartupFetch."
+ "ActiveSuggestionsConsumer",
+ time_until_startup_fetch, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(7),
/*bucket_count=*/50);
break;
@@ -288,8 +330,10 @@ bool RemoteSuggestionsSchedulerImpl::FetchingSchedule::operator==(
const FetchingSchedule& other) const {
return interval_persistent_wifi == other.interval_persistent_wifi &&
interval_persistent_fallback == other.interval_persistent_fallback &&
- interval_soft_wifi == other.interval_soft_wifi &&
- interval_soft_fallback == other.interval_soft_fallback;
+ interval_startup_wifi == other.interval_startup_wifi &&
+ interval_startup_fallback == other.interval_startup_fallback &&
+ interval_shown_wifi == other.interval_shown_wifi &&
+ interval_shown_fallback == other.interval_shown_fallback;
}
bool RemoteSuggestionsSchedulerImpl::FetchingSchedule::operator!=(
@@ -300,7 +344,9 @@ bool RemoteSuggestionsSchedulerImpl::FetchingSchedule::operator!=(
bool RemoteSuggestionsSchedulerImpl::FetchingSchedule::is_empty() const {
return interval_persistent_wifi.is_zero() &&
interval_persistent_fallback.is_zero() &&
- interval_soft_wifi.is_zero() && interval_soft_fallback.is_zero();
+ interval_startup_wifi.is_zero() &&
+ interval_startup_fallback.is_zero() && interval_shown_wifi.is_zero() &&
+ interval_shown_fallback.is_zero();
}
// The TriggerType enum specifies values for the events that can trigger
@@ -361,8 +407,11 @@ void RemoteSuggestionsSchedulerImpl::RegisterProfilePrefs(
registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalWifi, 0);
registry->RegisterInt64Pref(prefs::kSnippetPersistentFetchingIntervalFallback,
0);
- registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalWifi, 0);
- registry->RegisterInt64Pref(prefs::kSnippetSoftFetchingIntervalFallback, 0);
+ registry->RegisterInt64Pref(prefs::kSnippetStartupFetchingIntervalWifi, 0);
+ registry->RegisterInt64Pref(prefs::kSnippetStartupFetchingIntervalFallback,
+ 0);
+ registry->RegisterInt64Pref(prefs::kSnippetShownFetchingIntervalWifi, 0);
+ registry->RegisterInt64Pref(prefs::kSnippetShownFetchingIntervalFallback, 0);
registry->RegisterInt64Pref(prefs::kSnippetLastFetchAttempt, 0);
// Cleanup procedure in M59. Remove for M62.
@@ -488,10 +537,14 @@ RemoteSuggestionsSchedulerImpl::GetDesiredFetchingSchedule() const {
GetDesiredFetchingInterval(FetchingInterval::PERSISTENT_WIFI, user_class);
schedule.interval_persistent_fallback = GetDesiredFetchingInterval(
FetchingInterval::PERSISTENT_FALLBACK, user_class);
- schedule.interval_soft_wifi =
- GetDesiredFetchingInterval(FetchingInterval::SOFT_WIFI, user_class);
- schedule.interval_soft_fallback =
- GetDesiredFetchingInterval(FetchingInterval::SOFT_FALLBACK, user_class);
+ schedule.interval_startup_wifi =
+ GetDesiredFetchingInterval(FetchingInterval::STARTUP_WIFI, user_class);
+ schedule.interval_startup_fallback = GetDesiredFetchingInterval(
+ FetchingInterval::STARTUP_FALLBACK, user_class);
+ schedule.interval_shown_wifi =
+ GetDesiredFetchingInterval(FetchingInterval::SHOWN_WIFI, user_class);
+ schedule.interval_shown_fallback =
+ GetDesiredFetchingInterval(FetchingInterval::SHOWN_FALLBACK, user_class);
return schedule;
}
@@ -502,10 +555,14 @@ void RemoteSuggestionsSchedulerImpl::LoadLastFetchingSchedule() {
schedule_.interval_persistent_fallback =
base::TimeDelta::FromInternalValue(profile_prefs_->GetInt64(
prefs::kSnippetPersistentFetchingIntervalFallback));
- schedule_.interval_soft_wifi = base::TimeDelta::FromInternalValue(
- profile_prefs_->GetInt64(prefs::kSnippetSoftFetchingIntervalWifi));
- schedule_.interval_soft_fallback = base::TimeDelta::FromInternalValue(
- profile_prefs_->GetInt64(prefs::kSnippetSoftFetchingIntervalFallback));
+ schedule_.interval_startup_wifi = base::TimeDelta::FromInternalValue(
+ profile_prefs_->GetInt64(prefs::kSnippetStartupFetchingIntervalWifi));
+ schedule_.interval_startup_fallback = base::TimeDelta::FromInternalValue(
+ profile_prefs_->GetInt64(prefs::kSnippetStartupFetchingIntervalFallback));
+ schedule_.interval_shown_wifi = base::TimeDelta::FromInternalValue(
+ profile_prefs_->GetInt64(prefs::kSnippetShownFetchingIntervalWifi));
+ schedule_.interval_shown_fallback = base::TimeDelta::FromInternalValue(
+ profile_prefs_->GetInt64(prefs::kSnippetShownFetchingIntervalFallback));
}
void RemoteSuggestionsSchedulerImpl::StoreFetchingSchedule() {
@@ -515,10 +572,15 @@ void RemoteSuggestionsSchedulerImpl::StoreFetchingSchedule() {
profile_prefs_->SetInt64(
prefs::kSnippetPersistentFetchingIntervalFallback,
schedule_.interval_persistent_fallback.ToInternalValue());
- profile_prefs_->SetInt64(prefs::kSnippetSoftFetchingIntervalWifi,
- schedule_.interval_soft_wifi.ToInternalValue());
- profile_prefs_->SetInt64(prefs::kSnippetSoftFetchingIntervalFallback,
- schedule_.interval_soft_fallback.ToInternalValue());
+ profile_prefs_->SetInt64(prefs::kSnippetStartupFetchingIntervalWifi,
+ schedule_.interval_startup_wifi.ToInternalValue());
+ profile_prefs_->SetInt64(
+ prefs::kSnippetStartupFetchingIntervalFallback,
+ schedule_.interval_startup_fallback.ToInternalValue());
+ profile_prefs_->SetInt64(prefs::kSnippetShownFetchingIntervalWifi,
+ schedule_.interval_shown_wifi.ToInternalValue());
+ profile_prefs_->SetInt64(prefs::kSnippetShownFetchingIntervalFallback,
+ schedule_.interval_shown_fallback.ToInternalValue());
}
void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundIfAppropriate(
@@ -541,7 +603,8 @@ void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundIfAppropriate(
clock_->Now() - last_fetch_attempt_time);
}
- if (is_soft && !ShouldRefetchInTheBackgroundNow(last_fetch_attempt_time)) {
+ if (is_soft &&
+ !ShouldRefetchInTheBackgroundNow(last_fetch_attempt_time, trigger)) {
return;
}
@@ -549,12 +612,20 @@ void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundIfAppropriate(
return;
}
- if (is_soft) {
- ReportTimeUntilSoftFetch(user_classifier_->GetUserClass(),
- clock_->Now() - last_fetch_attempt_time);
- } else {
- ReportTimeUntilPersistentFetch(user_classifier_->GetUserClass(),
- clock_->Now() - last_fetch_attempt_time);
+ base::TimeDelta diff = clock_->Now() - last_fetch_attempt_time;
+ switch (trigger) {
+ case TriggerType::PERSISTENT_SCHEDULER_WAKE_UP:
+ ReportTimeUntilPersistentFetch(user_classifier_->GetUserClass(), diff);
+ break;
+ case TriggerType::NTP_OPENED:
+ ReportTimeUntilShownFetch(user_classifier_->GetUserClass(), diff);
+ break;
+ case TriggerType::BROWSER_FOREGROUNDED:
+ case TriggerType::BROWSER_COLD_START:
+ ReportTimeUntilStartupFetch(user_classifier_->GetUserClass(), diff);
+ break;
+ case TriggerType::COUNT:
+ NOTREACHED();
}
UMA_HISTOGRAM_ENUMERATION(
@@ -568,16 +639,23 @@ void RemoteSuggestionsSchedulerImpl::RefetchInTheBackgroundIfAppropriate(
}
bool RemoteSuggestionsSchedulerImpl::ShouldRefetchInTheBackgroundNow(
- base::Time last_fetch_attempt_time) {
+ base::Time last_fetch_attempt_time,
+ TriggerType trigger) {
// If we have no persistent scheduler to ask, err on the side of caution.
bool wifi = false;
if (persistent_scheduler_) {
wifi = persistent_scheduler_->IsOnUnmeteredConnection();
}
- base::Time first_allowed_fetch_time =
- last_fetch_attempt_time +
- (wifi ? schedule_.interval_soft_wifi : schedule_.interval_soft_fallback);
+ base::Time first_allowed_fetch_time = last_fetch_attempt_time;
+ if (trigger == TriggerType::NTP_OPENED) {
+ first_allowed_fetch_time += (wifi ? schedule_.interval_shown_wifi
+ : schedule_.interval_shown_fallback);
+ } else {
+ first_allowed_fetch_time += (wifi ? schedule_.interval_startup_wifi
+ : schedule_.interval_startup_fallback);
+ }
+
base::Time now = clock_->Now();
return background_fetches_allowed_after_ <= now &&
first_allowed_fetch_time <= now;
@@ -686,7 +764,8 @@ RemoteSuggestionsSchedulerImpl::GetEnabledTriggerTypes() {
std::set<RemoteSuggestionsSchedulerImpl::TriggerType>
RemoteSuggestionsSchedulerImpl::GetDefaultEnabledTriggerTypes() {
- return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED};
+ return {TriggerType::PERSISTENT_SCHEDULER_WAKE_UP, TriggerType::NTP_OPENED,
+ TriggerType::BROWSER_COLD_START, TriggerType::BROWSER_FOREGROUNDED};
}
} // namespace ntp_snippets
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h b/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h
index 9921f51489a..3e103624bec 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h
@@ -71,8 +71,10 @@ class RemoteSuggestionsSchedulerImpl : public RemoteSuggestionsScheduler {
base::TimeDelta interval_persistent_wifi;
base::TimeDelta interval_persistent_fallback;
- base::TimeDelta interval_soft_wifi;
- base::TimeDelta interval_soft_fallback;
+ base::TimeDelta interval_startup_wifi;
+ base::TimeDelta interval_startup_fallback;
+ base::TimeDelta interval_shown_wifi;
+ base::TimeDelta interval_shown_fallback;
};
enum class TriggerType;
@@ -91,9 +93,10 @@ class RemoteSuggestionsSchedulerImpl : public RemoteSuggestionsScheduler {
// timing is appropriate for another fetch.
void RefetchInTheBackgroundIfAppropriate(TriggerType trigger);
- // Checks whether it is time to perform a soft background fetch, according to
- // |schedule|.
- bool ShouldRefetchInTheBackgroundNow(base::Time last_fetch_attempt_time);
+ // Checks whether it is time to perform a soft background fetch for |trigger|,
+ // according to |schedule|.
+ bool ShouldRefetchInTheBackgroundNow(base::Time last_fetch_attempt_time,
+ TriggerType trigger);
// Returns whether background fetching (for the given |trigger|) is disabled.
bool BackgroundFetchesDisabled(TriggerType trigger) const;
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl_unittest.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl_unittest.cc
index ea142787bcd..0c22282ea0a 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl_unittest.cc
@@ -489,8 +489,8 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
// Make the first soft fetch successful.
scheduler()->OnBrowserForegrounded();
signal_fetch_done.Run(Status::Success());
- // Open NTP again after 4hrs.
- test_clock()->Advance(base::TimeDelta::FromHours(4));
+ // Open NTP again after 9hrs.
+ test_clock()->Advance(base::TimeDelta::FromHours(24));
scheduler()->OnBrowserForegrounded();
}
@@ -603,7 +603,7 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
}
TEST_F(RemoteSuggestionsSchedulerImplTest,
- ReschedulesWhenSoftWifiParamChanges) {
+ ReschedulesWhenShownWifiParamChanges) {
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
ActivateProvider();
@@ -617,7 +617,7 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
}
TEST_F(RemoteSuggestionsSchedulerImplTest,
- ReschedulesWhenSoftFallbackParamChanges) {
+ ReschedulesWhenShownFallbackParamChanges) {
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
ActivateProvider();
@@ -630,12 +630,40 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
ActivateProvider();
}
-TEST_F(RemoteSuggestionsSchedulerImplTest, FetchIntervalForSoftTriggerOnWifi) {
+TEST_F(RemoteSuggestionsSchedulerImplTest,
+ ReschedulesWhenStartupWifiParamChanges) {
+ EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
+ ActivateProvider();
+
+ // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
+ // null. Change the on usage interval for this class.
+ SetVariationParameter("startup_fetching_interval_hours-wifi-active_ntp_user",
+ "1.5");
+
+ // Schedule() should get called for the second time after params have changed.
+ ActivateProvider();
+}
+
+TEST_F(RemoteSuggestionsSchedulerImplTest,
+ ReschedulesWhenStartupFallbackParamChanges) {
+ EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
+ ActivateProvider();
+
+ // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
+ // null. Change the fallback interval for this class.
+ SetVariationParameter(
+ "startup_fetching_interval_hours-fallback-active_ntp_user", "1.5");
+
+ // Schedule() should get called for the second time after params have changed.
+ ActivateProvider();
+}
+
+TEST_F(RemoteSuggestionsSchedulerImplTest, FetchIntervalForShownTriggerOnWifi) {
// Pretend we are on WiFi (already done in ctor, we make it explicit here).
EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
.WillRepeatedly(Return(true));
- // UserClassifier defaults to UserClass::ACTIVE_NTP_USER which uses a 3h time
- // interval by default for soft background fetches on WiFi.
+ // UserClassifier defaults to UserClass::ACTIVE_NTP_USER which uses a 8h time
+ // interval by default for shown trigger on WiFi.
// Initial scheduling after being enabled.
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
@@ -651,22 +679,22 @@ TEST_F(RemoteSuggestionsSchedulerImplTest, FetchIntervalForSoftTriggerOnWifi) {
signal_fetch_done.Run(Status::Success());
// Open NTP again after too short delay. This time no fetch is executed.
- test_clock()->Advance(base::TimeDelta::FromMinutes(30));
+ test_clock()->Advance(base::TimeDelta::FromHours(1));
scheduler()->OnNTPOpened();
// Open NTP after another delay, now together long enough to issue a fetch.
- test_clock()->Advance(base::TimeDelta::FromMinutes(150));
+ test_clock()->Advance(base::TimeDelta::FromHours(7));
EXPECT_CALL(*provider(), RefetchInTheBackground(_));
scheduler()->OnNTPOpened();
}
TEST_F(RemoteSuggestionsSchedulerImplTest,
- OverrideFetchIntervalForSoftTriggerOnWifi) {
+ OverrideFetchIntervalForShownTriggerOnWifi) {
// Pretend we are on WiFi (already done in ctor, we make it explicit here).
EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
.WillRepeatedly(Return(true));
// UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
- // null. Change the on usage interval for this class from 2h to 30min.
+ // null. Change the interval for this class from 4h to 30min.
SetVariationParameter("soft_fetching_interval_hours-wifi-active_ntp_user",
"0.5");
@@ -694,12 +722,12 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
}
TEST_F(RemoteSuggestionsSchedulerImplTest,
- FetchIntervalForSoftTriggerOnFallback) {
+ FetchIntervalForShownTriggerOnFallback) {
// Pretend we are not on wifi -> fallback connection.
EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
.WillRepeatedly(Return(false));
- // UserClassifier defaults to UserClass::ACTIVE_NTP_USER which uses a 6h time
- // interval by default for soft background fetches not on WiFi.
+ // UserClassifier defaults to UserClass::ACTIVE_NTP_USER which uses a 12h time
+ // interval by default for shown trigger not on WiFi.
// Initial scheduling after being enabled.
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
@@ -715,22 +743,22 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
signal_fetch_done.Run(Status::Success());
// Open NTP again after too short delay. This time no fetch is executed.
- test_clock()->Advance(base::TimeDelta::FromMinutes(300));
+ test_clock()->Advance(base::TimeDelta::FromHours(5));
scheduler()->OnNTPOpened();
// Open NTP after another delay, now together long enough to issue a fetch.
- test_clock()->Advance(base::TimeDelta::FromMinutes(60));
+ test_clock()->Advance(base::TimeDelta::FromHours(7));
EXPECT_CALL(*provider(), RefetchInTheBackground(_));
scheduler()->OnNTPOpened();
}
TEST_F(RemoteSuggestionsSchedulerImplTest,
- OverrideFetchIntervalForSoftTriggerOnFallback) {
+ OverrideFetchIntervalForShownTriggerOnFallback) {
// Pretend we are not on wifi -> fallback connection.
EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
.WillRepeatedly(Return(false));
// UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
- // null. Change the on usage interval for this class from 4h to 30min.
+ // null. Change the interval for this class from 4h to 30min.
SetVariationParameter("soft_fetching_interval_hours-fallback-active_ntp_user",
"0.5");
diff --git a/chromium/components/ntp_snippets/user_classifier.cc b/chromium/components/ntp_snippets/user_classifier.cc
index 92b0312de49..a2461be9ef9 100644
--- a/chromium/components/ntp_snippets/user_classifier.cc
+++ b/chromium/components/ntp_snippets/user_classifier.cc
@@ -41,11 +41,13 @@ const double kMinHours = 0.5;
const char kMinHoursParam[] = "user_classifier_min_hours";
// Classification constants.
-const double kActiveConsumerClicksAtLeastOncePerHours = 72;
+const double kActiveConsumerClicksAtLeastOncePerHours = 96;
const char kActiveConsumerClicksAtLeastOncePerHoursParam[] =
"user_classifier_active_consumer_clicks_at_least_once_per_hours";
-const double kRareUserOpensNTPAtMostOncePerHours = 96;
+// The previous value in production was 72, i.e. 3 days. The new value is a
+// cautios shift in the direction we want (having slightly more rare users).
+const double kRareUserOpensNTPAtMostOncePerHours = 66;
const char kRareUserOpensNTPAtMostOncePerHoursParam[] =
"user_classifier_rare_user_opens_ntp_at_most_once_per_hours";
@@ -73,7 +75,7 @@ const char* kLastTimeKeys[] = {prefs::kUserClassifierLastTimeToOpenNTP,
prefs::kUserClassifierLastTimeToUseSuggestions};
// Default lengths of the intervals for new users for the metrics.
-const double kInitialHoursBetweenEvents[] = {24, 48, 96};
+const double kInitialHoursBetweenEvents[] = {24, 48, 120};
const char* kInitialHoursBetweenEventsParams[] = {
"user_classifier_default_interval_ntp_opened",
"user_classifier_default_interval_suggestions_shown",
diff --git a/chromium/components/ntp_tiles/OWNERS b/chromium/components/ntp_tiles/OWNERS
index ccd0e3802de..80f0c928a4f 100644
--- a/chromium/components/ntp_tiles/OWNERS
+++ b/chromium/components/ntp_tiles/OWNERS
@@ -1,4 +1,6 @@
bauerb@chromium.org
+fhorschig@chromium.org
+jkrcal@chromium.org
mastiz@chromium.org
sfiera@chromium.org
treib@chromium.org
diff --git a/chromium/components/ntp_tiles/constants.cc b/chromium/components/ntp_tiles/constants.cc
index 0c54388e9a8..20bf4c36a3e 100644
--- a/chromium/components/ntp_tiles/constants.cc
+++ b/chromium/components/ntp_tiles/constants.cc
@@ -4,7 +4,9 @@
#include "components/ntp_tiles/constants.h"
+#include "base/command_line.h"
#include "base/feature_list.h"
+#include "components/ntp_tiles/switches.h"
namespace ntp_tiles {
@@ -13,4 +15,25 @@ const char kPopularSitesFieldTrialName[] = "NTPPopularSites";
extern const base::Feature kPopularSitesBakedInContentFeature{
"NTPPopularSitesBakedInContent", base::FEATURE_ENABLED_BY_DEFAULT};
+extern const base::Feature kNtpMostLikelyFaviconsFromServerFeature{
+ "NTPMostLikelyFaviconsFromServer", base::FEATURE_DISABLED_BY_DEFAULT};
+
+extern const base::Feature kPinHomePageAsTileFeature{
+ "PinHomePageAsTile", base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool AreNtpMostLikelyFaviconsFromServerEnabled() {
+ // Check if the experimental flag is forced on or off.
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(
+ switches::kEnableNtpMostLikelyFaviconsFromServer)) {
+ return true;
+ } else if (command_line->HasSwitch(
+ switches::kDisableNtpMostLikelyFaviconsFromServer)) {
+ return false;
+ }
+
+ // Check if the finch experiment is turned on.
+ return base::FeatureList::IsEnabled(kNtpMostLikelyFaviconsFromServerFeature);
+}
+
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/constants.h b/chromium/components/ntp_tiles/constants.h
index 42651086328..6619450363b 100644
--- a/chromium/components/ntp_tiles/constants.h
+++ b/chromium/components/ntp_tiles/constants.h
@@ -19,6 +19,19 @@ extern const char kPopularSitesFieldTrialName[];
// Android or iOS users.
extern const base::Feature kPopularSitesBakedInContentFeature;
+// Feature to allow the new Google favicon server for fetching favicons for Most
+// Likely tiles on the New Tab Page.
+extern const base::Feature kNtpMostLikelyFaviconsFromServerFeature;
+
+// Feature to pin any set home page as first tile.
+extern const base::Feature kPinHomePageAsTileFeature;
+
+// Use this to find out whether the kNtpMostLikelyFaviconsFromServerFeature is
+// enabled. This helper function abstracts iOS special way to override the
+// feature (via command-line params).
+// TODO(jkrcal): Remove once crbug.com/718926 is fixed.
+bool AreNtpMostLikelyFaviconsFromServerEnabled();
+
} // namespace ntp_tiles
#endif // COMPONENTS_NTP_TILES_CONSTANTS_H_
diff --git a/chromium/components/ntp_tiles/icon_cacher.h b/chromium/components/ntp_tiles/icon_cacher.h
index bfea2969464..8b5a2d3975d 100644
--- a/chromium/components/ntp_tiles/icon_cacher.h
+++ b/chromium/components/ntp_tiles/icon_cacher.h
@@ -10,12 +10,12 @@
namespace ntp_tiles {
-// Ensures that a Popular Sites icon is cached, downloading and saving it if
-// not.
+// Ensures that Popular Sites icons and MostLikely icons are cached, downloading
+// and saving them if not.
//
-// Does not provide any way to get a fetched favicon; use the FaviconService for
-// that. All this interface guarantees is that FaviconService will be able to
-// get you an icon (if it exists).
+// Does not provide any way to get a fetched favicon; use the FaviconService /
+// LargeIconService for that. All this interface guarantees is that
+// FaviconService will be able to get you an icon (if it exists).
class IconCacher {
public:
virtual ~IconCacher() = default;
@@ -25,9 +25,15 @@ class IconCacher {
// If there are preliminary icons (e.g. provided by static resources), the
// optional |preliminary_icon_available| callback will be invoked in addition.
// TODO(fhorschig): In case we keep these, make them OnceClosures.
- virtual void StartFetch(PopularSites::Site site,
- const base::Closure& icon_available,
- const base::Closure& preliminary_icon_available) = 0;
+ virtual void StartFetchPopularSites(
+ PopularSites::Site site,
+ const base::Closure& icon_available,
+ const base::Closure& preliminary_icon_available) = 0;
+
+ // Fetches the icon if necessary, then invokes |done| with true if it was
+ // newly fetched (false if it was already cached or could not be fetched).
+ virtual void StartFetchMostLikely(const GURL& page_url,
+ const base::Closure& icon_available) = 0;
};
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/icon_cacher_impl.cc b/chromium/components/ntp_tiles/icon_cacher_impl.cc
index f8480de51e9..015685fac36 100644
--- a/chromium/components/ntp_tiles/icon_cacher_impl.cc
+++ b/chromium/components/ntp_tiles/icon_cacher_impl.cc
@@ -7,12 +7,16 @@
#include <utility>
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "components/favicon/core/favicon_service.h"
#include "components/favicon/core/favicon_util.h"
+#include "components/favicon/core/large_icon_service.h"
+#include "components/favicon_base/fallback_icon_style.h"
#include "components/favicon_base/favicon_types.h"
#include "components/favicon_base/favicon_util.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/image_fetcher/core/image_fetcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
@@ -24,6 +28,12 @@ namespace {
constexpr int kDesiredFrameSize = 128;
+// TODO(jkrcal): Make the size in dip and the scale factor be passed as
+// arguments from the UI so that we desire for the right size on a given device.
+// See crbug.com/696563.
+constexpr int kTileIconMinSizePx = 48;
+constexpr int kTileIconDesiredSizePx = 96;
+
favicon_base::IconType IconType(const PopularSites::Site& site) {
return site.large_icon_url.is_valid() ? favicon_base::TOUCH_ICON
: favicon_base::FAVICON;
@@ -34,12 +44,22 @@ const GURL& IconURL(const PopularSites::Site& site) {
: site.favicon_url;
}
+bool HasResultDefaultBackgroundColor(
+ const favicon_base::LargeIconResult& result) {
+ if (!result.fallback_icon_style) {
+ return false;
+ }
+ return result.fallback_icon_style->is_default_background_color;
+}
+
} // namespace
IconCacherImpl::IconCacherImpl(
favicon::FaviconService* favicon_service,
+ favicon::LargeIconService* large_icon_service,
std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher)
: favicon_service_(favicon_service),
+ large_icon_service_(large_icon_service),
image_fetcher_(std::move(image_fetcher)),
weak_ptr_factory_(this) {
image_fetcher_->SetDataUseServiceName(
@@ -51,48 +71,72 @@ IconCacherImpl::IconCacherImpl(
IconCacherImpl::~IconCacherImpl() = default;
-void IconCacherImpl::StartFetch(
+void IconCacherImpl::StartFetchPopularSites(
PopularSites::Site site,
const base::Closure& icon_available,
const base::Closure& preliminary_icon_available) {
// Copy values from |site| before it is moved.
GURL site_url = site.url;
+ if (!StartRequest(site_url, icon_available)) {
+ return;
+ }
+
favicon_base::IconType icon_type = IconType(site);
favicon::GetFaviconImageForPageURL(
favicon_service_, site_url, icon_type,
base::Bind(&IconCacherImpl::OnGetFaviconImageForPageURLFinished,
- base::Unretained(this), std::move(site), icon_available,
+ base::Unretained(this), std::move(site),
preliminary_icon_available),
&tracker_);
}
void IconCacherImpl::OnGetFaviconImageForPageURLFinished(
PopularSites::Site site,
- const base::Closure& icon_available,
const base::Closure& preliminary_icon_available,
const favicon_base::FaviconImageResult& result) {
if (!result.image.IsEmpty()) {
+ FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/false);
return;
}
std::unique_ptr<CancelableImageCallback> preliminary_callback =
MaybeProvideDefaultIcon(site, preliminary_icon_available);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("icon_cacher", R"(
+ semantics {
+ sender: "Popular Sites New Tab Fetch"
+ description:
+ "Chrome may display a list of regionally-popular web sites on the "
+ "New Tab Page. This service fetches icons from those sites."
+ trigger:
+ "Whenever a popular site would be displayed, but its icon is not "
+ "yet cached in the browser."
+ data: "The URL for which to retrieve an icon."
+ destination: WEBSITE
+ }
+ policy {
+ cookies_allowed: false
+ setting: "This feature cannot be disabled in settings."
+ policy_exception_justification: "Not implemented."
+ })");
image_fetcher_->StartOrQueueNetworkRequest(
std::string(), IconURL(site),
- base::Bind(&IconCacherImpl::OnFaviconDownloaded, base::Unretained(this),
- site, base::Passed(std::move(preliminary_callback)),
- icon_available));
+ base::Bind(&IconCacherImpl::OnPopularSitesFaviconDownloaded,
+ base::Unretained(this), site,
+ base::Passed(std::move(preliminary_callback))),
+ traffic_annotation);
}
-void IconCacherImpl::OnFaviconDownloaded(
+void IconCacherImpl::OnPopularSitesFaviconDownloaded(
PopularSites::Site site,
std::unique_ptr<CancelableImageCallback> preliminary_callback,
- const base::Closure& icon_available,
const std::string& id,
const gfx::Image& fetched_image,
const image_fetcher::RequestMetadata& metadata) {
if (fetched_image.IsEmpty()) {
+ FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/false);
+ UMA_HISTOGRAM_BOOLEAN("NewTabPage.TileFaviconFetchSuccess.Popular", false);
return;
}
@@ -101,13 +145,23 @@ void IconCacherImpl::OnFaviconDownloaded(
if (preliminary_callback) {
preliminary_callback->Cancel();
}
- SaveAndNotifyIconForSite(site, icon_available, fetched_image);
+ SaveIconForSite(site, fetched_image);
+ FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/true);
+ UMA_HISTOGRAM_BOOLEAN("NewTabPage.TileFaviconFetchSuccess.Popular", true);
}
-void IconCacherImpl::SaveAndNotifyIconForSite(
+void IconCacherImpl::SaveAndNotifyDefaultIconForSite(
const PopularSites::Site& site,
- const base::Closure& icon_available,
+ const base::Closure& preliminary_icon_available,
const gfx::Image& image) {
+ SaveIconForSite(site, image);
+ if (preliminary_icon_available) {
+ preliminary_icon_available.Run();
+ }
+}
+
+void IconCacherImpl::SaveIconForSite(const PopularSites::Site& site,
+ const gfx::Image& image) {
// Although |SetFaviconColorSpace| affects OSX only, copies of gfx::Images are
// just copies of the reference to the image and therefore cheap.
gfx::Image img(image);
@@ -115,22 +169,19 @@ void IconCacherImpl::SaveAndNotifyIconForSite(
favicon_service_->SetFavicons(site.url, IconURL(site), IconType(site),
std::move(img));
-
- if (icon_available) {
- icon_available.Run();
- }
}
std::unique_ptr<IconCacherImpl::CancelableImageCallback>
-IconCacherImpl::MaybeProvideDefaultIcon(const PopularSites::Site& site,
- const base::Closure& icon_available) {
+IconCacherImpl::MaybeProvideDefaultIcon(
+ const PopularSites::Site& site,
+ const base::Closure& preliminary_icon_available) {
if (site.default_icon_resource < 0) {
return std::unique_ptr<CancelableImageCallback>();
}
std::unique_ptr<CancelableImageCallback> preliminary_callback(
- new CancelableImageCallback(
- base::Bind(&IconCacherImpl::SaveAndNotifyIconForSite,
- weak_ptr_factory_.GetWeakPtr(), site, icon_available)));
+ new CancelableImageCallback(base::Bind(
+ &IconCacherImpl::SaveAndNotifyDefaultIconForSite,
+ weak_ptr_factory_.GetWeakPtr(), site, preliminary_icon_available)));
image_fetcher_->GetImageDecoder()->DecodeImage(
ResourceBundle::GetSharedInstance()
.GetRawDataResource(site.default_icon_resource)
@@ -140,4 +191,66 @@ IconCacherImpl::MaybeProvideDefaultIcon(const PopularSites::Site& site,
return preliminary_callback;
}
+void IconCacherImpl::StartFetchMostLikely(const GURL& page_url,
+ const base::Closure& icon_available) {
+ if (!StartRequest(page_url, icon_available)) {
+ return;
+ }
+
+ // Desired size 0 means that we do not want the service to resize the image
+ // (as we will not use it anyway).
+ large_icon_service_->GetLargeIconOrFallbackStyle(
+ page_url, kTileIconMinSizePx, /*desired_size_in_pixel=*/0,
+ base::Bind(&IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished,
+ weak_ptr_factory_.GetWeakPtr(), page_url),
+ &tracker_);
+}
+
+void IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished(
+ const GURL& page_url,
+ const favicon_base::LargeIconResult& result) {
+ if (!HasResultDefaultBackgroundColor(result)) {
+ // We should only fetch for default "gray" tiles so that we never overrite
+ // any favicon of any size.
+ FinishRequestAndNotifyIconAvailable(page_url, /*newly_available=*/false);
+ return;
+ }
+
+ large_icon_service_
+ ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
+ page_url, kTileIconMinSizePx, kTileIconDesiredSizePx,
+ /*may_page_url_be_private=*/true,
+ base::Bind(&IconCacherImpl::OnMostLikelyFaviconDownloaded,
+ weak_ptr_factory_.GetWeakPtr(), page_url));
+}
+
+void IconCacherImpl::OnMostLikelyFaviconDownloaded(const GURL& request_url,
+ bool success) {
+ UMA_HISTOGRAM_BOOLEAN("NewTabPage.TileFaviconFetchSuccess.Server", success);
+ FinishRequestAndNotifyIconAvailable(request_url, success);
+}
+
+bool IconCacherImpl::StartRequest(const GURL& request_url,
+ const base::Closure& icon_available) {
+ bool in_flight = in_flight_requests_.count(request_url) > 0;
+ in_flight_requests_[request_url].push_back(icon_available);
+ return !in_flight;
+}
+
+void IconCacherImpl::FinishRequestAndNotifyIconAvailable(
+ const GURL& request_url,
+ bool newly_available) {
+ std::vector<base::Closure> callbacks =
+ std::move(in_flight_requests_[request_url]);
+ in_flight_requests_.erase(request_url);
+ if (!newly_available) {
+ return;
+ }
+ for (const base::Closure& callback : callbacks) {
+ if (callback) {
+ callback.Run();
+ }
+ }
+}
+
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/icon_cacher_impl.h b/chromium/components/ntp_tiles/icon_cacher_impl.h
index 58ed735eb65..a124b2c21d2 100644
--- a/chromium/components/ntp_tiles/icon_cacher_impl.h
+++ b/chromium/components/ntp_tiles/icon_cacher_impl.h
@@ -6,7 +6,9 @@
#define COMPONENTS_NTP_TILES_ICON_CACHER_IMPL_H_
#include <memory>
+#include <set>
#include <string>
+#include <vector>
#include "base/callback.h"
#include "base/cancelable_callback.h"
@@ -17,10 +19,12 @@
namespace favicon {
class FaviconService;
+class LargeIconService;
} // namespace favicon
namespace favicon_base {
struct FaviconImageResult;
+struct LargeIconResult;
} // namespace favicon_base
namespace gfx {
@@ -36,13 +40,19 @@ namespace ntp_tiles {
class IconCacherImpl : public IconCacher {
public:
+ // TODO(jkrcal): Make this eventually use only LargeIconService.
+ // crbug.com/696563
IconCacherImpl(favicon::FaviconService* favicon_service,
+ favicon::LargeIconService* large_icon_service,
std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher);
~IconCacherImpl() override;
- void StartFetch(PopularSites::Site site,
- const base::Closure& icon_available,
- const base::Closure& preliminary_icon_available) override;
+ void StartFetchPopularSites(
+ PopularSites::Site site,
+ const base::Closure& icon_available,
+ const base::Closure& preliminary_icon_available) override;
+ void StartFetchMostLikely(const GURL& page_url,
+ const base::Closure& icon_available) override;
private:
using CancelableImageCallback =
@@ -50,28 +60,41 @@ class IconCacherImpl : public IconCacher {
void OnGetFaviconImageForPageURLFinished(
PopularSites::Site site,
- const base::Closure& icon_available,
const base::Closure& preliminary_icon_available,
const favicon_base::FaviconImageResult& result);
- void OnFaviconDownloaded(
+ void OnPopularSitesFaviconDownloaded(
PopularSites::Site site,
std::unique_ptr<CancelableImageCallback> preliminary_callback,
- const base::Closure& icon_available,
const std::string& id,
const gfx::Image& fetched_image,
const image_fetcher::RequestMetadata& metadata);
std::unique_ptr<CancelableImageCallback> MaybeProvideDefaultIcon(
const PopularSites::Site& site,
- const base::Closure& icon_available);
- void SaveAndNotifyIconForSite(const PopularSites::Site& site,
- const base::Closure& icon_available,
- const gfx::Image& image);
+ const base::Closure& preliminary_icon_available);
+ void SaveAndNotifyDefaultIconForSite(
+ const PopularSites::Site& site,
+ const base::Closure& preliminary_icon_available,
+ const gfx::Image& image);
+ void SaveIconForSite(const PopularSites::Site& site, const gfx::Image& image);
+
+ void OnGetLargeIconOrFallbackStyleFinished(
+ const GURL& page_url,
+ const favicon_base::LargeIconResult& result);
+
+ void OnMostLikelyFaviconDownloaded(const GURL& request_url, bool success);
+
+ bool StartRequest(const GURL& request_url,
+ const base::Closure& icon_available);
+ void FinishRequestAndNotifyIconAvailable(const GURL& request_url,
+ bool newly_available);
base::CancelableTaskTracker tracker_;
favicon::FaviconService* const favicon_service_;
+ favicon::LargeIconService* const large_icon_service_;
std::unique_ptr<image_fetcher::ImageFetcher> const image_fetcher_;
+ std::map<GURL, std::vector<base::Closure>> in_flight_requests_;
base::WeakPtrFactory<IconCacherImpl> weak_ptr_factory_;
diff --git a/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc b/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc
index 4a2ddc2513d..54f2fc20f3f 100644
--- a/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc
+++ b/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc
@@ -11,6 +11,7 @@
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
+#include "base/test/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_simple_task_runner.h"
@@ -18,21 +19,26 @@
#include "components/favicon/core/favicon_client.h"
#include "components/favicon/core/favicon_service_impl.h"
#include "components/favicon/core/favicon_util.h"
+#include "components/favicon/core/large_icon_service.h"
#include "components/history/core/browser/history_database_params.h"
#include "components/history/core/browser/history_service.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/image_fetcher/core/request_metadata.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/gfx/image/image_unittest_util.h"
+using base::Bucket;
using ::testing::_;
+using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::InSequence;
+using ::testing::IsEmpty;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnArg;
@@ -48,10 +54,11 @@ class MockImageFetcher : public image_fetcher::ImageFetcher {
void(image_fetcher::ImageFetcher::DataUseServiceName name));
MOCK_METHOD1(SetImageDownloadLimit,
void(base::Optional<int64_t> max_download_bytes));
- MOCK_METHOD3(StartOrQueueNetworkRequest,
+ MOCK_METHOD4(StartOrQueueNetworkRequest,
void(const std::string& id,
const GURL& image_url,
- const ImageFetcherCallback& callback));
+ const ImageFetcherCallback& callback,
+ const net::NetworkTrafficAnnotationTag&));
MOCK_METHOD1(SetDesiredImageFrameSize, void(const gfx::Size&));
MOCK_METHOD0(GetImageDecoder, image_fetcher::ImageDecoder*());
};
@@ -94,54 +101,37 @@ class MockResourceDelegate : public ui::ResourceBundle::Delegate {
MOCK_METHOD2(GetLocalizedString, bool(int message_id, base::string16* value));
};
-class IconCacherTest : public ::testing::Test {
- protected:
- IconCacherTest()
- : site_(base::string16(), // title, unused
- GURL("http://url.google/"),
- GURL("http://url.google/icon.png"),
- GURL("http://url.google/favicon.ico"),
- GURL()), // thumbnail, unused
- image_fetcher_(new ::testing::StrictMock<MockImageFetcher>),
- image_decoder_(new ::testing::StrictMock<MockImageDecoder>),
- favicon_service_(/*favicon_client=*/nullptr, &history_service_),
- task_runner_(new base::TestSimpleTaskRunner()) {
- CHECK(history_dir_.CreateUniqueTempDir());
- CHECK(history_service_.Init(
- history::HistoryDatabaseParams(history_dir_.GetPath(), 0, 0)));
- }
+ACTION(FailFetch) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(arg2, arg0, gfx::Image(), image_fetcher::RequestMetadata()));
+}
- void SetUp() override {
- if (ui::ResourceBundle::HasSharedInstance()) {
- ui::ResourceBundle::CleanupSharedInstance();
- }
- ON_CALL(mock_resource_delegate_, GetPathForResourcePack(_, _))
- .WillByDefault(ReturnArg<0>());
- ON_CALL(mock_resource_delegate_, GetPathForLocalePack(_, _))
- .WillByDefault(ReturnArg<0>());
- ui::ResourceBundle::InitSharedInstanceWithLocale(
- "en-US", &mock_resource_delegate_,
- ui::ResourceBundle::LOAD_COMMON_RESOURCES);
- }
+ACTION_P2(DecodeSuccessfully, width, height) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(arg2, gfx::test::CreateImage(width, height)));
+}
- void TearDown() override {
- if (ui::ResourceBundle::HasSharedInstance()) {
- ui::ResourceBundle::CleanupSharedInstance();
- }
- base::FilePath pak_path;
-#if defined(OS_ANDROID)
- PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &pak_path);
-#else
- PathService::Get(base::DIR_MODULE, &pak_path);
-#endif
+ACTION_P2(PassFetch, width, height) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(arg2, arg0, gfx::test::CreateImage(width, height),
+ image_fetcher::RequestMetadata()));
+}
- base::FilePath ui_test_pak_path;
- ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
- ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
+ACTION_P(Quit, run_loop) {
+ run_loop->Quit();
+}
- ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
- pak_path.AppendASCII("components_tests_resources.pak"),
- ui::SCALE_FACTOR_NONE);
+// TODO(jkrcal): Split off large_icon_service.h and large_icon_service_impl.h.
+// Use then mocks of FaviconService and LargeIconService instead of the real
+// things.
+class IconCacherTestBase : public ::testing::Test {
+ protected:
+ IconCacherTestBase()
+ : favicon_service_(/*favicon_client=*/nullptr, &history_service_) {
+ CHECK(history_dir_.CreateUniqueTempDir());
+ CHECK(history_service_.Init(
+ history::HistoryDatabaseParams(history_dir_.GetPath(), 0, 0)));
}
void PreloadIcon(const GURL& url,
@@ -176,41 +166,77 @@ class IconCacherTest : public ::testing::Test {
return image;
}
- void WaitForTasksToFinish() { task_runner_->RunUntilIdle(); }
+ void WaitForHistoryThreadTasksToFinish() {
+ base::RunLoop loop;
+ base::MockCallback<base::Closure> done;
+ EXPECT_CALL(done, Run()).WillOnce(Quit(&loop));
+ history_service_.FlushForTest(done.Get());
+ loop.Run();
+ }
+
+ void WaitForMainThreadTasksToFinish() {
+ base::RunLoop loop;
+ loop.RunUntilIdle();
+ }
base::test::ScopedTaskEnvironment scoped_task_environment_;
- PopularSites::Site site_;
- std::unique_ptr<MockImageFetcher> image_fetcher_;
- std::unique_ptr<MockImageDecoder> image_decoder_;
base::ScopedTempDir history_dir_;
history::HistoryService history_service_;
favicon::FaviconServiceImpl favicon_service_;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
- NiceMock<MockResourceDelegate> mock_resource_delegate_;
};
-ACTION(FailFetch) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(arg2, arg0, gfx::Image(), image_fetcher::RequestMetadata()));
-}
+class IconCacherTestPopularSites : public IconCacherTestBase {
+ protected:
+ IconCacherTestPopularSites()
+ : site_(base::string16(), // title, unused
+ GURL("http://url.google/"),
+ GURL("http://url.google/icon.png"),
+ GURL("http://url.google/favicon.ico"),
+ GURL()), // thumbnail, unused
+ image_fetcher_(new ::testing::StrictMock<MockImageFetcher>),
+ image_decoder_(new ::testing::StrictMock<MockImageDecoder>) {}
-ACTION_P2(DecodeSuccessfully, width, height) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(arg2, gfx::test::CreateImage(width, height)));
-}
+ void SetUp() override {
+ if (ui::ResourceBundle::HasSharedInstance()) {
+ ui::ResourceBundle::CleanupSharedInstance();
+ }
+ ON_CALL(mock_resource_delegate_, GetPathForResourcePack(_, _))
+ .WillByDefault(ReturnArg<0>());
+ ON_CALL(mock_resource_delegate_, GetPathForLocalePack(_, _))
+ .WillByDefault(ReturnArg<0>());
+ ui::ResourceBundle::InitSharedInstanceWithLocale(
+ "en-US", &mock_resource_delegate_,
+ ui::ResourceBundle::LOAD_COMMON_RESOURCES);
+ }
-ACTION_P2(PassFetch, width, height) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(arg2, arg0, gfx::test::CreateImage(width, height),
- image_fetcher::RequestMetadata()));
-}
+ void TearDown() override {
+ if (ui::ResourceBundle::HasSharedInstance()) {
+ ui::ResourceBundle::CleanupSharedInstance();
+ }
+ base::FilePath pak_path;
+#if defined(OS_ANDROID)
+ PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &pak_path);
+#else
+ PathService::Get(base::DIR_MODULE, &pak_path);
+#endif
-ACTION_P(Quit, run_loop) {
- run_loop->Quit();
-}
+ base::FilePath ui_test_pak_path;
+ ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
+ ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
-TEST_F(IconCacherTest, LargeCached) {
+ ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
+ pak_path.AppendASCII("components_tests_resources.pak"),
+ ui::SCALE_FACTOR_NONE);
+ }
+
+ PopularSites::Site site_;
+ std::unique_ptr<MockImageFetcher> image_fetcher_;
+ std::unique_ptr<MockImageDecoder> image_decoder_;
+ NiceMock<MockResourceDelegate> mock_resource_delegate_;
+};
+
+TEST_F(IconCacherTestPopularSites, LargeCached) {
+ base::HistogramTester histogram_tester;
base::MockCallback<base::Closure> done;
EXPECT_CALL(done, Run()).Times(0);
base::RunLoop loop;
@@ -223,14 +249,18 @@ TEST_F(IconCacherTest, LargeCached) {
}
PreloadIcon(site_.url, site_.large_icon_url, favicon_base::TOUCH_ICON, 128,
128);
- IconCacherImpl cacher(&favicon_service_, std::move(image_fetcher_));
- cacher.StartFetch(site_, done.Get(), done.Get());
- WaitForTasksToFinish();
+ IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
+ cacher.StartFetchPopularSites(site_, done.Get(), done.Get());
+ WaitForMainThreadTasksToFinish();
EXPECT_FALSE(IconIsCachedFor(site_.url, favicon_base::FAVICON));
EXPECT_TRUE(IconIsCachedFor(site_.url, favicon_base::TOUCH_ICON));
+ EXPECT_THAT(histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Popular"),
+ IsEmpty());
}
-TEST_F(IconCacherTest, LargeNotCachedAndFetchSucceeded) {
+TEST_F(IconCacherTestPopularSites, LargeNotCachedAndFetchSucceeded) {
+ base::HistogramTester histogram_tester;
base::MockCallback<base::Closure> done;
base::RunLoop loop;
{
@@ -240,19 +270,22 @@ TEST_F(IconCacherTest, LargeNotCachedAndFetchSucceeded) {
data_use_measurement::DataUseUserData::NTP_TILES));
EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
EXPECT_CALL(*image_fetcher_,
- StartOrQueueNetworkRequest(_, site_.large_icon_url, _))
+ StartOrQueueNetworkRequest(_, site_.large_icon_url, _, _))
.WillOnce(PassFetch(128, 128));
EXPECT_CALL(done, Run()).WillOnce(Quit(&loop));
}
- IconCacherImpl cacher(&favicon_service_, std::move(image_fetcher_));
- cacher.StartFetch(site_, done.Get(), done.Get());
+ IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
+ cacher.StartFetchPopularSites(site_, done.Get(), done.Get());
loop.Run();
EXPECT_FALSE(IconIsCachedFor(site_.url, favicon_base::FAVICON));
EXPECT_TRUE(IconIsCachedFor(site_.url, favicon_base::TOUCH_ICON));
+ EXPECT_THAT(histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Popular"),
+ ElementsAre(Bucket(/*bucket=*/true, /*count=*/1)));
}
-TEST_F(IconCacherTest, SmallNotCachedAndFetchSucceeded) {
+TEST_F(IconCacherTestPopularSites, SmallNotCachedAndFetchSucceeded) {
site_.large_icon_url = GURL();
base::MockCallback<base::Closure> done;
@@ -264,19 +297,20 @@ TEST_F(IconCacherTest, SmallNotCachedAndFetchSucceeded) {
data_use_measurement::DataUseUserData::NTP_TILES));
EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
EXPECT_CALL(*image_fetcher_,
- StartOrQueueNetworkRequest(_, site_.favicon_url, _))
+ StartOrQueueNetworkRequest(_, site_.favicon_url, _, _))
.WillOnce(PassFetch(128, 128));
EXPECT_CALL(done, Run()).WillOnce(Quit(&loop));
}
- IconCacherImpl cacher(&favicon_service_, std::move(image_fetcher_));
- cacher.StartFetch(site_, done.Get(), done.Get());
+ IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
+ cacher.StartFetchPopularSites(site_, done.Get(), done.Get());
loop.Run();
EXPECT_TRUE(IconIsCachedFor(site_.url, favicon_base::FAVICON));
EXPECT_FALSE(IconIsCachedFor(site_.url, favicon_base::TOUCH_ICON));
}
-TEST_F(IconCacherTest, LargeNotCachedAndFetchFailed) {
+TEST_F(IconCacherTestPopularSites, LargeNotCachedAndFetchFailed) {
+ base::HistogramTester histogram_tester;
base::MockCallback<base::Closure> done;
EXPECT_CALL(done, Run()).Times(0);
{
@@ -286,28 +320,43 @@ TEST_F(IconCacherTest, LargeNotCachedAndFetchFailed) {
data_use_measurement::DataUseUserData::NTP_TILES));
EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
EXPECT_CALL(*image_fetcher_,
- StartOrQueueNetworkRequest(_, site_.large_icon_url, _))
+ StartOrQueueNetworkRequest(_, site_.large_icon_url, _, _))
.WillOnce(FailFetch());
}
- IconCacherImpl cacher(&favicon_service_, std::move(image_fetcher_));
- cacher.StartFetch(site_, done.Get(), done.Get());
- WaitForTasksToFinish();
+ IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
+ cacher.StartFetchPopularSites(site_, done.Get(), done.Get());
+ WaitForMainThreadTasksToFinish();
EXPECT_FALSE(IconIsCachedFor(site_.url, favicon_base::FAVICON));
EXPECT_FALSE(IconIsCachedFor(site_.url, favicon_base::TOUCH_ICON));
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Popular"),
+ ElementsAre(Bucket(/*bucket=*/false, /*count=*/1)));
}
-TEST_F(IconCacherTest, HandlesEmptyCallbacksNicely) {
+TEST_F(IconCacherTestPopularSites, HandlesEmptyCallbacksNicely) {
+ base::HistogramTester histogram_tester;
EXPECT_CALL(*image_fetcher_, SetDataUseServiceName(_));
EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(_));
- ON_CALL(*image_fetcher_, StartOrQueueNetworkRequest(_, _, _))
- .WillByDefault(PassFetch(128, 128));
- IconCacherImpl cacher(&favicon_service_, std::move(image_fetcher_));
- cacher.StartFetch(site_, base::Closure(), base::Closure());
- WaitForTasksToFinish();
+ EXPECT_CALL(*image_fetcher_, StartOrQueueNetworkRequest(_, _, _, _))
+ .WillOnce(PassFetch(128, 128));
+ IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
+ cacher.StartFetchPopularSites(site_, base::Closure(), base::Closure());
+ WaitForHistoryThreadTasksToFinish(); // Writing the icon into the DB.
+ WaitForMainThreadTasksToFinish(); // Finishing tasks after the DB write.
+ // Even though the callbacks are not called, the icon gets written out.
+ EXPECT_FALSE(IconIsCachedFor(site_.url, favicon_base::FAVICON));
+ EXPECT_TRUE(IconIsCachedFor(site_.url, favicon_base::TOUCH_ICON));
+ // The histogram gets reported despite empty callbacks.
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Popular"),
+ ElementsAre(Bucket(/*bucket=*/true, /*count=*/1)));
}
-TEST_F(IconCacherTest, ProvidesDefaultIconAndSucceedsWithFetching) {
+TEST_F(IconCacherTestPopularSites, ProvidesDefaultIconAndSucceedsWithFetching) {
+ base::HistogramTester histogram_tester;
// The returned data string is not used by the mocked decoder.
ON_CALL(mock_resource_delegate_, GetRawDataResource(12345, _, _))
.WillByDefault(Return(""));
@@ -328,7 +377,7 @@ TEST_F(IconCacherTest, ProvidesDefaultIconAndSucceedsWithFetching) {
data_use_measurement::DataUseUserData::NTP_TILES));
EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
EXPECT_CALL(*image_fetcher_,
- StartOrQueueNetworkRequest(_, site_.large_icon_url, _))
+ StartOrQueueNetworkRequest(_, site_.large_icon_url, _, _))
.WillOnce(PassFetch(128, 128));
// Both callback are called async after the request but preliminary has to
@@ -338,10 +387,10 @@ TEST_F(IconCacherTest, ProvidesDefaultIconAndSucceedsWithFetching) {
EXPECT_CALL(icon_available, Run()).WillOnce(Quit(&fetch_loop));
}
- IconCacherImpl cacher(&favicon_service_, std::move(image_fetcher_));
+ IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
site_.default_icon_resource = 12345;
- cacher.StartFetch(site_, icon_available.Get(),
- preliminary_icon_available.Get());
+ cacher.StartFetchPopularSites(site_, icon_available.Get(),
+ preliminary_icon_available.Get());
default_loop.Run(); // Wait for the default image.
EXPECT_THAT(GetCachedIconFor(site_.url, favicon_base::TOUCH_ICON).Size(),
@@ -351,6 +400,224 @@ TEST_F(IconCacherTest, ProvidesDefaultIconAndSucceedsWithFetching) {
fetch_loop.Run(); // Wait for the updated image.
EXPECT_THAT(GetCachedIconFor(site_.url, favicon_base::TOUCH_ICON).Size(),
Eq(gfx::Size(128, 128))); // Compares dimensions, not objects.
+ // The histogram gets reported only once (for the downloaded icon, not for the
+ // default one).
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Popular"),
+ ElementsAre(Bucket(/*bucket=*/true, /*count=*/1)));
+}
+
+TEST_F(IconCacherTestPopularSites, LargeNotCachedAndFetchPerformedOnlyOnce) {
+ base::MockCallback<base::Closure> done;
+ base::RunLoop loop;
+ {
+ InSequence s;
+ // Image fetcher is used only once.
+ EXPECT_CALL(*image_fetcher_,
+ SetDataUseServiceName(
+ data_use_measurement::DataUseUserData::NTP_TILES));
+ EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
+ EXPECT_CALL(*image_fetcher_,
+ StartOrQueueNetworkRequest(_, site_.large_icon_url, _, _))
+ .WillOnce(PassFetch(128, 128));
+ // Success will be notified to both requests.
+ EXPECT_CALL(done, Run()).WillOnce(Return()).WillOnce(Quit(&loop));
+ }
+
+ IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
+ cacher.StartFetchPopularSites(site_, done.Get(), done.Get());
+ cacher.StartFetchPopularSites(site_, done.Get(), done.Get());
+ loop.Run();
+ EXPECT_FALSE(IconIsCachedFor(site_.url, favicon_base::FAVICON));
+ EXPECT_TRUE(IconIsCachedFor(site_.url, favicon_base::TOUCH_ICON));
+}
+
+class IconCacherTestMostLikely : public IconCacherTestBase {
+ protected:
+ IconCacherTestMostLikely()
+ : large_icon_service_background_task_runner_(
+ new base::TestSimpleTaskRunner()),
+ fetcher_for_large_icon_service_(
+ base::MakeUnique<::testing::StrictMock<MockImageFetcher>>()),
+ fetcher_for_icon_cacher_(
+ base::MakeUnique<::testing::StrictMock<MockImageFetcher>>()) {
+ // Expect uninteresting calls here, |fetcher_for_icon_cacher_| is not
+ // related to these tests. Keep it strict to make sure we do not use it in
+ // any other way.
+ EXPECT_CALL(*fetcher_for_icon_cacher_,
+ SetDataUseServiceName(
+ data_use_measurement::DataUseUserData::NTP_TILES));
+ EXPECT_CALL(*fetcher_for_icon_cacher_,
+ SetDesiredImageFrameSize(gfx::Size(128, 128)));
+ }
+
+ scoped_refptr<base::TestSimpleTaskRunner>
+ large_icon_service_background_task_runner_;
+ std::unique_ptr<MockImageFetcher> fetcher_for_large_icon_service_;
+ std::unique_ptr<MockImageFetcher> fetcher_for_icon_cacher_;
+};
+
+TEST_F(IconCacherTestMostLikely, Cached) {
+ GURL page_url("http://www.site.com");
+ base::HistogramTester histogram_tester;
+
+ GURL icon_url("http://www.site.com/favicon.png");
+ PreloadIcon(page_url, icon_url, favicon_base::TOUCH_ICON, 128, 128);
+
+ favicon::LargeIconService large_icon_service(
+ &favicon_service_, large_icon_service_background_task_runner_,
+ std::move(fetcher_for_large_icon_service_));
+ IconCacherImpl cacher(&favicon_service_, &large_icon_service,
+ std::move(fetcher_for_icon_cacher_));
+
+ base::MockCallback<base::Closure> done;
+ EXPECT_CALL(done, Run()).Times(0);
+ cacher.StartFetchMostLikely(page_url, done.Get());
+ WaitForMainThreadTasksToFinish();
+
+ EXPECT_FALSE(IconIsCachedFor(page_url, favicon_base::FAVICON));
+ EXPECT_TRUE(IconIsCachedFor(page_url, favicon_base::TOUCH_ICON));
+ EXPECT_THAT(histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Server"),
+ IsEmpty());
+}
+
+TEST_F(IconCacherTestMostLikely, NotCachedAndFetchSucceeded) {
+ GURL page_url("http://www.site.com");
+ base::HistogramTester histogram_tester;
+
+ base::MockCallback<base::Closure> done;
+ base::RunLoop loop;
+ {
+ InSequence s;
+ EXPECT_CALL(*fetcher_for_large_icon_service_,
+ SetDataUseServiceName(
+ data_use_measurement::DataUseUserData::LARGE_ICON_SERVICE));
+ EXPECT_CALL(*fetcher_for_large_icon_service_,
+ StartOrQueueNetworkRequest(_, _, _, _))
+ .WillOnce(PassFetch(128, 128));
+ EXPECT_CALL(done, Run()).WillOnce(Quit(&loop));
+ }
+
+ favicon::LargeIconService large_icon_service(
+ &favicon_service_, large_icon_service_background_task_runner_,
+ std::move(fetcher_for_large_icon_service_));
+ IconCacherImpl cacher(&favicon_service_, &large_icon_service,
+ std::move(fetcher_for_icon_cacher_));
+
+ cacher.StartFetchMostLikely(page_url, done.Get());
+ // Both these task runners need to be flushed in order to get |done| called by
+ // running the main loop.
+ WaitForHistoryThreadTasksToFinish();
+ large_icon_service_background_task_runner_->RunUntilIdle();
+
+ loop.Run();
+ EXPECT_FALSE(IconIsCachedFor(page_url, favicon_base::FAVICON));
+ EXPECT_TRUE(IconIsCachedFor(page_url, favicon_base::TOUCH_ICON));
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Server"),
+ ElementsAre(Bucket(/*bucket=*/true, /*count=*/1)));
+}
+
+TEST_F(IconCacherTestMostLikely, NotCachedAndFetchFailed) {
+ GURL page_url("http://www.site.com");
+ base::HistogramTester histogram_tester;
+
+ base::MockCallback<base::Closure> done;
+ {
+ InSequence s;
+ EXPECT_CALL(*fetcher_for_large_icon_service_,
+ SetDataUseServiceName(
+ data_use_measurement::DataUseUserData::LARGE_ICON_SERVICE));
+ EXPECT_CALL(*fetcher_for_large_icon_service_,
+ StartOrQueueNetworkRequest(_, _, _, _))
+ .WillOnce(FailFetch());
+ EXPECT_CALL(done, Run()).Times(0);
+ }
+
+ favicon::LargeIconService large_icon_service(
+ &favicon_service_, large_icon_service_background_task_runner_,
+ std::move(fetcher_for_large_icon_service_));
+ IconCacherImpl cacher(&favicon_service_, &large_icon_service,
+ std::move(fetcher_for_icon_cacher_));
+
+ cacher.StartFetchMostLikely(page_url, done.Get());
+ // Both these task runners need to be flushed before flushing the main thread
+ // queue in order to finish the work.
+ WaitForHistoryThreadTasksToFinish();
+ large_icon_service_background_task_runner_->RunUntilIdle();
+ WaitForMainThreadTasksToFinish();
+
+ EXPECT_FALSE(IconIsCachedFor(page_url, favicon_base::FAVICON));
+ EXPECT_FALSE(IconIsCachedFor(page_url, favicon_base::TOUCH_ICON));
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples(
+ "NewTabPage.TileFaviconFetchSuccess.Server"),
+ ElementsAre(Bucket(/*bucket=*/false, /*count=*/1)));
+}
+
+TEST_F(IconCacherTestMostLikely, HandlesEmptyCallbacksNicely) {
+ GURL page_url("http://www.site.com");
+
+ EXPECT_CALL(*fetcher_for_large_icon_service_, SetDataUseServiceName(_));
+ EXPECT_CALL(*fetcher_for_large_icon_service_,
+ StartOrQueueNetworkRequest(_, _, _, _))
+ .WillOnce(PassFetch(128, 128));
+
+ favicon::LargeIconService large_icon_service(
+ &favicon_service_, large_icon_service_background_task_runner_,
+ std::move(fetcher_for_large_icon_service_));
+ IconCacherImpl cacher(&favicon_service_, &large_icon_service,
+ std::move(fetcher_for_icon_cacher_));
+
+ cacher.StartFetchMostLikely(page_url, base::Closure());
+ // Both these task runners need to be flushed before flushing the main thread
+ // queue in order to finish the work.
+ WaitForHistoryThreadTasksToFinish();
+ large_icon_service_background_task_runner_->RunUntilIdle();
+ WaitForMainThreadTasksToFinish();
+
+ // Even though the callbacks are not called, the icon gets written out.
+ EXPECT_FALSE(IconIsCachedFor(page_url, favicon_base::FAVICON));
+ EXPECT_TRUE(IconIsCachedFor(page_url, favicon_base::TOUCH_ICON));
+}
+
+TEST_F(IconCacherTestMostLikely, NotCachedAndFetchPerformedOnlyOnce) {
+ GURL page_url("http://www.site.com");
+
+ base::MockCallback<base::Closure> done;
+ base::RunLoop loop;
+ {
+ InSequence s;
+ // Image fetcher is used only once.
+ EXPECT_CALL(*fetcher_for_large_icon_service_,
+ SetDataUseServiceName(
+ data_use_measurement::DataUseUserData::LARGE_ICON_SERVICE));
+ EXPECT_CALL(*fetcher_for_large_icon_service_,
+ StartOrQueueNetworkRequest(_, _, _, _))
+ .WillOnce(PassFetch(128, 128));
+ // Success will be notified to both requests.
+ EXPECT_CALL(done, Run()).WillOnce(Return()).WillOnce(Quit(&loop));
+ }
+
+ favicon::LargeIconService large_icon_service(
+ &favicon_service_, large_icon_service_background_task_runner_,
+ std::move(fetcher_for_large_icon_service_));
+ IconCacherImpl cacher(&favicon_service_, &large_icon_service,
+ std::move(fetcher_for_icon_cacher_));
+
+ cacher.StartFetchMostLikely(page_url, done.Get());
+ cacher.StartFetchMostLikely(page_url, done.Get());
+ // Both these task runners need to be flushed in order to get |done| called by
+ // running the main loop.
+ WaitForHistoryThreadTasksToFinish();
+ large_icon_service_background_task_runner_->RunUntilIdle();
+
+ loop.Run();
+ EXPECT_FALSE(IconIsCachedFor(page_url, favicon_base::FAVICON));
+ EXPECT_TRUE(IconIsCachedFor(page_url, favicon_base::TOUCH_ICON));
}
} // namespace
diff --git a/chromium/components/ntp_tiles/metrics.cc b/chromium/components/ntp_tiles/metrics.cc
index 819a6aed935..f657ced1822 100644
--- a/chromium/components/ntp_tiles/metrics.cc
+++ b/chromium/components/ntp_tiles/metrics.cc
@@ -25,6 +25,7 @@ const char kHistogramClientName[] = "client";
const char kHistogramServerName[] = "server";
const char kHistogramPopularName[] = "popular";
const char kHistogramWhitelistName[] = "whitelist";
+const char kHistogramHomepageName[] = "homepage";
// Suffixes for the various icon types.
const char kTileTypeSuffixIconColor[] = "IconsColor";
@@ -56,6 +57,8 @@ std::string GetSourceHistogramName(TileSource source) {
return kHistogramWhitelistName;
case TileSource::SUGGESTIONS_SERVICE:
return kHistogramServerName;
+ case TileSource::HOMEPAGE:
+ return kHistogramHomepageName;
}
NOTREACHED();
return std::string();
diff --git a/chromium/components/ntp_tiles/most_visited_sites.cc b/chromium/components/ntp_tiles/most_visited_sites.cc
index 6809aa4dcbd..19c2f957f89 100644
--- a/chromium/components/ntp_tiles/most_visited_sites.cc
+++ b/chromium/components/ntp_tiles/most_visited_sites.cc
@@ -5,13 +5,12 @@
#include "components/ntp_tiles/most_visited_sites.h"
#include <algorithm>
-#include <set>
-#include <string>
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/feature_list.h"
+#include "base/metrics/user_metrics.h"
#include "base/strings/utf_string_conversions.h"
#include "components/history/core/browser/top_sites.h"
#include "components/ntp_tiles/constants.h"
@@ -53,15 +52,17 @@ MostVisitedSites::MostVisitedSites(
SuggestionsService* suggestions,
std::unique_ptr<PopularSites> popular_sites,
std::unique_ptr<IconCacher> icon_cacher,
- std::unique_ptr<MostVisitedSitesSupervisor> supervisor)
+ std::unique_ptr<MostVisitedSitesSupervisor> supervisor,
+ std::unique_ptr<HomePageClient> home_page_client)
: prefs_(prefs),
top_sites_(top_sites),
suggestions_service_(suggestions),
popular_sites_(std::move(popular_sites)),
icon_cacher_(std::move(icon_cacher)),
supervisor_(std::move(supervisor)),
+ home_page_client_(std::move(home_page_client)),
observer_(nullptr),
- num_sites_(0),
+ num_sites_(0u),
top_sites_observer_(this),
mv_source_(TileSource::TOP_SITES),
top_sites_weak_ptr_factory_(this) {
@@ -73,6 +74,21 @@ MostVisitedSites::MostVisitedSites(
supervisor_->SetObserver(this);
}
+MostVisitedSites::MostVisitedSites(
+ PrefService* prefs,
+ scoped_refptr<history::TopSites> top_sites,
+ SuggestionsService* suggestions,
+ std::unique_ptr<PopularSites> popular_sites,
+ std::unique_ptr<IconCacher> icon_cacher,
+ std::unique_ptr<MostVisitedSitesSupervisor> supervisor)
+ : MostVisitedSites(prefs,
+ top_sites,
+ suggestions,
+ std::move(popular_sites),
+ std::move(icon_cacher),
+ std::move(supervisor),
+ nullptr) {}
+
MostVisitedSites::~MostVisitedSites() {
if (supervisor_)
supervisor_->SetObserver(nullptr);
@@ -88,13 +104,15 @@ bool MostVisitedSites::DoesSourceExist(TileSource source) const {
return popular_sites_ != nullptr;
case TileSource::WHITELIST:
return supervisor_ != nullptr;
+ case TileSource::HOMEPAGE:
+ return home_page_client_ != nullptr;
}
NOTREACHED();
return false;
}
void MostVisitedSites::SetMostVisitedURLsObserver(Observer* observer,
- int num_sites) {
+ size_t num_sites) {
DCHECK(observer);
observer_ = observer;
num_sites_ = num_sites;
@@ -134,6 +152,13 @@ void MostVisitedSites::Refresh() {
void MostVisitedSites::AddOrRemoveBlacklistedUrl(const GURL& url,
bool add_url) {
+ if (add_url) {
+ base::RecordAction(base::UserMetricsAction("Suggestions.Site.Removed"));
+ } else {
+ base::RecordAction(
+ base::UserMetricsAction("Suggestions.Site.RemovalUndone"));
+ }
+
if (top_sites_) {
// Always blacklist in the local TopSites.
if (add_url)
@@ -203,8 +228,7 @@ void MostVisitedSites::OnMostVisitedURLsAvailable(
}
NTPTilesVector tiles;
- size_t num_tiles =
- std::min(visited_list.size(), static_cast<size_t>(num_sites_));
+ size_t num_tiles = std::min(visited_list.size(), num_sites_);
for (size_t i = 0; i < num_tiles; ++i) {
const history::MostVisitedURL& visited = visited_list[i];
if (visited.url.is_empty())
@@ -243,7 +267,7 @@ void MostVisitedSites::BuildCurrentTiles() {
void MostVisitedSites::BuildCurrentTilesGivenSuggestionsProfile(
const suggestions::SuggestionsProfile& suggestions_profile) {
- int num_tiles = suggestions_profile.suggestions_size();
+ size_t num_tiles = suggestions_profile.suggestions_size();
// With no server suggestions, fall back to local TopSites.
if (num_tiles == 0 ||
!base::FeatureList::IsEnabled(kDisplaySuggestionsServiceTiles)) {
@@ -255,7 +279,7 @@ void MostVisitedSites::BuildCurrentTilesGivenSuggestionsProfile(
num_tiles = num_sites_;
NTPTilesVector tiles;
- for (int i = 0; i < num_tiles; ++i) {
+ for (size_t i = 0; i < num_tiles; ++i) {
const ChromeSuggestion& suggestion_pb = suggestions_profile.suggestions(i);
GURL url(suggestion_pb.url());
if (supervisor_ && supervisor_->IsBlocked(url))
@@ -268,6 +292,11 @@ void MostVisitedSites::BuildCurrentTilesGivenSuggestionsProfile(
tile.whitelist_icon_path = GetWhitelistLargeIconPath(url);
tile.thumbnail_url = GURL(suggestion_pb.thumbnail());
tile.favicon_url = GURL(suggestion_pb.favicon_url());
+ if (AreNtpMostLikelyFaviconsFromServerEnabled()) {
+ icon_cacher_->StartFetchMostLikely(
+ url, base::Bind(&MostVisitedSites::OnIconMadeAvailable,
+ base::Unretained(this), url));
+ }
tiles.push_back(std::move(tile));
}
@@ -277,23 +306,15 @@ void MostVisitedSites::BuildCurrentTilesGivenSuggestionsProfile(
}
NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles(
- const NTPTilesVector& personal_tiles) {
+ const std::set<std::string>& used_hosts,
+ size_t num_actual_tiles) {
if (!supervisor_) {
return NTPTilesVector();
}
- size_t num_personal_tiles = personal_tiles.size();
- DCHECK_LE(num_personal_tiles, static_cast<size_t>(num_sites_));
-
- size_t num_whitelist_tiles = num_sites_ - num_personal_tiles;
NTPTilesVector whitelist_tiles;
-
- std::set<std::string> personal_hosts;
- for (const auto& tile : personal_tiles)
- personal_hosts.insert(tile.url.host());
-
for (const auto& whitelist : supervisor_->whitelists()) {
- if (whitelist_tiles.size() >= num_whitelist_tiles)
+ if (whitelist_tiles.size() + num_actual_tiles >= num_sites_)
break;
// Skip blacklisted sites.
@@ -301,8 +322,7 @@ NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles(
continue;
// Skip tiles already present.
- if (personal_hosts.find(whitelist.entry_point.host()) !=
- personal_hosts.end())
+ if (used_hosts.find(whitelist.entry_point.host()) != used_hosts.end())
continue;
// Skip whitelist entry points that are manually blocked.
@@ -321,62 +341,90 @@ NTPTilesVector MostVisitedSites::CreateWhitelistEntryPointTiles(
}
NTPTilesVector MostVisitedSites::CreatePopularSitesTiles(
- const NTPTilesVector& personal_tiles,
- const NTPTilesVector& whitelist_tiles) {
+ const std::set<std::string>& used_hosts,
+ size_t num_actual_tiles) {
// For child accounts popular sites tiles will not be added.
- if (supervisor_ && supervisor_->IsChildProfile())
+ if (supervisor_ && supervisor_->IsChildProfile()) {
return NTPTilesVector();
+ }
- size_t num_tiles = personal_tiles.size() + whitelist_tiles.size();
- DCHECK_LE(num_tiles, static_cast<size_t>(num_sites_));
+ if (!popular_sites_ || !ShouldShowPopularSites()) {
+ return NTPTilesVector();
+ }
// Collect non-blacklisted popular suggestions, skipping those already present
// in the personal suggestions.
- size_t num_popular_sites_tiles = num_sites_ - num_tiles;
NTPTilesVector popular_sites_tiles;
+ for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
+ if (popular_sites_tiles.size() + num_actual_tiles >= num_sites_)
+ break;
- if (num_popular_sites_tiles > 0 && popular_sites_ &&
- ShouldShowPopularSites()) {
- std::set<std::string> hosts;
- for (const auto& tile : personal_tiles)
- hosts.insert(tile.url.host());
- for (const auto& tile : whitelist_tiles)
- hosts.insert(tile.url.host());
- for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
- // Skip blacklisted sites.
- if (top_sites_ && top_sites_->IsBlacklisted(popular_site.url))
- continue;
- std::string host = popular_site.url.host();
- // Skip tiles already present in personal or whitelists.
- if (hosts.find(host) != hosts.end())
- continue;
-
- NTPTile tile;
- tile.title = popular_site.title;
- tile.url = GURL(popular_site.url);
- tile.source = TileSource::POPULAR;
-
- popular_sites_tiles.push_back(std::move(tile));
- base::Closure icon_available =
- base::Bind(&MostVisitedSites::OnIconMadeAvailable,
- base::Unretained(this), popular_site.url);
- icon_cacher_->StartFetch(popular_site, icon_available, icon_available);
- if (popular_sites_tiles.size() >= num_popular_sites_tiles)
- break;
- }
+ // Skip blacklisted sites.
+ if (top_sites_ && top_sites_->IsBlacklisted(popular_site.url))
+ continue;
+
+ const std::string& host = popular_site.url.host();
+ // Skip tiles already present in personal or whitelists.
+ if (used_hosts.find(host) != used_hosts.end())
+ continue;
+
+ NTPTile tile;
+ tile.title = popular_site.title;
+ tile.url = GURL(popular_site.url);
+ tile.source = TileSource::POPULAR;
+ popular_sites_tiles.push_back(std::move(tile));
+ base::Closure icon_available =
+ base::Bind(&MostVisitedSites::OnIconMadeAvailable,
+ base::Unretained(this), popular_site.url);
+ icon_cacher_->StartFetchPopularSites(popular_site, icon_available,
+ icon_available);
}
return popular_sites_tiles;
}
+NTPTilesVector MostVisitedSites::CreatePersonalTilesWithHomeTile(
+ NTPTilesVector tiles) const {
+ DCHECK(home_page_client_);
+ DCHECK_GT(num_sites_, 0u);
+
+ const GURL& home_page_url = home_page_client_->GetHomepageUrl();
+ NTPTilesVector new_tiles;
+ // Add the home tile as first tile.
+ NTPTile home_tile;
+ home_tile.url = home_page_url;
+ home_tile.source = TileSource::HOMEPAGE;
+ new_tiles.push_back(std::move(home_tile));
+
+ for (auto& tile : tiles) {
+ if (new_tiles.size() >= num_sites_) {
+ break;
+ }
+
+ if (tile.url.host() == home_page_url.host()) {
+ continue;
+ }
+
+ new_tiles.push_back(std::move(tile));
+ }
+ return new_tiles;
+}
+
void MostVisitedSites::SaveNewTilesAndNotify(NTPTilesVector personal_tiles) {
+ std::set<std::string> used_hosts;
+ size_t num_actual_tiles = 0u;
+
+ if (ShouldAddHomeTile()) {
+ personal_tiles = CreatePersonalTilesWithHomeTile(std::move(personal_tiles));
+ }
+ AddToHostsAndTotalCount(personal_tiles, &used_hosts, &num_actual_tiles);
+
NTPTilesVector whitelist_tiles =
- CreateWhitelistEntryPointTiles(personal_tiles);
- NTPTilesVector popular_sites_tiles =
- CreatePopularSitesTiles(personal_tiles, whitelist_tiles);
+ CreateWhitelistEntryPointTiles(used_hosts, num_actual_tiles);
+ AddToHostsAndTotalCount(whitelist_tiles, &used_hosts, &num_actual_tiles);
- size_t num_actual_tiles = personal_tiles.size() + whitelist_tiles.size() +
- popular_sites_tiles.size();
- DCHECK_LE(num_actual_tiles, static_cast<size_t>(num_sites_));
+ NTPTilesVector popular_sites_tiles =
+ CreatePopularSitesTiles(used_hosts, num_actual_tiles);
+ AddToHostsAndTotalCount(popular_sites_tiles, &used_hosts, &num_actual_tiles);
NTPTilesVector new_tiles =
MergeTiles(std::move(personal_tiles), std::move(whitelist_tiles),
@@ -422,7 +470,8 @@ void MostVisitedSites::OnPopularSitesDownloaded(bool success) {
for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
// Ignore callback; these icons will be seen on the *next* NTP.
- icon_cacher_->StartFetch(popular_site, base::Closure(), base::Closure());
+ icon_cacher_->StartFetchPopularSites(popular_site, base::Closure(),
+ base::Closure());
}
}
@@ -440,4 +489,23 @@ void MostVisitedSites::TopSitesChanged(TopSites* top_sites,
}
}
+bool MostVisitedSites::ShouldAddHomeTile() const {
+ return base::FeatureList::IsEnabled(kPinHomePageAsTileFeature) &&
+ num_sites_ > 0u && home_page_client_ &&
+ home_page_client_->IsHomePageEnabled() &&
+ !home_page_client_->IsNewTabPageUsedAsHomePage() &&
+ !(top_sites_ &&
+ top_sites_->IsBlacklisted(home_page_client_->GetHomepageUrl()));
+}
+
+void MostVisitedSites::AddToHostsAndTotalCount(const NTPTilesVector& new_tiles,
+ std::set<std::string>* hosts,
+ size_t* total_tile_count) const {
+ for (const auto& tile : new_tiles) {
+ hosts->insert(tile.url.host());
+ }
+ *total_tile_count += new_tiles.size();
+ DCHECK_LE(*total_tile_count, num_sites_);
+}
+
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/most_visited_sites.h b/chromium/components/ntp_tiles/most_visited_sites.h
index 10473ce6886..271d6084977 100644
--- a/chromium/components/ntp_tiles/most_visited_sites.h
+++ b/chromium/components/ntp_tiles/most_visited_sites.h
@@ -8,6 +8,8 @@
#include <stddef.h>
#include <memory>
+#include <set>
+#include <string>
#include <vector>
#include "base/compiler_specific.h"
@@ -89,11 +91,31 @@ class MostVisitedSites : public history::TopSitesObserver,
virtual ~Observer() {}
};
+ // This interface delegates the retrieval of the home page to the
+ // platform-specific implementation.
+ class HomePageClient {
+ public:
+ virtual ~HomePageClient() = default;
+ virtual bool IsHomePageEnabled() const = 0;
+ virtual bool IsNewTabPageUsedAsHomePage() const = 0;
+ virtual GURL GetHomepageUrl() const = 0;
+ };
+
// Construct a MostVisitedSites instance.
//
// |prefs| and |suggestions| are required and may not be null. |top_sites|,
- // |popular_sites|, and |supervisor| are optional and if null the associated
- // features will be disabled.
+ // |popular_sites|, |supervisor| and |home_page_client| are optional and if
+ // null, the associated features will be disabled.
+ MostVisitedSites(PrefService* prefs,
+ scoped_refptr<history::TopSites> top_sites,
+ suggestions::SuggestionsService* suggestions,
+ std::unique_ptr<PopularSites> popular_sites,
+ std::unique_ptr<IconCacher> icon_cacher,
+ std::unique_ptr<MostVisitedSitesSupervisor> supervisor,
+ std::unique_ptr<HomePageClient> home_page_client);
+
+ // TODO(fhorschig): Adjust all factories and delete this.
+ // Constructs a MostVisitedSites instance without HomePageClient.
MostVisitedSites(PrefService* prefs,
scoped_refptr<history::TopSites> top_sites,
suggestions::SuggestionsService* suggestions,
@@ -119,7 +141,7 @@ class MostVisitedSites : public history::TopSitesObserver,
// Sets the observer, and immediately fetches the current suggestions.
// Does not take ownership of |observer|, which must outlive this object and
// must not be null.
- void SetMostVisitedURLsObserver(Observer* observer, int num_sites);
+ void SetMostVisitedURLsObserver(Observer* observer, size_t num_sites);
// Requests an asynchronous refresh of the suggestions. Notifies the observer
// if the request resulted in the set of tiles changing.
@@ -163,15 +185,15 @@ class MostVisitedSites : public history::TopSitesObserver,
void BuildCurrentTilesGivenSuggestionsProfile(
const suggestions::SuggestionsProfile& suggestions_profile);
- // Takes the personal suggestions and creates whitelist entry point
- // suggestions if necessary.
+ // Creates whitelist entry point suggestions whose hosts weren't used yet.
NTPTilesVector CreateWhitelistEntryPointTiles(
- const NTPTilesVector& personal_tiles);
+ const std::set<std::string>& used_hosts,
+ size_t num_actual_tiles);
- // Takes the personal and whitelist tiles and creates popular tiles if
- // necessary.
- NTPTilesVector CreatePopularSitesTiles(const NTPTilesVector& personal_tiles,
- const NTPTilesVector& whitelist_tiles);
+ // Creates popular tiles whose hosts weren't used yet.
+ NTPTilesVector CreatePopularSitesTiles(
+ const std::set<std::string>& used_hosts,
+ size_t num_actual_tiles);
// Takes the personal tiles, creates and merges in whitelist and popular tiles
// if appropriate, and saves the new tiles. Notifies the observer if the tiles
@@ -182,6 +204,20 @@ class MostVisitedSites : public history::TopSitesObserver,
void OnIconMadeAvailable(const GURL& site_url);
+ // Updates the already used hosts and the total tile count based on given new
+ // tiles. Enforces that the required amount of tiles is not exceeded.
+ void AddToHostsAndTotalCount(const NTPTilesVector& new_tiles,
+ std::set<std::string>* hosts,
+ size_t* total_tile_count) const;
+
+ // Adds the home page as first tile to |tiles| and returns them as new vector.
+ // Drops existing tiles with the same host as the home page and tiles that
+ // would exceed the maximum.
+ NTPTilesVector CreatePersonalTilesWithHomeTile(NTPTilesVector tiles) const;
+
+ // Returns true if there is a valid home page that can be pinned as tile.
+ bool ShouldAddHomeTile() const;
+
// history::TopSitesObserver implementation.
void TopSitesLoaded(history::TopSites* top_sites) override;
void TopSitesChanged(history::TopSites* top_sites,
@@ -193,11 +229,12 @@ class MostVisitedSites : public history::TopSitesObserver,
std::unique_ptr<PopularSites> const popular_sites_;
std::unique_ptr<IconCacher> const icon_cacher_;
std::unique_ptr<MostVisitedSitesSupervisor> supervisor_;
+ std::unique_ptr<HomePageClient> const home_page_client_;
Observer* observer_;
// The maximum number of most visited sites to return.
- int num_sites_;
+ size_t num_sites_;
std::unique_ptr<
suggestions::SuggestionsService::ResponseCallbackList::Subscription>
diff --git a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc
index 650b10e925a..4bd8bc92ab5 100644
--- a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc
+++ b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -20,10 +20,12 @@
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/cancelable_task_tracker.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/sequenced_worker_pool_owner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/history/core/browser/top_sites.h"
#include "components/history/core/browser/top_sites_observer.h"
+#include "components/ntp_tiles/constants.h"
#include "components/ntp_tiles/icon_cacher.h"
#include "components/ntp_tiles/json_unsafe_parser.h"
#include "components/ntp_tiles/popular_sites_impl.h"
@@ -52,28 +54,45 @@ using suggestions::ChromeSuggestion;
using suggestions::SuggestionsProfile;
using suggestions::SuggestionsService;
using testing::AtLeast;
+using testing::AllOf;
+using testing::AnyNumber;
using testing::ByMove;
+using testing::Contains;
using testing::ElementsAre;
+using testing::Eq;
using testing::InSequence;
using testing::Invoke;
using testing::IsEmpty;
using testing::Mock;
+using testing::Not;
using testing::Return;
using testing::ReturnRef;
using testing::SizeIs;
using testing::StrictMock;
using testing::_;
-MATCHER_P3(MatchesTile,
+const char kHomePageUrl[] = "http://ho.me/";
+
+std::string PrintTile(const std::string& title,
+ const std::string& url,
+ TileSource source) {
+ return std::string("has title \"") + title + std::string("\" and url \"") +
+ url + std::string("\" and source ") +
+ testing::PrintToString(static_cast<int>(source));
+}
+
+MATCHER_P3(MatchesTile, title, url, source, PrintTile(title, url, source)) {
+ return arg.title == base::ASCIIToUTF16(title) && arg.url == GURL(url) &&
+ arg.source == source;
+}
+
+MATCHER_P3(FirstTileIs,
title,
url,
source,
- std::string("has title \"") + title + std::string("\" and url \"") +
- url +
- std::string("\" and source ") +
- testing::PrintToString(static_cast<int>(source))) {
- return arg.title == base::ASCIIToUTF16(title) && arg.url == GURL(url) &&
- arg.source == source;
+ std::string("first tile ") + PrintTile(title, url, source)) {
+ return !arg.empty() && arg[0].title == base::ASCIIToUTF16(title) &&
+ arg[0].url == GURL(url) && arg[0].source == source;
}
// testing::InvokeArgument<N> does not work with base::Callback, fortunately
@@ -192,12 +211,38 @@ class MockMostVisitedSitesObserver : public MostVisitedSites::Observer {
MOCK_METHOD1(OnIconMadeAvailable, void(const GURL& site_url));
};
+class FakeHomePageClient : public MostVisitedSites::HomePageClient {
+ public:
+ FakeHomePageClient() : home_page_enabled_(false), ntp_is_homepage_(false) {}
+ ~FakeHomePageClient() override {}
+
+ bool IsHomePageEnabled() const override { return home_page_enabled_; }
+
+ bool IsNewTabPageUsedAsHomePage() const override { return ntp_is_homepage_; }
+
+ GURL GetHomepageUrl() const override { return GURL(kHomePageUrl); }
+
+ void SetHomePageEnabled(bool home_page_enabled) {
+ home_page_enabled_ = home_page_enabled;
+ }
+
+ void SetNtpIsHomePage(bool ntp_is_homepage) {
+ ntp_is_homepage_ = ntp_is_homepage;
+ }
+
+ private:
+ bool home_page_enabled_;
+ bool ntp_is_homepage_;
+};
+
class MockIconCacher : public IconCacher {
public:
- MOCK_METHOD3(StartFetch,
+ MOCK_METHOD3(StartFetchPopularSites,
void(PopularSites::Site site,
const base::Closure& icon_available,
const base::Closure& preliminary_icon_available));
+ MOCK_METHOD2(StartFetchMostLikely,
+ void(const GURL& page_url, const base::Closure& icon_available));
};
class PopularSitesFactoryForTest {
@@ -287,9 +332,14 @@ class MostVisitedSitesTest : public ::testing::TestWithParam<bool> {
switches::kDisableNTPPopularSites);
}
+ // Disable in most tests, this is overriden in a specific test.
+ feature_list_.InitAndDisableFeature(
+ kNtpMostLikelyFaviconsFromServerFeature);
+
// We use StrictMock to make sure the object is not used unless Popular
// Sites is enabled.
auto icon_cacher = base::MakeUnique<StrictMock<MockIconCacher>>();
+ icon_cacher_ = icon_cacher.get();
if (IsPopularSitesEnabledViaVariations()) {
// Populate Popular Sites' internal cache by mimicking a past usage of
@@ -313,13 +363,17 @@ class MostVisitedSitesTest : public ::testing::TestWithParam<bool> {
.WillRepeatedly(Return(false));
// Mock icon cacher never replies, and we also don't verify whether the
// code uses it correctly.
- EXPECT_CALL(*icon_cacher, StartFetch(_, _, _)).Times(AtLeast(0));
+ EXPECT_CALL(*icon_cacher, StartFetchPopularSites(_, _, _))
+ .Times(AtLeast(0));
}
+ auto home_page_client = base::MakeUnique<FakeHomePageClient>();
+ home_page_client_ = home_page_client.get();
+
most_visited_sites_ = base::MakeUnique<MostVisitedSites>(
&pref_service_, mock_top_sites_, &mock_suggestions_service_,
popular_sites_factory_.New(), std::move(icon_cacher),
- /*supervisor=*/nullptr);
+ /*supervisor=*/nullptr, std::move(home_page_client));
}
bool IsPopularSitesEnabledViaVariations() const { return GetParam(); }
@@ -338,6 +392,19 @@ class MostVisitedSitesTest : public ::testing::TestWithParam<bool> {
return success;
}
+ void DisableRemoteSuggestions() {
+ EXPECT_CALL(mock_suggestions_service_, AddCallback(_))
+ .Times(AnyNumber())
+ .WillRepeatedly(Invoke(&suggestions_service_callbacks_,
+ &SuggestionsService::ResponseCallbackList::Add));
+ EXPECT_CALL(mock_suggestions_service_, GetSuggestionsDataFromCache())
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(SuggestionsProfile())); // Empty cache.
+ EXPECT_CALL(mock_suggestions_service_, FetchSuggestionsData())
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(true));
+ }
+
base::CallbackList<SuggestionsService::ResponseCallback::RunType>
suggestions_service_callbacks_;
TopSitesCallbackList top_sites_callbacks_;
@@ -348,7 +415,10 @@ class MostVisitedSitesTest : public ::testing::TestWithParam<bool> {
scoped_refptr<StrictMock<MockTopSites>> mock_top_sites_;
StrictMock<MockSuggestionsService> mock_suggestions_service_;
StrictMock<MockMostVisitedSitesObserver> mock_observer_;
+ FakeHomePageClient* home_page_client_;
std::unique_ptr<MostVisitedSites> most_visited_sites_;
+ base::test::ScopedFeatureList feature_list_;
+ MockIconCacher* icon_cacher_;
};
TEST_P(MostVisitedSitesTest, ShouldStartNoCallInConstructor) {
@@ -357,6 +427,218 @@ TEST_P(MostVisitedSitesTest, ShouldStartNoCallInConstructor) {
base::RunLoop().RunUntilIdle();
}
+TEST_P(MostVisitedSitesTest, ShouldIncludeTileForHomePage) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{}));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_, OnMostVisitedURLsAvailable(FirstTileIs(
+ "", kHomePageUrl, TileSource::HOMEPAGE)));
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/3);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomePageIfFeatureDisabled) {
+ base::test::ScopedFeatureList features;
+ features.InitAndDisableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{}));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_,
+ OnMostVisitedURLsAvailable(Not(Contains(
+ MatchesTile("", kHomePageUrl, TileSource::HOMEPAGE)))));
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/3);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomePageIfNoTileRequested) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{}));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_, OnMostVisitedURLsAvailable(IsEmpty()));
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/0);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldReturnOnlyHomePageIfOneTileRequested) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(
+ (MostVisitedURLList{MakeMostVisitedURL("Site 1", "http://site1/")})));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_,
+ OnMostVisitedURLsAvailable(ElementsAre(
+ MatchesTile("", kHomePageUrl, TileSource::HOMEPAGE))));
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/1);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldDeduplicateHomePageWithTopSites) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(
+ (MostVisitedURLList{MakeMostVisitedURL("Site 1", "http://site1/"),
+ MakeMostVisitedURL("", kHomePageUrl)})));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_,
+ OnMostVisitedURLsAvailable(
+ AllOf(FirstTileIs("", kHomePageUrl, TileSource::HOMEPAGE),
+ Not(Contains(MatchesTile("", kHomePageUrl,
+ TileSource::TOP_SITES))))));
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/3);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomePageIfItIsNewTabPage) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+ home_page_client_->SetNtpIsHomePage(true);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{}));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_,
+ OnMostVisitedURLsAvailable(Not(Contains(
+ MatchesTile("", kHomePageUrl, TileSource::HOMEPAGE)))));
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/3);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomePageIfThereIsNone) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(false);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(MostVisitedURLList{}));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_,
+ OnMostVisitedURLsAvailable(Not(Contains(
+ MatchesTile("", kHomePageUrl, TileSource::HOMEPAGE)))));
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/3);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldNotIncludeHomePageIfBlacklisted) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillRepeatedly(InvokeCallbackArgument<0>(
+ (MostVisitedURLList{MakeMostVisitedURL("", kHomePageUrl)})));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AtLeast(1))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(mock_observer_,
+ OnMostVisitedURLsAvailable(Not(Contains(
+ MatchesTile("", kHomePageUrl, TileSource::HOMEPAGE)))));
+
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/3);
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldPinHomePageAgainIfBlacklistingUndone) {
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(ntp_tiles::kPinHomePageAsTileFeature);
+ home_page_client_->SetHomePageEnabled(true);
+
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillOnce(InvokeCallbackArgument<0>(
+ (MostVisitedURLList{MakeMostVisitedURL("", kHomePageUrl)})));
+ EXPECT_CALL(*mock_top_sites_, SyncWithHistory());
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AtLeast(1))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(mock_observer_,
+ OnMostVisitedURLsAvailable(Not(Contains(
+ MatchesTile("", kHomePageUrl, TileSource::HOMEPAGE)))));
+
+ most_visited_sites_->SetMostVisitedURLsObserver(&mock_observer_,
+ /*num_sites=*/3);
+ base::RunLoop().RunUntilIdle();
+ VerifyAndClearExpectations();
+
+ DisableRemoteSuggestions();
+ EXPECT_CALL(*mock_top_sites_, GetMostVisitedURLs(_, false))
+ .WillOnce(InvokeCallbackArgument<0>(MostVisitedURLList{}));
+ EXPECT_CALL(*mock_top_sites_, IsBlacklisted(Eq(GURL(kHomePageUrl))))
+ .Times(AtLeast(1))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(mock_observer_, OnMostVisitedURLsAvailable(Contains(MatchesTile(
+ "", kHomePageUrl, TileSource::HOMEPAGE))));
+
+ most_visited_sites_->OnBlockedSitesChanged();
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_P(MostVisitedSitesTest, ShouldInformSuggestionSourcesWhenBlacklisting) {
+ EXPECT_CALL(*mock_top_sites_, AddBlacklistedURL(Eq(GURL(kHomePageUrl))))
+ .Times(1);
+ EXPECT_CALL(mock_suggestions_service_, BlacklistURL(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber());
+ most_visited_sites_->AddOrRemoveBlacklistedUrl(GURL(kHomePageUrl),
+ /*add_url=*/true);
+ EXPECT_CALL(*mock_top_sites_, RemoveBlacklistedURL(Eq(GURL(kHomePageUrl))))
+ .Times(1);
+ EXPECT_CALL(mock_suggestions_service_,
+ UndoBlacklistURL(Eq(GURL(kHomePageUrl))))
+ .Times(AnyNumber());
+ most_visited_sites_->AddOrRemoveBlacklistedUrl(GURL(kHomePageUrl),
+ /*add_url=*/false);
+}
+
TEST_P(MostVisitedSitesTest, ShouldHandleTopSitesCacheHit) {
// If cached, TopSites returns the tiles synchronously, running the callback
// even before the function returns.
@@ -540,6 +822,18 @@ TEST_P(MostVisitedSitesWithCacheHitTest,
base::RunLoop().RunUntilIdle();
}
+TEST_P(MostVisitedSitesWithCacheHitTest, ShouldFetchFaviconsIfEnabled) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(kNtpMostLikelyFaviconsFromServerFeature);
+
+ EXPECT_CALL(mock_observer_, OnMostVisitedURLsAvailable(_));
+ EXPECT_CALL(*icon_cacher_, StartFetchMostLikely(GURL("http://site4/"), _));
+
+ suggestions_service_callbacks_.Notify(
+ MakeProfile({MakeSuggestion("Site 4", "http://site4/")}));
+ base::RunLoop().RunUntilIdle();
+}
+
INSTANTIATE_TEST_CASE_P(MostVisitedSitesWithCacheHitTest,
MostVisitedSitesWithCacheHitTest,
::testing::Bool());
diff --git a/chromium/components/ntp_tiles/popular_sites.h b/chromium/components/ntp_tiles/popular_sites.h
index 43dbc84a09a..f1e207fcac1 100644
--- a/chromium/components/ntp_tiles/popular_sites.h
+++ b/chromium/components/ntp_tiles/popular_sites.h
@@ -66,6 +66,7 @@ class PopularSites {
// Various internals exposed publicly for diagnostic pages only.
virtual GURL GetLastURLFetched() const = 0;
virtual GURL GetURLToFetch() = 0;
+ virtual std::string GetDirectoryToFetch() = 0;
virtual std::string GetCountryToFetch() = 0;
virtual std::string GetVersionToFetch() = 0;
virtual const base::ListValue* GetCachedJson() = 0;
diff --git a/chromium/components/ntp_tiles/popular_sites_impl.cc b/chromium/components/ntp_tiles/popular_sites_impl.cc
index f083770a26e..4e0d73f150a 100644
--- a/chromium/components/ntp_tiles/popular_sites_impl.cc
+++ b/chromium/components/ntp_tiles/popular_sites_impl.cc
@@ -18,6 +18,7 @@
#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/google/core/browser/google_util.h"
#include "components/ntp_tiles/constants.h"
@@ -34,7 +35,7 @@
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
-#if defined(OS_ANDROID) || defined(OS_IOS)
+#if defined(OS_ANDROID)
#include "base/json/json_reader.h"
#include "components/grit/components_resources.h"
#include "ui/base/resource/resource_bundle.h"
@@ -52,7 +53,8 @@ namespace ntp_tiles {
namespace {
const char kPopularSitesURLFormat[] =
- "https://www.gstatic.com/chrome/ntp/suggested_sites_%s_%s.json";
+ "https://www.gstatic.com/%ssuggested_sites_%s_%s.json";
+const char kPopularSitesDefaultDirectory[] = "chrome/ntp/";
const char kPopularSitesDefaultCountryCode[] = "DEFAULT";
const char kPopularSitesDefaultVersion[] = "5";
const int kPopularSitesRedownloadIntervalHours = 24;
@@ -65,10 +67,11 @@ const char kPopularSitesJsonPref[] = "suggested_sites_json";
// versions of Chrome, no longer used. Remove after M61.
const char kPopularSitesLocalFilenameToCleanup[] = "suggested_sites.json";
-GURL GetPopularSitesURL(const std::string& country,
+GURL GetPopularSitesURL(const std::string& directory,
+ const std::string& country,
const std::string& version) {
- return GURL(base::StringPrintf(kPopularSitesURLFormat, country.c_str(),
- version.c_str()));
+ return GURL(base::StringPrintf(kPopularSitesURLFormat, directory.c_str(),
+ country.c_str(), version.c_str()));
}
// Extract the country from the default search engine if the default search
@@ -137,7 +140,7 @@ PopularSites::SitesVector ParseSiteList(const base::ListValue& list) {
return sites;
}
-#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_ANDROID) || defined(OS_IOS))
+#if defined(GOOGLE_CHROME_BUILD) && defined(OS_ANDROID)
void SetDefaultResourceForSite(int index,
int resource_id,
base::ListValue* sites) {
@@ -151,7 +154,7 @@ void SetDefaultResourceForSite(int index,
// Creates the list of popular sites based on a snapshot available for mobile.
std::unique_ptr<base::ListValue> DefaultPopularSites() {
-#if !defined(OS_ANDROID) && !defined(OS_IOS)
+#if !defined(OS_ANDROID)
return base::MakeUnique<base::ListValue>();
#else
if (!base::FeatureList::IsEnabled(kPopularSitesBakedInContentFeature)) {
@@ -259,13 +262,25 @@ GURL PopularSitesImpl::GetLastURLFetched() const {
}
GURL PopularSitesImpl::GetURLToFetch() {
+ const std::string directory = GetDirectoryToFetch();
const std::string country = GetCountryToFetch();
const std::string version = GetVersionToFetch();
const GURL override_url =
GURL(prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL));
- return override_url.is_valid() ? override_url
- : GetPopularSitesURL(country, version);
+ return override_url.is_valid()
+ ? override_url
+ : GetPopularSitesURL(directory, country, version);
+}
+
+std::string PopularSitesImpl::GetDirectoryToFetch() {
+ std::string directory =
+ prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideDirectory);
+
+ if (directory.empty())
+ directory = kPopularSitesDefaultDirectory;
+
+ return directory;
}
// Determine the country code to use. In order of precedence:
@@ -325,6 +340,8 @@ void PopularSitesImpl::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* user_prefs) {
user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideURL,
std::string());
+ user_prefs->RegisterStringPref(
+ ntp_tiles::prefs::kPopularSitesOverrideDirectory, std::string());
user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideCountry,
std::string());
user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideVersion,
@@ -413,7 +430,8 @@ void PopularSitesImpl::OnDownloadFailed() {
if (!is_fallback_) {
DLOG(WARNING) << "Download country site list failed";
is_fallback_ = true;
- pending_url_ = GetPopularSitesURL(kPopularSitesDefaultCountryCode,
+ pending_url_ = GetPopularSitesURL(kPopularSitesDefaultDirectory,
+ kPopularSitesDefaultCountryCode,
kPopularSitesDefaultVersion);
FetchPopularSites();
} else {
diff --git a/chromium/components/ntp_tiles/popular_sites_impl.h b/chromium/components/ntp_tiles/popular_sites_impl.h
index 1f0fbbe6b1c..b045dea6a79 100644
--- a/chromium/components/ntp_tiles/popular_sites_impl.h
+++ b/chromium/components/ntp_tiles/popular_sites_impl.h
@@ -67,6 +67,7 @@ class PopularSitesImpl : public PopularSites, public net::URLFetcherDelegate {
const SitesVector& sites() const override;
GURL GetLastURLFetched() const override;
GURL GetURLToFetch() override;
+ std::string GetDirectoryToFetch() override;
std::string GetCountryToFetch() override;
std::string GetVersionToFetch() override;
const base::ListValue* GetCachedJson() override;
diff --git a/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc b/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc
index 1deff6bd575..b04bf8b8750 100644
--- a/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc
+++ b/chromium/components/ntp_tiles/popular_sites_impl_unittest.cc
@@ -16,12 +16,14 @@
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/sequenced_worker_pool_owner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "components/ntp_tiles/constants.h"
#include "components/ntp_tiles/json_unsafe_parser.h"
#include "components/ntp_tiles/pref_names.h"
@@ -59,7 +61,7 @@ using TestPopularSiteVector = std::vector<TestPopularSite>;
}
size_t GetNumberOfDefaultPopularSitesForPlatform() {
-#if defined(OS_ANDROID) || defined(OS_IOS)
+#if defined(OS_ANDROID)
return 8ul;
#else
return 0ul;
@@ -264,7 +266,7 @@ TEST_F(PopularSitesTest, AddsIconResourcesToDefaultPages) {
std::unique_ptr<PopularSites> popular_sites =
CreatePopularSites(url_request_context.get());
-#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_ANDROID) || defined(OS_IOS))
+#if defined(GOOGLE_CHROME_BUILD) && defined(OS_ANDROID)
ASSERT_FALSE(popular_sites->sites().empty());
for (const auto& site : popular_sites->sites()) {
EXPECT_THAT(site.default_icon_resource, Gt(0));
@@ -458,5 +460,18 @@ TEST_F(PopularSitesTest, RefetchesAfterFallback) {
EXPECT_THAT(sites[0].url, URLEq("https://www.chromium.org/"));
}
+TEST_F(PopularSitesTest, ShouldOverrideDirectory) {
+ SetCountryAndVersion("ZZ", "9");
+ prefs_->SetString(prefs::kPopularSitesOverrideDirectory, "foo/bar/");
+ RespondWithJSON("https://www.gstatic.com/foo/bar/suggested_sites_ZZ_9.json",
+ {kWikipedia});
+
+ PopularSites::SitesVector sites;
+ EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites),
+ Eq(base::Optional<bool>(true)));
+
+ EXPECT_THAT(sites.size(), Eq(1u));
+}
+
} // namespace
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/pref_names.cc b/chromium/components/ntp_tiles/pref_names.cc
index 1988357f410..c8839987362 100644
--- a/chromium/components/ntp_tiles/pref_names.cc
+++ b/chromium/components/ntp_tiles/pref_names.cc
@@ -15,6 +15,10 @@ const char kNumPersonalTiles[] = "ntp.num_personal_suggestions";
// overrides for country and version below.
const char kPopularSitesOverrideURL[] = "popular_sites.override_url";
+// If set, this will override the URL path directory for popular sites.
+const char kPopularSitesOverrideDirectory[] =
+ "popular_sites.override_directory";
+
// If set, this will override the country detection for popular sites.
const char kPopularSitesOverrideCountry[] = "popular_sites.override_country";
diff --git a/chromium/components/ntp_tiles/pref_names.h b/chromium/components/ntp_tiles/pref_names.h
index cdaa896eee7..9c4de063cf9 100644
--- a/chromium/components/ntp_tiles/pref_names.h
+++ b/chromium/components/ntp_tiles/pref_names.h
@@ -11,6 +11,7 @@ namespace prefs {
extern const char kNumPersonalTiles[];
extern const char kPopularSitesOverrideURL[];
+extern const char kPopularSitesOverrideDirectory[];
extern const char kPopularSitesOverrideCountry[];
extern const char kPopularSitesOverrideVersion[];
diff --git a/chromium/components/ntp_tiles/resources/default_popular_sites.json b/chromium/components/ntp_tiles/resources/default_popular_sites.json
index a41a914871b..f193c1807f7 100644
--- a/chromium/components/ntp_tiles/resources/default_popular_sites.json
+++ b/chromium/components/ntp_tiles/resources/default_popular_sites.json
@@ -16,7 +16,7 @@
},
{
"large_icon_url": "https://developers.google.com/_static/9bce7b6017/images/touch-icon.png",
- "title": "Google Open Soruce Programs Office",
+ "title": "Google Open Source Programs Office",
"url": "https://developers.google.com/open-source/"
},
{
diff --git a/chromium/components/ntp_tiles/switches.cc b/chromium/components/ntp_tiles/switches.cc
index 9ae60506c5d..bd1ca443818 100644
--- a/chromium/components/ntp_tiles/switches.cc
+++ b/chromium/components/ntp_tiles/switches.cc
@@ -18,5 +18,15 @@ const char kEnableNTPPopularSites[] = "enable-ntp-popular-sites";
// Disables showing popular sites on the NTP.
const char kDisableNTPPopularSites[] = "disable-ntp-popular-sites";
+// Enables the new Google favicon server for fetching favicons for Most Likely
+// tiles on the New Tab Page.
+const char kEnableNtpMostLikelyFaviconsFromServer[] =
+ "enable-ntp-most-likely-favicons-from-server";
+
+// Disables the new Google favicon server for fetching favicons for Most Likely
+// tiles on the New Tab Page.
+const char kDisableNtpMostLikelyFaviconsFromServer[] =
+ "disable-ntp-most-likely-favicons-from-server";
+
} // namespace switches
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/switches.h b/chromium/components/ntp_tiles/switches.h
index 2405e7d185a..799d4176e8e 100644
--- a/chromium/components/ntp_tiles/switches.h
+++ b/chromium/components/ntp_tiles/switches.h
@@ -13,6 +13,11 @@ extern const char kEnableNTPSearchEngineCountryDetection[];
extern const char kEnableNTPPopularSites[];
extern const char kDisableNTPPopularSites[];
+// These switches are only introduced to allow iOS to override a feature.
+// TODO(jkrcal): Remove once crbug.com/718926 is fixed.
+extern const char kEnableNtpMostLikelyFaviconsFromServer[];
+extern const char kDisableNtpMostLikelyFaviconsFromServer[];
+
} // namespace switches
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/tile_source.h b/chromium/components/ntp_tiles/tile_source.h
index f8aec297ad2..53ca5eab207 100644
--- a/chromium/components/ntp_tiles/tile_source.h
+++ b/chromium/components/ntp_tiles/tile_source.h
@@ -19,8 +19,10 @@ enum class TileSource {
POPULAR,
// Tile is on a custodian-managed whitelist.
WHITELIST,
+ // Tile containing the user-set home page is replacing the home page button.
+ HOMEPAGE,
- LAST = WHITELIST
+ LAST = HOMEPAGE
};
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc b/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc
index 7cc00477154..ea6ee51c758 100644
--- a/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc
+++ b/chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc
@@ -110,6 +110,15 @@ void NTPTilesInternalsMessageHandler::HandleUpdate(
url_formatter::FixupURL(url, std::string()).spec());
}
+ std::string directory;
+ dict->GetString("popular.overrideDirectory", &directory);
+ if (directory.empty()) {
+ prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideDirectory);
+ } else {
+ prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideDirectory,
+ directory);
+ }
+
std::string country;
dict->GetString("popular.overrideCountry", &country);
if (country.empty()) {
@@ -181,6 +190,7 @@ void NTPTilesInternalsMessageHandler::SendSourceInfo() {
if (most_visited_sites_->DoesSourceExist(TileSource::POPULAR)) {
auto* popular_sites = most_visited_sites_->popular_sites();
value.SetString("popular.url", popular_sites->GetURLToFetch().spec());
+ value.SetString("popular.directory", popular_sites->GetDirectoryToFetch());
value.SetString("popular.country", popular_sites->GetCountryToFetch());
value.SetString("popular.version", popular_sites->GetVersionToFetch());
@@ -188,6 +198,9 @@ void NTPTilesInternalsMessageHandler::SendSourceInfo() {
"popular.overrideURL",
prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL));
value.SetString(
+ "popular.overrideDirectory",
+ prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideDirectory));
+ value.SetString(
"popular.overrideCountry",
prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideCountry));
value.SetString(
diff --git a/chromium/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc b/chromium/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc
index 7163b59fd88..68cc22283b4 100644
--- a/chromium/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc
+++ b/chromium/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc
@@ -59,7 +59,7 @@ void PopularSitesInternalsMessageHandler::HandleRegisterForEvents(
void PopularSitesInternalsMessageHandler::HandleUpdate(
const base::ListValue* args) {
- DCHECK_EQ(3u, args->GetSize());
+ DCHECK_EQ(4u, args->GetSize());
PrefService* prefs = web_ui_->GetPrefs();
@@ -71,15 +71,23 @@ void PopularSitesInternalsMessageHandler::HandleUpdate(
prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideURL,
url_formatter::FixupURL(url, std::string()).spec());
+ std::string directory;
+ args->GetString(1, &directory);
+ if (directory.empty())
+ prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideDirectory);
+ else
+ prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideDirectory,
+ directory);
+
std::string country;
- args->GetString(1, &country);
+ args->GetString(2, &country);
if (country.empty())
prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideCountry);
else
prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideCountry, country);
std::string version;
- args->GetString(2, &version);
+ args->GetString(3, &version);
if (version.empty())
prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideVersion);
else
@@ -109,13 +117,15 @@ void PopularSitesInternalsMessageHandler::SendOverrides() {
PrefService* prefs = web_ui_->GetPrefs();
std::string url =
prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL);
+ std::string directory =
+ prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideDirectory);
std::string country =
prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideCountry);
std::string version =
prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideVersion);
web_ui_->CallJavascriptFunction(
"chrome.popular_sites_internals.receiveOverrides", base::Value(url),
- base::Value(country), base::Value(version));
+ base::Value(directory), base::Value(country), base::Value(version));
}
void PopularSitesInternalsMessageHandler::SendDownloadResult(bool success) {
diff --git a/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html b/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html
index dfdfe36b602..ea70d72ccf7 100644
--- a/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html
+++ b/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html
@@ -65,6 +65,10 @@ found in the LICENSE file.
</tr>
<tr jsdisplay="$this">
<td class="detail">Country</td>
+ <td class="value"><input id="override-directory" type="text" jsvalues="value:overrideDirectory;placeholder:directory"></td>
+ </tr>
+ <tr jsdisplay="$this">
+ <td class="detail">Country</td>
<td class="value"><input id="override-country" type="text" jsvalues="value:overrideCountry;placeholder:country"></td>
</tr>
<tr jsdisplay="$this">
@@ -125,4 +129,3 @@ found in the LICENSE file.
</body>
</html>
-
diff --git a/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.js b/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.js
index d0cbbdc4c2d..10b2bbb15f3 100644
--- a/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.js
+++ b/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.js
@@ -11,6 +11,7 @@ cr.define('chrome.ntp_tiles_internals', function() {
chrome.send('update', [{
"popular": {
"overrideURL": $('override-url').value,
+ "overrideDirectory": $('override-directory').value,
"overrideCountry": $('override-country').value,
"overrideVersion": $('override-version').value,
},
@@ -52,4 +53,3 @@ cr.define('chrome.ntp_tiles_internals', function() {
document.addEventListener('DOMContentLoaded',
chrome.ntp_tiles_internals.initialize);
-
diff --git a/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.html b/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.html
index 81d8145c963..5ce97bcf64f 100644
--- a/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.html
+++ b/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.html
@@ -31,10 +31,14 @@ found in the LICENSE file.
<h2>Download</h2>
<table class="section-details">
<tr>
- <td class="detail">URL (takes precedence over Country and Version)</td>
+ <td class="detail">URL (takes precedence over Directory, Country and Version)</td>
<td class="value"><input id="override-url" type="text"></td>
</tr>
<tr>
+ <td class="detail">Override Directory</td>
+ <td class="value"><input id="override-directory" type="text"></td>
+ </tr>
+ <tr>
<td class="detail">Override Country</td>
<td class="value"><input id="override-country" type="text"></td>
</tr>
@@ -80,4 +84,3 @@ found in the LICENSE file.
</body>
</html>
-
diff --git a/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.js b/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.js
index 10a4010716a..3bfcf8b4c57 100644
--- a/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.js
+++ b/chromium/components/ntp_tiles/webui/resources/popular_sites_internals.js
@@ -9,6 +9,7 @@ cr.define('chrome.popular_sites_internals', function() {
function submitUpdate(event) {
$('download-result').textContent = '';
chrome.send('update', [$('override-url').value,
+ $('override-directory').value,
$('override-country').value,
$('override-version').value]);
event.preventDefault();
@@ -27,8 +28,9 @@ cr.define('chrome.popular_sites_internals', function() {
chrome.send('registerForEvents');
}
- function receiveOverrides(url, country, version) {
+ function receiveOverrides(url, directory, country, version) {
$('override-url').value = url;
+ $('override-directory').value = directory;
$('override-country').value = country;
$('override-version').value = version;
}
@@ -59,4 +61,3 @@ cr.define('chrome.popular_sites_internals', function() {
document.addEventListener('DOMContentLoaded',
chrome.popular_sites_internals.initialize);
-
diff --git a/chromium/components/offline_items_collection/core/BUILD.gn b/chromium/components/offline_items_collection/core/BUILD.gn
index ee5d1350792..b2ef4a55c3d 100644
--- a/chromium/components/offline_items_collection/core/BUILD.gn
+++ b/chromium/components/offline_items_collection/core/BUILD.gn
@@ -23,10 +23,13 @@ static_library("core") {
public_deps = [
"//base",
"//components/keyed_service/core",
+ "//ui/gfx",
"//url",
]
- deps = []
+ deps = [
+ "//ui/gfx/geometry",
+ ]
if (is_android) {
sources += [
@@ -34,6 +37,8 @@ static_library("core") {
"android/offline_content_aggregator_bridge.h",
"android/offline_item_bridge.cc",
"android/offline_item_bridge.h",
+ "android/offline_item_visuals_bridge.cc",
+ "android/offline_item_visuals_bridge.h",
]
deps += [ ":jni_headers" ]
@@ -58,12 +63,15 @@ source_set("unit_tests") {
if (is_android) {
android_library("core_java") {
java_files = [
+ "android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemBridge.java",
+ "android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemVisualsBridge.java",
"android/java/src/org/chromium/components/offline_items_collection/ContentId.java",
"android/java/src/org/chromium/components/offline_items_collection/LegacyHelpers.java",
"android/java/src/org/chromium/components/offline_items_collection/OfflineContentAggregatorBridge.java",
"android/java/src/org/chromium/components/offline_items_collection/OfflineContentProvider.java",
"android/java/src/org/chromium/components/offline_items_collection/OfflineItem.java",
- "android/java/src/org/chromium/components/offline_items_collection/OfflineItemBridge.java",
+ "android/java/src/org/chromium/components/offline_items_collection/OfflineItemVisuals.java",
+ "android/java/src/org/chromium/components/offline_items_collection/VisualsCallback.java",
]
srcjar_deps = [ ":jni_enums" ]
@@ -79,7 +87,8 @@ if (is_android) {
sources = [
"android/java/src/org/chromium/components/offline_items_collection/OfflineContentAggregatorBridge.java",
- "android/java/src/org/chromium/components/offline_items_collection/OfflineItemBridge.java",
+ "android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemBridge.java",
+ "android/java/src/org/chromium/components/offline_items_collection/bridges/OfflineItemVisualsBridge.java",
]
jni_package = "components/offline_items_collection/core/android"
@@ -89,6 +98,7 @@ if (is_android) {
visibility = [ ":*" ]
sources = [
+ "offline_item.h",
"offline_item_filter.h",
"offline_item_state.h",
]
diff --git a/chromium/components/offline_items_collection/core/DEPS b/chromium/components/offline_items_collection/core/DEPS
index bf267f99ddd..38d6d22e25c 100644
--- a/chromium/components/offline_items_collection/core/DEPS
+++ b/chromium/components/offline_items_collection/core/DEPS
@@ -4,5 +4,6 @@ include_rules = [
"+components/offline_pages",
"+jni",
"+testing",
+ "+ui/gfx",
"+url",
]
diff --git a/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc b/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc
index 70184f92a2e..eef6057d986 100644
--- a/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc
+++ b/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.cc
@@ -5,8 +5,12 @@
#include "components/offline_items_collection/core/android/offline_content_aggregator_bridge.h"
#include "base/android/jni_string.h"
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "components/offline_items_collection/core/android/offline_item_bridge.h"
+#include "components/offline_items_collection/core/android/offline_item_visuals_bridge.h"
#include "components/offline_items_collection/core/offline_item.h"
+#include "components/offline_items_collection/core/throttled_offline_content_provider.h"
#include "jni/OfflineContentAggregatorBridge_jni.h"
using base::android::AttachCurrentThread;
@@ -14,6 +18,7 @@ using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
+using base::android::ScopedJavaGlobalRef;
namespace offline_items_collection {
namespace android {
@@ -28,6 +33,16 @@ ContentId CreateContentId(JNIEnv* env,
ConvertJavaStringToUTF8(env, j_id));
}
+void GetVisualsForItemHelperCallback(ScopedJavaGlobalRef<jobject> j_callback,
+ const ContentId& id,
+ const OfflineItemVisuals* visuals) {
+ JNIEnv* env = AttachCurrentThread();
+ Java_OfflineContentAggregatorBridge_onVisualsAvailable(
+ env, j_callback.obj(), ConvertUTF8ToJavaString(env, id.name_space),
+ ConvertUTF8ToJavaString(env, id.id),
+ OfflineItemVisualsBridge::CreateOfflineItemVisuals(env, visuals));
+}
+
} // namespace
// static.
@@ -40,8 +55,9 @@ base::android::ScopedJavaLocalRef<jobject>
OfflineContentAggregatorBridge::GetBridgeForOfflineContentAggregator(
OfflineContentAggregator* aggregator) {
if (!aggregator->GetUserData(kOfflineContentAggregatorBridgeUserDataKey)) {
- aggregator->SetUserData(kOfflineContentAggregatorBridgeUserDataKey,
- new OfflineContentAggregatorBridge(aggregator));
+ aggregator->SetUserData(
+ kOfflineContentAggregatorBridgeUserDataKey,
+ base::WrapUnique(new OfflineContentAggregatorBridge(aggregator)));
}
OfflineContentAggregatorBridge* bridge =
static_cast<OfflineContentAggregatorBridge*>(
@@ -52,18 +68,18 @@ OfflineContentAggregatorBridge::GetBridgeForOfflineContentAggregator(
OfflineContentAggregatorBridge::OfflineContentAggregatorBridge(
OfflineContentAggregator* aggregator)
- : aggregator_(aggregator) {
+ : provider_(base::MakeUnique<ThrottledOfflineContentProvider>(aggregator)) {
JNIEnv* env = AttachCurrentThread();
java_ref_.Reset(Java_OfflineContentAggregatorBridge_create(
env, reinterpret_cast<intptr_t>(this)));
- aggregator_->AddObserver(this);
+ provider_->AddObserver(this);
}
OfflineContentAggregatorBridge::~OfflineContentAggregatorBridge() {
// TODO(dtrainor): Do not need to unregister because in the destructor of the
// base class of OfflineContentAggregator. Is |observers_| already dead?
- aggregator_->RemoveObserver(this);
+ provider_->RemoveObserver(this);
Java_OfflineContentAggregatorBridge_onNativeDestroyed(AttachCurrentThread(),
java_ref_.obj());
@@ -72,7 +88,7 @@ OfflineContentAggregatorBridge::~OfflineContentAggregatorBridge() {
jboolean OfflineContentAggregatorBridge::AreItemsAvailable(
JNIEnv* env,
const JavaParamRef<jobject>& jobj) {
- return aggregator_->AreItemsAvailable();
+ return provider_->AreItemsAvailable();
}
void OfflineContentAggregatorBridge::OpenItem(
@@ -80,7 +96,7 @@ void OfflineContentAggregatorBridge::OpenItem(
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jstring>& j_namespace,
const JavaParamRef<jstring>& j_id) {
- aggregator_->OpenItem(CreateContentId(env, j_namespace, j_id));
+ provider_->OpenItem(CreateContentId(env, j_namespace, j_id));
}
void OfflineContentAggregatorBridge::RemoveItem(
@@ -88,7 +104,7 @@ void OfflineContentAggregatorBridge::RemoveItem(
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jstring>& j_namespace,
const JavaParamRef<jstring>& j_id) {
- aggregator_->RemoveItem(CreateContentId(env, j_namespace, j_id));
+ provider_->RemoveItem(CreateContentId(env, j_namespace, j_id));
}
void OfflineContentAggregatorBridge::CancelDownload(
@@ -96,7 +112,7 @@ void OfflineContentAggregatorBridge::CancelDownload(
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jstring>& j_namespace,
const JavaParamRef<jstring>& j_id) {
- aggregator_->CancelDownload(CreateContentId(env, j_namespace, j_id));
+ provider_->CancelDownload(CreateContentId(env, j_namespace, j_id));
}
void OfflineContentAggregatorBridge::PauseDownload(
@@ -104,7 +120,7 @@ void OfflineContentAggregatorBridge::PauseDownload(
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jstring>& j_namespace,
const JavaParamRef<jstring>& j_guid) {
- aggregator_->PauseDownload(CreateContentId(env, j_namespace, j_guid));
+ provider_->PauseDownload(CreateContentId(env, j_namespace, j_guid));
}
void OfflineContentAggregatorBridge::ResumeDownload(
@@ -112,7 +128,7 @@ void OfflineContentAggregatorBridge::ResumeDownload(
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jstring>& j_namespace,
const JavaParamRef<jstring>& j_id) {
- aggregator_->ResumeDownload(CreateContentId(env, j_namespace, j_id));
+ provider_->ResumeDownload(CreateContentId(env, j_namespace, j_id));
}
ScopedJavaLocalRef<jobject> OfflineContentAggregatorBridge::GetItemById(
@@ -121,7 +137,7 @@ ScopedJavaLocalRef<jobject> OfflineContentAggregatorBridge::GetItemById(
const JavaParamRef<jstring>& j_namespace,
const JavaParamRef<jstring>& j_id) {
const OfflineItem* item =
- aggregator_->GetItemById(CreateContentId(env, j_namespace, j_id));
+ provider_->GetItemById(CreateContentId(env, j_namespace, j_id));
return OfflineItemBridge::CreateOfflineItem(env, item);
}
@@ -130,7 +146,19 @@ ScopedJavaLocalRef<jobject> OfflineContentAggregatorBridge::GetAllItems(
JNIEnv* env,
const JavaParamRef<jobject>& jobj) {
return OfflineItemBridge::CreateOfflineItemList(env,
- aggregator_->GetAllItems());
+ provider_->GetAllItems());
+}
+
+void OfflineContentAggregatorBridge::GetVisualsForItem(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& jobj,
+ const JavaParamRef<jstring>& j_namespace,
+ const JavaParamRef<jstring>& j_id,
+ const JavaParamRef<jobject>& j_callback) {
+ provider_->GetVisualsForItem(
+ CreateContentId(env, j_namespace, j_id),
+ base::Bind(&GetVisualsForItemHelperCallback,
+ ScopedJavaGlobalRef<jobject>(env, j_callback)));
}
void OfflineContentAggregatorBridge::OnItemsAvailable(
diff --git a/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.h b/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.h
index 5a291c6f1d6..e367edf468e 100644
--- a/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.h
+++ b/chromium/components/offline_items_collection/core/android/offline_content_aggregator_bridge.h
@@ -15,6 +15,7 @@ namespace offline_items_collection {
struct ContentId;
struct OfflineItem;
+class ThrottledOfflineContentProvider;
namespace android {
@@ -69,6 +70,12 @@ class OfflineContentAggregatorBridge : public OfflineContentProvider::Observer,
base::android::ScopedJavaLocalRef<jobject> GetAllItems(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj);
+ void GetVisualsForItem(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj,
+ const base::android::JavaParamRef<jstring>& j_namespace,
+ const base::android::JavaParamRef<jstring>& j_id,
+ const base::android::JavaParamRef<jobject>& j_callback);
private:
OfflineContentAggregatorBridge(OfflineContentAggregator* aggregator);
@@ -84,7 +91,7 @@ class OfflineContentAggregatorBridge : public OfflineContentProvider::Observer,
// OfflineContentAggregatorBridge.java.
base::android::ScopedJavaGlobalRef<jobject> java_ref_;
- OfflineContentAggregator* const aggregator_;
+ std::unique_ptr<ThrottledOfflineContentProvider> provider_;
DISALLOW_COPY_AND_ASSIGN(OfflineContentAggregatorBridge);
};
diff --git a/chromium/components/offline_items_collection/core/android/offline_item_bridge.cc b/chromium/components/offline_items_collection/core/android/offline_item_bridge.cc
index a21c50c5343..9cb70e5f88a 100644
--- a/chromium/components/offline_items_collection/core/android/offline_item_bridge.cc
+++ b/chromium/components/offline_items_collection/core/android/offline_item_bridge.cc
@@ -37,7 +37,8 @@ ScopedJavaLocalRef<jobject> createOfflineItemAndMaybeAddToList(
ConvertUTF8ToJavaString(env, item.page_url.spec()),
ConvertUTF8ToJavaString(env, item.original_url.spec()),
item.is_off_the_record, static_cast<jint>(item.state), item.is_resumable,
- item.allow_metered, item.received_bytes, item.percent_completed,
+ item.allow_metered, item.received_bytes, item.progress.value,
+ item.progress.max.value_or(-1), static_cast<jint>(item.progress.unit),
item.time_remaining_ms);
}
diff --git a/chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.cc b/chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.cc
new file mode 100644
index 00000000000..a1ff778155d
--- /dev/null
+++ b/chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.cc
@@ -0,0 +1,33 @@
+// Copyright 2017 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/offline_items_collection/core/android/offline_item_visuals_bridge.h"
+
+#include "components/offline_items_collection/core/offline_item.h"
+#include "jni/OfflineItemVisualsBridge_jni.h"
+#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/image/image.h"
+
+using base::android::ScopedJavaLocalRef;
+
+namespace offline_items_collection {
+namespace android {
+
+// static
+ScopedJavaLocalRef<jobject> OfflineItemVisualsBridge::CreateOfflineItemVisuals(
+ JNIEnv* env,
+ const OfflineItemVisuals* const visuals) {
+ if (!visuals)
+ return nullptr;
+
+ base::android::ScopedJavaLocalRef<jobject> j_icon;
+
+ if (!visuals->icon.IsEmpty())
+ j_icon = gfx::ConvertToJavaBitmap(visuals->icon.ToSkBitmap());
+
+ return Java_OfflineItemVisualsBridge_createOfflineItemVisuals(env, j_icon);
+}
+
+} // namespace android
+} // namespace offline_items_collection
diff --git a/chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.h b/chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.h
new file mode 100644
index 00000000000..472e34ecb98
--- /dev/null
+++ b/chromium/components/offline_items_collection/core/android/offline_item_visuals_bridge.h
@@ -0,0 +1,35 @@
+// Copyright 2017 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_OFFLINE_ITEMS_COLLECTION_CORE_ANDROID_OFFLINE_ITEM_VISUALS_BRIDGE_H_
+#define COMPONENTS_OFFLINE_ITEMS_COLLECTION_CORE_ANDROID_OFFLINE_ITEM_VISUALS_BRIDGE_H_
+
+#include <vector>
+
+#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+
+namespace offline_items_collection {
+
+struct OfflineItemVisuals;
+
+namespace android {
+
+// A helper class for creating Java OfflineItemVisuals instances from the C++
+// OfflineItemVisuals counterpart.
+class OfflineItemVisualsBridge {
+ public:
+ // Creates a Java OfflineItemVisuals from |visuals|.
+ static base::android::ScopedJavaLocalRef<jobject> CreateOfflineItemVisuals(
+ JNIEnv* env,
+ const OfflineItemVisuals* const visuals);
+
+ private:
+ OfflineItemVisualsBridge();
+};
+
+} // namespace android
+} // namespace offline_items_collection
+
+#endif // COMPONENTS_OFFLINE_ITEMS_COLLECTION_CORE_ANDROID_OFFLINE_ITEM_VISUALS_BRIDGE_H_
diff --git a/chromium/components/offline_items_collection/core/offline_content_aggregator.cc b/chromium/components/offline_items_collection/core/offline_content_aggregator.cc
index acbfd5a130b..19eaa574efe 100644
--- a/chromium/components/offline_items_collection/core/offline_content_aggregator.cc
+++ b/chromium/components/offline_items_collection/core/offline_content_aggregator.cc
@@ -145,6 +145,20 @@ OfflineContentAggregator::GetAllItems() {
return items;
}
+void OfflineContentAggregator::GetVisualsForItem(
+ const ContentId& id,
+ const VisualsCallback& callback) {
+ auto it = providers_.find(id.name_space);
+
+ if (it == providers_.end()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, id, nullptr));
+ return;
+ }
+
+ it->second->GetVisualsForItem(id, callback);
+}
+
void OfflineContentAggregator::AddObserver(
OfflineContentProvider::Observer* observer) {
DCHECK(observer);
diff --git a/chromium/components/offline_items_collection/core/offline_content_aggregator.h b/chromium/components/offline_items_collection/core/offline_content_aggregator.h
index 03497084678..68df56858a9 100644
--- a/chromium/components/offline_items_collection/core/offline_content_aggregator.h
+++ b/chromium/components/offline_items_collection/core/offline_content_aggregator.h
@@ -84,6 +84,8 @@ class OfflineContentAggregator : public OfflineContentProvider,
void ResumeDownload(const ContentId& id) override;
const OfflineItem* GetItemById(const ContentId& id) override;
OfflineItemList GetAllItems() override;
+ void GetVisualsForItem(const ContentId& id,
+ const VisualsCallback& callback) override;
void AddObserver(OfflineContentProvider::Observer* observer) override;
void RemoveObserver(OfflineContentProvider::Observer* observer) override;
diff --git a/chromium/components/offline_items_collection/core/offline_content_aggregator_unittest.cc b/chromium/components/offline_items_collection/core/offline_content_aggregator_unittest.cc
index 36193408445..45d77fd42e2 100644
--- a/chromium/components/offline_items_collection/core/offline_content_aggregator_unittest.cc
+++ b/chromium/components/offline_items_collection/core/offline_content_aggregator_unittest.cc
@@ -299,6 +299,8 @@ TEST_F(OfflineContentAggregatorTest, ActionPropagatesToRightProvider) {
EXPECT_CALL(provider2, ResumeDownload(id2)).Times(1);
EXPECT_CALL(provider1, PauseDownload(id1)).Times(1);
EXPECT_CALL(provider2, PauseDownload(id2)).Times(1);
+ EXPECT_CALL(provider1, GetVisualsForItem(id1, _)).Times(1);
+ EXPECT_CALL(provider2, GetVisualsForItem(id2, _)).Times(1);
aggregator_.OpenItem(id1);
aggregator_.OpenItem(id2);
aggregator_.RemoveItem(id1);
@@ -309,6 +311,8 @@ TEST_F(OfflineContentAggregatorTest, ActionPropagatesToRightProvider) {
aggregator_.ResumeDownload(id2);
aggregator_.PauseDownload(id1);
aggregator_.PauseDownload(id2);
+ aggregator_.GetVisualsForItem(id1, OfflineContentProvider::VisualsCallback());
+ aggregator_.GetVisualsForItem(id2, OfflineContentProvider::VisualsCallback());
}
TEST_F(OfflineContentAggregatorTest, ActionPropagatesAfterInitialize) {
diff --git a/chromium/components/offline_items_collection/core/offline_content_provider.h b/chromium/components/offline_items_collection/core/offline_content_provider.h
index 353a7bc2520..82af9958674 100644
--- a/chromium/components/offline_items_collection/core/offline_content_provider.h
+++ b/chromium/components/offline_items_collection/core/offline_content_provider.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/callback.h"
#include "base/macros.h"
#include "url/gurl.h"
@@ -15,6 +16,7 @@ namespace offline_items_collection {
struct ContentId;
struct OfflineItem;
+struct OfflineItemVisuals;
// A provider of a set of OfflineItems that are meant to be exposed to the UI.
// The provider is required to notify all observers of OnItemsAvailable when the
@@ -23,6 +25,8 @@ struct OfflineItem;
class OfflineContentProvider {
public:
using OfflineItemList = std::vector<OfflineItem>;
+ using VisualsCallback =
+ base::Callback<void(const ContentId&, const OfflineItemVisuals*)>;
// An observer class that should be notified of relevant changes to the
// underlying data source.
@@ -44,6 +48,7 @@ class OfflineContentProvider {
// Called when the contents of |item| have been updated and the UI should be
// refreshed for that item.
+ // TODO(dtrainor): Make this take a list of OfflineItems.
virtual void OnItemUpdated(const OfflineItem& item) = 0;
protected:
@@ -79,6 +84,13 @@ class OfflineContentProvider {
// Returns all OfflineItems for this particular provider.
virtual OfflineItemList GetAllItems() = 0;
+ // Asks for an OfflineItemVisuals struct for an OfflineItem represented by
+ // |id| or |nullptr| if one doesn't exist. The implementer should post any
+ // replies even if the results are available immediately to prevent reentrancy
+ // and for consistent behavior.
+ virtual void GetVisualsForItem(const ContentId& id,
+ const VisualsCallback& callback) = 0;
+
// Adds an observer that should be notified of OfflineItem list modifications.
// If the provider is already initialized OnItemsAvailable should be scheduled
// on this observer (suggested over calling the method directly to avoid
diff --git a/chromium/components/offline_items_collection/core/offline_item.cc b/chromium/components/offline_items_collection/core/offline_item.cc
index 9506bcf7f8d..762a17fa95d 100644
--- a/chromium/components/offline_items_collection/core/offline_item.cc
+++ b/chromium/components/offline_items_collection/core/offline_item.cc
@@ -26,6 +26,18 @@ bool ContentId::operator<(const ContentId& content_id) const {
std::tie(content_id.name_space, content_id.id);
}
+OfflineItem::Progress::Progress()
+ : value(0), unit(OfflineItemProgressUnit::BYTES) {}
+
+OfflineItem::Progress::Progress(const OfflineItem::Progress& other) = default;
+
+OfflineItem::Progress::~Progress() = default;
+
+bool OfflineItem::Progress::operator==(
+ const OfflineItem::Progress& other) const {
+ return value == other.value && max == other.max && unit == other.unit;
+}
+
OfflineItem::OfflineItem()
: filter(OfflineItemFilter::FILTER_OTHER),
is_transient(false),
@@ -37,7 +49,6 @@ OfflineItem::OfflineItem()
is_resumable(false),
allow_metered(false),
received_bytes(0),
- percent_completed(0),
time_remaining_ms(0) {}
OfflineItem::OfflineItem(const OfflineItem& other) = default;
@@ -65,8 +76,13 @@ bool OfflineItem::operator==(const OfflineItem& offline_item) const {
is_resumable == offline_item.is_resumable &&
allow_metered == offline_item.allow_metered &&
received_bytes == offline_item.received_bytes &&
- percent_completed == offline_item.percent_completed &&
+ progress == offline_item.progress &&
time_remaining_ms == offline_item.time_remaining_ms;
}
+OfflineItemVisuals::OfflineItemVisuals() = default;
+OfflineItemVisuals::OfflineItemVisuals(const OfflineItemVisuals& other) =
+ default;
+OfflineItemVisuals::~OfflineItemVisuals() = default;
+
} // namespace offline_items_collection
diff --git a/chromium/components/offline_items_collection/core/offline_item.h b/chromium/components/offline_items_collection/core/offline_item.h
index 5c98e94cd2b..12525688425 100644
--- a/chromium/components/offline_items_collection/core/offline_item.h
+++ b/chromium/components/offline_items_collection/core/offline_item.h
@@ -7,9 +7,11 @@
#include <string>
+#include "base/optional.h"
#include "base/time/time.h"
#include "components/offline_items_collection/core/offline_item_filter.h"
#include "components/offline_items_collection/core/offline_item_state.h"
+#include "ui/gfx/image/image.h"
#include "url/gurl.h"
namespace offline_items_collection {
@@ -37,6 +39,14 @@ struct ContentId {
bool operator<(const ContentId& content_id) const;
};
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.offline_items_collection
+enum class OfflineItemProgressUnit {
+ BYTES,
+ FILES,
+ PERCENTAGE,
+};
+
// This struct holds the relevant pieces of information to represent an abstract
// offline item to the front end. This is meant to be backed by components that
// need to both show content being offlined (downloading, saving, etc.) as well
@@ -45,6 +55,26 @@ struct ContentId {
//
// A new feature should expose these OfflineItems via an OfflineContentProvider.
struct OfflineItem {
+ // This struct holds the essential pieces of information to compute the
+ // download progress for an offline item to display in the UI.
+ struct Progress {
+ Progress();
+ Progress(const Progress& other);
+ ~Progress();
+
+ bool operator==(const Progress& progress) const;
+
+ // Current value of the download progress.
+ int64_t value;
+
+ // The maximum value of the download progress. Absence of the value implies
+ // indeterminate progress.
+ base::Optional<int64_t> max;
+
+ // The unit of progress to be displayed in the UI.
+ OfflineItemProgressUnit unit;
+ };
+
OfflineItem();
OfflineItem(const OfflineItem& other);
explicit OfflineItem(const ContentId& id);
@@ -121,11 +151,9 @@ struct OfflineItem {
// if |state| is COMPLETE.
int64_t received_bytes;
- // How complete (from 0 to 100) the offlining process is for this item. -1
- // represents that progress cannot be determined for this item and an
- // indeterminate progress bar should be used. This field is not used if
+ // Represents the current progress of this item. This field is not used if
// |state| is COMPLETE.
- int percent_completed;
+ Progress progress;
// The estimated time remaining for the download in milliseconds. -1
// represents an unknown time remaining. This field is not used if |state| is
@@ -133,6 +161,27 @@ struct OfflineItem {
int64_t time_remaining_ms;
};
+// This struct holds any potentially expensive visuals for an OfflineItem. If
+// the front end requires the visuals it will ask for them through the
+// OfflineContentProvider interface asynchronously to give the backend time to
+// generate them if necessary.
+//
+// It is not expected that these will change. Currently the UI might cache the
+// results of this call.
+// TODO(dtrainor): If we run into a scenario where this changes, add a way for
+// an OfflineItem update to let us know about an update to the visuals.
+struct OfflineItemVisuals {
+ OfflineItemVisuals();
+ OfflineItemVisuals(const OfflineItemVisuals& other);
+
+ ~OfflineItemVisuals();
+
+ // The icon to use for displaying this item. The icon should be 64dp x 64dp.
+ // TODO(dtrainor): Suggest icon size based on the icon size supported by the
+ // current OS.
+ gfx::Image icon;
+};
+
} // namespace offline_items_collection
#endif // COMPONENTS_OFFLINE_ITEMS_COLLECTION_OFFLINE_ITEM_H_
diff --git a/chromium/components/offline_items_collection/core/test_support/mock_offline_content_provider.h b/chromium/components/offline_items_collection/core/test_support/mock_offline_content_provider.h
index 5e4e0d599fe..c0c49a4cedb 100644
--- a/chromium/components/offline_items_collection/core/test_support/mock_offline_content_provider.h
+++ b/chromium/components/offline_items_collection/core/test_support/mock_offline_content_provider.h
@@ -44,6 +44,8 @@ class MockOfflineContentProvider : public OfflineContentProvider {
MOCK_METHOD1(PauseDownload, void(const ContentId&));
MOCK_METHOD1(ResumeDownload, void(const ContentId&));
MOCK_METHOD1(GetItemById, const OfflineItem*(const ContentId&));
+ MOCK_METHOD2(GetVisualsForItem,
+ void(const ContentId&, const VisualsCallback&));
MOCK_METHOD0(GetAllItems, OfflineItemList());
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
diff --git a/chromium/components/offline_items_collection/core/throttled_offline_content_provider.cc b/chromium/components/offline_items_collection/core/throttled_offline_content_provider.cc
index 1b534c84b87..b1a01640043 100644
--- a/chromium/components/offline_items_collection/core/throttled_offline_content_provider.cc
+++ b/chromium/components/offline_items_collection/core/throttled_offline_content_provider.cc
@@ -26,6 +26,7 @@ ThrottledOfflineContentProvider::ThrottledOfflineContentProvider(
const base::TimeDelta& delay_between_updates,
OfflineContentProvider* provider)
: delay_between_updates_(delay_between_updates),
+ last_update_time_(base::TimeTicks::Now()),
update_queued_(false),
wrapped_provider_(provider),
weak_ptr_factory_(this) {
@@ -43,22 +44,27 @@ bool ThrottledOfflineContentProvider::AreItemsAvailable() {
void ThrottledOfflineContentProvider::OpenItem(const ContentId& id) {
wrapped_provider_->OpenItem(id);
+ FlushUpdates();
}
void ThrottledOfflineContentProvider::RemoveItem(const ContentId& id) {
wrapped_provider_->RemoveItem(id);
+ FlushUpdates();
}
void ThrottledOfflineContentProvider::CancelDownload(const ContentId& id) {
wrapped_provider_->CancelDownload(id);
+ FlushUpdates();
}
void ThrottledOfflineContentProvider::PauseDownload(const ContentId& id) {
wrapped_provider_->PauseDownload(id);
+ FlushUpdates();
}
void ThrottledOfflineContentProvider::ResumeDownload(const ContentId& id) {
wrapped_provider_->ResumeDownload(id);
+ FlushUpdates();
}
const OfflineItem* ThrottledOfflineContentProvider::GetItemById(
@@ -77,6 +83,12 @@ ThrottledOfflineContentProvider::GetAllItems() {
return items;
}
+void ThrottledOfflineContentProvider::GetVisualsForItem(
+ const ContentId& id,
+ const VisualsCallback& callback) {
+ wrapped_provider_->GetVisualsForItem(id, callback);
+}
+
void ThrottledOfflineContentProvider::AddObserver(
OfflineContentProvider::Observer* observer) {
DCHECK(observer);
@@ -116,15 +128,27 @@ void ThrottledOfflineContentProvider::OnItemRemoved(const ContentId& id) {
void ThrottledOfflineContentProvider::OnItemUpdated(const OfflineItem& item) {
updates_[item.id] = item;
+
+ // If we already queued an update, we're throttling, just wait until the
+ // update passes through.
if (update_queued_)
return;
+ // If we haven't sent an update recently, let the update go through.
+ base::TimeDelta current_delay = base::TimeTicks::Now() - last_update_time_;
+ if (current_delay >= delay_between_updates_) {
+ FlushUpdates();
+ return;
+ }
+
+ // Queue the update so we wait for the proper amount of time before notifying
+ // observers.
update_queued_ = true;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&ThrottledOfflineContentProvider::FlushUpdates,
weak_ptr_factory_.GetWeakPtr()),
- delay_between_updates_);
+ delay_between_updates_ - current_delay);
}
void ThrottledOfflineContentProvider::NotifyItemsAvailable(
@@ -142,6 +166,7 @@ void ThrottledOfflineContentProvider::UpdateItemIfPresent(
}
void ThrottledOfflineContentProvider::FlushUpdates() {
+ last_update_time_ = base::TimeTicks::Now();
update_queued_ = false;
OfflineItemMap updates = std::move(updates_);
diff --git a/chromium/components/offline_items_collection/core/throttled_offline_content_provider.h b/chromium/components/offline_items_collection/core/throttled_offline_content_provider.h
index b704ffb0a23..86845f92666 100644
--- a/chromium/components/offline_items_collection/core/throttled_offline_content_provider.h
+++ b/chromium/components/offline_items_collection/core/throttled_offline_content_provider.h
@@ -19,7 +19,7 @@ namespace offline_items_collection {
// A simple wrapper around an OfflineContentProvider that throttles
// OfflineContentProvider::Observer::OnItemUpdated() calls to all registered
-// observers. This class will coalesce updates to an item with an equal
+// observers. This class will coalesce updates to an item with an equal
// ContentId.
class ThrottledOfflineContentProvider
: public OfflineContentProvider,
@@ -32,6 +32,10 @@ class ThrottledOfflineContentProvider
// OfflineContentProvider implementation.
bool AreItemsAvailable() override;
+
+ // Taking actions on the OfflineContentProvider will flush any queued updates
+ // immediately after performing the action. This is to make sure item updates
+ // in response to the update are immediately reflected back to the caller.
void OpenItem(const ContentId& id) override;
void RemoveItem(const ContentId& id) override;
void CancelDownload(const ContentId& id) override;
@@ -43,9 +47,15 @@ class ThrottledOfflineContentProvider
// the future.
const OfflineItem* GetItemById(const ContentId& id) override;
OfflineItemList GetAllItems() override;
+ void GetVisualsForItem(const ContentId& id,
+ const VisualsCallback& callback) override;
void AddObserver(OfflineContentProvider::Observer* observer) override;
void RemoveObserver(OfflineContentProvider::Observer* observer) override;
+ // Visible for testing. Overrides the time at which this throttle last pushed
+ // updates to observers.
+ void set_last_update_time(const base::TimeTicks& t) { last_update_time_ = t; }
+
private:
// OfflineContentProvider::Observer implementation.
void OnItemsAvailable(OfflineContentProvider* provider) override;
@@ -57,14 +67,17 @@ class ThrottledOfflineContentProvider
// called OfflineContentProvider::Observer::OnItemsAvailable().
void NotifyItemsAvailable(OfflineContentProvider::Observer* observer);
- // Checks if |item| already has an update pending. If so, replaces the
- // content of the update with |item|.
+ // Checks if |item| already has an update pending. If so, replaces the content
+ // of the update with |item|.
void UpdateItemIfPresent(const OfflineItem& item);
// Flushes all pending updates to the observers.
void FlushUpdates();
const base::TimeDelta delay_between_updates_;
+
+ // Information about whether or not we're queuing updates.
+ base::TimeTicks last_update_time_;
bool update_queued_;
OfflineContentProvider* const wrapped_provider_;
diff --git a/chromium/components/offline_items_collection/core/throttled_offline_content_provider_unittest.cc b/chromium/components/offline_items_collection/core/throttled_offline_content_provider_unittest.cc
index 414247b35c5..7191fb253df 100644
--- a/chromium/components/offline_items_collection/core/throttled_offline_content_provider_unittest.cc
+++ b/chromium/components/offline_items_collection/core/throttled_offline_content_provider_unittest.cc
@@ -13,9 +13,12 @@
#include "components/offline_items_collection/core/test_support/scoped_mock_offline_content_provider.h"
#include "components/offline_items_collection/core/throttled_offline_content_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gmock_mutant.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
+using testing::CallbackToFunctor;
+using testing::InvokeWithoutArgs;
using testing::Return;
namespace offline_items_collection {
@@ -56,13 +59,20 @@ class ThrottledOfflineContentProviderTest : public testing::Test {
ThrottledOfflineContentProviderTest()
: task_runner_(new base::TestMockTimeTaskRunner),
handle_(task_runner_),
- provider_(base::TimeDelta::FromMilliseconds(1), &wrapped_provider_) {}
+ delay_(base::TimeDelta::FromSeconds(1)),
+ provider_(delay_, &wrapped_provider_) {}
~ThrottledOfflineContentProviderTest() override {}
protected:
+ base::TimeTicks GetTimeThatWillAllowAnUpdate() {
+ return base::TimeTicks::Now() - delay_ -
+ base::TimeDelta::FromMilliseconds(1);
+ }
+
scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
base::ThreadTaskRunnerHandle handle_;
+ base::TimeDelta delay_;
MockOfflineContentProvider wrapped_provider_;
ThrottledOfflineContentProvider provider_;
};
@@ -105,15 +115,16 @@ TEST_F(ThrottledOfflineContentProviderTest, TestBasicPassthrough) {
EXPECT_CALL(wrapped_provider_, CancelDownload(id));
EXPECT_CALL(wrapped_provider_, PauseDownload(id));
EXPECT_CALL(wrapped_provider_, ResumeDownload(id));
+ EXPECT_CALL(wrapped_provider_, GetVisualsForItem(id, _));
EXPECT_CALL(wrapped_provider_, GetItemById(id)).WillRepeatedly(Return(&item));
EXPECT_CALL(wrapped_provider_, GetAllItems()).WillRepeatedly(Return(items));
-
wrapped_provider_.NotifyOnItemsAvailable();
provider_.OpenItem(id);
provider_.RemoveItem(id);
provider_.CancelDownload(id);
provider_.PauseDownload(id);
provider_.ResumeDownload(id);
+ provider_.GetVisualsForItem(id, OfflineContentProvider::VisualsCallback());
EXPECT_EQ(&item, provider_.GetItemById(id));
EXPECT_EQ(items, provider_.GetAllItems());
}
@@ -129,6 +140,7 @@ TEST_F(ThrottledOfflineContentProviderTest, TestRemoveCancelsUpdate) {
EXPECT_CALL(observer, OnItemRemoved(id)).Times(1);
wrapped_provider_.NotifyOnItemsAvailable();
+ provider_.set_last_update_time(base::TimeTicks::Now());
wrapped_provider_.NotifyOnItemUpdated(item);
wrapped_provider_.NotifyOnItemRemoved(id);
task_runner_->FastForwardUntilNoTasksRemain();
@@ -153,6 +165,7 @@ TEST_F(ThrottledOfflineContentProviderTest, TestOnItemUpdatedSquashed) {
EXPECT_CALL(observer, OnItemUpdated(updated_item2)).Times(1);
wrapped_provider_.NotifyOnItemsAvailable();
+ provider_.set_last_update_time(base::TimeTicks::Now());
wrapped_provider_.NotifyOnItemUpdated(item1);
wrapped_provider_.NotifyOnItemUpdated(item2);
wrapped_provider_.NotifyOnItemUpdated(updated_item2);
@@ -180,6 +193,7 @@ TEST_F(ThrottledOfflineContentProviderTest, TestGetItemByIdOverridesUpdate) {
EXPECT_CALL(observer, OnItemUpdated(item2)).Times(1);
wrapped_provider_.NotifyOnItemsAvailable();
+ provider_.set_last_update_time(base::TimeTicks::Now());
wrapped_provider_.NotifyOnItemUpdated(item1);
wrapped_provider_.NotifyOnItemUpdated(item2);
@@ -210,6 +224,7 @@ TEST_F(ThrottledOfflineContentProviderTest, TestGetAllItemsOverridesUpdate) {
EXPECT_CALL(observer, OnItemUpdated(item2)).Times(1);
wrapped_provider_.NotifyOnItemsAvailable();
+ provider_.set_last_update_time(base::TimeTicks::Now());
wrapped_provider_.NotifyOnItemUpdated(item1);
wrapped_provider_.NotifyOnItemUpdated(item2);
@@ -231,20 +246,61 @@ TEST_F(ThrottledOfflineContentProviderTest, TestThrottleWorksProperly) {
OfflineItem item3(id1);
item3.title = "updated2";
- EXPECT_CALL(observer, OnItemsAvailable(&provider_)).Times(1);
- EXPECT_CALL(observer, OnItemUpdated(item2)).Times(1);
+ OfflineItem item4(id1);
+ item4.title = "updated3";
+ EXPECT_CALL(observer, OnItemsAvailable(&provider_)).Times(1);
wrapped_provider_.NotifyOnItemsAvailable();
{
+ EXPECT_CALL(observer, OnItemUpdated(item1)).Times(1);
+ provider_.set_last_update_time(GetTimeThatWillAllowAnUpdate());
wrapped_provider_.NotifyOnItemUpdated(item1);
- wrapped_provider_.NotifyOnItemUpdated(item2);
- task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
}
{
EXPECT_CALL(observer, OnItemUpdated(item3)).Times(1);
+ provider_.set_last_update_time(base::TimeTicks::Now());
+ wrapped_provider_.NotifyOnItemUpdated(item2);
wrapped_provider_.NotifyOnItemUpdated(item3);
+ task_runner_->FastForwardBy(delay_);
+ }
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item4)).Times(1);
+ provider_.set_last_update_time(GetTimeThatWillAllowAnUpdate());
+ wrapped_provider_.NotifyOnItemUpdated(item4);
+ task_runner_->FastForwardUntilNoTasksRemain();
+ }
+}
+
+TEST_F(ThrottledOfflineContentProviderTest, TestInitialRequestGoesThrough) {
+ ScopedMockOfflineContentProvider::ScopedMockObserver observer(&provider_);
+
+ ContentId id1("1", "A");
+
+ OfflineItem item1(id1);
+
+ OfflineItem item1_updated(id1);
+ item1_updated.title = "updated1";
+
+ EXPECT_CALL(observer, OnItemsAvailable(&provider_)).Times(1);
+ wrapped_provider_.NotifyOnItemsAvailable();
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item1)).Times(1);
+ provider_.set_last_update_time(GetTimeThatWillAllowAnUpdate());
+ wrapped_provider_.NotifyOnItemUpdated(item1);
+ }
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(_)).Times(0);
+ provider_.set_last_update_time(base::TimeTicks::Now());
+ wrapped_provider_.NotifyOnItemUpdated(item1_updated);
+ }
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item1_updated)).Times(1);
task_runner_->FastForwardUntilNoTasksRemain();
}
}
@@ -260,13 +316,12 @@ TEST_F(ThrottledOfflineContentProviderTest, TestReentrantUpdatesGetQueued) {
updated_item);
EXPECT_CALL(observer, OnItemsAvailable(&provider_)).Times(1);
-
wrapped_provider_.NotifyOnItemsAvailable();
{
wrapped_provider_.NotifyOnItemUpdated(item);
EXPECT_CALL(observer, OnItemUpdated(item)).Times(1);
- task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
+ task_runner_->FastForwardBy(delay_);
}
{
@@ -275,5 +330,81 @@ TEST_F(ThrottledOfflineContentProviderTest, TestReentrantUpdatesGetQueued) {
}
}
+TEST_F(ThrottledOfflineContentProviderTest, TestPokingProviderFlushesQueue) {
+ ScopedMockOfflineContentProvider::ScopedMockObserver observer(&provider_);
+
+ EXPECT_CALL(observer, OnItemsAvailable(&provider_)).Times(1);
+ wrapped_provider_.NotifyOnItemsAvailable();
+
+ ContentId id1("1", "A");
+ OfflineItem item1(id1);
+
+ OfflineItem item2(ContentId("2", "B"));
+ OfflineItem item3(ContentId("3", "C"));
+ OfflineItem item4(ContentId("4", "D"));
+ OfflineItem item5(ContentId("5", "E"));
+ OfflineItem item6(ContentId("6", "F"));
+
+ auto updater = base::Bind(&MockOfflineContentProvider::NotifyOnItemUpdated,
+ base::Unretained(&wrapped_provider_));
+
+ // Set up reentrancy calls back into the provider.
+ EXPECT_CALL(wrapped_provider_, OpenItem(_))
+ .WillRepeatedly(
+ InvokeWithoutArgs(CallbackToFunctor(base::Bind(updater, item2))));
+ EXPECT_CALL(wrapped_provider_, RemoveItem(_))
+ .WillRepeatedly(
+ InvokeWithoutArgs(CallbackToFunctor(base::Bind(updater, item3))));
+ EXPECT_CALL(wrapped_provider_, CancelDownload(_))
+ .WillRepeatedly(
+ InvokeWithoutArgs(CallbackToFunctor(base::Bind(updater, item4))));
+ EXPECT_CALL(wrapped_provider_, PauseDownload(_))
+ .WillRepeatedly(
+ InvokeWithoutArgs(CallbackToFunctor(base::Bind(updater, item5))));
+ EXPECT_CALL(wrapped_provider_, ResumeDownload(_))
+ .WillRepeatedly(
+ InvokeWithoutArgs(CallbackToFunctor(base::Bind(updater, item6))));
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item1)).Times(1);
+ EXPECT_CALL(observer, OnItemUpdated(item2)).Times(1);
+ provider_.set_last_update_time(base::TimeTicks::Now());
+ wrapped_provider_.NotifyOnItemUpdated(item1);
+ provider_.OpenItem(id1);
+ }
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item1)).Times(1);
+ EXPECT_CALL(observer, OnItemUpdated(item3)).Times(1);
+ provider_.set_last_update_time(base::TimeTicks::Now());
+ wrapped_provider_.NotifyOnItemUpdated(item1);
+ provider_.RemoveItem(id1);
+ }
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item1)).Times(1);
+ EXPECT_CALL(observer, OnItemUpdated(item4)).Times(1);
+ provider_.set_last_update_time(base::TimeTicks::Now());
+ wrapped_provider_.NotifyOnItemUpdated(item1);
+ provider_.CancelDownload(id1);
+ }
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item1)).Times(1);
+ EXPECT_CALL(observer, OnItemUpdated(item5)).Times(1);
+ provider_.set_last_update_time(base::TimeTicks::Now());
+ wrapped_provider_.NotifyOnItemUpdated(item1);
+ provider_.PauseDownload(id1);
+ }
+
+ {
+ EXPECT_CALL(observer, OnItemUpdated(item1)).Times(1);
+ EXPECT_CALL(observer, OnItemUpdated(item6)).Times(1);
+ provider_.set_last_update_time(base::TimeTicks::Now());
+ wrapped_provider_.NotifyOnItemUpdated(item1);
+ provider_.ResumeDownload(id1);
+ }
+}
+
} // namespace
} // namespace offline_items_collection;
diff --git a/chromium/components/offline_pages/OWNERS b/chromium/components/offline_pages/OWNERS
index 4b3428eacec..5ccdbe2c8d6 100644
--- a/chromium/components/offline_pages/OWNERS
+++ b/chromium/components/offline_pages/OWNERS
@@ -4,4 +4,5 @@ fgorski@chromium.org
jianli@chromium.org
petewil@chromium.org
+# TEAM: offline-dev@chromium.org
# COMPONENT: UI>Browser>Offline
diff --git a/chromium/components/offline_pages/content/BUILD.gn b/chromium/components/offline_pages/content/BUILD.gn
new file mode 100644
index 00000000000..5b1ddb58446
--- /dev/null
+++ b/chromium/components/offline_pages/content/BUILD.gn
@@ -0,0 +1,45 @@
+# Copyright 2015 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.
+
+if (is_android) {
+ import("//build/config/android/rules.gni")
+}
+
+static_library("content") {
+ sources = [
+ "prefetch_service_factory.cc",
+ "prefetch_service_factory.h",
+ "suggested_articles_observer.cc",
+ "suggested_articles_observer.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/keyed_service/content",
+ "//components/ntp_snippets",
+ "//components/offline_pages/core",
+ "//components/offline_pages/core:switches",
+ "//components/offline_pages/core/prefetch",
+ "//content/public/browser",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "suggested_articles_observer_unittest.cc",
+ ]
+
+ deps = [
+ ":content",
+ "//base",
+ "//base/test:test_support",
+ "//components/offline_pages/core",
+ "//components/offline_pages/core:test_support",
+ "//components/offline_pages/core/prefetch",
+ "//content/test:test_support",
+ "//testing/gtest",
+ "//url",
+ ]
+}
diff --git a/chromium/components/offline_pages/content/DEPS b/chromium/components/offline_pages/content/DEPS
new file mode 100644
index 00000000000..4edd3b18c37
--- /dev/null
+++ b/chromium/components/offline_pages/content/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+components/keyed_service/content",
+ "+components/ntp_snippets",
+ "+content/public/browser",
+ "+content/public/test",
+]
diff --git a/chromium/components/offline_pages/content/prefetch_service_factory.cc b/chromium/components/offline_pages/content/prefetch_service_factory.cc
new file mode 100644
index 00000000000..ffe46b26308
--- /dev/null
+++ b/chromium/components/offline_pages/content/prefetch_service_factory.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 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/offline_pages/content/prefetch_service_factory.h"
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/offline_pages/core/prefetch/prefetch_service_impl.h"
+#include "content/public/browser/browser_context.h"
+
+namespace offline_pages {
+
+PrefetchServiceFactory::PrefetchServiceFactory()
+ : BrowserContextKeyedServiceFactory(
+ "OfflinePagePrefetchService",
+ BrowserContextDependencyManager::GetInstance()) {}
+
+// static
+PrefetchServiceFactory* PrefetchServiceFactory::GetInstance() {
+ return base::Singleton<PrefetchServiceFactory>::get();
+}
+
+// static
+PrefetchService* PrefetchServiceFactory::GetForBrowserContext(
+ content::BrowserContext* context) {
+ return static_cast<PrefetchService*>(
+ GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+KeyedService* PrefetchServiceFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new PrefetchServiceImpl();
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/content/prefetch_service_factory.h b/chromium/components/offline_pages/content/prefetch_service_factory.h
new file mode 100644
index 00000000000..c7f4fb16696
--- /dev/null
+++ b/chromium/components/offline_pages/content/prefetch_service_factory.h
@@ -0,0 +1,43 @@
+// Copyright 2017 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_OFFLINE_PAGES_CONTENT_PREFETCH_SERVICE_FACTORY_H_
+#define COMPONENTS_OFFLINE_PAGES_CONTENT_PREFETCH_SERVICE_FACTORY_H_
+
+#include "base/macros.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+} // namespace base
+
+namespace offline_pages {
+
+class PrefetchService;
+
+// A factory to create one PrefetchServiceImpl per browser context. Prefetching
+// Offline Pages is not supported in incognito, so this class uses default
+// implementation of |GetBrowserContextToUse|.
+class PrefetchServiceFactory : public BrowserContextKeyedServiceFactory {
+ public:
+ static PrefetchServiceFactory* GetInstance();
+ static PrefetchService* GetForBrowserContext(
+ content::BrowserContext* context);
+
+ private:
+ friend struct base::DefaultSingletonTraits<PrefetchServiceFactory>;
+
+ PrefetchServiceFactory();
+ ~PrefetchServiceFactory() override {}
+
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefetchServiceFactory);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CONTENT_PREFETCH_SERVICE_FACTORY_H_
diff --git a/chromium/components/offline_pages/content/suggested_articles_observer.cc b/chromium/components/offline_pages/content/suggested_articles_observer.cc
new file mode 100644
index 00000000000..4b60a286f7b
--- /dev/null
+++ b/chromium/components/offline_pages/content/suggested_articles_observer.cc
@@ -0,0 +1,170 @@
+// Copyright 2017 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/offline_pages/content/suggested_articles_observer.h"
+
+#include <unordered_set>
+
+#include "base/memory/ptr_util.h"
+#include "components/ntp_snippets/category.h"
+#include "components/ntp_snippets/category_status.h"
+#include "components/offline_pages/content/prefetch_service_factory.h"
+#include "components/offline_pages/core/client_namespace_constants.h"
+#include "components/offline_pages/core/offline_page_feature.h"
+#include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
+#include "components/offline_pages/core/prefetch/prefetch_service.h"
+
+using ntp_snippets::Category;
+using ntp_snippets::ContentSuggestion;
+
+namespace offline_pages {
+
+namespace {
+
+int kOfflinePageSuggestedArticlesObserverUserDataKey;
+
+const ntp_snippets::Category& ArticlesCategory() {
+ static ntp_snippets::Category articles =
+ Category::FromKnownCategory(ntp_snippets::KnownCategories::ARTICLES);
+ return articles;
+}
+
+ClientId CreateClientIDFromSuggestionId(const ContentSuggestion::ID& id) {
+ return ClientId(kSuggestedArticlesNamespace, id.id_within_category());
+}
+
+// The default delegate that contains external dependencies for the Offline Page
+// Suggestions Observer. This is unused in tests, which implement their own
+// Delegate.
+class DefaultDelegate : public SuggestedArticlesObserver::Delegate {
+ public:
+ explicit DefaultDelegate(ntp_snippets::ContentSuggestionsService* service);
+ ~DefaultDelegate() override = default;
+
+ const std::vector<ContentSuggestion>& GetSuggestions(
+ const Category& category) override;
+ PrefetchService* GetPrefetchService(
+ content::BrowserContext* context) override;
+
+ private:
+ ntp_snippets::ContentSuggestionsService* service_;
+};
+
+DefaultDelegate::DefaultDelegate(
+ ntp_snippets::ContentSuggestionsService* service)
+ : service_(service) {}
+
+const std::vector<ContentSuggestion>& DefaultDelegate::GetSuggestions(
+ const Category& category) {
+ return service_->GetSuggestionsForCategory(category);
+}
+
+PrefetchService* DefaultDelegate::GetPrefetchService(
+ content::BrowserContext* context) {
+ return PrefetchServiceFactory::GetForBrowserContext(context);
+}
+
+} // namespace
+
+// static
+void SuggestedArticlesObserver::ObserveContentSuggestionsService(
+ content::BrowserContext* browser_context,
+ ntp_snippets::ContentSuggestionsService* service) {
+ if (!offline_pages::IsPrefetchingOfflinePagesEnabled())
+ return;
+
+ auto suggestions_observer = base::MakeUnique<SuggestedArticlesObserver>(
+ browser_context, base::MakeUnique<DefaultDelegate>(service));
+ service->AddObserver(suggestions_observer.get());
+ service->SetUserData(&kOfflinePageSuggestedArticlesObserverUserDataKey,
+ std::move(suggestions_observer));
+}
+
+SuggestedArticlesObserver::SuggestedArticlesObserver(
+ content::BrowserContext* browser_context,
+ std::unique_ptr<Delegate> delegate)
+ : browser_context_(browser_context), delegate_(std::move(delegate)) {}
+
+SuggestedArticlesObserver::~SuggestedArticlesObserver() = default;
+
+void SuggestedArticlesObserver::OnNewSuggestions(Category category) {
+ // TODO(dewittj): Change this to check whether a given category is not
+ // a _remote_ category.
+ if (category != ArticlesCategory() ||
+ category_status_ != ntp_snippets::CategoryStatus::AVAILABLE) {
+ return;
+ }
+
+ const std::vector<ContentSuggestion>& suggestions =
+ delegate_->GetSuggestions(ArticlesCategory());
+ if (suggestions.empty())
+ return;
+
+ std::vector<PrefetchDispatcher::PrefetchURL> prefetch_urls;
+ for (const ContentSuggestion& suggestion : suggestions) {
+ prefetch_urls.push_back(
+ {CreateClientIDFromSuggestionId(suggestion.id()), suggestion.url()});
+ }
+
+ PrefetchService* service = delegate_->GetPrefetchService(browser_context_);
+ if (service == nullptr) {
+ DVLOG(1) << "PrefetchService unavailable to the "
+ "SuggestedArticlesObserver.";
+ return;
+ }
+ service->GetDispatcher()->AddCandidatePrefetchURLs(prefetch_urls);
+}
+
+void SuggestedArticlesObserver::OnCategoryStatusChanged(
+ Category category,
+ ntp_snippets::CategoryStatus new_status) {
+ if (category != ArticlesCategory() || category_status_ == new_status)
+ return;
+
+ category_status_ = new_status;
+
+ if (category_status_ ==
+ ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED ||
+ category_status_ ==
+ ntp_snippets::CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED) {
+ PrefetchService* service = delegate_->GetPrefetchService(browser_context_);
+ if (service == nullptr) {
+ DVLOG(1) << "PrefetchService unavailable to the "
+ "SuggestedArticlesObserver.";
+ return;
+ }
+ service->GetDispatcher()->RemoveAllUnprocessedPrefetchURLs(
+ kSuggestedArticlesNamespace);
+ }
+}
+
+void SuggestedArticlesObserver::OnSuggestionInvalidated(
+ const ContentSuggestion::ID& suggestion_id) {
+ PrefetchService* service = delegate_->GetPrefetchService(browser_context_);
+ if (service == nullptr) {
+ DVLOG(1) << "PrefetchService unavailable to the "
+ "SuggestedArticlesObserver.";
+ return;
+ }
+ service->GetDispatcher()->RemovePrefetchURLsByClientId(
+ CreateClientIDFromSuggestionId(suggestion_id));
+}
+
+void SuggestedArticlesObserver::OnFullRefreshRequired() {
+ PrefetchService* service = delegate_->GetPrefetchService(browser_context_);
+ if (service == nullptr) {
+ DVLOG(1) << "PrefetchService unavailable to the "
+ "SuggestedArticlesObserver.";
+ return;
+ }
+ service->GetDispatcher()->RemoveAllUnprocessedPrefetchURLs(
+ kSuggestedArticlesNamespace);
+ OnNewSuggestions(ArticlesCategory());
+}
+
+void SuggestedArticlesObserver::ContentSuggestionsServiceShutdown() {
+ // No need to do anything here, we will just stop getting events.
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/content/suggested_articles_observer.h b/chromium/components/offline_pages/content/suggested_articles_observer.h
new file mode 100644
index 00000000000..6448c013538
--- /dev/null
+++ b/chromium/components/offline_pages/content/suggested_articles_observer.h
@@ -0,0 +1,80 @@
+// Copyright 2017 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_OFFLINE_PAGES_CONTENT_SUGGESTED_ARTICLES_OBSERVER_H_
+#define COMPONENTS_OFFLINE_PAGES_CONTENT_SUGGESTED_ARTICLES_OBSERVER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "components/ntp_snippets/content_suggestions_service.h"
+
+namespace content {
+class BrowserContext;
+} // namespace content
+
+namespace ntp_snippets {
+class Category;
+}
+
+namespace offline_pages {
+class PrefetchService;
+
+// Observes the ContentSuggestionsService, listening for new suggestions in the
+// ARTICLES category. When those suggestions arrive, it then forwards them to
+// the Prefetch Service, which does not know about Content Suggestions
+// specifically.
+class SuggestedArticlesObserver
+ : public ntp_snippets::ContentSuggestionsService::Observer,
+ public base::SupportsUserData::Data {
+ public:
+ // Delegate exists to allow for dependency injection in unit tests.
+ // SuggestedArticlesObserver implements its own delegate, |DefaultDelegate| in
+ // the .cc file that forwards to the ContentSuggestionsService and the
+ // PrefetchServiceFactory. Code inside |DefaultDelegate| should be as simple
+ // as possible, since it will only be covered by instrumentation/browser
+ // tests.
+ class Delegate {
+ public:
+ virtual const std::vector<ntp_snippets::ContentSuggestion>& GetSuggestions(
+ const ntp_snippets::Category& category) = 0;
+ virtual PrefetchService* GetPrefetchService(
+ content::BrowserContext* context) = 0;
+ virtual ~Delegate() = default;
+ };
+
+ // This API creates a new SuggestedArticlesObserver and adds it as an
+ // observer to the ContentSuggestionsService provided. Its lifetime is
+ // managed by the ContentSuggestionsService.
+ static void ObserveContentSuggestionsService(
+ content::BrowserContext* browser_context,
+ ntp_snippets::ContentSuggestionsService* service);
+
+ SuggestedArticlesObserver(content::BrowserContext* browser_context,
+ std::unique_ptr<Delegate> delegate);
+ ~SuggestedArticlesObserver() override;
+
+ // ContentSuggestionsService::Observer overrides.
+ void OnNewSuggestions(ntp_snippets::Category category) override;
+ void OnCategoryStatusChanged(
+ ntp_snippets::Category category,
+ ntp_snippets::CategoryStatus new_status) override;
+ void OnSuggestionInvalidated(
+ const ntp_snippets::ContentSuggestion::ID& suggestion_id) override;
+ void OnFullRefreshRequired() override;
+ void ContentSuggestionsServiceShutdown() override;
+
+ private:
+ content::BrowserContext* browser_context_;
+ ntp_snippets::CategoryStatus category_status_ =
+ ntp_snippets::CategoryStatus::INITIALIZING;
+ std::unique_ptr<Delegate> delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(SuggestedArticlesObserver);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CONTENT_SUGGESTED_ARTICLES_OBSERVER_H_
diff --git a/chromium/components/offline_pages/content/suggested_articles_observer_unittest.cc b/chromium/components/offline_pages/content/suggested_articles_observer_unittest.cc
new file mode 100644
index 00000000000..6fae70d85ce
--- /dev/null
+++ b/chromium/components/offline_pages/content/suggested_articles_observer_unittest.cc
@@ -0,0 +1,215 @@
+// Copyright 2017 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/offline_pages/content/suggested_articles_observer.h"
+
+#include "base/run_loop.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/offline_pages/core/client_namespace_constants.h"
+#include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
+#include "components/offline_pages/core/prefetch/prefetch_service.h"
+#include "components/offline_pages/core/stub_offline_page_model.h"
+#include "content/public/test/test_browser_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+using ntp_snippets::Category;
+using ntp_snippets::ContentSuggestion;
+
+namespace offline_pages {
+
+namespace {
+
+ContentSuggestion ContentSuggestionFromTestURL(const GURL& test_url) {
+ auto category =
+ Category::FromKnownCategory(ntp_snippets::KnownCategories::ARTICLES);
+ return ContentSuggestion(category, test_url.spec(), test_url);
+}
+
+class TestingPrefetchDispatcher : public PrefetchDispatcher {
+ public:
+ TestingPrefetchDispatcher() = default;
+
+ void AddCandidatePrefetchURLs(
+ const std::vector<PrefetchURL>& suggested_urls) override {
+ latest_prefetch_urls = suggested_urls;
+ new_suggestions_count++;
+ }
+
+ void RemoveAllUnprocessedPrefetchURLs(
+ const std::string& name_space) override {
+ DCHECK_EQ(name_space, kSuggestedArticlesNamespace);
+ latest_prefetch_urls.clear();
+ remove_all_suggestions_count++;
+ }
+
+ void RemovePrefetchURLsByClientId(const ClientId& client_id) override {
+ DCHECK_EQ(client_id.name_space, kSuggestedArticlesNamespace);
+ remove_by_client_id_count++;
+ last_removed_client_id = base::MakeUnique<ClientId>(client_id);
+ }
+
+ void BeginBackgroundTask(
+ std::unique_ptr<ScopedBackgroundTask> task) override {}
+ void StopBackgroundTask(ScopedBackgroundTask* task) override {}
+
+ std::vector<PrefetchURL> latest_prefetch_urls;
+ std::unique_ptr<ClientId> last_removed_client_id;
+
+ int new_suggestions_count = 0;
+ int remove_all_suggestions_count = 0;
+ int remove_by_client_id_count = 0;
+};
+
+class TestingPrefetchService : public PrefetchService {
+ public:
+ TestingPrefetchService() = default;
+
+ PrefetchDispatcher* GetDispatcher() override { return &dispatcher; };
+
+ TestingPrefetchDispatcher dispatcher;
+};
+
+class TestDelegate : public SuggestedArticlesObserver::Delegate {
+ public:
+ TestDelegate() = default;
+ ~TestDelegate() override = default;
+
+ const std::vector<ContentSuggestion>& GetSuggestions(
+ const Category& category) override {
+ get_suggestions_count++;
+ return suggestions;
+ }
+
+ PrefetchService* GetPrefetchService(
+ content::BrowserContext* context) override {
+ return &prefetch_service;
+ }
+
+ TestingPrefetchService prefetch_service;
+
+ // Public for test manipulation.
+ std::vector<ContentSuggestion> suggestions;
+
+ // Signals that delegate was called.
+ int get_suggestions_count = 0;
+};
+
+} // namespace
+
+class OfflinePageSuggestedArticlesObserverTest : public testing::Test {
+ public:
+ OfflinePageSuggestedArticlesObserverTest() = default;
+
+ void SetUp() override {
+ observer_ =
+ base::MakeUnique<SuggestedArticlesObserver>(&context_, MakeDelegate());
+ }
+
+ virtual std::unique_ptr<SuggestedArticlesObserver::Delegate> MakeDelegate() {
+ auto delegate_ptr = base::MakeUnique<TestDelegate>();
+ test_delegate_ = delegate_ptr.get();
+ return std::move(delegate_ptr);
+ }
+
+ SuggestedArticlesObserver* observer() { return observer_.get(); }
+
+ TestDelegate* test_delegate() { return test_delegate_; }
+
+ TestingPrefetchService* test_prefetch_service() {
+ return &(test_delegate()->prefetch_service);
+ }
+
+ TestingPrefetchDispatcher* test_prefetch_dispatcher() {
+ return &(test_prefetch_service()->dispatcher);
+ }
+
+ protected:
+ Category category =
+ Category::FromKnownCategory(ntp_snippets::KnownCategories::ARTICLES);
+ content::TestBrowserContext context_;
+
+ private:
+ std::unique_ptr<SuggestedArticlesObserver> observer_;
+ TestDelegate* test_delegate_;
+};
+
+TEST_F(OfflinePageSuggestedArticlesObserverTest,
+ CallsDelegateOnNewSuggestions) {
+ // We should not do anything if the category is not loaded.
+ observer()->OnNewSuggestions(category);
+ EXPECT_EQ(0, test_delegate()->get_suggestions_count);
+ EXPECT_EQ(0, test_prefetch_dispatcher()->new_suggestions_count);
+
+ // Once the category becomes available, new suggestions should cause us to ask
+ // the delegate for suggestion URLs.
+ observer()->OnCategoryStatusChanged(category,
+ ntp_snippets::CategoryStatus::AVAILABLE);
+ observer()->OnNewSuggestions(category);
+ EXPECT_EQ(1, test_delegate()->get_suggestions_count);
+
+ // We expect that no pages were forwarded to the prefetch service since no
+ // pages were prepopulated.
+ EXPECT_EQ(0, test_prefetch_dispatcher()->new_suggestions_count);
+}
+
+TEST_F(OfflinePageSuggestedArticlesObserverTest,
+ ForwardsSuggestionsToPrefetchService) {
+ const GURL test_url_1("https://www.example.com/1");
+ test_delegate()->suggestions.push_back(
+ ContentSuggestionFromTestURL(test_url_1));
+
+ observer()->OnCategoryStatusChanged(category,
+ ntp_snippets::CategoryStatus::AVAILABLE);
+ observer()->OnNewSuggestions(category);
+ EXPECT_EQ(1, test_prefetch_dispatcher()->new_suggestions_count);
+ EXPECT_EQ(1U, test_prefetch_dispatcher()->latest_prefetch_urls.size());
+ EXPECT_EQ(test_url_1,
+ test_prefetch_dispatcher()->latest_prefetch_urls[0].url);
+ EXPECT_EQ(
+ kSuggestedArticlesNamespace,
+ test_prefetch_dispatcher()->latest_prefetch_urls[0].client_id.name_space);
+}
+
+TEST_F(OfflinePageSuggestedArticlesObserverTest, RemovesAllOnBadStatus) {
+ const GURL test_url_1("https://www.example.com/1");
+ const GURL test_url_2("https://www.example.com/2");
+ test_delegate()->suggestions.push_back(
+ ContentSuggestionFromTestURL(test_url_1));
+ test_delegate()->suggestions.push_back(
+ ContentSuggestionFromTestURL(test_url_2));
+
+ observer()->OnCategoryStatusChanged(category,
+ ntp_snippets::CategoryStatus::AVAILABLE);
+ observer()->OnNewSuggestions(category);
+ ASSERT_EQ(2U, test_prefetch_dispatcher()->latest_prefetch_urls.size());
+
+ observer()->OnCategoryStatusChanged(
+ category, ntp_snippets::CategoryStatus::CATEGORY_EXPLICITLY_DISABLED);
+ EXPECT_EQ(1, test_prefetch_dispatcher()->remove_all_suggestions_count);
+ observer()->OnCategoryStatusChanged(
+ category,
+ ntp_snippets::CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED);
+ EXPECT_EQ(2, test_prefetch_dispatcher()->remove_all_suggestions_count);
+}
+
+TEST_F(OfflinePageSuggestedArticlesObserverTest, RemovesClientIdOnInvalidated) {
+ const GURL test_url_1("https://www.example.com/1");
+ test_delegate()->suggestions.push_back(
+ ContentSuggestionFromTestURL(test_url_1));
+ observer()->OnCategoryStatusChanged(category,
+ ntp_snippets::CategoryStatus::AVAILABLE);
+ observer()->OnNewSuggestions(category);
+ ASSERT_EQ(1U, test_prefetch_dispatcher()->latest_prefetch_urls.size());
+
+ observer()->OnSuggestionInvalidated(
+ ntp_snippets::ContentSuggestion::ID(category, test_url_1.spec()));
+
+ EXPECT_EQ(1, test_prefetch_dispatcher()->remove_by_client_id_count);
+ EXPECT_EQ(ClientId(kSuggestedArticlesNamespace, test_url_1.spec()),
+ *test_prefetch_dispatcher()->last_removed_client_id);
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/BUILD.gn b/chromium/components/offline_pages/core/BUILD.gn
index 21708d2b71c..315f64b4376 100644
--- a/chromium/components/offline_pages/core/BUILD.gn
+++ b/chromium/components/offline_pages/core/BUILD.gn
@@ -20,7 +20,6 @@ static_library("core") {
"offline_page_client_policy.h",
"offline_page_item.cc",
"offline_page_item.h",
- "offline_page_metadata_store.cc",
"offline_page_metadata_store.h",
"offline_page_metadata_store_sql.cc",
"offline_page_metadata_store_sql.h",
@@ -95,9 +94,10 @@ source_set("unit_tests") {
"archive_manager_unittest.cc",
"client_policy_controller_unittest.cc",
"offline_event_logger_unittest.cc",
- "offline_page_metadata_store_impl_unittest.cc",
+ "offline_page_metadata_store_unittest.cc",
"offline_page_model_event_logger_unittest.cc",
"offline_page_model_impl_unittest.cc",
+ "offline_page_model_query_unittest.cc",
"offline_page_storage_manager_unittest.cc",
"snapshot_controller_unittest.cc",
"task_queue_unittest.cc",
@@ -108,6 +108,7 @@ source_set("unit_tests") {
":core",
":switches",
":test_support",
+ "prefetch:unit_tests",
"recent_tabs:unit_tests",
"//base",
"//base/test:test_support",
diff --git a/chromium/components/offline_pages/core/background/BUILD.gn b/chromium/components/offline_pages/core/background/BUILD.gn
index 63971560654..083e7a9e898 100644
--- a/chromium/components/offline_pages/core/background/BUILD.gn
+++ b/chromium/components/offline_pages/core/background/BUILD.gn
@@ -23,6 +23,7 @@ static_library("background_offliner") {
"get_requests_task.h",
"initialize_store_task.cc",
"initialize_store_task.h",
+ "load_termination_listener.h",
"mark_attempt_aborted_task.cc",
"mark_attempt_aborted_task.h",
"mark_attempt_completed_task.cc",
diff --git a/chromium/components/offline_pages/core/background/cleanup_task.cc b/chromium/components/offline_pages/core/background/cleanup_task.cc
index d66d48b610e..4bde94370c4 100644
--- a/chromium/components/offline_pages/core/background/cleanup_task.cc
+++ b/chromium/components/offline_pages/core/background/cleanup_task.cc
@@ -14,6 +14,24 @@
#include "components/offline_pages/core/background/save_page_request.h"
namespace offline_pages {
+namespace {
+RequestNotifier::BackgroundSavePageResult ToBackgroundSavePageResult(
+ OfflinerPolicyUtils::RequestExpirationStatus expiration_status) {
+ switch (expiration_status) {
+ case OfflinerPolicyUtils::RequestExpirationStatus::EXPIRED:
+ return RequestNotifier::BackgroundSavePageResult::EXPIRED;
+ case OfflinerPolicyUtils::RequestExpirationStatus::START_COUNT_EXCEEDED:
+ return RequestNotifier::BackgroundSavePageResult::START_COUNT_EXCEEDED;
+ case OfflinerPolicyUtils::RequestExpirationStatus::
+ COMPLETION_COUNT_EXCEEDED:
+ return RequestNotifier::BackgroundSavePageResult::RETRY_COUNT_EXCEEDED;
+ case OfflinerPolicyUtils::RequestExpirationStatus::VALID:
+ default:
+ NOTREACHED();
+ return RequestNotifier::BackgroundSavePageResult::EXPIRED;
+ }
+}
+} // namespace
CleanupTask::CleanupTask(RequestQueueStore* store,
OfflinerPolicy* policy,
@@ -46,18 +64,18 @@ void CleanupTask::Prune(
return;
}
- // Get the expired requests to be removed from the queue.
- std::vector<int64_t> expired_request_ids;
- GetExpiredRequestIds(std::move(requests), &expired_request_ids);
+ PopulateExpiredRequestIdsAndReasons(std::move(requests));
- // Continue processing by handling expired requests, if any.
- if (expired_request_ids.size() == 0) {
+ // If there are no expired requests processing is done.
+ if (expired_request_ids_and_reasons_.size() == 0) {
TaskComplete();
return;
}
- // TODO(petewil): Add UMA saying why we remove them. Round trip the reason
- // for deleting through the RQ callbacks. crbug.com/705115.
+ std::vector<int64_t> expired_request_ids;
+ for (auto const& id_reason_pair : expired_request_ids_and_reasons_)
+ expired_request_ids.push_back(id_reason_pair.first);
+
store_->RemoveRequests(expired_request_ids,
base::Bind(&CleanupTask::OnRequestsExpired,
weak_ptr_factory_.GetWeakPtr()));
@@ -65,9 +83,17 @@ void CleanupTask::Prune(
void CleanupTask::OnRequestsExpired(
std::unique_ptr<UpdateRequestsResult> result) {
- RequestNotifier::BackgroundSavePageResult save_page_result(
- RequestNotifier::BackgroundSavePageResult::EXPIRED);
for (const auto& request : result->updated_items) {
+ // Ensure we have an expiration reason for this request.
+ auto iter = expired_request_ids_and_reasons_.find(request.request_id());
+ if (iter == expired_request_ids_and_reasons_.end()) {
+ NOTREACHED() << "Expired request not found in deleted results.";
+ continue;
+ }
+
+ // Establish save page result based on the expiration reason.
+ RequestNotifier::BackgroundSavePageResult save_page_result(
+ ToBackgroundSavePageResult(iter->second));
event_logger_->RecordDroppedSavePageRequest(
request.client_id().name_space, save_page_result, request.request_id());
notifier_->NotifyCompleted(request, save_page_result);
@@ -77,9 +103,8 @@ void CleanupTask::OnRequestsExpired(
TaskComplete();
}
-void CleanupTask::GetExpiredRequestIds(
- std::vector<std::unique_ptr<SavePageRequest>> requests,
- std::vector<int64_t>* expired_request_ids) {
+void CleanupTask::PopulateExpiredRequestIdsAndReasons(
+ std::vector<std::unique_ptr<SavePageRequest>> requests) {
for (auto& request : requests) {
// Check for requests past their expiration time or with too many tries. If
// it is not still valid, push the request and the reason onto the deletion
@@ -94,9 +119,7 @@ void CleanupTask::GetExpiredRequestIds(
// we call cleanup, and we shouldn't delete the request while offlining it.
if (status != OfflinerPolicyUtils::RequestExpirationStatus::VALID &&
request->request_state() != SavePageRequest::RequestState::OFFLINING) {
- // TODO(petewil): Push both request and reason, will need to change type
- // of list to pairs.
- expired_request_ids->push_back(request->request_id());
+ expired_request_ids_and_reasons_.emplace(request->request_id(), status);
}
}
}
diff --git a/chromium/components/offline_pages/core/background/cleanup_task.h b/chromium/components/offline_pages/core/background/cleanup_task.h
index fbe8e0c4e5b..2201982b5a3 100644
--- a/chromium/components/offline_pages/core/background/cleanup_task.h
+++ b/chromium/components/offline_pages/core/background/cleanup_task.h
@@ -5,10 +5,12 @@
#ifndef COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_CLEANUP_TASK_H_
#define COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_CLEANUP_TASK_H_
+#include <map>
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
+#include "components/offline_pages/core/background/offliner_policy_utils.h"
#include "components/offline_pages/core/background/request_queue_results.h"
#include "components/offline_pages/core/background/save_page_request.h"
#include "components/offline_pages/core/task.h"
@@ -43,15 +45,19 @@ class CleanupTask : public Task {
void OnRequestsExpired(std::unique_ptr<UpdateRequestsResult> result);
// Build a list of IDs whose request has expired.
- void GetExpiredRequestIds(
- std::vector<std::unique_ptr<SavePageRequest>> requests,
- std::vector<int64_t>* expired_request_ids);
+ void PopulateExpiredRequestIdsAndReasons(
+ std::vector<std::unique_ptr<SavePageRequest>> requests);
// Member variables, all pointers are not owned here.
RequestQueueStore* store_;
OfflinerPolicy* policy_;
RequestNotifier* notifier_;
RequestCoordinatorEventLogger* event_logger_;
+
+ // Holds a map of expired request IDs and respective expiration reasons.
+ std::map<int64_t, OfflinerPolicyUtils::RequestExpirationStatus>
+ expired_request_ids_and_reasons_;
+
// Allows us to pass a weak pointer to callbacks.
base::WeakPtrFactory<CleanupTask> weak_ptr_factory_;
};
diff --git a/chromium/components/offline_pages/core/background/load_termination_listener.h b/chromium/components/offline_pages/core/background/load_termination_listener.h
new file mode 100644
index 00000000000..09b61cadc4f
--- /dev/null
+++ b/chromium/components/offline_pages/core/background/load_termination_listener.h
@@ -0,0 +1,33 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_BACKGROUND_LOAD_TERMINATION_LISTENER_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_LOAD_TERMINATION_LISTENER_H_
+
+#include "components/offline_pages/core/background/offliner.h"
+
+namespace offline_pages {
+
+// The OS-specific instance of this class is created and passed to
+// BackgroundLoaderOffliner which takes lifetime ownership of it.
+// When listener receives signals requiring immediate termination of loading,
+// it should call Offliner::TerminateLoadIfInProgress().
+class LoadTerminationListener {
+ public:
+ LoadTerminationListener() = default;
+ virtual ~LoadTerminationListener() = default;
+
+ // Called by Offliner when it takes ownership of this listener. Used to
+ // cache pointer back to offliner to terminate the load.
+ void set_offliner(Offliner* offliner) { offliner_ = offliner; }
+
+ protected:
+ // Raw pointer because this class is owned by Offliner.
+ Offliner* offliner_ = nullptr;
+ DISALLOW_COPY_AND_ASSIGN(LoadTerminationListener);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_LOAD_TERMINATION_LISTENER_H_ \ No newline at end of file
diff --git a/chromium/components/offline_pages/core/background/network_quality_provider_stub.cc b/chromium/components/offline_pages/core/background/network_quality_provider_stub.cc
index f4243af9ade..9c5cf28f00f 100644
--- a/chromium/components/offline_pages/core/background/network_quality_provider_stub.cc
+++ b/chromium/components/offline_pages/core/background/network_quality_provider_stub.cc
@@ -24,10 +24,10 @@ NetworkQualityProviderStub* NetworkQualityProviderStub::GetUserData(
// static
void NetworkQualityProviderStub::SetUserData(
base::SupportsUserData* supports_user_data,
- NetworkQualityProviderStub* stub) {
+ std::unique_ptr<NetworkQualityProviderStub> stub) {
DCHECK(supports_user_data);
DCHECK(stub);
- supports_user_data->SetUserData(&kOfflineNQPKey, stub);
+ supports_user_data->SetUserData(&kOfflineNQPKey, std::move(stub));
}
void NetworkQualityProviderStub::AddEffectiveConnectionTypeObserver(
diff --git a/chromium/components/offline_pages/core/background/network_quality_provider_stub.h b/chromium/components/offline_pages/core/background/network_quality_provider_stub.h
index 525e1141f39..54923f02392 100644
--- a/chromium/components/offline_pages/core/background/network_quality_provider_stub.h
+++ b/chromium/components/offline_pages/core/background/network_quality_provider_stub.h
@@ -23,7 +23,7 @@ class NetworkQualityProviderStub
static NetworkQualityProviderStub* GetUserData(
base::SupportsUserData* supports_user_data);
static void SetUserData(base::SupportsUserData* supports_user_data,
- NetworkQualityProviderStub* stub);
+ std::unique_ptr<NetworkQualityProviderStub> stub);
net::EffectiveConnectionType GetEffectiveConnectionType() const override;
diff --git a/chromium/components/offline_pages/core/background/offliner.h b/chromium/components/offline_pages/core/background/offliner.h
index 2f151289977..20a953f5ae1 100644
--- a/chromium/components/offline_pages/core/background/offliner.h
+++ b/chromium/components/offline_pages/core/background/offliner.h
@@ -55,6 +55,17 @@ class Offliner {
QUEUE_UPDATE_FAILED = 13,
// Scheduler canceled processing of requests.
BACKGROUND_SCHEDULER_CANCELED = 14,
+ // We saved a snapshot on the last retry, after timeout.
+ SAVED_ON_LAST_RETRY = 15,
+ // Indicates that attempt failed due to browser being killed.
+ // There are 3 ways that might happen:
+ // * System was running out of memory, while browser was running in the
+ // background.
+ // * User swiped away the browser as it was offlining content.
+ // * Offliner crashed.
+ // We detect the situation in ReconcileTask after starting
+ // RequestCoordinator.
+ BROWSER_KILLED = 16,
// NOTE: insert new values above this line and update histogram enum too.
STATUS_COUNT
};
@@ -63,12 +74,11 @@ class Offliner {
typedef base::Callback<void(const SavePageRequest&, int64_t received_bytes)>
ProgressCallback;
// Reports the completion status of a request.
- // TODO(dougarnett): consider passing back a request id instead of request.
typedef base::Callback<void(const SavePageRequest&, RequestStatus)>
CompletionCallback;
// Reports that the cancel operation has completed.
// TODO(chili): make save operation cancellable.
- typedef base::Callback<void(int64_t request_id)> CancelCallback;
+ typedef base::Callback<void(const SavePageRequest&)> CancelCallback;
Offliner() {}
virtual ~Offliner() {}
@@ -83,12 +93,19 @@ class Offliner {
const ProgressCallback& progress_callback) = 0;
// Clears the currently processing request, if any, and skips running its
- // CompletionCallback.
- virtual void Cancel(const CancelCallback& callback) = 0;
+ // CompletionCallback. Returns false if there is nothing to cancel, otherwise
+ // returns true and canceled request will be delivered using callback.
+ virtual bool Cancel(const CancelCallback& callback) = 0;
+
+ // On some external condition changes (RAM pressure, browser backgrounded on
+ // low-level devices, etc) it is needed to terminate a load if there is one
+ // in progress. It is no-op if there is no active request loading.
+ virtual void TerminateLoadIfInProgress() = 0;
// Handles timeout scenario. Returns true if lowbar is met and try to do a
- // snapshot of the current webcontents.
- virtual bool HandleTimeout(const SavePageRequest& request) = 0;
+ // snapshot of the current webcontents. If that is the case, the result of
+ // offlining will be provided by |completion_callback|.
+ virtual bool HandleTimeout(int64_t request_id) = 0;
// TODO(dougarnett): add policy support methods.
};
diff --git a/chromium/components/offline_pages/core/background/offliner_stub.cc b/chromium/components/offline_pages/core/background/offliner_stub.cc
index 04fe6eae134..92518428923 100644
--- a/chromium/components/offline_pages/core/background/offliner_stub.cc
+++ b/chromium/components/offline_pages/core/background/offliner_stub.cc
@@ -24,31 +24,45 @@ bool OfflinerStub::LoadAndSave(const SavePageRequest& request,
if (disable_loading_)
return false;
+ pending_request_.reset(new SavePageRequest(request));
completion_callback_ = completion_callback;
- progress_callback_ = progress_callback;
// Post the callback on the run loop.
if (enable_callback_) {
const int64_t arbitrary_size = 153LL;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(progress_callback_, request, arbitrary_size));
+ FROM_HERE, base::Bind(progress_callback, request, arbitrary_size));
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(completion_callback_, request,
+ FROM_HERE, base::Bind(completion_callback, *pending_request_.get(),
Offliner::RequestStatus::SAVED));
}
return true;
}
-void OfflinerStub::Cancel(const CancelCallback& callback) {
+bool OfflinerStub::Cancel(const CancelCallback& callback) {
cancel_called_ = true;
- callback.Run(0LL);
+ if (!pending_request_)
+ return false;
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, *pending_request_.get()));
+ pending_request_.reset();
+ return true;
+}
+
+void OfflinerStub::TerminateLoadIfInProgress() {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(completion_callback_, *pending_request_.get(),
+ Offliner::RequestStatus::FOREGROUND_CANCELED));
+ pending_request_.reset();
}
-bool OfflinerStub::HandleTimeout(const SavePageRequest& request) {
+bool OfflinerStub::HandleTimeout(int64_t request_id) {
if (snapshot_on_last_retry_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(completion_callback_, request,
+ FROM_HERE, base::Bind(completion_callback_, *pending_request_.get(),
Offliner::RequestStatus::SAVED));
+ pending_request_.reset();
return true;
}
return false;
diff --git a/chromium/components/offline_pages/core/background/offliner_stub.h b/chromium/components/offline_pages/core/background/offliner_stub.h
index 2d7f72a27df..a4485990b82 100644
--- a/chromium/components/offline_pages/core/background/offliner_stub.h
+++ b/chromium/components/offline_pages/core/background/offliner_stub.h
@@ -5,6 +5,9 @@
#ifndef COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_OFFLINER_STUB_H_
#define COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_OFFLINER_STUB_H_
+#include <memory>
+
+#include "base/callback_forward.h"
#include "components/offline_pages/core/background/offliner.h"
namespace offline_pages {
@@ -20,7 +23,11 @@ class OfflinerStub : public Offliner {
const CompletionCallback& completion_callback,
const ProgressCallback& progress_callback) override;
- void Cancel(const CancelCallback& callback) override;
+ bool Cancel(const CancelCallback& callback) override;
+
+ void TerminateLoadIfInProgress() override;
+
+ bool HandleTimeout(int64_t request_id) override;
void disable_loading() { disable_loading_ = true; }
@@ -30,13 +37,11 @@ class OfflinerStub : public Offliner {
void reset_cancel_called() { cancel_called_ = false; }
- bool HandleTimeout(const SavePageRequest& request) override;
-
void enable_snapshot_on_last_retry() { snapshot_on_last_retry_ = true; }
private:
CompletionCallback completion_callback_;
- ProgressCallback progress_callback_;
+ std::unique_ptr<SavePageRequest> pending_request_;
bool disable_loading_;
bool enable_callback_;
bool cancel_called_;
diff --git a/chromium/components/offline_pages/core/background/remove_requests_task.cc b/chromium/components/offline_pages/core/background/remove_requests_task.cc
index f958e670814..a18d31aeed5 100644
--- a/chromium/components/offline_pages/core/background/remove_requests_task.cc
+++ b/chromium/components/offline_pages/core/background/remove_requests_task.cc
@@ -35,9 +35,8 @@ void RemoveRequestsTask::RemoveRequests() {
}
void RemoveRequestsTask::CompleteEarly(ItemActionStatus status) {
- // TODO(fgorski): store_->state() once implemented
std::unique_ptr<UpdateRequestsResult> result(
- new UpdateRequestsResult(StoreState::LOADED));
+ new UpdateRequestsResult(store_->state()));
for (int64_t request_id : request_ids_)
result->item_statuses.push_back(std::make_pair(request_id, status));
CompleteWithResult(std::move(result));
diff --git a/chromium/components/offline_pages/core/background/remove_requests_task.h b/chromium/components/offline_pages/core/background/remove_requests_task.h
index 6372d3d1822..19b55438660 100644
--- a/chromium/components/offline_pages/core/background/remove_requests_task.h
+++ b/chromium/components/offline_pages/core/background/remove_requests_task.h
@@ -38,7 +38,6 @@ class RemoveRequestsTask : public Task {
// Store that this task updates.
RequestQueueStore* store_;
// Request IDs to be updated.
- // TODO(fgorski): perhaps convert to unique_ptr to a vector.
std::vector<int64_t> request_ids_;
// Callback to complete the task.
RequestQueueStore::UpdateCallback callback_;
diff --git a/chromium/components/offline_pages/core/background/request_coordinator.cc b/chromium/components/offline_pages/core/background/request_coordinator.cc
index 167ffa78c7f..7e0882deb46 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator.cc
+++ b/chromium/components/offline_pages/core/background/request_coordinator.cc
@@ -61,7 +61,8 @@ void RecordOfflinerResultUMA(const ClientId& client_id,
histogram->Add(static_cast<int>(request_status));
// For successful requests also record time from request to save.
- if (request_status == Offliner::RequestStatus::SAVED) {
+ if (request_status == Offliner::RequestStatus::SAVED ||
+ request_status == Offliner::RequestStatus::SAVED_ON_LAST_RETRY) {
// Using regular histogram (with dynamic suffix) rather than time-oriented
// one to record samples in seconds rather than milliseconds.
base::HistogramBase* histogram = base::Histogram::FactoryGet(
@@ -157,6 +158,23 @@ void RecordSavePageLaterNetworkQuality(
histogram->Add(effective_connection);
}
+// Record the network quality at request creation time per namespace.
+void RecordNetworkQualityAtRequestStartForFailedRequest(
+ const ClientId& client_id,
+ const net::EffectiveConnectionType effective_connection) {
+ // The histogram below is an expansion of the UMA_HISTOGRAM_ENUMERATION
+ // macro adapted to allow for a dynamically suffixed histogram name.
+ // Note: The factory creates and owns the histogram.
+ base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
+ AddHistogramSuffix(
+ client_id,
+ "OfflinePages.Background.EffectiveConnectionType.OffliningStartType"),
+ 1, net::EFFECTIVE_CONNECTION_TYPE_LAST - 1,
+ net::EFFECTIVE_CONNECTION_TYPE_LAST,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+ histogram->Add(effective_connection);
+}
+
// This should use the same algorithm as we use for OfflinePageItem, so the IDs
// are similar.
int64_t GenerateOfflineId() {
@@ -206,7 +224,8 @@ RequestCoordinator::RequestCoordinator(
scheduler_(std::move(scheduler)),
policy_controller_(new ClientPolicyController()),
network_quality_estimator_(network_quality_estimator),
- active_request_(nullptr),
+ network_quality_at_request_start_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
+ active_request_id_(0),
last_offlining_status_(Offliner::RequestStatus::UNKNOWN),
scheduler_callback_(base::Bind(&EmptySchedulerCallback)),
internal_start_processing_callback_(base::Bind(&EmptySchedulerCallback)),
@@ -283,21 +302,19 @@ void RequestCoordinator::GetQueuedRequestsCallback(
callback.Run(std::move(requests));
}
-void RequestCoordinator::StopPrerendering(
- const Offliner::CancelCallback& final_callback,
- Offliner::RequestStatus stop_status) {
+void RequestCoordinator::StopOfflining(const CancelCallback& final_callback,
+ Offliner::RequestStatus stop_status) {
if (offliner_ && state_ == RequestCoordinatorState::OFFLINING) {
- DCHECK(active_request_.get());
- offliner_->Cancel(base::Bind(
- &RequestCoordinator::HandleCancelUpdateStatusCallback,
- weak_ptr_factory_.GetWeakPtr(), final_callback, stop_status));
- return;
+ DCHECK_NE(active_request_id_, 0);
+ if (offliner_->Cancel(base::Bind(
+ &RequestCoordinator::HandleCancelUpdateStatusCallback,
+ weak_ptr_factory_.GetWeakPtr(), final_callback, stop_status))) {
+ return;
+ }
}
UpdateStatusForCancel(stop_status);
- int64_t request_id =
- active_request_.get() ? active_request_->request_id() : 0LL;
- final_callback.Run(request_id);
+ final_callback.Run(active_request_id_);
}
void RequestCoordinator::GetRequestsForSchedulingCallback(
@@ -323,15 +340,13 @@ void RequestCoordinator::GetRequestsForSchedulingCallback(
bool RequestCoordinator::CancelActiveRequestIfItMatches(
const std::vector<int64_t>& request_ids) {
// If we have a request in progress and need to cancel it, call the
- // pre-renderer to cancel. TODO Make sure we remove any page created by the
- // prerenderer if it doesn't get the cancel in time.
- if (active_request_ != nullptr) {
- if (request_ids.end() != std::find(request_ids.begin(), request_ids.end(),
- active_request_->request_id())) {
- StopPrerendering(
- base::Bind(&RequestCoordinator::ResetActiveRequestCallback,
- weak_ptr_factory_.GetWeakPtr()),
- Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED);
+ // offliner to cancel.
+ if (active_request_id_ != 0) {
+ if (request_ids.end() !=
+ std::find(request_ids.begin(), request_ids.end(), active_request_id_)) {
+ StopOfflining(base::Bind(&RequestCoordinator::ResetActiveRequestCallback,
+ weak_ptr_factory_.GetWeakPtr()),
+ Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED);
return true;
}
}
@@ -397,9 +412,9 @@ void RequestCoordinator::RemoveRequests(
request_ids,
base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback,
weak_ptr_factory_.GetWeakPtr(), callback,
- RequestNotifier::BackgroundSavePageResult::REMOVED));
+ RequestNotifier::BackgroundSavePageResult::USER_CANCELED));
- // Record the network quality when this request is made.
+ // Record the network quality when this request is removed.
if (network_quality_estimator_) {
UMA_HISTOGRAM_ENUMERATION(
"OfflinePages.Background.EffectiveConnectionType.RemoveRequests",
@@ -428,7 +443,7 @@ void RequestCoordinator::PauseRequests(
base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
weak_ptr_factory_.GetWeakPtr()));
- // Record the network quality when this request is made.
+ // Record the network quality when this request is paused.
if (network_quality_estimator_) {
UMA_HISTOGRAM_ENUMERATION(
"OfflinePages.Background.EffectiveConnectionType.PauseRequests",
@@ -449,7 +464,7 @@ void RequestCoordinator::ResumeRequests(
base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback,
weak_ptr_factory_.GetWeakPtr()));
- // Record the network quality when this request is made.
+ // Record the network quality when this request is resumed.
if (network_quality_estimator_) {
UMA_HISTOGRAM_ENUMERATION(
"OfflinePages.Background.EffectiveConnectionType.ResumeRequests",
@@ -501,8 +516,10 @@ void RequestCoordinator::UpdateMultipleRequestsCallback(
void RequestCoordinator::ReconcileCallback(
std::unique_ptr<UpdateRequestsResult> result) {
- for (const auto& request : result->updated_items)
+ for (const auto& request : result->updated_items) {
+ RecordOfflinerResult(request, Offliner::RequestStatus::BROWSER_KILLED);
NotifyChanged(request);
+ }
}
void RequestCoordinator::HandleRemovedRequestsAndCallback(
@@ -525,42 +542,33 @@ void RequestCoordinator::HandleRemovedRequests(
}
void RequestCoordinator::HandleCancelUpdateStatusCallback(
- const Offliner::CancelCallback& final_callback,
+ const CancelCallback& final_callback,
Offliner::RequestStatus stop_status,
- int64_t offline_id) {
+ const SavePageRequest& canceled_request) {
if (stop_status == Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT ||
stop_status == Offliner::RequestStatus::BACKGROUND_SCHEDULER_CANCELED) {
// Consider watchdog timeout a completed attempt.
- SavePageRequest request(*active_request_.get());
- UpdateRequestForCompletedAttempt(request, stop_status);
+ UpdateRequestForCompletedAttempt(canceled_request, stop_status);
} else {
// Otherwise consider this stop an aborted attempt.
- UpdateRequestForAbortedAttempt(*active_request_.get());
+ UpdateRequestForAbortedAttempt(canceled_request);
}
+ RecordOfflinerResult(canceled_request, stop_status);
UpdateStatusForCancel(stop_status);
- final_callback.Run(offline_id);
+ final_callback.Run(canceled_request.request_id());
}
void RequestCoordinator::UpdateStatusForCancel(
Offliner::RequestStatus stop_status) {
// Stopping offliner means it will not call callback so set last status.
last_offlining_status_ = stop_status;
-
- if (active_request_) {
- event_logger_.RecordOfflinerResult(active_request_->client_id().name_space,
- last_offlining_status_,
- active_request_->request_id());
- RecordOfflinerResultUMA(active_request_->client_id(),
- active_request_->creation_time(),
- last_offlining_status_);
- active_request_.reset();
- }
+ active_request_id_ = 0;
state_ = RequestCoordinatorState::IDLE;
}
void RequestCoordinator::ResetActiveRequestCallback(int64_t offline_id) {
- active_request_.reset();
+ active_request_id_ = 0;
}
void RequestCoordinator::StartSchedulerCallback(int64_t offline_id) {
@@ -580,19 +588,19 @@ void RequestCoordinator::ScheduleAsNeeded() {
void RequestCoordinator::StopProcessing(Offliner::RequestStatus stop_status) {
processing_state_ = ProcessingWindowState::STOPPED;
- StopPrerendering(base::Bind(&RequestCoordinator::StartSchedulerCallback,
- weak_ptr_factory_.GetWeakPtr()),
- stop_status);
+ StopOfflining(base::Bind(&RequestCoordinator::StartSchedulerCallback,
+ weak_ptr_factory_.GetWeakPtr()),
+ stop_status);
}
void RequestCoordinator::HandleWatchdogTimeout() {
Offliner::RequestStatus watchdog_status =
Offliner::REQUEST_COORDINATOR_TIMED_OUT;
- if (offliner_->HandleTimeout(*active_request_.get()))
+ if (offliner_->HandleTimeout(active_request_id_))
return;
- StopPrerendering(base::Bind(&RequestCoordinator::TryNextRequestCallback,
- weak_ptr_factory_.GetWeakPtr()),
- watchdog_status);
+ StopOfflining(base::Bind(&RequestCoordinator::TryNextRequestCallback,
+ weak_ptr_factory_.GetWeakPtr()),
+ watchdog_status);
}
// Returns true if the caller should expect a callback, false otherwise. For
@@ -885,10 +893,9 @@ void RequestCoordinator::StartOffliner(
return;
}
- // TODO(fgorski): Switch to request_id only, so that this value is not written
- // back to the store.
- active_request_.reset(
- new SavePageRequest(update_result->updated_items.at(0)));
+ active_request_id_ = request_id;
+ network_quality_at_request_start_ =
+ network_quality_estimator_->GetEffectiveConnectionType();
// Start the load and save process in the offliner (Async).
if (offliner_->LoadAndSave(
@@ -908,9 +915,9 @@ void RequestCoordinator::StartOffliner(
}
// Inform observer of active request.
- NotifyChanged(*active_request_.get());
+ NotifyChanged(update_result->updated_items.at(0));
- // Start a watchdog timer to catch pre-renders running too long
+ // Start a watchdog timer to catch offliners running too long
watchdog_timer_.Start(FROM_HERE, timeout, this,
&RequestCoordinator::HandleWatchdogTimeout);
} else {
@@ -931,14 +938,11 @@ void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request,
<< ", status: " << static_cast<int>(status) << ", " << __func__;
DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN);
DCHECK_NE(status, Offliner::RequestStatus::LOADED);
- event_logger_.RecordOfflinerResult(request.client_id().name_space, status,
- request.request_id());
+ RecordOfflinerResult(request, status);
last_offlining_status_ = status;
- RecordOfflinerResultUMA(request.client_id(), request.creation_time(),
- last_offlining_status_);
watchdog_timer_.Stop();
state_ = RequestCoordinatorState::IDLE;
- active_request_.reset(nullptr);
+ active_request_id_ = 0;
UpdateRequestForCompletedAttempt(request, status);
if (ShouldTryNextRequest(status))
@@ -958,13 +962,22 @@ void RequestCoordinator::OfflinerProgressCallback(
void RequestCoordinator::UpdateRequestForCompletedAttempt(
const SavePageRequest& request,
Offliner::RequestStatus status) {
+ // If the request failed, report the connection type as of the start of the
+ // request.
+ if (status != Offliner::RequestStatus::SAVED &&
+ status != Offliner::RequestStatus::SAVED_ON_LAST_RETRY) {
+ RecordNetworkQualityAtRequestStartForFailedRequest(
+ request.client_id(), network_quality_at_request_start_);
+ }
+
if (status == Offliner::RequestStatus::FOREGROUND_CANCELED ||
status == Offliner::RequestStatus::LOADING_CANCELED) {
// Update the request for the canceled attempt.
// TODO(dougarnett): See if we can conclusively identify other attempt
// aborted cases to treat this way (eg, for Render Process Killed).
UpdateRequestForAbortedAttempt(request);
- } else if (status == Offliner::RequestStatus::SAVED) {
+ } else if (status == Offliner::RequestStatus::SAVED ||
+ status == Offliner::RequestStatus::SAVED_ON_LAST_RETRY) {
// Remove the request from the queue if it succeeded.
RemoveAttemptedRequest(request,
RequestNotifier::BackgroundSavePageResult::SUCCESS);
@@ -999,7 +1012,6 @@ bool RequestCoordinator::ShouldTryNextRequest(
case Offliner::RequestStatus::SAVED:
case Offliner::RequestStatus::SAVE_FAILED:
case Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED:
- case Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT:
case Offliner::RequestStatus::LOADING_FAILED:
case Offliner::RequestStatus::LOADING_FAILED_NO_RETRY:
return true;
@@ -1008,6 +1020,10 @@ bool RequestCoordinator::ShouldTryNextRequest(
case Offliner::RequestStatus::LOADING_FAILED_NO_NEXT:
// No further processing in this service window.
return false;
+ case Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT:
+ case Offliner::RequestStatus::SAVED_ON_LAST_RETRY:
+ // If we timed out, check to see that there is time budget.
+ return processing_state_ == ProcessingWindowState::IMMEDIATE_WINDOW;
default:
// Make explicit choice about new status codes that actually reach here.
// Their default is no further processing in this service window.
@@ -1098,6 +1114,13 @@ ClientPolicyController* RequestCoordinator::GetPolicyController() {
return policy_controller_.get();
}
+void RequestCoordinator::RecordOfflinerResult(const SavePageRequest& request,
+ Offliner::RequestStatus status) {
+ event_logger_.RecordOfflinerResult(request.client_id().name_space, status,
+ request.request_id());
+ RecordOfflinerResultUMA(request.client_id(), request.creation_time(), status);
+}
+
void RequestCoordinator::Shutdown() {
network_quality_estimator_ = nullptr;
}
diff --git a/chromium/components/offline_pages/core/background/request_coordinator.h b/chromium/components/offline_pages/core/background/request_coordinator.h
index 412808c9da6..05a1bace1c5 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator.h
+++ b/chromium/components/offline_pages/core/background/request_coordinator.h
@@ -98,6 +98,9 @@ class RequestCoordinator : public KeyedService,
typedef base::Callback<void(std::vector<std::unique_ptr<SavePageRequest>>)>
GetRequestsCallback;
+ // Callback for stopping the background offlining.
+ typedef base::Callback<void(int64_t request_id)> CancelCallback;
+
RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy,
std::unique_ptr<Offliner> offliner,
std::unique_ptr<RequestQueue> queue,
@@ -112,7 +115,7 @@ class RequestCoordinator : public KeyedService,
int64_t SavePageLater(const SavePageLaterParams& save_page_later_params);
// Remove a list of requests by |request_id|. This removes requests from the
- // request queue, and cancels an in-progress prerender.
+ // request queue, and cancels an in-progress offliner.
void RemoveRequests(const std::vector<int64_t>& request_ids,
const RemoveRequestsCallback& callback);
@@ -284,9 +287,9 @@ class RequestCoordinator : public KeyedService,
// Handle updating of request status after cancel is called. Will call
// HandleCancelRecordResultCallback for UMA handling
void HandleCancelUpdateStatusCallback(
- const Offliner::CancelCallback& next_callback,
+ const CancelCallback& next_callback,
Offliner::RequestStatus stop_status,
- int64_t offline_id);
+ const SavePageRequest& canceled_request);
void UpdateStatusForCancel(Offliner::RequestStatus stop_status);
void ResetActiveRequestCallback(int64_t offline_id);
void StartSchedulerCallback(int64_t offline_id);
@@ -335,9 +338,9 @@ class RequestCoordinator : public KeyedService,
void HandleWatchdogTimeout();
- // Cancels an in progress pre-rendering, and updates state appropriately.
- void StopPrerendering(const Offliner::CancelCallback& callback,
- Offliner::RequestStatus stop_status);
+ // Cancels an in progress offlining, and updates state appropriately.
+ void StopOfflining(const CancelCallback& callback,
+ Offliner::RequestStatus stop_status);
// Marks attempt on the request and sends it to offliner in continuation.
void SendRequestToOffliner(const SavePageRequest& request);
@@ -396,6 +399,10 @@ class RequestCoordinator : public KeyedService,
const std::string& name_space,
std::unique_ptr<UpdateRequestsResult> result);
+ // Reports offliner status through UMA and event logger.
+ void RecordOfflinerResult(const SavePageRequest& request,
+ Offliner::RequestStatus status);
+
void SetDeviceConditionsForTest(const DeviceConditions& current_conditions) {
use_test_device_conditions_ = true;
current_conditions_.reset(new DeviceConditions(current_conditions));
@@ -436,8 +443,9 @@ class RequestCoordinator : public KeyedService,
// Unowned pointer to the Network Quality Estimator.
net::NetworkQualityEstimator::NetworkQualityProvider*
network_quality_estimator_;
- // Holds copy of the active request, if any.
- std::unique_ptr<SavePageRequest> active_request_;
+ net::EffectiveConnectionType network_quality_at_request_start_;
+ // Holds an ID of the currently active request.
+ int64_t active_request_id_;
// Status of the most recent offlining.
Offliner::RequestStatus last_offlining_status_;
// A set of request_ids that we are holding off until the download manager is
diff --git a/chromium/components/offline_pages/core/background/request_coordinator_event_logger.cc b/chromium/components/offline_pages/core/background/request_coordinator_event_logger.cc
index 0820146f0ac..d044c691e8f 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator_event_logger.cc
+++ b/chromium/components/offline_pages/core/background/request_coordinator_event_logger.cc
@@ -41,6 +41,8 @@ static std::string OfflinerRequestStatusToString(
return "QUEUE_UPDATE_FAILED";
case Offliner::BACKGROUND_SCHEDULER_CANCELED:
return "BACKGROUND_SCHEDULER_CANCELED";
+ case Offliner::SAVED_ON_LAST_RETRY:
+ return "SAVED_ON_LAST_RETRY";
default:
NOTREACHED();
return std::to_string(static_cast<int>(request_status));
@@ -66,7 +68,7 @@ static std::string BackgroundSavePageResultToString(
return "RETRY_COUNT_EXCEEDED";
case RequestNotifier::BackgroundSavePageResult::START_COUNT_EXCEEDED:
return "START_COUNT_EXCEEDED";
- case RequestNotifier::BackgroundSavePageResult::REMOVED:
+ case RequestNotifier::BackgroundSavePageResult::USER_CANCELED:
return "REMOVED";
default:
NOTREACHED();
@@ -94,8 +96,9 @@ void RequestCoordinatorEventLogger::RecordOfflinerResult(
const std::string& name_space,
Offliner::RequestStatus new_status,
int64_t request_id) {
+ std::string request_id_str = std::to_string(request_id);
RecordActivity("Background save attempt for " + name_space + ":" +
- std::to_string(request_id) + " - " +
+ request_id_str + " - " +
OfflinerRequestStatusToString(new_status));
}
@@ -103,8 +106,9 @@ void RequestCoordinatorEventLogger::RecordDroppedSavePageRequest(
const std::string& name_space,
RequestNotifier::BackgroundSavePageResult result,
int64_t request_id) {
+ std::string request_id_str = std::to_string(request_id);
RecordActivity("Background save request removed " + name_space + ":" +
- std::to_string(request_id) + " - " +
+ request_id_str + " - " +
BackgroundSavePageResultToString(result));
}
diff --git a/chromium/components/offline_pages/core/background/request_coordinator_unittest.cc b/chromium/components/offline_pages/core/background/request_coordinator_unittest.cc
index b45cf5547f3..9291c1841dd 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator_unittest.cc
+++ b/chromium/components/offline_pages/core/background/request_coordinator_unittest.cc
@@ -784,6 +784,12 @@ TEST_F(RequestCoordinatorTest, OfflinerDoneRequestFailedNoRetryFailure) {
EXPECT_TRUE(observer().completed_called());
EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::LOADING_FAILURE,
observer().last_status());
+ // We should have a histogram entry for the effective network conditions
+ // when this failed request began.
+ histograms().ExpectBucketCount(
+ "OfflinePages.Background.EffectiveConnectionType.OffliningStartType."
+ "bookmark",
+ net::NetworkChangeNotifier::CONNECTION_UNKNOWN, 1);
}
TEST_F(RequestCoordinatorTest, OfflinerDoneRequestFailedNoNextFailure) {
@@ -842,7 +848,7 @@ TEST_F(RequestCoordinatorTest, OfflinerDoneForegroundCancel) {
EXPECT_EQ(0L, last_requests().at(0)->completed_attempt_count());
}
-TEST_F(RequestCoordinatorTest, OfflinerDonePrerenderingCancel) {
+TEST_F(RequestCoordinatorTest, OfflinerDoneOffliningCancel) {
// Add a request to the queue, wait for callbacks to finish.
offline_pages::SavePageRequest request(kRequestId1, kUrl1, kClientId1,
base::Time::Now(), kUserRequested);
@@ -861,7 +867,7 @@ TEST_F(RequestCoordinatorTest, OfflinerDonePrerenderingCancel) {
// Request still in the queue.
EXPECT_EQ(1UL, last_requests().size());
- // Verify prerendering cancel not counted as an attempt after all.
+ // Verify offlining cancel not counted as an attempt after all.
const std::unique_ptr<SavePageRequest>& found_request =
last_requests().front();
EXPECT_EQ(0L, found_request->completed_attempt_count());
@@ -1099,7 +1105,7 @@ TEST_F(RequestCoordinatorTest, MarkRequestCompleted) {
coordinator()->MarkRequestCompleted(request_id);
PumpLoop();
- // Our observer should have seen SUCCESS instead of REMOVED.
+ // Our observer should have seen SUCCESS instead of USER_CANCELED.
EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::SUCCESS,
observer().last_status());
EXPECT_TRUE(observer().completed_called());
@@ -1301,13 +1307,7 @@ TEST_F(RequestCoordinatorTest, GetAllRequests) {
EXPECT_EQ(kRequestId2, last_requests().at(1)->request_id());
}
-#if defined(OS_IOS)
-// Flaky on IOS. http://crbug/663311
-#define MAYBE_PauseAndResumeObserver DISABLED_PauseAndResumeObserver
-#else
-#define MAYBE_PauseAndResumeObserver PauseAndResumeObserver
-#endif
-TEST_F(RequestCoordinatorTest, MAYBE_PauseAndResumeObserver) {
+TEST_F(RequestCoordinatorTest, PauseAndResumeObserver) {
// Set low-end device status to actual status.
SetIsLowEndDeviceForTest(base::SysInfo::IsLowEndDevice());
@@ -1359,7 +1359,7 @@ TEST_F(RequestCoordinatorTest, RemoveRequest) {
PumpLoop();
EXPECT_TRUE(observer().completed_called());
- EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::REMOVED,
+ EXPECT_EQ(RequestCoordinator::BackgroundSavePageResult::USER_CANCELED,
observer().last_status());
EXPECT_EQ(1UL, last_remove_results().size());
EXPECT_EQ(kRequestId1, std::get<0>(last_remove_results().at(0)));
diff --git a/chromium/components/offline_pages/core/background/request_notifier.h b/chromium/components/offline_pages/core/background/request_notifier.h
index e5723a8ef44..12534dfecec 100644
--- a/chromium/components/offline_pages/core/background/request_notifier.h
+++ b/chromium/components/offline_pages/core/background/request_notifier.h
@@ -26,7 +26,7 @@ class RequestNotifier {
EXPIRED = 5,
RETRY_COUNT_EXCEEDED = 6,
START_COUNT_EXCEEDED = 7,
- REMOVED = 8,
+ USER_CANCELED = 8,
// NOTE: insert new values above this line and update histogram enum too.
STATUS_COUNT
};
diff --git a/chromium/components/offline_pages/core/background/request_queue_store_sql.cc b/chromium/components/offline_pages/core/background/request_queue_store_sql.cc
index 16a13e49c6b..87dc3bfab1b 100644
--- a/chromium/components/offline_pages/core/background/request_queue_store_sql.cc
+++ b/chromium/components/offline_pages/core/background/request_queue_store_sql.cc
@@ -12,6 +12,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/offline_pages/core/background/save_page_request.h"
#include "sql/connection.h"
diff --git a/chromium/components/offline_pages/core/client_namespace_constants.cc b/chromium/components/offline_pages/core/client_namespace_constants.cc
index 1a1385f8e95..66a4321fb36 100644
--- a/chromium/components/offline_pages/core/client_namespace_constants.cc
+++ b/chromium/components/offline_pages/core/client_namespace_constants.cc
@@ -12,6 +12,7 @@ const char kAsyncNamespace[] = "async_loading";
const char kCCTNamespace[] = "custom_tabs";
const char kDownloadNamespace[] = "download";
const char kNTPSuggestionsNamespace[] = "ntp_suggestions";
+const char kSuggestedArticlesNamespace[] = "suggested_articles";
const char kDefaultNamespace[] = "default";
diff --git a/chromium/components/offline_pages/core/client_namespace_constants.h b/chromium/components/offline_pages/core/client_namespace_constants.h
index 7991a511792..8cd093c8401 100644
--- a/chromium/components/offline_pages/core/client_namespace_constants.h
+++ b/chromium/components/offline_pages/core/client_namespace_constants.h
@@ -17,6 +17,7 @@ extern const char kAsyncNamespace[];
extern const char kCCTNamespace[];
extern const char kDownloadNamespace[];
extern const char kNTPSuggestionsNamespace[];
+extern const char kSuggestedArticlesNamespace[];
// Currently used for fallbacks like tests.
extern const char kDefaultNamespace[];
diff --git a/chromium/components/offline_pages/core/client_policy_controller.cc b/chromium/components/offline_pages/core/client_policy_controller.cc
index c2db0518641..3000b74664d 100644
--- a/chromium/components/offline_pages/core/client_policy_controller.cc
+++ b/chromium/components/offline_pages/core/client_policy_controller.cc
@@ -38,8 +38,11 @@ ClientPolicyController::ClientPolicyController() {
.Build()));
policies_.insert(std::make_pair(
kCCTNamespace,
- MakePolicy(kCCTNamespace, LifetimeType::TEMPORARY,
- base::TimeDelta::FromDays(2), kUnlimitedPages, 1)));
+ OfflinePageClientPolicyBuilder(kCCTNamespace, LifetimeType::TEMPORARY,
+ kUnlimitedPages, 1)
+ .SetExpirePeriod(base::TimeDelta::FromDays(2))
+ .SetIsDisabledWhenPrefetchDisabled(true)
+ .Build()));
policies_.insert(std::make_pair(
kDownloadNamespace, OfflinePageClientPolicyBuilder(
kDownloadNamespace, LifetimeType::PERSISTENT,
@@ -53,6 +56,16 @@ ClientPolicyController::ClientPolicyController() {
LifetimeType::PERSISTENT, kUnlimitedPages,
kUnlimitedPages)
.SetIsSupportedByDownload(true)
+ .SetIsRemovedOnCacheReset(false)
+ .Build()));
+ policies_.insert(std::make_pair(
+ kSuggestedArticlesNamespace,
+ OfflinePageClientPolicyBuilder(kSuggestedArticlesNamespace,
+ LifetimeType::TEMPORARY, kUnlimitedPages,
+ kUnlimitedPages)
+ .SetIsRemovedOnCacheReset(true)
+ .SetIsDisabledWhenPrefetchDisabled(true)
+ .SetExpirePeriod(base::TimeDelta::FromDays(30))
.Build()));
// Fallback policy.
@@ -154,6 +167,26 @@ ClientPolicyController::GetNamespacesRestrictedToOriginalTab() const {
return *show_in_original_tab_cache_;
}
+bool ClientPolicyController::IsDisabledWhenPrefetchDisabled(
+ const std::string& name_space) const {
+ return GetPolicy(name_space).feature_policy.disabled_when_prefetch_disabled;
+}
+
+const std::vector<std::string>&
+ClientPolicyController::GetNamespacesDisabledWhenPrefetchDisabled() const {
+ if (disabled_when_prefetch_disabled_cache_)
+ return *disabled_when_prefetch_disabled_cache_;
+
+ disabled_when_prefetch_disabled_cache_ =
+ base::MakeUnique<std::vector<std::string>>();
+ for (const auto& policy_item : policies_) {
+ if (policy_item.second.feature_policy.disabled_when_prefetch_disabled)
+ disabled_when_prefetch_disabled_cache_->emplace_back(policy_item.first);
+ }
+
+ return *disabled_when_prefetch_disabled_cache_;
+}
+
void ClientPolicyController::AddPolicyForTest(
const std::string& name_space,
const OfflinePageClientPolicyBuilder& builder) {
diff --git a/chromium/components/offline_pages/core/client_policy_controller.h b/chromium/components/offline_pages/core/client_policy_controller.h
index 5e5cd21467a..25b9a31d701 100644
--- a/chromium/components/offline_pages/core/client_policy_controller.h
+++ b/chromium/components/offline_pages/core/client_policy_controller.h
@@ -56,6 +56,10 @@ class ClientPolicyController {
bool IsRestrictedToOriginalTab(const std::string& name_space) const;
const std::vector<std::string>& GetNamespacesRestrictedToOriginalTab() const;
+ bool IsDisabledWhenPrefetchDisabled(const std::string& name_space) const;
+ const std::vector<std::string>& GetNamespacesDisabledWhenPrefetchDisabled()
+ const;
+
void AddPolicyForTest(const std::string& name_space,
const OfflinePageClientPolicyBuilder& builder);
@@ -68,6 +72,8 @@ class ClientPolicyController {
mutable std::unique_ptr<std::vector<std::string>> download_namespace_cache_;
mutable std::unique_ptr<std::vector<std::string>> recent_tab_namespace_cache_;
mutable std::unique_ptr<std::vector<std::string>> show_in_original_tab_cache_;
+ mutable std::unique_ptr<std::vector<std::string>>
+ disabled_when_prefetch_disabled_cache_;
DISALLOW_COPY_AND_ASSIGN(ClientPolicyController);
};
diff --git a/chromium/components/offline_pages/core/client_policy_controller_unittest.cc b/chromium/components/offline_pages/core/client_policy_controller_unittest.cc
index e3721a8cdd3..4959013eef5 100644
--- a/chromium/components/offline_pages/core/client_policy_controller_unittest.cc
+++ b/chromium/components/offline_pages/core/client_policy_controller_unittest.cc
@@ -6,8 +6,6 @@
#include <algorithm>
-#include "base/bind.h"
-#include "base/time/time.h"
#include "components/offline_pages/core/client_namespace_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,9 +30,12 @@ class ClientPolicyControllerTest : public testing::Test {
void TearDown() override;
protected:
+ void ExpectRemovedOnCacheReset(std::string name_space, bool expectation);
void ExpectDownloadSupport(std::string name_space, bool expectation);
void ExpectRecentTab(std::string name_space, bool expectation);
void ExpectOnlyOriginalTab(std::string name_space, bool expectation);
+ void ExpectDisabledWhenPrefetchDisabled(std::string name_space,
+ bool expectation);
private:
std::unique_ptr<ClientPolicyController> controller_;
@@ -48,13 +49,28 @@ void ClientPolicyControllerTest::TearDown() {
controller_.reset();
}
+void ClientPolicyControllerTest::ExpectRemovedOnCacheReset(
+ std::string name_space,
+ bool expectation) {
+ EXPECT_EQ(expectation, controller()->IsRemovedOnCacheReset(name_space))
+ << "Namespace " << name_space
+ << " had incorrect removed_on_cache_reset setting when directly checking"
+ " is removed-on-cache-reset.";
+}
+
void ClientPolicyControllerTest::ExpectDownloadSupport(std::string name_space,
bool expectation) {
std::vector<std::string> cache =
controller()->GetNamespacesSupportedByDownload();
auto result = std::find(cache.begin(), cache.end(), name_space);
- EXPECT_EQ(expectation, result != cache.end());
- EXPECT_EQ(expectation, controller()->IsSupportedByDownload(name_space));
+ EXPECT_EQ(expectation, result != cache.end())
+ << "Namespace " << name_space
+ << " had incorrect download support when getting namespaces supported by"
+ " download.";
+ EXPECT_EQ(expectation, controller()->IsSupportedByDownload(name_space))
+ << "Namespace " << name_space
+ << " had incorrect download support when directly checking if supported"
+ " by download.";
}
void ClientPolicyControllerTest::ExpectRecentTab(std::string name_space,
@@ -62,9 +78,14 @@ void ClientPolicyControllerTest::ExpectRecentTab(std::string name_space,
std::vector<std::string> cache =
controller()->GetNamespacesShownAsRecentlyVisitedSite();
auto result = std::find(cache.begin(), cache.end(), name_space);
- EXPECT_EQ(expectation, result != cache.end());
- EXPECT_EQ(expectation,
- controller()->IsShownAsRecentlyVisitedSite(name_space));
+ EXPECT_EQ(expectation, result != cache.end())
+ << "Namespace " << name_space
+ << " had incorrect recent tab support when getting namespaces shown as a"
+ " recently visited site.";
+ EXPECT_EQ(expectation, controller()->IsShownAsRecentlyVisitedSite(name_space))
+ << "Namespace " << name_space
+ << " had incorrect recent tab support when directly checking if shown as"
+ " a recently visited site.";
}
void ClientPolicyControllerTest::ExpectOnlyOriginalTab(std::string name_space,
@@ -72,8 +93,31 @@ void ClientPolicyControllerTest::ExpectOnlyOriginalTab(std::string name_space,
std::vector<std::string> cache =
controller()->GetNamespacesRestrictedToOriginalTab();
auto result = std::find(cache.begin(), cache.end(), name_space);
- EXPECT_EQ(expectation, result != cache.end());
- EXPECT_EQ(expectation, controller()->IsRestrictedToOriginalTab(name_space));
+ EXPECT_EQ(expectation, result != cache.end())
+ << "Namespace " << name_space
+ << " had incorrect restriction when getting namespaces restricted to"
+ " the original tab";
+ EXPECT_EQ(expectation, controller()->IsRestrictedToOriginalTab(name_space))
+ << "Namespace " << name_space
+ << " had incorrect restriction when directly checking if the namespace"
+ " is restricted to the original tab";
+}
+
+void ClientPolicyControllerTest::ExpectDisabledWhenPrefetchDisabled(
+ std::string name_space,
+ bool expectation) {
+ std::vector<std::string> cache =
+ controller()->GetNamespacesDisabledWhenPrefetchDisabled();
+ auto result = std::find(cache.begin(), cache.end(), name_space);
+ EXPECT_EQ(expectation, result != cache.end())
+ << "Namespace " << name_space
+ << " had incorrect prefetch pref support when getting namespaces"
+ " disabled when prefetch settings are disabled.";
+ EXPECT_EQ(expectation,
+ controller()->IsDisabledWhenPrefetchDisabled(name_space))
+ << "Namespace " << name_space
+ << " had incorrect download support when directly checking if disabled"
+ " when prefetch settings are disabled.";
}
TEST_F(ClientPolicyControllerTest, FallbackTest) {
@@ -81,9 +125,11 @@ TEST_F(ClientPolicyControllerTest, FallbackTest) {
EXPECT_EQ(policy.name_space, kDefaultNamespace);
EXPECT_TRUE(isTemporary(policy));
EXPECT_TRUE(controller()->IsRemovedOnCacheReset(kUndefinedNamespace));
+ ExpectRemovedOnCacheReset(kUndefinedNamespace, true);
ExpectDownloadSupport(kUndefinedNamespace, false);
ExpectRecentTab(kUndefinedNamespace, false);
ExpectOnlyOriginalTab(kUndefinedNamespace, false);
+ ExpectDisabledWhenPrefetchDisabled(kUndefinedNamespace, false);
}
TEST_F(ClientPolicyControllerTest, CheckBookmarkDefined) {
@@ -91,9 +137,11 @@ TEST_F(ClientPolicyControllerTest, CheckBookmarkDefined) {
EXPECT_EQ(policy.name_space, kBookmarkNamespace);
EXPECT_TRUE(isTemporary(policy));
EXPECT_TRUE(controller()->IsRemovedOnCacheReset(kBookmarkNamespace));
+ ExpectRemovedOnCacheReset(kBookmarkNamespace, true);
ExpectDownloadSupport(kBookmarkNamespace, false);
ExpectRecentTab(kBookmarkNamespace, false);
ExpectOnlyOriginalTab(kBookmarkNamespace, false);
+ ExpectDisabledWhenPrefetchDisabled(kBookmarkNamespace, false);
}
TEST_F(ClientPolicyControllerTest, CheckLastNDefined) {
@@ -101,9 +149,11 @@ TEST_F(ClientPolicyControllerTest, CheckLastNDefined) {
EXPECT_EQ(policy.name_space, kLastNNamespace);
EXPECT_TRUE(isTemporary(policy));
EXPECT_TRUE(controller()->IsRemovedOnCacheReset(kLastNNamespace));
+ ExpectRemovedOnCacheReset(kLastNNamespace, true);
ExpectDownloadSupport(kLastNNamespace, false);
ExpectRecentTab(kLastNNamespace, true);
ExpectOnlyOriginalTab(kLastNNamespace, true);
+ ExpectDisabledWhenPrefetchDisabled(kLastNNamespace, false);
}
TEST_F(ClientPolicyControllerTest, CheckAsyncDefined) {
@@ -111,9 +161,11 @@ TEST_F(ClientPolicyControllerTest, CheckAsyncDefined) {
EXPECT_EQ(policy.name_space, kAsyncNamespace);
EXPECT_FALSE(isTemporary(policy));
EXPECT_FALSE(controller()->IsRemovedOnCacheReset(kAsyncNamespace));
+ ExpectRemovedOnCacheReset(kAsyncNamespace, false);
ExpectDownloadSupport(kAsyncNamespace, true);
ExpectRecentTab(kAsyncNamespace, false);
ExpectOnlyOriginalTab(kAsyncNamespace, false);
+ ExpectDisabledWhenPrefetchDisabled(kAsyncNamespace, false);
}
TEST_F(ClientPolicyControllerTest, CheckCCTDefined) {
@@ -121,9 +173,11 @@ TEST_F(ClientPolicyControllerTest, CheckCCTDefined) {
EXPECT_EQ(policy.name_space, kCCTNamespace);
EXPECT_TRUE(isTemporary(policy));
EXPECT_TRUE(controller()->IsRemovedOnCacheReset(kCCTNamespace));
+ ExpectRemovedOnCacheReset(kCCTNamespace, true);
ExpectDownloadSupport(kCCTNamespace, false);
ExpectRecentTab(kCCTNamespace, false);
ExpectOnlyOriginalTab(kCCTNamespace, false);
+ ExpectDisabledWhenPrefetchDisabled(kCCTNamespace, true);
}
TEST_F(ClientPolicyControllerTest, CheckDownloadDefined) {
@@ -131,9 +185,11 @@ TEST_F(ClientPolicyControllerTest, CheckDownloadDefined) {
EXPECT_EQ(policy.name_space, kDownloadNamespace);
EXPECT_FALSE(isTemporary(policy));
EXPECT_FALSE(controller()->IsRemovedOnCacheReset(kDownloadNamespace));
+ ExpectRemovedOnCacheReset(kDownloadNamespace, false);
ExpectDownloadSupport(kDownloadNamespace, true);
ExpectRecentTab(kDownloadNamespace, false);
ExpectOnlyOriginalTab(kDownloadNamespace, false);
+ ExpectDisabledWhenPrefetchDisabled(kDownloadNamespace, false);
}
TEST_F(ClientPolicyControllerTest, CheckNTPSuggestionsDefined) {
@@ -141,10 +197,25 @@ TEST_F(ClientPolicyControllerTest, CheckNTPSuggestionsDefined) {
controller()->GetPolicy(kNTPSuggestionsNamespace);
EXPECT_EQ(policy.name_space, kNTPSuggestionsNamespace);
EXPECT_FALSE(isTemporary(policy));
- EXPECT_TRUE(controller()->IsRemovedOnCacheReset(kNTPSuggestionsNamespace));
+ EXPECT_FALSE(controller()->IsRemovedOnCacheReset(kNTPSuggestionsNamespace));
+ ExpectRemovedOnCacheReset(kNTPSuggestionsNamespace, false);
ExpectDownloadSupport(kNTPSuggestionsNamespace, true);
ExpectRecentTab(kNTPSuggestionsNamespace, false);
ExpectOnlyOriginalTab(kNTPSuggestionsNamespace, false);
+ ExpectDisabledWhenPrefetchDisabled(kNTPSuggestionsNamespace, false);
+}
+
+TEST_F(ClientPolicyControllerTest, CheckSuggestedArticlesDefined) {
+ OfflinePageClientPolicy policy =
+ controller()->GetPolicy(kSuggestedArticlesNamespace);
+ EXPECT_EQ(policy.name_space, kSuggestedArticlesNamespace);
+ EXPECT_TRUE(isTemporary(policy));
+ EXPECT_TRUE(controller()->IsRemovedOnCacheReset(kSuggestedArticlesNamespace));
+ ExpectRemovedOnCacheReset(kSuggestedArticlesNamespace, true);
+ ExpectDownloadSupport(kSuggestedArticlesNamespace, false);
+ ExpectRecentTab(kSuggestedArticlesNamespace, false);
+ ExpectOnlyOriginalTab(kSuggestedArticlesNamespace, false);
+ ExpectDisabledWhenPrefetchDisabled(kSuggestedArticlesNamespace, true);
}
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/downloads/download_notifying_observer.cc b/chromium/components/offline_pages/core/downloads/download_notifying_observer.cc
index 00cc67daf40..da9ad6c7d52 100644
--- a/chromium/components/offline_pages/core/downloads/download_notifying_observer.cc
+++ b/chromium/components/offline_pages/core/downloads/download_notifying_observer.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/downloads/download_notifying_observer.h"
+#include "base/memory/ptr_util.h"
#include "components/offline_pages/core/background/request_coordinator.h"
#include "components/offline_pages/core/background/save_page_request.h"
#include "components/offline_pages/core/client_policy_controller.h"
@@ -36,11 +37,11 @@ void DownloadNotifyingObserver::CreateAndStartObserving(
std::unique_ptr<OfflinePageDownloadNotifier> notifier) {
DCHECK(request_coordinator);
DCHECK(notifier.get());
- DownloadNotifyingObserver* observer = new DownloadNotifyingObserver(
- std::move(notifier), request_coordinator->GetPolicyController());
- request_coordinator->AddObserver(observer);
- // |request_coordinator| takes ownership of observer here.
- request_coordinator->SetUserData(&kUserDataKey, observer);
+ std::unique_ptr<DownloadNotifyingObserver> observer =
+ base::WrapUnique(new DownloadNotifyingObserver(
+ std::move(notifier), request_coordinator->GetPolicyController()));
+ request_coordinator->AddObserver(observer.get());
+ request_coordinator->SetUserData(&kUserDataKey, std::move(observer));
}
void DownloadNotifyingObserver::OnAdded(const SavePageRequest& request) {
@@ -79,7 +80,8 @@ void DownloadNotifyingObserver::OnCompleted(
return;
if (status == RequestCoordinator::BackgroundSavePageResult::SUCCESS)
notifier_->NotifyDownloadSuccessful(DownloadUIItem(request));
- else if (status == RequestCoordinator::BackgroundSavePageResult::REMOVED)
+ else if (status ==
+ RequestCoordinator::BackgroundSavePageResult::USER_CANCELED)
notifier_->NotifyDownloadCanceled(DownloadUIItem(request));
else
notifier_->NotifyDownloadFailed(DownloadUIItem(request));
diff --git a/chromium/components/offline_pages/core/downloads/download_notifying_observer_unittest.cc b/chromium/components/offline_pages/core/downloads/download_notifying_observer_unittest.cc
index 6db87708702..48af1b047b1 100644
--- a/chromium/components/offline_pages/core/downloads/download_notifying_observer_unittest.cc
+++ b/chromium/components/offline_pages/core/downloads/download_notifying_observer_unittest.cc
@@ -211,8 +211,8 @@ TEST_F(DownloadNotifyingObserverTest, OnCompletedSuccess) {
TEST_F(DownloadNotifyingObserverTest, OnCompletedCanceled) {
SavePageRequest request(kTestOfflineId, GURL(kTestUrl), kTestClientId,
kTestCreationTime, kTestUserRequested);
- observer()->OnCompleted(request,
- RequestNotifier::BackgroundSavePageResult::REMOVED);
+ observer()->OnCompleted(
+ request, RequestNotifier::BackgroundSavePageResult::USER_CANCELED);
EXPECT_EQ(LastNotificationType::DOWNLOAD_CANCELED,
notifier()->last_notification_type());
EXPECT_EQ(kTestGuid, notifier()->download_item()->guid);
diff --git a/chromium/components/offline_pages/core/downloads/download_ui_adapter.cc b/chromium/components/offline_pages/core/downloads/download_ui_adapter.cc
index 35910a0fe72..7e1368ec7ba 100644
--- a/chromium/components/offline_pages/core/downloads/download_ui_adapter.cc
+++ b/chromium/components/offline_pages/core/downloads/download_ui_adapter.cc
@@ -32,11 +32,12 @@ DownloadUIAdapter* DownloadUIAdapter::FromOfflinePageModel(
}
// static
-void DownloadUIAdapter::AttachToOfflinePageModel(DownloadUIAdapter* adapter,
- OfflinePageModel* model) {
+void DownloadUIAdapter::AttachToOfflinePageModel(
+ std::unique_ptr<DownloadUIAdapter> adapter,
+ OfflinePageModel* model) {
DCHECK(adapter);
DCHECK(model);
- model->SetUserData(kDownloadUIAdapterKey, adapter);
+ model->SetUserData(kDownloadUIAdapterKey, std::move(adapter));
}
DownloadUIAdapter::ItemInfo::ItemInfo(const OfflinePageItem& page,
diff --git a/chromium/components/offline_pages/core/downloads/download_ui_adapter.h b/chromium/components/offline_pages/core/downloads/download_ui_adapter.h
index 2744f0b6438..9868fb009ca 100644
--- a/chromium/components/offline_pages/core/downloads/download_ui_adapter.h
+++ b/chromium/components/offline_pages/core/downloads/download_ui_adapter.h
@@ -83,8 +83,9 @@ class DownloadUIAdapter : public OfflinePageModel::Observer,
~DownloadUIAdapter() override;
static DownloadUIAdapter* FromOfflinePageModel(OfflinePageModel* model);
- static void AttachToOfflinePageModel(DownloadUIAdapter* adapter,
- OfflinePageModel* model);
+ static void AttachToOfflinePageModel(
+ std::unique_ptr<DownloadUIAdapter> adapter,
+ OfflinePageModel* model);
// This adapter is potentially shared by UI elements, each of which adds
// itself as an observer.
diff --git a/chromium/components/offline_pages/core/offline_page_archiver.h b/chromium/components/offline_pages/core/offline_page_archiver.h
index cfada7b4dea..30dd2945554 100644
--- a/chromium/components/offline_pages/core/offline_page_archiver.h
+++ b/chromium/components/offline_pages/core/offline_page_archiver.h
@@ -56,10 +56,14 @@ class OfflinePageArchiver {
// Describes the parameters to control how to create an archive.
struct CreateArchiveParams {
- CreateArchiveParams() : remove_popup_overlay(false) {}
+ CreateArchiveParams()
+ : remove_popup_overlay(false), use_page_problem_detectors(false) {}
// Whether to remove popup overlay that obstructs viewing normal content.
bool remove_popup_overlay;
+
+ // Run page problem detectors while generating MTHML if true.
+ bool use_page_problem_detectors;
};
typedef base::Callback<void(OfflinePageArchiver* /* archiver */,
diff --git a/chromium/components/offline_pages/core/offline_page_client_policy.h b/chromium/components/offline_pages/core/offline_page_client_policy.h
index 4c70894522b..9f637612470 100644
--- a/chromium/components/offline_pages/core/offline_page_client_policy.h
+++ b/chromium/components/offline_pages/core/offline_page_client_policy.h
@@ -55,12 +55,16 @@ struct FeaturePolicy {
bool only_shown_in_original_tab;
// Whether pages are removed on user-initiated cache reset. Defaults to true.
bool is_removed_on_cache_reset;
+ // Whether the namespace should be disabled if prefetching-related preferences
+ // are disabled.
+ bool disabled_when_prefetch_disabled;
FeaturePolicy()
: is_supported_by_download(false),
is_supported_by_recent_tabs(false),
only_shown_in_original_tab(false),
- is_removed_on_cache_reset(true) {}
+ is_removed_on_cache_reset(true),
+ disabled_when_prefetch_disabled(false) {}
};
// The struct describing policies for various namespaces (Bookmark, Last-N etc.)
@@ -144,6 +148,13 @@ class OfflinePageClientPolicyBuilder {
return *this;
}
+ OfflinePageClientPolicyBuilder& SetIsDisabledWhenPrefetchDisabled(
+ const bool disabled_when_prefetch_disabled) {
+ policy_.feature_policy.disabled_when_prefetch_disabled =
+ disabled_when_prefetch_disabled;
+ return *this;
+ }
+
private:
OfflinePageClientPolicy policy_;
diff --git a/chromium/components/offline_pages/core/offline_page_metadata_store.cc b/chromium/components/offline_pages/core/offline_page_metadata_store.cc
deleted file mode 100644
index 761d34983ea..00000000000
--- a/chromium/components/offline_pages/core/offline_page_metadata_store.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 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/offline_pages/core/offline_page_metadata_store.h"
-
-namespace offline_pages {
-
-template class StoreUpdateResult<OfflinePageItem>;
-
-OfflinePageMetadataStore::~OfflinePageMetadataStore() {
-}
-
-} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/offline_page_metadata_store.h b/chromium/components/offline_pages/core/offline_page_metadata_store.h
index d96fce7530a..fdc1f4e8f47 100644
--- a/chromium/components/offline_pages/core/offline_page_metadata_store.h
+++ b/chromium/components/offline_pages/core/offline_page_metadata_store.h
@@ -44,7 +44,7 @@ class OfflinePageMetadataStore {
typedef base::Callback<void(std::unique_ptr<OfflinePagesUpdateResult>)>
UpdateCallback;
- virtual ~OfflinePageMetadataStore();
+ virtual ~OfflinePageMetadataStore(){};
// Initializes the store. Should be called before any other methods.
virtual void Initialize(const InitializeCallback& callback) = 0;
diff --git a/chromium/components/offline_pages/core/offline_page_metadata_store_sql.cc b/chromium/components/offline_pages/core/offline_page_metadata_store_sql.cc
index a4a8ea080b2..c4ac133441e 100644
--- a/chromium/components/offline_pages/core/offline_page_metadata_store_sql.cc
+++ b/chromium/components/offline_pages/core/offline_page_metadata_store_sql.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/offline_pages/core/offline_page_item.h"
@@ -273,12 +274,19 @@ bool InitDatabase(sql::Connection* db, base::FilePath path) {
db->set_histogram_tag("OfflinePageMetadata");
db->set_exclusive_locking();
- base::File::Error err;
- if (!base::CreateDirectoryAndGetError(path.DirName(), &err)) {
- LOG(ERROR) << "Failed to create offline pages db directory: "
- << base::File::ErrorToString(err);
- return false;
+ base::File::Error error = base::File::FILE_OK;
+
+ if (!base::DirectoryExists(path.DirName())) {
+ if (!base::CreateDirectoryAndGetError(path.DirName(), &error)) {
+ LOG(ERROR) << "Failed to create offline pages db directory: "
+ << base::File::ErrorToString(error);
+ return false;
+ }
}
+
+ UMA_HISTOGRAM_ENUMERATION("OfflinePages.SQLStorage.CreateDirectoryResult",
+ -error, -base::File::FILE_ERROR_MAX);
+
if (!db->Open(path)) {
LOG(ERROR) << "Failed to open database";
return false;
@@ -288,26 +296,29 @@ bool InitDatabase(sql::Connection* db, base::FilePath path) {
return CreateSchema(db);
}
-void NotifyLoadResult(scoped_refptr<base::SingleThreadTaskRunner> runner,
- const OfflinePageMetadataStore::LoadCallback& callback,
- OfflinePageMetadataStore::LoadStatus status,
- const std::vector<OfflinePageItem>& result) {
+void RecordLoadResult(OfflinePageMetadataStore::LoadStatus status,
+ int32_t page_count) {
UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", status,
OfflinePageMetadataStore::LOAD_STATUS_COUNT);
if (status == OfflinePageMetadataStore::LOAD_SUCCEEDED) {
- UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount",
- static_cast<int32_t>(result.size()));
+ UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", page_count);
} else {
DVLOG(1) << "Offline pages database loading failed: " << status;
}
- runner->PostTask(FROM_HERE, base::Bind(callback, result));
}
-void OpenConnectionSync(sql::Connection* db,
- scoped_refptr<base::SingleThreadTaskRunner> runner,
- const base::FilePath& path,
- const base::Callback<void(bool)>& callback) {
+void OpenConnectionSync(
+ sql::Connection* db,
+ scoped_refptr<base::SingleThreadTaskRunner> runner,
+ const base::FilePath& path,
+ const base::Callback<void(StoreState)>& set_state_callback,
+ const OfflinePageMetadataStore::InitializeCallback& callback) {
bool success = InitDatabase(db, path);
+ // First set the state of the DB, then report to the caller.
+ // Sequence of these callbacks is important.
+ runner->PostTask(FROM_HERE, base::Bind(set_state_callback,
+ success ? StoreState::LOADED
+ : StoreState::FAILED_LOADING));
runner->PostTask(FROM_HERE, base::Bind(callback, success));
}
@@ -330,6 +341,7 @@ bool GetPageByOfflineIdSync(sql::Connection* db,
void GetOfflinePagesSync(
sql::Connection* db,
scoped_refptr<base::SingleThreadTaskRunner> runner,
+ const base::Callback<void(StoreState)>& set_state_callback,
const OfflinePageMetadataStore::LoadCallback& callback) {
const char kSql[] = "SELECT * FROM " OFFLINE_PAGES_TABLE_NAME;
@@ -340,13 +352,20 @@ void GetOfflinePagesSync(
result.push_back(MakeOfflinePageItem(&statement));
if (statement.Succeeded()) {
- NotifyLoadResult(runner, callback, OfflinePageMetadataStore::LOAD_SUCCEEDED,
- result);
+ RecordLoadResult(OfflinePageMetadataStore::LOAD_SUCCEEDED, result.size());
} else {
result.clear();
- NotifyLoadResult(runner, callback,
- OfflinePageMetadataStore::STORE_LOAD_FAILED, result);
+ // Zombify store. If we were unable to read from it, avoid consistency
+ // check and other potentially destructive operations.
+ // Note this callback should be posted back to the original thread before
+ // the main callback got the GetOfflinePages caller. Sequence of these
+ // callbacks is important.
+ runner->PostTask(
+ FROM_HERE, base::Bind(set_state_callback, StoreState::FAILED_LOADING));
+
+ RecordLoadResult(OfflinePageMetadataStore::STORE_LOAD_FAILED, 0);
}
+ runner->PostTask(FROM_HERE, base::Bind(callback, result));
}
void AddOfflinePageSync(sql::Connection* db,
@@ -460,20 +479,6 @@ void RemoveOfflinePagesSync(
runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result)));
}
-void ResetSync(sql::Connection* db,
- const base::FilePath& db_file_path,
- scoped_refptr<base::SingleThreadTaskRunner> runner,
- const base::Callback<void(bool)>& callback) {
- // This method deletes the content of the whole store and reinitializes it.
- bool success = true;
- if (db) {
- success = db->Raze();
- db->Close();
- }
- success = base::DeleteFile(db_file_path, true /*recursive*/) && success;
- runner->PostTask(FROM_HERE, base::Bind(callback, success));
-}
-
} // anonymous namespace
OfflinePageMetadataStoreSQL::OfflinePageMetadataStoreSQL(
@@ -497,11 +502,11 @@ void OfflinePageMetadataStoreSQL::Initialize(
DCHECK(!db_);
db_.reset(new sql::Connection());
background_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&OpenConnectionSync, db_.get(),
- base::ThreadTaskRunnerHandle::Get(), db_file_path_,
- base::Bind(&OfflinePageMetadataStoreSQL::OnOpenConnectionDone,
- weak_ptr_factory_.GetWeakPtr(), callback)));
+ FROM_HERE, base::Bind(&OpenConnectionSync, db_.get(),
+ base::ThreadTaskRunnerHandle::Get(), db_file_path_,
+ base::Bind(&OfflinePageMetadataStoreSQL::SetState,
+ weak_ptr_factory_.GetWeakPtr()),
+ callback));
}
void OfflinePageMetadataStoreSQL::GetOfflinePages(
@@ -514,7 +519,10 @@ void OfflinePageMetadataStoreSQL::GetOfflinePages(
background_task_runner_->PostTask(
FROM_HERE, base::Bind(&GetOfflinePagesSync, db_.get(),
- base::ThreadTaskRunnerHandle::Get(), callback));
+ base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&OfflinePageMetadataStoreSQL::SetState,
+ weak_ptr_factory_.GetWeakPtr()),
+ callback));
}
void OfflinePageMetadataStoreSQL::AddOfflinePage(
@@ -570,13 +578,14 @@ void OfflinePageMetadataStoreSQL::RemoveOfflinePages(
base::ThreadTaskRunnerHandle::Get(), callback));
}
+// No-op implementation. This database does not reset.
+// TODO(dimich): Observe UMA and decide if this database has to be erased.
+// Note is potentially contains user-saved data.
void OfflinePageMetadataStoreSQL::Reset(const ResetCallback& callback) {
- background_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&ResetSync, db_.get(), db_file_path_,
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&OfflinePageMetadataStoreSQL::OnResetDone,
- weak_ptr_factory_.GetWeakPtr(), callback)));
+ bool success = true;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, success));
+ return;
}
StoreState OfflinePageMetadataStoreSQL::state() const {
@@ -590,20 +599,10 @@ void OfflinePageMetadataStoreSQL::SetStateForTesting(StoreState state,
db_.reset(nullptr);
}
-void OfflinePageMetadataStoreSQL::OnOpenConnectionDone(
- const InitializeCallback& callback,
- bool success) {
+void OfflinePageMetadataStoreSQL::SetState(StoreState state) {
DCHECK(db_.get());
- state_ = success ? StoreState::LOADED : StoreState::FAILED_LOADING;
- callback.Run(success);
-}
-
-void OfflinePageMetadataStoreSQL::OnResetDone(const ResetCallback& callback,
- bool success) {
- state_ = success ? StoreState::NOT_LOADED : StoreState::FAILED_RESET;
- db_.reset();
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback, success));
+ DCHECK(state == StoreState::LOADED || state == StoreState::FAILED_LOADING);
+ state_ = state;
}
bool OfflinePageMetadataStoreSQL::CheckDb() const {
diff --git a/chromium/components/offline_pages/core/offline_page_metadata_store_sql.h b/chromium/components/offline_pages/core/offline_page_metadata_store_sql.h
index 04265262562..41b96fa475c 100644
--- a/chromium/components/offline_pages/core/offline_page_metadata_store_sql.h
+++ b/chromium/components/offline_pages/core/offline_page_metadata_store_sql.h
@@ -76,9 +76,8 @@ class OfflinePageMetadataStoreSQL : public OfflinePageMetadataStore {
void SetStateForTesting(StoreState state, bool reset_db);
private:
- // Used to conclude opening/resetting DB connection.
- void OnOpenConnectionDone(const InitializeCallback& callback, bool success);
- void OnResetDone(const ResetCallback& callback, bool success);
+ // Used as callback to set state from open / initial read operations.
+ void SetState(StoreState state);
// Checks whether a valid DB connection is present and store state is LOADED.
bool CheckDb() const;
diff --git a/chromium/components/offline_pages/core/offline_page_metadata_store_impl_unittest.cc b/chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc
index 7dcb7898685..cdfdc473cc5 100644
--- a/chromium/components/offline_pages/core/offline_page_metadata_store_impl_unittest.cc
+++ b/chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc
@@ -910,7 +910,9 @@ TEST_F(OfflinePageMetadataStoreTest, UpdateOfflinePage) {
EXPECT_EQ(offline_page, offline_pages_[0]);
}
-TEST_F(OfflinePageMetadataStoreTest, ClearAllOfflinePages) {
+// In current implementation Reset is a no-op. No pages are erased.
+// See bug 725122 for more info.
+TEST_F(OfflinePageMetadataStoreTest, ResetStoreDoesNotErase) {
std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
// Add 2 offline pages.
@@ -945,7 +947,6 @@ TEST_F(OfflinePageMetadataStoreTest, ClearAllOfflinePages) {
EXPECT_EQ(LOAD, last_called_callback_);
EXPECT_EQ(2U, offline_pages_.size());
- // Clear all records from the store.
store->Reset(base::Bind(&OfflinePageMetadataStoreTest::ResetCallback,
base::Unretained(this)));
PumpLoop();
@@ -960,8 +961,9 @@ TEST_F(OfflinePageMetadataStoreTest, ClearAllOfflinePages) {
base::Unretained(this)));
PumpLoop();
+ // Verify the store still loads with original content.
EXPECT_EQ(LOAD, last_called_callback_);
- ASSERT_EQ(0U, offline_pages_.size());
+ ASSERT_EQ(2U, offline_pages_.size());
}
TEST_F(OfflinePageMetadataStoreTest, ResetStore) {
diff --git a/chromium/components/offline_pages/core/offline_page_model.h b/chromium/components/offline_pages/core/offline_page_model.h
index 434687e9e11..52c24570922 100644
--- a/chromium/components/offline_pages/core/offline_page_model.h
+++ b/chromium/components/offline_pages/core/offline_page_model.h
@@ -73,6 +73,9 @@ class OfflinePageModel : public base::SupportsUserData {
// Whether the page is being saved in the background.
bool is_background;
+
+ // Run page problem detectors while generating MTHML if true.
+ bool use_page_problem_detectors;
};
// Observer of the OfflinePageModel.
diff --git a/chromium/components/offline_pages/core/offline_page_model_impl.cc b/chromium/components/offline_pages/core/offline_page_model_impl.cc
index 596892d6171..4c3bbdce98b 100644
--- a/chromium/components/offline_pages/core/offline_page_model_impl.cc
+++ b/chromium/components/offline_pages/core/offline_page_model_impl.cc
@@ -42,6 +42,12 @@ namespace {
const base::TimeDelta kStorageManagerStartingDelay =
base::TimeDelta::FromSeconds(20);
+// Number of times to try to initialize the underlying database.
+// TODO(dimich): Replace with a schema that eventually obliterates the database
+// if it has permanent damage. Note this DB contains data saved by user, so
+// need to be gentle.
+const int kInitializeAttemptsMax = 3;
+
int64_t GenerateOfflineId() {
return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1;
}
@@ -308,6 +314,11 @@ void ReportPageHistogramsAfterAccess(const OfflinePageItem& offline_page_item,
(access_time - offline_page_item.last_access_time).InMinutes());
}
+void ReportInitializationAttemptsSpent(int attempts_spent) {
+ UMA_HISTOGRAM_EXACT_LINEAR("OfflinePages.Model.InitAttemptsSpent",
+ attempts_spent, kInitializeAttemptsMax);
+}
+
} // namespace
// protected
@@ -370,6 +381,8 @@ void OfflinePageModelImpl::SavePage(
// If the page is being saved in the background, we should try to remove the
// popup overlay that obstructs viewing the normal content.
create_archive_params.remove_popup_overlay = save_page_params.is_background;
+ create_archive_params.use_page_problem_detectors =
+ save_page_params.use_page_problem_detectors;
archiver->CreateArchive(
archives_dir_, create_archive_params,
base::Bind(&OfflinePageModelImpl::OnCreateArchiveDone,
@@ -656,6 +669,12 @@ void OfflinePageModelImpl::GetPagesByURLWhenLoadDone(
}
void OfflinePageModelImpl::CheckMetadataConsistency() {
+ DCHECK(is_loaded_);
+
+ // Avoid consistency check if disk store couldn't load.
+ if (store_->state() != StoreState::LOADED)
+ return;
+
archive_manager_->GetAllArchives(
base::Bind(&OfflinePageModelImpl::CheckMetadataConsistencyForArchivePaths,
weak_ptr_factory_.GetWeakPtr()));
@@ -776,17 +795,18 @@ void OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone(
UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime",
base::TimeTicks::Now() - start_time);
- const int kResetAttemptsLeft = 1;
store_->Initialize(base::Bind(&OfflinePageModelImpl::OnStoreInitialized,
- weak_ptr_factory_.GetWeakPtr(), start_time,
- kResetAttemptsLeft));
+ weak_ptr_factory_.GetWeakPtr(), start_time, 0));
}
void OfflinePageModelImpl::OnStoreInitialized(const base::TimeTicks& start_time,
- int reset_attempts_left,
+ int init_attempts_spent,
bool success) {
+ init_attempts_spent++;
+
if (success) {
DCHECK_EQ(store_->state(), StoreState::LOADED);
+ ReportInitializationAttemptsSpent(init_attempts_spent);
store_->GetOfflinePages(
base::Bind(&OfflinePageModelImpl::OnInitialGetOfflinePagesDone,
weak_ptr_factory_.GetWeakPtr(), start_time));
@@ -794,31 +814,29 @@ void OfflinePageModelImpl::OnStoreInitialized(const base::TimeTicks& start_time,
}
DCHECK_EQ(store_->state(), StoreState::FAILED_LOADING);
- // If there are no more reset attempts left, stop here.
- if (reset_attempts_left == 0) {
+ // If there are no more init attempts left, stop here.
+ if (init_attempts_spent >= kInitializeAttemptsMax) {
FinalizeModelLoad();
return;
}
- // Otherwise reduce the remaining attempts counter and reset store.
- store_->Reset(base::Bind(&OfflinePageModelImpl::OnStoreResetDone,
- weak_ptr_factory_.GetWeakPtr(), start_time,
- reset_attempts_left - 1));
+ // The DB failed to load. If this is a transient condition (locks not
+ // yet released etc) chances are that a retry with a delay will succeed.
+ const base::TimeDelta delay = base::TimeDelta::FromMilliseconds(100);
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&OfflinePageModelImpl::RetryDbInitialization,
+ weak_ptr_factory_.GetWeakPtr(), start_time,
+ init_attempts_spent),
+ delay);
}
-void OfflinePageModelImpl::OnStoreResetDone(const base::TimeTicks& start_time,
- int reset_attempts_left,
- bool success) {
- if (success) {
- DCHECK_EQ(store_->state(), StoreState::NOT_LOADED);
- store_->Initialize(base::Bind(&OfflinePageModelImpl::OnStoreInitialized,
- weak_ptr_factory_.GetWeakPtr(), start_time,
- reset_attempts_left));
- return;
- }
-
- DCHECK_EQ(store_->state(), StoreState::FAILED_RESET);
- FinalizeModelLoad();
+void OfflinePageModelImpl::RetryDbInitialization(
+ const base::TimeTicks& start_time,
+ int init_attempts_spent) {
+ store_->Initialize(base::Bind(&OfflinePageModelImpl::OnStoreInitialized,
+ weak_ptr_factory_.GetWeakPtr(), start_time,
+ init_attempts_spent));
}
void OfflinePageModelImpl::OnInitialGetOfflinePagesDone(
@@ -842,6 +860,9 @@ void OfflinePageModelImpl::FinalizeModelLoad() {
// All actions below are meant to be taken regardless of successful load of
// the store.
+ UMA_HISTOGRAM_BOOLEAN("OfflinePages.Model.FinalLoadSuccessful",
+ store_->state() == StoreState::LOADED);
+
// Inform observers the load is done.
for (Observer& observer : observers_)
observer.OfflinePageModelLoaded(this);
diff --git a/chromium/components/offline_pages/core/offline_page_model_impl.h b/chromium/components/offline_pages/core/offline_page_model_impl.h
index 64e2e3cfdfd..0b9ba3e5065 100644
--- a/chromium/components/offline_pages/core/offline_page_model_impl.h
+++ b/chromium/components/offline_pages/core/offline_page_model_impl.h
@@ -146,11 +146,10 @@ class OfflinePageModelImpl : public OfflinePageModel, public KeyedService {
// Callback for loading pages from the offline page metadata store.
void OnStoreInitialized(const base::TimeTicks& start_time,
- int reset_attempts_left,
+ int init_attempts_spent,
bool success);
- void OnStoreResetDone(const base::TimeTicks& start_time,
- int reset_attempts_left,
- bool success);
+ void RetryDbInitialization(const base::TimeTicks& start_time,
+ int init_attempts_spent);
void OnInitialGetOfflinePagesDone(
const base::TimeTicks& start_time,
const std::vector<OfflinePageItem>& offline_pages);
diff --git a/chromium/components/offline_pages/core/offline_page_model_impl_unittest.cc b/chromium/components/offline_pages/core/offline_page_model_impl_unittest.cc
index 8d20e475263..6280ae09ff4 100644
--- a/chromium/components/offline_pages/core/offline_page_model_impl_unittest.cc
+++ b/chromium/components/offline_pages/core/offline_page_model_impl_unittest.cc
@@ -39,6 +39,7 @@
namespace offline_pages {
namespace {
+const char kOriginalTabNamespace[] = "original_tab_testing_namespace";
const char kTestClientNamespace[] = "default";
const char kUserRequestedNamespace[] = "download";
const GURL kTestUrl("http://example.com");
@@ -117,6 +118,9 @@ class OfflinePageModelImplTest
// Fast-forwards virtual time by |delta|, causing tasks with a remaining
// delay less than or equal to |delta| to be executed.
void FastForwardBy(base::TimeDelta delta);
+ // Runs tasks and moves time forward until no tasks remain in the queue.
+ void FastForwardUntilNoTasksRemain();
+
void ResetResults();
OfflinePageTestStore* GetStore();
@@ -224,6 +228,14 @@ OfflinePageModelImplTest::~OfflinePageModelImplTest() {}
void OfflinePageModelImplTest::SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
model_ = BuildModel(BuildStore());
+ model_->GetPolicyController()->AddPolicyForTest(
+ kOriginalTabNamespace,
+ OfflinePageClientPolicyBuilder(
+ kOriginalTabNamespace,
+ offline_pages::LifetimePolicy::LifetimeType::TEMPORARY,
+ kUnlimitedPages, kUnlimitedPages)
+ .SetIsOnlyShownInOriginalTab(true));
+
model_->AddObserver(this);
PumpLoop();
}
@@ -313,6 +325,10 @@ void OfflinePageModelImplTest::FastForwardBy(base::TimeDelta delta) {
task_runner_->FastForwardBy(delta);
}
+void OfflinePageModelImplTest::FastForwardUntilNoTasksRemain() {
+ task_runner_->FastForwardUntilNoTasksRemain();
+}
+
void OfflinePageModelImplTest::ResetResults() {
last_save_result_ = SavePageResult::CANCELLED;
last_delete_result_ = DeletePageResult::CANCELLED;
@@ -661,6 +677,7 @@ TEST_F(OfflinePageModelImplTest, SavePageOnBackground) {
save_page_params.url = kTestUrl;
save_page_params.client_id = kTestClientId1;
save_page_params.is_background = true;
+ save_page_params.use_page_problem_detectors = false;
SavePageWithParamsAsync(save_page_params, std::move(archiver));
EXPECT_TRUE(archiver_ptr->create_archive_called());
// |remove_popup_overlay| should be turned on on background mode.
@@ -1033,9 +1050,7 @@ TEST_F(OfflinePageModelImplTest, CheckPagesExistOffline) {
SavePage(kTestUrl, kTestClientId1);
SavePage(kTestUrl2, kTestClientId2);
- // TODO(dewittj): Remove the "Last N" restriction in favor of a better query
- // interface. See https://crbug.com/622763 for information.
- const ClientId last_n_client_id(kLastNNamespace, "1234");
+ const ClientId last_n_client_id(kOriginalTabNamespace, "1234");
SavePage(kTestUrl3, last_n_client_id);
std::set<GURL> input;
@@ -1222,38 +1237,40 @@ TEST_F(OfflinePageModelImplTest, NewTabPageNamespace) {
static_cast<int>(SavePageResult::SUCCESS), 1);
}
-TEST_F(OfflinePageModelImplTest, StoreResetSuccessful) {
- GetStore()->set_test_scenario(
- OfflinePageTestStore::TestScenario::LOAD_FAILED_RESET_SUCCESS);
- ResetModel();
-
- const std::vector<OfflinePageItem>& offline_pages = GetAllPages();
-
- EXPECT_TRUE(model()->is_loaded());
- EXPECT_EQ(StoreState::LOADED, GetStore()->state());
- EXPECT_EQ(0UL, offline_pages.size());
-
- std::pair<SavePageResult, int64_t> result =
- SavePage(kTestUrl, ClientId(kDownloadNamespace, "123"));
+TEST_F(OfflinePageModelImplTest, StoreLoadFailurePersists) {
+ // Initial database load is successful. Only takes 1 attempt.
+ EXPECT_EQ(1, GetStore()->initialize_attempts_count());
+ histograms().ExpectUniqueSample("OfflinePages.Model.FinalLoadSuccessful",
+ true, 1);
+ histograms().ExpectUniqueSample("OfflinePages.Model.InitAttemptsSpent", 1, 1);
- EXPECT_EQ(SavePageResult::SUCCESS, result.first);
-}
-
-TEST_F(OfflinePageModelImplTest, StoreResetFailed) {
GetStore()->set_test_scenario(
- OfflinePageTestStore::TestScenario::LOAD_FAILED_RESET_FAILED);
+ OfflinePageTestStore::TestScenario::LOAD_FAILED_RESET_SUCCESS);
ResetModel();
+ // Skip all the retries with delays.
+ FastForwardUntilNoTasksRemain();
+ // All available attempts were spent.
+ EXPECT_EQ(3, GetStore()->initialize_attempts_count());
+
+ // Should record failure to load.
+ histograms().ExpectBucketCount("OfflinePages.Model.FinalLoadSuccessful",
+ false, 1);
+ // Should show the previous count since no attempts are recorded for failure.
+ // In case of failure, all attempts are assumed spent.
+ histograms().ExpectUniqueSample("OfflinePages.Model.InitAttemptsSpent", 1, 1);
const std::vector<OfflinePageItem>& offline_pages = GetAllPages();
+ // Model will 'load' but the store underneath it is not functional and
+ // will silently fail all sql operations.
EXPECT_TRUE(model()->is_loaded());
- EXPECT_EQ(StoreState::FAILED_RESET, GetStore()->state());
+ EXPECT_EQ(StoreState::FAILED_LOADING, GetStore()->state());
EXPECT_EQ(0UL, offline_pages.size());
- ResetResults();
+ // The pages can still be saved, they will not be persisted to disk.
+ // Verify no crashes and error code returned.
std::pair<SavePageResult, int64_t> result =
SavePage(kTestUrl, ClientId(kDownloadNamespace, "123"));
-
EXPECT_EQ(SavePageResult::STORE_FAILURE, result.first);
}
diff --git a/chromium/components/offline_pages/core/offline_page_model_query.cc b/chromium/components/offline_pages/core/offline_page_model_query.cc
index 6aa192b6713..382e20b7273 100644
--- a/chromium/components/offline_pages/core/offline_page_model_query.cc
+++ b/chromium/components/offline_pages/core/offline_page_model_query.cc
@@ -41,6 +41,13 @@ OfflinePageModelQueryBuilder& OfflinePageModelQueryBuilder::SetUrls(
}
OfflinePageModelQueryBuilder&
+OfflinePageModelQueryBuilder::RequireRemovedOnCacheReset(
+ Requirement removed_on_cache_reset) {
+ removed_on_cache_reset_ = removed_on_cache_reset;
+ return *this;
+}
+
+OfflinePageModelQueryBuilder&
OfflinePageModelQueryBuilder::RequireSupportedByDownload(
Requirement supported_by_download) {
supported_by_download_ = supported_by_download;
@@ -61,6 +68,12 @@ OfflinePageModelQueryBuilder::RequireRestrictedToOriginalTab(
return *this;
}
+OfflinePageModelQueryBuilder& OfflinePageModelQueryBuilder::RequireNamespace(
+ const std::string& name_space) {
+ name_space_ = base::MakeUnique<std::string>(name_space);
+ return *this;
+}
+
std::unique_ptr<OfflinePageModelQuery> OfflinePageModelQueryBuilder::Build(
ClientPolicyController* controller) {
DCHECK(controller);
@@ -82,10 +95,20 @@ std::unique_ptr<OfflinePageModelQuery> OfflinePageModelQueryBuilder::Build(
std::vector<std::string> allowed_namespaces;
bool uses_namespace_restrictions = false;
- for (auto& name_space : controller->GetAllNamespaces()) {
+ std::vector<std::string> namespaces;
+ if (name_space_) {
+ uses_namespace_restrictions = true;
+ namespaces.push_back(*name_space_);
+ } else {
+ namespaces = controller->GetAllNamespaces();
+ }
+
+ for (auto& name_space : namespaces) {
// If any exclusion requirements exist, and the namespace matches one of
// those excluded by policy, skip adding it to |allowed_namespaces|.
- if ((supported_by_download_ == Requirement::EXCLUDE_MATCHING &&
+ if ((removed_on_cache_reset_ == Requirement::EXCLUDE_MATCHING &&
+ controller->IsRemovedOnCacheReset(name_space)) ||
+ (supported_by_download_ == Requirement::EXCLUDE_MATCHING &&
controller->IsSupportedByDownload(name_space)) ||
(shown_as_recently_visited_site_ == Requirement::EXCLUDE_MATCHING &&
controller->IsShownAsRecentlyVisitedSite(name_space)) ||
@@ -96,7 +119,9 @@ std::unique_ptr<OfflinePageModelQuery> OfflinePageModelQueryBuilder::Build(
continue;
}
- if ((supported_by_download_ == Requirement::INCLUDE_MATCHING &&
+ if ((removed_on_cache_reset_ == Requirement::INCLUDE_MATCHING &&
+ !controller->IsRemovedOnCacheReset(name_space)) ||
+ (supported_by_download_ == Requirement::INCLUDE_MATCHING &&
!controller->IsSupportedByDownload(name_space)) ||
(shown_as_recently_visited_site_ == Requirement::INCLUDE_MATCHING &&
!controller->IsShownAsRecentlyVisitedSite(name_space)) ||
@@ -111,6 +136,7 @@ std::unique_ptr<OfflinePageModelQuery> OfflinePageModelQueryBuilder::Build(
allowed_namespaces.emplace_back(name_space);
}
+ removed_on_cache_reset_ = Requirement::UNSET;
supported_by_download_ = Requirement::UNSET;
shown_as_recently_visited_site_ = Requirement::UNSET;
restricted_to_original_tab_ = Requirement::UNSET;
diff --git a/chromium/components/offline_pages/core/offline_page_model_query.h b/chromium/components/offline_pages/core/offline_page_model_query.h
index 526c3707ab9..4107b39063e 100644
--- a/chromium/components/offline_pages/core/offline_page_model_query.h
+++ b/chromium/components/offline_pages/core/offline_page_model_query.h
@@ -86,6 +86,13 @@ class OfflinePageModelQueryBuilder {
const std::vector<GURL>& urls);
// Only include pages whose namespaces satisfy
+ // ClientPolicyController::IsRemovedOnCacheReset(|namespace|) ==
+ // |removed_on_cache_reset|
+ // Multiple calls overwrite previous ones.
+ OfflinePageModelQueryBuilder& RequireRemovedOnCacheReset(
+ Requirement removed_on_cache_reset);
+
+ // Only include pages whose namespaces satisfy
// ClientPolicyController::IsSupportedByDownload(|namespace|) ==
// |supported_by_download|
// Multiple calls overwrite previous ones.
@@ -106,6 +113,9 @@ class OfflinePageModelQueryBuilder {
OfflinePageModelQueryBuilder& RequireRestrictedToOriginalTab(
Requirement original_tab);
+ // Only include results from a single namespace.
+ OfflinePageModelQueryBuilder& RequireNamespace(const std::string& name_space);
+
// Builds the query using the namespace policies provided by |controller|
// This resets the internal state. |controller| should not be |nullptr|.
std::unique_ptr<OfflinePageModelQuery> Build(
@@ -123,10 +133,13 @@ class OfflinePageModelQueryBuilder {
std::pair<Requirement, std::vector<ClientId>> client_ids_;
std::pair<Requirement, std::vector<GURL>> urls_;
+ Requirement removed_on_cache_reset_ = Requirement::UNSET;
Requirement supported_by_download_ = Requirement::UNSET;
Requirement shown_as_recently_visited_site_ = Requirement::UNSET;
Requirement restricted_to_original_tab_ = Requirement::UNSET;
+ std::unique_ptr<std::string> name_space_;
+
DISALLOW_COPY_AND_ASSIGN(OfflinePageModelQueryBuilder);
};
diff --git a/chromium/components/offline_pages/core/offline_page_model_query_unittest.cc b/chromium/components/offline_pages/core/offline_page_model_query_unittest.cc
index fc05633013b..01eb27b6a69 100644
--- a/chromium/components/offline_pages/core/offline_page_model_query_unittest.cc
+++ b/chromium/components/offline_pages/core/offline_page_model_query_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/time/time.h"
-#include "components/offline_pages/client_namespace_constants.h"
-#include "components/offline_pages/client_policy_controller.h"
#include "components/offline_pages/core/offline_page_model_query.h"
-#include "components/offline_pages/offline_page_client_policy.h"
-#include "components/offline_pages/offline_page_item.h"
+#include "base/time/time.h"
+#include "components/offline_pages/core/client_namespace_constants.h"
+#include "components/offline_pages/core/client_policy_controller.h"
+#include "components/offline_pages/core/offline_page_client_policy.h"
+#include "components/offline_pages/core/offline_page_item.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace offline_pages {
@@ -37,6 +37,10 @@ class OfflinePageModelQueryTest : public testing::Test {
ClientPolicyController policy_;
OfflinePageModelQueryBuilder builder_;
+ const OfflinePageItem cache_page() {
+ return OfflinePageItem(GURL("https://download.com"), 3,
+ {kBookmarkNamespace, "id1"}, base::FilePath(), 3);
+ }
const OfflinePageItem download_page() {
return OfflinePageItem(GURL("https://download.com"), 4,
{kDownloadNamespace, "id1"}, base::FilePath(), 4);
@@ -278,6 +282,43 @@ TEST_F(OfflinePageModelQueryTest, UrlsReplace) {
EXPECT_TRUE(query->Matches(kTestItem2));
}
+TEST_F(OfflinePageModelQueryTest, RequireRemovedOnCacheReset_Only) {
+ builder_.RequireRemovedOnCacheReset(Requirement::INCLUDE_MATCHING);
+ std::unique_ptr<OfflinePageModelQuery> query = builder_.Build(&policy_);
+
+ auto restriction = query->GetRestrictedToNamespaces();
+ std::set<std::string> namespaces_allowed = restriction.second;
+ bool restricted_to_namespaces = restriction.first;
+ EXPECT_TRUE(restricted_to_namespaces);
+
+ for (const std::string& name_space : namespaces_allowed) {
+ EXPECT_TRUE(policy_.IsRemovedOnCacheReset(name_space))
+ << "Namespace: " << name_space;
+ }
+ EXPECT_TRUE(query->Matches(kTestItem1));
+ EXPECT_TRUE(query->Matches(cache_page()));
+ EXPECT_FALSE(query->Matches(download_page()));
+}
+
+TEST_F(OfflinePageModelQueryTest, RequireRemovedOnCacheReset_Except) {
+ builder_.RequireRemovedOnCacheReset(Requirement::EXCLUDE_MATCHING);
+ std::unique_ptr<OfflinePageModelQuery> query = builder_.Build(&policy_);
+
+ auto restriction = query->GetRestrictedToNamespaces();
+ std::set<std::string> namespaces_allowed = restriction.second;
+ bool restricted_to_namespaces = restriction.first;
+ EXPECT_TRUE(restricted_to_namespaces);
+
+ for (const std::string& name_space : namespaces_allowed) {
+ EXPECT_FALSE(policy_.IsRemovedOnCacheReset(name_space))
+ << "Namespace: " << name_space;
+ }
+
+ EXPECT_FALSE(query->Matches(kTestItem1));
+ EXPECT_FALSE(query->Matches(cache_page()));
+ EXPECT_TRUE(query->Matches(download_page()));
+}
+
TEST_F(OfflinePageModelQueryTest, RequireSupportedByDownload_Only) {
builder_.RequireSupportedByDownload(Requirement::INCLUDE_MATCHING);
std::unique_ptr<OfflinePageModelQuery> query = builder_.Build(&policy_);
@@ -396,4 +437,19 @@ TEST_F(OfflinePageModelQueryTest, IntersectNamespaces) {
EXPECT_FALSE(query->Matches(recent_page()));
}
+TEST_F(OfflinePageModelQueryTest, RequireNamespace) {
+ builder_.RequireNamespace(kDefaultNamespace);
+ std::unique_ptr<OfflinePageModelQuery> query = builder_.Build(&policy_);
+ auto restriction = query->GetRestrictedToNamespaces();
+ std::set<std::string> namespaces_allowed = restriction.second;
+ bool restricted_to_namespaces = restriction.first;
+ EXPECT_TRUE(restricted_to_namespaces);
+ EXPECT_EQ(1U, namespaces_allowed.size());
+ EXPECT_TRUE(namespaces_allowed.find(kDefaultNamespace) !=
+ namespaces_allowed.end());
+
+ EXPECT_TRUE(query->Matches(kTestItem1));
+ EXPECT_FALSE(query->Matches(test_namespace_page()));
+}
+
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/offline_page_storage_manager_unittest.cc b/chromium/components/offline_pages/core/offline_page_storage_manager_unittest.cc
index bc3208a2dcc..29dbced847b 100644
--- a/chromium/components/offline_pages/core/offline_page_storage_manager_unittest.cc
+++ b/chromium/components/offline_pages/core/offline_page_storage_manager_unittest.cc
@@ -13,7 +13,6 @@
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
#include "components/offline_pages/core/archive_manager.h"
-#include "components/offline_pages/core/client_namespace_constants.h"
#include "components/offline_pages/core/client_policy_controller.h"
#include "components/offline_pages/core/offline_page_item.h"
#include "components/offline_pages/core/offline_page_model_impl.h"
@@ -28,6 +27,9 @@ using StorageStats = offline_pages::ArchiveManager::StorageStats;
namespace offline_pages {
namespace {
+const char kOneDayNamespace[] = "temporary_namespace_1day";
+const char kOneWeekNamespace[] = "temporary_namespace_7day";
+const char kPersistentNamespace[] = "persistent_namespace";
const GURL kTestUrl("http://example.com");
const base::FilePath::CharType kFilePath[] = FILE_PATH_LITERAL("/data");
const int64_t kTestFileSize = 1 << 19; // Make a page 512KB.
@@ -49,11 +51,30 @@ class OfflinePageTestModel : public OfflinePageModelImpl {
public:
OfflinePageTestModel(std::vector<PageSettings> page_settings,
base::SimpleTestClock* clock,
+ ClientPolicyController* policy_controller,
TestOptions options = TestOptions::DEFAULT)
- : policy_controller_(new ClientPolicyController()),
+ : policy_controller_(policy_controller),
clock_(clock),
options_(options),
next_offline_id_(0) {
+ policy_controller_->AddPolicyForTest(
+ kOneDayNamespace,
+ OfflinePageClientPolicyBuilder(kOneDayNamespace,
+ LifetimePolicy::LifetimeType::TEMPORARY,
+ kUnlimitedPages, kUnlimitedPages)
+ .SetExpirePeriod(base::TimeDelta::FromDays(1)));
+ policy_controller_->AddPolicyForTest(
+ kOneWeekNamespace,
+ OfflinePageClientPolicyBuilder(kOneWeekNamespace,
+ LifetimePolicy::LifetimeType::TEMPORARY,
+ kUnlimitedPages, 1)
+ .SetExpirePeriod(base::TimeDelta::FromDays(7)));
+ policy_controller_->AddPolicyForTest(
+ kPersistentNamespace,
+ OfflinePageClientPolicyBuilder(kPersistentNamespace,
+ LifetimePolicy::LifetimeType::PERSISTENT,
+ kUnlimitedPages, kUnlimitedPages)
+ .SetIsRemovedOnCacheReset(false));
for (const auto& setting : page_settings)
AddPages(setting);
}
@@ -82,12 +103,17 @@ class OfflinePageTestModel : public OfflinePageModelImpl {
base::SimpleTestClock* clock() { return clock_; }
+ ClientPolicyController* GetPolicyController() override {
+ return policy_controller_;
+ }
+
private:
std::map<int64_t, OfflinePageItem> pages_;
std::vector<OfflinePageItem> removed_pages_;
- std::unique_ptr<ClientPolicyController> policy_controller_;
+ // Owned by the test.
+ ClientPolicyController* policy_controller_;
base::SimpleTestClock* clock_;
@@ -217,7 +243,8 @@ void OfflinePageStorageManagerTest::Initialize(
std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
clock_ = clock.get();
clock_->SetNow(base::Time::Now());
- model_.reset(new OfflinePageTestModel(page_settings, clock_, options));
+ model_.reset(new OfflinePageTestModel(page_settings, clock_,
+ policy_controller_.get(), options));
if (stats.free_disk_space == 0)
stats.free_disk_space = kFreeSpaceNormal;
@@ -249,7 +276,7 @@ void OfflinePageStorageManagerTest::OnPagesCleared(size_t pages_cleared_count,
TEST_F(OfflinePageStorageManagerTest, TestClearPagesLessThanLimit) {
Initialize(std::vector<PageSettings>(
- {{kBookmarkNamespace, 1, 1}, {kLastNNamespace, 1, 1}}));
+ {{kOneWeekNamespace, 1, 1}, {kOneDayNamespace, 1, 1}}));
clock()->Advance(base::TimeDelta::FromMinutes(30));
TryClearPages();
EXPECT_EQ(2, last_cleared_page_count());
@@ -260,7 +287,7 @@ TEST_F(OfflinePageStorageManagerTest, TestClearPagesLessThanLimit) {
TEST_F(OfflinePageStorageManagerTest, TestClearPagesMoreThanLimit) {
Initialize(std::vector<PageSettings>(
- {{kBookmarkNamespace, 10, 15}, {kLastNNamespace, 5, 30}}));
+ {{kOneWeekNamespace, 10, 15}, {kOneDayNamespace, 5, 30}}));
clock()->Advance(base::TimeDelta::FromMinutes(30));
TryClearPages();
EXPECT_EQ(45, last_cleared_page_count());
@@ -271,7 +298,7 @@ TEST_F(OfflinePageStorageManagerTest, TestClearPagesMoreThanLimit) {
TEST_F(OfflinePageStorageManagerTest, TestClearPagesMoreFreshPages) {
Initialize(std::vector<PageSettings>(
- {{kBookmarkNamespace, 30, 0}, {kLastNNamespace, 100, 1}}),
+ {{kOneWeekNamespace, 30, 0}, {kOneDayNamespace, 100, 1}}),
{1000 * (1 << 20), 0});
clock()->Advance(base::TimeDelta::FromMinutes(30));
TryClearPages();
@@ -281,8 +308,8 @@ TEST_F(OfflinePageStorageManagerTest, TestClearPagesMoreFreshPages) {
EXPECT_EQ(1, static_cast<int>(model()->GetRemovedPages().size()));
}
-TEST_F(OfflinePageStorageManagerTest, TestDeleteAsyncPages) {
- Initialize(std::vector<PageSettings>({{kAsyncNamespace, 20, 0}}));
+TEST_F(OfflinePageStorageManagerTest, TestDeletePersistentPages) {
+ Initialize(std::vector<PageSettings>({{kPersistentNamespace, 20, 0}}));
clock()->Advance(base::TimeDelta::FromDays(367));
TryClearPages();
EXPECT_EQ(0, last_cleared_page_count());
@@ -293,7 +320,7 @@ TEST_F(OfflinePageStorageManagerTest, TestDeleteAsyncPages) {
TEST_F(OfflinePageStorageManagerTest, TestDeletionFailed) {
Initialize(std::vector<PageSettings>(
- {{kBookmarkNamespace, 10, 10}, {kLastNNamespace, 10, 10}}),
+ {{kOneWeekNamespace, 10, 10}, {kOneDayNamespace, 10, 10}}),
{kFreeSpaceNormal, 0}, TestOptions::DELETE_FAILURE);
TryClearPages();
EXPECT_EQ(20, last_cleared_page_count());
@@ -304,7 +331,7 @@ TEST_F(OfflinePageStorageManagerTest, TestDeletionFailed) {
TEST_F(OfflinePageStorageManagerTest, TestStorageTimeInterval) {
Initialize(std::vector<PageSettings>(
- {{kBookmarkNamespace, 10, 10}, {kLastNNamespace, 10, 10}}));
+ {{kOneWeekNamespace, 10, 10}, {kOneDayNamespace, 10, 10}}));
clock()->Advance(base::TimeDelta::FromMinutes(30));
TryClearPages();
EXPECT_EQ(20, last_cleared_page_count());
@@ -332,13 +359,13 @@ TEST_F(OfflinePageStorageManagerTest, TestStorageTimeInterval) {
}
TEST_F(OfflinePageStorageManagerTest, TestClearMultipleTimes) {
- Initialize(std::vector<PageSettings>({{kBookmarkNamespace, 30, 0},
- {kLastNNamespace, 100, 1},
- {kAsyncNamespace, 40, 0}}),
+ Initialize(std::vector<PageSettings>({{kOneWeekNamespace, 30, 0},
+ {kOneDayNamespace, 100, 1},
+ {kPersistentNamespace, 40, 0}}),
{1000 * (1 << 20), 0});
clock()->Advance(base::TimeDelta::FromMinutes(30));
LifetimePolicy policy =
- policy_controller()->GetPolicy(kLastNNamespace).lifetime_policy;
+ policy_controller()->GetPolicy(kOneDayNamespace).lifetime_policy;
TryClearPages();
EXPECT_EQ(1, last_cleared_page_count());
@@ -365,7 +392,7 @@ TEST_F(OfflinePageStorageManagerTest, TestClearMultipleTimes) {
// Adding more fresh pages to make it go over limit.
clock()->Advance(base::TimeDelta::FromMinutes(5));
- model()->AddPages({kBookmarkNamespace, 400, 0});
+ model()->AddPages({kOneWeekNamespace, 400, 0});
int64_t total_size_before = model()->GetTotalSize();
int64_t available_space = 300 * (1 << 20); // 300 MB
test_archive_manager()->SetValues({available_space, total_size_before});
diff --git a/chromium/components/offline_pages/core/offline_page_test_store.cc b/chromium/components/offline_pages/core/offline_page_test_store.cc
index 225d777694d..5ed9b202fc4 100644
--- a/chromium/components/offline_pages/core/offline_page_test_store.cc
+++ b/chromium/components/offline_pages/core/offline_page_test_store.cc
@@ -16,17 +16,24 @@ OfflinePageTestStore::OfflinePageTestStore(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
: task_runner_(task_runner),
scenario_(TestScenario::SUCCESSFUL),
- store_state_(StoreState::NOT_LOADED) {}
+ store_state_(StoreState::NOT_LOADED),
+ initialize_attempts_count_(0) {}
+// This ctor is used in tests to 'reload' the model. Therefore it starts
+// from NOT_LOADED and 0 attampts, to be able to verify those directly and not
+// accumulate form previous load. However, the set of test pages is preserved.
OfflinePageTestStore::OfflinePageTestStore(
const OfflinePageTestStore& other_store)
: task_runner_(other_store.task_runner_),
scenario_(other_store.scenario_),
+ store_state_(StoreState::NOT_LOADED),
+ initialize_attempts_count_(0),
offline_pages_(other_store.offline_pages_) {}
OfflinePageTestStore::~OfflinePageTestStore() {}
void OfflinePageTestStore::Initialize(const InitializeCallback& callback) {
+ initialize_attempts_count_++;
if (scenario_ == TestScenario::LOAD_FAILED_RESET_FAILED ||
scenario_ == TestScenario::LOAD_FAILED_RESET_SUCCESS) {
store_state_ = StoreState::FAILED_LOADING;
diff --git a/chromium/components/offline_pages/core/offline_page_test_store.h b/chromium/components/offline_pages/core/offline_page_test_store.h
index 7b7599d8c75..0b04b7948ea 100644
--- a/chromium/components/offline_pages/core/offline_page_test_store.h
+++ b/chromium/components/offline_pages/core/offline_page_test_store.h
@@ -61,11 +61,14 @@ class OfflinePageTestStore : public OfflinePageMetadataStore {
void set_test_scenario(TestScenario scenario) { scenario_ = scenario; };
+ int initialize_attempts_count() const { return initialize_attempts_count_; }
+
private:
OfflinePageItem last_saved_page_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
TestScenario scenario_;
StoreState store_state_;
+ int initialize_attempts_count_;
std::map<int64_t, OfflinePageItem> offline_pages_;
diff --git a/chromium/components/offline_pages/core/offline_page_types.h b/chromium/components/offline_pages/core/offline_page_types.h
index 4bb3342e1d1..e266bba419b 100644
--- a/chromium/components/offline_pages/core/offline_page_types.h
+++ b/chromium/components/offline_pages/core/offline_page_types.h
@@ -77,6 +77,7 @@ typedef base::Callback<void(const OfflinePageItem*)>
typedef base::Callback<void(const MultipleOfflinePageItemResult&)>
MultipleOfflinePageItemCallback;
typedef base::Callback<bool(const GURL&)> UrlPredicate;
+typedef base::Callback<void(int64_t)> SizeInBytesCallback;
} // namespace offline_pages
#endif // COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_TYPES_H_
diff --git a/chromium/components/offline_pages/core/prefetch/BUILD.gn b/chromium/components/offline_pages/core/prefetch/BUILD.gn
new file mode 100644
index 00000000000..ae365d2bd5a
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/BUILD.gn
@@ -0,0 +1,75 @@
+# Copyright 2017 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.
+
+if (is_android) {
+ import("//build/config/android/rules.gni")
+}
+import("//third_party/protobuf/proto_library.gni")
+
+static_library("prefetch") {
+ sources = [
+ "generate_page_bundle_request.cc",
+ "generate_page_bundle_request.h",
+ "get_operation_request.cc",
+ "get_operation_request.h",
+ "prefetch_dispatcher.h",
+ "prefetch_dispatcher_impl.cc",
+ "prefetch_dispatcher_impl.h",
+ "prefetch_item.cc",
+ "prefetch_item.h",
+ "prefetch_proto_utils.cc",
+ "prefetch_proto_utils.h",
+ "prefetch_request_fetcher.cc",
+ "prefetch_request_fetcher.h",
+ "prefetch_service.h",
+ "prefetch_service_impl.cc",
+ "prefetch_service_impl.h",
+ "prefetch_types.cc",
+ "prefetch_types.h",
+ ]
+
+ public_deps = [
+ ":proto",
+ ]
+ deps = [
+ "//base",
+ "//components/keyed_service/core",
+ "//components/offline_pages/core",
+ "//net:net",
+ "//url",
+ ]
+}
+
+proto_library("proto") {
+ sources = [
+ "proto/any.proto",
+ "proto/offline_pages.proto",
+ "proto/operation.proto",
+ "proto/status.proto",
+ "proto/timestamp.proto",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "generate_page_bundle_request_unittest.cc",
+ "get_operation_request_unittest.cc",
+ "prefetch_dispatcher_impl_unittest.cc",
+ "prefetch_item_unittest.cc",
+ "prefetch_request_fetcher_unittest.cc",
+ "prefetch_request_operation_response_unittest.cc",
+ "prefetch_request_test_base.cc",
+ "prefetch_request_test_base.h",
+ ]
+
+ deps = [
+ ":prefetch",
+ "//components/offline_pages/core",
+ "//net:test_support",
+ "//testing/gmock",
+ "//testing/gtest",
+ "//url",
+ ]
+}
diff --git a/chromium/components/offline_pages/core/prefetch/README.md b/chromium/components/offline_pages/core/prefetch/README.md
new file mode 100644
index 00000000000..46e5a0e5563
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/README.md
@@ -0,0 +1,6 @@
+# Prefetching Offline Pages: development guidelines
+
+* Implementations that are injected dependencies should always provide
+ lightweight construction and postpone heavier initialization (i.e. DB
+ connection) to a later moment. Lazy initialization upon first actual usage is
+ recommended.
diff --git a/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.cc b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.cc
new file mode 100644
index 00000000000..e6a3c99e38b
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.cc
@@ -0,0 +1,71 @@
+// Copyright 2017 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/offline_pages/core/prefetch/generate_page_bundle_request.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "components/offline_pages/core/prefetch/prefetch_proto_utils.h"
+#include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h"
+#include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+namespace {
+const char kGeneratePageBundleRequestURLPath[] = "v1:GeneratePageBundle";
+} // namespace
+
+GeneratePageBundleRequest::GeneratePageBundleRequest(
+ const std::string& user_agent,
+ const std::string& gcm_registration_id,
+ int max_bundle_size_bytes,
+ const std::vector<std::string>& page_urls,
+ net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback)
+ : callback_(callback) {
+ proto::GeneratePageBundleRequest request;
+ request.set_user_agent(user_agent);
+ request.set_max_bundle_size_bytes(max_bundle_size_bytes);
+ request.set_output_format(proto::FORMAT_MHTML);
+ request.set_gcm_registration_id(gcm_registration_id);
+
+ for (const auto& page_url : page_urls) {
+ proto::PageParameters* page = request.add_pages();
+ page->set_url(page_url);
+ page->set_transformation(proto::NO_TRANSFORMATION);
+ }
+
+ std::string upload_data;
+ request.SerializeToString(&upload_data);
+
+ fetcher_ = PrefetchRequestFetcher::CreateForPost(
+ kGeneratePageBundleRequestURLPath, upload_data, request_context_getter,
+ base::Bind(&GeneratePageBundleRequest::OnCompleted,
+ // Fetcher is owned by this instance.
+ base::Unretained(this)));
+}
+
+GeneratePageBundleRequest::~GeneratePageBundleRequest() {}
+
+void GeneratePageBundleRequest::OnCompleted(PrefetchRequestStatus status,
+ const std::string& data) {
+ if (status != PrefetchRequestStatus::SUCCESS) {
+ callback_.Run(status, std::vector<RenderPageInfo>());
+ return;
+ }
+
+ std::vector<RenderPageInfo> pages;
+ if (!ParseOperationResponse(data, &pages)) {
+ callback_.Run(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ std::vector<RenderPageInfo>());
+ return;
+ }
+
+ callback_.Run(PrefetchRequestStatus::SUCCESS, pages);
+}
+
+} // offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.h b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.h
new file mode 100644
index 00000000000..43113135169
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.h
@@ -0,0 +1,44 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_GENERATE_PAGE_BUNDLE_REQUEST_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_GENERATE_PAGE_BUNDLE_REQUEST_H_
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace offline_pages {
+
+class PrefetchRequestFetcher;
+
+class GeneratePageBundleRequest {
+ public:
+ GeneratePageBundleRequest(
+ const std::string& user_agent,
+ const std::string& gcm_registration_id,
+ int max_bundle_size_bytes,
+ const std::vector<std::string>& page_urls,
+ net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback);
+ ~GeneratePageBundleRequest();
+
+ private:
+ void OnCompleted(PrefetchRequestStatus status, const std::string& data);
+
+ PrefetchRequestFinishedCallback callback_;
+ std::unique_ptr<PrefetchRequestFetcher> fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeneratePageBundleRequest);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_GENERATE_PAGE_BUNDLE_REQUEST_H_
diff --git a/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request_unittest.cc b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request_unittest.cc
new file mode 100644
index 00000000000..297b3e8aa8f
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request_unittest.cc
@@ -0,0 +1,98 @@
+// Copyright 2017 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/offline_pages/core/prefetch/generate_page_bundle_request.h"
+
+#include "base/test/mock_callback.h"
+#include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+#include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Eq;
+using testing::SaveArg;
+
+namespace offline_pages {
+
+namespace {
+const char kTestURL[] = "http://example.com";
+const char kTestURL2[] = "http://example.com/2";
+const char kTestUserAgent[] = "Test User Agent";
+const char kTestGCMID[] = "Test GCM ID";
+const int kTestMaxBundleSize = 100000;
+} // namespace
+
+// All tests cases here only validate the request data and check for general
+// http response. The tests for the Operation proto data returned in the http
+// response are covered in PrefetchRequestOperationResponseTest.
+class GeneratePageBundleRequestTest : public PrefetchRequestTestBase {
+ public:
+ std::unique_ptr<GeneratePageBundleRequest> CreateRequest(
+ const PrefetchRequestFinishedCallback& callback) {
+ std::vector<std::string> page_urls = {kTestURL, kTestURL2};
+ return std::unique_ptr<GeneratePageBundleRequest>(
+ new GeneratePageBundleRequest(kTestUserAgent, kTestGCMID,
+ kTestMaxBundleSize, page_urls,
+ request_context(), callback));
+ }
+};
+
+TEST_F(GeneratePageBundleRequestTest, RequestData) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ std::unique_ptr<GeneratePageBundleRequest> request(
+ CreateRequest(callback.Get()));
+
+ net::TestURLFetcher* fetcher = GetRunningFetcher();
+ EXPECT_FALSE(fetcher->upload_content_type().empty());
+ EXPECT_FALSE(fetcher->upload_data().empty());
+
+ proto::GeneratePageBundleRequest bundle_data;
+ ASSERT_TRUE(bundle_data.ParseFromString(fetcher->upload_data()));
+ EXPECT_EQ(kTestUserAgent, bundle_data.user_agent());
+ EXPECT_EQ(proto::FORMAT_MHTML, bundle_data.output_format());
+ EXPECT_EQ(kTestMaxBundleSize, bundle_data.max_bundle_size_bytes());
+ EXPECT_EQ(kTestGCMID, bundle_data.gcm_registration_id());
+ ASSERT_EQ(2, bundle_data.pages_size());
+ EXPECT_EQ(kTestURL, bundle_data.pages(0).url());
+ EXPECT_EQ(proto::NO_TRANSFORMATION, bundle_data.pages(0).transformation());
+ EXPECT_EQ(kTestURL2, bundle_data.pages(1).url());
+ EXPECT_EQ(proto::NO_TRANSFORMATION, bundle_data.pages(1).transformation());
+}
+
+TEST_F(GeneratePageBundleRequestTest, EmptyResponse) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ std::unique_ptr<GeneratePageBundleRequest> request(
+ CreateRequest(callback.Get()));
+
+ PrefetchRequestStatus status;
+ std::vector<RenderPageInfo> pages;
+ EXPECT_CALL(callback, Run(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages)));
+ RespondWithData("");
+
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF, status);
+ EXPECT_TRUE(pages.empty());
+}
+
+TEST_F(GeneratePageBundleRequestTest, InvalidResponse) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ std::unique_ptr<GeneratePageBundleRequest> request(
+ CreateRequest(callback.Get()));
+
+ PrefetchRequestStatus status;
+ std::vector<RenderPageInfo> pages;
+ EXPECT_CALL(callback, Run(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages)));
+ RespondWithData("Some invalid data");
+
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF, status);
+ EXPECT_TRUE(pages.empty());
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/get_operation_request.cc b/chromium/components/offline_pages/core/prefetch/get_operation_request.cc
new file mode 100644
index 00000000000..1f3a78ac5b5
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/get_operation_request.cc
@@ -0,0 +1,54 @@
+// Copyright 2017 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/offline_pages/core/prefetch/get_operation_request.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "components/offline_pages/core/prefetch/prefetch_proto_utils.h"
+#include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+namespace {
+const char kGetOperationURLPath[] = "v1/operations/";
+} // namespace
+
+GetOperationRequest::GetOperationRequest(
+ const std::string& name,
+ net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback)
+ : callback_(callback) {
+ std::string path(kGetOperationURLPath);
+ path += name;
+ fetcher_ = PrefetchRequestFetcher::CreateForGet(
+ path, request_context_getter,
+ base::Bind(&GetOperationRequest::OnCompleted,
+ // Fetcher is owned by this instance.
+ base::Unretained(this)));
+}
+
+GetOperationRequest::~GetOperationRequest() {}
+
+void GetOperationRequest::OnCompleted(PrefetchRequestStatus status,
+ const std::string& data) {
+ if (status != PrefetchRequestStatus::SUCCESS) {
+ callback_.Run(status, std::vector<RenderPageInfo>());
+ return;
+ }
+
+ std::vector<RenderPageInfo> pages;
+ if (!ParseOperationResponse(data, &pages)) {
+ callback_.Run(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ std::vector<RenderPageInfo>());
+ return;
+ }
+
+ callback_.Run(PrefetchRequestStatus::SUCCESS, pages);
+}
+
+} // offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/get_operation_request.h b/chromium/components/offline_pages/core/prefetch/get_operation_request.h
new file mode 100644
index 00000000000..6793f2eb229
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/get_operation_request.h
@@ -0,0 +1,45 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_GET_OPERATION_REQUEST_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_GET_OPERATION_REQUEST_H_
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace offline_pages {
+
+class PrefetchRequestFetcher;
+
+// Sends this request to find out the current state of an operation that is
+// triggered by GeneratePageBundleRequest but not finished at that time.
+class GetOperationRequest {
+ public:
+ // |name| identifies the operation triggered by the GeneratePageBundleRequest.
+ // It is retrieved from the operation data returned in the
+ // GeneratePageBundleRequest response.
+ GetOperationRequest(const std::string& name,
+ net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback);
+ ~GetOperationRequest();
+
+ private:
+ void OnCompleted(PrefetchRequestStatus status, const std::string& data);
+
+ PrefetchRequestFinishedCallback callback_;
+ std::unique_ptr<PrefetchRequestFetcher> fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetOperationRequest);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_GET_OPERATION_REQUEST_H_
diff --git a/chromium/components/offline_pages/core/prefetch/get_operation_request_unittest.cc b/chromium/components/offline_pages/core/prefetch/get_operation_request_unittest.cc
new file mode 100644
index 00000000000..e0535d9aeee
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/get_operation_request_unittest.cc
@@ -0,0 +1,83 @@
+// Copyright 2017 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/offline_pages/core/prefetch/get_operation_request.h"
+
+#include "base/test/mock_callback.h"
+#include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+#include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Eq;
+using testing::SaveArg;
+
+namespace offline_pages {
+
+namespace {
+const char kTestMethodName[] = "Test name";
+} // namespace
+
+// All tests cases here only validate the request data and check for general
+// http response. The tests for the Operation proto data returned in the http
+// response are covered in PrefetchRequestOperationResponseTest.
+class GetOperationRequestTest : public PrefetchRequestTestBase {
+ public:
+ std::unique_ptr<GetOperationRequest> CreateRequest(
+ const PrefetchRequestFinishedCallback& callback) {
+ return std::unique_ptr<GetOperationRequest>(
+ new GetOperationRequest(kTestMethodName, request_context(), callback));
+ }
+};
+
+TEST_F(GetOperationRequestTest, RequestData) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ std::unique_ptr<GetOperationRequest> request(CreateRequest(callback.Get()));
+
+ net::TestURLFetcher* fetcher = GetRunningFetcher();
+ net::HttpRequestHeaders headers;
+ fetcher->GetExtraRequestHeaders(&headers);
+ std::string content_type_header;
+ headers.GetHeader(net::HttpRequestHeaders::kContentType,
+ &content_type_header);
+ EXPECT_EQ("application/x-protobuf", content_type_header);
+
+ EXPECT_TRUE(fetcher->upload_content_type().empty());
+ EXPECT_TRUE(fetcher->upload_data().empty());
+}
+
+TEST_F(GetOperationRequestTest, EmptyResponse) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ std::unique_ptr<GetOperationRequest> request(CreateRequest(callback.Get()));
+
+ PrefetchRequestStatus status;
+ std::vector<RenderPageInfo> pages;
+ EXPECT_CALL(callback, Run(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages)));
+ RespondWithData("");
+
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF, status);
+ EXPECT_TRUE(pages.empty());
+}
+
+TEST_F(GetOperationRequestTest, InvalidResponse) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ std::unique_ptr<GetOperationRequest> request(CreateRequest(callback.Get()));
+
+ PrefetchRequestStatus status;
+ std::vector<RenderPageInfo> pages;
+ EXPECT_CALL(callback, Run(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages)));
+ RespondWithData("Some invalid data");
+
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF, status);
+ EXPECT_TRUE(pages.empty());
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher.h b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher.h
new file mode 100644
index 00000000000..36f9b206de3
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher.h
@@ -0,0 +1,78 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "components/offline_pages/core/offline_page_item.h"
+#include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
+
+class GURL;
+
+namespace offline_pages {
+
+// Serves as the entry point for external signals into the prefetching system.
+// It listens to these events, converts them to the appropriate internal tasks
+// and manage their execution and inter-dependencies.
+class PrefetchDispatcher {
+ public:
+ struct PrefetchURL {
+ // Used to differentiate URLs from different sources. |name_space| should
+ // be unique per source. |id| can be anything useful to identify the page,
+ // but will not be used for deduplication.
+ ClientId client_id;
+
+ // This URL will be prefetched by the system.
+ GURL url;
+ };
+
+ // A |ScopedBackgroundTask| is created when we are running in a background
+ // task. Destroying this object should notify the system that we are done
+ // processing the background task.
+ class ScopedBackgroundTask {
+ public:
+ ScopedBackgroundTask() = default;
+ virtual ~ScopedBackgroundTask() = default;
+
+ // Used on destruction to inform the system about whether rescheduling is
+ // required.
+ virtual void SetNeedsReschedule(bool reschedule) = 0;
+ };
+
+ virtual ~PrefetchDispatcher() = default;
+
+ // Called when a consumer has candidate URLs for the system to prefetch.
+ // Duplicates are accepted by the PrefetchDispatcher but ignored.
+ virtual void AddCandidatePrefetchURLs(
+ const std::vector<PrefetchURL>& prefetch_urls) = 0;
+
+ // Called when all existing suggestions are no longer considered valid for a
+ // given namespace. The prefetch system should remove any URLs that
+ // have not yet started downloading within that namespace.
+ virtual void RemoveAllUnprocessedPrefetchURLs(
+ const std::string& name_space) = 0;
+
+ // Called to invalidate a single PrefetchURL entry identified by |client_id|.
+ // If multiple have the same |client_id|, they will all be removed.
+ virtual void RemovePrefetchURLsByClientId(const ClientId& client_id) = 0;
+
+ // Called when Android OS has scheduled us for background work. When
+ // destroyed, |task| will call back and inform the OS that we are done work
+ // (if required). |task| also manages rescheduling behavior.
+ virtual void BeginBackgroundTask(
+ std::unique_ptr<ScopedBackgroundTask> task) = 0;
+
+ // Called when a task must stop immediately due to system constraints. After
+ // this call completes, the system will reschedule the task based on whether
+ // SetNeedsReschedule has been called.
+ virtual void StopBackgroundTask(ScopedBackgroundTask* task) = 0;
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
new file mode 100644
index 00000000000..3c84ca5e937
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
@@ -0,0 +1,38 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_dispatcher_impl.h"
+
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+PrefetchDispatcherImpl::PrefetchDispatcherImpl() {}
+
+PrefetchDispatcherImpl::~PrefetchDispatcherImpl() = default;
+
+void PrefetchDispatcherImpl::AddCandidatePrefetchURLs(
+ const std::vector<PrefetchURL>& url_suggestions) {
+ NOTIMPLEMENTED();
+}
+void PrefetchDispatcherImpl::RemoveAllUnprocessedPrefetchURLs(
+ const std::string& name_space) {
+ NOTIMPLEMENTED();
+}
+
+void PrefetchDispatcherImpl::RemovePrefetchURLsByClientId(
+ const ClientId& client_id) {
+ NOTIMPLEMENTED();
+}
+
+void PrefetchDispatcherImpl::BeginBackgroundTask(
+ std::unique_ptr<ScopedBackgroundTask> task) {
+ NOTIMPLEMENTED();
+}
+
+void PrefetchDispatcherImpl::StopBackgroundTask(ScopedBackgroundTask* task) {
+ NOTIMPLEMENTED();
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h
new file mode 100644
index 00000000000..e826d0a9f9c
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h
@@ -0,0 +1,32 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_IMPL_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_IMPL_H_
+
+#include "base/macros.h"
+#include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
+
+namespace offline_pages {
+
+class PrefetchDispatcherImpl : public PrefetchDispatcher {
+ public:
+ PrefetchDispatcherImpl();
+ ~PrefetchDispatcherImpl() override;
+
+ // PrefetchDispatcher implementation:
+ void AddCandidatePrefetchURLs(
+ const std::vector<PrefetchURL>& suggested_urls) override;
+ void RemoveAllUnprocessedPrefetchURLs(const std::string& name_space) override;
+ void RemovePrefetchURLsByClientId(const ClientId& client_id) override;
+ void BeginBackgroundTask(std::unique_ptr<ScopedBackgroundTask> task) override;
+ void StopBackgroundTask(ScopedBackgroundTask* task) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PrefetchDispatcherImpl);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_IMPL_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
new file mode 100644
index 00000000000..0a0bd961d48
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
@@ -0,0 +1,24 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_dispatcher_impl.h"
+
+#include "base/memory/ptr_util.h"
+#include "components/offline_pages/core/client_namespace_constants.h"
+#include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+TEST(PrefetchDispatcherTest, DispatcherDoesNotCrash) {
+ PrefetchDispatcherImpl dispatcher;
+
+ dispatcher.AddCandidatePrefetchURLs(
+ std::vector<PrefetchDispatcher::PrefetchURL>());
+ dispatcher.RemoveAllUnprocessedPrefetchURLs(kSuggestedArticlesNamespace);
+ dispatcher.RemovePrefetchURLsByClientId({kSuggestedArticlesNamespace, "123"});
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_item.cc b/chromium/components/offline_pages/core/prefetch/prefetch_item.cc
new file mode 100644
index 00000000000..8e1119d4f69
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_item.cc
@@ -0,0 +1,32 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_item.h"
+
+namespace offline_pages {
+
+PrefetchItem::PrefetchItem() = default;
+
+PrefetchItem::PrefetchItem(const PrefetchItem& other) = default;
+
+PrefetchItem::~PrefetchItem(){};
+
+bool PrefetchItem::operator==(const PrefetchItem& other) const {
+ return guid == other.guid && client_name_space == other.client_name_space &&
+ client_id == other.client_id && state == other.state &&
+ url == other.url && final_archived_url == other.final_archived_url &&
+ request_archive_attempt_count == other.request_archive_attempt_count &&
+ operation_name == other.operation_name &&
+ archive_body_name == other.archive_body_name &&
+ archive_body_length == other.archive_body_length &&
+ creation_time == other.creation_time &&
+ freshness_time == other.freshness_time &&
+ error_code == other.error_code;
+}
+
+bool PrefetchItem::operator!=(const PrefetchItem& other) const {
+ return !(*this == other);
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_item.h b/chromium/components/offline_pages/core/prefetch/prefetch_item.h
new file mode 100644
index 00000000000..e648ba9290a
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_item.h
@@ -0,0 +1,92 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_ITEM_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_ITEM_H_
+
+#include <string>
+
+#include "base/time/time.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+// Data object representing an item progressing through the prefetching process
+// from the moment a URL is requested by a client until its processing is done,
+// successfully or not.
+// Instances of this class are in-memory representations of items in (or to be
+// inserted into) the persistent prefetching data store.
+struct PrefetchItem {
+ PrefetchItem();
+ explicit PrefetchItem(const PrefetchItem& other);
+
+ ~PrefetchItem();
+
+ bool operator==(const PrefetchItem& other) const;
+ bool operator!=(const PrefetchItem& other) const;
+
+ // Primary key/ID for this prefetch item (See |base::GenerateGUID()|). This
+ // value will be reused when communicating with other systems accepting GUID
+ // identifiers for operations linked to this item.
+ std::string guid;
+
+ // Externally provided namespace and id values so that this item can be
+ // uniquely identified by the client requesting it. It is the client's
+ // responsibility to make sure the id is unique within the context of its
+ // assigned namespace.
+ std::string client_name_space;
+ std::string client_id;
+
+ // Current prefetching progress state.
+ PrefetchItemState state = PrefetchItemState::NEW_REQUEST;
+
+ // The URL of the page the client requested to be prefetched.
+ GURL url;
+
+ // The final URL whose page was actually included in a successfully created
+ // archive after redirects, if it was different than the |url|. It will be
+ // left empty if they are the same.
+ GURL final_archived_url;
+
+ // Number of times an attempt was made to generate an archive for this item.
+ int request_archive_attempt_count = 0;
+
+ // Name used to identify the archiving operation being executed by the
+ // prefetching service for processing this item's URL. It is used as the
+ // |operation_name| reported by an incoming GCM message and in the
+ // |GetOperationRequest.name| field of the respective GetOperation RPC.
+ std::string operation_name;
+
+ // The name specific to this item's archive that can be used to build the URL
+ // to allow the downloading of that archive. Will only be set when and if an
+ // archive was successfully created for this item. It will be kept empty
+ // otherwise.
+ std::string archive_body_name;
+
+ // The final size of the generated archive that contains this item's page
+ // snapshot. The archive might also include other articles in a bundle so the
+ // length is not necessarily directly related to this item's page contents.
+ // Will only be set when and if an archive was successfully created for this
+ // item. It holds a negative value otherwise.
+ int64_t archive_body_length = -1;
+
+ // Time when this item was inserted into the store with the URL to be
+ // prefetched.
+ base::Time creation_time;
+
+ // Time used for the expiration of the item depending on the applicable policy
+ // for its current state. It is initially set with the same value as
+ // |creation_time|. Its value is "refreshed" to the current time on some state
+ // transitions considered significant for the prefetching process.
+ base::Time freshness_time;
+
+ // The reason why the item was set to the FINISHED state. Should be
+ // disregarded until reaching that state.
+ PrefetchItemErrorCode error_code = PrefetchItemErrorCode::SUCCESS;
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_ITEM_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_item_unittest.cc b/chromium/components/offline_pages/core/prefetch/prefetch_item_unittest.cc
new file mode 100644
index 00000000000..68433d477dc
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_item_unittest.cc
@@ -0,0 +1,84 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_item.h"
+
+#include "base/time/time.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+TEST(PrefetchItemTest, OperatorEqualsAndCopyConstructor) {
+ PrefetchItem item1;
+ EXPECT_EQ(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+
+ item1.guid = "A";
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.client_name_space = "B";
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.client_id = "C";
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.state = PrefetchItemState::AWAITING_GCM;
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.url = GURL("http://test.com");
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.final_archived_url = GURL("http://test.com/final");
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.request_archive_attempt_count = 10;
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.operation_name = "D";
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.archive_body_name = "E";
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.archive_body_length = 20;
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.creation_time = base::Time::FromJavaTime(1000L);
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.freshness_time = base::Time::FromJavaTime(2000L);
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+ item1 = PrefetchItem();
+
+ item1.error_code = PrefetchItemErrorCode::EXPIRED;
+ EXPECT_NE(item1, PrefetchItem());
+ EXPECT_EQ(item1, PrefetchItem(item1));
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.cc b/chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.cc
new file mode 100644
index 00000000000..0fe504049bc
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.cc
@@ -0,0 +1,140 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_proto_utils.h"
+
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "components/offline_pages/core/prefetch/proto/any.pb.h"
+#include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
+#include "components/offline_pages/core/prefetch/proto/operation.pb.h"
+
+namespace offline_pages {
+
+const char kPageBundleTypeURL[] =
+ "type.googleapis.com/google.internal.chrome.offlinepages.v1.PageBundle";
+
+namespace {
+
+// Parse PageBundle data stored as Any proto data. True is returned when the
+// parsing succeeds and the result pages are stored in |pages|.
+bool ParsePageBundleInAnyData(const proto::Any& any_data,
+ std::vector<RenderPageInfo>* pages) {
+ if (any_data.type_url() != kPageBundleTypeURL) {
+ DVLOG(1) << "Wrong type url in any data";
+ return false;
+ }
+
+ proto::PageBundle page_bundle;
+ if (!page_bundle.ParseFromString(any_data.value())) {
+ DVLOG(1) << "Failed to parse PageBundle in any data";
+ return false;
+ }
+
+ if (!page_bundle.archives_size()) {
+ DVLOG(1) << "No archive in PageBundle";
+ return false;
+ }
+
+ for (int i = 0; i < page_bundle.archives_size(); ++i) {
+ const proto::Archive& archive = page_bundle.archives(i);
+
+ if (!archive.page_infos_size()) {
+ DVLOG(1) << "No page in archive";
+ return false;
+ ;
+ }
+
+ // Only one page is available in PageInfos.
+ const proto::PageInfo& page_info = archive.page_infos(0);
+
+ if (page_info.url().empty()) {
+ DVLOG(1) << "Empty page url";
+ return false;
+ ;
+ }
+
+ RenderPageInfo page;
+ page.url = page_info.url();
+ page.redirect_url = page_info.redirect_url();
+ if (page_info.has_status()) {
+ switch (page_info.status().code()) {
+ case proto::OK:
+ page.status = RenderStatus::RENDERED;
+ break;
+ case proto::NOT_FOUND:
+ page.status = RenderStatus::PENDING;
+ break;
+ case proto::FAILED_PRECONDITION:
+ page.status = RenderStatus::EXCEEDED_LIMIT;
+ break;
+ case proto::UNKNOWN:
+ page.status = RenderStatus::FAILED;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ } else {
+ page.status = RenderStatus::RENDERED;
+ }
+
+ if (page.status == RenderStatus::RENDERED) {
+ page.body_name = archive.body_name();
+ page.body_length = archive.body_length();
+ page.render_time =
+ base::Time::FromJavaTime(page_info.render_time().seconds() * 1000 +
+ page_info.render_time().nanos() / 1000000);
+ }
+
+ DVLOG(1) << "Got page " << page.url << " " << static_cast<int>(page.status)
+ << " " << page.body_name << " " << page.body_length;
+ pages->push_back(page);
+ }
+
+ return true;
+}
+
+bool ParseDoneOperationResponse(const proto::Operation& operation,
+ std::vector<RenderPageInfo>* pages) {
+ switch (operation.result_case()) {
+ case proto::Operation::kError:
+ DCHECK_NE(proto::OK, operation.error().code());
+ DVLOG(1) << "Error found in operation: " << operation.error().code()
+ << operation.error().message();
+ return false;
+ case proto::Operation::kResponse:
+ return ParsePageBundleInAnyData(operation.response(), pages);
+ default:
+ DVLOG(1) << "Result not set in operation";
+ return false;
+ }
+}
+
+bool ParsePendingOperationResponse(const proto::Operation& operation,
+ std::vector<RenderPageInfo>* pages) {
+ if (!operation.has_metadata()) {
+ DVLOG(1) << "metadata not found in GeneratePageBundle response";
+ return false;
+ }
+ return ParsePageBundleInAnyData(operation.metadata(), pages);
+}
+
+} // namespace
+
+bool ParseOperationResponse(const std::string& data,
+ std::vector<RenderPageInfo>* pages) {
+ proto::Operation operation;
+ if (!operation.ParseFromString(data)) {
+ DVLOG(1) << "Failed to parse operation";
+ return false;
+ }
+
+ if (operation.done())
+ return ParseDoneOperationResponse(operation, pages);
+ else
+ return ParsePendingOperationResponse(operation, pages);
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.h b/chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.h
new file mode 100644
index 00000000000..cc77de109bd
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_proto_utils.h
@@ -0,0 +1,22 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_PROTO_UTILS_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_PROTO_UTILS_H_
+
+#include <vector>
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+
+namespace offline_pages {
+
+// The fully qualified type name for PageBundle defined in proto.
+extern const char kPageBundleTypeURL[];
+
+// Used to parse the Operation serialized in binary proto |data|.
+bool ParseOperationResponse(const std::string& data,
+ std::vector<RenderPageInfo>* pages);
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_PROTO_UTILS_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc
new file mode 100644
index 00000000000..1974a1bcc32
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc
@@ -0,0 +1,142 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_request_fetcher.h"
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_status.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+namespace {
+
+const char kPrefetchServer[] =
+ "http://staging-offlinepages-pa.sandbox.googleapis.com/";
+
+// Content type needed in order to communicate with the server in binary
+// proto format.
+const char kRequestContentType[] = "application/x-protobuf";
+
+GURL CompleteURL(const std::string& url_path) {
+ GURL::Replacements replacements;
+ replacements.SetPathStr(url_path);
+ return GURL(kPrefetchServer).ReplaceComponents(replacements);
+}
+
+} // namespace
+
+// static
+std::unique_ptr<PrefetchRequestFetcher> PrefetchRequestFetcher::CreateForGet(
+ const std::string& url_path,
+ net::URLRequestContextGetter* request_context_getter,
+ const FinishedCallback& callback) {
+ return base::WrapUnique(new PrefetchRequestFetcher(
+ url_path, std::string(), request_context_getter, callback));
+}
+
+// static
+std::unique_ptr<PrefetchRequestFetcher> PrefetchRequestFetcher::CreateForPost(
+ const std::string& url_path,
+ const std::string& message,
+ net::URLRequestContextGetter* request_context_getter,
+ const FinishedCallback& callback) {
+ return base::WrapUnique(new PrefetchRequestFetcher(
+ url_path, message, request_context_getter, callback));
+}
+
+PrefetchRequestFetcher::PrefetchRequestFetcher(
+ const std::string& url_path,
+ const std::string& message,
+ net::URLRequestContextGetter* request_context_getter,
+ const FinishedCallback& callback)
+ : request_context_getter_(request_context_getter), callback_(callback) {
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("offline_prefetch", R"(
+ semantics {
+ sender: "Offline Prefetch"
+ description:
+ "Chromium interacts with Offline Page Service to prefetch "
+ "suggested website resources."
+ trigger:
+ "When there are suggested website resources to fetch."
+ data:
+ "URLs of the suggested website resources to fetch."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can enable or disable the offline prefetch by toggling"
+ "chrome://flags#offline-prefetch in Chromium on Android."
+ policy_exception_justification:
+ "Not implemented, considered not useful."
+ })");
+ url_fetcher_ = net::URLFetcher::Create(
+ CompleteURL(url_path),
+ message.empty() ? net::URLFetcher::GET : net::URLFetcher::POST, this,
+ traffic_annotation);
+ url_fetcher_->SetRequestContext(request_context_getter_.get());
+ url_fetcher_->SetAutomaticallyRetryOn5xx(false);
+ url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(0);
+ if (message.empty()) {
+ std::string extra_header(net::HttpRequestHeaders::kContentType);
+ extra_header += ": ";
+ extra_header += kRequestContentType;
+ url_fetcher_->AddExtraRequestHeader(extra_header);
+ } else {
+ url_fetcher_->SetUploadData(kRequestContentType, message);
+ }
+ url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
+ url_fetcher_->Start();
+}
+
+PrefetchRequestFetcher::~PrefetchRequestFetcher() {}
+
+void PrefetchRequestFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
+ std::string data;
+ PrefetchRequestStatus status = ParseResponse(source, &data);
+
+ // TODO(jianli): Report UMA.
+
+ callback_.Run(status, data);
+}
+
+PrefetchRequestStatus PrefetchRequestFetcher::ParseResponse(
+ const net::URLFetcher* source,
+ std::string* data) {
+ if (!source->GetStatus().is_success()) {
+ net::Error net_error = source->GetStatus().ToNetError();
+ DVLOG(1) << "Net error: " << net_error;
+ return (net_error == net::ERR_BLOCKED_BY_ADMINISTRATOR)
+ ? PrefetchRequestStatus::SHOULD_SUSPEND
+ : PrefetchRequestStatus::SHOULD_RETRY_WITHOUT_BACKOFF;
+ }
+
+ net::HttpStatusCode response_status =
+ static_cast<net::HttpStatusCode>(source->GetResponseCode());
+ if (response_status != net::HTTP_OK) {
+ DVLOG(1) << "HTTP status: " << response_status;
+ return (response_status == net::HTTP_NOT_IMPLEMENTED)
+ ? PrefetchRequestStatus::SHOULD_SUSPEND
+ : PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF;
+ }
+
+ if (!source->GetResponseAsString(data) || data->empty()) {
+ DVLOG(1) << "Failed to get response or empty response";
+ return PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF;
+ }
+
+ return PrefetchRequestStatus::SUCCESS;
+}
+
+} // offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h
new file mode 100644
index 00000000000..c24515ecf94
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h
@@ -0,0 +1,64 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_REQUEST_FETCHER_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_REQUEST_FETCHER_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+#include "net/url_request/url_fetcher_delegate.h"
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace offline_pages {
+
+// Asynchronously fetches the offline prefetch related data from the server.
+class PrefetchRequestFetcher : public net::URLFetcherDelegate {
+ public:
+ using FinishedCallback = base::Callback<void(PrefetchRequestStatus status,
+ const std::string& data)>;
+
+ // Creates a fetcher that will sends a GET request to the server.
+ static std::unique_ptr<PrefetchRequestFetcher> CreateForGet(
+ const std::string& url_path,
+ net::URLRequestContextGetter* request_context_getter,
+ const FinishedCallback& callback);
+
+ // Creates a fetcher that will sends a POST request to the server.
+ static std::unique_ptr<PrefetchRequestFetcher> CreateForPost(
+ const std::string& url_path,
+ const std::string& message,
+ net::URLRequestContextGetter* request_context_getter,
+ const FinishedCallback& callback);
+
+ ~PrefetchRequestFetcher() override;
+
+ // URLFetcherDelegate implementation.
+ void OnURLFetchComplete(const net::URLFetcher* source) override;
+
+ private:
+ // If |message| is empty, the GET request is sent. Otherwise, the POST request
+ // is sent with |message| as post data.
+ PrefetchRequestFetcher(const std::string& url_path,
+ const std::string& message,
+ net::URLRequestContextGetter* request_context_getter,
+ const FinishedCallback& callback);
+
+ PrefetchRequestStatus ParseResponse(const net::URLFetcher* source,
+ std::string* data);
+
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+ std::unique_ptr<net::URLFetcher> url_fetcher_;
+ FinishedCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefetchRequestFetcher);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_REQUEST_FETCHER_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc
new file mode 100644
index 00000000000..3dbed4f1221
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc
@@ -0,0 +1,140 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_request_fetcher.h"
+
+#include "base/test/mock_callback.h"
+#include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Eq;
+using testing::SaveArg;
+
+namespace offline_pages {
+
+namespace {
+const char kTestURLPath[] = "/test";
+const char kTestMessage[] = "Testing";
+} // namespace
+
+class PrefetchRequestFetcherTest : public PrefetchRequestTestBase {
+ public:
+ PrefetchRequestStatus RunFetcherWithNetError(net::Error net_error);
+ PrefetchRequestStatus RunFetcherWithHttpError(int http_error);
+ PrefetchRequestStatus RunFetcherWithData(const std::string& response_data,
+ std::string* data_received);
+
+ private:
+ PrefetchRequestStatus RunFetcher(
+ const base::Callback<void(void)>& respond_callback,
+ std::string* data_received);
+};
+
+PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcherWithNetError(
+ net::Error net_error) {
+ std::string data_received;
+ PrefetchRequestStatus status =
+ RunFetcher(base::Bind(&PrefetchRequestTestBase::RespondWithNetError,
+ base::Unretained(this), net_error),
+ &data_received);
+ EXPECT_TRUE(data_received.empty());
+ return status;
+}
+
+PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcherWithHttpError(
+ int http_error) {
+ std::string data_received;
+ PrefetchRequestStatus status =
+ RunFetcher(base::Bind(&PrefetchRequestTestBase::RespondWithHttpError,
+ base::Unretained(this), http_error),
+ &data_received);
+ EXPECT_TRUE(data_received.empty());
+ return status;
+}
+
+PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcherWithData(
+ const std::string& response_data,
+ std::string* data_received) {
+ return RunFetcher(base::Bind(&PrefetchRequestTestBase::RespondWithData,
+ base::Unretained(this), response_data),
+ data_received);
+}
+
+PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcher(
+ const base::Callback<void(void)>& respond_callback,
+ std::string* data_received) {
+ base::MockCallback<PrefetchRequestFetcher::FinishedCallback> callback;
+ std::unique_ptr<PrefetchRequestFetcher> fetcher =
+ PrefetchRequestFetcher::CreateForPost(kTestURLPath, kTestMessage,
+ request_context(), callback.Get());
+
+ PrefetchRequestStatus status;
+ std::string data;
+ EXPECT_CALL(callback, Run(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&data)));
+ respond_callback.Run();
+
+ *data_received = data;
+ return status;
+}
+
+TEST_F(PrefetchRequestFetcherTest, NetErrors) {
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_SUSPEND,
+ RunFetcherWithNetError(net::ERR_BLOCKED_BY_ADMINISTRATOR));
+
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITHOUT_BACKOFF,
+ RunFetcherWithNetError(net::ERR_INTERNET_DISCONNECTED));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITHOUT_BACKOFF,
+ RunFetcherWithNetError(net::ERR_NETWORK_CHANGED));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITHOUT_BACKOFF,
+ RunFetcherWithNetError(net::ERR_CONNECTION_RESET));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITHOUT_BACKOFF,
+ RunFetcherWithNetError(net::ERR_CONNECTION_CLOSED));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITHOUT_BACKOFF,
+ RunFetcherWithNetError(net::ERR_CONNECTION_REFUSED));
+}
+
+TEST_F(PrefetchRequestFetcherTest, HttpErrors) {
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_SUSPEND,
+ RunFetcherWithHttpError(net::HTTP_NOT_IMPLEMENTED));
+
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_BAD_REQUEST));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_UNAUTHORIZED));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_NOT_FOUND));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_CONFLICT));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_INTERNAL_SERVER_ERROR));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_BAD_GATEWAY));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_SERVICE_UNAVAILABLE));
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithHttpError(net::HTTP_GATEWAY_TIMEOUT));
+}
+
+TEST_F(PrefetchRequestFetcherTest, EmptyResponse) {
+ std::string data;
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ RunFetcherWithData("", &data));
+ EXPECT_TRUE(data.empty());
+}
+
+TEST_F(PrefetchRequestFetcherTest, Success) {
+ std::string data;
+ EXPECT_EQ(PrefetchRequestStatus::SUCCESS,
+ RunFetcherWithData("Any data.", &data));
+ EXPECT_FALSE(data.empty());
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_operation_response_unittest.cc b/chromium/components/offline_pages/core/prefetch/prefetch_request_operation_response_unittest.cc
new file mode 100644
index 00000000000..22d676d84fc
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_operation_response_unittest.cc
@@ -0,0 +1,399 @@
+// Copyright 2017 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 "base/test/mock_callback.h"
+#include "components/offline_pages/core/prefetch/generate_page_bundle_request.h"
+#include "components/offline_pages/core/prefetch/get_operation_request.h"
+#include "components/offline_pages/core/prefetch/prefetch_proto_utils.h"
+#include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
+#include "components/offline_pages/core/prefetch/prefetch_types.h"
+#include "components/offline_pages/core/prefetch/proto/offline_pages.pb.h"
+#include "components/offline_pages/core/prefetch/proto/operation.pb.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Eq;
+using testing::SaveArg;
+
+namespace offline_pages {
+
+namespace {
+const char kTestURL[] = "http://example.com";
+const char kTestURL2[] = "http://example.com/2";
+const char kTestURL3[] = "http://example.com/3";
+const char kTestURL4[] = "http://example.com/4";
+const char kTestUserAgent[] = "Test User Agent";
+const char kTestGCMID[] = "Test GCM ID";
+const int kTestMaxBundleSize = 100000;
+const char kTestBodyName[] = "body_name";
+const int64_t kTestBodyLength = 12345678LL;
+const char kTestMethodName[] = "Test name";
+const char kErrorMessage[] = "Invalid parameter";
+} // namespace
+
+// Builds the request for GeneratePageBundleRequest / GetOperationRequest.
+class RequestBuilder {
+ public:
+ RequestBuilder() {}
+ virtual ~RequestBuilder() {}
+
+ virtual void CreateRequest(
+ net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback) = 0;
+};
+
+class GeneratePageBundleRequestBuilder : public RequestBuilder {
+ public:
+ void CreateRequest(net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback) override {
+ std::vector<std::string> pages = {kTestURL, kTestURL2};
+ fetcher_.reset(new GeneratePageBundleRequest(
+ kTestUserAgent, kTestGCMID, kTestMaxBundleSize, pages,
+ request_context_getter, callback));
+ }
+
+ private:
+ std::unique_ptr<GeneratePageBundleRequest> fetcher_;
+};
+
+class GetOperationRequestBuilder : public RequestBuilder {
+ public:
+ void CreateRequest(net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback) override {
+ fetcher_.reset(new GetOperationRequest(kTestMethodName,
+ request_context_getter, callback));
+ }
+
+ private:
+ std::unique_ptr<GetOperationRequest> fetcher_;
+};
+
+// Builds the response that returns a pending/done operation.
+class OperationBuilder {
+ public:
+ virtual ~OperationBuilder() {}
+
+ // Builds the opereation with an Any value and returns it in binary serialized
+ // format. Notes that Any value could be set in either 'metadata' or
+ // 'result.response' field depending on the state of the operation, pending or
+ // done.
+ virtual std::string BuildFromAny(const std::string& any_type_url,
+ const std::string& any_value) = 0;
+
+ // Builds the operation with an error value and returns it in binary
+ // serialized format. Notes that the error is only respected for done
+ // operation.
+ virtual std::string BuildFromError(int error_code,
+ const std::string& error_message) = 0;
+
+ protected:
+ // Helper function to build the operation based on |is_done| that controls
+ // where Any value goes.
+ std::string BuildOperation(bool is_done,
+ int error_code,
+ const std::string& error_message,
+ const std::string& any_type_url,
+ const std::string& any_value) {
+ proto::Operation operation;
+ operation.set_done(is_done);
+ if (error_code != proto::OK) {
+ operation.mutable_error()->set_code(error_code);
+ operation.mutable_error()->set_message(error_message);
+ }
+ if (!any_type_url.empty()) {
+ proto::Any* any =
+ is_done ? operation.mutable_response() : operation.mutable_metadata();
+ any->set_type_url(any_type_url);
+ any->set_value(any_value);
+ }
+ std::string data;
+ EXPECT_TRUE(operation.SerializeToString(&data));
+ return data;
+ }
+};
+
+class DoneOperationBuilder : public OperationBuilder {
+ public:
+ ~DoneOperationBuilder() override {}
+
+ std::string BuildFromAny(const std::string& any_type_url,
+ const std::string& any_value) override {
+ return BuildOperation(true, 0, std::string(), any_type_url, any_value);
+ }
+
+ std::string BuildFromError(int error_code,
+ const std::string& error_message) override {
+ return BuildOperation(true, error_code, error_message, std::string(),
+ std::string());
+ }
+};
+
+class PendingOperationBuilder : public OperationBuilder {
+ public:
+ ~PendingOperationBuilder() override {}
+
+ std::string BuildFromAny(const std::string& any_type_url,
+ const std::string& any_value) override {
+ return BuildOperation(false, 0, std::string(), any_type_url, any_value);
+ }
+
+ std::string BuildFromError(int error_code,
+ const std::string& error_message) override {
+ return BuildOperation(false, error_code, error_message, std::string(),
+ std::string());
+ }
+};
+
+// Combines both RequestBuilder and OperationBuilder in order to feed to
+// PrefetchRequestOperationResponseTest.
+class PrefetchRequestOperationResponseTestBuilder {
+ public:
+ PrefetchRequestOperationResponseTestBuilder() {}
+ virtual ~PrefetchRequestOperationResponseTestBuilder() {}
+
+ void CreateRequest(net::URLRequestContextGetter* request_context_getter,
+ const PrefetchRequestFinishedCallback& callback) {
+ request_builder_->CreateRequest(request_context_getter, callback);
+ }
+
+ std::string BuildFromAny(const std::string& any_type_url,
+ const std::string& any_value) {
+ return operation_builder_->BuildFromAny(any_type_url, any_value);
+ }
+
+ std::string BuildFromError(int error_code, const std::string& error_message) {
+ return operation_builder_->BuildFromError(error_code, error_message);
+ }
+
+ protected:
+ std::unique_ptr<RequestBuilder> request_builder_;
+ std::unique_ptr<OperationBuilder> operation_builder_;
+};
+
+class GeneratePageBundleRequestDoneOperationBuilder
+ : public PrefetchRequestOperationResponseTestBuilder {
+ public:
+ GeneratePageBundleRequestDoneOperationBuilder() {
+ request_builder_.reset(new GeneratePageBundleRequestBuilder);
+ operation_builder_.reset(new DoneOperationBuilder);
+ }
+};
+
+class GeneratePageBundleRequestPendingOperationBuilder
+ : public PrefetchRequestOperationResponseTestBuilder {
+ public:
+ GeneratePageBundleRequestPendingOperationBuilder() {
+ request_builder_.reset(new GeneratePageBundleRequestBuilder);
+ operation_builder_.reset(new PendingOperationBuilder);
+ }
+};
+
+class GetOperationRequestDoneOperationBuilder
+ : public PrefetchRequestOperationResponseTestBuilder {
+ public:
+ GetOperationRequestDoneOperationBuilder() {
+ request_builder_.reset(new GetOperationRequestBuilder);
+ operation_builder_.reset(new DoneOperationBuilder);
+ }
+};
+
+class GetOperationRequestPendingOperationBuilder
+ : public PrefetchRequestOperationResponseTestBuilder {
+ public:
+ GetOperationRequestPendingOperationBuilder() {
+ request_builder_.reset(new GetOperationRequestBuilder);
+ operation_builder_.reset(new PendingOperationBuilder);
+ }
+};
+
+template <typename T>
+class PrefetchRequestOperationResponseTest : public PrefetchRequestTestBase {
+ public:
+ PrefetchRequestStatus SendWithErrorResponse(
+ int error_code,
+ const std::string& error_message) {
+ return SendWithResponse(builder_.BuildFromError(error_code, error_message));
+ }
+
+ PrefetchRequestStatus SendWithAnyResponse(const std::string& any_type_url,
+ const std::string& any_value) {
+ return SendWithResponse(builder_.BuildFromAny(any_type_url, any_value));
+ }
+
+ PrefetchRequestStatus SendWithPageBundleResponse(
+ const proto::PageBundle& bundle) {
+ std::string bundle_data;
+ EXPECT_TRUE(bundle.SerializeToString(&bundle_data));
+ return SendWithResponse(
+ builder_.BuildFromAny(kPageBundleTypeURL, bundle_data));
+ }
+
+ const std::vector<RenderPageInfo>& pages() const { return pages_; }
+
+ private:
+ PrefetchRequestStatus SendWithResponse(const std::string& response_data) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ builder_.CreateRequest(request_context(), callback.Get());
+
+ PrefetchRequestStatus status;
+ pages_.clear();
+ EXPECT_CALL(callback, Run(_, _))
+ .WillOnce(DoAll(SaveArg<0>(&status), SaveArg<1>(&pages_)));
+ RespondWithData(response_data);
+ return status;
+ }
+
+ T builder_;
+ std::vector<RenderPageInfo> pages_;
+};
+
+// Lists all scenarios we want to test.
+typedef testing::Types<GeneratePageBundleRequestDoneOperationBuilder,
+ GeneratePageBundleRequestPendingOperationBuilder,
+ GetOperationRequestDoneOperationBuilder,
+ GetOperationRequestPendingOperationBuilder>
+ MyTypes;
+TYPED_TEST_CASE(PrefetchRequestOperationResponseTest, MyTypes);
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, EmptyOperation) {
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ // No error is set for OK. Thus this will cause the operation
+ // being filled with only done flag.
+ this->SendWithErrorResponse(proto::OK, ""));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, ErrorValue) {
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ this->SendWithErrorResponse(proto::UNKNOWN, kErrorMessage));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, InvalidTypeUrl) {
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ this->SendWithAnyResponse("foo", ""));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, InvalidValue) {
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ this->SendWithAnyResponse(kPageBundleTypeURL, "foo"));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, EmptyPageBundle) {
+ proto::PageBundle bundle;
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ this->SendWithPageBundleResponse(bundle));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, EmptyArchive) {
+ proto::PageBundle bundle;
+ bundle.add_archives();
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ this->SendWithPageBundleResponse(bundle));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, NoPageInfo) {
+ proto::PageBundle bundle;
+ proto::Archive* archive = bundle.add_archives();
+ archive->set_body_name(kTestBodyName);
+ archive->set_body_length(kTestBodyLength);
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ this->SendWithPageBundleResponse(bundle));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, MissingPageInfoUrl) {
+ proto::PageBundle bundle;
+ proto::Archive* archive = bundle.add_archives();
+ proto::PageInfo* page_info = archive->add_page_infos();
+ page_info->set_redirect_url(kTestURL);
+ EXPECT_EQ(PrefetchRequestStatus::SHOULD_RETRY_WITH_BACKOFF,
+ this->SendWithPageBundleResponse(bundle));
+ EXPECT_TRUE(this->pages().empty());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, SinglePage) {
+ proto::PageBundle bundle;
+ proto::Archive* archive = bundle.add_archives();
+ archive->set_body_name(kTestBodyName);
+ archive->set_body_length(kTestBodyLength);
+ proto::PageInfo* page_info = archive->add_page_infos();
+ page_info->set_url(kTestURL);
+ page_info->set_redirect_url(kTestURL2);
+ page_info->mutable_status()->set_code(proto::OK);
+ page_info->set_transformation(proto::NO_TRANSFORMATION);
+ int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
+ page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
+ page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
+ 1000000);
+ EXPECT_EQ(PrefetchRequestStatus::SUCCESS,
+ this->SendWithPageBundleResponse(bundle));
+ ASSERT_EQ(1u, this->pages().size());
+ EXPECT_EQ(kTestURL, this->pages().back().url);
+ EXPECT_EQ(kTestURL2, this->pages().back().redirect_url);
+ EXPECT_EQ(RenderStatus::RENDERED, this->pages().back().status);
+ EXPECT_EQ(kTestBodyName, this->pages().back().body_name);
+ EXPECT_EQ(kTestBodyLength, this->pages().back().body_length);
+ EXPECT_EQ(ms_since_epoch, this->pages().back().render_time.ToJavaTime());
+}
+
+TYPED_TEST(PrefetchRequestOperationResponseTest, MultiplePages) {
+ proto::PageBundle bundle;
+
+ // Adds a page that is still being rendered.
+ proto::Archive* archive = bundle.add_archives();
+ proto::PageInfo* page_info = archive->add_page_infos();
+ page_info->set_url(kTestURL);
+ page_info->mutable_status()->set_code(proto::NOT_FOUND);
+
+ // Adds a page that failed to render due to bundle size limits.
+ archive = bundle.add_archives();
+ page_info = archive->add_page_infos();
+ page_info->set_url(kTestURL2);
+ page_info->mutable_status()->set_code(proto::FAILED_PRECONDITION);
+
+ // Adds a page that failed to render for any other reason.
+ archive = bundle.add_archives();
+ page_info = archive->add_page_infos();
+ page_info->set_url(kTestURL3);
+ page_info->mutable_status()->set_code(proto::UNKNOWN);
+
+ // Adds a page that was rendered successfully.
+ archive = bundle.add_archives();
+ archive->set_body_name(kTestBodyName);
+ archive->set_body_length(kTestBodyLength);
+ page_info = archive->add_page_infos();
+ page_info->set_url(kTestURL4);
+ page_info->mutable_status()->set_code(proto::OK);
+ page_info->set_transformation(proto::NO_TRANSFORMATION);
+ int64_t ms_since_epoch = base::Time::Now().ToJavaTime();
+ page_info->mutable_render_time()->set_seconds(ms_since_epoch / 1000);
+ page_info->mutable_render_time()->set_nanos((ms_since_epoch % 1000) *
+ 1000000);
+
+ EXPECT_EQ(PrefetchRequestStatus::SUCCESS,
+ this->SendWithPageBundleResponse(bundle));
+ ASSERT_EQ(4u, this->pages().size());
+ EXPECT_EQ(kTestURL, this->pages().at(0).url);
+ EXPECT_EQ(RenderStatus::PENDING, this->pages().at(0).status);
+ EXPECT_EQ(kTestURL2, this->pages().at(1).url);
+ EXPECT_EQ(RenderStatus::EXCEEDED_LIMIT, this->pages().at(1).status);
+ EXPECT_EQ(kTestURL3, this->pages().at(2).url);
+ EXPECT_EQ(RenderStatus::FAILED, this->pages().at(2).status);
+ EXPECT_EQ(kTestURL4, this->pages().at(3).url);
+ EXPECT_EQ(RenderStatus::RENDERED, this->pages().at(3).status);
+ EXPECT_EQ(kTestBodyName, this->pages().at(3).body_name);
+ EXPECT_EQ(kTestBodyLength, this->pages().at(3).body_length);
+ EXPECT_EQ(ms_since_epoch, this->pages().at(3).render_time.ToJavaTime());
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.cc b/chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
new file mode 100644
index 00000000000..1a6305d1450
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
@@ -0,0 +1,51 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_request_test_base.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "net/url_request/url_fetcher_delegate.h"
+
+namespace offline_pages {
+
+PrefetchRequestTestBase::PrefetchRequestTestBase()
+ : task_runner_(new base::TestSimpleTaskRunner),
+ task_runner_handle_(task_runner_),
+ request_context_(new net::TestURLRequestContextGetter(
+ base::ThreadTaskRunnerHandle::Get())) {}
+
+PrefetchRequestTestBase::~PrefetchRequestTestBase() {}
+
+void PrefetchRequestTestBase::RespondWithNetError(int net_error) {
+ net::TestURLFetcher* url_fetcher = GetRunningFetcher();
+ DCHECK(url_fetcher);
+ url_fetcher->set_status(net::URLRequestStatus::FromError(net_error));
+ url_fetcher->SetResponseString("");
+ url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
+}
+
+void PrefetchRequestTestBase::RespondWithHttpError(int http_error) {
+ net::TestURLFetcher* url_fetcher = GetRunningFetcher();
+ DCHECK(url_fetcher);
+ url_fetcher->set_status(net::URLRequestStatus());
+ url_fetcher->set_response_code(http_error);
+ url_fetcher->SetResponseString("");
+ url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
+}
+
+void PrefetchRequestTestBase::RespondWithData(const std::string& data) {
+ net::TestURLFetcher* url_fetcher = GetRunningFetcher();
+ DCHECK(url_fetcher);
+ url_fetcher->set_status(net::URLRequestStatus());
+ url_fetcher->set_response_code(net::HTTP_OK);
+ url_fetcher->SetResponseString(data);
+ url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
+}
+
+net::TestURLFetcher* PrefetchRequestTestBase::GetRunningFetcher() {
+ // All created TestURLFetchers have ID 0 by default.
+ return url_fetcher_factory_.GetFetcherByID(0);
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.h b/chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.h
new file mode 100644
index 00000000000..a45e94da730
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_test_base.h
@@ -0,0 +1,41 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_REQUEST_FETCHER_TEST_BASE_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_REQUEST_FETCHER_TEST_BASE_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace offline_pages {
+
+// Base class for testing prefetch requests with simulated responses.
+class PrefetchRequestTestBase : public testing::Test {
+ public:
+ PrefetchRequestTestBase();
+ ~PrefetchRequestTestBase() override;
+
+ void RespondWithNetError(int net_error);
+ void RespondWithHttpError(int http_error);
+ void RespondWithData(const std::string& data);
+ net::TestURLFetcher* GetRunningFetcher();
+
+ net::URLRequestContextGetter* request_context() const {
+ return request_context_.get();
+ }
+
+ private:
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+ base::ThreadTaskRunnerHandle task_runner_handle_;
+ net::TestURLFetcherFactory url_fetcher_factory_;
+ scoped_refptr<net::TestURLRequestContextGetter> request_context_;
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_REQUEST_FETCHER_TEST_BASE_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_service.h b/chromium/components/offline_pages/core/prefetch/prefetch_service.h
new file mode 100644
index 00000000000..9e5ec6cbf62
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_service.h
@@ -0,0 +1,25 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVICE_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVICE_H_
+
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace offline_pages {
+
+class PrefetchDispatcher;
+
+// Main class and entry point for the Offline Pages Prefetching feature, that
+// controls the lifetime of all major subcomponents of the prefetching system.
+class PrefetchService : public KeyedService {
+ public:
+ ~PrefetchService() override = default;
+
+ virtual PrefetchDispatcher* GetDispatcher() = 0;
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVICE_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc
new file mode 100644
index 00000000000..9e86aba0b59
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc
@@ -0,0 +1,25 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_service_impl.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h"
+
+namespace offline_pages {
+
+PrefetchServiceImpl::PrefetchServiceImpl()
+ : dispatcher_(base::MakeUnique<PrefetchDispatcherImpl>()) {}
+
+PrefetchServiceImpl::~PrefetchServiceImpl() = default;
+
+PrefetchDispatcher* PrefetchServiceImpl::GetDispatcher() {
+ return dispatcher_.get();
+};
+
+void PrefetchServiceImpl::Shutdown() {}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h
new file mode 100644
index 00000000000..c476f13e90e
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h
@@ -0,0 +1,34 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVICE_IMPL_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVICE_IMPL_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "components/offline_pages/core/prefetch/prefetch_service.h"
+
+namespace offline_pages {
+
+class PrefetchServiceImpl : public PrefetchService {
+ public:
+ PrefetchServiceImpl();
+ ~PrefetchServiceImpl() override;
+
+ // PrefetchService implementation:
+ PrefetchDispatcher* GetDispatcher() override;
+
+ // KeyedService implementation:
+ void Shutdown() override;
+
+ private:
+ std::unique_ptr<PrefetchDispatcher> dispatcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefetchServiceImpl);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_SERVICE_IMPL_H_
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_types.cc b/chromium/components/offline_pages/core/prefetch/prefetch_types.cc
new file mode 100644
index 00000000000..8f06ddd2c8c
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_types.cc
@@ -0,0 +1,13 @@
+// Copyright 2017 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/offline_pages/core/prefetch/prefetch_types.h"
+
+namespace offline_pages {
+
+RenderPageInfo::RenderPageInfo() {}
+
+RenderPageInfo::RenderPageInfo(const RenderPageInfo& other) = default;
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_types.h b/chromium/components/offline_pages/core/prefetch/prefetch_types.h
new file mode 100644
index 00000000000..f36526dcc7f
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_types.h
@@ -0,0 +1,110 @@
+// Copyright 2017 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_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_TYPES_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_TYPES_H_
+
+#include <vector>
+#include "base/macros.h"
+#include "base/time/time.h"
+
+namespace offline_pages {
+
+// Status for sending prefetch request to the server.
+enum class PrefetchRequestStatus {
+ // Request completed successfully.
+ SUCCESS,
+ // Request failed due to to local network problem, unrelated to server load
+ // levels. The caller will simply reschedule the retry in the next available
+ // WiFi window after 15 minutes have passed.
+ SHOULD_RETRY_WITHOUT_BACKOFF,
+ // Request failed probably related to transient server problems. The caller
+ // will reschedule the retry with backoff included.
+ SHOULD_RETRY_WITH_BACKOFF,
+ // Request failed with error indicating that the server no longer knows how
+ // to service a request. The caller will prevent network requests for the
+ // period of 1 day.
+ SHOULD_SUSPEND
+};
+
+// Status indicating the page rendering status in the server.
+enum class RenderStatus {
+ // The page is rendered.
+ RENDERED,
+ // The page is still being processed.
+ PENDING,
+ // The page failed to render.
+ FAILED,
+ // Failed due to bundle size limits.
+ EXCEEDED_LIMIT
+};
+
+// Information about the page rendered in the server.
+struct RenderPageInfo {
+ RenderPageInfo();
+ RenderPageInfo(const RenderPageInfo& other);
+
+ // The URL of the page that was rendered.
+ std::string url;
+ // The final URL after redirects. Empty if the final URL is url.
+ std::string redirect_url;
+ // Status of the render attempt.
+ RenderStatus status = RenderStatus::FAILED;
+ // Resource name for the body which can be read via the ByteStream API.
+ // Set only when |status| is RENDERED.
+ std::string body_name;
+ // Length of the body in bytes. Set only when |status| is RENDERED.
+ int64_t body_length = 0LL;
+ // Time the page was rendered. Set only when |status| is RENDERED.
+ base::Time render_time;
+};
+
+// List of states a prefetch item can be at during its progress through the
+// prefetching process. They follow somewhat the order below, but some states
+// might be skipped.
+enum class PrefetchItemState {
+ // New request just received from the client.
+ NEW_REQUEST,
+ // The item has been included in a GeneratePageBundle RPC requesting the
+ // creation of an archive for its URL.
+ SENT_GENERATE_PAGE_BUNDLE,
+ // The archive was not immediately available (cached) upon the request and
+ // is now waiting for a GCM message notifying of its archiving operation
+ // completion.
+ AWAITING_GCM,
+ // The GCM message notifying of the archiving operation completion was
+ // received for this item.
+ RECEIVED_GCM,
+ // A GetOperation RPC was sent for this item to query for the final results
+ // of its archiving request.
+ SENT_GET_OPERATION,
+ // Information was received about a successfully created archive for this
+ // item that can now be downloaded.
+ RECEIVED_BUNDLE,
+ // This item's archive is currently being downloaded.
+ DOWNLOADING,
+ // Item has finished processing, successfully or otherwise, and is waiting to
+ // be processed for stats reporting to UMA.
+ FINISHED,
+ // UMA stats have been reported and the item is being kept just long enough
+ // to confirm that the same URL is not being repeatedly requested by its
+ // client.
+ ZOMBIE,
+};
+
+// Error codes used to identify the reason why a prefetch item has finished
+// processing.
+enum class PrefetchItemErrorCode {
+ SUCCESS,
+ EXPIRED,
+};
+
+// Callback invoked upon completion of a prefetch request.
+using PrefetchRequestFinishedCallback =
+ base::Callback<void(PrefetchRequestStatus status,
+ const std::vector<RenderPageInfo>& pages)>;
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_TYPES_H_
diff --git a/chromium/components/offline_pages/core/prefetch/proto/any.proto b/chromium/components/offline_pages/core/prefetch/proto/any.proto
new file mode 100644
index 00000000000..bc7100281f1
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/proto/any.proto
@@ -0,0 +1,13 @@
+// Copyright 2017 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.
+
+syntax = "proto3";
+option optimize_for = LITE_RUNTIME;
+
+package offline_pages.proto;
+
+message Any {
+ string type_url = 1;
+ bytes value = 2;
+}
diff --git a/chromium/components/offline_pages/core/prefetch/proto/offline_pages.proto b/chromium/components/offline_pages/core/prefetch/proto/offline_pages.proto
new file mode 100644
index 00000000000..bffc766694a
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/proto/offline_pages.proto
@@ -0,0 +1,98 @@
+// Copyright 2017 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.
+
+syntax = "proto3";
+option optimize_for = LITE_RUNTIME;
+
+package offline_pages.proto;
+
+import "status.proto";
+import "timestamp.proto";
+
+// Type of transformation applied to a web page.
+enum Transformation {
+ // Transformation not specified.
+ TRANSFORMATION_UNSPECIFIED = 0;
+ // Minimal transformation required to provide an offline-accessible web page.
+ NO_TRANSFORMATION = 1;
+}
+
+// Page package format.
+enum OutputFormat {
+ // Format not specified.
+ FORMAT_UNSPECIFIED = 0;
+ // An MHTML archive containing a single web page.
+ FORMAT_MHTML = 1;
+}
+
+// Response to the GeneratePageBundle request.
+message PageBundle {
+ // The list of archives in the bundle. The distribution of pages into archives
+ // is arbitrary.
+ repeated Archive archives = 1;
+}
+
+// A resource containing one or more serialized offline pages.
+message Archive {
+ // Information about the individual page(s) used to create the Archive.
+ // There will be one PageInfo message for every page in the archive, including
+ // those that encountered an error or were elided due to size considerations.
+ repeated PageInfo page_infos = 1;
+ // Format of the body.
+ OutputFormat output_format = 2;
+ // Resource name for the body which can be read via the ByteStream API.
+ // This resource will remain available for a minimum of 24 hours after the
+ // GeneratePageBundle request.
+ string body_name = 3;
+ // Length of the body in bytes.
+ int64 body_length = 4;
+}
+
+// Information about a single returned offline page.
+message PageInfo {
+ // The URL of the page that was rendered.
+ string url = 1;
+ // The final URL after redirects. Empty if the final URL is url.
+ string redirect_url = 2;
+ // Status of the render attempt. If status.code != OK, fields below this will
+ // be unset. If the operation is still running, status is NotFound to
+ // indicate the page is still being processed.
+ // If the page was not returned due to bundle size limits, status is
+ // FailedPrecondition. If the page failed to render for any other reason,
+ // status is Unknown.
+ Status status = 3;
+ // Transformation that was applied to the page.
+ Transformation transformation = 4;
+ // Time the page was rendered.
+ Timestamp render_time = 5;
+}
+
+// Request to return a list of pages in a format suitable for offline viewing.
+message GeneratePageBundleRequest {
+ // The client's browser's user agent string.
+ string user_agent = 1;
+ // Preferred browser language(s) as defined by
+ // [IETF BCP 47](https://tools.ietf.org/html/bcp47).
+ repeated string browser_languages = 2;
+ // Desired format of the web page archive(s).
+ OutputFormat output_format = 3;
+ // Maximum size of the generated body. If all pages' output would exceed this
+ // size, only the first N pages are returned.
+ int64 max_bundle_size_bytes = 4;
+ // The GCM registration ID that can be used to inform the client
+ // of LRO completion.
+ string gcm_registration_id = 5;
+ // List of individual page requests, in order of priority. At most 100 pages
+ // may be requested at a time.
+ repeated PageParameters pages = 6;
+}
+
+// Request a set of pages to be returned in a format suitable for offline
+// viewing.
+message PageParameters {
+ // URL of the web page to return.
+ string url = 1;
+ // Transformation to apply. Must not be TRANSFORMATION_UNSPECIFIED.
+ Transformation transformation = 2;
+}
diff --git a/chromium/components/offline_pages/core/prefetch/proto/operation.proto b/chromium/components/offline_pages/core/prefetch/proto/operation.proto
new file mode 100644
index 00000000000..77558d9fb65
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/proto/operation.proto
@@ -0,0 +1,42 @@
+// Copyright 2017 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.
+
+syntax = "proto3";
+option optimize_for = LITE_RUNTIME;
+
+package offline_pages.proto;
+;
+
+import "any.proto";
+import "status.proto";
+
+// This resource represents a long-running operation that is the result of a
+// network API call.
+message Operation {
+ // The server-assigned name, which is only unique within the same service that
+ // originally returns it.
+ string name = 1;
+
+ // Service-specific metadata associated with the operation. It typically
+ // contains progress information and common metadata such as create time.
+ // Some services might not provide such metadata. Any method that returns a
+ // long-running operation should document the metadata type, if any.
+ Any metadata = 2;
+
+ // If the value is 'false', it means the operation is still in progress.
+ // If true, the operation is completed, and either 'error' or 'response' is
+ // available.
+ bool done = 3;
+
+ // The operation result, which can be either an 'error' or a valid 'response'.
+ // If 'done' == 'false', neither 'error' nor 'response' is set.
+ // If 'done' == 'true', exactly one of 'error' or 'response' is set.
+ oneof result {
+ // The error result of the operation in case of failure or cancellation.
+ Status error = 4;
+
+ // The normal response of the operation in case of success.
+ Any response = 5;
+ }
+} \ No newline at end of file
diff --git a/chromium/components/offline_pages/core/prefetch/proto/status.proto b/chromium/components/offline_pages/core/prefetch/proto/status.proto
new file mode 100644
index 00000000000..f7187993d23
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/proto/status.proto
@@ -0,0 +1,29 @@
+// Copyright 2017 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.
+
+syntax = "proto3";
+option optimize_for = LITE_RUNTIME;
+
+package offline_pages.proto;
+
+import "any.proto";
+
+enum Code {
+ OK = 0;
+ UNKNOWN = 2;
+ NOT_FOUND = 5;
+ FAILED_PRECONDITION = 9;
+}
+
+message Status {
+ // The status code.
+ int32 code = 1;
+
+ // A developer-facing error message, which should be in English.
+ string message = 2;
+
+ // A list of messages that carry the error details. There will be a
+ // common set of message types for APIs to use.
+ repeated Any details = 3;
+}
diff --git a/chromium/components/offline_pages/core/prefetch/proto/timestamp.proto b/chromium/components/offline_pages/core/prefetch/proto/timestamp.proto
new file mode 100644
index 00000000000..c9658e73ca0
--- /dev/null
+++ b/chromium/components/offline_pages/core/prefetch/proto/timestamp.proto
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+syntax = "proto3";
+option optimize_for = LITE_RUNTIME;
+
+package offline_pages.proto;
+
+message Timestamp {
+ // Represents seconds of UTC time since Unix epoch
+ // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
+ // 9999-12-31T23:59:59Z inclusive.
+ int64 seconds = 1;
+
+ // Non-negative fractions of a second at nanosecond resolution. Negative
+ // second values with fractions must still have non-negative nanos values
+ // that count forward in time. Must be from 0 to 999,999,999
+ // inclusive.
+ int32 nanos = 2;
+}
diff --git a/chromium/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc b/chromium/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc
index ebfb5110f62..ab366b53647 100644
--- a/chromium/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc
+++ b/chromium/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc
@@ -5,6 +5,7 @@
#include "components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.h"
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/offline_pages/core/client_policy_controller.h"
#include "components/offline_pages/core/offline_page_model.h"
@@ -35,7 +36,7 @@ RecentTabsUIAdapterDelegate::GetOrCreateRecentTabsUIAdapter(
recent_tabs_ui_adapter = new DownloadUIAdapter(
offline_page_model, request_coordinator, std::move(delegate));
offline_page_model->SetUserData(kRecentTabsUIAdapterKey,
- recent_tabs_ui_adapter);
+ base::WrapUnique(recent_tabs_ui_adapter));
}
return recent_tabs_ui_adapter;
diff --git a/chromium/components/offline_pages/features/BUILD.gn b/chromium/components/offline_pages/features/BUILD.gn
new file mode 100644
index 00000000000..fdf4451198a
--- /dev/null
+++ b/chromium/components/offline_pages/features/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2017 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.
+
+import("//build/buildflag_header.gni")
+import("//components/offline_pages/features/features.gni")
+
+# This file is in a separate directory so all targets in the build can refer to
+# the buildflag header to get the necessary preprocessor defines without
+# bringing in all of offline_pages. Other targets can depend on this target
+# regardless of whether extensions are enabled.
+
+buildflag_header("features") {
+ header = "features.h"
+ flags = [
+ "ENABLE_OFFLINE_PAGES=$enable_offline_pages",
+ "ENABLE_OFFLINE_PAGES_HARNESS=$enable_offline_pages_harness",
+ ]
+}
diff --git a/chromium/components/offline_pages/features/features.gni b/chromium/components/offline_pages/features/features.gni
new file mode 100644
index 00000000000..2c8c75b1f4f
--- /dev/null
+++ b/chromium/components/offline_pages/features/features.gni
@@ -0,0 +1,13 @@
+# Copyright 2017 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.
+
+declare_args() {
+ # Whether to enable OfflinePages support. Currently user-visible features
+ # are Android-only.
+ enable_offline_pages = is_android
+
+ # This enables test API for locally-built harness which is used for quality
+ # evaluations. Requires setting this variable manually at local environment.
+ enable_offline_pages_harness = false
+}
diff --git a/chromium/components/onc/docs/onc_spec.md b/chromium/components/onc/docs/onc_spec.md
index 7729193aa98..4c3e961e98a 100644
--- a/chromium/components/onc/docs/onc_spec.md
+++ b/chromium/components/onc/docs/onc_spec.md
@@ -230,6 +230,11 @@ Field **NetworkConfigurations** is an array of
[Cellular](#Cellular-type)
* Cellular settings.
+* **Tether**
+ * (required if **Type** is *Tether*, otherwise ignored) -
+ [Tether](#Tether-type)
+ * Tether settings.
+
* **Type**
* (required if **Remove** is *false*, otherwise ignored) - **string**
* `Allowed values are` *Cellular*,
@@ -1037,9 +1042,19 @@ type exists to configure the authentication.
* (required if **ClientCertType** is *Ref*, otherwise ignored) - **string**
* Reference to client certificate stored in certificate section.
+* **ClientCertPKCS11Id**
+ * (required if **ClientCertType** is *PKCS11Id*, otherwise ignored) -
+ * PKCS#11 identifier in the format slot:key_id.
+
* **ClientCertType**
- * (optional) **string**
- `Allowed values are` *Ref*, and *Pattern*.
+ * (optional) - **string**
+ * `Allowed values are` *Ref*, *Pattern*, *PKCS11Id* and *None*.
+ * *Ref* and *Pattern* indicate that the associated property should be used
+ to identify the client certificate.
+ * *PKCS11Id* is used when representing a certificate in a local store and is
+ only valid when describing a local configuration.
+ * *None* indicates that the server is configured to not require client
+ certificates.
* **Identity**
* (optional) - **string**
@@ -1052,20 +1067,15 @@ type exists to configure the authentication.
expansions.
* **Inner**
- * (optional if **Outer** is
- *EAP-FAST*, *EAP-TTLS*
- or *PEAP*, otherwise ignored, defaults to *Automatic*) - **string**
- * `Allowed values are` *Automatic*,
- *MD5*, *MSCHAPv2*,
- *EAP-MSCHAPv2*,
- *PAP*, and *GTC*.
+ * (optional if **Outer** is *EAP-FAST*, *EAP-TTLS* or *PEAP*, otherwise
+ ignored, defaults to *Automatic*) - **string**
+ * `Allowed values are` *Automatic*, *MD5*, *MSCHAP*, *MSCHAPv2*, *PAP*,
+ *CHAP* and *GTC*.
* For tunneling outer protocols.
* **Outer**
* (required) - **string**
- * `Allowed values are` *LEAP*,
- *EAP-AKA*, *EAP-FAST*,
- *EAP-TLS*, *EAP-TTLS*,
+ * `Allowed values are` *LEAP*, *EAP-AKA*, *EAP-FAST*, *EAP-TLS*, *EAP-TTLS*,
*EAP-SIM* and *PEAP*.
* **Password**
@@ -1105,6 +1115,11 @@ type exists to configure the authentication.
A verification using the system's CA certificates may still apply.
See **UseSystemCAs** for this.
+* **SubjectMatch**
+ * (optional) - **string**
+ * WiFi only. A substring which a remote RADIUS service certificate subject
+ name must contain in order to connect.
+
* **UseSystemCAs**
* (optional, defaults to *true*) - **boolean**
* Required server certificate to be signed by "system default certificate
@@ -1431,6 +1446,40 @@ ONC configuration of of **Cellular** networks is not yet supported.
changes to *sim-puk*).
+## Tether Networks
+
+For Tether connections, **Type** must be set to *Tether* and the
+field **Tether** must be set to an object of type [Tether](#Tether-type).
+
+Used for representing a tether hotspot provided by an external device, e.g.
+a phone.
+
+### Tether type
+
+* **BatteryPercentage**
+ * (optional, read-only) - **integer**
+ * The battery percentage of the device providing the tether hotspot in the
+ range [0, 100].
+
+* **Carrier**
+ * (optional, read-only) - **string**
+ * The name of the cellular carrier when the hotspot is provided by a
+ cellular connection.
+
+* **HasConnectedToHost**
+ * (read-only) - **boolean**
+ * If *true*, the current device has already connected to a Tether network
+ created by the same external device which is providing this Tether
+ network.
+
+* **SignalStrength**
+ * (optional, read-only) - **integer**
+ * The current signal strength for the hotspot's connection in the range
+ [0, 100]. Note that this value refers to the strength of the signal
+ between the external device and its data provider, not the strength of the
+ signal between the current device and the external device.
+
+
## Bluetooth / WiFi Direct Networks
This format will eventually also cover configuration of Bluetooth and WiFi
diff --git a/chromium/components/onc/onc_constants.cc b/chromium/components/onc/onc_constants.cc
index ef314226ed0..80a95efc3c9 100644
--- a/chromium/components/onc/onc_constants.cc
+++ b/chromium/components/onc/onc_constants.cc
@@ -59,6 +59,7 @@ const char kSourceUser[] = "User";
const char kSourceUserPolicy[] = "UserPolicy";
const char kSource[] = "Source";
const char kStaticIPConfig[] = "StaticIPConfig";
+const char kTether[] = "Tether";
const char kType[] = "Type";
const char kVPN[] = "VPN";
const char kWiFi[] = "WiFi";
@@ -68,6 +69,10 @@ std::string CellularProperty(const std::string& property) {
return std::string(kCellular) + "." + property;
}
+std::string TetherProperty(const std::string& property) {
+ return std::string(kTether) + "." + property;
+}
+
std::string VpnProperty(const std::string& property) {
return std::string(kVPN) + "." + property;
}
@@ -82,6 +87,7 @@ namespace network_type {
const char kAllTypes[] = "All";
const char kCellular[] = "Cellular";
const char kEthernet[] = "Ethernet";
+const char kTether[] = "Tether";
const char kVPN[] = "VPN";
const char kWiFi[] = "WiFi";
const char kWimax[] = "WiMAX";
@@ -188,6 +194,13 @@ const char kEAP[] = "EAP";
const char k8021X[] = "8021X";
} // namespace ethernet
+namespace tether {
+const char kBatteryPercentage[] = "BatteryPercentage";
+const char kCarrier[] = "Carrier";
+const char kHasConnectedToHost[] = "HasConnectedToHost";
+const char kSignalStrength[] = "SignalStrength";
+} // namespace tether
+
namespace ipconfig {
const char kGateway[] = "Gateway";
const char kIPAddress[] = "IPAddress";
@@ -230,6 +243,7 @@ const char kSignalStrength[] = "SignalStrength";
namespace client_cert {
const char kClientCertPattern[] = "ClientCertPattern";
+const char kClientCertPKCS11Id[] = "ClientCertPKCS11Id";
const char kClientCertRef[] = "ClientCertRef";
const char kClientCertType[] = "ClientCertType";
const char kClientCertTypeNone[] = "None";
@@ -243,6 +257,7 @@ const char kLocality[] = "Locality";
const char kOrganization[] = "Organization";
const char kOrganizationalUnit[] = "OrganizationalUnit";
const char kPattern[] = "Pattern";
+const char kPKCS11Id[] = "PKCS11Id";
const char kRef[] = "Ref";
const char kSubject[] = "Subject";
} // namespace client_cert
@@ -286,6 +301,7 @@ const char kIdentity[] = "Identity";
const char kInner[] = "Inner";
const char kLEAP[] = "LEAP";
const char kMD5[] = "MD5";
+const char kMSCHAP[] = "MSCHAP";
const char kMSCHAPv2[] = "MSCHAPv2";
const char kOuter[] = "Outer";
const char kPAP[] = "PAP";
@@ -295,6 +311,7 @@ const char kSaveCredentials[] = "SaveCredentials";
const char kServerCAPEMs[] = "ServerCAPEMs";
const char kServerCARef[] = "ServerCARef";
const char kServerCARefs[] = "ServerCARefs";
+const char kSubjectMatch[] = "SubjectMatch";
const char kUseSystemCAs[] = "UseSystemCAs";
const char kUseProactiveKeyCaching[] = "UseProactiveKeyCaching";
} // namespace eap
diff --git a/chromium/components/onc/onc_constants.h b/chromium/components/onc/onc_constants.h
index 8576292b04e..20ece16b6af 100644
--- a/chromium/components/onc/onc_constants.h
+++ b/chromium/components/onc/onc_constants.h
@@ -82,12 +82,14 @@ ONC_EXPORT extern const char kConnectionState[];
ONC_EXPORT extern const char kRestrictedConnectivity[];
ONC_EXPORT extern const char kConnectable[];
ONC_EXPORT extern const char kErrorState[];
+ONC_EXPORT extern const char kTether[];
ONC_EXPORT extern const char kType[];
ONC_EXPORT extern const char kVPN[];
ONC_EXPORT extern const char kWiFi[];
ONC_EXPORT extern const char kWimax[];
ONC_EXPORT extern std::string CellularProperty(const std::string& property);
+ONC_EXPORT extern std::string TetherProperty(const std::string& property);
ONC_EXPORT extern std::string VpnProperty(const std::string& property);
ONC_EXPORT extern std::string WifiProperty(const std::string& property);
@@ -96,6 +98,7 @@ ONC_EXPORT extern std::string WifiProperty(const std::string& property);
namespace network_type {
ONC_EXPORT extern const char kCellular[];
ONC_EXPORT extern const char kEthernet[];
+ONC_EXPORT extern const char kTether[];
ONC_EXPORT extern const char kVPN[];
ONC_EXPORT extern const char kWiFi[];
ONC_EXPORT extern const char kWimax[];
@@ -216,6 +219,13 @@ ONC_EXPORT extern const char kEAP[];
ONC_EXPORT extern const char k8021X[];
} // namespace ethernet
+namespace tether {
+ONC_EXPORT extern const char kBatteryPercentage[];
+ONC_EXPORT extern const char kCarrier[];
+ONC_EXPORT extern const char kHasConnectedToHost[];
+ONC_EXPORT extern const char kSignalStrength[];
+} // namespace tether
+
namespace wifi {
ONC_EXPORT extern const char kAllowGatewayARPPolling[];
ONC_EXPORT extern const char kAutoConnect[];
@@ -246,6 +256,7 @@ ONC_EXPORT extern const char kSignalStrength[];
namespace client_cert {
ONC_EXPORT extern const char kClientCertPattern[];
+ONC_EXPORT extern const char kClientCertPKCS11Id[];
ONC_EXPORT extern const char kClientCertRef[];
ONC_EXPORT extern const char kClientCertType[];
ONC_EXPORT extern const char kClientCertTypeNone[];
@@ -259,6 +270,7 @@ ONC_EXPORT extern const char kLocality[];
ONC_EXPORT extern const char kOrganization[];
ONC_EXPORT extern const char kOrganizationalUnit[];
ONC_EXPORT extern const char kPattern[];
+ONC_EXPORT extern const char kPKCS11Id[];
ONC_EXPORT extern const char kRef[];
ONC_EXPORT extern const char kSubject[];
} // namespace client_cert
@@ -302,6 +314,7 @@ ONC_EXPORT extern const char kIdentity[];
ONC_EXPORT extern const char kInner[];
ONC_EXPORT extern const char kLEAP[];
ONC_EXPORT extern const char kMD5[];
+ONC_EXPORT extern const char kMSCHAP[];
ONC_EXPORT extern const char kMSCHAPv2[];
ONC_EXPORT extern const char kOuter[];
ONC_EXPORT extern const char kPAP[];
@@ -311,6 +324,7 @@ ONC_EXPORT extern const char kSaveCredentials[];
ONC_EXPORT extern const char kServerCAPEMs[];
ONC_EXPORT extern const char kServerCARef[];
ONC_EXPORT extern const char kServerCARefs[];
+ONC_EXPORT extern const char kSubjectMatch[];
ONC_EXPORT extern const char kUseSystemCAs[];
ONC_EXPORT extern const char kUseProactiveKeyCaching[];
} // namespace eap
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content.cc b/chromium/components/open_from_clipboard/clipboard_recent_content.cc
index a06be7bf454..fc040be2dae 100644
--- a/chromium/components/open_from_clipboard/clipboard_recent_content.cc
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content.cc
@@ -12,16 +12,6 @@
namespace {
ClipboardRecentContent* g_clipboard_recent_content = nullptr;
-// Schemes appropriate for suggestion by ClipboardRecentContent.
-const char* kAuthorizedSchemes[] = {
- url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme,
- // TODO(mpearson): add support for chrome:// URLs. Right now the scheme
- // for that lives in content and is accessible via
- // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme
- // TODO(mpearson): when adding desktop support, add kFileScheme, kFtpScheme,
- // and kGopherScheme.
-};
-
} // namespace
ClipboardRecentContent::ClipboardRecentContent() {}
@@ -42,18 +32,6 @@ void ClipboardRecentContent::SetInstance(
}
// static
-bool ClipboardRecentContent::IsAppropriateSuggestion(const GURL& url) {
- // Check to make sure it's a scheme we're willing to suggest.
- for (const auto* authorized_scheme : kAuthorizedSchemes) {
- if (url.SchemeIs(authorized_scheme))
- return true;
- }
-
- // Not a scheme we're allowed to return.
- return false;
-}
-
-// static
base::TimeDelta ClipboardRecentContent::MaximumAgeOfClipboard() {
// Identify the current setting for this parameter from the omnibox field
// trial.
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content.h b/chromium/components/open_from_clipboard/clipboard_recent_content.h
index 78a1b49c4bf..6d118906f0b 100644
--- a/chromium/components/open_from_clipboard/clipboard_recent_content.h
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content.h
@@ -45,9 +45,6 @@ class ClipboardRecentContent {
// older than this.
static base::TimeDelta MaximumAgeOfClipboard();
- // Returns true if the URL is appropriate to be suggested.
- static bool IsAppropriateSuggestion(const GURL& url);
-
private:
DISALLOW_COPY_AND_ASSIGN(ClipboardRecentContent);
};
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content_generic.cc b/chromium/components/open_from_clipboard/clipboard_recent_content_generic.cc
index 15ffa42eb98..70b3691661d 100644
--- a/chromium/components/open_from_clipboard/clipboard_recent_content_generic.cc
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content_generic.cc
@@ -7,6 +7,19 @@
#include "base/strings/string_util.h"
#include "ui/base/clipboard/clipboard.h"
+namespace {
+// Schemes appropriate for suggestion by ClipboardRecentContent.
+const char* kAuthorizedSchemes[] = {
+ url::kAboutScheme, url::kDataScheme, url::kHttpScheme, url::kHttpsScheme,
+ // TODO(mpearson): add support for chrome:// URLs. Right now the scheme
+ // for that lives in content and is accessible via
+ // GetEmbedderRepresentationOfAboutScheme() or content::kChromeUIScheme
+ // TODO(mpearson): when adding desktop support, add kFileScheme, kFtpScheme,
+ // and kGopherScheme.
+};
+
+} // namespace
+
ClipboardRecentContentGeneric::ClipboardRecentContentGeneric() {}
bool ClipboardRecentContentGeneric::GetRecentURLFromClipboard(GURL* url) {
@@ -63,3 +76,15 @@ void ClipboardRecentContentGeneric::SuppressClipboardContent() {
// not recent.
ui::Clipboard::GetForCurrentThread()->ClearLastModifiedTime();
}
+
+// static
+bool ClipboardRecentContentGeneric::IsAppropriateSuggestion(const GURL& url) {
+ // Check to make sure it's a scheme we're willing to suggest.
+ for (const auto* authorized_scheme : kAuthorizedSchemes) {
+ if (url.SchemeIs(authorized_scheme))
+ return true;
+ }
+
+ // Not a scheme we're allowed to return.
+ return false;
+}
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content_generic.h b/chromium/components/open_from_clipboard/clipboard_recent_content_generic.h
index c0b8704742a..4a5d4a4fe61 100644
--- a/chromium/components/open_from_clipboard/clipboard_recent_content_generic.h
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content_generic.h
@@ -27,6 +27,9 @@ class ClipboardRecentContentGeneric : public ClipboardRecentContent {
void SuppressClipboardContent() override;
private:
+ // Returns true if the URL is appropriate to be suggested.
+ static bool IsAppropriateSuggestion(const GURL& url);
+
DISALLOW_COPY_AND_ASSIGN(ClipboardRecentContentGeneric);
};
diff --git a/chromium/components/os_crypt/os_crypt.h b/chromium/components/os_crypt/os_crypt.h
index b62aca48365..b03d72608d6 100644
--- a/chromium/components/os_crypt/os_crypt.h
+++ b/chromium/components/os_crypt/os_crypt.h
@@ -38,6 +38,9 @@ class OSCrypt {
// this when we stop supporting keyring.
static void SetMainThreadRunner(
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner);
+
+ // Returns true iff the real secret key (not hardcoded one) is available.
+ static bool IsEncryptionAvailable();
#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
// Encrypt a string16. The output (second argument) is really an array of
@@ -80,6 +83,10 @@ class OSCrypt {
// If all parameters are |nullptr|, the real implementation is restored.
void UseMockKeyStorageForTesting(KeyStorageLinux* (*get_key_storage_mock)(),
std::string* (*get_password_v11_mock)());
+
+// Clears any caching and most lazy initialisations performed by the production
+// code. Should be used after any test which required a password.
+void ClearCacheForTesting();
#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(UNIT_TEST)
#endif // COMPONENTS_OS_CRYPT_OS_CRYPT_H_
diff --git a/chromium/components/os_crypt/os_crypt_linux.cc b/chromium/components/os_crypt/os_crypt_linux.cc
index 496d9716ea4..b8b6ada030e 100644
--- a/chromium/components/os_crypt/os_crypt_linux.cc
+++ b/chromium/components/os_crypt/os_crypt_linux.cc
@@ -12,6 +12,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
@@ -248,6 +249,19 @@ void OSCrypt::SetMainThreadRunner(
KeyStorageLinux::SetMainThreadRunner(main_thread_runner);
}
+// static
+bool OSCrypt::IsEncryptionAvailable() {
+ return g_get_password[Version::V11]();
+}
+
+void ClearCacheForTesting() {
+ g_cache.Get().key_storage_cache.reset();
+ g_cache.Get().password_v10_cache.reset();
+ g_cache.Get().password_v11_cache.reset();
+ g_cache.Get().is_key_storage_cached = false;
+ g_cache.Get().is_password_v11_cached = false;
+}
+
void UseMockKeyStorageForTesting(KeyStorageLinux* (*get_key_storage_mock)(),
std::string* (*get_password_v11_mock)()) {
// Save the real implementation to restore it later.
@@ -259,7 +273,7 @@ void UseMockKeyStorageForTesting(KeyStorageLinux* (*get_key_storage_mock)(),
is_get_password_saved = true;
}
- if (get_key_storage_mock && get_password_v11_mock) {
+ if (get_key_storage_mock || get_password_v11_mock) {
// Bypass calling KeyStorage::CreateService and caching of the key for V11
if (get_password_v11_mock)
g_get_password[Version::V11] = get_password_v11_mock;
diff --git a/chromium/components/os_crypt/os_crypt_linux_unittest.cc b/chromium/components/os_crypt/os_crypt_linux_unittest.cc
index 5f22c316aed..dce4c4a20e7 100644
--- a/chromium/components/os_crypt/os_crypt_linux_unittest.cc
+++ b/chromium/components/os_crypt/os_crypt_linux_unittest.cc
@@ -12,6 +12,10 @@
namespace {
+KeyStorageLinux* GetNullKeyStorage() {
+ return nullptr;
+}
+
class OSCryptLinuxTest : public testing::Test {
public:
OSCryptLinuxTest() = default;
@@ -67,4 +71,13 @@ TEST_F(OSCryptLinuxTest, VerifyV11) {
ASSERT_EQ(originaltext, decipheredtext);
}
+TEST_F(OSCryptLinuxTest, IsEncryptionAvailable) {
+ EXPECT_TRUE(OSCrypt::IsEncryptionAvailable());
+ // Restore default GetKeyStorage and GetPassword functions.
+ UseMockKeyStorageForTesting(nullptr, nullptr);
+ // Mock only GetKeyStorage function.
+ UseMockKeyStorageForTesting(GetNullKeyStorage, nullptr);
+ EXPECT_FALSE(OSCrypt::IsEncryptionAvailable());
+}
+
} // namespace
diff --git a/chromium/components/os_crypt/os_crypt_mocker_linux.cc b/chromium/components/os_crypt/os_crypt_mocker_linux.cc
index a222c88d98a..d4dc0ac361c 100644
--- a/chromium/components/os_crypt/os_crypt_mocker_linux.cc
+++ b/chromium/components/os_crypt/os_crypt_mocker_linux.cc
@@ -55,4 +55,5 @@ void OSCryptMockerLinux::SetUpWithSingleton() {
// static
void OSCryptMockerLinux::TearDown() {
UseMockKeyStorageForTesting(nullptr, nullptr);
+ ClearCacheForTesting();
}
diff --git a/chromium/components/page_info_strings.grdp b/chromium/components/page_info_strings.grdp
index 54e83360073..7dac8f62dcc 100644
--- a/chromium/components/page_info_strings.grdp
+++ b/chromium/components/page_info_strings.grdp
@@ -1,114 +1,330 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
- <!-- Summary strings -->
- <message name="IDS_PAGEINFO_SECURE_SUMMARY" desc="A short summary phrase at the top of the Page Info bubble (which shows when you click the lock icon) that indicates that the connection to the current website is secure.">
+ <!-- Security summary strings -->
+ <!-- TODO(crbug.com/716305): Rename remaining IDS_PAGE_INFO_* strings to IDS_PAGE_INFO_* -->
+ <message name="IDS_PAGE_INFO_SECURE_SUMMARY" desc="A short summary phrase at the top of the Page Info bubble (which shows when you click the lock icon) that indicates that the connection to the current website is secure.">
Secure connection
</message>
- <message name="IDS_PAGEINFO_MIXED_CONTENT_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the connection to the current website is using mainly using a secure connection but has some insecure parts (like insecurely loaded images).">
+ <message name="IDS_PAGE_INFO_MIXED_CONTENT_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the connection to the current website is using mainly using a secure connection but has some insecure parts (like insecurely loaded images).">
Your connection to this site is not fully secure
</message>
- <message name="IDS_PAGEINFO_NOT_SECURE_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the connection to the current website is secure.">
+ <message name="IDS_PAGE_INFO_NOT_SECURE_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the connection to the current website is secure.">
Your connection to this site is not secure
</message>
- <message name="IDS_PAGEINFO_MALWARE_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the current website has been flagged as containing malware.">
+ <message name="IDS_PAGE_INFO_MALWARE_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the current website has been flagged as containing malware.">
This site contains malware
</message>
- <message name="IDS_PAGEINFO_SOCIAL_ENGINEERING_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the current website has been flagged as social engineering.">
+ <message name="IDS_PAGE_INFO_SOCIAL_ENGINEERING_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the current website has been flagged as social engineering.">
This site is deceptive
</message>
- <message name="IDS_PAGEINFO_UNWANTED_SOFTWARE_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the current website has been flagged as containing unwanted software.">
+ <message name="IDS_PAGE_INFO_UNWANTED_SOFTWARE_SUMMARY" desc="A one-line summary at the top of the Page Info bubble (which shows when you click the security indicator) if the current website has been flagged as containing unwanted software.">
This site contains harmful programs
</message>
+ <!-- Internal page summary strings -->
+ <!-- Note: IDS_PAGE_INFO_INTERNAL_PAGE would be here, but it is in components_{chromium,google_chrome}_strings.grd because it uses the browser name. -->
+ <message name="IDS_PAGE_INFO_EXTENSION_PAGE" desc="Message to display in the page info bubble when the page you are on is a chrome-extension:// page. This refers to Chrome extensions.">
+ You're viewing an extension page
+ </message>
+ <message name="IDS_PAGE_INFO_VIEW_SOURCE_PAGE" desc="Message to display in the page info bubble when you are viewing page sources by using |View page source| option from the right click menu.">
+ You're viewing the source of a web page
+ </message>
+
<!-- Detail strings -->
- <message name="IDS_PAGEINFO_SECURE_DETAILS" desc="A short paragraph explaining a secure site to the user.">
+ <message name="IDS_PAGE_INFO_SECURE_DETAILS" desc="A short paragraph explaining a secure site to the user.">
Your information (for example, passwords or credit card numbers) is private when it is sent to this site.
</message>
- <message name="IDS_PAGEINFO_MIXED_CONTENT_DETAILS" desc="A short paragraph explaining a partially insecure site to the user.">
+ <message name="IDS_PAGE_INFO_MIXED_CONTENT_DETAILS" desc="A short paragraph explaining a partially insecure site to the user.">
Attackers might be able to see the images you’re looking at on this site and trick you by modifying them.
</message>
- <message name="IDS_PAGEINFO_NOT_SECURE_DETAILS" desc="A short paragraph explaining a non-secure site to the user.">
+ <message name="IDS_PAGE_INFO_NOT_SECURE_DETAILS" desc="A short paragraph explaining a non-secure site to the user.">
You should not enter any sensitive information on this site (for example, passwords or credit cards), because it could be stolen by attackers.
</message>
- <message name="IDS_PAGEINFO_INVALID_CERTIFICATE_DESCRIPTION" desc="A short paragraph to the user that security warnings are disabled. This is the case when the user has encountered a certificate error for the current site and chosen to override it.">
- You have chosen to disable security warnings for this site.
- </message>
- <message name="IDS_PAGEINFO_MALWARE_DETAILS" desc="A short paragraph explaining to the user that the current website has been flagged as containing malware.">
+ <message name="IDS_PAGE_INFO_MALWARE_DETAILS" desc="A short paragraph explaining to the user that the current website has been flagged as containing malware.">
Attackers on this site might attempt to install dangerous programs on your computer that steal or delete your information (for example, photos, passwords, messages, and credit cards).
</message>
- <message name="IDS_PAGEINFO_SOCIAL_ENGINEERING_DETAILS" desc="A short paragraph explaining to the user that the current website has been flagged as social engineering.">
+ <message name="IDS_PAGE_INFO_SOCIAL_ENGINEERING_DETAILS" desc="A short paragraph explaining to the user that the current website has been flagged as social engineering.">
Attackers on this site may trick you into doing something dangerous like installing software or revealing your personal information (for example, passwords, phone numbers, or credit cards).
</message>
- <message name="IDS_PAGEINFO_UNWANTED_SOFTWARE_DETAILS" desc="A short paragraph explaining to the user that the current website has been flagged as containing unwanted software.">
+ <message name="IDS_PAGE_INFO_UNWANTED_SOFTWARE_DETAILS" desc="A short paragraph explaining to the user that the current website has been flagged as containing unwanted software.">
Attackers on this site might try to trick you into installing programs that harm your browsing experience (for example, by changing your homepage or showing extra ads on sites you visit).
</message>
- <message name="IDS_PAGE_INFO_HELP_CENTER_LINK" desc="This is the text of the link pointing to the Help Center. This appears at the bottom of the SSL dialog and 'this' refers to the sections within the bubble.">
- What do these mean?
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_DEPRECATED_SIGNATURE_ALGORITHM" desc="The security summary phrase in the page information panel for a security problem where the site's certificate chain contains a SHA1 signature. Such certificates are treated as errors except when a policy override is present.">
- The certificate chain for this site contains a certificate signed using SHA-1.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT" desc="The text of the connection section when the connection is encrypted.">
- Your connection to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> is encrypted using a modern cipher suite.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR" desc="Some extra text of the connection section when the connection is encrypted and the page contains insecure content which has been run (e.g. script).">
- Further, this page includes other resources which are not secure. These resources can be viewed by others while in transit, and can be modified by an attacker to change the behavior of the page.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING" desc="Some extra text of the connection section when the connection is encrypted and the page contains insecure content which has been displayed (e.g. images, CSS).">
- Further, this page includes other resources which are not secure. These resources can be viewed by others while in transit, and can be modified by an attacker to change the look of the page.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_FORM_WARNING" desc="Some extra text of the connection section when the connection is encrypted and the page contains a form with a non-secure target.">
- This page includes a form that may not submit securely. Data you send can be viewed by others while in transit or could be modified by an attacker to change what the server receives.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK" desc="Linking 2 sentences in 1 paragraph.">
- <ph name="SENTENCE1">$1<ex>Your connection is encrypted.</ex></ph> <ph name="SENTENCE2">$2<ex>However, this page includes resources from other pages whose identity cannot be verified.</ex></ph>
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS" desc="This message gives details of the cryptographic primitives used to protect the HTTPS connection.">
- The connection is encrypted using <ph name="CIPHER">$1<ex>AES_128</ex></ph>, with <ph name="MAC">$2<ex>HMAC-SHA1</ex></ph> for message authentication and <ph name="KX">$3<ex>RSA</ex></ph> as the key exchange mechanism.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD" desc="This message gives details of the cryptographic primitives used to protect the HTTPS connection. It should be translated in a similar manner as IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS">
- The connection is encrypted and authenticated using <ph name="CIPHER">$1<ex>AES_128_GCM</ex></ph> and uses <ph name="KX">$2<ex>RSA</ex></ph> as the key exchange mechanism.
- </message>
+ <!-- Identity detail strings shared with iOS -->
<message name="IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY" desc="The text of the identity section when the page is not secure.">
The identity of this website has not been verified.
</message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME" desc="The text of the identity section when the host is not unique (such as with Intranet host names).">
- The identity of the server you are connected to cannot be fully validated. You are connected to a server using a name only valid within your network, which an external certificate authority has no way to validate ownership of. As some certificate authorities will issue certificates for these names regardless, there is no way to ensure you are connected to the intended website and not an attacker.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT" desc="The text of the connection section when the connection is not encrypted.">
- Your connection to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> is not encrypted.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM" desc="The text of the identity section when there is no certificate revocation mechanism.">
- The certificate does not specify a mechanism to check whether it has been revoked.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION" desc="This message gives the version of the SSL protocol used to protect the HTTPS connection.">
- The connection uses <ph name="SSL_VERSION">$1<ex>TLS 1.0</ex></ph>.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION" desc="The text of the identity section when we were unable to check if the certificate has been revoked.">
- Unable to check whether the certificate has been revoked.
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY" desc="The default name used when we did not find a principal name.">
- unknown name
- </message>
- <message name="IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT" desc="The text of the connection section when the connection uses weak encryption.">
- Your connection to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> is encrypted using an obsolete cipher suite.
- </message>
- <message name="IDS_PAGE_INFO_EXTENSION_PAGE" desc="Message to display in the page info bubble when the page you are on is a chrome-extension:// page. This refers to Chrome extensions.">
- You're viewing an extension page
- </message>
- <message name="IDS_PAGE_INFO_VIEW_SOURCE_PAGE" desc="Message to display in the page info bubble when you are viewing page sources by using |View page source| option from the right click menu.">
- You're viewing the source of a web page
- </message>
- <if expr="not use_titlecase">
- <message name="IDS_PAGEINFO_CERT_INFO_BUTTON" desc="Text of button in the page info that shows the SSL certificate.">
- Certificate information
+ <!-- Strings below are not used on iOS. -->
+ <if expr="not is_ios">
+
+ <!-- Administrator-provided certificate notifications -->
+ <!-- TODO(crbug.com/717802): Only include this on Chrome OS. -->
+ <message name="IDS_CERT_POLICY_PROVIDED_CERT_MESSAGE" desc="Text that is displayed in the Website Settings popup when using an administrator-provided certificate">
+ You have accessed content using an administrator-provided certificate. Data you provide to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> can be intercepted by your administrator.
</message>
- </if>
- <if expr="use_titlecase">
- <message name="IDS_PAGEINFO_CERT_INFO_BUTTON" desc="In Title Case: Text of button in the page info that shows the SSL certificate.">
- Certificate Information
+
+ <!-- Certificate exception decision UI (after clicking through an SSL certificate error) -->
+ <!-- TODO(crbug.com/502473): Support revoking certificate overrides on iOS Page Info. -->
+ <message name="IDS_PAGE_INFO_INVALID_CERTIFICATE_DESCRIPTION" desc="A short paragraph to the user that security warnings are disabled. This is the case when the user has encountered a certificate error for the current site and chosen to override it.">
+ You have chosen to disable security warnings for this site.
+ </message>
+ <if expr="is_android">
+ <message name="IDS_PAGE_INFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON" desc="Text of button in the page info that resets allow/deny decisions of invalid certificates, which will start showing security warnings for the page again.">
+ Stop using an invalid certificate
+ </message>
+ </if>
+ <if expr="not is_android">
+ <message name="IDS_PAGE_INFO_RESET_INVALID_CERTIFICATE_DECISIONS_BUTTON" desc="Text of button in the page info that resets allow/deny decisions of invalid certificates, which will start showing security warnings for the page again.">
+ Re-enable warnings
+ </message>
+ </if>
+
+ <!-- Old connection info UI. Only used on Android, but still compiled on desktop. -->
+ <message name="IDS_PAGE_INFO_HELP_CENTER_LINK" desc="This is the text of the link pointing to the Help Center. This appears at the bottom of the SSL dialog and 'this' refers to the sections within the bubble.">
+ What do these mean?
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_DEPRECATED_SIGNATURE_ALGORITHM" desc="The security summary phrase in the page information panel for a security problem where the site's certificate chain contains a SHA1 signature. Such certificates are treated as errors except when a policy override is present.">
+ The certificate chain for this site contains a certificate signed using SHA-1.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT" desc="The text of the connection section when the connection is encrypted.">
+ Your connection to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> is encrypted using a modern cipher suite.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR" desc="Some extra text of the connection section when the connection is encrypted and the page contains insecure content which has been run (e.g. script).">
+ Further, this page includes other resources which are not secure. These resources can be viewed by others while in transit, and can be modified by an attacker to change the behavior of the page.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING" desc="Some extra text of the connection section when the connection is encrypted and the page contains insecure content which has been displayed (e.g. images, CSS).">
+ Further, this page includes other resources which are not secure. These resources can be viewed by others while in transit, and can be modified by an attacker to change the look of the page.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_FORM_WARNING" desc="Some extra text of the connection section when the connection is encrypted and the page contains a form with a non-secure target.">
+ This page includes a form that may not submit securely. Data you send can be viewed by others while in transit or could be modified by an attacker to change what the server receives.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK" desc="Linking 2 sentences in 1 paragraph.">
+ <ph name="SENTENCE1">$1<ex>Your connection is encrypted.</ex></ph> <ph name="SENTENCE2">$2<ex>However, this page includes resources from other pages whose identity cannot be verified.</ex></ph>
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS" desc="This message gives details of the cryptographic primitives used to protect the HTTPS connection.">
+ The connection is encrypted using <ph name="CIPHER">$1<ex>AES_128</ex></ph>, with <ph name="MAC">$2<ex>HMAC-SHA1</ex></ph> for message authentication and <ph name="KX">$3<ex>RSA</ex></ph> as the key exchange mechanism.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD" desc="This message gives details of the cryptographic primitives used to protect the HTTPS connection. It should be translated in a similar manner as IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS">
+ The connection is encrypted and authenticated using <ph name="CIPHER">$1<ex>AES_128_GCM</ex></ph> and uses <ph name="KX">$2<ex>RSA</ex></ph> as the key exchange mechanism.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME" desc="The text of the identity section when the host is not unique (such as with Intranet host names).">
+ The identity of the server you are connected to cannot be fully validated. You are connected to a server using a name only valid within your network, which an external certificate authority has no way to validate ownership of. As some certificate authorities will issue certificates for these names regardless, there is no way to ensure you are connected to the intended website and not an attacker.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT" desc="The text of the connection section when the connection is not encrypted.">
+ Your connection to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> is not encrypted.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM" desc="The text of the identity section when there is no certificate revocation mechanism.">
+ The certificate does not specify a mechanism to check whether it has been revoked.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION" desc="This message gives the version of the SSL protocol used to protect the HTTPS connection.">
+ The connection uses <ph name="SSL_VERSION">$1<ex>TLS 1.0</ex></ph>.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION" desc="The text of the identity section when we were unable to check if the certificate has been revoked.">
+ Unable to check whether the certificate has been revoked.
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY" desc="The default name used when we did not find a principal name.">
+ unknown name
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT" desc="The text of the connection section when the connection uses weak encryption.">
+ Your connection to <ph name="DOMAIN">$1<ex>www.google.com</ex></ph> is encrypted using an obsolete cipher suite.
+ </message>
+ <if expr="not use_titlecase">
+ <message name="IDS_PAGE_INFO_CERT_INFO_BUTTON" desc="Text of button in the page info that shows the SSL certificate.">
+ Certificate information
+ </message>
+ </if>
+ <if expr="use_titlecase">
+ <message name="IDS_PAGE_INFO_CERT_INFO_BUTTON" desc="In Title Case: Text of button in the page info that shows the SSL certificate.">
+ Certificate Information
+ </message>
+ </if>
+ <message name="IDS_PAGE_INFO_ADDRESS" desc="Locality as reported in the EV identity text.">
+ <ph name="CITY">$1<ex>Mountain View</ex></ph>, <ph name="STATE">$2<ex>California</ex></ph> <ph name="COUNTRY">$3<ex>USA</ex></ph>
+ </message>
+ <message name="IDS_PAGE_INFO_PARTIAL_ADDRESS" desc="Locality with missing state as reported in the EV identity text.">
+ <ph name="CITY">$1<ex>Mountain View</ex></ph>, <ph name="COUNTRY">$2<ex>US</ex></ph>
+ </message>
+ <message name="IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV_VERIFIED" desc="The text of the identity section when the page is secured with a valid EV cert.">
+ The identity of <ph name="ORGANIZATION">$1<ex>Google</ex></ph> at <ph name="LOCALITY">$2<ex>Mountain View, CA US</ex></ph> has been verified by <ph name="ISSUER">$3<ex>VeriSign</ex></ph>.
+ </message>
+
+ <!-- Certificate Viewer link -->
+ <if expr="not is_android">
+ <message name="IDS_PAGE_INFO_CERTIFICATE" desc="Title of the certificate area in the Page Info bubble, shown when a HTTPS site is loaded.">
+ Certificate
+ </message>
+ <message name="IDS_PAGE_INFO_CERTIFICATE_VALID_LINK" desc="This appears in the Page Info bubble when a HTTPS site is loaded with a valid certificate. Text of the link that launches the Certificate Viewer.">
+ Valid
+ </message>
+ <message name="IDS_PAGE_INFO_CERTIFICATE_INVALID_LINK" desc="This appears in the Page Info bubble when a HTTPS site is loaded with an invalid certificate, e.g. https://wrong.host.badssl.com/. Text of the link that launches the Certificate Viewer.">
+ Invalid
+ </message>
+ <message name="IDS_PAGE_INFO_CERTIFICATE_VALID_LINK_TOOLTIP" desc="The text of the tooltip on IDS_PAGE_INFO_CERTIFICATE_VALID_LINK">
+ Issued by <ph name="ISSUER">$1<ex>Let's Encrypt X3</ex></ph>
+ </message>
+ </if>
+
+ <!-- Cookies -->
+ <if expr="not is_android">
+ <message name="IDS_PAGE_INFO_COOKIES" desc="The label for the Cookies setting in the Page Information Window.">
+ Cookies
+ </message>
+ <message name="IDS_PAGE_INFO_NUM_COOKIES" desc="The label of the counts for allowed cookies that are in use on the page.">
+ {NUM_COOKIES, plural, =1 {1 in use} other {# in use}}
+ </message>
+ </if>
+
+ <!-- Permission names -->
+ <message name="IDS_PAGE_INFO_TYPE_AUTOPLAY" desc="The label used for the autoplay permission controls in the Website Settings popup.">
+ Autoplay
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_BACKGROUND_SYNC" desc="The label used for the background sync permission controls in the Website Settings popup.">
+ Background Sync
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_IMAGES" desc="The label used for images permission controls in the Website Settings popup.">
+ Images
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_JAVASCRIPT" desc="The label used for JavaScript permission controls in the Website Settings popup.">
+ JavaScript
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_POPUPS" desc="The label used for popups permission controls in the Website Settings popup.">
+ Popups
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_FLASH" desc="The label used for Flash permissions in the Website Settings popup.">
+ Flash
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_LOCATION" desc="The label used for location permission controls in the Website Settings popup.">
+ Location
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_NOTIFICATIONS" desc="The label used for notifications permission controls in the Website Settings popup.">
+ Notifications
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_MIC" desc="The label used for the microphone permission controls in the Website Settings popup.">
+ Microphone
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_CAMERA" desc="The label used for the camera permission controls in the Website Settings popup.">
+ Camera
+ </message>
+ <message name="IDS_PAGE_INFO_TYPE_MIDI_SYSEX" desc="The label used for MIDI system exclusive message permission controls in the Website Settings popup.">
+ MIDI devices full control
+ </message>
+ <!-- TODO(crbug.com/716303): A few permissions are missing here. -->
+
+ <!-- Permission values -->
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to allow by the user.">
+ Allow
+ </message>
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to block by the user.">
+ Block
+ </message>
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to ask by the user.">
+ Ask
+ </message>
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_USER" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to detect important content by the user.">
+ Detect
+ </message>
+
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is allow.">
+ Allow (default)
+ </message>
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is block.">
+ Block (default)
+ </message>
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is ask.">
+ Ask (default)
+ </message>
+ <message name="IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_DEFAULT" desc="The Website Settings popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is detect important content.">
+ Detect (default)
+ </message>
+
+ <message name="IDS_PAGE_INFO_MENU_ITEM_DEFAULT_ALLOW" desc="The text of the menu item of a permissions menu on the Page Info UI that resets the setting to the default setting which is allow.">
+ Use global default (Allow)
+ </message>
+ <message name="IDS_PAGE_INFO_MENU_ITEM_DEFAULT_BLOCK" desc="The text of the menu item of a permissions menu on the Page Info UI that resets the setting to the default setting which is block.">
+ Use global default (Block)
+ </message>
+ <message name="IDS_PAGE_INFO_MENU_ITEM_DEFAULT_ASK" desc="The text of the menu item of a permissions menu on the Page Info UI that reset the setting to the default setting which is ask.">
+ Use global default (Ask)
+ </message>
+ <message name="IDS_PAGE_INFO_MENU_ITEM_DEFAULT_DETECT_IMPORTANT_CONTENT" desc="The text of the menu item of a permissions menu on the Page Info UI that reset the setting to the default setting which is detect important content.">
+ Use global default (Detect)
+ </message>
+
+ <message name="IDS_PAGE_INFO_MENU_ITEM_ALLOW" desc="The text of the menu item of a permissions menu on the Page Info UI that sets the setting to allow.">
+ Always allow on this site
+ </message>
+ <message name="IDS_PAGE_INFO_MENU_ITEM_BLOCK" desc="The text of the menu item of a permissions menu on the Page Info UI that sets the setting to allow.">
+ Always block on this site
+ </message>
+ <message name="IDS_PAGE_INFO_MENU_ITEM_DETECT_IMPORTANT_CONTENT" desc="The text of the menu item of a permissions menu on the Page Info UI that sets the setting to detect important content.">
+ Always detect important content on this site
+ </message>
+ <!-- IDS_PAGE_INFO_MENU_ITEM_SUBRESOURCE_FILTER_BLOCK is currently the same as IDS_PAGE_INFO_MENU_ITEM_BLOCK, but we use a different string identifier in the code for the flexibility to change it in the future. -->
+ <message name="IDS_PAGE_INFO_MENU_ITEM_SUBRESOURCE_FILTER_BLOCK" desc="The text of the menu item of a permissions menu on the Page Info UI for the subresource filter permission in Block mode">
+ Always block on this site
+ </message>
+
+ <!-- UI for device access granted to the site using the device chooser (e.g. USB, Bluetooth) -->
+ <message name="IDS_PAGE_INFO_USB_DEVICE_LABEL" desc="The label used to describe a USB device that the user has granted the site permission to access.">
+ <ph name="DEVICE_NAME">$1<ex>Android Phone</ex></ph>
+ </message>
+ <message name="IDS_PAGE_INFO_DELETE_USB_DEVICE" desc="The tooltip displayed when hovering over the button that will remove permission to access a USB device that the user previously granted to the site.">
+ Revoke access
+ </message>
+
+ <!-- Site settings link -->
+ <message name="IDS_PAGE_INFO_SITE_SETTINGS_LINK" desc="This is the text of the link pointing to Chrome's Site Settings page. This appears at the bottom of the Permissions pane of the Page Information Window.">
+ Site settings
+ </message>
+
+ <!-- Permission decision strings -->
+ <message name="IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_POLICY" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly allowed by the user's enterprise policy.">
+ Allowed by your administrator
+ </message>
+ <message name="IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_POLICY" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly blocked by the user's enterprise policy.">
+ Blocked by your administrator
+ </message>
+ <message name="IDS_PAGE_INFO_PERMISSION_ASK_BY_POLICY" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly set to 'Ask' by the user's enterprise policy.">
+ Setting controlled by your administrator
+ </message>
+ <message name="IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_EXTENSION" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly allowed by one of the user's extensions.">
+ Allowed by an extension
+ </message>
+ <message name="IDS_PAGE_INFO_PERMISSION_BLOCKED_BY_EXTENSION" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly blocked by one of the user's extensions.">
+ Blocked by an extension
+ </message>
+ <message name="IDS_PAGE_INFO_PERMISSION_ASK_BY_EXTENSION" desc="The label used underneath a permission listed in the Page Info bubble if the permission was explicitly set to 'Ask' by one of the user's extensions.">
+ Setting controlled by an extension
+ </message>
+ <message name="IDS_PAGE_INFO_PERMISSION_AUTOMATICALLY_BLOCKED" desc="The label used underneath a permission listed in the Page Info bubble if the permission was blocked by Chrome on behalf of the user.">
+ Automatically blocked
+ </message>
+ <message name="IDS_PAGE_INFO_PERMISSION_SUBRESOURCE_FILTER_SUBTITLE" desc="The label used underneath the subresource filter permission in the Page Info UI. Used on desktop and Android platforms" translateable="false" formatter_data="android_java">
+ Subresource filter activated
+ </message>
+
+ <!-- Permission change infobar. -->
+ <if expr="not is_android">
+ <message name="IDS_PAGE_INFO_INFOBAR_TEXT" desc="The string shown in the infobar after the user has changed site permissions settings, reminding them to reload the page in order for the new settings to take effect.">
+ New site permissions settings will take effect after reloading the page.
+ </message>
+ <message name="IDS_PAGE_INFO_INFOBAR_BUTTON" desc="The string used in the infobar button allowing the user to reload the page directly from the infobar.">
+ Reload
+ </message>
+ </if>
+
+ <!-- VR browser -->
+ <message name="IDS_PAGE_INFO_VR_BROWSER_UNSUPPORTED_MODE" desc="This text is displayed as a large toast to inform the user that they cannot currently browse in VR and they will soon exit VR mode.">
+ This page contains features not yet supported in VR. Exiting...
+ </message>
+
+ <!-- WebVR -->
+ <message name="IDS_PAGE_INFO_INSECURE_WEBVR_CONTENT_TRANSIENT" desc="Text that is displayed temporarily as a large toast on first entering a WebVR page over non-secure transport.">
+ Your connection to this site is not private. To exit VR mode at any time, remove headset and press back.
+ </message>
+ <message name="IDS_PAGE_INFO_INSECURE_WEBVR_CONTENT_PERMANENT" desc="Text that is displayed in a small permanent notification on a WebVR page loaded over non-secure transport. (Should be short, does not need to be a complete sentence.)">
+ Not secure
</message>
</if>
</grit-part>
diff --git a/chromium/components/pairing/bluetooth_controller_pairing_controller.cc b/chromium/components/pairing/bluetooth_controller_pairing_controller.cc
index 5ef30c9c992..3553f828298 100644
--- a/chromium/components/pairing/bluetooth_controller_pairing_controller.cc
+++ b/chromium/components/pairing/bluetooth_controller_pairing_controller.cc
@@ -72,9 +72,12 @@ void BluetoothControllerPairingController::DeviceFound(
device::BluetoothDevice* device) {
DCHECK_EQ(current_stage_, STAGE_DEVICES_DISCOVERY);
DCHECK(thread_checker_.CalledOnValidThread());
+
+ device::BluetoothDevice::UUIDSet uuids = device->GetUUIDs();
if (base::StartsWith(device->GetNameForDisplay(),
base::ASCIIToUTF16(kDeviceNamePrefix),
- base::CompareCase::INSENSITIVE_ASCII)) {
+ base::CompareCase::INSENSITIVE_ASCII) &&
+ base::ContainsKey(uuids, device::BluetoothUUID(kPairingServiceUUID))) {
discovered_devices_.insert(device->GetAddress());
for (ControllerPairingController::Observer& observer : observers_)
observer.DiscoveredDevicesListChanged();
@@ -241,7 +244,7 @@ void BluetoothControllerPairingController::StartPairing() {
current_stage_ == STAGE_DEVICE_NOT_FOUND ||
current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR ||
current_stage_ == STAGE_HOST_ENROLLMENT_ERROR);
- if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
+ if (!device::BluetoothAdapterFactory::IsBluetoothSupported()) {
ChangeStage(STAGE_INITIALIZATION_ERROR);
return;
}
@@ -396,6 +399,13 @@ void BluetoothControllerPairingController::OnHostStatusMessage(
} else if (enrollment_status ==
pairing_api::HostStatusParameters::ENROLLMENT_STATUS_FAILURE) {
ChangeStage(STAGE_HOST_ENROLLMENT_ERROR);
+ // Reboot the host if enrollment failed.
+ pairing_api::Reboot reboot;
+ reboot.set_api_version(kPairingAPIVersion);
+ int size = 0;
+ scoped_refptr<net::IOBuffer> io_buffer(
+ ProtoDecoder::SendRebootHost(reboot, &size));
+ SendBuffer(io_buffer, size);
} else if (update_status ==
pairing_api::HostStatusParameters::UPDATE_STATUS_UPDATING) {
ChangeStage(STAGE_HOST_UPDATE_IN_PROGRESS);
@@ -446,6 +456,11 @@ void BluetoothControllerPairingController::OnAddNetworkMessage(
NOTREACHED();
}
+void BluetoothControllerPairingController::OnRebootMessage(
+ const pairing_api::Reboot& message) {
+ NOTREACHED();
+}
+
void BluetoothControllerPairingController::DeviceAdded(
device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
diff --git a/chromium/components/pairing/bluetooth_controller_pairing_controller.h b/chromium/components/pairing/bluetooth_controller_pairing_controller.h
index 15d0833702d..40ad48daf95 100644
--- a/chromium/components/pairing/bluetooth_controller_pairing_controller.h
+++ b/chromium/components/pairing/bluetooth_controller_pairing_controller.h
@@ -87,6 +87,7 @@ class BluetoothControllerPairingController
const pairing_api::CompleteSetup& message) override;
void OnErrorMessage(const pairing_api::Error& message) override;
void OnAddNetworkMessage(const pairing_api::AddNetwork& message) override;
+ void OnRebootMessage(const pairing_api::Reboot& message) override;
// BluetoothAdapter::Observer:
void DeviceAdded(device::BluetoothAdapter* adapter,
diff --git a/chromium/components/pairing/bluetooth_host_pairing_controller.cc b/chromium/components/pairing/bluetooth_host_pairing_controller.cc
index c8c534fa06a..2968c879956 100644
--- a/chromium/components/pairing/bluetooth_host_pairing_controller.cc
+++ b/chromium/components/pairing/bluetooth_host_pairing_controller.cc
@@ -23,21 +23,6 @@ namespace pairing_chromeos {
namespace {
const int kReceiveSize = 16384;
-std::string GetChromeOSDeviceType() {
- switch (chromeos::GetDeviceType()) {
- case chromeos::DeviceType::kChromebox:
- return std::string(kDeviceNamePrefix) + "box";
- case chromeos::DeviceType::kChromebase:
- return std::string(kDeviceNamePrefix) + "base";
- case chromeos::DeviceType::kChromebit:
- return std::string(kDeviceNamePrefix) + "bit";
- case chromeos::DeviceType::kChromebook:
- return std::string(kDeviceNamePrefix) + "book";
- default:
- return std::string(kDeviceNamePrefix) + "device";
- }
-}
-
pairing_api::HostStatusParameters::Connectivity PairingApiConnectivityStatus(
HostPairingController::Connectivity connectivity_status) {
switch (connectivity_status) {
@@ -187,29 +172,14 @@ void BluetoothHostPairingController::OnGetAdapter(
adapter_ = adapter;
if (adapter_->IsPresent()) {
- SetName();
+ SetPowered();
} else {
// Set the name once the adapter is present.
adapter_->AddObserver(this);
}
}
-void BluetoothHostPairingController::SetName() {
- // Hash the bluetooth address and take the lower 2 bytes to create a human
- // readable device name.
- const uint32_t device_id = base::Hash(adapter_->GetAddress()) & 0xFFFF;
- device_name_ =
- base::StringPrintf("%s_%04X", GetChromeOSDeviceType().c_str(), device_id);
-
- adapter_->SetName(
- device_name_,
- base::Bind(&BluetoothHostPairingController::OnSetName,
- ptr_factory_.GetWeakPtr()),
- base::Bind(&BluetoothHostPairingController::OnSetError,
- ptr_factory_.GetWeakPtr()));
-}
-
-void BluetoothHostPairingController::OnSetName() {
+void BluetoothHostPairingController::SetPowered() {
DCHECK(thread_checker_.CalledOnValidThread());
if (adapter_->IsPowered()) {
was_powered_ = true;
@@ -440,6 +410,13 @@ void BluetoothHostPairingController::OnErrorMessage(
NOTREACHED();
}
+void BluetoothHostPairingController::OnRebootMessage(
+ const pairing_api::Reboot& message) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ for (Observer& observer : observers_)
+ observer.RebootHostRequested();
+}
+
void BluetoothHostPairingController::OnAddNetworkMessage(
const pairing_api::AddNetwork& message) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -453,7 +430,7 @@ void BluetoothHostPairingController::AdapterPresentChanged(
DCHECK_EQ(adapter, adapter_.get());
if (present) {
adapter_->RemoveObserver(this);
- SetName();
+ SetPowered();
}
}
@@ -471,9 +448,9 @@ HostPairingController::Stage BluetoothHostPairingController::GetCurrentStage() {
void BluetoothHostPairingController::StartPairing() {
DCHECK_EQ(current_stage_, STAGE_NONE);
- bool bluetooth_available =
- device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable();
- if (!bluetooth_available) {
+ const bool bluetooth_supported =
+ device::BluetoothAdapterFactory::IsBluetoothSupported();
+ if (!bluetooth_supported) {
ChangeStage(STAGE_INITIALIZATION_ERROR);
return;
}
@@ -484,7 +461,7 @@ void BluetoothHostPairingController::StartPairing() {
}
std::string BluetoothHostPairingController::GetDeviceName() {
- return device_name_;
+ return adapter_.get() ? adapter_->GetName() : std::string();
}
std::string BluetoothHostPairingController::GetConfirmationCode() {
diff --git a/chromium/components/pairing/bluetooth_host_pairing_controller.h b/chromium/components/pairing/bluetooth_host_pairing_controller.h
index 9c84a0d3dfa..a9a9d4010a2 100644
--- a/chromium/components/pairing/bluetooth_host_pairing_controller.h
+++ b/chromium/components/pairing/bluetooth_host_pairing_controller.h
@@ -76,8 +76,7 @@ class BluetoothHostPairingController
void SendHostStatus();
void OnGetAdapter(scoped_refptr<device::BluetoothAdapter> adapter);
- void SetName();
- void OnSetName();
+ void SetPowered();
void OnSetPowered();
void OnCreateService(scoped_refptr<device::BluetoothSocket> socket);
void OnSetDiscoverable(bool change_stage);
@@ -121,6 +120,7 @@ class BluetoothHostPairingController
const pairing_api::CompleteSetup& message) override;
void OnErrorMessage(const pairing_api::Error& message) override;
void OnAddNetworkMessage(const pairing_api::AddNetwork& message) override;
+ void OnRebootMessage(const pairing_api::Reboot& message) override;
// BluetoothAdapter::Observer:
void AdapterPresentChanged(device::BluetoothAdapter* adapter,
@@ -139,7 +139,6 @@ class BluetoothHostPairingController
void AuthorizePairing(device::BluetoothDevice* device) override;
Stage current_stage_;
- std::string device_name_;
std::string confirmation_code_;
std::string enrollment_domain_;
Connectivity connectivity_status_;
diff --git a/chromium/components/pairing/host_pairing_controller.h b/chromium/components/pairing/host_pairing_controller.h
index 869f1e9fa4a..76fdd66e746 100644
--- a/chromium/components/pairing/host_pairing_controller.h
+++ b/chromium/components/pairing/host_pairing_controller.h
@@ -72,6 +72,10 @@ class HostPairingController {
// Called when the controller has provided an |auth_token| for enrollment.
virtual void EnrollHostRequested(const std::string& auth_token) {}
+ // Called when the controller has sent a reboot request. This will happen
+ // when the host enrollment fails.
+ virtual void RebootHostRequested() {}
+
private:
DISALLOW_COPY_AND_ASSIGN(Observer);
};
diff --git a/chromium/components/pairing/pairing_api.proto b/chromium/components/pairing/pairing_api.proto
index 22843be31a6..76c7032ac41 100644
--- a/chromium/components/pairing/pairing_api.proto
+++ b/chromium/components/pairing/pairing_api.proto
@@ -97,3 +97,8 @@ message AddNetwork {
optional int32 api_version = 1;
optional AddNetworkParameters parameters = 2;
}
+
+message Reboot {
+ optional int32 api_version = 1;
+ optional bool reboot = 2 [default = true];
+}
diff --git a/chromium/components/pairing/proto_decoder.cc b/chromium/components/pairing/proto_decoder.cc
index 52853d30cb9..c0e01a6c049 100644
--- a/chromium/components/pairing/proto_decoder.cc
+++ b/chromium/components/pairing/proto_decoder.cc
@@ -16,6 +16,7 @@ enum {
MESSAGE_COMPLETE_SETUP,
MESSAGE_ERROR,
MESSAGE_ADD_NETWORK,
+ MESSAGE_REBOOT,
NUM_MESSAGES,
};
}
@@ -112,6 +113,12 @@ bool ProtoDecoder::DecodeIOBuffer(int size,
observer_->OnAddNetworkMessage(message);
}
break;
+ case MESSAGE_REBOOT: {
+ pairing_api::Reboot message;
+ message.ParseFromArray(&buffer[0], buffer.size());
+ observer_->OnRebootMessage(message);
+ }
+ break;
default:
LOG(WARNING) << "Skipping unknown message type: " << next_message_type_;
@@ -180,6 +187,16 @@ ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendError(
return SendMessage(MESSAGE_ERROR, serialized_proto, size);
}
+ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendRebootHost(
+ const pairing_api::Reboot& message,
+ int* size) {
+ std::string serialized_proto;
+ if (!message.SerializeToString(&serialized_proto))
+ NOTREACHED();
+
+ return SendMessage(MESSAGE_REBOOT, serialized_proto, size);
+}
+
ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendMessage(
uint8_t message_type,
const std::string& message,
diff --git a/chromium/components/pairing/proto_decoder.h b/chromium/components/pairing/proto_decoder.h
index ab82377ff1c..6a8e774980b 100644
--- a/chromium/components/pairing/proto_decoder.h
+++ b/chromium/components/pairing/proto_decoder.h
@@ -25,6 +25,7 @@ class ConfigureHost;
class Error;
class HostStatus;
class PairDevices;
+class Reboot;
} // namespace pairing_api
namespace pairing_chromeos {
@@ -51,6 +52,7 @@ class ProtoDecoder {
const pairing_api::Error& message) = 0;
virtual void OnAddNetworkMessage(
const pairing_api::AddNetwork& message) = 0;
+ virtual void OnRebootMessage(const pairing_api::Reboot& message) = 0;
protected:
Observer() {}
@@ -78,6 +80,8 @@ class ProtoDecoder {
static IOBufferRefPtr SendCompleteSetup(
const pairing_api::CompleteSetup& message, int* size);
static IOBufferRefPtr SendError(const pairing_api::Error& message, int* size);
+ static IOBufferRefPtr SendRebootHost(const pairing_api::Reboot& message,
+ int* size);
private:
static IOBufferRefPtr SendMessage(uint8_t message_type,
diff --git a/chromium/components/password_manager/content/browser/PRESUBMIT.py b/chromium/components/password_manager/content/browser/PRESUBMIT.py
index 1507afc4db2..c17399159d8 100644
--- a/chromium/components/password_manager/content/browser/PRESUBMIT.py
+++ b/chromium/components/password_manager/content/browser/PRESUBMIT.py
@@ -8,7 +8,7 @@ match the corresponding bad_message.h file.
def _RunHistogramChecks(input_api, output_api, histogram_name):
try:
- # Setup sys.path so that we can call histrogram code
+ # Setup sys.path so that we can call histograms code.
import sys
original_sys_path = sys.path
sys.path = sys.path + [input_api.os_path.join(
diff --git a/chromium/components/password_manager/content/browser/content_password_manager_driver.cc b/chromium/components/password_manager/content/browser/content_password_manager_driver.cc
index 90b20e9f4e3..3a847908681 100644
--- a/chromium/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/chromium/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -38,6 +38,7 @@ ContentPasswordManagerDriver::ContentPasswordManagerDriver(
password_generation_manager_(client, this),
password_autofill_manager_(this, autofill_client),
next_free_key_(0),
+ is_main_frame_(render_frame_host->GetParent() == nullptr),
password_manager_binding_(this),
weak_factory_(this) {
// Does nothing if a VisiblePasswordObserver has already been created
@@ -161,6 +162,10 @@ autofill::AutofillDriver* ContentPasswordManagerDriver::GetAutofillDriver() {
render_frame_host_);
}
+bool ContentPasswordManagerDriver::IsMainFrame() const {
+ return is_main_frame_;
+}
+
PasswordGenerationManager*
ContentPasswordManagerDriver::GetPasswordGenerationManager() {
return &password_generation_manager_;
@@ -283,6 +288,14 @@ void ContentPasswordManagerDriver::SaveGenerationFieldDetectedByClassifier(
password_form, generation_field);
}
+void ContentPasswordManagerDriver::CheckSafeBrowsingReputation(
+ const GURL& form_action,
+ const GURL& frame_url) {
+#if defined(SAFE_BROWSING_DB_LOCAL)
+ client_->CheckSafeBrowsingReputation(form_action, frame_url);
+#endif
+}
+
void ContentPasswordManagerDriver::ShowPasswordSuggestions(
int key,
base::i18n::TextDirection text_direction,
@@ -332,9 +345,8 @@ ContentPasswordManagerDriver::GetAutofillAgent() {
const autofill::mojom::PasswordAutofillAgentPtr&
ContentPasswordManagerDriver::GetPasswordAutofillAgent() {
if (!password_autofill_agent_) {
- autofill::mojom::PasswordAutofillAgentRequest request(
- &password_autofill_agent_);
- // Some test codes may have no initialized remote interfaces.
+ auto request = mojo::MakeRequest(&password_autofill_agent_);
+ // Some test environments may have no remote interface support.
if (render_frame_host_->GetRemoteInterfaces()) {
render_frame_host_->GetRemoteInterfaces()->GetInterface(
std::move(request));
diff --git a/chromium/components/password_manager/content/browser/content_password_manager_driver.h b/chromium/components/password_manager/content/browser/content_password_manager_driver.h
index a1c2168995b..c7a867a23ec 100644
--- a/chromium/components/password_manager/content/browser/content_password_manager_driver.h
+++ b/chromium/components/password_manager/content/browser/content_password_manager_driver.h
@@ -78,6 +78,7 @@ class ContentPasswordManagerDriver
void SendLoggingAvailability() override;
void AllowToRunFormClassifier() override;
autofill::AutofillDriver* GetAutofillDriver() override;
+ bool IsMainFrame() const override;
PasswordGenerationManager* GetPasswordGenerationManager() override;
PasswordManager* GetPasswordManager() override;
@@ -109,6 +110,8 @@ class ContentPasswordManagerDriver
void SaveGenerationFieldDetectedByClassifier(
const autofill::PasswordForm& password_form,
const base::string16& generation_field) override;
+ void CheckSafeBrowsingReputation(const GURL& form_action,
+ const GURL& frame_url) override;
void OnPasswordFormsParsedNoRenderCheck(
const std::vector<autofill::PasswordForm>& forms);
@@ -143,6 +146,11 @@ class ContentPasswordManagerDriver
// it to each other over IPC. The counter below is used to generate new IDs.
int next_free_key_;
+ // It should be filled in the constructor, since later the frame might be
+ // detached and it would be impossible to check whether the frame is a main
+ // frame.
+ const bool is_main_frame_;
+
autofill::mojom::PasswordAutofillAgentPtr password_autofill_agent_;
autofill::mojom::PasswordGenerationAgentPtr password_gen_agent_;
diff --git a/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.cc b/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.cc
index eb9c1b119b9..c1dddc0ee88 100644
--- a/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.cc
+++ b/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.cc
@@ -51,7 +51,7 @@ void ContentPasswordManagerDriverFactory::CreateForWebContents(
web_contents->SetUserData(
kContentPasswordManagerDriverFactoryWebContentsUserDataKey,
- new_factory.release());
+ std::move(new_factory));
}
ContentPasswordManagerDriverFactory::ContentPasswordManagerDriverFactory(
@@ -76,6 +76,7 @@ ContentPasswordManagerDriverFactory::FromWebContents(
// static
void ContentPasswordManagerDriverFactory::BindPasswordManagerDriver(
content::RenderFrameHost* render_frame_host,
+ const service_manager::BindSourceInfo& source_info,
autofill::mojom::PasswordManagerDriverRequest request) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
@@ -100,6 +101,7 @@ void ContentPasswordManagerDriverFactory::BindPasswordManagerDriver(
// static
void ContentPasswordManagerDriverFactory::BindSensitiveInputVisibilityService(
content::RenderFrameHost* render_frame_host,
+ const service_manager::BindSourceInfo& source_info,
blink::mojom::SensitiveInputVisibilityServiceRequest request) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
diff --git a/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.h b/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.h
index 6c5de068d5d..12c3aef641e 100644
--- a/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.h
+++ b/chromium/components/password_manager/content/browser/content_password_manager_driver_factory.h
@@ -17,6 +17,7 @@
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "content/public/browser/web_contents_observer.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
#include "third_party/WebKit/public/platform/modules/sensitive_input_visibility/sensitive_input_visibility_service.mojom.h"
namespace content {
@@ -43,10 +44,12 @@ class ContentPasswordManagerDriverFactory
static void BindPasswordManagerDriver(
content::RenderFrameHost* render_frame_host,
+ const service_manager::BindSourceInfo& source_info,
autofill::mojom::PasswordManagerDriverRequest request);
static void BindSensitiveInputVisibilityService(
content::RenderFrameHost* render_frame_host,
+ const service_manager::BindSourceInfo& source_info,
blink::mojom::SensitiveInputVisibilityServiceRequest request);
ContentPasswordManagerDriver* GetDriverForFrame(
diff --git a/chromium/components/password_manager/content/browser/content_password_manager_driver_unittest.cc b/chromium/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
index e91435b3185..69741b25a5a 100644
--- a/chromium/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
+++ b/chromium/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
@@ -43,6 +43,9 @@ class MockPasswordManagerClient : public StubPasswordManagerClient {
~MockPasswordManagerClient() override = default;
MOCK_CONST_METHOD0(GetLogManager, const LogManager*());
+#if defined(SAFE_BROWSING_DB_LOCAL)
+ MOCK_METHOD2(CheckSafeBrowsingReputation, void(const GURL&, const GURL&));
+#endif
private:
DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerClient);
@@ -59,8 +62,8 @@ class FakePasswordAutofillAgent
~FakePasswordAutofillAgent() override {}
void BindRequest(mojo::ScopedMessagePipeHandle handle) {
- binding_.Bind(mojo::MakeRequest<autofill::mojom::PasswordAutofillAgent>(
- std::move(handle)));
+ binding_.Bind(
+ autofill::mojom::PasswordAutofillAgentRequest(std::move(handle)));
}
bool called_set_logging_state() { return called_set_logging_state_; }
@@ -86,7 +89,7 @@ class FakePasswordAutofillAgent
const autofill::FormsPredictionsMap& predictions) override {}
void FindFocusedPasswordForm(
- const FindFocusedPasswordFormCallback& callback) override {}
+ FindFocusedPasswordFormCallback callback) override {}
// Records whether SetLoggingState() gets called.
bool called_set_logging_state_;
@@ -425,6 +428,16 @@ TEST_F(ContentPasswordManagerDriverTest, ClearPasswordsOnAutofill) {
}
}
+#if defined(SAFE_BROWSING_DB_LOCAL)
+TEST_F(ContentPasswordManagerDriverTest, CheckSafeBrowsingReputationCalled) {
+ std::unique_ptr<ContentPasswordManagerDriver> driver(
+ new ContentPasswordManagerDriver(main_rfh(), &password_manager_client_,
+ &autofill_client_));
+ EXPECT_CALL(password_manager_client_, CheckSafeBrowsingReputation(_, _));
+ driver->CheckSafeBrowsingReputation(GURL(), GURL());
+}
+#endif
+
INSTANTIATE_TEST_CASE_P(,
ContentPasswordManagerDriverTest,
testing::Values(true, false));
diff --git a/chromium/components/password_manager/content/browser/credential_manager_impl.cc b/chromium/components/password_manager/content/browser/credential_manager_impl.cc
index 14261ccac92..d423a3a64f6 100644
--- a/chromium/components/password_manager/content/browser/credential_manager_impl.cc
+++ b/chromium/components/password_manager/content/browser/credential_manager_impl.cc
@@ -22,7 +22,6 @@
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/browser/password_store.h"
-#include "components/password_manager/core/common/credential_manager_types.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "content/public/browser/web_contents.h"
@@ -30,9 +29,9 @@ namespace password_manager {
namespace {
-void RunMojoGetCallback(const mojom::CredentialManager::GetCallback& callback,
+void RunMojoGetCallback(mojom::CredentialManager::GetCallback callback,
const CredentialInfo& info) {
- callback.Run(mojom::CredentialManagerError::SUCCESS, info);
+ std::move(callback).Run(mojom::CredentialManagerError::SUCCESS, info);
}
} // namespace
@@ -41,7 +40,10 @@ void RunMojoGetCallback(const mojom::CredentialManager::GetCallback& callback,
CredentialManagerImpl::CredentialManagerImpl(content::WebContents* web_contents,
PasswordManagerClient* client)
- : WebContentsObserver(web_contents), client_(client), weak_factory_(this) {
+ : WebContentsObserver(web_contents),
+ client_(client),
+ binding_(this),
+ weak_factory_(this) {
DCHECK(web_contents);
auto_signin_enabled_.Init(prefs::kCredentialsEnableAutosignin,
client_->GetPrefs());
@@ -50,12 +52,30 @@ CredentialManagerImpl::CredentialManagerImpl(content::WebContents* web_contents,
CredentialManagerImpl::~CredentialManagerImpl() {}
void CredentialManagerImpl::BindRequest(
- mojom::CredentialManagerRequest request) {
- bindings_.AddBinding(this, std::move(request));
+ mojom::CredentialManagerAssociatedRequest request) {
+ DCHECK(!binding_.is_bound());
+ binding_.Bind(std::move(request));
+
+ // The browser side will close the message pipe on DidFinishNavigation before
+ // the renderer side would be destroyed, and the renderer never explicitly
+ // closes the pipe. So a connection error really means an error here, in which
+ // case the renderer will try to reconnect when the next call to the API is
+ // made. Make sure this implementation will no longer be bound to a broken
+ // pipe once that happens, so the DCHECK above will succeed.
+ binding_.set_connection_error_handler(base::Bind(
+ &CredentialManagerImpl::DisconnectBinding, base::Unretained(this)));
+}
+
+bool CredentialManagerImpl::HasBinding() const {
+ return binding_.is_bound();
+}
+
+void CredentialManagerImpl::DisconnectBinding() {
+ binding_.Close();
}
void CredentialManagerImpl::Store(const CredentialInfo& credential,
- const StoreCallback& callback) {
+ StoreCallback callback) {
DCHECK_NE(CredentialType::CREDENTIAL_TYPE_EMPTY, credential.type);
if (password_manager_util::IsLoggingActive(client_)) {
@@ -65,7 +85,7 @@ void CredentialManagerImpl::Store(const CredentialInfo& credential,
}
// Send acknowledge response back.
- callback.Run();
+ std::move(callback).Run();
if (!client_->IsSavingAndFillingEnabledForCurrentPage() ||
!client_->OnCredentialManagerUsed())
@@ -79,9 +99,11 @@ void CredentialManagerImpl::Store(const CredentialInfo& credential,
std::unique_ptr<autofill::PasswordForm> observed_form =
CreateObservedPasswordFormFromOrigin(origin);
- // Create a custom form fetcher with suppressed HTTP->HTTPS migration.
+ // Create a custom form fetcher without HTTP->HTTPS migration, as well as
+ // without fetching of suppressed HTTPS credentials on HTTP origins as the API
+ // is only available on HTTPS origins.
auto form_fetcher = base::MakeUnique<FormFetcherImpl>(
- PasswordStore::FormDigest(*observed_form), client_, false);
+ PasswordStore::FormDigest(*observed_form), client_, false, false);
form_manager_ = base::MakeUnique<CredentialManagerPasswordFormManager>(
client_, GetDriver(), *observed_form, std::move(form), this, nullptr,
std::move(form_fetcher));
@@ -125,14 +147,14 @@ void CredentialManagerImpl::OnProvisionalSaveComplete() {
client_->PromptUserToSaveOrUpdatePassword(std::move(form_manager_), false);
}
-void CredentialManagerImpl::RequireUserMediation(
- const RequireUserMediationCallback& callback) {
+void CredentialManagerImpl::PreventSilentAccess(
+ PreventSilentAccessCallback callback) {
if (password_manager_util::IsLoggingActive(client_)) {
CredentialManagerLogger(client_->GetLogManager())
- .LogRequireUserMediation(web_contents()->GetLastCommittedURL());
+ .LogPreventSilentAccess(web_contents()->GetLastCommittedURL());
}
// Send acknowledge response back.
- callback.Run();
+ std::move(callback).Run();
PasswordStore* store = GetPasswordStore();
if (!store || !client_->IsSavingAndFillingEnabledForCurrentPage() ||
@@ -141,33 +163,32 @@ void CredentialManagerImpl::RequireUserMediation(
if (!pending_require_user_mediation_) {
pending_require_user_mediation_.reset(
- new CredentialManagerPendingRequireUserMediationTask(this));
+ new CredentialManagerPendingPreventSilentAccessTask(this));
}
pending_require_user_mediation_->AddOrigin(GetSynthesizedFormForOrigin());
}
-void CredentialManagerImpl::Get(bool zero_click_only,
+void CredentialManagerImpl::Get(CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& federations,
- const GetCallback& callback) {
+ GetCallback callback) {
using metrics_util::LogCredentialManagerGetResult;
- metrics_util::CredentialManagerGetMediation mediation_status =
- zero_click_only ? metrics_util::CREDENTIAL_MANAGER_GET_UNMEDIATED
- : metrics_util::CREDENTIAL_MANAGER_GET_MEDIATED;
+
PasswordStore* store = GetPasswordStore();
if (password_manager_util::IsLoggingActive(client_)) {
CredentialManagerLogger(client_->GetLogManager())
- .LogRequestCredential(web_contents()->GetLastCommittedURL(),
- zero_click_only, federations);
+ .LogRequestCredential(web_contents()->GetLastCommittedURL(), mediation,
+ federations);
}
if (pending_request_ || !store) {
// Callback error.
- callback.Run(pending_request_
- ? mojom::CredentialManagerError::PENDINGREQUEST
- : mojom::CredentialManagerError::PASSWORDSTOREUNAVAILABLE,
- base::nullopt);
+ std::move(callback).Run(
+ pending_request_
+ ? mojom::CredentialManagerError::PENDINGREQUEST
+ : mojom::CredentialManagerError::PASSWORDSTOREUNAVAILABLE,
+ base::nullopt);
LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_REJECTED,
- mediation_status);
+ mediation);
return;
}
@@ -175,23 +196,25 @@ void CredentialManagerImpl::Get(bool zero_click_only,
// page is being prerendered.
if (!client_->IsFillingEnabledForCurrentPage() ||
!client_->OnCredentialManagerUsed()) {
- callback.Run(mojom::CredentialManagerError::SUCCESS, CredentialInfo());
+ std::move(callback).Run(mojom::CredentialManagerError::SUCCESS,
+ CredentialInfo());
LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_NONE,
- mediation_status);
+ mediation);
return;
}
// Return an empty credential if zero-click is required but disabled.
- if (zero_click_only && !IsZeroClickAllowed()) {
+ if (mediation == CredentialMediationRequirement::kSilent &&
+ !IsZeroClickAllowed()) {
// Callback with empty credential info.
- callback.Run(mojom::CredentialManagerError::SUCCESS, CredentialInfo());
+ std::move(callback).Run(mojom::CredentialManagerError::SUCCESS,
+ CredentialInfo());
LogCredentialManagerGetResult(
- metrics_util::CREDENTIAL_MANAGER_GET_NONE_ZERO_CLICK_OFF,
- mediation_status);
+ metrics_util::CREDENTIAL_MANAGER_GET_NONE_ZERO_CLICK_OFF, mediation);
return;
}
pending_request_.reset(new CredentialManagerPendingRequestTask(
- this, base::Bind(&RunMojoGetCallback, callback), zero_click_only,
+ this, base::Bind(&RunMojoGetCallback, base::Passed(&callback)), mediation,
include_passwords, federations));
// This will result in a callback to
// PendingRequestTask::OnGetPasswordStoreResults().
@@ -232,6 +255,7 @@ void CredentialManagerImpl::SendCredential(
void CredentialManagerImpl::SendPasswordForm(
const SendCredentialCallback& send_callback,
+ CredentialMediationRequirement mediation,
const autofill::PasswordForm* form) {
CredentialInfo info;
if (form) {
@@ -250,14 +274,12 @@ void CredentialManagerImpl::SendPasswordForm(
base::RecordAction(
base::UserMetricsAction("CredentialManager_AccountChooser_Accepted"));
metrics_util::LogCredentialManagerGetResult(
- metrics_util::CREDENTIAL_MANAGER_GET_ACCOUNT_CHOOSER,
- metrics_util::CREDENTIAL_MANAGER_GET_MEDIATED);
+ metrics_util::CREDENTIAL_MANAGER_GET_ACCOUNT_CHOOSER, mediation);
} else {
base::RecordAction(
base::UserMetricsAction("CredentialManager_AccountChooser_Dismissed"));
metrics_util::LogCredentialManagerGetResult(
- metrics_util::CREDENTIAL_MANAGER_GET_NONE,
- metrics_util::CREDENTIAL_MANAGER_GET_MEDIATED);
+ metrics_util::CREDENTIAL_MANAGER_GET_NONE, mediation);
}
SendCredential(send_callback, info);
}
diff --git a/chromium/components/password_manager/content/browser/credential_manager_impl.h b/chromium/components/password_manager/content/browser/credential_manager_impl.h
index 3b3f5cd97ba..4e6369dfe30 100644
--- a/chromium/components/password_manager/content/browser/credential_manager_impl.h
+++ b/chromium/components/password_manager/content/browser/credential_manager_impl.h
@@ -12,12 +12,13 @@
#include "base/memory/weak_ptr.h"
#include "components/password_manager/content/common/credential_manager.mojom.h"
#include "components/password_manager/core/browser/credential_manager_password_form_manager.h"
+#include "components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.h"
#include "components/password_manager/core/browser/credential_manager_pending_request_task.h"
-#include "components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
+#include "components/password_manager/core/common/credential_manager_types.h"
#include "components/prefs/pref_member.h"
#include "content/public/browser/web_contents_observer.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
class GURL;
@@ -41,23 +42,23 @@ class CredentialManagerImpl
public content::WebContentsObserver,
public CredentialManagerPasswordFormManagerDelegate,
public CredentialManagerPendingRequestTaskDelegate,
- public CredentialManagerPendingRequireUserMediationTaskDelegate {
+ public CredentialManagerPendingPreventSilentAccessTaskDelegate {
public:
CredentialManagerImpl(content::WebContents* web_contents,
PasswordManagerClient* client);
~CredentialManagerImpl() override;
- void BindRequest(mojom::CredentialManagerRequest request);
+ void BindRequest(mojom::CredentialManagerAssociatedRequest request);
+ bool HasBinding() const;
+ void DisconnectBinding();
// mojom::CredentialManager methods:
- void Store(const CredentialInfo& credential,
- const StoreCallback& callback) override;
- void RequireUserMediation(
- const RequireUserMediationCallback& callback) override;
- void Get(bool zero_click_only,
+ void Store(const CredentialInfo& credential, StoreCallback callback) override;
+ void PreventSilentAccess(PreventSilentAccessCallback callback) override;
+ void Get(CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& federations,
- const GetCallback& callback) override;
+ GetCallback callback) override;
// CredentialManagerPendingRequestTaskDelegate:
bool IsZeroClickAllowed() const override;
@@ -65,6 +66,7 @@ class CredentialManagerImpl
void SendCredential(const SendCredentialCallback& send_callback,
const CredentialInfo& info) override;
void SendPasswordForm(const SendCredentialCallback& send_callback,
+ CredentialMediationRequirement mediation,
const autofill::PasswordForm* form) override;
PasswordManagerClient* client() const override;
@@ -94,10 +96,10 @@ class CredentialManagerImpl
// they can properly respond to the request once the PasswordStore gives
// us data.
std::unique_ptr<CredentialManagerPendingRequestTask> pending_request_;
- std::unique_ptr<CredentialManagerPendingRequireUserMediationTask>
+ std::unique_ptr<CredentialManagerPendingPreventSilentAccessTask>
pending_require_user_mediation_;
- mojo::BindingSet<mojom::CredentialManager> bindings_;
+ mojo::AssociatedBinding<mojom::CredentialManager> binding_;
base::WeakPtrFactory<CredentialManagerImpl> weak_factory_;
diff --git a/chromium/components/password_manager/content/browser/credential_manager_impl_unittest.cc b/chromium/components/password_manager/content/browser/credential_manager_impl_unittest.cc
index 9563fc28c69..0e7a132ff74 100644
--- a/chromium/components/password_manager/content/browser/credential_manager_impl_unittest.cc
+++ b/chromium/components/password_manager/content/browser/credential_manager_impl_unittest.cc
@@ -8,6 +8,7 @@
#include <string>
#include <tuple>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -15,6 +16,7 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h"
@@ -290,17 +292,17 @@ class CredentialManagerImplTest : public content::RenderViewHostTestHarness {
content::RenderViewHostTestHarness::TearDown();
}
- void ExpectZeroClickSignInFailure(bool zero_click_only,
+ void ExpectZeroClickSignInFailure(CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& federations) {
bool called = false;
mojom::CredentialManagerError error;
base::Optional<CredentialInfo> credential;
- CallGet(zero_click_only, include_passwords, federations,
- base::Bind(&GetCredentialCallback, &called, &error, &credential));
EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _))
.Times(testing::Exactly(0));
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
+ CallGet(mediation, include_passwords, federations,
+ base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -309,18 +311,18 @@ class CredentialManagerImplTest : public content::RenderViewHostTestHarness {
EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY, credential->type);
}
- void ExpectZeroClickSignInSuccess(bool zero_click_only,
+ void ExpectZeroClickSignInSuccess(CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& federations,
CredentialType type) {
bool called = false;
mojom::CredentialManagerError error;
base::Optional<CredentialInfo> credential;
- CallGet(zero_click_only, include_passwords, federations,
- base::Bind(&GetCredentialCallback, &called, &error, &credential));
EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _))
.Times(testing::Exactly(0));
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(1));
+ CallGet(mediation, include_passwords, federations,
+ base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -329,14 +331,14 @@ class CredentialManagerImplTest : public content::RenderViewHostTestHarness {
EXPECT_EQ(type, credential->type);
}
- void ExpectCredentialType(bool zero_click_only,
+ void ExpectCredentialType(CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& federations,
CredentialType type) {
bool called = false;
mojom::CredentialManagerError error;
base::Optional<CredentialInfo> credential;
- CallGet(zero_click_only, include_passwords, federations,
+ CallGet(mediation, include_passwords, federations,
base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -350,21 +352,21 @@ class CredentialManagerImplTest : public content::RenderViewHostTestHarness {
// Helpers for testing CredentialManagerImpl methods.
void CallStore(const CredentialInfo& info,
- const CredentialManagerImpl::StoreCallback& callback) {
- cm_service_impl_->Store(info, callback);
+ CredentialManagerImpl::StoreCallback callback) {
+ cm_service_impl_->Store(info, std::move(callback));
}
- void CallRequireUserMediation(
- const CredentialManagerImpl::RequireUserMediationCallback& callback) {
- cm_service_impl_->RequireUserMediation(callback);
+ void CallPreventSilentAccess(
+ CredentialManagerImpl::PreventSilentAccessCallback callback) {
+ cm_service_impl_->PreventSilentAccess(std::move(callback));
}
- void CallGet(bool zero_click_only,
+ void CallGet(CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& federations,
- const CredentialManagerImpl::GetCallback& callback) {
- cm_service_impl_->Get(zero_click_only, include_passwords, federations,
- callback);
+ CredentialManagerImpl::GetCallback callback) {
+ cm_service_impl_->Get(mediation, include_passwords, federations,
+ std::move(callback));
}
protected:
@@ -678,7 +680,7 @@ TEST_F(CredentialManagerImplTest, CredentialManagerGetOverwriteZeroClick) {
bool called = false;
mojom::CredentialManagerError error;
base::Optional<CredentialInfo> credential;
- CallGet(false, true, federations,
+ CallGet(CredentialMediationRequirement::kOptional, true, federations,
base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -709,7 +711,7 @@ TEST_F(CredentialManagerImplTest,
EXPECT_FALSE(client_->pending_manager());
}
-TEST_F(CredentialManagerImplTest, CredentialManagerOnRequireUserMediation) {
+TEST_F(CredentialManagerImplTest, CredentialManagerOnPreventSilentAccess) {
store_->AddLogin(form_);
store_->AddLogin(subdomain_form_);
store_->AddLogin(cross_origin_form_);
@@ -725,7 +727,7 @@ TEST_F(CredentialManagerImplTest, CredentialManagerOnRequireUserMediation) {
EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
bool called = false;
- CallRequireUserMediation(base::Bind(&RespondCallback, &called));
+ CallPreventSilentAccess(base::Bind(&RespondCallback, &called));
RunAllPendingTasks();
@@ -742,7 +744,7 @@ TEST_F(CredentialManagerImplTest, CredentialManagerOnRequireUserMediation) {
}
TEST_F(CredentialManagerImplTest,
- CredentialManagerOnRequireUserMediationIncognito) {
+ CredentialManagerOnPreventSilentAccessIncognito) {
EXPECT_CALL(*client_, IsSavingAndFillingEnabledForCurrentPage())
.WillRepeatedly(testing::Return(false));
store_->AddLogin(form_);
@@ -754,7 +756,7 @@ TEST_F(CredentialManagerImplTest,
EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
bool called = false;
- CallRequireUserMediation(base::Bind(&RespondCallback, &called));
+ CallPreventSilentAccess(base::Bind(&RespondCallback, &called));
RunAllPendingTasks();
EXPECT_TRUE(called);
@@ -766,7 +768,7 @@ TEST_F(CredentialManagerImplTest,
}
TEST_F(CredentialManagerImplTest,
- CredentialManagerOnRequireUserMediationWithAffiliation) {
+ CredentialManagerOnPreventSilentAccessWithAffiliation) {
store_->AddLogin(form_);
store_->AddLogin(cross_origin_form_);
store_->AddLogin(affiliated_form1_);
@@ -791,7 +793,7 @@ TEST_F(CredentialManagerImplTest,
EXPECT_FALSE(passwords[affiliated_form2_.signon_realm][0].skip_zero_click);
bool called = false;
- CallRequireUserMediation(base::Bind(&RespondCallback, &called));
+ CallPreventSilentAccess(base::Bind(&RespondCallback, &called));
RunAllPendingTasks();
passwords = store_->stored_passwords();
@@ -811,8 +813,8 @@ TEST_F(CredentialManagerImplTest,
.Times(testing::Exactly(0));
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
- ExpectCredentialType(false, true, federations,
- CredentialType::CREDENTIAL_TYPE_EMPTY);
+ ExpectCredentialType(CredentialMediationRequirement::kOptional, true,
+ federations, CredentialType::CREDENTIAL_TYPE_EMPTY);
}
TEST_F(CredentialManagerImplTest,
@@ -824,8 +826,8 @@ TEST_F(CredentialManagerImplTest,
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
std::vector<GURL> federations;
- ExpectCredentialType(false, true, federations,
- CredentialType::CREDENTIAL_TYPE_EMPTY);
+ ExpectCredentialType(CredentialMediationRequirement::kOptional, true,
+ federations, CredentialType::CREDENTIAL_TYPE_EMPTY);
}
TEST_F(CredentialManagerImplTest,
@@ -837,7 +839,8 @@ TEST_F(CredentialManagerImplTest,
UnorderedElementsAre(Pointee(subdomain_form_)), _, _));
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(0);
- ExpectCredentialType(false, true, std::vector<GURL>(),
+ ExpectCredentialType(CredentialMediationRequirement::kOptional, true,
+ std::vector<GURL>(),
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -852,7 +855,8 @@ TEST_F(CredentialManagerImplTest,
Pointee(form_)),
_, _));
- ExpectCredentialType(false, true, std::vector<GURL>(),
+ ExpectCredentialType(CredentialMediationRequirement::kOptional, true,
+ std::vector<GURL>(),
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -867,7 +871,8 @@ TEST_F(CredentialManagerImplTest,
store_->AddLogin(duplicate);
std::vector<GURL> federations;
- ExpectZeroClickSignInSuccess(false, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kOptional, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -910,7 +915,7 @@ TEST_F(CredentialManagerImplTest,
base::Optional<CredentialInfo> credential;
std::vector<GURL> federations;
federations.push_back(GURL("https://google.com/"));
- CallGet(false, true, federations,
+ CallGet(CredentialMediationRequirement::kOptional, true, federations,
base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -927,8 +932,8 @@ TEST_F(CredentialManagerImplTest,
.Times(testing::Exactly(0));
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
- ExpectCredentialType(false, true, federations,
- CredentialType::CREDENTIAL_TYPE_EMPTY);
+ ExpectCredentialType(CredentialMediationRequirement::kOptional, true,
+ federations, CredentialType::CREDENTIAL_TYPE_EMPTY);
}
TEST_F(CredentialManagerImplTest,
@@ -944,7 +949,7 @@ TEST_F(CredentialManagerImplTest,
bool called = false;
mojom::CredentialManagerError error;
base::Optional<CredentialInfo> credential;
- CallGet(false, true, federations,
+ CallGet(CredentialMediationRequirement::kOptional, true, federations,
base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -961,7 +966,8 @@ TEST_F(
.Times(testing::Exactly(0));
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest,
@@ -973,7 +979,8 @@ TEST_F(CredentialManagerImplTest,
EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -986,7 +993,8 @@ TEST_F(CredentialManagerImplTest,
EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
- ExpectZeroClickSignInFailure(true, false, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, false,
+ federations);
}
TEST_F(CredentialManagerImplTest,
@@ -1001,7 +1009,8 @@ TEST_F(CredentialManagerImplTest,
EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_FEDERATED);
}
@@ -1017,7 +1026,8 @@ TEST_F(CredentialManagerImplTest,
EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest,
@@ -1036,7 +1046,8 @@ TEST_F(CredentialManagerImplTest,
// We pass in 'true' for the 'include_passwords' argument to ensure that
// password-type credentials are included as potential matches.
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -1056,7 +1067,8 @@ TEST_F(CredentialManagerImplTest,
// We pass in 'false' for the 'include_passwords' argument to ensure that
// password-type credentials are excluded as potential matches.
- ExpectZeroClickSignInFailure(true, false, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, false,
+ federations);
}
TEST_F(CredentialManagerImplTest,
@@ -1078,7 +1090,8 @@ TEST_F(CredentialManagerImplTest,
->ExpectCallToGetAffiliatedAndroidRealms(
cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_FEDERATED);
}
@@ -1101,7 +1114,8 @@ TEST_F(CredentialManagerImplTest,
->ExpectCallToGetAffiliatedAndroidRealms(
cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest, RequestCredentialWithoutFirstRun) {
@@ -1114,7 +1128,8 @@ TEST_F(CredentialManagerImplTest, RequestCredentialWithoutFirstRun) {
NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_)))
.Times(1);
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest, RequestCredentialWithFirstRunAndSkip) {
@@ -1128,7 +1143,8 @@ TEST_F(CredentialManagerImplTest, RequestCredentialWithFirstRunAndSkip) {
NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_)))
.Times(1);
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest, RequestCredentialWithTLSErrors) {
@@ -1140,7 +1156,8 @@ TEST_F(CredentialManagerImplTest, RequestCredentialWithTLSErrors) {
std::vector<GURL> federations;
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest, RequestCredentialWhilePrerendering) {
@@ -1152,7 +1169,8 @@ TEST_F(CredentialManagerImplTest, RequestCredentialWhilePrerendering) {
std::vector<GURL> federations;
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest,
@@ -1166,8 +1184,8 @@ TEST_F(CredentialManagerImplTest,
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
// With two items in the password store, we shouldn't get credentials back.
- ExpectCredentialType(true, true, federations,
- CredentialType::CREDENTIAL_TYPE_EMPTY);
+ ExpectCredentialType(CredentialMediationRequirement::kSilent, true,
+ federations, CredentialType::CREDENTIAL_TYPE_EMPTY);
}
TEST_F(CredentialManagerImplTest,
@@ -1183,8 +1201,8 @@ TEST_F(CredentialManagerImplTest,
// With two items in the password store, we shouldn't get credentials back,
// even though only one item has |skip_zero_click| set |false|.
- ExpectCredentialType(true, true, federations,
- CredentialType::CREDENTIAL_TYPE_EMPTY);
+ ExpectCredentialType(CredentialMediationRequirement::kSilent, true,
+ federations, CredentialType::CREDENTIAL_TYPE_EMPTY);
}
TEST_F(CredentialManagerImplTest,
@@ -1201,8 +1219,8 @@ TEST_F(CredentialManagerImplTest,
// We only have cross-origin zero-click credentials; they should not be
// returned.
- ExpectCredentialType(true, true, federations,
- CredentialType::CREDENTIAL_TYPE_EMPTY);
+ ExpectCredentialType(CredentialMediationRequirement::kSilent, true,
+ federations, CredentialType::CREDENTIAL_TYPE_EMPTY);
}
TEST_F(CredentialManagerImplTest,
@@ -1220,14 +1238,14 @@ TEST_F(CredentialManagerImplTest,
mojom::CredentialManagerError error_1;
base::Optional<CredentialInfo> credential_1;
CallGet(
- false, true, federations,
+ CredentialMediationRequirement::kOptional, true, federations,
base::Bind(&GetCredentialCallback, &called_1, &error_1, &credential_1));
// 2nd request.
bool called_2 = false;
mojom::CredentialManagerError error_2;
base::Optional<CredentialInfo> credential_2;
CallGet(
- false, true, federations,
+ CredentialMediationRequirement::kOptional, true, federations,
base::Bind(&GetCredentialCallback, &called_2, &error_2, &credential_2));
EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _))
@@ -1284,7 +1302,7 @@ TEST_F(CredentialManagerImplTest, ResetSkipZeroClickAfterPrompt) {
bool called = false;
mojom::CredentialManagerError error;
base::Optional<CredentialInfo> credential;
- CallGet(false, true, federations,
+ CallGet(CredentialMediationRequirement::kOptional, true, federations,
base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -1320,7 +1338,7 @@ TEST_F(CredentialManagerImplTest, NoResetSkipZeroClickAfterPromptInIncognito) {
bool called = false;
mojom::CredentialManagerError error;
base::Optional<CredentialInfo> credential;
- CallGet(false, true, std::vector<GURL>(),
+ CallGet(CredentialMediationRequirement::kOptional, true, std::vector<GURL>(),
base::Bind(&GetCredentialCallback, &called, &error, &credential));
RunAllPendingTasks();
@@ -1341,8 +1359,8 @@ TEST_F(CredentialManagerImplTest, IncognitoZeroClickRequestCredential) {
.Times(testing::Exactly(0));
EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
- ExpectCredentialType(true, true, federations,
- CredentialType::CREDENTIAL_TYPE_EMPTY);
+ ExpectCredentialType(CredentialMediationRequirement::kSilent, true,
+ federations, CredentialType::CREDENTIAL_TYPE_EMPTY);
}
TEST_F(CredentialManagerImplTest, ZeroClickWithAffiliatedFormInPasswordStore) {
@@ -1361,7 +1379,8 @@ TEST_F(CredentialManagerImplTest, ZeroClickWithAffiliatedFormInPasswordStore) {
->ExpectCallToGetAffiliatedAndroidRealms(
cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -1383,7 +1402,8 @@ TEST_F(CredentialManagerImplTest,
->ExpectCallToGetAffiliatedAndroidRealms(
cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest,
@@ -1410,7 +1430,8 @@ TEST_F(CredentialManagerImplTest,
->ExpectCallToGetAffiliatedAndroidRealms(digest, affiliated_realms);
std::vector<GURL> federations;
- ExpectZeroClickSignInFailure(true, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ federations);
}
TEST_F(CredentialManagerImplTest,
@@ -1430,7 +1451,8 @@ TEST_F(CredentialManagerImplTest,
->ExpectCallToGetAffiliatedAndroidRealms(
cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -1438,7 +1460,8 @@ TEST_F(CredentialManagerImplTest, ZeroClickWithPSLCredential) {
subdomain_form_.skip_zero_click = false;
store_->AddLogin(subdomain_form_);
- ExpectZeroClickSignInFailure(true, true, std::vector<GURL>());
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true,
+ std::vector<GURL>());
}
TEST_F(CredentialManagerImplTest, ZeroClickWithPSLAndNormalCredentials) {
@@ -1450,7 +1473,8 @@ TEST_F(CredentialManagerImplTest, ZeroClickWithPSLAndNormalCredentials) {
store_->AddLogin(subdomain_form_);
std::vector<GURL> federations = {GURL("https://google.com/")};
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_FEDERATED);
}
@@ -1464,7 +1488,8 @@ TEST_F(CredentialManagerImplTest, ZeroClickAfterMigratingHttpCredential) {
store_->AddLogin(form_);
std::vector<GURL> federations;
- ExpectZeroClickSignInSuccess(true, true, federations,
+ ExpectZeroClickSignInSuccess(CredentialMediationRequirement::kSilent, true,
+ federations,
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
@@ -1473,7 +1498,30 @@ TEST_F(CredentialManagerImplTest, MigrateWithEmptyStore) {
NavigateAndCommit(GURL("http://127.0.0.1:8000/"));
std::vector<GURL> federations;
- ExpectZeroClickSignInFailure(false, true, federations);
+ ExpectZeroClickSignInFailure(CredentialMediationRequirement::kOptional, true,
+ federations);
+}
+
+TEST_F(CredentialManagerImplTest, MediationRequiredPreventsAutoSignIn) {
+ form_.skip_zero_click = false;
+ store_->AddLogin(form_);
+
+ std::vector<GURL> federations;
+ bool called = false;
+ mojom::CredentialManagerError error;
+ base::Optional<CredentialInfo> credential;
+
+ EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _))
+ .Times(testing::Exactly(1));
+ EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(testing::Exactly(0));
+ CallGet(CredentialMediationRequirement::kRequired, true, federations,
+ base::Bind(&GetCredentialCallback, &called, &error, &credential));
+
+ RunAllPendingTasks();
+
+ EXPECT_TRUE(called);
+ EXPECT_EQ(mojom::CredentialManagerError::SUCCESS, error);
+ EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_PASSWORD, credential->type);
}
TEST_F(CredentialManagerImplTest, GetSynthesizedFormForOrigin) {
diff --git a/chromium/components/password_manager/content/common/OWNERS b/chromium/components/password_manager/content/common/OWNERS
index 154435234ea..2c44a463856 100644
--- a/chromium/components/password_manager/content/common/OWNERS
+++ b/chromium/components/password_manager/content/common/OWNERS
@@ -2,3 +2,5 @@ per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
per-file *_struct_traits*.*=set noparent
per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/password_manager/content/common/credential_manager.mojom b/chromium/components/password_manager/content/common/credential_manager.mojom
index cc4981d8bc8..ea7cf47559a 100644
--- a/chromium/components/password_manager/content/common/credential_manager.mojom
+++ b/chromium/components/password_manager/content/common/credential_manager.mojom
@@ -13,6 +13,12 @@ enum CredentialType {
FEDERATED
};
+enum CredentialMediationRequirement {
+ kSilent,
+ kOptional,
+ kRequired
+};
+
enum CredentialManagerError {
SUCCESS,
DISABLED,
@@ -34,13 +40,13 @@ interface CredentialManager {
// Store credential. For navigator.credentials.store().
Store(CredentialInfo credential) => ();
- // Require user mediation. For navigator.credentials.requireUserMediation().
- RequireUserMediation() => ();
+ // Require user mediation. For navigator.credentials.preventSilentAccess().
+ PreventSilentAccess() => ();
// Get Credential. For navigator.credentials.get().
// The result callback will return a non-null and valid CredentialInfo
// if succeeded, or null with a CredentialManagerError if failed.
- Get(bool zero_click_only,
+ Get(CredentialMediationRequirement mediation,
bool include_passwords,
array<url.mojom.Url> federations)
=> (CredentialManagerError error, CredentialInfo? credential);
diff --git a/chromium/components/password_manager/content/common/credential_manager.typemap b/chromium/components/password_manager/content/common/credential_manager.typemap
index 180b08170aa..571ba267ca3 100644
--- a/chromium/components/password_manager/content/common/credential_manager.typemap
+++ b/chromium/components/password_manager/content/common/credential_manager.typemap
@@ -16,5 +16,6 @@ deps = [
type_mappings = [
"password_manager.mojom.CredentialType=password_manager::CredentialType",
+ "password_manager.mojom.CredentialMediationRequirement=password_manager::CredentialMediationRequirement",
"password_manager.mojom.CredentialInfo=password_manager::CredentialInfo",
]
diff --git a/chromium/components/password_manager/content/common/credential_manager_struct_traits.cc b/chromium/components/password_manager/content/common/credential_manager_struct_traits.cc
index 315ebaf39aa..4ca8787b46d 100644
--- a/chromium/components/password_manager/content/common/credential_manager_struct_traits.cc
+++ b/chromium/components/password_manager/content/common/credential_manager_struct_traits.cc
@@ -49,6 +49,45 @@ bool EnumTraits<mojom::CredentialType, CredentialType>::FromMojom(
}
// static
+mojom::CredentialMediationRequirement EnumTraits<
+ mojom::CredentialMediationRequirement,
+ CredentialMediationRequirement>::ToMojom(CredentialMediationRequirement
+ input) {
+ switch (input) {
+ case CredentialMediationRequirement::kSilent:
+ return mojom::CredentialMediationRequirement::kSilent;
+ case CredentialMediationRequirement::kOptional:
+ return mojom::CredentialMediationRequirement::kOptional;
+ case CredentialMediationRequirement::kRequired:
+ return mojom::CredentialMediationRequirement::kRequired;
+ }
+
+ NOTREACHED();
+ return mojom::CredentialMediationRequirement::kOptional;
+}
+
+// static
+bool EnumTraits<mojom::CredentialMediationRequirement,
+ CredentialMediationRequirement>::
+ FromMojom(mojom::CredentialMediationRequirement input,
+ CredentialMediationRequirement* output) {
+ switch (input) {
+ case mojom::CredentialMediationRequirement::kSilent:
+ *output = CredentialMediationRequirement::kSilent;
+ return true;
+ case mojom::CredentialMediationRequirement::kOptional:
+ *output = CredentialMediationRequirement::kOptional;
+ return true;
+ case mojom::CredentialMediationRequirement::kRequired:
+ *output = CredentialMediationRequirement::kRequired;
+ return true;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+// static
bool StructTraits<mojom::CredentialInfoDataView, CredentialInfo>::Read(
mojom::CredentialInfoDataView data,
CredentialInfo* out) {
diff --git a/chromium/components/password_manager/content/common/credential_manager_struct_traits.h b/chromium/components/password_manager/content/common/credential_manager_struct_traits.h
index cf8c5a7c33e..aa544b782ce 100644
--- a/chromium/components/password_manager/content/common/credential_manager_struct_traits.h
+++ b/chromium/components/password_manager/content/common/credential_manager_struct_traits.h
@@ -22,6 +22,16 @@ struct EnumTraits<password_manager::mojom::CredentialType,
};
template <>
+struct EnumTraits<password_manager::mojom::CredentialMediationRequirement,
+ password_manager::CredentialMediationRequirement> {
+ static password_manager::mojom::CredentialMediationRequirement ToMojom(
+ password_manager::CredentialMediationRequirement input);
+ static bool FromMojom(
+ password_manager::mojom::CredentialMediationRequirement input,
+ password_manager::CredentialMediationRequirement* output);
+};
+
+template <>
struct StructTraits<password_manager::mojom::CredentialInfoDataView,
password_manager::CredentialInfo> {
static password_manager::CredentialType type(
diff --git a/chromium/components/password_manager/content/renderer/credential_manager_client.cc b/chromium/components/password_manager/content/renderer/credential_manager_client.cc
index b859abb1185..6a6d0b2eba4 100644
--- a/chromium/components/password_manager/content/renderer/credential_manager_client.cc
+++ b/chromium/components/password_manager/content/renderer/credential_manager_client.cc
@@ -13,9 +13,9 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "components/password_manager/core/common/credential_manager_types.h"
+#include "content/public/common/associated_interface_provider.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebCredential.h"
#include "third_party/WebKit/public/platform/WebCredentialManagerError.h"
#include "third_party/WebKit/public/platform/WebFederatedCredential.h"
@@ -65,6 +65,21 @@ std::unique_ptr<blink::WebCredential> CredentialInfoToWebCredential(
return nullptr;
}
+CredentialMediationRequirement GetCredentialMediationRequirementFromBlink(
+ blink::WebCredentialMediationRequirement mediation) {
+ switch (mediation) {
+ case blink::WebCredentialMediationRequirement::kSilent:
+ return CredentialMediationRequirement::kSilent;
+ case blink::WebCredentialMediationRequirement::kOptional:
+ return CredentialMediationRequirement::kOptional;
+ case blink::WebCredentialMediationRequirement::kRequired:
+ return CredentialMediationRequirement::kRequired;
+ }
+
+ NOTREACHED();
+ return CredentialMediationRequirement::kOptional;
+}
+
blink::WebCredentialManagerError GetWebCredentialManagerErrorFromMojo(
mojom::CredentialManagerError error) {
switch (error) {
@@ -216,18 +231,18 @@ void CredentialManagerClient::DispatchStore(
base::Owned(new NotificationCallbacksWrapper(callbacks))));
}
-void CredentialManagerClient::DispatchRequireUserMediation(
+void CredentialManagerClient::DispatchPreventSilentAccess(
blink::WebCredentialManagerClient::NotificationCallbacks* callbacks) {
DCHECK(callbacks);
ConnectToMojoCMIfNeeded();
- mojo_cm_service_->RequireUserMediation(
+ mojo_cm_service_->PreventSilentAccess(
base::Bind(&RespondToNotificationCallback,
base::Owned(new NotificationCallbacksWrapper(callbacks))));
}
void CredentialManagerClient::DispatchGet(
- bool zero_click_only,
+ blink::WebCredentialMediationRequirement mediation,
bool include_passwords,
const blink::WebVector<blink::WebURL>& federations,
RequestCallbacks* callbacks) {
@@ -239,7 +254,8 @@ void CredentialManagerClient::DispatchGet(
federation_vector.push_back(federations[i]);
mojo_cm_service_->Get(
- zero_click_only, include_passwords, federation_vector,
+ GetCredentialMediationRequirementFromBlink(mediation), include_passwords,
+ federation_vector,
base::Bind(&RespondToRequestCallback,
base::Owned(new RequestCallbacksWrapper(callbacks))));
}
@@ -249,7 +265,18 @@ void CredentialManagerClient::ConnectToMojoCMIfNeeded() {
return;
content::RenderFrame* main_frame = render_view()->GetMainRenderFrame();
- main_frame->GetRemoteInterfaces()->GetInterface(&mojo_cm_service_);
+ main_frame->GetRemoteAssociatedInterfaces()->GetInterface(&mojo_cm_service_);
+
+ // The remote end of the pipe will be forcibly closed by the browser side
+ // after each main frame navigation. Set up an error handler to reset the
+ // local end so that there will be an attempt at reestablishing the connection
+ // at the next call to the API.
+ mojo_cm_service_.set_connection_error_handler(base::Bind(
+ &CredentialManagerClient::OnMojoConnectionError, base::Unretained(this)));
+}
+
+void CredentialManagerClient::OnMojoConnectionError() {
+ mojo_cm_service_.reset();
}
void CredentialManagerClient::OnDestruct() {
diff --git a/chromium/components/password_manager/content/renderer/credential_manager_client.h b/chromium/components/password_manager/content/renderer/credential_manager_client.h
index 388ed941ec8..513b389ecd2 100644
--- a/chromium/components/password_manager/content/renderer/credential_manager_client.h
+++ b/chromium/components/password_manager/content/renderer/credential_manager_client.h
@@ -11,6 +11,7 @@
#include "content/public/renderer/render_view_observer.h"
#include "third_party/WebKit/public/platform/WebCredentialManagerClient.h"
#include "third_party/WebKit/public/platform/WebCredentialManagerError.h"
+#include "third_party/WebKit/public/platform/WebCredentialMediationRequirement.h"
#include "third_party/WebKit/public/platform/WebVector.h"
namespace blink {
@@ -46,8 +47,8 @@ class CredentialManagerClient : public blink::WebCredentialManagerClient,
void DispatchStore(
const blink::WebCredential& credential,
WebCredentialManagerClient::NotificationCallbacks* callbacks) override;
- void DispatchRequireUserMediation(NotificationCallbacks* callbacks) override;
- void DispatchGet(bool zero_click_only,
+ void DispatchPreventSilentAccess(NotificationCallbacks* callbacks) override;
+ void DispatchGet(blink::WebCredentialMediationRequirement mediation,
bool include_passwords,
const blink::WebVector<blink::WebURL>& federations,
RequestCallbacks* callbacks) override;
@@ -57,8 +58,9 @@ class CredentialManagerClient : public blink::WebCredentialManagerClient,
void OnDestruct() override;
void ConnectToMojoCMIfNeeded();
+ void OnMojoConnectionError();
- mojom::CredentialManagerPtr mojo_cm_service_;
+ mojom::CredentialManagerAssociatedPtr mojo_cm_service_;
DISALLOW_COPY_AND_ASSIGN(CredentialManagerClient);
};
diff --git a/chromium/components/password_manager/content/renderer/credential_manager_client_browsertest.cc b/chromium/components/password_manager/content/renderer/credential_manager_client_browsertest.cc
index 8b25db6779c..e384b24c885 100644
--- a/chromium/components/password_manager/content/renderer/credential_manager_client_browsertest.cc
+++ b/chromium/components/password_manager/content/renderer/credential_manager_client_browsertest.cc
@@ -8,20 +8,23 @@
#include <memory>
#include <tuple>
+#include <utility>
#include "base/location.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/common/associated_interface_provider.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "content/public/test/render_view_test.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCredential.h"
#include "third_party/WebKit/public/platform/WebCredentialManagerClient.h"
#include "third_party/WebKit/public/platform/WebCredentialManagerError.h"
+#include "third_party/WebKit/public/platform/WebCredentialMediationRequirement.h"
#include "third_party/WebKit/public/platform/WebPasswordCredential.h"
namespace password_manager {
@@ -37,41 +40,42 @@ class FakeCredentialManager : public mojom::CredentialManager {
FakeCredentialManager() {}
~FakeCredentialManager() override {}
- void BindRequest(mojom::CredentialManagerRequest request) {
+ void BindRequest(mojom::CredentialManagerAssociatedRequest request) {
bindings_.AddBinding(this, std::move(request));
}
private:
// mojom::CredentialManager methods:
void Store(const CredentialInfo& credential,
- const StoreCallback& callback) override {
- callback.Run();
+ StoreCallback callback) override {
+ std::move(callback).Run();
}
- void RequireUserMediation(
- const RequireUserMediationCallback& callback) override {
- callback.Run();
+ void PreventSilentAccess(PreventSilentAccessCallback callback) override {
+ std::move(callback).Run();
}
- void Get(bool zero_click_only,
+ void Get(CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& federations,
- const GetCallback& callback) override {
+ GetCallback callback) override {
const std::string& url = federations[0].spec();
if (url == kTestCredentialPassword) {
CredentialInfo info;
info.type = CredentialType::CREDENTIAL_TYPE_PASSWORD;
- callback.Run(mojom::CredentialManagerError::SUCCESS, info);
+ std::move(callback).Run(mojom::CredentialManagerError::SUCCESS, info);
} else if (url == kTestCredentialEmpty) {
- callback.Run(mojom::CredentialManagerError::SUCCESS, CredentialInfo());
+ std::move(callback).Run(mojom::CredentialManagerError::SUCCESS,
+ CredentialInfo());
} else if (url == kTestCredentialReject) {
- callback.Run(mojom::CredentialManagerError::PASSWORDSTOREUNAVAILABLE,
- base::nullopt);
+ std::move(callback).Run(
+ mojom::CredentialManagerError::PASSWORDSTOREUNAVAILABLE,
+ base::nullopt);
}
}
- mojo::BindingSet<mojom::CredentialManager> bindings_;
+ mojo::AssociatedBindingSet<mojom::CredentialManager> bindings_;
};
class CredentialManagerClientTest : public content::RenderViewTest {
@@ -84,10 +88,9 @@ class CredentialManagerClientTest : public content::RenderViewTest {
content::RenderViewTest::SetUp();
client_.reset(new CredentialManagerClient(view_));
- service_manager::InterfaceProvider* remote_interfaces =
- view_->GetMainRenderFrame()->GetRemoteInterfaces();
- service_manager::InterfaceProvider::TestApi test_api(remote_interfaces);
- test_api.SetBinderForName(
+ content::AssociatedInterfaceProvider* remote_interfaces =
+ view_->GetMainRenderFrame()->GetRemoteAssociatedInterfaces();
+ remote_interfaces->OverrideBinderForTesting(
mojom::CredentialManager::Name_,
base::Bind(&CredentialManagerClientTest::BindCredentialManager,
base::Unretained(this)));
@@ -104,9 +107,9 @@ class CredentialManagerClientTest : public content::RenderViewTest {
bool callback_succeeded() const { return callback_succeeded_; }
void set_callback_succeeded(bool state) { callback_succeeded_ = state; }
- void BindCredentialManager(mojo::ScopedMessagePipeHandle handle) {
+ void BindCredentialManager(mojo::ScopedInterfaceEndpointHandle handle) {
fake_cm_.BindRequest(
- mojo::MakeRequest<mojom::CredentialManager>(std::move(handle)));
+ mojom::CredentialManagerAssociatedRequest(std::move(handle)));
}
std::unique_ptr<blink::WebPasswordCredential> credential_;
@@ -193,7 +196,7 @@ TEST_F(CredentialManagerClientTest, SendStore) {
TEST_F(CredentialManagerClientTest, SendRequestUserMediation) {
std::unique_ptr<TestNotificationCallbacks> callbacks(
new TestNotificationCallbacks(this));
- client_->DispatchRequireUserMediation(callbacks.release());
+ client_->DispatchPreventSilentAccess(callbacks.release());
RunAllPendingTasks();
@@ -206,7 +209,8 @@ TEST_F(CredentialManagerClientTest, SendRequestCredential) {
new TestRequestCallbacks(this));
std::vector<GURL> federations;
federations.push_back(GURL(kTestCredentialPassword));
- client_->DispatchGet(false, true, federations, callbacks.release());
+ client_->DispatchGet(blink::WebCredentialMediationRequirement::kOptional,
+ true, federations, callbacks.release());
RunAllPendingTasks();
@@ -221,7 +225,8 @@ TEST_F(CredentialManagerClientTest, SendRequestCredentialEmpty) {
new TestRequestCallbacks(this));
std::vector<GURL> federations;
federations.push_back(GURL(kTestCredentialEmpty));
- client_->DispatchGet(false, true, federations, callbacks.release());
+ client_->DispatchGet(blink::WebCredentialMediationRequirement::kOptional,
+ true, federations, callbacks.release());
RunAllPendingTasks();
@@ -235,7 +240,8 @@ TEST_F(CredentialManagerClientTest, SendRequestCredentialReject) {
new TestRequestCallbacks(this));
std::vector<GURL> federations;
federations.push_back(GURL(kTestCredentialReject));
- client_->DispatchGet(false, true, federations, callbacks.release());
+ client_->DispatchGet(blink::WebCredentialMediationRequirement::kOptional,
+ true, federations, callbacks.release());
RunAllPendingTasks();
diff --git a/chromium/components/password_manager/core/browser/BUILD.gn b/chromium/components/password_manager/core/browser/BUILD.gn
index d7be596e6c7..056d7d6164c 100644
--- a/chromium/components/password_manager/core/browser/BUILD.gn
+++ b/chromium/components/password_manager/core/browser/BUILD.gn
@@ -35,10 +35,10 @@ static_library("browser") {
"credential_manager_logger.h",
"credential_manager_password_form_manager.cc",
"credential_manager_password_form_manager.h",
+ "credential_manager_pending_prevent_silent_access_task.cc",
+ "credential_manager_pending_prevent_silent_access_task.h",
"credential_manager_pending_request_task.cc",
"credential_manager_pending_request_task.h",
- "credential_manager_pending_require_user_mediation_task.cc",
- "credential_manager_pending_require_user_mediation_task.h",
"credentials_filter.h",
"export/csv_writer.cc",
"export/csv_writer.h",
@@ -122,6 +122,8 @@ static_library("browser") {
"sql_table_builder.h",
"statistics_table.cc",
"statistics_table.h",
+ "suppressed_form_fetcher.cc",
+ "suppressed_form_fetcher.h",
"test_affiliation_fetcher_factory.h",
"webdata/logins_table.cc",
"webdata/logins_table.h",
@@ -163,6 +165,7 @@ static_library("browser") {
"//components/url_formatter",
"//components/variations",
"//components/webdata/common",
+ "//crypto",
"//google_apis",
"//net",
"//sql",
@@ -319,6 +322,7 @@ source_set("unit_tests") {
"psl_matching_helper_unittest.cc",
"sql_table_builder_unittest.cc",
"statistics_table_unittest.cc",
+ "suppressed_form_fetcher_unittest.cc",
]
if (is_mac) {
sources -= [ "password_store_default_unittest.cc" ]
diff --git a/chromium/components/password_manager/core/browser/DEPS b/chromium/components/password_manager/core/browser/DEPS
index 2b537df53bd..d4cbab297ac 100644
--- a/chromium/components/password_manager/core/browser/DEPS
+++ b/chromium/components/password_manager/core/browser/DEPS
@@ -9,6 +9,7 @@ include_rules = [
"+components/url_formatter",
"+components/variations",
"+components/webdata/common",
+ "+crypto",
"+google_apis",
"+grit",
]
diff --git a/chromium/components/password_manager/core/browser/affiliation_fetcher.cc b/chromium/components/password_manager/core/browser/affiliation_fetcher.cc
index 15eae8c99d6..fb486e7bb93 100644
--- a/chromium/components/password_manager/core/browser/affiliation_fetcher.cc
+++ b/chromium/components/password_manager/core/browser/affiliation_fetcher.cc
@@ -119,7 +119,7 @@ void AffiliationFetcher::StartRequest() {
chrome_policy {
SyncDisabled {
policy_options {mode: MANDATORY}
- SyncDisabled: True
+ SyncDisabled: true
}
}
})");
diff --git a/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.cc b/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.cc
index e2523ec7a17..c4d79d28522 100644
--- a/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.cc
+++ b/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.cc
@@ -164,6 +164,16 @@ void BrowserSavePasswordProgressLogger::LogString(StringID label,
LogValue(label, base::Value(s));
}
+void BrowserSavePasswordProgressLogger::LogSuccessfulSubmissionIndicatorEvent(
+ autofill::PasswordForm::SubmissionIndicatorEvent event) {
+ std::ostringstream submission_event_string_stream;
+ submission_event_string_stream << event;
+ std::string message =
+ GetStringFromID(STRING_SUCCESSFUL_SUBMISSION_INDICATOR_EVENT) + ": " +
+ submission_event_string_stream.str();
+ SendLog(message);
+}
+
void BrowserSavePasswordProgressLogger::SendLog(const std::string& log) {
log_manager_->LogSavePasswordProgress(log);
}
diff --git a/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.h b/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.h
index d5c94232dec..de2f893b0b5 100644
--- a/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.h
+++ b/chromium/components/password_manager/core/browser/browser_save_password_progress_logger.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/macros.h"
+#include "components/autofill/core/common/password_form.h"
#include "components/autofill/core/common/save_password_progress_logger.h"
#include "url/gurl.h"
@@ -45,6 +46,10 @@ class BrowserSavePasswordProgressLogger
// passed to SendLog for display.
void LogString(StringID label, const std::string& s);
+ // Log a password successful submission event.
+ void LogSuccessfulSubmissionIndicatorEvent(
+ autofill::PasswordForm::SubmissionIndicatorEvent event);
+
protected:
// autofill::SavePasswordProgressLogger:
void SendLog(const std::string& log) override;
diff --git a/chromium/components/password_manager/core/browser/credential_manager_logger.cc b/chromium/components/password_manager/core/browser/credential_manager_logger.cc
index f5173c1868a..ac083ae6b32 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_logger.cc
+++ b/chromium/components/password_manager/core/browser/credential_manager_logger.cc
@@ -21,11 +21,22 @@ CredentialManagerLogger::~CredentialManagerLogger() = default;
void CredentialManagerLogger::LogRequestCredential(
const GURL& url,
- bool zero_click_only,
+ CredentialMediationRequirement mediation,
const std::vector<GURL>& federations) {
std::string s("CM API get credentials: origin=" +
SavePasswordProgressLogger::ScrubURL(url));
- s += ", zero_click_only=" + base::IntToString(zero_click_only);
+ s += ", mediation=";
+ switch (mediation) {
+ case CredentialMediationRequirement::kSilent:
+ s += "silent";
+ break;
+ case CredentialMediationRequirement::kOptional:
+ s += "optional";
+ break;
+ case CredentialMediationRequirement::kRequired:
+ s += "required";
+ break;
+ }
s += ", federations=";
for (const GURL& federation_provider : federations)
s += SavePasswordProgressLogger::ScrubURL(federation_provider) + ", ";
@@ -49,7 +60,7 @@ void CredentialManagerLogger::LogStoreCredential(const GURL& url,
log_manager_->LogSavePasswordProgress(s);
}
-void CredentialManagerLogger::LogRequireUserMediation(const GURL& url) {
+void CredentialManagerLogger::LogPreventSilentAccess(const GURL& url) {
std::string s("CM API sign out: origin=" +
SavePasswordProgressLogger::ScrubURL(url));
log_manager_->LogSavePasswordProgress(s);
diff --git a/chromium/components/password_manager/core/browser/credential_manager_logger.h b/chromium/components/password_manager/core/browser/credential_manager_logger.h
index c99f7f692a3..ff342e572e9 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_logger.h
+++ b/chromium/components/password_manager/core/browser/credential_manager_logger.h
@@ -23,11 +23,11 @@ class CredentialManagerLogger {
~CredentialManagerLogger();
void LogRequestCredential(const GURL& url,
- bool zero_click_only,
+ CredentialMediationRequirement mediation,
const std::vector<GURL>& federations);
void LogSendCredential(const GURL& url, CredentialType type);
void LogStoreCredential(const GURL& url, CredentialType type);
- void LogRequireUserMediation(const GURL& url);
+ void LogPreventSilentAccess(const GURL& url);
private:
// The LogManager to which logs can be sent for display.
diff --git a/chromium/components/password_manager/core/browser/credential_manager_logger_unittest.cc b/chromium/components/password_manager/core/browser/credential_manager_logger_unittest.cc
index af6a98faba5..74e31a547f5 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_logger_unittest.cc
+++ b/chromium/components/password_manager/core/browser/credential_manager_logger_unittest.cc
@@ -53,7 +53,8 @@ TEST_F(CredentialManagerLoggerTest, LogRequestCredential) {
EXPECT_CALL(log_manager(),
LogSavePasswordProgress(
AllOf(HasSubstr(kSiteOrigin), HasSubstr(kFederationOrigin))));
- logger().LogRequestCredential(GURL(kSiteOrigin), true,
+ logger().LogRequestCredential(GURL(kSiteOrigin),
+ CredentialMediationRequirement::kSilent,
{GURL(kFederationOrigin)});
}
@@ -69,9 +70,9 @@ TEST_F(CredentialManagerLoggerTest, LogStoreCredential) {
CredentialType::CREDENTIAL_TYPE_PASSWORD);
}
-TEST_F(CredentialManagerLoggerTest, LogRequireUserMediation) {
+TEST_F(CredentialManagerLoggerTest, LogPreventSilentAccess) {
EXPECT_CALL(log_manager(), LogSavePasswordProgress(HasSubstr(kSiteOrigin)));
- logger().LogRequireUserMediation(GURL(kSiteOrigin));
+ logger().LogPreventSilentAccess(GURL(kSiteOrigin));
}
} // namespace
diff --git a/chromium/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc b/chromium/components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.cc
index 79cfe6b1816..b0e1ab14608 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc
+++ b/chromium/components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.cc
@@ -2,29 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h"
+#include "components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.h"
#include "components/autofill/core/common/password_form.h"
namespace password_manager {
-CredentialManagerPendingRequireUserMediationTask::
- CredentialManagerPendingRequireUserMediationTask(
- CredentialManagerPendingRequireUserMediationTaskDelegate* delegate)
+CredentialManagerPendingPreventSilentAccessTask::
+ CredentialManagerPendingPreventSilentAccessTask(
+ CredentialManagerPendingPreventSilentAccessTaskDelegate* delegate)
: delegate_(delegate), pending_requests_(0) {}
-CredentialManagerPendingRequireUserMediationTask::
- ~CredentialManagerPendingRequireUserMediationTask() = default;
+CredentialManagerPendingPreventSilentAccessTask::
+ ~CredentialManagerPendingPreventSilentAccessTask() = default;
-void CredentialManagerPendingRequireUserMediationTask::AddOrigin(
+void CredentialManagerPendingPreventSilentAccessTask::AddOrigin(
const PasswordStore::FormDigest& form_digest) {
delegate_->GetPasswordStore()->GetLogins(form_digest, this);
pending_requests_++;
}
-void CredentialManagerPendingRequireUserMediationTask::
- OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
+void CredentialManagerPendingPreventSilentAccessTask::OnGetPasswordStoreResults(
+ std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
PasswordStore* store = delegate_->GetPasswordStore();
for (const auto& form : results) {
if (!form->skip_zero_click) {
diff --git a/chromium/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h b/chromium/components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.h
index a703bc5c0a7..38fcb4ee3dd 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h
+++ b/chromium/components/password_manager/core/browser/credential_manager_pending_prevent_silent_access_task.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_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_REQUIRE_USER_MEDIATION_TASK_H_
-#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_REQUIRE_USER_MEDIATION_TASK_H_
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_PREVENT_SILENT_ACCESS_TASK_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_PREVENT_SILENT_ACCESS_TASK_H_
#include "base/macros.h"
#include "components/password_manager/core/browser/password_store.h"
@@ -12,9 +12,9 @@
namespace password_manager {
// Handles mediation completion and retrieves embedder-dependent services.
-class CredentialManagerPendingRequireUserMediationTaskDelegate {
+class CredentialManagerPendingPreventSilentAccessTaskDelegate {
public:
- virtual ~CredentialManagerPendingRequireUserMediationTaskDelegate() {}
+ virtual ~CredentialManagerPendingPreventSilentAccessTaskDelegate() {}
// Retrieves the PasswordStore.
virtual PasswordStore* GetPasswordStore() = 0;
@@ -24,12 +24,12 @@ class CredentialManagerPendingRequireUserMediationTaskDelegate {
};
// Notifies the password store that a list of origins require user mediation.
-class CredentialManagerPendingRequireUserMediationTask
+class CredentialManagerPendingPreventSilentAccessTask
: public PasswordStoreConsumer {
public:
- explicit CredentialManagerPendingRequireUserMediationTask(
- CredentialManagerPendingRequireUserMediationTaskDelegate* delegate);
- ~CredentialManagerPendingRequireUserMediationTask() override;
+ explicit CredentialManagerPendingPreventSilentAccessTask(
+ CredentialManagerPendingPreventSilentAccessTaskDelegate* delegate);
+ ~CredentialManagerPendingPreventSilentAccessTask() override;
// Adds an origin to require user mediation.
void AddOrigin(const PasswordStore::FormDigest& form_digest);
@@ -39,15 +39,15 @@ class CredentialManagerPendingRequireUserMediationTask
void OnGetPasswordStoreResults(
std::vector<std::unique_ptr<autofill::PasswordForm>> results) override;
- CredentialManagerPendingRequireUserMediationTaskDelegate* const
+ CredentialManagerPendingPreventSilentAccessTaskDelegate* const
delegate_; // Weak.
// Number of password store requests to be resolved.
int pending_requests_;
- DISALLOW_COPY_AND_ASSIGN(CredentialManagerPendingRequireUserMediationTask);
+ DISALLOW_COPY_AND_ASSIGN(CredentialManagerPendingPreventSilentAccessTask);
};
} // namespace password_manager
-#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_REQUIRE_USER_MEDIATION_TASK_H_
+#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_CREDENTIAL_MANAGER_PENDING_PREVENT_SILENT_ACCESS_TASK_H_
diff --git a/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.cc
index cd89fb0e894..6901dc02dfe 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.cc
+++ b/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -113,12 +113,12 @@ void FilterDuplicatesAndEmptyUsername(
CredentialManagerPendingRequestTask::CredentialManagerPendingRequestTask(
CredentialManagerPendingRequestTaskDelegate* delegate,
const SendCredentialCallback& callback,
- bool request_zero_click_only,
+ CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& request_federations)
: delegate_(delegate),
send_callback_(callback),
- zero_click_only_(request_zero_click_only),
+ mediation_(mediation),
origin_(delegate_->GetOrigin()),
include_passwords_(include_passwords) {
CHECK(!delegate_->client()->DidLastPageLoadEncounterSSLErrors());
@@ -149,12 +149,9 @@ void CredentialManagerPendingRequestTask::ProcessMigratedForms(
void CredentialManagerPendingRequestTask::ProcessForms(
std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
using metrics_util::LogCredentialManagerGetResult;
- metrics_util::CredentialManagerGetMediation mediation_status =
- zero_click_only_ ? metrics_util::CREDENTIAL_MANAGER_GET_UNMEDIATED
- : metrics_util::CREDENTIAL_MANAGER_GET_MEDIATED;
if (delegate_->GetOrigin() != origin_) {
LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_NONE,
- mediation_status);
+ mediation_);
delegate_->SendCredential(send_callback_, CredentialInfo());
return;
}
@@ -187,13 +184,15 @@ void CredentialManagerPendingRequestTask::ProcessForms(
FilterDuplicatesAndEmptyUsername(&local_results, &has_empty_username,
&has_duplicates);
- // We only perform zero-click sign-in when the result is completely
- // unambigious. If there is one and only one entry, and zero-click is
+ // We only perform zero-click sign-in when it is not forbidden via the
+ // mediation requirement and the result is completely unambigious.
+ // If there is one and only one entry, and zero-click is
// enabled for that entry, return it.
//
// Moreover, we only return such a credential if the user has opted-in via the
// first-run experience.
const bool can_use_autosignin =
+ mediation_ != CredentialMediationRequirement::kRequired &&
local_results.size() == 1u && delegate_->IsZeroClickAllowed();
if (can_use_autosignin && !local_results[0]->skip_zero_click &&
!password_bubble_experiment::ShouldShowAutoSignInPromptFirstRunExperience(
@@ -206,12 +205,12 @@ void CredentialManagerPendingRequestTask::ProcessForms(
origin_);
base::RecordAction(base::UserMetricsAction("CredentialManager_Autosignin"));
LogCredentialManagerGetResult(
- metrics_util::CREDENTIAL_MANAGER_GET_AUTOSIGNIN, mediation_status);
+ metrics_util::CREDENTIAL_MANAGER_GET_AUTOSIGNIN, mediation_);
delegate_->SendCredential(send_callback_, info);
return;
}
- if (zero_click_only_) {
+ if (mediation_ == CredentialMediationRequirement::kSilent) {
metrics_util::CredentialManagerGetResult get_result;
if (local_results.empty())
get_result = metrics_util::CREDENTIAL_MANAGER_GET_NONE_EMPTY_STORE;
@@ -231,7 +230,7 @@ void CredentialManagerPendingRequestTask::ProcessForms(
std::move(local_results[0]));
}
- LogCredentialManagerGetResult(get_result, mediation_status);
+ LogCredentialManagerGetResult(get_result, mediation_);
delegate_->SendCredential(send_callback_, CredentialInfo());
return;
}
@@ -246,8 +245,7 @@ void CredentialManagerPendingRequestTask::ProcessForms(
if (local_results.empty()) {
LogCredentialManagerGetResult(
- metrics_util::CREDENTIAL_MANAGER_GET_NONE_EMPTY_STORE,
- mediation_status);
+ metrics_util::CREDENTIAL_MANAGER_GET_NONE_EMPTY_STORE, mediation_);
delegate_->SendCredential(send_callback_, CredentialInfo());
return;
}
@@ -258,9 +256,9 @@ void CredentialManagerPendingRequestTask::ProcessForms(
std::move(local_results), origin_,
base::Bind(
&CredentialManagerPendingRequestTaskDelegate::SendPasswordForm,
- base::Unretained(delegate_), send_callback_))) {
+ base::Unretained(delegate_), send_callback_, mediation_))) {
LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_NONE,
- mediation_status);
+ mediation_);
delegate_->SendCredential(send_callback_, CredentialInfo());
}
}
diff --git a/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.h b/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.h
index a444a723130..6c31ab0cbac 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.h
+++ b/chromium/components/password_manager/core/browser/credential_manager_pending_request_task.h
@@ -15,6 +15,7 @@
#include "components/password_manager/core/browser/http_password_store_migrator.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
+#include "components/password_manager/core/common/credential_manager_types.h"
#include "url/gurl.h"
namespace autofill {
@@ -49,6 +50,7 @@ class CredentialManagerPendingRequestTaskDelegate {
// Updates |skip_zero_click| for |form| in the PasswordStore if required.
// Sends a credential to JavaScript.
virtual void SendPasswordForm(const SendCredentialCallback& send_callback,
+ CredentialMediationRequirement mediation,
const autofill::PasswordForm* form) = 0;
};
@@ -60,7 +62,7 @@ class CredentialManagerPendingRequestTask
CredentialManagerPendingRequestTask(
CredentialManagerPendingRequestTaskDelegate* delegate,
const SendCredentialCallback& callback,
- bool request_zero_click_only,
+ CredentialMediationRequirement mediation,
bool include_passwords,
const std::vector<GURL>& request_federations);
~CredentialManagerPendingRequestTask() override;
@@ -82,7 +84,7 @@ class CredentialManagerPendingRequestTask
CredentialManagerPendingRequestTaskDelegate* delegate_; // Weak;
SendCredentialCallback send_callback_;
- const bool zero_click_only_;
+ const CredentialMediationRequirement mediation_;
const GURL origin_;
const bool include_passwords_;
std::set<std::string> federations_;
diff --git a/chromium/components/password_manager/core/browser/fake_form_fetcher.cc b/chromium/components/password_manager/core/browser/fake_form_fetcher.cc
index e2f13a896c3..7e7911c3eee 100644
--- a/chromium/components/password_manager/core/browser/fake_form_fetcher.cc
+++ b/chromium/components/password_manager/core/browser/fake_form_fetcher.cc
@@ -37,6 +37,25 @@ FakeFormFetcher::GetFederatedMatches() const {
return federated_;
}
+const std::vector<const PasswordForm*>&
+FakeFormFetcher::GetSuppressedHTTPSForms() const {
+ return suppressed_https_forms_;
+}
+
+const std::vector<const autofill::PasswordForm*>&
+FakeFormFetcher::GetSuppressedPSLMatchingForms() const {
+ return suppressed_psl_matching_forms_;
+}
+
+const std::vector<const autofill::PasswordForm*>&
+FakeFormFetcher::GetSuppressedSameOrganizationNameForms() const {
+ return suppressed_same_organization_name_forms_;
+}
+
+bool FakeFormFetcher::DidCompleteQueryingSuppressedForms() const {
+ return did_complete_querying_suppressed_forms_;
+}
+
void FakeFormFetcher::SetNonFederated(
const std::vector<const autofill::PasswordForm*>& non_federated,
size_t filtered_count) {
diff --git a/chromium/components/password_manager/core/browser/fake_form_fetcher.h b/chromium/components/password_manager/core/browser/fake_form_fetcher.h
index 891291d1938..d7c64a327a2 100644
--- a/chromium/components/password_manager/core/browser/fake_form_fetcher.h
+++ b/chromium/components/password_manager/core/browser/fake_form_fetcher.h
@@ -56,6 +56,39 @@ class FakeFormFetcher : public FormFetcher {
federated_ = federated;
}
+ const std::vector<const autofill::PasswordForm*>& GetSuppressedHTTPSForms()
+ const override;
+
+ // The pointees in |suppressed_forms| must outlive the fetcher.
+ void set_suppressed_https_forms(
+ const std::vector<const autofill::PasswordForm*>& suppressed_forms) {
+ suppressed_https_forms_ = suppressed_forms;
+ }
+
+ const std::vector<const autofill::PasswordForm*>&
+ GetSuppressedPSLMatchingForms() const override;
+
+ // The pointees in |suppressed_forms| must outlive the fetcher.
+ void set_suppressed_psl_matching_forms(
+ const std::vector<const autofill::PasswordForm*>& suppressed_forms) {
+ suppressed_psl_matching_forms_ = suppressed_forms;
+ }
+
+ const std::vector<const autofill::PasswordForm*>&
+ GetSuppressedSameOrganizationNameForms() const override;
+
+ // The pointees in |suppressed_forms| must outlive the fetcher.
+ void set_suppressed_same_organization_name_forms(
+ const std::vector<const autofill::PasswordForm*>& suppressed_forms) {
+ suppressed_same_organization_name_forms_ = suppressed_forms;
+ }
+
+ bool DidCompleteQueryingSuppressedForms() const override;
+
+ void set_did_complete_querying_suppressed_forms(bool value) {
+ did_complete_querying_suppressed_forms_ = value;
+ }
+
void SetNonFederated(
const std::vector<const autofill::PasswordForm*>& non_federated,
size_t filtered_count);
@@ -71,6 +104,11 @@ class FakeFormFetcher : public FormFetcher {
State state_ = State::NOT_WAITING;
std::vector<InteractionsStats> stats_;
std::vector<const autofill::PasswordForm*> federated_;
+ std::vector<const autofill::PasswordForm*> suppressed_https_forms_;
+ std::vector<const autofill::PasswordForm*> suppressed_psl_matching_forms_;
+ std::vector<const autofill::PasswordForm*>
+ suppressed_same_organization_name_forms_;
+ bool did_complete_querying_suppressed_forms_ = false;
DISALLOW_COPY_AND_ASSIGN(FakeFormFetcher);
};
diff --git a/chromium/components/password_manager/core/browser/form_fetcher.h b/chromium/components/password_manager/core/browser/form_fetcher.h
index bfbd22f7709..22bcd52aa55 100644
--- a/chromium/components/password_manager/core/browser/form_fetcher.h
+++ b/chromium/components/password_manager/core/browser/form_fetcher.h
@@ -71,6 +71,42 @@ class FormFetcher {
virtual const std::vector<const autofill::PasswordForm*>&
GetFederatedMatches() const = 0;
+ // The following accessors return various kinds of `suppressed` credentials.
+ // These are stored credentials that are not (auto-)filled, because they are
+ // for an origin that is similar to, but not exactly matching the origin that
+ // this FormFetcher was created for. They are used for recording metrics on
+ // how often such -- potentially, but not necessarily related -- credentials
+ // are not offered to the user, unduly increasing log-in friction.
+ //
+ // There are currently three kinds of suppressed credentials:
+ // 1.) HTTPS credentials not filled on the HTTP version of the origin.
+ // 2.) PSL-matches that are not auto-filled (but filled on account select).
+ // 3.) Same-organization name credentials, not filled.
+ //
+ // Results below are queried on a best-effort basis, might be somewhat stale,
+ // and are available shortly after the Consumer::ProcessMatches callback.
+
+ // When this instance fetches forms for an HTTP origin: Returns saved
+ // credentials, if any, found for the HTTPS version of that origin. Empty
+ // otherwise.
+ virtual const std::vector<const autofill::PasswordForm*>&
+ GetSuppressedHTTPSForms() const = 0;
+
+ // Returns saved credentials, if any, for PSL-matching origins. Autofilling
+ // these is suppressed, however, they *can be* filled on account select.
+ virtual const std::vector<const autofill::PasswordForm*>&
+ GetSuppressedPSLMatchingForms() const = 0;
+
+ // Returns saved credentials, if any, found for HTTP/HTTPS origins with the
+ // same organization name as the origin this FormFetcher was created for.
+ virtual const std::vector<const autofill::PasswordForm*>&
+ GetSuppressedSameOrganizationNameForms() const = 0;
+
+ // Whether querying suppressed forms (of all flavors) was attempted and did
+ // complete at least once during the lifetime of this instance, regardless of
+ // whether there have been any results.
+ virtual bool DidCompleteQueryingSuppressedForms() const = 0;
+
// Fetches stored matching logins. In addition the statistics is fetched on
// platforms with the password bubble. This is called automatically during
// construction and can be called manually later as well to cause an update
diff --git a/chromium/components/password_manager/core/browser/form_fetcher_impl.cc b/chromium/components/password_manager/core/browser/form_fetcher_impl.cc
index b73501a2c74..c8127b0ebd5 100644
--- a/chromium/components/password_manager/core/browser/form_fetcher_impl.cc
+++ b/chromium/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -15,6 +15,7 @@
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/psl_matching_helper.h"
#include "components/password_manager/core/browser/statistics_table.h"
using autofill::PasswordForm;
@@ -46,6 +47,43 @@ std::vector<std::unique_ptr<PasswordForm>> SplitFederatedMatches(
return federated_matches;
}
+void SplitSuppressedFormsAndAssignTo(
+ const PasswordStore::FormDigest& observed_form_digest,
+ std::vector<std::unique_ptr<PasswordForm>> suppressed_forms,
+ std::vector<std::unique_ptr<PasswordForm>>* same_origin_https_forms,
+ std::vector<std::unique_ptr<PasswordForm>>* psl_matching_forms,
+ std::vector<std::unique_ptr<PasswordForm>>* same_organization_name_forms) {
+ DCHECK(same_origin_https_forms);
+ DCHECK(psl_matching_forms);
+ DCHECK(same_organization_name_forms);
+ same_origin_https_forms->clear();
+ psl_matching_forms->clear();
+ same_organization_name_forms->clear();
+ for (auto& form : suppressed_forms) {
+ switch (GetMatchResult(*form, observed_form_digest)) {
+ case MatchResult::PSL_MATCH:
+ psl_matching_forms->push_back(std::move(form));
+ break;
+ case MatchResult::NO_MATCH:
+ if (form->origin.host() != observed_form_digest.origin.host()) {
+ same_organization_name_forms->push_back(std::move(form));
+ } else if (form->origin.SchemeIs(url::kHttpsScheme) &&
+ observed_form_digest.origin.SchemeIs(url::kHttpScheme)) {
+ same_origin_https_forms->push_back(std::move(form));
+ } else {
+ // HTTP form suppressed on HTTPS observed page: The HTTP->HTTPS
+ // migration can leave tons of such HTTP forms behind, ignore these.
+ }
+ break;
+ case MatchResult::EXACT_MATCH:
+ case MatchResult::FEDERATED_MATCH:
+ case MatchResult::FEDERATED_PSL_MATCH:
+ NOTREACHED() << "Suppressed match cannot be exact or federated.";
+ break;
+ }
+ }
+}
+
// Create a vector of const PasswordForm from a vector of
// unique_ptr<PasswordForm> by applying get() item-wise.
std::vector<const PasswordForm*> MakeWeakCopies(
@@ -73,10 +111,12 @@ std::vector<std::unique_ptr<PasswordForm>> MakeCopies(
FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest,
const PasswordManagerClient* client,
- bool should_migrate_http_passwords)
+ bool should_migrate_http_passwords,
+ bool should_query_suppressed_forms)
: form_digest_(std::move(form_digest)),
client_(client),
- should_migrate_http_passwords_(should_migrate_http_passwords) {}
+ should_migrate_http_passwords_(should_migrate_http_passwords),
+ should_query_suppressed_forms_(should_query_suppressed_forms) {}
FormFetcherImpl::~FormFetcherImpl() = default;
@@ -106,6 +146,25 @@ const std::vector<const PasswordForm*>& FormFetcherImpl::GetFederatedMatches()
return weak_federated_;
}
+const std::vector<const PasswordForm*>&
+FormFetcherImpl::GetSuppressedHTTPSForms() const {
+ return weak_suppressed_same_origin_https_forms_;
+}
+
+const std::vector<const PasswordForm*>&
+FormFetcherImpl::GetSuppressedPSLMatchingForms() const {
+ return weak_suppressed_psl_matching_forms_;
+}
+
+const std::vector<const PasswordForm*>&
+FormFetcherImpl::GetSuppressedSameOrganizationNameForms() const {
+ return weak_suppressed_same_organization_name_forms_;
+}
+
+bool FormFetcherImpl::DidCompleteQueryingSuppressedForms() const {
+ return did_complete_querying_suppressed_forms_;
+}
+
void FormFetcherImpl::OnGetPasswordStoreResults(
std::vector<std::unique_ptr<PasswordForm>> results) {
DCHECK_EQ(State::WAITING, state_);
@@ -126,6 +185,17 @@ void FormFetcherImpl::OnGetPasswordStoreResults(
logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size());
}
+ // Kick off the discovery of suppressed credentials, regardless of whether
+ // there are some precisely matching |results|. These results are used only
+ // for recording metrics at PasswordFormManager desctruction time, this is why
+ // they are requested this late.
+ if (should_query_suppressed_forms_ &&
+ form_digest_.scheme == PasswordForm::SCHEME_HTML &&
+ GURL(form_digest_.signon_realm).SchemeIsHTTPOrHTTPS()) {
+ suppressed_form_fetcher_ = base::MakeUnique<SuppressedFormFetcher>(
+ form_digest_.signon_realm, client_, this);
+ }
+
if (should_migrate_http_passwords_ && results.empty() &&
form_digest_.origin.SchemeIs(url::kHttpsScheme)) {
http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>(
@@ -148,6 +218,21 @@ void FormFetcherImpl::ProcessMigratedForms(
ProcessPasswordStoreResults(std::move(forms));
}
+void FormFetcherImpl::ProcessSuppressedForms(
+ std::vector<std::unique_ptr<autofill::PasswordForm>> forms) {
+ did_complete_querying_suppressed_forms_ = true;
+ SplitSuppressedFormsAndAssignTo(form_digest_, std::move(forms),
+ &suppressed_same_origin_https_forms_,
+ &suppressed_psl_matching_forms_,
+ &suppressed_same_organization_name_forms_);
+ weak_suppressed_same_origin_https_forms_ =
+ MakeWeakCopies(suppressed_same_origin_https_forms_);
+ weak_suppressed_psl_matching_forms_ =
+ MakeWeakCopies(suppressed_psl_matching_forms_);
+ weak_suppressed_same_organization_name_forms_ =
+ MakeWeakCopies(suppressed_same_organization_name_forms_);
+}
+
void FormFetcherImpl::Fetch() {
std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
if (password_manager_util::IsLoggingActive(client_)) {
@@ -188,14 +273,27 @@ std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() {
// Create the copy without the "HTTPS migration" activated. If it was needed,
// then it was done by |this| already.
- auto result = base::MakeUnique<FormFetcherImpl>(form_digest_, client_, false);
+ auto result = base::MakeUnique<FormFetcherImpl>(
+ form_digest_, client_, false, should_query_suppressed_forms_);
result->non_federated_ = MakeCopies(this->non_federated_);
result->federated_ = MakeCopies(this->federated_);
result->interactions_stats_ = this->interactions_stats_;
+ result->suppressed_same_origin_https_forms_ =
+ MakeCopies(this->suppressed_same_origin_https_forms_);
+ result->suppressed_psl_matching_forms_ =
+ MakeCopies(this->suppressed_psl_matching_forms_);
+ result->suppressed_same_organization_name_forms_ =
+ MakeCopies(this->suppressed_same_organization_name_forms_);
result->weak_non_federated_ = MakeWeakCopies(result->non_federated_);
result->weak_federated_ = MakeWeakCopies(result->federated_);
+ result->weak_suppressed_same_origin_https_forms_ =
+ MakeWeakCopies(result->suppressed_same_origin_https_forms_);
+ result->weak_suppressed_psl_matching_forms_ =
+ MakeWeakCopies(result->suppressed_psl_matching_forms_);
+ result->weak_suppressed_same_organization_name_forms_ =
+ MakeWeakCopies(result->suppressed_same_organization_name_forms_);
result->filtered_count_ = this->filtered_count_;
result->state_ = this->state_;
diff --git a/chromium/components/password_manager/core/browser/form_fetcher_impl.h b/chromium/components/password_manager/core/browser/form_fetcher_impl.h
index af6ba69f034..29fe6a7b340 100644
--- a/chromium/components/password_manager/core/browser/form_fetcher_impl.h
+++ b/chromium/components/password_manager/core/browser/form_fetcher_impl.h
@@ -14,6 +14,7 @@
#include "components/password_manager/core/browser/http_password_store_migrator.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
+#include "components/password_manager/core/browser/suppressed_form_fetcher.h"
namespace password_manager {
@@ -23,13 +24,15 @@ class PasswordManagerClient;
// with a particular origin.
class FormFetcherImpl : public FormFetcher,
public PasswordStoreConsumer,
- public HttpPasswordStoreMigrator::Consumer {
+ public HttpPasswordStoreMigrator::Consumer,
+ public SuppressedFormFetcher::Consumer {
public:
// |form_digest| describes what credentials need to be retrieved and
// |client| serves the PasswordStore, the logging information etc.
FormFetcherImpl(PasswordStore::FormDigest form_digest,
const PasswordManagerClient* client,
- bool should_migrate_http_passwords);
+ bool should_migrate_http_passwords,
+ bool should_query_suppressed_forms);
~FormFetcherImpl() override;
@@ -40,6 +43,13 @@ class FormFetcherImpl : public FormFetcher,
const std::vector<InteractionsStats>& GetInteractionsStats() const override;
const std::vector<const autofill::PasswordForm*>& GetFederatedMatches()
const override;
+ const std::vector<const autofill::PasswordForm*>& GetSuppressedHTTPSForms()
+ const override;
+ const std::vector<const autofill::PasswordForm*>&
+ GetSuppressedPSLMatchingForms() const override;
+ const std::vector<const autofill::PasswordForm*>&
+ GetSuppressedSameOrganizationNameForms() const override;
+ bool DidCompleteQueryingSuppressedForms() const override;
void Fetch() override;
std::unique_ptr<FormFetcher> Clone() override;
@@ -52,6 +62,10 @@ class FormFetcherImpl : public FormFetcher,
void ProcessMigratedForms(
std::vector<std::unique_ptr<autofill::PasswordForm>> forms) override;
+ // SuppressedFormFetcher::Consumer:
+ void ProcessSuppressedForms(
+ std::vector<std::unique_ptr<autofill::PasswordForm>> forms) override;
+
private:
// Processes password form results and forwards them to the |consumers_|.
void ProcessPasswordStoreResults(
@@ -71,9 +85,27 @@ class FormFetcherImpl : public FormFetcher,
// Statistics for the current domain.
std::vector<InteractionsStats> interactions_stats_;
+ std::vector<std::unique_ptr<autofill::PasswordForm>>
+ suppressed_same_origin_https_forms_;
+ std::vector<std::unique_ptr<autofill::PasswordForm>>
+ suppressed_psl_matching_forms_;
+ std::vector<std::unique_ptr<autofill::PasswordForm>>
+ suppressed_same_organization_name_forms_;
+
+ // Whether querying |suppressed_https_forms_| was attempted and did complete
+ // at least once during the lifetime of this instance, regardless of whether
+ // there have been any results.
+ bool did_complete_querying_suppressed_forms_ = false;
+
// Non-owning copies of the vectors above.
std::vector<const autofill::PasswordForm*> weak_non_federated_;
std::vector<const autofill::PasswordForm*> weak_federated_;
+ std::vector<const autofill::PasswordForm*>
+ weak_suppressed_same_origin_https_forms_;
+ std::vector<const autofill::PasswordForm*>
+ weak_suppressed_psl_matching_forms_;
+ std::vector<const autofill::PasswordForm*>
+ weak_suppressed_same_organization_name_forms_;
// Consumers of the fetcher, all are assumed to outlive |this|.
std::set<FormFetcher::Consumer*> consumers_;
@@ -95,9 +127,18 @@ class FormFetcherImpl : public FormFetcher,
// Indicates whether HTTP passwords should be migrated to HTTPS.
const bool should_migrate_http_passwords_;
+ // Indicates whether to query suppressed forms.
+ const bool should_query_suppressed_forms_;
+
// Does the actual migration.
std::unique_ptr<HttpPasswordStoreMigrator> http_migrator_;
+ // Responsible for looking up `suppressed` credentials. These are stored
+ // credentials that were not filled, even though they might be related to the
+ // origin that this instance was created for. Look-up happens asynchronously,
+ // without blocking Consumer::ProcessMatches.
+ std::unique_ptr<SuppressedFormFetcher> suppressed_form_fetcher_;
+
DISALLOW_COPY_AND_ASSIGN(FormFetcherImpl);
};
diff --git a/chromium/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/chromium/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
index 90c36a90dbf..07cf4325d65 100644
--- a/chromium/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
+++ b/chromium/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -20,6 +20,7 @@
#include "build/build_config.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/mock_password_store.h"
+#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/statistics_table.h"
#include "components/password_manager/core/browser/stub_credentials_filter.h"
@@ -38,12 +39,29 @@ using testing::IsEmpty;
using testing::Pointee;
using testing::Return;
using testing::UnorderedElementsAre;
+using testing::UnorderedElementsAreArray;
using testing::WithArg;
namespace password_manager {
namespace {
+constexpr const char kTestHttpURL[] = "http://example.in/";
+constexpr const char kTestHttpActionURL[] = "http://login.example.org/";
+
+constexpr const char kTestHttpsURL[] = "https://example.in/";
+constexpr const char kTestHttpsActionURL[] = "https://login.example.org/";
+
+constexpr const char kTestPSLMatchingHttpURL[] = "http://psl.example.in/";
+constexpr const char kTestPSLMatchingHttpsURL[] = "https://psl.example.in/";
+
+constexpr const char kTestHttpSameOrgNameURL[] = "http://sub.example.com/";
+constexpr const char kTestHttpsSameOrgNameURL[] = "https://sub.example.com/";
+
+constexpr const char kTestFederatedRealm[] =
+ "federation://example.in/accounts.google.com";
+constexpr const char kTestFederationURL[] = "https://accounts.google.com/";
+
class MockConsumer : public FormFetcher::Consumer {
public:
MOCK_METHOD2(ProcessMatches,
@@ -102,42 +120,46 @@ class FakePasswordManagerClient : public StubPasswordManagerClient {
DISALLOW_COPY_AND_ASSIGN(FakePasswordManagerClient);
};
+PasswordForm CreateHTMLForm(const char* origin_url,
+ const char* username_value,
+ const char* password_value) {
+ PasswordForm form;
+ form.scheme = PasswordForm::SCHEME_HTML;
+ form.origin = GURL(origin_url);
+ form.signon_realm = origin_url;
+ form.username_value = ASCIIToUTF16(username_value);
+ form.password_value = ASCIIToUTF16(password_value);
+ return form;
+}
+
// Creates a dummy non-federated form with some basic arbitrary values.
PasswordForm CreateNonFederated() {
- PasswordForm form;
- form.origin = GURL("https://example.in");
- form.signon_realm = form.origin.spec();
- form.action = GURL("https://login.example.org");
- form.username_value = ASCIIToUTF16("user");
- form.password_value = ASCIIToUTF16("password");
+ PasswordForm form = CreateHTMLForm(kTestHttpsURL, "user", "password");
+ form.action = GURL(kTestHttpsActionURL);
return form;
}
// Creates a dummy non-federated HTTP form with some basic arbitrary values.
PasswordForm CreateHTTPNonFederated() {
- PasswordForm form;
- form.origin = GURL("http://example.in");
- form.signon_realm = form.origin.spec();
- form.action = GURL("http://login.example.org");
- form.username_value = ASCIIToUTF16("user");
- form.password_value = ASCIIToUTF16("password");
+ PasswordForm form = CreateHTMLForm(kTestHttpURL, "user", "password");
+ form.action = GURL(kTestHttpActionURL);
return form;
}
// Creates a dummy federated form with some basic arbitrary values.
PasswordForm CreateFederated() {
PasswordForm form = CreateNonFederated();
+ form.signon_realm = kTestFederatedRealm;
form.password_value.clear();
- form.federation_origin = url::Origin(GURL("https://accounts.google.com/"));
+ form.federation_origin = url::Origin(GURL(kTestFederationURL));
return form;
}
// Creates an Android federated credential.
PasswordForm CreateAndroidFederated() {
- PasswordForm form = CreateFederated();
- form.signon_realm = "android://hash@com.example.android/";
- form.origin = GURL(form.signon_realm);
- form.action = GURL();
+ PasswordForm form =
+ CreateHTMLForm("android://hash@com.example.android/", "user", "");
+ form.federation_origin = url::Origin(GURL(kTestFederationURL));
form.is_affiliation_based_match = true;
return form;
}
@@ -152,6 +174,15 @@ std::vector<std::unique_ptr<PasswordForm>> MakeResults(
return results;
}
+std::vector<PasswordForm> PointeeValues(
+ const std::vector<const PasswordForm*> forms) {
+ std::vector<PasswordForm> result;
+ result.reserve(forms.size());
+ for (const PasswordForm* form : forms)
+ result.push_back(*form);
+ return result;
+}
+
ACTION_P(GetAndAssignWeakPtr, ptr) {
*ptr = arg0->GetWeakPtr();
}
@@ -162,13 +193,14 @@ class FormFetcherImplTest : public testing::Test {
public:
FormFetcherImplTest()
: form_digest_(PasswordForm::SCHEME_HTML,
- "http://accounts.google.com",
- GURL("http://accounts.google.com/a/LoginAuth")) {
+ kTestHttpURL,
+ GURL(kTestHttpURL)) {
mock_store_ = new MockPasswordStore();
client_.set_store(mock_store_.get());
form_fetcher_ = base::MakeUnique<FormFetcherImpl>(
- form_digest_, &client_, /* should_migrate_http_passwords */ false);
+ form_digest_, &client_, false /* should_migrate_http_passwords */,
+ false /* should_query_suppressed_https_forms */);
}
~FormFetcherImplTest() override { mock_store_->ShutdownOnUIThread(); }
@@ -186,6 +218,55 @@ class FormFetcherImplTest : public testing::Test {
testing::Mock::VerifyAndClearExpectations(mock_store_.get());
}
+ void RecreateFormFetcherWithQueryingSuppressedForms() {
+ form_fetcher_ = base::MakeUnique<FormFetcherImpl>(
+ form_digest_, &client_, false /* should_migrate_http_passwords */,
+ true /* should_query_suppressed_https_forms */);
+ EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u));
+ form_fetcher_->AddConsumer(&consumer_);
+ testing::Mock::VerifyAndClearExpectations(&consumer_);
+ }
+
+ // Simulates a call to Fetch(), and supplies |simulated_matches| as the
+ // PasswordStore results. Expects that this will trigger the querying of
+ // suppressed forms by means of a GetLoginsForSameOrganizationName call
+ // being issued against the |expected_signon_realm|.
+ //
+ // Call CompleteQueryingSuppressedForms with the emitted |consumer_ptr|
+ // to complete the query.
+ void SimulateFetchAndExpectQueryingSuppressedForms(
+ const std::vector<PasswordForm>& simulated_get_logins_matches,
+ const std::string& expected_signon_realm,
+ base::WeakPtr<PasswordStoreConsumer>* consumer_ptr /* out */) {
+ ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
+
+ Fetch();
+
+ EXPECT_CALL(*mock_store_,
+ GetLoginsForSameOrganizationName(expected_signon_realm, _))
+ .WillOnce(::testing::WithArg<1>(GetAndAssignWeakPtr(consumer_ptr)));
+ const size_t num_matches = simulated_get_logins_matches.size();
+ EXPECT_CALL(consumer_, ProcessMatches(::testing::SizeIs(num_matches), 0u));
+
+ form_fetcher_->OnGetPasswordStoreResults(
+ MakeResults(simulated_get_logins_matches));
+
+ ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&consumer_));
+ ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock_store_.get()));
+ ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
+ ASSERT_TRUE(*consumer_ptr);
+ }
+
+ void CompleteQueryingSuppressedForms(
+ const std::vector<PasswordForm>& simulated_suppressed_forms,
+ base::WeakPtr<PasswordStoreConsumer> consumer_ptr) {
+ ASSERT_TRUE(consumer_ptr);
+ ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
+ consumer_ptr->OnGetPasswordStoreResults(
+ MakeResults(simulated_suppressed_forms));
+ ASSERT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
+ }
+
base::MessageLoop message_loop_; // Used by mock_store_.
PasswordStore::FormDigest form_digest_;
std::unique_ptr<FormFetcherImpl> form_fetcher_;
@@ -399,7 +480,8 @@ TEST_F(FormFetcherImplTest, DoNotTryToMigrateHTTPPasswordsOnHTTPSites) {
// A new form fetcher is created to be able to set the form digest and
// migration flag.
form_fetcher_ = base::MakeUnique<FormFetcherImpl>(
- form_digest_, &client_, /* should_migrate_http_passwords */ true);
+ form_digest_, &client_, true /* should_migrate_http_passwords */,
+ false /* should_query_suppressed_https_forms */);
EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u));
form_fetcher_->AddConsumer(&consumer_);
@@ -441,7 +523,8 @@ TEST_F(FormFetcherImplTest, TryToMigrateHTTPPasswordsOnHTTPSSites) {
// A new form fetcher is created to be able to set the form digest and
// migration flag.
form_fetcher_ = base::MakeUnique<FormFetcherImpl>(
- form_digest_, &client_, /* should_migrate_http_passwords */ true);
+ form_digest_, &client_, true /* should_migrate_http_passwords */,
+ false /* should_query_suppressed_https_forms */);
EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u));
form_fetcher_->AddConsumer(&consumer_);
@@ -510,7 +593,8 @@ TEST_F(FormFetcherImplTest, StateIsWaitingDuringMigration) {
// A new form fetcher is created to be able to set the form digest and
// migration flag.
form_fetcher_ = base::MakeUnique<FormFetcherImpl>(
- form_digest_, &client_, /* should_migrate_http_passwords */ true);
+ form_digest_, &client_, true /* should_migrate_http_passwords */,
+ false /* should_query_suppressed_https_forms */);
PasswordForm https_form = CreateNonFederated();
@@ -551,19 +635,229 @@ TEST_F(FormFetcherImplTest, StateIsWaitingDuringMigration) {
EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
}
+TEST_F(FormFetcherImplTest, SuppressedForms_QueriedForHTTPAndHTTPSOrigins) {
+ static const PasswordStore::FormDigest kObservedHTTPSFormDigest(
+ PasswordForm::SCHEME_HTML, kTestHttpsURL, GURL(kTestHttpsURL));
+
+ static const PasswordForm kFormHttpSameHost =
+ CreateHTMLForm(kTestHttpURL, "user_1", "pass_1");
+ static const PasswordForm kFormHttpsSameHost =
+ CreateHTMLForm(kTestHttpsURL, "user_2", "pass_2");
+ static const PasswordForm kFormHttpPSLMatchingHost =
+ CreateHTMLForm(kTestPSLMatchingHttpURL, "user_3", "pass_3");
+ static const PasswordForm kFormHttpsPSLMatchingHost =
+ CreateHTMLForm(kTestPSLMatchingHttpsURL, "user_4", "pass_4");
+ static const PasswordForm kFormHttpSameOrgNameHost =
+ CreateHTMLForm(kTestHttpSameOrgNameURL, "user_5", "pass_5");
+ static const PasswordForm kFormHttpsSameOrgNameHost =
+ CreateHTMLForm(kTestHttpsSameOrgNameURL, "user_6", "pass_6");
+
+ static const struct {
+ const char* observed_form_origin;
+ const char* observed_form_realm;
+ std::vector<PasswordForm> matching_forms;
+ std::vector<PasswordForm> all_suppressed_forms;
+ std::vector<PasswordForm> expected_suppressed_https_forms;
+ std::vector<PasswordForm> expected_suppressed_psl_forms;
+ std::vector<PasswordForm> expected_suppressed_same_org_name_forms;
+ } kTestCases[] = {
+ {kTestHttpURL,
+ kTestHttpURL,
+ {kFormHttpSameHost},
+ {kFormHttpsSameHost, kFormHttpPSLMatchingHost, kFormHttpsPSLMatchingHost,
+ kFormHttpSameOrgNameHost, kFormHttpsSameOrgNameHost},
+ {kFormHttpsSameHost},
+ {kFormHttpPSLMatchingHost},
+ {kFormHttpsPSLMatchingHost, kFormHttpSameOrgNameHost,
+ kFormHttpsSameOrgNameHost}},
+
+ {kTestHttpsURL,
+ kTestHttpsURL,
+ {kFormHttpsSameHost},
+ {kFormHttpSameHost, kFormHttpPSLMatchingHost, kFormHttpsPSLMatchingHost,
+ kFormHttpSameOrgNameHost, kFormHttpsSameOrgNameHost},
+ std::vector<PasswordForm>(),
+ {kFormHttpsPSLMatchingHost},
+ {kFormHttpPSLMatchingHost, kFormHttpSameOrgNameHost,
+ kFormHttpsSameOrgNameHost}},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(test_case.observed_form_origin);
+
+ form_digest_ = PasswordStore::FormDigest(
+ PasswordForm::SCHEME_HTML, test_case.observed_form_origin,
+ GURL(test_case.observed_form_origin));
+ RecreateFormFetcherWithQueryingSuppressedForms();
+
+ // The matching PasswordStore results coming in should trigger another
+ // GetLogins request to fetcht the suppressed forms.
+ base::WeakPtr<PasswordStoreConsumer> suppressed_form_fetcher_ptr = nullptr;
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ test_case.matching_forms, test_case.observed_form_realm,
+ &suppressed_form_fetcher_ptr));
+
+ EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+ EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), IsEmpty());
+
+ ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms(
+ test_case.all_suppressed_forms, suppressed_form_fetcher_ptr));
+
+ EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+ EXPECT_THAT(
+ PointeeValues(form_fetcher_->GetSuppressedHTTPSForms()),
+ UnorderedElementsAreArray(test_case.expected_suppressed_https_forms));
+ EXPECT_THAT(
+ PointeeValues(form_fetcher_->GetSuppressedPSLMatchingForms()),
+ UnorderedElementsAreArray(test_case.expected_suppressed_psl_forms));
+ EXPECT_THAT(
+ PointeeValues(form_fetcher_->GetSuppressedSameOrganizationNameForms()),
+ UnorderedElementsAreArray(
+ test_case.expected_suppressed_same_org_name_forms));
+ }
+}
+
+TEST_F(FormFetcherImplTest, SuppressedForms_RequeriedOnRefetch) {
+ RecreateFormFetcherWithQueryingSuppressedForms();
+
+ base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr;
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr));
+ ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms(
+ std::vector<PasswordForm>(), https_form_fetcher_ptr));
+
+ // Another call to Fetch() should refetch the list of suppressed credentials.
+ const PasswordForm suppressed_https_form = CreateNonFederated();
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr));
+ ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms(
+ {suppressed_https_form}, https_form_fetcher_ptr));
+
+ EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(),
+ UnorderedElementsAre(Pointee(suppressed_https_form)));
+}
+
+TEST_F(FormFetcherImplTest, SuppressedForms_NeverWiped) {
+ RecreateFormFetcherWithQueryingSuppressedForms();
+
+ static const PasswordForm kFormHttpsSameHost =
+ CreateHTMLForm(kTestHttpsURL, "user_1", "pass_1");
+ static const PasswordForm kFormHttpPSLMatchingHost =
+ CreateHTMLForm(kTestPSLMatchingHttpURL, "user_2", "pass_2");
+ static const PasswordForm kFormHttpSameOrgNameHost =
+ CreateHTMLForm(kTestHttpSameOrgNameURL, "user_3", "pass_3");
+
+ base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr;
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr));
+ ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms(
+ {kFormHttpsSameHost, kFormHttpPSLMatchingHost, kFormHttpSameOrgNameHost},
+ https_form_fetcher_ptr));
+
+ // Ensure that calling Fetch() does not wipe (even temporarily) the previously
+ // fetched list of suppressed HTTPS credentials. Stale is better than nothing.
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr));
+
+ EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+ EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(),
+ UnorderedElementsAre(Pointee(kFormHttpsSameHost)));
+ EXPECT_THAT(form_fetcher_->GetSuppressedPSLMatchingForms(),
+ UnorderedElementsAre(Pointee(kFormHttpPSLMatchingHost)));
+ EXPECT_THAT(form_fetcher_->GetSuppressedSameOrganizationNameForms(),
+ UnorderedElementsAre(Pointee(kFormHttpSameOrgNameHost)));
+}
+
+TEST_F(FormFetcherImplTest, SuppressedForms_FormFetcherDestroyedWhileQuerying) {
+ RecreateFormFetcherWithQueryingSuppressedForms();
+
+ base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr = nullptr;
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr));
+
+ EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+
+ // Destroy FormFetcher while SuppressedHTTPSFormFetcher is busy.
+ form_fetcher_.reset();
+}
+
+// Exercise the scenario where querying the suppressed HTTPS logins takes so
+// long that in the meantime there is another call to Fetch(), which completes,
+// and triggers fetching HTTPS suppressed forms yet again. In this case, the
+// first SuppressedHTTPSFormFetcher is destroyed and its query cancelled.
+TEST_F(FormFetcherImplTest, SuppressedForms_SimultaneousQueries) {
+ RecreateFormFetcherWithQueryingSuppressedForms();
+
+ base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr1;
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr1));
+
+ base::WeakPtr<PasswordStoreConsumer> https_form_fetcher_ptr2;
+ ASSERT_NO_FATAL_FAILURE(SimulateFetchAndExpectQueryingSuppressedForms(
+ std::vector<PasswordForm>(), kTestHttpURL, &https_form_fetcher_ptr2));
+
+ EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+ EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(), IsEmpty());
+ EXPECT_FALSE(https_form_fetcher_ptr1);
+ ASSERT_TRUE(https_form_fetcher_ptr2);
+
+ static const PasswordForm kFormHttpsSameHost =
+ CreateHTMLForm(kTestHttpsURL, "user_1", "pass_1");
+ static const PasswordForm kFormHttpPSLMatchingHost =
+ CreateHTMLForm(kTestPSLMatchingHttpURL, "user_2", "pass_2");
+ static const PasswordForm kFormHttpSameOrgNameHost =
+ CreateHTMLForm(kTestHttpSameOrgNameURL, "user_3", "pass_3");
+
+ ASSERT_NO_FATAL_FAILURE(CompleteQueryingSuppressedForms(
+ {kFormHttpsSameHost, kFormHttpPSLMatchingHost, kFormHttpSameOrgNameHost},
+ https_form_fetcher_ptr2));
+
+ EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+
+ EXPECT_TRUE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+ EXPECT_THAT(form_fetcher_->GetSuppressedHTTPSForms(),
+ UnorderedElementsAre(Pointee(kFormHttpsSameHost)));
+ EXPECT_THAT(form_fetcher_->GetSuppressedPSLMatchingForms(),
+ UnorderedElementsAre(Pointee(kFormHttpPSLMatchingHost)));
+ EXPECT_THAT(form_fetcher_->GetSuppressedSameOrganizationNameForms(),
+ UnorderedElementsAre(Pointee(kFormHttpSameOrgNameHost)));
+}
+
+TEST_F(FormFetcherImplTest, SuppressedForms_NotQueriedForFederatedRealms) {
+ form_digest_ = PasswordStore::FormDigest(
+ PasswordForm::SCHEME_HTML, kTestFederatedRealm, GURL(kTestFederationURL));
+ RecreateFormFetcherWithQueryingSuppressedForms();
+ Fetch();
+
+ EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0);
+ EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u));
+
+ form_fetcher_->OnGetPasswordStoreResults(
+ MakeResults(std::vector<PasswordForm>()));
+
+ EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
+ EXPECT_FALSE(form_fetcher_->DidCompleteQueryingSuppressedForms());
+}
+
// Cloning a FormFetcherImpl with empty results should result in an
// instance with empty results.
TEST_F(FormFetcherImplTest, Clone_EmptyResults) {
+ RecreateFormFetcherWithQueryingSuppressedForms();
Fetch();
+ EXPECT_CALL(consumer_, ProcessMatches(IsEmpty(), 0u));
+ EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _));
form_fetcher_->OnGetPasswordStoreResults(
std::vector<std::unique_ptr<PasswordForm>>());
+ ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(mock_store_.get()));
// Clone() should not cause re-fetching from PasswordStore.
EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0);
+ EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _)).Times(0);
auto clone = form_fetcher_->Clone();
EXPECT_EQ(FormFetcher::State::NOT_WAITING, clone->GetState());
EXPECT_THAT(clone->GetInteractionsStats(), IsEmpty());
EXPECT_THAT(clone->GetFederatedMatches(), IsEmpty());
+ EXPECT_THAT(clone->GetSuppressedHTTPSForms(), IsEmpty());
MockConsumer consumer;
EXPECT_CALL(consumer, ProcessMatches(IsEmpty(), 0u));
clone->AddConsumer(&consumer);
@@ -572,6 +866,7 @@ TEST_F(FormFetcherImplTest, Clone_EmptyResults) {
// Cloning a FormFetcherImpl with non-empty results should result in an
// instance with the same results.
TEST_F(FormFetcherImplTest, Clone_NonEmptyResults) {
+ RecreateFormFetcherWithQueryingSuppressedForms();
Fetch();
PasswordForm non_federated = CreateNonFederated();
PasswordForm federated = CreateFederated();
@@ -580,10 +875,15 @@ TEST_F(FormFetcherImplTest, Clone_NonEmptyResults) {
results.push_back(base::MakeUnique<PasswordForm>(non_federated));
results.push_back(base::MakeUnique<PasswordForm>(federated));
results.push_back(base::MakeUnique<PasswordForm>(android_federated));
+
+ EXPECT_CALL(consumer_, ProcessMatches(::testing::SizeIs(1), 0u));
+ EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _));
form_fetcher_->OnGetPasswordStoreResults(std::move(results));
+ ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(mock_store_.get()));
// Clone() should not cause re-fetching from PasswordStore.
EXPECT_CALL(*mock_store_, GetLogins(_, _)).Times(0);
+ EXPECT_CALL(*mock_store_, GetLoginsForSameOrganizationName(_, _)).Times(0);
auto clone = form_fetcher_->Clone();
// Additionally, destroy the original FormFetcher. This should not invalidate
@@ -615,6 +915,33 @@ TEST_F(FormFetcherImplTest, Clone_Stats) {
EXPECT_EQ(1u, clone->GetInteractionsStats().size());
}
+// Cloning a FormFetcherImpl with some suppressed credentials should
+// result in an instance with the same suppressed credentials.
+TEST_F(FormFetcherImplTest, Clone_SuppressedCredentials) {
+ Fetch();
+ form_fetcher_->OnGetPasswordStoreResults(
+ std::vector<std::unique_ptr<PasswordForm>>());
+
+ static const PasswordForm kFormHttpsSameHost =
+ CreateHTMLForm(kTestHttpsURL, "user_1", "pass_1");
+ static const PasswordForm kFormHttpPSLMatchingHost =
+ CreateHTMLForm(kTestPSLMatchingHttpURL, "user_2", "pass_2");
+ static const PasswordForm kFormHttpSameOrgNameHost =
+ CreateHTMLForm(kTestHttpSameOrgNameURL, "user_3", "pass_3");
+
+ form_fetcher_->ProcessSuppressedForms(
+ MakeResults({kFormHttpsSameHost, kFormHttpPSLMatchingHost,
+ kFormHttpSameOrgNameHost}));
+
+ auto clone = form_fetcher_->Clone();
+ EXPECT_THAT(PointeeValues(clone->GetSuppressedHTTPSForms()),
+ UnorderedElementsAre(kFormHttpsSameHost));
+ EXPECT_THAT(PointeeValues(clone->GetSuppressedPSLMatchingForms()),
+ UnorderedElementsAre(kFormHttpPSLMatchingHost));
+ EXPECT_THAT(PointeeValues(clone->GetSuppressedSameOrganizationNameForms()),
+ UnorderedElementsAre(kFormHttpSameOrgNameHost));
+}
+
// Check that removing consumers stops them from receiving store updates.
TEST_F(FormFetcherImplTest, RemoveConsumer) {
Fetch();
diff --git a/chromium/components/password_manager/core/browser/login_database.cc b/chromium/components/password_manager/core/browser/login_database.cc
index 5de021e0ea7..e2067b61a2f 100644
--- a/chromium/components/password_manager/core/browser/login_database.cc
+++ b/chromium/components/password_manager/core/browser/login_database.cc
@@ -30,12 +30,14 @@
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/browser/password_manager_util.h"
+#include "components/password_manager/core/browser/psl_matching_helper.h"
#include "components/password_manager/core/browser/sql_table_builder.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_urls.h"
#include "sql/connection.h"
#include "sql/statement.h"
#include "sql/transaction.h"
+#include "third_party/re2/src/re2/re2.h"
#include "url/origin.h"
#include "url/url_constants.h"
@@ -1133,6 +1135,48 @@ bool LoginDatabase::GetLogins(
return false;
}
+bool LoginDatabase::GetLoginsForSameOrganizationName(
+ const std::string& signon_realm,
+ std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const {
+ DCHECK(forms);
+ forms->clear();
+
+ GURL signon_realm_as_url(signon_realm);
+ if (!signon_realm_as_url.SchemeIsHTTPOrHTTPS())
+ return true;
+
+ std::string organization_name =
+ GetOrganizationIdentifyingName(signon_realm_as_url);
+ if (organization_name.empty())
+ return true;
+
+ // SQLite does not provide a function to escape special characters, but
+ // seemingly uses POSIX Extended Regular Expressions (ERE), and so does RE2.
+ // In the worst case the bogus results will be filtered out below.
+ static constexpr char kRESchemeAndSubdomains[] = "^https?://([\\w+%-]+\\.)*";
+ static constexpr char kREDotAndEffectiveTLD[] = "(\\.[\\w+%-]+)+/$";
+ const std::string signon_realms_with_same_organization_name_regexp =
+ kRESchemeAndSubdomains + RE2::QuoteMeta(organization_name) +
+ kREDotAndEffectiveTLD;
+ sql::Statement s(db_.GetCachedStatement(
+ SQL_FROM_HERE, get_same_organization_name_logins_statement_.c_str()));
+ s.BindString(0, signon_realms_with_same_organization_name_regexp);
+
+ bool success = StatementToForms(&s, nullptr, forms);
+
+ using PasswordFormPtr = std::unique_ptr<autofill::PasswordForm>;
+ base::EraseIf(*forms, [&organization_name](const PasswordFormPtr& form) {
+ GURL candidate_signon_realm_as_url(form->signon_realm);
+ DCHECK_EQ(form->scheme, PasswordForm::SCHEME_HTML);
+ DCHECK(candidate_signon_realm_as_url.SchemeIsHTTPOrHTTPS());
+ std::string candidate_form_organization_name =
+ GetOrganizationIdentifyingName(candidate_signon_realm_as_url);
+ return candidate_form_organization_name != organization_name;
+ });
+
+ return success;
+}
+
bool LoginDatabase::GetLoginsCreatedBetween(
const base::Time begin,
const base::Time end,
@@ -1315,6 +1359,11 @@ void LoginDatabase::InitializeStatementStrings(const SQLTableBuilder& builder) {
DCHECK(get_statement_psl_federated_.empty());
get_statement_psl_federated_ =
get_statement_ + psl_statement + psl_federated_statement;
+ DCHECK(get_same_organization_name_logins_statement_.empty());
+ get_same_organization_name_logins_statement_ =
+ "SELECT " + all_column_names +
+ " FROM LOGINS"
+ " WHERE scheme == 0 AND signon_realm REGEXP ?";
DCHECK(created_statement_.empty());
created_statement_ =
"SELECT " + all_column_names +
diff --git a/chromium/components/password_manager/core/browser/login_database.h b/chromium/components/password_manager/core/browser/login_database.h
index c6cf73dc834..ed53b3a8e08 100644
--- a/chromium/components/password_manager/core/browser/login_database.h
+++ b/chromium/components/password_manager/core/browser/login_database.h
@@ -91,6 +91,18 @@ class LoginDatabase {
std::vector<std::unique_ptr<autofill::PasswordForm>>* forms)
const WARN_UNUSED_RESULT;
+ // Retrieves all stored credentials with SCHEME_HTTP that have a realm whose
+ // organization-identifying name -- that is, the first domain name label below
+ // the effective TLD -- matches that of |signon_realm|. Return value indicates
+ // a successful query (but potentially no results).
+ //
+ // For example, the organization-identifying name of "https://foo.example.org"
+ // is `example`, and logins will be returned for "http://bar.example.co.uk",
+ // but not for "http://notexample.com" or "https://example.foo.com".
+ bool GetLoginsForSameOrganizationName(
+ const std::string& signon_realm,
+ std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const;
+
// Gets all logins created from |begin| onwards (inclusive) and before |end|.
// You may use a null Time value to do an unbounded search in either
// direction.
@@ -224,6 +236,7 @@ class LoginDatabase {
std::string get_statement_psl_;
std::string get_statement_federated_;
std::string get_statement_psl_federated_;
+ std::string get_same_organization_name_logins_statement_;
std::string created_statement_;
std::string synced_statement_;
std::string blacklisted_statement_;
diff --git a/chromium/components/password_manager/core/browser/login_database_unittest.cc b/chromium/components/password_manager/core/browser/login_database_unittest.cc
index e04d1c25c32..f219fd8be9e 100644
--- a/chromium/components/password_manager/core/browser/login_database_unittest.cc
+++ b/chromium/components/password_manager/core/browser/login_database_unittest.cc
@@ -21,6 +21,7 @@
#include "build/build_config.h"
#include "components/autofill/core/common/password_form.h"
#include "components/os_crypt/os_crypt_mocker.h"
+#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/psl_matching_helper.h"
#include "sql/connection.h"
#include "sql/statement.h"
@@ -447,7 +448,7 @@ TEST_F(LoginDatabaseTest, TestFederatedMatchingLocalhost) {
EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
EXPECT_EQ(AddChangeForForm(form_with_port), db().AddLogin(form_with_port));
- // Match twice.
+ // Match localhost with and without port.
PasswordStore::FormDigest form_request(PasswordForm::SCHEME_HTML,
"http://localhost/",
GURL("http://localhost/"));
@@ -455,7 +456,6 @@ TEST_F(LoginDatabaseTest, TestFederatedMatchingLocalhost) {
EXPECT_TRUE(db().GetLogins(form_request, &result));
EXPECT_THAT(result, UnorderedElementsAre(Pointee(form)));
- // Match against the mobile site.
form_request.origin = GURL("http://localhost:8080/");
form_request.signon_realm = "http://localhost:8080/";
EXPECT_TRUE(db().GetLogins(form_request, &result));
@@ -790,6 +790,146 @@ TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingRegexp) {
EXPECT_EQ(0U, result.size());
}
+TEST_F(LoginDatabaseTest,
+ GetLoginsForSameOrganizationName_OnlyWebHTTPFormsAreConsidered) {
+ static constexpr const struct {
+ const PasswordFormData form_data;
+ const char* other_queried_signon_realm;
+ bool expected_matches_itself;
+ bool expected_matches_other_realm;
+ } kTestCases[] = {
+ {{PasswordForm::SCHEME_HTML, "https://example.com/",
+ "https://example.com/origin", "", L"", L"", L"", L"u", L"p", false, 1},
+ nullptr,
+ true,
+ true},
+ {{PasswordForm::SCHEME_BASIC, "http://example.com/realm",
+ "http://example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
+ nullptr,
+ false,
+ false},
+ {{PasswordForm::SCHEME_OTHER, "ftp://example.com/realm",
+ "ftp://example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
+ "http://example.com/realm",
+ false,
+ false},
+ {{PasswordForm::SCHEME_HTML,
+ "federation://example.com/accounts.google.com",
+ "https://example.com/orgin", "", L"", L"", L"", L"u",
+ kTestingFederatedLoginMarker, false, 1},
+ "http://example.com/",
+ false,
+ false},
+ {{PasswordForm::SCHEME_HTML, "android://hash@example.com/",
+ "android://hash@example.com/", "", L"", L"", L"", L"u", L"p", false, 1},
+ "http://example.com/",
+ false,
+ false},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(test_case.form_data.signon_realm);
+
+ std::unique_ptr<PasswordForm> form =
+ CreatePasswordFormFromDataForTesting(test_case.form_data);
+ ASSERT_EQ(AddChangeForForm(*form), db().AddLogin(*form));
+
+ std::vector<std::unique_ptr<PasswordForm>> same_organization_forms;
+ EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
+ form->signon_realm, &same_organization_forms));
+ EXPECT_EQ(test_case.expected_matches_itself ? 1u : 0u,
+ same_organization_forms.size());
+
+ if (test_case.other_queried_signon_realm) {
+ same_organization_forms.clear();
+ EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
+ test_case.other_queried_signon_realm, &same_organization_forms));
+ EXPECT_EQ(test_case.expected_matches_other_realm ? 1u : 0u,
+ same_organization_forms.size());
+ }
+
+ ASSERT_TRUE(db().RemoveLogin(*form));
+ }
+}
+
+TEST_F(LoginDatabaseTest, GetLoginsForSameOrganizationName_DetailsOfMatching) {
+ const struct {
+ const char* saved_signon_realm;
+ const char* queried_signon_realm;
+ bool expected_matches;
+ } kTestCases[] = {
+ // PSL matches are also same-organization-name matches.
+ {"http://psl.example.com/", "http://example.com/", true},
+ {"http://example.com/", "http://sub.example.com/", true},
+ {"https://a.b.example.co.uk/", "https://c.d.e.example.co.uk/", true},
+
+ // Non-PSL but same-organization-name matches. Also an illustration why it
+ // would be unsafe to offer these credentials for filling.
+ {"https://example.com/", "https://example.co.uk/", true},
+ {"https://example.co.uk/", "https://example.com/", true},
+ {"https://a.example.appspot.com/", "https://b.example.co.uk/", true},
+
+ // Same-organization-name matches are HTTP/HTTPS-agnostic.
+ {"https://example.com/", "http://example.com/", true},
+ {"http://example.com/", "https://example.com/", true},
+
+ {"http://www.foo-bar.com/", "http://sub.foo-bar.com", true},
+ {"http://www.foo_bar.com/", "http://sub.foo_bar.com", true},
+ {"http://www.foo-bar.com/", "http://sub.foo%2Dbar.com", true},
+ {"http://www.foo%21bar.com/", "http://sub.foo!bar.com", true},
+ {"http://a.xn--sztr-7na0i.co.uk/", "http://xn--sztr-7na0i.com/", true},
+ {"http://a.xn--sztr-7na0i.co.uk/", "http://www.sz\xc3\xb3t\xc3\xa1r.com/",
+ true},
+
+ {"http://www.foo+bar.com/", "http://sub.foo+bar.com", true},
+ {"http://www.foooobar.com/", "http://sub.foo+bar.com", false},
+ {"http://www.fobar.com/", "http://sub.foo?bar.com", false},
+ {"http://www.foozbar.com/", "http://sub.foo.bar.com", false},
+ {"http://www.foozbar.com/", "http://sub.foo[a-z]bar.com", false},
+
+ {"https://notexample.com/", "https://example.com/", false},
+ {"https://a.notexample.com/", "https://example.com/", false},
+ {"https://example.com/", "https://notexample.com/", false},
+ {"https://example.com/", "https://example.bar.com/", false},
+ {"https://example.foo.com/", "https://example.com/", false},
+ {"https://example.foo.com/", "https://example.bar.com/", false},
+
+ // URLs without host portions, hosts without registry controlled domains
+ // or hosts consisting of a registry.
+ {"http://localhost/", "http://localhost/", false},
+ {"https://example/", "https://example/", false},
+ {"https://co.uk/", "https://co.uk/", false},
+ {"https://example/", "https://example.com/", false},
+ {"https://a.example/", "https://example.com/", false},
+ {"https://example.com/", "https://example/", false},
+ {"https://127.0.0.1/", "https://127.0.0.1/", false},
+ {"https:/[3ffe:2a00:100:7031::1]/", "https:/[3ffe:2a00:100:7031::1]/",
+ false},
+
+ // Queried |signon-realms| are invalid URIs.
+ {"https://example.com/", "", false},
+ {"https://example.com/", "bad url", false},
+ {"https://example.com/", "https://", false},
+ {"https://example.com/", "http://www.foo;bar.com", false},
+ {"https://example.com/", "example", false},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(test_case.saved_signon_realm);
+ SCOPED_TRACE(test_case.queried_signon_realm);
+
+ std::unique_ptr<PasswordForm> form = CreatePasswordFormFromDataForTesting(
+ {PasswordForm::SCHEME_HTML, test_case.saved_signon_realm,
+ test_case.saved_signon_realm, "", L"", L"", L"", L"u", L"p", true, 1});
+ std::vector<std::unique_ptr<PasswordForm>> result;
+ ASSERT_EQ(AddChangeForForm(*form), db().AddLogin(*form));
+ EXPECT_TRUE(db().GetLoginsForSameOrganizationName(
+ test_case.queried_signon_realm, &result));
+ EXPECT_EQ(test_case.expected_matches ? 1u : 0u, result.size());
+ ASSERT_TRUE(db().RemoveLogin(*form));
+ }
+}
+
static bool AddTimestampedLogin(LoginDatabase* db,
std::string url,
const std::string& unique_string,
diff --git a/chromium/components/password_manager/core/browser/mock_password_store.h b/chromium/components/password_manager/core/browser/mock_password_store.h
index a8dbbf4d36b..fe210f3da18 100644
--- a/chromium/components/password_manager/core/browser/mock_password_store.h
+++ b/chromium/components/password_manager/core/browser/mock_password_store.h
@@ -13,18 +13,23 @@
#include "components/password_manager/core/browser/statistics_table.h"
#include "testing/gmock/include/gmock/gmock.h"
+class PrefService;
+
namespace password_manager {
class MockPasswordStore : public PasswordStore {
public:
MockPasswordStore();
- bool Init(const syncer::SyncableService::StartSyncFlare& flare) override {
+ bool Init(const syncer::SyncableService::StartSyncFlare& flare,
+ PrefService* prefs) override {
return true;
};
MOCK_METHOD1(RemoveLogin, void(const autofill::PasswordForm&));
MOCK_METHOD2(GetLogins,
void(const PasswordStore::FormDigest&, PasswordStoreConsumer*));
+ MOCK_METHOD2(GetLoginsForSameOrganizationName,
+ void(const std::string&, PasswordStoreConsumer*));
MOCK_METHOD1(AddLogin, void(const autofill::PasswordForm&));
MOCK_METHOD1(UpdateLogin, void(const autofill::PasswordForm&));
MOCK_METHOD2(UpdateLoginWithPrimaryKey,
@@ -57,6 +62,10 @@ class MockPasswordStore : public PasswordStore {
const PasswordStore::FormDigest& form) override {
return std::vector<std::unique_ptr<autofill::PasswordForm>>();
}
+ std::vector<std::unique_ptr<autofill::PasswordForm>>
+ FillLoginsForSameOrganizationName(const std::string& signon_realm) override {
+ return std::vector<std::unique_ptr<autofill::PasswordForm>>();
+ }
MOCK_METHOD1(FillAutofillableLogins,
bool(std::vector<std::unique_ptr<autofill::PasswordForm>>*));
MOCK_METHOD1(FillBlacklistLogins,
diff --git a/chromium/components/password_manager/core/browser/password_form_manager.cc b/chromium/components/password_manager/core/browser/password_form_manager.cc
index eb88be67ab7..98100d29dd9 100644
--- a/chromium/components/password_manager/core/browser/password_form_manager.cc
+++ b/chromium/components/password_manager/core/browser/password_form_manager.cc
@@ -11,6 +11,7 @@
#include <utility>
#include "base/feature_list.h"
+#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
@@ -197,14 +198,6 @@ void LabelFields(const FieldTypeMap& field_types,
}
}
-// Check whether |form_data| corresponds to a 2 field form with 1 text field and
-// 1 password field. Such form is likely sign-in form.
-bool IsSignInSubmission(const FormData& form_data) {
- return form_data.fields.size() == 2 &&
- form_data.fields[0].form_control_type == "text" &&
- form_data.fields[1].form_control_type == "password";
-}
-
} // namespace
PasswordFormManager::PasswordFormManager(
@@ -239,12 +232,13 @@ PasswordFormManager::PasswordFormManager(
submit_result_(kSubmitResultNotSubmitted),
form_type_(kFormTypeUnspecified),
form_saver_(std::move(form_saver)),
- owned_form_fetcher_(form_fetcher
- ? nullptr
- : base::MakeUnique<FormFetcherImpl>(
- PasswordStore::FormDigest(observed_form),
- client,
- /* should_migrate_http_passwords */ true)),
+ owned_form_fetcher_(
+ form_fetcher ? nullptr
+ : base::MakeUnique<FormFetcherImpl>(
+ PasswordStore::FormDigest(observed_form),
+ client,
+ true /* should_migrate_http_passwords */,
+ true /* should_query_suppressed_https_forms */)),
form_fetcher_(form_fetcher ? form_fetcher : owned_form_fetcher_.get()),
is_main_frame_secure_(client->IsMainFrameSecure()) {
if (owned_form_fetcher_)
@@ -261,6 +255,7 @@ PasswordFormManager::~PasswordFormManager() {
UMA_HISTOGRAM_ENUMERATION("PasswordManager.ActionsTakenV3", GetActionsTaken(),
kMaxNumActionsTaken);
+
// Use the visible main frame URL at the time the PasswordFormManager
// is created, in case a navigation has already started and the
// visible URL has changed.
@@ -268,6 +263,9 @@ PasswordFormManager::~PasswordFormManager() {
UMA_HISTOGRAM_ENUMERATION("PasswordManager.ActionsTakenOnNonSecureForm",
GetActionsTaken(), kMaxNumActionsTaken);
}
+
+ RecordHistogramsOnSuppressedAccounts();
+
if (submit_result_ == kSubmitResultNotSubmitted) {
if (has_generated_password_)
metrics_util::LogPasswordGenerationSubmissionEvent(
@@ -276,6 +274,7 @@ PasswordFormManager::~PasswordFormManager() {
metrics_util::LogPasswordGenerationAvailableSubmissionEvent(
metrics_util::PASSWORD_NOT_SUBMITTED);
}
+
if (form_type_ != kFormTypeUnspecified) {
UMA_HISTOGRAM_ENUMERATION("PasswordManager.SubmittedFormType", form_type_,
kFormTypeMax);
@@ -292,6 +291,95 @@ int PasswordFormManager::GetActionsTaken() const {
(manager_action_ + kManagerActionMax * submit_result_);
}
+int PasswordFormManager::GetHistogramSampleForSuppressedAccounts(
+ const std::vector<const autofill::PasswordForm*> suppressed_forms,
+ PasswordForm::Type manual_or_generated) const {
+ DCHECK(form_fetcher_->DidCompleteQueryingSuppressedForms());
+
+ SuppressedAccountExistence best_matching_account = kSuppressedAccountNone;
+ for (const autofill::PasswordForm* form : suppressed_forms) {
+ if (form->type != manual_or_generated)
+ continue;
+
+ SuppressedAccountExistence current_account;
+ if (pending_credentials_.password_value.empty())
+ current_account = kSuppressedAccountExists;
+ else if (form->username_value != pending_credentials_.username_value)
+ current_account = kSuppressedAccountExistsDifferentUsername;
+ else if (form->password_value != pending_credentials_.password_value)
+ current_account = kSuppressedAccountExistsSameUsername;
+ else
+ current_account = kSuppressedAccountExistsSameUsernameAndPassword;
+
+ best_matching_account = std::max(best_matching_account, current_account);
+ }
+
+ // Merge kManagerActionNone and kManagerActionBlacklisted_Obsolete. This
+ // lowers the number of histogram buckets used by 33%.
+ ManagerActionNew manager_action_new =
+ (manager_action_ == kManagerActionAutofilled)
+ ? kManagerActionNewAutofilled
+ : kManagerActionNewNone;
+
+ // Encoding: most significant digit is the |best_matching_account|.
+ int mixed_base_encoding = 0;
+ mixed_base_encoding += best_matching_account;
+ (mixed_base_encoding *= kSubmitResultMax) += submit_result_;
+ (mixed_base_encoding *= kManagerActionNewMax) += manager_action_new;
+ (mixed_base_encoding *= kUserActionMax) += user_action_;
+ DCHECK_LT(mixed_base_encoding, kMaxSuppressedAccountStats);
+ return mixed_base_encoding;
+}
+
+void PasswordFormManager::RecordHistogramsOnSuppressedAccounts() const {
+ UMA_HISTOGRAM_BOOLEAN("PasswordManager.QueryingSuppressedAccountsFinished",
+ form_fetcher_->DidCompleteQueryingSuppressedForms());
+
+ if (!form_fetcher_->DidCompleteQueryingSuppressedForms())
+ return;
+
+ if (!observed_form_.origin.SchemeIsCryptographic()) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.SuppressedAccount.Generated.HTTPSNotHTTP",
+ GetHistogramSampleForSuppressedAccounts(
+ form_fetcher_->GetSuppressedHTTPSForms(),
+ PasswordForm::TYPE_GENERATED),
+ kMaxSuppressedAccountStats);
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.SuppressedAccount.Manual.HTTPSNotHTTP",
+ GetHistogramSampleForSuppressedAccounts(
+ form_fetcher_->GetSuppressedHTTPSForms(),
+ PasswordForm::TYPE_MANUAL),
+ kMaxSuppressedAccountStats);
+ }
+
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.SuppressedAccount.Generated.PSLMatching",
+ GetHistogramSampleForSuppressedAccounts(
+ form_fetcher_->GetSuppressedPSLMatchingForms(),
+ PasswordForm::TYPE_GENERATED),
+ kMaxSuppressedAccountStats);
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.SuppressedAccount.Manual.PSLMatching",
+ GetHistogramSampleForSuppressedAccounts(
+ form_fetcher_->GetSuppressedPSLMatchingForms(),
+ PasswordForm::TYPE_MANUAL),
+ kMaxSuppressedAccountStats);
+
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.SuppressedAccount.Generated.SameOrganizationName",
+ GetHistogramSampleForSuppressedAccounts(
+ form_fetcher_->GetSuppressedSameOrganizationNameForms(),
+ PasswordForm::TYPE_GENERATED),
+ kMaxSuppressedAccountStats);
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.SuppressedAccount.Manual.SameOrganizationName",
+ GetHistogramSampleForSuppressedAccounts(
+ form_fetcher_->GetSuppressedSameOrganizationNameForms(),
+ PasswordForm::TYPE_MANUAL),
+ kMaxSuppressedAccountStats);
+}
+
// static
base::string16 PasswordFormManager::PasswordToSave(const PasswordForm& form) {
if (form.new_password_element.empty() || form.new_password_value.empty())
@@ -419,6 +507,9 @@ void PasswordFormManager::Save() {
DCHECK_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
DCHECK(!client_->IsIncognito());
+ metrics_util::LogPasswordAcceptedSaveUpdateSubmissionIndicatorEvent(
+ submitted_form_->submission_event);
+
if ((user_action_ == kUserActionNone) &&
DidPreferenceChange(best_matches_, pending_credentials_.username_value)) {
SetUserAction(kUserActionChoose);
@@ -451,6 +542,8 @@ void PasswordFormManager::Save() {
void PasswordFormManager::Update(
const autofill::PasswordForm& credentials_to_update) {
+ metrics_util::LogPasswordAcceptedSaveUpdateSubmissionIndicatorEvent(
+ submitted_form_->submission_event);
if (observed_form_.IsPossibleChangePasswordForm()) {
FormStructure form_structure(credentials_to_update.form_data);
UploadPasswordVote(observed_form_, autofill::NEW_PASSWORD,
@@ -623,19 +716,12 @@ void PasswordFormManager::ProcessFrameInternal(
// Proceed to autofill.
// Note that we provide the choices but don't actually prefill a value if:
- // (1) we are in Incognito mode, (2) the ACTION paths don't match,
- // (3) if it matched using public suffix domain matching, or
- // (4) the form is change password form.
- // However, 2 and 3 should not apply to Android-based credentials found
- // via affiliation-based matching (we want to autofill them).
- // TODO(engedy): Clean this up. See: https://crbug.com/476519.
- bool wait_for_username =
- client_->IsIncognito() ||
- (!IsValidAndroidFacetURI(preferred_match_->signon_realm) &&
- (observed_form_.action.GetWithEmptyPath() !=
- preferred_match_->action.GetWithEmptyPath() ||
- preferred_match_->is_public_suffix_match ||
- observed_form_.IsPossibleChangePasswordForm()));
+ // (1) we are in Incognito mode, or
+ // (2) if it matched using public suffix domain matching, or
+ // (3) the form is change password form.
+ bool wait_for_username = client_->IsIncognito() ||
+ preferred_match_->is_public_suffix_match ||
+ observed_form_.IsPossibleChangePasswordForm();
if (wait_for_username) {
manager_action_ = kManagerActionNone;
} else {
@@ -1298,8 +1384,16 @@ void PasswordFormManager::SendVotesOnSave() {
if (observed_form_.IsPossibleChangePasswordFormWithoutUsername())
return;
- if (IsSignInSubmission(pending_credentials_.form_data)) {
- SendSignInVote(pending_credentials_.form_data);
+ // Send votes for sign-in form.
+ autofill::FormData& form_data = pending_credentials_.form_data;
+ if (form_data.fields.size() == 2 &&
+ form_data.fields[0].form_control_type == "text" &&
+ form_data.fields[1].form_control_type == "password") {
+ // |form_data| is received from the renderer and does not contain field
+ // values. Fill username field value with username to allow AutofillManager
+ // to detect username autofill type.
+ form_data.fields[0].value = pending_credentials_.username_value;
+ SendSignInVote(form_data);
return;
}
diff --git a/chromium/components/password_manager/core/browser/password_form_manager.h b/chromium/components/password_manager/core/browser/password_form_manager.h
index 0ad2261d268..2bc3bb26ab8 100644
--- a/chromium/components/password_manager/core/browser/password_form_manager.h
+++ b/chromium/components/password_manager/core/browser/password_form_manager.h
@@ -273,6 +273,13 @@ class PasswordFormManager : public FormFetcher::Consumer {
kManagerActionMax
};
+ // Same as above, without the obsoleted 'Blacklisted' action.
+ enum ManagerActionNew {
+ kManagerActionNewNone,
+ kManagerActionNewAutofilled,
+ kManagerActionNewMax
+ };
+
// UserAction - What does the user do with this form? If they do nothing
// (either by accepting what the password manager did, or by simply (not
// typing anything at all), you get None. If there were multiple choices and
@@ -325,6 +332,30 @@ class PasswordFormManager : public FormFetcher::Consumer {
static const int kMaxNumActionsTaken =
kManagerActionMax * kUserActionMax * kSubmitResultMax;
+ // Enumerates whether there were `suppressed` credentials. These are stored
+ // credentials that were not filled, even though they might be related to the
+ // |observed_form_|. See FormFetcher::GetSuppressed* for details.
+ //
+ // If suppressed credentials exist, it is also recorded whether their username
+ // and/or password matched those submitted.
+ enum SuppressedAccountExistence {
+ kSuppressedAccountNone,
+ // Recorded when there exists a suppressed account, but there was no
+ // submitted form to compare its username and password to.
+ kSuppressedAccountExists,
+ // Recorded when there was a submitted form.
+ kSuppressedAccountExistsDifferentUsername,
+ kSuppressedAccountExistsSameUsername,
+ kSuppressedAccountExistsSameUsernameAndPassword,
+ kSuppressedAccountExistenceMax,
+ };
+
+ // The maximum number of combinations recorded into histograms in the
+ // PasswordManager.SuppressedAccount.* family.
+ static constexpr int kMaxSuppressedAccountStats =
+ kSuppressedAccountExistenceMax * kManagerActionNewMax * kUserActionMax *
+ kSubmitResultMax;
+
// Through |driver|, supply the associated frame with appropriate information
// (fill data, whether to allow password generation, etc.).
void ProcessFrameInternal(const base::WeakPtr<PasswordManagerDriver>& driver);
@@ -399,6 +430,23 @@ class PasswordFormManager : public FormFetcher::Consumer {
// UMA.
int GetActionsTaken() const;
+ // When supplied with the list of all |suppressed_forms| that belong to
+ // certain suppressed credential type (see FormFetcher::GetSuppressed*),
+ // filters that list down to forms that are either |manual_or_generated|, and
+ // based on that, computes the histogram sample that is a mixed-based
+ // representation of a combination of four attributes:
+ // -- whether there were suppressed credentials (and if so, their relation to
+ // the submitted username/password).
+ // -- whether the |observed_form_| got ultimately submitted
+ // -- what action the password manager performed (|manager_action_|),
+ // -- and what action the user performed (|user_action_|_).
+ int GetHistogramSampleForSuppressedAccounts(
+ const std::vector<const autofill::PasswordForm*> suppressed_forms,
+ autofill::PasswordForm::Type manual_or_generated) const;
+
+ // Records all histograms in the PasswordManager.SuppressedAccount.* family.
+ void RecordHistogramsOnSuppressedAccounts() const;
+
// Tries to set all votes (e.g. autofill field types, generation vote) to
// a |FormStructure| and upload it to the server. Returns true on success.
bool UploadPasswordVote(const autofill::PasswordForm& form_to_upload,
@@ -469,7 +517,7 @@ class PasswordFormManager : public FormFetcher::Consumer {
// Set of blacklisted forms from the PasswordStore that best match the current
// form. They are owned by |form_fetcher_|, with the exception that if
// |new_blacklisted_| is not null, the address of that form is also inside
- // |blacklisted_matches_|..
+ // |blacklisted_matches_|.
std::vector<const autofill::PasswordForm*> blacklisted_matches_;
// If the observed form gets blacklisted through |this|, the blacklist entry
diff --git a/chromium/components/password_manager/core/browser/password_form_manager_unittest.cc b/chromium/components/password_manager/core/browser/password_form_manager_unittest.cc
index fd752c0aa7a..e4ed9f70800 100644
--- a/chromium/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -713,6 +713,92 @@ class PasswordFormManagerTest : public testing::Test {
// To spare typing for PasswordFormManager instances which need no driver.
const base::WeakPtr<PasswordManagerDriver> kNoDriver;
+ protected:
+ enum class SimulatedManagerAction { NONE, AUTOFILLED, OFFERED, OFFERED_PSL };
+ enum class SimulatedSubmitResult { NONE, PASSED, FAILED };
+ enum class SuppressedFormType { HTTPS, PSL_MATCH, SAME_ORGANIZATION_NAME };
+
+ PasswordForm CreateSuppressedForm(SuppressedFormType suppression_type,
+ const char* username,
+ const char* password,
+ PasswordForm::Type manual_or_generated) {
+ PasswordForm form = *saved_match();
+ switch (suppression_type) {
+ case SuppressedFormType::HTTPS:
+ form.origin = GURL("https://accounts.google.com/a/LoginAuth");
+ form.signon_realm = "https://accounts.google.com/";
+ break;
+ case SuppressedFormType::PSL_MATCH:
+ form.origin = GURL("http://other.google.com/");
+ form.signon_realm = "http://other.google.com/";
+ break;
+ case SuppressedFormType::SAME_ORGANIZATION_NAME:
+ form.origin = GURL("https://may-or-may-not-be.google.appspot.com/");
+ form.signon_realm = "https://may-or-may-not-be.google.appspot.com/";
+ break;
+ }
+ form.type = manual_or_generated;
+ form.username_value = ASCIIToUTF16(username);
+ form.password_value = ASCIIToUTF16(password);
+ return form;
+ }
+
+ void SimulateActionsOnHTTPObservedForm(
+ FakeFormFetcher* fetcher,
+ SimulatedManagerAction manager_action,
+ SimulatedSubmitResult submit_result,
+ const char* filled_username,
+ const char* filled_password,
+ const char* submitted_password = nullptr) {
+ PasswordFormManager form_manager(
+ password_manager(), client(), client()->driver(), *observed_form(),
+ base::MakeUnique<NiceMock<MockFormSaver>>(), fetcher);
+
+ EXPECT_CALL(*client()->mock_driver()->mock_autofill_download_manager(),
+ StartUploadRequest(_, _, _, _, _))
+ .Times(::testing::AnyNumber());
+
+ PasswordForm http_stored_form = *saved_match();
+ http_stored_form.username_value = base::ASCIIToUTF16(filled_username);
+ http_stored_form.password_value = base::ASCIIToUTF16(filled_password);
+ if (manager_action == SimulatedManagerAction::OFFERED_PSL)
+ http_stored_form.is_public_suffix_match = true;
+
+ std::vector<const PasswordForm*> matches;
+ if (manager_action != SimulatedManagerAction::NONE)
+ matches.push_back(&http_stored_form);
+
+ // Extra mile: kUserActionChoose is only recorded if there were multiple
+ // logins available and the preferred one was changed.
+ PasswordForm http_stored_form2 = http_stored_form;
+ if (manager_action == SimulatedManagerAction::OFFERED) {
+ http_stored_form.preferred = false;
+ http_stored_form2.username_value = ASCIIToUTF16("user-other@gmail.com");
+ matches.push_back(&http_stored_form2);
+ }
+
+ fetcher->Fetch();
+ fetcher->SetNonFederated(matches, 0u);
+
+ if (submit_result != SimulatedSubmitResult::NONE) {
+ PasswordForm submitted_form(*observed_form());
+ submitted_form.preferred = true;
+ submitted_form.username_value = base::ASCIIToUTF16(filled_username);
+ submitted_form.password_value =
+ submitted_password ? base::ASCIIToUTF16(submitted_password)
+ : base::ASCIIToUTF16(filled_password);
+
+ form_manager.ProvisionallySave(
+ submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+ if (submit_result == SimulatedSubmitResult::PASSED) {
+ form_manager.LogSubmitPassed();
+ form_manager.Save();
+ } else {
+ form_manager.LogSubmitFailed();
+ }
+ }
+ }
+
private:
// Necessary for callbacks, and for TestAutofillDriver.
base::MessageLoop message_loop_;
@@ -3149,6 +3235,8 @@ TEST_F(PasswordFormManagerTest, UploadSignInForm_WithAutofillTypes) {
ASSERT_EQ(2u, uploaded_form_structure->field_count());
autofill::ServerFieldTypeSet expected_types = {autofill::PASSWORD};
+ EXPECT_EQ(form_to_save.username_value,
+ uploaded_form_structure->field(0)->value);
EXPECT_EQ(expected_types,
uploaded_form_structure->field(1)->possible_types());
}
@@ -3180,4 +3268,231 @@ TEST_F(PasswordFormManagerTest, NoUploadsForSubmittedFormWithOnlyOneField) {
form_manager.Save();
}
+TEST_F(PasswordFormManagerTest,
+ SuppressedHTTPSFormsHistogram_NotRecordedIfStoreWasTooSlow) {
+ base::HistogramTester histogram_tester;
+
+ fake_form_fetcher()->set_did_complete_querying_suppressed_forms(false);
+ fake_form_fetcher()->Fetch();
+ std::unique_ptr<PasswordFormManager> form_manager =
+ base::MakeUnique<PasswordFormManager>(
+ password_manager(), client(), client()->driver(), *observed_form(),
+ base::MakeUnique<NiceMock<MockFormSaver>>(), fake_form_fetcher());
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
+ form_manager.reset();
+
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.QueryingSuppressedAccountsFinished", false, 1);
+ const auto sample_counts = histogram_tester.GetTotalCountsForPrefix(
+ "PasswordManager.SuppressedAccount.");
+ EXPECT_THAT(sample_counts, IsEmpty());
+}
+
+TEST_F(PasswordFormManagerTest, SuppressedFormsHistograms) {
+ static constexpr const struct {
+ SuppressedFormType type;
+ const char* expected_histogram_suffix;
+ void (FakeFormFetcher::*suppressed_forms_setter_func)(
+ const std::vector<const autofill::PasswordForm*>&);
+ } kSuppressedFormTypeParams[] = {
+ {SuppressedFormType::HTTPS, "HTTPSNotHTTP",
+ &FakeFormFetcher::set_suppressed_https_forms},
+ {SuppressedFormType::PSL_MATCH, "PSLMatching",
+ &FakeFormFetcher::set_suppressed_psl_matching_forms},
+ {SuppressedFormType::SAME_ORGANIZATION_NAME, "SameOrganizationName",
+ &FakeFormFetcher::set_suppressed_same_organization_name_forms}};
+
+ struct SuppressedFormData {
+ const char* username_value;
+ const char* password_value;
+ PasswordForm::Type manual_or_generated;
+ };
+
+ static constexpr const char kUsernameAlpha[] = "user-alpha@gmail.com";
+ static constexpr const char kPasswordAlpha[] = "password-alpha";
+ static constexpr const char kUsernameBeta[] = "user-beta@gmail.com";
+ static constexpr const char kPasswordBeta[] = "password-beta";
+
+ static constexpr const SuppressedFormData kSuppressedGeneratedForm = {
+ kUsernameAlpha, kPasswordAlpha, PasswordForm::TYPE_GENERATED};
+ static constexpr const SuppressedFormData kOtherSuppressedGeneratedForm = {
+ kUsernameBeta, kPasswordBeta, PasswordForm::TYPE_GENERATED};
+ static constexpr const SuppressedFormData kSuppressedManualForm = {
+ kUsernameAlpha, kPasswordBeta, PasswordForm::TYPE_MANUAL};
+
+ const std::vector<const SuppressedFormData*> kSuppressedFormsNone;
+ const std::vector<const SuppressedFormData*> kSuppressedFormsOneGenerated = {
+ &kSuppressedGeneratedForm};
+ const std::vector<const SuppressedFormData*> kSuppressedFormsTwoGenerated = {
+ &kSuppressedGeneratedForm, &kOtherSuppressedGeneratedForm};
+ const std::vector<const SuppressedFormData*> kSuppressedFormsOneManual = {
+ &kSuppressedManualForm};
+ const std::vector<const SuppressedFormData*> kSuppressedFormsTwoMixed = {
+ &kSuppressedGeneratedForm, &kSuppressedManualForm};
+
+ const struct {
+ std::vector<const SuppressedFormData*> simulated_suppressed_forms;
+ SimulatedManagerAction simulate_manager_action;
+ SimulatedSubmitResult simulate_submit_result;
+ const char* filled_username;
+ const char* filled_password;
+ int expected_histogram_sample_generated;
+ int expected_histogram_sample_manual;
+ const char* submitted_password; // nullptr if same as |filled_password|.
+ } kTestCases[] = {
+ // See PasswordManagerSuppressedAccountCrossActionsTaken in enums.xml.
+ //
+ // Legend: (SuppressAccountType, SubmitResult, SimulatedManagerAction,
+ // UserAction)
+ // 24 = (None, Passed, None, OverrideUsernameAndPassword)
+ {kSuppressedFormsNone, SimulatedManagerAction::NONE,
+ SimulatedSubmitResult::PASSED, kUsernameAlpha, kPasswordAlpha, 24, 24},
+ // 5 = (None, NotSubmitted, Autofilled, None)
+ {kSuppressedFormsNone, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::NONE, kUsernameAlpha, kPasswordAlpha, 5, 5},
+ // 15 = (None, Failed, Autofilled, None)
+ {kSuppressedFormsNone, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::FAILED, kUsernameAlpha, kPasswordAlpha, 15, 15},
+
+ // 35 = (Exists, NotSubmitted, Autofilled, None)
+ {kSuppressedFormsOneGenerated, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::NONE, kUsernameAlpha, kPasswordAlpha, 35, 5},
+ // 145 = (ExistsSameUsernameAndPassword, Passed, Autofilled, None)
+ // 25 = (None, Passed, Autofilled, None)
+ {kSuppressedFormsOneGenerated, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::PASSED, kUsernameAlpha, kPasswordAlpha, 145, 25},
+ // 104 = (ExistsSameUsername, Failed, None, OverrideUsernameAndPassword)
+ // 14 = (None, Failed, None, OverrideUsernameAndPassword)
+ {kSuppressedFormsOneGenerated, SimulatedManagerAction::NONE,
+ SimulatedSubmitResult::FAILED, kUsernameAlpha, kPasswordBeta, 104, 14},
+ // 84 = (ExistsDifferentUsername, Passed, None,
+ // OverrideUsernameAndPassword)
+ {kSuppressedFormsOneGenerated, SimulatedManagerAction::NONE,
+ SimulatedSubmitResult::PASSED, kUsernameBeta, kPasswordAlpha, 84, 24},
+
+ // 144 = (ExistsSameUsernameAndPassword, Passed, None,
+ // OverrideUsernameAndPassword)
+ {kSuppressedFormsOneManual, SimulatedManagerAction::NONE,
+ SimulatedSubmitResult::PASSED, kUsernameAlpha, kPasswordBeta, 24, 144},
+ {kSuppressedFormsTwoMixed, SimulatedManagerAction::NONE,
+ SimulatedSubmitResult::PASSED, kUsernameBeta, kPasswordAlpha, 84, 84},
+
+ // 115 = (ExistsSameUsername, Passed, Autofilled, None)
+ {kSuppressedFormsTwoGenerated, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::PASSED, kUsernameAlpha, kPasswordAlpha, 145, 25},
+ {kSuppressedFormsTwoGenerated, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::PASSED, kUsernameAlpha, kPasswordBeta, 115, 25},
+ {kSuppressedFormsTwoGenerated, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::PASSED, kUsernameBeta, kPasswordAlpha, 115, 25},
+ {kSuppressedFormsTwoGenerated, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::PASSED, kUsernameBeta, kPasswordBeta, 145, 25},
+
+ // 86 = (ExistsDifferentUsername, Passed, Autofilled, Choose)
+ // 26 = (None, Passed, Autofilled, Choose)
+ {kSuppressedFormsOneGenerated, SimulatedManagerAction::OFFERED,
+ SimulatedSubmitResult::PASSED, kUsernameBeta, kPasswordAlpha, 86, 26},
+ // 72 = (ExistsDifferentUsername, Failed, None, ChoosePSL)
+ // 12 = (None, Failed, None, ChoosePSL)
+ {kSuppressedFormsOneGenerated, SimulatedManagerAction::OFFERED_PSL,
+ SimulatedSubmitResult::FAILED, kUsernameBeta, kPasswordAlpha, 72, 12},
+ // 148 = (ExistsSameUsernameAndPassword, Passed, Autofilled,
+ // OverridePassword)
+ // 28 = (None, Passed, Autofilled, OverridePassword)
+ {kSuppressedFormsTwoGenerated, SimulatedManagerAction::AUTOFILLED,
+ SimulatedSubmitResult::PASSED, kUsernameBeta, kPasswordAlpha, 148, 28,
+ kPasswordBeta},
+ };
+
+ for (const auto& suppression_params : kSuppressedFormTypeParams) {
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(suppression_params.expected_histogram_suffix);
+ SCOPED_TRACE(test_case.expected_histogram_sample_manual);
+ SCOPED_TRACE(test_case.expected_histogram_sample_generated);
+
+ base::HistogramTester histogram_tester;
+
+ std::vector<PasswordForm> suppressed_forms;
+ for (const auto* form_data : test_case.simulated_suppressed_forms) {
+ suppressed_forms.push_back(CreateSuppressedForm(
+ suppression_params.type, form_data->username_value,
+ form_data->password_value, form_data->manual_or_generated));
+ }
+
+ std::vector<const PasswordForm*> suppressed_forms_ptrs;
+ for (const auto& form : suppressed_forms)
+ suppressed_forms_ptrs.push_back(&form);
+
+ FakeFormFetcher fetcher;
+ fetcher.set_did_complete_querying_suppressed_forms(true);
+
+ (&fetcher->*suppression_params.suppressed_forms_setter_func)(
+ suppressed_forms_ptrs);
+
+ SimulateActionsOnHTTPObservedForm(
+ &fetcher, test_case.simulate_manager_action,
+ test_case.simulate_submit_result, test_case.filled_username,
+ test_case.filled_password, test_case.submitted_password);
+
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.QueryingSuppressedAccountsFinished", true, 1);
+
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples(
+ "PasswordManager.SuppressedAccount.Generated." +
+ std::string(suppression_params.expected_histogram_suffix)),
+ ::testing::ElementsAre(
+ base::Bucket(test_case.expected_histogram_sample_generated, 1)));
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples(
+ "PasswordManager.SuppressedAccount.Manual." +
+ std::string(suppression_params.expected_histogram_suffix)),
+ ::testing::ElementsAre(
+ base::Bucket(test_case.expected_histogram_sample_manual, 1)));
+ }
+ }
+}
+
+// If the frame containing the login form is served over HTTPS, no histograms on
+// supressed HTTPS forms should be recorded. Everything else should still be.
+TEST_F(PasswordFormManagerTest, SuppressedHTTPSFormsHistogram_NotRecordedFor) {
+ base::HistogramTester histogram_tester;
+
+ PasswordForm https_observed_form = *observed_form();
+ https_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth");
+ https_observed_form.signon_realm = "https://accounts.google.com/";
+
+ // Only the scheme of the frame containing the login form maters, not the
+ // scheme of the main frame.
+ ASSERT_FALSE(client()->IsMainFrameSecure());
+
+ // Even if there were any suppressed HTTPS forms, they should be are ignored
+ // (but there should be none in production in this case).
+ FakeFormFetcher fetcher;
+ fetcher.set_suppressed_https_forms({saved_match()});
+ fetcher.set_did_complete_querying_suppressed_forms(true);
+ fetcher.Fetch();
+
+ std::unique_ptr<PasswordFormManager> form_manager =
+ base::MakeUnique<PasswordFormManager>(
+ password_manager(), client(), client()->driver(), https_observed_form,
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
+ form_manager.reset();
+
+ histogram_tester.ExpectUniqueSample(
+ "PasswordManager.QueryingSuppressedAccountsFinished", true, 1);
+ histogram_tester.ExpectTotalCount(
+ "PasswordManager.SuppressedAccount.Generated.HTTPSNotHTTP", 0);
+ histogram_tester.ExpectTotalCount(
+ "PasswordManager.SuppressedAccount.Manual.HTTPSNotHTTP", 0);
+ histogram_tester.ExpectTotalCount(
+ "PasswordManager.SuppressedAccount.Generated.PSLMatching", 1);
+ histogram_tester.ExpectTotalCount(
+ "PasswordManager.SuppressedAccount.Manual.PSLMatching", 1);
+ histogram_tester.ExpectTotalCount(
+ "PasswordManager.SuppressedAccount.Generated.SameOrganizationName", 1);
+ histogram_tester.ExpectTotalCount(
+ "PasswordManager.SuppressedAccount.Manual.SameOrganizationName", 1);
+}
+
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/password_manager.cc b/chromium/components/password_manager/core/browser/password_manager.cc
index dae64390d35..804aa5d4348 100644
--- a/chromium/components/password_manager/core/browser/password_manager.cc
+++ b/chromium/components/password_manager/core/browser/password_manager.cc
@@ -155,6 +155,8 @@ void PasswordManager::RegisterProfilePrefs(
prefs::kCredentialsEnableAutosignin, true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
registry->RegisterBooleanPref(prefs::kWasObsoleteHttpDataCleaned, false);
+ registry->RegisterStringPref(prefs::kSyncPasswordHash, std::string(),
+ PrefRegistry::NO_REGISTRATION_FLAGS);
#if defined(OS_MACOSX)
registry->RegisterIntegerPref(
prefs::kKeychainMigrationStatus,
@@ -375,6 +377,29 @@ void PasswordManager::ProvisionallySavePassword(
// post-submit navigation concludes, we compare the landing URL against the
// cached and report the difference through UMA.
main_frame_url_ = client_->GetMainFrameURL();
+
+ // Report SubmittedFormFrame metric.
+ if (driver) {
+ metrics_util::SubmittedFormFrame frame;
+ if (driver->IsMainFrame()) {
+ frame = metrics_util::SubmittedFormFrame::MAIN_FRAME;
+ } else if (form.origin == main_frame_url_) {
+ frame =
+ metrics_util::SubmittedFormFrame::IFRAME_WITH_SAME_URL_AS_MAIN_FRAME;
+ } else {
+ GURL::Replacements rep;
+ rep.SetPathStr("");
+ std::string main_frame_signon_realm =
+ main_frame_url_.ReplaceComponents(rep).spec();
+ frame =
+ (main_frame_signon_realm == form.signon_realm)
+ ? metrics_util::SubmittedFormFrame::
+ IFRAME_WITH_DIFFERENT_URL_SAME_SIGNON_REALM_AS_MAIN_FRAME
+ : metrics_util::SubmittedFormFrame::
+ IFRAME_WITH_DIFFERENT_SIGNON_REALM;
+ }
+ metrics_util::LogSubmittedFormFrame(frame);
+ }
}
void PasswordManager::UpdateFormManagers() {
@@ -712,6 +737,14 @@ void PasswordManager::OnLoginSuccessful() {
client_->GetStoreResultFilter()->ReportFormLoginSuccess(
*provisional_save_manager_);
+ if (provisional_save_manager_->submitted_form()) {
+ metrics_util::LogPasswordSuccessfulSubmissionIndicatorEvent(
+ provisional_save_manager_->submitted_form()->submission_event);
+ if (logger) {
+ logger->LogSuccessfulSubmissionIndicatorEvent(
+ provisional_save_manager_->submitted_form()->submission_event);
+ }
+ }
if (base::FeatureList::IsEnabled(features::kDropSyncCredential)) {
DCHECK(provisional_save_manager_->submitted_form());
diff --git a/chromium/components/password_manager/core/browser/password_manager_client.h b/chromium/components/password_manager/core/browser/password_manager_client.h
index 5e854e16db4..7004aee79ab 100644
--- a/chromium/components/password_manager/core/browser/password_manager_client.h
+++ b/chromium/components/password_manager/core/browser/password_manager_client.h
@@ -202,6 +202,16 @@ class PasswordManagerClient {
// Return the PasswordProtectionService associated with this instance.
virtual safe_browsing::PasswordProtectionService*
GetPasswordProtectionService() const = 0;
+
+ // Checks the safe browsing reputation of the webpage where the focused
+ // username/password field is on.
+ virtual void CheckSafeBrowsingReputation(const GURL& form_action,
+ const GURL& frame_url) = 0;
+
+ // Checks the safe browsing reputation of the webpage where password reuse
+ // happens.
+ virtual void CheckProtectedPasswordEntry(
+ const std::string& password_saved_domain) = 0;
#endif
private:
diff --git a/chromium/components/password_manager/core/browser/password_manager_driver.h b/chromium/components/password_manager/core/browser/password_manager_driver.h
index 028bf7273ac..af6551c4256 100644
--- a/chromium/components/password_manager/core/browser/password_manager_driver.h
+++ b/chromium/components/password_manager/core/browser/password_manager_driver.h
@@ -101,6 +101,9 @@ class PasswordManagerDriver
// Return the associated AutofillDriver.
virtual autofill::AutofillDriver* GetAutofillDriver() = 0;
+ // Return true iff the driver corresponds to the main frame.
+ virtual bool IsMainFrame() const = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(PasswordManagerDriver);
};
diff --git a/chromium/components/password_manager/core/browser/password_manager_metrics_util.cc b/chromium/components/password_manager/core/browser/password_manager_metrics_util.cc
index 642f0308eda..a7bc2fe54a5 100644
--- a/chromium/components/password_manager/core/browser/password_manager_metrics_util.cc
+++ b/chromium/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -132,14 +132,18 @@ void LogAccountChooserUsability(AccountChooserUsabilityMetric usability,
}
void LogCredentialManagerGetResult(CredentialManagerGetResult result,
- CredentialManagerGetMediation status) {
- switch (status) {
- case CREDENTIAL_MANAGER_GET_UNMEDIATED:
- UMA_HISTOGRAM_ENUMERATION("PasswordManager.GetUnmediated", result,
+ CredentialMediationRequirement mediation) {
+ switch (mediation) {
+ case CredentialMediationRequirement::kSilent:
+ UMA_HISTOGRAM_ENUMERATION("PasswordManager.MediationSilent", result,
CREDENTIAL_MANAGER_GET_COUNT);
break;
- case CREDENTIAL_MANAGER_GET_MEDIATED:
- UMA_HISTOGRAM_ENUMERATION("PasswordManager.GetMediated", result,
+ case CredentialMediationRequirement::kOptional:
+ UMA_HISTOGRAM_ENUMERATION("PasswordManager.MediationOptional", result,
+ CREDENTIAL_MANAGER_GET_COUNT);
+ break;
+ case CredentialMediationRequirement::kRequired:
+ UMA_HISTOGRAM_ENUMERATION("PasswordManager.MediationRequired", result,
CREDENTIAL_MANAGER_GET_COUNT);
break;
}
@@ -174,6 +178,27 @@ void LogShowedFormNotSecureWarningOnCurrentNavigation() {
"PasswordManager.ShowedFormNotSecureWarningOnCurrentNavigation", true);
}
+void LogPasswordSuccessfulSubmissionIndicatorEvent(
+ autofill::PasswordForm::SubmissionIndicatorEvent event) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.SuccessfulSubmissionIndicatorEvent", event,
+ autofill::PasswordForm::SubmissionIndicatorEvent::
+ SUBMISSION_INDICATOR_EVENT_COUNT);
+}
+
+void LogPasswordAcceptedSaveUpdateSubmissionIndicatorEvent(
+ autofill::PasswordForm::SubmissionIndicatorEvent event) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "PasswordManager.AcceptedSaveUpdateSubmissionIndicatorEvent", event,
+ autofill::PasswordForm::SubmissionIndicatorEvent::
+ SUBMISSION_INDICATOR_EVENT_COUNT);
+}
+
+void LogSubmittedFormFrame(SubmittedFormFrame frame) {
+ UMA_HISTOGRAM_ENUMERATION("PasswordManager.SubmittedFormFrame", frame,
+ SubmittedFormFrame::SUBMITTED_FORM_FRAME_COUNT);
+}
+
} // namespace metrics_util
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/password_manager_metrics_util.h b/chromium/components/password_manager/core/browser/password_manager_metrics_util.h
index 2fb1b731404..203be60f70d 100644
--- a/chromium/components/password_manager/core/browser/password_manager_metrics_util.h
+++ b/chromium/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -9,6 +9,9 @@
#include <string>
+#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/common/credential_manager_types.h"
+
namespace password_manager {
namespace metrics_util {
@@ -168,11 +171,6 @@ enum CredentialManagerGetResult {
CREDENTIAL_MANAGER_GET_COUNT
};
-enum CredentialManagerGetMediation {
- CREDENTIAL_MANAGER_GET_MEDIATED,
- CREDENTIAL_MANAGER_GET_UNMEDIATED
-};
-
// Metrics: "PasswordManager.HttpPasswordMigrationMode"
enum HttpPasswordMigrationMode {
HTTP_PASSWORD_MIGRATION_MODE_MOVE,
@@ -186,6 +184,15 @@ enum PasswordReusePasswordFieldDetected {
PASSWORD_REUSE_PASSWORD_FIELD_DETECTED_COUNT
};
+// Recorded into a UMA histogram, so order of enumerators should not be changed.
+enum class SubmittedFormFrame {
+ MAIN_FRAME,
+ IFRAME_WITH_SAME_URL_AS_MAIN_FRAME,
+ IFRAME_WITH_DIFFERENT_URL_SAME_SIGNON_REALM_AS_MAIN_FRAME,
+ IFRAME_WITH_DIFFERENT_SIGNON_REALM,
+ SUBMITTED_FORM_FRAME_COUNT
+};
+
// A version of the UMA_HISTOGRAM_BOOLEAN macro that allows the |name|
// to vary over the program's runtime.
void LogUMAHistogramBoolean(const std::string& name, bool sample);
@@ -245,10 +252,9 @@ void LogAccountChooserUsability(AccountChooserUsabilityMetric usability,
int count_empty_icons,
int count_accounts);
-// Log the result of navigator.credentials.get. |status| specifies the
-// "unmediated" parameter of the API method.
+// Log the result of navigator.credentials.get.
void LogCredentialManagerGetResult(CredentialManagerGetResult result,
- CredentialManagerGetMediation status);
+ CredentialMediationRequirement mediation);
// Log the password reuse.
void LogPasswordReuse(int password_length,
@@ -264,6 +270,18 @@ void LogShowedHttpNotSecureExplanation();
// per main-frame navigation.
void LogShowedFormNotSecureWarningOnCurrentNavigation();
+// Log a password successful submission event.
+void LogPasswordSuccessfulSubmissionIndicatorEvent(
+ autofill::PasswordForm::SubmissionIndicatorEvent event);
+
+// Log a password successful submission event for accepted by user password save
+// or update.
+void LogPasswordAcceptedSaveUpdateSubmissionIndicatorEvent(
+ autofill::PasswordForm::SubmissionIndicatorEvent event);
+
+// Log a frame of a submitted password form.
+void LogSubmittedFormFrame(SubmittedFormFrame frame);
+
} // namespace metrics_util
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/password_manager_test_utils.h b/chromium/components/password_manager/core/browser/password_manager_test_utils.h
index 1958745a632..893c75f7137 100644
--- a/chromium/components/password_manager/core/browser/password_manager_test_utils.h
+++ b/chromium/components/password_manager/core/browser/password_manager_test_utils.h
@@ -27,7 +27,7 @@ namespace password_manager {
template <class Context, class Store>
scoped_refptr<RefcountedKeyedService> BuildPasswordStore(Context* context) {
scoped_refptr<password_manager::PasswordStore> store(new Store);
- if (!store->Init(syncer::SyncableService::StartSyncFlare()))
+ if (!store->Init(syncer::SyncableService::StartSyncFlare(), nullptr))
return nullptr;
return store;
}
diff --git a/chromium/components/password_manager/core/browser/password_manager_unittest.cc b/chromium/components/password_manager/core/browser/password_manager_unittest.cc
index 668303a45f5..d0895e8c8b5 100644
--- a/chromium/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_manager_unittest.cc
@@ -119,7 +119,9 @@ class PasswordManagerTest : public testing::Test {
void SetUp() override {
store_ = new testing::StrictMock<MockPasswordStore>;
EXPECT_CALL(*store_, ReportMetrics(_, _)).Times(AnyNumber());
- CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
+ EXPECT_CALL(*store_, GetLoginsForSameOrganizationName(_, _))
+ .Times(AnyNumber());
+ CHECK(store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr));
EXPECT_CALL(client_, GetPasswordStore())
.WillRepeatedly(Return(store_.get()));
@@ -1404,10 +1406,12 @@ TEST_F(PasswordManagerTest, PasswordGenerationPresavePasswordAndLogin) {
if (found_matched_logins_in_store) {
EXPECT_CALL(*store_, GetLogins(_, _))
.WillRepeatedly(WithArg<1>(InvokeConsumer(form)));
+ EXPECT_CALL(*store_, GetLoginsForSameOrganizationName(_, _));
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(2);
} else {
EXPECT_CALL(*store_, GetLogins(_, _))
.WillRepeatedly(WithArg<1>(InvokeEmptyConsumerWithForms()));
+ EXPECT_CALL(*store_, GetLoginsForSameOrganizationName(_, _));
}
std::unique_ptr<PasswordFormManager> form_manager;
if (found_matched_logins_in_store) {
diff --git a/chromium/components/password_manager/core/browser/password_manager_util.cc b/chromium/components/password_manager/core/browser/password_manager_util.cc
index d8d4eb65b9c..d104a6b7cdc 100644
--- a/chromium/components/password_manager/core/browser/password_manager_util.cc
+++ b/chromium/components/password_manager/core/browser/password_manager_util.cc
@@ -11,6 +11,7 @@
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/log_manager.h"
#include "components/sync/driver/sync_service.h"
+#include "crypto/sha2.h"
namespace password_manager_util {
@@ -83,4 +84,18 @@ bool IsLoggingActive(const password_manager::PasswordManagerClient* client) {
return log_manager && log_manager->IsLoggingActive();
}
+uint64_t Calculate37BitsOfSHA256Hash(const base::StringPiece16& text) {
+ constexpr size_t kBytesFromSha256Hash = 5;
+ uint8_t hash[kBytesFromSha256Hash];
+ base::StringPiece text_8bits(reinterpret_cast<const char*>(text.data()),
+ text.size() * 2);
+ crypto::SHA256HashString(text_8bits, hash, kBytesFromSha256Hash);
+ uint64_t hash37 = ((static_cast<uint64_t>(hash[0]))) |
+ ((static_cast<uint64_t>(hash[1])) << 8) |
+ ((static_cast<uint64_t>(hash[2])) << 16) |
+ ((static_cast<uint64_t>(hash[3])) << 24) |
+ (((static_cast<uint64_t>(hash[4])) & 0x1F) << 32);
+ return hash37;
+}
+
} // namespace password_manager_util
diff --git a/chromium/components/password_manager/core/browser/password_manager_util.h b/chromium/components/password_manager/core/browser/password_manager_util.h
index 68fc65b47a1..65a0c09762c 100644
--- a/chromium/components/password_manager/core/browser/password_manager_util.h
+++ b/chromium/components/password_manager/core/browser/password_manager_util.h
@@ -49,6 +49,9 @@ void TrimUsernameOnlyCredentials(
// and required to always return non-null.
bool IsLoggingActive(const password_manager::PasswordManagerClient* client);
+// Returns 37 bits from Sha256 hash.
+uint64_t Calculate37BitsOfSHA256Hash(const base::StringPiece16& text);
+
} // namespace password_manager_util
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_UTIL_H_
diff --git a/chromium/components/password_manager/core/browser/password_manager_util_unittest.cc b/chromium/components/password_manager/core/browser/password_manager_util_unittest.cc
index de4cffb10bf..3cc9fe20d6d 100644
--- a/chromium/components/password_manager/core/browser/password_manager_util_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -4,6 +4,7 @@
#include "components/password_manager/core/browser/password_manager_util.h"
+#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
@@ -56,3 +57,19 @@ TEST(PasswordManagerUtil, TrimUsernameOnlyCredentials) {
EXPECT_THAT(forms, UnorderedPasswordFormElementsAre(&expected_forms));
}
+
+TEST(PasswordManagerUtil, Calculate37BitsOfSHA256Hash) {
+ const char* kInputData[] = {"", "password", "secret"};
+
+ const uint64_t kExpectedResult[] = {
+ UINT64_C(0x1842c4b0e3), UINT64_C(0x55d0601e2), UINT64_C(0x8b9dea8b3)};
+
+ ASSERT_EQ(arraysize(kInputData), arraysize(kExpectedResult));
+
+ for (size_t i = 0; i < arraysize(kInputData); ++i) {
+ base::string16 input = base::UTF8ToUTF16(kInputData[i]);
+
+ EXPECT_EQ(kExpectedResult[i],
+ password_manager_util::Calculate37BitsOfSHA256Hash(input));
+ }
+}
diff --git a/chromium/components/password_manager/core/browser/password_reuse_detection_manager.cc b/chromium/components/password_manager/core/browser/password_reuse_detection_manager.cc
index ab55375398f..f549345cfcf 100644
--- a/chromium/components/password_manager/core/browser/password_reuse_detection_manager.cc
+++ b/chromium/components/password_manager/core/browser/password_reuse_detection_manager.cc
@@ -49,7 +49,7 @@ void PasswordReuseDetectionManager::OnKeyPressed(const base::string16& text) {
void PasswordReuseDetectionManager::OnReuseFound(
const base::string16& password,
- const std::string& saved_domain,
+ const std::string& legitimate_domain,
int saved_passwords,
int number_matches) {
std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
@@ -57,7 +57,7 @@ void PasswordReuseDetectionManager::OnReuseFound(
logger.reset(
new BrowserSavePasswordProgressLogger(client_->GetLogManager()));
logger->LogString(BrowserSavePasswordProgressLogger::STRING_REUSE_FOUND,
- saved_domain);
+ legitimate_domain);
}
metrics_util::LogPasswordReuse(
@@ -66,9 +66,7 @@ void PasswordReuseDetectionManager::OnReuseFound(
#if defined(SAFE_BROWSING_DB_LOCAL)
// TODO(jialiul): After CSD whitelist being added to Android, we should gate
// this by either SAFE_BROWSING_DB_LOCAL or SAFE_BROWSING_DB_REMOTE.
- safe_browsing::PasswordProtectionService* password_protection_service =
- client_->GetPasswordProtectionService();
- password_protection_service->RecordPasswordReuse(main_frame_url_);
+ client_->CheckProtectedPasswordEntry(legitimate_domain);
#endif
}
diff --git a/chromium/components/password_manager/core/browser/password_reuse_detection_manager.h b/chromium/components/password_manager/core/browser/password_reuse_detection_manager.h
index 9235fa5ab0d..9aba12ba0e9 100644
--- a/chromium/components/password_manager/core/browser/password_reuse_detection_manager.h
+++ b/chromium/components/password_manager/core/browser/password_reuse_detection_manager.h
@@ -26,7 +26,7 @@ class PasswordReuseDetectionManager : public PasswordReuseDetectorConsumer {
// PasswordReuseDetectorConsumer
void OnReuseFound(const base::string16& password,
- const std::string& saved_domain,
+ const std::string& legitimate_domain,
int saved_passwords,
int number_matches) override;
diff --git a/chromium/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc b/chromium/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc
index 3dadcc79450..d166a5b6a85 100644
--- a/chromium/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_reuse_detection_manager_unittest.cc
@@ -39,7 +39,7 @@ class PasswordReuseDetectionManagerTest : public ::testing::Test {
PasswordReuseDetectionManagerTest() {}
void SetUp() override {
store_ = new testing::StrictMock<MockPasswordStore>;
- CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
+ CHECK(store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr));
}
void TearDown() override {
store_->ShutdownOnUIThread();
diff --git a/chromium/components/password_manager/core/browser/password_reuse_detector.cc b/chromium/components/password_manager/core/browser/password_reuse_detector.cc
index dd9b2a94a5a..a06e94eb183 100644
--- a/chromium/components/password_manager/core/browser/password_reuse_detector.cc
+++ b/chromium/components/password_manager/core/browser/password_reuse_detector.cc
@@ -7,8 +7,16 @@
#include <algorithm>
#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/browser/password_manager_util.h"
#include "components/password_manager/core/browser/password_reuse_detector_consumer.h"
#include "components/password_manager/core/browser/psl_matching_helper.h"
+#include "components/password_manager/core/common/password_manager_pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "google_apis/gaia/gaia_auth_util.h"
+#include "google_apis/gaia/gaia_urls.h"
+#include "url/origin.h"
+
+using url::Origin;
namespace password_manager {
@@ -35,7 +43,8 @@ bool ReverseStringLess::operator()(const base::string16& lhs,
rhs.rend());
}
-PasswordReuseDetector::PasswordReuseDetector() {}
+PasswordReuseDetector::PasswordReuseDetector(PrefService* prefs)
+ : prefs_(prefs) {}
PasswordReuseDetector::~PasswordReuseDetector() {}
@@ -62,20 +71,69 @@ void PasswordReuseDetector::CheckReuse(
if (input.size() < kMinPasswordLengthToCheck)
return;
+ if (CheckSyncPasswordReuse(input, domain, consumer))
+ return;
+
+ if (CheckSavedPasswordReuse(input, domain, consumer))
+ return;
+}
+
+bool PasswordReuseDetector::CheckSyncPasswordReuse(
+ const base::string16& input,
+ const std::string& domain,
+ PasswordReuseDetectorConsumer* consumer) {
+ if (!sync_password_hash_.has_value())
+ return false;
+
+ const Origin gaia_origin(GaiaUrls::GetInstance()->gaia_url().GetOrigin());
+ if (Origin(GURL(domain)).IsSameOriginWith(gaia_origin))
+ return false;
+
+ // Check that some suffix of |input| has the same hash as the sync password.
+ for (size_t i = 0; i + kMinPasswordLengthToCheck <= input.size(); ++i) {
+ base::StringPiece16 input_suffix(input.c_str() + i, input.size() - i);
+ if (password_manager_util::Calculate37BitsOfSHA256Hash(input_suffix) ==
+ sync_password_hash_.value()) {
+ consumer->OnReuseFound(input_suffix.as_string(), gaia_origin.host(), 1,
+ 0);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool PasswordReuseDetector::CheckSavedPasswordReuse(
+ const base::string16& input,
+ const std::string& domain,
+ PasswordReuseDetectorConsumer* consumer) {
const std::string registry_controlled_domain =
GetRegistryControlledDomain(GURL(domain));
auto passwords_iterator = FindSavedPassword(input);
if (passwords_iterator == passwords_.end())
- return;
+ return false;
const std::set<std::string>& domains = passwords_iterator->second;
DCHECK(!domains.empty());
if (domains.find(registry_controlled_domain) == domains.end()) {
// Return only one domain.
- const std::string& saved_domain = *domains.begin();
- consumer->OnReuseFound(passwords_iterator->first, saved_domain,
+ const std::string& legitimate_domain = *domains.begin();
+ consumer->OnReuseFound(passwords_iterator->first, legitimate_domain,
saved_passwords_, domains.size());
- return;
+ return true;
+ }
+
+ return false;
+}
+
+void PasswordReuseDetector::SaveSyncPasswordHash(
+ const base::string16& password) {
+ sync_password_hash_ =
+ password_manager_util::Calculate37BitsOfSHA256Hash(password);
+ if (prefs_) {
+ // TODO(crbug.com/657041) Implement encrypting and saving of
+ // |sync_password_hash_| into preference kSyncPasswordHash.
+ prefs_->SetString(prefs::kSyncPasswordHash, std::string());
}
}
diff --git a/chromium/components/password_manager/core/browser/password_reuse_detector.h b/chromium/components/password_manager/core/browser/password_reuse_detector.h
index 967c941a9cd..d42f3137c77 100644
--- a/chromium/components/password_manager/core/browser/password_reuse_detector.h
+++ b/chromium/components/password_manager/core/browser/password_reuse_detector.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_REUSE_DETECTOR_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_REUSE_DETECTOR_H_
+#include <stdint.h>
#include <map>
#include <memory>
#include <set>
@@ -12,10 +13,13 @@
#include <vector>
#include "base/macros.h"
+#include "base/optional.h"
#include "base/strings/string16.h"
#include "components/password_manager/core/browser/password_store_change.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
+class PrefService;
+
namespace password_manager {
class PasswordReuseDetectorConsumer;
@@ -32,7 +36,7 @@ struct ReverseStringLess {
// a password reuse.
class PasswordReuseDetector : public PasswordStoreConsumer {
public:
- PasswordReuseDetector();
+ explicit PasswordReuseDetector(PrefService* prefs);
~PasswordReuseDetector() override;
// PasswordStoreConsumer
@@ -43,7 +47,7 @@ class PasswordReuseDetector : public PasswordStoreConsumer {
void OnLoginsChanged(const PasswordStoreChangeList& changes);
// Checks that some suffix of |input| equals to a password saved on another
- // registry controlled domain than |domain|.
+ // registry controlled domain than |domain| or to a sync password.
// If such suffix is found, |consumer|->OnReuseFound() is called on the same
// thread on which this method is called.
// |consumer| should not be null.
@@ -51,6 +55,9 @@ class PasswordReuseDetector : public PasswordStoreConsumer {
const std::string& domain,
PasswordReuseDetectorConsumer* consumer);
+ // Saves a hash of |password| for password reuse checking.
+ void SaveSyncPasswordHash(const base::string16& password);
+
private:
using passwords_iterator = std::map<base::string16,
std::set<std::string>,
@@ -59,6 +66,18 @@ class PasswordReuseDetector : public PasswordStoreConsumer {
// Add password from |form| to |passwords_|.
void AddPassword(const autofill::PasswordForm& form);
+ // Returns true iff a reuse of a sync password is found. If reuse is found it
+ // is reported to |consumer|.
+ bool CheckSyncPasswordReuse(const base::string16& input,
+ const std::string& domain,
+ PasswordReuseDetectorConsumer* consumer);
+
+ // Returns true iff a reuse of a saved password is found. If reuse is found it
+ // is reported to |consumer|.
+ bool CheckSavedPasswordReuse(const base::string16& input,
+ const std::string& domain,
+ PasswordReuseDetectorConsumer* consumer);
+
// Returns the iterator to |passwords_| that corresponds to the longest key in
// |passwords_| that is a suffix of |input|. Returns passwords_.end() in case
// when no key in |passwords_| is a prefix of |input|.
@@ -74,6 +93,9 @@ class PasswordReuseDetector : public PasswordStoreConsumer {
// of times how many different sites it's saved on.
int saved_passwords_ = 0;
+ base::Optional<uint64_t> sync_password_hash_;
+ PrefService* const prefs_;
+
DISALLOW_COPY_AND_ASSIGN(PasswordReuseDetector);
};
diff --git a/chromium/components/password_manager/core/browser/password_reuse_detector_consumer.h b/chromium/components/password_manager/core/browser/password_reuse_detector_consumer.h
index 254f29f79d9..b621b777e4f 100644
--- a/chromium/components/password_manager/core/browser/password_reuse_detector_consumer.h
+++ b/chromium/components/password_manager/core/browser/password_reuse_detector_consumer.h
@@ -21,11 +21,12 @@ class PasswordReuseDetectorConsumer
virtual ~PasswordReuseDetectorConsumer();
// Called when a password reuse is found.
- // |saved_domain| is the domain on which |password| is saved.
+ // |legitimate_domain| is the domain on which |password| is saved or the sync
+ // domain if |password| is a sync password.
// |saved_passwords| is total number of passwords stored in Password Manager.
// |number_matches| is a number of sites on which |password| is saved.
virtual void OnReuseFound(const base::string16& password,
- const std::string& saved_domain,
+ const std::string& legitimate_domain,
int saved_passwords,
int number_matches) = 0;
};
diff --git a/chromium/components/password_manager/core/browser/password_reuse_detector_unittest.cc b/chromium/components/password_manager/core/browser/password_reuse_detector_unittest.cc
index dac4dd694cb..94d2fa82665 100644
--- a/chromium/components/password_manager/core/browser/password_reuse_detector_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_reuse_detector_unittest.cc
@@ -11,6 +11,9 @@
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
+#include "components/password_manager/core/common/password_manager_pref_names.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -60,7 +63,7 @@ PasswordStoreChangeList GetChangeList(
}
TEST(PasswordReuseDetectorTest, TypingPasswordOnDifferentSite) {
- PasswordReuseDetector reuse_detector;
+ PasswordReuseDetector reuse_detector(nullptr);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer;
@@ -91,7 +94,7 @@ TEST(PasswordReuseDetectorTest, TypingPasswordOnDifferentSite) {
}
TEST(PasswordReuseDetectorTest, PSLMatchNoReuseEvent) {
- PasswordReuseDetector reuse_detector;
+ PasswordReuseDetector reuse_detector(nullptr);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer;
@@ -101,7 +104,7 @@ TEST(PasswordReuseDetectorTest, PSLMatchNoReuseEvent) {
}
TEST(PasswordReuseDetectorTest, NoPSLMatchReuseEvent) {
- PasswordReuseDetector reuse_detector;
+ PasswordReuseDetector reuse_detector(nullptr);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer;
@@ -114,7 +117,7 @@ TEST(PasswordReuseDetectorTest, NoPSLMatchReuseEvent) {
}
TEST(PasswordReuseDetectorTest, TooShortPasswordNoReuseEvent) {
- PasswordReuseDetector reuse_detector;
+ PasswordReuseDetector reuse_detector(nullptr);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer;
@@ -123,7 +126,7 @@ TEST(PasswordReuseDetectorTest, TooShortPasswordNoReuseEvent) {
}
TEST(PasswordReuseDetectorTest, PasswordNotInputSuffixNoReuseEvent) {
- PasswordReuseDetector reuse_detector;
+ PasswordReuseDetector reuse_detector(nullptr);
reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
MockPasswordReuseDetectorConsumer mockConsumer;
@@ -138,7 +141,7 @@ TEST(PasswordReuseDetectorTest, OnLoginsChanged) {
for (PasswordStoreChange::Type type :
{PasswordStoreChange::ADD, PasswordStoreChange::UPDATE,
PasswordStoreChange::REMOVE}) {
- PasswordReuseDetector reuse_detector;
+ PasswordReuseDetector reuse_detector(nullptr);
PasswordStoreChangeList changes =
GetChangeList(type, GetForms(GetTestDomainsPasswords()));
reuse_detector.OnLoginsChanged(changes);
@@ -162,7 +165,7 @@ TEST(PasswordReuseDetectorTest, CheckLongestPasswordMatchReturn) {
{"https://example3.com", "1234567890"},
};
- PasswordReuseDetector reuse_detector;
+ PasswordReuseDetector reuse_detector(nullptr);
reuse_detector.OnGetPasswordStoreResults(GetForms(domain_passwords));
MockPasswordReuseDetectorConsumer mockConsumer;
@@ -184,6 +187,59 @@ TEST(PasswordReuseDetectorTest, CheckLongestPasswordMatchReturn) {
&mockConsumer);
}
+TEST(PasswordReuseDetectorTest, SyncPasswordNoReuse) {
+ PasswordReuseDetector reuse_detector(nullptr);
+ reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
+ MockPasswordReuseDetectorConsumer mockConsumer;
+
+ reuse_detector.SaveSyncPasswordHash(ASCIIToUTF16("sync_password"));
+
+ EXPECT_CALL(mockConsumer, OnReuseFound(_, _, _, _)).Times(0);
+ reuse_detector.CheckReuse(ASCIIToUTF16("sync_password"),
+ "https://accounts.google.com", &mockConsumer);
+ // Only suffixes are verifed.
+ reuse_detector.CheckReuse(ASCIIToUTF16("sync_password123"),
+ "https://evil.com", &mockConsumer);
+}
+
+TEST(PasswordReuseDetectorTest, SyncPasswordReuseFound) {
+ PasswordReuseDetector reuse_detector(nullptr);
+ reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
+ MockPasswordReuseDetectorConsumer mockConsumer;
+
+ reuse_detector.SaveSyncPasswordHash(ASCIIToUTF16("sync_password"));
+
+ EXPECT_CALL(mockConsumer, OnReuseFound(ASCIIToUTF16("sync_password"),
+ "accounts.google.com", 1, 0));
+ reuse_detector.CheckReuse(ASCIIToUTF16("sync_password"), "https://evil.com",
+ &mockConsumer);
+}
+
+TEST(PasswordReuseDetectorTest, SavedPasswordsReuseSyncPasswordAvailable) {
+ // Check that reuse of saved passwords is detected also if the sync password
+ // hash is saved.
+ PasswordReuseDetector reuse_detector(nullptr);
+ reuse_detector.OnGetPasswordStoreResults(GetForms(GetTestDomainsPasswords()));
+ MockPasswordReuseDetectorConsumer mockConsumer;
+
+ reuse_detector.SaveSyncPasswordHash(ASCIIToUTF16("sync_password"));
+
+ EXPECT_CALL(mockConsumer,
+ OnReuseFound(ASCIIToUTF16("password"), "google.com", 5, 1));
+ reuse_detector.CheckReuse(ASCIIToUTF16("password"), "https://evil.com",
+ &mockConsumer);
+}
+
+TEST(PasswordReuseDetectorTest, CheckThatSyncPasswordIsStoredIntoPreferences) {
+ TestingPrefServiceSimple prefs;
+ prefs.registry()->RegisterStringPref(prefs::kSyncPasswordHash, std::string(),
+ PrefRegistry::NO_REGISTRATION_FLAGS);
+ ASSERT_FALSE(prefs.HasPrefPath(prefs::kSyncPasswordHash));
+ PasswordReuseDetector reuse_detector(&prefs);
+ reuse_detector.SaveSyncPasswordHash(ASCIIToUTF16("sync_password"));
+ EXPECT_TRUE(prefs.HasPrefPath(prefs::kSyncPasswordHash));
+}
+
} // namespace
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/password_store.cc b/chromium/components/password_manager/core/browser/password_store.cc
index 3597674b5ba..0575e5de99a 100644
--- a/chromium/components/password_manager/core/browser/password_store.cc
+++ b/chromium/components/password_manager/core/browser/password_store.cc
@@ -67,13 +67,13 @@ PasswordStore::CheckReuseRequest::~CheckReuseRequest() {}
void PasswordStore::CheckReuseRequest::OnReuseFound(
const base::string16& password,
- const std::string& saved_domain,
+ const std::string& legitimate_domain,
int saved_passwords,
int number_matches) {
origin_task_runner_->PostTask(
FROM_HERE,
base::Bind(&PasswordReuseDetectorConsumer::OnReuseFound, consumer_weak_,
- password, saved_domain, saved_passwords, number_matches));
+ password, legitimate_domain, saved_passwords, number_matches));
}
#endif
@@ -111,8 +111,10 @@ PasswordStore::PasswordStore(
is_propagating_password_changes_to_web_credentials_enabled_(false),
shutdown_called_(false) {}
-bool PasswordStore::Init(const syncer::SyncableService::StartSyncFlare& flare) {
- ScheduleTask(base::Bind(&PasswordStore::InitOnBackgroundThread, this, flare));
+bool PasswordStore::Init(const syncer::SyncableService::StartSyncFlare& flare,
+ PrefService* prefs) {
+ ScheduleTask(
+ base::Bind(&PasswordStore::InitOnBackgroundThread, this, flare, prefs));
return true;
}
@@ -223,6 +225,14 @@ void PasswordStore::GetLogins(const FormDigest& form,
}
}
+void PasswordStore::GetLoginsForSameOrganizationName(
+ const std::string& signon_realm,
+ PasswordStoreConsumer* consumer) {
+ std::unique_ptr<GetLoginsRequest> request(new GetLoginsRequest(consumer));
+ ScheduleTask(base::Bind(&PasswordStore::GetLoginsForSameOrganizationNameImpl,
+ this, signon_realm, base::Passed(&request)));
+}
+
void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) {
Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer);
}
@@ -317,6 +327,11 @@ void PasswordStore::CheckReuse(const base::string16& input,
ScheduleTask(base::Bind(&PasswordStore::CheckReuseImpl, this,
base::Passed(&check_reuse_request), input, domain));
}
+
+void PasswordStore::SaveSyncPasswordHash(const base::string16& password) {
+ ScheduleTask(
+ base::Bind(&PasswordStore::SaveSyncPasswordHashImpl, this, password));
+}
#endif
PasswordStore::~PasswordStore() {
@@ -399,6 +414,11 @@ void PasswordStore::CheckReuseImpl(std::unique_ptr<CheckReuseRequest> request,
if (reuse_detector_)
reuse_detector_->CheckReuse(input, domain, request.get());
}
+
+void PasswordStore::SaveSyncPasswordHashImpl(const base::string16& password) {
+ if (reuse_detector_)
+ reuse_detector_->SaveSyncPasswordHash(password);
+}
#endif
void PasswordStore::Schedule(
@@ -487,6 +507,13 @@ void PasswordStore::DisableAutoSignInForOriginsInternal(
main_thread_runner_->PostTask(FROM_HERE, completion);
}
+void PasswordStore::GetLoginsForSameOrganizationNameImpl(
+ const std::string& signon_realm,
+ std::unique_ptr<GetLoginsRequest> request) {
+ request->NotifyConsumerWithResults(
+ FillLoginsForSameOrganizationName(signon_realm));
+}
+
void PasswordStore::GetAutofillableLoginsImpl(
std::unique_ptr<GetLoginsRequest> request) {
std::vector<std::unique_ptr<PasswordForm>> obtained_forms;
@@ -708,14 +735,15 @@ void PasswordStore::ScheduleUpdateAffiliatedWebLoginsImpl(
}
void PasswordStore::InitOnBackgroundThread(
- const syncer::SyncableService::StartSyncFlare& flare) {
+ const syncer::SyncableService::StartSyncFlare& flare,
+ PrefService* prefs) {
DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
DCHECK(!syncable_service_);
syncable_service_.reset(new PasswordSyncableService(this));
syncable_service_->InjectStartSyncFlare(flare);
// TODO(crbug.com/706392): Fix password reuse detection for Android.
#if !defined(OS_ANDROID) && !defined(OS_IOS)
- reuse_detector_.reset(new PasswordReuseDetector);
+ reuse_detector_ = base::MakeUnique<PasswordReuseDetector>(prefs);
GetAutofillableLoginsImpl(
base::MakeUnique<GetLoginsRequest>(reuse_detector_.get()));
#endif
diff --git a/chromium/components/password_manager/core/browser/password_store.h b/chromium/components/password_manager/core/browser/password_store.h
index 0a0b915bbef..6c2f104e326 100644
--- a/chromium/components/password_manager/core/browser/password_store.h
+++ b/chromium/components/password_manager/core/browser/password_store.h
@@ -28,6 +28,7 @@
#endif
class PasswordStoreProxyMac;
+class PrefService;
namespace autofill {
struct PasswordForm;
@@ -92,7 +93,8 @@ class PasswordStore : protected PasswordStoreSync,
scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner);
// Reimplement this to add custom initialization. Always call this too.
- virtual bool Init(const syncer::SyncableService::StartSyncFlare& flare);
+ virtual bool Init(const syncer::SyncableService::StartSyncFlare& flare,
+ PrefService* prefs);
// RefcountedKeyedService:
void ShutdownOnUIThread() override;
@@ -180,6 +182,21 @@ class PasswordStore : protected PasswordStoreSync,
virtual void GetLogins(const FormDigest& form,
PasswordStoreConsumer* consumer);
+ // Returns all stored credentials with SCHEME_HTTP that have a realm whose
+ // organization-identifying name -- that is, the first domain name label below
+ // the effective TLD -- matches that of |signon_realm|. Notifies |consumer| on
+ // completion. The request will be cancelled if the consumer is destroyed.
+ //
+ // WARNING: This is *NOT* PSL (Public Suffix List) matching. The logins
+ // returned by this method are not safe to be filled into the observed form.
+ //
+ // For example, the organization-identifying name of "https://foo.example.org"
+ // is `example`, and logins will be returned for "http://bar.example.co.uk",
+ // but not for "http://notexample.com" or "https://example.foo.com".
+ virtual void GetLoginsForSameOrganizationName(
+ const std::string& signon_realm,
+ PasswordStoreConsumer* consumer);
+
// Gets the complete list of PasswordForms that are not blacklist entries--and
// are thus auto-fillable. |consumer| will be notified on completion.
// The request will be cancelled if the consumer is destroyed.
@@ -241,6 +258,9 @@ class PasswordStore : protected PasswordStoreSync,
virtual void CheckReuse(const base::string16& input,
const std::string& domain,
PasswordReuseDetectorConsumer* consumer);
+
+ // Saves a hash of |password| for password reuse checking.
+ void SaveSyncPasswordHash(const base::string16& password);
#endif
protected:
@@ -291,7 +311,7 @@ class PasswordStore : protected PasswordStoreSync,
// PasswordReuseDetectorConsumer
void OnReuseFound(const base::string16& password,
- const std::string& saved_domain,
+ const std::string& legitimate_domain,
int saved_passwords,
int number_matches) override;
@@ -369,6 +389,11 @@ class PasswordStore : protected PasswordStoreSync,
virtual std::vector<std::unique_ptr<autofill::PasswordForm>>
FillMatchingLogins(const FormDigest& form) = 0;
+ // Finds and returns all organization-name-matching logins, or returns an
+ // empty list on error.
+ virtual std::vector<std::unique_ptr<autofill::PasswordForm>>
+ FillLoginsForSameOrganizationName(const std::string& signon_realm) = 0;
+
// Synchronous implementation for manipulating with statistics.
virtual void AddSiteStatsImpl(const InteractionsStats& stats) = 0;
virtual void RemoveSiteStatsImpl(const GURL& origin_domain) = 0;
@@ -402,6 +427,9 @@ class PasswordStore : protected PasswordStoreSync,
void CheckReuseImpl(std::unique_ptr<CheckReuseRequest> request,
const base::string16& input,
const std::string& domain);
+
+ // Synchronous implementation of SaveSyncPasswordHash().
+ void SaveSyncPasswordHashImpl(const base::string16& password);
#endif
// TaskRunner for tasks that run on the main thread (usually the UI thread).
@@ -456,6 +484,12 @@ class PasswordStore : protected PasswordStoreSync,
const base::Callback<bool(const GURL&)>& origin_filter,
const base::Closure& completion);
+ // Finds all logins organization-name-matching |signon_realm| and notifies the
+ // consumer.
+ void GetLoginsForSameOrganizationNameImpl(
+ const std::string& signon_realm,
+ std::unique_ptr<GetLoginsRequest> request);
+
// Finds all non-blacklist PasswordForms, and notifies the consumer.
void GetAutofillableLoginsImpl(std::unique_ptr<GetLoginsRequest> request);
@@ -544,7 +578,8 @@ class PasswordStore : protected PasswordStoreSync,
// Creates PasswordSyncableService and PasswordReuseDetector instances on the
// background thread.
void InitOnBackgroundThread(
- const syncer::SyncableService::StartSyncFlare& flare);
+ const syncer::SyncableService::StartSyncFlare& flare,
+ PrefService* prefs);
// Deletes objest that should be destroyed on the background thread.
void DestroyOnBackgroundThread();
diff --git a/chromium/components/password_manager/core/browser/password_store_default.cc b/chromium/components/password_manager/core/browser/password_store_default.cc
index 23debe3534b..2e05c0a7c3d 100644
--- a/chromium/components/password_manager/core/browser/password_store_default.cc
+++ b/chromium/components/password_manager/core/browser/password_store_default.cc
@@ -27,9 +27,10 @@ PasswordStoreDefault::~PasswordStoreDefault() {
}
bool PasswordStoreDefault::Init(
- const syncer::SyncableService::StartSyncFlare& flare) {
+ const syncer::SyncableService::StartSyncFlare& flare,
+ PrefService* prefs) {
ScheduleTask(base::Bind(&PasswordStoreDefault::InitOnDBThread, this));
- return PasswordStore::Init(flare);
+ return PasswordStore::Init(flare, prefs);
}
void PasswordStoreDefault::ShutdownOnUIThread() {
@@ -181,6 +182,16 @@ PasswordStoreDefault::FillMatchingLogins(const FormDigest& form) {
return matched_forms;
}
+std::vector<std::unique_ptr<PasswordForm>>
+PasswordStoreDefault::FillLoginsForSameOrganizationName(
+ const std::string& signon_realm) {
+ std::vector<std::unique_ptr<PasswordForm>> forms;
+ if (login_db_ &&
+ !login_db_->GetLoginsForSameOrganizationName(signon_realm, &forms))
+ return std::vector<std::unique_ptr<PasswordForm>>();
+ return forms;
+}
+
bool PasswordStoreDefault::FillAutofillableLogins(
std::vector<std::unique_ptr<PasswordForm>>* forms) {
DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
diff --git a/chromium/components/password_manager/core/browser/password_store_default.h b/chromium/components/password_manager/core/browser/password_store_default.h
index 71b93656292..0c7faebef2d 100644
--- a/chromium/components/password_manager/core/browser/password_store_default.h
+++ b/chromium/components/password_manager/core/browser/password_store_default.h
@@ -10,9 +10,12 @@
#include <vector>
#include "base/macros.h"
+#include "base/single_thread_task_runner.h"
#include "components/password_manager/core/browser/login_database.h"
#include "components/password_manager/core/browser/password_store.h"
+class PrefService;
+
namespace password_manager {
// Simple password store implementation that delegates everything to
@@ -26,7 +29,8 @@ class PasswordStoreDefault : public PasswordStore {
scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner,
std::unique_ptr<LoginDatabase> login_db);
- bool Init(const syncer::SyncableService::StartSyncFlare& flare) override;
+ bool Init(const syncer::SyncableService::StartSyncFlare& flare,
+ PrefService* prefs) override;
void ShutdownOnUIThread() override;
@@ -66,6 +70,8 @@ class PasswordStoreDefault : public PasswordStore {
base::Time delete_end) override;
std::vector<std::unique_ptr<autofill::PasswordForm>> FillMatchingLogins(
const FormDigest& form) override;
+ std::vector<std::unique_ptr<autofill::PasswordForm>>
+ FillLoginsForSameOrganizationName(const std::string& signon_realm) override;
bool FillAutofillableLogins(
std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
bool FillBlacklistLogins(
diff --git a/chromium/components/password_manager/core/browser/password_store_default_unittest.cc b/chromium/components/password_manager/core/browser/password_store_default_unittest.cc
index f8239e5ceba..cc2e8afd92e 100644
--- a/chromium/components/password_manager/core/browser/password_store_default_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_store_default_unittest.cc
@@ -15,6 +15,7 @@
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/password_manager/core/browser/login_database.h"
@@ -97,21 +98,25 @@ class PasswordStoreDefaultTestDelegate {
base::FilePath test_login_db_file_path() const;
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
base::ScopedTempDir temp_dir_;
scoped_refptr<PasswordStoreDefault> store_;
DISALLOW_COPY_AND_ASSIGN(PasswordStoreDefaultTestDelegate);
};
-PasswordStoreDefaultTestDelegate::PasswordStoreDefaultTestDelegate() {
+PasswordStoreDefaultTestDelegate::PasswordStoreDefaultTestDelegate()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {
SetupTempDir();
store_ = CreateInitializedStore(
base::MakeUnique<LoginDatabase>(test_login_db_file_path()));
}
PasswordStoreDefaultTestDelegate::PasswordStoreDefaultTestDelegate(
- std::unique_ptr<LoginDatabase> database) {
+ std::unique_ptr<LoginDatabase> database)
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {
SetupTempDir();
store_ = CreateInitializedStore(std::move(database));
}
@@ -140,7 +145,7 @@ PasswordStoreDefaultTestDelegate::CreateInitializedStore(
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
std::move(database)));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
return store;
}
diff --git a/chromium/components/password_manager/core/browser/password_store_unittest.cc b/chromium/components/password_manager/core/browser/password_store_unittest.cc
index 527770396f7..53835261704 100644
--- a/chromium/components/password_manager/core/browser/password_store_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_store_unittest.cc
@@ -15,10 +15,12 @@
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -45,24 +47,32 @@ namespace password_manager {
namespace {
-const char kTestWebRealm1[] = "https://one.example.com/";
-const char kTestWebOrigin1[] = "https://one.example.com/origin";
-const char kTestWebRealm2[] = "https://two.example.com/";
-const char kTestWebOrigin2[] = "https://two.example.com/origin";
-const char kTestWebRealm3[] = "https://three.example.com/";
-const char kTestWebOrigin3[] = "https://three.example.com/origin";
-const char kTestWebRealm5[] = "https://five.example.com/";
-const char kTestWebOrigin5[] = "https://five.example.com/origin";
-const char kTestPSLMatchingWebRealm[] = "https://psl.example.com/";
-const char kTestPSLMatchingWebOrigin[] = "https://psl.example.com/origin";
-const char kTestUnrelatedWebRealm[] = "https://notexample.com/";
-const char kTestUnrelatedWebOrigin[] = "https:/notexample.com/origin";
-const char kTestInsecureWebRealm[] = "http://one.example.com/";
-const char kTestInsecureWebOrigin[] = "http://one.example.com/origin";
-const char kTestAndroidRealm1[] = "android://hash@com.example.android/";
-const char kTestAndroidRealm2[] = "android://hash@com.example.two.android/";
-const char kTestAndroidRealm3[] = "android://hash@com.example.three.android/";
-const char kTestUnrelatedAndroidRealm[] =
+constexpr const char kTestWebRealm1[] = "https://one.example.com/";
+constexpr const char kTestWebOrigin1[] = "https://one.example.com/origin";
+constexpr const char kTestWebRealm2[] = "https://two.example.com/";
+constexpr const char kTestWebOrigin2[] = "https://two.example.com/origin";
+constexpr const char kTestWebRealm3[] = "https://three.example.com/";
+constexpr const char kTestWebOrigin3[] = "https://three.example.com/origin";
+constexpr const char kTestWebRealm5[] = "https://five.example.com/";
+constexpr const char kTestWebOrigin5[] = "https://five.example.com/origin";
+constexpr const char kTestPSLMatchingWebRealm[] = "https://psl.example.com/";
+constexpr const char kTestPSLMatchingWebOrigin[] =
+ "https://psl.example.com/origin";
+constexpr const char kTestUnrelatedWebRealm[] = "https://notexample.com/";
+constexpr const char kTestUnrelatedWebOrigin[] = "https:/notexample.com/origin";
+constexpr const char kTestSameOrganizationNameWebRealm[] =
+ "https://example.appspot.com/";
+constexpr const char kTestSameOrganizationNameWebOrigin[] =
+ "https://example.appspot.com/origin";
+constexpr const char kTestInsecureWebRealm[] = "http://one.example.com/";
+constexpr const char kTestInsecureWebOrigin[] = "http://one.example.com/origin";
+constexpr const char kTestAndroidRealm1[] =
+ "android://hash@com.example.android/";
+constexpr const char kTestAndroidRealm2[] =
+ "android://hash@com.example.two.android/";
+constexpr const char kTestAndroidRealm3[] =
+ "android://hash@com.example.three.android/";
+constexpr const char kTestUnrelatedAndroidRealm[] =
"android://hash@com.notexample.android/";
class MockPasswordStoreConsumer : public PasswordStoreConsumer {
@@ -89,6 +99,10 @@ class StartSyncFlareMock {
class PasswordStoreTest : public testing::Test {
protected:
+ PasswordStoreTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
+
void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
void TearDown() override { ASSERT_TRUE(temp_dir_.Delete()); }
@@ -97,7 +111,7 @@ class PasswordStoreTest : public testing::Test {
return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("login_test"));
}
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
base::ScopedTempDir temp_dir_;
};
@@ -105,7 +119,7 @@ TEST_F(PasswordStoreTest, IgnoreOldWwwGoogleLogins) {
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
const time_t cutoff = 1325376000; // 00:00 Jan 1 2012 UTC
static const PasswordFormData form_data[] = {
@@ -201,7 +215,8 @@ TEST_F(PasswordStoreTest, StartSyncFlare) {
base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
StartSyncFlareMock mock;
store->Init(
- base::Bind(&StartSyncFlareMock::StartSyncFlare, base::Unretained(&mock)));
+ base::Bind(&StartSyncFlareMock::StartSyncFlare, base::Unretained(&mock)),
+ nullptr);
{
PasswordForm form;
form.origin = GURL("http://accounts.google.com/LoginAuth");
@@ -228,7 +243,7 @@ TEST_F(PasswordStoreTest, GetLoginImpl) {
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
// For each attribute in the primary key, create one form that mismatches on
// that attribute.
@@ -291,7 +306,7 @@ TEST_F(PasswordStoreTest, UpdateLoginPrimaryKeyFields) {
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
std::unique_ptr<PasswordForm> old_form(
CreatePasswordFormFromDataForTesting(kTestCredentials[0]));
@@ -344,7 +359,7 @@ TEST_F(PasswordStoreTest, RemoveLoginsCreatedBetweenCallbackIsCalled) {
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
std::unique_ptr<PasswordForm> test_form(
CreatePasswordFormFromDataForTesting(kTestCredential));
@@ -397,7 +412,7 @@ TEST_F(PasswordStoreTest, GetLoginsWithoutAffiliations) {
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));
@@ -502,7 +517,7 @@ TEST_F(PasswordStoreTest, GetLoginsWithAffiliations) {
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));
@@ -686,7 +701,7 @@ TEST_F(PasswordStoreTest, MAYBE_UpdatePasswordsStoredForAffiliatedWebsites) {
base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get(),
base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(),
base::Closure());
@@ -795,7 +810,7 @@ TEST_F(PasswordStoreTest, GetLoginsWithAffiliatedRealms) {
base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get(),
base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(),
base::Closure());
@@ -844,6 +859,61 @@ TEST_F(PasswordStoreTest, GetLoginsWithAffiliatedRealms) {
}
}
+TEST_F(PasswordStoreTest, GetLoginsForSameOrganizationName) {
+ static constexpr const PasswordFormData kSameOrganizationCredentials[] = {
+ // Credential that is an exact match of the observed form.
+ {PasswordForm::SCHEME_HTML, kTestWebRealm1, kTestWebOrigin1, "", L"", L"",
+ L"", L"username_value_1", L"", true, 1},
+ // Credential that is a PSL match of the observed form.
+ {PasswordForm::SCHEME_HTML, kTestPSLMatchingWebRealm,
+ kTestPSLMatchingWebOrigin, "", L"", L"", L"", L"username_value_2", L"",
+ true, 1},
+ // Credential for the HTTP version of the observed form. (Should not be
+ // filled, but returned as part of same-organization-name matches).
+ {PasswordForm::SCHEME_HTML, kTestInsecureWebRealm, kTestInsecureWebOrigin,
+ "", L"", L"", L"", L"username_value_3", L"", true, 1},
+ // Credential for a signon realm with a different TLD, but same
+ // organization identifying name.
+ {PasswordForm::SCHEME_HTML, kTestSameOrganizationNameWebRealm,
+ kTestSameOrganizationNameWebOrigin, "", L"", L"", L"",
+ L"username_value_4", L"", true, 1},
+ };
+
+ static constexpr const PasswordFormData kNotSameOrganizationCredentials[] = {
+ // Unrelated Web credential.
+ {PasswordForm::SCHEME_HTML, kTestUnrelatedWebRealm,
+ kTestUnrelatedWebOrigin, "", L"", L"", L"", L"username_value_5", L"",
+ true, 1},
+ // Credential for an affiliated Android application.
+ {PasswordForm::SCHEME_HTML, kTestAndroidRealm1, "", "", L"", L"", L"",
+ L"username_value_6", L"", true, 1}};
+
+ scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
+ base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
+ base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
+
+ std::vector<std::unique_ptr<PasswordForm>> expected_results;
+ for (const auto& form_data : kSameOrganizationCredentials) {
+ expected_results.push_back(CreatePasswordFormFromDataForTesting(form_data));
+ store->AddLogin(*expected_results.back());
+ }
+
+ for (const auto& form_data : kNotSameOrganizationCredentials) {
+ store->AddLogin(*CreatePasswordFormFromDataForTesting(form_data));
+ }
+
+ const std::string observed_form_realm = kTestWebRealm1;
+ MockPasswordStoreConsumer mock_consumer;
+ EXPECT_CALL(mock_consumer,
+ OnGetPasswordStoreResultsConstRef(
+ UnorderedPasswordFormElementsAre(&expected_results)));
+ store->GetLoginsForSameOrganizationName(observed_form_realm, &mock_consumer);
+ base::RunLoop().RunUntilIdle();
+ store->ShutdownOnUIThread();
+ base::RunLoop().RunUntilIdle();
+}
+
// TODO(crbug.com/706392): Fix password reuse detection for Android.
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PasswordStoreTest, CheckPasswordReuse) {
@@ -861,7 +931,7 @@ TEST_F(PasswordStoreTest, CheckPasswordReuse) {
scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
- store->Init(syncer::SyncableService::StartSyncFlare());
+ store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
for (const auto& test_credentials : kTestCredentials) {
auto credentials = CreatePasswordFormFromDataForTesting(test_credentials);
diff --git a/chromium/components/password_manager/core/browser/psl_matching_helper.cc b/chromium/components/password_manager/core/browser/psl_matching_helper.cc
index b4c4bef165c..6cbb305c764 100644
--- a/chromium/components/password_manager/core/browser/psl_matching_helper.cc
+++ b/chromium/components/password_manager/core/browser/psl_matching_helper.cc
@@ -116,4 +116,28 @@ std::string GetRegistryControlledDomain(const GURL& signon_realm) {
signon_realm,
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
}
+
+std::string GetOrganizationIdentifyingName(const GURL& url) {
+ if (!url.is_valid())
+ return std::string();
+
+ const std::string organization_and_registrar =
+ net::registry_controlled_domains::GetDomainAndRegistry(
+ url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+ const size_t registrar_length =
+ net::registry_controlled_domains::GetRegistryLength(
+ url, net::registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+
+ if (organization_and_registrar.empty() || !registrar_length ||
+ registrar_length == std::string::npos) {
+ return std::string();
+ }
+
+ // No CHECK, std::string::substr gracefully handles an underflow there.
+ DCHECK_LT(registrar_length, organization_and_registrar.size());
+ return organization_and_registrar.substr(
+ 0, organization_and_registrar.size() - registrar_length - 1);
+}
+
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/psl_matching_helper.h b/chromium/components/password_manager/core/browser/psl_matching_helper.h
index 7bfea29daa9..1d0e6596927 100644
--- a/chromium/components/password_manager/core/browser/psl_matching_helper.h
+++ b/chromium/components/password_manager/core/browser/psl_matching_helper.h
@@ -36,6 +36,8 @@ enum class MatchResult {
#if defined(UNIT_TEST)
std::ostream& operator<<(std::ostream& out, MatchResult result);
+// These functions are used in production internally but exposed for testing.
+
// Returns true iff |form_signon_realm| designates a federated credential for
// |origin|. It doesn't check the port because |form_signon_realm| doesn't have
// it.
@@ -74,6 +76,11 @@ bool IsPublicSuffixDomainMatch(const std::string& url1,
// registry-controlled domain part.
std::string GetRegistryControlledDomain(const GURL& signon_realm);
+// Returns the organization-identifying name of the host of |url|, that is, the
+// first domain name label below the effective TLD. Returns the empty string for
+// URLs where these concepts are ill-defined, as well as for invalid URLs.
+std::string GetOrganizationIdentifyingName(const GURL& url);
+
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PSL_MATCHING_HELPER_H_
diff --git a/chromium/components/password_manager/core/browser/psl_matching_helper_unittest.cc b/chromium/components/password_manager/core/browser/psl_matching_helper_unittest.cc
index 66c798df366..3f6a25b041d 100644
--- a/chromium/components/password_manager/core/browser/psl_matching_helper_unittest.cc
+++ b/chromium/components/password_manager/core/browser/psl_matching_helper_unittest.cc
@@ -5,10 +5,15 @@
#include "components/password_manager/core/browser/psl_matching_helper.h"
#include <stddef.h>
+#include <cctype>
#include "base/macros.h"
+#include "base/stl_util.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "components/autofill/core/common/password_form.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
namespace password_manager {
@@ -387,6 +392,102 @@ TEST(PSLMatchingUtilsTest, IsFederatedPSLMatch) {
}
}
+TEST(PSLMatchingUtilsTest, GetOrganizationIdentifyingName) {
+ static constexpr const struct {
+ const char* url;
+ const char* expected_organization_name;
+ } kTestCases[] = {
+ {"http://example.com/login", "example"},
+ {"https://example.com", "example"},
+ {"ftp://example.com/ftp_realm", "example"},
+
+ {"http://foo.bar.example.com", "example"},
+ {"http://example.co.uk", "example"},
+ {"http://bar.example.appspot.com", "example"},
+ {"http://foo.bar", "foo"},
+ {"https://user:pass@www.example.com:80/path?query#ref", "example"},
+
+ {"http://www.foo+bar.com", "foo+bar"},
+ {"http://www.foo-bar.com", "foo-bar"},
+ {"https://foo_bar.com", "foo_bar"},
+ {"http://www.foo%2Bbar.com", "foo+bar"},
+ {"http://www.foo%2Dbar.com", "foo-bar"},
+ {"https://foo%5Fbar.com", "foo_bar"},
+ {"http://www.foo%2Ebar.com", "bar"},
+
+ // Internationalized Domain Names: each dot-separated label of the domain
+ // name is individually Punycode-encoded, so the organization-identifying
+ // name is still well-defined and can be determined as normal.
+ // , ,
+ // szotar = sz\xc3\xb3t\xc3\xa1r (UTF-8) = xn--sztr-7na0i (IDN)
+ // | |
+ // U+00E1 U+00F3
+ {"https://www.sz\xc3\xb3t\xc3\xa1r.appspot.com", "xn--sztr-7na0i"},
+
+ {"http://www.foo!bar.com", "foo%21bar"},
+ {"http://www.foo%21bar.com", "foo%21bar"},
+ {"http://www.foo$bar.com", "foo%24bar"},
+ {"http://www.foo&bar.com", "foo%26bar"},
+ {"http://www.foo\'bar.com", "foo%27bar"},
+ {"http://www.foo(bar.com", "foo%28bar"},
+ {"http://www.foo)bar.com", "foo%29bar"},
+ {"http://www.foo*bar.com", "foo%2Abar"},
+ {"http://www.foo,bar.com", "foo%2Cbar"},
+ {"http://www.foo=bar.com", "foo%3Dbar"},
+
+ // URLs without host portions, hosts without registry controlled domains
+ // should, or hosts consisting of a registry yield the empty string.
+ {"http://localhost", ""},
+ {"http://co.uk", ""},
+ {"http://google", ""},
+ {"http://127.0.0.1", ""},
+ {"file:///usr/bin/stuff", ""},
+ {"federation://example.com/google.com", ""},
+ {"android://hash@com.example/", ""},
+ {"http://[1080:0:0:0:8:800:200C:417A]/", ""},
+ {"http://[3ffe:2a00:100:7031::1]", ""},
+ {"http://[::192.9.5.5]/", ""},
+
+ // Invalid URLs should yield the empty string.
+ {"", ""},
+ {"http://", ""},
+ {"bad url", ""},
+ {"http://www.example.com/%00", ""},
+ {"http://www.foo;bar.com", ""},
+ {"http://www.foo~bar.com", ""},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(test_case.url);
+ GURL url(test_case.url);
+ EXPECT_EQ(test_case.expected_organization_name,
+ GetOrganizationIdentifyingName(url));
+ }
+}
+
+// Apart from alphanumeric characters and '.', only |kExpectedUnescapedChars|
+// are expected to appear without percent-encoding in the domain of a valid,
+// canonicalized URL.
+//
+// The purpose of this test is to ensure that the test cases around unescaped
+// special characters in `GetOrganizationIdentifyingName` are exhaustive.
+TEST(PSLMatchingUtilsTest,
+ GetOrganizationIdentifyingName_UnescapedSpecialChars) {
+ static constexpr const char kExpectedNonAlnumChars[] = {'+', '-', '_', '.'};
+ for (int chr = 0; chr <= 255; ++chr) {
+ const auto percent_encoded = base::StringPrintf("http://a%%%02Xb.hu/", chr);
+ const GURL url(percent_encoded);
+ if (isalnum(chr) || base::ContainsValue(kExpectedNonAlnumChars, chr)) {
+ ASSERT_TRUE(url.is_valid());
+ const auto percent_decoded = base::StringPrintf(
+ "http://a%cb.hu/", base::ToLowerASCII(static_cast<char>(chr)));
+ EXPECT_EQ(percent_decoded, url.spec());
+ } else if (url.is_valid()) {
+ EXPECT_EQ(percent_encoded, url.spec());
+ }
+ }
+}
+
} // namespace
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/stub_password_manager_client.cc b/chromium/components/password_manager/core/browser/stub_password_manager_client.cc
index c4c9658ea66..309c877e946 100644
--- a/chromium/components/password_manager/core/browser/stub_password_manager_client.cc
+++ b/chromium/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -69,6 +69,13 @@ safe_browsing::PasswordProtectionService*
StubPasswordManagerClient::GetPasswordProtectionService() const {
return nullptr;
}
+
+void StubPasswordManagerClient::CheckSafeBrowsingReputation(
+ const GURL& form_action,
+ const GURL& frame_url) {}
+
+void StubPasswordManagerClient::CheckProtectedPasswordEntry(
+ const std::string& password_saved_domain) {}
#endif
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/stub_password_manager_client.h b/chromium/components/password_manager/core/browser/stub_password_manager_client.h
index a7a6b49588c..77c740befb5 100644
--- a/chromium/components/password_manager/core/browser/stub_password_manager_client.h
+++ b/chromium/components/password_manager/core/browser/stub_password_manager_client.h
@@ -46,6 +46,10 @@ class StubPasswordManagerClient : public PasswordManagerClient {
#if defined(SAFE_BROWSING_DB_LOCAL)
safe_browsing::PasswordProtectionService* GetPasswordProtectionService()
const override;
+ void CheckSafeBrowsingReputation(const GURL& form_action,
+ const GURL& frame_url) override;
+ void CheckProtectedPasswordEntry(
+ const std::string& password_saved_domain) override;
#endif
private:
diff --git a/chromium/components/password_manager/core/browser/stub_password_manager_driver.cc b/chromium/components/password_manager/core/browser/stub_password_manager_driver.cc
index 18b7dc56a7c..4a9145faa38 100644
--- a/chromium/components/password_manager/core/browser/stub_password_manager_driver.cc
+++ b/chromium/components/password_manager/core/browser/stub_password_manager_driver.cc
@@ -60,4 +60,8 @@ autofill::AutofillDriver* StubPasswordManagerDriver::GetAutofillDriver() {
return nullptr;
}
+bool StubPasswordManagerDriver::IsMainFrame() const {
+ return true;
+}
+
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/stub_password_manager_driver.h b/chromium/components/password_manager/core/browser/stub_password_manager_driver.h
index f7a1703d1d9..406190aef35 100644
--- a/chromium/components/password_manager/core/browser/stub_password_manager_driver.h
+++ b/chromium/components/password_manager/core/browser/stub_password_manager_driver.h
@@ -37,6 +37,7 @@ class StubPasswordManagerDriver : public PasswordManagerDriver {
PasswordManager* GetPasswordManager() override;
PasswordAutofillManager* GetPasswordAutofillManager() override;
autofill::AutofillDriver* GetAutofillDriver() override;
+ bool IsMainFrame() const override;
private:
DISALLOW_COPY_AND_ASSIGN(StubPasswordManagerDriver);
diff --git a/chromium/components/password_manager/core/browser/suppressed_form_fetcher.cc b/chromium/components/password_manager/core/browser/suppressed_form_fetcher.cc
new file mode 100644
index 00000000000..1a52b08999e
--- /dev/null
+++ b/chromium/components/password_manager/core/browser/suppressed_form_fetcher.cc
@@ -0,0 +1,41 @@
+// Copyright 2017 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/password_manager/core/browser/suppressed_form_fetcher.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "components/password_manager/core/browser/password_manager_client.h"
+#include "components/password_manager/core/browser/password_store.h"
+#include "url/gurl.h"
+
+namespace password_manager {
+
+SuppressedFormFetcher::SuppressedFormFetcher(
+ const std::string& observed_signon_realm,
+ const PasswordManagerClient* client,
+ Consumer* consumer)
+ : client_(client),
+ consumer_(consumer),
+ observed_signon_realm_(observed_signon_realm) {
+ DCHECK(client_);
+ DCHECK(consumer_);
+ DCHECK(GURL(observed_signon_realm_).SchemeIsHTTPOrHTTPS());
+ client_->GetPasswordStore()->GetLoginsForSameOrganizationName(
+ observed_signon_realm_, this);
+}
+
+SuppressedFormFetcher::~SuppressedFormFetcher() = default;
+
+void SuppressedFormFetcher::OnGetPasswordStoreResults(
+ std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
+ base::EraseIf(results,
+ [this](const std::unique_ptr<autofill::PasswordForm>& form) {
+ return form->signon_realm == observed_signon_realm_;
+ });
+
+ consumer_->ProcessSuppressedForms(std::move(results));
+}
+
+} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/suppressed_form_fetcher.h b/chromium/components/password_manager/core/browser/suppressed_form_fetcher.h
new file mode 100644
index 00000000000..7f663494b8f
--- /dev/null
+++ b/chromium/components/password_manager/core/browser/suppressed_form_fetcher.h
@@ -0,0 +1,62 @@
+// Copyright 2017 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_PASSWORD_MANAGER_CORE_BROWSER_SUPPRESSED_FORM_FETCHER_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SUPPRESSED_FORM_FETCHER_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/browser/password_store_consumer.h"
+
+namespace password_manager {
+
+class PasswordManagerClient;
+
+// Fetches credentials saved for the HTTPS counterpart of the given HTTP realm.
+//
+// Filling these HTTPS credentials into forms served over HTTP is obviously
+// suppressed, the purpose of doing such a query is to collect metrics on how
+// often this happens and inconveniences the user.
+//
+// This logic is implemented by this class, a separate PasswordStore consumer,
+// to make it very sure that these credentials will not get mistakenly filled.
+class SuppressedFormFetcher : public PasswordStoreConsumer {
+ public:
+ // Interface to be implemented by the consumer of this class.
+ class Consumer {
+ public:
+ virtual void ProcessSuppressedForms(
+ std::vector<std::unique_ptr<autofill::PasswordForm>> forms) = 0;
+ };
+
+ SuppressedFormFetcher(const std::string& observed_signon_realm,
+ const PasswordManagerClient* client,
+ Consumer* consumer);
+ ~SuppressedFormFetcher() override;
+
+ protected:
+ // PasswordStoreConsumer:
+ void OnGetPasswordStoreResults(
+ std::vector<std::unique_ptr<autofill::PasswordForm>> results) override;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(SuppressedFormFetcherTest, EmptyStore);
+ FRIEND_TEST_ALL_PREFIXES(SuppressedFormFetcherTest, FullStore);
+
+ // The client and the consumer should outlive |this|.
+ const PasswordManagerClient* client_;
+ Consumer* consumer_;
+
+ const std::string observed_signon_realm_;
+
+ DISALLOW_COPY_AND_ASSIGN(SuppressedFormFetcher);
+};
+
+} // namespace password_manager
+
+#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SUPPRESSED_FORM_FETCHER_H_
diff --git a/chromium/components/password_manager/core/browser/suppressed_form_fetcher_unittest.cc b/chromium/components/password_manager/core/browser/suppressed_form_fetcher_unittest.cc
new file mode 100644
index 00000000000..d4caa0422a2
--- /dev/null
+++ b/chromium/components/password_manager/core/browser/suppressed_form_fetcher_unittest.cc
@@ -0,0 +1,157 @@
+// Copyright 2017 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/password_manager/core/browser/suppressed_form_fetcher.h"
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "components/password_manager/core/browser/mock_password_store.h"
+#include "components/password_manager/core/browser/password_manager_test_utils.h"
+#include "components/password_manager/core/browser/stub_password_manager_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace password_manager {
+namespace {
+
+using autofill::PasswordForm;
+using testing::_;
+
+constexpr const char kTestHttpURL[] = "http://one.example.com/";
+constexpr const char kTestHttpsURL[] = "https://one.example.com/";
+constexpr const char kTestPSLMatchingHttpURL[] = "http://psl.example.com/";
+constexpr const char kTestPSLMatchingHttpsURL[] = "https://psl.example.com/";
+constexpr const char kTestHttpSameOrgNameURL[] = "http://login.example.co.uk/";
+constexpr const char kTestHttpsSameOrgNameURL[] =
+ "https://login.example.co.uk/";
+
+class MockConsumer : public SuppressedFormFetcher::Consumer {
+ public:
+ MockConsumer() = default;
+ ~MockConsumer() = default;
+
+ // GMock still cannot mock methods with move-only args.
+ MOCK_METHOD1(ProcessSuppressedHTTPSFormsConstRef,
+ void(const std::vector<std::unique_ptr<PasswordForm>>&));
+
+ protected:
+ // SuppressedFormFetcher::Consumer:
+ void ProcessSuppressedForms(
+ std::vector<std::unique_ptr<PasswordForm>> forms) override {
+ ProcessSuppressedHTTPSFormsConstRef(forms);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockConsumer);
+};
+
+class PasswordManagerClientWithMockStore : public StubPasswordManagerClient {
+ public:
+ PasswordManagerClientWithMockStore()
+ : mock_store_(new ::testing::StrictMock<MockPasswordStore>()) {}
+ ~PasswordManagerClientWithMockStore() override {
+ mock_store_->ShutdownOnUIThread();
+ }
+
+ MockPasswordStore& mock_password_store() const { return *mock_store_.get(); }
+
+ protected:
+ // StubPasswordManagerClient:
+ PasswordStore* GetPasswordStore() const override { return mock_store_.get(); }
+
+ private:
+ scoped_refptr<MockPasswordStore> mock_store_;
+
+ DISALLOW_COPY_AND_ASSIGN(PasswordManagerClientWithMockStore);
+};
+
+} // namespace
+
+class SuppressedFormFetcherTest : public testing::Test {
+ public:
+ SuppressedFormFetcherTest() = default;
+ ~SuppressedFormFetcherTest() override = default;
+
+ MockConsumer* mock_consumer() { return &consumer_; }
+ MockPasswordStore* mock_store() { return &client_.mock_password_store(); }
+ PasswordManagerClientWithMockStore* mock_client() { return &client_; }
+
+ private:
+ base::MessageLoop message_loop_; // Needed by the MockPasswordStore.
+
+ MockConsumer consumer_;
+ PasswordManagerClientWithMockStore client_;
+
+ DISALLOW_COPY_AND_ASSIGN(SuppressedFormFetcherTest);
+};
+
+TEST_F(SuppressedFormFetcherTest, EmptyStore) {
+ EXPECT_CALL(*mock_store(), GetLoginsForSameOrganizationName(kTestHttpURL, _));
+ SuppressedFormFetcher suppressed_form_fetcher(kTestHttpURL, mock_client(),
+ mock_consumer());
+ EXPECT_CALL(*mock_consumer(),
+ ProcessSuppressedHTTPSFormsConstRef(::testing::IsEmpty()));
+ suppressed_form_fetcher.OnGetPasswordStoreResults(
+ std::vector<std::unique_ptr<PasswordForm>>());
+}
+
+TEST_F(SuppressedFormFetcherTest, FullStore) {
+ static constexpr const PasswordFormData kSuppressedCredentials[] = {
+ // Credential that is for the HTTPS counterpart of the observed form.
+ {PasswordForm::SCHEME_HTML, kTestHttpsURL, kTestHttpsURL, "", L"", L"",
+ L"", L"username_value_1", L"password_value_1", true, 1},
+ // Once again, but with a different username/password.
+ {PasswordForm::SCHEME_HTML, kTestHttpsURL, kTestHttpsURL, "", L"", L"",
+ L"", L"username_value_2", L"password_value_2", true, 1},
+ // A PSL match to the observed form.
+ {PasswordForm::SCHEME_HTML, kTestPSLMatchingHttpURL,
+ kTestPSLMatchingHttpURL, "", L"", L"", L"", L"username_value_2",
+ L"password_value_2", true, 1},
+ // A PSL match to the HTTPS counterpart of the observed form. Note that
+ // this is *not* a PSL match to the observed form, but a same organization
+ // name match.
+ {PasswordForm::SCHEME_HTML, kTestPSLMatchingHttpsURL,
+ kTestPSLMatchingHttpsURL, "", L"", L"", L"", L"username_value_3",
+ L"password_value_3", true, 1},
+ // Credentials for a HTTP origin with the same organization
+ // identifying name.
+ {PasswordForm::SCHEME_HTML, kTestHttpSameOrgNameURL,
+ kTestHttpSameOrgNameURL, "", L"", L"", L"", L"username_value_4",
+ L"password_value_4", true, 1},
+ // Credentials for a HTTPS origin with the same organization
+ // identifying name.
+ {PasswordForm::SCHEME_HTML, kTestHttpsSameOrgNameURL,
+ kTestHttpsSameOrgNameURL, "", L"", L"", L"", L"username_value_5",
+ L"password_value_5", true, 1}};
+
+ static const PasswordFormData kNotSuppressedCredentials[] = {
+ // Credential exactly matching the observed form.
+ {PasswordForm::SCHEME_HTML, kTestHttpURL, kTestHttpURL, "", L"", L"", L"",
+ L"username_value_1", L"password_value_1", true, 1},
+ };
+
+ std::vector<std::unique_ptr<PasswordForm>> simulated_store_results;
+ std::vector<std::unique_ptr<PasswordForm>> expected_results;
+ for (const auto& form_data : kSuppressedCredentials) {
+ expected_results.push_back(CreatePasswordFormFromDataForTesting(form_data));
+ simulated_store_results.push_back(
+ CreatePasswordFormFromDataForTesting(form_data));
+ }
+ for (const auto& form_data : kNotSuppressedCredentials) {
+ simulated_store_results.push_back(
+ CreatePasswordFormFromDataForTesting(form_data));
+ }
+
+ EXPECT_CALL(*mock_store(), GetLoginsForSameOrganizationName(kTestHttpURL, _));
+ SuppressedFormFetcher suppressed_form_fetcher(kTestHttpURL, mock_client(),
+ mock_consumer());
+ EXPECT_CALL(*mock_consumer(),
+ ProcessSuppressedHTTPSFormsConstRef(
+ UnorderedPasswordFormElementsAre(&expected_results)));
+ suppressed_form_fetcher.OnGetPasswordStoreResults(
+ std::move(simulated_store_results));
+}
+
+} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/test_password_store.cc b/chromium/components/password_manager/core/browser/test_password_store.cc
index 6ab4b775e25..1e11a3241d4 100644
--- a/chromium/components/password_manager/core/browser/test_password_store.cc
+++ b/chromium/components/password_manager/core/browser/test_password_store.cc
@@ -87,7 +87,7 @@ TestPasswordStore::FillMatchingLogins(const FormDigest& form) {
std::vector<std::unique_ptr<autofill::PasswordForm>> matched_forms;
for (const auto& elements : stored_passwords_) {
// The code below doesn't support PSL federated credential. It's doable but
- // no test need it so far.
+ // no tests need it so far.
const bool realm_matches = elements.first == form.signon_realm;
const bool realm_psl_matches =
IsPublicSuffixDomainMatch(elements.first, form.signon_realm);
@@ -112,6 +112,13 @@ TestPasswordStore::FillMatchingLogins(const FormDigest& form) {
return matched_forms;
}
+std::vector<std::unique_ptr<autofill::PasswordForm>>
+TestPasswordStore::FillLoginsForSameOrganizationName(
+ const std::string& signon_realm) {
+ // TODO: Implement when needed.
+ return std::vector<std::unique_ptr<autofill::PasswordForm>>();
+}
+
void TestPasswordStore::ReportMetricsImpl(const std::string& sync_username,
bool custom_passphrase_sync_enabled) {
}
diff --git a/chromium/components/password_manager/core/browser/test_password_store.h b/chromium/components/password_manager/core/browser/test_password_store.h
index 8a644a6deb1..837dfaa6c7d 100644
--- a/chromium/components/password_manager/core/browser/test_password_store.h
+++ b/chromium/components/password_manager/core/browser/test_password_store.h
@@ -46,6 +46,8 @@ class TestPasswordStore : public PasswordStore {
const autofill::PasswordForm& form) override;
std::vector<std::unique_ptr<autofill::PasswordForm>> FillMatchingLogins(
const FormDigest& form) override;
+ std::vector<std::unique_ptr<autofill::PasswordForm>>
+ FillLoginsForSameOrganizationName(const std::string& signon_realm) override;
// Unused portions of PasswordStore interface
void ReportMetricsImpl(const std::string& sync_username,
diff --git a/chromium/components/password_manager/core/browser/webdata/password_web_data_service_win.cc b/chromium/components/password_manager/core/browser/webdata/password_web_data_service_win.cc
index b063667be7a..8a432564fb4 100644
--- a/chromium/components/password_manager/core/browser/webdata/password_web_data_service_win.cc
+++ b/chromium/components/password_manager/core/browser/webdata/password_web_data_service_win.cc
@@ -5,6 +5,7 @@
#include "components/password_manager/core/browser/webdata/password_web_data_service_win.h"
#include "base/bind.h"
+#include "base/single_thread_task_runner.h"
#include "components/os_crypt/ie7_password_win.h"
#include "components/password_manager/core/browser/webdata/logins_table.h"
#include "components/webdata/common/web_database_service.h"
diff --git a/chromium/components/password_manager/core/common/credential_manager_types.h b/chromium/components/password_manager/core/common/credential_manager_types.h
index 06e7f0096ce..b9fffab9380 100644
--- a/chromium/components/password_manager/core/common/credential_manager_types.h
+++ b/chromium/components/password_manager/core/common/credential_manager_types.h
@@ -33,6 +33,8 @@ enum class CredentialType {
CREDENTIAL_TYPE_LAST = CREDENTIAL_TYPE_FEDERATED
};
+enum class CredentialMediationRequirement { kSilent, kOptional, kRequired };
+
std::string CredentialTypeToString(CredentialType value);
std::ostream& operator<<(std::ostream& os, CredentialType value);
diff --git a/chromium/components/password_manager/core/common/password_manager_pref_names.cc b/chromium/components/password_manager/core/common/password_manager_pref_names.cc
index fd70a41fe4b..34f10eae2a8 100644
--- a/chromium/components/password_manager/core/common/password_manager_pref_names.cc
+++ b/chromium/components/password_manager/core/common/password_manager_pref_names.cc
@@ -39,5 +39,7 @@ const char kWasSignInPasswordPromoClicked[] =
const char kNumberSignInPasswordPromoShown[] =
"profile.number_sign_in_password_promo_shown";
+const char kSyncPasswordHash[] = "profile.sync_password_hash";
+
} // namespace prefs
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/common/password_manager_pref_names.h b/chromium/components/password_manager/core/common/password_manager_pref_names.h
index dba5fb451e4..9f05a765f1e 100644
--- a/chromium/components/password_manager/core/common/password_manager_pref_names.h
+++ b/chromium/components/password_manager/core/common/password_manager_pref_names.h
@@ -68,6 +68,9 @@ extern const char kWasSignInPasswordPromoClicked[];
// Number of times the Chrome Sign in promo popped up.
extern const char kNumberSignInPasswordPromoShown[];
+// String that represent the sync password hash.
+extern const char kSyncPasswordHash[];
+
} // namespace prefs
} // namespace password_manager
diff --git a/chromium/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc b/chromium/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc
index 6e432dfb60f..3ba8c194cfa 100644
--- a/chromium/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc
+++ b/chromium/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <utility>
+
#include "base/json/json_writer.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
@@ -192,7 +194,7 @@ class PasswordManagerSettingMigratorServiceTest : public testing::Test {
pref_service_syncable = factory.CreateSyncable(pref_registry.get());
migration_service_.reset(
new PasswordManagerSettingMigratorService(pref_service_syncable.get()));
- pref_service_.reset(pref_service_syncable.release());
+ pref_service_ = std::move(pref_service_syncable);
}
void ExpectValuesForBothPrefValues(bool new_pref_value, bool old_pref_value) {
diff --git a/chromium/components/payments/android/BUILD.gn b/chromium/components/payments/android/BUILD.gn
index fc5fe8b95a7..6484ece8d0a 100644
--- a/chromium/components/payments/android/BUILD.gn
+++ b/chromium/components/payments/android/BUILD.gn
@@ -4,6 +4,8 @@
static_library("android") {
sources = [
+ "payment_manifest_web_data_service.cc",
+ "payment_manifest_web_data_service.h",
"payment_method_manifest_table.cc",
"payment_method_manifest_table.h",
"web_app_manifest_section_table.cc",
@@ -11,7 +13,7 @@ static_library("android") {
]
deps = [
- "//components/payments/content:mojom_parser",
+ "//components/payments/mojom:mojom_parser",
"//components/webdata/common",
"//sql",
]
diff --git a/chromium/components/payments/android/DEPS b/chromium/components/payments/android/DEPS
index 0d58d2feb26..6d4be5a91a7 100644
--- a/chromium/components/payments/android/DEPS
+++ b/chromium/components/payments/android/DEPS
@@ -1,5 +1,5 @@
include_rules = [
- "+components/payments/content",
+ "-components/payments/content",
"+components/webdata/common",
"+sql",
] \ No newline at end of file
diff --git a/chromium/components/payments/android/OWNERS b/chromium/components/payments/android/OWNERS
new file mode 100644
index 00000000000..e39fa27b510
--- /dev/null
+++ b/chromium/components/payments/android/OWNERS
@@ -0,0 +1,3 @@
+gogerald@chromium.org
+
+# COMPONENT: UI>Browser>Autofill>Payments
diff --git a/chromium/components/payments/android/payment_manifest_web_data_service.cc b/chromium/components/payments/android/payment_manifest_web_data_service.cc
new file mode 100644
index 00000000000..b217c3d0e33
--- /dev/null
+++ b/chromium/components/payments/android/payment_manifest_web_data_service.cc
@@ -0,0 +1,110 @@
+// Copyright 2017 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/payments/android/payment_manifest_web_data_service.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+
+namespace payments {
+
+PaymentManifestWebDataService::PaymentManifestWebDataService(
+ scoped_refptr<WebDatabaseService> wdbs,
+ const ProfileErrorCallback& callback,
+ const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread)
+ : WebDataServiceBase(wdbs, callback, ui_thread) {}
+
+PaymentManifestWebDataService::~PaymentManifestWebDataService() {}
+
+void PaymentManifestWebDataService::AddPaymentWebAppManifest(
+ std::vector<mojom::WebAppManifestSectionPtr> manifest) {
+ wdbs_->ScheduleDBTask(
+ FROM_HERE,
+ base::Bind(&PaymentManifestWebDataService::AddPaymentWebAppManifestImpl,
+ this, std::move(manifest)));
+}
+
+WebDatabase::State PaymentManifestWebDataService::AddPaymentWebAppManifestImpl(
+ const std::vector<mojom::WebAppManifestSectionPtr>& manifest,
+ WebDatabase* db) {
+ if (WebAppManifestSectionTable::FromWebDatabase(db)->AddWebAppManifest(
+ manifest)) {
+ return WebDatabase::COMMIT_NEEDED;
+ }
+
+ return WebDatabase::COMMIT_NOT_NEEDED;
+}
+
+void PaymentManifestWebDataService::AddPaymentMethodManifest(
+ const std::string& payment_method,
+ std::vector<std::string> app_package_names) {
+ wdbs_->ScheduleDBTask(
+ FROM_HERE,
+ base::Bind(&PaymentManifestWebDataService::AddPaymentMethodManifestImpl,
+ this, payment_method, std::move(app_package_names)));
+}
+
+WebDatabase::State PaymentManifestWebDataService::AddPaymentMethodManifestImpl(
+ const std::string& payment_method,
+ const std::vector<std::string>& app_package_names,
+ WebDatabase* db) {
+ if (PaymentMethodManifestTable::FromWebDatabase(db)->AddManifest(
+ payment_method, app_package_names)) {
+ return WebDatabase::COMMIT_NEEDED;
+ }
+
+ return WebDatabase::COMMIT_NOT_NEEDED;
+}
+
+WebDataServiceBase::Handle
+PaymentManifestWebDataService::GetPaymentWebAppManifest(
+ const std::string& web_app,
+ WebDataServiceConsumer* consumer) {
+ return wdbs_->ScheduleDBTaskWithResult(
+ FROM_HERE,
+ base::Bind(&PaymentManifestWebDataService::GetPaymentWebAppManifestImpl,
+ this, web_app),
+ consumer);
+}
+
+std::unique_ptr<WDTypedResult>
+PaymentManifestWebDataService::GetPaymentWebAppManifestImpl(
+ const std::string& web_app,
+ WebDatabase* db) {
+ RemoveExpiredData(db);
+ return base::MakeUnique<
+ WDResult<std::vector<mojom::WebAppManifestSectionPtr>>>(
+ PAYMENT_WEB_APP_MANIFEST,
+ WebAppManifestSectionTable::FromWebDatabase(db)->GetWebAppManifest(
+ web_app));
+}
+
+WebDataServiceBase::Handle
+PaymentManifestWebDataService::GetPaymentMethodManifest(
+ const std::string& payment_method,
+ WebDataServiceConsumer* consumer) {
+ return wdbs_->ScheduleDBTaskWithResult(
+ FROM_HERE,
+ base::Bind(&PaymentManifestWebDataService::GetPaymentMethodManifestImpl,
+ this, payment_method),
+ consumer);
+}
+
+std::unique_ptr<WDTypedResult>
+PaymentManifestWebDataService::GetPaymentMethodManifestImpl(
+ const std::string& payment_method,
+ WebDatabase* db) {
+ RemoveExpiredData(db);
+ return base::MakeUnique<WDResult<std::vector<std::string>>>(
+ PAYMENT_METHOD_MANIFEST,
+ PaymentMethodManifestTable::FromWebDatabase(db)->GetManifest(
+ payment_method));
+}
+
+void PaymentManifestWebDataService::RemoveExpiredData(WebDatabase* db) {
+ PaymentMethodManifestTable::FromWebDatabase(db)->RemoveExpiredData();
+ WebAppManifestSectionTable::FromWebDatabase(db)->RemoveExpiredData();
+}
+
+} // namespace payments \ No newline at end of file
diff --git a/chromium/components/payments/android/payment_manifest_web_data_service.h b/chromium/components/payments/android/payment_manifest_web_data_service.h
new file mode 100644
index 00000000000..525172722f1
--- /dev/null
+++ b/chromium/components/payments/android/payment_manifest_web_data_service.h
@@ -0,0 +1,70 @@
+// Copyright 2017 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_PAYMENTS_ANDROID_PAYMENT_MANIFEST_WEB_DATA_SERVICE_H_
+#define COMPONENTS_PAYMENTS_ANDROID_PAYMENT_MANIFEST_WEB_DATA_SERVICE_H_
+
+#include "base/memory/ref_counted.h"
+#include "components/payments/android/payment_method_manifest_table.h"
+#include "components/payments/android/web_app_manifest_section_table.h"
+#include "components/webdata/common/web_data_results.h"
+#include "components/webdata/common/web_data_service_base.h"
+#include "components/webdata/common/web_data_service_consumer.h"
+#include "components/webdata/common/web_database_service.h"
+
+namespace payments {
+
+// Web data service to read/write data in WebAppManifestSectionTable and
+// PaymentMethodManifestTable.
+class PaymentManifestWebDataService : public WebDataServiceBase {
+ public:
+ PaymentManifestWebDataService(
+ scoped_refptr<WebDatabaseService> wdbs,
+ const ProfileErrorCallback& callback,
+ const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread);
+
+ // Adds the web app |manifest|.
+ void AddPaymentWebAppManifest(
+ std::vector<mojom::WebAppManifestSectionPtr> manifest);
+
+ // Adds the |payment_method|'s manifest.
+ void AddPaymentMethodManifest(const std::string& payment_method,
+ std::vector<std::string> app_package_names);
+
+ // Gets the |web_app|'s manifest.
+ WebDataServiceBase::Handle GetPaymentWebAppManifest(
+ const std::string& web_app,
+ WebDataServiceConsumer* consumer);
+
+ // Gets the |payment_method|'s manifest.
+ WebDataServiceBase::Handle GetPaymentMethodManifest(
+ const std::string& payment_method,
+ WebDataServiceConsumer* consumer);
+
+ private:
+ ~PaymentManifestWebDataService() override;
+
+ void RemoveExpiredData(WebDatabase* db);
+
+ WebDatabase::State AddPaymentWebAppManifestImpl(
+ const std::vector<mojom::WebAppManifestSectionPtr>& manifest,
+ WebDatabase* db);
+ WebDatabase::State AddPaymentMethodManifestImpl(
+ const std::string& payment_method,
+ const std::vector<std::string>& app_package_names,
+ WebDatabase* db);
+
+ std::unique_ptr<WDTypedResult> GetPaymentWebAppManifestImpl(
+ const std::string& web_app,
+ WebDatabase* db);
+ std::unique_ptr<WDTypedResult> GetPaymentMethodManifestImpl(
+ const std::string& payment_method,
+ WebDatabase* db);
+
+ DISALLOW_COPY_AND_ASSIGN(PaymentManifestWebDataService);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_ANDROID_PAYMENT_MANIFEST_WEB_DATA_SERVICE_H_
diff --git a/chromium/components/payments/android/payment_method_manifest_table.cc b/chromium/components/payments/android/payment_method_manifest_table.cc
index 8e7ac7f3d86..1c79556ed58 100644
--- a/chromium/components/payments/android/payment_method_manifest_table.cc
+++ b/chromium/components/payments/android/payment_method_manifest_table.cc
@@ -4,11 +4,17 @@
#include "components/payments/android/payment_method_manifest_table.h"
+#include <time.h>
+
+#include "base/time/time.h"
#include "sql/statement.h"
#include "sql/transaction.h"
namespace payments {
namespace {
+// Data valid duration in seconds.
+const time_t DATA_VALID_TIME_IN_SECONDS = 90 * 24 * 60 * 60;
+
WebDatabaseTable::TypeKey GetKey() {
// We just need a unique constant. Use the address of a static that
// COMDAT folding won't touch in an optimizing linker.
@@ -32,6 +38,7 @@ WebDatabaseTable::TypeKey PaymentMethodManifestTable::GetTypeKey() const {
bool PaymentMethodManifestTable::CreateTablesIfNecessary() {
if (!db_->Execute("CREATE TABLE IF NOT EXISTS payment_method_manifest ( "
+ "expire_date INTEGER NOT NULL DEFAULT 0, "
"method_name VARCHAR, "
"web_app_id VARCHAR) ")) {
NOTREACHED();
@@ -51,6 +58,14 @@ bool PaymentMethodManifestTable::MigrateToVersion(
return true;
}
+void PaymentMethodManifestTable::RemoveExpiredData() {
+ const time_t now_date_in_seconds = base::Time::NowFromSystemTime().ToTimeT();
+ sql::Statement s(db_->GetUniqueStatement(
+ "DELETE FROM payment_method_manifest WHERE expire_date < ? "));
+ s.BindInt64(0, now_date_in_seconds);
+ s.Run();
+}
+
bool PaymentMethodManifestTable::AddManifest(
const std::string& payment_method,
const std::vector<std::string>& web_app_ids) {
@@ -66,10 +81,13 @@ bool PaymentMethodManifestTable::AddManifest(
sql::Statement s2(
db_->GetUniqueStatement("INSERT INTO payment_method_manifest "
- "(method_name, web_app_id) "
- "VALUES (?, ?) "));
+ "(expire_date, method_name, web_app_id) "
+ "VALUES (?, ?, ?) "));
+ const time_t expire_date_in_seconds =
+ base::Time::NowFromSystemTime().ToTimeT() + DATA_VALID_TIME_IN_SECONDS;
for (const auto& id : web_app_ids) {
int index = 0;
+ s2.BindInt64(index++, expire_date_in_seconds);
s2.BindString(index++, payment_method);
s2.BindString(index, id);
if (!s2.Run())
diff --git a/chromium/components/payments/android/payment_method_manifest_table.h b/chromium/components/payments/android/payment_method_manifest_table.h
index 0e1f5ef9c88..3655f5e3e28 100644
--- a/chromium/components/payments/android/payment_method_manifest_table.h
+++ b/chromium/components/payments/android/payment_method_manifest_table.h
@@ -20,6 +20,9 @@ namespace payments {
// supported web app in this payment method manifest.
// Note that a payment method manifest might contain
// multiple supported web apps ids.
+//
+// expire_date The expire date in seconds from 1601-01-01 00:00:00
+// UTC.
// method_name The method name.
// web_app_id The supported web app id.
// (WebAppManifestSection.id).
@@ -38,6 +41,9 @@ class PaymentMethodManifestTable : public WebDatabaseTable {
bool IsSyncable() override;
bool MigrateToVersion(int version, bool* update_compatible_version) override;
+ // Remove expired data.
+ void RemoveExpiredData();
+
// Adds |payment_method|'s manifest. |web_app_ids| contains supported web apps
// ids.
bool AddManifest(const std::string& payment_method,
diff --git a/chromium/components/payments/android/web_app_manifest_section_table.cc b/chromium/components/payments/android/web_app_manifest_section_table.cc
index f7a06580fd8..ad2529cce5f 100644
--- a/chromium/components/payments/android/web_app_manifest_section_table.cc
+++ b/chromium/components/payments/android/web_app_manifest_section_table.cc
@@ -5,13 +5,17 @@
#include "components/payments/android/web_app_manifest_section_table.h"
#include <stdint.h>
-
+#include <time.h>
#include <memory>
+#include "base/time/time.h"
#include "sql/statement.h"
+#include "sql/transaction.h"
namespace payments {
namespace {
+// Data valid duration in seconds.
+const time_t DATA_VALID_TIME_IN_SECONDS = 90 * 24 * 60 * 60;
// Note that the fingerprint is calculated with SHA-256.
const size_t kFingerPrintLength = 32;
@@ -71,7 +75,8 @@ WebDatabaseTable::TypeKey WebAppManifestSectionTable::GetTypeKey() const {
bool WebAppManifestSectionTable::CreateTablesIfNecessary() {
if (!db_->Execute("CREATE TABLE IF NOT EXISTS web_app_manifest_section ( "
- "id VARCHAR PRIMARY KEY, "
+ "expire_date INTEGER NOT NULL DEFAULT 0, "
+ "id VARCHAR, "
"min_version INTEGER NOT NULL DEFAULT 0, "
"fingerprints BLOB) ")) {
NOTREACHED();
@@ -91,52 +96,85 @@ bool WebAppManifestSectionTable::MigrateToVersion(
return true;
}
+void WebAppManifestSectionTable::RemoveExpiredData() {
+ const time_t now_date_in_seconds = base::Time::NowFromSystemTime().ToTimeT();
+ sql::Statement s(db_->GetUniqueStatement(
+ "DELETE FROM web_app_manifest_section WHERE expire_date < ? "));
+ s.BindInt64(0, now_date_in_seconds);
+ s.Run();
+}
+
bool WebAppManifestSectionTable::AddWebAppManifest(
- mojom::WebAppManifestSection* manifest) {
- DCHECK(manifest);
- DCHECK(!manifest->id.empty());
+ const std::vector<mojom::WebAppManifestSectionPtr>& manifest) {
+ DCHECK_LT(0U, manifest.size());
- sql::Statement s(
- db_->GetUniqueStatement("INSERT OR REPLACE INTO web_app_manifest_section "
- "(id, min_version, fingerprints) "
- "VALUES (?, ?, ?)"));
- int index = 0;
- s.BindString(index++, manifest->id);
- s.BindInt64(index++, manifest->min_version);
- std::unique_ptr<std::vector<uint8_t>> serialized_fingerprints =
- SerializeFingerPrints(manifest->fingerprints);
- s.BindBlob(index, serialized_fingerprints->data(),
- serialized_fingerprints->size());
- if (!s.Run())
+ sql::Transaction transaction(db_);
+ if (!transaction.Begin())
+ return false;
+
+ sql::Statement s1(db_->GetUniqueStatement(
+ "DELETE FROM web_app_manifest_section WHERE id=? "));
+ s1.BindString(0, manifest[0]->id);
+ if (!s1.Run())
+ return false;
+
+ sql::Statement s2(
+ db_->GetUniqueStatement("INSERT INTO web_app_manifest_section "
+ "(expire_date, id, min_version, fingerprints) "
+ "VALUES (?, ?, ?, ?)"));
+ const time_t expire_date_in_seconds =
+ base::Time::NowFromSystemTime().ToTimeT() + DATA_VALID_TIME_IN_SECONDS;
+ for (const auto& section : manifest) {
+ DCHECK_EQ(manifest[0]->id, section->id);
+ int index = 0;
+ s2.BindInt64(index++, expire_date_in_seconds);
+ s2.BindString(index++, section->id);
+ s2.BindInt64(index++, section->min_version);
+ std::unique_ptr<std::vector<uint8_t>> serialized_fingerprints =
+ SerializeFingerPrints(section->fingerprints);
+ s2.BindBlob(index, serialized_fingerprints->data(),
+ serialized_fingerprints->size());
+ if (!s2.Run())
+ return false;
+ s2.Reset(true);
+ }
+
+ if (!transaction.Commit())
return false;
return true;
}
-mojom::WebAppManifestSectionPtr WebAppManifestSectionTable::GetWebAppManifest(
- const std::string& web_app) {
+std::vector<mojom::WebAppManifestSectionPtr>
+WebAppManifestSectionTable::GetWebAppManifest(const std::string& web_app) {
sql::Statement s(
db_->GetUniqueStatement("SELECT id, min_version, fingerprints "
"FROM web_app_manifest_section "
"WHERE id=?"));
s.BindString(0, web_app);
- if (!s.Step())
- return nullptr;
+ std::vector<mojom::WebAppManifestSectionPtr> manifest;
+ while (s.Step()) {
+ mojom::WebAppManifestSectionPtr section =
+ mojom::WebAppManifestSection::New();
- mojom::WebAppManifestSectionPtr manifest =
- mojom::WebAppManifestSection::New();
+ int index = 0;
+ section->id = s.ColumnString(index++);
+ section->min_version = s.ColumnInt64(index++);
- int index = 0;
- manifest->id = s.ColumnString(index++);
- manifest->min_version = s.ColumnInt64(index++);
+ std::vector<uint8_t> fingerprints;
+ if (!s.ColumnBlobAsVector(index, &fingerprints)) {
+ manifest.clear();
+ break;
+ }
- std::vector<uint8_t> fingerprints;
- if (!s.ColumnBlobAsVector(index, &fingerprints))
- return nullptr;
+ if (!DeserializeFingerPrints(fingerprints, section->fingerprints)) {
+ manifest.clear();
+ break;
+ }
- if (!DeserializeFingerPrints(fingerprints, manifest->fingerprints))
- return nullptr;
+ manifest.emplace_back(std::move(section));
+ }
return manifest;
}
diff --git a/chromium/components/payments/android/web_app_manifest_section_table.h b/chromium/components/payments/android/web_app_manifest_section_table.h
index 44a5c046a75..f39922d2a73 100644
--- a/chromium/components/payments/android/web_app_manifest_section_table.h
+++ b/chromium/components/payments/android/web_app_manifest_section_table.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "components/payments/content/payment_manifest_parser.mojom.h"
+#include "components/payments/mojom/payment_manifest_parser.mojom.h"
#include "components/webdata/common/web_database.h"
#include "components/webdata/common/web_database_table.h"
@@ -21,6 +21,8 @@ namespace payments {
// web_app_manifest_section The table stores the contents in
// WebAppManifestSection.
//
+// expire_date The data expire date in seconds from 1601-01-01
+// 00:00:00 UTC.
// id The package name of the app.
// min_version Minimum version number of the app.
// fingerprints The result of SHA256(signing certificate bytes) for
@@ -40,13 +42,18 @@ class WebAppManifestSectionTable : public WebDatabaseTable {
bool IsSyncable() override;
bool MigrateToVersion(int version, bool* update_compatible_version) override;
- // Adds the web app |*manifest|. Note that the previous web app manifest will
+ // Remove expired data.
+ void RemoveExpiredData();
+
+ // Adds the web app |manifest|. Note that the previous web app manifest will
// be deleted.
- bool AddWebAppManifest(mojom::WebAppManifestSection* manifest);
+ bool AddWebAppManifest(
+ const std::vector<mojom::WebAppManifestSectionPtr>& manifest);
- // Gets manifest of the |web_app|. Returns nullptr if no manifest exists for
- // the |web_app|.
- mojom::WebAppManifestSectionPtr GetWebAppManifest(const std::string& web_app);
+ // Gets manifest of the |web_app|. Returns empty vector if no manifest exists
+ // for the |web_app|.
+ std::vector<mojom::WebAppManifestSectionPtr> GetWebAppManifest(
+ const std::string& web_app);
private:
DISALLOW_COPY_AND_ASSIGN(WebAppManifestSectionTable);
diff --git a/chromium/components/payments/android/web_app_manifest_section_table_unittest.cc b/chromium/components/payments/android/web_app_manifest_section_table_unittest.cc
index 900cb34589d..97c82f2d262 100644
--- a/chromium/components/payments/android/web_app_manifest_section_table_unittest.cc
+++ b/chromium/components/payments/android/web_app_manifest_section_table_unittest.cc
@@ -50,9 +50,9 @@ class WebAppManifestSectionTableTest : public testing::Test {
TEST_F(WebAppManifestSectionTableTest, GetNonExistManifest) {
WebAppManifestSectionTable* web_app_manifest_section_table =
WebAppManifestSectionTable::FromWebDatabase(db_.get());
- mojom::WebAppManifestSectionPtr retrieved_manifest =
+ std::vector<mojom::WebAppManifestSectionPtr> retrieved_manifest =
web_app_manifest_section_table->GetWebAppManifest("https://bobpay.com");
- ASSERT_TRUE(retrieved_manifest.get() == nullptr);
+ ASSERT_TRUE(retrieved_manifest.empty());
}
TEST_F(WebAppManifestSectionTableTest, AddAndGetManifest) {
@@ -60,29 +60,30 @@ TEST_F(WebAppManifestSectionTableTest, AddAndGetManifest) {
std::vector<uint8_t> fingerprint_two = GenerateFingerprint(32);
// create a bobpay web app manifest.
- mojom::WebAppManifestSectionPtr manifest =
- mojom::WebAppManifestSection::New();
- manifest->id = "com.bobpay";
- manifest->min_version = static_cast<int64_t>(1);
- manifest->fingerprints.push_back(fingerprint_one);
- manifest->fingerprints.push_back(fingerprint_two);
+ std::vector<mojom::WebAppManifestSectionPtr> manifest;
+ mojom::WebAppManifestSectionPtr section = mojom::WebAppManifestSection::New();
+ section->id = "com.bobpay";
+ section->min_version = static_cast<int64_t>(1);
+ section->fingerprints.push_back(fingerprint_one);
+ section->fingerprints.push_back(fingerprint_two);
+ manifest.emplace_back(std::move(section));
// Adds the manifest to the table.
WebAppManifestSectionTable* web_app_manifest_section_table =
WebAppManifestSectionTable::FromWebDatabase(db_.get());
- ASSERT_TRUE(
- web_app_manifest_section_table->AddWebAppManifest(manifest.get()));
+ ASSERT_TRUE(web_app_manifest_section_table->AddWebAppManifest(manifest));
// Gets and verifys the manifest.
- mojom::WebAppManifestSectionPtr retrieved_manifest =
+ std::vector<mojom::WebAppManifestSectionPtr> retrieved_manifest =
web_app_manifest_section_table->GetWebAppManifest("com.bobpay");
- ASSERT_EQ(retrieved_manifest->id, "com.bobpay");
- ASSERT_EQ(retrieved_manifest->min_version, 1);
- ASSERT_EQ(retrieved_manifest->fingerprints.size(), 2U);
+ ASSERT_EQ(retrieved_manifest.size(), 1U);
+ ASSERT_EQ(retrieved_manifest[0]->id, "com.bobpay");
+ ASSERT_EQ(retrieved_manifest[0]->min_version, 1);
+ ASSERT_EQ(retrieved_manifest[0]->fingerprints.size(), 2U);
// Verify the two fingerprints.
- ASSERT_TRUE(retrieved_manifest->fingerprints[0] == fingerprint_one);
- ASSERT_TRUE(retrieved_manifest->fingerprints[1] == fingerprint_two);
+ ASSERT_TRUE(retrieved_manifest[0]->fingerprints[0] == fingerprint_one);
+ ASSERT_TRUE(retrieved_manifest[0]->fingerprints[1] == fingerprint_two);
}
TEST_F(WebAppManifestSectionTableTest, AddAndGetMultipleManifests) {
@@ -95,44 +96,48 @@ TEST_F(WebAppManifestSectionTableTest, AddAndGetMultipleManifests) {
WebAppManifestSectionTable::FromWebDatabase(db_.get());
// Adds bobpay manifest to the table.
- mojom::WebAppManifestSectionPtr manifest_1 =
+ std::vector<mojom::WebAppManifestSectionPtr> manifest_1;
+ mojom::WebAppManifestSectionPtr manifest_1_section =
mojom::WebAppManifestSection::New();
- manifest_1->id = "com.bobpay";
- manifest_1->min_version = static_cast<int64_t>(1);
+ manifest_1_section->id = "com.bobpay";
+ manifest_1_section->min_version = static_cast<int64_t>(1);
// Adds two finger prints.
- manifest_1->fingerprints.push_back(fingerprint_one);
- manifest_1->fingerprints.push_back(fingerprint_two);
- ASSERT_TRUE(
- web_app_manifest_section_table->AddWebAppManifest(manifest_1.get()));
+ manifest_1_section->fingerprints.push_back(fingerprint_one);
+ manifest_1_section->fingerprints.push_back(fingerprint_two);
+ manifest_1.emplace_back(std::move(manifest_1_section));
+ ASSERT_TRUE(web_app_manifest_section_table->AddWebAppManifest(manifest_1));
// Adds alicepay manifest to the table.
- mojom::WebAppManifestSectionPtr manifest_2 =
+ std::vector<mojom::WebAppManifestSectionPtr> manifest_2;
+ mojom::WebAppManifestSectionPtr manifest_2_section =
mojom::WebAppManifestSection::New();
- manifest_2->id = "com.alicepay";
- manifest_2->min_version = static_cast<int64_t>(2);
+ manifest_2_section->id = "com.alicepay";
+ manifest_2_section->min_version = static_cast<int64_t>(2);
// Adds two finger prints.
- manifest_2->fingerprints.push_back(fingerprint_three);
- manifest_2->fingerprints.push_back(fingerprint_four);
- ASSERT_TRUE(
- web_app_manifest_section_table->AddWebAppManifest(manifest_2.get()));
+ manifest_2_section->fingerprints.push_back(fingerprint_three);
+ manifest_2_section->fingerprints.push_back(fingerprint_four);
+ manifest_2.emplace_back(std::move(manifest_2_section));
+ ASSERT_TRUE(web_app_manifest_section_table->AddWebAppManifest(manifest_2));
// Verifys bobpay manifest.
- mojom::WebAppManifestSectionPtr bobpay_manifest =
+ std::vector<mojom::WebAppManifestSectionPtr> bobpay_manifest =
web_app_manifest_section_table->GetWebAppManifest("com.bobpay");
- ASSERT_EQ(bobpay_manifest->id, "com.bobpay");
- ASSERT_EQ(bobpay_manifest->min_version, 1);
- ASSERT_EQ(bobpay_manifest->fingerprints.size(), 2U);
- ASSERT_TRUE(bobpay_manifest->fingerprints[0] == fingerprint_one);
- ASSERT_TRUE(bobpay_manifest->fingerprints[1] == fingerprint_two);
+ ASSERT_EQ(bobpay_manifest.size(), 1U);
+ ASSERT_EQ(bobpay_manifest[0]->id, "com.bobpay");
+ ASSERT_EQ(bobpay_manifest[0]->min_version, 1);
+ ASSERT_EQ(bobpay_manifest[0]->fingerprints.size(), 2U);
+ ASSERT_TRUE(bobpay_manifest[0]->fingerprints[0] == fingerprint_one);
+ ASSERT_TRUE(bobpay_manifest[0]->fingerprints[1] == fingerprint_two);
// Verifys alicepay manifest.
- mojom::WebAppManifestSectionPtr alicepay_manifest =
+ std::vector<mojom::WebAppManifestSectionPtr> alicepay_manifest =
web_app_manifest_section_table->GetWebAppManifest("com.alicepay");
- ASSERT_EQ(alicepay_manifest->id, "com.alicepay");
- ASSERT_EQ(alicepay_manifest->min_version, 2);
- ASSERT_EQ(alicepay_manifest->fingerprints.size(), 2U);
- ASSERT_TRUE(alicepay_manifest->fingerprints[0] == fingerprint_three);
- ASSERT_TRUE(alicepay_manifest->fingerprints[1] == fingerprint_four);
+ ASSERT_EQ(alicepay_manifest.size(), 1U);
+ ASSERT_EQ(alicepay_manifest[0]->id, "com.alicepay");
+ ASSERT_EQ(alicepay_manifest[0]->min_version, 2);
+ ASSERT_EQ(alicepay_manifest[0]->fingerprints.size(), 2U);
+ ASSERT_TRUE(alicepay_manifest[0]->fingerprints[0] == fingerprint_three);
+ ASSERT_TRUE(alicepay_manifest[0]->fingerprints[1] == fingerprint_four);
}
} // namespace
diff --git a/chromium/components/payments/content/BUILD.gn b/chromium/components/payments/content/BUILD.gn
index a20079996c5..6396049b0ce 100644
--- a/chromium/components/payments/content/BUILD.gn
+++ b/chromium/components/payments/content/BUILD.gn
@@ -2,10 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//mojo/public/tools/bindings/mojom.gni")
-
static_library("content") {
sources = [
+ "can_make_payment_query_factory.cc",
+ "can_make_payment_query_factory.h",
"payment_request.cc",
"payment_request.h",
"payment_request_dialog.h",
@@ -20,46 +20,23 @@ static_library("content") {
]
deps = [
- ":mojom",
":utils",
"//components/autofill/core/browser",
+ "//components/keyed_service/content",
"//components/payments/core",
+ "//components/payments/mojom",
+ "//components/prefs",
+ "//components/strings:components_strings_grit",
"//content/public/browser",
"//mojo/public/cpp/bindings",
"//third_party/libphonenumber",
]
}
-mojom("mojom") {
- sources = [
- "payment_request.mojom",
- ]
-}
-
-mojom("mojom_parser") {
- sources = [
- "payment_manifest_parser.mojom",
- ]
-
- public_deps = [
- "//url/mojo:url_mojom_gurl",
- ]
-}
-
-mojom("mojom_payment_app") {
- sources = [
- "payment_app.mojom",
- ]
-
- public_deps = [
- ":mojom",
- "//mojo/common:common_custom_types",
- "//url/mojo:url_mojom_gurl",
- ]
-}
-
static_library("utils") {
sources = [
+ "origin_security_checker.cc",
+ "origin_security_checker.h",
"payment_details_validation.cc",
"payment_details_validation.h",
"payment_manifest_downloader.cc",
@@ -71,13 +48,13 @@ static_library("utils") {
]
deps = [
- ":mojom",
- ":mojom_parser",
"//base",
"//components/autofill/core/browser",
"//components/data_use_measurement/core",
"//components/link_header_util",
"//components/payments/core",
+ "//components/payments/mojom",
+ "//components/payments/mojom:mojom_parser",
"//components/strings",
"//content/public/browser",
"//net",
@@ -104,13 +81,15 @@ source_set("unit_tests") {
deps = [
":content",
- ":mojom",
":utils",
"//base",
"//base/test:test_support",
"//components/autofill/core/browser",
"//components/autofill/core/browser:test_support",
"//components/payments/core",
+ "//components/payments/core:test_support",
+ "//components/payments/mojom",
+ "//components/strings:components_strings_grit",
"//content/test:test_support",
"//net:test_support",
"//testing/gtest",
diff --git a/chromium/components/payments/content/DEPS b/chromium/components/payments/content/DEPS
index 548a1642252..de79a74acf5 100644
--- a/chromium/components/payments/content/DEPS
+++ b/chromium/components/payments/content/DEPS
@@ -3,7 +3,9 @@ include_rules = [
"-components/payments/content/utility",
"+components/autofill",
"+components/data_use_measurement",
+ "+components/keyed_service/content",
"+components/link_header_util",
+ "+components/prefs",
"+components/strings",
"+content/public",
"+mojo/public/cpp",
diff --git a/chromium/components/payments/content/OWNERS b/chromium/components/payments/content/OWNERS
index 82559c92e72..913eb47bf91 100644
--- a/chromium/components/payments/content/OWNERS
+++ b/chromium/components/payments/content/OWNERS
@@ -1,4 +1,3 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
+per-file payment_response_helper*=sebsg@chromium.org
# COMPONENT: UI>Browser>Autofill>Payments
diff --git a/chromium/components/payments/content/android/BUILD.gn b/chromium/components/payments/content/android/BUILD.gn
index 609224f1487..c11f428b301 100644
--- a/chromium/components/payments/content/android/BUILD.gn
+++ b/chromium/components/payments/content/android/BUILD.gn
@@ -12,6 +12,8 @@ static_library("android") {
"component_jni_registrar.h",
"currency_formatter_android.cc",
"currency_formatter_android.h",
+ "origin_security_checker_android.cc",
+ "origin_security_checker_android.h",
"payment_details_validation_android.cc",
"payment_details_validation_android.h",
"payment_manifest_downloader_android.cc",
@@ -22,9 +24,9 @@ static_library("android") {
deps = [
":jni_headers",
"//base",
- "//components/payments/content:mojom",
"//components/payments/content:utils",
"//components/payments/core",
+ "//components/payments/mojom",
"//content/public/browser",
"//net",
]
@@ -33,6 +35,7 @@ static_library("android") {
generate_jni("jni_headers") {
sources = [
"java/src/org/chromium/components/payments/CurrencyFormatter.java",
+ "java/src/org/chromium/components/payments/OriginSecurityChecker.java",
"java/src/org/chromium/components/payments/PaymentManifestDownloader.java",
"java/src/org/chromium/components/payments/PaymentManifestParser.java",
"java/src/org/chromium/components/payments/PaymentValidator.java",
@@ -43,14 +46,15 @@ generate_jni("jni_headers") {
android_library("java") {
java_files = [
"java/src/org/chromium/components/payments/CurrencyFormatter.java",
+ "java/src/org/chromium/components/payments/OriginSecurityChecker.java",
"java/src/org/chromium/components/payments/PaymentManifestDownloader.java",
"java/src/org/chromium/components/payments/PaymentManifestParser.java",
"java/src/org/chromium/components/payments/PaymentValidator.java",
]
deps = [
"//base:base_java",
- "//components/payments/content:mojom_java",
- "//components/payments/content:mojom_parser_java",
+ "//components/payments/mojom:mojom_java",
+ "//components/payments/mojom:mojom_parser_java",
"//content/public/android:content_java",
"//mojo/public/java:bindings_java",
]
diff --git a/chromium/components/payments/content/android/OWNERS b/chromium/components/payments/content/android/OWNERS
index 08850f42120..e39fa27b510 100644
--- a/chromium/components/payments/content/android/OWNERS
+++ b/chromium/components/payments/content/android/OWNERS
@@ -1,2 +1,3 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
+gogerald@chromium.org
+
+# COMPONENT: UI>Browser>Autofill>Payments
diff --git a/chromium/components/payments/content/android/origin_security_checker_android.cc b/chromium/components/payments/content/android/origin_security_checker_android.cc
new file mode 100644
index 00000000000..1ca7d1f2a5c
--- /dev/null
+++ b/chromium/components/payments/content/android/origin_security_checker_android.cc
@@ -0,0 +1,49 @@
+// Copyright 2017 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/payments/content/android/origin_security_checker_android.h"
+
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "components/payments/content/origin_security_checker.h"
+#include "content/public/browser/web_contents.h"
+#include "jni/OriginSecurityChecker_jni.h"
+
+namespace payments {
+namespace {
+
+using ::base::android::JavaParamRef;
+using ::base::android::ConvertJavaStringToUTF8;
+
+} // namespace
+
+// static
+jboolean IsOriginSecure(JNIEnv* env,
+ const JavaParamRef<jclass>& jcaller,
+ const JavaParamRef<jstring>& jurl) {
+ return OriginSecurityChecker::IsOriginSecure(
+ GURL(ConvertJavaStringToUTF8(env, jurl)));
+}
+
+// static
+jboolean IsSchemeCryptographic(JNIEnv* env,
+ const JavaParamRef<jclass>& jcaller,
+ const JavaParamRef<jstring>& jurl) {
+ return OriginSecurityChecker::IsSchemeCryptographic(
+ GURL(ConvertJavaStringToUTF8(env, jurl)));
+}
+
+// static
+jboolean IsOriginLocalhostOrFile(JNIEnv* env,
+ const JavaParamRef<jclass>& jcaller,
+ const JavaParamRef<jstring>& jurl) {
+ return OriginSecurityChecker::IsOriginLocalhostOrFile(
+ GURL(ConvertJavaStringToUTF8(env, jurl)));
+}
+
+bool RegisterOriginSecurityChecker(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/content/android/origin_security_checker_android.h b/chromium/components/payments/content/android/origin_security_checker_android.h
new file mode 100644
index 00000000000..d44138984b5
--- /dev/null
+++ b/chromium/components/payments/content/android/origin_security_checker_android.h
@@ -0,0 +1,16 @@
+// Copyright 2017 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_PAYMENTS_CONTENT_ANDROID_ORIGIN_SECURITY_CHECKER_ANDROID_H_
+#define COMPONENTS_PAYMENTS_CONTENT_ANDROID_ORIGIN_SECURITY_CHECKER_ANDROID_H_
+
+#include <jni.h>
+
+namespace payments {
+
+bool RegisterOriginSecurityChecker(JNIEnv* env);
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CONTENT_ANDROID_ORIGIN_SECURITY_CHECKER_ANDROID_H_
diff --git a/chromium/components/payments/content/android/payment_details_validation_android.cc b/chromium/components/payments/content/android/payment_details_validation_android.cc
index ddc7ffc4951..fa88d63a61d 100644
--- a/chromium/components/payments/content/android/payment_details_validation_android.cc
+++ b/chromium/components/payments/content/android/payment_details_validation_android.cc
@@ -13,7 +13,7 @@
#include "base/android/jni_android.h"
#include "components/payments/content/payment_details_validation.h"
-#include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/mojom/payment_request.mojom.h"
#include "jni/PaymentValidator_jni.h"
namespace payments {
diff --git a/chromium/components/payments/content/can_make_payment_query_factory.cc b/chromium/components/payments/content/can_make_payment_query_factory.cc
new file mode 100644
index 00000000000..2f8817302dc
--- /dev/null
+++ b/chromium/components/payments/content/can_make_payment_query_factory.cc
@@ -0,0 +1,36 @@
+// Copyright 2017 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/payments/content/can_make_payment_query_factory.h"
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/payments/core/can_make_payment_query.h"
+
+namespace payments {
+
+// static
+CanMakePaymentQueryFactory* CanMakePaymentQueryFactory::GetInstance() {
+ return base::Singleton<CanMakePaymentQueryFactory>::get();
+}
+
+CanMakePaymentQuery* CanMakePaymentQueryFactory::GetForContext(
+ content::BrowserContext* context) {
+ return static_cast<CanMakePaymentQuery*>(
+ GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+CanMakePaymentQueryFactory::CanMakePaymentQueryFactory()
+ : BrowserContextKeyedServiceFactory(
+ "CanMakePaymentQuery",
+ BrowserContextDependencyManager::GetInstance()) {}
+
+CanMakePaymentQueryFactory::~CanMakePaymentQueryFactory() {}
+
+KeyedService* CanMakePaymentQueryFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new CanMakePaymentQuery;
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/content/can_make_payment_query_factory.h b/chromium/components/payments/content/can_make_payment_query_factory.h
new file mode 100644
index 00000000000..3d67e036899
--- /dev/null
+++ b/chromium/components/payments/content/can_make_payment_query_factory.h
@@ -0,0 +1,46 @@
+// Copyright 2017 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_PAYMENTS_CONTENT_CAN_MAKE_PAYMENT_QUERY_FACTORY_H_
+#define COMPONENTS_PAYMENTS_CONTENT_CAN_MAKE_PAYMENT_QUERY_FACTORY_H_
+
+#include "base/macros.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}
+
+namespace content {
+class BrowserContext;
+}
+
+namespace payments {
+
+class CanMakePaymentQuery;
+
+// Ensures that there's only one instance of CanMakePaymentQuery per browser
+// context.
+class CanMakePaymentQueryFactory : public BrowserContextKeyedServiceFactory {
+ public:
+ static CanMakePaymentQueryFactory* GetInstance();
+ CanMakePaymentQuery* GetForContext(content::BrowserContext* context);
+
+ private:
+ friend struct base::DefaultSingletonTraits<CanMakePaymentQueryFactory>;
+
+ CanMakePaymentQueryFactory();
+ ~CanMakePaymentQueryFactory() override;
+
+ // BrowserContextKeyedServiceFactory:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+
+ DISALLOW_COPY_AND_ASSIGN(CanMakePaymentQueryFactory);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CONTENT_CAN_MAKE_PAYMENT_QUERY_FACTORY_H_
diff --git a/chromium/components/payments/content/origin_security_checker.cc b/chromium/components/payments/content/origin_security_checker.cc
new file mode 100644
index 00000000000..20986082d47
--- /dev/null
+++ b/chromium/components/payments/content/origin_security_checker.cc
@@ -0,0 +1,29 @@
+// Copyright 2017 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/payments/content/origin_security_checker.h"
+
+#include "content/public/common/origin_util.h"
+#include "net/base/url_util.h"
+#include "url/gurl.h"
+
+namespace payments {
+
+// static
+bool OriginSecurityChecker::IsOriginSecure(const GURL& url) {
+ return url.is_valid() && content::IsOriginSecure(url);
+}
+
+// static
+bool OriginSecurityChecker::IsSchemeCryptographic(const GURL& url) {
+ return url.is_valid() && url.SchemeIsCryptographic();
+}
+
+// static
+bool OriginSecurityChecker::IsOriginLocalhostOrFile(const GURL& url) {
+ return url.is_valid() &&
+ (net::IsLocalhost(url.HostNoBrackets()) || url.SchemeIsFile());
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/content/origin_security_checker.h b/chromium/components/payments/content/origin_security_checker.h
new file mode 100644
index 00000000000..818188d321c
--- /dev/null
+++ b/chromium/components/payments/content/origin_security_checker.h
@@ -0,0 +1,32 @@
+// Copyright 2017 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_PAYMENTS_CONTENT_ORIGIN_SECURITY_CHECKER_H_
+#define COMPONENTS_PAYMENTS_CONTENT_ORIGIN_SECURITY_CHECKER_H_
+
+#include "base/macros.h"
+
+class GURL;
+
+namespace payments {
+
+class OriginSecurityChecker {
+ public:
+ // Returns true for a valid |url| from a secure origin.
+ static bool IsOriginSecure(const GURL& url);
+
+ // Returns true for a valid |url| with a cryptographic scheme, e.g., HTTPS,
+ // HTTPS-SO, WSS.
+ static bool IsSchemeCryptographic(const GURL& url);
+
+ // Returns true for a valid |url| with localhost or file:// scheme origin.
+ static bool IsOriginLocalhostOrFile(const GURL& url);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(OriginSecurityChecker);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CONTENT_ORIGIN_SECURITY_CHECKER_H_
diff --git a/chromium/components/payments/content/payment_app.mojom b/chromium/components/payments/content/payment_app.mojom
deleted file mode 100644
index a980ddcf8a8..00000000000
--- a/chromium/components/payments/content/payment_app.mojom
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2016 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.
-
-module payments.mojom;
-
-import "components/payments/content/payment_request.mojom";
-import "mojo/common/time.mojom";
-import "url/mojo/url.mojom";
-
-enum PaymentAppManifestError {
- NONE,
- NOT_IMPLEMENTED,
- NO_ACTIVE_WORKER,
- MANIFEST_STORAGE_OPERATION_FAILED,
-};
-
-struct PaymentAppOption {
- string name;
- string? icon;
- string id;
- array<string> enabled_methods;
-};
-
-struct PaymentAppManifest {
- string name;
- string? icon;
- array<PaymentAppOption> options;
-};
-
-interface PaymentManager {
- Init(string service_worker_scope);
- SetManifest(PaymentAppManifest payment_app_manifest)
- => (PaymentAppManifestError error);
- GetManifest()
- => (PaymentAppManifest payment_app_manifest, PaymentAppManifestError error);
-};
-
-struct PaymentAppRequest {
- url.mojom.Url origin;
- array<PaymentMethodData> methodData;
- PaymentItem total;
- array<PaymentDetailsModifier> modifiers;
- string optionId;
-};
-
-struct PaymentAppResponse {
- string method_name;
- string stringified_details;
-};
-
-// This interface is provided to pass a payment app response from payment
-// request event in renderer side to browser side by calling respondWith().
-interface PaymentAppResponseCallback {
- OnPaymentAppResponse(PaymentAppResponse response,
- mojo.common.mojom.Time dispatch_event_time);
-};
diff --git a/chromium/components/payments/content/payment_details_validation.cc b/chromium/components/payments/content/payment_details_validation.cc
index 351e82c961b..e953cfb70dc 100644
--- a/chromium/components/payments/content/payment_details_validation.cc
+++ b/chromium/components/payments/content/payment_details_validation.cc
@@ -7,8 +7,8 @@
#include <set>
#include <vector>
-#include "components/payments/content/payment_request.mojom.h"
#include "components/payments/content/payments_validators.h"
+#include "components/payments/mojom/payment_request.mojom.h"
namespace payments {
namespace {
@@ -20,11 +20,6 @@ bool validateShippingOptionOrPaymentItem(
const T& item,
const payments::mojom::PaymentItemPtr& total,
std::string* error_message) {
- if (item->label.empty()) {
- *error_message = "Item label required";
- return false;
- }
-
if (!item->amount) {
*error_message = "Currency amount required";
return false;
@@ -40,11 +35,6 @@ bool validateShippingOptionOrPaymentItem(
return false;
}
- if (total && item->amount->currency != total->amount->currency) {
- *error_message = "Currencies must all be equal";
- return false;
- }
-
if (item->amount->currency_system.empty()) {
*error_message = "Currency system can't be empty";
return false;
diff --git a/chromium/components/payments/content/payment_details_validation.h b/chromium/components/payments/content/payment_details_validation.h
index e6230876a1c..fda9990749b 100644
--- a/chromium/components/payments/content/payment_details_validation.h
+++ b/chromium/components/payments/content/payment_details_validation.h
@@ -7,7 +7,7 @@
#include <string>
-#include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/mojom/payment_request.mojom.h"
namespace payments {
diff --git a/chromium/components/payments/content/payment_manifest_parser_host.h b/chromium/components/payments/content/payment_manifest_parser_host.h
index 2873bdf6d62..eb6887554c7 100644
--- a/chromium/components/payments/content/payment_manifest_parser_host.h
+++ b/chromium/components/payments/content/payment_manifest_parser_host.h
@@ -13,7 +13,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
-#include "components/payments/content/payment_manifest_parser.mojom.h"
+#include "components/payments/mojom/payment_manifest_parser.mojom.h"
#include "url/gurl.h"
namespace content {
diff --git a/chromium/components/payments/content/payment_request.cc b/chromium/components/payments/content/payment_request.cc
index 15aee2c6791..1363bb50a08 100644
--- a/chromium/components/payments/content/payment_request.cc
+++ b/chromium/components/payments/content/payment_request.cc
@@ -8,24 +8,35 @@
#include <utility>
#include "base/memory/ptr_util.h"
+#include "components/payments/content/can_make_payment_query_factory.h"
+#include "components/payments/content/origin_security_checker.h"
#include "components/payments/content/payment_details_validation.h"
#include "components/payments/content/payment_request_web_contents_manager.h"
+#include "components/payments/core/can_make_payment_query.h"
+#include "components/payments/core/payment_prefs.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
namespace payments {
PaymentRequest::PaymentRequest(
+ content::RenderFrameHost* render_frame_host,
content::WebContents* web_contents,
std::unique_ptr<PaymentRequestDelegate> delegate,
PaymentRequestWebContentsManager* manager,
- mojo::InterfaceRequest<payments::mojom::PaymentRequest> request,
+ mojo::InterfaceRequest<mojom::PaymentRequest> request,
ObserverForTest* observer_for_testing)
: web_contents_(web_contents),
delegate_(std::move(delegate)),
manager_(manager),
binding_(this, std::move(request)),
- observer_for_testing_(observer_for_testing) {
+ frame_origin_(GURL(render_frame_host->GetLastCommittedURL()).GetOrigin()),
+ observer_for_testing_(observer_for_testing),
+ journey_logger_(delegate_->IsIncognito(),
+ web_contents_->GetLastCommittedURL(),
+ delegate_->GetUkmRecorder()) {
// OnConnectionTerminated will be called when the Mojo pipe is closed. This
// will happen as a result of many renderer-side events (both successful and
// erroneous in nature).
@@ -37,24 +48,60 @@ PaymentRequest::PaymentRequest(
PaymentRequest::~PaymentRequest() {}
-void PaymentRequest::Init(
- payments::mojom::PaymentRequestClientPtr client,
- std::vector<payments::mojom::PaymentMethodDataPtr> method_data,
- payments::mojom::PaymentDetailsPtr details,
- payments::mojom::PaymentOptionsPtr options) {
+void PaymentRequest::Init(mojom::PaymentRequestClientPtr client,
+ std::vector<mojom::PaymentMethodDataPtr> method_data,
+ mojom::PaymentDetailsPtr details,
+ mojom::PaymentOptionsPtr options) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ client_ = std::move(client);
+
+ const GURL last_committed_url = delegate_->GetLastCommittedURL();
+ if (!OriginSecurityChecker::IsOriginSecure(last_committed_url)) {
+ LOG(ERROR) << "Not in a secure origin";
+ OnConnectionTerminated();
+ return;
+ }
+
+ bool allowed_origin =
+ OriginSecurityChecker::IsSchemeCryptographic(last_committed_url) ||
+ OriginSecurityChecker::IsOriginLocalhostOrFile(last_committed_url);
+ if (!allowed_origin) {
+ LOG(ERROR) << "Only localhost, file://, and cryptographic scheme origins "
+ "allowed";
+ }
+
+ bool invalid_ssl =
+ OriginSecurityChecker::IsSchemeCryptographic(last_committed_url) &&
+ !delegate_->IsSslCertificateValid();
+ if (invalid_ssl)
+ LOG(ERROR) << "SSL certificate is not valid";
+
+ if (!allowed_origin || invalid_ssl) {
+ // Don't show UI. Resolve .canMakepayment() with "false". Reject .show()
+ // with "NotSupportedError".
+ spec_ = base::MakeUnique<PaymentRequestSpec>(
+ mojom::PaymentOptions::New(), mojom::PaymentDetails::New(),
+ std::vector<mojom::PaymentMethodDataPtr>(), this,
+ delegate_->GetApplicationLocale());
+ state_ = base::MakeUnique<PaymentRequestState>(
+ spec_.get(), this, delegate_->GetApplicationLocale(),
+ delegate_->GetPersonalDataManager(), delegate_.get());
+ return;
+ }
+
std::string error;
- if (!payments::validatePaymentDetails(details, &error)) {
+ if (!validatePaymentDetails(details, &error)) {
LOG(ERROR) << error;
OnConnectionTerminated();
return;
}
+
if (!details->total) {
LOG(ERROR) << "Missing total";
OnConnectionTerminated();
return;
}
- client_ = std::move(client);
+
spec_ = base::MakeUnique<PaymentRequestSpec>(
std::move(options), std::move(details), std::move(method_data), this,
delegate_->GetApplicationLocale());
@@ -69,12 +116,30 @@ void PaymentRequest::Show() {
OnConnectionTerminated();
return;
}
+
+ // A tab can display only one PaymentRequest UI at a time.
+ if (!manager_->CanShow(this)) {
+ LOG(ERROR) << "A PaymentRequest UI is already showing";
+ client_->OnError(mojom::PaymentErrorReason::USER_CANCEL);
+ OnConnectionTerminated();
+ return;
+ }
+
+ if (!state_->AreRequestedMethodsSupported()) {
+ client_->OnError(mojom::PaymentErrorReason::NOT_SUPPORTED);
+ if (observer_for_testing_)
+ observer_for_testing_->OnNotSupportedError();
+ OnConnectionTerminated();
+ return;
+ }
+
+ journey_logger_.SetShowCalled();
delegate_->ShowDialog(this);
}
void PaymentRequest::UpdateWith(mojom::PaymentDetailsPtr details) {
std::string error;
- if (!payments::validatePaymentDetails(details, &error)) {
+ if (!validatePaymentDetails(details, &error)) {
LOG(ERROR) << error;
OnConnectionTerminated();
return;
@@ -83,11 +148,22 @@ void PaymentRequest::UpdateWith(mojom::PaymentDetailsPtr details) {
}
void PaymentRequest::Abort() {
- // The API user has decided to abort. We return a successful abort message to
- // the renderer, which closes the Mojo message pipe, which triggers
+ // The API user has decided to abort. If a successful abort message is
+ // returned to the renderer, the Mojo message pipe is closed, which triggers
// PaymentRequest::OnConnectionTerminated, which destroys this object.
+ // Otherwise, the abort promise is rejected and the pipe is not closed.
+ // The abort is only successful if the payment app wasn't yet invoked.
+ // TODO(crbug.com/716546): Add a merchant abort metric
+
+ bool accepting_abort = !state_->IsPaymentAppInvoked();
+ if (accepting_abort)
+ RecordFirstAbortReason(JourneyLogger::ABORT_REASON_ABORTED_BY_MERCHANT);
+
if (client_.is_bound())
- client_->OnAbort(true /* aborted_successfully */);
+ client_->OnAbort(accepting_abort);
+
+ if (observer_for_testing_)
+ observer_for_testing_->OnAbortCalled();
}
void PaymentRequest::Complete(mojom::PaymentComplete result) {
@@ -97,27 +173,48 @@ void PaymentRequest::Complete(mojom::PaymentComplete result) {
if (result != mojom::PaymentComplete::SUCCESS) {
delegate_->ShowErrorMessage();
} else {
+ DCHECK(!has_recorded_completion_);
+ journey_logger_.SetCompleted();
+ has_recorded_completion_ = true;
+
+ delegate_->GetPrefService()->SetBoolean(kPaymentsFirstTransactionCompleted,
+ true);
// When the renderer closes the connection,
// PaymentRequest::OnConnectionTerminated will be called.
client_->OnComplete();
+ state_->RecordUseStats();
}
}
void PaymentRequest::CanMakePayment() {
- // TODO(crbug.com/704676): Implement a quota policy for this method.
- // PaymentRequest.canMakePayments() never returns false in incognito mode.
- client_->OnCanMakePayment(
- delegate_->IsIncognito() || state()->CanMakePayment()
- ? mojom::CanMakePaymentQueryResult::CAN_MAKE_PAYMENT
- : mojom::CanMakePaymentQueryResult::CANNOT_MAKE_PAYMENT);
+ bool can_make_payment = state()->CanMakePayment();
+ if (delegate_->IsIncognito()) {
+ client_->OnCanMakePayment(
+ mojom::CanMakePaymentQueryResult::CAN_MAKE_PAYMENT);
+ journey_logger_.SetCanMakePaymentValue(true);
+ } else if (CanMakePaymentQueryFactory::GetInstance()
+ ->GetForContext(web_contents_->GetBrowserContext())
+ ->CanQuery(frame_origin_, spec()->stringified_method_data())) {
+ client_->OnCanMakePayment(
+ can_make_payment
+ ? mojom::CanMakePaymentQueryResult::CAN_MAKE_PAYMENT
+ : mojom::CanMakePaymentQueryResult::CANNOT_MAKE_PAYMENT);
+ journey_logger_.SetCanMakePaymentValue(can_make_payment);
+ } else if (OriginSecurityChecker::IsOriginLocalhostOrFile(frame_origin_)) {
+ client_->OnCanMakePayment(
+ can_make_payment
+ ? mojom::CanMakePaymentQueryResult::WARNING_CAN_MAKE_PAYMENT
+ : mojom::CanMakePaymentQueryResult::WARNING_CANNOT_MAKE_PAYMENT);
+ journey_logger_.SetCanMakePaymentValue(can_make_payment);
+ } else {
+ client_->OnCanMakePayment(
+ mojom::CanMakePaymentQueryResult::QUERY_QUOTA_EXCEEDED);
+ }
+
if (observer_for_testing_)
observer_for_testing_->OnCanMakePaymentCalled();
}
-void PaymentRequest::OnInvalidSpecProvided() {
- OnConnectionTerminated();
-}
-
void PaymentRequest::OnPaymentResponseAvailable(
mojom::PaymentResponsePtr response) {
client_->OnPaymentResponse(std::move(response));
@@ -139,15 +236,25 @@ void PaymentRequest::UserCancelled() {
if (!client_.is_bound())
return;
+ RecordFirstAbortReason(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
+
// This sends an error to the renderer, which informs the API user.
- client_->OnError(payments::mojom::PaymentErrorReason::USER_CANCEL);
+ client_->OnError(mojom::PaymentErrorReason::USER_CANCEL);
// We close all bindings and ask to be destroyed.
client_.reset();
binding_.Close();
+ if (observer_for_testing_)
+ observer_for_testing_->OnConnectionTerminated();
manager_->DestroyRequest(this);
}
+void PaymentRequest::DidStartNavigation(bool is_user_initiated) {
+ RecordFirstAbortReason(is_user_initiated
+ ? JourneyLogger::ABORT_REASON_USER_NAVIGATION
+ : JourneyLogger::ABORT_REASON_MERCHANT_NAVIGATION);
+}
+
void PaymentRequest::OnConnectionTerminated() {
// We are here because of a browser-side error, or likely as a result of the
// connection_error_handler on |binding_|, which can mean that the renderer
@@ -157,6 +264,10 @@ void PaymentRequest::OnConnectionTerminated() {
client_.reset();
binding_.Close();
delegate_->CloseDialog();
+ if (observer_for_testing_)
+ observer_for_testing_->OnConnectionTerminated();
+
+ RecordFirstAbortReason(JourneyLogger::ABORT_REASON_MOJO_CONNECTION_ERROR);
manager_->DestroyRequest(this);
}
@@ -164,4 +275,12 @@ void PaymentRequest::Pay() {
state_->GeneratePaymentResponse();
}
+void PaymentRequest::RecordFirstAbortReason(
+ JourneyLogger::AbortReason abort_reason) {
+ if (!has_recorded_completion_) {
+ has_recorded_completion_ = true;
+ journey_logger_.SetAborted(abort_reason);
+ }
+}
+
} // namespace payments
diff --git a/chromium/components/payments/content/payment_request.h b/chromium/components/payments/content/payment_request.h
index ad2abed152a..e0ab3fa4cd8 100644
--- a/chromium/components/payments/content/payment_request.h
+++ b/chromium/components/payments/content/payment_request.h
@@ -9,14 +9,17 @@
#include <vector>
#include "base/macros.h"
-#include "components/payments/content/payment_request.mojom.h"
#include "components/payments/content/payment_request_spec.h"
#include "components/payments/content/payment_request_state.h"
+#include "components/payments/core/journey_logger.h"
#include "components/payments/core/payment_request_delegate.h"
+#include "components/payments/mojom/payment_request.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
+#include "url/gurl.h"
namespace content {
+class RenderFrameHost;
class WebContents;
}
@@ -37,12 +40,16 @@ class PaymentRequest : public mojom::PaymentRequest,
class ObserverForTest {
public:
virtual void OnCanMakePaymentCalled() = 0;
+ virtual void OnNotSupportedError() = 0;
+ virtual void OnConnectionTerminated() = 0;
+ virtual void OnAbortCalled() = 0;
protected:
virtual ~ObserverForTest() {}
};
- PaymentRequest(content::WebContents* web_contents,
+ PaymentRequest(content::RenderFrameHost* render_frame_host,
+ content::WebContents* web_contents,
std::unique_ptr<PaymentRequestDelegate> delegate,
PaymentRequestWebContentsManager* manager,
mojo::InterfaceRequest<mojom::PaymentRequest> request,
@@ -62,7 +69,6 @@ class PaymentRequest : public mojom::PaymentRequest,
// PaymentRequestSpec::Observer:
void OnSpecUpdated() override {}
- void OnInvalidSpecProvided() override;
// PaymentRequestState::Delegate:
void OnPaymentResponseAvailable(mojom::PaymentResponsePtr response) override;
@@ -74,6 +80,10 @@ class PaymentRequest : public mojom::PaymentRequest,
// OnConnectionTerminated).
void UserCancelled();
+ // Called when the frame attached to this PaymentRequest is navigating away,
+ // but before the PaymentRequest is destroyed.
+ void DidStartNavigation(bool is_user_initiated);
+
// As a result of a browser-side error or renderer-initiated mojo channel
// closure (e.g. there was an error on the renderer side, or payment was
// successful), this method is called. It is responsible for cleaning up,
@@ -89,6 +99,11 @@ class PaymentRequest : public mojom::PaymentRequest,
PaymentRequestState* state() { return state_.get(); }
private:
+ // Only records the abort reason if it's the first completion for this Payment
+ // Request. This is necessary since the aborts cascade into one another with
+ // the first one being the most precise.
+ void RecordFirstAbortReason(JourneyLogger::AbortReason completion_status);
+
content::WebContents* web_contents_;
std::unique_ptr<PaymentRequestDelegate> delegate_;
// |manager_| owns this PaymentRequest.
@@ -99,9 +114,18 @@ class PaymentRequest : public mojom::PaymentRequest,
std::unique_ptr<PaymentRequestSpec> spec_;
std::unique_ptr<PaymentRequestState> state_;
+ // The RFC 6454 origin of the frame that has invoked PaymentRequest API. This
+ // can be either the main frame or an iframe.
+ const GURL frame_origin_;
+
// May be null, must outlive this object.
ObserverForTest* observer_for_testing_;
+ JourneyLogger journey_logger_;
+
+ // Whether a completion was already recorded for this Payment Request.
+ bool has_recorded_completion_ = false;
+
DISALLOW_COPY_AND_ASSIGN(PaymentRequest);
};
diff --git a/chromium/components/payments/content/payment_request_spec.cc b/chromium/components/payments/content/payment_request_spec.cc
index 6fbfc5f63cd..252fe150417 100644
--- a/chromium/components/payments/content/payment_request_spec.cc
+++ b/chromium/components/payments/content/payment_request_spec.cc
@@ -7,8 +7,11 @@
#include <utility>
#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
#include "components/payments/core/payment_method_data.h"
#include "components/payments/core/payment_request_data_util.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
namespace payments {
@@ -52,11 +55,10 @@ PaymentRequestSpec::PaymentRequestSpec(
: options_(std::move(options)),
details_(std::move(details)),
app_locale_(app_locale),
- selected_shipping_option_(nullptr),
- observer_for_testing_(nullptr) {
+ selected_shipping_option_(nullptr) {
if (observer)
AddObserver(observer);
- UpdateSelectedShippingOption();
+ UpdateSelectedShippingOption(/*after_update=*/false);
PopulateValidatedMethodData(method_data);
}
PaymentRequestSpec::~PaymentRequestSpec() {}
@@ -64,8 +66,9 @@ PaymentRequestSpec::~PaymentRequestSpec() {}
void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) {
details_ = std::move(details);
// We reparse the |details_| and update the observers.
- UpdateSelectedShippingOption();
+ UpdateSelectedShippingOption(/*after_update=*/true);
NotifyOnSpecUpdated();
+ current_update_reason_ = UpdateReason::NONE;
}
void PaymentRequestSpec::AddObserver(Observer* observer) {
@@ -112,40 +115,48 @@ bool PaymentRequestSpec::IsMethodSupportedThroughBasicCard(
}
base::string16 PaymentRequestSpec::GetFormattedCurrencyAmount(
- const std::string& amount) {
+ const mojom::PaymentCurrencyAmountPtr& currency_amount) {
CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter(
- details_->total->amount->currency,
- details_->total->amount->currency_system, app_locale_);
- return formatter->Format(amount);
+ currency_amount->currency, currency_amount->currency_system, app_locale_);
+ return formatter->Format(currency_amount->value);
}
-std::string PaymentRequestSpec::GetFormattedCurrencyCode() {
+std::string PaymentRequestSpec::GetFormattedCurrencyCode(
+ const mojom::PaymentCurrencyAmountPtr& currency_amount) {
CurrencyFormatter* formatter = GetOrCreateCurrencyFormatter(
- details_->total->amount->currency,
- details_->total->amount->currency_system, app_locale_);
+ currency_amount->currency, currency_amount->currency_system, app_locale_);
return formatter->formatted_currency_code();
}
void PaymentRequestSpec::StartWaitingForUpdateWith(
PaymentRequestSpec::UpdateReason reason) {
+ current_update_reason_ = reason;
for (auto& observer : observers_) {
observer.OnStartUpdating(reason);
}
}
+bool PaymentRequestSpec::IsMixedCurrency() const {
+ const std::string& total_currency = details_->total->amount->currency;
+ return std::any_of(details_->display_items.begin(),
+ details_->display_items.end(),
+ [&total_currency](const mojom::PaymentItemPtr& item) {
+ return item->amount->currency != total_currency;
+ });
+}
+
void PaymentRequestSpec::PopulateValidatedMethodData(
const std::vector<mojom::PaymentMethodDataPtr>& method_data_mojom) {
- if (method_data_mojom.empty()) {
- LOG(ERROR) << "Invalid payment methods or data";
- NotifyOnInvalidSpecProvided();
- return;
- }
-
std::vector<PaymentMethodData> method_data_vector;
method_data_vector.reserve(method_data_mojom.size());
for (const mojom::PaymentMethodDataPtr& method_data_entry :
method_data_mojom) {
+ for (const std::string& method : method_data_entry->supported_methods) {
+ stringified_method_data_[method].insert(
+ method_data_entry->stringified_data);
+ }
+
PaymentMethodData method_data;
method_data.supported_methods = method_data_entry->supported_methods;
// Transfer the supported basic card networks.
@@ -161,23 +172,51 @@ void PaymentRequestSpec::PopulateValidatedMethodData(
method_data_vector.push_back(std::move(method_data));
}
- if (!data_util::ParseBasicCardSupportedNetworks(
- method_data_vector, &supported_card_networks_,
- &basic_card_specified_networks_)) {
- LOG(ERROR) << "Invalid payment methods or data";
- NotifyOnInvalidSpecProvided();
- return;
- }
+ data_util::ParseBasicCardSupportedNetworks(method_data_vector,
+ &supported_card_networks_,
+ &basic_card_specified_networks_);
supported_card_networks_set_.insert(supported_card_networks_.begin(),
supported_card_networks_.end());
}
-void PaymentRequestSpec::UpdateSelectedShippingOption() {
+void PaymentRequestSpec::UpdateSelectedShippingOption(bool after_update) {
if (!request_shipping())
return;
+ selected_shipping_option_ = nullptr;
+ selected_shipping_option_error_.clear();
+ if (details().shipping_options.empty()) {
+ // No options are provided by the merchant.
+ if (after_update) {
+ // This is after an update, which means that the selected address is not
+ // supported. The merchant may have customized the error string, or a
+ // generic one is used.
+ if (!details().error.empty()) {
+ selected_shipping_option_error_ = base::UTF8ToUTF16(details().error);
+ } else {
+ // The generic error string depends on the shipping type.
+ switch (shipping_type()) {
+ case PaymentShippingType::DELIVERY:
+ selected_shipping_option_error_ = l10n_util::GetStringUTF16(
+ IDS_PAYMENTS_UNSUPPORTED_DELIVERY_ADDRESS);
+ break;
+ case PaymentShippingType::PICKUP:
+ selected_shipping_option_error_ = l10n_util::GetStringUTF16(
+ IDS_PAYMENTS_UNSUPPORTED_PICKUP_ADDRESS);
+ break;
+ case PaymentShippingType::SHIPPING:
+ selected_shipping_option_error_ = l10n_util::GetStringUTF16(
+ IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS);
+ break;
+ }
+ }
+ }
+ return;
+ }
+
// As per the spec, the selected shipping option should initially be the last
- // one in the array that has its selected field set to true.
+ // one in the array that has its selected field set to true. If none are
+ // selected by the merchant, |selected_shipping_option_| stays nullptr.
auto selected_shipping_option_it = std::find_if(
details().shipping_options.rbegin(), details().shipping_options.rend(),
[](const payments::mojom::PaymentShippingOptionPtr& element) {
@@ -185,36 +224,26 @@ void PaymentRequestSpec::UpdateSelectedShippingOption() {
});
if (selected_shipping_option_it != details().shipping_options.rend()) {
selected_shipping_option_ = selected_shipping_option_it->get();
- } else {
- // It's possible that there is no selected shipping option.
- // TODO(crbug.com/710004): Show an error in this case.
- selected_shipping_option_ = nullptr;
}
}
-void PaymentRequestSpec::NotifyOnInvalidSpecProvided() {
- for (auto& observer : observers_)
- observer.OnInvalidSpecProvided();
- if (observer_for_testing_)
- observer_for_testing_->OnInvalidSpecProvided();
-}
-
void PaymentRequestSpec::NotifyOnSpecUpdated() {
for (auto& observer : observers_)
observer.OnSpecUpdated();
- if (observer_for_testing_)
- observer_for_testing_->OnSpecUpdated();
}
CurrencyFormatter* PaymentRequestSpec::GetOrCreateCurrencyFormatter(
const std::string& currency_code,
const std::string& currency_system,
const std::string& locale_name) {
- if (!currency_formatter_) {
- currency_formatter_.reset(
- new CurrencyFormatter(currency_code, currency_system, locale_name));
- }
- return currency_formatter_.get();
+ // Create a currency formatter for |currency_code|, or if already created
+ // return the cached version.
+ std::pair<std::map<std::string, CurrencyFormatter>::iterator, bool>
+ emplace_result = currency_formatters_.emplace(
+ std::piecewise_construct, std::forward_as_tuple(currency_code),
+ std::forward_as_tuple(currency_code, currency_system, locale_name));
+
+ return &(emplace_result.first->second);
}
} // namespace payments
diff --git a/chromium/components/payments/content/payment_request_spec.h b/chromium/components/payments/content/payment_request_spec.h
index de0187a5aaa..1835c75ef06 100644
--- a/chromium/components/payments/content/payment_request_spec.h
+++ b/chromium/components/payments/content/payment_request_spec.h
@@ -5,15 +5,17 @@
#ifndef COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_SPEC_H_
#define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_SPEC_H_
+#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/observer_list.h"
-#include "components/payments/content/payment_request.mojom.h"
+#include "base/strings/string16.h"
#include "components/payments/core/currency_formatter.h"
#include "components/payments/core/payment_options_provider.h"
+#include "components/payments/mojom/payment_request.mojom.h"
namespace payments {
@@ -37,9 +39,6 @@ class PaymentRequestSpec : public PaymentOptionsProvider {
// notification about spec events.
class Observer {
public:
- // Called when the provided spec (details, options, method_data) is invalid.
- virtual void OnInvalidSpecProvided() = 0;
-
// Called when the website is notified that the user selected shipping
// options or a shipping address. This will be followed by a call to
// OnSpecUpdated or the PaymentRequest being aborted due to a timeout.
@@ -79,47 +78,57 @@ class PaymentRequestSpec : public PaymentOptionsProvider {
const std::set<std::string>& supported_card_networks_set() const {
return supported_card_networks_set_;
}
+ const std::map<std::string, std::set<std::string>>& stringified_method_data()
+ const {
+ return stringified_method_data_;
+ }
// Returns whether the |method_name| was specified as supported through the
// "basic-card" payment method. If false, it means either the |method_name| is
// not supported at all, or specified directly in supportedMethods.
bool IsMethodSupportedThroughBasicCard(const std::string& method_name);
- // Uses CurrencyFormatter to format |amount| with the currency symbol for this
- // request's currency. Will use currency of the "total" display item, because
- // all items are supposed to have the same currency in a given request.
- base::string16 GetFormattedCurrencyAmount(const std::string& amount);
+ // Uses CurrencyFormatter to format the value of |currency_amount| with the
+ // currency symbol for its currency.
+ base::string16 GetFormattedCurrencyAmount(
+ const mojom::PaymentCurrencyAmountPtr& currency_amount);
- // Uses CurrencyFormatter to get the formatted currency code for this
- // request's currency. Will use currency of the "total" display item, because
- // all items are supposed to have the same currency in a given request.
- std::string GetFormattedCurrencyCode();
+ // Uses CurrencyFormatter to get the formatted currency code for
+ // |currency_amount|'s currency.
+ std::string GetFormattedCurrencyCode(
+ const mojom::PaymentCurrencyAmountPtr& currency_amount);
mojom::PaymentShippingOption* selected_shipping_option() const {
return selected_shipping_option_;
}
+ // This may contain a non-empty error returned by the merchant. In this case
+ // PaymentRequestState::selected_shipping_option_error_profile() will contain
+ // the profile related to the error.
+ const base::string16& selected_shipping_option_error() const {
+ return selected_shipping_option_error_;
+ }
const mojom::PaymentDetails& details() const { return *details_.get(); }
void StartWaitingForUpdateWith(UpdateReason reason);
- private:
- friend class PaymentRequestDialogView;
- void add_observer_for_testing(Observer* observer_for_testing) {
- observer_for_testing_ = observer_for_testing;
- }
+ bool IsMixedCurrency() const;
+ UpdateReason current_update_reason() const { return current_update_reason_; }
+
+ private:
// Validates the |method_data| and fills |supported_card_networks_|,
// |supported_card_networks_set_| and |basic_card_specified_networks_|.
void PopulateValidatedMethodData(
const std::vector<mojom::PaymentMethodDataPtr>& method_data);
- // Updates the selected_shipping_option based on the data passed to this
+ // Updates the |selected_shipping_option| based on the data passed to this
// payment request by the website. This will set selected_shipping_option_ to
- // the last option marked selected in the options array.
- void UpdateSelectedShippingOption();
+ // the last option marked selected in the options array. If no options are
+ // provided and this method is called |after_update|, it means the merchant
+ // doesn't ship to this location. In this case,
+ // |selected_shipping_option_error_| will be set.
+ void UpdateSelectedShippingOption(bool after_update);
- // Will notify all observers that the spec is invalid.
- void NotifyOnInvalidSpecProvided();
// Will notify all observers that the spec has changed.
void NotifyOnSpecUpdated();
@@ -137,8 +146,10 @@ class PaymentRequestSpec : public PaymentOptionsProvider {
const std::string app_locale_;
// The currently shipping option as specified by the merchant.
mojom::PaymentShippingOption* selected_shipping_option_;
+ base::string16 selected_shipping_option_error_;
- std::unique_ptr<CurrencyFormatter> currency_formatter_;
+ // One currency formatter is instantiated and cached per currency code.
+ std::map<std::string, CurrencyFormatter> currency_formatters_;
// A list/set of supported basic card networks. The list is used to keep the
// order in which they were specified by the merchant. The set is used for
@@ -150,10 +161,16 @@ class PaymentRequestSpec : public PaymentOptionsProvider {
// |supported_card_networks_set_| to check merchant support.
std::set<std::string> basic_card_specified_networks_;
+ // A mapping of the payment method names to the corresponding JSON-stringified
+ // payment method specific data.
+ std::map<std::string, std::set<std::string>> stringified_method_data_;
+
+ // The reason why this payment request is waiting for updateWith.
+ UpdateReason current_update_reason_;
+
// The |observer_for_testing_| will fire after all the |observers_| have been
// notified.
base::ObserverList<Observer> observers_;
- Observer* observer_for_testing_;
DISALLOW_COPY_AND_ASSIGN(PaymentRequestSpec);
};
diff --git a/chromium/components/payments/content/payment_request_spec_unittest.cc b/chromium/components/payments/content/payment_request_spec_unittest.cc
index a90d1e45191..235a17adffc 100644
--- a/chromium/components/payments/content/payment_request_spec_unittest.cc
+++ b/chromium/components/payments/content/payment_request_spec_unittest.cc
@@ -7,8 +7,11 @@
#include <utility>
#include "base/memory/weak_ptr.h"
-#include "components/payments/content/payment_request.mojom.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/payments/mojom/payment_request.mojom.h"
+#include "components/strings/grit/components_strings.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
namespace payments {
@@ -17,9 +20,6 @@ class PaymentRequestSpecTest : public testing::Test,
protected:
~PaymentRequestSpecTest() override {}
- void OnInvalidSpecProvided() override {
- on_invalid_spec_provided_called_ = true;
- }
void OnSpecUpdated() override { on_spec_updated_called_ = true; }
void RecreateSpecWithMethodData(
@@ -37,21 +37,16 @@ class PaymentRequestSpecTest : public testing::Test,
}
PaymentRequestSpec* spec() { return spec_.get(); }
- bool on_invalid_spec_provided_called() {
- return on_invalid_spec_provided_called_;
- }
private:
std::unique_ptr<PaymentRequestSpec> spec_;
- bool on_invalid_spec_provided_called_ = false;
bool on_spec_updated_called_ = false;
};
-// Test that empty method data notifies observers of an invalid spec.
+// Test that empty method data is parsed correctly.
TEST_F(PaymentRequestSpecTest, EmptyMethodData) {
std::vector<mojom::PaymentMethodDataPtr> method_data;
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_TRUE(on_invalid_spec_provided_called());
// No supported card networks.
EXPECT_EQ(0u, spec()->supported_card_networks().size());
@@ -76,12 +71,12 @@ TEST_F(PaymentRequestSpecTest, IsMethodSupportedThroughBasicCard) {
RecreateSpecWithMethodData(std::move(method_data));
- // Only unionpay and jcb are supported through basic-card.
+ // unionpay and jcb are supported through basic-card. visa is supported
+ // through basic card because it was specified in basic-card in addition to
+ // supportedMethods.
EXPECT_TRUE(spec()->IsMethodSupportedThroughBasicCard("unionpay"));
EXPECT_TRUE(spec()->IsMethodSupportedThroughBasicCard("jcb"));
- // "visa" is NOT supported through basic card because it was specified
- // directly first in supportedMethods.
- EXPECT_FALSE(spec()->IsMethodSupportedThroughBasicCard("visa"));
+ EXPECT_TRUE(spec()->IsMethodSupportedThroughBasicCard("visa"));
EXPECT_FALSE(spec()->IsMethodSupportedThroughBasicCard("mastercard"));
EXPECT_FALSE(spec()->IsMethodSupportedThroughBasicCard("diners"));
EXPECT_FALSE(spec()->IsMethodSupportedThroughBasicCard("garbage"));
@@ -127,7 +122,6 @@ TEST_F(PaymentRequestSpecTest, SupportedMethods) {
method_data.push_back(std::move(entry));
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_FALSE(on_invalid_spec_provided_called());
// Only "visa" and "mastercard" remain, in order.
EXPECT_EQ(2u, spec()->supported_card_networks().size());
@@ -151,7 +145,6 @@ TEST_F(PaymentRequestSpecTest, SupportedMethods_MultipleEntries) {
method_data.push_back(std::move(entry3));
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_FALSE(on_invalid_spec_provided_called());
// Only "visa" and "mastercard" remain, in order.
EXPECT_EQ(2u, spec()->supported_card_networks().size());
@@ -177,7 +170,6 @@ TEST_F(PaymentRequestSpecTest, SupportedMethods_MultipleEntries_OneEmpty) {
method_data.push_back(std::move(entry3));
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_TRUE(on_invalid_spec_provided_called());
// Visa was parsed, but not mastercard.
EXPECT_EQ(1u, spec()->supported_card_networks().size());
@@ -192,7 +184,6 @@ TEST_F(PaymentRequestSpecTest, SupportedMethods_OnlyBasicCard) {
method_data.push_back(std::move(entry));
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_FALSE(on_invalid_spec_provided_called());
// All of the basic card networks are supported.
EXPECT_EQ(8u, spec()->supported_card_networks().size());
@@ -216,7 +207,6 @@ TEST_F(PaymentRequestSpecTest, SupportedMethods_BasicCard_WithSpecificMethod) {
method_data.push_back(std::move(entry));
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_FALSE(on_invalid_spec_provided_called());
// All of the basic card networks are supported, but JCB is first because it
// was specified first.
@@ -248,7 +238,6 @@ TEST_F(PaymentRequestSpecTest, SupportedMethods_BasicCard_Overlap) {
method_data.push_back(std::move(entry2));
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_FALSE(on_invalid_spec_provided_called());
EXPECT_EQ(3u, spec()->supported_card_networks().size());
EXPECT_EQ("mastercard", spec()->supported_card_networks()[0]);
@@ -268,7 +257,6 @@ TEST_F(PaymentRequestSpecTest,
method_data.push_back(std::move(entry));
RecreateSpecWithMethodData(std::move(method_data));
- EXPECT_FALSE(on_invalid_spec_provided_called());
// Only the specified networks are supported.
EXPECT_EQ(2u, spec()->supported_card_networks().size());
@@ -296,22 +284,150 @@ TEST_F(PaymentRequestSpecTest, ShippingOptionsSelection) {
RecreateSpecWithOptionsAndDetails(std::move(options), std::move(details));
EXPECT_EQ("option:2", spec()->selected_shipping_option()->id);
+ EXPECT_TRUE(spec()->selected_shipping_option_error().empty());
+ // Call updateWith with option:1 now selected.
std::vector<mojom::PaymentShippingOptionPtr> new_shipping_options;
mojom::PaymentShippingOptionPtr new_option =
mojom::PaymentShippingOption::New();
new_option->id = "option:1";
- new_option->selected = false;
- shipping_options.push_back(std::move(new_option));
+ new_option->selected = true;
+ new_shipping_options.push_back(std::move(new_option));
mojom::PaymentShippingOptionPtr new_option2 =
mojom::PaymentShippingOption::New();
new_option2->id = "option:2";
- new_option2->selected = true;
+ new_option2->selected = false;
new_shipping_options.push_back(std::move(new_option2));
mojom::PaymentDetailsPtr new_details = mojom::PaymentDetails::New();
new_details->shipping_options = std::move(new_shipping_options);
spec()->UpdateWith(std::move(new_details));
+
+ EXPECT_EQ("option:1", spec()->selected_shipping_option()->id);
+ EXPECT_TRUE(spec()->selected_shipping_option_error().empty());
+}
+
+// Test that the last shipping option is selected, even in the case of
+// updateWith.
+TEST_F(PaymentRequestSpecTest, ShippingOptionsSelection_NoOptionsAtAll) {
+ // No options are provided at first.
+ mojom::PaymentOptionsPtr options = mojom::PaymentOptions::New();
+ options->request_shipping = true;
+ RecreateSpecWithOptionsAndDetails(std::move(options),
+ mojom::PaymentDetails::New());
+
+ // No option selected, but no error either (the flow just started and no
+ // address has been selected yet).
+ EXPECT_EQ(nullptr, spec()->selected_shipping_option());
+ EXPECT_TRUE(spec()->selected_shipping_option_error().empty());
+
+ // Call updateWith with still no options.
+ spec()->UpdateWith(mojom::PaymentDetails::New());
+
+ // Now it's more serious. No option selected, but there is a generic error.
+ EXPECT_EQ(nullptr, spec()->selected_shipping_option());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF16(IDS_PAYMENTS_UNSUPPORTED_SHIPPING_ADDRESS),
+ spec()->selected_shipping_option_error());
+
+ // Call updateWith with still no options, but a customized error string.
+ mojom::PaymentDetailsPtr details = mojom::PaymentDetails::New();
+ details->error = "No can do shipping.";
+ spec()->UpdateWith(std::move(details));
+
+ // No option selected, but there is an error provided by the mercahnt.
+ EXPECT_EQ(nullptr, spec()->selected_shipping_option());
+ EXPECT_EQ(base::ASCIIToUTF16("No can do shipping."),
+ spec()->selected_shipping_option_error());
+}
+
+TEST_F(PaymentRequestSpecTest, SingleCurrencyWithoutDisplayItems) {
+ mojom::PaymentDetailsPtr details = mojom::PaymentDetails::New();
+ mojom::PaymentItemPtr total = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr amount = mojom::PaymentCurrencyAmount::New();
+ amount->currency = "USD";
+ total->amount = std::move(amount);
+ details->total = std::move(total);
+
+ RecreateSpecWithOptionsAndDetails(mojom::PaymentOptions::New(),
+ std::move(details));
+ // If the request only has a total, it must not have mixed currencies.
+ EXPECT_FALSE(spec()->IsMixedCurrency());
+}
+
+TEST_F(PaymentRequestSpecTest, SingleCurrencyWithDisplayItems) {
+ mojom::PaymentDetailsPtr details = mojom::PaymentDetails::New();
+ mojom::PaymentItemPtr total = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr amount = mojom::PaymentCurrencyAmount::New();
+ amount->currency = "USD";
+ total->amount = std::move(amount);
+ details->total = std::move(total);
+
+ mojom::PaymentItemPtr display_item = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr display_amount =
+ mojom::PaymentCurrencyAmount::New();
+ display_amount->currency = "USD";
+ display_item->amount = std::move(display_amount);
+ details->display_items.push_back(std::move(display_item));
+
+ RecreateSpecWithOptionsAndDetails(mojom::PaymentOptions::New(),
+ std::move(details));
+ // Both the total and the display item have matching currency codes, this
+ // isn't a mixed currency case.
+ EXPECT_FALSE(spec()->IsMixedCurrency());
+}
+
+TEST_F(PaymentRequestSpecTest, MultipleCurrenciesWithOneDisplayItem) {
+ mojom::PaymentDetailsPtr details = mojom::PaymentDetails::New();
+ mojom::PaymentItemPtr total = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr amount = mojom::PaymentCurrencyAmount::New();
+ amount->currency = "USD";
+ total->amount = std::move(amount);
+ details->total = std::move(total);
+
+ mojom::PaymentItemPtr display_item = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr display_amount =
+ mojom::PaymentCurrencyAmount::New();
+ display_amount->currency = "CAD";
+ display_item->amount = std::move(display_amount);
+ details->display_items.push_back(std::move(display_item));
+
+ RecreateSpecWithOptionsAndDetails(mojom::PaymentOptions::New(),
+ std::move(details));
+
+ // The display item currency and the total's currency don't match, this is a
+ // mixed currencies case.
+ EXPECT_TRUE(spec()->IsMixedCurrency());
+}
+
+TEST_F(PaymentRequestSpecTest, MultipleCurrenciesWithTwoDisplayItem) {
+ mojom::PaymentDetailsPtr details = mojom::PaymentDetails::New();
+ mojom::PaymentItemPtr total = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr amount = mojom::PaymentCurrencyAmount::New();
+ amount->currency = "USD";
+ total->amount = std::move(amount);
+ details->total = std::move(total);
+
+ mojom::PaymentItemPtr display_item1 = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr display_amount1 =
+ mojom::PaymentCurrencyAmount::New();
+ display_amount1->currency = "CAD";
+ display_item1->amount = std::move(display_amount1);
+ details->display_items.push_back(std::move(display_item1));
+
+ mojom::PaymentItemPtr display_item2 = mojom::PaymentItem::New();
+ mojom::PaymentCurrencyAmountPtr display_amount2 =
+ mojom::PaymentCurrencyAmount::New();
+ display_amount2->currency = "USD";
+ display_item2->amount = std::move(display_amount2);
+ details->display_items.push_back(std::move(display_item2));
+
+ RecreateSpecWithOptionsAndDetails(mojom::PaymentOptions::New(),
+ std::move(details));
+
+ // At least one of the display items has a different currency, this is a mixed
+ // currency case.
+ EXPECT_TRUE(spec()->IsMixedCurrency());
}
} // namespace payments
diff --git a/chromium/components/payments/content/payment_request_state.cc b/chromium/components/payments/content/payment_request_state.cc
index c3f152640f2..47a068ec878 100644
--- a/chromium/components/payments/content/payment_request_state.cc
+++ b/chromium/components/payments/content/payment_request_state.cc
@@ -9,16 +9,16 @@
#include <utility>
#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/personal_data_manager.h"
-#include "components/payments/content/payment_request_spec.h"
#include "components/payments/content/payment_response_helper.h"
#include "components/payments/core/autofill_payment_instrument.h"
#include "components/payments/core/payment_instrument.h"
+#include "components/payments/core/payment_request_data_util.h"
#include "components/payments/core/payment_request_delegate.h"
-#include "components/payments/core/profile_util.h"
namespace payments {
@@ -29,16 +29,20 @@ PaymentRequestState::PaymentRequestState(
autofill::PersonalDataManager* personal_data_manager,
PaymentRequestDelegate* payment_request_delegate)
: is_ready_to_pay_(false),
+ is_waiting_for_merchant_validation_(false),
app_locale_(app_locale),
spec_(spec),
delegate_(delegate),
personal_data_manager_(personal_data_manager),
selected_shipping_profile_(nullptr),
+ selected_shipping_option_error_profile_(nullptr),
selected_contact_profile_(nullptr),
selected_instrument_(nullptr),
- payment_request_delegate_(payment_request_delegate) {
+ payment_request_delegate_(payment_request_delegate),
+ profile_comparator_(app_locale, *spec) {
PopulateProfileCache();
SetDefaultProfileSelections();
+ spec_->AddObserver(this);
}
PaymentRequestState::~PaymentRequestState() {}
@@ -47,18 +51,54 @@ void PaymentRequestState::OnPaymentResponseReady(
delegate_->OnPaymentResponseAvailable(std::move(payment_response));
}
+void PaymentRequestState::OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) {
+ delegate_->OnShippingAddressSelected(
+ PaymentResponseHelper::GetMojomPaymentAddressFromAutofillProfile(
+ normalized_profile, app_locale_));
+}
+
+void PaymentRequestState::OnCouldNotNormalize(
+ const autofill::AutofillProfile& profile) {
+ // Since the phone number is formatted in either case, this profile should be
+ // used.
+ OnAddressNormalized(profile);
+}
+
+void PaymentRequestState::OnSpecUpdated() {
+ if (spec_->selected_shipping_option_error().empty()) {
+ selected_shipping_option_error_profile_ = nullptr;
+ } else {
+ selected_shipping_option_error_profile_ = selected_shipping_profile_;
+ selected_shipping_profile_ = nullptr;
+ }
+ is_waiting_for_merchant_validation_ = false;
+ UpdateIsReadyToPayAndNotifyObservers();
+}
+
bool PaymentRequestState::CanMakePayment() const {
for (const std::unique_ptr<PaymentInstrument>& instrument :
available_instruments_) {
- if (instrument->IsValidForCanMakePayment() &&
- spec_->supported_card_networks_set().count(
- instrument.get()->method_name())) {
+ if (instrument->IsValidForCanMakePayment()) {
+ // AddAutofillPaymentInstrument() filters out available instruments based
+ // on supported card networks.
+ DCHECK(spec_->supported_card_networks_set().find(
+ instrument->method_name()) !=
+ spec_->supported_card_networks_set().end());
return true;
}
}
return false;
}
+bool PaymentRequestState::AreRequestedMethodsSupported() const {
+ return !spec_->supported_card_networks().empty();
+}
+
+std::string PaymentRequestState::GetAuthenticatedEmail() const {
+ return payment_request_delegate_->GetAuthenticatedEmail();
+}
+
void PaymentRequestState::AddObserver(Observer* observer) {
CHECK(observer);
observers_.AddObserver(observer);
@@ -73,16 +113,37 @@ void PaymentRequestState::GeneratePaymentResponse() {
// Once the response is ready, will call back into OnPaymentResponseReady.
response_helper_ = base::MakeUnique<PaymentResponseHelper>(
- app_locale_, spec_, selected_instrument_, selected_shipping_profile_,
- selected_contact_profile_, this);
+ app_locale_, spec_, selected_instrument_, payment_request_delegate_,
+ selected_shipping_profile_, selected_contact_profile_, this);
+}
+
+void PaymentRequestState::RecordUseStats() {
+ if (spec_->request_shipping()) {
+ DCHECK(selected_shipping_profile_);
+ personal_data_manager_->RecordUseOf(*selected_shipping_profile_);
+ }
+
+ if (spec_->request_payer_name() || spec_->request_payer_email() ||
+ spec_->request_payer_phone()) {
+ DCHECK(selected_contact_profile_);
+
+ // If the same address was used for both contact and shipping, the stats
+ // should only be updated once.
+ if (!spec_->request_shipping() || (selected_shipping_profile_->guid() !=
+ selected_contact_profile_->guid())) {
+ personal_data_manager_->RecordUseOf(*selected_contact_profile_);
+ }
+ }
+
+ selected_instrument_->RecordUse();
}
void PaymentRequestState::AddAutofillPaymentInstrument(
bool selected,
const autofill::CreditCard& card) {
std::string basic_card_network =
- autofill::data_util::GetPaymentRequestData(card.type())
- .basic_card_payment_type;
+ autofill::data_util::GetPaymentRequestData(card.network())
+ .basic_card_issuer_network;
if (!spec_->supported_card_networks_set().count(basic_card_network))
return;
@@ -98,6 +159,32 @@ void PaymentRequestState::AddAutofillPaymentInstrument(
SetSelectedInstrument(available_instruments_.back().get());
}
+void PaymentRequestState::AddAutofillShippingProfile(
+ bool selected,
+ const autofill::AutofillProfile& profile) {
+ profile_cache_.push_back(
+ base::MakeUnique<autofill::AutofillProfile>(profile));
+ // TODO(tmartino): Implement deduplication rules specific to shipping
+ // profiles.
+ autofill::AutofillProfile* new_cached_profile = profile_cache_.back().get();
+ shipping_profiles_.push_back(new_cached_profile);
+
+ if (selected)
+ SetSelectedShippingProfile(new_cached_profile);
+}
+
+void PaymentRequestState::AddAutofillContactProfile(
+ bool selected,
+ const autofill::AutofillProfile& profile) {
+ profile_cache_.push_back(
+ base::MakeUnique<autofill::AutofillProfile>(profile));
+ autofill::AutofillProfile* new_cached_profile = profile_cache_.back().get();
+ contact_profiles_.push_back(new_cached_profile);
+
+ if (selected)
+ SetSelectedContactProfile(new_cached_profile);
+}
+
void PaymentRequestState::SetSelectedShippingOption(
const std::string& shipping_option_id) {
spec_->StartWaitingForUpdateWith(
@@ -112,10 +199,19 @@ void PaymentRequestState::SetSelectedShippingProfile(
spec_->StartWaitingForUpdateWith(
PaymentRequestSpec::UpdateReason::SHIPPING_ADDRESS);
selected_shipping_profile_ = profile;
+
+ // The user should not be able to click on pay until the callback from the
+ // merchant.
+ is_waiting_for_merchant_validation_ = true;
UpdateIsReadyToPayAndNotifyObservers();
- delegate_->OnShippingAddressSelected(
- PaymentResponseHelper::GetMojomPaymentAddressFromAutofillProfile(
- selected_shipping_profile_, app_locale_));
+
+ // Start the normalization of the shipping address.
+ // Use the country code from the profile if it is set, otherwise infer it
+ // from the |app_locale_|.
+ std::string country_code = data_util::GetCountryCodeWithFallback(
+ selected_shipping_profile_, app_locale_);
+ payment_request_delegate_->GetAddressNormalizer()->StartAddressNormalization(
+ *selected_shipping_profile_, country_code, /*timeout_seconds=*/2, this);
}
void PaymentRequestState::SetSelectedContactProfile(
@@ -137,44 +233,37 @@ autofill::PersonalDataManager* PaymentRequestState::GetPersonalDataManager() {
return personal_data_manager_;
}
-std::unique_ptr<const ::i18n::addressinput::Source>
-PaymentRequestState::GetAddressInputSource() {
- return payment_request_delegate_->GetAddressInputSource();
+autofill::RegionDataLoader* PaymentRequestState::GetRegionDataLoader() {
+ return payment_request_delegate_->GetRegionDataLoader();
}
-std::unique_ptr<::i18n::addressinput::Storage>
-PaymentRequestState::GetAddressInputStorage() {
- return payment_request_delegate_->GetAddressInputStorage();
+bool PaymentRequestState::IsPaymentAppInvoked() const {
+ return !!response_helper_;
}
void PaymentRequestState::PopulateProfileCache() {
std::vector<autofill::AutofillProfile*> profiles =
personal_data_manager_->GetProfilesToSuggest();
+ std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering;
+ raw_profiles_for_filtering.reserve(profiles.size());
+
// PaymentRequest may outlive the Profiles returned by the Data Manager.
// Thus, we store copies, and return a vector of pointers to these copies
- // whenever Profiles are requested. The same is true for credit cards.
+ // whenever Profiles are requested.
for (size_t i = 0; i < profiles.size(); i++) {
profile_cache_.push_back(
base::MakeUnique<autofill::AutofillProfile>(*profiles[i]));
-
- // TODO(tmartino): Implement deduplication rules specific to shipping
- // profiles.
- shipping_profiles_.push_back(profile_cache_[i].get());
+ raw_profiles_for_filtering.push_back(profile_cache_.back().get());
}
- std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering(
- profile_cache_.size());
- std::transform(profile_cache_.begin(), profile_cache_.end(),
- raw_profiles_for_filtering.begin(),
- [](const std::unique_ptr<autofill::AutofillProfile>& p) {
- return p.get();
- });
+ contact_profiles_ = profile_comparator()->FilterProfilesForContact(
+ raw_profiles_for_filtering);
+ shipping_profiles_ = profile_comparator()->FilterProfilesForShipping(
+ raw_profiles_for_filtering);
- contact_profiles_ = profile_util::FilterProfilesForContact(
- raw_profiles_for_filtering, GetApplicationLocale(), *spec_);
-
- // Create the list of available instruments.
+ // Create the list of available instruments. A copy of each card will be made
+ // by their respective AutofillPaymentInstrument.
const std::vector<autofill::CreditCard*>& cards =
personal_data_manager_->GetCreditCardsToSuggest();
for (autofill::CreditCard* card : cards)
@@ -183,11 +272,17 @@ void PaymentRequestState::PopulateProfileCache() {
void PaymentRequestState::SetDefaultProfileSelections() {
// Only pre-select an address if the merchant provided at least one selected
- // shipping option.
- if (!shipping_profiles().empty() && spec_->selected_shipping_option())
+ // shipping option, and the top profile is complete. Assumes that profiles
+ // have already been sorted for completeness and frecency.
+ if (!shipping_profiles().empty() && spec_->selected_shipping_option() &&
+ profile_comparator()->IsShippingComplete(shipping_profiles_[0])) {
selected_shipping_profile_ = shipping_profiles()[0];
+ }
- if (!contact_profiles().empty())
+ // Contact profiles were ordered by completeness in addition to frecency;
+ // the first one is the best default selection.
+ if (!contact_profiles().empty() &&
+ profile_comparator()->IsContactInfoComplete(contact_profiles_[0]))
selected_contact_profile_ = contact_profiles()[0];
// TODO(crbug.com/702063): Change this code to prioritize instruments by use
@@ -200,11 +295,9 @@ void PaymentRequestState::SetDefaultProfileSelections() {
[](const std::unique_ptr<PaymentInstrument>& instrument) {
return instrument->IsCompleteForPayment();
});
-
selected_instrument_ = first_complete_instrument == instruments.end()
? nullptr
: first_complete_instrument->get();
-
UpdateIsReadyToPayAndNotifyObservers();
}
@@ -227,12 +320,16 @@ bool PaymentRequestState::ArePaymentDetailsSatisfied() {
}
bool PaymentRequestState::ArePaymentOptionsSatisfied() {
- // TODO(mathp): Have a measure of shipping address completeness.
- if (spec_->request_shipping() && selected_shipping_profile_ == nullptr)
+ if (is_waiting_for_merchant_validation_)
+ return false;
+
+ if (!profile_comparator()->IsShippingComplete(selected_shipping_profile_))
+ return false;
+
+ if (spec_->request_shipping() && !spec_->selected_shipping_option())
return false;
- profile_util::PaymentsProfileComparator comparator(app_locale_, *spec_);
- return comparator.IsContactInfoComplete(selected_contact_profile_);
+ return profile_comparator()->IsContactInfoComplete(selected_contact_profile_);
}
} // namespace payments
diff --git a/chromium/components/payments/content/payment_request_state.h b/chromium/components/payments/content/payment_request_state.h
index cb0b2a97dd0..a62d2b84eae 100644
--- a/chromium/components/payments/content/payment_request_state.h
+++ b/chromium/components/payments/content/payment_request_state.h
@@ -11,33 +11,31 @@
#include "base/macros.h"
#include "base/observer_list.h"
-#include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/content/payment_request_spec.h"
#include "components/payments/content/payment_response_helper.h"
-
-namespace i18n {
-namespace addressinput {
-class Storage;
-class Source;
-} // namespace addressinput
-} // namespace i18n
+#include "components/payments/core/address_normalizer.h"
+#include "components/payments/core/payments_profile_comparator.h"
+#include "components/payments/mojom/payment_request.mojom.h"
namespace autofill {
class AutofillProfile;
class CreditCard;
class PersonalDataManager;
+class RegionDataLoader;
} // namespace autofill
namespace payments {
class PaymentInstrument;
class PaymentRequestDelegate;
-class PaymentRequestSpec;
// Keeps track of the information currently selected by the user and whether the
// user is ready to pay. Uses information from the PaymentRequestSpec, which is
// what the merchant has specified, as input into the "is ready to pay"
// computation.
-class PaymentRequestState : public PaymentResponseHelper::Delegate {
+class PaymentRequestState : public PaymentResponseHelper::Delegate,
+ public AddressNormalizer::Delegate,
+ public PaymentRequestSpec::Observer {
public:
// Any class call add itself as Observer via AddObserver() and receive
// notification about the state changing.
@@ -79,9 +77,27 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate {
void OnPaymentResponseReady(
mojom::PaymentResponsePtr payment_response) override;
+ // AddressNormalizer::Delegate
+ void OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) override;
+ void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override;
+
+ // PaymentRequestSpec::Observer
+ void OnStartUpdating(PaymentRequestSpec::UpdateReason reason) override {}
+ void OnSpecUpdated() override;
+
// Returns whether the user has at least one instrument that satisfies the
// specified supported payment methods.
bool CanMakePayment() const;
+
+ // Returns true if the payment methods that the merchant website have
+ // requested are supported. For example, may return true for "basic-card", but
+ // false for "https://bobpay.com".
+ bool AreRequestedMethodsSupported() const;
+
+ // Returns authenticated user email, or empty string.
+ std::string GetAuthenticatedEmail() const;
+
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
@@ -89,12 +105,20 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate {
// |is_ready_to_pay|, which is inexpensive.
void GeneratePaymentResponse();
+ // Record the use of the data models that were used in the Payment Request.
+ void RecordUseStats();
+
// Gets the Autofill Profile representing the shipping address or contact
// information currently selected for this PaymentRequest flow. Can return
// null.
autofill::AutofillProfile* selected_shipping_profile() const {
return selected_shipping_profile_;
}
+ // If |spec()->selected_shipping_option_error()| is not empty, this contains
+ // the profile for which the error is about.
+ autofill::AutofillProfile* selected_shipping_option_error_profile() const {
+ return selected_shipping_option_error_profile_;
+ }
autofill::AutofillProfile* selected_contact_profile() const {
return selected_contact_profile_;
}
@@ -124,6 +148,18 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate {
void AddAutofillPaymentInstrument(bool selected,
const autofill::CreditCard& card);
+ // Creates and adds an AutofillProfile as a shipping profile, which makes a
+ // copy of |profile|. |selected| indicates if the newly-created shipping
+ // profile should be selected, after which observers will be notified.
+ void AddAutofillShippingProfile(bool selected,
+ const autofill::AutofillProfile& profile);
+
+ // Creates and adds an AutofillProfile as a contact profile, which makes a
+ // copy of |profile|. |selected| indicates if the newly-created shipping
+ // profile should be selected, after which observers will be notified.
+ void AddAutofillContactProfile(bool selected,
+ const autofill::AutofillProfile& profile);
+
// Setters to change the selected information. Will have the side effect of
// recomputing "is ready to pay" and notify observers.
void SetSelectedShippingOption(const std::string& shipping_option_id);
@@ -135,11 +171,18 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate {
const std::string& GetApplicationLocale();
autofill::PersonalDataManager* GetPersonalDataManager();
- std::unique_ptr<const ::i18n::addressinput::Source> GetAddressInputSource();
- std::unique_ptr<::i18n::addressinput::Storage> GetAddressInputStorage();
+ autofill::RegionDataLoader* GetRegionDataLoader();
Delegate* delegate() { return delegate_; }
+ PaymentsProfileComparator* profile_comparator() {
+ return &profile_comparator_;
+ }
+
+ // Returns true if the payment app has been invoked and the payment response
+ // generation has begun. False otherwise.
+ bool IsPaymentAppInvoked() const;
+
private:
// Fetches the Autofill Profiles for this user from the PersonalDataManager,
// and stores copies of them, owned by this PaymentRequestState, in
@@ -167,6 +210,9 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate {
bool is_ready_to_pay_;
+ // Whether the data is currently being validated by the merchant.
+ bool is_waiting_for_merchant_validation_;
+
const std::string app_locale_;
// Not owned. Never null. Both outlive this object.
@@ -175,6 +221,7 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate {
autofill::PersonalDataManager* personal_data_manager_;
autofill::AutofillProfile* selected_shipping_profile_;
+ autofill::AutofillProfile* selected_shipping_option_error_profile_;
autofill::AutofillProfile* selected_contact_profile_;
PaymentInstrument* selected_instrument_;
@@ -191,6 +238,8 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate {
std::unique_ptr<PaymentResponseHelper> response_helper_;
+ PaymentsProfileComparator profile_comparator_;
+
base::ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(PaymentRequestState);
diff --git a/chromium/components/payments/content/payment_request_state_unittest.cc b/chromium/components/payments/content/payment_request_state_unittest.cc
index 8509777bda6..186fca9ea65 100644
--- a/chromium/components/payments/content/payment_request_state_unittest.cc
+++ b/chromium/components/payments/content/payment_request_state_unittest.cc
@@ -12,8 +12,9 @@
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
-#include "components/payments/content/payment_request.mojom.h"
#include "components/payments/content/payment_request_spec.h"
+#include "components/payments/core/test_payment_request_delegate.h"
+#include "components/payments/mojom/payment_request.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace payments {
@@ -24,6 +25,7 @@ class PaymentRequestStateTest : public testing::Test,
protected:
PaymentRequestStateTest()
: num_on_selected_information_changed_called_(0),
+ test_payment_request_delegate_(/*personal_data_manager=*/nullptr),
address_(autofill::test::GetFullProfile()),
credit_card_visa_(autofill::test::GetCreditCard()) {
test_personal_data_manager_.AddTestingProfile(&address_);
@@ -43,7 +45,9 @@ class PaymentRequestStateTest : public testing::Test,
payment_response_ = std::move(response);
};
void OnShippingOptionIdSelected(std::string shipping_option_id) override {}
- void OnShippingAddressSelected(mojom::PaymentAddressPtr address) override {}
+ void OnShippingAddressSelected(mojom::PaymentAddressPtr address) override {
+ selected_shipping_address_ = std::move(address);
+ }
void RecreateStateWithOptionsAndDetails(
mojom::PaymentOptionsPtr options,
@@ -51,17 +55,24 @@ class PaymentRequestStateTest : public testing::Test,
std::vector<mojom::PaymentMethodDataPtr> method_data) {
// The spec will be based on the |options| and |details| passed in.
spec_ = base::MakeUnique<PaymentRequestSpec>(
- std::move(options), std::move(details), std::move(method_data), nullptr,
- "en-US");
+ std::move(options), std::move(details), std::move(method_data),
+ /*observer=*/nullptr, "en-US");
state_ = base::MakeUnique<PaymentRequestState>(
- spec_.get(), this, "en-US", &test_personal_data_manager_, nullptr);
+ spec_.get(), this, "en-US", &test_personal_data_manager_,
+ &test_payment_request_delegate_);
state_->AddObserver(this);
}
// Convenience method to create a PaymentRequestState with default details
// (one shipping option) and method data (only supports visa).
void RecreateStateWithOptions(mojom::PaymentOptionsPtr options) {
- // Create dummy PaymentDetails with a single shipping option.
+ RecreateStateWithOptionsAndDetails(
+ std::move(options), CreateDefaultDetails(), GetMethodDataForVisa());
+ }
+
+ // Convenience method that returns a dummy PaymentDetails with a single
+ // shipping option.
+ mojom::PaymentDetailsPtr CreateDefaultDetails() {
std::vector<mojom::PaymentShippingOptionPtr> shipping_options;
mojom::PaymentShippingOptionPtr option =
mojom::PaymentShippingOption::New();
@@ -69,9 +80,7 @@ class PaymentRequestStateTest : public testing::Test,
shipping_options.push_back(std::move(option));
mojom::PaymentDetailsPtr details = mojom::PaymentDetails::New();
details->shipping_options = std::move(shipping_options);
-
- RecreateStateWithOptionsAndDetails(std::move(options), std::move(details),
- GetMethodDataForVisa());
+ return details;
}
// Convenience method that returns MethodData that supports Visa.
@@ -84,19 +93,28 @@ class PaymentRequestStateTest : public testing::Test,
}
PaymentRequestState* state() { return state_.get(); }
+ PaymentRequestSpec* spec() { return spec_.get(); }
const mojom::PaymentResponsePtr& response() { return payment_response_; }
+ const mojom::PaymentAddressPtr& selected_shipping_address() {
+ return selected_shipping_address_;
+ }
int num_on_selected_information_changed_called() {
return num_on_selected_information_changed_called_;
}
autofill::AutofillProfile* test_address() { return &address_; }
+ TestPaymentRequestDelegate* test_payment_request_delegate() {
+ return &test_payment_request_delegate_;
+ }
private:
std::unique_ptr<PaymentRequestState> state_;
std::unique_ptr<PaymentRequestSpec> spec_;
int num_on_selected_information_changed_called_;
mojom::PaymentResponsePtr payment_response_;
+ mojom::PaymentAddressPtr selected_shipping_address_;
autofill::TestPersonalDataManager test_personal_data_manager_;
+ TestPaymentRequestDelegate test_payment_request_delegate_;
// Test data.
autofill::AutofillProfile address_;
@@ -206,6 +224,19 @@ TEST_F(PaymentRequestStateTest, ReadyToPay_DefaultSelections) {
state()->SetSelectedShippingProfile(test_address());
EXPECT_EQ(1, num_on_selected_information_changed_called());
+ // Simulate that the merchant has validated the shipping address change.
+ spec()->UpdateWith(CreateDefaultDetails());
+ EXPECT_EQ(2, num_on_selected_information_changed_called());
+
+ // Not ready to pay since there's no selected shipping option.
+ EXPECT_FALSE(state()->is_ready_to_pay());
+
+ // Simulate that the website validates the shipping option.
+ state()->SetSelectedShippingOption("option:1");
+ auto details = CreateDefaultDetails();
+ details->shipping_options[0]->selected = true;
+ spec()->UpdateWith(std::move(details));
+ EXPECT_EQ(3, num_on_selected_information_changed_called());
EXPECT_TRUE(state()->is_ready_to_pay());
}
@@ -247,4 +278,50 @@ TEST_F(PaymentRequestStateTest, ReadyToPay_ContactInfo) {
EXPECT_TRUE(state()->is_ready_to_pay());
}
+TEST_F(PaymentRequestStateTest, SelectedShippingAddressMessage_Normalized) {
+ mojom::PaymentOptionsPtr options = mojom::PaymentOptions::New();
+ options->request_shipping = true;
+ RecreateStateWithOptions(std::move(options));
+
+ // Make the normalization not be instantaneous.
+ test_payment_request_delegate()
+ ->test_address_normalizer()
+ ->DelayNormalization();
+
+ EXPECT_EQ(0, num_on_selected_information_changed_called());
+
+ // Select an address, nothing should happen until the normalization is
+ // completed and the merchant has validated the address.
+ state()->SetSelectedShippingProfile(test_address());
+ EXPECT_EQ(1, num_on_selected_information_changed_called());
+ EXPECT_FALSE(state()->is_ready_to_pay());
+
+ // Complete the normalization.
+ test_payment_request_delegate()
+ ->test_address_normalizer()
+ ->CompleteAddressNormalization();
+ EXPECT_EQ(1, num_on_selected_information_changed_called());
+ EXPECT_FALSE(state()->is_ready_to_pay());
+
+ // Simulate that the merchant has validated the shipping address change.
+ spec()->UpdateWith(CreateDefaultDetails());
+ EXPECT_EQ(2, num_on_selected_information_changed_called());
+ // Not ready to pay because there's no selected shipping option.
+ EXPECT_FALSE(state()->is_ready_to_pay());
+
+ // Check that all the expected values were set for the shipping address.
+ EXPECT_EQ("US", selected_shipping_address()->country);
+ EXPECT_EQ("666 Erebus St.", selected_shipping_address()->address_line[0]);
+ EXPECT_EQ("Apt 8", selected_shipping_address()->address_line[1]);
+ EXPECT_EQ("CA", selected_shipping_address()->region);
+ EXPECT_EQ("Elysium", selected_shipping_address()->city);
+ EXPECT_EQ("", selected_shipping_address()->dependent_locality);
+ EXPECT_EQ("91111", selected_shipping_address()->postal_code);
+ EXPECT_EQ("", selected_shipping_address()->sorting_code);
+ EXPECT_EQ("", selected_shipping_address()->language_code);
+ EXPECT_EQ("Underworld", selected_shipping_address()->organization);
+ EXPECT_EQ("John H. Doe", selected_shipping_address()->recipient);
+ EXPECT_EQ("16502111111", selected_shipping_address()->phone);
+}
+
} // namespace payments
diff --git a/chromium/components/payments/content/payment_request_web_contents_manager.cc b/chromium/components/payments/content/payment_request_web_contents_manager.cc
index 2f11a65ebdb..315962fadc0 100644
--- a/chromium/components/payments/content/payment_request_web_contents_manager.cc
+++ b/chromium/components/payments/content/payment_request_web_contents_manager.cc
@@ -10,6 +10,7 @@
#include "base/memory/ptr_util.h"
#include "components/payments/content/payment_request.h"
#include "components/payments/core/payment_request_delegate.h"
+#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
DEFINE_WEB_CONTENTS_USER_DATA_KEY(payments::PaymentRequestWebContentsManager);
@@ -28,22 +29,47 @@ PaymentRequestWebContentsManager::GetOrCreateForWebContents(
}
void PaymentRequestWebContentsManager::CreatePaymentRequest(
+ content::RenderFrameHost* render_frame_host,
content::WebContents* web_contents,
std::unique_ptr<PaymentRequestDelegate> delegate,
mojo::InterfaceRequest<payments::mojom::PaymentRequest> request,
PaymentRequest::ObserverForTest* observer_for_testing) {
auto new_request = base::MakeUnique<PaymentRequest>(
- web_contents, std::move(delegate), this, std::move(request),
- observer_for_testing);
+ render_frame_host, web_contents, std::move(delegate), this,
+ std::move(request), observer_for_testing);
PaymentRequest* request_ptr = new_request.get();
payment_requests_.insert(std::make_pair(request_ptr, std::move(new_request)));
}
+void PaymentRequestWebContentsManager::DidStartNavigation(
+ content::NavigationHandle* navigation_handle) {
+ for (auto& it : payment_requests_) {
+ // Since the PaymentRequest dialog blocks the content of the page, the user
+ // cannot click on a link to navigate away. Therefore, if the navigation
+ // is initiated in the renderer, it does not come from the user.
+ it.second->DidStartNavigation(!navigation_handle->IsRendererInitiated());
+ }
+}
+
void PaymentRequestWebContentsManager::DestroyRequest(PaymentRequest* request) {
+ if (request == showing_)
+ showing_ = nullptr;
payment_requests_.erase(request);
}
+bool PaymentRequestWebContentsManager::CanShow(PaymentRequest* request) {
+ DCHECK(request);
+ DCHECK(payment_requests_.find(request) != payment_requests_.end());
+ if (!showing_) {
+ showing_ = request;
+ return true;
+ } else {
+ return false;
+ }
+}
+
PaymentRequestWebContentsManager::PaymentRequestWebContentsManager(
- content::WebContents* web_contents) {}
+ content::WebContents* web_contents)
+ : content::WebContentsObserver(web_contents), showing_(nullptr) {}
} // namespace payments
diff --git a/chromium/components/payments/content/payment_request_web_contents_manager.h b/chromium/components/payments/content/payment_request_web_contents_manager.h
index 08433584721..25a47effca1 100644
--- a/chromium/components/payments/content/payment_request_web_contents_manager.h
+++ b/chromium/components/payments/content/payment_request_web_contents_manager.h
@@ -5,18 +5,21 @@
#ifndef COMPONENTS_PAYMENTS_PAYMENT_REQUEST_WEB_CONTENTS_MANAGER_H_
#define COMPONENTS_PAYMENTS_PAYMENT_REQUEST_WEB_CONTENTS_MANAGER_H_
+#include <map>
#include <memory>
-#include <unordered_map>
#include "base/macros.h"
#include "components/payments/content/payment_request.h"
-#include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/mojom/payment_request.mojom.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace content {
+class RenderFrameHost;
+class NavigationHandle;
class WebContents;
-}
+} // namespace content
namespace payments {
@@ -30,7 +33,8 @@ class PaymentRequestDelegate;
// it is ready to die. Otherwise it gets destroyed when the WebContents (thus
// this class) goes away.
class PaymentRequestWebContentsManager
- : public content::WebContentsUserData<PaymentRequestWebContentsManager> {
+ : public content::WebContentsObserver,
+ public content::WebContentsUserData<PaymentRequestWebContentsManager> {
public:
~PaymentRequestWebContentsManager() override;
@@ -40,8 +44,10 @@ class PaymentRequestWebContentsManager
static PaymentRequestWebContentsManager* GetOrCreateForWebContents(
content::WebContents* web_contents);
- // Creates the PaymentRequest that will interact with this |web_contents|.
+ // Creates the PaymentRequest that will interact with this |render_frame_host|
+ // and the associated |web_contents|.
void CreatePaymentRequest(
+ content::RenderFrameHost* render_frame_host,
content::WebContents* web_contents,
std::unique_ptr<PaymentRequestDelegate> delegate,
mojo::InterfaceRequest<payments::mojom::PaymentRequest> request,
@@ -50,6 +56,16 @@ class PaymentRequestWebContentsManager
// Destroys the given |request|.
void DestroyRequest(PaymentRequest* request);
+ // Called when |request| has received the show() call. If the |request| can be
+ // shown, then returns true and assumes that |request| is now showing until
+ // DestroyRequest(|request|) is called with the same pointer. (Only one
+ // request at a time can be shown per tab.)
+ bool CanShow(PaymentRequest* request);
+
+ // WebContentsObserver::
+ void DidStartNavigation(
+ content::NavigationHandle* navigation_handle) override;
+
private:
explicit PaymentRequestWebContentsManager(content::WebContents* web_contents);
friend class content::WebContentsUserData<PaymentRequestWebContentsManager>;
@@ -59,8 +75,11 @@ class PaymentRequestWebContentsManager
// PaymentRequestWebContentsManager's lifetime is tied to the WebContents,
// these requests only get destroyed when the WebContents goes away, or when
// the requests themselves call DestroyRequest().
- std::unordered_map<PaymentRequest*, std::unique_ptr<PaymentRequest>>
- payment_requests_;
+ std::map<PaymentRequest*, std::unique_ptr<PaymentRequest>> payment_requests_;
+
+ // The currently displayed instance of PaymentRequest. Points to one of the
+ // elements in |payment_requests_|. Can be null.
+ PaymentRequest* showing_;
DISALLOW_COPY_AND_ASSIGN(PaymentRequestWebContentsManager);
};
diff --git a/chromium/components/payments/content/payment_response_helper.cc b/chromium/components/payments/content/payment_response_helper.cc
index 0d1177a9490..4e6a2994622 100644
--- a/chromium/components/payments/content/payment_response_helper.cc
+++ b/chromium/components/payments/content/payment_response_helper.cc
@@ -4,78 +4,102 @@
#include "components/payments/content/payment_response_helper.h"
+#include <string>
+
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_country.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/payments/content/payment_request_spec.h"
-#include "third_party/libphonenumber/phonenumber_api.h"
+#include "components/payments/core/payment_request_data_util.h"
+#include "components/payments/core/payment_request_delegate.h"
namespace payments {
-namespace {
-
-using ::i18n::phonenumbers::PhoneNumberUtil;
-
-} // namespace
-
PaymentResponseHelper::PaymentResponseHelper(
const std::string& app_locale,
PaymentRequestSpec* spec,
PaymentInstrument* selected_instrument,
+ PaymentRequestDelegate* payment_request_delegate,
autofill::AutofillProfile* selected_shipping_profile,
autofill::AutofillProfile* selected_contact_profile,
Delegate* delegate)
: app_locale_(app_locale),
+ is_waiting_for_shipping_address_normalization_(false),
+ is_waiting_for_instrument_details_(false),
spec_(spec),
delegate_(delegate),
selected_instrument_(selected_instrument),
- selected_shipping_profile_(selected_shipping_profile),
+ payment_request_delegate_(payment_request_delegate),
selected_contact_profile_(selected_contact_profile) {
DCHECK(spec_);
DCHECK(selected_instrument_);
DCHECK(delegate_);
+ is_waiting_for_instrument_details_ = true;
+
+ // Start to normalize the shipping address, if necessary.
+ if (spec_->request_shipping()) {
+ DCHECK(selected_shipping_profile);
+ DCHECK(spec_->selected_shipping_option());
+
+ is_waiting_for_shipping_address_normalization_ = true;
+
+ // Use the country code from the profile if it is set, otherwise infer it
+ // from the |app_locale_|.
+ std::string country_code = base::UTF16ToUTF8(
+ selected_shipping_profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
+ if (!autofill::data_util::IsValidCountryCode(country_code)) {
+ country_code =
+ autofill::AutofillCountry::CountryCodeForLocale(app_locale_);
+ }
+
+ payment_request_delegate_->GetAddressNormalizer()
+ ->StartAddressNormalization(*selected_shipping_profile, country_code,
+ /*timeout_seconds=*/5, this);
+ }
+
// Start to get the instrument details. Will call back into
// OnInstrumentDetailsReady.
selected_instrument_->InvokePaymentApp(this);
-};
+}
-PaymentResponseHelper::~PaymentResponseHelper(){};
+PaymentResponseHelper::~PaymentResponseHelper() {}
// static
mojom::PaymentAddressPtr
PaymentResponseHelper::GetMojomPaymentAddressFromAutofillProfile(
- const autofill::AutofillProfile* const profile,
+ const autofill::AutofillProfile& profile,
const std::string& app_locale) {
mojom::PaymentAddressPtr payment_address = mojom::PaymentAddress::New();
payment_address->country =
- base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
+ base::UTF16ToUTF8(profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
payment_address->address_line = base::SplitString(
- base::UTF16ToUTF8(profile->GetInfo(
+ base::UTF16ToUTF8(profile.GetInfo(
autofill::AutofillType(autofill::ADDRESS_HOME_STREET_ADDRESS),
app_locale)),
"\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
payment_address->region =
- base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_STATE));
+ base::UTF16ToUTF8(profile.GetRawInfo(autofill::ADDRESS_HOME_STATE));
payment_address->city =
- base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_CITY));
+ base::UTF16ToUTF8(profile.GetRawInfo(autofill::ADDRESS_HOME_CITY));
payment_address->dependent_locality = base::UTF16ToUTF8(
- profile->GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY));
+ profile.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY));
payment_address->postal_code =
- base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_ZIP));
+ base::UTF16ToUTF8(profile.GetRawInfo(autofill::ADDRESS_HOME_ZIP));
payment_address->sorting_code = base::UTF16ToUTF8(
- profile->GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE));
- payment_address->language_code = profile->language_code();
+ profile.GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE));
+ payment_address->language_code = profile.language_code();
payment_address->organization =
- base::UTF16ToUTF8(profile->GetRawInfo(autofill::COMPANY_NAME));
- payment_address->recipient = base::UTF16ToUTF8(profile->GetInfo(
- autofill::AutofillType(autofill::NAME_FULL), app_locale));
+ base::UTF16ToUTF8(profile.GetRawInfo(autofill::COMPANY_NAME));
+ payment_address->recipient = base::UTF16ToUTF8(
+ profile.GetInfo(autofill::AutofillType(autofill::NAME_FULL), app_locale));
// TODO(crbug.com/705945): Format phone number according to spec.
payment_address->phone =
- base::UTF16ToUTF8(profile->GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER));
+ base::UTF16ToUTF8(profile.GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER));
return payment_address;
}
@@ -83,25 +107,52 @@ PaymentResponseHelper::GetMojomPaymentAddressFromAutofillProfile(
void PaymentResponseHelper::OnInstrumentDetailsReady(
const std::string& method_name,
const std::string& stringified_details) {
+ method_name_ = method_name;
+ stringified_details_ = stringified_details;
+ is_waiting_for_instrument_details_ = false;
+
+ if (!is_waiting_for_shipping_address_normalization_)
+ GeneratePaymentResponse();
+}
+
+void PaymentResponseHelper::OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) {
+ if (is_waiting_for_shipping_address_normalization_) {
+ shipping_address_ = normalized_profile;
+ is_waiting_for_shipping_address_normalization_ = false;
+
+ if (!is_waiting_for_instrument_details_)
+ GeneratePaymentResponse();
+ }
+}
+
+void PaymentResponseHelper::OnCouldNotNormalize(
+ const autofill::AutofillProfile& profile) {
+ // Since the phone number is formatted in either case, this profile should be
+ // used.
+ OnAddressNormalized(profile);
+}
+
+void PaymentResponseHelper::GeneratePaymentResponse() {
+ DCHECK(!is_waiting_for_instrument_details_);
+ DCHECK(!is_waiting_for_shipping_address_normalization_);
+
mojom::PaymentResponsePtr payment_response = mojom::PaymentResponse::New();
// Make sure that we return the method name that the merchant specified for
// this instrument: cards can be either specified through their name (e.g.,
// "visa") or through basic-card's supportedNetworks.
payment_response->method_name =
- spec_->IsMethodSupportedThroughBasicCard(method_name)
+ spec_->IsMethodSupportedThroughBasicCard(method_name_)
? kBasicCardMethodName
- : method_name;
- payment_response->stringified_details = stringified_details;
+ : method_name_;
+ payment_response->stringified_details = stringified_details_;
// Shipping Address section
if (spec_->request_shipping()) {
- DCHECK(selected_shipping_profile_);
payment_response->shipping_address =
- GetMojomPaymentAddressFromAutofillProfile(selected_shipping_profile_,
+ GetMojomPaymentAddressFromAutofillProfile(shipping_address_,
app_locale_);
-
- DCHECK(spec_->selected_shipping_option());
payment_response->shipping_option = spec_->selected_shipping_option()->id;
}
@@ -124,23 +175,15 @@ void PaymentResponseHelper::OnInstrumentDetailsReady(
// Response, as defined in the Payment Request spec. If it's not possible,
// send the original. More info at:
// https://w3c.github.io/browser-payment-api/#paymentrequest-updated-algorithm
- // TODO(sebsg): Move this code to a reusable location.
const std::string original_number =
base::UTF16ToUTF8(selected_contact_profile_->GetInfo(
autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
app_locale_));
- i18n::phonenumbers::PhoneNumber parsed_number;
- PhoneNumberUtil* phone_number_util = PhoneNumberUtil::GetInstance();
- if (phone_number_util->Parse(original_number, "US", &parsed_number) ==
- ::i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) {
- std::string formatted_number;
- phone_number_util->Format(parsed_number,
- PhoneNumberUtil::PhoneNumberFormat::E164,
- &formatted_number);
- payment_response->payer_phone = formatted_number;
- } else {
- payment_response->payer_phone = original_number;
- }
+
+ const std::string default_region_code =
+ autofill::AutofillCountry::CountryCodeForLocale(app_locale_);
+ payment_response->payer_phone =
+ data_util::FormatPhoneForResponse(original_number, default_region_code);
}
delegate_->OnPaymentResponseReady(std::move(payment_response));
diff --git a/chromium/components/payments/content/payment_response_helper.h b/chromium/components/payments/content/payment_response_helper.h
index c8903e22b92..b9cf024718e 100644
--- a/chromium/components/payments/content/payment_response_helper.h
+++ b/chromium/components/payments/content/payment_response_helper.h
@@ -6,21 +6,19 @@
#define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_RESPONSE_HELPER_H_
#include "base/macros.h"
-#include "components/payments/content/payment_request.mojom.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/payments/core/address_normalizer.h"
#include "components/payments/core/payment_instrument.h"
-
-namespace autofill {
-class AutofillProfile;
-} // namespace autofill
+#include "components/payments/mojom/payment_request.mojom.h"
namespace payments {
+class PaymentRequestDelegate;
class PaymentRequestSpec;
-// TODO(sebsg): Asynchronously normalize the billing and shipping addresses
-// before adding them to the PaymentResponse.
// A helper class to facilitate the creation of the PaymentResponse.
-class PaymentResponseHelper : public PaymentInstrument::Delegate {
+class PaymentResponseHelper : public PaymentInstrument::Delegate,
+ public AddressNormalizer::Delegate {
public:
class Delegate {
public:
@@ -34,6 +32,7 @@ class PaymentResponseHelper : public PaymentInstrument::Delegate {
PaymentResponseHelper(const std::string& app_locale,
PaymentRequestSpec* spec,
PaymentInstrument* selected_instrument,
+ PaymentRequestDelegate* payment_request_delegate,
autofill::AutofillProfile* selected_shipping_profile,
autofill::AutofillProfile* selected_contact_profile,
Delegate* delegate);
@@ -42,7 +41,7 @@ class PaymentResponseHelper : public PaymentInstrument::Delegate {
// Returns a new mojo PaymentAddress based on the specified
// |profile| and |app_locale|.
static mojom::PaymentAddressPtr GetMojomPaymentAddressFromAutofillProfile(
- const autofill::AutofillProfile* const profile,
+ const autofill::AutofillProfile& profile,
const std::string& app_locale);
// PaymentInstrument::Delegate
@@ -51,18 +50,36 @@ class PaymentResponseHelper : public PaymentInstrument::Delegate {
const std::string& stringified_details) override;
void OnInstrumentDetailsError() override {}
+ // AddressNormalizer::Delegate
+ void OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) override;
+ void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override;
+
private:
+ // Generates the Payment Response and sends it to the delegate.
+ void GeneratePaymentResponse();
+
const std::string& app_locale_;
+ bool is_waiting_for_shipping_address_normalization_;
+ bool is_waiting_for_instrument_details_;
// Not owned, cannot be null.
PaymentRequestSpec* spec_;
Delegate* delegate_;
PaymentInstrument* selected_instrument_;
+ PaymentRequestDelegate* payment_request_delegate_;
// Not owned, can be null (dependent on the spec).
- autofill::AutofillProfile* selected_shipping_profile_;
autofill::AutofillProfile* selected_contact_profile_;
+ // A normalized copy of the shipping address, which will be included in the
+ // PaymentResponse.
+ autofill::AutofillProfile shipping_address_;
+
+ // Instrument Details.
+ std::string method_name_;
+ std::string stringified_details_;
+
DISALLOW_COPY_AND_ASSIGN(PaymentResponseHelper);
};
diff --git a/chromium/components/payments/content/payment_response_helper_unittest.cc b/chromium/components/payments/content/payment_response_helper_unittest.cc
index 7f63b6658e9..6279886ca02 100644
--- a/chromium/components/payments/content/payment_response_helper_unittest.cc
+++ b/chromium/components/payments/content/payment_response_helper_unittest.cc
@@ -15,62 +15,19 @@
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
-#include "components/payments/content/payment_request.mojom.h"
#include "components/payments/content/payment_request_spec.h"
#include "components/payments/core/autofill_payment_instrument.h"
-#include "components/payments/core/payment_request_delegate.h"
+#include "components/payments/core/test_payment_request_delegate.h"
+#include "components/payments/mojom/payment_request.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace payments {
-class FakePaymentRequestDelegate : public PaymentRequestDelegate {
- public:
- FakePaymentRequestDelegate(
- autofill::PersonalDataManager* personal_data_manager)
- : personal_data_manager_(personal_data_manager), locale_("en-US") {}
- void ShowDialog(PaymentRequest* request) override {}
-
- void CloseDialog() override {}
-
- void ShowErrorMessage() override {}
-
- autofill::PersonalDataManager* GetPersonalDataManager() override {
- return personal_data_manager_;
- }
-
- const std::string& GetApplicationLocale() const override { return locale_; }
-
- bool IsIncognito() const override { return false; }
-
- void DoFullCardRequest(
- const autofill::CreditCard& credit_card,
- base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
- result_delegate) override {
- result_delegate->OnFullCardRequestSucceeded(credit_card,
- base::ASCIIToUTF16("123"));
- }
-
- std::unique_ptr<const ::i18n::addressinput::Source> GetAddressInputSource()
- override {
- return nullptr;
- }
-
- std::unique_ptr<::i18n::addressinput::Storage> GetAddressInputStorage()
- override {
- return nullptr;
- }
-
- private:
- autofill::PersonalDataManager* personal_data_manager_;
- std::string locale_;
- DISALLOW_COPY_AND_ASSIGN(FakePaymentRequestDelegate);
-};
-
class PaymentResponseHelperTest : public testing::Test,
public PaymentResponseHelper::Delegate {
protected:
PaymentResponseHelperTest()
- : payment_request_delegate_(&test_personal_data_manager_),
+ : test_payment_request_delegate_(&test_personal_data_manager_),
address_(autofill::test::GetFullProfile()),
billing_addresses_({&address_}) {
test_personal_data_manager_.AddTestingProfile(&address_);
@@ -81,7 +38,7 @@ class PaymentResponseHelperTest : public testing::Test,
visa_card.set_use_count(5u);
autofill_instrument_ = base::MakeUnique<AutofillPaymentInstrument>(
"visa", visa_card, billing_addresses_, "en-US",
- &payment_request_delegate_);
+ &test_payment_request_delegate_);
}
~PaymentResponseHelperTest() override {}
@@ -131,12 +88,15 @@ class PaymentResponseHelperTest : public testing::Test,
const mojom::PaymentResponsePtr& response() { return payment_response_; }
autofill::AutofillProfile* test_address() { return &address_; }
PaymentInstrument* test_instrument() { return autofill_instrument_.get(); }
+ PaymentRequestDelegate* test_payment_request_delegate() {
+ return &test_payment_request_delegate_;
+ }
private:
std::unique_ptr<PaymentRequestSpec> spec_;
mojom::PaymentResponsePtr payment_response_;
autofill::TestPersonalDataManager test_personal_data_manager_;
- FakePaymentRequestDelegate payment_request_delegate_;
+ TestPaymentRequestDelegate test_payment_request_delegate_;
// Test data.
autofill::AutofillProfile address_;
@@ -149,11 +109,11 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_SupportedMethod) {
// Default options (no shipping, no contact info).
RecreateSpecWithOptions(mojom::PaymentOptions::New());
- // TODO(mathp): Currently synchronous, when async will need a RunLoop.
// "visa" is specified directly in the supportedMethods so it is returned
// as the method name.
PaymentResponseHelper helper("en-US", spec(), test_instrument(),
- test_address(), test_address(), this);
+ test_payment_request_delegate(), test_address(),
+ test_address(), this);
EXPECT_EQ("visa", response()->method_name);
EXPECT_EQ(
"{\"billingAddress\":"
@@ -186,10 +146,10 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_BasicCard) {
mojom::PaymentDetails::New(),
std::move(method_data));
- // TODO(mathp): Currently synchronous, when async will need a RunLoop.
// "basic-card" is specified so it is returned as the method name.
PaymentResponseHelper helper("en-US", spec(), test_instrument(),
- test_address(), test_address(), this);
+ test_payment_request_delegate(), test_address(),
+ test_address(), this);
EXPECT_EQ("basic-card", response()->method_name);
EXPECT_EQ(
"{\"billingAddress\":"
@@ -226,7 +186,8 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_ShippingAddress) {
GetMethodDataForVisa());
PaymentResponseHelper helper("en-US", spec(), test_instrument(),
- test_address(), test_address(), this);
+ test_payment_request_delegate(), test_address(),
+ test_address(), this);
// Check that all the expected values were set.
EXPECT_EQ("US", response()->shipping_address->country);
@@ -254,7 +215,8 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_ContactDetails_All) {
RecreateSpecWithOptions(std::move(options));
PaymentResponseHelper helper("en-US", spec(), test_instrument(),
- test_address(), test_address(), this);
+ test_payment_request_delegate(), test_address(),
+ test_address(), this);
// Check that all the expected values were set.
EXPECT_EQ("John H. Doe", response()->payer_name.value());
@@ -271,7 +233,8 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_ContactDetails_Some) {
RecreateSpecWithOptions(std::move(options));
PaymentResponseHelper helper("en-US", spec(), test_instrument(),
- test_address(), test_address(), this);
+ test_payment_request_delegate(), test_address(),
+ test_address(), this);
// Check that the name was set, but not the other values.
EXPECT_EQ("John H. Doe", response()->payer_name.value());
@@ -291,7 +254,8 @@ TEST_F(PaymentResponseHelperTest,
RecreateSpecWithOptions(std::move(options));
PaymentResponseHelper helper("en-US", spec(), test_instrument(),
- test_address(), test_address(), this);
+ test_payment_request_delegate(), test_address(),
+ test_address(), this);
// Check that the phone was formatted.
EXPECT_EQ("+15151231234", response()->payer_phone.value());
diff --git a/chromium/components/payments/content/payments_validators.h b/chromium/components/payments/content/payments_validators.h
index 135074cc1aa..33af75925be 100644
--- a/chromium/components/payments/content/payments_validators.h
+++ b/chromium/components/payments/content/payments_validators.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/macros.h"
-#include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/mojom/payment_request.mojom.h"
namespace payments {
diff --git a/chromium/components/payments/content/utility/BUILD.gn b/chromium/components/payments/content/utility/BUILD.gn
index 643a1b64437..d202928861f 100644
--- a/chromium/components/payments/content/utility/BUILD.gn
+++ b/chromium/components/payments/content/utility/BUILD.gn
@@ -11,7 +11,7 @@ static_library("utility") {
]
deps = [
"//base",
- "//components/payments/content:mojom_parser",
+ "//components/payments/mojom:mojom_parser",
"//url",
]
}
diff --git a/chromium/components/payments/content/utility/payment_manifest_parser.cc b/chromium/components/payments/content/utility/payment_manifest_parser.cc
index 4c77062fdaf..f3a4aaa4e1f 100644
--- a/chromium/components/payments/content/utility/payment_manifest_parser.cc
+++ b/chromium/components/payments/content/utility/payment_manifest_parser.cc
@@ -22,6 +22,7 @@ namespace payments {
// static
void PaymentManifestParser::Create(
+ const service_manager::BindSourceInfo& source_info,
mojom::PaymentManifestParserRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<PaymentManifestParser>(),
std::move(request));
@@ -179,14 +180,14 @@ PaymentManifestParser::~PaymentManifestParser() {}
void PaymentManifestParser::ParsePaymentMethodManifest(
const std::string& content,
- const ParsePaymentMethodManifestCallback& callback) {
- callback.Run(ParsePaymentMethodManifestIntoVector(content));
+ ParsePaymentMethodManifestCallback callback) {
+ std::move(callback).Run(ParsePaymentMethodManifestIntoVector(content));
}
void PaymentManifestParser::ParseWebAppManifest(
const std::string& content,
- const ParseWebAppManifestCallback& callback) {
- callback.Run(ParseWebAppManifestIntoVector(content));
+ ParseWebAppManifestCallback callback) {
+ std::move(callback).Run(ParseWebAppManifestIntoVector(content));
}
} // namespace payments
diff --git a/chromium/components/payments/content/utility/payment_manifest_parser.h b/chromium/components/payments/content/utility/payment_manifest_parser.h
index 3e74394ed0c..cabdc15924c 100644
--- a/chromium/components/payments/content/utility/payment_manifest_parser.h
+++ b/chromium/components/payments/content/utility/payment_manifest_parser.h
@@ -9,9 +9,13 @@
#include <vector>
#include "base/macros.h"
-#include "components/payments/content/payment_manifest_parser.mojom.h"
+#include "components/payments/mojom/payment_manifest_parser.mojom.h"
#include "url/gurl.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace payments {
// Parser for payment method manifests and web app manifests. Should be used
@@ -42,7 +46,8 @@ namespace payments {
// https://docs.google.com/document/d/1izV4uC-tiRJG3JLooqY3YRLU22tYOsLTNq0P_InPJeE
class PaymentManifestParser : public mojom::PaymentManifestParser {
public:
- static void Create(mojom::PaymentManifestParserRequest request);
+ static void Create(const service_manager::BindSourceInfo& source_info,
+ mojom::PaymentManifestParserRequest request);
static std::vector<GURL> ParsePaymentMethodManifestIntoVector(
const std::string& input);
@@ -57,9 +62,9 @@ class PaymentManifestParser : public mojom::PaymentManifestParser {
// mojom::PaymentManifestParser
void ParsePaymentMethodManifest(
const std::string& content,
- const ParsePaymentMethodManifestCallback& callback) override;
+ ParsePaymentMethodManifestCallback callback) override;
void ParseWebAppManifest(const std::string& content,
- const ParseWebAppManifestCallback& callack) override;
+ ParseWebAppManifestCallback callack) override;
private:
DISALLOW_COPY_AND_ASSIGN(PaymentManifestParser);
diff --git a/chromium/components/payments/core/BUILD.gn b/chromium/components/payments/core/BUILD.gn
index 1892be27352..eaa3d417ba7 100644
--- a/chromium/components/payments/core/BUILD.gn
+++ b/chromium/components/payments/core/BUILD.gn
@@ -4,12 +4,17 @@
static_library("core") {
sources = [
- "address_normalizer.cc",
+ "address_normalization_manager.cc",
+ "address_normalization_manager.h",
"address_normalizer.h",
+ "address_normalizer_impl.cc",
+ "address_normalizer_impl.h",
"autofill_payment_instrument.cc",
"autofill_payment_instrument.h",
"basic_card_response.cc",
"basic_card_response.h",
+ "can_make_payment_query.cc",
+ "can_make_payment_query.h",
"currency_formatter.cc",
"currency_formatter.h",
"journey_logger.cc",
@@ -21,18 +26,24 @@ static_library("core") {
"payment_method_data.cc",
"payment_method_data.h",
"payment_options_provider.h",
+ "payment_prefs.cc",
+ "payment_prefs.h",
"payment_request_data_util.cc",
"payment_request_data_util.h",
"payment_request_delegate.h",
- "profile_util.cc",
- "profile_util.h",
+ "payments_profile_comparator.cc",
+ "payments_profile_comparator.h",
"strings_util.cc",
"strings_util.h",
+ "subkey_requester.cc",
+ "subkey_requester.h",
]
deps = [
"//base",
"//components/autofill/core/browser",
+ "//components/keyed_service/core",
+ "//components/pref_registry",
"//components/strings:components_strings_grit",
"//components/ukm",
"//third_party/libphonenumber",
@@ -46,10 +57,27 @@ static_library("core") {
]
}
+static_library("test_support") {
+ testonly = true
+ sources = [
+ "test_address_normalizer.cc",
+ "test_address_normalizer.h",
+ "test_payment_request_delegate.cc",
+ "test_payment_request_delegate.h",
+ ]
+
+ deps = [
+ ":core",
+ "//base",
+ "//components/autofill/core/browser",
+ ]
+}
+
source_set("unit_tests") {
testonly = true
sources = [
- "address_normalizer_unittest.cc",
+ "address_normalization_manager_unittest.cc",
+ "address_normalizer_impl_unittest.cc",
"autofill_payment_instrument_unittest.cc",
"basic_card_response_unittest.cc",
"currency_formatter_unittest.cc",
@@ -57,20 +85,24 @@ source_set("unit_tests") {
"payment_address_unittest.cc",
"payment_method_data_unittest.cc",
"payment_request_data_util_unittest.cc",
- "profile_util_unittest.cc",
+ "payments_profile_comparator_unittest.cc",
+ "subkey_requester_unittest.cc",
]
deps = [
":core",
+ ":test_support",
"//base",
"//base/test:test_support",
"//components/autofill/core/browser",
"//components/autofill/core/browser:test_support",
"//components/metrics/proto",
+ "//components/strings:components_strings_grit",
"//components/ukm",
"//components/ukm:test_support",
"//testing/gmock",
"//testing/gtest",
"//third_party/libaddressinput:test_support",
+ "//ui/base",
]
}
diff --git a/chromium/components/payments/core/DEPS b/chromium/components/payments/core/DEPS
index 9347542b4fc..20bc8d9c09b 100644
--- a/chromium/components/payments/core/DEPS
+++ b/chromium/components/payments/core/DEPS
@@ -2,7 +2,9 @@ include_rules = [
"-components/payments/content",
"-content",
"+components/autofill/core",
+ "+components/keyed_service/core",
"+components/metrics",
+ "+components/pref_registry",
"+components/strings",
"+components/ukm",
"+third_party/libaddressinput",
diff --git a/chromium/components/payments/core/OWNERS b/chromium/components/payments/core/OWNERS
new file mode 100644
index 00000000000..396d240ce37
--- /dev/null
+++ b/chromium/components/payments/core/OWNERS
@@ -0,0 +1,4 @@
+per-file journey_logger*=sebsg@chromium.org
+per-file address_normalizer*=sebsg@chromium.org
+
+# COMPONENT: UI>Browser>Autofill>Payments
diff --git a/chromium/components/payments/core/address_normalization_manager.cc b/chromium/components/payments/core/address_normalization_manager.cc
new file mode 100644
index 00000000000..21475900670
--- /dev/null
+++ b/chromium/components/payments/core/address_normalization_manager.cc
@@ -0,0 +1,103 @@
+// Copyright 2017 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/payments/core/address_normalization_manager.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/field_types.h"
+
+namespace payments {
+
+namespace {
+constexpr int kAddressNormalizationTimeoutSeconds = 5;
+} // namespace
+
+AddressNormalizationManager::AddressNormalizationManager(
+ std::unique_ptr<AddressNormalizer> address_normalizer,
+ const std::string& default_country_code)
+ : default_country_code_(default_country_code),
+ address_normalizer_(std::move(address_normalizer)) {
+ DCHECK(autofill::data_util::IsValidCountryCode(default_country_code));
+ DCHECK(address_normalizer_);
+
+ // Start loading rules for the default country code. This happens
+ // asynchronously, and will speed up normalization later if the rules for the
+ // address' region have already been loaded.
+ address_normalizer_->LoadRulesForRegion(default_country_code);
+}
+
+AddressNormalizationManager::~AddressNormalizationManager() {}
+
+void AddressNormalizationManager::FinalizeWithCompletionCallback(
+ base::OnceClosure completion_callback) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ completion_callback_ = std::move(completion_callback);
+ accepting_requests_ = false;
+ MaybeRunCompletionCallback();
+}
+
+void AddressNormalizationManager::StartNormalizingAddress(
+ autofill::AutofillProfile* profile) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(accepting_requests_) << "FinalizeWithCompletionCallback has been "
+ "called, cannot normalize more addresses";
+
+ delegates_.push_back(base::MakeUnique<NormalizerDelegate>(
+ this, address_normalizer_.get(), profile));
+}
+
+void AddressNormalizationManager::MaybeRunCompletionCallback() {
+ if (accepting_requests_ || !completion_callback_)
+ return;
+
+ for (const auto& delegate : delegates_) {
+ if (!delegate->has_completed())
+ return;
+ }
+
+ // We're no longer accepting requests, and all the delegates have completed.
+ // Now's the time to run the completion callback.
+ std::move(completion_callback_).Run();
+}
+
+AddressNormalizationManager::NormalizerDelegate::NormalizerDelegate(
+ AddressNormalizationManager* owner,
+ AddressNormalizer* address_normalizer,
+ autofill::AutofillProfile* profile)
+ : owner_(owner), profile_(profile) {
+ DCHECK(owner_);
+ DCHECK(profile_);
+
+ std::string country_code =
+ base::UTF16ToUTF8(profile_->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
+ if (!autofill::data_util::IsValidCountryCode(country_code))
+ country_code = owner_->default_country_code_;
+
+ address_normalizer->StartAddressNormalization(
+ *profile_, country_code, kAddressNormalizationTimeoutSeconds, this);
+}
+
+void AddressNormalizationManager::NormalizerDelegate::OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) {
+ OnCompletion(normalized_profile);
+}
+
+void AddressNormalizationManager::NormalizerDelegate::OnCouldNotNormalize(
+ const autofill::AutofillProfile& profile) {
+ // Since the phone number is formatted in either case, this profile should
+ // be used.
+ OnCompletion(profile);
+}
+
+void AddressNormalizationManager::NormalizerDelegate::OnCompletion(
+ const autofill::AutofillProfile& profile) {
+ DCHECK(!has_completed_);
+ has_completed_ = true;
+ *profile_ = profile;
+ owner_->MaybeRunCompletionCallback();
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/address_normalization_manager.h b/chromium/components/payments/core/address_normalization_manager.h
new file mode 100644
index 00000000000..a838dbce183
--- /dev/null
+++ b/chromium/components/payments/core/address_normalization_manager.h
@@ -0,0 +1,107 @@
+// Copyright 2017 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_PAYMENTS_CORE_ADDRESS_NORMALIZATION_MANAGER_H_
+#define COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZATION_MANAGER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/threading/thread_checker.h"
+#include "components/payments/core/address_normalizer.h"
+
+namespace autofill {
+class AutofillProfile;
+} // namespace autofill
+
+namespace payments {
+
+class AddressNormalizer;
+
+// Class to handle multiple concurrent address normalization requests. This
+// class is not thread-safe.
+class AddressNormalizationManager {
+ public:
+ // Initializes an AddressNormalizationManager. |default_country_code| will be
+ // used if the country code in an AutofillProfile to normalize is not valid.
+ // The AddressNormalizationManager takes ownership of |address_normalizer|.
+ AddressNormalizationManager(
+ std::unique_ptr<AddressNormalizer> address_normalizer,
+ const std::string& default_country_code);
+
+ ~AddressNormalizationManager();
+
+ // Stops accepting normalization requests. If all the address normalization
+ // requests have already completed, |completion_callback| will be called
+ // before this method returns. Otherwise, it will be called as soon as the
+ // last pending request completes.
+ void FinalizeWithCompletionCallback(base::OnceClosure completion_callback);
+
+ // Normalizes the address in |profile|. This may or may not happen
+ // asynchronously. On completion, the address in |profile| will be updated
+ // with the normalized address.
+ void StartNormalizingAddress(autofill::AutofillProfile* profile);
+
+ private:
+ // Implements the payments::AddressNormalizer::Delegate interface, and
+ // notifies its parent AddressNormalizationManager when normalization has
+ // completed.
+ class NormalizerDelegate : public AddressNormalizer::Delegate {
+ public:
+ // |owner| is the parent AddressNormalizationManager, |address_normalizer|
+ // is a pointer to an instance of AddressNormalizer which will handle
+ // normalization of |profile|. |profile| will be updated when normalization
+ // is complete.
+ NormalizerDelegate(AddressNormalizationManager* owner,
+ AddressNormalizer* address_normalizer,
+ autofill::AutofillProfile* profile);
+
+ // Returns whether this delegate has completed or not.
+ bool has_completed() const { return has_completed_; }
+
+ // payments::AddressNormalizer::Delegate:
+ void OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) override;
+ void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override;
+
+ private:
+ // Helper method that handles when normalization has completed.
+ void OnCompletion(const autofill::AutofillProfile& profile);
+
+ bool has_completed_ = false;
+ AddressNormalizationManager* owner_ = nullptr;
+ autofill::AutofillProfile* profile_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(NormalizerDelegate);
+ };
+
+ friend class NormalizerDelegate;
+
+ // Runs the completion callback if all the delegates have completed.
+ void MaybeRunCompletionCallback();
+
+ // Whether the AddressNormalizationManager is still accepting requests or not.
+ bool accepting_requests_ = true;
+
+ // The default country code to use if a profile does not have a valid country.
+ const std::string default_country_code_;
+
+ // The callback to execute when all addresses have been normalized.
+ base::OnceClosure completion_callback_;
+
+ // Storage for all the delegates that handle the normalization requests.
+ std::vector<std::unique_ptr<NormalizerDelegate>> delegates_;
+
+ // The AddressNormalizer to use. Owned by this class.
+ std::unique_ptr<AddressNormalizer> address_normalizer_;
+
+ THREAD_CHECKER(thread_checker_);
+ DISALLOW_COPY_AND_ASSIGN(AddressNormalizationManager);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZATION_MANAGER_H_
diff --git a/chromium/components/payments/core/address_normalization_manager_unittest.cc b/chromium/components/payments/core/address_normalization_manager_unittest.cc
new file mode 100644
index 00000000000..c0a60fa2c80
--- /dev/null
+++ b/chromium/components/payments/core/address_normalization_manager_unittest.cc
@@ -0,0 +1,65 @@
+// Copyright 2017 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/payments/core/address_normalization_manager.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/ptr_util.h"
+#include "components/payments/core/test_address_normalizer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace payments {
+
+class AddressNormalizationManagerTest : public testing::Test {
+ protected:
+ AddressNormalizationManagerTest() {}
+
+ void Initialize(const std::string& country_code) {
+ std::unique_ptr<TestAddressNormalizer> address_normalizer =
+ base::MakeUnique<TestAddressNormalizer>();
+ address_normalizer_ = address_normalizer.get();
+ manager_ = base::MakeUnique<AddressNormalizationManager>(
+ std::move(address_normalizer), country_code);
+ }
+
+ void Finalize() {
+ manager_->FinalizeWithCompletionCallback(
+ base::BindOnce(&AddressNormalizationManagerTest::CompletionCallback,
+ base::Unretained(this)));
+ }
+
+ void CompletionCallback() { completion_callback_called_ = true; }
+
+ std::unique_ptr<AddressNormalizationManager> manager_;
+ TestAddressNormalizer* address_normalizer_ = nullptr; // Weak.
+ bool completion_callback_called_ = false;
+};
+
+TEST_F(AddressNormalizationManagerTest, SynchronousResult) {
+ Initialize("US");
+
+ autofill::AutofillProfile profile_to_normalize;
+ manager_->StartNormalizingAddress(&profile_to_normalize);
+
+ EXPECT_FALSE(completion_callback_called_);
+ Finalize();
+ EXPECT_TRUE(completion_callback_called_);
+}
+
+TEST_F(AddressNormalizationManagerTest, AsynchronousResult) {
+ Initialize("US");
+ address_normalizer_->DelayNormalization();
+
+ autofill::AutofillProfile profile_to_normalize;
+ manager_->StartNormalizingAddress(&profile_to_normalize);
+
+ EXPECT_FALSE(completion_callback_called_);
+ Finalize();
+ EXPECT_FALSE(completion_callback_called_);
+ address_normalizer_->CompleteAddressNormalization();
+ EXPECT_TRUE(completion_callback_called_);
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/address_normalizer.h b/chromium/components/payments/core/address_normalizer.h
index f3d2a240fb5..c46371cfcbc 100644
--- a/chromium/components/payments/core/address_normalizer.h
+++ b/chromium/components/payments/core/address_normalizer.h
@@ -5,25 +5,14 @@
#ifndef COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZER_H_
#define COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZER_H_
-#include <map>
-#include <memory>
#include <string>
-#include <vector>
-#include "base/macros.h"
#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
namespace autofill {
class AutofillProfile;
}
-namespace i18n {
-namespace libadderssinput {
-class Source;
-class Storage;
-}
-}
-
namespace payments {
// A class used to normalize addresses.
@@ -49,16 +38,12 @@ class AddressNormalizer : public autofill::LoadRulesListener {
virtual ~Request() {}
};
- AddressNormalizer(std::unique_ptr<::i18n::addressinput::Source> source,
- std::unique_ptr<::i18n::addressinput::Storage> storage);
- ~AddressNormalizer() override;
-
// Start loading the validation rules for the specified |region_code|.
- virtual void LoadRulesForRegion(const std::string& region_code);
+ virtual void LoadRulesForRegion(const std::string& region_code) = 0;
// Returns whether the rules for the specified |region_code| have finished
// loading.
- bool AreRulesLoadedForRegion(const std::string& region_code);
+ virtual bool AreRulesLoadedForRegion(const std::string& region_code) = 0;
// Starts the normalization of the |profile| based on the |region_code|. The
// normalized profile will be returned to the |requester| possibly
@@ -68,25 +53,11 @@ class AddressNormalizer : public autofill::LoadRulesListener {
// happen synchronously, or not at all if the rules are not already loaded.
// Will start loading the rules for the |region_code| if they had not started
// loading.
- void StartAddressNormalization(const autofill::AutofillProfile& profile,
- const std::string& region_code,
- int timeout_seconds,
- Delegate* requester);
-
- private:
- // Called when the validation rules for the |region_code| have finished
- // loading. Implementation of the LoadRulesListener interface.
- void OnAddressValidationRulesLoaded(const std::string& region_code,
- bool success) override;
-
- // Map associating a region code to pending normalizations.
- std::map<std::string, std::vector<std::unique_ptr<Request>>>
- pending_normalization_;
-
- // The address validator used to normalize addresses.
- autofill::AddressValidator address_validator_;
-
- DISALLOW_COPY_AND_ASSIGN(AddressNormalizer);
+ virtual void StartAddressNormalization(
+ const autofill::AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ Delegate* requester) = 0;
};
} // namespace payments
diff --git a/chromium/components/payments/core/address_normalizer.cc b/chromium/components/payments/core/address_normalizer_impl.cc
index d432ff11e15..12961bd99c6 100644
--- a/chromium/components/payments/core/address_normalizer.cc
+++ b/chromium/components/payments/core/address_normalizer_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/payments/core/address_normalizer.h"
+#include "components/payments/core/address_normalizer_impl.h"
#include <stddef.h>
#include <utility>
@@ -123,22 +123,22 @@ class AddressNormalizationRequest : public AddressNormalizer::Request {
} // namespace
-AddressNormalizer::AddressNormalizer(std::unique_ptr<Source> source,
- std::unique_ptr<Storage> storage)
+AddressNormalizerImpl::AddressNormalizerImpl(std::unique_ptr<Source> source,
+ std::unique_ptr<Storage> storage)
: address_validator_(std::move(source), std::move(storage), this) {}
-AddressNormalizer::~AddressNormalizer() {}
+AddressNormalizerImpl::~AddressNormalizerImpl() {}
-void AddressNormalizer::LoadRulesForRegion(const std::string& region_code) {
+void AddressNormalizerImpl::LoadRulesForRegion(const std::string& region_code) {
address_validator_.LoadRules(region_code);
}
-bool AddressNormalizer::AreRulesLoadedForRegion(
+bool AddressNormalizerImpl::AreRulesLoadedForRegion(
const std::string& region_code) {
return address_validator_.AreRulesLoadedForRegion(region_code);
}
-void AddressNormalizer::StartAddressNormalization(
+void AddressNormalizerImpl::StartAddressNormalization(
const AutofillProfile& profile,
const std::string& region_code,
int timeout_seconds,
@@ -173,7 +173,7 @@ void AddressNormalizer::StartAddressNormalization(
}
}
-void AddressNormalizer::OnAddressValidationRulesLoaded(
+void AddressNormalizerImpl::OnAddressValidationRulesLoaded(
const std::string& region_code,
bool success) {
// Check if an address normalization is pending.
diff --git a/chromium/components/payments/core/address_normalizer_impl.h b/chromium/components/payments/core/address_normalizer_impl.h
new file mode 100644
index 00000000000..1444e8ad43f
--- /dev/null
+++ b/chromium/components/payments/core/address_normalizer_impl.h
@@ -0,0 +1,62 @@
+// Copyright 2017 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_PAYMENTS_CORE_ADDRESS_NORMALIZER_IMPL_H_
+#define COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZER_IMPL_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "components/payments/core/address_normalizer.h"
+
+namespace autofill {
+class AutofillProfile;
+}
+
+namespace i18n {
+namespace addressinput {
+class Source;
+class Storage;
+}
+}
+
+namespace payments {
+
+// A class used to normalize addresses.
+class AddressNormalizerImpl : public AddressNormalizer {
+ public:
+ AddressNormalizerImpl(std::unique_ptr<::i18n::addressinput::Source> source,
+ std::unique_ptr<::i18n::addressinput::Storage> storage);
+ ~AddressNormalizerImpl() override;
+
+ // AddressNormalizer implementation.
+ void LoadRulesForRegion(const std::string& region_code) override;
+ bool AreRulesLoadedForRegion(const std::string& region_code) override;
+ void StartAddressNormalization(const autofill::AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ Delegate* requester) override;
+
+ private:
+ // Called when the validation rules for the |region_code| have finished
+ // loading. Implementation of the LoadRulesListener interface.
+ void OnAddressValidationRulesLoaded(const std::string& region_code,
+ bool success) override;
+
+ // Map associating a region code to pending normalizations.
+ std::map<std::string, std::vector<std::unique_ptr<Request>>>
+ pending_normalization_;
+
+ // The address validator used to normalize addresses.
+ autofill::AddressValidator address_validator_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressNormalizerImpl);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZER_IMPL_H_
diff --git a/chromium/components/payments/core/address_normalizer_unittest.cc b/chromium/components/payments/core/address_normalizer_impl_unittest.cc
index da9760b3ef2..495dd04030c 100644
--- a/chromium/components/payments/core/address_normalizer_unittest.cc
+++ b/chromium/components/payments/core/address_normalizer_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/payments/core/address_normalizer.h"
+#include "components/payments/core/address_normalizer_impl.h"
#include <utility>
@@ -79,13 +79,13 @@ class ChromiumTestdataSource : public TestdataSource {
DISALLOW_COPY_AND_ASSIGN(ChromiumTestdataSource);
};
-// A test subclass of the AddressNormalizer. Used to simulate rules not being
-// loaded.
-class TestAddressNormalizer : public AddressNormalizer {
+// A test subclass of the AddressNormalizerImpl. Used to simulate rules not
+// being loaded.
+class TestAddressNormalizer : public AddressNormalizerImpl {
public:
TestAddressNormalizer(std::unique_ptr<::i18n::addressinput::Source> source,
std::unique_ptr<::i18n::addressinput::Storage> storage)
- : AddressNormalizer(std::move(source), std::move(storage)),
+ : AddressNormalizerImpl(std::move(source), std::move(storage)),
should_load_rules_(true) {}
~TestAddressNormalizer() override {}
@@ -96,7 +96,7 @@ class TestAddressNormalizer : public AddressNormalizer {
void LoadRulesForRegion(const std::string& region_code) override {
if (should_load_rules_) {
- AddressNormalizer::LoadRulesForRegion(region_code);
+ AddressNormalizerImpl::LoadRulesForRegion(region_code);
}
}
diff --git a/chromium/components/payments/core/autofill_payment_instrument.cc b/chromium/components/payments/core/autofill_payment_instrument.cc
index 398edb70f90..82ff24d2c62 100644
--- a/chromium/components/payments/core/autofill_payment_instrument.cc
+++ b/chromium/components/payments/core/autofill_payment_instrument.cc
@@ -4,12 +4,17 @@
#include "components/payments/core/autofill_payment_instrument.h"
+#include <memory>
+
#include "base/json/json_writer.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
+#include "components/autofill/core/browser/autofill_country.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"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/payments/core/basic_card_response.h"
#include "components/payments/core/payment_request_data_util.h"
@@ -17,20 +22,6 @@
namespace payments {
-namespace {
-
-// Returns whether |card| has a non-empty number and cardholder name. Server
-// cards will have a non-empty number.
-bool CreditCardHasNumberAndName(const autofill::CreditCard& card,
- const std::string& app_locale) {
- return !card.number().empty() &&
- !card.GetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL),
- app_locale)
- .empty();
-}
-
-} // namespace
-
AutofillPaymentInstrument::AutofillPaymentInstrument(
const std::string& method_name,
const autofill::CreditCard& card,
@@ -39,11 +30,7 @@ AutofillPaymentInstrument::AutofillPaymentInstrument(
PaymentRequestDelegate* payment_request_delegate)
: PaymentInstrument(
method_name,
- /* label= */ card.TypeAndLastFourDigits(),
- /* sublabel= */
- card.GetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL),
- app_locale),
- autofill::data_util::GetPaymentRequestData(card.type())
+ autofill::data_util::GetPaymentRequestData(card.network())
.icon_resource_id,
PaymentInstrument::Type::AUTOFILL),
credit_card_(card),
@@ -63,21 +50,70 @@ void AutofillPaymentInstrument::InvokePaymentApp(
DCHECK(!delegate_);
delegate_ = delegate;
+ // Get the billing address.
+ if (!credit_card_.billing_address_id().empty()) {
+ autofill::AutofillProfile* billing_address =
+ autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
+ credit_card_.billing_address_id(), billing_profiles_);
+ if (billing_address)
+ billing_address_ = *billing_address;
+ }
+
+ is_waiting_for_billing_address_normalization_ = true;
+ is_waiting_for_card_unmask_ = true;
+
+ // Start the normalization of the billing address.
+ // Use the country code from the profile if it is set, otherwise infer it
+ // from the |app_locale_|.
+ std::string country_code = base::UTF16ToUTF8(
+ billing_address_.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
+ if (!autofill::data_util::IsValidCountryCode(country_code)) {
+ country_code = autofill::AutofillCountry::CountryCodeForLocale(app_locale_);
+ }
+ payment_request_delegate_->GetAddressNormalizer()->StartAddressNormalization(
+ billing_address_, country_code, /*timeout_seconds=*/5, this);
+
payment_request_delegate_->DoFullCardRequest(credit_card_,
weak_ptr_factory_.GetWeakPtr());
}
bool AutofillPaymentInstrument::IsCompleteForPayment() {
- // A card is complete for payment if it's not expired, its number is not
- // empty (a server card fills this condition) and there is a cardholder name.
- // TODO(crbug.com/709776): Check for billing address association.
- return !credit_card_.IsExpired(autofill::AutofillClock::Now()) &&
- CreditCardHasNumberAndName(credit_card_, app_locale_);
+ // COMPLETE or EXPIRED cards are considered valid for payment. The user will
+ // be prompted to enter the new expiration at the CVC step.
+ return autofill::GetCompletionStatusForCard(credit_card_, app_locale_,
+ billing_profiles_) <=
+ autofill::CREDIT_CARD_EXPIRED;
+}
+
+base::string16 AutofillPaymentInstrument::GetMissingInfoLabel() {
+ return autofill::GetCompletionMessageForCard(
+ autofill::GetCompletionStatusForCard(credit_card_, app_locale_,
+ billing_profiles_));
}
bool AutofillPaymentInstrument::IsValidForCanMakePayment() {
- // An expired card is still valid for the purposes of canMakePayment.
- return CreditCardHasNumberAndName(credit_card_, app_locale_);
+ autofill::CreditCardCompletionStatus status =
+ autofill::GetCompletionStatusForCard(credit_card_, app_locale_,
+ billing_profiles_);
+ // Card has to have a cardholder name and number for the purposes of
+ // CanMakePayment. An expired card is still valid at this stage.
+ return !(status & autofill::CREDIT_CARD_NO_CARDHOLDER ||
+ status & autofill::CREDIT_CARD_NO_NUMBER);
+}
+
+void AutofillPaymentInstrument::RecordUse() {
+ // Record the use of the credit card.
+ payment_request_delegate_->GetPersonalDataManager()->RecordUseOf(
+ credit_card_);
+}
+
+base::string16 AutofillPaymentInstrument::GetLabel() const {
+ return credit_card_.NetworkAndLastFourDigits();
+}
+
+base::string16 AutofillPaymentInstrument::GetSublabel() const {
+ return credit_card_.GetInfo(
+ autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL), app_locale_);
}
void AutofillPaymentInstrument::OnFullCardRequestSucceeded(
@@ -85,19 +121,53 @@ void AutofillPaymentInstrument::OnFullCardRequestSucceeded(
const base::string16& cvc) {
DCHECK(delegate_);
credit_card_ = card;
+ cvc_ = cvc;
+ is_waiting_for_card_unmask_ = false;
+
+ if (!is_waiting_for_billing_address_normalization_)
+ GenerateBasicCardResponse();
+}
+
+void AutofillPaymentInstrument::OnFullCardRequestFailed() {
+ // The user may have cancelled the unmask or something has gone wrong (e.g.,
+ // the network request failed). In all cases, reset the |delegate_| so another
+ // request can start.
+ delegate_ = nullptr;
+}
+
+void AutofillPaymentInstrument::OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) {
+ DCHECK(is_waiting_for_billing_address_normalization_);
+
+ billing_address_ = normalized_profile;
+ is_waiting_for_billing_address_normalization_ = false;
+
+ if (!is_waiting_for_card_unmask_)
+ GenerateBasicCardResponse();
+}
+
+void AutofillPaymentInstrument::OnCouldNotNormalize(
+ const autofill::AutofillProfile& profile) {
+ // Since the phone number is formatted in either case, this profile should be
+ // used.
+ OnAddressNormalized(profile);
+}
+
+void AutofillPaymentInstrument::GenerateBasicCardResponse() {
+ DCHECK(!is_waiting_for_billing_address_normalization_);
+ DCHECK(!is_waiting_for_card_unmask_);
+ DCHECK(delegate_);
+
std::unique_ptr<base::DictionaryValue> response_value =
payments::data_util::GetBasicCardResponseFromAutofillCreditCard(
- credit_card_, cvc, billing_profiles_, app_locale_)
+ credit_card_, cvc_, billing_address_, app_locale_)
.ToDictionaryValue();
std::string stringified_details;
base::JSONWriter::Write(*response_value, &stringified_details);
delegate_->OnInstrumentDetailsReady(method_name(), stringified_details);
- delegate_ = nullptr;
-}
-void AutofillPaymentInstrument::OnFullCardRequestFailed() {
- // TODO(anthonyvd): Do something with the error.
delegate_ = nullptr;
+ cvc_ = base::UTF8ToUTF16("");
}
} // namespace payments
diff --git a/chromium/components/payments/core/autofill_payment_instrument.h b/chromium/components/payments/core/autofill_payment_instrument.h
index 84b343ab4c6..6df075f621a 100644
--- a/chromium/components/payments/core/autofill_payment_instrument.h
+++ b/chromium/components/payments/core/autofill_payment_instrument.h
@@ -10,14 +10,13 @@
#include <vector>
#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/full_card_request.h"
+#include "components/payments/core/address_normalizer.h"
#include "components/payments/core/payment_instrument.h"
-namespace autofill {
-class AutofillProfile;
-}
-
namespace payments {
class PaymentRequestDelegate;
@@ -26,7 +25,8 @@ class PaymentRequestDelegate;
// Request.
class AutofillPaymentInstrument
: public PaymentInstrument,
- public autofill::payments::FullCardRequest::ResultDelegate {
+ public autofill::payments::FullCardRequest::ResultDelegate,
+ public AddressNormalizer::Delegate {
public:
// |billing_profiles| is owned by the caller and should outlive this object.
// |payment_request_delegate| must outlive this object.
@@ -41,16 +41,28 @@ class AutofillPaymentInstrument
// PaymentInstrument:
void InvokePaymentApp(PaymentInstrument::Delegate* delegate) override;
bool IsCompleteForPayment() override;
+ base::string16 GetMissingInfoLabel() override;
bool IsValidForCanMakePayment() override;
+ void RecordUse() override;
+ base::string16 GetLabel() const override;
+ base::string16 GetSublabel() const override;
// autofill::payments::FullCardRequest::ResultDelegate:
void OnFullCardRequestSucceeded(const autofill::CreditCard& card,
const base::string16& cvc) override;
void OnFullCardRequestFailed() override;
+ // AddressNormalizer::Delegate:
+ void OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) override;
+ void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override;
+
autofill::CreditCard* credit_card() { return &credit_card_; }
private:
+ // Generates the basic card response and sends it to the delegate.
+ void GenerateBasicCardResponse();
+
// A copy of the card is owned by this object.
autofill::CreditCard credit_card_;
// Not owned by this object, should outlive this.
@@ -60,6 +72,12 @@ class AutofillPaymentInstrument
PaymentInstrument::Delegate* delegate_;
PaymentRequestDelegate* payment_request_delegate_;
+ autofill::AutofillProfile billing_address_;
+
+ base::string16 cvc_;
+
+ bool is_waiting_for_card_unmask_;
+ bool is_waiting_for_billing_address_normalization_;
base::WeakPtrFactory<AutofillPaymentInstrument> weak_ptr_factory_;
diff --git a/chromium/components/payments/core/autofill_payment_instrument_unittest.cc b/chromium/components/payments/core/autofill_payment_instrument_unittest.cc
index 7b9db0be6a9..7f84726ad79 100644
--- a/chromium/components/payments/core/autofill_payment_instrument_unittest.cc
+++ b/chromium/components/payments/core/autofill_payment_instrument_unittest.cc
@@ -5,14 +5,141 @@
#include "components/payments/core/autofill_payment_instrument.h"
#include "base/macros.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/credit_card.h"
+#include "components/payments/core/address_normalizer.h"
+#include "components/payments/core/test_payment_request_delegate.h"
+#include "components/strings/grit/components_strings.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
namespace payments {
+namespace {
+
+class FakePaymentInstrumentDelegate : public PaymentInstrument::Delegate {
+ public:
+ FakePaymentInstrumentDelegate() {}
+
+ void OnInstrumentDetailsReady(
+ const std::string& method_name,
+ const std::string& stringified_details) override {
+ on_instrument_details_ready_called_ = true;
+ }
+
+ void OnInstrumentDetailsError() override {
+ on_instrument_details_error_called_ = true;
+ }
+
+ bool WasOnInstrumentDetailsReadyCalled() {
+ return on_instrument_details_ready_called_;
+ }
+
+ bool WasOnInstrumentDetailsErrorCalled() {
+ return on_instrument_details_error_called_;
+ }
+
+ private:
+ bool on_instrument_details_ready_called_ = false;
+ bool on_instrument_details_error_called_ = false;
+};
+
+class FakeAddressNormalizer : public AddressNormalizer {
+ public:
+ FakeAddressNormalizer() {}
+
+ void LoadRulesForRegion(const std::string& region_code) override {}
+
+ bool AreRulesLoadedForRegion(const std::string& region_code) override {
+ return true;
+ }
+
+ void StartAddressNormalization(
+ const autofill::AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ AddressNormalizer::Delegate* requester) override {
+ profile_ = profile;
+ requester_ = requester;
+ }
+
+ void OnAddressValidationRulesLoaded(const std::string& region_code,
+ bool success) override {}
+
+ void CompleteAddressNormalization() {
+ requester_->OnAddressNormalized(profile_);
+ }
+
+ private:
+ autofill::AutofillProfile profile_;
+ AddressNormalizer::Delegate* requester_;
+};
+
+class FakePaymentRequestDelegate : public PaymentRequestDelegate {
+ public:
+ FakePaymentRequestDelegate()
+ : locale_("en-US"), last_committed_url_("https://shop.com") {}
+ void ShowDialog(PaymentRequest* request) override {}
+
+ void CloseDialog() override {}
+
+ void ShowErrorMessage() override {}
+
+ autofill::PersonalDataManager* GetPersonalDataManager() override {
+ return nullptr;
+ }
+
+ const std::string& GetApplicationLocale() const override { return locale_; }
+
+ bool IsIncognito() const override { return false; }
+
+ bool IsSslCertificateValid() override { return true; }
+
+ const GURL& GetLastCommittedURL() const override {
+ return last_committed_url_;
+ }
+
+ void DoFullCardRequest(
+ const autofill::CreditCard& credit_card,
+ base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
+ result_delegate) override {
+ full_card_request_card_ = credit_card;
+ full_card_result_delegate_ = result_delegate;
+ }
+
+ AddressNormalizer* GetAddressNormalizer() override {
+ return &address_normalizer_;
+ }
+
+ FakeAddressNormalizer* GetTestAddressNormalizer() {
+ return &address_normalizer_;
+ }
+
+ void CompleteFullCardRequest() {
+ full_card_result_delegate_->OnFullCardRequestSucceeded(
+ full_card_request_card_, base::ASCIIToUTF16("123"));
+ }
+
+ autofill::RegionDataLoader* GetRegionDataLoader() override { return nullptr; }
+
+ ukm::UkmRecorder* GetUkmRecorder() override { return nullptr; }
+
+ private:
+ std::string locale_;
+ const GURL last_committed_url_;
+ FakeAddressNormalizer address_normalizer_;
+
+ autofill::CreditCard full_card_request_card_;
+ base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
+ full_card_result_delegate_;
+ DISALLOW_COPY_AND_ASSIGN(FakePaymentRequestDelegate);
+};
+
+} // namespace
+
class AutofillPaymentInstrumentTest : public testing::Test {
protected:
AutofillPaymentInstrumentTest()
@@ -40,15 +167,17 @@ TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment) {
AutofillPaymentInstrument instrument("visa", local_credit_card(),
billing_profiles(), "en-US", nullptr);
EXPECT_TRUE(instrument.IsCompleteForPayment());
+ EXPECT_TRUE(instrument.GetMissingInfoLabel().empty());
}
-// An expired local card is not a valid instrument for payment.
+// An expired local card is still a valid instrument for payment.
TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_Expired) {
autofill::CreditCard& card = local_credit_card();
card.SetExpirationYear(2016); // Expired.
AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
"en-US", nullptr);
- EXPECT_FALSE(instrument.IsCompleteForPayment());
+ EXPECT_TRUE(instrument.IsCompleteForPayment());
+ EXPECT_EQ(base::string16(), instrument.GetMissingInfoLabel());
}
// A local card with no name is not a valid instrument for payment.
@@ -56,35 +185,92 @@ TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_NoName) {
autofill::CreditCard& card = local_credit_card();
card.SetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL),
base::ASCIIToUTF16(""), "en-US");
+ base::string16 missing_info;
AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
"en-US", nullptr);
EXPECT_FALSE(instrument.IsCompleteForPayment());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_NAME_ON_CARD_REQUIRED),
+ instrument.GetMissingInfoLabel());
}
// A local card with no name is not a valid instrument for payment.
TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_NoNumber) {
autofill::CreditCard& card = local_credit_card();
card.SetNumber(base::ASCIIToUTF16(""));
+ base::string16 missing_info;
+ AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
+ "en-US", nullptr);
+ EXPECT_FALSE(instrument.IsCompleteForPayment());
+ EXPECT_EQ(l10n_util::GetStringUTF16(
+ IDS_PAYMENTS_CARD_NUMBER_INVALID_VALIDATION_MESSAGE),
+ instrument.GetMissingInfoLabel());
+}
+
+// A local card with no billing address id is not a valid instrument for
+// payment.
+TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_NoBillinbAddressId) {
+ autofill::CreditCard& card = local_credit_card();
+ card.set_billing_address_id("");
+ base::string16 missing_info;
+ AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
+ "en-US", nullptr);
+ EXPECT_FALSE(instrument.IsCompleteForPayment());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF16(IDS_PAYMENTS_CARD_BILLING_ADDRESS_REQUIRED),
+ instrument.GetMissingInfoLabel());
+}
+
+// A local card with an invalid billing address id is not a valid instrument for
+// payment.
+TEST_F(AutofillPaymentInstrumentTest,
+ IsCompleteForPayment_InvalidBillinbAddressId) {
+ autofill::CreditCard& card = local_credit_card();
+ card.set_billing_address_id("InvalidBillingAddressId");
+ base::string16 missing_info;
AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
"en-US", nullptr);
EXPECT_FALSE(instrument.IsCompleteForPayment());
+ EXPECT_EQ(
+ l10n_util::GetStringUTF16(IDS_PAYMENTS_CARD_BILLING_ADDRESS_REQUIRED),
+ instrument.GetMissingInfoLabel());
+}
+
+// A local card with no name and no number is not a valid instrument for
+// payment.
+TEST_F(AutofillPaymentInstrumentTest,
+ IsCompleteForPayment_MultipleThingsMissing) {
+ autofill::CreditCard& card = local_credit_card();
+ card.SetNumber(base::ASCIIToUTF16(""));
+ card.SetInfo(autofill::AutofillType(autofill::CREDIT_CARD_NAME_FULL),
+ base::ASCIIToUTF16(""), "en-US");
+ AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
+ "en-US", nullptr);
+ EXPECT_FALSE(instrument.IsCompleteForPayment());
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_MORE_INFORMATION_REQUIRED),
+ instrument.GetMissingInfoLabel());
}
// A Masked (server) card is a valid instrument for payment.
TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_MaskedCard) {
autofill::CreditCard card = autofill::test::GetMaskedServerCard();
+ ASSERT_GT(billing_profiles().size(), 0UL);
+ card.set_billing_address_id(billing_profiles()[0]->guid());
AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
"en-US", nullptr);
EXPECT_TRUE(instrument.IsCompleteForPayment());
+ EXPECT_TRUE(instrument.GetMissingInfoLabel().empty());
}
-// An expired masked (server) card is not a valid instrument for payment.
+// An expired masked (server) card is still a valid instrument for payment.
TEST_F(AutofillPaymentInstrumentTest, IsCompleteForPayment_ExpiredMaskedCard) {
autofill::CreditCard card = autofill::test::GetMaskedServerCard();
+ ASSERT_GT(billing_profiles().size(), 0UL);
+ card.set_billing_address_id(billing_profiles()[0]->guid());
card.SetExpirationYear(2016); // Expired.
AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
"en-US", nullptr);
- EXPECT_FALSE(instrument.IsCompleteForPayment());
+ EXPECT_TRUE(instrument.IsCompleteForPayment());
+ EXPECT_EQ(base::string16(), instrument.GetMissingInfoLabel());
}
// An expired card is a valid instrument for canMakePayment.
@@ -124,4 +310,60 @@ TEST_F(AutofillPaymentInstrumentTest, IsValidForCanMakePayment_NoNumber) {
EXPECT_FALSE(instrument.IsValidForCanMakePayment());
}
+// Tests that the autofill instrument only calls OnInstrumentDetailsReady when
+// the billing address has been normalized and the card has been unmasked.
+TEST_F(AutofillPaymentInstrumentTest,
+ InvokePaymentApp_NormalizationBeforeUnmask) {
+ TestPaymentRequestDelegate delegate(/*personal_data_manager=*/nullptr);
+ delegate.DelayFullCardRequestCompletion();
+ delegate.test_address_normalizer()->DelayNormalization();
+
+ autofill::CreditCard& card = local_credit_card();
+ card.SetNumber(base::ASCIIToUTF16(""));
+ AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
+ "en-US", &delegate);
+
+ FakePaymentInstrumentDelegate instrument_delegate;
+
+ instrument.InvokePaymentApp(&instrument_delegate);
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled());
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled());
+
+ delegate.test_address_normalizer()->CompleteAddressNormalization();
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled());
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled());
+
+ delegate.CompleteFullCardRequest();
+ EXPECT_TRUE(instrument_delegate.WasOnInstrumentDetailsReadyCalled());
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled());
+}
+
+// Tests that the autofill instrument only calls OnInstrumentDetailsReady when
+// the billing address has been normalized and the card has been unmasked.
+TEST_F(AutofillPaymentInstrumentTest,
+ InvokePaymentApp_UnmaskBeforeNormalization) {
+ TestPaymentRequestDelegate delegate(/*personal_data_manager=*/nullptr);
+ delegate.DelayFullCardRequestCompletion();
+ delegate.test_address_normalizer()->DelayNormalization();
+
+ autofill::CreditCard& card = local_credit_card();
+ card.SetNumber(base::ASCIIToUTF16(""));
+ AutofillPaymentInstrument instrument("visa", card, billing_profiles(),
+ "en-US", &delegate);
+
+ FakePaymentInstrumentDelegate instrument_delegate;
+
+ instrument.InvokePaymentApp(&instrument_delegate);
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled());
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled());
+
+ delegate.CompleteFullCardRequest();
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled());
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled());
+
+ delegate.test_address_normalizer()->CompleteAddressNormalization();
+ EXPECT_TRUE(instrument_delegate.WasOnInstrumentDetailsReadyCalled());
+ EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled());
+}
+
} // namespace payments
diff --git a/chromium/components/payments/core/can_make_payment_query.cc b/chromium/components/payments/core/can_make_payment_query.cc
new file mode 100644
index 00000000000..c4264be89be
--- /dev/null
+++ b/chromium/components/payments/core/can_make_payment_query.cc
@@ -0,0 +1,44 @@
+// Copyright 2017 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/payments/core/can_make_payment_query.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/memory/ptr_util.h"
+#include "base/time/time.h"
+
+namespace payments {
+
+CanMakePaymentQuery::CanMakePaymentQuery() {}
+
+CanMakePaymentQuery::~CanMakePaymentQuery() {}
+
+bool CanMakePaymentQuery::CanQuery(
+ const GURL& frame_origin,
+ const std::map<std::string, std::set<std::string>>& query) {
+ const auto& it = queries_.find(frame_origin);
+ if (it == queries_.end()) {
+ std::unique_ptr<base::OneShotTimer> timer =
+ base::MakeUnique<base::OneShotTimer>();
+ timer->Start(FROM_HERE, base::TimeDelta::FromMinutes(30),
+ base::Bind(&CanMakePaymentQuery::ExpireQuotaForFrameOrigin,
+ base::Unretained(this), frame_origin));
+ timers_.insert(std::make_pair(frame_origin, std::move(timer)));
+ queries_.insert(std::make_pair(frame_origin, query));
+ return true;
+ }
+
+ return it->second == query;
+}
+
+void CanMakePaymentQuery::ExpireQuotaForFrameOrigin(const GURL& frame_origin) {
+ timers_.erase(frame_origin);
+ queries_.erase(frame_origin);
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/can_make_payment_query.h b/chromium/components/payments/core/can_make_payment_query.h
new file mode 100644
index 00000000000..69da5761453
--- /dev/null
+++ b/chromium/components/payments/core/can_make_payment_query.h
@@ -0,0 +1,50 @@
+// Copyright 2017 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_PAYMENTS_CORE_CAN_MAKE_PAYMENT_QUERY_H_
+#define COMPONENTS_PAYMENTS_CORE_CAN_MAKE_PAYMENT_QUERY_H_
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+
+#include "base/macros.h"
+#include "base/timer/timer.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "url/gurl.h"
+
+namespace payments {
+
+// Keeps track of canMakePayment() queries per browser context.
+class CanMakePaymentQuery : public KeyedService {
+ public:
+ CanMakePaymentQuery();
+ ~CanMakePaymentQuery() override;
+
+ // Returns whether |frame_origin| can call canMakePayment() with |query|,
+ // which is a mapping of payment method names to the corresponding
+ // JSON-stringified payment method data. Remembers the frame-to-query mapping
+ // for 30 minutes to enforce the quota.
+ bool CanQuery(const GURL& frame_origin,
+ const std::map<std::string, std::set<std::string>>& query);
+
+ private:
+ void ExpireQuotaForFrameOrigin(const GURL& frame_origin);
+
+ // A mapping of frame origin to the timer that, when fired, allows the frame
+ // to invoke canMakePayment() with a different query.
+ std::map<GURL, std::unique_ptr<base::OneShotTimer>> timers_;
+
+ // A mapping of frame origin to its last query. Each query is a mapping of
+ // payment method names to the corresponding JSON-stringified payment method
+ // data.
+ std::map<GURL, std::map<std::string, std::set<std::string>>> queries_;
+
+ DISALLOW_COPY_AND_ASSIGN(CanMakePaymentQuery);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_CAN_MAKE_PAYMENT_QUERY_H_
diff --git a/chromium/components/payments/core/currency_formatter.cc b/chromium/components/payments/core/currency_formatter.cc
index 4eb4f74ea06..dae2383c932 100644
--- a/chromium/components/payments/core/currency_formatter.cc
+++ b/chromium/components/payments/core/currency_formatter.cc
@@ -104,19 +104,23 @@ base::string16 CurrencyFormatter::Format(const std::string& amount) {
if (output.isEmpty())
return base::UTF8ToUTF16(amount);
- // Explicitly removes the currency code (truncated to its 3-letter and
- // 2-letter versions) from the output, because callers are expected to
+ // Explicitly removes the currency code (truncated to its 3-letter, 2-letter
+ // and 1-letter versions) from the output, because callers are expected to
// display the currency code alongside this result.
//
// 3+ letters: If currency code is "ABCDEF" or "BTX", this code will
// transform "ABC55.00"/"BTX55.00" to "55.00".
// 2 letters: If currency code is "CAD", this code will transform "CA$55.00"
// to "$55.00" (en_US) or "55,00 $ CA" to "55,00 $" (fr_FR).
+ // 1 letter: If currency code is "AUD", this code will transform "A$55.00"
+ // to "$55.00" (en_US).
icu::UnicodeString tmp_currency_code(*currency_code_);
tmp_currency_code.truncate(3);
output.findAndReplace(tmp_currency_code, "");
tmp_currency_code.truncate(2);
output.findAndReplace(tmp_currency_code, "");
+ tmp_currency_code.truncate(1);
+ output.findAndReplace(tmp_currency_code, "");
// Trims any unicode whitespace (including non-breaking space).
if (u_isUWhiteSpace(output[0])) {
output.remove(0, 1);
diff --git a/chromium/components/payments/core/currency_formatter_unittest.cc b/chromium/components/payments/core/currency_formatter_unittest.cc
index e55a2fe29a5..41793ef4c0c 100644
--- a/chromium/components/payments/core/currency_formatter_unittest.cc
+++ b/chromium/components/payments/core/currency_formatter_unittest.cc
@@ -81,6 +81,11 @@ INSTANTIATE_TEST_CASE_P(
TestCase("55.00", "CAD", "fr_CA", "55,00 $", "CAD"),
TestCase("55.00", "CAD", "fr_FR", "55,00 $", "CAD"),
+ TestCase("55.00", "AUD", "en_US", "$55.00", "AUD"),
+ TestCase("55.00", "AUD", "en_CA", "$55.00", "AUD"),
+ TestCase("55.00", "AUD", "fr_CA", "55,00 $", "AUD"),
+ TestCase("55.00", "AUD", "fr_FR", "55,00 $", "AUD"),
+
TestCase("55.00", "BRL", "en_US", "R$55.00", "BRL"),
TestCase("55.00", "BRL", "fr_CA", "55,00 R$", "BRL"),
TestCase("55.00", "BRL", "pt_BR", "R$55,00", "BRL"),
@@ -119,8 +124,12 @@ INSTANTIATE_TEST_CASE_P(
"USD",
"fr_FR",
"123 456 789 012 345 678 901 234 567 890,123456789 $",
- "USD"),
+ "USD")));
+INSTANTIATE_TEST_CASE_P(
+ CurrencySystems,
+ PaymentsCurrencyFormatterTest,
+ testing::Values(
// When the currency system is not ISO4217, only the amount is formatted
// using the locale (there is no other indication of currency).
TestCase("55.00",
diff --git a/chromium/components/payments/core/journey_logger.cc b/chromium/components/payments/core/journey_logger.cc
index dc25cf6f1bf..7eee988f1be 100644
--- a/chromium/components/payments/core/journey_logger.cc
+++ b/chromium/components/payments/core/journey_logger.cc
@@ -8,9 +8,8 @@
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "components/autofill/core/browser/autofill_experiments.h"
-#include "components/ukm/ukm_entry_builder.h"
-#include "components/ukm/ukm_service.h"
+#include "components/ukm/public/ukm_entry_builder.h"
+#include "components/ukm/public/ukm_recorder.h"
namespace payments {
@@ -66,16 +65,16 @@ std::string GetHistogramNameSuffix(
JourneyLogger::JourneyLogger(bool is_incognito,
const GURL& url,
- ukm::UkmService* ukm_service)
- : was_can_make_payments_used_(false),
- could_make_payment_(false),
- was_show_called_(false),
- is_incognito_(is_incognito),
+ ukm::UkmRecorder* ukm_recorder)
+ : is_incognito_(is_incognito),
events_(EVENT_INITIATED),
url_(url),
- ukm_service_(ukm_service) {}
+ ukm_recorder_(ukm_recorder) {}
-JourneyLogger::~JourneyLogger() {}
+JourneyLogger::~JourneyLogger() {
+ if (was_show_called_)
+ DCHECK(has_recorded_);
+}
void JourneyLogger::IncrementSelectionAdds(Section section) {
DCHECK_LT(section, SECTION_MAX);
@@ -107,12 +106,68 @@ void JourneyLogger::SetShowCalled() {
was_show_called_ = true;
}
+void JourneyLogger::SetCompleted() {
+ UMA_HISTOGRAM_BOOLEAN("PaymentRequest.CheckoutFunnel.Completed", true);
+
+ RecordJourneyStatsHistograms(COMPLETION_STATUS_COMPLETED);
+}
+
+void JourneyLogger::SetAborted(AbortReason reason) {
+ base::UmaHistogramEnumeration("PaymentRequest.CheckoutFunnel.Aborted", reason,
+ ABORT_REASON_MAX);
+
+ if (reason == ABORT_REASON_ABORTED_BY_USER ||
+ reason == ABORT_REASON_USER_NAVIGATION)
+ RecordJourneyStatsHistograms(COMPLETION_STATUS_USER_ABORTED);
+ else
+ RecordJourneyStatsHistograms(COMPLETION_STATUS_OTHER_ABORTED);
+}
+
+#ifdef OS_ANDROID
+void JourneyLogger::SetNotShown(NotShownReason reason) {
+ base::UmaHistogramEnumeration("PaymentRequest.CheckoutFunnel.NoShow", reason,
+ NOT_SHOWN_REASON_MAX);
+
+ // Record that that Payment Request was initiated here, because nothing else
+ // will be recorded for a Payment Request that was not shown to the user.
+ UMA_HISTOGRAM_BOOLEAN("PaymentRequest.CheckoutFunnel.Initiated", true);
+}
+#endif
+
void JourneyLogger::SetEventOccurred(Event event) {
events_ |= event;
}
+void JourneyLogger::SetSelectedPaymentMethod(
+ SelectedPaymentMethod payment_method) {
+ payment_method_ = payment_method;
+}
+
+void JourneyLogger::SetRequestedInformation(bool requested_shipping,
+ bool requested_email,
+ bool requested_phone,
+ bool requested_name) {
+ // This method should only be called once per Payment Request.
+ DCHECK(requested_information_ == REQUESTED_INFORMATION_MAX);
+
+ requested_information_ =
+ (requested_shipping ? REQUESTED_INFORMATION_SHIPPING : 0) |
+ (requested_email ? REQUESTED_INFORMATION_EMAIL : 0) |
+ (requested_phone ? REQUESTED_INFORMATION_PHONE : 0) |
+ (requested_name ? REQUESTED_INFORMATION_NAME : 0);
+}
+
void JourneyLogger::RecordJourneyStatsHistograms(
CompletionStatus completion_status) {
+ DCHECK(!has_recorded_);
+ has_recorded_ = true;
+
+ RecordCheckoutFlowMetrics();
+
+ RecordPaymentMethodMetric();
+
+ RecordRequestedInformationMetrics();
+
RecordSectionSpecificStats(completion_status);
// Record the CanMakePayment metrics based on whether the transaction was
@@ -122,6 +177,33 @@ void JourneyLogger::RecordJourneyStatsHistograms(
RecordUrlKeyedMetrics(completion_status);
}
+void JourneyLogger::RecordCheckoutFlowMetrics() {
+ UMA_HISTOGRAM_BOOLEAN("PaymentRequest.CheckoutFunnel.Initiated", true);
+
+ if (events_ & EVENT_SHOWN)
+ UMA_HISTOGRAM_BOOLEAN("PaymentRequest.CheckoutFunnel.Shown", true);
+
+ if (events_ & EVENT_PAY_CLICKED)
+ UMA_HISTOGRAM_BOOLEAN("PaymentRequest.CheckoutFunnel.PayClicked", true);
+
+ if (events_ & EVENT_RECEIVED_INSTRUMENT_DETAILS)
+ UMA_HISTOGRAM_BOOLEAN(
+ "PaymentRequest.CheckoutFunnel.ReceivedInstrumentDetails", true);
+
+ if (events_ & EVENT_SKIPPED_SHOW)
+ UMA_HISTOGRAM_BOOLEAN("PaymentRequest.CheckoutFunnel.SkippedShow", true);
+}
+
+void JourneyLogger::RecordPaymentMethodMetric() {
+ base::UmaHistogramEnumeration("PaymentRequest.SelectedPaymentMethod",
+ payment_method_, SELECTED_PAYMENT_METHOD_MAX);
+}
+
+void JourneyLogger::RecordRequestedInformationMetrics() {
+ UMA_HISTOGRAM_ENUMERATION("PaymentRequest.RequestedInformation",
+ requested_information_, REQUESTED_INFORMATION_MAX);
+}
+
void JourneyLogger::RecordSectionSpecificStats(
CompletionStatus completion_status) {
// Record whether the user had suggestions for each requested information.
@@ -194,12 +276,12 @@ void JourneyLogger::RecordCanMakePaymentEffectOnShow() {
int effect_on_show = 0;
if (was_show_called_)
- effect_on_show |= CMP_SHOW_DID_SHOW;
+ effect_on_show |= CMP_EFFECT_ON_SHOW_DID_SHOW;
if (could_make_payment_)
- effect_on_show |= CMP_SHOW_COULD_MAKE_PAYMENT;
+ effect_on_show |= CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT;
UMA_HISTOGRAM_ENUMERATION("PaymentRequest.CanMakePayment.Used.EffectOnShow",
- effect_on_show, CMP_SHOW_MAX);
+ effect_on_show, CMP_EFFECT_ON_SHOW_MAX);
}
void JourneyLogger::RecordCanMakePaymentEffectOnCompletion(
@@ -221,14 +303,15 @@ void JourneyLogger::RecordCanMakePaymentEffectOnCompletion(
}
void JourneyLogger::RecordUrlKeyedMetrics(CompletionStatus completion_status) {
- if (!autofill::IsUkmLoggingEnabled() || !ukm_service_ || !url_.is_valid())
+ if (!ukm_recorder_ || !url_.is_valid())
return;
// Record the Checkout Funnel UKM.
- int32_t source_id = ukm_service_->GetNewSourceID();
- ukm_service_->UpdateSourceURL(source_id, url_);
- std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
- source_id, internal::kUKMCheckoutEventsEntryName);
+ ukm::SourceId source_id = ukm_recorder_->GetNewSourceID();
+ ukm_recorder_->UpdateSourceURL(source_id, url_);
+ std::unique_ptr<ukm::UkmEntryBuilder> builder =
+ ukm_recorder_->GetEntryBuilder(source_id,
+ internal::kUKMCheckoutEventsEntryName);
builder->AddMetric(internal::kUKMCompletionStatusMetricName,
completion_status);
builder->AddMetric(internal::kUKMEventsMetricName, events_);
diff --git a/chromium/components/payments/core/journey_logger.h b/chromium/components/payments/core/journey_logger.h
index c3330eb8540..b37f7ae48dd 100644
--- a/chromium/components/payments/core/journey_logger.h
+++ b/chromium/components/payments/core/journey_logger.h
@@ -11,7 +11,7 @@
#include "url/gurl.h"
namespace ukm {
-class UkmService;
+class UkmRecorder;
}
namespace payments {
@@ -30,11 +30,12 @@ extern const char kUKMEventsMetricName[];
// of the Payment Request.
class JourneyLogger {
public:
- // Note: These constants should always be in sync with their counterpart in
- // components/payments/content/android/java/src/org/chromium/components/
- // payments/JourneyLogger.java.
+ // Note: Java counterparts will be generated for these enums.
+
// The different sections of a Payment Request. Used to record journey
// stats.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: Section
enum Section {
SECTION_CONTACT_INFO = 0,
SECTION_CREDIT_CARDS = 1,
@@ -43,14 +44,51 @@ class JourneyLogger {
};
// For the CanMakePayment histograms.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: CanMakePaymentUsage
enum CanMakePaymentUsage {
CAN_MAKE_PAYMENT_USED = 0,
CAN_MAKE_PAYMENT_NOT_USED = 1,
CAN_MAKE_PAYMENT_USE_MAX,
};
+ // The information requested by the merchant.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: RequestedInformation
+ enum RequestedInformation {
+ REQUESTED_INFORMATION_NONE = 0,
+ REQUESTED_INFORMATION_EMAIL = 1 << 0,
+ REQUESTED_INFORMATION_PHONE = 1 << 1,
+ REQUESTED_INFORMATION_SHIPPING = 1 << 2,
+ REQUESTED_INFORMATION_NAME = 1 << 3,
+ REQUESTED_INFORMATION_MAX = 16,
+ };
+
+ // The payment method that was used by the user to complete the transaction.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: SelectedPaymentMethod
+ enum SelectedPaymentMethod {
+ SELECTED_PAYMENT_METHOD_CREDIT_CARD = 0,
+ SELECTED_PAYMENT_METHOD_ANDROID_PAY = 1,
+ SELECTED_PAYMENT_METHOD_OTHER_PAYMENT_APP = 2,
+ SELECTED_PAYMENT_METHOD_MAX = 3,
+ };
+
+ // Used to mesure the impact of the CanMakePayment return value on whether the
+ // Payment Request is shown to the user.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: CanMakePaymentEffectOnShow
+ enum CmpEffectOnShow {
+ CMP_EFFECT_ON_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW = 0,
+ CMP_EFFECT_ON_SHOW_DID_SHOW = 1 << 0,
+ CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT = 1 << 1,
+ CMP_EFFECT_ON_SHOW_MAX = 4,
+ };
+
// Used to log different parameters' effect on whether the transaction was
// completed.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: CompletionStatus
enum CompletionStatus {
COMPLETION_STATUS_COMPLETED = 0,
COMPLETION_STATUS_USER_ABORTED = 1,
@@ -60,25 +98,51 @@ class JourneyLogger {
// Used to record the different events that happened during the Payment
// Request.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: Event
enum Event {
EVENT_INITIATED = 0,
EVENT_SHOWN = 1 << 0,
EVENT_PAY_CLICKED = 1 << 1,
EVENT_RECEIVED_INSTRUMENT_DETAILS = 1 << 2,
EVENT_SKIPPED_SHOW = 1 << 3,
- EVENT_MAX = 16,
+ EVENT_ENUM_MAX = 16,
};
- // Used to mesure the impact of the CanMakePayment return value on whether the
- // Payment Request is shown to the user.
- static const int CMP_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW = 0;
- static const int CMP_SHOW_DID_SHOW = 1 << 0;
- static const int CMP_SHOW_COULD_MAKE_PAYMENT = 1 << 1;
- static const int CMP_SHOW_MAX = 4;
+ // The reason why the Payment Request was aborted.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: AbortReason
+ enum AbortReason {
+ ABORT_REASON_ABORTED_BY_USER = 0,
+ ABORT_REASON_ABORTED_BY_MERCHANT = 1,
+ ABORT_REASON_INVALID_DATA_FROM_RENDERER = 2,
+ ABORT_REASON_MOJO_CONNECTION_ERROR = 3,
+ ABORT_REASON_MOJO_RENDERER_CLOSING = 4,
+ ABORT_REASON_INSTRUMENT_DETAILS_ERROR = 5,
+ ABORT_REASON_NO_MATCHING_PAYMENT_METHOD = 6, // Deprecated.
+ ABORT_REASON_NO_SUPPORTED_PAYMENT_METHOD = 7, // Deprecated.
+ ABORT_REASON_OTHER = 8,
+ ABORT_REASON_USER_NAVIGATION = 9,
+ ABORT_REASON_MERCHANT_NAVIGATION = 10,
+ ABORT_REASON_MAX,
+ };
+
+#ifdef OS_ANDROID
+ // The reason why the Payment Request was not shown to the user.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.payments
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: NotShownReason
+ enum NotShownReason {
+ NOT_SHOWN_REASON_NO_MATCHING_PAYMENT_METHOD = 0,
+ NOT_SHOWN_REASON_NO_SUPPORTED_PAYMENT_METHOD = 1,
+ NOT_SHOWN_REASON_CONCURRENT_REQUESTS = 2,
+ NOT_SHOWN_REASON_OTHER = 3,
+ NOT_SHOWN_REASON_MAX = 4,
+ };
+#endif
JourneyLogger(bool is_incognito,
const GURL& url,
- ukm::UkmService* ukm_service);
+ ukm::UkmRecorder* ukm_recorder);
~JourneyLogger();
// Increments the number of selection adds for the specified section.
@@ -103,11 +167,28 @@ class JourneyLogger {
// Records that an event occurred.
void SetEventOccurred(Event event);
- // Records the histograms for all the sections that were requested by the
- // merchant and for the usage of the CanMakePayment method and its effect on
- // the transaction. This method should be called when the Payment Request has
- // either been completed or aborted.
- void RecordJourneyStatsHistograms(CompletionStatus completion_status);
+ // Records the payment method that was used to complete the Payment Request.
+ void SetSelectedPaymentMethod(SelectedPaymentMethod payment_method);
+
+ // Records the user information requested by the merchant.
+ void SetRequestedInformation(bool requested_shipping,
+ bool requested_email,
+ bool requested_phone,
+ bool requested_name);
+
+ // Records that the Payment Request was completed successfully, and starts the
+ // logging of all the journey metrics.
+ void SetCompleted();
+
+ // Records that the Payment Request was aborted along with the reason. Also
+ // starts the logging of all the journey metrics.
+ void SetAborted(AbortReason reason);
+
+#ifdef OS_ANDROID
+ // Records that the Payment Request was not shown to the user, along with the
+ // reason.
+ void SetNotShown(NotShownReason reason);
+#endif
private:
static const int NUMBER_OF_SECTIONS = 3;
@@ -137,6 +218,22 @@ class JourneyLogger {
};
// Records the histograms for all the sections that were requested by the
+ // merchant and for the usage of the CanMakePayment method and its effect on
+ // the transaction. This method should be called when the Payment Request has
+ // either been completed or aborted.
+ void RecordJourneyStatsHistograms(CompletionStatus completion_status);
+
+ // Records the histograms for all the steps of a complete checkout flow that
+ // were reached.
+ void RecordCheckoutFlowMetrics();
+
+ // Records the metric about the selected payment method.
+ void RecordPaymentMethodMetric();
+
+ // Records the user information that the merchant requested.
+ void RecordRequestedInformationMetrics();
+
+ // Records the histograms for all the sections that were requested by the
// merchant.
void RecordSectionSpecificStats(CompletionStatus completion_status);
@@ -157,18 +254,25 @@ class JourneyLogger {
void RecordUrlKeyedMetrics(CompletionStatus completion_status);
SectionStats sections_[NUMBER_OF_SECTIONS];
- bool was_can_make_payments_used_;
- bool could_make_payment_;
- bool was_show_called_;
+ bool has_recorded_ = false;
+ bool was_can_make_payments_used_ = false;
+ bool could_make_payment_ = false;
+ bool was_show_called_ = false;
bool is_incognito_;
// Accumulates the many events that have happened during the Payment Request.
int events_;
+ // To keep track of the selected payment method.
+ SelectedPaymentMethod payment_method_ = SELECTED_PAYMENT_METHOD_MAX;
+
+ // Keeps track of the user information requested by the merchant.
+ int requested_information_ = REQUESTED_INFORMATION_MAX;
+
const GURL url_;
// Not owned, will outlive this object.
- ukm::UkmService* ukm_service_;
+ ukm::UkmRecorder* ukm_recorder_;
DISALLOW_COPY_AND_ASSIGN(JourneyLogger);
};
diff --git a/chromium/components/payments/core/journey_logger_unittest.cc b/chromium/components/payments/core/journey_logger_unittest.cc
index fbb1efd4cbd..941fccb580d 100644
--- a/chromium/components/payments/core/journey_logger_unittest.cc
+++ b/chromium/components/payments/core/journey_logger_unittest.cc
@@ -7,10 +7,8 @@
#include "base/metrics/metrics_hashes.h"
#include "base/test/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
-#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/metrics/proto/ukm/entry.pb.h"
-#include "components/ukm/test_ukm_service.h"
-#include "components/ukm/ukm_entry.h"
+#include "components/ukm/test_ukm_recorder.h"
#include "components/ukm/ukm_source.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -19,29 +17,15 @@ using testing::ContainerEq;
namespace payments {
-namespace {
-// Finds the specified UKM metric by |name| in the specified UKM |metrics|.
-const ukm::Entry_Metric* FindMetric(
- const char* name,
- const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) {
- for (const auto& metric : metrics) {
- if (metric.metric_hash() == base::HashMetricName(name))
- return &metric;
- }
- return nullptr;
-}
-} // namespace
-
// Tests the canMakePayment stats for the case where the merchant does not use
// it and does not show the PaymentRequest to the user.
TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentNotCalled_NoShow) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED,
@@ -60,7 +44,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentNotCalled_ShowAndUserAbort) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -70,8 +54,7 @@ TEST(JourneyLoggerTest,
// The merchant does not query CanMakePayment, show the PaymentRequest and the
// user aborts it.
logger.SetShowCalled();
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED,
@@ -90,7 +73,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentNotCalled_ShowAndOtherAbort) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -100,8 +83,7 @@ TEST(JourneyLoggerTest,
// The merchant does not query CanMakePayment, show the PaymentRequest and
// there is an abort not initiated by the user.
logger.SetShowCalled();
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED,
@@ -120,7 +102,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentNotCalled_ShowAndComplete) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -130,8 +112,7 @@ TEST(JourneyLoggerTest,
// The merchant does not query CanMakePayment, show the PaymentRequest and the
// user completes it.
logger.SetShowCalled();
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_NOT_USED,
@@ -150,7 +131,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_FalseAndNoShow) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -159,8 +140,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetCanMakePaymentValue(false);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -169,7 +149,8 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW, 1);
+ JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW,
+ 1);
// There should be no completion stats since PR was not shown to the user.
EXPECT_THAT(
@@ -184,7 +165,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_TrueAndNoShow) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -193,8 +174,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetCanMakePaymentValue(true);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -203,7 +183,7 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_COULD_MAKE_PAYMENT, 1);
+ JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT, 1);
// There should be no completion stats since PR was not shown to the user.
EXPECT_THAT(
@@ -218,7 +198,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_FalseShowAndUserAbort) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -228,8 +208,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetShowCalled();
logger.SetCanMakePaymentValue(false);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -238,7 +217,7 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_DID_SHOW, 1);
+ JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1);
// There should be a record for an abort when CanMakePayment is false but the
// PR is shown to the user.
histogram_tester.ExpectBucketCount(
@@ -252,7 +231,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_FalseShowAndOtherAbort) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -262,8 +241,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetShowCalled();
logger.SetCanMakePaymentValue(false);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -272,7 +250,7 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_DID_SHOW, 1);
+ JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1);
// There should be a record for an abort when CanMakePayment is false but the
// PR is shown to the user.
histogram_tester.ExpectBucketCount(
@@ -286,7 +264,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_FalseShowAndComplete) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -296,8 +274,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetShowCalled();
logger.SetCanMakePaymentValue(false);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -306,7 +283,7 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_DID_SHOW, 1);
+ JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW, 1);
// There should be a record for an completion when CanMakePayment is false but
// the PR is shown to the user.
@@ -321,7 +298,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_TrueShowAndUserAbort) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -331,8 +308,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetShowCalled();
logger.SetCanMakePaymentValue(true);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -341,8 +317,8 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_DID_SHOW |
- JourneyLogger::CMP_SHOW_COULD_MAKE_PAYMENT,
+ JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW |
+ JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT,
1);
// There should be a record for an abort when CanMakePayment is true and the
// PR is shown to the user.
@@ -357,7 +333,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_TrueShowAndOtherAbort) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -367,8 +343,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetShowCalled();
logger.SetCanMakePaymentValue(true);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER);
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -377,8 +352,8 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_DID_SHOW |
- JourneyLogger::CMP_SHOW_COULD_MAKE_PAYMENT,
+ JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW |
+ JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT,
1);
// There should be a record for an abort when CanMakePayment is true and the
// PR is shown to the user.
@@ -393,7 +368,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePaymentCalled_TrueShowAndComplete) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -403,8 +378,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetShowCalled();
logger.SetCanMakePaymentValue(true);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
histogram_tester.ExpectBucketCount("PaymentRequest.CanMakePayment.Usage",
JourneyLogger::CAN_MAKE_PAYMENT_USED, 1);
@@ -413,8 +387,8 @@ TEST(JourneyLoggerTest,
// shown.
histogram_tester.ExpectBucketCount(
"PaymentRequest.CanMakePayment.Used.EffectOnShow",
- JourneyLogger::CMP_SHOW_DID_SHOW |
- JourneyLogger::CMP_SHOW_COULD_MAKE_PAYMENT,
+ JourneyLogger::CMP_EFFECT_ON_SHOW_DID_SHOW |
+ JourneyLogger::CMP_EFFECT_ON_SHOW_COULD_MAKE_PAYMENT,
1);
// There should be a record for a completion when CanMakePayment is true and
// the PR is shown to the user.
@@ -429,7 +403,7 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_CanMakePayment_IncognitoTab) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/true, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -439,8 +413,7 @@ TEST(JourneyLoggerTest,
// The user cannot make payment and the PaymentRequest is not shown.
logger.SetShowCalled();
logger.SetCanMakePaymentValue(true);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
// Expect no log for CanMakePayment.
EXPECT_THAT(
@@ -454,14 +427,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_SuggestionsForEverything_Completed) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1);
// Simulate that the user completes the checkout.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion",
@@ -479,14 +451,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_SuggestionsForEverything_UserAborted) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1);
// Simulate that the user aborts the checkout.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion",
@@ -504,14 +475,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_SuggestionsForEverything_OtherAborted) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1);
// Simulate that the checkout is aborted.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER);
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion",
@@ -530,14 +500,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_SuggestionsForEverything_Incognito) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/true, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1);
// Simulate that the user completes the checkout.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserHadSuggestionsForEverything.EffectOnCompletion",
@@ -555,14 +524,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_NoSuggestionsForEverything_Completed) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0);
// Simulate that the user completes the checkout.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
+ logger.SetCompleted();
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserDidNotHaveSuggestionsForEverything."
@@ -581,14 +549,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_NoSuggestionsForEverything_UserAborted) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0);
// Simulate that the user aborts the checkout.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserDidNotHaveSuggestionsForEverything."
@@ -607,14 +574,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_NoSuggestionsForEverything_OtherAborted) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0);
- // Simulate that the user aborts the checkout.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED);
+ // Simulate that the the checkout is aborted.
+ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER);
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserDidNotHaveSuggestionsForEverything."
@@ -634,14 +600,13 @@ TEST(JourneyLoggerTest,
RecordJourneyStatsHistograms_NoSuggestionsForEverything_Incognito) {
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/true, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Simulate that the user had suggestions for all the requested sections.
logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0);
// Simulate that the user aborts the checkout.
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
histogram_tester.ExpectBucketCount(
"PaymentRequest.UserDidNotHaveSuggestionsForEverything."
@@ -659,9 +624,9 @@ TEST(JourneyLoggerTest,
TEST(JourneyLoggerTest, RecordJourneyStatsHistograms_TwoPaymentRequests) {
base::HistogramTester histogram_tester;
JourneyLogger logger1(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
JourneyLogger logger2(/*is_incognito=*/false, /*url=*/GURL(""),
- /*ukm_service=*/nullptr);
+ /*ukm_recorder=*/nullptr);
// Make the two loggers have different data.
logger1.SetShowCalled();
@@ -673,10 +638,8 @@ TEST(JourneyLoggerTest, RecordJourneyStatsHistograms_TwoPaymentRequests) {
logger2.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0);
// Simulate that the user completes one checkout and aborts the other.
- logger1.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_COMPLETED);
- logger2.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger1.SetCompleted();
+ logger2.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
// Make sure the appropriate metrics were logged for logger1.
histogram_tester.ExpectBucketCount(
@@ -703,51 +666,41 @@ TEST(JourneyLoggerTest, RecordJourneyStatsHistograms_TwoPaymentRequests) {
// Tests that the Payment Request UKMs are logged correctly.
TEST(JourneyLoggerTest, RecordJourneyStatsHistograms_CheckoutFunnelUkm) {
- base::test::ScopedFeatureList scoped_feature_list_;
- scoped_feature_list_.InitAndEnableFeature(autofill::kAutofillUkmLogging);
-
- ukm::UkmServiceTestingHarness ukm_service_test_harness;
- ukm::TestUkmService* ukm_service =
- ukm_service_test_harness.test_ukm_service();
+ ukm::TestUkmRecorder ukm_recorder;
char test_url[] = "http://www.google.com/";
base::HistogramTester histogram_tester;
JourneyLogger logger(/*is_incognito=*/true, /*url=*/GURL(test_url),
- /*ukm_service=*/ukm_service);
+ /*ukm_recorder=*/&ukm_recorder);
// Simulate that the user aborts after being shown the Payment Request and
// clicking pay.
logger.SetEventOccurred(JourneyLogger::EVENT_SHOWN);
logger.SetEventOccurred(JourneyLogger::EVENT_PAY_CLICKED);
- logger.RecordJourneyStatsHistograms(
- JourneyLogger::COMPLETION_STATUS_USER_ABORTED);
+ logger.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER);
// Make sure the UKM was logged correctly.
- ASSERT_EQ(1U, ukm_service->sources_count());
- const ukm::UkmSource* source = ukm_service->GetSourceForUrl(test_url);
+ ASSERT_EQ(1U, ukm_recorder.sources_count());
+ const ukm::UkmSource* source = ukm_recorder.GetSourceForUrl(test_url);
ASSERT_NE(nullptr, source);
- ASSERT_EQ(1U, ukm_service->entries_count());
- const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
- EXPECT_EQ(source->id(), entry->source_id());
-
- ukm::Entry entry_proto;
- entry->PopulateProto(&entry_proto);
- EXPECT_EQ(source->id(), entry_proto.source_id());
+ ASSERT_EQ(1U, ukm_recorder.entries_count());
+ const ukm::mojom::UkmEntry* entry = ukm_recorder.GetEntry(0);
+ EXPECT_EQ(source->id(), entry->source_id);
EXPECT_EQ(base::HashMetricName(internal::kUKMCheckoutEventsEntryName),
- entry_proto.event_hash());
+ entry->event_hash);
- const ukm::Entry_Metric* status_metric = FindMetric(
- internal::kUKMCompletionStatusMetricName, entry_proto.metrics());
+ const ukm::mojom::UkmMetric* status_metric = ukm::TestUkmRecorder::FindMetric(
+ entry, internal::kUKMCompletionStatusMetricName);
ASSERT_NE(nullptr, status_metric);
EXPECT_EQ(JourneyLogger::COMPLETION_STATUS_USER_ABORTED,
- status_metric->value());
+ status_metric->value);
- const ukm::Entry_Metric* step_metric =
- FindMetric(internal::kUKMEventsMetricName, entry_proto.metrics());
+ const ukm::mojom::UkmMetric* step_metric =
+ ukm::TestUkmRecorder::FindMetric(entry, internal::kUKMEventsMetricName);
ASSERT_NE(nullptr, step_metric);
EXPECT_EQ(JourneyLogger::EVENT_SHOWN | JourneyLogger::EVENT_PAY_CLICKED,
- step_metric->value());
+ step_metric->value);
}
-} // namespace payments \ No newline at end of file
+} // namespace payments
diff --git a/chromium/components/payments/core/payment_instrument.cc b/chromium/components/payments/core/payment_instrument.cc
index 097917c8427..7f2c8a0f0e8 100644
--- a/chromium/components/payments/core/payment_instrument.cc
+++ b/chromium/components/payments/core/payment_instrument.cc
@@ -7,13 +7,9 @@
namespace payments {
PaymentInstrument::PaymentInstrument(const std::string& method_name,
- const base::string16& label,
- const base::string16& sublabel,
int icon_resource_id,
Type type)
: method_name_(method_name),
- label_(label),
- sublabel_(sublabel),
icon_resource_id_(icon_resource_id),
type_(type) {}
diff --git a/chromium/components/payments/core/payment_instrument.h b/chromium/components/payments/core/payment_instrument.h
index 5d70847f4f2..6da07693d8e 100644
--- a/chromium/components/payments/core/payment_instrument.h
+++ b/chromium/components/payments/core/payment_instrument.h
@@ -39,27 +39,29 @@ class PaymentInstrument {
// Returns whether the instrument is complete to be used as a payment method
// without further editing.
virtual bool IsCompleteForPayment() = 0;
+ // Returns a message to indicate to the user what's missing for the instrument
+ // to be complete for payment.
+ virtual base::string16 GetMissingInfoLabel() = 0;
// Returns whether the instrument is valid for the purposes of responding to
// canMakePayment.
virtual bool IsValidForCanMakePayment() = 0;
+ // Records the use of this payment instrument.
+ virtual void RecordUse() = 0;
+ // Return the sub/label of payment instrument, to be displayed to the user.
+ virtual base::string16 GetLabel() const = 0;
+ virtual base::string16 GetSublabel() const = 0;
const std::string& method_name() const { return method_name_; }
- const base::string16& label() const { return label_; }
- const base::string16& sublabel() const { return sublabel_; }
int icon_resource_id() const { return icon_resource_id_; }
Type type() { return type_; }
protected:
PaymentInstrument(const std::string& method_name,
- const base::string16& label,
- const base::string16& sublabel,
int icon_resource_id,
Type type);
private:
const std::string method_name_;
- const base::string16 label_;
- const base::string16 sublabel_;
int icon_resource_id_;
Type type_;
diff --git a/chromium/components/payments/core/payment_prefs.cc b/chromium/components/payments/core/payment_prefs.cc
new file mode 100644
index 00000000000..854769dad25
--- /dev/null
+++ b/chromium/components/payments/core/payment_prefs.cc
@@ -0,0 +1,18 @@
+// Copyright 2017 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/payments/core/payment_prefs.h"
+
+#include "components/pref_registry/pref_registry_syncable.h"
+
+namespace payments {
+
+const char kPaymentsFirstTransactionCompleted[] =
+ "payments.first_transaction_completed";
+
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterBooleanPref(kPaymentsFirstTransactionCompleted, false);
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/payment_prefs.h b/chromium/components/payments/core/payment_prefs.h
new file mode 100644
index 00000000000..1d5917ff2ac
--- /dev/null
+++ b/chromium/components/payments/core/payment_prefs.h
@@ -0,0 +1,22 @@
+// Copyright 2017 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_PAYMENTS_CORE_PAYMENT_PREFS_H_
+#define COMPONENTS_PAYMENTS_CORE_PAYMENT_PREFS_H_
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+namespace payments {
+
+// True if the profile has already successfully completed at least one payment
+// request transaction.
+extern const char kPaymentsFirstTransactionCompleted[];
+
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_PAYMENT_PREFS_H_
diff --git a/chromium/components/payments/core/payment_request_data_util.cc b/chromium/components/payments/core/payment_request_data_util.cc
index 8fb65723122..7f689419603 100644
--- a/chromium/components/payments/core/payment_request_data_util.cc
+++ b/chromium/components/payments/core/payment_request_data_util.cc
@@ -7,10 +7,13 @@
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_country.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/validation.h"
#include "components/payments/core/basic_card_response.h"
#include "components/payments/core/payment_address.h"
#include "components/payments/core/payment_method_data.h"
@@ -71,7 +74,7 @@ PaymentAddress GetPaymentAddressFromAutofillProfile(
BasicCardResponse GetBasicCardResponseFromAutofillCreditCard(
const autofill::CreditCard& card,
const base::string16& cvc,
- const std::vector<autofill::AutofillProfile*>& billing_profiles,
+ const autofill::AutofillProfile& billing_profile,
const std::string& app_locale) {
BasicCardResponse response;
response.cardholder_name = card.GetRawInfo(autofill::CREDIT_CARD_NAME_FULL);
@@ -81,79 +84,99 @@ BasicCardResponse GetBasicCardResponseFromAutofillCreditCard(
card.GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR);
response.card_security_code = cvc;
- // TODO(crbug.com/602666): Ensure we reach here only if the card has a billing
- // address. Then add DCHECK(!card->billing_address_id().empty()).
- if (!card.billing_address_id().empty()) {
- const autofill::AutofillProfile* billing_address =
- autofill::PersonalDataManager::GetProfileFromProfilesByGUID(
- card.billing_address_id(), billing_profiles);
- DCHECK(billing_address);
- response.billing_address =
- GetPaymentAddressFromAutofillProfile(*billing_address, app_locale);
- }
+ response.billing_address =
+ GetPaymentAddressFromAutofillProfile(billing_profile, app_locale);
return response;
}
-bool ParseBasicCardSupportedNetworks(
+void ParseBasicCardSupportedNetworks(
const std::vector<PaymentMethodData>& method_data,
std::vector<std::string>* out_supported_networks,
std::set<std::string>* out_basic_card_specified_networks) {
DCHECK(out_supported_networks->empty());
DCHECK(out_basic_card_specified_networks->empty());
- std::set<std::string> card_networks{"amex", "diners", "discover",
- "jcb", "mastercard", "mir",
- "unionpay", "visa"};
+ const std::set<std::string> kBasicCardNetworks{
+ "amex", "diners", "discover", "jcb",
+ "mastercard", "mir", "unionpay", "visa"};
+ std::set<std::string> remaining_card_networks(kBasicCardNetworks);
for (const PaymentMethodData& method_data_entry : method_data) {
if (method_data_entry.supported_methods.empty())
- return false;
+ return;
for (const std::string& method : method_data_entry.supported_methods) {
if (method.empty())
continue;
- // If a card network is specified right in "supportedMethods", add it.
const char kBasicCardMethodName[] = "basic-card";
- auto card_it = card_networks.find(method);
- if (card_it != card_networks.end()) {
+ // If a card network is specified right in "supportedMethods", add it.
+ auto card_it = remaining_card_networks.find(method);
+ if (card_it != remaining_card_networks.end()) {
out_supported_networks->push_back(method);
- // |method| removed from |card_networks| so that it is not doubly added
- // to |supported_card_networks_| if "basic-card" is specified with no
- // supported networks.
- card_networks.erase(card_it);
+ // |method| removed from |remaining_card_networks| so that it is not
+ // doubly added to |out_supported_networks|.
+ remaining_card_networks.erase(card_it);
} else if (method == kBasicCardMethodName) {
// For the "basic-card" method, check "supportedNetworks".
if (method_data_entry.supported_networks.empty()) {
// Empty |supported_networks| means all networks are supported.
out_supported_networks->insert(out_supported_networks->end(),
- card_networks.begin(),
- card_networks.end());
- out_basic_card_specified_networks->insert(card_networks.begin(),
- card_networks.end());
+ remaining_card_networks.begin(),
+ remaining_card_networks.end());
+ out_basic_card_specified_networks->insert(kBasicCardNetworks.begin(),
+ kBasicCardNetworks.end());
// Clear the set so that no further networks are added to
// |out_supported_networks|.
- card_networks.clear();
+ remaining_card_networks.clear();
} else {
// The merchant has specified a few basic card supported networks. Use
// the mapping to transform to known basic-card types.
for (const std::string& supported_network :
method_data_entry.supported_networks) {
// Make sure that the network was not already added to
- // |out_supported_networks|. If it's still in |card_networks| it's
- // fair game.
- auto it = card_networks.find(supported_network);
- if (it != card_networks.end()) {
+ // |out_supported_networks|. If it's still in
+ // |remaining_card_networks| it's fair game.
+ auto it = remaining_card_networks.find(supported_network);
+ if (it != remaining_card_networks.end()) {
out_supported_networks->push_back(supported_network);
+ remaining_card_networks.erase(it);
+ }
+ if (kBasicCardNetworks.find(supported_network) !=
+ kBasicCardNetworks.end()) {
out_basic_card_specified_networks->insert(supported_network);
- card_networks.erase(it);
}
}
}
}
}
}
- return true;
+}
+
+base::string16 GetFormattedPhoneNumberForDisplay(
+ const autofill::AutofillProfile& profile,
+ const std::string& locale) {
+ // Since the "+" is removed for some country's phone numbers, try to add a "+"
+ // and see if it is a valid phone number for a country.
+ // Having two "+" in front of a number has no effect on the formatted number.
+ // The reason for this is international phone numbers for another country. For
+ // example, without adding a "+", the US number 1-415-123-1234 for an AU
+ // address would be wrongly formatted as +61 1-415-123-1234 which is invalid.
+ std::string phone = base::UTF16ToUTF8(profile.GetInfo(
+ autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), locale));
+ std::string tentative_intl_phone = "+" + phone;
+
+ // Always favor the tentative international phone number if it's determined as
+ // being a valid number.
+ if (autofill::IsValidPhoneNumber(
+ base::UTF8ToUTF16(tentative_intl_phone),
+ GetCountryCodeWithFallback(&profile, locale))) {
+ return base::UTF8ToUTF16(FormatPhoneForDisplay(
+ tentative_intl_phone, GetCountryCodeWithFallback(&profile, locale)));
+ }
+
+ return base::UTF8ToUTF16(FormatPhoneForDisplay(
+ phone, GetCountryCodeWithFallback(&profile, locale)));
}
std::string FormatPhoneForDisplay(const std::string& phone_number,
@@ -168,5 +191,14 @@ std::string FormatPhoneForResponse(const std::string& phone_number,
PhoneNumberUtil::PhoneNumberFormat::E164);
}
+std::string GetCountryCodeWithFallback(const autofill::AutofillProfile* profile,
+ const std::string& app_locale) {
+ std::string country_code =
+ base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
+ if (!autofill::data_util::IsValidCountryCode(country_code))
+ country_code = autofill::AutofillCountry::CountryCodeForLocale(app_locale);
+ return country_code;
+}
+
} // namespace data_util
} // namespace payments
diff --git a/chromium/components/payments/core/payment_request_data_util.h b/chromium/components/payments/core/payment_request_data_util.h
index f3120c8c3d6..c301946d5e5 100644
--- a/chromium/components/payments/core/payment_request_data_util.h
+++ b/chromium/components/payments/core/payment_request_data_util.h
@@ -35,7 +35,7 @@ PaymentAddress GetPaymentAddressFromAutofillProfile(
BasicCardResponse GetBasicCardResponseFromAutofillCreditCard(
const autofill::CreditCard& card,
const base::string16& cvc,
- const std::vector<autofill::AutofillProfile*>& billing_profiles,
+ const autofill::AutofillProfile& billing_profile,
const std::string& app_locale);
// Parse the supported card networks from supportedMethods and "basic-card"'s
@@ -44,15 +44,19 @@ BasicCardResponse GetBasicCardResponseFromAutofillCreditCard(
// |out_basic_card_supported_networks| is a subset of |out_supported_networks|
// that includes all networks that were specified as part of "basic-card". This
// is used to know whether to return the card network name (e.g., "visa") or
-// "basic-card" in the PaymentResponse. Returns true on success, false on
-// invalid data specified. |method_data.supported_networks| is expected to only
-// contain basic-card card network names (the list is at
+// "basic-card" in the PaymentResponse. |method_data.supported_networks| is
+// expected to only contain basic-card card network names (the list is at
// https://www.w3.org/Payments/card-network-ids).
-bool ParseBasicCardSupportedNetworks(
+void ParseBasicCardSupportedNetworks(
const std::vector<PaymentMethodData>& method_data,
std::vector<std::string>* out_supported_networks,
std::set<std::string>* out_basic_card_supported_networks);
+// Returns the phone number from the given |profile| formatted for display.
+base::string16 GetFormattedPhoneNumberForDisplay(
+ const autofill::AutofillProfile& profile,
+ const std::string& locale);
+
// Formats the given number |phone_number| to
// i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL format
// by using i18n::phonenumbers::PhoneNumberUtil::Format.
@@ -67,6 +71,12 @@ std::string FormatPhoneForDisplay(const std::string& phone_number,
std::string FormatPhoneForResponse(const std::string& phone_number,
const std::string& country_code);
+// Returns a country code to be used when validating this profile. If the
+// profile has a valid country code set, it is returned. If not, a country code
+// associated with |app_locale| is used as a fallback.
+std::string GetCountryCodeWithFallback(const autofill::AutofillProfile* profile,
+ const std::string& app_locale);
+
} // namespace data_util
} // namespace payments
diff --git a/chromium/components/payments/core/payment_request_data_util_unittest.cc b/chromium/components/payments/core/payment_request_data_util_unittest.cc
index 5ad7e109637..3181a47d282 100644
--- a/chromium/components/payments/core/payment_request_data_util_unittest.cc
+++ b/chromium/components/payments/core/payment_request_data_util_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "base/json/json_writer.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "components/autofill/core/browser/autofill_profile.h"
@@ -49,8 +50,7 @@ TEST(PaymentRequestDataUtilTest, GetBasicCardResponseFromAutofillCreditCard) {
card.set_billing_address_id(address.guid());
std::unique_ptr<base::DictionaryValue> response_value =
payments::data_util::GetBasicCardResponseFromAutofillCreditCard(
- card, base::ASCIIToUTF16("123"),
- std::vector<autofill::AutofillProfile*>{&address}, "en-US")
+ card, base::ASCIIToUTF16("123"), address, "en-US")
.ToDictionaryValue();
std::string json_response;
base::JSONWriter::Write(*response_value, &json_response);
@@ -91,5 +91,171 @@ TEST(PaymentRequestDataUtilTest, FormatPhoneForDisplay) {
payments::data_util::FormatPhoneForDisplay("142685300", "FR"));
}
+// Test for the GetFormattedPhoneNumberForDisplay method.
+struct PhoneNumberFormatCase {
+ PhoneNumberFormatCase(const char* phone,
+ const char* country,
+ const char* expected_format,
+ const char* locale = "")
+ : phone(phone),
+ country(country),
+ expected_format(expected_format),
+ locale(locale) {}
+
+ const char* phone;
+ const char* country;
+ const char* expected_format;
+ const char* locale;
+};
+
+class GetFormattedPhoneNumberForDisplayTest
+ : public testing::TestWithParam<PhoneNumberFormatCase> {};
+
+TEST_P(GetFormattedPhoneNumberForDisplayTest,
+ GetFormattedPhoneNumberForDisplay) {
+ autofill::AutofillProfile profile;
+ profile.SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER,
+ base::UTF8ToUTF16(GetParam().phone));
+ profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY,
+ base::UTF8ToUTF16(GetParam().country));
+ EXPECT_EQ(GetParam().expected_format,
+ base::UTF16ToUTF8(
+ GetFormattedPhoneNumberForDisplay(profile, GetParam().locale)));
+}
+
+INSTANTIATE_TEST_CASE_P(
+ GetFormattedPhoneNumberForDisplay,
+ GetFormattedPhoneNumberForDisplayTest,
+ testing::Values(
+ //////////////////////////
+ // US phone in US.
+ //////////////////////////
+ // Formatted phone numbers.
+ PhoneNumberFormatCase("+1 415-555-5555", "US", "+1 415-555-5555"),
+ PhoneNumberFormatCase("1 415-555-5555", "US", "+1 415-555-5555"),
+ PhoneNumberFormatCase("415-555-5555", "US", "+1 415-555-5555"),
+ // Raw phone numbers.
+ PhoneNumberFormatCase("+14155555555", "US", "+1 415-555-5555"),
+ PhoneNumberFormatCase("14155555555", "US", "+1 415-555-5555"),
+ PhoneNumberFormatCase("4155555555", "US", "+1 415-555-5555"),
+
+ //////////////////////////
+ // US phone in CA.
+ //////////////////////////
+ // Formatted phone numbers.
+ PhoneNumberFormatCase("+1 415-555-5555", "CA", "+1 415-555-5555"),
+ PhoneNumberFormatCase("1 415-555-5555", "CA", "+1 415-555-5555"),
+ PhoneNumberFormatCase("415-555-5555", "CA", "+1 415-555-5555"),
+ // Raw phone numbers.
+ PhoneNumberFormatCase("+14155555555", "CA", "+1 415-555-5555"),
+ PhoneNumberFormatCase("14155555555", "CA", "+1 415-555-5555"),
+ PhoneNumberFormatCase("4155555555", "CA", "+1 415-555-5555"),
+
+ //////////////////////////
+ // US phone in AU.
+ //////////////////////////
+ // A US phone with the country code is correctly formatted as an US
+ // number.
+ PhoneNumberFormatCase("+1 415-555-5555", "AU", "+1 415-555-5555"),
+ PhoneNumberFormatCase("1 415-555-5555", "AU", "+1 415-555-5555"),
+ // Without a country code, the phone is formatted for the profile's
+ // country, even if it's invalid.
+ PhoneNumberFormatCase("415-555-5555", "AU", "+61 4155555555"),
+
+ //////////////////////////
+ // US phone in MX.
+ //////////////////////////
+ // A US phone with the country code is correctly formatted as an US
+ // number.
+ PhoneNumberFormatCase("+1 415-555-5555", "MX", "+1 415-555-5555"),
+ // "+52 1 415 555 5555" is a valid number for Mexico,
+ PhoneNumberFormatCase("1 415-555-5555", "MX", "+52 1 415 555 5555"),
+ // Without a country code, the phone is formatted for the profile's
+ // country.
+ PhoneNumberFormatCase("415-555-5555", "MX", "+52 415 555 5555"),
+
+ //////////////////////////
+ // AU phone in AU.
+ //////////////////////////
+ // Formatted phone numbers.
+ PhoneNumberFormatCase("+61 2 9374 4000", "AU", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("61 2 9374 4000", "AU", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("02 9374 4000", "AU", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("2 9374 4000", "AU", "+61 2 9374 4000"),
+ // Raw phone numbers.
+ PhoneNumberFormatCase("+61293744000", "AU", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("61293744000", "AU", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("0293744000", "AU", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("293744000", "AU", "+61 2 9374 4000"),
+
+ //////////////////////////
+ // AU phone in US.
+ //////////////////////////
+ // An AU phone with the country code is correctly formatted as an AU
+ // number.
+ PhoneNumberFormatCase("+61 2 9374 4000", "US", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("61 2 9374 4000", "US", "+61 2 9374 4000"),
+ // Without a country code, the phone is formatted for the profile's
+ // country.
+ // This local AU number fits the length of a US number, so it's
+ // formatted for US.
+ PhoneNumberFormatCase("02 9374 4000", "US", "+1 029-374-4000"),
+ // This local AU number is formatted as an US number, even if it's
+ // invlaid.
+ PhoneNumberFormatCase("2 9374 4000", "US", "+1 293744000"),
+
+ //////////////////////////
+ // MX phone in MX.
+ //////////////////////////
+ // Formatted phone numbers.
+ PhoneNumberFormatCase("+52 55 5342 8400", "MX", "+52 55 5342 8400"),
+ PhoneNumberFormatCase("52 55 5342 8400", "MX", "+52 55 5342 8400"),
+ PhoneNumberFormatCase("55 5342 8400", "MX", "+52 55 5342 8400"),
+ // Raw phone numbers.
+ PhoneNumberFormatCase("+525553428400", "MX", "+52 55 5342 8400"),
+ PhoneNumberFormatCase("525553428400", "MX", "+52 55 5342 8400"),
+ PhoneNumberFormatCase("5553428400", "MX", "+52 55 5342 8400"),
+
+ //////////////////////////
+ // MX phone in US.
+ //////////////////////////
+ // A MX phone with the country code is correctly formatted as a MX
+ // number.
+ PhoneNumberFormatCase("+52 55 5342 8400", "US", "+52 55 5342 8400"),
+ PhoneNumberFormatCase("52 55 5342 8400", "US", "+52 55 5342 8400"),
+ // This local MX number fits the length of a US number, so it's
+ // formatted for US.
+ PhoneNumberFormatCase("55 5342 8400", "US", "+1 555-342-8400")));
+
+INSTANTIATE_TEST_CASE_P(
+ GetFormattedPhoneNumberForDisplay_EdgeCases,
+ GetFormattedPhoneNumberForDisplayTest,
+ testing::Values(
+ //////////////////////////
+ // No country.
+ //////////////////////////
+ // Fallback to locale if no country is set.
+ PhoneNumberFormatCase("52 55 5342 8400",
+ "",
+ "+52 55 5342 8400",
+ "es_MX"),
+ PhoneNumberFormatCase("55 5342 8400", "", "+52 55 5342 8400", "es_MX"),
+ PhoneNumberFormatCase("55 5342 8400", "", "+1 555-342-8400", "en_US"),
+ PhoneNumberFormatCase("61 2 9374 4000", "", "+61 2 9374 4000", "en_AU"),
+ PhoneNumberFormatCase("02 9374 4000", "", "+61 2 9374 4000", "en_AU"),
+
+ //////////////////////////
+ // No country or locale.
+ //////////////////////////
+ // Format according to the country code.
+ PhoneNumberFormatCase("61 2 9374 4000", "", "+61 2 9374 4000"),
+ PhoneNumberFormatCase("52 55 5342 8400", "", "+52 55 5342 8400"),
+ PhoneNumberFormatCase("1 415 555 5555", "", "+1 415-555-5555"),
+ // If no country code is found, formats for US.
+ PhoneNumberFormatCase("02 9374 4000", "", "+1 029-374-4000"),
+ PhoneNumberFormatCase("2 9374 4000", "", "+1 293744000"),
+ PhoneNumberFormatCase("55 5342 8400", "", "+1 555-342-8400"),
+ PhoneNumberFormatCase("52 55 5342 8400", "", "+52 55 5342 8400"),
+ PhoneNumberFormatCase("415-555-5555", "", "+1 415-555-5555")));
} // namespace data_util
} // namespace payments
diff --git a/chromium/components/payments/core/payment_request_delegate.h b/chromium/components/payments/core/payment_request_delegate.h
index aab278af6f2..53a44c70626 100644
--- a/chromium/components/payments/core/payment_request_delegate.h
+++ b/chromium/components/payments/core/payment_request_delegate.h
@@ -10,23 +10,24 @@
#include "base/memory/weak_ptr.h"
#include "components/autofill/core/browser/payments/full_card_request.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
-#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
-namespace i18n {
-namespace addressinput {
-class Storage;
-class Source;
-} // namespace addressinput
-} // namespace i18n
+class GURL;
namespace autofill {
class CreditCard;
class PersonalDataManager;
+class RegionDataLoader;
} // namespace autofill
+class PrefService;
+
+namespace ukm {
+class UkmRecorder;
+} // namespace ukm
+
namespace payments {
+class AddressNormalizer;
class PaymentRequest;
class PaymentRequestDelegate {
@@ -53,17 +54,36 @@ class PaymentRequestDelegate {
// Returns whether the user is in Incognito mode.
virtual bool IsIncognito() const = 0;
+ // Returns true if the SSL certificate is valid. Should be called only for
+ // cryptographic schemes.
+ virtual bool IsSslCertificateValid() = 0;
+
+ // Returns the URL of the page that is currently being displayed.
+ virtual const GURL& GetLastCommittedURL() const = 0;
+
// Starts a FullCardRequest to unmask |credit_card|.
virtual void DoFullCardRequest(
const autofill::CreditCard& credit_card,
base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
result_delegate) = 0;
- // Returns the source and storage for country/region data loads.
- virtual std::unique_ptr<const ::i18n::addressinput::Source>
- GetAddressInputSource() = 0;
- virtual std::unique_ptr<::i18n::addressinput::Storage>
- GetAddressInputStorage() = 0;
+ // Returns a pointer to the address normalizer to use for the duration of this
+ // Payment Request.
+ virtual AddressNormalizer* GetAddressNormalizer() = 0;
+
+ // Creates a new region data loader that will self delete, or a test mock.
+ virtual autofill::RegionDataLoader* GetRegionDataLoader() = 0;
+
+ // Returns a pointer to the UKM service.
+ virtual ukm::UkmRecorder* GetUkmRecorder() = 0;
+
+ // Returns the user's signed-in email address, or empty string if not signed
+ // in.
+ virtual std::string GetAuthenticatedEmail() const = 0;
+
+ // Gets the pref service for the browser context associated with this
+ // PaymentRequest.
+ virtual PrefService* GetPrefService() = 0;
};
} // namespace payments
diff --git a/chromium/components/payments/core/payments_profile_comparator.cc b/chromium/components/payments/core/payments_profile_comparator.cc
new file mode 100644
index 00000000000..3190bacf2a9
--- /dev/null
+++ b/chromium/components/payments/core/payments_profile_comparator.cc
@@ -0,0 +1,286 @@
+// Copyright 2017 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/payments/core/payments_profile_comparator.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/address_i18n.h"
+#include "components/autofill/core/browser/autofill_country.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/validation.h"
+#include "components/payments/core/payment_options_provider.h"
+#include "components/payments/core/payment_request_data_util.h"
+#include "components/strings/grit/components_strings.h"
+#include "third_party/libaddressinput/chromium/addressinput_util.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace payments {
+
+PaymentsProfileComparator::PaymentsProfileComparator(
+ const std::string& app_locale,
+ const PaymentOptionsProvider& options)
+ : autofill::AutofillProfileComparator(app_locale), options_(options) {}
+
+PaymentsProfileComparator::~PaymentsProfileComparator() {}
+
+PaymentsProfileComparator::ProfileFields
+PaymentsProfileComparator::GetMissingProfileFields(
+ const autofill::AutofillProfile* profile) const {
+ if (!profile)
+ return kName | kPhone | kEmail | kAddress;
+
+ if (!cache_.count(profile->guid())) {
+ cache_[profile->guid()] = ComputeMissingFields(*profile);
+ } else {
+ // Cache hit. In debug mode, recompute and check that invalidation has
+ // occurred where necessary.
+ DCHECK_EQ(cache_[profile->guid()], ComputeMissingFields(*profile))
+ << "Profiles must be invalidated when their contents change.";
+ }
+
+ return cache_[profile->guid()];
+}
+
+std::vector<autofill::AutofillProfile*>
+PaymentsProfileComparator::FilterProfilesForContact(
+ const std::vector<autofill::AutofillProfile*>& profiles) const {
+ // We will be removing profiles, so we operate on a copy.
+ std::vector<autofill::AutofillProfile*> processed = profiles;
+
+ // Stable sort, since profiles are expected to be passed in frecency order.
+ std::stable_sort(
+ processed.begin(), processed.end(),
+ std::bind(&PaymentsProfileComparator::IsContactMoreComplete, this,
+ std::placeholders::_1, std::placeholders::_2));
+
+ auto it = processed.begin();
+ while (it != processed.end()) {
+ if (GetContactCompletenessScore(*it) == 0) {
+ // Since profiles are sorted by completeness, this and any further
+ // profiles can be discarded.
+ processed.erase(it, processed.end());
+ break;
+ }
+
+ // Attempt to find a matching element in the vector before the current.
+ // This is quadratic, but the number of elements is generally small
+ // (< 10), so a more complicated algorithm would be overkill.
+ if (std::find_if(processed.begin(), it,
+ [&](autofill::AutofillProfile* prior) {
+ return IsContactEqualOrSuperset(*prior, **it);
+ }) != it) {
+ // Remove the subset profile. |it| will point to the next element after
+ // erasure.
+ it = processed.erase(it);
+ } else {
+ it++;
+ }
+ }
+
+ return processed;
+}
+
+bool PaymentsProfileComparator::IsContactEqualOrSuperset(
+ const autofill::AutofillProfile& super,
+ const autofill::AutofillProfile& sub) const {
+ if (options_.request_payer_name()) {
+ if (sub.HasInfo(autofill::NAME_FULL) &&
+ !super.HasInfo(autofill::NAME_FULL)) {
+ return false;
+ }
+ if (!HaveMergeableNames(super, sub))
+ return false;
+ }
+ if (options_.request_payer_phone()) {
+ if (sub.HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER) &&
+ !super.HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) {
+ return false;
+ }
+ if (!HaveMergeablePhoneNumbers(super, sub))
+ return false;
+ }
+ if (options_.request_payer_email()) {
+ if (sub.HasInfo(autofill::EMAIL_ADDRESS) &&
+ !super.HasInfo(autofill::EMAIL_ADDRESS)) {
+ return false;
+ }
+ if (!HaveMergeableEmailAddresses(super, sub))
+ return false;
+ }
+ return true;
+}
+
+int PaymentsProfileComparator::GetContactCompletenessScore(
+ const autofill::AutofillProfile* profile) const {
+ // Create a bitmask of the fields that are both present and required.
+ ProfileFields present =
+ ~GetMissingProfileFields(profile) & GetRequiredProfileFieldsForContact();
+
+ // Count how many are set.
+ return !!(present & kName) + !!(present & kPhone) + !!(present & kEmail);
+}
+
+bool PaymentsProfileComparator::IsContactInfoComplete(
+ const autofill::AutofillProfile* profile) const {
+ // Mask the fields that are missing with those that are requried. If any bits
+ // are set (i.e., the result is nonzero), then contact info is incomplete.
+ return !(GetMissingProfileFields(profile) &
+ GetRequiredProfileFieldsForContact());
+}
+
+base::string16 PaymentsProfileComparator::GetStringForMissingContactFields(
+ const autofill::AutofillProfile& profile) const {
+ return GetStringForMissingFields(GetMissingProfileFields(&profile) &
+ GetRequiredProfileFieldsForContact());
+}
+
+std::vector<autofill::AutofillProfile*>
+PaymentsProfileComparator::FilterProfilesForShipping(
+ const std::vector<autofill::AutofillProfile*>& profiles) const {
+ // Since we'll be changing the order/contents of the const input vector,
+ // we make a copy.
+ std::vector<autofill::AutofillProfile*> processed = profiles;
+
+ std::stable_sort(
+ processed.begin(), processed.end(),
+ std::bind(&PaymentsProfileComparator::IsShippingMoreComplete, this,
+ std::placeholders::_1, std::placeholders::_2));
+
+ // TODO(crbug.com/722949): Remove profiles with no relevant information, or
+ // which are subsets of more-complete profiles.
+
+ return processed;
+}
+
+int PaymentsProfileComparator::GetShippingCompletenessScore(
+ const autofill::AutofillProfile* profile) const {
+ // Create a bitmask of the fields that are both present and required.
+ ProfileFields present =
+ ~GetMissingProfileFields(profile) & GetRequiredProfileFieldsForShipping();
+
+ // Count how many are set. The completeness of the address is weighted so as
+ // to dominate the other fields.
+ return !!(present & kName) + !!(present & kPhone) +
+ (10 * !!(present & kAddress));
+}
+
+bool PaymentsProfileComparator::IsShippingComplete(
+ const autofill::AutofillProfile* profile) const {
+ // Mask the fields that are missing with those that are requried. If any bits
+ // are set (i.e., the result is nonzero), then shipping is incomplete.
+ return !(GetMissingProfileFields(profile) &
+ GetRequiredProfileFieldsForShipping());
+}
+
+base::string16 PaymentsProfileComparator::GetStringForMissingShippingFields(
+ const autofill::AutofillProfile& profile) const {
+ return GetStringForMissingFields(GetMissingProfileFields(&profile) &
+ GetRequiredProfileFieldsForShipping());
+}
+
+void PaymentsProfileComparator::Invalidate(
+ const autofill::AutofillProfile& profile) {
+ cache_.erase(profile.guid());
+}
+
+PaymentsProfileComparator::ProfileFields
+PaymentsProfileComparator::ComputeMissingFields(
+ const autofill::AutofillProfile& profile) const {
+ ProfileFields missing = 0;
+
+ if (!profile.HasInfo(autofill::NAME_FULL))
+ missing |= kName;
+
+ // Determine the country code to use when validating the phone number. Use
+ // the profile's country if it has one, or the code for the app locale
+ // otherwise. Note that international format numbers will always work--this
+ // is just the region that will be used to check if the number is
+ // potentially in a local format.
+ std::string country =
+ data_util::GetCountryCodeWithFallback(&profile, app_locale());
+
+ base::string16 phone = profile.GetInfo(
+ autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), app_locale());
+ base::string16 intl_phone = base::UTF8ToUTF16("+" + base::UTF16ToUTF8(phone));
+ if (!(autofill::IsValidPhoneNumber(phone, country) ||
+ autofill::IsValidPhoneNumber(intl_phone, country)))
+ missing |= kPhone;
+
+ base::string16 email = profile.GetInfo(
+ autofill::AutofillType(autofill::EMAIL_ADDRESS), app_locale());
+ if (!autofill::IsValidEmailAddress(email))
+ missing |= kEmail;
+
+ if (!AreRequiredAddressFieldsPresent(profile))
+ missing |= kAddress;
+
+ return missing;
+}
+
+PaymentsProfileComparator::ProfileFields
+PaymentsProfileComparator::GetRequiredProfileFieldsForContact() const {
+ ProfileFields required = 0;
+ if (options_.request_payer_name())
+ required |= kName;
+ if (options_.request_payer_phone())
+ required |= kPhone;
+ if (options_.request_payer_email())
+ required |= kEmail;
+ return required;
+}
+
+PaymentsProfileComparator::ProfileFields
+PaymentsProfileComparator::GetRequiredProfileFieldsForShipping() const {
+ return options_.request_shipping() ? (kAddress | kName | kPhone) : 0;
+}
+
+base::string16 PaymentsProfileComparator::GetStringForMissingFields(
+ PaymentsProfileComparator::ProfileFields fields) const {
+ switch (fields) {
+ case 0:
+ // No bits are set, so no fields are missing.
+ return base::string16();
+ case kName:
+ return l10n_util::GetStringUTF16(IDS_PAYMENTS_NAME_REQUIRED);
+ case kPhone:
+ return l10n_util::GetStringUTF16(IDS_PAYMENTS_PHONE_NUMBER_REQUIRED);
+ case kEmail:
+ return l10n_util::GetStringUTF16(IDS_PAYMENTS_EMAIL_REQUIRED);
+ case kAddress:
+ return l10n_util::GetStringUTF16(IDS_PAYMENTS_INVALID_ADDRESS);
+ default:
+ // Either multiple bits are set (likely) or one bit that doesn't
+ // correspond to a named constant is set (shouldn't happen). Return a
+ // generic "More information" message.
+ return l10n_util::GetStringUTF16(IDS_PAYMENTS_MORE_INFORMATION_REQUIRED);
+ }
+}
+
+bool PaymentsProfileComparator::AreRequiredAddressFieldsPresent(
+ const autofill::AutofillProfile& profile) const {
+ std::unique_ptr<::i18n::addressinput::AddressData> data =
+ autofill::i18n::CreateAddressDataFromAutofillProfile(profile,
+ app_locale());
+
+ return autofill::addressinput::HasAllRequiredFields(*data);
+}
+
+bool PaymentsProfileComparator::IsContactMoreComplete(
+ const autofill::AutofillProfile* p1,
+ const autofill::AutofillProfile* p2) const {
+ return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2);
+}
+
+bool PaymentsProfileComparator::IsShippingMoreComplete(
+ const autofill::AutofillProfile* p1,
+ const autofill::AutofillProfile* p2) const {
+ return GetShippingCompletenessScore(p1) > GetShippingCompletenessScore(p2);
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/payments_profile_comparator.h b/chromium/components/payments/core/payments_profile_comparator.h
new file mode 100644
index 00000000000..e186e05efad
--- /dev/null
+++ b/chromium/components/payments/core/payments_profile_comparator.h
@@ -0,0 +1,124 @@
+// Copyright 2017 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_PAYMENTS_CORE_PAYMENTS_PROFILE_COMPARATOR_H_
+#define COMPONENTS_PAYMENTS_CORE_PAYMENTS_PROFILE_COMPARATOR_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "components/autofill/core/browser/autofill_profile_comparator.h"
+
+// Utility functions used for processing and filtering address profiles
+// (AutofillProfile).
+
+namespace autofill {
+class AutofillProfile;
+} // namespace autofill
+
+namespace payments {
+
+class PaymentOptionsProvider;
+
+// Helper class which evaluates profiles for similarity and completeness.
+// Profiles are evaluated once for completeness, and the result is cached,
+// meaning one instance of this class should be used per-request to avoid
+// redoing expensive validation checks.
+// Note that, if a profile is modified and saved during the course of the
+// PaymentRequest, it is important to call the Invalidate method to ensure
+// it is properly evaluated.
+class PaymentsProfileComparator : public autofill::AutofillProfileComparator {
+ public:
+ // Bitmask of potentially-required fields used in evaluating completeness.
+ using ProfileFields = uint32_t;
+ const static ProfileFields kName = 1 << 0;
+ const static ProfileFields kPhone = 1 << 1;
+ const static ProfileFields kEmail = 1 << 2;
+ const static ProfileFields kAddress = 1 << 3;
+
+ PaymentsProfileComparator(const std::string& app_locale,
+ const PaymentOptionsProvider& options);
+ ~PaymentsProfileComparator();
+
+ // Returns a bitmask indicating which fields (or groups of fields) on this
+ // profile are not complete and valid.
+ ProfileFields GetMissingProfileFields(
+ const autofill::AutofillProfile* profile) const;
+
+ // Returns profiles for contact info, ordered by completeness and
+ // deduplicated. |profiles| should be passed in order of frecency, and this
+ // order will be preserved among equally-complete profiles. Deduplication here
+ // means that profiles returned are excluded if they are a subset of a more
+ // complete or more frecent profile. Completeness here refers only to the
+ // presence of the fields requested per the request_payer_* fields in
+ // |options|.
+ std::vector<autofill::AutofillProfile*> FilterProfilesForContact(
+ const std::vector<autofill::AutofillProfile*>& profiles) const;
+
+ // Returns true iff all of the contact info in |sub| also appears in |super|.
+ // Only operates on fields requested in |options|.
+ bool IsContactEqualOrSuperset(const autofill::AutofillProfile& super,
+ const autofill::AutofillProfile& sub) const;
+
+ // Returns the number of contact fields requested in |options| which are
+ // nonempty in |profile|.
+ int GetContactCompletenessScore(
+ const autofill::AutofillProfile* profile) const;
+
+ // Returns true iff every contact field requested in |options| is nonempty in
+ // |profile|.
+ bool IsContactInfoComplete(const autofill::AutofillProfile* profile) const;
+
+ // Returns profiles for shipping, ordered by completeness. |profiles| should
+ // be passed in order of frecency, and this order will be preserved among
+ // equally-complete profiles.
+ std::vector<autofill::AutofillProfile*> FilterProfilesForShipping(
+ const std::vector<autofill::AutofillProfile*>& profiles) const;
+
+ int GetShippingCompletenessScore(
+ const autofill::AutofillProfile* profile) const;
+
+ // Returns true iff every field needed to use |profile| as a shipping address
+ // is populated.
+ bool IsShippingComplete(const autofill::AutofillProfile* profile) const;
+
+ // Returns a localized string to be displayed in UI indicating what action,
+ // if any, must be taken for the given profile to be used as contact info.
+ base::string16 GetStringForMissingContactFields(
+ const autofill::AutofillProfile& profile) const;
+
+ // Returns a localized string to be displayed in UI indicating what action,
+ // if any, must be taken for the given profile to be used as a shipping
+ // address.
+ base::string16 GetStringForMissingShippingFields(
+ const autofill::AutofillProfile& profile) const;
+
+ // Clears the cached evaluation result for |profile|. Must be called when a
+ // profile is modified and saved during the course of a PaymentRequest.
+ void Invalidate(const autofill::AutofillProfile& profile);
+
+ private:
+ ProfileFields ComputeMissingFields(
+ const autofill::AutofillProfile& profile) const;
+ ProfileFields GetRequiredProfileFieldsForContact() const;
+ ProfileFields GetRequiredProfileFieldsForShipping() const;
+ base::string16 GetStringForMissingFields(ProfileFields fields) const;
+ bool AreRequiredAddressFieldsPresent(
+ const autofill::AutofillProfile& profile) const;
+
+ // Comparison functions suitable for sorting profiles by completeness
+ // score with std::sort.
+ bool IsContactMoreComplete(const autofill::AutofillProfile* p1,
+ const autofill::AutofillProfile* p2) const;
+ bool IsShippingMoreComplete(const autofill::AutofillProfile* p1,
+ const autofill::AutofillProfile* p2) const;
+
+ mutable std::map<std::string, ProfileFields> cache_;
+ const PaymentOptionsProvider& options_;
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_PAYMENTS_PROFILE_COMPARATOR_H_ \ No newline at end of file
diff --git a/chromium/components/payments/core/payments_profile_comparator_unittest.cc b/chromium/components/payments/core/payments_profile_comparator_unittest.cc
new file mode 100644
index 00000000000..18f3e58ae15
--- /dev/null
+++ b/chromium/components/payments/core/payments_profile_comparator_unittest.cc
@@ -0,0 +1,464 @@
+// Copyright 2017 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/payments/core/payments_profile_comparator.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/guid.h"
+#include "base/memory/ptr_util.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/payments/core/payment_options_provider.h"
+#include "components/strings/grit/components_strings.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
+
+using autofill::AutofillProfile;
+
+namespace payments {
+
+constexpr uint32_t kRequestPayerName = 1 << 0;
+constexpr uint32_t kRequestPayerEmail = 1 << 1;
+constexpr uint32_t kRequestPayerPhone = 1 << 2;
+constexpr uint32_t kRequestShipping = 1 << 3;
+
+class MockPaymentOptionsProvider : public PaymentOptionsProvider {
+ public:
+ MockPaymentOptionsProvider(uint32_t options) : options_(options) {}
+
+ ~MockPaymentOptionsProvider() override {}
+ bool request_payer_name() const override {
+ return options_ & kRequestPayerName;
+ }
+ bool request_payer_email() const override {
+ return options_ & kRequestPayerEmail;
+ }
+ bool request_payer_phone() const override {
+ return options_ & kRequestPayerPhone;
+ }
+ bool request_shipping() const override { return options_ & kRequestShipping; }
+ PaymentShippingType shipping_type() const override {
+ return PaymentShippingType::SHIPPING;
+ }
+
+ private:
+ uint32_t options_;
+};
+
+AutofillProfile CreateProfileWithContactInfo(const char* name,
+ const char* email,
+ const char* phone) {
+ AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
+ autofill::test::SetProfileInfo(&profile, name, "", "", email, "", "", "", "",
+ "", "", "", phone);
+ return profile;
+}
+
+AutofillProfile CreateProfileWithCompleteAddress(const char* name,
+ const char* phone) {
+ AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
+ autofill::test::SetProfileInfo(&profile, name, "", "", "", "", "123 Fake St.",
+ "", "Fakesville", "MN", "54000", "US", phone);
+ return profile;
+}
+
+AutofillProfile CreateProfileWithPartialAddress(const char* name,
+ const char* phone) {
+ AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
+ autofill::test::SetProfileInfo(&profile, name, "", "", "", "", "123 Fake St.",
+ "", "", "", "54000", "", phone);
+ return profile;
+}
+
+TEST(PaymentRequestProfileUtilTest, FilterProfilesForContact) {
+ // These profiles are subset/equal, so only the first complete one is
+ // included.
+ AutofillProfile exclude_1 =
+ CreateProfileWithContactInfo("Homer", "", "6515553226");
+
+ AutofillProfile exclude_2 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
+
+ AutofillProfile include_1 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+
+ AutofillProfile exclude_3 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+
+ // This profile is different, so it should also be included. Since it is
+ // less complete than |include_1|, it will appear after.
+ AutofillProfile include_2 =
+ CreateProfileWithContactInfo("Marge", "marge@simpson.net", "");
+
+ // This profile is different, so it should also be included. Since it is
+ // equally complete with |include_1|, it will appear before |include_2|, but
+ // after |include_1| since order is preserved amongst profiles of equal
+ // completeness.
+ AutofillProfile include_3 = CreateProfileWithContactInfo(
+ "Bart", "eatmyshorts@simpson.net", "6515553226");
+
+ std::vector<AutofillProfile*> profiles = {&exclude_1, &exclude_2, &include_1,
+ &exclude_3, &include_2, &include_3};
+
+ MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail |
+ kRequestPayerPhone);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ std::vector<AutofillProfile*> filtered =
+ comp.FilterProfilesForContact(profiles);
+
+ ASSERT_EQ(3u, filtered.size());
+ EXPECT_EQ(&include_1, filtered[0]);
+ EXPECT_EQ(&include_3, filtered[1]);
+ EXPECT_EQ(&include_2, filtered[2]);
+
+ // Repeat the filter using a provider set to only request phone numbers.
+ // Under these rules, since all profiles have the same (or no) phone number,
+ // we should only see the first profile with a phone number, |exclude_1|.
+ MockPaymentOptionsProvider phone_only_provider(kRequestPayerPhone);
+ PaymentsProfileComparator phone_only_comp("en-US", phone_only_provider);
+ std::vector<AutofillProfile*> filtered_phones =
+ phone_only_comp.FilterProfilesForContact(profiles);
+ ASSERT_EQ(1u, filtered_phones.size());
+ EXPECT_EQ(&exclude_1, filtered_phones[0]);
+}
+
+TEST(PaymentRequestProfileUtilTest, IsContactEqualOrSuperset) {
+ MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail |
+ kRequestPayerPhone);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ AutofillProfile p1 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+
+ // Candidate subset profile is equal.
+ AutofillProfile p2 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p2));
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p2, p1));
+
+ // Candidate subset profile has non-matching fields.
+ AutofillProfile p3 = CreateProfileWithContactInfo(
+ "Homer", "homer@springfieldnuclear.gov", "6515553226");
+ EXPECT_FALSE(comp.IsContactEqualOrSuperset(p1, p3));
+ EXPECT_FALSE(comp.IsContactEqualOrSuperset(p3, p1));
+
+ // Candidate subset profile is equal, except for missing fields.
+ AutofillProfile p4 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p4));
+ EXPECT_FALSE(comp.IsContactEqualOrSuperset(p4, p1));
+
+ // One field is common, but each has a field which the other is missing.
+ AutofillProfile p5 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
+ AutofillProfile p6 = CreateProfileWithContactInfo("Homer", "", "6515553226");
+ EXPECT_FALSE(comp.IsContactEqualOrSuperset(p5, p6));
+ EXPECT_FALSE(comp.IsContactEqualOrSuperset(p6, p5));
+}
+
+TEST(PaymentRequestProfileUtilTest, IsContactEqualOrSuperset_WithFieldIgnored) {
+ // Discrepancies in email should be ignored throughout this test.
+ MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ AutofillProfile p1 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+
+ // Candidate subset profile is equal.
+ AutofillProfile p2 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p2));
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p2, p1));
+
+ // Email fields don't match, but profiles are still equal.
+ AutofillProfile p3 = CreateProfileWithContactInfo(
+ "Homer", "homer@springfieldnuclear.gov", "6515553226");
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p3));
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p3, p1));
+
+ // Profile without an email is mutual subset of profile with an email.
+ AutofillProfile p4 = CreateProfileWithContactInfo("Homer", "", "6515553226");
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p4));
+ EXPECT_TRUE(comp.IsContactEqualOrSuperset(p4, p1));
+}
+
+TEST(PaymentRequestProfileUtilTest, GetContactCompletenessScore) {
+ MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ // Two completeness points: One each for name and phone number, but not email
+ // as it was not requested.
+ AutofillProfile p1 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+ EXPECT_EQ(2, comp.GetContactCompletenessScore(&p1));
+
+ // One completeness point for name, no points for phone number (missing) or
+ // email (not requested).
+ AutofillProfile p2 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
+ EXPECT_EQ(1, comp.GetContactCompletenessScore(&p2));
+
+ // No completeness points, as the only field present was not requested.
+ AutofillProfile p3 =
+ CreateProfileWithContactInfo("", "homer@simpson.net", "");
+ EXPECT_EQ(0, comp.GetContactCompletenessScore(&p3));
+
+ // Null profile returns 0.
+ EXPECT_EQ(0, comp.GetContactCompletenessScore(nullptr));
+}
+
+TEST(PaymentRequestProfileUtilTest, IsContactInfoComplete) {
+ MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ // If name and email are present, return true regardless of the (ignored)
+ // phone value.
+ AutofillProfile p1 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+ AutofillProfile p2 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
+
+ EXPECT_TRUE(comp.IsContactInfoComplete(&p1));
+ EXPECT_TRUE(comp.IsContactInfoComplete(&p2));
+
+ // If name is not present, return false regardless of the (ignored)
+ // phone value.
+ AutofillProfile p3 =
+ CreateProfileWithContactInfo("", "homer@simpson.net", "6515553226");
+ AutofillProfile p4 =
+ CreateProfileWithContactInfo("", "homer@simpson.net", "");
+
+ EXPECT_FALSE(comp.IsContactInfoComplete(&p3));
+ EXPECT_FALSE(comp.IsContactInfoComplete(&p4));
+
+ // If no fields are requested, any profile (even empty or null) is complete.
+ MockPaymentOptionsProvider empty_provider(0);
+ PaymentsProfileComparator empty_comp("en-US", empty_provider);
+
+ AutofillProfile p5 = CreateProfileWithContactInfo("", "", "");
+
+ EXPECT_TRUE(empty_comp.IsContactInfoComplete(&p1));
+ EXPECT_TRUE(empty_comp.IsContactInfoComplete(&p5));
+ EXPECT_TRUE(empty_comp.IsContactInfoComplete(nullptr));
+}
+
+TEST(PaymentRequestProfileUtilTest, FilterProfilesForShipping) {
+ MockPaymentOptionsProvider provider(kRequestShipping);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ AutofillProfile address_only = CreateProfileWithCompleteAddress("", "");
+
+ AutofillProfile no_name = CreateProfileWithCompleteAddress("", "6515553226");
+ AutofillProfile no_phone = CreateProfileWithCompleteAddress("Homer", "");
+
+ AutofillProfile empty = CreateProfileWithContactInfo("", "", "");
+
+ AutofillProfile complete1 =
+ CreateProfileWithCompleteAddress("Homer", "6515553226");
+
+ AutofillProfile partial_address =
+ CreateProfileWithPartialAddress("Homer", "6515553226");
+ AutofillProfile no_address =
+ CreateProfileWithContactInfo("Homer", "", "6515553226");
+
+ AutofillProfile complete2 =
+ CreateProfileWithCompleteAddress("Bart", "6515553226");
+
+ AutofillProfile partial_no_phone =
+ CreateProfileWithPartialAddress("", "6515553226");
+ AutofillProfile partial_no_name =
+ CreateProfileWithPartialAddress("Homer", "");
+
+ std::vector<AutofillProfile*> profiles = {
+ &address_only, &no_name, &no_phone, &empty,
+ &complete1, &partial_address, &no_address, &complete2,
+ &partial_no_phone, &partial_no_name};
+
+ std::vector<AutofillProfile*> filtered =
+ comp.FilterProfilesForShipping(profiles);
+
+ // Current logic does not remove profiles, only reorder them.
+ ASSERT_EQ(10u, filtered.size());
+
+ // First, the complete profiles should be hoisted to the top, keeping their
+ // relative order.
+ EXPECT_EQ(&complete1, filtered[0]);
+ EXPECT_EQ(&complete2, filtered[1]);
+
+ // Next are profiles with a complete address but missing one other field.
+ EXPECT_EQ(&no_name, filtered[2]);
+ EXPECT_EQ(&no_phone, filtered[3]);
+
+ // A profile with only a complete address should still appear before profiles
+ // with partial/empty addresses.
+ EXPECT_EQ(&address_only, filtered[4]);
+
+ // Profiles with partial/no address then are sorted by whether or not they
+ // have names and/or phone numbers.
+ EXPECT_EQ(&partial_address, filtered[5]);
+ EXPECT_EQ(&no_address, filtered[6]);
+
+ EXPECT_EQ(&partial_no_phone, filtered[7]);
+ EXPECT_EQ(&partial_no_name, filtered[8]);
+
+ EXPECT_EQ(&empty, filtered[9]);
+}
+
+TEST(PaymentRequestProfileUtilTest, GetShippingCompletenessScore) {
+ MockPaymentOptionsProvider provider(kRequestShipping);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ // 12 points for a complete profile: 10 for address, 1 each for name/phone.
+ AutofillProfile p1 = CreateProfileWithCompleteAddress("Homer", "6515553226");
+ EXPECT_EQ(12, comp.GetShippingCompletenessScore(&p1));
+
+ // 11 points if name or phone is missing.
+ AutofillProfile p2 = CreateProfileWithCompleteAddress("", "6515553226");
+ AutofillProfile p3 = CreateProfileWithCompleteAddress("Homer", "");
+ EXPECT_EQ(11, comp.GetShippingCompletenessScore(&p2));
+ EXPECT_EQ(11, comp.GetShippingCompletenessScore(&p3));
+
+ // 10 points for complete address only.
+ AutofillProfile p4 = CreateProfileWithCompleteAddress("", "");
+ EXPECT_EQ(10, comp.GetShippingCompletenessScore(&p4));
+
+ // 2 points for name and phone without address.
+ AutofillProfile p5 = CreateProfileWithContactInfo("Homer", "", "6515553226");
+ EXPECT_EQ(2, comp.GetShippingCompletenessScore(&p5));
+
+ // 1 point for name or phone alone.
+ AutofillProfile p6 = CreateProfileWithContactInfo("Homer", "", "");
+ AutofillProfile p7 = CreateProfileWithContactInfo("", "", "6515553226");
+ EXPECT_EQ(1, comp.GetShippingCompletenessScore(&p6));
+ EXPECT_EQ(1, comp.GetShippingCompletenessScore(&p7));
+
+ // No points for empty profile, or profile with only a partial address.
+ AutofillProfile p8 = CreateProfileWithContactInfo("", "", "");
+ AutofillProfile p9 = CreateProfileWithPartialAddress("", "");
+ EXPECT_EQ(0, comp.GetShippingCompletenessScore(&p8));
+ EXPECT_EQ(0, comp.GetShippingCompletenessScore(&p9));
+}
+
+TEST(PaymentRequestProfileUtilTest, IsShippingComplete) {
+ MockPaymentOptionsProvider provider(kRequestShipping);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ // True if name, phone, and address are all populated.
+ AutofillProfile p1 = CreateProfileWithCompleteAddress("Homer", "6515553226");
+ EXPECT_TRUE(comp.IsShippingComplete(&p1));
+
+ // False if address is partially populated.
+ AutofillProfile p2 = CreateProfileWithPartialAddress("Homer", "6515553226");
+ EXPECT_FALSE(comp.IsShippingComplete(&p2));
+
+ // False if name isn't populated.
+ AutofillProfile p3 = CreateProfileWithCompleteAddress("", "6515553226");
+ EXPECT_FALSE(comp.IsShippingComplete(&p3));
+
+ // False if phone isn't populated.
+ AutofillProfile p4 = CreateProfileWithCompleteAddress("Homer", "");
+ EXPECT_FALSE(comp.IsShippingComplete(&p4));
+
+ // False if only contact info (no address fields) is populated.
+ AutofillProfile p5 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+ EXPECT_FALSE(comp.IsShippingComplete(&p5));
+
+ MockPaymentOptionsProvider provider_no_shipping(0);
+ PaymentsProfileComparator comp_no_shipping("en-US", provider_no_shipping);
+ // nullptr is handled correctly: false if shipping requested, true if not.
+ EXPECT_FALSE(comp.IsShippingComplete(nullptr));
+ EXPECT_TRUE(comp_no_shipping.IsShippingComplete(nullptr));
+}
+
+TEST(PaymentRequestProfileUtilTest, GetStringForMissingContactFields) {
+ MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone |
+ kRequestPayerEmail | kRequestShipping);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ // No error message for complete profile.
+ AutofillProfile p1 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+ EXPECT_TRUE(comp.GetStringForMissingContactFields(p1).empty());
+
+ MockPaymentOptionsProvider provider_no_email(
+ kRequestPayerName | kRequestPayerPhone | kRequestShipping);
+ PaymentsProfileComparator comp_no_email("en-US", provider_no_email);
+
+ // No error message if missing field wasn't required.
+ AutofillProfile p2 = CreateProfileWithContactInfo("Homer", "", "6515553226");
+ EXPECT_TRUE(comp_no_email.GetStringForMissingContactFields(p2).empty());
+
+ // Error message for email address if email address is missing and required.
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_EMAIL_REQUIRED),
+ comp.GetStringForMissingContactFields(p2));
+
+ // Error message for phone number if phone is missing and required.
+ AutofillProfile p3 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_PHONE_NUMBER_REQUIRED),
+ comp.GetStringForMissingContactFields(p3));
+
+ // Error message for name if name is missing and required.
+ AutofillProfile p4 =
+ CreateProfileWithContactInfo("", "homer@simpson.net", "6515553226");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_NAME_REQUIRED),
+ comp.GetStringForMissingContactFields(p4));
+
+ // Generic error message if multiple fields missing.
+ AutofillProfile p5 =
+ CreateProfileWithContactInfo("", "homer@simpson.net", "");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_MORE_INFORMATION_REQUIRED),
+ comp.GetStringForMissingContactFields(p5));
+}
+
+TEST(PaymentRequestProfileUtilTest, GetStringForMissingShippingFields) {
+ MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone |
+ kRequestPayerEmail | kRequestShipping);
+ PaymentsProfileComparator comp("en-US", provider);
+
+ // No error message for complete profile.
+ AutofillProfile p1 = CreateProfileWithCompleteAddress("Homer", "6515553226");
+ EXPECT_TRUE(comp.GetStringForMissingShippingFields(p1).empty());
+
+ // Error message for shipping if shipping requested and not present.
+ AutofillProfile p2 =
+ CreateProfileWithContactInfo("Homer", "homer@simpson.net", "6515553226");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_INVALID_ADDRESS),
+ comp.GetStringForMissingShippingFields(p2));
+
+ // Error message for shipping if shipping requested and only partially
+ // complete.
+ AutofillProfile p3 = CreateProfileWithPartialAddress("Homer", "6515553226");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_INVALID_ADDRESS),
+ comp.GetStringForMissingShippingFields(p3));
+
+ // Error message for name if name requested and missing.
+ AutofillProfile p4 = CreateProfileWithCompleteAddress("", "6515553226");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_NAME_REQUIRED),
+ comp.GetStringForMissingShippingFields(p4));
+
+ // Error message for phone if phone requested and missing.
+ AutofillProfile p5 = CreateProfileWithCompleteAddress("Homer", "");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_PHONE_NUMBER_REQUIRED),
+ comp.GetStringForMissingShippingFields(p5));
+
+ // Generic error message if multiple fields missing.
+ AutofillProfile p6 = CreateProfileWithContactInfo("", "", "");
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAYMENTS_MORE_INFORMATION_REQUIRED),
+ comp.GetStringForMissingShippingFields(p6));
+
+ MockPaymentOptionsProvider provider_no_shipping(
+ kRequestPayerName | kRequestPayerPhone | kRequestPayerEmail);
+ PaymentsProfileComparator comp_no_shipping("en-US", provider_no_shipping);
+
+ // No error message if everything is missing but shipping wasn't requested.
+ EXPECT_TRUE(comp_no_shipping.GetStringForMissingShippingFields(p6).empty());
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/profile_util.cc b/chromium/components/payments/core/profile_util.cc
deleted file mode 100644
index c1149c85ed8..00000000000
--- a/chromium/components/payments/core/profile_util.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 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/payments/core/profile_util.h"
-
-#include <algorithm>
-
-#include "components/autofill/core/browser/autofill_profile.h"
-#include "components/autofill/core/browser/field_types.h"
-#include "components/payments/core/payment_options_provider.h"
-
-namespace payments {
-namespace profile_util {
-
-std::vector<autofill::AutofillProfile*> FilterProfilesForContact(
- const std::vector<autofill::AutofillProfile*>& profiles,
- const std::string& app_locale,
- const PaymentOptionsProvider& options) {
- // We will be removing profiles, so we operate on a copy.
- std::vector<autofill::AutofillProfile*> processed = profiles;
-
- PaymentsProfileComparator comparator(app_locale, options);
-
- // Stable sort, since profiles are expected to be passed in frecency order.
- std::stable_sort(
- processed.begin(), processed.end(),
- std::bind(&PaymentsProfileComparator::IsContactMoreComplete, &comparator,
- std::placeholders::_1, std::placeholders::_2));
-
- auto it = processed.begin();
- while (it != processed.end()) {
- if (comparator.GetContactCompletenessScore(*it) == 0) {
- // Since profiles are sorted by completeness, this and any further
- // profiles can be discarded.
- processed.erase(it, processed.end());
- break;
- }
-
- // Attempt to find a matching element in the vector before the current.
- // This is quadratic, but the number of elements is generally small
- // (< 10), so a more complicated algorithm would be overkill.
- if (std::find_if(processed.begin(), it,
- [&](autofill::AutofillProfile* prior) {
- return comparator.IsContactEqualOrSuperset(*prior, **it);
- }) != it) {
- // Remove the subset profile. |it| will point to the next element after
- // erasure.
- it = processed.erase(it);
- } else {
- it++;
- }
- }
-
- return processed;
-}
-
-PaymentsProfileComparator::PaymentsProfileComparator(
- const std::string& app_locale,
- const PaymentOptionsProvider& options)
- : autofill::AutofillProfileComparator(app_locale), options_(options) {}
-
-PaymentsProfileComparator::~PaymentsProfileComparator() {}
-
-bool PaymentsProfileComparator::IsContactEqualOrSuperset(
- const autofill::AutofillProfile& super,
- const autofill::AutofillProfile& sub) {
- if (options_.request_payer_name()) {
- if (sub.HasInfo(autofill::NAME_FULL) &&
- !super.HasInfo(autofill::NAME_FULL)) {
- return false;
- }
- if (!HaveMergeableNames(super, sub))
- return false;
- }
- if (options_.request_payer_phone()) {
- if (sub.HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER) &&
- !super.HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) {
- return false;
- }
- if (!HaveMergeablePhoneNumbers(super, sub))
- return false;
- }
- if (options_.request_payer_email()) {
- if (sub.HasInfo(autofill::EMAIL_ADDRESS) &&
- !super.HasInfo(autofill::EMAIL_ADDRESS)) {
- return false;
- }
- if (!HaveMergeableEmailAddresses(super, sub))
- return false;
- }
- return true;
-}
-
-int PaymentsProfileComparator::GetContactCompletenessScore(
- const autofill::AutofillProfile* profile) {
- if (!profile)
- return 0;
-
- return (options_.request_payer_name() &&
- profile->HasInfo(autofill::NAME_FULL)) +
- (options_.request_payer_phone() &&
- profile->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) +
- (options_.request_payer_email() &&
- profile->HasInfo(autofill::EMAIL_ADDRESS));
-}
-
-bool PaymentsProfileComparator::IsContactInfoComplete(
- const autofill::AutofillProfile* profile) {
- int desired_score = options_.request_payer_name() +
- options_.request_payer_phone() +
- options_.request_payer_email();
- return GetContactCompletenessScore(profile) == desired_score;
-}
-
-bool PaymentsProfileComparator::IsContactMoreComplete(
- const autofill::AutofillProfile* p1,
- const autofill::AutofillProfile* p2) {
- return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2);
-}
-
-} // namespace profile_util
-} // namespace payments
diff --git a/chromium/components/payments/core/profile_util.h b/chromium/components/payments/core/profile_util.h
deleted file mode 100644
index 6693fe854c8..00000000000
--- a/chromium/components/payments/core/profile_util.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2017 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_PAYMENTS_CONTENT_PROFILE_UTIL_H_
-#define COMPONENTS_PAYMENTS_CONTENT_PROFILE_UTIL_H_
-
-#include <string>
-#include <vector>
-
-#include "components/autofill/core/browser/autofill_profile_comparator.h"
-
-// Utility functions used for processing and filtering address profiles
-// (AutofillProfile).
-
-namespace autofill {
-class AutofillProfile;
-} // namespace autofill
-
-namespace payments {
-
-class PaymentOptionsProvider;
-
-namespace profile_util {
-
-// Returns profiles for contact info, ordered by completeness and deduplicated.
-// |profiles| should be passed in order of frecency, and this order will be
-// preserved among equally-complete profiles. Deduplication here means that
-// profiles returned are excluded if they are a subset of a more complete or
-// more frecent profile. Completeness here refers only to the presence of the
-// fields requested per the request_payer_* fields in |options|.
-std::vector<autofill::AutofillProfile*> FilterProfilesForContact(
- const std::vector<autofill::AutofillProfile*>& profiles,
- const std::string& app_locale,
- const PaymentOptionsProvider& options);
-
-// Helper class which evaluates profiles for similarity and completeness.
-class PaymentsProfileComparator : public autofill::AutofillProfileComparator {
- public:
- PaymentsProfileComparator(const std::string& app_locale,
- const PaymentOptionsProvider& options);
- ~PaymentsProfileComparator();
-
- // Returns true iff all of the contact info in |sub| also appears in |super|.
- // Only operates on fields requested in |options|.
- bool IsContactEqualOrSuperset(const autofill::AutofillProfile& super,
- const autofill::AutofillProfile& sub);
-
- // Returns the number of contact fields requested in |options| which are
- // nonempty in |profile|.
- int GetContactCompletenessScore(const autofill::AutofillProfile* profile);
-
- // Returns true iff every contact field requested in |options| is nonempty in
- // |profile|.
- bool IsContactInfoComplete(const autofill::AutofillProfile* profile);
-
- // Comparison function suitable for sorting profiles by contact completeness
- // score with std::sort.
- bool IsContactMoreComplete(const autofill::AutofillProfile* p1,
- const autofill::AutofillProfile* p2);
-
- private:
- const PaymentOptionsProvider& options_;
-};
-
-} // namespace profile_util
-} // namespace payments
-
-#endif // COMPONENTS_PAYMENTS_CONTENT_PROFILE_UTIL_H_ \ No newline at end of file
diff --git a/chromium/components/payments/core/profile_util_unittest.cc b/chromium/components/payments/core/profile_util_unittest.cc
deleted file mode 100644
index 5ff1d7ec4e3..00000000000
--- a/chromium/components/payments/core/profile_util_unittest.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2017 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/payments/core/profile_util.h"
-
-#include <memory>
-#include <vector>
-
-#include "base/guid.h"
-#include "base/memory/ptr_util.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/payments/core/payment_options_provider.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using autofill::AutofillProfile;
-
-namespace payments {
-namespace profile_util {
-
-constexpr uint32_t kRequestPayerName = 1 << 0;
-constexpr uint32_t kRequestPayerEmail = 1 << 1;
-constexpr uint32_t kRequestPayerPhone = 1 << 2;
-constexpr uint32_t kRequestShipping = 1 << 3;
-
-class MockPaymentOptionsProvider : public PaymentOptionsProvider {
- public:
- MockPaymentOptionsProvider(uint32_t options) : options_(options) {}
-
- ~MockPaymentOptionsProvider() override {}
- bool request_payer_name() const override {
- return options_ & kRequestPayerName;
- }
- bool request_payer_email() const override {
- return options_ & kRequestPayerEmail;
- }
- bool request_payer_phone() const override {
- return options_ & kRequestPayerPhone;
- }
- bool request_shipping() const override { return options_ & kRequestShipping; }
- PaymentShippingType shipping_type() const override {
- return PaymentShippingType::SHIPPING;
- }
-
- private:
- uint32_t options_;
-};
-
-AutofillProfile CreateProfileWithContactInfo(const char* name,
- const char* email,
- const char* phone) {
- AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/");
- autofill::test::SetProfileInfo(&profile, name, "", "", email, "", "", "", "",
- "", "", "", phone);
- return profile;
-}
-
-TEST(PaymentRequestProfileUtilTest, FilterProfilesForContact) {
- // These profiles are subset/equal, so only the first complete one is
- // included.
- AutofillProfile exclude_1 =
- CreateProfileWithContactInfo("Homer", "", "5551234567");
-
- AutofillProfile exclude_2 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
-
- AutofillProfile include_1 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
-
- AutofillProfile exclude_3 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
-
- // This profile is different, so it should also be included. Since it is
- // less complete than |include_1|, it will appear after.
- AutofillProfile include_2 =
- CreateProfileWithContactInfo("Marge", "marge@simpson.net", "");
-
- // This profile is different, so it should also be included. Since it is
- // equally complete with |include_1|, it will appear before |include_2|, but
- // after |include_1| since order is preserved amongst profiles of equal
- // completeness.
- AutofillProfile include_3 = CreateProfileWithContactInfo(
- "Bart", "eatmyshorts@simpson.net", "5551234567");
-
- std::vector<AutofillProfile*> profiles = {&exclude_1, &exclude_2, &include_1,
- &exclude_3, &include_2, &include_3};
-
- MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail |
- kRequestPayerPhone);
- std::vector<AutofillProfile*> filtered =
- FilterProfilesForContact(profiles, "en-US", provider);
-
- ASSERT_EQ(3u, filtered.size());
- EXPECT_EQ(&include_1, filtered[0]);
- EXPECT_EQ(&include_3, filtered[1]);
- EXPECT_EQ(&include_2, filtered[2]);
-
- // Repeat the filter using a provider set to only request phone numbers.
- // Under these rules, since all profiles have the same (or no) phone number,
- // we should only see the first profile with a phone number, |exclude_1|.
- MockPaymentOptionsProvider phone_only_provider(kRequestPayerPhone);
- std::vector<AutofillProfile*> filtered_phones =
- FilterProfilesForContact(profiles, "en-US", phone_only_provider);
- ASSERT_EQ(1u, filtered_phones.size());
- EXPECT_EQ(&exclude_1, filtered_phones[0]);
-}
-
-TEST(PaymentRequestProfileUtilTest, IsContactEqualOrSuperset) {
- MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail |
- kRequestPayerPhone);
- PaymentsProfileComparator comp("en-US", provider);
-
- AutofillProfile p1 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
-
- // Candidate subset profile is equal.
- AutofillProfile p2 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p2));
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p2, p1));
-
- // Candidate subset profile has non-matching fields.
- AutofillProfile p3 = CreateProfileWithContactInfo(
- "Homer", "homer@springfieldnuclear.gov", "5551234567");
- EXPECT_FALSE(comp.IsContactEqualOrSuperset(p1, p3));
- EXPECT_FALSE(comp.IsContactEqualOrSuperset(p3, p1));
-
- // Candidate subset profile is equal, except for missing fields.
- AutofillProfile p4 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p4));
- EXPECT_FALSE(comp.IsContactEqualOrSuperset(p4, p1));
-
- // One field is common, but each has a field which the other is missing.
- AutofillProfile p5 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
- AutofillProfile p6 = CreateProfileWithContactInfo("Homer", "", "5551234567");
- EXPECT_FALSE(comp.IsContactEqualOrSuperset(p5, p6));
- EXPECT_FALSE(comp.IsContactEqualOrSuperset(p6, p5));
-}
-
-TEST(PaymentRequestProfileUtilTest, IsContactEqualOrSuperset_WithFieldIgnored) {
- // Discrepancies in email should be ignored throughout this test.
- MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone);
- PaymentsProfileComparator comp("en-US", provider);
-
- AutofillProfile p1 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
-
- // Candidate subset profile is equal.
- AutofillProfile p2 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p2));
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p2, p1));
-
- // Email fields don't match, but profiles are still equal.
- AutofillProfile p3 = CreateProfileWithContactInfo(
- "Homer", "homer@springfieldnuclear.gov", "5551234567");
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p3));
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p3, p1));
-
- // Profile without an email is mutual subset of profile with an email.
- AutofillProfile p4 = CreateProfileWithContactInfo("Homer", "", "5551234567");
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p4));
- EXPECT_TRUE(comp.IsContactEqualOrSuperset(p4, p1));
-}
-
-TEST(PaymentRequestProfileUtilTest, GetContactCompletenessScore) {
- MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone);
- PaymentsProfileComparator comp("en-US", provider);
-
- // Two completeness points: One each for name and phone number, but not email
- // as it was not requested.
- AutofillProfile p1 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
- EXPECT_EQ(2, comp.GetContactCompletenessScore(&p1));
-
- // One completeness point for name, no points for phone number (missing) or
- // email (not requested).
- AutofillProfile p2 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
- EXPECT_EQ(1, comp.GetContactCompletenessScore(&p2));
-
- // No completeness points, as the only field present was not requested.
- AutofillProfile p3 =
- CreateProfileWithContactInfo("", "homer@simpson.net", "");
- EXPECT_EQ(0, comp.GetContactCompletenessScore(&p3));
-
- // Null profile returns 0.
- EXPECT_EQ(0, comp.GetContactCompletenessScore(nullptr));
-}
-
-TEST(PaymentRequestProfileUtilTest, IsContactInfoComplete) {
- MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail);
- PaymentsProfileComparator comp("en-US", provider);
-
- // If name and email are present, return true regardless of the (ignored)
- // phone value.
- AutofillProfile p1 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567");
- AutofillProfile p2 =
- CreateProfileWithContactInfo("Homer", "homer@simpson.net", "");
-
- EXPECT_TRUE(comp.IsContactInfoComplete(&p1));
- EXPECT_TRUE(comp.IsContactInfoComplete(&p2));
-
- // If name is not present, return false regardless of the (ignored)
- // phone value.
- AutofillProfile p3 =
- CreateProfileWithContactInfo("", "homer@simpson.net", "5551234567");
- AutofillProfile p4 =
- CreateProfileWithContactInfo("", "homer@simpson.net", "");
-
- EXPECT_FALSE(comp.IsContactInfoComplete(&p3));
- EXPECT_FALSE(comp.IsContactInfoComplete(&p4));
-
- // If no fields are requested, any profile (even empty or null) is complete.
- MockPaymentOptionsProvider empty_provider(0);
- PaymentsProfileComparator empty_comp("en-US", empty_provider);
-
- AutofillProfile p5 = CreateProfileWithContactInfo("", "", "");
-
- EXPECT_TRUE(empty_comp.IsContactInfoComplete(&p1));
- EXPECT_TRUE(empty_comp.IsContactInfoComplete(&p5));
- EXPECT_TRUE(empty_comp.IsContactInfoComplete(nullptr));
-}
-
-} // namespace profile_util
-} // namespace payments
diff --git a/chromium/components/payments/core/strings_util.cc b/chromium/components/payments/core/strings_util.cc
index 8c405e5ba83..165d2b225b7 100644
--- a/chromium/components/payments/core/strings_util.cc
+++ b/chromium/components/payments/core/strings_util.cc
@@ -4,12 +4,53 @@
#include "components/payments/core/strings_util.h"
+#include <vector>
+
#include "base/logging.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace payments {
+base::string16 GetShippingAddressLabelFormAutofillProfile(
+ const autofill::AutofillProfile& profile,
+ const std::string& locale) {
+ // Name, phone number, and country are not included in the shipping address
+ // label.
+ static const std::vector<autofill::ServerFieldType> label_fields{
+ autofill::COMPANY_NAME,
+ autofill::ADDRESS_HOME_STREET_ADDRESS,
+ autofill::ADDRESS_HOME_DEPENDENT_LOCALITY,
+ autofill::ADDRESS_HOME_CITY,
+ autofill::ADDRESS_HOME_STATE,
+ autofill::ADDRESS_HOME_ZIP,
+ autofill::ADDRESS_HOME_SORTING_CODE,
+ };
+
+ return profile.ConstructInferredLabel(label_fields, label_fields.size(),
+ locale);
+}
+
+base::string16 GetBillingAddressLabelFromAutofillProfile(
+ const autofill::AutofillProfile& profile,
+ const std::string& locale) {
+ // Name, company, phone number, and country are not included in the billing
+ // address label.
+ static const std::vector<autofill::ServerFieldType> label_fields{
+ autofill::ADDRESS_HOME_STREET_ADDRESS,
+ autofill::ADDRESS_HOME_DEPENDENT_LOCALITY,
+ autofill::ADDRESS_HOME_CITY,
+ autofill::ADDRESS_HOME_STATE,
+ autofill::ADDRESS_HOME_ZIP,
+ autofill::ADDRESS_HOME_SORTING_CODE,
+ };
+
+ return profile.ConstructInferredLabel(label_fields, label_fields.size(),
+ locale);
+}
+
base::string16 GetShippingAddressSelectorInfoMessage(
PaymentShippingType shipping_type) {
switch (shipping_type) {
diff --git a/chromium/components/payments/core/strings_util.h b/chromium/components/payments/core/strings_util.h
index 3d72567c44c..c693d29fe6d 100644
--- a/chromium/components/payments/core/strings_util.h
+++ b/chromium/components/payments/core/strings_util.h
@@ -5,11 +5,27 @@
#ifndef COMPONENTS_PAYMENTS_CORE_STRINGS_UTIL_H_
#define COMPONENTS_PAYMENTS_CORE_STRINGS_UTIL_H_
+#include <string>
+
#include "base/strings/string16.h"
#include "components/payments/core/payment_options_provider.h"
+namespace autofill {
+class AutofillProfile;
+}
+
namespace payments {
+// Helper function to create a shipping address label from an autofill profile.
+base::string16 GetShippingAddressLabelFormAutofillProfile(
+ const autofill::AutofillProfile& profile,
+ const std::string& locale);
+
+// Helper function to create a billing address label from an autofill profile.
+base::string16 GetBillingAddressLabelFromAutofillProfile(
+ const autofill::AutofillProfile& profile,
+ const std::string& locale);
+
// Gets the informational message to be displayed in the shipping address
// selector view when there are no valid shipping options.
base::string16 GetShippingAddressSelectorInfoMessage(
diff --git a/chromium/components/payments/core/subkey_requester.cc b/chromium/components/payments/core/subkey_requester.cc
new file mode 100644
index 00000000000..513fc54ffc4
--- /dev/null
+++ b/chromium/components/payments/core/subkey_requester.cc
@@ -0,0 +1,129 @@
+// Copyright 2017 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/payments/core/subkey_requester.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/cancelable_callback.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/time/time.h"
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+namespace payments {
+
+namespace {
+
+using ::i18n::addressinput::Source;
+using ::i18n::addressinput::Storage;
+
+class SubKeyRequest : public SubKeyRequester::Request {
+ public:
+ // The |delegate| and |address_validator| need to outlive this Request.
+ SubKeyRequest(const std::string& region_code,
+ int timeout_seconds,
+ autofill::AddressValidator* address_validator,
+ SubKeyReceiverCallback on_subkeys_received)
+ : region_code_(region_code),
+ address_validator_(address_validator),
+ on_subkeys_received_(std::move(on_subkeys_received)),
+ has_responded_(false),
+ on_timeout_(base::Bind(&::payments::SubKeyRequest::OnRulesLoaded,
+ base::Unretained(this))) {
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, on_timeout_.callback(),
+ base::TimeDelta::FromSeconds(timeout_seconds));
+ }
+
+ ~SubKeyRequest() override {}
+
+ void OnRulesLoaded() override {
+ on_timeout_.Cancel();
+ // Check if the timeout happened before the rules were loaded.
+ if (has_responded_)
+ return;
+ has_responded_ = true;
+
+ std::move(on_subkeys_received_)
+ .Run(address_validator_->GetRegionSubKeys(region_code_));
+ }
+
+ private:
+ std::string region_code_;
+ // Not owned. Never null. Outlive this object.
+ autofill::AddressValidator* address_validator_;
+
+ SubKeyReceiverCallback on_subkeys_received_;
+
+ bool has_responded_;
+ base::CancelableCallback<void()> on_timeout_;
+
+ DISALLOW_COPY_AND_ASSIGN(SubKeyRequest);
+};
+
+} // namespace
+
+SubKeyRequester::SubKeyRequester(std::unique_ptr<Source> source,
+ std::unique_ptr<Storage> storage)
+ : address_validator_(std::move(source), std::move(storage), this) {}
+
+SubKeyRequester::~SubKeyRequester() {}
+
+void SubKeyRequester::StartRegionSubKeysRequest(const std::string& region_code,
+ int timeout_seconds,
+ SubKeyReceiverCallback cb) {
+ DCHECK(timeout_seconds >= 0);
+
+ std::unique_ptr<SubKeyRequest> request(base::MakeUnique<SubKeyRequest>(
+ region_code, timeout_seconds, &address_validator_, std::move(cb)));
+
+ if (AreRulesLoadedForRegion(region_code)) {
+ request->OnRulesLoaded();
+ } else {
+ // Setup the variables so that the subkeys request is sent, when the rules
+ // are loaded.
+ pending_subkey_region_code_ = region_code;
+ pending_subkey_request_ = std::move(request);
+
+ // Start loading the rules for that region. If the rules were already in the
+ // process of being loaded, this call will do nothing.
+ LoadRulesForRegion(region_code);
+ }
+}
+
+bool SubKeyRequester::AreRulesLoadedForRegion(const std::string& region_code) {
+ return address_validator_.AreRulesLoadedForRegion(region_code);
+}
+
+void SubKeyRequester::LoadRulesForRegion(const std::string& region_code) {
+ address_validator_.LoadRules(region_code);
+}
+
+void SubKeyRequester::OnAddressValidationRulesLoaded(
+ const std::string& region_code,
+ bool success) {
+ // The case for |success| == false is already handled. if |success| == false,
+ // AddressValidator::GetRegionSubKeys will return an empty list of subkeys.
+ // Therefore, here, we can ignore the value of |success|.
+
+ // Check if there is any subkey request for that region code.
+ if (!pending_subkey_region_code_.compare(region_code))
+ pending_subkey_request_->OnRulesLoaded();
+ pending_subkey_region_code_.clear();
+ pending_subkey_request_.reset();
+}
+
+void SubKeyRequester::CancelPendingGetSubKeys() {
+ pending_subkey_region_code_.clear();
+ pending_subkey_request_.reset();
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/subkey_requester.h b/chromium/components/payments/core/subkey_requester.h
new file mode 100644
index 00000000000..1813781d5b4
--- /dev/null
+++ b/chromium/components/payments/core/subkey_requester.h
@@ -0,0 +1,73 @@
+// Copyright 2017 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_PAYMENTS_CORE_SUBKEY_REQUESTER_H_
+#define COMPONENTS_PAYMENTS_CORE_SUBKEY_REQUESTER_H_
+
+#include "base/macros.h"
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+
+namespace payments {
+
+using SubKeyReceiverCallback =
+ base::OnceCallback<void(const std::vector<std::string>&)>;
+
+// SubKeyRequester Loads Rules from the server and extracts the subkeys.
+// For a given key (region code for a country, such as US), the list of its
+// corresponding subkeys is the list of that countries admin areas (states,
+// provinces, ..).
+class SubKeyRequester : public autofill::LoadRulesListener {
+ public:
+ // The interface for the subkey request.
+ class Request {
+ public:
+ virtual void OnRulesLoaded() = 0;
+ virtual ~Request() {}
+ };
+
+ SubKeyRequester(std::unique_ptr<i18n::addressinput::Source> source,
+ std::unique_ptr<i18n::addressinput::Storage> storage);
+ ~SubKeyRequester() override;
+
+ // If the rules for |region_code| are loaded, this gets the subkeys for the
+ // |region_code|, synchronously. If they are not loaded yet, it sets up a
+ // task to get the subkeys when the rules are loaded (asynchronous). If the
+ // loading has not yet started, it will also start loading the rules for the
+ // |region_code|. The received subkeys will be returned to the |requester|. If
+ // the subkeys are not received in |timeout_seconds|, then the requester will
+ // be informed and the request will be canceled. |requester| should never be
+ // null.
+ void StartRegionSubKeysRequest(const std::string& region_code,
+ int timeout_seconds,
+ SubKeyReceiverCallback cb);
+
+ // Returns whether the rules for the specified |region_code| have finished
+ // loading.
+ bool AreRulesLoadedForRegion(const std::string& region_code);
+
+ // Start loading the rules for the specified |region_code|.
+ virtual void LoadRulesForRegion(const std::string& region_code);
+
+ // Cancels the pending subkey request task.
+ void CancelPendingGetSubKeys();
+
+ private:
+ // Called when the address rules for the |region_code| have finished
+ // loading. Implementation of the LoadRulesListener interface.
+ void OnAddressValidationRulesLoaded(const std::string& region_code,
+ bool success) override;
+
+ // The region code and the request for the pending subkey request.
+ std::unique_ptr<Request> pending_subkey_request_;
+ std::string pending_subkey_region_code_;
+
+ // The address validator used to load subkeys.
+ autofill::AddressValidator address_validator_;
+
+ DISALLOW_COPY_AND_ASSIGN(SubKeyRequester);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_SUBKEY_REQUESTER_H_
diff --git a/chromium/components/payments/core/subkey_requester_unittest.cc b/chromium/components/payments/core/subkey_requester_unittest.cc
new file mode 100644
index 00000000000..f679c16a6b0
--- /dev/null
+++ b/chromium/components/payments/core/subkey_requester_unittest.cc
@@ -0,0 +1,194 @@
+// Copyright 2017 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/payments/core/subkey_requester.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_scheduler.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+#include "third_party/libaddressinput/src/cpp/test/testdata_source.h"
+
+namespace payments {
+namespace {
+
+using ::i18n::addressinput::NullStorage;
+using ::i18n::addressinput::Source;
+using ::i18n::addressinput::Storage;
+using ::i18n::addressinput::TestdataSource;
+
+const char kLocale[] = "OZ";
+const int kInvalidSize = -1;
+const int kCorrectSize = 2; // for subkeys = Do, Re
+const int kEmptySize = 0;
+
+class SubKeyReceiver : public base::RefCountedThreadSafe<SubKeyReceiver> {
+ public:
+ SubKeyReceiver() : subkeys_size_(kInvalidSize) {}
+
+ void OnSubKeysReceived(const std::vector<std::string>& subkeys) {
+ subkeys_size_ = subkeys.size();
+ }
+
+ int subkeys_size() const { return subkeys_size_; }
+
+ private:
+ friend class base::RefCountedThreadSafe<SubKeyReceiver>;
+ ~SubKeyReceiver() {}
+
+ int subkeys_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(SubKeyReceiver);
+};
+
+// Used to load region rules for this test.
+class ChromiumTestdataSource : public TestdataSource {
+ public:
+ ChromiumTestdataSource() : TestdataSource(true) {}
+
+ ~ChromiumTestdataSource() override {}
+
+ // For this test, only load the rules for the kLocale.
+ void Get(const std::string& key, const Callback& data_ready) const override {
+ data_ready(
+ true, key,
+ new std::string(
+ "{\"data/OZ\": "
+ "{\"id\":\"data/OZ\",\"key\":\"OZ\",\"name\":\"Oz \", "
+ "\"lang\":\"en\",\"languages\":\"en\",\"sub_keys\":\"DO~Re\"}}"));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ChromiumTestdataSource);
+};
+
+// A test subclass of the SubKeyRequesterImpl. Used to simulate rules not
+// being loaded.
+class TestSubKeyRequester : public SubKeyRequester {
+ public:
+ TestSubKeyRequester(std::unique_ptr<::i18n::addressinput::Source> source,
+ std::unique_ptr<::i18n::addressinput::Storage> storage)
+ : SubKeyRequester(std::move(source), std::move(storage)),
+ should_load_rules_(true) {}
+
+ ~TestSubKeyRequester() override {}
+
+ void ShouldLoadRules(bool should_load_rules) {
+ should_load_rules_ = should_load_rules;
+ }
+
+ void LoadRulesForRegion(const std::string& region_code) override {
+ if (should_load_rules_) {
+ SubKeyRequester::LoadRulesForRegion(region_code);
+ }
+ }
+
+ private:
+ bool should_load_rules_;
+ base::test::ScopedTaskScheduler scoped_task_scheduler_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestSubKeyRequester);
+};
+
+} // namespace
+
+class SubKeyRequesterTest : public testing::Test {
+ protected:
+ SubKeyRequesterTest()
+ : requester_(new TestSubKeyRequester(
+ std::unique_ptr<Source>(new ChromiumTestdataSource),
+ std::unique_ptr<Storage>(new NullStorage))) {}
+
+ ~SubKeyRequesterTest() override {}
+
+ const std::unique_ptr<TestSubKeyRequester> requester_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SubKeyRequesterTest);
+};
+
+// Tests that rules are not loaded by default.
+TEST_F(SubKeyRequesterTest, AreRulesLoadedForRegion_NotLoaded) {
+ EXPECT_FALSE(requester_->AreRulesLoadedForRegion(kLocale));
+}
+
+// Tests that the rules are loaded correctly.
+TEST_F(SubKeyRequesterTest, AreRulesLoadedForRegion_Loaded) {
+ requester_->LoadRulesForRegion(kLocale);
+ EXPECT_TRUE(requester_->AreRulesLoadedForRegion(kLocale));
+}
+
+// Tests that if the rules are loaded before the subkey request is started, the
+// received subkeys will be returned to the delegate synchronously.
+TEST_F(SubKeyRequesterTest, StartRequest_RulesLoaded) {
+ scoped_refptr<SubKeyReceiver> subkey_receiver_ = new SubKeyReceiver();
+
+ SubKeyReceiverCallback cb =
+ base::BindOnce(&SubKeyReceiver::OnSubKeysReceived, subkey_receiver_);
+
+ // Load the rules.
+ requester_->LoadRulesForRegion(kLocale);
+ EXPECT_TRUE(requester_->AreRulesLoadedForRegion(kLocale));
+
+ // Start the request.
+ requester_->StartRegionSubKeysRequest(kLocale, 0, std::move(cb));
+
+ // Since the rules are already loaded, the subkeys should be received
+ // synchronously.
+ EXPECT_EQ(subkey_receiver_->subkeys_size(), kCorrectSize);
+}
+
+// Tests that if the rules are not loaded before the request and cannot be
+// loaded after, the subkeys will not be received and the delegate will be
+// notified.
+TEST_F(SubKeyRequesterTest, StartRequest_RulesNotLoaded_WillNotLoad) {
+ scoped_refptr<SubKeyReceiver> subkey_receiver_ = new SubKeyReceiver();
+
+ SubKeyReceiverCallback cb =
+ base::BindOnce(&SubKeyReceiver::OnSubKeysReceived, subkey_receiver_);
+
+ // Make sure the rules will not be loaded in the StartRegionSubKeysRequest
+ // call.
+ requester_->ShouldLoadRules(false);
+
+ // Start the normalization.
+ requester_->StartRegionSubKeysRequest(kLocale, 0, std::move(cb));
+
+ // Let the timeout execute.
+ base::RunLoop().RunUntilIdle();
+
+ // Since the rules are never loaded and the timeout is 0, the delegate should
+ // get notified that the subkeys could not be received.
+ EXPECT_EQ(subkey_receiver_->subkeys_size(), kEmptySize);
+}
+
+// Tests that if the rules are not loaded before the call to
+// StartRegionSubKeysRequest, they will be loaded in the call.
+TEST_F(SubKeyRequesterTest, StartRequest_RulesNotLoaded_WillLoad) {
+ scoped_refptr<SubKeyReceiver> subkey_receiver_ = new SubKeyReceiver();
+
+ SubKeyReceiverCallback cb =
+ base::BindOnce(&SubKeyReceiver::OnSubKeysReceived, subkey_receiver_);
+
+ // Make sure the rules will not be loaded in the StartRegionSubKeysRequest
+ // call.
+ requester_->ShouldLoadRules(true);
+ // Start the request.
+ requester_->StartRegionSubKeysRequest(kLocale, 0, std::move(cb));
+
+ // Even if the rules are not loaded before the call to
+ // StartRegionSubKeysRequest, they should get loaded in the call. Since our
+ // test source is synchronous, the request will happen synchronously
+ // too.
+ EXPECT_TRUE(requester_->AreRulesLoadedForRegion(kLocale));
+ EXPECT_EQ(subkey_receiver_->subkeys_size(), kCorrectSize);
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/test_address_normalizer.cc b/chromium/components/payments/core/test_address_normalizer.cc
new file mode 100644
index 00000000000..e0b9fc868e8
--- /dev/null
+++ b/chromium/components/payments/core/test_address_normalizer.cc
@@ -0,0 +1,38 @@
+// Copyright 2017 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/payments/core/test_address_normalizer.h"
+
+namespace payments {
+
+bool TestAddressNormalizer::AreRulesLoadedForRegion(
+ const std::string& region_code) {
+ return true;
+}
+
+void TestAddressNormalizer::StartAddressNormalization(
+ const autofill::AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ AddressNormalizer::Delegate* requester) {
+ if (instantaneous_normalization_) {
+ requester->OnAddressNormalized(profile);
+ return;
+ }
+
+ // Setup the necessary variables for the delayed normalization.
+ profile_ = profile;
+ requester_ = requester;
+}
+
+void TestAddressNormalizer::DelayNormalization() {
+ instantaneous_normalization_ = false;
+}
+
+void TestAddressNormalizer::CompleteAddressNormalization() {
+ DCHECK(instantaneous_normalization_ == false);
+ requester_->OnAddressNormalized(profile_);
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/test_address_normalizer.h b/chromium/components/payments/core/test_address_normalizer.h
new file mode 100644
index 00000000000..56def89de36
--- /dev/null
+++ b/chromium/components/payments/core/test_address_normalizer.h
@@ -0,0 +1,46 @@
+// Copyright 2017 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_PAYMENTS_CORE_TEST_ADDRESS_NORMALIZER_H_
+#define COMPONENTS_PAYMENTS_CORE_TEST_ADDRESS_NORMALIZER_H_
+
+#include "components/payments/core/address_normalizer.h"
+
+#include "components/autofill/core/browser/autofill_profile.h"
+
+namespace payments {
+
+// A simpler version of the address normalizer to be used in tests. Can be set
+// to normalize instantaneously or to wait for a call.
+class TestAddressNormalizer : public AddressNormalizer {
+ public:
+ TestAddressNormalizer() {}
+
+ void LoadRulesForRegion(const std::string& region_code) override {}
+
+ bool AreRulesLoadedForRegion(const std::string& region_code) override;
+
+ void StartAddressNormalization(
+ const autofill::AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ AddressNormalizer::Delegate* requester) override;
+
+ void OnAddressValidationRulesLoaded(const std::string& region_code,
+ bool success) override {}
+
+ void DelayNormalization();
+
+ void CompleteAddressNormalization();
+
+ private:
+ autofill::AutofillProfile profile_;
+ AddressNormalizer::Delegate* requester_;
+
+ bool instantaneous_normalization_ = true;
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_TEST_ADDRESS_NORMALIZER_H_ \ No newline at end of file
diff --git a/chromium/components/payments/core/test_payment_request_delegate.cc b/chromium/components/payments/core/test_payment_request_delegate.cc
new file mode 100644
index 00000000000..66794195362
--- /dev/null
+++ b/chromium/components/payments/core/test_payment_request_delegate.cc
@@ -0,0 +1,88 @@
+// Copyright 2017 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/payments/core/test_payment_request_delegate.h"
+
+#include "base/strings/utf_string_conversions.h"
+
+namespace payments {
+
+TestPaymentRequestDelegate::TestPaymentRequestDelegate(
+ autofill::PersonalDataManager* personal_data_manager)
+ : personal_data_manager_(personal_data_manager),
+ locale_("en-US"),
+ last_committed_url_("https://shop.com") {}
+
+TestPaymentRequestDelegate::~TestPaymentRequestDelegate() {}
+
+autofill::PersonalDataManager*
+TestPaymentRequestDelegate::GetPersonalDataManager() {
+ return personal_data_manager_;
+}
+
+const std::string& TestPaymentRequestDelegate::GetApplicationLocale() const {
+ return locale_;
+}
+
+bool TestPaymentRequestDelegate::IsIncognito() const {
+ return false;
+}
+
+bool TestPaymentRequestDelegate::IsSslCertificateValid() {
+ return true;
+}
+
+const GURL& TestPaymentRequestDelegate::GetLastCommittedURL() const {
+ return last_committed_url_;
+}
+
+void TestPaymentRequestDelegate::DoFullCardRequest(
+ const autofill::CreditCard& credit_card,
+ base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
+ result_delegate) {
+ if (instantaneous_full_card_request_result_) {
+ result_delegate->OnFullCardRequestSucceeded(credit_card,
+ base::ASCIIToUTF16("123"));
+ return;
+ }
+
+ full_card_request_card_ = credit_card;
+ full_card_result_delegate_ = result_delegate;
+}
+
+AddressNormalizer* TestPaymentRequestDelegate::GetAddressNormalizer() {
+ return &address_normalizer_;
+}
+
+autofill::RegionDataLoader* TestPaymentRequestDelegate::GetRegionDataLoader() {
+ return nullptr;
+}
+
+ukm::UkmRecorder* TestPaymentRequestDelegate::GetUkmRecorder() {
+ return nullptr;
+}
+
+TestAddressNormalizer* TestPaymentRequestDelegate::test_address_normalizer() {
+ return &address_normalizer_;
+}
+
+void TestPaymentRequestDelegate::DelayFullCardRequestCompletion() {
+ instantaneous_full_card_request_result_ = false;
+}
+
+void TestPaymentRequestDelegate::CompleteFullCardRequest() {
+ DCHECK(instantaneous_full_card_request_result_ == false);
+ full_card_result_delegate_->OnFullCardRequestSucceeded(
+ full_card_request_card_, base::ASCIIToUTF16("123"));
+}
+
+std::string TestPaymentRequestDelegate::GetAuthenticatedEmail() const {
+ return "";
+}
+
+PrefService* TestPaymentRequestDelegate::GetPrefService() {
+ return nullptr;
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/core/test_payment_request_delegate.h b/chromium/components/payments/core/test_payment_request_delegate.h
new file mode 100644
index 00000000000..e0697a7d326
--- /dev/null
+++ b/chromium/components/payments/core/test_payment_request_delegate.h
@@ -0,0 +1,59 @@
+// Copyright 2017 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_PAYMENTS_CORE_TEST_PAYMENT_REQUEST_DELEGATE_H_
+#define COMPONENTS_PAYMENTS_CORE_TEST_PAYMENT_REQUEST_DELEGATE_H_
+
+#include <string>
+
+#include "components/payments/core/payment_request_delegate.h"
+#include "components/payments/core/test_address_normalizer.h"
+
+namespace payments {
+
+class TestPaymentRequestDelegate : public PaymentRequestDelegate {
+ public:
+ TestPaymentRequestDelegate(
+ autofill::PersonalDataManager* personal_data_manager);
+ ~TestPaymentRequestDelegate() override;
+
+ // PaymentRequestDelegate
+ void ShowDialog(PaymentRequest* request) override {}
+ void CloseDialog() override {}
+ void ShowErrorMessage() override {}
+ autofill::PersonalDataManager* GetPersonalDataManager() override;
+ const std::string& GetApplicationLocale() const override;
+ bool IsIncognito() const override;
+ bool IsSslCertificateValid() override;
+ const GURL& GetLastCommittedURL() const override;
+ void DoFullCardRequest(
+ const autofill::CreditCard& credit_card,
+ base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
+ result_delegate) override;
+ AddressNormalizer* GetAddressNormalizer() override;
+ autofill::RegionDataLoader* GetRegionDataLoader() override;
+ ukm::UkmRecorder* GetUkmRecorder() override;
+ std::string GetAuthenticatedEmail() const override;
+ PrefService* GetPrefService() override;
+
+ TestAddressNormalizer* test_address_normalizer();
+ void DelayFullCardRequestCompletion();
+ void CompleteFullCardRequest();
+
+ private:
+ autofill::PersonalDataManager* personal_data_manager_;
+ std::string locale_;
+ const GURL last_committed_url_;
+ TestAddressNormalizer address_normalizer_;
+
+ bool instantaneous_full_card_request_result_ = true;
+ autofill::CreditCard full_card_request_card_;
+ base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
+ full_card_result_delegate_;
+ DISALLOW_COPY_AND_ASSIGN(TestPaymentRequestDelegate);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_TEST_PAYMENT_REQUEST_DELEGATE_H_
diff --git a/chromium/components/payments/mojom/BUILD.gn b/chromium/components/payments/mojom/BUILD.gn
new file mode 100644
index 00000000000..9268a078a11
--- /dev/null
+++ b/chromium/components/payments/mojom/BUILD.gn
@@ -0,0 +1,33 @@
+# Copyright 2017 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("mojom") {
+ sources = [
+ "payment_request.mojom",
+ ]
+}
+
+mojom("mojom_parser") {
+ sources = [
+ "payment_manifest_parser.mojom",
+ ]
+
+ public_deps = [
+ "//url/mojo:url_mojom_gurl",
+ ]
+}
+
+mojom("mojom_payment_app") {
+ sources = [
+ "payment_app.mojom",
+ ]
+
+ public_deps = [
+ ":mojom",
+ "//mojo/common:common_custom_types",
+ "//url/mojo:url_mojom_gurl",
+ ]
+}
diff --git a/chromium/components/payments/mojom/OWNERS b/chromium/components/payments/mojom/OWNERS
new file mode 100644
index 00000000000..82559c92e72
--- /dev/null
+++ b/chromium/components/payments/mojom/OWNERS
@@ -0,0 +1,4 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# COMPONENT: UI>Browser>Autofill>Payments
diff --git a/chromium/components/payments/mojom/payment_app.mojom b/chromium/components/payments/mojom/payment_app.mojom
new file mode 100644
index 00000000000..dbf1a0f4694
--- /dev/null
+++ b/chromium/components/payments/mojom/payment_app.mojom
@@ -0,0 +1,61 @@
+// Copyright 2016 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.
+
+module payments.mojom;
+
+import "components/payments/mojom/payment_request.mojom";
+import "mojo/common/time.mojom";
+import "url/mojo/url.mojom";
+
+enum PaymentHandlerStatus {
+ SUCCESS,
+ NOT_IMPLEMENTED,
+ NOT_FOUND,
+ NO_ACTIVE_WORKER,
+ STORAGE_OPERATION_FAILED,
+};
+
+struct PaymentInstrument {
+ string name;
+ array<string> enabled_methods;
+ string stringified_capabilities;
+};
+
+interface PaymentManager {
+ Init(string service_worker_scope);
+ DeletePaymentInstrument(string instrument_key)
+ => (PaymentHandlerStatus status);
+ GetPaymentInstrument(string instrument_key)
+ => (PaymentInstrument instrument, PaymentHandlerStatus status);
+ KeysOfPaymentInstruments()
+ => (array<string> keys, PaymentHandlerStatus status);
+ HasPaymentInstrument(string instrument_key)
+ => (PaymentHandlerStatus status);
+ SetPaymentInstrument(string instrument_key, PaymentInstrument instrument)
+ => (PaymentHandlerStatus status);
+ ClearPaymentInstruments()
+ => (PaymentHandlerStatus status);
+};
+
+struct PaymentAppRequest {
+ url.mojom.Url top_level_origin;
+ url.mojom.Url payment_request_origin;
+ string payment_request_id;
+ array<PaymentMethodData> method_data;
+ PaymentItem total;
+ array<PaymentDetailsModifier> modifiers;
+ string instrument_key;
+};
+
+struct PaymentAppResponse {
+ string method_name;
+ string stringified_details;
+};
+
+// This interface is provided to pass a payment app response from payment
+// request event in renderer side to browser side by calling respondWith().
+interface PaymentAppResponseCallback {
+ OnPaymentAppResponse(PaymentAppResponse response,
+ mojo.common.mojom.Time dispatch_event_time);
+};
diff --git a/chromium/components/payments/content/payment_manifest_parser.mojom b/chromium/components/payments/mojom/payment_manifest_parser.mojom
index 96c3d3cb6d3..96c3d3cb6d3 100644
--- a/chromium/components/payments/content/payment_manifest_parser.mojom
+++ b/chromium/components/payments/mojom/payment_manifest_parser.mojom
diff --git a/chromium/components/payments/content/payment_request.mojom b/chromium/components/payments/mojom/payment_request.mojom
index 600838286ad..72c3dac791b 100644
--- a/chromium/components/payments/content/payment_request.mojom
+++ b/chromium/components/payments/mojom/payment_request.mojom
@@ -80,7 +80,12 @@ enum PaymentErrorReason {
enum CanMakePaymentQueryResult {
CAN_MAKE_PAYMENT,
CANNOT_MAKE_PAYMENT,
- QUERY_QUOTA_EXCEEDED
+ QUERY_QUOTA_EXCEEDED,
+
+ // Used only on localhost and file:// schemes to warn web developer that the
+ // query quota has exceeded, but Chrome is returning an answer anyway.
+ WARNING_CAN_MAKE_PAYMENT,
+ WARNING_CANNOT_MAKE_PAYMENT,
};
interface PaymentRequestClient {
@@ -91,6 +96,7 @@ interface PaymentRequestClient {
OnComplete();
OnAbort(bool aborted_successfully);
OnCanMakePayment(CanMakePaymentQueryResult result);
+ WarnNoFavicon();
};
struct PaymentItem {
@@ -188,6 +194,11 @@ struct PaymentDetails {
array<PaymentShippingOption> shipping_options;
array<PaymentDetailsModifier> modifiers;
string error = "";
+ // Identifier identifying the payment request, to be exposed
+ // to payment apps. It is optional since this structure is used
+ // by PaymentDetailsUpdate (next to PaymentDetailsInit) but
+ // PaymentDetailsUpdate has no id.
+ string? id;
};
enum PaymentShippingType {
diff --git a/chromium/components/payments_strings.grdp b/chromium/components/payments_strings.grdp
index b1e6220d38f..974c7a760c4 100644
--- a/chromium/components/payments_strings.grdp
+++ b/chromium/components/payments_strings.grdp
@@ -7,6 +7,12 @@
<message name="IDS_PAYMENTS_NAME_FIELD_IN_CONTACT_DETAILS" desc="The label for text input field containing the full name of a person. [CHAR-LIMIT=32]" formatter_data="android_java">
Name
</message>
+ <message name="IDS_PAYMENTS_PHONE_FIELD_IN_CONTACT_DETAILS" desc="The label for text input field containing a phone number. [CHAR-LIMIT=32]">
+ Phone number
+ </message>
+ <message name="IDS_PAYMENTS_EMAIL_FIELD_IN_CONTACT_DETAILS" desc="The label for text input field containing an email address. [CHAR-LIMIT=32]">
+ Email
+ </message>
<message name="IDS_PAYMENTS_SAVE_CARD_TO_DEVICE_CHECKBOX" desc="The label for the checkbox that enables the user to save a credit card to their device, for example, on their phone." formatter_data="android_java">
Save this card to this device
</message>
@@ -91,6 +97,9 @@
<message name="IDS_PAYMENTS_ADD_ADDRESS" desc="Text on a button that lets a user add new address." formatter_data="android_java">
Add address
</message>
+ <message name="IDS_PAYMENTS_EDIT_ADDRESS" desc="Text on a button that lets a user edit an existing address." formatter_data="android_java">
+ Edit address
+ </message>
<message name="IDS_PAYMENTS_CHECKING_OPTION" desc="Text explaining that the option the user selected is being checked and verified." formatter_data="android_java">
Checking
</message>
@@ -100,12 +109,22 @@
<message name="IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS" desc="Label of the section containing the link to go to the settings page for card and address options." formatter_data="android_java">
You can manage cards and addresses in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>.
</message>
- <message name="IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_IN" desc="Label of the section containing the origin description and the link to go to the settings page for card and address options. This label is used when the user is signed in." formatter_data="android_java">
- Cards and addresses are from Chrome and your Google Account (<ph name="ACCOUNT_EMAIL">%1$s<ex>johndoe@gmail.com</ex></ph>). You can manage them in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>.
- </message>
+ <if expr="is_android">
+ <message name="IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_IN" desc="Label of the section containing the origin description and the link to go to the settings page for card and address options. This label is used when the user is signed in." formatter_data="android_java">
+ Cards and addresses are from Chrome and your Google Account (<ph name="ACCOUNT_EMAIL">%1$s<ex>johndoe@gmail.com</ex></ph>). You can manage them in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>.
+ </message>
+ </if>
+ <if expr="not is_android">
+ <message name="IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_IN" desc="Label of the section containing the origin description and the link to go to the settings page for card and address options. This label is used when the user is signed in.">
+ Cards and addresses are from Chrome and your Google Account (<ph name="ACCOUNT_EMAIL">$1<ex>johndoe@gmail.com</ex></ph>). You can manage them in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>.
+ </message>
+ </if>
<message name="IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_OUT" desc="Label of the section containing the origin description and the link to go to the settings page for card and address options. This label is used when the user is not signed in." formatter_data="android_java">
Cards and addresses are from Chrome. You can manage them in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>.
</message>
+ <message name="IDS_PAYMENTS_CANCEL_PAYMENT" desc="Label of the secondary button in payment request editors. Clicking that button closes the dialog and aborts the payment request completely">
+ Cancel Payment
+ </message>
<!-- Credit Card form -->
<if expr="is_ios">
@@ -142,6 +161,9 @@
<message name="IDS_PAYMENTS_VALIDATION_UNSUPPORTED_CREDIT_CARD_TYPE" desc="Message displayed to user when the credit card type (e.g visa, mastercard) is not supported for this transaction.">
This type of card isn’t supported
</message>
+ <message name="IDS_PAYMENTS_VALIDATION_ALREADY_USED_CREDIT_CARD_NUMBER" desc="Message displayed to user when the credit card number they have entered corresponds to an existing credit card number in their user profile.">
+ This card number is already used
+ </message>
<message name="IDS_PAYMENTS_REQUIRED_FIELD_MESSAGE" desc="The text that informs the user that '*' character indicates an input field that is required. The '*' character should not be changed." formatter_data="android_java">
* Field is required
</message>
@@ -166,6 +188,9 @@
<message name="IDS_PAYMENTS_NAME_ON_CARD_REQUIRED" desc="The label to indicate the cardholder name (the name of the owner or “holder†of the credit card) must be entered." formatter_data="android_java">
Cardholder name required
</message>
+ <message name="IDS_PAYMENTS_CARD_BILLING_ADDRESS_REQUIRED" desc="The label to indicate the billing address of the credit card must be entered." formatter_data="android_java">
+ Card billing address required
+ </message>
<message name="IDS_PAYMENTS_MORE_INFORMATION_REQUIRED" desc="The label to indicate more information is required for payment card or shipping address or contact info." formatter_data="android_java">
More information required
</message>
@@ -198,8 +223,10 @@
<message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT" desc="The format specifier of the Total label in the Order Summary Sheet of the Payment Request dialog.">
<ph name="CURRENCY_CODE">$1<ex>USD</ex></ph> <ph name="FORMATTED_TOTAL_AMOUNT">$2<ex>$ 12.34</ex></ph>
</message>
- <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_MORE_ITEMS" desc="The label in the Order Summary section of the Payment Sheet that indicates how many display items are hidden.">
- <ph name="ITEM_COUNT">$1<ex>2</ex></ph> more items...
+ <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_MORE_ITEMS" desc="The label in the Order Summary section of the Payment Sheet that indicates how many display items are hidden. [ICU Syntax]">
+ {MORE_ITEMS, plural,
+ =1 {<ph name="ITEM_COUNT">#<ex>1</ex></ph> item}
+ other {<ph name="ITEM_COUNT">#<ex>2</ex></ph> items}}
</message>
<message name="IDS_PAYMENT_REQUEST_SHIPPING_SECTION_NAME" desc="The name of the Shipping Address section in the Payment Sheet of the Payment Request dialog.">
Shipping address
@@ -207,6 +234,9 @@
<message name="IDS_PAYMENT_REQUEST_CONTACT_INFO_SECTION_NAME" desc="The name of the Contact Info section in the Payment Sheet of the Payment Request dialog.">
Contact info
</message>
+ <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_MULTIPLE_CURRENCY_INDICATOR" desc="The label that indicates that there are multiple currencies among the display items">
+ Multiple
+ </message>
<!-- Shipping address in web payments API -->
<message name="IDS_PAYMENTS_SHIPPING_SUMMARY_LABEL" desc="The title for the section of shipping information. Shipping is used for packages and things that are mailed. In American English, “shipping†is differentiated from “deliveryâ€. “Delivery†is used, for example, for food delivery." formatter_data="android_java">
@@ -279,4 +309,28 @@
Leaving incognito mode to pay via an external application. Continue?
</message>
</if>
+
+ <!-- Payment Request section preview strings. They are slightly different on desktop and android because the pluralization and formatting code behaves differently. -->
+ <if expr="not is_android">
+ <message name="IDS_PAYMENT_REQUEST_PAYMENT_METHODS_PREVIEW" desc="This is a snippet of a payment method a user has saved to Chrome, plus an indication of the number of additional payment methods the user has saved. Its function is to show the user has payment methods that can be used to complete a payment, and thus doesn't have to type the entire payment method. [ICU Syntax]">
+ {PAYMENT_METHOD, plural,
+ =1 {<ph name="PAYMENT_METHOD_PREVIEW">{1}<ex>VISA ....1234</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS">{2}<ex>1</ex></ph> more}
+ other {<ph name="PAYMENT_METHOD_PREVIEW">{1}<ex>VISA ....1234</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS">{2}<ex>2</ex></ph> more}}
+ </message>
+ <message name="IDS_PAYMENT_REQUEST_SHIPPING_ADDRESSES_PREVIEW" desc="This is a snippet of a shipping address a user has saved to Chrome, plus an indication of the number of additional shipping addresses the user has saved. Its function is to show the user has shipping addresses that can be used to complete a purchase, and thus doesn't have to type the entire address. [ICU Syntax]" formatter_data="android_java">
+ {SHIPPING_ADDRESS, plural,
+ =1 {<ph name="SHIPPING_ADDRESS_PREVIEW">{1}<ex>Jerry, 1253 Mcgill college</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES">{2}<ex>1</ex></ph> more}
+ other {<ph name="SHIPPING_ADDRESS_PREVIEW">{1}<ex>Jerry, 1253 Mcgill college</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES">{2}<ex>2</ex></ph> more}}
+ </message>
+ <message name="IDS_PAYMENT_REQUEST_SHIPPING_OPTIONS_PREVIEW" desc="This is a snippet of a shipping option a merchant supports, plus an indication of the number of additional shipping options the merchant supports. Its function is to show the user can choose different shipping options to complete a purchase. [ICU Syntax]">
+ {SHIPPING_OPTIONS, plural,
+ =1 {<ph name="SHIPPING_OPTION_PREVIEW">{1}<ex>standard shipping</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS">{2}<ex>1</ex></ph> more}
+ other {<ph name="SHIPPING_OPTION_PREVIEW">{1}<ex>standard shipping</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS">{2}<ex>2</ex></ph> more}}
+ </message>
+ <message name="IDS_PAYMENT_REQUEST_CONTACTS_PREVIEW" desc="This is a snippet of a contact a user has saved to Chrome, plus an indication of the number of additional contacts the user has saved. Its function is to show the user has contacts that can be used to complete a purchase, and thus doesn't have to type the entire contact info. [ICU Syntax]">
+ {CONTACT, plural,
+ =1 {<ph name="CONTACT_PREVIEW">{1}<ex>Jerry, 438-123-1922</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS">{2}<ex>1</ex></ph> more}
+ other {<ph name="CONTACT_PREVIEW">{1}<ex>Jerry, 438-123-1922</ex></ph> and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS">{2}<ex>2</ex></ph> more}}
+ </message>
+ </if>
</grit-part>
diff --git a/chromium/components/pdf/browser/pdf_web_contents_helper.cc b/chromium/components/pdf/browser/pdf_web_contents_helper.cc
index fdbea015a20..64b814bfe29 100644
--- a/chromium/components/pdf/browser/pdf_web_contents_helper.cc
+++ b/chromium/components/pdf/browser/pdf_web_contents_helper.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/pdf/browser/pdf_web_contents_helper_client.h"
@@ -20,8 +21,9 @@ void PDFWebContentsHelper::CreateForWebContentsWithClient(
std::unique_ptr<PDFWebContentsHelperClient> client) {
if (FromWebContents(contents))
return;
- contents->SetUserData(UserDataKey(),
- new PDFWebContentsHelper(contents, std::move(client)));
+ contents->SetUserData(
+ UserDataKey(),
+ base::WrapUnique(new PDFWebContentsHelper(contents, std::move(client))));
}
PDFWebContentsHelper::PDFWebContentsHelper(
diff --git a/chromium/components/pdf/browser/pdf_web_contents_helper.h b/chromium/components/pdf/browser/pdf_web_contents_helper.h
index 080dca40599..0d848c7bfc5 100644
--- a/chromium/components/pdf/browser/pdf_web_contents_helper.h
+++ b/chromium/components/pdf/browser/pdf_web_contents_helper.h
@@ -29,6 +29,8 @@ class PDFWebContentsHelper
public content::WebContentsUserData<PDFWebContentsHelper>,
public mojom::PdfService {
public:
+ ~PDFWebContentsHelper() override;
+
static void CreateForWebContentsWithClient(
content::WebContents* contents,
std::unique_ptr<PDFWebContentsHelperClient> client);
@@ -36,7 +38,6 @@ class PDFWebContentsHelper
private:
PDFWebContentsHelper(content::WebContents* web_contents,
std::unique_ptr<PDFWebContentsHelperClient> client);
- ~PDFWebContentsHelper() override;
// mojom::PdfService:
void HasUnsupportedFeature() override;
diff --git a/chromium/components/pdf/renderer/pdf_accessibility_tree.cc b/chromium/components/pdf/renderer/pdf_accessibility_tree.cc
index d4c22578425..4512380c852 100644
--- a/chromium/components/pdf/renderer/pdf_accessibility_tree.cc
+++ b/chromium/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -275,7 +275,7 @@ ui::AXNodeData* PdfAccessibilityTree::CreateNode(ui::AXRole role) {
ui::AXNodeData* node = new ui::AXNodeData();
node->id = render_accessibility->GenerateAXID();
node->role = role;
- node->state = 1 << ui::AX_STATE_READ_ONLY;
+ node->AddState(ui::AX_STATE_READ_ONLY);
// All nodes other than the first one have coordinates relative to
// the first node.
diff --git a/chromium/components/pdf_strings.grdp b/chromium/components/pdf_strings.grdp
index b0c7ff70738..14a7c2f92a9 100644
--- a/chromium/components/pdf_strings.grdp
+++ b/chromium/components/pdf_strings.grdp
@@ -4,6 +4,9 @@
<message name="IDS_PDF_NEED_PASSWORD" desc="A message asking the user for a password to open a PDF file.">
This document is password protected. Please enter a password.
</message>
+ <message name="IDS_PDF_PASSWORD_DIALOG_TITLE" desc="Title of the dialog which asks the user for a password to open a PDF file.">
+ Password required
+ </message>
<message name="IDS_PDF_PASSWORD_SUBMIT" desc="Button label for the buton to submit the PDF password form">
Submit
</message>
@@ -14,8 +17,11 @@
<message name="IDS_PDF_PAGE_LOADING" desc="A message displayed on the PDF page while page is loading.">
Loading...
</message>
+ <message name="IDS_PDF_ERROR_DIALOG_TITLE" desc="Title of the dialog which shows a message indicating that there was an error while loading the PDF document.">
+ Error
+ </message>
<message name="IDS_PDF_PAGE_LOAD_FAILED" desc="A message displayed on the PDF control to indicate that the PDF document failed to load.">
- Failed to load PDF document
+ Failed to load PDF document.
</message>
<message name="IDS_PDF_PAGE_RELOAD_BUTTON" desc="Button label for the button to reload a PDF which has failed to load">
Reload
diff --git a/chromium/components/plugins/renderer/loadable_plugin_placeholder.cc b/chromium/components/plugins/renderer/loadable_plugin_placeholder.cc
index dde47c2569e..57678645368 100644
--- a/chromium/components/plugins/renderer/loadable_plugin_placeholder.cc
+++ b/chromium/components/plugins/renderer/loadable_plugin_placeholder.cc
@@ -59,10 +59,9 @@ void LoadablePluginPlaceholder::SetPremadePlugin(
LoadablePluginPlaceholder::LoadablePluginPlaceholder(
RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
const std::string& html_data)
- : PluginPlaceholderBase(render_frame, frame, params, html_data),
+ : PluginPlaceholderBase(render_frame, params, html_data),
heuristic_run_before_(false),
is_blocked_for_tinyness_(false),
is_blocked_for_background_tab_(false),
@@ -179,6 +178,10 @@ v8::Local<v8::Object> LoadablePluginPlaceholder::GetV8ScriptableObject(
return v8::Local<v8::Object>();
}
+bool LoadablePluginPlaceholder::IsErrorPlaceholder() {
+ return !allow_loading_;
+}
+
void LoadablePluginPlaceholder::OnUnobscuredRectUpdate(
const gfx::Rect& unobscured_rect) {
DCHECK(content::RenderThread::Get());
diff --git a/chromium/components/plugins/renderer/loadable_plugin_placeholder.h b/chromium/components/plugins/renderer/loadable_plugin_placeholder.h
index ea52ae9e5d6..f4a05997471 100644
--- a/chromium/components/plugins/renderer/loadable_plugin_placeholder.h
+++ b/chromium/components/plugins/renderer/loadable_plugin_placeholder.h
@@ -49,10 +49,8 @@ class LoadablePluginPlaceholder : public PluginPlaceholderBase {
protected:
LoadablePluginPlaceholder(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
const std::string& html_data);
-
~LoadablePluginPlaceholder() override;
void MarkPluginEssential(
@@ -91,6 +89,7 @@ class LoadablePluginPlaceholder : public PluginPlaceholderBase {
v8::Local<v8::Object> GetV8ScriptableObject(
v8::Isolate* isolate) const override;
void OnUnobscuredRectUpdate(const gfx::Rect& unobscured_rect) override;
+ bool IsErrorPlaceholder() override;
// RenderFrameObserver methods:
void WasShown() override;
diff --git a/chromium/components/plugins/renderer/plugin_placeholder.cc b/chromium/components/plugins/renderer/plugin_placeholder.cc
index a643433b1ef..950257531de 100644
--- a/chromium/components/plugins/renderer/plugin_placeholder.cc
+++ b/chromium/components/plugins/renderer/plugin_placeholder.cc
@@ -21,11 +21,9 @@ const char kPluginPlaceholderDataURL[] = "data:text/html,pluginplaceholderdata";
PluginPlaceholderBase::PluginPlaceholderBase(
content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
const std::string& html_data)
: content::RenderFrameObserver(render_frame),
- frame_(frame),
plugin_params_(params),
plugin_(WebViewPlugin::Create(render_frame->GetRenderView(),
this,
@@ -113,23 +111,15 @@ void PluginPlaceholderBase::HideCallback() {
HidePlugin();
}
-void PluginPlaceholderBase::OnDestruct() {
- frame_ = NULL;
-}
-
-blink::WebLocalFrame* PluginPlaceholderBase::GetFrame() {
- return frame_;
-}
+void PluginPlaceholderBase::OnDestruct() {}
// static
gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin};
PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
const std::string& html_data)
- : PluginPlaceholderBase(render_frame, frame, params, html_data) {
-}
+ : PluginPlaceholderBase(render_frame, params, html_data) {}
PluginPlaceholder::~PluginPlaceholder() {
}
@@ -138,6 +128,10 @@ v8::Local<v8::Value> PluginPlaceholder::GetV8Handle(v8::Isolate* isolate) {
return gin::CreateHandle(isolate, this).ToV8();
}
+bool PluginPlaceholderBase::IsErrorPlaceholder() {
+ return false;
+}
+
gin::ObjectTemplateBuilder PluginPlaceholder::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate)
diff --git a/chromium/components/plugins/renderer/plugin_placeholder.h b/chromium/components/plugins/renderer/plugin_placeholder.h
index 1be42e93477..86ca35287c7 100644
--- a/chromium/components/plugins/renderer/plugin_placeholder.h
+++ b/chromium/components/plugins/renderer/plugin_placeholder.h
@@ -20,19 +20,16 @@ namespace plugins {
class PluginPlaceholderBase : public content::RenderFrameObserver,
public WebViewPlugin::Delegate {
public:
- // |render_frame| and |frame| are weak pointers. If either one is going away,
- // our |plugin_| will be destroyed as well and will notify us.
+ // |render_frame| is a weak pointer. If it is going away, our |plugin_| will
+ // be destroyed as well and will notify us.
PluginPlaceholderBase(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
const std::string& html_data);
-
~PluginPlaceholderBase() override;
WebViewPlugin* plugin() { return plugin_; }
protected:
- blink::WebLocalFrame* GetFrame();
const blink::WebPluginParams& GetPluginParams() const;
// WebViewPlugin::Delegate methods:
@@ -40,11 +37,12 @@ class PluginPlaceholderBase : public content::RenderFrameObserver,
void PluginDestroyed() override;
v8::Local<v8::Object> GetV8ScriptableObject(
v8::Isolate* isolate) const override;
+ bool IsErrorPlaceholder() override;
protected:
// Hide this placeholder.
void HidePlugin();
- bool hidden() { return hidden_; }
+ bool hidden() const { return hidden_; }
// JavaScript callbacks:
void HideCallback();
@@ -53,7 +51,6 @@ class PluginPlaceholderBase : public content::RenderFrameObserver,
// RenderFrameObserver methods:
void OnDestruct() override;
- blink::WebLocalFrame* frame_;
blink::WebPluginParams plugin_params_;
WebViewPlugin* plugin_;
@@ -69,7 +66,6 @@ class PluginPlaceholder final : public PluginPlaceholderBase,
static gin::WrapperInfo kWrapperInfo;
PluginPlaceholder(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
const std::string& html_data);
~PluginPlaceholder() override;
diff --git a/chromium/components/plugins/renderer/webview_plugin.cc b/chromium/components/plugins/renderer/webview_plugin.cc
index fd001151967..80404cfe8a3 100644
--- a/chromium/components/plugins/renderer/webview_plugin.cc
+++ b/chromium/components/plugins/renderer/webview_plugin.cc
@@ -33,7 +33,6 @@ using blink::WebDragData;
using blink::WebDragOperationsMask;
using blink::WebFrameWidget;
using blink::WebImage;
-using blink::WebInputEvent;
using blink::WebLocalFrame;
using blink::WebMouseEvent;
using blink::WebPlugin;
@@ -148,6 +147,12 @@ void WebViewPlugin::UpdateAllLifecyclePhases() {
web_view()->UpdateAllLifecyclePhases();
}
+bool WebViewPlugin::IsErrorPlaceholder() {
+ if (!delegate_)
+ return false;
+ return delegate_->IsErrorPlaceholder();
+}
+
void WebViewPlugin::Paint(WebCanvas* canvas, const WebRect& rect) {
gfx::Rect paint_rect = gfx::IntersectRects(rect_, rect);
if (paint_rect.IsEmpty())
@@ -176,7 +181,6 @@ void WebViewPlugin::Paint(WebCanvas* canvas, const WebRect& rect) {
void WebViewPlugin::UpdateGeometry(const WebRect& window_rect,
const WebRect& clip_rect,
const WebRect& unobscured_rect,
- const WebVector<WebRect>& cut_outs_rects,
bool is_visible) {
DCHECK(container_);
@@ -200,19 +204,20 @@ void WebViewPlugin::UpdateFocus(bool focused, blink::WebFocusType focus_type) {
}
blink::WebInputEventResult WebViewPlugin::HandleInputEvent(
- const WebInputEvent& event,
+ const blink::WebCoalescedInputEvent& coalesced_event,
WebCursorInfo& cursor) {
+ const blink::WebInputEvent& event = coalesced_event.Event();
// For tap events, don't handle them. They will be converted to
// mouse events later and passed to here.
- if (event.GetType() == WebInputEvent::kGestureTap)
+ if (event.GetType() == blink::WebInputEvent::kGestureTap)
return blink::WebInputEventResult::kNotHandled;
// For LongPress events we return false, since otherwise the context menu will
// be suppressed. https://crbug.com/482842
- if (event.GetType() == WebInputEvent::kGestureLongPress)
+ if (event.GetType() == blink::WebInputEvent::kGestureLongPress)
return blink::WebInputEventResult::kNotHandled;
- if (event.GetType() == WebInputEvent::kContextMenu) {
+ if (event.GetType() == blink::WebInputEvent::kContextMenu) {
if (delegate_) {
const WebMouseEvent& mouse_event =
reinterpret_cast<const WebMouseEvent&>(event);
@@ -328,14 +333,20 @@ void WebViewPlugin::WebViewHelper::ScheduleAnimation() {
}
}
-void WebViewPlugin::WebViewHelper::DidClearWindowObject(WebLocalFrame* frame) {
- DCHECK_EQ(frame, web_view_->MainFrame());
+std::unique_ptr<blink::WebURLLoader>
+WebViewPlugin::WebViewHelper::CreateURLLoader() {
+ // TODO(yhirano): Stop using Platform::CreateURLLoader() here.
+ return blink::Platform::Current()->CreateURLLoader();
+}
+
+void WebViewPlugin::WebViewHelper::DidClearWindowObject() {
if (!plugin_->delegate_)
return;
v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = frame->MainWorldScriptContext();
+ v8::Local<v8::Context> context =
+ web_view_->MainFrame()->MainWorldScriptContext();
DCHECK(!context.IsEmpty());
v8::Context::Scope context_scope(context);
@@ -345,6 +356,14 @@ void WebViewPlugin::WebViewHelper::DidClearWindowObject(WebLocalFrame* frame) {
plugin_->delegate_->GetV8Handle(isolate));
}
+void WebViewPlugin::WebViewHelper::FrameDetached(blink::WebLocalFrame* frame,
+ DetachType type) {
+ if (frame->FrameWidget())
+ frame->FrameWidget()->Close();
+
+ frame->Close();
+}
+
void WebViewPlugin::OnZoomLevelChanged() {
if (container_) {
web_view()->SetZoomLevel(
diff --git a/chromium/components/plugins/renderer/webview_plugin.h b/chromium/components/plugins/renderer/webview_plugin.h
index 16daff31f3a..5e3693ea755 100644
--- a/chromium/components/plugins/renderer/webview_plugin.h
+++ b/chromium/components/plugins/renderer/webview_plugin.h
@@ -55,6 +55,8 @@ class WebViewPlugin : public blink::WebPlugin,
// Called when the unobscured rect of the plugin is updated.
virtual void OnUnobscuredRectUpdate(const gfx::Rect& unobscured_rect) {}
+
+ virtual bool IsErrorPlaceholder() = 0;
};
// Convenience method to set up a new WebViewPlugin using |preferences|
@@ -84,6 +86,8 @@ class WebViewPlugin : public blink::WebPlugin,
v8::Local<v8::Object> V8ScriptableObject(v8::Isolate* isolate) override;
+ bool IsErrorPlaceholder() override;
+
void UpdateAllLifecyclePhases() override;
void Paint(blink::WebCanvas* canvas, const blink::WebRect& rect) override;
@@ -91,14 +95,13 @@ class WebViewPlugin : public blink::WebPlugin,
void UpdateGeometry(const blink::WebRect& window_rect,
const blink::WebRect& clip_rect,
const blink::WebRect& unobscured_rect,
- const blink::WebVector<blink::WebRect>& cut_outs_rects,
bool is_visible) override;
void UpdateFocus(bool foucsed, blink::WebFocusType focus_type) override;
void UpdateVisibility(bool) override {}
blink::WebInputEventResult HandleInputEvent(
- const blink::WebInputEvent& event,
+ const blink::WebCoalescedInputEvent& event,
blink::WebCursorInfo& cursor_info) override;
void DidReceiveResponse(const blink::WebURLResponse& response) override;
@@ -168,9 +171,11 @@ class WebViewPlugin : public blink::WebPlugin,
void DidInvalidateRect(const blink::WebRect&) override;
void DidChangeCursor(const blink::WebCursorInfo& cursor) override;
void ScheduleAnimation() override;
+ std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override;
// WebFrameClient methods:
- void DidClearWindowObject(blink::WebLocalFrame* frame) override;
+ void DidClearWindowObject() override;
+ void FrameDetached(blink::WebLocalFrame*, DetachType) override;
private:
WebViewPlugin* plugin_;
diff --git a/chromium/components/policy/core/common/BUILD.gn b/chromium/components/policy/core/common/BUILD.gn
index 17a58604882..17217b1ad87 100644
--- a/chromium/components/policy/core/common/BUILD.gn
+++ b/chromium/components/policy/core/common/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//build/config/features.gni")
+import("//testing/libfuzzer/fuzzer_test.gni")
group("common") {
if (is_component_build) {
@@ -156,7 +157,8 @@ source_set("internal") {
"ntdsapi.lib",
]
}
- if (is_win || is_chromeos) {
+ # Compile on Linux for fuzzer and since code is reused on Chrome OS.
+ if (is_win || is_linux) {
sources += [
"preg_parser.cc",
"preg_parser.h",
@@ -296,7 +298,7 @@ source_set("unit_tests") {
"schema_registry_unittest.cc",
"schema_unittest.cc",
]
- if (is_win || is_chromeos) {
+ if (is_win || is_linux) {
sources += [
"preg_parser_unittest.cc",
"registry_dict_unittest.cc",
@@ -327,7 +329,7 @@ source_set("unit_tests") {
if (is_mac || is_ios) {
sources += [ "mac_util_unittest.cc" ]
}
- if (is_win || is_chromeos) {
+ if (is_win || is_linux) {
# Needed by policy_loader_win_unittest.cc and preg_parser_unittest.cc
data = [
"//chrome/test/data/policy/",
@@ -347,3 +349,17 @@ source_set("unit_tests") {
"//testing/gtest",
]
}
+
+if (is_win || is_linux) {
+ fuzzer_test("preg_parser_fuzzer") {
+ sources = [
+ "preg_parser_fuzzer.cc",
+ ]
+ seed_corpus = "//chrome/test/data/policy/gpo/fuzzer_corpus"
+ dict = "//chrome/test/data/policy/gpo/fuzzer.dict"
+ deps = [
+ ":internal",
+ "//base",
+ ]
+ }
+}
diff --git a/chromium/components/policy/proto/BUILD.gn b/chromium/components/policy/proto/BUILD.gn
index 0fc12e082d0..785bd0d28d7 100644
--- a/chromium/components/policy/proto/BUILD.gn
+++ b/chromium/components/policy/proto/BUILD.gn
@@ -24,9 +24,6 @@ proto_library("proto_internal") {
if (!is_android && !is_ios) {
sources += [ "chrome_extension_policy.proto" ]
}
- if (is_chromeos) {
- sources += [ "device_management_local.proto" ]
- }
cc_generator_options = "dllexport_decl=POLICY_PROTO_EXPORT:"
cc_include = "components/policy/proto/policy_proto_export.h"
diff --git a/chromium/components/precache/content/precache_manager.cc b/chromium/components/precache/content/precache_manager.cc
index e758a4bbbcc..d9ad0ae9809 100644
--- a/chromium/components/precache/content/precache_manager.cc
+++ b/chromium/components/precache/content/precache_manager.cc
@@ -14,6 +14,8 @@
#include "base/memory/ref_counted.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
@@ -284,6 +286,8 @@ void PrecacheManager::OnGetUnfinishedWorkDone(
unfinished_work_ = std::move(unfinished_work);
bool needs_top_hosts = unfinished_work_->top_host_size() == 0;
+ base::RecordAction(base::UserMetricsAction("Precache.Fetch.Begin"));
+
if (IsInExperimentGroup()) {
BrowserThread::PostTask(
BrowserThread::DB, FROM_HERE,
diff --git a/chromium/components/precache/core/precache_database_unittest.cc b/chromium/components/precache/core/precache_database_unittest.cc
index 233c2d0ce66..4fca60e72e3 100644
--- a/chromium/components/precache/core/precache_database_unittest.cc
+++ b/chromium/components/precache/core/precache_database_unittest.cc
@@ -17,6 +17,7 @@
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_base.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "components/history/core/browser/history_constants.h"
#include "net/http/http_response_headers.h"
@@ -89,7 +90,9 @@ namespace precache {
class PrecacheDatabaseTest : public testing::Test {
public:
- PrecacheDatabaseTest() {}
+ PrecacheDatabaseTest()
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
~PrecacheDatabaseTest() override {}
protected:
@@ -147,9 +150,7 @@ class PrecacheDatabaseTest : public testing::Test {
// Must be declared first so that it is destroyed last.
base::ScopedTempDir scoped_temp_dir_;
- // Having this MessageLoop member variable causes base::MessageLoop::current()
- // to be set properly.
- base::MessageLoopForUI loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<PrecacheDatabase> precache_database_;
base::HistogramTester histograms_;
diff --git a/chromium/components/precache/core/precache_fetcher_unittest.cc b/chromium/components/precache/core/precache_fetcher_unittest.cc
index 82cb8024e07..e790f950656 100644
--- a/chromium/components/precache/core/precache_fetcher_unittest.cc
+++ b/chromium/components/precache/core/precache_fetcher_unittest.cc
@@ -26,6 +26,7 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/precache/core/precache_database.h"
#include "components/precache/core/precache_switches.h"
@@ -147,7 +148,8 @@ class MockURLFetcherFactory : public net::URLFetcherFactory {
int id,
const GURL& url,
net::URLFetcher::RequestType request_type,
- net::URLFetcherDelegate* delegate) override {
+ net::URLFetcherDelegate* delegate,
+ net::NetworkTrafficAnnotationTag traffic_annotation) override {
return base::WrapUnique(
DoCreateURLFetcher(id, url, request_type, delegate));
}
@@ -210,7 +212,9 @@ class MockURLFetcherFactory : public net::URLFetcherFactory {
class PrecacheFetcherFetcherTest : public testing::Test {
public:
PrecacheFetcherFetcherTest()
- : request_context_(new net::TestURLRequestContextGetter(
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ request_context_(new net::TestURLRequestContextGetter(
base::ThreadTaskRunnerHandle::Get())),
scoped_url_fetcher_factory_(&factory_),
callback_(base::Bind(&PrecacheFetcherFetcherTest::Callback,
@@ -219,7 +223,7 @@ class PrecacheFetcherFetcherTest : public testing::Test {
MOCK_METHOD1(Callback, void(const PrecacheFetcher::Fetcher&));
protected:
- base::MessageLoopForUI loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_;
MockURLFetcherFactory factory_;
net::ScopedURLFetcherFactory scoped_url_fetcher_factory_;
@@ -425,7 +429,9 @@ TEST_F(PrecacheFetcherFetcherTest, ResourceTooBig) {
class PrecacheFetcherTest : public testing::Test {
public:
PrecacheFetcherTest()
- : task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ task_runner_(base::ThreadTaskRunnerHandle::Get()),
request_context_(new net::TestURLRequestContextGetter(
base::ThreadTaskRunnerHandle::Get())),
factory_(NULL,
@@ -482,7 +488,7 @@ class PrecacheFetcherTest : public testing::Test {
}
// Check again after allowing the message loop to process some messages.
- loop_.task_runner()->PostTask(
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(
&PrecacheFetcherTest::CheckUntilParallelFetchesBeyondCapacity,
@@ -497,7 +503,7 @@ class PrecacheFetcherTest : public testing::Test {
void Flush() { precache_database_.Flush(); }
// Must be declared first so that it is destroyed last.
- base::MessageLoopForUI loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_;
TestURLFetcherCallback url_callback_;
@@ -1740,7 +1746,8 @@ TEST_F(PrecacheFetcherTest, GloballyRankResourcesAfterPauseResume) {
precache_fetcher.resources_to_fetch_.empty())) {
LOG(INFO) << "remaining_tries: " << remaining_tries;
base::RunLoop run_loop;
- loop_.task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
run_loop.Run();
}
@@ -1977,7 +1984,8 @@ TEST_F(PrecacheFetcherTest, CancelPrecachingAfterAllManifestFetch) {
precache_fetcher.resources_to_fetch_.empty())) {
LOG(INFO) << "remaining_tries: " << remaining_tries;
base::RunLoop run_loop;
- loop_.task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
run_loop.Run();
}
diff --git a/chromium/components/precache/core/precache_manifest_util.cc b/chromium/components/precache/core/precache_manifest_util.cc
index 668a77fecb2..ab801f65163 100644
--- a/chromium/components/precache/core/precache_manifest_util.cc
+++ b/chromium/components/precache/core/precache_manifest_util.cc
@@ -36,19 +36,26 @@ base::Optional<std::vector<bool>> GetResourceBitset(
if (it != resource_bitset_map.end()) {
if (it->second.has_bitset()) {
const std::string& bitset = it->second.bitset();
- ret.emplace(bitset.size() * 8);
- for (size_t i = 0; i < bitset.size(); ++i) {
- for (size_t j = 0; j < 8; ++j) {
- if ((1 << j) & bitset[i])
- ret.value()[i * 8 + j] = true;
+ const int bitset_size = bitset.size() * 8;
+ DCHECK_GE(bitset_size, manifest.resource_size());
+ if (bitset_size >= manifest.resource_size()) {
+ ret.emplace(bitset_size);
+ for (size_t i = 0; i < bitset.size(); ++i) {
+ for (size_t j = 0; j < 8; ++j) {
+ if ((1 << j) & bitset[i])
+ ret.value()[i * 8 + j] = true;
+ }
}
}
} else if (it->second.has_deprecated_bitset()) {
uint64_t bitset = it->second.deprecated_bitset();
- ret.emplace(64);
- for (int i = 0; i < 64; ++i) {
- if ((0x1ULL << i) & bitset)
- ret.value()[i] = true;
+ DCHECK_GE(64, manifest.resource_size());
+ if (64 >= manifest.resource_size()) {
+ ret.emplace(64);
+ for (int i = 0; i < 64; ++i) {
+ if ((0x1ULL << i) & bitset)
+ ret.value()[i] = true;
+ }
}
}
}
diff --git a/chromium/components/precache/core/proto/precache.proto b/chromium/components/precache/core/proto/precache.proto
index 2e9aec257eb..f8a10c0e729 100644
--- a/chromium/components/precache/core/proto/precache.proto
+++ b/chromium/components/precache/core/proto/precache.proto
@@ -26,6 +26,20 @@ message PrecacheResource {
// This is a non-negative number, with higher being more important. Its value
// depends on PrecacheConfigurationSettings.resource_weight_function.
optional double weight = 4;
+
+ enum Type {
+ RESOURCE_TYPE_UNKNOWN = 0;
+
+ RESOURCE_TYPE_IMAGE = 1;
+ RESOURCE_TYPE_FONT = 2;
+ RESOURCE_TYPE_STYLESHEET = 3;
+ RESOURCE_TYPE_SCRIPT = 4;
+
+ RESOURCE_TYPE_OTHER = 7;
+ }
+
+ // The type of resource.
+ optional Type type = 5;
};
message PrecacheManifestId {
diff --git a/chromium/components/prefs/BUILD.gn b/chromium/components/prefs/BUILD.gn
index e3462a4a2ba..029c712bb78 100644
--- a/chromium/components/prefs/BUILD.gn
+++ b/chromium/components/prefs/BUILD.gn
@@ -43,6 +43,7 @@ component("prefs") {
"scoped_user_pref_update.h",
"value_map_pref_store.cc",
"value_map_pref_store.h",
+ "writeable_pref_store.cc",
"writeable_pref_store.h",
]
diff --git a/chromium/components/prefs/json_pref_store.cc b/chromium/components/prefs/json_pref_store.cc
index cf4d2a352cc..240f1daf563 100644
--- a/chromium/components/prefs/json_pref_store.cc
+++ b/chromium/components/prefs/json_pref_store.cc
@@ -143,13 +143,13 @@ scoped_refptr<base::SequencedTaskRunner> JsonPrefStore::GetTaskRunnerForFile(
JsonPrefStore::JsonPrefStore(
const base::FilePath& pref_filename,
- const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
+ scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner,
std::unique_ptr<PrefFilter> pref_filter)
: path_(pref_filename),
- sequenced_task_runner_(sequenced_task_runner),
+ sequenced_task_runner_(std::move(sequenced_task_runner)),
prefs_(new base::DictionaryValue()),
read_only_(false),
- writer_(pref_filename, sequenced_task_runner),
+ writer_(pref_filename, sequenced_task_runner_),
pref_filter_(std::move(pref_filter)),
initialized_(false),
filtering_in_progress_(false),
@@ -463,7 +463,9 @@ bool JsonPrefStore::SerializeData(std::string* output) {
// readable prefs for debugging purposes, you can dump your prefs into any
// command-line or online JSON pretty printing tool.
serializer.set_pretty_print(false);
- return serializer.Serialize(*prefs_);
+ bool success = serializer.Serialize(*prefs_);
+ DCHECK(success);
+ return success;
}
void JsonPrefStore::FinalizeFileRead(
diff --git a/chromium/components/prefs/json_pref_store.h b/chromium/components/prefs/json_pref_store.h
index 6284b8d5478..b298d30e691 100644
--- a/chromium/components/prefs/json_pref_store.h
+++ b/chromium/components/prefs/json_pref_store.h
@@ -19,9 +19,11 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
+#include "base/task_scheduler/post_task.h"
#include "base/threading/non_thread_safe.h"
#include "components/prefs/base_prefs_export.h"
#include "components/prefs/persistent_pref_store.h"
+#include "components/prefs/pref_filter.h"
class PrefFilter;
@@ -62,13 +64,18 @@ class COMPONENTS_PREFS_EXPORT JsonPrefStore
const base::FilePath& pref_filename,
base::SequencedWorkerPool* worker_pool);
- // |sequenced_task_runner| must be a shutdown-blocking task runner, ideally
- // created by the GetTaskRunnerForFile() method above.
- // |pref_filename| is the path to the file to read prefs from.
- JsonPrefStore(
- const base::FilePath& pref_filename,
- const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
- std::unique_ptr<PrefFilter> pref_filter);
+ // |pref_filename| is the path to the file to read prefs from. It is incorrect
+ // to create multiple JsonPrefStore with the same |pref_filename|.
+ // |sequenced_task_runner| is used for asynchronous reads and writes. It must
+ // have the base::TaskShutdownBehavior::BLOCK_SHUTDOWN and base::MayBlock()
+ // traits. Unless external tasks need to run on the same sequence as
+ // JsonPrefStore tasks, keep the default value.
+ JsonPrefStore(const base::FilePath& pref_filename,
+ scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner =
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(),
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN}),
+ std::unique_ptr<PrefFilter> pref_filter = nullptr);
// PrefStore overrides:
bool GetValue(const std::string& key,
diff --git a/chromium/components/prefs/overlay_user_pref_store.cc b/chromium/components/prefs/overlay_user_pref_store.cc
index ddc47c8f351..48271fb01eb 100644
--- a/chromium/components/prefs/overlay_user_pref_store.cc
+++ b/chromium/components/prefs/overlay_user_pref_store.cc
@@ -44,22 +44,17 @@ bool OverlayUserPrefStore::GetValue(const std::string& key,
if (overlay_.GetValue(key, result))
return true;
- return underlay_->GetValue(GetUnderlayKey(key), result);
+ return underlay_->GetValue(key, result);
}
std::unique_ptr<base::DictionaryValue> OverlayUserPrefStore::GetValues() const {
auto values = underlay_->GetValues();
auto overlay_values = overlay_.AsDictionaryValue();
- for (const auto& overlay_mapping : overlay_to_underlay_names_map_) {
- const std::string& overlay_key = overlay_mapping.first;
- const std::string& underlay_key = overlay_mapping.second;
+ for (const auto& key : overlay_names_set_) {
std::unique_ptr<base::Value> out_value;
- if (overlay_key != underlay_key) {
- values->Remove(underlay_key, &out_value);
- }
- overlay_values->Remove(overlay_key, &out_value);
+ overlay_values->Remove(key, &out_value);
if (out_value) {
- values->Set(overlay_key, std::move(out_value));
+ values->Set(key, std::move(out_value));
}
}
return values;
@@ -68,14 +63,14 @@ std::unique_ptr<base::DictionaryValue> OverlayUserPrefStore::GetValues() const {
bool OverlayUserPrefStore::GetMutableValue(const std::string& key,
base::Value** result) {
if (!ShallBeStoredInOverlay(key))
- return underlay_->GetMutableValue(GetUnderlayKey(key), result);
+ return underlay_->GetMutableValue(key, result);
if (overlay_.GetValue(key, result))
return true;
// Try to create copy of underlay if the overlay does not contain a value.
base::Value* underlay_value = NULL;
- if (!underlay_->GetMutableValue(GetUnderlayKey(key), &underlay_value))
+ if (!underlay_->GetMutableValue(key, &underlay_value))
return false;
*result = underlay_value->DeepCopy();
@@ -87,7 +82,7 @@ void OverlayUserPrefStore::SetValue(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
if (!ShallBeStoredInOverlay(key)) {
- underlay_->SetValue(GetUnderlayKey(key), std::move(value), flags);
+ underlay_->SetValue(key, std::move(value), flags);
return;
}
@@ -99,7 +94,7 @@ void OverlayUserPrefStore::SetValueSilently(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
if (!ShallBeStoredInOverlay(key)) {
- underlay_->SetValueSilently(GetUnderlayKey(key), std::move(value), flags);
+ underlay_->SetValueSilently(key, std::move(value), flags);
return;
}
@@ -108,7 +103,7 @@ void OverlayUserPrefStore::SetValueSilently(const std::string& key,
void OverlayUserPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
if (!ShallBeStoredInOverlay(key)) {
- underlay_->RemoveValue(GetUnderlayKey(key), flags);
+ underlay_->RemoveValue(key, flags);
return;
}
@@ -153,8 +148,8 @@ void OverlayUserPrefStore::ReportValueChanged(const std::string& key,
}
void OverlayUserPrefStore::OnPrefValueChanged(const std::string& key) {
- if (!overlay_.GetValue(GetOverlayKey(key), NULL))
- ReportValueChanged(GetOverlayKey(key), DEFAULT_PREF_WRITE_FLAGS);
+ if (!overlay_.GetValue(key, NULL))
+ ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
}
void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) {
@@ -163,22 +158,10 @@ void OverlayUserPrefStore::OnInitializationCompleted(bool succeeded) {
}
void OverlayUserPrefStore::RegisterOverlayPref(const std::string& key) {
- RegisterOverlayPref(key, key);
-}
-
-void OverlayUserPrefStore::RegisterOverlayPref(
- const std::string& overlay_key,
- const std::string& underlay_key) {
- DCHECK(!overlay_key.empty()) << "Overlay key is empty";
- DCHECK(overlay_to_underlay_names_map_.find(overlay_key) ==
- overlay_to_underlay_names_map_.end()) <<
- "Overlay key already registered";
- DCHECK(!underlay_key.empty()) << "Underlay key is empty";
- DCHECK(underlay_to_overlay_names_map_.find(underlay_key) ==
- underlay_to_overlay_names_map_.end()) <<
- "Underlay key already registered";
- overlay_to_underlay_names_map_[overlay_key] = underlay_key;
- underlay_to_overlay_names_map_[underlay_key] = overlay_key;
+ DCHECK(!key.empty()) << "Key is empty";
+ DCHECK(overlay_names_set_.find(key) == overlay_names_set_.end())
+ << "Key already registered";
+ overlay_names_set_.insert(key);
}
void OverlayUserPrefStore::ClearMutableValues() {
@@ -189,22 +172,7 @@ OverlayUserPrefStore::~OverlayUserPrefStore() {
underlay_->RemoveObserver(this);
}
-const std::string& OverlayUserPrefStore::GetOverlayKey(
- const std::string& underlay_key) const {
- NamesMap::const_iterator i =
- underlay_to_overlay_names_map_.find(underlay_key);
- return i != underlay_to_overlay_names_map_.end() ? i->second : underlay_key;
-}
-
-const std::string& OverlayUserPrefStore::GetUnderlayKey(
- const std::string& overlay_key) const {
- NamesMap::const_iterator i =
- overlay_to_underlay_names_map_.find(overlay_key);
- return i != overlay_to_underlay_names_map_.end() ? i->second : overlay_key;
-}
-
bool OverlayUserPrefStore::ShallBeStoredInOverlay(
const std::string& key) const {
- return overlay_to_underlay_names_map_.find(key) !=
- overlay_to_underlay_names_map_.end();
+ return overlay_names_set_.find(key) != overlay_names_set_.end();
}
diff --git a/chromium/components/prefs/overlay_user_pref_store.h b/chromium/components/prefs/overlay_user_pref_store.h
index 7d9eb3071a5..7766dcdbaed 100644
--- a/chromium/components/prefs/overlay_user_pref_store.h
+++ b/chromium/components/prefs/overlay_user_pref_store.h
@@ -62,8 +62,6 @@ class COMPONENTS_PREFS_EXPORT OverlayUserPrefStore : public PersistentPrefStore,
void OnInitializationCompleted(bool succeeded) override;
void RegisterOverlayPref(const std::string& key);
- void RegisterOverlayPref(const std::string& overlay_key,
- const std::string& underlay_key);
void ClearMutableValues() override;
@@ -71,10 +69,7 @@ class COMPONENTS_PREFS_EXPORT OverlayUserPrefStore : public PersistentPrefStore,
~OverlayUserPrefStore() override;
private:
- typedef std::map<std::string, std::string> NamesMap;
-
- const std::string& GetOverlayKey(const std::string& underlay_key) const;
- const std::string& GetUnderlayKey(const std::string& overlay_key) const;
+ typedef std::set<std::string> NamesSet;
// Returns true if |key| corresponds to a preference that shall be stored in
// an in-memory PrefStore that is not persisted to disk.
@@ -83,8 +78,7 @@ class COMPONENTS_PREFS_EXPORT OverlayUserPrefStore : public PersistentPrefStore,
base::ObserverList<PrefStore::Observer, true> observers_;
PrefValueMap overlay_;
scoped_refptr<PersistentPrefStore> underlay_;
- NamesMap overlay_to_underlay_names_map_;
- NamesMap underlay_to_overlay_names_map_;
+ NamesSet overlay_names_set_;
DISALLOW_COPY_AND_ASSIGN(OverlayUserPrefStore);
};
diff --git a/chromium/components/prefs/overlay_user_pref_store_unittest.cc b/chromium/components/prefs/overlay_user_pref_store_unittest.cc
index 5dded13ca04..e32bf1e35ae 100644
--- a/chromium/components/prefs/overlay_user_pref_store_unittest.cc
+++ b/chromium/components/prefs/overlay_user_pref_store_unittest.cc
@@ -24,10 +24,6 @@ const char kSharedKey[] = "sync_promo.show_on_first_run_allowed";
const char* const overlay_key = kBrowserWindowPlacement;
const char* const regular_key = kShowBookmarkBar;
const char* const shared_key = kSharedKey;
-// With the removal of the kWebKitGlobalXXX prefs, we'll no longer have real
-// prefs using the overlay pref store, so make up keys here.
-const char mapped_overlay_key[] = "test.per_tab.javascript_enabled";
-const char mapped_underlay_key[] = "test.per_profile.javascript_enabled";
} // namespace
@@ -38,7 +34,6 @@ class OverlayUserPrefStoreTest : public testing::Test {
overlay_(new OverlayUserPrefStore(underlay_.get())) {
overlay_->RegisterOverlayPref(overlay_key);
overlay_->RegisterOverlayPref(shared_key);
- overlay_->RegisterOverlayPref(mapped_overlay_key, mapped_underlay_key);
}
~OverlayUserPrefStoreTest() override {}
@@ -211,80 +206,6 @@ TEST_F(OverlayUserPrefStoreTest, GlobalPref) {
EXPECT_TRUE(obs.changed_keys.empty());
}
-// Check that names mapping works correctly.
-TEST_F(OverlayUserPrefStoreTest, NamesMapping) {
- PrefStoreObserverMock obs;
- overlay_->AddObserver(&obs);
-
- const Value* value = NULL;
-
- // Check that if there is no override in the overlay, changing underlay value
- // is reported as changing an overlay value.
- underlay_->SetValue(mapped_underlay_key, base::WrapUnique(new Value(42)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- obs.VerifyAndResetChangedKey(mapped_overlay_key);
-
- // Check that underlay overwriting is reported.
- underlay_->SetValue(mapped_underlay_key, base::WrapUnique(new Value(43)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- obs.VerifyAndResetChangedKey(mapped_overlay_key);
-
- // Check that we get this value from the overlay with both keys
- EXPECT_TRUE(overlay_->GetValue(mapped_overlay_key, &value));
- EXPECT_TRUE(base::Value(43).Equals(value));
- // In this case, overlay reads directly from the underlay.
- EXPECT_TRUE(overlay_->GetValue(mapped_underlay_key, &value));
- EXPECT_TRUE(base::Value(43).Equals(value));
-
- // Check that overwriting change in overlay is reported.
- overlay_->SetValue(mapped_overlay_key, base::WrapUnique(new Value(44)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- obs.VerifyAndResetChangedKey(mapped_overlay_key);
-
- // Check that we get an overriden value from overlay, while reading the
- // value from underlay still holds an old value.
- EXPECT_TRUE(overlay_->GetValue(mapped_overlay_key, &value));
- EXPECT_TRUE(base::Value(44).Equals(value));
- EXPECT_TRUE(overlay_->GetValue(mapped_underlay_key, &value));
- EXPECT_TRUE(base::Value(43).Equals(value));
- EXPECT_TRUE(underlay_->GetValue(mapped_underlay_key, &value));
- EXPECT_TRUE(base::Value(43).Equals(value));
-
- // Check that hidden underlay change is not reported.
- underlay_->SetValue(mapped_underlay_key, base::WrapUnique(new Value(45)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- EXPECT_TRUE(obs.changed_keys.empty());
-
- // Check that overlay remove is reported.
- overlay_->RemoveValue(mapped_overlay_key,
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- obs.VerifyAndResetChangedKey(mapped_overlay_key);
-
- // Check that underlay remove is reported.
- underlay_->RemoveValue(mapped_underlay_key,
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- obs.VerifyAndResetChangedKey(mapped_overlay_key);
-
- // Check that value was removed.
- EXPECT_FALSE(overlay_->GetValue(mapped_overlay_key, &value));
- EXPECT_FALSE(overlay_->GetValue(mapped_underlay_key, &value));
-
- // Check respecting of silence.
- overlay_->SetValueSilently(mapped_overlay_key,
- base::WrapUnique(new Value(46)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- EXPECT_TRUE(obs.changed_keys.empty());
-
- overlay_->RemoveObserver(&obs);
-
- // Check successful unsubscription.
- underlay_->SetValue(mapped_underlay_key, base::WrapUnique(new Value(47)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- overlay_->SetValue(mapped_overlay_key, base::WrapUnique(new Value(48)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- EXPECT_TRUE(obs.changed_keys.empty());
-}
-
// Check that mutable values are removed correctly.
TEST_F(OverlayUserPrefStoreTest, ClearMutableValues) {
// Set in overlay and underlay the same preference.
@@ -315,10 +236,6 @@ TEST_F(OverlayUserPrefStoreTest, GetValues) {
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
overlay_->SetValue(shared_key, base::WrapUnique(new Value(43)),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- underlay_->SetValue(mapped_underlay_key, base::WrapUnique(new Value(42)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
- overlay_->SetValue(mapped_overlay_key, base::WrapUnique(new Value(43)),
- WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
auto values = overlay_->GetValues();
const Value* value = nullptr;
@@ -333,11 +250,6 @@ TEST_F(OverlayUserPrefStoreTest, GetValues) {
// Check that the overlay is preferred.
ASSERT_TRUE(values->Get(shared_key, &value));
EXPECT_TRUE(base::Value(43).Equals(value));
-
- // Check that mapping works.
- ASSERT_TRUE(values->Get(mapped_overlay_key, &value));
- EXPECT_TRUE(base::Value(43).Equals(value));
- EXPECT_FALSE(values->Get(mapped_underlay_key, &value));
}
} // namespace base
diff --git a/chromium/components/prefs/pref_service.cc b/chromium/components/prefs/pref_service.cc
index 6858839110b..dccebf458a2 100644
--- a/chromium/components/prefs/pref_service.cc
+++ b/chromium/components/prefs/pref_service.cc
@@ -193,37 +193,27 @@ bool PrefService::HasPrefPath(const std::string& path) const {
return pref && !pref->IsDefaultValue();
}
-std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues()
- const {
+void PrefService::IteratePreferenceValues(
+ base::RepeatingCallback<void(const std::string& key,
+ const base::Value& value)> callback) const {
DCHECK(CalledOnValidThread());
- std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
- for (const auto& it : *pref_registry_) {
- out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
- }
- return out;
+ for (const auto& it : *pref_registry_)
+ callback.Run(it.first, *GetPreferenceValue(it.first));
}
-std::unique_ptr<base::DictionaryValue>
-PrefService::GetPreferenceValuesOmitDefaults() const {
+std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues(
+ IncludeDefaults include_defaults) const {
DCHECK(CalledOnValidThread());
std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
for (const auto& it : *pref_registry_) {
- const Preference* pref = FindPreference(it.first);
- if (pref->IsDefaultValue())
- continue;
- out->Set(it.first, pref->GetValue()->CreateDeepCopy());
- }
- return out;
-}
-
-std::unique_ptr<base::DictionaryValue>
-PrefService::GetPreferenceValuesWithoutPathExpansion() const {
- DCHECK(CalledOnValidThread());
- std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
- for (const auto& it : *pref_registry_) {
- const base::Value* value = GetPreferenceValue(it.first);
- DCHECK(value);
- out->SetWithoutPathExpansion(it.first, value->CreateDeepCopy());
+ if (include_defaults == INCLUDE_DEFAULTS) {
+ out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
+ } else {
+ const Preference* pref = FindPreference(it.first);
+ if (pref->IsDefaultValue())
+ continue;
+ out->Set(it.first, pref->GetValue()->CreateDeepCopy());
+ }
}
return out;
}
@@ -492,6 +482,14 @@ void PrefService::ReportUserPrefChanged(const std::string& key) {
user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
}
+void PrefService::ReportUserPrefChanged(
+ const std::string& key,
+ std::set<std::vector<std::string>> path_components) {
+ DCHECK(CalledOnValidThread());
+ user_pref_store_->ReportSubValuesChanged(key, std::move(path_components),
+ GetWriteFlags(FindPreference(key)));
+}
+
void PrefService::SetUserPrefValue(const std::string& path,
std::unique_ptr<base::Value> new_value) {
DCHECK(CalledOnValidThread());
diff --git a/chromium/components/prefs/pref_service.h b/chromium/components/prefs/pref_service.h
index e08e361c40b..a360afa44ac 100644
--- a/chromium/components/prefs/pref_service.h
+++ b/chromium/components/prefs/pref_service.h
@@ -39,6 +39,10 @@ namespace base {
class FilePath;
}
+namespace prefs {
+class ScopedDictionaryPrefUpdate;
+}
+
namespace subtle {
class PrefMemberBase;
class ScopedUserPrefUpdateBase;
@@ -60,6 +64,11 @@ class COMPONENTS_PREFS_EXPORT PrefService : public base::NonThreadSafe {
INITIALIZATION_STATUS_ERROR
};
+ enum IncludeDefaults {
+ INCLUDE_DEFAULTS,
+ EXCLUDE_DEFAULTS,
+ };
+
// A helper class to store all the information associated with a preference.
class COMPONENTS_PREFS_EXPORT Preference {
public:
@@ -250,23 +259,22 @@ class COMPONENTS_PREFS_EXPORT PrefService : public base::NonThreadSafe {
// this checks if a value exists for the path.
bool HasPrefPath(const std::string& path) const;
- // Returns a dictionary with effective preference values.
- std::unique_ptr<base::DictionaryValue> GetPreferenceValues() const;
-
- // Returns a dictionary with effective preference values, omitting prefs that
- // are at their default values.
- std::unique_ptr<base::DictionaryValue> GetPreferenceValuesOmitDefaults()
- const;
+ // Issues a callback for every preference value. The preferences must not be
+ // mutated during iteration.
+ void IteratePreferenceValues(
+ base::RepeatingCallback<void(const std::string& key,
+ const base::Value& value)> callback) const;
- // Returns a dictionary with effective preference values. Contrary to
- // GetPreferenceValues(), the paths of registered preferences are not split on
- // '.' characters. If a registered preference stores a dictionary, however,
- // the hierarchical structure inside the preference will be preserved.
- // For example, if "foo.bar" is a registered preference, the result could look
- // like this:
- // {"foo.bar": {"a": {"b": true}}}.
- std::unique_ptr<base::DictionaryValue>
- GetPreferenceValuesWithoutPathExpansion() const;
+ // Returns a dictionary with effective preference values. This is an expensive
+ // operation which does a deep copy. Use only if you really need the results
+ // in a base::Value (for example, for JSON serialization). Otherwise use
+ // IteratePreferenceValues above to avoid the copies.
+ //
+ // If INCLUDE_DEFAULTS is requested, preferences set to their default values
+ // will be included. Otherwise, these will be omitted from the returned
+ // dictionary.
+ std::unique_ptr<base::DictionaryValue> GetPreferenceValues(
+ IncludeDefaults include_defaults) const;
bool ReadOnly() const;
@@ -327,6 +335,7 @@ class COMPONENTS_PREFS_EXPORT PrefService : public base::NonThreadSafe {
// Give access to ReportUserPrefChanged() and GetMutableUserPref().
friend class subtle::ScopedUserPrefUpdateBase;
friend class PrefServiceTest_WriteablePrefStoreFlags_Test;
+ friend class prefs::ScopedDictionaryPrefUpdate;
// Registration of pref change observers must be done using the
// PrefChangeRegistrar, which is declared as a friend here to grant it
@@ -350,8 +359,12 @@ class COMPONENTS_PREFS_EXPORT PrefService : public base::NonThreadSafe {
virtual void RemovePrefObserver(const std::string& path, PrefObserver* obs);
// Sends notification of a changed preference. This needs to be called by
- // a ScopedUserPrefUpdate if a DictionaryValue or ListValue is changed.
+ // a ScopedUserPrefUpdate or ScopedDictionaryPrefUpdate if a DictionaryValue
+ // or ListValue is changed.
void ReportUserPrefChanged(const std::string& key);
+ void ReportUserPrefChanged(
+ const std::string& key,
+ std::set<std::vector<std::string>> path_components);
// Sets the value for this pref path in the user pref store and informs the
// PrefNotifier of the change.
diff --git a/chromium/components/prefs/testing_pref_store.cc b/chromium/components/prefs/testing_pref_store.cc
index e9b04c8e54f..efdc83fcc77 100644
--- a/chromium/components/prefs/testing_pref_store.cc
+++ b/chromium/components/prefs/testing_pref_store.cc
@@ -7,8 +7,10 @@
#include <memory>
#include <utility>
+#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"
+#include "testing/gtest/include/gtest/gtest.h"
TestingPrefStore::TestingPrefStore()
: read_only_(true),
@@ -61,6 +63,8 @@ void TestingPrefStore::SetValue(const std::string& key,
void TestingPrefStore::SetValueSilently(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
+ if (value)
+ CheckPrefIsSerializable(key, *value);
if (prefs_.SetValue(key, std::move(value)))
committed_ = false;
}
@@ -118,6 +122,10 @@ void TestingPrefStore::NotifyInitializationCompleted() {
void TestingPrefStore::ReportValueChanged(const std::string& key,
uint32_t flags) {
+ const base::Value* value = nullptr;
+ if (prefs_.GetValue(key, &value))
+ CheckPrefIsSerializable(key, *value);
+
for (Observer& observer : observers_)
observer.OnPrefValueChanged(key);
}
@@ -186,4 +194,15 @@ void TestingPrefStore::set_read_error(
read_error_ = read_error;
}
-TestingPrefStore::~TestingPrefStore() {}
+TestingPrefStore::~TestingPrefStore() {
+ for (auto& pref : prefs_) {
+ CheckPrefIsSerializable(pref.first, *pref.second);
+ }
+}
+
+void TestingPrefStore::CheckPrefIsSerializable(const std::string& key,
+ const base::Value& value) {
+ std::string json;
+ EXPECT_TRUE(base::JSONWriter::Write(value, &json))
+ << "Pref \"" << key << "\" is not serializable as JSON.";
+}
diff --git a/chromium/components/prefs/testing_pref_store.h b/chromium/components/prefs/testing_pref_store.h
index 2e685e4fde6..4e0afa46a0c 100644
--- a/chromium/components/prefs/testing_pref_store.h
+++ b/chromium/components/prefs/testing_pref_store.h
@@ -83,6 +83,9 @@ class TestingPrefStore : public PersistentPrefStore {
~TestingPrefStore() override;
private:
+ void CheckPrefIsSerializable(const std::string& key,
+ const base::Value& value);
+
// Stores the preference values.
PrefValueMap prefs_;
diff --git a/chromium/components/prefs/writeable_pref_store.cc b/chromium/components/prefs/writeable_pref_store.cc
new file mode 100644
index 00000000000..d51985e8238
--- /dev/null
+++ b/chromium/components/prefs/writeable_pref_store.cc
@@ -0,0 +1,14 @@
+// Copyright 2017 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/prefs/writeable_pref_store.h"
+
+void WriteablePrefStore::ReportSubValuesChanged(
+ const std::string& key,
+ std::set<std::vector<std::string>> path_components,
+ uint32_t flags) {
+ // Default implementation. Subclasses may use |path_components| to improve
+ // performance.
+ ReportValueChanged(key, flags);
+}
diff --git a/chromium/components/prefs/writeable_pref_store.h b/chromium/components/prefs/writeable_pref_store.h
index 6cfbcee32d8..9a69c7cbe47 100644
--- a/chromium/components/prefs/writeable_pref_store.h
+++ b/chromium/components/prefs/writeable_pref_store.h
@@ -8,7 +8,9 @@
#include <stdint.h>
#include <memory>
+#include <set>
#include <string>
+#include <vector>
#include "base/macros.h"
#include "components/prefs/pref_store.h"
@@ -46,13 +48,25 @@ class COMPONENTS_PREFS_EXPORT WriteablePrefStore : public PrefStore {
virtual bool GetMutableValue(const std::string& key,
base::Value** result) = 0;
- // Triggers a value changed notification. This function needs to be called
- // if one retrieves a list or dictionary with GetMutableValue and change its
- // value. SetValue takes care of notifications itself. Note that
- // ReportValueChanged will trigger notifications even if nothing has changed.
- // |flags| is a bitmask of PrefWriteFlags.
+ // Triggers a value changed notification. This function or
+ // ReportSubValuesChanged needs to be called if one retrieves a list or
+ // dictionary with GetMutableValue and change its value. SetValue takes care
+ // of notifications itself. Note that ReportValueChanged will trigger
+ // notifications even if nothing has changed. |flags| is a bitmask of
+ // PrefWriteFlags.
virtual void ReportValueChanged(const std::string& key, uint32_t flags) = 0;
+ // Triggers a value changed notification for |path_components| in the |key|
+ // pref. This function or ReportValueChanged needs to be called if one
+ // retrieves a list or dictionary with GetMutableValue and change its value.
+ // SetValue takes care of notifications itself. Note that
+ // ReportSubValuesChanged will trigger notifications even if nothing has
+ // changed. |flags| is a bitmask of PrefWriteFlags.
+ virtual void ReportSubValuesChanged(
+ const std::string& key,
+ std::set<std::vector<std::string>> path_components,
+ uint32_t flags);
+
// Same as SetValue, but doesn't generate notifications. This is used by
// PrefService::GetMutableUserPref() in order to put empty entries
// into the user pref store. Using SetValue is not an option since existing
diff --git a/chromium/components/previews/core/BUILD.gn b/chromium/components/previews/core/BUILD.gn
index e2f014cac8f..61052354174 100644
--- a/chromium/components/previews/core/BUILD.gn
+++ b/chromium/components/previews/core/BUILD.gn
@@ -11,6 +11,8 @@ static_library("core") {
"previews_decider.h",
"previews_experiments.cc",
"previews_experiments.h",
+ "previews_features.cc",
+ "previews_features.h",
"previews_io_data.cc",
"previews_io_data.h",
"previews_opt_out_store.h",
diff --git a/chromium/components/previews/core/previews_black_list.cc b/chromium/components/previews/core/previews_black_list.cc
index ea5de7d822f..c4f0570d188 100644
--- a/chromium/components/previews/core/previews_black_list.cc
+++ b/chromium/components/previews/core/previews_black_list.cc
@@ -6,8 +6,9 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram.h"
#include "base/optional.h"
+#include "base/strings/stringprintf.h"
#include "base/time/clock.h"
#include "components/previews/core/previews_black_list_item.h"
#include "components/previews/core/previews_experiments.h"
@@ -74,13 +75,12 @@ void PreviewsBlackList::AddPreviewNavigation(const GURL& url,
PreviewsType type) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(url.has_host());
- switch (type) {
- case PreviewsType::OFFLINE:
- UMA_HISTOGRAM_BOOLEAN("Previews.OptOut.UserOptedOut.Offline", opt_out);
- break;
- default:
- NOTREACHED();
- }
+
+ base::BooleanHistogram::FactoryGet(
+ base::StringPrintf("Previews.OptOut.UserOptedOut.%s",
+ GetStringNameForType(type).c_str()),
+ base::HistogramBase::kUmaTargetedHistogramFlag)
+ ->Add(opt_out);
if (opt_out) {
last_opt_out_time_ = clock_->Now();
}
@@ -158,6 +158,14 @@ void PreviewsBlackList::ClearBlackListSync(base::Time begin_time,
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(loaded_);
DCHECK_LE(begin_time, end_time);
+
+ // Clear last_opt_out_time_ if the period being cleared is larger than the
+ // short black list timeout and the last time the user opted out was before
+ // |end_time|.
+ if (end_time - begin_time > params::SingleOptOutDuration() &&
+ last_opt_out_time_ && last_opt_out_time_.value() < end_time) {
+ last_opt_out_time_.reset();
+ }
black_list_item_map_.reset();
host_indifferent_black_list_item_.reset();
loaded_ = false;
diff --git a/chromium/components/previews/core/previews_black_list.h b/chromium/components/previews/core/previews_black_list.h
index 6abac75b2e7..f45aa7770d0 100644
--- a/chromium/components/previews/core/previews_black_list.h
+++ b/chromium/components/previews/core/previews_black_list.h
@@ -49,8 +49,8 @@ enum class PreviewsEligibilityReason {
NETWORK_QUALITY_UNAVAILABLE = 6,
// The network was fast enough to not warrant previews.
NETWORK_NOT_SLOW = 7,
- // If the page was reloaded, the user should not be shown an offline preview.
- RELOAD_DISALLOWED_FOR_OFFLINE = 8,
+ // If the page was reloaded, the user should not be shown a stale preview.
+ RELOAD_DISALLOWED = 8,
LAST = 9,
};
diff --git a/chromium/components/previews/core/previews_black_list_unittest.cc b/chromium/components/previews/core/previews_black_list_unittest.cc
index 2c8a1fc3b80..6c809c24191 100644
--- a/chromium/components/previews/core/previews_black_list_unittest.cc
+++ b/chromium/components/previews/core/previews_black_list_unittest.cc
@@ -4,6 +4,7 @@
#include "components/previews/core/previews_black_list.h"
+#include <map>
#include <memory>
#include <string>
@@ -25,12 +26,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
-namespace {
-
-using PreviewsBlackListTest = testing::Test;
-
-} // namespace
-
namespace previews {
namespace {
@@ -75,292 +70,328 @@ class TestPreviewsOptOutStore : public PreviewsOptOutStore {
int clear_blacklist_count_;
};
-} // namespace
+class PreviewsBlackListTest : public testing::Test {
+ public:
+ PreviewsBlackListTest() : field_trial_list_(nullptr) {}
+ ~PreviewsBlackListTest() override {}
+
+ void TearDown() override { variations::testing::ClearAllVariationParams(); }
+
+ void StartTest(bool null_opt_out) {
+ if (params_.size() > 0) {
+ ASSERT_TRUE(variations::AssociateVariationParams("ClientSidePreviews",
+ "Enabled", params_));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("ClientSidePreviews",
+ "Enabled"));
+ params_.clear();
+ }
+ std::unique_ptr<base::SimpleTestClock> test_clock =
+ base::MakeUnique<base::SimpleTestClock>();
+ test_clock_ = test_clock.get();
+ std::unique_ptr<TestPreviewsOptOutStore> opt_out_store =
+ null_opt_out ? nullptr : base::MakeUnique<TestPreviewsOptOutStore>();
+ opt_out_store_ = opt_out_store.get();
+ black_list_ = base::MakeUnique<PreviewsBlackList>(std::move(opt_out_store),
+ std::move(test_clock));
+ start_ = test_clock_->Now();
+ }
+
+ void SetHostHistoryParam(size_t host_history) {
+ params_["per_host_max_stored_history_length"] =
+ base::SizeTToString(host_history);
+ }
+
+ void SetHostIndifferentHistoryParam(size_t host_indifferent_history) {
+ params_["host_indifferent_max_stored_history_length"] =
+ base::SizeTToString(host_indifferent_history);
+ }
+
+ void SetHostThresholdParam(int per_host_threshold) {
+ params_["per_host_opt_out_threshold"] =
+ base::IntToString(per_host_threshold);
+ }
+
+ void SetHostIndifferentThresholdParam(int host_indifferent_threshold) {
+ params_["host_indifferent_opt_out_threshold"] =
+ base::IntToString(host_indifferent_threshold);
+ }
+
+ void SetHostDurationParam(int duration_in_days) {
+ params_["per_host_black_list_duration_in_days"] =
+ base::IntToString(duration_in_days);
+ }
+
+ void SetSingleOptOutDurationParam(int single_opt_out_duration) {
+ params_["single_opt_out_duration_in_seconds"] =
+ base::IntToString(single_opt_out_duration);
+ }
+
+ void SetMaxHostInBlackListParam(size_t max_hosts_in_blacklist) {
+ params_["max_hosts_in_blacklist"] =
+ base::IntToString(max_hosts_in_blacklist);
+ }
+
+ // Adds an opt out and either clears the black list for a time either longer
+ // or shorter than the single opt out duration parameter depending on
+ // |short_time|.
+ void RunClearingBlackListTest(const GURL& url, bool short_time) {
+ const size_t host_indifferent_history = 1;
+ const int single_opt_out_duration = 5;
+ SetHostDurationParam(365);
+ SetHostIndifferentHistoryParam(host_indifferent_history);
+ SetHostIndifferentThresholdParam(host_indifferent_history + 1);
+ SetSingleOptOutDurationParam(single_opt_out_duration);
+
+ StartTest(false /* null_opt_out */);
+ if (!short_time)
+ test_clock_->Advance(
+ base::TimeDelta::FromSeconds(single_opt_out_duration));
+
+ black_list_->AddPreviewNavigation(url, true /* opt_out */,
+ PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->ClearBlackList(start_, test_clock_->Now());
+ base::RunLoop().RunUntilIdle();
+ }
+
+ protected:
+ base::MessageLoop loop_;
+
+ // Unowned raw pointers tied to the lifetime of |black_list_|.
+ base::SimpleTestClock* test_clock_;
+ TestPreviewsOptOutStore* opt_out_store_;
+ base::Time start_;
+ std::map<std::string, std::string> params_;
+ base::FieldTrialList field_trial_list_;
+
+ std::unique_ptr<PreviewsBlackList> black_list_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PreviewsBlackListTest);
+};
TEST_F(PreviewsBlackListTest, PerHostBlackListNoStore) {
- // Tests the black list behavior when a null OptOutSture is passed in.
+ // Tests the black list behavior when a null OptOutStore is passed in.
const GURL url_a("http://www.url_a.com");
const GURL url_b("http://www.url_b.com");
- const size_t per_host_history = 4;
- const int per_host_threshold = 2;
+
// Host indifferent blacklisting should have no effect with the following
// params.
const size_t host_indifferent_history = 1;
- const int host_indifferent_threshold = host_indifferent_history + 1;
- const int duration_in_days = 365;
+ SetHostHistoryParam(4);
+ SetHostIndifferentHistoryParam(host_indifferent_history);
+ SetHostThresholdParam(2);
+ SetHostIndifferentThresholdParam(host_indifferent_history + 1);
+ SetHostDurationParam(365);
// Disable single opt out by setting duration to 0.
- const int single_opt_out_duration = 0;
- base::FieldTrialList field_trial_list(nullptr);
- std::map<std::string, std::string> params;
- params["per_host_max_stored_history_length"] =
- base::SizeTToString(per_host_history);
- params["host_indifferent_max_stored_history_length"] =
- base::SizeTToString(host_indifferent_history);
- params["per_host_opt_out_threshold"] = base::IntToString(per_host_threshold);
- params["host_indifferent_opt_out_threshold"] =
- base::IntToString(host_indifferent_threshold);
- params["per_host_black_list_duration_in_days"] =
- base::IntToString(duration_in_days);
- params["single_opt_out_duration_in_seconds"] =
- base::IntToString(single_opt_out_duration);
- ASSERT_TRUE(
- variations::AssociateVariationParams("ClientSidePreviews", "Enabled",
- params) &&
- base::FieldTrialList::CreateFieldTrial("ClientSidePreviews", "Enabled"));
-
- base::SimpleTestClock* test_clock = new base::SimpleTestClock();
- base::Time start = test_clock->Now();
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
-
- std::unique_ptr<PreviewsBlackList> black_list(
- new PreviewsBlackList(nullptr, base::WrapUnique(test_clock)));
+ SetSingleOptOutDurationParam(0);
+
+ StartTest(true /* null_opt_out */);
+
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- black_list->ClearBlackList(start, test_clock->Now());
+ black_list_->ClearBlackList(start_, test_clock_->Now());
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
-
- variations::testing::ClearAllVariationParams();
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
}
TEST_F(PreviewsBlackListTest, PerHostBlackListWithStore) {
- // Tests the black list behavior when a non-null OptOutSture is passed in.
+ // Tests the black list behavior when a non-null OptOutStore is passed in.
const GURL url_a1("http://www.url_a.com/a1");
const GURL url_a2("http://www.url_a.com/a2");
const GURL url_b("http://www.url_b.com");
- const size_t per_host_history = 4;
- const int per_host_threshold = 2;
+
// Host indifferent blacklisting should have no effect with the following
// params.
const size_t host_indifferent_history = 1;
- const int host_indifferent_threshold = host_indifferent_history + 1;
- const int duration_in_days = 365;
+ SetHostHistoryParam(4);
+ SetHostIndifferentHistoryParam(host_indifferent_history);
+ SetHostThresholdParam(2);
+ SetHostIndifferentThresholdParam(host_indifferent_history + 1);
+ SetHostDurationParam(365);
// Disable single opt out by setting duration to 0.
- const int single_opt_out_duration = 0;
- base::FieldTrialList field_trial_list(nullptr);
- std::map<std::string, std::string> params;
- params["per_host_max_stored_history_length"] =
- base::SizeTToString(per_host_history);
- params["host_indifferent_max_stored_history_length"] =
- base::SizeTToString(host_indifferent_history);
- params["per_host_opt_out_threshold"] = base::IntToString(per_host_threshold);
- params["host_indifferent_opt_out_threshold"] =
- base::IntToString(host_indifferent_threshold);
- params["per_host_black_list_duration_in_days"] =
- base::IntToString(duration_in_days);
- params["single_opt_out_duration_in_seconds"] =
- base::IntToString(single_opt_out_duration);
- ASSERT_TRUE(
- variations::AssociateVariationParams("ClientSidePreviews", "Enabled",
- params) &&
- base::FieldTrialList::CreateFieldTrial("ClientSidePreviews", "Enabled"));
-
- base::MessageLoop loop;
-
- base::SimpleTestClock* test_clock = new base::SimpleTestClock();
- base::Time start = test_clock->Now();
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
-
- TestPreviewsOptOutStore* opt_out_store = new TestPreviewsOptOutStore();
-
- std::unique_ptr<PreviewsBlackList> black_list(new PreviewsBlackList(
- base::WrapUnique(opt_out_store), base::WrapUnique(test_clock)));
+ SetSingleOptOutDurationParam(0);
+
+ StartTest(false /* null_opt_out */);
+
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url_a1, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_a1, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_a1, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_a1, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
- EXPECT_EQ(0, opt_out_store->clear_blacklist_count());
- black_list->ClearBlackList(start, base::Time::Now());
- EXPECT_EQ(1, opt_out_store->clear_blacklist_count());
+ EXPECT_EQ(0, opt_out_store_->clear_blacklist_count());
+ black_list_->ClearBlackList(start_, base::Time::Now());
+ EXPECT_EQ(1, opt_out_store_->clear_blacklist_count());
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a2, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, opt_out_store->clear_blacklist_count());
+ EXPECT_EQ(1, opt_out_store_->clear_blacklist_count());
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a1, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
-
- variations::testing::ClearAllVariationParams();
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
}
TEST_F(PreviewsBlackListTest, HostIndifferentBlackList) {
- // Tests the black list behavior when a null OptOutSture is passed in.
+ // Tests the black list behavior when a null OptOutStore is passed in.
const GURL urls[] = {
GURL("http://www.url_0.com"), GURL("http://www.url_1.com"),
GURL("http://www.url_2.com"), GURL("http://www.url_3.com"),
};
+
// Per host blacklisting should have no effect with the following params.
const size_t per_host_history = 1;
- const int per_host_threshold = per_host_history + 1;
const size_t host_indifferent_history = 4;
- const int host_indifferent_threshold = host_indifferent_history;
- const int duration_in_days = 365;
+ const size_t host_indifferent_threshold = host_indifferent_history;
+ SetHostHistoryParam(per_host_history);
+ SetHostIndifferentHistoryParam(host_indifferent_history);
+ SetHostThresholdParam(per_host_history + 1);
+ SetHostIndifferentThresholdParam(host_indifferent_threshold);
+ SetHostDurationParam(365);
// Disable single opt out by setting duration to 0.
- const int single_opt_out_duration = 0;
- base::FieldTrialList field_trial_list(nullptr);
- std::map<std::string, std::string> params;
- params["per_host_max_stored_history_length"] =
- base::SizeTToString(per_host_history);
- params["host_indifferent_max_stored_history_length"] =
- base::SizeTToString(host_indifferent_history);
- params["per_host_opt_out_threshold"] = base::IntToString(per_host_threshold);
- params["host_indifferent_opt_out_threshold"] =
- base::IntToString(host_indifferent_threshold);
- params["per_host_black_list_duration_in_days"] =
- base::IntToString(duration_in_days);
- params["single_opt_out_duration_in_seconds"] =
- base::IntToString(single_opt_out_duration);
- ASSERT_TRUE(
- variations::AssociateVariationParams("ClientSidePreviews", "Enabled",
- params) &&
- base::FieldTrialList::CreateFieldTrial("ClientSidePreviews", "Enabled"));
-
- base::SimpleTestClock* test_clock = new base::SimpleTestClock();
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
-
- std::unique_ptr<PreviewsBlackList> black_list(
- new PreviewsBlackList(nullptr, base::WrapUnique(test_clock)));
+ SetSingleOptOutDurationParam(0);
+
+ StartTest(true /* null_opt_out */);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE));
for (size_t i = 0; i < host_indifferent_threshold; i++) {
- black_list->AddPreviewNavigation(urls[i], true, PreviewsType::OFFLINE);
+ black_list_->AddPreviewNavigation(urls[i], true, PreviewsType::OFFLINE);
EXPECT_EQ(i != 3 ? PreviewsEligibilityReason::ALLOWED
: PreviewsEligibilityReason::USER_BLACKLISTED,
- black_list->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
}
EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED,
- black_list->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED,
- black_list->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED,
- black_list->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::USER_BLACKLISTED,
- black_list->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(urls[3], false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(urls[3], false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
// New non-opt-out entry will cause these to be allowed now.
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[0], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[1], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(urls[2], PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE));
-
- variations::testing::ClearAllVariationParams();
+ black_list_->IsLoadedAndAllowed(urls[3], PreviewsType::OFFLINE));
}
TEST_F(PreviewsBlackListTest, QueueBehavior) {
@@ -369,76 +400,54 @@ TEST_F(PreviewsBlackListTest, QueueBehavior) {
// queued.
const GURL url("http://www.url.com");
const GURL url2("http://www.url2.com");
+
// Host indifferent blacklisting should have no effect with the following
// params.
const size_t host_indifferent_history = 1;
- const int host_indifferent_threshold = host_indifferent_history + 1;
- const int duration_in_days = 365;
+ SetHostIndifferentHistoryParam(host_indifferent_history);
+ SetHostIndifferentThresholdParam(host_indifferent_history + 1);
+ SetHostDurationParam(365);
// Disable single opt out by setting duration to 0.
- const int single_opt_out_duration = 0;
- base::FieldTrialList field_trial_list(nullptr);
- std::map<std::string, std::string> params;
- params["per_host_black_list_duration_in_days"] =
- base::IntToString(duration_in_days);
- params["host_indifferent_max_stored_history_length"] =
- base::SizeTToString(host_indifferent_history);
- params["host_indifferent_opt_out_threshold"] =
- base::IntToString(host_indifferent_threshold);
- params["single_opt_out_duration_in_seconds"] =
- base::IntToString(single_opt_out_duration);
- ASSERT_TRUE(
- variations::AssociateVariationParams("ClientSidePreviews", "Enabled",
- params) &&
- base::FieldTrialList::CreateFieldTrial("ClientSidePreviews", "Enabled"));
-
- base::MessageLoop loop;
+ SetSingleOptOutDurationParam(0);
std::vector<bool> test_opt_out{true, false};
for (auto opt_out : test_opt_out) {
- base::SimpleTestClock* test_clock = new base::SimpleTestClock();
- base::Time start = test_clock->Now();
-
- TestPreviewsOptOutStore* opt_out_store = new TestPreviewsOptOutStore();
-
- std::unique_ptr<PreviewsBlackList> black_list(new PreviewsBlackList(
- base::WrapUnique(opt_out_store), base::WrapUnique(test_clock)));
+ StartTest(false /* null_opt_out */);
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
+ black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
EXPECT_EQ(PreviewsEligibilityReason::BLACKLIST_DATA_NOT_LOADED,
- black_list->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(opt_out ? PreviewsEligibilityReason::HOST_BLACKLISTED
: PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
- black_list->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- EXPECT_EQ(0, opt_out_store->clear_blacklist_count());
- black_list->ClearBlackList(
- start, test_clock->Now() + base::TimeDelta::FromSeconds(1));
- EXPECT_EQ(1, opt_out_store->clear_blacklist_count());
- black_list->AddPreviewNavigation(url2, opt_out, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url2, opt_out, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
+ black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url, opt_out, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(0, opt_out_store_->clear_blacklist_count());
+ black_list_->ClearBlackList(
+ start_, test_clock_->Now() + base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(1, opt_out_store_->clear_blacklist_count());
+ black_list_->AddPreviewNavigation(url2, opt_out, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url2, opt_out, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1, opt_out_store->clear_blacklist_count());
+ EXPECT_EQ(1, opt_out_store_->clear_blacklist_count());
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
EXPECT_EQ(opt_out ? PreviewsEligibilityReason::HOST_BLACKLISTED
: PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url2, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url2, PreviewsType::OFFLINE));
}
-
- variations::testing::ClearAllVariationParams();
}
TEST_F(PreviewsBlackListTest, MaxHosts) {
@@ -449,69 +458,46 @@ TEST_F(PreviewsBlackListTest, MaxHosts) {
const GURL url_c("http://www.url_c.com");
const GURL url_d("http://www.url_d.com");
const GURL url_e("http://www.url_e.com");
- const size_t stored_history_length = 1;
- const int opt_out_threshold = 1;
- const int black_list_duration_in_days = 365;
- // Disable single opt out by setting duration to 0.
- const int single_opt_out_duration = 0;
- const size_t max_hosts_in_blacklist = 2;
+
// Host indifferent blacklisting should have no effect with the following
// params.
const size_t host_indifferent_history = 1;
- const int host_indifferent_threshold = host_indifferent_history + 1;
- base::FieldTrialList field_trial_list(nullptr);
- std::map<std::string, std::string> params;
- params["per_host_stored_history_length"] =
- base::SizeTToString(stored_history_length);
- params["per_host_opt_out_threshold"] = base::IntToString(opt_out_threshold);
- params["per_host_black_list_duration_in_days"] =
- base::IntToString(black_list_duration_in_days);
- params["max_hosts_in_blacklist"] =
- base::SizeTToString(max_hosts_in_blacklist);
- params["host_indifferent_max_stored_history_length"] =
- base::SizeTToString(host_indifferent_history);
- params["host_indifferent_opt_out_threshold"] =
- base::IntToString(host_indifferent_threshold);
- params["single_opt_out_duration_in_seconds"] =
- base::IntToString(single_opt_out_duration);
- ASSERT_TRUE(
- variations::AssociateVariationParams("ClientSidePreviews", "Enabled",
- params) &&
- base::FieldTrialList::CreateFieldTrial("ClientSidePreviews", "Enabled"));
-
- base::MessageLoop loop;
-
- base::SimpleTestClock* test_clock = new base::SimpleTestClock();
-
- std::unique_ptr<PreviewsBlackList> black_list(
- new PreviewsBlackList(nullptr, base::WrapUnique(test_clock)));
-
- black_list->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_c, false, PreviewsType::OFFLINE);
+ const size_t stored_history_length = 1;
+ SetHostHistoryParam(stored_history_length);
+ SetHostIndifferentHistoryParam(host_indifferent_history);
+ SetHostIndifferentThresholdParam(host_indifferent_history + 1);
+ SetMaxHostInBlackListParam(2);
+ SetHostThresholdParam(stored_history_length);
+ SetHostDurationParam(365);
+ // Disable single opt out by setting duration to 0.
+ SetSingleOptOutDurationParam(0);
+
+ StartTest(true /* null_opt_out */);
+
+ black_list_->AddPreviewNavigation(url_a, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_b, false, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_c, false, PreviewsType::OFFLINE);
// url_a should stay in the map, since it has an opt out time.
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_d, true, PreviewsType::OFFLINE);
- test_clock->Advance(base::TimeDelta::FromSeconds(1));
- black_list->AddPreviewNavigation(url_e, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_d, true, PreviewsType::OFFLINE);
+ test_clock_->Advance(base::TimeDelta::FromSeconds(1));
+ black_list_->AddPreviewNavigation(url_e, true, PreviewsType::OFFLINE);
// url_d and url_e should remain in the map, but url_a should be evicted.
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_d, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_d, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::HOST_BLACKLISTED,
- black_list->IsLoadedAndAllowed(url_e, PreviewsType::OFFLINE));
-
- variations::testing::ClearAllVariationParams();
+ black_list_->IsLoadedAndAllowed(url_e, PreviewsType::OFFLINE));
}
TEST_F(PreviewsBlackListTest, SingleOptOut) {
@@ -520,87 +506,90 @@ TEST_F(PreviewsBlackListTest, SingleOptOut) {
const GURL url_a("http://www.url_a.com");
const GURL url_b("http://www.url_b.com");
const GURL url_c("http://www.url_c.com");
- const size_t stored_history_length = 1;
- const int opt_out_threshold = 2;
- const int black_list_duration_in_days = 365;
- const int single_opt_out_duration = 5;
- const size_t max_hosts_in_blacklist = 10;
+
// Host indifferent blacklisting should have no effect with the following
// params.
const size_t host_indifferent_history = 1;
- const int host_indifferent_threshold = host_indifferent_history + 1;
- base::FieldTrialList field_trial_list(nullptr);
- std::map<std::string, std::string> params;
- params["per_host_stored_history_length"] =
- base::SizeTToString(stored_history_length);
- params["per_host_opt_out_threshold"] = base::IntToString(opt_out_threshold);
- params["per_host_black_list_duration_in_days"] =
- base::IntToString(black_list_duration_in_days);
- params["max_hosts_in_blacklist"] =
- base::SizeTToString(max_hosts_in_blacklist);
- params["host_indifferent_max_stored_history_length"] =
- base::SizeTToString(host_indifferent_history);
- params["host_indifferent_opt_out_threshold"] =
- base::IntToString(host_indifferent_threshold);
- params["single_opt_out_duration_in_seconds"] =
- base::IntToString(single_opt_out_duration);
- ASSERT_TRUE(
- variations::AssociateVariationParams("ClientSidePreviews", "Enabled",
- params) &&
- base::FieldTrialList::CreateFieldTrial("ClientSidePreviews", "Enabled"));
-
- base::SimpleTestClock* test_clock = new base::SimpleTestClock();
-
- std::unique_ptr<PreviewsBlackList> black_list(
- new PreviewsBlackList(nullptr, base::WrapUnique(test_clock)));
-
- black_list->AddPreviewNavigation(url_a, false, PreviewsType::OFFLINE);
+ const int single_opt_out_duration = 5;
+ SetHostHistoryParam(1);
+ SetHostIndifferentHistoryParam(2);
+ SetHostDurationParam(365);
+ SetMaxHostInBlackListParam(10);
+ SetHostIndifferentHistoryParam(host_indifferent_history);
+ SetHostIndifferentThresholdParam(host_indifferent_history + 1);
+ SetSingleOptOutDurationParam(single_opt_out_duration);
+
+ StartTest(true /* null_opt_out */);
+
+ black_list_->AddPreviewNavigation(url_a, false, PreviewsType::OFFLINE);
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_a, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
- test_clock->Advance(
+ test_clock_->Advance(
base::TimeDelta::FromSeconds(single_opt_out_duration + 1));
- black_list->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
+ black_list_->AddPreviewNavigation(url_b, true, PreviewsType::OFFLINE);
EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT,
- black_list->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
- test_clock->Advance(
+ test_clock_->Advance(
base::TimeDelta::FromSeconds(single_opt_out_duration - 1));
EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT,
- black_list->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
- test_clock->Advance(
+ test_clock_->Advance(
base::TimeDelta::FromSeconds(single_opt_out_duration + 1));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
+ black_list_->IsLoadedAndAllowed(url_b, PreviewsType::OFFLINE));
EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
- black_list->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
-
- variations::testing::ClearAllVariationParams();
+ black_list_->IsLoadedAndAllowed(url_c, PreviewsType::OFFLINE));
}
TEST_F(PreviewsBlackListTest, AddPreviewUMA) {
base::HistogramTester histogram_tester;
- base::SimpleTestClock* test_clock = new base::SimpleTestClock();
const GURL url("http://www.url.com");
- std::unique_ptr<PreviewsBlackList> black_list(
- new PreviewsBlackList(nullptr, base::WrapUnique(test_clock)));
- black_list->AddPreviewNavigation(url, false, PreviewsType::OFFLINE);
+ StartTest(false /* null_opt_out */);
+
+ black_list_->AddPreviewNavigation(url, false, PreviewsType::OFFLINE);
histogram_tester.ExpectUniqueSample("Previews.OptOut.UserOptedOut.Offline", 0,
1);
- black_list->AddPreviewNavigation(url, true, PreviewsType::OFFLINE);
+ black_list_->AddPreviewNavigation(url, true, PreviewsType::OFFLINE);
histogram_tester.ExpectBucketCount("Previews.OptOut.UserOptedOut.Offline", 1,
1);
}
+TEST_F(PreviewsBlackListTest, ClearShortTime) {
+ // Tests that clearing the black list for a short amount of time (relative to
+ // "SetSingleOptOutDurationParam") does not reset the blacklist's recent
+ // opt out rule.
+
+ const GURL url("http://www.url.com");
+ RunClearingBlackListTest(url, true /* short_time */);
+ EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT,
+ black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
+}
+
+TEST_F(PreviewsBlackListTest, ClearingBlackListClearsRecentNavigation) {
+ // Tests that clearing the black list for a long amount of time (relative to
+ // "single_opt_out_duration_in_seconds") resets the blacklist's recent opt out
+ // rule.
+
+ const GURL url("http://www.url.com");
+ RunClearingBlackListTest(url, false /* short_time */);
+
+ EXPECT_EQ(PreviewsEligibilityReason::ALLOWED,
+ black_list_->IsLoadedAndAllowed(url, PreviewsType::OFFLINE));
+}
+
+} // namespace
+
} // namespace previews
diff --git a/chromium/components/previews/core/previews_decider.h b/chromium/components/previews/core/previews_decider.h
index f293c87c1ad..2c518fe3d94 100644
--- a/chromium/components/previews/core/previews_decider.h
+++ b/chromium/components/previews/core/previews_decider.h
@@ -7,6 +7,8 @@
#include "components/previews/core/previews_experiments.h"
+#include "net/nqe/effective_connection_type.h"
+
namespace net {
class URLRequest;
}
@@ -15,7 +17,19 @@ namespace previews {
class PreviewsDecider {
public:
- // Whether |request| is allowed to show a preview of |type|.
+ // Whether |request| is allowed to show a preview of |type|. If the current
+ // ECT is strictly faster than |effective_connection_type_threshold|, the
+ // preview will be disallowed; preview types that check network quality before
+ // calling ShouldAllowPreviewAtECT should pass in
+ // EFFECTIVE_CONNECTION_TYPE_4G.
+ virtual bool ShouldAllowPreviewAtECT(
+ const net::URLRequest& request,
+ PreviewsType type,
+ net::EffectiveConnectionType effective_connection_type_threshold)
+ const = 0;
+
+ // Same as ShouldAllowPreviewAtECT, but uses the previews default
+ // EffectiveConnectionType.
virtual bool ShouldAllowPreview(const net::URLRequest& request,
PreviewsType type) const = 0;
diff --git a/chromium/components/previews/core/previews_experiments.cc b/chromium/components/previews/core/previews_experiments.cc
index e8d738aa60a..ccab155619a 100644
--- a/chromium/components/previews/core/previews_experiments.cc
+++ b/chromium/components/previews/core/previews_experiments.cc
@@ -4,13 +4,13 @@
#include "components/previews/core/previews_experiments.h"
-#include <string>
-
+#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "components/previews/core/previews_features.h"
namespace previews {
@@ -75,6 +75,15 @@ net::EffectiveConnectionType GetParamValueAsECT(
return value;
}
+bool IsIncludedInClientSidePreviewsExperimentsFieldTrial() {
+ // By convention, an experiment in the client-side previews study enables use
+ // of at least one client-side previews optimization if its name begins with
+ // "Enabled."
+ return base::StartsWith(
+ base::FieldTrialList::FindFullName(kClientSidePreviewsFieldTrial),
+ kEnabled, base::CompareCase::SENSITIVE);
+}
+
} // namespace
namespace params {
@@ -128,7 +137,7 @@ base::TimeDelta OfflinePreviewFreshnessDuration() {
"offline_preview_freshness_duration_in_days", 7));
}
-net::EffectiveConnectionType EffectiveConnectionTypeThresholdForOffline() {
+net::EffectiveConnectionType DefaultEffectiveConnectionTypeThreshold() {
return GetParamValueAsECT(kClientSidePreviewsFieldTrial,
kEffectiveConnectionTypeThreshold,
net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
@@ -136,10 +145,11 @@ net::EffectiveConnectionType EffectiveConnectionTypeThresholdForOffline() {
bool IsOfflinePreviewsEnabled() {
// Check if "show_offline_pages" is set to "true".
- return IsIncludedInClientSidePreviewsExperimentsFieldTrial() &&
- base::GetFieldTrialParamValue(kClientSidePreviewsFieldTrial,
- kOfflinePagesSlowNetwork) ==
- kExperimentEnabled;
+ return base::FeatureList::IsEnabled(features::kOfflinePreviews) ||
+ (IsIncludedInClientSidePreviewsExperimentsFieldTrial() &&
+ base::GetFieldTrialParamValue(kClientSidePreviewsFieldTrial,
+ kOfflinePagesSlowNetwork) ==
+ kExperimentEnabled);
}
int OfflinePreviewsVersion() {
@@ -147,9 +157,10 @@ int OfflinePreviewsVersion() {
}
bool IsClientLoFiEnabled() {
- return base::StartsWith(
- base::FieldTrialList::FindFullName(kClientLoFiExperimentName), kEnabled,
- base::CompareCase::SENSITIVE);
+ return base::FeatureList::IsEnabled(features::kClientLoFi) ||
+ base::StartsWith(
+ base::FieldTrialList::FindFullName(kClientLoFiExperimentName),
+ kEnabled, base::CompareCase::SENSITIVE);
}
int ClientLoFiVersion() {
@@ -164,13 +175,20 @@ net::EffectiveConnectionType EffectiveConnectionTypeThresholdForClientLoFi() {
} // namespace params
-bool IsIncludedInClientSidePreviewsExperimentsFieldTrial() {
- // By convention, an experiment in the client-side previews study enables use
- // of at least one client-side previews optimization if its name begins with
- // "Enabled."
- return base::StartsWith(
- base::FieldTrialList::FindFullName(kClientSidePreviewsFieldTrial),
- kEnabled, base::CompareCase::SENSITIVE);
+std::string GetStringNameForType(PreviewsType type) {
+ switch (type) {
+ case PreviewsType::OFFLINE:
+ return "Offline";
+ case PreviewsType::LOFI:
+ return "LoFi";
+ case PreviewsType::LITE_PAGE:
+ return "LitePage";
+ case PreviewsType::NONE:
+ case PreviewsType::LAST:
+ break;
+ }
+ NOTREACHED();
+ return std::string();
}
} // namespace previews
diff --git a/chromium/components/previews/core/previews_experiments.h b/chromium/components/previews/core/previews_experiments.h
index 7dd7bc2c42c..b7dd59954a5 100644
--- a/chromium/components/previews/core/previews_experiments.h
+++ b/chromium/components/previews/core/previews_experiments.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_PREVIEWS_CORE_PREVIEWS_EXPERIMENTS_H_
#define COMPONENTS_PREVIEWS_CORE_PREVIEWS_EXPERIMENTS_H_
+#include <string>
#include <utility>
#include <vector>
@@ -47,9 +48,9 @@ base::TimeDelta SingleOptOutDuration();
// shown as a preview.
base::TimeDelta OfflinePreviewFreshnessDuration();
-// The threshold of EffectiveConnectionType above which offline previews should
-// not be served.
-net::EffectiveConnectionType EffectiveConnectionTypeThresholdForOffline();
+// The threshold of EffectiveConnectionType above which previews will trigger by
+// default.
+net::EffectiveConnectionType DefaultEffectiveConnectionTypeThreshold();
// Whether offline previews are enabled.
bool IsOfflinePreviewsEnabled();
@@ -75,18 +76,21 @@ enum class PreviewsType {
// The user is shown an offline page as a preview.
OFFLINE = 1,
- // Replace images with placeholders generated on the client.
- CLIENT_LOFI = 2,
+ // Replace images with placeholders.
+ LOFI = 2,
+
+ // The user is shown a server lite page.
+ LITE_PAGE = 3,
// Insert new enum values here. Keep values sequential to allow looping
// from NONE+1 to LAST-1.
- LAST = 3,
+ LAST = 4,
};
typedef std::vector<std::pair<PreviewsType, int>> PreviewsTypeList;
-// Returns true if any client-side previews experiment is active.
-bool IsIncludedInClientSidePreviewsExperimentsFieldTrial();
+// Gets the string representation of |type|.
+std::string GetStringNameForType(PreviewsType type);
} // namespace previews
diff --git a/chromium/components/previews/core/previews_experiments_unittest.cc b/chromium/components/previews/core/previews_experiments_unittest.cc
index be81b3d7587..bc5efb819cf 100644
--- a/chromium/components/previews/core/previews_experiments_unittest.cc
+++ b/chromium/components/previews/core/previews_experiments_unittest.cc
@@ -7,6 +7,8 @@
#include <map>
#include <string>
+#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/string_util.h"
@@ -24,7 +26,6 @@ const char kEnabled[] = "Enabled";
// Verifies that we can enable offline previews via field trial.
TEST(PreviewsExperimentsTest, TestFieldTrialOfflinePage) {
- EXPECT_FALSE(IsIncludedInClientSidePreviewsExperimentsFieldTrial());
EXPECT_FALSE(params::IsOfflinePreviewsEnabled());
base::FieldTrialList field_trial_list(nullptr);
@@ -36,11 +37,26 @@ TEST(PreviewsExperimentsTest, TestFieldTrialOfflinePage) {
EXPECT_TRUE(base::FieldTrialList::CreateFieldTrial(
kClientSidePreviewsFieldTrial, kEnabled));
- EXPECT_TRUE(IsIncludedInClientSidePreviewsExperimentsFieldTrial());
EXPECT_TRUE(params::IsOfflinePreviewsEnabled());
variations::testing::ClearAllVariationParams();
}
+// Verifies that we can enable offline previews via comand line.
+TEST(PreviewsExperimentsTest, TestCommandLineOfflinePage) {
+ EXPECT_FALSE(params::IsOfflinePreviewsEnabled());
+
+ std::unique_ptr<base::FeatureList> feature_list =
+ base::MakeUnique<base::FeatureList>();
+
+ // The feature is explicitly enabled on the command-line.
+ feature_list->InitializeFromCommandLine("OfflinePreviews", "");
+ base::FeatureList::ClearInstanceForTesting();
+ base::FeatureList::SetInstance(std::move(feature_list));
+
+ EXPECT_TRUE(params::IsOfflinePreviewsEnabled());
+ base::FeatureList::ClearInstanceForTesting();
+}
+
// Verifies that the default params are correct, and that custom params can be
// set, for both the previews blacklist and offline previews.
TEST(PreviewsExperimentsTest, TestParamsForBlackListAndOffline) {
@@ -58,7 +74,7 @@ TEST(PreviewsExperimentsTest, TestParamsForBlackListAndOffline) {
EXPECT_EQ(base::TimeDelta::FromDays(7),
params::OfflinePreviewFreshnessDuration());
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
- params::EffectiveConnectionTypeThresholdForOffline());
+ params::DefaultEffectiveConnectionTypeThreshold());
EXPECT_EQ(0, params::OfflinePreviewsVersion());
base::FieldTrialList field_trial_list(nullptr);
@@ -94,7 +110,7 @@ TEST(PreviewsExperimentsTest, TestParamsForBlackListAndOffline) {
EXPECT_EQ(base::TimeDelta::FromDays(12),
params::OfflinePreviewFreshnessDuration());
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_4G,
- params::EffectiveConnectionTypeThresholdForOffline());
+ params::DefaultEffectiveConnectionTypeThreshold());
EXPECT_EQ(10, params::OfflinePreviewsVersion());
variations::testing::ClearAllVariationParams();
@@ -150,6 +166,22 @@ TEST(PreviewsExperimentsTest, TestEnableClientLoFiWithCustomParams) {
variations::testing::ClearAllVariationParams();
}
+// Verifies that we can enable offline previews via comand line.
+TEST(PreviewsExperimentsTest, TestCommandLineClientLoFi) {
+ EXPECT_FALSE(params::IsClientLoFiEnabled());
+
+ std::unique_ptr<base::FeatureList> feature_list =
+ base::MakeUnique<base::FeatureList>();
+
+ // The feature is explicitly enabled on the command-line.
+ feature_list->InitializeFromCommandLine("ClientLoFi", "");
+ base::FeatureList::ClearInstanceForTesting();
+ base::FeatureList::SetInstance(std::move(feature_list));
+
+ EXPECT_TRUE(params::IsClientLoFiEnabled());
+ base::FeatureList::ClearInstanceForTesting();
+}
+
} // namespace
} // namespace previews
diff --git a/chromium/components/previews/core/previews_features.cc b/chromium/components/previews/core/previews_features.cc
new file mode 100644
index 00000000000..d88577c41f2
--- /dev/null
+++ b/chromium/components/previews/core/previews_features.cc
@@ -0,0 +1,19 @@
+// Copyright 2017 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/previews/core/previews_features.h"
+
+namespace previews {
+namespace features {
+
+// Enables the Offline previews on Android.
+const base::Feature kOfflinePreviews{"OfflinePreviews",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Enables the Client Lo-Fi previews on Android.
+const base::Feature kClientLoFi{"ClientLoFi",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+} // namespace features
+} // namespace previews
diff --git a/chromium/components/previews/core/previews_features.h b/chromium/components/previews/core/previews_features.h
new file mode 100644
index 00000000000..2225bfd5e41
--- /dev/null
+++ b/chromium/components/previews/core/previews_features.h
@@ -0,0 +1,19 @@
+// Copyright 2017 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_PREVIEWS_CORE_PREVIEWS_FEATURES_H_
+#define COMPONENTS_PREVIEWS_CORE_PREVIEWS_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace previews {
+namespace features {
+
+extern const base::Feature kOfflinePreviews;
+extern const base::Feature kClientLoFi;
+
+} // namespace features
+} // namespace previews
+
+#endif // COMPONENTS_PREVIEWS_CORE_PREVIEWS_FEATURES_H_
diff --git a/chromium/components/previews/core/previews_io_data.cc b/chromium/components/previews/core/previews_io_data.cc
index 67403a17c3d..d2f8ed1361d 100644
--- a/chromium/components/previews/core/previews_io_data.cc
+++ b/chromium/components/previews/core/previews_io_data.cc
@@ -9,10 +9,12 @@
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram.h"
#include "base/sequenced_task_runner.h"
+#include "base/strings/stringprintf.h"
#include "base/time/default_clock.h"
#include "components/previews/core/previews_black_list.h"
+#include "components/previews/core/previews_experiments.h"
#include "components/previews/core/previews_opt_out_store.h"
#include "components/previews/core/previews_ui_service.h"
#include "net/base/load_flags.h"
@@ -27,35 +29,30 @@ namespace {
void LogPreviewsEligibilityReason(PreviewsEligibilityReason status,
PreviewsType type) {
- switch (type) {
- case PreviewsType::OFFLINE:
- UMA_HISTOGRAM_ENUMERATION(
- "Previews.EligibilityReason.Offline", static_cast<int>(status),
- static_cast<int>(PreviewsEligibilityReason::LAST));
- break;
- case PreviewsType::CLIENT_LOFI:
- UMA_HISTOGRAM_ENUMERATION(
- "Previews.EligibilityReason.ClientLoFi", static_cast<int>(status),
- static_cast<int>(PreviewsEligibilityReason::LAST));
- break;
- default:
- NOTREACHED();
- }
+ int32_t max_limit = static_cast<int32_t>(PreviewsEligibilityReason::LAST);
+ base::LinearHistogram::FactoryGet(
+ base::StringPrintf("Previews.EligibilityReason.%s",
+ GetStringNameForType(type).c_str()),
+ 1, max_limit, max_limit + 1,
+ base::HistogramBase::kUmaTargetedHistogramFlag)
+ ->Add(static_cast<int>(status));
}
-net::EffectiveConnectionType GetEffectiveConnectionTypeThresholdForPreviewsType(
- PreviewsType type) {
+bool AllowedOnReload(PreviewsType type) {
switch (type) {
+ // These types return new content on refresh.
+ case PreviewsType::LITE_PAGE:
+ case PreviewsType::LOFI:
+ return true;
+ // Loading these types will always be stale when refreshed.
case PreviewsType::OFFLINE:
- return params::EffectiveConnectionTypeThresholdForOffline();
- case PreviewsType::CLIENT_LOFI:
- return params::EffectiveConnectionTypeThresholdForClientLoFi();
+ return false;
case PreviewsType::NONE:
case PreviewsType::LAST:
break;
}
NOTREACHED();
- return net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
+ return false;
}
} // namespace
@@ -110,6 +107,14 @@ void PreviewsIOData::ClearBlackList(base::Time begin_time,
bool PreviewsIOData::ShouldAllowPreview(const net::URLRequest& request,
PreviewsType type) const {
+ return ShouldAllowPreviewAtECT(
+ request, type, params::DefaultEffectiveConnectionTypeThreshold());
+}
+
+bool PreviewsIOData::ShouldAllowPreviewAtECT(
+ const net::URLRequest& request,
+ PreviewsType type,
+ net::EffectiveConnectionType effective_connection_type_threshold) const {
if (is_enabled_callback_.is_null() || !previews_black_list_) {
LogPreviewsEligibilityReason(
PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE, type);
@@ -119,7 +124,7 @@ bool PreviewsIOData::ShouldAllowPreview(const net::URLRequest& request,
return false;
// The blacklist will disallow certain hosts for periods of time based on
- // user's opting out of the preview
+ // user's opting out of the preview.
PreviewsEligibilityReason status =
previews_black_list_->IsLoadedAndAllowed(request.url(), type);
if (status != PreviewsEligibilityReason::ALLOWED) {
@@ -137,20 +142,21 @@ bool PreviewsIOData::ShouldAllowPreview(const net::URLRequest& request,
}
if (network_quality_estimator->GetEffectiveConnectionType() >
- GetEffectiveConnectionTypeThresholdForPreviewsType(type)) {
+ effective_connection_type_threshold) {
LogPreviewsEligibilityReason(PreviewsEligibilityReason::NETWORK_NOT_SLOW,
type);
return false;
}
// LOAD_VALIDATE_CACHE or LOAD_BYPASS_CACHE mean the user reloaded the page.
// If this is a query for offline previews, reloads should be disallowed.
- if (type == PreviewsType::OFFLINE &&
- (request.load_flags() &
- (net::LOAD_VALIDATE_CACHE | net::LOAD_BYPASS_CACHE))) {
- LogPreviewsEligibilityReason(
- PreviewsEligibilityReason::RELOAD_DISALLOWED_FOR_OFFLINE, type);
+ if (!AllowedOnReload(type) &&
+ request.load_flags() &
+ (net::LOAD_VALIDATE_CACHE | net::LOAD_BYPASS_CACHE)) {
+ LogPreviewsEligibilityReason(PreviewsEligibilityReason::RELOAD_DISALLOWED,
+ type);
return false;
}
+
LogPreviewsEligibilityReason(PreviewsEligibilityReason::ALLOWED, type);
return true;
}
diff --git a/chromium/components/previews/core/previews_io_data.h b/chromium/components/previews/core/previews_io_data.h
index f6e85331562..f44fa304736 100644
--- a/chromium/components/previews/core/previews_io_data.h
+++ b/chromium/components/previews/core/previews_io_data.h
@@ -16,6 +16,7 @@
#include "base/time/time.h"
#include "components/previews/core/previews_decider.h"
#include "components/previews/core/previews_experiments.h"
+#include "net/nqe/effective_connection_type.h"
class GURL;
@@ -42,9 +43,10 @@ class PreviewsIOData : public PreviewsDecider {
// Stores |previews_ui_service| as |previews_ui_service_| and posts a task to
// InitializeOnIOThread on the IO thread.
- void Initialize(base::WeakPtr<PreviewsUIService> previews_ui_service,
- std::unique_ptr<PreviewsOptOutStore> previews_opt_out_store,
- const PreviewsIsEnabledCallback& is_enabled_callback);
+ virtual void Initialize(
+ base::WeakPtr<PreviewsUIService> previews_ui_service,
+ std::unique_ptr<PreviewsOptOutStore> previews_opt_out_store,
+ const PreviewsIsEnabledCallback& is_enabled_callback);
// Adds a navigation to |url| to the black list with result |opt_out|.
void AddPreviewNavigation(const GURL& url, bool opt_out, PreviewsType type);
@@ -59,6 +61,11 @@ class PreviewsIOData : public PreviewsDecider {
// PreviewsDecider implementation:
bool ShouldAllowPreview(const net::URLRequest& request,
PreviewsType type) const override;
+ bool ShouldAllowPreviewAtECT(
+ const net::URLRequest& request,
+ PreviewsType type,
+ net::EffectiveConnectionType effective_connection_type_threshold)
+ const override;
protected:
// Posts a task to SetIOData for |previews_ui_service_| on the UI thread with
diff --git a/chromium/components/previews/core/previews_io_data_unittest.cc b/chromium/components/previews/core/previews_io_data_unittest.cc
index 604cb1aa060..2de0ade9039 100644
--- a/chromium/components/previews/core/previews_io_data_unittest.cc
+++ b/chromium/components/previews/core/previews_io_data_unittest.cc
@@ -24,6 +24,7 @@
#include "base/time/time.h"
#include "components/previews/core/previews_black_list.h"
#include "components/previews/core/previews_black_list_item.h"
+#include "components/previews/core/previews_experiments.h"
#include "components/previews/core/previews_opt_out_store.h"
#include "components/previews/core/previews_ui_service.h"
#include "components/variations/variations_associated_data.h"
@@ -40,15 +41,16 @@ namespace previews {
namespace {
-// TODO(sclittle): Tests should be testing the actual prod code that checks if
-// the appropriate field trial is enabled for the preview, instead of testing
-// this function here. Consider moving that code out of
-// chrome/browser/previews/previews_service.cc and into the previews/ component.
+// This method simulates the actual behavior of the passed in callback, which is
+// validated in other tests. For simplicity, offline, lite page, and server LoFi
+// use the offline previews check. Client LoFi uses a seperate check to verify
+// that types are treated differently.
bool IsPreviewFieldTrialEnabled(PreviewsType type) {
switch (type) {
case PreviewsType::OFFLINE:
+ case PreviewsType::LITE_PAGE:
return params::IsOfflinePreviewsEnabled();
- case PreviewsType::CLIENT_LOFI:
+ case PreviewsType::LOFI:
return params::IsClientLoFiEnabled();
case PreviewsType::NONE:
case PreviewsType::LAST:
@@ -273,6 +275,25 @@ TEST_F(PreviewsIODataTest, TestDisallowOfflineWhenNetworkQualityUnavailable) {
1);
}
+TEST_F(PreviewsIODataTest, TestAllowLitePageWhenNetworkQualityFast) {
+ // LoFi and LitePage check NQE on their own.
+ InitializeUIService();
+ CreateFieldTrialWithParams("ClientSidePreviews", "Enabled",
+ {{"show_offline_pages", "true"},
+ {"max_allowed_effective_connection_type", "2G"}});
+
+ network_quality_estimator()->set_effective_connection_type(
+ net::EFFECTIVE_CONNECTION_TYPE_3G);
+
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(io_data()->ShouldAllowPreviewAtECT(
+ *CreateRequest(), PreviewsType::LITE_PAGE,
+ net::EFFECTIVE_CONNECTION_TYPE_4G));
+ histogram_tester.ExpectUniqueSample(
+ "Previews.EligibilityReason.LitePage",
+ static_cast<int>(PreviewsEligibilityReason::ALLOWED), 1);
+}
+
TEST_F(PreviewsIODataTest, TestDisallowOfflineWhenNetworkQualityFast) {
InitializeUIService();
CreateFieldTrialWithParams("ClientSidePreviews", "Enabled",
@@ -306,9 +327,7 @@ TEST_F(PreviewsIODataTest, TestDisallowOfflineOnReload) {
EXPECT_FALSE(io_data()->ShouldAllowPreview(*request, PreviewsType::OFFLINE));
histogram_tester.ExpectUniqueSample(
"Previews.EligibilityReason.Offline",
- static_cast<int>(
- PreviewsEligibilityReason::RELOAD_DISALLOWED_FOR_OFFLINE),
- 1);
+ static_cast<int>(PreviewsEligibilityReason::RELOAD_DISALLOWED), 1);
}
TEST_F(PreviewsIODataTest, TestAllowOffline) {
@@ -332,9 +351,10 @@ TEST_F(PreviewsIODataTest, ClientLoFiDisallowedByDefault) {
InitializeUIService();
base::HistogramTester histogram_tester;
- EXPECT_FALSE(io_data()->ShouldAllowPreview(*CreateRequest(),
- PreviewsType::CLIENT_LOFI));
- histogram_tester.ExpectTotalCount("Previews.EligibilityReason.ClientLoFi", 0);
+ EXPECT_FALSE(io_data()->ShouldAllowPreviewAtECT(
+ *CreateRequest(), PreviewsType::LOFI,
+ params::EffectiveConnectionTypeThresholdForClientLoFi()));
+ histogram_tester.ExpectTotalCount("Previews.EligibilityReason.LoFi", 0);
}
TEST_F(PreviewsIODataTest, ClientLoFiDisallowedWhenFieldTrialDisabled) {
@@ -342,9 +362,10 @@ TEST_F(PreviewsIODataTest, ClientLoFiDisallowedWhenFieldTrialDisabled) {
CreateFieldTrialWithParams("PreviewsClientLoFi", "Disabled", {});
base::HistogramTester histogram_tester;
- EXPECT_FALSE(io_data()->ShouldAllowPreview(*CreateRequest(),
- PreviewsType::CLIENT_LOFI));
- histogram_tester.ExpectTotalCount("Previews.EligibilityReason.ClientLoFi", 0);
+ EXPECT_FALSE(io_data()->ShouldAllowPreviewAtECT(
+ *CreateRequest(), PreviewsType::LOFI,
+ params::EffectiveConnectionTypeThresholdForClientLoFi()));
+ histogram_tester.ExpectTotalCount("Previews.EligibilityReason.LoFi", 0);
}
TEST_F(PreviewsIODataTest, ClientLoFiDisallowedWhenNetworkQualityUnavailable) {
@@ -355,10 +376,11 @@ TEST_F(PreviewsIODataTest, ClientLoFiDisallowedWhenNetworkQualityUnavailable) {
net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
base::HistogramTester histogram_tester;
- EXPECT_FALSE(io_data()->ShouldAllowPreview(*CreateRequest(),
- PreviewsType::CLIENT_LOFI));
+ EXPECT_FALSE(io_data()->ShouldAllowPreviewAtECT(
+ *CreateRequest(), PreviewsType::LOFI,
+ params::EffectiveConnectionTypeThresholdForClientLoFi()));
histogram_tester.ExpectUniqueSample(
- "Previews.EligibilityReason.ClientLoFi",
+ "Previews.EligibilityReason.LoFi",
static_cast<int>(PreviewsEligibilityReason::NETWORK_QUALITY_UNAVAILABLE),
1);
}
@@ -372,10 +394,11 @@ TEST_F(PreviewsIODataTest, ClientLoFiDisallowedWhenNetworkFast) {
net::EFFECTIVE_CONNECTION_TYPE_3G);
base::HistogramTester histogram_tester;
- EXPECT_FALSE(io_data()->ShouldAllowPreview(*CreateRequest(),
- PreviewsType::CLIENT_LOFI));
+ EXPECT_FALSE(io_data()->ShouldAllowPreviewAtECT(
+ *CreateRequest(), PreviewsType::LOFI,
+ params::EffectiveConnectionTypeThresholdForClientLoFi()));
histogram_tester.ExpectUniqueSample(
- "Previews.EligibilityReason.ClientLoFi",
+ "Previews.EligibilityReason.LoFi",
static_cast<int>(PreviewsEligibilityReason::NETWORK_NOT_SLOW), 1);
}
@@ -388,10 +411,11 @@ TEST_F(PreviewsIODataTest, ClientLoFiAllowed) {
net::EFFECTIVE_CONNECTION_TYPE_2G);
base::HistogramTester histogram_tester;
- EXPECT_TRUE(io_data()->ShouldAllowPreview(*CreateRequest(),
- PreviewsType::CLIENT_LOFI));
+ EXPECT_TRUE(io_data()->ShouldAllowPreviewAtECT(
+ *CreateRequest(), PreviewsType::LOFI,
+ params::EffectiveConnectionTypeThresholdForClientLoFi()));
histogram_tester.ExpectUniqueSample(
- "Previews.EligibilityReason.ClientLoFi",
+ "Previews.EligibilityReason.LoFi",
static_cast<int>(PreviewsEligibilityReason::ALLOWED), 1);
}
@@ -407,10 +431,11 @@ TEST_F(PreviewsIODataTest, ClientLoFiAllowedOnReload) {
request->SetLoadFlags(net::LOAD_BYPASS_CACHE);
base::HistogramTester histogram_tester;
- EXPECT_TRUE(
- io_data()->ShouldAllowPreview(*request, PreviewsType::CLIENT_LOFI));
+ EXPECT_TRUE(io_data()->ShouldAllowPreviewAtECT(
+ *request, PreviewsType::LOFI,
+ params::EffectiveConnectionTypeThresholdForClientLoFi()));
histogram_tester.ExpectUniqueSample(
- "Previews.EligibilityReason.ClientLoFi",
+ "Previews.EligibilityReason.LoFi",
static_cast<int>(PreviewsEligibilityReason::ALLOWED), 1);
}
diff --git a/chromium/components/previews/core/previews_opt_out_store_sql.cc b/chromium/components/previews/core/previews_opt_out_store_sql.cc
index 4b9b97b67d9..1446b0a8bb1 100644
--- a/chromium/components/previews/core/previews_opt_out_store_sql.cc
+++ b/chromium/components/previews/core/previews_opt_out_store_sql.cc
@@ -17,6 +17,7 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/previews/core/previews_black_list.h"
diff --git a/chromium/components/printing/browser/BUILD.gn b/chromium/components/printing/browser/BUILD.gn
index bddd3a67d52..3cce73a7647 100644
--- a/chromium/components/printing/browser/BUILD.gn
+++ b/chromium/components/printing/browser/BUILD.gn
@@ -10,10 +10,13 @@ static_library("browser") {
"print_manager_utils.h",
]
+ public_deps = [
+ "//content/public/browser",
+ ]
+
deps = [
"//base",
"//components/printing/common",
- "//content/public/browser",
"//printing",
]
}
diff --git a/chromium/components/printing/common/print_messages.h b/chromium/components/printing/common/print_messages.h
index d11d28dee8d..32b0451b60d 100644
--- a/chromium/components/printing/common/print_messages.h
+++ b/chromium/components/printing/common/print_messages.h
@@ -253,15 +253,9 @@ IPC_STRUCT_END()
// Parameters sent along with the page count.
IPC_STRUCT_BEGIN(PrintHostMsg_DidGetPreviewPageCount_Params)
- // Cookie for the document to ensure correctness.
- IPC_STRUCT_MEMBER(int, document_cookie)
-
// Total page count.
IPC_STRUCT_MEMBER(int, page_count)
- // Indicates whether the previewed document is modifiable.
- IPC_STRUCT_MEMBER(bool, is_modifiable)
-
// Scaling % to fit to page
IPC_STRUCT_MEMBER(int, fit_to_page_scaling)
@@ -467,7 +461,7 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewCancelled,
IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
int /* document cookie */)
-// Run a nested message loop in the renderer until print preview for
+// Run a nested run loop in the renderer until print preview for
// window.print() finishes.
IPC_SYNC_MESSAGE_ROUTED0_0(PrintHostMsg_SetupScriptedPrintPreview)
diff --git a/chromium/components/printing/renderer/print_web_view_helper.cc b/chromium/components/printing/renderer/print_web_view_helper.cc
index ab055908eb3..50ab353c84c 100644
--- a/chromium/components/printing/renderer/print_web_view_helper.cc
+++ b/chromium/components/printing/renderer/print_web_view_helper.cc
@@ -36,6 +36,7 @@
#include "printing/metafile_skia_wrapper.h"
#include "printing/pdf_metafile_skia.h"
#include "printing/units.h"
+#include "third_party/WebKit/public/platform/Platform.h"
#include "third_party/WebKit/public/platform/WebDoubleSize.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
@@ -84,11 +85,14 @@ enum PrintPreviewHelperEvents {
const double kMinDpi = 1.0;
-// Also set in third_party/WebKit/Source/core/page/PrintContext.cpp
-const float kPrintingMinimumShrinkFactor = 1.333f;
+// Also set in third_party/WebKit/Source/core/page/PrintContext.h
+const float kPrintingMinimumShrinkFactor = 1.33333333f;
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
bool g_is_preview_enabled = true;
+#else
+bool g_is_preview_enabled = false;
+#endif
const char kPageLoadScriptFormat[] =
"document.open(); document.write(%s); document.close();";
@@ -103,9 +107,6 @@ void ExecuteScript(blink::WebFrame* frame,
std::string script = base::StringPrintf(script_format, json.c_str());
frame->ExecuteScript(blink::WebString::FromUTF8(script));
}
-#else
-bool g_is_preview_enabled = false;
-#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW)
int GetDPI(const PrintMsg_Print_Params* print_params) {
#if defined(OS_MACOSX)
@@ -559,7 +560,6 @@ blink::WebView* FrameReference::view() {
return view_;
}
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// static - Not anonymous so that platform implementations can use it.
void PrintWebViewHelper::PrintHeaderAndFooter(
blink::WebCanvas* canvas,
@@ -588,8 +588,9 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
blink::WebWidgetClient web_widget_client;
blink::WebFrameWidget::Create(&web_widget_client, web_view, frame);
- base::Value html(ResourceBundle::GetSharedInstance().GetLocalizedString(
- IDR_PRINT_PREVIEW_PAGE));
+ base::Value html(
+ base::UTF8ToUTF16(ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_PRINT_PREVIEW_PAGE)));
// Load page with script to avoid async operations.
ExecuteScript(frame, kPageLoadScriptFormat, html);
@@ -617,7 +618,6 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
web_view->Close();
}
-#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW)
// static - Not anonymous so that platform implementations can use it.
float PrintWebViewHelper::RenderPageContent(blink::WebFrame* frame,
@@ -678,7 +678,9 @@ class PrepareFrameAndViewForPrint : public blink::WebViewClient,
const blink::WebString& name,
const blink::WebString& fallback_name,
blink::WebSandboxFlags sandbox_flags,
+ const blink::WebParsedFeaturePolicy& container_policy,
const blink::WebFrameOwnerProperties& frame_owner_properties) override;
+ std::unique_ptr<blink::WebURLLoader> CreateURLLoader() override;
void CallOnReady();
void ResizeForPrinting();
@@ -723,10 +725,8 @@ PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
ComputeWebKitPrintParamsInDesiredDpi(params, &web_print_params_);
frame->PrintBegin(web_print_params_, node_to_print_);
double scale_factor = 1.0f;
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
if (print_params.scale_factor >= PrintWebViewHelper::kEpsilon)
scale_factor = print_params.scale_factor;
-#endif
print_params = CalculatePrintParamsForCss(
frame, 0, print_params, ignore_css_margins, fit_to_page, &scale_factor);
frame->PrintEnd();
@@ -837,11 +837,19 @@ blink::WebLocalFrame* PrepareFrameAndViewForPrint::CreateChildFrame(
const blink::WebString& name,
const blink::WebString& fallback_name,
blink::WebSandboxFlags sandbox_flags,
+ const blink::WebParsedFeaturePolicy& container_policy,
const blink::WebFrameOwnerProperties& frame_owner_properties) {
- blink::WebLocalFrame* frame =
- blink::WebLocalFrame::Create(scope, this, nullptr, nullptr);
- parent->AppendChild(frame);
- return frame;
+ // This is called when printing a selection and when this selection contains
+ // an iframe. This is not supported yet. An empty rectangle will be displayed
+ // instead.
+ // Please see: https://crbug.com/732780.
+ return nullptr;
+}
+
+std::unique_ptr<blink::WebURLLoader>
+PrepareFrameAndViewForPrint::CreateURLLoader() {
+ // TODO(yhirano): Stop using Platform::CreateURLLoader() here.
+ return blink::Platform::Current()->CreateURLLoader();
}
void PrepareFrameAndViewForPrint::CallOnReady() {
@@ -987,7 +995,7 @@ void PrintWebViewHelper::ScriptedPrint(bool user_initiated) {
bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) {
// The class is not designed to handle recursive messages. This is not
// expected during regular flow. However, during rendering of content for
- // printing, lower level code may run nested message loop. E.g. PDF may has
+ // printing, lower level code may run nested run loop. E.g. PDF may has
// script to show message box http://crbug.com/502562. In that moment browser
// may receive updated printer capabilities and decide to restart print
// preview generation. When this happened message handling function may
@@ -1297,11 +1305,10 @@ bool PrintWebViewHelper::CreatePreviewDocument() {
PrintHostMsg_DidGetPreviewPageCount_Params params;
params.page_count = print_preview_context_.total_page_count();
- params.is_modifiable = print_preview_context_.IsModifiable();
params.fit_to_page_scaling = fit_to_page_scaling;
- params.document_cookie = print_params.document_cookie;
params.preview_request_id = print_params.preview_request_id;
- params.clear_preview_data = print_preview_context_.generate_draft_pages();
+ params.clear_preview_data = print_preview_context_.generate_draft_pages() ||
+ !print_preview_context_.IsModifiable();
Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), params));
if (CheckForCancel())
return false;
@@ -1349,6 +1356,7 @@ bool PrintWebViewHelper::RenderPreviewPage(
base::TimeTicks begin_time = base::TimeTicks::Now();
PrintPageInternal(print_params, page_number,
+ print_preview_context_.total_page_count(),
print_preview_context_.prepared_frame(),
initial_render_metafile, nullptr, nullptr, nullptr);
print_preview_context_.RenderedPreviewPage(
@@ -1849,6 +1857,7 @@ bool PrintWebViewHelper::RenderPagesForPrint(blink::WebLocalFrame* frame,
#if !defined(OS_MACOSX)
void PrintWebViewHelper::PrintPageInternal(const PrintMsg_Print_Params& params,
int page_number,
+ int page_count,
blink::WebLocalFrame* frame,
PdfMetafileSkia* metafile,
gfx::Size* page_size_in_dpi,
@@ -1857,10 +1866,8 @@ void PrintWebViewHelper::PrintPageInternal(const PrintMsg_Print_Params& params,
PageSizeMargins page_layout_in_points;
double css_scale_factor = 1.0f;
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
if (params.scale_factor >= kEpsilon)
css_scale_factor = params.scale_factor;
-#endif
// Save the original page size here to avoid rounding errors incurred by
// converting to pixels and back and by scaling the page for reflow and
@@ -1907,21 +1914,19 @@ void PrintWebViewHelper::PrintPageInternal(const PrintMsg_Print_Params& params,
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
if (params.display_header_footer) {
- // TODO(thestig): Figure out why Linux needs this. It is almost certainly
- // |printingMinimumShrinkFactor| from Blink.
#if defined(OS_WIN)
const float fudge_factor = 1;
#else
+ // TODO(thestig): Figure out why Linux needs this. It is almost certainly
+ // |kPrintingMinimumShrinkFactor| from Blink.
const float fudge_factor = kPrintingMinimumShrinkFactor;
#endif
// |page_number| is 0-based, so 1 is added.
- PrintHeaderAndFooter(
- canvas, page_number + 1, print_preview_context_.total_page_count(),
- *frame, scale_factor / fudge_factor, page_layout_in_points, params);
+ PrintHeaderAndFooter(canvas, page_number + 1, page_count, *frame,
+ scale_factor / fudge_factor, page_layout_in_points,
+ params);
}
-#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW)
float webkit_scale_factor = RenderPageContent(
frame, page_number, canvas_area, content_area, scale_factor, canvas);
diff --git a/chromium/components/printing/renderer/print_web_view_helper.h b/chromium/components/printing/renderer/print_web_view_helper.h
index 15d2c288e78..c4339d474ad 100644
--- a/chromium/components/printing/renderer/print_web_view_helper.h
+++ b/chromium/components/printing/renderer/print_web_view_helper.h
@@ -293,10 +293,12 @@ class PrintWebViewHelper
#if defined(OS_MACOSX)
void PrintPagesInternal(const PrintMsg_Print_Params& params,
const std::vector<int>& printed_pages,
+ int page_count,
blink::WebLocalFrame* frame);
#else
void PrintPageInternal(const PrintMsg_Print_Params& params,
int page_number,
+ int page_count,
blink::WebLocalFrame* frame,
PdfMetafileSkia* metafile,
gfx::Size* page_size_in_dpi,
@@ -308,6 +310,7 @@ class PrintWebViewHelper
#if defined(OS_MACOSX)
void RenderPage(const PrintMsg_Print_Params& params,
int page_number,
+ int page_count,
blink::WebLocalFrame* frame,
bool is_preview,
PdfMetafileSkia* metafile,
@@ -346,9 +349,8 @@ class PrintWebViewHelper
const PrintMsg_PrintPages_Params& params,
int page_count);
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
- // Given the |device| and |canvas| to draw on, prints the appropriate headers
- // and footers using strings from |header_footer_info| on to the canvas.
+ // Given the |canvas| to draw on, prints the appropriate headers and footers
+ // to |canvas| using information from the remaining parameters.
static void PrintHeaderAndFooter(blink::WebCanvas* canvas,
int page_number,
int total_pages,
@@ -356,7 +358,6 @@ class PrintWebViewHelper
float webkit_scale_factor,
const PageSizeMargins& page_layout_in_points,
const PrintMsg_Print_Params& params);
-#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW)
// Script Initiated Printing ------------------------------------------------
diff --git a/chromium/components/printing/renderer/print_web_view_helper_linux.cc b/chromium/components/printing/renderer/print_web_view_helper_linux.cc
index dac616a6bb6..910c471105f 100644
--- a/chromium/components/printing/renderer/print_web_view_helper_linux.cc
+++ b/chromium/components/printing/renderer/print_web_view_helper_linux.cc
@@ -55,8 +55,8 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebLocalFrame* frame,
return false;
for (int page_number : printed_pages) {
- PrintPageInternal(params.params, page_number, frame, &metafile, nullptr,
- nullptr, nullptr);
+ PrintPageInternal(params.params, page_number, page_count, frame, &metafile,
+ nullptr, nullptr, nullptr);
}
// blink::printEnd() for PDF should be called before metafile is closed.
@@ -94,7 +94,7 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebLocalFrame* frame,
printed_page_params.page_number = printed_pages[i];
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
// Send the rest of the pages with an invalid metafile handle.
- printed_page_params.metafile_data_handle.fd = -1;
+ printed_page_params.metafile_data_handle.Release();
}
return true;
#endif // defined(OS_ANDROID)
diff --git a/chromium/components/printing/renderer/print_web_view_helper_mac.mm b/chromium/components/printing/renderer/print_web_view_helper_mac.mm
index 4c1c5b9a73e..a00cfa0a95f 100644
--- a/chromium/components/printing/renderer/print_web_view_helper_mac.mm
+++ b/chromium/components/printing/renderer/print_web_view_helper_mac.mm
@@ -29,12 +29,13 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebLocalFrame* frame,
return false;
if (delegate_->UseSingleMetafile()) {
- PrintPagesInternal(print_params, printed_pages, frame);
+ PrintPagesInternal(print_params, printed_pages, page_count, frame);
return true;
}
for (int page_number : printed_pages)
- PrintPagesInternal(print_params, std::vector<int>{page_number}, frame);
+ PrintPagesInternal(print_params, std::vector<int>{page_number}, page_count,
+ frame);
return true;
}
#endif // BUILDFLAG(ENABLE_BASIC_PRINTING)
@@ -42,6 +43,7 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebLocalFrame* frame,
void PrintWebViewHelper::PrintPagesInternal(
const PrintMsg_Print_Params& params,
const std::vector<int>& printed_pages,
+ int page_count,
blink::WebLocalFrame* frame) {
PdfMetafileSkia metafile(PDF_SKIA_DOCUMENT_TYPE);
CHECK(metafile.Init());
@@ -49,8 +51,8 @@ void PrintWebViewHelper::PrintPagesInternal(
gfx::Size page_size_in_dpi;
gfx::Rect content_area_in_dpi;
for (int page_number : printed_pages) {
- RenderPage(params, page_number, frame, false, &metafile, &page_size_in_dpi,
- &content_area_in_dpi);
+ RenderPage(params, page_number, page_count, frame, false, &metafile,
+ &page_size_in_dpi, &content_area_in_dpi);
}
metafile.FinishDocument();
@@ -93,8 +95,10 @@ bool PrintWebViewHelper::RenderPreviewPage(
base::TimeTicks begin_time = base::TimeTicks::Now();
gfx::Size page_size;
- RenderPage(printParams, page_number, print_preview_context_.prepared_frame(),
- true, initial_render_metafile, &page_size, NULL);
+ RenderPage(printParams, page_number,
+ print_preview_context_.total_page_count(),
+ print_preview_context_.prepared_frame(), true,
+ initial_render_metafile, &page_size, NULL);
print_preview_context_.RenderedPreviewPage(
base::TimeTicks::Now() - begin_time);
@@ -115,6 +119,7 @@ bool PrintWebViewHelper::RenderPreviewPage(
void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
int page_number,
+ int page_count,
blink::WebLocalFrame* frame,
bool is_preview,
PdfMetafileSkia* metafile,
@@ -147,14 +152,11 @@ void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
cc::SetIsPreviewMetafile(canvas, is_preview);
-#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
if (params.display_header_footer) {
PrintHeaderAndFooter(static_cast<blink::WebCanvas*>(canvas),
- page_number + 1,
- print_preview_context_.total_page_count(), *frame,
- scale_factor, page_layout_in_points, params);
+ page_number + 1, page_count, *frame, scale_factor,
+ page_layout_in_points, params);
}
-#endif // BUILDFLAG(ENABLE_PRINT_PREVIEW)
RenderPageContent(frame, page_number, canvas_area, content_area,
scale_factor, static_cast<blink::WebCanvas*>(canvas));
}
diff --git a/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc b/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc
index 9c61a794a4c..d32141d81f5 100644
--- a/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc
+++ b/chromium/components/printing/renderer/print_web_view_helper_pdf_win.cc
@@ -30,8 +30,8 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebLocalFrame* frame,
CHECK(metafile.Init());
for (size_t i = 0; i < printed_pages.size(); ++i) {
- PrintPageInternal(params.params, printed_pages[i], frame, &metafile,
- &page_size_in_dpi[i], &content_area_in_dpi[i],
+ PrintPageInternal(params.params, printed_pages[i], page_count, frame,
+ &metafile, &page_size_in_dpi[i], &content_area_in_dpi[i],
&printable_area_in_dpi[i]);
}
diff --git a/chromium/components/printing/service/BUILD.gn b/chromium/components/printing/service/BUILD.gn
new file mode 100644
index 00000000000..077ee2813b0
--- /dev/null
+++ b/chromium/components/printing/service/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2017 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.
+
+import("//services/service_manager/public/cpp/service.gni")
+import("//services/service_manager/public/service_manifest.gni")
+
+static_library("service") {
+ sources = [
+ "pdf_compositor_impl.cc",
+ "pdf_compositor_impl.h",
+ "pdf_compositor_service.cc",
+ "pdf_compositor_service.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/discardable_memory/client",
+ "//components/discardable_memory/public/interfaces",
+ "//content/public/common:service_names",
+ "//content/public/utility",
+ "//printing/common",
+ "//skia",
+ ]
+
+ public_deps = [
+ "//components/printing/service/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
+
+service_manifest("pdf_compositor_manifest") {
+ name = "pdf_compositor"
+ source = "pdf_compositor_manifest.json"
+}
diff --git a/chromium/components/printing/service/DEPS b/chromium/components/printing/service/DEPS
new file mode 100644
index 00000000000..839127983cb
--- /dev/null
+++ b/chromium/components/printing/service/DEPS
@@ -0,0 +1,10 @@
+include_rules = [
+ "+components/discardable_memory/client",
+ "+content/public/common",
+ "+content/public/utility",
+ "+mojo/public/cpp",
+ "+printing/common",
+ "+services/service_manager/public/cpp",
+ "+skia",
+ "+third_party/skia",
+]
diff --git a/chromium/components/printing/service/README.md b/chromium/components/printing/service/README.md
new file mode 100644
index 00000000000..6ce9c170a85
--- /dev/null
+++ b/chromium/components/printing/service/README.md
@@ -0,0 +1,4 @@
+The pdf_compositor service should composite multiple raw pictures from different
+frames into a complete one, then converts it into a pdf file within an isolated
+sandboxed process. Currently, it has no compositing functionality, just convert
+a set of raw pictures into a pdf file within the sandboxed process.
diff --git a/chromium/components/printing/service/pdf_compositor_impl.cc b/chromium/components/printing/service/pdf_compositor_impl.cc
new file mode 100644
index 00000000000..c27e466ddd8
--- /dev/null
+++ b/chromium/components/printing/service/pdf_compositor_impl.cc
@@ -0,0 +1,86 @@
+// Copyright 2017 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/printing/service/pdf_compositor_impl.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/shared_memory.h"
+#include "base/memory/shared_memory_handle.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+#include "printing/common/pdf_metafile_utils.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkDocument.h"
+#include "third_party/skia/src/utils/SkMultiPictureDocument.h"
+
+namespace printing {
+
+PdfCompositorImpl::PdfCompositorImpl(
+ const std::string& creator,
+ std::unique_ptr<service_manager::ServiceContextRef> service_ref)
+ : service_ref_(std::move(service_ref)), creator_(creator) {}
+
+PdfCompositorImpl::~PdfCompositorImpl() = default;
+
+void PdfCompositorImpl::CompositePdf(
+ mojo::ScopedSharedBufferHandle sk_handle,
+ mojom::PdfCompositor::CompositePdfCallback callback) {
+ DCHECK(sk_handle.is_valid());
+
+ base::SharedMemoryHandle memory_handle;
+ size_t memory_size = 0;
+ bool read_only_flag = false;
+
+ const MojoResult result = mojo::UnwrapSharedMemoryHandle(
+ std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag);
+ DCHECK_EQ(MOJO_RESULT_OK, result);
+ DCHECK_GT(memory_size, 0u);
+
+ std::unique_ptr<base::SharedMemory> shm =
+ base::MakeUnique<base::SharedMemory>(memory_handle, true);
+ if (!shm->Map(memory_size)) {
+ DLOG(ERROR) << "CompositePdf: Shared memory map failed.";
+ std::move(callback).Run(mojo::ScopedSharedBufferHandle());
+ return;
+ }
+
+ SkMemoryStream stream(shm->memory(), memory_size);
+ int page_count = SkMultiPictureDocumentReadPageCount(&stream);
+ if (!page_count) {
+ DLOG(ERROR) << "CompositePdf: No page is read.";
+ std::move(callback).Run(mojo::ScopedSharedBufferHandle());
+ return;
+ }
+
+ std::vector<SkDocumentPage> pages(page_count);
+ if (!SkMultiPictureDocumentRead(&stream, pages.data(), page_count)) {
+ DLOG(ERROR) << "CompositePdf: Page reading failed.";
+ std::move(callback).Run(mojo::ScopedSharedBufferHandle());
+ return;
+ }
+
+ SkDynamicMemoryWStream wstream;
+ sk_sp<SkDocument> doc = MakePdfDocument(creator_, &wstream);
+
+ for (const auto& page : pages) {
+ SkCanvas* canvas = doc->beginPage(page.fSize.width(), page.fSize.height());
+ canvas->drawPicture(page.fPicture);
+ doc->endPage();
+ }
+ doc->close();
+
+ mojo::ScopedSharedBufferHandle buffer =
+ mojo::SharedBufferHandle::Create(wstream.bytesWritten());
+ DCHECK(buffer.is_valid());
+
+ mojo::ScopedSharedBufferMapping mapping = buffer->Map(wstream.bytesWritten());
+ DCHECK(mapping);
+ wstream.copyToAndReset(mapping.get());
+
+ std::move(callback).Run(std::move(buffer));
+}
+
+} // namespace printing
diff --git a/chromium/components/printing/service/pdf_compositor_impl.h b/chromium/components/printing/service/pdf_compositor_impl.h
new file mode 100644
index 00000000000..b7890fa10ee
--- /dev/null
+++ b/chromium/components/printing/service/pdf_compositor_impl.h
@@ -0,0 +1,38 @@
+// Copyright 2017 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_PRINTING_SERVICE_PDF_COMPOSITOR_IMPL_H_
+#define COMPONENTS_PRINTING_SERVICE_PDF_COMPOSITOR_IMPL_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "components/printing/service/public/interfaces/pdf_compositor.mojom.h"
+#include "mojo/public/cpp/system/buffer.h"
+#include "services/service_manager/public/cpp/service_context_ref.h"
+
+namespace printing {
+
+class PdfCompositorImpl : public mojom::PdfCompositor {
+ public:
+ PdfCompositorImpl(
+ const std::string& creator,
+ std::unique_ptr<service_manager::ServiceContextRef> service_ref);
+ ~PdfCompositorImpl() override;
+
+ void CompositePdf(
+ mojo::ScopedSharedBufferHandle sk_handle,
+ mojom::PdfCompositor::CompositePdfCallback callback) override;
+
+ private:
+ const std::unique_ptr<service_manager::ServiceContextRef> service_ref_;
+ const std::string creator_;
+
+ DISALLOW_COPY_AND_ASSIGN(PdfCompositorImpl);
+};
+
+} // namespace printing
+
+#endif // COMPONENTS_PRINTING_SERVICE_PDF_COMPOSITOR_IMPL_H_
diff --git a/chromium/components/printing/service/pdf_compositor_manifest.json b/chromium/components/printing/service/pdf_compositor_manifest.json
new file mode 100644
index 00000000000..9e9b05929d8
--- /dev/null
+++ b/chromium/components/printing/service/pdf_compositor_manifest.json
@@ -0,0 +1,15 @@
+{
+ "name": "pdf_compositor",
+ "display_name": "PDF Compositor Service",
+ "interface_provider_specs": {
+ "service_manager:connector": {
+ "provides": {
+ "composite": [ "printing::mojom::PdfCompositor" ]
+ },
+ "requires": {
+ "service_manager": [ "service_manager:all_users" ],
+ "content_browser": [ "utility" ]
+ }
+ }
+ }
+}
diff --git a/chromium/components/printing/service/pdf_compositor_service.cc b/chromium/components/printing/service/pdf_compositor_service.cc
new file mode 100644
index 00000000000..d00f3ed76bd
--- /dev/null
+++ b/chromium/components/printing/service/pdf_compositor_service.cc
@@ -0,0 +1,73 @@
+// Copyright 2017 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/printing/service/pdf_compositor_service.h"
+
+#include <utility>
+
+#include "base/lazy_instance.h"
+#include "base/memory/discardable_memory.h"
+#include "base/memory/ptr_util.h"
+#include "components/printing/service/pdf_compositor_impl.h"
+#include "components/printing/service/public/interfaces/pdf_compositor.mojom.h"
+#include "content/public/common/service_names.mojom.h"
+#include "content/public/utility/utility_thread.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/service_context.h"
+
+namespace {
+
+void OnPdfCompositorRequest(
+ const std::string& creator,
+ service_manager::ServiceContextRefFactory* ref_factory,
+ const service_manager::BindSourceInfo& source_info,
+ printing::mojom::PdfCompositorRequest request) {
+ mojo::MakeStrongBinding(base::MakeUnique<printing::PdfCompositorImpl>(
+ creator, ref_factory->CreateRef()),
+ std::move(request));
+}
+} // namespace
+
+namespace printing {
+
+PdfCompositorService::PdfCompositorService(const std::string& creator)
+ : creator_(creator.empty() ? "Chromium" : creator), weak_factory_(this) {}
+
+PdfCompositorService::~PdfCompositorService() = default;
+
+// static
+std::unique_ptr<service_manager::Service> PdfCompositorService::Create(
+ const std::string& creator) {
+ return base::MakeUnique<printing::PdfCompositorService>(creator);
+}
+
+void PdfCompositorService::OnStart() {
+ // Set up discardable memory manager.
+ discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
+ context()->connector()->BindInterface(content::mojom::kBrowserServiceName,
+ &manager_ptr);
+ discardable_shared_memory_manager_ = base::MakeUnique<
+ discardable_memory::ClientDiscardableSharedMemoryManager>(
+ std::move(manager_ptr), content::UtilityThread::Get()->GetIOTaskRunner());
+ DCHECK(discardable_shared_memory_manager_);
+ base::DiscardableMemoryAllocator::SetInstance(
+ discardable_shared_memory_manager_.get());
+
+ ref_factory_ = base::MakeUnique<service_manager::ServiceContextRefFactory>(
+ base::Bind(&service_manager::ServiceContext::RequestQuit,
+ base::Unretained(context())));
+ registry_.AddInterface(
+ base::Bind(&OnPdfCompositorRequest, creator_, ref_factory_.get()));
+}
+
+void PdfCompositorService::OnBindInterface(
+ const service_manager::BindSourceInfo& source_info,
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) {
+ registry_.BindInterface(source_info, interface_name,
+ std::move(interface_pipe));
+}
+
+} // namespace printing
diff --git a/chromium/components/printing/service/pdf_compositor_service.h b/chromium/components/printing/service/pdf_compositor_service.h
new file mode 100644
index 00000000000..31672988b5c
--- /dev/null
+++ b/chromium/components/printing/service/pdf_compositor_service.h
@@ -0,0 +1,54 @@
+// Copyright 2017 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_PRINTING_SERVICE_PDF_COMPOSITOR_SERVICE_H_
+#define COMPONENTS_PRINTING_SERVICE_PDF_COMPOSITOR_SERVICE_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/discardable_memory/client/client_discardable_shared_memory_manager.h"
+#include "components/printing/service/public/interfaces/pdf_compositor.mojom.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_context_ref.h"
+
+namespace printing {
+
+class PdfCompositorService : public service_manager::Service {
+ public:
+ explicit PdfCompositorService(const std::string& creator);
+ ~PdfCompositorService() override;
+
+ // Factory function for use as an embedded service.
+ static std::unique_ptr<service_manager::Service> Create(
+ const std::string& creator);
+
+ // service_manager::Service:
+ void OnStart() override;
+ void OnBindInterface(const service_manager::BindSourceInfo& source_info,
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) override;
+
+ private:
+ // The creator of this service.
+ // Currently contains the service creator's user agent string if given,
+ // otherwise just use string "Chromium".
+ const std::string creator_;
+
+ std::unique_ptr<discardable_memory::ClientDiscardableSharedMemoryManager>
+ discardable_shared_memory_manager_;
+ std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_;
+ service_manager::BinderRegistry registry_;
+ base::WeakPtrFactory<PdfCompositorService> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PdfCompositorService);
+};
+
+} // namespace printing
+
+#endif // COMPONENTS_PRINTING_SERVICE_PDF_COMPOSITOR_SERVICE_H_
diff --git a/chromium/components/printing/service/public/cpp/BUILD.gn b/chromium/components/printing/service/public/cpp/BUILD.gn
new file mode 100644
index 00000000000..f0c9b84f773
--- /dev/null
+++ b/chromium/components/printing/service/public/cpp/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2017 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+source_set("client") {
+ sources = [
+ "pdf_compositor_client.cc",
+ "pdf_compositor_client.h",
+ ]
+
+ public_deps = [
+ "//components/printing/service/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
+
+source_set("factory") {
+ sources = [
+ "pdf_compositor_service_factory.cc",
+ "pdf_compositor_service_factory.h",
+ ]
+
+ deps = [
+ "//components/printing/service/",
+ "//content/public/common",
+ "//content/public/utility",
+ ]
+
+ public_deps = [
+ "//components/printing/service/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/printing/service/public/cpp/pdf_compositor_client.cc b/chromium/components/printing/service/public/cpp/pdf_compositor_client.cc
new file mode 100644
index 00000000000..51aaa560bc6
--- /dev/null
+++ b/chromium/components/printing/service/public/cpp/pdf_compositor_client.cc
@@ -0,0 +1,58 @@
+// Copyright 2017 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/printing/service/public/cpp/pdf_compositor_client.h"
+
+#include <utility>
+
+#include "mojo/public/cpp/system/platform_handle.h"
+
+namespace printing {
+
+namespace {
+
+// Helper callback which owns an PdfCompositorPtr until invoked. This keeps the
+// PdfCompositor pipe open just long enough to dispatch a reply, at which point
+// the reply is forwarded to the wrapped |callback|.
+void OnCompositePdf(
+ printing::mojom::PdfCompositorPtr compositor,
+ printing::mojom::PdfCompositor::CompositePdfCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ mojo::ScopedSharedBufferHandle pdf_handle) {
+ task_runner->PostTask(FROM_HERE, base::BindOnce(std::move(callback),
+ base::Passed(&pdf_handle)));
+}
+
+} // namespace
+
+PdfCompositorClient::PdfCompositorClient() : compositor_(nullptr) {}
+
+PdfCompositorClient::~PdfCompositorClient() {}
+
+void PdfCompositorClient::Connect(service_manager::Connector* connector) {
+ DCHECK(!compositor_.is_bound());
+ connector->BindInterface(mojom::kServiceName, &compositor_);
+}
+
+void PdfCompositorClient::Composite(
+ service_manager::Connector* connector,
+ base::SharedMemoryHandle handle,
+ size_t data_size,
+ mojom::PdfCompositor::CompositePdfCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner) {
+ DCHECK(data_size);
+
+ if (!compositor_)
+ Connect(connector);
+
+ mojo::ScopedSharedBufferHandle buffer_handle =
+ mojo::WrapSharedMemoryHandle(handle, data_size, true);
+
+ compositor_->CompositePdf(
+ std::move(buffer_handle),
+ base::BindOnce(&OnCompositePdf, base::Passed(&compositor_),
+ std::move(callback), callback_task_runner));
+}
+
+} // namespace printing
diff --git a/chromium/components/printing/service/public/cpp/pdf_compositor_client.h b/chromium/components/printing/service/public/cpp/pdf_compositor_client.h
new file mode 100644
index 00000000000..d3d8c29b866
--- /dev/null
+++ b/chromium/components/printing/service/public/cpp/pdf_compositor_client.h
@@ -0,0 +1,38 @@
+// Copyright 2017 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_PRINTING_SERVICE_PUBLIC_CPP_PDF_COMPOSITOR_CLIENT_H_
+#define COMPONENTS_PRINTING_SERVICE_PUBLIC_CPP_PDF_COMPOSITOR_CLIENT_H_
+
+#include "base/memory/shared_memory_handle.h"
+#include "components/printing/service/public/interfaces/pdf_compositor.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace printing {
+
+// Helper class to composite a pdf via the pdf_compositor service.
+class PdfCompositorClient {
+ public:
+ PdfCompositorClient();
+ ~PdfCompositorClient();
+
+ // Composite the final picture and convert into a PDF file.
+ void Composite(service_manager::Connector* connector,
+ base::SharedMemoryHandle handle,
+ size_t data_size,
+ mojom::PdfCompositor::CompositePdfCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner);
+
+ private:
+ // Connect to the service.
+ void Connect(service_manager::Connector* connector);
+
+ mojom::PdfCompositorPtr compositor_;
+
+ DISALLOW_COPY_AND_ASSIGN(PdfCompositorClient);
+};
+
+} // namespace printing
+
+#endif // COMPONENTS_PRINTING_SERVICE_PUBLIC_CPP_PDF_COMPOSITOR_CLIENT_H_
diff --git a/chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.cc b/chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.cc
new file mode 100644
index 00000000000..f832f860313
--- /dev/null
+++ b/chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.cc
@@ -0,0 +1,23 @@
+// Copyright 2017 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/printing/service/public/cpp/pdf_compositor_service_factory.h"
+
+#include "components/printing/service/pdf_compositor_service.h"
+#include "content/public/utility/utility_thread.h"
+#include "third_party/WebKit/public/platform/WebImageGenerator.h"
+#include "third_party/skia/include/core/SkGraphics.h"
+
+namespace printing {
+
+std::unique_ptr<service_manager::Service> CreatePdfCompositorService(
+ const std::string& creator) {
+ content::UtilityThread::Get()->EnsureBlinkInitialized();
+ // Hook up blink's codecs so skia can call them.
+ SkGraphics::SetImageGeneratorFromEncodedDataFactory(
+ blink::WebImageGenerator::Create);
+ return printing::PdfCompositorService::Create(creator);
+}
+
+} // namespace printing
diff --git a/chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.h b/chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.h
new file mode 100644
index 00000000000..10d06bab09b
--- /dev/null
+++ b/chromium/components/printing/service/public/cpp/pdf_compositor_service_factory.h
@@ -0,0 +1,20 @@
+// Copyright 2017 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_PRINTING_SERVICE_PUBLIC_CPP_PDF_COMPOSITOR_SERVICE_FACTORY_H_
+#define COMPONENTS_PRINTING_SERVICE_PUBLIC_CPP_PDF_COMPOSITOR_SERVICE_FACTORY_H_
+
+#include <memory>
+#include <string>
+
+#include "services/service_manager/public/cpp/service.h"
+
+namespace printing {
+
+std::unique_ptr<service_manager::Service> CreatePdfCompositorService(
+ const std::string& creator);
+
+} // namespace printing
+
+#endif // COMPONENTS_PRINTING_SERVICE_PUBLIC_CPP_PDF_COMPOSITOR_SERVICE_FACTORY_H_
diff --git a/chromium/components/printing/service/public/interfaces/BUILD.gn b/chromium/components/printing/service/public/interfaces/BUILD.gn
new file mode 100644
index 00000000000..1efdb19418d
--- /dev/null
+++ b/chromium/components/printing/service/public/interfaces/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2017 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+ sources = [
+ "pdf_compositor.mojom",
+ ]
+}
diff --git a/chromium/components/printing/service/public/interfaces/OWNERS b/chromium/components/printing/service/public/interfaces/OWNERS
new file mode 100644
index 00000000000..08850f42120
--- /dev/null
+++ b/chromium/components/printing/service/public/interfaces/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/printing/service/public/interfaces/pdf_compositor.mojom b/chromium/components/printing/service/public/interfaces/pdf_compositor.mojom
new file mode 100644
index 00000000000..67f9448d947
--- /dev/null
+++ b/chromium/components/printing/service/public/interfaces/pdf_compositor.mojom
@@ -0,0 +1,16 @@
+// Copyright 2017 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.
+
+module printing.mojom;
+
+const string kServiceName = "pdf_compositor";
+
+// TODO(weili): Add support for printing frames from different processes.
+interface PdfCompositor {
+ // Currently directly convert passed in page data to a PDF file.
+ // |sk_handle| points to a buffer of a Skia MultiPictureDocument.
+ // |pdf_handle| points to the generated PDF file buffer.
+ CompositePdf(handle<shared_buffer> sk_handle)
+ => (handle<shared_buffer> pdf_handle);
+};
diff --git a/chromium/components/profile_metrics/OWNERS b/chromium/components/profile_metrics/OWNERS
index e43d48c20d7..eccc04a101f 100644
--- a/chromium/components/profile_metrics/OWNERS
+++ b/chromium/components/profile_metrics/OWNERS
@@ -1,5 +1,4 @@
anthonyvd@chromium.org
erg@chromium.org
-mlerman@chromium.org
# COMPONENT: UI>Browser>Profiles
diff --git a/chromium/components/proximity_auth/BUILD.gn b/chromium/components/proximity_auth/BUILD.gn
index 54800b9cb80..3f4a2a4bf9a 100644
--- a/chromium/components/proximity_auth/BUILD.gn
+++ b/chromium/components/proximity_auth/BUILD.gn
@@ -10,6 +10,10 @@ static_library("proximity_auth") {
"bluetooth_connection.h",
"bluetooth_connection_finder.cc",
"bluetooth_connection_finder.h",
+ "bluetooth_low_energy_connection_finder.cc",
+ "bluetooth_low_energy_connection_finder.h",
+ "bluetooth_low_energy_setup_connection_finder.cc",
+ "bluetooth_low_energy_setup_connection_finder.h",
"bluetooth_util.cc",
"bluetooth_util.h",
"bluetooth_util_chromeos.cc",
@@ -52,18 +56,12 @@ static_library("proximity_auth") {
"//components/cryptauth",
"//components/cryptauth/ble",
"//components/prefs",
- "//components/proximity_auth/ble",
"//components/proximity_auth/logging",
"//components/signin/core/account_id:account_id",
"//device/bluetooth",
"//net",
]
- # TODO(https://crbug.com/562683): This whitelists a circular include
- # dependency between this target and the following targets which should not
- # exist.
- allow_circular_includes_from = [ "//components/proximity_auth/ble" ]
-
if (is_chromeos) {
deps += [ "//chromeos" ]
}
@@ -98,6 +96,7 @@ source_set("unit_tests") {
sources = [
"bluetooth_connection_finder_unittest.cc",
"bluetooth_connection_unittest.cc",
+ "bluetooth_low_energy_connection_finder_unittest.cc",
"messenger_impl_unittest.cc",
"proximity_auth_pref_manager_unittest.cc",
"proximity_auth_system_unittest.cc",
@@ -117,8 +116,8 @@ source_set("unit_tests") {
"//base/test:test_support",
"//components/cryptauth:test_support",
"//components/cryptauth:unit_tests",
+ "//components/cryptauth/ble",
"//components/prefs:test_support",
- "//components/proximity_auth/ble:unit_tests",
"//components/proximity_auth/logging",
"//components/proximity_auth/logging:unit_tests",
"//device/bluetooth:mocks",
diff --git a/chromium/components/proximity_auth/ble/BUILD.gn b/chromium/components/proximity_auth/ble/BUILD.gn
deleted file mode 100644
index 4641f5ab74f..00000000000
--- a/chromium/components/proximity_auth/ble/BUILD.gn
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2014 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.
-
-import("//testing/test.gni")
-
-static_library("ble") {
- sources = [
- "bluetooth_low_energy_connection.cc",
- "bluetooth_low_energy_connection.h",
- "bluetooth_low_energy_connection_finder.cc",
- "bluetooth_low_energy_connection_finder.h",
- "bluetooth_low_energy_device_whitelist.cc",
- "bluetooth_low_energy_device_whitelist.h",
- "pref_names.cc",
- "pref_names.h",
- ]
-
- deps = [
- "//base",
- "//components/cryptauth",
- "//components/cryptauth/ble",
- "//components/prefs",
- "//components/proximity_auth/logging",
-
- # TODO(https://crbug.com/562683): This component has a circular dependency
- # with the root proximity auth target. It is whitelisted in that target for
- # includes.
- #"//components/proximity_auth",
- "//device/bluetooth",
- "//net",
- ]
-
- public_deps = [
- "//components/cryptauth/proto",
- ]
-}
-
-source_set("unit_tests") {
- testonly = true
- sources = [
- "bluetooth_low_energy_connection_finder_unittest.cc",
- "bluetooth_low_energy_connection_unittest.cc",
- "bluetooth_low_energy_device_whitelist_unittest.cc",
- ]
-
- configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
- deps = [
- ":ble",
- "//base/test:test_support",
- "//components/cryptauth",
- "//components/cryptauth:test_support",
- "//components/cryptauth/ble:ble",
- "//components/prefs:test_support",
- "//components/proximity_auth:test_support",
- "//device/bluetooth:mocks",
- "//testing/gmock",
- "//testing/gtest",
- ]
-
- public_deps = [
- "//components/cryptauth/proto",
- ]
-}
diff --git a/chromium/components/proximity_auth/webui/BUILD.gn b/chromium/components/proximity_auth/webui/BUILD.gn
index 54ff59e0879..6220af6fe0f 100644
--- a/chromium/components/proximity_auth/webui/BUILD.gn
+++ b/chromium/components/proximity_auth/webui/BUILD.gn
@@ -20,7 +20,6 @@ static_library("webui") {
"//components/cryptauth",
"//components/prefs",
"//components/proximity_auth",
- "//components/proximity_auth/ble",
"//components/proximity_auth/logging",
"//components/resources",
"//content/public/browser",
diff --git a/chromium/components/proxy_config/ios/BUILD.gn b/chromium/components/proxy_config/ios/BUILD.gn
new file mode 100644
index 00000000000..aafa2d3e816
--- /dev/null
+++ b/chromium/components/proxy_config/ios/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2017 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.
+
+component("ios") {
+ configs += [ "//build/config/compiler:enable_arc" ]
+
+ deps = [
+ "//base",
+ "//components/proxy_config",
+ "//ios/web",
+ "//net",
+ ]
+
+ sources = [
+ "proxy_service_factory.cc",
+ "proxy_service_factory.h",
+ ]
+}
diff --git a/chromium/components/proxy_config/ios/DEPS b/chromium/components/proxy_config/ios/DEPS
new file mode 100644
index 00000000000..c11101cf81b
--- /dev/null
+++ b/chromium/components/proxy_config/ios/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+ "+ios/public/provider/web",
+ "+ios/web/public",
+ "+net/proxy"
+]
diff --git a/chromium/components/proxy_config/ios/proxy_service_factory.cc b/chromium/components/proxy_config/ios/proxy_service_factory.cc
new file mode 100644
index 00000000000..600191ae7f8
--- /dev/null
+++ b/chromium/components/proxy_config/ios/proxy_service_factory.cc
@@ -0,0 +1,57 @@
+// Copyright 2015 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/proxy_config/ios/proxy_service_factory.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "ios/web/public/web_thread.h"
+#include "net/proxy/proxy_config_service.h"
+#include "net/proxy/proxy_service.h"
+
+// static
+std::unique_ptr<net::ProxyConfigService>
+ProxyServiceFactory::CreateProxyConfigService(PrefProxyConfigTracker* tracker) {
+ std::unique_ptr<net::ProxyConfigService> base_service(
+ net::ProxyService::CreateSystemProxyConfigService(
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::IO),
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE)));
+ return tracker->CreateTrackingProxyConfigService(std::move(base_service));
+}
+
+// static
+std::unique_ptr<PrefProxyConfigTracker>
+ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+ PrefService* browser_state_prefs,
+ PrefService* local_state_prefs) {
+ return base::MakeUnique<PrefProxyConfigTrackerImpl>(
+ browser_state_prefs,
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::IO));
+}
+
+// static
+std::unique_ptr<PrefProxyConfigTracker>
+ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+ PrefService* local_state_prefs) {
+ return base::MakeUnique<PrefProxyConfigTrackerImpl>(
+ local_state_prefs,
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::IO));
+}
+
+// static
+std::unique_ptr<net::ProxyService> ProxyServiceFactory::CreateProxyService(
+ net::NetLog* net_log,
+ net::URLRequestContext* context,
+ net::NetworkDelegate* network_delegate,
+ std::unique_ptr<net::ProxyConfigService> proxy_config_service,
+ bool quick_check_enabled) {
+ DCHECK_CURRENTLY_ON(web::WebThread::IO);
+ std::unique_ptr<net::ProxyService> proxy_service(
+ net::ProxyService::CreateUsingSystemProxyResolver(
+ std::move(proxy_config_service), net_log));
+ proxy_service->set_quick_check_enabled(quick_check_enabled);
+ return proxy_service;
+}
diff --git a/chromium/components/proxy_config/ios/proxy_service_factory.h b/chromium/components/proxy_config/ios/proxy_service_factory.h
new file mode 100644
index 00000000000..dfa00ca542e
--- /dev/null
+++ b/chromium/components/proxy_config/ios/proxy_service_factory.h
@@ -0,0 +1,52 @@
+// Copyright 2015 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_PROXY_CONFIG_IOS_PROXY_SERVICE_FACTORY_H_
+#define COMPONENTS_PROXY_CONFIG_IOS_PROXY_SERVICE_FACTORY_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "components/proxy_config/proxy_config_export.h"
+
+class PrefProxyConfigTracker;
+class PrefService;
+
+namespace net {
+class NetLog;
+class NetworkDelegate;
+class ProxyConfigService;
+class ProxyService;
+class URLRequestContext;
+}
+
+class PROXY_CONFIG_EXPORT ProxyServiceFactory {
+ public:
+ // Creates a ProxyConfigService that delivers the system preferences.
+ static std::unique_ptr<net::ProxyConfigService> CreateProxyConfigService(
+ PrefProxyConfigTracker* tracker);
+
+ // Creates a PrefProxyConfigTracker that tracks browser state preferences.
+ static std::unique_ptr<PrefProxyConfigTracker>
+ CreatePrefProxyConfigTrackerOfProfile(PrefService* browser_state_prefs,
+ PrefService* local_state_prefs);
+
+ // Creates a PrefProxyConfigTracker that tracks local state only. This tracker
+ // should be used for the system request context.
+ static std::unique_ptr<PrefProxyConfigTracker>
+ CreatePrefProxyConfigTrackerOfLocalState(PrefService* local_state_prefs);
+
+ // Create a proxy service.
+ static std::unique_ptr<net::ProxyService> CreateProxyService(
+ net::NetLog* net_log,
+ net::URLRequestContext* context,
+ net::NetworkDelegate* network_delegate,
+ std::unique_ptr<net::ProxyConfigService> proxy_config_service,
+ bool quick_check_enabled);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProxyServiceFactory);
+};
+
+#endif // COMPONENTS_PROXY_CONFIG_IOS_PROXY_SERVICE_FACTORY_H_
diff --git a/chromium/components/rappor/log_uploader_unittest.cc b/chromium/components/rappor/log_uploader_unittest.cc
index 8858203e270..346e6bca6aa 100644
--- a/chromium/components/rappor/log_uploader_unittest.cc
+++ b/chromium/components/rappor/log_uploader_unittest.cc
@@ -7,6 +7,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
@@ -60,13 +61,15 @@ class TestLogUploader : public LogUploader {
class LogUploaderTest : public testing::Test {
public:
LogUploaderTest()
- : request_context_(new net::TestURLRequestContextGetter(
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ request_context_(new net::TestURLRequestContextGetter(
base::ThreadTaskRunnerHandle::Get())),
factory_(NULL) {}
protected:
// Required for base::ThreadTaskRunnerHandle::Get().
- base::MessageLoopForUI loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_;
net::FakeURLFetcherFactory factory_;
diff --git a/chromium/components/rappor/rappor_recorder_impl.cc b/chromium/components/rappor/rappor_recorder_impl.cc
index 805e2fdca9b..4a2a23d3d78 100644
--- a/chromium/components/rappor/rappor_recorder_impl.cc
+++ b/chromium/components/rappor/rappor_recorder_impl.cc
@@ -17,8 +17,10 @@ RapporRecorderImpl::RapporRecorderImpl(RapporServiceImpl* rappor_service)
RapporRecorderImpl::~RapporRecorderImpl() = default;
// static
-void RapporRecorderImpl::Create(RapporServiceImpl* rappor_service,
- mojom::RapporRecorderRequest request) {
+void RapporRecorderImpl::Create(
+ RapporServiceImpl* rappor_service,
+ const service_manager::BindSourceInfo& source_info,
+ mojom::RapporRecorderRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<RapporRecorderImpl>(rappor_service),
std::move(request));
}
diff --git a/chromium/components/rappor/rappor_recorder_impl.h b/chromium/components/rappor/rappor_recorder_impl.h
index 103b4cd0358..c6da8a9d25d 100644
--- a/chromium/components/rappor/rappor_recorder_impl.h
+++ b/chromium/components/rappor/rappor_recorder_impl.h
@@ -10,6 +10,10 @@
class GURL;
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace rappor {
class RapporServiceImpl;
@@ -22,6 +26,7 @@ class RapporRecorderImpl : public mojom::RapporRecorder {
~RapporRecorderImpl() override;
static void Create(RapporServiceImpl* rappor_service,
+ const service_manager::BindSourceInfo& source_info,
mojom::RapporRecorderRequest request);
private:
diff --git a/chromium/components/reading_list/core/reading_list_entry.h b/chromium/components/reading_list/core/reading_list_entry.h
index 878278b71e2..d0f74512381 100644
--- a/chromium/components/reading_list/core/reading_list_entry.h
+++ b/chromium/components/reading_list/core/reading_list_entry.h
@@ -92,7 +92,7 @@ class ReadingListEntry {
// The URL that has been distilled to produce file stored at |DistilledPath|.
const GURL& DistilledURL() const;
// The time distillation was done. The value is in microseconds since Jan 1st
- // 1970.
+ // 1970. Returns 0 if the entry was not distilled.
int64_t DistillationTime() const;
// The size of the stored page in bytes.
int64_t DistillationSize() const;
diff --git a/chromium/components/reading_list/core/reading_list_model_impl.cc b/chromium/components/reading_list/core/reading_list_model_impl.cc
index d1ed193f0b5..92713dbd2cf 100644
--- a/chromium/components/reading_list/core/reading_list_model_impl.cc
+++ b/chromium/components/reading_list/core/reading_list_model_impl.cc
@@ -57,7 +57,7 @@ void ReadingListModelImpl::StoreLoaded(
void ReadingListModelImpl::Shutdown() {
DCHECK(CalledOnValidThread());
for (auto& observer : observers_)
- observer.ReadingListModelBeingDeleted(this);
+ observer.ReadingListModelBeingShutdown(this);
loaded_ = false;
}
diff --git a/chromium/components/reading_list/core/reading_list_model_observer.h b/chromium/components/reading_list/core/reading_list_model_observer.h
index 061d1cc3ac9..a0ad2bf3951 100644
--- a/chromium/components/reading_list/core/reading_list_model_observer.h
+++ b/chromium/components/reading_list/core/reading_list_model_observer.h
@@ -32,6 +32,9 @@ class ReadingListModelObserver {
virtual void ReadingListModelCompletedBatchUpdates(
const ReadingListModel* model) {}
+ // Invoked before the destruction of the model.
+ virtual void ReadingListModelBeingShutdown(const ReadingListModel* model) {}
+
// Invoked from the destructor of the model. The model is no longer valid
// after this call. There is no need to call RemoveObserver on the model from
// here, as the observers are automatically deleted.
diff --git a/chromium/components/reading_list/core/reading_list_model_unittest.cc b/chromium/components/reading_list/core/reading_list_model_unittest.cc
index a2b2b57fe46..c79a63578dc 100644
--- a/chromium/components/reading_list/core/reading_list_model_unittest.cc
+++ b/chromium/components/reading_list/core/reading_list_model_unittest.cc
@@ -314,6 +314,9 @@ TEST_F(ReadingListModelTest, EmptyLoaded) {
EXPECT_EQ(0ul, ReadSize());
model_->Shutdown();
EXPECT_FALSE(model_->loaded());
+ // Shutdown() does not delete the model observer. Verify that deleting the
+ // model will delete the model observer.
+ model_.reset();
AssertObserverCount(1, 0, 0, 1, 0, 0, 0, 0, 0);
}
diff --git a/chromium/components/reading_list/ios/reading_list_model_bridge_observer.h b/chromium/components/reading_list/ios/reading_list_model_bridge_observer.h
index 9b34e4939dd..33a433ec5b2 100644
--- a/chromium/components/reading_list/ios/reading_list_model_bridge_observer.h
+++ b/chromium/components/reading_list/ios/reading_list_model_bridge_observer.h
@@ -36,6 +36,7 @@
- (void)readingListModelBeganBatchUpdates:(const ReadingListModel*)model;
- (void)readingListModelCompletedBatchUpdates:(const ReadingListModel*)model;
+- (void)readingListModelBeingShutdown:(const ReadingListModel*)model;
- (void)readingListModelBeingDeleted:(const ReadingListModel*)model;
- (void)readingListModel:(const ReadingListModel*)model
@@ -58,6 +59,7 @@ class ReadingListModelBridge : public ReadingListModelObserver {
void ReadingListModelCompletedBatchUpdates(
const ReadingListModel* model) override;
void ReadingListModelLoaded(const ReadingListModel* model) override;
+ void ReadingListModelBeingShutdown(const ReadingListModel* model) override;
void ReadingListModelBeingDeleted(const ReadingListModel* model) override;
void ReadingListWillRemoveEntry(const ReadingListModel* model,
const GURL& url) override;
diff --git a/chromium/components/reading_list/ios/reading_list_model_bridge_observer.mm b/chromium/components/reading_list/ios/reading_list_model_bridge_observer.mm
index f295c7fdf63..a54a1a471f1 100644
--- a/chromium/components/reading_list/ios/reading_list_model_bridge_observer.mm
+++ b/chromium/components/reading_list/ios/reading_list_model_bridge_observer.mm
@@ -26,6 +26,14 @@ void ReadingListModelBridge::ReadingListModelLoaded(
[observer_ readingListModelLoaded:model];
}
+void ReadingListModelBridge::ReadingListModelBeingShutdown(
+ const ReadingListModel* model) {
+ if ([observer_
+ respondsToSelector:@selector(readingListModelBeingShutdown:)]) {
+ [observer_ readingListModelBeingShutdown:model];
+ }
+}
+
void ReadingListModelBridge::ReadingListModelBeingDeleted(
const ReadingListModel* model) {
if ([observer_ respondsToSelector:@selector(readingListModelBeingDeleted:)]) {
diff --git a/chromium/components/renderer_context_menu/context_menu_delegate.cc b/chromium/components/renderer_context_menu/context_menu_delegate.cc
index e9fbd97e488..07f74f2358d 100644
--- a/chromium/components/renderer_context_menu/context_menu_delegate.cc
+++ b/chromium/components/renderer_context_menu/context_menu_delegate.cc
@@ -4,6 +4,7 @@
#include "components/renderer_context_menu/context_menu_delegate.h"
+#include "base/memory/ptr_util.h"
#include "content/public/browser/web_contents.h"
namespace {
@@ -24,8 +25,9 @@ class ContextMenuDelegateUserData : public base::SupportsUserData::Data {
} // namespace
ContextMenuDelegate::ContextMenuDelegate(content::WebContents* web_contents) {
- web_contents->SetUserData(&kMenuDelegateUserDataKey,
- new ContextMenuDelegateUserData(this));
+ web_contents->SetUserData(
+ &kMenuDelegateUserDataKey,
+ base::MakeUnique<ContextMenuDelegateUserData>(this));
}
ContextMenuDelegate::~ContextMenuDelegate() {
diff --git a/chromium/components/renderer_context_menu/views/toolkit_delegate_views.cc b/chromium/components/renderer_context_menu/views/toolkit_delegate_views.cc
index 81dfe55f560..1e5357c08de 100644
--- a/chromium/components/renderer_context_menu/views/toolkit_delegate_views.cc
+++ b/chromium/components/renderer_context_menu/views/toolkit_delegate_views.cc
@@ -22,17 +22,16 @@ void ToolkitDelegateViews::RunMenuAt(views::Widget* parent,
type == ui::MENU_SOURCE_TOUCH_EDIT_MENU)
? views::MENU_ANCHOR_BOTTOMCENTER
: views::MENU_ANCHOR_TOPLEFT;
- ignore_result(menu_runner_->RunMenuAt(
- parent, NULL, gfx::Rect(point, gfx::Size()), anchor_position, type));
+ menu_runner_->RunMenuAt(parent, NULL, gfx::Rect(point, gfx::Size()),
+ anchor_position, type);
}
void ToolkitDelegateViews::Init(ui::SimpleMenuModel* menu_model) {
menu_adapter_.reset(new views::MenuModelAdapter(menu_model));
menu_view_ = menu_adapter_->CreateMenu();
- menu_runner_.reset(
- new views::MenuRunner(menu_view_, views::MenuRunner::HAS_MNEMONICS |
- views::MenuRunner::CONTEXT_MENU |
- views::MenuRunner::ASYNC));
+ menu_runner_.reset(new views::MenuRunner(
+ menu_view_,
+ views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU));
}
void ToolkitDelegateViews::Cancel() {
diff --git a/chromium/components/resources/BUILD.gn b/chromium/components/resources/BUILD.gn
index 6ead4c71c74..af21090adf5 100644
--- a/chromium/components/resources/BUILD.gn
+++ b/chromium/components/resources/BUILD.gn
@@ -31,7 +31,10 @@ grit("components_resources") {
"-E",
"about_credits_file=" + rebase_path(about_credits_file_bro, root_build_dir),
]
- defines = [ "enable_print_preview=$enable_print_preview" ]
+ defines = [
+ "enable_basic_printing=$enable_basic_printing",
+ "enable_print_preview=$enable_print_preview",
+ ]
deps = [
":compressed_about_credits",
diff --git a/chromium/components/resources/OWNERS b/chromium/components/resources/OWNERS
index 6b8b3768a21..f846201c619 100644
--- a/chromium/components/resources/OWNERS
+++ b/chromium/components/resources/OWNERS
@@ -1,4 +1,4 @@
-per-file autofill_scaled_resources.grdp=estade@chromium.org
+per-file autofill_scaled_resources.grdp=mathp@chromium.org
per-file content_suggestions*=file://components/ntp_snippets/OWNERS
per-file crash_*=cpu@chromium.org
per-file crash_*=jochen@chromium.org
@@ -19,7 +19,9 @@ per-file neterror*=juliatuttle@chromium.org
per-file neterror*=mmenke@chromium.org
per-file ntp_tiles_resources.grdp=file://components/ntp_tiles/OWNERS
per-file proximity_auth*=tengs@chromium.org
+per-file security_interstitials_resources.grdp=file://components/security_interstitials/OWNERS
per-file supervised_user_error_page.grpd=file://components/supervised_user_error_page/OWNERS
+per-file sync_driver_resources.grdp=file:components/sync/OWNERS
per-file version_ui*=achuith@chromium.org
per-file version_ui*=bauerb@chromium.org
per-file version_ui*=dbeam@chromium.org
diff --git a/chromium/components/resources/autofill_scaled_resources.grdp b/chromium/components/resources/autofill_scaled_resources.grdp
index 53b5a22a4b5..f4c1b62483d 100644
--- a/chromium/components/resources/autofill_scaled_resources.grdp
+++ b/chromium/components/resources/autofill_scaled_resources.grdp
@@ -3,10 +3,12 @@
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_AMEX" file="autofill/amex.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_DINERS" file="autofill/diners.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_DISCOVER" file="autofill/discover.png" />
+ <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_ELO" file="autofill/elo.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_GENERIC" file="autofill/cc-generic.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_JCB" file="autofill/jcb.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_MASTERCARD" file="autofill/mastercard.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_MIR" file="autofill/mir.png" />
+ <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_UNIONPAY" file="autofill/unionpay.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_VISA" file="autofill/visa.png" />
<!-- These are not used on desktop, only Android, so use a placeholder file.
@@ -16,21 +18,11 @@
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_SCAN_NEW" file="autofill/cc-generic.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_SCAN_NEW_KEYBOARD_ACCESSORY" file="autofill/cc-generic.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_SETTINGS" file="autofill/cc-generic.png" />
+ <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CREATE" file="autofill/cc-generic.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_HTTP_WARNING" file="autofill/cc-generic.png" />
<structure type="chrome_scaled_image" name="IDR_AUTOFILL_HTTPS_INVALID_WARNING" file="autofill/cc-generic.png" />
</if>
- <!-- PaymentRequest image variants. -->
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_AMEX" file="autofill/pr_amex.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_DINERS" file="autofill/pr_dinersclub.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_DISCOVER" file="autofill/pr_discover.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_GENERIC" file="autofill/pr_generic.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_JCB" file="autofill/pr_jcb.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_MASTERCARD" file="autofill/pr_mc.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_MIR" file="autofill/pr_mir.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_UNIONPAY" file="autofill/pr_unionpay.png" />
- <structure type="chrome_scaled_image" name="IDR_AUTOFILL_PR_VISA" file="autofill/pr_visa.png" />
-
<structure type="chrome_scaled_image" name="IDR_CREDIT_CARD_CVC_HINT" file="autofill/credit_card_cvc_hint.png" />
<structure type="chrome_scaled_image" name="IDR_CREDIT_CARD_CVC_HINT_AMEX" file="autofill/credit_card_cvc_hint_amex.png" />
<if expr="is_ios or is_android">
diff --git a/chromium/components/resources/default_100_percent/autofill/amex.png b/chromium/components/resources/default_100_percent/autofill/amex.png
index c441aff0f44..d012783cf25 100644
--- a/chromium/components/resources/default_100_percent/autofill/amex.png
+++ b/chromium/components/resources/default_100_percent/autofill/amex.png
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/elo.png b/chromium/components/resources/default_100_percent/autofill/elo.png
new file mode 100644
index 00000000000..346d0f40369
--- /dev/null
+++ b/chromium/components/resources/default_100_percent/autofill/elo.png
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/mir.png b/chromium/components/resources/default_100_percent/autofill/mir.png
index c9b3e79a841..2e094f4f6f9 100644
--- a/chromium/components/resources/default_100_percent/autofill/mir.png
+++ b/chromium/components/resources/default_100_percent/autofill/mir.png
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_amex.png b/chromium/components/resources/default_100_percent/autofill/pr_amex.png
deleted file mode 100644
index 67dfb96f3f8..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_amex.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_dinersclub.png b/chromium/components/resources/default_100_percent/autofill/pr_dinersclub.png
deleted file mode 100644
index a3446c40d75..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_dinersclub.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_discover.png b/chromium/components/resources/default_100_percent/autofill/pr_discover.png
deleted file mode 100644
index c6e04e9929e..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_discover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_generic.png b/chromium/components/resources/default_100_percent/autofill/pr_generic.png
deleted file mode 100644
index a93ff32d21e..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_generic.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_jcb.png b/chromium/components/resources/default_100_percent/autofill/pr_jcb.png
deleted file mode 100644
index 66495ce5106..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_jcb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_mc.png b/chromium/components/resources/default_100_percent/autofill/pr_mc.png
deleted file mode 100644
index bcdf48f0272..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_mc.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_mir.png b/chromium/components/resources/default_100_percent/autofill/pr_mir.png
deleted file mode 100644
index fc97556f02f..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_mir.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_unionpay.png b/chromium/components/resources/default_100_percent/autofill/pr_unionpay.png
deleted file mode 100644
index 0e11c0f97f3..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_unionpay.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/pr_visa.png b/chromium/components/resources/default_100_percent/autofill/pr_visa.png
deleted file mode 100644
index c0c8c08201e..00000000000
--- a/chromium/components/resources/default_100_percent/autofill/pr_visa.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_100_percent/autofill/unionpay.png b/chromium/components/resources/default_100_percent/autofill/unionpay.png
new file mode 100644
index 00000000000..e0ab343c7d3
--- /dev/null
+++ b/chromium/components/resources/default_100_percent/autofill/unionpay.png
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/amex.png b/chromium/components/resources/default_200_percent/autofill/amex.png
index 7a417d5a26a..a9749749272 100644
--- a/chromium/components/resources/default_200_percent/autofill/amex.png
+++ b/chromium/components/resources/default_200_percent/autofill/amex.png
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/elo.png b/chromium/components/resources/default_200_percent/autofill/elo.png
new file mode 100644
index 00000000000..ba88605913a
--- /dev/null
+++ b/chromium/components/resources/default_200_percent/autofill/elo.png
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/mir.png b/chromium/components/resources/default_200_percent/autofill/mir.png
index 9aaa05def04..02fc43cae1d 100644
--- a/chromium/components/resources/default_200_percent/autofill/mir.png
+++ b/chromium/components/resources/default_200_percent/autofill/mir.png
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_amex.png b/chromium/components/resources/default_200_percent/autofill/pr_amex.png
deleted file mode 100644
index f29dcdf57e1..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_amex.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_dinersclub.png b/chromium/components/resources/default_200_percent/autofill/pr_dinersclub.png
deleted file mode 100644
index c61096b0c69..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_dinersclub.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_discover.png b/chromium/components/resources/default_200_percent/autofill/pr_discover.png
deleted file mode 100644
index 6d8f2ff285b..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_discover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_generic.png b/chromium/components/resources/default_200_percent/autofill/pr_generic.png
deleted file mode 100644
index 8dd4609eb86..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_generic.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_jcb.png b/chromium/components/resources/default_200_percent/autofill/pr_jcb.png
deleted file mode 100644
index 2a18c032176..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_jcb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_mc.png b/chromium/components/resources/default_200_percent/autofill/pr_mc.png
deleted file mode 100644
index ade774b868f..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_mc.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_mir.png b/chromium/components/resources/default_200_percent/autofill/pr_mir.png
deleted file mode 100644
index 1b9e53300b2..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_mir.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_unionpay.png b/chromium/components/resources/default_200_percent/autofill/pr_unionpay.png
deleted file mode 100644
index 33f62de69f6..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_unionpay.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/pr_visa.png b/chromium/components/resources/default_200_percent/autofill/pr_visa.png
deleted file mode 100644
index 493c2ab6edb..00000000000
--- a/chromium/components/resources/default_200_percent/autofill/pr_visa.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_200_percent/autofill/unionpay.png b/chromium/components/resources/default_200_percent/autofill/unionpay.png
new file mode 100644
index 00000000000..7838060439c
--- /dev/null
+++ b/chromium/components/resources/default_200_percent/autofill/unionpay.png
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_amex.png b/chromium/components/resources/default_300_percent/autofill/pr_amex.png
deleted file mode 100644
index 318ec6584c8..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_amex.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_dinersclub.png b/chromium/components/resources/default_300_percent/autofill/pr_dinersclub.png
deleted file mode 100644
index 87fa3c42834..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_dinersclub.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_discover.png b/chromium/components/resources/default_300_percent/autofill/pr_discover.png
deleted file mode 100644
index b8109ff2dd9..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_discover.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_generic.png b/chromium/components/resources/default_300_percent/autofill/pr_generic.png
deleted file mode 100644
index bda5b34dec9..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_generic.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_jcb.png b/chromium/components/resources/default_300_percent/autofill/pr_jcb.png
deleted file mode 100644
index d9919ef04f1..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_jcb.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_mc.png b/chromium/components/resources/default_300_percent/autofill/pr_mc.png
deleted file mode 100644
index 4cdd3a52986..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_mc.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_mir.png b/chromium/components/resources/default_300_percent/autofill/pr_mir.png
deleted file mode 100644
index 56934a40d76..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_mir.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_unionpay.png b/chromium/components/resources/default_300_percent/autofill/pr_unionpay.png
deleted file mode 100644
index fa1bd84cb1b..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_unionpay.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/default_300_percent/autofill/pr_visa.png b/chromium/components/resources/default_300_percent/autofill/pr_visa.png
deleted file mode 100644
index ef6aa8566ba..00000000000
--- a/chromium/components/resources/default_300_percent/autofill/pr_visa.png
+++ /dev/null
Binary files differ
diff --git a/chromium/components/resources/printing_resources.grdp b/chromium/components/resources/printing_resources.grdp
index 7213746453b..26e300c0496 100644
--- a/chromium/components/resources/printing_resources.grdp
+++ b/chromium/components/resources/printing_resources.grdp
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
- <if expr="enable_print_preview">
+ <if expr="enable_basic_printing or enable_print_preview">
<include name="IDR_PRINT_PREVIEW_PAGE" file="../printing/resources/print_preview_page.html" flattenhtml="true" allowexternalscript="false" type="BINDATA" />
</if>
</grit-part>
diff --git a/chromium/components/resources/security_interstitials_resources.grdp b/chromium/components/resources/security_interstitials_resources.grdp
index 907ef5fe0fc..2fb0f05ce92 100644
--- a/chromium/components/resources/security_interstitials_resources.grdp
+++ b/chromium/components/resources/security_interstitials_resources.grdp
@@ -2,4 +2,5 @@
<grit-part>
<include name="IDR_SECURITY_INTERSTITIAL_UI_HTML" file="../security_interstitials/core/browser/resources/interstitial_ui.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_SECURITY_INTERSTITIAL_HTML" file="../security_interstitials/core/browser/resources/interstitial_v2.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_SECURITY_INTERSTITIAL_QUIET_HTML" file="../security_interstitials/core/browser/resources/interstitial_webview_quiet.html" flattenhtml="true" type="BINDATA" />
</grit-part> \ No newline at end of file
diff --git a/chromium/components/resources/sync_driver_resources.grdp b/chromium/components/resources/sync_driver_resources.grdp
index 50c111814c0..bb00a51651d 100644
--- a/chromium/components/resources/sync_driver_resources.grdp
+++ b/chromium/components/resources/sync_driver_resources.grdp
@@ -3,12 +3,13 @@
<include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_HTML" file="../sync/driver/resources/index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_JS" file="../sync/driver/resources/sync_index.js" type="BINDATA" />
<include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_CHROME_SYNC_JS" file="../sync/driver/resources/chrome_sync.js" type="BINDATA" />
- <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TYPES_JS" file="../sync/driver/resources/types.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TYPES_JS" file="../sync/driver/resources/types.js" type="BINDATA" />
<include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_LOG_JS" file="../sync/driver/resources/sync_log.js" type="BINDATA" />
- <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="../sync/driver/resources/sync_node_browser.js" type="BINDATA" />
- <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_SEARCH_JS" file="../sync/driver/resources/sync_search.js" type="BINDATA" />
- <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_ABOUT_JS" file="../sync/driver/resources/about.js" type="BINDATA" />
- <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_DATA_JS" file="../sync/driver/resources/data.js" type="BINDATA" />
- <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_EVENTS_JS" file="../sync/driver/resources/events.js" type="BINDATA" />
- <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SEARCH_JS" file="../sync/driver/resources/search.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="../sync/driver/resources/sync_node_browser.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_SEARCH_JS" file="../sync/driver/resources/sync_search.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_ABOUT_JS" file="../sync/driver/resources/about.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_DATA_JS" file="../sync/driver/resources/data.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_EVENTS_JS" file="../sync/driver/resources/events.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SEARCH_JS" file="../sync/driver/resources/search.js" type="BINDATA" />
+ <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_USER_EVENTS_JS" file="../sync/driver/resources/user_events.js" type="BINDATA" />
</grit-part>
diff --git a/chromium/components/safe_browsing/BUILD.gn b/chromium/components/safe_browsing/BUILD.gn
index ff80235e0f2..06bf6321c2c 100644
--- a/chromium/components/safe_browsing/BUILD.gn
+++ b/chromium/components/safe_browsing/BUILD.gn
@@ -24,11 +24,10 @@ source_set("safe_browsing") {
":base_ping_manager",
"//base:base",
"//base:i18n",
+ "//components/safe_browsing/common:safe_browsing_prefs",
"//components/safe_browsing_db:database_manager",
- "//components/safe_browsing_db:safe_browsing_prefs",
"//components/security_interstitials/content:security_interstitial_page",
"//components/security_interstitials/core:core",
- "//components/subresource_filter/content/browser:browser",
"//content/public/browser:browser",
"//content/public/common:common",
"//net:net",
diff --git a/chromium/components/safe_browsing/DEPS b/chromium/components/safe_browsing/DEPS
index 36b6e0f8aec..ccceca98f91 100644
--- a/chromium/components/safe_browsing/DEPS
+++ b/chromium/components/safe_browsing/DEPS
@@ -3,12 +3,12 @@ include_rules = [
"+components/safe_browsing_db",
"+components/security_interstitials/content",
"+components/security_interstitials/core",
- "+components/subresource_filter/content/browser",
"+content/public/browser",
"+content/public/common",
"+google_apis",
"+net/base",
"+net/log",
+ "+net/traffic_annotation",
"+net/url_request",
"+testing/gtest",
"+third_party/protobuf",
diff --git a/chromium/components/safe_browsing/base_blocking_page.cc b/chromium/components/safe_browsing/base_blocking_page.cc
index 3f91702ab29..9ddae815dc1 100644
--- a/chromium/components/safe_browsing/base_blocking_page.cc
+++ b/chromium/components/safe_browsing/base_blocking_page.cc
@@ -9,16 +9,18 @@
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/security_interstitials/content/security_interstitial_controller_client.h"
#include "components/security_interstitials/core/metrics_helper.h"
+#include "components/security_interstitials/core/safe_browsing_loud_error_ui.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
using content::InterstitialPage;
using content::WebContents;
-using security_interstitials::SafeBrowsingErrorUI;
+using security_interstitials::BaseSafeBrowsingErrorUI;
+using security_interstitials::SafeBrowsingLoudErrorUI;
using security_interstitials::SecurityInterstitialControllerClient;
namespace safe_browsing {
@@ -42,7 +44,7 @@ BaseBlockingPage::BaseBlockingPage(
const GURL& main_frame_url,
const UnsafeResourceList& unsafe_resources,
std::unique_ptr<SecurityInterstitialControllerClient> controller_client,
- const SafeBrowsingErrorUI::SBErrorDisplayOptions& display_options)
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options)
: SecurityInterstitialPage(web_contents,
unsafe_resources[0].url,
std::move(controller_client)),
@@ -53,32 +55,31 @@ BaseBlockingPage::BaseBlockingPage(
? -1
: web_contents->GetController().GetLastCommittedEntryIndex()),
unsafe_resources_(unsafe_resources),
- sb_error_ui_(base::MakeUnique<SafeBrowsingErrorUI>(
+ proceeded_(false),
+ threat_details_proceed_delay_ms_(kThreatDetailsProceedDelayMilliSeconds),
+ sb_error_ui_(base::MakeUnique<SafeBrowsingLoudErrorUI>(
unsafe_resources_[0].url,
main_frame_url_,
GetInterstitialReason(unsafe_resources_),
display_options,
ui_manager->app_locale(),
base::Time::NowFromSystemTime(),
- controller())),
- proceeded_(false),
- threat_details_proceed_delay_ms_(kThreatDetailsProceedDelayMilliSeconds) {
-}
+ controller())) {}
BaseBlockingPage::~BaseBlockingPage() {}
// static
-const SafeBrowsingErrorUI::SBErrorDisplayOptions
+const security_interstitials::BaseSafeBrowsingErrorUI::SBErrorDisplayOptions
BaseBlockingPage::CreateDefaultDisplayOptions(
const UnsafeResourceList& unsafe_resources) {
- return SafeBrowsingErrorUI::SBErrorDisplayOptions(
+ return BaseSafeBrowsingErrorUI::SBErrorDisplayOptions(
IsMainPageLoadBlocked(unsafe_resources),
- false, // kSafeBrowsingExtendedReportingOptInAllowed
- false, // is_off_the_record
- false, // is_extended_reporting
- false, // is_scout
- false, // kSafeBrowsingProceedAnywayDisabled
- true); // is_resource_cancellable
+ false, // kSafeBrowsingExtendedReportingOptInAllowed
+ false, // is_off_the_record
+ false, // is_extended_reporting
+ false, // is_scout
+ false, // kSafeBrowsingProceedAnywayDisabled
+ "cpn_safe_browsing"); // help_center_article_link
}
// static
@@ -206,7 +207,7 @@ bool BaseBlockingPage::ShouldCreateNewNavigation() const {
void BaseBlockingPage::PopulateInterstitialStrings(
base::DictionaryValue* load_time_data) {
- sb_error_ui_->PopulateStringsForHTML(load_time_data);
+ sb_error_ui_->PopulateStringsForHtml(load_time_data);
}
void BaseBlockingPage::FinishThreatDetails(const base::TimeDelta& delay,
@@ -222,14 +223,14 @@ BaseBlockingPage::GetUnsafeResourcesMap() {
// static
std::string BaseBlockingPage::GetMetricPrefix(
const UnsafeResourceList& unsafe_resources,
- SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) {
+ BaseSafeBrowsingErrorUI::SBInterstitialReason interstitial_reason) {
bool primary_subresource = unsafe_resources[0].is_subresource;
switch (interstitial_reason) {
- case SafeBrowsingErrorUI::SB_REASON_MALWARE:
+ case BaseSafeBrowsingErrorUI::SB_REASON_MALWARE:
return primary_subresource ? "malware_subresource" : "malware";
- case SafeBrowsingErrorUI::SB_REASON_HARMFUL:
+ case BaseSafeBrowsingErrorUI::SB_REASON_HARMFUL:
return primary_subresource ? "harmful_subresource" : "harmful";
- case SafeBrowsingErrorUI::SB_REASON_PHISHING:
+ case BaseSafeBrowsingErrorUI::SB_REASON_PHISHING:
ThreatPatternType threat_pattern_type =
unsafe_resources[0].threat_metadata.threat_pattern_type;
if (threat_pattern_type == ThreatPatternType::PHISHING ||
@@ -271,7 +272,7 @@ std::string BaseBlockingPage::GetExtraMetricsSuffix(
}
// static
-SafeBrowsingErrorUI::SBInterstitialReason
+security_interstitials::BaseSafeBrowsingErrorUI::SBInterstitialReason
BaseBlockingPage::GetInterstitialReason(
const UnsafeResourceList& unsafe_resources) {
bool harmful = false;
@@ -281,7 +282,7 @@ BaseBlockingPage::GetInterstitialReason(
safe_browsing::SBThreatType threat_type = resource.threat_type;
if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
- return SafeBrowsingErrorUI::SB_REASON_MALWARE;
+ return BaseSafeBrowsingErrorUI::SB_REASON_MALWARE;
} else if (threat_type == SB_THREAT_TYPE_URL_UNWANTED) {
harmful = true;
} else {
@@ -291,8 +292,8 @@ BaseBlockingPage::GetInterstitialReason(
}
if (harmful)
- return SafeBrowsingErrorUI::SB_REASON_HARMFUL;
- return SafeBrowsingErrorUI::SB_REASON_PHISHING;
+ return BaseSafeBrowsingErrorUI::SB_REASON_HARMFUL;
+ return BaseSafeBrowsingErrorUI::SB_REASON_PHISHING;
}
BaseUIManager* BaseBlockingPage::ui_manager() const {
@@ -308,7 +309,7 @@ BaseBlockingPage::unsafe_resources() const {
return unsafe_resources_;
}
-SafeBrowsingErrorUI* BaseBlockingPage::sb_error_ui() const {
+BaseSafeBrowsingErrorUI* BaseBlockingPage::sb_error_ui() const {
return sb_error_ui_.get();
}
@@ -319,7 +320,7 @@ void BaseBlockingPage::set_proceeded(bool proceeded) {
// static
security_interstitials::MetricsHelper::ReportDetails
BaseBlockingPage::GetReportingInfo(const UnsafeResourceList& unsafe_resources) {
- SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason =
+ BaseSafeBrowsingErrorUI::SBInterstitialReason interstitial_reason =
GetInterstitialReason(unsafe_resources);
security_interstitials::MetricsHelper::ReportDetails reporting_info;
@@ -348,4 +349,13 @@ BaseBlockingPage::CreateControllerClient(
ui_manager->app_locale(), ui_manager->default_safe_page());
}
+int BaseBlockingPage::GetHTMLTemplateId() {
+ return sb_error_ui_->GetHTMLTemplateId();
+}
+
+void BaseBlockingPage::set_sb_error_ui(
+ std::unique_ptr<BaseSafeBrowsingErrorUI> sb_error_ui) {
+ sb_error_ui_ = std::move(sb_error_ui);
+}
+
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/base_blocking_page.h b/chromium/components/safe_browsing/base_blocking_page.h
index 055bd0d429d..d4a8c674cdd 100644
--- a/chromium/components/safe_browsing/base_blocking_page.h
+++ b/chromium/components/safe_browsing/base_blocking_page.h
@@ -12,8 +12,8 @@
#include "base/macros.h"
#include "components/safe_browsing/base_ui_manager.h"
#include "components/security_interstitials/content/security_interstitial_page.h"
+#include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
#include "components/security_interstitials/core/metrics_helper.h"
-#include "components/security_interstitials/core/safe_browsing_error_ui.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "url/gurl.h"
@@ -24,14 +24,15 @@ class BaseBlockingPage
: public security_interstitials::SecurityInterstitialPage {
public:
typedef security_interstitials::UnsafeResource UnsafeResource;
- typedef security_interstitials::SafeBrowsingErrorUI SafeBrowsingErrorUI;
+ typedef security_interstitials::BaseSafeBrowsingErrorUI
+ BaseSafeBrowsingErrorUI;
typedef std::vector<UnsafeResource> UnsafeResourceList;
typedef std::unordered_map<content::WebContents*, UnsafeResourceList>
UnsafeResourceMap;
~BaseBlockingPage() override;
- static const SafeBrowsingErrorUI::SBErrorDisplayOptions
+ static const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions
CreateDefaultDisplayOptions(const UnsafeResourceList& unsafe_resources);
// Shows a blocking page warning the user about phishing/malware for a
@@ -61,7 +62,7 @@ class BaseBlockingPage
std::unique_ptr<
security_interstitials::SecurityInterstitialControllerClient>
controller_client,
- const SafeBrowsingErrorUI::SBErrorDisplayOptions& display_options);
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options);
// SecurityInterstitialPage methods:
bool ShouldCreateNewNavigation() const override;
@@ -81,14 +82,14 @@ class BaseBlockingPage
static std::string GetMetricPrefix(
const UnsafeResourceList& unsafe_resources,
- SafeBrowsingErrorUI::SBInterstitialReason interstitial_reason);
+ BaseSafeBrowsingErrorUI::SBInterstitialReason interstitial_reason);
static std::string GetExtraMetricsSuffix(
const UnsafeResourceList& unsafe_resources);
// Return the most severe interstitial reason from a list of unsafe resources.
// Severity ranking: malware > UwS (harmful) > phishing.
- static SafeBrowsingErrorUI::SBInterstitialReason GetInterstitialReason(
+ static BaseSafeBrowsingErrorUI::SBInterstitialReason GetInterstitialReason(
const UnsafeResourceList& unsafe_resources);
BaseUIManager* ui_manager() const;
@@ -97,7 +98,7 @@ class BaseBlockingPage
UnsafeResourceList unsafe_resources() const;
- SafeBrowsingErrorUI* sb_error_ui() const;
+ BaseSafeBrowsingErrorUI* sb_error_ui() const;
void set_proceeded(bool proceeded);
@@ -110,13 +111,17 @@ class BaseBlockingPage
void SetThreatDetailsProceedDelayForTesting(int64_t delay);
- private:
static std::unique_ptr<
security_interstitials::SecurityInterstitialControllerClient>
CreateControllerClient(content::WebContents* web_contents,
const UnsafeResourceList& unsafe_resources,
BaseUIManager* ui_manager);
+ int GetHTMLTemplateId() override;
+
+ void set_sb_error_ui(std::unique_ptr<BaseSafeBrowsingErrorUI> sb_error_ui);
+
+ private:
// For reporting back user actions.
BaseUIManager* ui_manager_;
@@ -130,9 +135,6 @@ class BaseBlockingPage
// The list of unsafe resources this page is warning about.
UnsafeResourceList unsafe_resources_;
- // For displaying safe browsing interstitial.
- std::unique_ptr<SafeBrowsingErrorUI> sb_error_ui_;
-
// Indicate whether user has proceeded this blocking page.
bool proceeded_;
@@ -142,6 +144,9 @@ class BaseBlockingPage
// milliseconds), in order to get data from the blocked resource itself.
int64_t threat_details_proceed_delay_ms_;
+ // For displaying safe browsing interstitial.
+ std::unique_ptr<BaseSafeBrowsingErrorUI> sb_error_ui_;
+
DISALLOW_COPY_AND_ASSIGN(BaseBlockingPage);
};
diff --git a/chromium/components/safe_browsing/base_ping_manager.cc b/chromium/components/safe_browsing/base_ping_manager.cc
index ed54971a028..30fdf1c079b 100644
--- a/chromium/components/safe_browsing/base_ping_manager.cc
+++ b/chromium/components/safe_browsing/base_ping_manager.cc
@@ -18,6 +18,7 @@
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/log/net_log_source_type.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
@@ -56,6 +57,42 @@ std::unique_ptr<base::Value> NetLogPingEndCallback(
return std::move(event_params);
}
+net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("safe_browsing_extended_reporting", R"(
+ semantics {
+ sender: "Safe Browsing Extended Reporting"
+ description:
+ "When a user is opted in to automatically reporting 'possible "
+ "security incidents to Google,' and they reach a bad page that's "
+ "flagged by Safe Browsing, Chrome will send a report to Google "
+ "with information about the threat. This helps Safe Browsing learn "
+ "where threats originate and thus protect more users."
+ trigger:
+ "When a red interstitial is shown, and the user is opted-in."
+ data:
+ "The report includes the URL and referrer chain of the page. If the "
+ "warning is triggered by a subresource on a partially loaded page, "
+ "the report will include the URL and referrer chain of sub frames "
+ "and resources loaded into the page. It may also include a subset "
+ "of headers for resources loaded, and some Google ad identifiers to "
+ "help block malicious ads."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: true
+ cookies_store: "Safe Browsing Cookie Store"
+ setting:
+ "Users can control this feature via the 'Automatically report "
+ "details of possible security incidents to Google' setting under "
+ "'Privacy'. The feature is disabled by default."
+ chrome_policy {
+ SafeBrowsingExtendedReportingOptInAllowed {
+ policy_options {mode: MANDATORY}
+ SafeBrowsingExtendedReportingOptInAllowed: false
+ }
+ }
+ })");
+
} // namespace
namespace safe_browsing {
@@ -113,7 +150,7 @@ void BasePingManager::ReportSafeBrowsingHit(
report_url,
hit_report.post_data.empty() ? net::URLFetcher::GET
: net::URLFetcher::POST,
- this);
+ this, kTrafficAnnotation);
net::URLFetcher* report = report_ptr.get();
data_use_measurement::DataUseUserData::AttachToFetcher(
report, data_use_measurement::DataUseUserData::SAFE_BROWSING);
@@ -137,8 +174,8 @@ void BasePingManager::ReportSafeBrowsingHit(
// Sends threat details for users who opt-in.
void BasePingManager::ReportThreatDetails(const std::string& report) {
GURL report_url = ThreatDetailsUrl();
- std::unique_ptr<net::URLFetcher> fetcher =
- net::URLFetcher::Create(report_url, net::URLFetcher::POST, this);
+ std::unique_ptr<net::URLFetcher> fetcher = net::URLFetcher::Create(
+ report_url, net::URLFetcher::POST, this, kTrafficAnnotation);
data_use_measurement::DataUseUserData::AttachToFetcher(
fetcher.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE);
diff --git a/chromium/components/safe_browsing/base_resource_throttle.cc b/chromium/components/safe_browsing/base_resource_throttle.cc
index ff2cf8e34f3..87a8812e2bf 100644
--- a/chromium/components/safe_browsing/base_resource_throttle.cc
+++ b/chromium/components/safe_browsing/base_resource_throttle.cc
@@ -10,7 +10,6 @@
#include "components/safe_browsing/base_ui_manager.h"
#include "components/safe_browsing_db/util.h"
#include "components/security_interstitials/content/unsafe_resource.h"
-#include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/web_contents.h"
@@ -302,43 +301,12 @@ void BaseResourceThrottle::StartDisplayingBlockingPageHelper(
}
// Static
-void BaseResourceThrottle::NotifySubresourceFilterOfBlockedResource(
- const security_interstitials::UnsafeResource& resource) {
- content::WebContents* web_contents = resource.web_contents_getter.Run();
- DCHECK(web_contents);
- // Once activated, the subresource filter will filter subresources, but is
- // triggered when the main frame document matches Safe Browsing blacklists.
- if (!resource.is_subresource) {
- using subresource_filter::ContentSubresourceFilterDriverFactory;
- ContentSubresourceFilterDriverFactory* driver_factory =
- ContentSubresourceFilterDriverFactory::FromWebContents(web_contents);
-
- // Content embedders (such as Android Webview) do not have a driver_factory.
- if (driver_factory) {
- // For a redirect chain of A -> B -> C, the subresource filter expects C
- // as the resource URL and [A, B] as redirect URLs.
- std::vector<GURL> redirect_parent_urls;
- if (!resource.redirect_urls.empty()) {
- redirect_parent_urls.push_back(resource.original_url);
- redirect_parent_urls.insert(redirect_parent_urls.end(),
- resource.redirect_urls.begin(),
- std::prev(resource.redirect_urls.end()));
- }
- driver_factory->OnMainResourceMatchedSafeBrowsingBlacklist(
- resource.url, redirect_parent_urls, resource.threat_type,
- resource.threat_metadata.threat_pattern_type);
- }
- }
-}
-
-// Static
void BaseResourceThrottle::StartDisplayingBlockingPage(
const base::WeakPtr<BaseResourceThrottle>& throttle,
scoped_refptr<BaseUIManager> ui_manager,
const security_interstitials::UnsafeResource& resource) {
content::WebContents* web_contents = resource.web_contents_getter.Run();
if (web_contents) {
- NotifySubresourceFilterOfBlockedResource(resource);
ui_manager->DisplayBlockingPage(resource);
return;
}
diff --git a/chromium/components/safe_browsing/base_ui_manager.cc b/chromium/components/safe_browsing/base_ui_manager.cc
index f951896d15e..5a63b615871 100644
--- a/chromium/components/safe_browsing/base_ui_manager.cc
+++ b/chromium/components/safe_browsing/base_ui_manager.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/i18n/rtl.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/supports_user_data.h"
#include "components/safe_browsing/base_blocking_page.h"
@@ -86,7 +87,7 @@ WhitelistUrlSet* GetOrCreateWhitelist(WebContents* web_contents) {
static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey));
if (!site_list) {
site_list = new WhitelistUrlSet;
- web_contents->SetUserData(kWhitelistKey, site_list);
+ web_contents->SetUserData(kWhitelistKey, base::WrapUnique(site_list));
}
return site_list;
}
@@ -243,11 +244,12 @@ void BaseUIManager::ShowBlockingPageForResource(
BaseBlockingPage::ShowBlockingPage(this, resource);
}
-// A safebrowsing hit is sent after a blocking page for malware/phishing
-// or after the warning dialog for download urls, only for
-// UMA || extended_reporting users.
+// A SafeBrowsing hit is sent after a blocking page for malware/phishing
+// or after the warning dialog for download urls, only for extended_reporting
+// users who are not in incognito mode.
void BaseUIManager::MaybeReportSafeBrowsingHit(
- const HitReport& hit_report) {
+ const HitReport& hit_report,
+ const content::WebContents* web_contents) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return;
}
diff --git a/chromium/components/safe_browsing/base_ui_manager.h b/chromium/components/safe_browsing/base_ui_manager.h
index 1230417c242..f20e0d938c0 100644
--- a/chromium/components/safe_browsing/base_ui_manager.h
+++ b/chromium/components/safe_browsing/base_ui_manager.h
@@ -61,9 +61,11 @@ class BaseUIManager
// This is a no-op in the base class, but should be overridden to report hits
// to the unsafe contents (malware, phishing, unsafe download URL)
- // to the server. Can only be called on UI thread.
+ // to the server. Can only be called on UI thread. Will only upload a hit
+ // report if the user has enabled SBER and is not currently in incognito mode.
virtual void MaybeReportSafeBrowsingHit(
- const safe_browsing::HitReport& hit_report);
+ const safe_browsing::HitReport& hit_report,
+ const content::WebContents* web_contents);
// A convenience wrapper method for IsUrlWhitelistedOrPendingForWebContents.
virtual bool IsWhitelisted(const UnsafeResource& resource);
diff --git a/chromium/components/safe_browsing/browser/BUILD.gn b/chromium/components/safe_browsing/browser/BUILD.gn
new file mode 100644
index 00000000000..8d7b1880c50
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2017 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.
+
+import("//build/config/features.gni")
+
+source_set("browser") {
+ sources = [
+ "safe_browsing_url_request_context_getter.cc",
+ "safe_browsing_url_request_context_getter.h",
+ "threat_details.cc",
+ "threat_details.h",
+ "threat_details_cache.cc",
+ "threat_details_cache.h",
+ "threat_details_history.cc",
+ "threat_details_history.h",
+ ]
+
+ deps = [
+ "//components/data_use_measurement/core:core",
+ "//components/history/core/browser:browser",
+ "//components/safe_browsing:csd_proto",
+ "//components/safe_browsing:safe_browsing",
+ "//components/safe_browsing/common:common",
+ "//components/security_interstitials/content:security_interstitial_page",
+ "//content/public/browser:browser",
+ "//net:extras",
+ ]
+}
diff --git a/chromium/components/safe_browsing/browser/DEPS b/chromium/components/safe_browsing/browser/DEPS
new file mode 100644
index 00000000000..37c91123491
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/DEPS
@@ -0,0 +1,10 @@
+include_rules = [
+ "+components/history/core/browser",
+ "+components/safe_browsing/csd.pb.h",
+ "+content/public/browser",
+ "+net/cookies",
+ "+net/extras",
+ "+net/http",
+ "+net/ssl",
+ "+net/traffic_annotation",
+] \ No newline at end of file
diff --git a/chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.cc b/chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.cc
new file mode 100644
index 00000000000..513698fde86
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.cc
@@ -0,0 +1,134 @@
+// Copyright 2017 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/safe_browsing/browser/safe_browsing_url_request_context_getter.h"
+
+#include "base/single_thread_task_runner.h"
+#include "base/task_scheduler/post_task.h"
+#include "components/safe_browsing/common/safebrowsing_constants.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/cookie_store_factory.h"
+#include "net/cookies/cookie_store.h"
+#include "net/extras/sqlite/sqlite_channel_id_store.h"
+#include "net/http/http_network_layer.h"
+#include "net/http/http_transaction_factory.h"
+#include "net/ssl/channel_id_service.h"
+#include "net/ssl/default_channel_id_store.h"
+#include "net/url_request/url_request_context.h"
+
+using content::BrowserThread;
+
+namespace safe_browsing {
+
+SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter(
+ scoped_refptr<net::URLRequestContextGetter> system_context_getter,
+ const base::FilePath& user_data_dir)
+ : shut_down_(false),
+ user_data_dir_(user_data_dir),
+ system_context_getter_(system_context_getter),
+ network_task_runner_(
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)) {
+ DCHECK(!user_data_dir.empty());
+}
+
+net::URLRequestContext*
+SafeBrowsingURLRequestContextGetter::GetURLRequestContext() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Check if the service has been shut down.
+ if (shut_down_)
+ return nullptr;
+
+ if (!safe_browsing_request_context_) {
+ safe_browsing_request_context_.reset(new net::URLRequestContext());
+ // May be NULL in unit tests.
+ if (system_context_getter_) {
+ safe_browsing_request_context_->CopyFrom(
+ system_context_getter_->GetURLRequestContext());
+ }
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner =
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
+ // Set up the ChannelIDService
+ scoped_refptr<net::SQLiteChannelIDStore> channel_id_db =
+ new net::SQLiteChannelIDStore(ChannelIDFilePath(),
+ background_task_runner);
+ channel_id_service_.reset(new net::ChannelIDService(
+ new net::DefaultChannelIDStore(channel_id_db.get())));
+
+ // Set up the CookieStore
+ content::CookieStoreConfig cookie_config(
+ CookieFilePath(), content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
+ nullptr, nullptr);
+ cookie_config.channel_id_service = channel_id_service_.get();
+ cookie_config.background_task_runner = background_task_runner;
+ safe_browsing_cookie_store_ = content::CreateCookieStore(cookie_config);
+ safe_browsing_request_context_->set_cookie_store(
+ safe_browsing_cookie_store_.get());
+
+ safe_browsing_request_context_->set_channel_id_service(
+ channel_id_service_.get());
+ safe_browsing_cookie_store_->SetChannelIDServiceID(
+ channel_id_service_->GetUniqueID());
+
+ // Rebuild the HttpNetworkSession and the HttpTransactionFactory to use the
+ // new ChannelIDService.
+ if (safe_browsing_request_context_->http_transaction_factory() &&
+ safe_browsing_request_context_->http_transaction_factory()
+ ->GetSession()) {
+ net::HttpNetworkSession::Params safe_browsing_params =
+ safe_browsing_request_context_->http_transaction_factory()
+ ->GetSession()
+ ->params();
+ safe_browsing_params.channel_id_service = channel_id_service_.get();
+ http_network_session_.reset(
+ new net::HttpNetworkSession(safe_browsing_params));
+ http_transaction_factory_.reset(
+ new net::HttpNetworkLayer(http_network_session_.get()));
+ safe_browsing_request_context_->set_http_transaction_factory(
+ http_transaction_factory_.get());
+ }
+ safe_browsing_request_context_->set_name("safe_browsing");
+ }
+
+ return safe_browsing_request_context_.get();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+SafeBrowsingURLRequestContextGetter::GetNetworkTaskRunner() const {
+ return network_task_runner_;
+}
+
+void SafeBrowsingURLRequestContextGetter::ServiceShuttingDown() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ shut_down_ = true;
+ URLRequestContextGetter::NotifyContextShuttingDown();
+ safe_browsing_request_context_.reset();
+}
+
+void SafeBrowsingURLRequestContextGetter::DisableQuicOnIOThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (http_network_session_)
+ http_network_session_->DisableQuic();
+}
+
+base::FilePath SafeBrowsingURLRequestContextGetter::GetBaseFilename() {
+ base::FilePath path(user_data_dir_);
+ return path.Append(kSafeBrowsingBaseFilename);
+}
+
+base::FilePath SafeBrowsingURLRequestContextGetter::CookieFilePath() {
+ return base::FilePath(GetBaseFilename().value() + kCookiesFile);
+}
+
+base::FilePath SafeBrowsingURLRequestContextGetter::ChannelIDFilePath() {
+ return base::FilePath(GetBaseFilename().value() + kChannelIDFile);
+}
+
+SafeBrowsingURLRequestContextGetter::~SafeBrowsingURLRequestContextGetter() {}
+
+} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.h b/chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.h
new file mode 100644
index 00000000000..710e11f4337
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/safe_browsing_url_request_context_getter.h
@@ -0,0 +1,67 @@
+// Copyright 2017 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_SAFE_BROWSING_BROWSER_SAFE_BROWSING_URL_REQUEST_CONTEXT_GETTER_H_
+#define COMPONENTS_SAFE_BROWSING_BROWSER_SAFE_BROWSING_URL_REQUEST_CONTEXT_GETTER_H_
+
+#include "base/files/file_path.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace net {
+class ChannelIDService;
+class CookieStore;
+class HttpNetworkSession;
+class HttpTransactionFactory;
+class URLRequestContext;
+}
+
+namespace safe_browsing {
+
+class SafeBrowsingURLRequestContextGetter
+ : public net::URLRequestContextGetter {
+ public:
+ explicit SafeBrowsingURLRequestContextGetter(
+ scoped_refptr<net::URLRequestContextGetter> system_context_getter,
+ const base::FilePath& user_data_dir);
+
+ // Implementation for net::UrlRequestContextGetter.
+ net::URLRequestContext* GetURLRequestContext() override;
+ scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+ const override;
+
+ // Shuts down any pending requests using the getter, and sets |shut_down_| to
+ // true.
+ void ServiceShuttingDown();
+
+ // Disables QUIC. This should not be necessary anymore when
+ // http://crbug.com/678653 is implemented.
+ void DisableQuicOnIOThread();
+
+ protected:
+ ~SafeBrowsingURLRequestContextGetter() override;
+
+ private:
+ base::FilePath GetBaseFilename();
+ base::FilePath CookieFilePath();
+ base::FilePath ChannelIDFilePath();
+
+ bool shut_down_;
+ base::FilePath user_data_dir_;
+
+ scoped_refptr<net::URLRequestContextGetter> system_context_getter_;
+ scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
+ std::unique_ptr<net::URLRequestContext> safe_browsing_request_context_;
+ std::unique_ptr<net::CookieStore> safe_browsing_cookie_store_;
+ std::unique_ptr<net::ChannelIDService> channel_id_service_;
+ std::unique_ptr<net::HttpNetworkSession> http_network_session_;
+ std::unique_ptr<net::HttpTransactionFactory> http_transaction_factory_;
+};
+
+} // namespace safe_browsing
+
+#endif // COMPONENTS_SAFE_BROWSING_BROWSER_SAFE_BROWSING_URL_REQUEST_CONTEXT_GETTER_H_
diff --git a/chromium/components/safe_browsing/browser/threat_details.cc b/chromium/components/safe_browsing/browser/threat_details.cc
new file mode 100644
index 00000000000..0e6cfb8cf11
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/threat_details.cc
@@ -0,0 +1,590 @@
+// Copyright (c) 2012 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.
+//
+// Implementation of the ThreatDetails class.
+
+#include "components/safe_browsing/browser/threat_details.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/string_util.h"
+#include "components/history/core/browser/history_service.h"
+#include "components/safe_browsing/base_ui_manager.h"
+#include "components/safe_browsing/browser/threat_details_cache.h"
+#include "components/safe_browsing/browser/threat_details_history.h"
+#include "components/safe_browsing/common/safebrowsing_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+#include "net/url_request/url_request_context_getter.h"
+
+using content::BrowserThread;
+using content::NavigationEntry;
+using content::RenderFrameHost;
+using content::WebContents;
+
+// Keep in sync with KMaxNodes in components/safe_browsing/renderer/
+// threat_dom_details.cc
+static const uint32_t kMaxDomNodes = 500;
+
+namespace safe_browsing {
+
+// static
+ThreatDetailsFactory* ThreatDetails::factory_ = NULL;
+
+namespace {
+
+typedef std::unordered_set<std::string> StringSet;
+// A set of HTTPS headers that are allowed to be collected. Contains both
+// request and response headers. All entries in this list should be lower-case
+// to support case-insensitive comparison.
+struct WhitelistedHttpsHeadersTraits
+ : base::internal::DestructorAtExitLazyInstanceTraits<StringSet> {
+ static StringSet* New(void* instance) {
+ StringSet* headers =
+ base::internal::DestructorAtExitLazyInstanceTraits<StringSet>::New(
+ instance);
+ headers->insert({"google-creative-id", "google-lineitem-id", "referer",
+ "content-type", "content-length", "date", "server",
+ "cache-control", "pragma", "expires"});
+ return headers;
+ }
+};
+base::LazyInstance<StringSet, WhitelistedHttpsHeadersTraits>
+ g_https_headers_whitelist = LAZY_INSTANCE_INITIALIZER;
+
+// Helper function that converts SBThreatType to
+// ClientSafeBrowsingReportRequest::ReportType.
+ClientSafeBrowsingReportRequest::ReportType GetReportTypeFromSBThreatType(
+ SBThreatType threat_type) {
+ switch (threat_type) {
+ case SB_THREAT_TYPE_URL_PHISHING:
+ return ClientSafeBrowsingReportRequest::URL_PHISHING;
+ case SB_THREAT_TYPE_URL_MALWARE:
+ return ClientSafeBrowsingReportRequest::URL_MALWARE;
+ case SB_THREAT_TYPE_URL_UNWANTED:
+ return ClientSafeBrowsingReportRequest::URL_UNWANTED;
+ case SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL:
+ return ClientSafeBrowsingReportRequest::CLIENT_SIDE_PHISHING_URL;
+ case SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL:
+ return ClientSafeBrowsingReportRequest::CLIENT_SIDE_MALWARE_URL;
+ default: // Gated by SafeBrowsingBlockingPage::ShouldReportThreatDetails.
+ NOTREACHED() << "We should not send report for threat type "
+ << threat_type;
+ return ClientSafeBrowsingReportRequest::UNKNOWN;
+ }
+}
+
+// Clears the specified HTTPS resource of any sensitive data, only retaining
+// data that is whitelisted for collection.
+void ClearHttpsResource(ClientSafeBrowsingReportRequest::Resource* resource) {
+ // Make a copy of the original resource to retain all data.
+ ClientSafeBrowsingReportRequest::Resource orig_resource(*resource);
+
+ // Clear the request headers and copy over any whitelisted ones.
+ resource->clear_request();
+ for (int i = 0; i < orig_resource.request().headers_size(); ++i) {
+ ClientSafeBrowsingReportRequest::HTTPHeader* orig_header =
+ orig_resource.mutable_request()->mutable_headers(i);
+ if (g_https_headers_whitelist.Get().count(
+ base::ToLowerASCII(orig_header->name())) > 0) {
+ resource->mutable_request()->add_headers()->Swap(orig_header);
+ }
+ }
+ // Also copy some other request fields.
+ resource->mutable_request()->mutable_bodydigest()->swap(
+ *orig_resource.mutable_request()->mutable_bodydigest());
+ resource->mutable_request()->set_bodylength(
+ orig_resource.request().bodylength());
+
+ // ...repeat for response headers.
+ resource->clear_response();
+ for (int i = 0; i < orig_resource.response().headers_size(); ++i) {
+ ClientSafeBrowsingReportRequest::HTTPHeader* orig_header =
+ orig_resource.mutable_response()->mutable_headers(i);
+ if (g_https_headers_whitelist.Get().count(
+ base::ToLowerASCII(orig_header->name())) > 0) {
+ resource->mutable_response()->add_headers()->Swap(orig_header);
+ }
+ }
+ // Also copy some other response fields.
+ resource->mutable_response()->mutable_bodydigest()->swap(
+ *orig_resource.mutable_response()->mutable_bodydigest());
+ resource->mutable_response()->set_bodylength(
+ orig_resource.response().bodylength());
+ resource->mutable_response()->mutable_remote_ip()->swap(
+ *orig_resource.mutable_response()->mutable_remote_ip());
+}
+
+std::string GetElementKey(const int frame_tree_node_id,
+ const int element_node_id) {
+ return base::StringPrintf("%d-%d", frame_tree_node_id, element_node_id);
+}
+
+} // namespace
+
+// The default ThreatDetailsFactory. Global, made a singleton so we
+// don't leak it.
+class ThreatDetailsFactoryImpl : public ThreatDetailsFactory {
+ public:
+ ThreatDetails* CreateThreatDetails(
+ BaseUIManager* ui_manager,
+ WebContents* web_contents,
+ const security_interstitials::UnsafeResource& unsafe_resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service) override {
+ return new ThreatDetails(ui_manager, web_contents, unsafe_resource,
+ request_context_getter, history_service);
+ }
+
+ private:
+ friend struct base::LazyInstanceTraitsBase<ThreatDetailsFactoryImpl>;
+
+ ThreatDetailsFactoryImpl() {}
+
+ DISALLOW_COPY_AND_ASSIGN(ThreatDetailsFactoryImpl);
+};
+
+static base::LazyInstance<ThreatDetailsFactoryImpl>::DestructorAtExit
+ g_threat_details_factory_impl = LAZY_INSTANCE_INITIALIZER;
+
+// Create a ThreatDetails for the given tab.
+/* static */
+ThreatDetails* ThreatDetails::NewThreatDetails(
+ BaseUIManager* ui_manager,
+ WebContents* web_contents,
+ const UnsafeResource& resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service) {
+ // Set up the factory if this has not been done already (tests do that
+ // before this method is called).
+ if (!factory_)
+ factory_ = g_threat_details_factory_impl.Pointer();
+ return factory_->CreateThreatDetails(ui_manager, web_contents, resource,
+ request_context_getter, history_service);
+}
+
+// Create a ThreatDetails for the given tab. Runs in the UI thread.
+ThreatDetails::ThreatDetails(
+ BaseUIManager* ui_manager,
+ content::WebContents* web_contents,
+ const UnsafeResource& resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service)
+ : content::WebContentsObserver(web_contents),
+ request_context_getter_(request_context_getter),
+ ui_manager_(ui_manager),
+ resource_(resource),
+ cache_result_(false),
+ did_proceed_(false),
+ num_visits_(0),
+ ambiguous_dom_(false),
+ cache_collector_(new ThreatDetailsCacheCollector) {
+ redirects_collector_ = new ThreatDetailsRedirectsCollector(
+ history_service ? history_service->AsWeakPtr()
+ : base::WeakPtr<history::HistoryService>());
+ StartCollection();
+}
+
+ThreatDetails::~ThreatDetails() {}
+
+bool ThreatDetails::OnMessageReceived(const IPC::Message& message,
+ RenderFrameHost* render_frame_host) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(ThreatDetails, message, render_frame_host)
+ IPC_MESSAGE_HANDLER(SafeBrowsingHostMsg_ThreatDOMDetails,
+ OnReceivedThreatDOMDetails)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+bool ThreatDetails::IsReportableUrl(const GURL& url) const {
+ // TODO(panayiotis): also skip internal urls.
+ return url.SchemeIs("http") || url.SchemeIs("https");
+}
+
+// Looks for a Resource for the given url in resources_. If found, it
+// updates |resource|. Otherwise, it creates a new message, adds it to
+// resources_ and updates |resource| to point to it.
+//
+ClientSafeBrowsingReportRequest::Resource* ThreatDetails::FindOrCreateResource(
+ const GURL& url) {
+ auto& resource = resources_[url.spec()];
+ if (!resource) {
+ // Create the resource for |url|.
+ int id = resources_.size() - 1;
+ std::unique_ptr<ClientSafeBrowsingReportRequest::Resource> new_resource(
+ new ClientSafeBrowsingReportRequest::Resource());
+ new_resource->set_url(url.spec());
+ new_resource->set_id(id);
+ resource = std::move(new_resource);
+ }
+ return resource.get();
+}
+
+HTMLElement* ThreatDetails::FindOrCreateElement(
+ const std::string& element_key) {
+ auto& element = elements_[element_key];
+ if (!element) {
+ // Create an entry for this element.
+ int element_dom_id = elements_.size() - 1;
+ std::unique_ptr<HTMLElement> new_element(new HTMLElement());
+ new_element->set_id(element_dom_id);
+ element = std::move(new_element);
+ }
+ return element.get();
+}
+
+ClientSafeBrowsingReportRequest::Resource* ThreatDetails::AddUrl(
+ const GURL& url,
+ const GURL& parent,
+ const std::string& tagname,
+ const std::vector<GURL>* children) {
+ if (!url.is_valid() || !IsReportableUrl(url))
+ return nullptr;
+
+ // Find (or create) the resource for the url.
+ ClientSafeBrowsingReportRequest::Resource* url_resource =
+ FindOrCreateResource(url);
+ if (!tagname.empty())
+ url_resource->set_tag_name(tagname);
+ if (!parent.is_empty() && IsReportableUrl(parent)) {
+ // Add the resource for the parent.
+ ClientSafeBrowsingReportRequest::Resource* parent_resource =
+ FindOrCreateResource(parent);
+ // Update the parent-child relation
+ url_resource->set_parent_id(parent_resource->id());
+ }
+ if (children) {
+ for (std::vector<GURL>::const_iterator it = children->begin();
+ it != children->end(); ++it) {
+ // TODO(lpz): Should this first check if the child URL is reportable
+ // before creating the resource?
+ ClientSafeBrowsingReportRequest::Resource* child_resource =
+ FindOrCreateResource(*it);
+ bool duplicate_child = false;
+ for (auto child_id : url_resource->child_ids()) {
+ if (child_id == child_resource->id()) {
+ duplicate_child = true;
+ break;
+ }
+ }
+ if (!duplicate_child)
+ url_resource->add_child_ids(child_resource->id());
+ }
+ }
+
+ return url_resource;
+}
+
+void ThreatDetails::AddDomElement(
+ const int frame_tree_node_id,
+ const int element_node_id,
+ const std::string& tagname,
+ const int parent_element_node_id,
+ const std::vector<AttributeNameValue>& attributes,
+ const ClientSafeBrowsingReportRequest::Resource* resource) {
+ // Create the element. It should not exist already since this function should
+ // only be called once for each element.
+ const std::string element_key =
+ GetElementKey(frame_tree_node_id, element_node_id);
+ HTMLElement* cur_element = FindOrCreateElement(element_key);
+
+ // Set some basic metadata about the element.
+ const std::string tag_name_upper = base::ToUpperASCII(tagname);
+ if (!tag_name_upper.empty()) {
+ cur_element->set_tag(tag_name_upper);
+ }
+ for (const AttributeNameValue& attribute : attributes) {
+ HTMLElement::Attribute* attribute_pb = cur_element->add_attribute();
+ attribute_pb->set_name(attribute.first);
+ attribute_pb->set_value(attribute.second);
+ }
+
+ if (resource) {
+ cur_element->set_resource_id(resource->id());
+ }
+
+ // Next we try to lookup the parent of the current element and add ourselves
+ // as a child of it.
+ HTMLElement* parent_element = nullptr;
+ if (parent_element_node_id == 0) {
+ // No parent indicates that this element is at the top of the current frame.
+ // Remember that this is a top-level element of the frame with the
+ // current |frame_tree_node_id|. If this element is inside an iframe, a
+ // second pass will insert this element as a child of its parent iframe.
+ frame_tree_id_to_children_map_[frame_tree_node_id].insert(
+ cur_element->id());
+ } else {
+ // We have a parent ID, so this element is just a child of something inside
+ // of our current frame. We can easily lookup our parent.
+ const std::string& parent_key =
+ GetElementKey(frame_tree_node_id, parent_element_node_id);
+ if (base::ContainsKey(elements_, parent_key)) {
+ parent_element = elements_[parent_key].get();
+ }
+ }
+
+ // If a parent element was found, add ourselves as a child, ensuring not to
+ // duplicate child IDs.
+ if (parent_element) {
+ bool duplicate_child = false;
+ for (const int child_id : parent_element->child_ids()) {
+ if (child_id == cur_element->id()) {
+ duplicate_child = true;
+ break;
+ }
+ }
+ if (!duplicate_child) {
+ parent_element->add_child_ids(cur_element->id());
+ }
+ }
+}
+
+void ThreatDetails::StartCollection() {
+ DVLOG(1) << "Starting to compute threat details.";
+ report_.reset(new ClientSafeBrowsingReportRequest());
+
+ if (IsReportableUrl(resource_.url)) {
+ report_->set_url(resource_.url.spec());
+ report_->set_type(GetReportTypeFromSBThreatType(resource_.threat_type));
+ }
+
+ GURL referrer_url;
+ NavigationEntry* nav_entry = resource_.GetNavigationEntryForResource();
+ if (nav_entry) {
+ GURL page_url = nav_entry->GetURL();
+ if (IsReportableUrl(page_url))
+ report_->set_page_url(page_url.spec());
+
+ referrer_url = nav_entry->GetReferrer().url;
+ if (IsReportableUrl(referrer_url))
+ report_->set_referrer_url(referrer_url.spec());
+
+ // Add the nodes, starting from the page url.
+ AddUrl(page_url, GURL(), std::string(), NULL);
+ }
+
+ // Add the resource_url and its original url, if non-empty and different.
+ if (!resource_.original_url.is_empty() &&
+ resource_.url != resource_.original_url) {
+ // Add original_url, as the parent of resource_url.
+ AddUrl(resource_.original_url, GURL(), std::string(), NULL);
+ AddUrl(resource_.url, resource_.original_url, std::string(), NULL);
+ } else {
+ AddUrl(resource_.url, GURL(), std::string(), NULL);
+ }
+
+ // Add the redirect urls, if non-empty. The redirect urls do not include the
+ // original url, but include the unsafe url which is the last one of the
+ // redirect urls chain
+ GURL parent_url;
+ // Set the original url as the parent of the first redirect url if it's not
+ // empty.
+ if (!resource_.original_url.is_empty())
+ parent_url = resource_.original_url;
+
+ // Set the previous redirect url as the parent of the next one
+ for (size_t i = 0; i < resource_.redirect_urls.size(); ++i) {
+ AddUrl(resource_.redirect_urls[i], parent_url, std::string(), NULL);
+ parent_url = resource_.redirect_urls[i];
+ }
+
+ // Add the referrer url.
+ if (!referrer_url.is_empty())
+ AddUrl(referrer_url, GURL(), std::string(), NULL);
+
+ if (!resource_.IsMainPageLoadBlocked()) {
+ // Get URLs of frames, scripts etc from the DOM.
+ // OnReceivedThreatDOMDetails will be called when the renderer replies.
+ // TODO(mattm): In theory, if the user proceeds through the warning DOM
+ // detail collection could be started once the page loads.
+ web_contents()->SendToAllFrames(
+ new SafeBrowsingMsg_GetThreatDOMDetails(MSG_ROUTING_NONE));
+ }
+}
+
+// When the renderer is done, this is called.
+void ThreatDetails::OnReceivedThreatDOMDetails(
+ content::RenderFrameHost* sender,
+ const std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node>& params) {
+ // Lookup the FrameTreeNode ID of any child frames in the list of DOM nodes.
+ const int sender_process_id = sender->GetProcess()->GetID();
+ const int sender_frame_tree_node_id = sender->GetFrameTreeNodeId();
+ KeyToFrameTreeIdMap child_frame_tree_map;
+ for (const SafeBrowsingHostMsg_ThreatDOMDetails_Node& node : params) {
+ if (node.child_frame_routing_id == 0)
+ continue;
+
+ const std::string cur_element_key =
+ GetElementKey(sender_frame_tree_node_id, node.node_id);
+ int child_frame_tree_node_id =
+ content::RenderFrameHost::GetFrameTreeNodeIdForRoutingId(
+ sender_process_id, node.child_frame_routing_id);
+ if (child_frame_tree_node_id ==
+ content::RenderFrameHost::kNoFrameTreeNodeId) {
+ ambiguous_dom_ = true;
+ } else {
+ child_frame_tree_map[cur_element_key] = child_frame_tree_node_id;
+ }
+ }
+
+ // Schedule this in IO thread, so it doesn't conflict with future users
+ // of our data structures (eg GetSerializedReport).
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ThreatDetails::AddDOMDetails, this, sender_frame_tree_node_id,
+ params, child_frame_tree_map));
+}
+
+void ThreatDetails::AddDOMDetails(
+ const int frame_tree_node_id,
+ const std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node>& params,
+ const KeyToFrameTreeIdMap& child_frame_tree_map) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DVLOG(1) << "Nodes from the DOM: " << params.size();
+
+ // If we have already started getting redirects from history service,
+ // don't modify state, otherwise will invalidate the iterators.
+ if (redirects_collector_->HasStarted())
+ return;
+
+ // If we have already started collecting data from the HTTP cache, don't
+ // modify our state.
+ if (cache_collector_->HasStarted())
+ return;
+
+ // Exit early if there are no nodes to process.
+ if (params.empty())
+ return;
+
+ // Copy FrameTreeNode IDs for the child frame into the combined mapping.
+ iframe_key_to_frame_tree_id_map_.insert(child_frame_tree_map.begin(),
+ child_frame_tree_map.end());
+
+ // Add the urls from the DOM to |resources_|. The renderer could be sending
+ // bogus messages, so limit the number of nodes we accept.
+ // Also update |elements_| with the DOM structure.
+ for (size_t i = 0; i < params.size() && i < kMaxDomNodes; ++i) {
+ SafeBrowsingHostMsg_ThreatDOMDetails_Node node = params[i];
+ DVLOG(1) << node.url << ", " << node.tag_name << ", " << node.parent;
+ ClientSafeBrowsingReportRequest::Resource* resource = nullptr;
+ if (!node.url.is_empty()) {
+ resource = AddUrl(node.url, node.parent, node.tag_name, &(node.children));
+ }
+ // Check for a tag_name to avoid adding the summary node to the DOM.
+ if (!node.tag_name.empty()) {
+ AddDomElement(frame_tree_node_id, node.node_id, node.tag_name,
+ node.parent_node_id, node.attributes, resource);
+ }
+ }
+}
+
+// Called from the SB Service on the IO thread, after the user has
+// closed the tab, or clicked proceed or goback. Since the user needs
+// to take an action, we expect this to be called after
+// OnReceivedThreatDOMDetails in most cases. If not, we don't include
+// the DOM data in our report.
+void ThreatDetails::FinishCollection(bool did_proceed, int num_visit) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Do a second pass over the elements and update iframe elements to have
+ // references to their children. Children may have been received from a
+ // different renderer than the iframe element.
+ for (auto& element_pair : elements_) {
+ const std::string& element_key = element_pair.first;
+ HTMLElement* element = element_pair.second.get();
+ if (base::ContainsKey(iframe_key_to_frame_tree_id_map_, element_key)) {
+ int frame_tree_id_of_iframe_renderer =
+ iframe_key_to_frame_tree_id_map_[element_key];
+ const std::unordered_set<int>& child_ids =
+ frame_tree_id_to_children_map_[frame_tree_id_of_iframe_renderer];
+ for (const int child_id : child_ids) {
+ element->add_child_ids(child_id);
+ }
+ }
+ }
+ did_proceed_ = did_proceed;
+ num_visits_ = num_visit;
+ std::vector<GURL> urls;
+ for (ResourceMap::const_iterator it = resources_.begin();
+ it != resources_.end(); ++it) {
+ urls.push_back(GURL(it->first));
+ }
+ redirects_collector_->StartHistoryCollection(
+ urls, base::Bind(&ThreatDetails::OnRedirectionCollectionReady, this));
+}
+
+void ThreatDetails::OnRedirectionCollectionReady() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const std::vector<RedirectChain>& redirects =
+ redirects_collector_->GetCollectedUrls();
+
+ for (size_t i = 0; i < redirects.size(); ++i)
+ AddRedirectUrlList(redirects[i]);
+
+ // Call the cache collector
+ cache_collector_->StartCacheCollection(
+ request_context_getter_.get(), &resources_, &cache_result_,
+ base::Bind(&ThreatDetails::OnCacheCollectionReady, this));
+}
+
+void ThreatDetails::AddRedirectUrlList(const std::vector<GURL>& urls) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ for (size_t i = 0; i < urls.size() - 1; ++i) {
+ AddUrl(urls[i], urls[i + 1], std::string(), NULL);
+ }
+}
+
+void ThreatDetails::OnCacheCollectionReady() {
+ DVLOG(1) << "OnCacheCollectionReady.";
+ // Add all the urls in our |resources_| maps to the |report_| protocol buffer.
+ for (auto& resource_pair : resources_) {
+ ClientSafeBrowsingReportRequest::Resource* pb_resource =
+ report_->add_resources();
+ pb_resource->Swap(resource_pair.second.get());
+ const GURL url(pb_resource->url());
+ if (url.SchemeIs("https")) {
+ // Sanitize the HTTPS resource by clearing out private data (like cookie
+ // headers).
+ DVLOG(1) << "Clearing out HTTPS resource: " << pb_resource->url();
+ ClearHttpsResource(pb_resource);
+ // Keep id, parent_id, child_ids, and tag_name.
+ }
+ }
+ for (auto& element_pair : elements_) {
+ report_->add_dom()->Swap(element_pair.second.get());
+ }
+ if (!elements_.empty()) {
+ // TODO(lpz): Consider including the ambiguous_dom_ bit in the report
+ // itself.
+ UMA_HISTOGRAM_BOOLEAN("SafeBrowsing.ThreatReport.DomIsAmbiguous",
+ ambiguous_dom_);
+ }
+
+ report_->set_did_proceed(did_proceed_);
+ // Only sets repeat_visit if num_visits_ >= 0.
+ if (num_visits_ >= 0) {
+ report_->set_repeat_visit(num_visits_ > 0);
+ }
+ report_->set_complete(cache_result_);
+
+ // Send the report, using the SafeBrowsingService.
+ std::string serialized;
+ if (!report_->SerializeToString(&serialized)) {
+ DLOG(ERROR) << "Unable to serialize the threat report.";
+ return;
+ }
+ ui_manager_->SendSerializedThreatDetails(serialized);
+}
+
+} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/browser/threat_details.h b/chromium/components/safe_browsing/browser/threat_details.h
new file mode 100644
index 00000000000..16a244f9e22
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/threat_details.h
@@ -0,0 +1,256 @@
+// Copyright (c) 2011 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_SAFE_BROWSING_BROWSER_THREAT_DETAILS_H_
+#define COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_H_
+
+// A class that encapsulates the detailed threat reports sent when
+// users opt-in to do so from the safe browsing warning page.
+
+// An instance of this class is generated when a safe browsing warning page
+// is shown (SafeBrowsingBlockingPage).
+
+#include <memory>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include "base/containers/hash_tables.h"
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "components/safe_browsing/common/safebrowsing_types.h"
+#include "components/safe_browsing/csd.pb.h"
+#include "components/security_interstitials/content/unsafe_resource.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "net/base/completion_callback.h"
+
+namespace history {
+class HistoryService;
+} // namespace history
+
+namespace net {
+class URLRequestContextGetter;
+} // namespace net
+
+struct SafeBrowsingHostMsg_ThreatDOMDetails_Node;
+
+namespace safe_browsing {
+
+class BaseUIManager;
+
+// Maps a URL to its Resource.
+class ThreatDetailsCacheCollector;
+class ThreatDetailsRedirectsCollector;
+class ThreatDetailsFactory;
+
+using ResourceMap =
+ base::hash_map<std::string,
+ std::unique_ptr<ClientSafeBrowsingReportRequest::Resource>>;
+
+// Maps a key of an HTML element to its corresponding HTMLElement proto message.
+// HTML Element keys have the form "<frame_id>-<node_id>", where |frame_id| is
+// the FrameTreeNode ID of the frame containing the element, and
+// |node_id| is a sequential ID for the element generated by the renderer.
+using ElementMap = base::hash_map<std::string, std::unique_ptr<HTMLElement>>;
+
+// Maps the key of an iframe element to the FrameTreeNode ID of the frame that
+// rendered the contents of the iframe.
+using KeyToFrameTreeIdMap = base::hash_map<std::string, int>;
+
+// Maps a FrameTreeNode ID of a frame to a set of child IDs. The child IDs are
+// the Element IDs of the top-level HTML Elements in this frame.
+using FrameTreeIdToChildIdsMap = base::hash_map<int, std::unordered_set<int>>;
+
+class ThreatDetails : public base::RefCountedThreadSafe<
+ ThreatDetails,
+ content::BrowserThread::DeleteOnUIThread>,
+ public content::WebContentsObserver {
+ public:
+ typedef security_interstitials::UnsafeResource UnsafeResource;
+
+ // Constructs a new ThreatDetails instance, using the factory.
+ static ThreatDetails* NewThreatDetails(
+ BaseUIManager* ui_manager,
+ content::WebContents* web_contents,
+ const UnsafeResource& resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service);
+
+ // Makes the passed |factory| the factory used to instantiate
+ // SafeBrowsingBlockingPage objects. Useful for tests.
+ static void RegisterFactory(ThreatDetailsFactory* factory) {
+ factory_ = factory;
+ }
+
+ // The SafeBrowsingBlockingPage calls this from the IO thread when
+ // the user is leaving the blocking page and has opted-in to sending
+ // the report. We start the redirection urls collection from history service
+ // in UI thread; then do cache collection back in IO thread. We also record
+ // if the user did proceed with the warning page, and how many times user
+ // visited this page before. When we are done, we send the report.
+ void FinishCollection(bool did_proceed, int num_visits);
+
+ void OnCacheCollectionReady();
+
+ void OnRedirectionCollectionReady();
+
+ // content::WebContentsObserver implementation.
+ bool OnMessageReceived(const IPC::Message& message,
+ content::RenderFrameHost* render_frame_host) override;
+
+ protected:
+ friend class ThreatDetailsFactoryImpl;
+ friend class TestThreatDetailsFactory;
+
+ ThreatDetails(BaseUIManager* ui_manager,
+ content::WebContents* web_contents,
+ const UnsafeResource& resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service);
+
+ ~ThreatDetails() override;
+
+ // Called on the IO thread with the DOM details.
+ virtual void AddDOMDetails(
+ const int frame_tree_node_id,
+ const std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node>& params,
+ const KeyToFrameTreeIdMap& child_frame_tree_map);
+
+ // The report protocol buffer.
+ std::unique_ptr<ClientSafeBrowsingReportRequest> report_;
+
+ // Used to get a pointer to the HTTP cache.
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+
+ private:
+ friend class base::RefCountedThreadSafe<ThreatDetails>;
+ friend struct content::BrowserThread::DeleteOnThread<
+ content::BrowserThread::UI>;
+ friend class base::DeleteHelper<ThreatDetails>;
+
+ // Starts the collection of the report.
+ void StartCollection();
+
+ // Whether the url is "public" so we can add it to the report.
+ bool IsReportableUrl(const GURL& url) const;
+
+ // Finds an existing Resource for the given url, or creates a new one if not
+ // found, and adds it to |resources_|. Returns the found/created resource.
+ ClientSafeBrowsingReportRequest::Resource* FindOrCreateResource(
+ const GURL& url);
+
+ // Finds an existing HTMLElement for a given key, or creates a new one if not
+ // found and adds it to |elements_|. Returns the found/created element.
+ HTMLElement* FindOrCreateElement(const std::string& element_key);
+
+ // Adds a Resource to resources_ with the given parent-child
+ // relationship. |parent| and |tagname| can be empty, |children| can be NULL.
+ // Returns the Resource that was affected, or null if no work was done.
+ ClientSafeBrowsingReportRequest::Resource* AddUrl(
+ const GURL& url,
+ const GURL& parent,
+ const std::string& tagname,
+ const std::vector<GURL>* children);
+
+ // Message handler.
+ void OnReceivedThreatDOMDetails(
+ content::RenderFrameHost* sender,
+ const std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node>& params);
+
+ void AddRedirectUrlList(const std::vector<GURL>& urls);
+
+ // Adds an HTML Element to the DOM structure. |frame_tree_node_id| is the
+ // unique ID of the frame the element came from. |element_node_id| is a unique
+ // ID of the element within the frame. |tag_name| is the tag of the element.
+ // |parent_element_node_id| is the unique ID of the parent element within the
+ // frame. |attributes| contains the names and values of the element's
+ // attributes. |resource| is set if this element is a resource.
+ void AddDomElement(const int frame_tree_node_id,
+ const int element_node_id,
+ const std::string& tag_name,
+ const int parent_element_node_id,
+ const std::vector<AttributeNameValue>& attributes,
+ const ClientSafeBrowsingReportRequest::Resource* resource);
+
+ scoped_refptr<BaseUIManager> ui_manager_;
+
+ const UnsafeResource resource_;
+
+ // For every Url we collect we create a Resource message. We keep
+ // them in a map so we can avoid duplicates.
+ ResourceMap resources_;
+
+ // Store all HTML elements collected, keep them in a map for easy lookup.
+ ElementMap elements_;
+
+ // For each iframe element encountered we map the key of the iframe to the
+ // FrameTreeNode ID of the frame containing the contents of that iframe.
+ // We populate this map when receiving results from ThreatDomDetails, and use
+ // it in a second pass (after FinishCollection) to attach children to iframe
+ // elements.
+ // Should only be accessed on the IO thread.
+ KeyToFrameTreeIdMap iframe_key_to_frame_tree_id_map_;
+
+ // When getting a set of elements from a frame, we store the frame's
+ // FrameTreeNode ID and a collection of all top-level elements in that frame.
+ // It is populated as we receive sets of nodes from different renderers.
+ // It is used together with |iframe_key_to_frame_tree_id_map_| in a second
+ // pass to insert child elements under their parent iframe elements.
+ FrameTreeIdToChildIdsMap frame_tree_id_to_children_map_;
+
+ // Result from the cache extractor.
+ bool cache_result_;
+
+ // Whether user did proceed with the safe browsing blocking page or
+ // not.
+ bool did_proceed_;
+
+ // How many times this user has visited this page before.
+ int num_visits_;
+
+ // Keeps track of whether we have an ambiguous DOM in this report. This can
+ // happen when the HTML Elements returned by a renderer can't be
+ // associated with a parent Element in the parent frame.
+ bool ambiguous_dom_;
+
+ // The factory used to instantiate SafeBrowsingBlockingPage objects.
+ // Useful for tests, so they can provide their own implementation of
+ // SafeBrowsingBlockingPage.
+ static ThreatDetailsFactory* factory_;
+
+ // Used to collect details from the HTTP Cache.
+ scoped_refptr<ThreatDetailsCacheCollector> cache_collector_;
+
+ // Used to collect redirect urls from the history service
+ scoped_refptr<ThreatDetailsRedirectsCollector> redirects_collector_;
+
+ FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, HistoryServiceUrls);
+ FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, HttpsResourceSanitization);
+ FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, HTTPCacheNoEntries);
+ FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, HTTPCache);
+ FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, ThreatDOMDetails_AmbiguousDOM);
+ FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, ThreatDOMDetails_MultipleFrames);
+ FRIEND_TEST_ALL_PREFIXES(ThreatDetailsTest, ThreatDOMDetails);
+
+ DISALLOW_COPY_AND_ASSIGN(ThreatDetails);
+};
+
+// Factory for creating ThreatDetails. Useful for tests.
+class ThreatDetailsFactory {
+ public:
+ virtual ~ThreatDetailsFactory() {}
+
+ virtual ThreatDetails* CreateThreatDetails(
+ BaseUIManager* ui_manager,
+ content::WebContents* web_contents,
+ const security_interstitials::UnsafeResource& unsafe_resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service) = 0;
+};
+
+} // namespace safe_browsing
+
+#endif // COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_H_
diff --git a/chromium/components/safe_browsing/browser/threat_details_cache.cc b/chromium/components/safe_browsing/browser/threat_details_cache.cc
new file mode 100644
index 00000000000..8604cb0d012
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/threat_details_cache.cc
@@ -0,0 +1,242 @@
+// Copyright (c) 2012 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.
+//
+// Implementation of the ThreatDetails class.
+
+#include "components/safe_browsing/browser/threat_details.h"
+
+#include <stdint.h>
+
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/md5.h"
+#include "base/strings/string_util.h"
+#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/safe_browsing/browser/threat_details_cache.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_response_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_status.h"
+
+using content::BrowserThread;
+
+// Only send small files for now, a better strategy would use the size
+// of the whole report and the user's bandwidth.
+static const uint32_t kMaxBodySizeBytes = 1024;
+
+namespace safe_browsing {
+
+ThreatDetailsCacheCollector::ThreatDetailsCacheCollector()
+ : resources_(NULL), result_(NULL), has_started_(false) {}
+
+void ThreatDetailsCacheCollector::StartCacheCollection(
+ net::URLRequestContextGetter* request_context_getter,
+ ResourceMap* resources,
+ bool* result,
+ const base::Closure& callback) {
+ // Start the data collection from the HTTP cache. We use a URLFetcher
+ // and set the right flags so we only hit the cache.
+ DVLOG(1) << "Getting cache data for all urls...";
+ request_context_getter_ = request_context_getter;
+ resources_ = resources;
+ resources_it_ = resources_->begin();
+ result_ = result;
+ callback_ = callback;
+ has_started_ = true;
+
+ // Post a task in the message loop, so the callers don't need to
+ // check if we call their callback immediately.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&ThreatDetailsCacheCollector::OpenEntry, this));
+}
+
+bool ThreatDetailsCacheCollector::HasStarted() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return has_started_;
+}
+
+ThreatDetailsCacheCollector::~ThreatDetailsCacheCollector() {}
+
+// Fetch a URL and advance to the next one when done.
+void ThreatDetailsCacheCollector::OpenEntry() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DVLOG(1) << "OpenEntry";
+
+ if (resources_it_ == resources_->end()) {
+ AllDone(true);
+ return;
+ }
+
+ if (!request_context_getter_.get()) {
+ DVLOG(1) << "Missing request context getter";
+ AllDone(false);
+ return;
+ }
+
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("safe_browsing_cache_collector", R"(
+ semantics {
+ sender: "Threat Details Cache Collector"
+ description:
+ "This request fetches different items from safe browsing cache "
+ "and DOES NOT make an actual network request."
+ trigger:
+ "When safe browsing extended report is collecting data."
+ data:
+ "None"
+ destination: OTHER
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can enable or disable this feature by stopping sending "
+ "security incident reports to Google via disabling 'Automatically "
+ "report details of possible security incidents to Google.' in "
+ "Chrome's settings under Advanced Settings, Privacy. The feature "
+ "is disabled by default."
+ chrome_policy {
+ SafeBrowsingExtendedReportingOptInAllowed {
+ policy_options {mode: MANDATORY}
+ SafeBrowsingExtendedReportingOptInAllowed: false
+ }
+ }
+ })");
+
+ current_fetch_ =
+ net::URLFetcher::Create(GURL(resources_it_->first), net::URLFetcher::GET,
+ this, traffic_annotation);
+ data_use_measurement::DataUseUserData::AttachToFetcher(
+ current_fetch_.get(),
+ data_use_measurement::DataUseUserData::SAFE_BROWSING);
+ current_fetch_->SetRequestContext(request_context_getter_.get());
+ // Only from cache, and don't save cookies.
+ current_fetch_->SetLoadFlags(net::LOAD_ONLY_FROM_CACHE |
+ net::LOAD_SKIP_CACHE_VALIDATION |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
+ current_fetch_->SetAutomaticallyRetryOn5xx(false); // No retries.
+ current_fetch_->Start(); // OnURLFetchComplete will be called when done.
+}
+
+ClientSafeBrowsingReportRequest::Resource*
+ThreatDetailsCacheCollector::GetResource(const GURL& url) {
+ ResourceMap::iterator it = resources_->find(url.spec());
+ if (it != resources_->end()) {
+ return it->second.get();
+ }
+ return NULL;
+}
+
+void ThreatDetailsCacheCollector::OnURLFetchComplete(
+ const net::URLFetcher* source) {
+ DVLOG(1) << "OnUrlFetchComplete";
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(current_fetch_.get());
+ if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS &&
+ source->GetStatus().error() == net::ERR_CACHE_MISS) {
+ // Cache miss, skip this resource.
+ DVLOG(1) << "Cache miss for url: " << source->GetURL();
+ AdvanceEntry();
+ return;
+ }
+
+ if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS) {
+ // Some other error occurred, e.g. the request could have been cancelled.
+ DVLOG(1) << "Unsuccessful fetch: " << source->GetURL();
+ AdvanceEntry();
+ return;
+ }
+
+ // Set the response headers and body to the right resource, which
+ // might not be the same as the one we asked for.
+ // For redirects, resources_it_->first != url.spec().
+ ClientSafeBrowsingReportRequest::Resource* resource =
+ GetResource(source->GetURL());
+ if (!resource) {
+ DVLOG(1) << "Cannot find resource for url:" << source->GetURL();
+ AdvanceEntry();
+ return;
+ }
+
+ ReadResponse(resource, source);
+ std::string data;
+ source->GetResponseAsString(&data);
+ ReadData(resource, data);
+ AdvanceEntry();
+}
+
+void ThreatDetailsCacheCollector::ReadResponse(
+ ClientSafeBrowsingReportRequest::Resource* pb_resource,
+ const net::URLFetcher* source) {
+ DVLOG(1) << "ReadResponse";
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ net::HttpResponseHeaders* headers = source->GetResponseHeaders();
+ if (!headers) {
+ DVLOG(1) << "Missing response headers.";
+ return;
+ }
+
+ ClientSafeBrowsingReportRequest::HTTPResponse* pb_response =
+ pb_resource->mutable_response();
+ pb_response->mutable_firstline()->set_code(headers->response_code());
+ size_t iter = 0;
+ std::string name, value;
+ while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+ ClientSafeBrowsingReportRequest::HTTPHeader* pb_header =
+ pb_response->add_headers();
+ pb_header->set_name(name);
+ // Strip any Set-Cookie headers.
+ if (base::LowerCaseEqualsASCII(name, "set-cookie")) {
+ pb_header->set_value("");
+ } else {
+ pb_header->set_value(value);
+ }
+ }
+
+ if (!source->WasFetchedViaProxy()) {
+ pb_response->set_remote_ip(source->GetSocketAddress().ToString());
+ }
+}
+
+void ThreatDetailsCacheCollector::ReadData(
+ ClientSafeBrowsingReportRequest::Resource* pb_resource,
+ const std::string& data) {
+ DVLOG(1) << "ReadData";
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ClientSafeBrowsingReportRequest::HTTPResponse* pb_response =
+ pb_resource->mutable_response();
+ if (data.size() <= kMaxBodySizeBytes) { // Only send small bodies for now.
+ pb_response->set_body(data);
+ }
+ pb_response->set_bodylength(data.size());
+ pb_response->set_bodydigest(base::MD5String(data));
+}
+
+void ThreatDetailsCacheCollector::AdvanceEntry() {
+ DVLOG(1) << "AdvanceEntry";
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Advance to the next resource.
+ ++resources_it_;
+ current_fetch_.reset(NULL);
+
+ // Create a task so we don't take over the IO thread for too long.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&ThreatDetailsCacheCollector::OpenEntry, this));
+}
+
+void ThreatDetailsCacheCollector::AllDone(bool success) {
+ DVLOG(1) << "AllDone";
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ *result_ = success;
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback_);
+ callback_.Reset();
+}
+
+} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/browser/threat_details_cache.h b/chromium/components/safe_browsing/browser/threat_details_cache.h
new file mode 100644
index 00000000000..8c0667e5df3
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/threat_details_cache.h
@@ -0,0 +1,107 @@
+// Copyright (c) 2012 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_SAFE_BROWSING_BROWSER_THREAT_DETAILS_CACHE_H_
+#define COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_CACHE_H_
+
+// A class that gets threat details from the HTTP Cache.
+// An instance of this class is generated by ThreatDetails.
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/containers/hash_tables.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "net/base/completion_callback.h"
+#include "net/url_request/url_fetcher_delegate.h"
+
+namespace net {
+class URLFetcher;
+}
+
+namespace safe_browsing {
+
+// Maps a URL to its Resource.
+typedef base::hash_map<
+ std::string,
+ std::unique_ptr<ClientSafeBrowsingReportRequest::Resource>>
+ ResourceMap;
+
+class ThreatDetailsCacheCollector
+ : public base::RefCountedThreadSafe<ThreatDetailsCacheCollector>,
+ public net::URLFetcherDelegate {
+ public:
+ ThreatDetailsCacheCollector();
+
+ // We use |request_context_getter|, we modify |resources| and
+ // |result|, and we call |callback|, so they must all remain alive
+ // for the lifetime of this object.
+ void StartCacheCollection(
+ net::URLRequestContextGetter* request_context_getter,
+ ResourceMap* resources,
+ bool* result,
+ const base::Closure& callback);
+
+ // Returns whether or not StartCacheCollection has been called.
+ bool HasStarted();
+
+ protected:
+ // Implementation of URLFetcher::Delegate. Called after the request
+ // completes (either successfully or with failure).
+ void OnURLFetchComplete(const net::URLFetcher* source) override;
+
+ private:
+ friend class base::RefCountedThreadSafe<ThreatDetailsCacheCollector>;
+
+ ~ThreatDetailsCacheCollector() override;
+
+ // Points to the url for which we are fetching the HTTP cache entry or
+ // redirect chain.
+ ResourceMap::iterator resources_it_;
+
+ // Points to the resources_ map in the ThreatDetails.
+ ResourceMap* resources_;
+
+ // Points to the cache_result_ in the ThreatDetails.
+ bool* result_;
+
+ // Method we call when we are done. The caller must be alive for the
+ // whole time, we are modifying its state (see above).
+ base::Closure callback_;
+
+ // Set to true as soon as StartCacheCollection is called.
+ bool has_started_;
+
+ // Used to get a pointer to the current request context.
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+
+ // The current URLFetcher.
+ std::unique_ptr<net::URLFetcher> current_fetch_;
+
+ // Returns the resource from resources_ that corresponds to |url|
+ ClientSafeBrowsingReportRequest::Resource* GetResource(const GURL& url);
+
+ // Creates a new URLFetcher and starts it.
+ void OpenEntry();
+
+ // Read the HTTP response from |source| and add it to |pb_resource|.
+ void ReadResponse(ClientSafeBrowsingReportRequest::Resource* pb_resource,
+ const net::URLFetcher* source);
+
+ // Read the body |data| and add it to |pb_resource|.
+ void ReadData(ClientSafeBrowsingReportRequest::Resource* pb_resource,
+ const std::string& data);
+
+ // Called when we are done.
+ void AllDone(bool success);
+
+ // Advances to the next entry in resources_it_.
+ void AdvanceEntry();
+};
+
+} // namespace safe_browsing
+
+#endif // COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_CACHE_H_
diff --git a/chromium/components/safe_browsing/browser/threat_details_history.cc b/chromium/components/safe_browsing/browser/threat_details_history.cc
new file mode 100644
index 00000000000..4f6552452a2
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/threat_details_history.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2012 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.
+//
+// Implementation of the ThreatDetailsRedirectsCollector class.
+
+#include "components/safe_browsing/browser/threat_details_history.h"
+
+#include <stddef.h>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "components/history/core/browser/history_service.h"
+#include "components/safe_browsing/browser/threat_details.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+
+using content::BrowserThread;
+
+namespace safe_browsing {
+
+ThreatDetailsRedirectsCollector::ThreatDetailsRedirectsCollector(
+ const base::WeakPtr<history::HistoryService>& history_service)
+ : has_started_(false),
+ history_service_(history_service),
+ history_service_observer_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (history_service) {
+ history_service_observer_.Add(history_service.get());
+ }
+}
+
+void ThreatDetailsRedirectsCollector::StartHistoryCollection(
+ const std::vector<GURL>& urls,
+ const base::Closure& callback) {
+ DVLOG(1) << "Num of urls to check in history service: " << urls.size();
+ has_started_ = true;
+ callback_ = callback;
+
+ if (urls.size() == 0) {
+ AllDone();
+ return;
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&ThreatDetailsRedirectsCollector::StartGetRedirects, this,
+ urls));
+}
+
+bool ThreatDetailsRedirectsCollector::HasStarted() const {
+ return has_started_;
+}
+
+const std::vector<RedirectChain>&
+ThreatDetailsRedirectsCollector::GetCollectedUrls() const {
+ return redirects_urls_;
+}
+
+ThreatDetailsRedirectsCollector::~ThreatDetailsRedirectsCollector() {}
+
+void ThreatDetailsRedirectsCollector::StartGetRedirects(
+ const std::vector<GURL>& urls) {
+ // History access from profile needs to happen in UI thread
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ for (size_t i = 0; i < urls.size(); ++i) {
+ urls_.push_back(urls[i]);
+ }
+ urls_it_ = urls_.begin();
+ GetRedirects(*urls_it_);
+}
+
+void ThreatDetailsRedirectsCollector::GetRedirects(const GURL& url) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (!history_service_) {
+ AllDone();
+ return;
+ }
+
+ history_service_->QueryRedirectsTo(
+ url,
+ base::Bind(&ThreatDetailsRedirectsCollector::OnGotQueryRedirectsTo,
+ base::Unretained(this), url),
+ &request_tracker_);
+}
+
+void ThreatDetailsRedirectsCollector::OnGotQueryRedirectsTo(
+ const GURL& url,
+ const history::RedirectList* redirect_list) {
+ if (!redirect_list->empty()) {
+ std::vector<GURL> urllist;
+ urllist.push_back(url);
+ urllist.insert(urllist.end(), redirect_list->begin(), redirect_list->end());
+ redirects_urls_.push_back(urllist);
+ }
+
+ // Proceed to next url
+ ++urls_it_;
+
+ if (urls_it_ == urls_.end()) {
+ AllDone();
+ return;
+ }
+
+ GetRedirects(*urls_it_);
+}
+
+void ThreatDetailsRedirectsCollector::AllDone() {
+ DVLOG(1) << "AllDone";
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback_);
+ callback_.Reset();
+}
+
+void ThreatDetailsRedirectsCollector::HistoryServiceBeingDeleted(
+ history::HistoryService* history_service) {
+ history_service_observer_.Remove(history_service);
+ history_service_.reset();
+}
+
+} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/browser/threat_details_history.h b/chromium/components/safe_browsing/browser/threat_details_history.h
new file mode 100644
index 00000000000..2bd96134df1
--- /dev/null
+++ b/chromium/components/safe_browsing/browser/threat_details_history.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2012 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_SAFE_BROWSING_BROWSER_THREAT_DETAILS_HISTORY_H_
+#define COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_HISTORY_H_
+
+// This class gets redirect chain for urls from the history service.
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/containers/hash_tables.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/scoped_observer.h"
+#include "base/sequenced_task_runner_helpers.h"
+#include "base/task/cancelable_task_tracker.h"
+#include "components/history/core/browser/history_service_observer.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/base/completion_callback.h"
+
+namespace safe_browsing {
+
+typedef std::vector<GURL> RedirectChain;
+
+class ThreatDetailsRedirectsCollector
+ : public base::RefCountedThreadSafe<
+ ThreatDetailsRedirectsCollector,
+ content::BrowserThread::DeleteOnUIThread>,
+ public history::HistoryServiceObserver {
+ public:
+ explicit ThreatDetailsRedirectsCollector(
+ const base::WeakPtr<history::HistoryService>& history_service);
+
+ // Collects urls' redirects chain information from the history service.
+ // We get access to history service via web_contents in UI thread.
+ // Notice the callback will be posted to the IO thread.
+ void StartHistoryCollection(const std::vector<GURL>& urls,
+ const base::Closure& callback);
+
+ // Returns whether or not StartCacheCollection has been called.
+ bool HasStarted() const;
+
+ // Returns the redirect urls we get from history service
+ const std::vector<RedirectChain>& GetCollectedUrls() const;
+
+ // history::HistoryServiceObserver
+ void HistoryServiceBeingDeleted(
+ history::HistoryService* history_service) override;
+
+ private:
+ friend struct content::BrowserThread::DeleteOnThread<
+ content::BrowserThread::UI>;
+ friend class base::DeleteHelper<ThreatDetailsRedirectsCollector>;
+
+ ~ThreatDetailsRedirectsCollector() override;
+
+ void StartGetRedirects(const std::vector<GURL>& urls);
+ void GetRedirects(const GURL& url);
+ void OnGotQueryRedirectsTo(const GURL& url,
+ const history::RedirectList* redirect_list);
+
+ // Posts the callback method back to IO thread when redirects collecting
+ // is all done.
+ void AllDone();
+
+ base::CancelableTaskTracker request_tracker_;
+
+ // Method we call when we are done. The caller must be alive for the
+ // whole time, we are modifying its state (see above).
+ base::Closure callback_;
+
+ // Sets to true once StartHistoryCollection is called
+ bool has_started_;
+
+ // The urls we need to get redirects for
+ std::vector<GURL> urls_;
+ // The iterator goes over urls_
+ std::vector<GURL>::iterator urls_it_;
+ // The collected directs from history service
+ std::vector<RedirectChain> redirects_urls_;
+
+ base::WeakPtr<history::HistoryService> history_service_;
+ ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
+ history_service_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreatDetailsRedirectsCollector);
+};
+
+} // namespace safe_browsing
+
+#endif // COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_HISTORY_H_
diff --git a/chromium/components/safe_browsing/common/BUILD.gn b/chromium/components/safe_browsing/common/BUILD.gn
index 4e32332c949..212b21df0d3 100644
--- a/chromium/components/safe_browsing/common/BUILD.gn
+++ b/chromium/components/safe_browsing/common/BUILD.gn
@@ -20,3 +20,28 @@ source_set("common") {
"//url/ipc:url_ipc",
]
}
+
+static_library("safe_browsing_prefs") {
+ sources = [
+ "safe_browsing_prefs.cc",
+ "safe_browsing_prefs.h",
+ ]
+ deps = [
+ "//base:base",
+ "//components/prefs",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "safe_browsing_prefs_unittest.cc",
+ ]
+ deps = [
+ ":safe_browsing_prefs",
+ "//base:base",
+ "//base/test:test_support",
+ "//components/prefs:test_support",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/safe_browsing/common/DEPS b/chromium/components/safe_browsing/common/DEPS
index acf92ab14c9..61eff4271b8 100644
--- a/chromium/components/safe_browsing/common/DEPS
+++ b/chromium/components/safe_browsing/common/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+components/prefs",
"+ipc",
"+url"
]
diff --git a/chromium/components/safe_browsing_db/safe_browsing_prefs.cc b/chromium/components/safe_browsing/common/safe_browsing_prefs.cc
index 3895131cbbe..83f75881b64 100644
--- a/chromium/components/safe_browsing_db/safe_browsing_prefs.cc
+++ b/chromium/components/safe_browsing/common/safe_browsing_prefs.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
+
#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "components/prefs/pref_service.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
namespace {
diff --git a/chromium/components/safe_browsing_db/safe_browsing_prefs.h b/chromium/components/safe_browsing/common/safe_browsing_prefs.h
index 54666f3b80b..ec87b39be1a 100644
--- a/chromium/components/safe_browsing_db/safe_browsing_prefs.h
+++ b/chromium/components/safe_browsing/common/safe_browsing_prefs.h
@@ -4,8 +4,8 @@
//
// Safe Browsing preferences and some basic utility functions for using them.
-#ifndef COMPONENTS_SAFE_BROWSING_DB_SAFE_BROWSING_PREFS_H_
-#define COMPONENTS_SAFE_BROWSING_DB_SAFE_BROWSING_PREFS_H_
+#ifndef COMPONENTS_SAFE_BROWSING_COMMON_SAFE_BROWSING_PREFS_H_
+#define COMPONENTS_SAFE_BROWSING_COMMON_SAFE_BROWSING_PREFS_H_
#include "base/feature_list.h"
@@ -148,4 +148,4 @@ void UpdatePrefsBeforeSecurityInterstitial(PrefService* prefs);
} // namespace safe_browsing
-#endif // COMPONENTS_SAFE_BROWSING_DB_SAFE_BROWSING_PREFS_H_
+#endif // COMPONENTS_SAFE_BROWSING_COMMON_SAFE_BROWSING_PREFS_H_
diff --git a/chromium/components/safe_browsing_db/safe_browsing_prefs_unittest.cc b/chromium/components/safe_browsing/common/safe_browsing_prefs_unittest.cc
index b6b3a088b45..5d110118147 100644
--- a/chromium/components/safe_browsing_db/safe_browsing_prefs_unittest.cc
+++ b/chromium/components/safe_browsing/common/safe_browsing_prefs_unittest.cc
@@ -11,7 +11,7 @@
#include "base/test/scoped_feature_list.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace safe_browsing {
diff --git a/chromium/components/safe_browsing/common/safebrowsing_constants.cc b/chromium/components/safe_browsing/common/safebrowsing_constants.cc
index 543f725e964..22e6de0cdf3 100644
--- a/chromium/components/safe_browsing/common/safebrowsing_constants.cc
+++ b/chromium/components/safe_browsing/common/safebrowsing_constants.cc
@@ -9,4 +9,8 @@ namespace safe_browsing {
const base::FilePath::CharType kSafeBrowsingBaseFilename[] =
FILE_PATH_LITERAL("Safe Browsing");
+const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies");
+const base::FilePath::CharType kChannelIDFile[] =
+ FILE_PATH_LITERAL(" Channel IDs");
+
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/common/safebrowsing_constants.h b/chromium/components/safe_browsing/common/safebrowsing_constants.h
index 17173ccf7c0..e6776b56274 100644
--- a/chromium/components/safe_browsing/common/safebrowsing_constants.h
+++ b/chromium/components/safe_browsing/common/safebrowsing_constants.h
@@ -11,6 +11,9 @@ namespace safe_browsing {
extern const base::FilePath::CharType kSafeBrowsingBaseFilename[];
+// Filename suffix for the cookie database.
+extern const base::FilePath::CharType kCookiesFile[];
+extern const base::FilePath::CharType kChannelIDFile[];
}
#endif // COMPONENTS_SAFE_BROWSING_COMMON_SAFEBROWSING_CONSTANTS_H_
diff --git a/chromium/components/safe_browsing/common/safebrowsing_messages.h b/chromium/components/safe_browsing/common/safebrowsing_messages.h
index 1e03fa10f45..400201d0d2d 100644
--- a/chromium/components/safe_browsing/common/safebrowsing_messages.h
+++ b/chromium/components/safe_browsing/common/safebrowsing_messages.h
@@ -4,6 +4,7 @@
// Multiply-included message file, so no include guard.
+#include <stdint.h>
#include <string>
#include <vector>
@@ -17,7 +18,7 @@
// A node is essentially a frame.
IPC_STRUCT_BEGIN(SafeBrowsingHostMsg_ThreatDOMDetails_Node)
// A unique ID for this node, unique to the current Render Frame.
- IPC_STRUCT_MEMBER(int, node_id)
+ IPC_STRUCT_MEMBER(int32_t, node_id)
// URL of this resource. Can be empty.
IPC_STRUCT_MEMBER(GURL, url)
@@ -30,16 +31,21 @@ IPC_STRUCT_BEGIN(SafeBrowsingHostMsg_ThreatDOMDetails_Node)
IPC_STRUCT_MEMBER(GURL, parent)
// The unique ID of the parent node. Can be 0 if this is the top node.
- IPC_STRUCT_MEMBER(int, parent_node_id)
+ IPC_STRUCT_MEMBER(int32_t, parent_node_id)
// children of this node. Can be emtpy.
IPC_STRUCT_MEMBER(std::vector<GURL>, children)
// The unique IDs of the child nodes. Can be empty if there are no children.
- IPC_STRUCT_MEMBER(std::vector<int>, child_node_ids)
+ IPC_STRUCT_MEMBER(std::vector<int32_t>, child_node_ids)
// The node's attributes, as a collection of name-value pairs.
IPC_STRUCT_MEMBER(std::vector<safe_browsing::AttributeNameValue>, attributes)
+
+ // If this node represents a frame or iframe, then this field is set to the
+ // routing ID of the local or remote frame in this renderer process that is
+ // responsible for rendering the contents of this frame (to handle OOPIFs).
+ IPC_STRUCT_MEMBER(int32_t, child_frame_routing_id)
IPC_STRUCT_END()
// SafeBrowsing client-side detection messages sent from the renderer to the
diff --git a/chromium/components/safe_browsing/csd.proto b/chromium/components/safe_browsing/csd.proto
index 023abe4ffbd..7bb5920bd7c 100644
--- a/chromium/components/safe_browsing/csd.proto
+++ b/chromium/components/safe_browsing/csd.proto
@@ -34,6 +34,14 @@ message ChromeUserPopulation {
EXTENDED_REPORTING = 2;
}
optional UserPopulation user_population = 1;
+
+ // If user enabled history sync.
+ optional bool is_history_sync_enabled = 2;
+
+ // The finch active groups this user belongs to (if any). Active group is
+ // defined by finch trial name and group name. Trial name and group name are
+ // concatenated with separator "|", e.g. "PingOnlyTrial|DefaultGroup".
+ repeated string finch_active_groups = 4;
}
message ClientPhishingRequest {
@@ -200,20 +208,24 @@ message LoginReputationClientRequest {
repeated Frame frames = 3;
// The message contains fields needed for a password reuse event.
+ // Next tag: 4
message PasswordReuseEvent {
- // Origins that the reused password had been used on. The origins are
- // maintained by Chrome password manager.
- // The field is filled in only when TriggerType is PASSWORD_REUSE_EVENT.
- repeated string password_reused_original_origins = 1;
+ reserved 1;
// The frame that the password reuse is detected.
optional int32 frame_id = 2;
+
+ // Whether the reused password is used for Chrome signin.
+ optional bool is_chrome_signin_password = 3;
}
optional PasswordReuseEvent password_reuse_event = 4;
// The number of verdicts stored on the client.
optional int32 stored_verdict_cnt = 5;
+
+ // Chrome user population.
+ optional ChromeUserPopulation population = 6;
}
// The message is used for client response for login reputation requests.
@@ -489,8 +501,9 @@ message ClientDownloadRequest {
// comes last.
repeated ReferrerChainEntry referrer_chain = 36;
- // Whether DownloadAttribution Finch experiment is enabled for this ping.
- optional bool download_attribution_finch_enabled = 39;
+ // Deprecated.
+ optional bool DEPRECATED_download_attribution_finch_enabled = 39
+ [deprecated = true];
}
message ReferrerChainEntry {
diff --git a/chromium/components/safe_browsing/password_protection/password_protection_request.cc b/chromium/components/safe_browsing/password_protection/password_protection_request.cc
index e7db6e05543..182070830a2 100644
--- a/chromium/components/safe_browsing/password_protection/password_protection_request.cc
+++ b/chromium/components/safe_browsing/password_protection/password_protection_request.cc
@@ -7,27 +7,33 @@
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/base/url_util.h"
#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
using content::BrowserThread;
+using content::WebContents;
namespace safe_browsing {
PasswordProtectionRequest::PasswordProtectionRequest(
+ WebContents* web_contents,
const GURL& main_frame_url,
+ const GURL& password_form_action,
+ const GURL& password_form_frame_url,
+ const std::string& saved_domain,
LoginReputationClientRequest::TriggerType type,
- bool is_extended_reporting,
- bool is_incognito,
- base::WeakPtr<PasswordProtectionService> pps,
+ PasswordProtectionService* pps,
int request_timeout_in_ms)
- : main_frame_url_(main_frame_url),
+ : web_contents_(web_contents),
+ main_frame_url_(main_frame_url),
+ password_form_action_(password_form_action),
+ password_form_frame_url_(password_form_frame_url),
+ saved_domain_(saved_domain),
request_type_(type),
- is_extended_reporting_(is_extended_reporting),
- is_incognito_(is_incognito),
password_protection_service_(pps),
request_timeout_in_ms_(request_timeout_in_ms),
weakptr_factory_(this) {
@@ -40,36 +46,27 @@ PasswordProtectionRequest::~PasswordProtectionRequest() {
void PasswordProtectionRequest::Start() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // Initially we only send ping for Safe Browsing Extended Reporting users when
- // they are not in incognito mode. We may loose these conditions later.
- if (is_incognito_) {
- Finish(RequestOutcome::INCOGNITO, nullptr);
- return;
- }
- if (!is_extended_reporting_) {
- Finish(RequestOutcome::NO_EXTENDED_REPORTING, nullptr);
- return;
- }
-
- CheckWhitelistsOnUIThread();
+ CheckWhitelistOnUIThread();
}
-void PasswordProtectionRequest::CheckWhitelistsOnUIThread() {
+void PasswordProtectionRequest::CheckWhitelistOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(password_protection_service_);
+ bool* match_whitelist = new bool(false);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ tracker_.PostTaskAndReply(
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(), FROM_HERE,
base::Bind(&PasswordProtectionService::CheckCsdWhitelistOnIOThread,
- password_protection_service_, main_frame_url_,
- base::Bind(&PasswordProtectionRequest::OnWhitelistCheckDone,
- GetWeakPtr())));
+ base::Unretained(password_protection_service_),
+ main_frame_url_, match_whitelist),
+ base::Bind(&PasswordProtectionRequest::OnWhitelistCheckDone, this,
+ base::Owned(match_whitelist)));
}
-void PasswordProtectionRequest::OnWhitelistCheckDone(bool match_whitelist) {
+void PasswordProtectionRequest::OnWhitelistCheckDone(
+ const bool* match_whitelist) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (match_whitelist)
- Finish(RequestOutcome::MATCHED_WHITELIST, nullptr);
+ if (*match_whitelist)
+ Finish(PasswordProtectionService::MATCHED_WHITELIST, nullptr);
else
CheckCachedVerdicts();
}
@@ -77,7 +74,7 @@ void PasswordProtectionRequest::OnWhitelistCheckDone(bool match_whitelist) {
void PasswordProtectionRequest::CheckCachedVerdicts() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!password_protection_service_) {
- Finish(RequestOutcome::SERVICE_DESTROYED, nullptr);
+ Finish(PasswordProtectionService::SERVICE_DESTROYED, nullptr);
return;
}
@@ -86,7 +83,8 @@ void PasswordProtectionRequest::CheckCachedVerdicts() {
auto verdict = password_protection_service_->GetCachedVerdict(
main_frame_url_, cached_response.get());
if (verdict != LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED)
- Finish(RequestOutcome::RESPONSE_ALREADY_CACHED, std::move(cached_response));
+ Finish(PasswordProtectionService::RESPONSE_ALREADY_CACHED,
+ std::move(cached_response));
else
SendRequest();
}
@@ -95,14 +93,43 @@ void PasswordProtectionRequest::FillRequestProto() {
request_proto_ = base::MakeUnique<LoginReputationClientRequest>();
request_proto_->set_page_url(main_frame_url_.spec());
request_proto_->set_trigger_type(request_type_);
+ password_protection_service_->FillUserPopulation(request_type_,
+ request_proto_.get());
request_proto_->set_stored_verdict_cnt(
password_protection_service_->GetStoredVerdictCount());
LoginReputationClientRequest::Frame* main_frame =
request_proto_->add_frames();
main_frame->set_url(main_frame_url_.spec());
+ main_frame->set_frame_index(0 /* main frame */);
password_protection_service_->FillReferrerChain(
main_frame_url_, -1 /* tab id not available */, main_frame);
- // TODO(jialiul): Add sub-frame information and password form information.
+
+ switch (request_type_) {
+ case LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE: {
+ LoginReputationClientRequest::Frame::Form* password_form;
+ if (password_form_frame_url_ == main_frame_url_) {
+ main_frame->set_has_password_field(true);
+ password_form = main_frame->add_forms();
+ } else {
+ LoginReputationClientRequest::Frame* password_frame =
+ request_proto_->add_frames();
+ password_frame->set_url(password_form_frame_url_.spec());
+ password_frame->set_has_password_field(true);
+ // TODO(jialiul): Add referrer chain for subframes later.
+ password_form = password_frame->add_forms();
+ }
+ password_form->set_action_url(password_form_action_.spec());
+ // TODO(jialiul): Fill more frame specific info when Safe Browsing backend
+ // is ready to handle these pieces of information.
+ break;
+ }
+ case LoginReputationClientRequest::PASSWORD_REUSE_EVENT: {
+ // TODO(jialiul): Fill more password reuse related information when ready.
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
}
void PasswordProtectionRequest::SendRequest() {
@@ -111,16 +138,47 @@ void PasswordProtectionRequest::SendRequest() {
std::string serialized_request;
if (!request_proto_->SerializeToString(&serialized_request)) {
- Finish(RequestOutcome::REQUEST_MALFORMED, nullptr);
+ Finish(PasswordProtectionService::REQUEST_MALFORMED, nullptr);
return;
}
// In case the request take too long, we set a timer to cancel this request.
StartTimeout();
-
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("password_protection_request", R"(
+ semantics {
+ sender: "Safe Browsing"
+ description:
+ "When the user is about to log in to a new, uncommon site, Chrome "
+ "will send a request to Safe Browsing to determine if the page is "
+ "phishing. It'll then show a warning if the page poses a risk of "
+ "phishing."
+ trigger:
+ "When a user focuses on a password field on a page that they "
+ "haven't visited before and that isn't popular or known to be safe."
+ data:
+ "URL and referrer of the current page, password form action, and "
+ "iframe structure."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: true
+ cookies_store: "Safe Browsing Cookie Store"
+ setting:
+ "Users can control this feature via 'Protect you and your device "
+ "from dangerous sites' or 'Automatically report details of "
+ "possible security incidents to Google' setting under 'Privacy'. "
+ "By default, the first setting is enabled and the second is not."
+ chrome_policy {
+ SafeBrowsingExtendedReportingOptInAllowed {
+ policy_options {mode: MANDATORY}
+ SafeBrowsingExtendedReportingOptInAllowed: false
+ }
+ }
+ })");
fetcher_ = net::URLFetcher::Create(
0, PasswordProtectionService::GetPasswordProtectionRequestUrl(),
- net::URLFetcher::POST, this);
+ net::URLFetcher::POST, this, traffic_annotation);
data_use_measurement::DataUseUserData::AttachToFetcher(
fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
@@ -157,7 +215,7 @@ void PasswordProtectionRequest::OnURLFetchComplete(
is_success ? response_code : status.error());
if (!is_success || net::HTTP_OK != response_code) {
- Finish(RequestOutcome::FETCH_FAILED, nullptr);
+ Finish(PasswordProtectionService::FETCH_FAILED, nullptr);
return;
}
@@ -169,32 +227,37 @@ void PasswordProtectionRequest::OnURLFetchComplete(
fetcher_.reset(); // We don't need it anymore.
UMA_HISTOGRAM_TIMES("PasswordProtection.RequestNetworkDuration",
base::TimeTicks::Now() - request_start_time_);
- if (response->ParseFromString(response_body)) {
- Finish(RequestOutcome::SUCCEEDED, std::move(response));
- } else {
- Finish(RequestOutcome::RESPONSE_MALFORMED, nullptr);
- }
+ if (response->ParseFromString(response_body))
+ Finish(PasswordProtectionService::SUCCEEDED, std::move(response));
+ else
+ Finish(PasswordProtectionService::RESPONSE_MALFORMED, nullptr);
}
void PasswordProtectionRequest::Finish(
- RequestOutcome outcome,
+ PasswordProtectionService::RequestOutcome outcome,
std::unique_ptr<LoginReputationClientResponse> response) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ tracker_.TryCancelAll();
- UMA_HISTOGRAM_ENUMERATION("PasswordProtection.RequestOutcome", outcome,
- RequestOutcome::MAX_OUTCOME);
+ if (request_type_ == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) {
+ UMA_HISTOGRAM_ENUMERATION(kPasswordOnFocusRequestOutcomeHistogramName,
+ outcome, PasswordProtectionService::MAX_OUTCOME);
+ } else {
+ UMA_HISTOGRAM_ENUMERATION(kPasswordEntryRequestOutcomeHistogramName,
+ outcome, PasswordProtectionService::MAX_OUTCOME);
+ }
if (response) {
switch (request_type_) {
case LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE:
UMA_HISTOGRAM_ENUMERATION(
- "PasswordProtection.UnfamiliarLoginPageVerdict",
+ "PasswordProtection.Verdict.PasswordFieldOnFocus",
response->verdict_type(),
LoginReputationClientResponse_VerdictType_VerdictType_MAX + 1);
break;
case LoginReputationClientRequest::PASSWORD_REUSE_EVENT:
UMA_HISTOGRAM_ENUMERATION(
- "PasswordProtection.PasswordReuseEventVerdict",
+ "PasswordProtection.Verdict.ProtectedPasswordEntry",
response->verdict_type(),
LoginReputationClientResponse_VerdictType_VerdictType_MAX + 1);
break;
@@ -211,7 +274,9 @@ void PasswordProtectionRequest::Cancel(bool timed_out) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
fetcher_.reset();
- Finish(timed_out ? TIMEDOUT : CANCELED, nullptr);
+ Finish(timed_out ? PasswordProtectionService::TIMEDOUT
+ : PasswordProtectionService::CANCELED,
+ nullptr);
}
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/password_protection/password_protection_request.h b/chromium/components/safe_browsing/password_protection/password_protection_request.h
index 52be0c11eb4..89fcf772f41 100644
--- a/chromium/components/safe_browsing/password_protection/password_protection_request.h
+++ b/chromium/components/safe_browsing/password_protection/password_protection_request.h
@@ -7,7 +7,9 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/task/cancelable_task_tracker.h"
#include "components/safe_browsing/password_protection/password_protection_service.h"
+#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
@@ -19,35 +21,34 @@ namespace safe_browsing {
// A request for checking if an unfamiliar login form or a password reuse event
// is safe. PasswordProtectionRequest objects are owned by
// PasswordProtectionService indicated by |password_protection_service_|.
-class PasswordProtectionRequest : public net::URLFetcherDelegate {
+// PasswordProtectionService is RefCountedThreadSafe such that it can post task
+// safely between IO and UI threads. It can only be destroyed on UI thread.
+//
+// PasswordProtectionRequest flow:
+// Step| Thread | Task
+// (1) | UI | If incognito or !SBER, quit request.
+// (2) | UI | Add task to IO thread for whitelist checking.
+// (3) | IO | Check whitelist and return the result back to UI thread.
+// (4) | UI | If whitelisted, check verdict cache; else quit request.
+// (5) | UI | If verdict cached, quit request; else prepare request proto.
+// (6) | UI | Start a timeout task, and send network request.
+// (7) | UI | On receiving response, handle response and finish.
+// | | On request timeout, cancel request.
+// | | On deletion of |password_protection_service_|, cancel request.
+class PasswordProtectionRequest : public base::RefCountedThreadSafe<
+ PasswordProtectionRequest,
+ content::BrowserThread::DeleteOnUIThread>,
+ public net::URLFetcherDelegate {
public:
- // The outcome of the request. These values are used for UMA.
- // DO NOT CHANGE THE ORDERING OF THESE VALUES.
- enum RequestOutcome {
- UNKNOWN = 0,
- SUCCEEDED = 1,
- CANCELED = 2,
- TIMEDOUT = 3,
- MATCHED_WHITELIST = 4,
- RESPONSE_ALREADY_CACHED = 5,
- NO_EXTENDED_REPORTING = 6,
- INCOGNITO = 7,
- REQUEST_MALFORMED = 8,
- FETCH_FAILED = 9,
- RESPONSE_MALFORMED = 10,
- SERVICE_DESTROYED = 11,
- MAX_OUTCOME
- };
-
- PasswordProtectionRequest(const GURL& main_frame_url,
+ PasswordProtectionRequest(content::WebContents* web_contents,
+ const GURL& main_frame_url,
+ const GURL& password_form_action,
+ const GURL& password_form_frame_url,
+ const std::string& saved_domain,
LoginReputationClientRequest::TriggerType type,
- bool is_extended_reporting,
- bool is_incognito,
- base::WeakPtr<PasswordProtectionService> pps,
+ PasswordProtectionService* pps,
int request_timeout_in_ms);
- ~PasswordProtectionRequest() override;
-
base::WeakPtr<PasswordProtectionRequest> GetWeakPtr() {
return weakptr_factory_.GetWeakPtr();
}
@@ -66,12 +67,25 @@ class PasswordProtectionRequest : public net::URLFetcherDelegate {
GURL main_frame_url() const { return main_frame_url_; }
- bool is_incognito() const { return is_incognito_; }
+ LoginReputationClientRequest* request_proto() { return request_proto_.get(); }
private:
+ friend class base::RefCountedThreadSafe<PasswordProtectionRequest>;
+ friend struct content::BrowserThread::DeleteOnThread<
+ content::BrowserThread::UI>;
+ friend class base::DeleteHelper<PasswordProtectionRequest>;
+ ~PasswordProtectionRequest() override;
+
+ void CheckWhitelistOnUIThread();
+
// If |main_frame_url_| matches whitelist, call Finish() immediately;
- // otherwise call CheckCachedVerdicts().
- void OnWhitelistCheckDone(bool match_whitelist);
+ // otherwise call CheckCachedVerdicts(). It is the task posted back to UI
+ // thread by the PostTaskAndReply() in CheckWhitelistOnUIThread().
+ // |match_whitelist| boolean pointer is used to pass whitelist checking result
+ // between UI and IO thread. The object it points to will be deleted at the
+ // end of OnWhitelistCheckDone(), since base::Owned() transfers its ownership
+ // to this callback function.
+ void OnWhitelistCheckDone(const bool* match_whitelist);
// Looks up cached verdicts. If verdict is already cached, call SendRequest();
// otherwise call Finish().
@@ -87,22 +101,26 @@ class PasswordProtectionRequest : public net::URLFetcherDelegate {
void StartTimeout();
// |this| will be destroyed after calling this function.
- void Finish(RequestOutcome outcome,
+ void Finish(PasswordProtectionService::RequestOutcome outcome,
std::unique_ptr<LoginReputationClientResponse> response);
- void CheckWhitelistsOnUIThread();
+ // WebContents of the password protection event.
+ content::WebContents* web_contents_;
// Main frame URL of the login form.
- GURL main_frame_url_;
+ const GURL main_frame_url_;
- // If this request is for unfamiliar login page or for a password reuse event.
- const LoginReputationClientRequest::TriggerType request_type_;
+ // The action URL of the password form.
+ const GURL password_form_action_;
- // If user is opted-in Safe Browsing Extended Reporting.
- const bool is_extended_reporting_;
+ // Frame url of the detected password form.
+ const GURL password_form_frame_url_;
- // If current session is in incognito mode.
- const bool is_incognito_;
+ // Domain on which a password is saved and gets reused.
+ const std::string saved_domain_;
+
+ // If this request is for unfamiliar login page or for a password reuse event.
+ const LoginReputationClientRequest::TriggerType request_type_;
// When request is sent.
base::TimeTicks request_start_time_;
@@ -111,7 +129,8 @@ class PasswordProtectionRequest : public net::URLFetcherDelegate {
std::unique_ptr<net::URLFetcher> fetcher_;
// The PasswordProtectionService instance owns |this|.
- base::WeakPtr<PasswordProtectionService> password_protection_service_;
+ // Can only be accessed on UI thread.
+ PasswordProtectionService* password_protection_service_;
// If we haven't receive response after this period of time, we cancel this
// request.
@@ -119,6 +138,9 @@ class PasswordProtectionRequest : public net::URLFetcherDelegate {
std::unique_ptr<LoginReputationClientRequest> request_proto_;
+ // Needed for canceling tasks posted to different threads.
+ base::CancelableTaskTracker tracker_;
+
base::WeakPtrFactory<PasswordProtectionRequest> weakptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PasswordProtectionRequest);
};
diff --git a/chromium/components/safe_browsing/password_protection/password_protection_service.cc b/chromium/components/safe_browsing/password_protection/password_protection_service.cc
index 3aee7ac1141..bdc9cff88cd 100644
--- a/chromium/components/safe_browsing/password_protection/password_protection_service.cc
+++ b/chromium/components/safe_browsing/password_protection/password_protection_service.cc
@@ -4,9 +4,11 @@
#include "components/safe_browsing/password_protection/password_protection_service.h"
+#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -17,10 +19,13 @@
#include "components/safe_browsing_db/database_manager.h"
#include "components/safe_browsing_db/v4_protocol_manager_util.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
#include "google_apis/google_api_keys.h"
#include "net/base/escape.h"
+#include "net/base/url_util.h"
using content::BrowserThread;
+using content::WebContents;
using history::HistoryService;
namespace safe_browsing {
@@ -63,6 +68,17 @@ GURL GetHostNameWithHTTPScheme(const GURL& url) {
} // namespace
+const base::Feature kPasswordFieldOnFocusPinging{
+ "PasswordFieldOnFocusPinging", base::FEATURE_DISABLED_BY_DEFAULT};
+
+const base::Feature kProtectedPasswordEntryPinging{
+ "ProtectedPasswordEntryPinging", base::FEATURE_DISABLED_BY_DEFAULT};
+
+const char kPasswordOnFocusRequestOutcomeHistogramName[] =
+ "PasswordProtection.RequestOutcome.PasswordFieldOnFocus";
+const char kPasswordEntryRequestOutcomeHistogramName[] =
+ "PasswordProtection.RequestOutcome.ProtectedPasswordEntry";
+
PasswordProtectionService::PasswordProtectionService(
const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager,
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
@@ -80,35 +96,27 @@ PasswordProtectionService::PasswordProtectionService(
}
PasswordProtectionService::~PasswordProtectionService() {
+ tracker_.TryCancelAll();
CancelPendingRequests();
history_service_observer_.RemoveAll();
weak_factory_.InvalidateWeakPtrs();
}
-void PasswordProtectionService::RecordPasswordReuse(const GURL& url) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(database_manager_);
- if (!url.is_valid())
- return;
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(
- &PasswordProtectionService::CheckCsdWhitelistOnIOThread, GetWeakPtr(),
- url,
- base::Bind(&PasswordProtectionService::OnMatchCsdWhiteListResult,
- base::Unretained(this))));
-}
-
void PasswordProtectionService::CheckCsdWhitelistOnIOThread(
const GURL& url,
- const CheckCsdWhitelistCallback& callback) {
+ bool* check_result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(database_manager_);
- bool check_result = database_manager_->MatchCsdWhitelistUrl(url);
- DCHECK(callback);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(callback, check_result));
+ *check_result =
+ url.is_valid() ? database_manager_->MatchCsdWhitelistUrl(url) : true;
+}
+
+bool PasswordProtectionService::CanGetReputationOfURL(const GURL& url) {
+ if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS())
+ return false;
+
+ const std::string& hostname = url.HostNoBrackets();
+ return !net::IsLocalhost(hostname) && !net::IsHostnameNonUnique(hostname) &&
+ hostname.find('.') != std::string::npos;
}
LoginReputationClientResponse::VerdictType
@@ -199,30 +207,123 @@ void PasswordProtectionService::CacheVerdict(
std::string(), std::move(verdict_dictionary));
}
+void PasswordProtectionService::CleanUpExpiredVerdicts() {
+ DCHECK(content_settings_);
+ if (GetStoredVerdictCount() <= 0)
+ return;
+
+ ContentSettingsForOneType password_protection_settings;
+ content_settings_->GetSettingsForOneType(
+ CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(),
+ &password_protection_settings);
+
+ for (const ContentSettingPatternSource& source :
+ password_protection_settings) {
+ GURL primary_pattern_url = GURL(source.primary_pattern.ToString());
+ // Find all verdicts associated with this origin.
+ std::unique_ptr<base::DictionaryValue> verdict_dictionary =
+ base::DictionaryValue::From(content_settings_->GetWebsiteSetting(
+ primary_pattern_url, GURL(),
+ CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), nullptr));
+ std::vector<std::string> expired_keys;
+ for (base::DictionaryValue::Iterator it(*verdict_dictionary.get());
+ !it.IsAtEnd(); it.Advance()) {
+ base::DictionaryValue* verdict_entry = nullptr;
+ CHECK(verdict_dictionary->GetDictionaryWithoutPathExpansion(
+ it.key(), &verdict_entry));
+ int verdict_received_time;
+ LoginReputationClientResponse verdict;
+ CHECK(ParseVerdictEntry(verdict_entry, &verdict_received_time, &verdict));
+
+ if (IsCacheExpired(verdict_received_time, verdict.cache_duration_sec())) {
+ // Since DictionaryValue::Iterator cannot be used to modify the
+ // dictionary, we record the keys of expired verdicts in |expired_keys|
+ // and remove them in the next for-loop.
+ expired_keys.push_back(it.key());
+ }
+ }
+
+ for (const std::string& key : expired_keys) {
+ verdict_dictionary->RemoveWithoutPathExpansion(key, nullptr);
+ stored_verdict_count_--;
+ }
+
+ if (verdict_dictionary->size() == 0u) {
+ content_settings_->ClearSettingsForOneTypeWithPredicate(
+ CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, base::Time(),
+ base::Bind(&OriginMatchPrimaryPattern, primary_pattern_url));
+ } else if (expired_keys.size() > 0u) {
+ // Set the website setting of this origin with the updated
+ // |verdict_diectionary|.
+ content_settings_->SetWebsiteSettingDefaultScope(
+ primary_pattern_url, GURL(),
+ CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(),
+ std::move(verdict_dictionary));
+ }
+ }
+}
+
void PasswordProtectionService::StartRequest(
+ WebContents* web_contents,
const GURL& main_frame_url,
+ const GURL& password_form_action,
+ const GURL& password_form_frame_url,
+ const std::string& saved_domain,
LoginReputationClientRequest::TriggerType type) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!IsPingingEnabled())
- return;
- std::unique_ptr<PasswordProtectionRequest> request =
- base::MakeUnique<PasswordProtectionRequest>(
- main_frame_url, type, IsExtendedReporting(), IsIncognito(),
- GetWeakPtr(), GetRequestTimeoutInMS());
+ scoped_refptr<PasswordProtectionRequest> request(
+ new PasswordProtectionRequest(web_contents, main_frame_url,
+ password_form_action,
+ password_form_frame_url, saved_domain, type,
+ this, GetRequestTimeoutInMS()));
DCHECK(request);
request->Start();
requests_.insert(std::move(request));
}
+void PasswordProtectionService::MaybeStartPasswordFieldOnFocusRequest(
+ WebContents* web_contents,
+ const GURL& main_frame_url,
+ const GURL& password_form_action,
+ const GURL& password_form_frame_url) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (CanSendPing(kPasswordFieldOnFocusPinging, main_frame_url)) {
+ StartRequest(web_contents, main_frame_url, password_form_action,
+ password_form_frame_url,
+ std::string(), /* saved_domain: not used for this type */
+ LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
+ }
+}
+
+void PasswordProtectionService::MaybeStartProtectedPasswordEntryRequest(
+ WebContents* web_contents,
+ const GURL& main_frame_url,
+ const std::string& saved_domain) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (CanSendPing(kProtectedPasswordEntryPinging, main_frame_url)) {
+ StartRequest(web_contents, main_frame_url, GURL(), GURL(), saved_domain,
+ LoginReputationClientRequest::PASSWORD_REUSE_EVENT);
+ }
+}
+
+bool PasswordProtectionService::CanSendPing(const base::Feature& feature,
+ const GURL& main_frame_url) {
+ RequestOutcome request_outcome = URL_NOT_VALID_FOR_REPUTATION_COMPUTING;
+ if (IsPingingEnabled(kPasswordFieldOnFocusPinging, &request_outcome) &&
+ CanGetReputationOfURL(main_frame_url)) {
+ return true;
+ }
+ RecordNoPingingReason(feature, request_outcome);
+ return false;
+}
+
void PasswordProtectionService::RequestFinished(
PasswordProtectionRequest* request,
std::unique_ptr<LoginReputationClientResponse> response) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(request);
- // TODO(jialiul): We don't cache verdict for incognito mode for now.
- // Later we may consider temporarily caching verdict.
- if (!request->is_incognito() && response)
+ if (response)
CacheVerdict(request->main_frame_url(), response.get(), base::Time::Now());
// Finished processing this request. Remove it from pending list.
@@ -246,6 +347,11 @@ void PasswordProtectionService::CancelPendingRequests() {
DCHECK(requests_.empty());
}
+scoped_refptr<SafeBrowsingDatabaseManager>
+PasswordProtectionService::database_manager() {
+ return database_manager_;
+}
+
GURL PasswordProtectionService::GetPasswordProtectionRequestUrl() {
GURL url(kPasswordProtectionRequestUrl);
std::string api_key = google_apis::GetAPIKey();
@@ -283,11 +389,29 @@ int PasswordProtectionService::GetRequestTimeoutInMS() {
return kRequestTimeoutMs;
}
-void PasswordProtectionService::OnMatchCsdWhiteListResult(
- bool match_whitelist) {
- UMA_HISTOGRAM_BOOLEAN(
- "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist",
- match_whitelist);
+void PasswordProtectionService::FillUserPopulation(
+ const LoginReputationClientRequest::TriggerType& request_type,
+ LoginReputationClientRequest* request_proto) {
+ ChromeUserPopulation* user_population = request_proto->mutable_population();
+ user_population->set_user_population(
+ IsExtendedReporting() ? ChromeUserPopulation::EXTENDED_REPORTING
+ : ChromeUserPopulation::SAFE_BROWSING);
+ user_population->set_is_history_sync_enabled(IsHistorySyncEnabled());
+
+ base::FieldTrial* low_reputation_field_trial =
+ base::FeatureList::GetFieldTrial(kPasswordFieldOnFocusPinging);
+ if (low_reputation_field_trial) {
+ user_population->add_finch_active_groups(
+ low_reputation_field_trial->trial_name() + "|" +
+ low_reputation_field_trial->group_name());
+ }
+ base::FieldTrial* password_entry_field_trial =
+ base::FeatureList::GetFieldTrial(kProtectedPasswordEntryPinging);
+ if (password_entry_field_trial) {
+ user_population->add_finch_active_groups(
+ low_reputation_field_trial->trial_name() + "|" +
+ low_reputation_field_trial->group_name());
+ }
}
void PasswordProtectionService::OnURLsDeleted(
@@ -296,6 +420,9 @@ void PasswordProtectionService::OnURLsDeleted(
bool expired,
const history::URLRows& deleted_rows,
const std::set<GURL>& favicon_urls) {
+ if (stored_verdict_count_ <= 0)
+ return;
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&PasswordProtectionService::RemoveContentSettingsOnURLsDeleted,
@@ -340,7 +467,7 @@ void PasswordProtectionService::RemoveContentSettingsOnURLsDeleted(
int verdict_count = static_cast<int>(verdict_dictionary->size());
stored_verdict_count_ = GetStoredVerdictCount() - verdict_count;
content_settings_->ClearSettingsForOneTypeWithPredicate(
- CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
+ CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, base::Time(),
base::Bind(&OriginMatchPrimaryPattern, url_key));
}
}
@@ -350,18 +477,14 @@ bool PasswordProtectionService::ParseVerdictEntry(
base::DictionaryValue* verdict_entry,
int* out_verdict_received_time,
LoginReputationClientResponse* out_verdict) {
- base::Value* binary_value = nullptr;
- bool result = verdict_entry && out_verdict &&
- verdict_entry->GetInteger(kCacheCreationTime,
- out_verdict_received_time) &&
- verdict_entry->Get(kVerdictProto, &binary_value);
- if (!result)
- return false;
- DCHECK(result);
- DCHECK_EQ(base::Value::Type::BINARY, binary_value->type());
- const auto blob = binary_value->GetBlob();
- const std::string serialized_verdict_proto(blob.begin(), blob.end());
- return out_verdict->ParseFromString(serialized_verdict_proto);
+ std::string serialized_verdict_proto;
+ return verdict_entry && out_verdict &&
+ verdict_entry->GetInteger(kCacheCreationTime,
+ out_verdict_received_time) &&
+ verdict_entry->GetString(kVerdictProto, &serialized_verdict_proto) &&
+ base::Base64Decode(serialized_verdict_proto,
+ &serialized_verdict_proto) &&
+ out_verdict->ParseFromString(serialized_verdict_proto);
}
bool PasswordProtectionService::PathVariantsMatchCacheExpression(
@@ -400,7 +523,10 @@ void PasswordProtectionService::GeneratePathVariantsWithoutQuery(
// "foo.com/foo/bar/" -> "/foo/bar/"
std::string PasswordProtectionService::GetCacheExpressionPath(
const std::string& cache_expression) {
- DCHECK(!cache_expression.empty());
+ // TODO(jialiul): Change this to a DCHECk when SB server is ready.
+ if (cache_expression.empty())
+ return std::string("/");
+
std::string out_put(cache_expression);
// Append a trailing slash if needed.
if (out_put[out_put.length() - 1] != '/')
@@ -420,16 +546,29 @@ PasswordProtectionService::CreateDictionaryFromVerdict(
base::MakeUnique<base::DictionaryValue>();
result->SetInteger(kCacheCreationTime,
static_cast<int>(receive_time.ToDoubleT()));
- // Because DictionaryValue cannot take non-UTF8 string, we need to store
- // serialized proto in its allowed binary format instead.
- const std::string serialized_proto(verdict->SerializeAsString());
- const std::vector<char> verdict_blob(serialized_proto.begin(),
- serialized_proto.end());
- std::unique_ptr<base::Value> binary_value =
- base::MakeUnique<base::Value>(verdict_blob);
- DCHECK_EQ(base::Value::Type::BINARY, binary_value->type());
- result->Set(kVerdictProto, std::move(binary_value));
+ std::string serialized_proto(verdict->SerializeAsString());
+ // Performs a base64 encoding on the serialized proto.
+ base::Base64Encode(serialized_proto, &serialized_proto);
+ result->SetString(kVerdictProto, serialized_proto);
return result;
}
+void PasswordProtectionService::RecordNoPingingReason(
+ const base::Feature& feature,
+ RequestOutcome reason) {
+ DCHECK(feature.name == kProtectedPasswordEntryPinging.name ||
+ feature.name == kPasswordFieldOnFocusPinging.name);
+
+ bool is_password_entry_ping =
+ feature.name == kProtectedPasswordEntryPinging.name;
+
+ if (is_password_entry_ping) {
+ UMA_HISTOGRAM_ENUMERATION(kPasswordEntryRequestOutcomeHistogramName, reason,
+ MAX_OUTCOME);
+ } else {
+ UMA_HISTOGRAM_ENUMERATION(kPasswordOnFocusRequestOutcomeHistogramName,
+ reason, MAX_OUTCOME);
+ }
+}
+
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/password_protection/password_protection_service.h b/chromium/components/safe_browsing/password_protection/password_protection_service.h
index d025871b422..7060bb20c2f 100644
--- a/chromium/components/safe_browsing/password_protection/password_protection_service.h
+++ b/chromium/components/safe_browsing/password_protection/password_protection_service.h
@@ -5,18 +5,25 @@
#ifndef COMPONENTS_SAFE_BROWSING_PASSWORD_PROTECTION_PASSWORD_PROTECTION_SERVICE_H_
#define COMPONENTS_SAFE_BROWSING_PASSWORD_PROTECTION_PASSWORD_PROTECTION_SERVICE_H_
-#include <unordered_set>
+#include <set>
#include "base/callback.h"
+#include "base/feature_list.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
+#include "base/task/cancelable_task_tracker.h"
#include "base/values.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/safe_browsing/csd.pb.h"
#include "net/url_request/url_request_context_getter.h"
+#include "third_party/protobuf/src/google/protobuf/repeated_field.h"
+
+namespace content {
+class WebContents;
+}
namespace history {
class HistoryService;
@@ -30,14 +37,37 @@ namespace safe_browsing {
class SafeBrowsingDatabaseManager;
class PasswordProtectionRequest;
+extern const base::Feature kPasswordFieldOnFocusPinging;
+extern const base::Feature kProtectedPasswordEntryPinging;
+extern const char kPasswordOnFocusRequestOutcomeHistogramName[];
+extern const char kPasswordEntryRequestOutcomeHistogramName[];
+
// Manage password protection pings and verdicts. There is one instance of this
// class per profile. Therefore, every PasswordProtectionService instance is
// associated with a unique HistoryService instance and a unique
// HostContentSettingsMap instance.
-class PasswordProtectionService : history::HistoryServiceObserver {
+class PasswordProtectionService : public history::HistoryServiceObserver {
public:
- using CheckCsdWhitelistCallback = base::Callback<void(bool)>;
-
+ // The outcome of the request. These values are used for UMA.
+ // DO NOT CHANGE THE ORDERING OF THESE VALUES.
+ enum RequestOutcome {
+ UNKNOWN = 0,
+ SUCCEEDED = 1,
+ CANCELED = 2,
+ TIMEDOUT = 3,
+ MATCHED_WHITELIST = 4,
+ RESPONSE_ALREADY_CACHED = 5,
+ DEPRECATED_NO_EXTENDED_REPORTING = 6,
+ DISABLED_DUE_TO_INCOGNITO = 7,
+ REQUEST_MALFORMED = 8,
+ FETCH_FAILED = 9,
+ RESPONSE_MALFORMED = 10,
+ SERVICE_DESTROYED = 11,
+ DISABLED_DUE_TO_FEATURE_DISABLED = 12,
+ DISABLED_DUE_TO_USER_POPULATION = 13,
+ URL_NOT_VALID_FOR_REPUTATION_COMPUTING = 14,
+ MAX_OUTCOME
+ };
PasswordProtectionService(
const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager,
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
@@ -50,10 +80,6 @@ class PasswordProtectionService : history::HistoryServiceObserver {
return weak_factory_.GetWeakPtr();
}
- // Checks if |url| matches CSD whitelist and record UMA metric accordingly.
- // Currently called by PasswordReuseDetectionManager on UI thread.
- void RecordPasswordReuse(const GURL& url);
-
// Looks up |settings| to find the cached verdict response. If verdict is not
// available or is expired, return VERDICT_TYPE_UNSPECIFIED. Can be called on
// any thread.
@@ -67,15 +93,50 @@ class PasswordProtectionService : history::HistoryServiceObserver {
LoginReputationClientResponse* verdict,
const base::Time& receive_time);
+ // Removes all the expired verdicts from cache.
+ void CleanUpExpiredVerdicts();
+
// Creates an instance of PasswordProtectionRequest and call Start() on that
// instance. This function also insert this request object in |requests_| for
// record keeping.
- void StartRequest(const GURL& main_frame_url,
+ void StartRequest(content::WebContents* web_contents,
+ const GURL& main_frame_url,
+ const GURL& password_form_action,
+ const GURL& password_form_frame_url,
+ const std::string& saved_domain,
LoginReputationClientRequest::TriggerType type);
+ virtual void MaybeStartPasswordFieldOnFocusRequest(
+ content::WebContents* web_contents,
+ const GURL& main_frame_url,
+ const GURL& password_form_action,
+ const GURL& password_form_frame_url);
+
+ virtual void MaybeStartProtectedPasswordEntryRequest(
+ content::WebContents* web_contents,
+ const GURL& main_frame_url,
+ const std::string& saved_domain);
+
+ scoped_refptr<SafeBrowsingDatabaseManager> database_manager();
+
+ // Safe Browsing backend cannot get a reliable reputation of a URL if
+ // (1) URL is not valid
+ // (2) URL doesn't have http or https scheme
+ // (3) It maps to a local host.
+ // (4) Its hostname is an IP Address in an IANA-reserved range.
+ // (5) Its hostname is a not-yet-assigned by ICANN gTLD.
+ // (6) Its hostname is a dotless domain.
+ static bool CanGetReputationOfURL(const GURL& url);
+
protected:
friend class PasswordProtectionRequest;
+ // Chrome can send password protection ping if it is allowed by Finch config
+ // and if Safe Browsing can compute reputation of |main_frame_url| (e.g.
+ // Safe Browsing is not able to compute reputation of a private IP or
+ // a local host.)
+ bool CanSendPing(const base::Feature& feature, const GURL& main_frame_url);
+
// Called by a PasswordProtectionRequest instance when it finishes to remove
// itself from |requests_|.
virtual void RequestFinished(
@@ -107,21 +168,26 @@ class PasswordProtectionService : history::HistoryServiceObserver {
int event_tab_id, // -1 if tab id is not available.
LoginReputationClientRequest::Frame* frame) = 0;
+ void FillUserPopulation(
+ const LoginReputationClientRequest::TriggerType& request_type,
+ LoginReputationClientRequest* request_proto);
+
virtual bool IsExtendedReporting() = 0;
+
virtual bool IsIncognito() = 0;
- // If we can send ping to Safe Browsing backend.
- virtual bool IsPingingEnabled() = 0;
+ virtual bool IsPingingEnabled(const base::Feature& feature,
+ RequestOutcome* reason) = 0;
+
+ virtual bool IsHistorySyncEnabled() = 0;
- void CheckCsdWhitelistOnIOThread(const GURL& url,
- const CheckCsdWhitelistCallback& callback);
+ void CheckCsdWhitelistOnIOThread(const GURL& url, bool* check_result);
- // Increases "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist" UMA
- // metric based on input.
- void OnMatchCsdWhiteListResult(bool match_whitelist);
+ HostContentSettingsMap* content_settings() const { return content_settings_; }
private:
friend class PasswordProtectionServiceTest;
+ friend class TestPasswordProtectionService;
FRIEND_TEST_ALL_PREFIXES(PasswordProtectionServiceTest,
TestParseInvalidVerdictEntry);
FRIEND_TEST_ALL_PREFIXES(PasswordProtectionServiceTest,
@@ -129,7 +195,9 @@ class PasswordProtectionService : history::HistoryServiceObserver {
FRIEND_TEST_ALL_PREFIXES(PasswordProtectionServiceTest,
TestPathVariantsMatchCacheExpression);
FRIEND_TEST_ALL_PREFIXES(PasswordProtectionServiceTest,
- TestCleanUpCachedVerdicts);
+ TestRemoveCachedVerdictOnURLsDeleted);
+ FRIEND_TEST_ALL_PREFIXES(PasswordProtectionServiceTest,
+ TestCleanUpExpiredVerdict);
// Overridden from history::HistoryServiceObserver.
void OnURLsDeleted(history::HistoryService* history_service,
@@ -166,6 +234,8 @@ class PasswordProtectionService : history::HistoryServiceObserver {
const LoginReputationClientResponse* verdict,
const base::Time& receive_time);
+ static void RecordNoPingingReason(const base::Feature& feature,
+ RequestOutcome reason);
// Number of verdict stored for this profile.
int stored_verdict_count_;
@@ -177,7 +247,7 @@ class PasswordProtectionService : history::HistoryServiceObserver {
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
// Set of pending PasswordProtectionRequests.
- std::unordered_set<std::unique_ptr<PasswordProtectionRequest>> requests_;
+ std::set<scoped_refptr<PasswordProtectionRequest>> requests_;
ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
history_service_observer_;
@@ -185,6 +255,10 @@ class PasswordProtectionService : history::HistoryServiceObserver {
// Content settings map associated with this instance.
HostContentSettingsMap* content_settings_;
+ // Weakptr can only cancel task if it is posted to the same thread. Therefore,
+ // we need CancelableTaskTracker to cancel tasks posted to IO thread.
+ base::CancelableTaskTracker tracker_;
+
base::WeakPtrFactory<PasswordProtectionService> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PasswordProtectionService);
};
diff --git a/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc
index e792f617c78..3deb72a2720 100644
--- a/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc
+++ b/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc
@@ -5,6 +5,7 @@
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/histogram_tester.h"
#include "base/test/null_task_runner.h"
@@ -19,12 +20,12 @@
namespace {
-const char kPasswordReuseMatchWhitelistHistogramName[] =
- "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist";
-const char kWhitelistedUrl[] = "http://inwhitelist.com";
-const char kNoneWhitelistedUrl[] = "http://notinwhitelist.com";
-const char kRequestOutcomeHistogramName[] = "PasswordProtection.RequestOutcome";
-const char kTargetUrl[] = "http://foo.com";
+const char kFormActionUrl[] = "https://form_action.com/";
+const char kPasswordFrameUrl[] = "https://password_frame.com/";
+const char kSavedDomain[] = "saved_domain.com";
+const char kTargetUrl[] = "http://foo.com/";
+const char kVerdictHistogramName[] =
+ "PasswordProtection.Verdict.PasswordFieldOnFocus";
} // namespace
@@ -72,15 +73,19 @@ class TestPasswordProtectionService : public PasswordProtectionService {
nullptr,
content_setting_map.get()),
is_extended_reporting_(true),
- is_incognito_(false) {}
+ is_incognito_(false),
+ latest_request_(nullptr) {}
void RequestFinished(
PasswordProtectionRequest* request,
std::unique_ptr<LoginReputationClientResponse> response) override {
+ latest_request_ = request;
latest_response_ = std::move(response);
}
- // Intentionally do nothing.
+ // Since referrer chain logic has been thoroughly tested in
+ // SBNavigationObserverBrowserTest class, we intentionally leave this function
+ // as a no-op here.
void FillReferrerChain(const GURL& event_url,
int event_tab_id,
LoginReputationClientRequest::Frame* frame) override {}
@@ -95,15 +100,29 @@ class TestPasswordProtectionService : public PasswordProtectionService {
void set_incognito(bool enabled) { is_incognito_ = enabled; }
- bool IsPingingEnabled() override { return true; }
+ bool IsPingingEnabled(const base::Feature& feature,
+ RequestOutcome* reason) override {
+ return true;
+ }
+
+ bool IsHistorySyncEnabled() override { return false; }
LoginReputationClientResponse* latest_response() {
return latest_response_.get();
}
+ ~TestPasswordProtectionService() override {}
+
+ size_t GetPendingRequestsCount() { return requests_.size(); }
+
+ LoginReputationClientRequest* GetLatestRequestProto() {
+ return latest_request_ ? latest_request_->request_proto() : nullptr;
+ }
+
private:
bool is_extended_reporting_;
bool is_incognito_;
+ PasswordProtectionRequest* latest_request_;
std::unique_ptr<LoginReputationClientResponse> latest_response_;
DISALLOW_COPY_AND_ASSIGN(TestPasswordProtectionService);
};
@@ -126,7 +145,8 @@ class PasswordProtectionServiceTest : public testing::Test {
void SetUp() override {
HostContentSettingsMap::RegisterProfilePrefs(test_pref_service_.registry());
content_setting_map_ = new HostContentSettingsMap(
- &test_pref_service_, false /* incognito */, false /* guest_profile */);
+ &test_pref_service_, false /* incognito */, false /* guest_profile */,
+ false /* store_last_modified */);
database_manager_ = new MockSafeBrowsingDatabaseManager();
dummy_request_context_getter_ = new DummyURLRequestContextGetter();
password_protection_service_ =
@@ -138,16 +158,29 @@ class PasswordProtectionServiceTest : public testing::Test {
void TearDown() override { content_setting_map_->ShutdownOnUIThread(); }
// Sets up |database_manager_| and |requests_| as needed.
- void InitializeAndStartRequest(bool match_whitelist, int timeout_in_ms) {
+ void InitializeAndStartPasswordOnFocusRequest(bool match_whitelist,
+ int timeout_in_ms) {
GURL target_url(kTargetUrl);
EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(target_url))
.WillRepeatedly(testing::Return(match_whitelist));
- request_ = base::MakeUnique<PasswordProtectionRequest>(
- target_url, LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE,
- password_protection_service_->IsExtendedReporting(),
- password_protection_service_->IsIncognito(),
- password_protection_service_->GetWeakPtr(), timeout_in_ms);
+ request_ = new PasswordProtectionRequest(
+ nullptr, target_url, GURL(kFormActionUrl), GURL(kPasswordFrameUrl),
+ std::string(), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE,
+ password_protection_service_.get(), timeout_in_ms);
+ request_->Start();
+ }
+
+ void InitializeAndStartPasswordEntryRequest(bool match_whitelist,
+ int timeout_in_ms) {
+ GURL target_url(kTargetUrl);
+ EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(target_url))
+ .WillRepeatedly(testing::Return(match_whitelist));
+
+ request_ = new PasswordProtectionRequest(
+ nullptr, target_url, GURL(), GURL(), std::string(kSavedDomain),
+ LoginReputationClientRequest::PASSWORD_REUSE_EVENT,
+ password_protection_service_.get(), timeout_in_ms);
request_->Start();
}
@@ -184,41 +217,10 @@ class PasswordProtectionServiceTest : public testing::Test {
scoped_refptr<HostContentSettingsMap> content_setting_map_;
scoped_refptr<DummyURLRequestContextGetter> dummy_request_context_getter_;
std::unique_ptr<TestPasswordProtectionService> password_protection_service_;
- std::unique_ptr<PasswordProtectionRequest> request_;
+ scoped_refptr<PasswordProtectionRequest> request_;
base::HistogramTester histograms_;
};
-TEST_F(PasswordProtectionServiceTest,
- TestPasswordReuseMatchWhitelistHistogram) {
- const GURL whitelisted_url(kWhitelistedUrl);
- const GURL not_whitelisted_url(kNoneWhitelistedUrl);
- EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(whitelisted_url))
- .WillOnce(testing::Return(true));
- EXPECT_CALL(*database_manager_.get(),
- MatchCsdWhitelistUrl(not_whitelisted_url))
- .WillOnce(testing::Return(false));
- histograms_.ExpectTotalCount(kPasswordReuseMatchWhitelistHistogramName, 0);
-
- // Empty url should not increment metric.
- password_protection_service_->RecordPasswordReuse(GURL());
- base::RunLoop().RunUntilIdle();
- histograms_.ExpectTotalCount(kPasswordReuseMatchWhitelistHistogramName, 0);
-
- // Whitelisted url should increase "True" bucket by 1.
- password_protection_service_->RecordPasswordReuse(whitelisted_url);
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(
- histograms_.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName),
- testing::ElementsAre(base::Bucket(1, 1)));
-
- // Non-whitelisted url should increase "False" bucket by 1.
- password_protection_service_->RecordPasswordReuse(not_whitelisted_url);
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(
- histograms_.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName),
- testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 1)));
-}
-
TEST_F(PasswordProtectionServiceTest, TestParseInvalidVerdictEntry) {
std::unique_ptr<base::DictionaryValue> invalid_verdict_entry =
base::MakeUnique<base::DictionaryValue>();
@@ -357,7 +359,7 @@ TEST_F(PasswordProtectionServiceTest, TestGetCachedVerdicts) {
GURL("http://test.com/def/ghi/index.html"), &actual_verdict));
}
-TEST_F(PasswordProtectionServiceTest, TestCleanUpCachedVerdicts) {
+TEST_F(PasswordProtectionServiceTest, TestRemoveCachedVerdictOnURLsDeleted) {
ASSERT_EQ(0U, GetStoredVerdictCount());
// Prepare 2 verdicts. One is for origin "http://foo.com", and the other is
// for "http://bar.com".
@@ -394,73 +396,88 @@ TEST_F(PasswordProtectionServiceTest, TestCleanUpCachedVerdicts) {
EXPECT_EQ(0U, GetStoredVerdictCount());
}
-TEST_F(PasswordProtectionServiceTest, TestNoRequestSentForIncognito) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
- password_protection_service_->set_incognito(true);
- password_protection_service_->StartRequest(
- GURL(kTargetUrl), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, password_protection_service_->latest_response());
- EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName),
- testing::ElementsAre(base::Bucket(7 /* INCOGNITO */, 1)));
-}
-
-TEST_F(PasswordProtectionServiceTest,
- TestNoRequestSentForNonExtendedReporting) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
- password_protection_service_->set_extended_reporting(false);
- password_protection_service_->StartRequest(
- GURL(kTargetUrl), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
-
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, password_protection_service_->latest_response());
- EXPECT_THAT(
- histograms_.GetAllSamples(kRequestOutcomeHistogramName),
- testing::ElementsAre(base::Bucket(6 /* NO_EXTENDED_REPORTING */, 1)));
+TEST_F(PasswordProtectionServiceTest, VerifyCanGetReputationOfURL) {
+ // Invalid main frame URL.
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(GURL()));
+
+ // Main frame URL scheme is not HTTP or HTTPS.
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("data:text/html, <p>hellow")));
+
+ // Main frame URL is a local host.
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://localhost:80")));
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://127.0.0.1")));
+
+ // Main frame URL is a private IP address or anything in an IANA-reserved
+ // range.
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://192.168.1.0/")));
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://10.0.1.0/")));
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://FEED::BEEF")));
+
+ // Main frame URL is a no-yet-assigned y ICANN gTLD.
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://intranet")));
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://host.intranet.example")));
+
+ // Main frame URL is a dotless domain.
+ EXPECT_FALSE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://go/example")));
+
+ // Main frame URL is anything else.
+ EXPECT_TRUE(PasswordProtectionService::CanGetReputationOfURL(
+ GURL("http://www.chromium.org")));
}
TEST_F(PasswordProtectionServiceTest, TestNoRequestSentForWhitelistedURL) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
- InitializeAndStartRequest(true /* match whitelist */,
- 10000 /* timeout in ms*/);
+ histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
+ InitializeAndStartPasswordOnFocusRequest(true /* match whitelist */,
+ 10000 /* timeout in ms*/);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(nullptr, password_protection_service_->latest_response());
- EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName),
- testing::ElementsAre(base::Bucket(4 /* MATCHED_WHITELIST */, 1)));
+ EXPECT_THAT(
+ histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
+ testing::ElementsAre(base::Bucket(4 /* MATCHED_WHITELIST */, 1)));
}
TEST_F(PasswordProtectionServiceTest, TestNoRequestSentIfVerdictAlreadyCached) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
+ histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
CacheVerdict(GURL(kTargetUrl), LoginReputationClientResponse::LOW_REPUTATION,
600, GURL(kTargetUrl).host(), base::Time::Now());
- InitializeAndStartRequest(false /* match whitelist */,
- 10000 /* timeout in ms*/);
+ InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */,
+ 10000 /* timeout in ms*/);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(
- histograms_.GetAllSamples(kRequestOutcomeHistogramName),
+ histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
testing::ElementsAre(base::Bucket(5 /* RESPONSE_ALREADY_CACHED */, 1)));
EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION,
password_protection_service_->latest_response()->verdict_type());
}
TEST_F(PasswordProtectionServiceTest, TestResponseFetchFailed) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
+ histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
net::TestURLFetcher failed_fetcher(0, GURL("http://bar.com"), nullptr);
// Set up failed response.
failed_fetcher.set_status(
net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
- InitializeAndStartRequest(false /* match whitelist */,
- 10000 /* timeout in ms*/);
+ InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */,
+ 10000 /* timeout in ms*/);
request_->OnURLFetchComplete(&failed_fetcher);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(nullptr, password_protection_service_->latest_response());
- EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName),
- testing::ElementsAre(base::Bucket(9 /* FETCH_FAILED */, 1)));
+ EXPECT_THAT(
+ histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
+ testing::ElementsAre(base::Bucket(9 /* FETCH_FAILED */, 1)));
}
TEST_F(PasswordProtectionServiceTest, TestMalformedResponse) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
+ histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
// Set up malformed response.
net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr);
fetcher.set_status(
@@ -468,28 +485,29 @@ TEST_F(PasswordProtectionServiceTest, TestMalformedResponse) {
fetcher.set_response_code(200);
fetcher.SetResponseString("invalid response");
- InitializeAndStartRequest(false /* match whitelist */,
- 10000 /* timeout in ms*/);
+ InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */,
+ 10000 /* timeout in ms*/);
request_->OnURLFetchComplete(&fetcher);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(nullptr, password_protection_service_->latest_response());
EXPECT_THAT(
- histograms_.GetAllSamples(kRequestOutcomeHistogramName),
+ histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
testing::ElementsAre(base::Bucket(10 /* RESPONSE_MALFORMED */, 1)));
}
TEST_F(PasswordProtectionServiceTest, TestRequestTimedout) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
- InitializeAndStartRequest(false /* match whitelist */,
- 0 /* timeout immediately */);
+ histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
+ InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */,
+ 0 /* timeout immediately */);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(nullptr, password_protection_service_->latest_response());
- EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName),
- testing::ElementsAre(base::Bucket(3 /* TIMEDOUT */, 1)));
+ EXPECT_THAT(
+ histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
+ testing::ElementsAre(base::Bucket(3 /* TIMEDOUT */, 1)));
}
TEST_F(PasswordProtectionServiceTest, TestRequestAndResponseSuccessfull) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
+ histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
// Set up valid response.
net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr);
fetcher.set_status(
@@ -499,12 +517,15 @@ TEST_F(PasswordProtectionServiceTest, TestRequestAndResponseSuccessfull) {
LoginReputationClientResponse::PHISHING, 600, GURL(kTargetUrl).host());
fetcher.SetResponseString(expected_response.SerializeAsString());
- InitializeAndStartRequest(false /* match whitelist */,
- 10000 /* timeout in ms*/);
+ InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */,
+ 10000 /* timeout in ms*/);
request_->OnURLFetchComplete(&fetcher);
base::RunLoop().RunUntilIdle();
- EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName),
- testing::ElementsAre(base::Bucket(1 /* SUCCEEDED */, 1)));
+ EXPECT_THAT(
+ histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
+ testing::ElementsAre(base::Bucket(1 /* SUCCEEDED */, 1)));
+ EXPECT_THAT(histograms_.GetAllSamples(kVerdictHistogramName),
+ testing::ElementsAre(base::Bucket(3 /* PHISHING */, 1)));
LoginReputationClientResponse* actual_response =
password_protection_service_->latest_response();
EXPECT_EQ(expected_response.verdict_type(), actual_response->verdict_type());
@@ -515,18 +536,117 @@ TEST_F(PasswordProtectionServiceTest, TestRequestAndResponseSuccessfull) {
}
TEST_F(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) {
- histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0);
+ histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0);
GURL target_url(kTargetUrl);
EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(target_url))
.WillRepeatedly(testing::Return(false));
password_protection_service_->StartRequest(
- target_url, LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
+ nullptr, target_url, GURL("http://foo.com/submit"),
+ GURL("http://foo.com/frame"), std::string(),
+ LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
// Destroy password_protection_service_ while there is one request pending.
password_protection_service_.reset();
base::RunLoop().RunUntilIdle();
- EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName),
- testing::ElementsAre(base::Bucket(2 /* CANCELED */, 1)));
+ EXPECT_THAT(
+ histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogramName),
+ testing::ElementsAre(base::Bucket(2 /* CANCELED */, 1)));
+}
+
+TEST_F(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) {
+ ASSERT_EQ(0U, GetStoredVerdictCount());
+ // Prepare 4 verdicts:
+ // (1) "foo.com/abc" valid
+ // (2) "foo.com/def" expired
+ // (3) "bar.com/abc" expired
+ // (4) "bar.com/def" expired
+ base::Time now = base::Time::Now();
+ CacheVerdict(GURL("https://foo.com/abc/index.jsp"),
+ LoginReputationClientResponse::LOW_REPUTATION, 10 * 60,
+ "foo.com/abc", now);
+ CacheVerdict(GURL("https://foo.com/def/index.jsp"),
+ LoginReputationClientResponse::LOW_REPUTATION, 0, "foo.com/def",
+ now);
+ CacheVerdict(GURL("https://bar.com/abc/index.jsp"),
+ LoginReputationClientResponse::PHISHING, 0, "bar.com/abc", now);
+ CacheVerdict(GURL("https://bar.com/def/index.jsp"),
+ LoginReputationClientResponse::PHISHING, 0, "bar.com/def", now);
+ ASSERT_EQ(4U, GetStoredVerdictCount());
+
+ password_protection_service_->CleanUpExpiredVerdicts();
+
+ ASSERT_EQ(1U, GetStoredVerdictCount());
+ LoginReputationClientResponse actual_verdict;
+ // Has cached verdict for foo.com/abc.
+ EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION,
+ password_protection_service_->GetCachedVerdict(
+ GURL("https://foo.com/abc/test.jsp"), &actual_verdict));
+ // No cached verdict for foo.com/def.
+ EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED,
+ password_protection_service_->GetCachedVerdict(
+ GURL("https://foo.com/def/index.jsp"), &actual_verdict));
+ // Nothing in content setting for bar.com.
+ EXPECT_EQ(nullptr, content_setting_map_->GetWebsiteSetting(
+ GURL("https://bar.com"), GURL(),
+ CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION,
+ std::string(), nullptr));
+}
+
+TEST_F(PasswordProtectionServiceTest, VerifyPasswordOnFocusRequestProto) {
+ // Set up valid response.
+ net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr);
+ fetcher.set_status(
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
+ fetcher.set_response_code(200);
+ LoginReputationClientResponse expected_response = CreateVerdictProto(
+ LoginReputationClientResponse::PHISHING, 600, GURL(kTargetUrl).host());
+ fetcher.SetResponseString(expected_response.SerializeAsString());
+
+ InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */,
+ 100000 /* timeout in ms*/);
+ base::RunLoop().RunUntilIdle();
+ request_->OnURLFetchComplete(&fetcher);
+ base::RunLoop().RunUntilIdle();
+
+ LoginReputationClientRequest* actual_request =
+ password_protection_service_->GetLatestRequestProto();
+ EXPECT_EQ(kTargetUrl, actual_request->page_url());
+ EXPECT_EQ(LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE,
+ actual_request->trigger_type());
+ ASSERT_EQ(2, actual_request->frames_size());
+ EXPECT_EQ(kTargetUrl, actual_request->frames(0).url());
+ EXPECT_EQ(kPasswordFrameUrl, actual_request->frames(1).url());
+ EXPECT_EQ(true, actual_request->frames(1).has_password_field());
+ ASSERT_EQ(1, actual_request->frames(1).forms_size());
+ EXPECT_EQ(kFormActionUrl, actual_request->frames(1).forms(0).action_url());
}
+
+TEST_F(PasswordProtectionServiceTest,
+ VerifyProtectedPasswordEntryRequestProto) {
+ // Set up valid response.
+ net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr);
+ fetcher.set_status(
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
+ fetcher.set_response_code(200);
+ LoginReputationClientResponse expected_response = CreateVerdictProto(
+ LoginReputationClientResponse::PHISHING, 600, GURL(kTargetUrl).host());
+ fetcher.SetResponseString(expected_response.SerializeAsString());
+ InitializeAndStartPasswordEntryRequest(false /* match whitelist */,
+ 100000 /* timeout in ms*/);
+ base::RunLoop().RunUntilIdle();
+ request_->OnURLFetchComplete(&fetcher);
+ base::RunLoop().RunUntilIdle();
+
+ LoginReputationClientRequest* actual_request =
+ password_protection_service_->GetLatestRequestProto();
+ EXPECT_EQ(kTargetUrl, actual_request->page_url());
+ EXPECT_EQ(LoginReputationClientRequest::PASSWORD_REUSE_EVENT,
+ actual_request->trigger_type());
+ EXPECT_EQ(1, actual_request->frames_size());
+ EXPECT_EQ(kTargetUrl, actual_request->frames(0).url());
+ // TODO(jialiul): Update this test when we're ready to fill more fields.
+ ASSERT_FALSE(actual_request->has_password_reuse_event());
+}
+
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/renderer/threat_dom_details.cc b/chromium/components/safe_browsing/renderer/threat_dom_details.cc
index b790b965ff2..0a36545b6c5 100644
--- a/chromium/components/safe_browsing/renderer/threat_dom_details.cc
+++ b/chromium/components/safe_browsing/renderer/threat_dom_details.cc
@@ -146,6 +146,15 @@ void HandleElement(
child_node.tag_name = element.TagName().Utf8();
child_node.parent = summary_node->url;
+ // The body of an iframe may be in a different renderer. Look up the routing
+ // ID of the local or remote frame and store it with the iframe node. If this
+ // element is not a frame then the result of the lookup will be null.
+ blink::WebFrame* subframe = blink::WebFrame::FromFrameOwnerElement(element);
+ if (subframe) {
+ child_node.child_frame_routing_id =
+ content::RenderFrame::GetRoutingIdForWebFrame(subframe);
+ }
+
// Populate the element's attributes, but only collect the ones that are
// configured in the finch study.
const auto& tag_attribute_iter = std::find_if(
diff --git a/chromium/components/safe_browsing/triggers/BUILD.gn b/chromium/components/safe_browsing/triggers/BUILD.gn
new file mode 100644
index 00000000000..aef9c9ab961
--- /dev/null
+++ b/chromium/components/safe_browsing/triggers/BUILD.gn
@@ -0,0 +1,22 @@
+# Copyright 2017 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.
+
+import("//build/config/features.gni")
+
+source_set("triggers") {
+ if (safe_browsing_mode != 0) {
+ sources = [
+ "trigger_manager.cc",
+ "trigger_manager.h",
+ ]
+
+ deps = [
+ "//base:base",
+ "//components/safe_browsing:safe_browsing",
+ "//components/safe_browsing/browser:browser",
+ "//components/security_interstitials/content:security_interstitial_page",
+ "//content/public/browser:browser",
+ ]
+ }
+}
diff --git a/chromium/components/safe_browsing/triggers/trigger_manager.cc b/chromium/components/safe_browsing/triggers/trigger_manager.cc
new file mode 100644
index 00000000000..d453630f8ff
--- /dev/null
+++ b/chromium/components/safe_browsing/triggers/trigger_manager.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2017 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/safe_browsing/triggers/trigger_manager.h"
+
+#include "components/safe_browsing/base_ui_manager.h"
+#include "components/safe_browsing/browser/threat_details.h"
+#include "content/public/browser/web_contents.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace safe_browsing {
+
+TriggerManager::TriggerManager(BaseUIManager* ui_manager)
+ : ui_manager_(ui_manager) {}
+
+TriggerManager::~TriggerManager() {}
+
+ThreatDetails* TriggerManager::StartCollectingThreatDetails(
+ content::WebContents* web_contents,
+ const security_interstitials::UnsafeResource& resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service) {
+ return ThreatDetails::NewThreatDetails(ui_manager_, web_contents, resource,
+ request_context_getter,
+ history_service);
+}
+
+} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/triggers/trigger_manager.h b/chromium/components/safe_browsing/triggers/trigger_manager.h
new file mode 100644
index 00000000000..1e66b0cd871
--- /dev/null
+++ b/chromium/components/safe_browsing/triggers/trigger_manager.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2017 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_SAFE_BROWSING_TRIGGERS_TRIGGER_MANAGER_H_
+#define COMPONENTS_SAFE_BROWSING_TRIGGERS_TRIGGER_MANAGER_H_
+
+#include "base/macros.h"
+#include "components/security_interstitials/content/unsafe_resource.h"
+
+namespace history {
+class HistoryService;
+}
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace safe_browsing {
+
+class BaseUIManager;
+class ThreatDetails;
+
+// This class manages SafeBrowsing data-reporting triggers. Triggers are
+// activated for users opted-in to Extended Reporting and when security-related
+// data collection is required.
+//
+// The TriggerManager has two main responsibilities: 1) ensuring triggers only
+// run when appropriate, by honouring user opt-ins and incognito state, and 2)
+// tracking how often triggers fire and throttling them when necessary.
+class TriggerManager {
+ public:
+ TriggerManager(BaseUIManager* ui_manager);
+ ~TriggerManager();
+
+ ThreatDetails* StartCollectingThreatDetails(
+ content::WebContents* web_contents,
+ const security_interstitials::UnsafeResource& resource,
+ net::URLRequestContextGetter* request_context_getter,
+ history::HistoryService* history_service);
+
+ private:
+ // The UI manager is used to send reports to Google. Not owned.
+ // TODO(lpz): we may only need a the PingManager here.
+ BaseUIManager* ui_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(TriggerManager);
+};
+
+} // namespace safe_browsing
+
+#endif // COMPONENTS_SAFE_BROWSING_TRIGGERS_TRIGGER_MANAGER_H_
diff --git a/chromium/components/safe_browsing_db/BUILD.gn b/chromium/components/safe_browsing_db/BUILD.gn
index 68a841c69e0..fb9286f8e4c 100644
--- a/chromium/components/safe_browsing_db/BUILD.gn
+++ b/chromium/components/safe_browsing_db/BUILD.gn
@@ -31,9 +31,9 @@ group("safe_browsing_db_shared") {
":database_manager",
":hit_report",
":prefix_set",
- ":safe_browsing_prefs",
":safebrowsing_proto",
":util",
+ "//components/safe_browsing/common:safe_browsing_prefs",
]
}
@@ -82,8 +82,8 @@ static_library("hit_report") {
":util",
]
deps = [
- ":safe_browsing_prefs",
"//components/metrics",
+ "//components/safe_browsing/common:safe_browsing_prefs",
"//url",
]
}
@@ -152,17 +152,6 @@ static_library("safe_browsing_api_handler_util") {
]
}
-static_library("safe_browsing_prefs") {
- sources = [
- "safe_browsing_prefs.cc",
- "safe_browsing_prefs.h",
- ]
- deps = [
- "//base:base",
- "//components/prefs",
- ]
-}
-
static_library("test_database_manager") {
sources = [
"test_database_manager.cc",
@@ -181,8 +170,8 @@ static_library("util") {
"util.h",
]
public_deps = [
- ":safe_browsing_prefs",
":v4_protocol_manager_util",
+ "//components/safe_browsing/common:safe_browsing_prefs",
]
deps = [
"//base",
@@ -325,12 +314,12 @@ static_library("v4_update_protocol_manager") {
"v4_update_protocol_manager.h",
]
deps = [
- ":safe_browsing_prefs",
":safebrowsing_proto",
":util",
":v4_protocol_manager_util",
"//base",
"//components/data_use_measurement/core",
+ "//components/safe_browsing/common:safe_browsing_prefs",
"//net",
"//url",
]
@@ -413,7 +402,6 @@ source_set("unit_tests") {
sources = [
"database_manager_unittest.cc",
"prefix_set_unittest.cc",
- "safe_browsing_prefs_unittest.cc",
"util_unittest.cc",
"v4_database_unittest.cc",
"v4_get_hash_protocol_manager_unittest.cc",
@@ -426,7 +414,6 @@ source_set("unit_tests") {
deps = [
":database_manager",
":prefix_set",
- ":safe_browsing_prefs",
":safebrowsing_proto",
":test_database_manager",
":util",
@@ -441,6 +428,7 @@ source_set("unit_tests") {
":v4_update_protocol_manager",
"//base",
"//components/prefs:test_support",
+ "//components/safe_browsing/common:safe_browsing_prefs",
"//content/test:test_support",
"//crypto",
"//net",
diff --git a/chromium/components/safe_browsing_db/DEPS b/chromium/components/safe_browsing_db/DEPS
index 7fafc802db3..55dc17a90ee 100644
--- a/chromium/components/safe_browsing_db/DEPS
+++ b/chromium/components/safe_browsing_db/DEPS
@@ -1,6 +1,6 @@
include_rules = [
"+components/data_use_measurement/core",
- "+components/prefs",
+ "+components/safe_browsing/common/safe_browsing_prefs.h",
"+components/variations",
"+components/version_info",
"+content/public/browser",
diff --git a/chromium/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc b/chromium/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc
index a4dd994d16c..8040c2caa50 100644
--- a/chromium/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc
+++ b/chromium/components/safe_browsing_db/android/safe_browsing_api_handler_bridge.cc
@@ -7,7 +7,6 @@
#include <memory>
#include <string>
-#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
@@ -19,7 +18,6 @@
using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF8ToJavaString;
-using base::android::GetApplicationContext;
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
using base::android::ToJavaIntArray;
@@ -48,6 +46,8 @@ int SBThreatTypeToJavaThreatType(const SBThreatType& sb_threat_type) {
return safe_browsing::JAVA_THREAT_TYPE_SOCIAL_ENGINEERING;
case SB_THREAT_TYPE_URL_MALWARE:
return safe_browsing::JAVA_THREAT_TYPE_POTENTIALLY_HARMFUL_APPLICATION;
+ case SB_THREAT_TYPE_URL_UNWANTED:
+ return safe_browsing::JAVA_THREAT_TYPE_UNWANTED_SOFTWARE;
default:
NOTREACHED();
return 0;
@@ -121,7 +121,7 @@ void OnUrlCheckDone(JNIEnv* env,
ReportUmaResult(
ParseJsonFromGMSCore(metadata_str, &worst_threat, &threat_metadata));
if (worst_threat != SB_THREAT_TYPE_SAFE) {
- DVLOG(1) << "Check " << callback_id << " marked as UNSAFE";
+ DVLOG(1) << "Check " << callback_id << " was a MATCH";
}
RunCallbackOnIOThread(*callback, worst_threat, threat_metadata);
@@ -140,8 +140,7 @@ bool SafeBrowsingApiHandlerBridge::CheckApiIsSupported() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!checked_api_support_) {
DVLOG(1) << "Checking API support.";
- j_api_handler_ = Java_SafeBrowsingApiBridge_create(AttachCurrentThread(),
- GetApplicationContext());
+ j_api_handler_ = Java_SafeBrowsingApiBridge_create(AttachCurrentThread());
checked_api_support_ = true;
}
return j_api_handler_.obj() != nullptr;
@@ -169,10 +168,7 @@ void SafeBrowsingApiHandlerBridge::StartURLCheck(
// Default threat types, to support upstream code that doesn't yet set them.
std::vector<SBThreatType> local_threat_types(threat_types);
- if (local_threat_types.empty()) {
- local_threat_types.push_back(SB_THREAT_TYPE_URL_PHISHING);
- local_threat_types.push_back(SB_THREAT_TYPE_URL_MALWARE);
- }
+ DCHECK(!local_threat_types.empty());
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, url.spec());
diff --git a/chromium/components/safe_browsing_db/hit_report.h b/chromium/components/safe_browsing_db/hit_report.h
index afa567637f1..4fecc44c9fa 100644
--- a/chromium/components/safe_browsing_db/hit_report.h
+++ b/chromium/components/safe_browsing_db/hit_report.h
@@ -7,7 +7,7 @@
#ifndef COMPONENTS_SAFE_BROWSING_DB_HIT_REPORT_H_
#define COMPONENTS_SAFE_BROWSING_DB_HIT_REPORT_H_
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/safe_browsing_db/util.h"
#include "url/gurl.h"
diff --git a/chromium/components/safe_browsing_db/remote_database_manager.cc b/chromium/components/safe_browsing_db/remote_database_manager.cc
index 2def386d5f8..b620426b711 100644
--- a/chromium/components/safe_browsing_db/remote_database_manager.cc
+++ b/chromium/components/safe_browsing_db/remote_database_manager.cc
@@ -22,15 +22,21 @@ namespace net {
class URLRequestContextGetter;
} // namespace net
+namespace safe_browsing {
+
namespace {
// Android field trial for controlling types_to_check.
const char kAndroidFieldExperiment[] = "SafeBrowsingAndroid";
const char kAndroidTypesToCheckParam[] = "types_to_check";
+void LogPendingChecks(size_t current_requests_size) {
+ UMA_HISTOGRAM_COUNTS_10000("SB2.RemoteCall.ChecksPending",
+ current_requests_size);
+}
+
} // namespace
-namespace safe_browsing {
//
// RemoteSafeBrowsingDatabaseManager::ClientRequest methods
@@ -99,6 +105,10 @@ void RemoteSafeBrowsingDatabaseManager::ClientRequest::OnRequestDone(
// TODO(nparker): Add more tests for this class
RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager() {
+ // Avoid memory allocations growing the underlying vector. Although this
+ // usually wastes a bit of memory, it will still be less than the default
+ // vector allocation strategy.
+ resource_types_to_check_.reserve(content::RESOURCE_TYPE_LAST_TYPE + 1);
// Decide which resource types to check. These two are the minimum.
resource_types_to_check_.insert(content::RESOURCE_TYPE_MAIN_FRAME);
resource_types_to_check_.insert(content::RESOURCE_TYPE_SUB_FRAME);
@@ -183,19 +193,19 @@ bool RemoteSafeBrowsingDatabaseManager::CheckBrowseUrl(const GURL& url,
return true; // Safe, continue right away.
std::unique_ptr<ClientRequest> req(new ClientRequest(client, this, url));
- std::vector<SBThreatType> threat_types; // Not currently used.
DVLOG(1) << "Checking for client " << client << " and URL " << url;
SafeBrowsingApiHandler* api_handler = SafeBrowsingApiHandler::GetInstance();
- // This shouldn't happen since SafeBrowsingResourceThrottle checks
- // IsSupported() earlier.
+ // This shouldn't happen since SafeBrowsingResourceThrottle and
+ // SubresourceFilterSafeBrowsingActivationThrottle check IsSupported()
+ // earlier.
DCHECK(api_handler) << "SafeBrowsingApiHandler was never constructed";
api_handler->StartURLCheck(
base::Bind(&ClientRequest::OnRequestDoneWeak, req->GetWeakPtr()), url,
- threat_types);
+ {SB_THREAT_TYPE_URL_MALWARE, SB_THREAT_TYPE_URL_PHISHING,
+ SB_THREAT_TYPE_URL_UNWANTED});
- UMA_HISTOGRAM_COUNTS_10000("SB2.RemoteCall.ChecksPending",
- current_requests_.size());
+ LogPendingChecks(current_requests_.size());
current_requests_.push_back(req.release());
// Defer the resource load.
@@ -225,7 +235,26 @@ bool RemoteSafeBrowsingDatabaseManager::CheckResourceUrl(const GURL& url,
bool RemoteSafeBrowsingDatabaseManager::CheckUrlForSubresourceFilter(
const GURL& url,
Client* client) {
- NOTREACHED();
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!enabled_ || !CanCheckUrl(url))
+ return true;
+
+ std::unique_ptr<ClientRequest> req(new ClientRequest(client, this, url));
+
+ DVLOG(1) << "Checking for client " << client << " and URL " << url;
+ SafeBrowsingApiHandler* api_handler = SafeBrowsingApiHandler::GetInstance();
+ // This shouldn't happen since SafeBrowsingResourceThrottle and
+ // SubresourceFilterSafeBrowsingActivationThrottle check IsSupported()
+ // earlier.
+ DCHECK(api_handler) << "SafeBrowsingApiHandler was never constructed";
+ api_handler->StartURLCheck(
+ base::Bind(&ClientRequest::OnRequestDoneWeak, req->GetWeakPtr()), url,
+ {SB_THREAT_TYPE_SUBRESOURCE_FILTER});
+
+ LogPendingChecks(current_requests_.size());
+ current_requests_.push_back(req.release());
+
+ // Defer the resource load.
return false;
}
diff --git a/chromium/components/safe_browsing_db/remote_database_manager.h b/chromium/components/safe_browsing_db/remote_database_manager.h
index 7f8ff4ea8c8..1f13ca391fb 100644
--- a/chromium/components/safe_browsing_db/remote_database_manager.h
+++ b/chromium/components/safe_browsing_db/remote_database_manager.h
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -74,7 +75,7 @@ class RemoteSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
// Requests currently outstanding. This owns the ptrs.
std::vector<ClientRequest*> current_requests_;
- std::set<content::ResourceType> resource_types_to_check_;
+ base::flat_set<content::ResourceType> resource_types_to_check_;
friend class base::RefCountedThreadSafe<RemoteSafeBrowsingDatabaseManager>;
DISALLOW_COPY_AND_ASSIGN(RemoteSafeBrowsingDatabaseManager);
diff --git a/chromium/components/safe_browsing_db/safe_browsing_api_handler_unittest.cc b/chromium/components/safe_browsing_db/safe_browsing_api_handler_unittest.cc
index fbf07be6136..c466dd99021 100644
--- a/chromium/components/safe_browsing_db/safe_browsing_api_handler_unittest.cc
+++ b/chromium/components/safe_browsing_db/safe_browsing_api_handler_unittest.cc
@@ -59,12 +59,12 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, BadJson) {
}
TEST_F(SafeBrowsingApiHandlerUtilTest, BasicThreats) {
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"4\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, threat_);
EXPECT_EQ(empty_meta_, meta_);
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"5\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_PHISHING, threat_);
EXPECT_EQ(empty_meta_, meta_);
@@ -72,7 +72,7 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, BasicThreats) {
TEST_F(SafeBrowsingApiHandlerUtilTest, MultipleThreats) {
EXPECT_EQ(
- UMA_STATUS_UNSAFE,
+ UMA_STATUS_MATCH,
ResetAndParseJson(
"{\"matches\":[{\"threat_type\":\"4\"}, {\"threat_type\":\"5\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, threat_);
@@ -82,7 +82,7 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, MultipleThreats) {
TEST_F(SafeBrowsingApiHandlerUtilTest, PhaSubType) {
ThreatMetadata expected;
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"4\", "
"\"pha_pattern_type\":\"LANDING\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, threat_);
@@ -91,14 +91,14 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, PhaSubType) {
// Test the ThreatMetadata comparitor for this field.
EXPECT_NE(empty_meta_, meta_);
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"4\", "
"\"pha_pattern_type\":\"DISTRIBUTION\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, threat_);
expected.threat_pattern_type = ThreatPatternType::MALWARE_DISTRIBUTION;
EXPECT_EQ(expected, meta_);
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"4\", "
"\"pha_pattern_type\":\"junk\"}]}"));
EXPECT_EQ(empty_meta_, meta_);
@@ -108,14 +108,14 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, SocialEngineeringSubType) {
ThreatMetadata expected;
EXPECT_EQ(
- UMA_STATUS_UNSAFE,
+ UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"5\", "
"\"se_pattern_type\":\"SOCIAL_ENGINEERING_ADS\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_PHISHING, threat_);
expected.threat_pattern_type = ThreatPatternType::SOCIAL_ENGINEERING_ADS;
EXPECT_EQ(expected, meta_);
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson(
"{\"matches\":[{\"threat_type\":\"5\", "
"\"se_pattern_type\":\"SOCIAL_ENGINEERING_LANDING\"}]}"));
@@ -123,14 +123,14 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, SocialEngineeringSubType) {
expected.threat_pattern_type = ThreatPatternType::SOCIAL_ENGINEERING_LANDING;
EXPECT_EQ(expected, meta_);
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"5\", "
"\"se_pattern_type\":\"PHISHING\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_PHISHING, threat_);
expected.threat_pattern_type = ThreatPatternType::PHISHING;
EXPECT_EQ(expected, meta_);
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"5\", "
"\"se_pattern_type\":\"junk\"}]}"));
EXPECT_EQ(empty_meta_, meta_);
@@ -139,7 +139,7 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, SocialEngineeringSubType) {
TEST_F(SafeBrowsingApiHandlerUtilTest, PopulationId) {
ThreatMetadata expected;
- EXPECT_EQ(UMA_STATUS_UNSAFE,
+ EXPECT_EQ(UMA_STATUS_MATCH,
ResetAndParseJson("{\"matches\":[{\"threat_type\":\"4\", "
"\"UserPopulation\":\"foobarbazz\"}]}"));
EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, threat_);
@@ -149,4 +149,31 @@ TEST_F(SafeBrowsingApiHandlerUtilTest, PopulationId) {
EXPECT_NE(empty_meta_, meta_);
}
+TEST_F(SafeBrowsingApiHandlerUtilTest, SubresourceFilterSubTypes) {
+ ThreatMetadata expected;
+
+ EXPECT_EQ(UMA_STATUS_MATCH,
+ ResetAndParseJson("{\"matches\":[{\"threat_type\":\"13\"}]}"));
+ EXPECT_EQ(SB_THREAT_TYPE_SUBRESOURCE_FILTER, threat_);
+ expected.threat_pattern_type = ThreatPatternType::NONE;
+ EXPECT_EQ(expected, meta_);
+}
+
+TEST_F(SafeBrowsingApiHandlerUtilTest, NoUnwantedSoftwareSubTypes) {
+ ThreatMetadata expected;
+
+ EXPECT_EQ(UMA_STATUS_MATCH,
+ ResetAndParseJson("{\"matches\":[{\"threat_type\":\"3\"}]}"));
+ EXPECT_EQ(SB_THREAT_TYPE_URL_UNWANTED, threat_);
+ expected.threat_pattern_type = ThreatPatternType::NONE;
+ EXPECT_EQ(expected, meta_);
+
+ EXPECT_EQ(UMA_STATUS_MATCH,
+ ResetAndParseJson("{\"matches\":[{\"threat_type\":\"3\", "
+ "\"se_pattern_type\":\"junk\"}]}"));
+ EXPECT_EQ(SB_THREAT_TYPE_URL_UNWANTED, threat_);
+ expected.threat_pattern_type = ThreatPatternType::NONE;
+ EXPECT_EQ(expected, meta_);
+}
+
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.cc b/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.cc
index 4e894f03ee5..04b8070cd9d 100644
--- a/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.cc
+++ b/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.cc
@@ -53,6 +53,11 @@ void ReportUmaThreatSubType(SBThreatType threat_type,
ThreatPatternType ParseThreatSubType(
const base::DictionaryValue* match,
SBThreatType threat_type) {
+ if (threat_type == SB_THREAT_TYPE_SUBRESOURCE_FILTER ||
+ threat_type == SB_THREAT_TYPE_URL_UNWANTED) {
+ return ThreatPatternType::NONE;
+ }
+
std::string pattern_key;
if (threat_type == SB_THREAT_TYPE_URL_MALWARE) {
pattern_key = "pha_pattern_type";
@@ -111,25 +116,35 @@ std::string ParseUserPopulation(const base::DictionaryValue* match) {
return population_id;
}
-int GetThreatSeverity(int java_threat_num) {
- // Assign higher numbers to more severe threats.
- switch (java_threat_num) {
+// Returns the severity level for a given SafeBrowsing list. The lowest value is
+// 0, which represents the most severe list.
+int GetThreatSeverity(JavaThreatTypes threat_type) {
+ switch (threat_type) {
case JAVA_THREAT_TYPE_POTENTIALLY_HARMFUL_APPLICATION:
- return 2;
+ return 0;
case JAVA_THREAT_TYPE_SOCIAL_ENGINEERING:
return 1;
- default:
- // Unknown threat type
- return -1;
+ case JAVA_THREAT_TYPE_UNWANTED_SOFTWARE:
+ return 2;
+ case JAVA_THREAT_TYPE_SUBRESOURCE_FILTER:
+ return 3;
+ case JAVA_THREAT_TYPE_MAX_VALUE:
+ return std::numeric_limits<int>::max();
}
+ NOTREACHED() << "Unhandled threat_type: " << threat_type;
+ return std::numeric_limits<int>::max();
}
SBThreatType JavaToSBThreatType(int java_threat_num) {
switch (java_threat_num) {
case JAVA_THREAT_TYPE_POTENTIALLY_HARMFUL_APPLICATION:
return SB_THREAT_TYPE_URL_MALWARE;
+ case JAVA_THREAT_TYPE_UNWANTED_SOFTWARE:
+ return SB_THREAT_TYPE_URL_UNWANTED;
case JAVA_THREAT_TYPE_SOCIAL_ENGINEERING:
return SB_THREAT_TYPE_URL_PHISHING;
+ case JAVA_THREAT_TYPE_SUBRESOURCE_FILTER:
+ return SB_THREAT_TYPE_SUBRESOURCE_FILTER;
default:
// Unknown threat type
return SB_THREAT_TYPE_SAFE;
@@ -146,9 +161,9 @@ SBThreatType JavaToSBThreatType(int java_threat_num) {
// or
// {"matches":[{"threat_type":"4", "UserPopulation":"YXNvZWZpbmFqO..."}]
UmaRemoteCallResult ParseJsonFromGMSCore(const std::string& metadata_str,
- SBThreatType* worst_threat,
+ SBThreatType* worst_sb_threat_type,
ThreatMetadata* metadata) {
- *worst_threat = SB_THREAT_TYPE_SAFE; // Default to safe.
+ *worst_sb_threat_type = SB_THREAT_TYPE_SAFE; // Default to safe.
*metadata = ThreatMetadata(); // Default values.
if (metadata_str.empty())
@@ -165,36 +180,40 @@ UmaRemoteCallResult ParseJsonFromGMSCore(const std::string& metadata_str,
}
// Go through each matched threat type and pick the most severe.
- int worst_threat_num = -1;
+ JavaThreatTypes worst_threat_type = JAVA_THREAT_TYPE_MAX_VALUE;
const base::DictionaryValue* worst_match = nullptr;
for (size_t i = 0; i < matches->GetSize(); i++) {
// Get the threat number
const base::DictionaryValue* match;
std::string threat_num_str;
- int java_threat_num = -1;
+
+ int threat_type_num;
if (!matches->GetDictionary(i, &match) ||
!match->GetString(kJsonKeyThreatType, &threat_num_str) ||
- !base::StringToInt(threat_num_str, &java_threat_num)) {
+ !base::StringToInt(threat_num_str, &threat_type_num)) {
continue; // Skip malformed list entries
}
- if (GetThreatSeverity(java_threat_num) >
- GetThreatSeverity(worst_threat_num)) {
- worst_threat_num = java_threat_num;
+ JavaThreatTypes threat_type = static_cast<JavaThreatTypes>(threat_type_num);
+ if (threat_type > JAVA_THREAT_TYPE_MAX_VALUE) {
+ threat_type = JAVA_THREAT_TYPE_MAX_VALUE;
+ }
+ if (GetThreatSeverity(threat_type) < GetThreatSeverity(worst_threat_type)) {
+ worst_threat_type = threat_type;
worst_match = match;
}
}
- *worst_threat = JavaToSBThreatType(worst_threat_num);
- if (*worst_threat == SB_THREAT_TYPE_SAFE || !worst_match)
+ *worst_sb_threat_type = JavaToSBThreatType(worst_threat_type);
+ if (*worst_sb_threat_type == SB_THREAT_TYPE_SAFE || !worst_match)
return UMA_STATUS_JSON_UNKNOWN_THREAT;
// Fill in the metadata
metadata->threat_pattern_type =
- ParseThreatSubType(worst_match, *worst_threat);
+ ParseThreatSubType(worst_match, *worst_sb_threat_type);
metadata->population_id = ParseUserPopulation(worst_match);
- return UMA_STATUS_UNSAFE; // success
+ return UMA_STATUS_MATCH; // success
}
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.h b/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.h
index 0cb5e579212..f3724808f6c 100644
--- a/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.h
+++ b/chromium/components/safe_browsing_db/safe_browsing_api_handler_util.h
@@ -21,10 +21,13 @@ enum RemoteCallResultStatus {
};
// Threat types as per the Java code.
-// This must match those in GMS's SafeBrowsingThreatTypes.java.
+// This must match those in GMS's SafeBrowsingThreat.java.
enum JavaThreatTypes {
+ JAVA_THREAT_TYPE_UNWANTED_SOFTWARE = 3,
JAVA_THREAT_TYPE_POTENTIALLY_HARMFUL_APPLICATION = 4,
JAVA_THREAT_TYPE_SOCIAL_ENGINEERING = 5,
+ JAVA_THREAT_TYPE_SUBRESOURCE_FILTER = 13,
+ JAVA_THREAT_TYPE_MAX_VALUE
};
// Do not reorder or delete entries, and make sure changes here are reflected
@@ -33,7 +36,7 @@ enum UmaRemoteCallResult {
UMA_STATUS_INTERNAL_ERROR = 0,
UMA_STATUS_TIMEOUT = 1,
UMA_STATUS_SAFE = 2,
- UMA_STATUS_UNSAFE = 3,
+ UMA_STATUS_MATCH = 3,
UMA_STATUS_JSON_EMPTY = 4,
UMA_STATUS_JSON_FAILED_TO_PARSE = 5,
UMA_STATUS_JSON_UNKNOWN_THREAT = 6,
diff --git a/chromium/components/safe_browsing_db/util.h b/chromium/components/safe_browsing_db/util.h
index ad6f4e820bd..dd03f5fe03f 100644
--- a/chromium/components/safe_browsing_db/util.h
+++ b/chromium/components/safe_browsing_db/util.h
@@ -16,7 +16,7 @@
#include "base/strings/string_piece.h"
#include "base/time/time.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/safe_browsing_db/v4_protocol_manager_util.h"
class GURL;
diff --git a/chromium/components/safe_browsing_db/v4_database.cc b/chromium/components/safe_browsing_db/v4_database.cc
index c1c7b3eedcd..9164951b2fb 100644
--- a/chromium/components/safe_browsing_db/v4_database.cc
+++ b/chromium/components/safe_browsing_db/v4_database.cc
@@ -204,17 +204,22 @@ std::unique_ptr<StoreStateMap> V4Database::GetStoreStateMap() {
return store_state_map;
}
-bool V4Database::AreStoresAvailable(
+bool V4Database::AreAnyStoresAvailable(
const StoresToCheck& stores_to_check) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (const ListIdentifier& identifier : stores_to_check) {
- const auto& store_pair = store_map_->find(identifier);
- if (store_pair == store_map_->end()) {
- return false; // Store not in our list
- }
- if (!store_pair->second->HasValidData()) {
- return false; // Store never properly populated.
- }
+ if (IsStoreAvailable(identifier))
+ return true;
+ }
+ return false;
+}
+
+bool V4Database::AreAllStoresAvailable(
+ const StoresToCheck& stores_to_check) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ for (const ListIdentifier& identifier : stores_to_check) {
+ if (!IsStoreAvailable(identifier))
+ return false;
}
return true;
}
@@ -226,6 +231,8 @@ void V4Database::GetStoresMatchingFullHash(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
matched_store_and_hash_prefixes->clear();
for (const ListIdentifier& identifier : stores_to_check) {
+ if (!IsStoreAvailable(identifier))
+ continue;
const auto& store_pair = store_map_->find(identifier);
DCHECK(store_pair != store_map_->end());
const std::unique_ptr<V4Store>& store = store_pair->second;
@@ -271,6 +278,19 @@ void V4Database::VerifyChecksumOnTaskRunner(
FROM_HERE, base::Bind(db_ready_for_updates_callback, stores_to_reset));
}
+bool V4Database::IsStoreAvailable(const ListIdentifier& identifier) const {
+ const auto& store_pair = store_map_->find(identifier);
+ if (store_pair == store_map_->end()) {
+ // Store not in our list
+ return false;
+ }
+ if (!store_pair->second->HasValidData()) {
+ // Store never properly populated
+ return false;
+ }
+ return true;
+}
+
void V4Database::RecordFileSizeHistograms() {
int64_t db_size = 0;
for (const auto& store_map_iter : *store_map_) {
diff --git a/chromium/components/safe_browsing_db/v4_database.h b/chromium/components/safe_browsing_db/v4_database.h
index 0fc398dcfb9..fd8b3af8148 100644
--- a/chromium/components/safe_browsing_db/v4_database.h
+++ b/chromium/components/safe_browsing_db/v4_database.h
@@ -20,7 +20,7 @@
#include "components/safe_browsing_db/v4_store.h"
namespace subresource_filter {
-class SubresourceFilterBrowserTestImpl;
+class SubresourceFilterBrowserTest;
}
namespace safe_browsing {
@@ -131,7 +131,13 @@ class V4Database {
// A store may be unavailble if either it hasn't yet gotten a proper
// full-update (just after install, or corrupted/missing file), or if it's
// not supported in this build (i.e. Chromium).
- virtual bool AreStoresAvailable(const StoresToCheck& stores_to_check) const;
+ virtual bool AreAllStoresAvailable(
+ const StoresToCheck& stores_to_check) const;
+
+ // Check if any of the stores are available and populated.
+ // Returns false if all of |stores_to_check| don't have valid data.
+ virtual bool AreAnyStoresAvailable(
+ const StoresToCheck& stores_to_check) const;
// Searches for a hash prefix matching the |full_hash| in stores in the
// database, filtered by |stores_to_check|, and returns the identifier of the
@@ -165,7 +171,7 @@ class V4Database {
const std::unique_ptr<StoreMap> store_map_;
private:
- friend class subresource_filter::SubresourceFilterBrowserTestImpl;
+ friend class subresource_filter::SubresourceFilterBrowserTest;
friend class V4DatabaseFactory;
friend class V4DatabaseTest;
friend class V4SafeBrowsingServiceTest;
@@ -209,6 +215,8 @@ class V4Database {
const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner,
DatabaseReadyForUpdatesCallback db_ready_for_updates_callback);
+ bool IsStoreAvailable(const ListIdentifier& identifier) const;
+
const scoped_refptr<base::SequencedTaskRunner> db_task_runner_;
DatabaseUpdatedCallback db_updated_callback_;
diff --git a/chromium/components/safe_browsing_db/v4_database_unittest.cc b/chromium/components/safe_browsing_db/v4_database_unittest.cc
index 431204551a8..66db6fa5b95 100644
--- a/chromium/components/safe_browsing_db/v4_database_unittest.cc
+++ b/chromium/components/safe_browsing_db/v4_database_unittest.cc
@@ -468,13 +468,22 @@ TEST_F(V4DatabaseTest, TestStoresAvailable) {
const ListIdentifier bogus_id(LINUX_PLATFORM, CHROME_EXTENSION,
CSD_WHITELIST);
- EXPECT_TRUE(v4_database_->AreStoresAvailable(
+ EXPECT_TRUE(v4_database_->AreAllStoresAvailable(
StoresToCheck({linux_malware_id_, win_malware_id_})));
+ EXPECT_TRUE(v4_database_->AreAnyStoresAvailable(
+ StoresToCheck({linux_malware_id_, win_malware_id_})));
+
+ EXPECT_TRUE(
+ v4_database_->AreAllStoresAvailable(StoresToCheck({linux_malware_id_})));
+ EXPECT_TRUE(
+ v4_database_->AreAnyStoresAvailable(StoresToCheck({linux_malware_id_})));
- EXPECT_FALSE(v4_database_->AreStoresAvailable(
+ EXPECT_FALSE(v4_database_->AreAllStoresAvailable(
+ StoresToCheck({linux_malware_id_, bogus_id})));
+ EXPECT_TRUE(v4_database_->AreAnyStoresAvailable(
StoresToCheck({linux_malware_id_, bogus_id})));
- EXPECT_FALSE(v4_database_->AreStoresAvailable(StoresToCheck({bogus_id})));
+ EXPECT_FALSE(v4_database_->AreAllStoresAvailable(StoresToCheck({bogus_id})));
}
// Test to ensure that the callback to the database is dropped when the database
diff --git a/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.cc b/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
index eba742b203e..77488c2c422 100644
--- a/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
+++ b/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
@@ -17,6 +17,7 @@
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h"
@@ -301,8 +302,41 @@ void V4GetHashProtocolManager::GetFullHashes(
net::HttpRequestHeaders headers;
GetHashUrlAndHeaders(req_base64, &gethash_url, &headers);
- std::unique_ptr<net::URLFetcher> owned_fetcher = net::URLFetcher::Create(
- url_fetcher_id_++, gethash_url, net::URLFetcher::GET, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("safe_browsing_v4_get_hash", R"(
+ semantics {
+ sender: "Safe Browsing"
+ description:
+ "When Safe Browsing detects that a URL might be dangerous based on "
+ "its local database, it sends a partial hash of that URL to Google "
+ "to verify it before showing a warning to the user. This partial "
+ "hash does not expose the URL to Google."
+ trigger:
+ "When a resource URL matches the local hash-prefix database of "
+ "potential threats (malware, phishing etc), and the full-hash "
+ "result is not already cached, this will be sent."
+ data:
+ "The 32-bit hash prefix of any potentially bad URLs. The URLs "
+ "themselves are not sent."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: true
+ cookies_store: "Safe Browsing cookie store"
+ setting:
+ "Users can disable Safe Browsing by unchecking 'Protect you and "
+ "your device from dangerous sites' in Chromium settings under "
+ "Privacy. The feature is enabled by default."
+ chrome_policy {
+ SafeBrowsingEnabled {
+ policy_options {mode: MANDATORY}
+ SafeBrowsingEnabled: false
+ }
+ }
+ })");
+ std::unique_ptr<net::URLFetcher> owned_fetcher =
+ net::URLFetcher::Create(url_fetcher_id_++, gethash_url,
+ net::URLFetcher::GET, this, traffic_annotation);
net::URLFetcher* fetcher = owned_fetcher.get();
pending_hash_requests_[fetcher].reset(new FullHashCallbackInfo(
cached_full_hash_infos, prefixes_to_request, std::move(owned_fetcher),
diff --git a/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.h b/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.h
index 8a0f855da50..7d9c2c2aff1 100644
--- a/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.h
+++ b/chromium/components/safe_browsing_db/v4_get_hash_protocol_manager.h
@@ -14,6 +14,7 @@
#include <memory>
#include <string>
+#include <unordered_map>
#include <utility>
#include <vector>
@@ -39,7 +40,7 @@ namespace safe_browsing {
// The matching hash prefixes and corresponding stores, for each full hash
// generated for a given URL.
-typedef base::hash_map<FullHash, StoreAndHashPrefixes>
+typedef std::unordered_map<FullHash, StoreAndHashPrefixes>
FullHashToStoreAndHashPrefixesMap;
// ----------------------------------------------------------------
@@ -90,7 +91,7 @@ struct CachedHashPrefixInfo {
// Cached full hashes received from the server for the corresponding hash
// prefixes.
-typedef base::hash_map<HashPrefix, CachedHashPrefixInfo> FullHashCache;
+typedef std::unordered_map<HashPrefix, CachedHashPrefixInfo> FullHashCache;
// FullHashCallback is invoked when GetFullHashes completes. The parameter is
// the vector of full hash results. If empty, indicates that there were no
@@ -295,8 +296,8 @@ class V4GetHashProtocolManager : public net::URLFetcherDelegate,
private:
// Map of GetHash requests to parameters which created it.
using PendingHashRequests =
- base::hash_map<const net::URLFetcher*,
- std::unique_ptr<FullHashCallbackInfo>>;
+ std::unordered_map<const net::URLFetcher*,
+ std::unique_ptr<FullHashCallbackInfo>>;
// The factory that controls the creation of V4GetHashProtocolManager.
// This is used by tests.
diff --git a/chromium/components/safe_browsing_db/v4_local_database_manager.cc b/chromium/components/safe_browsing_db/v4_local_database_manager.cc
index 6644f662d80..02617ce96cd 100644
--- a/chromium/components/safe_browsing_db/v4_local_database_manager.cc
+++ b/chromium/components/safe_browsing_db/v4_local_database_manager.cc
@@ -256,7 +256,7 @@ bool V4LocalDatabaseManager::CheckResourceUrl(const GURL& url, Client* client) {
StoresToCheck stores_to_check({GetChromeUrlClientIncidentId()});
- if (!CanCheckUrl(url) || !AreStoresAvailableNow(stores_to_check)) {
+ if (!CanCheckUrl(url) || !AreAllStoresAvailableNow(stores_to_check)) {
// Fail open: Mark resource as safe immediately.
// TODO(nparker): This should queue the request if the DB isn't yet
// loaded, and later decide if this store is available.
@@ -276,8 +276,9 @@ bool V4LocalDatabaseManager::CheckUrlForSubresourceFilter(const GURL& url,
Client* client) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- StoresToCheck stores_to_check({GetUrlSubresourceFilterId()});
- if (!AreStoresAvailableNow(stores_to_check) || !CanCheckUrl(url)) {
+ StoresToCheck stores_to_check(
+ {GetUrlSocEngId(), GetUrlSubresourceFilterId()});
+ if (!AreAnyStoresAvailableNow(stores_to_check) || !CanCheckUrl(url)) {
return true;
}
@@ -292,7 +293,7 @@ bool V4LocalDatabaseManager::MatchCsdWhitelistUrl(const GURL& url) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
StoresToCheck stores_to_check({GetUrlCsdWhitelistId()});
- if (!AreStoresAvailableNow(stores_to_check)) {
+ if (!AreAllStoresAvailableNow(stores_to_check)) {
// Fail open: Whitelist everything. Otherwise we may run the
// CSD phishing/malware detector on popular domains and generate
// undue load on the client and server. This has the effect of disabling
@@ -308,7 +309,7 @@ bool V4LocalDatabaseManager::MatchDownloadWhitelistString(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
StoresToCheck stores_to_check({GetCertCsdDownloadWhitelistId()});
- if (!AreStoresAvailableNow(stores_to_check)) {
+ if (!AreAllStoresAvailableNow(stores_to_check)) {
// Fail close: Whitelist nothing. This may generate download-protection
// pings for whitelisted binaries, but that's fine.
return false;
@@ -321,7 +322,7 @@ bool V4LocalDatabaseManager::MatchDownloadWhitelistUrl(const GURL& url) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
StoresToCheck stores_to_check({GetUrlCsdDownloadWhitelistId()});
- if (!AreStoresAvailableNow(stores_to_check)) {
+ if (!AreAllStoresAvailableNow(stores_to_check)) {
// Fail close: Whitelist nothing. This may generate download-protection
// pings for whitelisted domains, but that's fine.
return false;
@@ -351,7 +352,7 @@ bool V4LocalDatabaseManager::MatchModuleWhitelistString(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
StoresToCheck stores_to_check({GetChromeFilenameClientIncidentId()});
- if (!AreStoresAvailableNow(stores_to_check)) {
+ if (!AreAllStoresAvailableNow(stores_to_check)) {
// Fail open: Whitelist everything. This has the effect of marking
// all DLLs as safe until the DB is synced and loaded.
return true;
@@ -757,10 +758,16 @@ void V4LocalDatabaseManager::UpdateRequestCompleted(
db_updated_callback_);
}
-bool V4LocalDatabaseManager::AreStoresAvailableNow(
+bool V4LocalDatabaseManager::AreAllStoresAvailableNow(
const StoresToCheck& stores_to_check) const {
return enabled_ && v4_database_ &&
- v4_database_->AreStoresAvailable(stores_to_check);
+ v4_database_->AreAllStoresAvailable(stores_to_check);
+}
+
+bool V4LocalDatabaseManager::AreAnyStoresAvailableNow(
+ const StoresToCheck& stores_to_check) const {
+ return enabled_ && v4_database_ &&
+ v4_database_->AreAnyStoresAvailable(stores_to_check);
}
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing_db/v4_local_database_manager.h b/chromium/components/safe_browsing_db/v4_local_database_manager.h
index e010dee3cef..9e3ea4fa00f 100644
--- a/chromium/components/safe_browsing_db/v4_local_database_manager.h
+++ b/chromium/components/safe_browsing_db/v4_local_database_manager.h
@@ -272,7 +272,11 @@ class V4LocalDatabaseManager : public SafeBrowsingDatabaseManager {
// Return true if we're enabled and have loaded real data for all of
// these stores.
- bool AreStoresAvailableNow(const StoresToCheck& stores_to_check) const;
+ bool AreAllStoresAvailableNow(const StoresToCheck& stores_to_check) const;
+
+ // Return true if we're enabled and have loaded real data for any of
+ // these stores.
+ bool AreAnyStoresAvailableNow(const StoresToCheck& stores_to_check) const;
// The base directory under which to create the files that contain hashes.
const base::FilePath base_path_;
diff --git a/chromium/components/safe_browsing_db/v4_local_database_manager_unittest.cc b/chromium/components/safe_browsing_db/v4_local_database_manager_unittest.cc
index 595feec8aa7..34cb4ac5887 100644
--- a/chromium/components/safe_browsing_db/v4_local_database_manager_unittest.cc
+++ b/chromium/components/safe_browsing_db/v4_local_database_manager_unittest.cc
@@ -6,6 +6,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -119,7 +120,13 @@ class FakeV4Database : public V4Database {
}
}
- bool AreStoresAvailable(const StoresToCheck& stores_to_check) const override {
+ bool AreAllStoresAvailable(
+ const StoresToCheck& stores_to_check) const override {
+ return stores_available_;
+ }
+
+ bool AreAnyStoresAvailable(
+ const StoresToCheck& stores_to_check) const override {
return stores_available_;
}
diff --git a/chromium/components/safe_browsing_db/v4_protocol_manager_util.cc b/chromium/components/safe_browsing_db/v4_protocol_manager_util.cc
index 9a97b0e4229..bd097a72b58 100644
--- a/chromium/components/safe_browsing_db/v4_protocol_manager_util.cc
+++ b/chromium/components/safe_browsing_db/v4_protocol_manager_util.cc
@@ -5,6 +5,7 @@
#include "components/safe_browsing_db/v4_protocol_manager_util.h"
#include "base/base64.h"
+#include "base/hash.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "base/sha1.h"
@@ -304,7 +305,7 @@ bool V4ProtocolManagerUtil::FullHashToHashPrefix(const FullHash& full_hash,
if (full_hash.size() < prefix_size) {
return false;
}
- *hash_prefix = full_hash.substr(prefix_size);
+ *hash_prefix = full_hash.substr(0, prefix_size);
return true;
}
diff --git a/chromium/components/safe_browsing_db/v4_protocol_manager_util_unittest.cc b/chromium/components/safe_browsing_db/v4_protocol_manager_util_unittest.cc
index 0680d3cc060..8018a9a896f 100644
--- a/chromium/components/safe_browsing_db/v4_protocol_manager_util_unittest.cc
+++ b/chromium/components/safe_browsing_db/v4_protocol_manager_util_unittest.cc
@@ -269,4 +269,28 @@ TEST_F(V4ProtocolManagerUtilTest, TestIPAddressToEncodedIPV6) {
}
}
+TEST_F(V4ProtocolManagerUtilTest, TestFullHashToHashPrefix) {
+ const std::string full_hash = "abcdefgh";
+ std::vector<std::tuple<bool, std::string, PrefixSize, std::string>>
+ test_cases = {
+ std::make_tuple(true, "", 0, ""),
+ std::make_tuple(false, "", kMinHashPrefixLength, ""),
+ std::make_tuple(true, "a", 1, full_hash),
+ std::make_tuple(true, "abcd", kMinHashPrefixLength, full_hash),
+ std::make_tuple(true, "abcde", kMinHashPrefixLength + 1, full_hash)};
+ for (size_t i = 0; i < test_cases.size(); i++) {
+ DVLOG(1) << "Running case: " << i;
+ bool success = std::get<0>(test_cases[i]);
+ const auto& expected_prefix = std::get<1>(test_cases[i]);
+ const PrefixSize& prefix_size = std::get<2>(test_cases[i]);
+ const auto& input_full_hash = std::get<3>(test_cases[i]);
+ std::string prefix;
+ ASSERT_EQ(success, V4ProtocolManagerUtil::FullHashToHashPrefix(
+ input_full_hash, prefix_size, &prefix));
+ if (success) {
+ ASSERT_EQ(expected_prefix, prefix);
+ }
+ }
+}
+
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing_db/v4_update_protocol_manager.cc b/chromium/components/safe_browsing_db/v4_update_protocol_manager.cc
index e72eb44c029..3d485bdd6bf 100644
--- a/chromium/components/safe_browsing_db/v4_update_protocol_manager.cc
+++ b/chromium/components/safe_browsing_db/v4_update_protocol_manager.cc
@@ -17,6 +17,7 @@
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h"
@@ -311,8 +312,37 @@ void V4UpdateProtocolManager::IssueUpdateRequest() {
net::HttpRequestHeaders headers;
GetUpdateUrlAndHeaders(req_base64, &update_url, &headers);
- std::unique_ptr<net::URLFetcher> fetcher = net::URLFetcher::Create(
- url_fetcher_id_++, update_url, net::URLFetcher::GET, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("safe_browsing_g4_update", R"(
+ semantics {
+ sender: "Safe Browsing"
+ description:
+ "Safe Browsing issues a request to Google every 30 minutes or so "
+ "to get the latest database of hashes of bad URLs."
+ trigger:
+ "On a timer, approximately every 30 minutes."
+ data:
+ "The state of the local DB is sent so the server can send just "
+ "the changes. This doesn't include any user data."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: true
+ cookies_store: "Safe Browsing cookie store"
+ setting:
+ "Users can disable Safe Browsing by unchecking 'Protect you and "
+ "your device from dangerous sites' in Chromium settings under "
+ "Privacy. The feature is enabled by default."
+ chrome_policy {
+ SafeBrowsingEnabled {
+ policy_options {mode: MANDATORY}
+ SafeBrowsingEnabled: false
+ }
+ }
+ })");
+ std::unique_ptr<net::URLFetcher> fetcher =
+ net::URLFetcher::Create(url_fetcher_id_++, update_url,
+ net::URLFetcher::GET, this, traffic_annotation);
fetcher->SetExtraRequestHeaders(headers.ToString());
data_use_measurement::DataUseUserData::AttachToFetcher(
fetcher.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
diff --git a/chromium/components/safe_browsing_db/v4_update_protocol_manager.h b/chromium/components/safe_browsing_db/v4_update_protocol_manager.h
index 4405742938c..5c60a0c398d 100644
--- a/chromium/components/safe_browsing_db/v4_update_protocol_manager.h
+++ b/chromium/components/safe_browsing_db/v4_update_protocol_manager.h
@@ -21,7 +21,7 @@
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/safe_browsing_db/safebrowsing.pb.h"
#include "components/safe_browsing_db/util.h"
#include "components/safe_browsing_db/v4_protocol_manager_util.h"
diff --git a/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.cc b/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.cc
index 1595192008e..2cb3bb00b20 100644
--- a/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.cc
+++ b/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.cc
@@ -20,21 +20,22 @@ SafeJsonParserMojoImpl::~SafeJsonParserMojoImpl() = default;
// static
void SafeJsonParserMojoImpl::Create(
- mojo::InterfaceRequest<mojom::SafeJsonParser> request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::SafeJsonParserRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<SafeJsonParserMojoImpl>(),
std::move(request));
}
void SafeJsonParserMojoImpl::Parse(const std::string& json,
- const ParseCallback& callback) {
+ ParseCallback callback) {
int error_code;
std::string error;
std::unique_ptr<base::Value> value = base::JSONReader::ReadAndReturnError(
json, base::JSON_PARSE_RFC, &error_code, &error);
if (value) {
- callback.Run(std::move(value), base::nullopt);
+ std::move(callback).Run(std::move(value), base::nullopt);
} else {
- callback.Run(nullptr, base::make_optional(std::move(error)));
+ std::move(callback).Run(nullptr, base::make_optional(std::move(error)));
}
}
diff --git a/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.h b/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.h
index 0f3ed387161..cfe18d0ab37 100644
--- a/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.h
+++ b/chromium/components/safe_json/utility/safe_json_parser_mojo_impl.h
@@ -10,6 +10,10 @@
#include "base/macros.h"
#include "components/safe_json/public/interfaces/safe_json.mojom.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace safe_json {
class SafeJsonParserMojoImpl : public mojom::SafeJsonParser {
@@ -17,11 +21,12 @@ class SafeJsonParserMojoImpl : public mojom::SafeJsonParser {
SafeJsonParserMojoImpl();
~SafeJsonParserMojoImpl() override;
- static void Create(mojo::InterfaceRequest<mojom::SafeJsonParser> request);
+ static void Create(const service_manager::BindSourceInfo& source_info,
+ mojom::SafeJsonParserRequest request);
private:
// mojom::SafeJsonParser implementation.
- void Parse(const std::string& json, const ParseCallback& callback) override;
+ void Parse(const std::string& json, ParseCallback callback) override;
DISALLOW_COPY_AND_ASSIGN(SafeJsonParserMojoImpl);
};
diff --git a/chromium/components/search_engines/BUILD.gn b/chromium/components/search_engines/BUILD.gn
index 0b0da285dde..fc5445c3ccd 100644
--- a/chromium/components/search_engines/BUILD.gn
+++ b/chromium/components/search_engines/BUILD.gn
@@ -4,6 +4,10 @@
import("//build/config/features.gni")
import("//tools/json_to_struct/json_to_struct.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
static_library("search_engines") {
sources = [
@@ -46,16 +50,19 @@ static_library("search_engines") {
]
public_deps = [
+ "//base",
+ "//components/google/core/browser",
+ "//components/keyed_service/core",
"//components/metrics/proto",
+ "//components/prefs",
+ "//components/sync",
+ "//components/webdata/common",
]
deps = [
":prepopulated_engines",
- "//base",
"//base:i18n",
- "//components/google/core/browser",
"//components/history/core/browser",
- "//components/keyed_service/core",
"//components/metrics/proto",
# The search_engines target is in an include cycle with
@@ -65,12 +72,9 @@ static_library("search_engines") {
#"//components/omnibox/browser",
"//components/infobars/core",
"//components/pref_registry",
- "//components/prefs",
"//components/rappor",
"//components/strings",
- "//components/sync",
"//components/url_formatter",
- "//components/webdata/common",
"//google_apis",
"//net",
"//sql",
@@ -158,3 +162,11 @@ json_to_struct("prepopulated_engines") {
schema_file = "prepopulated_engines_schema.json"
namespace = "TemplateURLPrepopulateData"
}
+
+if (is_android) {
+ java_cpp_enum("search_engine_type_java") {
+ sources = [
+ "search_engine_type.h",
+ ]
+ }
+}
diff --git a/chromium/components/search_engines/prepopulated_engines.json b/chromium/components/search_engines/prepopulated_engines.json
index 3ebf56b8918..58f4ae0dcc9 100644
--- a/chromium/components/search_engines/prepopulated_engines.json
+++ b/chromium/components/search_engines/prepopulated_engines.json
@@ -616,7 +616,7 @@
"name": "\u042f\u043d\u0434\u0435\u043a\u0441",
"keyword": "yandex.ru",
"favicon_url": "https://yastatic.net/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico",
- "search_url": "https://yandex.ru/{yandex:searchPath}?text={searchTerms}",
+ "search_url": "https://yandex.ru/{yandex:searchPath}?text={searchTerms}&{yandex:referralID}",
"suggest_url": "https://suggest.yandex.ru/suggest-ff.cgi?part={searchTerms}",
"image_url": "https://yandex.ru/images/search/?rpt=imageview",
"image_url_post_params": "upfile={google:imageThumbnail},original_width={google:imageOriginalWidth},original_height={google:imageOriginalHeight},prg=1",
diff --git a/chromium/components/search_engines/search_engine_data_type_controller_unittest.cc b/chromium/components/search_engines/search_engine_data_type_controller_unittest.cc
index a9c07218644..ca42589b9be 100644
--- a/chromium/components/search_engines/search_engine_data_type_controller_unittest.cc
+++ b/chromium/components/search_engines/search_engine_data_type_controller_unittest.cc
@@ -27,7 +27,7 @@ using testing::_;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Return;
-using testing::SetArgumentPointee;
+using testing::SetArgPointee;
namespace browser_sync {
namespace {
diff --git a/chromium/components/search_engines/search_engine_type.h b/chromium/components/search_engines/search_engine_type.h
index f61971487da..c19dd0e91cf 100644
--- a/chromium/components/search_engines/search_engine_type.h
+++ b/chromium/components/search_engines/search_engine_type.h
@@ -8,6 +8,9 @@
// Enum to record the user's default search engine choice in UMA. Add new
// search engines at the bottom and do not delete from this list, so as not
// to disrupt UMA data already recorded.
+
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.search_engines
enum SearchEngineType {
// Prepopulated engines.
SEARCH_ENGINE_UNKNOWN = -1,
diff --git a/chromium/components/search_engines/search_terms_data.cc b/chromium/components/search_engines/search_terms_data.cc
index f0ef783c6ec..d532ae61c8c 100644
--- a/chromium/components/search_engines/search_terms_data.cc
+++ b/chromium/components/search_engines/search_terms_data.cc
@@ -66,3 +66,7 @@ std::string SearchTermsData::ForceInstantResultsParam(
std::string SearchTermsData::GoogleImageSearchSource() const {
return std::string();
}
+
+std::string SearchTermsData::GetYandexReferralID() const {
+ return std::string();
+}
diff --git a/chromium/components/search_engines/search_terms_data.h b/chromium/components/search_engines/search_terms_data.h
index 50f7ed2eb93..c72b99222f4 100644
--- a/chromium/components/search_engines/search_terms_data.h
+++ b/chromium/components/search_engines/search_terms_data.h
@@ -61,6 +61,10 @@ class SearchTermsData {
// GOOGLE_IMAGE_SEARCH_SOURCE.
virtual std::string GoogleImageSearchSource() const;
+ // Returns the optional referral ID to be passed to Yandex when searching from
+ // the omnibox (returns the empty string if not supported/applicable).
+ virtual std::string GetYandexReferralID() const;
+
private:
DISALLOW_COPY_AND_ASSIGN(SearchTermsData);
};
diff --git a/chromium/components/search_engines/template_url.cc b/chromium/components/search_engines/template_url.cc
index a3a162a0a26..1478d897802 100644
--- a/chromium/components/search_engines/template_url.cc
+++ b/chromium/components/search_engines/template_url.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/format_macros.h"
+#include "base/i18n/case_conversion.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
@@ -97,63 +98,63 @@ bool TryEncoding(const base::string16& terms,
return true;
}
-// Returns true if the search term placeholder is present, and also produces
-// the constant prefix/suffix found.
-bool TryMatchSearchParam(base::StringPiece text,
- base::StringPiece pattern,
- std::string* prefix,
- std::string* suffix) {
- auto pos = text.find(pattern);
- if (pos == base::StringPiece::npos)
- return false;
- text.substr(0, pos).CopyToString(prefix);
- text.substr(pos + pattern.length()).CopyToString(suffix);
- return true;
-}
-
-// Extract query key and host given a list of parameters coming from the URL
-// query or ref.
-struct SearchTermsKeyResult {
- std::string key;
- std::string value_prefix;
- std::string value_suffix;
- bool found() const { return !key.empty(); }
-};
-SearchTermsKeyResult FindSearchTermsKey(const std::string& params) {
- SearchTermsKeyResult result;
- if (params.empty())
- return result;
- url::Component query, key, value;
- query.len = static_cast<int>(params.size());
- while (url::ExtractQueryKeyValue(params.c_str(), &query, &key, &value)) {
- if (key.is_nonempty() && value.is_nonempty()) {
- const base::StringPiece value_string(params.c_str() + value.begin,
- value.len);
- if (TryMatchSearchParam(value_string, kSearchTermsParameterFull,
- &result.value_prefix, &result.value_suffix) ||
- TryMatchSearchParam(value_string,
- kGoogleUnescapedSearchTermsParameterFull,
- &result.value_prefix, &result.value_suffix)) {
- result.key = params.substr(key.begin, key.len);
- break;
+// Finds the position of the search terms' parameter in the URL component.
+class SearchTermLocation {
+ public:
+ SearchTermLocation(const base::StringPiece& url_component,
+ url::Parsed::ComponentType url_component_type)
+ : found_(false) {
+ if (url_component_type == url::Parsed::PATH) {
+ // GURL's constructor escapes "{" and "}" in the path of a passed string.
+ found_ =
+ TryMatchSearchParam(url_component, kSearchTermsParameterFullEscaped);
+ } else {
+ DCHECK((url_component_type == url::Parsed::QUERY) ||
+ (url_component_type == url::Parsed::REF));
+ url::Component query, key, value;
+ query.len = static_cast<int>(url_component.size());
+ while (url::ExtractQueryKeyValue(url_component.data(), &query, &key,
+ &value)) {
+ if (key.is_nonempty() && value.is_nonempty()) {
+ const base::StringPiece value_string =
+ url_component.substr(value.begin, value.len);
+ if (TryMatchSearchParam(value_string, kSearchTermsParameterFull) ||
+ TryMatchSearchParam(value_string,
+ kGoogleUnescapedSearchTermsParameterFull)) {
+ found_ = true;
+ url_component.substr(key.begin, key.len).CopyToString(&key_);
+ break;
+ }
+ }
}
}
}
- return result;
-}
-// Extract the position of the search terms' parameter in the URL path.
-bool FindSearchTermsInPath(const std::string& path,
- url::Component* parameter_position) {
- DCHECK(parameter_position);
- parameter_position->reset();
- const size_t begin = path.find(kSearchTermsParameterFullEscaped);
- if (begin == std::string::npos)
- return false;
- parameter_position->begin = begin;
- parameter_position->len = arraysize(kSearchTermsParameterFullEscaped) - 1;
- return true;
-}
+ bool found() const { return found_; }
+ const std::string& key() const { return key_; }
+ const std::string& value_prefix() const { return value_prefix_; }
+ const std::string& value_suffix() const { return value_suffix_; }
+
+ private:
+ // Returns true if the search term placeholder is present, and also assigns
+ // the constant prefix/suffix found.
+ bool TryMatchSearchParam(const base::StringPiece& value,
+ const base::StringPiece& pattern) {
+ size_t pos = value.find(pattern);
+ if (pos == base::StringPiece::npos)
+ return false;
+ value.substr(0, pos).CopyToString(&value_prefix_);
+ value.substr(pos + pattern.length()).CopyToString(&value_suffix_);
+ return true;
+ }
+
+ bool found_;
+ std::string key_;
+ std::string value_prefix_;
+ std::string value_suffix_;
+
+ DISALLOW_COPY_AND_ASSIGN(SearchTermLocation);
+};
bool IsTemplateParameterString(const std::string& param) {
return (param.length() > 2) && (*(param.begin()) == kStartParameter) &&
@@ -211,7 +212,6 @@ TemplateURLRef::TemplateURLRef(const TemplateURL* owner, Type type)
parsed_(false),
valid_(false),
supports_replacements_(false),
- search_term_position_in_path_(std::string::npos),
search_term_key_location_(url::Parsed::QUERY),
prepopulated_(false) {
DCHECK(owner_);
@@ -225,7 +225,6 @@ TemplateURLRef::TemplateURLRef(const TemplateURL* owner, size_t index_in_owner)
parsed_(false),
valid_(false),
supports_replacements_(false),
- search_term_position_in_path_(std::string::npos),
search_term_key_location_(url::Parsed::QUERY),
prepopulated_(false) {
DCHECK(owner_);
@@ -392,20 +391,26 @@ const std::string& TemplateURLRef::GetSearchTermKey(
return search_term_key_;
}
-size_t TemplateURLRef::GetSearchTermPositionInPath(
+url::Parsed::ComponentType TemplateURLRef::GetSearchTermKeyLocation(
const SearchTermsData& search_terms_data) const {
ParseIfNecessary(search_terms_data);
- return search_term_position_in_path_;
+ return search_term_key_location_;
}
-url::Parsed::ComponentType TemplateURLRef::GetSearchTermKeyLocation(
+const std::string& TemplateURLRef::GetSearchTermValuePrefix(
const SearchTermsData& search_terms_data) const {
ParseIfNecessary(search_terms_data);
- return search_term_key_location_;
+ return search_term_value_prefix_;
+}
+
+const std::string& TemplateURLRef::GetSearchTermValueSuffix(
+ const SearchTermsData& search_terms_data) const {
+ ParseIfNecessary(search_terms_data);
+ return search_term_value_suffix_;
}
base::string16 TemplateURLRef::SearchTermToString16(
- const std::string& term) const {
+ const base::StringPiece& term) const {
const std::vector<std::string>& encodings = owner_->input_encodings();
base::string16 result;
@@ -471,30 +476,33 @@ bool TemplateURLRef::ExtractSearchTermsFromURL(
return false;
}
- std::string source;
+ base::StringPiece source;
url::Component position;
if (search_term_key_location_ == url::Parsed::PATH) {
- source = url.path();
-
- // Characters in the path before and after search terms must match.
- if (source.length() < path_.length())
- return false;
- position.begin = search_term_position_in_path_;
- position.len = source.length() - path_.length();
- if (source.substr(0, position.begin) + source.substr(position.end()) !=
- path_)
+ source = url.path_piece();
+
+ // If the path does not contain the expected prefix and suffix, then this is
+ // not a match.
+ if (source.size() < (search_term_value_prefix_.size() +
+ search_term_value_suffix_.size()) ||
+ !source.starts_with(search_term_value_prefix_) ||
+ !source.ends_with(search_term_value_suffix_))
return false;
+ position =
+ url::MakeRange(search_term_value_prefix_.size(),
+ source.length() - search_term_value_suffix_.size());
} else {
DCHECK(search_term_key_location_ == url::Parsed::QUERY ||
search_term_key_location_ == url::Parsed::REF);
- source = (search_term_key_location_ == url::Parsed::QUERY) ?
- url.query() : url.ref();
+ source = (search_term_key_location_ == url::Parsed::QUERY)
+ ? url.query_piece()
+ : url.ref_piece();
url::Component query, key, value;
query.len = static_cast<int>(source.size());
bool key_found = false;
- while (url::ExtractQueryKeyValue(source.c_str(), &query, &key, &value)) {
+ while (url::ExtractQueryKeyValue(source.data(), &query, &key, &value)) {
if (key.is_nonempty()) {
if (source.substr(key.begin, key.len) == search_term_key_) {
// Fail if search term key is found twice.
@@ -538,8 +546,9 @@ void TemplateURLRef::InvalidateCachedValues() const {
port_.clear();
path_.clear();
search_term_key_.clear();
- search_term_position_in_path_ = std::string::npos;
search_term_key_location_ = url::Parsed::QUERY;
+ search_term_value_prefix_.clear();
+ search_term_value_suffix_.clear();
replacements_.clear();
post_params_.clear();
}
@@ -648,6 +657,8 @@ bool TemplateURLRef::ParseParameter(size_t start,
replacements->push_back(Replacement(GOOGLE_SUGGEST_REQUEST_ID, start));
} else if (parameter == kGoogleUnescapedSearchTermsParameter) {
replacements->push_back(Replacement(GOOGLE_UNESCAPED_SEARCH_TERMS, start));
+ } else if (parameter == "yandex:referralID") {
+ replacements->push_back(Replacement(YANDEX_REFERRAL_ID, start));
} else if (parameter == "yandex:searchPath") {
switch (ui::GetDeviceFormFactor()) {
case ui::DEVICE_FORM_FACTOR_DESKTOP:
@@ -790,35 +801,34 @@ void TemplateURLRef::ParseHostAndSearchTermKey(
if (!url.is_valid())
return;
- auto query_result = FindSearchTermsKey(url.query());
- auto ref_result = FindSearchTermsKey(url.ref());
- url::Component parameter_position;
+ SearchTermLocation query_result(url.query_piece(), url::Parsed::QUERY);
+ SearchTermLocation ref_result(url.ref_piece(), url::Parsed::REF);
+ SearchTermLocation path_result(url.path_piece(), url::Parsed::PATH);
const bool in_query = query_result.found();
const bool in_ref = ref_result.found();
- const bool in_path = FindSearchTermsInPath(url.path(), &parameter_position);
+ const bool in_path = path_result.found();
if (in_query ? (in_ref || in_path) : (in_ref == in_path))
return; // No key or multiple keys found. We only handle having one key.
host_ = url.host();
port_ = url.port();
- path_ = url.path();
if (in_query) {
- search_term_key_ = query_result.key;
search_term_key_location_ = url::Parsed::QUERY;
- search_term_value_prefix_ = query_result.value_prefix;
- search_term_value_suffix_ = query_result.value_suffix;
+ search_term_key_ = query_result.key();
+ search_term_value_prefix_ = query_result.value_prefix();
+ search_term_value_suffix_ = query_result.value_suffix();
+ path_ = url.path();
} else if (in_ref) {
- search_term_key_ = ref_result.key;
search_term_key_location_ = url::Parsed::REF;
- search_term_value_prefix_ = ref_result.value_prefix;
- search_term_value_suffix_ = ref_result.value_suffix;
+ search_term_key_ = ref_result.key();
+ search_term_value_prefix_ = ref_result.value_prefix();
+ search_term_value_suffix_ = ref_result.value_suffix();
+ path_ = url.path();
} else {
DCHECK(in_path);
- DCHECK_GE(parameter_position.begin, 1); // Path must start with '/'.
search_term_key_location_ = url::Parsed::PATH;
- search_term_position_in_path_ = parameter_position.begin;
- // Remove the "{searchTerms}" itself from |path_|.
- path_.erase(parameter_position.begin, parameter_position.len);
+ search_term_value_prefix_ = path_result.value_prefix();
+ search_term_value_suffix_ = path_result.value_suffix();
}
}
@@ -1124,6 +1134,13 @@ std::string TemplateURLRef::HandleReplacements(
#endif
break;
+ case YANDEX_REFERRAL_ID: {
+ std::string referral_id = search_terms_data.GetYandexReferralID();
+ if (!referral_id.empty())
+ HandleReplacement("clid", referral_id, *i, &url);
+ break;
+ }
+
default:
NOTREACHED();
break;
@@ -1140,8 +1157,12 @@ std::string TemplateURLRef::HandleReplacements(
// TemplateURL ----------------------------------------------------------------
TemplateURL::AssociatedExtensionInfo::AssociatedExtensionInfo(
- const std::string& extension_id)
- : extension_id(extension_id), wants_to_be_default_engine(false) {}
+ const std::string& extension_id,
+ base::Time install_time,
+ bool wants_to_be_default_engine)
+ : extension_id(extension_id),
+ install_time(install_time),
+ wants_to_be_default_engine(wants_to_be_default_engine) {}
TemplateURL::AssociatedExtensionInfo::~AssociatedExtensionInfo() {
}
@@ -1164,6 +1185,21 @@ TemplateURL::TemplateURL(const TemplateURLData& data, Type type)
data_.search_terms_replacement_key = google_util::kInstantExtendedAPIParam;
}
+TemplateURL::TemplateURL(const TemplateURLData& data,
+ Type type,
+ std::string extension_id,
+ base::Time install_time,
+ bool wants_to_be_default_engine)
+ : TemplateURL(data, type) {
+ DCHECK(type == NORMAL_CONTROLLED_BY_EXTENSION ||
+ type == OMNIBOX_API_EXTENSION);
+ // Omnibox keywords may not be set as default.
+ DCHECK(!wants_to_be_default_engine || type != OMNIBOX_API_EXTENSION) << type;
+ DCHECK_EQ(kInvalidTemplateURLID, data.id);
+ extension_info_ = base::MakeUnique<AssociatedExtensionInfo>(
+ extension_id, install_time, wants_to_be_default_engine);
+}
+
TemplateURL::~TemplateURL() {
}
@@ -1179,7 +1215,8 @@ base::string16 TemplateURL::GenerateKeyword(const GURL& url) {
// Special case: if the host was exactly "www." (not sure this can happen but
// perhaps with some weird intranet and custom DNS server?), ensure we at
// least don't return the empty string.
- return keyword.empty() ? base::ASCIIToUTF16("www") : keyword;
+ return keyword.empty() ? base::ASCIIToUTF16("www")
+ : base::i18n::ToLower(keyword);
}
// static
@@ -1329,7 +1366,7 @@ bool TemplateURL::ReplaceSearchTermsInURL(
const GURL& url,
const TemplateURLRef::SearchTermsArgs& search_terms_args,
const SearchTermsData& search_terms_data,
- GURL* result) {
+ GURL* result) const {
// TODO(beaudoin): Use AQS from |search_terms_args| too.
url::Parsed::ComponentType search_term_component;
url::Component search_terms_position;
diff --git a/chromium/components/search_engines/template_url.h b/chromium/components/search_engines/template_url.h
index 92fb852c1a5..169997d71bd 100644
--- a/chromium/components/search_engines/template_url.h
+++ b/chromium/components/search_engines/template_url.h
@@ -238,20 +238,26 @@ class TemplateURLRef {
const std::string& GetSearchTermKey(
const SearchTermsData& search_terms_data) const;
- // If this TemplateURLRef is valid and contains one search term
- // in its path, this returns the length of the subpath before the search term,
- // otherwise this returns std::string::npos.
- size_t GetSearchTermPositionInPath(
- const SearchTermsData& search_terms_data) const;
-
// If this TemplateURLRef is valid and contains one search term,
// this returns the location of the search term,
// otherwise this returns url::Parsed::QUERY.
url::Parsed::ComponentType GetSearchTermKeyLocation(
const SearchTermsData& search_terms_data) const;
+ // If this TemplateURLRef is valid and contains one search term,
+ // this returns the fixed prefix before the search term,
+ // otherwise this returns an empty string.
+ const std::string& GetSearchTermValuePrefix(
+ const SearchTermsData& search_terms_data) const;
+
+ // If this TemplateURLRef is valid and contains one search term,
+ // this returns the fixed suffix after the search term,
+ // otherwise this returns an empty string.
+ const std::string& GetSearchTermValueSuffix(
+ const SearchTermsData& search_terms_data) const;
+
// Converts the specified term in our owner's encoding to a base::string16.
- base::string16 SearchTermToString16(const std::string& term) const;
+ base::string16 SearchTermToString16(const base::StringPiece& term) const;
// Returns true if this TemplateURLRef has a replacement term of
// {google:baseURL} or {google:baseSuggestURL}.
@@ -321,6 +327,7 @@ class TemplateURLRef {
GOOGLE_UNESCAPED_SEARCH_TERMS,
LANGUAGE,
SEARCH_TERMS,
+ YANDEX_REFERRAL_ID,
};
// Used to identify an element of the raw url that can be replaced.
@@ -442,7 +449,6 @@ class TemplateURLRef {
mutable std::string port_;
mutable std::string path_;
mutable std::string search_term_key_;
- mutable size_t search_term_position_in_path_;
mutable url::Parsed::ComponentType search_term_key_location_;
mutable std::string search_term_value_prefix_;
mutable std::string search_term_value_suffix_;
@@ -482,20 +488,31 @@ class TemplateURL {
// An AssociatedExtensionInfo represents information about the extension that
// added the search engine.
struct AssociatedExtensionInfo {
- explicit AssociatedExtensionInfo(const std::string& extension_id);
+ AssociatedExtensionInfo(const std::string& extension_id,
+ base::Time install_time,
+ bool wants_to_be_default_engine);
~AssociatedExtensionInfo();
std::string extension_id;
- // Whether the search engine is supposed to be default.
- bool wants_to_be_default_engine;
-
// Used to resolve conflicts when there are multiple extensions specifying
// the default search engine. The most recently-installed wins.
base::Time install_time;
+
+ // Whether the search engine is supposed to be default.
+ bool wants_to_be_default_engine;
};
explicit TemplateURL(const TemplateURLData& data, Type type = NORMAL);
+
+ // Constructor for extension controlled engine. |type| must be
+ // NORMAL_CONTROLLED_BY_EXTENSION or OMNIBOX_API_EXTENSION.
+ TemplateURL(const TemplateURLData& data,
+ Type type,
+ std::string extension_id,
+ base::Time install_time,
+ bool wants_to_be_default_engine);
+
~TemplateURL();
// Generates a suitable keyword for the specified url, which must be valid.
@@ -660,7 +677,7 @@ class TemplateURL {
const GURL& url,
const TemplateURLRef::SearchTermsArgs& search_terms_args,
const SearchTermsData& search_terms_data,
- GURL* result);
+ GURL* result) const;
// Encodes the search terms from |search_terms_args| so that we know the
// |input_encoding|. Returns the |encoded_terms| and the
diff --git a/chromium/components/search_engines/template_url_service.cc b/chromium/components/search_engines/template_url_service.cc
index a4db5e184d0..9433205bea4 100644
--- a/chromium/components/search_engines/template_url_service.cc
+++ b/chromium/components/search_engines/template_url_service.cc
@@ -396,6 +396,13 @@ void TemplateURLService::AddMatchingDomainKeywords(
TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
const base::string16& keyword) {
+ return const_cast<TemplateURL*>(
+ static_cast<const TemplateURLService*>(this)->
+ GetTemplateURLForKeyword(keyword));
+}
+
+const TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
+ const base::string16& keyword) const {
KeywordToTURLAndMeaningfulLength::const_iterator elem(
keyword_to_turl_and_length_.find(keyword));
if (elem != keyword_to_turl_and_length_.end())
@@ -408,6 +415,13 @@ TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
TemplateURL* TemplateURLService::GetTemplateURLForGUID(
const std::string& sync_guid) {
+return const_cast<TemplateURL*>(
+ static_cast<const TemplateURLService*>(this)->
+ GetTemplateURLForGUID(sync_guid));
+}
+
+const TemplateURL* TemplateURLService::GetTemplateURLForGUID(
+ const std::string& sync_guid) const {
GUIDToTURL::const_iterator elem(guid_to_turl_.find(sync_guid));
if (elem != guid_to_turl_.end())
return elem->second;
@@ -419,6 +433,13 @@ TemplateURL* TemplateURLService::GetTemplateURLForGUID(
TemplateURL* TemplateURLService::GetTemplateURLForHost(
const std::string& host) {
+ return const_cast<TemplateURL*>(
+ static_cast<const TemplateURLService*>(this)->
+ GetTemplateURLForHost(host));
+}
+
+const TemplateURL* TemplateURLService::GetTemplateURLForHost(
+ const std::string& host) const {
if (loaded_)
return provider_map_->GetTemplateURLForHost(host);
TemplateURL* initial_dsp = initial_default_search_provider_.get();
@@ -431,6 +452,13 @@ TemplateURL* TemplateURLService::GetTemplateURLForHost(
TemplateURL* TemplateURLService::Add(
std::unique_ptr<TemplateURL> template_url) {
+ DCHECK(template_url);
+ DCHECK(
+ !IsCreatedByExtension(template_url.get()) ||
+ (!FindTemplateURLForExtension(template_url->extension_info_->extension_id,
+ template_url->type()) &&
+ template_url->id() == kInvalidTemplateURLID));
+
KeywordWebDataService::BatchModeScoper scoper(web_data_service_.get());
TemplateURL* template_url_ptr = AddNoNotify(std::move(template_url), true);
if (template_url_ptr)
@@ -452,21 +480,6 @@ TemplateURL* TemplateURLService::AddWithOverrides(
return Add(std::move(template_url));
}
-TemplateURL* TemplateURLService::AddExtensionControlledTURL(
- std::unique_ptr<TemplateURL> template_url,
- std::unique_ptr<TemplateURL::AssociatedExtensionInfo> info) {
- DCHECK(template_url);
- DCHECK_EQ(kInvalidTemplateURLID, template_url->id());
- DCHECK(info);
- DCHECK_NE(TemplateURL::NORMAL, template_url->type());
- DCHECK(
- !FindTemplateURLForExtension(info->extension_id, template_url->type()));
-
- template_url->extension_info_.swap(info);
-
- return Add(std::move(template_url));
-}
-
void TemplateURLService::Remove(TemplateURL* template_url) {
RemoveNoNotify(template_url);
NotifyObservers();
@@ -534,12 +547,9 @@ void TemplateURLService::RegisterOmniboxKeyword(
data.SetShortName(base::UTF8ToUTF16(extension_name));
data.SetKeyword(base::UTF8ToUTF16(keyword));
data.SetURL(template_url_string);
- std::unique_ptr<TemplateURL::AssociatedExtensionInfo> info(
- new TemplateURL::AssociatedExtensionInfo(extension_id));
- info->install_time = extension_install_time;
- AddExtensionControlledTURL(
- base::MakeUnique<TemplateURL>(data, TemplateURL::OMNIBOX_API_EXTENSION),
- std::move(info));
+ Add(base::MakeUnique<TemplateURL>(data, TemplateURL::OMNIBOX_API_EXTENSION,
+ extension_id, extension_install_time,
+ false));
}
TemplateURLService::TemplateURLVector TemplateURLService::GetTemplateURLs() {
@@ -604,11 +614,6 @@ void TemplateURLService::SetUserSelectedDefaultSearchProvider(
}
}
-TemplateURL* TemplateURLService::GetDefaultSearchProvider() {
- return const_cast<TemplateURL*>(
- static_cast<const TemplateURLService*>(this)->GetDefaultSearchProvider());
-}
-
const TemplateURL* TemplateURLService::GetDefaultSearchProvider() const {
return loaded_ ? default_search_provider_
: initial_default_search_provider_.get();
@@ -851,10 +856,7 @@ void TemplateURLService::OnWebDataServiceRequestDone(
base::string16 TemplateURLService::GetKeywordShortName(
const base::string16& keyword,
bool* is_omnibox_api_extension_keyword) const {
- // TODO(jeffschiller): Make GetTemplateURLForKeyword const and remove the
- // const_cast.
- const TemplateURL* template_url =
- const_cast<TemplateURLService*>(this)->GetTemplateURLForKeyword(keyword);
+ const TemplateURL* template_url = GetTemplateURLForKeyword(keyword);
// TODO(sky): Once LocationBarView adds a listener to the TemplateURLService
// to track changes to the model, this should become a DCHECK.
@@ -1264,7 +1266,7 @@ TemplateURLService::CreateTemplateURLFromTemplateURLAndSyncData(
TemplateURLServiceClient* client,
PrefService* prefs,
const SearchTermsData& search_terms_data,
- TemplateURL* existing_turl,
+ const TemplateURL* existing_turl,
const syncer::SyncData& sync_data,
syncer::SyncChangeList* change_list) {
DCHECK(change_list);
@@ -1921,7 +1923,7 @@ bool TemplateURLService::ApplyDefaultSearchChangeNoMetrics(
// mainly so we can hold ownership until we get to the point where the list
// of keywords from Web Data is the owner of everything including the
// default.
- bool changed = TemplateURL::MatchesData(
+ bool changed = !TemplateURL::MatchesData(
initial_default_search_provider_.get(), data, search_terms_data());
TemplateURL::Type initial_engine_type =
(source == DefaultSearchManager::FROM_EXTENSION)
@@ -1985,11 +1987,8 @@ bool TemplateURLService::ApplyDefaultSearchChangeNoMetrics(
// (1) Tests that initialize the TemplateURLService in peculiar ways.
// (2) If the user deleted the pre-populated default and we subsequently
// lost their user-selected value.
- std::unique_ptr<TemplateURL> new_dse_ptr =
- base::MakeUnique<TemplateURL>(*data);
- TemplateURL* new_dse = new_dse_ptr.get();
- if (AddNoNotify(std::move(new_dse_ptr), true))
- default_search_provider_ = new_dse;
+ default_search_provider_ =
+ AddNoNotify(base::MakeUnique<TemplateURL>(*data), true);
}
} else if (source == DefaultSearchManager::FROM_USER) {
default_search_provider_ = GetTemplateURLForGUID(data->sync_guid);
@@ -2002,11 +2001,8 @@ bool TemplateURLService::ApplyDefaultSearchChangeNoMetrics(
UpdateNoNotify(default_search_provider_, TemplateURL(new_data));
} else {
new_data.id = kInvalidTemplateURLID;
- std::unique_ptr<TemplateURL> new_dse_ptr =
- base::MakeUnique<TemplateURL>(new_data);
- TemplateURL* new_dse = new_dse_ptr.get();
- if (AddNoNotify(std::move(new_dse_ptr), true))
- default_search_provider_ = new_dse;
+ default_search_provider_ =
+ AddNoNotify(base::MakeUnique<TemplateURL>(new_data), true);
}
if (default_search_provider_ && prefs_) {
prefs_->SetString(prefs::kSyncedDefaultSearchProviderGUID,
@@ -2237,10 +2233,7 @@ bool TemplateURLService::IsLocalTemplateURLBetter(
const TemplateURL* local_turl,
const TemplateURL* sync_turl,
bool prefer_local_default) const {
- // TODO(jeffschiller): Make GetTemplateURLForKeyword const and remove the
- // const_cast.
- DCHECK(const_cast<TemplateURLService*>(this)->GetTemplateURLForGUID(
- local_turl->sync_guid()));
+ DCHECK(GetTemplateURLForGUID(local_turl->sync_guid()));
return local_turl->last_modified() > sync_turl->last_modified() ||
local_turl->created_by_policy() ||
(prefer_local_default && local_turl == GetDefaultSearchProvider());
@@ -2418,7 +2411,7 @@ void TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged() {
return;
}
- TemplateURL* turl = GetTemplateURLForGUID(new_guid);
+ const TemplateURL* turl = GetTemplateURLForGUID(new_guid);
if (turl)
default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data());
}
diff --git a/chromium/components/search_engines/template_url_service.h b/chromium/components/search_engines/template_url_service.h
index 4187327f06a..884c582eb70 100644
--- a/chromium/components/search_engines/template_url_service.h
+++ b/chromium/components/search_engines/template_url_service.h
@@ -167,15 +167,19 @@ class TemplateURLService : public WebDataServiceConsumer,
// The caller should not try to delete the returned pointer; the data store
// retains ownership of it.
TemplateURL* GetTemplateURLForKeyword(const base::string16& keyword);
+ const TemplateURL* GetTemplateURLForKeyword(
+ const base::string16& keyword) const;
// Returns that TemplateURL with the specified GUID, or NULL if not found.
// The caller should not try to delete the returned pointer; the data store
// retains ownership of it.
TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid);
+ const TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid) const;
// Returns the first TemplateURL found with a URL using the specified |host|,
// or NULL if there are no such TemplateURLs
TemplateURL* GetTemplateURLForHost(const std::string& host);
+ const TemplateURL* GetTemplateURLForHost(const std::string& host) const;
// Adds |template_url| to this model. Returns a raw pointer to |template_url|
// if the addition succeeded, or null on failure. (Many callers need still
@@ -189,11 +193,6 @@ class TemplateURLService : public WebDataServiceConsumer,
const base::string16& keyword,
const std::string& url);
- // Adds a search engine with the specified info for extensions.
- TemplateURL* AddExtensionControlledTURL(
- std::unique_ptr<TemplateURL> template_url,
- std::unique_ptr<TemplateURL::AssociatedExtensionInfo> info);
-
// Removes the keyword from the model. This deletes the supplied TemplateURL.
// This fails if the supplied template_url is the default search provider.
void Remove(TemplateURL* template_url);
@@ -258,10 +257,9 @@ class TemplateURLService : public WebDataServiceConsumer,
// Returns the default search provider. If the TemplateURLService hasn't been
// loaded, the default search provider is pulled from preferences.
//
- // NOTE: At least in unittest mode, this may return NULL.
- // TODO(blundell): See if all callers can be converted to take in const
- // pointers and eliminate this version of the method.
- TemplateURL* GetDefaultSearchProvider();
+ // NOTE: This may return null in certain circumstances such as:
+ // 1.) Unit test mode
+ // 2.) The default search engine is disabled by policy.
const TemplateURL* GetDefaultSearchProvider() const;
// Returns true if the |url| is a search results page from the default search
@@ -393,7 +391,7 @@ class TemplateURLService : public WebDataServiceConsumer,
TemplateURLServiceClient* client,
PrefService* prefs,
const SearchTermsData& search_terms_data,
- TemplateURL* existing_turl,
+ const TemplateURL* existing_turl,
const syncer::SyncData& sync_data,
syncer::SyncChangeList* change_list);
diff --git a/chromium/components/search_engines/template_url_unittest.cc b/chromium/components/search_engines/template_url_unittest.cc
index 31774626760..f269e0f2254 100644
--- a/chromium/components/search_engines/template_url_unittest.cc
+++ b/chromium/components/search_engines/template_url_unittest.cc
@@ -6,6 +6,7 @@
#include "base/base_paths.h"
#include "base/command_line.h"
+#include "base/i18n/case_conversion.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -22,6 +23,12 @@
using base::ASCIIToUTF16;
+namespace {
+bool IsLowerCase(const base::string16& str) {
+ return str == base::i18n::ToLower(str);
+}
+}
+
class TemplateURLTest : public testing::Test {
public:
TemplateURLTest() : search_terms_data_("http://www.google.com/") {}
@@ -771,23 +778,23 @@ TEST_F(TemplateURLTest, HostAndSearchTermKey) {
const std::string path;
const std::string search_term_key;
} test_data[] = {
- { "http://blah/?foo=bar&q={searchTerms}&b=x", "blah", "/", "q"},
- { "http://blah/{searchTerms}", "blah", "/", ""},
+ {"http://blah/?foo=bar&q={searchTerms}&b=x", "blah", "/", "q"},
+ {"http://blah/{searchTerms}", "blah", "", ""},
- // No term should result in empty values.
- { "http://blah/", "", "", ""},
+ // No term should result in empty values.
+ {"http://blah/", "", "", ""},
- // Multiple terms should result in empty values.
- { "http://blah/?q={searchTerms}&x={searchTerms}", "", "", ""},
+ // Multiple terms should result in empty values.
+ {"http://blah/?q={searchTerms}&x={searchTerms}", "", "", ""},
- // Term in the host shouldn't match.
- { "http://{searchTerms}", "", "", ""},
+ // Term in the host shouldn't match.
+ {"http://{searchTerms}", "", "", ""},
- { "http://blah/?q={searchTerms}", "blah", "/", "q"},
- { "https://blah/?q={searchTerms}", "blah", "/", "q"},
+ {"http://blah/?q={searchTerms}", "blah", "/", "q"},
+ {"https://blah/?q={searchTerms}", "blah", "/", "q"},
- // Single term with extra chars in value should match.
- { "http://blah/?q=stock:{searchTerms}", "blah", "/", "q"},
+ // Single term with extra chars in value should match.
+ {"http://blah/?q=stock:{searchTerms}", "blah", "/", "q"},
};
for (size_t i = 0; i < arraysize(test_data); ++i) {
@@ -806,28 +813,33 @@ TEST_F(TemplateURLTest, SearchTermKeyLocation) {
const std::string url;
const url::Parsed::ComponentType location;
const std::string path;
- size_t position_in_path;
+ const std::string key;
+ const std::string value_prefix;
+ const std::string value_suffix;
} test_data[] = {
- { "http://blah/{searchTerms}/", url::Parsed::PATH, "//", 1 },
- { "http://blah/{searchTerms}", url::Parsed::PATH, "/", 1 },
- { "http://blah/begin/{searchTerms}/end", url::Parsed::PATH, "/begin//end", 7 },
-
- { "http://blah/?foo=bar&q={searchTerms}&b=x", url::Parsed::QUERY,
- "/", std::string::npos },
- { "http://blah/?foo=bar#x={searchTerms}&b=x", url::Parsed::REF,
- "/", std::string::npos },
- // searchTerms is a key, not a value, so this should result in an empty
- // value.
- { "http://blah/?foo=bar#x=012345678901234&a=b&{searchTerms}=x",
- url::Parsed::QUERY, std::string(), std::string::npos },
-
- // Multiple search terms should result in empty values.
- { "http://blah/{searchTerms}?q={searchTerms}", url::Parsed::QUERY,
- "", std::string::npos },
- { "http://blah/{searchTerms}#x={searchTerms}", url::Parsed::QUERY,
- "", std::string::npos },
- { "http://blah/?q={searchTerms}#x={searchTerms}", url::Parsed::QUERY,
- "", std::string::npos },
+ {"http://blah/{searchTerms}/", url::Parsed::PATH, "", "", "/", "/"},
+ {"http://blah/{searchTerms}", url::Parsed::PATH, "", "", "/", ""},
+ {"http://blah/begin/{searchTerms}/end", url::Parsed::PATH, "", "",
+ "/begin/", "/end"},
+ {"http://blah/?foo=bar&q={searchTerms}&b=x", url::Parsed::QUERY, "/", "q",
+ "", ""},
+ {"http://blah/?foo=bar#x={searchTerms}&b=x", url::Parsed::REF, "/", "x",
+ "", ""},
+ {"http://www.example.com/?q=chromium-{searchTerms}@chromium.org/info",
+ url::Parsed::QUERY, "/", "q", "chromium-", "@chromium.org/info"},
+
+ // searchTerms is a key, not a value, so this should result in an empty
+ // value.
+ {"http://blah/?foo=bar#x=012345678901234&a=b&{searchTerms}=x",
+ url::Parsed::QUERY, "", "", "", ""},
+
+ // Multiple search terms should result in empty values.
+ {"http://blah/{searchTerms}?q={searchTerms}", url::Parsed::QUERY, "", "",
+ "", ""},
+ {"http://blah/{searchTerms}#x={searchTerms}", url::Parsed::QUERY, "", "",
+ "", ""},
+ {"http://blah/?q={searchTerms}#x={searchTerms}", url::Parsed::QUERY, "",
+ "", "", ""},
};
for (size_t i = 0; i < arraysize(test_data); ++i) {
@@ -838,8 +850,12 @@ TEST_F(TemplateURLTest, SearchTermKeyLocation) {
url.url_ref().GetSearchTermKeyLocation(search_terms_data_));
EXPECT_EQ(test_data[i].path,
url.url_ref().GetPath(search_terms_data_));
- EXPECT_EQ(test_data[i].position_in_path,
- url.url_ref().GetSearchTermPositionInPath(search_terms_data_));
+ EXPECT_EQ(test_data[i].key,
+ url.url_ref().GetSearchTermKey(search_terms_data_));
+ EXPECT_EQ(test_data[i].value_prefix,
+ url.url_ref().GetSearchTermValuePrefix(search_terms_data_));
+ EXPECT_EQ(test_data[i].value_suffix,
+ url.url_ref().GetSearchTermValueSuffix(search_terms_data_));
}
}
@@ -1742,6 +1758,13 @@ TEST_F(TemplateURLTest, GenerateKeyword) {
ASSERT_EQ(
base::UTF8ToUTF16("\xd0\xb0\xd0\xb1\xd0\xb2"),
TemplateURL::GenerateKeyword(GURL("http://xn--80acd")));
+
+ // Generated keywords must always be in lowercase, because TemplateURLs always
+ // converts keywords to lowercase in its constructor and TemplateURLService
+ // stores TemplateURLs in maps using keyword as key.
+ EXPECT_TRUE(IsLowerCase(TemplateURL::GenerateKeyword(GURL("http://BLAH/"))));
+ EXPECT_TRUE(IsLowerCase(
+ TemplateURL::GenerateKeyword(GURL("http://embeddedhtml.<head>/"))));
}
TEST_F(TemplateURLTest, GenerateSearchURL) {
diff --git a/chromium/components/search_provider_logos/logo_tracker_unittest.cc b/chromium/components/search_provider_logos/logo_tracker_unittest.cc
index 7181eca4afb..926f485feed 100644
--- a/chromium/components/search_provider_logos/logo_tracker_unittest.cc
+++ b/chromium/components/search_provider_logos/logo_tracker_unittest.cc
@@ -17,6 +17,7 @@
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
diff --git a/chromium/components/security_interstitials/DEPS b/chromium/components/security_interstitials/DEPS
index f88d8c33de1..76345d45448 100644
--- a/chromium/components/security_interstitials/DEPS
+++ b/chromium/components/security_interstitials/DEPS
@@ -6,6 +6,7 @@ include_rules = [
"+components/rappor",
"+components/ssl_errors",
"+components/strings/grit/components_strings.h",
+ "+components/grit/components_resources.h",
"+components/url_formatter",
"+net/base",
"+net/ssl",
diff --git a/chromium/components/security_interstitials/content/BUILD.gn b/chromium/components/security_interstitials/content/BUILD.gn
index d2252c2708b..d3e598ab3fe 100644
--- a/chromium/components/security_interstitials/content/BUILD.gn
+++ b/chromium/components/security_interstitials/content/BUILD.gn
@@ -20,8 +20,8 @@ static_library("security_interstitial_page") {
"//base",
"//components/prefs:prefs",
"//components/resources",
+ "//components/safe_browsing/common:safe_browsing_prefs",
"//components/safe_browsing_db:hit_report",
- "//components/safe_browsing_db:safe_browsing_prefs",
"//components/safe_browsing_db:util",
"//components/security_interstitials/core:core",
"//content/public/browser",
diff --git a/chromium/components/security_interstitials/content/DEPS b/chromium/components/security_interstitials/content/DEPS
index 5cb2f21ed51..ec5cfcdb5c5 100644
--- a/chromium/components/security_interstitials/content/DEPS
+++ b/chromium/components/security_interstitials/content/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+components/grit/components_resources.h",
"+components/prefs",
+ "+components/safe_browsing/common",
"+components/safe_browsing_db",
"+components/security_interstitials/core",
"+content/public/browser",
diff --git a/chromium/components/security_interstitials/content/security_interstitial_controller_client.cc b/chromium/components/security_interstitials/content/security_interstitial_controller_client.cc
index 150505e5f5a..87d0789a391 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_controller_client.cc
+++ b/chromium/components/security_interstitials/content/security_interstitial_controller_client.cc
@@ -7,7 +7,7 @@
#include <utility>
#include "components/prefs/pref_service.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/web_contents.h"
@@ -46,6 +46,10 @@ void SecurityInterstitialControllerClient::GoBack() {
interstitial_page_->DontProceed();
}
+bool SecurityInterstitialControllerClient::CanGoBack() {
+ return web_contents_->GetController().CanGoBack();
+}
+
void SecurityInterstitialControllerClient::GoBackAfterNavigationCommitted() {
// If the offending entry has committed, go back or to a safe page without
// closing the error page. This error page will be closed when the new page
diff --git a/chromium/components/security_interstitials/content/security_interstitial_controller_client.h b/chromium/components/security_interstitials/content/security_interstitial_controller_client.h
index 1d70720718c..f10d26b08c4 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_controller_client.h
+++ b/chromium/components/security_interstitials/content/security_interstitial_controller_client.h
@@ -40,6 +40,7 @@ class SecurityInterstitialControllerClient
// security_interstitials::ControllerClient overrides.
void GoBack() override;
+ bool CanGoBack() override;
void GoBackAfterNavigationCommitted() override;
void Proceed() override;
void Reload() override;
@@ -49,7 +50,7 @@ class SecurityInterstitialControllerClient
bool CanLaunchDateAndTimeSettings() override;
void LaunchDateAndTimeSettings() override;
-protected:
+ protected:
// security_interstitials::ControllerClient overrides.
const std::string GetExtendedReportingPrefName() const override;
content::WebContents* web_contents_;
diff --git a/chromium/components/security_interstitials/content/security_interstitial_page.cc b/chromium/components/security_interstitials/content/security_interstitial_page.cc
index f0733f0987a..db371a66c52 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_page.cc
+++ b/chromium/components/security_interstitials/content/security_interstitial_page.cc
@@ -11,10 +11,9 @@
#include "base/values.h"
#include "components/grit/components_resources.h"
#include "components/prefs/pref_service.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
+#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/security_interstitials/content/security_interstitial_controller_client.h"
#include "components/security_interstitials/core/common_string_util.h"
-#include "components/security_interstitials/core/metrics_helper.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/web_contents.h"
@@ -93,11 +92,6 @@ SecurityInterstitialControllerClient* SecurityInterstitialPage::controller() {
return controller_.get();
}
-security_interstitials::MetricsHelper*
-SecurityInterstitialPage::metrics_helper() {
- return controller_->metrics_helper();
-}
-
void SecurityInterstitialPage::UpdateMetricsAfterSecurityInterstitial() {
if (controller_->GetPrefService()) {
safe_browsing::UpdateMetricsAfterSecurityInterstitial(
@@ -111,13 +105,17 @@ base::string16 SecurityInterstitialPage::GetFormattedHostName() const {
request_url_);
}
+int SecurityInterstitialPage::GetHTMLTemplateId() {
+ return IDR_SECURITY_INTERSTITIAL_HTML;
+}
+
std::string SecurityInterstitialPage::GetHTMLContents() {
base::DictionaryValue load_time_data;
PopulateInterstitialStrings(&load_time_data);
webui::SetLoadTimeDataDefaults(
controller()->GetApplicationLocale(), &load_time_data);
std::string html = ResourceBundle::GetSharedInstance()
- .GetRawDataResource(IDR_SECURITY_INTERSTITIAL_HTML)
+ .GetRawDataResource(GetHTMLTemplateId())
.as_string();
webui::AppendWebUiCssTextDefaults(&html);
return webui::GetI18nTemplateHtml(html, &load_time_data);
diff --git a/chromium/components/security_interstitials/content/security_interstitial_page.h b/chromium/components/security_interstitials/content/security_interstitial_page.h
index 1b24add7e1c..710945cada9 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_page.h
+++ b/chromium/components/security_interstitials/content/security_interstitial_page.h
@@ -22,7 +22,6 @@ class WebContents;
}
namespace security_interstitials {
-class MetricsHelper;
class SecurityInterstitialControllerClient;
class SecurityInterstitialPage : public content::InterstitialPageDelegate {
@@ -54,6 +53,8 @@ class SecurityInterstitialPage : public content::InterstitialPageDelegate {
// interstitial_page_ will now have a value.
virtual void AfterShow() {}
+ virtual int GetHTMLTemplateId();
+
// InterstitialPageDelegate method:
std::string GetHTMLContents() override;
@@ -66,8 +67,6 @@ class SecurityInterstitialPage : public content::InterstitialPageDelegate {
SecurityInterstitialControllerClient* controller();
- MetricsHelper* metrics_helper();
-
// Update metrics when the interstitial is closed.
void UpdateMetricsAfterSecurityInterstitial();
@@ -90,8 +89,6 @@ class SecurityInterstitialPage : public content::InterstitialPageDelegate {
// For subclasses that don't have their own ControllerClients yet.
std::unique_ptr<SecurityInterstitialControllerClient> controller_;
- std::unique_ptr<MetricsHelper> metrics_helper_;
-
DISALLOW_COPY_AND_ASSIGN(SecurityInterstitialPage);
};
diff --git a/chromium/components/security_interstitials/core/BUILD.gn b/chromium/components/security_interstitials/core/BUILD.gn
index 6970a43949d..364f681b6cc 100644
--- a/chromium/components/security_interstitials/core/BUILD.gn
+++ b/chromium/components/security_interstitials/core/BUILD.gn
@@ -6,14 +6,18 @@ static_library("core") {
sources = [
"bad_clock_ui.cc",
"bad_clock_ui.h",
+ "base_safe_browsing_error_ui.cc",
+ "base_safe_browsing_error_ui.h",
"common_string_util.cc",
"common_string_util.h",
"controller_client.cc",
"controller_client.h",
"metrics_helper.cc",
"metrics_helper.h",
- "safe_browsing_error_ui.cc",
- "safe_browsing_error_ui.h",
+ "safe_browsing_loud_error_ui.cc",
+ "safe_browsing_loud_error_ui.h",
+ "safe_browsing_quiet_error_ui.cc",
+ "safe_browsing_quiet_error_ui.h",
"ssl_error_ui.cc",
"ssl_error_ui.h",
]
@@ -25,6 +29,7 @@ static_library("core") {
"//components/history/core/browser",
"//components/metrics",
"//components/prefs",
+ "//components/resources",
"//components/ssl_errors",
"//components/strings",
"//components/url_formatter",
diff --git a/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.cc b/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.cc
new file mode 100644
index 00000000000..ad7c340e53c
--- /dev/null
+++ b/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.cc
@@ -0,0 +1,55 @@
+// Copyright 2017 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/security_interstitials/core/base_safe_browsing_error_ui.h"
+
+namespace security_interstitials {
+
+BaseSafeBrowsingErrorUI::BaseSafeBrowsingErrorUI(
+ const GURL& request_url,
+ const GURL& main_frame_url,
+ BaseSafeBrowsingErrorUI::SBInterstitialReason reason,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options,
+ const std::string& app_locale,
+ const base::Time& time_triggered,
+ ControllerClient* controller)
+ : request_url_(request_url),
+ main_frame_url_(main_frame_url),
+ interstitial_reason_(reason),
+ display_options_(display_options),
+ app_locale_(app_locale),
+ time_triggered_(time_triggered),
+ controller_(controller) {}
+
+BaseSafeBrowsingErrorUI::~BaseSafeBrowsingErrorUI() {}
+
+BaseSafeBrowsingErrorUI::SBErrorDisplayOptions::SBErrorDisplayOptions(
+ bool is_main_frame_load_blocked,
+ bool is_extended_reporting_opt_in_allowed,
+ bool is_off_the_record,
+ bool is_extended_reporting_enabled,
+ bool is_scout_reporting_enabled,
+ bool is_proceed_anyway_disabled,
+ const std::string& help_center_article_link)
+ : is_main_frame_load_blocked(is_main_frame_load_blocked),
+ is_extended_reporting_opt_in_allowed(
+ is_extended_reporting_opt_in_allowed),
+ is_off_the_record(is_off_the_record),
+ is_extended_reporting_enabled(is_extended_reporting_enabled),
+ is_scout_reporting_enabled(is_scout_reporting_enabled),
+ is_proceed_anyway_disabled(is_proceed_anyway_disabled),
+ help_center_article_link(help_center_article_link) {}
+
+BaseSafeBrowsingErrorUI::SBErrorDisplayOptions::SBErrorDisplayOptions(
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& other)
+ : is_main_frame_load_blocked(other.is_main_frame_load_blocked),
+ is_extended_reporting_opt_in_allowed(
+ other.is_extended_reporting_opt_in_allowed),
+ is_off_the_record(other.is_off_the_record),
+ is_extended_reporting_enabled(other.is_extended_reporting_enabled),
+ is_scout_reporting_enabled(other.is_scout_reporting_enabled),
+ is_proceed_anyway_disabled(other.is_proceed_anyway_disabled),
+ help_center_article_link(other.help_center_article_link) {}
+
+} // security_interstitials
diff --git a/chromium/components/security_interstitials/core/safe_browsing_error_ui.h b/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h
index ed1a90584f4..1306fbdca8a 100644
--- a/chromium/components/security_interstitials/core/safe_browsing_error_ui.h
+++ b/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h
@@ -1,9 +1,9 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright 2017 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_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_ERROR_UI_H_
-#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_ERROR_UI_H_
+#ifndef COMPONENTS_SECURITY_INTERSTITIALS_CORE_BASE_SAFE_BROWSING_ERROR_UI_H_
+#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_BASE_SAFE_BROWSING_ERROR_UI_H_
#include "base/macros.h"
#include "base/time/time.h"
@@ -13,10 +13,11 @@
namespace security_interstitials {
+// A base class for quiet vs loud versions of the safe browsing interstitial.
// This class displays UI for Safe Browsing errors that block page loads. This
// class is purely about visual display; it does not do any error-handling logic
// to determine what type of error should be displayed when.
-class SafeBrowsingErrorUI {
+class BaseSafeBrowsingErrorUI {
public:
enum SBInterstitialReason {
SB_REASON_MALWARE,
@@ -31,15 +32,9 @@ class SafeBrowsingErrorUI {
bool is_extended_reporting_enabled,
bool is_scout_reporting_enabled,
bool is_proceed_anyway_disabled,
- bool is_resource_cancellable)
- : is_main_frame_load_blocked(is_main_frame_load_blocked),
- is_extended_reporting_opt_in_allowed(
- is_extended_reporting_opt_in_allowed),
- is_off_the_record(is_off_the_record),
- is_extended_reporting_enabled(is_extended_reporting_enabled),
- is_scout_reporting_enabled(is_scout_reporting_enabled),
- is_proceed_anyway_disabled(is_proceed_anyway_disabled),
- is_resource_cancellable(is_resource_cancellable) {}
+ const std::string& help_center_article_link);
+
+ SBErrorDisplayOptions(const SBErrorDisplayOptions& other);
// Indicates if this SB interstitial is blocking main frame load.
bool is_main_frame_load_blocked;
@@ -59,27 +54,20 @@ class SafeBrowsingErrorUI {
// Indicates if kSafeBrowsingProceedAnywayDisabled preference is set.
bool is_proceed_anyway_disabled;
- // Indicates if "back to safety" should cancel the pending navigation or
- // navigate back after it's committed.
- bool is_resource_cancellable;
+ // The p= query parameter used when visiting the Help Center. If this is
+ // nullptr, then a default value will be used for the SafeBrowsing article.
+ std::string help_center_article_link;
};
- SafeBrowsingErrorUI(const GURL& request_url,
- const GURL& main_frame_url,
- SBInterstitialReason reason,
- const SBErrorDisplayOptions& display_options,
- const std::string& app_locale,
- const base::Time& time_triggered,
- ControllerClient* controller);
- ~SafeBrowsingErrorUI();
-
- void PopulateStringsForHTML(base::DictionaryValue* load_time_data);
- void HandleCommand(SecurityInterstitialCommands command);
-
- // Checks if we should even show the extended reporting option. We don't show
- // it in incognito mode or if kSafeBrowsingExtendedReportingOptInAllowed
- // preference is disabled.
- bool CanShowExtendedReportingOption();
+ BaseSafeBrowsingErrorUI(
+ const GURL& request_url,
+ const GURL& main_frame_url,
+ BaseSafeBrowsingErrorUI::SBInterstitialReason reason,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options,
+ const std::string& app_locale,
+ const base::Time& time_triggered,
+ ControllerClient* controller);
+ virtual ~BaseSafeBrowsingErrorUI();
bool is_main_frame_load_blocked() const {
return display_options_.is_main_frame_load_blocked;
@@ -89,30 +77,53 @@ class SafeBrowsingErrorUI {
return display_options_.is_extended_reporting_opt_in_allowed;
}
- bool is_off_the_record() const {
- return display_options_.is_off_the_record;
- }
+ bool is_off_the_record() const { return display_options_.is_off_the_record; }
bool is_extended_reporting_enabled() const {
return display_options_.is_extended_reporting_enabled;
}
+ void set_extended_reporting(bool pref) {
+ display_options_.is_extended_reporting_enabled = pref;
+ }
+
+ bool is_scout_reporting_enabled() const {
+ return display_options_.is_scout_reporting_enabled;
+ }
+
bool is_proceed_anyway_disabled() const {
return display_options_.is_proceed_anyway_disabled;
}
- const std::string app_locale() const {
- return app_locale_;
+ const std::string& get_help_center_article_link() const {
+ return display_options_.help_center_article_link;
}
- private:
- // Fills the passed dictionary with the values to be passed to the template
- // when creating the HTML.
- void PopulateExtendedReportingOption(base::DictionaryValue* load_time_data);
- void PopulateMalwareLoadTimeData(base::DictionaryValue* load_time_data);
- void PopulateHarmfulLoadTimeData(base::DictionaryValue* load_time_data);
- void PopulatePhishingLoadTimeData(base::DictionaryValue* load_time_data);
+ // Checks if we should even show the extended reporting option. We don't show
+ // it in incognito mode or if kSafeBrowsingExtendedReportingOptInAllowed
+ // preference is disabled.
+ bool CanShowExtendedReportingOption() {
+ return !is_off_the_record() && is_extended_reporting_opt_in_allowed();
+ }
+
+ SBInterstitialReason interstitial_reason() const {
+ return interstitial_reason_;
+ }
+ const std::string app_locale() const { return app_locale_; }
+
+ ControllerClient* controller() { return controller_; };
+
+ GURL request_url() const { return request_url_; }
+ GURL main_frame_url() const { return main_frame_url_; }
+
+ virtual void PopulateStringsForHtml(
+ base::DictionaryValue* load_time_data) = 0;
+ virtual void HandleCommand(SecurityInterstitialCommands command) = 0;
+
+ virtual int GetHTMLTemplateId() const = 0;
+
+ private:
const GURL request_url_;
const GURL main_frame_url_;
const SBInterstitialReason interstitial_reason_;
@@ -122,9 +133,9 @@ class SafeBrowsingErrorUI {
ControllerClient* controller_;
- DISALLOW_COPY_AND_ASSIGN(SafeBrowsingErrorUI);
+ DISALLOW_COPY_AND_ASSIGN(BaseSafeBrowsingErrorUI);
};
} // security_interstitials
-#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_ERROR_UI_H_
+#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_BASE_SAFE_BROWSING_ERROR_UI_H_
diff --git a/chromium/components/security_interstitials/core/browser/resources/extended_reporting.js b/chromium/components/security_interstitials/core/browser/resources/extended_reporting.js
index 5a72ad12204..8acc16af783 100644
--- a/chromium/components/security_interstitials/core/browser/resources/extended_reporting.js
+++ b/chromium/components/security_interstitials/core/browser/resources/extended_reporting.js
@@ -35,13 +35,13 @@ function setupExtendedReportingCheckbox() {
if ($('whitepaper-link')) {
$('whitepaper-link').addEventListener('click', function(event) {
- sendCommand(CMD_OPEN_WHITEPAPER);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_WHITEPAPER);
});
}
$('opt-in-checkbox').addEventListener('click', function() {
sendCommand($('opt-in-checkbox').checked ?
- CMD_DO_REPORT :
- CMD_DONT_REPORT);
+ SecurityInterstitialCommandId.CMD_DO_REPORT :
+ SecurityInterstitialCommandId.CMD_DONT_REPORT);
});
}
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/blocked.svg b/chromium/components/security_interstitials/core/browser/resources/images/blocked.svg
new file mode 100644
index 00000000000..102d2b0d217
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/blocked.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="16px" viewBox="0 0 20 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g transform="translate(-2.000000, -4.000000)">
+ <g>
+ <polygon points="0 0 24 0 24 24 0 24"></polygon>
+ <path d="M20,4 C21,4 22,5 22,6 L22,18 C22,19 21,20 20,20 L4,20 C2.9,20 2,19.1 2,18 L2,6 C2,5 3,4 4,4 L20,4 Z M14.3923033,15.4598278 L15.4949742,14.3581062 L13.1207639,11.9859397 L15.5,9.60774749 L14.3973291,8.50602582 L12.0170879,10.8842181 L9.63182079,8.5 L8.52914991,9.60172166 L10.9154222,11.9859397 L8.5,14.3982783 L9.60267088,15.5 L12.0170879,13.0866571 L14.3923033,15.4598278 Z" fill-opacity="0.2" fill="#000000"></path>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_common.css b/chromium/components/security_interstitials/core/browser/resources/interstitial_common.css
new file mode 100644
index 00000000000..32a27b997ff
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_common.css
@@ -0,0 +1,35 @@
+/* Copyright 2017 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. */
+
+a {
+ color: rgb(88, 88, 88);
+}
+
+body {
+ background-color: rgb(247, 247, 247);
+ color: rgb(100, 100, 100);
+}
+
+#details-button {
+ background: inherit;
+ border: 0;
+ float: none;
+ margin: 0;
+ padding: 10px 0;
+ text-transform: uppercase;
+}
+
+.hidden {
+ display: none;
+}
+
+html {
+ -webkit-text-size-adjust: 100%;
+ font-size: 125%;
+}
+
+.icon {
+ background-repeat: no-repeat;
+ background-size: 100%;
+} \ No newline at end of file
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_common.js b/chromium/components/security_interstitials/core/browser/resources/interstitial_common.js
new file mode 100644
index 00000000000..e826a149075
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_common.js
@@ -0,0 +1,46 @@
+// Copyright 2017 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.
+
+// This is the shared code for security interstitials. It is used for both SSL
+// interstitials and Safe Browsing interstitials.
+
+// Should match security_interstitials::SecurityInterstitialCommands
+/** @enum| {string} */
+var SecurityInterstitialCommandId = {
+ CMD_DONT_PROCEED: 0,
+ CMD_PROCEED: 1,
+ // Ways for user to get more information
+ CMD_SHOW_MORE_SECTION: 2,
+ CMD_OPEN_HELP_CENTER: 3,
+ CMD_OPEN_DIAGNOSTIC: 4,
+ // Primary button actions
+ CMD_RELOAD: 5,
+ CMD_OPEN_DATE_SETTINGS: 6,
+ CMD_OPEN_LOGIN: 7,
+ // Safe Browsing Extended Reporting
+ CMD_DO_REPORT: 8,
+ CMD_DONT_REPORT: 9,
+ CMD_OPEN_REPORTING_PRIVACY: 10,
+ CMD_OPEN_WHITEPAPER: 11,
+ // Report a phishing error.
+ CMD_REPORT_PHISHING_ERROR: 12
+};
+
+/**
+ * A convenience method for sending commands to the parent page.
+ * @param {string} cmd The command to send.
+ */
+function sendCommand(cmd) {
+// <if expr="not is_ios">
+ window.domAutomationController.setAutomationId(1);
+ window.domAutomationController.send(cmd);
+// </if>
+// <if expr="is_ios">
+ // TODO(crbug.com/565877): Revisit message passing for WKWebView.
+ var iframe = document.createElement('IFRAME');
+ iframe.setAttribute('src', 'js-command:' + cmd);
+ document.documentElement.appendChild(iframe);
+ iframe.parentNode.removeChild(iframe);
+// </if>
+} \ No newline at end of file
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html b/chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html
index 852be930ad0..a759c82be28 100644
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_ui.html
@@ -1,61 +1,97 @@
<html>
<head>
<title>Interstitials</title>
+ <meta name="viewport" content="width=device-width">
+ <style>
+ body {
+ font-family: sans-serif;
+ line-height: 1.4;
+ }
+
+ h3, h4 {
+ margin-bottom: 0.5em;
+ }
+
+ ul {
+ margin-top: 0.5em;
+ }
+ </style>
</head>
<body>
<h2>Choose an interstitial</h2>
<h3>SSL</h3>
- <div>
- <a href="ssl?overridable=1&strict_enforcement=0">example.com (generic, overridable)</a>
- </div>
- <div>
- <a href="ssl?overridable=0&strict_enforcement=0">
- example.com (generic, non-overridable)
- </a>
- </div>
- <div>
- <a href="ssl?overridable=0&strict_enforcement=1">
- example.com (HSTS, non-overridable)
- </a>
- </div>
- <div>
- <a href="clock?clock_manipulation=2">Clock is ahead</a>
- </div>
- <div>
- <a href="clock?clock_manipulation=-2">Clock is behind</a>
- </div>
+ <ul>
+ <li>
+ <a href="ssl?overridable=1&strict_enforcement=0">example.com (generic, overridable)</a>
+ </li>
+ <li>
+ <a href="ssl?overridable=0&strict_enforcement=0">
+ example.com (generic, non-overridable)
+ </a>
+ </li>
+ <li>
+ <a href="ssl?overridable=0&strict_enforcement=1">
+ example.com (HSTS, non-overridable)
+ </a>
+ </li>
+ <li>
+ <a href="clock?clock_manipulation=2">Clock is ahead</a>
+ </li>
+ <li>
+ <a href="clock?clock_manipulation=-2">Clock is behind</a>
+ </li>
+ </ul>
<h3>SafeBrowsing</h3>
- <div>
- <a href="safebrowsing?type=malware">Malware</a>
- </div>
- <div>
- <a href="safebrowsing?type=phishing">Phishing</a>
- </div>
- <div>
- <a href="safebrowsing?type=clientside_malware">Client Side Malware</a>
- </div>
- <div>
- <a href="safebrowsing?type=clientside_phishing">Client Side Phishing</a>
- </div>
+ <h4>Loud</h4>
+ <ul>
+ <li>
+ <a href="safebrowsing?type=malware">Malware</a>
+ </li>
+ <li>
+ <a href="safebrowsing?type=phishing">Phishing</a>
+ </li>
+ <li>
+ <a href="safebrowsing?type=clientside_malware">Client Side Malware</a>
+ </li>
+ <li>
+ <a href="safebrowsing?type=clientside_phishing">Client Side Phishing</a>
+ </li>
+ </ul>
+ <h4>Quiet (WebView)</h4>
+ <ul>
+ <li>
+ <a href="quietsafebrowsing?type=malware">Malware</a>
+ </li>
+ <li>
+ <a href="quietsafebrowsing?type=phishing">Phishing</a>
+ </li>
+ <li>
+ <a href="quietsafebrowsing?type=giant">Giant</a>
+ </li>
+ </ul>
<h3>Captive Portal</h3>
- <div>
- <a href="captiveportal">Captive Portal, Non-WiFi</a>
- </div>
- <div>
- <a href="captiveportal?is_wifi=1">
- Captive Portal, WiFi
- </a>
- </div>
- <div>
- <a href="captiveportal?is_wifi=1&wifi_name=CoffeeShopWiFi">
- Captive Portal, WiFi with network name "CoffeeShopWiFi"
- </a>
- </div>
+ <ul>
+ <li>
+ <a href="captiveportal">Captive Portal, Non-WiFi</a>
+ </li>
+ <li>
+ <a href="captiveportal?is_wifi=1">
+ Captive Portal, WiFi
+ </a>
+ </li>
+ <li>
+ <a href="captiveportal?is_wifi=1&wifi_name=CoffeeShopWiFi">
+ Captive Portal, WiFi with network name "CoffeeShopWiFi"
+ </a>
+ </li>
+ </ul>
<h3>Supervised Users</h3>
- <div>
- <a href="supervised_user">
- Supervised User
- </a
- </div>>
+ <ul>
+ <li>
+ <a href="supervised_user">
+ Supervised User
+ </a>
+ </li>
+ </ul>
</body>
</html>
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css
index ebb5e48d58c..fdda65dff27 100644
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.css
@@ -2,21 +2,12 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. */
-a {
- color: #585858;
-}
-
.bad-clock .icon {
background-image: -webkit-image-set(
url(images/1x/clock.png) 1x,
url(images/2x/clock.png) 2x);
}
-body {
- background-color: #f7f7f7;
- color: #646464;
-}
-
body.safe-browsing {
background-color: rgb(206, 52, 38);
color: white;
@@ -74,22 +65,13 @@ button:hover {
#details {
color: #696969;
- margin: 45px 0 50px;
+ margin: 0 0 50px;
}
#details p:not(:first-of-type) {
margin-top: 20px;
}
-#details-button {
- background: inherit;
- border: 0;
- float: none;
- margin: 0;
- padding: 10px 0;
- text-transform: uppercase;
-}
-
#details-button:hover {
box-shadow: inherit;
text-decoration: underline;
@@ -97,10 +79,7 @@ button:hover {
.error-code {
color: #646464;
- display: inline;
font-size: .86667em;
- margin-top: 15px;
- opacity: 1;
text-transform: uppercase;
}
@@ -121,18 +100,7 @@ h2 {
font-weight: normal;
}
-.hidden {
- display: none;
-}
-
-html {
- -webkit-text-size-adjust: 100%;
- font-size: 125%;
-}
-
.icon {
- background-repeat: no-repeat;
- background-size: 100%;
height: 72px;
margin: 0 0 40px;
width: 72px;
@@ -331,10 +299,10 @@ input[type=checkbox]:checked ~ .checkbox::before {
* Details message replaces the top content in its own scrollable area.
*/
-@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait) {
+@media (max-width: 420px) {
#details-button {
border: 0;
- margin: 8px 0 0;
+ margin: 28px 0 0;
}
.secondary-button {
@@ -345,18 +313,17 @@ input[type=checkbox]:checked ~ .checkbox::before {
/* Fixed nav. */
@media (min-width: 240px) and (max-width: 420px) and
- (min-height: 401px) and (max-height: 736px) and (orientation:portrait),
- (min-width: 421px) and (max-width: 736px) and (min-height: 240px) and
- (max-height: 420px) and (orientation:landscape) {
+ (min-height: 401px),
+ (min-width: 421px) and (min-height: 240px) and
+ (max-height: 560px) {
body .nav-wrapper {
background: #f7f7f7;
bottom: 0;
box-shadow: 0 -22px 40px rgb(247, 247, 247);
- left: 0;
margin: 0;
max-width: 736px;
- padding-left: 24px;
- padding-right: 24px;
+ padding-left: 0px;
+ padding-right: 48px;
position: fixed;
z-index: 2;
}
@@ -374,10 +341,14 @@ input[type=checkbox]:checked ~ .checkbox::before {
#main-content {
padding-bottom: 40px;
}
+
+ #details {
+ padding-top: 5.5vh;
+ }
}
-@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait),
- (max-width: 736px) and (max-height: 420px) and (orientation: landscape) {
+@media (max-width: 420px) and (orientation: portrait),
+ (max-height: 560px) {
body {
margin: 0 auto;
}
@@ -417,6 +388,7 @@ input[type=checkbox]:checked ~ .checkbox::before {
height: 0;
opacity: 0;
overflow: hidden;
+ padding-bottom: 0;
transition: none;
}
@@ -431,12 +403,12 @@ input[type=checkbox]:checked ~ .checkbox::before {
}
.icon {
- margin-bottom: 12px;
+ margin-bottom: 5.69vh;
}
.interstitial-wrapper {
box-sizing: border-box;
- margin: 24px auto 12px;
+ margin: 7vh auto 12px;
padding: 0 24px;
position: relative;
}
@@ -463,151 +435,34 @@ input[type=checkbox]:checked ~ .checkbox::before {
}
}
-@media (min-height: 400px) and (orientation:portrait) {
+@media (min-width: 421px) and (min-height: 500px) and (max-height: 560px) {
.interstitial-wrapper {
- margin-bottom: 145px;
+ margin-top: 10vh;
}
}
-@media (min-height: 299px) and (orientation:portrait) {
- .nav-wrapper {
- padding-bottom: 16px;
- }
-}
-
-@media (min-height: 405px) and (max-height: 736px) and
- (max-width: 420px) and (orientation:portrait) {
- .icon {
- margin-bottom: 24px;
- }
-
- .interstitial-wrapper {
- margin-top: 64px;
- }
-}
-
-@media (min-height: 480px) and (max-width: 420px) and
- (max-height: 736px) and (orientation: portrait),
- (min-height: 338px) and (max-height: 420px) and (max-width: 736px) and
- (orientation: landscape) {
- .icon {
- margin-bottom: 24px;
- }
-
- .nav-wrapper {
- padding-bottom: 24px;
- }
-}
-
-@media (min-height: 500px) and (max-width: 414px) and (orientation: portrait) {
- .interstitial-wrapper {
- margin-top: 96px;
- }
-}
-
-/* Phablet sizing */
-@media (min-width: 375px) and (min-height: 641px) and (max-height: 736px) and
- (max-width: 414px) and (orientation: portrait) {
- button,
- [dir='rtl'] button,
- .small-link {
- font-size: 1em;
- padding-bottom: 12px;
- padding-top: 12px;
- }
-
- body:not(.offline) .icon {
- height: 80px;
- width: 80px;
- }
-
- #details-button {
- margin-top: 28px;
- }
-
- h1 {
- font-size: 1.7em;
- }
-
- .icon {
- margin-bottom: 28px;
- }
-
+@media (min-height: 400px) and (orientation:portrait) {
.interstitial-wrapper {
- padding: 28px;
- }
-
- .interstitial-wrapper p {
- font-size: 1.05em;
- }
-
- .nav-wrapper {
- padding: 28px;
+ margin-bottom: 145px;
}
}
-@media (min-width: 420px) and (max-width: 736px) and
- (min-height: 240px) and (max-height: 298px) and
- (orientation:landscape) {
- body:not(.offline) .icon {
- height: 50px;
- width: 50px;
- }
-
- .icon {
- padding-top: 0;
- }
-
- .interstitial-wrapper {
- margin-top: 16px;
- }
-
+@media (min-height: 299px) {
.nav-wrapper {
- padding: 0 24px 8px;
+ padding-bottom: 16px;
}
}
-@media (min-width: 420px) and (max-width: 736px) and
- (min-height: 240px) and (max-height: 420px) and
- (orientation:landscape) {
- #details-button {
- margin: 0;
- }
-
+@media (min-height: 500px) and (max-height: 650px) and (max-width: 414px) and
+ (orientation: portrait) {
.interstitial-wrapper {
- margin-bottom: 70px;
- }
-
- .nav-wrapper {
- margin-top: 0;
- }
-
- #extended-reporting-opt-in {
- margin-top: 0;
+ margin-top: 7vh;
}
}
-/* Phablet landscape */
-@media (min-width: 680px) and (max-height: 414px) {
+@media (min-height: 650px) and (max-width: 414px) and (orientation: portrait) {
.interstitial-wrapper {
- margin: 24px auto;
- }
-
- .nav-wrapper {
- margin: 16px auto 0;
- }
-}
-
-@media (max-height: 240px) and (orientation: landscape),
- (max-height: 480px) and (orientation: portrait),
- (max-width: 419px) and (max-height: 323px) {
- body:not(.offline) .icon {
- height: 56px;
- width: 56px;
- }
-
- .icon {
- margin-bottom: 16px;
+ margin-top: 10vh;
}
}
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html
index 9a3ad694433..f382689f3d3 100644
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.html
@@ -1,16 +1,18 @@
<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="initial-scale=1, minimum-scale=1, width=device-width">
<title i18n-content="tabTitle"></title>
+ <link rel="stylesheet" href="interstitial_common.css">
<link rel="stylesheet" href="interstitial_v2.css">
<script src="../../../../../ui/webui/resources/js/util.js"></script>
<script src="captive_portal.js"></script>
<script src="ssl.js"></script>
<script src="extended_reporting.js"></script>
<script src="interstitial_v2_mobile.js"></script>
+ <script src="interstitial_common.js"></script>
<script src="interstitial_v2.js"></script>
</head>
<body id="body">
@@ -18,7 +20,7 @@
<div id="main-content">
<div class="icon" id="icon"></div>
<div id="main-message">
- <h1 i18n-content="heading"></h1>
+ <h1>$i18n{heading}</h1>
<p i18n-values=".innerHTML:primaryParagraph"></p>
<div id="debugging">
<div id="error-code" class="error-code"></div>
@@ -36,9 +38,8 @@
</div>
</div>
<div class="nav-wrapper">
- <button i18n-content="primaryButtonText" id="primary-button"></button>
- <button id="details-button" class="small-link"
- i18n-content="openDetails"></button>
+ <button id="primary-button">$i18n{primaryButtonText}</button>
+ <button id="details-button" class="small-link">$i18n{openDetails}</button>
</div>
<div id="details" class="hidden">
<p i18n-values=".innerHTML:explanationParagraph"></p>
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js
index 4fa48eac865..815ba69fcae 100644
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2.js
@@ -8,43 +8,6 @@
var expandedDetails = false;
var keyPressState = 0;
-// Should match security_interstitials::SecurityInterstitialCommands
-var CMD_DONT_PROCEED = 0;
-var CMD_PROCEED = 1;
-// Ways for user to get more information
-var CMD_SHOW_MORE_SECTION = 2;
-var CMD_OPEN_HELP_CENTER = 3;
-var CMD_OPEN_DIAGNOSTIC = 4;
-// Primary button actions
-var CMD_RELOAD = 5;
-var CMD_OPEN_DATE_SETTINGS = 6;
-var CMD_OPEN_LOGIN = 7;
-// Safe Browsing Extended Reporting
-var CMD_DO_REPORT = 8;
-var CMD_DONT_REPORT = 9;
-var CMD_OPEN_REPORTING_PRIVACY = 10;
-var CMD_OPEN_WHITEPAPER = 11;
-// Report a phishing error.
-var CMD_REPORT_PHISHING_ERROR = 12;
-
-/**
- * A convenience method for sending commands to the parent page.
- * @param {string} cmd The command to send.
- */
-function sendCommand(cmd) {
-// <if expr="not is_ios">
- window.domAutomationController.setAutomationId(1);
- window.domAutomationController.send(cmd);
-// </if>
-// <if expr="is_ios">
- // TODO(crbug.com/565877): Revisit message passing for WKWebView.
- var iframe = document.createElement('IFRAME');
- iframe.setAttribute('src', 'js-command:' + cmd);
- document.documentElement.appendChild(iframe);
- iframe.parentNode.removeChild(iframe);
-// </if>
-}
-
/**
* This allows errors to be skippped by typing a secret phrase into the page.
* @param {string} e The key that was just pressed.
@@ -54,7 +17,7 @@ function handleKeypress(e) {
if (BYPASS_SEQUENCE.charCodeAt(keyPressState) == e.keyCode) {
keyPressState++;
if (keyPressState == BYPASS_SEQUENCE.length) {
- sendCommand(CMD_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_PROCEED);
keyPressState = 0;
}
} else {
@@ -102,8 +65,7 @@ function setupEvents() {
var ssl = interstitialType == 'SSL';
var captivePortal = interstitialType == 'CAPTIVE_PORTAL';
var badClock = ssl && loadTimeData.getBoolean('bad_clock');
- var hidePrimaryButton = badClock && loadTimeData.getBoolean(
- 'hide_primary_button');
+ var hidePrimaryButton = loadTimeData.getBoolean('hide_primary_button');
if (ssl) {
$('body').classList.add(badClock ? 'bad-clock' : 'ssl');
@@ -123,20 +85,20 @@ function setupEvents() {
$('primary-button').addEventListener('click', function() {
switch (interstitialType) {
case 'CAPTIVE_PORTAL':
- sendCommand(CMD_OPEN_LOGIN);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_LOGIN);
break;
case 'SSL':
if (badClock)
- sendCommand(CMD_OPEN_DATE_SETTINGS);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_DATE_SETTINGS);
else if (overridable)
- sendCommand(CMD_DONT_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_DONT_PROCEED);
else
- sendCommand(CMD_RELOAD);
+ sendCommand(SecurityInterstitialCommandId.CMD_RELOAD);
break;
case 'SAFEBROWSING':
- sendCommand(CMD_DONT_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_DONT_PROCEED);
break;
default:
@@ -148,7 +110,7 @@ function setupEvents() {
if (overridable) {
// Captive portal page isn't overridable.
$('proceed-link').addEventListener('click', function(event) {
- sendCommand(CMD_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_PROCEED);
});
} else if (!ssl) {
$('final-paragraph').classList.add('hidden');
@@ -160,13 +122,13 @@ function setupEvents() {
if ($('diagnostic-link')) {
$('diagnostic-link').addEventListener('click', function(event) {
- sendCommand(CMD_OPEN_DIAGNOSTIC);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_DIAGNOSTIC);
});
}
if ($('learn-more-link')) {
$('learn-more-link').addEventListener('click', function(event) {
- sendCommand(CMD_OPEN_HELP_CENTER);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_HELP_CENTER);
});
}
@@ -189,18 +151,15 @@ function setupEvents() {
loadTimeData.getString('closeDetails');
if (!expandedDetails) {
// Record a histogram entry only the first time that details is opened.
- sendCommand(CMD_SHOW_MORE_SECTION);
+ sendCommand(SecurityInterstitialCommandId.CMD_SHOW_MORE_SECTION);
expandedDetails = true;
}
});
}
- // TODO(felt): This should be simplified once the Finch trial is no longer
- // needed.
- if (interstitialType == 'SAFEBROWSING' &&
- loadTimeData.getBoolean('phishing') && $('report-error-link')) {
+ if ($('report-error-link')) {
$('report-error-link').addEventListener('click', function(event) {
- sendCommand(CMD_REPORT_PHISHING_ERROR);
+ sendCommand(SecurityInterstitialCommandId.CMD_REPORT_PHISHING_ERROR);
});
}
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js
index f296232387c..655d91f33be 100644
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js
@@ -12,10 +12,9 @@ function onResize() {
var helpOuterBox = document.querySelector('#details');
var mainContent = document.querySelector('#main-content');
var mediaQuery = '(min-width: 240px) and (max-width: 420px) and ' +
- '(max-height: 736px) and (min-height: 401px) and ' +
- '(orientation: portrait), (max-width: 736px) and ' +
- '(max-height: 420px) and (min-height: 240px) and ' +
- '(min-width: 421px) and (orientation: landscape)';
+ '(min-height: 401px), ' +
+ '(max-height: 560px) and (min-height: 240px) and ' +
+ '(min-width: 421px)';
var detailsHidden = helpOuterBox.classList.contains('hidden');
var runnerContainer = document.querySelector('.runner-container');
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.css b/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.css
new file mode 100644
index 00000000000..80a87648cb6
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.css
@@ -0,0 +1,112 @@
+/* Copyright 2017 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. */
+
+body {
+ margin: 0;
+}
+
+#details {
+ box-sizing: border-box;
+ height: auto;
+ line-height: 1.48em;
+ margin: 0;
+ opacity: 1;
+ transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+#details.hidden {
+ display: block;
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+ padding-bottom: 0;
+ transition: none;
+}
+
+#details-link {
+ color: rgba(0,0,0,.38);
+ /* For V1, the details link is hidden. */
+ display: none;
+ text-decoration: underline;
+ text-transform: none;
+}
+
+h1 {
+ color: rgba(0,0,0,.38);
+ font-size: 1.037037em;
+ line-height: 1.4em;
+ margin: 8px 0 8px;
+}
+
+.giant .icon {
+ bottom: 0;
+ left: 0;
+ margin: auto;
+ position: fixed;
+ right: 0;
+ top: 0;
+}
+
+.giant #details,
+.giant #main-message {
+ display: none;
+}
+
+.icon {
+ background-image: url(images/blocked.svg);
+ height: 20vh;
+ margin: 0 auto;
+ max-height: 36px;
+ max-width: 36px;
+ min-height: 18px;
+ min-width: 18px;
+ opacity: .54;
+ width: 20vh;
+}
+
+.interstitial-wrapper {
+ align-items: center;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ font-size: 0.9em;
+ height: 100vh;
+ justify-content: center;
+ line-height: 1.6em;
+ margin: 0 auto;
+ max-width: 640px;
+ padding: 16px;
+ width: 100%;
+}
+
+#main-content {
+ align-self: auto;
+ color: rgba(0, 0, 0, .54);
+ flex: 0 1 auto;
+ text-align: center;
+}
+
+@media (max-height:2em), (max-width:2em) {
+ .icon {
+ display: none;
+ }
+}
+
+@media (min-height:25em) and (min-width:37.5em),
+ (min-height:37.5em) and (min-width:25em) {
+ .icon {
+ height: 36px;
+ width: 36px;
+ }
+}
+
+/* Views that don't fit the details text. */
+@media (max-height:11.25em) and (max-width:18.75em),
+ (max-height:18.75em) and (max-width:11.25em),
+ (max-height:5em), (max-width:5em) {
+ #details,
+ #main-message {
+ display: none;
+ }
+}
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.html b/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.html
new file mode 100644
index 00000000000..63de8891ab1
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport"
+ content="initial-scale=1, minimum-scale=1, width=device-width">
+ <title>$i18n{tabTitle}</title>
+ <link rel="stylesheet" href="interstitial_common.css">
+ <link rel="stylesheet" href="interstitial_webview_quiet.css">
+ <script src="../../../../../ui/webui/resources/js/util.js"></script>
+ <script src="interstitial_webview_quiet.js"></script>
+</head>
+<body id="body">
+ <div class="interstitial-wrapper">
+ <div id="main-content">
+ <div class="icon"></div>
+ <div id="main-message">
+ <h1>
+ <span>$i18n{heading}</span>
+ <a id="details-link">$i18n{openDetails}</a>
+ </h1>
+ </div>
+ </div>
+ <div id="details" class="hidden">
+ <p>
+ $i18Raw{explanationParagraph}
+ </p>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js b/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js
new file mode 100644
index 00000000000..cb189d7128a
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js
@@ -0,0 +1,10 @@
+// Copyright 2017 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.
+
+function initPage() {
+ var isGiantWebView = loadTimeData.getBoolean('is_giant');
+ document.body.className = isGiantWebView ? 'giant' : '';
+}
+
+document.addEventListener('DOMContentLoaded', initPage);
diff --git a/chromium/components/security_interstitials/core/controller_client.h b/chromium/components/security_interstitials/core/controller_client.h
index 33d9cece494..613c6bc9f7f 100644
--- a/chromium/components/security_interstitials/core/controller_client.h
+++ b/chromium/components/security_interstitials/core/controller_client.h
@@ -71,6 +71,8 @@ class ControllerClient {
// Close the error and go back to the previous page. This applies to
// situations where navigation is blocked before committing.
virtual void GoBack() = 0;
+ // Whether it is possible to go 'Back to safety'.
+ virtual bool CanGoBack() = 0;
// If the offending entry has committed, go back or to a safe page without
// closing the error page. This error page will be closed when the new page
diff --git a/chromium/components/security_interstitials/core/safe_browsing_error_ui.cc b/chromium/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
index 38566d65e6c..12e67e3f66a 100644
--- a/chromium/components/security_interstitials/core/safe_browsing_error_ui.cc
+++ b/chromium/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
@@ -2,24 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/security_interstitials/core/safe_browsing_error_ui.h"
+#include "components/security_interstitials/core/safe_browsing_loud_error_ui.h"
#include "base/i18n/time_formatting.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "components/google/core/browser/google_util.h"
+#include "components/grit/components_resources.h"
#include "components/security_interstitials/core/common_string_util.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/strings/grit/components_strings.h"
#include "net/base/escape.h"
+#include "net/base/url_util.h"
#include "ui/base/l10n/l10n_util.h"
namespace security_interstitials {
namespace {
-// URL for the Help Center article on Safe Browsing warnings.
-const char kLearnMore[] = "https://support.google.com/chrome/answer/99020";
+// URL for the Help Center
+const char kLearnMore[] = "https://support.google.com/chrome/";
// For malware interstitial pages, we link the problematic URL to Google's
// diagnostic page.
@@ -50,7 +52,7 @@ void RecordExtendedReportingPrefChanged(bool report, bool is_scout) {
} // namespace
-SafeBrowsingErrorUI::SafeBrowsingErrorUI(
+SafeBrowsingLoudErrorUI::SafeBrowsingLoudErrorUI(
const GURL& request_url,
const GURL& main_frame_url,
SBInterstitialReason reason,
@@ -58,26 +60,26 @@ SafeBrowsingErrorUI::SafeBrowsingErrorUI(
const std::string& app_locale,
const base::Time& time_triggered,
ControllerClient* controller)
- : request_url_(request_url),
- main_frame_url_(main_frame_url),
- interstitial_reason_(reason),
- display_options_(display_options),
- app_locale_(app_locale),
- time_triggered_(time_triggered),
- controller_(controller) {
- controller_->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW);
- controller_->metrics_helper()->RecordUserInteraction(
+ : BaseSafeBrowsingErrorUI(request_url,
+ main_frame_url,
+ reason,
+ display_options,
+ app_locale,
+ time_triggered,
+ controller) {
+ controller->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW);
+ controller->metrics_helper()->RecordUserInteraction(
MetricsHelper::TOTAL_VISITS);
- if (display_options_.is_proceed_anyway_disabled)
- controller_->metrics_helper()->RecordUserDecision(
+ if (is_proceed_anyway_disabled())
+ controller->metrics_helper()->RecordUserDecision(
security_interstitials::MetricsHelper::PROCEEDING_DISABLED);
}
-SafeBrowsingErrorUI::~SafeBrowsingErrorUI() {
- controller_->metrics_helper()->RecordShutdownMetrics();
+SafeBrowsingLoudErrorUI::~SafeBrowsingLoudErrorUI() {
+ controller()->metrics_helper()->RecordShutdownMetrics();
}
-void SafeBrowsingErrorUI::PopulateStringsForHTML(
+void SafeBrowsingLoudErrorUI::PopulateStringsForHtml(
base::DictionaryValue* load_time_data) {
DCHECK(load_time_data);
@@ -93,17 +95,17 @@ void SafeBrowsingErrorUI::PopulateStringsForHTML(
load_time_data->SetString(
"primaryButtonText",
l10n_util::GetStringUTF16(IDS_SAFEBROWSING_OVERRIDABLE_SAFETY_BUTTON));
- load_time_data->SetBoolean("overridable",
- !display_options_.is_proceed_anyway_disabled);
+ load_time_data->SetBoolean("overridable", !is_proceed_anyway_disabled());
+ load_time_data->SetBoolean("hide_primary_button", !controller()->CanGoBack());
- switch (interstitial_reason_) {
- case SB_REASON_MALWARE:
+ switch (interstitial_reason()) {
+ case BaseSafeBrowsingErrorUI::SB_REASON_MALWARE:
PopulateMalwareLoadTimeData(load_time_data);
break;
- case SB_REASON_HARMFUL:
+ case BaseSafeBrowsingErrorUI::SB_REASON_HARMFUL:
PopulateHarmfulLoadTimeData(load_time_data);
break;
- case SB_REASON_PHISHING:
+ case BaseSafeBrowsingErrorUI::SB_REASON_PHISHING:
PopulatePhishingLoadTimeData(load_time_data);
break;
}
@@ -111,14 +113,15 @@ void SafeBrowsingErrorUI::PopulateStringsForHTML(
PopulateExtendedReportingOption(load_time_data);
}
-void SafeBrowsingErrorUI::HandleCommand(SecurityInterstitialCommands command) {
+void SafeBrowsingLoudErrorUI::HandleCommand(
+ SecurityInterstitialCommands command) {
switch (command) {
case CMD_PROCEED: {
// User pressed on the button to proceed.
- if (!display_options_.is_proceed_anyway_disabled) {
- controller_->metrics_helper()->RecordUserDecision(
+ if (!is_proceed_anyway_disabled()) {
+ controller()->metrics_helper()->RecordUserDecision(
MetricsHelper::PROCEED);
- controller_->Proceed();
+ controller()->Proceed();
break;
}
}
@@ -127,83 +130,83 @@ void SafeBrowsingErrorUI::HandleCommand(SecurityInterstitialCommands command) {
// User pressed on the button to return to safety.
// Don't record the user action here because there are other ways of
// triggering DontProceed, like clicking the back button.
- if (display_options_.is_resource_cancellable) {
+ if (is_main_frame_load_blocked()) {
// If the load is blocked, we want to close the interstitial and discard
// the pending entry.
- controller_->GoBack();
+ controller()->GoBack();
} else {
// Otherwise the offending entry has committed, and we need to go back
// or to a safe page. We will close the interstitial when that page
// commits.
- controller_->GoBackAfterNavigationCommitted();
+ controller()->GoBackAfterNavigationCommitted();
}
break;
}
case CMD_DO_REPORT: {
// User enabled SB Extended Reporting via the checkbox.
- display_options_.is_extended_reporting_enabled = true;
- controller_->SetReportingPreference(true);
- RecordExtendedReportingPrefChanged(
- true, display_options_.is_scout_reporting_enabled);
+ set_extended_reporting(true);
+ controller()->SetReportingPreference(true);
+ RecordExtendedReportingPrefChanged(true, is_scout_reporting_enabled());
break;
}
case CMD_DONT_REPORT: {
// User disabled SB Extended Reporting via the checkbox.
- display_options_.is_extended_reporting_enabled = false;
- controller_->SetReportingPreference(false);
- RecordExtendedReportingPrefChanged(
- false, display_options_.is_scout_reporting_enabled);
+ set_extended_reporting(false);
+ controller()->SetReportingPreference(false);
+ RecordExtendedReportingPrefChanged(false, is_scout_reporting_enabled());
break;
}
case CMD_SHOW_MORE_SECTION: {
- controller_->metrics_helper()->RecordUserInteraction(
+ controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::SHOW_ADVANCED);
break;
}
case CMD_OPEN_HELP_CENTER: {
// User pressed "Learn more".
- controller_->metrics_helper()->RecordUserInteraction(
+ controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::SHOW_LEARN_MORE);
GURL learn_more_url(kLearnMore);
+ learn_more_url = net::AppendQueryParameter(
+ learn_more_url, "p", get_help_center_article_link());
learn_more_url =
- google_util::AppendGoogleLocaleParam(learn_more_url, app_locale_);
- controller_->OpenUrlInCurrentTab(learn_more_url);
+ google_util::AppendGoogleLocaleParam(learn_more_url, app_locale());
+ controller()->OpenUrlInCurrentTab(learn_more_url);
break;
}
case CMD_RELOAD: {
- controller_->metrics_helper()->RecordUserInteraction(
+ controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::RELOAD);
- controller_->Reload();
+ controller()->Reload();
break;
}
case CMD_OPEN_REPORTING_PRIVACY: {
// User pressed on the SB Extended Reporting "privacy policy" link.
- controller_->OpenExtendedReportingPrivacyPolicy();
+ controller()->OpenExtendedReportingPrivacyPolicy();
break;
}
case CMD_OPEN_WHITEPAPER: {
- controller_->OpenExtendedReportingWhitepaper();
+ controller()->OpenExtendedReportingWhitepaper();
break;
}
case CMD_OPEN_DIAGNOSTIC: {
- controller_->metrics_helper()->RecordUserInteraction(
+ controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::SHOW_DIAGNOSTIC);
std::string diagnostic = base::StringPrintf(
kSbDiagnosticUrl,
- net::EscapeQueryParamValue(request_url_.spec(), true).c_str());
+ net::EscapeQueryParamValue(request_url().spec(), true).c_str());
GURL diagnostic_url(diagnostic);
diagnostic_url =
- google_util::AppendGoogleLocaleParam(diagnostic_url, app_locale_);
- controller_->OpenUrlInCurrentTab(diagnostic_url);
+ google_util::AppendGoogleLocaleParam(diagnostic_url, app_locale());
+ controller()->OpenUrlInCurrentTab(diagnostic_url);
break;
}
case CMD_REPORT_PHISHING_ERROR: {
- controller_->metrics_helper()->RecordUserInteraction(
+ controller()->metrics_helper()->RecordUserInteraction(
security_interstitials::MetricsHelper::REPORT_PHISHING_ERROR);
GURL phishing_error_url(kReportPhishingErrorUrl);
- phishing_error_url =
- google_util::AppendGoogleLocaleParam(phishing_error_url, app_locale_);
- controller_->OpenUrlInCurrentTab(phishing_error_url);
+ phishing_error_url = google_util::AppendGoogleLocaleParam(
+ phishing_error_url, app_locale());
+ controller()->OpenUrlInCurrentTab(phishing_error_url);
break;
}
case CMD_OPEN_DATE_SETTINGS:
@@ -215,11 +218,7 @@ void SafeBrowsingErrorUI::HandleCommand(SecurityInterstitialCommands command) {
}
}
-bool SafeBrowsingErrorUI::CanShowExtendedReportingOption() {
- return !is_off_the_record() && is_extended_reporting_opt_in_allowed();
-}
-
-void SafeBrowsingErrorUI::PopulateMalwareLoadTimeData(
+void SafeBrowsingLoudErrorUI::PopulateMalwareLoadTimeData(
base::DictionaryValue* load_time_data) {
load_time_data->SetBoolean("phishing", false);
load_time_data->SetString("heading",
@@ -228,23 +227,23 @@ void SafeBrowsingErrorUI::PopulateMalwareLoadTimeData(
"primaryParagraph",
l10n_util::GetStringFUTF16(
IDS_MALWARE_V3_PRIMARY_PARAGRAPH,
- common_string_util::GetFormattedHostName(request_url_)));
+ common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"explanationParagraph",
- display_options_.is_main_frame_load_blocked
+ is_main_frame_load_blocked()
? l10n_util::GetStringFUTF16(
IDS_MALWARE_V3_EXPLANATION_PARAGRAPH,
- common_string_util::GetFormattedHostName(request_url_))
+ common_string_util::GetFormattedHostName(request_url()))
: l10n_util::GetStringFUTF16(
IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE,
- base::UTF8ToUTF16(main_frame_url_.host()),
- common_string_util::GetFormattedHostName(request_url_)));
+ base::UTF8ToUTF16(main_frame_url().host()),
+ common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"finalParagraph",
l10n_util::GetStringUTF16(IDS_MALWARE_V3_PROCEED_PARAGRAPH));
}
-void SafeBrowsingErrorUI::PopulateHarmfulLoadTimeData(
+void SafeBrowsingLoudErrorUI::PopulateHarmfulLoadTimeData(
base::DictionaryValue* load_time_data) {
load_time_data->SetBoolean("phishing", false);
load_time_data->SetString("heading",
@@ -253,18 +252,18 @@ void SafeBrowsingErrorUI::PopulateHarmfulLoadTimeData(
"primaryParagraph",
l10n_util::GetStringFUTF16(
IDS_HARMFUL_V3_PRIMARY_PARAGRAPH,
- common_string_util::GetFormattedHostName(request_url_)));
+ common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"explanationParagraph",
l10n_util::GetStringFUTF16(
IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH,
- common_string_util::GetFormattedHostName(request_url_)));
+ common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"finalParagraph",
l10n_util::GetStringUTF16(IDS_HARMFUL_V3_PROCEED_PARAGRAPH));
}
-void SafeBrowsingErrorUI::PopulatePhishingLoadTimeData(
+void SafeBrowsingLoudErrorUI::PopulatePhishingLoadTimeData(
base::DictionaryValue* load_time_data) {
load_time_data->SetBoolean("phishing", true);
load_time_data->SetString("heading",
@@ -273,18 +272,18 @@ void SafeBrowsingErrorUI::PopulatePhishingLoadTimeData(
"primaryParagraph",
l10n_util::GetStringFUTF16(
IDS_PHISHING_V4_PRIMARY_PARAGRAPH,
- common_string_util::GetFormattedHostName(request_url_)));
+ common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"explanationParagraph",
l10n_util::GetStringFUTF16(
IDS_PHISHING_V4_EXPLANATION_PARAGRAPH,
- common_string_util::GetFormattedHostName(request_url_)));
+ common_string_util::GetFormattedHostName(request_url())));
load_time_data->SetString(
"finalParagraph",
l10n_util::GetStringUTF16(IDS_PHISHING_V4_PROCEED_AND_REPORT_PARAGRAPH));
}
-void SafeBrowsingErrorUI::PopulateExtendedReportingOption(
+void SafeBrowsingLoudErrorUI::PopulateExtendedReportingOption(
base::DictionaryValue* load_time_data) {
bool can_show_extended_reporting_option = CanShowExtendedReportingOption();
load_time_data->SetBoolean(security_interstitials::kDisplayCheckBox,
@@ -298,12 +297,16 @@ void SafeBrowsingErrorUI::PopulateExtendedReportingOption(
l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE).c_str());
load_time_data->SetString(security_interstitials::kOptInLink,
l10n_util::GetStringFUTF16(
- display_options_.is_scout_reporting_enabled
+ is_scout_reporting_enabled()
? IDS_SAFE_BROWSING_SCOUT_REPORTING_AGREE
: IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE,
base::UTF8ToUTF16(privacy_link)));
load_time_data->SetBoolean(security_interstitials::kBoxChecked,
- display_options_.is_extended_reporting_enabled);
+ is_extended_reporting_enabled());
}
+int SafeBrowsingLoudErrorUI::GetHTMLTemplateId() const {
+ return IDR_SECURITY_INTERSTITIAL_HTML;
+};
+
} // security_interstitials
diff --git a/chromium/components/security_interstitials/core/safe_browsing_loud_error_ui.h b/chromium/components/security_interstitials/core/safe_browsing_loud_error_ui.h
new file mode 100644
index 00000000000..d5a1e6a4c35
--- /dev/null
+++ b/chromium/components/security_interstitials/core/safe_browsing_loud_error_ui.h
@@ -0,0 +1,56 @@
+// Copyright 2016 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_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_LOUD_ERROR_UI_H_
+#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_LOUD_ERROR_UI_H_
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
+#include "components/security_interstitials/core/controller_client.h"
+#include "url/gurl.h"
+
+namespace security_interstitials {
+
+// Loud version of the safe browsing interstitial. This is the full screen
+// version of the interstitial used on Desktop, Android and iOS. It is
+// selectively used in parts of WebView.
+// This class displays UI for Safe Browsing errors that block page loads. This
+// class is purely about visual display; it does not do any error-handling logic
+// to determine what type of error should be displayed when.
+class SafeBrowsingLoudErrorUI
+ : public security_interstitials::BaseSafeBrowsingErrorUI {
+ public:
+ SafeBrowsingLoudErrorUI(
+ const GURL& request_url,
+ const GURL& main_frame_url,
+ BaseSafeBrowsingErrorUI::SBInterstitialReason reason,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options,
+ const std::string& app_locale,
+ const base::Time& time_triggered,
+ ControllerClient* controller);
+
+ ~SafeBrowsingLoudErrorUI() override;
+
+ // Implement BaseSafeBrowsingErrorUI.
+ void PopulateStringsForHtml(base::DictionaryValue* load_time_data) override;
+ void HandleCommand(SecurityInterstitialCommands command) override;
+
+ int GetHTMLTemplateId() const override;
+
+ private:
+ // Fills the passed dictionary with the values to be passed to the template
+ // when creating the HTML.
+ void PopulateExtendedReportingOption(base::DictionaryValue* load_time_data);
+ void PopulateMalwareLoadTimeData(base::DictionaryValue* load_time_data);
+ void PopulateHarmfulLoadTimeData(base::DictionaryValue* load_time_data);
+ void PopulatePhishingLoadTimeData(base::DictionaryValue* load_time_data);
+
+ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingLoudErrorUI);
+};
+
+} // security_interstitials
+
+#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_LOUD_ERROR_UI_H_
diff --git a/chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.cc b/chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.cc
new file mode 100644
index 00000000000..6afb802058e
--- /dev/null
+++ b/chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.cc
@@ -0,0 +1,100 @@
+// Copyright 2017 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/security_interstitials/core/safe_browsing_quiet_error_ui.h"
+
+#include "base/i18n/time_formatting.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/google/core/browser/google_util.h"
+#include "components/grit/components_resources.h"
+#include "components/security_interstitials/core/common_string_util.h"
+#include "components/security_interstitials/core/metrics_helper.h"
+#include "components/strings/grit/components_strings.h"
+#include "net/base/escape.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace security_interstitials {
+
+SafeBrowsingQuietErrorUI::SafeBrowsingQuietErrorUI(
+ const GURL& request_url,
+ const GURL& main_frame_url,
+ BaseSafeBrowsingErrorUI::SBInterstitialReason reason,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options,
+ const std::string& app_locale,
+ const base::Time& time_triggered,
+ ControllerClient* controller,
+ const bool is_giant_webview)
+ : BaseSafeBrowsingErrorUI(request_url,
+ main_frame_url,
+ reason,
+ display_options,
+ app_locale,
+ time_triggered,
+ controller),
+ is_giant_webview_(is_giant_webview) {
+ controller->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW);
+ controller->metrics_helper()->RecordUserInteraction(
+ MetricsHelper::TOTAL_VISITS);
+ if (is_proceed_anyway_disabled()) {
+ controller->metrics_helper()->RecordUserDecision(
+ security_interstitials::MetricsHelper::PROCEEDING_DISABLED);
+ }
+}
+
+SafeBrowsingQuietErrorUI::~SafeBrowsingQuietErrorUI() {
+ controller()->metrics_helper()->RecordShutdownMetrics();
+}
+
+void SafeBrowsingQuietErrorUI::PopulateStringsForHtml(
+ base::DictionaryValue* load_time_data) {
+ DCHECK(load_time_data);
+
+ load_time_data->SetString("type", "SAFEBROWSING");
+ load_time_data->SetString(
+ "tabTitle", l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_TITLE));
+ load_time_data->SetBoolean("overridable", !is_proceed_anyway_disabled());
+ load_time_data->SetString(
+ "openDetails",
+ l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_OPEN_DETAILS_BUTTON));
+ load_time_data->SetBoolean("is_giant", is_giant_webview_);
+
+ bool phishing =
+ interstitial_reason() == BaseSafeBrowsingErrorUI::SB_REASON_PHISHING;
+ load_time_data->SetBoolean("phishing", phishing);
+ load_time_data->SetString(
+ "heading", phishing
+ ? l10n_util::GetStringUTF16(IDS_PHISHING_WEBVIEW_HEADING)
+ : l10n_util::GetStringUTF16(IDS_MALWARE_WEBVIEW_HEADING));
+
+ int explanation_ids = -1;
+ if (phishing)
+ explanation_ids = IDS_PHISHING_WEBVIEW_EXPLANATION_PARAGRAPH;
+ else if (interstitial_reason() == BaseSafeBrowsingErrorUI::SB_REASON_MALWARE)
+ explanation_ids = IDS_MALWARE_WEBVIEW_EXPLANATION_PARAGRAPH;
+
+ if (explanation_ids > -1) {
+ load_time_data->SetString("explanationParagraph",
+ l10n_util::GetStringUTF16(explanation_ids));
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SafeBrowsingQuietErrorUI::SetGiantWebViewForTesting(
+ bool is_giant_webview) {
+ is_giant_webview_ = is_giant_webview;
+}
+
+void SafeBrowsingQuietErrorUI::HandleCommand(
+ SecurityInterstitialCommands command) {
+ NOTREACHED();
+}
+
+int SafeBrowsingQuietErrorUI::GetHTMLTemplateId() const {
+ return IDR_SECURITY_INTERSTITIAL_QUIET_HTML;
+};
+
+} // security_interstitials
diff --git a/chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.h b/chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.h
new file mode 100644
index 00000000000..cf57ab90fb3
--- /dev/null
+++ b/chromium/components/security_interstitials/core/safe_browsing_quiet_error_ui.h
@@ -0,0 +1,57 @@
+// Copyright 2016 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_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_QUIET_ERROR_UI_H_
+#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_QUIET_ERROR_UI_H_
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
+#include "components/security_interstitials/core/controller_client.h"
+#include "url/gurl.h"
+
+namespace security_interstitials {
+
+// Quiet version of the safe browsing interstitial. This is the small screen
+// version of the interstitial selectively used in parts of WebView.
+// This class displays a quiet UI for Safe Browsing errors that block page loads
+// specifically for WebView. This class is purely about visual display; it does
+// not do any error-handling logic to determine what type of error should be
+// displayed when.
+class SafeBrowsingQuietErrorUI
+ : public security_interstitials::BaseSafeBrowsingErrorUI {
+ public:
+ SafeBrowsingQuietErrorUI(
+ const GURL& request_url,
+ const GURL& main_frame_url,
+ BaseSafeBrowsingErrorUI::SBInterstitialReason reason,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options,
+ const std::string& app_locale,
+ const base::Time& time_triggered,
+ ControllerClient* controller,
+ const bool is_giant_webview);
+ ~SafeBrowsingQuietErrorUI() override;
+
+ // Fills the passed dictionary with the values to be passed to the template
+ // when creating the HTML.
+ void PopulateStringsForHtml(base::DictionaryValue* load_time_data) override;
+
+ void HandleCommand(SecurityInterstitialCommands command) override;
+
+ // Manually set whether displaying in a giant WebView. Specifially used in
+ // tests.
+ void SetGiantWebViewForTesting(bool is_giant_webview);
+
+ int GetHTMLTemplateId() const override;
+
+ private:
+ bool is_giant_webview_;
+
+ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingQuietErrorUI);
+};
+
+} // security_interstitials
+
+#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_QUIET_ERROR_UI_H_
diff --git a/chromium/components/security_interstitials/core/ssl_error_ui.cc b/chromium/components/security_interstitials/core/ssl_error_ui.cc
index e438bc601e2..1cde12396de 100644
--- a/chromium/components/security_interstitials/core/ssl_error_ui.cc
+++ b/chromium/components/security_interstitials/core/ssl_error_ui.cc
@@ -69,6 +69,7 @@ void SSLErrorUI::PopulateStringsForHTML(base::DictionaryValue* load_time_data) {
// Shared values for both the overridable and non-overridable versions.
load_time_data->SetBoolean("bad_clock", false);
+ load_time_data->SetBoolean("hide_primary_button", false);
load_time_data->SetString("tabTitle",
l10n_util::GetStringUTF16(IDS_SSL_V2_TITLE));
load_time_data->SetString("heading",
@@ -95,6 +96,7 @@ void SSLErrorUI::PopulateOverridableStrings(
ssl_info_.cert.get(), request_url_);
load_time_data->SetBoolean("overridable", true);
+ load_time_data->SetBoolean("hide_primary_button", false);
load_time_data->SetString("explanationParagraph", error_info.details());
load_time_data->SetString(
"primaryButtonText",
@@ -113,6 +115,7 @@ void SSLErrorUI::PopulateNonOverridableStrings(
ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error_);
load_time_data->SetBoolean("overridable", false);
+ load_time_data->SetBoolean("hide_primary_button", false);
load_time_data->SetString(
"explanationParagraph",
l10n_util::GetStringFUTF16(IDS_SSL_NONOVERRIDABLE_MORE, url));
diff --git a/chromium/components/security_interstitials_strings.grdp b/chromium/components/security_interstitials_strings.grdp
index 780a4e6b766..abe7d06f4a6 100644
--- a/chromium/components/security_interstitials_strings.grdp
+++ b/chromium/components/security_interstitials_strings.grdp
@@ -23,19 +23,19 @@
</message>
<if expr="not is_android and not is_ios">
<message name="IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH" desc="Main paragraph of an error message. Context: error shown when the browser can't load a page because the computer's clock is wrong.">
- A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your computer's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect.
+ A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your computer's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
</if>
<if expr="is_android">
<message name="IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH" desc="Main paragraph of an error message. Context: error shown when the browser can't load a page because the Android device's clock is wrong.">
- A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your device's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect.
+ A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your device's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
</if>
<if expr="is_ios">
<message name="IDS_CLOCK_ERROR_PRIMARY_PARAGRAPH" desc="Main paragraph of an error message. Context: error shown when the browser can't load a page because the device's clock is wrong. This paragraph explains the situation and gives instructions to fix it on iOS.">
&lt;p&gt;A private connection to <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="DOMAIN">$1<ex>paypal.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> can't be established because your device's date and time (<ph name="DATE_AND_TIME">$2<ex>Monday, January 1, 1970 2:44:30 PM</ex></ph>) are incorrect.&lt;/p&gt;
- &lt;p&gt;Please adjust the date and time from the &lt;strong&gt;General&lt;/strong&gt; section of the &lt;strong&gt;Settings&lt;/strong&gt; app.&lt;/p&gt;
+ &lt;p&gt;Please adjust the date and time from the &lt;strong&gt;General&lt;/strong&gt; section of the &lt;strong&gt;Settings&lt;/strong&gt; app.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
</if>
<if expr="_google_chrome">
@@ -65,7 +65,7 @@
Your connection is not private
</message>
<message name="IDS_SSL_V2_PRIMARY_PARAGRAPH" desc="The primary explanatory paragraph for the SSL interstitial.">
- Attackers might be trying to steal your information from <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>google.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> (for example, passwords, messages, or credit cards).
+ Attackers might be trying to steal your information from <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>google.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> (for example, passwords, messages, or credit cards). <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
<!-- SSL error page: overridable -->
@@ -81,20 +81,20 @@
Reload
</message>
<message name="IDS_SSL_NONOVERRIDABLE_PINNED" desc="A sentence to explain why the user can't proceed, plus a link to a help page about certificate pinning.">
- You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website uses certificate pinning. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website uses certificate pinning. Network errors and attacks are usually temporary, so this page will probably work later.
</message>
<message name="IDS_SSL_NONOVERRIDABLE_HSTS" desc="A sentence to explain why the user can't proceed, plus a link to a help page about HSTS.">
- You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website uses HSTS. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website uses HSTS. Network errors and attacks are usually temporary, so this page will probably work later.
</message>
<message name="IDS_SSL_NONOVERRIDABLE_REVOKED" desc="A sentence to explain why the user can't proceed, plus a link to a help page about certificate revocation.">
- You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because its certificate has been revoked. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because its certificate has been revoked. Network errors and attacks are usually temporary, so this page will probably work later.
</message>
<if expr="_google_chrome">
<message name="IDS_SSL_NONOVERRIDABLE_MORE" desc="Body text for the explanation shown if user clicks on the Details button.">
<ph name="SITE">$1<ex>google.com</ex></ph> normally uses encryption to protect your information. When Google Chrome tried to connect to <ph name="SITE">$1<ex>google.com</ex></ph> this time, the website sent back unusual and incorrect credentials. This may happen when an attacker is trying to pretend to be <ph name="SITE">$1<ex>google.com</ex></ph>, or a Wi-Fi sign-in screen has interrupted the connection. Your information is still secure because Google Chrome stopped the connection before any data was exchanged.
</message>
<message name="IDS_SSL_NONOVERRIDABLE_INVALID" desc="A sentence to explain why the user can't proceed.">
- You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website sent scrambled credentials that Google Chrome cannot process. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website sent scrambled credentials that Google Chrome cannot process. Network errors and attacks are usually temporary, so this page will probably work later.
</message>
</if>
<if expr="not _google_chrome">
@@ -102,7 +102,7 @@
<ph name="SITE">$1<ex>google.com</ex></ph> normally uses encryption to protect your information. When Chromium tried to connect to <ph name="SITE">$1<ex>google.com</ex></ph> this time, the website sent back unusual and incorrect credentials. This may happen when an attacker is trying to pretend to be <ph name="SITE">$1<ex>google.com</ex></ph>, or a Wi-Fi sign-in screen has interrupted the connection. Your information is still secure because Chromium stopped the connection before any data was exchanged.
</message>
<message name="IDS_SSL_NONOVERRIDABLE_INVALID" desc="A sentence to explain why the user can't proceed.">
- You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website sent scrambled credentials that Chromium cannot process. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You cannot visit <ph name="SITE">$1<ex>google.com</ex></ph> right now because the website sent scrambled credentials that Chromium cannot process. Network errors and attacks are usually temporary, so this page will probably work later.
</message>
</if>
@@ -120,30 +120,38 @@
Back to safety
</message>
- <!-- Malware interstitial V3 -->
- <message name="IDS_MALWARE_V3_HEADING" desc="The large heading at the top of the malware interstitial.">
- The site ahead contains malware
- </message>
+ <!-- Malware interstitial -->
+ <if expr="is_android">
+ <message name="IDS_MALWARE_V3_HEADING" desc="The large heading at the top of the malware interstitial.">
+ The site ahead contains dangerous apps
+ </message>
+ </if>
+ <if expr="not is_android">
+ <message name="IDS_MALWARE_V3_HEADING" desc="The large heading at the top of the malware interstitial.">
+ The site ahead contains malware
+ </message>
+ </if>
+
<if expr="is_android">
<message name="IDS_MALWARE_V3_PRIMARY_PARAGRAPH" desc="Mobile: The primary explanatory paragraph for the malware interstitial.">
- Attackers currently on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> might attempt to install dangerous apps on your device that steal or delete your information (for example, photos, passwords, messages, and credit cards).
+ Attackers currently on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> could install dangerous apps that damage your device, add hidden charges to your mobile bill, or steal your personal information. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
</if>
<if expr="is_macosx">
<message name="IDS_MALWARE_V3_PRIMARY_PARAGRAPH" desc="Mac: The primary explanatory paragraph for the malware interstitial.">
- Attackers currently on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> might attempt to install dangerous programs on your Mac that steal or delete your information (for example, photos, passwords, messages, and credit cards).
+ Attackers currently on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> might attempt to install dangerous programs on your Mac that steal or delete your information (for example, photos, passwords, messages, and credit cards). <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
</if>
<if expr="not is_android and not is_macosx">
<message name="IDS_MALWARE_V3_PRIMARY_PARAGRAPH" desc="The primary explanatory paragraph for the malware interstitial.">
- Attackers currently on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> might attempt to install dangerous programs on your computer that steal or delete your information (for example, photos, passwords, messages, and credit cards).
+ Attackers currently on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> might attempt to install dangerous programs on your computer that steal or delete your information (for example, photos, passwords, messages, and credit cards). <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
</if>
<message name="IDS_MALWARE_V3_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page.">
- Google Safe Browsing recently <ph name="BEGIN_LINK">&lt;a href="#" id="diagnostic-link"&gt;</ph>detected malware<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="SITE">$1<ex>example.com</ex></ph>. Websites that are normally safe are sometimes infected with malware. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ Google Safe Browsing recently <ph name="BEGIN_LINK">&lt;a href="#" id="diagnostic-link"&gt;</ph>detected malware<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="SITE">$1<ex>example.com</ex></ph>. Websites that are normally safe are sometimes infected with malware.
</message>
<message name="IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE" desc="The explanation of why Safe Browsing has blocked the page.">
- Google Safe Browsing recently <ph name="BEGIN_LINK">&lt;a href="#" id="diagnostic-link"&gt;</ph>detected malware<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="SITE">$1<ex>example.com</ex></ph>. Websites that are normally safe are sometimes infected with malware. The malicious content comes from <ph name="SUBRESOURCE_HOST">$2<ex>evil.com</ex></ph>, a known malware distributor. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ Google Safe Browsing recently <ph name="BEGIN_LINK">&lt;a href="#" id="diagnostic-link"&gt;</ph>detected malware<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="SITE">$1<ex>example.com</ex></ph>. Websites that are normally safe are sometimes infected with malware. The malicious content comes from <ph name="SUBRESOURCE_HOST">$2<ex>evil.com</ex></ph>, a known malware distributor.
</message>
<message name="IDS_MALWARE_V3_PROCEED_PARAGRAPH" desc="The paragraph that lets the user skip the warning.">
If you understand the risks to your security, you may <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>visit this unsafe site<ph name="END_LINK">&lt;/a&gt;</ph> before the dangerous programs have been removed.
@@ -158,32 +166,68 @@
Automatically send some <ph name="BEGIN_WHITEPAPER_LINK">&lt;a href="#" id="whitepaper-link"&gt;</ph>system information and page content<ph name="END_WHITEPAPER_LINK">&lt;/a&gt;</ph> to Google to help detect dangerous apps and sites. <ph name="PRIVACY_PAGE_LINK">$1</ph>
</message>
- <!-- Harmful download interstitial V3 -->
- <message name="IDS_HARMFUL_V3_HEADING" desc="The large heading at the top of the social engineering interstitial.">
- The site ahead contains harmful programs
- </message>
- <message name="IDS_HARMFUL_V3_PRIMARY_PARAGRAPH" desc="Mobile: The primary explanatory paragraph for the social engineering interstitial.">
- Attackers on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> might attempt to trick you into installing programs that harm your browsing experience (for example, by changing your homepage or showing extra ads on sites you visit).
- </message>
- <message name="IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page.">
- Google Safe Browsing recently <ph name="BEGIN_LINK">&lt;a href="#" id="diagnostic-link"&gt;</ph>found harmful programs<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="SITE">$1<ex>example.com</ex></ph>. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
- </message>
- <message name="IDS_HARMFUL_V3_PROCEED_PARAGRAPH" desc="The paragraph that lets the user skip the warning.">
- If you understand the risks to your security, you may <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>visit this site<ph name="END_LINK">&lt;/a&gt;</ph> before the harmful programs have been removed.
- </message>
+ <!-- Harmful download interstitial -->
+ <if expr="is_android">
+ <message name="IDS_HARMFUL_V3_HEADING" desc="The large heading at the top of the unwanted software interstitial.">
+ The site ahead contains harmful apps
+ </message>
+
+ <message name="IDS_HARMFUL_V3_PRIMARY_PARAGRAPH" desc="The primary explanatory paragraph for the unwanted software interstitial.">
+ Attackers on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> could install deceptive apps that pretend to be something else or collect data that may be used to track you. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
+ </message>
+
+ <message name="IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page.">
+ Google Safe Browsing recently <ph name="BEGIN_LINK">&lt;a href="#" id="diagnostic-link"&gt;</ph>found harmful apps<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="SITE">$1<ex>example.com</ex></ph>.
+ </message>
+
+ <message name="IDS_HARMFUL_V3_PROCEED_PARAGRAPH" desc="The paragraph that lets the user skip the warning.">
+ If you understand the risks to your security, you may <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>visit this site<ph name="END_LINK">&lt;/a&gt;</ph> before the harmful apps have been removed.
+ </message>
+ </if>
+ <if expr="not is_android">
+ <message name="IDS_HARMFUL_V3_HEADING" desc="The large heading at the top of the unwanted software interstitial.">
+ The site ahead contains harmful programs
+ </message>
+
+ <message name="IDS_HARMFUL_V3_PRIMARY_PARAGRAPH" desc="The primary explanatory paragraph for the unwanted software interstitial.">
+ Attackers on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> might attempt to trick you into installing programs that harm your browsing experience (for example, by changing your homepage or showing extra ads on sites you visit). <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
+ </message>
+
+ <message name="IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page.">
+ Google Safe Browsing recently <ph name="BEGIN_LINK">&lt;a href="#" id="diagnostic-link"&gt;</ph>found harmful programs<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="SITE">$1<ex>example.com</ex></ph>.
+ </message>
+
+ <message name="IDS_HARMFUL_V3_PROCEED_PARAGRAPH" desc="The paragraph that lets the user skip the warning.">
+ If you understand the risks to your security, you may <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>visit this site<ph name="END_LINK">&lt;/a&gt;</ph> before the harmful programs have been removed.
+ </message>
+ </if>
<!-- Phishing interstitial -->
<message name="IDS_PHISHING_V4_HEADING" desc="The large heading at the top of the phishing interstitial.">
Deceptive site ahead
</message>
<message name="IDS_PHISHING_V4_PRIMARY_PARAGRAPH" desc="The primary explanatory paragraph for the malware interstitial.">
- Attackers on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> may trick you into doing something dangerous like installing software or revealing your personal information (for example, passwords, phone numbers, or credit cards).
+ Attackers on <ph name="BEGIN_BOLD">&lt;strong&gt;</ph><ph name="SITE">$1<ex>example.com</ex></ph><ph name="END_BOLD">&lt;/strong&gt;</ph> may trick you into doing something dangerous like installing software or revealing your personal information (for example, passwords, phone numbers, or credit cards). <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>
</message>
<message name="IDS_PHISHING_V4_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page.">
- Google Safe Browsing recently detected phishing on <ph name="SITE">$1<ex>example.com</ex></ph>. Phishing sites pretend to be other websites to trick you. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ Google Safe Browsing recently detected phishing on <ph name="SITE">$1<ex>example.com</ex></ph>. Phishing sites pretend to be other websites to trick you.
</message>
<message name="IDS_PHISHING_V4_PROCEED_AND_REPORT_PARAGRAPH" desc="The paragraph that lets the user skip the warning.">
You can <ph name="BEGIN_ERROR_LINK">&lt;a href="#" id="report-error-link"&gt;</ph>report a detection problem<ph name="END_ERROR_LINK">&lt;/a&gt;</ph> or, if you understand the risks to your security, <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>visit this unsafe site<ph name="END_LINK">&lt;/a&gt;</ph>.
</message>
+ <!-- WebView Safe Browsing quiet interstitals medium sized -->
+ <message name="IDS_MALWARE_WEBVIEW_HEADING" desc="The heading of the malware interstitial on medium sized Webview.">
+ Dangerous content blocked
+ </message>
+ <message name="IDS_MALWARE_WEBVIEW_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page. Allows the user to proceed using a link.">
+ This content might try to install dangerous software on your device that steals or deletes your information. <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>Show anyway<ph name="END_LINK">&lt;/a&gt;</ph>.
+ </message>
+ <message name="IDS_PHISHING_WEBVIEW_HEADING" desc="The heading of the phishing interstitial on medium sized Webview.">
+ Deceptive content blocked
+ </message>
+ <message name="IDS_PHISHING_WEBVIEW_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page. Allows the user to proceed using a link.">
+ This content might try to trick you into installing software or revealing personal information. <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>Show anyway<ph name="END_LINK">&lt;/a&gt;</ph>.
+ </message>
+
</grit-part>
diff --git a/chromium/components/security_state/content/content_utils.cc b/chromium/components/security_state/content/content_utils.cc
index 0464d59e4a1..27986e01d39 100644
--- a/chromium/components/security_state/content/content_utils.cc
+++ b/chromium/components/security_state/content/content_utils.cc
@@ -154,10 +154,6 @@ std::unique_ptr<security_state::VisibleSecurityState> GetVisibleSecurityState(
state->key_exchange_group = ssl.key_exchange_group;
state->security_bits = ssl.security_bits;
state->pkp_bypassed = ssl.pkp_bypassed;
- state->sct_verify_statuses.clear();
- state->sct_verify_statuses.insert(state->sct_verify_statuses.begin(),
- ssl.sct_statuses.begin(),
- ssl.sct_statuses.end());
state->displayed_mixed_content =
!!(ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT);
state->ran_mixed_content =
@@ -310,8 +306,9 @@ blink::WebSecurityStyle GetSecurityStyle(
if (security_info.pkp_bypassed) {
security_style_explanations->info_explanations.push_back(
content::SecurityStyleExplanation(
- "Public-Key Pinning Bypassed",
- "Public-key pinning was bypassed by a local root certificate."));
+ l10n_util::GetStringUTF8(IDS_PRIVATE_KEY_PINNING_BYPASSED),
+ l10n_util::GetStringUTF8(
+ IDS_PRIVATE_KEY_PINNING_BYPASSED_DESCRIPTION)));
}
return security_style;
diff --git a/chromium/components/security_state/content/content_utils_unittest.cc b/chromium/components/security_state/content/content_utils_unittest.cc
index a9b5bbdcced..e0e37e0a45f 100644
--- a/chromium/components/security_state/content/content_utils_unittest.cc
+++ b/chromium/components/security_state/content/content_utils_unittest.cc
@@ -181,7 +181,7 @@ TEST(SecurityStateContentUtilsTest, ConnectionExplanation) {
GetSecurityStyle(security_info, &explanations);
content::SecurityStyleExplanation explanation;
ASSERT_TRUE(FindSecurityStyleExplanation(
- explanations.secure_explanations, "Secure Connection", &explanation));
+ explanations.secure_explanations, "Secure connection", &explanation));
EXPECT_EQ(
"The connection to this site is encrypted and authenticated using a "
"strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with "
@@ -197,7 +197,7 @@ TEST(SecurityStateContentUtilsTest, ConnectionExplanation) {
GetSecurityStyle(security_info, &explanations);
content::SecurityStyleExplanation explanation;
ASSERT_TRUE(FindSecurityStyleExplanation(
- explanations.secure_explanations, "Secure Connection", &explanation));
+ explanations.secure_explanations, "Secure connection", &explanation));
EXPECT_EQ(
"The connection to this site is encrypted and authenticated using a "
"strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA), and a "
@@ -216,7 +216,7 @@ TEST(SecurityStateContentUtilsTest, ConnectionExplanation) {
GetSecurityStyle(security_info, &explanations);
content::SecurityStyleExplanation explanation;
ASSERT_TRUE(FindSecurityStyleExplanation(
- explanations.secure_explanations, "Secure Connection", &explanation));
+ explanations.secure_explanations, "Secure connection", &explanation));
EXPECT_EQ(
"The connection to this site is encrypted and authenticated using a "
"strong protocol (TLS 1.3), a strong key exchange (X25519), and a "
diff --git a/chromium/components/security_state/core/security_state.cc b/chromium/components/security_state/core/security_state.cc
index 0843ff8e567..aed4e42d2bf 100644
--- a/chromium/components/security_state/core/security_state.cc
+++ b/chromium/components/security_state/core/security_state.cc
@@ -213,8 +213,6 @@ void SecurityInfoForRequest(
security_info->obsolete_ssl_status =
net::ObsoleteSSLStatus(security_info->connection_status);
security_info->pkp_bypassed = visible_security_state.pkp_bypassed;
- security_info->sct_verify_statuses =
- visible_security_state.sct_verify_statuses;
security_info->malicious_content_status =
visible_security_state.malicious_content_status;
@@ -304,7 +302,6 @@ bool VisibleSecurityState::operator==(const VisibleSecurityState& other) const {
connection_status == other.connection_status &&
key_exchange_group == other.key_exchange_group &&
security_bits == other.security_bits &&
- sct_verify_statuses == other.sct_verify_statuses &&
displayed_mixed_content == other.displayed_mixed_content &&
ran_mixed_content == other.ran_mixed_content &&
displayed_content_with_cert_errors ==
diff --git a/chromium/components/security_state/core/security_state.h b/chromium/components/security_state/core/security_state.h
index aa5e8d48c1c..4d1ec3f90ce 100644
--- a/chromium/components/security_state/core/security_state.h
+++ b/chromium/components/security_state/core/security_state.h
@@ -110,9 +110,6 @@ struct SecurityInfo {
// content that was loaded over an HTTPS connection with
// certificate errors.
ContentStatus content_with_cert_errors_status;
- // The verification statuses of the signed certificate timestamps
- // for the connection.
- std::vector<net::ct::SCTVerifyStatus> sct_verify_statuses;
bool scheme_is_cryptographic;
net::CertStatus cert_status;
scoped_refptr<net::X509Certificate> certificate;
@@ -168,9 +165,6 @@ struct VisibleSecurityState {
// unknown (older cache entries may not store the value) or not applicable.
uint16_t key_exchange_group;
int security_bits;
- // The verification statuses of the Signed Certificate
- // Timestamps (if any) that the server provided.
- std::vector<net::ct::SCTVerifyStatus> sct_verify_statuses;
// True if the page displayed passive mixed content.
bool displayed_mixed_content;
// True if the secure page contained a form with a nonsecure target.
diff --git a/chromium/components/security_state_strings.grdp b/chromium/components/security_state_strings.grdp
index d3580a9af31..1982f9112ba 100644
--- a/chromium/components/security_state_strings.grdp
+++ b/chromium/components/security_state_strings.grdp
@@ -2,43 +2,52 @@
<grit-part>
<!-- Strings describing Chrome security policy for DevTools security panel -->
<message name="IDS_PRIVATE_USER_DATA_INPUT" desc="Summary phrase for a security problem where the site collects private user data on an insecure page." translateable="false">
- Private User Data Input
+ Private user data input
+ </message>
+ <message name="IDS_PRIVATE_USER_DATA_INPUT_DESCRIPTION" desc="Description of a security problem where the site collects private user data on an insecure page, which results in an omnibox warning." translateable="false">
+ This page includes a password or credit card input over HTTP. A warning has been added to the URL bar.
</message>
<message name="IDS_SAFEBROWSING_WARNING" desc="Summary phrase for a security problem where the site is deemed unsafe by the SafeBrowsing service." translateable="false">
This page is dangerous (flagged by Google Safe Browsing).
</message>
<message name="IDS_SHA1" desc="Summary phrase for a security problem where the site's certificate chain contains a SHA1 signature." translateable="false">
- SHA-1 Certificate
+ SHA-1 certificate
</message>
<message name="IDS_SHA1_DESCRIPTION" desc="Description of a security problem where the site's certificate chain contains a SHA1 signature." translateable="false">
The certificate chain for this site contains a certificate signed using SHA-1.
</message>
<message name="IDS_SUBJECT_ALT_NAME_MISSING" desc="Summary phrase for a security problem where the site's certificate is missing a subjectAltName extension." translateable="false">
- Subject Alternative Name Missing
+ Subject Alternative Name missing
</message>
<message name="IDS_SUBJECT_ALT_NAME_MISSING_DESCRIPTION" desc="Description of a security problem where the site's certificate is missing a subjectAltName extension." translateable="false">
The certificate for this site does not contain a Subject Alternative Name extension containing a domain name or IP address.
</message>
<message name="IDS_CERTIFICATE_CHAIN_ERROR" desc="Summary phrase for a security problem with the site's certificate." translateable="false">
- Certificate Error
+ Certificate error
</message>
<message name="IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT" desc="Description of a security problem with the site's certificate." translateable="false">
There are issues with the site's certificate chain (<ph name="CERT_ERROR_DESCRIPTION">$1<ex>net::ERR_CERT_AUTHORITY_INVALID</ex></ph>).
</message>
<message name="IDS_VALID_SERVER_CERTIFICATE" desc="Summary phrase for a site that has a valid server certificate." translateable="false">
- Valid Certificate
+ Valid certificate
</message>
<message name="IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION" desc="Description of a site that has a valid server certificate." translateable="false">
The connection to this site is using a valid, trusted server certificate.
</message>
<message name="IDS_STRONG_SSL_SUMMARY" desc="Summary phrase for a site that uses a modern, secure TLS protocol and cipher." translateable="false">
- Secure Connection
+ Secure connection
+ </message>
+ <message name="IDS_PRIVATE_KEY_PINNING_BYPASSED" desc="Summary phrase for a security state where Private Key Pinning is ignored because the certificate chains to a locally-trusted root." translateable="false">
+ Public-Key-Pinning bypassed
+ </message>
+ <message name="IDS_PRIVATE_KEY_PINNING_BYPASSED_DESCRIPTION" desc="Description of a security state where Private Key Pinning is ignored because the certificate chains to a locally-trusted root." translateable="false">
+ Public-Key-Pinning was bypassed by a local root certificate.
</message>
<message name="IDS_STRONG_SSL_DESCRIPTION" desc="Description of a site that uses a modern, secure TLS protocol and cipher." translateable="false">
The connection to this site is encrypted and authenticated using a strong protocol (<ph name="PROTOCOL_VERSION">$1<ex>TLS 1.2</ex></ph>), a strong key exchange (<ph name="KEY_EXCHANGE">$2<ex>ECDHE_RSA</ex></ph>), and a strong cipher (<ph name="CIPHER_SUTE">$3<ex>AES_128_GCM</ex></ph>).
</message>
<message name="IDS_OBSOLETE_SSL_SUMMARY" desc="Summary phrase for a site that uses an outdated SSL settings (protocol, key exchange, or cipher)." translateable="false">
- Obsolete Connection Settings
+ Obsolete connection settings
</message>
<message name="IDS_OBSOLETE_SSL_DESCRIPTION" desc="Description of a site that uses an outdated TLS protocol or cipher." translateable="false">
The connection to this site uses <ph name="A_PROTOCOL">$1<ex>an obsolete protocol</ex></ph> (<ph name="PROTOCOL">$2<ex>TLS 1.0</ex></ph>), <ph name="A_KEY_EXCHANGE">$3<ex>an obsolete key exchange</ex></ph> (<ph name="KEY_EXCHANGE">$4<ex>ECDHE_RSA</ex></ph>), and <ph name="A_CIPHER">$5<ex>an obsolete cipher</ex></ph> (<ph name="CIPHER">$6<ex>AES_256_CBC with HMAC-SHA1</ex></ph>).
diff --git a/chromium/components/sessions/content/content_live_tab.cc b/chromium/components/sessions/content/content_live_tab.cc
index 3f1ef66e042..3e970b7387e 100644
--- a/chromium/components/sessions/content/content_live_tab.cc
+++ b/chromium/components/sessions/content/content_live_tab.cc
@@ -18,7 +18,7 @@ ContentLiveTab* ContentLiveTab::GetForWebContents(
content::WebContents* contents) {
if (!contents->GetUserData(kContentLiveTabWebContentsUserDataKey)) {
contents->SetUserData(kContentLiveTabWebContentsUserDataKey,
- new ContentLiveTab(contents));
+ base::WrapUnique(new ContentLiveTab(contents)));
}
return static_cast<ContentLiveTab*>(contents->GetUserData(
diff --git a/chromium/components/sessions/ios/ios_live_tab.mm b/chromium/components/sessions/ios/ios_live_tab.mm
index 584b5238dfc..0d0b1c90d39 100644
--- a/chromium/components/sessions/ios/ios_live_tab.mm
+++ b/chromium/components/sessions/ios/ios_live_tab.mm
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/sessions/ios/ios_live_tab.h"
+#include "base/memory/ptr_util.h"
#include "ios/web/public/navigation_manager.h"
namespace {
@@ -17,7 +18,7 @@ std::string IOSLiveTab::user_agent_override_;
IOSLiveTab* IOSLiveTab::GetForWebState(web::WebState* web_state) {
if (!web_state->GetUserData(kIOSLiveTabWebStateUserDataKey)) {
web_state->SetUserData(kIOSLiveTabWebStateUserDataKey,
- new IOSLiveTab(web_state));
+ base::WrapUnique(new IOSLiveTab(web_state)));
}
return static_cast<IOSLiveTab*>(
diff --git a/chromium/components/signin/core/browser/account_tracker_service_unittest.cc b/chromium/components/signin/core/browser/account_tracker_service_unittest.cc
index 9fae742506b..284cefb23bb 100644
--- a/chromium/components/signin/core/browser/account_tracker_service_unittest.cc
+++ b/chromium/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -15,6 +15,7 @@
#include "components/signin/core/browser/account_fetcher_service.h"
#include "components/signin/core/browser/account_info.h"
#include "components/signin/core/browser/account_tracker_service.h"
+#include "components/signin/core/browser/child_account_info_fetcher.h"
#include "components/signin/core/browser/fake_account_fetcher_service.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/signin/core/common/signin_pref_names.h"
@@ -255,6 +256,8 @@ class AccountTrackerServiceTest : public testing::Test {
~AccountTrackerServiceTest() override {}
void SetUp() override {
+ ChildAccountInfoFetcher::InitializeForTests();
+
fake_oauth2_token_service_.reset(new FakeOAuth2TokenService());
pref_service_.registry()->RegisterListPref(
diff --git a/chromium/components/signin/core/browser/android/BUILD.gn b/chromium/components/signin/core/browser/android/BUILD.gn
index 20aac14c374..f9f482b6a91 100644
--- a/chromium/components/signin/core/browser/android/BUILD.gn
+++ b/chromium/components/signin/core/browser/android/BUILD.gn
@@ -54,7 +54,7 @@ android_library("signin_java_test_support") {
java_files = [
"javatests/src/org/chromium/components/signin/test/util/AccountHolder.java",
- "javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java",
+ "javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java",
"javatests/src/org/chromium/components/signin/test/util/SimpleFuture.java",
]
}
diff --git a/chromium/components/signin/core/browser/child_account_info_fetcher.cc b/chromium/components/signin/core/browser/child_account_info_fetcher.cc
index 15bc0538f6e..804444b35d6 100644
--- a/chromium/components/signin/core/browser/child_account_info_fetcher.cc
+++ b/chromium/components/signin/core/browser/child_account_info_fetcher.cc
@@ -31,3 +31,9 @@ std::unique_ptr<ChildAccountInfoFetcher> ChildAccountInfoFetcher::CreateFrom(
ChildAccountInfoFetcher::~ChildAccountInfoFetcher() {
}
+
+void ChildAccountInfoFetcher::InitializeForTests() {
+#if defined(OS_ANDROID)
+ ChildAccountInfoFetcherAndroid::InitializeForTests();
+#endif
+}
diff --git a/chromium/components/signin/core/browser/child_account_info_fetcher.h b/chromium/components/signin/core/browser/child_account_info_fetcher.h
index 1c35c48d332..0b3623d6d31 100644
--- a/chromium/components/signin/core/browser/child_account_info_fetcher.h
+++ b/chromium/components/signin/core/browser/child_account_info_fetcher.h
@@ -34,6 +34,8 @@ class ChildAccountInfoFetcher {
net::URLRequestContextGetter* request_context_getter,
invalidation::InvalidationService* invalidation_service);
virtual ~ChildAccountInfoFetcher();
+
+ static void InitializeForTests();
};
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_CHILD_ACCOUNT_INFO_FETCHER_H_
diff --git a/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc b/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc
index 654a8154e3e..34446dad77e 100644
--- a/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc
+++ b/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc
@@ -29,6 +29,11 @@ std::unique_ptr<ChildAccountInfoFetcher> ChildAccountInfoFetcherAndroid::Create(
new ChildAccountInfoFetcherAndroid(service, account_id, account_name));
}
+void ChildAccountInfoFetcherAndroid::InitializeForTests() {
+ Java_ChildAccountInfoFetcher_initializeForTests(
+ base::android::AttachCurrentThread());
+}
+
ChildAccountInfoFetcherAndroid::ChildAccountInfoFetcherAndroid(
AccountFetcherService* service,
const std::string& account_id,
diff --git a/chromium/components/signin/core/browser/child_account_info_fetcher_android.h b/chromium/components/signin/core/browser/child_account_info_fetcher_android.h
index cb06fedbc05..05f30a177fc 100644
--- a/chromium/components/signin/core/browser/child_account_info_fetcher_android.h
+++ b/chromium/components/signin/core/browser/child_account_info_fetcher_android.h
@@ -20,6 +20,8 @@ class ChildAccountInfoFetcherAndroid : public ChildAccountInfoFetcher {
AccountFetcherService* service,
const std::string& account_id);
+ static void InitializeForTests();
+
// Register JNI methods.
static bool Register(JNIEnv* env);
diff --git a/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc b/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc
index a3aa65fe8ee..0e664641579 100644
--- a/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc
+++ b/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -10,6 +10,7 @@
#include "base/format_macros.h"
#include "base/json/json_reader.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
@@ -25,6 +26,7 @@
#include "google_apis/gaia/oauth2_token_service.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
@@ -213,8 +215,35 @@ void GaiaCookieManagerService::ExternalCcResultFetcher::
std::unique_ptr<net::URLFetcher>
GaiaCookieManagerService::ExternalCcResultFetcher::CreateFetcher(
const GURL& url) {
- std::unique_ptr<net::URLFetcher> fetcher =
- net::URLFetcher::Create(0, url, net::URLFetcher::GET, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation(
+ "gaia_cookie_manager_external_cc_result", R"(
+ semantics {
+ sender: "Gaia Cookie Manager"
+ description:
+ "This request is used by the GaiaCookieManager when adding an "
+ "account to the Google authentication cookies to check the "
+ "authentication server's connection state."
+ trigger:
+ "This is used at most once per lifetime of the application "
+ "during the first merge session flow (the flow used to add an "
+ "account for which Chrome has a valid OAuth2 refresh token to "
+ "the Gaia authentication cookies). The value of the first fetch "
+ "is stored in RAM for future uses."
+ data: "None."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting: "This feature cannot be disabled in settings."
+ policy_exception_justification:
+ "Not implemented. Disabling GaiaCookieManager would break "
+ "features that depend on it (like account consistency and "
+ "support for child accounts). It makes sense to control top "
+ "level features that use the GaiaCookieManager."
+ })");
+ std::unique_ptr<net::URLFetcher> fetcher = net::URLFetcher::Create(
+ 0, url, net::URLFetcher::GET, this, traffic_annotation);
fetcher->SetRequestContext(helper_->request_context());
fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES);
@@ -402,10 +431,11 @@ void GaiaCookieManagerService::TriggerListAccounts(const std::string& source) {
void GaiaCookieManagerService::ForceOnCookieChangedProcessing() {
GURL google_url = GaiaUrls::GetInstance()->google_url();
- std::unique_ptr<net::CanonicalCookie> cookie(net::CanonicalCookie::Create(
- google_url, kGaiaCookieName, std::string(), "." + google_url.host(),
- std::string(), base::Time(), base::Time(), false, false,
- net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
+ std::unique_ptr<net::CanonicalCookie> cookie(
+ base::MakeUnique<net::CanonicalCookie>(
+ kGaiaCookieName, std::string(), "." + google_url.host(), "/",
+ base::Time(), base::Time(), base::Time(), false, false,
+ net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
OnCookieChanged(*cookie, net::CookieStore::ChangeCause::UNKNOWN_DELETION);
}
diff --git a/chromium/components/signin/core/browser/signin_cookie_changed_subscription.cc b/chromium/components/signin/core/browser/signin_cookie_changed_subscription.cc
index 3f432525937..f32bd19b083 100644
--- a/chromium/components/signin/core/browser/signin_cookie_changed_subscription.cc
+++ b/chromium/components/signin/core/browser/signin_cookie_changed_subscription.cc
@@ -4,6 +4,7 @@
#include "components/signin/core/browser/signin_cookie_changed_subscription.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/cookies/cookie_store.h"
#include "net/url_request/url_request_context.h"
diff --git a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
index 1c67727627d..5141e3d3f0b 100644
--- a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
@@ -8,7 +8,7 @@
#include "base/message_loop/message_loop.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/signin/core/browser/signin_header_helper.h"
-#include "components/signin/core/common/signin_switches.h"
+#include "components/signin/core/common/profile_management_switches.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
@@ -22,7 +22,8 @@ class SigninHeaderHelperTest : public testing::Test {
HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry());
settings_map_ = new HostContentSettingsMap(
- &prefs_, false /* incognito_profile */, false /* guest_profile */);
+ &prefs_, false /* incognito_profile */, false /* guest_profile */,
+ false /* store_last_modified */);
cookie_settings_ =
new content_settings::CookieSettings(settings_map_.get(), &prefs_, "");
}
@@ -70,8 +71,8 @@ class SigninHeaderHelperTest : public testing::Test {
// Tests that no Mirror request is returned when the user is not signed in (no
// account id).
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "", "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "", "");
}
@@ -79,8 +80,8 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
// Tests that no Mirror request is returned when the cookies aren't allowed to
// be set.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "0123456789", "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "0123456789", "");
@@ -88,8 +89,8 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
// Tests that no Mirror request is returned when the target is a non-Google URL.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestExternalURL) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://foo.com"), "0123456789", "");
CheckMirrorCookieRequest(GURL("https://foo.com"), "0123456789", "");
}
@@ -97,8 +98,8 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestExternalURL) {
// Tests that the Mirror request is returned without the GAIA Id when the target
// is a google TLD domain.
TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleTLD) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://google.fr"), "0123456789",
"mode=0,enable_account_consistency=true");
CheckMirrorCookieRequest(GURL("https://google.de"), "0123456789",
@@ -108,8 +109,8 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleTLD) {
// Tests that the Mirror request is returned when the target is the domain
// google.com, and that the GAIA Id is only attached for the cookie.
TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleCom) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://www.google.com"), "0123456789",
"mode=0,enable_account_consistency=true");
CheckMirrorCookieRequest(
@@ -124,8 +125,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleCom) {
// only relevant on Desktop.
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) {
- DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableAccountConsistency));
+ DCHECK(!switches::IsEnableAccountConsistency());
CheckMirrorHeaderRequest(
GURL("https://docs.google.com/document"), "0123456789",
"id=0123456789,mode=0,enable_account_consistency=false");
@@ -134,8 +134,8 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) {
"id=0123456789:mode=0:enable_account_consistency=false");
// Enable Account Consistency will override the disable.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(
GURL("https://docs.google.com/document"), "0123456789",
"id=0123456789,mode=0,enable_account_consistency=true");
@@ -148,9 +148,8 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) {
// Tests that the Mirror header request is returned normally when the redirect
// URL is eligible.
TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
-
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
const GURL url("https://docs.google.com/document");
const GURL redirect_url("https://www.google.com");
const std::string account_id = "0123456789";
@@ -167,9 +166,8 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) {
// Tests that the Mirror header request is stripped when the redirect URL is not
// eligible.
TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
-
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
const GURL url("https://docs.google.com/document");
const GURL redirect_url("http://www.foo.com");
const std::string account_id = "0123456789";
@@ -186,9 +184,8 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) {
// Tests that the Mirror header, whatever its value is, is untouched when both
// the current and the redirect URL are non-eligible.
TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableAccountConsistency);
-
+ switches::EnableAccountConsistencyForTesting(
+ base::CommandLine::ForCurrentProcess());
const GURL url("https://www.bar.com");
const GURL redirect_url("http://www.foo.com");
const std::string account_id = "0123456789";
diff --git a/chromium/components/signin/core/browser/signin_manager.cc b/chromium/components/signin/core/browser/signin_manager.cc
index d27931d6a30..9e588dc9879 100644
--- a/chromium/components/signin/core/browser/signin_manager.cc
+++ b/chromium/components/signin/core/browser/signin_manager.cc
@@ -291,7 +291,7 @@ bool SigninManager::IsUsernameAllowedByPolicy(const std::string& username,
// See if the username matches the policy-provided pattern.
UErrorCode status = U_ZERO_ERROR;
- const icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
+ const icu::UnicodeString icu_pattern(FALSE, pattern.data(), pattern.length());
icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status);
if (!U_SUCCESS(status)) {
LOG(ERROR) << "Invalid login regex: " << pattern << ", status: " << status;
@@ -299,8 +299,8 @@ bool SigninManager::IsUsernameAllowedByPolicy(const std::string& username,
// break signin than to quietly allow users to sign in).
return false;
}
- base::string16 username16 = base::UTF8ToUTF16(username);
- icu::UnicodeString icu_input(username16.data(), username16.length());
+ // The default encoding is UTF-8 in Chromium's ICU.
+ icu::UnicodeString icu_input(username.data());
matcher.reset(icu_input);
status = U_ZERO_ERROR;
UBool match = matcher.matches(status);
diff --git a/chromium/components/signin/core/browser/signin_metrics.cc b/chromium/components/signin/core/browser/signin_metrics.cc
index 8010b84ac51..d754cf87a30 100644
--- a/chromium/components/signin/core/browser/signin_metrics.cc
+++ b/chromium/components/signin/core/browser/signin_metrics.cc
@@ -23,15 +23,71 @@ DifferentPrimaryAccounts ComparePrimaryAccounts(bool primary_accounts_same,
}
void LogSigninAccessPointStarted(AccessPoint access_point) {
+ LogSigninAccessPointStarted(
+ access_point, signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO);
+}
+
+void LogSigninAccessPointCompleted(AccessPoint access_point) {
+ LogSigninAccessPointCompleted(
+ access_point, signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO);
+}
+
+void LogSigninAccessPointStarted(AccessPoint access_point,
+ PromoAction promo_action) {
UMA_HISTOGRAM_ENUMERATION("Signin.SigninStartedAccessPoint",
static_cast<int>(access_point),
static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ switch (promo_action) {
+ case PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO:
+ break;
+ case PromoAction::PROMO_ACTION_WITH_DEFAULT:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Signin.SigninStartedAccessPoint.WithDefault",
+ static_cast<int>(access_point),
+ static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ break;
+ case PromoAction::PROMO_ACTION_NOT_DEFAULT:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Signin.SigninStartedAccessPoint.NotDefault",
+ static_cast<int>(access_point),
+ static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ break;
+ case PromoAction::PROMO_ACTION_NEW_ACCOUNT:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Signin.SigninStartedAccessPoint.NewAccount",
+ static_cast<int>(access_point),
+ static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ break;
+ }
}
-void LogSigninAccessPointCompleted(AccessPoint access_point) {
+void LogSigninAccessPointCompleted(AccessPoint access_point,
+ PromoAction promo_action) {
UMA_HISTOGRAM_ENUMERATION("Signin.SigninCompletedAccessPoint",
static_cast<int>(access_point),
static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ switch (promo_action) {
+ case PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO:
+ break;
+ case PromoAction::PROMO_ACTION_WITH_DEFAULT:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Signin.SigninCompletedAccessPoint.WithDefault",
+ static_cast<int>(access_point),
+ static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ break;
+ case PromoAction::PROMO_ACTION_NOT_DEFAULT:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Signin.SigninCompletedAccessPoint.NotDefault",
+ static_cast<int>(access_point),
+ static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ break;
+ case PromoAction::PROMO_ACTION_NEW_ACCOUNT:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Signin.SigninCompletedAccessPoint.NewAccount",
+ static_cast<int>(access_point),
+ static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
+ break;
+ }
}
void LogSigninReason(Reason reason) {
diff --git a/chromium/components/signin/core/browser/signin_metrics.h b/chromium/components/signin/core/browser/signin_metrics.h
index 061a4145ba4..177ed1fae62 100644
--- a/chromium/components/signin/core/browser/signin_metrics.h
+++ b/chromium/components/signin/core/browser/signin_metrics.h
@@ -146,6 +146,14 @@ enum class AccessPoint : int {
ACCESS_POINT_MAX, // This must be last.
};
+// Enum values which enumerates all user actions on the mobile sign-in promo.
+enum class PromoAction : int {
+ PROMO_ACTION_NO_SIGNIN_PROMO = 0,
+ PROMO_ACTION_WITH_DEFAULT,
+ PROMO_ACTION_NOT_DEFAULT,
+ PROMO_ACTION_NEW_ACCOUNT,
+};
+
// Enum values which enumerates all reasons to start sign in process.
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.signin
@@ -285,10 +293,16 @@ enum class AccountRelation : int {
// Different types of reporting. This is used as a histogram suffix.
enum class ReportingType { PERIODIC, ON_CHANGE };
-// Tracks the access point of sign in.
+// Tracks the access point of sign in on desktop.
void LogSigninAccessPointStarted(AccessPoint access_point);
void LogSigninAccessPointCompleted(AccessPoint access_point);
+// Tracks the access point of sign in on iOS.
+void LogSigninAccessPointStarted(AccessPoint access_point,
+ PromoAction promo_action);
+void LogSigninAccessPointCompleted(AccessPoint access_point,
+ PromoAction promo_action);
+
// Tracks the reason of sign in.
void LogSigninReason(Reason reason);
diff --git a/chromium/components/signin/core/common/profile_management_switches.cc b/chromium/components/signin/core/common/profile_management_switches.cc
index 733ea083103..4b14f6c0331 100644
--- a/chromium/components/signin/core/common/profile_management_switches.cc
+++ b/chromium/components/signin/core/common/profile_management_switches.cc
@@ -18,10 +18,10 @@ bool IsEnableAccountConsistency() {
#if defined(OS_ANDROID) || defined(OS_IOS)
// Account consistency is enabled on Android and iOS.
return true;
-#endif
-
+#else
return base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableAccountConsistency);
+#endif // defined(OS_ANDROID) || defined(OS_IOS)
}
bool IsExtensionsMultiAccount() {
@@ -36,13 +36,10 @@ bool IsExtensionsMultiAccount() {
IsEnableAccountConsistency();
}
-bool UsePasswordSeparatedSigninFlow() {
- return base::FeatureList::IsEnabled(
- switches::kUsePasswordSeparatedSigninFlow);
-}
-
void EnableAccountConsistencyForTesting(base::CommandLine* command_line) {
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
command_line->AppendSwitch(switches::kEnableAccountConsistency);
+#endif
}
} // namespace switches
diff --git a/chromium/components/signin/core/common/profile_management_switches.h b/chromium/components/signin/core/common/profile_management_switches.h
index 7ed543d0967..b3080e961d0 100644
--- a/chromium/components/signin/core/common/profile_management_switches.h
+++ b/chromium/components/signin/core/common/profile_management_switches.h
@@ -22,9 +22,6 @@ bool IsEnableAccountConsistency();
// Whether the chrome.identity API should be multi-account.
bool IsExtensionsMultiAccount();
-// Checks whether the new gaia password separated sign in flow is enabled.
-bool UsePasswordSeparatedSigninFlow();
-
// Called in tests to force enable account consistency.
void EnableAccountConsistencyForTesting(base::CommandLine* command_line);
diff --git a/chromium/components/signin/core/common/signin_switches.cc b/chromium/components/signin/core/common/signin_switches.cc
index f31bc2c7010..ef1d865c333 100644
--- a/chromium/components/signin/core/common/signin_switches.cc
+++ b/chromium/components/signin/core/common/signin_switches.cc
@@ -16,8 +16,10 @@ const char kDisableSigninPromo[] = "disable-signin-promo";
// Disables sending signin scoped device id to LSO with refresh token request.
const char kDisableSigninScopedDeviceId[] = "disable-signin-scoped-device-id";
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
// Enables consistent identity features.
const char kEnableAccountConsistency[] = "enable-account-consistency";
+#endif
// Enables sending EnableRefreshTokenAnnotationRequest.
extern const char kEnableRefreshTokenAnnotationRequest[] =
@@ -29,10 +31,4 @@ const char kEnableSigninPromo[] = "enable-signin-promo";
// Enables multiple account versions of chrome.identity APIs.
const char kExtensionsMultiAccount[] = "extensions-multi-account";
-// Enables or disables the new password separated sign in flow in a tab modal
-// dialog.
-const base::Feature kUsePasswordSeparatedSigninFlow {
- "UsePasswordSeparatedSigninFlow", base::FEATURE_ENABLED_BY_DEFAULT
-};
-
} // namespace switches
diff --git a/chromium/components/signin/core/common/signin_switches.h b/chromium/components/signin/core/common/signin_switches.h
index c2dd7384193..8c0ecc2db9b 100644
--- a/chromium/components/signin/core/common/signin_switches.h
+++ b/chromium/components/signin/core/common/signin_switches.h
@@ -18,12 +18,15 @@ namespace switches {
extern const char kClearTokenService[];
extern const char kDisableSigninPromo[];
extern const char kDisableSigninScopedDeviceId[];
-extern const char kEnableAccountConsistency[];
extern const char kEnableRefreshTokenAnnotationRequest[];
extern const char kEnableSigninPromo[];
extern const char kExtensionsMultiAccount[];
-extern const base::Feature kUsePasswordSeparatedSigninFlow;
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+// Note: Account consistency is already enabled on mobile platforms, so this
+// switch only exist on desktop platforms.
+extern const char kEnableAccountConsistency[];
+#endif
} // namespace switches
diff --git a/chromium/components/signin/ios/browser/BUILD.gn b/chromium/components/signin/ios/browser/BUILD.gn
index 9a736cc272a..b914497f1d0 100644
--- a/chromium/components/signin/ios/browser/BUILD.gn
+++ b/chromium/components/signin/ios/browser/BUILD.gn
@@ -33,6 +33,7 @@ source_set("browser") {
}
source_set("test_support") {
+ configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"fake_profile_oauth2_token_service_ios_provider.h",
diff --git a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
index ba160b6bf69..4dcfccf52ca 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -133,7 +133,8 @@ class AccountConsistencyServiceTest : public PlatformTest {
signin_client_.get(), nullptr, &account_tracker_service_, nullptr));
account_tracker_service_.Initialize(signin_client_.get());
settings_map_ = new HostContentSettingsMap(
- &prefs_, false /* incognito_profile */, false /* guest_profile */);
+ &prefs_, false /* incognito_profile */, false /* guest_profile */,
+ false /* store_last_modified */);
cookie_settings_ =
new content_settings::CookieSettings(settings_map_.get(), &prefs_, "");
ResetAccountConsistencyService();
diff --git a/chromium/components/signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.mm b/chromium/components/signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.mm
index 50cb0f853b0..cffec890989 100644
--- a/chromium/components/signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.mm
+++ b/chromium/components/signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.mm
@@ -9,6 +9,10 @@
#include "base/logging.h"
#include "base/strings/sys_string_conversions.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
FakeProfileOAuth2TokenServiceIOSProvider::
FakeProfileOAuth2TokenServiceIOSProvider() {
}
@@ -63,9 +67,9 @@ void FakeProfileOAuth2TokenServiceIOSProvider::
for (auto i = requests_.begin(); i != requests_.end(); ++i) {
std::string account_id = i->first;
AccessTokenCallback callback = i->second;
- NSError* error = [[[NSError alloc] initWithDomain:@"fake_access_token_error"
- code:-1
- userInfo:nil] autorelease];
+ NSError* error = [[NSError alloc] initWithDomain:@"fake_access_token_error"
+ code:-1
+ userInfo:nil];
callback.Run(nil, nil, error);
}
requests_.clear();
diff --git a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm
index d70d591f1cc..a4043b3f022 100644
--- a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm
+++ b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm
@@ -5,6 +5,7 @@
#include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
diff --git a/chromium/components/spellcheck/BUILD.gn b/chromium/components/spellcheck/BUILD.gn
index d8d629a98b7..a7d28cb485a 100644
--- a/chromium/components/spellcheck/BUILD.gn
+++ b/chromium/components/spellcheck/BUILD.gn
@@ -13,5 +13,6 @@ buildflag_header("build_features") {
flags = [
"ENABLE_SPELLCHECK=$enable_spellcheck",
"USE_BROWSER_SPELLCHECKER=$use_browser_spellchecker",
+ "HAS_SPELLCHECK_PANEL=$has_spellcheck_panel",
]
}
diff --git a/chromium/components/spellcheck/common/BUILD.gn b/chromium/components/spellcheck/common/BUILD.gn
index 69d4d0cbf28..4806ceef916 100644
--- a/chromium/components/spellcheck/common/BUILD.gn
+++ b/chromium/components/spellcheck/common/BUILD.gn
@@ -2,9 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//mojo/public/tools/bindings/mojom.gni")
+
source_set("common") {
sources = [
- "spellcheck_bdict_language.h",
"spellcheck_common.cc",
"spellcheck_common.h",
"spellcheck_features.cc",
@@ -18,11 +19,23 @@ source_set("common") {
]
public_deps = [
+ ":interfaces",
"//components/spellcheck:build_features",
]
+
deps = [
"//base:i18n",
"//ipc",
"//third_party/icu",
]
}
+
+mojom("interfaces") {
+ sources = [
+ "spellcheck.mojom",
+ ]
+
+ public_deps = [
+ "//mojo/common:common_custom_types",
+ ]
+}
diff --git a/chromium/components/spellcheck/common/OWNERS b/chromium/components/spellcheck/common/OWNERS
index 42444bcd16d..ef88cc78b08 100644
--- a/chromium/components/spellcheck/common/OWNERS
+++ b/chromium/components/spellcheck/common/OWNERS
@@ -1,2 +1,4 @@
per-file *_messages*.h=set noparent
per-file *_messages*.h=file://ipc/SECURITY_OWNERS
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/spellcheck/common/spellcheck.mojom b/chromium/components/spellcheck/common/spellcheck.mojom
new file mode 100644
index 00000000000..91952616731
--- /dev/null
+++ b/chromium/components/spellcheck/common/spellcheck.mojom
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+module spellcheck.mojom;
+
+import "mojo/common/file.mojom";
+
+// Render process interface exposed to the browser for receiving process-
+// wide spellcheck control and updates from the browser process.
+//
+interface SpellChecker {
+ // Initialize the render process spellchecker. Called after startup and
+ // also in response to a render process RequestDictionary request.
+ Initialize(array<SpellCheckBDictLanguage> dictionaries,
+ array<string> custom_words,
+ bool enable);
+
+ // Custom dictionary words have been added or removed: update the local
+ // custom word list.
+ CustomDictionaryChanged(array<string> words_added,
+ array<string> words_removed);
+};
+
+struct SpellCheckBDictLanguage {
+ mojo.common.mojom.File? file;
+ string language;
+};
diff --git a/chromium/components/spellcheck/common/spellcheck_bdict_language.h b/chromium/components/spellcheck/common/spellcheck_bdict_language.h
deleted file mode 100644
index 95022944076..00000000000
--- a/chromium/components/spellcheck/common/spellcheck_bdict_language.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 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_SPELLCHECK_COMMON_SPELLCHECK_BDICT_LANGUAGE_H_
-#define COMPONENTS_SPELLCHECK_COMMON_SPELLCHECK_BDICT_LANGUAGE_H_
-
-#include <string>
-
-#include "ipc/ipc_platform_file.h"
-
-struct SpellCheckBDictLanguage {
- IPC::PlatformFileForTransit file;
- std::string language;
-};
-
-#endif // COMPONENTS_SPELLCHECK_COMMON_SPELLCHECK_BDICT_LANGUAGE_H_
diff --git a/chromium/components/spellcheck/common/spellcheck_messages.h b/chromium/components/spellcheck/common/spellcheck_messages.h
index b31cf564969..e8e83a8f026 100644
--- a/chromium/components/spellcheck/common/spellcheck_messages.h
+++ b/chromium/components/spellcheck/common/spellcheck_messages.h
@@ -7,11 +7,9 @@
#include <stdint.h>
-#include "components/spellcheck/common/spellcheck_bdict_language.h"
#include "components/spellcheck/common/spellcheck_result.h"
#include "components/spellcheck/spellcheck_build_features.h"
#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_platform_file.h"
#if !BUILDFLAG(ENABLE_SPELLCHECK)
#error "Spellcheck should be enabled"
@@ -28,28 +26,8 @@ IPC_STRUCT_TRAITS_BEGIN(SpellCheckResult)
IPC_STRUCT_TRAITS_MEMBER(replacement)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(SpellCheckBDictLanguage)
- IPC_STRUCT_TRAITS_MEMBER(file)
- IPC_STRUCT_TRAITS_MEMBER(language)
-IPC_STRUCT_TRAITS_END()
-
// Messages sent from the browser to the renderer.
-IPC_MESSAGE_CONTROL1(SpellCheckMsg_EnableSpellCheck, bool)
-
-// Passes some initialization params from the browser to the renderer's
-// spellchecker. This can be called directly after startup or in (async)
-// response to a RequestDictionary ViewHost message.
-IPC_MESSAGE_CONTROL2(SpellCheckMsg_Init,
- std::vector<SpellCheckBDictLanguage> /* bdict_languages */,
- std::set<std::string> /* custom_dict_words */)
-
-// Words have been added and removed in the custom dictionary; update the local
-// custom word list.
-IPC_MESSAGE_CONTROL2(SpellCheckMsg_CustomDictionaryChanged,
- std::set<std::string> /* words_added */,
- std::set<std::string> /* words_removed */)
-
#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Sends text-check results from the Spelling service when the service finishes
// checking text received by a SpellCheckHostMsg_CallSpellingService message.
@@ -63,16 +41,18 @@ IPC_MESSAGE_ROUTED4(SpellCheckMsg_RespondSpellingService,
#endif
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
-// This message tells the renderer to advance to the next misspelling. It is
-// sent when the user clicks the "Find Next" button on the spelling panel.
-IPC_MESSAGE_ROUTED0(SpellCheckMsg_AdvanceToNextMisspelling)
-
// Sends when NSSpellChecker finishes checking text received by a preceding
// SpellCheckHostMsg_RequestTextCheck message.
IPC_MESSAGE_ROUTED3(SpellCheckMsg_RespondTextCheck,
int /* request identifier given by WebKit */,
base::string16 /* sentence */,
std::vector<SpellCheckResult>)
+#endif
+
+#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
+// This message tells the renderer to advance to the next misspelling. It is
+// sent when the user clicks the "Find Next" button on the spelling panel.
+IPC_MESSAGE_ROUTED0(SpellCheckMsg_AdvanceToNextMisspelling)
IPC_MESSAGE_ROUTED1(SpellCheckMsg_ToggleSpellPanel, bool)
#endif
@@ -100,14 +80,6 @@ IPC_MESSAGE_CONTROL3(SpellCheckHostMsg_CallSpellingService,
#endif
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
-// Tells the browser to display or not display the SpellingPanel
-IPC_MESSAGE_ROUTED1(SpellCheckHostMsg_ShowSpellingPanel,
- bool /* if true, then show it, otherwise hide it*/)
-
-// Tells the browser to update the spelling panel with the given word.
-IPC_MESSAGE_ROUTED1(SpellCheckHostMsg_UpdateSpellingPanelWithMisspelledWord,
- base::string16 /* the word to update the panel with */)
-
// TODO(groby): This needs to originate from SpellcheckProvider.
IPC_SYNC_MESSAGE_CONTROL2_1(SpellCheckHostMsg_CheckSpelling,
base::string16 /* word */,
@@ -127,3 +99,13 @@ IPC_MESSAGE_ROUTED2(SpellCheckHostMsg_ToggleSpellCheck,
bool /* enabled */,
bool /* checked */)
#endif // USE_BROWSER_SPELLCHECKER
+
+#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
+// Tells the browser to display or not display the SpellingPanel
+IPC_MESSAGE_ROUTED1(SpellCheckHostMsg_ShowSpellingPanel,
+ bool /* if true, then show it, otherwise hide it*/)
+
+// Tells the browser to update the spelling panel with the given word.
+IPC_MESSAGE_ROUTED1(SpellCheckHostMsg_UpdateSpellingPanelWithMisspelledWord,
+ base::string16 /* the word to update the panel with */)
+#endif
diff --git a/chromium/components/spellcheck/renderer/BUILD.gn b/chromium/components/spellcheck/renderer/BUILD.gn
index 1c3e482f24d..96c1cb91a78 100644
--- a/chromium/components/spellcheck/renderer/BUILD.gn
+++ b/chromium/components/spellcheck/renderer/BUILD.gn
@@ -8,16 +8,10 @@ source_set("renderer") {
sources = [
"custom_dictionary_engine.cc",
"custom_dictionary_engine.h",
- "hunspell_engine.cc",
- "hunspell_engine.h",
- "platform_spelling_engine.cc",
- "platform_spelling_engine.h",
"spellcheck.cc",
"spellcheck.h",
"spellcheck_language.cc",
"spellcheck_language.h",
- "spellcheck_panel.cc",
- "spellcheck_panel.h",
"spellcheck_provider.cc",
"spellcheck_provider.h",
"spellcheck_worditerator.cc",
@@ -25,15 +19,22 @@ source_set("renderer") {
"spelling_engine.h",
]
- if (!use_browser_spellchecker) {
- sources -= [
+ if (use_browser_spellchecker) {
+ sources += [
"platform_spelling_engine.cc",
"platform_spelling_engine.h",
]
}
- if (is_android) {
- sources -= [
+ if (has_spellcheck_panel) {
+ sources += [
+ "spellcheck_panel.cc",
+ "spellcheck_panel.h",
+ ]
+ }
+
+ if (!is_android) {
+ sources += [
"hunspell_engine.cc",
"hunspell_engine.h",
]
@@ -45,8 +46,10 @@ source_set("renderer") {
deps = [
"//base:i18n",
"//components/spellcheck/common",
+ "//content/public/common",
"//content/public/renderer",
"//ipc",
+ "//services/service_manager/public/cpp",
"//third_party/WebKit/public:blink",
"//third_party/icu",
]
@@ -64,32 +67,25 @@ source_set("unit_tests") {
testonly = true
sources = [
"custom_dictionary_engine_unittest.cc",
- "spellcheck_multilingual_unittest.cc",
- "spellcheck_provider_hunspell_unittest.cc",
"spellcheck_provider_mac_unittest.cc",
"spellcheck_provider_test.cc",
"spellcheck_provider_test.h",
"spellcheck_provider_unittest.cc",
- "spellcheck_unittest.cc",
"spellcheck_worditerator_unittest.cc",
]
data = [
"//third_party/hunspell_dictionaries/",
]
- if (is_mac) {
- sources -= [
- # This tests Chrome's spellchecker which Mac doesn't use.
- "spellcheck_multilingual_unittest.cc",
- "spellcheck_provider_hunspell_unittest.cc",
- ]
+ if (!is_android) {
+ sources += [ "spellcheck_unittest.cc" ]
}
- if (is_android) {
- sources -= [
+ if (!is_mac && !is_android) {
+ sources += [
+ # This tests Chrome's spellchecker which Mac doesn't use.
"spellcheck_multilingual_unittest.cc",
"spellcheck_provider_hunspell_unittest.cc",
- "spellcheck_unittest.cc",
]
}
diff --git a/chromium/components/spellcheck/renderer/DEPS b/chromium/components/spellcheck/renderer/DEPS
index 16305c71d9d..5911cd864ca 100644
--- a/chromium/components/spellcheck/renderer/DEPS
+++ b/chromium/components/spellcheck/renderer/DEPS
@@ -1,6 +1,9 @@
include_rules = [
+ "+content/public/common",
"+content/public/renderer",
"+ipc",
- "+third_party/WebKit/public",
+ "+mojo/public/cpp/bindings",
+ "+services/service_manager/public/cpp",
"+third_party/hunspell",
+ "+third_party/WebKit/public",
]
diff --git a/chromium/components/spellcheck/renderer/spellcheck.cc b/chromium/components/spellcheck/renderer/spellcheck.cc
index cd1a39774bd..4ef53a067a6 100644
--- a/chromium/components/spellcheck/renderer/spellcheck.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck.cc
@@ -20,24 +20,24 @@
#include "build/build_config.h"
#include "components/spellcheck/common/spellcheck_common.h"
#include "components/spellcheck/common/spellcheck_features.h"
-#include "components/spellcheck/common/spellcheck_messages.h"
#include "components/spellcheck/common/spellcheck_result.h"
#include "components/spellcheck/common/spellcheck_switches.h"
#include "components/spellcheck/renderer/spellcheck_language.h"
#include "components/spellcheck/renderer/spellcheck_provider.h"
#include "components/spellcheck/spellcheck_build_features.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/common/simple_connection_filter.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
-#include "content/public/renderer/render_view_visitor.h"
-#include "ipc/ipc_platform_file.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h"
#include "third_party/WebKit/public/web/WebTextCheckingResult.h"
#include "third_party/WebKit/public/web/WebTextDecorationType.h"
-#include "third_party/WebKit/public/web/WebView.h"
using blink::WebVector;
using blink::WebString;
@@ -65,11 +65,11 @@ bool UpdateSpellcheckEnabled::Visit(content::RenderFrame* render_frame) {
return true;
}
-class DocumentMarkersRemover : public content::RenderViewVisitor {
+class DocumentMarkersRemover : public content::RenderFrameVisitor {
public:
explicit DocumentMarkersRemover(const std::set<std::string>& words);
~DocumentMarkersRemover() override {}
- bool Visit(content::RenderView* render_view) override;
+ bool Visit(content::RenderFrame* render_frame) override;
private:
WebVector<WebString> words_;
@@ -83,9 +83,10 @@ DocumentMarkersRemover::DocumentMarkersRemover(
[](const std::string& w) { return WebString::FromUTF8(w); });
}
-bool DocumentMarkersRemover::Visit(content::RenderView* render_view) {
- if (render_view && render_view->GetWebView())
- render_view->GetWebView()->RemoveSpellingMarkersUnderWords(words_);
+bool DocumentMarkersRemover::Visit(content::RenderFrame* render_frame) {
+ // TODO(xiaochengh): Both nullptr checks seem unnecessary.
+ if (render_frame && render_frame->GetWebFrame())
+ render_frame->GetWebFrame()->RemoveSpellingMarkersUnderWords(words_);
return true;
}
@@ -150,7 +151,22 @@ class SpellCheck::SpellcheckRequest {
// and as such the SpellCheckProviders will never be notified of different
// values.
// TODO(groby): Simplify this.
-SpellCheck::SpellCheck() : spellcheck_enabled_(true) {}
+SpellCheck::SpellCheck() : spellcheck_enabled_(true) {
+ if (!content::ChildThread::Get())
+ return; // Can be NULL in tests.
+
+ auto* service_manager_connection =
+ content::ChildThread::Get()->GetServiceManagerConnection();
+ DCHECK(service_manager_connection);
+
+ auto registry = base::MakeUnique<service_manager::BinderRegistry>();
+ registry->AddInterface(
+ base::Bind(&SpellCheck::SpellCheckerRequest, base::Unretained(this)),
+ base::ThreadTaskRunnerHandle::Get());
+
+ service_manager_connection->AddConnectionFilter(
+ base::MakeUnique<content::SimpleConnectionFilter>(std::move(registry)));
+}
SpellCheck::~SpellCheck() {
}
@@ -184,51 +200,46 @@ void SpellCheck::FillSuggestions(
}
}
-bool SpellCheck::OnControlMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(SpellCheck, message)
- IPC_MESSAGE_HANDLER(SpellCheckMsg_Init, OnInit)
- IPC_MESSAGE_HANDLER(SpellCheckMsg_CustomDictionaryChanged,
- OnCustomDictionaryChanged)
- IPC_MESSAGE_HANDLER(SpellCheckMsg_EnableSpellCheck, OnEnableSpellCheck)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- return handled;
+void SpellCheck::SpellCheckerRequest(
+ const service_manager::BindSourceInfo& source_info,
+ spellcheck::mojom::SpellCheckerRequest request) {
+ spellchecker_bindings_.AddBinding(this, std::move(request));
}
-void SpellCheck::OnInit(
- const std::vector<SpellCheckBDictLanguage>& bdict_languages,
- const std::set<std::string>& custom_words) {
+void SpellCheck::Initialize(
+ std::vector<spellcheck::mojom::SpellCheckBDictLanguagePtr> dictionaries,
+ const std::vector<std::string>& custom_words,
+ bool enable) {
languages_.clear();
- for (const auto& bdict_language : bdict_languages) {
- AddSpellcheckLanguage(
- IPC::PlatformFileForTransitToFile(bdict_language.file),
- bdict_language.language);
- }
- custom_dictionary_.Init(custom_words);
+ for (const auto& dictionary : dictionaries)
+ AddSpellcheckLanguage(std::move(dictionary->file), dictionary->language);
+
+ custom_dictionary_.Init(
+ std::set<std::string>(custom_words.begin(), custom_words.end()));
#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
PostDelayedSpellCheckTask(pending_request_param_.release());
#endif
-}
-void SpellCheck::OnCustomDictionaryChanged(
- const std::set<std::string>& words_added,
- const std::set<std::string>& words_removed) {
- custom_dictionary_.OnCustomDictionaryChanged(words_added, words_removed);
- if (words_added.empty())
- return;
- DocumentMarkersRemover markersRemover(words_added);
- content::RenderView::ForEach(&markersRemover);
-}
-
-void SpellCheck::OnEnableSpellCheck(bool enable) {
spellcheck_enabled_ = enable;
UpdateSpellcheckEnabled updater(enable);
content::RenderFrame::ForEach(&updater);
}
+void SpellCheck::CustomDictionaryChanged(
+ const std::vector<std::string>& words_added,
+ const std::vector<std::string>& words_removed) {
+ const std::set<std::string> added(words_added.begin(), words_added.end());
+
+ custom_dictionary_.OnCustomDictionaryChanged(
+ added, std::set<std::string>(words_removed.begin(), words_removed.end()));
+ if (added.empty())
+ return;
+
+ DocumentMarkersRemover markersRemover(added);
+ content::RenderFrame::ForEach(&markersRemover);
+}
+
// TODO(groby): Make sure we always have a spelling engine, even before
// AddSpellcheckLanguage() is called.
void SpellCheck::AddSpellcheckLanguage(base::File file,
diff --git a/chromium/components/spellcheck/renderer/spellcheck.h b/chromium/components/spellcheck/renderer/spellcheck.h
index 4e8582537fe..c5a839f7ba6 100644
--- a/chromium/components/spellcheck/renderer/spellcheck.h
+++ b/chromium/components/spellcheck/renderer/spellcheck.h
@@ -15,11 +15,12 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
+#include "components/spellcheck/common/spellcheck.mojom.h"
#include "components/spellcheck/renderer/custom_dictionary_engine.h"
#include "components/spellcheck/spellcheck_build_features.h"
#include "content/public/renderer/render_thread_observer.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
-struct SpellCheckBDictLanguage;
class SpellcheckLanguage;
struct SpellCheckResult;
@@ -29,8 +30,8 @@ struct WebTextCheckingResult;
template <typename T> class WebVector;
}
-namespace IPC {
-class Message;
+namespace service_manager {
+struct BindSourceInfo;
}
// TODO(morrita): Needs reorg with SpellCheckProvider.
@@ -38,7 +39,8 @@ class Message;
// Shared spellchecking logic/data for a RenderProcess. All RenderViews use
// this object to perform spellchecking tasks.
class SpellCheck : public content::RenderThreadObserver,
- public base::SupportsWeakPtr<SpellCheck> {
+ public base::SupportsWeakPtr<SpellCheck>,
+ public spellcheck::mojom::SpellChecker {
public:
// TODO(groby): I wonder if this can be private, non-mac only.
class SpellcheckRequest;
@@ -121,15 +123,18 @@ class SpellCheck : public content::RenderThreadObserver,
const std::vector<std::vector<base::string16>>& suggestions_list,
std::vector<base::string16>* optional_suggestions);
- // RenderThreadObserver implementation:
- bool OnControlMessageReceived(const IPC::Message& message) override;
+ // Binds requests for the SpellChecker interface.
+ void SpellCheckerRequest(const service_manager::BindSourceInfo& source_info,
+ spellcheck::mojom::SpellCheckerRequest request);
- // Message handlers.
- void OnInit(const std::vector<SpellCheckBDictLanguage>& bdict_languages,
- const std::set<std::string>& custom_words);
- void OnCustomDictionaryChanged(const std::set<std::string>& words_added,
- const std::set<std::string>& words_removed);
- void OnEnableSpellCheck(bool enable);
+ // spellcheck::mojom::SpellChecker:
+ void Initialize(
+ std::vector<spellcheck::mojom::SpellCheckBDictLanguagePtr> dictionaries,
+ const std::vector<std::string>& custom_words,
+ bool enable) override;
+ void CustomDictionaryChanged(
+ const std::vector<std::string>& words_added,
+ const std::vector<std::string>& words_removed) override;
#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Posts delayed spellcheck task and clear it if any.
@@ -147,6 +152,9 @@ class SpellCheck : public content::RenderThreadObserver,
std::unique_ptr<SpellcheckRequest> pending_request_param_;
#endif
+ // Bindings for SpellChecker clients.
+ mojo::BindingSet<spellcheck::mojom::SpellChecker> spellchecker_bindings_;
+
// A vector of objects used to actually check spelling, one for each enabled
// language.
std::vector<std::unique_ptr<SpellcheckLanguage>> languages_;
diff --git a/chromium/components/spellcheck/renderer/spellcheck_panel.cc b/chromium/components/spellcheck/renderer/spellcheck_panel.cc
index 0e96ef4fe15..e2b0373d402 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_panel.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_panel.cc
@@ -22,10 +22,8 @@ SpellCheckPanel::SpellCheckPanel(content::RenderView* render_view)
SpellCheckPanel::~SpellCheckPanel() = default;
void SpellCheckPanel::ShowSpellingUI(bool show) {
-#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
UMA_HISTOGRAM_BOOLEAN("SpellCheck.api.showUI", show);
Send(new SpellCheckHostMsg_ShowSpellingPanel(routing_id(), show));
-#endif
}
bool SpellCheckPanel::IsShowingSpellingUI() {
@@ -34,17 +32,11 @@ bool SpellCheckPanel::IsShowingSpellingUI() {
void SpellCheckPanel::UpdateSpellingUIWithMisspelledWord(
const WebString& word) {
-#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
Send(new SpellCheckHostMsg_UpdateSpellingPanelWithMisspelledWord(
routing_id(), word.Utf16()));
-#endif
}
bool SpellCheckPanel::OnMessageReceived(const IPC::Message& message) {
-#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
- return false;
-#endif
-#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(SpellCheckPanel, message)
IPC_MESSAGE_HANDLER(SpellCheckMsg_AdvanceToNextMisspelling,
@@ -53,10 +45,8 @@ bool SpellCheckPanel::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
-#endif
}
-#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
void SpellCheckPanel::OnAdvanceToNextMisspelling() {
if (!render_view()->GetWebView())
return;
@@ -73,7 +63,6 @@ void SpellCheckPanel::OnToggleSpellPanel(bool is_currently_visible) {
render_view()->GetWebView()->FocusedFrame()->ExecuteCommand(
WebString::FromUTF8("ToggleSpellPanel"));
}
-#endif
void SpellCheckPanel::OnDestruct() {
delete this;
diff --git a/chromium/components/spellcheck/renderer/spellcheck_panel.h b/chromium/components/spellcheck/renderer/spellcheck_panel.h
index 87c42f6c82f..18c9c4e2f15 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_panel.h
+++ b/chromium/components/spellcheck/renderer/spellcheck_panel.h
@@ -11,9 +11,10 @@
#include "content/public/renderer/render_view_observer_tracker.h"
#include "third_party/WebKit/public/web/WebSpellCheckClient.h"
-// TODO(xiaochengh): Only Mac has spelling panel. Remove the #if checks in this
-// class, which seem unnecessary, and make sure that this class is compiled and
-// used only on Mac.
+#if !BUILDFLAG(HAS_SPELLCHECK_PANEL)
+#error "This file shouldn't be compiled without spellcheck panel."
+#endif
+
class SpellCheckPanel
: public content::RenderViewObserver,
public content::RenderViewObserverTracker<SpellCheckPanel>,
@@ -35,10 +36,8 @@ class SpellCheckPanel
void UpdateSpellingUIWithMisspelledWord(
const blink::WebString& word) override;
-#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
void OnAdvanceToNextMisspelling();
void OnToggleSpellPanel(bool is_currently_visible);
-#endif
// True if the browser is showing the spelling panel for us.
bool spelling_panel_visible_;
diff --git a/chromium/components/spellcheck/spellcheck_build_features.gni b/chromium/components/spellcheck/spellcheck_build_features.gni
index ef26aea4a71..34a27d7449c 100644
--- a/chromium/components/spellcheck/spellcheck_build_features.gni
+++ b/chromium/components/spellcheck/spellcheck_build_features.gni
@@ -9,3 +9,6 @@ enable_spellcheck = !is_ios
# not affect the "red underline" spellchecker which can consult Google's
# server-based spellcheck service.
use_browser_spellchecker = is_android || is_mac
+
+# Only Mac has a spellcheck panel.
+has_spellcheck_panel = is_mac
diff --git a/chromium/components/ssl_errors/error_info.cc b/chromium/components/ssl_errors/error_info.cc
index ab7afccb05c..a6bed5cea72 100644
--- a/chromium/components/ssl_errors/error_info.cc
+++ b/chromium/components/ssl_errors/error_info.cc
@@ -38,9 +38,9 @@ ErrorInfo ErrorInfo::CreateError(ErrorType error_type,
size_t i = 0;
if (dns_names.empty()) {
// The certificate had no DNS names, display an explanatory string.
- // TODO(elawrence): Change the error messsage instead of just the
- // placeholder string; see https://crbug.com/708268
- dns_names.push_back("[missing_subjectAltName]");
+ details = l10n_util::GetStringFUTF16(
+ IDS_CERT_ERROR_NO_SUBJECT_ALTERNATIVE_NAMES_DETAILS,
+ UTF8ToUTF16(request_url.host()));
} else {
// If the certificate contains multiple DNS names, we choose the most
// representative one -- either the DNS name that's also in the subject
@@ -54,12 +54,13 @@ ErrorInfo ErrorInfo::CreateError(ErrorType error_type,
}
if (i == dns_names.size())
i = 0;
+
+ details = l10n_util::GetStringFUTF16(
+ IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS,
+ UTF8ToUTF16(request_url.host()),
+ net::EscapeForHTML(UTF8ToUTF16(dns_names[i])));
}
- details = l10n_util::GetStringFUTF16(
- IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS,
- UTF8ToUTF16(request_url.host()),
- net::EscapeForHTML(UTF8ToUTF16(dns_names[i])));
short_description = l10n_util::GetStringUTF16(
IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION);
break;
diff --git a/chromium/components/ssl_errors_strings.grdp b/chromium/components/ssl_errors_strings.grdp
index 0b9c8c84a98..d39cd09c792 100644
--- a/chromium/components/ssl_errors_strings.grdp
+++ b/chromium/components/ssl_errors_strings.grdp
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
+ <message name="IDS_CERT_ERROR_NO_SUBJECT_ALTERNATIVE_NAMES_DETAILS" desc="Description for a certificate error where an X509 certificate does not contain the required Subject Alternative Name extension.">
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate does not specify Subject Alternative Names. This may be caused by a misconfiguration or an attacker intercepting your connection.
+ </message>
<message name="IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS" desc="Details for an unsafe common name in an X509 certificate">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is from <ph name="DOMAIN2">&lt;strong&gt;$2<ex>fakepaypal.com</ex>&lt;/strong&gt;</ph>. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is from <ph name="DOMAIN2">&lt;strong&gt;$2<ex>fakepaypal.com</ex>&lt;/strong&gt;</ph>. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
<message name="IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION" desc="Description for an unsafe common name in an X509 certificate">
Server's certificate does not match the URL.
@@ -10,8 +13,8 @@
<message name="IDS_CERT_ERROR_EXPIRED_DETAILS" desc="Details for an expired X509 certificate [ICU Syntax]">
{1, plural,
- =1 {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate expired yesterday. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.}
- other {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.}}
+ =1 {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate expired yesterday. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.}
+ other {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.}}
</message>
<message name="IDS_CERT_ERROR_EXPIRED_DESCRIPTION" desc="Description for an expired X509 certificate">
Server's certificate has expired.
@@ -19,15 +22,15 @@
<message name="IDS_CERT_ERROR_NOT_YET_VALID_DETAILS" desc="Details for an X509 certificate that is not yet valid [ICU Syntax]">
{1, plural,
- =1 {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is supposedly from tomorrow. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.}
- other {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is supposedly from # days in the future. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.}}
+ =1 {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is supposedly from tomorrow. This may be caused by a misconfiguration or an attacker intercepting your connection.}
+ other {This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;{0}<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is supposedly from # days in the future. This may be caused by a misconfiguration or an attacker intercepting your connection.}}
</message>
<message name="IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION" desc="Description for an X509 certificate that is not yet valid">
Server's certificate is not yet valid.
</message>
<message name="IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DETAILS" desc="Details for a chain with a X509 certificate that is not valid at this time.">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not valid at this time. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not valid at this time. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
<message name="IDS_CERT_ERROR_NOT_VALID_AT_THIS_TIME_DESCRIPTION" desc="Description for a chain with a X509 certificate that is not valid at this time.">
Server's certificate is not valid at this time.
@@ -38,62 +41,62 @@
</message>
<message name="IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS" desc="Details of the error page for an X509 certificate that contains errors">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate contains errors. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate contains errors. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
<message name="IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION" desc="Description of the error page for an X509 certificate that contains errors">
Server's certificate contains errors.
</message>
<message name="IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS" desc="Details for being unable to check revocation status of an X509 certificate">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
<message name="IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION" desc="Description for being unable to check revocation status of an X509 certificate">
Server's certificate cannot be checked.
</message>
<message name="IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS" desc="Details for not finding a revocation mechanism in an X509 certificate">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
<message name="IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION" desc="Description for not finding a revocation mechanism in an X509 certificate">
No revocation mechanism found.
</message>
<message name="IDS_CERT_ERROR_REVOKED_CERT_DETAILS" desc="Details of the error page for a revoked certificate">
- You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the certificate that the server presented has been revoked by its issuer. This means that the security credentials the server presented absolutely should not be trusted. You may be communicating with an attacker. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the certificate that the server presented has been revoked by its issuer. This means that the security credentials the server presented absolutely should not be trusted. You may be communicating with an attacker.
</message>
<message name="IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION" desc="Description of the error page for a revoked certificate">
Server's certificate has been revoked.
</message>
<message name="IDS_CERT_ERROR_INVALID_CERT_DETAILS" desc="Details of the error page for an X509 certificate that is invalid">
- You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented an invalid certificate. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented an invalid certificate.
</message>
<message name="IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION" desc="Description of the error page for an X509 certificate that is invalid">
Server's certificate is invalid.
</message>
<message name="IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS" desc="Details of the error page for a certificate signed using a weak signature algorithm">
- You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate signed using a weak signature algorithm (such as SHA-1). This means that the security credentials the server presented could have been forged, and the server may not be the server you expected (you may be communicating with an attacker). <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate signed using a weak signature algorithm (such as SHA-1). This means that the security credentials the server presented could have been forged, and the server may not be the server you expected (you may be communicating with an attacker).
</message>
<message name="IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION" desc="Description of the error page for a certificate signed using a weak signature algorithm">
Server's certificate is signed using a weak signature algorithm.
</message>
<message name="IDS_CERT_ERROR_WEAK_KEY_DETAILS" desc="Details of the error page for a certificate containing a weak key">
- You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate containing a weak key. An attacker could have broken the private key, and the server may not be the server you expected (you may be communicating with an attacker). <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate containing a weak key. An attacker could have broken the private key, and the server may not be the server you expected (you may be communicating with an attacker).
</message>
<message name="IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION" desc="Description of the error page for a certificate containing a weak key">
The server certificate contains a weak cryptographic key.
</message>
<message name="IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DETAILS" desc="Details of the error page for a certificate that contains a name outside of its scope">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might have been issued fraudulently. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate might have been issued fraudulently. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
<message name="IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DESCRIPTION" desc="Description of the error page for a certificate that contains a name outside of its scope">
Server's certificate violates name constraints.
</message>
<message name="IDS_CERT_ERROR_VALIDITY_TOO_LONG_DETAILS" desc="Details of the error page for a certificate whose validity period is too long">
- You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate whose validity period is too long to be trustworthy. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ You attempted to reach <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>, but the server presented a certificate whose validity period is too long to be trustworthy.
</message>
<message name="IDS_CERT_ERROR_VALIDITY_TOO_LONG_DESCRIPTION" desc="Description of the error page for a certificate whose validity period is too long">
The server certificate has a validity period that is too long.
@@ -107,14 +110,14 @@
</message>
<message name="IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DETAILS" desc="Details of the error page for a certificate which doesn't match the built-in pins for that name">
- The server presented a certificate that doesn't match built-in expectations. These expectations are included for certain, high-security websites in order to protect you. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ The server presented a certificate that doesn't match built-in expectations. These expectations are included for certain, high-security websites in order to protect you.
</message>
<message name="IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DESCRIPTION" desc="Description of the error page for a certificate which doesn't match the built-in pins for that name">
The server's certificate appears to be a forgery.
</message>
<message name="IDS_CERT_ERROR_CERTIFICATE_TRANSPARENCY_REQUIRED_DETAILS" desc="Details of the error page for a site or certificate that requires compliance with the Chromium Certificate Transparency Policy">
- The server presented a certificate that was not publicly disclosed using the Certificate Transparency policy. This is a requirement for some certificates, to ensure that they are trustworthy and protect against attackers. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ The server presented a certificate that was not publicly disclosed using the Certificate Transparency policy. This is a requirement for some certificates, to ensure that they are trustworthy and protect against attackers.
</message>
<message name="IDS_CERT_ERROR_CERTIFICATE_TRANSPARENCY_REQUIRED_DESCRIPTION" desc="Description of the error page for a site or certificate that requires compliance with the Chromium Certificate Transparency Policy">
The server's certificate was not disclosed via Certificate Transparency.
@@ -123,17 +126,17 @@
<if expr="_google_chrome">
<if expr="is_ios">
<message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by Chrome. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by Chrome. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
</if>
<if expr="is_android">
<message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
</if>
<if expr="not is_ios and not is_android">
<message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
</if>
</if>
@@ -141,17 +144,17 @@
<if expr="not _google_chrome">
<if expr="is_ios">
<message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by Chromium. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by Chromium. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
</if>
<if expr="is_android">
<message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
</if>
<if expr="not is_ios and not is_android">
<message name="IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS" desc="Details for an X509 certificate with an invalid authority">
- This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK">&lt;a href="#" id="learn-more-link"&gt;</ph>Learn more<ph name="END_LEARN_MORE_LINK">&lt;/a&gt;</ph>.
+ This server could not prove that it is <ph name="DOMAIN">&lt;strong&gt;$1<ex>paypal.com</ex>&lt;/strong&gt;</ph>; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
</message>
</if>
</if>
diff --git a/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.cc b/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.cc
index bcb1259f85e..2edb795765b 100644
--- a/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.cc
+++ b/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.cc
@@ -15,7 +15,9 @@ StartupMetricHostImpl::StartupMetricHostImpl() = default;
StartupMetricHostImpl::~StartupMetricHostImpl() = default;
// static
-void StartupMetricHostImpl::Create(mojom::StartupMetricHostRequest request) {
+void StartupMetricHostImpl::Create(
+ const service_manager::BindSourceInfo& source_info,
+ mojom::StartupMetricHostRequest request) {
mojo::MakeStrongBinding(base::MakeUnique<StartupMetricHostImpl>(),
std::move(request));
}
diff --git a/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.h b/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.h
index 6901e13bf56..cba0d723a4a 100644
--- a/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.h
+++ b/chromium/components/startup_metric_utils/browser/startup_metric_host_impl.h
@@ -11,6 +11,10 @@
#include "base/time/time.h"
#include "components/startup_metric_utils/common/startup_metric.mojom.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace startup_metric_utils {
class StartupMetricHostImpl : public mojom::StartupMetricHost {
@@ -18,7 +22,8 @@ class StartupMetricHostImpl : public mojom::StartupMetricHost {
StartupMetricHostImpl();
~StartupMetricHostImpl() override;
- static void Create(mojom::StartupMetricHostRequest request);
+ static void Create(const service_manager::BindSourceInfo& source_info,
+ mojom::StartupMetricHostRequest request);
private:
void RecordRendererMainEntryTime(
diff --git a/chromium/components/startup_metric_utils/browser/startup_metric_utils.cc b/chromium/components/startup_metric_utils/browser/startup_metric_utils.cc
index f1ad613d5df..8d9e4669e7c 100644
--- a/chromium/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/chromium/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -39,7 +39,7 @@ namespace {
// Mark as volatile to defensively make sure usage is thread-safe.
// Note that at the time of this writing, access is only on the UI thread.
-volatile bool g_non_browser_ui_displayed = false;
+volatile bool g_main_window_startup_interrupted = false;
base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks =
LAZY_INSTANCE_INITIALIZER;
@@ -53,6 +53,9 @@ base::LazyInstance<base::TimeTicks>::Leaky g_renderer_main_entry_point_ticks =
base::LazyInstance<base::TimeTicks>::Leaky
g_browser_exe_main_entry_point_ticks = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<base::TimeTicks>::Leaky g_message_loop_start_ticks =
+ LAZY_INSTANCE_INITIALIZER;
+
// Only used by RecordMainEntryTimeHistogram(), should go away with it (do not
// add new uses of this), see crbug.com/317481 for discussion on why it was kept
// as-is for now.
@@ -388,12 +391,12 @@ void RecordHardFaultHistogram() {
// also the time taken to synchronously resolve base::Time::Now() and
// base::TimeTicks::Now() at play, but in practice it is pretty much instant
// compared to multi-seconds startup timings.
-base::TimeTicks StartupTimeToTimeTicks(const base::Time& time) {
- // First get a base which represents the same point in time in both units.
- // Bump the priority of this thread while doing this as the wall clock time it
- // takes to resolve these two calls affects the precision of this method and
- // bumping the priority reduces the likelihood of a context switch interfering
- // with this computation.
+base::TimeTicks StartupTimeToTimeTicks(base::Time time) {
+// First get a base which represents the same point in time in both units.
+// Bump the priority of this thread while doing this as the wall clock time it
+// takes to resolve these two calls affects the precision of this method and
+// bumping the priority reduces the likelihood of a context switch interfering
+// with this computation.
// Enabling this logic on OS X causes a significant performance regression.
// https://crbug.com/601270
@@ -455,9 +458,9 @@ void RecordMainEntryTimeHistogram() {
// Record renderer main entry time histogram.
void RecordRendererMainEntryHistogram() {
- const base::TimeTicks& browser_main_entry_point_ticks =
+ const base::TimeTicks browser_main_entry_point_ticks =
g_browser_main_entry_point_ticks.Get();
- const base::TimeTicks& renderer_main_entry_point_ticks =
+ const base::TimeTicks renderer_main_entry_point_ticks =
g_renderer_main_entry_point_ticks.Get();
if (!browser_main_entry_point_ticks.is_null() &&
@@ -548,6 +551,11 @@ void RecordSameVersionStartupCount(PrefService* pref_service) {
g_startups_with_current_version);
}
+bool ShouldLogStartupHistogram() {
+ return !WasMainWindowStartupInterrupted() &&
+ !g_process_creation_ticks.Get().is_null();
+}
+
} // namespace
void RegisterPrefs(PrefRegistrySimple* registry) {
@@ -557,21 +565,25 @@ void RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterIntegerPref(prefs::kSameVersionStartupCount, 0);
}
-bool WasNonBrowserUIDisplayed() {
- return g_non_browser_ui_displayed;
+bool WasMainWindowStartupInterrupted() {
+ return g_main_window_startup_interrupted;
}
void SetNonBrowserUIDisplayed() {
- g_non_browser_ui_displayed = true;
+ g_main_window_startup_interrupted = true;
}
-void RecordStartupProcessCreationTime(const base::Time& time) {
+void SetBackgroundModeEnabled() {
+ g_main_window_startup_interrupted = true;
+}
+
+void RecordStartupProcessCreationTime(base::Time time) {
DCHECK(g_process_creation_ticks.Get().is_null());
g_process_creation_ticks.Get() = StartupTimeToTimeTicks(time);
DCHECK(!g_process_creation_ticks.Get().is_null());
}
-void RecordMainEntryPointTime(const base::Time& time) {
+void RecordMainEntryPointTime(base::Time time) {
DCHECK(g_browser_main_entry_point_ticks.Get().is_null());
g_browser_main_entry_point_ticks.Get() = StartupTimeToTimeTicks(time);
DCHECK(!g_browser_main_entry_point_ticks.Get().is_null());
@@ -583,16 +595,23 @@ void RecordMainEntryPointTime(const base::Time& time) {
DCHECK(!g_browser_main_entry_point_time.Get().is_null());
}
-void RecordExeMainEntryPointTicks(const base::TimeTicks& ticks) {
+void RecordExeMainEntryPointTicks(base::TimeTicks ticks) {
DCHECK(g_browser_exe_main_entry_point_ticks.Get().is_null());
g_browser_exe_main_entry_point_ticks.Get() = ticks;
DCHECK(!g_browser_exe_main_entry_point_ticks.Get().is_null());
}
-void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
+void RecordMessageLoopStartTicks(base::TimeTicks ticks) {
+ DCHECK(g_message_loop_start_ticks.Get().is_null());
+ g_message_loop_start_ticks.Get() = ticks;
+ DCHECK(!g_message_loop_start_ticks.Get().is_null());
+}
+
+void RecordBrowserMainMessageLoopStart(base::TimeTicks ticks,
bool is_first_run,
PrefService* pref_service) {
DCHECK(pref_service);
+ RecordMessageLoopStartTicks(ticks);
// Keep RecordSameVersionStartupCount() and RecordHardFaultHistogram()
// near the top of this method (as much as possible) as many other
@@ -604,8 +623,7 @@ void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
// Record timing of the browser message-loop start time.
base::StackSamplingProfiler::SetProcessMilestone(
metrics::CallStackProfileMetricsProvider::MAIN_LOOP_START);
- const base::TimeTicks& process_creation_ticks =
- g_process_creation_ticks.Get();
+ const base::TimeTicks process_creation_ticks = g_process_creation_ticks.Get();
if (!is_first_run && !process_creation_ticks.is_null()) {
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserMessageLoopStartTime",
@@ -657,12 +675,12 @@ void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
}
}
-void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) {
+void RecordBrowserWindowDisplay(base::TimeTicks ticks) {
static bool is_first_call = true;
if (!is_first_call || ticks.is_null())
return;
is_first_call = false;
- if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+ if (!ShouldLogStartupHistogram())
return;
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
@@ -670,7 +688,7 @@ void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) {
g_process_creation_ticks.Get(), ticks);
}
-void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta) {
+void RecordBrowserOpenTabsDelta(base::TimeDelta delta) {
static bool is_first_call = true;
if (!is_first_call)
return;
@@ -680,19 +698,19 @@ void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta) {
UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserOpenTabs", delta);
}
-void RecordRendererMainEntryTime(const base::TimeTicks& ticks) {
+void RecordRendererMainEntryTime(base::TimeTicks ticks) {
// Record the renderer main entry time, but don't log the UMA metric
// immediately because the startup temperature is not known yet.
if (g_renderer_main_entry_point_ticks.Get().is_null())
g_renderer_main_entry_point_ticks.Get() = ticks;
}
-void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks) {
+void RecordFirstWebContentsMainFrameLoad(base::TimeTicks ticks) {
static bool is_first_call = true;
if (!is_first_call || ticks.is_null())
return;
is_first_call = false;
- if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+ if (!ShouldLogStartupHistogram())
return;
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
@@ -700,7 +718,7 @@ void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks) {
g_process_creation_ticks.Get(), ticks);
}
-void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks) {
+void RecordFirstWebContentsNonEmptyPaint(base::TimeTicks ticks) {
static bool is_first_call = true;
if (!is_first_call || ticks.is_null())
return;
@@ -710,7 +728,7 @@ void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks) {
// entry time and the startup temperature are known.
RecordRendererMainEntryHistogram();
- if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+ if (!ShouldLogStartupHistogram())
return;
base::StackSamplingProfiler::SetProcessMilestone(
@@ -718,15 +736,19 @@ void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks) {
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100, "Startup.FirstWebContents.NonEmptyPaint2",
g_process_creation_ticks.Get(), ticks);
+ UMA_HISTOGRAM_WITH_TEMPERATURE(
+ UMA_HISTOGRAM_LONG_TIMES_100,
+ "Startup.BrowserMessageLoopStart.To.NonEmptyPaint2",
+ ticks - g_message_loop_start_ticks.Get());
}
-void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks,
+void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks,
WebContentsWorkload workload) {
static bool is_first_call = true;
if (!is_first_call || ticks.is_null())
return;
is_first_call = false;
- if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+ if (!ShouldLogStartupHistogram())
return;
base::StackSamplingProfiler::SetProcessMilestone(
@@ -735,6 +757,10 @@ void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks,
UMA_HISTOGRAM_LONG_TIMES_100,
"Startup.FirstWebContents.MainNavigationStart",
g_process_creation_ticks.Get(), ticks);
+ UMA_HISTOGRAM_WITH_TEMPERATURE(
+ UMA_HISTOGRAM_LONG_TIMES_100,
+ "Startup.BrowserMessageLoopStart.To.MainNavigationStart",
+ ticks - g_message_loop_start_ticks.Get());
// Log extra information about this startup's workload. Only added to this
// histogram as this extra suffix can help making it less noisy but isn't
@@ -752,13 +778,12 @@ void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks,
}
}
-void RecordFirstWebContentsMainNavigationFinished(
- const base::TimeTicks& ticks) {
+void RecordFirstWebContentsMainNavigationFinished(base::TimeTicks ticks) {
static bool is_first_call = true;
if (!is_first_call || ticks.is_null())
return;
is_first_call = false;
- if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null())
+ if (!ShouldLogStartupHistogram())
return;
base::StackSamplingProfiler::SetProcessMilestone(
@@ -769,6 +794,34 @@ void RecordFirstWebContentsMainNavigationFinished(
g_process_creation_ticks.Get(), ticks);
}
+void RecordBrowserWindowFirstPaint(base::TimeTicks ticks) {
+ static bool is_first_call = true;
+ if (!is_first_call || ticks.is_null())
+ return;
+ is_first_call = false;
+ if (!ShouldLogStartupHistogram())
+ return;
+
+ UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE(
+ UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserWindow.FirstPaint",
+ g_process_creation_ticks.Get(), ticks);
+}
+
+void RecordBrowserWindowFirstPaintCompositingEnded(
+ const base::TimeTicks ticks) {
+ static bool is_first_call = true;
+ if (!is_first_call || ticks.is_null())
+ return;
+ is_first_call = false;
+ if (!ShouldLogStartupHistogram())
+ return;
+
+ UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE(
+ UMA_HISTOGRAM_LONG_TIMES_100,
+ "Startup.BrowserWindow.FirstPaint.CompositingEnded",
+ g_process_creation_ticks.Get(), ticks);
+}
+
base::TimeTicks MainEntryPointTicks() {
return g_browser_main_entry_point_ticks.Get();
}
diff --git a/chromium/components/startup_metric_utils/browser/startup_metric_utils.h b/chromium/components/startup_metric_utils/browser/startup_metric_utils.h
index 5ebb8ff5e77..2e6fd0d3108 100644
--- a/chromium/components/startup_metric_utils/browser/startup_metric_utils.h
+++ b/chromium/components/startup_metric_utils/browser/startup_metric_utils.h
@@ -30,10 +30,9 @@ enum class WebContentsWorkload {
// Registers startup related prefs in |registry|.
void RegisterPrefs(PrefRegistrySimple* registry);
-// Returns true if any UI other than the browser window has been displayed
-// so far. Useful to test if UI has been displayed before the first browser
-// window was shown, which would invalidate any surrounding timing metrics.
-bool WasNonBrowserUIDisplayed();
+// Returns true when browser UI was not launched normally: some other UI was
+// shown first or browser was launched in background mode.
+bool WasMainWindowStartupInterrupted();
// Call this when displaying UI that might potentially delay startup events.
//
@@ -43,54 +42,66 @@ bool WasNonBrowserUIDisplayed();
// been displayed or not.
void SetNonBrowserUIDisplayed();
+// Call this when background mode gets enabled, as it might delay startup
+// events.
+void SetBackgroundModeEnabled();
+
// Call this with the creation time of the startup (initial/main) process.
-void RecordStartupProcessCreationTime(const base::Time& time);
+void RecordStartupProcessCreationTime(base::Time time);
// Call this with a time recorded as early as possible in the startup process.
// On Android, the entry point time is the time at which the Java code starts.
// In Mojo, the entry point time is the time at which the shell starts.
-void RecordMainEntryPointTime(const base::Time& time);
+void RecordMainEntryPointTime(base::Time time);
// Call this with the time when the executable is loaded and main() is entered.
// Can be different from |RecordMainEntryPointTime| when the startup process is
// contained in a separate dll, such as with chrome.exe / chrome.dll on Windows.
-void RecordExeMainEntryPointTicks(const base::TimeTicks& time);
+void RecordExeMainEntryPointTicks(base::TimeTicks time);
// Call this with the time recorded just before the message loop is started.
// |is_first_run| - is the current launch part of a first run. |pref_service| is
// used to store state for stats that span multiple startups.
-void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks,
+void RecordBrowserMainMessageLoopStart(base::TimeTicks ticks,
bool is_first_run,
PrefService* pref_service);
// Call this with the time when the first browser window became visible.
-void RecordBrowserWindowDisplay(const base::TimeTicks& ticks);
+void RecordBrowserWindowDisplay(base::TimeTicks ticks);
// Call this with the time delta that the browser spent opening its tabs.
-void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta);
+void RecordBrowserOpenTabsDelta(base::TimeDelta delta);
// Call this with a renderer main entry time. The value provided for the first
// call to this function is used to compute
// Startup.LoadTime.BrowserMainToRendererMain. Further calls to this
// function are ignored.
-void RecordRendererMainEntryTime(const base::TimeTicks& ticks);
+void RecordRendererMainEntryTime(base::TimeTicks ticks);
// Call this with the time when the first web contents loaded its main frame,
// only if the first web contents was unimpended in its attempt to do so.
-void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks);
+void RecordFirstWebContentsMainFrameLoad(base::TimeTicks ticks);
// Call this with the time when the first web contents had a non-empty paint,
// only if the first web contents was unimpended in its attempt to do so.
-void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks);
+void RecordFirstWebContentsNonEmptyPaint(base::TimeTicks ticks);
// Call this with the time when the first web contents began navigating its main
// frame. Adds a suffix to its metrics according to |workload|.
-void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks,
+void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks,
WebContentsWorkload workload);
// Call this with the time when the first web contents successfully committed
// its navigation for the main frame.
-void RecordFirstWebContentsMainNavigationFinished(const base::TimeTicks& ticks);
+void RecordFirstWebContentsMainNavigationFinished(base::TimeTicks ticks);
+
+// Call this with the time when the Browser window painted its children for the
+// first time.
+void RecordBrowserWindowFirstPaint(base::TimeTicks ticks);
+
+// Call this with the time when the Browser window painted its children for the
+// first time and we got a CompositingEnded after that.
+void RecordBrowserWindowFirstPaintCompositingEnded(base::TimeTicks ticks);
// Returns the TimeTicks corresponding to main entry as recorded by
// RecordMainEntryPointTime. Returns a null TimeTicks if a value has not been
diff --git a/chromium/components/storage_monitor/media_storage_util.cc b/chromium/components/storage_monitor/media_storage_util.cc
index 5dbfdcc083e..7841e4e294e 100644
--- a/chromium/components/storage_monitor/media_storage_util.cc
+++ b/chromium/components/storage_monitor/media_storage_util.cc
@@ -9,7 +9,6 @@
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
@@ -23,19 +22,6 @@ namespace storage_monitor {
namespace {
-// MediaDeviceNotification.DeviceInfo histogram values.
-enum DeviceInfoHistogramBuckets {
- MASS_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE,
- MASS_STORAGE_DEVICE_UUID_MISSING,
- MASS_STORAGE_DEVICE_NAME_MISSING,
- MASS_STORAGE_DEVICE_NAME_AND_UUID_MISSING,
- MTP_STORAGE_DEVICE_NAME_AND_UUID_AVAILABLE,
- MTP_STORAGE_DEVICE_UUID_MISSING,
- MTP_STORAGE_DEVICE_NAME_MISSING,
- MTP_STORAGE_DEVICE_NAME_AND_UUID_MISSING,
- DEVICE_INFO_BUCKET_BOUNDARY
-};
-
#if !defined(OS_WIN)
const char kRootPath[] = "/";
#endif
@@ -213,30 +199,6 @@ base::FilePath MediaStorageUtil::FindDevicePathById(
}
// static
-void MediaStorageUtil::RecordDeviceInfoHistogram(
- bool mass_storage,
- const std::string& device_uuid,
- const base::string16& device_label) {
- unsigned int event_number = 0;
- if (!mass_storage)
- event_number = 4;
-
- if (device_label.empty())
- event_number += 2;
-
- if (device_uuid.empty())
- event_number += 1;
- enum DeviceInfoHistogramBuckets event =
- static_cast<enum DeviceInfoHistogramBuckets>(event_number);
- if (event >= DEVICE_INFO_BUCKET_BOUNDARY) {
- NOTREACHED();
- return;
- }
- UMA_HISTOGRAM_ENUMERATION("MediaDeviceNotifications.DeviceInfo", event,
- DEVICE_INFO_BUCKET_BOUNDARY);
-}
-
-// static
bool MediaStorageUtil::IsRemovableStorageAttached(const std::string& id) {
StorageMonitor* monitor = StorageMonitor::GetInstance();
if (!monitor)
diff --git a/chromium/components/storage_monitor/media_storage_util.h b/chromium/components/storage_monitor/media_storage_util.h
index 99c14d66050..6b0bb74da2a 100644
--- a/chromium/components/storage_monitor/media_storage_util.h
+++ b/chromium/components/storage_monitor/media_storage_util.h
@@ -50,13 +50,6 @@ class MediaStorageUtil {
// the device is connected.
static base::FilePath FindDevicePathById(const std::string& device_id);
- // Record device information histogram for the given |device_uuid| and
- // |device_label|. |mass_storage| indicates whether the current device is a
- // mass storage device, as defined by IsMassStorageDevice().
- static void RecordDeviceInfoHistogram(bool mass_storage,
- const std::string& device_uuid,
- const base::string16& device_label);
-
// Returns true if the |id| is both a removable device and also
// currently attached.
static bool IsRemovableStorageAttached(const std::string& id);
diff --git a/chromium/components/storage_monitor/media_storage_util_unittest.cc b/chromium/components/storage_monitor/media_storage_util_unittest.cc
index 5b895a8701d..b478bf76d33 100644
--- a/chromium/components/storage_monitor/media_storage_util_unittest.cc
+++ b/chromium/components/storage_monitor/media_storage_util_unittest.cc
@@ -6,6 +6,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
diff --git a/chromium/components/storage_monitor/media_transfer_protocol_device_observer_chromeos.cc b/chromium/components/storage_monitor/media_transfer_protocol_device_observer_chromeos.cc
index 061619991f3..3a67e27d88c 100644
--- a/chromium/components/storage_monitor/media_transfer_protocol_device_observer_chromeos.cc
+++ b/chromium/components/storage_monitor/media_transfer_protocol_device_observer_chromeos.cc
@@ -11,7 +11,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/storage_monitor/media_storage_util.h"
#include "components/storage_monitor/removable_device_constants.h"
#include "device/media_transfer_protocol/mtp_storage_info.pb.h"
@@ -202,10 +201,6 @@ void MediaTransferProtocolDeviceObserverChromeOS::StorageChanged(
&storage_label, &location, &vendor_name,
&product_name);
- // Keep track of device id and device name to see how often we receive
- // empty values.
- MediaStorageUtil::RecordDeviceInfoHistogram(false, device_id,
- storage_label);
if (device_id.empty() || storage_label.empty())
return;
diff --git a/chromium/components/storage_monitor/portable_device_watcher_win.cc b/chromium/components/storage_monitor/portable_device_watcher_win.cc
index 1fa2e2320f5..62a08a0c39a 100644
--- a/chromium/components/storage_monitor/portable_device_watcher_win.cc
+++ b/chromium/components/storage_monitor/portable_device_watcher_win.cc
@@ -9,6 +9,7 @@
#include "components/storage_monitor/portable_device_watcher_win.h"
#include <dbt.h>
+#include <objbase.h>
#include <portabledevice.h>
#include "base/files/file_path.h"
@@ -20,7 +21,6 @@
#include "base/win/scoped_co_mem.h"
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_propvariant.h"
-#include "components/storage_monitor/media_storage_util.h"
#include "components/storage_monitor/removable_device_constants.h"
#include "components/storage_monitor/storage_info.h"
#include "content/public/browser/browser_thread.h"
@@ -123,8 +123,9 @@ bool GetDeviceDescription(const base::string16& pnp_device_id,
// application that communicates with the device.
bool GetClientInformation(
base::win::ScopedComPtr<IPortableDeviceValues>* client_info) {
- HRESULT hr = client_info->CreateInstance(__uuidof(PortableDeviceValues),
- NULL, CLSCTX_INPROC_SERVER);
+ HRESULT hr = ::CoCreateInstance(__uuidof(PortableDeviceValues), NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(client_info->GetAddressOf()));
if (FAILED(hr)) {
DPLOG(ERROR) << "Failed to create an instance of IPortableDeviceValues";
return false;
@@ -151,14 +152,15 @@ bool SetUp(const base::string16& pnp_device_id,
if (!GetClientInformation(&client_info))
return false;
- HRESULT hr = device->CreateInstance(__uuidof(PortableDevice), NULL,
- CLSCTX_INPROC_SERVER);
+ HRESULT hr =
+ ::CoCreateInstance(__uuidof(PortableDevice), NULL, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(device->GetAddressOf()));
if (FAILED(hr)) {
DPLOG(ERROR) << "Failed to create an instance of IPortableDevice";
return false;
}
- hr = (*device)->Open(pnp_device_id.c_str(), client_info.get());
+ hr = (*device)->Open(pnp_device_id.c_str(), client_info.Get());
if (SUCCEEDED(hr))
return true;
@@ -179,8 +181,9 @@ REFPROPERTYKEY GetUniqueIdPropertyKey(const base::string16& object_id) {
bool PopulatePropertyKeyCollection(
const base::string16& object_id,
base::win::ScopedComPtr<IPortableDeviceKeyCollection>* properties_to_read) {
- HRESULT hr = properties_to_read->CreateInstance(
- __uuidof(PortableDeviceKeyCollection), NULL, CLSCTX_INPROC_SERVER);
+ HRESULT hr = ::CoCreateInstance(
+ __uuidof(PortableDeviceKeyCollection), NULL, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(properties_to_read->GetAddressOf()));
if (FAILED(hr)) {
DPLOG(ERROR) << "Failed to create IPortableDeviceKeyCollection instance";
return false;
@@ -212,14 +215,14 @@ bool GetObjectUniqueId(IPortableDevice* device,
DCHECK(device);
DCHECK(unique_id);
base::win::ScopedComPtr<IPortableDeviceContent> content;
- HRESULT hr = device->Content(content.Receive());
+ HRESULT hr = device->Content(content.GetAddressOf());
if (FAILED(hr)) {
DPLOG(ERROR) << "Failed to get IPortableDeviceContent interface";
return false;
}
base::win::ScopedComPtr<IPortableDeviceProperties> properties;
- hr = content->Properties(properties.Receive());
+ hr = content->Properties(properties.GetAddressOf());
if (FAILED(hr)) {
DPLOG(ERROR) << "Failed to get IPortableDeviceProperties interface";
return false;
@@ -230,14 +233,13 @@ bool GetObjectUniqueId(IPortableDevice* device,
return false;
base::win::ScopedComPtr<IPortableDeviceValues> properties_values;
- if (FAILED(properties->GetValues(object_id.c_str(),
- properties_to_read.get(),
- properties_values.Receive()))) {
+ if (FAILED(properties->GetValues(object_id.c_str(), properties_to_read.Get(),
+ properties_values.GetAddressOf()))) {
return false;
}
REFPROPERTYKEY key = GetUniqueIdPropertyKey(object_id);
- return GetStringPropertyValue(properties_values.get(), key, unique_id);
+ return GetStringPropertyValue(properties_values.Get(), key, unique_id);
}
// Constructs the device storage unique identifier using |device_serial_num| and
@@ -263,7 +265,7 @@ bool GetRemovableStorageObjectIds(
DCHECK(device);
DCHECK(storage_object_ids);
base::win::ScopedComPtr<IPortableDeviceCapabilities> capabilities;
- HRESULT hr = device->Capabilities(capabilities.Receive());
+ HRESULT hr = device->Capabilities(capabilities.GetAddressOf());
if (FAILED(hr)) {
DPLOG(ERROR) << "Failed to get IPortableDeviceCapabilities interface";
return false;
@@ -271,7 +273,7 @@ bool GetRemovableStorageObjectIds(
base::win::ScopedComPtr<IPortableDevicePropVariantCollection> storage_ids;
hr = capabilities->GetFunctionalObjects(WPD_FUNCTIONAL_CATEGORY_STORAGE,
- storage_ids.Receive());
+ storage_ids.GetAddressOf());
if (FAILED(hr)) {
DPLOG(ERROR) << "Failed to get IPortableDevicePropVariantCollection";
return false;
@@ -336,18 +338,18 @@ bool GetDeviceStorageObjectsOnBlockingThread(
return false;
base::string16 device_serial_num;
- if (!GetObjectUniqueId(device.get(), WPD_DEVICE_OBJECT_ID,
+ if (!GetObjectUniqueId(device.Get(), WPD_DEVICE_OBJECT_ID,
&device_serial_num)) {
return false;
}
PortableDeviceWatcherWin::StorageObjectIDs storage_obj_ids;
- if (!GetRemovableStorageObjectIds(device.get(), &storage_obj_ids))
+ if (!GetRemovableStorageObjectIds(device.Get(), &storage_obj_ids))
return false;
for (PortableDeviceWatcherWin::StorageObjectIDs::const_iterator id_iter =
storage_obj_ids.begin(); id_iter != storage_obj_ids.end(); ++id_iter) {
base::string16 storage_persistent_id;
- if (!GetObjectUniqueId(device.get(), *id_iter, &storage_persistent_id))
+ if (!GetObjectUniqueId(device.Get(), *id_iter, &storage_persistent_id))
continue;
std::string device_storage_id;
@@ -387,8 +389,9 @@ bool GetDeviceInfoOnBlockingThread(
bool GetPortableDeviceManager(
base::win::ScopedComPtr<IPortableDeviceManager>* portable_device_mgr) {
DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
- HRESULT hr = portable_device_mgr->CreateInstance(
- __uuidof(PortableDeviceManager), NULL, CLSCTX_INPROC_SERVER);
+ HRESULT hr = ::CoCreateInstance(
+ __uuidof(PortableDeviceManager), NULL, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(portable_device_mgr->GetAddressOf()));
if (SUCCEEDED(hr))
return true;
@@ -423,7 +426,7 @@ bool EnumerateAttachedDevicesOnBlockingThread(
for (DWORD index = 0; index < pnp_device_count; ++index) {
PortableDeviceWatcherWin::DeviceDetails device_details;
- if (GetDeviceInfoOnBlockingThread(portable_device_mgr.get(),
+ if (GetDeviceInfoOnBlockingThread(portable_device_mgr.Get(),
pnp_device_ids[index], &device_details))
devices->push_back(device_details);
CoTaskMemFree(pnp_device_ids[index]);
@@ -446,7 +449,7 @@ bool HandleDeviceAttachedEventOnBlockingThread(
// Sometimes, portable device manager doesn't have the new device details.
// Refresh the manager device list to update its details.
portable_device_mgr->RefreshDeviceList();
- return GetDeviceInfoOnBlockingThread(portable_device_mgr.get(), pnp_device_id,
+ return GetDeviceInfoOnBlockingThread(portable_device_mgr.Get(), pnp_device_id,
device_details);
}
@@ -632,9 +635,6 @@ void PortableDeviceWatcherWin::OnDidHandleDeviceAttachEvent(
const std::string& storage_id = storage_iter->object_persistent_id;
DCHECK(!base::ContainsKey(storage_map_, storage_id));
- // Keep track of storage id and storage name to see how often we receive
- // empty values.
- MediaStorageUtil::RecordDeviceInfoHistogram(false, storage_id, name);
if (storage_id.empty() || name.empty())
return;
diff --git a/chromium/components/storage_monitor/storage_monitor_chromeos.cc b/chromium/components/storage_monitor/storage_monitor_chromeos.cc
index 228cc4408c2..edce2a560fd 100644
--- a/chromium/components/storage_monitor/storage_monitor_chromeos.cc
+++ b/chromium/components/storage_monitor/storage_monitor_chromeos.cc
@@ -57,10 +57,6 @@ bool GetDeviceInfo(const DiskMountManager::MountPointInfo& mount_info,
return false;
std::string unique_id = MakeDeviceUniqueId(*disk);
- // Keep track of device uuid and label, to see how often we receive empty
- // values.
- base::string16 device_label = base::UTF8ToUTF16(disk->device_label());
- MediaStorageUtil::RecordDeviceInfoHistogram(true, unique_id, device_label);
if (unique_id.empty())
return false;
@@ -68,12 +64,11 @@ bool GetDeviceInfo(const DiskMountManager::MountPointInfo& mount_info,
StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM :
StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM;
- *info = StorageInfo(StorageInfo::MakeDeviceId(type, unique_id),
- mount_info.mount_path,
- device_label,
- base::UTF8ToUTF16(disk->vendor_name()),
- base::UTF8ToUTF16(disk->product_name()),
- disk->total_size_in_bytes());
+ *info = StorageInfo(
+ StorageInfo::MakeDeviceId(type, unique_id), mount_info.mount_path,
+ base::UTF8ToUTF16(disk->device_label()),
+ base::UTF8ToUTF16(disk->vendor_name()),
+ base::UTF8ToUTF16(disk->product_name()), disk->total_size_in_bytes());
return true;
}
diff --git a/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc b/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc
index 5ffb3f8eacb..e644d2766ec 100644
--- a/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc
+++ b/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc
@@ -13,6 +13,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/disks/mock_disk_mount_manager.h"
diff --git a/chromium/components/storage_monitor/storage_monitor_linux.cc b/chromium/components/storage_monitor/storage_monitor_linux.cc
index 1bbffa9e65e..f0f53d70182 100644
--- a/chromium/components/storage_monitor/storage_monitor_linux.cc
+++ b/chromium/components/storage_monitor/storage_monitor_linux.cc
@@ -15,6 +15,7 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
@@ -54,11 +55,6 @@ const char kVendorID[] = "ID_VENDOR_ID";
// Construct a device id using label or manufacturer (vendor and model) details.
std::string MakeDeviceUniqueId(struct udev_device* device) {
std::string uuid = device::UdevDeviceGetPropertyValue(device, kFsUUID);
- // Keep track of device uuid, to see how often we receive empty uuid values.
- UMA_HISTOGRAM_BOOLEAN(
- "RemovableDeviceNotificationsLinux.device_file_system_uuid_available",
- !uuid.empty());
-
if (!uuid.empty())
return kFSUniqueIdPrefix + uuid;
@@ -104,12 +100,6 @@ uint64_t GetDeviceStorageSize(const base::FilePath& device_path,
const std::string partition_size =
device::UdevDeviceGetSysattrValue(device, kSizeSysAttr);
- // Keep track of device size, to see how often this information is
- // unavailable.
- UMA_HISTOGRAM_BOOLEAN(
- "RemovableDeviceNotificationsLinux.device_partition_size_available",
- !partition_size.empty());
-
uint64_t total_size_in_bytes = 0;
if (!base::StringToUint64(partition_size, &total_size_in_bytes))
return 0;
@@ -158,10 +148,6 @@ std::unique_ptr<StorageInfo> GetDeviceInfo(const base::FilePath& device_path,
device::UdevDeviceGetPropertyValue(device.get(), kModel));
std::string unique_id = MakeDeviceUniqueId(device.get());
-
- // Keep track of device info details to see how often we get invalid values.
- MediaStorageUtil::RecordDeviceInfoHistogram(true, unique_id, volume_label);
-
const char* value =
device::udev_device_get_sysattr_value(device.get(), kRemovableSysAttr);
if (!value) {
@@ -179,21 +165,17 @@ std::unique_ptr<StorageInfo> GetDeviceInfo(const base::FilePath& device_path,
StorageInfo::Type type = StorageInfo::FIXED_MASS_STORAGE;
if (is_removable) {
- if (MediaStorageUtil::HasDcim(mount_point))
- type = StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM;
- else
- type = StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM;
+ type = MediaStorageUtil::HasDcim(mount_point)
+ ? StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
+ : StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM;
}
results_recorder.set_result(true);
- storage_info.reset(new StorageInfo(
- StorageInfo::MakeDeviceId(type, unique_id),
- mount_point.value(),
- volume_label,
- vendor_name,
- model_name,
- GetDeviceStorageSize(device_path, device.get())));
+ storage_info = base::MakeUnique<StorageInfo>(
+ StorageInfo::MakeDeviceId(type, unique_id), mount_point.value(),
+ volume_label, vendor_name, model_name,
+ GetDeviceStorageSize(device_path, device.get()));
return storage_info;
}
diff --git a/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc b/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc
index 769d46e19d0..7c3b223c87b 100644
--- a/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc
+++ b/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc
@@ -18,6 +18,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/storage_monitor/storage_monitor_mac.mm b/chromium/components/storage_monitor/storage_monitor_mac.mm
index 47d91355feb..a48b02493f3 100644
--- a/chromium/components/storage_monitor/storage_monitor_mac.mm
+++ b/chromium/components/storage_monitor/storage_monitor_mac.mm
@@ -238,8 +238,6 @@ void StorageMonitorMac::UpdateDisk(
disk_info_map_.erase(it);
} else {
disk_info_map_[bsd_name] = info;
- MediaStorageUtil::RecordDeviceInfoHistogram(true, info.device_id(),
- info.storage_label());
if (ShouldPostNotificationForDisk(info))
receiver()->ProcessAttach(info);
}
diff --git a/chromium/components/storage_monitor/storage_monitor_win_unittest.cc b/chromium/components/storage_monitor/storage_monitor_win_unittest.cc
index 70f6d6c1826..1202054da1b 100644
--- a/chromium/components/storage_monitor/storage_monitor_win_unittest.cc
+++ b/chromium/components/storage_monitor/storage_monitor_win_unittest.cc
@@ -26,12 +26,11 @@
#include "components/storage_monitor/test_storage_monitor_win.h"
#include "components/storage_monitor/test_volume_mount_watcher_win.h"
#include "components/storage_monitor/volume_mount_watcher_win.h"
-#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
-using content::BrowserThread;
typedef std::vector<int> DeviceIndices;
@@ -51,9 +50,6 @@ class StorageMonitorWinTest : public testing::Test {
void PreAttachDevices();
- // Runs all the pending tasks on UI thread, FILE thread and blocking thread.
- void RunUntilIdle();
-
void DoMassStorageDeviceAttachedTest(const DeviceIndices& device_indices);
void DoMassStorageDevicesDetachedTest(const DeviceIndices& device_indices);
@@ -93,12 +89,12 @@ void StorageMonitorWinTest::SetUp() {
new TestPortableDeviceWatcherWin));
monitor_->Init();
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
monitor_->AddObserver(&observer_);
}
void StorageMonitorWinTest::TearDown() {
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
monitor_->RemoveObserver(&observer_);
// Windows storage monitor must be destroyed on the same thread
@@ -130,11 +126,7 @@ void StorageMonitorWinTest::PreAttachDevices() {
EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
- // This dance is because attachment bounces through a couple of
- // closures, which need to be executed to finish the process.
- RunUntilIdle();
- volume_mount_watcher_->FlushWorkerPoolForTesting();
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
std::vector<base::FilePath> checked_devices =
volume_mount_watcher_->devices_checked();
@@ -144,11 +136,6 @@ void StorageMonitorWinTest::PreAttachDevices() {
EXPECT_EQ(0, observer_.detach_calls());
}
-void StorageMonitorWinTest::RunUntilIdle() {
- volume_mount_watcher_->FlushWorkerPoolForTesting();
- base::RunLoop().RunUntilIdle();
-}
-
void StorageMonitorWinTest::DoMassStorageDeviceAttachedTest(
const DeviceIndices& device_indices) {
DEV_BROADCAST_VOLUME volume_broadcast;
@@ -170,9 +157,7 @@ void StorageMonitorWinTest::DoMassStorageDeviceAttachedTest(
monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
reinterpret_cast<LPARAM>(&volume_broadcast));
- RunUntilIdle();
- volume_mount_watcher_->FlushWorkerPoolForTesting();
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
EXPECT_EQ(0, observer_.detach_calls());
@@ -199,7 +184,7 @@ void StorageMonitorWinTest::DoMassStorageDevicesDetachedTest(
}
monitor_->InjectDeviceChange(DBT_DEVICEREMOVECOMPLETE,
reinterpret_cast<LPARAM>(&volume_broadcast));
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
EXPECT_EQ(pre_attach_calls, observer_.attach_calls());
EXPECT_EQ(expect_detach_calls, observer_.detach_calls());
}
@@ -246,7 +231,7 @@ void StorageMonitorWinTest::DoMTPDeviceTest(const base::string16& pnp_device_id,
test_attach ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE,
reinterpret_cast<LPARAM>(dev_interface_broadcast.get()));
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
EXPECT_EQ(expect_detach_calls, observer_.detach_calls());
}
@@ -262,7 +247,7 @@ bool StorageMonitorWinTest::GetMTPStorageInfo(
TEST_F(StorageMonitorWinTest, RandomMessage) {
monitor_->InjectDeviceChange(DBT_DEVICEQUERYREMOVE, NULL);
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(StorageMonitorWinTest, DevicesAttached) {
@@ -309,7 +294,7 @@ TEST_F(StorageMonitorWinTest, PathMountDevices) {
volume_mount_watcher_->AddDeviceForTesting(
base::FilePath(FILE_PATH_LITERAL("F:\\mount2")),
"dcim:mount2", L"mount2", 100);
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
EXPECT_EQ(init_storages + 3, monitor_->GetAllAvailableStorages().size());
StorageInfo info;
@@ -405,9 +390,7 @@ TEST_F(StorageMonitorWinTest, DevicesDetachedAdjacentBits) {
TEST_F(StorageMonitorWinTest, DuplicateAttachCheckSuppressed) {
// Make sure the original C: mount notification makes it all the
// way through.
- RunUntilIdle();
- volume_mount_watcher_->FlushWorkerPoolForTesting();
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
volume_mount_watcher_->BlockDeviceCheckForTesting();
base::FilePath kAttachedDevicePath =
@@ -431,13 +414,12 @@ TEST_F(StorageMonitorWinTest, DuplicateAttachCheckSuppressed) {
EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
volume_mount_watcher_->ReleaseDeviceCheck();
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
volume_mount_watcher_->ReleaseDeviceCheck();
// Now let all attach notifications finish running. We'll only get one
// finish-attach call.
- volume_mount_watcher_->FlushWorkerPoolForTesting();
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
const std::vector<base::FilePath>& checked_devices =
volume_mount_watcher_->devices_checked();
@@ -447,9 +429,9 @@ TEST_F(StorageMonitorWinTest, DuplicateAttachCheckSuppressed) {
// We'll receive a duplicate check now that the first check has fully cleared.
monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
reinterpret_cast<LPARAM>(&volume_broadcast));
- volume_mount_watcher_->FlushWorkerPoolForTesting();
+ content::RunAllBlockingPoolTasksUntilIdle();
volume_mount_watcher_->ReleaseDeviceCheck();
- RunUntilIdle();
+ content::RunAllBlockingPoolTasksUntilIdle();
ASSERT_EQ(2u, checked_devices.size());
EXPECT_EQ(kAttachedDevicePath, checked_devices[0]);
diff --git a/chromium/components/storage_monitor/test_volume_mount_watcher_win.cc b/chromium/components/storage_monitor/test_volume_mount_watcher_win.cc
index 36815463c9b..79521095a34 100644
--- a/chromium/components/storage_monitor/test_volume_mount_watcher_win.cc
+++ b/chromium/components/storage_monitor/test_volume_mount_watcher_win.cc
@@ -10,9 +10,7 @@
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "components/storage_monitor/storage_info.h"
-#include "content/public/browser/browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace storage_monitor {
@@ -110,10 +108,6 @@ void TestVolumeMountWatcherWin::SetAttachedDevicesFake() {
attached_devices_fake_ = true;
}
-void TestVolumeMountWatcherWin::FlushWorkerPoolForTesting() {
- content::BrowserThread::GetBlockingPool()->FlushForTesting();
-}
-
void TestVolumeMountWatcherWin::DeviceCheckComplete(
const base::FilePath& device_path) {
devices_checked_.push_back(device_path);
diff --git a/chromium/components/storage_monitor/test_volume_mount_watcher_win.h b/chromium/components/storage_monitor/test_volume_mount_watcher_win.h
index 89bbeecf330..9445433bee4 100644
--- a/chromium/components/storage_monitor/test_volume_mount_watcher_win.h
+++ b/chromium/components/storage_monitor/test_volume_mount_watcher_win.h
@@ -40,8 +40,6 @@ class TestVolumeMountWatcherWin : public VolumeMountWatcherWin {
void SetAttachedDevicesFake();
- void FlushWorkerPoolForTesting();
-
const std::vector<base::FilePath>& devices_checked() const {
return devices_checked_;
}
diff --git a/chromium/components/storage_monitor/volume_mount_watcher_win.cc b/chromium/components/storage_monitor/volume_mount_watcher_win.cc
index 5ac0b111395..b8b29fa9352 100644
--- a/chromium/components/storage_monitor/volume_mount_watcher_win.cc
+++ b/chromium/components/storage_monitor/volume_mount_watcher_win.cc
@@ -16,7 +16,6 @@
#include <algorithm>
#include "base/bind_helpers.h"
-#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -24,7 +23,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
#include "base/time/time.h"
#include "base/win/scoped_handle.h"
#include "components/storage_monitor/media_storage_util.h"
@@ -39,23 +38,12 @@ namespace {
const DWORD kMaxPathBufLen = MAX_PATH + 1;
-const char kDeviceInfoTaskRunnerName[] = "device-info-task-runner";
-
enum DeviceType {
FLOPPY,
REMOVABLE,
FIXED,
};
-// Histogram values for recording frequencies of eject attempts and
-// outcomes.
-enum EjectWinLockOutcomes {
- LOCK_ATTEMPT,
- LOCK_TIMEOUT,
- LOCK_TIMEOUT2,
- NUM_LOCK_OUTCOMES,
-};
-
// We are trying to figure out whether the drive is a fixed volume,
// a removable storage, or a floppy. A "floppy" here means "a volume we
// want to basically ignore because it won't fit media and will spin
@@ -262,12 +250,7 @@ void EjectDeviceInThreadPool(
// handle is closed, and this is done by the ScopedHandle above.
BOOL locked = DeviceIoControl(volume_handle.Get(), FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0, &bytes_returned, NULL);
- UMA_HISTOGRAM_ENUMERATION("StorageMonitor.EjectWinLock",
- LOCK_ATTEMPT, NUM_LOCK_OUTCOMES);
if (!locked) {
- UMA_HISTOGRAM_ENUMERATION("StorageMonitor.EjectWinLock",
- iteration == 0 ? LOCK_TIMEOUT : LOCK_TIMEOUT2,
- NUM_LOCK_OUTCOMES);
const int kNumLockRetries = 1;
const base::TimeDelta kLockRetryInterval =
base::TimeDelta::FromMilliseconds(500);
@@ -332,12 +315,11 @@ void EjectDeviceInThreadPool(
} // namespace
VolumeMountWatcherWin::VolumeMountWatcherWin()
- : notifications_(NULL), weak_factory_(this) {
- base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
- device_info_task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior(
- pool->GetNamedSequenceToken(kDeviceInfoTaskRunnerName),
- base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
-}
+ : device_info_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
+ notifications_(nullptr),
+ weak_factory_(this) {}
// static
base::FilePath VolumeMountWatcherWin::DriveNumberToFilePath(int drive_number) {
diff --git a/chromium/components/storage_monitor/volume_mount_watcher_win.h b/chromium/components/storage_monitor/volume_mount_watcher_win.h
index 2d183d88f5e..ca164afa338 100644
--- a/chromium/components/storage_monitor/volume_mount_watcher_win.h
+++ b/chromium/components/storage_monitor/volume_mount_watcher_win.h
@@ -90,7 +90,7 @@ class VolumeMountWatcherWin {
virtual GetDeviceDetailsCallbackType GetDeviceDetailsCallback() const;
// Used for device info calls that may take a long time.
- scoped_refptr<base::SequencedTaskRunner> device_info_task_runner_;
+ const scoped_refptr<base::SequencedTaskRunner> device_info_task_runner_;
private:
friend class TestVolumeMountWatcherWin;
diff --git a/chromium/components/strings/components_chromium_strings_am.xtb b/chromium/components/strings/components_chromium_strings_am.xtb
index 86589135382..7312aa8fd1a 100644
--- a/chromium/components/strings/components_chromium_strings_am.xtb
+++ b/chromium/components/strings/components_chromium_strings_am.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="am">
<translation id="130631256467250065">ለá‹áŒ¦á‰½á‹Ž መሣሪያዎን ዳáŒáˆ በሚያስጀáˆáˆ©á‰ á‰µ ቀጣዩ ጊዜ ላይ ይተገበራሉá¢</translation>
+<translation id="1838412507805038478">Chromium የዚህ ድር ጣቢያ እá‹á‰…ና ማረጋገጫ ያወጣዠ<ph name="ISSUER" /> መሆኑን አረጋáŒáŒ§áˆá¢</translation>
<translation id="275588974610408078">የብáˆáˆ½á‰µ ሪá–ርት በChromium á‹áˆµáŒ¥ አይገáŠáˆá¢</translation>
<translation id="3064346599913645280">ደህንáŠá‰± የተጠበቀ የChromium ገጽ እየተመለከቱ áŠá‹</translation>
<translation id="3550966579244642892">Chromium OS የመጀመሪያ á‹á‰…ሩን አላጠናቀቀáˆá¢</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ar.xtb b/chromium/components/strings/components_chromium_strings_ar.xtb
index 8b9d90ba2da..e34fbb7a576 100644
--- a/chromium/components/strings/components_chromium_strings_ar.xtb
+++ b/chromium/components/strings/components_chromium_strings_ar.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ar">
<translation id="130631256467250065">تسري التغييرات ÙÙŠ المرة التالية التي تعيد Ùيها تشغيل الجهاز.</translation>
+<translation id="1838412507805038478">â€Ù„قد تحقق Chromium من أن <ph name="ISSUER" /> أصدر شهادة موقع الويب هذه.</translation>
<translation id="275588974610408078">â€ØªÙ‚ارير الأعطال غير متاحة ÙÙŠ Chromium.</translation>
<translation id="3064346599913645280">â€Ø£Ù†Øª تعرض صÙحة Chromium آمنة</translation>
<translation id="3550966579244642892">â€Ù„Ù… ينته نظام تشغيل Chromium من إعداده المبدئي.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_bg.xtb b/chromium/components/strings/components_chromium_strings_bg.xtb
index 50743bf43b7..611d0d98007 100644
--- a/chromium/components/strings/components_chromium_strings_bg.xtb
+++ b/chromium/components/strings/components_chromium_strings_bg.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="bg">
<translation id="130631256467250065">Промените ви ще влÑзат в Ñила ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ð¿ÑŠÑ‚, когато реÑтартирате уÑтройÑтвото Ñи.</translation>
+<translation id="1838412507805038478">Chromium потвърди, че Ñертификатът на този уебÑайт е издаден от <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Подаването на Ñигнали за Ñривове не е налице в Chromium.</translation>
<translation id="3064346599913645280">Преглеждате защитена Ñтраница в Chromium.</translation>
<translation id="3550966579244642892">Първоначалното наÑтройване на Chromium OS не е завършено.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_bn.xtb b/chromium/components/strings/components_chromium_strings_bn.xtb
index b2b336cb219..38cc3ffee48 100644
--- a/chromium/components/strings/components_chromium_strings_bn.xtb
+++ b/chromium/components/strings/components_chromium_strings_bn.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="bn">
<translation id="130631256467250065">পরের বার আপনি আপনার ডিভাইস পà§à¦¨à¦°à¦¾à¦°à¦®à§à¦­ করলে আপনার পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ পà§à¦°à¦­à¦¾à¦¬à§€ হবে৷</translation>
+<translation id="1838412507805038478"><ph name="ISSUER" /> যে à¦à¦‡ ওয়েবসাইটের শংসাপতà§à¦° পà§à¦°à¦•à¦¾à¦¶ করেছে Chromium তা যাচাই করেছে।</translation>
<translation id="275588974610408078">Chromium-ঠকà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ উপলবà§à¦§ নেই৷</translation>
<translation id="3064346599913645280">আপনি à¦à¦•à¦Ÿà¦¿ নিরাপদ Chromium পৃষà§à¦ à¦¾ দেখছেন</translation>
<translation id="3550966579244642892">Chromium OS তার পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• সেটআপ সমà§à¦ªà§‚রà§à¦£ করেনি।</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ca.xtb b/chromium/components/strings/components_chromium_strings_ca.xtb
index 8818aa60a9b..88a6815ee27 100644
--- a/chromium/components/strings/components_chromium_strings_ca.xtb
+++ b/chromium/components/strings/components_chromium_strings_ca.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ca">
<translation id="130631256467250065">Els canvis es faran efectius la propera vegada que reinicieu el dispositiu.</translation>
+<translation id="1838412507805038478">Chromium ha verificat que <ph name="ISSUER" /> ha emès el certificat d'aquest lloc web.</translation>
<translation id="275588974610408078">La creació d'informes de bloqueig no està disponible a Chromium.</translation>
<translation id="3064346599913645280">Estàs visualitzant una pàgina segura de Chromium</translation>
<translation id="3550966579244642892">Chromium OS no ha completat la configuració inicial.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_cs.xtb b/chromium/components/strings/components_chromium_strings_cs.xtb
index c50ebd53a36..7190bdf4ee2 100644
--- a/chromium/components/strings/components_chromium_strings_cs.xtb
+++ b/chromium/components/strings/components_chromium_strings_cs.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="cs">
<translation id="130631256467250065">Změny se projeví po příštím restartu zařízení.</translation>
+<translation id="1838412507805038478">ProhlížeÄ Chromium ověřil, že certifikát tohoto webu byl vydán vydavatelem <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Hlášení o selhání není v prohlížeÄi Chromium k dispozici.</translation>
<translation id="3064346599913645280">Prohlížíte si zabezpeÄenou stránku vygenerovanou prohlížeÄem Chromium</translation>
<translation id="3550966579244642892">Systém Chromium OS nedokonÄil úvodní nastavení.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_da.xtb b/chromium/components/strings/components_chromium_strings_da.xtb
index 6536b5a4a9d..29efef81cb9 100644
--- a/chromium/components/strings/components_chromium_strings_da.xtb
+++ b/chromium/components/strings/components_chromium_strings_da.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="da">
<translation id="130631256467250065">Dine ændringer træder i kraft, næste gang du genstarter din enhed.</translation>
+<translation id="1838412507805038478">Chromium har bekræftet, at <ph name="ISSUER" /> har udstedt certifikatet for dette website.</translation>
<translation id="275588974610408078">Nedbrudsrapportering er ikke tilgængeligt i Chromium.</translation>
<translation id="3064346599913645280">Du ser en sikker Chromium-side</translation>
<translation id="3550966579244642892">Chromium OS har ikke gennemført sin indledende konfiguration.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_de.xtb b/chromium/components/strings/components_chromium_strings_de.xtb
index 80870c4d516..5c7c3774c9b 100644
--- a/chromium/components/strings/components_chromium_strings_de.xtb
+++ b/chromium/components/strings/components_chromium_strings_de.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="de">
<translation id="130631256467250065">Ihre Änderungen werden beim nächsten Neustart wirksam.</translation>
+<translation id="1838412507805038478">Chromium hat verifiziert, dass <ph name="ISSUER" /> das Zertifikat dieser Website ausgestellt hat.</translation>
<translation id="275588974610408078">Absturzberichte sind in Chromium nicht verfügbar.</translation>
<translation id="3064346599913645280">Dies ist eine sichere Chromium-Seite</translation>
<translation id="3550966579244642892">Die Ersteinrichtung von Chromium OS wurde nicht abgeschlossen.</translation>
@@ -18,6 +19,6 @@
und deaktivieren Sie "<ph name="NO_PREFETCH_DESCRIPTION" />".
Falls das Problem nicht dadurch verursacht wurde, empfehlen wir,
diese Option für eine verbesserte Leistung wieder zu aktivieren.</translation>
-<translation id="8187289872471304532">Gehen Sie zu "Anwendungen" &gt; "Systemeinstellungen" &gt; "Netzwerk" &gt; "Erweitert" &gt; "Proxys" und deaktivieren Sie alle ausgewählten Proxyserver.</translation>
+<translation id="8187289872471304532">Gehen Sie zu "Programme" &gt; "Systemeinstellungen" &gt; "Netzwerk" &gt; "Erweitert" &gt; "Proxys" und deaktivieren Sie alle ausgewählten Proxyserver.</translation>
<translation id="8684913864886094367">Chromium wurde nicht richtig beendet.</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_el.xtb b/chromium/components/strings/components_chromium_strings_el.xtb
index 07a838fce3d..99cee503af5 100644
--- a/chromium/components/strings/components_chromium_strings_el.xtb
+++ b/chromium/components/strings/components_chromium_strings_el.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="el">
<translation id="130631256467250065">Οι αλλαγές σας θα εφαÏμοστοÏν την επόμενη φοÏά που θα επανεκκινήσετε τη συσκευή σας.</translation>
+<translation id="1838412507805038478">Το Chromium επαλήθευσε ότι το πιστοποιητικό Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… ιστότοπου εκδόθηκε από τον/τη(ν) <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Η αναφοÏά σφαλμάτων δεν είναι διαθέσιμη στο Chromium.</translation>
<translation id="3064346599913645280">Βλέπετε μια ασφαλή σελίδα Chromium</translation>
<translation id="3550966579244642892">Το Chromium OS δεν ολοκλήÏωσε την αÏχική του ÏÏθμιση.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_en-GB.xtb b/chromium/components/strings/components_chromium_strings_en-GB.xtb
index 54a33f8dcc4..a84ee86c770 100644
--- a/chromium/components/strings/components_chromium_strings_en-GB.xtb
+++ b/chromium/components/strings/components_chromium_strings_en-GB.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="en-GB">
<translation id="130631256467250065">Your changes will take effect the next time that you restart your device.</translation>
+<translation id="1838412507805038478">Chromium verified that <ph name="ISSUER" /> issued this website's certificate.</translation>
<translation id="275588974610408078">Crash reporting is not available in Chromium.</translation>
<translation id="3064346599913645280">You're viewing a secure Chromium page</translation>
<translation id="3550966579244642892">Chromium OS hasn’t completed its initial setup.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_es-419.xtb b/chromium/components/strings/components_chromium_strings_es-419.xtb
index 5377f18118b..aa7e53d7bc9 100644
--- a/chromium/components/strings/components_chromium_strings_es-419.xtb
+++ b/chromium/components/strings/components_chromium_strings_es-419.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="es-419">
<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="1838412507805038478">Chromium verificó que <ph name="ISSUER" /> emitió el certificado de este sitio web.</translation>
<translation id="275588974610408078">El informe sobre fallos no está disponible en Chromium.</translation>
<translation id="3064346599913645280">Estás viendo una página de Chromium segura</translation>
<translation id="3550966579244642892">No se completó la configuración inicial del sistema operativo Chromium.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_es.xtb b/chromium/components/strings/components_chromium_strings_es.xtb
index 8aabfa86432..1f1d217ed0e 100644
--- a/chromium/components/strings/components_chromium_strings_es.xtb
+++ b/chromium/components/strings/components_chromium_strings_es.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="es">
<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="1838412507805038478">Chromium ha verificado que <ph name="ISSUER" /> emitió el certificado de este sitio web.</translation>
<translation id="275588974610408078">Los informes de errores no se encuentran disponibles en Chromium.</translation>
<translation id="3064346599913645280">Estás viendo una página de Chromium segura</translation>
<translation id="3550966579244642892">No se ha completado la configuración inicial de Chromium OS.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_et.xtb b/chromium/components/strings/components_chromium_strings_et.xtb
index c25ab0ef256..ca7dfcd9444 100644
--- a/chromium/components/strings/components_chromium_strings_et.xtb
+++ b/chromium/components/strings/components_chromium_strings_et.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="et">
<translation id="130631256467250065">Muudatused jõustuvad järgmine kord, kui seadme taaskäivitate.</translation>
+<translation id="1838412507805038478">Chromium kinnitas, et veebisaidi sertifikaadi väljastas <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Krahhiaruandlus ei ole Chromiumis saadaval.</translation>
<translation id="3064346599913645280">Vaatate turvalist Chromiumi lehte</translation>
<translation id="3550966579244642892">Chromium OS pole algseadistust lõpetanud.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_fa.xtb b/chromium/components/strings/components_chromium_strings_fa.xtb
index 5d2463f606b..1d0830d7fcb 100644
--- a/chromium/components/strings/components_chromium_strings_fa.xtb
+++ b/chromium/components/strings/components_chromium_strings_fa.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fa">
<translation id="130631256467250065">تغییرات بار بعد که دستگاه راه‌اندازی می‌شود اعمال می‌شوند.</translation>
+<translation id="1838412507805038478">â€Chromium تأیید کرد Ú©Ù‡ <ph name="ISSUER" /> گواهینامه این وب‌سایت را صادر کرده است.</translation>
<translation id="275588974610408078">â€Ú¯Ø²Ø§Ø±Ø´ خرابی در Chromium موجود نیست.</translation>
<translation id="3064346599913645280">â€Ø¯Ø±Ø­Ø§Ù„ مشاهده یک صÙحه Chromium امن هستید</translation>
<translation id="3550966579244642892">â€Ø±Ø§Ù‡â€ŒØ§Ù†Ø¯Ø§Ø²ÛŒ اولیه سیستم‌عامل Chromium تمام نشده است.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_fi.xtb b/chromium/components/strings/components_chromium_strings_fi.xtb
index 76d0ab239c5..8da4ffa8d9b 100644
--- a/chromium/components/strings/components_chromium_strings_fi.xtb
+++ b/chromium/components/strings/components_chromium_strings_fi.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fi">
<translation id="130631256467250065">Muutokset tulevat voimaan, kun käynnistät laitteen seuraavan kerran.</translation>
+<translation id="1838412507805038478">Chromium vahvisti, että <ph name="ISSUER" /> on myöntänyt tämän sivuston varmenteen.</translation>
<translation id="275588974610408078">Virheraportit eivät ole käytettävissä Chromiumissa.</translation>
<translation id="3064346599913645280">Tämä on suojattu Chromium-sivu</translation>
<translation id="3550966579244642892">Chromium-käyttöjärjestelmä ei ole suorittanut alkuasetuksia.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_fil.xtb b/chromium/components/strings/components_chromium_strings_fil.xtb
index 6f9e24d8eec..fe32fe075b8 100644
--- a/chromium/components/strings/components_chromium_strings_fil.xtb
+++ b/chromium/components/strings/components_chromium_strings_fil.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fil">
<translation id="130631256467250065">Magkakabisa ang iyong mga pagbabago sa susunod na i-restart ang iyong device.</translation>
+<translation id="1838412507805038478">Na-verify ng Chromium na ang <ph name="ISSUER" /> ang nag-isyu ng certificate ng website na ito.</translation>
<translation id="275588974610408078">Hindi available ang pag-uulat ng crash sa Chromium.</translation>
<translation id="3064346599913645280">Isang ligtas na page ng Chromium ang tinitingnan mo</translation>
<translation id="3550966579244642892">Hindi pa nakukumpleto ng Chromium OS ang paunang setup nito.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_fr.xtb b/chromium/components/strings/components_chromium_strings_fr.xtb
index 4a71940da73..c1277b13ebd 100644
--- a/chromium/components/strings/components_chromium_strings_fr.xtb
+++ b/chromium/components/strings/components_chromium_strings_fr.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fr">
<translation id="130631256467250065">Vos modifications seront prises en compte au prochain démarrage de l'appareil.</translation>
+<translation id="1838412507805038478">Chromium a confirmé que le certificat de ce site Web a bien été émis par <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Les rapports sur les plantages ne sont pas disponibles dans Chromium.</translation>
<translation id="3064346599913645280">Cette page Chromium est sécurisée</translation>
<translation id="3550966579244642892">La configuration initiale de Chromium OS n'est pas terminée.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_gu.xtb b/chromium/components/strings/components_chromium_strings_gu.xtb
index 52cad5aad18..b240f96b188 100644
--- a/chromium/components/strings/components_chromium_strings_gu.xtb
+++ b/chromium/components/strings/components_chromium_strings_gu.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="gu">
<translation id="130631256467250065">તમારા ફેરફારો તમે આગલી વખતે તમારા ઉપકરણને ફરી પà«àª°àª¾àª°àª‚ભ કરશો તà«àª¯àª¾àª°à«‡ પà«àª°àª­àª¾àªµàª®àª¾àª‚ આવશે.</translation>
+<translation id="1838412507805038478">Chromium ઠચકાસણી કરી છે કે <ph name="ISSUER" /> ઠઆ વેબસાઇટનà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° જારી કરà«àª¯à«àª‚ છે.</translation>
<translation id="275588974610408078">Chromium માં કà«àª°à«‡àª¶ રિપોરà«àªŸàª¿àª‚ગ ઉપલબà«àª§ નથી.</translation>
<translation id="3064346599913645280">તને àªàª• સà«àª°àª•à«àª·àª¿àª¤ Chromium પૃષà«àª  જોઈ રહà«àª¯àª¾àª‚ છો</translation>
<translation id="3550966579244642892">Chromium OS ઠતેનà«àª‚ પà«àª°àª¾àª°àª‚ભિક સેટઅપ પૂરà«àª£ કરà«àª¯à«àª‚ નથી.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_hi.xtb b/chromium/components/strings/components_chromium_strings_hi.xtb
index 7d19eab588c..6a59ea8701d 100644
--- a/chromium/components/strings/components_chromium_strings_hi.xtb
+++ b/chromium/components/strings/components_chromium_strings_hi.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="hi">
<translation id="130631256467250065">अगली बार अपना डिवाइस पà¥à¤¨: पà¥à¤°à¤¾à¤°à¤‚भ करने पर आपके परिवरà¥à¤¤à¤¨ पà¥à¤°à¤­à¤¾à¤µà¥€ हो जाà¤à¤‚गे.</translation>
+<translation id="1838412507805038478">कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® ने सतà¥â€à¤¯à¤¾à¤ªà¤¿à¤¤ किया है कि इस वेबसाइट का पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° <ph name="ISSUER" /> ने जारी किया है.</translation>
<translation id="275588974610408078">कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® में कà¥à¤°à¥ˆà¤¶ की रिपोरà¥à¤Ÿ करना उपलबà¥à¤§ नहीं है.</translation>
<translation id="3064346599913645280">आप à¤à¤• सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ Chromium पेज देख रहे हैं</translation>
<translation id="3550966579244642892">Chromium OS ने अपना आरंभिक सेटअप पूरà¥à¤£ नहीं किया है.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_hr.xtb b/chromium/components/strings/components_chromium_strings_hr.xtb
index 517a8a19cdf..66bc9fa8300 100644
--- a/chromium/components/strings/components_chromium_strings_hr.xtb
+++ b/chromium/components/strings/components_chromium_strings_hr.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="hr">
<translation id="130631256467250065">Promjene će poÄeti vrijediti sljedeći put kad ponovo pokrenete ureÄ‘aj.</translation>
+<translation id="1838412507805038478">Chromium je potvrdio da je <ph name="ISSUER" /> izdao certifikat web-lokacije.</translation>
<translation id="275588974610408078">Prijavljivanje padova nije dostupno u pregledniku Chromium.</translation>
<translation id="3064346599913645280">Gledate sigurnu stranicu Chromiuma</translation>
<translation id="3550966579244642892">OS Chromium nije dovrÅ¡io poÄetno postavljanje.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_hu.xtb b/chromium/components/strings/components_chromium_strings_hu.xtb
index dc58ee36e2b..86cacb88bac 100644
--- a/chromium/components/strings/components_chromium_strings_hu.xtb
+++ b/chromium/components/strings/components_chromium_strings_hu.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="hu">
<translation id="130631256467250065">A módosítások az eszköz következő újraindításakor lépnek életbe.</translation>
+<translation id="1838412507805038478">A Chromium ellenőrizte, hogy a(z) <ph name="ISSUER" /> adta ki ezt a webhelytanúsítványt.</translation>
<translation id="275588974610408078">A hibajelentések nem állnak rendelkezésre a Chromiumban.</translation>
<translation id="3064346599913645280">Jelenleg biztonságos Chromium-oldalt tekint meg</translation>
<translation id="3550966579244642892">A Chromium OS nem fejezte be a kezdeti beállítását.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_id.xtb b/chromium/components/strings/components_chromium_strings_id.xtb
index ead6779c345..8e1251e365f 100644
--- a/chromium/components/strings/components_chromium_strings_id.xtb
+++ b/chromium/components/strings/components_chromium_strings_id.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="id">
<translation id="130631256467250065">Perubahan Anda akan diterapkan pada saat Anda nanti menyalakan ulang perangkat.</translation>
+<translation id="1838412507805038478">Chromium memverifikasi bahwa <ph name="ISSUER" /> menerbitkan sertifikat situs web ini.</translation>
<translation id="275588974610408078">Pelaporan kerusakan tidak tersedia di Chromium.</translation>
<translation id="3064346599913645280">Anda melihat halaman Chromium yang aman</translation>
<translation id="3550966579244642892">Chromium OS belum menyelesaikan penyiapan awal.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_it.xtb b/chromium/components/strings/components_chromium_strings_it.xtb
index 5637e0293a7..0f89fff34b0 100644
--- a/chromium/components/strings/components_chromium_strings_it.xtb
+++ b/chromium/components/strings/components_chromium_strings_it.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="it">
<translation id="130631256467250065">Le modifiche verranno applicate al successivo riavvio del dispositivo.</translation>
+<translation id="1838412507805038478">Chromium ha verificato che il certificato del sito web è stato emesso da <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">I rapporti sugli arresti anomali non sono disponibili in Chromium.</translation>
<translation id="3064346599913645280">È visualizzata una pagina protetta di Chromium</translation>
<translation id="3550966579244642892">La configurazione iniziale di Chromium OS non è stata completata.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_iw.xtb b/chromium/components/strings/components_chromium_strings_iw.xtb
index 9da3fea092b..e35aa26d9e8 100644
--- a/chromium/components/strings/components_chromium_strings_iw.xtb
+++ b/chromium/components/strings/components_chromium_strings_iw.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="iw">
<translation id="130631256467250065">×”×©×™× ×•×™×™× ×™×™×›× ×¡×• לתוקף ×‘×¤×¢× ×”×‘××” שתפעיל מחדש ×ת המכשיר.</translation>
+<translation id="1838412507805038478">â€Chromium ×ימת ש-<ph name="ISSUER" /> הנפיק ×ת ×”×ישור של ×”×תר ×”×–×”.</translation>
<translation id="275588974610408078">â€×“יווח על התרסקויות ×ינו זמין ב-Chromium.</translation>
<translation id="3064346599913645280">â€×תה מציג דף מ×ובטח של Chromium</translation>
<translation id="3550966579244642892">â€×ž×¢×¨×›×ª ההפעלה של Chromium ×œ× ×”×©×œ×™×ž×” ×ת ההגדרה הר×שונית.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ja.xtb b/chromium/components/strings/components_chromium_strings_ja.xtb
index e3eadd0000d..707aa6884d7 100644
--- a/chromium/components/strings/components_chromium_strings_ja.xtb
+++ b/chromium/components/strings/components_chromium_strings_ja.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ja">
<translation id="130631256467250065">変更内容ã¯ã€æ¬¡å›žã®ç«¯æœ«ã®èµ·å‹•æ™‚ã«å映ã•ã‚Œã¾ã™ã€‚</translation>
+<translation id="1838412507805038478">ã“ã®ã‚¦ã‚§ãƒ–サイトã®è¨¼æ˜Žæ›¸ãŒ <ph name="ISSUER" /> 発行ã®ã‚‚ã®ã§ã‚ã‚‹ã“ã¨ãŒ Chromium ã§ç¢ºèªã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="275588974610408078">Chromium ã§ã¯ã€éšœå®³ãƒ¬ãƒãƒ¼ãƒˆã‚’ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。</translation>
<translation id="3064346599913645280">ä¿è­·ã•ã‚ŒãŸ Chromium ページを表示ã—ã¦ã„ã¾ã™</translation>
<translation id="3550966579244642892">Chromium OS ã¯åˆæœŸè¨­å®šãŒå®Œäº†ã—ã¦ã„ã¾ã›ã‚“。</translation>
diff --git a/chromium/components/strings/components_chromium_strings_kn.xtb b/chromium/components/strings/components_chromium_strings_kn.xtb
index cf0905e3814..78db23da26d 100644
--- a/chromium/components/strings/components_chromium_strings_kn.xtb
+++ b/chromium/components/strings/components_chromium_strings_kn.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="kn">
<translation id="130631256467250065">ನಿಮà³à²® ಸಾಧನವನà³à²¨à³ ನೀವೠಮà³à²‚ದಿನ ಬಾರಿ ಮರà³à²ªà³à²°à²¾à²°à²‚ಭಿಸಿದಾಗ ನಿಮà³à²® ಬದಲಾವಣೆಗಳೠಕಾರà³à²¯à²—ತಗೊಳà³à²³à³à²¤à³à²¤à²µà³†.</translation>
+<translation id="1838412507805038478">ಈ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ <ph name="ISSUER" /> ನೀಡಿದೆ ಎಂಬà³à²¦à²¾à²—ಿ Chromium ಪರಿಶೀಲಿಸಿದೆ.</translation>
<translation id="275588974610408078">Chromium ನಲà³à²²à²¿ ಕà³à²°à³à²¯à²¾à²¶à³ ವರದಿ ಮಾಡà³à²µà²¿à²•à³† ಲಭà³à²¯à²µà²¿à²²à³à²².</translation>
<translation id="3064346599913645280">ನೀವೠಸà³à²°à²•à³à²·à²¿à²¤ Chromium ಪà³à²Ÿà²µà²¨à³à²¨à³ ವೀಕà³à²·à²¿à²¸à³à²¤à³à²¤à²¿à²°à³à²µà²¿à²°à²¿</translation>
<translation id="3550966579244642892">Chromium OS ತನà³à²¨ ಪà³à²°à²¾à²°à²‚ಭಿಕ ಸೆಟಪೠಅನà³à²¨à³ ಪೂರà³à²£à²—ೊಳಿಸಿಲà³à²².</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ko.xtb b/chromium/components/strings/components_chromium_strings_ko.xtb
index c44e0bd56ed..d30ef37a853 100644
--- a/chromium/components/strings/components_chromium_strings_ko.xtb
+++ b/chromium/components/strings/components_chromium_strings_ko.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ko">
<translation id="130631256467250065">기기를 다시 시작할 ë•Œ ë³€ê²½ì‚¬í•­ì´ ì ìš©ë©ë‹ˆë‹¤.</translation>
+<translation id="1838412507805038478">Chromiumì´ <ph name="ISSUER" />ì—ì„œ ì´ ì›¹ì‚¬ì´íŠ¸ì˜ ì¸ì¦ì„œë¥¼ 발행했ìŒì„ 확ì¸í–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="275588974610408078">ë¹„ì •ìƒ ì¢…ë£Œ 보고서는 Chromiumì—ì„œ 사용할 수 없습니다.</translation>
<translation id="3064346599913645280">안전한 Chromium 페ì´ì§€ë¥¼ 보는 중</translation>
<translation id="3550966579244642892">Chromium OS 초기 ì„¤ì •ì´ ì™„ë£Œë˜ì§€ 않았습니다.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_lt.xtb b/chromium/components/strings/components_chromium_strings_lt.xtb
index 7ca0fb38679..33a611ea434 100644
--- a/chromium/components/strings/components_chromium_strings_lt.xtb
+++ b/chromium/components/strings/components_chromium_strings_lt.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="lt">
<translation id="130631256467250065">Pakeitimai įsigalios kitą kartą iš naujo paleidus įrenginį.</translation>
+<translation id="1838412507805038478">„Chromium“ patvirtino, kad „<ph name="ISSUER" />“ išdavė šios svetainės sertifikatą.</translation>
<translation id="275588974610408078">„Chromium“ negalima teikti strigÄių ataskaitų.</translation>
<translation id="3064346599913645280">Peržiūrite saugų „Chromium“ puslapį</translation>
<translation id="3550966579244642892">„Chromium“ OS neužbaigė šios pradinės sąrankos.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_lv.xtb b/chromium/components/strings/components_chromium_strings_lv.xtb
index daf77200819..707fe7a2cca 100644
--- a/chromium/components/strings/components_chromium_strings_lv.xtb
+++ b/chromium/components/strings/components_chromium_strings_lv.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="lv">
<translation id="130631256467250065">Izmaiņas stÄsies spÄ“kÄ nÄkamajÄ reizÄ“, kad restartÄ“siet ierÄ«ci.</translation>
+<translation id="1838412507805038478">Chromium apstiprinÄja, ka <ph name="ISSUER" /> izsniedza Å¡Ä«s vietnes sertifikÄtu.</translation>
<translation id="275588974610408078">AvÄriju pÄrskatu sÅ«tÄ«Å¡ana nav pieejama pÄrlÅ«kÄ Chromium.</translation>
<translation id="3064346599913645280">JÅ«s skatÄt droÅ¡u Chromium lapu.</translation>
<translation id="3550966579244642892">OperÄ“tÄjsistÄ“mÄ Chromium OS nav izpildÄ«ta tÄs sÄkotnÄ“jÄ iestatÄ«Å¡ana.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ml.xtb b/chromium/components/strings/components_chromium_strings_ml.xtb
index 10398da99bb..1bb1af505de 100644
--- a/chromium/components/strings/components_chromium_strings_ml.xtb
+++ b/chromium/components/strings/components_chromium_strings_ml.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ml">
<translation id="130631256467250065">നിങàµà´™àµ¾ à´…à´Ÿàµà´¤àµà´¤ തവണ ഉപകരണം à´ªàµà´¨à´°à´¾à´°à´‚à´­à´¿à´•àµà´•àµà´®àµà´ªàµ‹àµ¾ മാറàµà´±à´™àµà´™àµ¾ à´ªàµà´°à´¾à´¬à´²àµà´¯à´¤àµà´¤à´¿àµ½ വരàµà´‚.</translation>
+<translation id="1838412507805038478">à´ˆ വെബàµâ€Œà´¸àµˆà´±àµà´±à´¿à´¨àµà´±àµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ <ph name="ISSUER" /> നൽകിയതാണെനàµà´¨àµ Chromium പരിശോധിചàµà´šàµà´±à´ªàµà´ªà´¿à´šàµà´šàµ.</translation>
<translation id="275588974610408078">Chromium-à´¤àµà´¤à´¿àµ½ à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿà´¿à´‚ഗൠലഭàµà´¯à´®à´²àµà´².</translation>
<translation id="3064346599913645280">നിങàµà´™àµ¾ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯ ഒരൠChromium പേജാണൠകാണàµà´¨àµà´¨à´¤àµ</translation>
<translation id="3550966579244642892">Chromium OS, അതിനàµà´±àµ† à´ªàµà´°à´¾à´°à´‚à´­ സജàµà´œàµ€à´•à´°à´£à´‚ പൂർതàµà´¤à´¿à´¯à´¾à´•àµà´•à´¿à´¯à´¿à´Ÿàµà´Ÿà´¿à´²àµà´².</translation>
diff --git a/chromium/components/strings/components_chromium_strings_mr.xtb b/chromium/components/strings/components_chromium_strings_mr.xtb
index d3d1d46d345..2bd19779f1e 100644
--- a/chromium/components/strings/components_chromium_strings_mr.xtb
+++ b/chromium/components/strings/components_chromium_strings_mr.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="mr">
<translation id="130631256467250065">आपण आपलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¤¾ पà¥à¤¢à¥€à¤² वेळी पà¥à¤¨à¤°à¤¾à¤°à¤‚भ कराल तेवà¥à¤¹à¤¾ आपले बदल पà¥à¤°à¤­à¤¾à¤µà¥€ होतील.</translation>
+<translation id="1838412507805038478"><ph name="ISSUER" /> ने या वेबसाइटचे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° जारी केले हे Chromium ने सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ केले.</translation>
<translation id="275588974610408078">Chromium मधà¥à¤¯à¥‡ कà¥à¤°à¥…श अहवाल उपलबà¥à¤§ नाही.</translation>
<translation id="3064346599913645280">आपण à¤à¤• सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ Chromium पृषà¥à¤  पाहत आहात</translation>
<translation id="3550966579244642892">Chromium OS नी तà¥à¤¯à¤¾à¤šà¥‡ पà¥à¤°à¤¾à¤°à¤‚भिक सेटअप पूरà¥à¤£ केले नाही.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ms.xtb b/chromium/components/strings/components_chromium_strings_ms.xtb
index 5c5fa568b1d..1435a9bf94c 100644
--- a/chromium/components/strings/components_chromium_strings_ms.xtb
+++ b/chromium/components/strings/components_chromium_strings_ms.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ms">
<translation id="130631256467250065">Perubahan anda akan dilaksanakan apabila anda memulakan semula peranti anda pada masa akan datang.</translation>
+<translation id="1838412507805038478">Chromium mengesahkan bahawa <ph name="ISSUER" /> telah mengeluarkan sijil tapak web ini.</translation>
<translation id="275588974610408078">Laporan keranapan tidak tersedia dalam Chromium.</translation>
<translation id="3064346599913645280">Anda sedang melihat halaman Chromium yang selamat</translation>
<translation id="3550966579244642892">OS Chromium belum menyelesaikan persediaan awal.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_nl.xtb b/chromium/components/strings/components_chromium_strings_nl.xtb
index 90fdc932efa..a1d08b5424f 100644
--- a/chromium/components/strings/components_chromium_strings_nl.xtb
+++ b/chromium/components/strings/components_chromium_strings_nl.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="nl">
<translation id="130631256467250065">Je wijzigingen worden doorgevoerd wanneer je het apparaat opnieuw opstart.</translation>
+<translation id="1838412507805038478">Chromium heeft bevestigd dat <ph name="ISSUER" /> het certificaat voor deze website heeft verstrekt.</translation>
<translation id="275588974610408078">Crashrapportage is niet beschikbaar in Chromium.</translation>
<translation id="3064346599913645280">Je bekijkt een veilige Chromium-pagina</translation>
<translation id="3550966579244642892">De eerste configuratie van Chromium OS is niet voltooid.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_no.xtb b/chromium/components/strings/components_chromium_strings_no.xtb
index d26f214caa4..3cec4b433b9 100644
--- a/chromium/components/strings/components_chromium_strings_no.xtb
+++ b/chromium/components/strings/components_chromium_strings_no.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="no">
<translation id="130631256467250065">Endringene trer i kraft neste gang du starter enheten på nytt.</translation>
+<translation id="1838412507805038478">Chromium har bekreftet at sertifikatet for dette nettstedet er utstedt av <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Krasjrapportering er ikke tilgjengelig i Chromium.</translation>
<translation id="3064346599913645280">Du ser på en sikker Chromium-side</translation>
<translation id="3550966579244642892">Chromium OS har ikke vært gjennom den innledende konfigurasjonen.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_pl.xtb b/chromium/components/strings/components_chromium_strings_pl.xtb
index a995197db58..822112ed3ef 100644
--- a/chromium/components/strings/components_chromium_strings_pl.xtb
+++ b/chromium/components/strings/components_chromium_strings_pl.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="pl">
<translation id="130631256467250065">Zmiany zostaną zastosowane przy następnym uruchomieniu urządzenia.</translation>
+<translation id="1838412507805038478">Chromium sprawdził, że wydawcą certyfikatu tej witryny jest <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Zgłaszanie awarii nie jest dostępne w Chromium.</translation>
<translation id="3064346599913645280">PrzeglÄ…dasz bezpiecznÄ… stronÄ™ Chromium</translation>
<translation id="3550966579244642892">Nie ukończono wstępnej konfiguracji systemu operacyjnego Chromium.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_pt-BR.xtb b/chromium/components/strings/components_chromium_strings_pt-BR.xtb
index db59cee208f..2921f1bacfb 100644
--- a/chromium/components/strings/components_chromium_strings_pt-BR.xtb
+++ b/chromium/components/strings/components_chromium_strings_pt-BR.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="pt-BR">
<translation id="130631256467250065">As alterações entrarão em vigor na próxima vez que você reiniciar o dispositivo.</translation>
+<translation id="1838412507805038478">O Chromium verificou que <ph name="ISSUER" /> emitiu o certificado deste website.</translation>
<translation id="275588974610408078">O relatório de erros não está disponível no Chromium.</translation>
<translation id="3064346599913645280">Você está vendo uma página segura do Chromium</translation>
<translation id="3550966579244642892">O Chromium OS não concluiu a confirguração original</translation>
diff --git a/chromium/components/strings/components_chromium_strings_pt-PT.xtb b/chromium/components/strings/components_chromium_strings_pt-PT.xtb
index f79d4fdbb10..97ca7ce6342 100644
--- a/chromium/components/strings/components_chromium_strings_pt-PT.xtb
+++ b/chromium/components/strings/components_chromium_strings_pt-PT.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="pt-PT">
<translation id="130631256467250065">As alterações terão efeito da próxima vez que reiniciar o dispositivo.</translation>
+<translation id="1838412507805038478">O Chromium confirmou que a <ph name="ISSUER" /> emitiu o certificado deste Website.</translation>
<translation id="275588974610408078">O relatório de falha não está disponível no Chromium.</translation>
<translation id="3064346599913645280">Está a ver uma página segura do Chromium</translation>
<translation id="3550966579244642892">O SO Chromium não concluiu a configuração inicial.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ro.xtb b/chromium/components/strings/components_chromium_strings_ro.xtb
index f9cc2f6318d..fb116fac483 100644
--- a/chromium/components/strings/components_chromium_strings_ro.xtb
+++ b/chromium/components/strings/components_chromium_strings_ro.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ro">
<translation id="130631256467250065">Modificările dvs. se vor aplica următoarea dată când reporniți dispozitivul.</translation>
+<translation id="1838412507805038478">Chromium s-a asigurat că certificatul acestui site a fost emis de <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Raportarea blocărilor nu este disponibilă în Chromium.</translation>
<translation id="3064346599913645280">Se afișează o pagină Chromium securizată</translation>
<translation id="3550966579244642892">Sistemul de operare Chromium nu a finalizat configurarea inițială.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ru.xtb b/chromium/components/strings/components_chromium_strings_ru.xtb
index e939f7ddfaf..846277b9105 100644
--- a/chromium/components/strings/components_chromium_strings_ru.xtb
+++ b/chromium/components/strings/components_chromium_strings_ru.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ru">
<translation id="130631256467250065">Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑтупÑÑ‚ в Ñилу поÑле перезагрузки уÑтройÑтва.</translation>
+<translation id="1838412507805038478">Данные Chromium подтверждают, что Ñертификат Ñайта выпущен компанией <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Ð’ Chromium отÑутÑтвует Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ñ‚Ñ‡ÐµÑ‚Ð° об ошибках.</translation>
<translation id="3064346599913645280">Ð’Ñ‹ проÑматриваете безопаÑную Ñтраницу Chromium</translation>
<translation id="3550966579244642892">ÐŸÐµÑ€Ð²Ð¾Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ð½Ð°Ñтройка Chromium OS не завершена.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_sk.xtb b/chromium/components/strings/components_chromium_strings_sk.xtb
index 2125a414791..3453dba852b 100644
--- a/chromium/components/strings/components_chromium_strings_sk.xtb
+++ b/chromium/components/strings/components_chromium_strings_sk.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sk">
<translation id="130631256467250065">Zmeny sa prejavia po ÄalÅ¡om reÅ¡tartovaní zariadenia.</translation>
+<translation id="1838412507805038478">PrehliadaÄ Chromium overil, že certifikát tohto webu bol vydaný vydavateľom <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Správy o zlyhaní nie sú v prehliadaÄi Chromium k dispozícii.</translation>
<translation id="3064346599913645280">Prezeráte si zabezpeÄenú stránku prehliadaÄa Chromium</translation>
<translation id="3550966579244642892">Systém Chromium OS nedokonÄil poÄiatoÄné nastavenie.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_sl.xtb b/chromium/components/strings/components_chromium_strings_sl.xtb
index 18c038be9a7..488af1b5cb5 100644
--- a/chromium/components/strings/components_chromium_strings_sl.xtb
+++ b/chromium/components/strings/components_chromium_strings_sl.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sl">
<translation id="130631256467250065">Spremembe bodo uveljavljene pri naslednjem vnoviÄnem zagonu naprave.</translation>
+<translation id="1838412507805038478">Chromium je preveril, ali je izdajatelj <ph name="ISSUER" /> izdal potrdilo tega spletnega mesta.</translation>
<translation id="275588974610408078">PoroÄanje o zruÅ¡itvah ni na voljo v Chromiumu.</translation>
<translation id="3064346599913645280">Ogledujete si varno stran Chromiuma</translation>
<translation id="3550966579244642892">OS Chromium ni dokonÄal zaÄetne nastavitve.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_sr.xtb b/chromium/components/strings/components_chromium_strings_sr.xtb
index 62bf8d0de5a..bee837da221 100644
--- a/chromium/components/strings/components_chromium_strings_sr.xtb
+++ b/chromium/components/strings/components_chromium_strings_sr.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sr">
<translation id="130631256467250065">Промене ће Ñтупити на Ñнагу када Ñледећи пут поново покренете уређај.</translation>
+<translation id="1838412507805038478">Chromium је потврдио да је <ph name="ISSUER" /> издао Ñертификат овог веб-Ñајта.</translation>
<translation id="275588974610408078">Извештавање о отказивањима није доÑтупно у Chromium-у.</translation>
<translation id="3064346599913645280">Прегледате безбедну Chromium Ñтраницу.</translation>
<translation id="3550966579244642892">Chromium ОС није довршио почетно подешавање.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_sv.xtb b/chromium/components/strings/components_chromium_strings_sv.xtb
index 2964a155dab..50e6eb8a221 100644
--- a/chromium/components/strings/components_chromium_strings_sv.xtb
+++ b/chromium/components/strings/components_chromium_strings_sv.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sv">
<translation id="130631256467250065">Dina ändringar börjar gälla nästa gång du startar om enheten.</translation>
+<translation id="1838412507805038478">Chromium har verifierat att <ph name="ISSUER" /> har utfärdat webbplatsens certifikat.</translation>
<translation id="275588974610408078">Felrapportering är inte tillgängligt i Chromium.</translation>
<translation id="3064346599913645280">Du visar en säker Chromium-sida</translation>
<translation id="3550966579244642892">Den första konfigureringen av Chromium OS har inte slutförts.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_sw.xtb b/chromium/components/strings/components_chromium_strings_sw.xtb
index 99a78620698..66d4f6018e4 100644
--- a/chromium/components/strings/components_chromium_strings_sw.xtb
+++ b/chromium/components/strings/components_chromium_strings_sw.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sw">
<translation id="130631256467250065">Mabadiliko yako yatatekelezwa utakapowasha upya tena kifaa chako.</translation>
+<translation id="1838412507805038478">Chromium imethibitisha kuwa <ph name="ISSUER" /> ndiye mtoa cheti cha tovuti hii.</translation>
<translation id="275588974610408078">Kuripoti uharibifu hakupatikana katika Chromium.</translation>
<translation id="3064346599913645280">Unaangalia ukurasa salama wa Chromium</translation>
<translation id="3550966579244642892">Mfumo wa Uendeshaji wa Chromium haujakamilisha kuweka mipangilio ya awali.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_ta.xtb b/chromium/components/strings/components_chromium_strings_ta.xtb
index 566419ce2c9..6fe23f71b15 100644
--- a/chromium/components/strings/components_chromium_strings_ta.xtb
+++ b/chromium/components/strings/components_chromium_strings_ta.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ta">
<translation id="130631256467250065">அடà¯à®¤à¯à®¤ à®®à¯à®±à¯ˆ உஙà¯à®•à®³à¯ சாதனதà¯à®¤à¯ˆ மறà¯à®¤à¯Šà®Ÿà®•à¯à®•à®®à¯ செயà¯à®¯à¯à®®à¯à®ªà¯‹à®¤à¯, மாறà¯à®±à®™à¯à®•à®³à¯ செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®±à¯à®•à¯ வரà¯à®®à¯.</translation>
+<translation id="1838412507805038478">இநà¯à®¤ இணையதளச௠சானà¯à®±à®¿à®¤à®´à¯ˆ <ph name="ISSUER" /> தான௠வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¾à®°à¯ எனà¯à®ªà®¤à¯ˆ Chromium சரிபாரà¯à®¤à¯à®¤à®¤à¯.</translation>
<translation id="275588974610408078">சிதைவ௠அறிகà¯à®•à¯ˆ Chromium இல௠கிடைகà¯à®•à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="3064346599913645280">பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© Chromium பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பாரà¯à®•à¯à®•à®¿à®±à¯€à®°à¯à®•à®³à¯</translation>
<translation id="3550966579244642892">Chromium OS அதன௠தà¯à®µà®•à¯à®•à®¨à®¿à®²à¯ˆ அமைவை நிறைவà¯à®šà¯†à®¯à¯à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_te.xtb b/chromium/components/strings/components_chromium_strings_te.xtb
index b8a5ece0262..60015f6ffb3 100644
--- a/chromium/components/strings/components_chromium_strings_te.xtb
+++ b/chromium/components/strings/components_chromium_strings_te.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="te">
<translation id="130631256467250065">మీ మారà±à°ªà±à°²à± మీరౠమీ పరికరానà±à°¨à°¿ à°ªà±à°¨à°ƒà°ªà±à°°à°¾à°°à°‚భించే తదà±à°ªà°°à°¿à°¸à°¾à°°à°¿ à°ªà±à°°à°­à°¾à°µà°µà°‚తం à°…à°µà±à°¤à°¾à°¯à°¿.</translation>
+<translation id="1838412507805038478">Chromium à°ˆ వెబà±â€Œà°¸à±ˆà°Ÿà± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ <ph name="ISSUER" /> జారీ చేసినటà±à°²à± ధృవీకరించింది.</translation>
<translation id="275588974610408078">Chromiumలో à°•à±à°°à°¾à°·à± నివేదిక à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదà±.</translation>
<translation id="3064346599913645280">మీరౠసà±à°°à°•à±à°·à°¿à°¤à°®à±ˆà°¨ Chromium పేజీని వీకà±à°·à°¿à°¸à±à°¤à±à°¨à±à°¨à°¾à°°à±</translation>
<translation id="3550966579244642892">Chromium OS దాని à°ªà±à°°à°¾à°¥à°®à°¿à°• సెటపà±â€Œà°¨à± పూరà±à°¤à°¿ చేయలేదà±.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_th.xtb b/chromium/components/strings/components_chromium_strings_th.xtb
index 3f72bc4f2dd..b6aa5817dae 100644
--- a/chromium/components/strings/components_chromium_strings_th.xtb
+++ b/chromium/components/strings/components_chromium_strings_th.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="th">
<translation id="130631256467250065">à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸‚องคุณจะมีผลในครั้งถัดไปที่คุณรีสตาร์ทอุปà¸à¸£à¸“์ของคุณ</translation>
+<translation id="1838412507805038478">Chromium ยืนยันว่า <ph name="ISSUER" /> ได้ออà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸‚องเว็บไซต์นี้</translation>
<translation id="275588974610408078">ไม่มีà¸à¸²à¸£à¸£à¸²à¸¢à¸‡à¸²à¸™à¸‚้อขัดข้องใน Chrome</translation>
<translation id="3064346599913645280">คุณà¸à¸³à¸¥à¸±à¸‡à¸”ูหน้า Chromium ที่ปลอดภัย</translation>
<translation id="3550966579244642892">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าà¹à¸£à¸à¹€à¸£à¸´à¹ˆà¸¡à¸‚อง Chromium OS ยังไม่เสร็จสมบูรณ์</translation>
diff --git a/chromium/components/strings/components_chromium_strings_tr.xtb b/chromium/components/strings/components_chromium_strings_tr.xtb
index 57513efc9b5..61fc9c68973 100644
--- a/chromium/components/strings/components_chromium_strings_tr.xtb
+++ b/chromium/components/strings/components_chromium_strings_tr.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="tr">
<translation id="130631256467250065">Yaptığınız değişiklikler cihazı yeniden başlattığınızda etkinleşecektir.</translation>
+<translation id="1838412507805038478">Chromium, bu web sitesi sertifikasının <ph name="ISSUER" /> tarafından yayınlandığını doğruladı.</translation>
<translation id="275588974610408078">Chromium'da kilitlenmeyi raporlama özelliği yoktur.</translation>
<translation id="3064346599913645280">Güvenli bir Chromium sayfasını görüntülüyorsunuz</translation>
<translation id="3550966579244642892">Chromium OS ilk kurulumunu tamamlayamadı.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_uk.xtb b/chromium/components/strings/components_chromium_strings_uk.xtb
index 576830ceae6..7ab0f3f6608 100644
--- a/chromium/components/strings/components_chromium_strings_uk.xtb
+++ b/chromium/components/strings/components_chromium_strings_uk.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="uk">
<translation id="130631256467250065">Ваші зміни почнуть діÑти під Ñ‡Ð°Ñ Ð½Ð°Ñтупного перезапуÑку приÑтрою.</translation>
+<translation id="1838412507805038478">Chromium підтвердив, що Ñертифікат цьому веб-Ñайту надала ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ <ph name="ISSUER" />.</translation>
<translation id="275588974610408078">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ не доÑтупна в Chromium.</translation>
<translation id="3064346599913645280">Ви переглÑдаєте безпечну Ñторінку Chromium</translation>
<translation id="3550966579244642892">ОС Chromium не завершила початкове налаштуваннÑ.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_vi.xtb b/chromium/components/strings/components_chromium_strings_vi.xtb
index 669e0d8a6e1..a1ec81380a1 100644
--- a/chromium/components/strings/components_chromium_strings_vi.xtb
+++ b/chromium/components/strings/components_chromium_strings_vi.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="vi">
<translation id="130631256467250065">Thay đổi của bạn sẽ có hiệu lực vào lần tiếp theo bạn khởi động lại thiết bị của mình.</translation>
+<translation id="1838412507805038478">Chromium xác minh rằng <ph name="ISSUER" /> đã cấp chứng chỉ của trang web này.</translation>
<translation id="275588974610408078">Báo cáo sự cố hiện không khả dụng trong Chromium.</translation>
<translation id="3064346599913645280">Bạn đang xem trang Chromium an toàn</translation>
<translation id="3550966579244642892">Chromium OS chưa hoàn thành thiết lập ban đầu.</translation>
diff --git a/chromium/components/strings/components_chromium_strings_zh-CN.xtb b/chromium/components/strings/components_chromium_strings_zh-CN.xtb
index 295816050ee..724e5e98ae0 100644
--- a/chromium/components/strings/components_chromium_strings_zh-CN.xtb
+++ b/chromium/components/strings/components_chromium_strings_zh-CN.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="zh-CN">
<translation id="130631256467250065">您所åšçš„更改会在下次é‡æ–°å¯åŠ¨è®¾å¤‡æ—¶ç”Ÿæ•ˆã€‚</translation>
+<translation id="1838412507805038478">Chromium å·²è¯å®žï¼šæ­¤ç½‘站的è¯ä¹¦æ˜¯ç”± <ph name="ISSUER" /> ç­¾å‘的。</translation>
<translation id="275588974610408078">Chromium 未æ供崩溃报告。</translation>
<translation id="3064346599913645280">您正在查看安全的 Chromium 网页</translation>
<translation id="3550966579244642892">Chromium æ“作系统尚未完æˆå…¶åˆå§‹è®¾ç½®ã€‚</translation>
diff --git a/chromium/components/strings/components_chromium_strings_zh-TW.xtb b/chromium/components/strings/components_chromium_strings_zh-TW.xtb
index 250483f5ecc..01e354b648b 100644
--- a/chromium/components/strings/components_chromium_strings_zh-TW.xtb
+++ b/chromium/components/strings/components_chromium_strings_zh-TW.xtb
@@ -2,6 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="zh-TW">
<translation id="130631256467250065">你的變更會在下次é‡æ–°å•Ÿå‹•è£ç½®æ™‚生效。</translation>
+<translation id="1838412507805038478">Chromium 已驗證這個網站的憑證是由「<ph name="ISSUER" />ã€æ‰€æ ¸ç™¼ã€‚</translation>
<translation id="275588974610408078">Chromium ä¸æ”¯æ´ç•¶æ©Ÿå›žå ±åŠŸèƒ½ã€‚</translation>
<translation id="3064346599913645280">ç›®å‰é¡¯ç¤ºçš„是安全型 Chromium 網é </translation>
<translation id="3550966579244642892">Chromium 作業系統未完æˆåˆå§‹è¨­å®šã€‚</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_am.xtb b/chromium/components/strings/components_google_chrome_strings_am.xtb
index 4eee510f8c9..ced93a9dc34 100644
--- a/chromium/components/strings/components_google_chrome_strings_am.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_am.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="am">
<translation id="1016765312371154165">Chrome በትክክሠአáˆá‰°á‹˜áŒ‹áˆ áŠá‰ áˆ­á¢</translation>
<translation id="130631256467250065">ለá‹áŒ¦á‰½á‹Ž መሣሪያዎን ዳáŒáˆ በሚያስጀáˆáˆ©á‰ á‰µ ቀጣዩ ጊዜ ላይ ይተገበራሉá¢</translation>
+<translation id="2147651015520127414">Chrome የዚህ ድር ጣቢያ እá‹á‰…ና ማረጋገጫ ያወጣዠ<ph name="ISSUER" /> መሆኑን አረጋáŒáŒ§áˆá¢</translation>
<translation id="2874156562296220396">Google Chrome በ<ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> ክáት áˆáŠ•áŒ­ á•áˆ®áŒ€áŠ­á‰µ እና በሌላ <ph name="BEGIN_LINK_OSS" />ክáት áˆáŠ•áŒ­ ሶáትዌር<ph name="END_LINK_OSS" /> ሊሰራ ችáˆáˆá¢</translation>
<translation id="3140883423282498090">ለá‹áŒ¦á‰½á‹Ž Google Chrome ዳáŒáˆ በሚያስጀáˆáˆ©á‰ á‰µ ቀጣዩ ጊዜ ላይ ይተገበራሉá¢</translation>
<translation id="3444832043240812445">ይህ ገጽ <ph name="BEGIN_LINK" />የብáˆáˆ½á‰µ ሪá–ርት ማድረáŒ<ph name="END_LINK" />ን ካáŠá‰ የቅርብ ጊዜ ብáˆáˆ½á‰¶á‰½á‹ŽáŠ• ብቻ áŠá‹ መረጃ የሚያሳየá‹á¢</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ar.xtb b/chromium/components/strings/components_google_chrome_strings_ar.xtb
index 1a233662a1b..0c617ffc9a6 100644
--- a/chromium/components/strings/components_google_chrome_strings_ar.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ar.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ar">
<translation id="1016765312371154165">â€Ù„Ù… يتم إيقا٠تشغيل Chrome بشكل صحيح.</translation>
<translation id="130631256467250065">تسري التغييرات ÙÙŠ المرة التالية التي تعيد Ùيها تشغيل الجهاز.</translation>
+<translation id="2147651015520127414">â€Ù„قد تحقق Chrome من أن <ph name="ISSUER" /> أصدر شهادة الموقع الإلكتروني.</translation>
<translation id="2874156562296220396">â€Ù†ÙˆÙر لكم Google Chrome بÙضل المشروع المÙتوح المصدر <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> Ùˆ<ph name="BEGIN_LINK_OSS" />برامج أخرى Ù…Ùتوحة المصدر<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">â€Ø³ØªØ³Ø±ÙŠ التغييرات ÙÙŠ المرة التالية التي تعيد Ùيها تشغيل Google Chrome.</translation>
<translation id="3444832043240812445">تعرض هذه الصÙحة Ùقط معلومات عن الأعطال الحديثة إذا <ph name="BEGIN_LINK" />مكّنت الإبلاغ عن الأعطال<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_bg.xtb b/chromium/components/strings/components_google_chrome_strings_bg.xtb
index d506ed5e7d5..c6330186fd0 100644
--- a/chromium/components/strings/components_google_chrome_strings_bg.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_bg.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="bg">
<translation id="1016765312371154165">Chrome не Ñе затвори правилно.</translation>
<translation id="130631256467250065">Промените ви ще влÑзат в Ñила ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ð¿ÑŠÑ‚, когато реÑтартирате уÑтройÑтвото Ñи.</translation>
+<translation id="2147651015520127414">Chrome потвърди, че Ñертификатът на този уебÑайт е издаден от <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Google Chrome ÑъщеÑтвува благодарение на проекта Ñ Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½ код <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> и други <ph name="BEGIN_LINK_OSS" />Ñофтуерни продукти Ñ Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½ код<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Промените ви ще влÑзат в Ñила ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ð¿ÑŠÑ‚, когато Ñтартирате отново Google Chrome.</translation>
<translation id="3444832043240812445">Ð’ тази Ñтраница Ñе показва Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ñкорошните Ñривове Ñамо ако Ñте <ph name="BEGIN_LINK" />активирали изпращането на Ñигнали за Ñривове<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_bn.xtb b/chromium/components/strings/components_google_chrome_strings_bn.xtb
index aa3f4615b93..f2253b3cbe3 100644
--- a/chromium/components/strings/components_google_chrome_strings_bn.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_bn.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="bn">
<translation id="1016765312371154165">Chrome সঠিকভাবে বনà§à¦§ হয়নি৷</translation>
<translation id="130631256467250065">পরের বার আপনি আপনার ডিভাইস পà§à¦¨à¦°à¦¾à¦°à¦®à§à¦­ করলে আপনার পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ পà§à¦°à¦­à¦¾à¦¬à§€ হবে৷</translation>
+<translation id="2147651015520127414"><ph name="ISSUER" /> যে à¦à¦‡ ওয়েবসাইটের শংসাপতà§à¦° পà§à¦°à¦•à¦¾à¦¶ করেছে Chrome তা যাচাই করেছে।</translation>
<translation id="2874156562296220396">Google Chrome, সমà§à¦­à¦¬à¦¤ <ph name="BEGIN_LINK_CHROMIUM" />কà§à¦°à§‹à¦®à¦¿à§Ÿà¦¾à¦®<ph name="END_LINK_CHROMIUM" /> মà§à¦•à§à¦¤ উৎস পà§à¦°à§‹à¦œà§‡à¦•à§à¦Ÿ à¦à¦¬à¦‚ অনà§à¦¯à¦¾à¦¨à§à¦¯ <ph name="BEGIN_LINK_OSS" />মà§à¦•à§à¦¤ উৎস সফà§à¦Ÿà¦“য়à§à¦¯à¦¾à¦°<ph name="END_LINK_OSS" /> দà§à¦¬à¦¾à¦°à¦¾ তৈরি করা হয়েছে৷</translation>
<translation id="3140883423282498090">আপনি পরবরà§à¦¤à§€ সময়ে যখন Google Chrome আবার লঞà§à¦š করবেন আপনার পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ কারà§à¦¯à¦•à¦° হবে৷</translation>
<translation id="3444832043240812445">যদি আপনি <ph name="BEGIN_LINK" />কà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ সকà§à¦·à¦® করেন<ph name="END_LINK" /> তাহলে à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ কেবল আপনার সামà§à¦ªà§à¦°à¦¤à¦¿à¦• কà§à¦°à§à¦¯à¦¾à¦¶à¦—à§à¦²à¦¿à¦° তথà§à¦¯ দেখায়৷</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ca.xtb b/chromium/components/strings/components_google_chrome_strings_ca.xtb
index 3ae104a89fa..3a9b8d524ad 100644
--- a/chromium/components/strings/components_google_chrome_strings_ca.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ca.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ca">
<translation id="1016765312371154165">Chrome no s'ha tancat correctament.</translation>
<translation id="130631256467250065">Els canvis es faran efectius la propera vegada que reinicieu el dispositiu.</translation>
+<translation id="2147651015520127414">Chrome ha verificat que <ph name="ISSUER" /> ha emès el certificat d'aquest lloc web.</translation>
<translation id="2874156562296220396">Google Chrome ha estat possible gràcies al projecte de codi obert <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> i altres <ph name="BEGIN_LINK_OSS" />programes de codi obert<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Els canvis es faran efectius la propera vegada que reinicieu Google Chrome.</translation>
<translation id="3444832043240812445">Aquesta pàgina només mostrarà informació sobre els bloqueigs recents si <ph name="BEGIN_LINK" />activeu la creació d'informes de bloqueig<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_cs.xtb b/chromium/components/strings/components_google_chrome_strings_cs.xtb
index 2ca34c87add..65deb00da0e 100644
--- a/chromium/components/strings/components_google_chrome_strings_cs.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_cs.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="cs">
<translation id="1016765312371154165">Aplikace Chrome nebyla řádnÄ› ukonÄena.</translation>
<translation id="130631256467250065">Změny se projeví po příštím restartu zařízení.</translation>
+<translation id="2147651015520127414">Chrome ověřil, že certifikát tohoto webu byl vydán vydavatelem <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Google Chrome staví na projektu s otevřeným zdrojovým kódem <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> a využívá i další <ph name="BEGIN_LINK_OSS" />otevřený software<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">ZmÄ›ny se projeví po příštím restartu prohlížeÄe Google Chrome.</translation>
<translation id="3444832043240812445">Pokud zvolíte možnost <ph name="BEGIN_LINK" />povolit zprávy o selhání<ph name="END_LINK" />, tato stránka bude zobrazovat jen informace o posledních selháních.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_da.xtb b/chromium/components/strings/components_google_chrome_strings_da.xtb
index fe7ed5ef8a5..43d7974e66d 100644
--- a/chromium/components/strings/components_google_chrome_strings_da.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_da.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="da">
<translation id="1016765312371154165">Chrome blev ikke afsluttet korrekt.</translation>
<translation id="130631256467250065">Dine ændringer træder i kraft, næste gang du genstarter din enhed.</translation>
+<translation id="2147651015520127414">Chrome bekræftede, at <ph name="ISSUER" /> har udstedt certifikatet for dette website.</translation>
<translation id="2874156562296220396">Google Chrome er blevet en realitet på grund af <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> open source-projektet og anden <ph name="BEGIN_LINK_OSS" />open source-software<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Dine ændringer træder i kraft, næste gang du åbner Google Chrome.</translation>
<translation id="3444832043240812445">Denne side viser kun oplysninger om dine seneste nedbrud, hvis du <ph name="BEGIN_LINK" />aktiverer rapportering af nedbrud<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_de.xtb b/chromium/components/strings/components_google_chrome_strings_de.xtb
index bbc59c14097..c5b007dbac0 100644
--- a/chromium/components/strings/components_google_chrome_strings_de.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_de.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="de">
<translation id="1016765312371154165">Chrome wurde nicht richtig beendet.</translation>
<translation id="130631256467250065">Ihre Änderungen werden beim nächsten Neustart wirksam.</translation>
+<translation id="2147651015520127414">Chrome hat verifiziert, dass <ph name="ISSUER" /> das Zertifikat dieser Website ausgestellt hat.</translation>
<translation id="2874156562296220396">Google Chrome wird durch das Open-Source-Projekt <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> und andere <ph name="BEGIN_LINK_OSS" />Open-Source-Software<ph name="END_LINK_OSS" /> ermöglicht.</translation>
<translation id="3140883423282498090">Ihre Änderungen werden beim nächsten Neustart von Google Chrome wirksam.</translation>
<translation id="3444832043240812445">Diese Seite zeigt nur Informationen zu Ihren letzten Abstürzen, wenn Sie die <ph name="BEGIN_LINK" />Absturzberichtsfunktion aktivieren<ph name="END_LINK" />.</translation>
@@ -19,5 +20,5 @@
Falls das Problem nicht dadurch verursacht wurde, empfehlen wir,
diese Option für eine verbesserte Leistung wieder zu aktivieren.</translation>
<translation id="6855094794438142393">Gehen Sie zum Chrome-Menü &gt; "<ph name="SETTINGS_TITLE" />" &gt; "<ph name="ADVANCED_TITLE" />" &gt; "<ph name="PROXIES_TITLE" />" &gt; "LAN-Einstellungen" und deaktivieren Sie die Option "Proxyserver für LAN verwenden".</translation>
-<translation id="8187289872471304532">Gehen Sie zu "Anwendungen" &gt; "Systemeinstellungen" &gt; "Netzwerk" &gt; "Erweitert" &gt; "Proxys" und deaktivieren Sie alle ausgewählten Proxyserver.</translation>
+<translation id="8187289872471304532">Gehen Sie zu "Programme" &gt; "Systemeinstellungen" &gt; "Netzwerk" &gt; "Erweitert" &gt; "Proxys" und deaktivieren Sie alle ausgewählten Proxyserver.</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_el.xtb b/chromium/components/strings/components_google_chrome_strings_el.xtb
index 4c909c3027e..45046b13514 100644
--- a/chromium/components/strings/components_google_chrome_strings_el.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_el.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="el">
<translation id="1016765312371154165">Η λειτουÏγία του Chrome δεν τεÏματίστηκε σωστά.</translation>
<translation id="130631256467250065">Οι αλλαγές σας θα εφαÏμοστοÏν την επόμενη φοÏά που θα επανεκκινήσετε τη συσκευή σας.</translation>
+<translation id="2147651015520127414">Το Chrome επαλήθευσε ότι το πιστοποιητικό Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… ιστότοπου εκδόθηκε από τον/την <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Το Google Chrome υλοποιήθηκε με τη βοήθεια του έÏγου Î±Î½Î¿Î¹ÎºÏ„Î¿Ï ÎºÏŽÎ´Î¹ÎºÎ± <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> και άλλου <ph name="BEGIN_LINK_OSS" />Î»Î¿Î³Î¹ÏƒÎ¼Î¹ÎºÎ¿Ï Î±Î½Î¿Î¹ÎºÏ„Î¿Ï ÎºÏŽÎ´Î¹ÎºÎ±<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Οι αλλαγές που Ï€Ïαγματοποιήσατε θα ισχÏσουν την επόμενη φοÏά που θα επανεκκινήσετε το Google Chrome.</translation>
<translation id="3444832043240812445">Αυτή η σελίδα εμφανίζει μόνο πληÏοφοÏίες για τα σφάλματα που παÏουσιάστηκαν Ï€Ïόσφατα εφόσον <ph name="BEGIN_LINK" />έχετε ενεÏγοποιημένη την αναφοÏά σφαλμάτων<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_en-GB.xtb b/chromium/components/strings/components_google_chrome_strings_en-GB.xtb
index 600e88bca5f..efef1747dbd 100644
--- a/chromium/components/strings/components_google_chrome_strings_en-GB.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_en-GB.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="en-GB">
<translation id="1016765312371154165">Chrome didn't shut down correctly.</translation>
<translation id="130631256467250065">Your changes will take effect the next time that you restart your device.</translation>
+<translation id="2147651015520127414">Chrome verified that <ph name="ISSUER" /> issued this website's certificate.</translation>
<translation id="2874156562296220396">Google Chrome is made possible by the <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> open source project and other <ph name="BEGIN_LINK_OSS" />open source software<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Your changes will take effect the next time you relaunch Google Chrome.</translation>
<translation id="3444832043240812445">This page only shows information on your recent crashes if you <ph name="BEGIN_LINK" />enable crash reporting<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_es-419.xtb b/chromium/components/strings/components_google_chrome_strings_es-419.xtb
index 9207232535d..fd99a7f8cdc 100644
--- a/chromium/components/strings/components_google_chrome_strings_es-419.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_es-419.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="es-419">
<translation id="1016765312371154165">Chrome no se cerró correctamente.</translation>
<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="2147651015520127414">Chrome verificó que <ph name="ISSUER" /> emitió el certificado de este sitio web.</translation>
<translation id="2874156562296220396">Google Chrome es una realidad gracias al proyecto de código fuente abierto <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> y a otros <ph name="BEGIN_LINK_OSS" />programas de código abierto<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Los cambios se aplicarán la próxima vez que reinicies Google Chrome.</translation>
<translation id="3444832043240812445">Esta página sólo muestra información sobre fallas recientes si se <ph name="BEGIN_LINK" />activan los informes sobre fallas<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_es.xtb b/chromium/components/strings/components_google_chrome_strings_es.xtb
index e3b5b2b94cd..1e0d90dab84 100644
--- a/chromium/components/strings/components_google_chrome_strings_es.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_es.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="es">
<translation id="1016765312371154165">Chrome no se ha cerrado correctamente.</translation>
<translation id="130631256467250065">Los cambios se aplicarán la próxima vez que reinicies el dispositivo.</translation>
+<translation id="2147651015520127414">Chrome ha verificado que <ph name="ISSUER" /> emitió el certificado de este sitio web.</translation>
<translation id="2874156562296220396">Google Chrome es una realidad gracias al proyecto de software libre <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> y a otros <ph name="BEGIN_LINK_OSS" />programas de código abierto<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Los cambios se aplicarán la próxima vez que reinicies Google Chrome.</translation>
<translation id="3444832043240812445">Esta página solo muestra información sobre fallos recientes si se <ph name="BEGIN_LINK" />habilitan los informes sobre fallos<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_et.xtb b/chromium/components/strings/components_google_chrome_strings_et.xtb
index 6ad28c9a005..6370a150a2c 100644
--- a/chromium/components/strings/components_google_chrome_strings_et.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_et.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="et">
<translation id="1016765312371154165">Chrome ei sulgunud õigesti.</translation>
<translation id="130631256467250065">Muudatused jõustuvad järgmine kord, kui seadme taaskäivitate.</translation>
+<translation id="2147651015520127414">Chrome kinnitas, et veebisaidi sertifikaadi väljastas <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Google Chrome'i on teinud võimalikuks avatud lähtekoodiga <ph name="BEGIN_LINK_CHROMIUM" />Chromiumi<ph name="END_LINK_CHROMIUM" /> projekt ja muu <ph name="BEGIN_LINK_OSS" />avatud lähtekoodiga tarkvara<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Teie muudatused jõustuvad järgmine kord, kui avate Google Chrome'i.</translation>
<translation id="3444832043240812445">Lehel näidatakse vaid teavet hiljutiste krahhide kohta, kui olete <ph name="BEGIN_LINK" />krahhide aruandluse lubanud<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_fa.xtb b/chromium/components/strings/components_google_chrome_strings_fa.xtb
index cbddc052cf1..21ae9c75b79 100644
--- a/chromium/components/strings/components_google_chrome_strings_fa.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_fa.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="fa">
<translation id="1016765312371154165">â€Chrome به درستی بسته نشده است.</translation>
<translation id="130631256467250065">تغییرات بار بعد که دستگاه راه‌اندازی می‌شود اعمال می‌شوند.</translation>
+<translation id="2147651015520127414">â€Chrome تأیید می‌کند Ú©Ù‡ <ph name="ISSUER" /> گواهی‌نامه این وب‌سایت را صادر کرده است.</translation>
<translation id="2874156562296220396">â€Google Chrome با پروژه منبع باز <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> Ùˆ دیگر <ph name="BEGIN_LINK_OSS" />نرم‌اÙزارهای منبع باز<ph name="END_LINK_OSS" /> کار می‌کند.</translation>
<translation id="3140883423282498090">â€Ø¯Ùعه بعد Ú©Ù‡ Google Chrome را مجدداً راه‌اندازی می‌کنید، این تغییرات اعمال می‌شوند.</translation>
<translation id="3444832043240812445">درصورتی‌که <ph name="BEGIN_LINK" />ارسال گزارش خرابی را Ùعال کنید<ph name="END_LINK" />ØŒ این صÙحه Ùقط اطلاعاتی را در مورد مشکلات اخیر شما نشان می‌دهد.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_fi.xtb b/chromium/components/strings/components_google_chrome_strings_fi.xtb
index c52adfb9e40..79a62d046f2 100644
--- a/chromium/components/strings/components_google_chrome_strings_fi.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_fi.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="fi">
<translation id="1016765312371154165">Chromea ei suljettu oikein.</translation>
<translation id="130631256467250065">Muutokset tulevat voimaan, kun käynnistät laitteen seuraavan kerran.</translation>
+<translation id="2147651015520127414">Chrome vahvisti, että <ph name="ISSUER" /> on myöntänyt tämän sivuston varmenteen.</translation>
<translation id="2874156562296220396">Google Chromen mahdollistivat avoimen lähdekoodin projekti <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> ja muut <ph name="BEGIN_LINK_OSS" />avoimen lähdekoodin ohjelmistot<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Muutokset tulevat voimaan, kun käynnistät Google Chromen seuraavan kerran.</translation>
<translation id="3444832043240812445">Tällä sivulla näkyy tietoja viimeaikaisista kaatumisista vain, jos <ph name="BEGIN_LINK" />otat kaatumisraportit käyttöön<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_fil.xtb b/chromium/components/strings/components_google_chrome_strings_fil.xtb
index 21ab20f4956..02ca197e1ab 100644
--- a/chromium/components/strings/components_google_chrome_strings_fil.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_fil.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="fil">
<translation id="1016765312371154165">Hindi nag-shut down nang tama ang Chrome.</translation>
<translation id="130631256467250065">Magkakabisa ang iyong mga pagbabago sa susunod na i-restart ang iyong device.</translation>
+<translation id="2147651015520127414">Na-verify ng Chrome na ang <ph name="ISSUER" /> ang nagbigay sa certificate ng website na ito.</translation>
<translation id="2874156562296220396">Ang Google Chrome ay ginawang posible ng <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> open source project at iba pang <ph name="BEGIN_LINK_OSS" />open source software<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Magkakaroon ng bisa ang iyong mga pagbabago sa susunod na pagkakataong muli mong ilunsad ang Google Chrome.</translation>
<translation id="3444832043240812445">Ipinapakita lang ng pahinang ito ang impormasyon ng iyong kamakailang mga pag-crash kung <ph name="BEGIN_LINK" />papaganahin mo ang pag-uulat ng pag-crash<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_fr.xtb b/chromium/components/strings/components_google_chrome_strings_fr.xtb
index fe96aed4190..dd624f4cd7a 100644
--- a/chromium/components/strings/components_google_chrome_strings_fr.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_fr.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="fr">
<translation id="1016765312371154165">Chrome ne s'est pas correctement arrêté.</translation>
<translation id="130631256467250065">Vos modifications seront prises en compte au prochain démarrage de l'appareil.</translation>
+<translation id="2147651015520127414">Chrome a confirmé que le certificat de ce site Web a bien été émis par <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Google Chrome fonctionne grâce au projet Open Source <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> et à d'autres <ph name="BEGIN_LINK_OSS" />logiciels libres<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Vos modifications seront prises en compte au prochain redémarrage de Google Chrome.</translation>
<translation id="3444832043240812445">Cette page affiche uniquement des informations sur les erreurs récentes si vous <ph name="BEGIN_LINK" />activez l'envoi de rapports d'erreur<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_gu.xtb b/chromium/components/strings/components_google_chrome_strings_gu.xtb
index d1d9fa82205..9de8d67e5ab 100644
--- a/chromium/components/strings/components_google_chrome_strings_gu.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_gu.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="gu">
<translation id="1016765312371154165">Chrome યોગà«àª¯ રીતે શટ ડાઉન થયà«àª‚ નહોતà«àª‚.</translation>
<translation id="130631256467250065">તમારા ફેરફારો તમે આગલી વખતે તમારા ઉપકરણને ફરી પà«àª°àª¾àª°àª‚ભ કરશો તà«àª¯àª¾àª°à«‡ પà«àª°àª­àª¾àªµàª®àª¾àª‚ આવશે.</translation>
+<translation id="2147651015520127414">Chrome ઠચકાસણી કરી છે કે <ph name="ISSUER" /> ઠઆ વેબસાઇટનà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° ઇસà«àª¯à« કરà«àª¯à«àª‚ છે.</translation>
<translation id="2874156562296220396">Google Chrome <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> ઓપન સોરà«àª¸ પà«àª°à«‹àªœà«‡àª•à«àªŸ અને અનà«àª¯ <ph name="BEGIN_LINK_OSS" />ઓપન સોરà«àª¸ સૉફà«àªŸàªµà«‡àª°<ph name="END_LINK_OSS" /> દà«àªµàª¾àª°àª¾ સંભવ થયà«àª‚ છે.</translation>
<translation id="3140883423282498090">તમે આગલી વખત Google Chrome ને ફરીથી શરૂ કરશો તà«àª¯àª¾àª°à«‡ તમારા ફેરફારો પà«àª°àª­àª¾àªµà«€ થશે.</translation>
<translation id="3444832043240812445">આ પૃષà«àª  તો જ તમારા હાલનાં કà«àª°à«‡àª¶à«‡àª¸ પર માહિતી બતાવે છે જો તમે <ph name="BEGIN_LINK" />કà«àª°à«‡àª¶ રિપોરà«àªŸàª¿àª‚ગ સકà«àª·àª® કરો છો<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_hi.xtb b/chromium/components/strings/components_google_chrome_strings_hi.xtb
index 7f7004a163c..7f5e55978b1 100644
--- a/chromium/components/strings/components_google_chrome_strings_hi.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_hi.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="hi">
<translation id="1016765312371154165">Chrome सही तरीके से बंद नहीं हà¥à¤† था.</translation>
<translation id="130631256467250065">अगली बार अपना डिवाइस पà¥à¤¨: पà¥à¤°à¤¾à¤°à¤‚भ करने पर आपके परिवरà¥à¤¤à¤¨ पà¥à¤°à¤­à¤¾à¤µà¥€ हो जाà¤à¤‚गे.</translation>
+<translation id="2147651015520127414">Chrome ने सतà¥â€à¤¯à¤¾à¤ªà¤¿à¤¤ किया है कि वेबसाइट का यह पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° <ph name="ISSUER" /> ने जारी किया है.</translation>
<translation id="2874156562296220396">Google Chrome को <ph name="BEGIN_LINK_CHROMIUM" />कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤®<ph name="END_LINK_CHROMIUM" /> ओपन सोरà¥à¤¸ पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ और अनà¥à¤¯ <ph name="BEGIN_LINK_OSS" />ओपन सोरà¥à¤¸ सॉफà¥à¤Ÿà¤µà¥‡à¤¯à¤°<ph name="END_LINK_OSS" /> ने संभव बनाया है.</translation>
<translation id="3140883423282498090">आपके दà¥à¤µà¤¾à¤°à¤¾ अगली बार Google Chrome को पà¥à¤¨: लॉनà¥â€à¤š करने पर आपके परिवरà¥à¤¤à¤¨ पà¥à¤°à¤­à¤¾à¤µà¥€ हो जाà¤à¤‚गे.</translation>
<translation id="3444832043240812445">यदि आप <ph name="BEGIN_LINK" />कà¥à¤°à¥ˆà¤¶ रिपोरà¥à¤Ÿà¤¿à¤‚ग सकà¥à¤·à¤®<ph name="END_LINK" /> करते हैं तो यह पृषà¥â€à¤  केवल आपके हाल ही के कà¥à¤°à¥ˆà¤¶ की जानकारी पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ करेगा.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_hr.xtb b/chromium/components/strings/components_google_chrome_strings_hr.xtb
index 1240bbef3ea..a9302b345b4 100644
--- a/chromium/components/strings/components_google_chrome_strings_hr.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_hr.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="hr">
<translation id="1016765312371154165">Chrome se nije ispravno zatvorio.</translation>
<translation id="130631256467250065">Promjene će poÄeti vrijediti sljedeći put kad ponovo pokrenete ureÄ‘aj.</translation>
+<translation id="2147651015520127414">Chrome je potvrdio da je <ph name="ISSUER" /> izdao certifikat web-lokacije.</translation>
<translation id="2874156562296220396">Google Chrome omogućili su <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" />, projekt utemeljen na otvorenom kôdu i drugi <ph name="BEGIN_LINK_OSS" />softveri utemeljeni na otvorenom kôdu<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Vaše izmjene stupit će na snagu sljedeći put kada se ponovo pokrene Google Chrome.</translation>
<translation id="3444832043240812445">Ova stranica prikazuje samo informacije o vašim nedavnim padovima ako <ph name="BEGIN_LINK" />omogućite izvješćivanja o padu<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_hu.xtb b/chromium/components/strings/components_google_chrome_strings_hu.xtb
index 6e8a1d51c6e..8e37dcee7b9 100644
--- a/chromium/components/strings/components_google_chrome_strings_hu.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_hu.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="hu">
<translation id="1016765312371154165">A Chrome nem záródott be megfelelően.</translation>
<translation id="130631256467250065">A módosítások az eszköz következő újraindításakor lépnek életbe.</translation>
+<translation id="2147651015520127414">A Chrome ellenőrizte, hogy a(z) <ph name="ISSUER" /> adta ki ezt a webhelytanúsítványt.</translation>
<translation id="2874156562296220396">A Google Chrome a <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> nyílt forráskódú projektnek és további <ph name="BEGIN_LINK_OSS" />nyílt forráskódú szoftvereknek<ph name="END_LINK_OSS" /> köszönhetően jött létre.</translation>
<translation id="3140883423282498090">A módosítások a következő alkalommal lépnek életbe, amikor újraindítja a Google Chrome-ot.</translation>
<translation id="3444832043240812445">Ez az oldal csak akkor jelenít meg információkat a legutóbbi rendszerösszeomlásokról, ha <ph name="BEGIN_LINK" />engedélyezi a hibabejelentést<ph name="END_LINK" /> .</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_id.xtb b/chromium/components/strings/components_google_chrome_strings_id.xtb
index 3fb47959e96..99fa0b8212a 100644
--- a/chromium/components/strings/components_google_chrome_strings_id.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_id.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="id">
<translation id="1016765312371154165">Chrome tidak dinonaktifkan dengan benar.</translation>
<translation id="130631256467250065">Perubahan Anda akan diterapkan pada saat Anda nanti menyalakan ulang perangkat.</translation>
+<translation id="2147651015520127414">Chrome memverifikasi bahwa <ph name="ISSUER" /> menerbitkan sertifikat situs web ini.</translation>
<translation id="2874156562296220396">Google Chrome bisa ada berkat proyek sumber terbuka yaitu <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> dan berbagai <ph name="BEGIN_LINK_OSS" />software sumber terbuka<ph name="END_LINK_OSS" /> lainnya.</translation>
<translation id="3140883423282498090">Perubahan Anda akan berlaku pada peluncuran ulang Google Chrome selanjutnya.</translation>
<translation id="3444832043240812445">Laman ini hanya menunjukkan informasi tentang kondisi ngadat terkini jika Anda <ph name="BEGIN_LINK" />mengaktifkan pelaporan kondisi ngadat<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_it.xtb b/chromium/components/strings/components_google_chrome_strings_it.xtb
index 3749f844d29..122fd2f0204 100644
--- a/chromium/components/strings/components_google_chrome_strings_it.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_it.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="it">
<translation id="1016765312371154165">Chrome non si è chiuso correttamente.</translation>
<translation id="130631256467250065">Le modifiche verranno applicate al successivo riavvio del dispositivo.</translation>
+<translation id="2147651015520127414">Chrome ha verificato che <ph name="ISSUER" /> ha emesso il certificato del sito web.</translation>
<translation id="2874156562296220396">Google Chrome è reso possibile dal progetto open source <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> e da altri <ph name="BEGIN_LINK_OSS" />software open source<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Le modifiche verranno applicate al prossimo riavvio di Google Chrome.</translation>
<translation id="3444832043240812445">Questa pagina mostra solo informazioni sugli arresti anomali recenti se <ph name="BEGIN_LINK" />attivi la segnalazione degli arresti anomali<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_iw.xtb b/chromium/components/strings/components_google_chrome_strings_iw.xtb
index ec29f2cc481..847f25ba4cb 100644
--- a/chromium/components/strings/components_google_chrome_strings_iw.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_iw.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="iw">
<translation id="1016765312371154165">â€×›×™×‘וי Chrome ×œ× ×‘×•×¦×¢ כהלכה.</translation>
<translation id="130631256467250065">×”×©×™× ×•×™×™× ×™×™×›× ×¡×• לתוקף ×‘×¤×¢× ×”×‘××” שתפעיל מחדש ×ת המכשיר.</translation>
+<translation id="2147651015520127414">â€Chrome ×ימת ש-<ph name="ISSUER" /> הנפיק ×ת ×”×ישור של ×תר ×–×”.</translation>
<translation id="2874156562296220396">â€Google Chrome ×§×™×™× ×”×•×“×•×ª לפרויקט המקור הפתוח <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> <ph name="BEGIN_LINK_OSS" />ותוכנות מקור פתוח ×חרות<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">â€×”×©×™× ×•×™×™× ×™×™×›× ×¡×• לתוקף ×‘×¤×¢× ×”×‘××” שתשיק מחדש ×ת Google Chrome.</translation>
<translation id="3444832043240812445">דף ×–×” מציג מידע על הקריסות ×”×חרונות בלבד ×× <ph name="BEGIN_LINK" />תפעיל ×ת ×פשרות הדיווח על קריסות<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ja.xtb b/chromium/components/strings/components_google_chrome_strings_ja.xtb
index 838cacd09dd..df9d88bbc30 100644
--- a/chromium/components/strings/components_google_chrome_strings_ja.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ja.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ja">
<translation id="1016765312371154165">Chrome ã¯æ­£ã—ã終了ã—ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="130631256467250065">変更内容ã¯ã€æ¬¡å›žã®ç«¯æœ«ã®èµ·å‹•æ™‚ã«å映ã•ã‚Œã¾ã™ã€‚</translation>
+<translation id="2147651015520127414">ã“ã®ã‚¦ã‚§ãƒ–サイトã®è¨¼æ˜Žæ›¸ãŒ <ph name="ISSUER" /> 発行ã®ã‚‚ã®ã§ã‚ã‚‹ã¨ç¢ºèªã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="2874156562296220396">Google Chrome ã¯ã‚ªãƒ¼ãƒ—ンソース プロジェクト <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> ã‚„ãã®ä»–ã®<ph name="BEGIN_LINK_OSS" />オープンソース ソフトウェア<ph name="END_LINK_OSS" />ã«ã‚ˆã£ã¦å®Ÿç¾ã—ã¾ã—ãŸã€‚</translation>
<translation id="3140883423282498090">変更内容ã¯æ¬¡ã« Google Chrome ã‚’å†èµ·å‹•ã—ãŸã¨ãã«æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚</translation>
<translation id="3444832043240812445"><ph name="BEGIN_LINK" />障害レãƒãƒ¼ãƒˆã‚’有効<ph name="END_LINK" />ã«ã—ãŸå ´åˆã«ã®ã¿ã€ã“ã®ãƒšãƒ¼ã‚¸ã«æœ€è¿‘ã®éšœå®³æƒ…å ±ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_kn.xtb b/chromium/components/strings/components_google_chrome_strings_kn.xtb
index a48171c422d..b09feaa8241 100644
--- a/chromium/components/strings/components_google_chrome_strings_kn.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_kn.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="kn">
<translation id="1016765312371154165">Chrome ಅನà³à²¨à³ ಸರಿಯಾಗಿ ಸà³à²¥à²—ಿತಗೊಳಿಸಲಾಗಿಲà³à²².</translation>
<translation id="130631256467250065">ನಿಮà³à²® ಸಾಧನವನà³à²¨à³ ನೀವೠಮà³à²‚ದಿನ ಬಾರಿ ಮರà³à²ªà³à²°à²¾à²°à²‚ಭಿಸಿದಾಗ ನಿಮà³à²® ಬದಲಾವಣೆಗಳೠಕಾರà³à²¯à²—ತಗೊಳà³à²³à³à²¤à³à²¤à²µà³†.</translation>
+<translation id="2147651015520127414">ಈ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ <ph name="ISSUER" /> ನೀಡಿದೆ ಎಂಬà³à²¦à²¾à²—ಿ Chrome ಪರಿಶೀಲಿಸಿದೆ.</translation>
<translation id="2874156562296220396"><ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> ತೆರೆದ ಮೂಲ ಪà³à²°à²¾à²œà³†à²•à³à²Ÿà³ ಮತà³à²¤à³ ಇತರ <ph name="BEGIN_LINK_OSS" />ತೆರೆದ ಮೂಲ ಸಾಫà³à²Ÿà³â€Œà²µà³‡à²°à³â€Œâ€Œ<ph name="END_LINK_OSS" /> ನಿಂದ Google Chrome ಅನà³à²¨à³ ಸಾಧà³à²¯à²µà²¾à²—ಿಸಲಾಗಿದೆ.</translation>
<translation id="3140883423282498090">ನೀವೠಮà³à²‚ದಿನ ಬಾರಿ Google Chrome ಮರà³à²ªà³à²°à²¾à²°à²‚ಭಿಸಿದಾಗ ನಿಮà³à²® ಬದಲಾವಣೆಗಳೠಕಾರà³à²¯à²—ತಗೊಳà³à²³à³à²¤à³à²¤à²µà³†.</translation>
<translation id="3444832043240812445">ನೀವೠ<ph name="BEGIN_LINK" />ಕà³à²°â€à³à²¯à²¾à²¶à³â€Œâ€Œ ವರದಿಮಾಡà³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸಿದರೆ<ph name="END_LINK" /> ನಿಮà³à²® ಇತà³à²¤à³€à²šà²¿à²¨ ಕà³à²°â€à³à²¯à²¾à²¶à³â€Œà²—ಳಲà³à²²à²¿ ಮಾಹಿತಿಯನà³à²¨à³ ಈ ಪà³à²Ÿ ತೋರಿಸà³à²¤à³à²¤à²¦à³†.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ko.xtb b/chromium/components/strings/components_google_chrome_strings_ko.xtb
index 5f886042de1..f572798c244 100644
--- a/chromium/components/strings/components_google_chrome_strings_ko.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ko.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ko">
<translation id="1016765312371154165">Chromeì´ ì œëŒ€ë¡œ 종료ë˜ì§€ 않았습니다.</translation>
<translation id="130631256467250065">기기를 다시 시작할 ë•Œ ë³€ê²½ì‚¬í•­ì´ ì ìš©ë©ë‹ˆë‹¤.</translation>
+<translation id="2147651015520127414">Chromeì´ <ph name="ISSUER" />ì—ì„œ ì´ ì›¹ì‚¬ì´íŠ¸ì˜ ì¸ì¦ì„œë¥¼ 발행했ìŒì„ 확ì¸í–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="2874156562296220396">Chromeì€ <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> 오픈소스 프로ì íŠ¸ë¥¼ 비롯한 여러 <ph name="BEGIN_LINK_OSS" />오픈소스 소프트웨어<ph name="END_LINK_OSS" />ì— ê¸°ì´ˆí•´ 만들어진 브ë¼ìš°ì €ìž…니다.</translation>
<translation id="3140883423282498090">Chromeì„ ë‹¤ì‹œ 시작하면 ë³€ê²½ì‚¬í•­ì´ ì ìš©ë©ë‹ˆë‹¤.</translation>
<translation id="3444832043240812445"><ph name="BEGIN_LINK" />ë¹„ì •ìƒ ì¢…ë£Œ 보고를 사용<ph name="END_LINK" />하면 최근 ë¹„ì •ìƒ ì¢…ë£Œì— ëŒ€í•œ 정보만 ì´ íŽ˜ì´ì§€ì— 표시ë©ë‹ˆë‹¤.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_lt.xtb b/chromium/components/strings/components_google_chrome_strings_lt.xtb
index 4d2b5e76250..857c7d459dd 100644
--- a/chromium/components/strings/components_google_chrome_strings_lt.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_lt.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="lt">
<translation id="1016765312371154165">„Chrome“ netinkamai išsijungė.</translation>
<translation id="130631256467250065">Pakeitimai įsigalios kitą kartą iš naujo paleidus įrenginį.</translation>
+<translation id="2147651015520127414">„Chrome“ patvirtino, kad „<ph name="ISSUER" />“ išdavė šį svetainės sertifikatą.</translation>
<translation id="2874156562296220396">„Google Chrome“ sukurta pasitelkus atvirojo kodo projektą <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> ir kitą <ph name="BEGIN_LINK_OSS" />atvirojo kodo programinę įrangą<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Pakeitimai įsigalios kitą kartą iš naujo paleidus „Google Chrome“.</translation>
<translation id="3444832043240812445">Å iame puslapyje rodoma informacija apie paskutines strigtis, jei <ph name="BEGIN_LINK" />įgalinote strigÄių ataskaitų teikimÄ…<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_lv.xtb b/chromium/components/strings/components_google_chrome_strings_lv.xtb
index 989f49979f6..26ff2285739 100644
--- a/chromium/components/strings/components_google_chrome_strings_lv.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_lv.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="lv">
<translation id="1016765312371154165">Chrome netika pareizi izslēgts.</translation>
<translation id="130631256467250065">Izmaiņas stÄsies spÄ“kÄ nÄkamajÄ reizÄ“, kad restartÄ“siet ierÄ«ci.</translation>
+<translation id="2147651015520127414">Chrome apstiprinÄja, ka <ph name="ISSUER" /> izsniedza Å¡Ä«s vietnes sertifikÄtu.</translation>
<translation id="2874156562296220396">Pakalpojumu Google Chrome nodroÅ¡ina <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> atklÄtÄ pirmkoda projekts un <ph name="BEGIN_LINK_OSS" />atklÄtÄ pirmkoda programmatÅ«ra<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">JÅ«su izmaiņas stÄsies spÄ“kÄ nÄkamajÄ reizÄ“, kad atkÄrtoti palaidÄ«siet pÄrlÅ«ku Google Chrome.</translation>
<translation id="3444832043240812445">Å ajÄ lapÄ tiek parÄdÄ«ta tikai informÄcija par pÄ“dÄ“jÄ laika avÄrijÄm, ja <ph name="BEGIN_LINK" />iespÄ“jojat avÄriju pÄrskatu izveidi<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ml.xtb b/chromium/components/strings/components_google_chrome_strings_ml.xtb
index 4109a0eb387..95fd96defe6 100644
--- a/chromium/components/strings/components_google_chrome_strings_ml.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ml.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ml">
<translation id="1016765312371154165">Chrome ശരിയായി à´·à´Ÿàµà´Ÿàµâ€Œà´¡àµ—ൺ ചെയàµâ€Œà´¤à´¿à´Ÿàµà´Ÿà´¿à´²àµà´².</translation>
<translation id="130631256467250065">നിങàµà´™àµ¾ à´…à´Ÿàµà´¤àµà´¤ തവണ ഉപകരണം à´ªàµà´¨à´°à´¾à´°à´‚à´­à´¿à´•àµà´•àµà´®àµà´ªàµ‹àµ¾ മാറàµà´±à´™àµà´™àµ¾ à´ªàµà´°à´¾à´¬à´²àµà´¯à´¤àµà´¤à´¿àµ½ വരàµà´‚.</translation>
+<translation id="2147651015520127414">à´ˆ വെബàµâ€Œà´¸àµˆà´±àµà´±à´¿à´¨àµà´±àµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ <ph name="ISSUER" /> നൽകിയതാണെനàµà´¨àµ Chrome പരിശോധിചàµà´šàµà´±à´ªàµà´ªà´¿à´šàµà´šàµ.</translation>
<translation id="2874156562296220396">Google Chrome <ph name="BEGIN_LINK_CHROMIUM" />à´•àµà´°àµ‹à´®à´¿à´¯à´‚<ph name="END_LINK_CHROMIUM" /> à´“à´ªàµà´ªà´£àµâ€ സോഴàµà´¸àµ à´ªàµà´°àµ‹à´œà´•àµâ€Œà´Ÿàµà´‚ മറàµà´±àµ <ph name="BEGIN_LINK_OSS" />à´“à´ªàµà´ªà´£àµâ€ സോഴàµà´¸àµ സോഫàµâ€Œà´±àµà´±àµâ€Œà´µàµ†à´¯à´±àµà´‚<ph name="END_LINK_OSS" /> ഉപയോഗിചàµà´šàµ നിരàµâ€à´®àµà´®à´¿à´šàµà´šà´¤à´¾à´£àµ.</translation>
<translation id="3140883423282498090">നിങàµà´™à´³àµà´Ÿàµ† മാറàµà´±à´™àµà´™àµ¾ à´…à´Ÿàµà´¤àµà´¤ തവണ Google Chrome à´ªàµà´¨à´ƒà´¸à´®à´¾à´°à´‚à´­à´¿à´•àµà´•àµà´®àµà´ªàµ‹àµ¾ à´ªàµà´°à´¾à´¬à´²àµà´¯à´¤àµà´¤à´¿àµ½ വരàµà´‚.</translation>
<translation id="3444832043240812445">നിങàµà´™à´³àµâ€ <ph name="BEGIN_LINK" />à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹à´°àµâ€à´Ÿàµà´Ÿà´¿à´‚ഗൠപàµà´°à´¾à´ªàµà´¤à´®à´¾à´•àµà´•àµà´•à´¯à´¾à´£àµ†à´™àµà´•à´¿à´²àµâ€<ph name="END_LINK" /> നിങàµà´™à´³àµà´Ÿàµ† സമീപകാല à´•àµà´°à´¾à´·àµà´•à´³à´¿à´²àµ† വിവരങàµà´™à´³àµâ€ മാതàµà´°à´‚ à´ˆ പേജൠകാണികàµà´•àµà´¨àµà´¨àµ.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_mr.xtb b/chromium/components/strings/components_google_chrome_strings_mr.xtb
index ea3c96664d1..0e0ff230e79 100644
--- a/chromium/components/strings/components_google_chrome_strings_mr.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_mr.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="mr">
<translation id="1016765312371154165">Chrome योगà¥à¤¯à¤°à¤¿à¤¤à¥à¤¯à¤¾ बंद à¤à¤¾à¤²à¥‡ नाही.</translation>
<translation id="130631256467250065">आपण आपलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¤¾ पà¥à¤¢à¥€à¤² वेळी पà¥à¤¨à¤°à¤¾à¤°à¤‚भ कराल तेवà¥à¤¹à¤¾ आपले बदल पà¥à¤°à¤­à¤¾à¤µà¥€ होतील.</translation>
+<translation id="2147651015520127414"><ph name="ISSUER" /> ने या वेबसाइटचे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° जारी केले हे Chrome ने सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ केले.</translation>
<translation id="2874156562296220396"><ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> मà¥à¤•à¥à¤¤-सà¥à¤°à¥‹à¤¤ पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ आणि अनà¥à¤¯ <ph name="BEGIN_LINK_OSS" />मà¥à¤•à¥à¤¤ सà¥à¤°à¥‹à¤¤ सॉफà¥à¤Ÿà¤µà¥‡à¤…र<ph name="END_LINK_OSS" /> दà¥à¤µà¤¾à¤°à¥‡ Google Chrome ची निरà¥à¤®à¤¿à¤¤à¥€ करणे शकà¥à¤¯ à¤à¤¾à¤²à¥‡.</translation>
<translation id="3140883423282498090">पà¥à¤¢à¥€à¤² वेळी आपण Google Chrome पà¥à¤¨à¥à¤¹à¤¾ लाà¤à¤š केलà¥à¤¯à¤¾à¤¨à¤‚तर आपले बदल पà¥à¤°à¤­à¤¾à¤µà¥€ होतील.</translation>
<translation id="3444832043240812445">हे पृषà¥à¤  आपण <ph name="BEGIN_LINK" />कॅश अहवाल सकà¥à¤·à¤®<ph name="END_LINK" /> केलà¥à¤¯à¤¾à¤¸ केवळ आपलà¥à¤¯à¤¾à¤²à¤¾ अलीकडील कà¥à¤°à¥…शची माहिती दरà¥à¤¶à¤µà¤¿à¤¤à¥‡.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ms.xtb b/chromium/components/strings/components_google_chrome_strings_ms.xtb
index 4a021bd9604..6b57838c830 100644
--- a/chromium/components/strings/components_google_chrome_strings_ms.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ms.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ms">
<translation id="1016765312371154165">Chrome tidak ditutup dengan betul.</translation>
<translation id="130631256467250065">Perubahan anda akan dilaksanakan apabila anda memulakan semula peranti anda pada masa akan datang.</translation>
+<translation id="2147651015520127414">Chrome mengesahkan bahawa <ph name="ISSUER" /> telah mengeluarkan sijil tapak web ini.</translation>
<translation id="2874156562296220396">Google Chrome berjaya dilaksanakan melalui projek sumber terbuka <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> dan <ph name="BEGIN_LINK_OSS" />perisian sumber terbuka<ph name="END_LINK_OSS" /> yang lain.</translation>
<translation id="3140883423282498090">Perubahan anda akan berkuat kuasa apabila anda melancarkan semula Google Chrome pada masa hadapan.</translation>
<translation id="3444832043240812445">Halaman ini hanya menunjukkan maklumat mengenai nahas terkini anda jika anda <ph name="BEGIN_LINK" />mendayakan laporan nahas<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_nl.xtb b/chromium/components/strings/components_google_chrome_strings_nl.xtb
index dbfa5e645e1..52f0ad61de0 100644
--- a/chromium/components/strings/components_google_chrome_strings_nl.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_nl.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="nl">
<translation id="1016765312371154165">Chrome is niet correct afgesloten.</translation>
<translation id="130631256467250065">Je wijzigingen worden doorgevoerd wanneer je het apparaat opnieuw opstart.</translation>
+<translation id="2147651015520127414">Chrome heeft geverifieerd dat <ph name="ISSUER" /> het certificaat voor deze website heeft verstrekt.</translation>
<translation id="2874156562296220396">Google Chrome wordt mogelijk gemaakt door het open-source project <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> en andere <ph name="BEGIN_LINK_OSS" />open-source software<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Je wijzigingen worden toegepast als je Google Chrome opnieuw start.</translation>
<translation id="3444832043240812445">Deze pagina bevat alleen informatie over recente crashes als je <ph name="BEGIN_LINK" />crashrapportage inschakelt<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_no.xtb b/chromium/components/strings/components_google_chrome_strings_no.xtb
index b56bbde8ff8..af2e13c4a1a 100644
--- a/chromium/components/strings/components_google_chrome_strings_no.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_no.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="no">
<translation id="1016765312371154165">Chrome ble ikke avsluttet på riktig måte.</translation>
<translation id="130631256467250065">Endringene trer i kraft neste gang du starter enheten på nytt.</translation>
+<translation id="2147651015520127414">Chrome bekreftet at sertifikatet for dette nettstedet er utstedt av <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Google Chrome er tilgjengelig som følge av prosjektet for åpen kilde, <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" />, og annen <ph name="BEGIN_LINK_OSS" />programvare for åpen kilde<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Endringene dine trer i kraft neste gang du starter Google Chrome.</translation>
<translation id="3444832043240812445">Denne siden viser kun informasjon om nylige programstopp hvis du <ph name="BEGIN_LINK" />aktiverer rapportering av programstopp<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_pl.xtb b/chromium/components/strings/components_google_chrome_strings_pl.xtb
index db20dae9ac8..05ffe5ef78c 100644
--- a/chromium/components/strings/components_google_chrome_strings_pl.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_pl.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="pl">
<translation id="1016765312371154165">Chrome nie został poprawnie zamknięty.</translation>
<translation id="130631256467250065">Zmiany zostaną zastosowane przy następnym uruchomieniu urządzenia.</translation>
+<translation id="2147651015520127414">Chrome sprawdził, że wydawcą certyfikatu tej witryny jest <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Stworzenie przeglądarki Google Chrome było możliwe dzięki projektowi open source <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> i innym <ph name="BEGIN_LINK_OSS" />programom o otwartym kodzie źródłowym<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Zmiany zaczną obowiązywać po ponownym uruchomieniu Google Chrome.</translation>
<translation id="3444832043240812445">Ta strona zawiera informacje o ostatnich awariach tylko w przypadku <ph name="BEGIN_LINK" />włączenia funkcji zgłaszania awarii<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_pt-BR.xtb b/chromium/components/strings/components_google_chrome_strings_pt-BR.xtb
index 42a2762c194..c558f0d8221 100644
--- a/chromium/components/strings/components_google_chrome_strings_pt-BR.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_pt-BR.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="pt-BR">
<translation id="1016765312371154165">O Chrome não foi encerrado corretamente.</translation>
<translation id="130631256467250065">As alterações entrarão em vigor na próxima vez que você reiniciar o dispositivo.</translation>
+<translation id="2147651015520127414">O Chrome verificou que <ph name="ISSUER" /> emitiu o certificado desse website.</translation>
<translation id="2874156562296220396">O Google Chrome foi possibilitado pelo projeto de código aberto <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> e outros <ph name="BEGIN_LINK_OSS" />softwares de código aberto<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Suas alterações terão efeito na próxima vez que você reiniciar o Google Chrome.</translation>
<translation id="3444832043240812445">Esta página mostra apenas informações sobre suas falhas recentes se você <ph name="BEGIN_LINK" />ativar relatórios de erros<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_pt-PT.xtb b/chromium/components/strings/components_google_chrome_strings_pt-PT.xtb
index 763dbb4ce28..f86987732ef 100644
--- a/chromium/components/strings/components_google_chrome_strings_pt-PT.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_pt-PT.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="pt-PT">
<translation id="1016765312371154165">O Chrome não foi corretamente encerrado.</translation>
<translation id="130631256467250065">As alterações terão efeito da próxima vez que reiniciar o dispositivo.</translation>
+<translation id="2147651015520127414">O Chrome confirmou que <ph name="ISSUER" /> emitiu o certificado deste Website.</translation>
<translation id="2874156562296220396">O Google Chrome foi concretizado graças ao projecto open source (código fonte aberto) <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" />, assim como a outro <ph name="BEGIN_LINK_OSS" />software open source<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">As alterações terão efeito da próxima vez que voltar a iniciar o Google Chrome.</translation>
<translation id="3444832043240812445">Esta página mostra informações sobre falhas recentes apenas se <ph name="BEGIN_LINK" />ativar relatórios de falha<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ro.xtb b/chromium/components/strings/components_google_chrome_strings_ro.xtb
index 039753ff12a..a8e2fa8af1c 100644
--- a/chromium/components/strings/components_google_chrome_strings_ro.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ro.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ro">
<translation id="1016765312371154165">Chrome nu s-a închis corect.</translation>
<translation id="130631256467250065">Modificările dvs. se vor aplica următoarea dată când reporniți dispozitivul.</translation>
+<translation id="2147651015520127414">Chrome s-a asigurat că certificatul acestui site a fost emis de <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Google Chrome există ca urmare a proiectului open source <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> și al altor <ph name="BEGIN_LINK_OSS" />software-uri open source<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Modificările se vor aplica următoarea dată când relansați Google Chrome.</translation>
<translation id="3444832043240812445">Această pagină afișează informații cu privire la recentele blocări numai dacă <ph name="BEGIN_LINK" />activezi raportarea blocărilor<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ru.xtb b/chromium/components/strings/components_google_chrome_strings_ru.xtb
index c129491abab..562f62ec0f2 100644
--- a/chromium/components/strings/components_google_chrome_strings_ru.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ru.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ru">
<translation id="1016765312371154165">Работа Chrome была завершена некорректно.</translation>
<translation id="130631256467250065">Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑтупÑÑ‚ в Ñилу поÑле перезагрузки уÑтройÑтва.</translation>
+<translation id="2147651015520127414">Chrome определил, что Ñертификат Ñайта выпущен компанией <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Браузер Google Chrome Ñоздан на оÑнове проекта <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> и другого <ph name="BEGIN_LINK_OSS" />программного обеÑÐ¿ÐµÑ‡ÐµÐ½Ð¸Ñ Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ иÑходным кодом<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">ВнеÑенные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñтанут активны поÑле перезапуÑка Google Chrome.</translation>
<translation id="3444832043240812445">Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ недавних ÑбоÑÑ… отображаетÑÑ Ð½Ð° Ñтой Ñтранице только при <ph name="BEGIN_LINK" />включенной функции отчетов о ÑбоÑÑ…<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_sk.xtb b/chromium/components/strings/components_google_chrome_strings_sk.xtb
index eb18fc1f07e..5a27ab6acc9 100644
--- a/chromium/components/strings/components_google_chrome_strings_sk.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_sk.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="sk">
<translation id="1016765312371154165">Chrome nebol správne vypnutý.</translation>
<translation id="130631256467250065">Zmeny sa prejavia po ÄalÅ¡om reÅ¡tartovaní zariadenia.</translation>
+<translation id="2147651015520127414">Chrome overil, že certifikát tohto webu vydal vydavateľ <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Vytvorenie prehliadaÄa Google Chrome bolo umožnené prostredníctvom projektu otvoreného zdrojového kódu <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> a ÄalÅ¡ieho <ph name="BEGIN_LINK_OSS" />softvéru s otvoreným zdrojovým kódom<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Zmeny sa prejavia pri nasledujúcom reÅ¡tartovaní prehliadaÄa Google Chrome.</translation>
<translation id="3444832043240812445">Táto stránka zobrazuje informácie o nedávnych zlyhaniach, len ak ste <ph name="BEGIN_LINK" />povolili hlásenia zlyhaní<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_sl.xtb b/chromium/components/strings/components_google_chrome_strings_sl.xtb
index fcc8d2951e3..25866f90535 100644
--- a/chromium/components/strings/components_google_chrome_strings_sl.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_sl.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="sl">
<translation id="1016765312371154165">Chrome se ni pravilno zaustavil.</translation>
<translation id="130631256467250065">Spremembe bodo uveljavljene pri naslednjem vnoviÄnem zagonu naprave.</translation>
+<translation id="2147651015520127414">Chrome je preveril, da je izdajatelj <ph name="ISSUER" /> izdal potrdilo tega spletnega mesta.</translation>
<translation id="2874156562296220396">Brskalnik Google Chrome omogoÄa odprtokodni projekt <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> in druga <ph name="BEGIN_LINK_OSS" />odprtokodna programska oprema<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Spremembe bodo zaÄele veljati ob naslednjem zagonu Google Chroma.</translation>
<translation id="3444832043240812445">Ta stran prikazuje informacije o zadnjih zruÅ¡itvah, samo Äe <ph name="BEGIN_LINK" />omogoÄite poroÄanje o zruÅ¡itvah<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_sr.xtb b/chromium/components/strings/components_google_chrome_strings_sr.xtb
index 95130cf665f..96725de5dff 100644
--- a/chromium/components/strings/components_google_chrome_strings_sr.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_sr.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="sr">
<translation id="1016765312371154165">Chrome Ñе није иÑправно затворио.</translation>
<translation id="130631256467250065">Промене ће Ñтупити на Ñнагу када Ñледећи пут поново покренете уређај.</translation>
+<translation id="2147651015520127414">Chrome је потврдио да је <ph name="ISSUER" /> издао Ñертификат овог веб-Ñајта.</translation>
<translation id="2874156562296220396"><ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> пројекат Ñофтвера отвореног кода и други типови <ph name="BEGIN_LINK_OSS" />Ñофтвера отвореног кода<ph name="END_LINK_OSS" /> Ñу омогућили наÑтанак програма Google Chrome.</translation>
<translation id="3140883423282498090">Промене ће Ñтупити на Ñнагу када Ñледећи пут поново покренете Google Chrome.</translation>
<translation id="3444832043240812445">Ова Ñтраница приказује информације о недавним отказивањима Ñамо уколико <ph name="BEGIN_LINK" />омогућите извештавање о отказивањима<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_sv.xtb b/chromium/components/strings/components_google_chrome_strings_sv.xtb
index 599ee4fbb00..052ad600845 100644
--- a/chromium/components/strings/components_google_chrome_strings_sv.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_sv.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="sv">
<translation id="1016765312371154165">Chrome avslutades inte korrekt.</translation>
<translation id="130631256467250065">Dina ändringar börjar gälla nästa gång du startar om enheten.</translation>
+<translation id="2147651015520127414">Chrome har verifierat att <ph name="ISSUER" /> har utfärdat webbplatsens certifikat.</translation>
<translation id="2874156562296220396">Google Chrome fungerar tack vare det öppna källkodsprojektet <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> och andra <ph name="BEGIN_LINK_OSS" />program med öppen källkod<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Ändringarna börjar gälla nästa gång du startar Google Chrome.</translation>
<translation id="3444832043240812445">Du måste <ph name="BEGIN_LINK" />aktivera kraschrapportering<ph name="END_LINK" /> för att information om de senaste krascherna ska visas på den här sidan.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_sw.xtb b/chromium/components/strings/components_google_chrome_strings_sw.xtb
index 46b48b04d8e..03e7f74d2bb 100644
--- a/chromium/components/strings/components_google_chrome_strings_sw.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_sw.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="sw">
<translation id="1016765312371154165">Chrome haikuzimika kwa njia sahihi.</translation>
<translation id="130631256467250065">Mabadiliko yako yatatekelezwa utakapowasha upya tena kifaa chako.</translation>
+<translation id="2147651015520127414">Chrome imethibitisha kuwa <ph name="ISSUER" /> ndiye mtoa cheti cha tovuti hii.</translation>
<translation id="2874156562296220396">Google Chrome imefanikishwa na mradi wa programu huria wa <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> na <ph name="BEGIN_LINK_OSS" />programu huria<ph name="END_LINK_OSS" /> zingine.</translation>
<translation id="3140883423282498090">Mabadiliko yako yataanza kufanya kazi wakati ujao utakapozindua Google Chrome.</translation>
<translation id="3444832043240812445">Ukurasa huu unaonyesha tu maelezo yako ya uharibifu wa hivi karibuni ukiwezesha <ph name="BEGIN_LINK" />kuripoti uharibifu<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_ta.xtb b/chromium/components/strings/components_google_chrome_strings_ta.xtb
index bd558ec6ace..e4caed11c76 100644
--- a/chromium/components/strings/components_google_chrome_strings_ta.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ta.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="ta">
<translation id="1016765312371154165">Chrome சரியாக நிறà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="130631256467250065">அடà¯à®¤à¯à®¤ à®®à¯à®±à¯ˆ உஙà¯à®•à®³à¯ சாதனதà¯à®¤à¯ˆ மறà¯à®¤à¯Šà®Ÿà®•à¯à®•à®®à¯ செயà¯à®¯à¯à®®à¯à®ªà¯‹à®¤à¯, மாறà¯à®±à®™à¯à®•à®³à¯ செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®±à¯à®•à¯ வரà¯à®®à¯.</translation>
+<translation id="2147651015520127414">இநà¯à®¤ இணையதளச௠சானà¯à®±à®¿à®¤à®´à¯ <ph name="ISSUER" /> ஆல௠வழஙà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à®¾ என Chrome சரிபாரà¯à®¤à¯à®¤à®¤à¯.</translation>
<translation id="2874156562296220396"><ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" />ஓபன௠சோரà¯à®¸à¯ திடà¯à®Ÿà®ªà¯à®ªà®£à®¿ மறà¯à®±à¯à®®à¯ <ph name="BEGIN_LINK_OSS" />ஓபன௠சோரà¯à®¸à¯ மெனà¯à®ªà¯Šà®°à¯à®³à¯<ph name="END_LINK_OSS" /> இவறà¯à®±à®¾à®²à¯ Google Chrome ஠உரà¯à®µà®¾à®•à¯à®•à¯à®µà®¤à¯ சாதà¯à®¤à®¿à®¯à®®à®¾à®©à®¤à¯.</translation>
<translation id="3140883423282498090">அடà¯à®¤à¯à®¤ à®®à¯à®±à¯ˆ Google Chrome ஠மீணà¯à®Ÿà¯à®®à¯ தொடஙà¯à®•à®¿à®¯à®µà¯à®Ÿà®©à¯ உஙà¯à®•à®³à¯ மாறà¯à®±à®™à¯à®•à®³à¯ செயலà¯à®ªà®Ÿà¯à®®à¯.</translation>
<translation id="3444832043240812445">நீஙà¯à®•à®³à¯ <ph name="BEGIN_LINK" />செயலிழபà¯à®ªà¯ பà¯à®•à®¾à®°à®³à®¿à®¤à¯à®¤à®²à¯ˆ இயகà¯à®•à®¿à®¯à®¿à®°à¯à®¨à¯à®¤à®¾à®²à¯<ph name="END_LINK" /> மடà¯à®Ÿà¯à®®à¯‡, இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ உஙà¯à®•à®³à¯à®Ÿà¯ˆà®¯ சமீபதà¯à®¤à®¿à®¯ செயலிழபà¯à®ªà¯à®•à®³à¯ˆà®ªà¯ பறà¯à®±à®¿à®¯ தகவலà¯à®•à®³à¯ˆà®•à¯ காணà¯à®ªà®¿à®•à¯à®•à¯à®®à¯.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_te.xtb b/chromium/components/strings/components_google_chrome_strings_te.xtb
index 6debbd530ba..f5ab78a147a 100644
--- a/chromium/components/strings/components_google_chrome_strings_te.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_te.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="te">
<translation id="1016765312371154165">Chrome సరిగà±à°—à°¾ షటౠడౌనౠకాలేదà±.</translation>
<translation id="130631256467250065">మీ మారà±à°ªà±à°²à± మీరౠమీ పరికరానà±à°¨à°¿ à°ªà±à°¨à°ƒà°ªà±à°°à°¾à°°à°‚భించే తదà±à°ªà°°à°¿à°¸à°¾à°°à°¿ à°ªà±à°°à°­à°¾à°µà°µà°‚తం à°…à°µà±à°¤à°¾à°¯à°¿.</translation>
+<translation id="2147651015520127414">Chrome à°ˆ వెబà±â€Œà°¸à±ˆà°Ÿà± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ <ph name="ISSUER" /> జారీ చేసినటà±à°²à± ధృవీకరించింది.</translation>
<translation id="2874156562296220396">Google Chrome <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> ఓపెనౠసోరà±à°¸à± à°ªà±à°°à°¾à°œà±†à°•à±à°Ÿà±â€Œ మరియౠఇతర <ph name="BEGIN_LINK_OSS" />open source software‌<ph name="END_LINK_OSS" /> వలà±à°² సాధà±à°¯à°‚ à°…à°µà±à°¤à±à°‚ది.</translation>
<translation id="3140883423282498090">మీ మారà±à°ªà±à°²à± మీరౠGoogle Chromeనౠమళà±à°²à±€ à°ªà±à°°à°¾à°°à°‚భించినపà±à°ªà±à°¡à± à°ªà±à°°à°­à°¾à°µà°¾à°¨à±à°¨à°¿ చూపà±à°¤à°¾à°¯à°¿.</translation>
<translation id="3444832043240812445">మీరౠ<ph name="BEGIN_LINK" />à°•à±à°°à°¾à°·à±â€Œ నివేదికనౠపà±à°°à°¾à°°à°‚భించినపà±à°¡à±<ph name="END_LINK" /> à°ˆ పేజీ మీ ఇటీవలి à°•à±à°°à°¾à°·à±â€Œà°² సమాచారానà±à°¨à°¿ మాతà±à°°à°®à±‡ చూపిసà±à°¤à±à°‚ది.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_th.xtb b/chromium/components/strings/components_google_chrome_strings_th.xtb
index 2bdd4752f35..59bb53342a5 100644
--- a/chromium/components/strings/components_google_chrome_strings_th.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_th.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="th">
<translation id="1016765312371154165">Chrome ไม่ได้ปิดอย่างถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="130631256467250065">à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸‚องคุณจะมีผลในครั้งถัดไปที่คุณรีสตาร์ทอุปà¸à¸£à¸“์ของคุณ</translation>
+<translation id="2147651015520127414">Chrome ยืนยันว่า <ph name="ISSUER" /> ได้ออà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸‚องเว็บไซต์นี้</translation>
<translation id="2874156562296220396">Google Chrome เป็นจริงขึ้นได้จาà¸à¹‚ครงà¸à¸²à¸£à¹‚อเพนซอร์ส <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> à¹à¸¥à¸° <ph name="BEGIN_LINK_OSS" />ซอฟต์à¹à¸§à¸£à¹Œà¹‚อเพนซอร์สอื่นๆ<ph name="END_LINK_OSS" /></translation>
<translation id="3140883423282498090">à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸‚องคุณจะมีผลในครั้งถัดไปที่คุณเปิด Google Chrome</translation>
<translation id="3444832043240812445">หน้าเว็บนี้จะà¹à¸ªà¸”งเฉพาะข้อมูลเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸‚้อขัดข้องที่เà¸à¸´à¸”ขึ้นเมื่อเร็วๆ นี้ของคุณเท่านั้น หาà¸à¸„ุณ<ph name="BEGIN_LINK" />เปิดใช้งานà¸à¸²à¸£à¸£à¸²à¸¢à¸‡à¸²à¸™à¸‚้อขัดข้อง<ph name="END_LINK" /></translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_tr.xtb b/chromium/components/strings/components_google_chrome_strings_tr.xtb
index 165a210e25d..dfec95dcf6f 100644
--- a/chromium/components/strings/components_google_chrome_strings_tr.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_tr.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="tr">
<translation id="1016765312371154165">Chrome doğru bir şekilde kapatılmadı.</translation>
<translation id="130631256467250065">Yaptığınız değişiklikler cihazı yeniden başlattığınızda etkinleşecektir.</translation>
+<translation id="2147651015520127414">Chrome, bu web sitesi sertifikasının <ph name="ISSUER" /> tarafından yayınlandığını doğruladı.</translation>
<translation id="2874156562296220396">Google Chrome, <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> açık kaynak projesi ve diğer <ph name="BEGIN_LINK_OSS" />açık kaynak yazılımlar<ph name="END_LINK_OSS" /> ile oluşturulmuştur.</translation>
<translation id="3140883423282498090">Yaptığınız değişiklikler Google Chrome'u yeniden başlattığınızda geçerli olacak.</translation>
<translation id="3444832043240812445">Karşılaştığınız son kilitlenme olayları hakkındaki bilgiler yalnızca <ph name="BEGIN_LINK" />kilitlenme bildirmeyi etkinleştirdiyseniz<ph name="END_LINK" /> bu sayfada gösterilir.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_uk.xtb b/chromium/components/strings/components_google_chrome_strings_uk.xtb
index d477e93adda..49f92a3b32a 100644
--- a/chromium/components/strings/components_google_chrome_strings_uk.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_uk.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="uk">
<translation id="1016765312371154165">Chrome було неправильно закрито.</translation>
<translation id="130631256467250065">Ваші зміни почнуть діÑти під Ñ‡Ð°Ñ Ð½Ð°Ñтупного перезапуÑку приÑтрою.</translation>
+<translation id="2147651015520127414">Chrome підтвердив, що Ñертифікат цьому веб-Ñайту надала ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ <ph name="ISSUER" />.</translation>
<translation id="2874156562296220396">Google Chrome було Ñтворено на оÑнові проекту програмного Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð· відкритим кодом <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> та іншого <ph name="BEGIN_LINK_OSS" />програмного Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð· відкритим кодом<ph name="END_LINK_OSS" />.</translation>
<translation id="3140883423282498090">Ваші зміни почнуть діÑти піÑÐ»Ñ Ð½Ð°Ñтупного перезапуÑку Google Chrome.</translation>
<translation id="3444832043240812445">Ðа цій Ñторінці відображаєтьÑÑ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð»Ð¸ÑˆÐµ про оÑтанні випадки аварійного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸, Ñкщо <ph name="BEGIN_LINK" />ввімкнено Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_vi.xtb b/chromium/components/strings/components_google_chrome_strings_vi.xtb
index fcc981fb1e3..1b30e0a222f 100644
--- a/chromium/components/strings/components_google_chrome_strings_vi.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_vi.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="vi">
<translation id="1016765312371154165">Chrome đã không tắt đúng cách.</translation>
<translation id="130631256467250065">Thay đổi của bạn sẽ có hiệu lực vào lần tiếp theo bạn khởi động lại thiết bị của mình.</translation>
+<translation id="2147651015520127414">Chrome xác minh <ph name="ISSUER" /> đã cấp chứng chỉ của trang web này.</translation>
<translation id="2874156562296220396">Google Chrome được xây dá»±ng bằng dá»± án nguồn mở <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> và <ph name="BEGIN_LINK_OSS" />phần má»m nguồn mở<ph name="END_LINK_OSS" /> khác.</translation>
<translation id="3140883423282498090">Thay đổi của bạn sẽ có hiệu lực vào lần tiếp theo bạn chạy lại Google Chrome.</translation>
<translation id="3444832043240812445">Trang này chỉ hiển thị thông tin vỠcác sự cố gần đây của bạn nếu bạn <ph name="BEGIN_LINK" />bật báo cáo sự cố<ph name="END_LINK" />.</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_zh-CN.xtb b/chromium/components/strings/components_google_chrome_strings_zh-CN.xtb
index 5bd645cf2aa..fd9902fc830 100644
--- a/chromium/components/strings/components_google_chrome_strings_zh-CN.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_zh-CN.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="zh-CN">
<translation id="1016765312371154165">Chrome 未正确关闭。</translation>
<translation id="130631256467250065">您所åšçš„更改会在下次é‡æ–°å¯åŠ¨è®¾å¤‡æ—¶ç”Ÿæ•ˆã€‚</translation>
+<translation id="2147651015520127414">Chrome å·²è¯å®žæ­¤ç½‘站的è¯ä¹¦æ˜¯ç”± <ph name="ISSUER" /> ç­¾å‘的。</translation>
<translation id="2874156562296220396">Google Chrome 的诞生离ä¸å¼€ <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> å¼€æºé¡¹ç›®ä»¥åŠå…¶ä»–<ph name="BEGIN_LINK_OSS" />å¼€æºè½¯ä»¶<ph name="END_LINK_OSS" />。</translation>
<translation id="3140883423282498090">您所åšçš„更改会在下次é‡æ–°å¯åŠ¨ Google Chrome 时生效。</translation>
<translation id="3444832043240812445">如果<ph name="BEGIN_LINK" />å¯ç”¨å´©æºƒæŠ¥å‘Š<ph name="END_LINK" />,则该网页将åªæ˜¾ç¤ºæ‚¨æœ€è¿‘的崩溃信æ¯ã€‚</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_zh-TW.xtb b/chromium/components/strings/components_google_chrome_strings_zh-TW.xtb
index 434ce4f2b4e..f93d0dd3ce8 100644
--- a/chromium/components/strings/components_google_chrome_strings_zh-TW.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_zh-TW.xtb
@@ -3,6 +3,7 @@
<translationbundle lang="zh-TW">
<translation id="1016765312371154165">Chrome 未正確關閉。</translation>
<translation id="130631256467250065">你的變更會在下次é‡æ–°å•Ÿå‹•è£ç½®æ™‚生效。</translation>
+<translation id="2147651015520127414">Chrome 已驗證這個網站的憑證是由「<ph name="ISSUER" />ã€æ‰€æ ¸ç™¼ã€‚</translation>
<translation id="2874156562296220396">Google Chrome 的開發仰賴 <ph name="BEGIN_LINK_CHROMIUM" />Chromium<ph name="END_LINK_CHROMIUM" /> 開放原始碼計劃與其他<ph name="BEGIN_LINK_OSS" />開放原始碼軟體<ph name="END_LINK_OSS" />çš„å”助æ‰å¾—以完æˆã€‚</translation>
<translation id="3140883423282498090">你的變更將於下次é‡æ–°å•Ÿå‹• Google Chrome 時生效。</translation>
<translation id="3444832043240812445">如果你<ph name="BEGIN_LINK" />啟用當機報告功能<ph name="END_LINK" />,這個é é¢åƒ…會顯示最近的當機資訊。</translation>
diff --git a/chromium/components/strings/components_strings_am.xtb b/chromium/components/strings/components_strings_am.xtb
index dfa80b4fd58..012d0c91d91 100644
--- a/chromium/components/strings/components_strings_am.xtb
+++ b/chromium/components/strings/components_strings_am.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">በሰዓት አቅጣጫ አሽከርክር</translation>
<translation id="1038842779957582377">á‹«áˆá‰³á‹ˆá‰€ ስáˆ</translation>
<translation id="1050038467049342496">ሌሎች መተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• á‹­á‹áŒ‰</translation>
-<translation id="1053591932240354961">ድር ጣቢያዠGoogle Chrome ሊያስተናáŒá‹°á‹ የማይችሠብትንትን ያሉ አሳማአáˆáˆµáŠ­áˆ­áŠ•á‰¶á‰½ ስለላከ አáˆáŠ• <ph name="SITE" />ን መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች ብዙá‹áŠ• ጊዜ ጊዜያዊ ናቸá‹á£ ስለዚህ ይህ ገጽ áˆáŠ“áˆá‰£á‰µ በኋላ ላይ ሊሠራ ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="1055184225775184556">&amp;አክáˆáŠ• ቀáˆá‰¥áˆµ</translation>
<translation id="10614374240317010">በጭራሽ አáˆá‰°á‰€áˆ˜áŒ áˆ</translation>
<translation id="106701514854093668">የዴስክቶᕠዕáˆá‰£á‰¶á‰½</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">የመáˆáˆªá‹« መሸጎጫ እሺ</translation>
<translation id="113188000913989374"><ph name="SITE" /> እንዲህ ይላáˆá¦</translation>
<translation id="1132774398110320017">የChrome ራስ-ሙላ ቅንብሮች...</translation>
+<translation id="1150979032973867961">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠበኮáˆá’á‹á‰°áˆ­á‹Ž ስርዓተ ክወና የሚታመን አይደለáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
+<translation id="1151972924205500581">የይለá ቃሠያስáˆáˆáŒ‹áˆ</translation>
<translation id="1152921474424827756">የ<ph name="URL" /> <ph name="BEGIN_LINK" />የተሸጎጠ ቅጂ<ph name="END_LINK" /> ይድረሱ</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ሳይታሰብ áŒáŠ•áŠ™áŠá‰±áŠ• ዘáŒá‰·áˆá¢</translation>
<translation id="1161325031994447685">ከWi-Fi ጋር ዳáŒáˆ በማገናኘት</translation>
+<translation id="1165039591588034296">ስህተት</translation>
<translation id="1175364870820465910">&amp;አትáˆâ€¦</translation>
<translation id="1181037720776840403">አስወáŒá‹µ</translation>
<translation id="1184214524891303587">የደህንáŠá‰µ ሊሆኑ የሚችሉ የክስተቶች á‹áˆ­á‹áˆ®á‰½áŠ• በራስ-ሰር ለGoogle <ph name="BEGIN_WHITEPAPER_LINK" />ሪá–ርት ያድርጉ<ph name="END_WHITEPAPER_LINK" />ᢠ<ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">ተጨማሪ ከዚህ ጣቢያ</translation>
<translation id="1206967143813997005">መጥᎠየመጀመሪያ áŠáˆ­áˆ›</translation>
<translation id="1209206284964581585">ለአáˆáŠ• ደብቅ</translation>
+<translation id="121201262018556460"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋáˆá£ áŒáŠ• አገáˆáŒ‹á‹© ደካማ á‰áˆá የያዘ የእá‹á‰…ና ማረጋገጫ áŠá‹ ያቀረበá‹á¢ አንድ አጥቂ የáŒáˆ á‰áˆá‰áŠ• ሰብሮ ሊሆን ይችላáˆá£ እና አገáˆáŒ‹á‹© የጠበá‰á‰µ ላይሆን ይችላሠ(ከአጥቂ ጋር እየተገናኙ ሊሆኑ ይችላሉ)á¢</translation>
<translation id="1219129156119358924">የስርዓት ደህንáŠá‰µ</translation>
<translation id="1227224963052638717">á‹«áˆá‰³á‹ˆá‰€ መመሪያá¢</translation>
<translation id="1227633850867390598">እሴት ይደብá‰</translation>
<translation id="1228893227497259893">የተሳሳተ የáˆáŠ•áŠá‰µ ለዪ</translation>
<translation id="1232569758102978740">ርዕስ አáˆá‰£</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />ᣠ<ph name="TYPE_2" /> (ሰáˆáˆ¯áˆ)</translation>
<translation id="1263231323834454256">የንባብ á‹áˆ­á‹áˆ­</translation>
<translation id="1264126396475825575">በ<ph name="CRASH_TIME" /> ላይ የብáˆáˆ½á‰µ ሪá–ርት ተይዟሠ(እስካáˆáŠ• አáˆá‰°áˆ°á‰€áˆˆáˆ ወይሠችላ አáˆá‰°á‰£áˆˆáˆ)</translation>
+<translation id="1281526147609854549">በ<ph name="ISSUER" /> የተሰጠ</translation>
+<translation id="1283919782143846010">አደገኛ ይዘት ታáŒá‹·áˆ</translation>
<translation id="1285320974508926690">ይህን ጣቢያ በጭራሽ አትተርጉáˆ</translation>
<translation id="129553762522093515">በቅርብ ጊዜ የተዘጉ</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />ኩኪዎችዎን ማጽዳት ይሞክሩ<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">የእርስዎ እንቅስቃሴ ለሚከተሉት <ph name="BEGIN_EMPHASIS" />አáˆáŠ•áˆ የሚታይ ሊሆን ይችላáˆ<ph name="END_EMPHASIS" />á¦
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />እርስዎ የሚጎበኟቸዠድር ጣቢያዎች
+ <ph name="LIST_ITEM" />የእርስዎ አሰሪ ወይሠትáˆáˆ…ርት ቤት
+ <ph name="LIST_ITEM" />የእርስዎ በይáŠáˆ˜áˆ¨á‰¥ አገáˆáŒáˆŽá‰µ አቅራቢ
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">የáˆá‹áŒˆá‰£ ጎራá¦</translation>
<translation id="1340482604681802745">የመá‹áˆ°áŒƒ አድራሻ</translation>
<translation id="1344211575059133124">ይህን ጣቢያ ለመጎብኘት áˆá‰ƒá‹µ የሚያስáˆáˆáŒˆá‹Žá‰µ ይመስላáˆ</translation>
<translation id="1344588688991793829">የChromium ራስ-ሙላ ቅንብሮች...</translation>
+<translation id="1348198688976932919">ቀጥሎ እየመጣ ያለዠጣቢያ አደገኛ መተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• በá‹áˆµáŒ¡ á‹­á‹Ÿáˆ</translation>
<translation id="1374468813861204354">የቀረቡ የጥቆማ አስተያየቶች</translation>
<translation id="1375198122581997741">ስለ ስሪት</translation>
<translation id="1377321085342047638">የካርድ á‰áŒ¥áˆ­</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> áˆáŠ•áˆ á‹áˆ‚ብ አáˆáˆ‹áŠ¨áˆá¢</translation>
<translation id="1407135791313364759">áˆáˆ‰áŠ•áˆ ክáˆá‰µ</translation>
<translation id="1413809658975081374">የáŒáˆ‹á‹ŠáŠá‰µ ስህተት</translation>
+<translation id="14171126816530869">የ<ph name="ORGANIZATION" /> በ<ph name="LOCALITY" /> ማንáŠá‰± የተረጋገጠዠበ<ph name="ISSUER" /> áŠá‹á¢</translation>
<translation id="1426410128494586442">አዎ</translation>
<translation id="1430915738399379752">አትáˆ</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" />በ<ph name="DOMAIN" /> ላይ ያለá‹áŠ• ገጽ የመጎብኘት<ph name="END_LINK" /> ሙከራ ታáŒá‹·áˆá¢</translation>
-<translation id="1491663344921578213">የድር ጣቢያዠየእá‹á‰…ና ማረጋገጫ ማያያá‹áŠ• ስለሚጠቀሠአáˆáŠ• <ph name="SITE" />ን መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች ብዙá‹áŠ• ጊዜ ጊዜያዊ ናቸá‹á£ ስለዚህ ይህ ገጽ áˆáŠ“áˆá‰£á‰µ በኋላ ላይ ሊሠራ ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ተጨማሪ}one{<ph name="PAYMENT_METHOD_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ተጨማሪ}other{<ph name="PAYMENT_METHOD_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ተጨማሪ}}</translation>
<translation id="1506687042165942984">የዚህን ገጽ የተቀመጠ (ለáˆáˆ³áˆŒ ቀኑ ያለáˆá‰ á‰µ እንደሆአየታወቀ) ቅጂን አሳይá¢</translation>
<translation id="1517433312004943670">ስáˆáŠ­ á‰áŒ¥áˆ­ ያስáˆáˆáŒ‹áˆ</translation>
<translation id="1519264250979466059">የáŒáŠ•á‰¥ ቀን</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">ይህን ባህሪ ለመጠቀሠጃቫስክሪá•á‰µ መንቃት አለበትá¢</translation>
<translation id="1555130319947370107">ሰማያዊ</translation>
<translation id="1559528461873125649">እንደዚህ ያለ á‹á‹­áˆ ወይሠአቃአየለáˆ</translation>
-<translation id="1559572115229829303">&lt;p&gt;የእርስዎ መሣሪያ ቀን እና ሰዓት (<ph name="DATE_AND_TIME" />) ትክክሠስላáˆáˆ†áŠ‘ ወደ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> የáŒáˆ áŒáŠ•áŠ™áŠá‰µ ሊመሰረት አይችáˆáˆá¢&lt;/p&gt;
-
- &lt;p&gt;እባክዎ በ&lt;strong&gt;ቅንብሮች&lt;/strong&gt; መተáŒá‰ áˆªá‹«á‹ የ&lt;strong&gt;አጠቃላይ&lt;/strong&gt; ክáሠላይ ቀን እና ሰዓቱን ያስተካክሉá¢&lt;/p&gt;</translation>
<translation id="1583429793053364125">ይህን ድረ-ገጽ በማሳየት ላይ ሳለ የሆአችáŒáˆ­ ተáˆáŒ¥áˆ¯áˆá¢</translation>
<translation id="1592005682883173041">አካባቢያዊ የá‹áˆ‚ብ መድረሻ</translation>
+<translation id="1594030484168838125">áˆáˆ¨áŒ¥</translation>
<translation id="161042844686301425">á‹áˆƒ ሰማያዊ</translation>
+<translation id="1620510694547887537">ካሜራ</translation>
<translation id="1629803312968146339">ይህን ካርድ Chrome እንዲያስቀáˆáŒ¥áˆá‹Žá‰µ á‹­áˆáˆáŒ‹áˆ‰?</translation>
<translation id="1639239467298939599">በመጫን ላይ</translation>
<translation id="1640180200866533862">የተጠቃሚ መáˆáˆªá‹«á‹Žá‰½</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">የአá‹á‰³áˆ¨ መረቡ á‹á‰…ር áˆáŠ­ á‹«áˆáˆ†áŠ እና ሊመጣ የማይችሠáŠá‹á¢</translation>
<translation id="1644574205037202324">ታሪክ</translation>
<translation id="1645368109819982629">የማይደገá á•áˆ®á‰¶áŠ®áˆ</translation>
+<translation id="1655462015569774233">{1,plural, =1{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ለማረጋገጥ አይችáˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠትላንትና ጊዜዠአáˆáŽá‰ á‰³áˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢ የኮáˆá’á‹á‰°áˆ­á‹Ž ሰዓት አáˆáŠ• በ<ph name="CURRENT_DATE" /> ተቀናብሯáˆá¢ ትክክሠይመስáˆá‹Žá‰³áˆ? ትክክሠካáˆáˆ†áŠá£ የእርስዎን ስርዓት ሰዓት ማስተካከሠእና ይህንን áŒˆá… áˆ›á‹°áˆµ አለብዎá¢}one{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ለማረጋገጥ አይችáˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠከ# ቀኖች በáŠá‰µ ጊዜዠአáˆááˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢ የኮáˆá’á‹á‰°áˆ­á‹Ž ሰዓት አáˆáŠ• በ<ph name="CURRENT_DATE" /> ተቀናብሯáˆá¢ ትክክሠይመስáˆá‹Žá‰³áˆ? ትክክሠካáˆáˆ†áŠá£ የእርስዎን ስርዓት ሰዓት ማስተካከሠእና ይህንን áŒˆá… áˆ›á‹°áˆµ አለብዎá¢}other{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ለማረጋገጥ አይችáˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠከ# ቀኖች በáŠá‰µ ጊዜዠአáˆááˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢ የኮáˆá’á‹á‰°áˆ­á‹Ž ሰዓት አáˆáŠ• በ<ph name="CURRENT_DATE" /> ተቀናብሯáˆá¢ ትክክሠይመስáˆá‹Žá‰³áˆ? ትክክሠካáˆáˆ†áŠá£ የእርስዎን ስርዓት ሰዓት ማስተካከሠእና ይህንን áŒˆá… áˆ›á‹°áˆµ አለብዎá¢}}</translation>
<translation id="1656489000284462475">መá‹áˆ°áŒƒ</translation>
<translation id="1663943134801823270">ካርዶች እና አድራሻዎች ከChrome የመጡ ናቸá‹á¢ በ<ph name="BEGIN_LINK" />ቅንብሮች<ph name="END_LINK" /> á‹áˆµáŒ¥ ሊያስተዳድሯቸዠይችላሉá¢</translation>
<translation id="1676269943528358898"><ph name="SITE" /> የእርስዎን መረጃ ለመጠበቅ በመደበáŠáŠá‰µ áˆáˆµáŒ áˆ« ይጠቀማáˆá¢ Google Chrome አáˆáŠ• ከ<ph name="SITE" /> ጋር ለመገናኘት ሲሞክር ድር ጣቢያዠያáˆá‰°áˆˆáˆ˜á‹± እና ትክክሠያáˆáˆ†áŠ‘ áˆáˆµáŠ­áˆ­áŠá‰¶á‰½áŠ• መáˆáˆ·áˆá¢ ይህ አንድ አጥቂ <ph name="SITE" />ን አስመስሎ ለመቅረብ ሲሞክር áŠá‹ ወይሠአንድ የWi-Fi መáŒá‰¢á‹« ገጽ áŒáŠ•áŠ™áŠá‰±áŠ• ሲያቋረጥ ሊከሰት ይችላáˆá¢ Google Chrome ማንኛá‹áˆ የá‹áˆ‚ብ áˆá‹á‹áŒ¥ ከመካሄዱ በáŠá‰µ áŒáŠ•áŠ™áŠá‰±áŠ• ስላቋረጠዠየእርስዎ መረጃ ደህንáŠá‰µ አáˆáŠ•áˆ የተጠበቀ áŠá‹á¢</translation>
-<translation id="168328519870909584">በአáˆáŠ‘ ጊዜ በ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች መረጃዎን (ለáˆáˆ³áˆŒá¦ áŽá‰¶á‹Žá‰½á£ የይለá ቃላትᣠመáˆá‹•áŠ­á‰¶á‰½ እና ክሬዲት ካርዶች) የሚሰርበወይሠየሚሰርዙ አደገኛ መተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• ለመጫን ሊሞክሩ ይችላሉá¢</translation>
<translation id="168841957122794586">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫዠደካማ የሆአባለስá‹áˆ­ መረጃ á‰áˆá áŠá‹ ያለá‹á¢</translation>
+<translation id="1706954506755087368">{1,plural, =1{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> እንደሆአማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠከáŠáŒˆ የመጣ áŠá‹ ይላáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢}one{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> እንደሆአማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠየወደáŠá‰µ # ቀንኖች የመጣ áŠá‹ ይላáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢}other{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> እንደሆአማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠየወደáŠá‰µ # ቀንኖች የመጣ áŠá‹ ይላáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢}}</translation>
<translation id="1710259589646384581">ስርዓተ ክወና</translation>
<translation id="1721312023322545264">ይህን ጣቢያ ለመጎብኘት ከ<ph name="NAME" /> áˆá‰ƒá‹µ ያስáˆáˆáŒˆá‹Žá‰³áˆ</translation>
<translation id="1721424275792716183">* መስክ ያስáˆáˆáŒ‹áˆ</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">ገጹን በኋላ አá‹áˆ­á‹µ</translation>
<translation id="17513872634828108">ትሮችን ክáˆá‰µ</translation>
<translation id="1753706481035618306">የገጽ á‰áŒ¥áˆ­</translation>
+<translation id="1763864636252898013">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠበመሣሪያዎ ስርዓተ ክወና የሚታመን አይደለáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />የWindows አá‹á‰³áˆ¨ መረብ መመርመሪያá‹áŠ• ለማሄድ ይሞክሩ<ph name="END_LINK" />á¢</translation>
<translation id="1783075131180517613">እባክዎ የማመሳሰሠይለá áˆáˆ¨áŒá‹ŽáŠ• ያዘáˆáŠ‘á¢</translation>
<translation id="1787142507584202372">የእርስዎ ክáት ትሮች እዚህ ይመጣሉ</translation>
+<translation id="1789575671122666129">ብቅ-ባዮች</translation>
<translation id="1791429645902722292">Google ዘመናዊ á‰áˆá</translation>
<translation id="1803264062614276815">የካርድ ያዢዠስáˆ</translation>
-<translation id="1803678881841855883">Google የጥንቃቄ አሰሳ በቅርቡ በ<ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ተንኮáˆ-አዘሠዌር<ph name="END_LINK" /> እንዳለ ደርሶበታáˆá¢ በመደበኛ ጊዜ ደህንáŠá‰³á‰¸á‹ የተጠበበድር ጣቢያዎች አንዳንድ ጊዜ በተንኮáˆ-አዘሠዌር ሊጠበይችላሉᢠበተንኮáˆ-አዘሠዌር አሰራጭáŠá‰µ ከሚታወቀዠ<ph name="SUBRESOURCE_HOST" /> የመጣ áŠá‹á¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="1806541873155184440"><ph name="ADDED_TO_AUTOFILL_MONTH" /> ላይ ታክáˆáˆ</translation>
<translation id="1821930232296380041">áˆáŠ­ á‹«áˆáˆ†áŠ ጥያቄ ወይሠየጥያቄ áˆáŠ¬á‰¶á‰½</translation>
<translation id="1826516787628120939">በመáˆá‰°áˆ¸ ላይ</translation>
<translation id="1834321415901700177">ይህ ጣቢያ ጎጂ á•áˆ®áŒáˆ«áˆžá‰½áŠ• á‹­á‹Ÿáˆ</translation>
+<translation id="1840414022444569775">ይህ የካርድ á‰áŒ¥áˆ­ አስቀድሞ ስራ ላይ á‹áˆáˆ</translation>
<translation id="1842969606798536927">ይክáˆáˆ‰</translation>
<translation id="1871208020102129563">የ.pac ስክሪá•á‰µ ዩአርኤሠሳይሆን ተኪ አገáˆáŒ‹á‹®á‰½áŠ• እንዲጠቀሠáŠá‹ ተኪ የተዋቀረá‹á¢</translation>
<translation id="1871284979644508959">የሚያስáˆáˆáŒ መስክ</translation>
<translation id="187918866476621466">የመáŠáˆ» ገጾችን ክáˆá‰µ</translation>
<translation id="1883255238294161206">á‹áˆ­á‹áˆ­ ሰብስብ</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ተጨማሪ}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ተጨማሪ}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ተጨማሪ}}</translation>
<translation id="1898423065542865115">በማጣራት ላይ</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1 ጣቢያ}one{# ጣቢያዎች}other{# ጣቢያዎች}}</translation>
<translation id="194030505837763158">ወደ <ph name="LINK" /> ሂድ</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> እáˆá‰£á‰¶á‰½</translation>
<translation id="1973335181906896915">የመለያ á‰áŒ¥áˆ­ መስጠት ላይ ስህተት</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">በ<ph name="POLICY_NAME" /> ስለተሻረ ችላ ተብáˆáˆá¢</translation>
<translation id="2138201775715568214">በአቅራቢያ ያሉ አካላዊ ድረ-ገጾችን በመáˆáˆˆáŒ ላይ</translation>
<translation id="213826338245044447">የተንቀሳቃሽ ስáˆáŠ­ á‹•áˆá‰£á‰¶á‰½</translation>
-<translation id="2148716181193084225">ዛሬ</translation>
+<translation id="2147827593068025794">የጀርባ ስáˆáˆ¨á‰µ</translation>
<translation id="2154054054215849342">ስáˆáˆ¨á‰µ ለእርስዎ ጎራ አይገáŠáˆ</translation>
<translation id="2154484045852737596">ካርትን ያርትዑ</translation>
<translation id="2166049586286450108">ሙሉ የአስተዳደር መድረሻ</translation>
<translation id="2166378884831602661">ይህ ጣቢያ ደህንáŠá‰± አስተማማአየሆአáŒáŠ•áŠ™áŠá‰µ ማቅረብ አይችáˆáˆ</translation>
<translation id="2181821976797666341">መáˆáˆªá‹«á‹Žá‰½</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 አድራሻ}one{# አድራሻዎች}other{# አድራሻዎች}}</translation>
+<translation id="2187317261103489799">አáŒáŠ (áŠá‰£áˆª)</translation>
<translation id="2202020181578195191">ትክክለኛ የአገáˆáŒáˆŽá‰µ ማብቂያ ዓመት ያስገቡ</translation>
<translation id="2212735316055980242">መመሪያ አáˆá‰°áŒˆáŠ˜áˆ</translation>
<translation id="2213606439339815911">áŒá‰¤á‰¶á‰½áŠ• በማáˆáŒ£á‰µ ላይ...</translation>
+<translation id="2218879909401188352">በ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ አáˆáŠ• ያሉ አጥቂዎች የእርስዎን መሣሪያ የሚያበላሹ አደገኛ መተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• ሊጭኑᣠበእርስዎ ሞባይሠክáá‹« መጠየቂያ ላይ የተደበበክáá‹« መጠየቂያዎችን ሊያክሉ ወይሠየእርስዎን የáŒáˆ መረጃ ሊሰርበይችላሉᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />የመመርመሪያ መተáŒá‰ áˆªá‹«á‹áŠ•<ph name="END_LINK" /> በመጠቀሠáŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• ያስተካክሉት</translation>
<translation id="2239100178324503013">አáˆáŠ• ላክ</translation>
<translation id="225207911366869382">ይህ ዋጋ ለዚህ መመሪያ ተቋርጧáˆá¢</translation>
<translation id="2262243747453050782">የኤች ቲ ቲ ᒠስህተት</translation>
+<translation id="2270484714375784793">ስáˆáŠ­ á‰áŒ¥áˆ­</translation>
<translation id="2282872951544483773">የማይገኙ ሙከራዎች</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> ንጥáˆ}one{<ph name="ITEM_COUNT" /> ንጥሎች}other{<ph name="ITEM_COUNT" /> ንጥሎች}}</translation>
<translation id="2292556288342944218">የእርስዎ የበየáŠáˆ˜áˆ¨á‰¥ መዳረሻ ታáŒá‹·áˆ</translation>
<translation id="230155334948463882">አዲስ ካርድ?</translation>
-<translation id="2305919008529760154">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ á‹•á‹á‰…ና ማረገጫዠበተጭበረበረ መáˆáŠ© የወጣ ሊሆን ይችላáˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በጠለሠአጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> የተጠቃሚ ስሠእና የይለá ቃሠያስáˆáˆáŒˆá‹‹áˆá¢</translation>
-<translation id="2318774815570432836">የድር ጣቢያዠHSTS ስለሚጠቀሠአáˆáŠ• <ph name="SITE" /> መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች አብዛኛዠጊዜ ጊዜያዊ ናቸá‹á£ ስለዚህ ይህ ገጽ በኋላ ላይ ሊሠራ ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
+<translation id="2337852623177822836">ቅንብር በአስተዳዳሪዎ áŠá‹ á‰áŒ¥áŒ¥áˆ­ የሚደረáŒá‰ á‰µ</translation>
<translation id="2354001756790975382">ሌላ እáˆá‰£á‰¶á‰½</translation>
+<translation id="2354430244986887761">Google የጥንቃቄ አሰሳ በቅርብ ጊዜ በ<ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ጎጂ መተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• አáŒáŠá‰·áˆ<ph name="END_LINK" />á¢</translation>
<translation id="2355395290879513365">አጥቂዎች በዚህ ጣቢያ ላይ እርስዎ እየተመለከቱዋቸዠያሉ áˆáˆµáˆŽá‰½áŠ• ማየት እና በላያቸዠላይ ለá‹áŒ¦á‰½áŠ• በማድረጠሊያታáˆáˆá‹Žá‰µ ይችሉ ይሆናáˆá¢</translation>
+<translation id="2356070529366658676">ጠይቅ</translation>
+<translation id="2359629602545592467">በርካታ</translation>
<translation id="2359808026110333948">ቀጥáˆ</translation>
<translation id="2365563543831475020">በ<ph name="CRASH_TIME" /> ላይ የተያዘዠየብáˆáˆ½á‰µ ሪá–ርት አáˆá‰°áˆ°á‰€áˆˆáˆ</translation>
<translation id="2367567093518048410">ደረጃ</translation>
-<translation id="2371153335857947666">{1,plural, =1{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ áˆáˆµáŠ­áˆ­ ወረቀቱ ትላንትና ጊዜዠአáˆáŽá‰ á‰³áˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ የኮáˆá’á‹á‰°áˆ­á‹Ž ሰዓት አáˆáŠ• ወደ <ph name="CURRENT_DATE" /> ተቀናብሯáˆá¢ ትክክሠይመስáˆá‹Žá‰³áˆ? ትክክሠካáˆáˆ†áŠ የስርዓትዎዎን ሰዓት ማስተካከሠእና ይህንን ገጽ ማደስ አለብዎትᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢}one{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠከ# ቀኖች በáŠá‰µ ጊዜዠአáˆááˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ የኮáˆá’á‹á‰°áˆ­á‹Ž ሰዓት አáˆáŠ• ወደ <ph name="CURRENT_DATE" /> ተቀናብሯáˆá¢ ትክክሠይመስáˆá‹Žá‰³áˆ? ትክክሠካáˆáˆ†áŠ የስርዓትዎን ሰዓት ማስተካከሠእና ይህንን ገጽ ማደስ አለብዎትᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢}other{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠከ# ቀኖች በáŠá‰µ ጊዜዠአáˆááˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ የኮáˆá’á‹á‰°áˆ­á‹Ž ሰዓት አáˆáŠ• ወደ <ph name="CURRENT_DATE" /> ተቀናብሯáˆá¢ ትክክሠይመስáˆá‹Žá‰³áˆ? ትክክሠካáˆáˆ†áŠ የስርዓትዎን ሰዓት ማስተካከሠእና ይህንን ገጽ ማደስ አለብዎትᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢}}</translation>
<translation id="237718015863234333">áˆáŠ•áˆ የበይáŠáŒˆáŒ½ አማራጮች አይገኙáˆ</translation>
<translation id="2384307209577226199">የንáŒá‹µ ድርጅት áŠá‰£áˆª</translation>
<translation id="2386255080630008482">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫ ተሽሯáˆá¢</translation>
<translation id="2392959068659972793">áˆáŠ•áˆ እሴት á‹«áˆá‰°á‹‹á‰€áˆ¨áˆ‹á‰¸á‹ መáˆáˆªá‹«á‹Žá‰½áŠ• አሳይ</translation>
<translation id="239429038616798445">ይህ የመላኪያ ዘዴ አይገáŠáˆá¢ የተለየ ዘዴ ይሞክሩá¢</translation>
<translation id="2396249848217231973">&amp;ስረዛን ቀáˆá‰¥áˆµ</translation>
-<translation id="2460160116472764928">Google የጥንቃቄ አሰሳ በቅርብ ጊዜ በ<ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ተንኮáˆ-አዘሠዌር<ph name="END_LINK" /> ላይ አáŒáŠá‰·áˆá¢ በመደበኛ ጊዜ ደህንáŠá‰³á‰¸á‹ የተጠበበድር ጣቢያዎች አንዳንድ ጊዜ በተንኮáˆ-አዘሠዌር ሊጠበይችላሉᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠተሽሮ ሊሆን ይችላáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
<translation id="2463739503403862330">ሙላ</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />የአá‹á‰³áˆ¨ መረብ መመርመሪያን በማሄድ ላይ<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">áˆáŠ­ á‹«áˆáˆ†áŠ የáለጋ ዩአርኤáˆá¢</translation>
+<translation id="2482878487686419369">ማስታወቂያዎች</translation>
<translation id="2491120439723279231">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫ ስህተቶችን á‹­á‹Ÿáˆá¢</translation>
<translation id="2495083838625180221">JSON ተንታáŠ</translation>
<translation id="2495093607237746763">áˆáˆáŠ­á‰µ ከተደረገበት Chromium ለተሻለ የቅጽ አሞላሠáጥáŠá‰µ የካርድዎን ቅጂ በዚህ መሣሪያ ላይ ያከማቻáˆá¢</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">ወደ ኋላ ተመለስ</translation>
<translation id="2515629240566999685">በእርስዎ አካባቢ ያለá‹áŠ• ሲáŒáŠ“ሠመáˆá‰°áˆ½</translation>
<translation id="2516305470678292029">የበይáŠáŒˆáŒ½ አማራጮች</translation>
+<translation id="2539524384386349900">አáŒáŠ</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> áˆáŠ­ á‹«áˆáŠ¾áŠ áˆáˆ‹áˆ½ áˆáŠ³áˆá¢</translation>
-<translation id="2552545117464357659">በጣሠአዲስ</translation>
<translation id="2556876185419854533">&amp;አርትዕን ቀáˆá‰¥áˆµ</translation>
<translation id="2587730715158995865">ከ<ph name="ARTICLE_PUBLISHER" />ᢠይህን እና <ph name="OTHER_ARTICLE_COUNT" /> ሌሎች ዘገባዎችን ያንብቡá¢</translation>
<translation id="2587841377698384444">የማá‹áŒ« የኤá’አይ መታወቂያá¦</translation>
<translation id="2597378329261239068">ይህ ሰáŠá‹µ በይለá ቃሠየተጠበቀ áŠá‹á¢ እባክዎ የይለá ቃሠያስገቡá¢</translation>
<translation id="2609632851001447353">áˆá‹©áŠá‰¶á‰½</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1 መተáŒá‰ áˆªá‹« ($1)}=2{2 መተáŒá‰ áˆªá‹«á‹Žá‰½ ($1ᣠ$2)}one{# መተáŒá‰ áˆªá‹«á‹Žá‰½ ($1ᣠ$2ᣠ$3)}other{# መተáŒá‰ áˆªá‹«á‹Žá‰½ ($1ᣠ$2ᣠ$3)}}</translation>
<translation id="2625385379895617796">የእርስዎ ሰዓት ገና የወደáŠá‰µ áŠá‹</translation>
<translation id="2639739919103226564">áˆáŠ”ታá¦</translation>
+<translation id="2649204054376361687"><ph name="CITY" />ᣠ<ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">የá‹á‹­áˆ‰ መዳረሻ ተከáˆáŠ­áˆáˆ</translation>
<translation id="2653659639078652383">አስገባ</translation>
<translation id="2666117266261740852">ሌሎች ትሮችን ወይሠመተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• á‹­á‹áŒ‰</translation>
+<translation id="2670429602441959756">ይህ ገጽ እስካáˆáŠ• በVR á‹áˆµáŒ¥ የማይደገበባህሪያትን á‹­á‹Ÿáˆá¢ በመá‹áŒ£á‰µ ላይ...</translation>
<translation id="2674170444375937751">እርáŒáŒ áŠ› áŠá‹Žá‰µ እáŠá‹šáˆ…ን ገጾች ከታሪክዎ መሰረዠይáˆáˆáŒ‹áˆ‰?</translation>
<translation id="2677748264148917807">ለቅቀህ á‹áŒ£</translation>
-<translation id="269990154133806163">አገáˆáŒ‹á‹© የእá‹á‰…ና ማረጋገጫ áŒáˆáŒ½áŠá‰µ መመሪያá‹áŠ• በመጠቀሠበይዠያáˆá‰°áŒˆáˆˆáŒ¸ የእá‹á‰…ና ማረጋገጫን አቅርቧáˆá¢ ይህ ለአንዳንድ የእá‹á‰…ና ማረጋገጫዎች ሊታመኑ የሚችሉ መሆናቸá‹áŠ• ለማረጋገጥ እና ከአጥቂዎች ጥበቃ ለማድረጠእንዲቻሠአስáˆáˆ‹áŒŠ áŠá‹á¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">የንባብ á‹áˆ­á‹áˆ­</translation>
<translation id="2704283930420550640">ዋጋ ከቅርጸት ጋር አይዛመድáˆá¢</translation>
<translation id="2704951214193499422">Chromium በዚህ ጊዜ የእርስዎን ካርድ ማረጋገጥ አáˆá‰»áˆˆáˆá¢ እባክዎ ቆይተዠእንደገና ይሞክሩá¢</translation>
<translation id="2705137772291741111">የተቀመጠዠ(የተሸጎጠ) የዚህ ጣቢያ ቅጂ የሚáŠá‰ á‰¥ አáˆáŠá‰ áˆ¨áˆá¢</translation>
<translation id="2709516037105925701">ራስ-ሙላ</translation>
-<translation id="2712118517637785082"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋáˆá£ áŠáŒˆáˆ­ áŒáŠ• አገáˆáŒ‹á‹© ያቀረበዠየእá‹á‰…ና ማረጋገጫ በሰጪዠተሽሯáˆá¢ ይህ ማለት አገáˆáŒ‹á‹© ያቀረበዠየደህንáŠá‰µ áˆáˆµáŠ­áˆ­áŠá‰¶á‰½ áˆáŒ½áˆž ሊታመኑ አይገባáˆá¢ ከአጥቂ ጋር እየተገናኙ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">áቃድ ጠይቅ</translation>
<translation id="2713444072780614174">áŠáŒ­</translation>
<translation id="2720342946869265578">በአቅራቢያ</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">የሚጎድሠየመሣሪያ መá‹áŒˆá‰¥</translation>
<translation id="2784949926578158345">áŒáŠ•áŠ™áŠá‰± ዳáŒáˆ እንዲጀáˆáˆ­ ተደርጓáˆá¢</translation>
<translation id="2794233252405721443">ጣቢያ ታáŒá‹·áˆ</translation>
+<translation id="2799020568854403057">ቀጥሎ ያለዠጣቢያ ጎጂ መተáŒá‰ áˆªá‹«á‹Žá‰½ አሉት</translation>
+<translation id="2803306138276472711">Google የጥንቃቄ አሰሳ በቅርብ ጊዜ <ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ተንኮáˆ-አዘሠዌር<ph name="END_LINK" /> አáŒáŠá‰·áˆá¢ በመደበኛ ጊዜ ደህንáŠá‰³á‰¸á‹ የተጠበበድር ጣቢያዎች አንዳንድ ጊዜ በተንኮáˆ-አዘሠዌር ይጠቃሉá¢</translation>
<translation id="2824775600643448204">የአድራሻ እና áለጋ አሞሌ</translation>
<translation id="2826760142808435982">áŒáŠ•áŠ™áŠá‰± የተመሰጠረ እና <ph name="CIPHER" />ን በመጠቀሠየተረጋገጠ áŠá‹á£ እና <ph name="KX" />ን እንደ የá‰áˆá መቀያየሪያ ስáˆá‰µ ይጠቀáˆá‰ á‰³áˆá¢</translation>
<translation id="2835170189407361413">ቅጽ አጽዳ</translation>
+<translation id="2856444702002559011">አጥቂዎች የእርስዎን መረጃ (ለáˆáˆ³áˆŒá¦ የይለá ቃላትንᣠመáˆá‹•áŠ­á‰¶á‰½áŠ•á£ ወይሠየክሬዲት ካርዶችን የመሳሰሉ) ከ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ለመስረቅ እየሞከሩ ሊሆኑ ይችላሉᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">ዳáŒáˆ አትጫን</translation>
<translation id="2900469785430194048">Google Chrome ይህን ድረ-ገጽ ለማሳየት በሚሞክርበት ጊዜ ማኅደረ ትá‹áˆµá‰³ አáˆá‰†á‰ á‰³áˆá¢</translation>
<translation id="2909946352844186028">የአá‹á‰³áˆ¨ መረብ ለá‹áŒ¥ ተገáŠá‰·áˆá¢</translation>
<translation id="2916038427272391327">ሌሎች á•áˆ®áŒáˆ«áˆžá‰½áŠ• á‹­á‹áŒ‰</translation>
<translation id="2922350208395188000">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫ ሊረጋገጥ አáˆá‰»áˆˆáˆá¢</translation>
<translation id="2928905813689894207">ክáá‹« የሚጠየቅበት አድራሻ</translation>
+<translation id="2941952326391522266">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠበ<ph name="DOMAIN2" /> áŠá‹ የተሰጠá‹á¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
<translation id="2948083400971632585">ከቅንብሮች ገጽ ሆáŠá‹ ማናቸá‹áŠ•áˆ ለáŒáŠ•áŠ™áŠá‰µ የተዋቀሩ ተኪዎችን ማሰናከሠይችላሉá¢</translation>
<translation id="2955913368246107853">አáŒáŠ አሞሌን á‹áŒ‹</translation>
<translation id="2958431318199492670">የአá‹á‰³áˆ¨ መረብ á‹á‰…ሩ በኦ ኤን ሲ መስáˆáˆ­á‰± አይገዛáˆá¢ አንዳንድ የá‹á‰…ሩ ክáሎች ላይመጡ ይችላሉá¢</translation>
-<translation id="29611076221683977">በአáˆáŠ‘ ጊዜ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች በእርስዎ ማክ ላይ መረጃዎን የሚሰርበወይሠየሚሰርዙ (ለáˆáˆ³áˆŒá¦ áŽá‰¶á‹Žá‰½á£ የይለá ቃላትᣠመáˆá‹•áŠ­á‰¶á‰½ እና ክሬዲት ካርዶች) አደገኛ á•áˆ®áŒáˆ«áˆžá‰½áŠ• ለመጫን ሊሞክሩ ይችላሉá¢</translation>
<translation id="2966678944701946121">አገáˆáŒáˆŽá‰± የሚያበቃá‹á¦ <ph name="EXPIRATION_DATE_ABBR" />ᣠየታከለዠበ<ph name="ADDED_TO_AUTOFILL_MONTH" /> ላይ</translation>
<translation id="2969319727213777354">ደህንáŠá‰± የተጠበቀ áŒáŠ•áŠ™áŠá‰µ ለመመስረት የእርስዎ ሰዓት በትክክሠመዋቀር አለበትᢠይሄ የሆáŠá‰ á‰µ áˆáŠ­áŠ•á‹«á‰µ ድር ጣቢያዎች ራሳቸá‹áŠ• ለማሳወቅ የሚጠቀሙባቸዠየእá‹á‰…ና ማረጋገጫዎች የሚሰሩት ለተወሰኑ ጊዜዎች ብቻ ስለሆአáŠá‹á¢ የእርስዎ መሣሪያ ሰዓት ትክክሠእንዳለመሆኑ መጠን Google Chrome እáŠá‹šáˆ…ን የእá‹á‰…ና ማረጋገጫዎች ሊያረጋáŒáŒ¥ አይችáˆáˆá¢</translation>
<translation id="2972581237482394796">&amp;ድገáˆ</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">የሚሰራ አድራሻ ያስገቡ</translation>
<translation id="2986368408720340940">ይህ የመá‹áˆ°áŒƒ ዘዴ አይደገááˆá¢ የተለየ ዘዴ á‹­áˆáˆ¨áŒ¡á¢</translation>
<translation id="2991174974383378012">ከድረ ገጾች ጋር ማጋራት</translation>
+<translation id="2991571918955627853">የድር ጣቢያዠHSTS ስለሚጠቀሠአáˆáŠ• <ph name="SITE" />ን መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች አብዛኛዠጊዜ ጊዜያዊ ናቸá‹á£ ስለዚህ ይህ ገጽ በኋላ ላይ ሳይሠራ አይቀርáˆá¢</translation>
<translation id="3005723025932146533">የተቀመጠ ቅጂ አሳይ</translation>
<translation id="3008447029300691911">የ<ph name="CREDIT_CARD" /> ሲቪሲ ያስገቡᢠአንዴ ካረጋገጡ በኋላ የካርድ á‹áˆ­á‹áˆ®á‰½á‹Ž ለዚህ ጣቢያ ይጋራሉá¢</translation>
<translation id="3010559122411665027">የá‹áˆ­á‹áˆ­ áŒá‰¤á‰µ «<ph name="ENTRY_INDEX" />»ᦠ<ph name="ERROR" /></translation>
+<translation id="301521992641321250">በራስ-ሰር ታáŒá‹·áˆ</translation>
<translation id="3024663005179499861">የተሳሳተ የመáˆáˆªá‹« አይáŠá‰µ</translation>
<translation id="3032412215588512954">ይህን ጣቢያ ዳáŒáˆ መጫን á‹­áˆáˆáŒ‹áˆ‰?</translation>
<translation id="3037605927509011580">á‹á‹­á£ ተሰናከለ!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{በተሰመሩ መሣሪያዎች ላይ ቢያንስ 1 ንጥáˆ}=1{1 ንጥሠ(እና ተጨማሪ የተሰመሩ መሣሪያዎች ላይ)}one{# ንጥሎች (እና ተጨማሪ የተሰመሩ መሣሪያዎች ላይ)}other{# ንጥሎች (እና ተጨማሪ የተሰመሩ መሣሪያዎች ላይ)}}</translation>
<translation id="3041612393474885105">የሰርቲáŠáŠ¬á‰µ መረጃ</translation>
<translation id="3063697135517575841">Chrome በዚህ ጊዜ የእርስዎን ካርድ ማረጋገጥ አáˆá‰»áˆˆáˆá¢ እባክዎ ቆይተዠእንደገና ይሞክሩá¢</translation>
<translation id="3064966200440839136">በá‹áŒ«á‹Š ማከማቻ በኩሠለማጫወት ማንáŠá‰µ ከማያሳá‹á‰… áˆáŠá‰³ በመá‹áŒ£á‰µ ላይᢠይቀጥáˆ?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1 የይለá ቃáˆ}one{# የይለá ቃሎች}other{# የይለá ቃሎች}}</translation>
<translation id="3093245981617870298">ከመስመር á‹áŒª áŠá‹Žá‰µá¢</translation>
<translation id="3105172416063519923">የእሴት መታወቂያá¦</translation>
<translation id="3109728660330352905">ይህን ገጽ ለማየት áቃድ የለዎትáˆá¢</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />የáŒáŠ•áŠ™áŠá‰µ መመርመሪያን አሂደዠይሞክሩ<ph name="END_LINK" /></translation>
<translation id="3145945101586104090">áˆáˆ‹áˆ¹áŠ• መáŒáˆˆáŒ¥ አáˆá‰°áˆ³áŠ«áˆ</translation>
<translation id="3150653042067488994">ጊዜያዊ የአገáˆáŒ‹á‹­ ስህተት</translation>
@@ -247,15 +277,19 @@
<translation id="3167968892399408617">ማንáŠá‰µáŠ• በማያሳá‹á‰… ትሮች á‹áˆµáŒ¥ የሚያዩዋቸዠገጾች áˆáˆ‰áŠ•áˆ ማንáŠá‰µ የማያሳá‹á‰ ትሮችዎን ከዘጉ በኋላ በአሳሽዎ ታሪክᣠየኩኪ ማከማቻᣠወይሠየáለጋ ታሪክ á‹áˆµáŒ¥ አይቀመጡáˆá¢ ማንáŠá‰µ በማያስá‹á‰… áˆáŠá‰³ መሥራት የሌሎች ሰዎችᣠአገáˆáŒ‹á‹®á‰½á£ ሶáትዌሮች ወይሠከጀርባዎ የቆሙ የሌሎች ሰዎች ባህሪይ ላይ ለá‹áŒ¥ አያመጣáˆá¢</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ደሴት</translation>
+<translation id="317583078218509884">ገጹ ዳáŒáˆ ከተጫአበኋላ አዲስ የጣቢያ áቃዶች ቅንብሮቹ ይተገበራሉá¢</translation>
<translation id="3176929007561373547">ተኪ አገáˆáŒ‹á‹© በአáŒá‰£á‰¡ እየሰራ መሆኑን ለማረጋገጥ የተኪ ቅንብሮችዎን á‹­áˆá‰µáˆ¹ ወይሠየአá‹á‰³áˆ¨
መረብዎ አስተዳዳሪን á‹«áŒáŠ™á¢ ተኪ አገáˆáŒ‹á‹­ መጠቀሠእንደሌለብዎት የሚያáˆáŠ‘ ከሆኑá¦
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">ገጽ ማንáŠá‰µ በማያሳá‹á‰… áˆáŠá‰³ á‹áˆµáŒ¥ ይክáˆá‰±</translation>
-<translation id="3202578601642193415">እጅጠበጣሠአዲስ</translation>
+<translation id="320323717674993345">ክáያን ሰርá‹</translation>
<translation id="3207960819495026254">á‹•áˆá‰£á‰µ ተደርጎበታáˆ</translation>
+<translation id="3225919329040284222">አገáˆáŒ‹á‹© አብረዠየተሰሩ የሚጠበበማሟያዎችን የማያሟላ የእá‹á‰…ና ማረጋገጫ áŠá‹ ያቀረበá‹á¢ እáŠá‹šáˆ… የሚጠበበማሟያዎች እርስዎን ለመጠበቅ ለተረጋገጡ ከáተኛ ደህንáŠá‰µ ላላቸዠድር ጣቢያዎች ተካትተዋáˆá¢</translation>
<translation id="3226128629678568754">ገጹን ለመጫን የሚያስáˆáˆáŒˆá‹ á‹áˆ‚ብ ዳáŒáˆ ለማስገባት የዳáŒáˆ ጫን አá‹áˆ«áˆ©áŠ• ይጫኑá¢</translation>
+<translation id="3227137524299004712">ማይክሮáŽáŠ•</translation>
<translation id="3228969707346345236">ገጹ አስቀድሞ በ<ph name="LANGUAGE" /> ስለሆአትርጉሙ አáˆá‰°áˆ³áŠ«áˆá¢</translation>
<translation id="323107829343500871">የ<ph name="CREDIT_CARD" /> ሲቪሲ ያስገቡ</translation>
+<translation id="3234666976984236645">áˆáˆáŒŠá‹œ በዚህ ጣቢያ ላይ ያለ አስáˆáˆ‹áŒŠ ይዘትን አáŒáŠ</translation>
<translation id="3254409185687681395">ለእዚህ ገጽ á‹•áˆá‰£á‰µ አብጅ</translation>
<translation id="3270847123878663523">&amp;ዳáŒáˆ ደርድርን ቀáˆá‰¥áˆµ</translation>
<translation id="3282497668470633863">በካርድ ላይ ስሠያክሉ</translation>
@@ -269,42 +303,48 @@
<translation id="3340978935015468852">ቅንብሮች</translation>
<translation id="3345135638360864351">ይህን ጣቢያ ለመድረስ ያቀረቡት ጥያቄ ወደ <ph name="NAME" /> ሊላክ አáˆá‰°á‰»áˆˆáˆá¢ እባክዎ እንደገና ይሞክሩá¢</translation>
<translation id="3355823806454867987">የተኪ ቅንብሮችን በመቀየር ላይ...</translation>
+<translation id="3361596688432910856">Chrome የሚከተሉትን መረጃዎች <ph name="BEGIN_EMPHASIS" />አያስቀáˆáŒ¥áˆ<ph name="END_EMPHASIS" />á¦
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />የእርስዎ የአሰሳ ታሪክ
+ <ph name="LIST_ITEM" />ኩኪዎች እና የጣቢያ á‹áˆ‚ብ
+ <ph name="LIST_ITEM" />በቅጾች á‹áˆµáŒ¥ የገባ መረጃ
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">የሰዓት ስህተት</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> ተጨማሪ ንጥሎች...</translation>
<translation id="337363190475750230">አቅርቦት ተቋርጧáˆ</translation>
<translation id="3377188786107721145">የመáˆáˆªá‹« ትንተና ስህተት</translation>
<translation id="3380365263193509176">á‹«áˆá‰³á‹ˆá‰€ ስህተት</translation>
<translation id="3380864720620200369">የደንበኛ መታወቂያá¦</translation>
<translation id="3391030046425686457">የመላኪያ አድራሻ</translation>
<translation id="3395827396354264108">የመá‹áˆ°áŒƒ ዘዴ</translation>
-<translation id="340013220407300675">ጥቃት የሚያደርሱ አካላት መረጃዎን ከ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ለመስረቅ እየሞከሩ ሊሆን ይችላሠ(ለáˆáˆ³áˆŒá£ የይለá ቃሎችንᣠመáˆá‹•áŠ­á‰¶á‰½áŠ• ወይሠክሬዲት ካርዶችን)á¢</translation>
<translation id="3422248202833853650">የማህደረ ትá‹áˆµá‰³ ቦታን ለማስለቀቅ ከሌሎች á•áˆ®áŒáˆ«áˆžá‰½ ዘáŒá‰°á‹ ለመá‹áŒ£á‰µ á‹­á‹áŒ¡á¢</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> አáˆáŠ• ላይ ሊደረስበት አይችáˆáˆá¢</translation>
+<translation id="3427092606871434483">áቀድ (áŠá‰£áˆª)</translation>
<translation id="3427342743765426898">&amp;አርትዕን ድገáˆ</translation>
<translation id="3431636764301398940">ይህን ካርድ ወደዚህ መሣሪያ አስቀáˆáŒ¥</translation>
<translation id="3435896845095436175">አንቃ</translation>
<translation id="3447661539832366887">የዚህ መሣሪያ ባለቤት የዳይኖሰር ጨዋታá‹áŠ• አጥáቶታáˆá¢</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">የሚመጣዠበየá¦</translation>
<translation id="3462200631372590220">የላበደብቅ</translation>
<translation id="3467763166455606212">የካርድ á‹«á‹¥ ስሠያስáˆáˆáŒ‹áˆ</translation>
<translation id="3478058380795961209">ጊዜዠየሚያáˆáበት ወር</translation>
<translation id="3479539252931486093">ይህ á‹«áˆá‰°áŒ á‰ á‰€ áŠá‰ áˆ­? <ph name="BEGIN_LINK" />ያሳá‹á‰áŠ•<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">አáˆáŠ• አይደለáˆ</translation>
-<translation id="348000606199325318">የብáˆáˆ½á‰µ መታወቂያ <ph name="CRASH_LOCAL_ID" /> (የአገáˆáŒ‹á‹­ መታወቂያᦠ<ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">በዚህ ጊዜ ላይ ወላጅህን ማáŒáŠ˜á‰µ አáˆá‰»áˆáŠ•áˆá¢ እባክህ እንደገና ሞክርá¢</translation>
<translation id="3528171143076753409">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫ የታመአአይደለáˆá¢</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{በተሰመሩ መሣሪያዎች ላይ ቢያንስ 1 ንጥáˆ}=1{1 ንጥሠ(እና ተጨማሪ የተሰመሩ መሣሪያዎች ላይ)}one{# ንጥሎች (እና ተጨማሪ የተሰመሩ መሣሪያዎች ላይ)}other{# ንጥሎች (እና ተጨማሪ የተሰመሩ መሣሪያዎች ላይ)}}</translation>
<translation id="3539171420378717834">የዚህን ካርድ ቅጂ በዚህ መሣሪያ ላይ አቆይ</translation>
<translation id="3542684924769048008">የይለá ቃሠይጠቀሙ ለá¦</translation>
+<translation id="3545341443414427877">የእርስዎ ኮáˆá’á‹á‰°áˆ­ እና ሰዓት (<ph name="DATE_AND_TIME" />) ትክክሠስላáˆáˆ†áŠ‘ ከ<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ጋር የáŒáˆ áŒáŠ•áŠ™áŠá‰µ መመሥረት አይቻáˆáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">áˆáˆ‰áˆ የተመሳሰለ á‹áˆ‚ብ ከእራስዎ የተመሳሰለ ይለá áˆáˆ¨áŒ ጋር ያመስጥሩ</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> ተጨማሪ...</translation>
-<translation id="3555561725129903880">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የዕá‹á‰…ና ማረጋገጫዠከ<ph name="DOMAIN2" /> የመጣ áŠá‹á¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">የእርስዎ አስተዳዳሪ እገዳá‹áŠ• ሊያáŠáˆ±áˆá‹Ž ይችላሉ</translation>
<translation id="3566021033012934673">áŒáŠ•áŠ™áŠá‰µá‹Ž የáŒáˆ አይደለáˆ</translation>
+<translation id="3569145463236695319">&lt;p&gt;የመሣሪያዎ ቀን እና ሰዓት <ph name="DATE_AND_TIME" /> áˆáŠ­ ስላáˆáˆ†áŠ ከ<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ጋር የáŒáˆ áŒáŠ•áŠ™áŠá‰µ መመሥረት አይቻáˆáˆá¢&lt;/p&gt;
+
+ &lt;p&gt;እባክዎ ቀኑን እና ሰዓቱን ከ&lt;strong&gt;አጠቃላይ&lt;/strong&gt; ክáሠየሚለዠየ&lt;strong&gt;ቅንብሮች&lt;/strong&gt; መተáŒá‰ áˆªá‹« ላይ ያስተካክሉá¢&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />ᣠ<ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">ስሠያክሉ</translation>
<translation id="3583757800736429874">&amp;á‹áˆ°á‹µáŠ• ድገáˆ</translation>
<translation id="3586931643579894722">á‹áˆ­á‹áˆ­ ደብቅ</translation>
-<translation id="3587482841069643663">áˆáˆ‰áˆ</translation>
<translation id="3600246354004376029"><ph name="TITLE" />ᣠ<ph name="DOMAIN" />ᣠ<ph name="TIME" /></translation>
<translation id="3615877443314183785">ትክክለኛ የአገáˆáŒáˆŽá‰µ ማብቂያ ቀን ያስገቡ</translation>
<translation id="36224234498066874">የአሰሳ á‹áˆ‚ብ አስወáŒá‹µâ€¦</translation>
@@ -321,7 +361,6 @@
<translation id="3681007416295224113">የሰርቲáŠáŠ¬á‰µ መረጃ</translation>
<translation id="3690164694835360974">መáŒá‰¢á‹« ደህንáŠá‰± የተጠበቀ አይደለáˆ</translation>
<translation id="3693415264595406141">የይለá ቃáˆá¦</translation>
-<translation id="3696411085566228381">áˆáŠ•áˆ</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">በመጫን ላይ…</translation>
<translation id="3712624925041724820">áˆáˆ‰áˆ áቃዶች ተሞክረዋáˆ</translation>
@@ -329,12 +368,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ወኪሉንᣠኬላá‹áŠ• እና የዲኤንኤስ á‹á‰…ረትን መáˆá‰°áˆ½<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">ደህንáŠá‰µá‹Ž ላይ የሚያመጣቸá‹áŠ• ስጋቶች ከተረዱ አደገኛ á•áˆ®áŒáˆ«áˆžá‰¹ ከመወገዳቸዠበáŠá‰µ <ph name="BEGIN_LINK" />ይህን ደህንáŠá‰± á‹«áˆá‰°áŒ á‰ á‰€ ጣቢያ ሊጎብኙ<ph name="END_LINK" /> ይችላሉá¢</translation>
<translation id="3739623965217189342">እርስዎ የቀዱት አገናáŠ</translation>
+<translation id="3744899669254331632">የድር ጣቢያዠChromium ሊያስኬዳቸዠየማይችሉ የተዘበራረበáˆáˆµáŠ­áˆ­áŠá‰¶á‰½áŠ• ስለላከ አáˆáŠ• ላይ <ph name="SITE" />ን መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች ብዙá‹áŠ• ጊዜ ጊዜያዊ ናቸá‹á£ ስለዚህ ይህ ገጽ በኋላ ላይ áˆáŠ“áˆá‰£á‰µ ሊሰራ ይችሠይሆናáˆá¢</translation>
+<translation id="3748148204939282805">በ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች áˆáŠ­ እንደ ሶáትዌርን መጫን ወይሠየáŒáˆ መረጃዎችን (ለáˆáˆ³áˆŒá¦ የይለá ቃላትንᣠየስáˆáŠ­ á‰áŒ¥áˆ®á‰½áŠ• ወይሠየክሬዲት ካርዶችን የመሳሰሉ) አጋáˆáŒ¦ መስጠት እንዲያደርጉ ሊያታáˆáˆˆá‹Žá‰µ ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">በአገáˆáŒ‹á‹­ ስህተት áˆáŠ­áŠ•á‹«á‰µ የትርጉሠስራዠተሰናክáˆáˆá¢</translation>
<translation id="3759461132968374835">በቅርብ ጊዜ ሪá–ርት የተደረጉ ብáˆáˆ½á‰¶á‰½ የለዎትáˆá¢ የብáˆáˆ½á‰µ ሪá–ርት ማድረጠተሰናክሎ ሳለ የተከሰቱ ብáˆáˆ½á‰¶á‰½ እዚህ አይታዩáˆá¢</translation>
+<translation id="3778403066972421603">ይህን ካርድ በእርስዎ የGoogle መለያ እና በዚህ መሣሪያ ላይ ማስቀመጥ á‹­áˆáˆáŒ‹áˆ‰?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">በ<ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> ላይ የአገáˆáŒáˆŽá‰µ ጊዜዠያበቃáˆ</translation>
<translation id="382518646247711829">ተኪ አገáˆáŒ‹á‹­ የሚጠቀሙ ከሆኑ...</translation>
<translation id="3828924085048779000">ባዶ የይለá áˆáˆ¨áŒ አይáˆá‰€á‹µáˆá¢</translation>
-<translation id="3845539888601087042">ታሪክን ወደ መለያዎ ከገቡ መሣሪያዎችዎ በማሳየት ላይᢠ<ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation>
<translation id="385051799172605136">ተመለስ</translation>
<translation id="3858027520442213535">ቀን እና ሰዓትን አዘáˆáŠ•</translation>
<translation id="3884278016824448484">የሚጋጭ የመሣሪያ ለዪ</translation>
@@ -342,11 +384,13 @@
<translation id="3886446263141354045">ይህን ጣቢያ የመድረስ ጥያቄዎ ለ<ph name="NAME" /> ተáˆáŠ³áˆ</translation>
<translation id="3890664840433101773">ኢሜይሠያክሉ</translation>
<translation id="3901925938762663762">ካርዱ አገáˆáŒáˆŽá‰µ ጊዜዠአብቅቷáˆ</translation>
-<translation id="3933571093587347751">{1,plural, =1{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ áˆáˆµáŠ­áˆ­ ወረቀቱ ከáŠáŒˆ የመጣ መሆኑ áŠá‹á¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢}one{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠከ# ቀኖች ወደáŠá‰µ የመጣ መሆኑ áŠá‹á¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢}other{ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ ማረጋገጫ እá‹á‰…ና ማረጋገጫዠከ# ቀኖች ወደáŠá‰µ የመጣ መሆኑ áŠá‹á¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢}}</translation>
-<translation id="3934680773876859118">የᒠዲ ኤá ሰáŠá‹µ መጫን አáˆá‰°áˆ³áŠ«áˆ</translation>
+<translation id="3945915738023014686">የተሰቀለ የብáˆáˆ½á‰µ ሪá–ርት መታወቂያ <ph name="CRASH_ID" /> (የአካባቢ የብáˆáˆ½á‰µ መታወቂያᦠ<ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ á‹•á‹á‰…ና ማረጋገጫዠየርዕሰ ጒዳይ አማራጭ ስሞችን አይጠቅስáˆá¢ ይህ በተሳሳተ á‹á‰…ረት የተከሰተ ወይሠአጥቂ የእርስዎን áŒáŠ•áŠ™áŠá‰µ አቋርጦ እየገባ ስለሆአሊሆን ይችላáˆá¢</translation>
<translation id="3963721102035795474">የአንባቢ áˆáŠá‰³</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{áˆáŠ•áˆ}=1{ከ1 ጣቢያ }one{ከ# ጣቢያዎች }other{ከ# ጣቢያዎች }}</translation>
<translation id="397105322502079400">በማስላት ላይ...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> ታáŒá‹·áˆ</translation>
+<translation id="3987940399970879459">ከ1 ሜባ á‹«áŠáˆ°</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 ድረ-ገጽ በአቅራቢያ}one{# ድረ-ገጾች በአቅራቢያ}other{# ድረ-ገጾች በአቅራቢያ}}</translation>
<translation id="4021036232240155012">ዲኤንኤስ የአንድ ድር ጣቢያ ስሠወደ የእሱ የበይáŠáˆ˜áˆ¨á‰¥ አድራሻ የሚተረጉሠየአá‹á‰³áˆ¨ መረብ አገáˆáŒáˆŽá‰µ áŠá‹á¢</translation>
<translation id="4030383055268325496">&amp;አክáˆáŠ• ቀáˆá‰¥áˆµ</translation>
@@ -357,56 +401,63 @@
<translation id="4079302484614802869">የተኪ á‹á‰…ር ቋሚ አገáˆáŒ‹á‹®á‰½áŠ• ሳይሆን የ.pac ስክሪá•á‰µ ዩአርኤሠለመጠቀሠáŠá‹ የተዋቀረá‹á¢</translation>
<translation id="4098354747657067197">አሳሳች ጣቢያ ከáŠá‰µ አለ</translation>
<translation id="4103249731201008433">የመሣሪያ መለያ á‰áŒ¥áˆ­ áˆáŠ­ á‹«áˆáˆ†áŠ áŠá‹</translation>
+<translation id="410351446219883937">ራስ-አጫá‹á‰µ</translation>
<translation id="4103763322291513355">የተከለከሉ የዩ አር ኤሎች á‹áˆ­á‹áˆ­ እና ሌሎች በስርዓት አስተዳዳሪዎ አስገዳጅáŠá‰µ የተሰጣቸዠመመሪያዎችን ለማየት &lt;strong&gt;chrome://policy&lt;/strong&gt;ን ይጎብኙá¢</translation>
-<translation id="4110615724604346410">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የዕá‹á‰…ና ማረጋገጫዠስህተቶች አሉበትᢠይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="4115378294792113321">ሮá‹</translation>
+<translation id="4116663294526079822">áˆáˆáŒŠá‹œ በዚህ ጣቢያ ላይ áቀድ</translation>
<translation id="4117700440116928470">የመመሪያ ወሰን አይደገááˆá¢</translation>
-<translation id="4118212371799607889">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የዕá‹á‰…ና ማረጋገጫዠበChromium የታመአአይደለáˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 ሌላ}one{# ሌሎች}other{# ሌሎች}}</translation>
<translation id="4130226655945681476">የአá‹á‰³áˆ¨ መረብ ገመዶችንᣠሞደሠእና ራá‹á‰°áˆ­áŠ• በመáˆá‰°áˆ½ ላይ</translation>
+<translation id="413544239732274901">የበለጠ ለመረዳት</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">áˆáˆˆáŒˆá‰¥ áŠá‰£áˆªáŠ• ተጠቀሠ(አáŒáŠ)</translation>
+<translation id="4165986682804962316">የጣቢያ ቅንብሮች</translation>
<translation id="4169947484918424451">Chromium ይህን ካርድ እንዲያስቀáˆáŒ¥áˆá‹Žá‰µ á‹­áˆáˆáŒ‹áˆ‰?</translation>
<translation id="4171400957073367226">መጥᎠየማረጋገጫ áŠáˆ­áˆ›</translation>
<translation id="4196861286325780578">&amp;á‹áˆ°á‹µáŠ• ድገáˆ</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />የኬላ እና የጸረ-ቫይረስ á‹á‰…ረቶችን መáˆá‰°áˆ½<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1 መተáŒá‰ áˆªá‹« ($1)}=2{2 መተáŒá‰ áˆªá‹«á‹Žá‰½ ($1ᣠ$2)}one{# መተáŒá‰ áˆªá‹«á‹Žá‰½ ($1ᣠ$2ᣠ$3)}other{# መተáŒá‰ áˆªá‹«á‹Žá‰½ ($1ᣠ$2ᣠ$3)}}</translation>
<translation id="4220128509585149162">ብáˆáˆ½á‰¶á‰½</translation>
+<translation id="422022731706691852">በ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች (የአሰሳ ተሞክሮዎን የሚጎዱ á•áˆ®áŒáˆ«áˆžá‰½áŠ• እንዲጭኑ ሊያታáˆáˆá‹Žá‰µ ሊሞክሩ ይችላሉ ለáˆáˆ³áˆŒá¦ የእርስዎን የመáŠáˆ» ገጽ በመለወጥ ወይሠእርስዎ በሚጎበኙዋቸዠጣቢያዎች ላይ ትርá ማስታወቂያዎችን ማሳየት የመሳሰሉ በማድረáŒ)ᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />የአá‹á‰³áˆ¨ መረብ መመርመሪያን አሂደዠይሞክሩ<ph name="END_LINK" /></translation>
+<translation id="4235360514405112390">ትክክáˆ</translation>
<translation id="4250431568374086873">ወደዚህ ጣቢያ á‹«áˆá‹Žá‰µ áŒáŠ•áŠ™áŠá‰µ ሙሉ በሙሉ ደህንáŠá‰± አስተማማአአይደለáˆá¢</translation>
<translation id="4250680216510889253">አይ</translation>
<translation id="425582637250725228">ያደረጓቸዠለá‹áŒ¦á‰½ ላይቀመጡ ይችላሉá¢</translation>
<translation id="4258748452823770588">መጥᎠáŠáˆ­áˆ›</translation>
+<translation id="4265872034478892965">በእርስዎ አስተዳዳሪ የተáˆá‰€á‹°</translation>
<translation id="4269787794583293679">(áˆáŠ•áˆ የተጠቃሚ ስሠየለáˆ)</translation>
<translation id="4275830172053184480">መሣሪያዎን ዳáŒáˆ ያስጀáˆáˆ©</translation>
<translation id="4280429058323657511">ᣠአገáˆáŒáˆŽá‰± የሚያበቃዠበ<ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google የጥንቃቄ አሰሳ በቅርቡ በ<ph name="SITE" /> <ph name="BEGIN_LINK" />ጎጂ á•áˆ®áŒáˆ«áˆžá‰½<ph name="END_LINK" />ን ላይ አáŒáŠá‰·áˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="4300246636397505754">የወላጅ አስተያየት ጥቆማዎች</translation>
<translation id="4304224509867189079">á‹­áŒá‰¡</translation>
-<translation id="432290197980158659">አገáˆáŒ‹á‹© በá‹áˆµáŒ -áŒáŠ•á‰¡ የሚጠበበáŠáŒˆáˆ®á‰½ ጋር የማይዛመድ የዕá‹á‰…ና ማረጋገጫ አቅርቧáˆá¢ እáŠá‹šáˆ… የሚጠበበáŠáŒˆáˆ®á‰½ እርስዎን ለመጠበቅ ሲባሠከáተኛ ደህንáŠá‰µ ጥበቃ በሚያስáˆáˆáŒ‹á‰¸á‹ የተወሰኑ ድር ጣቢያዎች ላይ ተካትተዋáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
+<translation id="4312866146174492540">አáŒá‹µ (áŠá‰£áˆª)</translation>
<translation id="4325863107915753736">ጽሑá‰áŠ• ማáŒáŠ˜á‰µ አáˆá‰°á‰»áˆˆáˆ</translation>
<translation id="4326324639298822553">የእርስዎን የአገáˆáŒáˆŽá‰µ ማብቂያ ቀን ይመáˆáŠ¨á‰± እና እንደገና ይሞክሩ</translation>
<translation id="4331708818696583467">ደህንáŠá‰± አáˆá‰°áŒ á‰ á‰€áˆ</translation>
<translation id="4356973930735388585">በዚህ ጣቢያ ላይ ያሉ አጥቂዎች መረጃዎን (ለáˆáˆ³áˆŒá¦ áŽá‰¶á‹Žá‰½á£ የይለá ቃላትᣠመáˆá‹•áŠ­á‰¶á‰½ እና ክሬዲት ካርዶች) ሊሰርበወይሠሊሰርዙ የሚችሉ አደገኛ á•áˆ®áŒáˆ«áˆžá‰½áŠ• በኮáˆá’á‹á‰°áˆ­á‹Ž ላይ ለመጫን ሊሞክሩ ይችላሉá¢</translation>
<translation id="4372948949327679948">የተጠበቀዠየ<ph name="VALUE_TYPE" /> ዋጋ áŠá‹á¢</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋáˆá£ áŠáŒˆáˆ­ áŒáŠ• አገáˆáŒ‹á‹© ያቀረበዠየእá‹á‰…ና ማረጋገጫ በሰጪዠተሽሯáˆá¢ ይህ ማለት አገáˆáŒ‹á‹© ያቀረበዠየደህንáŠá‰µ áˆáˆµáŠ­áˆ­áŠá‰¶á‰½ áˆáŒ½áˆž ሊታመኑ አይገባáˆá¢ ከአጥቂ ጋር እየተገናኙ ሊሆን ይችላáˆá¢</translation>
<translation id="4381091992796011497">የተጣቃሚ ስáˆá¦</translation>
<translation id="4394049700291259645">አሰናክáˆ</translation>
<translation id="4406896451731180161">የáለጋ á‹áŒ¤á‰¶á‰½</translation>
+<translation id="4424024547088906515">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠበChrome የሚታመን አይደለáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> የመáŒá‰¢á‹« እá‹á‰…ና ማረጋገጫዎን አáˆá‰°á‰€á‰ áˆˆáˆá£ ወይሠገና አáˆá‰°áˆ°áŒ á‹Žá‰µ ይሆናáˆá¢</translation>
<translation id="443673843213245140">የተኪ መጠቀሠተሰናክáˆáˆ áŒáŠ• áŒáˆáŒ½ የሆአየተኪ á‹á‰…ር ተገáˆáŒ¿áˆá¢</translation>
-<translation id="4492190037599258964">የáለጋ á‹áŒ¤á‰¶á‰½ ለ'<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">የማረጋገጥ ስህተትᦠ<ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">የሥርዓት አስተዳዳሪá‹áŠ• ማáŠáŒ‹áŒˆáˆ­</translation>
<translation id="450710068430902550">ከአስተዳዳሪ ጋር ማጋራት</translation>
<translation id="4515275063822566619">ካርዶች እና አድራሻዎች ከChrome እና ከGoogle መለያዎ (<ph name="ACCOUNT_EMAIL" />) የተገኙ ናቸá‹á¢ በ<ph name="BEGIN_LINK" />ቅንብሮች<ph name="END_LINK" /> á‹áˆµáŒ¥ ሊያቀናብሯቸዠይችላሉá¢</translation>
<translation id="4522570452068850558">á‹áˆ­á‹áˆ®á‰½</translation>
+<translation id="4552089082226364758">ብáˆáŒ­á‰³</translation>
<translation id="4558551763791394412">ቅጥያዎችዎን አሰናክለዠይሞክሩá¢</translation>
<translation id="457875822857220463">መላኪያ</translation>
<translation id="4587425331216688090">አድራሻ ከChrome ይወገድ?</translation>
-<translation id="4589078953350245614">ወደ <ph name="DOMAIN" /> ለመድረስ ሞክረዠáŠá‰ áˆ­á£ áŠáŒˆáˆ­ áŒáŠ• አገáˆáŒ‹á‹© የማይሠራ የዕá‹á‰…ና ማረጋገጫ አቅርቧáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="4592951414987517459">ወደ የእርስዎ <ph name="DOMAIN" /> áŒáŠ•áŠ™áŠá‰µ ዘመናዊ የáˆáˆµáŒ áˆ« ጥቅሠበመጠቀሠተመስጥሯáˆá¢</translation>
<translation id="4594403342090139922">&amp;ሰርá‹áŠ• ቀáˆá‰¥áˆµ</translation>
<translation id="4619615317237390068">ከሌሎች መሣሪያዎች የመጡ ትሮች</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠስህተቶች አሉበትᢠይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
+<translation id="4690462567478992370">áˆáŠ­ á‹«áˆáˆ†áŠ የእá‹á‰…ና ማረጋገጫ መጠቀሠአá‰áˆ</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">የእርስዎ áŒáŠ•áŠ™áŠá‰µ ተቋርጧáˆ</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />የWindows አá‹á‰³áˆ¨ መረብ መመርመሪያን በማሄድ ላይ<ph name="END_LINK" /></translation>
@@ -423,21 +474,24 @@
<translation id="4771973620359291008">á‹«áˆá‰³á‹ˆá‰€ ስህተት ተከስቷáˆá¢</translation>
<translation id="4800132727771399293">የእርስዎን የአገáˆáŒáˆŽá‰µ ማብቂያ ቀን እና CVC á‹­áˆá‰µáˆ¹ እና እንደገና ይሞክሩ</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102"><ph name="SITE" /> Google Chrome ሊሰራባቸዠየማይችላቸዠየተዘበራረበáˆáˆµáŠ­áˆ­áŠá‰¶á‰½áŠ• ስለላከ ድር ጣቢያá‹áŠ• አáˆáŠ• መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች አብዛኛዠጊዜ ጊዜያዊ ናቸá‹á£ ስለዚህ ይህ ገጽ በኋላ ላይ ሊሰራ ይችላáˆá¢</translation>
<translation id="4813512666221746211">የአá‹á‰³áˆ¨ መረብ ስህተት</translation>
<translation id="4816492930507672669">ገጹን አመጣጥን</translation>
<translation id="483020001682031208">áˆáŠ•áˆ የሚታዩ አካላዊ ድረ-ገጾች የሉáˆ</translation>
<translation id="4850886885716139402">አሳይ</translation>
<translation id="4854362297993841467">የማድረሻ ዘዴዠአይገáŠáˆá¢ የተለየ ዘዴ ይሞክሩá¢</translation>
<translation id="4858792381671956233">ይህን ገጽ መጎብኘት ችáŒáˆ­ ካለዠወላጆችዎንጠይቀዋáˆ</translation>
+<translation id="4863764087567530506">ይህ ይዘት ሶáትዌር እንዲጭኑ ወይሠየáŒáˆ መረጃ ገáˆáŒ¸á‹ እንዲያሳዩ ሊያሳስትዎት ሊሞክር ይችሠይሆናáˆá¢ <ph name="BEGIN_LINK" />የሆáŠá‹ ሆኖ አሳይ<ph name="END_LINK" />á¢</translation>
<translation id="4880827082731008257">የáለጋ ታሪክ</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />ᣠ<ph name="TYPE_2" />á£, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{እና 1 ተጨማሪ ድረ-ገጽ}one{እና # ተጨማሪ ድረ-ገጾች}other{እና # ተጨማሪ ድረ-ገጾች}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">ገጹ ከማይታወቅ ቋንቋ ወደ <ph name="LANGUAGE_LANGUAGE" /> ተተርጉሟáˆ</translation>
<translation id="4923459931733593730">ክáá‹«</translation>
<translation id="4926049483395192435">መገለጽ አለበትá¢</translation>
<translation id="495170559598752135">እርáˆáŒƒá‹Žá‰½</translation>
<translation id="4958444002117714549">á‹áˆ­á‹áˆ©áŠ• ዘርጋ</translation>
-<translation id="4962322354953122629">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የዕá‹á‰…ና ማረጋገጫዠበChrome የታመአአይደለáˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
+<translation id="4974590756084640048">ማስጠንቀቂያዎችን ዳáŒáˆ አንቃ</translation>
<translation id="4989809363548539747">ይህ ተሰኪ አይደገááˆ</translation>
<translation id="5002932099480077015">የáŠá‰ƒ እንደሆአChrome ለበለጠ áˆáŒ£áŠ• ቅጽ አሞላሠሲባሠበዚህ መሳሪያ ላይ ያለዠየካርድዎን ቅጂ ያከማቻáˆá¢</translation>
<translation id="5018422839182700155">ይህን ገጽ መክáˆá‰µ አáˆá‰°á‰»áˆˆáˆ</translation>
@@ -445,14 +499,15 @@
<translation id="5023310440958281426">የአስተዳዳሪዎ መመሪያዎችን ያረጋáŒáŒ¡</translation>
<translation id="5029568752722684782">ቅጂን አጽዳ</translation>
<translation id="5031870354684148875">ስለ Google ትርጉáˆ</translation>
+<translation id="5039804452771397117">áቀድ</translation>
<translation id="5040262127954254034">áŒáˆ‹á‹ŠáŠá‰µ</translation>
<translation id="5045550434625856497">ትክክሠያáˆáˆ†áŠ የይለá ቃáˆ</translation>
<translation id="5056549851600133418">ለእርስዎ የሚሆኑ ጽሑáŽá‰½</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />የወኪሉን አድራሻ መáˆá‰°áˆ½<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{áˆáŠ•áˆ ኩኪዎች የሉáˆ}=1{1 ጣቢያ ኩኪዎችን ይጠቀማáˆá¢ }one{# ጣቢያዎች ኩኪዎችን ይጠቀማሉᢠ}other{# ጣቢያዎች ኩኪዎችን ይጠቀማሉᢠ}}</translation>
<translation id="5087286274860437796">የአገáˆáŒ‹á‹­ የዕá‹á‰…ና ማረጋገጫ በዚህ ጊዜ ላይ የሚሰራ አይደለáˆá¢</translation>
<translation id="5087580092889165836">ካርድ አክáˆ</translation>
<translation id="5089810972385038852">áŒá‹›á‰µ</translation>
+<translation id="5094747076828555589">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠበChromium የሚታመን አይደለáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
<translation id="5095208057601539847">ጠቅላይ áŒá‹›á‰µ</translation>
<translation id="5115563688576182185">(64-ቢት)</translation>
<translation id="5141240743006678641">የተመሳሰሉ የይለá ቃላት ከGoogle áˆáˆµáŠ­áˆ­áŠá‰¶á‰½á‹Ž ጋር ያመሳስሉ</translation>
@@ -468,26 +523,26 @@
<translation id="5222812217790122047">ኢሜይሠያስáˆáˆáŒ‹áˆ</translation>
<translation id="5251803541071282808">ደመና</translation>
<translation id="5277279256032773186">በሥራ ላይ Chrome እየተጠቀሙ áŠá‹Žá‰µ? ንáŒá‹µ ሥራዎች ለሠራተኞቻቸዠየChrome ቅንብሮችን ማስተዳደር ይችላሉᢠየበለጠ ይረዱ</translation>
+<translation id="5297526204711817721">ከዚህ ጣቢያ ጋር ያለዎት áŒáŠ•áŠ™áŠá‰µ áŒáˆ‹á‹Š አይደለáˆá¢ ከáˆáŠ“ባዊ á‹•á‹áŠá‰³ áˆáŠá‰³ በማናቸá‹áˆ ጊዜ ለመá‹áŒ£á‰µá£ የጆሮ ማዳመጫን ያስወáŒá‹± እና ተመለስ የሚለá‹áŠ• ይጫኑá¢</translation>
<translation id="5299298092464848405">መáˆáˆªá‹«áŠ• መተንተን ላይ ስህተት</translation>
-<translation id="5300589172476337783">አሳይ</translation>
<translation id="5308689395849655368">የብáˆáˆ½á‰µ ሪá–ርት ማድረጠተሰናክáˆáˆá¢</translation>
<translation id="5317780077021120954">አስቀáˆáŒ¥</translation>
<translation id="5327248766486351172">ስáˆ</translation>
-<translation id="5337705430875057403">በ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች እንደ ሶáትዌር መጫን ወይሠየáŒáˆ መረጃዎን (ለáˆáˆ³áˆŒá¦ የይለá ቃሎችᣠየስáˆáŠ­ á‰áŒ¥áˆ®á‰½ ወይሠክሬዲት ካርዶች) አሳáˆáŽ መáŒáˆˆáŒ½ ያሉ አደገኛ áŠáŒˆáˆ®á‰½áŠ• እንዲያደርጉ ሊያታáˆáˆ‰á‹Žá‰µ ይችሉ ይሆናáˆá¢</translation>
-<translation id="5359637492792381994">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የዕá‹á‰…ና ማረጋገጫዠበዚህ ጊዜ ላይ የሚሠራ አይደለáˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
+<translation id="5355557959165512791">የዕá‹á‰…ና ማረጋገጫዠስለተሻረ <ph name="SITE" />ን መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች አብዛኛዠጊዜ ጊዜያዊ ብቻ ናቸá‹á£ ስለዚህ ይህ ገጽ በኋላ ላይ ሊሠራ ይችላáˆá¢</translation>
<translation id="536296301121032821">የመáˆáˆªá‹« ቅንብሮችን ማከማቸት አáˆá‰°áˆ³áŠ«áˆ</translation>
<translation id="5386426401304769735">የዚህ ጣቢያ የዕá‹á‰…ና ማረጋገጫ ሰንሰለቱ SHA-1 በመጠቀሠየተáˆáˆ¨áˆ˜ የዕá‹á‰…ና ማረጋገጫን ያካትታáˆá¢</translation>
<translation id="5402410679244714488">አገáˆáŒáˆŽá‰± የሚያበቃá‹á¦ <ph name="EXPIRATION_DATE_ABBR" />ᣠለመጨረሻ ጊዜ ጥቅሠላይ የዋለዠከአንድ ዓመት በáŠá‰µ</translation>
+<translation id="540969355065856584">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠበዚህ ጊዜ ላይ የሚሰራ አይደለáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
<translation id="5421136146218899937">የአሰሳ á‹áˆ‚ብ አጽዳ…</translation>
<translation id="5430298929874300616">á‹•áˆá‰£á‰µ አስወáŒá‹µ</translation>
<translation id="5431657950005405462">የእርስዎ á‹á‹­áˆ አáˆá‰°áŒˆáŠ˜áˆ</translation>
-<translation id="5435775191620395718">ታሪክን ከዚህ መሣሪያ በማሳየት ላይᢠ<ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">«<ph name="ERROR_PATH" />» ላይ የብያኔ ማረጋገጥ ስህተትᦠ<ph name="ERROR" /></translation>
<translation id="5452270690849572955">ይህ <ph name="HOST_NAME" /> ገጽ ሊገአአይችáˆáˆ</translation>
<translation id="5455374756549232013">መጥᎠየመáˆáˆªá‹« ጊዜ ማህተáˆ</translation>
<translation id="5455790498993699893">'<ph name="ACTIVE_MATCH" /> ከ
<ph name="TOTAL_MATCHCOUNT" />'
nil</translation>
+<translation id="5457113250005438886">áˆáŠ­ á‹«áˆáˆ†áŠ</translation>
<translation id="5470861586879999274">&amp;አርትዕን ድገáˆ</translation>
<translation id="54817484435770891">የሚሰራ አድራሻ ያስገቡ</translation>
<translation id="5492298309214877701">በኩባንያᣠበድርጅት ወይሠበትáˆáˆ…ርት ቤት á‹áˆµáŒ  መረብ á‹áˆµáŒ¥ ያለዠይህ ጣቢያ እንደ á‹áŒ«á‹Š የድር ጣቢያ ተመሳሳይ ዩአርኤሠአለá‹á¢
@@ -504,6 +559,8 @@ nil</translation>
<translation id="5571083550517324815">ከዚህ አድራሻ ላይ መá‹áˆ°á‹µ አይቻáˆáˆá¢ የተለየ አድራሻ á‹­áˆáˆ¨áŒ¡á¢</translation>
<translation id="5572851009514199876">Chrome እርስዎ ይህን ጣቢያ እንዲደርሱ የተáˆá‰€á‹°áˆá‹Ž መሆኑን ወይሠአለመሆኑን እንዲያረጋáŒáŒ¥ እባክዎ ይጀáˆáˆ©áŠ“ ወደ Chrome á‹­áŒá‰¡á¢</translation>
<translation id="5580958916614886209">የእርስዎን የአገáˆáŒáˆŽá‰µ ማብቂያ ወር ይመáˆáŠ¨á‰± እና እንደገና ይሞክሩ</translation>
+<translation id="5586446728396275693">áˆáŠ•áˆ የተቀመጡ አድራሻዎች የሉáˆ</translation>
+<translation id="5595485650161345191">አድራሻ አርትዕ</translation>
<translation id="560412284261940334">አስተዳደር አይደገááˆ</translation>
<translation id="5610142619324316209">áŒáŠ•áŠ™áŠá‰±áŠ• መáˆá‰°áˆ½</translation>
<translation id="5610807607761827392">ካርዶችን እና አድራሻዎችን በ<ph name="BEGIN_LINK" />ቅንብሮች<ph name="END_LINK" /> á‹áˆµáŒ¥ ማቀናበር ይችላሉá¢</translation>
@@ -511,15 +568,18 @@ nil</translation>
<translation id="5622887735448669177">ይህን ጣቢያ መá‹áŒ£á‰µ á‹­áˆáˆáŒ‹áˆ‰?</translation>
<translation id="5629630648637658800">የመáˆáˆªá‹« ቅንብሮችን መጫን አáˆá‰°áˆ³áŠ«áˆ</translation>
<translation id="5631439013527180824">áˆáŠ­ á‹«áˆáˆ†áŠ የመሣሪያ አስተዳደር ማስመሰያ</translation>
+<translation id="5633066919399395251">በአáˆáŠ‘ ጊዜ በ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ የሚገኙ አጥቂዎች የእርስዎን መረጃ (ለáˆáˆ³áˆŒá¦ áŽá‰¶á‹Žá‰½á£ የይለá ቃላትᣠመáˆá‹•áŠ­á‰¶á‰½ እና ክሬዲት ካርዶች) የሚሰርበወይሠየሚሰርዙ አደገኛ á•áˆ®áŒáˆ«áˆžá‰½áŠ• በእርስዎ ኮáˆá’á‹á‰°áˆ­ ላይ ለመጫን እየሞከሩ ሊሆኑ ይችላሉᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">አካባቢ</translation>
+<translation id="5659593005791499971">ኢሜይáˆ</translation>
<translation id="5669703222995421982">áŒáˆ‹á‹ŠáŠá‰µ የተላበሰ ይዘት á‹«áŒáŠ™</translation>
<translation id="5675650730144413517">ይህ ገጽ እየሠራ አይደለáˆ</translation>
-<translation id="5677928146339483299">ታáŒá‹·áˆ</translation>
-<translation id="5694783966845939798"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋáˆá£ áŠáŒˆáˆ­ áŒáŠ• አገáˆáŒ‹á‹© ደካማ የáŠáˆ­áˆ› ስáˆá‰°-ቀመር (እንደ SHA-1 ያለ) በመጠቀሠየተáˆáˆ¨áˆ˜ የእá‹á‰…ና ማረጋገጫ áŠá‹ ያቀረበá‹á¢ ይህሠማለት አገáˆáŒ‹á‹© ያቀረበዠየደህንáŠá‰µ áˆáˆµáŠ­áˆ­áŠá‰¶á‰½ የተጭበረበሩ ሊሆኑ ይችላሉᣠእናሠአገáˆáŒ‹á‹© እርስዎ የሚጠብá‰á‰µ አገáˆáŒ‹á‹­ ላይሆን ይችላሠ(ከአጥቂ ጋር እየተገናኙ ሊሆን ይችላáˆ)ᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="5710435578057952990">የዚህ ድረ-ገጽ ማንáŠá‰µ አáˆá‰°áˆ¨áŒ‹áŒˆáŒ áˆá¢</translation>
+<translation id="5713016350996637505">አታላይ ይዘት ታáŒá‹·áˆ</translation>
<translation id="5720705177508910913">የአáˆáŠ‘ ተጠቃሚ</translation>
<translation id="5732392974455271431">የእርስዎ ወላጆች እገዳá‹áŠ• ሊያáŠáˆ±áˆá‹Ž ይችላሉ</translation>
<translation id="5763042198335101085">ትክክለኛ የኢሜይሠአድራሻ ያስገቡ</translation>
<translation id="5765072501007116331">የማድረሻ ዘዴዎችን እና መስáˆáˆ­á‰¶á‰½áŠ• ለመመáˆáŠ¨á‰µ አድራሻ á‹­áˆáˆ¨áŒ¡</translation>
+<translation id="5778550464785688721">MIDI መሣሪያዎች ሙሉ á‰áŒ¥áŒ¥áˆ­</translation>
<translation id="5784606427469807560">የእርስዎን ካርድ ማረጋገጥ ላይ አንድ ችáŒáˆ­ áŠá‰ áˆ­á¢ የበይáŠáˆ˜áˆ¨á‰¥ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• á‹­áˆá‰µáˆ¹á‰µ እና እንደገና ይሞክሩá¢</translation>
<translation id="5785756445106461925">በተጨማሪᣠይህ ገጽ ደህንáŠá‰³á‰¸á‹ á‹«áˆá‰°áŒ á‰ á‰€ ሌሎች ንብረቶችን አካትቷáˆá¢ እáŠá‹šáˆ… ንብረቶች በሽáŒáŒáˆ­ ወቅት በሌሎች ሊታዩ ይችላሉᣠእናሠየገጹን መáˆáŠ­ ለመለወጥ በአጥቂዎች ሊቀየሩ ይችላሉá¢</translation>
<translation id="5786044859038896871">የካርድዎን መረጃ መሙላት á‹­áˆáˆáŒ‹áˆ‰?</translation>
@@ -528,14 +588,14 @@ nil</translation>
<translation id="5813119285467412249">&amp;አክáˆáŠ• ድገáˆ</translation>
<translation id="5814352347845180253">ከ<ph name="SITE" /> እና ሌሎች አንዳንድ ጣቢያዎች የመጣ የá•áˆªáˆšá‹¨áˆ ይዘት መዳረሻ ሊያጡ ይችላሉá¢</translation>
<translation id="5838278095973806738">በአጥቂዎች ሊሰረቅ ስለሚችሠበዚህ ጣቢያ ላይ ማናቸá‹áˆ አደጋን ሊያስከትሠየሚችሠመረጃ (ለáˆáˆ³áˆŒá¦ የይለá ቃሎች ወይሠየክሬዲት ካርዶች) ማስገባት የለብዎትáˆá¢</translation>
-<translation id="5843436854350372569"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋáˆá£ áŒáŠ• አገáˆáŒ‹á‹© ደካማ á‰áˆá የያዘ የእá‹á‰…ና ማረጋገጫ áŠá‹ ያቀረበá‹á¢ አንድ አጥቂ የáŒáˆ á‰áˆá‰áŠ• ሰብሮ ሊሆን ይችላáˆá£ እና አገáˆáŒ‹á‹© የጠበá‰á‰µ ላይሆን ይችላሠ(ከአጥቂ ጋር እየተገናኙ ሊሆኑ ይችላሉ)ᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">ይህ ጣቢያ ሊደረስበት አይችáˆáˆ</translation>
<translation id="5869522115854928033">የተቀመጡ የይለá ቃሎች</translation>
<translation id="5872918882028971132">የወላጅ አስተያየት ጥቆማዎች</translation>
<translation id="5901630391730855834">ቢጫ</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (ሰáˆáˆ¯áˆ)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 ጥቅሠላይ ያለ}one{# ጥቅሠላይ ያለ}other{# ጥቅሠላይ}}</translation>
<translation id="5926846154125914413">ከአንዳንድ ጣቢያዎች የመጣ የá•áˆªáˆšá‹¨áˆ ይዘት መዳረሻ ሊያጡ ይችላሉá¢</translation>
<translation id="5959728338436674663">አደገኛ መተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• እና ጣቢያዎችን ማáŒáŠ˜á‰µ እንዲያáŒá‹ አንዳንድ <ph name="BEGIN_WHITEPAPER_LINK" />የሥርዓት መረጃ እና የገጽ ይዘት<ph name="END_WHITEPAPER_LINK" />ን በራስ-ሰር ወደ Google ይላኩᢠ<ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">ሳáˆáŠ•á‰µ</translation>
<translation id="5967867314010545767">ከታሪክ አስወáŒá‹µ</translation>
<translation id="5975083100439434680">አሳንስ</translation>
<translation id="598637245381783098">የክáá‹« መተáŒá‰ áˆªá‹«áŠ• መክáˆá‰µ አይቻáˆáˆ</translation>
@@ -544,21 +604,29 @@ nil</translation>
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{ገጽ 1}one{ገጽ #}other{ገጽ #}}</translation>
<translation id="6017514345406065928">አረንጓዴ</translation>
+<translation id="6017850046339264347">በ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች የሆአሌላ áŠáŒˆáˆ­ እንደሆአመስለዠየሚቀርቡ አታላይ መተáŒá‰ áˆªá‹«á‹Žá‰½áŠ• ሊጭኑ ወይሠየእርስዎን ዱካ ለመከታተሠየሚያስችሠá‹áˆ‚ብን ሊሰበስቡ ይችላሉᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />ᣠ<ph name="TYPE_2" />ᣠ<ph name="TYPE_3" /> (ሰáˆáˆ¯áˆ)</translation>
<translation id="6027201098523975773">ስሠያስገቡ</translation>
<translation id="6040143037577758943">á‹áŒ‹</translation>
<translation id="6042308850641462728">ተጨማሪ</translation>
+<translation id="6047233362582046994">በእርስዎ ደህንáŠá‰µ ላይ የሚያመጣቸá‹áŠ• ስጋቶች ከተረዱ አደገኛ መተáŒá‰ áˆªá‹«á‹Žá‰¹ ከመወገዳቸዠበáŠá‰µ <ph name="BEGIN_LINK" />ይህን ጣቢያ መጎብኘት<ph name="END_LINK" /> ይችላሉá¢</translation>
+<translation id="6051221802930200923"><ph name="SITE" /> የዕá‹á‰…ና ማረጋገጫ ሚስማር መሰካትን ስለሚጠቀሠድር ጣቢያá‹áŠ• አáˆáŠ• መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች ብዙá‹áŠ• ጊዜ ጊዜያዊ ስለሆኑ ይህ ገጽ በኋላ ላይ ሊሠራ ይችላáˆá¢</translation>
<translation id="6060685159320643512">ይጠንቀá‰á£ እáŠá‹šáˆ… ሙከራዎች ሊያስቸáŒáˆ© ይችላሉ</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">በአስተዳዳሪ የቀረበ የእá‹á‰…ና ማረጋገጫ በመጠቀሠይዘት ደርሰዋáˆá¢ ለ<ph name="DOMAIN" /> የሚያቀርቡት á‹áˆ‚ብ በአስተዳዳሪዎ ሊያዠይችላáˆá¢</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1 የይለá ቃሠ(የተሰመረ)}one{# የይለá ቃሎች (የተሰመሩ)}other{# የይለá ቃሎች (የተሰመሩ)}}</translation>
<translation id="6146055958333702838">ማናቸá‹áˆ ገመዶችን á‹­áˆá‰µáˆ¹áŠ“ እየተጠቀሙ ሊሆኑ የሚችáˆá‰¸á‹áŠ• ማንኛá‹áˆ ራá‹á‰°áˆ®á‰½á£
ሞደሞችን ወይሠሌላ አá‹á‰³áˆ¨ መረብ መሣሪያዎችን ዳáŒáˆ ያስጀáˆáˆ©á¢</translation>
<translation id="614940544461990577">ይሞክሩá¦</translation>
<translation id="6151417162996330722">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫዠበጣሠረጅሠየሆአየማረጋገጫ ጊዜ አለá‹á¢</translation>
<translation id="6157877588268064908">የመላኪያ ዘዴዎችን እና መስáˆáˆ­á‰¶á‰½áŠ• ለመመáˆáŠ¨á‰µ አድራሻ á‹­áˆáˆ¨áŒ¡</translation>
+<translation id="6158003235852588289">የGoogle ጥንቃቄ አሰሳ በቅርቡ በ<ph name="SITE" /> ላይ Google ማስገር እንዳለ ደርሶበታáˆá¢ አስጋሪ ጣቢያዎች እርስዎን ለማታለሠእንደ ሌሎች ድር ጣቢያዎች መስለዠይቀርባሉá¢</translation>
<translation id="6165508094623778733">ተጨማሪ ለመረዳት</translation>
+<translation id="6169916984152623906">አáˆáŠ• በáŒáˆ ማሰስ ይችላሉᣠእና ይህን መሣሪያ የሚጠቀሙ ሰዎች የእርስዎን እንቅስቃሴ አይመለከቱáˆá¢ á‹­áˆáŠ•áŠ“ᣠá‹áˆ­á‹¶á‰½ እና á‹•áˆá‰£á‰¶á‰½ ይቀመጣሉá¢</translation>
<translation id="6177128806592000436">ወደዚህ ጣቢያ á‹«áˆá‹Žá‰µ áŒáŠ•áŠ™áŠá‰µ ደህንáŠá‰± አስተማማአአይደለáˆ</translation>
<translation id="6184817833369986695">(የተመሳሳይ ሰዎች ስብስብᦠ<ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">የበይáŠáˆ˜áˆ¨á‰¥ áŒáŠ‘áŠáŠá‰µá‹ŽáŠ• ያረጋáŒáŒ¡</translation>
<translation id="6218753634732582820">ከChromium ላይ አድራሻ ይወገድ?</translation>
+<translation id="6221345481584921695">Google የጥንቃቄ አሰሳ በቅርብ ጊዜ <ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ተንኮáˆ-አዘሠዌር<ph name="END_LINK" /> አáŒáŠá‰·áˆá¢ በመደበኛ ጊዜ ደህንáŠá‰³á‰¸á‹ የተጠበበድር ጣቢያዎች አንዳንድ ጊዜ በተንኮáˆ-አዘሠዌር ሊጠበይችላሉᢠተንኮáˆ-አዘሠይዘቱ የሚታወቅ የተንኮáˆ-አዘሠዌር አሰራጭ ከሆáŠá‹ <ph name="SUBRESOURCE_HOST" /> áŠá‹ የመጣá‹á¢</translation>
<translation id="6251924700383757765">የáŒáˆ‹á‹ŠáŠá‰µ መመሪያ</translation>
<translation id="6254436959401408446">ይህን ገጽ ለመክáˆá‰µ በቂ ማህደረ ትá‹áˆµá‰³ የለáˆ</translation>
<translation id="625755898061068298">ለዚህ ጣቢያ የደህንáŠá‰µ ማስጠንቀቂያዎችን ለማሰናከሠመርጠዋáˆá¢</translation>
@@ -584,15 +652,14 @@ nil</translation>
<translation id="6404511346730675251">á‹•áˆá‰£á‰µ አርትዕ</translation>
<translation id="6410264514553301377">የ<ph name="CREDIT_CARD" /> የአገáˆáŒáˆŽá‰µ ማብቂያ ቀን እና ሲቪሲ ያስገቡ</translation>
<translation id="6414888972213066896">ይህን ጣቢያ መጎብኘት ችáŒáˆ­ ካለዠወላጅዎን ጠይቀዋáˆ</translation>
-<translation id="6416403317709441254">የድር ጣቢያዠChrome ሊያስተናáŒá‹°á‹ የማይችሠብትንትን ያሉ አሳማአáˆáˆµáŠ­áˆ­áŠ•á‰¶á‰½ ስለላከ አáˆáŠ• <ph name="SITE" />ን መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች ብዙá‹áŠ• ጊዜ ጊዜያዊ ናቸዠስለዚህ ይህ ገጽ áˆáŠ“áˆá‰£á‰µ በኋላ ላይ ሊሠራ ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="6417515091412812850">የእá‹á‰…ና ማረጋገጫዠተሽሮ እንደሆአማረጋገጥ አáˆá‰°á‰»áˆˆáˆá¢</translation>
<translation id="6433490469411711332">የዕá‹á‰‚á‹« መረጃን ያርትዑ</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ማገናኘት አሻáˆáˆ¨áŠ ብáˆáˆá¢</translation>
<translation id="6446608382365791566">ተጨማሪ መረጃ ያክሉ</translation>
+<translation id="6447842834002726250">ኩኪዎች</translation>
<translation id="6451458296329894277">እንደገና ለማስገባት የማረጋገጫ ቅጽ</translation>
<translation id="6456339708790392414">የእርስዎ ክáá‹«</translation>
<translation id="6458467102616083041">áŠá‰£áˆªá‹ áለጋ በመáˆáˆªá‹« ስለተሰናከለ ችላ ተብáˆáˆá¢</translation>
-<translation id="6462969404041126431">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ á‹•á‹á‰…ና ማረጋገጫዠተሽሮ ሊሆን ይችላáˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="647261751007945333">የመሣሪያ መáˆáˆªá‹«á‹Žá‰½</translation>
<translation id="6477321094435799029">Chrome በዚህ ገጽ ላይ á‹«áˆá‰°áˆˆáˆ˜á‹° ኮድ አáŒáŠá‰·áˆá£ እና የእርስዎን የáŒáˆ መረጃ (ለáˆáˆ³áˆŒá¦ የይለá ቃላትᣠስáˆáŠ­ á‰áŒ¥áˆ®á‰½ እና ክሬዲት ካርዶች) ለመጠበቅ ሲባሠአáŒá‹¶á‰³áˆá¢</translation>
<translation id="6489534406876378309">ድáˆáˆµáˆ¶á‰½áŠ• መስቀሠጀáˆáˆ­</translation>
@@ -604,20 +671,19 @@ nil</translation>
<translation id="6556915248009097796">አገáˆáŒáˆŽá‰± የሚያበቃá‹á¦ <ph name="EXPIRATION_DATE_ABBR" />ᣠለመጨረሻ ጊዜ ጥቅሠላይ የዋለዠበ<ph name="LAST_USED_DATE_NO_DETAIL" /> ላይ</translation>
<translation id="6563469144985748109">የእርስዎ አስተዳዳሪ ገና አላጸደá‰á‰µáˆ</translation>
<translation id="6569060085658103619">የቅጥያ ገጽ እየተመለከቱ áŠá‹</translation>
-<translation id="6593753688552673085">ከ<ph name="UPPER_ESTIMATE" /> በታች</translation>
+<translation id="657639383826808334">ይህ ይዘት በእርስዎ መሣሪያ ላይ የእርስዎን መረጃ የሚሰርቅ ወይሠየሚሰርዠአደገኛ ሶáትዌርን ለመጫን ሊሞክር ይችሠይሆናáˆá¢ <ph name="BEGIN_LINK" />የሆáŠá‹ ሆኖ አሳይ<ph name="END_LINK" />á¢</translation>
<translation id="6596325263575161958">የáˆáˆµáŒ áˆ« አማራጮች</translation>
<translation id="662080504995468778">ቆይ</translation>
<translation id="6626291197371920147">የሚሰራ የካርድ á‰áŒ¥áˆ­ ያክሉ</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> áለጋ</translation>
+<translation id="6630809736994426279">አáˆáŠ• <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ የሚገኙ አጥቂዎች የእርስዎን መረጃ (ለáˆáˆ³áˆŒá¦ áŽá‰¶á‹Žá‰½á£ የይለá ቃላትᣠመáˆá‹•áŠ­á‰¶á‰½á£ እና ክሬዲት ካርዶች የመሳሰሉ) የሚሰርበወይሠየሚሰርዙ አደገኛ á•áˆ®áŒáˆ«áˆžá‰½áŠ• በእርስዎ Mac ላይ ለመጫን እየሞከሩ ሊሆኑ ይችላሉᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">ይህ መመሪያ ተቋርጧáˆá¢</translation>
-<translation id="6652240803263749613">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ á‹•á‹á‰…ና ማረጋገጫዠበእርስዎ ኮáˆá’á‹á‰°áˆ­ ሥርዓተ ክá‹áŠ“ የታመአአይደለáˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="6671697161687535275">የአስተያየት ጥቆማ ከChromium ይወገድ?</translation>
<translation id="6685834062052613830">ዘáŒá‰°á‹ á‹­á‹áŒ¡ እና ቅንብርን ያጠናቅá‰</translation>
<translation id="6710213216561001401">ቀዳሚ</translation>
<translation id="6710594484020273272">&lt;የáለጋ ቃሠይተይቡ&gt;</translation>
<translation id="6711464428925977395">በተኪ አገáˆáŒ‹á‹© ላይ የሆአችáŒáˆ­ አለ ወይሠአድራሻዠትክክሠአይደለáˆá¢</translation>
<translation id="6727102863431372879">አዘጋጅ</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1 ንጥáˆ}one{# ንጥሎች}other{# ንጥሎች}}</translation>
<translation id="674375294223700098">á‹«áˆá‰³á‹ˆá‰€ የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫ ስህተትá¢</translation>
<translation id="6753269504797312559">የመáˆáˆªá‹« እሴት</translation>
<translation id="6757797048963528358">የእርስዎ መሣሪያ ተáŠá‰·áˆá¢</translation>
@@ -625,6 +691,8 @@ nil</translation>
<translation id="6810899417690483278">የብáŒáŠá‰µ መታወቂያ</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">የክáˆáˆŽá‰½ á‹áˆ‚ብን መጫን አáˆá‰°áˆ³áŠ«áˆ</translation>
+<translation id="6825578344716086703">እርስዎ <ph name="DOMAIN" />ን ለመድረስ ሞክረዋáˆá£ áŠáŒˆáˆ­ áŒáŠ• አገáˆáŒ‹á‹© ደካማ የáŠáˆ­áˆ› ስáˆá‰°-ቀመር (እንደ SHA-1 ያለ) በመጠቀሠየተáˆáˆ¨áˆ˜ የዕá‹á‰…ና ማረጋገጫ áŠá‹ ያቀረበá‹á¢ ይህ ማለት አገáˆáŒ‹á‹© ያቀረበዠየደህንáŠá‰µ áˆáˆµáŠ­áˆ­áŠá‰¶á‰½ የተጭበረበሩ ሊሆኑ ይችላሉᣠእናሠአገáˆáŒ‹á‹© እርስዎ የሚጠብá‰á‰µ አገáˆáŒ‹á‹­ ላይሆን ይችላሠ(ከአጥቂ ጋር እየተገናኙ ሊሆን ይችላáˆ)á¢</translation>
+<translation id="6830728435402077660">ደህንáŠá‰± አáˆá‰°áŒ á‰ á‰€áˆ</translation>
<translation id="6831043979455480757">መተርጎáˆ</translation>
<translation id="6839929833149231406">አካባቢ</translation>
<translation id="6874604403660855544">&amp;አክáˆáŠ• ድገáˆ</translation>
@@ -632,6 +700,7 @@ nil</translation>
<translation id="6895330447102777224">የእርስዎ ካርድ ተረጋáŒáŒ§áˆ</translation>
<translation id="6897140037006041989">የተጠቀሚ ተወካይ</translation>
<translation id="6915804003454593391">ተጠቃሚá¦</translation>
+<translation id="6945221475159498467">á‹­áˆáˆ¨áŒ¡</translation>
<translation id="6948701128805548767">የመá‹áˆ°áŒƒ ዘዴዎችን እና መስáˆáˆ­á‰¶á‰½áŠ• ለመመáˆáŠ¨á‰µ አድራሻ á‹­áˆáˆ¨áŒ¡</translation>
<translation id="6957887021205513506">የአገáˆáŒ‹á‹© እá‹á‰…ና ማረጋገጫ የተጭበረበረ ይመስላáˆá¢</translation>
<translation id="6965382102122355670">እሺ</translation>
@@ -640,15 +709,16 @@ nil</translation>
<translation id="6973656660372572881">áˆáˆˆá‰±áˆ ቋሚ ተኪ አገáˆáŒ‹á‹®á‰½ እና የ.pac ስክሪá•á‰µ ዩአርኤሠተገáˆáŒ¸á‹‹áˆá¢</translation>
<translation id="6989763994942163495">የላበቅንብሮችን አሳይ...</translation>
<translation id="7000990526846637657">áˆáŠ•áˆ የታሪክ áŒá‰¤á‰¶á‰½ አáˆá‰°áŒˆáŠ™áˆ</translation>
-<translation id="7009986207543992532">ወደ <ph name="DOMAIN" /> ለመድረስ ሞክረዋáˆá£ áŠáŒˆáˆ­ áŒáŠ• አገáˆáŒ‹á‹© የሚሠራበት ክáለ ጊዜ የታመአእንዳይሆን ከáˆáŠ­ በላይ ረዥሠጊዜ የሆአየዕá‹á‰…ና ማረጋገጫን አቅርቧáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">የእርስዎ Google መለያ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> ላይ ሌሎች የአሰሳ ታሪክ á‹“á‹­áŠá‰¶á‰½ ሊኖረዠይችላáˆ</translation>
<translation id="7029809446516969842">የይለá ቃላት</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" /> ጋር ለመድረስ ሞክረዋáˆá£ áŠáŒˆáˆ­ áŒáŠ• አገáˆáŒ‹á‹© አስተማማአለመሆን የሚያስቸáŒáˆ­ በጣሠረጅሠየሆአየማረጋገጫ ጊዜ áŠá‹ ያለá‹á¢</translation>
+<translation id="7053983685419859001">አáŒá‹µ</translation>
<translation id="7064851114919012435">የእá‹á‰‚á‹« መረጃ</translation>
<translation id="7079718277001814089">ይህ ጣቢያ ተንኮáˆ-አዘሠዌር á‹­á‹Ÿáˆ</translation>
<translation id="7087282848513945231">አá‹áˆ«áŒƒ</translation>
-<translation id="7088615885725309056">የቆየ</translation>
<translation id="7090678807593890770"><ph name="LINK" />ን በGoogle ላይ á‹­áˆáˆáŒ‰</translation>
+<translation id="7108819624672055576">በቅጥያ የተáˆá‰€á‹°</translation>
<translation id="7119414471315195487">ሌሎች ትሮችን ወይሠá•áˆ®áŒáˆ«áˆžá‰½áŠ• á‹­á‹áŒ‰</translation>
<translation id="7129409597930077180">ወደዚህ አድራሻ መላክ አይቻáˆáˆá¢ የተለየ አድራሻ á‹­áˆáˆ¨áŒ¡á¢</translation>
<translation id="7138472120740807366">የማድረሻ ስáˆá‰µ</translation>
@@ -666,22 +736,18 @@ nil</translation>
<translation id="7220786058474068424">በማስሄድ ላይ</translation>
<translation id="724691107663265825">áŠá‰µ ያለዠጣቢያ ተንኮáˆ-አዘሠዌር አለá‹</translation>
<translation id="724975217298816891">የካርድ á‹áˆ­á‹áˆ®á‰½á‹ŽáŠ• ለማዘመን የ<ph name="CREDIT_CARD" /> ጊዜ ማለáŠá‹« ቀን እና ሲቪሲ ያስገቡᢠአንዴ ካረጋገጡ በኋላ የካርድ á‹áˆ­á‹áˆ®á‰½á‹Ž ለዚህ ጣቢያ ይጋራሉá¢</translation>
-<translation id="725866823122871198">የእርስዎ የኮáˆá’ዩተር ቀን እና ሰዓት (<ph name="DATE_AND_TIME" />) áˆáŠ­ ስላáˆáˆ†áŠ‘ የáŒáˆ áŒáŠ•áŠ™áŠá‰µ ወደ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ሊመሰረት አይችáˆáˆá¢</translation>
+<translation id="7260504762447901703">መዳረሻን ሻር</translation>
<translation id="7275334191706090484">የተዳደሩ እáˆá‰£á‰¶á‰½</translation>
<translation id="7298195798382681320">የተመከሩ</translation>
<translation id="7309308571273880165">በ<ph name="CRASH_TIME" /> ላይ የተáŠáˆ³ የብáˆáˆ½á‰µ ሪá–ርት (ሰቀላ በተጠቃሚ ተጠይቆ áŠá‰ áˆ­á£ ሆኖሠáŒáŠ• እስካáˆáŠ• አáˆá‰°áˆ°á‰€áˆˆáˆ)</translation>
<translation id="7334320624316649418">&amp;ማስተካከáˆáŠ• ድገáˆ</translation>
<translation id="733923710415886693">የአገáˆáŒ‹á‹© የእá‹á‰…ና ማረጋገጫ በእá‹á‰…ና ማረጋገጫ áŒáˆáŒ½áŠá‰µ በኩሠአáˆá‰°áŒˆáˆˆáŒ¸áˆá¢</translation>
-<translation id="7351800657706554155">ይህ የእá‹á‰…ና ማረጋገጫ ስለተሻረ <ph name="SITE" />ን መጎብኘት አይችሉáˆá¢ የአá‹á‰³áˆ¨ መረብ ስህተቶች እና ጥቃቶች አብዛኛዠጊዜ ጊዜያዊ ብቻ ናቸá‹á£ ስለዚህ ይህ ገጽ በኋላ ላይ ሊሠራ ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">የትእዛዠመስመር</translation>
<translation id="7372973238305370288">የáለጋ á‹áŒ¤á‰µ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">አይ</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">ካርድ ያረጋáŒáŒ¡</translation>
-<translation id="7394102162464064926">እርáŒáŒ áŠ› áŠá‹Žá‰µ እáŠá‹šáˆ…ን ገጾች ከታሪክዎ መሰረዠይáˆáˆáŒ‹áˆ‰?
-
-አንዴ ያዳáˆáŒ¡áŠ•áˆ›! ማንáŠá‰µáŠ• የማያሳá‹á‰… áˆáŠá‰³ <ph name="SHORTCUT_KEY" /> ሌላ ጊዜ ላይ ሊጠቅሠይችላáˆá¢</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">የመገለጫ ዱካ</translation>
<translation id="7424977062513257142">በዚህ ድረ-ገጽ ላይ ያለ የተካተተ ገጽ እንዲህ ይላáˆá¦</translation>
@@ -689,6 +755,7 @@ nil</translation>
<translation id="7444046173054089907">ይህ ጣቢያ ታáŒá‹·áˆ</translation>
<translation id="7445762425076701745">የተገናኙት የአገáˆáŒ‹á‹­ ማንáŠá‰µ ሙሉ ለሙሉ ሊረጋገጥ አáˆá‰»áˆˆáˆá¢ ስሙ በአá‹á‰³áˆ¨ መረብዎ á‹áˆµáŒ¥ ብቻ áˆáŠ­ ከሆአአገáˆáŒ‹á‹­ ጋር áŠá‹ የተገናኙትᣠእና ባለቤትáŠá‰± በá‹áŒ«á‹Š የእá‹á‰…ና ማረጋገጫ ሊረጋገጥ አይችáˆáˆá¢ አንዳንድ የእá‹á‰…ና ማረጋገጫ ባለስáˆáŒ£áŠ“ት á‹­áˆáŠ• ብለዠለእáŠá‹šáˆ… ስሞች የእá‹á‰…ና ማረጋገጫዎች መስጠታቸዠየማይቀር እንደመሆኑ መጠንᣠከአጥቂ ሳይሆን ከታሰበዠድር ጣቢያ ጋር መገናኘትዎን የሚረጋገጥበት áˆáŠ•áˆ መንገድ የለáˆá¢</translation>
<translation id="7451311239929941790">ስለዚህ ችáŒáˆ­ <ph name="BEGIN_LINK" />ይበáˆáŒ¥ በመረዳት ላይ<ph name="END_LINK" />á¢</translation>
+<translation id="7455133967321480974">áˆáˆˆáŠ•á‰°áŠ“á‹Š áŠá‰£áˆªá‹áŠ• ተጠቀሠ(አáŒá‹µ)</translation>
<translation id="7460163899615895653">ከሌሎች መሣሪያዎች የመጡ የቅርብ ጊዜ ትሮችዎ እዚህ ይመጣሉ</translation>
<translation id="7469372306589899959">ካርድን በማረጋገጥ ላይ</translation>
<translation id="7481312909269577407">ወደ áŠá‰µ</translation>
@@ -696,36 +763,43 @@ nil</translation>
<translation id="7508255263130623398">የተመላሽ መመሪያ መሣሪያ መታወቂያ ባዶ áŠá‹ ወይሠከአáˆáŠ‘ የመሣሪያ መታወቂያ ጋር አይዛመድáˆ</translation>
<translation id="7514365320538308">አá‹áˆ­á‹µ</translation>
<translation id="7518003948725431193">ለዚህ የድር አድራሻ áˆáŠ•áˆ ድረ-ገጽ አáˆá‰°áŒˆáŠ˜áˆá¦ <ph name="URL" /></translation>
+<translation id="7521387064766892559">ጃቫስክሪá•á‰µ</translation>
<translation id="7535087603100972091">እሴት</translation>
<translation id="7537536606612762813">áŒá‹´á‰³</translation>
+<translation id="7542403920425041731">አንዴ ካረጋገጡ በኋላ የካርድ á‹áˆ­á‹áˆ®á‰½á‹Ž ለዚህ ጣቢያ ይጋራሉá¢</translation>
<translation id="7542995811387359312">ይህ ቅጽ ደህንáŠá‰± የተጠበቀ áŒáŠ•áŠ™áŠá‰µ ስለማይጠቀሠየክሬዲት ካርድ ራስ-መሙላት ተሰናክáˆáˆá¢</translation>
<translation id="7543525346216957623">የእርስዎን ወላጅ ይጠይá‰</translation>
<translation id="7549584377607005141">ይህ ድረ-ገጽ በአáŒá‰£á‰¡ እንዲታይ ቀደሠብለዠያስገቡት á‹áˆ‚ብ ያስáˆáˆáŒˆá‹‹áˆá¢ ይህን á‹áˆ‚ብ እንደገና መላክ ይችላሉᣠáŠáŒˆáˆ­ áŒáŠ• ይህን በማድረáŒá‹Ž ይህ ገጽ ከዚህ በáŠá‰µ ያከናወáŠá‹ ማንኛá‹áˆ እርáˆáŒƒ á‹­á‹°áŒáˆ›áˆ‰á¢</translation>
<translation id="7552846755917812628">የሚከተሉትን ጠቃሚ áˆáŠ­áˆ®á‰½ ይሞክሩá¦</translation>
<translation id="7554791636758816595">አዲስ ትር</translation>
+<translation id="7567204685887185387">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ሊያረጋáŒáŒ¥ አáˆá‰»áˆˆáˆá¤ የደህንáŠá‰µ እá‹á‰…ና ማረጋገጫዠበተጭበረበረ áˆáŠ”ታ ተሰጥቶ ሊሆን ይችላáˆá¢ ይሄ በተሳሳተ አወቃቀር ወይሠአንድ አጥቂ áŒáŠ•áŠ™áŠá‰µá‹ŽáŠ• በመጥለበየተከሰተ ሊሆን ይችላáˆá¢</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ተጨማሪ}one{<ph name="CONTACT_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ተጨማሪ}other{<ph name="CONTACT_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ተጨማሪ}}</translation>
<translation id="7568593326407688803">ይህ ገጽ በ<ph name="ORIGINAL_LANGUAGE" />áŠá‹á¢ መተርጎሠይáˆáˆáŒ‹áˆ‰?</translation>
<translation id="7569952961197462199">ክሬዲት ካርድ ከChrome ይወገድ?</translation>
<translation id="7569983096843329377">ጥá‰áˆ­</translation>
<translation id="7578104083680115302">Google ላይ ያስቀመጧቸá‹áŠ• ካርዶች በመጠቀሠበáˆáˆ‰áˆ መሣሪያዎች ላይ በጣቢያዎችና መተáŒá‰ áˆªá‹«á‹Žá‰½ ላይ በáጥáŠá‰µ ይክáˆáˆ‰á¢</translation>
<translation id="7588950540487816470">አካላዊ ድር</translation>
<translation id="7592362899630581445">የአገáˆáŒ‹á‹© እá‹á‰…ና ማረጋገጫ አንዳንድ ገደቦችን ይጥሳáˆá¢</translation>
+<translation id="7598391785903975535">ከ<ph name="UPPER_ESTIMATE" /> በታች</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> በአáˆáŠ‘ ጊዜ ይህን ጥያቄ ተቀብሎ ለማስተናገድ አይችáˆáˆá¢</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" />ን በጭራሽ አትተርጉáˆ</translation>
<translation id="7610193165460212391">እሴት ከክáˆáˆ <ph name="VALUE" /> á‹áŒª áŠá‹á¢</translation>
<translation id="7613889955535752492">የሚያበቃበት ጊዜᦠ<ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">አስቀድሞ በተለየ የGoogle መለያዎ ይለá ቃሠስሪት የተመሰጠረ á‹áˆ‚ብ አለዎትᢠእባክዎ ከታች ያስገቡትá¢</translation>
-<translation id="7634554953375732414">ወደዚህ ጣቢያ á‹«áˆá‹Žá‰µ áŒáŠ•áŠ™áŠá‰µ የáŒáˆá‹Ž አይደለáˆá¢</translation>
<translation id="7637571805876720304">ክሬዲት ካርድ ከChromium ይወገድ?</translation>
<translation id="765676359832457558">የላበቅንብሮችን ደብቅ...</translation>
<translation id="7658239707568436148">ይቅር</translation>
+<translation id="7662298039739062396">ቅንብር በቅጥያ á‰áŒ¥áŒ¥áˆ­ ይደረáŒá‰ á‰³áˆ</translation>
<translation id="7667346355482952095">የተመለሰዠየመመሪያ ማስመሰያ ባዶ áŠá‹ ወይሠከአáˆáŠ‘ ማስመሰያ ጋር አይዛመድáˆ</translation>
<translation id="7668654391829183341">á‹«áˆá‰³á‹ˆá‰€ መሣሪያ</translation>
<translation id="7669271284792375604">በዚህ ጣቢያ ላይ ያሉ አጥቂዎች እርስዎ የአሰሳ ተሞክሮዎን ሊጎዱ (ለáˆáˆ³áˆŒá¦ መáŠáˆ» ገጽዎን በመቀየር ወይሠበሚጎበኟቸዠጣቢያዎች ላይ ተጨማሪ ማስታወቂያዎችን በማሳየት) የሚችሉ á•áˆ®áŒáˆ«áˆžá‰½áŠ• እንዲጭኑ ለማታለሠሊሞክሩ ይችላሉá¢</translation>
<translation id="7674629440242451245">አዲስ የሆኑ አሪá የChrome ባህሪያትን á‹­áˆáˆáŒ‹áˆ‰? በ chrome.com/dev ላይ ያለá‹áŠ• የdev ሰርጣችንን ይሞክሩትá¢</translation>
<translation id="7682287625158474539">ዕቃን የማጓጓዠስራ</translation>
+<translation id="7701040980221191251">áˆáŠ•áˆ</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />ወደ <ph name="SITE" /> ቀጥሠ(ደህንáŠá‰± á‹«áˆá‰°áŒ á‰ á‰€)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">ሰርቲáŠáŠ¬á‰µ</translation>
+<translation id="7716147886133743102">በእርስዎ አስተዳዳሪ ታáŒá‹·áˆ</translation>
<translation id="7716424297397655342">ይህ ጣቢያ ከመሸጎጫዠላይ ሊጫን አይችáˆáˆ</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">አይቀናበርáˆ</translation>
<translation id="7755287808199759310">የእርስዎ ወላጅ እገዳá‹áŠ• ሊያáŠáˆ±áˆá‹Ž ይችላሉ</translation>
<translation id="7758069387465995638">የኬላ ወይሠየá€áˆ¨-ቫይረስ ሶáትዌር áŒáŠ•áŠ™áŠá‰±áŠ• አáŒá‹¶á‰µ ሊሆን ይችላáˆá¢</translation>
@@ -752,15 +826,15 @@ nil</translation>
<translation id="7951415247503192394">(32-ቢት)</translation>
<translation id="7956713633345437162">የተንቀሳቃሽ ስáˆáŠ­ á‹•áˆá‰£á‰¶á‰½</translation>
<translation id="7961015016161918242">በáጹáˆ</translation>
-<translation id="7962083544045318153">የብáˆáˆ½á‰µ መታወቂያ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">áˆáˆáŒŠá‹œ <ph name="ORIGINAL_LANGUAGE" />ን ወደ<ph name="TARGET_LANGUAGE" /> መተርጎáˆ</translation>
<translation id="7995512525968007366">አáˆá‰°áŒ á‰€áˆ°áˆ</translation>
<translation id="800218591365569300">የማህደረ ትá‹áˆµá‰³ ቦታን ለማስለቀቅ ሌሎች ትሮችን ወይሠá•áˆ®áŒáˆ«áˆžá‰½áŠ• ዘáŒá‰°á‹ ይሞክሩá¢</translation>
<translation id="8012647001091218357">በዚህ ጊዜ ላይ ወላጆችህን መድረስ አáˆá‰»áˆáŠ•áˆá¢ እባክህ እንደገና ሞክርá¢</translation>
<translation id="8025119109950072390">በዚህ ጣቢያ ላይ ያሉ አጥቂዎች እርስዎ እንደ ሶáትዌር መጫን ወይሠየáŒáˆ መረጃዎን (ለáˆáˆ³áˆŒá¦ የይለá ቃላትᣠስáˆáŠ­ á‰áŒ¥áˆ®á‰½ ወይሠክሬዲት ካርዶች) አሳáˆáˆá‹ እንዲሰጡ ያሉ አደገኛ áŠáŒˆáˆ­ እንዲያደርጉ ሊያታáˆáˆ‰á‹Žá‰µ ይችላሉá¢</translation>
-<translation id="803030522067524905">Google የጥንቃቄ አሰሳ በ<ph name="SITE" /> ላይ ማስገር እንዳለ ደርሶበታáˆá¢ አስጋሪ ጣቢያዎች እርስዎን ለማታለሠእንደ ሌሎች ድር ጣቢያዎች አስመስለዠይቀርባሉᢠ<ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="8034522405403831421">ይህ ገጽ በ<ph name="SOURCE_LANGUAGE" /> áŠá‹á¢ ወደ <ph name="TARGET_LANGUAGE" /> ይተርጎáˆ?</translation>
+<translation id="8037357227543935929">ጠይቅ (áŠá‰£áˆª)</translation>
<translation id="8041089156583427627">áŒá‰¥áˆ¨ መáˆáˆµ ላክ</translation>
+<translation id="8041940743680923270">áˆáˆˆáŠ•á‰°áŠ“á‹Š áŠá‰£áˆªá‹áŠ• ተጠቀሙ (ጠይቅ)</translation>
<translation id="8088680233425245692">ጽሑá‰áŠ• ማየት አáˆá‰°á‰»áˆˆáˆá¢</translation>
<translation id="8089520772729574115">ከ1 ሜባ á‹«áŠáˆ°</translation>
<translation id="8091372947890762290">ማáŒá‰ áˆ­ በአገáˆáŒ‹á‹© ላይ በመጠባበቅ ላይ áŠá‹</translation>
@@ -769,13 +843,14 @@ nil</translation>
<translation id="8134994873729925007">የ<ph name="HOST_NAME" /> አገáˆáŒ‹á‹­ <ph name="BEGIN_ABBR" />ዲኤንኤስ አድራሻ<ph name="END_ABBR" /> ሊገአአáˆá‰°á‰»áˆˆáˆá¢</translation>
<translation id="8149426793427495338">የእርስዎ ኮáˆá’á‹á‰° ተáŠá‰·áˆá¢</translation>
<translation id="8150722005171944719"><ph name="URL" /> ላይ ያለዠá‹á‹­áˆ የሚáŠá‰ á‰¥ አይደለáˆá¢ ተወáŒá‹¶á£ ተወስዶ ወይሠየá‹á‹­áˆ áቃዶቹ መዳረሻ እየከለከሉ ሊሆኑ ይችላሉá¢</translation>
+<translation id="8184538546369750125">áˆáˆˆáŠ•á‰°áŠ“á‹Š áŠá‰£áˆªá‹áŠ• ተጠቀሠ(áቀድ)</translation>
+<translation id="8191494405820426728">ከባቢያዊ የብáˆáˆ½á‰µ መታወቂያ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;á‹áˆ°á‹µáŠ• ቀáˆá‰¥áˆµ</translation>
<translation id="8201077131113104583">የማይሰራ የURL á‹áˆ›áŠ” ለቅጥያ ከመታወቂያ «<ph name="EXTENSION_ID" />» ጋርá¢</translation>
<translation id="8202097416529803614">የትዕዛዠማጠቃለያ</translation>
<translation id="8218327578424803826">የተመደበ መገኛ አካባቢá¦</translation>
<translation id="8225771182978767009">ይህን ኮáˆá’á‹á‰°áˆ­ ያቀናበረዠሰዠይህን ጣቢያ ለማገድ መርጧáˆá¢</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />ᣠ<ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">በአáˆáŠ‘ ጊዜ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች በእርስዎ ኮáˆá’á‹á‰°áˆ­ ላይ መረጃዎን የሚሰርበወይሠየሚሰርዙ (ለáˆáˆ³áˆŒá¦ áŽá‰¶á‹Žá‰½á£ የይለá ቃላትᣠመáˆá‹•áŠ­á‰¶á‰½ እና ክሬዲት ካርዶች) አደገኛ á•áˆ®áŒáˆ«áˆžá‰½áŠ• ለመጫን ሊሞክሩ ይችላሉá¢á‹¨á‰°á‰€áˆ˜áŒ¡</translation>
<translation id="8241707690549784388">እየáˆáˆˆáŒ‰á‰µ ያሉት ገጽ ያስገቡትን መረጃ ተጥቅሟáˆá¢ ወደዛ ገጽ መመለስ ወስደá‹á‰µ የáŠá‰ áˆ¨á‹áŠ• ርáˆáŒƒ እንዲደገሠሊያደርጠይችላáˆá¢ ለመቀጠሠይáˆáˆáŒ‹áˆ‰?</translation>
<translation id="8249320324621329438">ለመጨረሻ ጊዜ የመጣá‹á¦</translation>
<translation id="8253091569723639551">የማስከáˆá‹« አድራሻ ያስáˆáˆáŒ‹áˆ</translation>
@@ -783,6 +858,7 @@ nil</translation>
<translation id="8289355894181816810">ይሄ áˆáŠ• ማለት እንደሆአእርáŒáŒ áŠ› ካáˆáˆ†áŠ‘ የአá‹á‰³áˆ¨ መረብ አስተዳዳሪዎን á‹«áŒáŠ™á¢</translation>
<translation id="8293206222192510085">እáˆá‰£á‰µ ያክሉ</translation>
<translation id="8294431847097064396">áˆáŠ•áŒ­</translation>
+<translation id="8306404619377842860">የእርስዎ መሣሪያ ቀን እና ሰዓት (<ph name="DATE_AND_TIME" />) ትክክሠስላáˆáˆ†áŠ‘ ከ<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ጋር የáŒáˆ áŒáŠ•áŠ™áŠá‰µ መመሥረት አይቻáˆáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">በአá‹á‰³áˆ¨áˆ˜áˆ¨á‰¥ áŒáŠ•áŠ™áŠá‰µ ችáŒáˆ­ áˆáŠ­áŠ•á‹«á‰µ የትርጉሠስራዠተሰናክáˆáˆá¢</translation>
<translation id="8332188693563227489">የ<ph name="HOST_NAME" /> መዳረሻ ተከáˆáŠ­áˆáˆ</translation>
<translation id="834457929814110454">በእርስዎ ደህንáŠá‰µ ላይ የሚያመጣቸá‹áŠ• ስጋቶች ከተረዱ አደገኛ á•áˆ®áŒáˆ«áˆžá‰¹ ከመወገዳቸዠበáŠá‰µ <ph name="BEGIN_LINK" />ይህን ጣቢያ መጎብኘት<ph name="END_LINK" /> ይችላሉá¢</translation>
@@ -803,11 +879,9 @@ nil</translation>
<translation id="8483780878231876732">ከእርስዎ የGoogle መለያ ካርዶችን ለመጠቀሠወደ Chrome በመለያ á‹­áŒá‰¡</translation>
<translation id="8488350697529856933">የሚመለከተዠለ</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> áˆáˆ‹áˆ½ ለመስጠት ከáˆáŠ­ በላይ ረዥሠጊዜ ወስዷáˆá¢</translation>
-<translation id="852346902619691059">ይህ አገáˆáŒ‹á‹­ <ph name="DOMAIN" /> መሆኑን ማረጋገጥ አáˆá‰»áˆˆáˆá¤ የዕá‹á‰…ና ማረጋገጫዠበእርስዎ መሣሪያ ሥርዓተ ክወና የታመአአይደለáˆá¢ ይህ በተሳሳተ á‹á‰…ረት ወይሠየእርስዎን áŒáŠ•áŠ™áŠá‰µ በሚጠáˆá አጥቂ áˆáŠ­áŠ•á‹«á‰µ የተáˆáŒ áˆ¨ ሊሆን ይችላáˆá¢ <ph name="BEGIN_LEARN_MORE_LINK" />የበለጠ ለመረዳት<ph name="END_LEARN_MORE_LINK" />á¢</translation>
<translation id="8532105204136943229">ጊዜዠየሚያáˆáበት ዓመት</translation>
<translation id="8543181531796978784"><ph name="BEGIN_ERROR_LINK" />የáˆáˆáŒŽ ማáŒáŠ˜á‰µ ችáŒáˆ­áŠ• ሪá–ርት ማድረáŒ<ph name="END_ERROR_LINK" />ᣠወይሠደáŒáˆž በእርስዎ ደህንáŠá‰µ ላይ ሊያስከትሠየሚችለá‹áŠ• አደጋ ከተረዱ <ph name="BEGIN_LINK" />ይህን ደህንáŠá‰± á‹«áˆá‰°áŒ á‰ á‰€ ጣቢያ መጎብኘት<ph name="END_LINK" /> ይችላሉá¢</translation>
<translation id="8553075262323480129">የገጹ ቋንቋ ሊታወቅ ስላáˆá‰»áˆˆ ትርጉሙ አáˆá‰°áˆ³áŠ«áˆá¢</translation>
-<translation id="8559762987265718583">የእርስዎ መሣሪያ ቀን (<ph name="DATE_AND_TIME" />) áˆáŠ­ ስላáˆáˆ†áŠ ወደ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> የáŒáˆ áŒáŠ•áŠ™áŠá‰µ መመስረት አይቻáˆáˆá¢</translation>
<translation id="8571890674111243710">ገጽ ወደ <ph name="LANGUAGE" /> በመተርጎሠላይ...</translation>
<translation id="858637041960032120">ስáˆáŠ­ á‰áŒ¥áˆ­ ያክሉ
</translation>
@@ -822,6 +896,7 @@ nil</translation>
<translation id="8738058698779197622">ደህንáŠá‰± የተጠበቀ áŒáŠ•áŠ™áŠá‰µ ለመመስረትᣠየእርስዎ ሰዓት በትክክሠመቀናበር ያስáˆáˆáŒˆá‹‹áˆá¢ ይህን የሆáŠá‰ á‰µ áˆáŠ­áŠ•á‹«á‰µ የድር ጣቢያዎች ራሳቸá‹áŠ• ለማሳወቅ የሚጠቀሙባቸዠየáˆáˆµáŠ­áˆ­ ወረቀቶች የሚሰሩት ለተወሰኑ ክáለ ጊዜያቶች ብቻ ስለሆአáŠá‹á¢ የእርስዎ መሣሪያ ሰዓት áˆáŠ­ እንዳለመሆኑ መጠን Chromium እáŠá‹šáˆ…ን áˆáˆµáŠ­áˆ­ ወረቀቶች ሊያረጋáŒáŒ£á‰¸á‹ አይችáˆáˆá¢</translation>
<translation id="8740359287975076522">የ<ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;የዲኤንኤስ አድራሻ&lt;/abbr&gt; ሊገአአáˆá‰°á‰»áˆˆáˆá¢ ችáŒáˆ©áŠ• በመመርመር ላይá¢</translation>
<translation id="8759274551635299824">ይህ ካርድ የአገáˆáŒáˆŽá‰µ ጊዜዠአብቅቷáˆ</translation>
+<translation id="8761567432415473239">Google የጥንቃቄ አሰሳ በቅርብ ጊዜ በ<ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ጎጂ á•áˆ®áŒáˆ­áˆ«áˆžá‰½áŠ• አáŒáŠá‰·áˆ<ph name="END_LINK" />á¢</translation>
<translation id="8790007591277257123">&amp;ሰርá‹áŠ• ድገáˆ</translation>
<translation id="8800988563907321413">በአቅራቢያዎ ያሉ የአስተያየት ጥቆማዎች እዚህ ይመጣሉ</translation>
<translation id="8820817407110198400">á‹•áˆá‰£á‰¶á‰½</translation>
@@ -834,29 +909,30 @@ nil</translation>
<translation id="8870413625673593573">በቅርብ ጊዜ የተዘጉ</translation>
<translation id="8874824191258364635">የሚሰራ የካርድ á‰áŒ¥áˆ­ ያስገቡ</translation>
<translation id="8876793034577346603">የአá‹á‰³áˆ¨ መረብ á‹á‰…ር ሊተáŠá‰°áŠ• አáˆá‰»áˆˆáˆá¢</translation>
-<translation id="8877192140621905067">አንዴ ካረጋገጡ በኋላ የካርድ á‹áˆ­á‹áˆ®á‰½á‹Ž ለዚህ ጣቢያ ይጋራሉ</translation>
<translation id="8889402386540077796">ለይ ቀለáˆ</translation>
<translation id="8891727572606052622">áˆáŠ­ á‹«áˆáˆ†áŠ የተኪ áˆáŠá‰³á¢</translation>
<translation id="889901481107108152">ይቅርታᣠይህ ሙከራ ለመሣሪያ ስርዓትዎ አይገáŠáˆá¢</translation>
<translation id="8903921497873541725">አጉላ</translation>
<translation id="8931333241327730545">ይህን ካርድ በእርስዎ የGoogle መለያ ላይ ማስቀመጥ á‹­áˆáˆáŒ‹áˆ‰?</translation>
<translation id="8932102934695377596">የእርስዎ ሰዓት ወደ ኋላ ቀርቷáˆ</translation>
-<translation id="8954894007019320973">(ቀጣይ)</translation>
<translation id="8971063699422889582">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫ ጊዜዠአáˆáŽá‰ á‰³áˆá¢</translation>
<translation id="8986494364107987395">የአጠቃቀሠስታስቲክስ እና የብáˆáˆ½á‰µ ሪá–ርቶች በራስ ሰር ወደ Google ይላኩá¢</translation>
-<translation id="8987927404178983737">ወር</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ቀጥሎ ያለዠጣቢያ ጎጂ á•áˆ®áŒáˆ«áˆ™á‰½ አሉት</translation>
+<translation id="8997023839087525404">አገáˆáŒ‹á‹© የእá‹á‰…ና ማረጋገጫ áŒáˆáŒ½áŠá‰µ መመሪያá‹áŠ• በመጠቀሠበይዠያáˆá‰°áŒˆáˆˆáŒ¸ የእá‹á‰…ና ማረጋገጫን አቅርቧáˆá¢ ይህ ለአንዳንድ የእá‹á‰…ና ማረጋገጫዎች ሊታመኑ የሚችሉ መሆናቸá‹áŠ• ለማረጋገጥ እና ከአጥቂዎች ጥበቃ ለማድረጠእንዲቻሠአስáˆáˆ‹áŒŠ áŠá‹á¢</translation>
<translation id="9001074447101275817">ተኪ <ph name="DOMAIN" /> የተጠቃሚ ስሠእና የይለá ቃሠያስáˆáˆáŒˆá‹‹áˆá¢</translation>
+<translation id="9005998258318286617">የá’ዲኤá ሰáŠá‹µ መጫን አáˆá‰°áˆ³áŠ«áˆá¢</translation>
<translation id="901974403500617787">በመላዠስርዓት ላይ የሚተገበሩ ጥቆማዎች በባለቤቱ ብቻ áŠá‹ ሊዋቀሩ የሚችሉትᦠ<ph name="OWNER_EMAIL" />á¢</translation>
+<translation id="9020200922353704812">የካርድ ማስከáˆá‹« አድራሻ ያስáˆáˆáŒ‹áˆ</translation>
<translation id="9020542370529661692">ይህ ገጽ ወደ <ph name="TARGET_LANGUAGE" /> ተተርጉሟáˆ</translation>
<translation id="9035022520814077154">የደህንáŠá‰µ ጥበቃ ስህተት</translation>
<translation id="9038649477754266430">ገጾችን ይበáˆáŒ¥ በáጥáŠá‰µ ለመጫን የáŒáˆ˜á‰³ አገáˆáŒáˆŽá‰µáŠ• ይጠቀሙ</translation>
<translation id="9039213469156557790">በተጨማሪᣠይህ ገጽ ደህንáŠá‰³á‰¸á‹ á‹«áˆá‰°áŒ á‰ á‰€ ሌሎች ንብረቶችን አካትቷáˆá¢ እáŠá‹šáˆ… ንብረቶች በሽáŒáŒáˆ­ ወቅት በሌሎች ሊታዩ ይችላሉᣠእናሠየገጹን ባህሪ ለመለወጥ በአጥቂዎች ሊቀየሩ ይችላሉá¢</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ላይ ያሉ አጥቂዎች የአሰሳ ተሞክሮዎን የሚጎዱ á•áˆ®áŒáˆ«áˆžá‰½á‹ŽáŠ• እንዲጭኑ እርስዎን ለማታለሠሊሞክሩ ይችላሉ (ለáˆáˆ³áˆŒá¦ የመáŠáˆ» ገጽዎን በመቀየር ወይሠበጎበኟቸዠጣቢያዎች ላይ ተጨማሪ ማስታወቂያዎችን በማሳየት)á¢</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" />ን ለመድረስ ሞክረዠáŠá‰ áˆ­á£ áŒáŠ• አገáˆáŒ‹á‹© áˆáŠ­ á‹«áˆáˆ†áŠ የእá‹á‰…ና ማረጋገጫ áŠá‹ ያሳየá‹á¢</translation>
<translation id="9050666287014529139">የይለá áˆáˆ¨áŒ</translation>
<translation id="9065203028668620118">አርትዕ</translation>
<translation id="9068849894565669697">ቀለሠይáˆáˆ¨áŒ¡</translation>
+<translation id="9069693763241529744">በቅጥያ ታáŒá‹·áˆ</translation>
<translation id="9076283476770535406">ለአዋቂ ብቻ የሚሆን ይዘት ሊኖረዠይችላáˆ</translation>
<translation id="9078964945751709336">ተጨማሪ መረጃ ያስáˆáˆáŒ‹áˆ</translation>
<translation id="9103872766612412690"><ph name="SITE" /> የእርስዎን መረጃ ለመጠበቅ በመደበáŠáŠá‰µ áˆáˆµáŒ áˆ«áŠ• ይጠቀማáˆá¢ Chromium አáˆáŠ• ከ<ph name="SITE" /> ጋር ለመገናኘት ሲሞክር ድር ጣቢያዠያáˆá‰°áˆˆáˆ˜á‹± እና ትክክሠያáˆáˆ†áŠ‘ áˆáˆµáŠ­áˆ­áŠá‰¶á‰½áŠ• መáˆáˆ·áˆá¢ ይህ አንድ አጥቂ <ph name="SITE" />ን አስመስሎ ለመቅረብ ሲሞክር áŠá‹ ወይሠአንድ የWi-Fi መáŒá‰¢á‹« ገጽ áŒáŠ•áŠ™áŠá‰±áŠ• ሲቋረጥ ሊከሰት ይችላáˆá¢ Chromium ማንኛá‹áˆ የá‹áˆ‚ብ áˆá‹á‹áŒ¥ ከመካሄዱ በáŠá‰µ áŒáŠ•áŠ™áŠá‰±áŠ• ስላቋረጠዠአáˆáŠ•áˆ የእርስዎ መረጃ ደህንáŠá‰µ የተጠበቀ áŠá‹á¢</translation>
@@ -865,16 +941,21 @@ nil</translation>
<translation id="9148507642005240123">&amp;አርትዕን ቀáˆá‰¥áˆµ</translation>
<translation id="9154194610265714752">የተዘመáŠ</translation>
<translation id="9157595877708044936">በማዋቀር ላይ…</translation>
+<translation id="9169664750068251925">áˆáˆáŒŠá‹œ በዚህ ጣቢያ ላይ አáŒá‹µ</translation>
<translation id="9170848237812810038">&amp;ቀáˆá‰¥áˆµ</translation>
<translation id="917450738466192189">የአገáˆáŒ‹á‹­ እá‹á‰…ና ማረጋገጫ áˆáŠ­ á‹«áˆáŠ¾áŠ áŠá‹á¢</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ተጨማሪ}one{<ph name="SHIPPING_OPTION_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ተጨማሪ}other{<ph name="SHIPPING_OPTION_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ተጨማሪ}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> የማይጠቀሠá•áˆ®á‰¶áŠ®áˆ ይጠቀማáˆá¢</translation>
<translation id="9205078245616868884">የእርስዎ á‹áˆ‚ብ በእርስዎ የስáˆáˆ¨á‰µ የይለá ቃሠተመስጥሯáˆá¢ ስáˆáˆ¨á‰µáŠ• ለመጀመር ያስገቡትá¢</translation>
<translation id="9207861905230894330">ጽሑá ማከሠአáˆá‰°á‰»áˆˆáˆá¢</translation>
+<translation id="9219103736887031265">áˆáˆµáˆŽá‰½</translation>
<translation id="933612690413056017">áˆáŠ•áˆ የበይáŠáˆ˜áˆ¨á‰¥ áŒáŠ•áŠ™áŠá‰µ የለáˆ</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ቅጽን አጽዳ</translation>
<translation id="939736085109172342">አዲስ ዓቃáŠ</translation>
<translation id="941721044073577244">ይህን ጣቢያ የመጎብኘት áˆá‰ƒá‹µ የሌለዎት ይመስላሉ</translation>
<translation id="969892804517981540">á‹­á‹ áŒáŠ•á‰£á‰³</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{áˆáŠ•áˆ}=1{1 ንጥáˆ}one{# ንጥሎች}other{# ንጥሎች}}</translation>
<translation id="988159990683914416">የገንቢዎች áŒáŠ•á‰£á‰³</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ar.xtb b/chromium/components/strings/components_strings_ar.xtb
index 88c9218ff6e..fc18a7380fd 100644
--- a/chromium/components/strings/components_strings_ar.xtb
+++ b/chromium/components/strings/components_strings_ar.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">تدوير ÙÙŠ اتجاه عقارب الساعة</translation>
<translation id="1038842779957582377">اسم غير معروÙ</translation>
<translation id="1050038467049342496">إغلاق التطبيقات الأخرى</translation>
-<translation id="1053591932240354961">â€Ù„ا يمكنك زيارة <ph name="SITE" /> الآن نظرًا لأن موقع الويب أرسل بيانات اعتماد مختلطة يتعذر على Google Chrome معالجتها. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصÙحة لاحقًا على الأرجح. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">تراجع عن الإ&amp;ضاÙØ©</translation>
<translation id="10614374240317010">لم يتم الحÙظ مطلقًا</translation>
<translation id="106701514854093668">الإشارات المرجعية على سطح المكتب</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">ذاكرة التخزين المؤقت للسياسة بحالة جيدة</translation>
<translation id="113188000913989374"><ph name="SITE" /> يعرض:</translation>
<translation id="1132774398110320017">â€Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª الملء التلقائي ÙÙŠ Chrome...</translation>
+<translation id="1150979032973867961">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان غير موثقة من خلال نظام تشغيل الكمبيوتر. وربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض الاتصال.</translation>
+<translation id="1151972924205500581">كلمة المرور مطلوبة</translation>
<translation id="1152921474424827756">الدخول إلى <ph name="BEGIN_LINK" />النسخة المخزنة مؤقتًا<ph name="END_LINK" /> من <ph name="URL" /></translation>
<translation id="1158211211994409885">أغلق <ph name="HOST_NAME" /> الاتصال على نحو غير متوقع.</translation>
<translation id="1161325031994447685">â€Ø¥Ø¹Ø§Ø¯Ø© الاتصال بـ Wi-Fi</translation>
+<translation id="1165039591588034296">خطأ</translation>
<translation id="1175364870820465910">ط&amp;باعة...</translation>
<translation id="1181037720776840403">إزالة</translation>
<translation id="1184214524891303587">â€<ph name="BEGIN_WHITEPAPER_LINK" />إبلاغ Google تلقائيًا<ph name="END_WHITEPAPER_LINK" /> بتÙاصيل أي مخاطر أمنية محتملة. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">المزيد من هذا الموقع</translation>
<translation id="1206967143813997005">توقيع أوَّلي سيئ</translation>
<translation id="1209206284964581585">إخÙاء الآن</translation>
+<translation id="121201262018556460">لقد حاولت الوصول إلى <ph name="DOMAIN" />ØŒ ولكن الخادم قدّم شهادة تحتوي على Ù…Ùتاح ضعيÙ. ربما قام أحد المهاجمين باختراق المÙتاح الخاص، ولا يكون الخادم هو الخادم الذي تتوقعه (قد تكون على اتصال بأحد المهاجمين).</translation>
<translation id="1219129156119358924">أمان النظام</translation>
<translation id="1227224963052638717">سياسة غير معروÙØ©.</translation>
<translation id="1227633850867390598">إخÙاء القيمة</translation>
<translation id="1228893227497259893">معر٠الكيان خاطئ</translation>
<translation id="1232569758102978740">بلا عنوان</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />، <ph name="TYPE_2" /> (تمت المزامنة)</translation>
<translation id="1263231323834454256">قائمة القراءة</translation>
<translation id="1264126396475825575">تقرير الأعطال الذي تم الحصول عليه ÙÙŠ <ph name="CRASH_TIME" /> (لم يتم تحميله بعد أو تجاهله)</translation>
+<translation id="1281526147609854549">تم الإصدار بواسطة <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">تم حظر المحتوى الخطير</translation>
<translation id="1285320974508926690">عدم ترجمة هذا الموقع مطلقًا</translation>
<translation id="129553762522093515">المغلقة حديثًا</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />جرّب محو ملÙات تعري٠الارتباط<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">قد يظل <ph name="BEGIN_EMPHASIS" />نشاطك مرئيًا<ph name="END_EMPHASIS" /> للجهات التالية:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />مواقع الويب التي تزورها
+ <ph name="LIST_ITEM" />صاحب العمل أو المدرسة
+ <ph name="LIST_ITEM" />مزوّد خدمة الإنترنت
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">نطاق التسجيل:</translation>
<translation id="1340482604681802745">عنوان الاستلام</translation>
<translation id="1344211575059133124">يبدو أنك بحاجة إلى الحصول على إذن لزيارة هذا الموقع</translation>
<translation id="1344588688991793829">â€Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª الملء التلقائي ÙÙŠ Chromium...</translation>
+<translation id="1348198688976932919">يحتوي موقع الويب المقصود على تطبيقات خطيرة</translation>
<translation id="1374468813861204354">اقتراحات</translation>
<translation id="1375198122581997741">معلومات عن الإصدار</translation>
<translation id="1377321085342047638">رقم البطاقة</translation>
<translation id="139305205187523129">لم يرسل <ph name="HOST_NAME" /> أي بيانات.</translation>
<translation id="1407135791313364759">Ùتح الكل</translation>
<translation id="1413809658975081374">خطأ ÙÙŠ الخصوصية</translation>
+<translation id="14171126816530869">تمّ التحقق من هوية <ph name="ORGANIZATION" /> ÙÙŠ <ph name="LOCALITY" /> من Ù‚Ùبل <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">نعم</translation>
<translation id="1430915738399379752">طباعة</translation>
-<translation id="1442912890475371290">تمّ منع محاولة <ph name="BEGIN_LINK" /> الانتقال إلى إحدى الصÙحات على <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">لا يمكنك زيارة <ph name="SITE" /> الآن نظرًا لأن موقع الويب يستخدم أداة التحقق من صحة الشهادات. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصÙحة لاحقًا على الأرجح. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> وطريقة دÙع واحدة (<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />) أخرى}zero{<ph name="PAYMENT_METHOD_PREVIEW" /> Ùˆ<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> طريقة دÙع أخرى}two{<ph name="PAYMENT_METHOD_PREVIEW" /> وطريقتا دÙع (<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />) أخريان}few{<ph name="PAYMENT_METHOD_PREVIEW" /> Ùˆ<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> طرق دÙع أخرى}many{<ph name="PAYMENT_METHOD_PREVIEW" /> Ùˆ<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> طريقة دÙع أخرى}other{<ph name="PAYMENT_METHOD_PREVIEW" /> Ùˆ<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> طريقة دÙع أخرى}}</translation>
<translation id="1506687042165942984">عرض نسخة محÙوظة (أي معرو٠أنها منتهية) من هذه الصÙحة.</translation>
<translation id="1517433312004943670">رقم الهات٠مطلوب</translation>
<translation id="1519264250979466059">تاريخ الإصدار</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">â€ÙŠØ¬Ø¨ تمكين JavaScript لاستخدام هذه الميزة.</translation>
<translation id="1555130319947370107">أزرق</translation>
<translation id="1559528461873125649">لا وجود لمثل هذا المل٠أو الدليل</translation>
-<translation id="1559572115229829303">â€&lt;p&gt;تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن تاريخ ووقت جهازك (<ph name="DATE_AND_TIME" />) غير صحيحين.&lt;/p&gt;
-
- &lt;p&gt;ÙŠÙرجى تعديل التاريخ والوقت من القسم &lt;strong&gt;عام&lt;/strong&gt; ÙÙŠ تطبيق &lt;strong&gt;الإعدادات&lt;/strong&gt; .&lt;/p&gt;</translation>
<translation id="1583429793053364125">حدث خطأ ÙÙŠ شيء ما أثناء عرض صÙحة الويب هذه.</translation>
<translation id="1592005682883173041">الوصول إلى البيانات المحلية</translation>
+<translation id="1594030484168838125">اختيار</translation>
<translation id="161042844686301425">سماوي</translation>
+<translation id="1620510694547887537">الكاميرا</translation>
<translation id="1629803312968146339">â€Ù‡Ù„ تريد من Chrome Ø­Ùظ هذه البطاقة؟</translation>
<translation id="1639239467298939599">جار٠التحميل.</translation>
<translation id="1640180200866533862">سياسات المستخدم</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">تهيئة الشبكة غير صالحة ويتعذر استيرادها.</translation>
<translation id="1644574205037202324">السجل</translation>
<translation id="1645368109819982629">بروتوكول غير معتمد</translation>
+<translation id="1655462015569774233">{1,plural, =1{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه أمس. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصÙحة.}zero{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # يوم. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصÙحة.}two{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ يومين (#). ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصÙحة.}few{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # أيام. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصÙحة.}many{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # يومًا. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصÙحة.}other{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # يوم. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك ثم تحديث هذه الصÙحة.}}</translation>
<translation id="1656489000284462475">الاستلام</translation>
<translation id="1663943134801823270">â€ØªØ£ØªÙŠ البطاقات والعناوين من Chrome. ويمكنك إدارتها ÙÙŠ <ph name="BEGIN_LINK" />الإعدادات<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">â€ÙŠØ³ØªØ®Ø¯Ù… <ph name="SITE" /> التشÙير عادة لحماية معلوماتك. عندما حاول Google Chrome الاتصال بموقع <ph name="SITE" /> هذه المرة، أرجَع موقع الويب بيانات اعتماد غير عادية وغير صحيحة. وقد يحدث هذا عندما يحاول أحد المهاجمين التظاهر بأنه موقع <ph name="SITE" />ØŒ أو إذا قاطعت شاشة تسجيل دخول Wi-Fi الاتصال. ولكن لا تزال معلوماتك آمنة نظرًا لأن Google Chrome أوقَ٠الاتصال قبل تبادل أي بيانات.</translation>
-<translation id="168328519870909584">قد يحاول المهاجمون الموجودون حاليًا على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> تثبيت تطبيقات خطيرة على جهازك والتي تسرق معلوماتك أو تحذÙها (على سبيل المثال، الصور وكلمات المرور والرسائل وبطاقات الائتمان).</translation>
<translation id="168841957122794586">تحتوي شهادة الخادم على Ù…Ùتاح تشÙير ضعيÙ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه من الغد. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك.}zero{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # يوم ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك.}two{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال يومين (#) ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك.}few{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # أيام ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك.}many{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # يومًا ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك.}other{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # يوم ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك.}}</translation>
<translation id="1710259589646384581">نظام التشغيل</translation>
<translation id="1721312023322545264">أنت بحاجة لإذن من <ph name="NAME" /> لزيارة هذا الموقع</translation>
<translation id="1721424275792716183">* هناك حقل مطلوب</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">تنزيل الصÙحة لاحقًا</translation>
<translation id="17513872634828108">علامات التبويب المÙتوحة</translation>
<translation id="1753706481035618306">رقم الصÙحة</translation>
+<translation id="1763864636252898013">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان غير موثوقة من خلال نظام تشغيل جهازك. وربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض الاتصال.</translation>
<translation id="1768211456781949159">â€<ph name="BEGIN_LINK" />تجربة تشغيل بيانات التشخيص لشبكة Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">الرجاء تحديث عبارة مرور المزامنة.</translation>
<translation id="1787142507584202372">تظهر علامات التبويب المÙتوحة هنا</translation>
+<translation id="1789575671122666129">النواÙØ° المنبثقة</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">اسم حامل البطاقة</translation>
-<translation id="1803678881841855883">â€Ø§ÙƒØªØ´Ù التصÙØ­ الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />برامج ضارة<ph name="END_LINK" /> على <ph name="SITE" />. أحيانًا تÙصاب مواقع الويب الآمنة ÙÙŠ الوضع العادي ببرامج ضارة. ويÙعد مصدر محتوى البرامج الضارة هو <ph name="SUBRESOURCE_HOST" />ØŒ وهو موزع معرو٠للبرامج الضارة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">تمت الإضاÙØ© ÙÙŠ <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">طلب غير صالح، أو معلمات طلب غير صالحة</translation>
<translation id="1826516787628120939">حساب شيكات</translation>
<translation id="1834321415901700177">يحتوي هذا الموقع على برامج ضارة</translation>
+<translation id="1840414022444569775">رقم البطاقة هذا مستخدم من قبل</translation>
<translation id="1842969606798536927">الدÙع</translation>
<translation id="1871208020102129563">â€ØªÙ… تعيين الخادم الوكيل لاستخدام الخوادم الوكيلة الثابتة وليس عنوان URL لنص برمجي pac.</translation>
<translation id="1871284979644508959">حقل مطلوب</translation>
<translation id="187918866476621466">Ùتح صÙحات بدء التشغيل</translation>
<translation id="1883255238294161206">تصغير القائمة</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> وعنوان واحد (<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />) آخر}zero{<ph name="SHIPPING_ADDRESS_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عنوان آخر}two{<ph name="SHIPPING_ADDRESS_PREVIEW" /> وعنوانان (<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />) آخران}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عناوين أخرى}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عنوانًا آخرًا}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> عنوان آخر}}</translation>
<translation id="1898423065542865115">التصÙية</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{بدون}=1{موقع واحد}two{ موقعان (#)}few{# مواقع}many{# موقعًا}other{# موقع}}</translation>
<translation id="194030505837763158">الانتقال إلى <ph name="LINK" /></translation>
<translation id="1962204205936693436">إشارات <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">خطأ أثناء التسلسل</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">تم تجاهلها نظرًا لتجاوزها بواسطة <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">جار٠البحث عن صÙحات الشبكة المادية المجاورة</translation>
<translation id="213826338245044447">الإشارات المرجعية على الجوال</translation>
-<translation id="2148716181193084225">اليوم</translation>
+<translation id="2147827593068025794">مزامنة الخلÙية</translation>
<translation id="2154054054215849342">المزامنة غير متاحة لنطاقك</translation>
<translation id="2154484045852737596">تعديل البطاقة</translation>
<translation id="2166049586286450108">الوصول الكامل للمشرÙ</translation>
<translation id="2166378884831602661">لا يمكن لموقع الويب هذا توÙير اتصال آمن</translation>
<translation id="2181821976797666341">السياسات</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{عنوان واحد}zero{# عنوان}two{عنوانان (#)}few{# عناوين}many{# عنوانًا}other{# عنوان}}</translation>
+<translation id="2187317261103489799">اكتشا٠(اÙتراضي)</translation>
<translation id="2202020181578195191">أدخÙÙ„ سنة تاريخ انتهاء صلاحية صحيحة</translation>
<translation id="2212735316055980242">تعذر العثور على السياسة</translation>
<translation id="2213606439339815911">جار٠جلب الإدخالات...</translation>
+<translation id="2218879909401188352">يمكن حاليًا للمهاجمين على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> تثبيت تطبيقات خطيرة تدمر الجهاز أو تضي٠رسومًا إلى Ùاتورة الجوّال أو تسرق المعلومات الشخصية. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">إصلاح الاتصال باستخدام <ph name="BEGIN_LINK" />تطبيق بيانات التشخيص<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">إرسال الآن</translation>
<translation id="225207911366869382">تم تجاهل القيمة لهذه السياسة.</translation>
<translation id="2262243747453050782">â€Ø®Ø·Ø£ HTTP</translation>
+<translation id="2270484714375784793">رقم الهاتÙ</translation>
<translation id="2282872951544483773">التجارب غير المتاحة</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{عنصر واحد (<ph name="ITEM_COUNT" />)}zero{<ph name="ITEM_COUNT" /> عنصر}two{عنصران (<ph name="ITEM_COUNT" />)}few{<ph name="ITEM_COUNT" /> عناصر}many{<ph name="ITEM_COUNT" /> عنصرًا}other{<ph name="ITEM_COUNT" /> عنصر}}</translation>
<translation id="2292556288342944218">تم حظر دخولك إلى الإنترنت</translation>
<translation id="230155334948463882">بطاقة جديدة؟</translation>
-<translation id="2305919008529760154">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› قد يكون تم إصدار شهادة أمانه عن طريق الاحتيال. وربما يكون سبب ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">يتطلَّب <ph name="DOMAIN" /> اسم مستخدم وكلمة مرور.</translation>
-<translation id="2318774815570432836">â€Ù„ا يمكنك زيارة <ph name="SITE" /> الآن نظرًا لأن موقع الويب يستخدم HSTS. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصÙحة لاحقًا على الأرجح. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">يتم التحكّم ÙÙŠ الإعداد من قبل المشرÙ</translation>
<translation id="2354001756790975382">الإشارات الأخرى</translation>
+<translation id="2354430244986887761">â€Ø¹Ø«Ø± â€â€«Ø§Ù„تصÙØ­ الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />على تطبيقات ضارة<ph name="END_LINK" /> ÙÙŠ <ph name="SITE" />.</translation>
<translation id="2355395290879513365">قد يتمكن المهاجمون من رؤية الصور التي تتطلع عليها على هذا الموقع وخداعك من خلال تعديلها.</translation>
+<translation id="2356070529366658676">طلب</translation>
+<translation id="2359629602545592467">متعددة</translation>
<translation id="2359808026110333948">المتابعة</translation>
<translation id="2365563543831475020">لم يتم تحميل تقرير الأعطال الذي تم الحصول عليه ÙÙŠ <ph name="CRASH_TIME" /></translation>
<translation id="2367567093518048410">المستوى</translation>
-<translation id="2371153335857947666">{1,plural, =1{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه أمس. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك Ø«ÙÙ… تحديث هذه الصÙحة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}zero{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # يوم. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك Ø«ÙÙ… تحديث هذه الصÙحة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}two{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ يومين (#). ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك Ø«ÙÙ… تحديث هذه الصÙحة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}few{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # أيام. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك Ø«ÙÙ… تحديث هذه الصÙحة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}many{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # يومًا. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك Ø«ÙÙ… تحديث هذه الصÙحة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}other{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› انتهت صلاحية شهادة أمانه منذ # يوم. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. تم تعيين ساعة الكمبيوتر لديك حاليًا على <ph name="CURRENT_DATE" />. هل يبدو ذلك صحيحًا؟ إذا لم يكن الأمر كذلك، يجب تصحيح ساعة النظام لديك Ø«ÙÙ… تحديث هذه الصÙحة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">لا توجد بدائل لعناصر واجهة المستخدم</translation>
<translation id="2384307209577226199">السياسة اÙتراضية ÙÙŠ المؤسسة ويمكن إلغاؤها</translation>
<translation id="2386255080630008482">تم إبطال شهادة الخادم.</translation>
<translation id="2392959068659972793">عرض السياسات التي لم يتم تعيين قيم لها</translation>
<translation id="239429038616798445">طريقة الشحن هذه غير متاحة، جرّÙب طريقة أخرى.</translation>
<translation id="2396249848217231973">تراجع عن الحذ&amp;Ù</translation>
-<translation id="2460160116472764928">â€Ø§ÙƒØªØ´Ù التصÙØ­ الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />برامج ضارة<ph name="END_LINK" /> على <ph name="SITE" />. أحيانًا تÙصاب مواقع الويب الآمنة ÙÙŠ الوضع العادي ببرامج ضارة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان ربما تم إلغاء صلاحيتها. وربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض اتصالك.</translation>
<translation id="2463739503403862330">ملء</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />تشغيل بيانات تشخيص الشبكة<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">â€Ø¹Ù†ÙˆØ§Ù† URL للبحث غير صالح.</translation>
+<translation id="2482878487686419369">الاشعارات</translation>
<translation id="2491120439723279231">تحتوي شهادة الخادم على أخطاء.</translation>
<translation id="2495083838625180221">â€Ù…حلل JSON اللغوي</translation>
<translation id="2495093607237746763">â€Ø¹Ù†Ø¯ وضع علامة على هذا الخيار، سيخزّن Chromium نسخة من بطاقتك على هذا الجهاز لتعبئة النماذج بشكل أسرع.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">الرجوع للخلÙ</translation>
<translation id="2515629240566999685">التحقق من الإشارة ÙÙŠ منطقتك</translation>
<translation id="2516305470678292029">بدائل عناصر واجهة المستخدم</translation>
+<translation id="2539524384386349900">اكتشاÙ</translation>
<translation id="255002559098805027">أرسل <ph name="HOST_NAME" /> استجابة غير صالحة.</translation>
-<translation id="2552545117464357659">أحدث</translation>
<translation id="2556876185419854533">تراجع عن ا&amp;لتحرير</translation>
<translation id="2587730715158995865">من <ph name="ARTICLE_PUBLISHER" />. يمكنك قراءة هذه المقالة و<ph name="OTHER_ARTICLE_COUNT" /> قصص أخرى.</translation>
<translation id="2587841377698384444">رقم تعري٠واجهة برمجة التطبيقات الدليل:</translation>
<translation id="2597378329261239068">هذا المستند محمي بكلمة المرور. الرجاء إدخال كلمة مرور.</translation>
<translation id="2609632851001447353">الاختلاÙات</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{بدون}=1{تطبيق واحد ($1)}=2{تطبيقان (2) ($1، $2)}few{# تطبيقات ($1، $2، $3)}many{# تطبيقًا ($1، $2، $3)}other{# تطبيق ($1، $2، $3)}}</translation>
<translation id="2625385379895617796">توقيت ساعتك متقدم عن الوقت الحالي</translation>
<translation id="2639739919103226564">الحالة:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">تم رÙض الدخول إلى الملÙ</translation>
<translation id="2653659639078652383">إرسال</translation>
<translation id="2666117266261740852">إغلاق علامات التبويب والتطبيقات الأخرى</translation>
+<translation id="2670429602441959756">â€ØªØ­ØªÙˆÙŠ هذه الصÙحة على ميزات لم يتم دعمها بعد ÙÙŠ الواقع الاÙتراضي (VR). جار٠الخروج...</translation>
<translation id="2674170444375937751">هل تريد Ùعلًا حذ٠هذه الصÙحات من السجل؟</translation>
<translation id="2677748264148917807">الخروج</translation>
-<translation id="269990154133806163">قدم الخادم شهادة لم يتم الكش٠عنها علنًا باستخدام سياسة شهادة الشÙاÙية. وهذا ضروري لبعض الشهادات، لضمان أنها جديرة بالثقة ومحمية من المهاجمين. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">قائمة القراءة</translation>
<translation id="2704283930420550640">القيمة لا تطابق التنسيق.</translation>
<translation id="2704951214193499422">â€Ù„Ù… يتمكن Chromium من التأكد من بطاقتك ÙÙŠ الوقت الحالي. ÙŠÙرجى إعادة المحاولة ÙÙŠ وقت لاحق.</translation>
<translation id="2705137772291741111">تعذر قراءة النسخة المحÙوظة (المخزنة ÙÙŠ ذاكرة التخزين المؤقت) لموقع الويب هذا.</translation>
<translation id="2709516037105925701">الملء التلقائي</translation>
-<translation id="2712118517637785082">لقد حاولت الوصول إلى <ph name="DOMAIN" />ØŒ ولكن جهة إصدار الشهادة التي قدمها الخادم قد أبطلت الشهادة. وهذا يعني أن بيانات اعتماد الأمان التي قدمها الخادم يجب عدم الوثوق بها مطلقًا. Ùقد تكون على اتصال بأحد المهاجمين. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">طلب إذن</translation>
<translation id="2713444072780614174">أبيض</translation>
<translation id="2720342946869265578">المجاورة</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">سجÙلّ الجهاز Ù…Ùقود</translation>
<translation id="2784949926578158345">تمت إعادة تعيين الاتصال.</translation>
<translation id="2794233252405721443">تم حظر الموقع</translation>
+<translation id="2799020568854403057">يحتوي موقع الويب المقصود على تطبيقات ضارة</translation>
+<translation id="2803306138276472711">â€Ø§ÙƒØªØ´Ù التصÙØ­ الآمن من Google مؤخرًا <ph name="BEGIN_LINK" />برامج ضارة<ph name="END_LINK" /> على <ph name="SITE" />. أحيانًا تصاب مواقع الويب الآمنة ÙÙŠ الوضع العادي ببرامج ضارة.</translation>
<translation id="2824775600643448204">شريط العناوين والبحث</translation>
<translation id="2826760142808435982">تم تشÙير الاتصال ومصادقته باستخدام <ph name="CIPHER" />ØŒ ويستخدم <ph name="KX" /> كآلية التبادل الرئيسية.</translation>
<translation id="2835170189407361413">محو النموذج</translation>
+<translation id="2856444702002559011">قد يحاول المهاجمون سرقة معلوماتك من <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (على سبيل المثال، كلمات المرور، أو الرسائل، أو بطاقات الائتمان). <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">إلغاء إعادة التحميل</translation>
<translation id="2900469785430194048">â€Ù†Ùدت ذاكرة Google Chrome أثناء محاولة عرض صÙحة الويب هذه.</translation>
<translation id="2909946352844186028">تم اكتشا٠حدوث تغيير ÙÙŠ الشبكة.</translation>
<translation id="2916038427272391327">إغلاق البرامج الأخرى</translation>
<translation id="2922350208395188000">لا يمكن التحقق من شهادة الخادم.</translation>
<translation id="2928905813689894207">عنوان إرسال الÙواتير</translation>
+<translation id="2941952326391522266">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان من <ph name="DOMAIN2" />. وربما سبب ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض اتصالك.</translation>
<translation id="2948083400971632585">يمكنك تعطيل أي خوادم وكيلة تمت تهيئتها لاتصال من صÙحة الإعدادات.</translation>
<translation id="2955913368246107853">إغلاق شريط البحث</translation>
<translation id="2958431318199492670">â€Ù„ا تتواÙÙ‚ تهيئة الشبكة مع معيار ONC. قد لا يتم استيراد بعض أجزاء التهيئة.</translation>
-<translation id="29611076221683977">â€Ù‚د يحاول المستهدÙون الموجودون حاليًا على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> تثبيت برامج خطيرة على Mac التابع لك تسرق معلوماتك أو تحذÙها (على سبيل المثال، الصور وكلمات المرور والرسائل وبطاقات الائتمان).</translation>
<translation id="2966678944701946121">تاريخ انتهاء الصلاحية: <ph name="EXPIRATION_DATE_ABBR" />ØŒ وتمت الإضاÙØ© ÙÙŠ <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">â€Ù„إنشاء اتصال آمن، Ùإنك بحاجة إلى ضبط ساعتك بشكل صحيح. وذلك لأن الشهادات التي تستخدمها مواقع الويب لتعري٠نÙسها تكون صالحة Ùقط Ù„Ùترات محددة من الوقت. Ùإذا كانت ساعة جهازك غير صحيحة، Ùلن يتمكن Google Chrome من التحقق من هذه الشهادات.</translation>
<translation id="2972581237482394796">إعا&amp;دة</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">أدخÙÙ„ عنوانًا صحيحًا</translation>
<translation id="2986368408720340940">طريقة الاستلام هذه غير متاحة. جرّÙب طريقة أخرى.</translation>
<translation id="2991174974383378012">المشاركة مع مواقع الويب</translation>
+<translation id="2991571918955627853">â€Ù„ا يمكنك زيارة <ph name="SITE" /> ÙÙŠ الوقت الحالي لأن موقع الويب يستخدم HSTS. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصÙحة ÙÙŠ وقت لاحق على الأرجح.</translation>
<translation id="3005723025932146533">عرض نسخة محÙوظة</translation>
<translation id="3008447029300691911">â€Ø£Ø¯Ø®Ù„ رمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" />. بعد تأكيدك، ستتم مشاركة تÙاصيل بطاقتك مع هذا الموقع.</translation>
<translation id="3010559122411665027">إدخال القائمة "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">تم الحظر تلقائيًا</translation>
<translation id="3024663005179499861">نوع السياسة غير صحيح</translation>
<translation id="3032412215588512954">هل تريد إعادة تحميل هذا الموقع؟</translation>
<translation id="3037605927509011580">عذرًا!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{عنصر واحد على الأقل على الأجهزة المتزامنة}=1{عنصر واحد (1) (وأكثر على الأجهزة المتزامنة)}two{عنصران (#) (وأكثر على الأجهزة المتزامنة)}few{# عناصر (وأكثر على الأجهزة المتزامنة)}many{# عنصرًا (وأكثر على الأجهزة المتزامنة)}other{# عنصر (وأكثر على الأجهزة المتزامنة)}}</translation>
<translation id="3041612393474885105">معلومات الشهادة</translation>
<translation id="3063697135517575841">â€Ù„Ù… يتمكن Chrome من التأكد من بطاقتك ÙÙŠ الوقت الحالي. ÙŠÙرجى إعادة المحاولة ÙÙŠ وقت لاحق.</translation>
<translation id="3064966200440839136">ستتم مغادرة وضع التصÙØ­ المتخÙÙŠ للدÙع عبر تطبيق خارجي. هل تريد المتابعة؟</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{بدون}=1{كلمة مرور واحدة}two{كلمتا مرور (#)}few{# كلمات مرور}many{# كلمة مرور}other{# كلمة مرور}}</translation>
<translation id="3093245981617870298">أنت غير متصل.</translation>
<translation id="3105172416063519923">رقم تعري٠الأصل:</translation>
<translation id="3109728660330352905">ليس لديك إذن بعرض هذه الصÙحة.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />تجربة تشغيل بيانات تشخيص الاتصال<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">تعذّر ÙÙƒ تشÙير الاستجابة</translation>
<translation id="3150653042067488994">خطأ مؤقت ÙÙŠ الخادم</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">لن يتم تسجيل الصÙحات التي تعرضها ÙÙŠ علامات تبويب التصÙØ­ المتخÙÙŠ ÙÙŠ سجل المتصÙØ­ أو مخزن ملÙات تعري٠الارتباط أو سجل البحث بعد إغلاق جميع علامات التبويب ÙÙŠ وضع التصÙØ­ المتخÙÙŠ. ولكن سيتم الاحتÙاظ بأي ملÙات تنزلها أو إشارات مرجعية تنشئها.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">جزيرة</translation>
+<translation id="317583078218509884">ستسري إعدادات أذونات الموقع بعد إعادة تحميل الصÙحة.</translation>
<translation id="3176929007561373547">تحقق من إعدادات الخادم الوكيل أو اتصل بمشر٠الشبكة
للتأكد من عمل الخادم الوكيل. Ùإذا كنت لا تعتقد أنه يجب عليك استخدام
خادم وكيل:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Ùتح صÙحة ÙÙŠ وضع التصÙØ­ المتخÙÙŠ</translation>
-<translation id="3202578601642193415">الأحدث</translation>
+<translation id="320323717674993345">إلغاء الدÙع</translation>
<translation id="3207960819495026254">محدد بعلامة متابعة القراءة</translation>
+<translation id="3225919329040284222">قدم الخادم شهادة لا تتطابق مع التوقعات المضمّنة. تم تضمين هذه التوقعات للحصول على مواقع ويب موثوقة وآمنة جدًا لتوÙير الحماية لك.</translation>
<translation id="3226128629678568754">اضغط على زر إعادة التحميل لإعادة إرسال البيانات المطلوبة لتحميل الصÙحة.</translation>
+<translation id="3227137524299004712">الميكروÙون</translation>
<translation id="3228969707346345236">أخÙقت الترجمة لأن الصÙحة باللغة <ph name="LANGUAGE" /> Ùعلاً.</translation>
<translation id="323107829343500871">â€Ø£Ø¯Ø®Ù„ رمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">الكش٠دائمًا عن المحتوى المهم على هذا الموقع</translation>
<translation id="3254409185687681395">وضع إشارة على هذه الصÙحة</translation>
<translation id="3270847123878663523">تراجع عن إعادة الت&amp;رتيب</translation>
<translation id="3282497668470633863">إضاÙØ© الاسم الوارد ÙÙŠ البطاقة</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">الإعدادات</translation>
<translation id="3345135638360864351">تعذر إرسال طلبك للوصول إلى هذا الموقع إلى <ph name="NAME" />. ÙŠÙرجى إعادة المحاولة مرة أخرى.</translation>
<translation id="3355823806454867987">تغيير إعدادات الخادم الوكيل...</translation>
+<translation id="3361596688432910856">â€Ù„Ù† يحÙظ <ph name="BEGIN_EMPHASIS" />Chrome<ph name="END_EMPHASIS" /> المعلومات التالية:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />سجل التصÙّح لديك
+ <ph name="LIST_ITEM" />ملÙات تعري٠الارتباط وبيانات الموقع
+ <ph name="LIST_ITEM" />المعلومات التي تم إدخالها ÙÙŠ النماذج
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">خطأ ÙÙŠ الساعة</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> من العناصر الأخرى...</translation>
<translation id="337363190475750230">تم إلغاء التوÙير</translation>
<translation id="3377188786107721145">خطأ ÙÙŠ تحليل السياسة</translation>
<translation id="3380365263193509176">خطأ غير معروÙ</translation>
<translation id="3380864720620200369">معرّÙ٠العميل:</translation>
<translation id="3391030046425686457">عنوان التسليم</translation>
<translation id="3395827396354264108">طريقة الاستلام</translation>
-<translation id="340013220407300675">قد يحاول المهاجمون سرقة معلوماتك من <ph name="BEGIN_BOLD" /> <ph name="SITE" /> <ph name="END_BOLD" /> (على سبيل المثال: كلمات المرور أو الرسائل، أو بطاقات الائتمان).</translation>
<translation id="3422248202833853650">جرّب الخروج من البرامج الأخرى لتÙريغ مساحة من الذاكرة.</translation>
<translation id="3422472998109090673">يتعذر الوصول إلى <ph name="HOST_NAME" /> حاليًا.</translation>
+<translation id="3427092606871434483">السماح (اÙتراضي)</translation>
<translation id="3427342743765426898">إعادة الت&amp;حرير</translation>
<translation id="3431636764301398940">Ø­Ùظ هذه البطاقة إلى هذا الجهاز</translation>
<translation id="3435896845095436175">تمكين الإضاÙات</translation>
<translation id="3447661539832366887">عطل مالك هذا الجهاز تشغيل لعبة الديناصور.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">الÙاصل الزمني للجلب:</translation>
<translation id="3462200631372590220">الإخÙاء (خيار متقدم)</translation>
<translation id="3467763166455606212">اسم حامل البطاقة مطلوب</translation>
<translation id="3478058380795961209">شهر انتهاء الصلاحية</translation>
<translation id="3479539252931486093">ألم تتوقَّع هذا؟ <ph name="BEGIN_LINK" />أطلÙعنا على الأمر<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">ليس الآن</translation>
-<translation id="348000606199325318">معرّ٠التعطّÙÙ„ <ph name="CRASH_LOCAL_ID" /> (معرّ٠الخادم: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">لم نتمكن من الوصول إلى أحد والديك ÙÙŠ الوقت الحالي. ÙŠÙرجى إعادة المحاولة مرة أخرى.</translation>
<translation id="3528171143076753409">شهادة الخادم غير موثوق Ùيها.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{عنصر واحد على الأقل على الأجهزة المتزامنة}=1{عنصر واحد (1) (وأكثر على الأجهزة المتزامنة)}two{عنصران (#) (وأكثر على الأجهزة المتزامنة)}few{# عناصر (وأكثر على الأجهزة المتزامنة)}many{# عنصرًا (وأكثر على الأجهزة المتزامنة)}other{# عنصر (وأكثر على الأجهزة المتزامنة)}}</translation>
<translation id="3539171420378717834">الاحتÙاظ بنسخة من هذه البطاقة على هذا الجهاز</translation>
<translation id="3542684924769048008">استخدام كلمة مرور لـ:</translation>
+<translation id="3545341443414427877">تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن تاريخ ووقت الكمبيوتر (<ph name="DATE_AND_TIME" />) غير صحيحين. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">تشÙير جميع البيانات المتزامنة باستخدام عبارة مرور المزامنة</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> أخرى...</translation>
-<translation id="3555561725129903880">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />ØŒ بل إن شهادة أمانه من <ph name="DOMAIN2" />. وربما يكون سبب ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">يمكن لمديرك إلغاء الحظر لك</translation>
<translation id="3566021033012934673">اتصالك ليس خاصًا</translation>
+<translation id="3569145463236695319">â€&lt;p&gt;تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن تاريخ ووقت جهازك (<ph name="DATE_AND_TIME" />) غير صحيحين.&lt;/p&gt;
+
+ &lt;p&gt;ÙŠÙرجى تعديل التاريخ والوقت من القسم &lt;strong&gt;عام&lt;/strong&gt; ÙÙŠ تطبيق &lt;strong&gt;الإعدادات&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">إضاÙØ© اسم</translation>
<translation id="3583757800736429874">إ&amp;عادة النقل</translation>
<translation id="3586931643579894722">إخÙاء التÙاصيل</translation>
-<translation id="3587482841069643663">الكل</translation>
<translation id="3600246354004376029"><ph name="TITLE" />، و<ph name="DOMAIN" />، و<ph name="TIME" /></translation>
<translation id="3615877443314183785">أدخÙÙ„ تاريخ انتهاء صلاحية صحيحًا</translation>
<translation id="36224234498066874">مسح بيانات التصÙØ­...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">معلومات الشهادة</translation>
<translation id="3690164694835360974">عملية تسجيل الدخول غير آمنة</translation>
<translation id="3693415264595406141">كلمة المرور:</translation>
-<translation id="3696411085566228381">بدون</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">جار٠التحميل...</translation>
<translation id="3712624925041724820">التراخيص مستنÙذة</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />التحقق من تهيئة الخادم الوكيل والجدار الناري ونظام أسماء النطاقات<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">إذا كنت على دراية بالمخاطر على أمنك، يمكنك <ph name="BEGIN_LINK" />زيارة هذا الموقع غير الآمن<ph name="END_LINK" /> قبل أن تتم إزالة البرامج الخطيرة.</translation>
<translation id="3739623965217189342">الرابط الذي نسخته</translation>
+<translation id="3744899669254331632">â€Ù„ا يمكنك زيارة <ph name="SITE" /> ÙÙŠ الوقت الحالي لأن الموقع أرسل اعتمادات مختلطة حيث لا يستطيع Chromium المعالجة. أخطاء الشبكة وهجماتها عادةً ما تكون مؤقتة، لذلك من المحتمل أن تعمل هذه الصÙحة ÙÙŠ وقت لاحق.</translation>
+<translation id="3748148204939282805">قد يخدعك المهاجمون على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> لتنÙيذ أمور خطيرة، مثل تثبيت البرامج أو نشر معلوماتك الشخصية (على سبيل المثال، كلمات المرور، أو أرقام الهاتÙØŒ أو بطاقات الائتمان). <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">أخÙقت الترجمة بسبب حدوث خطأ ÙÙŠ الخادم.</translation>
<translation id="3759461132968374835">ليس لديك أي أعطال تم الإبلاغ عنها مؤخرًا. الأعطال التي حدثت عندما تم تعطيل الإبلاغ عن الأعطال لن تظهر هنا.</translation>
+<translation id="3778403066972421603">â€Ù‡Ù„ تريد Ø­Ùظ هذه البطاقة ÙÙŠ حسابك ÙÙŠ Google وعلى هذا الجهاز؟</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">تنتهي ÙÙŠ <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">إذا كنت تستخدم خادمًا وكيلاً...</translation>
<translation id="3828924085048779000">غير مسموح باستخدام عبارة مرور Ùارغة.</translation>
-<translation id="3845539888601087042">عرض السجلّ من الأجهزة التي تم تسجيل الدخول عليها. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">الرجوع إلى الوراء</translation>
<translation id="3858027520442213535">تحديث التاريخ والوقت</translation>
<translation id="3884278016824448484">معر٠جهاز متضارب</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">تمّ إرسال طلبك للدخول إلى هذا الموقع إلى <ph name="NAME" /></translation>
<translation id="3890664840433101773">إضاÙØ© بريد إلكتروني</translation>
<translation id="3901925938762663762">انتهت صلاحية البطاقة</translation>
-<translation id="3933571093587347751">{1,plural, =1{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه من الغد. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}zero{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # يوم ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}two{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال يومين (#) ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}few{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # أيام ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}many{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # يومًا ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}other{هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› من المÙترض أن تبدأ شهادة أمانه خلال # يوم ÙÙŠ المستقبل. ربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">â€Ø¥Ø®Ùاق تحميل مستند PDF</translation>
+<translation id="3945915738023014686">تحميل Ù…Ùعرّ٠تقارير الأعطال <ph name="CRASH_ID" /> (Ù…Ùعرّ٠الأعطال المحلية: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">لم يتمكن هذا الخادم من إثبات أنه <ph name="DOMAIN" />Ø› بل إن شهادة الأمان التابعة له لا تÙحدّد الأسماء البديلة للمضيÙات. وربما يكون السبب ÙÙŠ ذلك وجود خطأ ÙÙŠ التهيئة أو اعتراض أحد المهاجمين للاتصال.</translation>
<translation id="3963721102035795474">وضع القارئ</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{بدون}=1{من موقع واحد }two{من موقعين (#) }few{من # مواقع }many{من # موقعًا }other{من # موقع }}</translation>
<translation id="397105322502079400">جار٠الحساب...</translation>
<translation id="3973234410852337861">تم حظر <ph name="HOST_NAME" /></translation>
+<translation id="3987940399970879459">أقل من ميغابايت واحد</translation>
<translation id="40103911065039147">{URL_count,plural, =1{صÙحة ويب واحدة مجاورة}zero{# صÙحات ويب مجاورة}two{صÙحتا ويب (#) مجاورتان}few{# صÙحات ويب مجاورة}many{# صÙحة ويب مجاورة}other{# صÙحة ويب مجاورة}}</translation>
<translation id="4021036232240155012">â€ÙŠÙعد نظام أسماء النطاقات (DNS) هو خدمة الشبكة التي تترجم اسم موقع ويب إلى عنوانه على شبكة الإنترنت.</translation>
<translation id="4030383055268325496">تراجع عن الإ&amp;ضاÙØ©</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">â€ØªÙ… تعيين تهيئة الخادم الوكيل لاستخدام عنوان URL نص برمجي ‎.pac وليس الخوادم الوكيلة الثابتة.</translation>
<translation id="4098354747657067197">موقع مخادع ÙÙŠ انتظارك</translation>
<translation id="4103249731201008433">الرقم التسلسلي للجهاز غير صالح</translation>
+<translation id="410351446219883937">تشغيل تلقائي</translation>
<translation id="4103763322291513355">â€Ø§Ù†ØªÙ‚Ù„ إلى &lt;strong&gt;chrome://policy&lt;/strong&gt; لمشاهدة قائمة بعناوين URL المضاÙØ© إلى القائمة السوداء والسياسات الأخرى التي Ùرضها مشر٠النظام.</translation>
-<translation id="4110615724604346410">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />ØŒ بل إن شهادة أمانه تحتوي على أخطاء. وربما يكون سبب ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">أرجواني</translation>
+<translation id="4116663294526079822">إلغاء الحظر دومًا على هذا الموقع</translation>
<translation id="4117700440116928470">نطاق السياسة غير متواÙÙ‚.</translation>
-<translation id="4118212371799607889">â€Ù‡Ø°Ø§ الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />ØŒ بل إن شهادة أمانه غير موثوقة من Ù‚Ùبل Chromium. وربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{عنصر واحد آخر}zero{# عنصر آخر}two{عنصران آخران (#)}few{# عناصر أخرى}many{# عنصرًا آخر}other{# عنصر آخر}}</translation>
<translation id="4130226655945681476">التحقق من كابلات الشبكة، والمودم، وجهاز التوجيه</translation>
+<translation id="413544239732274901">مزيد من المعلومات</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">استخدام الإعدادات العمومية الاÙتراضية (كشÙ)</translation>
+<translation id="4165986682804962316">إعدادات الموقع</translation>
<translation id="4169947484918424451">â€Ù‡Ù„ تريد من Chromium Ø­Ùظ هذه البطاقة؟</translation>
<translation id="4171400957073367226">توقيع تحقق سيئ</translation>
<translation id="4196861286325780578">إ&amp;عادة النقل</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />التحقق من عمليات تهيئة الجدار الناري وبرامج مكاÙحة الÙيروسات<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{لا شيء}=1{تطبيق واحد ($1)}=2{تطبيقان (2) ($1، $2)}few{# تطبيقات ($1، $2، $3)}many{# تطبيقًا ($1، $2، $3)}other{# تطبيق ($1، $2، $3)}}</translation>
<translation id="4220128509585149162">الأعطال</translation>
+<translation id="422022731706691852">قد يحاول المهاجمون ÙÙŠ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> خداعك لتثبيت برامج تلحق الضرر بتجربة التصÙØ­ (على سبيل المثال، من خلال تغيير صÙحتك الرئيسية أو عرض إعلانات إضاÙية على المواقع التي تزورها). <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />تجربة تشغيل بيانات تشخيص الشبكة<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">صالح</translation>
<translation id="4250431568374086873">إن اتصالك بهذا الموقع غير آمن تمامًا</translation>
<translation id="4250680216510889253">لا</translation>
<translation id="425582637250725228">قد لا يتم Ø­Ùظ التغييرات التي أجريتها.</translation>
<translation id="4258748452823770588">توقيع غير صالح</translation>
+<translation id="4265872034478892965">تم السماح من قبل المشرÙ</translation>
<translation id="4269787794583293679">(اسم المستخدم غير موجود)</translation>
<translation id="4275830172053184480">إعادة تشغيل جهازك</translation>
<translation id="4280429058323657511">، تاريخ انتهاء الصلاحية <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">â€Ø§ÙƒØªØ´Ù التصÙØ­ الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />برامج ضارة<ph name="END_LINK" /> على <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">اقتراحات الآباء</translation>
<translation id="4304224509867189079">تسجيل الدخول</translation>
-<translation id="432290197980158659">قدم الخادم شهادة لا تتطابق مع التوقعات المضمّنة. تم تضمين هذه التوقعات للحصول على مواقع ويب موثوقة وآمنة جدًا لتوÙير الحماية لك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">حظر (اÙتراضي)</translation>
<translation id="4325863107915753736">تعذّر العثور على المقالة</translation>
<translation id="4326324639298822553">تحقق من تاريخ انتهاء الصلاحية وأعÙد المحاولة مرة أخرى</translation>
<translation id="4331708818696583467">غير آمن</translation>
<translation id="4356973930735388585">قد يحاول المهاجمون الموجودون على هذا الموقع تثبيت برامج خطيرة على الكمبيوتر التابع لك تسرق معلوماتك أو تحذÙها (على سبيل المثال، الصور وكلمات المرور والرسائل وبطاقات الائتمان).</translation>
<translation id="4372948949327679948">القيمة <ph name="VALUE_TYPE" /> المتوقعة.</translation>
+<translation id="4377125064752653719">لقد حاولت الوصول إلى <ph name="DOMAIN" />ØŒ ولكن جهة إصدار الشهادة التي قدمها الخادم قد أبطلت الشهادة. وهذا يعني أن بيانات اعتماد الأمان التي قدمها الخادم يجب عدم الوثوق بها مطلقًا. Ùقد تكون على اتصال بأحد المهاجمين.</translation>
<translation id="4381091992796011497">اسم المستخدم:</translation>
<translation id="4394049700291259645">تعطيل</translation>
<translation id="4406896451731180161">نتائج البحث</translation>
+<translation id="4424024547088906515">â€Ù‡Ø°Ø§ الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان غير موثوقة من قبل Chrome. وربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض الاتصال.</translation>
<translation id="4432688616882109544">لم يقبل <ph name="HOST_NAME" /> شهادة تسجيل الدخول أو من المحتمل ألا يكون قد تم تقديم واحدة.</translation>
<translation id="443673843213245140">تم تعطيل استخدام الخادم الوكيل ولكن تم تحديد تهيئة صريحة للخادم الوكيل.</translation>
-<translation id="4492190037599258964">نتائج البحث عن '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">خطأ ÙÙŠ عملية التحقق: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4506599922270137252">الاتصال بمشر٠النظام</translation>
<translation id="450710068430902550">المشاركة مع المشرÙ</translation>
<translation id="4515275063822566619">â€ØªØ£ØªÙŠ البطاقات والعناوين من Chrome وحسابك ÙÙŠ Google (<ph name="ACCOUNT_EMAIL" />). ويمكنك إدارتها ÙÙŠ <ph name="BEGIN_LINK" />الإعدادات<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">التÙاصيل</translation>
+<translation id="4552089082226364758">الÙلاش</translation>
<translation id="4558551763791394412">جرّب تعطيل الإضاÙات.</translation>
<translation id="457875822857220463">التسليم</translation>
<translation id="4587425331216688090">â€Ù‡Ù„ تريد إزالة العنوان من ChromeØŸ</translation>
-<translation id="4589078953350245614">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن الخادم قدم شهادة غير صالحة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">يتم ترميز اتصالك بالنطاق <ph name="DOMAIN" /> باستخدام مجموعة تشÙير حديثة.</translation>
<translation id="4594403342090139922">تراجع عن الحذ&amp;Ù</translation>
<translation id="4619615317237390068">علامات التبويب من الأجهزة الأخرى</translation>
<translation id="4668929960204016307">،</translation>
+<translation id="467662567472608290">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان تحتوي على أخطاء. وربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض اتصالك.</translation>
+<translation id="4690462567478992370">التوق٠عن استخدام شهادة غير صالحة</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" />†<ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">تم قطع اتصالك</translation>
<translation id="4722547256916164131">â€<ph name="BEGIN_LINK" />تشغيل بيانات تشخيص شبكة Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">حدث خطأ غير محدّد.</translation>
<translation id="4800132727771399293">â€ØªØ­Ù‚Ù‚ من تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) وأعد المحاولة مرة أخرى.</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">â€Ù„ا يمكنك زيارة <ph name="SITE" /> الآن نظرًا لأن موقع الويب أرسل بيانات اعتماد مختلطة يتعذر على Google Chrome معالجتها. وعادةً ما تكون أخطاء الشبكة والهجمات عليها مؤقتة؛ لذا ستعمل هذه الصÙحة لاحقًا على الأرجح.</translation>
<translation id="4813512666221746211">حدث خطأ ÙÙŠ الشبكة</translation>
<translation id="4816492930507672669">احتواء ضمن الصÙحة</translation>
<translation id="483020001682031208">لا توجد صÙحات شبكة مادية متاحة للعرض</translation>
<translation id="4850886885716139402">عرض</translation>
<translation id="4854362297993841467">طريقة التسليم هذه غير متاحة. جرّÙب طريقة أخرى.</translation>
<translation id="4858792381671956233">لقد سألت والديك ما إذا كانت زيارة هذا الموقع مناسبةً لك</translation>
+<translation id="4863764087567530506">قد يحاول هذا المحتوى خداعك لتنزيل برامج أو الكش٠عن معلومات شخصية. <ph name="BEGIN_LINK" />عرض على أي حال<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">سجلّ البحث</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />، <ph name="TYPE_2" />، <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{وصÙحة ويب واحدة إضاÙية}zero{Ùˆ# صÙحة ويب إضاÙية}two{وصÙحتا ويب (#) إضاÙيتان}few{Ùˆ# صÙحات ويب إضاÙية}many{Ùˆ# صÙحة ويب إضاÙية}other{Ùˆ# صÙحة ويب إضاÙية}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">تمت ترجمة هذه الصÙحة من لغة غير معروÙØ© إلى اللغة <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">الدÙع</translation>
<translation id="4926049483395192435">يجب تحديدها.</translation>
<translation id="495170559598752135">إجراءات</translation>
<translation id="4958444002117714549">توسيع القائمة</translation>
-<translation id="4962322354953122629">â€Ù‡Ø°Ø§ الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إن شهادة أمانه غير موثوقة من Ù‚Ùبل Chrome. وربما يكون السبب ÙÙŠ ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">إعادة تمكين التحذيرات</translation>
<translation id="4989809363548539747">هذا المكوّÙÙ† الإضاÙÙŠ غير مدعوم</translation>
<translation id="5002932099480077015">â€Ø¥Ø°Ø§ تم التمكين، سيخزن Chrome نسخة من بطاقتك على هذا الجهاز لملء النموذج بشكل أسرع.</translation>
<translation id="5018422839182700155">يتعذّر Ùتح هذه الصÙحة</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">التحقق من سياسات المشرÙ</translation>
<translation id="5029568752722684782">محو النسخة</translation>
<translation id="5031870354684148875">â€Ù…علومات عن الترجمة من Google</translation>
+<translation id="5039804452771397117">سماح</translation>
<translation id="5040262127954254034">الخصوصية</translation>
<translation id="5045550434625856497">كلمة مرور غير صحيحة</translation>
<translation id="5056549851600133418">مقالات من أجلك</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />التحقق من عنوان الخادم الوكيل<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{لا توجد ملÙات تعري٠ارتباط}=1{يستخدم موقع ويب واحد ملÙات تعري٠الارتباط. }two{يستخدم موقعا ويب (#) ملÙات تعري٠الارتباط. }few{تستخدم # مواقع ويب ملÙات تعري٠الارتباط. }many{يستخدم # موقعًا من مواقع الويب ملÙات تعري٠الارتباط. }other{يستخدم # موقع ويب ملÙات تعري٠الارتباط. }}</translation>
<translation id="5087286274860437796">شهادة الخادم ليست صالحة حاليًا.</translation>
<translation id="5087580092889165836">إضاÙØ© بطاقة</translation>
<translation id="5089810972385038852">بلد/دولة</translation>
+<translation id="5094747076828555589">â€Ù‡Ø°Ø§ الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان غير موثوقة من قبل Chromium. وربما يكون السبب ÙÙŠ ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض الاتصال.</translation>
<translation id="5095208057601539847">الإقليم</translation>
<translation id="5115563688576182185">(64 بت)</translation>
<translation id="5141240743006678641">â€ØªØ´Ùير كلمات المرور المتزامنة باستخدام بيانات اعتماد Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">البريد الإلكتروني مطلوب</translation>
<translation id="5251803541071282808">السحاب</translation>
<translation id="5277279256032773186">â€Ù‡Ù„ تستخدم Chrome ÙÙŠ العمل؟ يمكن للأنشطة التجارية إدارة إعدادات Chrome لموظÙيها. تعرَّ٠على المزيد</translation>
+<translation id="5297526204711817721">â€Ø§ØªØµØ§Ù„Ùƒ بهذا الموقع ليس له خصوصية. للخروج من وضع الواقع الاÙتراضي (VR) ÙÙŠ أي وقت، أزل سماعة الرأس واضغط على رجوع.</translation>
<translation id="5299298092464848405">خطأ ÙÙŠ تحليل السياسة</translation>
-<translation id="5300589172476337783">عرض</translation>
<translation id="5308689395849655368">ميزة الإبلاغ عن الأعطال معطلة.</translation>
<translation id="5317780077021120954">Ø­Ùظ</translation>
<translation id="5327248766486351172">الاسم</translation>
-<translation id="5337705430875057403">قد يخدعك المخترقون الموجودون على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> بÙعل شيء خطير كتثبيت البرامج أو الكش٠عن معلوماتك الشخصية (على سبيل المثال، كلمات المرور، أرقام الهواتÙØŒ أو بطاقات الائتمان).</translation>
-<translation id="5359637492792381994">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />ØŒ بل إن شهادة أمانه غير صالحة حاليًا. وربما يكون السبب ÙÙŠ ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">لا يمكنك زيارة <ph name="SITE" /> الآن لأنه تم إبطال شهادته. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصÙحة ÙÙŠ وقت على الأرجح.</translation>
<translation id="536296301121032821">تعذّر تخزين إعدادات السياسة</translation>
<translation id="5386426401304769735">â€ØªØªØ¶Ù…Ù† سلسلة الشهادات لهذا الموقع شهادة موقعة باستخدام SHA-1.</translation>
<translation id="5402410679244714488">تاريخ انتهاء الصلاحية: <ph name="EXPIRATION_DATE_ABBR" />، تم استخدامها آخر مرة قبل أكثر من عام</translation>
+<translation id="540969355065856584">لم يتمكن هذا الخادم من إثبات أنه <ph name="DOMAIN" />Ø› بل إن شهادة الأمان الخاصة به غير صالحة حاليًا. وربما يكون السبب ÙÙŠ ذلك وجود خطأ ÙÙŠ التكوين أو اعترض أحد المهاجمين للاتصال.</translation>
<translation id="5421136146218899937">محو بيانات التصÙØ­...</translation>
<translation id="5430298929874300616">إزالة إشارة مرجعية</translation>
<translation id="5431657950005405462">لم يتم العثور على ملÙÙƒ</translation>
-<translation id="5435775191620395718">عرض السجل من هذا الجهاز. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">حدث خطأ ÙÙŠ مصادقة المخطط على "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">لا يمكن العثور على صÙحة <ph name="HOST_NAME" /> هذه.</translation>
<translation id="5455374756549232013">الطابع الزمني للسياسة سيئ</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> من <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">غير صالحة</translation>
<translation id="5470861586879999274">إعادة الت&amp;حرير</translation>
<translation id="54817484435770891">إضاÙØ© عنوان صالح</translation>
<translation id="5492298309214877701">â€ÙŠÙƒÙˆÙ† لموقع الويب هذا على الشبكة الداخلية للشركة أو المؤسسة أو المدرسة Ù†Ùس عنوان URL لأحد مواقع الويب الخارجية.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">لا يمكن الاستلام من هذا العنوان. حدّÙد عنوانًا آخر.</translation>
<translation id="5572851009514199876">â€ÙŠÙرجى البدء وتسجيل الدخول إلى Chrome لكي يتأكد Chrome مما إذا كان مسموحًا لك الوصول إلى موقع الويب هذا أم لا.</translation>
<translation id="5580958916614886209">تحقق من شهر انتهاء الصلاحية وأعÙد المحاولة مرة أخرى</translation>
+<translation id="5586446728396275693">لا توجد عناوين محÙوظة</translation>
+<translation id="5595485650161345191">تعديل العنوان</translation>
<translation id="560412284261940334">الإدارة غير متوÙرة</translation>
<translation id="5610142619324316209">التحقق من الاتصال</translation>
<translation id="5610807607761827392">يمكنك إدارة البطاقات والعناوين ÙÙŠ <ph name="BEGIN_LINK" />الإعدادات<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">هل تريد الخروج من هذا الموقع؟</translation>
<translation id="5629630648637658800">تعذّر تحميل إعدادات السياسة</translation>
<translation id="5631439013527180824">الرمز المميز لإدارة الجهاز غير صالح</translation>
+<translation id="5633066919399395251">يمكن حاليًا للمهاجمين على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> محاولة تثبيت برامج خطيرة على الكمبيوتر تسرق أو تحذ٠معلوماتك (على سبيل المثال، الصور، وكلمات المرور، والرسائل، وبطاقات الائتمان). <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">الموقع</translation>
+<translation id="5659593005791499971">البريد الإلكتروني</translation>
<translation id="5669703222995421982">الحصول على محتوى مخصص</translation>
<translation id="5675650730144413517">يتعذّر على هذه الصÙحة العمل</translation>
-<translation id="5677928146339483299">تم المنع</translation>
-<translation id="5694783966845939798">â€Ù„قد حاولت الوصول إلى <ph name="DOMAIN" />ØŒ ولكن قدَّم الخادم شهادة موقّعة باستخدام خوارزمية توقيع ضعيÙØ© (مثل SHA-1). مما يعني أن بيانات اعتماد الأمان التي قدمها الخادم من المحتمل أنه تم تزييÙها، وأن الخادم قد لا يكون هو الخادم الذي تتوقعه (قد تكون على اتصال بأحد المهاجمين). <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">لم يتمّ التحقق من هوية هذا الموقع.</translation>
+<translation id="5713016350996637505">تم حظر المحتوى المÙضلل</translation>
<translation id="5720705177508910913">المستخدم الحالي</translation>
<translation id="5732392974455271431">يمكن لوالديك إلغاء الحظر لك</translation>
<translation id="5763042198335101085">أدخÙÙ„ عنوان بريد إلكتروني صحيحًا</translation>
<translation id="5765072501007116331">لعرض طرق التسليم ومتطلباته، حدّÙد عنوانًا</translation>
+<translation id="5778550464785688721">â€Ø§Ù„تحكم الكامل ÙÙŠ MIDI</translation>
<translation id="5784606427469807560">حدثت مشكلة أثناء التأكد من بطاقتك. تحقق من اتصالك بالإنترنت وأعد المحاولة.</translation>
<translation id="5785756445106461925">إضاÙØ© إلى ذلك، تتضمن هذه الصÙحة موارد أخرى غير آمنة. ويستطيع الآخرون مشاهدة هذه الموارد أثناء نقلها، كما يستطيع أي مهاجم تعديلها لتغيير مظهر الصÙحة.</translation>
<translation id="5786044859038896871">هل تريد ملء معلومات بطاقتك؟</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">إعا&amp;دة الإضاÙØ©</translation>
<translation id="5814352347845180253">قد تÙقد إمكانية الدخول إلى محتوى متميز من <ph name="SITE" /> وبعض المواقع الأخرى.</translation>
<translation id="5838278095973806738">يجب عدم إدخال معلومات حسّاسة على هذا الموقع (على سبيل المثال، كلمات المرور أو بطاقات الائتمان)ØŒ نظرًا لأنه قد تتم سرقتها من Ù‚Ùبل المهاجمين.</translation>
-<translation id="5843436854350372569">لقد حاولت الوصول إلى <ph name="DOMAIN" />ØŒ ولكن الخادم قدّم شهادة تحتوي على Ù…Ùتاح ضعيÙ. ربما اخترق أحد المهاجمين المÙتاح الخاص، وقد لا يكون الخادم هو الخادم الذي تتوقعه (قد تكون على اتصال بأحد المهاجمين). <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">لا يمكن الوصول إلى موقع الويب هذا</translation>
<translation id="5869522115854928033">كلمات المرور المحÙوظة</translation>
<translation id="5872918882028971132">اقتراحات الآباء</translation>
<translation id="5901630391730855834">أصÙر</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (تمت المزامنة)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 قيد الاستخدام}zero{# قيد الاستخدام}two{# قيد الاستخدام}few{# قيد الاستخدام}many{# قيد الاستخدام}other{# قيد الاستخدام}}</translation>
<translation id="5926846154125914413">قد تÙقد إمكانية الدخول إلى محتوى متميز من بعض المواقع.</translation>
<translation id="5959728338436674663">â€ÙŠÙ…كنك إرسال بعض <ph name="BEGIN_WHITEPAPER_LINK" />معلومات النظام ومحتوى الصÙحة<ph name="END_WHITEPAPER_LINK" /> إلى Google تلقائيًا للمساعدة ÙÙŠ اكتشا٠التطبيقات والمواقع الضارة. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">الأسبوع</translation>
<translation id="5967867314010545767">إزالة من السجل</translation>
<translation id="5975083100439434680">تصغير</translation>
<translation id="598637245381783098">لا يمكن Ùتح تطبيق الدÙع</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{صÙحة 1}zero{صÙحة #}two{صÙحة #}few{صÙحة #}many{صÙحة #}other{صÙحة #}}</translation>
<translation id="6017514345406065928">أخضر</translation>
+<translation id="6017850046339264347">يمكن للمهاجمين على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> تثبيت تطبيقات مضللة تدعي أنها شيء آخر أو تجمع بيانات قد يتم استخدامها لتتبعك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />، <ph name="TYPE_2" />، <ph name="TYPE_3" /> (تمت المزامنة)</translation>
<translation id="6027201098523975773">أدخÙÙ„ اسمًا</translation>
<translation id="6040143037577758943">إغلاق</translation>
<translation id="6042308850641462728">المزيد</translation>
+<translation id="6047233362582046994">إذا كنت على دراية بالمخاطر التي تهدد أمانك، يمكنك <ph name="BEGIN_LINK" />زيارة موقع الويب هذا<ph name="END_LINK" /> قبل أن تتم إزالة التطبيقات الضارة.</translation>
+<translation id="6051221802930200923">لا يمكنك زيارة <ph name="SITE" /> ÙÙŠ الوقت الحالي لأن الموقع يستخدم أداة التحقق من صحة الشهادات. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصÙحة ÙÙŠ وقت لاحق على الأرجح.</translation>
<translation id="6060685159320643512">احذر، هذه التجارب غير مضمونة النتائج</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{لا شيء}=1{1}two{#}few{#}many{#}other{#}}</translation>
+<translation id="6080696365213338172">لقد دخلت إلى المحتوى باستخدام شهادة ÙˆÙرها المشرÙ. ويمكن أن يعترض المشر٠طريق البيانات التي تقدمها إلى <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{بدون}=1{ كلمة مرور واحدة (تمت مزامنتها)}two{كلمتا مرور (#) (تمت مزامنتهما)}few{# كلمات مرور (تمت مزامنتها)}many{# كلمة مرور (تمت مزامنتها)}other{# كلمة مرور (تمت مزامنتها)}}</translation>
<translation id="6146055958333702838">تحقق من أي كابلات وأعد تشغيل أي أجهزة توجيه أو أجهزة مودم أو أجهزة شبكة
أخرى ربما تستخدمها.</translation>
<translation id="614940544461990577">جرّب:</translation>
<translation id="6151417162996330722">Ùترة صلاحية شهادة الخادم طويلة جدًا.</translation>
<translation id="6157877588268064908">لعرض طرق الشحن ومتطلباته، حدّÙد عنوانًا</translation>
+<translation id="6158003235852588289">â€Ø§ÙƒØªØ´Ù التصÙØ­ الآمن من Google‬ مؤخرًا تصيّدًا احتياليًا على <ph name="SITE" />. تتظاهر مواقع التصيد بكونها مواقع ويب أخرى لخداعك.</translation>
<translation id="6165508094623778733">مزيد من المعلومات</translation>
+<translation id="6169916984152623906">يمكنك الآن التصÙØ­ بشكل٠سري، ولن يتمكّن الأشخاص الآخرون الذين يستخدمون هذا الجهاز من مشاهدة نشاطك. ولكن، سيتم Ø­Ùظ عمليات التنزيل والإشارات المرجعيّة.</translation>
<translation id="6177128806592000436">إن اتصالك بهذا الموقع غير آمن</translation>
<translation id="6184817833369986695">(مجموعة نموذجية: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">التحقق من اتصالك بالإنترنت</translation>
<translation id="6218753634732582820">â€Ù‡Ù„ تريد إزالة العنوان من ChromiumØŸ</translation>
+<translation id="6221345481584921695">â€Ø§ÙƒØªØ´Ù التصÙØ­ الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />برامج ضارة<ph name="END_LINK" /> على <ph name="SITE" />. أحيانًا تصاب مواقع الويب الآمنة ÙÙŠ الوضع العادي ببرامج ضارة. مصدر محتوى البرامج الضارة <ph name="SUBRESOURCE_HOST" />ØŒ وهو ناشر معرو٠للبرامج الضارة.</translation>
<translation id="6251924700383757765">سياسة الخصوصية</translation>
<translation id="6254436959401408446">لا تتوÙر ذاكرة كاÙية Ù„Ùتح هذه الصÙحة</translation>
<translation id="625755898061068298">لقد اخترت تعطيل تحذيرات الأمان لهذا الموقع.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">تعديل إشارة مرجعية</translation>
<translation id="6410264514553301377">â€Ø£Ø¯Ø®ÙÙ„ تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">لقد سألت والديك ما إذا كانت زيارة هذا الموقع مناسبةً لك</translation>
-<translation id="6416403317709441254">â€Ù„ا يمكنك زيارة <ph name="SITE" /> الآن نظرًا لأن موقع الويب أرسل بيانات اعتماد مختلطة يتعذر على Chromium معالجتها. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصÙحة لاحقًا على الأرجح. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">تعذر التحقق مما إذا كانت الشهادة قد تم إبطالها.</translation>
<translation id="6433490469411711332">تعديل معلومات الاتصال</translation>
<translation id="6433595998831338502">رÙض <ph name="HOST_NAME" /> الاتصال.</translation>
<translation id="6446608382365791566">إضاÙØ© مزيد من المعلومات</translation>
+<translation id="6447842834002726250">ملÙّات تعري٠الارتباط</translation>
<translation id="6451458296329894277">تأكيد إعادة إرسال النموذج</translation>
<translation id="6456339708790392414">دÙعتك</translation>
<translation id="6458467102616083041">تم التجاهل نظرًا لتعطيل البحث الاÙتراضي بواسطة السياسة.</translation>
-<translation id="6462969404041126431">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />ØŒ قد يكون تم إبطال شهادة أمانه. وربما يكون سبب ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">سياسات الأجهزة</translation>
<translation id="6477321094435799029">â€Ø§ÙƒØªØ´Ù Chrome وجود رمز غير عادي على هذه الصÙحة وأجرى حظرًا لهذا الرمز لحماية معلوماتك الشخصية (على سبيل المثال، كلمات المرور، وأرقام الهواتÙØŒ وبطاقات الائتمان).</translation>
<translation id="6489534406876378309">بدء تحميل الأعطال</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">تاريخ انتهاء الصلاحية: <ph name="EXPIRATION_DATE_ABBR" />، وتاريخ آخر استخدام: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">لم يواÙÙ‚ عليه مديرك حتى الآن</translation>
<translation id="6569060085658103619">أنت تعرض صÙحة إضاÙØ©</translation>
-<translation id="6593753688552673085">أقل من <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">قد يحاول هذا المحتوى تثبيت برامج خطيرة على جهازك تسرق معلوماتك أو تحذÙها. <ph name="BEGIN_LINK" />عرض على أي حال<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">خيارات التشÙير</translation>
<translation id="662080504995468778">البقاء</translation>
<translation id="6626291197371920147">إضاÙØ© رقم بطاقة صالح</translation>
<translation id="6628463337424475685">بحث <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">â€Ù‚د يحاول المهاجمون حاليًا على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> تثبيت برامج خطيرة على جهاز Mac تؤدي إلى سرقة أو حذ٠معلوماتك (على سبيل المثال، الصور، وكلمات المرور، والرسائل، وبطاقات الائتمان) <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">تم تجاهل هذه السياسة.</translation>
-<translation id="6652240803263749613">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />ØŒ بل إن شهادة أمانه غير موثوقة من Ù‚Ùبل نظام تشغيل الكمبيوتر. وربما يكون السبب ÙÙŠ ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">â€Ù‡Ù„ تريد إزالة اقتراح النموذج من ChromiumØŸ</translation>
<translation id="6685834062052613830">الخروج وإكمال الإعداد</translation>
<translation id="6710213216561001401">السابق</translation>
<translation id="6710594484020273272">&lt;إدخال عبارة البحث&gt;</translation>
<translation id="6711464428925977395">هناك خطأ ما ÙÙŠ الخادم الوكيل، أو العنوان غير صحيح.</translation>
<translation id="6727102863431372879">تعيين</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{لا شيء}=1{عنصر واحد}two{عنصران (#)}few{# عناصر}many{# عنصرًا}other{# عنصر}}</translation>
<translation id="674375294223700098">حدث خطأ غير معرو٠ÙÙŠ شهادة الخادم.</translation>
<translation id="6753269504797312559">قيمة السياسة</translation>
<translation id="6757797048963528358">خضع جهازك إلى وضع السكون.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">رقم تعري٠التخصيص</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">تعذَّر تحميل بيانات المناطق</translation>
+<translation id="6825578344716086703">â€Ù„قد حاولت الوصول إلى <ph name="DOMAIN" />ØŒ ولكن قدَّم الخادم شهادة موقّعة باستخدام خوارزمية توقيع ضعيÙØ© (مثل SHA-1)ØŒ مما يعني أن بيانات اعتماد الأمان التي قدمها الخادم من المحتمل أنه تم تزييÙها، وأن الخادم قد لا يكون هو الخادم الذي تتوقعه (قد تكون على اتصال بأحد المهاجمين).</translation>
+<translation id="6830728435402077660">غير آمن</translation>
<translation id="6831043979455480757">ترجمة</translation>
<translation id="6839929833149231406">المنطقة</translation>
<translation id="6874604403660855544">إعا&amp;دة الإضاÙØ©</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">تم التأكد من بطاقتك</translation>
<translation id="6897140037006041989">وكيل المستخدم</translation>
<translation id="6915804003454593391">المستخدم:</translation>
+<translation id="6945221475159498467">تحديد</translation>
<translation id="6948701128805548767">لعرض طرق الاستلام ومتطلباته، حدّÙد عنوانًا</translation>
<translation id="6957887021205513506">يبدو أن شهادة الخادم مزيÙØ©.</translation>
<translation id="6965382102122355670">مواÙÙ‚</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">â€ØªÙ… تحديد كل من الخوادم الوكيلة الثابتة وعنوان URL للنص البرمجي pac.</translation>
<translation id="6989763994942163495">عرض الإعدادات المتقدمة...</translation>
<translation id="7000990526846637657">لم يتم العثور على أي إدخالات ÙÙŠ السجلّ</translation>
-<translation id="7009986207543992532">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن الخادم قدّم شهادة مدة صلاحيتها طويلة جدًا مما يجعلها غير جديرة بالثقة. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">â€Ù‚د يتضمن حسابك ÙÙŠ Google نماذج أخرى من سجلّ التصÙØ­ ÙÙŠ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">كلمات المرور</translation>
+<translation id="7050187094878475250">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن الخادم قدم شهادة مدة صلاحيتها طويلة جدًا مما يجعلها غير جديرة بالثقة.</translation>
+<translation id="7053983685419859001">منع</translation>
<translation id="7064851114919012435">معلومات الاتصال</translation>
<translation id="7079718277001814089">يحتوي هذا الموقع على برامج ضارة</translation>
<translation id="7087282848513945231">المقاطعة/الإقليم/المنطقة</translation>
-<translation id="7088615885725309056">أقدم</translation>
<translation id="7090678807593890770">â€Ø§Ù„بحث ÙÙŠ Google عن <ph name="LINK" /></translation>
+<translation id="7108819624672055576">تم السماح بواسطة إحدى الإضاÙات</translation>
<translation id="7119414471315195487">إغلاق علامات التبويب أو البرامج الأخرى</translation>
<translation id="7129409597930077180">لا يمكن الشحن على هذا العنوان. حدّÙد عنوانًا آخر.</translation>
<translation id="7138472120740807366">طريقة التسليم</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">جار٠المعالجة</translation>
<translation id="724691107663265825">يحتوي موقع الويب المقصود على برامج ضارة</translation>
<translation id="724975217298816891">â€Ø£Ø¯Ø®Ù„ تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" /> لتحديث تÙاصيل بطاقتك. بعد تأكيدك، ستتم مشاركة تÙاصيل بطاقتك مع هذا الموقع.</translation>
-<translation id="725866823122871198">تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن التاريخ والوقت لجهاز الكمبيوتر (<ph name="DATE_AND_TIME" />) غير صحيحين.</translation>
+<translation id="7260504762447901703">إبطال حق الدخول</translation>
<translation id="7275334191706090484">الإشارات المرجعية المÙدارة</translation>
<translation id="7298195798382681320">موصى بها</translation>
<translation id="7309308571273880165">تقرير الأعطال الذي تم الحصول عليه ÙÙŠ <ph name="CRASH_TIME" /> (التحميل مطلوب بواسطة المستخدم، لم يتم التحميل بعد)</translation>
<translation id="7334320624316649418">إعادة إ&amp;جراء الترتيب</translation>
<translation id="733923710415886693">لم يتم الكش٠عن شهادة الخادم عن طريق شهادة الشÙاÙية.</translation>
-<translation id="7351800657706554155">لا يمكنك زيارة <ph name="SITE" /> الآن نظرًا لأنه تم إبطال شهادته. وعادةً ما تكون أخطاء الشبكة والهجمات عليها مؤقتة، لذا ستعمل هذه الصÙحة لاحقًا على الأرجح. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">سطر الأوامر</translation>
<translation id="7372973238305370288">نتيجة البحث</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" />†- <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">لا</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">التأكد من البطاقة</translation>
-<translation id="7394102162464064926">هل تريد Ùعلًا حذ٠هذه الصÙحات من السجل؟
-
-اعلم أنه يمكن الاستÙادة من وضع التصÙØ­ المتخÙÙŠ <ph name="SHORTCUT_KEY" /> ÙÙŠ المرة التالية.</translation>
<translation id="7400418766976504921">â€Ø¹Ù†ÙˆØ§Ù† URL</translation>
<translation id="7419106976560586862">مسار المل٠الشخصي</translation>
<translation id="7424977062513257142">صÙحة Ù…Ùضمنة ÙÙŠ صÙحة الويب هذه تعرض:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">تم حظر هذا الموقع</translation>
<translation id="7445762425076701745">لا يمكن التحقق بصورة كاملة من صحة هوية الخادم الذي تتصل به. Ùأنت متصل بخادم باستخدام اسم صالح Ùقط ضمن شبكتك، والذي لن يتمكن المرجع المصدق الخارجي من التحقق من ملكيته. وحيث إن بعض المراجع المصدقة تÙصدر الشهادات لهذه الأسماء على أي حال، Ùليست هناك طريقة للتأكد من أنك متصل بموقع الويب المقصود وليس بأحد المهاجمين.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /> حول هذه المشكلة.</translation>
+<translation id="7455133967321480974">استخدام الإعداد الاÙتراضي العمومي (حظر)</translation>
<translation id="7460163899615895653">تظهر علامات التبويب الأخيرة من الأجهزة الأخرى هنا</translation>
<translation id="7469372306589899959">جار٠التاكد من البطاقة</translation>
<translation id="7481312909269577407">إلى الأمام</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">رقم تعري٠الجهاز المعروض للسياسة Ùارغ أو لا يتطابق مع رقم تعري٠الجهاز الحالي</translation>
<translation id="7514365320538308">تنزيل</translation>
<translation id="7518003948725431193">لم يتم العثور على أي صÙحة ويب لعنوان الويب:<ph name="URL" /></translation>
+<translation id="7521387064766892559">جاÙا سكريبت</translation>
<translation id="7535087603100972091">القيمة</translation>
<translation id="7537536606612762813">إلزامية</translation>
+<translation id="7542403920425041731">بعد تأكيدك، ستتم مشاركة تÙاصيل بطاقتك مع موقع الويب هذا.</translation>
<translation id="7542995811387359312">تم تعطيل الملء التلقائي لبطاقة الائتمان لأن هذا النموذج لا يستخدم اتصالاً آمنًا.</translation>
<translation id="7543525346216957623">اسأل والديك</translation>
<translation id="7549584377607005141">تتطلب صÙحة الويب هذه البيانات التي أدخلتها ÙÙŠ وقت سابق لعرضها بشكل صحيح. يمكنك إرسال هذه المعلومات مرة أخرى ولكن بذلك ستكرر أي إجراء اتخذته هذه الصÙحة ÙÙŠ وقت سابق.</translation>
<translation id="7552846755917812628">جرّب النصائح التالية:</translation>
<translation id="7554791636758816595">علامة تبويب جديدة</translation>
+<translation id="7567204685887185387">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إنه شهادة أمان تم إصدارها عن طريق الاحتيال. وربما يكون سبب ذلك خطأ ÙÙŠ التكوين أو مهاجمًا يعترض اتصالك.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> وجهة اتصال واحدة (<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />) أخرى}zero{<ph name="CONTACT_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> جهة اتصال أخرى}two{<ph name="CONTACT_PREVIEW" /> وجهتا اتصال (<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />) أخريان}few{<ph name="CONTACT_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> جهات اتصال أخرى}many{<ph name="CONTACT_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> جهة اتصال أخرى}other{<ph name="CONTACT_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> جهة اتصال أخرى}}</translation>
<translation id="7568593326407688803">تتوÙر هذه الصÙحة باللغة<ph name="ORIGINAL_LANGUAGE" />Ùهل تريد ترجمتها؟</translation>
<translation id="7569952961197462199">â€Ù‡Ù„ تريد إزالة بطاقة الائتمان من ChromeØŸ</translation>
<translation id="7569983096843329377">أسود</translation>
<translation id="7578104083680115302">â€Ø§Ù„دÙع سريعًا على المواقع والتطبيقات عبر الأجهزة باستخدام البطاقات التي Ø­Ùظتها ÙÙŠ Google.</translation>
<translation id="7588950540487816470">الشبكة المادية</translation>
<translation id="7592362899630581445">تنتهك شهادة الخادم القيود المÙروضة على الاسم.</translation>
+<translation id="7598391785903975535">أقل من <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">يتعذر على <ph name="HOST_NAME" /> معالجة هذا الطلب حاليًا.</translation>
<translation id="7600965453749440009">عدم الترجمة مطلقًا من اللغة <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">القيمة خارج النطاق <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">تاريخ انتهاء الصلاحية: <ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">â€Ù„ديك Ùعلاً بيانات تم تشÙيرها باستخدام نسخة أخرى من كلمة مرور حسابك ÙÙŠ Google. الرجاء إدخالها أدناه.</translation>
-<translation id="7634554953375732414">إن اتصالك بهذا الموقع ليس له خصوصية.</translation>
<translation id="7637571805876720304">â€Ù‡Ù„ تريد إزالة بطاقة الائتمان من ChromiumØŸ</translation>
<translation id="765676359832457558">إخÙاء الإعدادات المتقدمة...</translation>
<translation id="7658239707568436148">إلغاء</translation>
+<translation id="7662298039739062396">يتم التحكّم ÙÙŠ الإعداد بواسطة إحدى الإضاÙات</translation>
<translation id="7667346355482952095">الرمز المميز المعروض للسياسة خاليًا أو لا يتطابق مع الرمز المميز الحالي</translation>
<translation id="7668654391829183341">جهاز غير معروÙ</translation>
<translation id="7669271284792375604">قد يحاول المهاجمون ÙÙŠ هذا الموقع خداعك من خلال تثبيت برامج تضر بتجربة التصÙØ­ (على سبيل المثال، من خلال تغيير صÙحتك الرئيسية أو عرض إعلانات إضاÙية على المواقع التي تزورها).</translation>
<translation id="7674629440242451245">â€Ø¥Ø°Ø§ كنت مهتمًا بميزات Google الجديدة والرائعة، ÙÙŠÙمكنك تجربة قناة مطوري البرامج على chrome.com/dev.</translation>
<translation id="7682287625158474539">الشحن</translation>
+<translation id="7701040980221191251">بلا</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />متابعة إلى <ph name="SITE" /> (غير آمن)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">شهادة</translation>
+<translation id="7716147886133743102">تم الحظر من قبل المشرÙ</translation>
<translation id="7716424297397655342">لا يمكن تحميل موقع الويب هذا من ذاكرة التخزين المؤقت</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">غير Ù…Ùدار</translation>
<translation id="7755287808199759310">قد يلغي والداك الحظر لك</translation>
<translation id="7758069387465995638">ربما حظر الجدار الناري أو برامج مكاÙحة الÙيروسات الاتصال.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32 بت)</translation>
<translation id="7956713633345437162">الإشارات المرجعية على الجوال</translation>
<translation id="7961015016161918242">مطلقًا</translation>
-<translation id="7962083544045318153">معرّ٠التعطّÙÙ„ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">الترجمة من اللغة <ph name="ORIGINAL_LANGUAGE" /> إلى اللغة <ph name="TARGET_LANGUAGE" /> دومًا</translation>
<translation id="7995512525968007366">غير محدد</translation>
<translation id="800218591365569300">جرّب إغلاق علامات التبويب أو البرامج الأخرى لتÙريغ مساحة من الذاكرة.</translation>
<translation id="8012647001091218357">لم نتمكن من الوصول إلى والديك ÙÙŠ الوقت الحالي. ÙŠÙرجى إعادة المحاولة مرة أخرى.</translation>
<translation id="8025119109950072390">قد يحاول المهاجمون الموجودون على هذا الموقع Ùعل شيء خطير كتثبيت البرامج أو الكش٠عن معلوماتك الشخصية (على سبيل المثال، كلمات المرور أو أرقام الهوات٠أو بطاقات الائتمان).</translation>
-<translation id="803030522067524905">â€Ø§ÙƒØªØ´Ù التصÙØ­ الآمن من Google‬ مؤخرًا تصيّد احتيالي على <ph name="SITE" />. تتظاهر مواقع التصيّد الاحتيالي بكونها مواقع ويب أخرى للاحتيال عليك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">هذه الصÙحة باللغة <ph name="SOURCE_LANGUAGE" />. هل تريد ترجمتها إلى اللغة <ph name="TARGET_LANGUAGE" />ØŸ</translation>
+<translation id="8037357227543935929">الطلب (اÙتراضي)</translation>
<translation id="8041089156583427627">إرسال تعليقات</translation>
+<translation id="8041940743680923270">استخدام الإعداد الاÙتراضي العمومي (طلب)</translation>
<translation id="8088680233425245692">تعذّر عرض المقالة.</translation>
<translation id="8089520772729574115">أقل من ميغابايت واحدة</translation>
<translation id="8091372947890762290">التنشيط قيد الانتظار ÙÙŠ الخادم</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007">تعذر العثور على <ph name="BEGIN_ABBR" />عنوان نظام أسماء النطاقات<ph name="END_ABBR" /> للخادم <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">خضع جهاز الكمبيوتر إلى وضع السكون.</translation>
<translation id="8150722005171944719">المل٠الموجود على <ph name="URL" /> غير قابل للقراءة. ربما تمت إزالته، أو ربما تكون أذونات المل٠هي التي تمنع الدخول.</translation>
+<translation id="8184538546369750125">استخدام الإعداد الاÙتراضي العمومي (سماح)</translation>
+<translation id="8191494405820426728">معرّ٠الأعطال المحلي <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">تراجع عن ال&amp;نقل</translation>
<translation id="8201077131113104583">â€Ø¹Ù†ÙˆØ§Ù† URL لتحديث الإضاÙØ© التي تحتوي على رقم التعري٠"<ph name="EXTENSION_ID" />" غير صالح.</translation>
<translation id="8202097416529803614">ملخص الطلب</translation>
<translation id="8218327578424803826">الموقع الذي تم تعيينه:</translation>
<translation id="8225771182978767009">اختار الشخص الذي أعد جهاز الكمبيوتر حظر موقع الويب هذا.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />، <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">قد يحاول المستهدÙون الموجودون حاليًا على <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> تثبيت برامج خطيرة على جهاز الكمبيوتر التابع لك تسرق معلوماتك أو تحذÙها (على سبيل المثال، الصور وكلمات المرور والرسائل وبطاقات الائتمان).</translation>
<translation id="8241707690549784388">استخدمت الصÙحة التي تبحث عنها المعلومات التي أدخلتها وقد يؤدّي الرجوع إليها إلى تكرار جميع الإجراءات السابقة. هل تريد المتابعة؟</translation>
<translation id="8249320324621329438">تاريخ آخر عملية جلب:</translation>
<translation id="8253091569723639551">عنوان إرسال الÙواتير مطلوب</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">اتصل بمشر٠الشبكة إذا لم تكن متأكدًا مما يعنيه هذا.</translation>
<translation id="8293206222192510085">إضاÙØ© إشارة مرجعية</translation>
<translation id="8294431847097064396">المصدر</translation>
+<translation id="8306404619377842860">تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن تاريخ ووقت جهازك (<ph name="DATE_AND_TIME" />) غير صحيحين. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">أخÙقت الترجمة بسبب حدوث مشكلة ÙÙŠ الاتصال بالشبكة.</translation>
<translation id="8332188693563227489">تم رÙض الدخول إلى <ph name="HOST_NAME" />.</translation>
<translation id="834457929814110454">إذا كنت على دراية بالمخاطر التي تهدد أمانك، يمكنك <ph name="BEGIN_LINK" />زيارة هذا الموقع<ph name="END_LINK" /> قبل أن تتم إزالة البرامج الضارة.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">â€Ù„استخدام البطاقات من حسابك ÙÙŠ GoogleØŒ ÙŠÙرجى تسجيل الدخول إلى Chrome</translation>
<translation id="8488350697529856933">تنطبق على</translation>
<translation id="8498891568109133222">استغرق <ph name="HOST_NAME" /> وقتًا أطول مما يجب للاستجابة.</translation>
-<translation id="852346902619691059">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />Ø› بل إن شهادة أمانه غير موثوقة من Ù‚Ùبل نظام تشغيل جهازك. وربما يكون السبب ÙÙŠ ذلك خطأً ÙÙŠ التهيئة أو مهاجمًا يعترض اتصالك. <ph name="BEGIN_LEARN_MORE_LINK" />مزيد من المعلومات<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">عام انتهاء الصلاحية</translation>
<translation id="8543181531796978784">يمكنك <ph name="BEGIN_ERROR_LINK" />الإبلاغ عن اكتشا٠مشكلة<ph name="END_ERROR_LINK" /> أو، إذا كنت تدرك المخاطر المتعلقة بالأمان، يمكنك <ph name="BEGIN_LINK" />زيارة هذا الموقع غير الآمن<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">أخÙقت الترجمة لتعذر تحديد لغة الصÙحة.</translation>
-<translation id="8559762987265718583">تعذر إنشاء اتصال خاص بـ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> نظرًا لأن التاريخ والوقت للجهاز (<ph name="DATE_AND_TIME" />) غير صحيحين.</translation>
<translation id="8571890674111243710">جار٠ترجمة الصÙحة إلى <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">إضاÙØ© رقم هاتÙ
</translation>
@@ -821,6 +895,7 @@
<translation id="8738058698779197622">â€Ù„إنشاء اتصال آمن، Ùإنك بحاجة إلى ضبط ساعتك بشكل صحيح. وذلك لأن الشهادات التي تستخدمها مواقع الويب لتعري٠نÙسها تكون صالحة Ùقط Ù„Ùترات محددة من الوقت. Ùإذا كانت ساعة جهازك غير صحيحة، Ùلن يتمكن Chromium من التحقق من هذه الشهادات.</translation>
<translation id="8740359287975076522">â€ØªØ¹Ø°Ø± العثور على &lt;/abbr&gt;عنوان نظام أسماء النطاقات (DNS)â€&lt;abbr id="dnsDefinition"&gt; لـ <ph name="HOST_NAME" />. جار٠تشخيص المشكلة.</translation>
<translation id="8759274551635299824">هذه البطاقة منتهية الصلاحية</translation>
+<translation id="8761567432415473239">â€Ø¹Ø«Ø± â€â€«Ø§Ù„تصÙØ­ الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />على برامج ضارة<ph name="END_LINK" /> ÙÙŠ <ph name="SITE" />.</translation>
<translation id="8790007591277257123">إعادة الح&amp;Ø°Ù</translation>
<translation id="8800988563907321413">تظهر اقتراحاتك "المجاورة" هنا</translation>
<translation id="8820817407110198400">إشارات</translation>
@@ -833,29 +908,30 @@
<translation id="8870413625673593573">العناصر المغلقة مؤخرًا</translation>
<translation id="8874824191258364635">أدخÙÙ„ رقم بطاقة صحيحًا</translation>
<translation id="8876793034577346603">تعذّر تحليل تهيئة الشبكة</translation>
-<translation id="8877192140621905067">بعد تأكيدك، ستتم مشاركة تÙاصيل بطاقتك مع هذا الموقع</translation>
<translation id="8889402386540077796">تدرج اللون</translation>
<translation id="8891727572606052622">وضع الخادم الوكيل غير صالح.</translation>
<translation id="889901481107108152">عذرًا، هذه التجربة غير متاحة على نظامك الأساسي.</translation>
<translation id="8903921497873541725">تكبير</translation>
<translation id="8931333241327730545">â€Ù‡Ù„ تريد Ø­Ùظ هذه البطاقة إلى حسابك ÙÙŠ GoogleØŸ</translation>
<translation id="8932102934695377596">توقيت ساعتك متأخر عن الوقت الحالي</translation>
-<translation id="8954894007019320973">(يتبع)</translation>
<translation id="8971063699422889582">انتهت صلاحية شهادة الخادم.</translation>
<translation id="8986494364107987395">â€Ø¥Ø±Ø³Ø§Ù„ إحصائيات الاستخدام وتقارير الأعطال إلى Google تلقائيًا</translation>
-<translation id="8987927404178983737">شهر</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" />†[<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">تحتوي مقدمة الموقع على برامج ضارة</translation>
+<translation id="8997023839087525404">قدم الخادم شهادة لم يتم الكش٠عنها علنًا باستخدام سياسة شهادة الشÙاÙية. وهذا ضروري لبعض الشهادات، لضمان أنها جديرة بالثقة ومحمية من المهاجمين.</translation>
<translation id="9001074447101275817">يتطلب الخادم الوكيل <ph name="DOMAIN" /> اسم مستخدم وكلمة مرور.</translation>
+<translation id="9005998258318286617">â€Ùشل تحميل مستند PDF.</translation>
<translation id="901974403500617787">لا يمكن تعيين العلامات التي تسري عبر النظام إلا من Ù‚Ùبل المالك: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">عنوان إرسال الÙواتير للبطاقة مطلوب</translation>
<translation id="9020542370529661692">تمت ترجمة هذه الصÙحة إلى <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">خطأ متعلق بالأمان</translation>
<translation id="9038649477754266430">استخدام إحدى خدمات التوقع لتحميل الصÙحات بسرعة أكبر</translation>
<translation id="9039213469156557790">إضاÙØ© إلى ذلك، تتضمن هذه الصÙحة موارد أخرى غير آمنة. ويستطيع الآخرون مشاهدة هذه الموارد أثناء نقلها، كما يستطيع أي مهاجم تعديلها لتغيير سلوك الصÙحة.</translation>
-<translation id="9040185888511745258">قد يحاول المهاجمون ÙÙŠ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> خداعك من خلال تثبيت برامج تضر بتجربة التصÙØ­ (على سبيل المثال، من خلال تغيير صÙحتك الرئيسية أو عرض إعلانات إضاÙية على المواقع التي تزورها).</translation>
+<translation id="9049981332609050619">لقد حاولت الوصول إلى <ph name="DOMAIN" />, ولكن الخادم قدّم شهادة غير صالحة.</translation>
<translation id="9050666287014529139">عبارة المرور</translation>
<translation id="9065203028668620118">تحرير</translation>
<translation id="9068849894565669697">اختيار اللون</translation>
+<translation id="9069693763241529744">تم الحظر بواسطة إحدى الإضاÙات</translation>
<translation id="9076283476770535406">قد يتضمن محتوى للبالغين</translation>
<translation id="9078964945751709336">مطلوب مزيد من المعلومات</translation>
<translation id="9103872766612412690">â€ÙŠØ³ØªØ®Ø¯Ù… <ph name="SITE" /> التشÙير عادة لحماية معلوماتك. عندما حاول Chromium الاتصال بموقع <ph name="SITE" /> هذه المرة، أرجَع موقع الويب بيانات اعتماد غير عادية وغير صحيحة. وقد يحدث هذا عندما يحاول أحد المهاجمين التظاهر بأنه موقع <ph name="SITE" />ØŒ أو إذا قاطعت شاشة تسجيل دخول Wi-Fi الاتصال. ولكن لا تزال معلوماتك آمنة نظرًا لأن Chromium أوقَÙÙŽ الاتصال قبل تبادل أي بيانات.</translation>
@@ -864,16 +940,21 @@
<translation id="9148507642005240123">تراجع عن ا&amp;لتحرير</translation>
<translation id="9154194610265714752">تم التحديث</translation>
<translation id="9157595877708044936">جار٠الإعداد...</translation>
+<translation id="9169664750068251925">الحظر دومًا على هذا الموقع</translation>
<translation id="9170848237812810038">&amp;إلغاء</translation>
<translation id="917450738466192189">شهادة الخادم غير صالحة.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> وخيار واحد (<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />) آخر}zero{<ph name="SHIPPING_OPTION_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> خيار آخر}two{<ph name="SHIPPING_OPTION_PREVIEW" /> وخياران (<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />) آخران}few{<ph name="SHIPPING_OPTION_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> خيارات أخرى}many{<ph name="SHIPPING_OPTION_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> خيارًا آخرًا}other{<ph name="SHIPPING_OPTION_PREVIEW" /> و<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> خيار آخر}}</translation>
<translation id="9183425211371246419">يستخدم <ph name="HOST_NAME" /> بروتوكول غير مدعوم.</translation>
<translation id="9205078245616868884">يتم تشÙير بياناتك باستخدام عبارة مرور المزامنة. أدخلها لبدء المزامنة.</translation>
<translation id="9207861905230894330">أخÙقت إضاÙØ© مقالة.</translation>
+<translation id="9219103736887031265">صور</translation>
<translation id="933612690413056017">لا يوجد اتصال بالإنترنت</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">محو النموذج</translation>
<translation id="939736085109172342">مجلد جديد</translation>
<translation id="941721044073577244">يبدو أنه ليس لديك إذن بالدخول إلى هذا الموقع</translation>
<translation id="969892804517981540">البنية الرسمية</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{بدون}=1{عنصر واحد}two{عنصران (#)}few{# عناصر}many{# عنصرًا}other{# عنصر}}</translation>
<translation id="988159990683914416">بنية المطوّÙر</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_bg.xtb b/chromium/components/strings/components_strings_bg.xtb
index f786ce8cba1..acf9186f0db 100644
--- a/chromium/components/strings/components_strings_bg.xtb
+++ b/chromium/components/strings/components_strings_bg.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Завъртане по чаÑовниковата Ñтрелка</translation>
<translation id="1038842779957582377">неизвеÑтно име</translation>
<translation id="1050038467049342496">Затворете другите приложениÑ.</translation>
-<translation id="1053591932240354961">Ð’ момента не можете да поÑетите <ph name="SITE" />, защото уебÑайтът изпрати невалидни идентификационни данни, които Google Chrome не може да обработи. Обикновено мрежовите грешки и атаки Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;ОтмÑна на добавÑнето</translation>
<translation id="10614374240317010">Ðезапазвани никога</translation>
<translation id="106701514854093668">ÐаÑтолни отметки</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Кешът на правилото е в добро ÑÑŠÑтоÑние</translation>
<translation id="113188000913989374"><ph name="SITE" /> изпраща подкана:</translation>
<translation id="1132774398110320017">ÐаÑтройки за Ðвтоматично попълване в Chrome...</translation>
+<translation id="1150979032973867961">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; операционната ÑиÑтема на компютъра ви нÑма доверие на Ñертификата му за ÑигурноÑÑ‚. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="1151972924205500581">ИзиÑква Ñе парола</translation>
<translation id="1152921474424827756">Вижте <ph name="BEGIN_LINK" />кеширано копие<ph name="END_LINK" /> на <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> неочаквано прекрати връзката.</translation>
<translation id="1161325031994447685">Свържете Ñе отново Ñ Wi-Fi.</translation>
+<translation id="1165039591588034296">Грешка</translation>
<translation id="1175364870820465910">&amp;Печат...</translation>
<translation id="1181037720776840403">Премахване</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Ðвтоматично Ñъобщаване<ph name="END_WHITEPAPER_LINK" /> на Google на подробноÑти за евентуални инциденти, Ñвързани ÑÑŠÑ ÑигурноÑтта. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Още от този Ñайт</translation>
<translation id="1206967143813997005">Ðевалиден първоначален подпиÑ</translation>
<translation id="1209206284964581585">Скриване заÑега</translation>
+<translation id="121201262018556460">Ðаправихте опит да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предоÑтави Ñертификат, Ñъдържащ Ñлаб ключ. Възможно е извършител на атака да е пробил Ð»Ð¸Ñ‡Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ и Ñървърът да не е този, който очаквате (възможно е да Ñте Ñе Ñвързали Ñ Ð¸Ð·Ð²ÑŠÑ€ÑˆÐ¸Ñ‚ÐµÐ» на атака).</translation>
<translation id="1219129156119358924">СигурноÑÑ‚ на ÑиÑтемата</translation>
<translation id="1227224963052638717">ÐеизвеÑтно правило.</translation>
<translation id="1227633850867390598">Скриване на ÑтойноÑтта</translation>
<translation id="1228893227497259893">Грешен идентификатор на обект</translation>
<translation id="1232569758102978740">Ðеозаглавен</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (Ñинхронизирани)</translation>
<translation id="1263231323834454256">СпиÑък за четене</translation>
<translation id="1264126396475825575">Сигнал за Ñрив, запиÑан в/ъв <ph name="CRASH_TIME" /> (още не е качен или пренебрегнат)</translation>
+<translation id="1281526147609854549">Издадено от <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Блокирахме опаÑно Ñъдържание</translation>
<translation id="1285320974508926690">Този Ñайт да не Ñе превежда никога</translation>
<translation id="129553762522093515">ÐаÑкоро затворени</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Опитайте да изчиÑтите „биÑквитките“ Ñи<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">ÐктивноÑтта ви <ph name="BEGIN_EMPHASIS" />може да оÑтане видима<ph name="END_EMPHASIS" /> за:
+<ph name="BEGIN_LIST" />
+<ph name="LIST_ITEM" />уебÑайтовете, които поÑещавате;
+<ph name="LIST_ITEM" />Ñ€Ð°Ð±Ð¾Ñ‚Ð¾Ð´Ð°Ñ‚ÐµÐ»Ñ Ð²Ð¸ или учебното ви заведение;
+<ph name="LIST_ITEM" />доÑтавчика ви на интернет уÑлуги.
+<ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Домейн за запиÑване:</translation>
<translation id="1340482604681802745">ÐÐ´Ñ€ÐµÑ Ð·Ð° вземане</translation>
<translation id="1344211575059133124">Изглежда, че Ñе нуждаете от разрешение, за да поÑетите този Ñайт</translation>
<translation id="1344588688991793829">ÐаÑтройки за Ðвтоматично попълване в Chromium...</translation>
+<translation id="1348198688976932919">Ðа хоризонта Ñе задава Ñайт Ñ Ð¾Ð¿Ð°Ñни приложениÑ</translation>
<translation id="1374468813861204354">предложениÑ</translation>
<translation id="1375198122581997741">Ð’Ñичко за верÑиÑта</translation>
<translation id="1377321085342047638">№ на картата</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> не изпрати данни.</translation>
<translation id="1407135791313364759">ОтварÑне на вÑички</translation>
<translation id="1413809658975081374">Грешка, Ñвързана в поверителноÑтта</translation>
+<translation id="14171126816530869">СамоличноÑтта на <ph name="ORGANIZATION" /> от <ph name="LOCALITY" /> е проверена от <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Да</translation>
<translation id="1430915738399379752">Печат</translation>
-<translation id="1442912890475371290">Блокиран бе опит за <ph name="BEGIN_LINK" />поÑещение на Ñтраница от <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Ð’ момента не можете да поÑетите <ph name="SITE" />, защото уебÑайтът използва фикÑиране на Ñертификатите. Обикновено мрежовите грешки и атаки Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Показване на запазено копие на тази Ñтраница (за което е извеÑтно, че не е актуално).</translation>
<translation id="1517433312004943670">ТелефонниÑÑ‚ номер е задължителен</translation>
<translation id="1519264250979466059">Дата на верÑиÑта</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">ТрÑбва да активирате JavaScript, за да използвате тази функциÑ.</translation>
<translation id="1555130319947370107">Ñиньо</translation>
<translation id="1559528461873125649">ÐÑма такъв файл или директориÑ</translation>
-<translation id="1559572115229829303">&lt;p&gt;Ðе може да Ñе уÑтанови чаÑтна връзка Ñ/ÑŠÑ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и чаÑÑŠÑ‚ на уÑтройÑтвото ви (<ph name="DATE_AND_TIME" />) Ñа неправилни.&lt;/p&gt;
-
-&lt;p&gt;МолÑ, коригирайте датата и чаÑа от ÑекциÑта &lt;strong&gt;General&lt;/strong&gt; на приложението &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Възникна проблем при показването на тази уеб Ñтраница.</translation>
<translation id="1592005682883173041">ДоÑтъп до локални данни</translation>
+<translation id="1594030484168838125">Избор</translation>
<translation id="161042844686301425">Ñиньозелено</translation>
+<translation id="1620510694547887537">Камера</translation>
<translation id="1629803312968146339">ИÑкате ли Chrome да запази тази карта?</translation>
<translation id="1639239467298939599">Зарежда Ñе</translation>
<translation id="1640180200866533862">Правила за потребителите</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">КонфигурациÑта на мрежата е невалидна и не можа да Ñе импортира.</translation>
<translation id="1644574205037202324">ИÑториÑ</translation>
<translation id="1645368109819982629">Ðеподдържан протокол</translation>
+<translation id="1655462015569774233">{1,plural, =1{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е изтекъл вчера. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. ПонаÑтоÑщем чаÑовникът на компютъра ви показва <ph name="CURRENT_DATE" />. Това изглежда ли правилно? Ðко не е, Ñ‚Ñ€Ñбва да Ñверите ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ñ‡Ð°Ñовник и Ñлед това да опреÑните Ñтраницата.}other{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е изтекъл преди # дни. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. ПонаÑтоÑщем чаÑовникът на компютъра ви показва <ph name="CURRENT_DATE" />. Това изглежда ли правилно? Ðко не е, Ñ‚Ñ€Ñбва да Ñверите ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ñ‡Ð°Ñовник и Ñлед това да опреÑните Ñтраницата.}}</translation>
<translation id="1656489000284462475">Вземане</translation>
<translation id="1663943134801823270">Картите и адреÑите Ñа от Chrome. Можете да ги управлÑвате от <ph name="BEGIN_LINK" />наÑтройките<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Обикновено <ph name="SITE" /> използва шифроване за защита на информациÑта ви. Когато Google Chrome опита да уÑтанови връзка Ñ/ÑŠÑ <ph name="SITE" /> този път, уебÑайтът върна необичайни и неправилни идентификационни данни. Това може да Ñе Ñлучи, когато извършител на атака пробва да Ñе предÑтави за <ph name="SITE" /> или връзката е прекъÑната от екран за вход в Wi-Fi. ИнформациÑта ви продължава да е защитена, тъй като Chrome ÑÐ¿Ñ€Ñ Ð²Ñ€ÑŠÐ·ÐºÐ°Ñ‚Ð°, преди да бъдат обменени данни.</translation>
-<translation id="168328519870909584">ПонаÑтоÑщем извършители на атака Ñрещу <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> може да опитат да инÑталират опаÑни Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° уÑтройÑтвото ви, които крадат или изтриват Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (например Ñнимки, пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ номера на кредитни карти).</translation>
<translation id="168841957122794586">Сертификатът на Ñървъра Ñъдържа Ñлаб криптографÑки ключ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е от утре. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака.}other{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е от # дни в бъдещето. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака.}}</translation>
<translation id="1710259589646384581">ОС</translation>
<translation id="1721312023322545264">Ðеобходимо ви е разрешение от <ph name="NAME" />, за да поÑетите този Ñайт</translation>
<translation id="1721424275792716183">* Полето е задължително</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">ИзтеглÑне на Ñтраницата по-къÑно</translation>
<translation id="17513872634828108">Отворени раздели</translation>
<translation id="1753706481035618306">Ðомер на Ñтраницата</translation>
+<translation id="1763864636252898013">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; операционната ÑиÑтема на уÑтройÑтвото ви нÑма доверие на Ñертификата му за ÑигурноÑÑ‚. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Опитайте да Ñтартирате мрежова диагноÑтика в Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">МолÑ, актуализирайте пропуÑка Ñи за Ñинхронизиране.</translation>
<translation id="1787142507584202372">Тук ще Ñе показват отворените ви раздели</translation>
+<translation id="1789575671122666129">ИзÑкачащи прозорци</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Име на титулÑÑ€Ñ Ð½Ð° картата</translation>
-<translation id="1803678881841855883">Google БезопаÑно Ñърфиране наÑкоро <ph name="BEGIN_LINK" />откри злонамерен Ñофтуер<ph name="END_LINK" /> на <ph name="SITE" />. УебÑайтовете, които обикновено Ñа безопаÑни, понÑкога Ñе заразÑват Ñ Ñ‚Ð°ÐºÑŠÐ² Ñофтуер. Източникът на Ñъответното Ñъдържание е <ph name="SUBRESOURCE_HOST" /> – извеÑтен разпроÑтранител на злонамерен Ñофтуер. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Добавено: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">ЗаÑвката или параметрите й Ñа невалидни</translation>
<translation id="1826516787628120939">Извършва Ñе проверка</translation>
<translation id="1834321415901700177">Този Ñайт Ñъдържа опаÑни програми</translation>
+<translation id="1840414022444569775">Този номер на карта вече Ñе използва</translation>
<translation id="1842969606798536927">Плащане</translation>
<translation id="1871208020102129563">За прокÑи Ñървъра е зададено да използва фикÑирани прокÑи Ñървъри, а не URL Ð°Ð´Ñ€ÐµÑ Ð½Ð° Ñкрипт във формат .pac.</translation>
<translation id="1871284979644508959">Задължително поле</translation>
<translation id="187918866476621466">ОтварÑне на Ñтраниците при Ñтартиране</translation>
<translation id="1883255238294161206">Свиване на ÑпиÑъка</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Филтриране</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{ÐÑма}=1{1 Ñайт}other{# Ñайта}}</translation>
<translation id="194030505837763158">Към <ph name="LINK" /></translation>
<translation id="1962204205936693436">Отметки от <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Грешка при Ñериализирането</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Бе пренебрегнато, защото бе отменено от <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">ТърÑÑÑ‚ Ñе намиращи Ñе в близоÑÑ‚ Ñтраници във ФизичеÑката мрежа</translation>
<translation id="213826338245044447">Мобилни отметки</translation>
-<translation id="2148716181193084225">ДнеÑ</translation>
+<translation id="2147827593068025794">Синхронизиране на заден план</translation>
<translation id="2154054054215849342">Синхронизирането не е налице за Ð²ÑŠÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ñ‚ Ð²Ð°Ñ Ð´Ð¾Ð¼ÐµÐ¹Ð½</translation>
<translation id="2154484045852737596">Редактиране на картата</translation>
<translation id="2166049586286450108">Пълен админиÑтраторÑки доÑтъп</translation>
<translation id="2166378884831602661">Този Ñайт не може да оÑигури защитена връзка</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адреÑ}other{# адреÑа}}</translation>
+<translation id="2187317261103489799">Откриване (по подразбиране)</translation>
<translation id="2202020181578195191">Въведете валидна година на изтичане</translation>
<translation id="2212735316055980242">Правилото не е намерено</translation>
<translation id="2213606439339815911">ЗапиÑите Ñе извличат...</translation>
+<translation id="2218879909401188352">ПонаÑтоÑщем извършители на атака Ñрещу <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могат да инÑталират опаÑни приложениÑ, които да повредÑÑ‚ уÑтройÑтвото ви, да добавÑÑ‚ Ñкрити такÑи към Ñметката ви за мобилни уÑлуги или да откраднат личната ви информациÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Поправете връзката Ñи поÑредÑтвом <ph name="BEGIN_LINK" />приложението за диагноÑтика<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Изпращане Ñега</translation>
<translation id="225207911366869382">СтойноÑтта е оттеглена за това правило.</translation>
<translation id="2262243747453050782">HTTP грешка</translation>
+<translation id="2270484714375784793">Телефонен номер</translation>
<translation id="2282872951544483773">ЕкÑперименти, които не Ñа налице</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> елемент}other{<ph name="ITEM_COUNT" /> елемента}}</translation>
<translation id="2292556288342944218">ДоÑтъпът ви до интернет е блокиран</translation>
<translation id="230155334948463882">Ðова карта?</translation>
-<translation id="2305919008529760154">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Възможно е Ñертификатът му за ÑигурноÑÑ‚ да е издаден измамничеÑки. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">ИзиÑкват Ñе потребителÑко име и парола за <ph name="DOMAIN" />.</translation>
-<translation id="2318774815570432836">Ð’ момента не можете да поÑетите <ph name="SITE" />, защото уебÑайтът използва HSTS. Обикновено мрежовите грешки и атаки Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">ÐаÑтройката Ñе контролира от админиÑтратора ви</translation>
<translation id="2354001756790975382">Други отметки</translation>
+<translation id="2354430244986887761">Google БезопаÑно Ñърфиране наÑкоро <ph name="BEGIN_LINK" />откри опаÑни приложениÑ<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Извършители на атаки може да Ñа в ÑÑŠÑтоÑние да видÑÑ‚ изображениÑта, които преглеждате на този Ñайт, и да ви подведат, като ги променÑÑ‚.</translation>
+<translation id="2356070529366658676">Попитайте ме</translation>
+<translation id="2359629602545592467">ÐÑколко</translation>
<translation id="2359808026110333948">Ðапред</translation>
<translation id="2365563543831475020">Сигналът за Ñрив, запиÑан в/ъв <ph name="CRASH_TIME" />, не бе качен</translation>
<translation id="2367567093518048410">Ðиво</translation>
-<translation id="2371153335857947666">{1,plural, =1{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е изтекъл вчера. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. ПонаÑтоÑщем чаÑовникът на компютъра ви показва <ph name="CURRENT_DATE" />. Това изглежда ли правилно? Ðко не е, Ñ‚Ñ€Ñбва да Ñверите ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ñ‡Ð°Ñовник и Ñлед това да опреÑните Ñтраницата. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.}other{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е изтекъл преди # дни. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. ПонаÑтоÑщем чаÑовникът на компютъра ви показва <ph name="CURRENT_DATE" />. Това изглежда ли правилно? Ðко не е, Ñ‚Ñ€Ñбва да Ñверите ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ñ‡Ð°Ñовник и Ñлед това да опреÑните Ñтраницата. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">ÐÑма алтернативи на потребителÑÐºÐ¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ</translation>
<translation id="2384307209577226199">Зададено по подразбиране в корпоративна Ñреда</translation>
<translation id="2386255080630008482">Сертификатът на Ñървъра е анулиран.</translation>
<translation id="2392959068659972793">Да Ñе показват правилата без зададена ÑтойноÑÑ‚</translation>
<translation id="239429038616798445">Този начин на доÑтавка не Ñе поддържа. Опитайте Ñ Ð´Ñ€ÑƒÐ³.</translation>
<translation id="2396249848217231973">&amp;ОтмÑна на изтриването</translation>
-<translation id="2460160116472764928">Google БезопаÑно Ñърфиране наÑкоро <ph name="BEGIN_LINK" />откри злонамерен Ñофтуер<ph name="END_LINK" /> на <ph name="SITE" />. УебÑайтовете, които обикновено Ñа безопаÑни, понÑкога Ñе заразÑват Ñ Ñ‚Ð°ÐºÑŠÐ² Ñофтуер. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; възможно е Ñертификатът му за ÑигурноÑÑ‚ да е оттеглен. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="2463739503403862330">Попълване</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Стартирайте мрежова диагноÑтика<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Ðевалиден URL Ð°Ð´Ñ€ÐµÑ Ð·Ð° Ñ‚ÑŠÑ€Ñене.</translation>
+<translation id="2482878487686419369">ИзвеÑтиÑ</translation>
<translation id="2491120439723279231">Сертификатът на Ñървъра Ñъдържа грешки.</translation>
<translation id="2495083838625180221">Синтактичен анализ на JSON</translation>
<translation id="2495093607237746763">Ðко поÑтавите отметка, Chromium ще ÑъхранÑва на това уÑтройÑтво копие на картата ви Ñ Ñ†ÐµÐ» по-бързо попълване на формулÑри.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Ðазад</translation>
<translation id="2515629240566999685">Проверете Ñигнала в района.</translation>
<translation id="2516305470678292029">Ðлтернативи на потребителÑÐºÐ¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ</translation>
+<translation id="2539524384386349900">Откриване</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> изпрати невалиден отговор.</translation>
-<translation id="2552545117464357659">По-нова</translation>
<translation id="2556876185419854533">&amp;ОтмÑна на редактирането</translation>
<translation id="2587730715158995865">От <ph name="ARTICLE_PUBLISHER" />. Прочетете тази и още <ph name="OTHER_ARTICLE_COUNT" /> Ñтатии.</translation>
<translation id="2587841377698384444">ID на API за директории:</translation>
<translation id="2597378329261239068">Този документ е защитен Ñ Ð¿Ð°Ñ€Ð¾Ð»Ð°. МолÑ, въведете Ñ.</translation>
<translation id="2609632851001447353">Вариации</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{ÐÑма}=1{1 приложение ($1)}=2{2 Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2)}other{# Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">ЧаÑовникът ви е напред</translation>
<translation id="2639739919103226564">СъÑтоÑние:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ДоÑтъпът до файла бе отказан</translation>
<translation id="2653659639078652383">Изпращане</translation>
<translation id="2666117266261740852">Затворете другите раздели или приложениÑ.</translation>
+<translation id="2670429602441959756">Тази Ñтраница Ñъдържа функции, които още не Ñе поддържат във VR. Режимът Ñе затварÑ...</translation>
<translation id="2674170444375937751">ÐаиÑтина ли иÑкате да изтриете тези Ñтраници от иÑториÑта Ñи?</translation>
<translation id="2677748264148917807">Излизане</translation>
-<translation id="269990154133806163">Сървърът предоÑтави Ñертификат, който не е разкрит публично чрез правило в ПрозрачноÑÑ‚ на Ñертификатите. Това Ñе изиÑква за нÑкои Ñертификати Ñ Ñ†ÐµÐ» защита Ñрещу хакери и за да е Ñигурно, че Ñа надеждни. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">СпиÑък за четене</translation>
<translation id="2704283930420550640">СтойноÑтта не ÑъответÑтва на формата.</translation>
<translation id="2704951214193499422">Chromium не можа да потвърди картата ви. МолÑ, опитайте отново по-къÑно.</translation>
<translation id="2705137772291741111">Запазеното (кеширано) копие на този Ñайт не можа да Ñе прочете.</translation>
<translation id="2709516037105925701">Ðвтоматично попълване</translation>
-<translation id="2712118517637785082">Ðаправихте опит да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предoÑтави Ñертификат, анулиран от Ð¸Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ Ð¼Ñƒ. Това означава, че в никакъв Ñлучай не Ñ‚Ñ€Ñбва да Ñе доверÑвате на предÑтавените от Ñървъра идентификационни данни за ÑигурноÑÑ‚. Възможно е да Ñте Ñе Ñвързали Ñ Ð¸Ð·Ð²ÑŠÑ€ÑˆÐ¸Ñ‚ÐµÐ» на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">ИÑкане на разрешение</translation>
<translation id="2713444072780614174">бÑло</translation>
<translation id="2720342946869265578">Ð’ близоÑÑ‚</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ЛипÑващ Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° уÑтройÑтвото</translation>
<translation id="2784949926578158345">Връзката бе възÑтановена.</translation>
<translation id="2794233252405721443">Сайтът е блокиран</translation>
+<translation id="2799020568854403057">Ðа хоризонта Ñе задава Ñайт Ñ Ð¾Ð¿Ð°Ñни приложениÑ</translation>
+<translation id="2803306138276472711">Google БезопаÑно Ñърфиране наÑкоро <ph name="BEGIN_LINK" />откри злонамерен Ñофтуер<ph name="END_LINK" /> на <ph name="SITE" />. УебÑайтовете, които обикновено Ñа надеждни, понÑкога Ñе заразÑват Ñ Ð¾Ð¿Ð°Ñен Ñофтуер.</translation>
<translation id="2824775600643448204">Лента за адреÑи и за Ñ‚ÑŠÑ€Ñене</translation>
<translation id="2826760142808435982">Връзката е шифрована и удоÑтоверена поÑредÑтвом <ph name="CIPHER" /> и използва <ph name="KX" /> като механизъм за обмен на ключове.</translation>
<translation id="2835170189407361413">ИзчиÑтване на формулÑра</translation>
+<translation id="2856444702002559011">Възможно е извършители на атака да опитват да откраднат информациÑта ви от <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (например пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ номера на кредитни карти). <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Без презареждане</translation>
<translation id="2900469785430194048">Паметта на Google Chrome Ñе изчерпа, докато браузърът опитваше да покаже тази уеб Ñтраница.</translation>
<translation id="2909946352844186028">УÑтановена бе промÑна в мрежата.</translation>
<translation id="2916038427272391327">Затворете другите програми.</translation>
<translation id="2922350208395188000">Сертификатът на Ñървъра не може да бъде проверен.</translation>
<translation id="2928905813689894207">ÐÐ´Ñ€ÐµÑ Ð·Ð° фактуриране</translation>
+<translation id="2941952326391522266">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Ñертификатът му за ÑигурноÑÑ‚ е от <ph name="DOMAIN2" />. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="2948083400971632585">Можете да деактивирате вÑички конфигурирани за дадена връзка прокÑи Ñървъри от Ñтраницата „ÐаÑтройки“.</translation>
<translation id="2955913368246107853">ЗатварÑне на лентата за Ñ‚ÑŠÑ€Ñене</translation>
<translation id="2958431318199492670">КонфигурациÑта на мрежата не Ñпазва Ñтандарта на ONC. Възможно е чаÑти от Ð½ÐµÑ Ð´Ð° не Ñа импортирани.</translation>
-<translation id="29611076221683977">ПонаÑтоÑщем извършители на атака Ñрещу <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> може да опитат да инÑталират опаÑни програми на компютъра ви под Mac, които крадат или изтриват информациÑта ви (например Ñнимки, пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ номера на кредитни карти).</translation>
<translation id="2966678944701946121">ВалидноÑÑ‚: <ph name="EXPIRATION_DATE_ABBR" />. Добавено: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">За уÑтановÑване на Ñигурна връзка е необходимо чаÑовникът ви да е верен. Това е така, защото Ñертификатите, Ñ ÐºÐ¾Ð¸Ñ‚Ð¾ уебÑайтовете Ñе идентифицират, Ñа валидни Ñамо за конкретни периоди от време. Тъй като чаÑовникът на уÑтройÑтвото ви не е верен, Google Chrome не може да потвърди тези Ñертификати.</translation>
<translation id="2972581237482394796">&amp;ВъзÑтановÑване</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Въведете валиден адреÑ</translation>
<translation id="2986368408720340940">Този начин на вземане не Ñе поддържа. Опитайте Ñ Ð´Ñ€ÑƒÐ³.</translation>
<translation id="2991174974383378012">СподелÑне Ñ ÑƒÐµÐ±Ñайтове</translation>
+<translation id="2991571918955627853">Ð’ момента не можете да поÑетите <ph name="SITE" />, тъй като уебÑайтът използва HSTS. Обикновено грешките в мрежата и атаките Ñрещу Ð½ÐµÑ Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно.</translation>
<translation id="3005723025932146533">Показване на запазено копие</translation>
<translation id="3008447029300691911">Въведете кода за проверка за <ph name="CREDIT_CARD" />. След като потвърдите картата Ñи, данните за Ð½ÐµÑ Ñ‰Ðµ бъдат Ñподелени Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт.</translation>
<translation id="3010559122411665027">СпиÑъчен Ð·Ð°Ð¿Ð¸Ñ â€ž<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Ðвтоматично блокирано</translation>
<translation id="3024663005179499861">Грешен тип на правилото</translation>
<translation id="3032412215588512954">ИÑкате ли да презаредите този Ñайт?</translation>
<translation id="3037605927509011580">УжаÑ!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{поне 1 елемент на Ñинхронизирани уÑтройÑтва}=1{1 елемент (и други на Ñинхронизирани уÑтройÑтва)}other{# елемента (и други на Ñинхронизирани уÑтройÑтва)}}</translation>
<translation id="3041612393474885105">Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ñертификата</translation>
<translation id="3063697135517575841">Chrome не можа да потвърди картата ви. МолÑ, опитайте отново по-къÑно.</translation>
<translation id="3064966200440839136">Ще напуÑнете режим „инкогнито“, за да платите във външно приложение. ИÑкате ли да продължите?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{ÐÑма}=1{1 парола}other{# пароли}}</translation>
<translation id="3093245981617870298">ПонаÑтоÑщем Ñте офлайн.</translation>
<translation id="3105172416063519923">ID на актива:</translation>
<translation id="3109728660330352905">ÐÑмате Ð¿ÑŠÐ»Ð½Ð¾Ð¼Ð¾Ñ‰Ð¸Ñ Ð·Ð° преглед на тази Ñтраница.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Опитайте да Ñтартирате диагноÑтика на ÑвързаноÑтта<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Декодирането на отговора не бе уÑпешно</translation>
<translation id="3150653042067488994">Временна грешка в Ñървъра</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Страниците, които преглеждате в разделите в режим „инкогнито“, нÑма да оÑтанат в иÑториÑта на браузъра, хранилището за „биÑквитки“ или иÑториÑта на Ñ‚ÑŠÑ€Ñенето, Ñлед като затворите вÑички раздели в този режим. Изтеглените от Ð²Ð°Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ или Ñъздадените от Ð²Ð°Ñ Ð¾Ñ‚Ð¼ÐµÑ‚ÐºÐ¸ обаче ще бъдат запазени.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ОÑтров</translation>
+<translation id="317583078218509884">Ðовите наÑтройки за разрешениÑта за Ñайтове ще влÑзат в Ñила Ñлед презареждането на Ñтраницата.</translation>
<translation id="3176929007561373547">За да Ñе уверите, че прокÑи Ñървърът работи,
проверете наÑтройките му или Ñе Ñвържете ÑÑŠÑ ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ñи админиÑтратор. Ðко ÑмÑтате, че не Ñ‚Ñ€Ñбва
да използвате прокÑи Ñървър:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Отворете Ñтраницата в режим „инкогнито“.</translation>
-<translation id="3202578601642193415">Ðай-нова</translation>
+<translation id="320323717674993345">Ðнулиране на плащането</translation>
<translation id="3207960819495026254">С отметка</translation>
+<translation id="3225919329040284222">Сървърът предоÑтави Ñертификат, който не ÑъответÑтва на вградените очакваниÑ. Те Ñа включени за определени уебÑайтове Ñ Ð³Ð¾Ð»Ñма Ñтепен на ÑигурноÑÑ‚, за да ви предпазим.</translation>
<translation id="3226128629678568754">ÐатиÑнете бутона за презареждане, за да изпратите отново данните, необходими за отварÑнето на Ñтраницата.</translation>
+<translation id="3227137524299004712">Микрофон</translation>
<translation id="3228969707346345236">Преводът не бе уÑпешен, защото Ñтраницата вече е на <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Въведете кода за проверка за <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Важното Ñъдържание на този Ñайт да Ñе открива винаги</translation>
<translation id="3254409185687681395">Запазване на отметка към тази Ñтраница</translation>
<translation id="3270847123878663523">&amp;ОтмÑна на пренареждането</translation>
<translation id="3282497668470633863">ДобавÑне на името на картодържателÑ</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">наÑтройки</translation>
<translation id="3345135638360864351">ЗаÑвката ви за доÑтъп до този Ñайт не можа да Ñе изпрати до <ph name="NAME" />. МолÑ, опитайте отново.</translation>
<translation id="3355823806454867987">ПромÑна на наÑтройките на прокÑи Ñървъра...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />нÑма да ÑъхранÑва<ph name="END_EMPHASIS" /> Ñледната информациÑ:
+<ph name="BEGIN_LIST" />
+<ph name="LIST_ITEM" />иÑториÑта на Ñърфирането ви;
+<ph name="LIST_ITEM" />„биÑквитките“ и данните за Ñайтове;
+<ph name="LIST_ITEM" />въведените във формулÑри данни.
+<ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Грешка в чаÑовника</translation>
-<translation id="337311366426640088">Още <ph name="ITEM_COUNT" /> елемента...</translation>
<translation id="337363190475750230">Обезпечаването е отменено</translation>
<translation id="3377188786107721145">Грешка при ÑÐ¸Ð½Ñ‚Ð°ÐºÑ‚Ð¸Ñ‡Ð½Ð¸Ñ Ð°Ð½Ð°Ð»Ð¸Ð· на правилото</translation>
<translation id="3380365263193509176">ÐеизвеÑтна грешка</translation>
<translation id="3380864720620200369">Идент. â„– на клиентÑката програма:</translation>
<translation id="3391030046425686457">ÐÐ´Ñ€ÐµÑ Ð·Ð° бърза доÑтавка</translation>
<translation id="3395827396354264108">Ðачин на вземане</translation>
-<translation id="340013220407300675">Възможно е извършители на атака да опитват да откраднат ваша Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (например пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ данни за кредитни карти).</translation>
<translation id="3422248202833853650">Затворете другите програми, за да оÑвободите памет.</translation>
<translation id="3422472998109090673">ПонаÑтоÑщем нÑма доÑтъп до <ph name="HOST_NAME" />.</translation>
+<translation id="3427092606871434483">Разрешаване (по подразбиране)</translation>
<translation id="3427342743765426898">&amp;ВъзÑтановÑване на редактирането</translation>
<translation id="3431636764301398940">Запазване на картата на това уÑтройÑтво</translation>
<translation id="3435896845095436175">Ðктивиране</translation>
<translation id="3447661539832366887">СобÑтвеникът на това уÑтройÑтво е изключил играта Ñ Ð´Ð¸Ð½Ð¾Ð·Ð°Ð²ÑŠÑ€Ð°.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Интервал на извличане:</translation>
<translation id="3462200631372590220">Скриване на подробноÑтите</translation>
<translation id="3467763166455606212">ТрÑбва да въведете името на титулÑÑ€Ñ Ð½Ð° картата</translation>
<translation id="3478058380795961209">МеÑец на валидноÑÑ‚</translation>
<translation id="3479539252931486093">Това неочаквано ли беше? <ph name="BEGIN_LINK" />Уведомете ни<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ðе Ñега</translation>
-<translation id="348000606199325318">Идентификатор на Ñрива: <ph name="CRASH_LOCAL_ID" /> (Идентификатор на Ñървъра: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Ðе можахме да Ñе Ñвържем Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ Ð²Ð¸. МолÑ, опитайте отново.</translation>
<translation id="3528171143076753409">Сертификатът на Ñървъра не е надежден.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Поне 1 елемент на Ñинхронизирани уÑтройÑтва}=1{1 елемент (и други на Ñинхронизирани уÑтройÑтва)}other{# елемента (и други на Ñинхронизирани уÑтройÑтва)}}</translation>
<translation id="3539171420378717834">СъхранÑване на копие на картата на това уÑтройÑтво</translation>
<translation id="3542684924769048008">Използване на паролата за:</translation>
+<translation id="3545341443414427877">Ðе може да Ñе уÑтанови чаÑтна връзка ÑÑŠÑ Ñайта <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и чаÑÑŠÑ‚ на компютъра ви (<ph name="DATE_AND_TIME" />) Ñа неправилни. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Ð’Ñички Ñинхронизирани данни да Ñе шифроват ÑÑŠÑ ÑобÑÑ‚Ð²ÐµÐ½Ð¸Ñ Ð²Ð¸ пропуÑк за Ñинхронизиране</translation>
-<translation id="3549761410225185768">Още <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е от <ph name="DOMAIN2" />. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Мениджърът ви може да го отблокира за ваÑ</translation>
<translation id="3566021033012934673">Връзката ви не е поверителна</translation>
+<translation id="3569145463236695319">&lt;p&gt;Ðе може да Ñе уÑтанови чаÑтна връзка ÑÑŠÑ Ñайта <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и чаÑÑŠÑ‚ на уÑтройÑтвото ви (<ph name="DATE_AND_TIME" />) Ñа неправилни.&lt;/p&gt;
+
+&lt;p&gt;МолÑ, коригирайте датата и чаÑа от ÑекциÑта &lt;strong&gt;General&lt;/strong&gt; на приложението &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Добавете име</translation>
<translation id="3583757800736429874">&amp;ВъзÑтановÑване на премеÑтването</translation>
<translation id="3586931643579894722">Скриване на подробноÑтите</translation>
-<translation id="3587482841069643663">Ð’Ñички</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Въведете валидна дата на изтичане</translation>
<translation id="36224234498066874">ИзчиÑтване на данните за Ñърфирането...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ñертификата</translation>
<translation id="3690164694835360974">Страницата за вход не е защитена</translation>
<translation id="3693415264595406141">Парола:</translation>
-<translation id="3696411085566228381">нÑма</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> „<ph name="TITLE" />“ <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Зарежда Ñе...</translation>
<translation id="3712624925041724820">Лицензите Ñа изчерпани</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Проверете конфигурациÑта на прокÑи Ñървъра, защитната Ñтена и DNS<ph name="END_LINK" />.</translation>
<translation id="3736520371357197498">Ðко разбирате риÑковете за ÑигурноÑтта Ñи, може <ph name="BEGIN_LINK" />да поÑетите този ненадежден Ñайт<ph name="END_LINK" /> преди премахването на опаÑните програми.</translation>
<translation id="3739623965217189342">Копирана от Ð²Ð°Ñ Ð²Ñ€ÑŠÐ·ÐºÐ°</translation>
+<translation id="3744899669254331632">Ð’ момента не можете да поÑетите <ph name="SITE" />, защото уебÑайтът изпрати кодирани идентификационни данни, които Chromium не може да обработи. Обикновено грешките в мрежата и атаките Ñрещу Ð½ÐµÑ Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно.</translation>
+<translation id="3748148204939282805">Извършители на атака, използващи <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, може да ви подведат да направите нещо опаÑно, като например да инÑталирате Ñофтуер или да разкриете лична Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (например пароли, телефонни номера или номера на кредитни карти). <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Преводът не бе уÑпешен поради грешка в Ñървъра.</translation>
<translation id="3759461132968374835">ÐаÑкоро не Ñте Ñъобщавали за Ñривове. Тези, възникнали при деактивирано изпращане на Ñигнали за Ñривове, не Ñе показват тук.</translation>
+<translation id="3778403066972421603">ИÑкате ли тази карта да Ñе запази на уÑтройÑтвото и в профила ви в Google?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Изтича на <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Ðко използвате прокÑи Ñървър...</translation>
<translation id="3828924085048779000">Ðе може пропуÑкът да не Ñе попълни.</translation>
-<translation id="3845539888601087042">Показва Ñе иÑториÑта от уÑтройÑтвата, на които Ñте влезли в профила Ñи. <ph name="BEGIN_LINK" />Ðаучете повече<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Ðазад</translation>
<translation id="3858027520442213535">Ðктуализиране на датата и чаÑа</translation>
<translation id="3884278016824448484">ИдентификационниÑÑ‚ номер на уÑтройÑтвото е неÑъвмеÑтим</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">ЗаÑвката ви за доÑтъп до този Ñайт бе изпратена до <ph name="NAME" /></translation>
<translation id="3890664840433101773">ДобавÑне на имейл адреÑ</translation>
<translation id="3901925938762663762">Картата е Ñ Ð¸Ð·Ñ‚ÐµÐºÐ»Ð° валидноÑÑ‚</translation>
-<translation id="3933571093587347751">{1,plural, =1{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е от утре. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.}other{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ е от # дни в бъдещето. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF документът не уÑÐ¿Ñ Ð´Ð° Ñе зареди</translation>
+<translation id="3945915738023014686">Идентификатор на ÐºÐ°Ñ‡ÐµÐ½Ð¸Ñ Ñигнал за Ñрив: <ph name="CRASH_ID" /> (локален идентификатор на Ñрива: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Ð’ Ñертификата му за ÑигурноÑÑ‚ не Ñа поÑочени алтернативни имена на обекта. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от извършител на атака.</translation>
<translation id="3963721102035795474">Режим за четене</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{ÐÑма}=1{От 1 Ñайт }other{От # Ñайта }}</translation>
<translation id="397105322502079400">ИзчиÑлÑва Ñе...</translation>
<translation id="3973234410852337861">ХоÑÑ‚ÑŠÑ‚ <ph name="HOST_NAME" /> е блокиран</translation>
+<translation id="3987940399970879459">По-малко от 1 МБ</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 уеб Ñтраница в близоÑÑ‚}other{# уеб Ñтраници в близоÑÑ‚}}</translation>
<translation id="4021036232240155012">DNS е уÑлугата за мрежи, коÑто преобразува имената на уебÑайтовете към техните адреÑи в интернет.</translation>
<translation id="4030383055268325496">&amp;ОтмÑна на добавÑнето</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">За конфигурациÑта на прокÑи Ñървъра е зададено да използва URL Ð°Ð´Ñ€ÐµÑ Ð½Ð° Ñкрипт във формат .pac, а не фикÑирани прокÑи Ñървъри.</translation>
<translation id="4098354747657067197">Ðа хоризонта Ñе задава измамен Ñайт</translation>
<translation id="4103249731201008433">СерийниÑÑ‚ номер на уÑтройÑтвото е невалиден</translation>
+<translation id="410351446219883937">Ðвтоматично възпроизвеждане</translation>
<translation id="4103763322291513355">ПоÑетете &lt;strong&gt;chrome://policy&lt;/strong&gt;, за да видите изброени URL адреÑите в Ñ‡ÐµÑ€Ð½Ð¸Ñ ÑпиÑък и другите правила, наложени от ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ð²Ð¸ админиÑтратор.</translation>
-<translation id="4110615724604346410">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ Ñъдържа грешки. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">пурпурно</translation>
+<translation id="4116663294526079822">Разрешаване винаги на този Ñайт</translation>
<translation id="4117700440116928470">Обхватът на правилата не Ñе поддържа.</translation>
-<translation id="4118212371799607889">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ не Ñе Ñчита за надежден от Chromium. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{още 1 елемент}other{още # елемента}}</translation>
<translation id="4130226655945681476">Проверете мрежовите кабели, модема и маршрутизатора.</translation>
+<translation id="413544239732274901">Ðаучете повече</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Използване на глобалната Ñтандартна ÑтойноÑÑ‚ (Откриване)</translation>
+<translation id="4165986682804962316">ÐаÑтройки за Ñайта</translation>
<translation id="4169947484918424451">ИÑкате ли Chromium да запази тази карта?</translation>
<translation id="4171400957073367226">Ðевалиден Ð¿Ð¾Ð´Ð¿Ð¸Ñ Ð·Ð° потвърждаване</translation>
<translation id="4196861286325780578">&amp;ВъзÑтановÑване на премеÑтването</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Проверете конфигурациÑта на защитната Ñтена и антивируÑÐ½Ð¸Ñ Ñофтуер<ph name="END_LINK" />.</translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{нÑма}=1{1 приложение ($1)}=2{2 Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2)}other{# Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Сривове</translation>
+<translation id="422022731706691852">Извършители на атаки, използващи <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, може да опитат да ви подведат да инÑталирате програми, които вредÑÑ‚ на практичеÑката ви работа при Ñърфиране (например като променÑÑ‚ началната ви Ñтраница или показват допълнителни реклами в поÑещаваните от Ð²Ð°Ñ Ñайтове). <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Опитайте да Ñтартирате мрежова диагноÑтика<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Валиден Ñертификат</translation>
<translation id="4250431568374086873">Връзката ви Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт не е напълно защитена</translation>
<translation id="4250680216510889253">Ðе</translation>
<translation id="425582637250725228">Ðаправените от Ð²Ð°Ñ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸ може да не Ñе запазÑÑ‚.</translation>
<translation id="4258748452823770588">Ðевалиден подпиÑ</translation>
+<translation id="4265872034478892965">Разрешено от админиÑтратора ви</translation>
<translation id="4269787794583293679">(ÐÑма потребителÑко име)</translation>
<translation id="4275830172053184480">РеÑтартиране на уÑтройÑтвото ви</translation>
<translation id="4280429058323657511">, изтича: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google БезопаÑно Ñърфиране наÑкоро <ph name="BEGIN_LINK" />намери опаÑни програми<ph name="END_LINK" /> на <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">ОÑновни предложениÑ</translation>
<translation id="4304224509867189079">Вход</translation>
-<translation id="432290197980158659">Сървърът предоÑтави Ñертификат, който не ÑъответÑтва на вградените очакваниÑ. С цел ваша защита те Ñа включени за определени уебÑайтове Ñ Ð³Ð¾Ð»Ñма Ñтепен на ÑигурноÑÑ‚. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Блокиране (по подразбиране)</translation>
<translation id="4325863107915753736">Ðамирането на ÑтатиÑта не бе уÑпешно</translation>
<translation id="4326324639298822553">Проверете датата на валидноÑÑ‚ и опитайте отново</translation>
<translation id="4331708818696583467">ÐÑма защита</translation>
<translation id="4356973930735388585">Извършители на атака, използващи този Ñайт, може да опитат да инÑталират опаÑни програми на компютъра ви, които крадат или изтриват информациÑта ви (например Ñнимки, пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ номера на кредитни карти).</translation>
<translation id="4372948949327679948">Очаквана е ÑтойноÑÑ‚ от тип <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Ðаправихте опит да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предoÑтави Ñертификат, анулиран от Ð¸Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ Ñи. Това означава, че в никакъв Ñлучай не Ñ‚Ñ€Ñбва да Ñе доверÑвате на предÑтавените от Ñървъра идентификационни данни за ÑигурноÑÑ‚. Възможно е да Ñте Ñе Ñвързали Ñ Ð¸Ð·Ð²ÑŠÑ€ÑˆÐ¸Ñ‚ÐµÐ» на атака.</translation>
<translation id="4381091992796011497">ПотребителÑко име:</translation>
<translation id="4394049700291259645">Деактивиране</translation>
<translation id="4406896451731180161">резултата от Ñ‚ÑŠÑ€Ñенето</translation>
+<translation id="4424024547088906515">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Chrome нÑма доверие на Ñертификата му за ÑигурноÑÑ‚. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> не прие Ñертификата ви за вход или е възможно да не е предоÑтавен такъв.</translation>
<translation id="443673843213245140">Използването на прокÑи Ñървър е деактивирано, но е поÑочена изрична негова конфигурациÑ.</translation>
-<translation id="4492190037599258964">Резултати от Ñ‚ÑŠÑ€Ñенето на „<ph name="SEARCH_STRING" />“</translation>
<translation id="4506176782989081258">Грешка при потвърждаването: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Свържете Ñе ÑÑŠÑ ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратор.</translation>
<translation id="450710068430902550">СподелÑне Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратор</translation>
<translation id="4515275063822566619">Картите и адреÑите Ñа от Chrome и профила ви в Google (<ph name="ACCOUNT_EMAIL" />). Можете да ги управлÑвате от <ph name="BEGIN_LINK" />наÑтройките<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">ПодробноÑти</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Опитайте да деактивирате разширениÑта.</translation>
<translation id="457875822857220463">Бърза доÑтавка</translation>
<translation id="4587425331216688090">ÐдреÑÑŠÑ‚ да Ñе премахне ли от Chrome?</translation>
-<translation id="4589078953350245614">Опитахте да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предоÑтави невалиден Ñертификат. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Връзката ви Ñ/ÑŠÑ <ph name="DOMAIN" /> е шифрована ÑÑŠÑ Ñъвременен криптографÑки пакет.</translation>
<translation id="4594403342090139922">&amp;ОтмÑна на изтриването</translation>
<translation id="4619615317237390068">Раздели от други уÑтройÑтва</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Ñертификатът му за ÑигурноÑÑ‚ Ñъдържа грешки. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="4690462567478992370">Спиране на използването на невалиден Ñертификат</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Връзката ви бе прекъÑната</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Стартирайте мрежова диагноÑтика в Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Възникна неизвеÑтна грешка.</translation>
<translation id="4800132727771399293">Прегледайте датата на валидноÑÑ‚ и кода за проверка и оптитайте отново</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Ð’ момента не можете да поÑетите <ph name="SITE" />, защото уебÑайтът изпрати кодирани идентификационни данни, които Google Chrome не може да обработи. Обикновено грешките в мрежата и атаките Ñрещу Ð½ÐµÑ Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно.</translation>
<translation id="4813512666221746211">Грешка в мрежата</translation>
<translation id="4816492930507672669">Да Ñе побере в Ñтраницата</translation>
<translation id="483020001682031208">ÐÑма Ñтраници във ФизичеÑката мрежа, които да ви покажем</translation>
<translation id="4850886885716139402">Изглед</translation>
<translation id="4854362297993841467">Този начин на бърза доÑтавка не Ñе поддържа. Опитайте Ñ Ð´Ñ€ÑƒÐ³.</translation>
<translation id="4858792381671956233">Попитахте родителите Ñи дали може да поÑетите този Ñайт</translation>
+<translation id="4863764087567530506">ВъпроÑното Ñъдържание може да Ñе опита да ви подведе да инÑталирате Ñофтуер или да разкриете лична информациÑ. <ph name="BEGIN_LINK" />Показване въпреки това<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">ТърÑене в иÑториÑта</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> и <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{и още 1 уеб Ñтраница}other{и още # уеб Ñтраници}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Тази Ñтраница е преведена от непознат език на <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Плащане</translation>
<translation id="4926049483395192435">ТрÑбва да Ñе поÑочи.</translation>
<translation id="495170559598752135">ДейÑтвиÑ</translation>
<translation id="4958444002117714549">Разгъване на ÑпиÑъка</translation>
-<translation id="4962322354953122629">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ не Ñе Ñчита за надежден от Chrome. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Повторно активиране на предупреждениÑта</translation>
<translation id="4989809363548539747">Тази приÑтавка не Ñе поддържа</translation>
<translation id="5002932099480077015">Ðко наÑтройката е активирана, копие на картата ви ще Ñе ÑъхранÑва в Chrome на това уÑтройÑтво Ñ Ñ†ÐµÐ» по-бързо попълване на формулÑри.</translation>
<translation id="5018422839182700155">Тази Ñтраница не може да Ñе отвори</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Проверете правилата на админиÑтратора</translation>
<translation id="5029568752722684782">ИзчиÑтване на копието</translation>
<translation id="5031870354684148875">Ð’Ñичко за Google Преводач</translation>
+<translation id="5039804452771397117">Разрешаване</translation>
<translation id="5040262127954254034">ПоверителноÑÑ‚</translation>
<translation id="5045550434625856497">Грешна парола</translation>
<translation id="5056549851600133418">Статии за ваÑ</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Проверете адреÑа на прокÑи Ñървъра<ph name="END_LINK" />.</translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{ÐÑма „биÑквитки“}=1{1 Ñайт използва „биÑквитки“. }other{# Ñайта използват „биÑквитки“. }}</translation>
<translation id="5087286274860437796">ПонаÑтоÑщем Ñертификатът на Ñървъра не е валиден.</translation>
<translation id="5087580092889165836">ДобавÑне на карта</translation>
<translation id="5089810972385038852">Щат</translation>
+<translation id="5094747076828555589">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Chromium нÑма доверие на Ñертификата му за ÑигурноÑÑ‚. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="5095208057601539847">ПровинциÑ</translation>
<translation id="5115563688576182185">(64 бита)</translation>
<translation id="5141240743006678641">Синхронизираните пароли да Ñе шифроват Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¾Ð½Ð½Ð¸Ñ‚Ðµ ви данни за Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Имейл адреÑÑŠÑ‚ е задължителен</translation>
<translation id="5251803541071282808">Облак</translation>
<translation id="5277279256032773186">Използвате Chrome на работното Ñи мÑÑто? БизнеÑите могат да управлÑват наÑтройките на браузъра за Ñлужителите Ñи. Ðаучете повече</translation>
+<translation id="5297526204711817721">Връзката ви Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт не е чаÑтна. За да излезете от режима на VR, премахнете очилата и натиÑнете бутона за назад.</translation>
<translation id="5299298092464848405">Грешка при ÑÐ¸Ð½Ñ‚Ð°ÐºÑ‚Ð¸Ñ‡Ð½Ð¸Ñ Ð°Ð½Ð°Ð»Ð¸Ð· на правилото</translation>
-<translation id="5300589172476337783">Показване</translation>
<translation id="5308689395849655368">Изпращането на Ñигнали за Ñривове е деактивирано.</translation>
<translation id="5317780077021120954">Запазване</translation>
<translation id="5327248766486351172">Име</translation>
-<translation id="5337705430875057403">Извършителите на атака Ñрещу <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> може да ви подведат да направите нещо опаÑно, като например да инÑталирате Ñофтуер или да разкриете лична Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (например пароли, телефонни номера или номера на кредитни карти).</translation>
-<translation id="5359637492792381994">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. ПонаÑтоÑщем Ñертификатът му за ÑигурноÑÑ‚ не е валиден. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Ð’ момента не можете да поÑетите Ñайта <ph name="SITE" />, защото Ñертификатът му е анулиран. Обикновено грешките в мрежата и атаките Ñрещу Ð½ÐµÑ Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно.</translation>
<translation id="536296301121032821">СъхранÑването на наÑтройките за правилото не бе уÑпешно</translation>
<translation id="5386426401304769735">Веригата от Ñертификати за този Ñайт Ñъдържа Ñертификат, подпиÑан Ñ SHA-1.</translation>
<translation id="5402410679244714488">ВалидноÑÑ‚: <ph name="EXPIRATION_DATE_ABBR" />. ПоÑледно използване преди повече от година</translation>
+<translation id="540969355065856584">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. ПонаÑтоÑщем Ñертификатът му за ÑигурноÑÑ‚ не е валиден. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от извършител на атака.</translation>
<translation id="5421136146218899937">ИзчиÑтване на данните за Ñърфирането...</translation>
<translation id="5430298929874300616">Премахване на отметката</translation>
<translation id="5431657950005405462">Файлът ви не бе намерен</translation>
-<translation id="5435775191620395718">Показва Ñе иÑториÑта от това уÑтройÑтво. <ph name="BEGIN_LINK" />Ðаучете повече<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">При потвърждаване на Ñхемата възникна грешка в/ъв „<ph name="ERROR_PATH" />“: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Тази Ñтраница на <ph name="HOST_NAME" /> не може да бъде намерена</translation>
<translation id="5455374756549232013">Ðевалидно клеймо за дата и Ñ‡Ð°Ñ Ð½Ð° правилото</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> от <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Ðевалидно</translation>
<translation id="5470861586879999274">&amp;ВъзÑтановÑване на редактирането</translation>
<translation id="54817484435770891">ДобавÑне на валиден адреÑ</translation>
<translation id="5492298309214877701">Този интранет Ñайт на фирмата, организациÑта или училището има ÑÑŠÑ‰Ð¸Ñ URL Ð°Ð´Ñ€ÐµÑ ÐºÐ°Ñ‚Ð¾ на външен уебÑайт.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Този Ð°Ð´Ñ€ÐµÑ Ð·Ð° вземане не Ñе поддържа. Изберете друг.</translation>
<translation id="5572851009514199876">МолÑ, Ñтартирайте браузъра Chrome и влезте в него, за да Ñе провери дали имате доÑтъп до този Ñайт.</translation>
<translation id="5580958916614886209">Проверете меÑеца на валидноÑÑ‚ и опитайте отново</translation>
+<translation id="5586446728396275693">ÐÑма запазени адреÑи</translation>
+<translation id="5595485650161345191">Редактиране на адреÑа</translation>
<translation id="560412284261940334">Управлението не Ñе поддържа</translation>
<translation id="5610142619324316209">Проверете връзката.</translation>
<translation id="5610807607761827392">Можете да управлÑвате картите и адреÑите от <ph name="BEGIN_LINK" />наÑтройките<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">ИÑкате ли да напуÑнете този Ñайт?</translation>
<translation id="5629630648637658800">Зареждането на наÑтройките за правилото не бе уÑпешно</translation>
<translation id="5631439013527180824">Ðевалидно означение за управление на уÑтройÑтвото</translation>
+<translation id="5633066919399395251">Извършители на атака, понаÑтоÑщем използващи <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, може да опитат да инÑталират опаÑни програми на компютъра ви, които крадат или изтриват информациÑта ви (например Ñнимки, пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ номера на кредитни карти). <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">МеÑтоположение</translation>
+<translation id="5659593005791499971">Имейл</translation>
<translation id="5669703222995421982">Получаване на перÑонализирано Ñъдържание</translation>
<translation id="5675650730144413517">Тази Ñтраница не работи</translation>
-<translation id="5677928146339483299">Блокирано</translation>
-<translation id="5694783966845939798">Ðаправихте опит да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предоÑтави Ñертификат, подпиÑан ÑÑŠÑ Ñлаб алгоритъм (например SHA-1). Това означава, че идентификационните данни за ÑигурноÑÑ‚ от Ñървъра може да Ñа фалшифицирани и той да не е този, който очаквате (възможно е да Ñте Ñе Ñвързали Ñ Ð¸Ð·Ð²ÑŠÑ€ÑˆÐ¸Ñ‚ÐµÐ» на атака). <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">СамоличноÑтта на този уебÑайт не е потвърдена.</translation>
+<translation id="5713016350996637505">Блокирахме измамно Ñъдържание</translation>
<translation id="5720705177508910913">ТекущиÑÑ‚ потребител</translation>
<translation id="5732392974455271431">Родителите ви могат да го отблокират за ваÑ</translation>
<translation id="5763042198335101085">Въведете валиден имейл адреÑ</translation>
<translation id="5765072501007116331">За да видите начините на бърза доÑтавка и изиÑкваниÑта, изберете адреÑ</translation>
+<translation id="5778550464785688721">Пълен контрол над MIDI уÑтройÑтва</translation>
<translation id="5784606427469807560">При потвърждаването на картата ви възникна проблем. Проверете връзката Ñи Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð½ÐµÑ‚ и опитайте отново.</translation>
<translation id="5785756445106461925">ОÑвен това тази Ñтраница включва други реÑурÑи, които не Ñа защитени. Докато Ñе предават, те могат да бъдат видени от други хора и да бъдат модифицирани от извършител на атака, така че да Ñе промени изгледът на Ñтраницата.</translation>
<translation id="5786044859038896871">ИÑкате ли да Ñе попълнÑÑ‚ данните за кредитната ви карта?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;ВъзÑтановÑване на добавÑнето</translation>
<translation id="5814352347845180253">Може да загубите доÑтъп до платено Ñъдържание от <ph name="SITE" /> и нÑкои други Ñайтове.</translation>
<translation id="5838278095973806738">Ðе ви препоръчваме да въвеждате поверителна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð² този Ñайт (например пароли или номера на кредитни карти), тъй като може да бъде открадната от извършители на атаки.</translation>
-<translation id="5843436854350372569">Опитахте да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предоÑтави Ñертификат, Ñъдържащ Ñлаб ключ. Възможно е извършител на атака да е компрометирал чаÑÑ‚Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ и Ñървърът да не е този, който очаквате (възможно е да Ñте Ñе Ñвързали Ñ Ð¸Ð·Ð²ÑŠÑ€ÑˆÐ¸Ñ‚ÐµÐ» на атака). <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">ÐÑма доÑтъп до този Ñайт</translation>
<translation id="5869522115854928033">Запазени пароли</translation>
<translation id="5872918882028971132">ОÑновни предложениÑ</translation>
<translation id="5901630391730855834">жълто</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (Ñинхронизирано)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{Използва Ñе 1}other{Използват Ñе #}}</translation>
<translation id="5926846154125914413">Може да загубите доÑтъп до платено Ñъдържание от нÑкои Ñайтове.</translation>
<translation id="5959728338436674663">Ðвтоматично изпращане до Google на <ph name="BEGIN_WHITEPAPER_LINK" />ÑиÑтемна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¸ чаÑÑ‚ от Ñъдържанието на Ñтраниците<ph name="END_WHITEPAPER_LINK" /> Ñ Ñ†ÐµÐ» по-леÑно откриване на опаÑни Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ Ñайтове. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Седмица</translation>
<translation id="5967867314010545767">Премахване от иÑториÑта</translation>
<translation id="5975083100439434680">ÐамалÑване на мащаба</translation>
<translation id="598637245381783098">Приложението за плащане не може да Ñе отвори</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Страница 1}other{Страница #}}</translation>
<translation id="6017514345406065928">зелено</translation>
+<translation id="6017850046339264347">Извършители на атака Ñрещу <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могат да инÑталират измамни приложениÑ, които Ñе предÑтавÑÑ‚ за нещо друго или Ñъбират данни, които може да Ñе използват за проÑледÑването ви. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (Ñинхронизирани)</translation>
<translation id="6027201098523975773">Въведете име</translation>
<translation id="6040143037577758943">ЗатварÑне</translation>
<translation id="6042308850641462728">Още</translation>
+<translation id="6047233362582046994">Ðко разбирате риÑковете за ÑигурноÑтта Ñи, може <ph name="BEGIN_LINK" />да поÑетите този Ñайт<ph name="END_LINK" /> преди премахването на опаÑните приложениÑ.</translation>
+<translation id="6051221802930200923">Ð’ момента не можете да поÑетите <ph name="SITE" />, защото уебÑайтът използва метод за допълнително потвърждаване на Ñертификатите. Обикновено грешките в мрежата и атаките Ñрещу Ð½ÐµÑ Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно.</translation>
<translation id="6060685159320643512">Внимавайте, тези екÑперименти може да Ñа опаÑни</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{нÑма}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">ОÑъщеÑтвихте доÑтъп до Ñъдържанието поÑредÑтвом оÑигурен от админиÑтратора Ñертификат. Данните, които предоÑтавите на <ph name="DOMAIN" />, могат да бъдат прихванати от админиÑтратора ви.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{ÐÑма}=1{1 парола (Ñинхронизирана)}other{# пароли (Ñинхронизирани)}}</translation>
<translation id="6146055958333702838">Проверете вÑички кабели и реÑтартирайте маршрутизаторите, модемите или другите мрежови
уÑтройÑтва, които може да използвате.</translation>
<translation id="614940544461990577">Изпробвайте Ñледното:</translation>
<translation id="6151417162996330722">Сертификатът на Ñървъра има твърде дълъг период на валидноÑÑ‚.</translation>
<translation id="6157877588268064908">За да видите начините на доÑтавка и изиÑкваниÑта, изберете адреÑ</translation>
+<translation id="6158003235852588289">Google БезопаÑно Ñърфиране наÑкоро откри фишинг на <ph name="SITE" />. Сайтовете за фишинг Ñе предÑтавÑÑ‚ за други уебÑайтове Ñ Ñ†ÐµÐ» да ви подведат.</translation>
<translation id="6165508094623778733">Ðаучете повече</translation>
+<translation id="6169916984152623906">Вече можете да Ñърфирате чаÑтно. Така другите хора, които използват това уÑтройÑтво, нÑма да виждат активноÑтта ви. ИзтеглÑниÑта и отметките обаче ще Ñе запазват.</translation>
<translation id="6177128806592000436">Връзката ви Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт не е защитена</translation>
<translation id="6184817833369986695">(кохорта: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Проверете връзката Ñи Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð½ÐµÑ‚</translation>
<translation id="6218753634732582820">ÐдреÑÑŠÑ‚ да Ñе премахне ли от Chromium?</translation>
+<translation id="6221345481584921695">Google БезопаÑно Ñърфиране наÑкоро <ph name="BEGIN_LINK" />откри злонамерен Ñофтуер<ph name="END_LINK" /> на <ph name="SITE" />. УебÑайтовете, които обикновено Ñа надеждни, понÑкога Ñе заразÑват Ñ Ð¾Ð¿Ð°Ñен Ñофтуер. ВъпроÑното Ñъдържание произлиза от <ph name="SUBRESOURCE_HOST" /> – извеÑтен разпроÑтранител на злонамерени програми.</translation>
<translation id="6251924700383757765">Ð”ÐµÐºÐ»Ð°Ñ€Ð°Ñ†Ð¸Ñ Ð·Ð° поверителноÑÑ‚</translation>
<translation id="6254436959401408446">ÐÑма доÑтатъчно памет за отварÑне на тази Ñтраница</translation>
<translation id="625755898061068298">Деактивирахте предупреждениÑта отноÑно ÑигурноÑтта на този Ñайт.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Редактиране на отметката</translation>
<translation id="6410264514553301377">Въвеждане на датата на валидноÑÑ‚ и кода за проверка за <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Попитахте Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ Ñи дали може да поÑетите този Ñайт</translation>
-<translation id="6416403317709441254">Ð’ момента не можете да поÑетите <ph name="SITE" />, защото уебÑайтът изпрати невалидни идентификационни данни, които Chromium не може да обработи. Обикновено мрежовите грешки и атаки Ñа временни, така че Ñтраницата вероÑтно ще работи по-къÑно. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Ðе може да Ñе провери дали Ñертификатът е анулиран.</translation>
<translation id="6433490469411711332">Редактиране на информациÑта за връзка</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> отказа да уÑтанови връзка.</translation>
<translation id="6446608382365791566">ДобавÑне на още информациÑ</translation>
+<translation id="6447842834002726250">„БиÑквитки“</translation>
<translation id="6451458296329894277">Потвърдете повторното изпращане на формулÑра</translation>
<translation id="6456339708790392414">Вашето плащане</translation>
<translation id="6458467102616083041">Бе пренебрегнато, защото оÑновното Ñ‚ÑŠÑ€Ñене е деактивирано от правило.</translation>
-<translation id="6462969404041126431">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Възможно е Ñертификатът му за ÑигурноÑÑ‚ да е анулиран. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Правила за уÑтройÑтвото</translation>
<translation id="6477321094435799029">Chrome откри необичаен код на тази Ñтраница и Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð°, за да защити личната ви Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (например пароли, телефонни номера и номера на кредитни карти).</translation>
<translation id="6489534406876378309">Стартиране на качването на Ñривове</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">ВалидноÑÑ‚: <ph name="EXPIRATION_DATE_ABBR" />. ПоÑледно използване: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Мениджърът ви вÑе още не е одобрил заÑвката</translation>
<translation id="6569060085658103619">Преглеждате Ñтраница на разширение</translation>
-<translation id="6593753688552673085">по-малко от <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">ВъпроÑното Ñъдържание може да Ñе опита да инÑталира опаÑен Ñофтуер на уÑтройÑтвото ви, който да открадне или изтрие информациÑта ви. <ph name="BEGIN_LINK" />Показване въпреки това<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Опции за шифроване</translation>
<translation id="662080504995468778">ОÑтаване</translation>
<translation id="6626291197371920147">ДобавÑне на валиден номер на карта</translation>
<translation id="6628463337424475685">ТърÑене Ñ/ÑŠÑ <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Извършители на атака, понаÑтоÑщем използващи <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, може да опитат да инÑталират опаÑни програми на компютъра ви Mac, които крадат или изтриват информациÑта ви (например Ñнимки, пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ номера на кредитни карти). <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Това правило е оттеглено.</translation>
-<translation id="6652240803263749613">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ не Ñе Ñчита за надежден от операционната ÑиÑтема на компютъра ви. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Предложението за формулÑри да Ñе премахне ли от Chromium?</translation>
<translation id="6685834062052613830">Излизане от профила и завършване на наÑтройването</translation>
<translation id="6710213216561001401">Предишна</translation>
<translation id="6710594484020273272">&lt;Въведете дума за Ñ‚ÑŠÑ€Ñене&gt;</translation>
<translation id="6711464428925977395">Ðещо не е наред Ñ Ð¿Ñ€Ð¾ÐºÑи Ñървъра или адреÑÑŠÑ‚ е неправилен.</translation>
<translation id="6727102863431372879">Задаване</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{нÑма}=1{1 елемент}other{# елемента}}</translation>
<translation id="674375294223700098">ÐеизвеÑтна грешка в Ñертификата на Ñървъра.</translation>
<translation id="6753269504797312559">СтойноÑÑ‚ за правилото</translation>
<translation id="6757797048963528358">УÑтройÑтвото ви премина в ÑпÑщ режим.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Идент. â„– на перÑонализирането</translation>
<translation id="6820686453637990663">Код за ÑигурноÑÑ‚</translation>
<translation id="6824266427216888781">Зареждането на данните за регионите не бе уÑпешно</translation>
+<translation id="6825578344716086703">Опитахте да отворите <ph name="DOMAIN" />, но Ñървърът предоÑтави Ñертификат, подпиÑан ÑÑŠÑ Ñлаб алгоритъм (например SHA-1). Това означава, че идентификационните данни за ÑигурноÑÑ‚ от Ñървъра може да Ñа фалшифицирани и той да не е този, който очаквате (възможно е да Ñте Ñе Ñвързали Ñ Ð¸Ð·Ð²ÑŠÑ€ÑˆÐ¸Ñ‚ÐµÐ» на атака).</translation>
+<translation id="6830728435402077660">ÐÑма защита</translation>
<translation id="6831043979455480757">Превод</translation>
<translation id="6839929833149231406">Район</translation>
<translation id="6874604403660855544">&amp;ВъзÑтановÑване на добавÑнето</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Картата ви е потвърдена</translation>
<translation id="6897140037006041989">ПотребителÑки агент</translation>
<translation id="6915804003454593391">Потребител:</translation>
+<translation id="6945221475159498467">Изберете</translation>
<translation id="6948701128805548767">За да видите начините на вземане и изиÑкваниÑта, изберете адреÑ</translation>
<translation id="6957887021205513506">Изглежда, че Ñертификатът на Ñървъра е подправен.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">ПоÑочени Ñа както фикÑирани прокÑи Ñървъри, така и URL Ð°Ð´Ñ€ÐµÑ Ð½Ð° Ñкрипт във формат .pac.</translation>
<translation id="6989763994942163495">Показване на разширените наÑтройки...</translation>
<translation id="7000990526846637657">ÐÑма намерени запиÑи в иÑториÑта</translation>
-<translation id="7009986207543992532">Опитахте да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предоÑтави Ñертификат, чийто период на валидноÑÑ‚ е твърде дълъг, за да е надежден. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Възможно е в профила ви в Google да има други видове иÑÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ð° Ñърфиране, ÑъхранÑвани на Ð°Ð´Ñ€ÐµÑ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Пароли</translation>
+<translation id="7050187094878475250">Опитахте да Ñе Ñвържете Ñ/ÑŠÑ <ph name="DOMAIN" />, но Ñървърът предоÑтави Ñертификат, чийто период на валидноÑÑ‚ е твърде дълъг, за да е надежден.</translation>
+<translation id="7053983685419859001">Блокиране</translation>
<translation id="7064851114919012435">Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° връзка</translation>
<translation id="7079718277001814089">Този Ñайт Ñъдържа злонамерен Ñофтуер</translation>
<translation id="7087282848513945231">Окръг</translation>
-<translation id="7088615885725309056">По-Ñтара</translation>
<translation id="7090678807593890770">ПотърÑете „<ph name="LINK" />“ Ñ Google</translation>
+<translation id="7108819624672055576">Разрешено от разширение</translation>
<translation id="7119414471315195487">Затворете другите раздели или програми.</translation>
<translation id="7129409597930077180">Този Ð°Ð´Ñ€ÐµÑ Ð·Ð° доÑтавка не Ñе поддържа. Изберете друг.</translation>
<translation id="7138472120740807366">Ðачин на бърза доÑтавка</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Обработва Ñе</translation>
<translation id="724691107663265825">Ðа хоризонта Ñе задава Ñайт ÑÑŠÑ Ð·Ð»Ð¾Ð½Ð°Ð¼ÐµÑ€ÐµÐ½ Ñофтуер</translation>
<translation id="724975217298816891">Въведете датата на валидноÑÑ‚ и кода за проверка за <ph name="CREDIT_CARD" />, за да актуализирате данните за картата Ñи. След като Ñ Ð¿Ð¾Ñ‚Ð²ÑŠÑ€Ð´Ð¸Ñ‚Ðµ, те ще бъдат Ñподелени Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт.</translation>
-<translation id="725866823122871198">Ðе може да Ñе уÑтанови чаÑтна връзка Ñ/ÑŠÑ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и чаÑÑŠÑ‚ на компютъра ви (<ph name="DATE_AND_TIME" />) Ñа неправилни.</translation>
+<translation id="7260504762447901703">ОтмÑна на доÑтъпа</translation>
<translation id="7275334191706090484">УправлÑвани отметки</translation>
<translation id="7298195798382681320">Препоръчително</translation>
<translation id="7309308571273880165">Сигнал за Ñрив, запиÑан в/ъв <ph name="CRASH_TIME" /> (потребителÑÑ‚ е заÑвил качване, което още не е извършено)</translation>
<translation id="7334320624316649418">&amp;ВъзÑтановÑване на пренареждането</translation>
<translation id="733923710415886693">Сертификатът на Ñървъра не е разкрит чрез ПрозрачноÑÑ‚ на Ñертификатите.</translation>
-<translation id="7351800657706554155">Ð’ момента не можете да поÑетите Ñайта <ph name="SITE" />, защото Ñертификатът му е анулиран. Обикновено мрежовите грешки и атаки Ñа временни, така че тази Ñтраница вероÑтно ще работи по-къÑно. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Команден ред</translation>
<translation id="7372973238305370288">резултат от Ñ‚ÑŠÑ€Ñенето</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ðе</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Потвърждаване на картата</translation>
-<translation id="7394102162464064926">ÐаиÑтина ли иÑкате да изтриете тези Ñтраници от иÑториÑта Ñи?
-
-Ðе забравÑйте, че режим „инкогнито“ (<ph name="SHORTCUT_KEY" />) може да е полезен ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ð¿ÑŠÑ‚.</translation>
<translation id="7400418766976504921">URL адреÑ</translation>
<translation id="7419106976560586862">Път на потребителÑÐºÐ¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»</translation>
<translation id="7424977062513257142">Страница, вградена в тази уеб Ñтраница, изпраща подкана:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">Този Ñайт е блокиран</translation>
<translation id="7445762425076701745">ИдентичноÑтта на Ñървъра, към който Ñте Ñвързани, не може да бъде потвърдена изцÑло. Свързани Ñте към Ñървър чрез име, което е валидно Ñамо във вашата мрежа и чиÑто ÑобÑтвеноÑÑ‚ нÑма начин да Ñе потвърди от външен Ñертифициращ орган. Тъй като нÑкои Ñертифициращи органи въпреки това издават Ñертификати за такива имена, не е възможно да Ñе гарантира, че Ñте Ñвързани към Ð¶ÐµÐ»Ð°Ð½Ð¸Ñ Ñайт, а не към атакуващ.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Ðаучете повече<ph name="END_LINK" /> за този проблем.</translation>
+<translation id="7455133967321480974">Използване на глобалната Ñтандартна ÑтойноÑÑ‚ (блокиране)</translation>
<translation id="7460163899615895653">Тук Ñе показват Ñкорошните раздели от други уÑтройÑтва</translation>
<translation id="7469372306589899959">Картата Ñе потвърждава</translation>
<translation id="7481312909269577407">Препращане</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">ВърнатиÑÑ‚ от правилата идентификационен номер на уÑтройÑтвото е празен или не ÑъответÑтва на текущиÑ</translation>
<translation id="7514365320538308">ИзтеглÑне</translation>
<translation id="7518003948725431193">Ðе е намерена уеб Ñтраница за уеб адреÑа: <ph name="URL" /></translation>
+<translation id="7521387064766892559">Javascript</translation>
<translation id="7535087603100972091">СтойноÑÑ‚</translation>
<translation id="7537536606612762813">Задължително</translation>
+<translation id="7542403920425041731">След като потвърдите картата Ñи, данните за Ð½ÐµÑ Ñ‰Ðµ бъдат Ñподелени Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт.</translation>
<translation id="7542995811387359312">Ðвтоматичното попълване на кредитната карта е деактивирано, защото този формулÑÑ€ не използва защитена връзка.</translation>
<translation id="7543525346216957623">Попитайте Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ Ñи</translation>
<translation id="7549584377607005141">За да Ñе покаже правилно тази уеб Ñтраница, Ñа необходими по-рано въведените от Ð²Ð°Ñ Ð´Ð°Ð½Ð½Ð¸. Можете да ги изпратите отново, но така ще повторите вÑÑко изпълнено от Ð½ÐµÑ Ð´ÐµÐ¹Ñтвие.</translation>
<translation id="7552846755917812628">Изпробвайте Ñледните Ñъвети:</translation>
<translation id="7554791636758816595">Ðов раздел</translation>
+<translation id="7567204685887185387">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; възможно е Ñертификатът му за ÑигурноÑÑ‚ да е издаден измамничеÑки. Това може да Ñе дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Тази Ñтраница е на<ph name="ORIGINAL_LANGUAGE" />ИÑкате ли да Ñ Ð¿Ñ€ÐµÐ²ÐµÐ´ÐµÑ‚Ðµ?</translation>
<translation id="7569952961197462199">Кредитната карта да Ñе премахне ли от Chrome?</translation>
<translation id="7569983096843329377">черно</translation>
<translation id="7578104083680115302">Извършвайте бързи Ð¿Ð»Ð°Ñ‰Ð°Ð½Ð¸Ñ Ð² Ñайтове и Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¾Ñ‚ вÑÑкакви уÑтройÑтва поÑредÑтвом картите, които Ñте запазили в Google.</translation>
<translation id="7588950540487816470">ФизичеÑка мрежа</translation>
<translation id="7592362899630581445">Сертификатът на Ñървъра нарушава ограничениÑта за име.</translation>
+<translation id="7598391785903975535">По-малко от <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">ПонаÑтоÑщем <ph name="HOST_NAME" /> не може да обработи тази заÑвка.</translation>
<translation id="7600965453749440009">Ðикога да не Ñе превежда от <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">СтойноÑтта е извън обхват <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Валидна до: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Вече имате данни, които Ñа шифровани поÑредÑтвом друга верÑÐ¸Ñ Ð½Ð° паролата за профила ви в Google. МолÑ, въведете Ñ Ð¿Ð¾-долу.</translation>
-<translation id="7634554953375732414">Връзката ви Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт не е поверителна.</translation>
<translation id="7637571805876720304">Кредитната карта да Ñе премахне ли от Chromium?</translation>
<translation id="765676359832457558">Скриване на разширените наÑтройки...</translation>
<translation id="7658239707568436148">Отказ</translation>
+<translation id="7662298039739062396">ÐаÑтройката Ñе контролира от разширение</translation>
<translation id="7667346355482952095">Върнатото означение за правилата е празно или не ÑъответÑтва на текущото</translation>
<translation id="7668654391829183341">ÐеизвеÑтно уÑтройÑтво</translation>
<translation id="7669271284792375604">Извършителите на атаки, използващи този Ñайт, може да опитат да ви подведат да инÑталирате програми, които вредÑÑ‚ на Ñърфирането ви (например, като променÑÑ‚ началната ви Ñтраница или показват допълнителни реклами в поÑещаваните от Ð²Ð°Ñ Ñайтове).</translation>
<translation id="7674629440242451245">ТърÑите интереÑни нови функции на Chrome? Изпробвайте канала за програмиÑти на Ð°Ð´Ñ€ÐµÑ chrome.com/dev.</translation>
<translation id="7682287625158474539">ÐÐ´Ñ€ÐµÑ Ð·Ð° доÑтавка</translation>
+<translation id="7701040980221191251">ÐÑма</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Продължаване към <ph name="SITE" /> (опаÑно)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Сертификат</translation>
+<translation id="7716147886133743102">Блокирано от админиÑтратора ви</translation>
<translation id="7716424297397655342">Този Ñайт не може да Ñе зареди от кеш паметта</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Ðе Ñе управлÑва</translation>
<translation id="7755287808199759310">РодителÑÑ‚ ви може да го отблокира за ваÑ</translation>
<translation id="7758069387465995638">Възможно е връзката да е блокирана от защитна Ñтена или антивируÑен Ñофтуер.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32 бита)</translation>
<translation id="7956713633345437162">Мобилни отметки</translation>
<translation id="7961015016161918242">Ðикога</translation>
-<translation id="7962083544045318153">Идентификатор на Ñрива: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Винаги да Ñе превежда от <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ðе е поÑочено</translation>
<translation id="800218591365569300">Затворете другите раздели или програми, за да оÑвободите памет.</translation>
<translation id="8012647001091218357">Ðе можахме да Ñе Ñвържем Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ ви. МолÑ, опитайте отново.</translation>
<translation id="8025119109950072390">Извършителите на атаки, използващи този Ñайт, може да ви подведат да направите нещо опаÑно, като например да инÑталирате Ñофтуер или да разкриете лична Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (например пароли, телефонни номера или номера на кредитни карти).</translation>
-<translation id="803030522067524905">Google БезопаÑно Ñърфиране наÑкоро откри фишинг на <ph name="SITE" />. Сайтовете за фишинг Ñе предÑтавÑÑ‚ за други уебÑайтове Ñ Ñ†ÐµÐ» да ви подведат. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Тази Ñтраница е на <ph name="SOURCE_LANGUAGE" />. Да Ñе преведе ли на <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Извеждане на запитване (по подразбиране)</translation>
<translation id="8041089156583427627">Изпращане на отзивите</translation>
+<translation id="8041940743680923270">Използване на глобалната Ñтандартна ÑтойноÑÑ‚ (запитване)</translation>
<translation id="8088680233425245692">Преглеждането на ÑтатиÑта не бе уÑпешно.</translation>
<translation id="8089520772729574115">по-малко от 1 МБ</translation>
<translation id="8091372947890762290">Ð’ Ñървъра Ñе изчаква активиране</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007">Ðе можа да бъде намерен <ph name="BEGIN_ABBR" />DNS адреÑÑŠÑ‚<ph name="END_ABBR" /> на Ñървъра на <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Компютърът ви премина в ÑпÑщ режим.</translation>
<translation id="8150722005171944719">Файлът на Ð°Ð´Ñ€ÐµÑ <ph name="URL" /> не може да бъде прочетен. Възможно е да е премахнат, премеÑтен или разрешениÑта му да предотвратÑват доÑтъпа.</translation>
+<translation id="8184538546369750125">Използване на глобалната Ñтандартна ÑтойноÑÑ‚ (разрешаване)</translation>
+<translation id="8191494405820426728">Локален идентификатор на Ñрива: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;ОтмÑна на премеÑтването</translation>
<translation id="8201077131113104583">Ðевалиден URL Ð°Ð´Ñ€ÐµÑ Ð·Ð° актуализиране на разширението Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¾Ð½ÐµÐ½ номер <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Обобщена Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° поръчката</translation>
<translation id="8218327578424803826">Зададено меÑтоположение:</translation>
<translation id="8225771182978767009">Човекът, който е наÑтроил компютъра, е блокирал този Ñайт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" /> и <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">ПонаÑтоÑщем извършители на атака Ñрещу <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> може да опитат да инÑталират опаÑни програми на компютъра ви, които крадат или изтриват информациÑта ви (например Ñнимки, пароли, ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ номера на кредитни карти).</translation>
<translation id="8241707690549784388">Страницата, коÑто Ñ‚ÑŠÑ€Ñите, използва въведената от Ð²Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ. Ðко Ñе върнете на тази Ñтраница, дейÑтвиÑта, които вече Ñте изпълнили, може да бъдат повторени. ИÑкате ли да продължите?</translation>
<translation id="8249320324621329438">ПоÑледно извличане:</translation>
<translation id="8253091569723639551">ÐдреÑÑŠÑ‚ за фактуриране е задължителен</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">Свържете Ñе ÑÑŠÑ ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ñи админиÑтратор, ако не Ñте Ñигурни какво означава това.</translation>
<translation id="8293206222192510085">ДобавÑне на отметка</translation>
<translation id="8294431847097064396">Източник</translation>
+<translation id="8306404619377842860">Ðе може да Ñе уÑтанови чаÑтна връзка ÑÑŠÑ Ñайта <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и чаÑÑŠÑ‚ на уÑтройÑтвото ви (<ph name="DATE_AND_TIME" />) Ñа неправилни. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Преводът не бе уÑпешен поради проблем Ñ Ð²Ñ€ÑŠÐ·ÐºÐ°Ñ‚Ð° към мрежата.</translation>
<translation id="8332188693563227489">ДоÑтъпът до <ph name="HOST_NAME" /> бе отказан</translation>
<translation id="834457929814110454">Ðко разбирате риÑковете за ÑигурноÑтта Ñи, може <ph name="BEGIN_LINK" />да поÑетите този Ñайт<ph name="END_LINK" /> преди премахването на опаÑните програми.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">За да използвате картите от профила Ñи в Google, влезте в Chrome</translation>
<translation id="8488350697529856933">Прилага Ñе към</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> не Ð¾Ñ‚Ð³Ð¾Ð²Ð°Ñ€Ñ Ñ‚Ð²ÑŠÑ€Ð´Ðµ дълго време.</translation>
-<translation id="852346902619691059">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за ÑигурноÑÑ‚ не Ñе Ñчита за надежден от операционната ÑиÑтема на уÑтройÑтвото ви. Това може да Ñе дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака. <ph name="BEGIN_LEARN_MORE_LINK" />Ðаучете повече<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Година на валидноÑÑ‚</translation>
<translation id="8543181531796978784">Можете да <ph name="BEGIN_ERROR_LINK" />подадете Ñигнал за проблем при откриването<ph name="END_ERROR_LINK" /> или, ако разбирате риÑковете за ÑигурноÑтта Ñи, да <ph name="BEGIN_LINK" />поÑетите този небезопаÑен Ñайт<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Преводът не бе уÑпешен, защото езикът на Ñтраницата не можа да бъде определен.</translation>
-<translation id="8559762987265718583">Ðе може да Ñе уÑтанови чаÑтна връзка Ñ/ÑŠÑ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, тъй като датата и чаÑÑŠÑ‚ на уÑтройÑтвото ви (<ph name="DATE_AND_TIME" />) Ñа неправилни.</translation>
<translation id="8571890674111243710">Превод на Ñтраницата на <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">+ тел. номер</translation>
<translation id="859285277496340001">Сертификатът не поÑочва механизъм за проверка дали е бил анулиран.</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">За уÑтановÑване на Ñигурна връзка е необходимо чаÑовникът ви да е верен. Това е така, защото Ñертификатите, Ñ ÐºÐ¾Ð¸Ñ‚Ð¾ уебÑайтовете Ñе идентифицират, Ñа валидни Ñамо за конкретни периоди от време. Тъй като чаÑовникът на уÑтройÑтвото ви не е верен, Chromium не може да потвърди тези Ñертификати.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;DNS адреÑÑŠÑ‚&lt;/abbr&gt; на <ph name="HOST_NAME" /> не можа да бъде намерен. Проблемът Ñе диагноÑтицира.</translation>
<translation id="8759274551635299824">Тази карта е изтекла</translation>
+<translation id="8761567432415473239">Google БезопаÑно Ñърфиране наÑкоро <ph name="BEGIN_LINK" />откри опаÑни програми<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;ВъзÑтановÑване на изтриването</translation>
<translation id="8800988563907321413">Тук ще Ñе показват Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° неща в близоÑÑ‚</translation>
<translation id="8820817407110198400">Отметки</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">ÐаÑкоро затворени</translation>
<translation id="8874824191258364635">Въведете валиден номер на карта</translation>
<translation id="8876793034577346603">СинтактичниÑÑ‚ анализ на конфигурациÑта на мрежата не бе уÑпешен.</translation>
-<translation id="8877192140621905067">След като потвърдите картата Ñи, данните за Ð½ÐµÑ Ñ‰Ðµ бъдат Ñподелени Ñ Ñ‚Ð¾Ð·Ð¸ Ñайт</translation>
<translation id="8889402386540077796">Цветови тон</translation>
<translation id="8891727572606052622">Ðевалиден режим на прокÑи Ñървъра.</translation>
<translation id="889901481107108152">За Ñъжаление този екÑперимент не Ñе предлага за платформата ви.</translation>
<translation id="8903921497873541725">Увеличаване на мащаба</translation>
<translation id="8931333241327730545">ИÑкате ли да запазите тази карта в профила Ñи в Google?</translation>
<translation id="8932102934695377596">ЧаÑовникът ви е назад</translation>
-<translation id="8954894007019320973">(Прод.)</translation>
<translation id="8971063699422889582">Сертификатът на Ñървъра е Ñ Ð¸Ð·Ñ‚ÐµÐºÐ»Ð° валидноÑÑ‚.</translation>
<translation id="8986494364107987395">Ðвтоматично изпращане до Google на ÑтатиÑтичеÑки данни за използването на Chrome и Ñигнали за Ñривове</translation>
-<translation id="8987927404178983737">МеÑец</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Ðа хоризонта Ñе задава Ñайт Ñ Ð¾Ð¿Ð°Ñни програми</translation>
+<translation id="8997023839087525404">Сървърът предоÑтави Ñертификат, който не е разкрит публично чрез правило в ПрозрачноÑÑ‚ на Ñертификатите. Това Ñе изиÑква за нÑкои Ñертификати Ñ Ñ†ÐµÐ» защита Ñрещу хакери и за да е Ñигурно, че може да им Ñе има доверие.</translation>
<translation id="9001074447101275817">ИзиÑкват Ñе потребителÑко име и парола за прокÑи Ñървъра <ph name="DOMAIN" />.</translation>
+<translation id="9005998258318286617">Зареждането на PDF документа не бе уÑпешно.</translation>
<translation id="901974403500617787">Флаговете, които Ñе прилагат за цÑлата ÑиÑтема, могат да бъдат зададени Ñамо от ÑобÑтвеника: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">СвързаниÑÑ‚ Ñ ÐºÐ°Ñ€Ñ‚Ð°Ñ‚Ð° Ð°Ð´Ñ€ÐµÑ Ð·Ð° фактуриране е задължителен</translation>
<translation id="9020542370529661692">Тази Ñтраница е преведена на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Грешка в ÑигурноÑтта</translation>
<translation id="9038649477754266430">Използване на уÑлуга за предвиждане Ñ Ñ†ÐµÐ» по-бързо зареждане на Ñтраниците</translation>
<translation id="9039213469156557790">ОÑвен това тази Ñтраница включва други реÑурÑи, които не Ñа защитени. Докато Ñе предават, те могат да бъдат видени от други хора и да бъдат модифицирани от извършител на атака, така че да Ñе промени поведението на Ñтраницата.</translation>
-<translation id="9040185888511745258">Извършителите на атаки Ñрещу <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> може да опитат да ви подведат да инÑталирате програми, които вредÑÑ‚ на практичеÑката ви работа при Ñърфиране (например като променÑÑ‚ началната ви Ñтраница или показват допълнителни реклами в поÑещаваните от Ð²Ð°Ñ Ñайтове).</translation>
+<translation id="9049981332609050619">Опитахте да отворите <ph name="DOMAIN" />, но Ñървърът предоÑтави невалиден Ñертификат.</translation>
<translation id="9050666287014529139">Парола</translation>
<translation id="9065203028668620118">Редактиране</translation>
<translation id="9068849894565669697">Избор на цвÑÑ‚</translation>
+<translation id="9069693763241529744">Блокирано от разширение</translation>
<translation id="9076283476770535406">Възможно е да има Ñъдържание за пълнолетни</translation>
<translation id="9078964945751709336">ИзиÑква Ñе още информациÑ</translation>
<translation id="9103872766612412690">Обикновено <ph name="SITE" /> използва шифроване за защита на информациÑта ви. Когато Chromium опита да уÑтанови връзка Ñ/ÑŠÑ <ph name="SITE" /> този път, уебÑайтът върна необичайни и неправилни идентификационни данни. Това може да Ñе Ñлучи, когато извършител на атака пробва да Ñе предÑтави за <ph name="SITE" /> или връзката е прекъÑната от екран за вход в Wi-Fi. ИнформациÑта ви продължава да е защитена, тъй като Chromium ÑÐ¿Ñ€Ñ Ð²Ñ€ÑŠÐ·ÐºÐ°Ñ‚Ð°, преди да бъдат обменени данни.</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">&amp;ОтмÑна на редактирането</translation>
<translation id="9154194610265714752">Ðктуализирано</translation>
<translation id="9157595877708044936">ÐаÑтройва Ñе...</translation>
+<translation id="9169664750068251925">Блокиране винаги на този Ñайт</translation>
<translation id="9170848237812810038">&amp;ОтмÑна</translation>
<translation id="917450738466192189">Сертификатът на Ñървъра е невалиден.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> и още <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> използва неподдържан протокол.</translation>
<translation id="9205078245616868884">Данните ви Ñа шифровани Ñ Ð¿Ñ€Ð¾Ð¿ÑƒÑка ви за Ñинхронизиране. Въведете го, за да Ñтартирате Ñинхронизирането.</translation>
<translation id="9207861905230894330">ДобавÑнето на ÑтатиÑта не бе уÑпешно.</translation>
+<translation id="9219103736887031265">ИзображениÑ</translation>
<translation id="933612690413056017">ÐÑма връзка Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð½ÐµÑ‚</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ИЗЧИСТВÐÐЕ ÐРФОРМУЛЯРÐ</translation>
<translation id="939736085109172342">Ðова папка</translation>
<translation id="941721044073577244">Изглежда, че нÑмате разрешение да поÑетите този Ñайт</translation>
<translation id="969892804517981540">Официално издание</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{ÐÑма}=1{1 елемент}other{# елемента}}</translation>
<translation id="988159990683914416">Компилирана програма за програмиÑти</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_bn.xtb b/chromium/components/strings/components_strings_bn.xtb
index 41b1c904228..d2952543bac 100644
--- a/chromium/components/strings/components_strings_bn.xtb
+++ b/chromium/components/strings/components_strings_bn.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">ঘড়ির কাà¦à¦Ÿà¦¾à¦° দিকে ঘোরান</translation>
<translation id="1038842779957582377">অজানা নাম</translation>
<translation id="1050038467049342496">অনà§à¦¯à¦¾à¦¨à§à¦¯ অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨à¦—à§à¦²à¦¿ বনà§à¦§ করà§à¦¨</translation>
-<translation id="1053591932240354961">à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ আপনি <ph name="SITE" /> ঠযেতে পারবেন না কারণ ওয়েবসাইটটি à¦à¦®à¦¨ অবোধà§à¦¯ শংসাপতà§à¦° পাঠিয়েছে যেটি Google Chrome চালাতে পারছে না। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত কিছà§à¦•à§à¦·à¦¨à§‡à¦° জনà§à¦¯ হয়ে থাকে, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="1055184225775184556">&amp;যোগ করাকে পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
<translation id="10614374240317010">কখনও সংরকà§à¦·à¦¿à¦¤ হয়নি</translation>
<translation id="106701514854093668">ডেসà§à¦•à¦Ÿà¦ª বà§à¦•à¦®à¦¾à¦°à§à¦•</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">নীতি কà§à¦¯à¦¾à¦¶à§‡à¦Ÿà¦¿ ঠিক আছে</translation>
<translation id="113188000913989374"><ph name="SITE" /> বলছে:</translation>
<translation id="1132774398110320017">Chrome সà§à¦¬à¦¤à¦ƒà¦ªà§‚রà§à¦£ সেটিংস...</translation>
+<translation id="1150979032973867961">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° নিকট বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
+<translation id="1151972924205500581">পাসওয়ারà§à¦¡ পà§à¦°à§Ÿà§‹à¦œà¦¨</translation>
<translation id="1152921474424827756"><ph name="URL" /> à¦à¦° <ph name="BEGIN_LINK" />কà§à¦¯à¦¾à¦¶à§‡ করা অনà§à¦²à¦¿à¦ªà¦¿<ph name="END_LINK" /> অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ করà§à¦¨</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¦­à¦¾à¦¬à§‡ সংযোগ বনà§à¦§ করেছে।</translation>
<translation id="1161325031994447685">ওয়াই-ফাই ঠআবার সংযà§à¦•à§à¦¤ করে দেখà§à¦¨</translation>
+<translation id="1165039591588034296">তà§à¦°à§à¦Ÿà¦¿</translation>
<translation id="1175364870820465910">&amp;মà§à¦¦à§à¦°à¦£...</translation>
<translation id="1181037720776840403">সরান</translation>
<translation id="1184214524891303587">নিরাপতà§à¦¤à¦¾à¦° সমà§à¦­à¦¾à¦¬à§à¦¯ লঙà§à¦˜à¦¨à§‡à¦° ঘটনাগà§à¦²à¦¿à¦° বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ বিবরণ Google à¦à¦° কাছে <ph name="BEGIN_WHITEPAPER_LINK" />সà§à¦¬à¦¯à¦¼à¦‚কà§à¦°à¦¿à¦¯à¦¼à¦­à¦¾à¦¬à§‡ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ করà§à¦¨<ph name="END_WHITEPAPER_LINK" />। <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">à¦à¦‡ সাইট থেকে আরো</translation>
<translation id="1206967143813997005">নষà§à¦Ÿ পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• সà§à¦¬à¦¾à¦•à§à¦·à¦°</translation>
<translation id="1209206284964581585">à¦à¦–নকার মতো লà§à¦•à¦¾à¦¨</translation>
+<translation id="121201262018556460">আপনি <ph name="DOMAIN" />-ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ করেছেন, কিনà§à¦¤à§ সারà§à¦­à¦¾à¦° à¦à¦•à¦Ÿà¦¿ দà§à¦°à§à¦¬à¦² কী সমà§à¦¬à¦²à¦¿à¦¤ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে৷ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কী ভঙà§à¦— করে থাকতে পারে à¦à¦¬à¦‚ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ আপনার পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ সারà§à¦­à¦¾à¦° নাও হতে পারে (হতে পারে আপনি à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° সাথে যোগাযোগ করছেন)৷</translation>
<translation id="1219129156119358924">সিসà§à¦Ÿà§‡à¦® নিরাপতà§à¦¤à¦¾</translation>
<translation id="1227224963052638717">অজানা নীতি৷</translation>
<translation id="1227633850867390598">মান লà§à¦•à¦¾à¦¨</translation>
<translation id="1228893227497259893">ভà§à¦² সতà§à¦¤à¦¾ সনাকà§à¦¤à¦•à¦¾à¦°à§€</translation>
<translation id="1232569758102978740">শিরোনামহীন</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (সিঙà§à¦• হয়েছে)</translation>
<translation id="1263231323834454256">পড়ার তালিকা</translation>
<translation id="1264126396475825575">কà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ <ph name="CRASH_TIME" /> ঠকà§à¦¯à¦¾à¦ªà¦šà¦¾à¦° করা হয়েছে (à¦à¦–নো আপলোড করা বা উপেকà§à¦·à¦¾ করা হয়নি)</translation>
+<translation id="1281526147609854549">জারি করেছে <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">বিপজà§à¦œà¦¨à¦• কনà§à¦Ÿà§‡à¦¨à§à¦Ÿ বà§à¦²à¦• করা হয়েছে</translation>
<translation id="1285320974508926690">কখনই à¦à¦‡ সাইটটিকে অনà§à¦¬à¦¾à¦¦ করবেন না</translation>
<translation id="129553762522093515">সমà§à¦ªà§à¦°à¦¤à¦¿ বনà§à¦§ হয়েছে</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />আপনার কà§à¦•à¦¿à¦œ সাফ করে দেখà§à¦¨<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">à¦à¦—à§à¦²à¦¿à¦¤à§‡ আপনার কারà§à¦¯à¦•à¦²à¦¾à¦ª <ph name="BEGIN_EMPHASIS" />à¦à¦–নও দেখা যেতে পারে<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />যে ওয়েবসাইট আপনি দেখেছেন
+ <ph name="LIST_ITEM" />আপনার নিয়োগকরà§à¦¤à¦¾ অথবা সà§à¦•à§à¦²
+ <ph name="LIST_ITEM" />আপনার ইনà§à¦Ÿà¦¾à¦°à¦¨à§‡à¦Ÿ পরিষেবা পà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">ডোমেন নথিভà§à¦•à§à¦¤ করà§à¦¨:</translation>
<translation id="1340482604681802745">যে ঠিকানা থেকে নিতে হবে</translation>
<translation id="1344211575059133124">মনে হচà§à¦›à§‡ à¦à¦‡ সাইটটি ঘà§à¦°à§‡ দেখতে আপনাকে অনà§à¦®à¦¤à¦¿ নিতে হবে</translation>
<translation id="1344588688991793829">Chromium সà§à¦¬à¦¤à¦ƒà¦ªà§‚রà§à¦£ সেটিংস...</translation>
+<translation id="1348198688976932919">যে সাইট খà§à¦²à¦¤à§‡ চলেছেন সেটিতে বিপজà§à¦œà¦¨à¦• অà§à¦¯à¦¾à¦ª আছে</translation>
<translation id="1374468813861204354">পà§à¦°à¦¸à§à¦¤à¦¾à¦¬à¦¨à¦¾à¦—à§à¦²à¦¿</translation>
<translation id="1375198122581997741">সংসà§à¦•à¦°à¦£ সমà§à¦ªà¦°à§à¦•à§‡</translation>
<translation id="1377321085342047638">কারà§à¦¡ নমà§à¦¬à¦°</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> কোনো তথà§à¦¯ পাঠায়নি।</translation>
<translation id="1407135791313364759">সব খà§à¦²à§à¦¨</translation>
<translation id="1413809658975081374">গোপনীয়তা তà§à¦°à§à¦Ÿà¦¿</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" />-তে <ph name="ORGANIZATION" />-à¦à¦° পরিচয় <ph name="ISSUER" /> যাচাই করেছে৷</translation>
<translation id="1426410128494586442">হà§à¦¯à¦¾à¦</translation>
<translation id="1430915738399379752">পà§à¦°à¦¿à¦¨à§à¦Ÿ</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> ঠপৃষà§à¦ à¦¾ পরিদরà§à¦¶à¦¨ করার<ph name="END_LINK" /> পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ অবরà§à¦¦à§à¦§ করা হয়েছে৷</translation>
-<translation id="1491663344921578213">আপনি à¦à¦–ন <ph name="SITE" /> ঠযেতে পারবেন না কারণ ওয়েবসাইটটি পিন করা শংসাপতà§à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° করছে। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়ে থাকে, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />টি}one{<ph name="PAYMENT_METHOD_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />টি}other{<ph name="PAYMENT_METHOD_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />টি}}</translation>
<translation id="1506687042165942984">à¦à¦‡ পৃষà§à¦ à¦¾à¦° à¦à¦•à¦Ÿà¦¿ সংরকà§à¦·à¦¿à¦¤ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ (অরà§à¦¥à¦¾à§Ž,তারিখ সীমার বাইরে হিসাবে পরিচিত) পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করà§à¦¨à§·</translation>
<translation id="1517433312004943670">ফোন নমà§à¦¬à¦° আবশà§à¦¯à¦•</translation>
<translation id="1519264250979466059">নিরà§à¦®à¦¾à¦£à§‡à¦° তারিখ</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">à¦à¦‡ বৈশিষà§à¦Ÿà§à¦¯à¦Ÿà¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করার জনà§à¦¯ JavaScript সকà§à¦·à¦® করা পà§à¦°à§Ÿà§‹à¦œà¦¨à¥¤</translation>
<translation id="1555130319947370107">নীল</translation>
<translation id="1559528461873125649">à¦à¦®à¦¨ কোন ফাইল বা ডিরেকà§à¦Ÿà¦°à¦¿ নেই</translation>
-<translation id="1559572115229829303">&lt;p&gt;<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ঠà¦à¦•à¦Ÿà¦¿ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা যায়নি কারণ আপনার ডিভাইসের তারিখ à¦à¦¬à¦‚ সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়৷&lt;/p&gt;
-
-&lt;p&gt;দয়া করে &lt;strong&gt;সেটিংস&lt;/strong&gt; অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨à§‡à¦° &lt;strong&gt;সাধারণ&lt;/strong&gt; বিভাগ থেকে তারিখ à¦à¦¬à¦‚ সময় সংশোধন করà§à¦¨à§·&lt;/p&gt;</translation>
<translation id="1583429793053364125">à¦à¦‡ ওয়েবপৃষà§à¦ à¦¾à¦Ÿà¦¿ দেখানোর সময় কোনো সমসà§à¦¯à¦¾ হয়েছে।</translation>
<translation id="1592005682883173041">সà§à¦¥à¦¾à¦¨à§€à§Ÿ ডেটা অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸</translation>
+<translation id="1594030484168838125">বেছে নিন</translation>
<translation id="161042844686301425">নীলাভ</translation>
+<translation id="1620510694547887537">কà§à¦¯à¦¾à¦®à§‡à¦°à¦¾</translation>
<translation id="1629803312968146339">আপনি কি চান যে Chrome à¦à¦‡ কারà§à¦¡ সংরকà§à¦·à¦£ করà§à¦•?</translation>
<translation id="1639239467298939599">লোড হচà§à¦›à§‡</translation>
<translation id="1640180200866533862">বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নীতিসমূহ</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">নেটওয়ারà§à¦• কনফিগারেশনটি অবৈধ à¦à¦¬à¦‚ আমদানি করা যায়নি৷</translation>
<translation id="1644574205037202324">ইতিহাস</translation>
<translation id="1645368109819982629">অসমরà§à¦¥à¦¿à¦¤ পà§à¦°à§‹à¦Ÿà§‹à¦•à¦²</translation>
+<translation id="1655462015569774233">{1,plural, =1{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ গতকাল মেয়াদোতà§à¦¤à§€à¦°à§à¦£ হয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° ঘড়ি বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="CURRENT_DATE" /> ঠসেট করা আছে। à¦à¦Ÿà¦¿ কি ঠিক আছে বলে মনে হচà§à¦›à§‡? যদি তা না হয়, তাহলে আপনার সিসà§à¦Ÿà§‡à¦® ঘড়িটি ঠিক করা উচিত হবে à¦à¦¬à¦‚ তারপর à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ রিফà§à¦°à§‡à¦¶ করা উচিত।}one{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ # দিন আগে মেয়াদোতà§à¦¤à§€à¦°à§à¦£ হয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° ঘড়ি বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="CURRENT_DATE" /> ঠসেট করা আছে। à¦à¦Ÿà¦¿ কি ঠিক আছে বলে মনে হচà§à¦›à§‡? যদি তা না হয়, তাহলে আপনার সিসà§à¦Ÿà§‡à¦® ঘড়িটি ঠিক করা উচিত হবে à¦à¦¬à¦‚ তারপর à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ রিফà§à¦°à§‡à¦¶ করা উচিত।}other{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ # দিন আগে মেয়াদোতà§à¦¤à§€à¦°à§à¦£ হয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° ঘড়ি বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="CURRENT_DATE" /> ঠসেট করা আছে। à¦à¦Ÿà¦¿ কি ঠিক আছে বলে মনে হচà§à¦›à§‡? যদি তা না হয়, তাহলে আপনার সিসà§à¦Ÿà§‡à¦® ঘড়িটি ঠিক করা উচিত হবে à¦à¦¬à¦‚ তারপর à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ রিফà§à¦°à§‡à¦¶ করা উচিত।}}</translation>
<translation id="1656489000284462475">তà§à¦²à§‡ নিন</translation>
<translation id="1663943134801823270">Chrome থেকে কারà§à¦¡ à¦à¦¬à¦‚ ঠিকানাগà§à¦²à¦¿ à¦à¦¸à§‡à¦›à§‡à¥¤ আপনি <ph name="BEGIN_LINK" />সেটিংস<ph name="END_LINK" /> ঠà¦à¦—à§à¦²à¦¿ পরিচালনা করতে পারবেন।</translation>
<translation id="1676269943528358898"><ph name="SITE" /> সাধারণত আপনার তথà§à¦¯ সà§à¦°à¦•à§à¦·à¦¿à¦¤ রাখতে à¦à¦¨à¦•à§à¦°à¦¿à¦ªà¦¶à¦¾à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে। à¦à¦‡à¦¬à¦¾à¦° যখন Google Chrome <ph name="SITE" /> à¦à¦° সাথে সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করার চেষà§à¦Ÿà¦¾ করেছে, তখন ওয়েবসাইটটি অসà§à¦¬à¦¾à¦­à¦¾à¦¬à¦¿à¦• à¦à¦¬à¦‚ ভà§à¦² শংসাপতà§à¦° পাঠিয়েছে। হয় à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ <ph name="SITE" /> হওয়ার ভান করছে, অথবা কোনো ওয়াই-ফাই পà§à¦°à¦¬à§‡à¦¶ করà§à¦¨ সà§à¦•à§à¦°à§€à¦£ সংযোগকে বাধা দেওয়া হয়েছে। আপনার তথà§à¦¯ à¦à¦–নো নিরাপদ আছে কারণ কোনো ডেটা আদানপà§à¦°à¦¦à¦¾à¦¨à§‡à¦° আগেই Google Chrome সংযোগটিকে বনà§à¦§ করে দিয়েছে।</translation>
-<translation id="168328519870909584">বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ঠথাকা আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনার ডিভাইসে বিপদজনক অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨ ইনà§à¦¸à¦Ÿà¦² করার চেষà§à¦Ÿà¦¾ করতে পারে, যা আপনার তথà§à¦¯ (উদাহরণসà§à¦¬à¦°à§‚প, ফটো, পাসওয়ারà§à¦¡, বারà§à¦¤à¦¾, à¦à¦¬à¦‚ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) চà§à¦°à¦¿ করতে বা মà§à¦›à§‡ দিতে পারে।</translation>
<translation id="168841957122794586">সারà§à¦­à¦¾à¦° শংসাপতà§à¦°à§‡ à¦à¦•à¦Ÿà¦¿ দà§à¦°à§à¦¬à¦² কপিরাইট কী আছে৷</translation>
+<translation id="1706954506755087368">{1,plural, =1{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আগামীকালের বলে মনে হচà§à¦›à§‡à¥¤ কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে।}one{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আগামী # দিন পরের বলে মনে হচà§à¦›à§‡à¥¤ কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে।}other{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আগামী # দিন পরের বলে মনে হচà§à¦›à§‡à¥¤ কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে।}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">à¦à¦‡ সাইটে যেতে আপনাকে <ph name="NAME" /> à¦à¦° কাছ থেকে অনà§à¦®à¦¤à¦¿ নিতে হবে</translation>
<translation id="1721424275792716183">* à¦à¦‡ ফিলà§à¦¡à§‡ কিছৠলেখা পà§à¦°à§Ÿà§‹à¦œà¦¨</translation>
@@ -91,23 +104,27 @@
<translation id="1745358365027406341">পৃষà§à¦ à¦¾à¦Ÿà¦¿ পরে ডাউনলোড করà§à¦¨</translation>
<translation id="17513872634828108">খোলা টà§à¦¯à¦¾à¦¬</translation>
<translation id="1753706481035618306">পৃষà§à¦ à¦¾ সংখà§à¦¯à¦¾</translation>
+<translation id="1763864636252898013">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আপনার ডিভােইসের নিকট বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows নেটওয়ারà§à¦• ডায়গনিসà§à¦Ÿà¦¿à¦•à§à¦¸ চালিয়ে দেখà§à¦¨<ph name="END_LINK" />।</translation>
<translation id="1783075131180517613">দয়া করে আপনার সিঙà§à¦• পাসফà§à¦°à§‡à¦œ আপডেট করà§à¦¨à§·</translation>
<translation id="1787142507584202372">আপনার খোলা টà§à¦¯à¦¾à¦¬à¦—à§à¦²à¦¿ à¦à¦–ানে দেখা যাবে</translation>
+<translation id="1789575671122666129">পপআপ</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">কারà§à¦¡ হোলà§à¦¡à¦¾à¦°à§‡à¦° নাম</translation>
-<translation id="1803678881841855883">Google নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সমà§à¦ªà§à¦°à¦¤à¦¿ <ph name="SITE" /> ঠ<ph name="BEGIN_LINK" />মালওয়ের শনাকà§à¦¤ করেছে<ph name="END_LINK" />। যেসব ওয়েবসাইট সাধারণত নিরাপদ থাকে, সেগà§à¦²à¦¿ কখনও কখনও মালওয়ের দà§à¦¬à¦¾à¦°à¦¾ আকà§à¦°à¦¾à¦¨à§à¦¤ হয়। à¦à¦•à¦Ÿà¦¿ পরিচিত মালওয়ের বিতরণকারী, <ph name="SUBRESOURCE_HOST" /> থেকে কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• সামগà§à¦°à§€à¦Ÿà¦¿ à¦à¦¸à§‡à¦›à§‡à¥¤ <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="1806541873155184440">যোগ করা হয়েছে <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">অবৈধ অনà§à¦°à§‹à¦§ বা অনà§à¦°à§‹à¦§ মাপকাঠিগà§à¦²à¦¿</translation>
<translation id="1826516787628120939">চেক করা হচà§à¦›à§‡</translation>
<translation id="1834321415901700177">à¦à¦‡ সাইটটিতে কà§à¦·à¦¤à¦¿à¦•à¦° পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® রয়েছে</translation>
+<translation id="1840414022444569775">à¦à¦‡ কারà§à¦¡à§‡à¦° নমà§à¦¬à¦°à¦Ÿà¦¿ আগেই বà§à¦¯à¦¬à¦¹à¦¾à¦° করেছেন</translation>
<translation id="1842969606798536927">অরà§à¦¥ পà§à¦°à¦¦à¦¾à¦¨ করà§à¦¨</translation>
<translation id="1871208020102129563">
পà§à¦°à¦•à§à¦¸à¦¿ সà§à¦¥à¦¿à¦° পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦°à¦—à§à¦²à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করতে সেট করা আছে কোনো .pac সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ URL নয়৷</translation>
<translation id="1871284979644508959">আবশà§à¦¯à¦• কà§à¦·à§‡à¦¤à§à¦°</translation>
<translation id="187918866476621466">শà§à¦°à§à¦° পৃষà§à¦ à¦¾à¦—à§à¦²à¦¿ খà§à¦²à§à¦¨</translation>
<translation id="1883255238294161206">তালিকা সঙà§à¦•à§à¦šà¦¿à¦¤ করà§à¦¨</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />টি}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />টি}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />টি}}</translation>
<translation id="1898423065542865115">ফিলà§à¦Ÿà¦¾à¦° হচà§à¦›à§‡</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{কিছà§à¦‡ নয়}=1{১টি সাইট}one{#টি সাইট}other{#টি সাইট}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> ঠযান</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> বà§à¦•à¦®à¦¾à¦°à§à¦•à¦—à§à¦²à¦¿</translation>
<translation id="1973335181906896915">ধারাবাহিকতাতে তà§à¦°à§à¦Ÿà¦¿</translation>
@@ -131,42 +148,48 @@
<translation id="2114841414352855701">à¦à§œà¦¿à§Ÿà§‡ যাওয়া হয়েছে কারণ à¦à¦Ÿà¦¿ <ph name="POLICY_NAME" />-দà§à¦¬à¦¾à¦°à¦¾ ওভাররাইড করা হয়েছিল৷</translation>
<translation id="2138201775715568214">আশেপাশের বাসà§à¦¤à¦¬à¦¿à¦• ওয়েব পৃষà§à¦ à¦¾à¦—à§à¦²à¦¿ খà§à¦à¦œà¦›à§‡</translation>
<translation id="213826338245044447">মোবাইল বà§à¦•à¦®à¦¾à¦°à§à¦•</translation>
-<translation id="2148716181193084225">আজ</translation>
+<translation id="2147827593068025794">পটভূমি সিঙà§à¦•</translation>
<translation id="2154054054215849342">আপনার ডোমেনের জনà§à¦¯ সিঙà§à¦• উপলবà§à¦§ নেই</translation>
<translation id="2154484045852737596">কারà§à¦¡ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করà§à¦¨</translation>
<translation id="2166049586286450108">পূরà§à¦£ পà§à¦°à¦¶à¦¾à¦¸à¦• অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸</translation>
<translation id="2166378884831602661">à¦à¦‡ সাইটটি à¦à¦•à¦Ÿà¦¿ সà§à¦°à¦•à§à¦·à¦¿à¦¤ সংযোগ দিতে পারছে না</translation>
<translation id="2181821976797666341">নীতিসমূহ</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{১টি ঠিকানা}one{ #টি ঠিকানা}other{ #টি ঠিকানা}}</translation>
+<translation id="2187317261103489799">সনাকà§à¦¤ করà§à¦¨ (ডিফলà§à¦Ÿ)</translation>
<translation id="2202020181578195191">মেয়াদ শেষ হওয়ার বছরের সঠিক মান লিখà§à¦¨</translation>
<translation id="2212735316055980242">নীতি পাওয়া যায়নি</translation>
<translation id="2213606439339815911">à¦à¦¨à§à¦Ÿà§à¦°à¦¿à¦—à§à¦²à¦¿ আনা হচà§à¦›à§‡...</translation>
+<translation id="2218879909401188352"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ঠযে আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ সকà§à¦°à¦¿à§Ÿ আছে, তারা à¦à¦®à¦¨ বিপজà§à¦œà¦¨à¦• অà§à¦¯à¦¾à¦ª ইনসà§à¦Ÿà¦² করে দিতে পারে যেগà§à¦²à¦¿ আপনার ডিভাইসের কà§à¦·à¦¤à¦¿ করতে, আপনার মোবাইলের বিলে লà§à¦•à¦¾à¦¨à§‹ চারà§à¦œ যোগ করতে, বা আপনার বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত তথà§à¦¯ চà§à¦°à¦¿ করতে পারে৷ <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />ডায়াগনসà§à¦Ÿà¦¿à¦• অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨<ph name="END_LINK" /> বà§à¦¯à¦¬à¦¹à¦¾à¦° করে আপনার সংযোগ ঠিক করà§à¦¨</translation>
<translation id="2239100178324503013">à¦à¦–নই পাঠান</translation>
<translation id="225207911366869382">à¦à¦‡ মান à¦à¦‡ নীতির জনà§à¦¯ অসমরà§à¦¥à¦¿à¦¤ হয়েছে৷</translation>
<translation id="2262243747453050782">HTTP তà§à¦°à§à¦Ÿà¦¿</translation>
+<translation id="2270484714375784793">ফোন নমà§à¦¬à¦°</translation>
<translation id="2282872951544483773">অনà§à¦ªà¦²à¦¬à§à¦§ পরীকà§à¦·à¦¾à¦¨à¦¿à¦°à§€à¦•à§à¦·à¦¾à¦—à§à¦²à¦¿</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" />টি আইটেম}one{<ph name="ITEM_COUNT" />টি আইটেম}other{<ph name="ITEM_COUNT" />টি আইটেম}}</translation>
<translation id="2292556288342944218">আপনার ইনà§à¦Ÿà¦¾à¦°à¦¨à§‡à¦Ÿ অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ অবরà§à¦¦à§à¦§ করা হয়েছে</translation>
<translation id="230155334948463882">নতà§à¦¨ কারà§à¦¡?</translation>
-<translation id="2305919008529760154">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ পà§à¦°à¦¤à¦¾à¦°à¦£à¦¾à¦ªà§‚রà§à¦£ উপায়ে জারি করা হতে পারে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> à¦à¦° জনà§à¦¯ à¦à¦•à¦Ÿà¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম à¦à¦¬à¦‚ পাসওয়ারà§à¦¡ পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨à¥¤</translation>
-<translation id="2318774815570432836">আপনি à¦à¦–ন <ph name="SITE" /> ঠযেতে পারবেন না কারণ ওয়েবসাইটটি HSTS বà§à¦¯à¦¬à¦¹à¦¾à¦° করছে। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়ে থাকে, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
+<translation id="2337852623177822836">সেটিংস আপনার পà§à¦°à¦¶à¦¾à¦¸à¦• নিয়নà§à¦¤à§à¦°à¦£ করে</translation>
<translation id="2354001756790975382">অনà§à¦¯ বà§à¦•à¦®à¦¾à¦°à§à¦•à¦¸</translation>
+<translation id="2354430244986887761">Google নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সমà§à¦ªà§à¦°à¦¤à¦¿ <ph name="SITE" /> ঠ<ph name="BEGIN_LINK" />কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• অà§à¦¯à¦¾à¦ª<ph name="END_LINK" /> খà§à¦à¦œà§‡ পেয়েছে।</translation>
<translation id="2355395290879513365">আপনি à¦à¦‡ সাইটে যেসব ছবি দেখছেন, আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ সেগà§à¦²à¦¿ দেখতে পেতে পারে à¦à¦¬à¦‚ সেগà§à¦²à¦¿ পরিবরà§à¦¤à¦¨ করে আপনাকে বোকা বানাতে পারে।</translation>
+<translation id="2356070529366658676">জিজà§à¦žà¦¾à¦¸à¦¾ করà§à¦¨</translation>
+<translation id="2359629602545592467">à¦à¦•à¦¾à¦§à¦¿à¦•</translation>
<translation id="2359808026110333948">অবিরত</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> ঠকà§à¦¯à¦¾à¦ªà¦šà¦¾à¦° করা কà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ আপলোড করা হয়নি</translation>
<translation id="2367567093518048410">সà§à¦¤à¦°</translation>
-<translation id="2371153335857947666">{1,plural, =1{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ গতকাল মেয়াদোতà§à¦¤à§€à¦°à§à¦£ হয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° ঘড়ি বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="CURRENT_DATE" /> ঠসেট করা আছে। à¦à¦Ÿà¦¿ কি ঠিক আছে বলে মনে হচà§à¦›à§‡? যদি তা না হয়, তাহলে আপনার সিসà§à¦Ÿà§‡à¦® ঘড়িটি ঠিক করা উচিত হবে à¦à¦¬à¦‚ তারপর à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ রিফà§à¦°à§‡à¦¶ করা উচিত। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।}one{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ # দিন আগে মেয়াদোতà§à¦¤à§€à¦°à§à¦£ হয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° ঘড়ি বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="CURRENT_DATE" /> ঠসেট করা আছে। à¦à¦Ÿà¦¿ কি ঠিক আছে বলে মনে হচà§à¦›à§‡? যদি তা না হয়, তাহলে আপনার সিসà§à¦Ÿà§‡à¦® ঘড়িটি ঠিক করা উচিত হবে à¦à¦¬à¦‚ তারপর à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ রিফà§à¦°à§‡à¦¶ করা উচিত। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।}other{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ # দিন আগে মেয়াদোতà§à¦¤à§€à¦°à§à¦£ হয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° ঘড়ি বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="CURRENT_DATE" /> ঠসেট করা আছে। à¦à¦Ÿà¦¿ কি ঠিক আছে বলে মনে হচà§à¦›à§‡? যদি তা না হয়, তাহলে আপনার সিসà§à¦Ÿà§‡à¦® ঘড়িটি ঠিক করা উচিত হবে à¦à¦¬à¦‚ তারপর à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ রিফà§à¦°à§‡à¦¶ করা উচিত। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।}}</translation>
<translation id="237718015863234333">কোনো UI বিকলà§à¦ª উপলবà§à¦§ নেই</translation>
<translation id="2384307209577226199">à¦à¦¨à§à¦Ÿà¦¾à¦°à¦ªà§à¦°à¦¾à¦‡à¦œ ডিফলà§à¦Ÿ</translation>
<translation id="2386255080630008482">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦°à¦Ÿà¦¿ পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করা হয়েছে৷</translation>
<translation id="2392959068659972793">কোনো মান সেট করা নেই à¦à¦®à¦¨ নীতিগà§à¦²à¦¿ দেখান</translation>
<translation id="239429038616798445">à¦à¦‡ পদà§à¦§à¦¤à¦¿à¦¤à§‡ শিপিং করা যাবে না। অনà§à¦¯ পদà§à¦§à¦¤à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤</translation>
<translation id="2396249848217231973">&amp;মà§à¦›à§‡ ফেলাকে পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
-<translation id="2460160116472764928">Google নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সমà§à¦ªà§à¦°à¦¤à¦¿ <ph name="SITE" /> ঠ<ph name="BEGIN_LINK" />মালওয়ের শনাকà§à¦¤ করেছে<ph name="END_LINK" />। যেসব ওয়েবসাইট সাধারণত নিরাপদ থাকে, সেগà§à¦²à¦¿ কখনও কখনও মালওয়ের দà§à¦¬à¦¾à¦°à¦¾ আকà§à¦°à¦¾à¦¨à§à¦¤ হয়। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
+<translation id="2413528052993050574">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করা হতে পারে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
<translation id="2463739503403862330">পূরণ করà§à¦¨</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />নেটওয়ারà§à¦• ডায়গনিসà§à¦Ÿà¦¿à¦•à§à¦¸ চালান<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">অবৈধ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° URL৷</translation>
+<translation id="2482878487686419369">বিজà§à¦žà¦ªà§à¦¤à¦¿à¦—à§à¦²à¦¿</translation>
<translation id="2491120439723279231">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦°à§‡ তà§à¦°à§à¦Ÿà¦¿ আছে৷</translation>
<translation id="2495083838625180221">JSON বিশà§à¦²à§‡à¦·à¦•</translation>
<translation id="2495093607237746763">টিক চিহà§à¦£ দেওয়া থাকলে, ফরà§à¦® পূরনের কাজ দà§à¦°à§à¦¤ করতে Chromium à¦à¦‡ ডিভাইসে আপনার কারà§à¦¡à§‡à¦° à¦à¦•à¦Ÿà¦¿ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ সঞà§à¦šà§Ÿ করবে।</translation>
@@ -174,27 +197,28 @@
<translation id="2501278716633472235">ফিরে যান</translation>
<translation id="2515629240566999685">আপনার à¦à¦²à¦¾à¦•à¦¾à¦¯à¦¼ সংকেত পরীকà§à¦·à¦¾ করে দেখà§à¦¨</translation>
<translation id="2516305470678292029">UI বিকলà§à¦ªà¦—à§à¦²à¦¿</translation>
+<translation id="2539524384386349900">সনাকà§à¦¤ করà§à¦¨</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> à¦à¦•à¦Ÿà¦¿ অবৈধ পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ পাঠিয়েছে।</translation>
-<translation id="2552545117464357659">নবীনতর</translation>
<translation id="2556876185419854533">&amp;সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦•à§‡ পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> থেকে পাওয়া। à¦à¦Ÿà¦¿ à¦à¦¬à¦‚ আরো <ph name="OTHER_ARTICLE_COUNT" />টি গলà§à¦ª পড়à§à¦¨à¥¤</translation>
<translation id="2587841377698384444">ডিরেকà§à¦Ÿà¦°à¦¿ API আইডি:</translation>
<translation id="2597378329261239068">à¦à¦‡ দসà§à¦¤à¦¾à¦¬à§‡à¦œà¦Ÿà¦¿ পাসওয়ারà§à¦¡ সà§à¦°à¦•à§à¦·à¦¿à¦¤à§· দয়া করে à¦à¦•à¦Ÿà¦¿ পাসওয়ারà§à¦¡ লিখà§à¦¨à§·</translation>
<translation id="2609632851001447353">বৈচিতà§à¦°à¦¤à¦¾</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{কিছà§à¦‡ নয়}=1{১টি অà§à¦¯à¦¾à¦ª ($১)}=2{২টি অà§à¦¯à¦¾à¦ª ($১, $২)}one{#টি অà§à¦¯à¦¾à¦ª ($১, $২, $৩)}other{#টি অà§à¦¯à¦¾à¦ª ($১, $২, $৩)}}</translation>
<translation id="2625385379895617796">আপনার ঘড়ির সময় অনেকটা à¦à¦—িয়ে</translation>
<translation id="2639739919103226564">সà§à¦¥à¦¿à¦¤à¦¿: </translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ফাইলে অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ অসà§à¦¬à§€à¦•à§ƒà¦¤ হয়েছে</translation>
<translation id="2653659639078652383">জমা</translation>
<translation id="2666117266261740852">অনà§à¦¯à¦¾à¦¨à§à¦¯ টà§à¦¯à¦¾à¦¬ বা অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨à¦—à§à¦²à¦¿ বনà§à¦§ করà§à¦¨</translation>
+<translation id="2670429602441959756">à¦à¦‡ পৃষà§à¦ à¦¾à§Ÿ à¦à¦®à¦¨ কিছৠবৈশিষà§à¦Ÿà§à¦¯ রয়েছে যা à¦à¦–নও VR ঠসমরà§à¦¥à¦¿à¦¤ নয়। পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করা হচà§à¦›à§‡...</translation>
<translation id="2674170444375937751">আপনি কি আপনার ইতিহাস থেকে à¦à¦‡ পৃষà§à¦ à¦¾à¦—à§à¦²à¦¿ মোছার বিষয়ে নিশà§à¦šà¦¿à¦¤?</translation>
<translation id="2677748264148917807">ছেড়ে চলে যান</translation>
-<translation id="269990154133806163">সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে যেটি শংসাপতà§à¦°à§‡à¦° সà§à¦¬à¦šà§à¦›à¦¤à¦¾à¦° নীতি বà§à¦¯à¦¬à¦¹à¦¾à¦° করে সরà§à¦¬à¦œà¦¨à§€à¦¨à¦­à¦¾à¦¬à§‡ পà§à¦°à¦•à¦¾à¦¶ করা হয়নি। à¦à¦Ÿà¦¿ কিছৠশংসাপতà§à¦°à§‡à¦° জনà§à¦¯ à¦à¦•à¦Ÿà¦¿ আবশà§à¦¯à¦•à¦¤à¦¾, যাতে করে সেগà§à¦²à¦¿à¦° বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯à¦¤à¦¾ নিশà§à¦šà¦¿à¦¤ করা যায় à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦¦à§‡à¦° বিরà§à¦¦à§à¦§à§‡ সà§à¦°à¦•à§à¦·à¦¾ নেওয়া যায়।<ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="2702801445560668637">পড়ার তালিকা</translation>
<translation id="2704283930420550640">বিনà§à¦¯à¦¾à¦¸à§‡à¦° সাথে মূলà§à¦¯ মেলে না৷</translation>
<translation id="2704951214193499422">Chromium à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ আপনার কারà§à¦¡ নিশà§à¦šà¦¿à¦¤ করতে অকà§à¦·à¦® হয়েছে৷ দয়া করে পরে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à§·</translation>
<translation id="2705137772291741111">à¦à¦‡ সাইটের সংরকà§à¦·à¦¿à¦¤ (সঞà§à¦šà¦¿à¦¤) অনà§à¦²à¦¿à¦ªà¦¿ পড়া সমà§à¦­à¦¬ হয়নি।</translation>
<translation id="2709516037105925701">সà§à¦¬à§Ÿà¦‚পূরণ</translation>
-<translation id="2712118517637785082">আপনি <ph name="DOMAIN" /> ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ করেছেন, তবে সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ যে শংসাপতà§à¦°à¦Ÿà¦¿ উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে সেটির ইসà§à¦¯à§à¦•à¦¾à¦°à§€ সেটিকে পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করেছে। à¦à¦° অরà§à¦¥ হ'ল সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ যে সà§à¦°à¦•à§à¦·à¦¾ পà§à¦°à¦®à¦¾à¦¨à¦ªà¦¤à§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে তা à¦à¦•à§‡à¦¬à¦¾à¦°à§‡à¦‡ বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়। হতে পারে আপনি à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° সাথে যোগাযোগ করছেন। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="2712173769900027643">অনà§à¦®à¦¤à¦¿ নিন</translation>
<translation id="2713444072780614174">সাদা</translation>
<translation id="2720342946869265578">আশেপাশে</translation>
@@ -207,19 +231,22 @@
<translation id="277499241957683684">ডিভাইস রেকরà§à¦¡ অনà§à¦ªà¦¸à§à¦¥à¦¿à¦¤</translation>
<translation id="2784949926578158345">সংযোগ পà§à¦¨à¦ƒà¦¸à§‡à¦Ÿ করা হয়েছে৷</translation>
<translation id="2794233252405721443">সাইট অবরà§à¦¦à§à¦§ করা হয়েছে</translation>
+<translation id="2799020568854403057">যে সাইট খà§à¦²à¦¤à§‡ চলেছেন সেটিতে কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• অà§à¦¯à¦¾à¦ª আছে</translation>
+<translation id="2803306138276472711">Google নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সামà§à¦ªà§à¦°à¦¤à¦¿à¦• <ph name="SITE" /> ঠ<ph name="BEGIN_LINK" />মà§à¦¯à¦¾à¦²à¦“য়à§à¦¯à¦¾à¦° শনাকà§à¦¤ করেছে<ph name="END_LINK" />। যেসব ওয়েবসাইট সাধারণত নিরাপদ থাকে, সেগà§à¦²à¦¿ কখনও কখনও মà§à¦¯à¦¾à¦²à¦“য়à§à¦¯à¦¾à¦° দà§à¦¬à¦¾à¦°à¦¾ আকà§à¦°à¦¾à¦¨à§à¦¤ হয়।</translation>
<translation id="2824775600643448204">ঠিকানা à¦à¦¬à¦‚ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ দণà§à¦¡</translation>
<translation id="2826760142808435982"><ph name="CIPHER" /> বà§à¦¯à¦¬à¦¹à¦¾à¦° করে à¦à¦‡ সংযোগটি à¦à¦¨à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦¡ à¦à¦¬à¦‚ পà§à¦°à¦®à¦¾à¦£à§€à¦•à§ƒà¦¤ করা হয়েছে à¦à¦¬à¦‚ কী à¦à¦•à§à¦¸à¦šà§‡à¦žà§à¦œ পà§à¦°à¦•à§à¦°à¦¿à§Ÿà¦¾ হিসাবে <ph name="KX" /> বà§à¦¯à¦¬à¦¹à¦¾à¦° করে৷</translation>
<translation id="2835170189407361413">ফরà§à¦® সাফ করà§à¦¨</translation>
+<translation id="2856444702002559011">আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ হয়ত <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> থেকে আপনার তথà§à¦¯ (যেমন পাসওয়ারà§à¦¡, মেসেজ বা কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) চà§à¦°à¦¿ করার চেষà§à¦Ÿà¦¾ করছে। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">আবার লোড করবেন না</translation>
<translation id="2900469785430194048">à¦à¦‡ ওয়েবপৃষà§à¦ à¦¾ পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করার সময় Google Chrome à¦à¦° মেমরি শেষ হয়ে গেছে।</translation>
<translation id="2909946352844186028">à¦à¦•à¦Ÿà¦¿ নেটওয়ারà§à¦• পরিবরà§à¦¤à¦¨ সনাকà§à¦¤ হয়েছে৷</translation>
<translation id="2916038427272391327">অনà§à¦¯à¦¾à¦¨à§à¦¯ পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à¦—à§à¦²à¦¿ বনà§à¦§ করà§à¦¨</translation>
<translation id="2922350208395188000">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦° চেক করা যাবে না৷</translation>
<translation id="2928905813689894207">বিলিংয়ের ঠিকানা</translation>
+<translation id="2941952326391522266">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦° <ph name="DOMAIN2" /> থেকে পাওয়া। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
<translation id="2948083400971632585">আপনি সেটিংস পৃষà§à¦ à¦¾ থেকে সংযোগের জনà§à¦¯ কনফিগার করা যেকোনো পà§à¦°à¦•à§à¦¸à¦¿ নিষà§à¦•à§à¦°à¦¿à¦¯à¦¼ করতে পারেন৷</translation>
<translation id="2955913368246107853">খোà¦à¦œ দণà§à¦¡ বনà§à¦§ করà§à¦¨</translation>
<translation id="2958431318199492670">নেটওয়ারà§à¦• কনফিগারেশন ONC মানকের সাথে সমà§à¦®à¦¤ নয়৷ কনফিগারেশনের অংশগà§à¦²à¦¿ আমদানিকৃত নাও হতে পারে৷</translation>
-<translation id="29611076221683977">বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à¦à¦° আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনার Mac ঠকà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® ইনসà§à¦Ÿà¦² করতে পারে বা আপনার তথà§à¦¯ (উদাহরণসà§à¦¬à¦°à§à¦ª, ফটো, পাসওয়ারà§à¦¡, বারà§à¦¤à¦¾ à¦à¦¬à¦‚ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) চà§à¦°à¦¿ করতে বা মà§à¦›à§‡ দিতে পারে।</translation>
<translation id="2966678944701946121">মেয়াদ শেষের তারিখ: <ph name="EXPIRATION_DATE_ABBR" />, যোগ করা হয়েছে <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">নিরাপদ নেটওয়ারà§à¦• সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করতে আপনার ঘড়িকে সঠিকভাবে সেট করতে হবে। à¦à¦®à¦¨ হওয়ার কারণ হলো, নিরাপদ সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করার জনà§à¦¯ নিজেদের সনাকà§à¦¤ করার জনà§à¦¯ ওয়েবসাইটগà§à¦²à¦¿ যে শংসাপতà§à¦°à¦—à§à¦²à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে, সেগà§à¦²à¦¿ শà§à¦§à§à¦®à¦¾à¦¤à§à¦° নিরà§à¦¦à¦¿à¦·à§à¦Ÿ সময়ের জনà§à¦¯ বৈধ থাকে। যেহেতৠআপনার ডিভাইসের ঘড়িটি ভà§à¦², সেই জনà§à¦¯ Google Chrome সঠিকভাবে শংসাপতà§à¦°à¦—à§à¦²à¦¿ পরীকà§à¦·à¦¾ করতে পারছে না।</translation>
<translation id="2972581237482394796">&amp;পà§à¦¨à¦°à¦¾à§Ÿ করà§à¦¨</translation>
@@ -227,19 +254,22 @@
<translation id="2985398929374701810">à¦à¦•à¦Ÿà¦¿ সঠিক ঠিকানা লিখà§à¦¨</translation>
<translation id="2986368408720340940">à¦à¦‡ পদà§à¦§à¦¤à¦¿à¦¤à§‡ পিক-আপ করা যাবে না। অনà§à¦¯ পদà§à¦§à¦¤à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤</translation>
<translation id="2991174974383378012">ওয়েবসাইটের সাথে ভাগ করছে</translation>
+<translation id="2991571918955627853">ওয়েবসাইটটি HSTS বà§à¦¯à¦¬à¦¹à¦¾à¦° করার কারণে আপনি à¦à¦–ন <ph name="SITE" /> ঠযেতে পারবেন না। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে।</translation>
<translation id="3005723025932146533">সংরকà§à¦·à¦¿à¦¤ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ দেখান</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> à¦à¦° CVC লিখà§à¦¨à¥¤ আপনি নিশà§à¦šà¦¿à¦¤ করলে, আপনার কারà§à¦¡à§‡à¦° বিবরণ à¦à¦‡ সাইটের সাথে শেয়ার করা হবে।</translation>
<translation id="3010559122411665027">তালিকার à¦à¦¨à§à¦Ÿà§à¦°à¦¿ " <ph name="ENTRY_INDEX" /> ": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿà¦­à¦¾à¦¬à§‡ বà§à¦²à¦• করা হয়েছে</translation>
<translation id="3024663005179499861">নীতির ভà§à¦² পà§à¦°à¦•à¦¾à¦°</translation>
<translation id="3032412215588512954">আপনি কি à¦à¦‡ সাইটটি পà§à¦¨à¦°à¦¾à¦¯à¦¼ লোড করতে চান?</translation>
<translation id="3037605927509011580">ইস!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{সিঙà§à¦• করা ডিভাইসে নà§à¦¯à§‚নতম ১টি আইটেম}=1{১টি আইটেম (à¦à¦¬à¦‚ সিঙà§à¦• করা ডিভাইসে আরো)}one{#টি আইটেম (à¦à¦¬à¦‚ সিঙà§à¦• করা ডিভাইসে আরো)}other{#টি আইটেম (à¦à¦¬à¦‚ সিঙà§à¦• করা ডিভাইসে আরো)}}</translation>
<translation id="3041612393474885105">শংসাপতà§à¦° তথà§à¦¯</translation>
<translation id="3063697135517575841">Chrome à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ আপনার কারà§à¦¡ নিশà§à¦šà¦¿à¦¤ করতে পারছে না৷ অনà§à¦—à§à¦°à¦¹ করে পরে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à§·</translation>
<translation id="3064966200440839136">বহিরাগত অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨à§‡à¦° মাধà§à¦¯à¦®à§‡ অরà§à¦¥à¦ªà§à¦°à¦¦à¦¾à¦¨ করার জনà§à¦¯ ছদà§à¦®à¦¬à§‡à¦¶à§€ মোড থেকে বেরিয়ে যাচà§à¦›à§‡à¥¤ চালিয়ে যাবেন?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{কিছà§à¦‡ নয়}=1{১টি পাসওয়ারà§à¦¡}one{#টি পাসওয়ারà§à¦¡}other{#টি পাসওয়ারà§à¦¡}}</translation>
<translation id="3093245981617870298">আপনি অফলাইনে আছেন৷</translation>
<translation id="3105172416063519923">সমà§à¦ªà¦¦ আইডি:</translation>
<translation id="3109728660330352905">আপনার à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ দেখার জনà§à¦¯ অনà§à¦®à§‹à¦¦à¦¨ নেই।</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />সংযোগের ডায়গনিসà§à¦Ÿà¦¿à¦•à§à¦¸ চালিয়ে দেখà§à¦¨<ph name="END_LINK" />।</translation>
<translation id="3145945101586104090">পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ ডিকোড করতে বà§à¦¯à¦°à§à¦¥ হয়েছে</translation>
<translation id="3150653042067488994">সাময়িক সারà§à¦­à¦¾à¦° তà§à¦°à§à¦Ÿà¦¿</translation>
@@ -248,16 +278,20 @@
<translation id="3167968892399408617">ছদà§à¦®à¦¬à§‡à¦¶à§€ টà§à¦¯à¦¾à¦¬à¦—à§à¦²à¦¿à¦¤à§‡ আপনি যে পৃষà§à¦ à¦¾à¦—à§à¦²à¦¿ দেখেন সেগà§à¦²à¦¿ আপনার সব ছদà§à¦®à¦¬à§‡à¦¶à§€ টà§à¦¯à¦¾à¦¬ বনà§à¦§ করে দেওয়ার পর বà§à¦°à¦¾à¦‰à¦œà¦¾à¦°à§‡à¦° ইতিহাস, কà§à¦•à¦¿ সà§à¦Ÿà§‹à¦° বা অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ ইতিহাসে থাকবে না। আপনি ডাউনলোড করেছেন à¦à¦®à¦¨ ফাইল বা বà§à¦•à¦®à¦¾à¦°à§à¦• তৈরি করছেন à¦à¦®à¦¨ সবগà§à¦²à¦¿ রেখে দেওয়া হবে।</translation>
<translation id="3169472444629675720">আবিষà§à¦•à¦¾à¦° করà§à¦¨</translation>
<translation id="3174168572213147020">দà§à¦¬à§€à¦ª</translation>
+<translation id="317583078218509884">পৃষà§à¦ à¦¾à¦Ÿà¦¿ পà§à¦¨à¦ƒà¦²à§‹à¦¡à§‡à¦° পরে নতà§à¦¨ সাইট অনà§à¦®à¦¤à¦¿ সেটিংস পà§à¦°à¦­à¦¾à¦¬à§€ হবে৷</translation>
<translation id="3176929007561373547">পà§à¦°à¦•à§à¦¸à§€ সারà§à¦­à¦¾à¦° কাজ করছে কি না, তা নিশà§à¦šà¦¿à¦¤ করতে আপনার পà§à¦°à¦•à§à¦¸à§€ সেটিংস পরীকà§à¦·à¦¾ করà§à¦¨
বা আপনার নেটওয়ারà§à¦• পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° সাথে যোগাযোগ করà§à¦¨à§· আপনি কোনো পà§à¦°à¦•à§à¦¸à§€ সারà§à¦­à¦¾à¦°
বà§à¦¯à¦¬à¦¹à¦¾à¦° করবেন না বলে মনে করলে:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">ছদà§à¦®à¦¬à§‡à¦¶à§€ মোডে পৃষà§à¦ à¦¾ খà§à¦²à§à¦¨</translation>
-<translation id="3202578601642193415">নবীনতম</translation>
+<translation id="320323717674993345">পেমেনà§à¦Ÿ বাতিল করà§à¦¨</translation>
<translation id="3207960819495026254">বà§à¦•à¦®à¦¾à¦°à§à¦• করা হয়েছে</translation>
+<translation id="3225919329040284222">সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨à¦¾ করেছে যা বিলà§à¦Ÿ-ইন পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¾à¦—à§à¦²à¦¿à¦° সাথে মেলে না৷ à¦à¦‡ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¾à¦—à§à¦²à¦¿ আপনাকে সà§à¦°à¦•à§à¦·à¦¿à¦¤ করতে কিছৠনিশà§à¦šà¦¿à¦¤, উচà§à¦š সà§à¦°à¦•à§à¦·à¦¾à¦° ওয়েবসাইটের জনà§à¦¯ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤à§·</translation>
<translation id="3226128629678568754">পৃষà§à¦ à¦¾à¦Ÿà¦¿ লোড করতে পà§à¦°à§Ÿà§‹à¦œà¦¨à§€à§Ÿ ডেটেটি আবার জমা দিতে আবার লোড করার বোতামটি টিপà§à¦¨à§·</translation>
+<translation id="3227137524299004712">মাইকà§à¦°à§‹à¦«à§‹à¦¨</translation>
<translation id="3228969707346345236">পৃষà§à¦ à¦¾à¦Ÿà¦¿ ইতিমধà§à¦¯à§‡ <ph name="LANGUAGE" />-ঠথাকার কারণে অনà§à¦¬à¦¾à¦¦ বà§à¦¯à¦°à§à¦¥ হয়েছে৷</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> à¦à¦° CVC লিখà§à¦¨</translation>
+<translation id="3234666976984236645">à¦à¦‡ সাইটে সরà§à¦¬à¦¦à¦¾ গà§à¦°à§à¦¤à§à¦¬à¦ªà§‚রà§à¦£ সামগà§à¦°à§€ সনাকà§à¦¤ করà§à¦¨</translation>
<translation id="3254409185687681395">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ বà§à¦•à¦®à¦¾à¦°à§à¦• করà§à¦¨</translation>
<translation id="3270847123878663523">&amp;পà§à¦¨à¦°à§à¦¬à¦¿à¦¨à§à¦¯à¦¾à¦¸à¦•à§‡ পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
<translation id="3282497668470633863">কারà§à¦¡à§‡ থাকা নাম যোগ করà§à¦¨</translation>
@@ -271,42 +305,48 @@
<translation id="3340978935015468852">সেটিংস</translation>
<translation id="3345135638360864351">à¦à¦‡ সাইটটি অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ করার জনà§à¦¯ আপনার অনà§à¦°à§‹à¦§ <ph name="NAME" /> ঠপাঠানো যায়নি৷ অনà§à¦—à§à¦°à¦¹ করে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à§·</translation>
<translation id="3355823806454867987">পà§à¦°à¦•à§à¦¸à¦¿ সেটিংস পরিবরà§à¦¤à¦¨ করà§à¦¨...</translation>
+<translation id="3361596688432910856">Chrome ঠনিমà§à¦¨à¦²à¦¿à¦–িত তথà§à¦¯ <ph name="BEGIN_EMPHASIS" />সংরকà§à¦·à¦£ করা হয় না<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />আপনার বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ à¦à¦° ইতিহাস
+ <ph name="LIST_ITEM" />কà§à¦•à¦¿à¦œ à¦à¦¬à¦‚ সাইটের ডেটা
+ <ph name="LIST_ITEM" />আপনি ফরà§à¦®à§‡ যে তথà§à¦¯ দিয়েছেন
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">ঘড়ির তà§à¦°à§à¦Ÿà¦¿</translation>
-<translation id="337311366426640088">আরো <ph name="ITEM_COUNT" />টি আইটেম...</translation>
<translation id="337363190475750230">পà§à¦°à¦¦à¦¾à¦¨ করবে না</translation>
<translation id="3377188786107721145">নীতি বিশà§à¦²à§‡à¦·à¦£ তà§à¦°à§à¦Ÿà¦¿</translation>
<translation id="3380365263193509176">অজানা তà§à¦°à§à¦Ÿà¦¿</translation>
<translation id="3380864720620200369">কà§à¦²à¦¾à§Ÿà§‡à¦¨à§à¦Ÿ ID:</translation>
<translation id="3391030046425686457">পৌà¦à¦›à§‡ দেওয়ার ঠিকানা</translation>
<translation id="3395827396354264108">পিকআপের পদà§à¦§à¦¤à¦¿</translation>
-<translation id="340013220407300675">আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ <ph name="BEGIN_BOLD" /> <ph name="SITE" /> <ph name="END_BOLD" /> (যেমন, পাসওয়ারà§à¦¡, বারà§à¦¤à¦¾ বা কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) থেকে আপনার তথà§à¦¯ চà§à¦°à¦¿ করার চেষà§à¦Ÿà¦¾ করতে পারে।</translation>
<translation id="3422248202833853650">মেমরি ফাà¦à¦•à¦¾ করতে অনà§à¦¯à¦¾à¦¨à§à¦¯ পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® থেকে বেরিয়ে যাওয়ার চেষà§à¦Ÿà¦¾ করà§à¦¨à¥¤</translation>
<translation id="3422472998109090673">বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="HOST_NAME" /> পাওয়া যাচà§à¦›à§‡ না।</translation>
+<translation id="3427092606871434483">মঞà§à¦œà§à¦°à¦¿ দিন (ডিফলà§à¦Ÿ)</translation>
<translation id="3427342743765426898">&amp;সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦•à§‡ আবার করà§à¦¨</translation>
<translation id="3431636764301398940">à¦à¦‡ ডিভাইসে à¦à¦‡ কারà§à¦¡à¦Ÿà¦¿ সংরকà§à¦·à¦£ করà§à¦¨</translation>
<translation id="3435896845095436175">সকà§à¦·à¦® করà§à¦¨</translation>
<translation id="3447661539832366887">à¦à¦‡ ডিভাইসের মালিক ডাইনোসর গেমটি বনà§à¦§ করেছেন৷</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">বিরামকাল পà§à¦°à¦¾à¦ªà§à¦¤ করà§à¦¨:</translation>
<translation id="3462200631372590220">উনà§à¦¨à¦¤ করার বিশদ বিবরণ, লà§à¦•à¦¾à¦¨</translation>
<translation id="3467763166455606212">কারà§à¦¡à¦¹à§‹à¦²à§à¦¡à¦¾à¦°à§‡à¦° নাম পà§à¦°à§Ÿà§‹à¦œà¦¨</translation>
<translation id="3478058380795961209">মেয়াদপূরà§à¦¤à¦¿à¦° মাস</translation>
<translation id="3479539252931486093">à¦à¦Ÿà¦¿ কি অপà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ ছিল? <ph name="BEGIN_LINK" />আমাদেরকে জানান<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">à¦à¦–নই নয়</translation>
-<translation id="348000606199325318">কà§à¦°à§à¦¯à¦¾à¦¶ আইডি <ph name="CRASH_LOCAL_ID" /> (সারà§à¦­à¦¾à¦° আইডি: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">আমরা à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ আপনার পিতামাতার সাথে যোগাযোগ করতে পারিনি৷ অনà§à¦—à§à¦°à¦¹ করে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à§·</translation>
<translation id="3528171143076753409">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦° বিশà§à¦¬à¦¸à§à¦¤ নয়৷</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{সিঙà§à¦• করা ডিভাইসে কমপকà§à¦·à§‡ ১টি আইটেম}=1{১টি আইটেম (à¦à¦¬à¦‚ সিঙà§à¦• করা ডিভাইসে আরও)}one{#টি আইটেম (à¦à¦¬à¦‚ সিঙà§à¦• করা ডিভাইসে আরও)}other{#টি আইটেম (à¦à¦¬à¦‚ সিঙà§à¦• করা ডিভাইসে আরও)}}</translation>
<translation id="3539171420378717834">à¦à¦‡ ডিভাইসে কারà§à¦¡à¦Ÿà¦¿à¦° à¦à¦•à¦Ÿà¦¿ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ রাখà§à¦¨</translation>
<translation id="3542684924769048008">à¦à¦° জনà§à¦¯ পাসওয়ারà§à¦¡ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨:</translation>
+<translation id="3545341443414427877"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à¦à¦° সাথে বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা যাবে না কারণ আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° তারিখ ও সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">আপনার নিজসà§à¦¬ সিঙà§à¦• পাসফà§à¦°à§‡à¦œà§‡à¦° মাধà§à¦¯à¦®à§‡ সমসà§à¦¤ সিঙà§à¦• হওয়া ডেটা à¦à¦¨à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ করà§à¦¨</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" />টি আরো...</translation>
-<translation id="3555561725129903880">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ <ph name="DOMAIN2" /> থেকে à¦à¦¸à§‡à¦›à§‡à¥¤ কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="3556433843310711081">আপনার পরিচালক আপনার হয়ে à¦à¦Ÿà¦¿ অবরোধ মà§à¦•à§à¦¤ করতে পারবে</translation>
<translation id="3566021033012934673">আপনার সংযোগ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত নয়</translation>
+<translation id="3569145463236695319">&lt;p&gt;<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à¦à¦° সাথে বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা যাবে না কারণ আপনার ডিভাইসের তারিখ ও সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়।&lt;/p&gt;
+
+ &lt;p&gt;অনà§à¦—à§à¦°à¦¹ করে &lt;strong&gt;সেটিংস&lt;/strong&gt; অà§à¦¯à¦¾à¦ªà§‡à¦° &lt;strong&gt;সাধারণ&lt;/strong&gt; বিভাগ থেকে তারিখ à¦à¦¬à¦‚ সময় সংশোধন করà§à¦¨à¥¤&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">নাম যোগ করà§à¦¨</translation>
<translation id="3583757800736429874">&amp;সরানোর কাজটি আবার করà§à¦¨</translation>
<translation id="3586931643579894722">বিশদ বিবরণ লà§à¦•à¦¾à¦¨</translation>
-<translation id="3587482841069643663">সকল</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">মেয়াদ শেষ হওয়ার তারিখের সঠিক মান লিখà§à¦¨</translation>
<translation id="36224234498066874">বà§à¦°à¦¾à¦‰à¦œ করা ডেটা সাফ করà§à¦¨...</translation>
@@ -323,7 +363,6 @@
<translation id="3681007416295224113">শংসাপতà§à¦° তথà§à¦¯</translation>
<translation id="3690164694835360974">লগইন সà§à¦°à¦•à§à¦·à¦¿à¦¤ নয়</translation>
<translation id="3693415264595406141">পাসওয়ারà§à¦¡:</translation>
-<translation id="3696411085566228381">কিছà§à¦‡ নেই</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">লোড হচà§à¦›à§‡...</translation>
<translation id="3712624925041724820">লাইসেনà§à¦¸à¦—à§à¦²à¦¿à¦° মেয়াদ শেষ হয়ে গেছে</translation>
@@ -331,12 +370,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />পà§à¦°à¦•à§à¦¸à¦¿, ফায়ারওয়াল à¦à¦¬à¦‚ DNS কনফিগারেশন পরীকà§à¦·à¦¾ করে দেখà§à¦¨<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">আপনি যদি আপনার নিরাপতà§à¦¤à¦¾à¦° à¦à§à¦à¦•à¦¿à¦—à§à¦²à¦¿ বà§à¦à¦¤à§‡ পারেন, তাহলে কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® সরানোর আগে আপনি <ph name="BEGIN_LINK" />অসà§à¦°à¦•à§à¦·à¦¿à¦¤ সাইটে যেতে পারেন<ph name="END_LINK" />।</translation>
<translation id="3739623965217189342">আপনার অনà§à¦²à¦¿à¦ªà¦¿ করা লিঙà§à¦•</translation>
+<translation id="3744899669254331632">à¦à¦‡ মূহà§à¦°à§à¦¤à§‡ আপনি <ph name="SITE" />-ঠযেতে পারবেন না কারণ ওয়েবসাইটি মিশà§à¦°à¦¿à¦¤ পà§à¦°à¦®à¦¾à¦£à¦ªà¦¤à§à¦°à¦¾à¦¦à¦¿ পাঠিয়েছে যা Chromium পà§à¦°à¦•à§à¦°à¦¿à§Ÿà¦¾ করতে পারেনা৷ নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত অসà§à¦¥à¦¾à¦¯à¦¼à§€, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে৷</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à¦à¦° আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনাকে সফà§à¦Ÿà¦“য়à§à¦¯à¦¾à¦° ইনসà§à¦Ÿà¦²à§‡à¦¶à¦¨ বা আপনার বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত তথà§à¦¯ (যেমন পাসওয়ারà§à¦¡, ফোন নমà§à¦¬à¦° বা কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) পà§à¦°à¦•à¦¾à¦¶ করার মত বিপজà§à¦œà¦¨à¦• কাজ করার জনà§à¦¯ পà§à¦°à¦¤à¦¾à¦°à¦¿à¦¤ করতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">à¦à¦•à¦Ÿà¦¿ সারà§à¦­à¦¾à¦° তà§à¦°à§à¦Ÿà¦¿à¦° কারণে অনà§à¦¬à¦¾à¦¦ বà§à¦¯à¦°à§à¦¥ হয়েছে৷</translation>
<translation id="3759461132968374835">আপনার কাছে সামà§à¦ªà§à¦°à¦¤à¦¿à¦• পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ করা কোনও কà§à¦°à§à¦¯à¦¾à¦¶ নেই৷ কà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ অকà§à¦·à¦® থাকাকালীন ঘটা কà§à¦°à§à¦¯à¦¾à¦¶ à¦à¦–ানে উপসà§à¦¥à¦¿à¦¤ হবে না৷</translation>
+<translation id="3778403066972421603">আপনি কি à¦à¦‡ কারà§à¦¡à¦Ÿà¦¿ আপনার Google অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡ ও à¦à¦‡ ডিভাইসে সেভ করতে চান?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> ঠমেয়াদ শেষ হবে</translation>
<translation id="382518646247711829">যদি আপনি à¦à¦•à¦Ÿà¦¿ পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° করেন...</translation>
<translation id="3828924085048779000">ফাà¦à¦•à¦¾ পাসফà§à¦°à§‡à¦œà§‡à¦° অনà§à¦®à¦¤à¦¿ নেই৷</translation>
-<translation id="3845539888601087042">আপনার পà§à¦°à¦¬à§‡à¦¶ করা ডিভাইসগà§à¦²à¦¿ থেকে ইতিহাস দেখাচà§à¦›à§‡à¥¤ <ph name="BEGIN_LINK" />আরো জানà§à¦¨<ph name="END_LINK" />।</translation>
<translation id="385051799172605136">ফিরà§à¦¨</translation>
<translation id="3858027520442213535">তারিখ à¦à¦¬à¦‚ সময় আপডেট করà§à¦¨</translation>
<translation id="3884278016824448484">পরসà§à¦ªà¦° বিরোধী ডিভাইস সনাকà§à¦¤à¦•à¦¾à¦°à§€</translation>
@@ -344,11 +386,13 @@
<translation id="3886446263141354045">à¦à¦‡ সাইটটি অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ করার জনà§à¦¯ আপনার অনà§à¦°à§‹à¦§ <ph name="NAME" />কে পাঠানো হয়েছে</translation>
<translation id="3890664840433101773">ইমেল যোগ করà§à¦¨</translation>
<translation id="3901925938762663762">কারà§à¦¡à¦Ÿà¦¿à¦° মেয়াদ শেষ হয়েছে</translation>
-<translation id="3933571093587347751">{1,plural, =1{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আগামীকালের বলে মনে হচà§à¦›à§‡à¥¤ কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।}one{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আগামী # দিন পরের বলে মনে হচà§à¦›à§‡à¥¤ কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।}other{à¦à¦‡ সারà§à¦­à¦¾à¦° যে <ph name="DOMAIN" /> তা à¦à¦Ÿà¦¿ পà§à¦°à¦®à¦¾à¦£ করতে পারেনি; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ আগামী # দিন পরের বলে মনে হচà§à¦›à§‡à¥¤ কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা আপনার সংযোগে বাধাপà§à¦°à¦¦à¦¾à¦¨à¦•à¦¾à¦°à§€ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° কারণে à¦à¦®à¦¨à¦Ÿà¦¿ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।}}</translation>
-<translation id="3934680773876859118">PDF দসà§à¦¤à¦¾à¦¬à§‡à¦œ লোড হতে বà§à¦¯à¦°à§à¦¥</translation>
+<translation id="3945915738023014686">কà§à¦°à§à¦¯à¦¾à¦¶ রিপোরà§à¦Ÿ আইডি <ph name="CRASH_ID" /> আপলোড করা হয়েছে (সà§à¦¥à¦¾à¦¨à§€à§Ÿ কà§à¦°à§à¦¯à¦¾à¦¶ আইডি: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">à¦à¦‡ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿à¦•à§‡ <ph name="DOMAIN" /> হিসাবে পà§à¦°à¦®à¦¾à¦£ করা যায়নি; à¦à¦Ÿà¦¿à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à§‡ সাবজেকà§à¦Ÿ অলà§à¦Ÿà¦¾à¦°à¦¨à§‡à¦Ÿà¦¿à¦­ নেমà§à¦¸ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা নেই। কনফিগারেশনের কোনও সমসà§à¦¯à¦¾ অথবা আপনার সংযোগে কোনও আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আড়ি পাতার কারণে à¦à¦Ÿà¦¿ হয়ে থাকতে পারে।</translation>
<translation id="3963721102035795474">পাঠক মোড</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{কিছà§à¦‡ নয়}=1{১টি সাইট থেকে }one{#টি সাইট থেকে }other{#টি সাইট থেকে }}</translation>
<translation id="397105322502079400">গণনা করা হচà§à¦›à§‡...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> অবরà§à¦¦à§à¦§ হয়ে রয়েছে</translation>
+<translation id="3987940399970879459">১ MB à¦à¦° কম</translation>
<translation id="40103911065039147">{URL_count,plural, =1{আশেপাশের ১টি ওয়েবপৃষà§à¦ à¦¾}one{আশেপাশের #টি ওয়েবপৃষà§à¦ à¦¾}other{আশেপাশের #টি ওয়েবপৃষà§à¦ à¦¾}}</translation>
<translation id="4021036232240155012">DNS সেই নেটওয়ারà§à¦• পরিষেবা যা কোনো ওয়েবসাইটের নামকে ইনà§à¦Ÿà¦¾à¦°à¦¨à§‡à¦Ÿ ঠিকানায় রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à¦¿à¦¤ করে।</translation>
<translation id="4030383055268325496">&amp;যোগ করাকে পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
@@ -359,56 +403,63 @@
<translation id="4079302484614802869">পà§à¦°à¦•à§à¦¸à¦¿ কনফিগারেশনটি .pac সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ URL-ঠবà§à¦¯à¦¬à¦¹à¦¾à¦° করাতে সেট থাকে সà§à¦¥à¦¿à¦° পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦°à¦—à§à¦²à¦¿à¦¤à§‡ নয়৷</translation>
<translation id="4098354747657067197">সামনে ধোà¦à¦•à¦¾à¦¬à¦¾à¦œ সাইট</translation>
<translation id="4103249731201008433">ডিভাইসের কà§à¦°à¦®à¦¿à¦• সংখà§à¦¯à¦¾ অবৈধ</translation>
+<translation id="410351446219883937">সà§à¦¬à¦¤à¦ƒà¦šà¦¾à¦²à¦¾à¦¨à§‹</translation>
<translation id="4103763322291513355">নিবারিত URLগà§à¦²à¦¿à¦° তালিকা à¦à¦¬à¦‚ আপনার সিসà§à¦Ÿà§‡à¦® পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° দà§à¦¬à¦¾à¦°à¦¾ জারি করা অনà§à¦¯à¦¾à¦¨à§à¦¯ নীতিগà§à¦²à¦¿ দেখার জনà§à¦¯ &lt;strong&gt;chrome://policy&lt;/strong&gt; ঠযান৷</translation>
-<translation id="4110615724604346410">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿à¦¤à§‡ তà§à¦°à§à¦Ÿà¦¿ রয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="4115378294792113321">মà§à¦¯à¦¾à¦œà§‡à¦¨à§à¦Ÿà¦¾</translation>
+<translation id="4116663294526079822">à¦à¦‡ সাইটে সরà§à¦¬à¦¦à¦¾ অনà§à¦®à¦¤à¦¿ দিন</translation>
<translation id="4117700440116928470">নীতির সà§à¦¯à§‹à¦—টি সমরà§à¦¥à¦¿à¦¤ নয়৷</translation>
-<translation id="4118212371799607889">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; Chromium à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿à¦•à§‡ বিশà§à¦¬à¦¾à¦¸ করে না। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{আরো ১টি}one{অনà§à¦¯à¦¾à¦¨à§à¦¯ #টি}other{অনà§à¦¯à¦¾à¦¨à§à¦¯ #টি}}</translation>
<translation id="4130226655945681476">নেটওয়ারà§à¦•à§‡à¦° তার, মডেম, à¦à¦¬à¦‚ রাউটার পরীকà§à¦·à¦¾ করà§à¦¨</translation>
+<translation id="413544239732274901">আরও জানà§à¦¨</translation>
<translation id="4148925816941278100">আমেরিকান à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¸</translation>
+<translation id="4151403195736952345">গà§à¦²à§‹à¦¬à¦¾à¦² ডিফলà§à¦Ÿ (সনাকà§à¦¤ করà§à¦¨) বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨</translation>
+<translation id="4165986682804962316">সাইটের সেটিংস</translation>
<translation id="4169947484918424451">আপনি কি চান যে Chromium à¦à¦‡ কারà§à¦¡ সংরকà§à¦·à¦£ করà§à¦•?</translation>
<translation id="4171400957073367226">খারাপ যাচাইকরণের সà§à¦¬à¦¾à¦•à§à¦·à¦°</translation>
<translation id="4196861286325780578">&amp;সরানোর কাজটি আবার করà§à¦¨</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ফায়ারওয়াল à¦à¦¬à¦‚ অà§à¦¯à¦¾à¦¨à§à¦Ÿà¦¿à¦­à¦¾à¦‡à¦°à¦¾à¦¸ কনফিগারেশন পরীকà§à¦·à¦¾ করে দেখà§à¦¨<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{কিছà§à¦‡ নেই}=1{১টি অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨ ($1)}=2{২টি অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨ ($1, $2)}one{#টি অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨ ($1, $2, $3)}other{#টি অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">কà§à¦°à§à¦¯à¦¾à¦¶à§‡à¦¸</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à¦à¦° আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনাকে à¦à¦®à¦¨ সফà§à¦Ÿà¦“য়à§à¦¯à¦¾à¦° ইনসà§à¦Ÿà¦² করার জনà§à¦¯ পà§à¦°à¦¤à¦¾à¦°à¦¿à¦¤ করার চেষà§à¦Ÿà¦¾ করতে পারে যার ফলে আপনার বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚য়ে অভিজà§à¦žà¦¤à¦¾ খারাপ হতে পারে (যেমন আপনার হোমপেজ পরিবরà§à¦¤à¦¨ করা বা আপনি যে সাইটগà§à¦²à¦¿à¦¤à§‡ যান সেগà§à¦²à¦¿à¦¤à§‡ অতিরিকà§à¦¤ বিজà§à¦žà¦¾à¦ªà¦¨ দেখানো)। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />নেটওয়ারà§à¦• ডায়গনিসà§à¦Ÿà¦¿à¦•à§à¦¸ চালিয়ে দেখà§à¦¨<ph name="END_LINK" />।</translation>
+<translation id="4235360514405112390">সঠিক</translation>
<translation id="4250431568374086873">à¦à¦‡ সাইটে আপনার সংযোগ সমà§à¦ªà§‚রà§à¦£à¦°à§‚পে নিরাপদ নয়</translation>
<translation id="4250680216510889253">না</translation>
<translation id="425582637250725228">আপনার করা পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ নাও করা হতে পারে।</translation>
<translation id="4258748452823770588">তà§à¦°à§à¦Ÿà¦¿à¦ªà§‚রà§à¦£ সà§à¦¬à¦¾à¦•à§à¦·à¦°</translation>
+<translation id="4265872034478892965">আপনার পà§à¦°à¦¶à¦¾à¦¸à¦• অনà§à¦®à¦¤à¦¿ দিয়েছে</translation>
<translation id="4269787794583293679">(কোনো বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম নেই)</translation>
<translation id="4275830172053184480">আপনার ডিভাইস বনà§à¦§ করে চালৠকরà§à¦¨</translation>
<translation id="4280429058323657511">, মেয়াদ শেষ <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সমà§à¦ªà§à¦°à¦¤à¦¿ <ph name="SITE" /> ঠ<ph name="BEGIN_LINK" />কà§à¦·à¦¤à¦¿à¦•à¦° পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® সনাকà§à¦¤ করেছে<ph name="END_LINK" />। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="4300246636397505754">মূল পà§à¦°à¦¸à§à¦¤à¦¾à¦¬à¦¨à¦¾à¦—à§à¦²à¦¿</translation>
<translation id="4304224509867189079">লগ ইন</translation>
-<translation id="432290197980158659">সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে যা বিলà§à¦Ÿ-ইন পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¾à¦—à§à¦²à¦¿à¦° সাথে মিলছে না। à¦à¦‡ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¾à¦—à§à¦²à¦¿ আপনাকে সà§à¦°à¦•à§à¦·à¦¿à¦¤ করতে কিছৠনিরà§à¦¦à¦¿à¦·à§à¦Ÿ, উচà§à¦š সà§à¦°à¦•à§à¦·à¦¾à¦° ওয়েবসাইটের জনà§à¦¯ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ করা হয়। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
+<translation id="4312866146174492540">অবরà§à¦¦à§à¦§ করà§à¦¨ (ডিফলà§à¦Ÿ)</translation>
<translation id="4325863107915753736">নিবনà§à¦§ খà§à¦à¦œà§‡ পেতে বà§à¦¯à¦°à§à¦¥ হয়েছে</translation>
<translation id="4326324639298822553">আপনার মেয়াদ শেষের তারিখ পরীকà§à¦·à¦¾ করে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨</translation>
<translation id="4331708818696583467">সà§à¦°à¦•à§à¦·à¦¿à¦¤ নয়</translation>
<translation id="4356973930735388585">à¦à¦‡ সাইটে আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡ কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® ইনসà§à¦Ÿà¦² করতে পারে যা আপনার তথà§à¦¯ (উদাহরণসà§à¦¬à¦°à§à¦ª, ফটো, পাসওয়ারà§à¦¡, বারà§à¦¤à¦¾ à¦à¦¬à¦‚ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) চà§à¦°à¦¿ করতে বা মà§à¦›à§‡ দিতে পারে।</translation>
<translation id="4372948949327679948">পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ <ph name="VALUE_TYPE" /> মান৷</translation>
+<translation id="4377125064752653719">আপনি <ph name="DOMAIN" />-ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ করেছেন, তবে সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ যে শংসাপতà§à¦°à¦Ÿà¦¿ উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে সেটির জারিকরà§à¦¤à¦¾ সেটিকে পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করেছে৷ à¦à¦° অরà§à¦¥ হ'ল সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ যে সà§à¦°à¦•à§à¦·à¦¾ পà§à¦°à¦®à¦¾à¦¨à¦ªà¦¤à§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে তা কোনওমতেই বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়৷ হতে পারে আপনি à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° সাথে যোগাযোগ করছেন৷</translation>
<translation id="4381091992796011497">বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€ নাম:</translation>
<translation id="4394049700291259645">অকà§à¦·à¦®</translation>
<translation id="4406896451731180161">অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° ফলাফলগà§à¦²à¦¿</translation>
+<translation id="4424024547088906515">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦° Chrome à¦à¦° নিকট বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> আপনার লগইন শংসাপতà§à¦°à¦Ÿà¦¿ সà§à¦¬à§€à¦•à¦¾à¦° করেনি, অথবা কোনো শংসাপতà§à¦° দেওয়া হয়নি।</translation>
<translation id="443673843213245140">পà§à¦°à¦•à§à¦¸à¦¿à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° অকà§à¦·à¦® করা হয়েছে কিনà§à¦¤à§ কোনো সà§à¦ªà¦·à§à¦Ÿ পà§à¦°à¦•à§à¦¸à¦¿ কনফিগারেশান নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা হয়েছে৷</translation>
-<translation id="4492190037599258964">'<ph name="SEARCH_STRING" />'-à¦à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ ফলাফল</translation>
<translation id="4506176782989081258">যাচাইকরণের তà§à¦°à§à¦Ÿà¦¿: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">সিসà§à¦Ÿà§‡à¦® পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° সাথে যোগাযোগ করে দেখà§à¦¨</translation>
<translation id="450710068430902550">পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° সাথে ভাগ করছে</translation>
<translation id="4515275063822566619">কারà§à¦¡ ও ঠিকানাগà§à¦²à¦¿ Chrome à¦à¦¬à¦‚ আপনার Google অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ (<ph name="ACCOUNT_EMAIL" />) থেকে à¦à¦¸à§‡à¦›à§‡à¥¤ আপনি <ph name="BEGIN_LINK" />সেটিংস<ph name="END_LINK" /> ঠগিয়ে সেগà§à¦²à¦¿ পরিচালনা করতে পারবেন।</translation>
<translation id="4522570452068850558">বিশদ বিবরণ</translation>
+<translation id="4552089082226364758">ফà§à¦²à§à¦¯à¦¾à¦¶</translation>
<translation id="4558551763791394412">আপনার à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¾à¦¨à¦—à§à¦²à¦¿ অকà§à¦·à¦® করে দেখà§à¦¨à¥¤</translation>
<translation id="457875822857220463">পৌà¦à¦›à§‡ দেওয়া</translation>
<translation id="4587425331216688090">Chrome থেকে ঠিকানা সরাবেন?</translation>
-<translation id="4589078953350245614">আপনি <ph name="DOMAIN" /> ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ চালিয়েছেন কিনà§à¦¤à§ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦•à¦Ÿà¦¿ অবৈধ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="4592951414987517459">à¦à¦•à¦Ÿà¦¿ আধà§à¦¨à¦¿à¦• সাইফার সà§à¦¯à§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে <ph name="DOMAIN" />-ঠআপনার সংযোগ à¦à¦¨à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ করা হয়েছে।</translation>
<translation id="4594403342090139922">&amp;মà§à¦›à§‡ ফেলাকে পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
<translation id="4619615317237390068">অনà§à¦¯à¦¾à¦¨à§à¦¯ ডিভাইসগà§à¦²à¦¿ থেকে টà§à¦¯à¦¾à¦¬</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à§‡ কিছৠতà§à¦°à§à¦Ÿà¦¿ আছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
+<translation id="4690462567478992370">কোনো অবৈধ শংসাপতà§à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° করা বনà§à¦§ করà§à¦¨</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">আপনার সংযোগ বাধাপà§à¦°à¦¾à¦ªà§à¦¤ হয়েছে</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows নেটওয়ারà§à¦• ডায়গনিসà§à¦Ÿà¦¿à¦•à§à¦¸ চালান<ph name="END_LINK" /></translation>
@@ -425,21 +476,24 @@
<translation id="4771973620359291008">à¦à¦•à¦Ÿà¦¿ অজানা তà§à¦°à§à¦Ÿà¦¿ ঘটেছে৷</translation>
<translation id="4800132727771399293">আপনার মেয়াদ শেষের তারিখ à¦à¦¬à¦‚ CVC পরীকà§à¦·à¦¾ করà§à¦¨ à¦à¦¬à¦‚ আবার চেষà§à¦Ÿà¦¾ করà§à¦¨</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ আপনি <ph name="SITE" /> ঠযেতে পারবেন না কারণ ওয়েবসাইটটি অবোধà§à¦¯ শংসাপতà§à¦° পাঠিয়েছে যেটি Google Chrome পà§à¦°à¦•à§à¦°à¦¿à§Ÿà¦¾ করতে পারছে না। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়, তাই à¦à¦‡ পৃষà§à¦ à¦¾ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে।</translation>
<translation id="4813512666221746211">নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿</translation>
<translation id="4816492930507672669">পৃষà§à¦ à¦¾à¦¤à§‡ মানানসই</translation>
<translation id="483020001682031208">দেখানোর মতো কোনো বাসà§à¦¤à¦¬à¦¿à¦• ওয়েব পৃষà§à¦ à¦¾ নেই</translation>
<translation id="4850886885716139402">দেখà§à¦¨</translation>
<translation id="4854362297993841467">à¦à¦‡ পদà§à¦§à¦¤à¦¿à¦¤à§‡ ডেলিভারি করা যাবে না। অনà§à¦¯ পদà§à¦§à¦¤à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤</translation>
<translation id="4858792381671956233">à¦à¦‡ সাইটটি দেখার জনà§à¦¯ উপযà§à¦•à§à¦¤ কিনা তা আপনি আপনার পিতামাতাকে জিজà§à¦žà¦¾à¦¸à¦¾ করেছেন</translation>
+<translation id="4863764087567530506">à¦à¦‡ কনà§à¦Ÿà§‡à¦¨à§à¦Ÿ পà§à¦°à¦¤à¦¾à¦°à¦£à¦¾à¦° মাধà§à¦¯à¦®à§‡ আপনাকে দিয়ে কোনও সফà§à¦Ÿà¦“য়à§à¦¯à¦¾à¦° ইনসà§à¦Ÿà¦² করাতে অথবা আপনার বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত তথà§à¦¯ জেনে নেওয়ার চেষà§à¦Ÿà¦¾ করতে পারে। <ph name="BEGIN_LINK" />তবà§à¦“ à¦à¦Ÿà¦¿ দেখতে চাই<ph name="END_LINK" />।</translation>
<translation id="4880827082731008257">ইতিহাস অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{à¦à¦¬à¦‚ আরো ১টি ওয়েব পৃষà§à¦ à¦¾}one{à¦à¦¬à¦‚ আরো #টি ওয়েব পৃষà§à¦ à¦¾}other{à¦à¦¬à¦‚ আরো #টি ওয়েব পৃষà§à¦ à¦¾}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ কোন অজানা ভাষা থেকে <ph name="LANGUAGE_LANGUAGE" />-ঠঅনà§à¦¬à¦¾à¦¦ করা হয়েছে</translation>
<translation id="4923459931733593730">অরà§à¦¥à¦ªà§à¦°à¦¦à¦¾à¦¨</translation>
<translation id="4926049483395192435">নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা উচিত৷</translation>
<translation id="495170559598752135">কà§à¦°à¦¿à§Ÿà¦¾à¦¸à¦®à§‚হ</translation>
<translation id="4958444002117714549">তালিকা পà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤ করà§à¦¨</translation>
-<translation id="4962322354953122629">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; Chrome à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿à¦•à§‡ বিশà§à¦¬à¦¾à¦¸ করে না। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
+<translation id="4974590756084640048">সতরà§à¦•à¦¬à¦¾à¦°à§à¦¤à¦¾à¦—à§à¦²à¦¿ পà§à¦¨à¦ƒà¦¸à¦•à§à¦·à¦® করà§à¦¨</translation>
<translation id="4989809363548539747">à¦à¦‡ পà§à¦²à¦¾à¦— ইন সমরà§à¦¥à¦¿à¦¤ নয়</translation>
<translation id="5002932099480077015">সকà§à¦°à¦¿à¦¯à¦¼ করা হলে, ফরà§à¦® পূরনের কাজ দà§à¦°à§à¦¤ করতে Chrome à¦à¦‡ ডিভাইসে আপনার কারà§à¦¡à§‡à¦° à¦à¦•à¦Ÿà¦¿ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ সংরকà§à¦·à¦£ করবে।</translation>
<translation id="5018422839182700155">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ খোলা যাচà§à¦›à§‡ না</translation>
@@ -447,14 +501,15 @@
<translation id="5023310440958281426">আপনার পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° নীতিগà§à¦²à¦¿ দেখà§à¦¨</translation>
<translation id="5029568752722684782">পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ সাফ করà§à¦¨</translation>
<translation id="5031870354684148875">Google অনà§à¦¬à¦¾à¦¦ সমà§à¦¬à¦¨à§à¦§à§‡</translation>
+<translation id="5039804452771397117">অনà§à¦®à¦¤à¦¿ দিন</translation>
<translation id="5040262127954254034">গোপনীয়তা</translation>
<translation id="5045550434625856497">ভà§à¦² পাসওয়ারà§à¦¡</translation>
<translation id="5056549851600133418">আপনার জনà§à¦¯ নিবনà§à¦§à¦—à§à¦²à¦¿</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />পà§à¦°à¦•à§à¦¸à¦¿ ঠিকানা পরীকà§à¦·à¦¾ করে দেখà§à¦¨<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{কোনো কà§à¦•à¦¿ নেই}=1{১টি সাইট কà§à¦•à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে। }one{#টি সাইট কà§à¦•à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে। }other{#টি সাইট কà§à¦•à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে। }}</translation>
<translation id="5087286274860437796">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦° à¦à¦‡ সময়ে বৈধ নয়৷</translation>
<translation id="5087580092889165836">কারà§à¦¡ জà§à¦¡à¦¼à§à¦¨</translation>
<translation id="5089810972385038852">রাজà§à¦¯</translation>
+<translation id="5094747076828555589">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ Chromium à¦à¦° নিকট বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
<translation id="5095208057601539847">পà§à¦°à¦¦à§‡à¦¶</translation>
<translation id="5115563688576182185">(৬৪-বিট)</translation>
<translation id="5141240743006678641">আপনার Google শংসাপতà§à¦°à§‡à¦° সাথে সিঙà§à¦• করা পাসওয়ারà§à¦¡à¦—à§à¦²à¦¿ à¦à¦¨à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ করà§à¦¨à§·</translation>
@@ -470,24 +525,24 @@
<translation id="5222812217790122047">ইমেল পà§à¦°à§Ÿà§‹à¦œà¦¨</translation>
<translation id="5251803541071282808">কà§à¦²à¦¾à¦‰à¦¡</translation>
<translation id="5277279256032773186">করà§à¦®à¦•à§à¦·à§‡à¦¤à§à¦°à§‡ Chrome বà§à¦¯à¦¬à¦¹à¦¾à¦° করছেন? বà§à¦¯à¦¬à¦¸à¦¾à¦—à§à¦²à§‹ তাদের করà§à¦®à¦šà¦¾à¦°à§€à¦¦à§‡à¦° জনà§à¦¯ Chrome সেটিংস পরিচালনা করতে পারে। আরো জানà§à¦¨</translation>
+<translation id="5297526204711817721">à¦à¦‡ সাইটে আপনার সংযোগ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত নয়। যেকোনো সময় (ভিআর)VR মোড থেকে বেরিয়ে যাওয়ার জনà§à¦¯, হেডসেট সরান à¦à¦¬à¦‚ 'পিছনে' চাপà§à¦¨à¥¤</translation>
<translation id="5299298092464848405">নীতি বিশà§à¦²à§‡à¦·à¦£ করার সময় তà§à¦°à§à¦Ÿà¦¿</translation>
-<translation id="5300589172476337783">দেখান</translation>
<translation id="5308689395849655368">কà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ অকà§à¦·à¦® আছে৷</translation>
<translation id="5317780077021120954">সংরকà§à¦·à¦£ করà§à¦¨</translation>
<translation id="5327248766486351172">নাম</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ঠআকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনাকে ধোà¦à¦•à¦¾ দিয়ে সফটওয়à§à¦¯à¦¾à¦° ইনসà§à¦Ÿà¦² করা বা আপনার বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত তথà§à¦¯ (উদাহরণসà§à¦¬à¦°à§‚প, পাসওয়ারà§à¦¡, ফোন নমà§à¦¬à¦°, বা কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) পà§à¦°à¦•à¦¾à¦¶ করার মত বিপজà§à¦œà¦¨à¦• কিছৠকরাতে পারে।</translation>
-<translation id="5359637492792381994">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; বরà§à¦¤à¦®à¦¾à¦¨à§‡ à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ বৈধ না। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
+<translation id="5355557959165512791">ওয়েবসাইটটির শংসাপতà§à¦° তà§à¦²à§‡ নেওয়ার কারণে আপনি à¦à¦–ন <ph name="SITE" /> ঠযেতে পারবেন না। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে।</translation>
<translation id="536296301121032821">নীতি সেটিংস সংরকà§à¦·à¦£ করতে বà§à¦¯à¦°à§à¦¥ হয়েছে</translation>
<translation id="5386426401304769735">à¦à¦‡ সাইটের শংসাপতà§à¦° শৃঙà§à¦–লে SHA-1 বà§à¦¯à¦¬à¦¹à¦¾à¦° করে সà§à¦¬à¦¾à¦•à§à¦·à¦° করা à¦à¦•à¦Ÿà¦¿ শংসাপতà§à¦° রয়েছে।</translation>
<translation id="5402410679244714488">মেয়াদোতà§à¦¤à§€à¦°à§à¦£: <ph name="EXPIRATION_DATE_ABBR" />, à¦à¦• বছরেরও বেশি সময় পূরà§à¦¬à§‡ সরà§à¦¬à¦¶à§‡à¦· বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হয়েছে</translation>
+<translation id="540969355065856584">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦° à¦à¦‡ সময়ে বৈধ নয়। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
<translation id="5421136146218899937">বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ ডেটা সাফ করà§à¦¨...</translation>
<translation id="5430298929874300616">বà§à¦•à¦®à¦¾à¦°à§à¦• সরান</translation>
<translation id="5431657950005405462">আপনার ফাইলটি পাওয়া যায়নি</translation>
-<translation id="5435775191620395718">à¦à¦‡ ডিভাইস থেকে ইতিহাস দেখাচà§à¦›à§‡à¥¤ <ph name="BEGIN_LINK" />আরো জানà§à¦¨<ph name="END_LINK" />।</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" ঠসà§à¦•à¦¿à¦®à¦¾ বৈধতার তà§à¦°à§à¦Ÿà¦¿ হয়েছে: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">à¦à¦‡ <ph name="HOST_NAME" /> পৃষà§à¦ à¦¾à¦Ÿà¦¿ পাওয়া যাচà§à¦›à§‡ না</translation>
<translation id="5455374756549232013">তà§à¦°à§à¦Ÿà¦¿à¦ªà§‚রà§à¦£ নীতি টাইমসà§à¦Ÿà§à¦¯à¦¾à¦®à§à¦ª</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" /> à¦à¦° <ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">অবৈধ</translation>
<translation id="5470861586879999274">&amp;সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦•à§‡ আবার করà§à¦¨</translation>
<translation id="54817484435770891">বৈধ ঠিকানা যোগ করà§à¦¨</translation>
<translation id="5492298309214877701">কোমà§à¦ªà¦¾à¦¨à§€, সংসà§à¦¥à¦¾ বা সà§à¦•à§à¦² ইনà§à¦Ÿà§à¦°à¦¾à¦¨à§‡à¦Ÿà§‡ à¦à¦‡ সাইটটির à¦à¦•à¦Ÿà¦¿ বাহà§à¦¯à¦¿à¦• ওয়েবসাইটের মতো à¦à¦•à¦‡ URL আছে।
@@ -504,6 +559,8 @@
<translation id="5571083550517324815">à¦à¦‡ ঠিকানা থেকে পিক-আপ করা যাবে না। অনà§à¦¯ ঠিকানা বেছে নিন।</translation>
<translation id="5572851009514199876">আপনার à¦à¦‡ সাইটে অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ করার অনà§à¦®à¦¤à¦¿ আছে কিনা তা Chrome পরীকà§à¦·à¦¾ করার জনà§à¦¯ অনà§à¦—à§à¦°à¦¹ করে শà§à¦°à§ করà§à¦¨ à¦à¦¬à¦‚ Chrome ঠপà§à¦°à¦¬à§‡à¦¶ করà§à¦¨à¥¤</translation>
<translation id="5580958916614886209">আপনার মেয়াদ শেষের মাস পরীকà§à¦·à¦¾ করে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨</translation>
+<translation id="5586446728396275693">কোনও ঠিকানা সংরকà§à¦·à¦£ করা নেই</translation>
+<translation id="5595485650161345191">ঠিকানা সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করà§à¦¨</translation>
<translation id="560412284261940334">পরিচালনা সমরà§à¦¥à¦¿à¦¤ নয়</translation>
<translation id="5610142619324316209">সংযোগ পরীকà§à¦·à¦¾ করে দেখà§à¦¨</translation>
<translation id="5610807607761827392">আপনি <ph name="BEGIN_LINK" />সেটিংস<ph name="END_LINK" /> থেকে কারà§à¦¡ à¦à¦¬à¦‚ ঠিকানাগà§à¦²à¦¿ পরিচালনা করতে পারেন।</translation>
@@ -511,15 +568,18 @@
<translation id="5622887735448669177">আপনি কি à¦à¦‡ সাইটটি ছেড়ে যেতে চান?</translation>
<translation id="5629630648637658800">নীতি সেটিংস লোড করতে বà§à¦¯à¦°à§à¦¥ হয়েছে</translation>
<translation id="5631439013527180824">অবৈধ ডিভাইস পরিচালনা টোকেন</translation>
+<translation id="5633066919399395251"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ঠযে আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ সকà§à¦°à¦¿à§Ÿ আছে, তারা আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡ à¦à¦®à¦¨ বিপজà§à¦œà¦¨à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® ইনসà§à¦Ÿà¦² করে দিতে পারে যেগà§à¦²à¦¿ আপনার তথà§à¦¯à§‡à¦° (যেমন ফটো, পাসওয়ারà§à¦¡, মেসেজ à¦à¦¬à¦‚ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) কà§à¦·à¦¤à¦¿ করতে বা সেগà§à¦²à¦¿ চà§à¦°à¦¿ করতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">অবসà§à¦¥à¦¾à¦¨</translation>
+<translation id="5659593005791499971">ইমেল</translation>
<translation id="5669703222995421982">বà§à¦¯à¦•à§à¦¤à¦¿à¦—তকৃত সামগà§à¦°à§€ পান</translation>
<translation id="5675650730144413517">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ কাজ করছে না</translation>
-<translation id="5677928146339483299">অবরà§à¦¦à§à¦§</translation>
-<translation id="5694783966845939798">আপনি <ph name="DOMAIN" /> ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° চেষà§à¦Ÿà¦¾ করেছেন, কিনà§à¦¤à§ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦•à¦Ÿà¦¿ দà§à¦°à§à¦¬à¦² সà§à¦¬à¦¾à¦•à§à¦·à¦° অà§à¦¯à¦¾à¦²à¦—রিদম (যেমন SHA-1) বà§à¦¯à¦¬à¦¹à¦¾à¦° করে à¦à¦•à¦Ÿà¦¿ সà§à¦¬à¦¾à¦•à§à¦·à¦°à¦¿à¦¤ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে। à¦à¦° অরà§à¦¥ হ'ল সারà§à¦­à¦¾à¦° যে সà§à¦°à¦•à§à¦·à¦¾ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে তা জাল হতে পারে à¦à¦¬à¦‚ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ আপনার পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ সারà§à¦­à¦¾à¦° নাও হতে পারে (হতে পারে আপনি à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° সাথে যোগাযোগ করছেন)। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="5710435578057952990">à¦à¦‡ ওয়েবসাইটির পরিচয় যাচাই করা হয় নি৷</translation>
+<translation id="5713016350996637505">পà§à¦°à¦¤à¦¾à¦°à¦£à¦¾à¦®à§‚লক কনà§à¦Ÿà§‡à¦¨à§à¦Ÿ বà§à¦²à¦• করা হয়েছে</translation>
<translation id="5720705177508910913">বরà§à¦¤à¦®à¦¾à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€</translation>
<translation id="5732392974455271431">আপনার পিতামাতা à¦à¦Ÿà¦¿ আপনার জনà§à¦¯ অবরোধ মà§à¦•à§à¦¤ করতে পারবেন</translation>
<translation id="5763042198335101085">à¦à¦•à¦Ÿà¦¿ সঠিক ইমেল ঠিকানা লিখà§à¦¨</translation>
<translation id="5765072501007116331">ডেলিভারির পদà§à¦§à¦¤à¦¿ à¦à¦¬à¦‚ পà§à¦°à§Ÿà§‹à¦œà¦¨à§€à§Ÿà¦¤à¦¾à¦—à§à¦²à¦¿ দেখতে à¦à¦•à¦Ÿà¦¿ ঠিকানা বেছে নিন</translation>
+<translation id="5778550464785688721">MIDI ডিভাইসসমূহ পূরà§à¦£ নিয়নà§à¦¤à§à¦°à¦£</translation>
<translation id="5784606427469807560">আপনার কারà§à¦¡à¦Ÿà¦¿ নিশà§à¦šà¦¿à¦¤ করতে à¦à¦•à¦Ÿà¦¿ সমসà§à¦¯à¦¾ হয়েছিল৷আপনার ইনà§à¦Ÿà¦¾à¦°à¦¨à§‡à¦Ÿ সংযোগ পরীকà§à¦·à¦¾ করে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à§·</translation>
<translation id="5785756445106461925">উপরনà§à¦¤à§, à¦à¦‡ পৃষà§à¦ à¦¾à¦¤à§‡ অনà§à¦¯à¦¾à¦¨à§à¦¯ সংসà§à¦¥à¦¾à¦¨ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ রয়েছে যা নিরাপদ নয়৷ à¦à¦‡ সংসà§à¦¥à¦¾à¦¨à¦—à§à¦²à¦¿ টà§à¦°à¦¾à¦¨à¦œà¦¿à¦Ÿà§‡à¦° সময় অনà§à¦¯à¦°à¦¾ দেখতে পাবে à¦à¦¬à¦‚ পৃষà§à¦ à¦¾à¦Ÿà¦¿à¦° চেহারাটি পরিবরà§à¦¤à¦¨ করতে কোনও আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ à¦à¦° পরিবরà§à¦¤à¦¨ করতে পারেন৷</translation>
<translation id="5786044859038896871">আপনি কি আপনার কারà§à¦¡à§‡à¦° তথà§à¦¯ পূরণ করতে চান?</translation>
@@ -528,14 +588,14 @@
<translation id="5813119285467412249">&amp;যোগ করাকে পà§à¦¨à¦°à¦¾à¦¯à¦¼ করà§à¦¨</translation>
<translation id="5814352347845180253">আপনি <ph name="SITE" /> à¦à¦¬à¦‚ অনà§à¦¯à¦¾à¦¨à§à¦¯ সাইট থেকে পà§à¦°à¦¿à¦®à¦¿à¦¯à¦¼à¦¾à¦® সামগà§à¦°à§€à¦¤à§‡ অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ হারাতে পারেন।</translation>
<translation id="5838278095973806738">à¦à¦‡ সাইটে আপনার কোনো সংবেদনশীল তথà§à¦¯ দেওয়া উচিত হবে না (উদাহরণসà§à¦¬à¦°à§‚প, পাসওয়ারà§à¦¡ বা কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) কারণ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ à¦à¦—à§à¦²à¦¿ চà§à¦°à¦¿ করতে পারে।</translation>
-<translation id="5843436854350372569">আপনি <ph name="DOMAIN" /> ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ করেছেন, কিনà§à¦¤à§ সারà§à¦­à¦¾à¦° à¦à¦•à¦Ÿà¦¿ দà§à¦°à§à¦¬à¦² কী সমà§à¦¬à¦²à¦¿à¦¤ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে৷ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত কী ভঙà§à¦— করে থাকতে পারে à¦à¦¬à¦‚ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ আপনার পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ সারà§à¦­à¦¾à¦° নাও হতে পারে (হতে পারে আপনি à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° সাথে যোগাযোগ করছেন)। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="5869405914158311789">à¦à¦‡ সাইটটিতে পৌছানো যাচà§à¦›à§‡ না</translation>
<translation id="5869522115854928033">সংরকà§à¦·à¦¿à¦¤ পাসওয়ারà§à¦¡</translation>
<translation id="5872918882028971132">মূল পà§à¦°à¦¸à§à¦¤à¦¾à¦¬à¦¨à¦¾à¦—à§à¦²à¦¿</translation>
<translation id="5901630391730855834">হলà§à¦¦</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (সিঙà§à¦• হয়েছে)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{১টি বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হচà§à¦›à§‡}one{#টি বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হচà§à¦›à§‡}other{#টি বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হচà§à¦›à§‡}}</translation>
<translation id="5926846154125914413">আপনি কিছৠসাইট থেকে পà§à¦°à¦¿à¦®à¦¿à¦¯à¦¼à¦¾à¦® সামগà§à¦°à§€à¦¤à§‡ অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ হারাতে পারেন।</translation>
<translation id="5959728338436674663">বিপজà§à¦œà¦¨à¦• অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨ ও সাইটগà§à¦²à¦¿ সনাকà§à¦¤ করতে Google à¦à¦° কাছে কিছà§<ph name="BEGIN_WHITEPAPER_LINK" /> সিসà§à¦Ÿà§‡à¦® তথà§à¦¯ ও পৃষà§à¦ à¦¾à¦° সামগà§à¦°à§€<ph name="END_WHITEPAPER_LINK" /> সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿà¦­à¦¾à¦¬à§‡ পাঠান। <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">সপà§à¦¤à¦¾à¦¹</translation>
<translation id="5967867314010545767">ইতিহাস থেকে সরান</translation>
<translation id="5975083100439434680">জà§à¦® কমান</translation>
<translation id="598637245381783098">পেমেনà§à¦Ÿ অà§à¦¯à¦¾à¦ª খোলা যাচà§à¦›à§‡ না</translation>
@@ -544,20 +604,28 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{পৃষà§à¦ à¦¾ ১}one{পৃষà§à¦ à¦¾ #}other{পৃষà§à¦ à¦¾ #}}</translation>
<translation id="6017514345406065928">সবà§à¦œ</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ঠসকà§à¦°à¦¿à§Ÿ থাকা আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ à¦à¦®à¦¨ পà§à¦°à¦¤à¦¾à¦°à¦£à¦¾à¦®à§‚লক অà§à¦¯à¦¾à¦ª ইনসà§à¦Ÿà¦² করে দিতে পারে যেগà§à¦²à¦¿ অনà§à¦¯à¦¾à¦¨à§à¦¯ আপের থেকে আলাদা করা যায় না, অথবা যেগà§à¦²à¦¿ à¦à¦®à¦¨ ডেটা সংগà§à¦°à¦¹ করে যা দিয়ে আপনার উপরে নজর রাখা যাবে। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (সিঙà§à¦• হয়েছে)</translation>
<translation id="6027201098523975773">à¦à¦•à¦Ÿà¦¿ নাম লিখà§à¦¨</translation>
<translation id="6040143037577758943">বনà§à¦§</translation>
<translation id="6042308850641462728">আরো</translation>
+<translation id="6047233362582046994">আপনি যদি আপনার নিরাপতà§à¦¤à¦¾à¦° à¦à§à¦à¦•à¦¿à¦—à§à¦²à¦¿ বà§à¦à§‡ নিয়ে থাকেন, তাহলে কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• অà§à¦¯à¦¾à¦ªà¦—à§à¦²à¦¿ সরানোর আগে <ph name="BEGIN_LINK" />à¦à¦‡ সাইটে যেতে পারেন<ph name="END_LINK" />৷</translation>
+<translation id="6051221802930200923">ওয়েবসাইটটি পিন করা শংসাপতà§à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° করার কারণে আপনি à¦à¦–ন <ph name="SITE" /> ঠযেতে পারবেন না। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে।</translation>
<translation id="6060685159320643512">সাবধান হন, à¦à¦‡ পরীকà§à¦·à¦¾à¦—à§à¦²à¦¿ সমসà§à¦¯à¦¾ সৃষà§à¦Ÿà¦¿ করতে পারে</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{কিছà§à¦‡ নেই}=1{১}one{#}other{#}}</translation>
+<translation id="6080696365213338172">পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° দà§à¦¬à¦¾à¦°à¦¾ সরবরাহ করা শংসাপতà§à¦°à§‡à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦° করে আপনি সামগà§à¦°à§€ বà§à¦¯à¦¬à¦¹à¦¾à¦° করেছেন৷ <ph name="DOMAIN" /> কে আপনি যে ডেটা সরবরাহ করেন তা আপনার পà§à¦°à¦¶à¦¾à¦¸à¦• বাধা দিতে পারে৷</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{কিছà§à¦‡ নয়}=1{১টি পাসওয়ারà§à¦¡ (সিঙà§à¦• করা হয়েছে)}one{#টি পাসওয়ারà§à¦¡ (সিঙà§à¦• করা হয়েছে)}other{#টি পাসওয়ারà§à¦¡ (সিঙà§à¦• করা হয়েছে)}}</translation>
<translation id="6146055958333702838">সব কেবল পরীকà§à¦·à¦¾ করà§à¦¨ à¦à¦¬à¦‚ আপনি বà§à¦¯à¦¬à¦¹à¦¾à¦° করছেন à¦à¦®à¦¨ যেকোনো রাউটার, মডেম বা অনà§à¦¯à¦¾à¦¨à§à¦¯ নেটওয়ারà§à¦• ডিভাইসগà§à¦²à¦¿ আবার চালৠকরà§à¦¨à¥¤</translation>
<translation id="614940544461990577">à¦à¦Ÿà¦¿ করে দেখà§à¦¨:</translation>
<translation id="6151417162996330722">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦°à§‡à¦° বৈধতার সময়সীমা আছে যা খà§à¦¬à¦‡ দীরà§à¦˜à¥¤</translation>
<translation id="6157877588268064908">শিপিং à¦à¦° পদà§à¦§à¦¤à¦¿ à¦à¦¬à¦‚ পà§à¦°à§Ÿà§‹à¦œà¦¨à§€à§Ÿà¦¤à¦¾ দেখতে à¦à¦•à¦Ÿà¦¿ ঠিকানা বেছে নিন</translation>
+<translation id="6158003235852588289">Google à¦à¦° নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সমà§à¦ªà§à¦°à¦¤à¦¿ <ph name="SITE" /> ঠফিশিং শনাকà§à¦¤ করেছে। ফিশিং সাইটগà§à¦²à¦¿ আপনাকে পà§à¦°à¦¤à¦¾à¦°à¦¿à¦¤ করার জনà§à¦¯ অনà§à¦¯à¦¾à¦¨à§à¦¯ সাইট যেমন হয় সেইরকম ভান করে।</translation>
<translation id="6165508094623778733">আরো জানà§à¦¨</translation>
+<translation id="6169916984152623906">à¦à¦–ন আপনি গোপনভাবে বà§à¦°à¦¾à¦‰à¦œ করতে পারেন, à¦à¦¬à¦‚ অনà§à¦¯ যেসব বকà§à¦¤à¦¿ à¦à¦‡ ডিভাইস বà§à¦¯à¦¬à¦¹à¦¾à¦° করেন তারা আপনার কারà§à¦¯à¦•à¦²à¦¾à¦ª দেখতে পাবেন না। তবে, আপনার ডাউনলোড à¦à¦¬à¦‚ বà§à¦•à¦®à¦¾à¦°à§à¦•à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করা হবে।</translation>
<translation id="6177128806592000436">à¦à¦‡ সাইটে আপনার সংযোগ নিরাপদ নয়</translation>
<translation id="6184817833369986695">(দল: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">আপনার ইনà§à¦Ÿà¦¾à¦°à¦¨à§‡à¦Ÿ সংযোগ পরীকà§à¦·à¦¾ করà§à¦¨</translation>
<translation id="6218753634732582820">Chromium থেকে ঠিকানা সরাবেন?</translation>
+<translation id="6221345481584921695">Google নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সামà§à¦ªà§à¦°à¦¤à¦¿à¦• <ph name="SITE" /> ঠ<ph name="BEGIN_LINK" />মà§à¦¯à¦¾à¦²à¦“য়à§à¦¯à¦¾à¦° শনাকà§à¦¤ করেছে<ph name="END_LINK" />। যেসব ওয়েবসাইট সাধারণত নিরাপদ থাকে, সেগà§à¦²à¦¿ কখনও কখনও মà§à¦¯à¦¾à¦²à¦“য়à§à¦¯à¦¾à¦° দà§à¦¬à¦¾à¦°à¦¾ আকà§à¦°à¦¾à¦¨à§à¦¤ হয়। <ph name="SUBRESOURCE_HOST" />, à¦à¦•à¦Ÿà¦¿ পরিচিত মà§à¦¯à¦¾à¦²à¦“য়à§à¦¯à¦¾à¦° বিতরণকারী, থেকে কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• সামগà§à¦°à§€ আসে। কয়েক ঘণà§à¦Ÿà¦¾ পরে আপনার ফিরে আসা উচিত।</translation>
<translation id="6251924700383757765">গোপনীয়তা নীতি</translation>
<translation id="6254436959401408446">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ খোলার জনà§à¦¯ পরà§à¦¯à¦¾à¦ªà§à¦¤ মেমরি নেই</translation>
<translation id="625755898061068298">আপনি à¦à¦‡ সাইটের জনà§à¦¯ নিরাপতà§à¦¤à¦¾ সতরà§à¦•à¦¬à¦¾à¦°à§à¦¤à¦¾ অকà§à¦·à¦® করতে চয়ন করেছেন।</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">বà§à¦•à¦®à¦¾à¦°à§à¦• সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করà§à¦¨</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> à¦à¦° মেয়াদ শেষের তারিখ à¦à¦¬à¦‚ CVC লিখà§à¦¨</translation>
<translation id="6414888972213066896">à¦à¦‡ সাইটটি ঘà§à¦°à§‡ দেখা ঠিক হবে কিনা সেই বিষয়ে আপনি আপনার পিতামাতাকে জিজà§à¦žà¦¾à¦¸à¦¾ করেছেন</translation>
-<translation id="6416403317709441254">আপনি <ph name="SITE" /> ঠযেতে পারবেন না কারণ ওয়েবসাইটটি à¦à¦•à¦Ÿà¦¿ অবোধà§à¦¯ শংসাপতà§à¦° পাঠিয়েছে যেটি Chromium পà§à¦°à¦•à§à¦°à¦¿à§Ÿà¦¾ করতে পারছে না। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়ে থাকে, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="6417515091412812850">শংসাপতà§à¦°à¦•à¦°à¦£à¦Ÿà¦¿ পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করা হয়েছে কিনা তা যাচাইয়ে অকà§à¦·à¦®à§·</translation>
<translation id="6433490469411711332">পরিচিতি তথà§à¦¯ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করà§à¦¨</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> সংযোগ করতে পà§à¦°à¦¤à§à¦¯à¦¾à¦–à§à¦¯à¦¾à¦¨ করেছে।</translation>
<translation id="6446608382365791566">আরো তথà§à¦¯ যোগ করà§à¦¨</translation>
+<translation id="6447842834002726250">কà§à¦•à¦¿à¦œ</translation>
<translation id="6451458296329894277">ফরà§à¦® পà§à¦¨à¦ƒà¦œà¦®à¦¾ নিশà§à¦šà¦¿à¦¤ করà§à¦¨</translation>
<translation id="6456339708790392414">আপনার অরà§à¦¥à¦ªà§à¦°à¦¦à¦¾à¦¨</translation>
<translation id="6458467102616083041">নীতি দà§à¦¬à¦¾à¦°à¦¾ ডিফলà§à¦Ÿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ অকà§à¦·à¦® করা হয়েছে সেই কারণে উপেকà§à¦·à¦¾ করা হয়েছে৷</translation>
-<translation id="6462969404041126431">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿ হয়ত পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করা হয়েছে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="647261751007945333">ডিভাইস নীতিগà§à¦²à¦¿</translation>
<translation id="6477321094435799029">Chrome à¦à¦‡ পৃষà§à¦ à¦¾à¦¤à§‡ অসà§à¦¬à¦¾à¦­à¦¾à¦¬à¦¿à¦• কোড পেয়েছে à¦à¦¬à¦‚ আপনার বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত তথà§à¦¯à§‡à¦° (উদাহরণসà§à¦¬à¦°à§‚প, পাসওয়ারà§à¦¡, ফোন নমà§à¦¬à¦°, à¦à¦¬à¦‚ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) সà§à¦°à¦•à§à¦·à¦¾à¦° জনà§à¦¯ à¦à¦Ÿà¦¿ অবরà§à¦¦à§à¦§ করেছে।</translation>
<translation id="6489534406876378309">কà§à¦°à§à¦¯à¦¾à¦¶à¦—à§à¦²à¦¿ আপলোড করা শà§à¦°à§ করà§à¦¨</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">মেয়াদ শেষের তারিখ: <ph name="EXPIRATION_DATE_ABBR" />, শেষবার বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হয়েছে <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">আপনার পরিচালক à¦à¦–নও à¦à¦Ÿà¦¿ অনà§à¦®à§‹à¦¦à¦¨ করেন নি</translation>
<translation id="6569060085658103619">আপনি à¦à¦•à¦Ÿà¦¿ à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¾à¦¨ পৃষà§à¦ à¦¾ দেখছেন</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> à¦à¦° কম</translation>
+<translation id="657639383826808334">à¦à¦‡ কনà§à¦Ÿà§‡à¦¨à§à¦Ÿ আপনার ডিভাইসে à¦à¦®à¦¨ বিপজà§à¦œà¦¨à¦• সফà§à¦Ÿà¦“য়à§à¦¯à¦¾à¦° ইনসà§à¦Ÿà¦² করার চেষà§à¦Ÿà¦¾ করতে পারে যা আপনার তথà§à¦¯ চà§à¦°à¦¿ করে বা মà§à¦›à§‡ দেয়। <ph name="BEGIN_LINK" />তবà§à¦“ à¦à¦Ÿà¦¿ দেখতে চাই<ph name="END_LINK" />।</translation>
<translation id="6596325263575161958">à¦à¦¨à¦•à§à¦°à¦¿à¦ªà¦¶à¦¨ বিকলà§à¦ªà¦—à§à¦²à¦¿</translation>
<translation id="662080504995468778">থাকà§à¦¨</translation>
<translation id="6626291197371920147">বৈধ কারà§à¦¡ নমà§à¦¬à¦° যোগ করà§à¦¨</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ঠযে আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ সকà§à¦°à¦¿à§Ÿ আছে, তারা আপনার Mac ঠà¦à¦®à¦¨ বিপজà§à¦œà¦¨à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® ইনসà§à¦Ÿà¦² করে দিতে পারে যেগà§à¦²à¦¿ আপনার তথà§à¦¯à§‡à¦° (যেমন ফটো, পাসওয়ারà§à¦¡, মেসেজ à¦à¦¬à¦‚ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) কà§à¦·à¦¤à¦¿ করতে বা সেগà§à¦²à¦¿ চà§à¦°à¦¿ করতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">à¦à¦‡ নীতিটি অসমরà§à¦¥à¦¿à¦¤ হয়েছে৷</translation>
-<translation id="6652240803263749613">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° অপারেটিং সিসà§à¦Ÿà§‡à¦® à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿à¦•à§‡ বিশà§à¦¬à¦¾à¦¸ করে না। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="6671697161687535275">Chromium থেকে ফরà§à¦® পà§à¦°à¦¸à§à¦¤à¦¾à¦¬à¦¨à¦¾ সরাবেন?</translation>
<translation id="6685834062052613830">পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করà§à¦¨ করে সেটআপ সমà§à¦ªà§‚রà§à¦£ করà§à¦¨</translation>
<translation id="6710213216561001401">পূরà§à¦¬à¦¬à¦°à§à¦¤à§€</translation>
<translation id="6710594484020273272">&lt;অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° পদ লিখà§à¦¨&gt;</translation>
<translation id="6711464428925977395">পà§à¦°à¦•à§à¦¸à§€ সারà§à¦­à¦¾à¦°à§‡à¦° কোনো সমসà§à¦¯à¦¾ হয়েছে, অথবা ঠিকানাটি ভà§à¦²à¥¤</translation>
<translation id="6727102863431372879">সেট</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{কিছà§à¦‡ নেই}=1{১টি আইটেম}one{#টি আইটেম}other{#টি আইটেম}}</translation>
<translation id="674375294223700098">অজানা সারà§à¦­à¦¾à¦° শংসাপতà§à¦° তà§à¦°à§à¦Ÿà¦¿à§·</translation>
<translation id="6753269504797312559">নীতি মান</translation>
<translation id="6757797048963528358">আপনার ডিভাইস নিদà§à¦°à¦¾ মোডে গিয়েছে।</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">কাসà§à¦Ÿà¦®à¦¾à¦‡à¦œà§‡à¦¶à¦¨ আইডি</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">আঞà§à¦šà¦²à¦¿à¦• ডেটা লোড করা যায়নি</translation>
+<translation id="6825578344716086703">আপনি <ph name="DOMAIN" />-ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ করেছেন, কিনà§à¦¤à§ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦•à¦Ÿà¦¿ দà§à¦°à§à¦¬à¦² অà§à¦¯à¦¾à¦²à¦—ারিদম সà§à¦¬à¦¾à¦•à§à¦·à¦° (যেমন SHA-1) বà§à¦¯à¦¬à¦¹à¦¾à¦° করে à¦à¦•à¦Ÿà¦¿ সà§à¦¬à¦¾à¦•à§à¦·à¦°à¦¿à¦¤ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে। à¦à¦° অরà§à¦¥ হল সারà§à¦­à¦¾à¦° যে সà§à¦°à¦•à§à¦·à¦¾ পà§à¦°à¦®à¦¾à¦£à¦ªà¦¤à§à¦°à¦¾à¦¦à¦¿ উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে তা জাল হতে পারে à¦à¦¬à¦‚ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ আপনার পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤ সারà§à¦­à¦¾à¦° নাও হতে পারে (হতে পারে আপনি à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦° সাথে যোগাযোগ করছেন)।</translation>
+<translation id="6830728435402077660">সà§à¦°à¦•à§à¦·à¦¿à¦¤ নয়</translation>
<translation id="6831043979455480757">অনà§à¦¬à¦¾à¦¦</translation>
<translation id="6839929833149231406">à¦à¦²à¦¾à¦•à¦¾</translation>
<translation id="6874604403660855544">&amp;যোগ করাকে পà§à¦¨à¦°à¦¾à¦¯à¦¼ করà§à¦¨</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">আপনার কারà§à¦¡à¦Ÿà¦¿ নিশà§à¦šà¦¿à¦¤ করা হয়েছে</translation>
<translation id="6897140037006041989">বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€ à¦à¦œà§‡à¦¨à§à¦Ÿ</translation>
<translation id="6915804003454593391">বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€:</translation>
+<translation id="6945221475159498467">নিরà§à¦¬à¦¾à¦šà¦¨</translation>
<translation id="6948701128805548767">পিকআপ à¦à¦° পদà§à¦§à¦¤à¦¿ à¦à¦¬à¦‚ পà§à¦°à§Ÿà§‹à¦œà¦¨à§€à§Ÿà¦¤à¦¾ দেখতে à¦à¦•à¦Ÿà¦¿ ঠিকানা বেছে নিন</translation>
<translation id="6957887021205513506">সারà§à¦­à¦¾à¦°à¦Ÿà¦¿à¦° শংসাপতà§à¦°à¦Ÿà¦¿ à¦à¦•à¦Ÿà¦¿ জাল হিসাবে উপসà§à¦¥à¦¿à¦¤ হয়েছে৷</translation>
<translation id="6965382102122355670">ঠিক আছে</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">সà§à¦¥à¦¿à¦° পà§à¦°à¦•à§à¦¸à¦¿ সারà§à¦­à¦¾à¦° à¦à¦¬à¦‚ .pac সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ URL-à¦à¦° উভয়ই নিরà§à¦¦à¦¿à¦·à§à¦Ÿ আছে৷</translation>
<translation id="6989763994942163495">উনà§à¦¨à¦¤ সেটিংস দেখান ...</translation>
<translation id="7000990526846637657">কোনো ইতিহাস à¦à¦¨à§à¦Ÿà§à¦°à¦¿ পাওয়া যায়নি</translation>
-<translation id="7009986207543992532">আপনি <ph name="DOMAIN" /> ঠপৌà¦à¦›à¦¾à¦¨à§‹à¦° পà§à¦°à¦šà§‡à¦·à§à¦Ÿà¦¾ করেছেন, কিনà§à¦¤à§ সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে যার মেয়াদ খà§à¦¬ বেশি সময়ের যা বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985"><ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> ঠআপনার Google অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡à¦° অনà§à¦¯à¦¾à¦¨à§à¦¯ ধরনের বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ ইতিহাস থাকতে পারে</translation>
<translation id="7029809446516969842">পাসওয়ারà§à¦¡</translation>
+<translation id="7050187094878475250">আমি <ph name="DOMAIN" />-ঠসংযোগ করার চেষà§à¦Ÿà¦¾ করেছেন, কিনà§à¦¤à§ সারà§à¦­à¦¾à¦° à¦à¦•à¦Ÿà¦¿ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে যার বৈধতার সময়সীমা à¦à¦¤ বেশী যে বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯ নয়।</translation>
+<translation id="7053983685419859001">বà§à¦²à¦• করà§à¦¨</translation>
<translation id="7064851114919012435">পরিচিতি তথà§à¦¯</translation>
<translation id="7079718277001814089">à¦à¦‡ সাইটে মালওয়ের আছে</translation>
<translation id="7087282848513945231">দেশ</translation>
-<translation id="7088615885725309056">পূরà§à¦¬à¦¤à¦°</translation>
<translation id="7090678807593890770">Google ঠ<ph name="LINK" /> à¦à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨</translation>
+<translation id="7108819624672055576">à¦à¦•à¦Ÿà¦¿ à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ দà§à¦¬à¦¾à¦°à¦¾ অনà§à¦®à§‹à¦¦à¦¿à¦¤</translation>
<translation id="7119414471315195487">অনà§à¦¯à¦¾à¦¨à§à¦¯ টà§à¦¯à¦¾à¦¬ বা পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® বনà§à¦§ করà§à¦¨</translation>
<translation id="7129409597930077180">à¦à¦‡ ঠিকানায় শিপিং করা যাবে না। অনà§à¦¯ ঠিকানা বেছে নিন।</translation>
<translation id="7138472120740807366">ডেলিভারির পদà§à¦§à¦¤à¦¿</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">পà§à¦°à¦•à§à¦°à¦¿à§Ÿà¦¾à§Ÿ রয়েছে</translation>
<translation id="724691107663265825">à¦à¦‡ সাইটটিতে মà§à¦¯à¦¾à¦²à¦“য়à§à¦¯à¦¾à¦° আছে</translation>
<translation id="724975217298816891">আপনার কারà§à¦¡à§‡à¦° বিবরণ আপডেট করার জনà§à¦¯ মেয়াদ শেষের তারিখ à¦à¦¬à¦‚ <ph name="CREDIT_CARD" /> à¦à¦° CVC লিখà§à¦¨à¥¤ আপনি নিশà§à¦šà¦¿à¦¤ করলে, আপনার কারà§à¦¡à§‡à¦° বিবরণ à¦à¦‡ সাইটের সাথে শেয়ার করা হবে।</translation>
-<translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ঠà¦à¦•à¦Ÿà¦¿ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা যায়নি কারণ আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡à¦° তারিখ à¦à¦¬à¦‚ সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়৷</translation>
+<translation id="7260504762447901703">অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করà§à¦¨</translation>
<translation id="7275334191706090484">পরিচালিত বà§à¦•à¦®à¦¾à¦°à§à¦•à¦—à§à¦²à¦¿</translation>
<translation id="7298195798382681320">পà§à¦°à¦¸à§à¦¤à¦¾à¦¬à¦¿à¦¤</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> ঠকà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ কà§à¦¯à¦¾à¦ªà¦šà¦¾à¦° করা হয়েছে (বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€ দà§à¦¬à¦¾à¦°à¦¾ আপলোডের অনà§à¦°à§‹à¦§ করা হয়েছে, à¦à¦–নও আপলোড করা হয়নি)</translation>
<translation id="7334320624316649418">&amp;পà§à¦¨à¦°à§à¦¬à¦¿à¦¨à§à¦¯à¦¾à¦¸à¦•à§‡ আবার করà§à¦¨</translation>
<translation id="733923710415886693">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦°à¦Ÿà¦¿ শংসাপতà§à¦°à§‡à¦° সà§à¦¬à¦šà§à¦›à¦¤à¦¾à¦° মাধà§à¦¯à¦®à§‡ পà§à¦°à¦•à¦¾à¦¶ করা হয়নি।</translation>
-<translation id="7351800657706554155">আপনি à¦à¦–ন <ph name="SITE" /> ঠযেতে পারবেন না কারণ à¦à¦‡ শংসাপতà§à¦° পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করা হয়েছে। নেটওয়ারà§à¦• তà§à¦°à§à¦Ÿà¦¿ à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£ সাধারণত সাময়িকভাবে হয়ে থাকে, তাই à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ সমà§à¦­à¦¬à¦¤ পরে কাজ করবে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="7353601530677266744">কমà§à¦¯à¦¾à¦¨à§à¦¡ লাইন</translation>
<translation id="7372973238305370288">ফলাফল অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">না</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">কারà§à¦¡ নিশà§à¦šà¦¿à¦¤ করà§à¦¨</translation>
-<translation id="7394102162464064926">আপনার ইতিহাস থেকে à¦à¦‡ পৃষà§à¦ à¦¾à¦—à§à¦²à¦¿ মোছার বà§à¦¯à¦¾à¦ªà¦¾à¦°à§‡ আপনি কি নিশà§à¦šà¦¿à¦¤?
-
-চà§à¦ª! ছদà§à¦®à¦¬à§‡à¦¶à§€ মোড <ph name="SHORTCUT_KEY" /> পরের বারে কাজে লাগতে পারে৷</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">পà§à¦°à§‹à¦«à¦¾à¦‡à¦² পথ</translation>
<translation id="7424977062513257142">à¦à¦‡ ওয়েব পৃষà§à¦ à¦¾à§Ÿ à¦à¦•à¦Ÿà¦¿ à¦à¦®à§à¦¬à§‡à¦¡à§‡à¦¡ পৃষà§à¦ à¦¾ বলছে:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">সাইটটি অবরà§à¦¦à§à¦§</translation>
<translation id="7445762425076701745">আপনি যে সারà§à¦­à¦¾à¦°à§‡ সংযà§à¦•à§à¦¤ রয়েছে সেটিকে সমà§à¦ªà§‚রà§à¦£ যাচাই করতে পারা যায় না৷ আপনি নামগà§à¦²à¦¿ দিয়ে à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ সারà§à¦­à¦¾à¦°à§‡ সংযà§à¦•à§à¦¤ রয়েছেন যা আপনার নেটওয়ারà§à¦•à§‡ বৈধ, যেটি à¦à¦•à¦Ÿà¦¿ বাহà§à¦¯à¦¿à¦• শংসাকরণ করà§à¦¤à§ƒà¦ªà¦•à§à¦· যার à¦à¦Ÿà¦¿à¦° মালিকানা যাচাই করার কোনও উপায় নেই৷ কিছৠশংসাপতà§à¦° করà§à¦¤à§ƒà¦ªà¦•à§à¦· à¦à¦‡ নামগà§à¦²à¦¿ নিরà§à¦¬à¦¿à¦šà¦¾à¦°à§‡ শংসাপতà§à¦°à¦—à§à¦²à¦¿ ইসà§à¦¯à§ করবে, আপনি উদà§à¦¦à¦¿à¦·à§à¦Ÿ ওয়েবসাইটে সংযà§à¦•à§à¦¤ রয়েছেন কোনও আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦¤à§‡ নয় তা নিশà§à¦šà¦¿à¦¤ করার কোনও উপায় নেই৷</translation>
<translation id="7451311239929941790">à¦à¦‡ সমসà§à¦¯à¦¾ সমà§à¦ªà¦°à§à¦•à§‡ <ph name="BEGIN_LINK" />আরো জানà§à¦¨<ph name="END_LINK" />।</translation>
+<translation id="7455133967321480974">বিশà§à¦¬à¦¬à§à¦¯à¦¾à¦ªà§€ ডিফলà§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ (অবরোধ করà§à¦¨)</translation>
<translation id="7460163899615895653">অনà§à¦¯à¦¾à¦¨à§à¦¯ ডিভাইসগà§à¦²à¦¿ থেকে আপনার সামà§à¦ªà§à¦°à¦¤à¦¿à¦• টà§à¦¯à¦¾à¦¬à¦—à§à¦²à¦¿ à¦à¦–ানে দেখা যাবে</translation>
<translation id="7469372306589899959">কারà§à¦¡ নিশà§à¦šà¦¿à¦¤ করা হচà§à¦›à§‡</translation>
<translation id="7481312909269577407">ফরওয়ারà§à¦¡</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">ফিরে পাওয়া নীতির ডিভাইস আইডি খালি অথবা বরà§à¦¤à¦®à¦¾à¦¨ ডিভাইস আইডির সাথে মিলছে না</translation>
<translation id="7514365320538308">ডাউনলোড করà§à¦¨</translation>
<translation id="7518003948725431193">à¦à¦‡ ওয়েব ঠিকানার কোনও ওয়েবপৃষà§à¦ à¦¾ পাওয়া যায় নি: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">মান</translation>
<translation id="7537536606612762813">বাধà§à¦¯à¦¤à¦¾à¦®à§‚লক</translation>
+<translation id="7542403920425041731">আপনি নিশà§à¦šà¦¿à¦¤ করলে আপনার কারà§à¦¡à§‡à¦° বিবরণ à¦à¦‡ সাইটের সাথে শেয়ার করা হবে।</translation>
<translation id="7542995811387359312">সà§à¦¬à¦¯à¦¼à¦‚কà§à¦°à¦¿à¦¯à¦¼ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡ পূরণটি অকà§à¦·à¦® রয়েছে কারণ à¦à¦‡ ফরà§à¦®à¦Ÿà¦¿ কোনও সà§à¦°à¦•à§à¦·à¦¿à¦¤ সংযোগ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে না৷</translation>
<translation id="7543525346216957623">আপনার বাবা-মাকে জিজà§à¦žà¦¾à¦¸à¦¾ করà§à¦¨</translation>
<translation id="7549584377607005141">à¦à¦‡ ওয়েবপৃষà§à¦ à¦¾à¦° à¦à¦®à¦¨ ডেটার দরকার যা আপনি ঠিকভাবে পà§à¦°à¦¦à¦°à§à¦¶à¦¿à¦¤ হওয়ার জনà§à¦¯ আগেই পà§à¦°à¦¬à§‡à¦¶ করেছেন৷ আপনি à¦à¦‡ ডেটাটি আবার পাঠাতে পারেন, কিনà§à¦¤à§ à¦à¦®à¦¨à¦Ÿà¦¿ করে আপনি যেকোনো পদকà§à¦·à§‡à¦ªà§‡à¦° পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿ করবেন যা à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ আগেই সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করেছে৷</translation>
<translation id="7552846755917812628">নিমà§à¦¨à§‹à¦²à§à¦²à¦¿à¦–িত টিপà§à¦¸ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে দেখà§à¦¨:</translation>
<translation id="7554791636758816595">নতà§à¦¨ টà§à¦¯à¦¾à¦¬</translation>
+<translation id="7567204685887185387">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¿ <ph name="DOMAIN" />; à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦° পà§à¦°à¦¤à¦¾à¦°à¦£à¦¾à¦ªà§‚রà§à¦£à¦­à¦¾à¦¬à§‡ ইসà§à¦¯à§ করা হয়ে থাকতে পারে। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে।</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />টি}one{<ph name="CONTACT_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />টি}other{<ph name="CONTACT_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />টি}}</translation>
<translation id="7568593326407688803">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿<ph name="ORIGINAL_LANGUAGE" />ভাষাতে আছে আপনি কি à¦à¦Ÿà¦¿à¦•à§‡ অনà§à¦¬à¦¾à¦¦ করতে চাইবেন?</translation>
<translation id="7569952961197462199">Chrome থেকে কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡ সরাবেন?</translation>
<translation id="7569983096843329377">কালো</translation>
<translation id="7578104083680115302">আপনি Google à¦à¦° সাথে সংরকà§à¦·à¦£ করেছেন à¦à¦®à¦¨ কারà§à¦¡ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে ডিভাইস জà§à¦¡à¦¼à§‡ সাইট à¦à¦¬à¦‚ অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¾à¦¨à¦—à§à¦²à¦¿à¦¤à§‡ দà§à¦°à§à¦¤ অরà§à¦¥ পরিশোধ করà§à¦¨à¥¤</translation>
<translation id="7588950540487816470">বাসà§à¦¤à¦¬à¦¿à¦• ওয়েব</translation>
<translation id="7592362899630581445">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦°, নামের সীমাবদà§à¦§à¦¤à¦¾à¦—à§à¦²à¦¿ লঙà§à¦˜à¦¨ করে৷</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> à¦à¦° কম</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> বরà§à¦¤à¦®à¦¾à¦¨à§‡ à¦à¦‡ অনà§à¦°à§‹à¦§à¦Ÿà¦¿ পরিচালনা করতে অকà§à¦·à¦®à¥¤</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> কখনও অনà§à¦¬à¦¾à¦¦ করবেন না</translation>
<translation id="7610193165460212391">সীমার বাইরে মান <ph name="VALUE" />৷</translation>
<translation id="7613889955535752492">মেয়াদোতà§à¦¤à§€à¦°à§à¦£: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">আপনার কাছে ইতিমধà§à¦¯à§‡à¦‡ à¦à¦®à¦¨ ডেটা আছে যা Google অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡à¦° পাসওয়ারà§à¦¡à§‡à¦° কোনো ভিনà§à¦¨ সংসà§à¦•à¦°à¦£ বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° দà§à¦¬à¦¾à¦°à¦¾ à¦à¦¨à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ করা হয়৷ দয়া করে à¦à¦Ÿà¦¿à¦•à§‡ নিচে লিখà§à¦¨à§·</translation>
-<translation id="7634554953375732414">à¦à¦‡ সাইটে আপনার সংযোগ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত নয়।</translation>
<translation id="7637571805876720304">Chromium থেকে কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡ সরাবেন?</translation>
<translation id="765676359832457558">উনà§à¦¨à¦¤ সেটিংস লà§à¦•à¦¾à¦¨...</translation>
<translation id="7658239707568436148">বাতিল</translation>
+<translation id="7662298039739062396">সেটিংস à¦à¦•à¦Ÿà¦¿ à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ দà§à¦¬à¦¾à¦°à¦¾ নিয়নà§à¦¤à§à¦°à¦¿à¦¤</translation>
<translation id="7667346355482952095">ফিরে পাওয়া নীতির টোকেন খালি অথবা বরà§à¦¤à¦®à¦¾à¦¨ টোকেনের সঙà§à¦—ে মেলে না</translation>
<translation id="7668654391829183341">অজানা ডিভাইস</translation>
<translation id="7669271284792375604">à¦à¦‡ সাইটে থাকা আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ কৌশলে আপনাকে দিয়ে à¦à¦®à¦¨ পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® ইনসà§à¦Ÿà¦² করাতে পারে যা আপনার বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ অভিজà§à¦žà¦¤à¦¾à¦° জনà§à¦¯ কà§à¦·à¦¤à¦¿à¦•à¦° হতে পারে (উদাহরণসà§à¦¬à¦°à§‚প, আপনার হোমপৃষà§à¦ à¦¾ পরিবরà§à¦¤à¦¨ করা বা আপনার পরিদরà§à¦¶à¦¿à¦¤ সাইটগà§à¦²à¦¿à¦¤à§‡ অতিরিকà§à¦¤ বিজà§à¦žà¦¾à¦ªà¦¨ দেখানো)৷</translation>
<translation id="7674629440242451245">Chrome à¦à¦° নতà§à¦¨ দà§à¦°à§à¦¦à¦¾à¦¨à§à¦¤ বৈশিষà§à¦Ÿà§à¦¯à¦—à§à¦²à¦¿à¦¤à§‡ আগà§à¦°à¦¹à§€? chrome.com/dev ঠআমাদের ডেভ চà§à¦¯à¦¾à¦¨à§‡à¦² বà§à¦¯à¦¬à¦¹à¦¾à¦° করে দেখà§à¦¨à§·</translation>
<translation id="7682287625158474539">শিপিং</translation>
+<translation id="7701040980221191251">কিছà§à¦‡ নয়</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /> <ph name="SITE" /> ঠà¦à¦—িয়ে যান (নিরাপদ নয়) <ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">শংসাপতà§à¦°</translation>
+<translation id="7716147886133743102">আপনার পà§à¦°à¦¶à¦¾à¦¸à¦• বà§à¦²à¦• করেছে</translation>
<translation id="7716424297397655342">à¦à¦‡ সাইটটি কà§à¦¯à¦¾à¦¶à§‡ থেকে লোড করা যাবে না</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">অপরিচালিত</translation>
<translation id="7755287808199759310">আপনার পিতামাতা à¦à¦Ÿà¦¿ আপনার জনà§à¦¯ অবরোধ মà§à¦•à§à¦¤ করতে পারবেন</translation>
<translation id="7758069387465995638">ফায়ারওয়াল বা অà§à¦¯à¦¾à¦¨à§à¦Ÿà¦¿à¦­à¦¾à¦‡à¦°à¦¾à¦¸ সফটওয়à§à¦¯à¦¾à¦° সংযোগকে অবরà§à¦¦à§à¦§ করে থাকতে পারে।</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(৩২-বিট)</translation>
<translation id="7956713633345437162">মোবাইল বà§à¦•à¦®à¦¾à¦°à§à¦•</translation>
<translation id="7961015016161918242">কখনই নয়</translation>
-<translation id="7962083544045318153">কà§à¦°à§à¦¯à¦¾à¦¶ আইডি <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">সরà§à¦¬à¦¦à¦¾ <ph name="ORIGINAL_LANGUAGE" />-কে <ph name="TARGET_LANGUAGE" />-তে অনà§à¦¬à¦¾à¦¦ করà§à¦¨</translation>
<translation id="7995512525968007366">নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করে উলà§à¦²à§‡à¦– করা নেই</translation>
<translation id="800218591365569300">মেমরি ফাà¦à¦•à¦¾ করতে অনà§à¦¯à¦¾à¦¨à§à¦¯ টà§à¦¯à¦¾à¦¬ বা পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® বনà§à¦§ করার চেষà§à¦Ÿà¦¾ করà§à¦¨à¥¤</translation>
<translation id="8012647001091218357">à¦à¦‡ মà§à¦¹à§‚রà§à¦¤à§‡ আমরা আপনার পিতামাতার কাছে পৌà¦à¦›à¦¾à¦¤à§‡ পারিনি৷ অনà§à¦—à§à¦°à¦¹ করে আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à§·</translation>
<translation id="8025119109950072390">à¦à¦‡ সাইটে আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনাকে ধোà¦à¦•à¦¾ দিয়ে সফটওয়à§à¦¯à¦¾à¦° ইনসà§à¦Ÿà¦² করা বা আপনার বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত তথà§à¦¯ (উদাহরণসà§à¦¬à¦°à§‚প, পাসওয়ারà§à¦¡, ফোন নমà§à¦¬à¦°, বা কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) পà§à¦°à¦•à¦¾à¦¶ করার মত বিপজà§à¦œà¦¨à¦• কিছৠকরাতে পারে।</translation>
-<translation id="803030522067524905">সমà§à¦ªà§à¦°à¦¤à¦¿ Google à¦à¦° নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ <ph name="SITE" /> ঠফিশিং শনাকà§à¦¤ করেছে। ফিশিং সাইটগà§à¦²à¦¿ আপনার থেকে কৌশলে তথà§à¦¯ নিয়ে নেওয়ার জনà§à¦¯ অনà§à¦¯à¦¾à¦¨à§à¦¯ সাইট যেমন হয় সেইরকম হওয়ার ভান করে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="8034522405403831421">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ <ph name="SOURCE_LANGUAGE" /> ভাষায় রয়েছে৷ à¦à¦Ÿà¦¿à¦•à§‡ <ph name="TARGET_LANGUAGE" /> ভাষায় অনà§à¦¬à¦¾à¦¦ করবেন?</translation>
+<translation id="8037357227543935929">জিজà§à¦žà¦¾à¦¸à¦¾ করà§à¦¨ (ডিফলà§à¦Ÿ)</translation>
<translation id="8041089156583427627">পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ পাঠান</translation>
+<translation id="8041940743680923270">বিশà§à¦¬à¦¬à§à¦¯à¦¾à¦ªà§€ ডিফলà§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ (জানতে চান)</translation>
<translation id="8088680233425245692">নিবনà§à¦§ দেখতে বà§à¦¯à¦°à§à¦¥ হয়েছে৷</translation>
<translation id="8089520772729574115">১ মেগাবাইটের কম</translation>
<translation id="8091372947890762290">সারà§à¦­à¦¾à¦°à§‡ সকà§à¦°à¦¿à§Ÿà¦•à¦°à¦£ বাকি আছে</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> à¦à¦° সারà§à¦­à¦¾à¦° <ph name="BEGIN_ABBR" />DNS ঠিকানা<ph name="END_ABBR" />খà§à¦à¦œà§‡ পাওয়া যায়নি।</translation>
<translation id="8149426793427495338">আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à¦Ÿà¦¿ নিদà§à¦°à¦¾ মোডে গিয়েছে।</translation>
<translation id="8150722005171944719"><ph name="URL" />ঠফাইলটি পাঠযোগà§à¦¯ নয়৷ à¦à¦Ÿà¦¾ মà§à¦›à§‡ ফেলা হয়েছে পারে, সরিয়ে দেওয়া হয়েছে, অথবা ফাইল অনà§à¦®à¦¤à¦¿ পà§à¦°à¦¬à§‡à¦¶à¦¾à¦§à¦¿à¦•à¦¾à¦° পà§à¦°à¦¤à¦¿à¦°à§‹à¦§ করতে পারে৷</translation>
+<translation id="8184538546369750125">বিশà§à¦¬à¦¬à§à¦¯à¦¾à¦ªà§€ ডিফলà§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ (অনà§à¦®à¦¤à¦¿ দিন)</translation>
+<translation id="8191494405820426728">সà§à¦¥à¦¾à¦¨à§€à§Ÿ কà§à¦°à§à¦¯à¦¾à¦¶ আইডি <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;সরানোকে পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ID যà§à¦•à§à¦¤ à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¾à¦¨à§‡à¦° অবৈধ আপডেট URL।</translation>
<translation id="8202097416529803614">অরà§à¦¡à¦¾à¦°à§‡à¦° সারসংকà§à¦·à§‡à¦ª</translation>
<translation id="8218327578424803826">নিরà§à¦§à¦¾à¦°à¦¿à¦¤ অবসà§à¦¥à¦¾à¦¨:</translation>
<translation id="8225771182978767009">à¦à¦‡ কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦° যিনি সেট আপ করেছেন তিনি à¦à¦‡ সাইটটি অবরà§à¦¦à§à¦§ করার বিষয়টি চয়ন করেছেন।</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">বরà§à¦¤à¦®à¦¾à¦¨à§‡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à¦à¦° আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦°à¦¾ আপনার কমà§à¦ªà¦¿à¦‰à¦Ÿà¦¾à¦°à§‡ কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® ইনসà§à¦Ÿà¦² করতে পারে যা আপনার তথà§à¦¯ (উদাহরণসà§à¦¬à¦°à§à¦ª, ফটো, পাসওয়ারà§à¦¡, বারà§à¦¤à¦¾ à¦à¦¬à¦‚ কà§à¦°à§‡à¦¡à¦¿à¦Ÿ কারà§à¦¡) চà§à¦°à¦¿ করতে বা মà§à¦›à§‡ দিতে পারে।</translation>
<translation id="8241707690549784388">আপনি যে পৃষà§à¦ à¦¾à¦Ÿà¦¿ খà§à¦à¦œà¦›à§‡à¦¨ সেটি আপনার পà§à¦°à¦¬à§‡à¦¶ করানো তথà§à¦¯ বà§à¦¯à¦¬à¦¹à¦¾à¦° করছে৷ à¦à¦‡ পৃষà§à¦ à¦¾à¦¤à§‡ ফিরে à¦à¦²à§‡ কোনো কà§à¦°à¦¿à§Ÿà¦¾ আবার করতে হতে পারে৷ আপনি কি অবিরত করতে চান?</translation>
<translation id="8249320324621329438">সরà§à¦¬à¦¶à§‡à¦· পà§à¦°à¦¾à¦ªà§à¦¤ করেছে:</translation>
<translation id="8253091569723639551">বিলিং ঠিকানা পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">যদি আপনি à¦à¦° অরà§à¦¥à§‡à¦° বà§à¦¯à¦¾à¦ªà¦¾à¦°à§‡ নিশà§à¦šà¦¿à¦¤ না হন তাহলে আপনার নেটওয়ারà§à¦• পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° সঙà§à¦—ে যোগাযোগ করà§à¦¨à§·</translation>
<translation id="8293206222192510085">বà§à¦•à¦®à¦¾à¦°à§à¦• যà§à¦•à§à¦¤ করà§à¦¨</translation>
<translation id="8294431847097064396">উৎস</translation>
+<translation id="8306404619377842860"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à¦à¦° সাথে বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা যাবে না কারণ আপনার ডিভাইসের তারিখ ও সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়। <ph name="BEGIN_LEARN_MORE_LINK" />আরও জানà§à¦¨<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">নেটওয়ারà§à¦• সংযোগে কোন সমসà§à¦¯à¦¾ হওয়ার কারণে অনà§à¦¬à¦¾à¦¦ বà§à¦¯à¦°à§à¦¥ হয়েছে৷</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ঠঅà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ অসà§à¦¬à§€à¦•à¦¾à¦° করা হয়েছে</translation>
<translation id="834457929814110454">আপনি যদি আপনার নিরাপতà§à¦¤à¦¾à¦° à¦à§à¦à¦•à¦¿à¦—à§à¦²à¦¿ বà§à¦à¦¤à§‡ পারেন, তাহলে কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® সরানোর আগে আপনি <ph name="BEGIN_LINK" />à¦à¦‡ সাইটে যেতে পারেন<ph name="END_LINK" />৷</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">আপনার Google অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ থেকে কারà§à¦¡ বà§à¦¯à¦¬à¦¹à¦¾à¦° করার জনà§à¦¯ Chrome ঠসাইন ইন করà§à¦¨</translation>
<translation id="8488350697529856933">à¦à¦¤à§‡ পà§à¦°à§Ÿà§‹à¦— হয়</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> সাড়া দিতে খà§à¦¬à§‡ বেশি সময় নিয়েছে।</translation>
-<translation id="852346902619691059">à¦à¦‡ সারà§à¦­à¦¾à¦° পà§à¦°à¦®à¦¾à¦£ করতে পারেনি যে à¦à¦Ÿà¦¾ <ph name="DOMAIN" />; আপনার ডিভাইসের অপারেটিং সিসà§à¦Ÿà§‡à¦® à¦à¦° নিরাপতà§à¦¤à¦¾ শংসাপতà§à¦°à¦Ÿà¦¿à¦•à§‡ বিশà§à¦¬à¦¾à¦¸ করে না। কোনো ভà§à¦² কনফিগারেশনের কারণে অথবা কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ আপনার সংযোগ মাà¦à¦ªà¦¥à§‡ আটকে দিচà§à¦›à§‡ বলে à¦à¦®à¦¨à¦Ÿà¦¾ হতে পারে। <ph name="BEGIN_LEARN_MORE_LINK" />আরো জানà§à¦¨<ph name="END_LEARN_MORE_LINK" />।</translation>
<translation id="8532105204136943229">মেয়াদপূরà§à¦¤à¦¿à¦° বছর</translation>
<translation id="8543181531796978784">আপনি <ph name="BEGIN_ERROR_LINK" />à¦à¦•à¦Ÿà¦¿ সনাকà§à¦¤à¦•à¦°à¦£ সমসà§à¦¯à¦¾ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ করতে পারেন<ph name="END_ERROR_LINK" /> অথবা, আপনি আপনার নিরাপতà§à¦¤à¦¾ à¦à§à¦à¦•à¦¿ বà§à¦à¦¤à§‡ পারলে, <ph name="BEGIN_LINK" />à¦à¦‡ অনিরাপদ সাইটটি ঘà§à¦°à§‡ দেখà§à¦¨<ph name="END_LINK" />।</translation>
<translation id="8553075262323480129">পৃষà§à¦ à¦¾à¦° ভাষা নিরà§à¦§à¦¾à¦°à¦£ না করতে পারার কারণে অনà§à¦¬à¦¾à¦¦ বà§à¦¯à¦°à§à¦¥ হয়েছে৷</translation>
-<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ঠà¦à¦•à¦Ÿà¦¿ বà§à¦¯à¦•à§à¦¤à¦¿à¦—ত সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করা যায়নি কারণ আপনার ডিভাইসের তারিখ à¦à¦¬à¦‚ সময় (<ph name="DATE_AND_TIME" />) সঠিক নয়৷</translation>
<translation id="8571890674111243710">পৃষà§à¦ à¦¾à¦Ÿà¦¿<ph name="LANGUAGE" />তে অনà§à¦¬à¦¾à¦¦ করà§à¦¨...</translation>
<translation id="858637041960032120">ফোননমà§à¦¬à¦° জà§à¦¡à¦¼à§à¦¨</translation>
<translation id="859285277496340001">শংসাপতà§à¦°à¦Ÿà¦¿ পà§à¦°à¦¤à§à¦¯à¦¾à¦¹à¦¾à¦° করা হয়েছে কিনা তা যাচাই করতে শংসাপতà§à¦°à¦Ÿà¦¿ কোনও কারিগরীকে নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করে না৷</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">নিরাপদ নেটওয়ারà§à¦• সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করতে আপনার ঘড়িকে সঠিকভাবে সেট করতে হবে৷ নিরাপদ সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করার জনà§à¦¯ নিজেদের সনাকà§à¦¤ করার জনà§à¦¯ ওয়েবসাইটগà§à¦²à¦¿ যে শংসাপতà§à¦°à¦—à§à¦²à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে, সেগà§à¦²à¦¿ শà§à¦§à§à¦®à¦¾à¦¤à§à¦° নিরà§à¦¦à¦¿à¦·à§à¦Ÿ সময়ের জনà§à¦¯ বৈধ থাকে৷ যেহেতৠআপনার ডিভাইসের ঘড়িটি ভà§à¦², সেই জনà§à¦¯ Chromium সঠিকভাবে শংসাপতà§à¦°à¦—à§à¦²à¦¿ পরীকà§à¦·à¦¾ করতে পারে না৷</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> à¦à¦° &lt;abbr id="dnsDefinition"&gt;DNS ঠিকানা&lt;/abbr&gt; পাওয়া যায়নি। সমসà§à¦¯à¦¾ নিরà§à¦£à§Ÿ করা হচà§à¦›à§‡à¥¤</translation>
<translation id="8759274551635299824">à¦à¦‡ কারà§à¦¡à¦Ÿà¦¿à¦° মেয়াদ শেষ হয়েছে</translation>
+<translation id="8761567432415473239">Google নিরাপদ বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ সমà§à¦ªà§à¦°à¦¤à¦¿ <ph name="SITE" /> ঠ<ph name="BEGIN_LINK" />কà§à¦·à¦¤à¦¿à¦•à¦¾à¦°à¦• পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à¦—à§à¦²à¦¿ খà§à¦à¦œà§‡ পেয়েছে<ph name="END_LINK" />৷</translation>
<translation id="8790007591277257123">&amp;মà§à¦›à§‡ ফেলাকে আবার করà§à¦¨</translation>
<translation id="8800988563907321413">আপনার জনà§à¦¯ আশেপাশের পà§à¦°à¦¸à§à¦¤à¦¾à¦¬à¦¨à¦¾à¦—à§à¦²à¦¿ à¦à¦–ানে দেখা যাবে</translation>
<translation id="8820817407110198400">বà§à¦•à¦®à¦¾à¦°à§à¦•à¦¸</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">সমà§à¦ªà§à¦°à¦¤à¦¿ বনà§à¦§ হয়েছে</translation>
<translation id="8874824191258364635">à¦à¦•à¦Ÿà¦¿ সঠিক কারà§à¦¡ নমà§à¦¬à¦° লিখà§à¦¨</translation>
<translation id="8876793034577346603">নেটওয়ারà§à¦• কনফিগারেশন বিশà§à¦²à§‡à¦·à¦£ করতে বà§à¦¯à¦°à§à¦¥ হয়েছে৷</translation>
-<translation id="8877192140621905067">আপনি নিশà§à¦šà¦¿à¦¤ করলে, আপনার কারà§à¦¡à§‡à¦° বিবরণ à¦à¦‡ সাইটের সাথে শেয়ার করা হবে</translation>
<translation id="8889402386540077796">রঙ বিনà§à¦¯à¦¾à¦¸</translation>
<translation id="8891727572606052622">পà§à¦°à¦•à§à¦¸à¦¿ মোড অবৈধ৷</translation>
<translation id="889901481107108152">দà§à¦ƒà¦–িত, à¦à¦‡ গবেষণা আপনার পà§à¦²à§à¦¯à¦¾à¦Ÿà¦«à¦°à§à¦®à§‡ উপলবà§à¦§ নেই৷</translation>
<translation id="8903921497873541725">জà§à¦® বাড়ান</translation>
<translation id="8931333241327730545">আপনি কি আপনার Google অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡ à¦à¦‡ কারà§à¦¡ সংরকà§à¦·à¦£ করতে চান?</translation>
<translation id="8932102934695377596">আপনার ঘড়ির সময় পিছিয়ে রয়েছে</translation>
-<translation id="8954894007019320973">(চলছে)</translation>
<translation id="8971063699422889582">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦°à§‡à¦° মেয়াদ ফà§à¦°à¦¿à§Ÿà§‡à¦›à§‡à§·</translation>
<translation id="8986494364107987395">বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° পরিসংখà§à¦¯à¦¾à¦¨ à¦à¦¬à¦‚ কà§à¦°à§à¦¯à¦¾à¦¶ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨à¦—à§à¦²à¦¿ সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿà¦­à¦¾à¦¬à§‡ Google-ঠপাঠান</translation>
-<translation id="8987927404178983737">মাস</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">সামনের সাইটটিতে কà§à¦·à¦¤à¦¿à¦•à¦° পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à¦—à§à¦²à¦¿ রয়েছে</translation>
+<translation id="8997023839087525404">সারà§à¦­à¦¾à¦°à¦Ÿà¦¿ à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে যেটি শংসাপতà§à¦°à§‡à¦° সà§à¦¬à¦šà§à¦›à¦¤à¦¾à¦° নীতি বà§à¦¯à¦¬à¦¹à¦¾à¦° করে সরà§à¦¬à¦œà¦¨à§€à¦¨à¦­à¦¾à¦¬à§‡ পà§à¦°à¦•à¦¾à¦¶ করা হয়নি। à¦à¦Ÿà¦¾ কিছৠশংসাপতà§à¦°à§‡à¦° জনà§à¦¯ à¦à¦•à¦Ÿà¦¿ আবশà§à¦¯à¦•à¦¤à¦¾, যাতে করে সেগà§à¦²à¦¿à¦° বিশà§à¦¬à¦¾à¦¸à¦¯à§‹à¦—à§à¦¯à¦¤ করা যায় à¦à¦¬à¦‚ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€à¦¦à§‡à¦° বিরà§à¦¦à§à¦§à§‡ সà§à¦°à¦•à§à¦·à¦¾ নেওয়া যায়।</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> পà§à¦°à¦•à§à¦¸à§€à¦Ÿà¦¿à¦° à¦à¦•à¦Ÿà¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€ নাম à¦à¦¬à¦‚ পাসওয়ারà§à¦¡ পà§à¦°à§Ÿà§‹à¦œà¦¨à¥¤</translation>
+<translation id="9005998258318286617">PDF ডকà§à¦®à§‡à¦¨à§à¦Ÿ লোড করা যায়নি।</translation>
<translation id="901974403500617787">যে ফà§à¦²à§à¦¯à¦¾à¦—গà§à¦²à¦¿ সমসà§à¦¤ সিসà§à¦Ÿà§‡à¦® জà§à§œà§‡ পà§à¦°à§Ÿà§‹à¦— করা হয় সেগà§à¦²à¦¿ শà§à¦§à§à¦®à¦¾à¦¤à§à¦° মালিকের দà§à¦¬à¦¾à¦°à¦¾ সেট করা যেতে পারে: <ph name="OWNER_EMAIL" />৷</translation>
+<translation id="9020200922353704812">কারà§à¦¡à§‡à¦° বিলিং ঠিকানা পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨</translation>
<translation id="9020542370529661692">à¦à¦‡ পৃষà§à¦ à¦¾à¦Ÿà¦¿ <ph name="TARGET_LANGUAGE" /> ঠঅনà§à¦¬à¦¾à¦¦ করা হয়েছে</translation>
<translation id="9035022520814077154">নিরাপতà§à¦¤à¦¾ তà§à¦°à§à¦Ÿà¦¿</translation>
<translation id="9038649477754266430">পৃষà§à¦ à¦¾ আরো দà§à¦°à§à¦¤ লোড করার জনà§à¦¯ কোনো পূরà§à¦¬à¦¾à¦­à¦¾à¦· পরিষেবা বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨</translation>
<translation id="9039213469156557790">উপরনà§à¦¤à§, à¦à¦‡ পৃষà§à¦ à¦¾à¦¤à§‡ অনà§à¦¯à¦¾à¦¨à§à¦¯ সংসà§à¦¥à¦¾à¦¨ অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤ রয়েছে যা নিরাপদ নয়৷ à¦à¦‡ সংসà§à¦¥à¦¾à¦¨à¦—à§à¦²à¦¿ টà§à¦°à¦¾à¦¨à¦œà¦¿à¦Ÿà§‡à¦° সময় অনà§à¦¯à¦°à¦¾ দেখতে পাবে à¦à¦¬à¦‚ পৃষà§à¦ à¦¾à¦Ÿà¦¿à¦° আচরণ পরিবরà§à¦¤à¦¨ করার জনà§à¦¯ কোনো আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ à¦à¦° পরিবরà§à¦¤à¦¨ করতে পারেন৷</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ঠথাকা আকà§à¦°à¦®à¦¨à¦•à¦¾à¦°à§€à¦°à¦¾ ছà§à¦²à¦¨à¦¾à¦° আশà§à¦°à§Ÿ নিয়ে আপনাকে পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à¦—à§à¦²à¦¿ ইনসà§à¦Ÿà¦² করতে পà§à¦°à¦£à§‹à¦¦à¦¿à¦¤ করে যা আপনার বà§à¦°à¦¾à¦‰à¦œà¦¿à¦‚ অভিজà§à¦žà¦¤à¦¾à¦•à§‡ পà§à¦°à¦­à¦¾à¦¬à¦¿à¦¤ করতে পারে (যেমন, আপনার হোমপৃষà§à¦ à¦¾ পরিবরà§à¦¤à¦¨ করা বা আপনার পরিদরà§à¦¶à¦¿à¦¤ সাইটগà§à¦²à¦¿à¦¤à§‡ অতিরিকà§à¦¤ বিজà§à¦žà¦¾à¦ªà¦¨ দেখানো)৷</translation>
+<translation id="9049981332609050619">আপনি <ph name="DOMAIN" />-ঠপৌছানোর পà§à¦°à§Ÿà¦¾à¦¸ করছেন, কিনà§à¦¤à§ সারà§à¦­à¦¾à¦° à¦à¦•à¦Ÿà¦¿ অবৈধ শংসাপতà§à¦° উপসà§à¦¥à¦¾à¦ªà¦¨ করেছে|</translation>
<translation id="9050666287014529139">পাসফà§à¦°à§‡à¦œ</translation>
<translation id="9065203028668620118">সমà§à¦ªà¦¾à¦¦à¦¨à¦¾</translation>
<translation id="9068849894565669697">রঙ নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨</translation>
+<translation id="9069693763241529744">à¦à¦•à¦Ÿà¦¿ à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ বà§à¦²à¦• করেছে</translation>
<translation id="9076283476770535406">à¦à¦¤à§‡ পà§à¦°à¦¾à¦ªà§à¦¤à¦¬à§Ÿà¦¸à§à¦•à¦¦à§‡à¦° সামগà§à¦°à§€ থাকতে পারে</translation>
<translation id="9078964945751709336">আরো তথà§à¦¯ পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨</translation>
<translation id="9103872766612412690"><ph name="SITE" /> সাধারণত আপনার তথà§à¦¯ সà§à¦°à¦•à§à¦·à¦¿à¦¤ রাখতে à¦à¦¨à¦•à§à¦°à¦¿à¦ªà¦¶à¦¾à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করে। à¦à¦‡à¦¬à¦¾à¦° যখন Chromium <ph name="SITE" /> à¦à¦° সাথে সংযোগ সà§à¦¥à¦¾à¦ªà¦¨ করার চেষà§à¦Ÿà¦¾ করেছে, তখন ওয়েবসাইটটি অসà§à¦¬à¦¾à¦­à¦¾à¦¬à¦¿à¦• à¦à¦¬à¦‚ ভà§à¦² শংসাপতà§à¦° পাঠিয়েছে। হয় à¦à¦•à¦œà¦¨ আকà§à¦°à¦®à¦£à¦•à¦¾à¦°à§€ <ph name="SITE" /> হওয়ার ভান করছে, অথবা à¦à¦•à¦Ÿà¦¿ ওয়াই-ফাই পà§à¦°à¦¬à§‡à¦¶ করà§à¦¨ সà§à¦•à§à¦°à§€à¦£ সংযোগকে বাধাপà§à¦°à¦¦à¦¾à¦¨ করেছে। আপনার তথà§à¦¯ à¦à¦–নো নিরাপদ আছে কারণ কোনো ডেটা আদানপà§à¦°à¦¦à¦¾à¦¨à§‡à¦° আগেই Chromium সংযোগটিকে বনà§à¦§ করে দিয়েছে।</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">&amp;সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦•à§‡ পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফেরান</translation>
<translation id="9154194610265714752">আপডেট রয়েছে</translation>
<translation id="9157595877708044936">সেট আপ হচà§à¦›à§‡...</translation>
+<translation id="9169664750068251925">à¦à¦‡ সাইটে সরà§à¦¬à¦¦à¦¾ অবরোধ করà§à¦¨</translation>
<translation id="9170848237812810038">&amp;পূরà§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à§Ÿ ফিরà§à¦¨</translation>
<translation id="917450738466192189">সারà§à¦­à¦¾à¦°à§‡à¦° শংসাপতà§à¦° অকারà§à¦¯à¦•à¦°à§·</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />টি}one{<ph name="SHIPPING_OPTION_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />টি}other{<ph name="SHIPPING_OPTION_PREVIEW" /> à¦à¦¬à¦‚ আরও <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />টি}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> à¦à¦•à¦Ÿà¦¿ অসমরà§à¦¥à¦¿à¦¤ পà§à¦°à§‹à¦Ÿà§‹à¦•à¦² বà§à¦¯à¦¬à¦¹à¦¾à¦° করে।</translation>
<translation id="9205078245616868884">আপনার ডেটা আপনার সিঙà§à¦• পাসফà§à¦°à§‡à¦œ দিয়ে à¦à¦¨à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ করা হয়েছে। সিঙà§à¦• শà§à¦°à§ করার জনà§à¦¯ à¦à¦Ÿà¦¿ লিখà§à¦¨à¥¤</translation>
<translation id="9207861905230894330">নিবনà§à¦§ যোগ করতে বà§à¦¯à¦°à§à¦¥ হয়েছে৷</translation>
+<translation id="9219103736887031265">চিতà§à¦°à¦—à§à¦²à¦¿</translation>
<translation id="933612690413056017">কোনো ইনà§à¦Ÿà¦¾à¦°à¦¨à§‡à¦Ÿ সংযোগ নেই</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ফরà§à¦® সাফ করà§à¦¨</translation>
<translation id="939736085109172342">নতà§à¦¨ ফোলà§à¦¡à¦¾à¦°</translation>
<translation id="941721044073577244">মনে হচà§à¦›à§‡ à¦à¦‡ সাইটটি ঘà§à¦°à§‡ দেখার অনà§à¦®à¦¤à¦¿ আপনার নেই</translation>
<translation id="969892804517981540">অফিসিয়াল বিলà§à¦¡</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{কিছà§à¦‡ নয়}=1{১টি আইটেম}one{#টি আইটেম}other{#টি আইটেম}}</translation>
<translation id="988159990683914416">বিকাশকারী বিলà§à¦¡</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ca.xtb b/chromium/components/strings/components_strings_ca.xtb
index 0b009baa947..bce15d3ef69 100644
--- a/chromium/components/strings/components_strings_ca.xtb
+++ b/chromium/components/strings/components_strings_ca.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Gira en el sentit de les agulles del rellotge</translation>
<translation id="1038842779957582377">nom desconegut</translation>
<translation id="1050038467049342496">Tanca altres aplicacions</translation>
-<translation id="1053591932240354961">En aquest moment no pots visitar <ph name="SITE" /> perquè el lloc web ha enviat credencials aleatòries que Google Chrome no pot processar. Els errors i els atacs de xarxa solen ser temporals, de manera que és probable que aquesta pàgina torni a funcionar més tard. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Desfés l'addició</translation>
<translation id="10614374240317010">Contrasenyes que no es desen mai</translation>
<translation id="106701514854093668">Adreces d'interès d'escriptori</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">La memòria cau de la política està en bon estat</translation>
<translation id="113188000913989374"><ph name="SITE" /> diu:</translation>
<translation id="1132774398110320017">Configuració d'Emplenament automàtic de Chrome...</translation>
+<translation id="1150979032973867961">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè el sistema operatiu del vostre ordinador considera que el seu certificat de seguretat no és de confiança. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
+<translation id="1151972924205500581">Es requereix una contrasenya</translation>
<translation id="1152921474424827756">Accediu a una <ph name="BEGIN_LINK" />còpia emmagatzemada a la memòria cau<ph name="END_LINK" /> de la pàgina <ph name="URL" />.</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ha tancat la connexió de manera inesperada.</translation>
<translation id="1161325031994447685">Torneu-vos a connectar a la xarxa Wi-Fi</translation>
+<translation id="1165039591588034296">Error</translation>
<translation id="1175364870820465910">&amp;Imprimeix...</translation>
<translation id="1181037720776840403">Suprimeix</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Informa automàticament<ph name="END_WHITEPAPER_LINK" /> Google dels detalls sobre possibles incidències de seguretat. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Més entrades d'aquest lloc</translation>
<translation id="1206967143813997005">Signatura inicial incorrecta</translation>
<translation id="1209206284964581585">Amaga per ara</translation>
+<translation id="121201262018556460">Heu provat d'accedir a <ph name="DOMAIN" />, però el servidor ha presentat un certificat que conté una clau dèbil. És possible que un atacant hagi accedit a la clau privada i que aquest servidor no sigui el que espereu (pot ser que us estigueu comunicant amb un atacant).</translation>
<translation id="1219129156119358924">Seguretat del sistema</translation>
<translation id="1227224963052638717">Política desconeguda.</translation>
<translation id="1227633850867390598">Amaga el valor</translation>
<translation id="1228893227497259893">Identificador d'entitat incorrecte</translation>
<translation id="1232569758102978740">Sense títol</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (informació sincronitzada)</translation>
<translation id="1263231323834454256">Llista de lectura</translation>
<translation id="1264126396475825575">S'ha capturat un informe d'error (<ph name="CRASH_TIME" />) (encara no s'ha penjat ni ignorat)</translation>
+<translation id="1281526147609854549">Emès per <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Contingut perillós bloquejat</translation>
<translation id="1285320974508926690">No tradueixis mai aquest lloc</translation>
<translation id="129553762522093515">Tancades recentment</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Esborreu les galetes<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">És possible que la teva activitat <ph name="BEGIN_EMPHASIS" />continuï sent visible<ph name="END_EMPHASIS" /> en:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Els llocs web que visitis
+ <ph name="LIST_ITEM" />La teva empresa o el teu centre educatiu
+ <ph name="LIST_ITEM" />El teu proveïdor de serveis d'Internet
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domini d'inscripció:</translation>
<translation id="1340482604681802745">Adreça de recollida</translation>
<translation id="1344211575059133124">Sembla que necessites permís per visitar aquest lloc</translation>
<translation id="1344588688991793829">Configuració d'Emplenament automàtic de Chromium...</translation>
+<translation id="1348198688976932919">Aquest lloc web conté aplicacions perilloses</translation>
<translation id="1374468813861204354">suggeriments</translation>
<translation id="1375198122581997741">Quan a la versió</translation>
<translation id="1377321085342047638">Número de targeta</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> no ha enviat dades.</translation>
<translation id="1407135791313364759">Obre-les totes</translation>
<translation id="1413809658975081374">Error de privadesa</translation>
+<translation id="14171126816530869">La identitat de <ph name="ORGANIZATION" /> a <ph name="LOCALITY" /> ha estat verificada per <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Sí</translation>
<translation id="1430915738399379752">Impressió</translation>
-<translation id="1442912890475371290">S'ha bloquejat un intent <ph name="BEGIN_LINK" />d'accés a una pàgina de <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">En aquest moment no pots visitar <ph name="SITE" /> perquè el lloc web fa servir la fixació de certificats. Els errors i els atacs de xarxa solen ser temporals, de manera que és probable que aquesta pàgina torni a funcionar més tard. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> més}other{<ph name="PAYMENT_METHOD_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> més}}</translation>
<translation id="1506687042165942984">Mostra una còpia desada (és a dir, no actualitzada) d'aquesta pàgina.</translation>
<translation id="1517433312004943670">El número de telèfon és obligatori</translation>
<translation id="1519264250979466059">Data de creació</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Heu d'activar el JavaScript per utilitzar aquesta funció.</translation>
<translation id="1555130319947370107">Blau</translation>
<translation id="1559528461873125649">No existeix el fitxer o el directori</translation>
-<translation id="1559572115229829303">&lt;p&gt;No es pot establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora (<ph name="DATE_AND_TIME" />) del vostre dispositiu no són correctes.&lt;/p&gt;
-
- &lt;p&gt;Canvieu la data i l'hora a la secció &lt;strong&gt;General&lt;/strong&gt; de l'aplicació &lt;strong&gt;Configuració&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">S'ha produït un error en mostrar aquesta pàgina web.</translation>
<translation id="1592005682883173041">Accés a les dades locals</translation>
+<translation id="1594030484168838125">Tria</translation>
<translation id="161042844686301425">Cian</translation>
+<translation id="1620510694547887537">Càmera</translation>
<translation id="1629803312968146339">Voleu que Chrome desi aquesta targeta?</translation>
<translation id="1639239467298939599">S'està carregant</translation>
<translation id="1640180200866533862">Polítiques d'usuari</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">La configuració de la xarxa no és vàlida i no s'ha pogut importar.</translation>
<translation id="1644574205037202324">Historial</translation>
<translation id="1645368109819982629">Protocol no admès</translation>
+<translation id="1655462015569774233">{1,plural, =1{Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" /> perquè el seu certificat de seguretat va caducar ahir. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió. Actualment, el rellotge del vostre ordinador està configurat amb la data <ph name="CURRENT_DATE" />. És correcta? Si no ho és, corregiu el rellotge del sistema i, a continuació, actualitzeu aquesta pàgina.}other{Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" /> perquè el seu certificat va caducar fa # dies. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió. Actualment, el rellotge del vostre ordinador està configurat amb la data <ph name="CURRENT_DATE" />. És correcta? Si no ho és, corregiu el rellotge del sistema i, a continuació, actualitzeu aquesta pàgina.}}</translation>
<translation id="1656489000284462475">Recollida</translation>
<translation id="1663943134801823270">Les targetes i les adreces s'obtenen de Chrome. Pots gestionar-les des de <ph name="BEGIN_LINK" />Configuració<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> utilitza normalment l'encriptació per protegir la vostra informació. En aquesta ocasió, quan Google Chrome ha provat de connectar-se a <ph name="SITE" />, el lloc web ha enviat credencials poc comunes i incorrectes. Pot ser que un atacant estigui provant de fer-se passar per <ph name="SITE" /> o que una pantalla d'inici de sessió a la xarxa Wi-Fi hagi interromput la connexió. En qualsevol cas, la vostra informació continua estant segura, perquè Google Chrome ha aturat la connexió abans no s'intercanviés cap dada.</translation>
-<translation id="168328519870909584">Els atacants que actualment són al lloc <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> poden provar d'instal·lar aplicacions perilloses al dispositiu per robar o suprimir la teva informació (com ara fotos, contrasenyes, missatges i targetes de crèdit).</translation>
<translation id="168841957122794586">El certificat de servidor conté una clau criptogràfica dèbil.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" /> perquè, suposadament, el seu certificat de seguretat té la data de demà. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.}other{Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" />; perquè, suposadament, el seu certificat de seguretat té una data que és d'aquí a # dies. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.}}</translation>
<translation id="1710259589646384581">SO</translation>
<translation id="1721312023322545264">Cal que <ph name="NAME" /> et doni permís per visitar aquest lloc</translation>
<translation id="1721424275792716183">* El camp és obligatori</translation>
@@ -91,23 +104,27 @@
<translation id="1745358365027406341">Baixa la pàgina més tard</translation>
<translation id="17513872634828108">Pestanyes obertes</translation>
<translation id="1753706481035618306">Número de pàgina</translation>
+<translation id="1763864636252898013">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè el sistema operatiu del vostre dispositiu considera que el seu certificat de seguretat no és de confiança. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Proveu d'executar el Diagnòstic de xarxa de Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Actualitzeu la frase de contrasenya de sincronització.</translation>
<translation id="1787142507584202372">Les pestanyes obertes es mostren aquí</translation>
+<translation id="1789575671122666129">Finestres emergents</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nom del titular de la targeta</translation>
-<translation id="1803678881841855883">Fa poc, la funció Navegació segura de Google <ph name="BEGIN_LINK" />ha detectat programari maliciós<ph name="END_LINK" /> a <ph name="SITE" />. De vegades, els llocs web que acostumen a ser segurs s'infecten amb programari maliciós. El contingut maliciós prové de l'amfitrió <ph name="SUBRESOURCE_HOST" />, un distribuïdor conegut de programari maliciós. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Afegida el dia <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Sol·licitud o paràmetres de la sol·licitud no vàlids</translation>
<translation id="1826516787628120939">S'està comprovant</translation>
<translation id="1834321415901700177">Aquest lloc conté programes perjudicials</translation>
+<translation id="1840414022444569775">Aquest número de targeta ja s'utilitza</translation>
<translation id="1842969606798536927">Pagament</translation>
<translation id="1871208020102129563">El servidor intermediari està configurat perquè utilitzi servidors intermediaris fixos, en lloc d'un URL d'script .pac.</translation>
<translation id="1871284979644508959">Camp obligatori</translation>
<translation id="187918866476621466">Obre les pàgines d'inici</translation>
<translation id="1883255238294161206">Redueix la llista</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> més}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> més}}</translation>
<translation id="1898423065542865115">Filtratge</translation>
-<translation id="194030505837763158">Vés a <ph name="LINK" /></translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Cap}=1{1 lloc}other{# llocs}}</translation>
+<translation id="194030505837763158">Ves a <ph name="LINK" /></translation>
<translation id="1962204205936693436">Adreces d'interès de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error de serialització</translation>
<translation id="1974060860693918893">Configuració avançada</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">S'ha ignorat perquè <ph name="POLICY_NAME" /> l'ha substituït.</translation>
<translation id="2138201775715568214">S'estan cercant pàgines del Web físic a prop</translation>
<translation id="213826338245044447">Adreces d'interès per a mòbils</translation>
-<translation id="2148716181193084225">Avui</translation>
+<translation id="2147827593068025794">Sincronització en segon pla</translation>
<translation id="2154054054215849342">La sincronització no està disponible per al teu domini</translation>
<translation id="2154484045852737596">Edita la targeta</translation>
<translation id="2166049586286450108">Accés complet d'administrador</translation>
<translation id="2166378884831602661">Aquest lloc no pot proporcionar una connexió segura</translation>
<translation id="2181821976797666341">Polítiques</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adreça}other{# adreces}}</translation>
+<translation id="2187317261103489799">Detecta (opció predeterminada)</translation>
<translation id="2202020181578195191">Introdueix un any de caducitat vàlid</translation>
<translation id="2212735316055980242">No es troba la política</translation>
<translation id="2213606439339815911">S'estan recuperant les entrades...</translation>
+<translation id="2218879909401188352">És possible que els atacants que es troben a <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> instal·lin aplicacions perilloses que malmetin el teu dispositiu, afegeixin càrrecs amagats a la teva factura telefònica o et robin informació personal. <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Repareu la connexió amb l'<ph name="BEGIN_LINK" />aplicació de diagnòstic<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Envia ara</translation>
<translation id="225207911366869382">El valor d'aquesta política és obsolet.</translation>
<translation id="2262243747453050782">Error d'HTTP</translation>
+<translation id="2270484714375784793">Número de telèfon</translation>
<translation id="2282872951544483773">Experiments no disponibles</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element}other{<ph name="ITEM_COUNT" /> elements}}</translation>
<translation id="2292556288342944218">El vostre accés a Internet està bloquejat</translation>
<translation id="230155334948463882">És una targeta nova?</translation>
-<translation id="2305919008529760154">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" />. És possible que el seu certificat de seguretat s'hagi emès de manera fraudulenta. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> requereix un nom d'usuari i una contrasenya.</translation>
-<translation id="2318774815570432836">En aquest moment no pots visitar <ph name="SITE" /> perquè el lloc web fa servir HSTS. Els errors i els atacs de xarxa solen ser temporals, de manera que és probable que aquesta pàgina torni a funcionar més tard. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">L'administrador controla l'opció de configuració</translation>
<translation id="2354001756790975382">Altres adreces d'interès</translation>
+<translation id="2354430244986887761">Recentment, Navegació segura de Google <ph name="BEGIN_LINK" />ha trobat aplicacions perjudicials<ph name="END_LINK" /> a <ph name="SITE" />.</translation>
<translation id="2355395290879513365">És possible que els atacants puguin veure les imatges que miris en aquest lloc i que les modifiquin per enganyar-te.</translation>
+<translation id="2356070529366658676">Pregunta-ho</translation>
+<translation id="2359629602545592467">Diverses</translation>
<translation id="2359808026110333948">Continua</translation>
<translation id="2365563543831475020">L'informe d'error capturat (<ph name="CRASH_TIME" />) no s'ha penjat</translation>
<translation id="2367567093518048410">Nivell</translation>
-<translation id="2371153335857947666">{1,plural, =1{Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" /> perquè el seu certificat de seguretat va caducar ahir. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. Actualment, el rellotge del teu ordinador està configurat amb la data <ph name="CURRENT_DATE" />. És correcta? Si no ho és, corregeix el rellotge del sistema i, a continuació, actualitza aquesta pàgina. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.}other{Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" /> perquè el seu certificat va caducar fa # dies. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. Actualment, el rellotge del teu ordinador està configurat amb la data <ph name="CURRENT_DATE" />. És correcta? Si no ho és, corregeix el rellotge del sistema i, a continuació, actualitza aquesta pàgina. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">No hi ha cap alternativa a la IU disponible.</translation>
<translation id="2384307209577226199">Predeterminada de l'empresa</translation>
<translation id="2386255080630008482">El certificat del servidor s'ha revocat.</translation>
<translation id="2392959068659972793">Mostra les polítiques sense valors definits</translation>
<translation id="239429038616798445">Aquest mètode d'enviament no està disponible. Prova'n un altre.</translation>
<translation id="2396249848217231973">&amp;Desfés la supressió</translation>
-<translation id="2460160116472764928">Fa poc, la funció Navegació segura de Google <ph name="BEGIN_LINK" />ha detectat programari maliciós<ph name="END_LINK" /> a <ph name="SITE" />. De vegades, els llocs web que acostumen a ser segurs s'infecten amb programari maliciós. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">El servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè és possible que el seu certificat de seguretat s'hagi revocat. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
<translation id="2463739503403862330">Emplena</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Executar el Diagnòstic de xarxa<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL de cerca no vàlid.</translation>
+<translation id="2482878487686419369">Notificacions</translation>
<translation id="2491120439723279231">El certificat del servidor conté errors.</translation>
<translation id="2495083838625180221">Analitzador JSON</translation>
<translation id="2495093607237746763">Si s'activa aquesta casella, Chromium desa una còpia de la vostra targeta al dispositiu per agilitzar l'emplenament de formularis.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Enrere</translation>
<translation id="2515629240566999685">Comproveu el senyal a la vostra zona</translation>
<translation id="2516305470678292029">Alternatives a la IU</translation>
+<translation id="2539524384386349900">Detecta</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ha enviat una resposta que no és vàlida.</translation>
-<translation id="2552545117464357659">Més nova</translation>
<translation id="2556876185419854533">&amp;Desfés la modificació</translation>
<translation id="2587730715158995865">Publicat per <ph name="ARTICLE_PUBLISHER" />. Llegeix aquesta història i <ph name="OTHER_ARTICLE_COUNT" /> més.</translation>
<translation id="2587841377698384444">Identificador de l'API de directoris:</translation>
<translation id="2597378329261239068">Aquest document està protegit mitjançant contrasenya. Introduïu una contrasenya.</translation>
<translation id="2609632851001447353">Variacions</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Cap}=1{1 aplicació ($1)}=2{2 aplicacions ($1, $2)}other{# aplicacions ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">El rellotge està avançat</translation>
<translation id="2639739919103226564">Estat:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">S'ha denegat l'accés al fitxer</translation>
<translation id="2653659639078652383">Envia</translation>
<translation id="2666117266261740852">Tanca altres pestanyes o aplicacions</translation>
-<translation id="2674170444375937751">Estàs segur que vols suprimir aquestes pàgines de l'historial?</translation>
+<translation id="2670429602441959756">Aquesta pàgina conté funcions que encara no s'admeten en RV. Se n'està sortint...</translation>
+<translation id="2674170444375937751">Confirmes que vols suprimir aquestes pàgines de l'historial?</translation>
<translation id="2677748264148917807">Surt</translation>
-<translation id="269990154133806163">El servidor ha presentat un certificat que no s'ha divulgat públicament mitjançant la política Transparència de certificats. Això és un requisit d'alguns certificats per garantir que són de confiança i una mesura de protecció contra els atacants. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Llista de lectura</translation>
<translation id="2704283930420550640">El valor no coincideix amb el format.</translation>
<translation id="2704951214193499422">En aquest moment Chromium no ha pogut confirmar la teva targeta. Torna-ho a provar més tard.</translation>
<translation id="2705137772291741111">La còpia desada (a la memòria cau) d'aquest lloc no s'ha pogut llegir.</translation>
<translation id="2709516037105925701">Emplenament autom.</translation>
-<translation id="2712118517637785082">Has provat d'accedir a <ph name="DOMAIN" />, però l'emissor ha revocat el certificat que ha presentat el servidor. Això vol dir que les credencials de seguretat que ha proporcionat el servidor no són de confiança. És possible que t'estiguis comunicant amb un atacant. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Demana permís</translation>
<translation id="2713444072780614174">Blanc</translation>
<translation id="2720342946869265578">A prop</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Falta el registre del dispositiu</translation>
<translation id="2784949926578158345">S'ha restablert la connexió.</translation>
<translation id="2794233252405721443">Lloc bloquejat</translation>
+<translation id="2799020568854403057">Aquest lloc web conté aplicacions perjudicials</translation>
+<translation id="2803306138276472711">Navegació segura de Google ha <ph name="BEGIN_LINK" />detectat programari maliciós<ph name="END_LINK" /> recentment a la pàgina <ph name="SITE" />. De vegades, els llocs web que acostumen a ser segurs s'infecten amb programari maliciós.</translation>
<translation id="2824775600643448204">Barra d'adreces i de cerca</translation>
<translation id="2826760142808435982">La connexió s'ha encriptat i autenticat mitjançant <ph name="CIPHER" /> i fa servir <ph name="KX" /> com a mecanisme d'intercanvi clau.</translation>
<translation id="2835170189407361413">Esborra el formulari</translation>
+<translation id="2856444702002559011">Pot ser que els atacants provin de robar la teva informació del lloc web <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (per exemple, contrasenyes, missatges o targetes de crèdit). <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">No tornis a carregar</translation>
<translation id="2900469785430194048">Google Chrome s'ha quedat sense memòria en provar de mostrar aquesta pàgina web.</translation>
<translation id="2909946352844186028">S'ha detectat un canvi a la xarxa.</translation>
<translation id="2916038427272391327">Tanca altres programes</translation>
<translation id="2922350208395188000">No es pot comprovar el certificat del servidor.</translation>
<translation id="2928905813689894207">Adreça de facturació</translation>
+<translation id="2941952326391522266">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè el seu certificat de seguretat prové del domini <ph name="DOMAIN2" />. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
<translation id="2948083400971632585">Podeu desactivar qualsevol servidor intermediari configurat per a una connexió des de la pàgina de configuració.</translation>
<translation id="2955913368246107853">Tanca la barra de cerca</translation>
<translation id="2958431318199492670">La configuració de la xarxa no compleix l'estàndard ONC. Pot ser que algunes opcions de configuració no s'hagin importat.</translation>
-<translation id="29611076221683977">Els atacants que actualment són al lloc <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> poden provar d'instal·lar programes perillosos al dispositiu Mac per robar o suprimir la teva informació (per exemple, les fotos, les contrasenyes, els missatges i les targetes de crèdit).</translation>
<translation id="2966678944701946121">Data de caducitat: <ph name="EXPIRATION_DATE_ABBR" />; afegida el dia <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Per establir una connexió segura, heu de tenir el rellotge ben configurat, ja que els certificats que els llocs web fan servir per identificar-se només són vàlids durant períodes de temps concrets. Com que el rellotge del dispositiu no està ben configurat, Google Chrome no pot verificar aquests certificats.</translation>
<translation id="2972581237482394796">&amp;Refés</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Introdueix una adreça vàlida</translation>
<translation id="2986368408720340940">Aquest mètode de recollida no està disponible. Prova'n un altre.</translation>
<translation id="2991174974383378012">Comparteix informació amb llocs web</translation>
+<translation id="2991571918955627853">En aquest moments no pots visitar la pàgina <ph name="SITE" /> perquè el lloc web fa servir HSTS. Els atacs i els errors de xarxa acostumen a ser temporals, o sigui que probablement la pàgina funcionarà més endavant.</translation>
<translation id="3005723025932146533">Mostra la còpia desada</translation>
<translation id="3008447029300691911">Introdueix el CVC de la targeta <ph name="CREDIT_CARD" />. Un cop confirmada, els detalls de la targeta es compartiran amb aquest lloc.</translation>
<translation id="3010559122411665027">Entrada de llista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Bloquejada automàticament</translation>
<translation id="3024663005179499861">Tipus de política incorrecte</translation>
<translation id="3032412215588512954">Voleu tornar a carregar aquest lloc?</translation>
<translation id="3037605927509011580">Oh, no!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{almenys 1 element als dispositius sincronitzats}=1{1 element (i altres elements als dispositius sincronitzats)}other{# elements (i altres elements als dispositius sincronitzats)}}</translation>
<translation id="3041612393474885105">Informació del certificat</translation>
<translation id="3063697135517575841">Chrome no ha pogut confirmar la teva targeta. Torna-ho a provar més tard.</translation>
<translation id="3064966200440839136">Per pagar amb una aplicació externa sortiràs del mode d'incògnit. Vols continuar?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Cap}=1{1 contrasenya}other{# contrasenyes}}</translation>
<translation id="3093245981617870298">Esteu fora de línia.</translation>
<translation id="3105172416063519923">Identificador de l'element:</translation>
<translation id="3109728660330352905">No teniu permís per veure aquesta pàgina.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Proveu d'executar el Diagnòstic de connectivitat<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">No s'ha pogut descodificar la resposta</translation>
<translation id="3150653042067488994">Error temporal del servidor</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Les pàgines que consulteu en pestanyes d'incògnit no s'emmagatzemaran a l'historial del navegador, al magatzem de galetes ni a l'historial de cerca després d'haver tancat totes les pestanyes d'incògnit. Els fitxers que baixeu i les adreces d'interès que creeu sí que es desaran.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Illa</translation>
+<translation id="317583078218509884">La nova configuració dels permisos del lloc es farà efectiva quan torneu a carregar la pàgina.</translation>
<translation id="3176929007561373547">Comproveu la configuració del servidor intermediari o contacteu amb l'administrador de la xarxa per
assegurar-vos que el servidor intermediari funcioni correctament. Si creieu que no és necessari
utilitzar un servidor intermediari:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Obre la pàgina en mode d'incògnit</translation>
-<translation id="3202578601642193415">Els més recents</translation>
+<translation id="320323717674993345">Cancel·la el pagament</translation>
<translation id="3207960819495026254">S'ha afegit a les adreces d'interès.</translation>
+<translation id="3225919329040284222">El servidor ha presentat un certificat que no coincideix amb les expectatives integrades. Les expectatives s'inclouen perquè determinats llocs web d'alta seguretat us protegeixin.</translation>
<translation id="3226128629678568754">Premeu el botó de tornar a carregar per tornar a enviar les dades necessàries per carregar la pàgina.</translation>
+<translation id="3227137524299004712">Micròfon</translation>
<translation id="3228969707346345236">S'ha produït un error en fer la traducció perquè la pàgina ja està en <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Introdueix el CVC de la targeta <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Detecta sempre el contingut important d'aquest lloc</translation>
<translation id="3254409185687681395">Afegeix aquesta pàgina a les adreces d'interès</translation>
<translation id="3270847123878663523">&amp;Desfés el canvi d'ordre</translation>
<translation id="3282497668470633863">Afegeix el titular de la targeta</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">configuració</translation>
<translation id="3345135638360864351">La sol·licitud per accedir al lloc no s'ha pogut enviar a <ph name="NAME" />. Torneu-ho a provar.</translation>
<translation id="3355823806454867987">Canvia la configuració del servidor intermediari...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />no desarà<ph name="END_EMPHASIS" /> la informació següent:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />El teu historial de navegació
+ <ph name="LIST_ITEM" />Les galetes i les dades de llocs
+ <ph name="LIST_ITEM" />La informació que introdueixis en formularis
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Error de rellotge</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> elements més...</translation>
<translation id="337363190475750230">No administrat</translation>
<translation id="3377188786107721145">S'ha produït un error en analitzar la política</translation>
<translation id="3380365263193509176">Error desconegut</translation>
<translation id="3380864720620200369">Identificador de client:</translation>
<translation id="3391030046425686457">Adreça d'entrega</translation>
<translation id="3395827396354264108">Mètode de recollida</translation>
-<translation id="340013220407300675">És possible que hi hagi atacants que estiguin provant de robar-vos informació de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (per exemple, contrasenyes, missatges o targetes de crèdit).</translation>
<translation id="3422248202833853650">Prova de sortir d'altres programes per alliberar memòria.</translation>
<translation id="3422472998109090673">Actualment no es pot accedir a <ph name="HOST_NAME" />.</translation>
+<translation id="3427092606871434483">Permet (opció predeterminada)</translation>
<translation id="3427342743765426898">&amp;Refés la modificació</translation>
<translation id="3431636764301398940">Desa aquesta targeta al dispositiu</translation>
<translation id="3435896845095436175">Activa</translation>
<translation id="3447661539832366887">El propietari d'aquest dispositiu ha desactivat el joc de dinosaures.</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">Obtén l'interval:</translation>
<translation id="3462200631372590220">Amaga la configuració avançada</translation>
<translation id="3467763166455606212">El nom del titular de la targeta és obligatori</translation>
<translation id="3478058380795961209">Mes de caducitat</translation>
<translation id="3479539252931486093">Heu trobat el lloc bloquejat de manera inesperada? <ph name="BEGIN_LINK" />Informeu-nos-en<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ara no</translation>
-<translation id="348000606199325318">Identificador d'error <ph name="CRASH_LOCAL_ID" /> (identificador de servidor: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">En aquests moments no ens hem pogut posar en contacte amb els pares. Torneu-ho a provar.</translation>
<translation id="3528171143076753409">El certificat del servidor no és de confiança.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Almenys 1 element als dispositius sincronitzats}=1{1 element (i altres elements als dispositius sincronitzats)}other{# elements (i altres elements als dispositius sincronitzats)}}</translation>
<translation id="3539171420378717834">Desa una còpia d'aquesta targeta al dispositiu</translation>
<translation id="3542684924769048008">Utilitzar la contrasenya per a:</translation>
+<translation id="3545341443414427877">No es pot establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora de l'ordinador (<ph name="DATE_AND_TIME" />) no són correctes. <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Encripta totes les dades sincronitzades amb la teva frase de contrasenya de sincronització</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> més...</translation>
-<translation id="3555561725129903880">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" /> perquè el seu certificat de seguretat prové del domini <ph name="DOMAIN2" />. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">El teu gestor te'l pot desbloquejar</translation>
<translation id="3566021033012934673">La vostra connexió no és privada</translation>
+<translation id="3569145463236695319">&lt;p&gt;No es pot establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora del dispositiu (<ph name="DATE_AND_TIME" />) no són correctes.&lt;/p&gt;
+
+ &lt;p&gt;Canvia la data i l'hora a la secció &lt;strong&gt;General&lt;/strong&gt; de l'aplicació &lt;strong&gt;Configuració&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Afegeix el nom</translation>
<translation id="3583757800736429874">&amp;Refés el moviment</translation>
<translation id="3586931643579894722">Oculta els detalls</translation>
-<translation id="3587482841069643663">Tots</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Introdueix una data de caducitat vàlida</translation>
<translation id="36224234498066874">Esborra les dades de navegació</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informació del certificat</translation>
<translation id="3690164694835360974">L'inici de sessió no és segur</translation>
<translation id="3693415264595406141">Contrasenya:</translation>
-<translation id="3696411085566228381">cap</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">S'està carregant...</translation>
<translation id="3712624925041724820">Llicències exhaurides</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Comproveu el servidor intermediari, el tallafoc i la configuració de DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Si enteneu el risc que suposa per a la vostra seguretat, podeu <ph name="BEGIN_LINK" />visitar aquest lloc no segur<ph name="END_LINK" /> abans que no s'hagin suprimit els programes perillosos.</translation>
<translation id="3739623965217189342">Enllaç que heu copiat</translation>
+<translation id="3744899669254331632">En aquest moments no podeu visitar la pàgina <ph name="SITE" /> perquè el lloc web ha enviat credencials aleatòries que Chromium no pot processar. Els atacs i els errors de xarxa acostumen a ser temporals, o sigui que probablement la pàgina funcionarà més endavant.</translation>
+<translation id="3748148204939282805">Els atacants del lloc web <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> et poden enganyar perquè facis alguna acció perillosa, com ara instal·lar programari o revelar informació personal (per exemple, contrasenyes, números de telèfon o targetes de crèdit). <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">S'ha produït un error en el procés de traducció a causa d'un error del servidor.</translation>
<translation id="3759461132968374835">No heu informat de cap bloqueig recentment. Els bloquejos que es van produir mentre la creació d'informes de bloqueig estava desactivada no apareixeran aquí.</translation>
+<translation id="3778403066972421603">Vols desar aquesta targeta al teu compte de Google i en aquest dispositiu?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Data de caducitat: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Si feu servir un servidor intermediari...</translation>
<translation id="3828924085048779000">Les frases de contrasenya no poder estar buides.</translation>
-<translation id="3845539888601087042">Es mostra l'historial dels dispositius en què heu iniciat la sessió. <ph name="BEGIN_LINK" />Obteniu més informació<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Enrere</translation>
<translation id="3858027520442213535">Actualitza la data i l'hora</translation>
<translation id="3884278016824448484">L'identificador del dispositiu ja s'està utilitzant</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">La teva sol·licitud per accedir a aquest lloc s'ha enviat a <ph name="NAME" /></translation>
<translation id="3890664840433101773">Afegeix un correu electrònic</translation>
<translation id="3901925938762663762">La targeta ha caducat</translation>
-<translation id="3933571093587347751">{1,plural, =1{Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" /> perquè, suposadament, el seu certificat de seguretat té la data de demà. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.}other{Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" /> perquè, suposadament, el seu certificat de seguretat té una data que és d'aquí a # dies. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">No es pot carregar el document en format PDF</translation>
+<translation id="3945915738023014686">S'ha penjat l'identificador <ph name="CRASH_ID" /> de l'informe d'error (identificador d'error local: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" />, perquè el seu certificat de seguretat no especifica noms alternatius per a l'assumpte. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la connexió.</translation>
<translation id="3963721102035795474">Mode de lector</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Cap}=1{D'1 lloc }other{De # llocs }}</translation>
<translation id="397105322502079400">S’està calculant...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> està bloquejat</translation>
+<translation id="3987940399970879459">Menys d'1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{Hi ha 1 pàgina web a prop}other{Hi ha # pàgines web a prop}}</translation>
<translation id="4021036232240155012">DNS és el servei de xarxa que tradueix el nom d'un lloc web en l'adreça d'Internet corresponent.</translation>
<translation id="4030383055268325496">&amp;Desfés l'addició</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">La configuració del servidor intermediari s'ha definit perquè utilitzi un URL d'script .pac, en lloc de servidors intermedis fixos.</translation>
<translation id="4098354747657067197">Aquest lloc web és enganyós</translation>
<translation id="4103249731201008433">El número de sèrie del dispositiu no és vàlid</translation>
+<translation id="410351446219883937">Reproducció automàtica</translation>
<translation id="4103763322291513355">Visiteu &lt;strong&gt;chrome://policy&lt;/strong&gt; per veure la llista d'URL inclosos a la llista negra i altres polítiques aplicades per l'administrador del sistema.</translation>
-<translation id="4110615724604346410">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" /> perquè el seu certificat de seguretat conté errors. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Permet sempre en aquest lloc</translation>
<translation id="4117700440116928470">L'àmbit de la política no s'admet.</translation>
-<translation id="4118212371799607889">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" />. Chromium no confia en el certificat de seguretat presentat. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 element més}other{# elements més}}</translation>
<translation id="4130226655945681476">Comproveu els cables de xarxa, el mòdem i l'encaminador</translation>
+<translation id="413544239732274901">Més informació</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Utilitza el valor predeterminat global (detecta)</translation>
+<translation id="4165986682804962316">Configuració del lloc</translation>
<translation id="4169947484918424451">Voleu que Chromium desi aquesta targeta?</translation>
<translation id="4171400957073367226">La signatura de verificació és incorrecta</translation>
<translation id="4196861286325780578">&amp;Refés el moviment</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Comproveu la configuració del tallafoc i de l'antivirus<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{cap}=1{1 aplicació ($1)}=2{2 aplicacions ($1, $2)}other{# aplicacions ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Errors</translation>
+<translation id="422022731706691852">És possible que els atacants del lloc web <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> provin d'enganyar-te perquè instal·lis programes que poden perjudicar la teva experiència de navegació (per exemple, et poden canviar la pàgina d'inici o mostrar anuncis addicionals als llocs web que visitis). <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Proveu d'executar el Diagnòstic de xarxa<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Vàlid</translation>
<translation id="4250431568374086873">La teva connexió amb aquest lloc no és del tot segura</translation>
<translation id="4250680216510889253">No</translation>
<translation id="425582637250725228">És possible que els canvis que heu fet no es desin.</translation>
<translation id="4258748452823770588">Signatura errònia</translation>
+<translation id="4265872034478892965">Permès per l'administrador</translation>
<translation id="4269787794583293679">(Sense nom d'usuari)</translation>
<translation id="4275830172053184480">Reinici del dispositiu</translation>
<translation id="4280429058323657511">, caduca el dia <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Fa poc, la funció Navegació segura de Google <ph name="BEGIN_LINK" />ha trobat programes perjudicials<ph name="END_LINK" /> a <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Suggeriments per als responsables</translation>
<translation id="4304224509867189079">Accedeix</translation>
-<translation id="432290197980158659">El servidor ha presentat un certificat que no coincideix amb el que s'esperava. Aquestes expectatives es posen en pràctica en determinats llocs web d'alta seguretat per protegir-te. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Bloqueja (opció predeterminada)</translation>
<translation id="4325863107915753736">No s'ha pogut trobar l'article</translation>
<translation id="4326324639298822553">Comprova la data de caducitat i torna-ho a provar</translation>
<translation id="4331708818696583467">No segur</translation>
<translation id="4356973930735388585">Els atacants d'aquest lloc poden provar d'instal·lar programes perillosos a l'ordinador per robar o suprimir la teva informació (per exemple, les fotos, les contrasenyes, els missatges i les targetes de crèdit).</translation>
<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE" /> esperat.</translation>
+<translation id="4377125064752653719">Heu provat d'accedir a <ph name="DOMAIN" />, però l'emissor ha revocat el certificat que ha presentat el servidor. Això vol dir que no heu de confiar gens en les credencials de seguretat que ha presentat el servidor. És possible que us estigueu comunicant amb un atacant.</translation>
<translation id="4381091992796011497">Nom d'usuari:</translation>
<translation id="4394049700291259645">Desactiva</translation>
<translation id="4406896451731180161">resultats de la cerca</translation>
+<translation id="4424024547088906515">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè Chrome considera que el seu certificat de seguretat no és de confiança. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> no ha acceptat el certificat d'inici de sessió o pot ser que no se n'hagi proporcionat cap.</translation>
<translation id="443673843213245140">L'ús d'un servidor intermediari no està activat, però s'ha especificat una configuració explícita d'un servidor intermediari.</translation>
-<translation id="4492190037599258964">Resultats de la cerca per a "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Error de validació: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Contacteu amb l'administrador del sistema</translation>
<translation id="450710068430902550">Comparteix informació amb l'administrador</translation>
<translation id="4515275063822566619">Les targetes i les adreces s'obtenen de Chrome i del teu compte de Google (<ph name="ACCOUNT_EMAIL" />). Pots gestionar-les des de <ph name="BEGIN_LINK" />Configuració<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detalls</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Desactiveu les extensions</translation>
<translation id="457875822857220463">Entrega</translation>
<translation id="4587425331216688090">Voleu suprimir l'adreça de Chrome?</translation>
-<translation id="4589078953350245614">Has provat d'accedir a <ph name="DOMAIN" />, però el certificat que ha presentat el servidor no és vàlid. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">La connexió a <ph name="DOMAIN" /> s'ha encriptat amb un sistema de xifratge modern.</translation>
<translation id="4594403342090139922">&amp;Desfés la supressió</translation>
<translation id="4619615317237390068">Pestanyes d'altres dispositius</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">El servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè el seu certificat de seguretat conté errors. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
+<translation id="4690462567478992370">Deixa de fer servir un certificat no vàlid</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">La connexió s'ha interromput</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Executar el Diagnòstic de xarxa de Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">S'ha produït un error desconegut.</translation>
<translation id="4800132727771399293">Comproveu la data de caducitat i el CVC i torneu-ho a provar</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">En aquest moment no podeu visitar <ph name="SITE" /> perquè el lloc web ha enviat credencials aleatòries que Google Chrome no pot processar. Els errors i els atacs de xarxa solen ser temporals, de manera que és probable que aquesta pàgina torni a funcionar més tard.</translation>
<translation id="4813512666221746211">Error de xarxa</translation>
<translation id="4816492930507672669">Ajusta a la mida de la pàgina</translation>
<translation id="483020001682031208">No es pot mostrar cap pàgina del Web físic</translation>
<translation id="4850886885716139402">Mostra</translation>
<translation id="4854362297993841467">Aquest mètode d'entrega no està disponible. Prova'n un altre.</translation>
<translation id="4858792381671956233">Has demanat permís als teus pares per visitar aquest lloc</translation>
+<translation id="4863764087567530506">Aquest contingut pot provar d'enganyar-te perquè instal·lis programari o proporcionis informació personal. <ph name="BEGIN_LINK" />Mostra igualment<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Cerca a l'historial</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{i 1 pàgina web més}other{i # pàgines web més}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Aquesta pàgina s'ha traduït des d'un idioma desconegut a: <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pagament</translation>
<translation id="4926049483395192435">S'ha d'especificar.</translation>
<translation id="495170559598752135">Accions</translation>
<translation id="4958444002117714549">Desplega la llista</translation>
-<translation id="4962322354953122629">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" />. Chrome no confia en el certificat de seguretat presentat. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Torna a activar els advertiments</translation>
<translation id="4989809363548539747">Aquest connector no és compatible</translation>
<translation id="5002932099480077015">Si s'activa, Chrome emmagatzemarà una còpia de la targeta en aquest dispositiu per agilitzar l'emplenament de formularis.</translation>
<translation id="5018422839182700155">No es pot obrir aquesta pàgina</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Consulteu les polítiques de l'administrador</translation>
<translation id="5029568752722684782">Esborra la còpia</translation>
<translation id="5031870354684148875">Sobre el Traductor de Google</translation>
+<translation id="5039804452771397117">Permet</translation>
<translation id="5040262127954254034">Privadesa</translation>
<translation id="5045550434625856497">Contrasenya incorrecta</translation>
<translation id="5056549851600133418">Articles que us poden interessar</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Comproveu l'adreça del servidor intermediari<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{No s'utilitzen galetes}=1{1 lloc utilitza galetes. }other{# llocs utilitzen galetes. }}</translation>
<translation id="5087286274860437796">En aquest moment el certificat del servidor no és vàlid.</translation>
<translation id="5087580092889165836">Afegiu una targeta</translation>
<translation id="5089810972385038852">Estat</translation>
+<translation id="5094747076828555589">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè Chromium considera que el seu certificat de seguretat no és de confiança. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
<translation id="5095208057601539847">Província</translation>
<translation id="5115563688576182185">(64 bits)</translation>
<translation id="5141240743006678641">Encripta contrasenyes sincronitzades amb les vostres credencials de Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">El correu electrònic és obligatori</translation>
<translation id="5251803541071282808">Núvol</translation>
<translation id="5277279256032773186">Fas servir Chrome a la feina? Les empreses poden gestionar la configuració de Chrome dels empleats. Més informació</translation>
+<translation id="5297526204711817721">La teva connexió amb aquest lloc no és privada. Per sortir del mode RV en qualsevol moment, treu-te el visor i prem Enrere.</translation>
<translation id="5299298092464848405">S'ha produït un error en analitzar la política</translation>
-<translation id="5300589172476337783">Mostra</translation>
<translation id="5308689395849655368">La creació d'informes de bloqueig està desactivada.</translation>
<translation id="5317780077021120954">Desa</translation>
<translation id="5327248766486351172">Nom</translation>
-<translation id="5337705430875057403">Els atacants de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> us poden enganyar perquè feu alguna acció perillosa, com ara instal·lar programari o revelar informació personal (per exemple, contrasenyes, números de telèfon o targetes de crèdit).</translation>
-<translation id="5359637492792381994">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" /> perquè el seu certificat de seguretat no és vàlid en aquest moment. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">En aquest moment no pots visitar <ph name="SITE" /> perquè se li ha revocat el certificat. Els atacs i els errors de xarxa acostumen a ser temporals, o sigui que probablement la pàgina funcionarà més endavant.</translation>
<translation id="536296301121032821">No s'ha pogut emmagatzemar la configuració de la política</translation>
<translation id="5386426401304769735">La cadena de certificats d'aquest lloc conté un certificat que s'ha signat amb SHA-1.</translation>
<translation id="5402410679244714488">Data de caducitat: <ph name="EXPIRATION_DATE_ABBR" />, última utilització fa més d'un any</translation>
+<translation id="540969355065856584">Aquest servidor no ha pogut demostrar que sigui <ph name="DOMAIN" /> perquè el seu certificat de seguretat no és vàlid en aquest moment. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la connexió.</translation>
<translation id="5421136146218899937">Esborra les dades de navegació...</translation>
<translation id="5430298929874300616">Suprimeix l'adreça d'interès</translation>
<translation id="5431657950005405462">No s'ha trobat el fitxer</translation>
-<translation id="5435775191620395718">Es mostra l'historial d'aquest dispositiu. <ph name="BEGIN_LINK" />Obteniu més informació<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Error de validació de l'esquema a "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">No s'ha trobat aquesta pàgina de <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">Marca de temps de la política incorrecta</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> de <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">No vàlides</translation>
<translation id="5470861586879999274">&amp;Refés la modificació</translation>
<translation id="54817484435770891">Afegeix una adreça vàlida</translation>
<translation id="5492298309214877701">Aquest lloc de la intranet de l'empresa, l'organització o el centre educatiu té el mateix URL que un lloc web extern.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">No es pot fer la recollida en aquesta adreça. Selecciona'n una altra.</translation>
<translation id="5572851009514199876">Obre Chrome i inicia-hi la sessió perquè Chrome pugui comprovar si tens permís per accedir a aquest lloc.</translation>
<translation id="5580958916614886209">Comprova el mes de caducitat i torna-ho a provar</translation>
+<translation id="5586446728396275693">No hi ha cap adreça desada</translation>
+<translation id="5595485650161345191">Edita l'adreça</translation>
<translation id="560412284261940334">Gestió no compatible</translation>
<translation id="5610142619324316209">Comproveu la connexió</translation>
<translation id="5610807607761827392">Pots gestionar les targetes i les adreces a <ph name="BEGIN_LINK" />Configuració<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Voleu sortir d'aquest lloc?</translation>
<translation id="5629630648637658800">No s'ha pogut carregar la configuració de la política</translation>
<translation id="5631439013527180824">Testimoni de gestió del dispositiu no vàlid</translation>
+<translation id="5633066919399395251">És possible que els atacants del lloc web <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> provin d'instal·lar programes perillosos a l'ordinador per robar o suprimir la teva informació (per exemple, les fotos, les contrasenyes, els missatges i les targetes de crèdit). <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Ubicació</translation>
+<translation id="5659593005791499971">Correu electrònic</translation>
<translation id="5669703222995421982">Obtén contingut personalitzat</translation>
<translation id="5675650730144413517">Aquesta pàgina no funciona</translation>
-<translation id="5677928146339483299">Bloquejades</translation>
-<translation id="5694783966845939798">Has provat d'accedir a <ph name="DOMAIN" />, però el servidor ha proporcionat un certificat signat mitjançant un algoritme de signatura poc segur (com ara SHA-1). Això indica que les credencials de seguretat que ha proporcionat el servidor es podrien haver falsificat i que és possible que el servidor no sigui el que esperaves (sinó un atacant). <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">La identitat d'aquest lloc web no ha estat verificada.</translation>
+<translation id="5713016350996637505">Contingut enganyós bloquejat</translation>
<translation id="5720705177508910913">Usuari actual</translation>
<translation id="5732392974455271431">Els teus pares te'l poden desbloquejar</translation>
<translation id="5763042198335101085">Introdueix una adreça electrònica vàlida</translation>
<translation id="5765072501007116331">Per veure els mètodes i els requisits d'entrega, selecciona una adreça</translation>
+<translation id="5778550464785688721">Control total dels dispositius MIDI</translation>
<translation id="5784606427469807560">S'ha produït un problema en confirmar la targeta. Comprova la connexió a Internet i torna-ho a provar.</translation>
<translation id="5785756445106461925">A més, aquesta pàgina conté altres recursos que no són segurs. La resta d'usuaris poden visualitzar-los mentre estan en trànsit, i algun atacant podria modificar-los per canviar l'aparença de la pàgina.</translation>
<translation id="5786044859038896871">Vols emplenar la informació de la teva targeta?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Refés l'addició</translation>
<translation id="5814352347845180253">Pot ser que perdis l'accés al contingut prèmium de <ph name="SITE" /> i d'altres llocs.</translation>
<translation id="5838278095973806738">No introdueixis informació confidencial en aquest lloc (com ara contrasenyes o targetes de crèdit), ja que alguns atacants podrien robar-la.</translation>
-<translation id="5843436854350372569">Has provat d'accedir a <ph name="DOMAIN" />, però el servidor ha presentat un certificat que conté una clau poc segura. És possible que un atacant hagi desencriptat la clau privada i que aquest servidor no sigui el que esperaves (sinó un atacant). <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">No es pot accedir a aquest lloc</translation>
<translation id="5869522115854928033">Contrasenyes desades</translation>
<translation id="5872918882028971132">Suggeriments per als responsables</translation>
<translation id="5901630391730855834">Groc</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (informació sincronitzada)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 en ús}other{# en ús}}</translation>
<translation id="5926846154125914413">Pot ser que perdis l'accés al contingut prèmium d'alguns llocs.</translation>
<translation id="5959728338436674663">Envia automàticament algunes <ph name="BEGIN_WHITEPAPER_LINK" />dades del sistema i contingut de les pàgines<ph name="END_WHITEPAPER_LINK" /> a Google per ajudar a detectar les aplicacions i els llocs perillosos. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Setmana</translation>
<translation id="5967867314010545767">Elimina de l'historial</translation>
<translation id="5975083100439434680">Redueix</translation>
<translation id="598637245381783098">No es pot obrir l'aplicació de pagament</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Pàgina 1}other{Pàgina #}}</translation>
<translation id="6017514345406065928">Verd</translation>
+<translation id="6017850046339264347">Pot ser que els atacants que es troben a <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> instal·lin aplicacions enganyoses que es facin passar per qui no són o recopilin dades que podrien utilitzar-se per fer un seguiment de la teva activitat. <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (informació sincronitzada)</translation>
<translation id="6027201098523975773">Escriu un nom</translation>
<translation id="6040143037577758943">Tanca</translation>
<translation id="6042308850641462728">Més</translation>
+<translation id="6047233362582046994">Si entens el risc que suposa per a la teva seguretat, pots <ph name="BEGIN_LINK" />visitar aquest lloc web<ph name="END_LINK" /> abans que no s'hagin suprimit les aplicacions perjudicials.</translation>
+<translation id="6051221802930200923">En aquests moments no pots visitar <ph name="SITE" /> perquè el lloc web fa servir una fixació de certificat. Els atacs i els errors de xarxa acostumen a ser temporals, o sigui que probablement la pàgina funcionarà més endavant.</translation>
<translation id="6060685159320643512">Compte! Aquests experiments mosseguen</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{cap}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Heu accedit a contingut mitjançant un certificat proporcionat per l'administrador. Per tant, l'administrador por interceptar les dades que proporcioneu a <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Cap}=1{1 contrasenya (sincronitzada)}other{# contrasenyes (sincronitzades)}}</translation>
<translation id="6146055958333702838">Reviseu els cables i reinicieu els encaminadors, els mòdems o altres
dispositius de xarxa que feu servir.</translation>
<translation id="614940544461990577">Proveu aquestes solucions:</translation>
<translation id="6151417162996330722">El període de validesa del certificat del servidor és massa gran.</translation>
<translation id="6157877588268064908">Per veure els mètodes i els requisits d'enviament, selecciona una adreça</translation>
+<translation id="6158003235852588289">Navegació segura de Google ha detectat recentment activitat de pesca a <ph name="SITE" />. Els llocs web de pesca es fan passar per altres llocs web per enganyar-te.</translation>
<translation id="6165508094623778733">Més informació</translation>
+<translation id="6169916984152623906">Ara pots navegar de manera privada i les altres persones que utilitzin aquest dispositiu no veuran la teva activitat. Tanmateix, les baixades i les adreces d'interès sí que es desaran.</translation>
<translation id="6177128806592000436">La teva connexió amb aquest lloc no és segura</translation>
<translation id="6184817833369986695">(cohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Comprovació de la connexió a Internet</translation>
<translation id="6218753634732582820">Voleu suprimir l'adreça de Chromium?</translation>
+<translation id="6221345481584921695">Navegació segura de Google ha <ph name="BEGIN_LINK" />detectat programari maliciós<ph name="END_LINK" /> recentment a <ph name="SITE" />. De vegades, els llocs web que acostumen a ser segurs s'infecten amb programari maliciós. El contingut maliciós prové de l'amfitrió <ph name="SUBRESOURCE_HOST" />, un distribuïdor conegut de programari maliciós.</translation>
<translation id="6251924700383757765">Política de privadesa</translation>
<translation id="6254436959401408446">No hi ha prou memòria per obrir aquesta pàgina</translation>
<translation id="625755898061068298">Has decidit desactivar els advertiments de seguretat en aquest lloc.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Edita l'adreça d'interès</translation>
<translation id="6410264514553301377">Introdueix la data de caducitat i el CVC de la targeta <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Has demanat permís als teus pares per visitar aquest lloc</translation>
-<translation id="6416403317709441254">En aquest moment no pots visitar <ph name="SITE" /> perquè el lloc web ha enviat credencials aleatòries que Chromium no pot processar. Els errors i els atacs de xarxa solen ser temporals, de manera que és probable que aquesta pàgina torni a funcionar més tard. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">No es pot comprovar si s'ha revocat el certificat.</translation>
<translation id="6433490469411711332">Edita la informació de contacte</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> no ens ha permès establir la connexió.</translation>
<translation id="6446608382365791566">Afegeix més informació</translation>
+<translation id="6447842834002726250">Galetes</translation>
<translation id="6451458296329894277">Confirma el reenviament del formulari</translation>
<translation id="6456339708790392414">El teu pagament</translation>
<translation id="6458467102616083041">S'ha ignorat perquè la política ha desactivat la cerca predeterminada.</translation>
-<translation id="6462969404041126431">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" />. És possible que el seu certificat de seguretat s'hagi revocat. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Polítiques de dispositius</translation>
<translation id="6477321094435799029">Chrome ha detectat codi poc comú en aquesta pàgina i, per tant, l'ha bloquejat per protegir la teva informació personal (per exemple, contrasenyes, números de telèfon i targetes de crèdit).</translation>
<translation id="6489534406876378309">Comença a penjar els errors</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Data de caducitat: <ph name="EXPIRATION_DATE_ABBR" />; última utilització: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">El teu gestor encara no ho ha aprovat</translation>
<translation id="6569060085658103619">Estàs consultant la pàgina d'una extensió</translation>
-<translation id="6593753688552673085">menys de: <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Aquest contingut pot provar d'instal·lar programari maliciós al teu dispositiu per suprimir-ne informació o robar-te'n. <ph name="BEGIN_LINK" />Mostra igualment<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opcions d'encriptació</translation>
<translation id="662080504995468778">No surtis</translation>
<translation id="6626291197371920147">Afegeix un número de targeta vàlid</translation>
<translation id="6628463337424475685">Cerca de <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">És possible que els atacants que es troben a <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> provin d'instal·lar programes perillosos a l'ordinador Mac per robar-te o suprimir-te informació (per exemple, fotos, contrasenyes, missatges i targetes de crèdit). <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Aquesta política ha quedat obsoleta.</translation>
-<translation id="6652240803263749613">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" />. El sistema operatiu del teu ordinador no confia en el certificat de seguretat presentat. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Voleu suprimir el suggeriment de formulari de Chromium?</translation>
<translation id="6685834062052613830">Tanqueu la sessió i completeu la configuració</translation>
<translation id="6710213216561001401">Anterior</translation>
<translation id="6710594484020273272">&lt;Escriviu el terme de cerca&gt;</translation>
<translation id="6711464428925977395">Hi ha hagut algun problema amb el servidor intermediari o l'adreça no és correcta.</translation>
<translation id="6727102863431372879">Configura</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{cap}=1{1 element}other{# elements}}</translation>
<translation id="674375294223700098">Error de certificat del servidor desconegut.</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6757797048963528358">El dispositiu ha entrat en mode de repòs.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Identificador de personalització</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">No s'han pogut carregar les dades de la regió</translation>
+<translation id="6825578344716086703">Has provat d'accedir a <ph name="DOMAIN" />, però el servidor ha presentat un certificat signat mitjançant un algoritme de signatura dèbil (com ara SHA-1). Això indica que les credencials de seguretat que ha presentat el servidor podrien haver estat falsificades i que pot ser que el servidor no sigui el que esperaves (és possible que t'estiguis comunicant amb un atacant).</translation>
+<translation id="6830728435402077660">No segura</translation>
<translation id="6831043979455480757">Tradueix</translation>
<translation id="6839929833149231406">Àrea</translation>
<translation id="6874604403660855544">&amp;Refés l'addició</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">La teva targeta s'ha confirmat</translation>
<translation id="6897140037006041989">Agent d'usuari</translation>
<translation id="6915804003454593391">Usuari:</translation>
+<translation id="6945221475159498467">Selecciona</translation>
<translation id="6948701128805548767">Per veure els mètodes i els requisits de recollida, selecciona una adreça</translation>
<translation id="6957887021205513506">Sembla que el certificat del servidor és una falsificació.</translation>
<translation id="6965382102122355670">D'acord</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">S'especifiquen tant els servidors intermediaris fixos com un URL d'script .pac.</translation>
<translation id="6989763994942163495">Mostra la configuració avançada...</translation>
<translation id="7000990526846637657">No s'ha trobat cap entrada a l'historial</translation>
-<translation id="7009986207543992532">Has provat d'accedir a <ph name="DOMAIN" />, però el servidor ha presentat un certificat amb un període de validesa massa llarg per poder confiar-hi. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">És possible que el teu compte de Google tingui altres formes de l'historial de navegació a <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Contrasenyes</translation>
+<translation id="7050187094878475250">Heu provat de connectar-vos a <ph name="DOMAIN" />, però el servidor ha presentat un certificat amb un període de validesa massa gran per poder confiar-hi.</translation>
+<translation id="7053983685419859001">Bloqueja</translation>
<translation id="7064851114919012435">Informació de contacte</translation>
<translation id="7079718277001814089">Aquest lloc conté programari maliciós</translation>
<translation id="7087282848513945231">Comptat</translation>
-<translation id="7088615885725309056">Més antic</translation>
<translation id="7090678807593890770">Cerqueu <ph name="LINK" /> a Google</translation>
+<translation id="7108819624672055576">Permès per una extensió</translation>
<translation id="7119414471315195487">Tanca altres pestanyes o programes</translation>
<translation id="7129409597930077180">No es pot enviar a aquesta adreça. Selecciona'n una altra.</translation>
<translation id="7138472120740807366">Mètode d'entrega</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">S'està processant</translation>
<translation id="724691107663265825">Aquest lloc conté programari maliciós</translation>
<translation id="724975217298816891">Introdueix la data de caducitat i el CVC de la targeta <ph name="CREDIT_CARD" /> per actualitzar-ne els detalls. Un cop confirmada, els detalls de la targeta es compartiran amb aquest lloc.</translation>
-<translation id="725866823122871198">No s'ha pogut establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora (<ph name="DATE_AND_TIME" />) de l'ordinador no són correctes.</translation>
+<translation id="7260504762447901703">Revoca l'accés</translation>
<translation id="7275334191706090484">Adreces d'interès gestionades</translation>
<translation id="7298195798382681320">Recomanada</translation>
<translation id="7309308571273880165">S'ha capturat un informe d'error (<ph name="CRASH_TIME" />) (càrrega sol·licitada per l'usuari, encara no s'ha dut a terme)</translation>
<translation id="7334320624316649418">&amp;Refés el canvi d'ordre</translation>
<translation id="733923710415886693">El certificat del servidor no s'ha divulgat mitjançant la Transparència de certificats.</translation>
-<translation id="7351800657706554155">En aquest moment no pots visitar <ph name="SITE" /> perquè el seu certificat s'ha revocat. Els errors i els atacs de xarxa solen ser temporals, de manera que és probable que aquesta pàgina torni a funcionar més tard. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Línia d'ordres</translation>
<translation id="7372973238305370288">resultat de la cerca</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">No</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Confirma la targeta</translation>
-<translation id="7394102162464064926">Confirmes que vols suprimir aquestes pàgines de l'historial?
-
-El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la propera vegada.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Camí del perfil</translation>
<translation id="7424977062513257142">Una pàgina inserida en aquesta pàgina web diu:</translation>
@@ -688,6 +754,7 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="7444046173054089907">Aquest lloc està bloquejat</translation>
<translation id="7445762425076701745">La identitat del servidor al qual esteu connectat no es pot acabar de validar. Esteu connectat a un servidor que utilitza un nom que només és vàlid dins la vostra xarxa, de manera que una autoritat de certificació externa no en pot validar la propietat. Com que de tota manera algunes autoritats de certificació emetran certificats per a aquests noms, no es pot assegurar que estigueu connectat al lloc web previst i no a un atacant.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Obtenir més informació<ph name="END_LINK" /> sobre aquest problema</translation>
+<translation id="7455133967321480974">Utilitza l'opció predeterminada global (Bloqueja)</translation>
<translation id="7460163899615895653">Les teves pestanyes recents d'altres dispositius es mostraran aquí</translation>
<translation id="7469372306589899959">S'està confirmant la targeta</translation>
<translation id="7481312909269577407">Endavant</translation>
@@ -695,36 +762,43 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="7508255263130623398">L'identificador de dispositiu de la política que s'ha tornat és buit o no coincideix amb l'actual</translation>
<translation id="7514365320538308">Baixa</translation>
<translation id="7518003948725431193">No s'ha trobat cap pàgina web per a l'adreça: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obligatòria</translation>
+<translation id="7542403920425041731">Un cop confirmada, els detalls de la targeta es compartiran amb aquest lloc web.</translation>
<translation id="7542995811387359312">L'emplenament automàtic de targetes de crèdit està desactivat perquè el formulari no utilitza una connexió segura.</translation>
<translation id="7543525346216957623">Demana-ho al teu pare o a la teva mare</translation>
<translation id="7549584377607005141">Aquesta pàgina web necessita dades que heu introduït anteiorment per poder mostrar-la correctament. Podeu tornar a enviar les dades, però es tornarà a repetir qualsevol acció que la pàgina hagi dut a terme prèviament.</translation>
<translation id="7552846755917812628">Prova els consells següents:</translation>
<translation id="7554791636758816595">Pestanya nova</translation>
+<translation id="7567204685887185387">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè és possible que el seu certificat de seguretat s'hagi emès de manera fraudulenta. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> més}other{<ph name="CONTACT_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> més}}</translation>
<translation id="7568593326407688803">Aquesta pàgina està en<ph name="ORIGINAL_LANGUAGE" />Voleu traduir-la?</translation>
<translation id="7569952961197462199">Voleu suprimir la targeta de crèdit de Chrome?</translation>
<translation id="7569983096843329377">Negre</translation>
<translation id="7578104083680115302">Agilitzeu els pagaments en llocs i en aplicacions des de qualsevol dispositiu mitjançant les targetes que hàgiu desat a Google.</translation>
<translation id="7588950540487816470">El Web físic</translation>
<translation id="7592362899630581445">El certificat del servidor incompleix les restriccions de nom.</translation>
+<translation id="7598391785903975535">Menys de: <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> no pot gestionar la sol·licitud en aquest moment.</translation>
<translation id="7600965453749440009">No tradueixis mai de: <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">El valor es troba fora de l'interval <ph name="VALUE" /> .</translation>
<translation id="7613889955535752492">Data de caducitat: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Ja teniu dades encriptades amb una versió diferent de la contrasenya del vostre compte de Google. Introduïu-la a continuació.</translation>
-<translation id="7634554953375732414">La vostra connexió amb aquest lloc no és privada.</translation>
<translation id="7637571805876720304">Voleu suprimir la targeta de crèdit de Chromium?</translation>
<translation id="765676359832457558">Amaga la configuració avançada...</translation>
<translation id="7658239707568436148">Cancel·la</translation>
+<translation id="7662298039739062396">Configuració controlada per una extensió</translation>
<translation id="7667346355482952095">El testimoni de la política que s'ha retornat és buit o no coincideix amb el testimoni actual</translation>
<translation id="7668654391829183341">Dispositiu desconegut</translation>
<translation id="7669271284792375604">És possible que els atacants d'aquest lloc intentin enganyar-te perquè instal·lis programes que perjudiquen la teva navegació (per exemple, et poden canviar la pàgina d'inici o mostrar anuncis addicionals als llocs que visites).</translation>
<translation id="7674629440242451245">Esteu interessat en les funcions de Chrome noves i interessants? Proveu el nostre canal per a desenvolupadors a la pàgina chrome.com/dev.</translation>
<translation id="7682287625158474539">Enviament</translation>
+<translation id="7701040980221191251">Cap</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Continua per accedir a <ph name="SITE" /> (no segur)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificat</translation>
+<translation id="7716147886133743102">Bloquejat per l'administrador</translation>
<translation id="7716424297397655342">Aquest lloc no es pot carregar des de la memòria cau</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Sense gestionar</translation>
<translation id="7755287808199759310">El teu pare o la teva mare et poden desbloquejar el lloc</translation>
<translation id="7758069387465995638">És possible que l'antivirus o el tallafoc hagi bloquejat la connexió.</translation>
@@ -751,15 +825,15 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="7951415247503192394">(32 bits)</translation>
<translation id="7956713633345437162">Adreces d'interès per a mòbils</translation>
<translation id="7961015016161918242">Mai</translation>
-<translation id="7962083544045318153">Identificador d'error <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Tradueix sempre de: <ph name="ORIGINAL_LANGUAGE" /> a: <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">No especificat</translation>
<translation id="800218591365569300">Prova de tancar altres pestanyes o programes per alliberar memòria.</translation>
<translation id="8012647001091218357">En aquests moments no ens hem pogut posar en contacte amb els pares. Torneu-ho a provar.</translation>
<translation id="8025119109950072390">Els atacants d'aquest lloc et poden enganyar perquè facis alguna acció perillosa, com ara instal·lar programari o revelar informació personal (per exemple, contrasenyes, números de telèfon o targetes de crèdit).</translation>
-<translation id="803030522067524905">Fa poc, la funció Navegació segura de Google ha detectat activitat de pesca (suplantació d'identitat) a <ph name="SITE" />. Els llocs de pesca es fan passar per altres llocs web per enganyar-te. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Aquesta pàgina està escrita en <ph name="SOURCE_LANGUAGE" />. Vols traduir-la a <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Pregunta (opció predeterminada)</translation>
<translation id="8041089156583427627">Envia comentaris</translation>
+<translation id="8041940743680923270">Utilitza l'opció predeterminada global (Pregunta)</translation>
<translation id="8088680233425245692">No s'ha pogut consultar l'article.</translation>
<translation id="8089520772729574115">menys d'1 MB</translation>
<translation id="8091372947890762290">L'activació està pendent al servidor</translation>
@@ -768,13 +842,14 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="8134994873729925007">No s'ha trobat l'<ph name="BEGIN_ABBR" />adreça DNS<ph name="END_ABBR" /> del servidor de <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">L'ordinador ha entrat en mode de repòs.</translation>
<translation id="8150722005171944719">El fitxer de <ph name="URL" /> no es pot llegir. Pot ser que s'hagi eliminat, que s'hagi traslladat o que els permisos del fitxer n'impedeixin l'accés.</translation>
+<translation id="8184538546369750125">Utilitza l'opció predeterminada global (Permet)</translation>
+<translation id="8191494405820426728">Identificador de l'error local: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Desfés el moviment</translation>
<translation id="8201077131113104583">L'URL d'actualització per a l'extensió amb identificador "<ph name="EXTENSION_ID" />" no és vàlid.</translation>
<translation id="8202097416529803614">Resum de la comanda</translation>
<translation id="8218327578424803826">Ubicació assignada:</translation>
<translation id="8225771182978767009">La persona que ha configurat l'ordinador ha bloquejat aquest lloc.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Els atacants que actualment són al lloc <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> poden provar d'instal·lar programes perillosos a l'ordinador per robar o suprimir la teva informació (per exemple, les fotos, les contrasenyes, els missatges i les targetes de crèdit).</translation>
<translation id="8241707690549784388">La pàgina que busques utilitzava informació que vas introduir. Tornar a aquesta pàgina podria provocar una repetició de qualsevol acció realitzada. Vols continuar?</translation>
<translation id="8249320324621329438">Última obtenció:</translation>
<translation id="8253091569723639551">Cal indicar l'adreça de facturació</translation>
@@ -782,6 +857,7 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="8289355894181816810">Si no esteu segur de què significa això, contacteu amb l'administrador de la xarxa.</translation>
<translation id="8293206222192510085">Afegeix una adreça d'interès</translation>
<translation id="8294431847097064396">Font</translation>
+<translation id="8306404619377842860">No es pot establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora del dispositiu (<ph name="DATE_AND_TIME" />) no són correctes. <ph name="BEGIN_LEARN_MORE_LINK" />Més informació<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">No s'ha pogut executar la traducció a causa d'un problema amb la connexió de xarxa.</translation>
<translation id="8332188693563227489">S'ha rebutjat l'accés a <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Si enteneu el risc que suposa per a la vostra seguretat, podeu <ph name="BEGIN_LINK" />visitar aquest lloc<ph name="END_LINK" /> abans que no s'hagin suprimit els programes perjudicials.</translation>
@@ -802,11 +878,9 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="8483780878231876732">Per poder utilitzar targetes del teu compte de Google, inicia la sessió a Chrome</translation>
<translation id="8488350697529856933">Objectiu d'aplicació</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ha tardat massa a respondre.</translation>
-<translation id="852346902619691059">Aquest servidor no ha pogut demostrar que és <ph name="DOMAIN" />. El sistema operatiu del teu dispositiu no confia en el certificat de seguretat presentat. Això pot ser a causa d'una configuració incorrecta o d'un atacant que ha interceptat la teva connexió. <ph name="BEGIN_LEARN_MORE_LINK" />Obtén més informació<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Any de caducitat</translation>
<translation id="8543181531796978784">Podeu <ph name="BEGIN_ERROR_LINK" />informar d'un problema de detecció<ph name="END_ERROR_LINK" /> o, si enteneu els riscos que això comporta per a la vostra seguretat, <ph name="BEGIN_LINK" />visiteu aquest lloc no segur<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">S'ha produït un error en fer la traducció perquè no s'ha pogut determinar l'idioma de la pàgina.</translation>
-<translation id="8559762987265718583">No es pot establir una connexió privada amb <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perquè la data i l'hora (<ph name="DATE_AND_TIME" />) del dispositiu són incorrectes.</translation>
<translation id="8571890674111243710">S'està traduint la pàgina a l'idioma <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Afegeix un número de telèfon</translation>
<translation id="859285277496340001">El certificat no especifica un mecanisme per comprovar si s'ha revocat.</translation>
@@ -820,6 +894,7 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="8738058698779197622">Per establir una connexió segura, el rellotge ha d'estar ben ajustat, perquè els certificats que els llocs web fan servir per identificar-se només són vàlids per a períodes de temps concrets. Com que el rellotge del dispositiu no està ben ajustat, Chromium no pot verificar aquests certificats.</translation>
<translation id="8740359287975076522">No s'ha trobat l'&lt;abbr id="dnsDefinition"&gt;adreça DNS&lt;/abbr&gt; de <ph name="HOST_NAME" />. S'està diagnosticant el problema.</translation>
<translation id="8759274551635299824">Aquesta targeta ha caducat</translation>
+<translation id="8761567432415473239">Recentment, amb Navegació segura de Google s'han <ph name="BEGIN_LINK" />detectat programes perjudicials<ph name="END_LINK" /> al lloc <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Refés la supressió</translation>
<translation id="8800988563907321413">Els suggeriments més propers es mostren aquí</translation>
<translation id="8820817407110198400">Adreces d'interès</translation>
@@ -832,29 +907,30 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="8870413625673593573">Tancades recentment</translation>
<translation id="8874824191258364635">Introdueix un número de targeta vàlid</translation>
<translation id="8876793034577346603">No s'ha pogut analitzar la configuració de la xarxa.</translation>
-<translation id="8877192140621905067">Un cop confirmada, els detalls de la targeta es compartiran amb aquest lloc</translation>
<translation id="8889402386540077796">To</translation>
<translation id="8891727572606052622">El mode de servidor intermediari no és vàlid.</translation>
<translation id="889901481107108152">Aquest experiment no està disponible a la vostra plataforma.</translation>
<translation id="8903921497873541725">Amplia</translation>
<translation id="8931333241327730545">Voleu desar aquesta targeta al vostre compte de Google?</translation>
<translation id="8932102934695377596">El rellotge està endarrerit</translation>
-<translation id="8954894007019320973">(Cont.)</translation>
<translation id="8971063699422889582">El certificat del servidor ha caducat.</translation>
<translation id="8986494364107987395">Envia automàticament estadístiques d'ús i informes d'error a Google</translation>
-<translation id="8987927404178983737">Mes</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Aquest lloc conté programes perjudicials</translation>
+<translation id="8997023839087525404">El servidor ha presentat un certificat que no s'ha divulgat públicament mitjançant la política Transparència de certificats. Això és un requisit d'alguns certificats per garantir que són de confiança i una mesura de protecció contra els atacants.</translation>
<translation id="9001074447101275817">El servidor intermediari del domini <ph name="DOMAIN" /> requereix un nom d'usuari i una contrasenya.</translation>
+<translation id="9005998258318286617">No es pot carregar el document PDF.</translation>
<translation id="901974403500617787">Les marques que s'apliquen a tot el sistema només les pot definir l'usuari: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Es requereix l'adreça de facturació de la targeta</translation>
<translation id="9020542370529661692">Aquesta pàgina s'ha traduït a <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Error de seguretat</translation>
<translation id="9038649477754266430">Utilitza un servei de predicció per poder carregar les pàgines més ràpidament</translation>
<translation id="9039213469156557790">A més, aquesta pàgina conté altres recursos que no són segurs. La resta d'usuaris poden visualitzar-los mentre estan en trànsit, i algun atacant podria modificar-los per canviar el comportament de la pàgina.</translation>
-<translation id="9040185888511745258">És possible que els atacants del lloc <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> provin d'enganyar-vos perquè instal·leu programes que poden perjudicar la vostra experiència de navegació (per exemple, us poden canviar la pàgina d'inici o mostrar anuncis addicionals als llocs que visiteu).</translation>
+<translation id="9049981332609050619">Heu provat d'accedir a <ph name="DOMAIN" />, però el servidor ha presentat un certificat no vàlid.</translation>
<translation id="9050666287014529139">Frase de contrasenya</translation>
<translation id="9065203028668620118">Edita</translation>
<translation id="9068849894565669697">Selecció de color</translation>
+<translation id="9069693763241529744">Bloquejat per una extensió</translation>
<translation id="9076283476770535406">Pot incloure contingut per a adults</translation>
<translation id="9078964945751709336">Necessitem més informació</translation>
<translation id="9103872766612412690"><ph name="SITE" /> utilitza normalment l'encriptació per protegir la vostra informació. En aquesta ocasió, quan Chromium ha provat de connectar-se a <ph name="SITE" />, el lloc web ha enviat credencials poc comunes i incorrectes. Pot ser que un atacant estigui provant de fer-se passar per <ph name="SITE" /> o que una pantalla d'inici de sessió a la xarxa Wi-Fi hagi interromput la connexió. En qualsevol cas, la vostra informació continua estant segura, perquè Chromium ha aturat la connexió abans no s'intercanviés cap dada.</translation>
@@ -863,16 +939,21 @@ El mode d'incògnit, <ph name="SHORTCUT_KEY" />, us pot resultar pràctic la pro
<translation id="9148507642005240123">&amp;Desfés la modificació</translation>
<translation id="9154194610265714752">S'ha actualitzat.</translation>
<translation id="9157595877708044936">S'està configurant...</translation>
+<translation id="9169664750068251925">Bloqueja sempre en aquest lloc</translation>
<translation id="9170848237812810038">&amp;Desfés</translation>
<translation id="917450738466192189">El certificat del servidor no és vàlid.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> més}other{<ph name="SHIPPING_OPTION_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> més}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> fa servir un protocol no admès.</translation>
<translation id="9205078245616868884">Les vostres dades estan encriptades amb la vostra frase de contrasenya de sincronització. Introduïu-la per començar la sincronització.</translation>
<translation id="9207861905230894330">No s'ha pogut afegir l'article.</translation>
+<translation id="9219103736887031265">Imatges</translation>
<translation id="933612690413056017">No hi ha connexió a Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ESBORRA EL FORMULARI</translation>
<translation id="939736085109172342">Carpeta nova</translation>
<translation id="941721044073577244">Sembla que no tens permís per visitar aquest lloc</translation>
<translation id="969892804517981540">Muntatge oficial</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Cap}=1{1 element}other{# elements}}</translation>
<translation id="988159990683914416">Muntatge del desenvolupador</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_cs.xtb b/chromium/components/strings/components_strings_cs.xtb
index e7b47222fb0..04fd935ffdf 100644
--- a/chromium/components/strings/components_strings_cs.xtb
+++ b/chromium/components/strings/components_strings_cs.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">OtoÄit ve smÄ›ru hodinových ruÄiÄek</translation>
<translation id="1038842779957582377">neznámé jméno</translation>
<translation id="1050038467049342496">Zavřete ostatní aplikace</translation>
-<translation id="1053591932240354961">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože webové stránky odeslaly zakódované identifikaÄní údaje, které Chrome nedokáže zpracovat. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;Vrátit přidání zpět</translation>
<translation id="10614374240317010">Nikdy se neukládají</translation>
<translation id="106701514854093668">Záložky v PC</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Mezipaměť zásady je v pořádku</translation>
<translation id="113188000913989374">Web <ph name="SITE" /> říká:</translation>
<translation id="1132774398110320017">Nastavení Automatického vyplňování v prohlížeÄi Chrome...</translation>
+<translation id="1150979032973867961">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. OperaÄní systém vaÅ¡eho poÄítaÄe nedůvěřuje jeho bezpeÄnostnímu certifikátu.Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
+<translation id="1151972924205500581">Je vyžadováno heslo</translation>
<translation id="1152921474424827756">Otevřete <ph name="BEGIN_LINK" />archivovanou kopii<ph name="END_LINK" /> stránky <ph name="URL" /></translation>
<translation id="1158211211994409885">Web <ph name="HOST_NAME" /> neoÄekávanÄ› ukonÄil pÅ™ipojení.</translation>
<translation id="1161325031994447685">Obnovit připojení k síti Wi-Fi</translation>
+<translation id="1165039591588034296">Chyba</translation>
<translation id="1175364870820465910">Tisk...</translation>
<translation id="1181037720776840403">Odebrat</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Automaticky Googlu hlásit<ph name="END_WHITEPAPER_LINK" /> podrobnosti o možných bezpeÄnostních incidentech. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Více z tohoto webu</translation>
<translation id="1206967143813997005">Chybný poÄáteÄní podpis</translation>
<translation id="1209206284964581585">Prozatím skrýt</translation>
+<translation id="121201262018556460">Pokusili jste se pÅ™ejít na web <ph name="DOMAIN" />, server vÅ¡ak pÅ™edložil certifikát obsahující slabý klíÄ. ÚtoÄník možná prolomil soukromý klÃ­Ä a může se jednat o jiný server, než pÅ™edpokládáte (můžete komunikovat s útoÄníkem).</translation>
<translation id="1219129156119358924">ZabezpeÄení systému</translation>
<translation id="1227224963052638717">Neznámá zásada.</translation>
<translation id="1227633850867390598">Skrýt hodnotu</translation>
<translation id="1228893227497259893">Nesprávný identifikátor subjektu</translation>
<translation id="1232569758102978740">Bez názvu</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronizováno)</translation>
<translation id="1263231323834454256">Seznam Äetby</translation>
<translation id="1264126396475825575">Zpráva o selhání pořízená <ph name="CRASH_TIME" /> (dosud nenahrána nebo ignorována)</translation>
+<translation id="1281526147609854549">Vydavatel: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Byl zablokován nebezpeÄný obsah</translation>
<translation id="1285320974508926690">Tento web nikdy nepřekládat</translation>
<translation id="129553762522093515">Nedávno zavřené</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Zkuste vymazat soubory cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Vaše aktivita <ph name="BEGIN_EMPHASIS" />může být nadále viditelná<ph name="END_EMPHASIS" /> pro následující subjekty:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />navštívené weby,
+ <ph name="LIST_ITEM" />váš zaměstnavatel nebo škola,
+ <ph name="LIST_ITEM" />váš poskytovatel internetových služeb.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Doména registrace:</translation>
<translation id="1340482604681802745">Adresa vyzvednutí</translation>
<translation id="1344211575059133124">Zdá se, že k návštěvě tohoto webu potřebuješ povolení</translation>
<translation id="1344588688991793829">Nastavení Automatického vyplňování v prohlížeÄi Chromium...</translation>
+<translation id="1348198688976932919">Web, na který se chystáte pÅ™ejít, obsahuje nebezpeÄné aplikace</translation>
<translation id="1374468813861204354">návrhy</translation>
<translation id="1375198122581997741">O verzi aplikace</translation>
<translation id="1377321085342047638">Číslo karty</translation>
<translation id="139305205187523129">Web <ph name="HOST_NAME" /> neodeslal žádná data.</translation>
<translation id="1407135791313364759">Otevřít vše</translation>
<translation id="1413809658975081374">Chyba ochrany soukromí</translation>
+<translation id="14171126816530869">Identitu <ph name="ORGANIZATION" />v <ph name="LOCALITY" /> ověřil/a <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ano</translation>
<translation id="1430915738399379752">Tisk</translation>
-<translation id="1442912890475371290">Byl zablokován pokus <ph name="BEGIN_LINK" /> navštívit stránku v doméně <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože používá pÅ™ipínání certifikátů. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> další}few{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> další}many{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> dalšího}other{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> dalších}}</translation>
<translation id="1506687042165942984">Zobrazí uloženou (tj. neaktuální) kopii této stránky</translation>
<translation id="1517433312004943670">Je vyžadováno telefonní Äíslo</translation>
<translation id="1519264250979466059">Datum sestavení</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Chcete-li tuto funkci použít, musí být aktivován JavaScript.</translation>
<translation id="1555130319947370107">Modrá</translation>
<translation id="1559528461873125649">Daný soubor nebo adresář neexistuje.</translation>
-<translation id="1559572115229829303">&lt;p&gt;Soukromé pÅ™ipojení k doménÄ› <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v zařízení nastaveno chybné datum a Äas (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
-
- &lt;p&gt;Datum a Äas upravte v aplikaci &lt;strong&gt;Nastavení&lt;/strong&gt; v sekci &lt;strong&gt;Obecné&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Při zobrazování této webové stránky došlo k chybě.</translation>
<translation id="1592005682883173041">Přístup k místním datům</translation>
+<translation id="1594030484168838125">Zvolit</translation>
<translation id="161042844686301425">Azurová</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Chcete, aby Chrome tuto kartu uložil?</translation>
<translation id="1639239467298939599">NaÄítání</translation>
<translation id="1640180200866533862">Zásady pro uživatele</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Konfigurace sítě je neplatná a nelze ji importovat.</translation>
<translation id="1644574205037202324">Historie</translation>
<translation id="1645368109819982629">Nepodporovaný protokol</translation>
+<translation id="1655462015569774233">{1,plural, =1{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vÄera vyprÅ¡ela. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste nastavit správné hodiny systému a poté tuto stránku naÄíst znovu.}few{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vyprÅ¡ela pÅ™ed # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste Äas v poÄítaÄi opravit a poté tuto stránku naÄíst znovu.}many{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vyprÅ¡ela pÅ™ed # dnem. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste nastavit správné hodiny systému a poté tuto stránku naÄíst znovu.}other{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vyprÅ¡ela pÅ™ed # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste nastavit správné hodiny systému a poté tuto stránku naÄíst znovu.}}</translation>
<translation id="1656489000284462475">Vyzvednutí</translation>
<translation id="1663943134801823270">Karty a adresy pocházejí z Chromu. Můžete je spravovat v <ph name="BEGIN_LINK" />Nastavení<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Web <ph name="SITE" /> vaÅ¡e informace běžnÄ› chrání Å¡ifrováním. Když se prohlížeÄ Chrome k webu <ph name="SITE" /> pokusil pÅ™ipojit tentokrát, web vrátil neobvyklé a nesprávné identifikaÄní údaje. K tomuto problému může dojít, pokud se za web <ph name="SITE" /> pokouší vydávat nÄ›jaký útoÄník nebo pokud bylo pÅ™ipojení pÅ™eruÅ¡eno pÅ™ihlaÅ¡ovací obrazovkou sítÄ› Wi-Fi. VaÅ¡e informace jsou i nadále v bezpeÄí, protože prohlížeÄ Google Chrome pÅ™ipojení pÅ™eruÅ¡il dříve, než doÅ¡lo k odeslání jakýchkoliv dat.</translation>
-<translation id="168328519870909584">ÚtoÄníci, kteří se aktuálnÄ› nacházejí na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, se mohou pokusit nainstalovat do vaÅ¡eho zařízení nebezpeÄné aplikace, které mohou ukrást nebo smazat vaÅ¡e informace (například fotky, hesla, zprávy nebo platební karty).</translation>
<translation id="168841957122794586">Certifikát serveru obsahuje slabý kryptografický klíÄ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je zítra. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.}few{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je až za # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.}many{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je až za # dne. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.}other{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je až za # dní. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.}}</translation>
<translation id="1710259589646384581">OperaÄní systém</translation>
<translation id="1721312023322545264">Zdá se, že k návštěvě tohoto webu potřebujete povolení od správce <ph name="NAME" /></translation>
<translation id="1721424275792716183">* Pole je povinné</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Stáhnout stránku později</translation>
<translation id="17513872634828108">Otevřené karty</translation>
<translation id="1753706481035618306">Číslo stránky</translation>
+<translation id="1763864636252898013">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. OperaÄní systém vaÅ¡eho zařízení nedůvěřuje jeho bezpeÄnostnímu certifikátu. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Zkuste spustit Diagnostiku sítě systému Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Aktualizujte prosím heslovou frázi pro synchronizaci.</translation>
<translation id="1787142507584202372">Zde se zobrazí otevřené karty</translation>
+<translation id="1789575671122666129">Vyskakovací okna</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Jméno držitele karty</translation>
-<translation id="1803678881841855883">Služba BezpeÄné prohlížení Google na webu <ph name="SITE" /> nedávno <ph name="BEGIN_LINK" />zjistila malware<ph name="END_LINK" />. NÄ›kdy mohou být malwarem nakaženy i weby, které jsou obvykle bezpeÄné. Tento Å¡kodlivý obsah pochází z webu <ph name="SUBRESOURCE_HOST" />, který je distribucí malwaru známý. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Přidáno <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Neplatný požadavek nebo parametry požadavku</translation>
<translation id="1826516787628120939">Probíhá kontrola</translation>
<translation id="1834321415901700177">Tento web obsahuje škodlivé programy</translation>
+<translation id="1840414022444569775">Toto Äíslo karty již existuje</translation>
<translation id="1842969606798536927">Zaplatit</translation>
<translation id="1871208020102129563">Proxy je nastaveno na používání pevně daných serverů proxy, nikoliv adresy URL skriptu PAC.</translation>
<translation id="1871284979644508959">Povinné pole</translation>
<translation id="187918866476621466">Otevřít poÄáteÄní stránky</translation>
<translation id="1883255238294161206">Sbalit seznam</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> další}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> další}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> dalšího}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> dalších}}</translation>
<translation id="1898423065542865115">Filtrování</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Žádné}=1{1 web}few{# weby}many{# webu}other{# webů}}</translation>
<translation id="194030505837763158">Přejít na odkaz <ph name="LINK" /></translation>
<translation id="1962204205936693436">Záložky domény <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Chyba serializace</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Zásada ignorována, protože bylo přepsána zásadou <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Vyhledávání stránek fyzického webu v okolí</translation>
<translation id="213826338245044447">Mobilní záložky</translation>
-<translation id="2148716181193084225">Dnes</translation>
+<translation id="2147827593068025794">Synchronizace na pozadí</translation>
<translation id="2154054054215849342">Synchronizace není pro vaši doménu k dispozici</translation>
<translation id="2154484045852737596">Úprava karty</translation>
<translation id="2166049586286450108">Úplný přístup administrátora</translation>
<translation id="2166378884831602661">Tento web nemůže poskytnout zabezpeÄené pÅ™ipojení</translation>
<translation id="2181821976797666341">Zásady</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresa}few{# adresy}many{# adresy}other{# adres}}</translation>
+<translation id="2187317261103489799">Rozpoznat (výchozí)</translation>
<translation id="2202020181578195191">Zadejte platný rok vypršení platnosti</translation>
<translation id="2212735316055980242">Zásada nebyla nalezena</translation>
<translation id="2213606439339815911">NaÄítání záznamů...</translation>
+<translation id="2218879909401188352">ÚtoÄníci, kteří na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> aktuálnÄ› působí, by vám do zařízení mohli nainstalovat nebezpeÄné aplikace, které jej poÅ¡kodí, pÅ™idat skryté poplatky na úÄet za mobilní služby nebo odcizit osobní údaje. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Opravte připojení pomocí <ph name="BEGIN_LINK" />diagnostické aplikace<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Odeslat</translation>
<translation id="225207911366869382">Tato hodnota již pro tuto zásadu není podporována.</translation>
<translation id="2262243747453050782">Chyba protokolu HTTP</translation>
+<translation id="2270484714375784793">Telefonní Äíslo</translation>
<translation id="2282872951544483773">Nedostupné experimenty</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> položka}few{<ph name="ITEM_COUNT" /> položky}many{<ph name="ITEM_COUNT" /> položky}other{<ph name="ITEM_COUNT" /> položek}}</translation>
<translation id="2292556288342944218">Vaše připojení k internetu je blokováno</translation>
<translation id="230155334948463882">Nová karta?</translation>
-<translation id="2305919008529760154">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Je možné, že jeho bezpeÄnostní certifikát byl vydán podvodnÄ›. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535">Doména <ph name="DOMAIN" /> vyžaduje zadání uživatelského jména a hesla.</translation>
-<translation id="2318774815570432836">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože používá zabezpeÄení HSTS. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Nastavení je spravováno administrátorem</translation>
<translation id="2354001756790975382">Ostatní záložky</translation>
+<translation id="2354430244986887761">BezpeÄné prohlížení Google na webu <ph name="SITE" /> nedávno <ph name="BEGIN_LINK" />nalezlo Å¡kodlivé aplikace<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">ÚtoÄníci mohou vidÄ›t obrázky, které si na tomto webu prohlížíte, a oklamat vás tím, že tyto obrázky upraví.</translation>
+<translation id="2356070529366658676">Zeptat se</translation>
+<translation id="2359629602545592467">Několik</translation>
<translation id="2359808026110333948">PokraÄovat</translation>
<translation id="2365563543831475020">Zpráva o selhání pořízená <ph name="CRASH_TIME" /> nebyla nahrána</translation>
<translation id="2367567093518048410">Úroveň</translation>
-<translation id="2371153335857947666">{1,plural, =1{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vÄera vyprÅ¡ela. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste hodiny systému nastavit správnÄ› a poté tuto stránku naÄíst znovu. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}few{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vyprÅ¡ela pÅ™ed # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste hodiny systému nastavit správnÄ› a poté tuto stránku naÄíst znovu. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}many{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vyprÅ¡ela pÅ™ed # dne. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste hodiny systému nastavit správnÄ› a poté tuto stránku naÄíst znovu. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}other{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Platnost jeho bezpeÄnostního certifikátu vyprÅ¡ela pÅ™ed # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. Hodiny ve vaÅ¡em poÄítaÄi jsou aktuálnÄ› nastaveny na <ph name="CURRENT_DATE" />. Je to správnÄ›? Pokud ne, mÄ›li byste hodiny systému nastavit správnÄ› a poté tuto stránku naÄíst znovu. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">Žádné alternativy uživatelského rozhraní nejsou k dispozici</translation>
<translation id="2384307209577226199">Výchozí podnikové nastavení</translation>
<translation id="2386255080630008482">Certifikát serveru byl zamítnut.</translation>
<translation id="2392959068659972793">Zobrazit zásady bez nastavených hodnot</translation>
<translation id="239429038616798445">Tento způsob dopravy není k dispozici. Zkuste použít jiný způsob.</translation>
<translation id="2396249848217231973">&amp;Vrátit smazání zpět</translation>
-<translation id="2460160116472764928">Služba BezpeÄné prohlížení Google na webu <ph name="SITE" /> nedávno <ph name="BEGIN_LINK" />zjistila malware<ph name="END_LINK" />. NÄ›kdy mohou být malwarem nakaženy i weby, které jsou obvykle bezpeÄné. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Jeho bezpeÄnostní certifikát byl zÅ™ejmÄ› zruÅ¡en. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
<translation id="2463739503403862330">Vyplnit</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Spustit Diagnostiku sítě<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Neplatná adresa URL vyhledávání.</translation>
+<translation id="2482878487686419369">Oznámení</translation>
<translation id="2491120439723279231">Certifikát serveru obsahuje chyby.</translation>
<translation id="2495083838625180221">Analyzátor souborů JSON</translation>
<translation id="2495093607237746763">Pokud je tato možnost zaÅ¡krtnuta, prohlížeÄ Chromium do zařízení uloží kopii karty za úÄelem rychlejšího vyplňování formulářů.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Zpět</translation>
<translation id="2515629240566999685">Zkontrolovat, zda máte dostateÄnÄ› silný signál</translation>
<translation id="2516305470678292029">Alternativy uživatelského rozhraní</translation>
+<translation id="2539524384386349900">Rozpoznat</translation>
<translation id="255002559098805027">Web <ph name="HOST_NAME" /> vrátil neplatnou odpovÄ›Ä.</translation>
-<translation id="2552545117464357659">Novější</translation>
<translation id="2556876185419854533">&amp;Vrátit úpravy zpět</translation>
<translation id="2587730715158995865">Vydavatel: <ph name="ARTICLE_PUBLISHER" />. PÅ™eÄtÄ›te si tento Älánek a další (<ph name="OTHER_ARTICLE_COUNT" />).</translation>
<translation id="2587841377698384444">ID rozhraní Directory API:</translation>
<translation id="2597378329261239068">Tento dokument je chráněn heslem. Zadejte prosím heslo.</translation>
<translation id="2609632851001447353">Varianty</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Žádné}=1{1 aplikace ($1)}=2{2 aplikace ($1, $2)}few{# aplikace ($1, $2 $3)}many{# aplikace ($1, $2 $3)}other{# aplikací ($1, $2 $3)}}</translation>
<translation id="2625385379895617796">Vaše hodiny jdou napřed</translation>
<translation id="2639739919103226564">Stav:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Přístup k souboru byl odepřen.</translation>
<translation id="2653659639078652383">Odeslat</translation>
<translation id="2666117266261740852">Zavřete ostatní karty nebo aplikace</translation>
+<translation id="2670429602441959756">Tato stránka obsahuje funkce, které ve virtuální realitě dosud nejsou podporovány. Režim virtuální reality se zavře...</translation>
<translation id="2674170444375937751">Jste si jisti, že chcete tyto stránky odstranit ze své historie?</translation>
<translation id="2677748264148917807">Odejít</translation>
-<translation id="269990154133806163">Server pÅ™edložil certifikát, který nebyl zveÅ™ejnÄ›n v souladu se zásadou Certificate Transparency. U nÄ›kterých certifikátů je to z důvodu kontroly důvÄ›ryhodnosti a ochrany pÅ™ed útoÄníky vyžadováno. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Seznam Äetby</translation>
<translation id="2704283930420550640">Hodnota neodpovídá formátu.</translation>
<translation id="2704951214193499422">ProhlížeÄ Chromium vaÅ¡i kartu aktuálnÄ› nemohl ověřit. Zkuste to prosím znovu pozdÄ›ji.</translation>
<translation id="2705137772291741111">Kopii tohoto webu uloženou v mezipamÄ›ti se nepodaÅ™ilo pÅ™eÄíst.</translation>
<translation id="2709516037105925701">Automatické vyplňování</translation>
-<translation id="2712118517637785082">Pokusili jste se pÅ™ejít na web <ph name="DOMAIN" />, ale certifikát pÅ™edložený tímto webem byl vydavatelem zruÅ¡en. To znamená, že bezpeÄnostním pověřením, která web pÅ™edložil, nelze vůbec důvěřovat. Je možné, že komunikujete s útoÄníkem. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Požádat o oprávnění</translation>
<translation id="2713444072780614174">Bílá</translation>
<translation id="2720342946869265578">Nablízku</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Chybějící záznam zařízení</translation>
<translation id="2784949926578158345">Připojení bylo resetováno.</translation>
<translation id="2794233252405721443">Web je blokován</translation>
+<translation id="2799020568854403057">Web, na který se chystáte přejít, obsahuje škodlivé aplikace</translation>
+<translation id="2803306138276472711">Služba BezpeÄné prohlížení Google na webu <ph name="SITE" /> nedávno <ph name="BEGIN_LINK" />zjistila malware<ph name="END_LINK" />. NÄ›kdy mohou být malwarem nakaženy i weby, které jsou obvykle bezpeÄné.</translation>
<translation id="2824775600643448204">Adresní a vyhledávací řádek</translation>
<translation id="2826760142808435982">PÅ™ipojení je Å¡ifrováno a ověřeno pomocí Å¡ifry <ph name="CIPHER" /> a jako mechanismus výmÄ›ny klíÄů používá <ph name="KX" />.</translation>
<translation id="2835170189407361413">Vymazat formulář</translation>
+<translation id="2856444702002559011">ÚtoÄníci se mohou pokusit odcizit vaÅ¡e údaje na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (například hesla, zprávy nebo informace o platebních kartách). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">NenaÄítat znovu</translation>
<translation id="2900469785430194048">ProhlížeÄ Google Chrome k zobrazení této webové stránky nemÄ›l dostatek pamÄ›ti.</translation>
<translation id="2909946352844186028">Byla zjištěna změna sítě.</translation>
<translation id="2916038427272391327">Zavřete ostatní programy</translation>
<translation id="2922350208395188000">Certifikát serveru nelze zkontrolovat.</translation>
<translation id="2928905813689894207">FakturaÄní adresa</translation>
+<translation id="2941952326391522266">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Jeho bezpeÄnostní certifikát pochází z domény <ph name="DOMAIN2" />. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
<translation id="2948083400971632585">Libovolné servery proxy nakonfigurované pro připojení můžete zakázat na stránce Nastavení.</translation>
<translation id="2955913368246107853">Zavřít vyhledávací lištu</translation>
<translation id="2958431318199492670">Konfigurace sítÄ› nesplňuje standard ONC. Může se stát, že nÄ›které Äásti konfigurace nebudou importovány.</translation>
-<translation id="29611076221683977">ÚtoÄníci, kteří se aktuálnÄ› nacházejí na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, se mohou pokusit nainstalovat vám do poÄítaÄe Mac nebezpeÄné programy, které mohou ukrást nebo smazat vaÅ¡e informace (například fotky, hesla, zprávy nebo platební karty).</translation>
<translation id="2966678944701946121">Platnost do <ph name="EXPIRATION_DATE_ABBR" />, přidáno <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Aby bylo možné navázat zabezpeÄené spojení, musejí být správnÄ› nastaveny hodiny. Důvodem je, že certifikáty, pomocí kterých se weby identifikují, platí pouze pro konkrétní období. Jelikož hodiny v zařízení nejsou nastaveny správnÄ›, Google Chrome tyto certifikáty nemůže ověřit.</translation>
<translation id="2972581237482394796">&amp;Opakovat</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Zadejte platnou adresu</translation>
<translation id="2986368408720340940">Tento způsob vyzvednutí není k dispozici. Zkuste použít jiný způsob.</translation>
<translation id="2991174974383378012">Sdílení s weby</translation>
+<translation id="2991571918955627853">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože používá zabezpeÄení HSTS. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat.</translation>
<translation id="3005723025932146533">Zobrazit uloženou kopii</translation>
<translation id="3008447029300691911">Zadejte kód CVC karty <ph name="CREDIT_CARD" />. Po ověření budou údaje o kartě sdíleny s tímto webem.</translation>
<translation id="3010559122411665027">Položka seznamu „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automaticky blokováno</translation>
<translation id="3024663005179499861">Chybný typ zásady</translation>
<translation id="3032412215588512954">Chcete tento web naÄíst znovu?</translation>
<translation id="3037605927509011580">Aj, chyba!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{alespoň jedna položka v synchronizovaných zařízeních}=1{1 položka (a další v synchronizovaných zařízeních)}few{# položky (a další v synchronizovaných zařízeních)}many{# položky (a další v synchronizovaných zařízeních)}other{# položek (a další v synchronizovaných zařízeních)}}</translation>
<translation id="3041612393474885105">Informace o certifikátu</translation>
<translation id="3063697135517575841">Chrome vaši kartu aktuálně nemohl ověřit. Zkuste to prosím znovu později.</translation>
<translation id="3064966200440839136">Chystáte se opustit anonymní režim, abyste mohli zaplatit v externí aplikaci. Chcete pokraÄovat?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Žádné}=1{1 heslo}few{# hesla}many{# hesla}other{# hesel}}</translation>
<translation id="3093245981617870298">Nejste připojeni k síti.</translation>
<translation id="3105172416063519923">ID díla:</translation>
<translation id="3109728660330352905">K zobrazení této stránky nemáte oprávnění.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Zkuste spustit Diagnostiku připojení<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Dekódování odpovědi se nezdařilo</translation>
<translation id="3150653042067488994">DoÄasná chyba serveru</translation>
@@ -247,13 +277,17 @@
<translation id="3167968892399408617">Stránky, které otevÅ™ete na anonymních kartách, po zavÅ™ení vÅ¡ech anonymních karet nezanechají žádné stopy v historii prohlížeÄe, v úložiÅ¡ti souborů cookie ani v historii vyhledávání. Zachovány vÅ¡ak zůstanou vÅ¡echny stažené soubory a vytvoÅ™ené záložky.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ostrov</translation>
+<translation id="317583078218509884">Nové nastavení oprávnÄ›ní webových stránek se projeví po opÄ›tovném naÄtení stránky.</translation>
<translation id="3176929007561373547">Zkontrolujte nastavení proxy serveru nebo se obraťte na správce sítě, aby ověřil, zda proxy server funguje. Pokud se domníváte, že by proxy server neměl být používán: <ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Otevřete stránku v anonymním režimu</translation>
-<translation id="3202578601642193415">Nejnovější</translation>
+<translation id="320323717674993345">Zrušit platbu</translation>
<translation id="3207960819495026254">Přidáno do záložek</translation>
+<translation id="3225919329040284222">Server se prokázal certifikátem, který neodpovídá integrovaným oÄekáváním. Tato oÄekávaní jsou zahrnuta u urÄitých webových stránek s vysokou úrovní zabezpeÄení kvůli vaší ochranÄ›.</translation>
<translation id="3226128629678568754">KliknÄ›te na tlaÄítko NaÄíst znovu. Tím znovu odeÅ¡lete údaje potÅ™ebné k naÄtení stránky.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Překlad se nezdařil. Stránka je již v jazyce <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Zadejte kód CVC karty <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Vždy na tomto webu zjišťovat důležitý obsah</translation>
<translation id="3254409185687681395">Přidat stránku do záložek</translation>
<translation id="3270847123878663523">&amp;Vrátit změnu uspořádání zpět</translation>
<translation id="3282497668470633863">Přidání jména na kartě</translation>
@@ -267,42 +301,48 @@
<translation id="3340978935015468852">nastavení</translation>
<translation id="3345135638360864351">Odeslání žádosti o přístup k tomuto webu uživateli <ph name="NAME" /> se nezdařilo. Zkuste to prosím znovu.</translation>
<translation id="3355823806454867987">Změna nastavení proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />nebude ukládat<ph name="END_EMPHASIS" /> následující informace:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />vaši historii prohlížení,
+ <ph name="LIST_ITEM" />soubory cookie a data webů,
+ <ph name="LIST_ITEM" />údaje zadané do formulářů.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Chyba hodin</translation>
-<translation id="337311366426640088">Další položky: <ph name="ITEM_COUNT" /></translation>
<translation id="337363190475750230">Vyřazeno</translation>
<translation id="3377188786107721145">Chyba analýzy zásady</translation>
<translation id="3380365263193509176">Neznámá chyba</translation>
<translation id="3380864720620200369">Číslo klienta:</translation>
<translation id="3391030046425686457">Adresa doruÄení</translation>
<translation id="3395827396354264108">Způsob vyzvednutí</translation>
-<translation id="340013220407300675">ÚtoÄníci se mohou pokusit ukrást vaÅ¡e údaje na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (například hesla, zprávy nebo informace o platebních kartách).</translation>
<translation id="3422248202833853650">Zkuste uvolnit paměť ukonÄením jiných programů.</translation>
<translation id="3422472998109090673">Web <ph name="HOST_NAME" /> momentálně není dostupný.</translation>
+<translation id="3427092606871434483">Povolit (výchozí)</translation>
<translation id="3427342743765426898">&amp;Opakovat úpravy</translation>
<translation id="3431636764301398940">Uložit tuto kartu do zařízení</translation>
<translation id="3435896845095436175">Aktivovat</translation>
<translation id="3447661539832366887">Vlastník tohoto zařízení hru s dinosaurem vypnul.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval naÄtení:</translation>
<translation id="3462200631372590220">Skrýt rozšířené</translation>
<translation id="3467763166455606212">Je nutné zadat jméno držitele karty</translation>
<translation id="3478058380795961209">Měsíc vypršení platnosti</translation>
<translation id="3479539252931486093">Nebylo toto oÄekáváno? <ph name="BEGIN_LINK" />Informujte nás<ph name="END_LINK" />.</translation>
<translation id="3479552764303398839">Nyní ne</translation>
-<translation id="348000606199325318">ID selhání <ph name="CRASH_LOCAL_ID" /> (ID serveru: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">V tuto chvíli se nám s vaším rodiÄem nepodaÅ™ilo spojit. Zkuste to prosím znovu.</translation>
<translation id="3528171143076753409">Certifikát serveru není důvěryhodný.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Alespoň jedna položka v synchronizovaných zařízeních}=1{1 položka (a další v synchronizovaných zařízeních)}few{# položky (a další v synchronizovaných zařízeních)}many{# položky (a další v synchronizovaných zařízeních)}other{# položek (a další v synchronizovaných zařízeních)}}</translation>
<translation id="3539171420378717834">Uchovat kopii této karty v tomto zařízení</translation>
<translation id="3542684924769048008">Použít heslo pro:</translation>
+<translation id="3545341443414427877">Soukromé pÅ™ipojení k doménÄ› <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v poÄítaÄi nastaveno chybné datum a Äas (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Šifrovat synchronizovaná data pomocí vlastní heslové fráze pro synchronizaci.</translation>
-<translation id="3549761410225185768">Ještě <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Jeho bezpeÄnostní certifikát pochází z domény <ph name="DOMAIN2" />. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Správce vám jej může odblokovat.</translation>
<translation id="3566021033012934673">Vaše připojení není soukromé</translation>
+<translation id="3569145463236695319">&lt;p&gt;Soukromé pÅ™ipojení k doménÄ› <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v zařízení nastaveno chybné datum a Äas (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
+
+ &lt;p&gt;Datum a Äas upravte v aplikaci &lt;strong&gt;Nastavení&lt;/strong&gt; v sekci &lt;strong&gt;Obecné&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Přidejte jméno</translation>
<translation id="3583757800736429874">&amp;Opakovat přesunutí</translation>
<translation id="3586931643579894722">Skrýt podrobnosti</translation>
-<translation id="3587482841069643663">VÅ¡e</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Zadejte platné datum vypršení platnosti</translation>
<translation id="36224234498066874">Smazat údaje o prohlížení...</translation>
@@ -318,7 +358,6 @@
<translation id="3681007416295224113">Informace o certifikátu</translation>
<translation id="3690164694835360974">PÅ™ihlášení není zabezpeÄené</translation>
<translation id="3693415264595406141">Heslo:</translation>
-<translation id="3696411085566228381">žádné</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">NaÄítání...</translation>
<translation id="3712624925041724820">Byly vyÄerpány licence</translation>
@@ -326,12 +365,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Zkontrolovat proxy server, firewall a konfiguraci DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Pokud bezpeÄnostní rizika chápete, můžete <ph name="BEGIN_LINK" />tento nespolehlivý web navÅ¡tívit<ph name="END_LINK" /> jeÅ¡tÄ› pÅ™ed tím, než budou nebezpeÄné programy odstranÄ›ny.</translation>
<translation id="3739623965217189342">Zkopírovaný odkaz</translation>
+<translation id="3744899669254331632">Web <ph name="SITE" /> nyní nelze navÅ¡tívit, protože tento web odeslal nesprávné identifikaÄní údaje, které prohlížeÄ Chromium nedokáže zpracovat. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat.</translation>
+<translation id="3748148204939282805">ÚtoÄníci na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vás mohou podvodem pÅ™imÄ›t k nebezpeÄnému chování, jako je instalace softwaru nebo vyzrazení osobních údajů (například hesel, telefonních Äísel nebo platebních karet). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Z důvodu chyby serveru se překlad nezdařil.</translation>
<translation id="3759461132968374835">Nemáte žádná nedávno hlášená selhání. Selhání, ke kterým došlo, když byla služba hlášení o selháních vypnutá, se zde nezobrazují.</translation>
+<translation id="3778403066972421603">Chcete tuto kartu uložit do svého úÄtu Google a do tohoto zařízení?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Platnost do: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Pokud používáte proxy server...</translation>
<translation id="3828924085048779000">Prázdná heslová fráze není povolena.</translation>
-<translation id="3845539888601087042">Zobrazuje se historie z vašich přihlášených zařízení. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Zpět</translation>
<translation id="3858027520442213535">Aktualizovat datum a Äas</translation>
<translation id="3884278016824448484">Konfliktní identifikátor zařízení</translation>
@@ -339,11 +381,13 @@
<translation id="3886446263141354045">Vaše žádost o přístup k tomuto webu byla odeslána uživateli <ph name="NAME" />.</translation>
<translation id="3890664840433101773">Přidat e-mail</translation>
<translation id="3901925938762663762">Karta vypršela</translation>
-<translation id="3933571093587347751">{1,plural, =1{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je zítra. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}few{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je až za # dny. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}many{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je až za # dne. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}other{Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Uvedené datum vystavení jeho bezpeÄnostního certifikátu je až za # dní. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">NaÄítání dokumentu PDF se nezdaÅ™ilo.</translation>
+<translation id="3945915738023014686">ID nahrané zprávy o selhání <ph name="CRASH_ID" /> (místní ID selhání: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. V jeho bezpeÄnostním certifikátu nejsou uvedeny alternativní názvy subjektu. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
<translation id="3963721102035795474">Režim ÄteÄky</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Žádné}=1{Z 1 webu }few{Z # webů }many{Z # webu }other{Z # webů }}</translation>
<translation id="397105322502079400">Probíhá výpoÄet…</translation>
<translation id="3973234410852337861">Web <ph name="HOST_NAME" /> je blokován</translation>
+<translation id="3987940399970879459">Méně než 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 webová stránka v okolí}few{# webové stránky v okolí}many{# webové stránky v okolí}other{# webových stránek v okolí}}</translation>
<translation id="4021036232240155012">DNS je síťová služba, která překládá názvy webů na internetové adresy.</translation>
<translation id="4030383055268325496">&amp;Vrátit přidání zpět</translation>
@@ -354,56 +398,63 @@
<translation id="4079302484614802869">Proxy je nastaveno na používání adresy URL skriptu PAC, nikoliv pevně daných serverů proxy.</translation>
<translation id="4098354747657067197">Chystáte se navštívit podvodné webové stránky</translation>
<translation id="4103249731201008433">Sériové Äíslo zařízení je neplatné</translation>
+<translation id="410351446219883937">Automatické přehrávání</translation>
<translation id="4103763322291513355">Na stránce &lt;strong&gt;chrome://policy&lt;/strong&gt; naleznete seznam zakázaných adres URL a další zásady vynucené vaším správcem systému.</translation>
-<translation id="4110615724604346410">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />, protože jeho bezpeÄnostní certifikát obsahuje chyby. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Purpurová</translation>
+<translation id="4116663294526079822">Povolit vždy na tomto webu</translation>
<translation id="4117700440116928470">Rozsah zásady není podporován.</translation>
-<translation id="4118212371799607889">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Chromium jeho bezpeÄnostnímu certifikátu nedůvěřuje. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 další}few{# další}many{# další}other{# dalších}}</translation>
<translation id="4130226655945681476">Zkontrolovat síťové kabely, modem a smÄ›rovaÄ</translation>
+<translation id="413544239732274901">Další informace</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Použít globální výchozí nastavení (zjistit)</translation>
+<translation id="4165986682804962316">Nastavení webu</translation>
<translation id="4169947484918424451">Chcete, aby prohlížeÄ Chromium tuto kartu uložil?</translation>
<translation id="4171400957073367226">Chybný ověřovací podpis</translation>
<translation id="4196861286325780578">&amp;Opakovat přesunutí</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Zkontrolovat konfiguraci firewallu a antivirového softwaru<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{žádná aplikace}=1{1 aplikace ($1)}=2{2 aplikace ($1, $2)}few{# aplikace ($1, $2 $3)}many{# aplikace ($1, $2 $3)}other{# aplikací ($1, $2 $3)}}</translation>
<translation id="4220128509585149162">Selhání</translation>
+<translation id="422022731706691852">ÚtoÄníci na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> by se mohli pokusit pÅ™imÄ›t vás k instalaci programů, které nepříznivÄ› ovlivní procházení webu (například zmÄ›ní vaÅ¡i domovskou stránku nebo na navÅ¡tÄ›vovaných stránkách budou zobrazovat další reklamy). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Zkuste spustit Diagnostiku sítě<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Platný</translation>
<translation id="4250431568374086873">Spojení s tímto webem není plnÄ› zabezpeÄené</translation>
<translation id="4250680216510889253">Ne</translation>
<translation id="425582637250725228">Je možné, že provedené změny nebudou uloženy.</translation>
<translation id="4258748452823770588">Chybný podpis</translation>
+<translation id="4265872034478892965">Povoleno administrátorem</translation>
<translation id="4269787794583293679">(Žádné uživatelské jméno)</translation>
<translation id="4275830172053184480">Restartovat zařízení</translation>
<translation id="4280429058323657511">s platností do <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">BezpeÄné prohlížení Google na webu <ph name="SITE" /> nedávno <ph name="BEGIN_LINK" />nalezlo Å¡kodlivé programy<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">Návrhy rodiÄů</translation>
<translation id="4304224509867189079">Přihlásit se</translation>
-<translation id="432290197980158659">Server se prokázal certifikátem, který neodpovídá integrovaným oÄekáváním. Tato oÄekávaní jsou zahrnuta u urÄitých webových stránek s vysokou úrovní zabezpeÄení kvůli vaší ochranÄ›. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Blokovat (výchozí)</translation>
<translation id="4325863107915753736">Článek nebyl nalezen</translation>
<translation id="4326324639298822553">Zkontrolujte datum vypršení platnosti a zkuste to znovu.</translation>
<translation id="4331708818696583467">NezabezpeÄeno</translation>
<translation id="4356973930735388585">ÚtoÄníci, kteří se aktuálnÄ› nacházejí na tomto webu, se mohou pokusit nainstalovat vám do poÄítaÄe nebezpeÄné programy, které mohou ukrást nebo smazat vaÅ¡e informace (například fotky, hesla, zprávy nebo platební karty).</translation>
<translation id="4372948949327679948">OÄekávána hodnota <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Pokusili jste se pÅ™ejít na web <ph name="DOMAIN" />, ale certifikát prezentovaný tímto webem byl vydavatelem certifikátu zruÅ¡en. To znamená, že bezpeÄnostním pověřením, která web prezentoval, nelze zcela důvěřovat. Je možné, že komunikujete s útoÄníkem.</translation>
<translation id="4381091992796011497">Jméno uživatele:</translation>
<translation id="4394049700291259645">Deaktivovat</translation>
<translation id="4406896451731180161">výsledky vyhledávání</translation>
+<translation id="4424024547088906515">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Chrome jeho bezpeÄnostnímu certifikátu nedůvěřuje. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
<translation id="4432688616882109544">Web <ph name="HOST_NAME" /> nepřijal přihlašovací certifikát, případně žádný certifikát nebyl poskytnut.</translation>
<translation id="443673843213245140">Využití proxy serveru je zakázáno, je vÅ¡ak urÄena explicitní konfigurace proxy serveru.</translation>
-<translation id="4492190037599258964">Výsledky vyhledávání pro výraz „<ph name="SEARCH_STRING" />“</translation>
<translation id="4506176782989081258">Chyba ověřování: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4506599922270137252">Kontaktovat administrátora systému</translation>
<translation id="450710068430902550">Sdílení s administrátorem</translation>
<translation id="4515275063822566619">Karty a adresy pocházejí z Chromu a z vaÅ¡eho úÄtu Google (<ph name="ACCOUNT_EMAIL" />). Můžete je spravovat v <ph name="BEGIN_LINK" />Nastavení<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Podrobnosti</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Zkuste zakázat rozšíření.</translation>
<translation id="457875822857220463">DoruÄení</translation>
<translation id="4587425331216688090">Odstranit adresu z Chromu?</translation>
-<translation id="4589078953350245614">Pokusili jste se přejít do domény <ph name="DOMAIN" />, ale server předložil neplatný certifikát. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Vaše připojení k doméně <ph name="DOMAIN" /> je šifrováno za použití moderní šifrovací sady.</translation>
<translation id="4594403342090139922">&amp;Vrátit smazání zpět</translation>
<translation id="4619615317237390068">Karty z ostatních zařízení</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />, protože jeho bezpeÄnostní certifikát obsahuje chyby. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
+<translation id="4690462567478992370">Přestat používat neplatný certifikát</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Připojení bylo přerušeno</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Spustit Diagnostiku sítě systému Windows<ph name="END_LINK" /></translation>
@@ -420,21 +471,24 @@
<translation id="4771973620359291008">Došlo k neznámé chybě.</translation>
<translation id="4800132727771399293">Zkontrolujte datum vypršení platnosti a kód CVC a zkuste to znovu.</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože webové stránky odeslaly zakódované identifikaÄní údaje, které Chrome nedokáže zpracovat. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat.</translation>
<translation id="4813512666221746211">Chyba sítě</translation>
<translation id="4816492930507672669">Přizpůsobit na stránku</translation>
<translation id="483020001682031208">Nejsou k dispozici žádné stránky fyzického webu, které by bylo možné zobrazit</translation>
<translation id="4850886885716139402">Zobrazit</translation>
<translation id="4854362297993841467">Tento způsob doruÄení není k dispozici. Zkuste použít jiný způsob.</translation>
<translation id="4858792381671956233">Požádal(a) jsi rodiÄe o povolení návÅ¡tÄ›vy tohoto webu.</translation>
+<translation id="4863764087567530506">Tento obsah by se vás podvodem mohl pokusit přimět k instalaci softwaru nebo odhalení osobních údajů. <ph name="BEGIN_LINK" />Přesto zobrazit<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Hledat v historii</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{a 1 další webová stránka}few{a # další webové stránky}many{a # další webové stránky}other{a # dalších webových stránek}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Tato stránka byla přeložena z neznámého jazyka do jazyka <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Platba</translation>
<translation id="4926049483395192435">Musí být uvedeno</translation>
<translation id="495170559598752135">Akce</translation>
<translation id="4958444002117714549">Rozbalit seznam</translation>
-<translation id="4962322354953122629">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Chrome jeho bezpeÄnostnímu certifikátu nedůvěřuje. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Znovu zapnout upozornění</translation>
<translation id="4989809363548539747">Tento plugin není podporován</translation>
<translation id="5002932099480077015">Pokud je tato možnost aktivována, Chrome do zařízení uloží kopii karty za úÄelem rychlejšího vyplňování formulářů.</translation>
<translation id="5018422839182700155">Tuto stránku nelze otevřít</translation>
@@ -442,14 +496,15 @@
<translation id="5023310440958281426">Zkontrolujte zásady svého správce</translation>
<translation id="5029568752722684782">Vymazat kopii</translation>
<translation id="5031870354684148875">O PÅ™ekladaÄi Google</translation>
+<translation id="5039804452771397117">Povolit</translation>
<translation id="5040262127954254034">Ochrana soukromí</translation>
<translation id="5045550434625856497">Nesprávné heslo</translation>
<translation id="5056549851600133418">Články pro vás</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Zkontrolovat adresu proxy serveru<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Žádné soubory cookie}=1{Soubory cookie používá 1 web. }few{Soubory cookie používají # weby. }many{Soubory cookie používá # webu. }other{Soubory cookie používá # webů. }}</translation>
<translation id="5087286274860437796">Certifikát serveru v tuto chvíli není platný.</translation>
<translation id="5087580092889165836">Přidat kartu</translation>
<translation id="5089810972385038852">Stát/kraj</translation>
+<translation id="5094747076828555589">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Chromium jeho bezpeÄnostnímu certifikátu nedůvěřuje. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
<translation id="5095208057601539847">Provincie</translation>
<translation id="5115563688576182185">(64bitový)</translation>
<translation id="5141240743006678641">Å ifrovat synchronizovaná hesla pomocí hesla k úÄtu Google</translation>
@@ -465,24 +520,24 @@
<translation id="5222812217790122047">Je nutné zadat e-mail</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Používáte Chrome v práci? Firmy mohou spravovat nastavení prohlížeÄe Chrome pro své zamÄ›stnance. Další informace</translation>
+<translation id="5297526204711817721">PÅ™ipojení k tomuto webu není soukromé. Režim VR můžete kdykoliv ukonÄit tím, že sejmete náhlavní soupravu a stisknete tlaÄítko ZpÄ›t.</translation>
<translation id="5299298092464848405">Při analýze zásady došlo k chybě</translation>
-<translation id="5300589172476337783">Zobrazit</translation>
<translation id="5308689395849655368">Zprávy o selhání jsou zakázány.</translation>
<translation id="5317780077021120954">Uložit</translation>
<translation id="5327248766486351172">Název</translation>
-<translation id="5337705430875057403">ÚtoÄníci na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vás mohou podvodem pÅ™imÄ›t k nebezpeÄnému chování, jako je instalace softwaru nebo vyzrazení osobních údajů (například hesel, telefonních Äísel nebo platebních karet).</translation>
-<translation id="5359637492792381994">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Jeho bezpeÄnostní certifikát v tuto chvíli není platný. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože jeho certifikát byl zruÅ¡en. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat.</translation>
<translation id="536296301121032821">Ukládání nastavení zásady se nezdařilo</translation>
<translation id="5386426401304769735">Řetězec certifikátů tohoto webu obsahuje certifikát podepsaný algoritmem SHA-1.</translation>
<translation id="5402410679244714488">Platnost do: <ph name="EXPIRATION_DATE_ABBR" />, naposledy použito více než před rokem</translation>
+<translation id="540969355065856584">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Jeho bezpeÄnostní certifikát v tuto chvíli není platný. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
<translation id="5421136146218899937">Vymazat údaje o prohlížení...</translation>
<translation id="5430298929874300616">Odstranit záložku</translation>
<translation id="5431657950005405462">Soubor nebyl nalezen</translation>
-<translation id="5435775191620395718">Zobrazuje se historie z tohoto zařízení. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Chyba validace schématu v místě <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Tuto stránku na webu <ph name="HOST_NAME" /> nelze najít</translation>
<translation id="5455374756549232013">Chybné Äasové razítko zásady</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> z <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Neplatné</translation>
<translation id="5470861586879999274">&amp;Opakovat úpravy</translation>
<translation id="54817484435770891">Přidejte platnou adresu</translation>
<translation id="5492298309214877701">Tato stránka v intranetu spoleÄnosti, organizace nebo Å¡koly má stejnou adresu URL jako externí web.
@@ -499,6 +554,8 @@ Kontaktujte administrátora systému.</translation>
<translation id="5571083550517324815">Vyzvednutí na této adrese není možné. Vyberte jinou adresu.</translation>
<translation id="5572851009514199876">Přihlaste se do Chromu, aby bylo možné ověřit, zda máte povolení tento web navštívit.</translation>
<translation id="5580958916614886209">Zkontrolujte měsíc vypršení platnosti a zkuste to znovu.</translation>
+<translation id="5586446728396275693">Žádné uložené adresy</translation>
+<translation id="5595485650161345191">Upravit adresu</translation>
<translation id="560412284261940334">Správa není podporována</translation>
<translation id="5610142619324316209">Zkontrolovat připojení</translation>
<translation id="5610807607761827392">Karty a adresy můžete spravovat v <ph name="BEGIN_LINK" />Nastavení<ph name="END_LINK" />.</translation>
@@ -506,15 +563,18 @@ Kontaktujte administrátora systému.</translation>
<translation id="5622887735448669177">Chcete tento web opustit?</translation>
<translation id="5629630648637658800">NaÄítání nastavení zásady se nezdaÅ™ilo</translation>
<translation id="5631439013527180824">Neplatný token správy zařízení</translation>
+<translation id="5633066919399395251">ÚtoÄníci, kteří se aktuálnÄ› nacházejí na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, se mohou pokusit nainstalovat vám do poÄítaÄe nebezpeÄné programy, které mohou ukrást nebo smazat vaÅ¡e informace (například fotky, hesla, zprávy nebo platební karty). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Poloha</translation>
+<translation id="5659593005791499971">E-mail</translation>
<translation id="5669703222995421982">Získejte personalizovaný obsah</translation>
<translation id="5675650730144413517">Tato stránka nefunguje</translation>
-<translation id="5677928146339483299">Zablokováno</translation>
-<translation id="5694783966845939798">Pokusili jste se pÅ™ejít na web <ph name="DOMAIN" />, server vÅ¡ak pÅ™edložil certifikát podepsaný slabým algoritmem (například SHA-1). To znamená, že bezpeÄnostní identifikaÄní údaje pÅ™edložené serverem mohou být faleÅ¡né a může se jednat o úplnÄ› jiný server, než pÅ™edpokládáte (můžete komunikovat s útoÄníkem). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">Identita těchto webových stránek nebyla ověřena.</translation>
+<translation id="5713016350996637505">Byl zablokován klamavý obsah</translation>
<translation id="5720705177508910913">Aktuální uživatel</translation>
<translation id="5732392974455271431">RodiÄe ti jej mohou odblokovat.</translation>
<translation id="5763042198335101085">Zadejte platnou e-mailovou adresu</translation>
<translation id="5765072501007116331">Chcete-li zobrazit způsoby doruÄení a požadavky, vyberte adresu</translation>
+<translation id="5778550464785688721">Úplná kontrola zařízení MIDI</translation>
<translation id="5784606427469807560">Při ověřování vaší karty došlo k problému. Zkontrolujte připojení k internetu a zkuste to znovu.</translation>
<translation id="5785756445106461925">Tato stránka obsahuje jeÅ¡tÄ› další nezabezpeÄené zdroje. Tyto zdroje budou bÄ›hem pÅ™enosu moci zobrazit jiní uživatelé a případní útoÄníci je mohou upravit a zmÄ›nit tak vzhled stránky.</translation>
<translation id="5786044859038896871">Chcete vyplnit informace o kartě?</translation>
@@ -523,14 +583,14 @@ Kontaktujte administrátora systému.</translation>
<translation id="5813119285467412249">&amp;Opakovat přidání</translation>
<translation id="5814352347845180253">Můžete ztratit přístup k prémiovému obsahu z webu <ph name="SITE" /> a některých dalších webů.</translation>
<translation id="5838278095973806738">Na tento web byste nemÄ›li zadávat citlivé údaje (například hesla nebo Äísla platebních karet), protože by je mohli odcizit útoÄníci.</translation>
-<translation id="5843436854350372569">Pokusili jste se pÅ™ejít do domény <ph name="DOMAIN" />, ale server pÅ™edložil certifikát se slabým klíÄem. Je možné, že se útoÄníkovi podaÅ™ilo soukromý klÃ­Ä prolomit a že se jedná o jiný server, než pÅ™edpokládáte (můžete komunikovat s útoÄníkem). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">Tento web není dostupný</translation>
<translation id="5869522115854928033">Uložená hesla</translation>
<translation id="5872918882028971132">Návrhy rodiÄů</translation>
<translation id="5901630391730855834">Žlutá</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synchronizováno)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{Používá se 1}few{Používají se #}many{Používá se #}other{Používá se #}}</translation>
<translation id="5926846154125914413">Můžete ztratit přístup k prémiovému obsahu z některých webů.</translation>
<translation id="5959728338436674663">Automaticky odesílat Äást <ph name="BEGIN_WHITEPAPER_LINK" />informací o systému a obsahu stránek<ph name="END_WHITEPAPER_LINK" /> do Googlu s cílem pomoci rozpoznávat nebezpeÄné aplikace a weby. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Týden</translation>
<translation id="5967867314010545767">Odstranit z historie</translation>
<translation id="5975083100439434680">Oddálit</translation>
<translation id="598637245381783098">Platební aplikaci nelze otevřít</translation>
@@ -539,20 +599,28 @@ Kontaktujte administrátora systému.</translation>
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Stránka 1}few{Stránka #}many{Stránka #}other{Stránka #}}</translation>
<translation id="6017514345406065928">Zelená</translation>
+<translation id="6017850046339264347">ÚtoÄníci na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> by vám do zařízení mohli nainstalovat klamavé aplikace, které se vydávají za nÄ›co jiného nebo shromažÄují data ke sledování vaší aktivity. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synchronizováno)</translation>
<translation id="6027201098523975773">Zadejte jméno</translation>
<translation id="6040143037577758943">Zavřít</translation>
<translation id="6042308850641462728">Více</translation>
+<translation id="6047233362582046994">Pokud bezpeÄnostní rizika chápete, můžete <ph name="BEGIN_LINK" />tento web navÅ¡tívit<ph name="END_LINK" /> pÅ™ed tím, než budou nebezpeÄné aplikace odstranÄ›ny.</translation>
+<translation id="6051221802930200923">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože používá pÅ™ipínání certifikátů. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat.</translation>
<translation id="6060685159320643512">Pozor, tyto experimenty mohou skonÄit vÅ¡elijak.</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{žádná aplikace}=1{1}few{#}many{#}other{#}}</translation>
+<translation id="6080696365213338172">Získali jste přístup k obsahu pomocí certifikátu poskytnutého správcem. Údaje poskytovaná doméně <ph name="DOMAIN" /> bude správce moci zachytit.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Žádné}=1{1 heslo (synchronizováno)}few{# hesla (synchronizováno)}many{# hesla (synchronizováno)}other{# hesel (synchronizováno)}}</translation>
<translation id="6146055958333702838">Zkontrolujte vÅ¡echny kabely a restartujte vÅ¡echny smÄ›rovaÄe, modemy a další síťová zařízení, která používáte.</translation>
<translation id="614940544461990577">Zkuste:</translation>
<translation id="6151417162996330722">Certifikát serveru má příliš dlouhé období platnosti.</translation>
<translation id="6157877588268064908">Chcete-li zobrazit způsoby dopravy a požadavky, vyberte adresu</translation>
+<translation id="6158003235852588289">Služba BezpeÄné prohlížení Google nedávno na webu <ph name="SITE" /> zjistila phishing. Phishingové weby se vás snaží oklamat tím, že se vydávají za jiné weby.</translation>
<translation id="6165508094623778733">Další informace</translation>
+<translation id="6169916984152623906">Nyní můžete procházet internet v soukromí a ostatní uživatelé tohoto zařízení vaši aktivitu neuvidí. Stažené soubory a záložky budou uloženy.</translation>
<translation id="6177128806592000436">Spojení s tímto webem není bezpeÄné</translation>
<translation id="6184817833369986695">(kohorta: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Zkontrolujte připojení k internetu</translation>
<translation id="6218753634732582820">Odstranit adresu z prohlížeÄe Chromium?</translation>
+<translation id="6221345481584921695">Služba BezpeÄné prohlížení Google na webu <ph name="SITE" /> nedávno <ph name="BEGIN_LINK" />zjistila malware<ph name="END_LINK" />. NÄ›kdy mohou být malwarem nakaženy i weby, které jsou obvykle bezpeÄné. Tento Å¡kodlivý obsah pochází z webu <ph name="SUBRESOURCE_HOST" />, který je distribucí malwaru známý.</translation>
<translation id="6251924700383757765">Zásady ochrany soukromí</translation>
<translation id="6254436959401408446">K otevření této stránky není k dispozici dostatek paměti</translation>
<translation id="625755898061068298">U tohoto webu jste deaktivovali bezpeÄnostní upozornÄ›ní.</translation>
@@ -578,15 +646,14 @@ Kontaktujte administrátora systému.</translation>
<translation id="6404511346730675251">Upravit záložku</translation>
<translation id="6410264514553301377">Zadejte datum vypršení platnosti a kód CVC karty <ph name="CREDIT_CARD" />.</translation>
<translation id="6414888972213066896">Zeptal(a) ses rodiÄe, zda můžeÅ¡ navÅ¡tívit tento web.</translation>
-<translation id="6416403317709441254">Web <ph name="SITE" /> nyní nelze navÅ¡tívit, protože tento web odeslal nesprávné identifikaÄní údaje, které prohlížeÄ Chromium nedokáže zpracovat. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">Nelze ověřit, zda byl certifikát zrušen.</translation>
<translation id="6433490469411711332">Upravit kontaktní údaje</translation>
<translation id="6433595998831338502">Web <ph name="HOST_NAME" /> odmítl připojení.</translation>
<translation id="6446608382365791566">Přidání dalších informací</translation>
+<translation id="6447842834002726250">Soubory cookie</translation>
<translation id="6451458296329894277">Potvrdit nové odeslání formuláře</translation>
<translation id="6456339708790392414">Vaše platba</translation>
<translation id="6458467102616083041">Ignorováno, protože výchozí vyhledávání je zakázáno zásadou.</translation>
-<translation id="6462969404041126431">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Je možné, že jeho bezpeÄnostní certifikát byl zruÅ¡en. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Zásady zařízení</translation>
<translation id="6477321094435799029">Chrome na této stránce zjistil neobvyklý kód a z důvodu ochrany vaÅ¡ich osobních údajů (například hesel, telefonních Äísel a platebních karet) ji zablokoval.</translation>
<translation id="6489534406876378309">ZaÄít nahrávat zprávy o selhání</translation>
@@ -598,20 +665,19 @@ Kontaktujte administrátora systému.</translation>
<translation id="6556915248009097796">Platnost do <ph name="EXPIRATION_DATE_ABBR" />, naposledy použito <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Správce vám přístup na web dosud neschválil.</translation>
<translation id="6569060085658103619">Prohlížíte si stránku rozšíření</translation>
-<translation id="6593753688552673085">méně než <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Tento obsah by vám do zařízení mohl zkusit nainstalovat nebezpeÄný software, který odcizuje nebo maže informace. <ph name="BEGIN_LINK" />PÅ™esto zobrazit<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Možnosti šifrování</translation>
<translation id="662080504995468778">Zůstat</translation>
<translation id="6626291197371920147">PÅ™idání platného Äísla karty</translation>
<translation id="6628463337424475685">Vyhledávání <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">ÚtoÄníci, kteří se aktuálnÄ› nacházejí na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, se mohou pokusit nainstalovat do vaÅ¡eho poÄítaÄe Mac nebezpeÄné programy, které mohou ukrást nebo smazat vaÅ¡e informace (například fotky, hesla, zprávy nebo platební karty). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Tato zásada se již nepoužívá.</translation>
-<translation id="6652240803263749613">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. OperaÄní systém vaÅ¡eho poÄítaÄe jeho bezpeÄnostnímu certifikátu nedůvěřuje. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Odstranit návrh položky formuláře z prohlížeÄe Chromium?</translation>
<translation id="6685834062052613830">Odhlaste se a dokonÄete nastavení</translation>
<translation id="6710213216561001401">Předchozí</translation>
<translation id="6710594484020273272">&lt;Zadejte vyhledávací dotaz&gt;</translation>
<translation id="6711464428925977395">Došlo k chybě proxy serveru nebo jste zadali nesprávnou adresu.</translation>
<translation id="6727102863431372879">Nastavit</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{žádné položky}=1{1 položka}few{# položky}many{# položky}other{# položek}}</translation>
<translation id="674375294223700098">Neznámá chyba certifikátu serveru.</translation>
<translation id="6753269504797312559">Hodnota zásady</translation>
<translation id="6757797048963528358">Zařízení přešlo do režimu spánku.</translation>
@@ -619,6 +685,8 @@ Kontaktujte administrátora systému.</translation>
<translation id="6810899417690483278">ID přizpůsobení</translation>
<translation id="6820686453637990663">BezpeÄnostní kód platební karty (CVC)</translation>
<translation id="6824266427216888781">Údaje o oblastech se nepodaÅ™ilo naÄíst</translation>
+<translation id="6825578344716086703">Pokusili jste se pÅ™ejít na web <ph name="DOMAIN" />, server vÅ¡ak pÅ™edložil certifikát podepsaný slabým algoritmem (například SHA-1). To znamená, že bezpeÄnostní pověření pÅ™edložená serverem mohou být faleÅ¡ná a může se jednat o úplnÄ› jiný server, než pÅ™edpokládáte (můžete komunikovat s útoÄníkem).</translation>
+<translation id="6830728435402077660">NezabezpeÄeno</translation>
<translation id="6831043979455480757">Přeložit</translation>
<translation id="6839929833149231406">Region</translation>
<translation id="6874604403660855544">&amp;Opakovat přidání</translation>
@@ -626,6 +694,7 @@ Kontaktujte administrátora systému.</translation>
<translation id="6895330447102777224">Vaše karta je ověřena</translation>
<translation id="6897140037006041989">User agent</translation>
<translation id="6915804003454593391">Uživatel:</translation>
+<translation id="6945221475159498467">Vybrat</translation>
<translation id="6948701128805548767">Chcete-li zobrazit způsoby vyzvednutí a požadavky, vyberte adresu</translation>
<translation id="6957887021205513506">Zdá se, že certifikát serveru je podvrh.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -634,15 +703,16 @@ Kontaktujte administrátora systému.</translation>
<translation id="6973656660372572881">UrÄeny jsou pevnÄ› dané servery proxy i adresa URL skriptu PAC.</translation>
<translation id="6989763994942163495">Zobrazit rozšířená nastavení...</translation>
<translation id="7000990526846637657">Nebyly nalezeny žádné historické záznamy</translation>
-<translation id="7009986207543992532">Pokusili jste se připojit k doméně <ph name="DOMAIN" />, ale server předložil certifikát, který má příliš dlouhé období platnosti, a je proto nedůvěryhodný. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Na adrese <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> mohou být k dispozici další formy historie prohlížení zaznamenané ve vaÅ¡em úÄtu Google</translation>
<translation id="7029809446516969842">Hesla</translation>
+<translation id="7050187094878475250">Pokusili jste se připojit k doméně <ph name="DOMAIN" />, ale server předložil certifikát, který má příliš dlouhé období platnosti a je proto nedůvěryhodný.</translation>
+<translation id="7053983685419859001">Blokovat</translation>
<translation id="7064851114919012435">Kontaktní údaje</translation>
<translation id="7079718277001814089">Tento web obsahuje malware</translation>
<translation id="7087282848513945231">Obvod</translation>
-<translation id="7088615885725309056">Starší</translation>
<translation id="7090678807593890770">Vyhledejte na Googlu <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Povoleno rozšířením</translation>
<translation id="7119414471315195487">Zavřete ostatní karty nebo programy</translation>
<translation id="7129409597930077180">Dodání na tuto adresu není možné. Vyberte jinou adresu.</translation>
<translation id="7138472120740807366">Způsob doruÄení</translation>
@@ -660,22 +730,18 @@ Kontaktujte administrátora systému.</translation>
<translation id="7220786058474068424">Zpracovávání</translation>
<translation id="724691107663265825">Webové stránky, které chcete otevřít, obsahují malware</translation>
<translation id="724975217298816891">Chcete-li aktualizovat údaje o kartě, zadejte datum vypršení platnosti a kód CVC karty <ph name="CREDIT_CARD" />. Po ověření budou údaje o kartě sdíleny s tímto webem.</translation>
-<translation id="725866823122871198">Soukromé pÅ™ipojení k doménÄ› <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v poÄítaÄi nastaveno chybné datum a Äas (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="7260504762447901703">Zrušit přístup</translation>
<translation id="7275334191706090484">Spravované záložky</translation>
<translation id="7298195798382681320">DoporuÄeno</translation>
<translation id="7309308571273880165">Zpráva o selhání pořízená <ph name="CRASH_TIME" /> (o nahrání požádal uživatel, dosud nenahrána)</translation>
<translation id="7334320624316649418">&amp;Opakovat změnu uspořádání</translation>
<translation id="733923710415886693">Certifikát serveru nebyl zveřejněn prostřednictvím projektu Certificate Transparency.</translation>
-<translation id="7351800657706554155">Web <ph name="SITE" /> nyní nemůžete navÅ¡tívit, protože jeho certifikát byl zruÅ¡en. Síťové chyby a útoky jsou obvykle doÄasné, tato stránka pravdÄ›podobnÄ› pozdÄ›ji bude fungovat. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">Příkazový řádek</translation>
<translation id="7372973238305370288">výsledek vyhledávání</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ne</translation>
<translation id="7378810950367401542"> / </translation>
<translation id="7390545607259442187">Ověření karty</translation>
-<translation id="7394102162464064926">Opravdu chcete tyto stránky vymazat z historie?
-
-Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY" />).</translation>
<translation id="7400418766976504921">Adresa URL</translation>
<translation id="7419106976560586862">Cesta k profilu</translation>
<translation id="7424977062513257142">Stránka vložená na této webové stránce říká:</translation>
@@ -683,6 +749,7 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="7444046173054089907">Tento web je blokován</translation>
<translation id="7445762425076701745">Totožnost serveru, k nÄ›muž jste pÅ™ipojeni, nelze plnÄ› ověřit. Jste pÅ™ipojeni k serveru, který používá název platný pouze v rámci vaší sítÄ›. Externí certifikaÄní autorita nemůže vlastnictví názvu nijak ověřit. NÄ›které certifikaÄní autority vÅ¡ak vydají certifikát i pro takové názvy, a nelze tedy zaruÄit, že jste pÅ™ipojeni k požadovanému webu a nikoli k webu útoÄníka.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /> o tomto problému.</translation>
+<translation id="7455133967321480974">Použít výchozí globální hodnotu (Blokovat)</translation>
<translation id="7460163899615895653">Zde se zobrazují nedávno otevřené karty z jiných zařízení.</translation>
<translation id="7469372306589899959">Ověřování karty</translation>
<translation id="7481312909269577407">Vpřed</translation>
@@ -690,36 +757,43 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="7508255263130623398">Vrácené ID zařízení pro zásady je prázdné nebo neodpovídá aktuálnímu ID zařízení</translation>
<translation id="7514365320538308">Stáhnout</translation>
<translation id="7518003948725431193">Na webové adrese <ph name="URL" /> se nepodařilo nalézt žádnou webovou stránku.</translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Hodnota</translation>
<translation id="7537536606612762813">Povinná</translation>
+<translation id="7542403920425041731">Po ověření budou údaje o kartě sdíleny s tímto webem.</translation>
<translation id="7542995811387359312">Automatické vyplňování údajů platební karty je deaktivováno, protože tento formulář nepoužívá zabezpeÄené pÅ™ipojení.</translation>
<translation id="7543525346216957623">Požádej rodiÄe</translation>
<translation id="7549584377607005141">Tato stránka potřebuje ke správnému zobrazení data, která jste zadali dříve. Tyto údaje můžete odeslat znovu, ale zopakujete tím všechny akce, které tato stránka již předtím provedla.</translation>
<translation id="7552846755917812628">Vyzkoušejte následující tipy:</translation>
<translation id="7554791636758816595">Nová karta</translation>
+<translation id="7567204685887185387">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. Jeho bezpeÄnostní certifikát byl zÅ™ejmÄ› vydán podvodnÄ›. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> další}few{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> další}many{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> dalšího}other{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> dalších}}</translation>
<translation id="7568593326407688803">Tato stránka je v jazyce<ph name="ORIGINAL_LANGUAGE" />Chcete ji přeložit?</translation>
<translation id="7569952961197462199">Odstranit platební kartu z Chromu?</translation>
<translation id="7569983096843329377">Černá</translation>
<translation id="7578104083680115302">Plaťte na webech a v aplikacích v různých zařízeních rychle pomocí karet uložených na Googlu.</translation>
<translation id="7588950540487816470">Fyzický web</translation>
<translation id="7592362899630581445">Certifikát serveru porušuje omezení názvů domén.</translation>
+<translation id="7598391785903975535">Méně než <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Web <ph name="HOST_NAME" /> momentálně tento požadavek nemůže zpracovat.</translation>
<translation id="7600965453749440009">Jazyk <ph name="LANGUAGE" /> nikdy nepřekládat</translation>
<translation id="7610193165460212391">Hodnota <ph name="VALUE" /> je mimo rozsah.</translation>
<translation id="7613889955535752492">Vypršení platnosti: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Již máte údaje, které jsou Å¡ifrovány pomocí jiné verze vaÅ¡eho hesla k úÄtu Google. Zadejte toto heslo prosím níže.</translation>
-<translation id="7634554953375732414">Spojení s tímto webem není soukromé.</translation>
<translation id="7637571805876720304">Odstranit platební kartu z prohlížeÄe Chromium?</translation>
<translation id="765676359832457558">Skrýt rozšířená nastavení...</translation>
<translation id="7658239707568436148">Zrušit</translation>
+<translation id="7662298039739062396">Nastavení je spravováno rozšířením</translation>
<translation id="7667346355482952095">Vrácený klÃ­Ä zásady je prázdný nebo neodpovídá aktuálnímu klíÄi.</translation>
<translation id="7668654391829183341">Neznámé zařízení</translation>
<translation id="7669271284792375604">ÚtoÄníci na tomto webu by se mohli pokusit pÅ™imÄ›t vás k instalaci programů, které nepříznivÄ› ovlivní procházení webu (například zmÄ›ní vaÅ¡i domovskou stránku nebo na navÅ¡tÄ›vovaných stránkách budou zobrazovat další reklamy).</translation>
<translation id="7674629440242451245">Zajímají vás nové funkce Chromu? Vyzkoušejte kanál pro vývojáře na adrese chrome.com/dev.</translation>
<translation id="7682287625158474539">Doprava</translation>
+<translation id="7701040980221191251">Žádné</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />PokraÄovat na web <ph name="SITE" /> (nespolehlivý)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certifikát</translation>
+<translation id="7716147886133743102">Blokováno administrátorem</translation>
<translation id="7716424297397655342">Tento web nelze naÄíst z mezipamÄ›ti</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Nespravováno</translation>
<translation id="7755287808199759310">RodiÄ ti jej může odblokovat.</translation>
<translation id="7758069387465995638">Připojení mohlo být zablokováno firewallem nebo antivirovým softwarem.</translation>
@@ -746,15 +820,15 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="7951415247503192394">(32bitový)</translation>
<translation id="7956713633345437162">Mobilní záložky</translation>
<translation id="7961015016161918242">Nikdy</translation>
-<translation id="7962083544045318153">ID selhání <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Vždy překládat z jazyka <ph name="ORIGINAL_LANGUAGE" /> do jazyka <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Není zadáno</translation>
<translation id="800218591365569300">Zkuste uvolnit paměť tím, že zavřete ostatní karty nebo programy.</translation>
<translation id="8012647001091218357">V tuto chvíli se nám s vaÅ¡imi rodiÄi nepodaÅ™ilo spojit. Zkuste to prosím znovu.</translation>
<translation id="8025119109950072390">ÚtoÄníci na tomto webu vás mohou podvodem pÅ™imÄ›t k nebezpeÄnému chování, jako je instalace softwaru nebo vyzrazení osobních údajů (například hesel, telefonních Äísel nebo platebních karet).</translation>
-<translation id="803030522067524905">Služba BezpeÄné prohlížení Google nedávno na webu <ph name="SITE" /> zjistila phishing. Phishingové weby se vás snaží oklamat tím, že se vydávají za jiné weby. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Stránka je v jazyce <ph name="SOURCE_LANGUAGE" />. Chcete ji přeložit do jazyka <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Zeptat se (výchozí)</translation>
<translation id="8041089156583427627">Odeslat svůj názor</translation>
+<translation id="8041940743680923270">Použít výchozí globální hodnotu (Dotázat se)</translation>
<translation id="8088680233425245692">Zobrazení Älánku se nezdaÅ™ilo.</translation>
<translation id="8089520772729574115">méně než 1 MB</translation>
<translation id="8091372947890762290">Čeká se na aktivaci na serveru</translation>
@@ -763,13 +837,14 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />Adresa DNS<ph name="END_ABBR" /> serveru <ph name="HOST_NAME" /> nebyla nalezena.</translation>
<translation id="8149426793427495338">PoÄítaÄ pÅ™eÅ¡el do režimu spánku.</translation>
<translation id="8150722005171944719">Soubor na adrese <ph name="URL" /> nelze naÄíst. Možná byl odstranÄ›n, pÅ™esunut nebo mohou přístupu bránit oprávnÄ›ní souboru.</translation>
+<translation id="8184538546369750125">Použít výchozí globální hodnotu (Povolit)</translation>
+<translation id="8191494405820426728">Místní ID selhání <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Vrátit přesunutí zpět</translation>
<translation id="8201077131113104583">Neplatná adresa URL aktualizace rozšíření s ID <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Shrnutí objednávky</translation>
<translation id="8218327578424803826">Přiřazené místo:</translation>
<translation id="8225771182978767009">Uživatel, který tento poÄítaÄ nastavoval, se rozhodl tento web blokovat.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">ÚtoÄníci, kteří se aktuálnÄ› nacházejí na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, se mohou pokusit nainstalovat vám do poÄítaÄe nebezpeÄné programy, které mohou ukrást nebo smazat vaÅ¡e informace (například fotky, hesla, zprávy nebo platební karty).</translation>
<translation id="8241707690549784388">Stránka, kterou hledáte, používala vámi zadané informace. Návrat na tuto stránku by mohl způsobit, že akce, kterou jste provedli, bude opakována. PÅ™ejete si pokraÄovat?</translation>
<translation id="8249320324621329438">Naposledy naÄteno:</translation>
<translation id="8253091569723639551">FakturaÄní adresa je povinná</translation>
@@ -777,6 +852,7 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="8289355894181816810">Pokud nevíte, co dělat, obraťte se na svého správce sítě.</translation>
<translation id="8293206222192510085">Přidat záložku</translation>
<translation id="8294431847097064396">Zdroj</translation>
+<translation id="8306404619377842860">Soukromé pÅ™ipojení k doménÄ› <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v zařízení nastaveno chybné datum a Äas (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Překlad se nezdařil kvůli problému s připojením k síti.</translation>
<translation id="8332188693563227489">Přístup k webu <ph name="HOST_NAME" /> byl odepřen</translation>
<translation id="834457929814110454">Pokud bezpeÄnostní rizika chápete, můžete <ph name="BEGIN_LINK" />tento web navÅ¡tívit<ph name="END_LINK" /> pÅ™ed tím, než budou nebezpeÄné programy odstranÄ›ny.</translation>
@@ -797,11 +873,9 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="8483780878231876732">Chcete-li používat karty z úÄtu Google, pÅ™ihlaste se do Chromu.</translation>
<translation id="8488350697529856933">Platí pro</translation>
<translation id="8498891568109133222">OdpovÄ›Ä webu <ph name="HOST_NAME" /> trvala příliÅ¡ dlouho.</translation>
-<translation id="852346902619691059">Server nedokázal prokázat, že patří doménÄ› <ph name="DOMAIN" />. OperaÄní systém vaÅ¡eho zařízení jeho bezpeÄnostnímu certifikátu nedůvěřuje. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaÅ¡e pÅ™ipojení zachytává útoÄník. <ph name="BEGIN_LEARN_MORE_LINK" />Další informace<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Rok vypršení platnosti</translation>
<translation id="8543181531796978784">Můžete <ph name="BEGIN_ERROR_LINK" />nahlásit problém se zjiÅ¡tÄ›ným webem<ph name="END_ERROR_LINK" />. Pokud bezpeÄnostní rizika chápete, můžete <ph name="BEGIN_LINK" />tento nespolehlivý web navÅ¡tívit<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Překlad se nezdařil. Nepodařilo se rozpoznat jazyk stránky.</translation>
-<translation id="8559762987265718583">Soukromé pÅ™ipojení k doménÄ› <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nelze navázat, protože máte v zařízení nastaveno chybné datum a Äas (<ph name="DATE_AND_TIME" />).</translation>
<translation id="8571890674111243710">Překlad stránky do jazyka: <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Přidat telefon
</translation>
@@ -816,6 +890,7 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="8738058698779197622">Aby bylo možné navázat zabezpeÄené spojení, hodiny musejí být nastaveny správnÄ›. Důvodem je, že certifikáty, pomocí kterých se weby identifikují, platí pouze pro pevnÄ› daná období. Jelikož hodiny v zařízení nejsou nastaveny správnÄ›, prohlížeÄ Chromium tyto certifikáty nemůže ověřit.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;Adresu DNS&lt;/abbr&gt; webu <ph name="HOST_NAME" /> nelze najít. Diagnostikování problému…</translation>
<translation id="8759274551635299824">Platnost této karty vypršela</translation>
+<translation id="8761567432415473239">BezpeÄné prohlížení Google na webu <ph name="SITE" /> nedávno <ph name="BEGIN_LINK" />nalezlo Å¡kodlivé programy<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;Opakovat smazání</translation>
<translation id="8800988563907321413">Zde se zobrazí návrhy funkce Nablízku</translation>
<translation id="8820817407110198400">Záložky</translation>
@@ -828,29 +903,30 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="8870413625673593573">Nedávno zavřené</translation>
<translation id="8874824191258364635">Zadejte platné Äíslo karty</translation>
<translation id="8876793034577346603">Analýza konfigurace sítě se nezdařila.</translation>
-<translation id="8877192140621905067">Po ověření budou údaje o kartě sdíleny s tímto webem.</translation>
<translation id="8889402386540077796">Odstín</translation>
<translation id="8891727572606052622">Neplatný režim proxy serveru.</translation>
<translation id="889901481107108152">Je nám líto, tento experiment není na vaší platformě dostupný.</translation>
<translation id="8903921497873541725">Přiblížit</translation>
<translation id="8931333241327730545">Chcete tuto kartu uložit do úÄtu Google?</translation>
<translation id="8932102934695377596">VaÅ¡e hodiny se zpožÄují</translation>
-<translation id="8954894007019320973">(pokraÄování)</translation>
<translation id="8971063699422889582">Platnost certifikátu serveru vypršela.</translation>
<translation id="8986494364107987395">Automaticky posílat spoleÄnosti Google statistiky používání a zprávy o selhání</translation>
-<translation id="8987927404178983737">Měsíc</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Web, na který se chystáte přejít, obsahuje škodlivé programy</translation>
+<translation id="8997023839087525404">Server pÅ™edložil certifikát, který nebyl zveÅ™ejnÄ›n v souladu se zásadou Certificate Transparency. U nÄ›kterých certifikátů je to z důvodu kontroly důvÄ›ryhodnosti a ochrany pÅ™ed útoÄníky vyžadováno.</translation>
<translation id="9001074447101275817">Proxy <ph name="DOMAIN" /> vyžaduje uživatelské jméno a heslo.</translation>
+<translation id="9005998258318286617">NaÄtení dokumentu PDF se nezdaÅ™ilo.</translation>
<translation id="901974403500617787">Příznaky, které platí v celém systému, může nastavit pouze vlastník: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">FakturaÄní adresa karty je povinná</translation>
<translation id="9020542370529661692">Stránka byla přeložena do jazyka <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Chyba zabezpeÄení</translation>
<translation id="9038649477754266430">Používat službu pÅ™edpovídání k rychlejšímu naÄítání stránek</translation>
<translation id="9039213469156557790">Tato stránka obsahuje jeÅ¡tÄ› další nezabezpeÄené zdroje. Tyto zdroje budou bÄ›hem pÅ™enosu moci zobrazit jiní uživatelé a případní útoÄníci je mohou upravit a zmÄ›nit tak chování stránky.</translation>
-<translation id="9040185888511745258">ÚtoÄníci na webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> by se mohli pokusit pÅ™imÄ›t vás k instalaci programů, které nepříznivÄ› ovlivní procházení webu (například zmÄ›ní vaÅ¡i domovskou stránku nebo na navÅ¡tÄ›vovaných stránkách budou zobrazovat další reklamy).</translation>
+<translation id="9049981332609050619">Pokusili jste se přejít do domény <ph name="DOMAIN" />, ale server předložil certifikát, jehož platnost vypršela.</translation>
<translation id="9050666287014529139">Heslová fráze</translation>
<translation id="9065203028668620118">Upravit</translation>
<translation id="9068849894565669697">Výběr barvy</translation>
+<translation id="9069693763241529744">Blokováno rozšířením</translation>
<translation id="9076283476770535406">Může obsahovat materiály pouze pro dospělé</translation>
<translation id="9078964945751709336">Jsou potřeba další informace</translation>
<translation id="9103872766612412690">Web <ph name="SITE" /> vaÅ¡e informace běžnÄ› chrání Å¡ifrováním. Když se prohlížeÄ Chromium k webu <ph name="SITE" /> pokusil pÅ™ipojit tentokrát, web vrátil neobvyklé a nesprávné identifikaÄní údaje. K tomuto problému může dojít, pokud se za web <ph name="SITE" /> pokouší vydávat nÄ›jaký útoÄník nebo pokud bylo pÅ™ipojení pÅ™eruÅ¡eno pÅ™ihlaÅ¡ovací obrazovkou sítÄ› Wi-Fi. VaÅ¡e informace jsou i nadále v bezpeÄí, protože prohlížeÄ Chromium pÅ™ipojení pÅ™eruÅ¡il dříve, než doÅ¡lo k odeslání jakýchkoliv dat.</translation>
@@ -859,16 +935,21 @@ Pssst! Příště by se vám mohl hodit anonymní režim (<ph name="SHORTCUT_KEY
<translation id="9148507642005240123">&amp;Vrátit úpravy zpět</translation>
<translation id="9154194610265714752">Aktualizováno</translation>
<translation id="9157595877708044936">Nastavování...</translation>
+<translation id="9169664750068251925">Blokovat vždy na tomto webu</translation>
<translation id="9170848237812810038">Z&amp;pět</translation>
<translation id="917450738466192189">Certifikát serveru je neplatný.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> další}few{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> další}many{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> dalšího}other{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> dalších}}</translation>
<translation id="9183425211371246419">Web <ph name="HOST_NAME" /> používá nepodporovaný protokol.</translation>
<translation id="9205078245616868884">Vaše data jsou šifrována pomocí heslové fráze pro synchronizaci. Chcete-li zahájit synchronizaci, zadejte ji.</translation>
<translation id="9207861905230894330">PÅ™idání Älánku se nezdaÅ™ilo.</translation>
+<translation id="9219103736887031265">Obrázky</translation>
<translation id="933612690413056017">Připojení k internetu není k dispozici</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">VYMAZAT FORMULÃŘ</translation>
<translation id="939736085109172342">Nová složka</translation>
<translation id="941721044073577244">Zdá se, že k přístupu na tento web nemáte oprávnění</translation>
<translation id="969892804517981540">Oficiální sestavení</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Žádné}=1{1 položka}few{# položky}many{# položky}other{# položek}}</translation>
<translation id="988159990683914416">Vývojářské sestavení</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_da.xtb b/chromium/components/strings/components_strings_da.xtb
index 349c4a87a1d..3e54384ac0a 100644
--- a/chromium/components/strings/components_strings_da.xtb
+++ b/chromium/components/strings/components_strings_da.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Rotér med uret</translation>
<translation id="1038842779957582377">ukendt navn</translation>
<translation id="1050038467049342496">Luk andre apps</translation>
-<translation id="1053591932240354961">Du kan ikke gå til <ph name="SITE" /> lige nu, da websitet sendte krypterede loginoplysninger, som Google Chrome ikke kan behandle. Netværksfejl og hackerangreb er normalt midlertidige, så siden vil sandsynligvis fungere senere. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Fortryd tilføjelse</translation>
<translation id="10614374240317010">Aldrig gemt</translation>
<translation id="106701514854093668">Bogmærker på pc</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cache for politik er OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> siger:</translation>
<translation id="1132774398110320017">Indstillinger for Autofyld i Chrome...</translation>
+<translation id="1150979032973867961">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da operativsystemet på din computer ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
+<translation id="1151972924205500581">En adgangskode er påkrævet</translation>
<translation id="1152921474424827756">FÃ¥ adgang til en <ph name="BEGIN_LINK" />cachelagret kopi<ph name="END_LINK" /> af <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> lukkede forbindelsen uventet.</translation>
<translation id="1161325031994447685">Genoprette forbindelse til Wi-Fi</translation>
+<translation id="1165039591588034296">Fejl</translation>
<translation id="1175364870820465910">&amp;Udskriv...</translation>
<translation id="1181037720776840403">Fjern</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Rapportér automatisk<ph name="END_WHITEPAPER_LINK" /> oplysninger om mulige sikkerhedsproblemer til Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Mere fra dette website</translation>
<translation id="1206967143813997005">Ugyldig første signatur</translation>
<translation id="1209206284964581585">Skjul indtil videre</translation>
+<translation id="121201262018556460">Du har forsøgt at få fat i <ph name="DOMAIN" />, men serveren har præsenteret et certifikat med en svag nøgle. En hacker kan have knækket den private nøgle, og serveren er muligvis ikke den forventede server (du kommunikerer muligvis med en hacker).</translation>
<translation id="1219129156119358924">Systemsikkerhed</translation>
<translation id="1227224963052638717">Ukendt politik.</translation>
<translation id="1227633850867390598">Skjul værdi</translation>
<translation id="1228893227497259893">Forkert enheds-id</translation>
<translation id="1232569758102978740">Unavngivet</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synkroniseret)</translation>
<translation id="1263231323834454256">Læseliste</translation>
<translation id="1264126396475825575">Der blev registreret en nedbrudsrapport <ph name="CRASH_TIME" /> (endnu ikke uploadet eller ignoreret)</translation>
+<translation id="1281526147609854549">Udgivet af <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Farligt indhold er blokeret</translation>
<translation id="1285320974508926690">Oversæt aldrig dette website</translation>
<translation id="129553762522093515">Senest lukkede</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Prøv at rydde dine cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Din aktivitet <ph name="BEGIN_EMPHASIS" />er muligvis stadig synlig<ph name="END_EMPHASIS" /> for:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Websites, du besøger
+ <ph name="LIST_ITEM" />Din arbejdsgiver eller skole
+ <ph name="LIST_ITEM" />Din internetudbyder
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Registreringsdomæne:</translation>
<translation id="1340482604681802745">Afhentningsadresse</translation>
<translation id="1344211575059133124">Det ser ud til, at du skal have tilladelse til at besøge dette website</translation>
<translation id="1344588688991793829">Indstillinger for AutoFyld i Chromium...</translation>
+<translation id="1348198688976932919">Det website, du er på vej til, indeholder farlige apps</translation>
<translation id="1374468813861204354">forslag</translation>
<translation id="1375198122581997741">Om version</translation>
<translation id="1377321085342047638">Kortnummer</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> har ikke sendt nogen data.</translation>
<translation id="1407135791313364759">Ã…bn alle</translation>
<translation id="1413809658975081374">Fejl i forbindelse med beskyttelse af personlige oplysninger</translation>
+<translation id="14171126816530869">Identiteten for <ph name="ORGANIZATION" /> på <ph name="LOCALITY" /> er bekræftet af <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Udskriv</translation>
-<translation id="1442912890475371290">Et forsøg på at <ph name="BEGIN_LINK" />besøge en side på <ph name="DOMAIN" /><ph name="END_LINK" /> blev blokeret.</translation>
-<translation id="1491663344921578213">Du kan ikke gå til <ph name="SITE" /> lige nu, da websitet anvender certifikatlåsning. Netværksfejl og hackerangreb er normalt midlertidige, så denne side vil sandsynligvis fungere senere. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> anden}one{<ph name="PAYMENT_METHOD_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> anden}other{<ph name="PAYMENT_METHOD_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> andre}}</translation>
<translation id="1506687042165942984">Vis en gemt (dvs. forældet) kopi af denne side.</translation>
<translation id="1517433312004943670">Telefonnummer er påkrævet</translation>
<translation id="1519264250979466059">Versionsdato</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript skal være aktiveret, før du kan bruge denne funktion.</translation>
<translation id="1555130319947370107">Blå</translation>
<translation id="1559528461873125649">Filen eller mappen findes ikke</translation>
-<translation id="1559572115229829303">&lt;p&gt;Der kan ikke oprettes en privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da datoen og tiden på din enhed (<ph name="DATE_AND_TIME" />) er forkert.&lt;/p&gt;
-
- &lt;p&gt;Juster datoen og tiden i sektionen &lt;strong&gt;Generelt&lt;/strong&gt; i appen &lt;strong&gt;Indstillinger&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Der opstod en fejl ved visningen af denne webside.</translation>
<translation id="1592005682883173041">Lokal dataadgang</translation>
+<translation id="1594030484168838125">Vælg</translation>
<translation id="161042844686301425">Cyan</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Skal Chrome gemme dette kort?</translation>
<translation id="1639239467298939599">Indlæser...</translation>
<translation id="1640180200866533862">Brugerpolitikker</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Netværkskonfigurationen er ugyldig og kunne ikke importeres.</translation>
<translation id="1644574205037202324">Historik</translation>
<translation id="1645368109819982629">Ikke-understøttet protokol</translation>
+<translation id="1655462015569774233">{1,plural, =1{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat udløb i går. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side.}one{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat udløb for # dag siden. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side.}other{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat udløb for # dage siden. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side.}}</translation>
<translation id="1656489000284462475">Afhentning</translation>
<translation id="1663943134801823270">Kort og adresser er fra Chrome. Du kan administrere dem i <ph name="BEGIN_LINK" />Indstillinger<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> bruger normalt kryptering til at beskytte dine oplysninger. Da Google Chrome forsøgte at oprette forbindelse til <ph name="SITE" /> denne gang, returnerede websitet usædvanlige og forkerte legitimationsoplysninger. Dette kan skyldes, at en hacker forsøger at udgive sig for at være <ph name="SITE" />, eller at en Wi-Fi-loginskærm har forstyrret forbindelsen. Dine oplysninger er stadig sikre, idet Google Chrome afbrød forbindelsen, inden der blev udvekslet data.</translation>
-<translation id="168328519870909584">Hackere, der i øjeblikket befinder sig på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, vil muligvis forsøge at installere farlige apps på din enhed for at stjæle eller slette dine oplysninger (f.eks. billeder, adgangskoder, beskeder og kreditkortoplysninger).</translation>
<translation id="168841957122794586">Servercertifikatet indeholder en svag kryptografisk nøgle.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat tilsyneladende først gælder fra i morgen. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.}one{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat tilsyneladende først gælder fra om # dag. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.}other{Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat tilsyneladende først gælder fra om # dage. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Du skal have tilladelse fra <ph name="NAME" /> til at besøge dette website</translation>
<translation id="1721424275792716183">* Feltet skal udfyldes</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Download siden senere</translation>
<translation id="17513872634828108">Ã…bne faner</translation>
<translation id="1753706481035618306">Sidetal</translation>
+<translation id="1763864636252898013">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da operativsystemet på din enhed ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Prøv at køre Windows Netværksdiagnosticering<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Opdater din adgangssætning til synkronisering.</translation>
<translation id="1787142507584202372">Dine åbne faner vises her</translation>
+<translation id="1789575671122666129">Pop op-vinduer</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Kortindehaverens navn</translation>
-<translation id="1803678881841855883">Google Beskyttet browsing har for nylig <ph name="BEGIN_LINK" />registreret malware<ph name="END_LINK" /> på <ph name="SITE" />. Websites, der normalt er sikre, bliver undertiden inficeret med malware. Det skadelige indhold kommer fra <ph name="SUBRESOURCE_HOST" />, som er en kendt malwaredistributør. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Tilføjet <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Ugyldig anmodning eller anmodningsparametre</translation>
<translation id="1826516787628120939">Kontrollerer</translation>
<translation id="1834321415901700177">Dette website indeholder skadelige programmer</translation>
+<translation id="1840414022444569775">Dette kortnummer bruges allerede</translation>
<translation id="1842969606798536927">Betal</translation>
<translation id="1871208020102129563">Proxy er indstillet til at bruge faste proxyservere, ikke webadresser til .pac-scripts.</translation>
<translation id="1871284979644508959">Obligatorisk felt</translation>
<translation id="187918866476621466">Ã…bn opstartssider</translation>
<translation id="1883255238294161206">Skjul liste</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> anden}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> anden}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> andre}}</translation>
<translation id="1898423065542865115">Filtrering</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ingen}=1{1 website}one{# website}other{# websites}}</translation>
<translation id="194030505837763158">GÃ¥ til <ph name="LINK" /></translation>
<translation id="1962204205936693436">Bogmærker fra <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Serialiseringsfejl</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignoreret, da den blev tilsidesat af <ph name="POLICY_NAME" /> .</translation>
<translation id="2138201775715568214">Leder efter Fysisk web-sider i nærheden</translation>
<translation id="213826338245044447">Bogmærker på mobil</translation>
-<translation id="2148716181193084225">I dag</translation>
+<translation id="2147827593068025794">Synkronisering i baggrunden</translation>
<translation id="2154054054215849342">Synkronisering er ikke tilgængelig for dit domæne</translation>
<translation id="2154484045852737596">Rediger kort</translation>
<translation id="2166049586286450108">Fuld administratoradgang</translation>
<translation id="2166378884831602661">Dette website kan ikke levere en sikker forbindelse</translation>
<translation id="2181821976797666341">Politikker</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresse}one{# adresse}other{# adresser}}</translation>
+<translation id="2187317261103489799">Registrer (standardindstilling)</translation>
<translation id="2202020181578195191">Angiv et gyldigt udløbsår</translation>
<translation id="2212735316055980242">Politikken blev ikke fundet</translation>
<translation id="2213606439339815911">Indlæg hentes...</translation>
+<translation id="2218879909401188352">Hackere, der i øjeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, kan installere farlige apps, som kan skade din enhed, føje skjulte gebyrer til din mobilregning eller stjæle dine personlige oplysninger. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Ret problemerne med din forbindelse ved hjælp af <ph name="BEGIN_LINK" />diagnoseappen<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Send nu</translation>
<translation id="225207911366869382">Denne værdi er forældet for denne politik.</translation>
<translation id="2262243747453050782">HTTP-fejl</translation>
+<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2282872951544483773">Utilgængelige eksperimenter</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element}one{<ph name="ITEM_COUNT" /> element}other{<ph name="ITEM_COUNT" /> elementer}}</translation>
<translation id="2292556288342944218">Din internetadgang er blokeret</translation>
<translation id="230155334948463882">Har du fået nyt kort?</translation>
-<translation id="2305919008529760154">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet kan være udstedt på ulovlig vis. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> kræver et brugernavn og en adgangskode.</translation>
-<translation id="2318774815570432836">Du kan ikke gå til <ph name="SITE" /> lige nu, fordi websitet bruger HSTS. Netværksfejl og hackerangreb er normalt midlertidige, så siden vil sandsynligvis fungere senere. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Indstillingen styres af din administrator</translation>
<translation id="2354001756790975382">Andre bogmærker</translation>
+<translation id="2354430244986887761">Google Beskyttet browsing har for nylig <ph name="BEGIN_LINK" />fundet skadelige apps<ph name="END_LINK" /> på <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Hackere kan muligvis se de billeder, du kigger på på dette website, og narre dig ved at ændre dem.</translation>
+<translation id="2356070529366658676">Spørg</translation>
+<translation id="2359629602545592467">Flere</translation>
<translation id="2359808026110333948">Fortsæt</translation>
<translation id="2365563543831475020">Nedbrudsrapporten, der blev registreret <ph name="CRASH_TIME" />, blev ikke uploadet</translation>
<translation id="2367567093518048410">Niveau</translation>
-<translation id="2371153335857947666">{1,plural, =1{Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet udløb i går. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.}one{Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet udløb for # dag siden. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.}other{Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet udløb for # dage siden. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. Computerens ur er angivet til <ph name="CURRENT_DATE" />. Er det korrekt? Hvis ikke, skal du rette systemets ur og derefter opdatere denne side. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Der er ingen alternative grænseflader</translation>
<translation id="2384307209577226199">Virksomhedsstandard</translation>
<translation id="2386255080630008482">Serverens certifikat er blevet tilbagekaldt.</translation>
<translation id="2392959068659972793">Vis politikker uden nogen værdier</translation>
<translation id="239429038616798445">Denne forsendelsesmetode er ikke tilgængelig. Prøv en anden metode.</translation>
<translation id="2396249848217231973">&amp;Fortryd sletning</translation>
-<translation id="2460160116472764928">Google Beskyttet browsing har for nylig <ph name="BEGIN_LINK" />registreret malware<ph name="END_LINK" /> på <ph name="SITE" />. Websites, der normalt er sikre, bliver undertiden inficeret med malware. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da sikkerhedscertifikatet muligvis er blevet tilbagekaldt. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="2463739503403862330">Udfyld</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Køre Netværksdiagnosticering<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Ugyldig søgewebadresse.</translation>
+<translation id="2482878487686419369">Underretninger</translation>
<translation id="2491120439723279231">Serverens certifikat indeholder fejl.</translation>
<translation id="2495083838625180221">Værktøj til parsing af JSON-filer</translation>
<translation id="2495093607237746763">Hvis dette felt er markeret, gemmer Chromium en kopi af dit kort på denne enhed for at gøre det hurtigere at udfylde formularer.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">GÃ¥ tilbage</translation>
<translation id="2515629240566999685">Kontrollere signalet i dit område</translation>
<translation id="2516305470678292029">Alternative grænseflader</translation>
+<translation id="2539524384386349900">Registrer</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> sendte et ugyldigt svar.</translation>
-<translation id="2552545117464357659">Nyere</translation>
<translation id="2556876185419854533">&amp;Fortryd redigering</translation>
<translation id="2587730715158995865">Fra <ph name="ARTICLE_PUBLISHER" />. Læs denne og <ph name="OTHER_ARTICLE_COUNT" /> andre historier.</translation>
<translation id="2587841377698384444">Id for Directory API:</translation>
<translation id="2597378329261239068">Dette dokument er adgangskodebeskyttet. Indtast en adgangskode.</translation>
<translation id="2609632851001447353">Varianter</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ingen}=1{1 app ($1)}=2{2 apps ($1, $2)}one{# app ($1, $2, $3)}other{# apps ($1, $2 $3)}}</translation>
<translation id="2625385379895617796">Dit ur er foran</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Der blev nægtet adgang til filen</translation>
<translation id="2653659639078652383">Indsend</translation>
<translation id="2666117266261740852">Luk andre faner eller apps</translation>
+<translation id="2670429602441959756">Denne side indeholder funktioner, der endnu ikke understøttes i VR. Afslutter...</translation>
<translation id="2674170444375937751">Er du sikker på, at du vil slette disse sider fra din historik?</translation>
<translation id="2677748264148917807">Forlad</translation>
-<translation id="269990154133806163">Serveren præsenterede et certifikat, som ikke var offentliggjort via politikken Certifikatgennemsigtighed. Dette er et krav for visse certifikater for at sikre, at de er pålidelige og beskytter mod hackere. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Læseliste</translation>
<translation id="2704283930420550640">Værdien stemmer ikke overens med formatet.</translation>
<translation id="2704951214193499422">Chromium kan ikke bekræfte dit kort i øjeblikket. Prøv igen senere.</translation>
<translation id="2705137772291741111">Den gemte (cachelagrede) kopi af dette website kunne ikke læses.</translation>
<translation id="2709516037105925701">AutoFyld</translation>
-<translation id="2712118517637785082">Du har forsøgt at få forbindelse til <ph name="DOMAIN" />, men serverens certifikat er blevet tilbagekaldt af udstederen. Det betyder, at du bestemt ikke bør have tillid til serverens sikkerhedsoplysninger. Du kommunikerer muligvis med en hacker. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Spørg om tilladelse</translation>
<translation id="2713444072780614174">Hvid</translation>
<translation id="2720342946869265578">Tæt på</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Manglende enhedsregistrering</translation>
<translation id="2784949926578158345">Forbindelsen blev nulstillet.</translation>
<translation id="2794233252405721443">Websitet er blokeret</translation>
+<translation id="2799020568854403057">Det website, du er på vej til, indeholder skadelige apps</translation>
+<translation id="2803306138276472711">Google Beskyttet browsing <ph name="BEGIN_LINK" />registrerede malware<ph name="END_LINK" /> på <ph name="SITE" />. Websites, der normalt er sikre, bliver undertiden inficeret med malware.</translation>
<translation id="2824775600643448204">Adresse og søgelinje</translation>
<translation id="2826760142808435982">Forbindelsen er krypteret og godkendt ved hjælp af <ph name="CIPHER" />, og den anvender <ph name="KX" /> som primær udvekslingsmekanisme.</translation>
<translation id="2835170189407361413">Ryd formular</translation>
+<translation id="2856444702002559011">Brugere med ondsindede hensigter kan forsøge at stjæle dine oplysninger fra <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (f.eks. adgangskoder, beskeder eller kreditkort). <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Genindlæs ikke siden</translation>
<translation id="2900469785430194048">Google Chrome løb tør for hukommelse, da websiden skulle vises.</translation>
<translation id="2909946352844186028">Der blev registreret en netværksændring.</translation>
<translation id="2916038427272391327">Luk andre programmer</translation>
<translation id="2922350208395188000">Serverens certifikat kan ikke kontrolleres.</translation>
<translation id="2928905813689894207">Faktureringsadresse</translation>
+<translation id="2941952326391522266">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da sikkerhedscertifikatet er fra <ph name="DOMAIN2" />. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="2948083400971632585">Du kan deaktivere alle proxyer, der er konfigureret for en forbindelse, fra siden Indstillinger.</translation>
<translation id="2955913368246107853">Luk søgefeltet</translation>
<translation id="2958431318199492670">Netværkskonfigurationen overholder ikke ONC-standarden. Dele af konfiguration kan muligvis ikke importeres.</translation>
-<translation id="29611076221683977">Hackere, der i øjeblikket befinder sig på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, vil muligvis forsøge at installere skadelige programmer på din Mac for at stjæle eller slette dine oplysninger (f.eks. billeder, adgangskoder, beskeder og kreditkortoplysninger).</translation>
<translation id="2966678944701946121">Udløbsdato: <ph name="EXPIRATION_DATE_ABBR" />. Tilføjet <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Uret på din enhed skal være indstillet korrekt, før du kan oprette en sikker forbindelse. Dette er vigtigt, da de certifikater, websites bruger til at identificere sig selv, kun er gyldige i bestemte perioder. Da uret på din enhed er indstillet forkert, kan Chrome ikke bekræfte disse certifikater.</translation>
<translation id="2972581237482394796">&amp;Annuller fortryd</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Angiv en gyldig adresse</translation>
<translation id="2986368408720340940">Denne afhentningsmetode er ikke tilgængelig. Prøv en anden metode.</translation>
<translation id="2991174974383378012">Deling med websites</translation>
+<translation id="2991571918955627853">Du kan ikke besøge <ph name="SITE" /> lige nu, da websitet bruger HSTS. Netværksfejl og angreb er normalt midlertidige, så siden vil sandsynligvis fungere senere.</translation>
<translation id="3005723025932146533">Vis gemt kopi</translation>
<translation id="3008447029300691911">Indtast kontrolkoden for <ph name="CREDIT_CARD" />. Når du bekræfter, deles dine kortoplysninger med dette website.</translation>
<translation id="3010559122411665027">Angiv posten "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatisk blokering</translation>
<translation id="3024663005179499861">Forkert politiktype</translation>
<translation id="3032412215588512954">Vil du genindlæse denne side?</translation>
<translation id="3037605927509011580">Øv, surt!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{mindst 1 element på synkroniserede enheder}=1{1 element (og flere på synkroniserede enheder)}one{# element (og flere på synkroniserede enheder)}other{# elementer (og flere på synkroniserede enheder)}}</translation>
<translation id="3041612393474885105">Certifikatoplysninger</translation>
<translation id="3063697135517575841">Chrome kan ikke bekræfte dit kort i øjeblikket. Prøv igen senere.</translation>
<translation id="3064966200440839136">Du forlader inkognitotilstand for at betale via en ekstern applikation. Vil du fortsætte?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ingen}=1{1 adgangskode}one{# adgangskode}other{# adgangskoder}}</translation>
<translation id="3093245981617870298">Du er offline.</translation>
<translation id="3105172416063519923">Aktiv-id:</translation>
<translation id="3109728660330352905">Du har ikke tilladelse til at se denne side.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Prøv at køre Diagnosticering af forbindelse<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Svaret kunne ikke afkodes</translation>
<translation id="3150653042067488994">Midlertidig serverfejl</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Når du har lukket alle dine inkognitofaner, gemmes der hverken cookies, browser- eller søgehistorik for de sider, du besøger i inkognitotilstand. Dog gemmes alle de filer, du downloader, og bogmærker, du opretter.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ø</translation>
+<translation id="317583078218509884">De nye indstillinger for websitetilladelser træder i kraft, når du har genindlæst siden.</translation>
<translation id="3176929007561373547">Kontrollér dine proxyindstillinger, eller kontakt din netværksadministrator
for at sikre, at proxyserveren fungerer. Hvis du ikke mener,
at du skal bruge en proxyserver, skal du:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Ã…bn side i inkognitotilstand</translation>
-<translation id="3202578601642193415">Nyeste</translation>
+<translation id="320323717674993345">Annuller betaling</translation>
<translation id="3207960819495026254">Bogmærket</translation>
+<translation id="3225919329040284222">Serveren præsenterede et certifikat, der ikke svarer til de indbyggede forventninger. Disse forventninger medtages for bestemte websites med høj sikkerhed for at beskytte dig.</translation>
<translation id="3226128629678568754">Tryk på genindlæsningsknappen for at genindsende de data, der er nødvendige for at indlæse siden.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Oversættelsen mislykkedes, fordi siden allerede er på <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Indtast kontrolkoden for <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Registrer altid vigtigt indhold på dette website</translation>
<translation id="3254409185687681395">Tilføj denne side som bogmærke</translation>
<translation id="3270847123878663523">&amp;Fortryd omarrangering</translation>
<translation id="3282497668470633863">Tilføj navn på kort</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">indstillinger</translation>
<translation id="3345135638360864351">Din anmodning om at få adgang til dette website kunne ikke sendes til <ph name="NAME" />. Prøv igen.</translation>
<translation id="3355823806454867987">Skift indstillinger for proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />gemmer ikke<ph name="END_EMPHASIS" /> følgende oplysninger:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Din browserhistorik
+ <ph name="LIST_ITEM" />Cookies og websitedata
+ <ph name="LIST_ITEM" />Oplysninger, du angiver i formularer
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Urfejl</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> elementer mere...</translation>
<translation id="337363190475750230">Fjernet</translation>
<translation id="3377188786107721145">Det opstod en fejl ved parsing af politik</translation>
<translation id="3380365263193509176">Ukendt fejl</translation>
<translation id="3380864720620200369">Klient-id:</translation>
<translation id="3391030046425686457">Leveringsadresse</translation>
<translation id="3395827396354264108">Afhentningsmetode</translation>
-<translation id="340013220407300675">Angriberen prøver muligvis at stjæle dine oplysninger fra <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (f.eks. adgangskoder, beskeder eller kreditkort).</translation>
<translation id="3422248202833853650">Prøv at lukke programmer for at frigøre hukommelse.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> kan ikke læses i øjeblikket.</translation>
+<translation id="3427092606871434483">Tillad (standardindstilling)</translation>
<translation id="3427342743765426898">&amp;Annuller fortryd redigering</translation>
<translation id="3431636764301398940">Gem dette kort på denne enhed</translation>
<translation id="3435896845095436175">Aktivér</translation>
<translation id="3447661539832366887">Ejeren af denne enhed har lukket dinosaurspillet.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hent interval:</translation>
<translation id="3462200631372590220">Skjul avanceret</translation>
<translation id="3467763166455606212">Kortindehavers navn skal angives</translation>
<translation id="3478058380795961209">Udløbsmåned:</translation>
<translation id="3479539252931486093">Var dette uventet? <ph name="BEGIN_LINK" />Giv os gerne feedback<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ikke nu</translation>
-<translation id="348000606199325318">Nedbruds-id <ph name="CRASH_LOCAL_ID" /> (server-id: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Vi kan ikke få fat i din forælder på nuværende tidspunkt. Prøv igen.</translation>
<translation id="3528171143076753409">Serverens certifikat er ikke troværdigt.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Mindst 1 element på synkroniserede enheder}=1{1 element (og flere på synkroniserede enheder)}one{# element (og flere på synkroniserede enheder)}other{# elementer (og flere på synkroniserede enheder)}}</translation>
<translation id="3539171420378717834">Gem en kopi af dette kort på denne enhed</translation>
<translation id="3542684924769048008">Brug adgangskode til:</translation>
+<translation id="3545341443414427877">Der kan ikke oprettes forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da din computers dato og klokkeslæt (<ph name="DATE_AND_TIME" />) er forkerte. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Krypter alle synkroniserede data med din egen adgangssætning til synkronisering</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> mere...</translation>
-<translation id="3555561725129903880">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet tilhører <ph name="DOMAIN2" />. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Din administrator kan fjerne blokeringen for dig</translation>
<translation id="3566021033012934673">Din forbindelse er ikke privat</translation>
+<translation id="3569145463236695319">&lt;p&gt;Der kan ikke oprettes en privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da din computers dato og klokkeslæt (<ph name="DATE_AND_TIME" />) er forkerte.&lt;/p&gt;
+
+ &lt;p&gt;Tilpas dato og klokkeslæt i sektionen &lt;strong&gt;Generelt&lt;/strong&gt; i appen &lt;strong&gt;Indstillinger&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Tilføj navn</translation>
<translation id="3583757800736429874">&amp;Annuller fortryd flytning</translation>
<translation id="3586931643579894722">Skjul oplysninger</translation>
-<translation id="3587482841069643663">Alle</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Angiv en gyldig udløbsdato</translation>
<translation id="36224234498066874">Ryd browserdata...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Certifikatoplysninger</translation>
<translation id="3690164694835360974">Login er ikke sikkert</translation>
<translation id="3693415264595406141">Adgangskode:</translation>
-<translation id="3696411085566228381">ingen</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Indlæser...</translation>
<translation id="3712624925041724820">Licenserne er opbrugt</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Tjekke proxy-, firewall- og DNS-konfigurationen<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Hvis du forstår den sikkerhedsrisiko, du udsætter dig for, kan du <ph name="BEGIN_LINK" />gå til dette usikre website<ph name="END_LINK" />, inden de farlige programmer er fjernet.</translation>
<translation id="3739623965217189342">Link, du har kopieret</translation>
+<translation id="3744899669254331632">Du kan ikke gå til <ph name="SITE" /> lige nu, da websitet sendte krypterede loginoplysninger, som Chromium ikke kan behandle. Netværksfejl og angreb er normalt midlertidige, så denne side vil sandsynligvis fungere igen senere.</translation>
+<translation id="3748148204939282805">Brugere med ondsindede hensigter <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan narre dig til at gøre noget farligt såsom at installere software eller afsløre dine personlige oplysninger (f.eks. adgangskoder, telefonnumre eller kreditkort). <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Oversættelsen mislykkedes på grund af en serverfejl.</translation>
<translation id="3759461132968374835">Du har ingen nyligt rapporterede nedbrud. Nedbrud, der opstod, mens rapportering om nedbrud var deaktiveret, vises ikke her.</translation>
+<translation id="3778403066972421603">Vil du gemme dette kort på din Google-konto og på denne enhed?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Udløber <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Hvis du bruger en proxyserver...</translation>
<translation id="3828924085048779000">Tomme adgangssætninger er ikke tilladt.</translation>
-<translation id="3845539888601087042">Viser historik fra de enheder, hvor du er logget ind. <ph name="BEGIN_LINK" />FÃ¥ flere oplysninger<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Tilbage</translation>
<translation id="3858027520442213535">Opdater dato og tid</translation>
<translation id="3884278016824448484">Modstridende enheds-id</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Din anmodning om adgang til dette website er blevet sendt til <ph name="NAME" />.</translation>
<translation id="3890664840433101773">Tilføj e-mail</translation>
<translation id="3901925938762663762">Kortet er udløbet</translation>
-<translation id="3933571093587347751">{1,plural, =1{Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet tilsyneladende først gælder fra i morgen. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.}one{Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet tilsyneladende først gælder fra om # dag. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.}other{Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet tilsyneladende først gælder fra om # dage. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF-dokumentet kunne ikke indlæses</translation>
+<translation id="3945915738023014686">Uploadet nedbruds-id <ph name="CRASH_ID" /> (lokalt nedbruds-id: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da sikkerhedscertifikatet ikke angiver alternative navne på emner. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="3963721102035795474">Læser-tilstand</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ingen}=1{1 website }one{# website }other{# websites }}</translation>
<translation id="397105322502079400">Beregner...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> er blokeret</translation>
+<translation id="3987940399970879459">Mindre end 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 webside tæt på}one{# webside tæt på}other{# websider tæt på}}</translation>
<translation id="4021036232240155012">DNS er den netværkstjeneste, der oversætter navnet på et website til dets internetadresse.</translation>
<translation id="4030383055268325496">&amp;Fortryd tilføjelse</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Proxykonfiguration er angivet til at anvende en webadresse for .pac-script, ikke faste proxyservere.</translation>
<translation id="4098354747657067197">Misvisende website forude</translation>
<translation id="4103249731201008433">Enhedens serienummer er ugyldigt</translation>
+<translation id="410351446219883937">Autoplay</translation>
<translation id="4103763322291513355">GÃ¥ til &lt;strong&gt;chrome://policy&lt;/strong&gt; for at se listen over sortlistede webadresser og andre politikker, din systemadministrator har igangsat.</translation>
-<translation id="4110615724604346410">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet indeholder fejl. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Tillad altid på dette website</translation>
<translation id="4117700440116928470">Politikkens omfang understøttes ikke.</translation>
-<translation id="4118212371799607889">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da Chromium ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 anden/andet}one{# anden/andet}other{# andre}}</translation>
<translation id="4130226655945681476">Kontrollere netværkskabler, modem og router</translation>
+<translation id="413544239732274901">FÃ¥ flere oplysninger</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Brug globale standardindstillinger (registrer)</translation>
+<translation id="4165986682804962316">Indstillinger for website</translation>
<translation id="4169947484918424451">Skal Chromium gemme dette kort?</translation>
<translation id="4171400957073367226">Ugyldig verifikationssignatur</translation>
<translation id="4196861286325780578">&amp;Annuller fortryd flytning</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Kontrollere firewall- og antiviruskonfigurationer<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ingen}=1{1 app ($1)}=2{2 apps ($1, $2)}one{# app ($1, $2, $3)}other{# apps ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Nedbrud</translation>
+<translation id="422022731706691852">Brugere med ondsindede hensigter på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan forsøge at narre dig til at installere programmer, der giver en dårligere browsingoplevelse (f.eks. ved at ændre din startside eller vise flere annoncer på de websites, du besøger). <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Prøv at køre Netværksdiagnosticering<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Gyldig</translation>
<translation id="4250431568374086873">Din forbindelse til dette website er ikke helt sikker</translation>
<translation id="4250680216510889253">Nej</translation>
<translation id="425582637250725228">Ændringer, du har foretaget, gemmes muligvis ikke.</translation>
<translation id="4258748452823770588">Forkert signatur</translation>
+<translation id="4265872034478892965">Tilladt af din administrator</translation>
<translation id="4269787794583293679">(Intet brugernavn)</translation>
<translation id="4275830172053184480">Genstart din enhed</translation>
<translation id="4280429058323657511">udløber <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google Beskyttet browsing har for nylig <ph name="BEGIN_LINK" />fundet skadelige programmer<ph name="END_LINK" /> på <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Forslag fra forældre</translation>
<translation id="4304224509867189079">Log ind</translation>
-<translation id="432290197980158659">Serveren præsenterede et certifikat, der ikke svarer til de indbyggede forventninger. Disse forventninger medtages for bestemte websites med høj sikkerhed for at beskytte dig. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Bloker (standardindstilling)</translation>
<translation id="4325863107915753736">Artiklen blev ikke fundet.</translation>
<translation id="4326324639298822553">Kontrollér, om udløbsdatoen er korrekt, og prøv igen.</translation>
<translation id="4331708818696583467">Ikke sikker</translation>
<translation id="4356973930735388585">Hackere på dette website vil muligvis forsøge at installere skadelige programmer på din computer, som stjæler eller sletter dine oplysninger (f.eks. billeder, adgangskoder, beskeder og kreditkortoplysninger).</translation>
<translation id="4372948949327679948">Forventet <ph name="VALUE_TYPE" />-værdi.</translation>
+<translation id="4377125064752653719">Du har forsøgt at få fat på <ph name="DOMAIN" />, men serverens certifikat er blevet tilbagekaldt af udgiveren. Det betyder, at du bestemt ikke bør have tillid til serverens sikkerhedsoplysninger. Du kommunikerer muligvis med en hacker.</translation>
<translation id="4381091992796011497">Brugernavn:</translation>
<translation id="4394049700291259645">Deaktiver</translation>
<translation id="4406896451731180161">søgeresultater</translation>
+<translation id="4424024547088906515">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da Chrome ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> accepterede ikke dit logincertifikat, eller der er ikke angivet et.</translation>
<translation id="443673843213245140">Brug af en proxy er deaktiveret, men en eksplicit proxykonfiguration er angivet.</translation>
-<translation id="4492190037599258964">Søgeresultater for '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Valideringsfejl: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Kontakte systemadministratoren</translation>
<translation id="450710068430902550">Deling med administrator</translation>
<translation id="4515275063822566619">Kort og adresser er fra Chrome og din Google-konto (<ph name="ACCOUNT_EMAIL" />). Du kan administrere dem i <ph name="BEGIN_LINK" />Indstillinger<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detaljer</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Prøv at deaktivere dine udvidelser.</translation>
<translation id="457875822857220463">Levering</translation>
<translation id="4587425331216688090">Vil du fjerne adressen fra Chrome?</translation>
-<translation id="4589078953350245614">Du har forsøgt at få forbindelse til <ph name="DOMAIN" />, men serveren præsenterede et ugyldigt certifikat. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Din forbindelse til <ph name="DOMAIN" /> er krypteret ved hjælp af en moderne krypteringspakke.</translation>
<translation id="4594403342090139922">&amp;Fortryd sletning</translation>
<translation id="4619615317237390068">Faner fra andre enheder</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da sikkerhedscertifikatet indeholder fejl. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
+<translation id="4690462567478992370">Stop med at bruge et ugyldigt certifikat</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Din forbindelse blev afbrudt</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Køre Windows Netværksdiagnosticering<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Der er opstået en ukendt fejl.</translation>
<translation id="4800132727771399293">Kontrollér, om din kontrolkode og udløbsdato er korrekte, og prøv igen.</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Du kan ikke gå til <ph name="SITE" /> lige nu, da websitet sendte krypterede legitimationsoplysninger, som Google Chrome ikke kan håndtere. Netværksfejl og angreb er normalt midlertidige, så denne side vil sandsynligvis fungere senere.</translation>
<translation id="4813512666221746211">Netværksfejl</translation>
<translation id="4816492930507672669">Tilpas til siden</translation>
<translation id="483020001682031208">Der er ingen Fysisk web-sider at vise</translation>
<translation id="4850886885716139402">Vis</translation>
<translation id="4854362297993841467">Denne leveringsmetode er ikke tilgængelig. Prøv en anden metode.</translation>
<translation id="4858792381671956233">Du har spurgt dine forældre, om det er i orden at besøge dette website.</translation>
+<translation id="4863764087567530506">Dette indhold forsøger muligvis at narre dig til at installere software eller afsløre personlige oplysninger. <ph name="BEGIN_LINK" />Vis alligevel<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Søg i historikken</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{og 1 anden webside}one{og # anden webside}other{og # andre websider}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Denne side er oversat fra et ukendt sprog til <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Betaling</translation>
<translation id="4926049483395192435">Skal angives.</translation>
<translation id="495170559598752135">Handlinger</translation>
<translation id="4958444002117714549">Udvid liste</translation>
-<translation id="4962322354953122629">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da Chrome ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Genaktiver advarsler</translation>
<translation id="4989809363548539747">Dette plugin understøttes ikke</translation>
<translation id="5002932099480077015">Hvis denne indstilling er slået til, gemmer Chrome en kopi af dit kort på denne enhed for at gøre det hurtigere at udfylde formularer.</translation>
<translation id="5018422839182700155">Denne side kan ikke åbnes</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Læs din administrators politikker</translation>
<translation id="5029568752722684782">Slet kopi</translation>
<translation id="5031870354684148875">Om Google Oversæt</translation>
+<translation id="5039804452771397117">Tillad</translation>
<translation id="5040262127954254034">Beskyttelse af personlige oplysninger</translation>
<translation id="5045550434625856497">Ugyldig adgangskode</translation>
<translation id="5056549851600133418">Artikler til dig</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Tjekke proxy-adressen<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Ingen cookies}=1{1 website bruger cookies. }one{# website bruger cookies. }other{# websites bruger cookies. }}</translation>
<translation id="5087286274860437796">Serverens certifikatet er ikke gyldigt i øjeblikket.</translation>
<translation id="5087580092889165836">Tilføj kort</translation>
<translation id="5089810972385038852">Delstat</translation>
+<translation id="5094747076828555589">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da Chromium ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="5095208057601539847">Provins</translation>
<translation id="5115563688576182185">(64-bit)</translation>
<translation id="5141240743006678641">Krypter synkroniserede adgangskoder med dine Google-loginoplysninger</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-mail påkrævet</translation>
<translation id="5251803541071282808">Skyen</translation>
<translation id="5277279256032773186">Bruger du Chrome på arbejdet? Virksomheder kan administrere Chrome-indstillinger for deres medarbejdere. Få flere oplysninger</translation>
+<translation id="5297526204711817721">Din forbindelse til dette website er ikke privat. Du kan til enhver tid afslutte VR-tilstanden ved at tage headsettet af og trykke på Tilbage.</translation>
<translation id="5299298092464848405">Der opstod en fejl ved parsing af politik</translation>
-<translation id="5300589172476337783">Vis</translation>
<translation id="5308689395849655368">Rapportering af nedbrud er deaktiveret.</translation>
<translation id="5317780077021120954">Gem</translation>
<translation id="5327248766486351172">Navn</translation>
-<translation id="5337705430875057403">Hackere på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan narre dig til at gøre noget farligt, såsom at installere software eller afsløre dine personlige oplysninger (f.eks. adgangskoder, telefonnumre eller kreditkort).</translation>
-<translation id="5359637492792381994">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet ikke er gyldigt i øjeblikket. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Du kan ikke besøge <ph name="SITE" /> lige nu, da dets certifikat er blevet tilbagekaldt. Netværksfejl og angreb er normalt midlertidige, så siden vil sandsynligvis fungere igen senere.</translation>
<translation id="536296301121032821">Der kunne ikke gemmes indstillinger for politik</translation>
<translation id="5386426401304769735">Certifikatkæden for dette website indeholder et certifikat, der er signeret med SHA-1.</translation>
<translation id="5402410679244714488">Udløbsdato: <ph name="EXPIRATION_DATE_ABBR" />, sidst anvendt for mere end et år siden</translation>
+<translation id="540969355065856584">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da dens sikkerhedscertifikat ikke er gyldigt i øjeblikket. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
<translation id="5421136146218899937">Ryd browserdata...</translation>
<translation id="5430298929874300616">Fjern bogmærke</translation>
<translation id="5431657950005405462">Din fil blev ikke fundet</translation>
-<translation id="5435775191620395718">Viser historik fra denne enhed. <ph name="BEGIN_LINK" />FÃ¥ flere oplysninger<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Skemavalideringsfejl på "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Denne side fra <ph name="HOST_NAME" /> blev ikke fundet</translation>
<translation id="5455374756549232013">Forkert tidsstempel for politik</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> af <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Ugyldig</translation>
<translation id="5470861586879999274">&amp;Annuller fortryd redigering</translation>
<translation id="54817484435770891">Tilføj gyldig adresse</translation>
<translation id="5492298309214877701">Dette website på virksomhedens, organisationens eller skolens intranet har samme webadresse som et eksternt website.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Der kan ikke afhentes på denne adresse. Vælg en anden adresse.</translation>
<translation id="5572851009514199876">Start og log ind på Chrome, så Chrome kan kontrollere, om du har adgang til dette website.</translation>
<translation id="5580958916614886209">Kontrollér, om udløbsmåneden er korrekt, og prøv igen.</translation>
+<translation id="5586446728396275693">Der er ikke nogen gemte adresser</translation>
+<translation id="5595485650161345191">Rediger adresse</translation>
<translation id="560412284261940334">Administration er ikke understøttet</translation>
<translation id="5610142619324316209">Kontrollere forbindelsen</translation>
<translation id="5610807607761827392">Du kan administrere kort og adresser i <ph name="BEGIN_LINK" />Indstillinger<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Vil du forlade denne side?</translation>
<translation id="5629630648637658800">Der kunne ikke indlæses indstillinger for politik</translation>
<translation id="5631439013527180824">Ugyldigt token for enhedsadministration</translation>
+<translation id="5633066919399395251">Brugere med ondsindede hensigter, der i øjeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, kan forsøge at installere farlige programmer på din computer, der stjæler eller sletter dine oplysninger (f.eks. fotos, adgangskoder, beskeder og kreditkort). <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Placering</translation>
+<translation id="5659593005791499971">E-mail</translation>
<translation id="5669703222995421982">FÃ¥ tilpasset indhold</translation>
<translation id="5675650730144413517">Denne side virker ikke</translation>
-<translation id="5677928146339483299">Blokeret</translation>
-<translation id="5694783966845939798">Du forsøgte at få forbindelse til <ph name="DOMAIN" />, men serveren har præsenteret et certifikat, der er signeret med en svag signaturalgoritme (f.eks. SHA-1). Det betyder, at sikkerhedsoplysningerne fra serveren kan være forfalskede, og at serveren muligvis ikke er den server, du forventede (du kommunikerer muligvis med en hacker). <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Dette websites identitet er ikke blevet bekræftet.</translation>
+<translation id="5713016350996637505">Der er blevet blokeret vildledende indhold</translation>
<translation id="5720705177508910913">Aktuel bruger</translation>
<translation id="5732392974455271431">Dine forældre kan fjerne blokeringen for dig</translation>
<translation id="5763042198335101085">Angiv en gyldig mailadresse</translation>
<translation id="5765072501007116331">Vælg en adresse for at se leveringsmetoder og -krav</translation>
+<translation id="5778550464785688721">Fuld kontrol over MIDI</translation>
<translation id="5784606427469807560">Der opstod et problem under bekræftelsen af dit kort. Kontrollér, at du har forbindelse til internettet, og prøv igen.</translation>
<translation id="5785756445106461925">Desuden indeholder denne side andre ressourcer, som ikke er sikre. Disse ressourcer kan ses af andre under overførslen og kan ændres af en hacker, så siden ser anderledes ud.</translation>
<translation id="5786044859038896871">Skal dine kortoplysninger udfyldes?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Annuller fortryd tilføjelse</translation>
<translation id="5814352347845180253">Du kan miste adgangen til Premium-indhold på <ph name="SITE" /> og visse andre websites.</translation>
<translation id="5838278095973806738">Du bør ikke indtaste følsomme oplysninger på dette website (f.eks. adgangskoder eller kreditkortoplysninger), da de kan blive stjålet af hackere.</translation>
-<translation id="5843436854350372569">Du har forsøgt at få forbindelse til <ph name="DOMAIN" />, men serveren har præsenteret et certifikat med en svag nøgle. En hacker kan have knækket den private nøgle, og serveren er muligvis ikke den forventede server (du kommunikerer muligvis med en hacker). <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Der kan ikke oprettes forbindelse til dette website</translation>
<translation id="5869522115854928033">Gemte adgangskoder</translation>
<translation id="5872918882028971132">Forslag fra forældre</translation>
<translation id="5901630391730855834">Gul</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synkroniseret)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 i brug}one{# i brug}other{# i brug}}</translation>
<translation id="5926846154125914413">Du kan miste adgangen til Premium-indhold på visse websites.</translation>
<translation id="5959728338436674663">Send automatisk <ph name="BEGIN_WHITEPAPER_LINK" />nogle systemoplysninger og noget sideindhold<ph name="END_WHITEPAPER_LINK" /> til Google som en hjælp til at registrere skadelige apps og websites. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Uge</translation>
<translation id="5967867314010545767">Fjern fra historik</translation>
<translation id="5975083100439434680">Zoom ud</translation>
<translation id="598637245381783098">Betalingsappen kan ikke åbnes</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Side 1}one{Side #}other{Side #}}</translation>
<translation id="6017514345406065928">Grøn</translation>
+<translation id="6017850046339264347">Hackere på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan installere vildledende apps, der foregiver at være noget andet, eller som indsamler data, der kan anvendes til at overvåge dig. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synkroniseret)</translation>
<translation id="6027201098523975773">Angiv et navn</translation>
<translation id="6040143037577758943">Luk</translation>
<translation id="6042308850641462728">Mere</translation>
+<translation id="6047233362582046994">Hvis du er indforstået med de forbundne sikkerhedsrisici, kan du <ph name="BEGIN_LINK" />besøge dette website<ph name="END_LINK" />, inden de skadelige apps fjernes.</translation>
+<translation id="6051221802930200923">Du kan ikke besøge <ph name="SITE" /> lige nu, da websitet bruger certifikatlåsning. Netværksfejl og angreb er normalt midlertidige, så siden vil sandsynligvis fungere igen senere.</translation>
<translation id="6060685159320643512">Vær forsigtig. Disse eksperimenter kan være farlige</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ingen}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">Du har opnår adgang til indhold vha. et administratorcertifikat. De data, du angiver til <ph name="DOMAIN" />, kan indhentes af din administrator.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ingen}=1{1 adgangskode (synkroniseret)}one{# adgangskode (synkroniseret)}other{# adgangskoder (synkroniseret)}}</translation>
<translation id="6146055958333702838">Kontrollér eventuelle kabler, og genstart alle routere, modemmer eller andre
netværksenheder, du bruger.</translation>
<translation id="614940544461990577">Prøv at:</translation>
<translation id="6151417162996330722">Servercertifikatet har en gyldighedsperiode, der er for lang.</translation>
<translation id="6157877588268064908">Vælg en adresse for at se forsendelsesmetoder og -krav</translation>
+<translation id="6158003235852588289">Google Beskyttet browsing registrerede for nylig phishing på <ph name="SITE" />. Phishing-websites udgiver sig for at være andre websites med det formål at narre dig.</translation>
<translation id="6165508094623778733">Flere oplysninger</translation>
+<translation id="6169916984152623906">Nu kan du gå på nettet privat, og andre brugere på denne enhed kan ikke se din aktivitet. Downloads og bogmærker gemmes dog stadig.</translation>
<translation id="6177128806592000436">Din forbindelse til dette website er ikke sikker.</translation>
<translation id="6184817833369986695">(kohorte: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Kontrollér din internetforbindelse</translation>
<translation id="6218753634732582820">Vil du fjerne adressen fra Chromium?</translation>
+<translation id="6221345481584921695">Google Beskyttet browsing <ph name="BEGIN_LINK" />registrerede malware<ph name="END_LINK" /> på <ph name="SITE" /> for nylig. Websites, der normalt er sikre, inficeres undertiden med malware. Det skadelige indhold kommer fra <ph name="SUBRESOURCE_HOST" />, som er en kendt malwaredistributør.</translation>
<translation id="6251924700383757765">Privatlivspolitik</translation>
<translation id="6254436959401408446">Der er ikke nok hukommelse til at åbne denne side</translation>
<translation id="625755898061068298">Du har valgt at deaktivere sikkerhedsadvarsler for dette website.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Rediger bogmærke</translation>
<translation id="6410264514553301377">Indtast udløbsdatoen og kontrolkoden for <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Du har spurgt en af dine forældre, om det er i orden, at du besøger dette website.</translation>
-<translation id="6416403317709441254">Du kan ikke gå til <ph name="SITE" /> lige nu, da websitet sender krypterede loginoplysninger, som Chromium ikke kan behandle. Netværksfejl og hackerangreb er normalt midlertidige, så siden vil sandsynligvis fungere senere. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Kan ikke kontrollere, om certifikatet er tilbagekaldt.</translation>
<translation id="6433490469411711332">Rediger kontaktoplysninger</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> nægtede at oprette forbindelse.</translation>
<translation id="6446608382365791566">Tilføj flere oplysninger</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Bekræft genindsendelse af formular</translation>
<translation id="6456339708790392414">Din betaling</translation>
<translation id="6458467102616083041">Ignoreret, fordi standardsøgning er deaktiveret af politikken.</translation>
-<translation id="6462969404041126431">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da sikkerhedscertifikatet muligvis er blevet tilbagekaldt. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Enhedspolitikker</translation>
<translation id="6477321094435799029">Chrome registrerede usædvanlig kode på denne side og blokerede den for at beskytte dine personlige oplysninger (f.eks. adgangskoder, telefonnumre eller kreditkort).</translation>
<translation id="6489534406876378309">Start upload af nedbrud</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Udløbsdato: <ph name="EXPIRATION_DATE_ABBR" />. Sidst anvendt <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Din administrator har ikke godkendt det endnu</translation>
<translation id="6569060085658103619">Du ser en udvidelsesside</translation>
-<translation id="6593753688552673085">mindre end <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Dette indhold forsøger muligvis at installere farlig software på din enhed, der kan stjæle eller slette dine oplysninger. <ph name="BEGIN_LINK" />Vis alligevel<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Krypteringsmuligheder</translation>
<translation id="662080504995468778">Bliv her</translation>
<translation id="6626291197371920147">Tilføj gyldigt kortnummer</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> -søgning</translation>
+<translation id="6630809736994426279">Brugere med ondsindede hensigter, der i øjeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, kan forsøge at installere farlige programmer på din Mac, som stjæler eller sletter dine oplysninger (f.eks. fotos, adgangskoder, beskeder og kreditkort). <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Denne politik er forældet.</translation>
-<translation id="6652240803263749613">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da din computers operativsystem ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Vil du fjerne formularforslag fra Chromium?</translation>
<translation id="6685834062052613830">Log ud, og fuldfør konfigurationen</translation>
<translation id="6710213216561001401">Forrige</translation>
<translation id="6710594484020273272">&lt;Indtast søgeterm&gt;</translation>
<translation id="6711464428925977395">Der er noget galt med proxyserveren, eller adressen er forkert.</translation>
<translation id="6727102863431372879">Angiv</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ingen}=1{1 element}one{# element}other{# elementer}}</translation>
<translation id="674375294223700098">Ukendt fejl i servercertifikatet.</translation>
<translation id="6753269504797312559">Politikkens værdi</translation>
<translation id="6757797048963528358">Din enhed gik i dvale.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Tilpasnings-id</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Områdedata kunne ikke indlæses</translation>
+<translation id="6825578344716086703">Du forsøgte at få fat i <ph name="DOMAIN" />, men serveren præsenterede et certifikat, der er signeret med en svag signaturalgoritme (f.eks. SHA-1). Det betyder, at sikkerhedsoplysningerne fra serveren kan være forfalskede, og at serveren muligvis ikke er den server, som du forventede (du kommunikerer muligvis med en person med ondsindede hensigter).</translation>
+<translation id="6830728435402077660">Ikke sikker</translation>
<translation id="6831043979455480757">Oversæt</translation>
<translation id="6839929833149231406">Område</translation>
<translation id="6874604403660855544">&amp;Annuller fortryd tilføjelse</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Dit kort er bekræftet</translation>
<translation id="6897140037006041989">Brugeragent</translation>
<translation id="6915804003454593391">Bruger:</translation>
+<translation id="6945221475159498467">Vælg</translation>
<translation id="6948701128805548767">Vælg en adresse for at se afhentningsmetoder og -krav</translation>
<translation id="6957887021205513506">Serverens certifikat ser ud til at være en forfalskning.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">BÃ¥de faste proxyservere og en webadresse for .pac-script angives.</translation>
<translation id="6989763994942163495">Vis avancerede indstillinger...</translation>
<translation id="7000990526846637657">Der blev ikke fundet nogen poster i historikken</translation>
-<translation id="7009986207543992532">Du forsøgte at få forbindelse til <ph name="DOMAIN" />, men serveren præsenterede et certifikat, hvis gyldighedsperiode er for lang til at være pålidelig. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Din Google-konto kan have andre former for browserhistorik på <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />.</translation>
<translation id="7029809446516969842">Adgangskoder</translation>
+<translation id="7050187094878475250">Du forsøgte at gå til <ph name="DOMAIN" />, men serveren præsenterede et certifikat, hvis gyldighedsperiode er for lang til at være pålidelig.</translation>
+<translation id="7053983685419859001">Bloker</translation>
<translation id="7064851114919012435">Kontaktoplysninger</translation>
<translation id="7079718277001814089">Dette website indeholder malware</translation>
<translation id="7087282848513945231">Amt/region</translation>
-<translation id="7088615885725309056">Ældre</translation>
<translation id="7090678807593890770">Søg efter <ph name="LINK" /> på Google</translation>
+<translation id="7108819624672055576">Tilladt med en udvidelse</translation>
<translation id="7119414471315195487">Luk andre faner eller programmer</translation>
<translation id="7129409597930077180">Der kan ikke sendes til denne adresse. Vælg en anden adresse.</translation>
<translation id="7138472120740807366">Leveringsmetode</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Behandler</translation>
<translation id="724691107663265825">Det site, du er på vej til, indeholder malware</translation>
<translation id="724975217298816891">Opdater dine kortoplysninger ved at indtaste udløbsdatoen og kontrolkoden for <ph name="CREDIT_CARD" />. Når du bekræfter, deles dine kortoplysninger med dette website.</translation>
-<translation id="725866823122871198">Der kunne ikke oprettes en privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da dato og tid (<ph name="DATE_AND_TIME" />) på din enhed er forkerte.</translation>
+<translation id="7260504762447901703">Tilbagekald adgangstilladelsen</translation>
<translation id="7275334191706090484">Administrerede bogmærker</translation>
<translation id="7298195798382681320">Anbefalet</translation>
<translation id="7309308571273880165">Nedbrudsrapport registreret <ph name="CRASH_TIME" /> (upload, som brugeren anmodede om, er endnu ikke uploadet)</translation>
<translation id="7334320624316649418">&amp;Annuller fortryd omarrangering</translation>
<translation id="733923710415886693">Servercertifikatet blev ikke fremvist via Certifikatsgennemsigtighed.</translation>
-<translation id="7351800657706554155">Du kan ikke gå til <ph name="SITE" /> lige nu, da dette certifikat er blevet tilbagekaldt. Netværksfejl og hackerangreb er normalt midlertidige, så denne side vil sandsynligvis fungere senere. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Kommandolinje</translation>
<translation id="7372973238305370288">søgeresultat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nej</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Bekræft kort</translation>
-<translation id="7394102162464064926">Er du sikker på, at du vil slette disse sider fra din historik?
-
-Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</translation>
<translation id="7400418766976504921">Webadresse</translation>
<translation id="7419106976560586862">Profilsti</translation>
<translation id="7424977062513257142">En integreret side på denne webside siger:</translation>
@@ -688,6 +754,7 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="7444046173054089907">Dette website er blokeret</translation>
<translation id="7445762425076701745">Identiteten på den server, som du er tilknyttet, kan ikke bekræftes. Du er tilknyttet en server via et navn, der kun er gyldigt i dit netværk, og som en ekstern certifikatautoritet derfor ikke har mulighed for at bekræfte ejerskabet på. Da enkelte certifikatautoriteter alligevel udsteder certifikater for disse navne, kan vi på ingen måde sikre, at du er tilknyttet det tilsigtede website og ikke til en forbryder.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />FÃ¥ flere oplysninger<ph name="END_LINK" /> om dette problem.</translation>
+<translation id="7455133967321480974">Brug global standard (bloker)</translation>
<translation id="7460163899615895653">Dine seneste faner fra andre enheder vises her</translation>
<translation id="7469372306589899959">Bekræfter kort</translation>
<translation id="7481312909269577407">Frem</translation>
@@ -695,36 +762,43 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="7508255263130623398">Det returnerede enheds-id for politikken er tomt eller stemmer ikke overens med det nuværende enheds-id</translation>
<translation id="7514365320538308">Download</translation>
<translation id="7518003948725431193">Ingen webside fundet på webadressen: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Værdi</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
+<translation id="7542403920425041731">Når du har bekræftet, deles dine kortoplysninger med dette website.</translation>
<translation id="7542995811387359312">Automatisk udfyldning af kreditkort er deaktiveret, fordi formularen ikke bruger en sikker forbindelse.</translation>
<translation id="7543525346216957623">Spørg en af dine forældre</translation>
<translation id="7549584377607005141">Denne webside kræver data, du tidligere har indtastet, før den kan vises korrekt. Du kan sende disse data igen, men hvis du gør dette, gentager du enhver handling, som denne side tidligere har foretaget.</translation>
<translation id="7552846755917812628">Prøv de følgende tips:</translation>
<translation id="7554791636758816595">Ny fane</translation>
+<translation id="7567204685887185387">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da sikkerhedscertifikatet er udstedt på ulovlig vis. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> anden}one{<ph name="CONTACT_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> anden}other{<ph name="CONTACT_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> andre}}</translation>
<translation id="7568593326407688803">Denne side er på<ph name="ORIGINAL_LANGUAGE" />Vil du oversætte den?</translation>
<translation id="7569952961197462199">Vil du fjerne kreditkortet fra Chrome?</translation>
<translation id="7569983096843329377">Sort</translation>
<translation id="7578104083680115302">Betal hurtigt på websites og i apps på alle enheder ved hjælp af kort, du har gemt med Google.</translation>
<translation id="7588950540487816470">Fysisk web</translation>
<translation id="7592362899630581445">Begrænsningerne for serverens certifikatnavn er overtrådt.</translation>
+<translation id="7598391785903975535">Mindre end <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> kan i øjeblikket ikke behandle denne anmodning.</translation>
<translation id="7600965453749440009">Oversæt aldrig <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Værdien er uden for intervallet <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Udløbsdato: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Du har allerede data, der er krypteret med en anden version af adgangskoden til din Google-konto. Indtast adgangskoden i feltet nedenfor.</translation>
-<translation id="7634554953375732414">Din forbindelse til dette website er ikke privat.</translation>
<translation id="7637571805876720304">Vil du fjerne kreditkortet fra Chromium?</translation>
<translation id="765676359832457558">Skjul avancerede indstillinger...</translation>
<translation id="7658239707568436148">Annuller</translation>
+<translation id="7662298039739062396">Indstillingen styres af en udvidelse</translation>
<translation id="7667346355482952095">Det returnerede token for politikken er tomt eller stemmer ikke overens med det nuværende token</translation>
<translation id="7668654391829183341">Ukendt enhed</translation>
<translation id="7669271284792375604">Hackere på dette website kan forsøge at narre dig til at installere programmer, der skader din browseroplevelse (f.eks. ved at ændre din startside eller vise flere annoncer på de websites, du besøger).</translation>
<translation id="7674629440242451245">Er du interesseret i smarte nye Chrome-funktioner? Prøv vores udviklerkanal på chrome.com/dev.</translation>
<translation id="7682287625158474539">Forsendelse</translation>
+<translation id="7701040980221191251">Ingen</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Fortsæt til <ph name="SITE" /> (usikkert)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certifikat</translation>
+<translation id="7716147886133743102">Blokeret af din administrator</translation>
<translation id="7716424297397655342">Dette website kan ikke indlæses fra cachen</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Administreres ikke</translation>
<translation id="7755287808199759310">Din forælder kan fjerne blokeringen for dig</translation>
<translation id="7758069387465995638">Firewall- eller antivirussoftware kan have blokeret forbindelsen.</translation>
@@ -751,15 +825,15 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Bogmærker på mobil</translation>
<translation id="7961015016161918242">Aldrig</translation>
-<translation id="7962083544045318153">Nedbruds-id <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Oversæt altid <ph name="ORIGINAL_LANGUAGE" /> til <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ikke angivet</translation>
<translation id="800218591365569300">Prøv at lukke andre faner eller programmer for at frigøre hukommelse.</translation>
<translation id="8012647001091218357">Vi kan ikke få kontakt til dine forældre på nuværende tidspunkt. Prøv igen.</translation>
<translation id="8025119109950072390">Hackere på dette website kan narre dig til at gøre noget farligt, såsom at installere software eller afsløre dine personlige oplysninger (f.eks. adgangskoder, telefonnumre eller kreditkort).</translation>
-<translation id="803030522067524905">Google Beskyttet browsing har for nylig registreret phishing på <ph name="SITE" />. Phishingwebsites udgiver sig for at være andre websites for at narre dig. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Denne side er på <ph name="SOURCE_LANGUAGE" />. Vil du oversætte den til <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Spørg (standardindstilling)</translation>
<translation id="8041089156583427627">Send feedback</translation>
+<translation id="8041940743680923270">Brug global standard (spørg)</translation>
<translation id="8088680233425245692">Artiklen kunne ikke vises.</translation>
<translation id="8089520772729574115">mindre end 1 MB</translation>
<translation id="8091372947890762290">Aktivering afventer serveren</translation>
@@ -768,13 +842,14 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />DNS-adressen<ph name="END_ABBR" /> for <ph name="HOST_NAME" />s server blev ikke fundet.</translation>
<translation id="8149426793427495338">Din computer gik i dvale.</translation>
<translation id="8150722005171944719">Filen i <ph name="URL" /> kan ikke læses. Den kan være blevet fjernet, flyttet, eller også forhindrer filtilladelser muligvis adgangen.</translation>
+<translation id="8184538546369750125">Brug global standard (tillad)</translation>
+<translation id="8191494405820426728">Lokalt nedbruds-id <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Fortryd flytning</translation>
<translation id="8201077131113104583">Ugyldig webadresse til opdatering for udvidelse med id'et "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Ordreoversigt</translation>
<translation id="8218327578424803826">Tildelt placering:</translation>
<translation id="8225771182978767009">Den person, der har konfigureret denne computer, har valgt at blokere dette website.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Hackere, der i øjeblikket befinder sig på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, vil muligvis forsøge at installere skadelige programmer på din computer, som stjæler eller sletter dine oplysninger (f.eks. billeder, adgangskoder, beskeder og kreditkortoplysninger).</translation>
<translation id="8241707690549784388">Siden, du søger, benyttede oplysninger, du har indtastet. Vender du tilbage til denne side kan det betyde, at enhver handling, du har foretaget, skal gentages. Vil du fortsætte?</translation>
<translation id="8249320324621329438">Sidste hentet:</translation>
<translation id="8253091569723639551">Faktureringsadresse skal angives</translation>
@@ -782,6 +857,7 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="8289355894181816810">Kontakt din netværksadministrator, hvis du ikke er sikker på, hvad det betyder.</translation>
<translation id="8293206222192510085">Tilføj bogmærke</translation>
<translation id="8294431847097064396">Kilde</translation>
+<translation id="8306404619377842860">Der kan ikke oprettes en privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da enhedens dato og klokkeslæt (<ph name="DATE_AND_TIME" />) ikke er korrekte. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Oversættelsen mislykkedes på grund af problemer med netværksforbindelsen.</translation>
<translation id="8332188693563227489">Adgangen til <ph name="HOST_NAME" /> blev nægtet</translation>
<translation id="834457929814110454">Hvis du er indforstået med de forbundne sikkerhedsrisici, kan du <ph name="BEGIN_LINK" />besøge dette website<ph name="END_LINK" />, inden de skadelige programmer fjernes.</translation>
@@ -802,11 +878,9 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="8483780878231876732">Hvis du vil bruge kort fra din Google-konto, skal du logge ind i Chrome</translation>
<translation id="8488350697529856933">Gælder for</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> var for lang tid om at svare.</translation>
-<translation id="852346902619691059">Denne server kunne ikke bevise, at den tilhører <ph name="DOMAIN" />, da din enheds operativsystem ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse. <ph name="BEGIN_LEARN_MORE_LINK" />Få flere oplysninger<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Udløbsår</translation>
<translation id="8543181531796978784">Du kan <ph name="BEGIN_ERROR_LINK" />rapportere et registreringsproblem<ph name="END_ERROR_LINK" /> eller, hvis du forstår den sikkerhedsrisiko, du udsætter dig for, <ph name="BEGIN_LINK" />kan du gå til dette usikre website<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Oversættelsen mislykkedes, fordi sidens sprog ikke kunne fastslås.</translation>
-<translation id="8559762987265718583">Der kan ikke oprettes en privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, da tid og dato (<ph name="DATE_AND_TIME" />) på din enhed er forkerte.</translation>
<translation id="8571890674111243710">Oversætter siden til <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Tilføj tlf.nr.
</translation>
@@ -821,6 +895,7 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="8738058698779197622">For at kunne oprette en sikker forbindelse skal dit ur være indstillet korrekt. Det er vigtigt, da de certifikater, som websites bruger til at identificere sig selv, kun er gyldige i bestemte tidsperioder. Da uret på din enhed går forkert, kan Chromium ikke bekræfte disse certifikater.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;DNS-adressen&lt;/abbr&gt; for <ph name="HOST_NAME" /> blev ikke fundet. Diagnosticerer problemet.</translation>
<translation id="8759274551635299824">Kortet er udløbet</translation>
+<translation id="8761567432415473239">Beskyttet browsing i Google har for nylig <ph name="BEGIN_LINK" />fundet skadelige programmer<ph name="END_LINK" /> på <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Annuller fortryd sletning</translation>
<translation id="8800988563907321413">Her vises de forslag, der er tæt på dig</translation>
<translation id="8820817407110198400">Bogmærker</translation>
@@ -833,29 +908,30 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="8870413625673593573">Senest lukkede</translation>
<translation id="8874824191258364635">Angiv et gyldigt kortnummer</translation>
<translation id="8876793034577346603">Netværkskonfiguration kunne ikke parses.</translation>
-<translation id="8877192140621905067">Når du har bekræftet, deles dine kortoplysninger med dette website</translation>
<translation id="8889402386540077796">Farvetone</translation>
<translation id="8891727572606052622">Ugyldig proxytilstand.</translation>
<translation id="889901481107108152">Dette eksperiment er ikke tilgængeligt på din platform.</translation>
<translation id="8903921497873541725">Zoom ind</translation>
<translation id="8931333241327730545">Vil du gemme dette kort på din Google-konto?</translation>
<translation id="8932102934695377596">Dit ur er bagud</translation>
-<translation id="8954894007019320973">(Forts.)</translation>
<translation id="8971063699422889582">Serverens certifikat er udløbet.</translation>
<translation id="8986494364107987395">Send automatisk brugsstatistikker og nedbrudsrapporter til Google</translation>
-<translation id="8987927404178983737">MÃ¥ned</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Det website, du er på vej til, indeholder skadelige programmer</translation>
+<translation id="8997023839087525404">Serveren viste et certifikat, der ikke blev fremvist offentligt ved hjælp af politikken for Certifikatsgennemsigtighed. Dette påkræves for nogle certifikater for at sikre, at de er troværdige, og beskytter mod hackere.</translation>
<translation id="9001074447101275817">Proxyserveren <ph name="DOMAIN" /> kræver et brugernavn og en adgangskode.</translation>
+<translation id="9005998258318286617">PDF-dokumentet kunne ikke indlæses.</translation>
<translation id="901974403500617787">Markeringer, der gælder for hele systemet, kan kun indstilles af ejeren: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Kortets faktureringsadresse er obligatorisk</translation>
<translation id="9020542370529661692">Denne side er oversat til <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Sikkerhedsfejl</translation>
<translation id="9038649477754266430">Brug en forudsigelsestjeneste til hurtigere sideindlæsning</translation>
<translation id="9039213469156557790">Desuden indeholder denne side andre ressourcer, som ikke er sikre. Disse ressourcer kan ses af andre under overførslen og kan ændres af en hacker, så siden opfører sig anderledes.</translation>
-<translation id="9040185888511745258">Hackere, der befinder sig på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan forsøge at narre dig til at installere programmer, der skader din browseroplevelse (f.eks. ved at ændre din startside eller vise flere annoncer på de websites, du besøger).</translation>
+<translation id="9049981332609050619">Du har forsøgt at nå <ph name="DOMAIN" />, men serveren præsenterede et ugyldigt certifikat.</translation>
<translation id="9050666287014529139">Adgangssætning</translation>
<translation id="9065203028668620118">Rediger</translation>
<translation id="9068849894565669697">Vælg farve</translation>
+<translation id="9069693763241529744">Blokeret af en udvidelse</translation>
<translation id="9076283476770535406">Der er muligvis indhold for voksne på websitet</translation>
<translation id="9078964945751709336">Flere oplysninger kræves</translation>
<translation id="9103872766612412690"><ph name="SITE" /> bruger normalt kryptering til at beskytte dine oplysninger. Da Chromium forsøgte at oprette forbindelse til <ph name="SITE" /> denne gang, returnerede websitet usædvanlige og forkerte loginoplysninger. Dette kan skyldes, at en hacker forsøger at udgive sig for at være <ph name="SITE" />, eller at en Wi-Fi-loginskærm har forstyrret forbindelsen. Dine oplysninger er stadig sikre, idet Chromium afbrød forbindelsen, inden der blev udvekslet data.</translation>
@@ -864,16 +940,21 @@ Psst! Prøv at bruge Inkognitotilstand <ph name="SHORTCUT_KEY" /> næste gang.</
<translation id="9148507642005240123">&amp;Fortryd redigering</translation>
<translation id="9154194610265714752">Opdateret</translation>
<translation id="9157595877708044936">Konfigurerer...</translation>
+<translation id="9169664750068251925">Bloker altid på dette website</translation>
<translation id="9170848237812810038">&amp;Fortryd</translation>
<translation id="917450738466192189">Serverens certifikat er ugyldigt.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> anden}one{<ph name="SHIPPING_OPTION_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> anden}other{<ph name="SHIPPING_OPTION_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> andre}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> anvender en ikke-understøttet protokol.</translation>
<translation id="9205078245616868884">Dine data er krypteret med din adgangssætning til synkronisering. Indtast den for at starte synkroniseringen.</translation>
<translation id="9207861905230894330">Artiklen kunne ikke tilføjes.</translation>
+<translation id="9219103736887031265">Billeder</translation>
<translation id="933612690413056017">Der er ingen internetforbindelse</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">RYD FORMULAREN</translation>
<translation id="939736085109172342">Ny mappe</translation>
<translation id="941721044073577244">Det ser ud til, at du ikke har tilladelse til at se dette website</translation>
<translation id="969892804517981540">Officiel version</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ingen}=1{1 element}one{# element}other{# elementer}}</translation>
<translation id="988159990683914416">Udviklerversion</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_de.xtb b/chromium/components/strings/components_strings_de.xtb
index 9488eb2f1a8..16544a13fe6 100644
--- a/chromium/components/strings/components_strings_de.xtb
+++ b/chromium/components/strings/components_strings_de.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Im Uhrzeigersinn drehen</translation>
<translation id="1038842779957582377">Unbekannter Name</translation>
<translation id="1050038467049342496">Andere Apps schließen</translation>
-<translation id="1053591932240354961">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, weil die Website verschlüsselte Anmeldedaten gesendet hat, die von Google Chrome nicht verarbeitet werden können. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;Hinzufügen rückgängig machen</translation>
<translation id="10614374240317010">Nie speichern für…</translation>
<translation id="106701514854093668">Desktop-Lesezeichen</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Richtlinien-Cache einwandfrei</translation>
<translation id="113188000913989374">Unter <ph name="SITE" /> wird Folgendes angezeigt:</translation>
<translation id="1132774398110320017">AutoFill-Einstellungen für Chrome...</translation>
+<translation id="1150979032973867961">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird vom Betriebssystem Ihres Computers als nicht vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
+<translation id="1151972924205500581">Passwort erforderlich</translation>
<translation id="1152921474424827756">Rufen Sie eine <ph name="BEGIN_LINK" />im Cache gespeicherte Kopie<ph name="END_LINK" /> von <ph name="URL" /> auf.</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> hat die Verbindung unerwartet geschlossen.</translation>
<translation id="1161325031994447685">WLAN-Verbindung erneut herstellen</translation>
+<translation id="1165039591588034296">Fehler</translation>
<translation id="1175364870820465910">&amp;Drucken...</translation>
<translation id="1181037720776840403">Entfernen</translation>
<translation id="1184214524891303587">Informationen zu sicherheitsrelevanten Zwischenfällen <ph name="BEGIN_WHITEPAPER_LINK" />automatisch Google melden<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Mehr von dieser Website</translation>
<translation id="1206967143813997005">Erste Signatur ungültig</translation>
<translation id="1209206284964581585">Vorerst ausblenden</translation>
+<translation id="121201262018556460">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat jedoch ein Zertifikat mit einem schwachen Schlüssel übermittelt. Ein Hacker könnte den privaten Schlüssel geknackt haben, sodass es sich möglicherweise nicht um den erwarteten Server handelt, sondern Sie stattdessen mit einem Hacker kommunizieren.</translation>
<translation id="1219129156119358924">Systemsicherheit</translation>
<translation id="1227224963052638717">Unbekannte Richtlinie</translation>
<translation id="1227633850867390598">Wert ausblenden</translation>
<translation id="1228893227497259893">Falsche Entitätskennung</translation>
<translation id="1232569758102978740">Unbenannt</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronisiert)</translation>
<translation id="1263231323834454256">Leseliste</translation>
<translation id="1264126396475825575">Absturzbericht erfasst am <ph name="CRASH_TIME" />, wurde noch nicht hochgeladen oder wurde ignoriert</translation>
+<translation id="1281526147609854549">Ausgestellt von <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Gefährliche Inhalte blockiert</translation>
<translation id="1285320974508926690">Diese Website nie übersetzen</translation>
<translation id="129553762522093515">Kürzlich geschlossen</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Löschen Sie Ihre Cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Ihre Aktivitäten <ph name="BEGIN_EMPHASIS" />sind eventuell weiterhin sichtbar<ph name="END_EMPHASIS" /> für:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Von Ihnen besuchte Websites
+ <ph name="LIST_ITEM" />Ihren Arbeitgeber oder Ihre Bildungseinrichtung
+ <ph name="LIST_ITEM" />Ihren Internetanbieter
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Anmeldedomain:</translation>
<translation id="1340482604681802745">Abholadresse</translation>
<translation id="1344211575059133124">Offenbar benötigst du eine Berechtigung, um diese Website zu besuchen</translation>
<translation id="1344588688991793829">AutoFill-Einstellungen für Chromium...</translation>
+<translation id="1348198688976932919">Die Website, die Sie aufrufen möchten, enthält gefährliche Apps</translation>
<translation id="1374468813861204354">Vorschläge</translation>
<translation id="1375198122581997741">Informationen zur Version</translation>
<translation id="1377321085342047638">Kartennummer</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> hat keine Daten gesendet.</translation>
<translation id="1407135791313364759">Alle öffnen</translation>
<translation id="1413809658975081374">Datenschutzfehler</translation>
+<translation id="14171126816530869">Die Identität von <ph name="ORGANIZATION" /> bei <ph name="LOCALITY" /> wurde von <ph name="ISSUER" /> verifiziert.</translation>
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Drucken</translation>
-<translation id="1442912890475371290">Versuch zum <ph name="BEGIN_LINK" />Besuch einer Seite unter <ph name="DOMAIN" /><ph name="END_LINK" /> blockiert</translation>
-<translation id="1491663344921578213">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, weil die Website das Zertifikats-Pinning nutzt. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite später wahrscheinlich wieder funktioniert. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> weitere}other{<ph name="PAYMENT_METHOD_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> weitere}}</translation>
<translation id="1506687042165942984">Zeigt eine gespeicherte (veraltete) Kopie dieser Seite an</translation>
<translation id="1517433312004943670">Telefonnummer erforderlich</translation>
<translation id="1519264250979466059">Build-Datum</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Für diese Funktion muss JavaScript aktiviert sein.</translation>
<translation id="1555130319947370107">Blau</translation>
<translation id="1559528461873125649">Datei oder Verzeichnis nicht vorhanden</translation>
-<translation id="1559572115229829303">&lt;p&gt;Es kann keine private Verbindung zu <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hergestellt werden, weil Datum und Uhrzeit (<ph name="DATE_AND_TIME" />) Ihres Geräts falsch sind.&lt;/p&gt;
-
- &lt;p&gt;Stellen Sie in der App &lt;strong&gt;Einstellungen&lt;/strong&gt; im Bereich &lt;strong&gt;Allgemein&lt;/strong&gt; Datum und Uhrzeit richtig ein.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Fehler beim Anzeigen dieser Webseite.</translation>
<translation id="1592005682883173041">Zugriff auf lokale Daten</translation>
+<translation id="1594030484168838125">Auswählen</translation>
<translation id="161042844686301425">Cyan</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Möchten Sie, dass Chrome diese Karte speichert?</translation>
<translation id="1639239467298939599">Wird geladen...</translation>
<translation id="1640180200866533862">Nutzerrichtlinien</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Die Netzwerkkonfiguration ist ungültig und konnte nicht importiert werden.</translation>
<translation id="1644574205037202324">Verlauf</translation>
<translation id="1645368109819982629">Nicht unterstütztes Protokoll</translation>
+<translation id="1655462015569774233">{1,plural, =1{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist gestern abgelaufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. Die Uhr Ihres Computers ist derzeit auf <ph name="CURRENT_DATE" /> eingestellt. Ist das korrekt? Falls nicht, stellen Sie die Uhr Ihres Systems richtig ein und aktualisieren Sie anschließend diese Seite.}other{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist vor # Tagen abgelaufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. Die Uhr Ihres Computers ist derzeit auf <ph name="CURRENT_DATE" /> eingestellt. Ist das korrekt? Falls nicht, stellen Sie die Uhr Ihres Systems richtig ein und aktualisieren Sie anschließend diese Seite.}}</translation>
<translation id="1656489000284462475">Abholung</translation>
<translation id="1663943134801823270">Die Karten und Adressen stammen aus Chrome. Sie werden in den <ph name="BEGIN_LINK" />Einstellungen<ph name="END_LINK" /> verwaltet.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> schützt Ihre Daten in der Regel durch Verschlüsselung. Als Google Chrome dieses Mal versuchte, eine Verbindung zu <ph name="SITE" /> herzustellen, gab die Website ungewöhnliche und falsche Anmeldedaten zurück. Entweder versucht ein Angreifer, sich als <ph name="SITE" /> auszugeben, oder die Verbindung wurde durch eine WLAN-Anmeldeseite unterbrochen. Da Google Chrome die Verbindung vor dem Austausch von Daten unterbrochen hat, sind Ihre Informationen weiterhin sicher.</translation>
-<translation id="168328519870909584">Hacker, die derzeit auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> zugreifen, versuchen unter Umständen, gefährliche Programme auf Ihrem Gerät zu installieren, um Ihre Daten zu stehlen oder zu löschen, zum Beispiel Fotos, Passwörter, Nachrichten und Kreditkartendaten.</translation>
<translation id="168841957122794586">Das Serverzertifikat weist einen schwachen kryptografischen Schlüssel auf.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat gilt vermutlich erst ab morgen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.}other{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat gilt vermutlich erst in # Tagen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.}}</translation>
<translation id="1710259589646384581">Betriebssystem</translation>
<translation id="1721312023322545264">Du benötigst die Berechtigung von <ph name="NAME" />, um diese Website zu besuchen</translation>
<translation id="1721424275792716183">* Pflichtfeld</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Seite später herunterladen</translation>
<translation id="17513872634828108">Geöffnete Tabs</translation>
<translation id="1753706481035618306">Seitennummer</translation>
+<translation id="1763864636252898013">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird vom Betriebssystem Ihres Geräts als nicht vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Versuchen Sie, die Windows-Netzwerkdiagnose auszuführen.<ph name="END_LINK" /></translation>
<translation id="1783075131180517613">Synchronisierungs-Passphrase aktualisieren</translation>
<translation id="1787142507584202372">Hier werden Ihre offenen Tabs angezeigt</translation>
+<translation id="1789575671122666129">Pop-ups</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Name des Karteninhabers</translation>
-<translation id="1803678881841855883">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />Malware<ph name="END_LINK" /> auf <ph name="SITE" /> gefunden. Websites, die in der Regel sicher sind, können gelegentlich mit Malware infiziert sein. Der schädliche Inhalt stammt von <ph name="SUBRESOURCE_HOST" />, einem bekannten Verteiler von Malware. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Hinzugefügt: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Anfrage oder Anfrageparameter ungültig</translation>
<translation id="1826516787628120939">Überprüfung läuft</translation>
<translation id="1834321415901700177">Diese Website enthält schädliche Programme</translation>
+<translation id="1840414022444569775">Diese Kartennummer wird bereits verwendet</translation>
<translation id="1842969606798536927">Bezahlen</translation>
<translation id="1871208020102129563">Der Proxy ist zur Verwendung von festen Proxyservern konfiguriert, nicht zur Verwendung einer PAC-Skript-URL.</translation>
<translation id="1871284979644508959">Pflichtfeld</translation>
<translation id="187918866476621466">"Beim Start"-Seiten öffnen</translation>
<translation id="1883255238294161206">Liste ausblenden</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> weitere}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> weitere}}</translation>
<translation id="1898423065542865115">Filtern</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Keine}=1{1 Website}other{# Websites}}</translation>
<translation id="194030505837763158">Besuchen Sie die Seite <ph name="LINK" />.</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" />-Lesezeichen</translation>
<translation id="1973335181906896915">Fehler bei der Serialisierung</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Wird ignoriert, da sie von <ph name="POLICY_NAME" /> außer Kraft gesetzt wurde.</translation>
<translation id="2138201775715568214">Nach Physical Web-Seiten zu Objekten in der Nähe wird gesucht.</translation>
<translation id="213826338245044447">Mobile Lesezeichen</translation>
-<translation id="2148716181193084225">Heute</translation>
+<translation id="2147827593068025794">Hintergrundsynchronisierung</translation>
<translation id="2154054054215849342">Die Synchronisierung ist für Ihre Domain nicht verfügbar</translation>
<translation id="2154484045852737596">Karte bearbeiten</translation>
<translation id="2166049586286450108">Vollständiger Administratorzugriff</translation>
<translation id="2166378884831602661">Diese Website kann keine sichere Verbindung bereitstellen</translation>
<translation id="2181821976797666341">Richtlinien</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 Adresse}other{# Adressen}}</translation>
+<translation id="2187317261103489799">Erkennen (Standardeinstellung)</translation>
<translation id="2202020181578195191">Geben Sie ein gültiges Ablaufjahr ein</translation>
<translation id="2212735316055980242">Richtlinie nicht gefunden</translation>
<translation id="2213606439339815911">Einträge werden abgerufen...</translation>
+<translation id="2218879909401188352">Angreifer auf der Website <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> könnten gefährliche Apps installieren, die Ihr Gerät beschädigen, Ihrer Mobilfunkrechnung versteckte Kosten hinzufügen oder Ihre personenbezogenen Daten stehlen könnten. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Beheben Sie den Verbindungsfehler mithilfe der <ph name="BEGIN_LINK" />Diagnose-App<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Jetzt senden</translation>
<translation id="225207911366869382">Dieser Wert für die Richtlinie ist veraltet.</translation>
<translation id="2262243747453050782">HTTP-Fehler</translation>
+<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2282872951544483773">Nicht verfügbare Experimente</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> Element}other{<ph name="ITEM_COUNT" /> Elemente}}</translation>
<translation id="2292556288342944218">Ihre Internetverbindung ist gesperrt</translation>
<translation id="230155334948463882">Neue Karte?</translation>
-<translation id="2305919008529760154">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wurde möglicherweise in betrügerischer Absicht ausgegeben. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535">Für <ph name="DOMAIN" /> sind ein Nutzername und ein Passwort erforderlich.</translation>
-<translation id="2318774815570432836">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, da die Website HSTS verwendet. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Einstellung wird von Ihrem Administrator gesteuert</translation>
<translation id="2354001756790975382">Weitere Lesezeichen</translation>
+<translation id="2354430244986887761">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />schädliche Apps<ph name="END_LINK" /> auf der Website <ph name="SITE" /> gefunden.</translation>
<translation id="2355395290879513365">Angreifer können unter Umständen die Bilder sehen, die Sie sich auf dieser Website ansehen, und könnten dann versuchen, Sie durch Ändern der Bilder zu täuschen.</translation>
+<translation id="2356070529366658676">Fragen</translation>
+<translation id="2359629602545592467">Mehrere</translation>
<translation id="2359808026110333948">Weiter</translation>
<translation id="2365563543831475020">Absturzbericht erfasst am <ph name="CRASH_TIME" />, wurde nicht hochgeladen</translation>
<translation id="2367567093518048410">Ebene</translation>
-<translation id="2371153335857947666">{1,plural, =1{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist gestern abgelaufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. Die Uhr Ihres Computers ist derzeit auf <ph name="CURRENT_DATE" /> eingestellt. Ist das korrekt? Falls nicht, stellen Sie die Uhr Ihres Systems richtig ein und aktualisieren Sie anschließend diese Seite. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" />}other{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist vor # Tagen abgelaufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. Die Uhr Ihres Computers ist derzeit auf <ph name="CURRENT_DATE" /> eingestellt. Ist das korrekt? Falls nicht, stellen Sie die Uhr Ihres Systems richtig ein und aktualisieren Sie anschließend diese Seite. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">Keine Alternativen für die Benutzeroberfläche verfügbar</translation>
<translation id="2384307209577226199">Standardeinstellung durch Unternehmen</translation>
<translation id="2386255080630008482">Das Serverzertifikat wurde aufgehoben.</translation>
<translation id="2392959068659972793">Richtlinien ohne Wert zeigen</translation>
<translation id="239429038616798445">Diese Versandart ist nicht verfügbar. Bitte wählen Sie eine andere aus.</translation>
<translation id="2396249848217231973">&amp;Löschen rückgängig machen</translation>
-<translation id="2460160116472764928">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />Malware<ph name="END_LINK" /> auf <ph name="SITE" /> gefunden. Websites, die in der Regel sicher sind, können gelegentlich mit Malware infiziert sein. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wurde möglicherweise widerrufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="2463739503403862330">Ausfüllen</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Netzwerkdiagnose ausführen<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Ungültige Such-URL</translation>
+<translation id="2482878487686419369">Benachrichtigungen</translation>
<translation id="2491120439723279231">Das Serverzertifikat enthält Fehler.</translation>
<translation id="2495083838625180221">JSON-Parser</translation>
<translation id="2495093607237746763">Wenn Sie diese Option auswählen, speichert Chromium eine Kopie Ihrer Karte auf diesem Gerät, damit Formulare schneller ausgefüllt werden können.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Zurück</translation>
<translation id="2515629240566999685">Signal an Ihrem Standort prüfen</translation>
<translation id="2516305470678292029">Alternativen für die Benutzeroberfläche</translation>
+<translation id="2539524384386349900">Erkennen</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> hat eine ungültige Antwort gesendet.</translation>
-<translation id="2552545117464357659">Neuer</translation>
<translation id="2556876185419854533">&amp;Bearbeiten rückgängig machen</translation>
<translation id="2587730715158995865">Von <ph name="ARTICLE_PUBLISHER" />. Diese Meldung und <ph name="OTHER_ARTICLE_COUNT" /> weitere Meldungen lesen.</translation>
<translation id="2587841377698384444">Directory API-ID:</translation>
<translation id="2597378329261239068">Dieses Dokument ist passwortgeschützt. Geben Sie ein Passwort ein.</translation>
<translation id="2609632851001447353">Varianten</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Keine}=1{1 App ($1)}=2{2 Apps ($1, $2)}other{# Apps ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Ihre Uhr geht vor.</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Der Zugriff auf die Datei wurde verweigert.</translation>
<translation id="2653659639078652383">Senden</translation>
<translation id="2666117266261740852">Andere Tabs oder Apps schließen</translation>
+<translation id="2670429602441959756">Diese Seite enthält Funktionen, die noch nicht in VR unterstützt werden. Modus wird beendet…</translation>
<translation id="2674170444375937751">Möchten Sie diese Seiten wirklich aus dem Verlauf löschen?</translation>
<translation id="2677748264148917807">Verlassen</translation>
-<translation id="269990154133806163">Der Server hat ein Zertifikat übermittelt, das nicht gemäß der Richtlinien zur Zertifikatstransparenz öffentlich offengelegt wurde. Dies ist für einige Zertifikate jedoch eine Voraussetzung, mit der sichergestellt wird, dass sie vertrauenswürdig sind und vor Angriffen schützen. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Leseliste</translation>
<translation id="2704283930420550640">Wert stimmt nicht mit dem Format überein.</translation>
<translation id="2704951214193499422">Ihre Karte kann von Chromium zurzeit nicht bestätigt werden. Bitte versuchen Sie es später noch einmal.</translation>
<translation id="2705137772291741111">Die (im Cache) gespeicherte Kopie dieser Website war nicht lesbar.</translation>
<translation id="2709516037105925701">AutoFill</translation>
-<translation id="2712118517637785082">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, das vom Server übermittelte Zertifikat wurde jedoch vom entsprechenden Aussteller widerrufen. Das bedeutet, dass die vom Server übermittelten Sicherheitsinformationen nicht vertrauenswürdig sind. Möglicherweise kommunizieren Sie mit einem Hacker. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Berechtigung anfordern</translation>
<translation id="2713444072780614174">Weiß</translation>
<translation id="2720342946869265578">In der Nähe</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Fehlender Gerätedatensatz</translation>
<translation id="2784949926578158345">Verbindung wurde zurückgesetzt.</translation>
<translation id="2794233252405721443">Website blockiert</translation>
+<translation id="2799020568854403057">Die Website, die Sie aufrufen möchten, enthält schädliche Apps</translation>
+<translation id="2803306138276472711">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />Malware<ph name="END_LINK" /> auf <ph name="SITE" /> gefunden. Websites, die in der Regel sicher sind, können gelegentlich mit Malware infiziert sein.</translation>
<translation id="2824775600643448204">Adress- und Suchleiste</translation>
<translation id="2826760142808435982">Die Verbindung ist mit <ph name="CIPHER" /> verschlüsselt und authentifiziert und verwendet <ph name="KX" /> als Mechanismus für den Schlüsselaustausch.</translation>
<translation id="2835170189407361413">Formular leeren</translation>
+<translation id="2856444702002559011">Hacker könnten versuchen, Ihre Daten von <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> zu stehen, zum Beispiel Passwörter, Nachrichten oder Kreditkartendaten. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Nicht neu laden</translation>
<translation id="2900469785430194048">Beim Versuch, diese Webseite aufzurufen, hat Google Chrome das Arbeitsspeicherlimit erreicht.</translation>
<translation id="2909946352844186028">Eine Netzwerkänderung ist aufgetreten.</translation>
<translation id="2916038427272391327">Andere Programme schließen</translation>
<translation id="2922350208395188000">Das Serverzertifikat kann nicht überprüft werden.</translation>
<translation id="2928905813689894207">Rechnungsadresse</translation>
+<translation id="2941952326391522266">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat stammt von <ph name="DOMAIN2" />. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="2948083400971632585">Sie können alle für eine Verbindung konfigurierten Proxys auf der Seite "Einstellungen" deaktivieren.</translation>
<translation id="2955913368246107853">Suchleiste schließen</translation>
<translation id="2958431318199492670">Die Netzwerkkonfiguration stimmt nicht mit dem ONC-Standard überein. Die Konfiguration wird unter Umständen nicht vollständig importiert.</translation>
-<translation id="29611076221683977">Zurzeit auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> befindliche Angreifer versuchen unter Umständen, gefährliche Programme auf Ihrem Mac zu installieren, um Ihre Daten zu stehlen oder zu löschen, zum Beispiel Fotos, Passwörter, Nachrichten und Kreditkartendaten.</translation>
<translation id="2966678944701946121">Gültig bis: <ph name="EXPIRATION_DATE_ABBR" />, hinzugefügt: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Zum Herstellen einer sicheren Verbindung muss die Uhrzeit richtig eingestellt sein. Der Grund hierfür ist, dass Websites sich mithilfe von Zertifikaten identifizieren, die nur für einen bestimmten Zeitraum gelten. Da die Uhrzeit Ihres Geräts falsch ist, kann Google Chrome diese Zertifikate nicht bestätigen.</translation>
<translation id="2972581237482394796">&amp;Wiederholen</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Gültige Adresse eingeben</translation>
<translation id="2986368408720340940">Diese Abholoption ist nicht verfügbar. Bitte wählen Sie eine andere Option aus.</translation>
<translation id="2991174974383378012">Datenfreigabe an Websites</translation>
+<translation id="2991571918955627853">Sie können <ph name="SITE" /> derzeit nicht aufrufen, da die Website HSTS verwendet. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert.</translation>
<translation id="3005723025932146533">Gespeicherte Kopie anzeigen</translation>
<translation id="3008447029300691911">Geben Sie den CVC für <ph name="CREDIT_CARD" /> ein. Nach erfolgter Bestätigung werden die Kartendetails an diese Website weitergegeben.</translation>
<translation id="3010559122411665027">Listeneintrag "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatisch blockiert</translation>
<translation id="3024663005179499861">Falscher Richtlinientyp</translation>
<translation id="3032412215588512954">Möchten Sie diese Website neu laden?</translation>
<translation id="3037605927509011580">Oh nein!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{mindestens 1 Inhalt auf synchronisierten Geräten}=1{1 Inhalt (und weitere auf synchronisierten Geräten)}other{# Inhalte (und weitere auf synchronisierten Geräten)}}</translation>
<translation id="3041612393474885105">Zertifikatinformationen</translation>
<translation id="3063697135517575841">Ihre Karte kann von Chrome zurzeit nicht bestätigt werden. Bitte versuchen Sie es später noch einmal.</translation>
<translation id="3064966200440839136">Der Inkognitomodus wird beendet, um über eine externe Anwendung zu zahlen. Fortfahren?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Keine}=1{1 Passwort}other{# Passwörter}}</translation>
<translation id="3093245981617870298">Sie sind offline.</translation>
<translation id="3105172416063519923">Geräte-ID:</translation>
<translation id="3109728660330352905">Sie sind nicht zum Aufrufen dieser Seite autorisiert.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Versuchen Sie, die Verbindungsdiagnose auszuführen.<ph name="END_LINK" /></translation>
<translation id="3145945101586104090">Fehler beim Dekodieren der Antwort</translation>
<translation id="3150653042067488994">Vorübergehender Serverfehler</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Seiten, die Sie sich auf Inkognito-Tabs ansehen, werden nach dem Schließen aller Inkognito-Tabs nicht in Ihrem Browserverlauf, Cookiespeicher oder Suchverlauf gespeichert. Ihre Lesezeichen und heruntergeladenen Dateien bleiben erhalten.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Insel</translation>
+<translation id="317583078218509884">Neue Einstellungen zu Websiteberechtigungen werden nach dem Aktualisieren der Seite wirksam.</translation>
<translation id="3176929007561373547">Vergewissern Sie sich, dass der Proxyserver funktioniert. Überprüfen Sie die
Proxyeinstellungen oder wenden Sie sich an Ihren Netzwerkadministrator.
Falls Sie keinen Proxyserver verwenden möchten, deaktivieren Sie ihn wie
folgt: <ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Seite im Inkognitomodus öffnen</translation>
-<translation id="3202578601642193415">Neueste</translation>
+<translation id="320323717674993345">Zahlung abbrechen</translation>
<translation id="3207960819495026254">Mit einem Lesezeichen versehen</translation>
+<translation id="3225919329040284222">Der Server hat ein Zertifikat übermittelt, das nicht mit den integrierten Erwartungen übereinstimmt. Diese Erwartungen sind zu Ihrem Schutz in bestimmten Websites mit hohen Sicherheitsstandards enthalten.</translation>
<translation id="3226128629678568754">Klicken Sie auf die Schaltfläche zum erneuten Laden, um die für das Laden der Seite erforderlichen Daten erneut zu senden.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Die Ãœbersetzung ist fehlgeschlagen, weil die Seite bereits auf <ph name="LANGUAGE" /> ist.</translation>
<translation id="323107829343500871">CVC für <ph name="CREDIT_CARD" /> eingeben</translation>
+<translation id="3234666976984236645">Wichtige Inhalte auf dieser Website immer erkennen</translation>
<translation id="3254409185687681395">Lesezeichen für diese Seite erstellen</translation>
<translation id="3270847123878663523">&amp;Neu anordnen rückgängig machen</translation>
<translation id="3282497668470633863">Angabe für "Name auf der Karte" hinzufügen</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">Einstellungen</translation>
<translation id="3345135638360864351">Ihre Zugriffsanfrage für diese Website konnte nicht an <ph name="NAME" /> gesendet werden. Bitte versuchen Sie es erneut.</translation>
<translation id="3355823806454867987">Proxy-Einstellungen ändern...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />speichert die folgenden Informationen nicht<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Ihren Browserverlauf
+ <ph name="LIST_ITEM" />Cookies und Websitedaten
+ <ph name="LIST_ITEM" />In Formulare eingegebene Informationen
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Fehler bei der Uhrzeit</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> weitere Elemente…</translation>
<translation id="337363190475750230">Bereitstellung aufgehoben</translation>
<translation id="3377188786107721145">Fehler beim Parsen der Richtlinie</translation>
<translation id="3380365263193509176">Unbekannter Fehler</translation>
<translation id="3380864720620200369">Client-ID:</translation>
<translation id="3391030046425686457">Lieferadresse</translation>
<translation id="3395827396354264108">Abholoption</translation>
-<translation id="340013220407300675">Unbefugte Dritte könnten versuchen, Ihre Informationen von <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> zu stehlen, z. B. Passwörter, Nachrichten oder Kreditkartendaten.</translation>
<translation id="3422248202833853650">Versuchen Sie, andere Programme zu beenden, um Speicher freizugeben.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> ist momentan nicht erreichbar.</translation>
+<translation id="3427092606871434483">Zulassen (Standardeinstellung)</translation>
<translation id="3427342743765426898">&amp;Bearbeiten wiederholen</translation>
<translation id="3431636764301398940">Diese Karte für dieses Gerät speichern</translation>
<translation id="3435896845095436175">Aktivieren</translation>
<translation id="3447661539832366887">Der Besitzer dieses Geräts hat das Dinosaurier-Spiel deaktiviert.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Abrufintervall:</translation>
<translation id="3462200631372590220">Erweiterte Informationen ausblenden</translation>
<translation id="3467763166455606212">Name des Karteninhabers erforderlich</translation>
<translation id="3478058380795961209">Ablaufmonat</translation>
<translation id="3479539252931486093">Geschah dies unerwartet? <ph name="BEGIN_LINK" />Informieren Sie uns<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Jetzt nicht</translation>
-<translation id="348000606199325318">Absturz-ID <ph name="CRASH_LOCAL_ID" /> (Server-ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Wir können deinen Vater bzw. deine Mutter momentan nicht erreichen. Bitte versuche es später erneut.</translation>
<translation id="3528171143076753409">Serverzertifikat ist nicht vertrauenswürdig.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Mindestens 1 Eintrag auf synchronisierten Geräten}=1{1 Eintrag (und weitere auf synchronisierten Geräten)}other{# Einträge (und weitere auf synchronisierten Geräten)}}</translation>
<translation id="3539171420378717834">Kopie dieser Karte auf diesem Gerät speichern</translation>
<translation id="3542684924769048008">Passwort verwenden für:</translation>
+<translation id="3545341443414427877">Eine private Verbindung mit <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ist nicht möglich, da Datum und Uhrzeit Ihres Computers (<ph name="DATE_AND_TIME" />) falsch eingestellt sind. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Alle synchronisierten Daten mit Ihrer eigenen Synchronisierungspassphrase verschlüsseln</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> weitere...</translation>
-<translation id="3555561725129903880">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat stammt von <ph name="DOMAIN2" />. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Dein Administrator kann die Blockierung aufheben</translation>
<translation id="3566021033012934673">Dies ist keine sichere Verbindung</translation>
+<translation id="3569145463236695319">&lt;p&gt;Eine private Verbindung mit <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ist nicht möglich, da Datum und Uhrzeit Ihres Geräts (<ph name="DATE_AND_TIME" />) falsch eingestellt sind.&lt;/p&gt;
+
+ &lt;p&gt;Passen Sie Datum und Uhrzeit im Abschnitt &lt;strong&gt;Allgemein&lt;/strong&gt; der App &lt;strong&gt;Einstellungen&lt;/strong&gt; an.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Namen hinzufügen</translation>
<translation id="3583757800736429874">&amp;Verschieben wiederholen</translation>
<translation id="3586931643579894722">Details ausblenden</translation>
-<translation id="3587482841069643663">Alle</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Geben Sie ein gültiges Ablaufdatum ein</translation>
<translation id="36224234498066874">Browserdaten löschen...</translation>
@@ -321,7 +361,6 @@
<translation id="3681007416295224113">Zertifikatinformationen</translation>
<translation id="3690164694835360974">Log-in nicht sicher</translation>
<translation id="3693415264595406141">Passwort:</translation>
-<translation id="3696411085566228381">keine</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Wird geladen...</translation>
<translation id="3712624925041724820">Lizenzen aufgebraucht</translation>
@@ -329,12 +368,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Proxy, Firewall und DNS-Konfiguration prüfen<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Wenn Sie die Sicherheitsrisiken kennen, können Sie <ph name="BEGIN_LINK" />diese unsichere Website aufrufen<ph name="END_LINK" />, bevor die gefährlichen Programme entfernt wurden.</translation>
<translation id="3739623965217189342">Von Ihnen kopierter Link</translation>
+<translation id="3744899669254331632">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, weil die Website verschlüsselte Anmeldedaten gesendet hat, die von Chromium nicht verarbeitet werden können. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert.</translation>
+<translation id="3748148204939282805">Hacker könnten auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> etwa versuchen, Sie zur Installation von Software oder zur Herausgabe von Daten wie Passwörter, Telefonnummern oder Kreditkartendaten zu bewegen. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Aufgrund eines Serverfehlers ist die Ãœbersetzung fehlgeschlagen.</translation>
<translation id="3759461132968374835">Es liegen keine kürzlich gemeldeten Abstürze vor. Abstürze, die bei deaktivierter Absturzberichtsfunktion aufgetreten sind, werden hier nicht angezeigt.</translation>
+<translation id="3778403066972421603">Möchten Sie diese Karte in Ihrem Google-Konto und auf diesem Gerät speichern?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Ablaufdatum: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Falls Sie einen Proxyserver verwenden...</translation>
<translation id="3828924085048779000">Eine leere Passphrase ist nicht zulässig.</translation>
-<translation id="3845539888601087042">Der Verlauf für alle Geräte, auf denen Sie angemeldet sind, wird angezeigt. <ph name="BEGIN_LINK" />Weitere Informationen.<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Zurück</translation>
<translation id="3858027520442213535">Datum und Uhrzeit aktualisieren</translation>
<translation id="3884278016824448484">In Konflikt stehende Gerätekennung</translation>
@@ -342,11 +384,13 @@
<translation id="3886446263141354045">Deine Anfrage zum Zugriff auf diese Website wurde an <ph name="NAME" /> gesendet</translation>
<translation id="3890664840433101773">E-Mail-Adresse hinzufügen</translation>
<translation id="3901925938762663762">Die Karte ist abgelaufen.</translation>
-<translation id="3933571093587347751">{1,plural, =1{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat gilt vermutlich erst ab morgen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" />}other{Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat gilt vermutlich erst in # Tagen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">Fehler beim Laden des PDF-Dokuments</translation>
+<translation id="3945915738023014686">ID des hochgeladenen Absturzberichts: <ph name="CRASH_ID" /> (lokale Absturz-ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat gibt keine alternativen Namen an. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="3963721102035795474">Lesemodus</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Keine}=1{Von 1 Website }other{Von # Websites }}</translation>
<translation id="397105322502079400">Wird berechnet...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> ist gesperrt</translation>
+<translation id="3987940399970879459">Weniger als 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 Webseite in der Nähe}other{# Webseiten in der Nähe}}</translation>
<translation id="4021036232240155012">DNS ist der Netzwerkdienst, der den Namen einer Website in die entsprechende Internetadresse umwandelt.</translation>
<translation id="4030383055268325496">&amp;Hinzufügen rückgängig machen</translation>
@@ -357,56 +401,63 @@
<translation id="4079302484614802869">Die Proxy-Konfiguration ist auf die Verwendung einer PAC-Skript-URL und nicht die von festen Proxyservern eingestellt.</translation>
<translation id="4098354747657067197">Bei der aufgerufenen Website besteht Phishing-Verdacht!</translation>
<translation id="4103249731201008433">Seriennummer des Geräts ist ungültig.</translation>
+<translation id="410351446219883937">Autoplay</translation>
<translation id="4103763322291513355">Unter &lt;strong&gt;chrome://policy&lt;/strong&gt; finden Sie eine Liste der blockierten URLs und andere Richtlinien, die durch Ihren Systemadministrator erzwungen werden.</translation>
-<translation id="4110615724604346410">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat enthält Fehler. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Auf dieser Website immer zulassen</translation>
<translation id="4117700440116928470">Richtlinienbereich wird nicht unterstützt.</translation>
-<translation id="4118212371799607889">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird von Chromium nicht als vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 weiterer}other{# weitere}}</translation>
<translation id="4130226655945681476">Prüfen Sie Netzwerkkabel, Modem und Router</translation>
+<translation id="413544239732274901">Weitere Informationen</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Globalen Standard verwenden (Erkennen)</translation>
+<translation id="4165986682804962316">Website-Einstellungen</translation>
<translation id="4169947484918424451">Möchten Sie, dass Chromium diese Karte speichert?</translation>
<translation id="4171400957073367226">Ungültige Bestätigungssignatur</translation>
<translation id="4196861286325780578">&amp;Verschieben wiederholen</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Firewall und Antivirenkonfiguration prüfen<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{keine}=1{1 App ($1)}=2{2 Apps ($1, $2)}other{# Apps ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Abstürze</translation>
+<translation id="422022731706691852">Hacker könnten auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> versuchen, Sie zur Installation von Programmen zu bewegen, die sich nachteilig auf Ihre Browsernutzung auswirken. Dabei kann zum Beispiel Ihre Startseite geändert werden oder es erscheint zusätzliche Werbung auf von Ihnen besuchten Websites.<ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Versuchen Sie, die Netzwerkdiagnose auszuführen.<ph name="END_LINK" /></translation>
+<translation id="4235360514405112390">Gültig</translation>
<translation id="4250431568374086873">Die Verbindung zu dieser Website ist nicht uneingeschränkt sicher</translation>
<translation id="4250680216510889253">Nein</translation>
<translation id="425582637250725228">Die von Ihnen vorgenommenen Änderungen werden möglicherweise nicht gespeichert.</translation>
<translation id="4258748452823770588">Fehlerhafte Signatur</translation>
+<translation id="4265872034478892965">Von Ihrem Administrator zugelassen</translation>
<translation id="4269787794583293679">(Kein Nutzername)</translation>
<translation id="4275830172053184480">Gerät neu starten</translation>
<translation id="4280429058323657511">Gültig bis: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />schädliche Programme<ph name="END_LINK" /> auf <ph name="SITE" /> gefunden. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">Vorschläge für Eltern</translation>
<translation id="4304224509867189079">Anmelden</translation>
-<translation id="432290197980158659">Der Server hat ein Zertifikat übermittelt, das nicht mit den integrierten Erwartungen übereinstimmt. Diese Erwartungen sind zu Ihrem Schutz in bestimmten Websites mit hohen Sicherheitsstandards enthalten. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Blockieren (Standardeinstellung)</translation>
<translation id="4325863107915753736">Der Artikel wurde nicht gefunden.</translation>
<translation id="4326324639298822553">Prüfen Sie Ihr Ablaufdatum und versuchen Sie es dann erneut</translation>
<translation id="4331708818696583467">Nicht sicher</translation>
<translation id="4356973930735388585">Unbefugte Dritte auf dieser Website versuchen unter Umständen, gefährliche Programme auf Ihrem Computer zu installieren, um Ihre Daten zu stehlen oder zu löschen, zum Beispiel Fotos, Passwörter, Nachrichten und Kreditkartendaten.</translation>
<translation id="4372948949327679948">Erwarteter <ph name="VALUE_TYPE" />-Wert</translation>
+<translation id="4377125064752653719">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, das vom Server übermittelte Zertifikat wurde jedoch vom entsprechenden Aussteller widerrufen. Das bedeutet, dass die vom Server übermittelten Sicherheitsinformationen nicht vertrauenswürdig sind. Möglicherweise kommunizieren Sie mit einem Hacker.</translation>
<translation id="4381091992796011497">Nutzername:</translation>
<translation id="4394049700291259645">Deaktivieren</translation>
<translation id="4406896451731180161">Suchergebnisse</translation>
+<translation id="4424024547088906515">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird von Chrome als nicht vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> hat Ihr Anmeldezertifikat nicht akzeptiert oder es wurde keines bereitgestellt.</translation>
<translation id="443673843213245140">Die Proxy-Nutzung ist deaktiviert, es ist jedoch eine explizite Proxy-Konfiguration festgelegt.</translation>
-<translation id="4492190037599258964">Suchergebnisse für "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Fehler bei der Überprüfung: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Kontakt mit dem Systemadministrator aufnehmen</translation>
<translation id="450710068430902550">Datenfreigabe an Administrator</translation>
<translation id="4515275063822566619">Karten und Adressen stammen aus Chrome und aus Ihrem Google-Konto (<ph name="ACCOUNT_EMAIL" />). Sie können sie in den <ph name="BEGIN_LINK" />Einstellungen<ph name="END_LINK" /> verwalten.</translation>
<translation id="4522570452068850558">Details</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Deaktivieren Sie Ihre Erweiterungen.</translation>
<translation id="457875822857220463">Lieferung</translation>
<translation id="4587425331216688090">Adresse aus Chrome entfernen?</translation>
-<translation id="4589078953350245614">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat sich jedoch mit einem ungültigen Zertifikat ausgewiesen. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Ihre Verbindung zu <ph name="DOMAIN" /> ist mit einer modernen Codier-Suite verschlüsselt.</translation>
<translation id="4594403342090139922">&amp;Löschen rückgängig machen</translation>
<translation id="4619615317237390068">Tabs von anderen Geräten</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat enthält Fehler. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
+<translation id="4690462567478992370">Ungültiges Zertifikat nicht mehr verwenden</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Ihre Verbindung wurde unterbrochen</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows-Netzwerkdiagnose ausführen<ph name="END_LINK" /></translation>
@@ -423,21 +474,24 @@
<translation id="4771973620359291008">Ein unbekannter Fehler ist aufgetreten.</translation>
<translation id="4800132727771399293">Prüfen Sie Ihr Ablaufdatum und Ihren CVC und versuchen Sie es dann erneut.</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, da die Website verschlüsselte Anmeldedaten gesendet hat, die von Google Chrome nicht verarbeitet werden können. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert.</translation>
<translation id="4813512666221746211">Netzwerkfehler</translation>
<translation id="4816492930507672669">An Seite anpassen</translation>
<translation id="483020001682031208">Keine Physical Web-Seiten verfügbar</translation>
<translation id="4850886885716139402">Anzeigen</translation>
<translation id="4854362297993841467">Diese Lieferoption ist nicht verfügbar. Bitte wählen Sie eine andere Option aus.</translation>
<translation id="4858792381671956233">Du hast deine Eltern gefragt, ob du diese Website besuchen darfst</translation>
+<translation id="4863764087567530506">Mit diesen Inhalten wird möglicherweise versucht, Sie zu täuschen und so zur Installation von Software oder der Offenlegung personenbezogener Daten zu bringen. <ph name="BEGIN_LINK" />Trotzdem anzeigen<ph name="END_LINK" /></translation>
<translation id="4880827082731008257">Im Verlauf suchen</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{und 1 weitere Webseite}other{und # weitere Webseiten}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Diese Seite wurde von einer unbekannten Sprache in <ph name="LANGUAGE_LANGUAGE" /> übersetzt.</translation>
<translation id="4923459931733593730">Zahlung</translation>
<translation id="4926049483395192435">Angabe erforderlich</translation>
<translation id="495170559598752135">Aktionen</translation>
<translation id="4958444002117714549">Liste einblenden</translation>
-<translation id="4962322354953122629">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird von Chrome nicht als vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Warnmeldungen wieder aktivieren</translation>
<translation id="4989809363548539747">Dieses Plug-in wird nicht unterstützt</translation>
<translation id="5002932099480077015">Wenn diese Funktion aktiviert ist, speichert Chrome eine Kopie Ihrer Karte auf diesem Gerät, um ein Ausfüllen von Formularen zu beschleunigen.</translation>
<translation id="5018422839182700155">Diese Seite kann nicht geöffnet werden</translation>
@@ -445,14 +499,15 @@
<translation id="5023310440958281426">Informieren Sie sich über die von Ihrem Administrator festgelegten Richtlinien.</translation>
<translation id="5029568752722684782">Kopie löschen</translation>
<translation id="5031870354684148875">Ãœber Google Ãœbersetzer</translation>
+<translation id="5039804452771397117">Zulassen</translation>
<translation id="5040262127954254034">Datenschutz</translation>
<translation id="5045550434625856497">Falsches Passwort</translation>
<translation id="5056549851600133418">Artikel für Sie</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Proxyadresse prüfen<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Keine Cookies}=1{1 Website verwendet Cookies. }other{# Websites verwenden Cookies. }}</translation>
<translation id="5087286274860437796">Das Serverzertifikat ist zurzeit ungültig.</translation>
<translation id="5087580092889165836">Karte hinzufügen</translation>
<translation id="5089810972385038852">Bundesstaat/-land</translation>
+<translation id="5094747076828555589">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird von Chromium als nicht vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="5095208057601539847">Provinz</translation>
<translation id="5115563688576182185">(64-Bit)</translation>
<translation id="5141240743006678641">Synchronisierte Passwörter mit Ihren Google-Anmeldeinformationen verschlüsseln</translation>
@@ -468,24 +523,24 @@
<translation id="5222812217790122047">E-Mail-Adresse erforderlich</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Nutzen Sie Chrome bei der Arbeit? Unternehmen können Chrome-Einstellungen für ihre Mitarbeiter verwalten. Weitere Informationen</translation>
+<translation id="5297526204711817721">Ihre Verbindung zu dieser Website ist nicht sicher. Sie können den VR-Mode jederzeit verlassen, indem Sie das Headset abnehmen und auf "Zurück" klicken.</translation>
<translation id="5299298092464848405">Fehler beim Parsen der Richtlinie</translation>
-<translation id="5300589172476337783">Anzeigen</translation>
<translation id="5308689395849655368">Die Absturzberichtsfunktion ist deaktiviert.</translation>
<translation id="5317780077021120954">Speichern</translation>
<translation id="5327248766486351172">Name</translation>
-<translation id="5337705430875057403">Angreifer auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> versuchen unter Umständen auf betrügerische Weise, Sie zur Installation von Software zu bewegen oder Ihnen personenbezogene Daten zu entlocken, zum Beispiel Passwörter, Telefonnummern oder Kreditkartendaten.</translation>
-<translation id="5359637492792381994">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist zurzeit ungültig. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, da das Zertifikat widerrufen wurde. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert.</translation>
<translation id="536296301121032821">Fehler beim Speichern der Richtlinieneinstellungen</translation>
<translation id="5386426401304769735">Die Zertifikatskette für diese Website enthält ein Zertifikat mit SHA-1-Signatur.</translation>
<translation id="5402410679244714488">Gültig bis: <ph name="EXPIRATION_DATE_ABBR" />, vor über einem Jahr zuletzt verwendet</translation>
+<translation id="540969355065856584">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat ist zurzeit ungültig. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
<translation id="5421136146218899937">Browserdaten löschen...</translation>
<translation id="5430298929874300616">Lesezeichen löschen</translation>
<translation id="5431657950005405462">Ihre Datei wurde nicht gefunden</translation>
-<translation id="5435775191620395718">Der Verlauf für dieses Gerät wird angezeigt. <ph name="BEGIN_LINK" />Weitere Informationen.<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Schemavalidierungsfehler in "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Diese <ph name="HOST_NAME" />-Seite wurde nicht gefunden</translation>
<translation id="5455374756549232013">Zeitstempel der Richtlinie ist fehlerhaft.</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> von <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Ungültig</translation>
<translation id="5470861586879999274">&amp;Bearbeiten wiederholen</translation>
<translation id="54817484435770891">Gültige Adresse hinzufügen</translation>
<translation id="5492298309214877701">Diese Website im Intranet des Unternehmens, der Organisation oder der Schule hat die gleiche URL wie eine externe Website.
@@ -502,6 +557,8 @@
<translation id="5571083550517324815">Diese Abholadresse wird nicht unterstützt. Bitte wählen Sie eine andere Adresse aus.</translation>
<translation id="5572851009514199876">Melden Sie sich zuerst in Chrome an, damit überprüft werden kann, ob Sie auf diese Website zugreifen dürfen.</translation>
<translation id="5580958916614886209">Prüfen Sie Ihren Ablaufmonat und versuchen Sie es dann erneut</translation>
+<translation id="5586446728396275693">Keine gespeicherten Adressen</translation>
+<translation id="5595485650161345191">Adresse bearbeiten</translation>
<translation id="560412284261940334">Verwaltung wird nicht unterstützt.</translation>
<translation id="5610142619324316209">Verbindung prüfen</translation>
<translation id="5610807607761827392"><ph name="BEGIN_LINK" />Karten und Adressen können Sie in den Einstellungen verwalten.<ph name="END_LINK" /></translation>
@@ -509,15 +566,18 @@
<translation id="5622887735448669177">Möchten Sie diese Website verlassen?</translation>
<translation id="5629630648637658800">Fehler beim Laden der Richtlinieneinstellungen</translation>
<translation id="5631439013527180824">Ungültiges Management-Token für das Gerät</translation>
+<translation id="5633066919399395251">Zurzeit auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> befindliche Hacker könnten versuchen, gefährliche Programme auf Ihrem Computer zu installieren, um Daten wie Fotos, Passwörter, Nachrichten und Kreditkartendaten zu stehlen oder zu löschen. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Standort</translation>
+<translation id="5659593005791499971">E-Mail-Adresse</translation>
<translation id="5669703222995421982">Personalisierte Inhalte erhalten</translation>
<translation id="5675650730144413517">Diese Seite funktioniert nicht</translation>
-<translation id="5677928146339483299">Blockiert</translation>
-<translation id="5694783966845939798">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat jedoch ein Zertifikat übermittelt, das einen schwachen Signaturalgorithmus verwendet, zum Beispiel SHA-1. Das bedeutet, dass die vom Server übermittelten Sicherheitsinformationen gefälscht sein könnten und es sich möglicherweise gar nicht um den erwarteten Server handelt, sondern Sie mit einem Hacker kommunizieren. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">Die Identität dieser Website wurde nicht verifiziert.</translation>
+<translation id="5713016350996637505">Betrügerische Inhalte blockiert</translation>
<translation id="5720705177508910913">Aktueller Nutzer</translation>
<translation id="5732392974455271431">Deine Eltern können die Blockierung aufheben</translation>
<translation id="5763042198335101085">Geben Sie eine gültige E-Mail-Adresse ein</translation>
<translation id="5765072501007116331">Wählen Sie eine Adresse aus, um Lieferoptionen und -anforderungen zu sehen</translation>
+<translation id="5778550464785688721">MIDI-Geräte: volle Kontrolle</translation>
<translation id="5784606427469807560">Beim Bestätigen Ihrer Karte ist ein Problem aufgetreten. Überprüfen Sie Ihre Internetverbindung und versuchen Sie es noch einmal.</translation>
<translation id="5785756445106461925">Außerdem enthält diese Seite andere, nicht sichere Ressourcen. Diese Ressourcen können während der Übertragung von anderen Nutzern angezeigt und von Angreifern bearbeitet werden, die das Layout der Seite verändern.</translation>
<translation id="5786044859038896871">Möchten Sie Ihre Kreditkarteninformationen eingeben?</translation>
@@ -526,14 +586,14 @@
<translation id="5813119285467412249">&amp;Hinzufügen wiederholen</translation>
<translation id="5814352347845180253">Eventuell verlieren Sie den Zugriff auf Premiuminhalte von <ph name="SITE" /> und einigen anderen Websites.</translation>
<translation id="5838278095973806738">Sie sollten keine vertraulichen Informationen wie Passwörter oder Kreditkartennummern auf dieser Website eingeben, da sie von Angreifern gestohlen werden könnten.</translation>
-<translation id="5843436854350372569">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat jedoch ein Zertifikat mit einem schwachen Schlüssel übermittelt. Ein Hacker könnte den privaten Schlüssel geknackt haben, sodass es sich möglicherweise nicht um den erwarteten Server handelt, sondern Sie stattdessen mit einem Hacker kommunizieren. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">Diese Website ist nicht erreichbar</translation>
<translation id="5869522115854928033">Gespeicherte Passwörter</translation>
<translation id="5872918882028971132">Vorschläge für Eltern</translation>
<translation id="5901630391730855834">Gelb</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synchronisiert)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 wird verwendet}other{# werden verwendet}}</translation>
<translation id="5926846154125914413">Eventuell verlieren Sie den Zugriff auf Premiuminhalte von einigen Websites.</translation>
<translation id="5959728338436674663"><ph name="BEGIN_WHITEPAPER_LINK" />Ich möchte automatisch einige Systeminformationen und Seiteninhalte an Google senden<ph name="END_WHITEPAPER_LINK" />, um bei der Erfassung schädlicher Apps und Websites zu helfen. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Woche</translation>
<translation id="5967867314010545767">Aus Verlauf entfernen</translation>
<translation id="5975083100439434680">Verkleinern</translation>
<translation id="598637245381783098">Fehler beim Öffnen der Zahlungs-App</translation>
@@ -542,21 +602,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Seite 1}other{Seite #}}</translation>
<translation id="6017514345406065928">Grün</translation>
+<translation id="6017850046339264347">Angreifer auf der Website <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> könnten betrügerische Apps installieren, die scheinbar einem anderen Zweck dienen oder Daten sammeln, um Sie auszuspionieren. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synchronisiert)</translation>
<translation id="6027201098523975773">Geben Sie einen Namen ein</translation>
<translation id="6040143037577758943">Schließen</translation>
<translation id="6042308850641462728">Mehr</translation>
+<translation id="6047233362582046994">Wenn Sie die Sicherheitsrisiken kennen, können Sie <ph name="BEGIN_LINK" />diese Website aufrufen<ph name="END_LINK" />, bevor die schädlichen Apps entfernt wurden.</translation>
+<translation id="6051221802930200923">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, weil die Website das Zertifikats-Pinning nutzt. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert.</translation>
<translation id="6060685159320643512">Vorsichtig, diese Experimente können gefährlich sein!</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{keine}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Sie haben über ein vom Administrator bereitgestelltes Zertifikat auf Inhalte zugegriffen. Die Daten, die Sie innerhalb von <ph name="DOMAIN" /> bereitstellen, können von Ihrem Administrator abgefangen werden.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Keine}=1{1 Passwort (synchronisiert)}other{# Passwörter (synchronisiert)}}</translation>
<translation id="6146055958333702838">Überprüfen Sie alle Kabel und starten Sie alle verwendeten Router, Modems und
anderen Netzwerkgeräte neu.</translation>
<translation id="614940544461990577">Versuchen Sie Folgendes:</translation>
<translation id="6151417162996330722">Die Gültigkeitsdauer des Serverzertifikats ist zu lang.</translation>
<translation id="6157877588268064908">Wählen Sie eine Adresse aus, um Versandoptionen und -anforderungen zu sehen</translation>
+<translation id="6158003235852588289">Google Safe Browsing hat kürzlich Phishingaktivitäten auf <ph name="SITE" /> festgestellt. Phishingwebsites geben sich als andere Websites aus, um Sie zu täuschen.</translation>
<translation id="6165508094623778733">Weitere Informationen</translation>
+<translation id="6169916984152623906">Sie können jetzt privat surfen. Für andere Personen, die dieses Gerät nutzen, sind Ihre Aktivitäten nicht sichtbar. Ihre Downloads und Lesezeichen werden jedoch gespeichert.</translation>
<translation id="6177128806592000436">Die Verbindung zu dieser Website ist nicht sicher</translation>
<translation id="6184817833369986695">(Kohorte: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Bitte überprüfen Sie Ihre Internetverbindung.</translation>
<translation id="6218753634732582820">Adresse aus Chromium entfernen?</translation>
+<translation id="6221345481584921695">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />Malware<ph name="END_LINK" /> auf <ph name="SITE" /> gefunden. Websites, die in der Regel sicher sind, können gelegentlich mit Malware infiziert sein. Der schädliche Inhalt stammt von <ph name="SUBRESOURCE_HOST" />, einem bekannten Verteiler von Malware.</translation>
<translation id="6251924700383757765">Datenschutzerklärung</translation>
<translation id="6254436959401408446">Nicht genügend Speicher, um diese Seite zu öffnen</translation>
<translation id="625755898061068298">Sie haben die Sicherheitswarnmeldungen für diese Website deaktiviert.</translation>
@@ -582,15 +650,14 @@
<translation id="6404511346730675251">Lesezeichen bearbeiten</translation>
<translation id="6410264514553301377">Ablaufdatum und CVC für <ph name="CREDIT_CARD" /> eingeben</translation>
<translation id="6414888972213066896">Du hast ein Elternteil gefragt, ob du diese Website besuchen darfst</translation>
-<translation id="6416403317709441254">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, weil die Website verschlüsselte Anmeldedaten gesendet hat, die von Chromium nicht verarbeitet werden können. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">Überprüfung, ob das Zertifikat zurückgerufen wurde, nicht möglich</translation>
<translation id="6433490469411711332">Kontaktdaten bearbeiten</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> hat die Verbindung abgelehnt.</translation>
<translation id="6446608382365791566">Weitere Informationen hinzufügen</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Erneute Formular-Übermittlung bestätigen</translation>
<translation id="6456339708790392414">Bezahlung</translation>
<translation id="6458467102616083041">Ignoriert, da Standardsuche durch Richtlinie deaktiviert</translation>
-<translation id="6462969404041126431">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wurde möglicherweise widerrufen. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Geräterichtlinien</translation>
<translation id="6477321094435799029">Chrome hat auf dieser Seite ungewöhnlichen Code erfasst und diese Seite daher blockiert, um Ihre personenbezogenen Daten wie Passwörter, Telefonnummern oder Kreditkarteninformationen zu schützen.</translation>
<translation id="6489534406876378309">Hochladen von Abstürzen starten</translation>
@@ -602,20 +669,19 @@
<translation id="6556915248009097796">Gültig bis: <ph name="EXPIRATION_DATE_ABBR" />, zuletzt verwendet: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Der Administrator hat die Berechtigung noch nicht erteilt</translation>
<translation id="6569060085658103619">Dies ist eine Erweiterungsseite</translation>
-<translation id="6593753688552673085">weniger als <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Diese Inhalte versuchen möglicherweise, gefährliche Software auf Ihrem Gerät zu installieren, durch die Ihre Informationen gestohlen oder gelöscht werden. <ph name="BEGIN_LINK" />Trotzdem anzeigen<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">Verschlüsselungsoptionen</translation>
<translation id="662080504995468778">Bleiben</translation>
<translation id="6626291197371920147">Gültige Kartennummer hinzufügen</translation>
<translation id="6628463337424475685"><ph name="ENGINE" />-Suche</translation>
+<translation id="6630809736994426279">Zurzeit auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> befindliche Hacker könnten versuchen, gefährliche Programme auf Ihrem Mac zu installieren, um Daten wie Fotos, Passwörter, Nachrichten und Kreditkartendaten zu stehlen oder zu löschen. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Diese Richtlinie ist veraltet.</translation>
-<translation id="6652240803263749613">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird vom Betriebssystem Ihres Computers nicht als vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Vorschlag für das Formular aus Chromium entfernen?</translation>
<translation id="6685834062052613830">Abmelden und Einrichtung abschließen</translation>
<translation id="6710213216561001401">Zurück</translation>
<translation id="6710594484020273272">&lt;Suchbegriff eingeben&gt;</translation>
<translation id="6711464428925977395">Mit dem Proxyserver ist ein Problem aufgetreten oder die Adresse ist falsch.</translation>
<translation id="6727102863431372879">Festlegen</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{keine}=1{1 Inhalt}other{# Inhalte}}</translation>
<translation id="674375294223700098">Fehler wegen unbekanntem Serverzertifikat</translation>
<translation id="6753269504797312559">Wert der Richtlinie</translation>
<translation id="6757797048963528358">Ihr Gerät ist im Ruhemodus.</translation>
@@ -623,6 +689,8 @@
<translation id="6810899417690483278">Personalisierungs-ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Fehler beim Laden der Regionsdaten</translation>
+<translation id="6825578344716086703">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat jedoch ein Zertifikat übermittelt, das einen schwachen Signaturalgorithmus verwendet, zum Beispiel SHA-1. Das bedeutet, dass die vom Server übermittelten Sicherheitsinformationen gefälscht sein könnten und es sich möglicherweise gar nicht um den erwarteten Server handelt, sondern Sie mit einem Hacker kommunizieren.</translation>
+<translation id="6830728435402077660">Nicht sicher</translation>
<translation id="6831043979455480757">Ãœbersetzen</translation>
<translation id="6839929833149231406">Stadtteil</translation>
<translation id="6874604403660855544">&amp;Hinzufügen wiederholen</translation>
@@ -630,6 +698,7 @@
<translation id="6895330447102777224">Ihre Karte wurde bestätigt</translation>
<translation id="6897140037006041989">User-Agent</translation>
<translation id="6915804003454593391">Nutzer:</translation>
+<translation id="6945221475159498467">Auswählen</translation>
<translation id="6948701128805548767">Wählen Sie eine Adresse aus, um Abholoptionen und -anforderungen zu sehen</translation>
<translation id="6957887021205513506">Das Zertifikat des Servers ist möglicherweise eine Fälschung.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -638,15 +707,16 @@
<translation id="6973656660372572881">Sowohl feste Proxyserver als auch eine PAC-Skript-URL sind festgelegt.</translation>
<translation id="6989763994942163495">Erweiterte Einstellungen anzeigen</translation>
<translation id="7000990526846637657">Keine Verlaufseinträge gefunden</translation>
-<translation id="7009986207543992532">Sie haben versucht, <ph name="DOMAIN" /> aufzurufen. Der Server hat jedoch ein Zertifikat präsentiert, dessen Gültigkeitsdauer zu lang ist, um vertrauenswürdig zu sein.<ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Möglicherweise sind in Ihrem Google-Konto noch andere Formen des Browserverlaufs unter <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> vorhanden</translation>
<translation id="7029809446516969842">Passwörter</translation>
+<translation id="7050187094878475250">Sie haben versucht, <ph name="DOMAIN" /> zu erreichen. Der Server hat jedoch ein Zertifikat präsentiert, dessen Gültigkeitsdauer zu lang ist, um vertrauenswürdig zu sein.</translation>
+<translation id="7053983685419859001">Blockieren</translation>
<translation id="7064851114919012435">Kontaktdaten</translation>
<translation id="7079718277001814089">Diese Website enthält Malware</translation>
<translation id="7087282848513945231">Landkreis</translation>
-<translation id="7088615885725309056">Älter</translation>
<translation id="7090678807593890770">Auf Google nach <ph name="LINK" /> suchen</translation>
+<translation id="7108819624672055576">Von einer Erweiterung zugelassen</translation>
<translation id="7119414471315195487">Andere Tabs oder Programme schließen</translation>
<translation id="7129409597930077180">Der Versand an diese Adresse ist nicht möglich. Bitte wählen Sie eine andere Adresse aus.</translation>
<translation id="7138472120740807366">Lieferoption</translation>
@@ -664,22 +734,18 @@
<translation id="7220786058474068424">Verarbeitung läuft</translation>
<translation id="724691107663265825">Malware auf nachfolgender Website</translation>
<translation id="724975217298816891">Geben Sie das Gültigkeitsdatum und den CVC für <ph name="CREDIT_CARD" /> ein, um Ihre Kartendetails zu aktualisieren. Nach erfolgter Bestätigung werden die Kartendetails an diese Website weitergegeben.</translation>
-<translation id="725866823122871198">Es kann keine private Verbindung zu <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hergestellt werden, weil Datum und Uhrzeit Ihres Computers falsch sind (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="7260504762447901703">Zugriff entziehen</translation>
<translation id="7275334191706090484">Verwaltete Lesezeichen</translation>
<translation id="7298195798382681320">Empfohlen</translation>
<translation id="7309308571273880165">Absturzbericht erfasst: <ph name="CRASH_TIME" /> (Upload wurde vom Nutzer angefordert, aber noch nicht abgeschlossen)</translation>
<translation id="7334320624316649418">&amp;Neu anordnen wiederholen</translation>
<translation id="733923710415886693">Das Serverzertifikat wurde nicht über die Zertifikatstransparenz offengelegt.</translation>
-<translation id="7351800657706554155">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, da das Zertifikat dieser Website widerrufen wurde. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen.<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">Befehlszeile</translation>
<translation id="7372973238305370288">Suchergebnis</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nein</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Karte bestätigen</translation>
-<translation id="7394102162464064926">Möchten Sie diese Seiten wirklich aus Ihrem Verlauf löschen?
-
-Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_KEY" />).</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Profilpfad</translation>
<translation id="7424977062513257142">Auf einer in dieser Webseite eingebetteten Seite wird Folgendes angezeigt:</translation>
@@ -687,6 +753,7 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="7444046173054089907">Diese Website ist blockiert</translation>
<translation id="7445762425076701745">Die Identität des Servers, mit dem Sie verbunden sind, kann nicht vollständig überprüft werden. Sie sind mit einem Server verbunden, dessen Name nur innerhalb Ihres Netzwerks gültig ist und dessen Inhaberschaft von einer externen Zertifizierungsstelle nicht überprüft werden kann. Da einige Zertifizierungsstellen ungeachtet dessen dennoch Zertifikate für diese Namen ausstellen, gibt es keine Möglichkeit, sicherzustellen, dass Sie mit der gewünschten Website und nicht mit einem Angreifer verbunden sind.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Weitere Informationen<ph name="END_LINK" /> zu diesem Problem.</translation>
+<translation id="7455133967321480974">Globalen Standard verwenden (Blockieren)</translation>
<translation id="7460163899615895653">Ihre zuletzt geöffneten Tabs von anderen Geräten erscheinen hier</translation>
<translation id="7469372306589899959">Karte wird bestätigt</translation>
<translation id="7481312909269577407">Vorwärts</translation>
@@ -694,36 +761,43 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="7508255263130623398">Zurückgegebene Geräte-ID der Richtlinie ist leer oder entspricht nicht der aktuellen Geräte-ID</translation>
<translation id="7514365320538308">Herunterladen</translation>
<translation id="7518003948725431193">Für folgende Webadresse wurde keine Webseite gefunden: <ph name="URL" />.</translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Wert</translation>
<translation id="7537536606612762813">Verbindlich</translation>
+<translation id="7542403920425041731">Nach erfolgter Bestätigung werden die Kartendetails an diese Website weitergegeben.</translation>
<translation id="7542995811387359312">Die Funktion zur automatischen Ausfüllung der Kreditkartendaten ist deaktiviert, da dieses Formular keine sichere Verbindung nutzt.</translation>
<translation id="7543525346216957623">Frag deine Eltern</translation>
<translation id="7549584377607005141">Damit diese Webseite richtig angezeigt wird, werden die Daten benötigt, die Sie zuvor eingegeben haben. Sie können diese Daten erneut senden, dabei werden jedoch sämtliche Aktionen wiederholt, die zuvor durch diese Seite ausgeführt wurden.</translation>
<translation id="7552846755917812628">Probieren Sie folgende Tipps aus:</translation>
<translation id="7554791636758816595">Neuer Tab</translation>
+<translation id="7567204685887185387">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wurde möglicherweise in betrügerischer Absicht ausgegeben. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> weiterer}other{<ph name="CONTACT_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> weitere}}</translation>
<translation id="7568593326407688803">Diese Seite ist auf<ph name="ORIGINAL_LANGUAGE" />Soll sie übersetzt werden?</translation>
<translation id="7569952961197462199">Kreditkarte aus Chrome entfernen?</translation>
<translation id="7569983096843329377">Schwarz</translation>
<translation id="7578104083680115302">Mit Karten, die Sie bei Google gespeichert haben, können Sie schnell und geräteübergreifend auf Websites und in Apps bezahlen.</translation>
<translation id="7588950540487816470">Physical Web</translation>
<translation id="7592362899630581445">Das Serverzertifikat verstößt gegen Namensbeschränkungen.</translation>
+<translation id="7598391785903975535">Weniger als <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> kann diese Anfrage momentan nicht verarbeiten.</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> nie übersetzen</translation>
<translation id="7610193165460212391">Wert liegt außerhalb des zulässigen Bereichs (<ph name="VALUE" />).</translation>
<translation id="7613889955535752492">Gültig bis: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Sie verfügen bereits über Daten, die mit einem vorherigen Passwort für Ihr Google-Konto verschlüsselt wurden. Bitte geben Sie dieses Passwort unten ein.</translation>
-<translation id="7634554953375732414">Die Verbindung zu dieser Website ist nicht sicher.</translation>
<translation id="7637571805876720304">Kreditkarte aus Chromium entfernen?</translation>
<translation id="765676359832457558">Erweiterte Einstellungen ausblenden</translation>
<translation id="7658239707568436148">Abbrechen</translation>
+<translation id="7662298039739062396">Einstellung wird von einer Erweiterung gesteuert</translation>
<translation id="7667346355482952095">Zurückgegebenes Token der Richtlinie ist leer oder entspricht nicht dem aktuellen Token</translation>
<translation id="7668654391829183341">Unbekanntes Gerät</translation>
<translation id="7669271284792375604">Unbefugte Dritte auf dieser Website versuchen eventuell, Sie zur Installation von Programmen zu bewegen, die sich nachteilig auf Ihre Browsernutzung auswirken. Dabei kann zum Beispiel Ihre Startseite geändert werden oder es erscheinen zusätzliche Anzeigen auf von Ihnen besuchten Websites.</translation>
<translation id="7674629440242451245">Interessiert an coolen neuen Chrome-Funktionen? Testen Sie unsere Dev-Version unter chrome.com/dev.</translation>
<translation id="7682287625158474539">Versand</translation>
+<translation id="7701040980221191251">Keine</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Weiter zu <ph name="SITE" /> (unsicher)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Zertifikat</translation>
+<translation id="7716147886133743102">Von Ihrem Administrator blockiert</translation>
<translation id="7716424297397655342">Diese Website kann nicht aus dem Cache geladen werden</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Nicht verwaltet</translation>
<translation id="7755287808199759310">Deine Eltern können die Blockierung aufheben</translation>
<translation id="7758069387465995638">Möglicherweise wurde die Verbindung von einer Firewall oder Antivirensoftware blockiert.</translation>
@@ -750,15 +824,15 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="7951415247503192394">(32-Bit)</translation>
<translation id="7956713633345437162">Mobile Lesezeichen</translation>
<translation id="7961015016161918242">Nie</translation>
-<translation id="7962083544045318153">Absturz-ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> immer auf <ph name="TARGET_LANGUAGE" /> übersetzen</translation>
<translation id="7995512525968007366">Nicht angegeben</translation>
<translation id="800218591365569300">Versuchen Sie, andere Tabs oder Programme zu schließen, um Speicher freizugeben.</translation>
<translation id="8012647001091218357">Wir können deine Eltern momentan nicht erreichen. Bitte versuche es später erneut.</translation>
<translation id="8025119109950072390">Unbefugte Dritte auf dieser Website versuchen unter Umständen auf betrügerische Weise, Sie zur Installation von Software zu bewegen oder Ihnen personenbezogene Daten zu entlocken, zum Beispiel Passwörter, Telefonnummern oder Kreditkartendaten.</translation>
-<translation id="803030522067524905">Google Safe Browsing hat kürzlich Phishing auf <ph name="SITE" /> gefunden. Phishing-Websites täuschen die Nutzer, indem sie sich als andere Websites ausgeben. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Diese Seite ist auf <ph name="SOURCE_LANGUAGE" />. In folgende Sprache übersetzen: <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Nachfragen (Standardeinstellung)</translation>
<translation id="8041089156583427627">Feedback geben</translation>
+<translation id="8041940743680923270">Globalen Standard verwenden (Fragen)</translation>
<translation id="8088680233425245692">Der Artikel kann nicht angezeigt werden.</translation>
<translation id="8089520772729574115">weniger als 1 MB</translation>
<translation id="8091372947890762290">Aktivierung auf dem Server steht noch aus.</translation>
@@ -767,13 +841,14 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="8134994873729925007">Die <ph name="BEGIN_ABBR" />DNS-Adresse<ph name="END_ABBR" /> des Servers von <ph name="HOST_NAME" /> wurde nicht gefunden.</translation>
<translation id="8149426793427495338">Ihr Computer ist im Ruhemodus.</translation>
<translation id="8150722005171944719">Die Datei unter <ph name="URL" /> kann nicht gelesen werden. Sie wurde möglicherweise entfernt oder verschoben oder die Dateiberechtigungen verhindern den Zugriff.</translation>
+<translation id="8184538546369750125">Globalen Standard verwenden (Zulassen)</translation>
+<translation id="8191494405820426728">Lokale Absturz-ID: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Verschieben rückgängig machen</translation>
<translation id="8201077131113104583">Ungültige Update-URL für Erweiterung mit der ID "<ph name="EXTENSION_ID" />"</translation>
<translation id="8202097416529803614">Zusammenfassung der Bestellung</translation>
<translation id="8218327578424803826">Zugewiesener Standort:</translation>
<translation id="8225771182978767009">Die Person, die diesen Computer eingerichtet hat, hat diese Website gesperrt.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Zurzeit auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> befindliche Angreifer versuchen unter Umständen, gefährliche Programme auf Ihrem Computer zu installieren, um Ihre Daten zu stehlen oder zu löschen, zum Beispiel Fotos, Passwörter, Nachrichten und Kreditkartendaten.</translation>
<translation id="8241707690549784388">Die gesuchte Seite hat die von Ihnen eingegebenen Informationen verwendet bzw. verarbeitet. Wenn Sie zu dieser Seite zurückgehen, wird möglicherweise eine bereits ausgeführte Aktion wiederholt. Möchten Sie fortfahren?</translation>
<translation id="8249320324621329438">Letzter Abruf:</translation>
<translation id="8253091569723639551">Rechnungsadresse ist erforderlich</translation>
@@ -781,6 +856,7 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="8289355894181816810">Wenn Sie weitere Informationen dazu benötigen, kann Ihnen Ihr Netzwerkadministrator weiterhelfen.</translation>
<translation id="8293206222192510085">Lesezeichen hinzufügen</translation>
<translation id="8294431847097064396">Quelle</translation>
+<translation id="8306404619377842860">Eine private Verbindung mit <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ist nicht möglich, da Datum und Uhrzeit Ihres Geräts (<ph name="DATE_AND_TIME" />) falsch eingestellt sind. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Die Ãœbersetzung ist aufgrund eines Problems mit der Netzwerkverbindung fehlgeschlagen.</translation>
<translation id="8332188693563227489">Der Zugriff auf <ph name="HOST_NAME" /> wurde verweigert</translation>
<translation id="834457929814110454">Wenn Sie die Sicherheitsrisiken kennen, können Sie <ph name="BEGIN_LINK" />diese Website aufrufen<ph name="END_LINK" />, bevor die schädlichen Programme entfernt wurden.</translation>
@@ -801,11 +877,9 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="8483780878231876732">Melden Sie sich in Chrome an, um in Ihrem Google-Konto gespeicherte Kreditkarten zu verwenden</translation>
<translation id="8488350697529856933">Gilt für</translation>
<translation id="8498891568109133222">Die Antwort von <ph name="HOST_NAME" /> hat zu lange gedauert.</translation>
-<translation id="852346902619691059">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird vom Betriebssystem Ihres Geräts nicht als vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Ablaufjahr</translation>
<translation id="8543181531796978784">Sie können ein <ph name="BEGIN_ERROR_LINK" />Erkennungsproblem melden<ph name="END_ERROR_LINK" /> oder, wenn Sie die Sicherheitsrisiken kennen, <ph name="BEGIN_LINK" />diese unsichere Website aufrufen<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Die Ãœbersetzung ist fehlgeschlagen, weil die Sprache der Seite nicht ermittelt werden konnte.</translation>
-<translation id="8559762987265718583">Es kann keine private Verbindung zu <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hergestellt werden, weil Datum und Uhrzeit Ihres Geräts falsch sind (<ph name="DATE_AND_TIME" />).</translation>
<translation id="8571890674111243710">Seite wird in folgende Sprache übersetzt: <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Weitere Nummer
</translation>
@@ -820,6 +894,7 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="8738058698779197622">Zum Aufbau einer sicheren Verbindung muss die Uhrzeit richtig eingestellt sein. Der Grund hierfür ist, dass Websites sich mithilfe von Zertifikaten identifizieren, die nur für einen bestimmten Zeitraum gelten. Da die Uhrzeit Ihres Geräts falsch ist, kann Chromium diese Zertifikate nicht bestätigen.</translation>
<translation id="8740359287975076522">Die &lt;abbr id="dnsDefinition"&gt;DNS-Adresse&lt;/abbr&gt; von <ph name="HOST_NAME" /> wurde nicht gefunden. Eine Problemdiagnose wird durchgeführt.</translation>
<translation id="8759274551635299824">Diese Karte ist abgelaufen</translation>
+<translation id="8761567432415473239">Google Safe Browsing hat vor Kurzem <ph name="BEGIN_LINK" />schädliche Programme<ph name="END_LINK" /> auf <ph name="SITE" /> gefunden.</translation>
<translation id="8790007591277257123">&amp;Löschen wiederholen</translation>
<translation id="8800988563907321413">Hier werden Ihre Vorschläge in der Nähe angezeigt</translation>
<translation id="8820817407110198400">Lesezeichen</translation>
@@ -832,29 +907,30 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="8870413625673593573">Kürzlich geschlossen</translation>
<translation id="8874824191258364635">Geben Sie eine gültige Kartennummer ein</translation>
<translation id="8876793034577346603">Fehler beim Parsen der Netzwerkkonfiguration</translation>
-<translation id="8877192140621905067">Nach erfolgter Bestätigung werden die Kartendetails an diese Website weitergegeben</translation>
<translation id="8889402386540077796">Farbton</translation>
<translation id="8891727572606052622">Ungültiger Proxy-Modus</translation>
<translation id="889901481107108152">Leider steht dieses Experiment auf Ihrer Plattform nicht zur Verfügung.</translation>
<translation id="8903921497873541725">Vergrößern</translation>
<translation id="8931333241327730545">Möchten Sie diese Karte in Ihrem Google-Konto speichern?</translation>
<translation id="8932102934695377596">Ihre Uhr geht nach.</translation>
-<translation id="8954894007019320973">(Fortsetzung)</translation>
<translation id="8971063699422889582">Das Serverzertifikat ist abgelaufen.</translation>
<translation id="8986494364107987395">Nutzungsstatistiken und Absturzberichte automatisch an Google senden</translation>
-<translation id="8987927404178983737">Monat</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Die Website, die Sie aufrufen möchten, enthält schädliche Programme.</translation>
+<translation id="8997023839087525404">Der Server präsentierte ein Zertifikat, das nicht gemäß der Richtlinie zur Zertifikatstransparenz öffentlich offengelegt wurde. Dies ist für einige Zertifikate jedoch eine Voraussetzung, mit der sichergestellt wird, dass sie vertrauenswürdig sind und vor Angriffen schützen.</translation>
<translation id="9001074447101275817">Für den Proxy <ph name="DOMAIN" /> sind ein Nutzername und ein Passwort erforderlich.</translation>
+<translation id="9005998258318286617">Fehler beim Laden des PDF-Dokuments.</translation>
<translation id="901974403500617787">Parameter, die systemweit gelten, können nur vom Eigentümer festgelegt werden: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Rechnungsadresse für Kreditkarte erforderlich</translation>
<translation id="9020542370529661692">Die Seite wurde übersetzt und liegt nun auf <ph name="TARGET_LANGUAGE" /> vor.</translation>
<translation id="9035022520814077154">Sicherheitsfehler</translation>
<translation id="9038649477754266430">Vorhersagedienst zum schnelleren Laden von Seiten verwenden</translation>
<translation id="9039213469156557790">Außerdem enthält diese Seite andere, nicht sichere Ressourcen. Diese Ressourcen können während der Übertragung von anderen Nutzern angezeigt und von Angreifern bearbeitet werden, die das Verhalten der Seite verändern.</translation>
-<translation id="9040185888511745258">Unbefugte Dritte könnten auf <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> versuchen, Sie zur Installation von Programmen zu bewegen, die sich nachteilig auf Ihre Browsernutzung auswirken. Dabei kann zum Beispiel Ihre Startseite geändert werden oder es erscheinen zusätzliche Anzeigen auf von Ihnen besuchten Websites.</translation>
+<translation id="9049981332609050619">Sie haben versucht, auf <ph name="DOMAIN" /> zuzugreifen, der Server hat sich jedoch mit einem ungültigen Zertifikat ausgewiesen.</translation>
<translation id="9050666287014529139">Passphrase</translation>
<translation id="9065203028668620118">Bearbeiten</translation>
<translation id="9068849894565669697">Farbe auswählen</translation>
+<translation id="9069693763241529744">Von einer Erweiterung blockiert</translation>
<translation id="9076283476770535406">Eventuell enthält sie nicht jugendfreie Inhalte</translation>
<translation id="9078964945751709336">Weitere Informationen erforderlich</translation>
<translation id="9103872766612412690"><ph name="SITE" /> schützt Ihre Daten in der Regel durch Verschlüsselung. Als Chromium dieses Mal versuchte, eine Verbindung zu <ph name="SITE" /> herzustellen, gab die Website ungewöhnliche und falsche Anmeldedaten zurück. Entweder versucht ein Angreifer, sich als <ph name="SITE" /> auszugeben, oder die Verbindung wurde durch eine WLAN-Anmeldeseite unterbrochen. Da Chromium die Verbindung vor dem Austausch von Daten unterbrochen hat, sind Ihre Informationen weiterhin sicher.</translation>
@@ -863,16 +939,21 @@ Geheimtipp: Verwenden Sie nächstes Mal den Inkognitomodus (<ph name="SHORTCUT_K
<translation id="9148507642005240123">&amp;Bearbeiten rückgängig machen</translation>
<translation id="9154194610265714752">Aktualisiert</translation>
<translation id="9157595877708044936">Einrichtung läuft...</translation>
+<translation id="9169664750068251925">Auf dieser Website immer blockieren</translation>
<translation id="9170848237812810038">&amp;Rückgängig</translation>
<translation id="917450738466192189">Das Serverzertifikat ist ungültig.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> weitere}other{<ph name="SHIPPING_OPTION_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> weitere}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> verwendet ein nicht unterstütztes Protokoll.</translation>
<translation id="9205078245616868884">Ihre Daten sind mit Ihrer Synchronisierungspassphrase verschlüsselt. Geben Sie diese ein, um die Synchronisierung zu starten.</translation>
<translation id="9207861905230894330">Der Artikel konnte nicht hinzugefügt werden.</translation>
+<translation id="9219103736887031265">Bilder</translation>
<translation id="933612690413056017">Keine Internetverbindung</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">Formular leeren</translation>
<translation id="939736085109172342">Neuer Ordner</translation>
<translation id="941721044073577244">Du bist offenbar nicht berechtigt, auf diese Website zuzugreifen</translation>
<translation id="969892804517981540">Offizieller Build</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Keine}=1{1 Eintrag}other{# Einträge}}</translation>
<translation id="988159990683914416">Entwickler-Build</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_el.xtb b/chromium/components/strings/components_strings_el.xtb
index 2742d0f9b52..882bde64fd6 100644
--- a/chromium/components/strings/components_strings_el.xtb
+++ b/chromium/components/strings/components_strings_el.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">ΠεÏιστÏοφή Ï€Ïος τα δεξιά</translation>
<translation id="1038842779957582377">άγνωστο όνομα</translation>
<translation id="1050038467049342496">Κλείστε τις άλλες εφαÏμογές</translation>
-<translation id="1053591932240354961">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή γιατί ο ιστότοπος έστειλε κωδικοποιημένα διαπιστευτήÏια τα οποία δεν μποÏεί να επεξεÏγαστεί το Chrome. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;ΑναίÏεση Ï€Ïοσθήκης</translation>
<translation id="10614374240317010">Δεν έχει αποθηκευθεί ποτέ</translation>
<translation id="106701514854093668">Σελιδοδείκτες επιτÏαπέζιου υπολογιστή</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Η Ï€ÏοσωÏινή μνήμη της πολιτικής είναι εντάξει</translation>
<translation id="113188000913989374">Ο ιστότοπος <ph name="SITE" /> λέει:</translation>
<translation id="1132774398110320017">Ρυθμίσεις Αυτόματης συμπλήÏωσης Chrome…</translation>
+<translation id="1150979032973867961">Ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από το λειτουÏγικό σÏστημα της συσκευής σας. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
+<translation id="1151972924205500581">Απαιτείται κωδικός Ï€Ïόσβασης</translation>
<translation id="1152921474424827756">ΠÏόσβαση σε <ph name="BEGIN_LINK" />Ï€ÏοσωÏινό αντίγÏαφο<ph name="END_LINK" /> της διεÏθυνσης <ph name="URL" /></translation>
<translation id="1158211211994409885">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> τεÏμάτισε απÏοσδόκητα τη σÏνδεση.</translation>
<translation id="1161325031994447685">Επανασυνδεθείτε στο Wi-Fi</translation>
+<translation id="1165039591588034296">Σφάλμα</translation>
<translation id="1175364870820465910">&amp;ΕκτÏπωση...</translation>
<translation id="1181037720776840403">ΚατάÏγηση</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Αυτόματη αναφοÏά<ph name="END_WHITEPAPER_LINK" /> στην Google λεπτομεÏειών σχετικά με πιθανά πεÏιστατικά ασφάλειας.<ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">ΠεÏισσότεÏα από αυτόν τον ιστότοπο</translation>
<translation id="1206967143813997005">Εσφαλμένη αÏχική υπογÏαφή</translation>
<translation id="1209206284964581585">ΠÏοσωÏινή απόκÏυψη</translation>
+<translation id="121201262018556460">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παÏουσίασε ένα πιστοποιητικό που πεÏιέχει ένα αδÏναμο κλειδί. Κάποιος εισβολέας θα μποÏοÏσε να έχει παÏαβιάσει το ιδιωτικό κλειδί και ο διακομιστής ενδέχεται να μην είναι ο διακομιστής που αναμένατε (μποÏεί να επικοινωνείτε με έναν εισβολέα).</translation>
<translation id="1219129156119358924">Ασφάλεια συστήματος</translation>
<translation id="1227224963052638717">Άγνωστη πολιτική.</translation>
<translation id="1227633850867390598">ΑπόκÏυψη τιμής</translation>
<translation id="1228893227497259893">Εσφαλμένο αναγνωÏιστικό οντότητας</translation>
<translation id="1232569758102978740">ΧωÏίς τίτλο</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (συγχÏονισμένο)</translation>
<translation id="1263231323834454256">Λίστα ανάγνωσης</translation>
<translation id="1264126396475825575">ΚαταγÏάφηκαν αναφοÏές σφαλμάτων <ph name="CRASH_TIME" /> (δεν έχουν ακόμη μεταφοÏτωθεί ή παÏαβλεφθεί)</translation>
+<translation id="1281526147609854549">Εκδόθηκε από <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Το επικίνδυνο πεÏιεχόμενο αποκλείστηκε</translation>
<translation id="1285320974508926690">Îα μην γίνεται ποτέ μετάφÏαση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… ιστότοπου</translation>
<translation id="129553762522093515">Έκλεισαν Ï€Ïόσφατα</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Δοκιμάστε να διαγÏάψετε τα cookie σας<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Η δÏαστηÏιότητά σας <ph name="BEGIN_EMPHASIS" />μποÏεί να εξακολουθήσει να είναι οÏατή<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Στους ιστοτόπους που επισκέπτεστε
+ <ph name="LIST_ITEM" />Στον εÏγοδότη ή στο σχολείο σας
+ <ph name="LIST_ITEM" />Στον παÏοχέα υπηÏεσιών διαδικτÏου σας
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Τομέας εγγÏαφής:</translation>
<translation id="1340482604681802745">ΔιεÏθυνση παÏαλαβής</translation>
<translation id="1344211575059133124">Φαίνεται πως χÏειάζεστε άδεια για να επισκεφτείτε αυτόν τον ιστότοπο</translation>
<translation id="1344588688991793829">Ρυθμίσεις αυτόματης συμπλήÏωσης Chromium…</translation>
+<translation id="1348198688976932919">Ο ιστότοπος που Ï€Ïόκειται να επισκεφτείτε πεÏιέχει επικίνδυνες εφαÏμογές</translation>
<translation id="1374468813861204354">Ï€Ïοτάσεις</translation>
<translation id="1375198122581997741">Σχετικά με την έκδοση</translation>
<translation id="1377321085342047638">ΑÏ.κάÏτας</translation>
<translation id="139305205187523129">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> δεν έστειλε δεδομένα.</translation>
<translation id="1407135791313364759">Άνοιγμα όλων</translation>
<translation id="1413809658975081374">Σφάλμα αποÏÏήτου</translation>
+<translation id="14171126816530869">Η ταυτότητα του <ph name="ORGANIZATION" /> στο <ph name="LOCALITY" /> επαληθεÏτηκε από <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Îαι</translation>
<translation id="1430915738399379752">ΕκτÏπωση</translation>
-<translation id="1442912890475371290">Αποκλείστηκε απόπειÏα <ph name="BEGIN_LINK" /> ανοίγματος σελίδας στο <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή γιατί ο ιστότοπος χÏησιμοποιεί certificate pinning (κλείδωμα πιστοποιητικών). Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ακόμη}other{<ph name="PAYMENT_METHOD_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ακόμη}}</translation>
<translation id="1506687042165942984">Εμφάνιση ενός αποθηκευμένου αντιγÏάφου (Ï€.χ. επιβεβαιωμένες μη ενημεÏωμένες εκδόσεις) αυτής της σελίδας.</translation>
<translation id="1517433312004943670">Απαιτείται αÏιθμός τηλεφώνου</translation>
<translation id="1519264250979466059">ΗμεÏομηνία κατασκευής</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Θα Ï€Ïέπει να ενεÏγοποιηθεί η JavaScript για τη χÏήση αυτής της λειτουÏγίας.</translation>
<translation id="1555130319947370107">Μπλε</translation>
<translation id="1559528461873125649">Δεν υπάÏχει τέτοιο αÏχείο ή κατάλογος</translation>
-<translation id="1559572115229829303">&lt;p&gt;Δεν είναι δυνατή η επίτευξη ιδιωτικής σÏνδεσης με τον τομέα <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημεÏομηνία και η ÏŽÏα (<ph name="DATE_AND_TIME" />) της συσκευής σας είναι λανθασμένες.&lt;/p&gt;
-
- &lt;p&gt;ΠÏοσαÏμόστε την ημεÏομηνία και την ÏŽÏα από την ενότητα &lt;strong&gt;Γενικές&lt;/strong&gt; της εφαÏμογής &lt;strong&gt;Ρυθμίσεις&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">ΠαÏουσιάστηκε Ï€Ïόβλημα κατά την εμφάνιση αυτής της ιστοσελίδας.</translation>
<translation id="1592005682883173041">ΠÏόσβαση σε τοπικά δεδομένα</translation>
+<translation id="1594030484168838125">Επιλογή</translation>
<translation id="161042844686301425">Κυανό</translation>
+<translation id="1620510694547887537">ΚάμεÏα</translation>
<translation id="1629803312968146339">Θέλετε το Chrome να αποθηκεÏσει αυτήν την κάÏτα;</translation>
<translation id="1639239467298939599">Γίνεται φόÏτωση</translation>
<translation id="1640180200866533862">Πολιτικές χÏηστών</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Η διαμόÏφωση δικτÏου είναι μη έγκυÏη και δεν ήταν δυνατή η εισαγωγή της.</translation>
<translation id="1644574205037202324">ΙστοÏικό</translation>
<translation id="1645368109819982629">Μη υποστηÏιζόμενο Ï€Ïωτόκολλο</translation>
+<translation id="1655462015569774233">{1,plural, =1{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του έληξε χθες. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. Το Ïολόι του υπολογιστή σας αυτήν τη στιγμή είναι Ïυθμισμένο στην ημεÏομηνία <ph name="CURRENT_DATE" />. Είναι σωστή αυτή η ÏÏθμιση; Εάν όχι, θα Ï€Ïέπει να διοÏθώσετε το Ïολόι του συστήματός σας και έπειτα να ανανεώσετε αυτήν τη σελίδα.}other{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του έληξε Ï€Ïιν από # ημέÏες. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. Το Ïολόι του υπολογιστή σας αυτήν τη στιγμή είναι Ïυθμισμένο στην ημεÏομηνία <ph name="CURRENT_DATE" />. Είναι σωστή αυτή η ÏÏθμιση; Εάν όχι, θα Ï€Ïέπει να διοÏθώσετε το Ïολόι του συστήματός σας και έπειτα να ανανεώσετε αυτήν τη σελίδα.}}</translation>
<translation id="1656489000284462475">ΠαÏαλαβή</translation>
<translation id="1663943134801823270">Οι κάÏτες και οι διευθÏνσεις Ï€ÏοέÏχονται από το Chrome. ΜποÏείτε να τις διαχειÏιστείτε στις <ph name="BEGIN_LINK" />Ρυθμίσεις<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Κανονικά, ο ιστότοπος <ph name="SITE" /> χÏησιμοποιεί κÏυπτογÏάφηση για να Ï€ÏοστατεÏει τα στοιχεία σας. Όταν το Google Chrome επιχείÏησε Ï€Ïόσφατα να συνδεθεί στο <ph name="SITE" />, ο ιστότοπος ανταποκÏίθηκε δημιουÏγώντας ασυνήθιστα και εσφαλμένα διαπιστευτήÏια. Αυτό μποÏεί να συμβεί όταν κάποιος εισβολέας Ï€Ïοσπαθεί να υποκÏιθεί ότι είναι ο ιστότοπος <ph name="SITE" /> ή όταν κάποια οθόνη σÏνδεσης Wi-Fi έχει διακόψει τη σÏνδεσή σας. Τα στοιχεία σας εξακολουθοÏν να είναι ασφαλή επειδή το Google Chrome διέκοψε τη σÏνδεση Ï€Ïιν από την ανταλλαγή δεδομένων.</translation>
-<translation id="168328519870909584">Οι εισβολείς που βÏίσκονται αυτήν τη στιγμή στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ενδέχεται να επιχειÏήσουν να εγκαταστήσουν επικίνδυνες εφαÏμογές στη συσκευή σας, οι οποίες μποÏοÏν να υποκλέψουν ή να διαγÏάψουν τα δεδομένα σας (για παÏάδειγμα, φωτογÏαφίες, κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα και στοιχεία πιστωτικών καÏτών).</translation>
<translation id="168841957122794586">Το πιστοποιητικό διακομιστή πεÏιέχει ένα αδÏναμο κÏυπτογÏαφικό κλειδί.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημεÏομηνία του Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Î±ÏƒÏ†Î±Î»ÎµÎ¯Î±Ï‚ του υποτίθεται ότι είναι αυÏιανή. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας.}other{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημεÏομηνία του Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Î±ÏƒÏ†Î±Î»ÎµÎ¯Î±Ï‚ του υποτίθεται ότι είναι από # ημέÏες μετά. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Για να επισκεφτείτε αυτήν τη σελίδα, χÏειάζεστε άδεια από τον διαχειÏιστή <ph name="NAME" /></translation>
<translation id="1721424275792716183">* Το πεδίο είναι υποχÏεωτικό</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Λήψη σελίδας αÏγότεÏα</translation>
<translation id="17513872634828108">Ανοικτές καÏτέλες</translation>
<translation id="1753706481035618306">ΑÏιθμός σελίδας</translation>
+<translation id="1763864636252898013">Ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από το λειτουÏγικό σÏστημα της συσκευής σας. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Δοκιμάστε να εκτελέσετε τον Διαγνωστικό έλεγχο δικτÏου των Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">ΕνημεÏώστε την κωδική φÏάση Ï€Ïόσβασης συγχÏονισμοÏ.</translation>
<translation id="1787142507584202372">Οι ανοιχτές καÏτέλες σας εμφανίζονται εδώ</translation>
+<translation id="1789575671122666129">Αναδυόμενα παÏάθυÏα</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Όνομα κατόχου κάÏτας</translation>
-<translation id="1803678881841855883">Η Ασφαλής πεÏιήγηση Google <ph name="BEGIN_LINK" />εντόπισε κακόβουλο Ï€ÏόγÏαμμα<ph name="END_LINK" /> Ï€Ïόσφατα στον ιστότοπο <ph name="SITE" />. Οι ιστότοποι που είναι συνήθως ασφαλείς Ï€Ïοσβάλλονται οÏισμένες φοÏές από κακόβουλο λογισμικό. Το κακόβουλο λογισμικό Ï€ÏοέÏχεται από τον κεντÏικό υπολογιστή <ph name="SUBRESOURCE_HOST" />, γνωστό διανομέα κακόβουλου λογισμικοÏ. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">ΠÏοστέθηκε <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Μη έγκυÏο αίτημα ή παÏάμετÏοι αιτήματος</translation>
<translation id="1826516787628120939">Έλεγχος</translation>
<translation id="1834321415901700177">Αυτός ο ιστότοπος πεÏιέχει κακόβουλα Ï€ÏογÏάμματα</translation>
+<translation id="1840414022444569775">Αυτός ο αÏιθμός κάÏτας χÏησιμοποιείται ήδη</translation>
<translation id="1842969606798536927">ΠληÏωμή</translation>
<translation id="1871208020102129563">Ο διακομιστής μεσολάβησης έχει Ïυθμιστεί να χÏησιμοποιεί διακομιστές μεσολάβησης και όχι μια διεÏθυνση URL σεναÏίου .pac.</translation>
<translation id="1871284979644508959">ΑπαιτοÏμενο πεδίο</translation>
<translation id="187918866476621466">Άνοιγμα σελίδων εκκίνησης</translation>
<translation id="1883255238294161206">ΣÏμπτυξη λίστας</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ακόμη}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ακόμη}}</translation>
<translation id="1898423065542865115">ΦιλτÏάÏισμα</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Κανένας}=1{1 ιστότοπος}other{# ιστότοποι}}</translation>
<translation id="194030505837763158">Μετάβαση στο σÏνδεσμο <ph name="LINK" /></translation>
<translation id="1962204205936693436">Σελιδοδείκτες <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Σφάλμα σειÏιοποίησης</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Αγνοήθηκε επειδή αντικαταστάθηκε από την πολιτική <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Αναζήτηση κοντινών σελίδων Î¦Ï…ÏƒÎ¹ÎºÎ¿Ï Î´Î¹ÎºÏ„Ïου</translation>
<translation id="213826338245044447">Σελιδοδείκτες κινητής συσκευής</translation>
-<translation id="2148716181193084225">ΣήμεÏα</translation>
+<translation id="2147827593068025794">ΣυγχÏονισμός παÏασκηνίου</translation>
<translation id="2154054054215849342">Ο συγχÏονισμός δεν είναι διαθέσιμος για τον τομέα σας</translation>
<translation id="2154484045852737596">ΕπεξεÏγασία κάÏτας</translation>
<translation id="2166049586286450108">ΠλήÏης Ï€Ïόσβαση διαχειÏιστή</translation>
<translation id="2166378884831602661">Αυτός ο ιστότοπος δεν μποÏεί να Ï€ÏοσφέÏει ασφαλή σÏνδεση</translation>
<translation id="2181821976797666341">Πολιτικές</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 διεÏθυνση}other{# διευθÏνσεις}}</translation>
+<translation id="2187317261103489799">Εντοπισμός (Ï€Ïοεπιλογή)</translation>
<translation id="2202020181578195191">Εισαγάγετε ένα έγκυÏο έτος λήξης</translation>
<translation id="2212735316055980242">Η πολιτική δε βÏέθηκε</translation>
<translation id="2213606439339815911">Ανάκτηση καταχωÏίσεων…</translation>
+<translation id="2218879909401188352">Οι εισβολείς στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> θα μποÏοÏσαν να εγκαταστήσουν επικίνδυνες εφαÏμογές που Ï€ÏοκαλοÏν ζημιά στη συσκευή σας, να Ï€Ïοσθέσουν κÏυφές χÏεώσεις στον λογαÏιασμό του ÎºÎ¹Î½Î·Ï„Î¿Ï ÏƒÎ±Ï‚ ή να κλέψουν τα Ï€Ïοσωπικά στοιχεία σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">ΕπιδιοÏθώστε τη σÏνδεσή σας χÏησιμοποιώντας την <ph name="BEGIN_LINK" />εφαÏμογή διαγνωστικών ελέγχων<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Αποστολή Ï„ÏŽÏα</translation>
<translation id="225207911366869382">Αυτή η πολιτική έχει καταÏγηθεί για τη συγκεκÏιμένη πολιτική.</translation>
<translation id="2262243747453050782">Σφάλμα HTTP</translation>
+<translation id="2270484714375784793">ΑÏιθμός τηλεφώνου</translation>
<translation id="2282872951544483773">Μη διαθέσιμα πειÏάματα</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> στοιχείο}other{<ph name="ITEM_COUNT" /> στοιχεία}}</translation>
<translation id="2292556288342944218">Η Ï€Ïόσβασή σας στο διαδίκτυο είναι αποκλεισμένη</translation>
<translation id="230155334948463882">Îέα κάÏτα;</translation>
-<translation id="2305919008529760154">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μποÏεί να εκδόθηκε παÏάνομα. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">Ο τομέας <ph name="DOMAIN" /> απαιτεί ένα όνομα χÏήστη και έναν κωδικό Ï€Ïόσβασης.</translation>
-<translation id="2318774815570432836">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή γιατί ο ιστότοπος χÏησιμοποιεί HSTS. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Η ÏÏθμιση ελέγχεται από τον διαχειÏιστή σας</translation>
<translation id="2354001756790975382">Άλλοι σελιδοδείκτες</translation>
+<translation id="2354430244986887761">Η Ασφαλής πεÏιήγηση Google Ï€Ïόσφατα <ph name="BEGIN_LINK" />εντόπισε επιβλαβείς εφαÏμογές<ph name="END_LINK" /> στον ιστότοπο <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Οι εισβολείς ενδέχεται να έχουν τη δυνατότητα να δουν τις εικόνες που Ï€Ïοβάλετε σε αυτόν τον ιστότοπο και να σας εξαπατήσουν Ï„Ïοποποιώντας τες.</translation>
+<translation id="2356070529366658676">Îα γίνεται εÏώτηση</translation>
+<translation id="2359629602545592467">Πολλά</translation>
<translation id="2359808026110333948">Συνέχεια</translation>
<translation id="2365563543831475020">Οι αναφοÏές σφαλμάτων που καταγÏάφηκαν <ph name="CRASH_TIME" /> δεν έχουν μεταφοÏτωθεί</translation>
<translation id="2367567093518048410">Επίπεδο</translation>
-<translation id="2371153335857947666">{1,plural, =1{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του έληξε χθες. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. Το Ïολόι του υπολογιστή σας αυτήν τη στιγμή είναι Ïυθμισμένο στην ημεÏομηνία <ph name="CURRENT_DATE" />. Είναι σωστή αυτή η ÏÏθμιση; Εάν όχι, θα Ï€Ïέπει να διοÏθώσετε το Ïολόι του συστήματός σας και έπειτα να ανανεώσετε αυτήν τη σελίδα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.}other{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του έληξε Ï€Ïιν από # ημέÏες. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. Το Ïολόι του υπολογιστή σας αυτήν τη στιγμή είναι Ïυθμισμένο στην ημεÏομηνία <ph name="CURRENT_DATE" />. Είναι σωστή αυτή η ÏÏθμιση; Εάν όχι, θα Ï€Ïέπει να διοÏθώσετε το Ïολόι του συστήματός σας και έπειτα να ανανεώσετε αυτήν τη σελίδα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Δεν διατίθενται εναλλακτικές διεπαφές</translation>
<translation id="2384307209577226199">ΠÏοεπιλογή επιχείÏησης</translation>
<translation id="2386255080630008482">Το πιστοποιητικό του διακομιστή ανακλήθηκε.</translation>
<translation id="2392959068659972793">Εμφάνιση πολιτικών χωÏίς τιμή που να έχει οÏιστεί.</translation>
<translation id="239429038616798445">Αυτός ο Ï„Ïόπος αποστολής δεν είναι διαθέσιμος. Δοκιμάστε έναν άλλο Ï„Ïόπο.</translation>
<translation id="2396249848217231973">&amp;ΑναίÏεση διαγÏαφής</translation>
-<translation id="2460160116472764928">Η ασφαλής πεÏιήγηση Google <ph name="BEGIN_LINK" />εντόπισε κακόβουλο Ï€ÏόγÏαμμα<ph name="END_LINK" /> Ï€Ïόσφατα στον ιστότοπο <ph name="SITE" />. Οι ιστότοποι που είναι ασφαλείς υπό φυσιολογικές συνθήκες μεÏικές φοÏές Ï€Ïοσβάλλονται από κακόβουλα λογισμικά. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Ο διακομιστής δεν κατάφεÏε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μποÏεί να έχει ανακληθεί. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
<translation id="2463739503403862330">ΣυμπλήÏωση</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Îα εκτελέσετε τον Διαγνωστικό έλεγχο δικτÏου<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Μη έγκυÏη διεÏθυνση URL αναζήτησης.</translation>
+<translation id="2482878487686419369">Ειδοποιήσεις</translation>
<translation id="2491120439723279231">Το πιστοποιητικό του διακομιστή πεÏιέχει σφάλματα.</translation>
<translation id="2495083838625180221">Συντακτικός αναλυτής JSON</translation>
<translation id="2495093607237746763">Εάν επιλεγεί, το Chromium θα αποθηκεÏσει ένα αντίγÏαφο της κάÏτας σας σε αυτήν τη συσκευή για ταχÏτεÏη συμπλήÏωση φοÏμών.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">ΕπιστÏοφή</translation>
<translation id="2515629240566999685">Ελέγξτε το σήμα στην πεÏιοχή σας</translation>
<translation id="2516305470678292029">Εναλλακτικές διεπαφές</translation>
+<translation id="2539524384386349900">ΑναγνώÏιση</translation>
<translation id="255002559098805027">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> έστειλε μια μη έγκυÏη απόκÏιση.</translation>
-<translation id="2552545117464357659">ÎεότεÏη</translation>
<translation id="2556876185419854533">&amp;ΑναίÏεση επεξεÏγασίας</translation>
<translation id="2587730715158995865">Από <ph name="ARTICLE_PUBLISHER" />. Διαβάστε αυτό το άÏθÏο και <ph name="OTHER_ARTICLE_COUNT" /> ακόμα ιστοÏίες.</translation>
<translation id="2587841377698384444">ΑναγνωÏιστικό API καταλόγου:</translation>
<translation id="2597378329261239068">Αυτό το έγγÏαφο Ï€ÏοστατεÏεται με κωδικό Ï€Ïόσβασης. ΠληκτÏολογήστε έναν κωδικό Ï€Ïόσβασης.</translation>
<translation id="2609632851001447353">ΠαÏαλλαγές</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Καμία}=1{1 εφαÏμογή ($1)}=2{2 εφαÏμογές ($1, $2)}other{# εφαÏμογές ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Το Ïολόι σας πάει μπÏοστά</translation>
<translation id="2639739919103226564">Κατάσταση:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Η Ï€Ïόσβαση στο αÏχείο αποÏÏίφθηκε</translation>
<translation id="2653659639078652383">Υποβολή</translation>
<translation id="2666117266261740852">Κλείστε τις άλλες καÏτέλες ή εφαÏμογές</translation>
+<translation id="2670429602441959756">Αυτή η σελίδα πεÏιέχει λειτουÏγίες που δεν υποστηÏίζονται ακόμη στο VR. Έξοδος...</translation>
<translation id="2674170444375937751">Είστε βέβαιοι ότι θέλετε να διαγÏάψετε αυτές τις σελίδες από το ιστοÏικό σας;</translation>
<translation id="2677748264148917807">ΑποχώÏηση</translation>
-<translation id="269990154133806163">Ο διακομιστής παÏουσίασε ένα πιστοποιητικό το οποίο δεν αποκαλÏφθηκε δημοσίως με χÏήση της πολιτικής Διαφάνειας πιστοποιητικών. Αυτό απαιτείται για οÏισμένα πιστοποιητικά, Ï€Ïοκειμένου να διασφαλιστεί ότι είναι αξιόπιστα και παÏέχουν Ï€Ïοστασία ενάντια σε εισβολείς. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Λίστα ανάγνωσης</translation>
<translation id="2704283930420550640">Η τιμή δεν συμφωνεί με τη μοÏφή.</translation>
<translation id="2704951214193499422">Δεν ήταν δυνατή η επιβεβαίωση της κάÏτας σας από το Chromium αυτήν τη στιγμή. Δοκιμάστε ξανά αÏγότεÏα.</translation>
<translation id="2705137772291741111">Δεν είναι δυνατή η ανάγνωση του αποθηκευμένου αντιγÏάφου (κÏυφής μνήμης) Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… ιστότοπου.</translation>
<translation id="2709516037105925701">Αυτόματη συμπλήÏωση</translation>
-<translation id="2712118517637785082">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, όμως το πιστοποιητικό που παÏουσιάστηκε από τον διακομιστή ανακλήθηκε από τον εκδότη του. Αυτό σημαίνει ότι τα διαπιστευτήÏια ασφαλείας που παÏουσιάστηκαν από τον διακομιστή δεν Ï€Ïέπει σε καμία πεÏίπτωση να θεωÏηθοÏν αξιόπιστα. Ενδέχεται να επικοινωνείτε με κάποιον εισβολέα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Îα ζητηθεί άδεια</translation>
<translation id="2713444072780614174">Λευκό</translation>
<translation id="2720342946869265578">Σε κοντινή απόσταση</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Λείπει κάποιο αÏχείο συσκευής</translation>
<translation id="2784949926578158345">Έγινε επαναφοÏά της σÏνδεσης.</translation>
<translation id="2794233252405721443">Ο ιστότοπος έχει αποκλειστεί</translation>
+<translation id="2799020568854403057">Ο ιστότοπος που Ï€Ïόκειται να επισκεφτείτε πεÏιέχει επιβλαβείς εφαÏμογές</translation>
+<translation id="2803306138276472711">ΠÏόσφατα η Ασφαλής πεÏιήγηση Google <ph name="BEGIN_LINK" />εντόπισε κακόβουλο λογισμικό<ph name="END_LINK" /> στον ιστότοπο <ph name="SITE" />. Οι ιστότοποι που είναι ασφαλείς υπό φυσιολογικές συνθήκες μεÏικές φοÏές Ï€Ïοσβάλλονται από κακόβουλα λογισμικά.</translation>
<translation id="2824775600643448204">ΓÏαμμή διευθÏνσεων και αναζήτησης</translation>
<translation id="2826760142808435982">Η κÏυπτογÏάφηση και ο έλεγχος ταυτότητας της σÏνδεσης γίνονται με <ph name="CIPHER" /> και χÏησιμοποιεί το <ph name="KX" /> ως μηχανισμό ανταλλαγής κλειδιών.</translation>
<translation id="2835170189407361413">ΔιαγÏαφή φόÏμας</translation>
+<translation id="2856444702002559011">Οι εισβολείς ενδέχεται να Ï€Ïοσπαθήσουν να υποκλέψουν τα στοιχεία σας από τον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (για παÏάδειγμα, κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα ή πιστωτικές κάÏτες). <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Îα μην γίνει επανάληψη φόÏτωσης</translation>
<translation id="2900469785430194048">Η διαθέσιμη μνήμη του Google Chrome εξαντλήθηκε, κατά την Ï€Ïοσπάθεια Ï€Ïοβολής αυτής της ιστοσελίδας.</translation>
<translation id="2909946352844186028">Εντοπίστηκε μια αλλαγή δικτÏου.</translation>
<translation id="2916038427272391327">Κλείστε τα άλλα Ï€ÏογÏάμματα</translation>
<translation id="2922350208395188000">Δεν είναι δυνατός ο έλεγχος του Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Ï„Î¿Ï… διακομιστή.</translation>
<translation id="2928905813689894207">ΔιεÏθυνση χÏέωσης</translation>
+<translation id="2941952326391522266">Ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του είναι από το <ph name="DOMAIN2" />. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
<translation id="2948083400971632585">ΜποÏείτε να απενεÏγοποιήσετε τυχόν διακομιστές μεσολάβησης που έχουν διαμοÏφωθεί για μια σÏνδεση από τη σελίδα Ïυθμίσεων.</translation>
<translation id="2955913368246107853">Κλείσιμο γÏαμμής εÏÏεσης</translation>
<translation id="2958431318199492670">Η διαμόÏφωση δικτÏου δεν συμμοÏφώνεται με το Ï€Ïότυπο ONC. ΟÏισμένα τμήματα αυτής της διαμόÏφωσης ενδέχεται να μην εισαχθοÏν.</translation>
-<translation id="29611076221683977">Οι εισβολείς που βÏίσκονται αυτήν τη στιγμή στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ενδέχεται να επιχειÏήσουν να εγκαταστήσουν επικίνδυνα Ï€ÏογÏάμματα στον υπολογιστή σας Mac, για να υποκλέψουν ή να διαγÏάψουν τα δεδομένα σας (για παÏάδειγμα, φωτογÏαφίες, κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα και πιστωτικές κάÏτες).</translation>
<translation id="2966678944701946121">Λήξη: <ph name="EXPIRATION_DATE_ABBR" />, Ï€Ïοστέθηκε <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Για την επίτευξη μιας ασφαλοÏÏ‚ σÏνδεσης, θα Ï€Ïέπει να γίνει σωστή ÏÏθμιση του ÏÎ¿Î»Î¿Î³Î¹Î¿Ï ÏƒÎ±Ï‚. Αυτό οφείλεται στο γεγονός ότι τα πιστοποιητικά που χÏησιμοποιοÏν οι ιστότοποι για την ταυτοποίησή τους είναι έγκυÏα μόνο για συγκεκÏιμένες χÏονικές πεÏιόδους. Εφόσον το Ïολόι της συσκευής σας δεν είναι σωστά Ïυθμισμένο, το Google Chrome δεν μποÏεί να επαληθεÏσει αυτά τα πιστοποιητικά.</translation>
<translation id="2972581237482394796">&amp;Επανάληψη ενέÏγειας</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Εισαγάγετε μια έγκυÏη διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου</translation>
<translation id="2986368408720340940">Ο Ï„Ïόπος παÏαλαβής δεν είναι διαθέσιμος. Δοκιμάστε έναν άλλο Ï„Ïόπο.</translation>
<translation id="2991174974383378012">Κοινοποίηση σε ιστότοπους</translation>
+<translation id="2991571918955627853">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή, επειδή ο ιστότοπος χÏησιμοποιεί HSTS. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα.</translation>
<translation id="3005723025932146533">Εμφάνιση αποθηκευμένου αντιγÏάφου</translation>
<translation id="3008447029300691911">Εισαγάγετε τον κωδικό CVC για την πιστωτική κάÏτα <ph name="CREDIT_CARD" />. Μετά την επιβεβαίωση, θα γίνει κοινή χÏήση των στοιχείων της κάÏτας σας με αυτόν τον ιστότοπο.</translation>
<translation id="3010559122411665027">ΚαταχώÏιση λίστας "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Αποκλείστηκε αυτόματα</translation>
<translation id="3024663005179499861">Λανθασμένος Ï„Ïπος πολιτικής</translation>
<translation id="3032412215588512954">Θέλετε να φοÏτώσετε ξανά αυτόν τον ιστότοπο;</translation>
<translation id="3037605927509011580">Όπα! Κάτι πήγε στÏαβά!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{τουλάχιστον ένα στοιχείο στις συγχÏονισμένες συσκευές}=1{1 στοιχείο (και πεÏισσότεÏα στις συγχÏονισμένες συσκευές)}other{# στοιχεία (και πεÏισσότεÏα στις συγχÏονισμένες συσκευές)}}</translation>
<translation id="3041612393474885105">ΠληÏοφοÏίες πιστοποιητικοÏ</translation>
<translation id="3063697135517575841">Δεν ήταν δυνατή η επιβεβαίωση της κάÏτας σας από το Chrome αυτήν τη στιγμή. Δοκιμάστε ξανά αÏγότεÏα.</translation>
<translation id="3064966200440839136">ΑποχώÏηση από την κατάσταση ανώνυμης πεÏιήγησης για πληÏωμή μέσω εξωτεÏικής εφαÏμογής. Συνέχεια;</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Κανένας}=1{1 κωδικός Ï€Ïόσβασης}other{# κωδικοί Ï€Ïόσβασης}}</translation>
<translation id="3093245981617870298">Είστε εκτός σÏνδεσης.</translation>
<translation id="3105172416063519923">ΑναγνωÏιστικό στοιχείο:</translation>
<translation id="3109728660330352905">Δεν έχετε εξουσιοδότηση για την Ï€Ïοβολή αυτής της σελίδας.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Δοκιμάστε να εκτελέσετε τα Διαγνωστικά στοιχεία συνδεσιμότητας<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Αποτυχία αποκωδικοποίησης απόκÏισης</translation>
<translation id="3150653042067488994">ΠÏοσωÏινό σφάλμα διακομιστή</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Οι σελίδες που Ï€Ïοβάλλετε στις καÏτέλες της ανώνυμης πεÏιήγησης δεν διατηÏοÏνται στο ιστοÏικό του Ï€ÏογÏάμματος πεÏιήγησης, στα cookie ή στο ιστοÏικό αναζήτησης, Î±Ï†Î¿Ï ÎºÎ»ÎµÎ¯ÏƒÎµÏ„Îµ όλες τις καÏτέλες της ανώνυμης πεÏιήγησης. Τα αÏχεία που κατεβάζετε ή οι σελιδοδείκτες που δημιουÏγείτε θα διατηÏοÏνται.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Îησί</translation>
+<translation id="317583078218509884">Οι νέες Ïυθμίσεις αδειών ιστότοπου θα τεθοÏν σε Î¹ÏƒÏ‡Ï Î¼ÎµÏ„Î¬ την επανάληψη φόÏτωσης της σελίδας.</translation>
<translation id="3176929007561373547">Ελέγξτε τις Ïυθμίσεις του διακομιστή μεσολάβησης ή επικοινωνήστε με το διαχειÏιστή του δικτÏου σας, για
να βεβαιωθείτε ότι ο διακομιστής μεσολάβησης λειτουÏγεί. Εάν δεν πιστεÏετε ότι
απαιτείται η χÏήση διακομιστή μεσολάβησης:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Ανοίξτε τη σελίδα σε κατάσταση ανώνυμης πεÏιήγησης</translation>
-<translation id="3202578601642193415">ÎεότεÏο</translation>
+<translation id="320323717674993345">ΑκÏÏωση πληÏωμής</translation>
<translation id="3207960819495026254">ΠÏοστέθηκε στους σελιδοδείκτες</translation>
+<translation id="3225919329040284222">Ο διακομιστής παÏουσίασε ένα πιστοποιητικό που δεν αντιστοιχεί στις ενσωματωμένες Ï€Ïοϋποθέσεις. Αυτές οι Ï€Ïοϋποθέσεις συμπεÏιλαμβάνονται σε συγκεκÏιμένους ιστότοπους υψηλής ασφάλειας για την Ï€Ïοστασία σας.</translation>
<translation id="3226128629678568754">Πατήστε το κουμπί της επανάληψης φόÏτωσης για να υποβάλετε ξανά τα δεδομένα που απαιτοÏνται για τη φόÏτωση της σελίδας.</translation>
+<translation id="3227137524299004712">ΜικÏόφωνο</translation>
<translation id="3228969707346345236">Η μετάφÏαση απέτυχε επειδή η σελίδα είναι ήδη στα <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Εισαγάγετε τον κωδικό CVC για την πιστωτική κάÏτα <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Îα εντοπίζεται πάντα σημαντικό πεÏιεχόμενο σε αυτόν τον ιστότοπο</translation>
<translation id="3254409185687681395">ΠÏοσθήκη αυτής της σελίδας στους σελιδοδείκτες</translation>
<translation id="3270847123878663523">&amp;ΑναίÏεση αναδιάταξης</translation>
<translation id="3282497668470633863">ΠÏοσθήκη ονόματος στην κάÏτα</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">Ïυθμίσεις</translation>
<translation id="3345135638360864351">Δεν ήταν δυνατή η αποστολή του αιτήματος Ï€Ïόσβασής σας σε αυτόν τον ιστότοπο σε <ph name="NAME" />. Δοκιμάστε ξανά.</translation>
<translation id="3355823806454867987">Αλλαγή Ïυθμίσεων διακομιστή μεσολάβησης...</translation>
+<translation id="3361596688432910856">Το Chrome <ph name="BEGIN_EMPHASIS" />δεν θα αποθηκεÏει<ph name="END_EMPHASIS" /> τις παÏακάτω πληÏοφοÏίες:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Το ιστοÏικό πεÏιήγησής σας
+ <ph name="LIST_ITEM" />Cookie και δεδομένα ιστοτόπου
+ <ph name="LIST_ITEM" />ΠληÏοφοÏίες που εισάγετε σε φόÏμες
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Σφάλμα ÏολογιοÏ</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> ακόμη στοιχεία…</translation>
<translation id="337363190475750230">ΚατάÏγηση παÏοχής</translation>
<translation id="3377188786107721145">Σφάλμα ανάλυσης πολιτικής</translation>
<translation id="3380365263193509176">Άγνωστο σφάλμα</translation>
<translation id="3380864720620200369">ΑναγνωÏιστικό πελάτη:</translation>
<translation id="3391030046425686457">ΔιεÏθυνση παÏάδοσης</translation>
<translation id="3395827396354264108">ΤÏόπος παÏαλαβής</translation>
-<translation id="340013220407300675">Οι εισβολείς ενδέχεται να Ï€ÏοσπαθοÏν να υποκλέψουν τα στοιχεία σας από <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (για παÏάδειγμα κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα ή πιστωτικές κάÏτες).</translation>
<translation id="3422248202833853650">Δοκιμάστε να εξέλθετε από τα άλλα Ï€ÏογÏάμματα για να απελευθεÏώσετε μνήμη.</translation>
<translation id="3422472998109090673">ΠÏος το παÏόν, δεν είναι δυνατή η Ï€Ïόσβαση στον κεντÏικό υπολογιστή <ph name="HOST_NAME" />.</translation>
+<translation id="3427092606871434483">Îα επιτÏέπεται (Ï€Ïοεπιλογή)</translation>
<translation id="3427342743765426898">&amp;Επανάληψη επεξεÏγασίας</translation>
<translation id="3431636764301398940">Αποθήκευση αυτής της κάÏτας στη συγκεκÏιμένη συσκευή</translation>
<translation id="3435896845095436175">ΕνεÏγοποίηση</translation>
<translation id="3447661539832366887">Ο κάτοχος αυτής της συσκευής απενεÏγοποίησε το παιχνίδι με τους δεινοσαÏÏους.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Διάστημα ανάκτησης:</translation>
<translation id="3462200631372590220">ΑπόκÏυψη σÏνθετων</translation>
<translation id="3467763166455606212">Απαιτείται το όνομα κατόχου κάÏτας</translation>
<translation id="3478058380795961209">Μήνας λήξης</translation>
<translation id="3479539252931486093">Δεν το πεÏιμένατε; <ph name="BEGIN_LINK" />ΕνημεÏώστε μας<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Όχι Ï„ÏŽÏα</translation>
-<translation id="348000606199325318">ΑναγνωÏιστικό σφάλματος <ph name="CRASH_LOCAL_ID" /> (ΑναγνωÏιστικό διακομιστή: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Δεν ήταν δυνατή η επικοινωνία με τον γονέα σας αυτήν τη στιγμή. Δοκιμάστε ξανά.</translation>
<translation id="3528171143076753409">Το πιστοποιητικό του διακομιστή δεν είναι αξιόπιστο.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Τουλάχιστον ένα στοιχείο στις συγχÏονισμένες συσκευές}=1{1 στοιχείο (και πεÏισσότεÏα στις συγχÏονισμένες συσκευές)}other{# στοιχεία (και πεÏισσότεÏα στις συγχÏονισμένες συσκευές)}}</translation>
<translation id="3539171420378717834">ΔιατήÏηση αντιγÏάφου αυτής της κάÏτας σε αυτήν τη συσκευή</translation>
<translation id="3542684924769048008">ΧÏήση ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης για:</translation>
+<translation id="3545341443414427877">Δεν είναι δυνατή η δημιουÏγία μιας ιδιωτικής σÏνδεσης στον τομέα <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημεÏομηνία και η ÏŽÏα του υπολογιστή σας (<ph name="DATE_AND_TIME" />) είναι λανθασμένες. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">ΚÏυπτογÏάφηση όλων των συγχÏονισμένων δεδομένων με τη δική σας φÏάση Ï€Ïόσβασης συγχÏονισμοÏ</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> πεÏισσότεÏες…</translation>
-<translation id="3555561725129903880">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του είναι από το <ph name="DOMAIN2" />. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Ο διαχειÏιστής σας μποÏεί να καταÏγήσει τον αποκλεισμό του για εσάς</translation>
<translation id="3566021033012934673">Η σÏνδεσή σας δεν είναι ιδιωτική</translation>
+<translation id="3569145463236695319">&lt;p&gt;Δεν είναι δυνατή η επίτευξη ιδιωτικής σÏνδεσης με τον τομέα <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημεÏομηνία και η ÏŽÏα (<ph name="DATE_AND_TIME" />) της συσκευής σας είναι λανθασμένες.&lt;/p&gt;
+
+ &lt;p&gt;ΠÏοσαÏμόστε την ημεÏομηνία και την ÏŽÏα από την ενότητα &lt;strong&gt;Γενικές&lt;/strong&gt; της εφαÏμογής &lt;strong&gt;Ρυθμίσεις&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">ΠÏοσθήκη ονόματος</translation>
<translation id="3583757800736429874">&amp;Επανάληψη μετακίνησης</translation>
<translation id="3586931643579894722">ΑπόκÏυψη λεπτομεÏειών</translation>
-<translation id="3587482841069643663">Όλες</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Εισαγάγετε μια έγκυÏη ημεÏομηνία λήξης</translation>
<translation id="36224234498066874">ΔιαγÏαφή Δεδομένων ΠεÏιήγησης...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">ΠληÏοφοÏίες πιστοποιητικοÏ</translation>
<translation id="3690164694835360974">Μη ασφαλής σÏνδεση</translation>
<translation id="3693415264595406141">Κωδικός Ï€Ïόσβασης:</translation>
-<translation id="3696411085566228381">κανένα</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ΦόÏτωση...</translation>
<translation id="3712624925041724820">Οι άδειες έχουν εξαντληθεί</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Ελέγξτε το διακομιστή μεσολάβησης, το τείχος Ï€Ïοστασίας και τη διαμόÏφωση DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Εάν κατανοείτε τους κινδÏνους για την ασφάλειά σας, μποÏείτε να <ph name="BEGIN_LINK" />επισκεφτείτε αυτόν τον μη ασφαλή ιστότοπο<ph name="END_LINK" /> Ï€Ïιν από την κατάÏγηση των επικίνδυνων Ï€ÏογÏαμμάτων.</translation>
<translation id="3739623965217189342">ΣÏνδεσμος που αντιγÏ.</translation>
+<translation id="3744899669254331632">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή, επειδή ο ιστότοπος έστειλε κωδικοποιημένα διαπιστευτήÏια τα οποία δεν είναι δυνατό να επεξεÏγαστεί το Chromium. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά φαινόμενα, συνεπώς η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα.</translation>
+<translation id="3748148204939282805">Οι εισβολείς σε αυτόν τον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> μποÏεί να σας εξαπατήσουν και να κάνετε κάτι επικίνδυνο, όπως να εγκαταστήσετε κάποιο λογισμικό ή να αποκαλÏψετε Ï€Ïοσωπικά σας στοιχεία (για παÏάδειγμα, κωδικοÏÏ‚ Ï€Ïόσβασης, αÏιθμοÏÏ‚ τηλεφώνου ή στοιχεία πιστωτικών καÏτών). <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Η μετάφÏαση απέτυχε λόγω σφάλματος διακομιστή.</translation>
<translation id="3759461132968374835">Δεν έχετε Ï€Ïόσφατα αναφεÏθέντα σφάλματα. Τα σφάλματα που Ï€Ïοέκυψαν όταν η αναφοÏά σφαλμάτων ήταν απενεÏγοποιημένη δεν θα εμφανιστοÏν εδώ.</translation>
+<translation id="3778403066972421603">Θέλετε να αποθηκεÏσετε αυτήν την κάÏτα στον ΛογαÏιασμό σας Google και σε αυτήν τη συσκευή;</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Λήγει <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Εάν χÏησιμοποιείτε διακομιστή μεσολάβησης…</translation>
<translation id="3828924085048779000">Δεν επιτÏέπεται να είναι κενή η φÏάση Ï€Ïόσβασης.</translation>
-<translation id="3845539888601087042">Εμφάνιση ιστοÏÎ¹ÎºÎ¿Ï Î±Ï€ÏŒ τις συνδεδεμένες συσκευές σας. <ph name="BEGIN_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Πίσω</translation>
<translation id="3858027520442213535">ΕνημέÏωση ημεÏομηνίας και ÏŽÏας</translation>
<translation id="3884278016824448484">ΑναγνωÏιστικό συσκευής που Ï€Ïοκαλεί διένεξη</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Το αίτημά σας για να αποκτήσετε Ï€Ïόσβαση σε αυτόν τον ιστότοπο έχει σταλεί στον/η(ν) <ph name="NAME" /></translation>
<translation id="3890664840433101773">ΠÏοσθήκη διεÏθυνσης ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου</translation>
<translation id="3901925938762663762">Η κάÏτα έχει λήξει</translation>
-<translation id="3933571093587347751">{1,plural, =1{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημεÏομηνία του Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Î±ÏƒÏ†Î±Î»ÎµÎ¯Î±Ï‚ του υποτίθεται ότι είναι αυÏιανή. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.}other{Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημεÏομηνία του Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Î±ÏƒÏ†Î±Î»ÎµÎ¯Î±Ï‚ του υποτίθεται ότι είναι από # ημέÏες μετά. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Δεν ήταν δυνατή η φόÏτωση του εγγÏάφου PDF</translation>
+<translation id="3945915738023014686">ΑναγνωÏιστικό μεταφοÏτωμένης αναφοÏάς σφαλμάτων <ph name="CRASH_ID" /> (ΑναγνωÏιστικό Ï„Î¿Ï€Î¹ÎºÎ¿Ï ÏƒÏ†Î¬Î»Î¼Î±Ï„Î¿Ï‚: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Αυτός ο διακομιστής δεν μποÏεί να αποδείξει ότι είναι ο τομέας <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας δεν Ï€ÏοσδιοÏίζει Εναλλακτικά ονόματα θέματος. Αυτό μποÏεί να οφείλεται σε εσφαλμένη διαμόÏφωση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
<translation id="3963721102035795474">ΛειτουÏγία αναγνώστη</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Κανένα}=1{Από 1 ιστότοπο }other{Από # ιστοτόπους }}</translation>
<translation id="397105322502079400">Υπολογισμός…</translation>
<translation id="3973234410852337861">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> είναι αποκλεισμένος</translation>
+<translation id="3987940399970879459">ΛιγότεÏα από 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 ιστοσελίδα σε κοντινή απόσταση}other{# ιστοσελίδες σε κοντινή απόσταση}}</translation>
<translation id="4021036232240155012">Το DNS είναι η υπηÏεσία δικτÏου που μεταφÏάζει το όνομα ενός ιστότοπου στη διεÏθυνσή του στο διαδίκτυο.</translation>
<translation id="4030383055268325496">&amp;ΑναίÏεση Ï€Ïοσθήκης</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Η διαμόÏφωση του διακομιστή μεσολάβησης είναι οÏισμένη να χÏησιμοποιεί μια διεÏθυνση URL σεναÏίου .pac και όχι σταθεÏοÏÏ‚ διακομιστές μεσολάβησης.</translation>
<translation id="4098354747657067197">Ακολουθεί παÏαπλανητικός ιστότοπος</translation>
<translation id="4103249731201008433">Ο σειÏιακός αÏιθμός της συσκευής δεν είναι έγκυÏος</translation>
+<translation id="410351446219883937">Αυτόματη αναπαÏαγωγή</translation>
<translation id="4103763322291513355">Επισκεφτείτε την &lt;strong&gt;chrome://policy&lt;/strong&gt; για να δείτε τη λίστα των ανεπιθÏμητων διευθÏνσεων URL και άλλες πολιτικές που έχουν τεθεί σε εφαÏμογή από το διαχειÏιστή του συστήματός σας.</translation>
-<translation id="4110615724604346410">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του πεÏιέχει σφάλματα. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Ματζέντα</translation>
+<translation id="4116663294526079822">Îα επιτÏέπεται πάντα σε αυτόν τον ιστότοπο</translation>
<translation id="4117700440116928470">Το εÏÏος της πολιτικής δεν υποστηÏίζεται.</translation>
-<translation id="4118212371799607889">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από το Chromium. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 ακόμα}other{# ακόμα}}</translation>
<translation id="4130226655945681476">Έλεγχος καλωδίων, μόντεμ και δÏομολογητή δικτÏου</translation>
+<translation id="413544239732274901">Μάθετε πεÏισσότεÏα</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">ΧÏήση καθολικής Ï€Ïοεπιλογής (Εντοπισμός)</translation>
+<translation id="4165986682804962316">Ρυθμίσεις ιστότοπου</translation>
<translation id="4169947484918424451">Θέλετε το Chromium να αποθηκεÏσει αυτήν την κάÏτα;</translation>
<translation id="4171400957073367226">Εσφαλμένη υπογÏαφή επαλήθευσης</translation>
<translation id="4196861286325780578">&amp;Επανάληψη μετακίνησης</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Ελέγξτε τις διαμοÏφώσεις του τείχους Ï€Ïοστασίας και της Ï€Ïοστασίας από ιοÏÏ‚<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{καμία}=1{1 εφαÏμογή ($1)}=2{2 εφαÏμογές ($1, $2)}other{# εφαÏμογές ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Απότομες διακοπές λειτουÏγίας</translation>
+<translation id="422022731706691852">Οι εισβολείς στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> μποÏεί να Ï€Ïοσπαθήσουν να σας εξαπατήσουν ώστε να εγκαταστήσετε Ï€ÏογÏάμματα που βλάπτουν την εμπειÏία πεÏιήγησής σας (για παÏάδειγμα, αλλάζοντας την αÏχική σελίδα σας ή εμφανίζοντας επιπλέον διαφημίσεις στους ιστοτόπους που επισκέπτεστε). <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Δοκιμάστε να εκτελέσετε τον Διαγνωστικό έλεγχο δικτÏου<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">ΈγκυÏο</translation>
<translation id="4250431568374086873">Η σÏνδεσή σας σε αυτόν τον ιστότοπο δεν είναι πλήÏως ασφαλής</translation>
<translation id="4250680216510889253">Όχι</translation>
<translation id="425582637250725228">Οι αλλαγές που κάνατε ενδέχεται να μην έχουν αποθηκευτεί.</translation>
<translation id="4258748452823770588">Εσφαλμένη υπογÏαφή</translation>
+<translation id="4265872034478892965">ΕπιτÏέπεται από τον διαχειÏιστή σας</translation>
<translation id="4269787794583293679">(ΧωÏίς όνομα χÏήστη)</translation>
<translation id="4275830172053184480">Επανεκκινήστε τη συσκευή σας</translation>
<translation id="4280429058323657511">, λήξη <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Η ασφαλής πεÏιήγηση Google <ph name="BEGIN_LINK" />εντόπισε επιβλαβή Ï€ÏογÏάμματα<ph name="END_LINK" /> στον ιστότοπο <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Γονικές Ï€Ïοτάσεις</translation>
<translation id="4304224509867189079">ΣÏνδεση</translation>
-<translation id="432290197980158659">Αυτός ο διακομιστής παÏουσίασε ένα πιστοποιητικό που δεν αντιστοιχεί στις ενσωματωμένες Ï€Ïοϋποθέσεις. Αυτές οι Ï€Ïοϋποθέσεις συμπεÏιλαμβάνονται σε συγκεκÏιμένους ιστότοπους υψηλής ασφάλειας για την Ï€Ïοστασία σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Αποκλεισμός (Ï€Ïοεπιλογή)</translation>
<translation id="4325863107915753736">Αποτυχία εÏÏεσης άÏθÏου</translation>
<translation id="4326324639298822553">Ελέγξτε την ημεÏομηνία λήξης σας και δοκιμάστε ξανά</translation>
<translation id="4331708818696583467">Μη ασφαλές</translation>
<translation id="4356973930735388585">Οι εισβολείς σε αυτόν τον ιστότοπο μποÏεί να επιχειÏήσουν να εγκαταστήσουν επικίνδυνα Ï€ÏογÏάμματα στον υπολογιστή σας, τα οποία μποÏοÏν να υποκλέψουν ή να διαγÏάψουν τα δεδομένα σας (για παÏάδειγμα, φωτογÏαφίες, κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα και στοιχεία πιστωτικών καÏτών).</translation>
<translation id="4372948949327679948">Αναμενόμενη τιμή <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, όμως το πιστοποιητικό που παÏουσιάστηκε από το διακομιστή ανακλήθηκε από τον εκδότη του. Αυτό σημαίνει ότι τα διαπιστευτήÏια ασφαλείας που παÏουσιάστηκαν από το διακομιστή δεν Ï€Ïέπει σε καμία πεÏίπτωση να θεωÏηθοÏν αξιόπιστα. Ενδέχεται να επικοινωνείτε με κάποιον εισβολέα.</translation>
<translation id="4381091992796011497">Όνομα χÏήστη:</translation>
<translation id="4394049700291259645">ΑπενεÏγοποίηση</translation>
<translation id="4406896451731180161">αποτελέσματα αναζήτησης</translation>
+<translation id="4424024547088906515">Ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από τον Chrome. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
<translation id="4432688616882109544">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> δεν αποδέχτηκε το πιστοποιητικό σÏνδεσής σας ή μποÏεί να μην διατέθηκε πιστοποιητικό σÏνδεσης.</translation>
<translation id="443673843213245140">Η χÏήση ενός διακομιστή μεσολάβησης είναι απενεÏγοποιημένη, αλλά έχει καθοÏιστεί μια Ïητή διαμόÏφωση διακομιστή μεσολάβησης.</translation>
-<translation id="4492190037599258964">Αποτελέσματα αναζήτησης για "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Σφάλμα επικÏÏωσης: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Επικοινωνήστε με το διαχειÏιστή συστήματος</translation>
<translation id="450710068430902550">Κοινοποίηση στο διαχειÏιστή</translation>
<translation id="4515275063822566619">Οι κάÏτες και οι διευθÏνσεις Ï€ÏοέÏχονται από το Chrome και τον ΛογαÏιασμό σας Google (<ph name="ACCOUNT_EMAIL" />). ΜποÏείτε να τις διαχειÏιστείτε στις <ph name="BEGIN_LINK" />Ρυθμίσεις<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">ΛεπτομέÏειες</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Δοκιμάστε να απενεÏγοποιήσετε τις επεκτάσεις σας.</translation>
<translation id="457875822857220463">ΠαÏάδοση</translation>
<translation id="4587425331216688090">ΚατάÏγηση διεÏθυνσης από το Chrome;</translation>
-<translation id="4589078953350245614">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παÏουσίασε ένα μη έγκυÏο πιστοποιητικό. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Η σÏνδεσή σας στο <ph name="DOMAIN" /> κÏυπτογÏαφείται χÏησιμοποιώντας ένα σÏγχÏονο Ï€ÏόγÏαμμα κÏυπτογÏάφησης.</translation>
<translation id="4594403342090139922">&amp;ΑναίÏεση διαγÏαφής</translation>
<translation id="4619615317237390068">ΚαÏτέλες από άλλες συσκευές</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Ο διακομιστής δεν κατάφεÏε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του πεÏιέχει σφάλματα. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
+<translation id="4690462567478992370">Διακοπή χÏήσης μη έγκυÏου πιστοποιητικοÏ</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Η σÏνδεσή σας διακόπηκε</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Îα εκτελέσετε τον Διαγνωστικό έλεγχο δικτÏου των Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">ΠαÏουσιάστηκε άγνωστο σφάλμα.</translation>
<translation id="4800132727771399293">Ελέγξτε την ημεÏομηνία λήξης και τον κωδικό σας CVC και δοκιμάστε ξανά</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Δεν μποÏείτε να επισκεφτείτε το <ph name="SITE" /> αυτήν τη στιγμή επειδή ο ιστότοπος έστειλε κωδικοποιημένα διαπιστευτήÏια τα οποία δεν μποÏεί να επεξεÏγαστεί το Google Chrome. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα.</translation>
<translation id="4813512666221746211">Σφάλμα δικτÏου</translation>
<translation id="4816492930507672669">ΠÏοσαÏμογή στη σελίδα</translation>
<translation id="483020001682031208">Δεν υπάÏχουν σελίδες του Î¦Ï…ÏƒÎ¹ÎºÎ¿Ï Î´Î¹ÎºÏ„Ïου για εμφάνιση</translation>
<translation id="4850886885716139402">ΠÏοβολή</translation>
<translation id="4854362297993841467">Αυτός ο Ï„Ïόπος παÏάδοσης δεν είναι διαθέσιμος. Δοκιμάστε έναν άλλο Ï„Ïόπο.</translation>
<translation id="4858792381671956233">Ρώτησες τους γονείς σου εάν σου επιτÏέπουν να επισκεφτείς αυτόν τον ιστότοπο</translation>
+<translation id="4863764087567530506">Αυτό το πεÏιεχόμενο μποÏεί να Ï€Ïοσπαθήσει να σας εξαπατήσει έτσι ώστε να εγκαταστήσετε λογισμικό ή να αποκαλÏψετε Ï€Ïοσωπικά στοιχεία. <ph name="BEGIN_LINK" />Εμφάνιση οÏτως ή άλλως<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">ΙστοÏικό αναζήτησης</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{και 1 ακόμη ιστοσελίδα}other{και # ακόμη ιστοσελίδες}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Αυτή η σελίδα έχει μεταφÏαστεί από μια άγνωστη γλώσσας στα <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">ΠληÏωμή</translation>
<translation id="4926049483395192435">ΠÏέπει να καθοÏιστεί.</translation>
<translation id="495170559598752135">ΕνέÏγειες</translation>
<translation id="4958444002117714549">Ανάπτυξη λίστας</translation>
-<translation id="4962322354953122629">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από το Chrome. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">ΕπανενεÏγοποίηση Ï€Ïοειδοποιήσεων</translation>
<translation id="4989809363548539747">Αυτή η Ï€Ïοσθήκη δεν υποστηÏίζεται</translation>
<translation id="5002932099480077015">Εάν ενεÏγοποιηθεί, το Chrome θα αποθηκεÏσει ένα αντίγÏαφο της κάÏτας σας σε αυτήν τη συσκευή για ταχÏτεÏη συμπλήÏωση φοÏμών.</translation>
<translation id="5018422839182700155">Δεν είναι δυνατό το άνοιγμα αυτής της σελίδας</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Ελέγξτε τις πολιτικές του διαχειÏιστή</translation>
<translation id="5029568752722684782">ΔιαγÏαφή αντιγÏάφου</translation>
<translation id="5031870354684148875">Σχετικά με τη Google ΜετάφÏαση</translation>
+<translation id="5039804452771397117">ΕπιτÏέπεται</translation>
<translation id="5040262127954254034">ΑπόÏÏητο</translation>
<translation id="5045550434625856497">Λανθασμένος κωδικός Ï€Ïόσβασης</translation>
<translation id="5056549851600133418">ΆÏθÏα για εσάς</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Ελέγξτε τη διεÏθυνση του διακομιστή μεσολάβησης<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{ΧωÏίς cookie}=1{1 ιστότοπος χÏησιμοποιεί cookie. }other{# ιστότοποι χÏησιμοποιοÏν cookie. }}</translation>
<translation id="5087286274860437796">Το πιστοποιητικό του διακομιστή δεν είναι έγκυÏο αυτήν τη στιγμή.</translation>
<translation id="5087580092889165836">ΠÏοσθήκη κάÏτας</translation>
<translation id="5089810972385038852">Πολιτεία</translation>
+<translation id="5094747076828555589">Ο διακομιστής δεν μποÏεί να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από το Chromium. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
<translation id="5095208057601539847">ΕπαÏχία</translation>
<translation id="5115563688576182185">(64-bit)</translation>
<translation id="5141240743006678641">ΚÏυπτογÏαφήστε συγχÏονισμένους κωδικοÏÏ‚ Ï€Ïόσβασης με τα διαπιστευτήÏιά σας Google.</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Απαιτείται διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">ΧÏησιμοποιείτε το Chrome στη δουλειά σας; Οι επιχειÏήσεις μποÏοÏν να διαχειÏίζονται τις Ïυθμίσεις του Chrome για τους εÏγαζόμενοÏÏ‚ τους. Μάθετε πεÏισσότεÏα</translation>
+<translation id="5297526204711817721">Η σÏνδεσή σας σε αυτόν τον ιστότοπο δεν είναι ιδιωτική. Για έξοδο από τη λειτουÏγία VR, ανά πάσα στιγμή, αφαιÏέστε το ακουστικό και πιέστε πίσω.</translation>
<translation id="5299298092464848405">Σφάλμα ανάλυσης πολιτικής</translation>
-<translation id="5300589172476337783">Εμφάνιση</translation>
<translation id="5308689395849655368">Η αναφοÏά σφαλμάτων είναι απενεÏγοποιημένη.</translation>
<translation id="5317780077021120954">Αποθήκευση</translation>
<translation id="5327248766486351172">Όνομα</translation>
-<translation id="5337705430875057403">Οι εισβολείς στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> μποÏεί να σας ξεγελάσουν και να κάνετε κάτι επικίνδυνο, όπως να εγκαταστήσετε κάποιο λογισμικό ή να αποκαλÏψετε Ï€Ïοσωπικά σας στοιχεία (για παÏάδειγμα, κωδικοÏÏ‚ Ï€Ïόσβασης, αÏιθμοÏÏ‚ τηλεφώνου ή πιστωτικές κάÏτες).</translation>
-<translation id="5359637492792381994">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν είναι έγκυÏο αυτήν τη στιγμή. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή επειδή το πιστοποιητικό έχει ανακληθεί. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα.</translation>
<translation id="536296301121032821">Αποτυχία αποθήκευσης Ïυθμίσεων πολιτικής</translation>
<translation id="5386426401304769735">Η αλυσίδα Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Î³Î¹Î± αυτόν τον ιστότοπο πεÏιέχει ένα πιστοποιητικό το οποίο είναι υπογεγÏαμμένο με χÏήση SHA-1.</translation>
<translation id="5402410679244714488">Λήξη: <ph name="EXPIRATION_DATE_ABBR" />, τελευταία χÏήση Ï€Ïιν από πεÏισσότεÏο από ένα έτος</translation>
+<translation id="540969355065856584">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν είναι έγκυÏο αυτήν τη στιγμή. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας.</translation>
<translation id="5421136146218899937">ΔιαγÏαφή δεδομένων πεÏιήγησης...</translation>
<translation id="5430298929874300616">ΚατάÏγηση σελιδοδείκτη</translation>
<translation id="5431657950005405462">Το αÏχείο σας δεν βÏέθηκε</translation>
-<translation id="5435775191620395718">Εμφάνιση ιστοÏÎ¹ÎºÎ¿Ï Î±Ï€ÏŒ αυτήν τη συσκευή. <ph name="BEGIN_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Σφάλμα επαλήθευσης σχήματος σε "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Δεν είναι δυνατός ο εντοπισμός αυτής της σελίδας του κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î® <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">Εσφαλμένη χÏονική σήμανση πολιτικής</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> από <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Μη έγκυÏο</translation>
<translation id="5470861586879999274">&amp;Επανάληψη επεξεÏγασίας</translation>
<translation id="54817484435770891">ΠÏοσθήκη έγκυÏης διεÏθυνσης</translation>
<translation id="5492298309214877701">Αυτός ο ιστότοπος που βÏίσκεται στο εσωτεÏικό δίκτυο της εταιÏείας, του οÏÎ³Î±Î½Î¹ÏƒÎ¼Î¿Ï Î® του σχολείου έχει το ίδιο URL με έναν εξωτεÏικό ιστότοπο.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Δεν είναι δυνατή η παÏαλαβή από αυτήν τη διεÏθυνση. Επιλέξτε μια άλλη διεÏθυνση.</translation>
<translation id="5572851009514199876">Εκκινήστε και συνδεθείτε στο Chrome, έτσι ώστε το Chrome να μποÏεί να ελέγξει εάν έχετε δικαίωμα Ï€Ïόσβασης σε αυτόν τον ιστότοπο.</translation>
<translation id="5580958916614886209">Ελέγξτε τον μήνα λήξης σας και δοκιμάστε ξανά</translation>
+<translation id="5586446728396275693">Δεν υπάÏχουν αποθηκευμένες διευθÏνσεις</translation>
+<translation id="5595485650161345191">ΕπεξεÏγασία διεÏθυνσης</translation>
<translation id="560412284261940334">Η διαχείÏιση δεν υποστηÏίζεται</translation>
<translation id="5610142619324316209">Ελέγξτε τη σÏνδεση</translation>
<translation id="5610807607761827392">ΜποÏείτε να διαχειÏιστείτε τις κάÏτες και τις διευθÏνσεις στις <ph name="BEGIN_LINK" />Ρυθμίσεις<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Θέλετε να φÏγετε από αυτόν τον ιστότοπο;</translation>
<translation id="5629630648637658800">Αποτυχία φόÏτωσης Ïυθμίσεων πολιτικής</translation>
<translation id="5631439013527180824">Μη έγκυÏο διακÏιτικό διαχείÏισης συσκευής</translation>
+<translation id="5633066919399395251">Οι εισβολείς που βÏίσκονται αυτήν τη στιγμή στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ενδέχεται να επιχειÏήσουν να εγκαταστήσουν επικίνδυνα Ï€ÏογÏάμματα στον υπολογιστή σας, τα οποία μποÏοÏν να υποκλέψουν ή να διαγÏάψουν τα δεδομένα σας (για παÏάδειγμα, φωτογÏαφίες, κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα και στοιχεία πιστωτικών καÏτών). <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Τοποθεσία</translation>
+<translation id="5659593005791499971">ΔιεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου</translation>
<translation id="5669703222995421982">Λήψη εξατομικευμένου πεÏιεχομένου</translation>
<translation id="5675650730144413517">Αυτή η σελίδα δεν λειτουÏγεί</translation>
-<translation id="5677928146339483299">Αποκλεισμένος</translation>
-<translation id="5694783966845939798">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παÏουσίασε ένα πιστοποιητικό το οποίο ήταν υπογεγÏαμμένο με έναν αδÏναμο αλγόÏιθμο υπογÏαφής (όπως SHA-1). Αυτό σημαίνει ότι μποÏεί να έχουν πλαστογÏαφηθεί τα διαπιστευτήÏια ασφαλείας που επέδειξε ο διακομιστής και ότι αυτός ο διακομιστής μποÏεί να μην είναι αυτό που πεÏιμένατε (μποÏεί να επικοινωνείτε με έναν εισβολέα). <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Η ταυτότητα Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… ιστότοπου δεν έχει επαληθευτεί.</translation>
+<translation id="5713016350996637505">Το παÏαπλανητικό πεÏιεχόμενο αποκλείστηκε</translation>
<translation id="5720705177508910913">ΤÏέχων χÏήστης</translation>
<translation id="5732392974455271431">Οι γονείς σου μποÏοÏν να καταÏγήσουν τον αποκλεισμό του</translation>
<translation id="5763042198335101085">Εισαγάγετε μια έγκυÏη διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου</translation>
<translation id="5765072501007116331">Για να δείτε Ï„Ïόπους και απαιτήσεις παÏάδοσης, επιλέξτε μια διεÏθυνση</translation>
+<translation id="5778550464785688721">ΠλήÏης έλεγχος συσκευών MIDI</translation>
<translation id="5784606427469807560">ΠαÏουσιάστηκε κάποιο Ï€Ïόβλημα κατά την επιβεβαίωση της κάÏτας σας. Ελέγξτε τη σÏνδεσή σας στο διαδίκτυο και δοκιμάστε ξανά.</translation>
<translation id="5785756445106461925">Επίσης, αυτή η σελίδα πεÏιέχει άλλους πόÏους, οι οποίοι δεν είναι ασφαλείς. Αυτοί οι πόÏοι μποÏοÏν να Ï€ÏοβληθοÏν από άλλους χÏήστες κατά τη μετάβαση και μποÏοÏν να Ï„ÏοποποιηθοÏν από έναν εισβολέα ώστε να αλλάξει η εμφάνιση της σελίδας.</translation>
<translation id="5786044859038896871">Θέλετε να συμπληÏωθοÏν τα στοιχεία της κάÏτας σας;</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Επανάληψη Ï€Ïοσθήκης</translation>
<translation id="5814352347845180253">Ενδέχεται να χάσετε την Ï€Ïόσβαση σε Ï€Ïονομιακό πεÏιεχόμενο από τον ιστότοπο <ph name="SITE" /> και οÏισμένους άλλους ιστότοπους.</translation>
<translation id="5838278095973806738">Δεν θα Ï€Ïέπει να εισαγάγετε ευαίσθητες πληÏοφοÏίες σε αυτόν τον ιστότοπο (για παÏάδειγμα, κωδικοÏÏ‚ Ï€Ïόσβασης ή πιστωτικές κάÏτες), επειδή ενδέχεται να υποκλαποÏν από εισβολείς.</translation>
-<translation id="5843436854350372569">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παÏουσίασε ένα πιστοποιητικό που πεÏιέχει ένα αδÏναμο κλειδί. Κάποιος εισβολέας θα μποÏοÏσε να έχει παÏαβιάσει το ιδιωτικό κλειδί και ο διακομιστής ενδέχεται να μην είναι ο διακομιστής που αναμένατε (μποÏεί να επικοινωνείτε με έναν εισβολέα). <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Δεν είναι δυνατή η Ï€Ïόσβαση σε αυτόν τον ιστότοπο</translation>
<translation id="5869522115854928033">Αποθηκευμένοι κωδικοί Ï€Ïόσβασης</translation>
<translation id="5872918882028971132">Γονικές Ï€Ïοτάσεις</translation>
<translation id="5901630391730855834">ΚίτÏινο</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (συγχÏονισμένο)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 σε χÏήση}other{# σε χÏήση}}</translation>
<translation id="5926846154125914413">Ενδέχεται να χάσετε την Ï€Ïόσβαση σε Ï€Ïονομιακό πεÏιεχόμενο από οÏισμένους ιστότοπους.</translation>
<translation id="5959728338436674663">Αυτόματη αποστολή οÏισμένων <ph name="BEGIN_WHITEPAPER_LINK" />πληÏοφοÏιών συστήματος και πεÏιεχομένου σελίδων<ph name="END_WHITEPAPER_LINK" /> στην Google για διευκόλυνση του ÎµÎ½Ï„Î¿Ï€Î¹ÏƒÎ¼Î¿Ï ÎµÏ€Î¹ÎºÎ¯Î½Î´Ï…Î½Ï‰Î½ εφαÏμογών και ιστοτόπων<ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Εβδομάδα</translation>
<translation id="5967867314010545767">ΚατάÏγηση από το ιστοÏικό</translation>
<translation id="5975083100439434680">ΣμίκÏυνση</translation>
<translation id="598637245381783098">Δεν είναι δυνατό το άνοιγμα της εφαÏμογής πληÏωμής</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1 σελίδα}other{# σελίδες}}</translation>
<translation id="6017514345406065928">ΠÏάσινο</translation>
+<translation id="6017850046339264347">Οι εισβολείς στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> θα μποÏοÏσαν να εγκαταστήσουν παÏαπλανητικές εφαÏμογές που Ï€ÏοσποιοÏνται ότι είναι κάτι άλλο ή συλλέγουν δεδομένα τα οποία μποÏεί να χÏησιμοποιηθοÏν για την παÏακολοÏθησή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (συγχÏονισμένο)</translation>
<translation id="6027201098523975773">Εισαγωγή ονόματος</translation>
<translation id="6040143037577758943">Κλείσιμο</translation>
<translation id="6042308850641462728">ΠεÏισσότεÏα</translation>
+<translation id="6047233362582046994">Εάν κατανοείτε τους κινδÏνους για την ασφάλειά σας, μποÏείτε να <ph name="BEGIN_LINK" />επισκεφτείτε αυτόν τον ιστότοπο<ph name="END_LINK" /> Ï€Ïιν από την κατάÏγηση των επιβλαβών εφαÏμογών.</translation>
+<translation id="6051221802930200923">Δεν μποÏείτε να επισκεφτείτε το <ph name="SITE" /> αυτήν τη στιγμή επειδή ο ιστότοπος χÏησιμοποιεί certificate pinning (κλείδωμα πιστοποιητικών). Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα.</translation>
<translation id="6060685159320643512">ΠÏοσοχή, τέτοια πειÏάματα είναι επικÏνδυνα</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{καμία}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Η Ï€Ïόσβασή σας στο πεÏιεχόμενο Ï€Ïαγματοποιήθηκε με τη χÏήση ενός Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Ï€Î¿Ï… παÏασχέθηκε από διαχειÏιστή. Τα δεδομένα που παÏέχετε στο <ph name="DOMAIN" /> μποÏεί να ελέγχονται από το διαχειÏιστή σας.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Κανένας}=1{1 κωδικός Ï€Ïόσβασης (συγχÏονισμένος)}other{# κωδικοί Ï€Ïόσβασης (συγχÏονισμένοι)}}</translation>
<translation id="6146055958333702838">Ελέγξτε τυχόν καλώδια και επανεκκινήστε δÏομολογητές, μόντεμ ή άλλες συσκευές
του δικτÏου που ενδεχομένως χÏησιμοποιείτε.</translation>
<translation id="614940544461990577">Δοκιμάστε να κάνετε τα εξής:</translation>
<translation id="6151417162996330722">Το πιστοποιητικό του διακομιστή έχει Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î· πεÏίοδο εγκυÏότητας.</translation>
<translation id="6157877588268064908">Για να δείτε Ï„Ïόπους και απαιτήσεις αποστολής, επιλέξτε μια διεÏθυνση</translation>
+<translation id="6158003235852588289">ΠÏόσφατα η Ασφαλής πεÏιήγηση Google εντόπισε εκδηλώσεις ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï ÏˆÎ±Ïέματος (phishing) στον ιστότοπο <ph name="SITE" />. Οι ιστότοποι ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï ÏˆÎ±Ïέματος (phishing) παÏουσιάζονται ψευδώς σαν άλλου Ï„Ïπου ιστότοποι για να σας εξαπατήσουν.</translation>
<translation id="6165508094623778733">Μάθετε πεÏισσότεÏα</translation>
+<translation id="6169916984152623906">Στο εξής μποÏείτε να πεÏιηγηθείτε ιδιωτικά και η δÏαστηÏιότητά σας δεν θα είναι οÏατή στα άλλα άτομα που χÏησιμοποιοÏν αυτήν τη συσκευή. Ωστόσο, οι λήψεις και οι σελιδοδείκτες θα αποθηκεÏονται</translation>
<translation id="6177128806592000436">Η σÏνδεσή σας σε αυτόν τον ιστότοπο δεν είναι ασφαλής</translation>
<translation id="6184817833369986695">(κοόÏτη: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Ελέγξτε τη σÏνδεσή σας στο Internet</translation>
<translation id="6218753634732582820">Îα καταÏγηθεί η διεÏθυνση από το Chromium;</translation>
+<translation id="6221345481584921695">ΠÏόσφατα η Ασφαλής πεÏιήγηση Google <ph name="BEGIN_LINK" />εντόπισε κακόβουλο λογισμικό<ph name="END_LINK" /> στον ιστότοπο <ph name="SITE" />. Οι ιστότοποι που είναι ασφαλείς υπό φυσιολογικές συνθήκες μεÏικές φοÏές Ï€Ïοσβάλλονται από κακόβουλα λογισμικά. Το κακόβουλο πεÏιεχόμενο Ï€ÏοέÏχεται από το <ph name="SUBRESOURCE_HOST" />, έναν γνωστό διανομέα κακόβουλου λογισμικοÏ.</translation>
<translation id="6251924700383757765">Πολιτική αποÏÏήτου</translation>
<translation id="6254436959401408446">Δεν υπάÏχει αÏκετή μνήμη για το άνοιγμα αυτής της σελίδας</translation>
<translation id="625755898061068298">Έχετε επιλέξει να απενεÏγοποιήσετε τις Ï€Ïοειδοποιήσεις ασφάλειας για αυτόν τον ιστότοπο.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">ΕπεξεÏγασία σελιδοδείκτη</translation>
<translation id="6410264514553301377">Εισαγάγετε την ημεÏομηνία λήξης και τον κωδικό CVC για την κάÏτα <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Ρώτησες τους γονείς σου εάν σου επιτÏέπουν να επισκεφτείς αυτόν τον ιστότοπο</translation>
-<translation id="6416403317709441254">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή γιατί ο ιστότοπος έστειλε κωδικοποιημένα διαπιστευτήÏια τα οποία δεν είναι δυνατό να επεξεÏγαστεί το Chromium. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά φαινόμενα, συνεπώς η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Δεν είναι δυνατόν να ελεγχθεί αν το πιστοποιητικό έχει ακυÏωθεί.</translation>
<translation id="6433490469411711332">ΕπεξεÏγασία στοιχείων επαφής</translation>
<translation id="6433595998831338502">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> απέÏÏιψε τη σÏνδεση.</translation>
<translation id="6446608382365791566">ΠÏοσθήκη πεÏισσότεÏων πληÏοφοÏιών</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Επιβεβαίωση νέας υποβολής φόÏμας</translation>
<translation id="6456339708790392414">Η πληÏωμή σας</translation>
<translation id="6458467102616083041">Αγνοήθηκε επειδή η Ï€Ïοεπιλεγμένη αναζήτηση είναι απενεÏγοποιημένη από την πολιτική.</translation>
-<translation id="6462969404041126431">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μποÏεί να ανακληθεί. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Πολιτικές συσκευών </translation>
<translation id="6477321094435799029">Το Chrome εντόπισε ασυνήθιστο κώδικα σε αυτήν τη σελίδα και τον απέκλεισε για να Ï€ÏοστατεÏσει τα Ï€Ïοσωπικά σας στοιχεία (για παÏάδειγμα, κωδικοÏÏ‚ Ï€Ïόσβασης, αÏιθμοÏÏ‚ τηλεφώνου ή πιστωτικές κάÏτες).</translation>
<translation id="6489534406876378309">ΈναÏξη μεταφόÏτωσης σφαλμάτων</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Λήξη: <ph name="EXPIRATION_DATE_ABBR" />, τελευταία χÏήση <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Ο διαχειÏιστής σας δεν τον έχει εγκÏίνει ακόμα</translation>
<translation id="6569060085658103619">Βλέπετε μια σελίδα επέκτασης</translation>
-<translation id="6593753688552673085">λιγότεÏο από <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Αυτό το πεÏιεχόμενο μποÏεί να Ï€Ïοσπαθήσει να εγκαταστήσει επικίνδυνο λογισμικό στη συσκευή σας το οποίο κλέβει ή διαγÏάφει τα στοιχεία σας. <ph name="BEGIN_LINK" />Εμφάνιση οÏτως ή άλλως<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Επιλογές κÏυπτογÏάφησης</translation>
<translation id="662080504995468778">ΠαÏαμονή</translation>
<translation id="6626291197371920147">ΠÏοσθήκη έγκυÏου αÏÎ¹Î¸Î¼Î¿Ï ÎºÎ¬Ïτας</translation>
<translation id="6628463337424475685">Αναζήτηση <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Οι εισβολείς που βÏίσκονται αυτήν τη στιγμή στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ενδέχεται να επιχειÏήσουν να εγκαταστήσουν επικίνδυνα Ï€ÏογÏάμματα στον υπολογιστή σας Mac, για να υποκλέψουν ή να διαγÏάψουν τα δεδομένα σας (για παÏάδειγμα, φωτογÏαφίες, κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα και πιστωτικές κάÏτες). <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Αυτή η πολιτική έχει αποσυÏθεί.</translation>
-<translation id="6652240803263749613">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από το λειτουÏγικό σÏστημα του υπολογιστή σας. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Îα καταÏγηθεί η Ï€Ïόταση φόÏμας από το Chromium;</translation>
<translation id="6685834062052613830">Αποσυνδεθείτε και ολοκληÏώστε την εγκατάσταση</translation>
<translation id="6710213216561001401">ΠÏοηγοÏμενο</translation>
<translation id="6710594484020273272">&lt;ΠληκτÏολογήστε ÏŒÏο αναζήτησης&gt;</translation>
<translation id="6711464428925977395">ΥπάÏχει κάποιο Ï€Ïόβλημα με το διακομιστή μεσολάβησης ή η διεÏθυνση είναι εσφαλμένη.</translation>
<translation id="6727102863431372879">ΟÏισμός</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{καμία}=1{1 στοιχείο}other{# στοιχεία}}</translation>
<translation id="674375294223700098">Άγνωστο σφάλμα Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¹Î·Ï„Î¹ÎºÎ¿Ï Î´Î¹Î±ÎºÎ¿Î¼Î¹ÏƒÏ„Î®</translation>
<translation id="6753269504797312559">Τιμή πολιτικής</translation>
<translation id="6757797048963528358">Η συσκευή σας τέθηκε σε αδÏάνεια.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ΑναγνωÏιστικό Ï€ÏοσαÏμογής</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Δεν ήταν δυνατή η φόÏτωση των δεδομένων πεÏιοχών</translation>
+<translation id="6825578344716086703">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παÏουσίασε ένα πιστοποιητικό το οποίο ήταν υπογεγÏαμμένο με έναν αδÏναμο αλγόÏιθμο υπογÏαφής (όπως SHA-1). Αυτό σημαίνει ότι μποÏεί να έχουν πλαστογÏαφηθεί τα διαπιστευτήÏια ασφαλείας που επέδειξε ο διακομιστής και ότι αυτός ο διακομιστής ενδέχεται να μην είναι αυτό που αναμένετε (ενδέχεται να επικοινωνείτε με έναν εισβολέα).</translation>
+<translation id="6830728435402077660">Μη ασφαλές</translation>
<translation id="6831043979455480757">ΜετάφÏαση</translation>
<translation id="6839929833149231406">ΠεÏιοχή</translation>
<translation id="6874604403660855544">&amp;Επανάληψη Ï€Ïοσθήκης</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Η κάÏτα σας επιβεβαιώθηκε</translation>
<translation id="6897140037006041989">ΠαÏάγοντας χÏήστη</translation>
<translation id="6915804003454593391">ΧÏήστης</translation>
+<translation id="6945221475159498467">Επιλογή</translation>
<translation id="6948701128805548767">Για να δείτε Ï„Ïόπους και απαιτήσεις παÏαλαβής, επιλέξτε μια διεÏθυνση</translation>
<translation id="6957887021205513506">Το πιστοποιητικό του διακομιστή φαίνεται να είναι πλαστό.</translation>
<translation id="6965382102122355670">ΕÎΤΑΞΕΙ</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">ΚαθοÏίζονται τόσο οι σταθεÏοί διακομιστές μεσολάβησης όσο και μια διεÏθυνση URL σεναÏίου .pac.</translation>
<translation id="6989763994942163495">Εμφάνιση σÏνθετων Ïυθμίσεων…</translation>
<translation id="7000990526846637657">Δεν βÏέθηκαν καταχωÏίσεις ιστοÏικοÏ</translation>
-<translation id="7009986207543992532">ΠÏοσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, αλλά ο διακομιστής παÏουσίασε ένα πιστοποιητικό με πεÏίοδο εγκυÏότητας η οποία είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î· για να θεωÏηθεί αξιόπιστη. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Ο ΛογαÏιασμός σας Google ενδέχεται να διαθέτει άλλες μοÏφές ιστοÏÎ¹ÎºÎ¿Ï Ï€ÎµÏιήγησης στη διεÏθυνση <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Κωδικοί Ï€Ïόσβασης</translation>
+<translation id="7050187094878475250">ΕπιχειÏήσατε να μεταβείτε στο <ph name="DOMAIN" />, αλλά ο διακομιστής παÏουσίασε ένα πιστοποιητικό με πεÏίοδο εγκυÏότητας η οποία είναι Ï€Î¿Î»Ï Î¼ÎµÎ³Î¬Î»Î· για να θεωÏηθεί αξιόπιστη.</translation>
+<translation id="7053983685419859001">Αποκλεισμός</translation>
<translation id="7064851114919012435">Στοιχεία επικοινωνίας</translation>
<translation id="7079718277001814089">Ο ιστότοπος πεÏιέχει κακόβουλο Ï€ÏόγÏαμμα</translation>
<translation id="7087282848513945231">ΠεÏιφέÏεια</translation>
-<translation id="7088615885725309056">ΠαλαιότεÏο</translation>
<translation id="7090678807593890770">Αναζητήστε στο Google για <ph name="LINK" /></translation>
+<translation id="7108819624672055576">ΕπιτÏέπεται από μια επέκταση</translation>
<translation id="7119414471315195487">Κλείστε τις άλλες καÏτέλες ή τα Ï€ÏογÏάμματα</translation>
<translation id="7129409597930077180">Δεν είναι δυνατή η αποστολή σε αυτήν τη διεÏθυνση. Επιλέξτε μια άλλη διεÏθυνση.</translation>
<translation id="7138472120740807366">Μέθοδος Ï€Ïοβολής</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">ΕπεξεÏγασία</translation>
<translation id="724691107663265825">Ο ιστότοπος μετάβασης πεÏιέχει κακόβουλο λογισμικό</translation>
<translation id="724975217298816891">Εισαγάγετε την ημεÏομηνία λήξης και τον κωδικό CVC για την πιστωτική κάÏτα <ph name="CREDIT_CARD" />, Ï€Ïοκειμένου να ενημεÏώσετε τα στοιχεία της κάÏτας σας. Μετά την επιβεβαίωση, θα γίνει κοινή χÏήση των στοιχείων της κάÏτας σας με αυτόν τον ιστότοπο.</translation>
-<translation id="725866823122871198">Δεν είναι δυνατή η επίτευξη ιδιωτικής σÏνδεσης με τον τομέα <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημεÏομηνία και η ÏŽÏα (<ph name="DATE_AND_TIME" />) του υπολογιστή σας είναι λανθασμένες.</translation>
+<translation id="7260504762447901703">Ανάκληση Ï€Ïόσβασης</translation>
<translation id="7275334191706090484">ΔιαχειÏιζόμενοι σελιδοδείκτες</translation>
<translation id="7298195798382681320">ΠÏοτεινόμενες</translation>
<translation id="7309308571273880165">ΑναφοÏά σφαλμάτων που καταγÏάφηκε στις <ph name="CRASH_TIME" /> (η μεταφόÏτωση ζητήθηκε από τον χÏήστη, δεν έχει μεταφοÏτωθεί ακόμη)</translation>
<translation id="7334320624316649418">&amp;Επανάληψη αναδιάταξης</translation>
<translation id="733923710415886693">Το πιστοποιητικό του διακομιστή δεν αποκαλÏφθηκε μέσω της Διαφάνειας πιστοποιητικών.</translation>
-<translation id="7351800657706554155">Δεν μποÏείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή γιατί το πιστοποιητικό του έχει ανακληθεί. Τα σφάλματα δικτÏου και οι επιθέσεις είναι συνήθως Ï€ÏοσωÏινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουÏγήσει αÏγότεÏα. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">ΓÏαμμή εντολών</translation>
<translation id="7372973238305370288">αποτέλεσμα αναζήτησης</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Όχι</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Επιβεβαίωση κάÏτας</translation>
-<translation id="7394102162464064926">Είστε βέβαιοι ότι θέλετε να διαγÏάψετε αυτές τις σελίδες από το ιστοÏικό σας;
-
-Η κατάσταση ανώνυμης πεÏιήγησης <ph name="SHORTCUT_KEY" /> μποÏεί να είναι χÏήσιμη την επόμενη φοÏά.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">ΔιαδÏομή Ï€Ïοφίλ</translation>
<translation id="7424977062513257142">Μια ενσωματωμένη σελίδα σε αυτό τον ιστότοπο λέει:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">Αυτός ο ιστότοπος είναι αποκλεισμένος</translation>
<translation id="7445762425076701745">Η ταυτότητα του διακομιστή στον οποίο έχετε συνδεθεί δεν μποÏεί να επικυÏωθεί πλήÏως. Είστε συδεδεμένοι σε ένα διακομιστή χÏησιμοποιώντας ένα όνομα που είναι έγκυÏο μόνο εντός του δικτÏου σας, την κατοχή του οποίου δεν έχει Ï„Ïόπο να επικυÏώσει μια εξωτεÏική αÏχή πιστοποίησης. Καθώς οÏισμένες αÏχές πιστοποιητικών εκδίδουν πιστοποιητικά για αυτά τα ονόματα οÏτως ή άλλως, δεν υπάÏχει Ï„Ïόπος να βεβαιωθείτε ότι είστε συνδεδεμένοι στον ιστότοπο που επιθυμείτε και όχι σε έναν εισβολέα.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Îα μάθετε πεÏισσότεÏα<ph name="END_LINK" /> σχετικά με αυτό το Ï€Ïόβλημα.</translation>
+<translation id="7455133967321480974">ΧÏήση καθολικής Ï€Ïοεπιλεγμένης ÏÏθμισης (Αποκλεισμός)</translation>
<translation id="7460163899615895653">Οι Ï€Ïόσφατες καÏτέλες σας από άλλες συσκευές εμφανίζονται εδώ</translation>
<translation id="7469372306589899959">Επιβεβαίωση κάÏτας</translation>
<translation id="7481312909269577407">ΠÏοώθηση</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">Η εμφανιζόμενη συσκευή πολιτικής είναι κενή ή δεν αντιστοιχεί στο Ï„Ïέχον αναγνωÏιστικό συσκευής</translation>
<translation id="7514365320538308">Λήψη</translation>
<translation id="7518003948725431193">Δεν βÏέθηκε καμία ιστοσελίδα για τη διεÏθυνση ιστοÏ:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Τιμή</translation>
<translation id="7537536606612762813">ΥποχÏεωτική</translation>
+<translation id="7542403920425041731">Μετά την επιβεβαίωση, τα στοιχεία της κάÏτας θα κοινοποιηθοÏν σε αυτόν τον ιστότοπο.</translation>
<translation id="7542995811387359312">Η αυτόματη συμπλήÏωση πιστωτικής κάÏτας έχει απενεÏγοποιηθεί, επειδή αυτή η φόÏμα δεν χÏησιμοποιεί ασφαλή σÏνδεση.</translation>
<translation id="7543525346216957623">Ζητήστε την άδεια του γονέα σας</translation>
<translation id="7549584377607005141">Για τη σωστή εμφάνιση αυτής της ιστοσελίδας, απαιτοÏνται δεδομένα που καταχωÏίσατε νωÏίτεÏα. ΜποÏείτε να αποστείλετε ξανά αυτά τα δεδομένα, ωστόσο, έτσι θα επαναλάβετε κάθε ενέÏγεια που εκτέλεσε νωÏίτεÏα αυτή η σελίδα.</translation>
<translation id="7552846755917812628">Δοκιμάστε τις παÏακάτω συμβουλές:</translation>
<translation id="7554791636758816595">Îέα καÏτέλα</translation>
+<translation id="7567204685887185387">Ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μποÏεί να εκδόθηκε παÏάνομα. Αυτό μποÏεί να οφείλεται σε λανθασμένη ÏÏθμιση ή σε κάποιον Ï„Ïίτο που επιτίθεται στη σÏνδεσή σας.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ακόμη}other{<ph name="CONTACT_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ακόμη}}</translation>
<translation id="7568593326407688803">Αυτή η σελίδα είναι στα<ph name="ORIGINAL_LANGUAGE" />Θέλετε να τη μεταφÏάσετε;</translation>
<translation id="7569952961197462199">ΚατάÏγηση πιστωτικής κάÏτας από το Chrome;</translation>
<translation id="7569983096843329377">ΜαÏÏο</translation>
<translation id="7578104083680115302">Κάντε γÏήγοÏες πληÏωμές σε ιστότοπους και εφαÏμογές σε διαφοÏετικές συσκευές χÏησιμοποιώντας κάÏτες που έχετε αποθηκεÏσει στο Google.</translation>
<translation id="7588950540487816470">Φυσικό δίκτυο</translation>
<translation id="7592362899630581445">Το πιστοποιητικό του διακομιστή παÏαβαίνει τους πεÏιοÏισμοÏÏ‚ ονόματος.</translation>
+<translation id="7598391785903975535">ΛιγότεÏο από <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Αυτήν τη στιγμή, ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> δεν μποÏεί να διαχειÏιστεί αυτό το αίτημα.</translation>
<translation id="7600965453749440009">Îα μην γίνεται ποτέ μετάφÏαση από <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Η τιμή είναι εκτός του εÏÏους τιμών <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Λήξη: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Έχετε ήδη δεδομένα που είναι κÏυπτογÏαφημένα με χÏήση διαφοÏετικής έκδοσης του ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€Ïόσβασης για τον ΛογαÏιασμό σας Google. Εισαγάγετέ τον παÏακάτω.</translation>
-<translation id="7634554953375732414">Η σÏνδεσή σας σε αυτόν τον ιστότοπο δεν είναι ιδιωτική.</translation>
<translation id="7637571805876720304">Îα καταÏγηθεί η πιστωτική κάÏτα από το Chromium;</translation>
<translation id="765676359832457558">ΑπόκÏυψη σÏνθετων Ïυθμίσεων…</translation>
<translation id="7658239707568436148">ΑκÏÏωση</translation>
+<translation id="7662298039739062396">Η ÏÏθμιση ελέγχεται από μια επέκταση</translation>
<translation id="7667346355482952095">Το εμφανιζόμενο διακÏιτικό πολιτικής είναι κενό ή δεν αντιστοιχεί στο Ï„Ïέχον διακÏιτικό</translation>
<translation id="7668654391829183341">Άγνωστη συσκευή</translation>
<translation id="7669271284792375604">Οι εισβολείς σε αυτόν τον ιστότοπο μποÏεί να επιχειÏήσουν να σας ξεγελάσουν, έτσι ώστε να εγκαταστήσετε Ï€ÏογÏάμματα που βλάπτουν την εμπειÏία πεÏιήγησής σας (για παÏάδειγμα, αλλάζοντας την αÏχική σελίδα σας ή εμφανίζοντας επιπλέον διαφημίσεις στους ιστότοπους που επισκέπτεστε).</translation>
<translation id="7674629440242451245">Θέλετε να ενημεÏώνεστε για τις συναÏπαστικές νέες δυνατότητες του Chrome; Επισκεφτείτε το κανάλι Ï€ÏογÏαμματιστών στη διεÏθυνση chrome.com/dev.</translation>
<translation id="7682287625158474539">Αποστολή</translation>
+<translation id="7701040980221191251">Καμία</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Μετάβαση στον ιστότοπο <ph name="SITE" /> (μη ασφαλής)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Πιστοποιητικό</translation>
+<translation id="7716147886133743102">Αποκλείστηκε από τον διαχειÏιστή σας</translation>
<translation id="7716424297397655342">Δεν είναι δυνατή η φόÏτωση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… ιστότοπου από την κÏυφή μνήμη</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">ΧωÏίς διαχείÏιση</translation>
<translation id="7755287808199759310">Ο γονέας σας μποÏεί να καταÏγήσει τον αποκλεισμό του για εσάς</translation>
<translation id="7758069387465995638">Το τείχος Ï€Ïοστασίας ή το λογισμικό Ï€Ïοστασίας από ιοÏÏ‚ ενδέχεται να έχει αποκλείσει τη σÏνδεση.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Σελιδοδείκτες κινητής συσκευής</translation>
<translation id="7961015016161918242">Ποτέ</translation>
-<translation id="7962083544045318153">ΑναγνωÏιστικό σφάλματος <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Îα γίνεται πάντα μετάφÏαση των <ph name="ORIGINAL_LANGUAGE" /> στα <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Δεν καθοÏίστηκε</translation>
<translation id="800218591365569300">Δοκιμάστε να κλείσετε τις άλλες καÏτέλες ή τα άλλα Ï€ÏογÏάμματα για να απελευθεÏώσετε μνήμη.</translation>
<translation id="8012647001091218357">Δεν ήταν δυνατή η επικοινωνία με τους γονείς σας αυτήν τη στιγμή. Δοκιμάστε ξανά.</translation>
<translation id="8025119109950072390">Οι εισβολείς σε αυτόν τον ιστότοπο μποÏεί να σας ξεγελάσουν και να κάνετε κάτι επικίνδυνο, όπως να εγκαταστήσετε κάποιο λογισμικό ή να αποκαλÏψετε Ï€Ïοσωπικά σας στοιχεία (για παÏάδειγμα, κωδικοÏÏ‚ Ï€Ïόσβασης, αÏιθμοÏÏ‚ τηλεφώνου ή πιστωτικές κάÏτες).</translation>
-<translation id="803030522067524905">Η Ασφαλής πεÏιήγηση Google εντόπισε Ï€Ïόσφατα εκδηλώσεις ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï ÏˆÎ±Ïέματος (phishing) <ph name="SITE" />. Οι ιστότοποι ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï ÏˆÎ±Ïέματος (phishing) παÏουσιάζονται ψευδώς σαν άλλου Ï„Ïπου ιστότοποι για να σας ξεγελάσουν. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Αυτή η σελίδα είναι στα <ph name="SOURCE_LANGUAGE" />. ΜετάφÏασή της στα <ph name="TARGET_LANGUAGE" />;</translation>
+<translation id="8037357227543935929">Îα γίνεται εÏώτηση (Ï€Ïοεπιλογή)</translation>
<translation id="8041089156583427627">Αποστολή σχολίων</translation>
+<translation id="8041940743680923270">ΧÏήση καθολικής Ï€Ïοεπιλεγμένης ÏÏθμισης (ΕÏώτηση)</translation>
<translation id="8088680233425245692">Αποτυχία Ï€Ïοβολής άÏθÏου.</translation>
<translation id="8089520772729574115">λιγότεÏο από 1 MB</translation>
<translation id="8091372947890762290">Η ενεÏγοποίηση στο διακομιστή εκκÏεμεί</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007">Δεν ήταν δυνατή η εÏÏεση της <ph name="BEGIN_ABBR" />διεÏθυνσης DNS<ph name="END_ABBR" /> του διακομιστή <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Ο υπολογιστής σας τέθηκε σε αδÏάνεια.</translation>
<translation id="8150722005171944719">Δεν είναι δυνατή η ανάγνωση του αÏχείου στη διεÏθυνση <ph name="URL" />. Ενδέχεται να καταÏγήθηκε, να μετακινήθηκε ή τα δικαιώματα αÏχείου μποÏεί να μην επιτÏέπουν την Ï€Ïόσβαση.</translation>
+<translation id="8184538546369750125">ΧÏήση καθολικής Ï€Ïοεπιλεγμένης ÏÏθμισης (ΕπιτÏέπεται)</translation>
+<translation id="8191494405820426728">ΑναγνωÏιστικό Ï„Î¿Ï€Î¹ÎºÎ¿Ï ÏƒÏ†Î¬Î»Î¼Î±Ï„Î¿Ï‚ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;ΑναίÏεση μετακίνησης</translation>
<translation id="8201077131113104583">Η διεÏθυνση URL ενημέÏωσης για την επέκταση με αναγνωÏιστικό ID "<ph name="EXTENSION_ID" />", δεν είναι έγκυÏη.</translation>
<translation id="8202097416529803614">ΣÏνοψη παÏαγγελίας</translation>
<translation id="8218327578424803826">ΕκχωÏημένη τοποθεσία:</translation>
<translation id="8225771182978767009">Το άτομο που ÏÏθμισε αυτόν τον υπολογιστή επέλεξε να αποκλείσει αυτόν τον ιστότοπο.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Οι εισβολείς που βÏίσκονται αυτήν τη στιγμή στον ιστότοπο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ενδέχεται να επιχειÏήσουν να εγκαταστήσουν επικίνδυνα Ï€ÏογÏάμματα στον υπολογιστή σας, τα οποία μποÏοÏν να υποκλέψουν ή να διαγÏάψουν τα δεδομένα σας (για παÏάδειγμα, φωτογÏαφίες, κωδικοÏÏ‚ Ï€Ïόσβασης, μηνÏματα και στοιχεία πιστωτικών καÏτών).</translation>
<translation id="8241707690549784388">Στη σελίδα που αναζητάτε χÏησιμοποποιήθηκαν πληÏοφοÏίες που καταχωÏίσατε. Αν επιστÏέψετε σε αυτή τη σελίδα ίσως επαναληφθοÏν ενέÏγειες που εκτελέσατε. Θέλετε να συνεχίσετε;</translation>
<translation id="8249320324621329438">Τελευταία ανάκτηση:</translation>
<translation id="8253091569723639551">Απαιτείται διεÏθυνση χÏέωσης</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">Επικοινωνήστε με το διαχειÏιστή του δικτÏου σας εάν δεν είστε βέβαιοι για το τι σημαίνει αυτό.</translation>
<translation id="8293206222192510085">ΠÏοσθήκη σελιδοδείκτη</translation>
<translation id="8294431847097064396">Πηγή</translation>
+<translation id="8306404619377842860">Δεν είναι δυνατή η δημιουÏγία μιας ιδιωτικής σÏνδεσης <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημεÏομηνία και η ÏŽÏα της συσκευής σας (<ph name="DATE_AND_TIME" />) είναι λανθασμένες. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Η μετάφÏαση απέτυχε λόγω Ï€Ïοβλήματος με τη σÏνδεση δικτÏου.</translation>
<translation id="8332188693563227489">ΑποÏÏίφθηκε η Ï€Ïόσβαση στο κεντÏικό υπολογιστή <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Εάν κατανοείτε τους κινδÏνους για την ασφάλειά σας, μποÏείτε να <ph name="BEGIN_LINK" />επισκεφτείτε αυτόν τον ιστότοπο<ph name="END_LINK" /> Ï€Ïιν από την κατάÏγηση των επικίνδυνων Ï€ÏογÏαμμάτων.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">Για να χÏησιμοποιήσετε κάÏτες από τον ΛογαÏιασμό σας Google, συνδεθείτε στο Chrome</translation>
<translation id="8488350697529856933">ΙσχÏει για</translation>
<translation id="8498891568109133222">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> άÏγησε Ï€Î¿Î»Ï Î½Î± ανταποκÏιθεί.</translation>
-<translation id="852346902619691059">Αυτός ο διακομιστής δεν μπόÏεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωÏείται έμπιστο από το λειτουÏγικό σÏστημα της συσκευής σας. Αυτό μποÏεί να οφείλεται σε εσφαλμένη ÏÏθμιση ή σε κάποιον εισβολέα που παÏεμβαίνει στη σÏνδεσή σας. <ph name="BEGIN_LEARN_MORE_LINK" />Μάθετε πεÏισσότεÏα<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Έτος λήξης</translation>
<translation id="8543181531796978784">ΜποÏείτε να <ph name="BEGIN_ERROR_LINK" />αναφέÏετε ένα Ï€Ïόβλημα εντοπισμοÏ<ph name="END_ERROR_LINK" /> ή, εάν κατανοείτε τους κινδÏνους ασφαλείας, να <ph name="BEGIN_LINK" />επισκεφτείτε αυτόν τον μη ασφαλή ιστότοπο<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Η μετάφÏαση απέτυχε επειδή δεν ήταν δυνατός ο Ï€ÏοσδιοÏισμός της σελίδας.</translation>
-<translation id="8559762987265718583">Δεν είναι δυνατή η επίτευξη ιδιωτικής σÏνδεσης με τον τομέα <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> επειδή η ημεÏομηνία και η ÏŽÏα (<ph name="DATE_AND_TIME" />) της συσκευής σας είναι λανθασμένες.</translation>
<translation id="8571890674111243710">ΜετάφÏαση σελίδας σε <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">ΠÏοσθ. τηλεφ.
</translation>
@@ -821,6 +895,7 @@
<translation id="8738058698779197622">Για την επίτευξη μιας ασφαλοÏÏ‚ σÏνδεσης, θα Ï€Ïέπει να γίνει σωστή ÏÏθμιση του ÏÎ¿Î»Î¿Î³Î¹Î¿Ï ÏƒÎ±Ï‚. Αυτό οφείλεται στο γεγονός ότι τα πιστοποιητικά που χÏησιμοποιοÏν οι ιστότοποι για την ταυτοποίησή τους είναι έγκυÏα μόνο για συγκεκÏιμένες χÏονικές πεÏιόδους. Εφόσον το Ïολόι της συσκευής σας δεν είναι σωστά Ïυθμισμένο, το Chromium δεν μποÏεί να επαληθεÏσει αυτά τα πιστοποιητικά.</translation>
<translation id="8740359287975076522">Δεν ήταν δυνατός ο εντοπισμός της &lt;abbr id="dnsDefinition"&gt;διεÏθυνσης DNS&lt;/abbr&gt; του κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î® <ph name="HOST_NAME" />. Γίνεται διάγνωση του Ï€Ïοβλήματος.</translation>
<translation id="8759274551635299824">Αυτή η κάÏτα έχει λήξει</translation>
+<translation id="8761567432415473239">Η ασφαλής πεÏιήγηση Google <ph name="BEGIN_LINK" />εντόπισε επιβλαβή Ï€ÏογÏάμματα<ph name="END_LINK" /> Ï€Ïόσφατα στο <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Επανάληψη διαγÏαφής</translation>
<translation id="8800988563907321413">Οι Ï€Ïοτάσεις σε κοντινή απόσταση εμφανίζονται εδώ</translation>
<translation id="8820817407110198400">Σελιδοδείκτες</translation>
@@ -833,29 +908,30 @@
<translation id="8870413625673593573">Έκλεισαν Ï€Ïόσφατα</translation>
<translation id="8874824191258364635">Εισαγάγετε έναν έγκυÏο αÏιθμό κάÏτας</translation>
<translation id="8876793034577346603">Αποτυχία ανάλυσης της διαμόÏφωσης δικτÏου</translation>
-<translation id="8877192140621905067">Μετά την επιβεβαίωση, θα γίνει κοινή χÏήση των στοιχείων της κάÏτας σας με αυτόν τον ιστότοπο</translation>
<translation id="8889402386540077796">ΑπόχÏωση</translation>
<translation id="8891727572606052622">Μη έγκυÏη λειτουÏγία διακομιστή μεσολάβησης.</translation>
<translation id="889901481107108152">ΛυποÏμαστε, αυτό το πείÏαμα δεν είναι διαθέσιμο στην πλατφόÏμα σας.</translation>
<translation id="8903921497873541725">Μεγέθυνση</translation>
<translation id="8931333241327730545">Θέλετε να αποθηκεÏσετε αυτήν την κάÏτα στο ΛογαÏιασμό σας Google;</translation>
<translation id="8932102934695377596">Το Ïολόι σας πάει πίσω</translation>
-<translation id="8954894007019320973">(ΠεÏιεχ.)</translation>
<translation id="8971063699422889582">Το πιστοποιητικό του διακομιστή έχει λήξει.</translation>
<translation id="8986494364107987395">Αυτόματη αποστολή στατιστικών στοιχείων χÏήσης και αναφοÏών σφαλμάτων στην Google</translation>
-<translation id="8987927404178983737">Μήνας</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Ο ιστότοπος που Ï€Ïόκειται να επισκεφτείτε πεÏιέχει κακόβουλα Ï€ÏογÏάμματα</translation>
+<translation id="8997023839087525404">Ο διακομιστής παÏουσίασε ένα πιστοποιητικό το οποίο δεν αποκαλÏφθηκε δημοσίως με χÏήση της πολιτικής Διαφάνειας πιστοποιητικών. Αυτό απαιτείται για οÏισμένα πιστοποιητικά, Ï€Ïοκειμένου να διασφαλιστεί ότι είναι αξιόπιστα και παÏέχουν Ï€Ïοστασία ενάντια σε εισβολείς.</translation>
<translation id="9001074447101275817">Απαιτείται όνομα χÏήστη και κωδικός Ï€Ïόσβασης για το διακομιστή μεσολάβησης <ph name="DOMAIN" />.</translation>
+<translation id="9005998258318286617">Η φόÏτωση του εγγÏάφου PDF απέτυχε.</translation>
<translation id="901974403500617787">Οι επισημάνσεις που ισχÏουν για ολόκληÏο το σÏστημα μποÏοÏν να οÏιστοÏν μόνο από τον κάτοχο: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Απαιτείται διεÏθυνση χÏέωσης της κάÏτας</translation>
<translation id="9020542370529661692">Αυτή η σελίδα έχει μεταφÏαστεί στα <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="9035022520814077154">Σφάλμα ασφάλειας</translation>
<translation id="9038649477754266430">ΧÏήση μιας υπηÏεσίας Ï€Ïόβλεψης για ταχÏτεÏη φόÏτωση σελίδων</translation>
<translation id="9039213469156557790">Επίσης, αυτή η σελίδα πεÏιέχει άλλους πόÏους, οι οποίοι δεν είναι ασφαλείς. Αυτοί οι πόÏοι μποÏοÏν να Ï€ÏοβληθοÏν από άλλους χÏήστες κατά τη μετάβαση και μποÏοÏν να Ï„ÏοποποιηθοÏν από έναν εισβολέα ώστε να αλλάξει η συμπεÏιφοÏά της σελίδας.</translation>
-<translation id="9040185888511745258">Όσοι εισβάλλουν στο <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> μποÏεί να Ï€Ïοσπαθήσουν να σας ξεγελάσουν ώστε να εγκαταστήσετε Ï€ÏογÏάμματα που βλάπτουν την εμπειÏία πεÏιήγησής σας (για παÏάδειγμα, αλλάζοντας την αÏχική σελίδα σας ή εμφανίζοντας επιπλέον διαφημίσεις στους ιστότοπους που επισκέπτεστε).</translation>
+<translation id="9049981332609050619">ΕπιχειÏήσατε να μεταβείτε στον <ph name="DOMAIN" /> , αλλά ο διακομιστής παÏουσίασε ένα μη έγκυÏο πιστοποιητικό.</translation>
<translation id="9050666287014529139">ΦÏάση Ï€Ïόσβασής σας</translation>
<translation id="9065203028668620118">ΕπεξεÏγασία</translation>
<translation id="9068849894565669697">Επιλογή χÏώματος</translation>
+<translation id="9069693763241529744">Αποκλείστηκε από μια επέκταση</translation>
<translation id="9076283476770535406">ΜποÏεί να διαθέτει πεÏιεχόμενο για ενηλίκους</translation>
<translation id="9078964945751709336">ΑπαιτοÏνται πεÏισσότεÏες πληÏοφοÏίες</translation>
<translation id="9103872766612412690">Κανονικά, ο ιστότοπος <ph name="SITE" /> χÏησιμοποιεί κÏυπτογÏάφηση για να Ï€ÏοστατεÏει τα στοιχεία σας. Όταν το Chromium επιχείÏησε Ï€Ïόσφατα να συνδεθεί στο <ph name="SITE" />, ο ιστότοπος ανταποκÏίθηκε δημιουÏγώντας ασυνήθιστα και εσφαλμένα διαπιστευτήÏια. Αυτό μποÏεί να συμβεί όταν κάποιος εισβολέας Ï€Ïοσπαθεί να υποκÏιθεί ότι είναι ο ιστότοπος <ph name="SITE" /> ή όταν κάποια οθόνη σÏνδεσης Wi-Fi έχει διακόψει τη σÏνδεσή σας. Τα στοιχεία σας εξακολουθοÏν να είναι ασφαλή επειδή το Chromium διέκοψε τη σÏνδεση Ï€Ïιν από την ανταλλαγή δεδομένων.</translation>
@@ -864,16 +940,21 @@
<translation id="9148507642005240123">&amp;ΑναίÏεση επεξεÏγασίας</translation>
<translation id="9154194610265714752">ΕνημεÏώθηκε</translation>
<translation id="9157595877708044936">ΡÏθμιση...</translation>
+<translation id="9169664750068251925">Îα γίνεται πάντα αποκλεισμός σε αυτόν τον ιστότοπο</translation>
<translation id="9170848237812810038">Αναί&amp;Ïεση</translation>
<translation id="917450738466192189">Το πιστοποιητικό του διακομιστή δεν είναι έγκυÏο.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ακόμη}other{<ph name="SHIPPING_OPTION_PREVIEW" /> και <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ακόμη}}</translation>
<translation id="9183425211371246419">Ο κεντÏικός υπολογιστής <ph name="HOST_NAME" /> χÏησιμοποιεί μη υποστηÏιζόμενο Ï€Ïωτόκολλο.</translation>
<translation id="9205078245616868884">Τα δεδομένα σας είναι κÏυπτογÏαφημένα με τη δική σας φÏάση Ï€Ïόσβασης συγχÏονισμοÏ. ΠληκτÏολογήστε την για να ξεκινήσει ο συγχÏονισμός.</translation>
<translation id="9207861905230894330">Αποτυχία Ï€Ïοσθήκης άÏθÏου.</translation>
+<translation id="9219103736887031265">Εικόνες</translation>
<translation id="933612690413056017">Δεν υπάÏχει σÏνδεση στο διαδίκτυο</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ΔΙΑΓΡΑΦΗ ΦΟΡΜΑΣ</translation>
<translation id="939736085109172342">Îέος φάκελος</translation>
<translation id="941721044073577244">Φαίνεται ότι δεν έχετε άδεια να επισκεφτείτε αυτόν τον ιστότοπο</translation>
<translation id="969892804517981540">Επίσημη έκδοση</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Κανένα}=1{1 στοιχείο}other{# στοιχεία}}</translation>
<translation id="988159990683914416">Έκδοση Ï€ÏογÏαμματιστή</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_en-GB.xtb b/chromium/components/strings/components_strings_en-GB.xtb
index 09b6b0d398f..266e93d1968 100644
--- a/chromium/components/strings/components_strings_en-GB.xtb
+++ b/chromium/components/strings/components_strings_en-GB.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Rotate clockwise</translation>
<translation id="1038842779957582377">unknown name</translation>
<translation id="1050038467049342496">Close other apps</translation>
-<translation id="1053591932240354961">You cannot visit <ph name="SITE" /> at the moment because the website sent scrambled credentials that Google Chrome cannot process. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Undo Add</translation>
<translation id="10614374240317010">Never saved</translation>
<translation id="106701514854093668">Desktop Bookmarks</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Policy cache OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> says:</translation>
<translation id="1132774398110320017">Chrome Auto-fill settings...</translation>
+<translation id="1150979032973867961">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
+<translation id="1151972924205500581">Password required</translation>
<translation id="1152921474424827756">Access a <ph name="BEGIN_LINK" />cached copy<ph name="END_LINK" /> of <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> unexpectedly closed the connection.</translation>
<translation id="1161325031994447685">Reconnecting to Wi-Fi</translation>
+<translation id="1165039591588034296">Error</translation>
<translation id="1175364870820465910">&amp;Print...</translation>
<translation id="1181037720776840403">Remove</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Automatically report<ph name="END_WHITEPAPER_LINK" /> details of possible security incidents to Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">More from this site</translation>
<translation id="1206967143813997005">Bad initial signature</translation>
<translation id="1209206284964581585">Hide for now</translation>
+<translation id="121201262018556460">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate containing a weak key. An attacker could have broken the private key and the server may not be the server you expected (you may be communicating with an attacker).</translation>
<translation id="1219129156119358924">System Security</translation>
<translation id="1227224963052638717">Unknown policy.</translation>
<translation id="1227633850867390598">Hide value</translation>
<translation id="1228893227497259893">Wrong entity identifier</translation>
<translation id="1232569758102978740">Untitled</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synced)</translation>
<translation id="1263231323834454256">Reading list</translation>
<translation id="1264126396475825575">Crash report captured on <ph name="CRASH_TIME" /> (not yet uploaded or ignored)</translation>
+<translation id="1281526147609854549">Issued by <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Dangerous content blocked</translation>
<translation id="1285320974508926690">Never translate this site</translation>
<translation id="129553762522093515">Recently closed</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Try clearing your cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Your activity <ph name="BEGIN_EMPHASIS" />might still be visible<ph name="END_EMPHASIS" /> to:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Websites that you visit
+ <ph name="LIST_ITEM" />Your employer or school
+ <ph name="LIST_ITEM" />Your Internet service provider
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Enrolment domain:</translation>
<translation id="1340482604681802745">Pickup address</translation>
<translation id="1344211575059133124">Looks like you need permission to visit this site</translation>
<translation id="1344588688991793829">Chromium Auto-fill settings...</translation>
+<translation id="1348198688976932919">The site ahead contains dangerous apps</translation>
<translation id="1374468813861204354">suggestions</translation>
<translation id="1375198122581997741">About Version</translation>
<translation id="1377321085342047638">Card Number</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> didn’t send any data.</translation>
<translation id="1407135791313364759">Open all</translation>
<translation id="1413809658975081374">Privacy error</translation>
+<translation id="14171126816530869">The identity of <ph name="ORGANIZATION" /> at <ph name="LOCALITY" /> has been verified by <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Yes</translation>
<translation id="1430915738399379752">Print</translation>
-<translation id="1442912890475371290">Blocked attempt <ph name="BEGIN_LINK" /> to visit a page on <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">You cannot visit <ph name="SITE" /> at the moment because the website uses certificate pinning. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation>
<translation id="1506687042165942984">Show a saved (i.e. known to be out of date) copy of this page.</translation>
<translation id="1517433312004943670">Phone number required</translation>
<translation id="1519264250979466059">Build Date</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript must be enabled to use this feature.</translation>
<translation id="1555130319947370107">Blue</translation>
<translation id="1559528461873125649">No such file or directory</translation>
-<translation id="1559572115229829303">&lt;p&gt;A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your device's date and time (<ph name="DATE_AND_TIME" />) are incorrect.&lt;/p&gt;
-
- &lt;p&gt;Please adjust the date and time from the &lt;strong&gt;General&lt;/strong&gt; section of the &lt;strong&gt;Settings&lt;/strong&gt; app.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Something went wrong while displaying this web page.</translation>
<translation id="1592005682883173041">Local Data Access</translation>
+<translation id="1594030484168838125">Choose</translation>
<translation id="161042844686301425">Cyan</translation>
+<translation id="1620510694547887537">Camera</translation>
<translation id="1629803312968146339">Do you want Chrome to save this card?</translation>
<translation id="1639239467298939599">Loading</translation>
<translation id="1640180200866533862">User policies</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">The network configuration is invalid and couldn't be imported.</translation>
<translation id="1644574205037202324">History</translation>
<translation id="1645368109819982629">Unsupported protocol</translation>
+<translation id="1655462015569774233">{1,plural, =1{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired yesterday. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page.}other{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page.}}</translation>
<translation id="1656489000284462475">Pick up</translation>
<translation id="1663943134801823270">Cards and addresses are from Chrome. You can manage them in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> normally uses encryption to protect your information. When Google Chrome tried to connect to <ph name="SITE" /> this time, the website sent back unusual and incorrect credentials. This may happen when an attacker is trying to pretend to be <ph name="SITE" />, or a Wi-Fi sign-in screen has interrupted the connection. Your information is still secure because Google Chrome stopped the connection before any data was exchanged.</translation>
-<translation id="168328519870909584">Attackers currently on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to install dangerous apps on your device that steal or delete your information (for example, photos, passwords, messages and credit cards).</translation>
<translation id="168841957122794586">The server certificate contains a weak cryptographic key.</translation>
+<translation id="1706954506755087368">{1,plural, =1{This server could not prove that it is <ph name="DOMAIN" />; its security certificate is supposedly from tomorrow. This may be caused by a misconfiguration or an attacker intercepting your connection.}other{This server could not prove that it is <ph name="DOMAIN" />; its security certificate is supposedly from # days in the future. This may be caused by a misconfiguration or an attacker intercepting your connection.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">You need permission from <ph name="NAME" /> to visit this site</translation>
<translation id="1721424275792716183">* Field is required</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Download page later</translation>
<translation id="17513872634828108">Open tabs</translation>
<translation id="1753706481035618306">Page number</translation>
+<translation id="1763864636252898013">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Try running Windows Network Diagnostics<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Please update your sync passphrase.</translation>
<translation id="1787142507584202372">Your open tabs appear here</translation>
+<translation id="1789575671122666129">Popups</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Cardholder Name</translation>
-<translation id="1803678881841855883">Google Safe Browsing recently <ph name="BEGIN_LINK" />detected malware<ph name="END_LINK" /> on <ph name="SITE" />. Websites that are normally safe are sometimes infected with malware. The malicious content comes from <ph name="SUBRESOURCE_HOST" />, a known malware distributor. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Added <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Invalid request or request parameters</translation>
<translation id="1826516787628120939">Checking</translation>
<translation id="1834321415901700177">This site contains harmful programs</translation>
+<translation id="1840414022444569775">This card number is already used</translation>
<translation id="1842969606798536927">Pay</translation>
<translation id="1871208020102129563">Proxy is set to use fixed proxy servers, not a .pac script URL.</translation>
<translation id="1871284979644508959">Required field</translation>
<translation id="187918866476621466">Open startup pages</translation>
<translation id="1883255238294161206">Collapse list</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation>
<translation id="1898423065542865115">Filtering</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{None}=1{1 site}other{# sites}}</translation>
<translation id="194030505837763158">Go to <ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> Bookmarks</translation>
<translation id="1973335181906896915">Serialisation error</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignored because it was overridden by <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Looking for nearby Physical Web pages</translation>
<translation id="213826338245044447">Mobile Bookmarks</translation>
-<translation id="2148716181193084225">Today</translation>
+<translation id="2147827593068025794">Background Sync</translation>
<translation id="2154054054215849342">Sync is not available for your domain</translation>
<translation id="2154484045852737596">Edit card</translation>
<translation id="2166049586286450108">Full Admin Access</translation>
<translation id="2166378884831602661">This site can’t provide a secure connection</translation>
<translation id="2181821976797666341">Policies</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 address}other{# addresses}}</translation>
+<translation id="2187317261103489799">Detect (default)</translation>
<translation id="2202020181578195191">Enter a valid expiry year</translation>
<translation id="2212735316055980242">Policy not found</translation>
<translation id="2213606439339815911">Fetching entries...</translation>
+<translation id="2218879909401188352">Attackers currently on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> could install dangerous apps that damage your device, add hidden charges to your mobile bill or steal your personal information. <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Fix your connection using the <ph name="BEGIN_LINK" />diagnostics app<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Send now</translation>
<translation id="225207911366869382">This value is deprecated for this policy.</translation>
<translation id="2262243747453050782">HTTP error</translation>
+<translation id="2270484714375784793">Phone number</translation>
<translation id="2282872951544483773">Unavailable Experiments</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item}other{<ph name="ITEM_COUNT" /> items}}</translation>
<translation id="2292556288342944218">Your Internet access is blocked</translation>
<translation id="230155334948463882">New card?</translation>
-<translation id="2305919008529760154">This server could not prove that it is <ph name="DOMAIN" />; its security certificate might have been issued fraudulently. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> requires a username and password.</translation>
-<translation id="2318774815570432836">You cannot visit <ph name="SITE" /> at the moment because the website uses HSTS. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Setting controlled by your administrator</translation>
<translation id="2354001756790975382">Other bookmarks</translation>
+<translation id="2354430244986887761">Google Safe Browsing recently <ph name="BEGIN_LINK" />found harmful apps<ph name="END_LINK" /> on <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Attackers might be able to see the images that you’re looking at on this site and trick you by modifying them.</translation>
+<translation id="2356070529366658676">Ask</translation>
+<translation id="2359629602545592467">Multiple</translation>
<translation id="2359808026110333948">Continue</translation>
<translation id="2365563543831475020">Crash report captured on <ph name="CRASH_TIME" /> was not uploaded</translation>
<translation id="2367567093518048410">Level</translation>
-<translation id="2371153335857947666">{1,plural, =1{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired yesterday. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.}other{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">No UI alternatives available</translation>
<translation id="2384307209577226199">Enterprise default</translation>
<translation id="2386255080630008482">Server's certificate has been revoked</translation>
<translation id="2392959068659972793">Show policies with no value set</translation>
<translation id="239429038616798445">This delivery method isn’t available. Try a different method.</translation>
<translation id="2396249848217231973">&amp;Undo delete</translation>
-<translation id="2460160116472764928">Google Safe Browsing recently <ph name="BEGIN_LINK" />detected malware<ph name="END_LINK" /> on <ph name="SITE" />. Websites that are normally safe are sometimes infected with malware. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">This server could not prove that it is <ph name="DOMAIN" />; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="2463739503403862330">Fill in</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Running Network Diagnostics<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Invalid search URL.</translation>
+<translation id="2482878487686419369">Notifications</translation>
<translation id="2491120439723279231">Server's certificate contains errors.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2495093607237746763">If ticked, Chromium will store a copy of your card on this device for faster form filling.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Go back</translation>
<translation id="2515629240566999685">Checking the signal in your area</translation>
<translation id="2516305470678292029">UI Alternatives</translation>
+<translation id="2539524384386349900">Detect</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> sent an invalid response.</translation>
-<translation id="2552545117464357659">Newer</translation>
<translation id="2556876185419854533">&amp;Undo Edit</translation>
<translation id="2587730715158995865">From <ph name="ARTICLE_PUBLISHER" />. Read this and <ph name="OTHER_ARTICLE_COUNT" /> other stories.</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">This document is password-protected. Please enter a password.</translation>
<translation id="2609632851001447353">Variations</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{None}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Your clock is ahead</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Access to the file was denied</translation>
<translation id="2653659639078652383">Submit</translation>
<translation id="2666117266261740852">Close other tabs or apps</translation>
+<translation id="2670429602441959756">This page contains features not yet supported in VR. Exiting...</translation>
<translation id="2674170444375937751">Are you sure that you want to delete these pages from your history?</translation>
<translation id="2677748264148917807">Leave</translation>
-<translation id="269990154133806163">The server presented a certificate that was not publicly disclosed using the Certificate Transparency policy. This is a requirement for some certificates, to ensure that they are trustworthy and protect against attackers. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Reading List</translation>
<translation id="2704283930420550640">Value doesn't match format.</translation>
<translation id="2704951214193499422">Chromium was unable to confirm your card at this time. Please try again later.</translation>
<translation id="2705137772291741111">The saved (cached) copy of this site was unreadable.</translation>
<translation id="2709516037105925701">Auto-fill</translation>
-<translation id="2712118517637785082">You attempted to reach <ph name="DOMAIN" />, but the certificate that the server presented has been revoked by its issuer. This means that the security credentials the server presented absolutely should not be trusted. You may be communicating with an attacker. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Ask permission</translation>
<translation id="2713444072780614174">White</translation>
<translation id="2720342946869265578">Nearby</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Missing device record</translation>
<translation id="2784949926578158345">The connection was reset.</translation>
<translation id="2794233252405721443">Site blocked</translation>
+<translation id="2799020568854403057">The site ahead contains harmful apps</translation>
+<translation id="2803306138276472711">Google Safe Browsing recently <ph name="BEGIN_LINK" />detected malware<ph name="END_LINK" /> on <ph name="SITE" />. Websites that are normally safe are sometimes infected with malware.</translation>
<translation id="2824775600643448204">Address and search bar</translation>
<translation id="2826760142808435982">The connection is encrypted and authenticated using <ph name="CIPHER" /> and uses <ph name="KX" /> as the key exchange mechanism.</translation>
<translation id="2835170189407361413">Clear form</translation>
+<translation id="2856444702002559011">Attackers might be trying to steal your information from <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (for example, passwords, messages or credit cards). <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Don't reload</translation>
<translation id="2900469785430194048">Google Chrome ran out of memory while trying to display this web page.</translation>
<translation id="2909946352844186028">A network change was detected.</translation>
<translation id="2916038427272391327">Close other programmes</translation>
<translation id="2922350208395188000">Server's certificate cannot be checked.</translation>
<translation id="2928905813689894207">Billing Address</translation>
+<translation id="2941952326391522266">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is from <ph name="DOMAIN2" />. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="2948083400971632585">You can disable any proxies configured for a connection from the settings page.</translation>
<translation id="2955913368246107853">Close find bar</translation>
<translation id="2958431318199492670">The network configuration doesn't comply to the ONC standard. Parts of the configuration may not be imported.</translation>
-<translation id="29611076221683977">Attackers currently on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to install dangerous programs on your Mac that steal or delete your information (for example photos, passwords, messages and credit cards).</translation>
<translation id="2966678944701946121">Exp: <ph name="EXPIRATION_DATE_ABBR" />, added <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">To establish a secure connection, your clock needs to be set correctly. This is because the certificates that websites use to identify themselves are only valid for specific periods of time. Since your device's clock is incorrect, Google Chrome cannot verify these certificates.</translation>
<translation id="2972581237482394796">&amp;Redo</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Enter a valid address</translation>
<translation id="2986368408720340940">This pickup method isn’t available. Try a different method.</translation>
<translation id="2991174974383378012">Sharing with Websites</translation>
+<translation id="2991571918955627853">You cannot visit <ph name="SITE" /> right now because the website uses HSTS. Network errors and attacks are usually temporary, so this page will probably work later.</translation>
<translation id="3005723025932146533">Show saved copy</translation>
<translation id="3008447029300691911">Enter the CVC for <ph name="CREDIT_CARD" />. Once you confirm, your card details will be shared with this site.</translation>
<translation id="3010559122411665027">List entry "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatically blocked</translation>
<translation id="3024663005179499861">Wrong policy type</translation>
<translation id="3032412215588512954">Do you want to reload this site?</translation>
<translation id="3037605927509011580">Aw, Snap!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{at least 1 item on synced devices}=1{1 item (and more on synced devices)}other{# items (and more on synced devices)}}</translation>
<translation id="3041612393474885105">Certificate Information</translation>
<translation id="3063697135517575841">Chrome was unable to confirm your card at this time. Please try again later.</translation>
<translation id="3064966200440839136">Leaving incognito mode to pay via an external application. Continue?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{None}=1{1 password}other{# passwords}}</translation>
<translation id="3093245981617870298">You are offline</translation>
<translation id="3105172416063519923">Asset ID:</translation>
<translation id="3109728660330352905">You don't have authorisation to view this page.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Try running Connectivity Diagnostics<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Failed to decode response</translation>
<translation id="3150653042067488994">Temporary server error</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files you download or bookmarks you create will be kept.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Island</translation>
+<translation id="317583078218509884">New site permissions settings will take effect after reloading the page.</translation>
<translation id="3176929007561373547">Check your proxy settings or contact your network administrator to
make sure that the proxy server is working. If you don't believe you should
be using a proxy server:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Open page in Incognito mode</translation>
-<translation id="3202578601642193415">Newest</translation>
+<translation id="320323717674993345">Cancel payment</translation>
<translation id="3207960819495026254">Bookmarked</translation>
+<translation id="3225919329040284222">The server presented a certificate that doesn't match built-in expectations. These expectations are included for certain, high-security websites in order to protect you.</translation>
<translation id="3226128629678568754">Press the reload button to resubmit the data needed to load the page.</translation>
+<translation id="3227137524299004712">Microphone</translation>
<translation id="3228969707346345236">The translation failed because the page is already in <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Enter the CVC for <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Always detect important content on this site</translation>
<translation id="3254409185687681395">Bookmark this page</translation>
<translation id="3270847123878663523">&amp;Undo Reorder</translation>
<translation id="3282497668470633863">Add name on card</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">settings</translation>
<translation id="3345135638360864351">Your request to access this site could not be sent to <ph name="NAME" />. Please try again.</translation>
<translation id="3355823806454867987">Change proxy settings...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />won’t save<ph name="END_EMPHASIS" /> the following information:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Your browsing history
+ <ph name="LIST_ITEM" />Cookies and site data
+ <ph name="LIST_ITEM" />Information entered in forms
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Clock error</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> more items...</translation>
<translation id="337363190475750230">Deprovisioned</translation>
<translation id="3377188786107721145">Policy parse error</translation>
<translation id="3380365263193509176">Unknown error</translation>
<translation id="3380864720620200369">Client ID:</translation>
<translation id="3391030046425686457">Delivery address</translation>
<translation id="3395827396354264108">Pickup method</translation>
-<translation id="340013220407300675">Attackers might be trying to steal your information from <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (for example, passwords, messages or credit cards).</translation>
<translation id="3422248202833853650">Try exiting other programmes to free up memory.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> is currently unreachable.</translation>
+<translation id="3427092606871434483">Allow (default)</translation>
<translation id="3427342743765426898">&amp;Redo Edit</translation>
<translation id="3431636764301398940">Save this card to this device</translation>
<translation id="3435896845095436175">Enable</translation>
<translation id="3447661539832366887">The owner of this device turned off the dinosaur game.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Fetch interval:</translation>
<translation id="3462200631372590220">Hide advanced</translation>
<translation id="3467763166455606212">Cardholder name required</translation>
<translation id="3478058380795961209">Month of Expiry</translation>
<translation id="3479539252931486093">Was this unexpected? <ph name="BEGIN_LINK" />Let us know<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Not now</translation>
-<translation id="348000606199325318">Crash ID <ph name="CRASH_LOCAL_ID" /> (Server ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">We could not reach your parent at the moment. Please try again.</translation>
<translation id="3528171143076753409">Server's certificate is not trusted</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{At least 1 item on synced devices}=1{1 item (and more on synced devices)}other{# items (and more on synced devices)}}</translation>
<translation id="3539171420378717834">Keep a copy of this card on this device</translation>
<translation id="3542684924769048008">Use password for:</translation>
+<translation id="3545341443414427877">A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your computer's date and time (<ph name="DATE_AND_TIME" />) are incorrect. <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> more...</translation>
-<translation id="3555561725129903880">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is from <ph name="DOMAIN2" />. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Your manager can unblock it for you</translation>
<translation id="3566021033012934673">Your connection is not private</translation>
+<translation id="3569145463236695319">&lt;p&gt;A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your device's date and time (<ph name="DATE_AND_TIME" />) are incorrect.&lt;/p&gt;
+
+ &lt;p&gt;Please adjust the date and time from the &lt;strong&gt;General&lt;/strong&gt; section of the &lt;strong&gt;Settings&lt;/strong&gt; app.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Add name</translation>
<translation id="3583757800736429874">&amp;Redo Move</translation>
<translation id="3586931643579894722">Hide details</translation>
-<translation id="3587482841069643663">All</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Enter a valid expiry date</translation>
<translation id="36224234498066874">Clear Browsing Data...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Certificate information</translation>
<translation id="3690164694835360974">Login not secure</translation>
<translation id="3693415264595406141">Password:</translation>
-<translation id="3696411085566228381">none</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Loading...</translation>
<translation id="3712624925041724820">Licenses exhausted</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Checking the proxy, firewall and DNS configuration<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">If you understand the risks to your security, you may <ph name="BEGIN_LINK" />visit this unsafe site<ph name="END_LINK" /> before the dangerous programs have been removed.</translation>
<translation id="3739623965217189342">Link that you copied</translation>
+<translation id="3744899669254331632">You cannot visit <ph name="SITE" /> right now because the website sent scrambled credentials that Chromium cannot process. Network errors and attacks are usually temporary, so this page will probably work later.</translation>
+<translation id="3748148204939282805">Attackers on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> may trick you into doing something dangerous like installing software or revealing your personal information (for example, passwords, phone numbers or credit cards). <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">The translation failed because of a server error.</translation>
<translation id="3759461132968374835">You have no recently reported crashes. Crashes that occurred when crash reporting was disabled will not appear here.</translation>
+<translation id="3778403066972421603">Do you want to save this card to your Google account and on this device?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Expires <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">If you use a proxy server...</translation>
<translation id="3828924085048779000">Empty passphrase is not allowed.</translation>
-<translation id="3845539888601087042">Showing history from your signed-in devices. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Back</translation>
<translation id="3858027520442213535">Update date and time</translation>
<translation id="3884278016824448484">Conflicting device identifier</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Your request to access this site has been sent to <ph name="NAME" /></translation>
<translation id="3890664840433101773">Add email</translation>
<translation id="3901925938762663762">The card is expired</translation>
-<translation id="3933571093587347751">{1,plural, =1{This server could not prove that it is <ph name="DOMAIN" />; its security certificate is supposedly from tomorrow. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.}other{This server could not prove that it is <ph name="DOMAIN" />; its security certificate is supposedly from # days in the future. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Failed to load PDF document</translation>
+<translation id="3945915738023014686">Uploaded Crash Report ID <ph name="CRASH_ID" /> (Local Crash ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">This server could not prove that it is <ph name="DOMAIN" />; its security certificate does not specify Subject Alternative Names. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="3963721102035795474">Reader Mode</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{None}=1{From 1 site }other{From # sites }}</translation>
<translation id="397105322502079400">Calculating...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> is blocked</translation>
+<translation id="3987940399970879459">Less than 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 web page nearby}other{# web pages nearby}}</translation>
<translation id="4021036232240155012">DNS is the network service that translates a website’s name to its Internet address.</translation>
<translation id="4030383055268325496">&amp;Undo add</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Proxy configuration is set to use a .pac script URL, not fixed proxy servers.</translation>
<translation id="4098354747657067197">Deceptive site ahead</translation>
<translation id="4103249731201008433">Device serial number is invalid</translation>
+<translation id="410351446219883937">Autoplay</translation>
<translation id="4103763322291513355">Visit &lt;strong&gt;chrome://policy&lt;/strong&gt; to see the list of blacklisted URLs and other policies enforced by your system administrator.</translation>
-<translation id="4110615724604346410">This server could not prove that it is <ph name="DOMAIN" />; its security certificate contains errors. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Always allow on this site</translation>
<translation id="4117700440116928470">Policy scope is not supported.</translation>
-<translation id="4118212371799607889">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by Chromium. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 other}other{# others}}</translation>
<translation id="4130226655945681476">Checking the network cables, modem and router</translation>
+<translation id="413544239732274901">Learn more</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Use global default (Detect)</translation>
+<translation id="4165986682804962316">Site settings</translation>
<translation id="4169947484918424451">Do you want Chromium to save this card?</translation>
<translation id="4171400957073367226">Bad verification signature</translation>
<translation id="4196861286325780578">&amp;Redo move</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Checking firewall and antivirus configurations<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{none}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Crashes</translation>
+<translation id="422022731706691852">Attackers on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to trick you into installing programs that harm your browsing experience (for example, by changing your homepage or showing extra ads on sites that you visit). <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Try running Network Diagnostics<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Valid</translation>
<translation id="4250431568374086873">Your connection to this site is not fully secure</translation>
<translation id="4250680216510889253">No</translation>
<translation id="425582637250725228">Changes that you made may not be saved.</translation>
<translation id="4258748452823770588">Bad signature</translation>
+<translation id="4265872034478892965">Allowed by your administrator</translation>
<translation id="4269787794583293679">(No username)</translation>
<translation id="4275830172053184480">Restart your device</translation>
<translation id="4280429058323657511">, exp <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google Safe Browsing recently <ph name="BEGIN_LINK" />found harmful programs<ph name="END_LINK" /> on <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Parent suggestions</translation>
<translation id="4304224509867189079">Log In</translation>
-<translation id="432290197980158659">The server presented a certificate that doesn't match built-in expectations. These expectations are included for certain, high-security websites in order to protect you. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Block (default)</translation>
<translation id="4325863107915753736">Failed to find article</translation>
<translation id="4326324639298822553">Check your expiry date and try again</translation>
<translation id="4331708818696583467">Not Secure</translation>
<translation id="4356973930735388585">Attackers on this site might attempt to install dangerous programs on your computer that steal or delete your information (for example, photos, passwords, messages and credit cards).</translation>
<translation id="4372948949327679948">Expected <ph name="VALUE_TYPE" /> value.</translation>
+<translation id="4377125064752653719">You attempted to reach <ph name="DOMAIN" />, but the certificate that the server presented has been revoked by its issuer. This means that the security credentials the server presented absolutely should not be trusted. You may be communicating with an attacker.</translation>
<translation id="4381091992796011497">User Name:</translation>
<translation id="4394049700291259645">Disable</translation>
<translation id="4406896451731180161">search results</translation>
+<translation id="4424024547088906515">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by Chrome. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> didn’t accept your login certificate, or one may not have been provided.</translation>
<translation id="443673843213245140">Use of a proxy is disabled but an explicit proxy configuration is specified.</translation>
-<translation id="4492190037599258964">Search results for '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Validation error: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Contacting the system admin</translation>
<translation id="450710068430902550">Sharing with Administrator</translation>
<translation id="4515275063822566619">Cards and addresses are from Chrome and your Google account (<ph name="ACCOUNT_EMAIL" />). You can manage them in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Details</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Try disabling your extensions.</translation>
<translation id="457875822857220463">Delivery</translation>
<translation id="4587425331216688090">Remove address from Chrome?</translation>
-<translation id="4589078953350245614">You attempted to reach <ph name="DOMAIN" />, but the server presented an invalid certificate. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Your connection to <ph name="DOMAIN" /> is encrypted using a modern cipher suite.</translation>
<translation id="4594403342090139922">&amp;Undo Delete</translation>
<translation id="4619615317237390068">Tabs from other devices</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">This server could not prove that it is <ph name="DOMAIN" />; its security certificate contains errors. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
+<translation id="4690462567478992370">Stop using an invalid certificate</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Your connection was interrupted</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Running Windows Network Diagnostics<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">An unknown error has occurred.</translation>
<translation id="4800132727771399293">Check your expiration date and CVC and try again</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">You cannot visit <ph name="SITE" /> at the moment because the website sent scrambled credentials that Google Chrome cannot process. Network errors and attacks are usually temporary, so this page will probably work later.</translation>
<translation id="4813512666221746211">Network error</translation>
<translation id="4816492930507672669">Fit to page</translation>
<translation id="483020001682031208">No Physical Web pages to show</translation>
<translation id="4850886885716139402">View</translation>
<translation id="4854362297993841467">This delivery method isn’t available. Try a different method.</translation>
<translation id="4858792381671956233">You asked your parents if it's OK to visit this site</translation>
+<translation id="4863764087567530506">This content might try to trick you into installing software or revealing personal information. <ph name="BEGIN_LINK" />Show anyway<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Search history</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{and 1 more web page}other{and # more web pages}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">This page has been translated from an unknown language into <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Payment</translation>
<translation id="4926049483395192435">Must be specified.</translation>
<translation id="495170559598752135">Actions</translation>
<translation id="4958444002117714549">Expand list</translation>
-<translation id="4962322354953122629">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by Chrome. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Re-enable warnings</translation>
<translation id="4989809363548539747">This plug-in is not supported</translation>
<translation id="5002932099480077015">If enabled, Chrome will store a copy of your card on this device for faster form filling.</translation>
<translation id="5018422839182700155">Can't open this page</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Check your administrator's policies</translation>
<translation id="5029568752722684782">Clear copy</translation>
<translation id="5031870354684148875">About Google Translate</translation>
+<translation id="5039804452771397117">Allow</translation>
<translation id="5040262127954254034">Privacy</translation>
<translation id="5045550434625856497">Incorrect password</translation>
<translation id="5056549851600133418">Articles for you</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Checking the proxy address<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{No cookies}=1{1 site uses cookies. }other{# sites use cookies. }}</translation>
<translation id="5087286274860437796">Server's certificate is not valid at this time.</translation>
<translation id="5087580092889165836">Add card</translation>
<translation id="5089810972385038852">County</translation>
+<translation id="5094747076828555589">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by Chromium. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="5095208057601539847">Province</translation>
<translation id="5115563688576182185">(64-bit)</translation>
<translation id="5141240743006678641">Encrypt synced passwords with your Google credentials</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Email (required)</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Using Chrome at work? Businesses can manage Chrome settings for their employees. Find out more</translation>
+<translation id="5297526204711817721">Your connection to this site is not private. To exit VR mode at any time, remove headset and press back.</translation>
<translation id="5299298092464848405">Error parsing policy</translation>
-<translation id="5300589172476337783">Show</translation>
<translation id="5308689395849655368">Crash reporting is disabled.</translation>
<translation id="5317780077021120954">Save</translation>
<translation id="5327248766486351172">Name</translation>
-<translation id="5337705430875057403">Attackers on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> may trick you into doing something dangerous like installing software or revealing your personal information (for example, passwords, phone numbers or credit cards).</translation>
-<translation id="5359637492792381994">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not valid at this time. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">You cannot visit <ph name="SITE" /> right now because its certificate has been revoked. Network errors and attacks are usually temporary, so this page will probably work later.</translation>
<translation id="536296301121032821">Failed to store policy settings</translation>
<translation id="5386426401304769735">The certificate chain for this site contains a certificate signed using SHA-1.</translation>
<translation id="5402410679244714488">Exp: <ph name="EXPIRATION_DATE_ABBR" />, last used over a year ago</translation>
+<translation id="540969355065856584">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not valid at this time. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
<translation id="5421136146218899937">Clear browsing data...</translation>
<translation id="5430298929874300616">Remove bookmark</translation>
<translation id="5431657950005405462">Your file was not found</translation>
-<translation id="5435775191620395718">Showing history from this device. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Schema validation error at "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">This <ph name="HOST_NAME" /> page can’t be found</translation>
<translation id="5455374756549232013">Bad policy timestamp</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> of <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Invalid</translation>
<translation id="5470861586879999274">&amp;Redo edit</translation>
<translation id="54817484435770891">Add valid address</translation>
<translation id="5492298309214877701">This site on the company, organisation or school intranet has the same URL as an external website.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Can’t pick up from this address. Select a different address.</translation>
<translation id="5572851009514199876">Please start and sign in to Chrome so that Chrome can check whether you are allowed to access this site.</translation>
<translation id="5580958916614886209">Check your expiry month and try again</translation>
+<translation id="5586446728396275693">No saved addresses</translation>
+<translation id="5595485650161345191">Edit address</translation>
<translation id="560412284261940334">Management not supported</translation>
<translation id="5610142619324316209">Checking the connection</translation>
<translation id="5610807607761827392">You can manage cards and addresses in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Do you want to leave this site?</translation>
<translation id="5629630648637658800">Failed to load policy settings</translation>
<translation id="5631439013527180824">Invalid device management token</translation>
+<translation id="5633066919399395251">Attackers currently on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to install dangerous programs on your computer that steal or delete your information (for example, photos, passwords, messages and credit cards). <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Location</translation>
+<translation id="5659593005791499971">Email</translation>
<translation id="5669703222995421982">Get personalised content</translation>
<translation id="5675650730144413517">This page isn’t working</translation>
-<translation id="5677928146339483299">Blocked</translation>
-<translation id="5694783966845939798">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate signed using a weak signature algorithm (such as SHA-1). This means that the security credentials the server presented could have been forged, and the server may not be the server you expected (you may be communicating with an attacker). <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">The identity of this website has not been verified.</translation>
+<translation id="5713016350996637505">Deceptive content blocked</translation>
<translation id="5720705177508910913">Current user</translation>
<translation id="5732392974455271431">Your parents can unblock it for you</translation>
<translation id="5763042198335101085">Enter a valid email address</translation>
<translation id="5765072501007116331">To see delivery methods and requirements, select an address</translation>
+<translation id="5778550464785688721">MIDI devices full control</translation>
<translation id="5784606427469807560">There was a problem confirming your card. Check your Internet connection and try again.</translation>
<translation id="5785756445106461925">Further, this page includes other resources which are not secure. These resources can be viewed by others while in transit, and can be modified by an attacker to change the look of the page.</translation>
<translation id="5786044859038896871">Do you want to fill in your card info?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Redo Add</translation>
<translation id="5814352347845180253">You may lose access to premium content from <ph name="SITE" /> and some other sites.</translation>
<translation id="5838278095973806738">You should not enter any sensitive information on this site (for example, passwords or credit cards), because it could be stolen by attackers.</translation>
-<translation id="5843436854350372569">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate containing a weak key. An attacker could have broken the private key, and the server may not be the server you expected (you may be communicating with an attacker). <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">This site can’t be reached</translation>
<translation id="5869522115854928033">Saved passwords</translation>
<translation id="5872918882028971132">Parent Suggestions</translation>
<translation id="5901630391730855834">Yellow</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synced)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 in use}other{# in use}}</translation>
<translation id="5926846154125914413">You may lose access to premium content from some sites.</translation>
<translation id="5959728338436674663">Automatically send some <ph name="BEGIN_WHITEPAPER_LINK" />system information and page content<ph name="END_WHITEPAPER_LINK" /> to Google to help detect dangerous apps and sites. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Week</translation>
<translation id="5967867314010545767">Remove from history</translation>
<translation id="5975083100439434680">Zoom out</translation>
<translation id="598637245381783098">Can’t open payment app</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Page 1}other{Page #}}</translation>
<translation id="6017514345406065928">Green</translation>
+<translation id="6017850046339264347">Attackers on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> could install deceptive apps that pretend to be something else or collect data that may be used to track you. <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synced)</translation>
<translation id="6027201098523975773">Enter a name</translation>
<translation id="6040143037577758943">Close</translation>
<translation id="6042308850641462728">More</translation>
+<translation id="6047233362582046994">If you understand the risks to your security, you may <ph name="BEGIN_LINK" />visit this site<ph name="END_LINK" /> before the harmful apps have been removed.</translation>
+<translation id="6051221802930200923">You cannot visit <ph name="SITE" /> right now because the website uses certificate pinning. Network errors and attacks are usually temporary, so this page will probably work later.</translation>
<translation id="6060685159320643512">Careful, these experiments may bite</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{none}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">You have accessed content using an administrator-provided certificate. Data you provide to <ph name="DOMAIN" /> can be intercepted by your administrator.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{None}=1{1 password (synced)}other{# passwords (synced)}}</translation>
<translation id="6146055958333702838">Check any cables and reboot any routers, modems or other network
devices you may be using.</translation>
<translation id="614940544461990577">Try:</translation>
<translation id="6151417162996330722">The server certificate has a validity period that is too long.</translation>
<translation id="6157877588268064908">To see delivery methods and requirements, select an address</translation>
+<translation id="6158003235852588289">Google Safe Browsing recently detected phishing on <ph name="SITE" />. Phishing sites pretend to be other websites to trick you.</translation>
<translation id="6165508094623778733">Learn more</translation>
+<translation id="6169916984152623906">Now you can browse privately, and other people who use this device won’t see your activity. However, downloads and bookmarks will be saved.</translation>
<translation id="6177128806592000436">Your connection to this site is not secure</translation>
<translation id="6184817833369986695">(cohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Check your Internet connection</translation>
<translation id="6218753634732582820">Remove address from Chromium?</translation>
+<translation id="6221345481584921695">Google Safe Browsing recently <ph name="BEGIN_LINK" />detected malware<ph name="END_LINK" /> on <ph name="SITE" />. Websites that are normally safe are sometimes infected with malware. The malicious content comes from <ph name="SUBRESOURCE_HOST" />, a known malware distributor.</translation>
<translation id="6251924700383757765">Privacy Policy</translation>
<translation id="6254436959401408446">Not enough memory to open this page</translation>
<translation id="625755898061068298">You have chosen to disable security warnings for this site.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Edit bookmark</translation>
<translation id="6410264514553301377">Enter the expiry date and CVC for <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">You asked your parent if it's OK to visit this site</translation>
-<translation id="6416403317709441254">You cannot visit <ph name="SITE" /> at the moment because the website sent scrambled credentials that Chromium cannot process. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Unable to check whether the certificate has been revoked.</translation>
<translation id="6433490469411711332">Edit contact info</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> refused to connect.</translation>
<translation id="6446608382365791566">Add more information</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirm Form Resubmission</translation>
<translation id="6456339708790392414">Your Payment</translation>
<translation id="6458467102616083041">Ignored because default search is disabled by policy.</translation>
-<translation id="6462969404041126431">This server could not prove that it is <ph name="DOMAIN" />; its security certificate might be revoked. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Device policies</translation>
<translation id="6477321094435799029">Chrome detected unusual code on this page and blocked it to protect your personal information (for example, passwords, phone numbers and credit cards).</translation>
<translation id="6489534406876378309">Start uploading crashes</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Exp: <ph name="EXPIRATION_DATE_ABBR" />, last used <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Your manager hasn't approved it yet</translation>
<translation id="6569060085658103619">You're viewing an extension page</translation>
-<translation id="6593753688552673085">less than <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">This content might try to install dangerous software on your device that steals or deletes your information. <ph name="BEGIN_LINK" />Show anyway<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Encryption options</translation>
<translation id="662080504995468778">Stay</translation>
<translation id="6626291197371920147">Add valid card number</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Search</translation>
+<translation id="6630809736994426279">Attackers currently on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to install dangerous programs on your Mac that steal or delete your information (for example, photos, passwords, messages and credit cards). <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">This policy has been deprecated.</translation>
-<translation id="6652240803263749613">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Remove form suggestion from Chromium?</translation>
<translation id="6685834062052613830">Sign out and complete setup</translation>
<translation id="6710213216561001401">Previous</translation>
<translation id="6710594484020273272">&lt;Type search term&gt;</translation>
<translation id="6711464428925977395">There is something wrong with the proxy server or the address is incorrect.</translation>
<translation id="6727102863431372879">Set</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{none}=1{1 item}other{# items}}</translation>
<translation id="674375294223700098">Unknown server certificate error.</translation>
<translation id="6753269504797312559">Policy Value</translation>
<translation id="6757797048963528358">Your device went to sleep.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Customisation ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Failed loading regions data</translation>
+<translation id="6825578344716086703">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate signed using a weak signature algorithm (such as SHA-1). This means that the security credentials that the server presented could have been forged, and the server may not be the server that you expected (you may be communicating with an attacker).</translation>
+<translation id="6830728435402077660">Not secure</translation>
<translation id="6831043979455480757">Translate</translation>
<translation id="6839929833149231406">Area</translation>
<translation id="6874604403660855544">&amp;Redo add</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Your card is confirmed</translation>
<translation id="6897140037006041989">User Agent</translation>
<translation id="6915804003454593391">User:</translation>
+<translation id="6945221475159498467">Select</translation>
<translation id="6948701128805548767">To see pickup methods and requirements, select an address</translation>
<translation id="6957887021205513506">The server's certificate appears to be a forgery.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Both fixed proxy servers and a .pac script URL are specified.</translation>
<translation id="6989763994942163495">+ Show advanced settings</translation>
<translation id="7000990526846637657">No history entries found</translation>
-<translation id="7009986207543992532">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate whose validity period is too long to be trustworthy. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Your Google account may have other forms of browsing history at <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Passwords</translation>
+<translation id="7050187094878475250">You attempted to reach <ph name="DOMAIN" />, but the server presented a certificate whose validity period is too long to be trustworthy.</translation>
+<translation id="7053983685419859001">Block</translation>
<translation id="7064851114919012435">Contact info</translation>
<translation id="7079718277001814089">This site contains malware</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7088615885725309056">Older</translation>
<translation id="7090678807593890770">Search Google for <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Allowed by an extension</translation>
<translation id="7119414471315195487">Close other tabs or programmes</translation>
<translation id="7129409597930077180">Can’t deliver to this address. Select a different address.</translation>
<translation id="7138472120740807366">Delivery method</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Processing</translation>
<translation id="724691107663265825">The site ahead contains malware</translation>
<translation id="724975217298816891">Enter the expiry date and CVC for <ph name="CREDIT_CARD" /> to update your card details. Once you've confirmed, your card details will be shared with this site.</translation>
-<translation id="725866823122871198">A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your computer's date and time (<ph name="DATE_AND_TIME" />) are incorrect.</translation>
+<translation id="7260504762447901703">Revoke access</translation>
<translation id="7275334191706090484">Managed Bookmarks</translation>
<translation id="7298195798382681320">Recommended</translation>
<translation id="7309308571273880165">Crash report captured on <ph name="CRASH_TIME" /> (upload requested by user, not yet uploaded)</translation>
<translation id="7334320624316649418">&amp;Redo reorder</translation>
<translation id="733923710415886693">The server's certificate was not disclosed via Certificate Transparency.</translation>
-<translation id="7351800657706554155">You cannot visit <ph name="SITE" /> at the moment because its certificate has been revoked. Network errors and attacks are usually temporary, so this page will probably work later. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Command Line</translation>
<translation id="7372973238305370288">search result</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nope</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Confirm Card</translation>
-<translation id="7394102162464064926">Are you sure that you want to delete these pages from your history?
-
-Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Profile Path</translation>
<translation id="7424977062513257142">An embedded page on this webpage says:</translation>
@@ -688,6 +754,7 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="7444046173054089907">This site is blocked</translation>
<translation id="7445762425076701745">The identity of the server to which you are connected cannot be fully validated. You are connected to a server using a name valid only within your network, and an external certificate authority has no way to validate ownership. As some certificate authorities will issue certificates for these names regardless, there is no way to ensure that you are connected to the intended website and not to an attacker.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about this problem.</translation>
+<translation id="7455133967321480974">Use global default (Block)</translation>
<translation id="7460163899615895653">Your recent tabs from other devices appear here</translation>
<translation id="7469372306589899959">Confirming card</translation>
<translation id="7481312909269577407">Forward</translation>
@@ -695,36 +762,43 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="7508255263130623398">Returned policy device ID is empty or doesn't match current device ID</translation>
<translation id="7514365320538308">Download</translation>
<translation id="7518003948725431193">No web page was found for the web address: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Value</translation>
<translation id="7537536606612762813">Mandatory</translation>
+<translation id="7542403920425041731">Once you confirm, your card details will be shared with this site.</translation>
<translation id="7542995811387359312">Automatic credit card filling is disabled because this form does not use a secure connection.</translation>
<translation id="7543525346216957623">Ask your parent</translation>
<translation id="7549584377607005141">This web page requires data that you entered earlier in order to be properly displayed. You can send this data again, but by doing so you will repeat any action this page previously performed.</translation>
<translation id="7552846755917812628">Try the following tips:</translation>
<translation id="7554791636758816595">New Tab</translation>
+<translation id="7567204685887185387">This server could not prove that it is <ph name="DOMAIN" />; its security certificate might have been issued fraudulently. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation>
<translation id="7568593326407688803">This page is in<ph name="ORIGINAL_LANGUAGE" />Would you like to translate it?</translation>
<translation id="7569952961197462199">Remove credit card from Chrome?</translation>
<translation id="7569983096843329377">Black</translation>
<translation id="7578104083680115302">Pay quickly on sites and apps across devices using cards that you have saved with Google.</translation>
-<translation id="7588950540487816470">Physical web</translation>
+<translation id="7588950540487816470">Physical Web</translation>
<translation id="7592362899630581445">Server's certificate violates name constraints.</translation>
+<translation id="7598391785903975535">Less than <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> is currently unable to handle this request.</translation>
<translation id="7600965453749440009">Never translate <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Value is out of range <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Exp: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">You already have data that is encrypted using a different version of your Google Account password. Please enter it below.</translation>
-<translation id="7634554953375732414">Your connection to this site is not private.</translation>
<translation id="7637571805876720304">Remove credit card from Chromium?</translation>
<translation id="765676359832457558">Hide advanced settings ...</translation>
<translation id="7658239707568436148">Cancel</translation>
+<translation id="7662298039739062396">Setting controlled by an extension</translation>
<translation id="7667346355482952095">Returned policy token is empty or doesn't match current token</translation>
<translation id="7668654391829183341">Unknown device</translation>
<translation id="7669271284792375604">Attackers on this site might try to trick you into installing programs that harm your browsing experience (for example, by changing your homepage or showing extra ads on sites that you visit).</translation>
<translation id="7674629440242451245">Interested in cool new Chrome features? Try our dev channel at chrome.com/dev.</translation>
<translation id="7682287625158474539">Shipping</translation>
+<translation id="7701040980221191251">None</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Proceed to <ph name="SITE" /> (unsafe)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificate</translation>
+<translation id="7716147886133743102">Blocked by your administrator</translation>
<translation id="7716424297397655342">This site can’t be loaded from the cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Unmanaged</translation>
<translation id="7755287808199759310">Your parent can unblock it for you</translation>
<translation id="7758069387465995638">Firewall or antivirus software may have blocked the connection.</translation>
@@ -751,15 +825,15 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Mobile bookmarks</translation>
<translation id="7961015016161918242">Never</translation>
-<translation id="7962083544045318153">Crash ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Always translate <ph name="ORIGINAL_LANGUAGE" /> to <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Not Specified</translation>
<translation id="800218591365569300">Try closing other tabs or programmes to free up memory.</translation>
<translation id="8012647001091218357">We could not reach your parents at the moment. Please try again.</translation>
<translation id="8025119109950072390">Attackers on this site may trick you into doing something dangerous like installing software or revealing your personal information (for example passwords, phone numbers or credit cards).</translation>
-<translation id="803030522067524905">Google Safe Browsing recently detected phishing on <ph name="SITE" />. Phishing sites pretend to be other websites to trick you. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">This page is in <ph name="SOURCE_LANGUAGE" />. Translate it to <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Ask (default)</translation>
<translation id="8041089156583427627">Send Feedback</translation>
+<translation id="8041940743680923270">Use global default (Ask)</translation>
<translation id="8088680233425245692">Failed to view article.</translation>
<translation id="8089520772729574115">less than 1 MB</translation>
<translation id="8091372947890762290">Activation is pending on the server</translation>
@@ -768,13 +842,14 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="8134994873729925007"><ph name="HOST_NAME" />’s server <ph name="BEGIN_ABBR" />DNS address<ph name="END_ABBR" /> could not be found.</translation>
<translation id="8149426793427495338">Your computer went to sleep.</translation>
<translation id="8150722005171944719">The file at <ph name="URL" /> is not readable. It may have been removed, moved or file permissions may be preventing access.</translation>
+<translation id="8184538546369750125">Use global default (Allow)</translation>
+<translation id="8191494405820426728">Local Crash ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Undo Move</translation>
<translation id="8201077131113104583">Invalid update URL for extension with ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Order summary</translation>
<translation id="8218327578424803826">Assigned Location:</translation>
<translation id="8225771182978767009">The person who set up this computer has chosen to block this site.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Attackers currently on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to install dangerous programs on your computer that steal or delete your information (for example photos, passwords, messages and credit cards).</translation>
<translation id="8241707690549784388">The page that you're looking for used information that you entered. Returning to that page might cause any action that you took to be repeated. Do you want to continue?</translation>
<translation id="8249320324621329438">Last fetched:</translation>
<translation id="8253091569723639551">Billing address required</translation>
@@ -782,6 +857,7 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="8289355894181816810">Contact your network administrator if you're not sure what this means.</translation>
<translation id="8293206222192510085">Add Bookmark</translation>
<translation id="8294431847097064396">Source</translation>
+<translation id="8306404619377842860">A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your device's date and time (<ph name="DATE_AND_TIME" />) are incorrect. <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">The translation failed because of a problem with the network connection.</translation>
<translation id="8332188693563227489">Access to <ph name="HOST_NAME" /> was denied</translation>
<translation id="834457929814110454">If you understand the risks to your security, you may <ph name="BEGIN_LINK" />visit this site<ph name="END_LINK" /> before the harmful programs have been removed.</translation>
@@ -802,11 +878,9 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="8483780878231876732">To use cards from your Google account, sign in to Chrome</translation>
<translation id="8488350697529856933">Applies to</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> took too long to respond.</translation>
-<translation id="852346902619691059">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by your device's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Find out more<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Year of Expiry</translation>
<translation id="8543181531796978784">You can <ph name="BEGIN_ERROR_LINK" />report a detection problem<ph name="END_ERROR_LINK" /> or, if you understand the risks to your security, <ph name="BEGIN_LINK" />visit this unsafe site<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">The translation failed because the page's language could not be determined.</translation>
-<translation id="8559762987265718583">A private connection to <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> can't be established because your device's date and time (<ph name="DATE_AND_TIME" />) are incorrect.</translation>
<translation id="8571890674111243710">Translating page into <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Add phone no.</translation>
<translation id="859285277496340001">The certificate does not specify a mechanism to check whether it has been revoked.</translation>
@@ -816,10 +890,11 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="8718314106902482036">Payment not completed</translation>
<translation id="8725066075913043281">Try again</translation>
<translation id="8728672262656704056">You’ve gone incognito</translation>
-<translation id="8730621377337864115">Finished</translation>
+<translation id="8730621377337864115">Done</translation>
<translation id="8738058698779197622">To establish a secure connection, your clock needs to be set correctly. This is because the certificates that websites use to identify themselves are only valid for specific periods of time. Since your device's clock is incorrect, Chromium cannot verify these certificates.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" />’s &lt;abbr id="dnsDefinition"&gt;DNS address&lt;/abbr&gt; could not be found. Diagnosing the problem.</translation>
<translation id="8759274551635299824">This card has expired</translation>
+<translation id="8761567432415473239">Google Safe Browsing recently <ph name="BEGIN_LINK" />found harmful programs<ph name="END_LINK" /> on <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Redo delete</translation>
<translation id="8800988563907321413">Your nearby suggestions appear here</translation>
<translation id="8820817407110198400">Bookmarks</translation>
@@ -832,29 +907,30 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="8870413625673593573">Recently Closed</translation>
<translation id="8874824191258364635">Enter a valid card number</translation>
<translation id="8876793034577346603">Network configuration failed to be parsed.</translation>
-<translation id="8877192140621905067">Once you've confirm, your card details will be shared with this site</translation>
<translation id="8889402386540077796">Hue</translation>
<translation id="8891727572606052622">Invalid proxy mode.</translation>
<translation id="889901481107108152">Sorry, this experiment is not available on your platform.</translation>
<translation id="8903921497873541725">Zoom in</translation>
<translation id="8931333241327730545">Do you want to save this card to your Google Account?</translation>
<translation id="8932102934695377596">Your clock is behind</translation>
-<translation id="8954894007019320973">(Cont.)</translation>
<translation id="8971063699422889582">Server's certificate has expired.</translation>
<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation>
-<translation id="8987927404178983737">Month</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">The site ahead contains harmful programs</translation>
+<translation id="8997023839087525404">The server presented a certificate that was not publicly disclosed using the Certificate Transparency policy. This is a requirement for some certificates, to ensure that they are trustworthy and protect against attackers.</translation>
<translation id="9001074447101275817">The proxy <ph name="DOMAIN" /> requires a username and password.</translation>
+<translation id="9005998258318286617">Failed to load PDF document.</translation>
<translation id="901974403500617787">Flags that apply system-wide can only be set by the owner: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Card billing address required</translation>
<translation id="9020542370529661692">This page has been translated to <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Security error</translation>
<translation id="9038649477754266430">Use a prediction service to load pages more quickly</translation>
<translation id="9039213469156557790">Furthermore, this page includes other resources which are not secure. These resources can be viewed by others while in transit, and can be modified by an attacker to change the behaviour of the page.</translation>
-<translation id="9040185888511745258">Attackers on <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> might attempt to trick you into installing programs that harm your browsing experience (for example, by changing your homepage or showing extra ads on sites that you visit).</translation>
+<translation id="9049981332609050619">You attempted to reach <ph name="DOMAIN" />, but the server presented an invalid certificate.</translation>
<translation id="9050666287014529139">Passphrase</translation>
<translation id="9065203028668620118">Edit</translation>
<translation id="9068849894565669697">Select colour</translation>
+<translation id="9069693763241529744">Blocked by an extension</translation>
<translation id="9076283476770535406">It may have mature content</translation>
<translation id="9078964945751709336">More information required</translation>
<translation id="9103872766612412690"><ph name="SITE" /> normally uses encryption to protect your information. When Chromium tried to connect to <ph name="SITE" /> this time, the website sent back unusual and incorrect credentials. This may happen when an attacker is trying to pretend to be <ph name="SITE" />, or a Wi-Fi sign-in screen has interrupted the connection. Your information is still secure because Chromium stopped the connection before any data was exchanged.</translation>
@@ -863,16 +939,21 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY" /> may come in handy next time.</tr
<translation id="9148507642005240123">&amp;Undo edit</translation>
<translation id="9154194610265714752">Updated</translation>
<translation id="9157595877708044936">Setting up...</translation>
+<translation id="9169664750068251925">Always block on this site</translation>
<translation id="9170848237812810038">&amp;Undo</translation>
<translation id="917450738466192189">Server's certificate is invalid.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" /> and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> uses an unsupported protocol.</translation>
<translation id="9205078245616868884">Your data is encrypted with your sync passphrase. Enter it to start sync.</translation>
<translation id="9207861905230894330">Failed to add article.</translation>
+<translation id="9219103736887031265">Images</translation>
<translation id="933612690413056017">There is no Internet connection</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CLEAR FORM</translation>
<translation id="939736085109172342">New folder</translation>
<translation id="941721044073577244">Looks like you don't have permission to visit this site</translation>
<translation id="969892804517981540">Official Build</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{None}=1{1 item}other{# items}}</translation>
<translation id="988159990683914416">Developer Build</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_es-419.xtb b/chromium/components/strings/components_strings_es-419.xtb
index 5b747a1b6b3..5021842842d 100644
--- a/chromium/components/strings/components_strings_es-419.xtb
+++ b/chromium/components/strings/components_strings_es-419.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Girar a la derecha</translation>
<translation id="1038842779957582377">nombre desconocido</translation>
<translation id="1050038467049342496">Cierra las demás apps.</translation>
-<translation id="1053591932240354961">No puedes visitar <ph name="SITE" /> ahora mismo porque el sitio web envió credenciales confusas que Google Chrome no puede procesar. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;Deshacer Agregar</translation>
<translation id="10614374240317010">Nunca guardado</translation>
<translation id="106701514854093668">Favoritos de escritorio</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Caché de política correcta</translation>
<translation id="113188000913989374"><ph name="SITE" /> dice:</translation>
<translation id="1132774398110320017">Configuración de la función Autocompletar de Chrome…</translation>
+<translation id="1150979032973867961">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el sistema operativo de la computadora no confía en el certificado de seguridad. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
+<translation id="1151972924205500581">Contraseña obligatoria</translation>
<translation id="1152921474424827756">Accede a una <ph name="BEGIN_LINK" />copia almacenada en caché<ph name="END_LINK" /> de <ph name="URL" />.</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> cerró la conexión de forma inesperada.</translation>
<translation id="1161325031994447685">Volver a conectarte a Wi-Fi</translation>
+<translation id="1165039591588034296">Error</translation>
<translation id="1175364870820465910">Im&amp;primir...</translation>
<translation id="1181037720776840403">Eliminar</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Informar automáticamente<ph name="END_WHITEPAPER_LINK" /> los detalles de posibles incidentes de seguridad a Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Más sobre este sitio</translation>
<translation id="1206967143813997005">La firma inicial no es válida</translation>
<translation id="1209206284964581585">Ocultar por el momento</translation>
+<translation id="121201262018556460">Intentaste acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado que contiene una clave no segura. Es posible que un atacante haya descifrado la clave privada y que este no sea el servidor esperado (es posible que hayas establecido comunicación con un atacante).</translation>
<translation id="1219129156119358924">Seguridad del sistema</translation>
<translation id="1227224963052638717">Política desconocida</translation>
<translation id="1227633850867390598">Ocultar valor</translation>
<translation id="1228893227497259893">El identificador de la entidad es incorrecto.</translation>
<translation id="1232569758102978740">Sin título</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
<translation id="1263231323834454256">Lista de lectura</translation>
<translation id="1264126396475825575">El informe de fallos se capturó el <ph name="CRASH_TIME" /> (todavía no se cargó ni se ignoró)</translation>
+<translation id="1281526147609854549">Emitido por <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Se bloqueó contenido peligroso</translation>
<translation id="1285320974508926690">Nunca traducir este sitio</translation>
<translation id="129553762522093515">Cerrado recientemente</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Intenta borrar tus cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Es posible que tu actividad <ph name="BEGIN_EMPHASIS" />todavía sea visible<ph name="END_EMPHASIS" /> para:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Los sitios web que visitas
+ <ph name="LIST_ITEM" />Tu empleador o institución educativa
+ <ph name="LIST_ITEM" />El proveedor de servicios de Internet
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Inscripción de dominio:</translation>
<translation id="1340482604681802745">Dirección de retiro</translation>
<translation id="1344211575059133124">Al parecer, necesitas permiso para visitar este sitio</translation>
<translation id="1344588688991793829">Configuración de la función Autocompletar de Chromium…</translation>
+<translation id="1348198688976932919">El siguiente sitio incluye apps peligrosas</translation>
<translation id="1374468813861204354">sugerencias</translation>
<translation id="1375198122581997741">Acerca de la versión</translation>
<translation id="1377321085342047638">N. tarjeta</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> no envió ningún dato.</translation>
<translation id="1407135791313364759">Abrir todas</translation>
<translation id="1413809658975081374">Error de privacidad</translation>
+<translation id="14171126816530869">La identidad de <ph name="ORGANIZATION" /> en <ph name="LOCALITY" /> ha sido verificada por <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Sí</translation>
<translation id="1430915738399379752">Imprimir</translation>
-<translation id="1442912890475371290">Se bloqueó un intento de <ph name="BEGIN_LINK" />acceso a una página en <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">No puedes visitar <ph name="SITE" /> ahora mismo porque el sitio web usa la fijación de certificados. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> más}other{<ph name="PAYMENT_METHOD_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> más}}</translation>
<translation id="1506687042165942984">Se muestra una copia guardada (es decir, desactualizada) de la página.</translation>
<translation id="1517433312004943670">Se requiere el número de teléfono</translation>
<translation id="1519264250979466059">Fecha de compilación</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript debe estar habilitado para usar esta función.</translation>
<translation id="1555130319947370107">Azul</translation>
<translation id="1559528461873125649">El archivo o directorio no existe</translation>
-<translation id="1559572115229829303">&lt;p&gt;No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora del dispositivo (<ph name="DATE_AND_TIME" />) son incorrectas.&lt;/p&gt;
-
- &lt;p&gt;Ajusta la fecha y la hora desde la sección &lt;strong&gt;General&lt;/strong&gt; de la app de &lt;strong&gt;Configuración&lt;/strong&gt; .&lt;/p&gt;</translation>
<translation id="1583429793053364125">Se produjo un error al mostrar la página web.</translation>
<translation id="1592005682883173041">Acceso a datos locales</translation>
+<translation id="1594030484168838125">Seleccionar</translation>
<translation id="161042844686301425">Cian</translation>
+<translation id="1620510694547887537">Cámara</translation>
<translation id="1629803312968146339">¿Quieres que Chrome guarde esta tarjeta?</translation>
<translation id="1639239467298939599">Cargando</translation>
<translation id="1640180200866533862">Políticas de usuario</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">La configuración de red no es válida y no se pudo importar.</translation>
<translation id="1644574205037202324">Historial</translation>
<translation id="1645368109819982629">Protocolo no compatible</translation>
+<translation id="1655462015569774233">{1,plural, =1{El servidor no logró comprobar si el dominio es <ph name="DOMAIN" />; el certificado de seguridad venció ayer. Es posible que esto se deba a una configuración incorrecta o a que un atacante haya interceptado la conexión. Actualmente, el reloj de la computadora está configurado en la siguiente fecha: <ph name="CURRENT_DATE" />. ¿Es correcto? De no ser así, corrige el reloj del sistema y, a continuación, actualiza la página.}other{El servidor no logró comprobar si el dominio es <ph name="DOMAIN" />; el certificado de seguridad venció hace # días. Es posible que esto se deba a una configuración incorrecta o a que un atacante haya interceptado la conexión. Actualmente, el reloj de la computadora está configurado en la siguiente fecha: <ph name="CURRENT_DATE" />. ¿Es correcto? De no ser así, corrige el reloj del sistema y, a continuación, actualiza la página.}}</translation>
<translation id="1656489000284462475">Retiro</translation>
<translation id="1663943134801823270">Las tarjetas y direcciones provienen de Chrome. Puedes administrarlas en <ph name="BEGIN_LINK" />Configuración<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> suele utilizar la encriptación para proteger la información. Cuando Google Chrome intentó conectarse a <ph name="SITE" />, el sitio web devolvió credenciales incorrectas y poco comunes. Es posible que un atacante quiera suplantar a <ph name="SITE" /> o que una pantalla de acceso Wi-Fi haya interrumpido la conexión. Tu información permanece segura porque Google Chrome detuvo la conexión para evitar el intercambio de datos.</translation>
-<translation id="168328519870909584">Los atacantes que se encuentran actualmente en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar instalar aplicaciones peligrosas en tu dispositivo con el objetivo de robarte información o borrarla (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="168841957122794586">El certificado del servidor contiene una clave criptográfica no segura.</translation>
+<translation id="1706954506755087368">{1,plural, =1{El servidor no logró comprobar si el dominio es <ph name="DOMAIN" />; supuestamente, el certificado de seguridad entra en vigencia mañana. Es posible que esto se deba a una configuración incorrecta o a que un atacante haya interceptado la conexión.}other{El servidor no logró comprobar si el dominio es <ph name="DOMAIN" />; supuestamente, el certificado de seguridad entra en vigencia en # días. Es posible que esto se deba a una configuración incorrecta o a que un atacante haya interceptado la conexión.}}</translation>
<translation id="1710259589646384581">SO</translation>
<translation id="1721312023322545264">Necesitas permiso de <ph name="NAME" /> para visitar este sitio</translation>
<translation id="1721424275792716183">* El campo es obligatorio</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Descargar la página más tarde</translation>
<translation id="17513872634828108">Pestañas abiertas</translation>
<translation id="1753706481035618306">Número de página</translation>
+<translation id="1763864636252898013">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el sistema operativo del dispositivo no confía en el certificado de seguridad. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Intenta ejecutar el Diagnóstico de red de Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Actualiza tu frase de contraseña de sincronización.</translation>
<translation id="1787142507584202372">Tus pestañas abiertas aparecen aquí</translation>
+<translation id="1789575671122666129">Ventanas emergentes</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nombre del titular de la tarjeta</translation>
-<translation id="1803678881841855883">Navegación segura de Google <ph name="BEGIN_LINK" />detectó software malicioso<ph name="END_LINK" /> en <ph name="SITE" /> recientemente. Los sitios web que por lo general son seguros a veces se infectan con software malicioso. El contenido malicioso proviene de <ph name="SUBRESOURCE_HOST" />, un conocido distribuidor de software malicioso. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Agregada: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Solicitud o parámetros de solicitud no válidos</translation>
<translation id="1826516787628120939">Comprobando</translation>
<translation id="1834321415901700177">Este sitio contiene programas dañinos</translation>
+<translation id="1840414022444569775">Este número de tarjeta ya está en uso</translation>
<translation id="1842969606798536927">Pagar</translation>
<translation id="1871208020102129563">El proxy está configurado para usar servidores proxy fijos, no una URL de script .pac.</translation>
<translation id="1871284979644508959">Campo obligatorio</translation>
<translation id="187918866476621466">Abrir páginas de inicio</translation>
<translation id="1883255238294161206">Ocultar lista</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> más}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> más}}</translation>
<translation id="1898423065542865115">Filtrado</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ninguno}=1{1 sitio}other{# sitios}}</translation>
<translation id="194030505837763158">Ir a <ph name="LINK" /></translation>
<translation id="1962204205936693436">Favoritos de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error de serialización</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Se ignoró porque fue anulada por <ph name="POLICY_NAME" /> .</translation>
<translation id="2138201775715568214">Buscando páginas web físicas cercanas</translation>
<translation id="213826338245044447">Favoritos del celular</translation>
-<translation id="2148716181193084225">Hoy</translation>
+<translation id="2147827593068025794">Sincronización en segundo plano</translation>
<translation id="2154054054215849342">El servicio de sincronización no está disponible para tu dominio</translation>
<translation id="2154484045852737596">Editar tarjeta</translation>
<translation id="2166049586286450108">Acceso de administrador completo</translation>
<translation id="2166378884831602661">Este sitio no puede proporcionar una conexión segura</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 dirección}other{# direcciones}}</translation>
+<translation id="2187317261103489799">Detectar (predeterminado)</translation>
<translation id="2202020181578195191">Ingresa un año de vencimiento válido</translation>
<translation id="2212735316055980242">No se encontró la política.</translation>
<translation id="2213606439339815911">Recuperando entradas…</translation>
+<translation id="2218879909401188352">Es posible que los atacantes que se encuentran actualmente en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> instalen apps peligrosas que dañen tu dispositivo, agreguen cargos ocultos en la factura de tu servicio móvil o roben tu información personal. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Corregir la conexión con la <ph name="BEGIN_LINK" />app de diagnóstico<ph name="END_LINK" />.</translation>
<translation id="2239100178324503013">Enviar ahora</translation>
<translation id="225207911366869382">Este valor ya no se utiliza para esta política.</translation>
<translation id="2262243747453050782">Error de HTTP</translation>
+<translation id="2270484714375784793">Número de teléfono</translation>
<translation id="2282872951544483773">Experimentos no disponibles</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> elemento}other{<ph name="ITEM_COUNT" /> elementos}}</translation>
<translation id="2292556288342944218">Se bloqueó tu acceso a Internet</translation>
<translation id="230155334948463882">¿Una tarjeta nueva?</translation>
-<translation id="2305919008529760154">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el certificado de seguridad podría haberse emitido de forma fraudulenta. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> requiere un nombre de usuario y una contraseña.</translation>
-<translation id="2318774815570432836">No puedes visitar <ph name="SITE" /> ahora mismo porque el sitio web usa HSTS. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Configuración controlada por tu administrador</translation>
<translation id="2354001756790975382">Otros favoritos</translation>
+<translation id="2354430244986887761">Navegación segura de Google recientemente <ph name="BEGIN_LINK" />encontró apps dañinas<ph name="END_LINK" /> en <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Es posible que los atacantes vean las imágenes que observas en este sitio y las modifiquen para engañarte.</translation>
+<translation id="2356070529366658676">Preguntar</translation>
+<translation id="2359629602545592467">Varias</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2365563543831475020">El informe de fallos que se capturó a las <ph name="CRASH_TIME" /> no se cargó</translation>
<translation id="2367567093518048410">Nivel</translation>
-<translation id="2371153335857947666">{1,plural, =1{Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; su certificado de seguridad caducó ayer. Es posible que esto se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. El reloj de la computadora actualmente está configurado en la siguiente fecha: <ph name="CURRENT_DATE" />. ¿Es correcto? De no ser así, corrige el reloj del sistema y, luego, actualiza esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}other{Este servidor no pudo comprobar si el dominio es <ph name="DOMAIN" />; su certificado de seguridad caducó hace # días. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. El reloj de la computadora actualmente está configurado en la siguiente fecha: <ph name="CURRENT_DATE" />. ¿Es correcto? De no ser así, corrige el reloj del sistema y, luego, actualiza esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">No hay alternativas de interfaz de usuario disponibles.</translation>
<translation id="2384307209577226199">Empresa (predeterminada)</translation>
<translation id="2386255080630008482">Se ha revocado el certificado del servidor.</translation>
<translation id="2392959068659972793">Mostrar políticas sin valor establecido</translation>
<translation id="239429038616798445">El método de envío no está disponible. Prueba otro método.</translation>
<translation id="2396249848217231973">&amp;Deshacer Eliminar</translation>
-<translation id="2460160116472764928">Navegación segura de Google <ph name="BEGIN_LINK" />detectó software malicioso<ph name="END_LINK" /> en <ph name="SITE" /> recientemente. Los sitios web que por lo general son seguros a veces se infectan con software malicioso. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" /> y se podría revocar el certificado de seguridad. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
<translation id="2463739503403862330">Llenar</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Ejecución del Diagnóstico de red<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL de búsqueda no válida</translation>
+<translation id="2482878487686419369">Notificaciones</translation>
<translation id="2491120439723279231">El certificado del servidor contiene errores.</translation>
<translation id="2495083838625180221">Analizador de JSON</translation>
<translation id="2495093607237746763">Si marcas esta opción, Chromium almacenará una copia de la tarjeta en el dispositivo para completar más rápidamente los formularios.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Ir atrás</translation>
<translation id="2515629240566999685">Verificar la señal en tu área.</translation>
<translation id="2516305470678292029">Alternativas de interfaz de usuario</translation>
+<translation id="2539524384386349900">Detectar</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> envió una respuesta no válida.</translation>
-<translation id="2552545117464357659">Reciente</translation>
<translation id="2556876185419854533">&amp;Deshacer Editar</translation>
<translation id="2587730715158995865">De <ph name="ARTICLE_PUBLISHER" />. Lee este artículo y <ph name="OTHER_ARTICLE_COUNT" /> más.</translation>
<translation id="2587841377698384444">ID de API de directorio:</translation>
<translation id="2597378329261239068">Este documento está protegido por contraseña. Ingresa una contraseña.</translation>
<translation id="2609632851001447353">Variaciones</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ninguna}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">El reloj está adelantado</translation>
<translation id="2639739919103226564">Estado:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Se denegó el acceso al archivo.</translation>
<translation id="2653659639078652383">Enviar</translation>
<translation id="2666117266261740852">Cierra las demás pestañas o apps.</translation>
+<translation id="2670429602441959756">Esta página incluye funciones que aún no son compatibles con RV. Saliendo…</translation>
<translation id="2674170444375937751">¿Estás seguro de que deseas eliminar estas páginas del historial?</translation>
<translation id="2677748264148917807">Abandonar</translation>
-<translation id="269990154133806163">El servidor presentó un certificado que no se divulgó de forma pública con la política Certificado de transparencia. Este es un requisito para algunos certificados que permite garantizar su confiabilidad y protegerte de atacantes. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Lista de lectura</translation>
<translation id="2704283930420550640">El valor no coincide con el formato.</translation>
<translation id="2704951214193499422">Chrome no pudo confirmar tu tarjeta. Vuelve a intentarlo más tarde.</translation>
<translation id="2705137772291741111">La copia guardada (en caché) de este sitio es ilegible.</translation>
<translation id="2709516037105925701">Autocompletar</translation>
-<translation id="2712118517637785082">Intentaste acceder a <ph name="DOMAIN" />, pero el emisor anuló el certificado que presentó el servidor. Esto significa que no se debe confiar en absoluto en las credenciales de seguridad que presentó el servidor; es posible que te comuniques con un atacante. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Solicitar permiso</translation>
<translation id="2713444072780614174">Blanco</translation>
<translation id="2720342946869265578">Cercanas</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Falta un registro de dispositivo.</translation>
<translation id="2784949926578158345">Se ha restablecido la conexión.</translation>
<translation id="2794233252405721443">Sitio bloqueado</translation>
+<translation id="2799020568854403057">El siguiente sitio incluye apps dañinas</translation>
+<translation id="2803306138276472711">La Navegación segura de Google <ph name="BEGIN_LINK" />detectó software malicioso<ph name="END_LINK" /> en <ph name="SITE" /> recientemente. A veces, los sitios web que suelen ser seguros contienen software malicioso.</translation>
<translation id="2824775600643448204">Barra de direcciones y de búsqueda</translation>
<translation id="2826760142808435982">La conexión se encriptó y autenticó con <ph name="CIPHER" />, y utiliza <ph name="KX" /> como el mecanismo de intercambio de claves.</translation>
<translation id="2835170189407361413">Eliminar formulario</translation>
+<translation id="2856444702002559011">Es posible que algunos atacantes intenten robar tu información de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (p. ej., contraseñas, mensajes o tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">No volver a cargar</translation>
<translation id="2900469785430194048">Google Chrome se quedó sin memoria cuando intentaba mostrar esta página web.</translation>
<translation id="2909946352844186028">Se detectó un cambio de red.</translation>
<translation id="2916038427272391327">Cierra los demás programas.</translation>
<translation id="2922350208395188000">No se puede comprobar el certificado del servidor.</translation>
<translation id="2928905813689894207">Dirección de facturación</translation>
+<translation id="2941952326391522266">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el certificado de seguridad proviene de <ph name="DOMAIN2" />. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
<translation id="2948083400971632585">Puedes inhabilitar los servidores proxy configurados para una conexión desde la página de configuración.</translation>
<translation id="2955913368246107853">Cerrar la barra de búsqueda</translation>
<translation id="2958431318199492670">La configuración de red no cumple con el estándar ONC. Es posible que no se importen algunas partes de la configuración.</translation>
-<translation id="29611076221683977">Los atacantes que se encuentran actualmente en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar instalar programas peligrosos en tu Mac con el fin de robarte información o eliminarla (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="2966678944701946121">Venc.: <ph name="EXPIRATION_DATE_ABBR" />, agregada: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Para establecer una conexión segura, el reloj se debe configurar correctamente. Esto se debe a que los certificados que usan los sitios web para su identificación solo son válidos por períodos de tiempo específicos. Debido a que la configuración del reloj del dispositivo es incorrecta, Google Chrome no puede verificar estos certificados.</translation>
<translation id="2972581237482394796">&amp;Rehacer</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Ingresa una dirección válida</translation>
<translation id="2986368408720340940">El método de retiro no está disponible. Prueba otro método.</translation>
<translation id="2991174974383378012">Compartir con los sitios web</translation>
+<translation id="2991571918955627853">No puedes visitar <ph name="SITE" /> ahora porque el sitio web usa HSTS. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde.</translation>
<translation id="3005723025932146533">Mostrar copia guardada</translation>
<translation id="3008447029300691911">Ingresa el CVC de la tarjeta <ph name="CREDIT_CARD" />. Después de confirmarla, los datos de tu tarjeta se compartirán con este sitio.</translation>
<translation id="3010559122411665027">Entrada de lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Bloqueado de forma automática</translation>
<translation id="3024663005179499861">Tipo de política incorrecto</translation>
<translation id="3032412215588512954">¿Deseas volver a cargar este sitio?</translation>
<translation id="3037605927509011580">¡Oh, no!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{al menos 1 elemento en dispositivos sincronizados}=1{1 elemento (y más en dispositivos sincronizados)}other{# elementos (y más en dispositivos sincronizados)}}</translation>
<translation id="3041612393474885105">Información sobre el certificado</translation>
<translation id="3063697135517575841">Chrome no pudo confirmar tu tarjeta en este momento. Vuelve a intentarlo más tarde.</translation>
<translation id="3064966200440839136">Saldrás del modo de navegación incógnito para pagar mediante una aplicación externa. ¿Deseas continuar?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ninguna}=1{1 contraseña}other{# contraseñas}}</translation>
<translation id="3093245981617870298">No estás conectado.</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3109728660330352905">No tienes autorización para ver esta página.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Intenta ejecutar el Diagnóstico de conectividad<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Se produjo un error al decodificar respuesta.</translation>
<translation id="3150653042067488994">Error temporal del servidor</translation>
@@ -247,17 +277,21 @@
<translation id="3167968892399408617">Una vez que cierres todas las pestañas de incógnito, las páginas que hayas visitado en ese modo no se guardarán en el historial del navegador, en la lista de cookies ni en el historial de búsquedas. Se guardarán los archivos que descargues y los favoritos que crees.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Isla</translation>
+<translation id="317583078218509884">La nueva configuración de permisos del sitio se aplicará al volver a cargar la página.</translation>
<translation id="3176929007561373547">Comprueba la configuración del proxy o comunícate con tu
administrador de red para asegurarte de que el
servidor proxy esté funcionando. Si consideras
que no necesitas usar un servidor proxy:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Abre la página en modo de navegación incógnito.</translation>
-<translation id="3202578601642193415">Más reciente</translation>
+<translation id="320323717674993345">Cancelar pago</translation>
<translation id="3207960819495026254">Agregada a favoritos</translation>
+<translation id="3225919329040284222">El servidor mostró un certificado que no coincide con lo esperado. Estas expectativas se incluyen en determinados sitios web con un alto nivel de seguridad para garantizar tu protección.</translation>
<translation id="3226128629678568754">Presiona el botón para volver a cargar y, de ese modo, enviar nuevamente los datos necesarios para cargar la página.</translation>
+<translation id="3227137524299004712">Micrófono</translation>
<translation id="3228969707346345236">Falló la traducción debido a que la página ya se encuentra en <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Ingresar el CVC de la tarjeta <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Siempre detectar contenido importante en este sitio</translation>
<translation id="3254409185687681395">Agregar esta página a Favoritos</translation>
<translation id="3270847123878663523">&amp;Deshacer Reorganizar</translation>
<translation id="3282497668470633863">Agregar el nombre en la tarjeta</translation>
@@ -271,42 +305,48 @@
<translation id="3340978935015468852">configuración</translation>
<translation id="3345135638360864351">No se pudo enviar la solicitud de acceso al sitio a <ph name="NAME" />. Vuelve a intentarlo.</translation>
<translation id="3355823806454867987">Cambiar la configuración del proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />no guardará<ph name="END_EMPHASIS" /> la siguiente información:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />El historial de navegación
+ <ph name="LIST_ITEM" />Cookies y datos de sitios
+ <ph name="LIST_ITEM" />Información que ingreses en formularios
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Error de reloj</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> artículos más…</translation>
<translation id="337363190475750230">Desaprovisionado</translation>
<translation id="3377188786107721145">Error al analizar la política</translation>
<translation id="3380365263193509176">Error desconocido</translation>
<translation id="3380864720620200369">ID de cliente:</translation>
<translation id="3391030046425686457">Dirección de entrega</translation>
<translation id="3395827396354264108">Método de retiro</translation>
-<translation id="340013220407300675">Es posible que usuarios no autorizados estén intentando robar tu información de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (por ejemplo, contraseñas, mensajes o tarjetas de crédito).</translation>
<translation id="3422248202833853650">Prueba cerrar los demás programas para liberar memoria.</translation>
<translation id="3422472998109090673">No se puede acceder a <ph name="HOST_NAME" /> en este momento.</translation>
+<translation id="3427092606871434483">Permitir (predeterminado)</translation>
<translation id="3427342743765426898">&amp;Rehacer Editar</translation>
<translation id="3431636764301398940">Guardar esta tarjeta para este dispositivo</translation>
<translation id="3435896845095436175">Habilitar</translation>
<translation id="3447661539832366887">El propietario del dispositivo desactivó el juego de dinosaurios.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Obtener intervalo:</translation>
<translation id="3462200631372590220">Ocultar detalles avanzados</translation>
<translation id="3467763166455606212">Se requiere el nombre del titular de la tarjeta</translation>
<translation id="3478058380795961209">Mes vencimiento</translation>
<translation id="3479539252931486093">¿Ocurrió algo inesperado? <ph name="BEGIN_LINK" />Cuéntanos<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ahora no</translation>
-<translation id="348000606199325318">ID de fallo <ph name="CRASH_LOCAL_ID" /> (ID de servidor: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">No pudimos comunicarnos con ninguno de tus padres. Vuelve a intentarlo.</translation>
<translation id="3528171143076753409">El certificado del servidor no es de confianza.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Al menos 1 elemento en dispositivos sincronizados}=1{1 elemento (y más en dispositivos sincronizados)}other{# elementos (y más en dispositivos sincronizados)}}</translation>
<translation id="3539171420378717834">Conservar una copia de la tarjeta en el dispositivo.</translation>
<translation id="3542684924769048008">Utilizar la contraseña para:</translation>
+<translation id="3545341443414427877">No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y hora de la computadora (<ph name="DATE_AND_TIME" />) son incorrectas. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Encriptar todos los datos sincronizados con tu propia frase de contraseña para sincronización</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> más...</translation>
-<translation id="3555561725129903880">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el certificado de seguridad es del dominio <ph name="DOMAIN2" />. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Tu administrador puede desbloquearlo por ti</translation>
<translation id="3566021033012934673">La conexión no es privada</translation>
+<translation id="3569145463236695319">&lt;p&gt;No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y hora del dispositivo (<ph name="DATE_AND_TIME" />) son incorrectas.&lt;/p&gt;
+
+ &lt;p&gt;Ajusta la fecha y hora desde la sección &lt;strong&gt;General&lt;/strong&gt; de la app de &lt;strong&gt;Configuración&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Agregar nombre</translation>
<translation id="3583757800736429874">&amp;Rehacer Mover</translation>
<translation id="3586931643579894722">Ocultar detalles</translation>
-<translation id="3587482841069643663">Todos</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Ingresa una fecha de vencimiento válida</translation>
<translation id="36224234498066874">Eliminar datos de navegación...</translation>
@@ -323,7 +363,6 @@
<translation id="3681007416295224113">Información sobre el certificado</translation>
<translation id="3690164694835360974">Acceso no seguro</translation>
<translation id="3693415264595406141">Contraseña:</translation>
-<translation id="3696411085566228381">ninguno</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Cargando...</translation>
<translation id="3712624925041724820">Licencias agotadas</translation>
@@ -331,12 +370,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Comprobar la configuración del proxy, firewall o DNS<ph name="END_LINK" />.</translation>
<translation id="3736520371357197498">Si comprendes los riesgos para tu seguridad, puedes <ph name="BEGIN_LINK" />visitar este sitio no seguro<ph name="END_LINK" /> antes de que se hayan eliminado los programas peligrosos.</translation>
<translation id="3739623965217189342">Vínculo copiado</translation>
+<translation id="3744899669254331632">No puedes visitar <ph name="SITE" /> en este momento porque el sitio web envió credenciales encriptadas que Chromium no puede procesar. Los ataques y errores de red generalmente son temporales, por lo que esta página probablemente funcionará de nuevo más tarde.</translation>
+<translation id="3748148204939282805">Es posible que los atacantes en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten engañarte para que realices alguna acción peligrosa, como instalar software o revelar información personal (p. ej., contraseñas, números de teléfono o tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Falló la traducción debido a un error de servidor.</translation>
<translation id="3759461132968374835">No has notificado ningún bloqueo recientemente. Los bloqueos que se hayan producido mientras la función de notificación de bloqueos estaba desactivada no aparecerán en esta página.</translation>
+<translation id="3778403066972421603">¿Deseas guardar esta tarjeta en tu cuenta de Google y en este dispositivo?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Vencimiento: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Si utilizas un servidor proxy...</translation>
<translation id="3828924085048779000">No se permite una frase de contraseña vacía.</translation>
-<translation id="3845539888601087042">Se muestra el historial de los dispositivos a los que accediste. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Atrás</translation>
<translation id="3858027520442213535">Actualizar fecha y hora</translation>
<translation id="3884278016824448484">Hay un identificador de dispositivo en conflicto.</translation>
@@ -344,11 +386,13 @@
<translation id="3886446263141354045">Tu solicitud de acceso a este sitio se envió a <ph name="NAME" /></translation>
<translation id="3890664840433101773">Agregar correo electrónico</translation>
<translation id="3901925938762663762">Caducó la tarjeta.</translation>
-<translation id="3933571093587347751">{1,plural, =1{Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; supuestamente, su certificado de seguridad entra en vigencia mañana. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}other{El servidor no pudo comprobar si el dominio es <ph name="DOMAIN" />; supuestamente, su certificado de seguridad entra en vigencia en # días. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">No se pudo cargar el documento PDF</translation>
+<translation id="3945915738023014686">ID del informe de fallos <ph name="CRASH_ID" /> cargado (ID de fallo local: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; su certificado de seguridad no especifica la extensión Nombres alternativos del asunto. Es posible que se deba a un error en la configuración o a que haya un atacante que está interceptando tu conexión.</translation>
<translation id="3963721102035795474">Modo de lectura</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ninguno}=1{De 1 sitio }other{De # sitios }}</translation>
<translation id="397105322502079400">Calculando...</translation>
<translation id="3973234410852337861">Se bloqueó <ph name="HOST_NAME" /></translation>
+<translation id="3987940399970879459">Menos de 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 página web cercana}other{# páginas web cercanas}}</translation>
<translation id="4021036232240155012">DNS es el servicio en red que traduce el nombre de un sitio web en su dirección de Internet.</translation>
<translation id="4030383055268325496">&amp;Deshacer Agregar</translation>
@@ -359,56 +403,63 @@
<translation id="4079302484614802869">El proxy está configurado para usar una URL de script .pac, no servidores proxy fijos.</translation>
<translation id="4098354747657067197">Sitio engañoso</translation>
<translation id="4103249731201008433">El número de serie del dispositivo no es válido.</translation>
+<translation id="410351446219883937">Reproducción automática</translation>
<translation id="4103763322291513355">Visita &lt;strong&gt;chrome://policy&lt;/strong&gt; para ver las URL en lista negra y otras políticas que estableció el administrador del sistema.</translation>
-<translation id="4110615724604346410">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; su certificado de seguridad tiene errores. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Permitir siempre en este sitio</translation>
<translation id="4117700440116928470">No se admite el alcance de la política.</translation>
-<translation id="4118212371799607889">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; Chromium no confía en el certificado de seguridad. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 más}other{# más}}</translation>
<translation id="4130226655945681476">Comprobar los cables de red, el módem y el router</translation>
+<translation id="413544239732274901">Más información</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Utilizar opción predeterminada global (detectar)</translation>
+<translation id="4165986682804962316">Configuración del sitio</translation>
<translation id="4169947484918424451">¿Quieres que Chromium guarde esta tarjeta?</translation>
<translation id="4171400957073367226">La firma de verificación no es válida.</translation>
<translation id="4196861286325780578">&amp;Rehacer Mover</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Comprobar las configuraciones de firewall y antivirus<ph name="END_LINK" />.</translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ninguna}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Fallos</translation>
+<translation id="422022731706691852">Es posible que los atacantes en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten engañarte para que instales programas que dañen tu experiencia de navegación (p. ej., al cambiar la página principal o mostrar anuncios adicionales en los sitios que visitas). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Intenta ejecutar el Diagnóstico de red<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Válido</translation>
<translation id="4250431568374086873">Tu conexión con este sitio no es completamente segura</translation>
<translation id="4250680216510889253">No</translation>
<translation id="425582637250725228">Es posible que los cambios que implementaste no se puedan guardar.</translation>
<translation id="4258748452823770588">Firma no válida</translation>
+<translation id="4265872034478892965">Permitido por tu administrador</translation>
<translation id="4269787794583293679">(Sin nombre de usuario)</translation>
<translation id="4275830172053184480">Reiniciar tu dispositivo</translation>
<translation id="4280429058323657511">, exp <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Navegación segura de Google <ph name="BEGIN_LINK" />encontró programas dañinos<ph name="END_LINK" /> en <ph name="SITE" /> recientemente. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">Sugerencias para padres</translation>
<translation id="4304224509867189079">Acceder</translation>
-<translation id="432290197980158659">El servidor mostró un certificado que no coincide con lo esperado. Estas expectativas se incluyen en determinados sitios web con un alto nivel de seguridad para garantizar tu protección. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Bloquear (predeterminado)</translation>
<translation id="4325863107915753736">No se pudo encontrar el artículo</translation>
<translation id="4326324639298822553">Comprueba la fecha de vencimiento y vuelve a intentarlo</translation>
<translation id="4331708818696583467">No seguro</translation>
<translation id="4356973930735388585">Es posible que los atacantes que se encuentren en este sitio intenten instalar programas peligrosos en tu computadora con el fin de robarte información o borrarla (p. ej., fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE" /> esperado.</translation>
+<translation id="4377125064752653719">Intentaste acceder a <ph name="DOMAIN" />, pero el emisor anuló el certificado que presentó el servidor. Esto significa que no se debe confiar en absoluto en las credenciales de seguridad que presentó el servidor. Te puedes estar comunicando con un atacante.</translation>
<translation id="4381091992796011497">Nombre de usuario:</translation>
<translation id="4394049700291259645">Inhabilitar</translation>
<translation id="4406896451731180161">resultados de búsqueda</translation>
+<translation id="4424024547088906515">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; Chrome no confía en el certificado de seguridad. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> no aceptó tu certificado de acceso o es posible que no se haya proporcionado.</translation>
<translation id="443673843213245140">Se inhabilitó el uso de un proxy, pero se especificó una configuración explícita de proxy.</translation>
-<translation id="4492190037599258964">Resultados de búsqueda de '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Error de validación: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Comunicarse con el administrador del sistema.</translation>
<translation id="450710068430902550">Compartir con el administrador</translation>
<translation id="4515275063822566619">Las tarjetas y direcciones provienen de Chrome y de tu cuenta de Google (<ph name="ACCOUNT_EMAIL" />). Puedes administrar esta información en <ph name="BEGIN_LINK" />Configuración<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detalles</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Intenta inhabilitar tus extensiones.</translation>
<translation id="457875822857220463">Entrega</translation>
<translation id="4587425331216688090">¿Confirmas que quieres quitar la dirección de Chrome?</translation>
-<translation id="4589078953350245614">Intentaste acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado no válido. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Tu conexión a <ph name="DOMAIN" /> está encriptada con un conjunto de cifrado moderno.</translation>
<translation id="4594403342090139922">&amp;Deshacer Eliminar</translation>
<translation id="4619615317237390068">Pestañas de otros dispositivos</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el certificado de seguridad contiene errores. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
+<translation id="4690462567478992370">Dejar de usar un certificado no válido</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Se interrumpió la conexión</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Ejecución del Diagnóstico de red de Windows<ph name="END_LINK" /></translation>
@@ -425,21 +476,24 @@
<translation id="4771973620359291008">Se ha producido un error desconocido.</translation>
<translation id="4800132727771399293">Verifica la fecha de vencimiento y el CVC, y vuelve a intentarlo.</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">No puedes visitar <ph name="SITE" /> ahora porque el sitio web envió credenciales confusas que Google Chrome no puede procesar. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde.</translation>
<translation id="4813512666221746211">Error de red</translation>
<translation id="4816492930507672669">Ajustar a la página</translation>
<translation id="483020001682031208">No hay páginas web físicas para mostrar</translation>
<translation id="4850886885716139402">Ver</translation>
<translation id="4854362297993841467">Este método de entrega no está disponible. Prueba otro método.</translation>
<translation id="4858792381671956233">Les preguntaste a tus padres si puedes visitar este sitio</translation>
+<translation id="4863764087567530506">Es posible que este contenido trate de engañarte para que instales software o reveles información personal. <ph name="BEGIN_LINK" />Mostrar de todos modos<ph name="END_LINK" /></translation>
<translation id="4880827082731008257">Buscar historial</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{y 1 página web más}other{y # páginas web más}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Esta página ha sido traducida desde un idioma desconocido a <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pago</translation>
<translation id="4926049483395192435">Debe especificarse un valor.</translation>
<translation id="495170559598752135">Acciones</translation>
<translation id="4958444002117714549">Mostrar lista</translation>
-<translation id="4962322354953122629">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; Chrome no confía en el certificado de seguridad. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Volver a habilitar las advertencias</translation>
<translation id="4989809363548539747">Este complemento no es compatible</translation>
<translation id="5002932099480077015">Si se habilita esta opción, Chrome almacenará una copia de la tarjeta en el dispositivo para llenar más rápidamente los formularios.</translation>
<translation id="5018422839182700155">No se puede abrir esta página</translation>
@@ -447,14 +501,15 @@
<translation id="5023310440958281426">Revisa las políticas del administrador.</translation>
<translation id="5029568752722684782">Borrar la copia</translation>
<translation id="5031870354684148875">Acerca de Google Traductor</translation>
+<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidad</translation>
<translation id="5045550434625856497">Contraseña incorrecta</translation>
<translation id="5056549851600133418">Artículos para ti</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Comprobar la dirección de proxy<ph name="END_LINK" />.</translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Sin cookies}=1{1 sitio usa cookies. }other{# sitios usan cookies. }}</translation>
<translation id="5087286274860437796">El certificado del servidor no es válido en este momento.</translation>
<translation id="5087580092889165836">Agregar tarjeta</translation>
<translation id="5089810972385038852">Estado</translation>
+<translation id="5094747076828555589">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; Chromium no confía en el certificado de seguridad. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
<translation id="5095208057601539847">Provincia</translation>
<translation id="5115563688576182185">(64 bits)</translation>
<translation id="5141240743006678641">Encriptar contraseñas sincronizadas con tus credenciales de Google</translation>
@@ -470,24 +525,24 @@
<translation id="5222812217790122047">Correo electrónico (obligatorio)</translation>
<translation id="5251803541071282808">Nube</translation>
<translation id="5277279256032773186">¿Usas Chrome en el trabajo? Las empresas pueden administrar la configuración de Chrome para sus empleados. Más información</translation>
+<translation id="5297526204711817721">Tu conexión a este sitio no es privada. Para salir del modo RV en cualquier momento, quita los auriculares y presiona Atrás.</translation>
<translation id="5299298092464848405">Error al analizar la política</translation>
-<translation id="5300589172476337783">Mostrar</translation>
<translation id="5308689395849655368">Notificación de fallas desactivada.</translation>
<translation id="5317780077021120954">Guardar</translation>
<translation id="5327248766486351172">Nombre</translation>
-<translation id="5337705430875057403">Los atacantes de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían engañarte para que hagas algo peligroso, como instalar software o divulgar información personal (por ejemplo, contraseñas, números de teléfono o tarjetas de crédito).</translation>
-<translation id="5359637492792381994">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; su certificado de seguridad no es válido en este momento. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">No puedes visitar <ph name="SITE" /> ahora porque este certificado se revocó. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde.</translation>
<translation id="536296301121032821">Error al almacenar la configuración de la política</translation>
<translation id="5386426401304769735">La cadena del certificado de este sitio web contiene un certificado que se firmó con SHA-1.</translation>
<translation id="5402410679244714488">Venc.: <ph name="EXPIRATION_DATE_ABBR" />, último uso: hace más de un año</translation>
+<translation id="540969355065856584">Este servidor no pudo demostrar que se trata de <ph name="DOMAIN" />; el certificado de seguridad no es válido en este momento. Esto puede deberse a una configuración incorrecta o a un ataque que intercepta tu conexión.</translation>
<translation id="5421136146218899937">Borrar datos de navegación...</translation>
<translation id="5430298929874300616">Eliminar marcador</translation>
<translation id="5431657950005405462">No se encontró tu archivo</translation>
-<translation id="5435775191620395718">Se muestra el historial de este dispositivo. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Error de validación de esquema en "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">No se encuentra esta página <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">Marca de tiempo de política incorrecta</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> de <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Sin validez</translation>
<translation id="5470861586879999274">&amp;Rehacer Editar</translation>
<translation id="54817484435770891">Agregar una dirección válida</translation>
<translation id="5492298309214877701">En la intranet de la compañía, organización o escuela, este sitio tiene la misma URL que un sitio web externo
@@ -504,6 +559,8 @@
<translation id="5571083550517324815">No se puede retirar el artículo en esta dirección. Selecciona una diferente.</translation>
<translation id="5572851009514199876">Abre Chrome y accede a tu cuenta para que el programa pueda comprobar si puedes acceder a este sitio.</translation>
<translation id="5580958916614886209">Comprueba el mes de vencimiento y vuelve a intentarlo</translation>
+<translation id="5586446728396275693">No hay direcciones guardadas</translation>
+<translation id="5595485650161345191">Editar dirección</translation>
<translation id="560412284261940334">No se admite la administración.</translation>
<translation id="5610142619324316209">Comprobar la conexión.</translation>
<translation id="5610807607761827392">Puedes administrar tarjetas y direcciones en <ph name="BEGIN_LINK" />Configuración<ph name="END_LINK" />.</translation>
@@ -511,15 +568,18 @@
<translation id="5622887735448669177">¿Deseas salir de este sitio?</translation>
<translation id="5629630648637658800">Error al cargar la configuración de la política</translation>
<translation id="5631439013527180824">Token de administración de dispositivos no válido</translation>
+<translation id="5633066919399395251">Es posible que los atacantes que actualmente se encuentran en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten instalar programas peligrosos en tu computadora para robar o borrar información (p. ej., fotos, contraseñas, mensajes y tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Ubicación</translation>
+<translation id="5659593005791499971">Correo electrónico</translation>
<translation id="5669703222995421982">Obtener contenido personalizado</translation>
<translation id="5675650730144413517">Esta página no funciona</translation>
-<translation id="5677928146339483299">Bloqueado</translation>
-<translation id="5694783966845939798">Intentaste acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado firmado con un algoritmo de firma no seguro (como SHA-1). Es posible que se hayan falsificado las credenciales de seguridad presentadas por el servidor y que este no sea el servidor esperado (es posible que te comuniques con un atacante). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">No se ha verificado la identidad de este sitio web.</translation>
+<translation id="5713016350996637505">Se bloqueó contenido engañoso</translation>
<translation id="5720705177508910913">Usuario actual</translation>
<translation id="5732392974455271431">Tus padres pueden desbloquearlo por ti</translation>
<translation id="5763042198335101085">Escribe una dirección de correo electrónico válida</translation>
<translation id="5765072501007116331">Para ver los requisitos y métodos de entrega, selecciona una dirección</translation>
+<translation id="5778550464785688721">Control total de dispositivos MIDI</translation>
<translation id="5784606427469807560">Se produjo un problema al confirmar tu tarjeta. Comprueba tu conexión a Internet y vuelve a intentarlo.</translation>
<translation id="5785756445106461925">Además, esta página incluye otros recursos que no son seguros. Otras personas pueden ver estos recursos mientras se encuentran en tránsito, y un atacante puede modificarlos para cambiar la apariencia de la página.</translation>
<translation id="5786044859038896871">¿Deseas llenar los campos con la información de tu tarjeta?</translation>
@@ -528,14 +588,14 @@
<translation id="5813119285467412249">&amp;Rehacer Agregar</translation>
<translation id="5814352347845180253">Es posible que ya no puedas acceder al contenido premium de <ph name="SITE" /> y otros sitios.</translation>
<translation id="5838278095973806738">No debes ingresar información confidencial en este sitio (p. ej., contraseñas o tarjetas de crédito), ya que los atacantes podrían robarla.</translation>
-<translation id="5843436854350372569">Intentaste acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado que contiene una clave no segura. Es posible que un atacante haya descifrado la clave privada y que este no sea el servidor esperado (es posible que te comuniques con un atacante). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">No se puede acceder a este sitio</translation>
<translation id="5869522115854928033">Contraseñas almacenadas</translation>
<translation id="5872918882028971132">Sugerencias para padres</translation>
<translation id="5901630391730855834">Amarillo</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sincronizado)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 en uso}other{# en uso}}</translation>
<translation id="5926846154125914413">Es posible que ya no puedas acceder al contenido premium de otros sitios.</translation>
<translation id="5959728338436674663">Enviar automáticamente <ph name="BEGIN_WHITEPAPER_LINK" />determinado contenido de la página e información del sistema<ph name="END_WHITEPAPER_LINK" /> a Google para detectar apps y sitios peligrosos <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Semana</translation>
<translation id="5967867314010545767">Eliminar del historial</translation>
<translation id="5975083100439434680">Alejar</translation>
<translation id="598637245381783098">No se puede abrir la app de pago</translation>
@@ -544,21 +604,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Página 1}other{Página #}}</translation>
<translation id="6017514345406065928">Verde</translation>
+<translation id="6017850046339264347">Es posible que los atacantes que se encuentran en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> instalen apps engañosas que se hagan pasar por otro tipo de contenido o que recopilen datos que se usen para rastrearte. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sincronizados)</translation>
<translation id="6027201098523975773">Ingresa un nombre</translation>
<translation id="6040143037577758943">Cerrar</translation>
<translation id="6042308850641462728">Más</translation>
+<translation id="6047233362582046994">Si comprendes los riesgos de seguridad, puedes <ph name="BEGIN_LINK" />visitar este sitio<ph name="END_LINK" /> antes de que se hayan quitado las apps dañinas.</translation>
+<translation id="6051221802930200923">No puedes visitar <ph name="SITE" /> ahora porque el sitio web usa la fijación de certificados. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde.</translation>
<translation id="6060685159320643512">Cuidado, estos experimentos pueden dañarte</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ninguna}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Accediste al contenido mediante un certificado proporcionado por el administrador. Los datos que proporciones a <ph name="DOMAIN" /> pueden ser interceptados por tu administrador.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ninguna}=1{1 contraseña (sincronizada)}other{# contraseñas (sincronizadas)}}</translation>
<translation id="6146055958333702838">Revisa los cables y reinicia los routers, módems u otros dispositivos
de red que estés usando.</translation>
<translation id="614940544461990577">Intenta:</translation>
<translation id="6151417162996330722">El certificado de servidor tiene un período de validez demasiado extenso.</translation>
<translation id="6157877588268064908">Para ver los requisitos y métodos de envío, selecciona una dirección</translation>
+<translation id="6158003235852588289">La Navegación segura de Google detectó un intento de suplantación de identidad (phishing) en <ph name="SITE" /> recientemente. Los sitios de suplantación de identidad imitan a otros sitios web para engañarte.</translation>
<translation id="6165508094623778733">Más información</translation>
+<translation id="6169916984152623906">Ahora puedes navegar con privacidad. Si otras personas usan este dispositivo, no verán tu actividad. Sin embargo, se guardarán las descargas y los favoritos.</translation>
<translation id="6177128806592000436">Tu conexión con este sitio no es segura</translation>
<translation id="6184817833369986695">(cohorte: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Comprueba tu conexión a Internet.</translation>
<translation id="6218753634732582820">¿Confirmas que quieres quitar la dirección de Chromium?</translation>
+<translation id="6221345481584921695">La Navegación segura de Google <ph name="BEGIN_LINK" />detectó software malicioso<ph name="END_LINK" /> en <ph name="SITE" /> recientemente. A veces, los sitios web que suelen ser seguros contienen software malicioso. El contenido malicioso proviene de <ph name="SUBRESOURCE_HOST" />, un conocido distribuidor de software malicioso.</translation>
<translation id="6251924700383757765">Política de privacidad</translation>
<translation id="6254436959401408446">Tu dispositivo no tiene suficiente memoria para abrir esta página</translation>
<translation id="625755898061068298">Decidiste inhabilitar las advertencias de seguridad para este sitio.</translation>
@@ -584,15 +652,14 @@
<translation id="6404511346730675251">Editar marcador</translation>
<translation id="6410264514553301377">Ingresar la fecha de vencimiento y el CVC para <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Les preguntaste a tus padres si puedes visitar este sitio</translation>
-<translation id="6416403317709441254">No puedes visitar <ph name="SITE" /> ahora mismo porque el sitio web envió credenciales confusas que Chromium no puede procesar. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">No se pudo verificar si el certificado ha sido revocado.</translation>
<translation id="6433490469411711332">Editar la información de contacto</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> rechazó la conexión.</translation>
<translation id="6446608382365791566">Agregar más información</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmar reenvío del formulario</translation>
<translation id="6456339708790392414">Tu pago</translation>
<translation id="6458467102616083041">Se ignora porque la política inhabilita la búsqueda predeterminada.</translation>
-<translation id="6462969404041126431">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; es posible que su certificado de seguridad se haya revocado. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Políticas de dispositivos</translation>
<translation id="6477321094435799029">Chrome detectó código inusual en esta página y la bloqueó para proteger tu información personal (p. ej.: contraseñas, números de teléfono y tarjetas de crédito).</translation>
<translation id="6489534406876378309">Comenzar a cargar fallos</translation>
@@ -604,20 +671,19 @@
<translation id="6556915248009097796">Venc.: <ph name="EXPIRATION_DATE_ABBR" />, último uso: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Tu administrador aún no lo aprobó</translation>
<translation id="6569060085658103619">Estás viendo la página de una extensión</translation>
-<translation id="6593753688552673085">menos de <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Es posible que este contenido intente instalar software peligroso en tu dispositivo que robe o borre tu información. <ph name="BEGIN_LINK" />Mostrar de todos modos<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">Opciones de encriptación</translation>
<translation id="662080504995468778">Permanecer aquí</translation>
<translation id="6626291197371920147">Agregar un número de tarjeta válido</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Búsqueda</translation>
+<translation id="6630809736994426279">Es posible que los atacantes que actualmente se encuentran en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten instalar programas peligrosos en tu Mac para robar o borrar información (p. ej., fotos, contraseñas, mensajes y tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Esta política no ha sido aprobada.</translation>
-<translation id="6652240803263749613">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el sistema operativo de tu computadora no confía en el certificado de seguridad. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">¿Confirmas que quieres quitar la sugerencia de formulario de Chromium?</translation>
<translation id="6685834062052613830">Salir y completar la configuración</translation>
<translation id="6710213216561001401">Anterior</translation>
<translation id="6710594484020273272">&lt;Escribe el término de búsqueda&gt;</translation>
<translation id="6711464428925977395">Hay un error en el servidor proxy o la dirección es incorrecta.</translation>
<translation id="6727102863431372879">Establecer</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ninguno}=1{1 elemento}other{# elementos}}</translation>
<translation id="674375294223700098">Error de certificado de servidor desconocido.</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6757797048963528358">El dispositivo se suspendió.</translation>
@@ -625,6 +691,8 @@
<translation id="6810899417690483278">ID de personalización</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">No se pudo cargar los datos de las regiones</translation>
+<translation id="6825578344716086703">Intentaste acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado firmado con un algoritmo de firma no seguro (como SHA-1). Esto significa que podrían haberse falsificado las credenciales de seguridad presentadas por el servidor y que este no sea el servidor esperado (es posible que hayas establecido comunicación con un atacante).</translation>
+<translation id="6830728435402077660">No seguro</translation>
<translation id="6831043979455480757">Traducir</translation>
<translation id="6839929833149231406">Ãrea</translation>
<translation id="6874604403660855544">&amp;Rehacer Agregar</translation>
@@ -632,6 +700,7 @@
<translation id="6895330447102777224">Tu tarjeta se confirmó</translation>
<translation id="6897140037006041989">User agent</translation>
<translation id="6915804003454593391">Usuario:</translation>
+<translation id="6945221475159498467">Seleccionar</translation>
<translation id="6948701128805548767">Para ver los requisitos y métodos de retiro, selecciona una dirección</translation>
<translation id="6957887021205513506">El certificado del servidor parece falso.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -640,15 +709,16 @@
<translation id="6973656660372572881">Se especifican servidores proxy fijos y URL de secuencias de comandos .pac.</translation>
<translation id="6989763994942163495">Mostrar configuración avanzada...</translation>
<translation id="7000990526846637657">No se encontraron entradas en el historial</translation>
-<translation id="7009986207543992532">Intentaste acceder a <ph name="DOMAIN" />, pero el certificado de servidor tenía un período de validez demasiado extenso para ser fiable. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Es posible que tu cuenta de Google tenga otros formularios del historial de navegación en <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Contraseñas</translation>
+<translation id="7050187094878475250">Intentaste acceder a <ph name="DOMAIN" />, pero el certificado de servidor tenía un período de validez demasiado extenso para ser fiable.</translation>
+<translation id="7053983685419859001">Bloquear</translation>
<translation id="7064851114919012435">Información de contacto</translation>
<translation id="7079718277001814089">Este sitio contiene software malicioso</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7088615885725309056">Anterior</translation>
<translation id="7090678807593890770">Buscar <ph name="LINK" /> en Google</translation>
+<translation id="7108819624672055576">Permitido por una extensión</translation>
<translation id="7119414471315195487">Cierra las demás pestañas o programas.</translation>
<translation id="7129409597930077180">No se pueden realizar envíos a esa dirección. Selecciona una dirección diferente.</translation>
<translation id="7138472120740807366">Método de entrega</translation>
@@ -666,22 +736,18 @@
<translation id="7220786058474068424">Procesando</translation>
<translation id="724691107663265825">Este sitio web contiene software malicioso</translation>
<translation id="724975217298816891">Ingresa la fecha de vencimiento y el CVC de la tarjeta <ph name="CREDIT_CARD" /> para actualizar sus datos. Después de confirmarla, los datos de tu tarjeta se compartirán con este sitio.</translation>
-<translation id="725866823122871198">No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora del equipo (<ph name="DATE_AND_TIME" />) son incorrectas.</translation>
+<translation id="7260504762447901703">Revocar acceso</translation>
<translation id="7275334191706090484">Favoritos administrados</translation>
<translation id="7298195798382681320">Recomendada</translation>
<translation id="7309308571273880165">El informe de fallos se capturó a las <ph name="CRASH_TIME" /> (el usuario solicitó la carga; todavía no se cargó)</translation>
<translation id="7334320624316649418">&amp;Rehacer Reorganizar</translation>
<translation id="733923710415886693">El certificado del servidor no se divulgó mediante el Certificado de transparencia.</translation>
-<translation id="7351800657706554155">No puedes visitar <ph name="SITE" /> ahora mismo porque este certificado se revocó. Los ataques y errores de red suelen ser temporales, por lo que es posible que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">Línea de comandos</translation>
<translation id="7372973238305370288">resultado de búsqueda</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">No</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Confirmar tarjeta</translation>
-<translation id="7394102162464064926">¿Estás seguro de que quieres eliminar estas páginas del historial?
-
-¡No se lo digas a nadie! El modo incógnito <ph name="SHORTCUT_KEY" /> puede resultarte útil la próxima vez.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Ruta del perfil</translation>
<translation id="7424977062513257142">Una página incrustada en esta página web dice:</translation>
@@ -689,6 +755,7 @@
<translation id="7444046173054089907">Este sitio está bloqueado</translation>
<translation id="7445762425076701745">La identidad del servidor al que estás conectado no se puede validar en su totalidad. Estás conectado a un servidor utilizando un nombre que sólo es válido dentro de tu red y cuya propiedad no puede validar una entidad externa de certificación. Debido a que algunas entidades emiten certificados aún para estos nombres, no hay manera de asegurar que estás conectado al sitio web que pretendías o a un atacante.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /> acerca de este problema</translation>
+<translation id="7455133967321480974">Usar configuración global predeterminada (Bloquear)</translation>
<translation id="7460163899615895653">Aquí aparecen tus pestañas recientes de otros dispositivos</translation>
<translation id="7469372306589899959">Confirmando la tarjeta</translation>
<translation id="7481312909269577407">Reenviar</translation>
@@ -696,36 +763,43 @@
<translation id="7508255263130623398">El ID de dispositivo de la política que se muestra está vacío o no coincide con el ID de dispositivo actual</translation>
<translation id="7514365320538308">Descargar</translation>
<translation id="7518003948725431193">No se encontró una página web para la siguiente dirección web: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obligatoria</translation>
+<translation id="7542403920425041731">Después de que se confirme, los datos de tu tarjeta se compartirán con este sitio.</translation>
<translation id="7542995811387359312">El rellenado automático de la tarjeta de crédito se inhabilitó porque este formulario no usa una conexión segura.</translation>
<translation id="7543525346216957623">Pregúntales a tus padres</translation>
<translation id="7549584377607005141">Esta página web necesita los datos ingresados anteriormente para mostrarse correctamente. Puedes volver a enviar los datos, pero ten en cuenta que se repetirán las acciones que la página haya realizado anteriormente.</translation>
<translation id="7552846755917812628">Intenta las siguientes sugerencias:</translation>
<translation id="7554791636758816595">Nueva pestaña</translation>
+<translation id="7567204685887185387">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el certificado de seguridad podría haberse emitido de forma fraudulenta. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> más}other{<ph name="CONTACT_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> más}}</translation>
<translation id="7568593326407688803">Esta página está en<ph name="ORIGINAL_LANGUAGE" />¿Quieres traducirla?</translation>
<translation id="7569952961197462199">¿Confirmas que quieres quitar la tarjeta de crédito de Chrome?</translation>
<translation id="7569983096843329377">Negro</translation>
<translation id="7578104083680115302">Paga con rapidez en sitios y apps a través de varios dispositivos con tarjetas que guardaste en Google.</translation>
<translation id="7588950540487816470">Web física</translation>
<translation id="7592362899630581445">El certificado del servidor no cumple con las restricciones de nombre.</translation>
+<translation id="7598391785903975535">Menos de <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> no puede procesar esta solicitud en este momento.</translation>
<translation id="7600965453749440009">Nunca traducir <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">El valor <ph name="VALUE" /> está fuera del rango.</translation>
<translation id="7613889955535752492">Vencimiento: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Ya has utilizado otra versión de la contraseña de tu cuenta de Google para encriptar contenido. Ingrésala a continuación.</translation>
-<translation id="7634554953375732414">Tu conexión con este sitio no es privada.</translation>
<translation id="7637571805876720304">¿Confirmas que quieres quitar la tarjeta de crédito de Chromium?</translation>
<translation id="765676359832457558">Ocultar configuración avanzada...</translation>
<translation id="7658239707568436148">Cancelar</translation>
+<translation id="7662298039739062396">Configuración controlada por una extensión</translation>
<translation id="7667346355482952095">El token de política mostrado está vacío o no coincide con el token actual</translation>
<translation id="7668654391829183341">Dispositivo desconocido</translation>
<translation id="7669271284792375604">Es posible que los atacantes de este sitio intenten engañarte para que instales programas que pueden afectar tu experiencia de navegación (p. ej., podrían cambiar la página principal o mostrar más anuncios en los sitios que visitas).</translation>
<translation id="7674629440242451245">Si estás interesado en probar nuevas e interesantes funciones de Chrome, visita nuestro canal de programadores en chrome.com/dev.</translation>
<translation id="7682287625158474539">Envío</translation>
+<translation id="7701040980221191251">Ninguno</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Continuar a <ph name="SITE" /> (no seguro)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificado</translation>
+<translation id="7716147886133743102">Bloqueado por tu administrador</translation>
<translation id="7716424297397655342">No se puede cargar este sitio desde la caché</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Sin administrar</translation>
<translation id="7755287808199759310">Uno de tus padres puede desbloquearlo por ti</translation>
<translation id="7758069387465995638">Es posible que un software antivirus o un firewarll hayan bloqueado la conexión.</translation>
@@ -752,15 +826,15 @@
<translation id="7951415247503192394">(32 bits)</translation>
<translation id="7956713633345437162">Favoritos del celular</translation>
<translation id="7961015016161918242">Nunca</translation>
-<translation id="7962083544045318153">ID del fallo <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Siempre traducir del <ph name="ORIGINAL_LANGUAGE" /> al <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Sin especificar</translation>
<translation id="800218591365569300">Prueba cerrar las demás pestañas o programas para liberar memoria.</translation>
<translation id="8012647001091218357">No pudimos comunicarnos con tus padres. Vuelve a intentarlo.</translation>
<translation id="8025119109950072390">Es posible que los atacantes de este sitio te engañen para que hagas algo peligroso, como instalar software o divulgar información personal (p. ej., contraseñas, números de teléfono o tarjetas de crédito).</translation>
-<translation id="803030522067524905">Navegación segura de Google detectó suplantación de identidad (phishing) en <ph name="SITE" /> recientemente. Este tipo de sitios se hacen pasar por otros sitios web para engañarte. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Esta página está en <ph name="SOURCE_LANGUAGE" />. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Preguntar (predeterminado)</translation>
<translation id="8041089156583427627">Enviar comentario</translation>
+<translation id="8041940743680923270">Usar configuración global predeterminada (Preguntar)</translation>
<translation id="8088680233425245692">Error al visualizar artículo</translation>
<translation id="8089520772729574115">menos de 1 Mb</translation>
<translation id="8091372947890762290">La activación está pendiente en el servidor.</translation>
@@ -769,13 +843,14 @@
<translation id="8134994873729925007">No se encontró la <ph name="BEGIN_ABBR" />dirección DNS<ph name="END_ABBR" /> del servidor de <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">La computadora se suspendió.</translation>
<translation id="8150722005171944719">El archivo de <ph name="URL" /> no se puede leer. Es posible que se haya eliminado o movido o que se impida el acceso a los permisos del archivo.</translation>
+<translation id="8184538546369750125">Usar configuración global predeterminada (Permitir)</translation>
+<translation id="8191494405820426728">ID del fallo local: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Deshacer Mover</translation>
<translation id="8201077131113104583">URL de actualización no válida para la extensión con ID "<ph name="EXTENSION_ID" />"</translation>
<translation id="8202097416529803614">Resumen del pedido</translation>
<translation id="8218327578424803826">Ubicación asignada:</translation>
<translation id="8225771182978767009">La persona que configuró esta computadora decidió bloquear este sitio.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Los atacantes que se encuentran actualmente en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar instalar programas peligrosos en tu computadora con el fin de robarte información o eliminarla (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="8241707690549784388">La página que buscas ha utilizado la información que has especificado. Volver a la página podría provocar la repetición de alguna acción. ¿Deseas continuar?</translation>
<translation id="8249320324621329438">Se obtuvo por última vez:</translation>
<translation id="8253091569723639551">Se requiere una dirección de facturación</translation>
@@ -783,6 +858,7 @@
<translation id="8289355894181816810">Comunícate con el administrador de red si no entiendes bien lo que significa.</translation>
<translation id="8293206222192510085">Agregar Marcador</translation>
<translation id="8294431847097064396">Fuente</translation>
+<translation id="8306404619377842860">No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y hora del dispositivo (<ph name="DATE_AND_TIME" />) son incorrectas. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Se produjo un error en la traducción a causa de un problema con la conexión de red.</translation>
<translation id="8332188693563227489">Se denegó el acceso a <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Si comprendes los riesgos de seguridad, puedes <ph name="BEGIN_LINK" />visitar este sitio<ph name="END_LINK" /> antes de que se hayan eliminado los programas peligrosos.</translation>
@@ -803,11 +879,9 @@
<translation id="8483780878231876732">Para usar tarjetas de tu cuenta de Google, accede a tu cuenta en Chrome</translation>
<translation id="8488350697529856933">Se aplica a</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> tardó demasiado en responder.</translation>
-<translation id="852346902619691059">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; el sistema operativo de tu dispositivo no confía en el certificado de seguridad. Es posible que se deba a una configuración incorrecta o a que un atacante haya interceptado tu conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Año vencimiento</translation>
<translation id="8543181531796978784">Puedes <ph name="BEGIN_ERROR_LINK" />informar un problema de detección<ph name="END_ERROR_LINK" /> o, si comprendes los riesgos de seguridad, puedes <ph name="BEGIN_LINK" />visitar el sitio no seguro<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Falló la traducción debido a que no se pudo determinar el idioma de la página.</translation>
-<translation id="8559762987265718583">No se puede establecer una conexión privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora del dispositivo (<ph name="DATE_AND_TIME" />) son incorrectas.</translation>
<translation id="8571890674111243710">Traduciendo página a <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Agregar teléfono
</translation>
@@ -822,6 +896,7 @@
<translation id="8738058698779197622">Para establecer una conexión segura, el reloj debe estar configurado correctamente. Esto se debe a que los certificados que usan los sitios web para su identificación solo son válidos por períodos de tiempo específicos. Debido a que la configuración del reloj del dispositivo es incorrecta, Chromium no puede verificar estos certificados.</translation>
<translation id="8740359287975076522">No se encontró <ph name="HOST_NAME" />’s &lt;abbr id="dnsDefinition"&gt;DNS address&lt;/abbr&gt;. Se está diagnosticando el problema.</translation>
<translation id="8759274551635299824">La tarjeta está vencida</translation>
+<translation id="8761567432415473239">La navegación segura de Google <ph name="BEGIN_LINK" />encontró programas peligrosos<ph name="END_LINK" /> recientemente en <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Rehacer Eliminar</translation>
<translation id="8800988563907321413">Las sugerencias de la sección Cercanas aparecen aquí</translation>
<translation id="8820817407110198400">Favoritos</translation>
@@ -834,29 +909,30 @@
<translation id="8870413625673593573">Cerrado recientemente</translation>
<translation id="8874824191258364635">Ingresa un número de tarjeta válido</translation>
<translation id="8876793034577346603">No se pudo analizar la configuración de red.</translation>
-<translation id="8877192140621905067">Después de que se confirme, los datos de tu tarjeta se compartirán con este sitio</translation>
<translation id="8889402386540077796">Tono</translation>
<translation id="8891727572606052622">Modo proxy no válido</translation>
<translation id="889901481107108152">Este experimento no está disponible en tu plataforma.</translation>
<translation id="8903921497873541725">Acercar</translation>
<translation id="8931333241327730545">¿Quieres guardar esta tarjeta en tu cuenta de Google?</translation>
<translation id="8932102934695377596">El reloj está atrasado</translation>
-<translation id="8954894007019320973">(Cont.)</translation>
<translation id="8971063699422889582">El certificado del servidor ha caducado.</translation>
<translation id="8986494364107987395">Enviar automáticamente estadísticas de uso e informes sobre fallos a Google</translation>
-<translation id="8987927404178983737">Mes</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">El siguiente sitio contiene programas peligrosos</translation>
+<translation id="8997023839087525404">El servidor presentó un certificado que no se divulgó de forma pública con la política Certificado de transparencia. Este es un requisito para algunos certificados que permite garantizar su confiabilidad y protegerte de atacantes.</translation>
<translation id="9001074447101275817">El proxy <ph name="DOMAIN" /> requiere un nombre de usuario y una contraseña.</translation>
+<translation id="9005998258318286617">No se pudo cargar el documento PDF.</translation>
<translation id="901974403500617787">El propietario es el único que puede especificar las marcas que se aplican a todo el sistema: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Se requiere una dirección de facturación de la tarjeta</translation>
<translation id="9020542370529661692">Esta página se tradujo al <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="9035022520814077154">Error de seguridad</translation>
<translation id="9038649477754266430">Utilizar un servicio de predicción para cargar las páginas más rápido</translation>
<translation id="9039213469156557790">Además, esta página incluye otros recursos que no son seguros. Otras personas pueden ver estos recursos mientras se encuentran en tránsito, y un atacante puede modificarlos para cambiar el funcionamiento de la página.</translation>
-<translation id="9040185888511745258">Los atacantes del sitio <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar engañarte para que instales programas que pueden afectar la navegación (por ejemplo, podrían cambiar la página principal o mostrar más anuncios en los sitios que visitas).</translation>
+<translation id="9049981332609050619">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor presentó un certificado no válido.</translation>
<translation id="9050666287014529139">Frase de contraseña</translation>
<translation id="9065203028668620118">Editar</translation>
<translation id="9068849894565669697">Seleccionar color</translation>
+<translation id="9069693763241529744">Bloqueado por una extensión</translation>
<translation id="9076283476770535406">Es posible que incluya contenido para adultos</translation>
<translation id="9078964945751709336">Se requiere más información</translation>
<translation id="9103872766612412690"><ph name="SITE" /> suele utilizar la encriptación para proteger la información. Cuando Chromium intentó conectarse a <ph name="SITE" />, el sitio web devolvió credenciales incorrectas y poco comunes. Es posible que un atacante quiera suplantar a <ph name="SITE" /> o que una pantalla de acceso Wi-Fi haya interrumpido la conexión. Tu información permanece segura porque Chromium detuvo la conexión para evitar el intercambio de datos.</translation>
@@ -865,16 +941,21 @@
<translation id="9148507642005240123">&amp;Deshacer Editar</translation>
<translation id="9154194610265714752">Actualizado</translation>
<translation id="9157595877708044936">Configurando...</translation>
+<translation id="9169664750068251925">Bloquear siempre en este sitio</translation>
<translation id="9170848237812810038">&amp;Deshacer</translation>
<translation id="917450738466192189">El certificado del servidor no es válido.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> más}other{<ph name="SHIPPING_OPTION_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> más}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> utiliza un protocolo no compatible.</translation>
<translation id="9205078245616868884">Tus datos están encriptados con tu frase de contraseña para sincronización. Debes ingresarla para iniciar la sincronización.</translation>
<translation id="9207861905230894330">Error al agregar artículo</translation>
+<translation id="9219103736887031265">Imágenes</translation>
<translation id="933612690413056017">No hay conexión a Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">BORRAR FORMULARIO</translation>
<translation id="939736085109172342">Nueva carpeta</translation>
<translation id="941721044073577244">Al parecer, no tienes permiso para visitar este sitio</translation>
<translation id="969892804517981540">Build oficial</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ninguno}=1{1 elemento}other{# elementos}}</translation>
<translation id="988159990683914416">Build para desarrolladores</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_es.xtb b/chromium/components/strings/components_strings_es.xtb
index 0c8ec0efe8d..14d9f646a0f 100644
--- a/chromium/components/strings/components_strings_es.xtb
+++ b/chromium/components/strings/components_strings_es.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Girar hacia la derecha</translation>
<translation id="1038842779957582377">nombre desconocido</translation>
<translation id="1050038467049342496">Cierra otras aplicaciones</translation>
-<translation id="1053591932240354961">No puedes acceder a <ph name="SITE" /> en este momento porque el sitio web ha enviado credenciales codificadas que Google Chrome no puede procesar. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;Deshacer acción de añadir</translation>
<translation id="10614374240317010">Contraseñas que nunca se guardan</translation>
<translation id="106701514854093668">Marcadores del ordenador</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Caché de política correcta</translation>
<translation id="113188000913989374"><ph name="SITE" /> dice:</translation>
<translation id="1132774398110320017">Configuración de la función Autocompletar de Chrome...</translation>
+<translation id="1150979032973867961">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, el sistema operativo de tu ordenador no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
+<translation id="1151972924205500581">Contraseña obligatoria</translation>
<translation id="1152921474424827756">Accede a una <ph name="BEGIN_LINK" />copia almacenada en caché<ph name="END_LINK" /> de <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ha cerrado la conexión de forma inesperada.</translation>
<translation id="1161325031994447685">Volver a conectarte a una red Wi-Fi</translation>
+<translation id="1165039591588034296">Error</translation>
<translation id="1175364870820465910">Im&amp;primir...</translation>
<translation id="1181037720776840403">Eliminar</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Informar automáticamente<ph name="END_WHITEPAPER_LINK" /> a Google sobre los detalles de posibles incidentes de seguridad. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Más entradas de este sitio</translation>
<translation id="1206967143813997005">Firma inicial no válida</translation>
<translation id="1209206284964581585">Ocultar por ahora</translation>
+<translation id="121201262018556460">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado que contiene una clave no segura. Es posible que alguien haya descifrado la clave privada y que hayas accedido a la página de esa persona en lugar de establecer conexión con el servidor.</translation>
<translation id="1219129156119358924">Seguridad del sistema</translation>
<translation id="1227224963052638717">Política desconocida</translation>
<translation id="1227633850867390598">Ocultar valor</translation>
<translation id="1228893227497259893">Identificador de entidad incorrecto</translation>
<translation id="1232569758102978740">Sin título</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
<translation id="1263231323834454256">Lista de lectura</translation>
<translation id="1264126396475825575">Informe sobre fallos registrado el <ph name="CRASH_TIME" /> (todavía no se ha subido ni ignorado)</translation>
+<translation id="1281526147609854549">Emitido por <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Contenido peligroso bloqueado</translation>
<translation id="1285320974508926690">No traducir nunca este sitio</translation>
<translation id="129553762522093515">Cerrado recientemente</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Borrar las cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Es posible que tu actividad <ph name="BEGIN_EMPHASIS" />todavía sea visible<ph name="END_EMPHASIS" /> para:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Los sitios web que visites
+ <ph name="LIST_ITEM" />Tu empresa o centro educativo
+ <ph name="LIST_ITEM" />Tu proveedor de servicios de Internet
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Dominio de registro:</translation>
<translation id="1340482604681802745">Dirección de recogida</translation>
<translation id="1344211575059133124">Parece que necesitas permiso para acceder a este sitio web</translation>
<translation id="1344588688991793829">Configuración de la función Autocompletar de Chromium...</translation>
+<translation id="1348198688976932919">El sitio web al que vas a acceder contiene aplicaciones peligrosas</translation>
<translation id="1374468813861204354">sugerencias</translation>
<translation id="1375198122581997741">Información de la versión</translation>
<translation id="1377321085342047638">Número de tarjeta</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> no ha enviado ningún dato.</translation>
<translation id="1407135791313364759">Abrir todas</translation>
<translation id="1413809658975081374">Error de privacidad</translation>
+<translation id="14171126816530869">La identidad de <ph name="ORGANIZATION" /> en <ph name="LOCALITY" /> ha sido verificada por <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Sí</translation>
<translation id="1430915738399379752">Imprimir</translation>
-<translation id="1442912890475371290">Se ha bloqueado un intento de <ph name="BEGIN_LINK" />acceso a una página de <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">No puedes acceder a <ph name="SITE" /> en este momento porque el sitio web utiliza la fijación de certificados. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> más}other{<ph name="PAYMENT_METHOD_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> más}}</translation>
<translation id="1506687042165942984">Muestra una copia guardada (es decir, no actualizada) de esta página.</translation>
<translation id="1517433312004943670">Número de teléfono requerido</translation>
<translation id="1519264250979466059">Fecha de compilación</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript debe estar habilitado para utilizar esta función.</translation>
<translation id="1555130319947370107">Azul</translation>
<translation id="1559528461873125649">No existe el archivo o el directorio.</translation>
-<translation id="1559572115229829303">&lt;p&gt;No se puede establecer una conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu dispositivo (<ph name="DATE_AND_TIME" />) no son correctas.&lt;/p&gt;
-
- &lt;p&gt;Ajusta la fecha y la hora en la sección &lt;strong&gt;General&lt;/strong&gt; de la aplicación &lt;strong&gt;Ajustes&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Se ha producido un error al mostrar esta página web.</translation>
<translation id="1592005682883173041">Acceso a datos locales</translation>
+<translation id="1594030484168838125">Seleccionar</translation>
<translation id="161042844686301425">Cian</translation>
+<translation id="1620510694547887537">Cámara</translation>
<translation id="1629803312968146339">¿Quieres que Chrome guarde esta tarjeta?</translation>
<translation id="1639239467298939599">Cargando</translation>
<translation id="1640180200866533862">Políticas de usuario</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">La configuración de red no es válida y no se ha podido importar.</translation>
<translation id="1644574205037202324">Historial</translation>
<translation id="1645368109819982629">Protocolo no admitido</translation>
+<translation id="1655462015569774233">{1,plural, =1{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad caducó ayer. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. El reloj de tu ordenador está establecido actualmente en las <ph name="CURRENT_DATE" />. ¿Es correcto? Si no lo es, corrige el reloj del sistema y, a continuación, actualiza esta página.}other{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad caducó hace # días. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. El reloj de tu ordenador está establecido actualmente en las <ph name="CURRENT_DATE" />. ¿Es correcto? Si no lo es, corrige el reloj del sistema y, a continuación, actualiza esta página.}}</translation>
<translation id="1656489000284462475">Recogida</translation>
<translation id="1663943134801823270">Las tarjetas y las direcciones proceden de Chrome. Puedes gestionarlas en <ph name="BEGIN_LINK" />Configuración<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> utiliza normalmente el cifrado para proteger tu información. Cuando Google Chrome intentó establecer conexión con <ph name="SITE" />, el sitio web devolvió unas credenciales inusuales e incorrectas. Esto puede ocurrir si un atacante intenta suplantar la identidad de <ph name="SITE" /> o si una pantalla de inicio de sesión Wi-Fi interrumpe la conexión. Tu información sigue estando protegida, ya que Google Chrome detuvo la conexión antes de que se intercambiaran datos.</translation>
-<translation id="168328519870909584">Los atacantes que se encuentran actualmente en el sitio <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar instalar aplicaciones peligrosas en tu dispositivo para robar o eliminar tu información (como fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="168841957122794586">El certificado del servidor contiene una clave criptográfica no segura.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; supuestamente, su certificado de seguridad es válido a partir de mañana. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión.}other{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; supuestamente, su certificado de seguridad es válido dentro de # días. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión.}}</translation>
<translation id="1710259589646384581">Sistema operativo</translation>
<translation id="1721312023322545264">Necesitas permiso de <ph name="NAME" /> para acceder a este sitio web</translation>
<translation id="1721424275792716183">* El campo es obligatorio</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Descargar la página más tarde</translation>
<translation id="17513872634828108">Pestañas abiertas</translation>
<translation id="1753706481035618306">Número de página</translation>
+<translation id="1763864636252898013">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, el sistema operativo de tu dispositivo no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Prueba a ejecutar Diagnósticos de red de Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Actualiza tu frase de contraseña de sincronización.</translation>
<translation id="1787142507584202372">Las pestañas abiertas aparecen aquí</translation>
+<translation id="1789575671122666129">Ventanas emergentes</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nombre del titular de la tarjeta</translation>
-<translation id="1803678881841855883">La función de Navegación Segura de Google <ph name="BEGIN_LINK" />detectó software malicioso<ph name="END_LINK" /> recientemente en <ph name="SITE" />. En ocasiones, los sitios web que suelen ser seguros contienen software malicioso. Este contenido procede de <ph name="SUBRESOURCE_HOST" />, un conocido distribuidor de este tipo de software. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Añadida el <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Parámetros de solicitud o solicitud no válidos</translation>
<translation id="1826516787628120939">Comprobando</translation>
<translation id="1834321415901700177">Este sitio web contiene programas dañinos</translation>
+<translation id="1840414022444569775">Esta tarjeta de crédito ya está en uso</translation>
<translation id="1842969606798536927">Pagar</translation>
<translation id="1871208020102129563">Se ha configurado el proxy de forma que use servidores proxy fijos, en lugar de una URL de secuencia de comandos .pac.</translation>
<translation id="1871284979644508959">Campo obligatorio</translation>
<translation id="187918866476621466">Abrir páginas de inicio</translation>
<translation id="1883255238294161206">Contraer lista</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> más}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> más}}</translation>
<translation id="1898423065542865115">Filtrado</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ninguno}=1{1 sitio web}other{# sitios web}}</translation>
<translation id="194030505837763158">Ir a <ph name="LINK" /></translation>
<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error de serialización</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Se ha ignorado la política porque la anula <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Buscando páginas de la Web física cercanas</translation>
<translation id="213826338245044447">Marcadores del móvil</translation>
-<translation id="2148716181193084225">Hoy</translation>
+<translation id="2147827593068025794">Sincronización en segundo plano</translation>
<translation id="2154054054215849342">La sincronización no está disponible para tu dominio</translation>
<translation id="2154484045852737596">Editar tarjeta</translation>
<translation id="2166049586286450108">Acceso de administrador completo</translation>
<translation id="2166378884831602661">Este sitio web no puede proporcionar una conexión segura</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{Una dirección}other{# direcciones}}</translation>
+<translation id="2187317261103489799">Detectar (predeterminado)</translation>
<translation id="2202020181578195191">Introduce un año de vencimiento válido</translation>
<translation id="2212735316055980242">Política no encontrada</translation>
<translation id="2213606439339815911">Recuperando entradas...</translation>
+<translation id="2218879909401188352">Se ha detectado la presencia de atacantes en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> que podrían instalar aplicaciones peligrosas que dañen tu dispositivo, añadir cargos ocultos a tu factura del móvil o robar tu información personal. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Soluciona los problemas de tu conexión con la <ph name="BEGIN_LINK" />aplicación de diagnóstico<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Enviar ahora</translation>
<translation id="225207911366869382">Este valor ya no se utiliza para esta política.</translation>
<translation id="2262243747453050782">Error de HTTP</translation>
+<translation id="2270484714375784793">Número de teléfono</translation>
<translation id="2282872951544483773">Experimentos no disponibles</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> elemento}other{<ph name="ITEM_COUNT" /> elementos}}</translation>
<translation id="2292556288342944218">Tu acceso a Internet está bloqueado</translation>
<translation id="230155334948463882">¿Nueva tarjeta?</translation>
-<translation id="2305919008529760154">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad podría haberse emitido de forma fraudulenta. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> necesita un nombre de usuario y una contraseña.</translation>
-<translation id="2318774815570432836">No puedes acceder a <ph name="SITE" /> en este momento por que el sitio web utiliza HSTS. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Configuración controlada por el administrador</translation>
<translation id="2354001756790975382">Otros marcadores</translation>
+<translation id="2354430244986887761">La función Navegación Segura de Google <ph name="BEGIN_LINK" />encontró aplicaciones dañinas<ph name="END_LINK" /> recientemente en <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Es posible que los atacantes puedan ver las imágenes que ves en este sitio web y que las modifiquen para engañarte.</translation>
+<translation id="2356070529366658676">Preguntar</translation>
+<translation id="2359629602545592467">Varias</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2365563543831475020">No se ha subido el informe sobre fallos registrado el <ph name="CRASH_TIME" /></translation>
<translation id="2367567093518048410">Nivel</translation>
-<translation id="2371153335857947666">{1,plural, =1{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad caducó ayer. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. La fecha que consta en el reloj de tu ordenador actualmente es el <ph name="CURRENT_DATE" />. ¿Es correcto? Si no lo es, corrige el reloj del sistema y, a continuación, actualiza esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}other{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad caducó hace # días. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. La fecha que consta en el reloj de tu ordenador actualmente es el <ph name="CURRENT_DATE" />. ¿Es correcto? Si no lo es, corrige el reloj del sistema y, a continuación, actualiza esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">No hay alternativas de IU disponibles</translation>
<translation id="2384307209577226199">Empresa (con valores predeterminados)</translation>
<translation id="2386255080630008482">Se ha revocado el certificado de servidor.</translation>
<translation id="2392959068659972793">Mostrar políticas sin valores establecidos</translation>
<translation id="239429038616798445">Este método de envío no está disponible. Selecciona otro.</translation>
<translation id="2396249848217231973">&amp;Deshacer eliminación</translation>
-<translation id="2460160116472764928">La función de Navegación Segura de Google <ph name="BEGIN_LINK" />detectó software malicioso<ph name="END_LINK" /> recientemente en <ph name="SITE" />. En ocasiones, los sitios web que suelen ser seguros contienen software malicioso. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" /> y se podría rechazar su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="2463739503403862330">Rellenar</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Ejecutar Diagnósticos de red<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">La URL de búsqueda no es válida.</translation>
+<translation id="2482878487686419369">Notificaciones</translation>
<translation id="2491120439723279231">El certificado del servidor contiene errores.</translation>
<translation id="2495083838625180221">Analizador de archivos JSON</translation>
<translation id="2495093607237746763">Si se activa esta opción, Chromium guardará una copia de tu tarjeta en este dispositivo para completar formularios más rápidamente.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Volver</translation>
<translation id="2515629240566999685">Comprobar la señal en tu zona</translation>
<translation id="2516305470678292029">Alternativas de IU</translation>
+<translation id="2539524384386349900">Detectar</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ha enviado una respuesta no válida.</translation>
-<translation id="2552545117464357659">Más recientes</translation>
<translation id="2556876185419854533">&amp;Deshacer edición</translation>
<translation id="2587730715158995865">De <ph name="ARTICLE_PUBLISHER" />. Lee este y <ph name="OTHER_ARTICLE_COUNT" /> artículos más.</translation>
<translation id="2587841377698384444">ID de la API del directorio:</translation>
<translation id="2597378329261239068">Este documento está protegido por contraseña. Introduce una contraseña.</translation>
<translation id="2609632851001447353">Variaciones</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ninguna}=1{1 aplicación ($1)}=2{2 aplicaciones ($1 y $2)}other{# aplicaciones ($1, $2 y $3)}}</translation>
<translation id="2625385379895617796">Tu reloj está adelantado</translation>
<translation id="2639739919103226564">Estado:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Acceso al archivo denegado</translation>
<translation id="2653659639078652383">Enviar</translation>
<translation id="2666117266261740852">Cierra otras pestañas o aplicaciones</translation>
+<translation id="2670429602441959756">Esta página contiene funciones que aún no se admiten en RV. Saliendo...</translation>
<translation id="2674170444375937751">¿Seguro que quieres eliminar estas páginas del historial?</translation>
<translation id="2677748264148917807">Salir</translation>
-<translation id="269990154133806163">El servidor ha mostrado un certificado que no se ha hecho público mediante la política de transparencia en los certificados. Este requisito se aplica a algunos certificados para garantizar que son de confianza y ofrecer protección contra los atacantes. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Lista de lectura</translation>
<translation id="2704283930420550640">El valor no coincide con el formato.</translation>
<translation id="2704951214193499422">Chromium no ha podido confirmar tu tarjeta en este momento. Vuelve a intentarlo más tarde.</translation>
<translation id="2705137772291741111">La copia guardada (almacenada en caché) de este sitio web no se ha podido leer.</translation>
<translation id="2709516037105925701">Autocompletar</translation>
-<translation id="2712118517637785082">Has intentado acceder a <ph name="DOMAIN" />, pero el emisor ha revocado el certificado mostrado por el servidor, lo que significa que las credenciales de seguridad presentadas por el servidor no son de confianza. Es posible que hayas accedido a la página de un atacante. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Solicitar permiso</translation>
<translation id="2713444072780614174">Blanco</translation>
<translation id="2720342946869265578">Cercanas</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Falta un registro de dispositivo.</translation>
<translation id="2784949926578158345">Se ha restablecido la conexión.</translation>
<translation id="2794233252405721443">Sito web bloqueado</translation>
+<translation id="2799020568854403057">El sitio web al que vas a acceder contiene aplicaciones dañinas</translation>
+<translation id="2803306138276472711">Recientemente, la función de Navegación Segura de Google <ph name="BEGIN_LINK" />ha detectado software malicioso<ph name="END_LINK" /> en <ph name="SITE" />. En ocasiones, los sitios web que normalmente son seguros contienen software malicioso.</translation>
<translation id="2824775600643448204">Barra de direcciones y de búsqueda </translation>
<translation id="2826760142808435982">La conexión se ha encriptado y autenticado con <ph name="CIPHER" />, y utiliza <ph name="KX" /> como el mecanismo de intercambio clave.</translation>
<translation id="2835170189407361413">Eliminar formulario</translation>
+<translation id="2856444702002559011">Es posible que los atacantes estén intentando robar tu información de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (por ejemplo, contraseñas, mensajes o tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">No volver a cargar</translation>
<translation id="2900469785430194048">Google Chrome se ha quedado sin memoria al intentar mostrar esta página web.</translation>
<translation id="2909946352844186028">Se ha detectado un cambio de red.</translation>
<translation id="2916038427272391327">Cierra otros programas</translation>
<translation id="2922350208395188000">No es posible comprobar el certificado del servidor.</translation>
<translation id="2928905813689894207">Dirección de facturación</translation>
+<translation id="2941952326391522266">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, su certificado de seguridad procede de <ph name="DOMAIN2" />. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="2948083400971632585">Puedes inhabilitar los servidores proxy configurados para una conexión en la página de configuración.</translation>
<translation id="2955913368246107853">Cerrar la barra de búsqueda</translation>
<translation id="2958431318199492670">La configuración de red no cumple el estándar ONC. Es posible que no se importen partes de la configuración.</translation>
-<translation id="29611076221683977">Los atacantes que se encuentran actualmente en el sitio <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar instalar programas peligrosos en tu Mac para robar o eliminar tu información (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="2966678944701946121">Fecha de caducidad: <ph name="EXPIRATION_DATE_ABBR" /> (añadida el <ph name="ADDED_TO_AUTOFILL_MONTH" />)</translation>
<translation id="2969319727213777354">Para establecer una conexión segura, el reloj debe estar configurado correctamente. Esto se debe a que los certificados que utilizan los sitios web para identificarse solo son válidos para períodos de tiempo específicos. Como el reloj de tu dispositivo no está configurado correctamente, Google Chrome no puede verificar estos certificados.</translation>
<translation id="2972581237482394796">&amp;Rehacer</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Introduce una dirección válida</translation>
<translation id="2986368408720340940">Este método de recogida no está disponible. Selecciona otro.</translation>
<translation id="2991174974383378012">Compartir con otros sitios web</translation>
+<translation id="2991571918955627853">No puedes acceder a <ph name="SITE" /> en este momento porque el sitio web utiliza HSTS. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde.</translation>
<translation id="3005723025932146533">Mostrar copia guardada</translation>
<translation id="3008447029300691911">Introduce el código CVC de la tarjeta <ph name="CREDIT_CARD" />. Cuando la confirmes, su información se compartirá con este sitio web.</translation>
<translation id="3010559122411665027">Entrada de lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Bloqueado automáticamente</translation>
<translation id="3024663005179499861">Tipo de política incorrecto</translation>
<translation id="3032412215588512954">¿Quieres volver a cargar este sitio web?</translation>
<translation id="3037605927509011580">¡Oh, no!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{al menos un elemento en dispositivos sincronizados}=1{un elemento (y otros elementos más en dispositivos sincronizados)}other{# elementos (y otros elementos más en dispositivos sincronizados)}}</translation>
<translation id="3041612393474885105">Datos del certificado</translation>
<translation id="3063697135517575841">Chrome no ha podido confirmar tu tarjeta en este momento. Vuelve a intentarlo más tarde.</translation>
<translation id="3064966200440839136">Saldrás del modo incógnito para realizar un pago en una aplicación externa. ¿Quieres continuar?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ninguna}=1{1 contraseña}other{# contraseñas}}</translation>
<translation id="3093245981617870298">No tienes conexión.</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3109728660330352905">No tienes autorización para ver esta página.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Prueba a ejecutar Diagnóstico de conectividad<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Error al decodificar respuesta</translation>
<translation id="3150653042067488994">Error de servidor temporal</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Las páginas que aparezcan en las pestañas de incógnito no se guardarán en el historial del navegador, en el almacén de cookies ni en el historial de búsquedas una vez que hayas cerrado todas tus pestañas de incógnito. Se mantendrán los archivos que descargues o los marcadores que crees.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Isla</translation>
+<translation id="317583078218509884">La nueva configuración de permisos del sitio se aplicará una vez que la página se haya vuelto a cargar.</translation>
<translation id="3176929007561373547">Comprueba la configuración del proxy o ponte en contacto con el administrador de red para
asegurarte de que el servidor proxy funcione correctamente. Si consideras que no necesitas utilizar
un servidor proxy, sigue estas instrucciones:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Abre la página en modo incógnito</translation>
-<translation id="3202578601642193415">Los más recientes</translation>
+<translation id="320323717674993345">Cancelar pago</translation>
<translation id="3207960819495026254">Añadido a marcadores</translation>
+<translation id="3225919329040284222">El servidor ha mostrado un certificado que no coincide con lo que se esperaba. Algunos sitios web tienen un alto nivel de seguridad para garantizar tu protección y esperan ciertas características de los certificados.</translation>
<translation id="3226128629678568754">Pulsa el botón de actualización de página para que se vuelvan a enviar los datos necesarios para cargar la página.</translation>
+<translation id="3227137524299004712">Micrófono</translation>
<translation id="3228969707346345236">La traducción no ha podido realizarse correctamente porque la página ya está en <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Introduce el código CVC de la tarjeta <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Detectar siempre contenido importante en este sitio</translation>
<translation id="3254409185687681395">Añadir esta página a marcadores</translation>
<translation id="3270847123878663523">&amp;Deshacer reorganización</translation>
<translation id="3282497668470633863">Añadir un nombre de la tarjeta</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">configuración</translation>
<translation id="3345135638360864351">No se ha podido enviar la solicitud de acceso a este sitio a <ph name="NAME" />. Vuelve a intentarlo.</translation>
<translation id="3355823806454867987">Cambiar la configuración de proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />no guardará<ph name="END_EMPHASIS" /> la siguiente información:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Tu historial de navegación
+ <ph name="LIST_ITEM" />Las cookies y los datos de sitios web
+ <ph name="LIST_ITEM" />La información introducida en formularios
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Error del reloj</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> elementos más...</translation>
<translation id="337363190475750230">Desaprovisionado</translation>
<translation id="3377188786107721145">Error al analizar la política</translation>
<translation id="3380365263193509176">Error desconocido</translation>
<translation id="3380864720620200369">ID de cliente:</translation>
<translation id="3391030046425686457">Dirección de entrega</translation>
<translation id="3395827396354264108">Método de recogida</translation>
-<translation id="340013220407300675">Es posible que los piratas informáticos estén intentando robar tu información de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (por ejemplo, contraseñas, mensajes o tarjetas de crédito).</translation>
<translation id="3422248202833853650">Prueba a salir de otros programas para liberar memoria.</translation>
<translation id="3422472998109090673">No se puede acceder a la página <ph name="HOST_NAME" /> en este momento.</translation>
+<translation id="3427092606871434483">Permitir (predeterminado)</translation>
<translation id="3427342743765426898">&amp;Rehacer edición</translation>
<translation id="3431636764301398940">Guardar esta tarjeta en el dispositivo</translation>
<translation id="3435896845095436175">Habilitar</translation>
<translation id="3447661539832366887">El propietario de este dispositivo ha desactivado el juego del dinosaurio.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Intervalo de comprobación:</translation>
<translation id="3462200631372590220">Ocultar configuración avanzada</translation>
<translation id="3467763166455606212">El nombre del titular de la tarjeta es obligatorio</translation>
<translation id="3478058380795961209">Mes de caducidad</translation>
<translation id="3479539252931486093">¿No te lo esperabas? <ph name="BEGIN_LINK" />Notifícanoslo<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ahora no</translation>
-<translation id="348000606199325318">ID de bloqueo <ph name="CRASH_LOCAL_ID" /> (ID de servidor: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">No hemos podido contactar con tu padre/madre/tutor. Vuelve a intentarlo.</translation>
<translation id="3528171143076753409">El certificado de servidor no es de confianza.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Al menos 1 elemento en dispositivos sincronizados}=1{1 elemento (y otros en dispositivos sincronizados)}other{# elementos (y otros en dispositivos sincronizados)}}</translation>
<translation id="3539171420378717834">Guardar una copia de la tarjeta en este dispositivo</translation>
<translation id="3542684924769048008">Utilizar contraseña para:</translation>
+<translation id="3545341443414427877">No se puede establecer ninguna conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu ordenador (<ph name="DATE_AND_TIME" />) no son correctas. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Cifrar todos los datos sincronizados con tu propia frase de contraseña de sincronización</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> más...</translation>
-<translation id="3555561725129903880">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad procede de <ph name="DOMAIN2" />. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Tu administrador puede desbloquearlo</translation>
<translation id="3566021033012934673">La conexión no es privada</translation>
+<translation id="3569145463236695319">&lt;p&gt;No se puede establecer ninguna conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu dispositivo (<ph name="DATE_AND_TIME" />) no son correctas.&lt;/p&gt;
+
+ &lt;p&gt;Ajusta la fecha y la hora en la sección &lt;strong&gt;General&lt;/strong&gt; de la aplicación &lt;strong&gt;Ajustes&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Añade un nombre</translation>
<translation id="3583757800736429874">&amp;Rehacer movimiento</translation>
<translation id="3586931643579894722">Ocultar detalles</translation>
-<translation id="3587482841069643663">Todo</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Introduce una fecha de vencimiento válida</translation>
<translation id="36224234498066874">Borrar datos de navegación...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Datos del certificado</translation>
<translation id="3690164694835360974">Inicio de sesión no seguro</translation>
<translation id="3693415264595406141">Contraseña:</translation>
-<translation id="3696411085566228381">ninguno</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Cargando...</translation>
<translation id="3712624925041724820">Licencias agotadas</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Comprobar el proxy, el cortafuegos y la configuración de DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Si entiendes los riesgos para tu seguridad, puedes <ph name="BEGIN_LINK" />acceder a este sitio no seguro<ph name="END_LINK" /> antes de que se hayan eliminado los programas peligrosos.</translation>
<translation id="3739623965217189342">Enlace copiado</translation>
+<translation id="3744899669254331632">No puedes acceder a <ph name="SITE" /> en este momento porque el sitio web ha enviado credenciales codificadas que Chromium no puede procesar. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde.</translation>
+<translation id="3748148204939282805">Es posible que los atacantes que se encuentren en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten engañarte para que realices una acción peligrosa, como instalar software o revelar tu información personal (por ejemplo, contraseñas, números de teléfono o tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Se ha producido un error de traducción debido a un problema con el servidor.</translation>
<translation id="3759461132968374835">No se ha notificado ningún fallo recientemente. Los fallos que se hayan producido cuando la función de notificación de fallos estaba inhabilitada no aparecerán en esta página.</translation>
+<translation id="3778403066972421603">¿Quieres guardar esta tarjeta en tu cuenta de Google y en este dispositivo?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Vencimiento: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Si utilizas un servidor proxy...</translation>
<translation id="3828924085048779000">La frase de contraseña no puede estar vacía.</translation>
-<translation id="3845539888601087042">Mostrando historial de dispositivos en los que has iniciado sesión. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Atrás</translation>
<translation id="3858027520442213535">Actualizar fecha y hora</translation>
<translation id="3884278016824448484">Identificador de dispositivo en conflicto</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Tu solicitud de acceso a este sitio web se ha enviado a <ph name="NAME" /></translation>
<translation id="3890664840433101773">Añadir correo electrónico</translation>
<translation id="3901925938762663762">La tarjeta ha caducado</translation>
-<translation id="3933571093587347751">{1,plural, =1{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; supuestamente, su certificado de seguridad es válido a partir de mañana. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}other{Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; supuestamente, su certificado de seguridad es válido dentro de # días. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">Se ha producido un error al cargar el documento PDF.</translation>
+<translation id="3945915738023014686">ID del informe sobre fallos subido: <ph name="CRASH_ID" /> (ID del fallo local: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad no especifica nombres alternativos del sujeto. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión.</translation>
<translation id="3963721102035795474">Modo de lectura</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ninguno}=1{De 1 sitio web }other{De # sitios web }}</translation>
<translation id="397105322502079400">Calculando...</translation>
<translation id="3973234410852337861">La página <ph name="HOST_NAME" /> está bloqueada</translation>
+<translation id="3987940399970879459">Menos de 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ 1 página web cercana}other{ # páginas web cercanas}}</translation>
<translation id="4021036232240155012">DNS es el servicio de red que permite traducir el nombre de un sitio web a su dirección de Internet.</translation>
<translation id="4030383055268325496">&amp;Deshacer acción de añadir</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Se ha configurado el proxy para que use una URL de secuencia de comandos .pac, en lugar de servidores proxy fijos.</translation>
<translation id="4098354747657067197">El sitio web al que vas a acceder es engañoso</translation>
<translation id="4103249731201008433">El número de serie del dispositivo no es válido.</translation>
+<translation id="410351446219883937">Reproducción automática</translation>
<translation id="4103763322291513355">Accede a la página &lt;strong&gt;chrome://policy&lt;/strong&gt; para ver la lista de URLs no admitidas y otras políticas establecidas por el administrador del sistema.</translation>
-<translation id="4110615724604346410">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad contiene errores. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Permitir siempre en este sitio</translation>
<translation id="4117700440116928470">No se admite el alcance de la política.</translation>
-<translation id="4118212371799607889">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; Chromium no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{Uno más}other{# más}}</translation>
<translation id="4130226655945681476">Comprobar los cables de red, el módem y el router</translation>
+<translation id="413544239732274901">Más información</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Utilizar valor predeterminado global (por defecto)</translation>
+<translation id="4165986682804962316">Configuración de sitios web</translation>
<translation id="4169947484918424451">¿Quieres que Chromium guarde esta tarjeta?</translation>
<translation id="4171400957073367226">La firma de verificación no es válida</translation>
<translation id="4196861286325780578">&amp;Rehacer movimiento</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Comprobar la configuración del cortafuegos y del antivirus<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ninguna}=1{Una aplicación ($1)}=2{Dos aplicaciones ($1, $2)}other{# aplicaciones ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">La página no responde o se cierra</translation>
+<translation id="422022731706691852">Es posible que los atacantes que se encuentren en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten engañarte para que instales programas que empeoren tu experiencia de navegación (por ejemplo, que cambien tu página principal o muestren anuncios adicionales en los sitios web a los que accedas). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Prueba a ejecutar Diagnósticos de red<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Válido</translation>
<translation id="4250431568374086873">Tu conexión con este sitio web no es completamente segura</translation>
<translation id="4250680216510889253">No</translation>
<translation id="425582637250725228">Es posible que los cambios no se guarden.</translation>
<translation id="4258748452823770588">Firma errónea</translation>
+<translation id="4265872034478892965">Permitido por el administrador</translation>
<translation id="4269787794583293679">(Ningún nombre de usuario)</translation>
<translation id="4275830172053184480">Reiniciar tu dispositivo</translation>
<translation id="4280429058323657511">Vcto. <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">La función de Navegación Segura de Google <ph name="BEGIN_LINK" />encontró programas dañinos<ph name="END_LINK" /> recientemente en <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">Sugerencias de padres</translation>
<translation id="4304224509867189079">Iniciar sesión</translation>
-<translation id="432290197980158659">El servidor ha mostrado un certificado que no coincide con lo que se esperaba. Algunos sitios web tienen un alto nivel de seguridad para garantizar tu protección y esperan ciertas características de los certificados. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Bloquear (predeterminado)</translation>
<translation id="4325863107915753736">Error al buscar el artículo</translation>
<translation id="4326324639298822553">Consulta la fecha de vencimiento y vuelve a intentarlo</translation>
<translation id="4331708818696583467">No es seguro</translation>
<translation id="4356973930735388585">Es posible que los atacantes que se encuentren en este sitio web intenten instalar programas peligrosos en tu ordenador para robar o eliminar tu información (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="4372948949327679948">Se esperaba un valor <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Has intentado acceder a <ph name="DOMAIN" />, pero el emisor ha revocado el certificado mostrado por el servidor, lo que significa que las credenciales de seguridad presentadas por el servidor no son de confianza. Es posible que hayas accedido a la página de un atacante.</translation>
<translation id="4381091992796011497">Nombre de usuario:</translation>
<translation id="4394049700291259645">Inhabilitar</translation>
<translation id="4406896451731180161">resultados de la búsqueda</translation>
+<translation id="4424024547088906515">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, Chrome no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> no ha aceptado el certificado de inicio de sesión o es posible que no se haya proporcionado ninguno.</translation>
<translation id="443673843213245140">Se ha inhabilitado el uso de un servidor proxy, pero se han especificado ajustes de proxy explícitos.</translation>
-<translation id="4492190037599258964">Resultados de búsqueda de "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Error de validación: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Ponerte en contacto con el administrador del sistema</translation>
<translation id="450710068430902550">Compartir con el administrador</translation>
<translation id="4515275063822566619">Las tarjetas y las direcciones proceden de Chrome y tu cuenta de Google (<ph name="ACCOUNT_EMAIL" />). Puedes gestionarlas en <ph name="BEGIN_LINK" />Configuración<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detalles</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Inhabilita las extensiones.</translation>
<translation id="457875822857220463">Envío</translation>
<translation id="4587425331216688090">¿Eliminar dirección de Chrome?</translation>
-<translation id="4589078953350245614">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado no válido. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Tu conexión con <ph name="DOMAIN" /> está cifrada con un conjunto de cifrado moderno.</translation>
<translation id="4594403342090139922">&amp;Deshacer eliminación</translation>
<translation id="4619615317237390068">Pestañas de otros dispositivos</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, su certificado de seguridad contiene errores. El problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
+<translation id="4690462567478992370">Dejar de utilizar un certificado no válido</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Se ha interrumpido la conexión</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Ejecutar Diagnósticos de red de Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Se ha producido un error desconocido.</translation>
<translation id="4800132727771399293">Comprueba la fecha de caducidad y el código CVC, y vuelve a intentarlo</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">No puedes acceder a <ph name="SITE" /> en este momento porque el sitio web ha enviado credenciales codificadas que Google Chrome no puede procesar. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde.</translation>
<translation id="4813512666221746211">Error de red</translation>
<translation id="4816492930507672669">Ajustar a página</translation>
<translation id="483020001682031208">No hay páginas de la Web física para mostrarse.</translation>
<translation id="4850886885716139402">Ver</translation>
<translation id="4854362297993841467">Este método de entrega no está disponible. Selecciona otro.</translation>
<translation id="4858792381671956233">Has solicitado permiso a tus padres para poder acceder a este sitio web</translation>
+<translation id="4863764087567530506">Es posible que este contenido intente engañarte para que instales software o reveles información personal. <ph name="BEGIN_LINK" />Mostrar de todos modos<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Buscar en el historial</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> y <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ y 1 página web más}other{ y # páginas web más}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Esta página se ha traducido de un idioma desconocido al <ph name="LANGUAGE_LANGUAGE" />.</translation>
<translation id="4923459931733593730">Pago</translation>
<translation id="4926049483395192435">Se debe especificar un valor.</translation>
<translation id="495170559598752135">Acciones</translation>
<translation id="4958444002117714549">Expandir lista</translation>
-<translation id="4962322354953122629">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; Chrome no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Volver a habilitar advertencias</translation>
<translation id="4989809363548539747">Este complemento no es compatible</translation>
<translation id="5002932099480077015">Si se habilita esta opción, Chrome guardará una copia de tu tarjeta en este dispositivo para rellenar la información más rápido.</translation>
<translation id="5018422839182700155">No se puede abrir esta página</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Consulta las políticas del administrador</translation>
<translation id="5029568752722684782">Borrar copia</translation>
<translation id="5031870354684148875">Informacion del Traductor de Google</translation>
+<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidad</translation>
<translation id="5045550434625856497">Contraseña incorrecta</translation>
<translation id="5056549851600133418">Artículos recomendados para ti</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Comprobar la dirección del proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{No hay cookies}=1{1 sitio web usa cookies. }other{# sitios web usan cookies. }}</translation>
<translation id="5087286274860437796">El certificado del servidor no es válido en este momento.</translation>
<translation id="5087580092889165836">Añadir tarjeta</translation>
<translation id="5089810972385038852">Estado</translation>
+<translation id="5094747076828555589">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, Chromium no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="5095208057601539847">Provincia</translation>
<translation id="5115563688576182185">(64 bits)</translation>
<translation id="5141240743006678641">Cifrar contraseñas sincronizadas con tus credenciales de Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Correo electrónico obligatorio</translation>
<translation id="5251803541071282808">Nube</translation>
<translation id="5277279256032773186">¿Usas Chrome en el trabajo? Las empresas pueden administrar la configuración de Chrome de sus empleados. Más información</translation>
+<translation id="5297526204711817721">Tu conexión a este sitio web no es privada. Para salir del modo RV en cualquier momento, quita el visor y pulsa Atrás.</translation>
<translation id="5299298092464848405">Error al analizar la política</translation>
-<translation id="5300589172476337783">Mostrar</translation>
<translation id="5308689395849655368">Notificación de fallos inhabilitada</translation>
<translation id="5317780077021120954">Guardar</translation>
<translation id="5327248766486351172">Nombre</translation>
-<translation id="5337705430875057403">Los atacantes del <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían engañarte para que hagas algo peligroso, como instalar software o revelar tu información personal (por ejemplo, contraseñas, números de teléfono o datos de tarjetas de crédito).</translation>
-<translation id="5359637492792381994">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; su certificado de seguridad no es válido en este momento. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">No puedes acceder a <ph name="SITE" /> en este momento porque su certificado se ha revocado. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde.</translation>
<translation id="536296301121032821">Error al almacenar la configuración de la política</translation>
<translation id="5386426401304769735">La cadena de certificados de este sitio web contiene un certificado firmado con SHA-1.</translation>
<translation id="5402410679244714488">Fecha de caducidad: <ph name="EXPIRATION_DATE_ABBR" /> (usada por última vez hace más de un año)</translation>
+<translation id="540969355065856584">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, ya que su certificado de seguridad no es válido en este momento. Esto puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
<translation id="5421136146218899937">Borrar datos de navegación...</translation>
<translation id="5430298929874300616">Eliminar marcador</translation>
<translation id="5431657950005405462">No se ha encontrado tu archivo</translation>
-<translation id="5435775191620395718">Mostrando historial de este dispositivo. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Error de validación de esquema en "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">No se puede encontrar esta página (<ph name="HOST_NAME" />)</translation>
<translation id="5455374756549232013">Marca de tiempo de política incorrecta</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> de <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">No válido</translation>
<translation id="5470861586879999274">&amp;Rehacer edición</translation>
<translation id="54817484435770891">Añadir dirección válida</translation>
<translation id="5492298309214877701">Este sitio web de la intranet del centro educativo, de la organización o de la empresa tiene la misma URL que un sitio web externo.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Los pedidos no se pueden recoger en esta dirección. Selecciona otra.</translation>
<translation id="5572851009514199876">Abre Chrome e inicia sesión en el navegador para que compruebe si tienes permiso para acceder a este sitio web.</translation>
<translation id="5580958916614886209">Consulta el mes de vencimiento y vuelve a intentarlo</translation>
+<translation id="5586446728396275693">Ninguna dirección guardada</translation>
+<translation id="5595485650161345191">Editar dirección</translation>
<translation id="560412284261940334">Administración no admitida</translation>
<translation id="5610142619324316209">Comprobar la conexión</translation>
<translation id="5610807607761827392">Puedes gestionar las tarjetas y las direcciones en <ph name="BEGIN_LINK" />Configuración<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">¿Quieres salir de este sitio web?</translation>
<translation id="5629630648637658800">Error al cargar la configuración de la política</translation>
<translation id="5631439013527180824">Token de administración de dispositivos no válido</translation>
+<translation id="5633066919399395251">Es posible que los atacantes que se encuentren en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten instalar programas peligrosos en tu ordenador para robar o eliminar tu información (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Ubicación</translation>
+<translation id="5659593005791499971">Correo electrónico</translation>
<translation id="5669703222995421982">Obtener contenido personalizado</translation>
<translation id="5675650730144413517">Esta página no funciona</translation>
-<translation id="5677928146339483299">Con bloqueo</translation>
-<translation id="5694783966845939798">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado firmado con un algoritmo de firma no seguro (por ejemplo, SHA-1). Una posible causa de este problema es que se hayan falsificado las credenciales de seguridad presentadas por el servidor y que hayas accedido a la página de un atacante en lugar de establecer conexión con el servidor en cuestión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">No se ha verificado la identidad de este sitio web.</translation>
+<translation id="5713016350996637505">Contenido engañoso bloqueado</translation>
<translation id="5720705177508910913">Usuario actual</translation>
<translation id="5732392974455271431">Tus padres pueden desbloquearlo</translation>
<translation id="5763042198335101085">Introduce una dirección de correo electrónico válida</translation>
<translation id="5765072501007116331">Selecciona una dirección para ver los métodos de entrega y los requisitos</translation>
+<translation id="5778550464785688721">Control total de dispositivos MIDI</translation>
<translation id="5784606427469807560">Se ha producido un problema al confirmar tu tarjeta. Comprueba tu conexión a Internet y vuelve a intentarlo.</translation>
<translation id="5785756445106461925">Además, esta página incluye otros recursos que no son seguros. Otros usuarios pueden acceder a estos recursos mientras están en circulación y un atacante puede modificarlos para cambiar el aspecto de la página.</translation>
<translation id="5786044859038896871">¿Quieres rellenar la información de la tarjeta?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Rehacer acción de añadir</translation>
<translation id="5814352347845180253">Es posible que dejes de tener acceso al contenido premium de <ph name="SITE" /> y algunos otros sitios web.</translation>
<translation id="5838278095973806738">No deberías introducir información confidencial en este sitio web (por ejemplo, contraseñas o tarjetas de crédito) porque los atacantes podrían robarla.</translation>
-<translation id="5843436854350372569">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado que contiene una clave no segura. Es posible que alguien haya descifrado la clave privada y que hayas accedido a la página de esa persona en lugar de establecer conexión con el servidor. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">No se puede acceder a este sitio web</translation>
<translation id="5869522115854928033">Contraseñas guardadas</translation>
<translation id="5872918882028971132">Sugerencias de padres</translation>
<translation id="5901630391730855834">Amarillo</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sincronizado)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 en uso}other{# en uso}}</translation>
<translation id="5926846154125914413">Es posible que dejes de tener acceso al contenido premium de algunos sitios web.</translation>
<translation id="5959728338436674663">Enviar automáticamente <ph name="BEGIN_WHITEPAPER_LINK" />información del sistema y contenido de las páginas<ph name="END_WHITEPAPER_LINK" /> a Google para facilitar la detección de aplicaciones y sitios web peligrosos. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Semana</translation>
<translation id="5967867314010545767">Eliminar del historial</translation>
<translation id="5975083100439434680">Reducir</translation>
<translation id="598637245381783098">No se ha podido abrir la aplicación de pago</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Página 1}other{Página #}}</translation>
<translation id="6017514345406065928">Verde</translation>
+<translation id="6017850046339264347">Se ha detectado la presencia de atacantes en el sitio web <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. Estos podrían instalar aplicaciones engañosas que se hagan pasar por otra persona o recojan datos que podrían usarse para realizar un seguimiento de tu actividad. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sincronizados)</translation>
<translation id="6027201098523975773">Introduce un nombre</translation>
<translation id="6040143037577758943">Cerrar</translation>
<translation id="6042308850641462728">Más</translation>
+<translation id="6047233362582046994">Si entiendes los riesgos para tu seguridad, puedes <ph name="BEGIN_LINK" />acceder a este sitio web<ph name="END_LINK" /> antes de que se hayan eliminado las aplicaciones dañinas.</translation>
+<translation id="6051221802930200923">No puedes acceder a <ph name="SITE" /> en este momento porque el sitio web utiliza la fijación de certificados. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde.</translation>
<translation id="6060685159320643512">¡Atención! Estos experimentos pueden ser peligrosos</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ninguna}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Has accedido al contenido mediante un certificado proporcionado por el administrador. Los datos que proporciones a <ph name="DOMAIN" /> pueden ser interceptados por tu administrador.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ninguna}=1{1 contraseña (sincronizada)}other{# contraseñas (sincronizadas)}}</translation>
<translation id="6146055958333702838">Comprueba los cables y reinicia los routers, los módems o cualquier otro dispositivo
de red que estés utilizando.</translation>
<translation id="614940544461990577">Prueba a:</translation>
<translation id="6151417162996330722">El certificado del servidor tiene un periodo de validez demasiado largo.</translation>
<translation id="6157877588268064908">Selecciona una dirección para ver los métodos de envío y los requisitos</translation>
+<translation id="6158003235852588289">La función Navegación Segura de Google ha detectado phishing recientemente en <ph name="SITE" />. Los sitios web de phishing imitan el aspecto de otros sitios web para engañarte.</translation>
<translation id="6165508094623778733">Más información</translation>
+<translation id="6169916984152623906">Ahora puedes navegar de forma privada; las otras personas que usen este dispositivo no verán tu actividad. No obstante, se guardarán las descargas y los marcadores.</translation>
<translation id="6177128806592000436">Tu conexión con este sitio web no es segura</translation>
<translation id="6184817833369986695">(cohorte: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Comprueba tu conexión a Internet</translation>
<translation id="6218753634732582820">¿Quitar dirección de Chromium?</translation>
+<translation id="6221345481584921695">Recientemente, la función de Navegación Segura de Google <ph name="BEGIN_LINK" />ha detectado software malicioso<ph name="END_LINK" /> en <ph name="SITE" />. En ocasiones, los sitios web que normalmente son seguros contienen software malicioso. Este contenido malintencionado procede de <ph name="SUBRESOURCE_HOST" />, un conocido distribuidor de software malicioso.</translation>
<translation id="6251924700383757765">Política de Privacidad</translation>
<translation id="6254436959401408446">No hay suficiente memoria para abrir esta página</translation>
<translation id="625755898061068298">Has elegido inhabilitar las advertencias de seguridad de este sitio web.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Editar marcador</translation>
<translation id="6410264514553301377">Introduce la fecha de vencimiento y el código CVC de la tarjeta <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Has solicitado permiso a uno de tus padres para poder acceder a este sitio web</translation>
-<translation id="6416403317709441254">No puedes acceder a <ph name="SITE" /> en este momento porque el sitio web ha enviado credenciales codificadas que Chromium no puede procesar. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">No se ha podido comprobar si se ha revocado el certificado.</translation>
<translation id="6433490469411711332">Editar información de contacto</translation>
<translation id="6433595998831338502">La página <ph name="HOST_NAME" /> ha rechazado la conexión.</translation>
<translation id="6446608382365791566">Añadir más información</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmar reenvío del formulario</translation>
<translation id="6456339708790392414">Tu pago</translation>
<translation id="6458467102616083041">Se ha ignorado el valor porque se ha establecido una política que inhabilita la búsqueda predeterminada.</translation>
-<translation id="6462969404041126431">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; es posible que su certificado de seguridad se revoque. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Políticas de dispositivos</translation>
<translation id="6477321094435799029">Chrome ha detectado un código inusual en esta página y lo ha bloqueado para proteger tu información personal (por ejemplo, contraseñas, números de teléfono y tarjetas de crédito).</translation>
<translation id="6489534406876378309">Empezar a subir errores</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Fecha de caducidad: <ph name="EXPIRATION_DATE_ABBR" /> (usada por última vez el <ph name="LAST_USED_DATE_NO_DETAIL" />)</translation>
<translation id="6563469144985748109">Tu administrador aún no la ha aprobado</translation>
<translation id="6569060085658103619">Estas viendo la página de una extensión</translation>
-<translation id="6593753688552673085">menos de <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Es posible que este contenido intente instalar software peligroso que robe o elimine tu información en el dispositivo. <ph name="BEGIN_LINK" />Mostrar de todos modos<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opciones de cifrado</translation>
<translation id="662080504995468778">Seguir aquí</translation>
<translation id="6626291197371920147">Añadir un número de tarjeta válido</translation>
<translation id="6628463337424475685">Búsqueda de <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Es posible que los atacantes que se encuentren en <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> intenten instalar programas peligrosos en tu Mac para robar o eliminar tu información (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Esta política está obsoleta.</translation>
-<translation id="6652240803263749613">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; el sistema operativo de tu ordenador no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">¿Quitar sugerencia de formulario de Chromium?</translation>
<translation id="6685834062052613830">Cierra sesión y completa la configuración</translation>
<translation id="6710213216561001401">Anterior</translation>
<translation id="6710594484020273272">&lt;Introducir término de búsqueda&gt;</translation>
<translation id="6711464428925977395">Se ha producido un error con el servidor proxy o la dirección es incorrecta.</translation>
<translation id="6727102863431372879">Establecer</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ninguno}=1{Un elemento}other{# elementos}}</translation>
<translation id="674375294223700098">Error de certificado de servidor desconocido</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6757797048963528358">El dispositivo se ha suspendido.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ID de personalización</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">No se han podido cargar los datos de las regiones</translation>
+<translation id="6825578344716086703">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado firmado con un algoritmo de firma no seguro (por ejemplo, SHA-1). Una posible causa de este problema es que se hayan falsificado las credenciales de seguridad presentadas por el servidor y que hayas accedido a la página de un atacante en lugar de establecer conexión con el servidor en cuestión.</translation>
+<translation id="6830728435402077660">No es seguro</translation>
<translation id="6831043979455480757">Traducir</translation>
<translation id="6839929833149231406">Ãrea</translation>
<translation id="6874604403660855544">&amp;Rehacer acción de añadir</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Tu tarjeta se ha confirmado</translation>
<translation id="6897140037006041989">Agente de usuario</translation>
<translation id="6915804003454593391">Usuario:</translation>
+<translation id="6945221475159498467">Seleccionar</translation>
<translation id="6948701128805548767">Selecciona una dirección para ver los métodos de recogida y los requisitos</translation>
<translation id="6957887021205513506">El certificado del servidor parece ser falso.</translation>
<translation id="6965382102122355670">Aceptar</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Se especifican tanto servidores proxy fijos como una URL de secuencia de comandos .pac.</translation>
<translation id="6989763994942163495">Mostrar configuración avanzada...</translation>
<translation id="7000990526846637657">No se han encontrado entradas del historial</translation>
-<translation id="7009986207543992532">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado cuyo periodo de validez es demasiado largo para que se considere de confianza. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Es posible que en tu cuenta de Google haya otros datos de navegación registrados, que puedes consultar en la página <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Contraseñas</translation>
+<translation id="7050187094878475250">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado cuyo periodo de validez es demasiado largo para que se considere de confianza.</translation>
+<translation id="7053983685419859001">Bloquear</translation>
<translation id="7064851114919012435">Información de contacto</translation>
<translation id="7079718277001814089">Este sitio web contiene software malicioso</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7088615885725309056">Más antiguos</translation>
<translation id="7090678807593890770">Busca <ph name="LINK" /> en Google</translation>
+<translation id="7108819624672055576">Permitido por una extensión</translation>
<translation id="7119414471315195487">Cierra otros programas o pestañas</translation>
<translation id="7129409597930077180">Los pedidos no se pueden enviar a esta dirección. Selecciona otra.</translation>
<translation id="7138472120740807366">Método de entrega</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Procesando pago</translation>
<translation id="724691107663265825">El sitio al que vas a acceder contiene software malicioso</translation>
<translation id="724975217298816891">Introduce la fecha de caducidad y el código CVC de la tarjeta <ph name="CREDIT_CARD" /> para actualizar sus detalles. Cuando la confirmes, su información se compartirá con este sitio web.</translation>
-<translation id="725866823122871198">No se puede establecer una conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu ordenador (<ph name="DATE_AND_TIME" />) no son correctas.</translation>
+<translation id="7260504762447901703">Revoca el acceso</translation>
<translation id="7275334191706090484">Marcadores administrados</translation>
<translation id="7298195798382681320">Recomendadas</translation>
<translation id="7309308571273880165">Informe sobre fallos registrado el <ph name="CRASH_TIME" /> (el usuario ha solicitado que se suba, pero aún no se ha hecho)</translation>
<translation id="7334320624316649418">&amp;Rehacer reorganización</translation>
<translation id="733923710415886693">El certificado del servidor no se ha revelado a través de la Transparencia en los Certificados.</translation>
-<translation id="7351800657706554155">No puedes acceder a <ph name="SITE" /> en este momento porque su certificado se ha revocado. Los ataques y los errores de red suelen ser temporales, por lo que es probable que esta página funcione más tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">Línea de comandos</translation>
<translation id="7372973238305370288">resultado de búsqueda</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">No</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Confirmar tarjeta</translation>
-<translation id="7394102162464064926">¿Seguro que quieres eliminar estas páginas de tu historial?
-
-¡Pst! El modo de incógnito <ph name="SHORTCUT_KEY" /> puede serte de utilidad la próxima vez.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Ruta del perfil</translation>
<translation id="7424977062513257142">Una página insertada en este sitio web dice:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">Este sitio web se ha bloqueado</translation>
<translation id="7445762425076701745">La identidad del servidor al que estás conectado no se puede validar por completo. Estás conectado a un servidor con un nombre que solo es válido en tu red y cuya propiedad no puede validar en modo alguno una entidad emisora de certificados externa. A pesar de ello, algunas entidades emisoras emiten certificados para esos nombres, por lo que no es posible garantizar que estés conectado al sitio web deseado, en lugar de a un atacante.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Consultar más información<ph name="END_LINK" /> sobre este problema</translation>
+<translation id="7455133967321480974">Utilizar valor predeterminado global (Bloquear)</translation>
<translation id="7460163899615895653">Las pestañas recientes de otros dispositivos aparecen aquí</translation>
<translation id="7469372306589899959">Confirmando tarjeta</translation>
<translation id="7481312909269577407">Adelante</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">El ID de dispositivo de política devuelto está vacío o no coincide con el ID de dispositivo actual</translation>
<translation id="7514365320538308">Descargar</translation>
<translation id="7518003948725431193">No se ha encontrado ninguna página web para la dirección <ph name="URL" />.</translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obligatoria</translation>
+<translation id="7542403920425041731">Cuando la confirmes, la información de la tarjeta se compartirá con este sitio web.</translation>
<translation id="7542995811387359312">La opción de autocompletado de la tarjeta de crédito está inhabilitada porque este formulario no utiliza una conexión segura.</translation>
<translation id="7543525346216957623">Pide permiso a uno de tus padres</translation>
<translation id="7549584377607005141">Esta página web necesita los datos introducidos anteriormente para mostrarse correctamente. Puedes volver a enviar los datos, pero se repetirán las acciones que haya realizado la página.</translation>
<translation id="7552846755917812628">Prueba los siguientes consejos:</translation>
<translation id="7554791636758816595">Nueva pestaña</translation>
+<translation id="7567204685887185387">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, su certificado de seguridad podría haberse emitido de forma fraudulenta. El problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> más}other{<ph name="CONTACT_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> más}}</translation>
<translation id="7568593326407688803">Esta página está escrita en<ph name="ORIGINAL_LANGUAGE" />¿Quieres traducirla?</translation>
<translation id="7569952961197462199">¿Eliminar tarjeta de crédito de Chrome?</translation>
<translation id="7569983096843329377">Negro</translation>
<translation id="7578104083680115302">Paga rápidamente en aplicaciones y sitios web desde tus dispositivos utilizando las tarjetas que has guardado en Google.</translation>
<translation id="7588950540487816470">Web física</translation>
<translation id="7592362899630581445">El certificado del servidor incluye un nombre que está fuera de su cobertura.</translation>
+<translation id="7598391785903975535">Menos de <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">La página <ph name="HOST_NAME" /> no puede procesar esta solicitud ahora.</translation>
<translation id="7600965453749440009">No traducir nunca del <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">El valor <ph name="VALUE" /> se encuentra fuera del intervalo.</translation>
<translation id="7613889955535752492">Caducidad: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Has usado anteriormente otra versión de la contraseña de tu cuenta de Google para el cifrado de datos. Introdúcela a continuación.</translation>
-<translation id="7634554953375732414">Tu conexión con este sitio no es privada.</translation>
<translation id="7637571805876720304">¿Quitar tarjeta de crédito de Chromium?</translation>
<translation id="765676359832457558">Ocultar configuración avanzada...</translation>
<translation id="7658239707568436148">Cancelar</translation>
+<translation id="7662298039739062396">Opción controlada por una extensión</translation>
<translation id="7667346355482952095">El token de política devuelto está vacío o no coincide con el token actual</translation>
<translation id="7668654391829183341">Dispositivo desconocido</translation>
<translation id="7669271284792375604">Es posible que los atacantes que se encuentren en este sitio web intenten engañarte para que instales programas que empeoren tu experiencia de navegación (por ejemplo, que cambien tu página principal o muestren anuncios adicionales en los sitios web a los que accedas).</translation>
<translation id="7674629440242451245">Si estás interesado en probar nuevas e interesantes funciones de Chrome, prueba el canal para desarrolladores en la página chrome.com/dev.</translation>
<translation id="7682287625158474539">Dirección de envío</translation>
+<translation id="7701040980221191251">Ninguno</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Acceder a <ph name="SITE" /> (sitio no seguro)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificado</translation>
+<translation id="7716147886133743102">Bloqueado por el administrador</translation>
<translation id="7716424297397655342">No se puede cargar este sitio web desde la caché</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">No administrado</translation>
<translation id="7755287808199759310">Uno de tus padres puede desbloquearlo</translation>
<translation id="7758069387465995638">Puede que el cortafuegos o el software antivirus hayan bloqueado la conexión.</translation>
@@ -751,30 +825,31 @@
<translation id="7951415247503192394">(32 bits)</translation>
<translation id="7956713633345437162">Marcadores del móvil</translation>
<translation id="7961015016161918242">Nunca</translation>
-<translation id="7962083544045318153">ID de bloqueo <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Traducir siempre del <ph name="ORIGINAL_LANGUAGE" /> al <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Sin especificar</translation>
<translation id="800218591365569300">Prueba a cerrar otros programas o pestañas para liberar memoria.</translation>
<translation id="8012647001091218357">No hemos podido contactar con tus padres. Vuelve a intentarlo.</translation>
<translation id="8025119109950072390">Es posible que los atacantes que se encuentren en este sitio web intenten engañarte para que realices una acción peligrosa, como instalar software o revelar tu información personal (por ejemplo, contraseñas, números de teléfono o tarjetas de crédito).</translation>
-<translation id="803030522067524905">La función de Navegación Segura de Google detectó phishing recientemente en <ph name="SITE" />. Los sitios web de phishing imitan el aspecto de otros sitios web para engañarte. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Esta página está escrita en <ph name="SOURCE_LANGUAGE" />. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Preguntar (predeterminado)</translation>
<translation id="8041089156583427627">Enviar</translation>
+<translation id="8041940743680923270">Utilizar valor predeterminado global (Preguntar)</translation>
<translation id="8088680233425245692">Se ha producido un error al ver el artículo.</translation>
<translation id="8089520772729574115">menos de 1 MB</translation>
<translation id="8091372947890762290">La activación está pendiente en el servidor.</translation>
-<translation id="8118489163946903409">Forma de pago</translation>
+<translation id="8118489163946903409">Método de pago</translation>
<translation id="8131740175452115882">Confirmar</translation>
<translation id="8134994873729925007">No se ha podido encontrar la <ph name="BEGIN_ABBR" />dirección DNS<ph name="END_ABBR" /> del servidor de <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">El ordenador se ha suspendido.</translation>
<translation id="8150722005171944719">El archivo que se encuentra en <ph name="URL" /> no se puede leer. Puede que se haya eliminado o movido o que los permisos del archivo impidan acceder a él.</translation>
+<translation id="8184538546369750125">Utilizar valor predeterminado global (Permitir)</translation>
+<translation id="8191494405820426728">ID del fallo local: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Deshacer movimiento</translation>
<translation id="8201077131113104583">URL de actualización no válida para la extensión <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Resumen del pedido</translation>
<translation id="8218327578424803826">Ubicación asignada:</translation>
<translation id="8225771182978767009">La persona que ha configurado este ordenador ha elegido bloquear este sitio web.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" /> o <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Los atacantes que se encuentran actualmente en el sitio <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar instalar programas peligrosos en tu ordenador para robar o eliminar tu información (por ejemplo, fotos, contraseñas, mensajes y tarjetas de crédito).</translation>
<translation id="8241707690549784388">La página que buscas ha utilizado la información que has especificado. Volver a la página podría provocar la repetición de alguna acción. ¿Quieres continuar?</translation>
<translation id="8249320324621329438">Última comprobación:</translation>
<translation id="8253091569723639551">Se necesita una dirección de facturación</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">Si tienes alguna duda, ponte en contacto con el administrador de red.</translation>
<translation id="8293206222192510085">Añadir marcador</translation>
<translation id="8294431847097064396">Origen</translation>
+<translation id="8306404619377842860">No se puede establecer ninguna conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu dispositivo (<ph name="DATE_AND_TIME" />) no son correctas. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Se ha producido un error de traducción debido a un problema con la conexión de red.</translation>
<translation id="8332188693563227489">Se ha denegado el acceso a <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Si entiendes los riesgos para tu seguridad, puedes <ph name="BEGIN_LINK" />acceder a este sitio<ph name="END_LINK" /> antes de que se hayan eliminado los programas dañinos.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">Inicia sesión en Chrome para utilizar tarjetas de tu cuenta de Google</translation>
<translation id="8488350697529856933">Aplicable a</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ha tardado demasiado tiempo en responder.</translation>
-<translation id="852346902619691059">Este servidor no ha podido demostrar que es <ph name="DOMAIN" />; el sistema operativo de tu dispositivo no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante ha interceptado la conexión. <ph name="BEGIN_LEARN_MORE_LINK" />Más información<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Año de caducidad</translation>
<translation id="8543181531796978784">Puedes <ph name="BEGIN_ERROR_LINK" />informar de un problema de detección<ph name="END_ERROR_LINK" /> o, si comprendes los riesgos que conlleva esta acción para tu seguridad, <ph name="BEGIN_LINK" />accede a este sitio web no seguro<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">La traducción no se ha realizado correctamente porque no se ha podido determinar el idioma de la página.</translation>
-<translation id="8559762987265718583">No se puede establecer una conexión privada con <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque la fecha y la hora de tu dispositivo (<ph name="DATE_AND_TIME" />) no son correctas.</translation>
<translation id="8571890674111243710">Traduciendo página a <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Añade un teléfono</translation>
<translation id="859285277496340001">El certificado no especifica ningún mecanismo para comprobar si se ha revocado.</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">Para establecer una conexión segura, tu reloj debe estar correctamente configurado. Esto se debe a que los certificados utilizados por los sitios web para identificarse son solo válidos durante períodos específicos de tiempo. Dado que la hora de tu dispositivo no es correcta, Chromium no puede verificar estos certificados.</translation>
<translation id="8740359287975076522">No se ha podido encontrar la &lt;abbr id="dnsDefinition"&gt;dirección DNS&lt;/abbr&gt; de la página <ph name="HOST_NAME" />. Se está diagnosticando el problema.</translation>
<translation id="8759274551635299824">La tarjeta ha caducado</translation>
+<translation id="8761567432415473239">La función de Navegación Segura de Google <ph name="BEGIN_LINK" />encontró programas dañinos<ph name="END_LINK" /> recientemente en el sitio <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Rehacer eliminación</translation>
<translation id="8800988563907321413">Las sugerencias de la sección Cercanas aparecen aquí</translation>
<translation id="8820817407110198400">Marcadores</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">Cerrado recientemente</translation>
<translation id="8874824191258364635">Introduce un número de tarjeta válido</translation>
<translation id="8876793034577346603">No se ha podido analizar la configuración de red.</translation>
-<translation id="8877192140621905067">Cuando confirmes la tarjeta, su información se compartirá con este sitio web</translation>
<translation id="8889402386540077796">Matiz</translation>
<translation id="8891727572606052622">El modo de proxy no es válido.</translation>
<translation id="889901481107108152">Esta función experimental no está disponible en tu plataforma.</translation>
<translation id="8903921497873541725">Acercar</translation>
<translation id="8931333241327730545">¿Quieres guardar esta tarjeta en tu cuenta de Google?</translation>
<translation id="8932102934695377596">Tu reloj está atrasado</translation>
-<translation id="8954894007019320973">(Cont.)</translation>
<translation id="8971063699422889582">El certificado del servidor ha caducado.</translation>
<translation id="8986494364107987395">Enviar automáticamente estadísticas de uso e informes sobre fallos a Google</translation>
-<translation id="8987927404178983737">Mes</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">El sitio al que vas a acceder contiene programas dañinos</translation>
+<translation id="8997023839087525404">El servidor ha mostrado un certificado que no se ha hecho público mediante la Política de Transparencia en los Certificados. Este requisito se aplica a algunos certificados para garantizar que son de confianza y ofrecer protección contra los atacantes.</translation>
<translation id="9001074447101275817">El proxy <ph name="DOMAIN" /> requiere un nombre de usuario y una contraseña.</translation>
+<translation id="9005998258318286617">Se ha producido un error al cargar el documento PDF.</translation>
<translation id="901974403500617787">Las opciones que se aplican a todo el sistema solo las puede establecer el propietario: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">La dirección de facturación de la tarjeta es obligatoria</translation>
<translation id="9020542370529661692">Esta página se ha traducido al <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Error de seguridad</translation>
<translation id="9038649477754266430">Utilizar un servicio de predicciones para que las páginas se carguen más rápido</translation>
<translation id="9039213469156557790">Además, esta página incluye otros recursos que no son seguros. Otros usuarios pueden acceder a estos recursos mientras están en circulación y un atacante puede modificarlos para cambiar el comportamiento de la página.</translation>
-<translation id="9040185888511745258">Los atacantes del sitio <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podrían intentar engañarte para que instales programas que afecten a tu navegación (por ejemplo, que cambien tu página principal o muestren anuncios adicionales en los sitios a los que accedas).</translation>
+<translation id="9049981332609050619">Has intentado acceder a <ph name="DOMAIN" />, pero el servidor ha presentado un certificado no válido.</translation>
<translation id="9050666287014529139">Frase de contraseña</translation>
<translation id="9065203028668620118">Editar</translation>
<translation id="9068849894565669697">Seleccionar color</translation>
+<translation id="9069693763241529744">Bloqueado por una extensión</translation>
<translation id="9076283476770535406">Es posible que incluya contenido para adultos</translation>
<translation id="9078964945751709336">Se necesita más información</translation>
<translation id="9103872766612412690"><ph name="SITE" /> utiliza normalmente el cifrado para proteger tu información. Cuando Chromium intentó establecer conexión con <ph name="SITE" />, el sitio web devolvió unas credenciales inusuales e incorrectas. Esto puede ocurrir si un atacante intenta suplantar la identidad de <ph name="SITE" /> o si una pantalla de inicio de sesión Wi-Fi interrumpe la conexión. Tu información sigue estando protegida, ya que Chromium detuvo la conexión antes de que se intercambiaran datos.</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">&amp;Deshacer edición</translation>
<translation id="9154194610265714752">Actualizado</translation>
<translation id="9157595877708044936">Configurando...</translation>
+<translation id="9169664750068251925">Bloquear siempre en este sitio</translation>
<translation id="9170848237812810038">&amp;Deshacer</translation>
<translation id="917450738466192189">El certificado del servidor no es válido.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> más}other{<ph name="SHIPPING_OPTION_PREVIEW" /> y <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> más}}</translation>
<translation id="9183425211371246419">La página <ph name="HOST_NAME" /> utiliza un protocolo no admitido.</translation>
<translation id="9205078245616868884">Tus datos se han cifrado con tu frase de contraseña de sincronización. Introdúcela para iniciar la sincronización.</translation>
<translation id="9207861905230894330">Se ha producido un error al añadir el artículo.</translation>
+<translation id="9219103736887031265">Imágenes</translation>
<translation id="933612690413056017">No hay conexión a Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">BORRAR FORMULARIO</translation>
<translation id="939736085109172342">Nueva carpeta</translation>
<translation id="941721044073577244">Parece que no tienes permiso para acceder a este sitio web</translation>
<translation id="969892804517981540">Build oficial</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ninguno}=1{1 elemento}other{# elementos}}</translation>
<translation id="988159990683914416">Build para desarrolladores</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_et.xtb b/chromium/components/strings/components_strings_et.xtb
index 9c53a53099f..9ba2036501d 100644
--- a/chromium/components/strings/components_strings_et.xtb
+++ b/chromium/components/strings/components_strings_et.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Pööra päripäeva</translation>
<translation id="1038842779957582377">tundmatu nimi</translation>
<translation id="1050038467049342496">Sulgege muud rakendused</translation>
-<translation id="1053591932240354961">Te ei saa saiti <ph name="SITE" /> praegu külastada, kuna see saatis šifreeritud mandaadi, mida Google Chrome ei saa töödelda. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht on tõenäoliselt hiljem töökorras. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Võta lisamine tagasi</translation>
<translation id="10614374240317010">Ei ole kunagi salvestatud</translation>
<translation id="106701514854093668">Töölaua järjehoidjad</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Reegli vahemälu töötab probleemideta</translation>
<translation id="113188000913989374"><ph name="SITE" /> ütleb:</translation>
<translation id="1132774398110320017">Chrome'i automaattäite seaded ...</translation>
+<translation id="1150979032973867961">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, arvuti operatsioonisüsteem ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
+<translation id="1151972924205500581">Parool on nõutav</translation>
<translation id="1152921474424827756">Hankige juurdepääs aadressi <ph name="URL" /> <ph name="BEGIN_LINK" />vahemällu salvestatud koopiale<ph name="END_LINK" /></translation>
<translation id="1158211211994409885">Host <ph name="HOST_NAME" /> sulges ootamatult ühenduse.</translation>
<translation id="1161325031994447685">Ãœhendage uuesti WiFi-ga</translation>
+<translation id="1165039591588034296">Viga</translation>
<translation id="1175364870820465910">&amp;Prindi...</translation>
<translation id="1181037720776840403">Eemalda</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Teavita Google'it automaatselt<ph name="END_WHITEPAPER_LINK" /> võimalikest turvaintsidentidest. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Veel sellelt saidilt</translation>
<translation id="1206967143813997005">Sobimatu algne allkiri</translation>
<translation id="1209206284964581585">Peida praeguseks</translation>
+<translation id="121201262018556460">Proovisite jõuda saidile <ph name="DOMAIN" />, kuid server esitas nõrka võtit sisaldava sertifikaadi. Võimalik, et ründaja on privaatvõtme lahti murdnud ja tegemist ei pruugi olla oodatud serveriga (võimalik, et suhtlete ründajaga).</translation>
<translation id="1219129156119358924">Süsteemi turvalisus</translation>
<translation id="1227224963052638717">Tundmatud eeskirjad.</translation>
<translation id="1227633850867390598">Peida väärtus</translation>
<translation id="1228893227497259893">Ãœksuse vale identifikaator</translation>
<translation id="1232569758102978740">Pealkirjata</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sünkroonitud)</translation>
<translation id="1263231323834454256">Lugemisloend</translation>
<translation id="1264126396475825575">Krahhiaruanne talletati <ph name="CRASH_TIME" /> (ei ole veel üles laaditud ega eiratud)</translation>
+<translation id="1281526147609854549">Väljaandja: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Ohtlik sisu blokeeriti</translation>
<translation id="1285320974508926690">Ära kunagi seda saiti tõlgi</translation>
<translation id="129553762522093515">Viimati suletud</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Kustutage küpsisefailid<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Teie tegevused <ph name="BEGIN_EMPHASIS" />võivad siiski olla nähtavad<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />teie külastatud veebisaitidele;
+ <ph name="LIST_ITEM" />teie tööandjale või koolile;
+ <ph name="LIST_ITEM" />teie Interneti-teenusepakkujale.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Registreerimisdomeen:</translation>
<translation id="1340482604681802745">Kättesaamise aadress</translation>
<translation id="1344211575059133124">Näib, et vajate saidi külastamiseks luba</translation>
<translation id="1344588688991793829">Chromiumi automaattäite seaded ...</translation>
+<translation id="1348198688976932919">Sait, mille soovite avada, sisaldab ohtlikke rakendusi</translation>
<translation id="1374468813861204354">soovitused</translation>
<translation id="1375198122581997741">Teave versiooni kohta</translation>
<translation id="1377321085342047638">Kaardinr</translation>
<translation id="139305205187523129">Host <ph name="HOST_NAME" /> ei saatnud andmeid.</translation>
<translation id="1407135791313364759">Ava kõik</translation>
<translation id="1413809658975081374">Privaatsuse viga</translation>
+<translation id="14171126816530869"><ph name="ORGANIZATION" /> identiteeti leheküljel <ph name="LOCALITY" /> kinnitas <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Jah</translation>
<translation id="1430915738399379752">Printimine</translation>
-<translation id="1442912890475371290">Blokeeriti katse <ph name="BEGIN_LINK" />domeeni <ph name="DOMAIN" /> lehte külastada<ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest see kasutab sertifikaadi kinnitamist. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht on tõenäoliselt hiljem töökorras. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Lehe salvestatud (s.t teadaolevalt aegunud) koopia kuvamine.</translation>
<translation id="1517433312004943670">Telefoninumber on nõutav</translation>
<translation id="1519264250979466059">Järgu kuupäev</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Selle funktsiooni kasutamiseks peab JavaScript olema lubatud.</translation>
<translation id="1555130319947370107">Sinine</translation>
<translation id="1559528461873125649">Pole sellist faili või kataloogi</translation>
-<translation id="1559572115229829303">&lt;p&gt;Domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei saa privaatset ühendust luua, kuna seadme kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />DATE_AND_TIME) on valed.&lt;/p&gt;
-
- &lt;p&gt;Kohandage kuupäeva ja kellaaega rakenduse &lt;strong&gt;Seaded&lt;/strong&gt; jaotises &lt;strong&gt;Üldine&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Veebilehe kuvamisel läks midagi valesti.</translation>
<translation id="1592005682883173041">Juurdepääs kohalikele andmetele</translation>
+<translation id="1594030484168838125">Vali</translation>
<translation id="161042844686301425">Tsüaan</translation>
+<translation id="1620510694547887537">Kaamera</translation>
<translation id="1629803312968146339">Kas soovite, et Chrome salvestaks selle kaardi?</translation>
<translation id="1639239467298939599">Laadimine</translation>
<translation id="1640180200866533862">Kasutajareeglid</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Võrgu seadistus on sobimatu ja seda ei saa importida.</translation>
<translation id="1644574205037202324">Ajalugu</translation>
<translation id="1645368109819982629">Toetuseta protokoll</translation>
+<translation id="1655462015569774233">{1,plural, =1{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />, selle turvasertifikaat aegus eile. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. Teie arvuti kell on praegu seatud kuupäevale <ph name="CURRENT_DATE" />. Kas see on õige? Kui ei ole, seadke süsteemi kell õigeks ja värskendage lehte.}other{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />, selle turvasertifikaat aegus # päeva tagasi. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. Teie arvuti kell on praegu seatud kuupäevale <ph name="CURRENT_DATE" />. Kas see on õige? Kui ei ole, seadke süsteemi kell õigeks ja värskendage lehte.}}</translation>
<translation id="1656489000284462475">Kättesaamine</translation>
<translation id="1663943134801823270">Kaardid ja aadressid pärinevad Chrome'ist. Neid saate hallata menüüs <ph name="BEGIN_LINK" />Seaded<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Sait <ph name="SITE" /> kasutab teie teabe kaitsmiseks tavaliselt krüpteerimist. Kui Google Chrome püüdis seekord saidiga <ph name="SITE" /> ühendust luua, tagastas veebisait ebatavalised ja valed mandaadid. See võib juhtuda siis, kui ründaja proovib teeselda, et on sait <ph name="SITE" />, või WiFi sisselogimisekraan on ühenduse katkestanud. Teie teave on endiselt kaitstud, sest Google Chrome peatas ühenduse enne andmevahetust.</translation>
-<translation id="168328519870909584">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> olevad ründajad võivad proovida installida teie seadmesse ohtlikke rakendusi, mis varastavad teie teavet või kustutavad selle (nt fotod, paroolid, sõnumid ja krediitkaardiandmed).</translation>
<translation id="168841957122794586">Serveri sertifikaat sisaldab nõrka krüptograafilist võtit.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />, selle turvasertifikaat hakkab väidetavalt kehtima homme. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja.}other{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />, selle turvasertifikaat hakkab väidetavalt kehtima # päeva pärast. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Vajate saidi külastamiseks halduri <ph name="NAME" /> luba</translation>
<translation id="1721424275792716183">* Kohustuslik väli</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Laadi leht hiljem alla</translation>
<translation id="17513872634828108">Avatud vahelehed</translation>
<translation id="1753706481035618306">Lk</translation>
+<translation id="1763864636252898013">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, seadme operatsioonisüsteem ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Proovige käitada Windowsi võrgudiagnostika tööriista<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Värskendage sünkroonimise parooli.</translation>
<translation id="1787142507584202372">Teie avatud vahelehed kuvatakse siin</translation>
+<translation id="1789575671122666129">Hüpikaknad</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Kaardiomaniku nimi</translation>
-<translation id="1803678881841855883">Google'i ohutu sirvimine avastas saidilt <ph name="SITE" /> hiljuti <ph name="BEGIN_LINK" />pahavara<ph name="END_LINK" />. Tavaliselt ohutud veebisaidid nakatuvad mõnikord pahavaraga. Pahatahtliku sisu allikas on tuntud pahavaralevitaja <ph name="SUBRESOURCE_HOST" />. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Lisati kuupäeval <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Taotlus või selle parameetrid on kehtetud</translation>
<translation id="1826516787628120939">Kontrollimine</translation>
<translation id="1834321415901700177">See sait sisaldab kahjulikke programme</translation>
+<translation id="1840414022444569775">See kaardinumber on juba kasutusel</translation>
<translation id="1842969606798536927">Maksmine</translation>
<translation id="1871208020102129563">Puhverserver on seatud kasutama fikseeritud puhverservereid, mitte pac-skripti URL-i.</translation>
<translation id="1871284979644508959">Kohustuslik väli</translation>
<translation id="187918866476621466">Ava käivitamisel avatavad lehed</translation>
<translation id="1883255238294161206">Ahenda loend</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtreerimine</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ãœhtegi}=1{1 sait}other{# saiti}}</translation>
<translation id="194030505837763158">Avage <ph name="LINK" /></translation>
<translation id="1962204205936693436">Domeeni <ph name="DOMAIN" /> järjehoidjad</translation>
<translation id="1973335181906896915">Viga jadaks teisendamisel</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Seda ignoreeritakse, kuna reegel <ph name="POLICY_NAME" /> alistab selle.</translation>
<translation id="2138201775715568214">Lähedalasuvate füüsilise veebi lehtede otsimine</translation>
<translation id="213826338245044447">Mobiili järjehoidjad</translation>
-<translation id="2148716181193084225">Täna</translation>
+<translation id="2147827593068025794">Taustal sünkroonimine</translation>
<translation id="2154054054215849342">Sünkroonimisteenus pole domeeni jaoks saadaval</translation>
<translation id="2154484045852737596">Kaardi muutmine</translation>
<translation id="2166049586286450108">Täielik administraatorijuurdepääs</translation>
<translation id="2166378884831602661">See sait ei saa turvalist ühendust luua</translation>
<translation id="2181821976797666341">Reeglid</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 aadress}other{# aadressi}}</translation>
+<translation id="2187317261103489799">Tuvasta (vaikimisi)</translation>
<translation id="2202020181578195191">Sisestage kehtiv aegumisaasta</translation>
<translation id="2212735316055980242">Reeglit ei leitud</translation>
<translation id="2213606439339815911">Kirjete toomine ...</translation>
+<translation id="2218879909401188352">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> olevad ründajad võivad installida ohtlikke rakendusi, mis kahjustavad teie seadet, lisavad mobiiliarvele varjatud kulusid või varastavad teie isiklikke andmeid. <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Parandage oma ühendus <ph name="BEGIN_LINK" />diagnostikarakenduse<ph name="END_LINK" /> abil</translation>
<translation id="2239100178324503013">Saada kohe</translation>
<translation id="225207911366869382">Väärtus on eeskirjade jaoks aegunud.</translation>
<translation id="2262243747453050782">HTTP viga</translation>
+<translation id="2270484714375784793">Telefoninumber</translation>
<translation id="2282872951544483773">Kättesaamatud katsetused</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> üksus}other{<ph name="ITEM_COUNT" /> üksust}}</translation>
<translation id="2292556288342944218">Teie juurdepääs Internetile on blokeeritud</translation>
<translation id="230155334948463882">Uus kaart?</translation>
-<translation id="2305919008529760154">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat võib olla väljastatud petturlikul moel. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">Domeen <ph name="DOMAIN" /> nõuab kasutajanime ja parooli.</translation>
-<translation id="2318774815570432836">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest veebisait kasutab HSTS-i. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht on tõenäoliselt hiljem töökorras. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Seadet juhib administraator</translation>
<translation id="2354001756790975382">Muud järjehoidjad</translation>
+<translation id="2354430244986887761">Google'i ohutu sirvimine leidis hiljuti saidilt <ph name="SITE" /> <ph name="BEGIN_LINK" />ohtlikke rakendusi<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">Ründajad võivad näha pilte, mida sellel saidil vaatate, ja teid neid pilte muutes petta.</translation>
+<translation id="2356070529366658676">Küsi</translation>
+<translation id="2359629602545592467">Mitu</translation>
<translation id="2359808026110333948">Jätka</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> talletatud krahhiaruannet ei laaditud üles</translation>
<translation id="2367567093518048410">Tase</translation>
-<translation id="2371153335857947666">{1,plural, =1{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat aegus eile. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. Teie arvuti kell on praegu seatud kuupäevale <ph name="CURRENT_DATE" />. Kas see on õige? Kui ei ole, seadke süsteemi kell õigeks ja värskendage lehte. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.}other{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat aegus # päeva tagasi. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. Teie arvuti kell on praegu seatud kuupäevale <ph name="CURRENT_DATE" />. Kas see on õige? Kui ei ole, seadke süsteemi kell õigeks ja värskendage lehte. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Kasutajaliidese alternatiive pole saadaval</translation>
<translation id="2384307209577226199">Ettevõtte vaikeseade</translation>
<translation id="2386255080630008482">Serveri sertifikaat on tühistatud.</translation>
<translation id="2392959068659972793">Kuva reeglid, mille väärtusi pole määratud</translation>
<translation id="239429038616798445">See tarneviis pole saadaval. Proovige mõnda teist tarneviisi.</translation>
<translation id="2396249848217231973">&amp;Võta kustutamine tagasi</translation>
-<translation id="2460160116472764928">Google'i ohutu sirvimine avastas saidilt <ph name="SITE" /> hiljuti <ph name="BEGIN_LINK" />pahavara<ph name="END_LINK" />. Tavaliselt ohutud veebisaidid nakatuvad mõnikord pahavaraga. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, selle turvasertifikaat võib olla tühistatud. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="2463739503403862330">Täida</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Võrgudiagnostika käitamine<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Kehtetu otsingu URL.</translation>
+<translation id="2482878487686419369">Märguanded</translation>
<translation id="2491120439723279231">Serveri sertifikaat sisaldab vigu.</translation>
<translation id="2495083838625180221">JSON-i parser</translation>
<translation id="2495093607237746763">Kui see on märgitud, salvestab Chromium teie kaardi koopia vormide kiiremaks täitmiseks sellesse seadmesse.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Mine tagasi</translation>
<translation id="2515629240566999685">Kontrollige oma piirkonna signaali</translation>
<translation id="2516305470678292029">Kasutajaliidese alternatiivid</translation>
+<translation id="2539524384386349900">Tuvasta</translation>
<translation id="255002559098805027">Host <ph name="HOST_NAME" /> saatis sobimatu vastuse.</translation>
-<translation id="2552545117464357659">Uuemad</translation>
<translation id="2556876185419854533">&amp;Võta muudatus tagasi</translation>
<translation id="2587730715158995865">Avaldajalt <ph name="ARTICLE_PUBLISHER" />. Lugege seda ja <ph name="OTHER_ARTICLE_COUNT" /> teist lugu.</translation>
<translation id="2587841377698384444">Kataloogi API ID:</translation>
<translation id="2597378329261239068">Dokument on parooliga kaitstud. Sisestage parool.</translation>
<translation id="2609632851001447353">Variatsioonid</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ãœhtegi}=1{1 rakendus ($1)}=2{2 rakendust ($1, $2)}other{# rakendust ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Teie kell on ees</translation>
<translation id="2639739919103226564">Olek:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Faili juurde ei saa pääseda</translation>
<translation id="2653659639078652383">Esita</translation>
<translation id="2666117266261740852">Sulgege muud vahelehed või rakendused</translation>
+<translation id="2670429602441959756">See leht sisaldab funktsioone, mida VR veel ei toeta. Väljumine …</translation>
<translation id="2674170444375937751">Olete kindel, et soovite need leheküljed oma ajaloost kustutada?</translation>
<translation id="2677748264148917807">Lahku</translation>
-<translation id="269990154133806163">Server esitas sertifikaadi, mida ei ole sertifikaadi läbipaistvuse reegli kohaselt avalikustatud. See on teatud sertifikaatide puhul nõutav, et need oleksid usaldusväärsed ja kaitseksid ründajate eest. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Lugemisloend</translation>
<translation id="2704283930420550640">Väärtus ei vasta vormingule.</translation>
<translation id="2704951214193499422">Chromium ei saanud praegu teie kaarti kinnitada. Proovige hiljem uuesti.</translation>
<translation id="2705137772291741111">Selle saidi (vahemällu) salvestatud koopia oli loetamatu.</translation>
<translation id="2709516037105925701">Automaatne täitmine</translation>
-<translation id="2712118517637785082">Püüdsite jõuda domeenile <ph name="DOMAIN" />, kuid sertifikaadi väljaandja on serveri esitatud sertifikaadi tühistanud. See tähendab, et serveri esitatud turvamandaate ei tohi mingil juhul usaldada. Võimalik, et suhtlete ründajaga. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Küsi luba</translation>
<translation id="2713444072780614174">Valge</translation>
<translation id="2720342946869265578">Läheduses</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Seadme kirje puudub</translation>
<translation id="2784949926578158345">Ühendus lähtestati.</translation>
<translation id="2794233252405721443">Sait on blokeeritud</translation>
+<translation id="2799020568854403057">Sait, mille soovite avada, sisaldab kahjulikke rakendusi</translation>
+<translation id="2803306138276472711">Google'i ohutu sirvimise teenus <ph name="BEGIN_LINK" />tuvastas hiljuti pahavara<ph name="END_LINK" /> saidil <ph name="SITE" />. Tavaliselt turvalisi veebisaite võidakse mõnikord nakatada pahavaraga.</translation>
<translation id="2824775600643448204">Aadressi- ja otsinguriba</translation>
<translation id="2826760142808435982">Ühendus on krüptitud ja autenditud üksusega <ph name="CIPHER" /> ning kasutab peamise vahetusmehhanismina üksust <ph name="KX" />.</translation>
<translation id="2835170189407361413">Tühjenda vorm</translation>
+<translation id="2856444702002559011">Ründajad võivad üritada varastada teie teavet (nt paroole, sõnumeid või krediitkaarditeavet) saidilt <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />. <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ära laadi uuesti</translation>
<translation id="2900469785430194048">Google Chrome'il pole selle veebilehe kuvamiseks piisavalt mälu.</translation>
<translation id="2909946352844186028">Tuvastati võrgumuudatus.</translation>
<translation id="2916038427272391327">Sulgege muud programmid</translation>
<translation id="2922350208395188000">Serveri sertifikaati ei saa kontrollida.</translation>
<translation id="2928905813689894207">Arveldusaadress</translation>
+<translation id="2941952326391522266">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, selle turvasertifikaati pärineb domeenilt <ph name="DOMAIN2" />. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="2948083400971632585">Seadete lehel saate keelata kõik ühenduse jaoks konfigureeritud puhverserverid.</translation>
<translation id="2955913368246107853">Sule leiuriba</translation>
<translation id="2958431318199492670">Võrgu seadistus ei vasta ONC standardile. On võimalik, et seadistuse mõnd osa ei saa importida.</translation>
-<translation id="29611076221683977">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> olevad ründajad võivad proovida installida teie Maci ohtlikke programme, mis varastavad teie teavet või kustutavad selle (nt fotod, paroolid, sõnumid ja krediitkaardiandmed).</translation>
<translation id="2966678944701946121">Aegub: <ph name="EXPIRATION_DATE_ABBR" />. Lisati kuupäeval <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Turvalise ühenduse loomiseks peab kell olema õigesti seadistatud, kuna sertifikaadid, mida veebisaidid kasutavad enda tuvastamiseks, kehtivad ainult teatud perioodi jooksul. Kuna teie seadme kell on vale, ei saa Chrome neid sertifikaate kinnitada.</translation>
<translation id="2972581237482394796">&amp;Tee uuesti</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Sisestage kehtiv aadress</translation>
<translation id="2986368408720340940">See kättesaamisviis pole saadaval. Proovige mõnda teist kättesaamisviisi.</translation>
<translation id="2991174974383378012">Veebisaitidega jagamine</translation>
+<translation id="2991571918955627853">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest veebisait kasutab HSTS-i. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht tõenäoliselt hiljem töötab.</translation>
<translation id="3005723025932146533">Kuva salvestatud koopia</translation>
<translation id="3008447029300691911">Sisestage krediitkaardi <ph name="CREDIT_CARD" /> CVC. Kui selle kinnitate, jagatakse teie kaardi üksikasju selle saidiga.</translation>
<translation id="3010559122411665027">Loendi kirje „<ph name="ENTRY_INDEX" />â€: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automaatselt blokeeritud</translation>
<translation id="3024663005179499861">Reegli tüüp on vale</translation>
<translation id="3032412215588512954">Kas soovite selle saidi uuesti laadida?</translation>
<translation id="3037605927509011580">Ups, ebaõnn!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{vähemalt 1 üksus sünkroonitud seadmetes}=1{1 üksus (ja rohkem sünkroonitud seadmetes)}other{# üksust (ja rohkem sünkroonitud seadmetes)}}</translation>
<translation id="3041612393474885105">Sertifikaadi andmed</translation>
<translation id="3063697135517575841">Chrome ei saanud praegu teie kaarti kinnitada. Proovige hiljem uuesti.</translation>
<translation id="3064966200440839136">Väljute inkognito režiimist, et välise rakenduse kaudu maksta. Kas soovite jätkata?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ãœhtegi}=1{1 parool}other{# parooli}}</translation>
<translation id="3093245981617870298">Olete võrguühenduseta.</translation>
<translation id="3105172416063519923">Vara ID:</translation>
<translation id="3109728660330352905">Teil pole volitust selle lehe vaatamiseks.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Proovige käitada ühenduvusdiagnostikat<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Vastuse dekodeerimine ebaõnnestus</translation>
<translation id="3150653042067488994">Serveris ilmnes ajutine viga</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Inkognito vahelehtedel kuvatavaid lehti ei talletata pärast vahelehtede sulgemist brauseri ajalukku, küpsistefailide salve ega otsinguajalukku. Allalaaditavad failid ja järjehoidjatesse lisatud sisu säilitatakse.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Saar</translation>
+<translation id="317583078218509884">Saidi uute lubade seaded jõustuvad pärast lehe uuesti laadimist.</translation>
<translation id="3176929007561373547">Kontrollige puhverserveri seadeid või võtke ühendust võrguadministraatoriga
ja veenduge, et puhverserver töötaks. Kui arvate, et teil ei ole vaja
puhverserverit kasutada:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Avage leht inkognito režiimis</translation>
-<translation id="3202578601642193415">Kõige uuemad</translation>
+<translation id="320323717674993345">Tühista makse</translation>
<translation id="3207960819495026254">Järjehoidjatesse lisatud</translation>
+<translation id="3225919329040284222">Serveri esitatud sertifikaat ei vasta sisseehitatud ootustele. Ootused on teie kaitsmiseks kaasatud kindlate kõrge turvalisusega veebisaitide jaoks.</translation>
<translation id="3226128629678568754">Lehe laadimiseks vajalike andmete uuesti esitamiseks vajutage uuesti laadimise nuppu.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Tõlkimine nurjus, kuna lehe keel on juba <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Krediitkaardi <ph name="CREDIT_CARD" /> CVC sisestamine</translation>
+<translation id="3234666976984236645">Sellel saidil olulise sisu alati tuvastamine</translation>
<translation id="3254409185687681395">Lisa see lehekülg järjehoidjatesse</translation>
<translation id="3270847123878663523">&amp;Võta korrastamine tagasi</translation>
<translation id="3282497668470633863">Kaardil oleva nime lisamine</translation>
@@ -270,45 +304,51 @@
<translation id="3340978935015468852">seaded</translation>
<translation id="3345135638360864351">Saidi külastamise taotlust ei õnnestunud saata kontaktile <ph name="NAME" />. Proovige uuesti.</translation>
<translation id="3355823806454867987">Muuda puhverserveri seadeid ...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />ei salvesta<ph name="END_EMPHASIS" /> järgmist teavet:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />teie sirvimisajalugu;
+ <ph name="LIST_ITEM" />küpsisefailid ja saidi andmed;
+ <ph name="LIST_ITEM" />vormidesse sisestatud teave.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Kella viga</translation>
-<translation id="337311366426640088">Veel <ph name="ITEM_COUNT" /> üksust …</translation>
<translation id="337363190475750230">Eraldatud</translation>
<translation id="3377188786107721145">Viga reegli sõelumisel</translation>
<translation id="3380365263193509176">Tundmatu viga</translation>
<translation id="3380864720620200369">Kliendi ID:</translation>
<translation id="3391030046425686457">Kohaletoimetamise aadress</translation>
<translation id="3395827396354264108">Kättesaamisviis</translation>
-<translation id="340013220407300675">Ründajad võivad üritada saidilt <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> varastada teie teavet (näiteks paroole, sõnumeid või krediitkaardiandmeid).</translation>
<translation id="3422248202833853650">Proovige mälu vabastamiseks väljuda muudest programmidest.</translation>
<translation id="3422472998109090673">Hostiga <ph name="HOST_NAME" /> ei saa praegu ühendust.</translation>
+<translation id="3427092606871434483">Luba (vaikimisi)</translation>
<translation id="3427342743765426898">&amp;Muuda uuesti</translation>
<translation id="3431636764301398940">Salvesta kaart sellesse seadmesse</translation>
<translation id="3435896845095436175">Luba</translation>
<translation id="3447661539832366887">Seadme omanik lülitas dinosaurusemängu välja.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hankimise intervall:</translation>
<translation id="3462200631372590220">Peida täpsemad üksikasjad</translation>
<translation id="3467763166455606212">Kaardiomaniku nimi on kohustuslik</translation>
<translation id="3478058380795961209">Aegumiskuu</translation>
<translation id="3479539252931486093">Kas see oli ootamatu? <ph name="BEGIN_LINK" />Andke meile sellest teada<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Mitte praegu</translation>
-<translation id="348000606199325318">Krahhi ID <ph name="CRASH_LOCAL_ID" /> (serveri ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Teie vanemaga ei õnnestunud praegu ühendust võtta. Proovige hiljem uuesti.</translation>
<translation id="3528171143076753409">Serveri sertifikaat ei ole usaldusväärne.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Vähemalt 1 üksus sünkroonitud seadmetes}=1{1 üksus (ja rohkem sünkroonitud seadmetes)}other{# üksust (ja rohkem sünkroonitud seadmetes)}}</translation>
<translation id="3539171420378717834">Säilita kaardi koopia seadmes</translation>
<translation id="3542684924769048008">Kasuta parooli:</translation>
+<translation id="3545341443414427877">Domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei saa privaatset ühendust luua, kuna arvuti kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />) on valed. <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Krüpteerige kõik sünkroonitud andmed oma sünkroonimise parooliga</translation>
-<translation id="3549761410225185768">Veel <ph name="NUM_TABS_MORE" /> ...</translation>
-<translation id="3555561725129903880">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />. Selle turvasertifikaat pärineb domeenilt <ph name="DOMAIN2" />. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Haldur saab blokeeringu teie eest tühistada</translation>
<translation id="3566021033012934673">Teie ühendus ei ole privaatne</translation>
+<translation id="3569145463236695319">&lt;p&gt;Domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei saa privaatset ühendust luua, kuna seadme kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />) on valed.&lt;/p&gt;
+
+ &lt;p&gt;Kohandage kuupäeva ja kellaaega rakenduse &lt;strong&gt;Seaded&lt;/strong&gt; jaotises &lt;strong&gt;Üldine&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Lisage nimi</translation>
<translation id="3583757800736429874">&amp;Teisalda uuesti</translation>
<translation id="3586931643579894722">Peida üksikasjad</translation>
-<translation id="3587482841069643663">Kõik</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Sisestage kehtiv aegumiskuupäev</translation>
-<translation id="36224234498066874">Kustuta sirvimise andmed...</translation>
+<translation id="36224234498066874">Sirvimisandmete kustutamine...</translation>
<translation id="362276910939193118">Näita kogu ajalugu</translation>
<translation id="3623476034248543066">Kuva väärtused</translation>
<translation id="3630155396527302611">Kui see on juba loendis kui programm, millele on lubatud võrgujuurdepääs, proovige
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Sertifikaadi andmed</translation>
<translation id="3690164694835360974">Sisselogimine pole turvaline</translation>
<translation id="3693415264595406141">Parool:</translation>
-<translation id="3696411085566228381">puudub</translation>
<translation id="3704609568417268905"><ph name="TIME" />, <ph name="BOOKMARKED" />, <ph name="TITLE" />, <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Laadimine...</translation>
<translation id="3712624925041724820">Litsentsid on ammendunud</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Kontrollige puhverserveri, tulemüüri ja DNS-i seadistust<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Kui mõistate, kuidas teie turvalisust ohustatakse, siis võite <ph name="BEGIN_LINK" />seda ebaturvalist saiti külastada<ph name="END_LINK" /> enne, kui ohtlikud programmid on eemaldatud.</translation>
<translation id="3739623965217189342">Teie kopeeritud link</translation>
+<translation id="3744899669254331632">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest veebisait saatis tagasi arusaamatud mandaadid, mida Chromium ei saa töödelda. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht tõenäoliselt hiljem töötab.</translation>
+<translation id="3748148204939282805">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> asuvad ründajad võivad teid meelitada ohtlikele tegevustele, nagu tarkvara installimine või isiklike andmete (nt paroolid, telefoninumbrid või krediitkaarditeave) avaldamine. <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Tõlkimine ebaõnnestus serverivea tõttu.</translation>
<translation id="3759461132968374835">Hiljuti teatatud krahhe ei ole. Siin ei ilmu krahhid, mis toimusid siis, kui krahhide aruandlus oli keelatud.</translation>
+<translation id="3778403066972421603">Kas soovite selle kaardi salvestada oma Google'i kontole ja sellesse seadmesse?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Aegub: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Kui kasutate puhverserverit ...</translation>
<translation id="3828924085048779000">Tühi parool ei ole lubatud.</translation>
-<translation id="3845539888601087042">Kuvatakse ajalugu teie sisselogitud seadmetest. <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Tagasi</translation>
<translation id="3858027520442213535">Värskenda kuupäeva ja kellaaega</translation>
<translation id="3884278016824448484">Seadme identifikaator on konfliktne</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Teie juurdepääsutaotlus sellele saidile saadeti kasutajale <ph name="NAME" /></translation>
<translation id="3890664840433101773">E-posti aadressi lisamine</translation>
<translation id="3901925938762663762">Kaart on aegunud</translation>
-<translation id="3933571093587347751">{1,plural, =1{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat hakkab väidetavalt kehtima homme. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.}other{Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat hakkab väidetavalt kehtima # päeva pärast. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF-dokumendi laadimine nurjus</translation>
+<translation id="3945915738023014686">Ãœleslaaditud krahhiaruande ID <ph name="CRASH_ID" /> (kohaliku krahhi ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />; selle turvasertifikaat ei määra laiendust Subject Alternative Names. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="3963721102035795474">Lugejarežiim</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ãœkski}=1{1 saidilt }other{# saidilt }}</translation>
<translation id="397105322502079400">Arvutamine ...</translation>
<translation id="3973234410852337861">Host <ph name="HOST_NAME" /> on blokeeritud</translation>
+<translation id="3987940399970879459">Alla 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{Läheduses on 1 veebileht}other{Läheduses on # veebilehte}}</translation>
<translation id="4021036232240155012">DNS on võrguteenus, mis tõlgib veebisaidi nime selle Interneti-aadressiks.</translation>
<translation id="4030383055268325496">&amp;Võta lisamine tagasi</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Puhverserveri konfigureerimine on määratud kasutama pac-skripti URL-i, mitte fikseeritud puhverservereid.</translation>
<translation id="4098354747657067197">Avatav sait on petturlik</translation>
<translation id="4103249731201008433">Seadme seerianumber on kehtetu</translation>
+<translation id="410351446219883937">Automaatesitus</translation>
<translation id="4103763322291513355">Külastage saiti &lt;strong&gt;chrome://policy&lt;/strong&gt;, et näha mustas nimekirjas olevate URL-ide loendit ja teisi reegleid, mille on jõustanud teie süsteemiadministraator.</translation>
-<translation id="4110615724604346410">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat sisaldab vigu. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Luba sellel saidil alati</translation>
<translation id="4117700440116928470">Reegli ulatust ei toetata.</translation>
-<translation id="4118212371799607889">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Chromium ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{veel 1}other{veel #}}</translation>
<translation id="4130226655945681476">Kontrollige võrgukaableid, modemit ja ruuterit</translation>
+<translation id="413544239732274901">Lisateave</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Kasuta üldist vaikevalikut (tuvasta)</translation>
+<translation id="4165986682804962316">Saidi seaded</translation>
<translation id="4169947484918424451">Kas soovite, et Chromium salvestaks selle kaardi?</translation>
<translation id="4171400957073367226">Sobimatu kinnitusallkiri</translation>
<translation id="4196861286325780578">&amp;Teisalda uuesti</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Kontrollige tulemüüri ja viirusetõrje seadistusi<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{mitte ühtegi}=1{1 rakendus ($1)}=2{2 rakendust ($1, $2)}other{# rakendust ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Krahhid</translation>
+<translation id="422022731706691852">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> asuvad ründajad võivad proovida meelitada teid installima programme, mis kahjustavad sirvimiskogemust (nt muudavad avalehte või kuvavad külastatavatel saitidel lisareklaame). <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Proovige käitada võrgudiagnostikat<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Kehtiv</translation>
<translation id="4250431568374086873">Teie ühendus selle saidiga pole täielikult turvaline</translation>
<translation id="4250680216510889253">Ei</translation>
<translation id="425582637250725228">Tehtud muudatusi ei pruugita salvestada.</translation>
<translation id="4258748452823770588">Sobimatu allkiri</translation>
+<translation id="4265872034478892965">Lubas administraator</translation>
<translation id="4269787794583293679">(Kasutajanimi puudub)</translation>
<translation id="4275830172053184480">Taaskäivitage seade</translation>
<translation id="4280429058323657511">, aegub <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google'i ohutu sirvimine leidis saidilt <ph name="SITE" /> hiljuti <ph name="BEGIN_LINK" />kahjulikke programme<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Vanema soovitused</translation>
<translation id="4304224509867189079">Logi sisse</translation>
-<translation id="432290197980158659">Server esitas sertifikaadi, mis ei kattu sisseehitatud ootustega. Ootusi rakendatakse teatud väga turvaliste veebisaitide puhul teie kaitsmiseks. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blokeeri (vaikimisi)</translation>
<translation id="4325863107915753736">Artiklit ei leitud</translation>
<translation id="4326324639298822553">Kontrollige aegumiskuupäeva ja proovige uuesti</translation>
<translation id="4331708818696583467">Pole turvaline</translation>
<translation id="4356973930735388585">Saidil olevad ründajad võivad proovida installida teie arvutisse ohtlikke programme, mis varastavad teie teavet või kustutavad selle (nt fotod, paroolid, sõnumid ja krediitkaardiandmed).</translation>
<translation id="4372948949327679948">Oodatud väärtus: <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Püüdsite jõuda saidile <ph name="DOMAIN" />, kuid sertifikaadi väljaandja on serveri esitatud sertifikaadi tagasi võtnud. See tähendab, et serveri esitatud turvamandaate ei tohiks mingil juhul usaldada. Võimalik, et suhtlete ründajaga.</translation>
<translation id="4381091992796011497">Kasutajanimi:</translation>
<translation id="4394049700291259645">Keela</translation>
<translation id="4406896451731180161">otsingutulemused</translation>
+<translation id="4424024547088906515">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, Chrome ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="4432688616882109544">Host <ph name="HOST_NAME" /> ei aktsepteerinud teie sisselogimise sertifikaati või te ei esitanud seda.</translation>
<translation id="443673843213245140">Puhverserveri kasutamine on keelatud, kuid määratud on ka konkreetne puhverserveri konfigureerimine.</translation>
-<translation id="4492190037599258964">Otsingutulemused „<ph name="SEARCH_STRING" />“ kohta</translation>
<translation id="4506176782989081258">Valideerimisviga: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Võtke ühendust süsteemiadministraatoriga</translation>
<translation id="450710068430902550">Administraatoriga jagamine</translation>
<translation id="4515275063822566619">Kaardid ja aadressid pärinevad Chrome'ist ning teie Google'i kontolt (<ph name="ACCOUNT_EMAIL" />). Neid saate hallata menüüs <ph name="BEGIN_LINK" />Seaded<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Ãœksikasjad</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Keelake laiendused.</translation>
<translation id="457875822857220463">Kohaletoimetamine</translation>
<translation id="4587425331216688090">Kas eemaldada Chrome'ist aadress?</translation>
-<translation id="4589078953350245614">Püüdsite jõuda domeenile <ph name="DOMAIN" />, ent server esitas kehtetu sertifikaadi. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Teie ühendus domeeniga <ph name="DOMAIN" /> on krüpteeritud tänapäevase šifreerimiskomplektiga.</translation>
<translation id="4594403342090139922">&amp;Võta kustutamine tagasi</translation>
<translation id="4619615317237390068">Muudest seadmetest pärinevad vahelehed</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, selle turvasertifikaat sisaldab vigu. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
+<translation id="4690462567478992370">Lõpeta kehtetu sertifikaadi kasutamine</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Teie ühendus katkes</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windowsi võrgudiagnostika käitamine<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Tekkis tundmatu viga.</translation>
<translation id="4800132727771399293">Kontrollige aegumiskuupäeva ja CVC-d ning proovige uuesti</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest veebisait saatis tagasi arusaamatud mandaadid, mida Google Chrome ei saa töödelda. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht tõenäoliselt hiljem töötab.</translation>
<translation id="4813512666221746211">Võrgu viga</translation>
<translation id="4816492930507672669">Sobita lehele</translation>
<translation id="483020001682031208">Kuvamiseks pole ühtegi füüsilise veebi lehte</translation>
<translation id="4850886885716139402">Kuva</translation>
<translation id="4854362297993841467">See kohaletoimetamisviis pole saadaval. Proovige mõnda teist kohaletoimetamisviisi.</translation>
<translation id="4858792381671956233">Küsisite oma vanematelt, kas võite seda lehte külastada</translation>
+<translation id="4863764087567530506">See sisu võib meelitada teid installima tarkvara või avaldama isiklikke andmeid. <ph name="BEGIN_LINK" />Kuva ikkagi<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Otsi ajaloost</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ja veel 1 veebileht}other{ja veel # veebilehte}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Leht on tõlgitud teadmata keelest <ph name="LANGUAGE_LANGUAGE" /> keelde</translation>
<translation id="4923459931733593730">Makse</translation>
<translation id="4926049483395192435">Tuleb määrata.</translation>
<translation id="495170559598752135">Toimingud</translation>
<translation id="4958444002117714549">Laienda loendit</translation>
-<translation id="4962322354953122629">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Chrome ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Luba hoiatused uuesti</translation>
<translation id="4989809363548539747">Seda pistikprogrammi ei toetata</translation>
<translation id="5002932099480077015">Kui see on lubatud, salvestab Chrome teie kaardi koopia vormide kiiremini täitmiseks sellesse seadmesse.</translation>
<translation id="5018422839182700155">Seda lehte ei saa avada</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Tutvuge administraatori reeglitega</translation>
<translation id="5029568752722684782">Kustuta koopia</translation>
<translation id="5031870354684148875">Teave Google'i tõlke kohta</translation>
+<translation id="5039804452771397117">Luba</translation>
<translation id="5040262127954254034">Privaatsus</translation>
<translation id="5045550434625856497">Vale salasõna</translation>
<translation id="5056549851600133418">Teile soovitatud artiklid</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Kontrollige puhverserveri aadressi<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Küpsisefaile pole}=1{1 sait kasutab küpsisefaile. }other{# saiti kasutab küpsisefaile. }}</translation>
<translation id="5087286274860437796">Serveri sertifikaat pole praegu kehtiv.</translation>
<translation id="5087580092889165836">Lisa kaart</translation>
<translation id="5089810972385038852">Osariik</translation>
+<translation id="5094747076828555589">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, Chromium ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="5095208057601539847">Provints</translation>
<translation id="5115563688576182185">(64-bitine)</translation>
<translation id="5141240743006678641">Krüpteerige sünkroonitud paroolid oma Google'i mandaadiga</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-posti aadress on nõutav</translation>
<translation id="5251803541071282808">Pilv</translation>
<translation id="5277279256032773186">Kas kasutate Chrome'i tööl? Ettevõtted võivad hallata töötajate Chrome'i seadeid. Lisateave</translation>
+<translation id="5297526204711817721">Teie ühendus saidiga ei ole privaatne. VR-režiimist väljumiseks võite igal ajal eemaldada peakomplekti ja vajutada tagasinuppu.</translation>
<translation id="5299298092464848405">Reegli sõelumisel ilmnes viga</translation>
-<translation id="5300589172476337783">Kuva</translation>
<translation id="5308689395849655368">Krahhide aruandlus on keelatud.</translation>
<translation id="5317780077021120954">Salvesta</translation>
<translation id="5327248766486351172">Nimi</translation>
-<translation id="5337705430875057403">Ründajad saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> võivad teid meelitada ohtlikele tegevustele, nagu tarkvara installimine või isiklike andmete avaldamine (nt paroolid, telefoninumbrid või krediitkaardid).</translation>
-<translation id="5359637492792381994">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat on praegu kehtetu. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest selle sertifikaat on tühistatud. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht tõenäoliselt hiljem töötab.</translation>
<translation id="536296301121032821">Reegli seadete talletamine ebaõnnestus</translation>
<translation id="5386426401304769735">Selle saidi sertifikaadiahel sisaldab sertifikaati, mis on allkirjastatud SHA-1-ga.</translation>
<translation id="5402410679244714488">Aegub: <ph name="EXPIRATION_DATE_ABBR" />, viimati kasutati üle aasta tagasi</translation>
+<translation id="540969355065856584">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />; selle turvasertifikaat pole praegu kehtiv. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
<translation id="5421136146218899937">Sirvimisandmete kustutamine ...</translation>
<translation id="5430298929874300616">Järjehoidja eemaldamine</translation>
<translation id="5431657950005405462">Teie faili ei leitud</translation>
-<translation id="5435775191620395718">Kuvatakse ajalugu sellest seadmest. <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Skeemi valideerimise viga asukohas „<ph name="ERROR_PATH" />â€: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Hosti <ph name="HOST_NAME" /> lehte ei leita</translation>
<translation id="5455374756549232013">Reegli ajatempel on sobimatu</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> / <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Kehtetu</translation>
<translation id="5470861586879999274">&amp;Muuda uuesti</translation>
<translation id="54817484435770891">Sisestage sobiv aadress</translation>
<translation id="5492298309214877701">Sellel ettevõtte, organisatsiooni või kooli intranetis oleval saidil on sama URL mis välisel veebisaidil.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Sellelt aadressilt ei saa kaupa kätte. Valige mõni teine aadress.</translation>
<translation id="5572851009514199876">Alustage ja logige Chrome'i sisse, et Chrome saaks kontrollida, kas teil on luba sellele saidile juurdepääsemiseks.</translation>
<translation id="5580958916614886209">Kontrollige aegumiskuud ja proovige uuesti</translation>
+<translation id="5586446728396275693">Salvestatud aadresse pole</translation>
+<translation id="5595485650161345191">Muuda aadressi</translation>
<translation id="560412284261940334">Haldust ei toetata</translation>
<translation id="5610142619324316209">Kontrollige ühendust</translation>
<translation id="5610807607761827392">Kaarte ja aadresse saate hallata menüüs <ph name="BEGIN_LINK" />Seaded<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Kas soovite sellelt saidilt lahkuda?</translation>
<translation id="5629630648637658800">Reegli seadete laadimine ebaõnnestus</translation>
<translation id="5631439013527180824">Seadme halduse luba on kehtetu</translation>
+<translation id="5633066919399395251">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> olevad ründajad võivad proovida installida teie arvutisse ohtlikke programme, mis varastavad teie teavet või kustutavad selle (nt fotod, paroolid, sõnumid ja krediitkaarditeave). <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Asukoht</translation>
+<translation id="5659593005791499971">Meil</translation>
<translation id="5669703222995421982">Isikupärastatud sisu hankimine</translation>
<translation id="5675650730144413517">See leht ei tööta</translation>
-<translation id="5677928146339483299">Blokeeritud</translation>
-<translation id="5694783966845939798">Püüdsite jõuda domeenile <ph name="DOMAIN" />, kuid server esitas sertifikaadi, mis on allkirjastatud nõrga allkirjaalgoritmiga (nt SHA-1). See tähendab, et serveri esitatud turvamandaadid võivad olla võltsitud ja tegemist ei pruugi olla õige serveriga (võimalik, et suhtlete ründajaga). <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Selle veebisaidi identiteeti pole kinnitanud.</translation>
+<translation id="5713016350996637505">Petlik sisu blokeeriti</translation>
<translation id="5720705177508910913">Praegune kasutaja</translation>
<translation id="5732392974455271431">Vanemad saavad blokeeringu teie eest tühistada</translation>
<translation id="5763042198335101085">Sisestage kehtiv e-posti aadress</translation>
<translation id="5765072501007116331">Kohaletoimetamisviiside ja nõuete nägemiseks valige aadress</translation>
+<translation id="5778550464785688721">MIDI-seadmete täielik juhtimine</translation>
<translation id="5784606427469807560">Kaardi kinnitamisel tekkis probleem. Kontrollige Interneti-ühendust ja proovige uuesti.</translation>
<translation id="5785756445106461925">Lisaks sisaldab see leht teisi ressursse, mis pole turvalised. Edastamise ajal võivad ressursse vaadata ka teised ja ründajad saavad lehe välimuse muutmiseks ressursse muuta.</translation>
<translation id="5786044859038896871">Kas soovite sisestada oma kaarditeabe?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Lisa uuesti</translation>
<translation id="5814352347845180253">Võite kaotada juurdepääsu saidi <ph name="SITE" /> ja mõnede muude saitide tasulisele sisule.</translation>
<translation id="5838278095973806738">Te ei tohiks sellele saidile sisestada tundlikku teavet (nt paroolid või krediitkaardid), kuna ründajad võivad selle varastada.</translation>
-<translation id="5843436854350372569">Proovisite jõuda domeenile <ph name="DOMAIN" />, kuid server esitas nõrka võtit sisaldava sertifikaadi. Võimalik, et ründaja on privaatvõtme lahti murdnud ja tegemist ei pruugi olla oodatud serveriga (võib-olla suhtlete ründajaga). <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Selle saidiga ei saa ühendust</translation>
<translation id="5869522115854928033">Salvestatud paroolid</translation>
<translation id="5872918882028971132">Vanema soovitused</translation>
<translation id="5901630391730855834">Kollane</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sünkroonitud)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 on kasutusel}other{# on kasutusel}}</translation>
<translation id="5926846154125914413">Võite kaotada juurdepääsu mõnede saitide tasulisele sisule.</translation>
<translation id="5959728338436674663">Saatke Google'ile automaatselt <ph name="BEGIN_WHITEPAPER_LINK" />süsteemiteavet ja lehe sisu<ph name="END_WHITEPAPER_LINK" />, et aidata tuvastada ohtlikke rakendusi ja saite. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Nädal</translation>
<translation id="5967867314010545767">Eemalda ajaloost</translation>
<translation id="5975083100439434680">Suumib välja</translation>
<translation id="598637245381783098">Makserakendust ei saa avada</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Lk 1}other{Lk #}}</translation>
<translation id="6017514345406065928">Roheline</translation>
+<translation id="6017850046339264347">Ründajad saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> võivad installida petlikke rakendusi, mis esinevad millegi muuna või koguvad andmeid, mida võidakse kasutada teie jälgimiseks. <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sünkroonitud)</translation>
<translation id="6027201098523975773">Sisestage nimi</translation>
<translation id="6040143037577758943">Sulge</translation>
<translation id="6042308850641462728">Rohkem</translation>
+<translation id="6047233362582046994">Kui mõistate, kuidas see teie turvalisust ohustab, siis võite <ph name="BEGIN_LINK" />seda saiti külastada<ph name="END_LINK" /> enne, kui kahjulikud rakendused on eemaldatud.</translation>
+<translation id="6051221802930200923">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest veebisait kasutab sertifikaadi kinnitamist. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht tõenäoliselt hiljem töötab.</translation>
<translation id="6060685159320643512">Ettevaatust, need katsed võivad hammustada.</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{mitte ühtegi}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Olete sisule juurde pääsenud administraatori antud sertifikaadiga. Administraator saab domeenile <ph name="DOMAIN" /> edastatavaid andmeid kinni pidada.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ühtegi}=1{1 parool (sünkroonitud)}other{# parooli (sünkroonitud)}}</translation>
<translation id="6146055958333702838">Kontrollige kaableid ning taaskäivitage kõik ruuterid, modemid ja muud
kasutuses olevad võrguseadmed.</translation>
<translation id="614940544461990577">Proovige järgmist.</translation>
<translation id="6151417162996330722">Serveri sertifikaadi kehtivusaeg on liiga pikk.</translation>
<translation id="6157877588268064908">Tarneviiside ja nõuete nägemiseks valige aadress</translation>
+<translation id="6158003235852588289">Google'i ohutu sirvimise teenus tuvastas hiljuti andmepüügi saidil <ph name="SITE" />. Andmepüügi saidid teesklevad teie petmiseks, et tegemist on teise saidiga.</translation>
<translation id="6165508094623778733">Lisateave</translation>
+<translation id="6169916984152623906">Nüüd saate sirvida privaatselt ja teised seadme kasutajad ei näe teie tegevusi. Allalaaditud failid ja järjehoidjad siiski salvestatakse.</translation>
<translation id="6177128806592000436">Teie ühendus selle saidiga pole turvaline</translation>
<translation id="6184817833369986695">(rühm: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Kontrollige Interneti-ühendust</translation>
<translation id="6218753634732582820">Kas eemaldada Chromiumist aadress?</translation>
+<translation id="6221345481584921695">Google'i ohutu sirvimise teenus <ph name="BEGIN_LINK" />tuvastas hiljuti pahavara<ph name="END_LINK" /> saidil <ph name="SITE" />. Tavaliselt turvalisi veebisaite võidakse mõnikord nakatada pahavaraga. Pahatahtlik sisu pärineb hostilt <ph name="SUBRESOURCE_HOST" />, mis on tuntud pahavara levitaja.</translation>
<translation id="6251924700383757765">Privaatsuseeskirjad</translation>
<translation id="6254436959401408446">Selle lehe avamiseks pole piisavalt mälu</translation>
<translation id="625755898061068298">Otsustasite turvahoiatused selle saidi puhul keelata.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Muuda järjehoidjat</translation>
<translation id="6410264514553301377">Sisestage krediitkaardi <ph name="CREDIT_CARD" /> aegumiskuupäev ja CVC</translation>
<translation id="6414888972213066896">Küsisite vanemalt, kas võite seda saiti külastada</translation>
-<translation id="6416403317709441254">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest veebisait saatis šifreeritud mandaadi, mida Chromium ei saa töödelda. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht on tõenäoliselt hiljem töökorras. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Ei saa kontrollida sertifikaadi võimalikku tühistamist.</translation>
<translation id="6433490469411711332">Kontaktandmete muutmine</translation>
<translation id="6433595998831338502">Host <ph name="HOST_NAME" /> keeldus ühendamast.</translation>
<translation id="6446608382365791566">Lisateabe lisamine</translation>
+<translation id="6447842834002726250">Küpsised</translation>
<translation id="6451458296329894277">Kinnita vormi uuestiesitamist</translation>
<translation id="6456339708790392414">Teie makse</translation>
<translation id="6458467102616083041">Seda eiratakse, kuna vaikeotsing on reegliga keelatud.</translation>
-<translation id="6462969404041126431">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Selle turvasertifikaat on võib-olla tühistatud. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Seadme reeglid</translation>
<translation id="6477321094435799029">Chrome tuvastas sellel lehel ebatavalise koodi ja blokeeris selle, et teie isiklikke andmeid (nt paroolid, telefoninumbrid ja krediitkaardiandmed) kaitsta.</translation>
<translation id="6489534406876378309">Krahhide üleslaadimise alustamine</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Aegub: <ph name="EXPIRATION_DATE_ABBR" />. Viimati kasutati kuupäeval <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Haldur ei ole seda veel kinnitanud</translation>
<translation id="6569060085658103619">Vaatate laienduse lehte</translation>
-<translation id="6593753688552673085">vähem kui <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">See sisu võib üritada installida teie seadmesse ohtlikku tarkvara, mis teie teavet varastab või selle kustutab. <ph name="BEGIN_LINK" />Kuva ikkagi<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Krüpteerimise valikud</translation>
<translation id="662080504995468778">Jää siia</translation>
<translation id="6626291197371920147">Kehtiva kaardinumbri lisamine</translation>
<translation id="6628463337424475685"><ph name="ENGINE" />'i otsing</translation>
+<translation id="6630809736994426279">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> olevad ründajad võivad proovida installida teie Maci ohtlikke programme, mis varastavad teie teavet või kustutavad selle (nt fotod, paroolid, sõnumid ja krediitkaarditeave). <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">See reegel on aegunud.</translation>
-<translation id="6652240803263749613">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Teie arvuti operatsioonisüsteem ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Kas eemaldada Chromiumist vormi soovitus?</translation>
<translation id="6685834062052613830">Logige välja ja viige seadistus lõpule</translation>
<translation id="6710213216561001401">Eelmine</translation>
<translation id="6710594484020273272">&lt;Sisestage otsingutermin&gt;</translation>
<translation id="6711464428925977395">Puhverserveriga on midagi valesti või aadress on vale.</translation>
<translation id="6727102863431372879">Määra</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{mitte ühtegi}=1{1 üksus}other{# üksust}}</translation>
<translation id="674375294223700098">Serveri sertifikaadi tundmatu viga.</translation>
<translation id="6753269504797312559">Reegli väärtus</translation>
<translation id="6757797048963528358">Teie seade lülitus unerežiimile.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Kohandamise ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Piirkondade andmete laadimine ebaõnnestus</translation>
+<translation id="6825578344716086703">Püüdsite jõuda domeenile <ph name="DOMAIN" />, kuid server esitas sertifikaadi, mis on allkirjastatud nõrga allkirjaalgoritmiga (nt SHA-1). See tähendab, et serveri esitatud turvamandaadid võivad olla võltsitud ja server ei pruugi olla see, mida eeldate (võimalik, et suhtlete ründajaga).</translation>
+<translation id="6830728435402077660">Pole turvaline</translation>
<translation id="6831043979455480757">Tõlgi</translation>
<translation id="6839929833149231406">Piirkond</translation>
<translation id="6874604403660855544">&amp;Lisa uuesti</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Teie kaart on kinnitatud</translation>
<translation id="6897140037006041989">Kasutajaagent</translation>
<translation id="6915804003454593391">Kasutaja:</translation>
+<translation id="6945221475159498467">Vali</translation>
<translation id="6948701128805548767">Kättesaamisviiside ja nõuete nägemiseks valige aadress</translation>
<translation id="6957887021205513506">Serveri sertifikaat näib olevat võltsing.</translation>
<translation id="6965382102122355670">Ok</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Määratud on nii fikseeritud puhverserverid kui ka pac-skriptiga URL.</translation>
<translation id="6989763994942163495">Kuva täpsemad seaded ...</translation>
<translation id="7000990526846637657">Ajalookirjeid ei leitud</translation>
-<translation id="7009986207543992532">Püüdsite jõuda domeenile <ph name="DOMAIN" />, ent server esitas sertifikaadi, mille kehtivusperiood on liiga pikk, et olla usaldusväärne. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">Hiina UnionPay</translation>
<translation id="7012372675181957985">Aadressil <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> võib teie Google'i kontol olla muus vormis sirvimisajalugu</translation>
<translation id="7029809446516969842">Paroolid</translation>
+<translation id="7050187094878475250">Üritasite jõuda domeenile <ph name="DOMAIN" />, kuid server esitas sertifikaadi, mille kehtivusaeg on liiga pikk, et olla usaldusväärne.</translation>
+<translation id="7053983685419859001">Blokeeri</translation>
<translation id="7064851114919012435">Kontaktteave</translation>
<translation id="7079718277001814089">See sait sisaldab pahavara</translation>
<translation id="7087282848513945231">Maakond</translation>
-<translation id="7088615885725309056">Vanemad</translation>
<translation id="7090678807593890770">Sisestage Google'isse otsing <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Lubas laiendus</translation>
<translation id="7119414471315195487">Sulgege muud vahelehed või programmid</translation>
<translation id="7129409597930077180">Sellele aadressile ei saa tarnida. Valige mõni teine aadress.</translation>
<translation id="7138472120740807366">Kohaletoimetamisviis</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Töötlemine</translation>
<translation id="724691107663265825">Avatav veebisait sisaldab pahavara</translation>
<translation id="724975217298816891">Kaardi üksikasjade värskendamiseks sisestage krediitkaardi <ph name="CREDIT_CARD" /> aegumiskuupäev ja CVC. Kui selle kinnitate, jagatakse teie kaardi üksikasju selle saidiga.</translation>
-<translation id="725866823122871198">Privaatset ühendust ei saa domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> luua, kuna arvuti kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />) on valed.</translation>
+<translation id="7260504762447901703">Juurdepääsu tühistamine</translation>
<translation id="7275334191706090484">Hallatud järjehoidjad</translation>
<translation id="7298195798382681320">Soovitatud</translation>
<translation id="7309308571273880165">Krahhiaruanne jäädvustati ajal <ph name="CRASH_TIME" /> (kasutaja taotles üleslaadimist; pole veel üles laaditud)</translation>
<translation id="7334320624316649418">&amp;Korrasta uuesti</translation>
<translation id="733923710415886693">Serveri sertifikaati ei avalikustatud sertifikaadi läbipaistvuse reegli kaudu.</translation>
-<translation id="7351800657706554155">Te ei saa saiti <ph name="SITE" /> praegu külastada, sest selle sertifikaat on tühistatud. Võrguvead ja -rünnakud on tavaliselt ajutised, nii et leht on tõenäoliselt hiljem töökorras. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Käsurida</translation>
<translation id="7372973238305370288">otsingutulemus</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ei</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Kaardi kinnitamine</translation>
-<translation id="7394102162464064926">Kas soovite kindlasti need lehed ajaloost kustutada?
-
-Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks osutuda.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Profiili tee</translation>
<translation id="7424977062513257142">Selle veebilehe manustatud leht ütleb:</translation>
@@ -688,6 +754,7 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="7444046173054089907">See sait on blokeeritud</translation>
<translation id="7445762425076701745">Serveri identiteeti, millega olete ühenduses, ei saa täielikult valideerida. Olete ühenduses serveriga nime abil, mis kehtib ainult teie võrgus, mistõttu ei saa väline sertifitseerimisorgan selle omandiõigust valideerida. Kuna mõni sertifitseerimisorgan väljastab sertifikaate hoolimata nende nimedest, puudub igasugune võimalus tagada, et olete ühenduses soovitud veebisaidi, mitte ründajaga.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Vaadake lisateavet<ph name="END_LINK" /> probleemi kohta.</translation>
+<translation id="7455133967321480974">Kasuta globaalset vaikeseadet (blokeeri)</translation>
<translation id="7460163899615895653">Siin kuvatakse teie hiljutised vahelehed teistest seadmetest</translation>
<translation id="7469372306589899959">Kaarti kinnitatakse</translation>
<translation id="7481312909269577407">Edasta</translation>
@@ -695,36 +762,43 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="7508255263130623398">Tagastatud reegli seadme-ID on tühi või ei kattu praeguse seadme-ID-ga</translation>
<translation id="7514365320538308">Laadi alla</translation>
<translation id="7518003948725431193">Järgneval veebiaadressil ei olnud ühtegi veebilehte: <ph name="URL" /></translation>
+<translation id="7521387064766892559">Javascript</translation>
<translation id="7535087603100972091">Väärtus</translation>
<translation id="7537536606612762813">Kohustuslik</translation>
+<translation id="7542403920425041731">Kui selle kinnitate, jagatakse teie kaardi üksikasju selle saidiga.</translation>
<translation id="7542995811387359312">Automaatne krediitkaardi täide on keelatud, sest see vorm ei kasuta turvalist ühendust.</translation>
<translation id="7543525346216957623">Küsige vanematelt abi</translation>
<translation id="7549584377607005141">See veebileht vajab korralikult kuvamiseks varem sisestatud andmeid. Võite need andmed uuesti saata, kuid seda tehes kordate lehe iga eelnevat toimingut.</translation>
<translation id="7552846755917812628">Proovige järgmiseid nõuandeid.</translation>
<translation id="7554791636758816595">Uus vaheleht</translation>
+<translation id="7567204685887185387">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, selle turvasertifikaat võib olla väljastatud pettuse teel. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">See leht on keeles<ph name="ORIGINAL_LANGUAGE" />Kas soovite seda tõlkida?</translation>
<translation id="7569952961197462199">Kas eemaldada Chrome'ist krediitkaart?</translation>
<translation id="7569983096843329377">Must</translation>
<translation id="7578104083680115302">Google'i salvestatud kaartide abil saate eri seadmetes saitidel ja rakendustes kiirelt maksta.</translation>
<translation id="7588950540487816470">Füüsiline veeb</translation>
<translation id="7592362899630581445">Serveri sertifikaat rikub nime piiranguid.</translation>
+<translation id="7598391785903975535">Alla <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Host <ph name="HOST_NAME" /> ei saa praegu seda taotlust töödelda.</translation>
<translation id="7600965453749440009">Ära kunagi tõlgi: <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Väärtus on vahemikust (<ph name="VALUE" />) väljaspool.</translation>
<translation id="7613889955535752492">Aegub: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Teil on juba andmed, mis on krüpteeritud Google'i konto parooli teise versiooniga. Sisestage see allpool.</translation>
-<translation id="7634554953375732414">Teie ühendus selle saidiga pole privaatne.</translation>
<translation id="7637571805876720304">Kas eemaldada Chromiumist krediitkaart?</translation>
<translation id="765676359832457558">Peida täpsemad seaded ...</translation>
<translation id="7658239707568436148">Tühista</translation>
+<translation id="7662298039739062396">Seadet juhib laiendus</translation>
<translation id="7667346355482952095">Tagastatud reegli luba on tühi või ei kattu praeguse loaga</translation>
<translation id="7668654391829183341">Tundmatu seade</translation>
<translation id="7669271284792375604">Sellel saidil asuvad ründajad võivad proovida meelitada teid installima programme, mis kahjustavad sirvimiskogemust (nt muudavad avalehte või kuvavad külastatavatel saitidel lisareklaame).</translation>
<translation id="7674629440242451245">Kas olete huvitatud Chrome'i uutest lahedatest funktsioonidest? Proovige meie arenduskanalit aadressil chrome.com/beta.</translation>
<translation id="7682287625158474539">Kohaletoimetamine</translation>
+<translation id="7701040980221191251">Mitte ükski</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Edasiliikumine saidile <ph name="SITE" /> (ebaturvaline)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Sertifikaat</translation>
+<translation id="7716147886133743102">Blokeeris administraator</translation>
<translation id="7716424297397655342">Seda saiti ei saa vahemälust laadida</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Haldamata</translation>
<translation id="7755287808199759310">Vanem saab blokeeringu teie eest tühistada</translation>
<translation id="7758069387465995638">Tulemüür või viirusetõrjetarkvara võis ühenduse blokeerida.</translation>
@@ -751,15 +825,15 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="7951415247503192394">(32-bitine)</translation>
<translation id="7956713633345437162">Mobiili järjehoidjad</translation>
<translation id="7961015016161918242">Mitte kunagi</translation>
-<translation id="7962083544045318153">Krahhi ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Tõlgi alati keelest <ph name="ORIGINAL_LANGUAGE" /> keelde <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ei ole määratud</translation>
<translation id="800218591365569300">Sulgege muud vahelehed või programmid, et mälu vabastada.</translation>
<translation id="8012647001091218357">Teie vanematega ei õnnestunud praegu ühendust võtta. Proovige hiljem uuesti.</translation>
<translation id="8025119109950072390">Sellel saidil asuvad ründajad võivad teid meelitada ohtlikele tegevustele, nagu tarkvara installimine või isiklike andmete (nt paroolid, telefoninumbrid või krediitkaardid) avaldamine.</translation>
-<translation id="803030522067524905">Google'i ohutu sirvimise teenus tuvastas hiljuti andmepüügi saidil <ph name="SITE" />. Andmepüügisaidid esitavad end teiste saitidena, et teid petta. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Leht on <ph name="SOURCE_LANGUAGE" /> keeles. Kas tõlkida <ph name="TARGET_LANGUAGE" /> keelde?</translation>
+<translation id="8037357227543935929">Küsi (vaikimisi)</translation>
<translation id="8041089156583427627">Saada tagasiside</translation>
+<translation id="8041940743680923270">Kasuta globaalset vaikeseadet (küsi)</translation>
<translation id="8088680233425245692">Artikli kuvamine ebaõnnestus.</translation>
<translation id="8089520772729574115">vähem kui 1 MB</translation>
<translation id="8091372947890762290">Aktiveerimine on serveris ootel</translation>
@@ -768,13 +842,14 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="8134994873729925007">Hosti <ph name="HOST_NAME" /> serveri <ph name="BEGIN_ABBR" />DNS-aadressi<ph name="END_ABBR" /> ei leitud.</translation>
<translation id="8149426793427495338">Teie arvuti lülitus unerežiimile.</translation>
<translation id="8150722005171944719">Fail <ph name="URL" /> ei ole loetav. Võimalik, et see on eemaldatud, teisaldatud või faili load takistavad juurdepääsu.</translation>
+<translation id="8184538546369750125">Kasuta globaalset vaikeseadet (luba)</translation>
+<translation id="8191494405820426728">Kohaliku krahhi ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Võta teisaldamine tagasi</translation>
<translation id="8201077131113104583">ID-ga „<ph name="EXTENSION_ID" />†laienduse kehtetu värskendamise URL.</translation>
<translation id="8202097416529803614">Tellimuse kokkuvõte</translation>
<translation id="8218327578424803826">Määratud asukoht:</translation>
<translation id="8225771182978767009">Arvuti seadistanud inimene blokeeris selle saidi.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> olevad ründajad võivad proovida installida teie arvutisse ohtlikke programme, mis varastavad teie teavet või kustutavad selle (nt fotod, paroolid, sõnumid ja krediitkaardiandmed).</translation>
<translation id="8241707690549784388">Teie poolt otsitav lehekülg kasutas teie sisestatud andmeid. Sellele leheküljele naasmine võib kaasa tuua kõikide sooritatud tegevuste kordamise. Soovite jätkata?</translation>
<translation id="8249320324621329438">Viimati toodud:</translation>
<translation id="8253091569723639551">Arveldusaadress on nõutav</translation>
@@ -782,6 +857,7 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="8289355894181816810">Kui te pole kindel, mida see tähendab, võtke ühendust oma võrguadministraatoriga.</translation>
<translation id="8293206222192510085">Lisa järjehoidja</translation>
<translation id="8294431847097064396">Allikas</translation>
+<translation id="8306404619377842860">Domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei saa privaatset ühendust luua, kuna seadme kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />) on valed. <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Tõlkimine ebaõnnestus võrguühenduse probleemi tõttu.</translation>
<translation id="8332188693563227489">Juurdepääs hostile <ph name="HOST_NAME" /> blokeeriti</translation>
<translation id="834457929814110454">Kui mõistate, kuidas teie turvalisust ohustatakse, siis võite <ph name="BEGIN_LINK" />seda saiti külastada<ph name="END_LINK" /> enne, kui kahjulikud programmid on eemaldatud.</translation>
@@ -802,11 +878,9 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="8483780878231876732">Google'i konto kaartide kasutamiseks logige sisse Chrome'i</translation>
<translation id="8488350697529856933">Kehtib:</translation>
<translation id="8498891568109133222">Hostil <ph name="HOST_NAME" /> kulus vastamiseks liiga kaua aega.</translation>
-<translation id="852346902619691059">Server ei suutnud tõestada, et tegemist on domeeniga <ph name="DOMAIN" />. Teie seadme operatsioonisüsteem ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või teie ühendust segav ründaja. <ph name="BEGIN_LEARN_MORE_LINK" />Vaadake lisateavet<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Aegumisaasta</translation>
<translation id="8543181531796978784">Võite <ph name="BEGIN_ERROR_LINK" />teavitada tuvastusprobleemist<ph name="END_ERROR_LINK" />. Kui mõistate ohtusid oma turvalisusele, võite <ph name="BEGIN_LINK" />seda ebaturvalist saiti külastada<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Tõlkimine nurjus, kuna lehe keelt ei õnnestunud määrata.</translation>
-<translation id="8559762987265718583">Privaatset ühendust ei saa domeeniga <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> luua, kuna seadme kuupäev ja kellaaeg (<ph name="DATE_AND_TIME" />) on valed.</translation>
<translation id="8571890674111243710">Lehe tõlkimine <ph name="LANGUAGE" /> keelde...</translation>
<translation id="858637041960032120">Lisage telefoninumber</translation>
<translation id="859285277496340001">Sertifikaat ei määratle mehhanismi enda võimaliku tühistamise kontrollimiseks.</translation>
@@ -820,6 +894,7 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="8738058698779197622">Turvalise ühenduse loomiseks peab kell olema õigesti seadistatud. See on nii, kuna sertifikaadid, mida veebisaidid kasutavad enda tuvastamiseks, kehtivad ainult teatud perioodi jooksul. Kuna teie seadme kell on vale, ei saa Chromium neid sertifikaate kinnitada.</translation>
<translation id="8740359287975076522">Hosti <ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;DNS-aadressi&lt;/abbr&gt; ei leitud. Probleemi diagnoositakse.</translation>
<translation id="8759274551635299824">See kaart on aegunud</translation>
+<translation id="8761567432415473239">Google'i ohutu sirvimine <ph name="BEGIN_LINK" />tuvastas hiljuti kahjulikud programmid<ph name="END_LINK" /> saidil <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Kustuta uuesti</translation>
<translation id="8800988563907321413">Teie lähedalasuvad soovitused kuvatakse siin</translation>
<translation id="8820817407110198400">Järjehoidjad</translation>
@@ -832,29 +907,30 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="8870413625673593573">Viimati suletud</translation>
<translation id="8874824191258364635">Sisestaeg kehtiv kaardinumber</translation>
<translation id="8876793034577346603">Võrgu seadistust ei õnnestunud sõeluda.</translation>
-<translation id="8877192140621905067">Kui selle kinnitate, jagatakse teie kaardi üksikasju selle saidiga</translation>
<translation id="8889402386540077796">Värvitoon</translation>
<translation id="8891727572606052622">Kehtetu puhverserveri režiim.</translation>
<translation id="889901481107108152">Kahjuks ei ole see eksperiment teie platvormil saadaval.</translation>
<translation id="8903921497873541725">Suurendab</translation>
<translation id="8931333241327730545">Kas soovite selle kaardi salvestada oma Google'i kontole?</translation>
<translation id="8932102934695377596">Teie kell on taga</translation>
-<translation id="8954894007019320973">(Jätkub)</translation>
<translation id="8971063699422889582">Serveri sertifikaat on aegunud.</translation>
<translation id="8986494364107987395">Saada kasutusstatistika ja krahhiaruanded automaatselt Google'ile</translation>
-<translation id="8987927404178983737">kuu</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Sait, mille soovite avada, sisaldab kahjulikke programme</translation>
+<translation id="8997023839087525404">Server esitas sertifikaadi, mida ei ole sertifikaadi läbipaistvuse reegli kohaselt avalikustatud. See on teatud sertifikaatide puhul nõutav, et need oleksid usaldusväärsed ja kaitseksid ründajate eest.</translation>
<translation id="9001074447101275817">Puhverserver <ph name="DOMAIN" /> nõuab kasutajanime ja parooli.</translation>
+<translation id="9005998258318286617">PDF-dokumendi laadimine ebaõnnestus.</translation>
<translation id="901974403500617787">Kogu süsteemis kehtivaid märgiseid saab määrata ainult omanik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Kaardi arveldusaadress on nõutav</translation>
<translation id="9020542370529661692">See leht on tõlgitud <ph name="TARGET_LANGUAGE" /> keelde</translation>
<translation id="9035022520814077154">Turvaviga</translation>
<translation id="9038649477754266430">Kasuta lehtede kiiremaks laadimiseks ennustusteenust</translation>
<translation id="9039213469156557790">Lisaks sisaldab see leht teisi ressursse, mis pole turvalised. Edastamise ajal võivad ressursse vaadata ka teised ja ründajad saavad lehe käitumise muutmiseks ressursse muuta.</translation>
-<translation id="9040185888511745258">Saidil <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> asuvad ründajad võivad proovida meelitada teid installima programme, mis kahjustavad sirvimiskogemust (nt muudavad avalehte või kuvavad külastatavatel saitidel lisareklaame).</translation>
+<translation id="9049981332609050619">Proovisite jõuda domeenile <ph name="DOMAIN" />, kuid server esitas kehtetu sertifikaadi.</translation>
<translation id="9050666287014529139">Parool</translation>
<translation id="9065203028668620118">Muuda</translation>
<translation id="9068849894565669697">Värvi valimine</translation>
+<translation id="9069693763241529744">Blokeeris laiendus</translation>
<translation id="9076283476770535406">See võib sisaldada täiskasvanutele mõeldud sisu</translation>
<translation id="9078964945751709336">Vaja on rohkem teavet</translation>
<translation id="9103872766612412690">Sait <ph name="SITE" /> kasutab teie teabe kaitsmiseks tavaliselt krüpteerimist. Kui Chromium püüdis seekord saidiga <ph name="SITE" /> ühendust luua, tagastas veebisait ebatavalised ja valed mandaadid. See võib juhtuda siis, kui ründaja proovib teeselda, et on sait <ph name="SITE" />, või WiFi sisselogimisekraan on ühenduse katkestanud. Teie teave on endiselt kaitstud, sest Chromium peatas ühenduse enne andmevahetust.</translation>
@@ -863,16 +939,21 @@ Inkognito režiim <ph name="SHORTCUT_KEY" /> võib järgmisel korral kasulikuks
<translation id="9148507642005240123">&amp;Võta muudatus tagasi</translation>
<translation id="9154194610265714752">Värskendatud</translation>
<translation id="9157595877708044936">Seadistamine...</translation>
+<translation id="9169664750068251925">Blokeeri sellel saidil alati</translation>
<translation id="9170848237812810038">&amp;Võta tagasi</translation>
<translation id="917450738466192189">Serveri sertifikaat on kehtetu.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ja veel <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419">Host <ph name="HOST_NAME" /> kasutab toetamata protokolli.</translation>
<translation id="9205078245616868884">Teie andmed on krüpteeritud teie sünkroonimisparooliga. Sisestage see sünkroonimise alustamiseks.</translation>
<translation id="9207861905230894330">Artikli lisamine ebaõnnestus.</translation>
+<translation id="9219103736887031265">Pildid</translation>
<translation id="933612690413056017">Interneti-ühendus puudub</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">TÃœHJENDA VORM</translation>
<translation id="939736085109172342">Uus kaust</translation>
<translation id="941721044073577244">Näib, et teil pole luba selle saidi külastamiseks</translation>
<translation id="969892804517981540">Ametlik järk</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ühtegi}=1{1 üksus}other{# üksust}}</translation>
<translation id="988159990683914416">Arendaja järk</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fa.xtb b/chromium/components/strings/components_strings_fa.xtb
index acefe3e0c0d..77036746cf5 100644
--- a/chromium/components/strings/components_strings_fa.xtb
+++ b/chromium/components/strings/components_strings_fa.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">چرخش در جهت عقربه‌های ساعت</translation>
<translation id="1038842779957582377">نام ناشناس</translation>
<translation id="1050038467049342496">برنامه‌های دیگر را ببندید</translation>
-<translation id="1053591932240354961">â€Ø¯Ø±Ø­Ø§Ù„‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا این وب‌سایت اعتبارنامه‌های درهمی ارسال کرده است Ú©Ù‡ Google Chrome نمی‌تواند آن‌ها را پردازش کند. خطاها Ùˆ حمله‌های شبکه معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;واگرد اÙزودن</translation>
<translation id="10614374240317010">هرگز ذخیره نمی‌شود</translation>
<translation id="106701514854093668">نشانک‌های دسک‌تاپ</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">حاÙظه پنهان خط‌مشی مورد تأیید است</translation>
<translation id="113188000913989374"><ph name="SITE" /> می‌گوید:</translation>
<translation id="1132774398110320017">â€ØªÙ†Ø¸ÛŒÙ…ات تکمیل خودکار Chrome...</translation>
+<translation id="1150979032973867961">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورداعتماد سیستم عامل رایانه شما نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
+<translation id="1151972924205500581">گذرواژه ضروری است</translation>
<translation id="1152921474424827756">دسترسی به یک <ph name="BEGIN_LINK" />نسخه ذخیره شده در حاÙظه پنهان<ph name="END_LINK" /> از <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> به‌طور غیرمنتظره‌ای اتصال را قطع کرد.</translation>
<translation id="1161325031994447685">â€Ø§ØªØµØ§Ù„ مجدد به Wi-Fi</translation>
+<translation id="1165039591588034296">خطا</translation>
<translation id="1175364870820465910">&amp;چاپ...</translation>
<translation id="1181037720776840403">حذÙ</translation>
<translation id="1184214524891303587">â€<ph name="BEGIN_WHITEPAPER_LINK" /> گزارش خودکار <ph name="END_WHITEPAPER_LINK" /> جزئیات حوادث امنیتی احتمالی به Google.†<ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">موارد بیشتر از این سایت</translation>
<translation id="1206967143813997005">امضای اولیه نادرست</translation>
<translation id="1209206284964581585">Ùعلاً پنهان شود</translation>
+<translation id="121201262018556460">شما می‌خواستید به <ph name="DOMAIN" /> دسترسی یابید، اما سرور یک گواهی دارای کلید ضعی٠ارائه داد. یک مهاجم ممکن است کلید خصوصی را تخریب کرده باشد و سرور، همان سروری نباشد که شما انتظار داشتید (ممکن است در حال ارتباط با یک مهاجم باشید).</translation>
<translation id="1219129156119358924">سیستم امنیتی</translation>
<translation id="1227224963052638717">خط‌مشی ناشناس.</translation>
<translation id="1227633850867390598">پنهان کردن مقدار</translation>
<translation id="1228893227497259893">â€Ø´Ù†Ø§Ø³Ù‡ entity نادرست</translation>
<translation id="1232569758102978740">بدون عنوان</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />، <ph name="TYPE_2" /> (همگام‌سازی‌شده)</translation>
<translation id="1263231323834454256">Ùهرست خواندن</translation>
<translation id="1264126396475825575">گزارش خرابی ثبت‌شده در <ph name="CRASH_TIME" /> (هنوز بارگذاری نشده است یا نادیده‌ گرÙته شده است)</translation>
+<translation id="1281526147609854549">صادرشده توسط <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">محتوای خطرناک مسدود شد</translation>
<translation id="1285320974508926690">این سایت هرگز ترجمه نشود</translation>
<translation id="129553762522093515">اخیراً بسته‌شده</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />کوکی‌ها را پاک کنید<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Ùعالیت شما <ph name="BEGIN_EMPHASIS" />ممکن است در موارد زیر قابل‌رؤیت باشد<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />در وب‌سایت‌هایی که بازدید می‌کنید
+ <ph name="LIST_ITEM" />برای کارÙرما یا مدرسه‌‌تان
+ <ph name="LIST_ITEM" />برای ارائه‌دهنده خدمات اینترنت شما
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">دامنه ثبت‌نام:</translation>
<translation id="1340482604681802745">نشانی تحویل گرÙتن کالا</translation>
<translation id="1344211575059133124">گویا برای بازدید این سایت به اجازه نیاز دارید</translation>
<translation id="1344588688991793829">â€ØªÙ†Ø¸ÛŒÙ…ات تکمیل خودکار Chromium...</translation>
+<translation id="1348198688976932919">سایت پیش‌رو حاوی برنامه‌های خطرناک است</translation>
<translation id="1374468813861204354">پیشنهادات</translation>
<translation id="1375198122581997741">درباره نسخه</translation>
<translation id="1377321085342047638">شماره کارت</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> داده‌ای ارسال نکرد.</translation>
<translation id="1407135791313364759">باز کردن همه</translation>
<translation id="1413809658975081374">خطای حریم خصوصی</translation>
+<translation id="14171126816530869">هویت <ph name="ORGANIZATION" /> در <ph name="LOCALITY" /> توسط <ph name="ISSUER" /> تأیید شده است.</translation>
<translation id="1426410128494586442">بله</translation>
<translation id="1430915738399379752">چاپ</translation>
-<translation id="1442912890475371290">تلاش <ph name="BEGIN_LINK" /> برای بازدید از صÙحه‌ای در <ph name="DOMAIN" /><ph name="END_LINK" /> مسدود شد.</translation>
-<translation id="1491663344921578213">درحال‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا این وب‌سایت از پین کردن گواهینامه استÙاده می‌کند. خطاها Ùˆ حمله‌های شبکه معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> روش دیگر}one{<ph name="PAYMENT_METHOD_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> روش دیگر}other{<ph name="PAYMENT_METHOD_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> روش دیگر}}</translation>
<translation id="1506687042165942984">یک نسخه ذخیره‌شده (یعنی قدیمی) از این صÙحه نشان داده شود.</translation>
<translation id="1517433312004943670">شماره تلÙÙ† ضروری است</translation>
<translation id="1519264250979466059">تاریخ ساخت</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">برای استÙاده از این قابلیت، جاوا اسکریپت باید Ùعال باشد.</translation>
<translation id="1555130319947370107">آبی</translation>
<translation id="1559528461873125649">Ùاقد چنین Ùایل یا دایرکتوری است</translation>
-<translation id="1559572115229829303">â€&lt;p&gt;اتصال خصوصی به <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> برقرار نشد، زیرا تاریخ Ùˆ زمان دستگاه شما (<ph name="DATE_AND_TIME" />) نادرست است.&lt;/p&gt;
-
- &lt;p&gt;لطÙاً تاریخ Ùˆ زمان را در بخش &lt;strong&gt;عمومی&lt;/strong&gt; برنامه &lt;strong&gt;تنظیمات&lt;/strong&gt; تنظیم کنید.&lt;/p&gt;</translation>
<translation id="1583429793053364125">هنگام نمایش این صÙحه وب مشکلی پیش آمد.</translation>
<translation id="1592005682883173041">دسترسی داده محلی</translation>
+<translation id="1594030484168838125">انتخاب</translation>
<translation id="161042844686301425">Ùیروزه‌ای</translation>
+<translation id="1620510694547887537">دوربین</translation>
<translation id="1629803312968146339">â€Ù…ی‌خواهید Chrome این کارت را ذخیره کند؟</translation>
<translation id="1639239467298939599">بارگیری</translation>
<translation id="1640180200866533862">خط‌مشی‌های کاربر</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">پیکربندی شبکه نامعتبر است و نتوانست وارد شود.</translation>
<translation id="1644574205037202324">سابقه</translation>
<translation id="1645368109819982629">پروتکل پشتیبانی‌نشده</translation>
+<translation id="1655462015569774233">{1,plural, =1{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است؛ اعتبار گواهی امنیتی آن دیروز به پایان رسیده است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. ساعت رایانه‌تان درحال‌حاضر روی <ph name="CURRENT_DATE" /> تنظیم شده است. آیا درست است؟ اگر پاسخ منÙÛŒ است، باید ساعت سیستمتان را درست کنید Ùˆ سپس این صÙحه را بازخوانی کنید.}one{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است. اعتبار گواهی امنیتی آن # روز قبل به پایان رسیده است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. ساعت رایانه‌تان درحال‌حاضر روی <ph name="CURRENT_DATE" /> تنظیم شده است. آیا درست است؟ اگر پاسخ منÙÛŒ است، باید ساعت سیستمتان را درست کنید Ùˆ سپس این صÙحه را بازخوانی کنید.}other{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است. اعتبار گواهی امنیتی آن # روز قبل به پایان رسیده است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. ساعت رایانه‌تان درحال‌حاضر روی <ph name="CURRENT_DATE" /> تنظیم شده است. آیا درست است؟ اگر پاسخ منÙÛŒ است، باید ساعت سیستمتان را درست کنید Ùˆ سپس این صÙحه را بازخوانی کنید.}}</translation>
<translation id="1656489000284462475">تحویل گرÙتن</translation>
<translation id="1663943134801823270">â€Ú©Ø§Ø±Øªâ€ŒÙ‡Ø§ Ùˆ نشانی‌ها از Chrome‌ هستند. می‌توانید آن‌ها را در <ph name="BEGIN_LINK" />تنظیمات<ph name="END_LINK" /> مدیریت کنید.</translation>
<translation id="1676269943528358898">â€<ph name="SITE" /> معمولاً برای محاÙظت از اطلاعات شما از رمزگذاری استÙاده می‌کند. اما این بار Ú©Ù‡ Chrome تلاش کرد به <ph name="SITE" /> متصل شود، وب‌سایت اعتبارنامه‌ای نامعمول Ùˆ نادرست را برگرداند. ممکن است مهاجمی در تلاش باشد خود را به‌جای <ph name="SITE" /> معرÙÛŒ کند یا یک صÙحه ورود به سیستم Wi-Fi در ارتباط اختلال ایجاد کرده باشد. اطلاعات شما همچنان ایمن است، زیرا Google Chrome قبل از هرگونه تبادل داده، اتصال را متوق٠کرد.</translation>
-<translation id="168328519870909584">مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> درحال‌حاضر ممکن است تلاش کنند تا برنامه‌های خطرناکی در دستگاهتان نصب کنند که اطلاعات شما (مانند کارت‌های اعتباری، عکس‌ها، گذرواژه‌ها و پیام‌هایتان) را سرقت یا حذ٠می‌کنند.</translation>
<translation id="168841957122794586">گواهی‌نامه سرور دارای یک کلید رمزنگاری ضعی٠است.</translation>
+<translation id="1706954506755087368">{1,plural, =1{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است؛ اعتبار گواهی امنیتی آن ظاهراً Ùردا شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند.}one{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است؛ اعتبار گواهی امنیتی آن ظاهراً # روز دیگر شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند.}other{این سرور نتوانست ثابت کند این <ph name="DOMAIN" /> است؛ اعتبار گواهی امنیتی آن ظاهراً # روز دیگر شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">برای بازدید این سایت باید از <ph name="NAME" /> اجازه بگیرید</translation>
<translation id="1721424275792716183">* این Ùیلد اجباری است</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">بارگیری صÙحه در Ùرصت دیگری</translation>
<translation id="17513872634828108">بازکردن برگه‌ها</translation>
<translation id="1753706481035618306">شماره صÙحه</translation>
+<translation id="1763864636252898013">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورداعتماد سیستم عامل دستگاه شما نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
<translation id="1768211456781949159">â€<ph name="BEGIN_LINK" />Windows Network Diagnostics را اجرا کنید<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">لطÙاً «رمز عبارتی همگام‌سازی» خود را به‌روزرسانی کنید.</translation>
<translation id="1787142507584202372">برگه‌های بازتان در اینجا نشان داده می‌شوند</translation>
+<translation id="1789575671122666129">پنجره‌های بازشو</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">نام صاحب کارت</translation>
-<translation id="1803678881841855883">â€Â«Ù…رور ایمن Google» به‌تازگی در <ph name="SITE" />ØŒ â€<ph name="BEGIN_LINK" />بداÙزار شناسایی کرده است<ph name="END_LINK" />. گاهی اوقات وب‌سایت‌هایی Ú©Ù‡ معمولاً امن هستند با بداÙزار آلوده می‌شوند. منبع محتوای مخرب <ph name="SUBRESOURCE_HOST" /> (یک توزیع‌کننده بداÙزار شناخته شده) است. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">تاریخ اضاÙÙ‡ شدن: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">پارامترهای درخواست یا درخواست نامعتبر</translation>
<translation id="1826516787628120939">در حال بررسی</translation>
<translation id="1834321415901700177">این سایت محتوی برنامه‌های مضر است</translation>
+<translation id="1840414022444569775">این شماره کارت قبلاً استÙاده شده است</translation>
<translation id="1842969606798536927">پرداخت</translation>
<translation id="1871208020102129563">â€ØªÙ†Ø¸ÛŒÙ… پروکسی به گونه‌ای است Ú©Ù‡ از سرورهای ثابت پروکسی استÙاده کند Ùˆ از آدرس اسکریپت pac. استÙاده نکند.</translation>
<translation id="1871284979644508959">قسمت الزامی</translation>
<translation id="187918866476621466">باز کردن صÙحه‌های شروع</translation>
<translation id="1883255238294161206">Ú©ÙˆÚ†Ú© کردن Ùهرست</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> نشانی دیگر}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> نشانی دیگر}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> نشانی دیگر}}</translation>
<translation id="1898423065542865115">Ùیلتر کردن</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{هیچ‌کدام}=1{۱ سایت}one{# سایت}other{# سایت}}</translation>
<translation id="194030505837763158">رÙتن به <ph name="LINK" /></translation>
<translation id="1962204205936693436">نشانک‌های <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">خطای ترتیب</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">نادیده گرÙته شد زیرا <ph name="POLICY_NAME" /> آن را لغو می‌کند.</translation>
<translation id="2138201775715568214">در حال جستجوی صÙحات وب Ùیزیکی اطراÙ</translation>
<translation id="213826338245044447">نشانک‌های تلÙن‌ همراه</translation>
-<translation id="2148716181193084225">امروز</translation>
+<translation id="2147827593068025794">همگام‌سازی پس‌زمینه</translation>
<translation id="2154054054215849342">همگام‌سازی برای دامنه شما در دسترس نیست</translation>
<translation id="2154484045852737596">ویرایش کارت</translation>
<translation id="2166049586286450108">دسترسی کامل سرپرست</translation>
<translation id="2166378884831602661">این سایت نمی‌تواند اتصالی ایمن ارائه دهد</translation>
<translation id="2181821976797666341">خط‌ مشی‌ها</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{۱ نشانی}one{# نشانی}other{# نشانی}}</translation>
+<translation id="2187317261103489799">تشخیص (پیش‌Ùرض)</translation>
<translation id="2202020181578195191">سال انقضای معتبری وارد کنید</translation>
<translation id="2212735316055980242">خط‌مشی یاÙت نشد</translation>
<translation id="2213606439339815911">در حال واکشی موارد...</translation>
+<translation id="2218879909401188352">درحال‌حاضر مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> می‌توانند برنامه‌های خطرناکی نصب کنند Ú©Ù‡ به دستگاهتان آسیب می‌زنند، هزینه‌های پنهانی به صورت‌حساب دستگاه همراهتان اضاÙÙ‡ می‌کنند یا اطلاعات شخصی‌تان را سرقت می‌کنند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">با استÙاده از <ph name="BEGIN_LINK" />برنامه عیب‌یابی<ph name="END_LINK" />ØŒ مشکل اتصالتان را برطر٠کنید</translation>
<translation id="2239100178324503013">اکنون ارسال شود</translation>
<translation id="225207911366869382">این مقدار برای این خط‌مشی منسوخ شده است؟</translation>
<translation id="2262243747453050782">â€Ø®Ø·Ø§ÛŒ HTTP</translation>
+<translation id="2270484714375784793">شماره تلÙÙ†</translation>
<translation id="2282872951544483773">آزمایش‌های غیرقابل دسترس</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> مورد}one{<ph name="ITEM_COUNT" /> مورد}other{<ph name="ITEM_COUNT" /> مورد}}</translation>
<translation id="2292556288342944218">دسترسی شما به اینترنت مسدود است</translation>
<translation id="230155334948463882">کارت جدید؟</translation>
-<translation id="2305919008529760154">این سرور نتوانست اثبات کند <ph name="DOMAIN" /> است؛ شاید گواهینامه امنیتی آن متقلبانه صادر شده باشد. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> به نام کاربری و گذرواژه نیاز دارد.</translation>
-<translation id="2318774815570432836">â€Ø¯Ø±Ø­Ø§Ù„‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا این وب‌سایت از HSTS استÙاده می‌کند. خطاها Ùˆ حمله‌های شبکه معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">تنظیم توسط سرپرست کنترل می‌شود</translation>
<translation id="2354001756790975382">نشانک‌های دیگر</translation>
+<translation id="2354430244986887761">â€Ù…رور ایمن GoogleØŒ اخیراً <ph name="BEGIN_LINK" />برنامه‌های خطرناکی<ph name="END_LINK" /> در <ph name="SITE" /> پیدا کرده است.</translation>
<translation id="2355395290879513365">مهاجمین ممکن است بتوانند تصاویری را Ú©Ù‡ در این سایت می‌بینید مشاهده کنند Ùˆ با دست‌کاری آن‌ها شما را Ùریب دهند.</translation>
+<translation id="2356070529366658676">سؤال شود</translation>
+<translation id="2359629602545592467">چند ارز</translation>
<translation id="2359808026110333948">ادامه</translation>
<translation id="2365563543831475020">گزارش خرابی ثبت‌شده در <ph name="CRASH_TIME" /> بارگذاری نشد</translation>
<translation id="2367567093518048410">سطح</translation>
-<translation id="2371153335857947666">{1,plural, =1{این سرور نتوانست ثابت کند Ú©Ù‡ <ph name="DOMAIN" /> است؛ اعتبار گواهینامه امنیتی آن دیروز به پایان رسیده است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. ساعت رایانه‌تان درحال‌حاضر روی <ph name="CURRENT_DATE" /> تنظیم شده است. درست است؟ اگر پاسخ منÙÛŒ است، باید ساعت سیستمتان را درست کنید Ùˆ سپس این صÙحه را بازخوانی کنید. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.}one{این سرور نتوانست ثابت کند Ú©Ù‡ <ph name="DOMAIN" /> است. اعتبار گواهینامه امنیتی آن # روز قبل به پایان رسیده است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. ساعت رایانه‌تان درحال‌حاضر روی <ph name="CURRENT_DATE" /> تنظیم شده است. درست است؟ اگر پاسخ منÙÛŒ است، باید ساعت سیستمتان را درست کنید Ùˆ سپس این صÙحه را بازخوانی کنید. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.}other{این سرور نتوانست ثابت کند Ú©Ù‡ <ph name="DOMAIN" /> است. اعتبار گواهینامه امنیتی آن # روز قبل به پایان رسیده است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. ساعت رایانه‌تان درحال‌حاضر روی <ph name="CURRENT_DATE" /> تنظیم شده است. درست است؟ اگر پاسخ منÙÛŒ است، باید ساعت سیستمتان را درست کنید Ùˆ سپس این صÙحه را بازخوانی کنید. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">هیچ گزینه واسط کاربری موجود نیست</translation>
<translation id="2384307209577226199">پیش‌Ùرض شرکتی</translation>
<translation id="2386255080630008482">گواهی سرور باطل شده است.</translation>
<translation id="2392959068659972793">نمایش خط‌مشی‌ها با مقدار تنظیم نشده</translation>
<translation id="239429038616798445">این روش ارسال در دسترس نیست. روش دیگری را امتحان کنید.</translation>
<translation id="2396249848217231973">&amp;واگرد حذÙ</translation>
-<translation id="2460160116472764928">â€Â«Ù…رور ایمن Google» به‌تازگی در <ph name="SITE" />ØŒ â€<ph name="BEGIN_LINK" />بداÙزار شناسایی کرده است<ph name="END_LINK" />. گاهی اوقات وب‌سایت‌هایی Ú©Ù‡ معمولاً امن هستند با بداÙزار آلوده می‌شوند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ ممکن است گواهی امنیتی آن باطل شده باشد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
<translation id="2463739503403862330">تکمیل</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />در حال اجرای عیب‌یابی شبکه<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">â€URL جستجو نامعتبر است.</translation>
+<translation id="2482878487686419369">اعلان‌ها</translation>
<translation id="2491120439723279231">گواهی سرور دارای چندین خطاست.</translation>
<translation id="2495083838625180221">â€ØªØ¬Ø²ÛŒÙ‡â€ŒÚ©Ù†Ù†Ø¯Ù‡ JSON</translation>
<translation id="2495093607237746763">â€Ø§Ú¯Ø± علامت زده شود، Chromium برای پر کردن سریع‌تر Ùرم، یک Ú©Ù¾ÛŒ از کارت شما در این دستگاه ذخیره می‌کند.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">بازگشت</translation>
<translation id="2515629240566999685">بررسی سیگنال در منطقه‌تان</translation>
<translation id="2516305470678292029">گزینه‌های واسط کاربر</translation>
+<translation id="2539524384386349900">تشخیص</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> پاسخی نامعتبر ارسال کرد.</translation>
-<translation id="2552545117464357659">جدیدتر</translation>
<translation id="2556876185419854533">&amp;واگرد ویرایش</translation>
<translation id="2587730715158995865">از <ph name="ARTICLE_PUBLISHER" />. این داستان و <ph name="OTHER_ARTICLE_COUNT" /> داستان دیگر را بخوانید.</translation>
<translation id="2587841377698384444">â€Ø´Ù†Ø§Ø³Ù‡ Directory API:</translation>
<translation id="2597378329261239068">این سند توسط گذرواژه محاÙظت می‌شود. لطÙاً یک گذرواژه وارد کنید.</translation>
<translation id="2609632851001447353">انواع مختلÙ</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{هیچ‌کدام}=1{۱ برنامه ($1)}=2{۲ برنامه ($1،†$2)}one{# برنامه ($1،†$2،†$3)}other{# برنامه ($1،†$2،†$3)}}</translation>
<translation id="2625385379895617796">ساعت شما جلو است</translation>
<translation id="2639739919103226564">وضعیت:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />، <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">دسترسی به Ùایل رد شد</translation>
<translation id="2653659639078652383">ارائه</translation>
<translation id="2666117266261740852">برگه‌ها یا برنامه‌های دیگر را ببندید</translation>
+<translation id="2670429602441959756">این صÙحه حاوی قابلیت‌هایی است Ú©Ù‡ هنوز در حالت «واقعیت مجازی» پشتیبانی نمی‌شوند. درحال خروج…</translation>
<translation id="2674170444375937751">آیا مطمئن هستید می‌خواهید این صÙحات را از سابقه خود حذ٠کنید؟</translation>
<translation id="2677748264148917807">خروج</translation>
-<translation id="269990154133806163">سرور گواهینامه‌ای ارائه کرد Ú©Ù‡ با استÙاده از خط‌مشی «شÙاÙ‌سازی گواهینامه» به‌صورت عمومی آشکار نشده بود. این شرط لازمی برای بعضی از گواهینامه‌ها است تا اطمینان حاصل شود Ú©Ù‡ قابل‌اعتماد هستند Ùˆ در برابر مهاجمین محاÙظت می‌شوند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Ùهرست خواندن</translation>
<translation id="2704283930420550640">مقدار با Ùرمت مطابقت ندارد.</translation>
<translation id="2704951214193499422">â€Chromium درحال حاضر نمی‌تواند کارت شما را تأیید کند. لطÙاً بعداً دوباره امتحان کنید.</translation>
<translation id="2705137772291741111">کپی ذخیره‌شده (ذخیره موقت‌شده) این سایت قابل خواندن نبود.</translation>
<translation id="2709516037105925701">تکمیل خودکار</translation>
-<translation id="2712118517637785082">سعی داشتید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما گواهینامه‌ای که سرور ارائه کرد توسط صادرکننده آن باطل شده است. به این معنی که قطعاً نباید به گواهینامه‌های امنیتی که این سرور ارائه می‌دهد اعتماد کرد. ممکن است درحال ارتباط با یک مهاجم باشید. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">درخواست اجازه</translation>
<translation id="2713444072780614174">سÙید</translation>
<translation id="2720342946869265578">اطراÙ</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ثبت دستگاه موجود نیست</translation>
<translation id="2784949926578158345">اتصال مجدداً برقرار شد.</translation>
<translation id="2794233252405721443">سایت مسدودشده</translation>
+<translation id="2799020568854403057">سایت پیش‌رو حاوی برنامه‌های خطرناک است</translation>
+<translation id="2803306138276472711">â€Google Safe Browsing به تازگی در <ph name="SITE" />ØŒ â€<ph name="BEGIN_LINK" />بداÙزار شناسایی کرده است<ph name="END_LINK" />. گاهی اوقات وب‌سایت‌هایی Ú©Ù‡ معمولاً ایمن هستند با بداÙزار آلوده می‌شوند.</translation>
<translation id="2824775600643448204">نوار جستجو و آدرس</translation>
<translation id="2826760142808435982">اتصال با استÙاده از <ph name="CIPHER" /> رمزگذاری Ùˆ راستی‌آزمایی شده است Ùˆ از <ph name="KX" /> به عنوان مکانیسم تبادل کلید استÙاده می‌کند.</translation>
<translation id="2835170189407361413">پاک کردن Ùرم</translation>
+<translation id="2856444702002559011">شاید مهاجم‌ها در تلاش باشند اطلاعات شما (مانند گذرواژه‌ها، پیام‌ها یا کارت‌های اعتباری) را از <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> سرقت کنند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">تازه‌سازی نشود</translation>
<translation id="2900469785430194048">â€Google Chrome هنگام تلاش برای نمایش این صÙحه با کمبود حاÙظه روبرو شد.</translation>
<translation id="2909946352844186028">تغییر شبکه تشخیص داده شد.</translation>
<translation id="2916038427272391327">برنامه‌های دیگر را ببندید</translation>
<translation id="2922350208395188000">گواهی سرور بررسی نمی‌شود.</translation>
<translation id="2928905813689894207">نشانی صورت‌حساب</translation>
+<translation id="2941952326391522266">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن از <ph name="DOMAIN2" /> است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
<translation id="2948083400971632585">در صÙحه تنظیمات می‌توانید همه پراکسی‌های پیکربندی شده برای هر اتصال را از کار بیاندازید.</translation>
<translation id="2955913368246107853">بستن نوار یاÙتن</translation>
<translation id="2958431318199492670">â€Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ شبکه با استاندارد ONC تطابق ندارد. بخشی از پیکربندی ممکن است وارد نشود.</translation>
-<translation id="29611076221683977">â€Ù…هاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> درحال‌حاضر ممکن است تلاش کنند تا برنامه‌های خطرناکی در Mac شما نصب کنند Ú©Ù‡ اطلاعات شما (مانند کارت‌های اعتباری، عکس‌ها، گذرواژه‌ها Ùˆ پیام‌هایتان) را سرقت یا حذ٠می‌کنند.</translation>
<translation id="2966678944701946121">تاریخ انقضا: <ph name="EXPIRATION_DATE_ABBR" />ØŒ تاریخ اضاÙÙ‡ شدن: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">â€Ø¨Ø±Ø§ÛŒ برقراری یک اتصال امن، لازم است ساعت شما درست تنظیم شده باشد. زیرا گواهی‌هایی Ú©Ù‡ وب‌سایت‌ها برای شناسایی خودشان استÙاده می‌کنند، تنها برای دوره‌های زمانی خاصی معتبرند. از آنجا Ú©Ù‡ ساعت دستگاه شما نادرست است، Google Chrome نمی‌تواند این گواهی‌ها را تأیید کند.</translation>
<translation id="2972581237482394796">انجام مجدد</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">نشانی معتبری وارد کنید</translation>
<translation id="2986368408720340940">این روش تحویل گرÙتن در دسترس نیست. روش دیگری را امتحان کنید.</translation>
<translation id="2991174974383378012">اشتراک‌گذاری با وب‌سایت‌ها</translation>
+<translation id="2991571918955627853">â€Ø¯Ø±Ø­Ø§Ù„‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا این وب‌سایت از HSTS استÙاده می‌کند. خطاهای شبکه Ùˆ حمله‌ها معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد.</translation>
<translation id="3005723025932146533">نمایش کپی ذخیره شده</translation>
<translation id="3008447029300691911">â€CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید. بعد از تأیید، جزئیات کارت شما با این سایت به اشتراک گذاشته می‌شود.</translation>
<translation id="3010559122411665027">ورودی Ùهرست "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">مسدود‌شده به‌طور خودکار</translation>
<translation id="3024663005179499861">نوع خط‌مشی اشتباه است</translation>
<translation id="3032412215588512954">می‌خواهید این سایت را تازه‌سازی کنید؟</translation>
<translation id="3037605927509011580">اوه، نه!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{حداقل ۱ مورد در دستگاه‌های همگام‌سازی‌شده}=1{۱ مورد (و بیشتر در دستگاه‌های همگام‌سازی‌شده)}one{# مورد (و بیشتر در دستگاه‌های همگام‌سازی‌شده)}other{# مورد (و بیشتر در دستگاه‌های همگام‌سازی‌شده)}}</translation>
<translation id="3041612393474885105">اطلاعات گواهی</translation>
<translation id="3063697135517575841">â€Chrome درحال حاضر نمی‌تواند کارت شما را تأیید کند. لطÙاً بعداً دوباره امتحان کنید.</translation>
<translation id="3064966200440839136">درحال خروج از حالت ناشناس، برای پرداخت ازطریق یک برنامه خارجی. ادامه می‌دهید؟</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{هیچ‌کدام}=1{۱ گذرواژه}one{# گذرواژه}other{# گذرواژه}}</translation>
<translation id="3093245981617870298">شما Ø¢Ùلاین هستید.</translation>
<translation id="3105172416063519923">شناسه دارایی:</translation>
<translation id="3109728660330352905">شما اجازه مشاهده این صÙحه را ندارید.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />عیب‌یابی اتصال را اجرا کنید<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">رمزگشایی پاسخ انجام نشد</translation>
<translation id="3150653042067488994">خطای موقت سرور</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">صÙحه‌هایی Ú©Ù‡ در برگه‌های حالت ناشناس مرور می‌کنید، بعد از بستن همه برگه‌های حالت ناشناس در سابقه مرورگر، Ùضای ذخیره Ú©ÙˆÚ©ÛŒ یا سابقه جستجو باقی نمی‌مانند. Ùایل‌هایی Ú©Ù‡ بارگیری می‌کنید یا نشانک‌هایی Ú©Ù‡ ایجاد می‌کنید Ø­Ùظ می‌شود.</translation>
<translation id="3169472444629675720">کش٠کردن</translation>
<translation id="3174168572213147020">جزیره</translation>
+<translation id="317583078218509884">تنظیمات مجوزهای جدید سایت پس از بارگیری مجدد صÙحه اعمال می‌شوند.</translation>
<translation id="3176929007561373547">تنظیمات پروکسی‌ را بررسی کنید یا با سرپرست شبکه‌‌تان تماس بگیرید تا
مطمئن شوید سرور پروکسی کار می‌کند. اگر مطمئن نیستید که باید از سرور
پروکسی استÙاده کنید:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">صÙحه را در حالت «ناشناس» باز کنید</translation>
-<translation id="3202578601642193415">جدیدترین</translation>
+<translation id="320323717674993345">لغو پرداخت</translation>
<translation id="3207960819495026254">نشانک‌گذاری شده</translation>
+<translation id="3225919329040284222">سرور گواهی را نشان می‌دهد Ú©Ù‡ با موارد پیش‌بینی‌شده داخلی مطابقت ندارد. این پیش‌بینی‌ها به‌طور حتم وب‌سایتهای دارای امنیت بالا را جهت محاÙظت از شما در بر می‌گیرند.</translation>
<translation id="3226128629678568754">دکمه تازه‌سازی را Ùشار دهید تا داده‌های مورد نیاز برای بارگیری صÙحه مجدداً ارسال شود.</translation>
+<translation id="3227137524299004712">میکروÙÙ†</translation>
<translation id="3228969707346345236">ترجمه انجام نشد زیرا صÙحه در حال حاضر به زبان <ph name="LANGUAGE" /> است.</translation>
<translation id="323107829343500871">â€CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید</translation>
+<translation id="3234666976984236645">همیشه محتوای مهم در این سایت شناسایی شود</translation>
<translation id="3254409185687681395">نشانک گذاری این صÙحه</translation>
<translation id="3270847123878663523">&amp;واگرد ترتیب‌بندی مجدد</translation>
<translation id="3282497668470633863">اÙزودن نام روی کارت</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">تنظیمات</translation>
<translation id="3345135638360864351">درخواست شما برای دسترسی به این سایت به <ph name="NAME" /> ارسال نشد. لطÙاً دوباره امتحان کنید.</translation>
<translation id="3355823806454867987">تغییر تنظیمات پروکسی...</translation>
+<translation id="3361596688432910856">â€Chrome اطلاعات زیر را <ph name="BEGIN_EMPHASIS" />ذخیره نخواهد کرد<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />سابقه مرور
+ <ph name="LIST_ITEM" />کوکی‌ها و داده‌های سایت
+ <ph name="LIST_ITEM" />اطلاعات واردشده در Ùرم‌ها
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">خطای ساعت</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> مورد دیگر...</translation>
<translation id="337363190475750230">لغو مجوز شد</translation>
<translation id="3377188786107721145">خطای تجزیه خط‌مشی</translation>
<translation id="3380365263193509176">خطای ناشناس</translation>
<translation id="3380864720620200369">شناسه سرویس‌گیرنده:</translation>
<translation id="3391030046425686457">نشانی ارسال</translation>
<translation id="3395827396354264108">روش تحویل گرÙتن</translation>
-<translation id="340013220407300675">ممکن است مهاجمان سعی در دزدیدن اطلاعات شما (مثل گذرواژه‌ها، پیام‌ها یا کارت‌های اعتباری) از <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> را داشته باشند.</translation>
<translation id="3422248202833853650">سعی کنید از برنامه‌های دیگر خارج شوید تا حاÙظه آزاد شود.</translation>
<translation id="3422472998109090673">دسترسی به <ph name="HOST_NAME" /> درحال حاضر امکان‌پذیر نیست.</translation>
+<translation id="3427092606871434483">اجازه (پیش‌Ùرض)</translation>
<translation id="3427342743765426898">&amp;انجام مجدد ویرایش</translation>
<translation id="3431636764301398940">این کارت را در این دستگاه ذخیره کنید</translation>
<translation id="3435896845095436175">Ùعال کردن</translation>
<translation id="3447661539832366887">مالک این دستگاه بازی دایناسور را خاموش کرده است</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Ùاصله زمانی واکشی:</translation>
<translation id="3462200631372590220">پنهان کردن پیشرÙته</translation>
<translation id="3467763166455606212">نام صاحب حساب الزامی است</translation>
<translation id="3478058380795961209">ماه انقضا</translation>
<translation id="3479539252931486093">غیرمنتظره بود؟ <ph name="BEGIN_LINK" />به ما اطلاع دهید<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">اکنون نه</translation>
-<translation id="348000606199325318">شناسه خرابی <ph name="CRASH_LOCAL_ID" /> (شناسه سرور: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">در حال حاضر نمی‌توانیم با والدینتان تماس برقرار کنیم. لطÙاً دوباره امتحان کنید.</translation>
<translation id="3528171143076753409">گواهی سرور مطمئن نیست.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{حداقل ۱ مورد در دستگاه‌های همگام‌سازی‌شده}=1{۱ مورد (و بیشتر در دستگاه‌های همگام‌سازی‌شده)}one{# مورد (و بیشتر در دستگاه‌های همگام‌سازی‌شده)}other{# مورد (و بیشتر در دستگاه‌های همگام‌سازی‌شده)}}</translation>
<translation id="3539171420378717834">یک کپی از این کارت در این دستگاه نگهداری شود</translation>
<translation id="3542684924769048008">استÙاده از گذرواژه برای:</translation>
+<translation id="3545341443414427877">برقراری اتصال خصوصی با <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ممکن نیست، زیرا تاریخ و زمان رایانه‌تان (<ph name="DATE_AND_TIME" />) نادرست است. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">رمزگذاری همه داده‌های همگام‌سازی‌شده با رمزعبارتی همگام‌سازی خودتان</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> برگه بیشتر...</translation>
-<translation id="3555561725129903880">این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن از <ph name="DOMAIN2" /> است. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی ارتباط شما را اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">مدیرتان می‌تواند این سایت را برای شما بگشاید</translation>
<translation id="3566021033012934673">اتصال شما خصوصی نیست</translation>
+<translation id="3569145463236695319">â€&lt;p&gt;برقراری اتصال خصوصی با <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ممکن نیست، زیرا تاریخ Ùˆ زمان دستگاهتان (<ph name="DATE_AND_TIME" />) نادرست است.&lt;/p&gt;
+
+ &lt;p&gt;لطÙاً تاریخ Ùˆ زمان را در بخش &lt;strong&gt;«موارد کلی»&lt;/strong&gt; برنامه &lt;strong&gt;«تنظیمات»&lt;/strong&gt; تنظیم کنید.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />، <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">اÙزودن نام</translation>
<translation id="3583757800736429874">&amp;انجام مجدد انتقال</translation>
<translation id="3586931643579894722">عدم نمایش جزئیات</translation>
-<translation id="3587482841069643663">همه</translation>
<translation id="3600246354004376029"><ph name="TITLE" />، <ph name="DOMAIN" />، <ph name="TIME" /></translation>
<translation id="3615877443314183785">تاریخ انقضای معتبری وارد کنید</translation>
<translation id="36224234498066874">پاک کردن داده‌های مرور...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">اطلاعات گواهی</translation>
<translation id="3690164694835360974">ورود به سیستم امن نیست</translation>
<translation id="3693415264595406141">گذرواژه:</translation>
-<translation id="3696411085566228381">هیچ‌کدام</translation>
<translation id="3704609568417268905"><ph name="TIME" /> â€<ph name="BOOKMARKED" /> â€<ph name="TITLE" /> â€<ph name="DOMAIN" /></translation>
<translation id="370665806235115550">در حال بارکردن…</translation>
<translation id="3712624925041724820">مجوزها دیگر معتبر نیستند</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159">â€<ph name="BEGIN_LINK" />بررسی پروکسی، دیوار آتش Ùˆ پیکربندی DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">اگر خطرات امنیتی که متوجه شما هستند را درک می‌کنید، می‌توانید قبل از حذ٠شدن برنامه‌های خطرناک از <ph name="BEGIN_LINK" />این سایت غیرایمن بازدید کنید<ph name="END_LINK" />.</translation>
<translation id="3739623965217189342">پیوندی که کپی کرده‌اید</translation>
+<translation id="3744899669254331632">â€Ù†Ù…ی‌توانید اکنون از <ph name="SITE" /> دیدن کنید زیرا وب‌سایت اعتبارنامه‌های درهمی ارسال کرده Ú©Ù‡ Chromium نمی‌تواند پردازش کند. خطاها Ùˆ حمله‌های شبکه معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار می‌کند.</translation>
+<translation id="3748148204939282805">ممکن است مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> شما را Ùریب دهند تا اقدام خطرناکی همچون نصب نرم‌اÙزار یا اÙشای اطلاعات شخصی (مانند گذرواژه‌ها، پیام‌ها یا کارت‌های اعتباری) انجام دهید. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">بدلیل خطای سرور ترجمه انجام نشد.</translation>
<translation id="3759461132968374835">شما اخیراً گزارش خرابی ارسال نکرده‌اید. مشکلاتی Ú©Ù‡ در هنگام غیرÙعال بودن ویژگی ارائه گزارش خرابی ایجاد شده است، در اینجا نمایش داده نمی‌شود.</translation>
+<translation id="3778403066972421603">â€Ø¢ÛŒØ§ می‌خواهید این کارت در حساب Google شما Ùˆ این دستگاه ذخیره شود؟</translation>
+<translation id="3783418713923659662">مسترکارت</translation>
<translation id="3787705759683870569">تاریخ انقضا <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">اگر از سرور پراکسی استÙاده می‌کنید...</translation>
<translation id="3828924085048779000">عبارت عبور خالی مجاز نیست.</translation>
-<translation id="3845539888601087042">در حال نمایش سابقه از دستگاه‌هایی که در آن‌ها به سیستم وارد شده‌اید. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">بازگشت</translation>
<translation id="3858027520442213535">به‌روزرسانی تاریخ و زمان</translation>
<translation id="3884278016824448484">شناسه دستگاه یکسان نیست</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">درخواست شما برای دسترسی به این سایت برای <ph name="NAME" /> ارسال شده است</translation>
<translation id="3890664840433101773">اÙزودن رایانامه</translation>
<translation id="3901925938762663762">کارت منقضی شده است</translation>
-<translation id="3933571093587347751">{1,plural, =1{این سرور نمی‌تواند ثابت کند <ph name="DOMAIN" /> است؛ اعتبار گواهینامه امنیتی آن ظاهراً Ùردا شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.}one{این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ اعتبار گواهینامه امنیتی آن ظاهراً # روز دیگر شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.}other{این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ اعتبار گواهینامه امنیتی آن ظاهراً # روز دیگر شروع می‌شود. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصالتان را قطع می‌کند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">â€Ø¨Ø§Ø±Ú¯ÛŒØ±ÛŒ سند PDF انجام نشد</translation>
+<translation id="3945915738023014686">شناسه گزارش خرابی بارگذاری‌شده <ph name="CRASH_ID" /> (شناسه خرابی محلی: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">â€Ø§ÛŒÙ† سرور نتوانست ثابت کند Ú©Ù‡ <ph name="DOMAIN" /> است؛ در گواهی امنیتی آن، Subject Alternative Names مشخص نشده است. ممکن است این مشکل به دلیل پیکربندی نادرست یا قطع اتصال شما توسط مهاجم ایجاد شده باشد.</translation>
<translation id="3963721102035795474">حالت «خواننده»</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{هیچ‌کدام}=1{از ۱ سایت }one{از # سایت }other{از # سایت }}</translation>
<translation id="397105322502079400">در حال محاسبه…</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> مسدود است</translation>
+<translation id="3987940399970879459">کمتر از ۱ مگابایت</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ Û± صÙحه وب در این نزدیکی است}one{ # صÙحه وب در این نزدیکی است}other{ # صÙحه وب در این نزدیکی است}}</translation>
<translation id="4021036232240155012">â€DNS خدماتی از شبکه است Ú©Ù‡ نام وب‌سایت را به آدرس اینترنتی آن ترجمه می‌کند.</translation>
<translation id="4030383055268325496">&amp;واگرد اÙزودن</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">â€ØªÙ†Ø¸ÛŒÙ…ات پروکسی، برای استÙاده از آدرس اسکریپت pac. تنظیم شده است Ùˆ از سرورهای ثابت نمی‌تواند استÙاده کند.</translation>
<translation id="4098354747657067197">احتیاط، سایت گول‌زننده</translation>
<translation id="4103249731201008433">شماره سریال دستگاه نامعتبر است</translation>
+<translation id="410351446219883937">پخش خودکار</translation>
<translation id="4103763322291513355">â€Ø¨Ø±Ø§ÛŒ مشاهده Ùهرست نشانی‌های وب ممنوع Ùˆ سایر خط‌مشی‌های اجباری براساس تصمیم سرپرست سیستم خود از &lt;strong&gt;chrome://policy&lt;/strong&gt; بازدید نمایید.</translation>
-<translation id="4110615724604346410">این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن خطاهایی دارد. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">سرخابی</translation>
+<translation id="4116663294526079822">همیشه مجاز در این سایت</translation>
<translation id="4117700440116928470">محدوده خط‌مشی پشتیبانی نمی‌شود.</translation>
-<translation id="4118212371799607889">â€Ø§ÛŒÙ† سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن مورداعتماد Chromium نیست. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{۱ مورد دیگر}one{# مورد دیگر}other{# مورد دیگر}}</translation>
<translation id="4130226655945681476">بررسی کابل‌های شبکه، مودم یا رهیاب</translation>
+<translation id="413544239732274901">بیشتر بدانید</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">استÙاده از پیش‌Ùرض Ú©Ù„ÛŒ (تشخیص)</translation>
+<translation id="4165986682804962316">تنظیمات سایت</translation>
<translation id="4169947484918424451">â€Ù…ی‌خواهید Chromium این کارت را ذخیره کند؟</translation>
<translation id="4171400957073367226">امضای تأیید نامناسب</translation>
<translation id="4196861286325780578">&amp;انجام مجدد انتقال</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />بررسی پیکربندی آنتی‌ویروس و دیوار آتش<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{هیچ‌}=1{۱ برنامه ($1)}=2{۲ برنامه ($1،†$2)}one{# برنامه ($1،†$2،†$3)}other{# برنامه ($1،†$2،†$3)}}</translation>
<translation id="4220128509585149162">خرابی ها</translation>
+<translation id="422022731706691852">شاید مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> تلاش کنند شما را Ùریب دهند تا برنامه‌هایی نصب کنید Ú©Ù‡ برای تجربه مرورتان مضر هستند (برای مثال با تغییر دادن صÙحه اصلی‌تان یا نشان دادن آگهی‌های اضاÙÛŒ در سایت‌هایی Ú©Ù‡ دیدن می‌کنید). <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />عیب‌یابی شبکه را اجرا کنید<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">معتبر</translation>
<translation id="4250431568374086873">اتصال شما به این سایت کاملاً امن نیست</translation>
<translation id="4250680216510889253">نه</translation>
<translation id="425582637250725228">تغییراتی که انجام داده‌اید ممکن است ذخیره نشده باشند.</translation>
<translation id="4258748452823770588">امضای نادرست</translation>
+<translation id="4265872034478892965">توسط سرپرست مجاز شده است</translation>
<translation id="4269787794583293679">(بدون نام کاربری)</translation>
<translation id="4275830172053184480">راه‌اندازی دستگاه خود</translation>
<translation id="4280429058323657511">، انقضا <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">â€Â«Ù…رور ایمن Google» به‌تازگی <ph name="BEGIN_LINK" />برنامه‌های مخرب<ph name="END_LINK" /> در <ph name="SITE" /> پیدا کرده است. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">پیشنهادات والدین</translation>
<translation id="4304224509867189079">ورود به سیستم</translation>
-<translation id="432290197980158659">سرور گواهینامه‌ای ارائه کرد Ú©Ù‡ با انتظارات داخلی مطابقت ندارد. این انتظارات برای بعضی از وب‌سایت‌های با امنیت بالا Ùˆ با هد٠محاÙظت از شما درنظر گرÙته شده‌اند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">مسدود کردن (پیش‌Ùرض)</translation>
<translation id="4325863107915753736">مقاله یاÙت نشد.</translation>
<translation id="4326324639298822553">تاریخ انقضا را بررسی و دوباره امتحان کنید</translation>
<translation id="4331708818696583467">امن نیست</translation>
<translation id="4356973930735388585">مهاجم‌ها در این سایت ممکن است تلاش کنند برنامه‌های خطرناکی در رایانه شما نصب کنند که اطلاعات شما (مانند عکس‌ها، گذرواژه‌ها، پیام‌ها و کارت‌های اعتباری) را به سرقت می‌برند یا حذ٠می‌کنند.</translation>
<translation id="4372948949327679948">مقدار مورد انتظار <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">شما سعی در دسترسی به <ph name="DOMAIN" /> را داشتید، اما صادر کننده، گواهی ارائه شده از سوی سرور را باطل کرده است. یعنی اصلاً نباید به اطلاعات کاربری که این سرور ارائه می‌کند اطمینان کرد. ممکن است شما با مهاجمی در ارتباط باشید.</translation>
<translation id="4381091992796011497">نام کاربری:</translation>
<translation id="4394049700291259645">غیر Ùعال کردن</translation>
<translation id="4406896451731180161">نتایج جستجو</translation>
+<translation id="4424024547088906515">â€Ø§ÛŒÙ† سرور نتوانست اثبات کند Ú©Ù‡ این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورداعتماد Chrome نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> گواهی ورود به سیستمتان را نپذیرÙت یا ممکن است گواهی‌ای ارائه نشده باشد.</translation>
<translation id="443673843213245140">استÙاده از پروکسی غیرÙعال است اما یک پیکربندی خاص برای پروکسی تعیین شده است.</translation>
-<translation id="4492190037599258964">نتایج جستجو برای "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">خطای ارزیابی: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">تماس با سرپرست سیستم</translation>
<translation id="450710068430902550">اشتراک‌گذاری با سرپرست سیستم</translation>
<translation id="4515275063822566619">â€Ú©Ø§Ø±Øªâ€ŒÙ‡Ø§ Ùˆ نشانی‌ها از Chrome Ùˆ حساب Google شما (<ph name="ACCOUNT_EMAIL" />) هستند. می‌توانید آن‌ها را در <ph name="BEGIN_LINK" />تنظیمات<ph name="END_LINK" /> مدیریت کنید.</translation>
<translation id="4522570452068850558">جزئیات</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">اÙزونه‌ها را غیرÙعال کنید.</translation>
<translation id="457875822857220463">ارسال</translation>
<translation id="4587425331216688090">â€Ø¢Ø¯Ø±Ø³ از Chrome پاک شود؟</translation>
-<translation id="4589078953350245614">سعی داشتید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما سرور گواهینامه نامعتبری ارائه کرد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">اتصال شما به <ph name="DOMAIN" /> با استÙاده از یک مجموعه رمز مدرن، رمزگذاری شده است.</translation>
<translation id="4594403342090139922">&amp;واگرد حذÙ</translation>
<translation id="4619615317237390068">برگه‌ها از دستگاه‌های دیگر</translation>
<translation id="4668929960204016307">،</translation>
+<translation id="467662567472608290">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن خطاهایی دارد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
+<translation id="4690462567478992370">توق٠استÙاده از گواهینامه نامعتبر</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">اتصال شما قطع شد</translation>
<translation id="4722547256916164131">â€<ph name="BEGIN_LINK" />در حال اجرای Windows Network Diagnostics<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">خطای ناشناخته‌ای رخ داد.</translation>
<translation id="4800132727771399293">â€ØªØ§Ø±ÛŒØ® انقضا Ùˆ CVC را بررسی کرده Ùˆ دوباره امتحان کنید</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">â€Ø¯Ø± این لحظه نمی‌توانید از <ph name="SITE" /> دیدن کنید زیرا این وب‌سایت اعتبارنامه‌های درهمی ارسال کرده است Ú©Ù‡ Google Chrome نمی‌تواند پردازش کند. خطاهای شبکه Ùˆ حمله‌ها معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد.</translation>
<translation id="4813512666221746211">خطای شبکه</translation>
<translation id="4816492930507672669">متناسب با صÙحه</translation>
<translation id="483020001682031208">هیچ صÙحه «وب Ùیزیکی» برای نمایش وجود ندارد</translation>
<translation id="4850886885716139402">نما</translation>
<translation id="4854362297993841467">این روش تحویل در دسترس نیست. روش دیگری را امتحان کنید.</translation>
<translation id="4858792381671956233">از والدینتان پرسیدید آیا اجازه بازدید از این سایت را دارید</translation>
+<translation id="4863764087567530506">شاید محتوای این صÙحه تلاش کند شما را Ùریب دهد تا نرم‌اÙزاری نصب کنید یا اطلاعات شخصی را اÙشا سازید. <ph name="BEGIN_LINK" />درهرصورت نمایش داده شود<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">سابقه جستجو</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />،†<ph name="TYPE_2" />،†<ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ Ùˆ Û± صÙحه وب دیگر}one{ Ùˆ # صÙحه وب دیگر}other{ Ùˆ # صÙحه وب دیگر}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">این صÙحه از یک زبان ناشناس به <ph name="LANGUAGE_LANGUAGE" /> ترجمه شده است.</translation>
<translation id="4923459931733593730">پرداخت</translation>
<translation id="4926049483395192435">باید مشخص شود.</translation>
<translation id="495170559598752135">عملکردها</translation>
<translation id="4958444002117714549">بزرگ کردن Ùهرست</translation>
-<translation id="4962322354953122629">â€Ø§ÛŒÙ† سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن مورداعتماد Chrome نیست. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Ùعال کردن مجدد اخطارها</translation>
<translation id="4989809363548539747">این اÙزایه پشتیبانی نمی‌شود</translation>
<translation id="5002932099480077015">â€Ø§Ú¯Ø± Ùعال شود، Chrome یک Ú©Ù¾ÛŒ از کارت شما را برای پرکردن سریع‌تر Ùرم در این دستگاه ذخیره می‌کند.</translation>
<translation id="5018422839182700155">این صÙحه نمی‌تواند باز شود</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">خط‌مشی‌های سرپرست سیستمتان را بررسی کنید</translation>
<translation id="5029568752722684782">پاک کردن نسخه کپی</translation>
<translation id="5031870354684148875">â€Ø¯Ø±Ø¨Ø§Ø±Ù‡ â€â€«Ù…ترجم Google‬</translation>
+<translation id="5039804452771397117">اجازه دادن</translation>
<translation id="5040262127954254034">حریم خصوصی</translation>
<translation id="5045550434625856497">گذرواژه نادرست</translation>
<translation id="5056549851600133418">مقالاتی برای شما</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />بررسی آدرس پروکسی<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{بدون Ú©ÙˆÚ©ÛŒ}=1{Û± سایت از Ú©ÙˆÚ©ÛŒ استÙاده می‌کند. }one{# سایت از Ú©ÙˆÚ©ÛŒ استÙاده می‌کنند. }other{# سایت از Ú©ÙˆÚ©ÛŒ استÙاده می‌کنند. }}</translation>
<translation id="5087286274860437796">در حال حاضر گواهی سرور معتبر نیست.</translation>
<translation id="5087580092889165836">اÙزودن کارت</translation>
<translation id="5089810972385038852">ایالت</translation>
+<translation id="5094747076828555589">â€Ø§ÛŒÙ† سرور نتوانست اثبات کند Ú©Ù‡ این <ph name="DOMAIN" /> است؛ گواهی امنیت آن مورداعتماد Chromium نیست. علت این موضوع می‌توان پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
<translation id="5095208057601539847">استان</translation>
<translation id="5115563688576182185">(۶۴ بیت)</translation>
<translation id="5141240743006678641">â€Ø±Ù…زگذاری گذرواژه‌های همگام‌سازی شده با اطلاعات کاربری Google شما</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">رایانامه ضروری است</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">â€Ø§Ø² Chrome در محل کار استÙاده می‌کنید؟ کسب Ùˆ کارها می‌توانند تنظیمات Chrome را برای کارمندانشان مدیریت کنند. بیشتر بدانید</translation>
+<translation id="5297526204711817721">â€Ø§ØªØµØ§Ù„ شما به این سایت خصوصی نیست. درهرزمانی برای خروج از حالت VRØŒ هدست را جدا کنید Ùˆ «برگشت» را Ùشار دهید.</translation>
<translation id="5299298092464848405">خطا در تجزیه خط‌‌مشی</translation>
-<translation id="5300589172476337783">نمایش</translation>
<translation id="5308689395849655368">گزارش خرابی غیر Ùعال است.</translation>
<translation id="5317780077021120954">ذخیره</translation>
<translation id="5327248766486351172">نام</translation>
-<translation id="5337705430875057403">مهاجمان <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ممکن است شما را Ùریب دهند Ùˆ به انجام کارهای خطرناکی مثل نصب نرم‌اÙزار یا ارائه اطلاعات شخصی‌تان (مثلاً گذرواژه، شماره تلÙÙ† یا کارت‌های اعتباری) ترغیب کنند.</translation>
-<translation id="5359637492792381994">این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن درحال‌حاضر معتبر نیست. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">درحال‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا گواهینامه آن لغو شده است. معمولاً خطاهای شبکه Ùˆ حمله‌ها موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد.</translation>
<translation id="536296301121032821">تنظیمات خط‌‌مشی ذخیره نشد</translation>
<translation id="5386426401304769735">â€Ø²Ù†Ø¬ÛŒØ±Ù‡ گواهی این سایت حاوی یک گواهی با امضای SHA-1 است.</translation>
<translation id="5402410679244714488">انقضا: <ph name="EXPIRATION_DATE_ABBR" />ØŒ آخرین استÙاده، بیش از یک سال قبل</translation>
+<translation id="540969355065856584">این سرور نتوانست ثابت کند که <ph name="DOMAIN" /> است؛ در حال حاضر، گواهی امنیتی آن معتبر نیست. ممکن است این مشکل به دلیل پیکربندی نادرست یا قطع اتصال شما توسط حمله‌کننده ایجاد شده باشد.</translation>
<translation id="5421136146218899937">پاک کردن داده‌های مرور...</translation>
<translation id="5430298929874300616">حذ٠نشانک</translation>
<translation id="5431657950005405462">Ùایل شما پیدا نشد</translation>
-<translation id="5435775191620395718">در حال نمایش سابقه از این دستگاه. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">خطای تأیید طرح در «<ph name="ERROR_PATH" />»:†<ph name="ERROR" /></translation>
<translation id="5452270690849572955">صÙحه <ph name="HOST_NAME" /> پیدا نمی‌شود</translation>
<translation id="5455374756549232013">مهر زمان خط‌مشی نادرست است</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> از <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">نامعتبر</translation>
<translation id="5470861586879999274">&amp;انجام مجدد ویرایش</translation>
<translation id="54817484435770891">نشانی معتبری اضاÙÙ‡ کنید</translation>
<translation id="5492298309214877701">نشانی وب این سایت در اینترانت شرکت، سازمان یا محل تحصیل با نشانی وب یک وب‌سایت خارجی یکسان است.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">تحویل گرÙتن از این نشانی ممکن نیست. نشانی دیگری را انتخاب کنید.</translation>
<translation id="5572851009514199876">â€Ù„Ø·Ùاً Chrome را باز کنید Ùˆ به سیستم آن وارد شوید تا Chrome بتواند بررسی کند آیا مجاز به دسترسی به این سایت هستید یا خیر.</translation>
<translation id="5580958916614886209">ماه انقضا را بررسی و دوباره امتحان کنید</translation>
+<translation id="5586446728396275693">نشانی ذخیره‌شده‌ای وجود ندارد</translation>
+<translation id="5595485650161345191">ویرایش آدرس</translation>
<translation id="560412284261940334">مدیریت پشتیبانی نمی‌شود</translation>
<translation id="5610142619324316209">بررسی اتصال</translation>
<translation id="5610807607761827392">می‌توانید در <ph name="BEGIN_LINK" />تنظیمات<ph name="END_LINK" />، کارت‌ها و نشانی‌ها را مدیریت کنید.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">می‌خواهید از این سایت خارج شوید؟</translation>
<translation id="5629630648637658800">تنظیمات خط‌مشی بارگیری نشد</translation>
<translation id="5631439013527180824">نشانه مدیریت دستگاه نامعتبر است</translation>
+<translation id="5633066919399395251">شاید درحال‌حاضر مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> در تلاش باشند برنامه‌های خطرناکی در رایانه‌تان نصب کنند که اطلاعات شما (مانند عکس‌ها، گذرواژه‌ها، پیام‌ها و کارت‌های اعتباری) را به سرقت می‌برند یا حذ٠می‌کنند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">مکان</translation>
+<translation id="5659593005791499971">رایانامه</translation>
<translation id="5669703222995421982">دریاÙت محتوای شخصی‌سازی‌شده</translation>
<translation id="5675650730144413517">این صÙحه کار نمی‌کند</translation>
-<translation id="5677928146339483299">مسدود است</translation>
-<translation id="5694783966845939798">â€Ø³Ø¹ÛŒ کردید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما سرور گواهینامه‌ای ارائه کرد Ú©Ù‡ با استÙاده از الگوریتم امضای ضعیÙÛŒ (مثل SHA-1) امضا شده بود. این یعنی ممکن است اعتبارنامه‌های امنیتی ارائه‌شده توسط این سرور جعلی باشند Ùˆ ممکن است این سرور، سرور موردانتظار شما نباشد (شاید درحال ارتباط با یک مهاجم باشید). <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">هویت این وب سایت تأیید نشده است.</translation>
+<translation id="5713016350996637505">محتوای Ùریب‌دهنده مسدود شد</translation>
<translation id="5720705177508910913">کاربر کنونی</translation>
<translation id="5732392974455271431">والدینتان می‌توانند این سایت را برای شما بگشایند</translation>
<translation id="5763042198335101085">نشانی رایانامه معتبری وارد کنید</translation>
<translation id="5765072501007116331">برای دیدن روش‌های تحویل و شرایط موردنیاز، یک نشانی انتخاب کنید</translation>
+<translation id="5778550464785688721">â€Ú©Ù†ØªØ±Ù„ کامل دستگاه‌های MIDI</translation>
<translation id="5784606427469807560">هنگام تأیید کارت مشکلی پیش آمد. اتصال اینترنتتان را بررسی و دوباره امتحان کنید.</translation>
<translation id="5785756445106461925">علاوه بر این، این صÙحه دارای منابع دیگری است Ú©Ù‡ امن نیستند. دیگران می‌توانند در حین انتقال، این منابع را ببینند Ùˆ این منابع می‌توانند برای تغییر Ù‚ÙÙ„ صÙحه، توسط یک مهاجم تغییر داده شوند.</translation>
<translation id="5786044859038896871">می‌خواهید اطلاعات کارتتان را وارد کنید؟</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;انجام مجدد اÙزودن</translation>
<translation id="5814352347845180253">ممکن است دسترسی به محتوای ممتاز از <ph name="SITE" /> و برخی دیگر سایت‌ها را از دست بدهید.</translation>
<translation id="5838278095973806738">نباید هیچ اطلاعات حساسی (مثل گذرواژه یا کارت اعتباری) را در این سایت وارد کنید، زیرا ممکن است مهاجمین آن‌ها را سرقت کنند.</translation>
-<translation id="5843436854350372569">سعی داشتید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما سرور گواهینامه‌ای حاوی یک کلید ضعی٠ارائه کرد. ممکن است مهاجمی کلید خصوصی را شکسته باشد و ممکن است این سرور، سرور موردانتظار شما نباشد (ممکن است درحال ارتباط با یک مهاجم باشید). <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">دسترسی به این سایت امکان‌پذیر نیست</translation>
<translation id="5869522115854928033">گذرواژه‌های ذخیره‌شده</translation>
<translation id="5872918882028971132">پیشنهادات والدین</translation>
<translation id="5901630391730855834">زرد</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (همگام‌سازی‌شده)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{Û± Ú©ÙˆÚ©ÛŒ درحال استÙاده}one{# Ú©ÙˆÚ©ÛŒ درحال استÙاده}other{# Ú©ÙˆÚ©ÛŒ درحال استÙاده}}</translation>
<translation id="5926846154125914413">ممکن است دسترسی به محتوای ممتاز برخی از سایت‌ها را از دست بدهید.</translation>
<translation id="5959728338436674663">â€Ø§Ø±Ø³Ø§Ù„ خودکار برخی از <ph name="BEGIN_WHITEPAPER_LINK" />اطلاعات سیستم Ùˆ محتوای صÙحه<ph name="END_WHITEPAPER_LINK" /> به Google برای Ú©Ù…Ú© به شناسایی برنامه‌ها Ùˆ سایت‌های خطرناک. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Ù‡Ùته</translation>
<translation id="5967867314010545767">حذ٠از سابقه</translation>
<translation id="5975083100439434680">کوچک نمایی</translation>
<translation id="598637245381783098">برنامه پرداخت باز نشد</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{صÙحه Û±}one{صÙحه #}other{صÙحه #}}</translation>
<translation id="6017514345406065928">سبز</translation>
+<translation id="6017850046339264347">مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> می‌توانند برنامه‌های Ùریب‌دهنده‌ای نصب کنند Ú©Ù‡ وانمود می‌کنند چیز دیگری هستند یا داده‌هایی جمع‌آوری کنند Ú©Ù‡ ممکن است برای ردیابی شما استÙاده شوند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />، <ph name="TYPE_2" />، <ph name="TYPE_3" /> (همگام‌سازی‌شده)</translation>
<translation id="6027201098523975773">نامی وارد کنید</translation>
<translation id="6040143037577758943">بستن</translation>
<translation id="6042308850641462728">بیشتر</translation>
+<translation id="6047233362582046994">اگر خطری را که امنیتتان را تهدید می‌کند درک می‌کنید، می‌توانید قبل از حذ٠برنامه‌های مضر، <ph name="BEGIN_LINK" />از این سایت بازدید کنید<ph name="END_LINK" />.</translation>
+<translation id="6051221802930200923">درحال‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا وب‌سایت از پین کردن گواهینامه استÙاده می‌کند. خطاهای شبکه Ùˆ حمله‌ها موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد.</translation>
<translation id="6060685159320643512">مراقب باشید، این آزمایشات ممکن است خطرناک باشند</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{هیچ‌}=1{۱}one{#}other{#}}</translation>
+<translation id="6080696365213338172">شما با استÙاده از گواهی ارائه شده توسط سرپرست سیستم به محتوا دسترسی پیدا کرده‌اید. داده‌هایی Ú©Ù‡ به <ph name="DOMAIN" /> ارائه می‌کنید ممکن است توسط سرپرست سیستم رهگیری شوند.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{هیچ‌کدام}=1{۱ گذرواژه (همگام‌سازی‌شده)}one{# گذرواژه (همگام‌سازی‌شده)}other{# گذرواژه (همگام‌سازی‌شده)}}</translation>
<translation id="6146055958333702838">همه کابل‌ها را بررسی کنید و همه ره‌یاب‌ها، مودم‌ها، یا دیگر دستگاه‌های
 شبکه‌ای را Ú©Ù‡ ممکن است درحال استÙاده از آن‌ها باشید مجدداً راه‌اندازی کنید.</translation>
<translation id="614940544461990577">این موارد را امتحان کنید:</translation>
<translation id="6151417162996330722">دوره اعتبار گواهینامه سرور بسیار طولانی است.</translation>
<translation id="6157877588268064908">برای دیدن روش‌های ارسال و شرایط موردنیاز، یک نشانی انتخاب کنید</translation>
+<translation id="6158003235852588289">â€Â«Ù…رور ایمن Google» اخیراً در <ph name="SITE" /> Ùیشینگ شناسایی کرده است. سایت‌های Ùیشینگ وانمود می‌کنند وب‌سایت‌های دیگری هستند تا شما را Ùریب دهند.</translation>
<translation id="6165508094623778733">بیشتر بدانید</translation>
+<translation id="6169916984152623906">اکنون می‌توانید به‌طور خصوصی مرور کنید Ùˆ سایر اÙرادی Ú©Ù‡ از این دستگاه استÙاده می‌کنند Ùعالیت شما را نخواهند دید. بااین‌وجود بارگیری‌ها Ùˆ نشانک‌ها ذخیره خواهند شد.</translation>
<translation id="6177128806592000436">اتصال شما به این سایت امن نیست</translation>
<translation id="6184817833369986695">(هم‌گروه: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">اتصال اینترنتتان را بررسی کنید</translation>
<translation id="6218753634732582820">â€Ø¢Ø¯Ø±Ø³ از Chromium پاک شود؟</translation>
+<translation id="6221345481584921695">â€Google Safe Browsing به تازگی در <ph name="SITE" />ØŒ â€<ph name="BEGIN_LINK" />بداÙزار شناسایی کرده است<ph name="END_LINK" />. گاهی اوقات وب‌سایت‌هایی Ú©Ù‡ معمولاً امن هستند، با بداÙزار آلوده می‌شوند. منبع محتوای مخرب <ph name="SUBRESOURCE_HOST" /> است Ú©Ù‡ یک توزیع‌کننده بداÙزار شناخته شده، می‌باشد.</translation>
<translation id="6251924700383757765">خط‌مشی رازداری</translation>
<translation id="6254436959401408446">حاÙظه کاÙÛŒ برای باز کردن این صÙحه وجود ندارد</translation>
<translation id="625755898061068298">انتخاب کردید اخطارهای امنیتی برای این سایت غیرÙعال شود.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">ویرایش نشانک</translation>
<translation id="6410264514553301377">â€CVC†و تاریخ انقضای <ph name="CREDIT_CARD" /> را وارد کنید</translation>
<translation id="6414888972213066896">از والدینتان پرسیدید آیا اجازه بازدید از این سایت را دارید</translation>
-<translation id="6416403317709441254">â€Ø¯Ø±Ø­Ø§Ù„‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا این وب‌سایت اعتبارنامه‌های درهمی ارسال کرده است Ú©Ù‡ Chromium نمی‌تواند آن‌ها را پردازش کند. خطاها Ùˆ حمله‌های شبکه معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">امکان بررسی اینکه آیا مجوز باطل شده است یا نه وجود ندارد.</translation>
<translation id="6433490469411711332">ویرایش اطلاعات تماس</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> از اتصال خودداری کرد.</translation>
<translation id="6446608382365791566">اÙزودن اطلاعات بیشتر</translation>
+<translation id="6447842834002726250">کوکی‌ها</translation>
<translation id="6451458296329894277">تأیید ارسال مجدد Ùرم</translation>
<translation id="6456339708790392414">پرداخت شما</translation>
<translation id="6458467102616083041">نادیده گرÙته شد زیرا جستجوی پیش‌Ùرض توسط قانون غیرÙعال شده است.</translation>
-<translation id="6462969404041126431">این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ شاید گواهینامه امنیتی آن باطل شده باشد. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">خط‌‌مشی‌های دستگاه</translation>
<translation id="6477321094435799029">â€Chrome کد نامعمول در این این صÙحه شناسایی کرده Ùˆ برای محاÙظت از اطلاعات شخصی‌تان (مثلاً گذرواژه‌ها، شماره تلÙن‌‌ها Ùˆ کارت‌های اعتباری) آن را مسدود کرده است.</translation>
<translation id="6489534406876378309">شروع بارگذاری کردن خرابی‌ها</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">تاریخ انقضا: <ph name="EXPIRATION_DATE_ABBR" />ØŒ آخرین استÙاده: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">مدیرتان هنوز این سایت را تأیید نکرده است</translation>
<translation id="6569060085658103619">درحال مشاهده یک صÙحه اÙزونه هستید</translation>
-<translation id="6593753688552673085">کمتر از <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">شاید این محتوا تلاش کند نرم‌اÙزار خطرناکی در دستگاهتان نصب کند Ú©Ù‡ اطلاعاتتان را سرقت یا حذ٠می‌کند. <ph name="BEGIN_LINK" />درهرصورت نمایش داده شود<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">گزینه‌های رمزگذاری</translation>
<translation id="662080504995468778">ماندن</translation>
<translation id="6626291197371920147">اÙزودن شماره کارت معتبر</translation>
<translation id="6628463337424475685">جستجوی <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">â€Ø´Ø§ÛŒØ¯ درحال‌حاضر مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> در تلاش باشند برنامه‌های خطرناکی در Mac شما نصب کنند Ú©Ù‡ اطلاعاتتان (مانند عکس‌ها، گذرواژه‌ها، پیام‌ها Ùˆ کارت‌های اعتباری) را به سرقت می‌برند یا حذ٠می‌کنند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">این قانون قدیمی شده است.</translation>
-<translation id="6652240803263749613">این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن مورداعتماد سیستم‌عامل رایانه شما نیست. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">â€Ù¾ÛŒØ´Ù†Ù‡Ø§Ø¯ Ùرم از Chromium پاک شود؟</translation>
<translation id="6685834062052613830">خروج از سیستم و تکمیل راه‌اندازی</translation>
<translation id="6710213216561001401">قبلی</translation>
<translation id="6710594484020273272">&lt;عبارت جستجو را تایپ کنید&gt;</translation>
<translation id="6711464428925977395">مشکلی در سرور پروکسی وجود دارد یا این آدرس درست نیست.</translation>
<translation id="6727102863431372879">تنظیم</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{هیچ‌}=1{۱ مورد}one{# مورد}other{# مورد}}</translation>
<translation id="674375294223700098">خطای ناشناس گواهی سرور.</translation>
<translation id="6753269504797312559">مقدار خط‌‌مشی</translation>
<translation id="6757797048963528358">دستگاهتان به خواب رÙته است.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">شناسه سÙارشی‌سازی</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">داده‌های منطقه‌ها بارگیری نشد</translation>
+<translation id="6825578344716086703">â€ØªÙ„اش کردید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما گواهینامه ارائه‌شده از سوی سرور با استÙاده از یک الگوریتم امضای ضعی٠(مانند SHA-1) امضا شده است. یعنی ممکن است اعتبارنامه امنیتی ارائه‌شده از سوی سرور جعلی باشد Ùˆ ممکن است سرور، سرور موردانتظار شما نباشد (ممکن است با یک مهاجم در ارتباط باشید).</translation>
+<translation id="6830728435402077660">امن نیست</translation>
<translation id="6831043979455480757">ترجمه</translation>
<translation id="6839929833149231406">منطقه حکومتی</translation>
<translation id="6874604403660855544">&amp;انجام مجدد اÙزودن</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">کارتتان تأیید شد</translation>
<translation id="6897140037006041989">نماینده کاربر</translation>
<translation id="6915804003454593391">کاربر:</translation>
+<translation id="6945221475159498467">انتخاب</translation>
<translation id="6948701128805548767">برای دیدن روش‌های تحویل گرÙتن Ùˆ شرایط موردنیاز، یک نشانی انتخاب کنید</translation>
<translation id="6957887021205513506">به نظر می‌رسد که گواهی سرور جعلی باشد.</translation>
<translation id="6965382102122355670">قبول</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">â€Ù‡Ù… سرورهای پروکسی ثابت Ùˆ هم آدرس اسکریپت pac. مشخص شده‌اند.</translation>
<translation id="6989763994942163495">نمایش تنظیمات پیشرÙته ...</translation>
<translation id="7000990526846637657">هیچ ورودی سابقه‌ای پیدا نشد</translation>
-<translation id="7009986207543992532">سعی کردید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما سرور گواهینامه‌ای ارائه کرد که دوره اعتبار بیش از اندازه طولانی آن قابل‌اعتماد نیست. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">â€Ù…Ù…Ú©Ù† است «حساب Google» شما سابقه مروری به Ø´Ú©Ù„ دیگری در <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> داشته باشد</translation>
<translation id="7029809446516969842">گذرواژه‌ها</translation>
+<translation id="7050187094878475250">تلاش کردید به دامنه <ph name="DOMAIN" /> بروید اما گواهینامه‌ای که سرور ارائه کرد، دارای یک تاریخ اعتبار بسیار طولانی است و مورداعتماد نیست.</translation>
+<translation id="7053983685419859001">مسدود کردن</translation>
<translation id="7064851114919012435">اطلاعات تماس</translation>
<translation id="7079718277001814089">این سایت حاوی بداÙزار است</translation>
<translation id="7087282848513945231">شهرستان</translation>
-<translation id="7088615885725309056">قدیمی تر</translation>
<translation id="7090678807593890770">â€Ø¬Ø³ØªØ¬ÙˆÛŒ <ph name="LINK" /> در Google</translation>
+<translation id="7108819624672055576">توسط اÙزونه مجاز شده است</translation>
<translation id="7119414471315195487">برگه‌ها یا برنامه‌های دیگر را ببندید</translation>
<translation id="7129409597930077180">ارسال به این نشانی ممکن نیست. نشانی دیگری را انتخاب کنید.</translation>
<translation id="7138472120740807366">روش تحویل</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">درحال پردازش</translation>
<translation id="724691107663265825">این وب‌سایت بداÙزار دارد</translation>
<translation id="724975217298816891">â€Ø¨Ø±Ø§ÛŒ به‌روزرسانی جزئیات کارتتان، تاریخ انقضا Ùˆ CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید. بعد از تأیید شدن، جزئیات کارتتان با این سایت به اشتراک گذاشته می‌شود.</translation>
-<translation id="725866823122871198">اتصال خصوصی به <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> برقرار نمی‌شود زیرا تاریخ و زمان رایانه شما (<ph name="DATE_AND_TIME" />) نادرست است.</translation>
+<translation id="7260504762447901703">لغو دسترسی</translation>
<translation id="7275334191706090484">نشانک‌های مدیریت شده</translation>
<translation id="7298195798382681320">توصیه می‌شود</translation>
<translation id="7309308571273880165">گزارش خرابی ثبت‌شده در <ph name="CRASH_TIME" /> (کاربر درخواست بارگذاری کرده است، هنوز بارگذاری نشده است)</translation>
<translation id="7334320624316649418">&amp;انجام مجدد ترتیب‌بندی مجدد</translation>
<translation id="733923710415886693">گواهی سرور از طریق Ø´ÙاÙیت گواهینامه نشان داده نشده بود.</translation>
-<translation id="7351800657706554155">درحال‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا گواهینامه آن باطل شده است. خطاها Ùˆ حمله‌های شبکه معمولاً موقتی هستند، بنابراین احتمالاً این صÙحه بعداً کار خواهد کرد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">خط Ùرمان</translation>
<translation id="7372973238305370288">نتیجه جستجو</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">نه</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">تأیید کارت</translation>
-<translation id="7394102162464064926">آیا مطمئنید می‌خواهید این صÙحه‌ها را از سابقه حذ٠کنید؟
-
-توجه! حالت ناشناس <ph name="SHORTCUT_KEY" /> ممکن است بار بعد قابل استÙاده باشد.</translation>
<translation id="7400418766976504921">نشانی وب</translation>
<translation id="7419106976560586862">مسیر نمایه</translation>
<translation id="7424977062513257142">صÙحه جاسازی‌شده‌ای در این صÙحه وب می‌گوید:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">این سایت مسدود شده است</translation>
<translation id="7445762425076701745">هویت سروری Ú©Ù‡ به آن متصل شده‌اید به‌طور کامل راستی‌آزمایی نمی‌شود. با استÙاده از نامی به سرور متصل شده‌اید Ú©Ù‡ Ùقط در شبکه شما معتبر است Ùˆ ارائه دهنده مجوز خارجی قادر به راستی‌آزمایی مالکیت آن نیست. به دلیل آنکه برخی از ارائه دهندگان مجوز بدون توجه به هر موردی، مجوزهایی را برای این نام‌ها ارائه می‌کنند، روشی برای اطمینان از این امر وجود ندارد Ú©Ù‡ آیا شما به سایت مورد نظر خود متصل شده‌اید یا یک سایت مضر.</translation>
<translation id="7451311239929941790">درباره این مشکل <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">استÙاده از پیش‌Ùرض جهانی (مسدود)</translation>
<translation id="7460163899615895653">برگه‌های اخیر شما از دیگر دستگاه‌ها اینجا نشان داده می‌شوند</translation>
<translation id="7469372306589899959">درحال تایید کارت</translation>
<translation id="7481312909269577407">ارسال کردن</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">شناسه دستگاه خط‌مشی برگردانده‌شده خالی است یا با شناسه کنونی دستگاه مطابقت ندارد</translation>
<translation id="7514365320538308">بارگیری</translation>
<translation id="7518003948725431193">صÙحه وبی با این آدرس وب یاÙت نشد: <ph name="URL" /></translation>
+<translation id="7521387064766892559">جاوا اسکریپت</translation>
<translation id="7535087603100972091">مقدار</translation>
<translation id="7537536606612762813">اجباری</translation>
+<translation id="7542403920425041731">بعد از تأیید شما، جزئیات کارتتان با این سایت به اشتراک گذاشته می‌شود.</translation>
<translation id="7542995811387359312">تکمیل خودکار کارت اعتباری غیر Ùعال است زیرا این Ùرم از یک اتصال امن استÙاده نمی‌کند.</translation>
<translation id="7543525346216957623">از والدینتان بخواهید این کار را انجام دهد</translation>
<translation id="7549584377607005141">این صÙحه وب برای نمایش صحیح به داده‌هایی نیاز دارد Ú©Ù‡ قبلاً وارد کرده‌اید. می‌توانید این داده‌ها را دوباره ارسال کنید، اما با انجام این کار، هر اقدامی Ú©Ù‡ این صÙحه قبلاً انجام داده است تکرار می‌شود.</translation>
<translation id="7552846755917812628">نکته‌های زیر را امتحان کنید:</translation>
<translation id="7554791636758816595">برگهٔ جدید</translation>
+<translation id="7567204685887185387">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ ممکن است گواهی امنیتی آن به صورت تقلبی صادر شده باشد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> مخاطب دیگر}one{<ph name="CONTACT_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> مخاطب دیگر}other{<ph name="CONTACT_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> مخاطب دیگر}}</translation>
<translation id="7568593326407688803">این صÙحه به <ph name="ORIGINAL_LANGUAGE" /> است، آیا مایلید ترجمه شود؟</translation>
<translation id="7569952961197462199">â€Ú©Ø§Ø±Øª اعتباری از Chrome پاک شود؟</translation>
<translation id="7569983096843329377">سیاه</translation>
<translation id="7578104083680115302">â€Ø¨Ø§ استÙاده از کارت‌هایی Ú©Ù‡ با Google ذخیره کرده‌اید به‌سرعت در همه دستگاه‌هایتان پرداخت‌های سایت‌ها Ùˆ برنامه‌ها را انجام دهید.</translation>
<translation id="7588950540487816470">وب Ùیزیکی</translation>
<translation id="7592362899630581445">گواهی سرور محدودیت‌های نام را نقض می‌کند.</translation>
+<translation id="7598391785903975535">کمتر از <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> درحال حاضر نمی‌تواند این درخواست را انجام دهد.</translation>
<translation id="7600965453749440009">هرگز <ph name="LANGUAGE" /> ترجمه نشود</translation>
<translation id="7610193165460212391">مقدار خارج از محدوده <ph name="VALUE" /> است.</translation>
<translation id="7613889955535752492">انقضا: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">â€Ø´Ù…ا در حال حاضر داده‌هایی دارید Ú©Ù‡ با استÙاده از نسخه دیگری از گذرواژه حساب Google شما رمزگذاری شده‌اند. لطÙاً آن را در زیر وارد کنید.</translation>
-<translation id="7634554953375732414">اتصال شما به این سایت خصوصی نیست.</translation>
<translation id="7637571805876720304">â€Ú©Ø§Ø±Øª اعتباری از Chromium پاک شود؟</translation>
<translation id="765676359832457558">پنهان کردن تنظیمات پیشرÙته…</translation>
<translation id="7658239707568436148">لغو</translation>
+<translation id="7662298039739062396">تنظیم توسط اÙزونه کنترل می‌شود</translation>
<translation id="7667346355482952095">کد خط‌مشی برگردانده‌شده خالی است یا با کد کنونی مطابقت ندارد</translation>
<translation id="7668654391829183341">دستگاه ناشناس</translation>
<translation id="7669271284792375604">مهاجمان در این سایت ممکن است تلاش کنند شما را با نصب برنامه‌هایی Ú©Ù‡ به تجربه مرور شما آسیب می‌رساند، Ùریب دهند (مثلاً با تغییر دادن صÙحه اصلی شما یا با نشان دادن آگهی‌های بیش از حد در سایت‌هایی Ú©Ù‡ بازدید می‌کنید).</translation>
<translation id="7674629440242451245">â€Ø¹Ù„اقه‌مند به قابلیت‌های جدید Ùˆ جالب Chrome هستید؟ کانال برنامه‌نویسان ما را در chrome.com/dev امتحان کنید.</translation>
<translation id="7682287625158474539">ارسال</translation>
+<translation id="7701040980221191251">هیچ کدام</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />ادامه به <ph name="SITE" /> (غیرایمن)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">گواهی</translation>
+<translation id="7716147886133743102">توسط سرپرست مسدود شده است</translation>
<translation id="7716424297397655342">این سایت نمی‌تواند از حاÙظه پنهان بار شود</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">مدیریت نشده</translation>
<translation id="7755287808199759310">والدینتان می‌توانند این سایت را برای شما بگشایند</translation>
<translation id="7758069387465995638">دیوار آتش یا نرم‌اÙزار ضدویروس ممکن است مانع اتصال شده باشد.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(۳۲ بیت)</translation>
<translation id="7956713633345437162">نشانک‌های تلÙن‌ همراه</translation>
<translation id="7961015016161918242">هرگز</translation>
-<translation id="7962083544045318153">شناسه خرابی <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">همیشه <ph name="ORIGINAL_LANGUAGE" /> به <ph name="TARGET_LANGUAGE" /> ترجمه شود</translation>
<translation id="7995512525968007366">تعیین نشده</translation>
<translation id="800218591365569300">سعی کنید برگه‌ها یا برنامه‌های دیگر را ببندید تا حاÙظه آزاد شود.</translation>
<translation id="8012647001091218357">در حال حاضر نمی‌توانیم با والدینتان ارتباط برقرار کنیم. لطÙاً دوباره امتحان کنید.</translation>
<translation id="8025119109950072390">مهاجمان در این سایت ممکن است شما را Ùریب دهند Ú©Ù‡ کارهای خطرناکی مثل نصب نرم‌اÙزار یا ارائه اطلاعات شخصی‌تان (مثلاً گذرواژه‌ها، شماره تلÙن‌ها یا کارت‌های اعتباری) انجام دهید.</translation>
-<translation id="803030522067524905">â€Â«Ù…رور ایمن Google» به‌تازگی در <ph name="SITE" /> Ùیشینگ شناسایی کرده است. سایت‌های Ùیشینگ برای Ùریب دادن شما وانمود می‌کنند سایت‌های دیگری هستند. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">این صÙحه به زبان <ph name="SOURCE_LANGUAGE" /> است. مایلید آن را به <ph name="TARGET_LANGUAGE" /> ترجمه کنید؟</translation>
+<translation id="8037357227543935929">درخواست (پیش‌Ùرض)</translation>
<translation id="8041089156583427627">ارسال بازخورد</translation>
+<translation id="8041940743680923270">استÙاده از پیش‌Ùرض جهانی (سؤال شود)</translation>
<translation id="8088680233425245692">مشاهده مقاله ناموÙÙ‚ بود.</translation>
<translation id="8089520772729574115">کمتر از ۱ مگابایت</translation>
<translation id="8091372947890762290">Ùعال‌سازی در سرور در حالت تعلیق است</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007">â€<ph name="BEGIN_ABBR" />نشانی DNS<ph name="END_ABBR" /> سرور <ph name="HOST_NAME" /> پیدا نشد.</translation>
<translation id="8149426793427495338">رایانه‌تان به خواب رÙته است.</translation>
<translation id="8150722005171944719">این Ùایل در <ph name="URL" /> قابل خواندن نیست. ممکن است حذ٠شده، جابجا شده باشد Ùˆ یا مجوزهای Ùایل از دسترسی جلوگیری می‌کنند.</translation>
+<translation id="8184538546369750125">استÙاده از پیش‌Ùرض جهانی (مجاز)</translation>
+<translation id="8191494405820426728">شناسه خرابی محلی <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;واگرد انتقال</translation>
<translation id="8201077131113104583">نشانی وب به‌روزرسانی نامعتبر برای برنامه اÙزودنی با شناسه «<ph name="EXTENSION_ID" />».</translation>
<translation id="8202097416529803614">خلاصه سÙارش</translation>
<translation id="8218327578424803826">مکان اختصاص یاÙته:</translation>
<translation id="8225771182978767009">شخصی که این رایانه را راه‌اندازی کرده این سایت را مسدود کرده است.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />،†<ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">مهاجم‌ها در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ممکن است تلاش کنند تا برنامه‌های خطرناکی در رایانه شما نصب کنند که اطلاعات شما (مانند کارت‌های اعتباری، عکس‌ها، گذرواژه‌ها و پیام‌هایتان) را سرقت یا حذ٠می‌کنند.</translation>
<translation id="8241707690549784388">صÙحه‌ای Ú©Ù‡ جستجو می‌کنید از اطلاعاتی استÙاده می‌کند Ú©Ù‡ شما وارد کرده‌اید. بازگشت به آن صÙحه ممکن است باعث شود اقدامی را Ú©Ù‡ قبلاً انجام دادید دوباره تکرار کنید. آیا می‌خواهید ادامه دهید؟</translation>
<translation id="8249320324621329438">آخرین واکشی شده:</translation>
<translation id="8253091569723639551">نشانی صورت‌حساب لازم است</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">اگر این موضوع را متوجه نمی‌شوید، با سرپرست شبکه‌تان تماس بگیرید.</translation>
<translation id="8293206222192510085">اÙزودن نشانک</translation>
<translation id="8294431847097064396">منبع</translation>
+<translation id="8306404619377842860">برقراری اتصال خصوصی با <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ممکن نیست، زیرا تاریخ و زمان دستگاهتان (<ph name="DATE_AND_TIME" />) نادرست است. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">ترجمه انجام نشد چون مشکلی در اتصال به شبکه رخ داد.</translation>
<translation id="8332188693563227489">دسترسی به <ph name="HOST_NAME" /> رد شد</translation>
<translation id="834457929814110454">اگر خطرات امنیتی‌ای که متوجه شما هستند را درک می‌کنید، می‌توانید قبل از حذ٠شدن برنامه‌های خطرناک، <ph name="BEGIN_LINK" />از این سایت بازدید کنید<ph name="END_LINK" />.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">â€Ø¨Ø±Ø§ÛŒ استÙاده از کارت‌ها از حساب Google خود، به سیستم Chrome وارد شوید</translation>
<translation id="8488350697529856933">اعمال برای</translation>
<translation id="8498891568109133222">پاسخ <ph name="HOST_NAME" /> بیش از حد طول کشیده است.</translation>
-<translation id="852346902619691059">این سرور نتوانست ثابت کند <ph name="DOMAIN" /> است؛ گواهینامه امنیتی آن مورداعتماد سیستم‌عامل دستگاه شما نیست. ممکن است پیکربندی اشتباهی علت آن باشد یا مهاجمی اتصالتان را قطع کرده باشد. <ph name="BEGIN_LEARN_MORE_LINK" />بیشتر بدانید<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">سال انقضا</translation>
<translation id="8543181531796978784">می‌توانید <ph name="BEGIN_ERROR_LINK" />یک مشکل شناسایی‌شده را گزارش کنید<ph name="END_ERROR_LINK" /> یا اگر از خطراتی که امنیت شما را تهدید می‌کنند مطلع شدید، <ph name="BEGIN_LINK" />از این سایت ناامن دیدن کنید<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">ترجمه انجام نشد زیرا زبان صÙحه تعیین نشد.</translation>
-<translation id="8559762987265718583">اتصال خصوصی به <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> انجام نمی‌شود، زیرا تاریخ و زمان دستگاه شما (<ph name="DATE_AND_TIME" />) نادرست است.</translation>
<translation id="8571890674111243710">ترجمه صÙحه به <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">اÙزودن شماره تلÙÙ†</translation>
<translation id="859285277496340001">این مجوز هیچ مکانیزمی را برای بررسی اینکه آیا باطل شده یا نه مشخص نمی‌کند.</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">â€Ø¨Ù‡ منظور برقراری یک اتصال امن، لازم است Ú©Ù‡ ساعت شما به درستی تنظیم شود. زیرا گواهینامه‌هایی Ú©Ù‡ وب‌سایت‌ها برای شناسایی خودشان استÙاده می‌کنند تنها برای دوره‌های زمانی خاصی معتبر هستند. از آنجایی Ú©Ù‡ ساعت دستگاه نادرست است، Chromium نمی‌تواند این گواهینامه‌ها را تأیید کند.</translation>
<translation id="8740359287975076522">â€<ph name="HOST_NAME" />’s &lt;abbr id="dnsDefinition"&gt;آدرس DNS&lt;/abbr&gt; پیدا نشد. درحال بررسی برای تشخیص مشکل.</translation>
<translation id="8759274551635299824">کارت منقضی شده است</translation>
+<translation id="8761567432415473239">â€Ù…رور ایمن Google اخیراً <ph name="BEGIN_LINK" />برنامه‌های خطرناک<ph name="END_LINK" /> را در <ph name="SITE" /> پیدا کرده است.</translation>
<translation id="8790007591277257123">&amp;انجام مجدد حذÙ</translation>
<translation id="8800988563907321413">پیشنهادات اطرا٠شما در اینجا نشان داده می‌شوند</translation>
<translation id="8820817407110198400">نشانک‌ها</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">اخیراً بسته‌شده</translation>
<translation id="8874824191258364635">شماره کارت معتبری وارد کنید</translation>
<translation id="8876793034577346603">پیکربندی شبکه نتوانست تجزیه شود.</translation>
-<translation id="8877192140621905067">بعد از تأیید کردن، جزئیات کارتتان با این سایت به اشتراک گذاشته می‌شود</translation>
<translation id="8889402386540077796">رنگ‌مایه</translation>
<translation id="8891727572606052622">حالت پروکسی نامعتبر است.</translation>
<translation id="889901481107108152">متأسÙیم، این آزمایش بر روی دستگاه شما قابل انجام نیست.</translation>
<translation id="8903921497873541725">بزرگ‌نمایی</translation>
<translation id="8931333241327730545">â€Ù…ی‌خواهید این کارت را در حساب Google خود ذخیره کنید؟</translation>
<translation id="8932102934695377596">ساعت شما عقب است</translation>
-<translation id="8954894007019320973">(ادامه)</translation>
<translation id="8971063699422889582">گواهی سرور منقضی شده است.</translation>
<translation id="8986494364107987395">â€Ø§Ø±Ø³Ø§Ù„ خودکار آمار کاربرد Ùˆ گزارش‌های خرابی به Google</translation>
-<translation id="8987927404178983737">ماه</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">سایت در پیش‌رو حاوی برنامه‌های خطرناک است</translation>
+<translation id="8997023839087525404">سرور گواهی‌ای را ارائه کرده است Ú©Ù‡ با استÙاده از خط‌مشی Ø´ÙاÙیت گواهینامه به‌صورت عمومی نشان داده نشده است. برای برخی گواهی‌ها این یک مسئله ضروری است تا از قابل اعتماد بودن آن‌ها Ùˆ محاÙظت دربرابر مهاجمین اطمینان حاصل شود.</translation>
<translation id="9001074447101275817">پروکسی <ph name="DOMAIN" /> به نام کاربری و گذرواژه نیاز دارد.</translation>
+<translation id="9005998258318286617">â€Ø³Ù†Ø¯ PDF بارگیری نشد.</translation>
<translation id="901974403500617787">پرچم‌هایی Ú©Ù‡ در تمام سیستم اعمال می‌شوند Ùقط توسط مالک قابل تنظیم هستند: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">نشانی صورت‌حساب کارت لازم است</translation>
<translation id="9020542370529661692">این صÙحه به <ph name="TARGET_LANGUAGE" /> ترجمه شده است</translation>
<translation id="9035022520814077154">خطای امنیتی</translation>
<translation id="9038649477754266430">استÙاده از یک سرویس پیش‌بینی برای بار کردن سریع‌تر صÙحه‌ها</translation>
<translation id="9039213469156557790">علاوه بر این، این صÙحه دارای منابع دیگری است Ú©Ù‡ امن نیستند. دیگران می‌توانند در حین انتقال، این منابع را ببینند Ùˆ این منابع می‌توانند برای تغییر رÙتار صÙحه، توسط یک مهاجم تغییر داده شوند.</translation>
-<translation id="9040185888511745258">ممکن است مهاجمان در <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> با Ùریب شما تلاش کنند شما را به نصب برنامه‌هایی تشویق کنند Ú©Ù‡ به تجربه مرورتان آسیب می‌رساند (برای مثال با تغییر صÙحه اصلی‌تان یا نشان دادن آگهی‌های زیادی در سایت‌هایی Ú©Ù‡ بازدید می‌کنید).</translation>
+<translation id="9049981332609050619">شما سعی کردید به <ph name="DOMAIN" /> دسترسی داشته باشید، اما سرور یک گواهی نامعتبر را نشان داد.</translation>
<translation id="9050666287014529139">عبارت عبور</translation>
<translation id="9065203028668620118">ویرایش</translation>
<translation id="9068849894565669697">انتخاب رنگ</translation>
+<translation id="9069693763241529744">توسط اÙزونه مسدود شده است</translation>
<translation id="9076283476770535406">این سایت ممکن است شامل محتوای مخصوص بزرگسالان باشد</translation>
<translation id="9078964945751709336">اطلاعات بیشتری نیاز است</translation>
<translation id="9103872766612412690">â€<ph name="SITE" /> معمولاً برای محاÙظت از اطلاعات شما از رمزگذاری استÙاده می‌کند. اما این بار Ú©Ù‡ Chromium تلاش کرد به <ph name="SITE" /> متصل شود، وب‌سایت اعتبارنامه‌ای نامعمول Ùˆ نادرست را برگرداند. ممکن است مهاجمی در تلاش باشد خود را به‌جای <ph name="SITE" /> معرÙÛŒ کند یا یک صÙحه ورود به سیستم Wi-Fi در ارتباط اختلال ایجاد کرده باشد. اطلاعات شما همچنان ایمن است، زیرا Chromium قبل از هرگونه تبادل داده، اتصال را متوق٠کرد.</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">&amp;واگرد ویرایش</translation>
<translation id="9154194610265714752">به‌روزرسانی ‌شد</translation>
<translation id="9157595877708044936">در حال راه‌اندازی...</translation>
+<translation id="9169664750068251925">همیشه مسدود در این سایت</translation>
<translation id="9170848237812810038">&amp;واگرد</translation>
<translation id="917450738466192189">گواهی سرور نامعتبر است.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> گزینه دیگر}one{<ph name="SHIPPING_OPTION_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> گزینه دیگر}other{<ph name="SHIPPING_OPTION_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> گزینه دیگر}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> از یک پروتکل پشتیبانی‌نشده استÙاده می‌کند.</translation>
<translation id="9205078245616868884">داده‌های شما با عبارت عبور همگام‌سازی رمزگذاری می‌شود. برای شروع همگام‌سازی آن را وارد کنید.</translation>
<translation id="9207861905230894330">اÙزودن مقاله ناموÙÙ‚ بود.</translation>
+<translation id="9219103736887031265">تصاویر</translation>
<translation id="933612690413056017">اتصال اینترنت قطع است</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">پاک کردن Ùرم</translation>
<translation id="939736085109172342">پوشهٔ جدید</translation>
<translation id="941721044073577244">گویا اجازه بازدید از این سایت را ندارید</translation>
<translation id="969892804517981540">ساخت رسمی</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{هیچ‌کدام}=1{۱ مورد}one{# مورد}other{# مورد}}</translation>
<translation id="988159990683914416">ساخت برنامه‌نویس</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fi.xtb b/chromium/components/strings/components_strings_fi.xtb
index 6ebd0c6f391..9085de7e6a8 100644
--- a/chromium/components/strings/components_strings_fi.xtb
+++ b/chromium/components/strings/components_strings_fi.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Käännä myötäpäivään</translation>
<translation id="1038842779957582377">tuntematon nimi</translation>
<translation id="1050038467049342496">Sulje muita sovelluksia.</translation>
-<translation id="1053591932240354961">Et voi siirtyä juuri nyt sivustolle <ph name="SITE" />, sillä se lähetti sekoitettuja tunnistetietoja, joita Google Chrome ei voi käsitellä. Verkkovirheet ja ‑hyökkäykset ovat yleensä väliaikaisia, joten voit todennäköisesti vierailla sivustolla myöhemmin. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">K&amp;umoa lisäys</translation>
<translation id="10614374240317010">Ei tallenneta</translation>
<translation id="106701514854093668">Työpöytäkirjanmerkit</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Käytännön välimuisti on OK</translation>
<translation id="113188000913989374">Viesti osoitteesta <ph name="SITE" />:</translation>
<translation id="1132774398110320017">Chromen automaattisen täytön asetukset…</translation>
+<translation id="1150979032973867961">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; tietokoneesi käyttöjärjestelmä ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
+<translation id="1151972924205500581">Salasana vaaditaan</translation>
<translation id="1152921474424827756">Käytä osoitteen <ph name="URL" /> <ph name="BEGIN_LINK" />välimuistiversiota<ph name="END_LINK" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> katkaisi yhteyden yllättäen.</translation>
<translation id="1161325031994447685">Muodosta yhteys Wi-Fi-verkkoon uudelleen.</translation>
+<translation id="1165039591588034296">Virhe</translation>
<translation id="1175364870820465910">Tulo&amp;sta...</translation>
<translation id="1181037720776840403">Poista</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Ilmoita Googlelle automaattisesti<ph name="END_WHITEPAPER_LINK" /> mahdollisista turvallisuusongelmista. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Lisää tästä sivustosta</translation>
<translation id="1206967143813997005">Virheellinen alkuperäinen allekirjoitus</translation>
<translation id="1209206284964581585">Piilota toistaiseksi</translation>
+<translation id="121201262018556460">Yritit yhdistää verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti varmenteen, joka käyttää heikkoa avainta. Hakkeri on saattanut murtaa avaimen. Palvelin ei siis välttämättä ole tavoittelemasi palvelin, vaan saatat viestiä hakkerin kanssa.</translation>
<translation id="1219129156119358924">Järjestelmän suojaus</translation>
<translation id="1227224963052638717">Tuntematon käytäntö.</translation>
<translation id="1227633850867390598">Piilota arvo</translation>
<translation id="1228893227497259893">Väärä entiteettitunnus</translation>
<translation id="1232569758102978740">Nimetön</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synkronoitu)</translation>
<translation id="1263231323834454256">Lukulista</translation>
<translation id="1264126396475825575">Kaatumisraportti tallennettu <ph name="CRASH_TIME" /> (ei vielä lähetetty tai ohitettu)</translation>
+<translation id="1281526147609854549">Myöntäjä: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Vaarallinen sisältö estetty</translation>
<translation id="1285320974508926690">Älä käännä tätä sivustoa</translation>
<translation id="129553762522093515">Hiljattain suljetut välilehdet</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Tyhjennä evästeet.<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Toimintasi <ph name="BEGIN_EMPHASIS" />saattaa silti näkyä<ph name="END_EMPHASIS" />
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />käymillesi verkkosivustoille
+ <ph name="LIST_ITEM" />työnantajallesi tai oppilaitoksellesi
+ <ph name="LIST_ITEM" />internetpalveluntarjoajallesi.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Käyttöönoton verkkotunnus:</translation>
<translation id="1340482604681802745">Nouto-osoite</translation>
<translation id="1344211575059133124">Vaikuttaa siltä, että tarvitset luvan tämän sivuston käyttämiseen.</translation>
<translation id="1344588688991793829">Chromiumin automaattisen täytön asetukset…</translation>
+<translation id="1348198688976932919">Sivusto sisältää vaarallisia sovelluksia</translation>
<translation id="1374468813861204354">ehdotuksia</translation>
<translation id="1375198122581997741">Tietoja versiosta</translation>
<translation id="1377321085342047638">Kortin numero</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ei lähettänyt tietoja.</translation>
<translation id="1407135791313364759">Avaa kaikki</translation>
<translation id="1413809658975081374">Tietosuojavirhe</translation>
+<translation id="14171126816530869">Organisaation <ph name="ORGANIZATION" /> identiteetin sijainnissa <ph name="LOCALITY" /> on vahvistanut <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Kyllä</translation>
<translation id="1430915738399379752">Tulosta</translation>
-<translation id="1442912890475371290">Estetty yritys <ph name="BEGIN_LINK" /> siirtyä sivulle <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Et voi siirtyä juuri nyt sivustolle <ph name="SITE" />, sillä se käyttää varmenteiden kiinnittämistä. Verkkovirheet ja ‑hyökkäykset ovat yleensä väliaikaisia, joten voit todennäköisesti vierailla sivustolla myöhemmin. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> toinen}other{<ph name="PAYMENT_METHOD_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> muuta}}</translation>
<translation id="1506687042165942984">Näytä tallennettu (eli vanhentuneeksi tiedetty) kopio tästä sivusta.</translation>
<translation id="1517433312004943670">Puhelinnumero vaaditaan</translation>
<translation id="1519264250979466059">Koontipäivä</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Tämän ominaisuuden käyttö edellyttää JavaScriptiä.</translation>
<translation id="1555130319947370107">Sininen</translation>
<translation id="1559528461873125649">Tiedostoa tai hakemistoa ei ole olemassa</translation>
-<translation id="1559572115229829303">&lt;p&gt;Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska laitteesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset.&lt;/p&gt;
-
- &lt;p&gt;Muokkaa aikaa ja päivämäärää &lt;strong&gt;Asetukset&lt;/strong&gt;‑sovelluksen &lt;strong&gt;Yleistä&lt;/strong&gt;‑osiossa.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Jokin meni vikaan tätä verkkosivua näytettäessä.</translation>
<translation id="1592005682883173041">Tietojen paikallinen käyttö</translation>
+<translation id="1594030484168838125">Valitse</translation>
<translation id="161042844686301425">Turkoosi</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Haluatko, että Chrome tallentaa tämän kortin?</translation>
<translation id="1639239467298939599">Ladataan</translation>
<translation id="1640180200866533862">Käyttäjäkäytännöt</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Verkkoasetukset ovat virheelliset eikä niitä voi tuoda.</translation>
<translation id="1644574205037202324">Historia</translation>
<translation id="1645368109819982629">Protokollaa ei tueta</translation>
+<translation id="1655462015569774233">{1,plural, =1{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne vanhentui eilen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä. Tietokoneesi kellonaika on tällä hetkellä <ph name="CURRENT_DATE" />. Onko se oikein? Jos ei, korjaa järjestelmän kellonaika ja päivitä sivu.}other{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne vanhentui # päivää sitten. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä. Tietokoneesi kellonaika on tällä hetkellä <ph name="CURRENT_DATE" />. Onko se oikein? Jos ei, korjaa järjestelmän kellonaika ja päivitä sivu.}}</translation>
<translation id="1656489000284462475">Noutoaika</translation>
<translation id="1663943134801823270">Kortit ja osoitteet ovat peräisin Chromesta. Voit hallinnoida niitä <ph name="BEGIN_LINK" />asetuksissa<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> suojaa tietosi normaalisti salauksen avulla. Kun Chrome yritti tällä kertaa yhdistää sivustoon <ph name="SITE" />, sivusto palautti epätavalliset ja virheelliset kirjautumistiedot. Hyökkääjä saattaa yrittää esiintyä sivustona <ph name="SITE" />, tai Wi-Fi-kirjautumisruutu on keskeyttänyt yhteyden. Tietosi ovat edelleen turvassa, sillä Google Chrome katkaisi yhteyden, ennen kuin mitään tietoja vaihdettiin.</translation>
-<translation id="168328519870909584">Sivustolle <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää asentaa laitteellesi vaarallisia ohjelmia, jotka varastavat tai poistavat tietojasi, kuten kuviasi, salasanojasi, viestejäsi ja luottokorttiesi tietoja.</translation>
<translation id="168841957122794586">Palvelinvarmenne sisältää heikon salausavaimen.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne on päivätty huomiselle. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.}other{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne on päivätty # päivää tulevaisuuteen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.}}</translation>
<translation id="1710259589646384581">Käyttöjärjestelmä</translation>
<translation id="1721312023322545264">Tarvitset henkilön <ph name="NAME" /> luvan käydä tällä sivustolla</translation>
<translation id="1721424275792716183">* Kenttä on pakollinen.</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Lataa sivu myöhemmin</translation>
<translation id="17513872634828108">Avoimet välilehdet</translation>
<translation id="1753706481035618306">Sivunumero</translation>
+<translation id="1763864636252898013">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; laitteesi käyttöjärjestelmä ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Kokeile Windowsin verkon diagnostiikkaa<ph name="END_LINK" /></translation>
<translation id="1783075131180517613">Päivitä synkronoinnin tunnuslause.</translation>
<translation id="1787142507584202372">Avoimet välilehdet näkyvät tässä.</translation>
+<translation id="1789575671122666129">Ponnahdusikkunat</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Kortinhaltijan nimi</translation>
-<translation id="1803678881841855883">Googlen selaussuoja <ph name="BEGIN_LINK" />havaitsi äskettäin haittaohjelman<ph name="END_LINK" /> sivustolla <ph name="SITE" />. Myös tavallisesti turvalliset verkkosivustot voivat joskus saada haittaohjelmatartunnan. Haitallisen sisällön lähde on <ph name="SUBRESOURCE_HOST" />, tunnettu haittaohjelmien jakelija. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Lisätty: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Pyyntö on virheellinen tai pyynnön parametrit ovat virheelliset</translation>
<translation id="1826516787628120939">Tarkistetaan</translation>
<translation id="1834321415901700177">Tämä sivusto sisältää haitallisia ohjelmia</translation>
+<translation id="1840414022444569775">Tämä korttinumero on jo käytössä.</translation>
<translation id="1842969606798536927">Maksa</translation>
<translation id="1871208020102129563">Välityspalvelin on asetettu käyttämään kiinteitä välityspalvelimia, ei .pac-URL-osoitetta.</translation>
<translation id="1871284979644508959">Pakollinen tieto</translation>
<translation id="187918866476621466">Avaa aloitussivut</translation>
<translation id="1883255238294161206">Tiivistä luettelo</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> toinen}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> muuta}}</translation>
<translation id="1898423065542865115">Suodatus</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ei mitään}=1{1 sivusto}other{# sivustoa}}</translation>
<translation id="194030505837763158">Siirry osoitteeseen <ph name="LINK" /></translation>
<translation id="1962204205936693436">Verkkotunnuksen <ph name="DOMAIN" /> kirjanmerkit</translation>
<translation id="1973335181906896915">Sarjaesittämisen virhe</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ei käytetä – käytännön <ph name="POLICY_NAME" /> ohittama.</translation>
<translation id="2138201775715568214">Etsitään lähistöllä olevia Fyysisen webin sivuja</translation>
<translation id="213826338245044447">Mobiilikirjanmerkit</translation>
-<translation id="2148716181193084225">Tänään</translation>
+<translation id="2147827593068025794">Taustasynkronointi</translation>
<translation id="2154054054215849342">Synkronointi ei ole käytettävissä verkkotunnuksessasi.</translation>
<translation id="2154484045852737596">Muokkaa korttia</translation>
<translation id="2166049586286450108">Järjestelmänvalvojan täydet käyttöoikeudet</translation>
<translation id="2166378884831602661">Tämä sivusto ei voi tarjota suojattua yhteyttä</translation>
<translation id="2181821976797666341">Käytännöt</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 osoite}other{# osoitetta}}</translation>
+<translation id="2187317261103489799">Tunnista (oletus)</translation>
<translation id="2202020181578195191">Anna kelvollinen viimeinen voimassaolovuosi.</translation>
<translation id="2212735316055980242">Käytäntöä ei löydy</translation>
<translation id="2213606439339815911">Noudetaan merkintöjä…</translation>
+<translation id="2218879909401188352">Sivustolla <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> tällä hetkellä olevat hyökkääjät voivat asentaa vaarallisia laitettasi vahingoittavia sovelluksia, lisätä piilomaksuja puhelinlaskuusi tai varastaa henkilökohtaisia tietojasi. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Korjaa yhteytesi käyttämällä <ph name="BEGIN_LINK" />diagnostiikkasovellusta<ph name="END_LINK" />.</translation>
<translation id="2239100178324503013">Lähetä nyt</translation>
<translation id="225207911366869382">Tämän käytännön arvo on vanhentunut.</translation>
<translation id="2262243747453050782">HTTP-virhe</translation>
+<translation id="2270484714375784793">Puhelinnumero</translation>
<translation id="2282872951544483773">Ei käytettävissä olevat kokeilut</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> kohde}other{<ph name="ITEM_COUNT" /> kohdetta}}</translation>
<translation id="2292556288342944218">Internetyhteytesi on estetty</translation>
<translation id="230155334948463882">Uusi kortti?</translation>
-<translation id="2305919008529760154">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />. Sen suojausvarmenne on ehkä myönnetty vilpillisesti. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> pyytää käyttäjänimeä ja salasanaa.</translation>
-<translation id="2318774815570432836">Et juuri nyt voi siirtyä sivustolle <ph name="SITE" />, sillä se käyttää HSTS:ää. Verkkovirheet ja ‑hyökkäykset ovat yleensä väliaikaisia, joten voit todennäköisesti vierailla sivustolla myöhemmin. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Järjestelmänvalvojan hallinnoima asetus</translation>
<translation id="2354001756790975382">Muut kirjanmerkit</translation>
+<translation id="2354430244986887761">Google-selaussuoja <ph name="BEGIN_LINK" />löysi äskettäin haitallisia sovelluksia<ph name="END_LINK" /> sivustolta <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Hyökkääjät voivat mahdollisesti nähdä kuvat, joita katselet tällä sivustolla, ja huijata sinua muokkaamalla niitä.</translation>
+<translation id="2356070529366658676">Kysy</translation>
+<translation id="2359629602545592467">Useita</translation>
<translation id="2359808026110333948">Jatka</translation>
<translation id="2365563543831475020">Kaatumisraportti tallennettu <ph name="CRASH_TIME" />, ei vielä lähetetty</translation>
<translation id="2367567093518048410">Taso</translation>
-<translation id="2371153335857947666">{1,plural, =1{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenne vanhentui eilen. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. Tietokoneesi kellonaika on tällä hetkellä <ph name="CURRENT_DATE" />. Onko se oikein? Jos ei, korjaa järjestelmän kellonaika ja päivitä sivu. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" />}other{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenne vanhentui # päivää sitten. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. Tietokoneesi kellonaika on tällä hetkellä <ph name="CURRENT_DATE" />. Onko se oikein? Jos ei, korjaa järjestelmän kellonaika ja päivitä sivu. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">Käyttöliittymävaihtoehtoja ei ole saatavilla</translation>
<translation id="2384307209577226199">Yrityksen oletus</translation>
<translation id="2386255080630008482">Palvelimen varmenne on kumottu.</translation>
<translation id="2392959068659972793">Näytä käytännöt, joille ei ole asetettu arvoa</translation>
<translation id="239429038616798445">Lähetystapa ei ole käytettävissä. Kokeile toista tapaa.</translation>
<translation id="2396249848217231973">K&amp;umoa poisto</translation>
-<translation id="2460160116472764928">Googlen selaussuoja <ph name="BEGIN_LINK" />havaitsi äskettäin haittaohjelman<ph name="END_LINK" /> sivustolla <ph name="SITE" />. Myös tavallisesti turvalliset verkkosivustot voivat joskus saada haittaohjelmatartunnan. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne ei välttämättä ole voimassa. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="2463739503403862330">Täytä</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />verkon diagnostiikkaa<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Virheellinen hakukoneen URL-osoite.</translation>
+<translation id="2482878487686419369">Ilmoitukset</translation>
<translation id="2491120439723279231">Palvelimen varmenteessa on virheitä.</translation>
<translation id="2495083838625180221">JSON-jäsentäjä</translation>
<translation id="2495093607237746763">Jos tämä on valittu, Chromium tallentaa kortin kopion tälle laitteelle nopeuttaakseen lomakkeiden täyttöä.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Takaisin</translation>
<translation id="2515629240566999685">Tarkista alueesi mobiilisignaali.</translation>
<translation id="2516305470678292029">Käyttöliittymävaihtoehdot</translation>
+<translation id="2539524384386349900">Tunnista</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> lähetti virheellisen vastauksen.</translation>
-<translation id="2552545117464357659">Uudempi</translation>
<translation id="2556876185419854533">K&amp;umoa muokkaus</translation>
<translation id="2587730715158995865">Julkaisijalta <ph name="ARTICLE_PUBLISHER" />. Lue tämä ja <ph name="OTHER_ARTICLE_COUNT" /> muuta tarinaa.</translation>
<translation id="2587841377698384444">Hakemistosovellusliittymän tunnus:</translation>
<translation id="2597378329261239068">Tämä asiakirja on suojattu salasanalla. Anna salasana.</translation>
<translation id="2609632851001447353">Muunnelmat</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ei mitään}=1{1 sovellus ($1)}=2{2 sovellusta ($1 ja $2)}other{# sovellusta ($1, $2 ja $3)}}</translation>
<translation id="2625385379895617796">Kellosi edistää</translation>
<translation id="2639739919103226564">Tila:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Tiedoston käyttöoikeus evättiin</translation>
<translation id="2653659639078652383">Lähetä</translation>
<translation id="2666117266261740852">Sulje muita välilehtiä tai sovelluksia.</translation>
+<translation id="2670429602441959756">Tämä sivu sisältää ominaisuuksia, joita ei vielä tueta virtuaalitodellisuudessa. Jännittävää…</translation>
<translation id="2674170444375937751">Haluatko varmasti poistaa nämä sivut historiastasi?</translation>
<translation id="2677748264148917807">Poistu</translation>
-<translation id="269990154133806163">Palvelimen lähettämän varmenteen tietoja ei ole annettu yleiseen käyttöön Certificate Transparency ‑käytännön mukaisesti. Tietojen antamista edellytetään joitakin varmenteita käytettäessä, jotta niiden luotettavuus voidaan varmistaa ja käyttäjiä voidaan suojella hakkereilta. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Lukulista</translation>
<translation id="2704283930420550640">Arvo ei vastaa muotoa.</translation>
<translation id="2704951214193499422">Chromium ei voinut vahvistaa korttiasi. Yritä myöhemmin uudelleen.</translation>
<translation id="2705137772291741111">Tämän sivuston välimuistiin tallennettu kopio oli lukukelvoton.</translation>
<translation id="2709516037105925701">Automaattinen täyttö</translation>
-<translation id="2712118517637785082">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta varmenteen myöntäjä on peruuttanut palvelimen esittämän varmenteen. Palvelimen esittämiin tunnistetietoihin ei missään tapauksessa tule luottaa. Saatat olla tekemisissä hakkerin kanssa. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Pyydä käyttölupaa</translation>
<translation id="2713444072780614174">Valkoinen</translation>
<translation id="2720342946869265578">Nearby</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Laitetallenne puuttuu</translation>
<translation id="2784949926578158345">Yhteys katkaistiin.</translation>
<translation id="2794233252405721443">Sivusto estetty</translation>
+<translation id="2799020568854403057">Sivusto sisältää haitallisia sovelluksia</translation>
+<translation id="2803306138276472711">Google-selaussuoja havaitsi sivustossa <ph name="SITE" /> äskettäin <ph name="BEGIN_LINK" />haittaohjelmia<ph name="END_LINK" />. Tavallisesti turvalliset sivustot voivat joskus saada haittaohjelmatartunnan.</translation>
<translation id="2824775600643448204">Osoite- ja hakupalkki</translation>
<translation id="2826760142808435982">Yhteys on salattu ja todennettu <ph name="CIPHER" />:n avulla ja se käyttää menetelmää <ph name="KX" /> avainvaihtomekanismina.</translation>
<translation id="2835170189407361413">Tyhjennä lomake</translation>
+<translation id="2856444702002559011">Sivustolle <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää varastaa tietojasi (esimerkiksi salasanoja, viestejä tai luottokorttitietoja). <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Älä päivitä</translation>
<translation id="2900469785430194048">Google Chromen muisti loppui verkkosivua näytettäessä.</translation>
<translation id="2909946352844186028">Verkossa havaittiin muutos.</translation>
<translation id="2916038427272391327">Sulje muita ohjelmia.</translation>
<translation id="2922350208395188000">Palvelimen varmennetta ei voi tarkistaa.</translation>
<translation id="2928905813689894207">Laskutusosoite</translation>
+<translation id="2941952326391522266">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne on verkkotunnuksesta <ph name="DOMAIN2" />. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="2948083400971632585">Voit poistaa yhteydelle määritetyt välityspalvelimet käytöstä asetussivulla.</translation>
<translation id="2955913368246107853">Sulje hakupalkki</translation>
<translation id="2958431318199492670">Verkkoasetukset eivät noudata ONC-standardia. Kaikkia asetuksia ei välttämättä tuoda.</translation>
-<translation id="29611076221683977">Sivustoon <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää asentaa Maciisi vaarallisia ohjelmia, jotka varastavat tai poistavat tietojasi, kuten kuviasi, salasanojasi, viestejäsi ja luottokorttiesi tietoja.</translation>
<translation id="2966678944701946121">Vanhenee: <ph name="EXPIRATION_DATE_ABBR" />, lisätty: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Kellosi täytyy asettaa oikeaan aikaan, jotta salattu yhteys voidaan muodostaa. Tämä johtuu siitä, että verkkosivustojen tunnistamisessa käytettävät varmenteet ovat voimassa vain tiettyinä aikoina. Chrome ei voi vahvistaa varmenteita, koska laitteesi kello on väärässä ajassa.</translation>
<translation id="2972581237482394796">&amp;Tee uudelleen</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Anna kelvollinen osoite.</translation>
<translation id="2986368408720340940">Tämä noutotapa ei ole käytettävissä. Kokeile toista tapaa.</translation>
<translation id="2991174974383378012">Jakaminen verkkosivustojen kanssa</translation>
+<translation id="2991571918955627853"><ph name="SITE" /> ei ole juuri nyt käytettävissä, koska se käyttää HSTS:ää. Verkkovirheet ja hyökkäykset ovat yleensä väliaikaisia, joten sivu luultavasti toimii myöhemmin.</translation>
<translation id="3005723025932146533">Näytä tallennettu kopio</translation>
<translation id="3008447029300691911">Anna kortin <ph name="CREDIT_CARD" /> CVC. Vahvistamisen jälkeen korttisi tiedot jaetaan sivuston kanssa.</translation>
<translation id="3010559122411665027">Luettelokohde "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Estetty automaattisesti</translation>
<translation id="3024663005179499861">Väärä käytäntötyyppi</translation>
<translation id="3032412215588512954">Haluatko päivittää tämän sivuston?</translation>
<translation id="3037605927509011580">Voi räkä!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{vähintään 1 kohde synkronoiduilla laitteilla}=1{1 kohde (ja lisää synkronoiduilla laitteilla)}other{# kohdetta (ja lisää synkronoiduilla laitteilla)}}</translation>
<translation id="3041612393474885105">Varmenteen tiedot</translation>
<translation id="3063697135517575841">Chrome ei voinut vahvistaa korttiasi. Yritä myöhemmin uudelleen.</translation>
<translation id="3064966200440839136">Incognito-tilasta poistutaan ulkoisessa sovelluksessa maksamisen vuoksi. Haluatko jatkaa?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ei mitään}=1{1 salasana}other{# salasanaa}}</translation>
<translation id="3093245981617870298">Olet offline-tilassa.</translation>
<translation id="3105172416063519923">Laitteen tunnus:</translation>
<translation id="3109728660330352905">Sinulla ei ole oikeutta tarkastella tätä sivua.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Kokeile yhteysdiagnostiikkaa<ph name="END_LINK" /></translation>
<translation id="3145945101586104090">Vastauksen purkaminen epäonnistui</translation>
<translation id="3150653042067488994">Tilapäinen palvelinvirhe</translation>
@@ -247,17 +277,21 @@
<translation id="3167968892399408617">Incognito-välilehdillä avattujen sivujen tietoja ei säilytetä selaimen historiassa, evästeissä tai hakuhistoriassa, kun kaikki incognito-välilehdet suljetaan. Ladatut tiedostot ja luodut kirjanmerkit säilytetään.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Saari</translation>
+<translation id="317583078218509884">Uudet sivuston käyttölupa-asetukset tulevat voimaan päivitettyäsi sivun.</translation>
<translation id="3176929007561373547">Tarkista välityspalvelinasetukset tai ota yhteyttä verkon järjestelmänvalvojaan
varmistaaksesi, että välityspalvelin toimii. Jos välityspalvelimen ei pitäisi olla
käytössä:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Avaa sivu incognito-tilassa.</translation>
-<translation id="3202578601642193415">Uusin</translation>
+<translation id="320323717674993345">Peruuta maksu</translation>
<translation id="3207960819495026254">Kirjanmerkeissä</translation>
+<translation id="3225919329040284222">Palvelin esitti varmenteen, joka ei vastaa sisäänrakennettuja odotuksia. Tietyillä tehokkaasti suojatuilla sivustoilla on odotuksia, joilla suojataan käyttäjiä.</translation>
<translation id="3226128629678568754">Paina päivityspainiketta, niin sivun lataukseen tarvittavat tiedot lähetetään uudelleen.</translation>
+<translation id="3227137524299004712">Mikrofoni</translation>
<translation id="3228969707346345236">Käännös epäonnistui, koska sivun kieli on jo <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Anna kortin <ph name="CREDIT_CARD" /> CVC</translation>
+<translation id="3234666976984236645">Havaitse aina tärkeä sisältö tällä sivustolla</translation>
<translation id="3254409185687681395">Luo kirjanmerkki tälle sivulle</translation>
<translation id="3270847123878663523">K&amp;umoa uudelleenjärjestely</translation>
<translation id="3282497668470633863">Lisää kortissa oleva nimi</translation>
@@ -271,42 +305,48 @@
<translation id="3340978935015468852">asetuksissa</translation>
<translation id="3345135638360864351">Tämän sivuston käyttöpyyntöä ei voitu lähettää henkilölle <ph name="NAME" />. Yritä uudelleen.</translation>
<translation id="3355823806454867987">Muuta välityspalvelimen asetuksia...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />ei tallenna<ph name="END_EMPHASIS" />
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />selaushistoriaasi
+ <ph name="LIST_ITEM" />evästeitä ja sivuston tietoja
+ <ph name="LIST_ITEM" />lomakkeisiin syötettyjä tietoja.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Väärä kellonaika</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> muuta kohdetta…</translation>
<translation id="337363190475750230">Poistettu käytöstä</translation>
<translation id="3377188786107721145">Virhe jäsennettäessä käytäntöä</translation>
<translation id="3380365263193509176">Tuntematon virhe</translation>
<translation id="3380864720620200369">Asiakastunnus:</translation>
<translation id="3391030046425686457">Toimitusosoite</translation>
<translation id="3395827396354264108">Noutotapa</translation>
-<translation id="340013220407300675">Hyökkääjät saattavat yrittää varastaa tietojasi (esimerkiksi salasanoja, viestejä tai luottokorttitietoja) kohteessa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />.</translation>
<translation id="3422248202833853650">Yritä vapauttaa muistia sulkemalla muita ohjelmia.</translation>
<translation id="3422472998109090673">Sivustoon <ph name="HOST_NAME" /> ei saada tällä hetkellä yhteyttä.</translation>
+<translation id="3427092606871434483">Salli (oletus)</translation>
<translation id="3427342743765426898">&amp;Toista muokkaus</translation>
<translation id="3431636764301398940">Tallenna kortti tälle laitteelle</translation>
<translation id="3435896845095436175">Ota käyttöön</translation>
<translation id="3447661539832366887">Tämän laitteen omistaja on poistanut dinosauruspelin käytöstä.</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">Hakuväli:</translation>
<translation id="3462200631372590220">Piilota lisäasetukset</translation>
<translation id="3467763166455606212">Kortinhaltijan nimi on pakollinen.</translation>
<translation id="3478058380795961209">Voimassa (kk)</translation>
<translation id="3479539252931486093">Etkö odottanut tätä? <ph name="BEGIN_LINK" />Kerro siitä meille.<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ei nyt</translation>
-<translation id="348000606199325318">Kaatumistunnus: <ph name="CRASH_LOCAL_ID" /> (palvelintunnus: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Emme tavoittaneet vanhempaasi. Yritä uudelleen.</translation>
<translation id="3528171143076753409">Palvelimen varmenne ei ole luotettava.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Vähintään 1 kohde synkronoiduilla laitteilla}=1{1 kohde (ja lisää synkronoiduilla laitteilla)}other{# kohdetta (ja lisää synkronoiduilla laitteilla)}}</translation>
<translation id="3539171420378717834">Säilytä tämän kortin kopio laitteella.</translation>
<translation id="3542684924769048008">Käytä salasanaa kohteeseen:</translation>
+<translation id="3545341443414427877">Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska tietokoneesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Salaa kaikki synkronoidut tiedot oman synkronoinnin tunnuslauseesi avulla</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> lisää…</translation>
-<translation id="3555561725129903880">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenne on peräisin verkkotunnukselta <ph name="DOMAIN2" />. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Ylläpitäjä voi kumota eston puolestasi.</translation>
<translation id="3566021033012934673">Yhteytesi ei ole salattu</translation>
+<translation id="3569145463236695319">&lt;p&gt;Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska tietokoneesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset.&lt;/p&gt;
+
+ &lt;p&gt;Muokkaa aikaa ja päivämäärää &lt;strong&gt;Asetukset&lt;/strong&gt;-sovelluksen&lt;strong&gt;Yleistä&lt;/strong&gt;-osiossa.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Lisää nimi</translation>
<translation id="3583757800736429874">&amp;Toista siirto</translation>
<translation id="3586931643579894722">Piilota lisätiedot</translation>
-<translation id="3587482841069643663">Kaikki</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Anna kelvollinen viimeinen voimassaolopäivä.</translation>
<translation id="36224234498066874">Poista selaustiedot...</translation>
@@ -323,7 +363,6 @@
<translation id="3681007416295224113">Varmenteen tiedot</translation>
<translation id="3690164694835360974">Sisäänkirjautuminen ei ole turvallinen</translation>
<translation id="3693415264595406141">Salasana:</translation>
-<translation id="3696411085566228381">ei mitään</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Ladataan...</translation>
<translation id="3712624925041724820">Käyttöluvat ovat lopussa</translation>
@@ -331,12 +370,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Tarkista välityspalvelimen, palomuurin ja nimipalvelun määritykset<ph name="END_LINK" />.</translation>
<translation id="3736520371357197498">Jos ymmärrät käyntiä koskevat turvallisuusriskit, voit <ph name="BEGIN_LINK" />siirtyä vaarantuneeseen sivustoon<ph name="END_LINK" /> jo ennen haitallisten ohjelmien poistamista.</translation>
<translation id="3739623965217189342">Kopioimasi linkki</translation>
+<translation id="3744899669254331632">Et voi siirtyä sivustoon <ph name="SITE" /> tällä hetkellä, koska sivusto lähetti salatut kirjautumistiedot, joita Chromium ei osaa käsitellä. Verkkovirheet ja hyökkäykset ovat yleensä väliaikaisia, joten sivu toimii luultavasti myöhemmin.</translation>
+<translation id="3748148204939282805">Sivustolle <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää huijata sinua tekemään jotain vaarallista, kuten asentamaan ohjelmia tai paljastamaan henkilötietojasi (esimerkiksi salasanoja, puhelinnumeroita tai luottokorttitietoja). <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Käännös epäonnistui palvelinvirheen vuoksi.</translation>
<translation id="3759461132968374835">Ei viimeaikaisia kaatumisilmoituksia. Jos selain kaatui kaatumisilmoitusten ollessa pois käytöstä, ilmoituksia ei näytetä täällä.</translation>
+<translation id="3778403066972421603">Haluatko tallentaa tämän kortin Google-tilille ja tälle laitteelle?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Vanhenee <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Jos käytät välityspalvelinta…</translation>
<translation id="3828924085048779000">Tunnuslause ei voi olla tyhjä.</translation>
-<translation id="3845539888601087042">Näytetään kirjautuneiden laitteiden historia. <ph name="BEGIN_LINK" />Lisätietoja<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Edellinen</translation>
<translation id="3858027520442213535">Päivitä päivämäärä ja aika</translation>
<translation id="3884278016824448484">Ristiriitainen laitteen tunnus</translation>
@@ -344,11 +386,13 @@
<translation id="3886446263141354045">Pyyntösi päästä tälle sivustolle on lähetetty henkilölle <ph name="NAME" />.</translation>
<translation id="3890664840433101773">Lisää sähköposti</translation>
<translation id="3901925938762663762">Kortti on vanhentunut.</translation>
-<translation id="3933571093587347751">{1,plural, =1{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenne on päivätty huomiselle. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" />}other{Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenne on päivätty # päivää tulevaisuuteen. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">PDF-asiakirjan lataaminen epäonnistui</translation>
+<translation id="3945915738023014686">Kaatumisraportti lähetetty, raporttitunnus: <ph name="CRASH_ID" /> (paikallinen kaatumistunnus: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenteessa ei määritetä kohteen vaihtoehtoisia nimiä. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="3963721102035795474">Lukijatila</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ei mitään}=1{1 sivustolta }other{# sivustolta }}</translation>
<translation id="397105322502079400">Lasketaan...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> on estetty</translation>
+<translation id="3987940399970879459">Alle 1 Mt</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 verkkosivu lähistöllä}other{# verkkosivua lähistöllä}}</translation>
<translation id="4021036232240155012">DNS on verkkopalvelu, joka kääntää verkkosivuston nimen sen internetosoitteeksi.</translation>
<translation id="4030383055268325496">K&amp;umoa lisäys</translation>
@@ -359,56 +403,63 @@
<translation id="4079302484614802869">Välityspalvelinmääritykset on asetettu käyttämään .pac-URL-osoitteita, ei kiinteitä välityspalvelimia.</translation>
<translation id="4098354747657067197">Seuraava sivusto on petollinen</translation>
<translation id="4103249731201008433">Laitteen sarjanumero on virheellinen</translation>
+<translation id="410351446219883937">Automaattinen toisto</translation>
<translation id="4103763322291513355">Voit lukea listan kielletyistä URL-osoitteista ja muut järjestelmänvalvojasi määräämät käytännöt osoitteessa &lt;strong&gt;chrome://policy&lt;/strong&gt;.</translation>
-<translation id="4110615724604346410">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenteessa on virheitä. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Purppura</translation>
+<translation id="4116663294526079822">Salli aina tässä sivustossa</translation>
<translation id="4117700440116928470">Käytännön laajuutta ei tueta.</translation>
-<translation id="4118212371799607889">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä Chromium ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 muu}other{# muuta}}</translation>
<translation id="4130226655945681476">Tarkista verkkojohdot, modeemi ja reititin.</translation>
+<translation id="413544239732274901">Lisätietoja</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Käytä yleistä oletusta (havaitse)</translation>
+<translation id="4165986682804962316">Sivustoasetukset</translation>
<translation id="4169947484918424451">Haluatko, että Chromium tallentaa tämän kortin?</translation>
<translation id="4171400957073367226">Virheellinen vahvistusallekirjoitus.</translation>
<translation id="4196861286325780578">&amp;Toista siirto</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Tarkista palomuurin ja virustorjuntaohjelmiston määritykset.<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ei yhtään}=1{1 sovellus ($1)}=2{2 sovellusta ($1 ja $2)}other{# sovellusta ($1, $2 $3)}}</translation>
<translation id="4220128509585149162">Kaatuu</translation>
+<translation id="422022731706691852">Sivustolle <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää huijata sinua asentamaan ohjelmia, jotka heikentävät selauskokemustasi (esimerkiksi vaihtamalla aloitussivusi tai näyttämällä ylimääräisiä mainoksia avaamillasi sivustoilla). <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Kokeile verkon diagnostiikkaa<ph name="END_LINK" /></translation>
+<translation id="4235360514405112390">Voimassa</translation>
<translation id="4250431568374086873">Yhteytesi sivustoon ei ole täysin suojattu.</translation>
<translation id="4250680216510889253">Ei</translation>
<translation id="425582637250725228">Tekemiäsi muutoksia ei välttämättä tallenneta.</translation>
<translation id="4258748452823770588">Virheellinen allekirjoitus</translation>
+<translation id="4265872034478892965">Järjestelmänvalvojan sallima</translation>
<translation id="4269787794583293679">(Ei käyttäjänimeä)</translation>
<translation id="4275830172053184480">Käynnistä laite uudelleen</translation>
<translation id="4280429058323657511">, vanhentumispäivä <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Googlen selaussuoja <ph name="BEGIN_LINK" />löysi äskettäin haitallisia ohjelmia<ph name="END_LINK" /> sivustolta <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">Ylätason ehdotukset</translation>
<translation id="4304224509867189079">Kirjaudu sisään</translation>
-<translation id="432290197980158659">Palvelimen esittämä varmenne ei vastaa sisäänrakennettuja odotuksia. Tietyillä tehokkaasti suojatuilla verkkosivustoilla on odotuksia, joilla suojataan käyttäjiä. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Estä (oletus)</translation>
<translation id="4325863107915753736">Artikkelia ei löydy</translation>
<translation id="4326324639298822553">Tarkista vanhentumispäivä ja yritä uudelleen.</translation>
<translation id="4331708818696583467">Ei turvallinen</translation>
<translation id="4356973930735388585">Tälle sivustolle hyökännyt taho voi yrittää asentaa tietokoneellesi vaarallisia ohjelmia, jotka varastavat tai poistavat tietojasi, kuten kuviasi, salasanojasi, viestejäsi ja luottokorttiesi tietoja.</translation>
<translation id="4372948949327679948">Odotettu <ph name="VALUE_TYPE" />-arvo.</translation>
+<translation id="4377125064752653719">Yritit yhdistää sivustoon <ph name="DOMAIN" />, mutta varmenteen myöntäjä on kumonnut palvelimen esittämän varmenteen. Palvelimen esittämiin suojaustietoihin ei siis tule luottaa. Saatat olla tekemisissä hakkerin kanssa.</translation>
<translation id="4381091992796011497">Käyttäjätunnus:</translation>
<translation id="4394049700291259645">Poista käytöstä</translation>
<translation id="4406896451731180161">hakutulokset</translation>
+<translation id="4424024547088906515">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; Chrome ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ei hyväksynyt kirjautumisvarmennettasi, tai varmennetta ei annettu.</translation>
<translation id="443673843213245140">Välityspalvelinta ei saa käyttää, mutta erilliset välityspalvelimen asetukset on määritetty.</translation>
-<translation id="4492190037599258964">Hakutulokset kyselylle <ph name="SEARCH_STRING" /></translation>
<translation id="4506176782989081258">Todennusvirhe: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Ota yhteyttä järjestelmänvalvojaan.</translation>
<translation id="450710068430902550">Jakaminen järjestelmänvalvojan kanssa</translation>
<translation id="4515275063822566619">Kortit ja osoitteet ovat peräisin Chromesta ja Google-tililtäsi (<ph name="ACCOUNT_EMAIL" />). Voit hallinnoida niitä <ph name="BEGIN_LINK" />asetuksissa<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Tiedot</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Poista laajennukset käytöstä.</translation>
<translation id="457875822857220463">Toimitus</translation>
<translation id="4587425331216688090">Poistetaanko osoite Chromen tiedoista?</translation>
-<translation id="4589078953350245614">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti virheellisen varmenteen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Yhteytesi kohteeseen <ph name="DOMAIN" /> on salattu nykyaikaisella salaustekniikalla.</translation>
<translation id="4594403342090139922">K&amp;umoa poisto</translation>
<translation id="4619615317237390068">Välilehdet muista laitteista</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne sisältää virheitä. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
+<translation id="4690462567478992370">Lopeta virheellisten varmenteiden käyttö</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Yhteys keskeytyi</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windowsin verkon diagnostiikkaa<ph name="END_LINK" /></translation>
@@ -425,21 +476,24 @@
<translation id="4771973620359291008">Tapahtui tuntematon virhe.</translation>
<translation id="4800132727771399293">Tarkista vanhenemispäivä ja CVC ja yritä uudelleen.</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Et voi siirtyä sivustoon <ph name="SITE" /> juuri nyt, koska sivusto lähetti sekoitetut kirjautumistiedot, joita Google Chrome ei voi käsitellä. Verkkovirheet ja hyökkäykset ovat yleensä väliaikaisia, joten sivu luultavasti toimii myöhemmin.</translation>
<translation id="4813512666221746211">Verkkovirhe</translation>
<translation id="4816492930507672669">Sovita sivulle</translation>
<translation id="483020001682031208">Ei näytettäviä Fyysinen web ‑sivuja</translation>
<translation id="4850886885716139402">Näytä</translation>
<translation id="4854362297993841467">Tämä toimitustapa ei ole käytettävissä. Kokeile toista tapaa.</translation>
<translation id="4858792381671956233">Pyysit vanhemmiltasi lupaa käydä tällä sivustolla.</translation>
+<translation id="4863764087567530506">Tämä sisältö saattaa yrittää huijata sinua asentamaan ohjelmistoja tai paljastamaan henkilökohtaisia tietoja. <ph name="BEGIN_LINK" />Näytä silti<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Haku historiasta</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ja 1 muu verkkosivu}other{ja # muuta verkkosivua}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Tämä sivu on käännetty tuntemattomasta kielestä kielelle <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Maksu</translation>
<translation id="4926049483395192435">On määritettävä.</translation>
<translation id="495170559598752135">Toiminnot</translation>
<translation id="4958444002117714549">Laajenna luettelo</translation>
-<translation id="4962322354953122629">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä Chrome ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Ota varoitukset uudelleen käyttöön</translation>
<translation id="4989809363548539747">Tätä laajennusta ei tueta.</translation>
<translation id="5002932099480077015">Kun tämä vaihtoehto on käytössä, Chrome nopeuttaa lomakkeiden täyttämistä tallentamalla kortin tiedot tälle laittelle.</translation>
<translation id="5018422839182700155">Sivun avaaminen epäonnistui</translation>
@@ -447,14 +501,15 @@
<translation id="5023310440958281426">Tarkista järjestelmänvalvojan käytännöt</translation>
<translation id="5029568752722684782">Poista kopio</translation>
<translation id="5031870354684148875">Tietoja Google-kääntäjästä</translation>
+<translation id="5039804452771397117">Salli</translation>
<translation id="5040262127954254034">Tietosuoja</translation>
<translation id="5045550434625856497">Väärä salasana</translation>
<translation id="5056549851600133418">Sinulle valitut artikkelit</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Tarkista välityspalvelimen osoite.<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Ei evästeitä}=1{1 sivusto käyttää evästeitä. }other{# sivustoa käyttää evästeitä. }}</translation>
<translation id="5087286274860437796">Palvelimen varmenne ei ole tällä hetkellä kelvollinen.</translation>
<translation id="5087580092889165836">Lisää kortti</translation>
<translation id="5089810972385038852">Osavaltio/alue</translation>
+<translation id="5094747076828555589">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; Chromium ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="5095208057601539847">Provinssi</translation>
<translation id="5115563688576182185">(64-bittinen)</translation>
<translation id="5141240743006678641">Salaa synkronoidut salasanat Google-kirjautumistietojesi avulla</translation>
@@ -470,24 +525,24 @@
<translation id="5222812217790122047">Sähköposti vaaditaan</translation>
<translation id="5251803541071282808">Pilvi</translation>
<translation id="5277279256032773186">Käytätkö Chromea töissä? Yritykset voivat hallita Chromen asetuksia työntekijöidensä puolesta. Lisätietoja</translation>
+<translation id="5297526204711817721">Yhteytesi tähän sivustoon ei ole yksityinen. Voit poistua VR-tilasta milloin tahansa ottamalla headsetin pois ja valitsemalla Takaisin.</translation>
<translation id="5299298092464848405">Virhe jäsennettäessä käytäntöä</translation>
-<translation id="5300589172476337783">Näytä</translation>
<translation id="5308689395849655368">Kaatumisraportit on poistettu käytöstä.</translation>
<translation id="5317780077021120954">Tallenna</translation>
<translation id="5327248766486351172">Nimi</translation>
-<translation id="5337705430875057403">Sivustoon <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää huijata sinua tekemään jotain vaarallista, kuten asentamaan ohjelmistoja tai paljastamaan henkilötietojasi (esimerkiksi salasanoja, puhelinnumeroita tai luottokorttitietoja).</translation>
-<translation id="5359637492792381994">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenne ei ole tällä hetkellä voimassa. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791"><ph name="SITE" /> ei juuri nyt ole käytettävissä, koska sen varmenne ei ole voimassa. Verkkovirheet ja hyökkäykset ovat yleensä väliaikaisia, joten sivu luultavasti toimii myöhemmin.</translation>
<translation id="536296301121032821">Käytännön asetuksien tallentaminen epäonnistui</translation>
<translation id="5386426401304769735">Tämän sivuston varmenneketju sisältää varmenteen, joka on allekirjoitettu SHA-1:llä.</translation>
<translation id="5402410679244714488">Vanhenee: <ph name="EXPIRATION_DATE_ABBR" />, käytetty viimeksi yli vuosi sitten</translation>
+<translation id="540969355065856584">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä sen suojausvarmenne ei tällä hetkellä ole kelvollinen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
<translation id="5421136146218899937">Poista selaustiedot...</translation>
<translation id="5430298929874300616">Poista kirjanmerkki</translation>
<translation id="5431657950005405462">Tiedostoasi ei löydy</translation>
-<translation id="5435775191620395718">Näytetään tämän laitteen historia. <ph name="BEGIN_LINK" />Lisätietoja<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Mallin todennusvirhe kohdassa <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Tätä sivuston <ph name="HOST_NAME" /> sivua ei löydy.</translation>
<translation id="5455374756549232013">Virheellinen käytännön aikaleima</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> / <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Virheellinen</translation>
<translation id="5470861586879999274">&amp;Toista muokkaus</translation>
<translation id="54817484435770891">Lisää kelvollinen osoite</translation>
<translation id="5492298309214877701">Tällä yrityksen, organisaation tai oppilaitoksen intranetissä olevalla sivustolla on sama URL-osoite kuin ulkoisella verkkosivustolla.
@@ -504,6 +559,8 @@
<translation id="5571083550517324815">Nouto tästä osoitteesta ei onnistu. Valitse eri osoite.</translation>
<translation id="5572851009514199876">Aloita ja kirjaudu sisään, jotta Chrome voi tarkistaa, onko sinulla oikeus käyttää tätä sivustoa.</translation>
<translation id="5580958916614886209">Tarkista vanhentumiskuukausi ja yritä uudelleen.</translation>
+<translation id="5586446728396275693">Ei tallennettuja osoitteita</translation>
+<translation id="5595485650161345191">Osoitteen muokkaus</translation>
<translation id="560412284261940334">Hallintaa ei tueta</translation>
<translation id="5610142619324316209">Tarkista yhteys.</translation>
<translation id="5610807607761827392">Voit hallita kortteja ja osoitteita <ph name="BEGIN_LINK" />Asetuksissa<ph name="END_LINK" />.</translation>
@@ -511,15 +568,18 @@
<translation id="5622887735448669177">Haluatko poistua tältä sivustolta?</translation>
<translation id="5629630648637658800">Käytännön asetuksien lataaminen epäonnistui</translation>
<translation id="5631439013527180824">Laitteenhallintatunnus on virheellinen</translation>
+<translation id="5633066919399395251">Sivustolle <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää asentaa tietokoneellesi vaarallisia ohjelmia, jotka varastavat tai poistavat tietojasi, esimerkiksi kuvia, salasanoja, viestejä tai luottokorttitietoja. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Sijainti</translation>
+<translation id="5659593005791499971">Sähköposti</translation>
<translation id="5669703222995421982">Hanki räätälöityä sisältöä</translation>
<translation id="5675650730144413517">Sivu ei toimi</translation>
-<translation id="5677928146339483299">Estetty</translation>
-<translation id="5694783966845939798">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelimen esittämä varmenne käyttää heikkoa allekirjoitusalgoritmia (esim. SHA-1). Palvelimen esittämät tunnistetiedot voivat olla väärennettyjä, eikä palvelin välttämättä ole tavoittelemasi palvelin (saatat olla tekemisissä hakkerin kanssa). <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">Tämän sivuston identiteettiä ei ole vahvistettu.</translation>
+<translation id="5713016350996637505">Harhaanjohtava sisältö estetty</translation>
<translation id="5720705177508910913">Nykyinen käyttäjä</translation>
<translation id="5732392974455271431">Vanhempasi voivat kumota eston puolestasi.</translation>
<translation id="5763042198335101085">Anna voimassa oleva sähköpostiosoite.</translation>
<translation id="5765072501007116331">Valitse osoite, niin näet toimitustavat ja vaatimukset.</translation>
+<translation id="5778550464785688721">MIDI-laitteiden täysi käyttöoikeus</translation>
<translation id="5784606427469807560">Korttia vahvistettaessa tapahtui virhe. Tarkista internetyhteys ja yritä uudelleen.</translation>
<translation id="5785756445106461925">Tällä sivulla on kuitenkin muita osia, jotka eivät ole suojattuja. Muut voivat tarkastella näitä osia siirron aikana, ja hyökkääjä voi muuttaa sivun ulkoasua muokkaamalla näitä osia.</translation>
<translation id="5786044859038896871">Täytetäänkö kortin tiedot?</translation>
@@ -528,14 +588,14 @@
<translation id="5813119285467412249">&amp;Toista lisäys</translation>
<translation id="5814352347845180253">Saatat menettää esim. sivuston <ph name="SITE" /> maksullisen sisällön käyttöoikeuden.</translation>
<translation id="5838278095973806738">Älä anna tälle sivustolle salasanoja, luottokorttinumeroita tai muita arkaluonteisia tietoja, sillä hyökkääjät saattavat varastaa ne.</translation>
-<translation id="5843436854350372569">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelimen esittämä varmenne sisältää heikon avaimen. Hakkeri on ehkä murtanut yksityisen avaimen, eikä palvelin välttämättä ole tavoittelemasi palvelin (saatat olla tekemisissä hakkerin kanssa). <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">Sivustoon ei saada yhteyttä</translation>
<translation id="5869522115854928033">Tallennetut salasanat</translation>
<translation id="5872918882028971132">Ylätason ehdotukset</translation>
<translation id="5901630391730855834">Keltainen</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synkronoitu)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 käytössä}other{# käytössä}}</translation>
<translation id="5926846154125914413">Saatat menettää joidenkin sivustojen maksullisen sisällön käyttöoikeuden.</translation>
<translation id="5959728338436674663"><ph name="BEGIN_WHITEPAPER_LINK" />Lähetä automaattisesti<ph name="END_WHITEPAPER_LINK" /> joitain järjestelmän tietoja ja sivujen sisältöjä Googlelle auttaaksesi sitä havaitsemaan vaarallisia sovelluksia ja sivustoja. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Viikko</translation>
<translation id="5967867314010545767">Poista historiasta</translation>
<translation id="5975083100439434680">Loitonna</translation>
<translation id="598637245381783098">Maksusovelluksen avaaminen ei onnistu.</translation>
@@ -544,21 +604,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Sivu 1}other{Sivu #}}</translation>
<translation id="6017514345406065928">Vihreä</translation>
+<translation id="6017850046339264347">Sivuston <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökkääjät voivat asentaa harhaanjohtavia sovelluksia, jotka teeskentelevät olevansa jotain muuta tai keräävät tietoja, joiden avulla ne voivat seurata sinua. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synkronoitu)</translation>
<translation id="6027201098523975773">Kirjoita nimi</translation>
<translation id="6040143037577758943">Sulje</translation>
<translation id="6042308850641462728">Lisää</translation>
+<translation id="6047233362582046994">Jos ymmärrät käyntiä koskevat turvallisuusriskit, voit <ph name="BEGIN_LINK" />siirtyä tälle sivustolle<ph name="END_LINK" /> jo ennen haitallisten sovellusten poistamista.</translation>
+<translation id="6051221802930200923"><ph name="SITE" /> ei juuri nyt ole käytettävissä, koska se käyttää varmenteiden kiinnittämistä. Verkkovirheet ja hyökkäykset ovat yleensä väliaikaisia, joten sivu luultavasti toimii myöhemmin.</translation>
<translation id="6060685159320643512">Varoitus, nämä kokeilut saattavat puraista</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ei yhtään}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Käytät sisältöä järjestelmänvalvojan myöntämällä varmenteella. Järjestelmänvalvoja voi käyttää verkkotunnukselle <ph name="DOMAIN" /> lähettämiäsi tietoja.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ei mitään}=1{1 salasana (synkronoitu)}other{# salasanaa (synkronoitu)}}</translation>
<translation id="6146055958333702838">Tarkista kaikki kaapelit ja käynnistä uudelleen reitittimet, modeemit ja muut
käytössä olevat verkkolaitteet.</translation>
<translation id="614940544461990577">Kokeile seuraavia toimenpiteitä:</translation>
<translation id="6151417162996330722">Palvelimen varmenteen voimassaoloaika on liian pitkä.</translation>
<translation id="6157877588268064908">Valitse osoite, niin näet toimitustavat ja vaatimukset.</translation>
+<translation id="6158003235852588289">Googlen selaussuoja havaitsi äskettäin tietojenkalasteluyrityksen sivustolla <ph name="SITE" />. Tietojenkalastelusivustot yrittävät huijata käyttäjiä tekeytymällä toisiksi sivustoiksi.</translation>
<translation id="6165508094623778733">Lisätietoja</translation>
+<translation id="6169916984152623906">Nyt voit selata verkkoa yksityisesti. Laitteen muut käyttäjät eivät näe selaushistoriaasi. Lataukset ja kirjanmerkit kuitenkin tallennetaan.</translation>
<translation id="6177128806592000436">Sivustoon ei ole muodostettu turvallista yhteyttä.</translation>
<translation id="6184817833369986695">(kohortti: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Tarkista internetyhteytesi</translation>
<translation id="6218753634732582820">Poistetaanko osoite Chromiumista?</translation>
+<translation id="6221345481584921695">Google-selaussuoja havaitsi sivustossa <ph name="SITE" /> äskettäin <ph name="BEGIN_LINK" />haittaohjelmia<ph name="END_LINK" />. Tavallisesti turvalliset sivustot voivat joskus saada haittaohjelmatartunnan. Haitallinen sisältö on peräisin tunnetusta haittaohjelmien jakelusivustosta nimeltä <ph name="SUBRESOURCE_HOST" />.</translation>
<translation id="6251924700383757765">Tietosuojakäytäntö</translation>
<translation id="6254436959401408446">Muisti ei riitä sivun avaamiseen</translation>
<translation id="625755898061068298">Olet poistanut tämän sivuston tietoturvavaroitukset käytöstä.</translation>
@@ -584,15 +652,14 @@
<translation id="6404511346730675251">Muokkaa kirjanmerkkiä</translation>
<translation id="6410264514553301377">Anna kortin <ph name="CREDIT_CARD" /> vanhentumispäivä ja CVC</translation>
<translation id="6414888972213066896">Pyysit vanhemmiltasi lupaa käydä tällä sivustolla.</translation>
-<translation id="6416403317709441254">Et voi juuri nyt siirtyä sivustolle <ph name="SITE" />, sillä se lähetti sekoitettuja tunnistetietoja, joita Chromium ei voi käsitellä. Verkkovirheet ja ‑hyökkäykset ovat yleensä väliaikaisia, joten voit todennäköisesti vierailla sivustolla myöhemmin. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">Ei voida tarkistaa, onko varmenne kumottu.</translation>
<translation id="6433490469411711332">Muokkaa yhteystietoja</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> kieltäytyi muodostamasta yhteyttä.</translation>
<translation id="6446608382365791566">Lisää tietoja</translation>
+<translation id="6447842834002726250">Evästeet</translation>
<translation id="6451458296329894277">Vahvista lomakkeen uudelleenlähetys</translation>
<translation id="6456339708790392414">Maksu</translation>
<translation id="6458467102616083041">Ohitettu, koska oletushaku on poistettu käytöstä käytännön mukaan.</translation>
-<translation id="6462969404041126431">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />. Sen suojausvarmenne on ehkä peruutettu. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Laitekäytännöt</translation>
<translation id="6477321094435799029">Chrome havaitsi tällä sivulla epätavallista koodia ja esti sen suojellakseen henkilötietojasi (esimerkiksi salasanoja, puhelinnumeroita tai luottokorttitietoja).</translation>
<translation id="6489534406876378309">Aloita kaatumistietojen lähettäminen</translation>
@@ -604,20 +671,19 @@
<translation id="6556915248009097796">Vanhenee: <ph name="EXPIRATION_DATE_ABBR" />, käytetty viimeksi: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Ylläpitäjä ei ole hyväksynyt sitä vielä.</translation>
<translation id="6569060085658103619">Tämä on laajennussivu.</translation>
-<translation id="6593753688552673085">alle <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Tämä sisältö saattaa yrittää asentaa vaarallisia ohjelmistoja laitteellesi tai varastaa tai poistaa tietojasi. <ph name="BEGIN_LINK" />Näytä silti<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Salausasetukset</translation>
<translation id="662080504995468778">Jää</translation>
<translation id="6626291197371920147">Lisää kelvollinen kortin numero</translation>
<translation id="6628463337424475685"><ph name="ENGINE" />-haku</translation>
+<translation id="6630809736994426279">Sivustolle <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää asentaa Maciisi vaarallisia ohjelmia, jotka varastavat tai poistavat tietojasi, esimerkiksi kuvia, salasanoja, viestejä tai luottokorttitietoja. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Tämä käytäntö on vanhentunut.</translation>
-<translation id="6652240803263749613">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä tietokoneesi käyttöjärjestelmä ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Poistetaanko lomake-ehdotus Chromiumista?</translation>
<translation id="6685834062052613830">Kirjaudu ulos ja suorita määritys loppuun.</translation>
<translation id="6710213216561001401">Edellinen</translation>
<translation id="6710594484020273272">&lt;Anna hakukysely&gt;</translation>
<translation id="6711464428925977395">Välityspalvelimessa on jotain vikaa tai osoite on virheellinen.</translation>
<translation id="6727102863431372879">Aseta</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ei yhtään}=1{1 kohde}other{# kohdetta}}</translation>
<translation id="674375294223700098">Tuntematon palvelimen varmennevirhe.</translation>
<translation id="6753269504797312559">Käytännön arvo</translation>
<translation id="6757797048963528358">Laitteesi siirtyi virransäästötilaan.</translation>
@@ -625,6 +691,8 @@
<translation id="6810899417690483278">Muokkaustunnus</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Aluetietojen lataus epäonnistui.</translation>
+<translation id="6825578344716086703"><ph name="DOMAIN" />-palvelin, johon yritit muodostaa yhteyden, esitti heikkoa allekirjoitusalgoritmia käyttävän varmenteen (esim. SHA-1). Tästä syystä palvelimen esittämät tunnistetiedot saattavat olla väärennettyjä. Palvelin ei siis välttämättä ole tavoittelemasi palvelin, vaan saatat viestiä hakkerin kanssa.</translation>
+<translation id="6830728435402077660">Ei turvallinen</translation>
<translation id="6831043979455480757">Käännä</translation>
<translation id="6839929833149231406">Alue</translation>
<translation id="6874604403660855544">&amp;Toista lisäys</translation>
@@ -632,6 +700,7 @@
<translation id="6895330447102777224">Korttisi vahvistettiin.</translation>
<translation id="6897140037006041989">User agent</translation>
<translation id="6915804003454593391">Käyttäjä:</translation>
+<translation id="6945221475159498467">Valitse</translation>
<translation id="6948701128805548767">Valitse osoite, niin näet noutotavat ja vaatimukset.</translation>
<translation id="6957887021205513506">Palvelimen varmenne näyttää olevan väärennös.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -640,15 +709,16 @@
<translation id="6973656660372572881">Sekä kiinteät välityspalvelimet että .pac-URL-osoite on määritetty.</translation>
<translation id="6989763994942163495">Näytä lisäasetukset...</translation>
<translation id="7000990526846637657">Historiamerkintöjä ei löytynyt</translation>
-<translation id="7009986207543992532">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelimen esittämän varmenteen voimassaoloaika on epäilyttävän pitkä. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Google-tililläsi voi olla muita selaushistoriatietoja osoitteessa <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />.</translation>
<translation id="7029809446516969842">Salasanat</translation>
+<translation id="7050187094878475250">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti varmenteen, joka on voimassa liian kauan ollakseen luotettava.</translation>
+<translation id="7053983685419859001">Estä</translation>
<translation id="7064851114919012435">Yhteystiedot</translation>
<translation id="7079718277001814089">Tämä sivusto sisältää haittaohjelmia</translation>
<translation id="7087282848513945231">Kunta</translation>
-<translation id="7088615885725309056">Vanhempi</translation>
<translation id="7090678807593890770">Tee Google-haku: <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Laajennuksen sallima</translation>
<translation id="7119414471315195487">Sulje muita välilehtiä tai ohjelmia.</translation>
<translation id="7129409597930077180">Lähetys tähän osoitteeseen ei onnistu. Valitse eri osoite.</translation>
<translation id="7138472120740807366">Toimitustapa</translation>
@@ -666,22 +736,18 @@
<translation id="7220786058474068424">Käsitellään.</translation>
<translation id="724691107663265825">Seuraava verkkosivusto sisältää haittaohjelmia</translation>
<translation id="724975217298816891">Päivitä kortin <ph name="CREDIT_CARD" /> tiedot antamalla sen CVC ja vanhenemispäivämäärä. Vahvistamisen jälkeen korttisi tiedot jaetaan sivuston kanssa.</translation>
-<translation id="725866823122871198">Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska tietokoneesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset.</translation>
+<translation id="7260504762447901703">Peruuta käyttöoikeus</translation>
<translation id="7275334191706090484">Hallinnoidut kirjanmerkit</translation>
<translation id="7298195798382681320">Suositus</translation>
<translation id="7309308571273880165">Kaatumisraportti tallennettu <ph name="CRASH_TIME" /> (käyttäjä pyysi latausta, ei vielä ladattu)</translation>
<translation id="7334320624316649418">&amp;Toista uudelleenjärjestely</translation>
<translation id="733923710415886693">Palvelimen varmenteesta ei ole saatu Certificate Transparencyn vaatimia tietoja.</translation>
-<translation id="7351800657706554155">Et voi juuri nyt siirtyä sivustolle <ph name="SITE" />, sillä sen varmenne on peruutettu. Verkkovirheet ja ‑hyökkäykset ovat yleensä väliaikaisia, joten voit todennäköisesti vierailla sivustolla myöhemmin. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">Komentorivi</translation>
<translation id="7372973238305370288">hakutulos</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ei</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Vahvista kortti</translation>
-<translation id="7394102162464064926">Haluatko varmasti poistaa nämä sivut historiastasi?
-
-Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORTCUT_KEY" />.</translation>
<translation id="7400418766976504921">URL-osoite</translation>
<translation id="7419106976560586862">Profiilin polku</translation>
<translation id="7424977062513257142">Viesti tälle verkkosivulle upotetulta sivulta:</translation>
@@ -689,6 +755,7 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="7444046173054089907">Tämä sivusto on estetty</translation>
<translation id="7445762425076701745">Palvelimen, johon olet muodostanut yhteyden, identiteettiä ei voi täysin todentaa. Tietokoneesi on yhdistetty palvelimeen sellaisen nimen avulla, joka on kelvollinen vain verkkosi sisällä ja jonka omistajaa ulkopuolinen varmenteen myöntäjä ei pysty todentamaan. Koska jotkin varmenteen myöntäjät kuitenkin myöntävät varmenteita tällaisille nimille, et voi varmistaa, että olet muodostanut yhteyden haluamaasi verkkosivustoon etkä hakkeriin.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />tiedonhakua<ph name="END_LINK" /> ongelmaan liittyen</translation>
+<translation id="7455133967321480974">Käytä yleistä oletusasetusta (estä)</translation>
<translation id="7460163899615895653">Muiden laitteidesi viimeisimmät välilehdet näkyvät täällä.</translation>
<translation id="7469372306589899959">Vahvistetaan korttia</translation>
<translation id="7481312909269577407">Seuraava</translation>
@@ -696,36 +763,43 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="7508255263130623398">Palautettu käytännön laitetunnus on tyhjä tai ei vastaa nykyistä laitetunnusta.</translation>
<translation id="7514365320538308">Lataa</translation>
<translation id="7518003948725431193">Verkkosivua ei löytynyt osoitteelle: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Arvo</translation>
<translation id="7537536606612762813">Pakollinen</translation>
+<translation id="7542403920425041731">Vahvistamisen jälkeen korttisi tiedot jaetaan sivuston kanssa.</translation>
<translation id="7542995811387359312">Automaattinen luottokortin tietojen täyttäminen on poistettu käytöstä, koska tämä lomake ei käytä suojattua yhteyttä.</translation>
<translation id="7543525346216957623">Pyydä lupaa vanhemmalta</translation>
<translation id="7549584377607005141">Tämän sivun näyttäminen oikein edellyttää aiemmin lähetettyjä tietoja. Voit lähettää tiedot uudelleen, mutta tällöin sivulla mahdollisesti suoritettu toiminto toistetaan.</translation>
<translation id="7552846755917812628">Kokeile seuraavia keinoja:</translation>
<translation id="7554791636758816595">Uusi välilehti</translation>
+<translation id="7567204685887185387">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; sen suojausvarmenne on ehkä luotu vilpillisesti. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> toinen}other{<ph name="CONTACT_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> muuta}}</translation>
<translation id="7568593326407688803">Tämä sivu on kirjoitettu kielellä<ph name="ORIGINAL_LANGUAGE" />Haluatko kääntää sen?</translation>
<translation id="7569952961197462199">Poistetaanko luottokortti Chromen tiedoista?</translation>
<translation id="7569983096843329377">Musta</translation>
<translation id="7578104083680115302">Voit maksaa sivustoilla ja sovelluksissa nopeasti eri laitteillasi käyttämällä Googleen tallennettuja kortteja.</translation>
<translation id="7588950540487816470">Fyysinen web</translation>
<translation id="7592362899630581445">Palvelimen varmenne rikkoo nimirajoituksia.</translation>
+<translation id="7598391785903975535">Alle <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ei voi käsitellä tätä pyyntöä tällä hetkellä.</translation>
<translation id="7600965453749440009">Älä koskaan käännä kieltä <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Arvo on alueen ulkopuolella (<ph name="VALUE" />).</translation>
<translation id="7613889955535752492">Vanhenee: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Tietojasi on jo salattu Google-tilisi salasanan muulla versiolla. Syötä salasana alla.</translation>
-<translation id="7634554953375732414">Sivustoon ei ole muodostettu salattua yhteyttä.</translation>
<translation id="7637571805876720304">Poistetaanko luottokortti Chromiumista?</translation>
<translation id="765676359832457558">Piilota lisäasetukset...</translation>
<translation id="7658239707568436148">Peruuta</translation>
+<translation id="7662298039739062396">Laajennuksen hallinnoima asetus</translation>
<translation id="7667346355482952095">Palautettu käytäntötunnus on tyhjä tai ei vastaa nykyistä tunnusta.</translation>
<translation id="7668654391829183341">Tuntematon laite</translation>
<translation id="7669271284792375604">Tämän sivuston hyökkääjät saattavat yrittää huijata sinua asentamaan ohjelmia, jotka ovat haitallisia selauskokemuksellesi (esimerkiksi vaihtamalla aloitussivusi tai näyttämällä ylimääräisiä mainoksia käymilläsi sivustoilla).</translation>
<translation id="7674629440242451245">Oletko kiinnostunut Chromen uusista jännittävistä ominaisuuksista? Kokeile kehittäjäkanavaa osoitteessa chrome.com/dev.</translation>
<translation id="7682287625158474539">Toimitus</translation>
+<translation id="7701040980221191251">Ei mitään</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Siirry sivustoon <ph name="SITE" /> (tämä ei ole turvallista)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Varmenne</translation>
+<translation id="7716147886133743102">Järjestelmänvalvojan estämä</translation>
<translation id="7716424297397655342">Tätä sivustoa ei voi ladata välimuistista</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Ei hallinnoida</translation>
<translation id="7755287808199759310">Vanhempasi voi kumota eston puolestasi.</translation>
<translation id="7758069387465995638">Palomuuri tai virustorjuntaohjelmisto on saattanut estää yhteyden.</translation>
@@ -752,15 +826,15 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="7951415247503192394">(32-bittinen)</translation>
<translation id="7956713633345437162">Mobiilikirjanmerkit</translation>
<translation id="7961015016161918242">Ei koskaan</translation>
-<translation id="7962083544045318153">Kaatumistunnus <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Käännä aina kielestä <ph name="ORIGINAL_LANGUAGE" /> kielelle <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ei määritetty</translation>
<translation id="800218591365569300">Yritä vapauttaa muistia sulkemalla muita välilehtiä tai ohjelmia.</translation>
<translation id="8012647001091218357">Emme tavoittaneet vanhempiasi. Yritä uudelleen.</translation>
<translation id="8025119109950072390">Tälle sivustolle hyökännyt taho voi yrittää huijata sinua tekemään jotain vaarallista, kuten asentamaan ohjelmistoja tai paljastamaan henkilötietojasi (esimerkiksi salasanoja, puhelinnumeroita tai luottokorttitietoja).</translation>
-<translation id="803030522067524905">Googlen selaussuoja havaitsi äskettäin tietojenkalasteluyrityksen sivustolla <ph name="SITE" />. Tietojenkalastelusivustot yrittävät huijata käyttäjiä tekeytymällä toisiksi sivustoiksi. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Sivu on kirjoitettu kielellä <ph name="SOURCE_LANGUAGE" />. Haluatko kääntää sen kielelle <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Kysy (oletus)</translation>
<translation id="8041089156583427627">Lähetä palautetta</translation>
+<translation id="8041940743680923270">Käytä yleistä oletusasetusta (kysy)</translation>
<translation id="8088680233425245692">Artikkelin näyttäminen epäonnistui.</translation>
<translation id="8089520772729574115">alle 1 Mt</translation>
<translation id="8091372947890762290">Aktivointi odottaa palvelimella</translation>
@@ -769,13 +843,14 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="8134994873729925007">Isäntänimen <ph name="HOST_NAME" /> palvelimen <ph name="BEGIN_ABBR" />DNS-osoitetta<ph name="END_ABBR" /> ei löytynyt.</translation>
<translation id="8149426793427495338">Tietokoneesi siirtyi virransäästötilaan.</translation>
<translation id="8150722005171944719">Tiedosto osoitteessa <ph name="URL" /> ei ole luettavissa. Se on voitu poistaa tai siirtää, tai tiedoston käyttöluvat voivat estää sen käytön.</translation>
+<translation id="8184538546369750125">Käytä yleistä oletusasetusta (salli)</translation>
+<translation id="8191494405820426728">Paikallinen kaatumistunnus <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">K&amp;umoa siirto</translation>
<translation id="8201077131113104583">Laajennuksella, jonka tunnus on <ph name="EXTENSION_ID" />, on virheellinen päivitys-URL-osoite.</translation>
<translation id="8202097416529803614">Tilauksen yhteenveto</translation>
<translation id="8218327578424803826">Määrätty sijainti:</translation>
<translation id="8225771182978767009">Tämän tietokoneen määrittänyt henkilö on estänyt tämän sivuston.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Sivustoon <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökännyt taho voi yrittää asentaa tietokoneeseesi vaarallisia ohjelmia, jotka varastavat tai poistavat tietojasi, kuten kuviasi, salasanojasi, viestejäsi ja luottokorttiesi tietoja.</translation>
<translation id="8241707690549784388">Etsimäsi sivu käytti antamiasi tietoja. Sivulle palaaminen voi johtaa jokaisen tekemäsi toiminnon toistamiseen. Haluatko jatkaa?</translation>
<translation id="8249320324621329438">Viimeksi haettu:</translation>
<translation id="8253091569723639551">Laskutusosoite tarvitaan</translation>
@@ -783,6 +858,7 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="8289355894181816810">Ota yhteyttä verkon ylläpitäjään, jos et tiedä, mitä tämä tarkoittaa.</translation>
<translation id="8293206222192510085">Lisää kirjanmerkki</translation>
<translation id="8294431847097064396">Lähde</translation>
+<translation id="8306404619377842860">Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska tietokoneesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Käännös epäonnistui, koska verkkoyhteydessä esiintyi ongelmia.</translation>
<translation id="8332188693563227489">Sivuston <ph name="HOST_NAME" /> käyttöoikeus evättiin</translation>
<translation id="834457929814110454">Jos ymmärrät käyntiä koskevat turvallisuusriskit, voit <ph name="BEGIN_LINK" />siirtyä tähän sivustoon<ph name="END_LINK" /> jo ennen haitallisten ohjelmien poistamista.</translation>
@@ -803,11 +879,9 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="8483780878231876732">Jos haluat käyttää Google-tilillesi tallennettuja kortteja, kirjaudu Chromeen</translation>
<translation id="8488350697529856933">Käyttöalue</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ei vastannut riittävän nopeasti.</translation>
-<translation id="852346902619691059">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />, sillä laitteesi käyttöjärjestelmä ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai hyökkäyksestä, jonka tavoitteena on verkkoyhteytesi sieppaaminen. <ph name="BEGIN_LEARN_MORE_LINK" />Lisätietoja<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Voimassa (vuosi)</translation>
<translation id="8543181531796978784">Voit <ph name="BEGIN_ERROR_LINK" />ilmoittaa löytyneestä ongelmasta<ph name="END_ERROR_LINK" /> tai <ph name="BEGIN_LINK" />siirtyä mahdollisesti haitalliselle sivustolle<ph name="END_LINK" />, jos ymmärrät tietoturvariskit.</translation>
<translation id="8553075262323480129">Käännös epäonnistui, sillä sivun kieltä ei voitu määrittää.</translation>
-<translation id="8559762987265718583">Verkkotunnukseen <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ei voi muodostaa salattua yhteyttä, koska laitteesi aika ja päivämäärä (<ph name="DATE_AND_TIME" />) ovat virheelliset.</translation>
<translation id="8571890674111243710">Käännetään sivua kielelle <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Lisää puh.nro
</translation>
@@ -822,6 +896,7 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="8738058698779197622">Kellosi täytyy asettaa oikeaan aikaan, jotta salattu yhteys voidaan muodostaa. Tämä johtuu siitä, että verkkosivustojen tunnistamisessa käytettävät varmenteet ovat voimassa vain tiettyinä ajanjaksoina. Chromium ei voi vahvistaa varmenteita, koska laitteesi kello on väärässä ajassa.</translation>
<translation id="8740359287975076522">Sivuston <ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;DNS-osoitetta&lt;/abbr&gt; ei löydy. Ongelmaa diagnosoidaan.</translation>
<translation id="8759274551635299824">Tämä kortti on vanhentunut.</translation>
+<translation id="8761567432415473239">Google-selaussuoja <ph name="BEGIN_LINK" />löysi hiljattain haitallisia ohjelmia<ph name="END_LINK" /> sivustolta <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Toista poisto</translation>
<translation id="8800988563907321413">Nearby-ehdotuksesi näkyvät tässä.</translation>
<translation id="8820817407110198400">Kirjanmerkit</translation>
@@ -834,29 +909,30 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="8870413625673593573">Hiljattain suljetut</translation>
<translation id="8874824191258364635">Anna kelvollinen kortin numero.</translation>
<translation id="8876793034577346603">Verkkoasetuksia ei voitu jäsentää.</translation>
-<translation id="8877192140621905067">Vahvistamisen jälkeen korttisi tiedot jaetaan sivuston kanssa.</translation>
<translation id="8889402386540077796">Sävy</translation>
<translation id="8891727572606052622">Virheellinen välityspalvelimen tila.</translation>
<translation id="889901481107108152">Tämä kokeilu ei ole käytettävissä käyttöympäristössäsi.</translation>
<translation id="8903921497873541725">Lähennä</translation>
<translation id="8931333241327730545">Haluatko tallentaa tämän kortin Google-tilillesi?</translation>
<translation id="8932102934695377596">Kellosi jätättää</translation>
-<translation id="8954894007019320973">(jatkuu)</translation>
<translation id="8971063699422889582">Palvelimen varmenne on vanhentunut.</translation>
<translation id="8986494364107987395">Lähetä Googlelle käyttötilastoja ja virheraportteja automaattisesti</translation>
-<translation id="8987927404178983737">Kuukausi</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Sivusto sisältää haitallisia ohjelmia</translation>
+<translation id="8997023839087525404">Palvelimen lähettämän varmenteen tietoja ei ole annettu yleiseen käyttöön Certificate Transparency ‑käytännön mukaisesti. Tietojen antamista edellytetään joiltakin varmenteilta, jotta niiden luotettavuus voidaan varmistaa ja käyttäjiä suojella hyökkääjiltä.</translation>
<translation id="9001074447101275817">Välityspalvelin <ph name="DOMAIN" /> vaatii käyttäjänimen ja salasanan.</translation>
+<translation id="9005998258318286617">PDF-asiakirjan lataaminen epäonnistui.</translation>
<translation id="901974403500617787">Koko järjestelmään vaikuttavat merkinnät voi tehdä vain omistaja: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Kortin laskutusosoite pakollinen</translation>
<translation id="9020542370529661692">Sivu on käännetty kielelle <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Suojausvirhe</translation>
<translation id="9038649477754266430">Ennakointipalvelun avulla voit ladata sivuja nopeammin</translation>
<translation id="9039213469156557790">Tällä sivulla on kuitenkin muita osia, jotka eivät ole suojattuja. Muut voivat tarkastella näitä osia siirron aikana, ja hyökkääjä voi muuttaa sivun käyttäytymistä muokkaamalla näitä osia.</translation>
-<translation id="9040185888511745258">Sivuston <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hyökkääjät saattavat yrittää huijata sinua asentamaan ohjelmia, jotka ovat haitallisia selauskokemuksellesi (esimerkiksi vaihtamalla aloitussivusi tai näyttämällä ylimääräisiä mainoksia käymilläsi sivustoilla).</translation>
+<translation id="9049981332609050619">Yritit muodostaa yhteyden verkkotunnukseen <ph name="DOMAIN" />, mutta palvelin esitti virheellisen varmenteen.</translation>
<translation id="9050666287014529139">Tunnuslause</translation>
<translation id="9065203028668620118">Muokkaa</translation>
<translation id="9068849894565669697">Valitse väri</translation>
+<translation id="9069693763241529744">Laajennuksen estämä</translation>
<translation id="9076283476770535406">Se saattaa sisältää vain aikuisille tarkoitettua sisältöä.</translation>
<translation id="9078964945751709336">Lisätietoja tarvitaan</translation>
<translation id="9103872766612412690"><ph name="SITE" /> suojaa tietosi normaalisti salauksen avulla. Kun Chromium yritti tällä kertaa yhdistää sivustoon <ph name="SITE" />, sivusto palautti epätavalliset ja virheelliset kirjautumistiedot. Hyökkääjä saattaa yrittää esiintyä sivustona <ph name="SITE" />, tai Wi-Fi-kirjautumisruutu on keskeyttänyt yhteyden. Tietosi ovat edelleen turvassa, sillä Chromium katkaisi yhteyden, ennen kuin mitään tietoja vaihdettiin.</translation>
@@ -865,16 +941,21 @@ Psst! Suosittelemme käyttämään ensi kerralla incognito-tilaa <ph name="SHORT
<translation id="9148507642005240123">K&amp;umoa muokkaus</translation>
<translation id="9154194610265714752">Päivitetty</translation>
<translation id="9157595877708044936">Valmistellaan...</translation>
+<translation id="9169664750068251925">Estä aina tämä sivusto</translation>
<translation id="9170848237812810038">K&amp;umoa</translation>
<translation id="917450738466192189">Palvelimen varmenne ei kelpaa.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> toinen}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ja <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> muuta}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> käyttää protokollaa, jota ei tueta.</translation>
<translation id="9205078245616868884">Tietosi on salattu synkronoinnin tunnuslauseesi avulla. Aloita synkronointi antamalla tunnuslause.</translation>
<translation id="9207861905230894330">Artikkelin lisääminen epäonnistui.</translation>
+<translation id="9219103736887031265">Kuvat</translation>
<translation id="933612690413056017">Ei internetyhteyttä</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">TYHJENNÄ LOMAKE</translation>
<translation id="939736085109172342">Uusi kansio</translation>
<translation id="941721044073577244">Vaikuttaa siltä, että sinulla ei ole lupaa käyttää tätä sivustoa.</translation>
<translation id="969892804517981540">Virallinen koontiversio</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ei mitään}=1{1 kohde}other{# kohdetta}}</translation>
<translation id="988159990683914416">Kehittäjän koontiversio</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fil.xtb b/chromium/components/strings/components_strings_fil.xtb
index 2e0ac889854..ef699ea5996 100644
--- a/chromium/components/strings/components_strings_fil.xtb
+++ b/chromium/components/strings/components_strings_fil.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">I-rotate pakanan</translation>
<translation id="1038842779957582377">Hindi kilalang pangalan</translation>
<translation id="1050038467049342496">Isara ang iba pang app</translation>
-<translation id="1053591932240354961">Hindi mo mabibisita ang <ph name="SITE" /> sa ngayon dahil nagpadala ang website ng mga pinaghalo-halong kredensyal na hindi maproseso ng Google Chrome. Kadalasang pansamantala lang ang mga error at atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;I-undo ang Pagdagdag</translation>
<translation id="10614374240317010">Hindi kailanman nag-save</translation>
<translation id="106701514854093668">Mga Bookmark sa Desktop</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">OK ang cache ng patakaran</translation>
<translation id="113188000913989374">Isinasaad ng <ph name="SITE" /> na:</translation>
<translation id="1132774398110320017">Mga setting ng Autofill ng Chrome...</translation>
+<translation id="1150979032973867961">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng operating system ng iyong computer ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
+<translation id="1151972924205500581">Kinakailangan ang password</translation>
<translation id="1152921474424827756">Mag-access ng <ph name="BEGIN_LINK" />naka-cache na kopya<ph name="END_LINK" /> ng <ph name="URL" /></translation>
<translation id="1158211211994409885">Pinutol ng <ph name="HOST_NAME" /> ang koneksyon nang hindi inaasahan.</translation>
<translation id="1161325031994447685">Muling kumonekta sa Wi-Fi</translation>
+<translation id="1165039591588034296">Error</translation>
<translation id="1175364870820465910">&amp;I-print...</translation>
<translation id="1181037720776840403">Alisin</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Awtomatikong iulat<ph name="END_WHITEPAPER_LINK" /> ang mga detalye ng mga posibleng insidente ng seguridad sa Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Higit pa mula sa site na ito</translation>
<translation id="1206967143813997005">Hindi magandang paunang signature</translation>
<translation id="1209206284964581585">Itago sa ngayon</translation>
+<translation id="121201262018556460">Tinangka mong maabot ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng isang certificate na naglalaman ng isang mahinang key. Maaaring sinira ng isang nang-aatake ang pribadong key, at ang server ay maaaring hindi ang server na iyong inaasahan (maaaring nakikipag-ugnay ka sa isang nang-aatake).</translation>
<translation id="1219129156119358924">Seguridad ng System</translation>
<translation id="1227224963052638717">Hindi kilalang patakaran</translation>
<translation id="1227633850867390598">Itago ang halaga</translation>
<translation id="1228893227497259893">Maling tagatukoy ng entity</translation>
<translation id="1232569758102978740">Walang pamagat</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (naka-sync)</translation>
<translation id="1263231323834454256">Listahan ng babasahin</translation>
<translation id="1264126396475825575">Ulat ng pag-crash na nakuha noong <ph name="CRASH_TIME" /> (hindi pa naa-upload o nababalewala)</translation>
+<translation id="1281526147609854549">Inisyu ng <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Na-block ang mapanganib na content</translation>
<translation id="1285320974508926690">Huwag isalin kailanman ang site na ito</translation>
<translation id="129553762522093515">Kamakailang isinara</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Subukang i-clear ang iyong cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Ang iyong aktibidad <ph name="BEGIN_EMPHASIS" />ay maaari pa ring makita<ph name="END_EMPHASIS" /> ng:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Mga binibisita mong website
+ <ph name="LIST_ITEM" />Iyong employer o paaralan
+ <ph name="LIST_ITEM" />Internet service provider mo
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domain ng pagpapatala:</translation>
<translation id="1340482604681802745">Address sa pag-pick up</translation>
<translation id="1344211575059133124">Mukhang kailangan mo ng pahintulot upang mabisita ang site na ito</translation>
<translation id="1344588688991793829">Mga setting ng Autofill ng Chromium...</translation>
+<translation id="1348198688976932919">Naglalaman ng mga mapanganib na app ang pupuntahang site</translation>
<translation id="1374468813861204354">mga suhestiyon</translation>
<translation id="1375198122581997741">Tungkol sa Bersyon</translation>
<translation id="1377321085342047638">Numero ng Card</translation>
<translation id="139305205187523129">Hindi nagpadala ng anumang data ang <ph name="HOST_NAME" />.</translation>
<translation id="1407135791313364759">Buksan lahat</translation>
<translation id="1413809658975081374">Error sa privacy</translation>
+<translation id="14171126816530869">Ang pagkilanlan ng <ph name="ORGANIZATION" /> sa <ph name="LOCALITY" /> ay napatotohanan ng <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Oo</translation>
<translation id="1430915738399379752">I-print</translation>
-<translation id="1442912890475371290">Na-block na pagtangkang <ph name="BEGIN_LINK" /> bumisita ng isang pahina sa <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Hindi mo mabibisita ang <ph name="SITE" /> sa ngayon dahil gumagamit ang website ng pagpi-pin ng certificate. Kadalasang pansamantala lang ang mga error at atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> pa}one{<ph name="PAYMENT_METHOD_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> pa}other{<ph name="PAYMENT_METHOD_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> pa}}</translation>
<translation id="1506687042165942984">Magpakita ng naka-save (ibigsabihin alam na hindi napapanahon) na kopya ng page na ito.</translation>
<translation id="1517433312004943670">Kinakailangan ang numero ng telepono</translation>
<translation id="1519264250979466059">Petsa ng Build</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Dapat naka-enable ang JavaScript upang magamit ang feature na ito.</translation>
<translation id="1555130319947370107">Asul</translation>
<translation id="1559528461873125649">Walang naturang file o direktoryo</translation>
-<translation id="1559572115229829303">&lt;p&gt;Hindi makapagtatag ng pribadong koneksyon sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras ng iyong device (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
-
- &lt;p&gt;Mangyaring isaayos ang petsa at oras mula sa seksyong &lt;strong&gt;Pangkalahatan&lt;/strong&gt; ng app na &lt;strong&gt;Mga Setting&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Nagkaroon ng problema habang ipinapakita ang webpage na ito.</translation>
<translation id="1592005682883173041">Access sa Lokal na Data</translation>
+<translation id="1594030484168838125">Pumili</translation>
<translation id="161042844686301425">Cyan</translation>
+<translation id="1620510694547887537">Camera</translation>
<translation id="1629803312968146339">Gusto mo bang i-save ng Chrome ang card na ito?</translation>
<translation id="1639239467298939599">Naglo-load</translation>
<translation id="1640180200866533862">Mga patakaran ng user</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Di-wasto ang configuration ng network at hindi maaaring i-import.</translation>
<translation id="1644574205037202324">History</translation>
<translation id="1645368109819982629">Hindi sinusuportahang protocol</translation>
+<translation id="1655462015569774233">{1,plural, =1{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate ng seguridad nito kahapon. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at pagkatapos ay i-refresh ang page na ito.}one{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate ng seguridad nito # araw na ang nakalipas. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at pagkatapos ay i-refresh ang page na ito.}other{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate ng seguridad nito # na araw na ang nakalipas. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at pagkatapos ay i-refresh ang page na ito.}}</translation>
<translation id="1656489000284462475">I-pick up</translation>
<translation id="1663943134801823270">Ang mga card at address ay mula sa Chrome. Maaari mong pamahalaan ang mga ito sa <ph name="BEGIN_LINK" />Mga Setting<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Karaniwang gumagamit ang <ph name="SITE" /> ng pag-encrypt upang protektahan ang iyong impormasyon. Noong sinubukang kumonekta ng Chrome sa <ph name="SITE" /> sa pagkakataong ito, nagbalik ang website ng mga hindi pangkaraniwan at maling kredensyal. Maaari itong mangyari kapag sinusubukan ng isang attacker na magpanggap bilang <ph name="SITE" />, o naputol ang koneksyon dahil sa isang screen ng pag-sign in sa Wi-Fi. Secure pa rin ang iyong impormasyon dahil inihinto ng Google Chrome ang koneksyon bago magkaroon ng palitan ng anumang data.</translation>
-<translation id="168328519870909584">Ang mga umaatakeng kasalukuyang nasa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ay maaaring magtangkang mag-install ng mapapanganib na app sa iyong device na nagnanakaw o nagde-delete ng iyong impormasyon (halimbawa, mga larawan, password, mensahe at credit card).</translation>
<translation id="168841957122794586">Naglalaman ang server certificate ng isang mahinang cryptographic key.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; tinatayang mula sa susunod na araw ang certificate ng seguridad nito. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon.}one{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; tinatayang mula sa # araw sa hinaharap ang certificate ng seguridad nito. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon.}other{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; tinatayang mula sa # na araw sa hinaharap ang certificate ng seguridad nito. Maaaring resulta ito ng maling configuration o kaya ng isang attacker na humahadlang sa iyong koneksyon.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Kailangan mo ng pahintulot mula kay <ph name="NAME" /> upang mabisita ang site na ito</translation>
<translation id="1721424275792716183">Kinakailangan ang field na may *</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">I-download ang page sa ibang pagkakataon</translation>
<translation id="17513872634828108">Mga bukas na tab</translation>
<translation id="1753706481035618306">Numero ng page</translation>
+<translation id="1763864636252898013">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng operating system ng iyong device ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Subukang patakbuhin ang Windows Network Diagnostics<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Mangyaring i-update ang iyong passphrase ng pag-sync.</translation>
<translation id="1787142507584202372">Lalabas dito ang iyong mga bukas na tab</translation>
+<translation id="1789575671122666129">Mga Popup</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Pangalan ng Cardholder</translation>
-<translation id="1803678881841855883">Kamakailan lang, <ph name="BEGIN_LINK" />nakakita ng malware<ph name="END_LINK" /> ang Google Safe Browsing sa <ph name="SITE" />. Nagkakaroon ng malware paminsan-minsan ang mga website na karaniwang ligtas. Nanggagaling ang nakakahamak na content sa <ph name="SUBRESOURCE_HOST" />, isang kilalang distributor ng malware. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Idinagdag noong <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Di-wastong kahilingan o mga parameter ng kahilingan</translation>
<translation id="1826516787628120939">Sinusuri</translation>
<translation id="1834321415901700177">Naglalaman ng mga mapanirang program ang site na ito</translation>
+<translation id="1840414022444569775">Nagamit na ang numero ng card na ito</translation>
<translation id="1842969606798536927">Magbayad</translation>
<translation id="1871208020102129563">Nakatakda ang proxy upang gumamit ng mga hindi nababagong proxy server, hindi ng isang .pac script URL.</translation>
<translation id="1871284979644508959">Kinakailangang field</translation>
<translation id="187918866476621466">Buksan ang mga page sa pagsisimula</translation>
<translation id="1883255238294161206">Tiklupin ang listahan</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> pa}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> pa}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> pa}}</translation>
<translation id="1898423065542865115">Pagfi-filter</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Wala}=1{1 site}one{# site}other{# na site}}</translation>
<translation id="194030505837763158">Pumunta sa <ph name="LINK" /></translation>
<translation id="1962204205936693436">Mga Bookmark ng <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Error sa serialization</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Binalewala dahil na-override ito ng <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Naghahanap ng mga kalapit na page sa Pisikal na Web</translation>
<translation id="213826338245044447">Mga Bookmark sa Mobile</translation>
-<translation id="2148716181193084225">Ngayon</translation>
+<translation id="2147827593068025794">Pag-sync sa Background</translation>
<translation id="2154054054215849342">Hindi available ang pag-sync para sa iyong domain</translation>
<translation id="2154484045852737596">I-edit ang card</translation>
<translation id="2166049586286450108">Ganap na Access ng Admin</translation>
<translation id="2166378884831602661">Hindi makakapagbigay ng secure na koneksyon ang site na ito</translation>
<translation id="2181821976797666341">Mga Patakaran</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 address}one{# address}other{# na address}}</translation>
+<translation id="2187317261103489799">Tukuyin (default)</translation>
<translation id="2202020181578195191">Maglagay ng wastong taon ng pag-expire</translation>
<translation id="2212735316055980242">Hindi nahanap ang patakaran</translation>
<translation id="2213606439339815911">Kinukuha ang mga entry...</translation>
+<translation id="2218879909401188352">Ang mga umaatake na kasalukuyang nasa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ay maaaring mag-install ng mga mapanganib na app na makakapinsala sa iyong device, magdagdag ng mga hindi alam na singil sa mobile bill mo, o magnakaw ng iyong personal na impormasyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Ayusin ang iyong koneksyon gamit ang <ph name="BEGIN_LINK" />diagnostics app<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Ipadala ngayon</translation>
<translation id="225207911366869382">Hindi na gimagamit ang halagang ito para sa patakarang ito.</translation>
<translation id="2262243747453050782">Error sa HTTP</translation>
+<translation id="2270484714375784793">Numero ng telepono</translation>
<translation id="2282872951544483773">Mga Eksperimentong Hindi Available</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item}one{<ph name="ITEM_COUNT" /> item}other{<ph name="ITEM_COUNT" /> na item}}</translation>
<translation id="2292556288342944218">Naka-block ang iyong access sa Internet</translation>
<translation id="230155334948463882">Bagong card?</translation>
-<translation id="2305919008529760154">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; maaaring mapanlokong ibinigay ang certificate na panseguridad. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">Kailangan ng <ph name="DOMAIN" /> ng username at password.</translation>
-<translation id="2318774815570432836">Hindi mo mabibisita ang <ph name="SITE" /> sa ngayon dahil gumagamit ang website ng HSTS. Kadalasang pansamantala lang ang mga error at atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Kinokontrol ng iyong administrator ang setting</translation>
<translation id="2354001756790975382">Iba pang mga bookmark</translation>
+<translation id="2354430244986887761"><ph name="BEGIN_LINK" />May nahanap na mga mapanganib na app<ph name="END_LINK" /> kamakailan ang Ligtas na Pag-browse ng Google sa <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Maaaring makita ng mga umaatake ang mga larawang tinitingnan mo sa site na ito at lilinlangin ka sa pamamagitan ng pagbago sa mga ito.</translation>
+<translation id="2356070529366658676">Magtanong</translation>
+<translation id="2359629602545592467">Marami</translation>
<translation id="2359808026110333948">Magpatuloy</translation>
<translation id="2365563543831475020">Hindi na-upload ang nakuhang ulat ng pag-crash noong <ph name="CRASH_TIME" /></translation>
<translation id="2367567093518048410">Antas</translation>
-<translation id="2371153335857947666">{1,plural, =1{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire kahapon ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at i-refresh ang page na ito pagkatapos. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.}one{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate na panseguridad nito # araw na ang nakalipas. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at i-refresh ang page na ito pagkatapos. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.}other{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; nag-expire na ang certificate na panseguridad nito # na araw na ang nakalipas. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. Sa kasalukuyan, nakatakda ang orasan ng iyong computer sa <ph name="CURRENT_DATE" />. Mukha bang tama iyon? Kung hindi, dapat mong ayusin ang orasan ng iyong system at i-refresh ang page na ito pagkatapos. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Walang mga available na alternatibo sa UI</translation>
<translation id="2384307209577226199">Default ng enterprise</translation>
<translation id="2386255080630008482">Nabawi ang certificate ng server.</translation>
<translation id="2392959068659972793">Ipakita ang mga patakarang walang nakatakdang halaga</translation>
<translation id="239429038616798445">Hindi available ang pamamaraan ng pagpapadala na ito. Sumubok ng ibang pamamaraan.</translation>
<translation id="2396249848217231973">&amp;I-undo ang pagtanggal</translation>
-<translation id="2460160116472764928">Kamakailan lang, <ph name="BEGIN_LINK" />nakakita ng malware<ph name="END_LINK" /> ang Google Safe Browsing sa <ph name="SITE" />.Nagkakaroon ng malware paminsan-minsan ang mga website na karaniwang ligtas. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; maaaring binawi ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
<translation id="2463739503403862330">Punan</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Magpatakbo ng Network Diagnostics<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Di-wastong URL ng paghahanap.</translation>
+<translation id="2482878487686419369">Mga Abiso</translation>
<translation id="2491120439723279231">Naglalaman ng mga error ang certificate ng server.</translation>
<translation id="2495083838625180221">Pang-parse ng JSON</translation>
<translation id="2495093607237746763">Kung may check, mag-iimbak ang Chromium ng kopya ng iyong card sa device na ito para sa mas mabilis na pagsagot sa form.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Bumalik</translation>
<translation id="2515629240566999685">Suriin ang signal sa iyong lugar</translation>
<translation id="2516305470678292029">Mga Alternatibo sa UI</translation>
+<translation id="2539524384386349900">Tukuyin</translation>
<translation id="255002559098805027">Nagpadala ng di-wastong tugon ang <ph name="HOST_NAME" />.</translation>
-<translation id="2552545117464357659">Mas Bago</translation>
<translation id="2556876185419854533">&amp;I-undo ang Pag-e-edit</translation>
<translation id="2587730715158995865">Mula sa <ph name="ARTICLE_PUBLISHER" />. Basahin ito at ang <ph name="OTHER_ARTICLE_COUNT" /> (na) iba pang kwento.</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">Protektado ng password ang dokumentong ito. Mangyaring magpasok ng password.</translation>
<translation id="2609632851001447353">Mga Pagkakaiba-iba</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Wala}=1{1 app ($1)}=2{2 app ($1, $2)}one{# app ($1, $2, $3)}other{# na app ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Nauuna ang iyong orasan</translation>
<translation id="2639739919103226564">Katayuan:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Tinanggihan ang access sa file</translation>
<translation id="2653659639078652383">Isumite</translation>
<translation id="2666117266261740852">Isara ang iba pang tab o app</translation>
+<translation id="2670429602441959756">Naglalaman ang page na ito ng mga feature na hindi pa sinusuportahan sa VR. Lumalabas...</translation>
<translation id="2674170444375937751">Sigurado ka bang nais mong tanggalin ang mga pahinang ito mula sa iyong history?</translation>
<translation id="2677748264148917807">Umalis</translation>
-<translation id="269990154133806163">Nagpakita ang server ng certificate na hindi inihayag sa publiko gamit ang patakaran sa Transparency ng Certificate. Kinakailangan ito para sa ilang certificate, upang siguraduhing mapagkakatiwalaan ang mga ito at upang maprotektahan laban sa mga nang-aatake. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Listahan ng Babasahin</translation>
<translation id="2704283930420550640">Hindi tumutugma ang format sa halaga.</translation>
<translation id="2704951214193499422">Hindi nakumpirma ng Chromium ang iyong card sa pagkakataong ito. Pakisubukang muli sa ibang pagkakataon.</translation>
<translation id="2705137772291741111">Hindi mabasa ang naka-save (naka-cache) na kopya ng site na ito.</translation>
<translation id="2709516037105925701">AutoFill</translation>
-<translation id="2712118517637785082">Tinangka mong makakonekta sa <ph name="DOMAIN" />, ngunit ang ipinakitang certificate ng server ay binawi ng nagbigay. Nangangahulugan ito na malinaw na hindi dapat pagkatiwalaan ang mga kredensyal na panseguridad na ipinakita ng server. Maaaring nakikipag-ugnayan ka sa isang nang-aatake. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Humingi ng pahintulot</translation>
<translation id="2713444072780614174">Puti</translation>
<translation id="2720342946869265578">Malapit</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Nawawalang tala ng device</translation>
<translation id="2784949926578158345">Na-reset ang koneksyon.</translation>
<translation id="2794233252405721443">Naka-block ang site</translation>
+<translation id="2799020568854403057">Naglalaman ng mga mapaminsalang app ang pupuntahang site</translation>
+<translation id="2803306138276472711">Kamakailan lang, ang Google Safe Browsing ay <ph name="BEGIN_LINK" />nakakita ng malware<ph name="END_LINK" /> sa <ph name="SITE" />. Paminsan-minsan, nagkakaroon ng malware ang mga website na karaniwang ligtas.</translation>
<translation id="2824775600643448204">Address bar at bar sa paghahanap</translation>
<translation id="2826760142808435982">Ine-encrypt at pinapatotoo ang koneksyon gamit ang <ph name="CIPHER" /> at ginagamit ang <ph name="KX" /> bilang key exchange mechanism.</translation>
<translation id="2835170189407361413">I-clear ang form</translation>
+<translation id="2856444702002559011">Maaaring sinusubukang nakawin ng mga attacker ang iyong impormasyon mula sa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (halimbawa, mga password, mensahe, o credit card). <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Huwag I-reload</translation>
<translation id="2900469785430194048">Naubusan ng memory ang Google Chrome habang sinusubukang ipakita ang webpage na ito.</translation>
<translation id="2909946352844186028">May nakitang pagbabago sa network.</translation>
<translation id="2916038427272391327">Isara ang iba pang program</translation>
<translation id="2922350208395188000">Hindi masuri ang certificate ng server.</translation>
<translation id="2928905813689894207">Billing Address</translation>
+<translation id="2941952326391522266">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; mula sa <ph name="DOMAIN2" /> ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
<translation id="2948083400971632585">Maaari mong i-disable ang anumang mga proxy na naka-configure para sa isang koneksyon mula sa pahina ng mga setting.</translation>
<translation id="2955913368246107853">Isara ang bar sa paghahanap</translation>
<translation id="2958431318199492670">Hindi sumusunod ang configuration ng network sa pamantayan ng ONC. Hindi maaaring i-import ang mga bahagi ng configuration.</translation>
-<translation id="29611076221683977">Maaaring subukan ng mga attacker na kasalukuyang nasa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na mag-install ng mga mapanganib na program sa iyong Mac na nagnanakaw o nagde-delete ng iyong impormasyon (halimbawa, mga larawan, password, mensahe at credit card).</translation>
<translation id="2966678944701946121">Exp: <ph name="EXPIRATION_DATE_ABBR" />, idinagdag noong <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Upang makapagtatag ng secure na koneksyon, kailangang itakda nang tama ang iyong orasan. Ito ay dahil sa may-bisa lang ang mga certificate na ginagamit ng mga website upang tukuyin ang mga sarili ng mga ito sa loob ng mga partikular na tagal ng panahon. Dahil mali ang orasan ng iyong device, hindi ma-verify ng Google Chrome ang mga certificate na ito.</translation>
<translation id="2972581237482394796">&amp;I-redo</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Maglagay ng wastong address</translation>
<translation id="2986368408720340940">Hindi available ang pamamaraan ng pag-pick up na ito. Sumubok ng ibang pamamaraan.</translation>
<translation id="2991174974383378012">Pagbabahagi sa Mga Website</translation>
+<translation id="2991571918955627853">Hindi mo maaaring bisitahin ang <ph name="SITE" /> sa ngayon dahil gumagamit ng HSTS ang website. Karaniwang pansamantala lang ang mga error at pag-atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon.</translation>
<translation id="3005723025932146533">Ipakita ang naka-save na kopya</translation>
<translation id="3008447029300691911">Ilagay ang CVC para sa <ph name="CREDIT_CARD" />. Kapag nagkumpirma ka na, ibabahagi ang mga detalye ng iyong card sa site na ito.</translation>
<translation id="3010559122411665027">Listahan ng entry na "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Awtomatikong na-block</translation>
<translation id="3024663005179499861">Maling uri ng patakaran</translation>
<translation id="3032412215588512954">Gusto mo bang i-reload ang site na ito?</translation>
<translation id="3037605927509011580">Ay, Naku!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{kahit 1 item sa mga naka-sync na device}=1{1 item (at higit pa sa mga naka-sync na device)}one{# item (at higit pa sa mga naka-sync na device)}other{# na item (at higit pa sa mga naka-sync na device)}}</translation>
<translation id="3041612393474885105">Impormasyon sa Certificate</translation>
<translation id="3063697135517575841">Hindi nakumpirma ng Chrome ang iyong card sa pagkakataong ito. Pakisubukang muli sa ibang pagkakataon.</translation>
<translation id="3064966200440839136">Aalis sa incognito mode upang magbayad sa pamamagitan ng external na application. Magpatuloy?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Wala}=1{1 password}one{# password}other{# na password}}</translation>
<translation id="3093245981617870298">Offline ka.</translation>
<translation id="3105172416063519923">Asset ID:</translation>
<translation id="3109728660330352905">Wala kang pahintulot na tingnan ang page na ito.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Subukang magpatakbo ng Connectivity Diagnostics<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Nabigong i-decode ang tugon</translation>
<translation id="3150653042067488994">Pansamantalang error sa server</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Ang mga page na titingnan mo sa mga tab na incognito ay hindi mananatili sa history, cookie store o history ng paghahanap ng iyong browser kapag naisara mo na ang lahat ng iyong tab na incognito. Papanatilihin ang anumang mga file na ida-download mo o mga bookmark na gagawin mo.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Pulo</translation>
+<translation id="317583078218509884">Magkakaroon ng bisa ang mga bagong setting ng pahintulot sa site pagkatapos i-reload ang pahina.</translation>
<translation id="3176929007561373547">Tingnan ang mga setting ng iyong proxy o makipag-ugnayan sa iyong network
administrator upang matiyak na gumagana ang proxy server. Kung sa palagay mo
ay hindi ka dapat gumagamit ng proxy server:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Buksan ang page sa Incognito mode</translation>
-<translation id="3202578601642193415">Pinakabago</translation>
+<translation id="320323717674993345">Kanselahin ang Pagbabayad</translation>
<translation id="3207960819495026254">Naka-bookmark</translation>
+<translation id="3225919329040284222">Nagpakita ang server ng certificate na hindi tumutugma sa mga built-in na inaasahan. Ang mga inaasahang ito ay isinama para sa ilang partikular na website na may mataas na antas ng seguridad upang maprotektahan ka.</translation>
<translation id="3226128629678568754">Pindutin ang button na i-reload upang isumiteng muli ang data na kailangan upang ma-load ang pahina.</translation>
+<translation id="3227137524299004712">Mikropono</translation>
<translation id="3228969707346345236">Nabigo ang pag-translate dahil nasa <ph name="LANGUAGE" /> na ang pahina.</translation>
<translation id="323107829343500871">Ilagay ang iyong CVC para sa <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Palaging tukuyin ang mahalagang content sa site na ito</translation>
<translation id="3254409185687681395">I-bookmark ang page na ito</translation>
<translation id="3270847123878663523">&amp;I-undo ang Pagbabago sa Ayos</translation>
<translation id="3282497668470633863">Magdagdag ng pangalan sa card</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">mga setting</translation>
<translation id="3345135638360864351">Hindi maipadala kay <ph name="NAME" /> ang iyong kahilingang i-access ang site na ito. Pakisubukang muli.</translation>
<translation id="3355823806454867987">Baguhin ang mga setting ng proxy...</translation>
+<translation id="3361596688432910856"><ph name="BEGIN_EMPHASIS" />Hindi ise-save<ph name="END_EMPHASIS" /> ng Chrome ang sumusunod na impormasyon:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Iyong history ng pag-browse
+ <ph name="LIST_ITEM" />Cookies at data ng site
+ <ph name="LIST_ITEM" />Impormasyong nilagay sa mga form
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Error sa orasan</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> pang item...</translation>
<translation id="337363190475750230">Naalis sa pagkakaprobisyon</translation>
<translation id="3377188786107721145">Error sa pag-parse ng patakaran</translation>
<translation id="3380365263193509176">Hindi kilalang error</translation>
<translation id="3380864720620200369">Client ID:</translation>
<translation id="3391030046425686457">Address kung saan maghahatid</translation>
<translation id="3395827396354264108">Pamamaraan sa pag-pick up</translation>
-<translation id="340013220407300675">Maaaring sinusubukan ng mga masasamang-loob na nakawin ang iyong impormasyon mula sa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (halimbawa, mga password, mensahe o credit card).</translation>
<translation id="3422248202833853650">Subukang lumabas sa iba pang program upang magbakante ng memory.</translation>
<translation id="3422472998109090673">Hindi makakonekta sa <ph name="HOST_NAME" /> sa kasalukuyan.</translation>
+<translation id="3427092606871434483">Payagan (default)</translation>
<translation id="3427342743765426898">&amp;Gawing Muli ang Pag-e-edit</translation>
<translation id="3431636764301398940">I-save ang card na ito sa device na ito</translation>
<translation id="3435896845095436175">I-enable</translation>
<translation id="3447661539832366887">Na-off ng may-ari ng device na ito ang larong dinosaur.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Kunin ang agwat:</translation>
<translation id="3462200631372590220">Itago ang advanced</translation>
<translation id="3467763166455606212">Kinakailangan ang pangalan ng cardholder</translation>
<translation id="3478058380795961209">Buwan ng Pag-expire</translation>
<translation id="3479539252931486093">Hindi mo ba ito inaasahan? <ph name="BEGIN_LINK" />Ipaalam sa amin<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Hindi ngayon</translation>
-<translation id="348000606199325318">Crash ID <ph name="CRASH_LOCAL_ID" /> (Server ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Hindi namin makaugnayan ang iyong magulang sa sandaling ito. Pakisubukang muli.</translation>
<translation id="3528171143076753409">Hindi pinagkakatiwalaan ang certificate ng server.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Hindi bababa sa 1 item sa mga naka-sync na device}=1{1 item (at higit pa sa mga naka-sync na device)}one{# item (at higit pa sa mga naka-sync na device)}other{# na item (at higit pa sa mga naka-sync na device)}}</translation>
<translation id="3539171420378717834">Magtago ng kopya ng card na ito sa device na ito</translation>
<translation id="3542684924769048008">Gamitin ang password para sa:</translation>
+<translation id="3545341443414427877">Hindi makakonekta nang pribado sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras (<ph name="DATE_AND_TIME" />) sa iyong computer. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">I-encrypt ang lahat ng naka-sync na data gamit ang sarili mong passphrase sa pag-sync</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> pa...</translation>
-<translation id="3555561725129903880">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; ang certificate na panseguridad nito ay nanggaling sa <ph name="DOMAIN2" />. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Maaari itong alisin sa pagkaka-block ng iyong manager para sa iyo</translation>
<translation id="3566021033012934673">Hindi pribado ang iyong koneksyon</translation>
+<translation id="3569145463236695319">&lt;p&gt;Hindi makakonekta nang pribado sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras (<ph name="DATE_AND_TIME" />) sa iyong device.&lt;/p&gt;
+
+ &lt;p&gt;Pakiayos ang petsa at oras mula sa seksyong &lt;strong&gt;Pangkalahatan&lt;/strong&gt; ng app na &lt;strong&gt;Mga Setting&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Magdagdag ng pangalan</translation>
<translation id="3583757800736429874">&amp;Gawing Muli ang Paglilipat</translation>
<translation id="3586931643579894722">Magtago ng mga detalye</translation>
-<translation id="3587482841069643663">Lahat</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Maglagay ng wastong petsa ng pag-expire</translation>
<translation id="36224234498066874">Clear Browsing Data...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Impormasyon sa certificate</translation>
<translation id="3690164694835360974">Hindi ligtas ang pag-log in</translation>
<translation id="3693415264595406141">Password:</translation>
-<translation id="3696411085566228381">wala</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Naglo-load...</translation>
<translation id="3712624925041724820">Naubos na ang mga lisensya</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Suriin ang configuration ng proxy, firewall at DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Kung nauunawaan mo ang mga peligro sa iyong seguridad, maaari mong <ph name="BEGIN_LINK" />bisitahin ang hindi ligtas na site na ito<ph name="END_LINK" /> bago maalis ang mga mapanganib na program.</translation>
<translation id="3739623965217189342">Link na kinopya mo</translation>
+<translation id="3744899669254331632">Hindi mo maaaring bisitahin ang <ph name="SITE" /> sa ngayon dahil nagpadala ang website ng mga pinaghalong kredensyal na hindi maproseso ng Chromium. Karaniwang pansamantala ang mga error at pag-atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon.</translation>
+<translation id="3748148204939282805">Maaaring linlangin ka ng mga attacker sa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na gawin ang isang mapanganib na bagay tulad ng pag-install ng software o paghayag ng iyong personal na impormasyon (halimbawa, mga password, numero ng telepono, o credit card). <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Nabigo ang translation dahil sa error sa server.</translation>
<translation id="3759461132968374835">Wala kang kamakailang iniulat na mga pag-crash. Hindi lilitaw dito ang mga pag-crash na naganap kapag hindi pinagana ang pag-uulat ng pag-crash.</translation>
+<translation id="3778403066972421603">Gusto mo bang i-save ang card na ito sa iyong Google Account at sa device na ito?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Mag-e-expire sa <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Kung gumagamit ka ng proxy server...</translation>
<translation id="3828924085048779000">Hindi pinapayagan ang walang laman na passphrase.</translation>
-<translation id="3845539888601087042">Ipinapakita ang history mula sa iyong mga naka-sign in na device. <ph name="BEGIN_LINK" />Matuto nang higit pa<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Bumalik</translation>
<translation id="3858027520442213535">I-update ang petsa at oras</translation>
<translation id="3884278016824448484">Sumasalungat na tagatukoy ng device</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Ipinadala ang iyong kahilingang i-access ang site na ito kay <ph name="NAME" /></translation>
<translation id="3890664840433101773">Magdagdag ng email</translation>
<translation id="3901925938762663762">Na-expire na ang card</translation>
-<translation id="3933571093587347751">{1,plural, =1{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; tinatayang mula sa susunod na araw ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.}one{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; tinatayang mula sa # araw sa hinaharap ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.}other{Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; tinatayang mula sa # na araw sa hinaharap ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Nabigong i-load ang dokumentong PDF</translation>
+<translation id="3945915738023014686">ID ng Na-upload na Ulat ng Pag-crash <ph name="CRASH_ID" /> (ID ng Lokal na Pag-crash: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Hindi mapatunayan ng server na ito na <ph name="DOMAIN" /> ito; hindi tinutukoy ng certificate ng seguridad nito ang Mga Alternatibong Pangalan ng Subject. Maaaring dahil ito sa isang maling configuration o sa isang umaatake na humahadlang sa iyong koneksyon.</translation>
<translation id="3963721102035795474">Reader Mode</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Wala}=1{Mula sa 1 site }one{Mula sa # site }other{Mula sa # na site }}</translation>
<translation id="397105322502079400">Kinakalkula...</translation>
<translation id="3973234410852337861">Naka-block ang <ph name="HOST_NAME" /></translation>
+<translation id="3987940399970879459">Wala pang 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 web page ang malapit}one{# web page ang malapit}other{# na web page ang malapit}}</translation>
<translation id="4021036232240155012">Ang DNS ay ang serbisyo sa network na nagta-translate ng pangalan ng isang website sa Internet address nito.</translation>
<translation id="4030383055268325496">&amp;I-undo ang pagdagdag</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Nakatakda ang configuration ng proxy upang gumamit ng isang .pac script URL, hindi ng mga hindi nababagong proxy server.</translation>
<translation id="4098354747657067197">May malapit na nakakapanlinlang na site</translation>
<translation id="4103249731201008433">Di-wasto ang serial number ng device</translation>
+<translation id="410351446219883937">I-autoplay</translation>
<translation id="4103763322291513355">Bisitahin ang &lt;strong&gt;chrome://policy&lt;/strong&gt; upang makita ang listahan ng mga naka-blacklist na URL at iba pang mga patakaran na ipinapatupad ng iyong system administrator.</translation>
-<translation id="4110615724604346410">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; naglalaman ng mga error ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Palaging payagan sa site na ito</translation>
<translation id="4117700440116928470">Hindi sinusuportahan ang saklaw ng patakaran.</translation>
-<translation id="4118212371799607889">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng Chromium ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 pa}one{# pa}other{# pa}}</translation>
<translation id="4130226655945681476">Suriin ang mga cable, modem at router ng network</translation>
+<translation id="413544239732274901">Matuto pa</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Gamitin ang pangkalahatang default (Tukuyin)</translation>
+<translation id="4165986682804962316">Mga setting ng site</translation>
<translation id="4169947484918424451">Gusto mo bang i-save ng Chromium ang card na ito?</translation>
<translation id="4171400957073367226">Hindi wasto ang signature sa pag-verify</translation>
<translation id="4196861286325780578">&amp;Gawing muli ang paglilipat</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Suriin ang mga configuration ng firewall at antivirus<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{wala}=1{1 app ($1)}=2{2 app ($1, $2)}one{# app ($1, $2, $3)}other{# na app ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Mga Pag-crash</translation>
+<translation id="422022731706691852">Maaaring magtangka ang mga attacker sa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na linlangin ka sa pag-install ng mga program na magdudulot ng hindi magandang karanasan sa iyong pag-browse (halimbawa, sa pamamagitan ng pagpapalit ng homepage mo o pagpapakita ng mga karagdagang ad sa mga site na binibisita mo). <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Subukang magpatakbo ng Network Diagnostics<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Wasto</translation>
<translation id="4250431568374086873">Hindi ganap na ligtas ang iyong koneksyon sa site na ito</translation>
<translation id="4250680216510889253">Hindi</translation>
<translation id="425582637250725228">Maaaring hindi ma-save ang mga pagbabagong ginawa mo.</translation>
<translation id="4258748452823770588">Maling lagda</translation>
+<translation id="4265872034478892965">Pinayagan ng iyong administrator</translation>
<translation id="4269787794583293679">(Walang username)</translation>
<translation id="4275830172053184480">I-restart ang iyong device</translation>
<translation id="4280429058323657511">, exp <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Kamakailan lang, <ph name="BEGIN_LINK" />nakakita ng mga nakakapinsalang program<ph name="END_LINK" /> ang Google Safe Browsing sa <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Mga suhestyon ng magulang</translation>
<translation id="4304224509867189079">Mag-log In</translation>
-<translation id="432290197980158659">Nagpakita ang server ng isang certificate na hindi tumutugma sa mga inaasahang built-in. Ang mga inaasahang ito ay isinama para sa ilang partikular na website na mahigpit sa seguridad upang maprotektahan ka. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">I-block (default)</translation>
<translation id="4325863107915753736">Hindi nahanap ang artikulo</translation>
<translation id="4326324639298822553">Tingnan ang iyong petsa ng pag-expire at subukang muli</translation>
<translation id="4331708818696583467">Hindi Secure</translation>
<translation id="4356973930735388585">Maaaring subukan ng mga attacker sa site na ito na mag-install ng mga mapanganib na program sa iyong computer na magnanakaw o magde-delete ng impormasyon mo (halimbawa, mga larawan, password, mensahe at credit card).</translation>
<translation id="4372948949327679948">Inaasahang <ph name="VALUE_TYPE" /> na halaga.</translation>
+<translation id="4377125064752653719">Tinangka mong maabot ang <ph name="DOMAIN" />, subalit ang certificate na ipinakita ng server ay binawi ng nagbigay nito. Nangangahulugan ito na ang mga kredensyal sa seguridad na ipinakita ng server ay talagang hindi dapat pagkatiwalaan. Maaaring nakikipag-ugnay ka sa isang nang-aatake.</translation>
<translation id="4381091992796011497">User Name:</translation>
<translation id="4394049700291259645">Huwag paganahin</translation>
<translation id="4406896451731180161">mga resulta ng paghahanap</translation>
+<translation id="4424024547088906515">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng Chrome ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
<translation id="4432688616882109544">Hindi tinanggap ng <ph name="HOST_NAME" /> ang iyong certificate sa pag-log in o maaaring walang ibinigay.</translation>
<translation id="443673843213245140">Hindi pinagana ang paggamit ng isang proxy ngunit tinutukoy ang isang tahasang configuration ng proxy.</translation>
-<translation id="4492190037599258964">Mga resulta ng paghahanap para sa '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Error sa pagpapatunay: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Makipag-ugnayan sa admin ng system</translation>
<translation id="450710068430902550">Pagbabahagi sa Administrator</translation>
<translation id="4515275063822566619">Ang mga card at address ay mula sa Chrome at sa iyong Google Account (<ph name="ACCOUNT_EMAIL" />). Maaari mong pamahalaan ang mga ito sa <ph name="BEGIN_LINK" />Mga Setting<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Mga Detalye</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Subukang i-disable ang iyong mga extension.</translation>
<translation id="457875822857220463">Paghahatid</translation>
<translation id="4587425331216688090">Alisin ang address sa Chrome?</translation>
-<translation id="4589078953350245614">Tinangka mong makakonekta sa <ph name="DOMAIN" />, ngunit nagpakita ang server ng di-wastong certificate. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Naka-encrypt ang iyong koneksyon sa <ph name="DOMAIN" /> gamit ang isang makabagong cipher suite.</translation>
<translation id="4594403342090139922">&amp;I-undo ang Pagtanggal</translation>
<translation id="4619615317237390068">Mga tab mula sa iba pang mga device</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; naglalaman ng mga error ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
+<translation id="4690462567478992370">Ihinto ang paggamit ng di-wastong certificate</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Naputol ang iyong koneksyon</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Magpatakbo ng Windows Network Diagnostics<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Isang hindi alam na error ang nangyari.</translation>
<translation id="4800132727771399293">Tingnan ang iyong petsa ng pag-expire at CVC at subukang muli</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Hindi mo maaaring bisitahin ang <ph name="SITE" /> sa ngayon dahil nagpadala ang website ng mga gulu-gulong kredensyal na hindi maproseso ng Google Chrome. Kadalasang pansamantala lang ang mga error at atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon.</translation>
<translation id="4813512666221746211">Error sa network</translation>
<translation id="4816492930507672669">Pagkasyahin sa pahina</translation>
<translation id="483020001682031208">Walang maipakitang page ng Pisikal na Web</translation>
<translation id="4850886885716139402">View</translation>
<translation id="4854362297993841467">Hindi available ang pamamaraan ng paghahatid na ito. Sumubok ng ibang pamamaraan.</translation>
<translation id="4858792381671956233">Tinanong mo sa iyong mga magulang kung maaari mong bisitahin ang site na ito</translation>
+<translation id="4863764087567530506">Maaaring subukan kang linlangin ng content na ito na mag-install ng software o maghayag ng personal na impormasyon. <ph name="BEGIN_LINK" />Ipakita pa rin<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">History ng paghahanap</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{at 1 pang web page}one{at # pang web page}other{at # pang web page}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Na-translate ang pahinang ito mula sa hindi kilalang wika patungo sa <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pagbabayad</translation>
<translation id="4926049483395192435">Dapat na tukuyin.</translation>
<translation id="495170559598752135">Mga Pagkilos</translation>
<translation id="4958444002117714549">Palawakin ang listahan</translation>
-<translation id="4962322354953122629">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng Chrome ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Muling i-enable ang mga babala</translation>
<translation id="4989809363548539747">Hindi sinusuportahan ang plugin na ito</translation>
<translation id="5002932099480077015">Kung naka-enable, mag-iimbak ang Chrome ng kopya ng iyong card sa device na ito para sa mas mabilis na pagsagot sa form.</translation>
<translation id="5018422839182700155">Hindi mabuksan ang page na ito</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Suriin ang mga patakaran ng iyong administrator</translation>
<translation id="5029568752722684782">I-clear ang kopya</translation>
<translation id="5031870354684148875">Tungkol sa Google Translate</translation>
+<translation id="5039804452771397117">Payagan</translation>
<translation id="5040262127954254034">Privacy</translation>
<translation id="5045550434625856497">Hindi wastong password</translation>
<translation id="5056549851600133418">Mga artikulo para sa iyo</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Suriin ang proxy address<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Walang cookies}=1{1 site ang gumagamit ng cookies. }one{# site ang gumagamit ng cookies. }other{# na site ang gumagamit ng cookies. }}</translation>
<translation id="5087286274860437796">Hindi angkop ang certificate ng server sa oras na ito.</translation>
<translation id="5087580092889165836">Magdagdag ng card</translation>
<translation id="5089810972385038852">Estado</translation>
+<translation id="5094747076828555589">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng Chromium ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
<translation id="5095208057601539847">Probinsya</translation>
<translation id="5115563688576182185">(64-bit)</translation>
<translation id="5141240743006678641">I-encrypt ang mga naka-sync na password gamit ang iyong mga kredensyal sa Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Kailangan ng email</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Ginagamit mo ba ang Chrome sa trabaho? Maaaring pamahalaan ng mga negosyo ang mga setting ng Chrome para sa kanilang mga empleyado. Matuto pa</translation>
+<translation id="5297526204711817721">Hindi pribado ang iyong koneksyon sa site na ito. Upang lumabas sa VR mode anumang oras, alisin ang headset at pindutin ang bumalik.</translation>
<translation id="5299298092464848405">Error sa pag-parse ng patakaran</translation>
-<translation id="5300589172476337783">Ipakita</translation>
<translation id="5308689395849655368">Hindi pinagana ang pag-uulat ng pag-crash.</translation>
<translation id="5317780077021120954">I-save</translation>
<translation id="5327248766486351172">Pangalan</translation>
-<translation id="5337705430875057403">Maaaring subukan ng mga attacker sa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na linlangin ka sa paggawa ng bagay na mapanganib gaya ng pag-i-install ng software o pagbubunyag ng iyong personal na impormasyon (halimbawa, mga password, numero ng telepono o credit card).</translation>
-<translation id="5359637492792381994">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; walang bisa ang certificate na panseguridad nito sa ngayon. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Hindi mo maaaring bisitahin ang <ph name="SITE" /> sa ngayon dahil binawi na ang certificate nito. Karaniwang pansamantala lang ang mga error at pag-atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon.</translation>
<translation id="536296301121032821">Nabigo i-load ang mga setting ng patakaran sa store</translation>
<translation id="5386426401304769735">Naglalaman ang chain ng certificate para sa site na ito ng certificate na naka-sign gamit ang SHA-1.</translation>
<translation id="5402410679244714488">Petsa ng pag-expire: <ph name="EXPIRATION_DATE_ABBR" />, huling ginamit mahigit isang taon na ang nakalipas</translation>
+<translation id="540969355065856584">Hindi mapatunayan ng server na ito ay ang <ph name="DOMAIN" />; walang bisa ang certificate sa seguridad nito sa pagkakataong ito. Maaaring dahil ito sa isang maling pag-configure o may isang attacker na humahadlang sa iyong koneksyon.</translation>
<translation id="5421136146218899937">I-clear ang data sa pagba-browse...</translation>
<translation id="5430298929874300616">Alisin ang bookmark</translation>
<translation id="5431657950005405462">Hindi nakita ang iyong file</translation>
-<translation id="5435775191620395718">Ipinapakita ang history mula sa device na ito. <ph name="BEGIN_LINK" />Matuto nang higit pa<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Error sa pagpapatunay ng schema sa "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Hindi makita ang <ph name="HOST_NAME" /> page na ito</translation>
<translation id="5455374756549232013">Maling timestamp ng patakaran</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> ng <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Di-wasto</translation>
<translation id="5470861586879999274">&amp;Gawing muli ang pag-e-edit</translation>
<translation id="54817484435770891">Magdagdag ng wastong address</translation>
<translation id="5492298309214877701">Ang URL ng site na ito sa intranet ng kumpanya, organisasyon o paaralan ay kapareho ng URL ng isang external na website.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Hindi maaaring mag-pick up mula sa address na ito. Pumili ng ibang address.</translation>
<translation id="5572851009514199876">Magsimula at mag-sign in sa Chrome upang masuri ng Chrome kung pinapayagan kang i-access ang site na ito.</translation>
<translation id="5580958916614886209">Tingnan ang iyong buwan ng pag-expire at subukang muli</translation>
+<translation id="5586446728396275693">Walang naka-save na address</translation>
+<translation id="5595485650161345191">Mag-edit ng address</translation>
<translation id="560412284261940334">Hindi sinusuportahan ang pamamahala</translation>
<translation id="5610142619324316209">Suriin ang koneksyon</translation>
<translation id="5610807607761827392">Maaari mong pamahalaan ang mga card at address sa <ph name="BEGIN_LINK" />Mga Setting<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Gusto mo bang umalis sa site na ito?</translation>
<translation id="5629630648637658800">Nabigong i-load ang mga setting ng patakaran</translation>
<translation id="5631439013527180824">Di-wastong token sa pamamahala ng device</translation>
+<translation id="5633066919399395251">Maaaring magtangka ang mga attacker na kasalukuyang nasa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na mag-install ng mga mapanganib na program sa iyong computer na magnanakaw o magde-delete ng impormasyon mo (halimbawa, mga larawan, password, mensahe, at credit card). <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Lokasyon</translation>
+<translation id="5659593005791499971">Email</translation>
<translation id="5669703222995421982">Makakuha ng naka-personalize na content</translation>
<translation id="5675650730144413517">Hindi gumagana ang page na ito</translation>
-<translation id="5677928146339483299">Naka-block</translation>
-<translation id="5694783966845939798">Sinubukan mong makakonekta sa <ph name="DOMAIN" />, ngunit ang certificate na ipinakita ng server ay nilagdaan gamit ang mahinang signature algorithm (gaya ng SHA-1). Nangangahulugan ito na maaaring napeke ang kredensyal na panseguridad na ipinakita ng server, at maaaring ang server ay hindi ang inaasahan mong server (maaaring nakikipag-ugnayan ka sa isang attacker). <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Ang pagkilala ng website na ito ay hindi natukoy.</translation>
+<translation id="5713016350996637505">Na-block ang mapanlinlang na content</translation>
<translation id="5720705177508910913">Kasalukuyang user</translation>
<translation id="5732392974455271431">Maaari itong alisin sa pagkaka-block ng iyong mga magulang para sa iyo</translation>
<translation id="5763042198335101085">Maglagay ng wastong email address</translation>
<translation id="5765072501007116331">Upang makita ang mga pamamaraan at kinakailangan sa paghahatid, pumili ng address</translation>
+<translation id="5778550464785688721">Ganap na pagkontrol sa mga MIDI device</translation>
<translation id="5784606427469807560">Nagkaroon ng problema sa pagkumpirma ng iyong card. Suriin ang koneksyon sa internet at subukang muli.</translation>
<translation id="5785756445106461925">Bukod pa rito, ang page na ito ay may iba pang mga mapagkukunang hindi secure. Makikita ng iba ang mga mapagkukunang ito habang ipinadadala, at maaaring baguhin ng isang umaatake upang baguhin ang hitsura ng page.</translation>
<translation id="5786044859038896871">Gusto mo bang ilagay ang impormasyon ng iyong card?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Gawing Muli ang Pagdagdag</translation>
<translation id="5814352347845180253">Maaari kang mawalan ng access sa premium na content mula sa <ph name="SITE" /> at ilan pang ibang site.</translation>
<translation id="5838278095973806738">Hindi ka dapat maglagay ng anumang sensitibong impormasyon sa site na ito (halimbawa, mga password o credit card), dahil maaari itong nakawin ng mga umaatake.</translation>
-<translation id="5843436854350372569">Tinangka mong makakonekta sa <ph name="DOMAIN" />, ngunit nagpakita ang server ng certificate na naglalaman ng isang mahinang key. Maaaring sinira ng isang nang-aatake ang pribadong key, at maaaring ang server ay hindi ang inaasahan mong server (maaaring nakikipag-ugnayan ka sa isang nang-aatake). <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Hindi makakonekta sa site na ito</translation>
<translation id="5869522115854928033">Mga naka-save na password</translation>
<translation id="5872918882028971132">Mga Suhestyon ng Magulang</translation>
<translation id="5901630391730855834">Dilaw</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (naka-sync)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 ang ginagamit}one{# ang ginagamit}other{# ang ginagamit}}</translation>
<translation id="5926846154125914413">Maaari kang mawalan ng access sa premium na content mula sa ilang site.</translation>
<translation id="5959728338436674663">Awtomatikong magpadala ng ilang <ph name="BEGIN_WHITEPAPER_LINK" />impormasyon sa system at content ng page<ph name="END_WHITEPAPER_LINK" /> sa Google upang makatulong na tumukoy ng mapapanganib na app at site. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Linggo</translation>
<translation id="5967867314010545767">Alisin sa history</translation>
<translation id="5975083100439434680">Mag-zoom out</translation>
<translation id="598637245381783098">Hindi mabuksan ang app sa pagbabayad</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Page 1}one{Page #}other{Page #}}</translation>
<translation id="6017514345406065928">Berde</translation>
+<translation id="6017850046339264347">Ang mga umaatake sa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ay maaaring mag-install ng mga mapanlinlang na app na nagpapanggap na ibang bagay o nangongolekta ng data na maaaring gamitin upang subaybayan ka. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (naka-sync)</translation>
<translation id="6027201098523975773">Maglagay ng pangalan</translation>
<translation id="6040143037577758943">Isara</translation>
<translation id="6042308850641462728">Higit pa</translation>
+<translation id="6047233362582046994">Kung nauunawaan mo ang mga panganib sa iyong seguridad, maaari mong <ph name="BEGIN_LINK" />bisitahin ang site na ito<ph name="END_LINK" /> bago maalis ang mga mapaminsalang app.</translation>
+<translation id="6051221802930200923">Hindi mo maaaring bisitahin ang <ph name="SITE" /> sa ngayon dahil gumagamit ng pag-pin ng certificate ang website. Karaniwang pansamantala lang ang mga error at pag-atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon.</translation>
<translation id="6060685159320643512">Mag-ingat, maaaring makahamak ang mga eksperimentong ito</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{wala}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">Nag-access ka ng nilalaman gamit ang isang certificate na ibinigay ng administrator. Maaaring harangin ng iyong administrator ang data na ibibigay mo sa <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Wala}=1{1 password (naka-sync)}one{# password (naka-sync)}other{# na password (naka-sync)}}</translation>
<translation id="6146055958333702838">Tingnan ang anumang mga kable at i-reboot ang anumang mga router, modem o iba
pang mga network device na maaaring ginagamit mo.</translation>
<translation id="614940544461990577">Subukang:</translation>
<translation id="6151417162996330722">Masyadong mahaba ang panahon ng pagkakaroon ng bisa ng certificate ng server.</translation>
<translation id="6157877588268064908">Upang makita ang mga pamamaraan at kinakailangan sa pagpapadala, pumili ng address</translation>
+<translation id="6158003235852588289">Kamakailan lang, may nakitang phishing sa <ph name="SITE" /> ang Ligtas na Pag-browse sa Google. Nagpapanggap ang mga phishing site bilang ibang website upang linlangin ka.</translation>
<translation id="6165508094623778733">Matuto nang higit pa</translation>
+<translation id="6169916984152623906">Makakapag-browse ka na ngayon nang pribado, at hindi makikita ng ibang taong gumagamit sa device na ito ang iyong aktibidad. Gayunpaman, mase-save ang mga download at bookmark.</translation>
<translation id="6177128806592000436">Hindi ligtas ang iyong koneksyon sa site na ito</translation>
<translation id="6184817833369986695">(cohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Suriin ang iyong koneksyon sa Internet</translation>
<translation id="6218753634732582820">Gusto mo bang alisin ang address sa Chromium?</translation>
+<translation id="6221345481584921695">Kamakailan lang, ang Google Safe Browsing ay <ph name="BEGIN_LINK" />nakakita ng malware<ph name="END_LINK" /> sa <ph name="SITE" />. Paminsan-minsan, nagkakaroon ng malware ang mga website na karaniwang ligtas. Ang nakakahamak na content ay galing sa <ph name="SUBRESOURCE_HOST" />, isang kilalang nagkakalat ng malware.</translation>
<translation id="6251924700383757765">Patakaran sa privacy</translation>
<translation id="6254436959401408446">Hindi sapat ang memory upang mabuksan ang page na ito</translation>
<translation id="625755898061068298">Pinili mong i-disable ang mga panseguridad na babala para sa site na ito.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">I-edit ang bookmark</translation>
<translation id="6410264514553301377">Ilagay ang petsa ng pag-expire at CVC para sa <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Tinanong mo ang iyong magulang kung maaari mong bisitahin ang site na ito</translation>
-<translation id="6416403317709441254">Hindi mo mabibisita ang <ph name="SITE" /> sa ngayon dahil nagpadala ang website ng mga pinaghalu-halong kredensyal na hindi maproseso ng Chromium. Kadalasang pansamantala lang ang mga error at atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Hindi nagawang masuri kung nabawi na ang certificate.</translation>
<translation id="6433490469411711332">I-edit ang impormasyon sa pakikipag-ugnayan</translation>
<translation id="6433595998831338502">Tumangging kumonekta ang <ph name="HOST_NAME" />.</translation>
<translation id="6446608382365791566">Magdagdag ng higit pang impormasyon</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Muling pagsusumite ng Form sa Pagkumpirma</translation>
<translation id="6456339708790392414">Iyong Pagbabayad</translation>
<translation id="6458467102616083041">Binalewala dahil hindi pinagana ng patakaran ang default na paghahanap.</translation>
-<translation id="6462969404041126431">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; maaaring mabawi ang certificate na panseguridad nito. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Mga patakaran sa device</translation>
<translation id="6477321094435799029">May natukoy na kakaibang code ang Chrome sa page na ito at na-block ito upang protektahan ang iyong personal na impormasyon (halimbawa, mga password, numero ng telepono at credit card).</translation>
<translation id="6489534406876378309">Simulang mag-upload ng mga pag-crash</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Exp: <ph name="EXPIRATION_DATE_ABBR" />, huling ginamit noong <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Hindi pa ito inaaprubahan ng iyong manager</translation>
<translation id="6569060085658103619">Isang page ng extension ang tinitingnan mo</translation>
-<translation id="6593753688552673085">wala pang <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Maaaring subukan ng content na ito na mag-install ng mapanganib na software sa iyong device na magnanakaw o magde-delete ng impormasyon mo. <ph name="BEGIN_LINK" />Ipakita pa rin<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Mga pagpipilian sa pag-encrypt</translation>
<translation id="662080504995468778">Manatili</translation>
<translation id="6626291197371920147">Magdagdag ng wastong card number</translation>
<translation id="6628463337424475685">Paghahanap ng <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Maaaring magtangka ang mga attacker na kasalukuyang nasa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na mag-install ng mga mapanganib na program sa iyong Mac na magnanakaw o magde-delete ng impormasyon mo (halimbawa, mga larawan, password, mensahe, at credit card). <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Hindi na ginagamit ang patakarang ito.</translation>
-<translation id="6652240803263749613">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; ang certificate na panseguridad nito ay hindi pinagkakatiwalaan ng operating system ng iyong computer. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Gusto mo bang alisin ang form para sa suhestyon sa Chromium?</translation>
<translation id="6685834062052613830">Mag-sign out at kumpletuhin ang setup</translation>
<translation id="6710213216561001401">Nakaraan</translation>
<translation id="6710594484020273272">&lt;I-type ang termino para sa paghahanap&gt;</translation>
<translation id="6711464428925977395">May problema sa proxy server, o mali ang address.</translation>
<translation id="6727102863431372879">Itakda</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{wala}=1{1 item}one{# item}other{# na item}}</translation>
<translation id="674375294223700098">Hindi alam na error sa certificate ng server</translation>
<translation id="6753269504797312559">Halaga ng patakaran</translation>
<translation id="6757797048963528358">Nag-sleep ang iyong device.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Customization ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Hindi na-load ang data ng mga rehiyon</translation>
+<translation id="6825578344716086703">Tinangka mong abutin ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng certificate na nilagdaan gamit ang isang mahinang signature algorithm (tulad ng SHA-1). Nangangahulugan ito na maaaring pineke ang mga panseguridad na kredensyal na ipinakita ng server, at ang server ay maaaring hindi ang server na inaasahan mo (maaaring nakikipag-ugnayan ka sa isang attacker).</translation>
+<translation id="6830728435402077660">Hindi secure</translation>
<translation id="6831043979455480757">Isalin</translation>
<translation id="6839929833149231406">Lugar</translation>
<translation id="6874604403660855544">&amp;Gawing muli ang pagdagdag</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Nakumpirma na ang iyong card</translation>
<translation id="6897140037006041989">User Agent</translation>
<translation id="6915804003454593391">User:</translation>
+<translation id="6945221475159498467">Pumili</translation>
<translation id="6948701128805548767">Upang makita ang mga pamamaraan at kinakailangan sa pag-pick up, pumili ng address</translation>
<translation id="6957887021205513506">Lumilitaw na isang pamamalsipika ang certificate ng server.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Tinukoy ang parehong mga hindi nababagong proxy server at isang .pac script URL.</translation>
<translation id="6989763994942163495">Ipakita ang mga advanced na setting...</translation>
<translation id="7000990526846637657">Walang nakitang mga entry sa history</translation>
-<translation id="7009986207543992532">Tinangka mong makakonekta sa <ph name="DOMAIN" />, ngunit ang server ay nagpakita ng certificate na masyadong matagal ang panahon ng pagkabisa, dahilan upang hindi maging katiwa-katiwala ito. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Ang iyong Google Account ay maaaring may iba pang mga form ng history ng pagba-browse sa <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Mga Password</translation>
+<translation id="7050187094878475250">Sinubukan mong puntahan ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng certificate na masyadong mahaba ang panahon ng pagkakaroon ng bisa upang maging mapagkakatiwalaan.</translation>
+<translation id="7053983685419859001">Harangan</translation>
<translation id="7064851114919012435">Impormasyon sa pakikipag-ugnayan</translation>
<translation id="7079718277001814089">Naglalaman ng malware ang site na ito</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7088615885725309056">Mas Nauna</translation>
<translation id="7090678807593890770">Hanapin sa Google ang <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Pinayagan ng isang extension</translation>
<translation id="7119414471315195487">Isara ang iba pang tab o program</translation>
<translation id="7129409597930077180">Hindi maaaring magpadala sa address na ito. Pumili ng ibang address.</translation>
<translation id="7138472120740807366">Pamamaraan ng paghahatid</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Pinoproseso</translation>
<translation id="724691107663265825">Naglalaman ng malware ang site</translation>
<translation id="724975217298816891">Ilagay ang petsa ng expiration at CVC para sa <ph name="CREDIT_CARD" /> upang i-update ang mga detalye ng iyong card. Kapag nagkumpirma ka na, ibabahagi ang mga detalye ng iyong card sa site na ito.</translation>
-<translation id="725866823122871198">Hindi makapagtatag ng pribadong koneksyon sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras ng iyong computer (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="7260504762447901703">Bawiin ang access</translation>
<translation id="7275334191706090484">Mga Pinamamahalaang Bookmark</translation>
<translation id="7298195798382681320">Inirerekomenda</translation>
<translation id="7309308571273880165">Ulat ng pag-crash na nakuha noong <ph name="CRASH_TIME" /> (humiling ng pag-upload ang user, hindi pa naa-upload)</translation>
<translation id="7334320624316649418">&amp;Gawing muli ang pagbabago sa ayos</translation>
<translation id="733923710415886693">Ang certificate ng server ay hindi inihayag sa pamamagitan ng Transparency ng Certificate.</translation>
-<translation id="7351800657706554155">Hindi mo maaaring bisitahin ang <ph name="SITE" /> sa ngayon dahil binawi na ang certificate nito. Karaniwang pansamantala lang ang mga error at atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Command Line</translation>
<translation id="7372973238305370288">resulta ng paghahanap</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Hindi</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Kumpirmahin ang Card</translation>
-<translation id="7394102162464064926">Sigurado ka bang gusto mong tanggalin ang mga pahinang ito sa iyong kasaysayan?
-
-Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT_KEY" /> sa susunod.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Path ng Profile</translation>
<translation id="7424977062513257142">Isinasaad ng isang naka-embed na page sa webpage na ito na:</translation>
@@ -688,6 +754,7 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="7444046173054089907">Naka-block ang site na ito</translation>
<translation id="7445762425076701745">Hindi ganap na mapatunayan ang pagkakakilanlan ng server na konektado ka. Konektado ka sa server gamit ang pangalan na angkop lamang sa loob ng iyong network, na walang paraan ang panglabas na certificate authority na patunayan ang pagmamay-ari. Dahil magbibigay ang ilang kinauukulan sa certificate para sa mga pangalang ito, walang paraan upang matiyak na konektado ka sa nilayong website at hindi isang umaatake.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Matuto nang higit pa<ph name="END_LINK" /> tungkol sa problemang ito.</translation>
+<translation id="7455133967321480974">Gamitin ang pangkalahatang default (I-block)</translation>
<translation id="7460163899615895653">Lumalabas dito ang mga kamakailan mong tab mula sa iba pang mga device</translation>
<translation id="7469372306589899959">Kinukumpirma ang card</translation>
<translation id="7481312909269577407">Sumulong</translation>
@@ -695,36 +762,43 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="7508255263130623398">Walang laman ang ibinalik na device id ng patakaran o hindi ito tumutugma sa kasalukuyang device id</translation>
<translation id="7514365320538308">I-download</translation>
<translation id="7518003948725431193">Walang webpage na nahanap para sa web address:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Value</translation>
<translation id="7537536606612762813">Kinakailangan</translation>
+<translation id="7542403920425041731">Kapag nagkumpirma ka, ibabahagi ang mga detalye ng iyong card sa site na ito.</translation>
<translation id="7542995811387359312">Hindi pinagana ang awtomatikong pagpuno ng credit card dahil ang form na ito ay hindi gumagamit ng secure na koneksyon.</translation>
<translation id="7543525346216957623">Hilingin sa iyong magulang</translation>
<translation id="7549584377607005141">Kinakailangan ng webpage na ito ng data na inilagay mo dati upang maipakita nang maayos. Maipapadala mong muli ang data na ito, ngunit kapag ginawa mo iyon, mauulit ang anumang pagkilos na isinagawa dati ng pahinang ito.</translation>
<translation id="7552846755917812628">Subukan ang mga sumusunod na tip:</translation>
<translation id="7554791636758816595">Bagong Tab</translation>
+<translation id="7567204685887185387">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; maaaring mapanlokong ibinigay ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> pa}one{<ph name="CONTACT_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> pa}other{<ph name="CONTACT_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> pa}}</translation>
<translation id="7568593326407688803">Ang pahinang ito ay nasa<ph name="ORIGINAL_LANGUAGE" />Gusto mong isalin ito?</translation>
<translation id="7569952961197462199">Alisin ang credit card sa Chrome?</translation>
<translation id="7569983096843329377">Itim</translation>
<translation id="7578104083680115302">Magbayad nang mabilis sa mga site at app sa iba't ibang device gamit ang mga card na na-save mo sa Google.</translation>
<translation id="7588950540487816470">Pisikal na Web</translation>
<translation id="7592362899630581445">Lumabag ang certificate ng server sa limitasyon sa pangalan.</translation>
+<translation id="7598391785903975535">Wala pang <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Sa kasalukuyan, hindi magagawa ng <ph name="HOST_NAME" /> ang kahilingang ito.</translation>
<translation id="7600965453749440009">Huwag isalin kailanman ang <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Wala sa sakop ang halaga <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Exp: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Mayroon ka nang data na na-encrypt gamit ang ibang bersyon ng iyong password ng Google Account. Pakilagay ito sa ibaba.</translation>
-<translation id="7634554953375732414">Hindi pribado ang iyong koneksyon sa site na ito.</translation>
<translation id="7637571805876720304">Gusto mo bang alisin ang credit card sa Chromium?</translation>
<translation id="765676359832457558">Itago ang mga advanced na setting...</translation>
<translation id="7658239707568436148">Ikansela</translation>
+<translation id="7662298039739062396">Kinokontrol ng isang extension ang setting</translation>
<translation id="7667346355482952095">Walang laman ang ibinalik na token ng patakaran o hindi tumutugma sa kasalukuyang token</translation>
<translation id="7668654391829183341">Hindi kilalang device</translation>
<translation id="7669271284792375604">Maaaring subukan ng mga attacker sa site na ito na linlangin ka upang mag-install ng mga program na makakasama sa iyong karanasan sa pag-browse (halimbawa, sa pamamagitan ng pagbabago ng iyong homepage o pagpapakita ng mga karagdagang ad sa mga site na binibisita mo).</translation>
<translation id="7674629440242451245">Interesado sa mga astig at bagong tampok sa Chrome? Subukan ang aming dev channel sa chrome.com/dev.</translation>
<translation id="7682287625158474539">Pagpapadala</translation>
+<translation id="7701040980221191251">Wala</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Magpatuloy sa <ph name="SITE" /> (hindi ligtas)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificate</translation>
+<translation id="7716147886133743102">Na-block ng iyong administrator</translation>
<translation id="7716424297397655342">Hindi maaaring i-load ang site na ito mula sa cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Hindi pinamamahalaan</translation>
<translation id="7755287808199759310">Maaari itong alisin sa pagkaka-block ng iyong magulang para sa iyo</translation>
<translation id="7758069387465995638">Maaaring na-block ng firewall o antivirus software ang koneksyon.</translation>
@@ -751,15 +825,15 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Mga bookmark sa mobile</translation>
<translation id="7961015016161918242">Hindi Kailanman</translation>
-<translation id="7962083544045318153">Crash ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Palaging isalin ang <ph name="ORIGINAL_LANGUAGE" /> sa <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Hindi Tinukoy</translation>
<translation id="800218591365569300">Subukang isara ang iba pang tab o program upang magbakante ng memory.</translation>
<translation id="8012647001091218357">Hindi namin makaugnayan ang iyong mga magulang sa sandaling ito. Pakisubukang muli.</translation>
<translation id="8025119109950072390">Maaari kang linlangin ng mga attacker sa site na ito na gumawa ng mga bagay na mapanganib tulad ng pag-i-install ng software o pagbubunyag ng iyong personal na impormasyon (halimbawa, mga password, numero ng telepono o credit card).</translation>
-<translation id="803030522067524905">Kamakailan lang, nakakita ang Google Safe Browsing ng phishing sa <ph name="SITE" />. Nagpapanggap ang mga site ng phishing bilang ibang mga website upang linlangin ka. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Nasa <ph name="SOURCE_LANGUAGE" /> ang pahinang ito. Isalin ito sa <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Magtanong (default)</translation>
<translation id="8041089156583427627">Magpadala ng Feedback</translation>
+<translation id="8041940743680923270">Gamitin ang pangkalahatang default (Tanungin)</translation>
<translation id="8088680233425245692">Hindi natingnan ang artikulo.</translation>
<translation id="8089520772729574115">wala pang 1 MB</translation>
<translation id="8091372947890762290">Nakabinbin sa server ang pag-activate</translation>
@@ -768,13 +842,14 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="8134994873729925007">Hindi makita ang <ph name="BEGIN_ABBR" />DNS address<ph name="END_ABBR" /> ng server ng <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Nag-sleep ang iyong computer.</translation>
<translation id="8150722005171944719">Hindi nababasa ang file sa <ph name="URL" />. Maaaring ito ay naalis, nalipat, o maaaring pinipigilan ng mga pagpapahintulot ng file ang access.</translation>
+<translation id="8184538546369750125">Gamitin ang pangkalahatang default (Payagan)</translation>
+<translation id="8191494405820426728">ID ng Lokal na Pag-crash <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;I-undo ang Paglilipat</translation>
<translation id="8201077131113104583">Di-wastong URL ng update para sa extension na may ID na "<ph name="EXTENSION_ID" />."</translation>
<translation id="8202097416529803614">Buod ng order</translation>
<translation id="8218327578424803826">Itinakdang Lokasyon:</translation>
<translation id="8225771182978767009">Pinili ng taong nag-set up ng computer na ito na i-block ang site na ito.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Maaaring subukan ng mga attacker na kasalukuyang nasa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na mag-install ng mga mapanganib na program sa iyong computer na nagnanakaw o nagde-delete ng iyong impormasyon (halimbawa, mga larawan, password, mensahe at credit card).</translation>
<translation id="8241707690549784388">Ang pahina na hinahanap mo para sa paggamit ng impormasyon na ipinasok mo. Ang pagbalik sa pahinang iyon maaaring magsanhi ng anumang aksyon na akalo mo ay naulit. Nais mo bang ipagpatuloy?</translation>
<translation id="8249320324621329438">Huling kinuha:</translation>
<translation id="8253091569723639551">Kinakailangan ang billing address</translation>
@@ -782,6 +857,7 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="8289355894181816810">Makipag-ugnay sa administrator ng iyong network kung hindi ka sigurado kung ano ang ibig sabihin nito.</translation>
<translation id="8293206222192510085">Magdagdag ng Bookmark</translation>
<translation id="8294431847097064396">Pinagmulan</translation>
+<translation id="8306404619377842860">Hindi makakonekta nang pribado sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras (<ph name="DATE_AND_TIME" />) sa iyong device. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto pa<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Nabigo ang translation dahil sa problema sa koneksyon sa network.</translation>
<translation id="8332188693563227489">Tinanggihan ang access sa <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Kung nauunawaan mo ang mga peligro sa iyong seguridad, maaari mong <ph name="BEGIN_LINK" />bisitahin ang site na ito<ph name="END_LINK" /> bago maalis ang mga mapanirang program.</translation>
@@ -802,11 +878,9 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="8483780878231876732">Upang gumamit ng mga card mula sa iyong Google Account, mag-sign in sa Chrome</translation>
<translation id="8488350697529856933">Nalalapat sa</translation>
<translation id="8498891568109133222">Masyadong matagal bago nakatugon ang <ph name="HOST_NAME" />.</translation>
-<translation id="852346902619691059">Hindi mapatunayan ng server na ito na ito ang <ph name="DOMAIN" />; ang certificate na panseguridad nito ay hindi pinagkakatiwalaan ng operating system ng iyong device. Maaaring sanhi ito ng maling pag-configure o ng isang nang-aatake na humahadlang sa iyong koneksyon. <ph name="BEGIN_LEARN_MORE_LINK" />Matuto nang higit pa<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Taon ng Pag-expire</translation>
<translation id="8543181531796978784">Maaari kang <ph name="BEGIN_ERROR_LINK" />mag-ulat ng problema sa pagtukoy<ph name="END_ERROR_LINK" /> o, kung nauunawaan mo ang mga panganib sa iyong seguridad, <ph name="BEGIN_LINK" />bisitahin ang hindi ligtas na site na ito<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Nabigo ang pag-translate dahil hindi matukoy ang wika ng pahina.</translation>
-<translation id="8559762987265718583">Hindi makapagtatag ng pribadong koneksyon sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras ng iyong device (<ph name="DATE_AND_TIME" />).</translation>
<translation id="8571890674111243710">Tina-translate ang pahina sa <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Magdagdag ng numero ng telepono</translation>
<translation id="859285277496340001">Hindi tumutukoy ang certificate na ito ng mekanismo upang masuri kung nabawi ito.</translation>
@@ -820,6 +894,7 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="8738058698779197622">Upang makapagtatag ng secure na koneksyon, kailangang itakda nang tama ang iyong orasan. Ito ay dahil sa may-bisa lang ang mga certificate na ginagamit ng mga website upang tukuyin ang mga sarili ng mga ito sa loob ng mga partikular na tagal ng panahon. Dahil mali ang orasan ng iyong device, hindi ma-verify ng Chromium ang mga certificate na ito.</translation>
<translation id="8740359287975076522">Hindi makita ang &lt;abbr id="dnsDefinition"&gt;DNS address&lt;/abbr&gt; ng <ph name="HOST_NAME" />. Dina-diagnose ang problema.</translation>
<translation id="8759274551635299824">Nag-expire na ang card na ito</translation>
+<translation id="8761567432415473239">Ang Google Safe Browsing ay may <ph name="BEGIN_LINK" />natagpuang mga nakakasirang program<ph name="END_LINK" /> sa <ph name="SITE" /> kamakailan.</translation>
<translation id="8790007591277257123">&amp;Gawing muli ang pagtanggal</translation>
<translation id="8800988563907321413">Lalabas dito ang iyong mga suhestyon na malapit</translation>
<translation id="8820817407110198400">Mga Bookmark</translation>
@@ -832,29 +907,30 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="8870413625673593573">Recently Closed</translation>
<translation id="8874824191258364635">Maglagay ng wastong numero ng card</translation>
<translation id="8876793034577346603">Nabigong ma-parse ang configuration ng network.</translation>
-<translation id="8877192140621905067">Kapag nagkumpirma ka na, ibabahagi ang mga detalye ng iyong card sa site na ito</translation>
<translation id="8889402386540077796">Hue</translation>
<translation id="8891727572606052622">Di-wastong mode ng proxy.</translation>
<translation id="889901481107108152">Paumanhin, hindi available ang eksperimentong ito sa iyong platform.</translation>
<translation id="8903921497873541725">Mag-zoom in</translation>
<translation id="8931333241327730545">Gusto mo bang i-save ang card na ito sa iyong Google Account?</translation>
<translation id="8932102934695377596">Nahuhuli ang iyong orasan</translation>
-<translation id="8954894007019320973">(Itinuloy)</translation>
<translation id="8971063699422889582">Nag-expire na ang certificate ng server.</translation>
<translation id="8986494364107987395">Awtomatikong ipadala ang mga istatistika ng paggamit at mga ulat ng pag-crash sa Google</translation>
-<translation id="8987927404178983737">Buwan</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Ang susunod na site ay naglalaman ng mga mapanirang program</translation>
+<translation id="8997023839087525404">Nagpakita ang server ng certificate na hindi inihayag sa publiko gamit ang patakaran sa Transparency ng Certificate. Kinakailangan ito para sa ilang certificate, upang matiyak na mapagkakatiwalaan ang mga ito at maprotektahan laban sa mga umaatake.</translation>
<translation id="9001074447101275817">Nangangailangan ang proxy na <ph name="DOMAIN" /> ng username at password.</translation>
+<translation id="9005998258318286617">Hindi na-load ang PDF document.</translation>
<translation id="901974403500617787">Ang may-ari lang ang maaaring magtakda ng mga flag na nalalapat sa buong system: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Kinakailangan ang address sa pagsingil ng card</translation>
<translation id="9020542370529661692">Na-translate sa <ph name="TARGET_LANGUAGE" /> ang pahinang ito</translation>
<translation id="9035022520814077154">Error sa seguridad</translation>
<translation id="9038649477754266430">Gumamit ng serbisyo sa paghula upang ma-load ang mga page nang mas mabilis</translation>
<translation id="9039213469156557790">Bukod pa rito, ang page na ito ay may iba pang mga mapagkukunang hindi secure. Makikita ng iba ang mga mapagkukunang ito habang ipinadadala, at maaaring baguhin ng isang umaatake upang baguhin ang gawi ng page.</translation>
-<translation id="9040185888511745258">Maaaring subukan ng mga attacker sa <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> na linlangin ka upang mag-install ng mga program na nakakasira sa iyong karanasan sa pagba-browse (halimbawa, sa pamamagitan ng pagbabago ng iyong homepage o pagpapakita ng mga karagdagang ad sa mga site na iyong binibisita).</translation>
+<translation id="9049981332609050619">Tinangka mong maabot ang <ph name="DOMAIN" />, ngunit nagpakita ang server ng isang di-wastong certificate.</translation>
<translation id="9050666287014529139">Passphrase</translation>
<translation id="9065203028668620118">I-edit</translation>
<translation id="9068849894565669697">Pumili ng kulay</translation>
+<translation id="9069693763241529744">Na-block ng isang extension</translation>
<translation id="9076283476770535406">Maaaring mayroon itong mature content</translation>
<translation id="9078964945751709336">Nangangailangan ng higit pang impormasyon</translation>
<translation id="9103872766612412690">Karaniwang gumagamit ang <ph name="SITE" /> ng pag-encrypt upang protektahan ang iyong impormasyon. Noong sinubukang kumonekta ng Chromium sa <ph name="SITE" /> sa pagkakataong ito, nagbalik ang website ng mga hindi pangkaraniwan at maling kredensyal. Maaari itong mangyari kapag sinusubukan ng isang attacker na magpanggap bilang <ph name="SITE" />, o naputol ang koneksyon dahil sa isang screen ng pag-sign in sa Wi-Fi. Secure pa rin ang iyong impormasyon dahil inihinto ng Chromium ang koneksyon bago magkaroon ng palitan ng anumang data.</translation>
@@ -863,16 +939,21 @@ Psst! Maaaring maging kapaki-pakinabang ang mode na incognito <ph name="SHORTCUT
<translation id="9148507642005240123">&amp;I-undo ang pag-e-edit</translation>
<translation id="9154194610265714752">Na-update</translation>
<translation id="9157595877708044936">Nagse-set up...</translation>
+<translation id="9169664750068251925">Palaging i-block sa site na ito</translation>
<translation id="9170848237812810038">&amp;I-undo</translation>
<translation id="917450738466192189">Di-wastong certificate ng server.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> pa}one{<ph name="SHIPPING_OPTION_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> pa}other{<ph name="SHIPPING_OPTION_PREVIEW" /> at <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> pa}}</translation>
<translation id="9183425211371246419">Gumagamit ng hindi sinusuportahang protocol ang <ph name="HOST_NAME" />.</translation>
<translation id="9205078245616868884">Na-encrypt ang iyong data gamit ang iyong passphrase sa pag-sync. Ilagay ito upang simulan ang pag-sync.</translation>
<translation id="9207861905230894330">Hindi naidagdag ang artikulo.</translation>
+<translation id="9219103736887031265">Mga Larawan</translation>
<translation id="933612690413056017">Walang koneksyon sa Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CLEAR FORM</translation>
<translation id="939736085109172342">Bagong folder</translation>
<translation id="941721044073577244">Mukhang wala kang pahintulot na bisitahin ang site na ito</translation>
<translation id="969892804517981540">Official Build</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Wala}=1{1 item}one{# item}other{# na item}}</translation>
<translation id="988159990683914416">Bumuo ang Developer</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_fr.xtb b/chromium/components/strings/components_strings_fr.xtb
index e57c3240f06..a7dbc20c6ae 100644
--- a/chromium/components/strings/components_strings_fr.xtb
+++ b/chromium/components/strings/components_strings_fr.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Faire pivoter vers la droite</translation>
<translation id="1038842779957582377">Nom inconnu</translation>
<translation id="1050038467049342496">Fermez les autres applications</translation>
-<translation id="1053591932240354961">Vous ne pouvez pas consulter le site Web <ph name="SITE" /> pour le moment, car il a envoyé des identifiants brouillés qui ne peuvent être traités par Google Chrome. Les attaques et les erreurs réseau sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page ultérieurement. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;Annuler l'ajout</translation>
<translation id="10614374240317010">Jamais enregistrés</translation>
<translation id="106701514854093668">Favoris sur l'ordinateur</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cache de la règle valide.</translation>
<translation id="113188000913989374"><ph name="SITE" /> indique :</translation>
<translation id="1132774398110320017">Paramètres de saisie automatique de Chrome…</translation>
+<translation id="1150979032973867961">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par le système d'exploitation de votre ordinateur. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
+<translation id="1151972924205500581">Veuillez saisir un mot de passe</translation>
<translation id="1152921474424827756">Accédez à une <ph name="BEGIN_LINK" />copie mise en cache<ph name="END_LINK" /> de <ph name="URL" />.</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> a mis fin à la connexion de manière inattendue.</translation>
<translation id="1161325031994447685">Se reconnecter au réseau Wi-Fi</translation>
+<translation id="1165039591588034296">Erreur</translation>
<translation id="1175364870820465910">Im&amp;primer...</translation>
<translation id="1181037720776840403">Supprimer</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Signaler automatiquement<ph name="END_WHITEPAPER_LINK" /> les incidents de sécurité potentiels à Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Plus de résultats pour ce site</translation>
<translation id="1206967143813997005">Signature initiale incorrecte</translation>
<translation id="1209206284964581585">Masquer pour le moment</translation>
+<translation id="121201262018556460">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le serveur a présenté un certificat contenant une clé faible. Il est possible qu'un pirate ait compromis la clé privée. Il est donc possible que le serveur auquel vous avez accédé ne soit pas celui que vous croyez, et que vous soyez en train de communiquer avec un pirate informatique.</translation>
<translation id="1219129156119358924">Sécurité du système</translation>
<translation id="1227224963052638717">Règle inconnue</translation>
<translation id="1227633850867390598">Masquer la valeur</translation>
<translation id="1228893227497259893">Identifiant d'entité incorrect.</translation>
<translation id="1232569758102978740">Sans titre</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronisés)</translation>
<translation id="1263231323834454256">Liste de lecture</translation>
<translation id="1264126396475825575">Rapport d'erreur enregistré le <ph name="CRASH_TIME" /> (pas encore importé ou ignoré)</translation>
+<translation id="1281526147609854549">Émis par <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Contenu dangereux bloqué</translation>
<translation id="1285320974508926690">Ne jamais traduire ce site</translation>
<translation id="129553762522093515">Récemment fermés</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Essayez de supprimer les cookies.<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Votre activité <ph name="BEGIN_EMPHASIS" />peut rester visible<ph name="END_EMPHASIS" /> par :
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Les sites Web que vous consultez
+ <ph name="LIST_ITEM" />Votre employeur ou votre établissement scolaire
+ <ph name="LIST_ITEM" />Votre fournisseur d'accès à Internet
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domaine d'enregistrement :</translation>
<translation id="1340482604681802745">Adresse d'enlèvement</translation>
<translation id="1344211575059133124">Tu n'es pas autorisé à consulter ce site</translation>
<translation id="1344588688991793829">Paramètres de saisie automatique de Chromium…</translation>
+<translation id="1348198688976932919">Ce site contient des applications dangereuses</translation>
<translation id="1374468813861204354">suggestions</translation>
<translation id="1375198122581997741">À propos de la version</translation>
<translation id="1377321085342047638">Numéro de carte</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> n'a envoyé aucune donnée.</translation>
<translation id="1407135791313364759">Tout ouvrir</translation>
<translation id="1413809658975081374">Erreur liée à la confidentialité</translation>
+<translation id="14171126816530869">L'identité de <ph name="ORGANIZATION" /> situé à <ph name="LOCALITY" /> a été vérifiée par <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Oui</translation>
<translation id="1430915738399379752">Imprimer</translation>
-<translation id="1442912890475371290">Une tentative de <ph name="BEGIN_LINK" />consultation d'une page sur <ph name="DOMAIN" /><ph name="END_LINK" /> a été bloquée.</translation>
-<translation id="1491663344921578213">Vous ne pouvez pas consulter le site Web <ph name="SITE" /> pour le moment, car les certificats y sont épinglés. Les attaques et les erreurs réseau sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page ultérieurement. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> autre}one{<ph name="PAYMENT_METHOD_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> autre}other{<ph name="PAYMENT_METHOD_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> autres}}</translation>
<translation id="1506687042165942984">Afficher une copie enregistrée (non actualisée) de cette page</translation>
<translation id="1517433312004943670">Veuillez saisir le numéro de téléphone.</translation>
<translation id="1519264250979466059">Date de création</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Vous devez activer JavaScript pour utiliser cette fonctionnalité.</translation>
<translation id="1555130319947370107">Bleu</translation>
<translation id="1559528461873125649">Fichier ou répertoire inexistant</translation>
-<translation id="1559572115229829303">&lt;p&gt;Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre appareil (<ph name="DATE_AND_TIME" />) sont incorrectes.&lt;/p&gt;
-
- &lt;p&gt;Veuillez ajuster la date et l'heure dans la section &lt;strong&gt;Général&lt;/strong&gt; de l'application &lt;strong&gt;Réglages&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Une erreur s'est produite lors de l'affichage de la page Web.</translation>
<translation id="1592005682883173041">Accès aux données locales</translation>
+<translation id="1594030484168838125">Sélectionner</translation>
<translation id="161042844686301425">Cyan</translation>
+<translation id="1620510694547887537">Appareil photo</translation>
<translation id="1629803312968146339">Voulez-vous que cette carte soit enregistrée dans Chrome ?</translation>
<translation id="1639239467298939599">Chargement en cours</translation>
<translation id="1640180200866533862">Règles relatives aux utilisateurs</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Impossible d'importer la configuration du réseau : elle n'est pas valide.</translation>
<translation id="1644574205037202324">Historique</translation>
<translation id="1645368109819982629">Protocole incompatible</translation>
+<translation id="1655462015569774233">{1,plural, =1{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré hier. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page.}one{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré il y a # jour. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page.}other{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré il y a # jours. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page.}}</translation>
<translation id="1656489000284462475">Enlèvement</translation>
<translation id="1663943134801823270">Les cartes et les adresses proviennent de Chrome. Vous pouvez les gérer dans les <ph name="BEGIN_LINK" />Paramètres<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Un chiffrement est normalement utilisé sur le site <ph name="SITE" /> pour protéger vos informations. Lors de la dernière tentative de connexion de Google Chrome au site <ph name="SITE" />, des identifiants inhabituels et incorrects ont été retournés. Il est possible qu'un individu malveillant tente de se faire passer pour <ph name="SITE" /> ou qu'un écran de connexion Wi-Fi ait interrompu la connexion. Vos informations restent sécurisées, car nous avons arrêté la connexion avant l'échange des données.</translation>
-<translation id="168328519870909584">Des individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient tenter d'installer des applications dangereuses sur votre appareil afin de récupérer ou de supprimer certaines informations : photos, mots de passe, messages, numéros de carte de paiement, etc.</translation>
<translation id="168841957122794586">Le certificat du serveur contient une clé de chiffrement faible.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car la date d'émission de son certificat de sécurité est fixée à demain. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.}one{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car la date d'émission de son certificat de sécurité est ultérieure de # jour à la date du jour. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.}other{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car la date d'émission de son certificat de sécurité est ultérieure de # jours à la date du jour. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.}}</translation>
<translation id="1710259589646384581">Système d'exploitation</translation>
<translation id="1721312023322545264">Vous devez disposer de l'autorisation de <ph name="NAME" /> pour consulter ce site</translation>
<translation id="1721424275792716183">* Champ obligatoire</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Télécharger la page plus tard</translation>
<translation id="17513872634828108">Onglets ouverts</translation>
<translation id="1753706481035618306">Numéro de page</translation>
+<translation id="1763864636252898013">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par le système d'exploitation de votre appareil. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Essayez d'exécuter les diagnostics réseau de Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Mettre à jour votre phrase secrète de synchronisation</translation>
<translation id="1787142507584202372">Les onglets ouverts s'affichent ici</translation>
+<translation id="1789575671122666129">Fenêtres pop-up</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nom du titulaire de la carte</translation>
-<translation id="1803678881841855883">La navigation sécurisée de Google a récemment <ph name="BEGIN_LINK" />détecté des logiciels malveillants<ph name="END_LINK" /> sur le site <ph name="SITE" />. Un site Web qui est normalement sans danger peut parfois être infecté par des logiciels malveillants. Le contenu en cause provient de l'hôte <ph name="SUBRESOURCE_HOST" />, une source de logiciels malveillants connue. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Date d'ajout : <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">La demande ou ses paramètres ne sont pas valides.</translation>
<translation id="1826516787628120939">Vérification en cours…</translation>
<translation id="1834321415901700177">Ce site contient des programmes dangereux</translation>
+<translation id="1840414022444569775">Ce numéro de carte est déjà utilisé</translation>
<translation id="1842969606798536927">Paiement</translation>
<translation id="1871208020102129563">Le proxy est configuré pour utiliser des serveurs proxy déterminés, pas une URL de script .pac.</translation>
<translation id="1871284979644508959">Veuillez compléter ce champ.</translation>
<translation id="187918866476621466">Ouvrir les pages de démarrage</translation>
<translation id="1883255238294161206">Réduire la liste</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> autre}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> autre}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> autres}}</translation>
<translation id="1898423065542865115">Filtrage</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Aucun}=1{1 site}one{# site}other{# sites}}</translation>
<translation id="194030505837763158">Accédez à <ph name="LINK" /></translation>
<translation id="1962204205936693436">Favoris du domaine <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Erreur de sérialisation.</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorée parce que remplacée par <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Recherche de pages Web physique à proximité</translation>
<translation id="213826338245044447">Favoris sur mobile</translation>
-<translation id="2148716181193084225">Aujourd'hui</translation>
+<translation id="2147827593068025794">Synchronisation en arrière-plan</translation>
<translation id="2154054054215849342">La synchronisation n'est pas disponible pour votre domaine</translation>
<translation id="2154484045852737596">Modifier la carte</translation>
<translation id="2166049586286450108">Accès administrateur complet</translation>
<translation id="2166378884831602661">Ce site ne peut pas fournir de connexion sécurisée</translation>
<translation id="2181821976797666341">Règles</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresse}one{# adresse}other{# adresses}}</translation>
+<translation id="2187317261103489799">Détecter (par défaut)</translation>
<translation id="2202020181578195191">Saisissez une année d'expiration valide</translation>
<translation id="2212735316055980242">Règle introuvable.</translation>
<translation id="2213606439339815911">Obtention des entrées en cours…</translation>
+<translation id="2218879909401188352">Les pirates informatiques qui contrôlent le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> peuvent installer des applications dangereuses qui endommagent votre appareil, ajoutent des frais cachés à votre facture de téléphonie mobile ou dérobent vos informations personnelles. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Vérifiez la connexion à l'aide de l'<ph name="BEGIN_LINK" />application de diagnostic<ph name="END_LINK" />.</translation>
<translation id="2239100178324503013">Envoyer maintenant</translation>
<translation id="225207911366869382">Cette valeur n'est plus utilisée dans le cadre de cette règle.</translation>
<translation id="2262243747453050782">Erreur HTTP.</translation>
+<translation id="2270484714375784793">N° de téléphone</translation>
<translation id="2282872951544483773">Tests non disponibles.</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> article}one{<ph name="ITEM_COUNT" /> article}other{<ph name="ITEM_COUNT" /> articles}}</translation>
<translation id="2292556288342944218">Votre accès à Internet est bloqué</translation>
<translation id="230155334948463882">Nouvelle carte ?</translation>
-<translation id="2305919008529760154">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car il se peut que son certificat de sécurité ait été émis de manière frauduleuse. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> nécessite un nom d'utilisateur et un mot de passe.</translation>
-<translation id="2318774815570432836">Vous ne pouvez pas consulter le site Web <ph name="SITE" /> pour le moment, car la technologie HSTS y est utilisée. Les attaques et les erreurs réseau sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page ultérieurement. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Paramètre contrôlé par votre administrateur</translation>
<translation id="2354001756790975382">Autres favoris</translation>
+<translation id="2354430244986887761">La navigation sécurisée de Google a récemment <ph name="BEGIN_LINK" />détecté des applications malveillantes<ph name="END_LINK" /> sur le site <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Il se peut que des pirates informatiques puissent voir les images que vous regardez sur ce site et vous piègent en les modifiant.</translation>
+<translation id="2356070529366658676">Demander</translation>
+<translation id="2359629602545592467">Plusieurs</translation>
<translation id="2359808026110333948">Continuer</translation>
<translation id="2365563543831475020">Le rapport d'erreur enregistré le <ph name="CRASH_TIME" /> n'a pas été importé.</translation>
<translation id="2367567093518048410">Niveau</translation>
-<translation id="2371153335857947666">{1,plural, =1{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré hier. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" />}one{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré il y a # jour. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" />}other{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité a expiré il y a # jours. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. L'horloge de votre ordinateur indique actuellement : <ph name="CURRENT_DATE" />. Cela vous semble-t-il correct ? Si ce n'est pas le cas, vous devez corriger l'horloge de votre système, puis actualiser la page. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">Aucune alternative disponible pour l'interface utilisateur</translation>
<translation id="2384307209577226199">Valeur par défaut définie par l'entreprise</translation>
<translation id="2386255080630008482">Le certificat du serveur a été révoqué.</translation>
<translation id="2392959068659972793">Afficher les règles non paramétrées</translation>
<translation id="239429038616798445">Mode d'expédition non disponible. Choisissez-en un autre.</translation>
<translation id="2396249848217231973">&amp;Annuler la suppression</translation>
-<translation id="2460160116472764928">La navigation sécurisée de Google a récemment <ph name="BEGIN_LINK" />détecté des logiciels malveillants<ph name="END_LINK" /> sur le site <ph name="SITE" />. Un site Web qui est normalement sans danger peut parfois être infecté par des logiciels malveillants. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />. Il se peut que son certificat de sécurité ait été révoqué. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="2463739503403862330">Remplir</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Exécuter les diagnostics du réseau<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL de recherche incorrecte</translation>
+<translation id="2482878487686419369">Notifications</translation>
<translation id="2491120439723279231">Le certificat du serveur contient des erreurs.</translation>
<translation id="2495083838625180221">Analyse de fichiers JSON</translation>
<translation id="2495093607237746763">Si cette case est cochée, Chromium enregistre une copie de votre carte sur cet appareil pour vous permettre de remplir plus rapidement les formulaires.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Retour</translation>
<translation id="2515629240566999685">Vérifier le signal dans votre zone</translation>
<translation id="2516305470678292029">Alternatives pour l'interface utilisateur</translation>
+<translation id="2539524384386349900">Détecter</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> a envoyé une réponse incorrecte.</translation>
-<translation id="2552545117464357659">Récent</translation>
<translation id="2556876185419854533">&amp;Annuler la modification</translation>
<translation id="2587730715158995865">Proposé par <ph name="ARTICLE_PUBLISHER" />. Lisez cet article et <ph name="OTHER_ARTICLE_COUNT" /> autres.</translation>
<translation id="2587841377698384444">ID de l'API d'annuaire :</translation>
<translation id="2597378329261239068">Ce document est protégé par mot de passe. Veuillez saisir ce dernier.</translation>
<translation id="2609632851001447353">Variantes</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Aucune}=1{1 application ($1)}=2{2 applications ($1, $2)}one{# application ($1, $2 $3)}other{# applications ($1, $2 $3)}}</translation>
<translation id="2625385379895617796">Votre horloge est en avance.</translation>
<translation id="2639739919103226564">État :</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Accès au fichier refusé</translation>
<translation id="2653659639078652383">Valider</translation>
<translation id="2666117266261740852">Fermez les autres onglets ou applications</translation>
+<translation id="2670429602441959756">Cette page contient des fonctionnalités non compatibles avec la RV. Fermeture…</translation>
<translation id="2674170444375937751">Voulez-vous vraiment supprimer ces pages de votre historique ?</translation>
<translation id="2677748264148917807">Quitter</translation>
-<translation id="269990154133806163">Le certificat présenté par le serveur n'a pas été communiqué au public. Selon le règlement de transparence des certificats, certains certificats doivent obligatoirement être communiqués publiquement pour garantir qu'ils sont dignes de confiance et qu'ils protègent contre les individus malveillants. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Liste lecture</translation>
<translation id="2704283930420550640">La valeur ne respecte pas le format requis.</translation>
<translation id="2704951214193499422">Impossible de valider votre carte dans Chromium pour le moment. Veuillez réessayer plus tard.</translation>
<translation id="2705137772291741111">La copie enregistrée (en cache) de ce site est illisible.</translation>
<translation id="2709516037105925701">Saisie automatique</translation>
-<translation id="2712118517637785082">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le certificat présenté par le serveur a été révoqué par son émetteur. Cela signifie qu'il ne faut en aucun cas faire confiance aux identifiants de sécurité présentés par le serveur. Il est possible que vous communiquiez avec un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Demander l'autorisation</translation>
<translation id="2713444072780614174">Blanc</translation>
<translation id="2720342946869265578">À proximité</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Enregistrement de l'appareil manquant.</translation>
<translation id="2784949926578158345">La connexion a été réinitialisée.</translation>
<translation id="2794233252405721443">Site bloqué</translation>
+<translation id="2799020568854403057">Ce site contient des applications malveillantes</translation>
+<translation id="2803306138276472711">La fonctionnalité de navigation sécurisée Google a récemment permis de <ph name="BEGIN_LINK" />détecter des logiciels malveillants<ph name="END_LINK" /> sur le site <ph name="SITE" />. Un site Web qui est normalement sans danger peut parfois être infecté par des logiciels malveillants.</translation>
<translation id="2824775600643448204">Barre d'adresse et de recherche</translation>
<translation id="2826760142808435982">La connexion est chiffrée et authentifiée avec la clé <ph name="CIPHER" />. La méthode d'échange de clés utilisé est <ph name="KX" />.</translation>
<translation id="2835170189407361413">Effacer le formulaire</translation>
+<translation id="2856444702002559011">Des individus malveillants tentent peut-être de subtiliser vos informations personnelles sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (mots de passe, messages ou numéros de carte de crédit, par exemple). <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ne pas actualiser</translation>
<translation id="2900469785430194048">Google Chrome n'avait pas suffisamment de mémoire pour afficher cette page Web.</translation>
<translation id="2909946352844186028">Un changement de réseau a été détecté.</translation>
<translation id="2916038427272391327">Fermez les autres programmes</translation>
<translation id="2922350208395188000">Impossible de vérifier le certificat du serveur.</translation>
<translation id="2928905813689894207">Adresse de facturation</translation>
+<translation id="2941952326391522266">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité provient du domaine <ph name="DOMAIN2" />. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="2948083400971632585">Vous pouvez désactiver tout proxy configuré pour une connexion à partir de la page des paramètres.</translation>
<translation id="2955913368246107853">Fermer la barre de recherche</translation>
<translation id="2958431318199492670">La configuration du réseau ne respecte pas les normes de l'ONC. Il est possible que des parties de la configuration ne soient pas importées.</translation>
-<translation id="29611076221683977">Des individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient tenter d'installer des applications dangereuses sur votre Mac afin de récupérer ou de supprimer certaines informations : photos, mots de passe, messages, numéros de carte de paiement, etc.</translation>
<translation id="2966678944701946121">Date d'expiration : <ph name="EXPIRATION_DATE_ABBR" />, date d'ajout : <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Afin d'établir une connexion sécurisée, votre horloge doit être réglée correctement. Les certificats permettant aux sites Web de s'identifier sont en effet valides pendant une période précise. Comme l'horloge de votre appareil est incorrecte, Google Chrome n'est pas en mesure de vérifier la validité des certificats.</translation>
<translation id="2972581237482394796">&amp;Rétablir</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Saisissez une adresse valide</translation>
<translation id="2986368408720340940">Mode d'enlèvement non disponible. Choisissez-en un autre.</translation>
<translation id="2991174974383378012">Partage avec les sites Web</translation>
+<translation id="2991571918955627853">Le site <ph name="SITE" /> est actuellement inaccessible, car il utilise la technologie HSTS. Les erreurs réseau et les attaques sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page plus tard.</translation>
<translation id="3005723025932146533">Afficher la copie enregistrée</translation>
<translation id="3008447029300691911">Saisissez le code CVC de la carte <ph name="CREDIT_CARD" />. Une fois la validation terminée, les informations relatives à la carte seront partagées avec ce site.</translation>
<translation id="3010559122411665027">Entrée de la liste "<ph name="ENTRY_INDEX" />" : <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Bloquée automatiquement</translation>
<translation id="3024663005179499861">Type de règle incorrect.</translation>
<translation id="3032412215588512954">Voulez-vous actualiser ce site ?</translation>
<translation id="3037605927509011580">Aie aie aie</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{au moins 1 élément sur les appareils synchronisés}=1{1 élément (et plus sur appareils synchronisés)}one{# élément (et plus sur appareils synchronisés)}other{# éléments (et plus sur appareils synchronisés)}}</translation>
<translation id="3041612393474885105">Informations relatives au certificat</translation>
<translation id="3063697135517575841">Impossible de valider votre carte dans Chrome pour le moment. Veuillez réessayer plus tard.</translation>
<translation id="3064966200440839136">En payant via une application externe, vous allez quitter le mode navigation privée. Voulez-vous continuer ?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Aucun}=1{1 mot de passe}one{# mot de passe}other{# mots de passe}}</translation>
<translation id="3093245981617870298">Vous êtes actuellement hors connexion</translation>
<translation id="3105172416063519923">ID d'élément :</translation>
<translation id="3109728660330352905">Vous n'êtes pas autorisé à consulter cette page.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Essayez d'exécuter les diagnostics de connectivité<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Échec du décodage de la réponse.</translation>
<translation id="3150653042067488994">Erreur temporaire du serveur.</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Les pages consultées dans les onglets de navigation privée ne sont pas enregistrées dans l'historique de votre navigateur, dans les cookies ni dans l'historique des recherches une fois que vous avez fermé tous les onglets de navigation privée. Les fichiers téléchargés et les favoris ajoutés sont conservés.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ÃŽle</translation>
+<translation id="317583078218509884">Les nouveaux paramètres des autorisations de site seront appliqués lorsque vous actualiserez la page.</translation>
<translation id="3176929007561373547">Vérifiez vos paramètres de proxy ou contactez votre administrateur réseau pour
vous assurer que le serveur proxy fonctionne. Si vous
ne pensez pas devoir utiliser de serveur proxy, procédez comme suit :
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Ouvrez la page en mode navigation privée</translation>
-<translation id="3202578601642193415">Le plus récent</translation>
+<translation id="320323717674993345">Annuler le paiement</translation>
<translation id="3207960819495026254">Favori</translation>
+<translation id="3225919329040284222">Le serveur dispose d'un certificat qui ne répond pas aux exigences intégrées. Celles-ci sont incluses dans certains sites Web très sécurisés afin de vous protéger.</translation>
<translation id="3226128629678568754">Veuillez appuyer sur le bouton d'actualisation pour renvoyer les données nécessaires au chargement de la page.</translation>
+<translation id="3227137524299004712">Micro</translation>
<translation id="3228969707346345236">La traduction a échoué, car la page est déjà en <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Saisir le code CVC de la carte <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Toujours détecter du contenu important sur ce site</translation>
<translation id="3254409185687681395">Ajouter cette page aux favoris</translation>
<translation id="3270847123878663523">&amp;Annuler la réorganisation</translation>
<translation id="3282497668470633863">Ajouter le nom sur la carte</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">paramètres</translation>
<translation id="3345135638360864351">Impossible d'envoyer votre demande d'accès au site à <ph name="NAME" />. Veuillez réessayer.</translation>
<translation id="3355823806454867987">Modifier les paramètres du proxy...</translation>
+<translation id="3361596688432910856">Les informations suivantes <ph name="BEGIN_EMPHASIS" />ne seront pas enregistrées<ph name="END_EMPHASIS" /> dans Chrome :
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Votre historique de navigation
+ <ph name="LIST_ITEM" />Les cookies et les données de sites
+ <ph name="LIST_ITEM" />Les informations saisies dans les formulaires
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Erreur de l'horloge</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> autres éléments…</translation>
<translation id="337363190475750230">Révoqué</translation>
<translation id="3377188786107721145">Erreur d'analyse de la règle.</translation>
<translation id="3380365263193509176">Erreur inconnue.</translation>
<translation id="3380864720620200369">ID client :</translation>
<translation id="3391030046425686457">Adresse de livraison</translation>
<translation id="3395827396354264108">Mode d'enlèvement</translation>
-<translation id="340013220407300675">Il se peut que des pirates soient en train d'essayer de dérober vos informations sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (par exemple, des mots de passe, des messages ou des informations sur vos cartes de paiement).</translation>
<translation id="3422248202833853650">Essayez de fermer les autres programmes pour libérer de la mémoire.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> est actuellement inaccessible.</translation>
+<translation id="3427092606871434483">Autoriser (par défaut)</translation>
<translation id="3427342743765426898">&amp;Rétablir la modification</translation>
<translation id="3431636764301398940">Enregistrer cette carte sur cet appareil</translation>
<translation id="3435896845095436175">Activer</translation>
<translation id="3447661539832366887">Le propriétaire de cet appareil a désactivé le jeu avec le dinosaure.</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">Intervalle de récupération :</translation>
<translation id="3462200631372590220">Masquer les paramètres avancés</translation>
<translation id="3467763166455606212">Nom du titulaire de la carte obligatoire</translation>
<translation id="3478058380795961209">Mois d'expiration</translation>
<translation id="3479539252931486093">S'agit-il d'une erreur inattendue ? <ph name="BEGIN_LINK" />Signalez-nous ce problème.<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Pas maintenant</translation>
-<translation id="348000606199325318">Identifiant de plantage <ph name="CRASH_LOCAL_ID" /> (identifiant de serveur : <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Impossible de joindre votre parent pour le moment. Veuillez réessayer.</translation>
<translation id="3528171143076753409">Le certificat du serveur n'est pas approuvé.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Au moins 1 élément sur les appareils synchronisés}=1{1 élément (et plus sur les appareils synchronisés)}one{# élément (et plus sur les appareils synchronisés)}other{# éléments (et plus sur les appareils synchronisés)}}</translation>
<translation id="3539171420378717834">Conserver une copie de cette carte sur cet appareil</translation>
<translation id="3542684924769048008">Utiliser un mot de passe pour :</translation>
+<translation id="3545341443414427877">Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre ordinateur (<ph name="DATE_AND_TIME" />) sont incorrectes. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Chiffrer toutes les données synchronisées avec votre propre phrase secrète de synchronisation</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> autres onglets…</translation>
-<translation id="3555561725129903880">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité provient du domaine <ph name="DOMAIN2" />. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Votre responsable peut vous le débloquer</translation>
<translation id="3566021033012934673">Votre connexion n'est pas privée</translation>
+<translation id="3569145463236695319">&lt;p&gt;Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre appareil (<ph name="DATE_AND_TIME" />) sont incorrectes.&lt;/p&gt;
+
+ &lt;p&gt;Veuillez ajuster la date et l'heure dans la section &lt;strong&gt;Général&lt;/strong&gt; de l'application &lt;strong&gt;Paramètres&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Ajouter un nom</translation>
<translation id="3583757800736429874">&amp;Rétablir le déplacement</translation>
<translation id="3586931643579894722">Masquer les détails</translation>
-<translation id="3587482841069643663">Tous</translation>
<translation id="3600246354004376029">"<ph name="TITLE" />", <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Saisissez une date d'expiration valide</translation>
<translation id="36224234498066874">Effacer les données de navigation...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informations relatives au certificat</translation>
<translation id="3690164694835360974">Connexion non sécurisée</translation>
<translation id="3693415264595406141">Mot de passe :</translation>
-<translation id="3696411085566228381">aucune</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Chargement en cours...</translation>
<translation id="3712624925041724820">Licences épuisées.</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Vérifier les configurations du proxy, du pare-feu et du DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Si vous avez compris les risques auxquels vous vous exposez, vous pouvez <ph name="BEGIN_LINK" />consulter ce site dangereux<ph name="END_LINK" /> avant que les programmes malveillants n'aient été supprimés.</translation>
<translation id="3739623965217189342">Lien copié</translation>
+<translation id="3744899669254331632"><ph name="SITE" /> est actuellement inaccessible. Le site Web a envoyé des identifiants brouillés inutilisables par Chromium. Les erreurs de réseau et les attaques étant généralement temporaires, cette page devrait à nouveau fonctionner ultérieurement.</translation>
+<translation id="3748148204939282805">Des individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient vous inciter à effectuer des opérations dangereuses, telles que l'installation d'un logiciel ou la divulgation d'informations personnelles (mots de passe, numéros de téléphone ou numéros de carte de crédit, par exemple). <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Échec de la traduction en raison d'une erreur de serveur</translation>
<translation id="3759461132968374835">Aucune erreur n'a été signalée récemment. Les erreurs n'apparaissent ici que lorsque l'envoi de rapports d'erreur est activé.</translation>
+<translation id="3778403066972421603">Voulez-vous enregistrer cette carte dans votre compte Google et sur cet appareil ?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Expire en <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Si vous utilisez un serveur proxy…</translation>
<translation id="3828924085048779000">La phrase secrète est obligatoire.</translation>
-<translation id="3845539888601087042">Affichage de l'historique des appareils auxquels vous êtes connecté. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Retour</translation>
<translation id="3858027520442213535">Mettre à jour la date et l'heure</translation>
<translation id="3884278016824448484">Identifiant de l'appareil en conflit.</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Votre demande d'accès à ce site a bien été envoyée à <ph name="NAME" /></translation>
<translation id="3890664840433101773">Ajouter une adresse e-mail</translation>
<translation id="3901925938762663762">La carte a expiré.</translation>
-<translation id="3933571093587347751">{1,plural, =1{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car la date d'émission de son certificat de sécurité est fixée à demain. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" />}one{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car la date d'émission de son certificat de sécurité est ultérieure de # jour à la date du jour. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" />}other{Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car la date d'émission de son certificat de sécurité est ultérieure de # jours à la date du jour. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">Échec du chargement du document PDF</translation>
+<translation id="3945915738023014686">ID du rapport d'erreur importé : <ph name="CRASH_ID" /> (ID de plantage local : <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité ne contient pas l'extension "Subject Alternative Names" (Autres noms de l'objet). Cela peut être dû à une mauvaise configuration ou à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="3963721102035795474">Mode lecture</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Aucun}=1{De 1 site }one{De # site }other{De # sites }}</translation>
<translation id="397105322502079400">Calcul en cours…</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> est bloqué</translation>
+<translation id="3987940399970879459">Moins de 1 Mo</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 page Web à proximité}one{# page Web à proximité}other{# pages Web à proximité}}</translation>
<translation id="4021036232240155012">DNS est le service Web qui convertit les noms de sites Web en adresses Internet.</translation>
<translation id="4030383055268325496">&amp;Annuler l'ajout</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">La configuration du proxy est définie pour utiliser une URL de script .pac, et non pas des serveurs proxy déterminés.</translation>
<translation id="4098354747657067197">Le site Web que vous allez ouvrir est trompeur</translation>
<translation id="4103249731201008433">Le numéro de série de l'appareil n'est pas valide.</translation>
+<translation id="410351446219883937">Lecture automatique</translation>
<translation id="4103763322291513355">Accédez à &lt;strong&gt;chrome://policy&lt;/strong&gt; pour consulter une liste des URL ajoutées à la liste noire et des autres règles définies par votre administrateur système.</translation>
-<translation id="4110615724604346410">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité contient des erreurs. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Toujours autoriser sur ce site</translation>
<translation id="4117700440116928470">La portée de la règle n'est pas compatible.</translation>
-<translation id="4118212371799607889">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par Chromium. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 autre}one{# autre}other{# autres}}</translation>
<translation id="4130226655945681476">Vérifiez les câbles réseau, le modem et le routeur.</translation>
+<translation id="413544239732274901">En savoir plus</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Utiliser la valeur par défaut globale (Détection)</translation>
+<translation id="4165986682804962316">Paramètres du site</translation>
<translation id="4169947484918424451">Voulez-vous que cette carte soit enregistrée dans Chromium ?</translation>
<translation id="4171400957073367226">Signature de validation non valide.</translation>
<translation id="4196861286325780578">&amp;Rétablir le déplacement</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Vérifier les configurations du pare-feu et de l'antivirus<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{aucune}=1{1 application ($1)}=2{2 applications ($1, $2)}one{# application ($1, $2 $3)}other{# applications ($1, $2 $3)}}</translation>
<translation id="4220128509585149162">Plantages</translation>
+<translation id="422022731706691852">Des individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient vous inciter à installer des programmes qui nuisent à votre confort de navigation (par exemple, en changeant votre page d'accueil ou en affichant des annonces supplémentaires sur les sites que vous consultez). <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Essayez d'exécuter les diagnostics réseau<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Valide</translation>
<translation id="4250431568374086873">Votre connexion à ce site n'est pas totalement sécurisée.</translation>
<translation id="4250680216510889253">Non</translation>
<translation id="425582637250725228">Les modifications que vous avez apportées ne seront peut-être pas enregistrées.</translation>
<translation id="4258748452823770588">Signature incorrecte.</translation>
+<translation id="4265872034478892965">Autorisé par votre administrateur</translation>
<translation id="4269787794583293679">(aucun nom d'utilisateur)</translation>
<translation id="4275830172053184480">Redémarrer l'appareil</translation>
<translation id="4280429058323657511">, expiration le <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">La navigation sécurisée de Google a récemment <ph name="BEGIN_LINK" />détecté des programmes dangereux<ph name="END_LINK" /> sur le site <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">Suggestions des parents</translation>
<translation id="4304224509867189079">Se connecter</translation>
-<translation id="432290197980158659">Le serveur a présenté un certificat qui ne répond pas aux exigences intégrées. Celles-ci sont incluses dans certains sites Web très sécurisés afin de vous protéger. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Bloquer (par défaut)</translation>
<translation id="4325863107915753736">Échec de la recherche de l'article.</translation>
<translation id="4326324639298822553">Veuillez vérifier la date d'expiration, puis réessayer</translation>
<translation id="4331708818696583467">Non sécurisé</translation>
<translation id="4356973930735388585">Des individus malveillants à l'œuvre sur ce site pourraient tenter d'installer des applications dangereuses sur votre ordinateur afin de récupérer ou de supprimer certaines informations : photos, mots de passe, messages, numéros de carte de paiement, etc.</translation>
<translation id="4372948949327679948">Valeur attendue : <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le certificat présenté par le serveur a été révoqué par son émetteur. Cela signifie que le certificat présenté par le serveur ne doit pas être approuvé. Il est donc possible que vous communiquiez avec un pirate informatique.</translation>
<translation id="4381091992796011497">Nom d'utilisateur :</translation>
<translation id="4394049700291259645">Désactiver</translation>
<translation id="4406896451731180161">résultats de recherche</translation>
+<translation id="4424024547088906515">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par Chrome. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> n'a pas accepté votre certificat de connexion, ou vous ne l'avez pas fourni.</translation>
<translation id="443673843213245140">L'utilisation d'un proxy est désactivée, mais une configuration de proxy explicite est spécifiée.</translation>
-<translation id="4492190037599258964">Résultats de recherche pour "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Erreur de validation : <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4506599922270137252">Contacter l'administrateur système</translation>
<translation id="450710068430902550">Partage avec l'administrateur</translation>
<translation id="4515275063822566619">Les cartes et les adresses proviennent de Chrome et de votre compte Google (<ph name="ACCOUNT_EMAIL" />). Vous pouvez les gérer dans les <ph name="BEGIN_LINK" />Paramètres<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Détails</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Essayez de désactiver les extensions.</translation>
<translation id="457875822857220463">Livraison</translation>
<translation id="4587425331216688090">Supprimer l'adresse de Chrome ?</translation>
-<translation id="4589078953350245614">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le certificat présenté par le serveur est incorrect. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Votre connexion à <ph name="DOMAIN" /> est chiffrée à l'aide d'une méthode de chiffrement récente.</translation>
<translation id="4594403342090139922">&amp;Annuler la suppression</translation>
<translation id="4619615317237390068">Onglets d'autres appareils</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité contient des erreurs. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
+<translation id="4690462567478992370">Arrêter d'utiliser un certificat non valide</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Votre connexion a été interrompue</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Exécuter les diagnostics réseau de Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Une erreur inconnue s'est produite.</translation>
<translation id="4800132727771399293">Veuillez vérifier la date d'expiration et le code CVC, puis réessayez.</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102"><ph name="SITE" /> est actuellement inaccessible. Le site Web a envoyé des identifiants brouillés inutilisables par Google Chrome. Les erreurs de réseau et les attaques étant généralement temporaires, cette page devrait à nouveau fonctionner ultérieurement.</translation>
<translation id="4813512666221746211">Erreur réseau.</translation>
<translation id="4816492930507672669">Ajuster à la page</translation>
<translation id="483020001682031208">Aucune page Web physique à afficher</translation>
<translation id="4850886885716139402">Afficher</translation>
<translation id="4854362297993841467">Mode de livraison non disponible. Choisissez-en un autre.</translation>
<translation id="4858792381671956233">Une demande d'autorisation a été envoyée à tes parents pour la consultation de ce site</translation>
+<translation id="4863764087567530506">Ce contenu peut vous inciter à installer un logiciel ou vous soutirer des informations personnelles. <ph name="BEGIN_LINK" />Je souhaite y accéder malgré tout.<ph name="END_LINK" /></translation>
<translation id="4880827082731008257">Rechercher dans l'historique</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{et 1 autre page Web}one{et # autre page Web}other{et # autres pages Web}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Cette page rédigée dans une langue non identifiée a été traduite en <ph name="LANGUAGE_LANGUAGE" />.</translation>
<translation id="4923459931733593730">Paiement</translation>
<translation id="4926049483395192435">Doit être spécifié.</translation>
<translation id="495170559598752135">Actions</translation>
<translation id="4958444002117714549">Développer la liste</translation>
-<translation id="4962322354953122629">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par Chrome. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Réactiver les avertissements</translation>
<translation id="4989809363548539747">Ce plug-in n'est pas compatible.</translation>
<translation id="5002932099480077015">Si cette option est activée, Chrome enregistre une copie de votre carte sur cet appareil pour vous permettre de remplir plus rapidement les formulaires.</translation>
<translation id="5018422839182700155">Impossible d'ouvrir cette page</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Vérifiez les règles définies par votre administrateur</translation>
<translation id="5029568752722684782">Effacer la copie</translation>
<translation id="5031870354684148875">À propos de Google Traduction</translation>
+<translation id="5039804452771397117">Autoriser</translation>
<translation id="5040262127954254034">Confidentialité</translation>
<translation id="5045550434625856497">Mot de passe incorrect</translation>
<translation id="5056549851600133418">Articles pour vous</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Vérifier l'adresse du proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Aucun cookie}=1{Un site utilise des cookies. }one{# site utilise des cookies. }other{# sites utilisent des cookies. }}</translation>
<translation id="5087286274860437796">Le certificat actuel du serveur n'est pas valide.</translation>
<translation id="5087580092889165836">Ajouter une carte</translation>
<translation id="5089810972385038852">État</translation>
+<translation id="5094747076828555589">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par Chromium. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="5095208057601539847">Province</translation>
<translation id="5115563688576182185">(64 bits)</translation>
<translation id="5141240743006678641">Chiffrer les mots de passe synchronisés avec vos informations de connexion Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Veuillez saisir une adresse e-mail</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Vous utilisez Chrome au travail ? Les entreprises peuvent gérer les paramètres Chrome de leurs employés. En savoir plus</translation>
+<translation id="5297526204711817721">Votre connexion à ce site n'est pas privée. Pour quitter le mode Réalité virtuelle à tout moment, retirez le casque, puis appuyez sur Retour.</translation>
<translation id="5299298092464848405">Erreur d'analyse de la règle.</translation>
-<translation id="5300589172476337783">Afficher</translation>
<translation id="5308689395849655368">L'envoi de rapports d'erreur est désactivé.</translation>
<translation id="5317780077021120954">Enregistrer</translation>
<translation id="5327248766486351172">Nom</translation>
-<translation id="5337705430875057403">Les individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient tenter de vous inciter à effectuer des opérations dangereuses, telles que l'installation d'un logiciel ou la révélation d'informations personnelles (par exemple des mots de passe, des numéros de téléphone ou des numéros de carte de paiement).</translation>
-<translation id="5359637492792381994">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité actuel n'est pas valide. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">Le site <ph name="SITE" /> est actuellement inaccessible, car son certificat a été révoqué. Les erreurs réseau et les attaques sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page plus tard.</translation>
<translation id="536296301121032821">Échec du stockage des paramètres de la règle.</translation>
<translation id="5386426401304769735">La chaîne de certificats de ce site contient un certificat signé avec SHA-1.</translation>
<translation id="5402410679244714488">Date d'expiration : <ph name="EXPIRATION_DATE_ABBR" />, dernière utilisation il y a plus d'un an</translation>
+<translation id="540969355065856584">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité actuel n'est pas valide. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
<translation id="5421136146218899937">Effacer les données de navigation...</translation>
<translation id="5430298929874300616">Supprimer le favori</translation>
<translation id="5431657950005405462">Votre fichier est introuvable</translation>
-<translation id="5435775191620395718">Affichage de l'historique de cet appareil. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Erreur de validation du schéma au niveau de "<ph name="ERROR_PATH" />" : <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Cette page du site <ph name="HOST_NAME" /> est introuvable</translation>
<translation id="5455374756549232013">Horodatage de la règle incorrect.</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> sur <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Non valide</translation>
<translation id="5470861586879999274">&amp;Rétablir la modification</translation>
<translation id="54817484435770891">Ajouter une adresse valide</translation>
<translation id="5492298309214877701">Ce site situé sur l'intranet de l'entreprise, de l'organisation ou de l'établissement scolaire possède la même URL qu'un site Web externe.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Enlèvement impossible à cette adresse. Sélectionnez-en une autre.</translation>
<translation id="5572851009514199876">Veuillez démarrer Chrome et vous connecter à votre compte pour que le navigateur puisse vérifier que vous êtes autorisé à accéder à ce site.</translation>
<translation id="5580958916614886209">Veuillez vérifier le mois d'expiration, puis réessayer</translation>
+<translation id="5586446728396275693">Aucune adresse enregistrée</translation>
+<translation id="5595485650161345191">Modifier l'adresse</translation>
<translation id="560412284261940334">Gestion non acceptée.</translation>
<translation id="5610142619324316209">Vérifier la connexion</translation>
<translation id="5610807607761827392">Vous pouvez gérer les cartes et les adresses dans les <ph name="BEGIN_LINK" />paramètres<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Voulez-vous quitter ce site ?</translation>
<translation id="5629630648637658800">Échec du chargement des paramètres de la règle.</translation>
<translation id="5631439013527180824">Jeton de gestion de l'appareil non valide.</translation>
+<translation id="5633066919399395251">Des individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient tenter d'installer des programmes dangereux sur votre ordinateur afin de récupérer ou de supprimer certaines informations (photos, mots de passe, messages ou numéros de carte de crédit, par exemple). <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Localisation</translation>
+<translation id="5659593005791499971">E-mail</translation>
<translation id="5669703222995421982">Obtenir une recommandation de contenu personnalisé</translation>
<translation id="5675650730144413517">Cette page ne fonctionne pas</translation>
-<translation id="5677928146339483299">Bloqué</translation>
-<translation id="5694783966845939798">Vous avez essayé d'accéder à <ph name="DOMAIN" />, mais le serveur a présenté un certificat signé avec un algorithme de signature faible (tel que SHA-1). Il se peut que les identifiants de sécurité présentés par le serveur aient été falsifiés. Le serveur n'est peut-être pas celui auquel vous souhaitez accéder (il peut s'agir d'une tentative de piratage). <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">L'identité de ce site Web n'a pas été vérifiée.</translation>
+<translation id="5713016350996637505">Contenu trompeur bloqué</translation>
<translation id="5720705177508910913">Utilisateur actuel</translation>
<translation id="5732392974455271431">Tes parents peuvent te le débloquer</translation>
<translation id="5763042198335101085">Saisissez une adresse e-mail valide</translation>
<translation id="5765072501007116331">Sélectionnez une adresse pour consulter les modes et conditions de livraison disponibles</translation>
+<translation id="5778550464785688721">Contrôle total des appareils MIDI</translation>
<translation id="5784606427469807560">Un problème est survenu lors de la validation de votre carte. Vérifiez votre connexion Internet, puis réessayez.</translation>
<translation id="5785756445106461925">De plus, cette page inclut d'autres ressources qui ne sont pas sécurisées. Ces ressources peuvent être consultées par des tiers pendant leur transfert, et modifiées par un pirate informatique dans le but de changer l'aspect de cette page.</translation>
<translation id="5786044859038896871">Souhaitez-vous indiquer vos informations de carte de paiement ?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Rétablir l'ajout</translation>
<translation id="5814352347845180253">Vous risquez de ne plus avoir accès au contenu premium de <ph name="SITE" /> et de certains autres sites.</translation>
<translation id="5838278095973806738">Vous ne devriez pas saisir d'informations sensibles sur ce site (par exemple, vos mots de passe ou les informations de votre carte de paiement), car elles risquent d'être dérobées par des pirates informatiques.</translation>
-<translation id="5843436854350372569">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le serveur a présenté un certificat contenant une clé faible. Il est possible qu'un pirate informatique ait compromis la clé privée, que le serveur auquel vous avez accédé ne soit pas celui que vous croyez et que vous soyez en train de communiquer avec un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">Ce site est inaccessible</translation>
<translation id="5869522115854928033">Mots de passe enregistrés</translation>
<translation id="5872918882028971132">Suggestions des parents</translation>
<translation id="5901630391730855834">Jaune</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synchronisés)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 en cours d'utilisation}one{# en cours d'utilisation}other{# en cours d'utilisation}}</translation>
<translation id="5926846154125914413">Vous risquez de ne plus avoir accès au contenu premium de certains sites.</translation>
<translation id="5959728338436674663">Envoyer automatiquement <ph name="BEGIN_WHITEPAPER_LINK" />des informations système et du contenu de page<ph name="END_WHITEPAPER_LINK" /> à Google afin de faciliter la détection d'applications et de sites dangereux. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Semaine</translation>
<translation id="5967867314010545767">Supprimer de l'historique</translation>
<translation id="5975083100439434680">Zoom arrière</translation>
<translation id="598637245381783098">Impossible d'ouvrir l'application de paiement</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Page 1}one{Page #}other{Page #}}</translation>
<translation id="6017514345406065928">Vert</translation>
+<translation id="6017850046339264347">Les pirates informatiques qui contrôlent le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> peuvent installer des applications trompeuses se faisant passer pour d'autres, ou collecter des données afin de vous surveiller. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synchronisés)</translation>
<translation id="6027201098523975773">Saisissez un nom</translation>
<translation id="6040143037577758943">Fermer</translation>
<translation id="6042308850641462728">Plus</translation>
+<translation id="6047233362582046994">Si vous êtes conscient des risques auxquels vous vous exposez, vous pouvez <ph name="BEGIN_LINK" />consulter ce site<ph name="END_LINK" /> avant que les applications dangereuses aient été supprimées.</translation>
+<translation id="6051221802930200923">Le site <ph name="SITE" /> est actuellement inaccessible, car il utilise l'épinglage des certificats. Les erreurs réseau et les attaques sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page plus tard.</translation>
<translation id="6060685159320643512">Attention, ces fonctionnalités expérimentales peuvent mordre.</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{aucun}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">Vous avez accédé à du contenu à l'aide d'un certificat fourni par l'administrateur. Les données que vous fournissez à <ph name="DOMAIN" /> peuvent être interceptées par votre administrateur.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Aucun}=1{1 mot de passe (synchronisé)}one{# mot de passe (synchronisé)}other{# mots de passe (synchronisés)}}</translation>
<translation id="6146055958333702838">Vérifiez les câbles et redémarrez votre routeur, votre modem
ou tout autre périphérique réseau utilisé.</translation>
<translation id="614940544461990577">Essayez les suggestions ci-dessous :</translation>
<translation id="6151417162996330722">La durée de validité du certificat du serveur est trop longue.</translation>
<translation id="6157877588268064908">Sélectionnez une adresse pour consulter les modes et conditions d'expédition disponibles</translation>
+<translation id="6158003235852588289">La fonctionnalité de navigation sécurisée Google a récemment permis de détecter une tentative d'hameçonnage sur le site <ph name="SITE" />. Un site d'hameçonnage se présente comme un site légitime dans le but de vous tromper.</translation>
<translation id="6165508094623778733">En savoir plus</translation>
+<translation id="6169916984152623906">Vous pouvez désormais naviguer de façon privée. Les autres utilisateurs de cet appareil ne verront pas votre activité. Les téléchargements et les favoris seront cependant enregistrés.</translation>
<translation id="6177128806592000436">Votre connexion à ce site n'est pas sécurisée.</translation>
<translation id="6184817833369986695">(cohorte : <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Vérifiez votre connexion Internet</translation>
<translation id="6218753634732582820">Supprimer l'adresse de Chromium ?</translation>
+<translation id="6221345481584921695">La fonctionnalité de navigation sécurisée Google a récemment permis de <ph name="BEGIN_LINK" />détecter des logiciels malveillants<ph name="END_LINK" /> sur le site <ph name="SITE" />. Un site Web qui est normalement sans danger peut parfois être infecté par des logiciels malveillants. Le contenu en cause provient de l'hôte "<ph name="SUBRESOURCE_HOST" />", une source de logiciels malveillants connue.</translation>
<translation id="6251924700383757765">Règles de confidentialité</translation>
<translation id="6254436959401408446">Mémoire insuffisante pour ouvrir cette page</translation>
<translation id="625755898061068298">Vous avez choisi de désactiver les avertissements de sécurité pour ce site.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Modifier le favori</translation>
<translation id="6410264514553301377">Saisissez la date d'expiration et le code CVC pour <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Une demande d'autorisation a été envoyée à tes parents pour la consultation de ce site</translation>
-<translation id="6416403317709441254">Vous ne pouvez pas consulter le site Web <ph name="SITE" /> pour le moment, car il a envoyé des identifiants brouillés qui ne peuvent être traités par Chromium. Les attaques et les erreurs réseau sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page ultérieurement. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">Impossible de vérifier si le certificat a été révoqué.</translation>
<translation id="6433490469411711332">Modifier les coordonnées</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> n'autorise pas la connexion.</translation>
<translation id="6446608382365791566">Ajouter d'autres informations</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmer le nouvel envoi du formulaire</translation>
<translation id="6456339708790392414">Votre paiement</translation>
<translation id="6458467102616083041">Ignoré parce que la recherche par défaut est désactivée par une règle.</translation>
-<translation id="6462969404041126431">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car il se peut que son certificat de sécurité ait été révoqué. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Règles relatives aux appareils</translation>
<translation id="6477321094435799029">Chrome a détecté un code inhabituel sur cette page et a bloqué cette dernière pour protéger vos informations personnelles (mots de passe, numéros de téléphone et de cartes de paiement).</translation>
<translation id="6489534406876378309">Lancer l'importation des plantages</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Date d'expiration : <ph name="EXPIRATION_DATE_ABBR" />, dernière utilisation : <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Votre responsable ne l'a pas encore autorisé</translation>
<translation id="6569060085658103619">Vous consultez actuellement une page d'extension</translation>
-<translation id="6593753688552673085">moins de <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Ce contenu peut essayer d'installer un logiciel dangereux sur votre appareil pour dérober ou supprimer vos informations. <ph name="BEGIN_LINK" />Je souhaite y accéder malgré tout.<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">Options de chiffrement</translation>
<translation id="662080504995468778">Rester</translation>
<translation id="6626291197371920147">Ajouter un numéro de carte valide</translation>
<translation id="6628463337424475685">Recherche <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Des individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient tenter d'installer des programmes dangereux sur votre Mac afin de récupérer ou de supprimer certaines informations (photos, mots de passe, messages ou numéros de carte de crédit, par exemple). <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Cette règle est obsolète.</translation>
-<translation id="6652240803263749613">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par le système d'exploitation de votre ordinateur. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Supprimer la suggestion de saisie de formulaire de Chromium ?</translation>
<translation id="6685834062052613830">Déconnectez-vous et complétez la configuration.</translation>
<translation id="6710213216561001401">Précédent</translation>
<translation id="6710594484020273272">&lt;Saisissez le terme de recherche&gt;</translation>
<translation id="6711464428925977395">Le serveur proxy présente une erreur, ou l'adresse est incorrecte.</translation>
<translation id="6727102863431372879">Définir</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{aucun}=1{1 élément}one{# élément}other{# éléments}}</translation>
<translation id="674375294223700098">Erreur inconnue liée au certificat du serveur.</translation>
<translation id="6753269504797312559">Valeur de la règle</translation>
<translation id="6757797048963528358">Votre appareil s'est mis en veille.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ID de la personnalisation</translation>
<translation id="6820686453637990663">Cryptogramme</translation>
<translation id="6824266427216888781">Échec du chargement des données relatives aux régions</translation>
+<translation id="6825578344716086703">Vous avez tenté d'accéder à <ph name="DOMAIN" />, mais le serveur a présenté un certificat signé à l'aide d'un algorithme de signature faible (par exemple, SHA-1). Il est possible que le certificat fourni par le serveur ait été falsifié. Il se peut donc que le serveur ne soit pas celui auquel vous souhaitez accéder, et qu'il s'agisse d'une tentative de piratage.</translation>
+<translation id="6830728435402077660">Non sécurisé</translation>
<translation id="6831043979455480757">Traduire</translation>
<translation id="6839929833149231406">Région</translation>
<translation id="6874604403660855544">&amp;Rétablir l'ajout</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Carte validée</translation>
<translation id="6897140037006041989">Agent utilisateur</translation>
<translation id="6915804003454593391">Utilisateur :</translation>
+<translation id="6945221475159498467">Sélectionner</translation>
<translation id="6948701128805548767">Sélectionnez une adresse pour consulter les modes et conditions d'enlèvement disponibles</translation>
<translation id="6957887021205513506">Le certificat du serveur semble être contrefait.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Les serveurs proxy déterminés et une URL de script .pac sont spécifiés tous les deux.</translation>
<translation id="6989763994942163495">Afficher les paramètres avancés…</translation>
<translation id="7000990526846637657">Aucune entrée d'historique trouvée</translation>
-<translation id="7009986207543992532">Vous avez essayé d'accéder à <ph name="DOMAIN" />, mais la durée de validité du certificat du serveur est trop longue pour être fiable. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Votre compte Google conserve peut-être d'autres formes d'historique de navigation sur la page <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />.</translation>
<translation id="7029809446516969842">Mots de passe</translation>
+<translation id="7050187094878475250">Vous avez essayé d'accéder à <ph name="DOMAIN" />, mais la durée de validité du certificat du serveur est trop longue pour être fiable.</translation>
+<translation id="7053983685419859001">Bloquer</translation>
<translation id="7064851114919012435">Coordonnées</translation>
<translation id="7079718277001814089">Ce site contient des logiciels malveillants</translation>
<translation id="7087282848513945231">Comté</translation>
-<translation id="7088615885725309056">Ancien</translation>
<translation id="7090678807593890770">Effectuez une recherche Google sur <ph name="LINK" />.</translation>
+<translation id="7108819624672055576">Autorisé par une extension</translation>
<translation id="7119414471315195487">Fermez les autres onglets ou programmes</translation>
<translation id="7129409597930077180">Impossible d'expédier à cette adresse. Sélectionnez-en une autre.</translation>
<translation id="7138472120740807366">Mode de livraison</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Traitement en cours</translation>
<translation id="724691107663265825">Le site que vous allez ouvrir contient des logiciels malveillants</translation>
<translation id="724975217298816891">Saisissez la date d'expiration et le code CVC de la carte <ph name="CREDIT_CARD" /> pour mettre à jour les informations relatives à celle-ci. Une fois la validation effectuée, les informations seront partagées avec ce site.</translation>
-<translation id="725866823122871198">Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre ordinateur (<ph name="DATE_AND_TIME" />) sont incorrectes.</translation>
+<translation id="7260504762447901703">Révoquer l'accès</translation>
<translation id="7275334191706090484">Favoris gérés</translation>
<translation id="7298195798382681320">Recommandé</translation>
<translation id="7309308571273880165">Rapport d'erreur enregistré le <ph name="CRASH_TIME" /> (importation demandée par l'utilisateur, mais non effectuée)</translation>
<translation id="7334320624316649418">&amp;Rétablir la réorganisation</translation>
<translation id="733923710415886693">Le certificat du serveur n'a pas été communiqué tel que le prévoient les règles de transparence des certificats.</translation>
-<translation id="7351800657706554155">Vous ne pouvez pas consulter le site <ph name="SITE" /> pour le moment, car le certificat correspondant a été révoqué. Les attaques et les erreurs réseau sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page plus tard. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">Ligne de commande</translation>
<translation id="7372973238305370288">résultat de recherche</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Non</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Valider la carte</translation>
-<translation id="7394102162464064926">Voulez-vous vraiment supprimer ces pages de votre historique ?
-
-Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous être utile la prochaine fois.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Chemin d'accès au profil</translation>
<translation id="7424977062513257142">Une page intégrée à cette page Web indique :</translation>
@@ -688,6 +754,7 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="7444046173054089907">Ce site est bloqué</translation>
<translation id="7445762425076701745">Impossible de valider entièrement l'identité du serveur auquel vous êtes connecté. Le nom utilisé pour cette connexion n'est valide que sur votre réseau et aucune autorité de certification externe ne peut en vérifier la propriété. Certaines autorités de certification délivrent tout de même des certificats pour ces types de nom, par conséquent nous ne sommes pas en mesure de vérifier que vous êtes connecté au site voulu et non à un site malveillant.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /> sur ce problème.</translation>
+<translation id="7455133967321480974">Utiliser le paramètre global par défaut ("Bloquer")</translation>
<translation id="7460163899615895653">Les onglets que vous avez utilisés récemment sur d'autres appareils s'affichent ici</translation>
<translation id="7469372306589899959">Validation de la carte…</translation>
<translation id="7481312909269577407">Avancer</translation>
@@ -695,36 +762,43 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="7508255263130623398">L'ID d'appareil de la règle renvoyé est vide ou ne correspond pas à l'ID d'appareil actuel.</translation>
<translation id="7514365320538308">Télécharger</translation>
<translation id="7518003948725431193">Aucune page Web trouvée à l'adresse :<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valeur</translation>
<translation id="7537536606612762813">Obligatoire</translation>
+<translation id="7542403920425041731">Une fois la validation terminée, les informations relatives à votre carte seront partagées avec ce site.</translation>
<translation id="7542995811387359312">La saisie automatique des numéros de carte de paiement est désactivée, car la connexion utilisée par ce formulaire n'est pas sécurisée.</translation>
<translation id="7543525346216957623">Demande à tes parents</translation>
<translation id="7549584377607005141">Pour s'afficher correctement, cette page Web a besoin des données que vous avez saisies précédemment. Vous pouvez envoyer de nouveau ces données. Cependant, en procédant ainsi, vous répéterez toute action déjà effectuée sur cette page.</translation>
<translation id="7552846755917812628">Essayez les astuces suivantes :</translation>
<translation id="7554791636758816595">Nouvel onglet</translation>
+<translation id="7567204685887185387">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />. Il se peut que son certificat de sécurité ait été émis de manière frauduleuse. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> autre}one{<ph name="CONTACT_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> autre}other{<ph name="CONTACT_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> autres}}</translation>
<translation id="7568593326407688803">Cette page est en<ph name="ORIGINAL_LANGUAGE" />Voulez-vous la traduire ?</translation>
<translation id="7569952961197462199">Supprimer les données de carte de paiement de Chrome ?</translation>
<translation id="7569983096843329377">Noir</translation>
<translation id="7578104083680115302">Payez rapidement sur des sites et dans des applications sur tous vos appareils au moyen de cartes que vous avez enregistrées sur Google.</translation>
<translation id="7588950540487816470">Web physique</translation>
<translation id="7592362899630581445">Le certificat du serveur ne respecte pas les restrictions de noms.</translation>
+<translation id="7598391785903975535">Moins de <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Impossible de traiter cette demande via <ph name="HOST_NAME" /> à l'heure actuelle.</translation>
<translation id="7600965453749440009">Ne jamais traduire les pages rédigées en <ph name="LANGUAGE" /> </translation>
<translation id="7610193165460212391">La valeur <ph name="VALUE" /> est hors limites.</translation>
<translation id="7613889955535752492">Date d'expiration : <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Vous disposez déjà de données chiffrées à l'aide d'une autre version de votre mot de passe de compte Google. Veuillez saisir celui-ci ci-dessous.</translation>
-<translation id="7634554953375732414">Votre connexion à ce site n'est pas privée.</translation>
<translation id="7637571805876720304">Supprimer les données de carte de paiement de Chromium ?</translation>
<translation id="765676359832457558">Masquer les paramètres avancés…</translation>
<translation id="7658239707568436148">Annuler</translation>
+<translation id="7662298039739062396">Paramètre contrôlé par une extension</translation>
<translation id="7667346355482952095">Le jeton de règle renvoyé est vide ou ne correspond pas au jeton actuel.</translation>
<translation id="7668654391829183341">Appareil inconnu</translation>
<translation id="7669271284792375604">Des individus malveillants à l'œuvre sur ce site pourraient vous inciter à installer des programmes qui nuisent à votre confort de navigation (par exemple, en changeant votre page d'accueil ou en affichant des annonces supplémentaires sur les sites que vous consultez.</translation>
<translation id="7674629440242451245">Vous souhaitez bénéficier de nouvelles fonctionnalités Chrome passionnantes ? Essayez notre version en développement à l'adresse chrome.com/dev.</translation>
<translation id="7682287625158474539">Adresse de livraison</translation>
+<translation id="7701040980221191251">Aucun</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Continuer vers le site <ph name="SITE" /> (dangereux)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificat</translation>
+<translation id="7716147886133743102">Bloqué par votre administrateur</translation>
<translation id="7716424297397655342">Impossible de charger ce site à partir du cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Non géré</translation>
<translation id="7755287808199759310">Ton parent peut te le débloquer</translation>
<translation id="7758069387465995638">Il est possible qu'un pare-feu ou un logiciel antivirus ait bloqué la connexion.</translation>
@@ -751,15 +825,15 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="7951415247503192394">(32 bits)</translation>
<translation id="7956713633345437162">Favoris sur mobile</translation>
<translation id="7961015016161918242">Jamais</translation>
-<translation id="7962083544045318153">Identifiant de plantage <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Toujours traduire en <ph name="TARGET_LANGUAGE" /> les pages en <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7995512525968007366">Non spécifié</translation>
<translation id="800218591365569300">Essayez de fermer les autres onglets ou programmes pour libérer de la mémoire.</translation>
<translation id="8012647001091218357">Impossible de joindre vos parents pour le moment. Veuillez réessayer.</translation>
<translation id="8025119109950072390">Des individus malveillants à l'œuvre sur ce site pourraient vous inciter à effectuer des opérations dangereuses, telles que l'installation d'un logiciel ou la révélation d'informations personnelles (par exemple des mots de passe, des numéros de téléphone ou des numéros de carte de paiement).</translation>
-<translation id="803030522067524905">La navigation sécurisée de Google a récemment détecté de l'hameçonnage sur le site <ph name="SITE" />. Les sites d'hameçonnage se font passer pour d'autres sites Web pour vous tromper. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Cette page est rédigée en <ph name="SOURCE_LANGUAGE" />. Voulez-vous la traduire en <ph name="TARGET_LANGUAGE" /> ?</translation>
+<translation id="8037357227543935929">Demander (par défaut)</translation>
<translation id="8041089156583427627">Envoyer</translation>
+<translation id="8041940743680923270">Utiliser le paramètre global par défaut ("Demander")</translation>
<translation id="8088680233425245692">Échec de l'affichage de l'article.</translation>
<translation id="8089520772729574115">moins de 1 Mo</translation>
<translation id="8091372947890762290">Activation en attente sur le serveur.</translation>
@@ -768,13 +842,14 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="8134994873729925007">Impossible de trouver l'<ph name="BEGIN_ABBR" />adresse DNS<ph name="END_ABBR" /> du serveur <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Votre ordinateur s'est mis en veille.</translation>
<translation id="8150722005171944719">Le fichier disponible à l'adresse <ph name="URL" /> n'est pas lisible. Il est possible qu'il ait été supprimé ou déplacé, ou que les autorisations associées empêchent d'y accéder.</translation>
+<translation id="8184538546369750125">Utiliser le paramètre global par défaut ("Autoriser")</translation>
+<translation id="8191494405820426728">ID de plantage local : <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Annuler le déplacement</translation>
<translation id="8201077131113104583">URL de mise à jour non valide pour l'extension associée à l'identifiant "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Récapitulatif de la commande</translation>
<translation id="8218327578424803826">Position attribuée :</translation>
<translation id="8225771182978767009">La personne qui a configuré cet ordinateur a choisi de bloquer ce site.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Des individus malveillants à l'œuvre sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient tenter d'installer des applications dangereuses sur votre ordinateur afin de récupérer ou de supprimer certaines informations : photos, mots de passe, messages, numéros de carte de paiement, etc.</translation>
<translation id="8241707690549784388">La page que vous recherchez a utilisé des informations que vous avez envoyées. Si vous revenez sur cette page, chaque action précédemment effectuée sera répétée. Souhaitez-vous continuer ?</translation>
<translation id="8249320324621329438">Dernière récupération :</translation>
<translation id="8253091569723639551">Adresse de facturation obligatoire</translation>
@@ -782,6 +857,7 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="8289355894181816810">Contactez votre administrateur réseau si vous n'êtes pas sûr de vous.</translation>
<translation id="8293206222192510085">Ajouter aux favoris</translation>
<translation id="8294431847097064396">Source</translation>
+<translation id="8306404619377842860">Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre appareil (<ph name="DATE_AND_TIME" />) sont incorrectes. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Échec de la traduction en raison d'un problème de connexion réseau</translation>
<translation id="8332188693563227489">L'accès à <ph name="HOST_NAME" /> a été refusé</translation>
<translation id="834457929814110454">Si vous êtes conscient des risques auxquels vous vous exposez, vous pouvez <ph name="BEGIN_LINK" />consulter ce site<ph name="END_LINK" /> avant que les programmes dangereux aient été supprimés.</translation>
@@ -802,11 +878,9 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="8483780878231876732">Pour utiliser les cartes de votre compte Google, connectez-vous à Chrome.</translation>
<translation id="8488350697529856933">S'applique à</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> a mis trop de temps à répondre.</translation>
-<translation id="852346902619691059">Impossible de vérifier que ce serveur est bien <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par le système d'exploitation de votre appareil. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique. <ph name="BEGIN_LEARN_MORE_LINK" />En savoir plus<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Année d'expiration</translation>
<translation id="8543181531796978784">Vous pouvez <ph name="BEGIN_ERROR_LINK" />signaler un problème de détection<ph name="END_ERROR_LINK" />. Si vous avez compris les risques auxquels vous vous exposez, vous pouvez <ph name="BEGIN_LINK" />consulter ce site dangereux<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">La traduction a échoué, car nous n'avons pas pu déterminer la langue de la page.</translation>
-<translation id="8559762987265718583">Impossible d'établir une connexion privée à <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> : la date et l'heure de votre appareil (<ph name="DATE_AND_TIME" />) sont incorrectes.</translation>
<translation id="8571890674111243710">Traduction de la page en <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Saisir num tél</translation>
<translation id="859285277496340001">Le certificat n'indique aucun mécanisme permettant de vérifier s'il a été révoqué.</translation>
@@ -820,6 +894,7 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="8738058698779197622">Afin d'établir une connexion sécurisée, votre horloge doit être réglée correctement. Les certificats permettant aux sites Web de s'identifier sont en effet valides pendant une période précise. Si l'horloge de votre appareil est incorrecte, Chromium n'est pas en mesure de vérifier la validité des certificats.</translation>
<translation id="8740359287975076522">L'&lt;abbr id="dnsDefinition"&gt;adresse DNS&lt;/abbr&gt; de <ph name="HOST_NAME" /> est introuvable. Identification du problème…</translation>
<translation id="8759274551635299824">Carte arrivée à expiration</translation>
+<translation id="8761567432415473239">La fonctionnalité de navigation sécurisée a récemment permis de <ph name="BEGIN_LINK" />détecter des programmes dangereux<ph name="END_LINK" /> sur le site <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Rétablir la suppression</translation>
<translation id="8800988563907321413">Vos suggestions à proximité s'affichent ici</translation>
<translation id="8820817407110198400">Favoris</translation>
@@ -832,29 +907,30 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="8870413625673593573">Récemment fermés</translation>
<translation id="8874824191258364635">Saisissez un numéro de carte valide</translation>
<translation id="8876793034577346603">Échec de l'analyse de la configuration du réseau.</translation>
-<translation id="8877192140621905067">Une fois la validation terminée, les informations relatives à votre carte seront partagées avec ce site.</translation>
<translation id="8889402386540077796">Teinte</translation>
<translation id="8891727572606052622">Mode proxy non valide.</translation>
<translation id="889901481107108152">Désolé, cette fonctionnalité expérimentale n'est pas disponible pour votre plate-forme.</translation>
<translation id="8903921497873541725">Zoom avant</translation>
<translation id="8931333241327730545">Voulez-vous enregistrer cette carte dans votre compte Google ?</translation>
<translation id="8932102934695377596">Votre horloge est en retard</translation>
-<translation id="8954894007019320973">(suite)</translation>
<translation id="8971063699422889582">Le certificat du serveur a expiré.</translation>
<translation id="8986494364107987395">Envoyer automatiquement les statistiques d'utilisation et les rapports d'erreur à Google</translation>
-<translation id="8987927404178983737">Mois</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Le site Web que vous allez ouvrir contient des programmes dangereux</translation>
+<translation id="8997023839087525404">Le certificat présenté par le serveur n'a pas été communiqué au public. Selon les règles de transparence des certificats, certains certificats doivent obligatoirement être communiqués publiquement pour garantir qu'ils sont dignes de confiance et qu'ils protègent contre les individus malveillants.</translation>
<translation id="9001074447101275817">Le proxy <ph name="DOMAIN" /> nécessite un nom d'utilisateur et un mot de passe.</translation>
+<translation id="9005998258318286617">Échec de chargement du document PDF.</translation>
<translation id="901974403500617787">Seul le propriétaire suivant peut définir les options qui s'appliquent à tout le système : <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Adresse de facturation de la carte obligatoire</translation>
<translation id="9020542370529661692">Cette page a été traduite en <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="9035022520814077154">Erreur liée à la sécurité</translation>
<translation id="9038649477754266430">Utiliser un service de prédiction pour charger les pages plus rapidement</translation>
<translation id="9039213469156557790">De plus, cette page inclut d'autres ressources qui ne sont pas sécurisées. Ces ressources peuvent être consultées par des tiers pendant leur transfert, et modifiées par un pirate informatique dans le but de changer le comportement de cette page.</translation>
-<translation id="9040185888511745258">Des pirates informatiques sur le site <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pourraient vous inciter à installer des programmes qui nuisent à votre confort de navigation (par exemple, en changeant votre page d'accueil ou en affichant des annonces supplémentaires sur les sites que vous consultez).</translation>
+<translation id="9049981332609050619">Vous avez tenté de contacter <ph name="DOMAIN" />, mais le certificat présenté par le serveur est incorrect.</translation>
<translation id="9050666287014529139">Phrase secrète</translation>
<translation id="9065203028668620118">Modifier</translation>
<translation id="9068849894565669697">Sélectionner couleur</translation>
+<translation id="9069693763241529744">Bloqué par une extension</translation>
<translation id="9076283476770535406">Il est possible qu'il comporte du contenu réservé aux adultes</translation>
<translation id="9078964945751709336">Veuillez fournir d'autres informations</translation>
<translation id="9103872766612412690">Un chiffrement est normalement utilisé sur le site <ph name="SITE" /> pour protéger vos informations. Lors de la dernière tentative de connexion de Chromium au site <ph name="SITE" />, des identifiants inhabituels et incorrects ont été retournés. Il est possible qu'un individu malveillant tente de se faire passer pour <ph name="SITE" /> ou qu'un écran de connexion Wi-Fi ait interrompu la connexion. Vos informations restent sécurisées, car nous avons arrêté la connexion avant l'échange des données.</translation>
@@ -863,16 +939,21 @@ Conseil : Le mode navigation privée (<ph name="SHORTCUT_KEY" />) pourra vous Ã
<translation id="9148507642005240123">&amp;Annuler la modification</translation>
<translation id="9154194610265714752">Mis à jour</translation>
<translation id="9157595877708044936">Configuration en cours...</translation>
+<translation id="9169664750068251925">Toujours bloquer sur ce site</translation>
<translation id="9170848237812810038">Ann&amp;uler</translation>
<translation id="917450738466192189">Le certificat du serveur n'est pas valide.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> autre}one{<ph name="SHIPPING_OPTION_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> autre}other{<ph name="SHIPPING_OPTION_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> autres}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> utilise un protocole incompatible.</translation>
<translation id="9205078245616868884">Vos données sont chiffrées avec votre phrase secrète de synchronisation. Saisissez-la pour lancer la synchronisation.</translation>
<translation id="9207861905230894330">Échec de l'ajout de l'article.</translation>
+<translation id="9219103736887031265">Images</translation>
<translation id="933612690413056017">Aucune connexion Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">EFFACER LE FORMULAIRE</translation>
<translation id="939736085109172342">Nouveau dossier</translation>
<translation id="941721044073577244">Vous n'êtes pas autorisé à consulter ce site</translation>
<translation id="969892804517981540">Build officiel</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Aucun}=1{1 élément}one{# élément}other{# éléments}}</translation>
<translation id="988159990683914416">Build de développement</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_gu.xtb b/chromium/components/strings/components_strings_gu.xtb
index c2942fce11b..9b2a35ffb39 100644
--- a/chromium/components/strings/components_strings_gu.xtb
+++ b/chromium/components/strings/components_strings_gu.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">ઘડિયાળની દિશામાં ફેરવો</translation>
<translation id="1038842779957582377">અજà«àªžàª¾àª¤ નામ</translation>
<translation id="1050038467049342496">અનà«àª¯ àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ બંધ કરો</translation>
-<translation id="1053591932240354961">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" /> ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે વેબસાઇટે સમજાય નહીં તેવા ઓળખપતà«àª° મોકલà«àª¯àª¾àª‚ છે જેની પર Google Chrome પà«àª°àª•à«àª°àª¿àª¯àª¾ કરી શકતà«àª‚ નથી. નેટવરà«àª• ભૂલો અને હà«àª®àª²àª¾ સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ છે, તેથી આ પૃષà«àª  સંભવિત રૂપે પછીથી કારà«àª¯ કરશે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;ઉમેરવà«àª‚ પૂરà«àªµàªµàª¤à« કરો</translation>
<translation id="10614374240317010">કà«àª¯àª¾àª°à«‡àª¯ ન સચવાયેલà«àª‚</translation>
<translation id="106701514854093668">ડેસà«àª•àªŸà«‰àªª બà«àª•àª®àª¾àª°à«àª•à«àª¸</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">નીતિ કેશ ઓકે</translation>
<translation id="113188000913989374"><ph name="SITE" /> આ કહે છે:</translation>
<translation id="1132774398110320017">Chrome સà«àªµàª¤àªƒàª­àª°àª£ સેટિંગà«àª¸...</translation>
+<translation id="1150979032973867961">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઑપરેટિંગ સિસà«àªŸàª® દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
+<translation id="1151972924205500581">પાસવરà«àª¡ આવશà«àª¯àª• છે</translation>
<translation id="1152921474424827756"><ph name="URL" /> ની <ph name="BEGIN_LINK" />કેશ કરેલ કૉપિ<ph name="END_LINK" /> àªàª•à«àª¸à«‡àª¸ કરો</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ઠઅનપેકà«àª·àª¿àª¤ રીતે કનેકà«àª¶àª¨ બંધ કરà«àª¯à«àª‚.</translation>
<translation id="1161325031994447685">Wi-Fi સાથે ફરીથી કનેકà«àªŸ કરીને</translation>
+<translation id="1165039591588034296">ભૂલ</translation>
<translation id="1175364870820465910">&amp;છાપો...</translation>
<translation id="1181037720776840403">દૂર કરો</translation>
<translation id="1184214524891303587">Google ને સંભવિત સà«àª°àª•à«àª·àª¾ ઘટનાઓની વિગતોની <ph name="BEGIN_WHITEPAPER_LINK" />આપમેળે જાણ કરો<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">આ સાઇટથી વધà«</translation>
<translation id="1206967143813997005">ખોટી નાની સહી</translation>
<translation id="1209206284964581585">હમણાં માટે છà«àªªàª¾àªµà«‹</translation>
+<translation id="121201262018556460">તમે <ph name="DOMAIN" /> સà«àª§à«€ પહોંચવાનો પà«àª°àª¯àª¾àª¸ કરà«àª¯à«‹, પણ પà«àª°àª®àª¾àª£àªªàª¤à«àª° રજૂ કરતા સરà«àªµàª° પાસે નબળી કી છે. હà«àª®àª²àª¾àª–ોરે ખાનગી કી તોડી હોઈ શકે છે, અને બને કે સરà«àªµàª° તમારà«àª‚ અપેકà«àª·àª¿àª¤ સરà«àªµàª° ન હોય (તમે કોઈ હà«àª®àª²àª¾àª–ોર સાથે વારà«àª¤àª¾àª²àª¾àªª કરી રહà«àª¯àª¾àª‚ હોઈ શકો છો).</translation>
<translation id="1219129156119358924">સિસà«àªŸàª® સà«àª°àª•à«àª·àª¾</translation>
<translation id="1227224963052638717">અજà«àªžàª¾àª¤ નીતિ.</translation>
<translation id="1227633850867390598">મૂલà«àª¯ છà«àªªàª¾àªµà«‹</translation>
<translation id="1228893227497259893">ખોટો અસà«àª¤àª¿àª¤à«àªµ ઓળખકરà«àª¤àª¾</translation>
<translation id="1232569758102978740">શીરà«àª·àª• વિનાનà«àª‚</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (સમનà«àªµàª¯àª¿àª¤)</translation>
<translation id="1263231323834454256">વાચન સૂચિ</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" /> ઠકà«àª°à«‡àª¶ રિપોરà«àªŸ કૅપà«àªšàª° કરવામાં આવી (હજી સà«àª§à«€ અપલોડ કરવામાં કે અવગણવામાં આવેલ નથી)</translation>
+<translation id="1281526147609854549"><ph name="ISSUER" /> દà«àªµàª¾àª°àª¾ જારી કરાયેલ</translation>
+<translation id="1283919782143846010">જોખમકારક કનà«àªŸà«‡àª¨à«àªŸ અવરોધિત કરà«àª¯à«àª‚</translation>
<translation id="1285320974508926690">આ સાઇટનà«àª‚ કà«àª¯àª¾àª°à«‡àª¯ ભાષાંતર કરશો નહીં</translation>
<translation id="129553762522093515">તાજેતરમાં બંધ કરેલા</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />તમારી કૂકીàªàª¨à«‡ સાફ કરવાનો પà«àª°àª¯àª¾àª¸ કરો<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">તમારી પà«àª°àªµà«ƒàª¤à«àª¤àª¿ <ph name="BEGIN_EMPHASIS" />હજીપણ દૃશà«àª¯àª•à«àª·àª® હોઈ શકે છે<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />વેબસાઇટો જેની તમે મà«àª²àª¾àª•àª¾àª¤ લેતા હો
+ <ph name="LIST_ITEM" />તમારા નિયોકà«àª¤àª¾ અથવા તમારી નિશાળ
+ <ph name="LIST_ITEM" />તમારા ઇનà«àªŸàª°àª¨à«‡àªŸ સેવા પà«àª°àª¦àª¾àª¤àª¾
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">નોંધણી ડોમેન:</translation>
<translation id="1340482604681802745">પિકઅપ માટેનà«àª‚ સરનામà«àª‚</translation>
<translation id="1344211575059133124">àªàªµà«àª‚ લાગે છે કે આ સાઇટની મà«àª²àª¾àª•àª¾àª¤ લેવા માટે તમને પરવાનગીની જરૂર છે</translation>
<translation id="1344588688991793829">Chromium સà«àªµàª¤àªƒàª­àª°àª£ સેટિંગà«àª¸...</translation>
+<translation id="1348198688976932919">સાઇટમાં આગળ જોખમકારક àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ છે</translation>
<translation id="1374468813861204354">સૂચનો</translation>
<translation id="1375198122581997741">વરà«àªàª¨ વિશે</translation>
<translation id="1377321085342047638">કારà«àª¡ નંબર</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ઠકોઈપણ ડેટા મોકલà«àª¯à«‹ ન હતો.</translation>
<translation id="1407135791313364759">બધà«àª‚ ખોલો</translation>
<translation id="1413809658975081374">ગોપનીયતા ભૂલ</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" /> માં <ph name="ORGANIZATION" /> ની ઓળખાણ <ph name="ISSUER" /> દà«àªµàª¾àª°àª¾ ચકાસવામાં આવી છે.</translation>
<translation id="1426410128494586442">હા</translation>
<translation id="1430915738399379752">છાપો</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> પર પૃષà«àª àª¨à«€ મà«àª²àª¾àª•àª¾àª¤ લેવા<ph name="END_LINK" /> માટેનો પà«àª°àª¯àª¤à«àª¨ અવરોધિત કરà«àª¯à«‹.</translation>
-<translation id="1491663344921578213">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" /> ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે વેબસાઇટ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પિનિંગનો ઉપયોગ કરે છે. નેટવરà«àª• ભૂલો અને હà«àª®àª²àª¾ સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ છે, તેથી આ પૃષà«àª  સંભવિત રૂપે પછીથી કારà«àª¯ કરશે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> વધà«}one{<ph name="PAYMENT_METHOD_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> વધà«}other{<ph name="PAYMENT_METHOD_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> વધà«}}</translation>
<translation id="1506687042165942984">આ પૃષà«àª àª¨à«€ સાચવેલી (àªàªŸàª²à«‡ કે જૂની થઈ ગયેલી તરીકે ઓળખાતી) કૉપિ દરà«àª¶àª¾àªµà«‹.</translation>
<translation id="1517433312004943670">ફોન નંબર આવશà«àª¯àª•</translation>
<translation id="1519264250979466059">નિરà«àª®àª¾àª£ તારીખ</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">આ સà«àªµàª¿àª§àª¾àª¨à«‹ ઉપયોગ કરવા માટે JavaScript સકà«àª·àª® કરેલ હોવી આવશà«àª¯àª• છે.</translation>
<translation id="1555130319947370107">વાદળી</translation>
<translation id="1559528461873125649">આવી કોઈ ફાઇલ અથવા નિરà«àª¦à«‡àª¶àª¿àª•àª¾ નથી</translation>
-<translation id="1559572115229829303">&lt;p&gt;<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> પર ખાનગી કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરી શકાતà«àª‚ નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) અયોગà«àª¯ છે.&lt;/p&gt;
-
- &lt;p&gt;કૃપા કરીને &lt;strong&gt;સેટિંગà«àª¸&lt;/strong&gt; અâ€à«…પà«àª²àª¿àª•à«‡àª¶àª¨àª¨àª¾ &lt;strong&gt;સામાનà«àª¯&lt;/strong&gt; વિભાગમાં તારીખ અને સમય સમાયોજિત કરો.&lt;/p&gt;</translation>
<translation id="1583429793053364125">આ વેબપૃષà«àª  પà«àª°àª¦àª°à«àª¶àª¿àª¤ કરતી વખતે કંઇક ખોટà«àª‚ થયà«àª‚.</translation>
<translation id="1592005682883173041">સà«àª¥àª¾àª¨àª¿àª• ડેટા àªàª•à«àª¸à«‡àª¸</translation>
+<translation id="1594030484168838125">પસંદ કરો</translation>
<translation id="161042844686301425">સà«àª¯àª¾àª¨</translation>
+<translation id="1620510694547887537">કૅમેરો</translation>
<translation id="1629803312968146339">શà«àª‚ તમે ઇચà«àª›à«‹ છો કે Chrome આ કારà«àª¡ સાચવે?</translation>
<translation id="1639239467298939599">લોડ કરી રહà«àª¯à«àª‚ છે</translation>
<translation id="1640180200866533862">વપરાશકરà«àª¤àª¾ નીતિઓ</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">નેટવરà«àª• ગોઠવણી અમાનà«àª¯ છે અને આયાત કરી શકાઇ નથી.</translation>
<translation id="1644574205037202324">ઇતિહાસ</translation>
<translation id="1645368109819982629">અસમરà«àª¥àª¿àª¤ પà«àª°à«‹àªŸà«‹àª•à«‹àª²</translation>
+<translation id="1655462015569774233">{1,plural, =1{આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«€ સમય સીમા ગઈકાલે સમાપà«àª¤ થઈ ગઈ. આ કોઇ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઇ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે. તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઘડિયાળને હાલમાં <ph name="CURRENT_DATE" /> પર સેટ કરવામાં આવી છે. શà«àª‚ તે બરાબર લાગે છે? જો ઠીક ન લાગતી હોય, તો તમારે તમારી સિસà«àªŸàª®àª¨à«€ ઘડિયાળને ઠીક કરવી જોઈઠઅને પછી આ પૃષà«àª  તાજà«àª‚ કરવà«àª‚ જોઈàª.}one{આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«€ સમય સીમા # દિવસ પહેલાં સમાપà«àª¤ થઈ ગઈ. આ કોઇ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઇ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે. તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઘડિયાળને હાલમાં <ph name="CURRENT_DATE" /> પર સેટ કરવામાં આવી છે. શà«àª‚ તે બરાબર લાગે છે? જો ઠીક ન લાગતી હોય, તો તમારે તમારી સિસà«àªŸàª®àª¨à«€ ઘડિયાળને ઠીક કરવી જોઈઠઅને પછી આ પૃષà«àª  તાજà«àª‚ કરવà«àª‚ જોઈàª.}other{આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«€ સમય સીમા # દિવસ પહેલાં સમાપà«àª¤ થઈ ગઈ. આ કોઇ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઇ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે. તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઘડિયાળને હાલમાં <ph name="CURRENT_DATE" /> પર સેટ કરવામાં આવી છે. શà«àª‚ તે બરાબર લાગે છે? જો ઠીક ન લાગતી હોય, તો તમારે તમારી સિસà«àªŸàª®àª¨à«€ ઘડિયાળને ઠીક કરવી જોઈઠઅને પછી આ પૃષà«àª  તાજà«àª‚ કરવà«àª‚ જોઈàª.}}</translation>
<translation id="1656489000284462475">પિકઅપ</translation>
<translation id="1663943134801823270">કારà«àª¡ અને સરનામા Chromeમાંથી છે. તમે તેને <ph name="BEGIN_LINK" />સેટિંગà«àª¸<ph name="END_LINK" />માં સંચાલિત કરી શકો છો.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> સામાનà«àª¯ રીતે તમારી માહિતીને સà«àª°àª•à«àª·àª¿àª¤ રાખવા માટે àªàª¨à«àª•à«àª°àª¿àªªà«àª¶àª¨àª¨à«‹ ઉપયોગ કરે છે. જà«àª¯àª¾àª°à«‡ આ સમયે Google Chrome દà«àªµàª¾àª°àª¾ <ph name="SITE" /> થી કનેકà«àªŸ કરવાનો પà«àª°àª¯àª¾àª¸ થયો, તà«àª¯àª¾àª°à«‡ વેબસાઇટે અસામાનà«àª¯ અને ખોટા ઓળખાણપતà«àª°à«‹àª¨à«‡ પાછા મોકલà«àª¯àª¾àª‚. આવà«àª‚ તà«àª¯àª¾àª°à«‡ થઇ શકે જà«àª¯àª¾àª°à«‡ કોઈ હà«àª®àª²àª¾àª–ોર <ph name="SITE" /> હોવાનો ડોળ કરવાનો પà«àª°àª¯àª¾àª¸ કરી રહà«àª¯à«‹ હોય અથવા કોઈ Wi-Fi સાઇન-ઇન સà«àª•à«àª°à«€àª¨à«‡ કનેકà«àª¶àª¨àª®àª¾àª‚ વિકà«àª·à«‡àªª પાડà«àª¯à«‹ હોય. તમારી માહિતી હજી પણ સà«àª°àª•à«àª·àª¿àª¤ છે કારણ કે Google Chrome ઠકોઈપણ ડેટા વિનિમય થાય તે પહેલાં જ કનેકà«àª¶àª¨ રોકી દીધà«àª‚.</translation>
-<translation id="168328519870909584"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પરનાં હà«àª®àª²àª¾àª–ોરો તમારા ઉપકરણ પર તમારી માહિતી (ઉદાહરણ તરીકે, ફોટા, પાસવરà«àª¡à«àª¸, સંદેશા અને કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸) ચોરી અથવા કાઢી નાખી શકે તેવી જોખમકારક àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ ઇનà«àª¸à«àªŸà«‹àª² કરવાનો પà«àª°àª¯àª¤à«àª¨ કરી શકે.</translation>
<translation id="168841957122794586">સરà«àªµàª° પà«àª°àª®àª¾àª£àªªàª¤à«àª° àªàª• નબળી કà«àª°àª¿àªªà«àªŸà«‹àª—à«àª°àª¾àª«àª¿àª• કી ધરાવે છે.</translation>
+<translation id="1706954506755087368">{1,plural, =1{આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° આવતીકાલથી માનવામાં આવે છે તે પà«àª°àª®àª¾àª£à«‡ છે. આ કોઇ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઇ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.}one{આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° માનવામાં આવે છે તે પà«àª°àª®àª¾àª£à«‡ ભવિષà«àª¯àª®àª¾àª‚ # દિવસથી છે. આ કોઇ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઇ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.}other{આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° માનવામાં આવે છે તે પà«àª°àª®àª¾àª£à«‡ ભવિષà«àª¯àª®àª¾àª‚ # દિવસથી છે. આ કોઇ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઇ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">આ સાઇટની મà«àª²àª¾àª•àª¾àª¤ લેવા માટે તમને <ph name="NAME" /> ની પરવાનગીની જરૂર છે</translation>
<translation id="1721424275792716183">* ફીલà«àª¡ આવશà«àª¯àª• છે</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">પૃષà«àª àª¨à«‡ પછીથી ડાઉનલોડ કરો</translation>
<translation id="17513872634828108">ટેબà«àª¸ ખોલો</translation>
<translation id="1753706481035618306">પૃષà«àª  નંબર</translation>
+<translation id="1763864636252898013">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° તમારા ઉપકરણની ઑપરેટિંગ સિસà«àªŸàª® દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows નેટવરà«àª• ડાયગà«àª¨à«‹àª¸à«àªŸàª¿àª•à«àª¸ ચલાવવાનો પà«àª°àª¯àª¾àª¸ કરો<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">કૃપા કરી તમારા સમનà«àªµàª¯àª¨ પાસફà«àª°à«‡àªàª¨à«‡ અપડેટ કરો.</translation>
<translation id="1787142507584202372">તમારા ખà«àª²à«àª²àª¾ ટૅબà«àª¸ અહીં દેખાય છે</translation>
+<translation id="1789575671122666129">પૉપઅપà«àª¸</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">કારà«àª¡àª§àª¾àª°àª•àª¨à«àª‚ નામ</translation>
-<translation id="1803678881841855883">Google સલામત બà«àª°àª¾àª‰àªàª¿àª‚ગને <ph name="SITE" /> પર <ph name="BEGIN_LINK" />માલવેર મળà«àª¯à«àª‚<ph name="END_LINK" />. વેબસાઇટà«àª¸ કે જે સામાનà«àª¯ રીતે સà«àª°àª•à«àª·àª¿àª¤ હોય છે તે કà«àª¯àª¾àª°à«‡àª• માલવેરથી દૂષિત હોય છે. દà«àª°à«àª­àª¾àªµàª¨àª¾àªªà«‚રà«àª£ સામગà«àª°à«€, <ph name="SUBRESOURCE_HOST" />, àªàª• જાણીતા માલવેર વિકà«àª°à«‡àª¤àª¾àª¥à«€ આવે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440"><ph name="ADDED_TO_AUTOFILL_MONTH" /> ના રોજ ઉમેરà«àª¯à«àª‚</translation>
<translation id="1821930232296380041">અમાનà«àª¯ વિનંતી અથવા વિનંતી પરિમાણો</translation>
<translation id="1826516787628120939">તપાસી રહà«àª¯àª¾àª‚ છે</translation>
<translation id="1834321415901700177">આ સાઇટમાં હાનિકારક પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ છે</translation>
+<translation id="1840414022444569775">આ કારà«àª¡ નંબર પહેલેથી જ વપરાયેલ છે</translation>
<translation id="1842969606798536927">ચà«àª•àªµàª£à«€ કરો</translation>
<translation id="1871208020102129563">પà«àª°à«‹àª•à«àª¸à«€ નિયત કરેલા પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª°àª¨à«‹ ઉપયોગ કરવા માટે સેટ કરેલી છે, .pac સà«àª•à«àª°àª¿àªªà«àªŸ URL નથી.</translation>
<translation id="1871284979644508959">આવશà«àª¯àª• ફીલà«àª¡</translation>
<translation id="187918866476621466">સà«àªŸàª¾àª°à«àªŸàª…પ પૃષà«àª à«‹ ખોલો</translation>
<translation id="1883255238294161206">સૂચિ સંકà«àªšàª¿àª¤ કરો</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> વધà«}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> વધà«}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> વધà«}}</translation>
<translation id="1898423065542865115">ફિલà«àªŸàª°àª¿àª‚ગ</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{કોઈ નહીં}=1{1 સાઇટ}one{# સાઇટ}other{# સાઇટ}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> પર જાઓ</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> બà«àª•àª®àª¾àª°à«àª•à«àª¸</translation>
<translation id="1973335181906896915">અનà«àª•à«àª°àª®àª¾àª‚કન ભૂલ</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">અવગણà«àª¯à«àª‚ કારણ કે તે <ph name="POLICY_NAME" /> દà«àªµàª¾àª°àª¾ ઓવરરાઇડ થયà«àª‚ હતà«àª‚.</translation>
<translation id="2138201775715568214">નજીકના વાસà«àª¤àªµàª¿àª• વેબ પૃષà«àª à«‹àª¨à«‡ શોધી રહà«àª¯àª¾àª‚ છો</translation>
<translation id="213826338245044447">મોબાઇલ બà«àª•àª®àª¾àª°à«àª•à«àª¸</translation>
-<translation id="2148716181193084225">આજે</translation>
+<translation id="2147827593068025794">પૃષà«àª àª­à«‚મિ સમનà«àªµàª¯àª¨</translation>
<translation id="2154054054215849342">સમનà«àªµàª¯àª¨ તમારા ડોમેન માટે ઉપલબà«àª§ નથી.</translation>
<translation id="2154484045852737596">કારà«àª¡ સંપાદિત કરો</translation>
<translation id="2166049586286450108">સંપૂરà«àª£ વà«àª¯àªµàª¸à«àª¥àª¾àªªàª• àªàª•à«àª¸à«‡àª¸</translation>
<translation id="2166378884831602661">આ સાઇટ àªàª• સà«àª°àª•à«àª·àª¿àª¤ કનેકà«àª¶àª¨ આપી શકતી નથી</translation>
<translation id="2181821976797666341">નીતિઓ</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 સરનામà«àª‚}one{# સરનામાં}other{# સરનામાં}}</translation>
+<translation id="2187317261103489799">શોધો (ડિફૉલà«àªŸ)</translation>
<translation id="2202020181578195191">àªàª• માનà«àª¯ સમાપà«àª¤àª¿ વરà«àª· દાખલ કરો</translation>
<translation id="2212735316055980242">નીતિ મળી નથી</translation>
<translation id="2213606439339815911">પà«àª°àªµàª¿àª·à«àªŸàª¿àª“નà«àª‚ આનયન કરી રહà«àª¯àª¾àª‚ છે...</translation>
+<translation id="2218879909401188352">હાલમાં હà«àª®àª²àª¾àª–ોરો <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પર જોખમકારક àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ઇનà«àª¸à«àªŸà«‰àª² કરી શકે છે જે તમારા ઉપકરણને નà«àª•àª¸àª¾àª¨ પહોંચાડે છે, તમારા મોબાઇલ બિલમાં છà«àªªàª¾àª¯à«‡àª²àª¾ ચારà«àªœ ઉમેરી શકે છે અથવા તમારી વà«àª¯àª•à«àª¤àª¿àª—ત માહિતી ચોરી શકે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />ડાયગà«àª¨à«‹àª¸à«àªŸàª¿àª•à«àª¸ àªàªªà«àª²àª¿àª•à«‡àª¶àª¨<ph name="END_LINK" />નો ઉપયોગ કરીને તમારà«àª‚ કનેકà«àª¶àª¨ ઠીક કરો</translation>
<translation id="2239100178324503013">હમણાં મોકલો</translation>
<translation id="225207911366869382">આ નીતિ માટે આ મૂલà«àª¯àª¨à«‡ નાપસંદ કરેલà«àª‚ છે.</translation>
<translation id="2262243747453050782">HTTP ભૂલ</translation>
+<translation id="2270484714375784793">ફોન નંબર</translation>
<translation id="2282872951544483773">અનà«àªªàª²àª¬à«àª§ પà«àª°àª¯à«‹àª—à«‹</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> આઇટમ}one{<ph name="ITEM_COUNT" /> આઇટમ}other{<ph name="ITEM_COUNT" /> આઇટમ}}</translation>
<translation id="2292556288342944218">તમારી ઇનà«àªŸàª°àª¨à«‡àªŸ àªàª•à«àª¸à«‡àª¸ અવરોધિત છે</translation>
<translation id="230155334948463882">નવà«àª‚ કારà«àª¡?</translation>
-<translation id="2305919008529760154">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° કપટપૂરà«àª£ રીતે જારી કરવામાં આવà«àª¯à«àª‚ હોઈ શકે છે. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> માટે વપરાશકરà«àª¤àª¾àª¨àª¾àª® અને પાસવરà«àª¡ આવશà«àª¯àª• છે.</translation>
-<translation id="2318774815570432836">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" /> ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે વેબસાઇટ HSTS નો ઉપયોગ કરે છે. નેટવરà«àª• ભૂલો અને હà«àª®àª²àª¾ સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ છે, તેથી આ પૃષà«àª  સંભવિત રૂપે પછીથી કારà«àª¯ કરશે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">તમારા વà«àª¯àªµàª¸à«àª¥àª¾àªªàª•à«‡ નિયંતà«àª°àª¿àª¤ કરેલ સેટિંગ</translation>
<translation id="2354001756790975382">અનà«àª¯ બà«àª•àª®àª¾àª°à«àª•à«àª¸</translation>
+<translation id="2354430244986887761">Google સલામત બà«àª°àª¾àª‰àªàª¿àª‚ગને તાજેતરમાં <ph name="SITE" /> પર <ph name="BEGIN_LINK" />હાનિકારક àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ મળી<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">તમે આ સાઇટ પર જોઈ રહà«àª¯àª¾àª‚ છો તે છબીઓને હà«àª®àª²àª¾àª–ોરો જોઈ શકે છે અને તેમને સંશોધિત કરીને તમને છેતરી શકે છે.</translation>
+<translation id="2356070529366658676">કહો</translation>
+<translation id="2359629602545592467">બહà«àªµàª¿àª§</translation>
<translation id="2359808026110333948">ચાલૠરાખો</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> ઠકૅપà«àªšàª° કરેલ કà«àª°à«‡àª¶ રિપોરà«àªŸ અપલોડ કરી ન હતી</translation>
<translation id="2367567093518048410">સà«àª¤àª°</translation>
-<translation id="2371153335857947666">{1,plural, =1{આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«€ સમય સીમા ગઈકાલે સમાપà«àª¤ થઈ ગઈ. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઘડિયાળને હાલમાં <ph name="CURRENT_DATE" /> પર સેટ કરવામાં આવી છે. શà«àª‚ તે બરાબર લાગે છે? જો ઠીક ન લાગતી હોય, તો તમારે તમારી સિસà«àªŸàª®àª¨à«€ ઘડિયાળને ઠીક કરી અને પછી આ પૃષà«àª  તાજà«àª‚ કરવà«àª‚ જોઈàª. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.}one{આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«€ સમય સીમા # દિવસ પહેલાં સમાપà«àª¤ થઈ ગઈ. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઘડિયાળને હાલમાં <ph name="CURRENT_DATE" /> પર સેટ કરવામાં આવી છે. શà«àª‚ તે બરાબર લાગે છે? જો ઠીક ન લાગતી હોય, તો તમારે તમારી સિસà«àªŸàª®àª¨à«€ ઘડિયાળને ઠીક કરી અને પછી આ પૃષà«àª  તાજà«àª‚ કરવà«àª‚ જોઈàª. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.}other{આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«€ સમય સીમા # દિવસ પહેલાં સમાપà«àª¤ થઈ ગઈ. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઘડિયાળને હાલમાં <ph name="CURRENT_DATE" /> પર સેટ કરવામાં આવી છે. શà«àª‚ તે બરાબર લાગે છે? જો ઠીક ન લાગતી હોય, તો તમારે તમારી સિસà«àªŸàª®àª¨à«€ ઘડિયાળને ઠીક કરી અને પછી આ પૃષà«àª  તાજà«àª‚ કરવà«àª‚ જોઈàª. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">કોઈ UI વિકલà«àªªà«‹ ઉપલબà«àª§ નથી</translation>
<translation id="2384307209577226199">àªàª¨à«àªŸàª°àªªà«àª°àª¾àª‡àª ડિફોલà«àªŸ</translation>
<translation id="2386255080630008482">સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° રદ કરવામાં આવà«àª¯à«àª‚ છે.</translation>
<translation id="2392959068659972793">કોઈ કિંમત સેટ નહીં સાથે નીતિઓ બતાવો</translation>
<translation id="239429038616798445">આ વિતરણ પદà«àª§àª¤àª¿ ઉપલબà«àª§ નથી. કોઈ ભિનà«àª¨ પદà«àª§àª¤àª¿ અજમાવો.</translation>
<translation id="2396249848217231973">&amp;કાઢી નાખવà«àª‚ પૂરà«àªµàªµàª¤à«â€Œ કરો</translation>
-<translation id="2460160116472764928">Google સલામત બà«àª°àª¾àª‰àªàª¿àª‚ગને તાજેતરમાં <ph name="SITE" /> પર <ph name="BEGIN_LINK" />માલવેર મળà«àª¯à«àª‚<ph name="END_LINK" />. વેબસાઇટà«àª¸ કે જે સામાનà«àª¯ રીતે સà«àª°àª•à«àª·àª¿àª¤ હોય છે તે કà«àª¯àª¾àª°à«‡àª• માલવેરથી દૂષિત હોય છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° રદબાતલ થયà«àª‚ હશે. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
<translation id="2463739503403862330">ભરો</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />નેટવરà«àª• ડાયગà«àª¨à«‹àª¸à«àªŸàª¿àª•à«àª¸ ચલાવી રહà«àª¯àª¾àª‚ છે<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">અમાનà«àª¯ શોધ URL.</translation>
+<translation id="2482878487686419369">સૂચનાઓ</translation>
<translation id="2491120439723279231">સરà«àªµàª°àª¨àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª®àª¾àª‚ ભૂલો છે.</translation>
<translation id="2495083838625180221">JSON વિશà«àª²à«‡àª¶àª•</translation>
<translation id="2495093607237746763">જો ચેક કરેલà«àª‚ હોય, તો àªàª¡àªªàª¥à«€ ફોરà«àª® ભરવા માટે Chromium આ ઉપકરણ પર તમારા કારà«àª¡àª¨à«€ àªàª• કૉપિ સંગà«àª°àª¹àª¿àª¤ કરશે.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">પાછા જાઓ</translation>
<translation id="2515629240566999685">તમારા વિસà«àª¤àª¾àª°àª®àª¾àª‚ સિગà«àª¨àª² તપાસીને</translation>
<translation id="2516305470678292029">UI વિકલà«àªªà«‹</translation>
+<translation id="2539524384386349900">શોધો</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ઠઅમાનà«àª¯ પà«àª°àª¤àª¿àª¸àª¾àª¦ મોકલà«àª¯à«‹.</translation>
-<translation id="2552545117464357659">વધૠનવà«àª‚</translation>
<translation id="2556876185419854533">&amp;સંપાદિત કરવà«àª‚ પૂરà«àªµàªµàª¤à«â€Œ કરો</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> તરફથી. આ અને અનà«àª¯ <ph name="OTHER_ARTICLE_COUNT" /> વારà«àª¤àª¾àª“ વાંચો.</translation>
<translation id="2587841377698384444">નિરà«àª¦à«‡àª¶àª¿àª•àª¾ API ID:</translation>
<translation id="2597378329261239068">આ દસà«àª¤àª¾àªµà«‡àªœ પાસવરà«àª¡ સà«àª°àª•à«àª·àª¿àª¤ છે. કૃપા કરીને પાસવરà«àª¡ દાખલ કરો.</translation>
<translation id="2609632851001447353">વૈવિધà«àª¯</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{કોઈ નહીં}=1{1 àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ($1)}=2{2 àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ ($1, $2)}one{# àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ ($1, $2, $3)}other{# àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">તમારી ઘડિયાળ આગળ છે</translation>
<translation id="2639739919103226564">સà«àª¥àª¿àª¤àª¿:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ફાઇલની àªàª•à«àª¸à«‡àª¸ નકારવામાં આવી હતી</translation>
<translation id="2653659639078652383">સબમિટ કરો</translation>
<translation id="2666117266261740852">અનà«àª¯ ટૅબ અથવા àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ બંધ કરો</translation>
+<translation id="2670429602441959756">આ પેજમાં હજી પણ àªàªµà«€ સà«àªµàª¿àª§àª¾àª“ છે કે જે VRમાં સમરà«àª¥àª¿àª¤ નથી. બહાર નીકાળી રહà«àª¯à«àª‚ છે…</translation>
<translation id="2674170444375937751">શà«àª‚ તમે ખરેખર તમારા ઇતિહાસમાંથી આ પૃષà«àª à«‹àª¨à«‡ કાઢી નાખવા માંગો છો?</translation>
<translation id="2677748264148917807">છોડો</translation>
-<translation id="269990154133806163">સરà«àªµàª°à«‡ àªàªµà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚ કે જે પà«àª°àª®àª¾àª£àªªàª¤à«àª° પારદરà«àª¶àª¿àª¤àª¾ નીતિનો ઉપયોગ કરીને સારà«àªµàªœàª¨àª¿àª• રીતે જાહેર કરà«àª¯à«àª‚ ન હતà«àª‚. આ કેટલાક પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹ માટે ઠખાતરી કરવા હેતૠઆવશà«àª¯àª• છે કે તેઓ વિશà«àªµàª¸àª¨à«€àª¯ છે અને હà«àª®àª²àª¾àª–ોરો સામે રકà«àª·àª£ કરે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">વાંચન સૂચિ</translation>
<translation id="2704283930420550640">મૂલà«àª¯ ફોરà«àª®à«‡àªŸàª¥à«€ મેળ ખાતà«àª‚ નથી.</translation>
<translation id="2704951214193499422">આ સમયે Chromium તમારા કારà«àª¡àª¨à«€ પà«àª·à«àªŸàª¿ કરવામાં અસમરà«àª¥ હતà«àª‚. કૃપા કરીને પછીથી ફરી પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="2705137772291741111">આ સાઇટની સાચવેલ (કૅશ કરેલ) કૉપિ વાંચવા યોગà«àª¯ ન હતી.</translation>
<translation id="2709516037105925701">સà«àªµàª¤àªƒàª­àª°à«‹</translation>
-<translation id="2712118517637785082">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¤à«àª¨ કરà«àª¯à«‹, પરંતૠસરà«àªµàª° દà«àªµàª¾àª°àª¾ પà«àª°àª¸à«àª¤à«àª¤ કરવામાં આવેલà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° તેના રજૂકરà«àª¤àª¾ દà«àªµàª¾àª°àª¾ જ રદ કરવામાં આવà«àª¯à«àª‚ છે. આનો અરà«àª¥ છે કે સરà«àªµàª°à«‡ પà«àª°àª¸à«àª¤à«àª¤ કરેલા સà«àª°àª•à«àª·àª¾ ઓળખપતà«àª° પર પૂરà«àª£àªªàª£à«‡ વિશà«àªµàª¾àª¸ કરવો જોઈઠનહીં. તમે કોઈ હà«àª®àª²àª¾àª–ોર સાથે વારà«àª¤àª¾àª²àª¾àªª કરી રહà«àª¯àª¾àª‚ હોઈ શકો છો. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">પરવાનગી માગો</translation>
<translation id="2713444072780614174">શà«àªµà«‡àª¤</translation>
<translation id="2720342946869265578">નજીકના</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ઉપકરણ રેકોરà«àª¡ ખૂટે છે</translation>
<translation id="2784949926578158345">કનેકà«àª¶àª¨ ફરીથી સેટ થયà«àª‚.</translation>
<translation id="2794233252405721443">સાઇટ અવરોધિત કરી</translation>
+<translation id="2799020568854403057">સાઇટ આગળ હાનિકારક àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ ધરાવે છે</translation>
+<translation id="2803306138276472711">Google Safe Browsing ને તાજેતરમાં <ph name="SITE" /> પર <ph name="BEGIN_LINK" />મૉલવેર મળà«àª¯à«àª‚<ph name="END_LINK" />. વેબસાઇટà«àª¸ કે જે સામાનà«àª¯ રીતે સà«àª°àª•à«àª·àª¿àª¤ છે તે કà«àª¯àª¾àª°à«‡àª• મૉલવેરથી દૂષિત હોય છે.</translation>
<translation id="2824775600643448204">સરનામà«àª‚ અને શોધ બાર</translation>
<translation id="2826760142808435982">કનેકà«àª¶àª¨ <ph name="CIPHER" /> નો ઉપયોગ કરીને àªàª¨à«àª•à«àª°àª¿àªªà«àªŸ અને પà«àª°àª®àª¾àª£àª¿àª¤ કરેલૠછે અને મà«àª–à«àª¯ àªàª•à«àª¸àªšà«‡àª¨à«àªœ મેકેનિàªà«àª® તરીકે <ph name="KX" /> નો ઉપયોગ કરે છે.</translation>
<translation id="2835170189407361413">ફોરà«àª® સાફ કરો</translation>
+<translation id="2856444702002559011">હà«àª®àª²àª¾àª–ોરો કદાચ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />માંથી તમારી માહિતી (ઉદાહરણ તરીકે, પાસવરà«àª¡, સંદેશા અથવા કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡) ચોરવાનો પà«àª°àª¯àª¾àª¸ કરી રહà«àª¯àª¾àª‚ હોઈ શકે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">ફરીથી લોડ કરશો નહીં</translation>
<translation id="2900469785430194048">આ વેબ પૃષà«àª  પà«àª°àª¦àª°à«àª¶àª¿àª¤ કરવાનો પà«àª°àª¯àª¾àª¸ કરતી વખતે Google Chrome ની મેમરી સમાપà«àª¤ થઈ ગઈ.</translation>
<translation id="2909946352844186028">નેટવરà«àª• ફેરફાર મળà«àª¯à«‹ હતો.</translation>
<translation id="2916038427272391327">અનà«àª¯ પà«àª°à«‹àª—à«àª°àª¾àª® બંધ કરો</translation>
<translation id="2922350208395188000">સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° તપાસી શકાતà«àª‚ નથી.</translation>
<translation id="2928905813689894207">બિલિંગનà«àª‚ સરનામà«àª‚</translation>
+<translation id="2941952326391522266">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° <ph name="DOMAIN2" /> નà«àª‚ છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
<translation id="2948083400971632585">તમે સેટિંગà«àª¸ પૃષà«àª àª®àª¾àª‚થી કનેકà«àª¶àª¨ માટે ગોઠવવામાં આવેલ કોઇપણ પà«àª°à«‹àª•à«àª¸à«€àª“ અકà«àª·àª® કરી શકો છો.</translation>
<translation id="2955913368246107853">શોધ બાર બંધ કરો</translation>
<translation id="2958431318199492670">નેટવરà«àª• ગોઠવણી ONC માનકનà«àª‚ પાલન કરતી નથી. ગોઠવણીના ભાગો આયાત કરી શકાશે નહીં.</translation>
-<translation id="29611076221683977">હà«àª®àª²àª¾àª–ોરો હાલમાં <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પર છે તે તમારા Mac પર તમારી માહિતી (ઉદાહરણ તરીકે, ફોટા, પાસવરà«àª¡à«àª¸, સંદેશા અને કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸) ને ચોરી શકે કે કાઢી નાખે તેવા જોખમી પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸àª¨à«‡ ઇનà«àª¸à«àªŸà«‹àª² કરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે.</translation>
<translation id="2966678944701946121">સમાપà«àª¤àª¿: <ph name="EXPIRATION_DATE_ABBR" />, <ph name="ADDED_TO_AUTOFILL_MONTH" /> ના રોજ ઉમેરà«àª¯à«àª‚</translation>
<translation id="2969319727213777354">àªàª• સà«àª°àª•à«àª·àª¿àª¤ કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરવા માટે, તમારી ઘડિયાળ યોગà«àª¯ રીતે સેટ હોવી જરૂરી છે. આનà«àª‚ કારણ ઠકે વેબસાઇટà«àª¸ તેઓને ઓળખવા માટે જે પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹àª¨à«‹ ઉપયોગ કરે છે તે ચોકà«àª•àª¸ સમય અવધિ માટે જ માનà«àª¯ હોય છે. તમારા ઉપકરણની ઘડિયાળ ખોટી હોવાને લીધે, Google Chrome આ પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹àª¨à«‡ ચકાસી શકતà«àª‚ નથી.</translation>
<translation id="2972581237482394796">&amp;ફરી કરો</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">àªàª• માનà«àª¯ સરનામà«àª‚ દાખલ કરો</translation>
<translation id="2986368408720340940">આ પિકઅપ પદà«àª§àª¤àª¿ ઉપલબà«àª§ નથી. કોઈ ભિનà«àª¨ પદà«àª§àª¤àª¿ અજમાવો.</translation>
<translation id="2991174974383378012">વેબસાઇટà«àª¸ સાથે શેર કરવà«àª‚</translation>
+<translation id="2991571918955627853">તમે હમણાં <ph name="SITE" />ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે તે વેબસાઇટ HSTSનો ઉપયોગ કરે છે. નેટવરà«àª•àª®àª¾àª‚ ભૂલ આવવી અને હà«àª®àª²àª¾ થવા સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ હોય છે, તેથી આ પેજ સંભવિત રૂપે થોડા સમય પછી કારà«àª¯ કરશે.</translation>
<translation id="3005723025932146533">સાચવેલી કૉપિ બતાવો</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> માટે CVC દાખલ કરો. àªàª•àªµàª¾àª° તમે પà«àª·à«àªŸàª¿ કરી લો, તે પછી આ સાઇટ સાથે તમારા કારà«àª¡àª¨à«€ વિગતો શેર કરવામાં આવશે.</translation>
<translation id="3010559122411665027">"<ph name="ENTRY_INDEX" />" àªàª¨à«àªŸà«àª°à«€àª¨à«‡ સૂચિબદà«àª§ કરો: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">આપમેળે અવરોધિત</translation>
<translation id="3024663005179499861">ખોટો નીતિ પà«àª°àª•àª¾àª°</translation>
<translation id="3032412215588512954">શà«àª‚ તમે આ સાઇટ ફરીથી લોડ કરવા માંગો છો?</translation>
<translation id="3037605927509011580">અરર કંઇક ભà«àª² થઇ!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{સમનà«àªµàª¯àª¿àª¤ ઉપકરણો પર ઓછામાં ઓછી 1 આઇટમ}=1{1 આઇટમ (અને સમનà«àªµàª¯àª¿àª¤ ઉપકરણો પર વધà«)}one{# આઇટમ (અને સમનà«àªµàª¯àª¿àª¤ ઉપકરણો પર વધà«)}other{# આઇટમ (અને સમનà«àªµàª¯àª¿àª¤ ઉપકરણો પર વધà«)}}</translation>
<translation id="3041612393474885105">પà«àª°àª®àª¾àª£àªªàª¤à«àª° માહિતી</translation>
<translation id="3063697135517575841">આ સમયે Chrome તમારા કારà«àª¡àª¨à«€ પà«àª·à«àªŸàª¿ કરવામાં અસમરà«àª¥ હતà«àª‚. કૃપા કરીને પછીથી ફરી પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="3064966200440839136">બાહà«àª¯ àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ મારફતે ચà«àª•àªµàª£à«€ કરવા માટે છà«àªªà«‹ મોડ છોડી રહà«àª¯àª¾àª‚ છીàª. તો ચાલૠરાખીàª?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{કોઈ નહીં}=1{1 પાસવરà«àª¡}one{# પાસવરà«àª¡}other{# પાસવરà«àª¡}}</translation>
<translation id="3093245981617870298">તમે ઑફલાઇન છો</translation>
<translation id="3105172416063519923">સંપતà«àª¤àª¿ ID:</translation>
<translation id="3109728660330352905">તમને આ પૃષà«àª àª¨à«‡ જોવાની અધિકૃતિ નથી.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />કનેકà«àªŸàª¿àªµàª¿àªŸà«€ ડાયગà«àª¨à«‹àª¸à«àªŸàª¿àª•à«àª¸ ચલાવવાનો પà«àª°àª¯àª¾àª¸ કરો<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">પà«àª°àª¤àª¿àª•à«àª°àª¿àª¯àª¾ ડિકોડ કરવી નિષà«àª«àª³ થઇ</translation>
<translation id="3150653042067488994">અસà«àª¥àª¾àª¯à«€ સરà«àªµàª° ભૂલ</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">તમે છà«àªªàª¾ ટેબà«àª¸àª®àª¾àª‚ જà«àª“ છો તે પૃષà«àª à«‹ તમે તમારા બધા છà«àªªàª¾ ટેબà«àª¸ બંધ કરી દો તે પછી તમારા બà«àª°àª¾àª‰àªàª°àª¨àª¾ ઇતિહાસ, કà«àª•à«€ સà«àªŸà«‹àª° અથવા શોધ ઇતિહાસમાં રહેશે નહીં. તમે ડાઉનલોડ કરો છો તે કોઈપણ ફાઇલો અથવા તમે બનાવો છો તે બà«àª•àª®àª¾àª°à«àª•à«àª¸ રાખવામાં આવશે.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">આઇલેનà«àª¡</translation>
+<translation id="317583078218509884">નવી સાઇટ પરવાનગીઓ સેટિંગà«àª¸ પૃષà«àª  ફરીથી લોડ કરà«àª¯àª¾ પછી પà«àª°àª­àª¾àªµàª®àª¾àª‚ આવશે.</translation>
<translation id="3176929007561373547">પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª° કારà«àª¯ કરી રહà«àª¯à«àª‚ છે તેની ખાતરી કરવા માટે તમારી પà«àª°à«‹àª•à«àª¸à«€ સેટિંગà«àª¸ તપાસો
અથવા તમારા નેટવરà«àª• વà«àª¯àªµàª¸à«àª¥àª¾àªªàª•àª¨à«‹ સંપરà«àª• કરો. જો તમે પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª°àª¨à«‹ ઉપયોગ કરવો 
જોઇઠàªàªµà«àª‚ ન માનતા હો:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">છà«àªªàª¾ મોડમાં પૃષà«àª  ખોલો</translation>
-<translation id="3202578601642193415">સૌથી નવà«àª‚</translation>
+<translation id="320323717674993345">ચà«àª•àªµàª£à«€ રદ કરો</translation>
<translation id="3207960819495026254">બà«àª•àª®àª¾àª°à«àª• કરેલ</translation>
+<translation id="3225919329040284222">સરà«àªµàª° àªàª• પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરે છે જે બિલà«àªŸ-ઇન અપેકà«àª·àª¾àª“ સાથે મેળ ખાતà«àª‚ નથી. આ અપેકà«àª·àª¾àª“માં તમને સà«àª°àª•à«àª·àª¿àª¤ રાખવા માટે અમà«àª• ચોકà«àª•àª¸, ઉચà«àªš-સà«àª°àª•à«àª·àª¾ વેબસાઇટà«àª¸àª¨à«‹ સમાવેશ થાય છે.</translation>
<translation id="3226128629678568754">પૃષà«àª àª¨à«‡ લોડ કરવા માટે જરૂરી ડેટા ફરીથી સબમિટ કરવા માટે ફરીથી લોડ કરો બટન દબાવો.</translation>
+<translation id="3227137524299004712">માઇકà«àª°à«‹àª«à«‹àª¨</translation>
<translation id="3228969707346345236">ભાષાંતર નિષà«àª«àª³ રહà«àª¯à«àª‚ કારણ કે પૃષà«àª  પહેલાથી જ <ph name="LANGUAGE" /> માં છે.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> માટે CVC દાખલ કરો</translation>
+<translation id="3234666976984236645">હંમેશા આ સાઇટ પરની મહતà«àªµàª¨à«€ સામગà«àª°à«€ શોધો</translation>
<translation id="3254409185687681395">આ પૃષà«àª àª¨à«‡ બà«àª•àª®àª¾àª°à«àª• કરો</translation>
<translation id="3270847123878663523">&amp;પà«àª¨àªƒàª•à«àª°àª®àª¾àª‚કિત કરવà«àª‚ પૂરà«àªµàªµàª¤à« કરો</translation>
<translation id="3282497668470633863">કારà«àª¡ પર નામ ઉમેરો</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">સેટિંગà«àª¸</translation>
<translation id="3345135638360864351">આ સાઇટને àªàª•à«àª¸à«‡àª¸ કરવાની તમારી વિનંતી <ph name="NAME" /> ને મોકલી શકાઈ નથી. કૃપા કરીને ફરી પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="3355823806454867987">પà«àª°à«‹àª•à«àª¸à«€ સેટિંગà«àª¸ બદલો...</translation>
+<translation id="3361596688432910856">Chrome નિમà«àª¨àª²àª¿àª–િત માહિતી <ph name="BEGIN_EMPHASIS" />સાચવશે નહીં<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />તમારો બà«àª°àª¾àª‰àªàª¿àª‚ગ ઇતિહાસ
+ <ph name="LIST_ITEM" />કà«àª•à«€ અને સાઇટ ડેટા
+ <ph name="LIST_ITEM" />ફોરà«àª®àª®àª¾àª‚ દાખલ કરેલી માહિતી
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">ઘડિયાળ ભૂલ</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> વધૠઆઇટમ...</translation>
<translation id="337363190475750230">જોગવાઈ દૂર કરી</translation>
<translation id="3377188786107721145">નીતિ વિશà«àª²à«‡àª·àª£ ભૂલ</translation>
<translation id="3380365263193509176">અજà«àªžàª¾àª¤ ભૂલ</translation>
<translation id="3380864720620200369">કà«àª²àª¾àª‡àª¨à«àªŸ ID:</translation>
<translation id="3391030046425686457">વિતરણ માટેનà«àª‚ સરનામà«àª‚</translation>
<translation id="3395827396354264108">પિકઅપ પદà«àª§àª¤àª¿</translation>
-<translation id="340013220407300675">હà«àª®àª²àª¾àª–ોરો <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> માંથી તમારી માહિતી ચોરી કરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે (ઉદાહરણ તરીકે, પાસવરà«àª¡à«àª¸, સંદેશા અથવા કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸).</translation>
<translation id="3422248202833853650">મેમરી ખાલી કરવા માટે અનà«àª¯ પà«àª°à«‹àª—à«àª°àª¾àª®àª¥à«€ બહાર નીકળવાનો પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> હાલમાં પહોંચવા યોગà«àª¯ નથી.</translation>
+<translation id="3427092606871434483">મંજૂરી આપો (ડિફૉલà«àªŸ)</translation>
<translation id="3427342743765426898">&amp;સંપાદિત કરવà«àª‚ ફરી કરો</translation>
<translation id="3431636764301398940">આ ઉપકરણ પર આ કારà«àª¡ સાચવો</translation>
<translation id="3435896845095436175">સકà«àª·àª® કરો</translation>
<translation id="3447661539832366887">આ ઉપકરણના માલિકે ડાયનાસોર રમત બંધ કરી છે.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">આનયન અંતરાલ:</translation>
<translation id="3462200631372590220">વિગતવાર છà«àªªàª¾àªµà«‹</translation>
<translation id="3467763166455606212">કારà«àª¡àª§àª¾àª°àª•àª¨à«àª‚ નામ આવશà«àª¯àª• છે</translation>
<translation id="3478058380795961209">સમય સમાપà«àª¤àª¿ મહિનો</translation>
<translation id="3479539252931486093">શà«àª‚ આ અનપેકà«àª·àª¿àª¤ હતà«àª‚? <ph name="BEGIN_LINK" />અમને જણાવો<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">હમણાં નહીં</translation>
-<translation id="348000606199325318">કà«àª°à«‡àª¶ ID <ph name="CRASH_LOCAL_ID" /> (સરà«àªµàª° ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">અમે આ પળે તમારા વાલી સà«àª§à«€ પહોંચી શકà«àª¯àª¾àª‚ નથી. કૃપા કરીને ફરી પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="3528171143076753409">સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° વિશà«àªµàª¸àª¨à«€àª¯ નથી.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{સિંક કરેલ ઉપકરણો પર ઓછામાં ઓછી 1 આઇટમ}=1{1 આઇટમ (અને સિંક કરેલ ઉપકરણો પર બીજી ઘણી બધી)}one{# આઇટમ (અને સિંક કરેલ ઉપકરણો પર બીજી ઘણી બધી)}other{# આઇટમ (અને સિંક કરેલ ઉપકરણો પર બીજી ઘણી બધી)}}</translation>
<translation id="3539171420378717834">આ ઉપકરણ પર આ કારà«àª¡àª¨à«€ àªàª• કૉપિ રાખો</translation>
<translation id="3542684924769048008">આ માટે પાસવરà«àª¡àª¨à«‹ ઉપયોગ કરો:</translation>
+<translation id="3545341443414427877"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> સાથે ખાનગી કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરી શકાતà«àª‚ નથી કારણ કે તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ તારીખ અને સમય (<ph name="DATE_AND_TIME" />) ખોટા છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">તમારા પોતાના સમનà«àªµàª¯àª¨ પાસફà«àª°à«‡àª સાથે તમામ સમનà«àªµàª¯àª¿àª¤ ડેટા àªàª¨à«àª•à«àª°àª¿àªªà«àªŸ કરો</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> વધà«...</translation>
-<translation id="3555561725129903880">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° <ph name="DOMAIN2" /> નà«àª‚ છે. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">તમારા માટે તમારા સંચાલક તેને અનાવરોધિત કરી શકે છે</translation>
<translation id="3566021033012934673">તમારà«àª‚ કનેકà«àª¶àª¨ ખાનગી નથી</translation>
+<translation id="3569145463236695319">&lt;p&gt;<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> સાથે ખાનગી કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરી શકાતà«àª‚ નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) ખોટા છે.&lt;/p&gt;
+
+ &lt;p&gt;કૃપા કરીને &lt;strong&gt;સેટિંગà«àª¸&lt;/strong&gt; àªàªªà«àª²àª¿àª•à«‡àª¶àª¨àª¨àª¾ &lt;strong&gt;સામાનà«àª¯&lt;/strong&gt; વિભાગમાંથી તારીખ અને સમય સમાયોજિત કરો.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">નામ ઉમેરો</translation>
<translation id="3583757800736429874">&amp;ખસેડવà«àª‚ ફરી કરો</translation>
<translation id="3586931643579894722">વિગતો છà«àªªàª¾àªµà«‹</translation>
-<translation id="3587482841069643663">બધા</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">àªàª• માનà«àª¯ સમાપà«àª¤àª¿ તારીખ દાખલ કરો</translation>
<translation id="36224234498066874">બà«àª°àª¾àª‰àªàª¿àª‚ગ ડેટા સાફ કરો...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">પà«àª°àª®àª¾àª£àªªàª¤à«àª° માહિતી</translation>
<translation id="3690164694835360974">લોગિન સà«àª°àª•à«àª·àª¿àª¤ નથી</translation>
<translation id="3693415264595406141">પાસવરà«àª¡:</translation>
-<translation id="3696411085566228381">કોઈ નહીં</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">લોડ કરી રહà«àª¯à«àª‚ છે...</translation>
<translation id="3712624925041724820">લાઇસેંસીસ પૂરà«àª£</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />પà«àª°à«‹àª•à«àª¸à«€, ફાયરવોલ અને DNS ગોઠવણી તપાસીને<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">જો તમે તમારી સà«àª°àª•à«àª·àª¾àª¨àª¾ જોખમોને સમજો છો, તો તમે જોખમી પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ દૂર કરી દેવામાં આવે તે પહેલાં <ph name="BEGIN_LINK" />આ અસલામત સાઇટની મà«àª²àª¾àª•àª¾àª¤<ph name="END_LINK" /> લઈ શકો છો.</translation>
<translation id="3739623965217189342">તમે કૉપિ કરેલ લિંક</translation>
+<translation id="3744899669254331632">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" /> ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતા નથી કારણ કે વેબસાઇટે સà«àª•à«àª°à«…મà«àª¬àª² કરેલ ઓળખાણપતà«àª°à«‹ મોકલà«àª¯àª¾àª‚ છે જેના પર Chromium પà«àª°àª•à«àª°àª¿àª¯àª¾ કરી શકતà«àª‚ નથી. નેટવરà«àª• ભૂલો અને હà«àª®àª²àª¾àª“ સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ હોય છે, તેથી આ પૃષà«àª  સંભવતઃ પછીથી કારà«àª¯ કરશે.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પરના હà«àª®àª²àª¾àª–ોરો તમને છેતરીને કંઈક જોખમકારક પà«àª°àªµà«ƒàª¤à«àª¤àª¿ જેમ કે સૉફà«àªŸàªµà«‡àª° ઇનà«àª¸à«àªŸà«‰àª² કરવા અથવા તમારી વà«àª¯àª•à«àª¤àª¿àª—ત માહિતી (ઉદાહરણ તરીકે, પાસવરà«àª¡, ફોન નંબર અથવા કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡) જણાવવા માટે પà«àª°à«‡àª°àª¿àª¤ કરી શકે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">સરà«àªµàª° ભૂલને કારણે ભાષાંતર નિષà«àª«àª³ રહà«àª¯à«àª‚.</translation>
<translation id="3759461132968374835">તમે હાલમાં કà«àª°à«‡àª¶àª¨à«€ જાણ કરી નથી. કà«àª°à«‡àª¶àª¨à«€ જાણ કરવાનà«àª‚ અકà«àª·àª® હતà«àª‚ તà«àª¯àª¾àª°à«‡ થયેલા કà«àª°à«‡àª¶ અહીં દેખાશે નહીં.</translation>
+<translation id="3778403066972421603">શà«àª‚ તમે આ કારà«àª¡àª¨à«‡ તમારા Google àªàª•àª¾àª‰àª¨à«àªŸ અને આ ઉપકરણ પર સાચવવા માગો છો?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> માં સમાપà«àª¤ થાય છે</translation>
<translation id="382518646247711829">જો તમે કોઈ પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª°àª¨à«‹ ઉપયોગ કરો છો...</translation>
<translation id="3828924085048779000">ખાલી પાસફà«àª°à«‡àªàª¨à«‡ અનà«àª®àª¤àª¿ નથી. </translation>
-<translation id="3845539888601087042">તમે સાઇન ઇન થયેલા હોય તેવા ઉપકરણોમાંથી ઇતિહાસ બતાવી રહà«àª¯àª¾àª‚ છે. <ph name="BEGIN_LINK" />વધૠજાણો<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">પાછળ</translation>
<translation id="3858027520442213535">તારીખ અને સમય અપડેટ કરો</translation>
<translation id="3884278016824448484">વિરોધાભાસી ઉપકરણ ઓળખકરà«àª¤àª¾</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">આ સાઇટને àªàª•à«àª¸à«‡àª¸ કરવાની તમારી વિનંતી <ph name="NAME" /> ને મોકલવામાં આવી છે</translation>
<translation id="3890664840433101773">ઇમેઇલ ઉમેરો</translation>
<translation id="3901925938762663762">કારà«àª¡àª¨à«€ સમયસીમા સમાપà«àª¤ થઇ ગઈ છે</translation>
-<translation id="3933571093587347751">{1,plural, =1{આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° સંભવિત રૂપે આવતીકાલથી લાગૠથાય. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.}one{આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° ભવિષà«àª¯àª®àª¾àª‚ # દિવસમાં લાગૠથાય. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.}other{આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° ભવિષà«àª¯àª®àª¾àª‚ # દિવસમાં લાગૠથાય. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF દસà«àª¤àª¾àªµà«‡àªœ લોડ કરવામાં નિષà«àª«àª³ રહà«àª¯àª¾</translation>
+<translation id="3945915738023014686">કà«àª°à«‡àª¶ રિપોરà«àªŸ ID <ph name="CRASH_ID" /> (સà«àª¥àª¾àª¨àª¿àª• કà«àª°à«‡àª¶ ID: <ph name="CRASH_LOCAL_ID" />) અપલોડ કરà«àª¯à«àª‚</translation>
+<translation id="3949571496842715403">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° વિષય વૈકલà«àªªàª¿àª• નામનો ઉલà«àª²à«‡àª– કરતà«àª‚ નથી. આ કોઈ ખોટી ગોઠવણીને કારણે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવતો હોવાને કારણે બનà«àª¯à«àª‚ હોઈ શકે.</translation>
<translation id="3963721102035795474">રીડર મોડ</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{કોઈ નહીં}=1{1 સાઇટમાંથી }one{# સાઇટમાંથી }other{# સાઇટમાંથી }}</translation>
<translation id="397105322502079400">ગણના કરી રહà«àª¯à«àª‚ છે...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> અવરોધિત છે</translation>
+<translation id="3987940399970879459">1 MB કરતાં ઓછà«àª‚</translation>
<translation id="40103911065039147">{URL_count,plural, =1{નજીકમાં 1 વેબ પૃષà«àª }one{નજીકમાં # વેબ પૃષà«àª }other{નજીકમાં # વેબ પૃષà«àª }}</translation>
<translation id="4021036232240155012">DNS ઠનેટવરà«àª• સેવા છે કે જે વેબસાઇટના નામનો અનà«àªµàª¾àª¦ તેના ઇનà«àªŸàª°àª¨à«‡àªŸ સરનામાં પર કરે છે.</translation>
<translation id="4030383055268325496">&amp;ઉમેરવà«àª‚ પૂરà«àªµàªµàª¤à« કરો</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">પà«àª°à«‹àª•à«àª¸à«€ ગોઠવણી .pac સà«àª•à«àª°àª¿àªªà«àªŸ URL નો ઉપયોગ કરવા માટે સેટ છે, નિયત પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª°à«àª¸ માટે નહીં.</translation>
<translation id="4098354747657067197">આગળ છેતરામણી સાઇટ છે</translation>
<translation id="4103249731201008433">ઉપકરણ અનà«àª•à«àª°à«àª®àª¾àª‚ક નંબર અમાનà«àª¯ છે</translation>
+<translation id="410351446219883937">ઑટોપà«àª²à«‡</translation>
<translation id="4103763322291513355">બà«àª²à«‡àª•àª²àª¿àª¸à«àªŸ કરેલા URL ની સૂચિ અને તમારા સિસà«àªŸàª® વà«àª¯àªµàª¸à«àª¥àª¾àªªàª• દà«àªµàª¾àª°àª¾ લાગૠઅનà«àª¯ નીતિઓ જોવા માટે &lt;strong&gt;chrome://policy&lt;/strong&gt; ની મà«àª²àª¾àª•àª¾àª¤ લો.</translation>
-<translation id="4110615724604346410">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª®àª¾àª‚ ભૂલો છે. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">કિરમજી</translation>
+<translation id="4116663294526079822">હંમેશા આ સાઇટ પર મંજૂરી આપો</translation>
<translation id="4117700440116928470">નીતિ મરà«àª¯àª¾àª¦àª¾ સમરà«àª¥àª¿àª¤ નથી.</translation>
-<translation id="4118212371799607889">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°, Chromium દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 અનà«àª¯}one{# અનà«àª¯}other{# અનà«àª¯}}</translation>
<translation id="4130226655945681476">નેટવરà«àª• કેબલà«àª¸, મૉડેમ અને રાઉટર તપાસીને</translation>
+<translation id="413544239732274901">વધૠજાણો</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">વૈશà«àªµàª¿àª• ડિફોલà«àªŸàª¨à«‹ ઉપયોગ કરો (શોધો)</translation>
+<translation id="4165986682804962316">સાઇટ સેટિંગà«àª¸</translation>
<translation id="4169947484918424451">શà«àª‚ તમે ઇચà«àª›à«‹ છો કે Chromium આ કારà«àª¡ સાચવે?</translation>
<translation id="4171400957073367226">ખોટી ચકાસણી સહી</translation>
<translation id="4196861286325780578">&amp;ખસેડવà«àª‚ ફરી કરો</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ફાયરવોલ અને àªàª¨à«àªŸà«€àªµàª¾àª‡àª°àª¸ ગોઠવણી તપાસીને<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{કોઈ નહીં}=1{1 àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ($1)}=2{2 àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ($1, $2)}one{# àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ($1, $2, $3)}other{# àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">કà«àª°à«‡àª¶à«‡àª¸</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પરના હà«àª®àª²àª¾àª–ોરો તમને તેવા પà«àª°à«‹àª—à«àª°àª¾àª® ઇનà«àª¸à«àªŸà«‰àª² કરવા માટે છેતરી શકે છે કે જે તમારા બà«àª°àª¾àª‰àªàª¿àª‚ગ અનà«àª­àªµàª¨à«‡ (ઉદાહરણ તરીકે, તમારા હોમપેજને બદલીને અથવા તમે જે સાઇટની મà«àª²àª¾àª•àª¾àª¤ લો છો તેની પર વધારાની જાહેરાતો બતાવીને) નà«àª•àª¸àª¾àª¨ પહોંચાડે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />નેટવરà«àª• ડાયગà«àª¨à«‹àª¸à«àªŸàª¿àª•à«àª¸ ચલાવવાનો પà«àª°àª¯àª¾àª¸ કરો<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">માનà«àª¯àª¤àª¾</translation>
<translation id="4250431568374086873">આ સાઇટ પરનà«àª‚ તમારà«àª‚ કનેકà«àª¶àª¨ પૂરà«àª£àªªàª£à«‡ સà«àª°àª•à«àª·àª¿àª¤ નથી</translation>
<translation id="4250680216510889253">નહીં</translation>
<translation id="425582637250725228">તમે કરેલા ફેરફારો સાચવવામાં આવà«àª¯àª¾àª‚ ન હોઇ શકે.</translation>
<translation id="4258748452823770588">ખરાબ હસà«àª¤àª¾àª•à«àª·àª°</translation>
+<translation id="4265872034478892965">તમારા વà«àª¯àªµàª¸à«àª¥àª¾àªªàª• દà«àªµàª¾àª°àª¾ મંજૂર</translation>
<translation id="4269787794583293679">(કોઇ વપરાશકરà«àª¤àª¾àª¨àª¾àª® નથી)</translation>
<translation id="4275830172053184480">તમારà«àª‚ ઉપકરણ પà«àª¨àªƒàªªà«àª°àª¾àª°àª‚ભ કરો</translation>
<translation id="4280429058323657511">, સમાપà«àª¤àª¿ તારીખ <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google સલામત બà«àª°àª¾àª‰àªàª¿àª‚ગને તાજેતરમાં <ph name="SITE" /> <ph name="BEGIN_LINK" />હાનિકારક પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ મળà«àª¯àª¾àª‚<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">પેરેનà«àªŸ સૂચનો</translation>
<translation id="4304224509867189079">લૉગ ઇન કરો</translation>
-<translation id="432290197980158659">સરà«àªµàª°à«‡ àªàªµà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚ કે જે બિલà«àªŸ-ઇન અપવાદો સાથે મેળ ખાતà«àª‚ નથી. તમને સà«àª°àª•à«àª·àª¿àª¤ રાખવા માટે, આ અપેકà«àª·àª¾àª“ અમà«àª• ચોકà«àª•àª¸, ઉચà«àªš-સà«àª°àª•à«àª·àª¾ વેબસાઇટà«àª¸ માટે શામેલ કરવામાં આવી છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">અવરોધિત કરો (ડિફૉલà«àªŸ)</translation>
<translation id="4325863107915753736">લેખ શોધવામાં નિષà«àª«àª³ થયાં</translation>
<translation id="4326324639298822553">તમારી સમાપà«àª¤àª¿ તારીખ તપાસો અને ફરી પà«àª°àª¯àª¾àª¸ કરો</translation>
<translation id="4331708818696583467">સà«àª°àª•à«àª·àª¿àª¤ નથી</translation>
<translation id="4356973930735388585">આ સાઇટ પરના હà«àª®àª²àª¾àª–ોરો તમારા કમà«àªªà«àª¯à«àªŸàª° પર તમારી માહિતી (ઉદાહરણ તરીકે, ફોટા, પાસવરà«àª¡à«àª¸, સંદેશા અને કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸) ને ચોરી શકે કે કાઢી નાખે તેવા જોખમી પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸àª¨à«‡ ઇનà«àª¸à«àªŸà«‹àª² કરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે.</translation>
<translation id="4372948949327679948">અપેકà«àª·àª¿àª¤ <ph name="VALUE_TYPE" /> મૂલà«àª¯.</translation>
+<translation id="4377125064752653719">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¾àª¸ કરà«àª¯à«‹, પણ સરà«àªµàª° દà«àªµàª¾àª°àª¾ પà«àª°àª¸à«àª¤à«àª¤ કરવામાં આવેલà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° તેના રજૂકરà«àª¤àª¾ દà«àªµàª¾àª°àª¾ જ રદ કરવામાં આવà«àª¯à«àª‚ છે. આનો અરà«àª¥ છે કે સરà«àªµàª°à«‡ પà«àª°àª¸à«àª¤à«àª¤ કરેલા સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹ પૂરà«àª£àªªàª£à«‡ વિશà«àªµàª¸àª¨à«€àª¯ નથી. તમે કોઈ હà«àª®àª²àª¾àª–ોર જોડે વાત કરતા હોઈ શકો છો.</translation>
<translation id="4381091992796011497">વપરાશકરà«àª¤àª¾àª¨à«àª‚ નામ:</translation>
<translation id="4394049700291259645">અકà«àª·àª® કરો</translation>
<translation id="4406896451731180161">શોધ પરિણામો</translation>
+<translation id="4424024547088906515">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° Chrome દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ઠતમારà«àª‚ લોગિન પà«àª°àª®àª¾àª£àªªàª¤à«àª° સà«àªµà«€àª•àª¾àª°à«àª¯à«àª‚ ન હતà«àª‚ અથવા કદાચ કોઈ àªàª• પà«àª°àª¦àª¾àª¨ કરવામાં આવà«àª¯à«àª‚ નથી.</translation>
<translation id="443673843213245140">પà«àª°à«‹àª•à«àª¸à«€àª¨à«‹ ઉપયોગ અકà«àª·àª® કરેલો છે પણ àªàª• સà«àªªàª·à«àªŸ પà«àª°à«‹àª•à«àª¸à«€ ગોઠવણી ઉલà«àª²à«‡àª–િત છે.</translation>
-<translation id="4492190037599258964">'<ph name="SEARCH_STRING" />' માટે શોધ પરિણામ</translation>
<translation id="4506176782989081258">માનà«àª¯àª¤àª¾ ભૂલ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">સિસà«àªŸàª® વà«àª¯àªµàª¸à«àª¥àª¾àªªàª•àª¨à«‹ સંપરà«àª• કરીને</translation>
<translation id="450710068430902550">વà«àª¯àªµàª¸à«àª¥àª¾àªªàª• સાથે શેર કરવà«àª‚</translation>
<translation id="4515275063822566619">કારà«àª¡ અને સરનામા Chrome અને Google àªàª•àª¾àª‰àª¨à«àªŸ (<ph name="ACCOUNT_EMAIL" />)માંથી છે. તમે તેને <ph name="BEGIN_LINK" />સેટિંગà«àª¸<ph name="END_LINK" />માં જઈને સંચાલિત કરી શકો છો.</translation>
<translation id="4522570452068850558">વિગતો</translation>
+<translation id="4552089082226364758">ફà«àª²à«‡àª¶</translation>
<translation id="4558551763791394412">તમારા àªàª•à«àª¸à«àªŸà«‡àª¨à«àª¶àª¨à«àª¸àª¨à«‡ અકà«àª·àª® કરવાનો પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="457875822857220463">વિતરણ</translation>
<translation id="4587425331216688090">Chrome માંથી સરનામà«àª‚ દૂર કરીàª?</translation>
-<translation id="4589078953350245614">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¤à«àª¨ કરà«àª¯à«‹, પરંતૠસરà«àªµàª°à«‡ અમાનà«àª¯ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">આધà«àª¨àª¿àª• સાઇફર સà«àª¯à«‚ટનો ઉપયોગ કરીને <ph name="DOMAIN" /> સાથેનà«àª‚ તમારà«àª‚ કનેકà«àª¶àª¨ àªàª¨à«àª•à«àª°àª¿àªªà«àªŸ કરાયà«àª‚ છે.</translation>
<translation id="4594403342090139922">&amp;કાઢી નાખવà«àª‚ પૂરà«àªµàªµàª¤à«â€Œ કરો</translation>
<translation id="4619615317237390068">અનà«àª¯ ઉપકરણોમાંથી ટૅબà«àª¸</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેના સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª®àª¾àª‚ ભૂલો છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
+<translation id="4690462567478992370">અમાનà«àª¯ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«‹ ઉપયોગ કરવાનà«àª‚ બંધ કરો</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">તમારà«àª‚ કનેકà«àª¶àª¨ અવરોધાયà«àª‚ હતà«àª‚</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows નેટવરà«àª• ડાયગà«àª¨à«‹àª¸à«àªŸàª¿àª•à«àª¸ ચલાવી રહà«àª¯àª¾àª‚ છે<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">કોઈ અજà«àªžàª¾àª¤ ભૂલ આવી.</translation>
<translation id="4800132727771399293">તમારી સમાપà«àª¤àª¿ તારીખ અને CVC તપાસો અને ફરીથી પà«àª°àª¯àª¾àª¸ કરો</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" /> ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે વેબસાઇટે સમજાય નહીં તેવા ઓળખપતà«àª° મોકલà«àª¯àª¾àª‚ છે જેની પર Google Chrome પà«àª°àª•à«àª°àª¿àª¯àª¾ કરી શકતà«àª‚ નથી. નેટવરà«àª• ભૂલો અને હà«àª®àª²àª¾ સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ છે, તેથી આ પૃષà«àª  સંભવિત રૂપે પછીથી કારà«àª¯ કરશે.</translation>
<translation id="4813512666221746211">નેટવરà«àª• ભૂલ</translation>
<translation id="4816492930507672669">પૃષà«àª  પર ફિટ</translation>
<translation id="483020001682031208">બતાવવા માટે કોઇ ભૌતિક વેબ પૃષà«àª à«‹ નથી</translation>
<translation id="4850886885716139402">જà«àª“</translation>
<translation id="4854362297993841467">વિતરણની આ પદà«àª§àª¤àª¿ ઉપલબà«àª§ નથી. કોઈ ભિનà«àª¨ પદà«àª§àª¤àª¿ અજમાવો.</translation>
<translation id="4858792381671956233">તમે આ સાઇટની મà«àª²àª¾àª•àª¾àª¤ લો છો તે ઠીક છે કે કેમ તેવà«àª‚ તમે તમારા માતાપિતાને પૂછà«àª¯à«àª‚</translation>
+<translation id="4863764087567530506">આ કનà«àªŸà«‡àª¨à«àªŸ કદાચ સૉફà«àªŸàªµà«‡àª° ઇનà«àª¸à«àªŸà«‰àª² કરવા માટે અથવા વà«àª¯àª•à«àª¤àª¿àª—ત માહિતી કઢાવવા માટે તમારી સાથે કપટ કરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે. <ph name="BEGIN_LINK" />છતાં પણ બતાવો<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">ઇતિહાસ શોધ</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{અને 1 વધૠવેબ પૃષà«àª }one{અને # વધૠવેબ પૃષà«àª }other{અને # વધૠવેબ પૃષà«àª }}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">આ પૃષà«àª  કોઈ અજà«àªžàª¾àª¤ ભાષામાંથી <ph name="LANGUAGE_LANGUAGE" /> માં અનà«àªµàª¾àª¦àª¿àª¤ કરવામાં આવà«àª¯à«àª‚ છે</translation>
<translation id="4923459931733593730">ચà«àª•àªµàª£à«€</translation>
<translation id="4926049483395192435">ઉલà«àª²à«‡àª–િત હોવà«àª‚ આવશà«àª¯àª• છે.</translation>
<translation id="495170559598752135">કà«àª°àª¿àª¯àª¾àª“</translation>
<translation id="4958444002117714549">સૂચિ વિસà«àª¤à«ƒàª¤ કરો</translation>
-<translation id="4962322354953122629">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°, Chrome દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">ચેતવણીઓ ફરીથી સકà«àª·àª® કરો</translation>
<translation id="4989809363548539747">આ પà«àª²àª—-ઇન સમરà«àª¥àª¿àª¤ નથી</translation>
<translation id="5002932099480077015">જો સકà«àª·àª® કરેલà«àª‚ હોય, તો àªàª¡àªªàª¥à«€ ફોરà«àª® ભરવા માટે Chrome આ ઉપકરણ પર તમારા કારà«àª¡àª¨à«€ àªàª• કૉપિ સંગà«àª°àª¹àª¶à«‡.</translation>
<translation id="5018422839182700155">આ પૃષà«àª  ખોલી શકતાં નથી</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">તમારા વà«àª¯àªµàª¸à«àª¥àª¾àªªàª•àª¨à«€ નીતિઓ તપાસો</translation>
<translation id="5029568752722684782">કૉપિ સાફ કરો</translation>
<translation id="5031870354684148875">Google અનà«àªµàª¾àª¦ વિશે</translation>
+<translation id="5039804452771397117">મંજૂરી આપો</translation>
<translation id="5040262127954254034">ગોપનીયતા</translation>
<translation id="5045550434625856497">ખોટો પાસવરà«àª¡</translation>
<translation id="5056549851600133418">તમારા માટે લેખ</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />પà«àª°à«‹àª•à«àª¸à«€ સરનામà«àª‚ તપાસીને<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{કોઈ કà«àª•à«€ નહીં}=1{1 સાઇટ કà«àª•à«€àª¨à«‹ ઉપયોગ કરે છે. }one{# સાઇટ કà«àª•à«€àª¨à«‹ ઉપયોગ કરે છે. }other{# સાઇટ કà«àª•à«€àª¨à«‹ ઉપયોગ કરે છે. }}</translation>
<translation id="5087286274860437796">સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° આ સમયે માનà«àª¯ નથી.</translation>
<translation id="5087580092889165836">કારà«àª¡ ઉમેરો</translation>
<translation id="5089810972385038852">રાજà«àª¯</translation>
+<translation id="5094747076828555589">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° Chromium દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
<translation id="5095208057601539847">પà«àª°àª¾àª‚ત</translation>
<translation id="5115563688576182185">(64-બિટ)</translation>
<translation id="5141240743006678641">તમારા Google ઓળખપતà«àª°à«‹ સાથે સમનà«àªµàª¯àª¿àª¤ પાસવરà«àª¡à«àª¸àª¨à«‡ àªàª¨à«àª•à«àª°àª¿àªªà«àªŸ કરો</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">ઇમેઇલ આવશà«àª¯àª• છે</translation>
<translation id="5251803541071282808">મેઘ</translation>
<translation id="5277279256032773186">કારà«àª¯ પર Chrome નો ઉપયોગ કરી રહà«àª¯àª¾àª‚ છો? વà«àª¯àªµàª¸àª¾àª¯à«‹ તેમના કરà«àª®àªšàª¾àª°à«€àª“ માટે Chrome સેટિંગà«àª¸àª¨à«‡ સંચાલિત કરી શકે છે. વધૠજાણો</translation>
+<translation id="5297526204711817721">આ સાઇટ પરનà«àª‚ તમારà«àª‚ કનેકà«àª¶àª¨ ખાનગી નથી. કોઈપણ સમયે VR મોડથી બહાર નીકળવા માટે, હેડસેટ દૂર કરો અને પાછળ દબાવો.</translation>
<translation id="5299298092464848405">ભૂલ વિશà«àª²à«‡àª·àª£ નીતિ</translation>
-<translation id="5300589172476337783">બતાવો</translation>
<translation id="5308689395849655368">કà«àª°à«‡àª¶àª¨à«€ જાણ કરવાનà«àª‚ અકà«àª·àª® કરà«àª¯à«àª‚ છે.</translation>
<translation id="5317780077021120954">સાચવો</translation>
<translation id="5327248766486351172">નામ</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પરના હà«àª®àª²àª¾àª–ોરો તમારી વà«àª¯àª•à«àª¤àª¿àª—ત માહિતી (ઉદાહરણ તરીકે, પાસવરà«àª¡à«àª¸, ફોન નંબરà«àª¸ અથવા કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸) ને દરà«àª¶àª¾àªµàªµàª¾ અથવા સોફà«àªŸàªµà«‡àª° ઇનà«àª¸à«àªŸà«‹àª² કરવા જેવી જોખમી વસà«àª¤à«àª“ને કરવા માટે તમને છેતરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે.</translation>
-<translation id="5359637492792381994">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° આ સમયે માનà«àª¯ નથી. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" />ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે તેનà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° રદબાતલ કરવામાં આવà«àª¯à«àª‚ છે. નેટવરà«àª•àª®àª¾àª‚ ભૂલ આવવી અને હà«àª®àª²àª¾ થવા સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ હોય છે, તેથી આ પેજ સંભવિત રૂપે થોડા સમય પછી કારà«àª¯ કરશે.</translation>
<translation id="536296301121032821">નીતિ સેટિંગà«àª¸ સà«àªŸà«‹àª° કરવામાં નિષà«àª«àª³ થયાં</translation>
<translation id="5386426401304769735">આ સાઇટ માટેની પà«àª°àª®àª¾àª£àªªàª¤à«àª° શà«àª°à«ƒàª‚ખલા SHA-1 નો ઉપયોગ કરીને સહી કરેલ પà«àª°àª®àª¾àª£àªªàª¤à«àª° ધરાવે છે.</translation>
<translation id="5402410679244714488">સમાપà«àª¤àª¿: <ph name="EXPIRATION_DATE_ABBR" />, છેલà«àª²à«‡ àªàª• વરà«àª· પહેલાં ઉપયોગ કરેલ</translation>
+<translation id="540969355065856584">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° આ સમયે માનà«àª¯ નથી. આ કોઇ ખોટી ગોઠવણીને કારણે થયà«àª‚ હોય અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોઇ શકે છે.</translation>
<translation id="5421136146218899937">બà«àª°àª¾àª‰àªàª¿àª‚ગ ડેટા સાફ કરો...</translation>
<translation id="5430298929874300616">બà«àª•àª®àª¾àª°à«àª• દૂર કરો</translation>
<translation id="5431657950005405462">તમારી ફાઇલ મળી ન હતી</translation>
-<translation id="5435775191620395718">આ ઉપકરણમાંથી ઇતિહાસ બતાવી રહà«àª¯àª¾àª‚ છે. <ph name="BEGIN_LINK" />વધૠજાણો<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" પર સà«àª•à«€àª®àª¾ માનà«àª¯àª¤àª¾ ભૂલ: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">આ <ph name="HOST_NAME" /> પૃષà«àª  શોધી શકાતà«àª‚ નથી</translation>
<translation id="5455374756549232013">ખરાબ નીતિ સમયનોંધ</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" /> માંથી <ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">અમાનà«àª¯</translation>
<translation id="5470861586879999274">&amp;સંપાદિત કરવà«àª‚ ફરી કરો</translation>
<translation id="54817484435770891">માનà«àª¯ સરનામà«àª‚ ઉમેરો</translation>
<translation id="5492298309214877701">કંપની, સંસà«àª¥àª¾ અથવા શાળા ઇનà«àªŸà«àª°àª¾àª¨à«‡àªŸ પર આ સાઇટ બાહà«àª¯ વેબસાઇટ જેવà«àª‚ જ URL ધરાવે છે.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">આ સરનામેથી પિકઅપ કરી શકતા નથી. કોઈ ભિનà«àª¨ સરનામà«àª‚ પસંદ કરો.</translation>
<translation id="5572851009514199876">કૃપા કરીને Chrome ને પà«àª°àª¾àª°àª‚ભ કરો અને સાઇન ઇન કરો જેથી કરીને Chrome તપાસી શકે કે તમને આ સાઇટની àªàª•à«àª¸à«‡àª¸àª¨à«€ મંજૂરી છે કે કેમ.</translation>
<translation id="5580958916614886209">તમારો સમાપà«àª¤àª¿ મહિનો તપાસો અને ફરી પà«àª°àª¯àª¾àª¸ કરો</translation>
+<translation id="5586446728396275693">કોઈ સાચવેલ àªàª¡à«àª°à«‡àª¸ નથી</translation>
+<translation id="5595485650161345191">સરનામà«àª‚ સંપાદિત કરો</translation>
<translation id="560412284261940334">સંચાલન સમરà«àª¥àª¿àª¤ નથી</translation>
<translation id="5610142619324316209">કનેકà«àª¶àª¨ તપાસીને</translation>
<translation id="5610807607761827392">તમે <ph name="BEGIN_LINK" />સેટિંગà«àª¸<ph name="END_LINK" />માં કારà«àª¡à«àª¸ અને સરનામાં સંચાલિત કરી શકો છો.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">શà«àª‚ તમે આ સાઇટ છોડવા માંગો છો?</translation>
<translation id="5629630648637658800">નીતિ સેટિંગà«àª¸ લોડ કરવામાં નિષà«àª«àª³ થયાં</translation>
<translation id="5631439013527180824">અમાનà«àª¯ ઉપકરણ સંચાલન ટોકન</translation>
+<translation id="5633066919399395251"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પરના હà«àª®àª²àª¾àª–ોરો કદાચ હાલમાં તમારા કમà«àªªà«àª¯à«àªŸàª° પર જોખમી પà«àª°à«‹àª—à«àª°àª¾àª® ઇનà«àª¸à«àªŸà«‰àª² કરવાનો પà«àª°àª¯àª¾àª¸ કરે છે કે જે તમારી માહિતી (ઉદાહરણ તરીકે, ફોટા, પાસવરà«àª¡, સંદેશા અને કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡) ચોરી અથવા કાઢી નાખી શકે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">સà«àª¥àª¾àª¨</translation>
+<translation id="5659593005791499971">ઇમેઇલ</translation>
<translation id="5669703222995421982">વà«àª¯àª•à«àª¤àª¿àª—ત કરેલ સામગà«àª°à«€ મેળવો</translation>
<translation id="5675650730144413517">આ પૃષà«àª  કામ કરી રહà«àª¯à«àª‚ નથી</translation>
-<translation id="5677928146339483299">અવરોધિત</translation>
-<translation id="5694783966845939798">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¤à«àª¨ કરà«àª¯à«‹, પરંતૠસરà«àªµàª°à«‡ નબળા હસà«àª¤àª¾àª•à«àª·àª° અલà«àª—ોરિધમ (જેમ કે SHA-1)નો ઉપયોગ કરીને સહી કરેલà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚. આનો અરà«àª¥ ઠછે કે સરà«àªµàª°à«‡ પà«àª°àª¸à«àª¤à«àª¤ કરેલા સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹ બનાવટી હોઈ શકે છે અને તે સરà«àªµàª° તમારà«àª‚ અપેકà«àª·àª¿àª¤ સરà«àªµàª° ન પણ હોય (તમે કોઈ હà«àª®àª²àª¾àª–ોર સાથે વારà«àª¤àª¾àª²àª¾àªª કરી રહà«àª¯àª¾àª‚ હોઈ શકો છો). <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">આ વેબસાઇટની ઓળખ ચકાસવામાં આવી નથી.</translation>
+<translation id="5713016350996637505">ભà«àª°àª¾àª®àª• કનà«àªŸà«‡àª¨à«àªŸ અવરોધિત કરà«àª¯à«àª‚</translation>
<translation id="5720705177508910913">વરà«àª¤àª®àª¾àª¨ વપરાશકરà«àª¤àª¾</translation>
<translation id="5732392974455271431">તમારા માટે તમારા માતાપિતા તેને અનાવરોધિત કરી શકે છે</translation>
<translation id="5763042198335101085">àªàª• માનà«àª¯ ઇમેઇલ àªàª¡à«àª°à«‡àª¸ ઉમેરો</translation>
<translation id="5765072501007116331">વિતરણ પદà«àª§àª¤àª¿àª“ અને આવશà«àª¯àª•àª¤àª¾àª“ જોવા માટે, àªàª• સરનામà«àª‚ પસંદ કરો</translation>
+<translation id="5778550464785688721">MIDI ઉપકરણોનà«àª‚ પૂરà«àª£ નિયંતà«àª°àª£</translation>
<translation id="5784606427469807560">તમારા કારà«àª¡àª¨à«€ પà«àª·à«àªŸàª¿ કરવામાં àªàª• સમસà«àª¯àª¾ આવી હતી. તમારà«àª‚ ઇનà«àªŸàª°àª¨à«‡àªŸ કનેકà«àª¶àª¨ તપાસો અને ફરીથી પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="5785756445106461925">વળી, આ પૃષà«àª àª®àª¾àª‚ અનà«àª¯ àªàªµàª¾ સાધનો છે જે સà«àª°àª•à«àª·àª¿àª¤ નથી. ટà«àª°àª¾àª‚àªàª¿àªŸàª®àª¾àª‚ હોવા પર અનà«àª¯ લોકો દà«àªµàª¾àª°àª¾ આ સાધનો જોઈ શકાય છે અને પૃષà«àª àª¨à«‹ દેખાવ બદલવા માટે હà«àª®àª²àª¾àª–ોર દà«àªµàª¾àª°àª¾ સંશોધિત કરવામાં આવી શકે છે.</translation>
<translation id="5786044859038896871">શà«àª‚ તમે તમારી કારà«àª¡ માહિતી ભરવા માગો છો?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;ઉમેરવà«àª‚ ફરી કરો</translation>
<translation id="5814352347845180253">તમે <ph name="SITE" /> અને કેટલીક અનà«àª¯ સાઇટà«àª¸àª¨à«€ પà«àª°à«€àª®àª¿àª¯àª® સામગà«àª°à«€àª¨à«€ àªàª•à«àª¸à«‡àª¸ ગà«àª®àª¾àªµà«€ શકો છો.</translation>
<translation id="5838278095973806738">તમારે આ સાઇટ પર કોઈપણ સંવેદનશીલ માહિતી (ઉદાહરણ તરીકે, પાસવરà«àª¡à«àª¸ અથવા કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸) દાખલ કરવી જોઈઠનહીં, કારણ કે તે હà«àª®àª²àª¾àª–ોર દà«àªµàª¾àª°àª¾ ચોરવામાં આવી શકે છે.</translation>
-<translation id="5843436854350372569">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¤à«àª¨ કરà«àª¯à«‹, પરંતૠસરà«àªµàª°à«‡ નબળી કી ધરાવતà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚. હà«àª®àª²àª¾àª–ોરે ખાનગી કી તોડી હોઈ શકે છે અને બને કે સરà«àªµàª° તમારà«àª‚ અપેકà«àª·àª¿àª¤ સરà«àªµàª° ન હોય (તમે કોઈ હà«àª®àª²àª¾àª–ોર સાથે વારà«àª¤àª¾àª²àª¾àªª કરી રહà«àª¯àª¾àª‚ હોઈ શકો છો). <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">આ સાઇટ પર પહોંચી શકાતà«àª‚ નથી</translation>
<translation id="5869522115854928033">સાચવેલા પાસવરà«àª¡à«àª¸</translation>
<translation id="5872918882028971132">પેરેનà«àªŸ સૂચનો</translation>
<translation id="5901630391730855834">પીળો</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (સમનà«àªµàª¯àª¿àª¤)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 ઉપયોગમાં છે}one{# ઉપયોગમાં છે}other{# ઉપયોગમાં છે}}</translation>
<translation id="5926846154125914413">તમે કેટલીક સાઇટà«àª¸àª¨à«€ પà«àª°à«€àª®àª¿àª¯àª® સામગà«àª°à«€àª¨à«€ àªàª•à«àª¸à«‡àª¸ ગà«àª®àª¾àªµà«€ શકો છો.</translation>
<translation id="5959728338436674663">જોખમી અâ€à«…પà«àª²àª¿àª•à«‡àª¶àª¨à«‹ અને સાઇટà«àª¸ શોધવામાં સહાય કરવા માટે Google ને કેટલીક <ph name="BEGIN_WHITEPAPER_LINK" />સિસà«àªŸàª® માહિતી અને પૃષà«àª  સામગà«àª°à«€<ph name="END_WHITEPAPER_LINK" /> આપમેળે મોકલો. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">અઠવાડિયà«àª‚</translation>
<translation id="5967867314010545767">ઇતિહાસમાંથી દૂર કરો</translation>
<translation id="5975083100439434680">àªà«‚મ ઘટાડો</translation>
<translation id="598637245381783098">ચà«àª•àªµàª£à«€ àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ખોલી શકાતી નથી</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{પૃષà«àª  1}one{પૃષà«àª  #}other{પૃષà«àª  #}}</translation>
<translation id="6017514345406065928">લીલો</translation>
+<translation id="6017850046339264347">હà«àª®àª²àª¾àª–ોરો <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પર ભà«àª°àª¾àª®àª• àªàªªà«àª²àª¿àª•à«‡àª¶àª¨ ઇનà«àª¸à«àªŸà«‰àª² કરી શકે છે જે કંઈક બીજà«àª‚ હોવાનો ડોળ કરે છે અથવા તમને ટà«àª°à«…ક કરવા માટે ઉપયોગમાં લઈ શકાય તેવો ડેટા àªàª•àª¤à«àª°àª¿àª¤ કરી શકે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (સમનà«àªµàª¯àª¿àª¤)</translation>
<translation id="6027201098523975773">àªàª• નામ દાખલ કરો</translation>
<translation id="6040143037577758943">બંધ કરો</translation>
<translation id="6042308850641462728">વધà«</translation>
+<translation id="6047233362582046994">જો તમે તમારી સà«àª°àª•à«àª·àª¾àª¨àª¾ જોખમોને સમજો છો, તો તમે જોખમકારક àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ દૂર કરતા પહેલા <ph name="BEGIN_LINK" />આ સાઇટની મà«àª²àª¾àª•àª¾àª¤<ph name="END_LINK" /> લઈ શકો છો.</translation>
+<translation id="6051221802930200923">તમે અતà«àª¯àª¾àª°à«‡ આ <ph name="SITE" />ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે આ વેબસાઇટ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પિનિંગનો ઉપયોગ કરે છે. નેટવરà«àª•àª®àª¾àª‚ ભૂલ આવવી અને હà«àª®àª²àª¾ થવા સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ હોય છે, તેથી આ પેજ સંભવિત રૂપે થોડા સમય પછી કારà«àª¯ કરશે.</translation>
<translation id="6060685159320643512">સાવચેતી રાખો, આ પà«àª°àª¯à«‹àª—à«‹ નà«àª•àª¸àª¾àª¨àª•àª¾àª°àª• હોઈ શકે છે</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{કોઈ નહીં}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">તમે વà«àª¯àªµàª¸à«àª¥àª¾àªªàª•-પà«àª°àª¦àª¤à«àª¤ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«‹ ઉપયોગ કરીને સામગà«àª°à«€ àªàª•à«àª¸à«‡àª¸ કરી છે. તમે <ph name="DOMAIN" /> ને પà«àª°àª¦àª¾àª¨ કરેલ ડેટા તમારા વà«àª¯àªµàª¸à«àª¥àª¾àªªàª• દà«àªµàª¾àª°àª¾ ઇનà«àªŸàª°àª¸à«‡àªªà«àªŸ થઈ શકે છે.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{કોઈ નહીં}=1{1 પાસવરà«àª¡ (સિંક કરેલ)}one{# પાસવરà«àª¡ (સિંક કરેલ)}other{# પાસવરà«àª¡ (સિંક કરેલ)}}</translation>
<translation id="6146055958333702838">કોઈપણ કેબલà«àª¸ તપાસો અને તમે કદાચ ઉપયોગમાં લઇ રહà«àª¯àª¾àª‚ હોય તેવા કોઇપણ રાઉટરà«àª¸, મૉડેમà«àª¸Â 
અથવા અનà«àª¯ નેટવરà«àª• ઉપકરણોને રીબૂટ કરો.</translation>
<translation id="614940544461990577">પà«àª°àª¯àª¾àª¸ કરો:</translation>
<translation id="6151417162996330722">સરà«àªµàª° પà«àª°àª®àª¾àª£àªªàª¤à«àª° પાસે ખૂબ લાંબી હોય àªàªµà«€ માનà«àª¯àª¤àª¾ અવધિ છે.</translation>
<translation id="6157877588268064908">વિતરણ પદà«àª§àª¤àª¿ અને આવશà«àª¯àª•àª¤àª¾àª“ જોવા માટે, àªàª• સરનામà«àª‚ પસંદ કરો</translation>
+<translation id="6158003235852588289">Google Safe Browsingને તાજેતરમાં જ <ph name="SITE" /> પર ફિશિંગ થયાનà«àª‚ જાણવા મળà«àª¯à«àª‚ છે. ફિશિંગ વેબસાઇટ તમને છેતરવા માટે અનà«àª¯ વેબસાઇટ હોવાનો ઢોંગ કરે છે.</translation>
<translation id="6165508094623778733">વધૠજાણો</translation>
+<translation id="6169916984152623906">હવે તમે ખાનગીમાં બà«àª°àª¾àª‰àª કરી શકો છો અને અનà«àª¯ લોકો જે આ ઉપકરણનો ઉપયોગ કરે છે તે પણ તમારી પà«àª°àªµà«ƒàª¤à«àª¤àª¿ જોઇ શકશે નહીં. જો કે ડાઉનલોડ અને બà«àª•àª®àª¾àª°à«àª• સાચવવામાં આવશે.</translation>
<translation id="6177128806592000436">આ સાઇટ પરનà«àª‚ તમારà«àª‚ કનેકà«àª¶àª¨ સà«àª°àª•à«àª·àª¿àª¤ નથી</translation>
<translation id="6184817833369986695">(સાથી: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">તમારà«àª‚ ઇનà«àªŸàª°àª¨à«‡àªŸ કનેકà«àª¶àª¨ તપાસો</translation>
<translation id="6218753634732582820">Chromium માંથી સરનામà«àª‚ દૂર કરીàª?</translation>
+<translation id="6221345481584921695">Google Safe Browsing ને તાજેતરમાં <ph name="SITE" /> પર <ph name="BEGIN_LINK" />મૉલવેર મળà«àª¯à«àª‚<ph name="END_LINK" />. વેબસાઇટà«àª¸ કે જે સામાનà«àª¯ રીતે સà«àª°àª•à«àª·àª¿àª¤ છે તે કà«àª¯àª¾àª°à«‡àª• મૉલવેરથી દૂષિત હોય છે. દà«àª°à«àª­àª¾àªµàª¨àª¾àªªà«‚રà«àª£ સામગà«àª°à«€ àªàª• જà«àªžàª¾àª¤ મૉલવેર વિકà«àª°à«‡àª¤àª¾ àªàªµàª¾, <ph name="SUBRESOURCE_HOST" /> થી આવે છે.</translation>
<translation id="6251924700383757765">ગોપનીયતા નીતિ</translation>
<translation id="6254436959401408446">આ પૃષà«àª  ખોલવા માટે પૂરતી મેમરી નથી</translation>
<translation id="625755898061068298">તમે આ સાઇટ માટે સà«àª°àª•à«àª·àª¾ ચેતવણીઓ અકà«àª·àª® કરવાનà«àª‚ પસંદ કરà«àª¯à«àª‚ છે.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">બà«àª•àª®àª¾àª°à«àª• સંપાદિત કરો</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> માટે સમાપà«àª¤àª¿ તારીખ અને CVC દાખલ કરો</translation>
<translation id="6414888972213066896">આ પૃષà«àª àª¨à«€ મà«àª²àª¾àª•àª¾àª¤ લો છો તે ઠીક છે કે કેમ તેવà«àª‚ તમે તમારા માતાપિતાને પૂછà«àª¯à«àª‚</translation>
-<translation id="6416403317709441254">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" /> ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે વેબસાઇટે સમજાય નહીં તેવા ઓળખપતà«àª° મોકલà«àª¯àª¾àª‚ છે જેની પર Chromium પà«àª°àª•à«àª°àª¿àª¯àª¾ કરી શકતà«àª‚ નથી. નેટવરà«àª• ભૂલો અને હà«àª®àª²àª¾ સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ છે, તેથી આ પૃષà«àª  સંભવિત રૂપે પછીથી કારà«àª¯ કરશે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">પà«àª°àª®àª¾àª£àªªàª¤à«àª° રદ કરવામાં આવà«àª¯à«àª‚ છે કે નહીં તે તપાસવામાં અકà«àª·àª® છે.</translation>
<translation id="6433490469411711332">સંપરà«àª• માહિતી સંપાદિત કરો</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ઠકનેકà«àªŸ કરવાનો ઇનકાર કરà«àª¯à«‹.</translation>
<translation id="6446608382365791566">વધૠમાહિતી ઉમેરો</translation>
+<translation id="6447842834002726250">કૂકીàª</translation>
<translation id="6451458296329894277">ફોરà«àª®àª¨àª¾àª‚ ફરી સબમિશનની પà«àª·à«àªŸàª¿ કરો</translation>
<translation id="6456339708790392414">તમારી ચà«àª•àªµàª£à«€</translation>
<translation id="6458467102616083041">અવગણો કારણ કે નીતિ દà«àªµàª¾àª°àª¾ ડિફૉલà«àªŸ શોધ અકà«àª·àª® કરેલી છે.</translation>
-<translation id="6462969404041126431">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° રદબાતલ કરà«àª¯à«àª‚ હોઈ શકે છે. આ કદાચ કોઈ ખોટી ગોઠવણી અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ હોવાને કારણે થયà«àª‚ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">ઉપકરણ નીતિઓ</translation>
<translation id="6477321094435799029">Chrome ને આ પૃષà«àª  પર અસામાનà«àª¯ કોડ મળà«àª¯à«‹ અને તમારી વà«àª¯àª•à«àª¤àª¿àª—ત માહિતી (ઉદાહરણ તરીકે, પાસવરà«àª¡à«àª¸, ફોન નંબરà«àª¸ અને કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸)ની સà«àª°àª•à«àª·àª¾ કરવા માટે તેને અવરોધિત કરેલ છે.</translation>
<translation id="6489534406876378309">કà«àª°à«‡àª¶ અપલોડ કરવાનà«àª‚ શરૂ કરો</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">સમાપà«àª¤àª¿: <ph name="EXPIRATION_DATE_ABBR" />, છેલà«àª²à«‡ <ph name="LAST_USED_DATE_NO_DETAIL" /> ના રોજ ઉપયોગ કરà«àª¯à«‹</translation>
<translation id="6563469144985748109">તમારા સંચાલકે હજી સà«àª§à«€ તેને મંજૂર કરેલ નથી</translation>
<translation id="6569060085658103619">તમે àªàª•à«àª¸à«àªŸà«‡àª¨à«àª¶àª¨ પૃષà«àª  જોઈ રહà«àª¯àª¾àª‚ છો</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> કરતાં ઓછà«àª‚</translation>
+<translation id="657639383826808334">આ કનà«àªŸà«‡àª¨à«àªŸ તમારા ઉપકરણ પર જોખમી સૉફà«àªŸàªµà«‡àª° ઇનà«àª¸à«àªŸà«‰àª² કરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે જે તમારી માહિતીની ચોરી કરે અથવા કાઢી નાખે છે. <ph name="BEGIN_LINK" />છતાં પણ બતાવો<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">àªàª¨à«àª•à«àª°àª¿àªªà«àª¶àª¨ વિકલà«àªªà«‹</translation>
<translation id="662080504995468778">પૃષà«àª  પર રહો</translation>
<translation id="6626291197371920147">માનà«àª¯ કારà«àª¡ નંબર ઉમેરો</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> શોધ</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પરના હà«àª®àª²àª¾àª–ોરો કદાચ હાલમાં તમારા Mac પર જોખમી પà«àª°à«‹àª—à«àª°àª¾àª® ઇનà«àª¸à«àªŸà«‰àª² કરવાનો પà«àª°àª¯àª¾àª¸ કરે છે કે જે તમારી માહિતી (ઉદાહરણ તરીકે, ફોટા, પાસવરà«àª¡, સંદેશા અને કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡) ચોરી અથવા કાઢી નાખી શકે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">આ નીતિ દૂર કરવામાં આવેલી છે.</translation>
-<translation id="6652240803263749613">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° તમારા કમà«àªªà«àª¯à«àªŸàª°àª¨à«€ ઓપરેટિંગ સિસà«àªŸàª® દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Chromium માંથી ફોરà«àª® સૂચન દૂર કરીàª?</translation>
<translation id="6685834062052613830">સાઇન આઉટ કરો અને સેટઅપ પૂરà«àª£ કરો</translation>
<translation id="6710213216561001401">પહેલાનà«àª‚</translation>
<translation id="6710594484020273272">&lt;શોધ શબà«àª¦ લખો&gt;</translation>
<translation id="6711464428925977395">પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª°àª®àª¾àª‚ કંઈક ખોટà«àª‚ થયà«àª‚ છે અથવા તો સરનામà«àª‚ ખોટà«àª‚ છે.</translation>
<translation id="6727102863431372879">સેટ કરો</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{કોઈ નહીં}=1{1 આઇટમ}one{# આઇટમ}other{# આઇટમ}}</translation>
<translation id="674375294223700098">અજà«àªžàª¾àª¤ સરà«àªµàª° પà«àª°àª®àª¾àª£àªªàª¤à«àª° ભૂલ.</translation>
<translation id="6753269504797312559">નીતિ મૂલà«àª¯</translation>
<translation id="6757797048963528358">તમારà«àª‚ ઉપકરણ નિષà«àª•à«àª°àª¿àª¯ થઈ ગયà«àª‚ હતà«àª‚.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">કસà«àªŸàª®àª¾àª‡àªà«‡àª¶àª¨ ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">પà«àª°àª¦à«‡àª¶àª¨à«‹ ડેટા લોડ કરવામાં નિષà«àª«àª³ થયાં</translation>
+<translation id="6825578344716086703">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¾àª¸ કરà«àª¯à«‹, પરંતૠસરà«àªµàª°à«‡ નબળા હસà«àª¤àª¾àª•à«àª·àª° અલà«àª—ોરિધમ (જેમ કે SHA-1)નો ઉપયોગ કરીને હસà«àª¤àª¾àª•à«àª·àª°àª¿àª¤ કરેલà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚. આનો અરà«àª¥ ઠછે કે સરà«àªµàª°à«‡ પà«àª°àª¸à«àª¤à«àª¤ કરેલા સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹ બનાવટી હોઈ શકે છે અને તે સરà«àªµàª° તમારà«àª‚ અપેકà«àª·àª¿àª¤ સરà«àªµàª° (તમે કોઈ હà«àª®àª²àª¾àª–ોર સાથે વારà«àª¤àª¾àª²àª¾àªª કરતા હોઠશકે) ન પણ હોય.</translation>
+<translation id="6830728435402077660">સà«àª°àª•à«àª·àª¿àª¤ નથી</translation>
<translation id="6831043979455480757">અનà«àªµàª¾àª¦ કરો</translation>
<translation id="6839929833149231406">વિસà«àª¤àª¾àª°</translation>
<translation id="6874604403660855544">&amp;ઉમેરવà«àª‚ ફરી કરો</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">તમારા કારà«àª¡àª¨à«€ પà«àª·à«àªŸàª¿ કરવામાં આવી છે</translation>
<translation id="6897140037006041989">વપરાશકરà«àª¤àª¾ àªàªœàª¨à«àªŸ</translation>
<translation id="6915804003454593391">વપરાશકરà«àª¤àª¾: </translation>
+<translation id="6945221475159498467">પસંદ કરો</translation>
<translation id="6948701128805548767">પિકઅપ પદà«àª§àª¤àª¿ અને આવશà«àª¯àª•àª¤àª¾àª“ જોવા માટે, àªàª• સરનામà«àª‚ પસંદ કરો</translation>
<translation id="6957887021205513506">સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° બનાવટી હોય àªàªµà«àª‚ લાગે છે.</translation>
<translation id="6965382102122355670">ઓકે</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">નિયત પà«àª°à«‹àª•à«àª¸à«€ સરà«àªµàª°à«àª¸ અને .pac script URL બનà«àª¨à«‡àª¨à«‹ ઉલà«àª²à«‡àª– કરેલો છે.</translation>
<translation id="6989763994942163495">વિગતવાર સેટિંગà«àª¸ બતાવો...</translation>
<translation id="7000990526846637657">કોઈ ઇતિહાસ પà«àª°àªµàª¿àª·à«àªŸàª¿àª“ મળી નથી</translation>
-<translation id="7009986207543992532">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¤à«àª¨ કરà«àª¯à«‹, પરંતૠસરà«àªµàª°à«‡ àªàªµà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚ કે જેની માનà«àª¯àª¤àª¾ અવધિ àªàªŸàª²à«€ લાંબી છે કે તે વિશà«àªµàª¸àª¨à«€àª¯ લાગતી નથી. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">તમારા Google àªàª•àª¾àª‰àª¨à«àªŸàª®àª¾àª‚ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> પર બà«àª°àª¾àª‰àªàª¿àª‚ગ ઇતિહાસના અનà«àª¯ સà«àªµàª°à«‚પો હોઇ શકે છે.</translation>
<translation id="7029809446516969842">પાસવરà«àª¡à«àª¸</translation>
+<translation id="7050187094878475250">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પà«àª°àª¯àª¾àª¸ કરેલો, પરંતૠસરà«àªµàª°à«‡ àªàªµà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚ જેની માનà«àª¯àª¤àª¾ અવધિ, વિશà«àªµàª¸àª¨à«€àª¯ હોવા માટે ખૂબ લાંબી છે.</translation>
+<translation id="7053983685419859001">અવરોધિત કરો</translation>
<translation id="7064851114919012435">સંપરà«àª• માહિતી</translation>
<translation id="7079718277001814089">આ સાઇટમાં માલવેર છે</translation>
<translation id="7087282848513945231">પરગણà«àª‚</translation>
-<translation id="7088615885725309056">વધૠજૂનà«àª‚</translation>
<translation id="7090678807593890770"><ph name="LINK" /> માટે Google પર શોધો</translation>
+<translation id="7108819624672055576">àªàª•à«àª¸àªŸà«‡àª¨à«àª¶àª¨ દà«àªµàª¾àª°àª¾ મંજૂર</translation>
<translation id="7119414471315195487">અનà«àª¯ ટૅબ અથવા પà«àª°à«‹àª—à«àª°àª¾àª® બંધ કરો</translation>
<translation id="7129409597930077180">આ સરનામે વિતરણ કરી શકાતà«àª‚ નથી. કોઈ ભિનà«àª¨ સરનામà«àª‚ પસંદ કરો.</translation>
<translation id="7138472120740807366">વિતરણ પદà«àª§àª¤àª¿</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">પà«àª°àª•à«àª°àª¿àª¯àª¾ કરી રહà«àª¯à«àª‚ છે</translation>
<translation id="724691107663265825">સાઇટ આગળ મૉલવેર ધરાવે છે</translation>
<translation id="724975217298816891">તમારા કારà«àª¡àª¨à«€ વિગતોને અપડેટ કરવા <ph name="CREDIT_CARD" /> માટે સમાપà«àª¤àª¿ તારીખ અને CVC દાખલ કરો. àªàª•àªµàª¾àª° તમે પà«àª·à«àªŸàª¿ કરી લો, તે પછી આ સાઇટ સાથે તમારા કારà«àª¡àª¨à«€ વિગતો શેર કરવામાં આવશે.</translation>
-<translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> પર ખાનગી કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરી શકાતà«àª‚ નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) અયોગà«àª¯ છે.</translation>
+<translation id="7260504762447901703">àªàª•à«àª¸à«‡àª¸ રદબાતલ કરો</translation>
<translation id="7275334191706090484">સંચાલિત બà«àª•àª®àª¾àª°à«àª•à«àª¸</translation>
<translation id="7298195798382681320">ભલામણ કરેલ</translation>
<translation id="7309308571273880165">કà«àª°à«‡àª¶ રિપોરà«àªŸ <ph name="CRASH_TIME" /> ઠકૅપà«àªšàª° કરવામાં આવી (વપરાશકરà«àª¤àª¾ દà«àªµàª¾àª°àª¾ અપલોડની વિનંતી કરવામાં આવી, હજી સà«àª§à«€ અપલોડ કરેલ નથી)</translation>
<translation id="7334320624316649418">&amp;પà«àª¨àªƒàª•à«àª°àª®àª¾àª‚કિત કરવà«àª‚ ફરી કરો</translation>
<translation id="733923710415886693">પà«àª°àª®àª¾àª£àªªàª¤à«àª° પારદરà«àª¶àª¿àª¤àª¾ દà«àªµàª¾àª°àª¾ સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° જાહેર કરવામાં આવà«àª¯à«àª‚ ન હતà«àª‚.</translation>
-<translation id="7351800657706554155">તમે અતà«àª¯àª¾àª°à«‡ <ph name="SITE" /> ની મà«àª²àª¾àª•àª¾àª¤ લઈ શકતાં નથી કારણ કે આ પà«àª°àª®àª¾àª£àªªàª¤à«àª° રદબાતલ કરવામાં આવà«àª¯à«àª‚ છે. નેટવરà«àª• ભૂલો અને હà«àª®àª²àª¾ સામાનà«àª¯ રીતે અસà«àª¥àª¾àª¯à«€ છે, તેથી આ પૃષà«àª  સંભવિત રૂપે પછીથી કારà«àª¯ કરશે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">આદેશ પંકà«àª¤àª¿</translation>
<translation id="7372973238305370288">શોધ પરિણામ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ના</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">કારà«àª¡àª¨à«€ પà«àª·à«àªŸàª¿ કરો</translation>
-<translation id="7394102162464064926">શà«àª‚ તમે ખરેખર તમારા ઇતિહાસમાંથી આ પૃષà«àª à«‹àª¨à«‡ કાઢી નાખવા માગો છો?
-
-અરેરે! છà«àªªà«‹ મોડ <ph name="SHORTCUT_KEY" /> આગલી વખતે ઉપયોગમાં આવી શકશે.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">પà«àª°à«‹àª«àª¾àª‡àª² પાથ</translation>
<translation id="7424977062513257142">આ વેબપૃષà«àª  પરનà«àª‚ àªàª®à«àª¬à«‡àª¡ કરેલ પૃષà«àª  આ કહે છે:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">આ સાઇટ અવરોધિત છે</translation>
<translation id="7445762425076701745">તમે જે સરà«àªµàª°àª¥à«€ કનેકà«àªŸ છો તેની ઓળખ સંપૂરà«àª£ રૂપે માનà«àª¯ કરી શકાતી નથી. તમે જે નામનો ઉપયોગ કરીને સરà«àªµàª°àª¥à«€ કનેકà«àªŸ છો, તે ફકà«àª¤ તમારા નેટવરà«àª•àª¨à«€ અંતરà«àª—ત જ માનà«àª¯ છે, જેના બાહà«àª¯ પà«àª°àª®àª¾àª£àªªàª¤à«àª° અધિકારીને માલિકીને માનà«àª¯ કરવાની કોઈ રીત નથી. આના પર ધà«àª¯àª¾àª¨ આપà«àª¯àª¾àª‚ વગર કેટલાક પà«àª°àª®àª¾àª£àªªàª¤à«àª° અધિકારીઓ આ નામો માટે પà«àª°àª®àª¾àª£àªªàª¤à«àª° બહાર પાડશે, તેથી તમે ઇચà«àª›àª¿àª¤ વેબસાઇટથી કનેકà«àªŸ છો કોઈ હà«àª®àª²àª¾àª–ોરથી નહીં, તેની ખાતરી કરવાની કોઈ રીત નથી.</translation>
<translation id="7451311239929941790">આ સમસà«àª¯àª¾ વિશે <ph name="BEGIN_LINK" />વધૠજાણો<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">વૈશà«àªµàª¿àª• ડિફોલà«àªŸàª¨à«‹ ઉપયોગ કરો (અવરોધિત કરો)</translation>
<translation id="7460163899615895653">અનà«àª¯ ઉપકરણોમાંના તમારા તાજેતરના ટૅબà«àª¸ અહીં દેખાય છે</translation>
<translation id="7469372306589899959">કારà«àª¡àª¨à«€ પà«àª·à«àªŸàª¿ કરી રહà«àª¯àª¾àª‚ છે</translation>
<translation id="7481312909269577407">ફોરà«àªµàª°à«àª¡ કરો</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">પરત થયેલ નીતિ ઉપકરણ id ખાલી છે અથવા વરà«àª¤àª®àª¾àª¨ ટોકન સાથે મેળ ખાતà«àª‚ નથી</translation>
<translation id="7514365320538308">ડાઉનલોડ કરો</translation>
<translation id="7518003948725431193">વેબ સરનામાં માટે કોઈ વેબપેજ મળà«àª¯à«àª‚ નથી: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">મૂલà«àª¯</translation>
<translation id="7537536606612762813">ફરજિયાત</translation>
+<translation id="7542403920425041731">àªàª•àªµàª¾àª° તમે પà«àª·à«àªŸàª¿ કરી લો તે પછી, આ સાઇટ સાથે તમારા કારà«àª¡àª¨à«€ વિગતો શેર કરવામાં આવશે.</translation>
<translation id="7542995811387359312">આપમેળે કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡ ભરણ અકà«àª·àª® કરà«àª¯à«àª‚ છે કારણ કે આ ફોરà«àª® સà«àª°àª•à«àª·àª¿àª¤ કનેકà«àª¶àª¨àª¨à«‹ ઉપયોગ કરતà«àª‚ નથી.</translation>
<translation id="7543525346216957623">તમારા માતા-પિતાને કહો</translation>
<translation id="7549584377607005141">આ વેબપૃષà«àª àª¨à«‡ તે ડેટાની જરૂર છે જે તમે પહેલા બરાબર રીતે પà«àª°àª¦àª°à«àª¶àª¿àª¤ થાય તે માટે દાખલ કરà«àª¯à«‹ હતો. તમે આ ડેટા ફરીથી મોકલી શકો છો, પણ આમ કરીને તમે કોઈપણ કà«àª°àª¿àª¯àª¾ કે જે પૃષà«àª  પહેલા જ કરી ચà«àª•à«àª¯à«àª‚ છે તેનà«àª‚ પà«àª¨àª°àª¾àªµàª°à«àª¤àª¨ કરશો.</translation>
<translation id="7552846755917812628">નીચેની ટિપને અજમાવો:</translation>
<translation id="7554791636758816595">નવà«àª‚ ટૅબ</translation>
+<translation id="7567204685887185387">આ સરà«àªµàª° સાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° કપટપૂરà«àªµàª• રજૂ કરવામાં આવેલ હોઈ શકે છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> વધà«}one{<ph name="CONTACT_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> વધà«}other{<ph name="CONTACT_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> વધà«}}</translation>
<translation id="7568593326407688803">આ પૃષà«àª <ph name="ORIGINAL_LANGUAGE" />માં છે શà«àª‚ તમે તેને અનà«àªµàª¾àª¦àª¿àª¤ કરવા માંગો છો?</translation>
<translation id="7569952961197462199">Chrome માંથી કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡ દૂર કરીàª?</translation>
<translation id="7569983096843329377">શà«àª¯àª¾àª®</translation>
<translation id="7578104083680115302">તમે Google સાથે સાચવà«àª¯àª¾àª‚ છે તે કારà«àª¡à«àª¸àª¨à«‹ ઉપયોગ કરીને સમગà«àª° ઉપકરણોમાં સાઇટà«àª¸ અને àªàªªà«àª²àª¿àª•à«‡àª¶àª¨à«‹ પર àªàª¡àªªàª¥à«€ ચà«àª•àªµàª£à«€ કરો.</translation>
<translation id="7588950540487816470">વાસà«àª¤àªµàª¿àª• વેબ</translation>
<translation id="7592362899630581445">સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª°, નામ નિગà«àª°àª¹à«‹àª¨à«àª‚ ઉલà«àª²àª‚ઘન કરે છે.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> કરતા ઓછà«àª‚</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" />, હાલમાં આ વિનંતીને હેનà«àª¡àª² કરવામાં અસમરà«àª¥ છે.</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> નà«àª‚ કà«àª¯àª¾àª°à«‡àª¯ અનà«àªµàª¾àª¦ કરશો નહીં</translation>
<translation id="7610193165460212391">મૂલà«àª¯ <ph name="VALUE" /> શà«àª°à«‡àª£à«€ બહારનà«àª‚ છે.</translation>
<translation id="7613889955535752492">સમાપà«àª¤àª¿: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">તમારી પાસે પેહલાથી જ ડેટા છે જે તમારા Google àªàª•àª¾àª‰àª¨à«àªŸ પાસવરà«àª¡àª¨àª¾ વિવિધ સંસà«àª•àª°àª£à«‹àª‚નો ઉપયોગ કરીને àªàª¨à«àª•à«àª°àª¿àªªà«àªŸ કરેલો છે. </translation>
-<translation id="7634554953375732414">આ સાઇટ પરનà«àª‚ તમારà«àª‚ કનેકà«àª¶àª¨ ખાનગી નથી.</translation>
<translation id="7637571805876720304">Chromium માંથી કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡ દૂર કરીàª?</translation>
<translation id="765676359832457558">વિગતવાર સેટિંગà«àª¸ છà«àªªàª¾àªµà«‹...</translation>
<translation id="7658239707568436148">રદ કરો</translation>
+<translation id="7662298039739062396">àªàª•à«àª¸àªŸà«‡àª¨à«àª¶àª¨ દà«àªµàª¾àª°àª¾ સેટિંગ નિયંતà«àª°àª¿àª¤ કરેલ છે</translation>
<translation id="7667346355482952095">પરત થયેલ નીતિ ટોકન ખાલી છે અથવા વરà«àª¤àª®àª¾àª¨ ટોકન સાથે મેળ ખાતà«àª‚ નથી</translation>
<translation id="7668654391829183341">અજà«àªžàª¾àª¤ ઉપકરણ</translation>
<translation id="7669271284792375604">આ સાઇટ પરના હà«àª®àª²àª¾àª–ોરો તમને તમારા બà«àª°àª¾àª‰àªàª¿àª‚ગ અનà«àª­àªµàª¨à«‡ નà«àª•àª¸àª¾àª¨ પહોંચાડે àªàªµàª¾ પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ ઇનà«àª¸à«àªŸà«‰àª² કરવા માટે છેતરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે (ઉદાહરણ તરીકે, તમારà«àª‚ હોમપેજ બદલીને અથવા તમે મà«àª²àª¾àª•àª¾àª¤ લો છો તે સાઇટà«àª¸ પર વધૠપડતી જાહેરાતો બતાવીને).</translation>
<translation id="7674629440242451245">શà«àª‚ કૂલ નવી Chrome સà«àªµàª¿àª§àª¾àª“માં રà«àªšàª¿ ધરાવો છો? chrome.com/dev પર અમારી dev ચૅનલ અજમાવી જà«àª“.</translation>
<translation id="7682287625158474539">શિપિંગ</translation>
+<translation id="7701040980221191251">કોઈ નહીં</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" /> પર આગળ વધો (અસલામત)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">પà«àª°àª®àª¾àª£àªªàª¤à«àª°</translation>
+<translation id="7716147886133743102">વà«àª¯àªµàª¸à«àª¥àª¾àªªàª• દà«àªµàª¾àª°àª¾ અવરોધિત કરેલ છે</translation>
<translation id="7716424297397655342">કૅશમાંથી આ સાઇટ લોડ કરી શકાતી નથી</translation>
-<translation id="7733391738235763478">( <ph name="NUMBER_VISITS" /> )</translation>
<translation id="7752995774971033316">બિનસંચાલિત</translation>
<translation id="7755287808199759310">તમારા માટે તમારા માતાપિતા તેને અનાવરોધિત કરી શકે છે</translation>
<translation id="7758069387465995638">ફાયરવોલ અથવા àªàª¨à«àªŸàª¿àªµàª¾àª¯àª°àª¸ સોફà«àªŸàªµà«‡àª° ઠકનેકà«àª¶àª¨ અવરોધિત કરà«àª¯à«àª‚ હોઈ શકે છે.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32-બિટ)</translation>
<translation id="7956713633345437162">મોબાઇલ બà«àª•àª®àª¾àª°à«àª•à«àª¸</translation>
<translation id="7961015016161918242">કà«àª¯àª¾àª°à«‡àª¯ નહીં</translation>
-<translation id="7962083544045318153">કà«àª°à«‡àª¶ ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">હંમેશા <ph name="ORIGINAL_LANGUAGE" /> નà«àª‚ <ph name="TARGET_LANGUAGE" /> માં ભાષાંતર કરો</translation>
<translation id="7995512525968007366">નિરà«àª¦àª¿àª·à«àªŸ કરાયેલ નથી</translation>
<translation id="800218591365569300">મેમરી ખાલી કરવા માટે અનà«àª¯ ટૅબ અથવા પà«àª°à«‹àª—à«àª°àª¾àª®àª¨à«‡ બંધ કરવાનો પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="8012647001091218357">અમે આ પળે તમારા વાલીઓ સà«àª§à«€ પહોંચી શકà«àª¯àª¾àª‚ નથી. કૃપા કરીને ફરી પà«àª°àª¯àª¾àª¸ કરો.</translation>
<translation id="8025119109950072390">આ સાઇટ પરના હà«àª®àª²àª¾àª–ોરો તમારી વà«àª¯àª•à«àª¤àª¿àª—ત માહિતી (ઉદાહરણ તરીકે, પાસવરà«àª¡à«àª¸, ફોન નંબરà«àª¸ અથવા કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸) ને દરà«àª¶àª¾àªµàªµàª¾ અથવા સોફà«àªŸàªµà«‡àª° ઇનà«àª¸à«àªŸà«‰àª² કરવા જેવી જોખમી વસà«àª¤à«àª“ને કરવા માટે તમને છેતરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે.</translation>
-<translation id="803030522067524905">Google સલામત બà«àª°àª¾àª‰àªàª¿àª‚ગને તાજેતરમાં <ph name="SITE" /> પર ફિશિંગ મળà«àª¯à«àª‚. ફિશિંગ સાઇટà«àª¸ તમને છેતરવા માટે અનà«àª¯ વેબસાઇટà«àª¸ હોવાનો ડોળ કરે છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">આ પૃષà«àª  <ph name="SOURCE_LANGUAGE" /> માં છે. શà«àª‚ તેનો અનà«àªµàª¾àª¦ <ph name="TARGET_LANGUAGE" /> માં કરીàª?</translation>
+<translation id="8037357227543935929">પૂછો (ડિફૉલà«àªŸ)</translation>
<translation id="8041089156583427627">પà«àª°àª¤àª¿àª¸àª¾àª¦ મોકલો</translation>
+<translation id="8041940743680923270">વૈશà«àªµàª¿àª• ડિફોલà«àªŸàª¨à«‹ ઉપયોગ કરો (કહો)</translation>
<translation id="8088680233425245692">લેખ જોવામાં નિષà«àª«àª³ થયાં.</translation>
<translation id="8089520772729574115">1 MB કરતાં ઓછà«àª‚</translation>
<translation id="8091372947890762290">સકà«àª°àª¿àª¯àª¤àª¾ સરà«àªµàª° પર બાકી છે</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> નà«àª‚ સરà«àªµàª° <ph name="BEGIN_ABBR" />DNS સરનામà«àª‚<ph name="END_ABBR" /> શોધી શકાયà«àª‚ નથી.</translation>
<translation id="8149426793427495338">તમારà«àª‚ કમà«àªªà«àª¯à«àªŸàª° નિષà«àª•à«àª°àª¿àª¯ થઈ ગયà«àª‚ હતà«àª‚.</translation>
<translation id="8150722005171944719"><ph name="URL" /> પરની ફાઇલ વાંચનયોગà«àª¯ નથી. તે દૂર કરવામાં, ખસેડવામાં આવી હોઈ શકે છે અથવા ફાઇલ પરવાનગીઓ àªàª•à«àª¸à«‡àª¸ કરવાથી અટકાવતી હોઈ શકે છે.</translation>
+<translation id="8184538546369750125">વૈશà«àªµàª¿àª• ડિફોલà«àªŸàª¨à«‹ ઉપયોગ કરો (મંજૂરી આપો)</translation>
+<translation id="8191494405820426728">સà«àª¥àª¾àª¨àª¿àª• કà«àª°à«‡àª¶ ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;ખસેડવà«àª‚ પૂરà«àªµàªµàª¤à«â€Œ કરો</translation>
<translation id="8201077131113104583">ID "<ph name="EXTENSION_ID" />" સાથેના àªàª•à«àª¸àªŸà«‡àª¨à«àª¶àª¨ માટે અમાનà«àª¯ અપડેટ URL.</translation>
<translation id="8202097416529803614">ઓરà«àª¡àª°àª¨à«‹ સારાંશ</translation>
<translation id="8218327578424803826">સોંપાયેલ સà«àª¥àª¾àª¨:</translation>
<translation id="8225771182978767009">આ કમà«àªªà«àª¯à«àªŸàª°àª¨à«‡ સેટ કરનાર વà«àª¯àª•à«àª¤àª¿àª આ સાઇટને અવરોધિત કરવાનà«àª‚ પસંદ કરà«àª¯à«àª‚ છે.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">હà«àª®àª²àª¾àª–ોરો હાલમાં <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પર છે તે તમારા કમà«àªªà«àª¯à«àªŸàª° પર તમારી માહિતી (ઉદાહરણ તરીકે, ફોટા, પાસવરà«àª¡à«àª¸, સંદેશા અને કà«àª°à«‡àª¡àª¿àªŸ કારà«àª¡à«àª¸) ને ચોરી શકે કે કાઢી નાખે તેવા જોખમી પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸àª¨à«‡ ઇનà«àª¸à«àªŸà«‹àª² કરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે.</translation>
<translation id="8241707690549784388">તમારા દà«àªµàª¾àª°àª¾ દાખલ કરાયેલી વપરાયેલી માહિતી માટે આ પાનà«àª‚ તમે જોઈ રહà«àª¯àª¾ છો. તે પૃષà«àª  પર પાછા જવાથી àªàªµà«€ કોઈપણ કà«àª°àª¿àª¯àª¾ ફરીથી થઈ શકે છે જે તમે પહેલા કરી હતી. શà«àª‚ તમે ચાલૠરાખવા માંગો છો?</translation>
<translation id="8249320324621329438">છેલà«àª²à«àª‚ આનયન:</translation>
<translation id="8253091569723639551">બિલિંગ સરનામà«àª‚ આવશà«àª¯àª•</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">આ શà«àª‚ છે તે ખાતરીપૂરà«àªµàª• જાણતા ન હો તો તમારા નેટવરà«àª• વà«àª¯àªµàª¸à«àª¥àª¾àªªàª•àª¨à«‹ સંપરà«àª• કરો.</translation>
<translation id="8293206222192510085">બà«àª•àª®àª¾àª°à«àª• ઉમેરો</translation>
<translation id="8294431847097064396">સà«àª°à«‹àª¤</translation>
+<translation id="8306404619377842860"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> સાથે ખાનગી કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરી શકાતà«àª‚ નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) ખોટા છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">નેટવરà«àª• કનેકà«àª¶àª¨àª®àª¾àª‚ સમસà«àª¯àª¾àª¨à«‡ કારણે ભાષાંતર નિષà«àª«àª³ રહà«àª¯à«àª‚.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ની àªàª•à«àª¸à«‡àª¸ નકારાઈ હતી</translation>
<translation id="834457929814110454">જો તમે તમારી સà«àª°àª•à«àª·àª¾àª¨àª¾ જોખમોને સમજો છો, તો તમે જોખમી પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ દૂર કરી દેવામાં આવે તે પહેલાં <ph name="BEGIN_LINK" />આ સાઇટની મà«àª²àª¾àª•àª¾àª¤<ph name="END_LINK" /> લઈ શકો છો.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">તમારા Google àªàª•àª¾àª‰àª¨à«àªŸàª®àª¾àª‚થી કારà«àª¡à«àª¸àª¨à«‹ ઉપયોગ કરવા માટે, Chrome માં સાઇન ઇન કરો</translation>
<translation id="8488350697529856933">આમને લાગà«</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ઠપà«àª°àª¤àª¿àª¸àª¾àª¦ આપવા માટે ઘણો સમય લીધો.</translation>
-<translation id="852346902619691059">આ સરà«àªµàª° ઠસાબિત કરી શકà«àª¯à«àª‚ નથી કે તે <ph name="DOMAIN" /> છે; તેનà«àª‚ સà«àª°àª•à«àª·àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª° તમારા ઉપકરણની ઓપરેટિંગ સિસà«àªŸàª® દà«àªµàª¾àª°àª¾ વિશà«àªµàª¸àª¨à«€àª¯ નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયà«àª‚ હશે અથવા કોઈ હà«àª®àª²àª¾àª–ોર તમારા કનેકà«àª¶àª¨àª¨à«‡ અટકાવી રહà«àª¯à«‹ છે. <ph name="BEGIN_LEARN_MORE_LINK" />વધૠજાણો<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">સમય સમાપà«àª¤àª¿ વરà«àª·</translation>
<translation id="8543181531796978784">તમે <ph name="BEGIN_ERROR_LINK" />શોધ સમસà«àª¯àª¾àª¨à«€ જાણ<ph name="END_ERROR_LINK" /> કરી શકો છો અથવા જો તમે તમારી સà«àª°àª•à«àª·àª¾ અંગેનાં જોખમોને સમજતાં હોવ, તો <ph name="BEGIN_LINK" />આ અસà«àª°àª•à«àª·àª¿àª¤ સાઇટની મà«àª²àª¾àª•àª¾àª¤<ph name="END_LINK" /> લઈ શકો છો.</translation>
<translation id="8553075262323480129">ભાષાંતર નિષà«àª«àª³ રહà«àª¯à«àª‚ કારણ કે પૃષà«àª àª¨à«€ ભાષા નિરà«àª§àª¾àª°àª¿àª¤ થઈ શકી નથી.</translation>
-<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> પર ખાનગી કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરી શકાતà«àª‚ નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) અયોગà«àª¯ છે.</translation>
<translation id="8571890674111243710">પૃષà«àª àª¨à«‡ <ph name="LANGUAGE" /> માં અનà«àªµàª¾àª¦àª¿àª¤ કરી રહà«àª¯à«àª‚ છે...</translation>
<translation id="858637041960032120">ફોન નંબર ઉમેરો</translation>
<translation id="859285277496340001">પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«‡ રદ કરવામાં આવà«àª¯à«àª‚ છે કે નહિ તે તપાસવા માટે કોઈપણ મેકેનિàªàª® નિરà«àª¦àª¿àª·à«àªŸ કરતà«àª‚ નથી.</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">àªàª• સà«àª°àª•à«àª·àª¿àª¤ કનેકà«àª¶àª¨ સà«àª¥àª¾àªªàª¿àª¤ કરવા માટે, તમારà«àª‚ ઘડિયાળ યોગà«àª¯ રીતે સેટ હોવà«àª‚ જરૂરી છે. આનà«àª‚ કારણ ઠકે વેબસાઇટà«àª¸ તેઓને ઓળખવા માટે જે પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹àª¨à«‹ ઉપયોગ કરે છે તે ચોકà«àª•àª¸ સમય અવધિ માટે જ માનà«àª¯ હોય છે. તમારા ઉપકરણની ઘડિયાળ ખોટી હોવાને લીધે, Chromium આ પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹àª¨à«‡ ચકાસી શકતà«àª‚ નથી.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> નà«àª‚ &lt;abbr id="dnsDefinition"&gt;DNS સરનામà«àª‚&lt;/abbr&gt; શોધી શકાયà«àª‚ નથી. સમસà«àª¯àª¾àª¨à«àª‚ નિદાન કરી રહà«àª¯àª¾àª‚ છીàª.</translation>
<translation id="8759274551635299824">આ કારà«àª¡àª¨à«€ સમયસીમા સમાપà«àª¤ થઈ ગઈ છે</translation>
+<translation id="8761567432415473239">Google Safe Browsing ને તાજેતરમાં <ph name="SITE" /> પર <ph name="BEGIN_LINK" />હાનિકારક પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ મળà«àª¯àª¾àª‚<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;કાઢી નાખવà«àª‚ ફરી કરો</translation>
<translation id="8800988563907321413">તમારા નજીકના સૂચનો અહીં દેખાય છે</translation>
<translation id="8820817407110198400">બà«àª•àª®àª¾àª°à«àª•à«àª¸</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">તાજેતરમાં બંધ કરેલા</translation>
<translation id="8874824191258364635">àªàª• માનà«àª¯ કારà«àª¡ નંબર દાખલ કરો</translation>
<translation id="8876793034577346603">નેટવરà«àª• ગોઠવણી વિશà«àª²à«‡àª·àª¿àª¤ થવામાં નિષà«àª«àª³ થઇ.</translation>
-<translation id="8877192140621905067">àªàª•àªµàª¾àª° તમે પà«àª·à«àªŸàª¿ કરી લો તે પછી, આ સાઇટ સાથે તમારા કારà«àª¡àª¨à«€ વિગતો શેર કરવામાં આવશે</translation>
<translation id="8889402386540077796">હà«àª¯à«</translation>
<translation id="8891727572606052622">અમાનà«àª¯ પà«àª°à«‹àª•à«àª¸à«€ મોડ.</translation>
<translation id="889901481107108152">માફ કરશો, આ પà«àª°àª¯à«‹àª— તમારા પà«àª²à«‡àªŸàª«à«‹àª°à«àª® પર ઉપલબà«àª§ નથી.</translation>
<translation id="8903921497873541725">àªà«‚મ વધારો</translation>
<translation id="8931333241327730545">શà«àª‚ તમે આ કારà«àª¡àª¨à«‡ તમારા Google àªàª•àª¾àª‰àª¨à«àªŸàª®àª¾àª‚ સાચવવા માગો છો?</translation>
<translation id="8932102934695377596">તમારી ઘડિયાળ પાછળ છે</translation>
-<translation id="8954894007019320973">(ચાલà«.)</translation>
<translation id="8971063699422889582">સરà«àªµàª°àª¨àª¾ પà«àª°àª®àª¾àª£àªªàª¤à«àª°àª¨à«€ સમયસીમા સમાપà«àª¤ થઈ છે.</translation>
<translation id="8986494364107987395">ઉપયોગિતા આંકડાઓ અને કà«àª°à«‡àª¶ રિપોરà«àªŸà«àª¸ Google ને આપમેળે મોકલો</translation>
-<translation id="8987927404178983737">મહિનો</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">સાઇટમાં આગળ હાનિકારક પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ છે</translation>
+<translation id="8997023839087525404">સરà«àªµàª°à«‡ àªàªµà«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚ કે જે પà«àª°àª®àª¾àª£àªªàª¤à«àª° પારદરà«àª¶àª¿àª¤àª¾ નીતિનો ઉપયોગ કરીને સારà«àªµàªœàª¨àª¿àª• રીતે જાહેર કરà«àª¯à«àª‚ ન હતà«àª‚. આ કેટલાક પà«àª°àª®àª¾àª£àªªàª¤à«àª°à«‹ માટે ઠખાતરી કરવા હેતૠઆવશà«àª¯àª• છે કે તેઓ વિશà«àªµàª¸àª¨à«€àª¯ છે અને હà«àª®àª²àª¾àª–ારો સામે રકà«àª·àª£ કરે છે.</translation>
<translation id="9001074447101275817">પà«àª°à«‹àª•à«àª¸à«€ <ph name="DOMAIN" /> ને વપરાશકરà«àª¤àª¾àª¨àª¾àª® અને પાસવરà«àª¡àª¨à«€ જરૂર છે.</translation>
+<translation id="9005998258318286617">PDF દસà«àª¤àª¾àªµà«‡àªœ લોડ કરવામાં નિષà«àª«àª³ થયાં.</translation>
<translation id="901974403500617787">ધà«àªµàªœà«‹ કે જે સિસà«àªŸàª®-વà«àª¯àª¾àªªà«€ લાગૠછે તે ફકà«àª¤ માલિક દà«àªµàª¾àª°àª¾ જ સેટ કરી શકાય છે: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">કારà«àª¡àª¨à«àª‚ બિલિંગ સરનામà«àª‚ આવશà«àª¯àª• છે</translation>
<translation id="9020542370529661692">આ પૃષà«àª àª¨à«‹ <ph name="TARGET_LANGUAGE" /> માં અનà«àªµàª¾àª¦ કરવામાં આવà«àª¯à«‹ છે</translation>
<translation id="9035022520814077154">સà«àª°àª•à«àª·àª¾ ભૂલ</translation>
<translation id="9038649477754266430">પૃષà«àª à«‹àª¨à«‡ વધૠàªàª¡àªªàª¥à«€ લોડ કરવા માટે પૂરà«àªµàª¾àª¨à«àª®àª¾àª¨ સેવાનો ઉપયોગ કરો</translation>
<translation id="9039213469156557790">વળી, આ પૃષà«àª àª®àª¾àª‚ અનà«àª¯ àªàªµàª¾ સાધનો છે જે સà«àª°àª•à«àª·àª¿àª¤ નથી. ટà«àª°àª¾àª‚àªàª¿àªŸàª®àª¾àª‚ હોવા પર અનà«àª¯ લોકો દà«àªµàª¾àª°àª¾ આ સાધનો જોઈ શકાય છે અને પૃષà«àª àª¨à«‹ વà«àª¯àªµàª¹àª¾àª° બદલવા માટે હà«àª®àª²àª¾àª–ોર દà«àªµàª¾àª°àª¾ સંશોધિત કરવામાં આવી શકે છે.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> પરનાં હà«àª®àª²àª¾àª–ોરો તમને àªàªµàª¾ પà«àª°à«‹àª—à«àª°àª¾àª®à«àª¸ ઇનà«àª¸à«àªŸà«‹àª² કરવા માટે ભà«àª°àª®àª¿àª¤ કરવાનો પà«àª°àª¯àª¾àª¸ કરી શકે છે જે તમારા બà«àª°àª¾àª‰àªàª¿àª‚ગ અનà«àª­àªµàª¨à«‡ નà«àª•àª¸àª¾àª¨ પહોંચાડે છે (ઉદાહરણ તરીકે, તમારà«àª‚ હોમપેજ બદલીને અથવા તમે મà«àª²àª¾àª•àª¾àª¤ લો છો તે સાઇટà«àª¸ પર વધૠપડતી જાહેરાતો દરà«àª¶àª¾àªµà«€àª¨à«‡).</translation>
+<translation id="9049981332609050619">તમે <ph name="DOMAIN" /> સà«àª§à«€ પહોંચવાનો પà«àª°àª¯àª¾àª¸ કરà«àª¯à«‹, પરંતૠસરà«àªµàª°à«‡ અમાનà«àª¯ પà«àª°àª®àª¾àª£àªªàª¤à«àª° પà«àª°àª¸à«àª¤à«àª¤ કરà«àª¯à«àª‚. </translation>
<translation id="9050666287014529139">પાસફà«àª°à«‡àª</translation>
<translation id="9065203028668620118">સંપાદન</translation>
<translation id="9068849894565669697">રંગ પસંદ કરો</translation>
+<translation id="9069693763241529744">àªàª•à«àª¸à«àªŸà«‡àª¨à«àª¶àª¨ દà«àªµàª¾àª°àª¾ અવરોધિત કરેલ છે</translation>
<translation id="9076283476770535406">તેમાં વયસà«àª• સામગà«àª°à«€ હોઈ શકે છે</translation>
<translation id="9078964945751709336">વધૠમાહિતી આવશà«àª¯àª•</translation>
<translation id="9103872766612412690"><ph name="SITE" /> સામાનà«àª¯ રીતે તમારી માહિતીને સà«àª°àª•à«àª·àª¿àª¤ રાખવા માટે àªàª¨à«àª•à«àª°àª¿àªªà«àª¶àª¨àª¨à«‹ ઉપયોગ કરે છે. જà«àª¯àª¾àª°à«‡ આ સમયે Chromium દà«àªµàª¾àª°àª¾ <ph name="SITE" /> થી કનેકà«àªŸ કરવાનો પà«àª°àª¯àª¾àª¸ થયો, તà«àª¯àª¾àª°à«‡ વેબસાઇટે અસામાનà«àª¯ અને ખોટા ઓળખાણપતà«àª°à«‹àª¨à«‡ પાછા મોકલà«àª¯àª¾àª‚. આવà«àª‚ તà«àª¯àª¾àª°à«‡ થઇ શકે જà«àª¯àª¾àª°à«‡ કોઈ હà«àª®àª²àª¾àª–ોર <ph name="SITE" /> હોવાનો ડોળ કરવાનો પà«àª°àª¯àª¾àª¸ કરી રહà«àª¯à«‹ હોય અથવા કોઈ Wi-Fi સાઇન-ઇન સà«àª•à«àª°à«€àª¨à«‡ કનેકà«àª¶àª¨àª®àª¾àª‚ વિકà«àª·à«‡àªª પાડà«àª¯à«‹ હોય. તમારી માહિતી હજી પણ સà«àª°àª•à«àª·àª¿àª¤ છે કારણ કે Chromium ઠકોઈપણ ડેટા વિનિમય થાય તે પહેલાં જ કનેકà«àª¶àª¨ રોકી દીધà«àª‚.</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">&amp;સંપાદિત કરવà«àª‚ પૂરà«àªµàªµàª¤à«â€Œ કરો</translation>
<translation id="9154194610265714752">અપડેટેડ</translation>
<translation id="9157595877708044936">સેટિંગ અપ...</translation>
+<translation id="9169664750068251925">હંમેશા આ સાઇટ પર અવરોધિત કરો</translation>
<translation id="9170848237812810038">&amp;પૂરà«àªµàªµàª¤à« કરો</translation>
<translation id="917450738466192189">સરà«àªµàª°àª¨à«àª‚ પà«àª°àª®àª¾àª£àªªàª¤à«àª° અમાનà«àª¯ છે.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> વધà«}one{<ph name="SHIPPING_OPTION_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> વધà«}other{<ph name="SHIPPING_OPTION_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> વધà«}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" />, àªàª• અસમરà«àª¥àª¿àª¤ પà«àª°à«‹àªŸà«‹àª•à«‹àª²àª¨à«‹ ઉપયોગ કરે છે.</translation>
<translation id="9205078245616868884">તમારો ડેટા તમારા સમનà«àªµàª¯àª¨ પાસફà«àª°à«‡àª સાથે àªàª¨à«àª•à«àª°àª¿àªªà«àªŸ કરવામાં આવà«àª¯à«‹ છે. સમનà«àªµàª¯àª¨ શરૂ કરવા માટે તે દાખલ કરો.</translation>
<translation id="9207861905230894330">લેખ ઉમેરવામાં નિષà«àª«àª³ થયાં.</translation>
+<translation id="9219103736887031265">છબીઓ</translation>
<translation id="933612690413056017">કોઈ ઇનà«àªŸàª°àª¨à«‡àªŸ કનેકà«àª¶àª¨ નથી</translation>
<translation id="933712198907837967">ડાઇનરà«àª¸ કà«àª²àª¬</translation>
<translation id="935608979562296692">ફોરà«àª® સાફ કરો</translation>
<translation id="939736085109172342">નવà«àª‚ ફોલà«àª¡àª°</translation>
<translation id="941721044073577244">àªàªµà«àª‚ લાગે છે કે તમને આ સાઇટની મà«àª²àª¾àª•àª¾àª¤ લેવા માટેની પરવાનગી નથી</translation>
<translation id="969892804517981540">આધિકારિક બિલà«àª¡</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{કોઈ નહીં}=1{1 આઇટમ}one{# આઇટમ}other{# આઇટમ}}</translation>
<translation id="988159990683914416">વિકાસકરà«àª¤àª¾ બિલà«àª¡</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_hi.xtb b/chromium/components/strings/components_strings_hi.xtb
index 6d64e70566d..9e86d87d351 100644
--- a/chromium/components/strings/components_strings_hi.xtb
+++ b/chromium/components/strings/components_strings_hi.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">घड़ी की दिशा में घà¥à¤®à¤¾à¤à¤‚</translation>
<translation id="1038842779957582377">अजà¥à¤žà¤¾à¤¤ नाम</translation>
<translation id="1050038467049342496">दूूूूसरे à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ बंद करें</translation>
-<translation id="1053591932240354961">आप इस समय <ph name="SITE" /> पर विज़िट नहीं कर सकते कà¥à¤¯à¥‹à¤‚कि वेबसाइट ने à¤à¤¸à¥‡ अवà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल भेजे हैं जिनà¥à¤¹à¥‡à¤‚ Google Chrome संसाधित नहीं कर सकता. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर असà¥à¤¥à¤¾à¤¯à¥€ होते हैं, इसलिठसंभवत: यह पेज बाद में काम करेगा. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;जोड़ना वापस लाà¤à¤‚</translation>
<translation id="10614374240317010">कभी नहीं सहेजा गया</translation>
<translation id="106701514854093668">डेसà¥à¤•à¤Ÿà¥‰à¤ª बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">नीति संचय ठीक है</translation>
<translation id="113188000913989374"><ph name="SITE" /> का कहना है:</translation>
<translation id="1132774398110320017">Chrome ऑटोमैटिक भरने वाली सेटिंग...</translation>
+<translation id="1150979032973867961">यह सरà¥à¤µà¤° यह नहीं पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपके कंपà¥à¤¯à¥‚टर के ऑपरेटिंग सिसà¥à¤Ÿà¤® दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¥žà¤¿à¤—रेशन या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="1151972924205500581">पासवरà¥à¤¡ आवशà¥à¤¯à¤•</translation>
<translation id="1152921474424827756"><ph name="URL" /> की <ph name="BEGIN_LINK" />संचित पà¥à¤°à¤¤à¤¿<ph name="END_LINK" /> à¤à¤•à¥à¤¸à¥‡à¤¸ करें</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ने अनपेकà¥à¤·à¤¿à¤¤ रूप से कनेकà¥à¤¶à¤¨ बंद कर दिया है.</translation>
<translation id="1161325031994447685">वाई-फ़ाई से फिर से कनेकà¥à¤Ÿ करें</translation>
+<translation id="1165039591588034296">गड़बड़ी</translation>
<translation id="1175364870820465910">&amp;पà¥à¤°à¤¿à¤‚ट करें...</translation>
<translation id="1181037720776840403">निकालें</translation>
<translation id="1184214524891303587">Google को संभावित सà¥à¤°à¤•à¥à¤·à¤¾ घटनाओं के विवरण की <ph name="BEGIN_WHITEPAPER_LINK" />अपने आप रिपोरà¥à¤Ÿ करें<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">इस साइट की ओर से अधिक</translation>
<translation id="1206967143813997005">नाम के पहले अकà¥à¤·à¤° के गलत हसà¥à¤¤à¤¾à¤•à¥à¤·à¤°</translation>
<translation id="1209206284964581585">अभी छिपाà¤à¤‚</translation>
+<translation id="121201262018556460">आपने <ph name="DOMAIN" /> तक पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन लेकिन सरà¥à¤µà¤° ने कमज़ोर कà¥à¤‚जी वाला पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥â€à¤¤à¥à¤¤ किया. संभवत: हमलावर ने निजी कà¥à¤‚जी का पता लगा लिया है, और हो सकता है कि सरà¥à¤µà¤° आपका अपेकà¥à¤·à¤¿à¤¤ सरà¥à¤µà¤° न हो (हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों).</translation>
<translation id="1219129156119358924">सिसà¥â€à¤Ÿà¤® सà¥à¤°à¤•à¥à¤·à¤¾</translation>
<translation id="1227224963052638717">अजà¥à¤žà¤¾à¤¤ नीति.</translation>
<translation id="1227633850867390598">मान छिपाà¤à¤‚</translation>
<translation id="1228893227497259893">गलत इकाई पहचानकरà¥à¤¤à¤¾</translation>
<translation id="1232569758102978740">शीरà¥à¤·à¤• रहित</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (सिंक किठगà¤)</translation>
<translation id="1263231323834454256">पठन सूची</translation>
<translation id="1264126396475825575">ख़राबी रिपोरà¥à¤Ÿ <ph name="CRASH_TIME" /> पर कैपà¥à¤šà¤° की गई (अभी तक अपलोड नहीं की गई या उसे अनदेखा किया गया)</translation>
+<translation id="1281526147609854549"><ph name="ISSUER" /> ने जारी किया है</translation>
+<translation id="1283919782143846010">खतरनाक सामगà¥à¤°à¥€ बà¥à¤²à¥‰à¤• की गई</translation>
<translation id="1285320974508926690">कभी भी इस साइट का अनà¥à¤µà¤¾à¤¦ न करें</translation>
<translation id="129553762522093515">हाल ही में बंद किठगà¤</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />अपनी कà¥à¤•à¥€ साफ़ करके देखें<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">आपकी गतिविधि इनà¥à¤¹à¥‡à¤‚ <ph name="BEGIN_EMPHASIS" />अभी भी दिखाई दे सकती है<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />जिन वेबसाइट पर आप जाते हैं
+ <ph name="LIST_ITEM" />आपका नियोकà¥à¤¤à¤¾ या विदà¥à¤¯à¤¾à¤²à¤¯
+ <ph name="LIST_ITEM" />आपका इंटरनेट सेवा पà¥à¤°à¤¦à¤¾à¤¤à¤¾
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">नामांकन डोमेन:</translation>
<translation id="1340482604681802745">पिकअप पता</translation>
<translation id="1344211575059133124">à¤à¤¸à¤¾ लगता है कि आपको इस साइट पर जाने की अनà¥à¤®à¤¤à¤¿ लेनी होगी</translation>
<translation id="1344588688991793829">कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® ऑटोमैटिक भरने वाली सेटिंग...</translation>
+<translation id="1348198688976932919">आगे आने वाली साइट में खतरनाक à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ हैं</translation>
<translation id="1374468813861204354">सà¥à¤à¤¾à¤µ</translation>
<translation id="1375198122581997741">वरà¥à¤¶à¤¨ के बारे में</translation>
<translation id="1377321085342047638">कारà¥à¤¡ नंबर</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ने कोई डेटा नहीं भेजा.</translation>
-<translation id="1407135791313364759">सभी खोलें</translation>
+<translation id="1407135791313364759">सभी बà¥à¤•à¤®à¤¾à¤°à¥à¤• खोलें</translation>
<translation id="1413809658975081374">निजता गड़बड़ी</translation>
+<translation id="14171126816530869"><ph name="ORGANIZATION" /> की पहचान <ph name="LOCALITY" /> में <ph name="ISSUER" /> दà¥à¤µà¤¾à¤°à¤¾ सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ की गई है.</translation>
<translation id="1426410128494586442">हां</translation>
<translation id="1430915738399379752">पà¥à¤°à¤¿à¤‚ट करें</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> के किसी पेज पर जाने का <ph name="END_LINK" /> पà¥à¤°à¤¯à¤¾à¤¸ अवरोधित किया गया.</translation>
-<translation id="1491663344921578213">आप इस समय <ph name="SITE" /> पर विज़िट नहीं कर सकते कà¥à¤¯à¥‹à¤‚कि वेबसाइट पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पिनिंग का उपयोग करती है. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर असà¥à¤¥à¤¾à¤¯à¥€ होते हैं, इसलिठसंभवत: यह पेज बाद में काम करेगा. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> अनà¥à¤¯}one{<ph name="PAYMENT_METHOD_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> अनà¥à¤¯}other{<ph name="PAYMENT_METHOD_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> अनà¥à¤¯}}</translation>
<translation id="1506687042165942984">इस पृषà¥â€à¤  की सहेजी गई (अरà¥à¤¥à¤¾à¤¤ जिसे पà¥à¤°à¤¾à¤¨à¤¾ माना जाता है) कॉपी दिखाà¤à¤‚.</translation>
<translation id="1517433312004943670">फ़ोन नंबर आवशà¥à¤¯à¤• है</translation>
<translation id="1519264250979466059">बिलà¥à¤¡ दिनांक</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">इस सà¥à¤µà¤¿à¤§à¤¾ का उपयोग करने के लिठJavaScript को सकà¥à¤·à¤® किया जाना चाहिà¤.</translation>
<translation id="1555130319947370107">नीला</translation>
<translation id="1559528461873125649">कोई à¤à¤¸à¥€ फ़ाइल या निरà¥à¤¦à¥‡à¤¶à¤¿à¤•à¤¾ नहीं है</translation>
-<translation id="1559572115229829303">&lt;p&gt;<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से निजी कनेकà¥â€à¤¶à¤¨ सà¥â€à¤¥à¤¾à¤ªà¤¿à¤¤ नहीं किया जा सकता कà¥â€à¤¯à¥‹à¤‚कि आपके डिवाइस का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.&lt;/p&gt;
-
- &lt;p&gt;कृपया दिनांक और समय को &lt;strong&gt;सेटिंग&lt;/strong&gt; à¤à¤ª के &lt;strong&gt;सामानà¥â€à¤¯&lt;/strong&gt; अनà¥à¤­à¤¾à¤— से à¤à¤¡à¤œà¤¸à¥â€à¤Ÿ करें.&lt;/p&gt;</translation>
<translation id="1583429793053364125">यह वेबपेज पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ करते समय कोई समसà¥à¤¯à¤¾ हà¥à¤ˆ.</translation>
<translation id="1592005682883173041">सà¥à¤¥à¤¾à¤¨à¥€à¤¯ डेटा à¤à¤•à¥à¤¸à¥‡à¤¸</translation>
+<translation id="1594030484168838125">चà¥à¤¨à¥‡à¤‚</translation>
<translation id="161042844686301425">सà¥à¤¯à¤¾à¤¨</translation>
+<translation id="1620510694547887537">कैमरा</translation>
<translation id="1629803312968146339">कà¥à¤¯à¤¾ आप चाहते हैं कि Chrome इस कारà¥à¤¡ को सहेजे?</translation>
<translation id="1639239467298939599">लोड हो रहा है</translation>
<translation id="1640180200866533862">उपयोगकरà¥à¤¤à¤¾ नीतियां</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">नेटवरà¥à¤• कॉनà¥à¤«à¤¼à¤¿à¤—रेशन अमानà¥à¤¯ है और उसे आयात नहीं किया जा सकेगा.</translation>
<translation id="1644574205037202324">इतिहास</translation>
<translation id="1645368109819982629">असमरà¥à¤¥à¤¿à¤¤ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•à¥‰à¤²</translation>
+<translation id="1655462015569774233">{1,plural, =1{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की समय सीमा कल समापà¥à¤¤ हो गई थी. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ को बाधित करने के कारण हो सकता है. आपके कंपà¥à¤¯à¥‚टर की घड़ी वरà¥à¤¤à¤®à¤¾à¤¨ में <ph name="CURRENT_DATE" /> पर सेट है. कà¥â€à¤¯à¤¾ यह सही है? यदि नहीं, तो आपको अपने सिसà¥à¤Ÿà¤® की घड़ी सही करनी चाहिठऔर फिर इस पेज को रीफà¥à¤°à¥‡à¤¶ करना चाहिà¤.}one{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की समय सीमा # दिन पहले समापà¥à¤¤ हो गई है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ को बाधित करने के कारण हो सकता है. आपके कंपà¥à¤¯à¥‚टर की घड़ी वरà¥à¤¤à¤®à¤¾à¤¨ में <ph name="CURRENT_DATE" /> पर सेट है. कà¥â€à¤¯à¤¾ यह सही है? यदि नहीं, तो आपको अपने सिसà¥à¤Ÿà¤® की घड़ी सही करनी चाहिठऔर फिर इस पेज को रीफà¥à¤°à¥‡à¤¶ करना चाहिà¤.}other{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की समय सीमा # दिन पहले समापà¥à¤¤ हो गई है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ को बाधित करने के कारण हो सकता है. आपके कंपà¥à¤¯à¥‚टर की घड़ी वरà¥à¤¤à¤®à¤¾à¤¨ में <ph name="CURRENT_DATE" /> पर सेट है. कà¥â€à¤¯à¤¾ यह सही है? यदि नहीं, तो आपको अपने सिसà¥à¤Ÿà¤® की घड़ी सही करनी चाहिठऔर फिर इस पेज को रीफà¥à¤°à¥‡à¤¶ करना चाहिà¤.}}</translation>
<translation id="1656489000284462475">पिकअप</translation>
<translation id="1663943134801823270">कारà¥à¤¡ और पते Chrome से मिलते हैं. आप उनà¥à¤¹à¥‡à¤‚ <ph name="BEGIN_LINK" />सेटिंग<ph name="END_LINK" /> में पà¥à¤°à¤¬à¤‚धित कर सकते हैं.</translation>
<translation id="1676269943528358898">आपकी जानकारी की सà¥à¤°à¤•à¥à¤·à¤¾ करने के लिठ<ph name="SITE" /> आमतौर पर à¤à¤¨à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤¶à¤¨ का उपयोग करती है. जब Google Chrome ने इस बार <ph name="SITE" /> से कनेकà¥à¤Ÿ करने का पà¥à¤°à¤¯à¤¾à¤¸ किया, तो वेबसाइट ने असामानà¥à¤¯ और गलत कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल वापस भेजे. à¤à¤¸à¤¾ तब हो सकता है जब कोई हमलावर <ph name="SITE" /> होने का दावा करने का पà¥à¤°à¤¯à¤¾à¤¸ कर रहा हो या किसी वाई-फ़ाई पà¥à¤°à¤µà¥‡à¤¶ सà¥à¤•à¥à¤°à¥€à¤¨ ने कनेकà¥à¤¶à¤¨ को बाधित कर दिया हो. आपकी जानकारी अभी भी सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ है कà¥à¤¯à¥‹à¤‚कि किसी भी डेटा के आदान-पà¥à¤°à¤¦à¤¾à¤¨ से पहले ही Google Chrome ने कनेकà¥à¤¶à¤¨ को रोक दिया था.</translation>
-<translation id="168328519870909584"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपके डिवाइस पर à¤à¤¸à¥‡ खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने की कोशिश कर सकते हैं जो आपकी जानकारी (उदाहरण के लिà¤, फ़ोटो, पासवरà¥à¤¡, संदेश और कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) को चà¥à¤°à¤¾ लेते हैं या उसे हटा देते हैं.</translation>
<translation id="168841957122794586">सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° में कमज़ोर कà¥à¤°à¤¿à¤ªà¥à¤Ÿà¥‹à¤—à¥à¤°à¤¾à¤«à¤¼à¤¿à¤• कà¥à¤‚जी है.</translation>
+<translation id="1706954506755087368">{1,plural, =1{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° कल से माना जाà¤à¤—ा. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ को बाधित करने के कारण हो सकता है.}one{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° # दिन बाद से माना जाà¤à¤—ा. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ को बाधित करने के कारण हो सकता है.}other{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° # दिन बाद से माना जाà¤à¤—ा. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ को बाधित करने के कारण हो सकता है.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">आपको <ph name="NAME" /> से इस साइट पर जाने की अनà¥à¤®à¤¤à¤¿ लेनी होगी</translation>
<translation id="1721424275792716183">* फ़ीलà¥à¤¡ ज़रूरी है</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">पेज को बाद में डाउनलोड करें</translation>
<translation id="17513872634828108">टैब खोलें</translation>
<translation id="1753706481035618306">पृषà¥â€à¤  संखà¥â€à¤¯à¤¾</translation>
+<translation id="1763864636252898013">यह सरà¥à¤µà¤° यह नहीं पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपके डिवाइस के ऑपरेटिंग सिसà¥à¤Ÿà¤® दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¥žà¤¿à¤—रेशन या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows नेटवरà¥à¤• निदान चलाकर देखें<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">कृपया अपना समनà¥â€à¤µà¤¯à¤¨ पासफà¥à¤°à¥‡à¤œà¤¼ अपडेट करें.</translation>
<translation id="1787142507584202372">आपके दà¥à¤µà¤¾à¤°à¤¾ खोले गठटैब, यहां दिखाई देंगे</translation>
+<translation id="1789575671122666129">पॉपअप</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">कारà¥à¤¡ के मालिक का नाम</translation>
-<translation id="1803678881841855883">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को हाल ही में <ph name="SITE" /> पर <ph name="BEGIN_LINK" />मैलवेयर का पता चला<ph name="END_LINK" /> है. आमतौर पर सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ रहने वाली वेबसाइट कभी-कभी मैलवेयर से संकà¥à¤°à¤®à¤¿à¤¤ हो जाती हैं. दà¥à¤°à¥à¤­à¤¾à¤µà¤¨à¤¾à¤ªà¥‚रà¥à¤£ सामगà¥à¤°à¥€ <ph name="SUBRESOURCE_HOST" /> से आती है, जिसे जà¥à¤žà¤¾à¤¤ मैलवेयर वितरक कहा जाता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440"><ph name="ADDED_TO_AUTOFILL_MONTH" /> को जोड़ा गया</translation>
<translation id="1821930232296380041">अमानà¥à¤¯ अनà¥à¤°à¥‹à¤§ या अनà¥à¤°à¥‹à¤§ पैरामीटर</translation>
<translation id="1826516787628120939">जांच की जा रही है</translation>
<translation id="1834321415901700177">इस साइट में हानिकारक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® हैं</translation>
+<translation id="1840414022444569775">इस कारà¥à¤¡ नंबर का उपयोग पहले ही किया जा चà¥à¤•à¤¾ है</translation>
<translation id="1842969606798536927">भà¥à¤—तान करें</translation>
<translation id="1871208020102129563">पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ को फ़िकà¥â€à¤¸à¥â€à¤¡ पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ सरà¥à¤µà¤° का उपयोग करने के लिठसेट किया गया है, .pac सà¥â€à¤•à¥à¤°à¤¿à¤ªà¥â€à¤Ÿ फ़ाइल का उपयोग करने के लिठनहीं.</translation>
<translation id="1871284979644508959">आवशà¥à¤¯à¤• फ़ीलà¥à¤¡</translation>
<translation id="187918866476621466">शà¥à¤°à¥à¤†à¤¤à¥€ पनà¥à¤¨à¤¾ खोलें</translation>
<translation id="1883255238294161206">सूची संकà¥à¤·à¤¿à¤ªà¥à¤¤ करें</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> अनà¥à¤¯}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> अनà¥à¤¯}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> अनà¥à¤¯}}</translation>
<translation id="1898423065542865115">फ़िलà¥à¤Ÿà¤° किया जा रहा है</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{कà¥à¤› नहीं}=1{1 साइट}one{# साइट}other{# साइट}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> पर जाà¤à¤‚</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
<translation id="1973335181906896915">कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ करने में गड़बड़ी</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">धà¥à¤¯à¤¾à¤¨ नहीं दिया गया कà¥à¤¯à¥‹à¤‚कि यह <ph name="POLICY_NAME" /> दà¥à¤µà¤¾à¤°à¤¾ ओवरराइड की गई थी.</translation>
<translation id="2138201775715568214">आस-पास के जीते-जागते वेब पृषà¥â€à¤  खोजे जा रहे हैं</translation>
<translation id="213826338245044447">मोबाइल बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
-<translation id="2148716181193084225">आज</translation>
+<translation id="2147827593068025794">पृषà¥à¤ à¤­à¥‚मि समनà¥à¤µà¤¯à¤¨</translation>
<translation id="2154054054215849342">आपके डोमेन के लिठसिंक करने की सà¥à¤µà¤¿à¤§à¤¾ उपलबà¥â€à¤§ नहीं है</translation>
<translation id="2154484045852737596">कारà¥à¤¡ संपादित करें</translation>
<translation id="2166049586286450108">पूरà¥à¤£ वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤•à¥€à¤¯ à¤à¤•à¥à¤¸à¥‡à¤¸</translation>
<translation id="2166378884831602661">यह साइट सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥à¤¶à¤¨ पà¥à¤°à¤¦à¤¾à¤¨ नहीं कर सकती</translation>
<translation id="2181821976797666341">नीतियां</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 पता}one{# पते}other{# पते}}</translation>
+<translation id="2187317261103489799">पता लगाà¤à¤‚ (डिफ़ॉलà¥à¤Ÿ)</translation>
<translation id="2202020181578195191">खतà¥à¤® होने का मानà¥à¤¯ वरà¥à¤· डालें</translation>
<translation id="2212735316055980242">नीति नहीं मिली</translation>
<translation id="2213606439339815911">पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚ फ़ेच की जा रही हैं...</translation>
+<translation id="2218879909401188352"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर इस समय मौजूद हमलावर à¤à¤¸à¥‡ खतरनाक à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ इंसà¥à¤Ÿà¥‰à¤² कर सकते हैं जो आपके डिवाइस को नà¥à¤•à¤¸à¤¾à¤¨ पहà¥à¤‚चा सकते हैं और आपके मोबाइल बिल में अनजाने खरà¥à¤šà¥‡ जोड़ सकते हैं या आपकी वà¥â€à¤¯à¤•à¥â€à¤¤à¤¿à¤—त जानकारी चà¥à¤°à¤¾ सकते हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />निदान à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨<ph name="END_LINK" /> का उपयोग करके अपने कनेकà¥à¤¶à¤¨ को ठीक करें</translation>
<translation id="2239100178324503013">अभी भेजें</translation>
<translation id="225207911366869382">यह मान इस नीति के लिठहटा दिया गया है.</translation>
<translation id="2262243747453050782">HTTP गड़बड़ी</translation>
+<translation id="2270484714375784793">फ़ोन नंबर</translation>
<translation id="2282872951544483773">अनà¥à¤ªà¤²à¤¬à¥à¤§ पà¥à¤°à¤¯à¥‹à¤—</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> आइटम}one{<ph name="ITEM_COUNT" /> आइटम}other{<ph name="ITEM_COUNT" /> आइटम}}</translation>
<translation id="2292556288342944218">आपका इंटरनेट कनेकà¥à¤¶à¤¨ अवरà¥à¤¦à¥à¤§ है</translation>
<translation id="230155334948463882">नया कारà¥à¤¡?</translation>
-<translation id="2305919008529760154">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; हो सकता है कि उसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° कपटपूरà¥à¤µà¤• जारी किया गया हो. à¤à¤¸à¤¾ किसी गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> के लिठउपयोगकरà¥à¤¤à¤¾ नाम और पासवरà¥à¤¡ आवशà¥à¤¯à¤• है.</translation>
-<translation id="2318774815570432836">आप इस समय <ph name="SITE" /> पर विज़िट नहीं कर सकते कà¥à¤¯à¥‹à¤‚कि वेबसाइट HSTS का उपयोग करती है. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर असà¥à¤¥à¤¾à¤¯à¥€ होते हैं, इसलिठसंभवत: यह पेज बाद में काम करेगा. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">वह सेटिंग जिसे आपका वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• नियंतà¥à¤°à¤¿à¤¤ करता है</translation>
<translation id="2354001756790975382">अनà¥à¤¯ बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
+<translation id="2354430244986887761">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को हाल में <ph name="SITE" /> पर <ph name="BEGIN_LINK" />नà¥à¤•à¤¸à¤¾à¤¨ पहà¥à¤‚चाने वाले à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ मिले हैं<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">आप इस साइट पर जिन चितà¥à¤°à¥‹à¤‚ को देख रहे हैं, हो सकता है कि वे हमलावरों को दिखाई दें और हमलावर उनà¥à¤¹à¥‡à¤‚ बदलने के लिठआपको भà¥à¤°à¤®à¤¿à¤¤ करें.</translation>
+<translation id="2356070529366658676">पूछें</translation>
+<translation id="2359629602545592467">à¤à¤• से अधिक</translation>
<translation id="2359808026110333948">जारी रखें</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> पर कैपà¥à¤šà¤° की गई ख़राबी रिपोरà¥à¤Ÿ अपलोड नहीं की गई</translation>
<translation id="2367567093518048410">सà¥à¤¤à¤°</translation>
-<translation id="2371153335857947666">{1,plural, =1{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की समय सीमा कल ही समापà¥à¤¤ हà¥à¤ˆ है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. आपके कंपà¥à¤¯à¥‚टर की घड़ी वरà¥à¤¤à¤®à¤¾à¤¨ में <ph name="CURRENT_DATE" /> पर सेट है. कà¥â€à¤¯à¤¾ वह सही है? यदि नहीं, तो आपको अपने सिसà¥à¤Ÿà¤® की घड़ी सही करनी चाहिठऔर इस पेज को रीफà¥à¤°à¥‡à¤¶ करना चाहिà¤. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.}one{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की समय सीमा # दिन पहले समापà¥à¤¤ हà¥à¤ˆ है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. आपके कंपà¥à¤¯à¥‚टर की घड़ी वरà¥à¤¤à¤®à¤¾à¤¨ में <ph name="CURRENT_DATE" /> पर सेट है. कà¥â€à¤¯à¤¾ वह सही है? यदि नहीं, तो आपको अपने सिसà¥à¤Ÿà¤® की घड़ी सही करनी चाहिठऔर इस पेज को रीफà¥à¤°à¥‡à¤¶ करना चाहिà¤. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.}other{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की समय सीमा # दिन पहले समापà¥à¤¤ हà¥à¤ˆ है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. आपके कंपà¥à¤¯à¥‚टर की घड़ी वरà¥à¤¤à¤®à¤¾à¤¨ में <ph name="CURRENT_DATE" /> पर सेट है. कà¥â€à¤¯à¤¾ वह सही है? यदि नहीं, तो आपको अपने सिसà¥à¤Ÿà¤® की घड़ी सही करनी चाहिठऔर इस पेज को रीफà¥à¤°à¥‡à¤¶ करना चाहिà¤. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">कोई UI विकलà¥à¤ª उपलबà¥à¤§ नहीं है</translation>
<translation id="2384307209577226199">à¤à¤‚टरपà¥à¤°à¤¾à¤‡à¤œà¤¼ डिफ़ॉलà¥à¤Ÿ</translation>
<translation id="2386255080630008482">सरà¥à¤µà¤° का पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ कर दिया गया है.</translation>
<translation id="2392959068659972793">कोई भी मान सेट नहीं की गई नीतियां दिखाà¤à¤‚</translation>
<translation id="239429038616798445">शिपिंग का यह तरीका उपलबà¥à¤§ नहीं है. कोई दूसरा तरीका आज़माà¤à¤‚.</translation>
<translation id="2396249848217231973">&amp;हटाना वापस लाà¤à¤‚</translation>
-<translation id="2460160116472764928">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को हाल ही में <ph name="SITE" /> पर <ph name="BEGIN_LINK" />मैलवेयर का पता चला<ph name="END_LINK" /> है. आमतौर पर सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ रहने वाली वेबसाइट कभी-कभी मैलवेयर से संकà¥à¤°à¤®à¤¿à¤¤ हो जाती हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">यह सरà¥à¤µà¤° यह पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" />; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ कर दिया गया है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="2463739503403862330">भरें</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />नेटवरà¥à¤• निदान चलाकर देखें<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">अमानà¥â€à¤¯ खोज URL.</translation>
+<translation id="2482878487686419369">अधिसूचनाà¤à¤‚</translation>
<translation id="2491120439723279231">सरà¥à¤µà¤° के पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° में तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚ हैं.</translation>
<translation id="2495083838625180221">JSON पारà¥à¤¸à¤°</translation>
<translation id="2495093607237746763">यदि चेक किया गया हो, तो अधिक तेज़ी से फ़ॉरà¥à¤® भरने के लिठकà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® इस डिवाइस पर आपके कारà¥à¤¡ की कॉपी संगà¥à¤°à¤¹à¤¿à¤¤ करेगा.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">वापस जाà¤à¤‚</translation>
<translation id="2515629240566999685">अपने कà¥à¤·à¥‡à¤¤à¥à¤° में सिगà¥à¤¨à¤² की जांच करें</translation>
<translation id="2516305470678292029">UI विकलà¥à¤ª</translation>
+<translation id="2539524384386349900">पता लगाà¤à¤‚</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ने à¤à¤• अमानà¥à¤¯ पà¥à¤°à¤¤à¤¿à¤¸à¤¾à¤¦ भेजा है.</translation>
-<translation id="2552545117464357659">इससे नà¤</translation>
<translation id="2556876185419854533">&amp;संपादन वापस लाà¤à¤‚</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> की ओर से. यह और <ph name="OTHER_ARTICLE_COUNT" /> दूसरे समाचार पढ़ें.</translation>
<translation id="2587841377698384444">निरà¥à¤¦à¥‡à¤¶à¤¿à¤•à¤¾ API आईडी:</translation>
<translation id="2597378329261239068">यह दसà¥à¤¤à¤¾à¤µà¥‡à¤œà¤¼ पासवरà¥à¤¡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ है. कृपया पासवरà¥à¤¡ डालें.</translation>
<translation id="2609632851001447353">विविधताà¤à¤‚</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{कà¥à¤› नहीं}=1{1 à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1)}=2{2 à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1, $2)}one{# à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1, $2, $3)}other{# à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">आपकी घड़ी आगे है</translation>
<translation id="2639739919103226564">सà¥à¤¥à¤¿à¤¤à¤¿:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">फ़ाइल तक पहà¥à¤‚च असà¥à¤µà¥€à¤•à¥ƒà¤¤ थी</translation>
<translation id="2653659639078652383">सबमिट करें</translation>
<translation id="2666117266261740852">दूसरे टैब या à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ बंद करें</translation>
+<translation id="2670429602441959756">इस पेज में à¤à¤¸à¥€ सà¥à¤µà¤¿à¤§à¤¾à¤à¤‚ मौजूद हैं जो अभी तक VR में काम नहीं करती हैं. बाहर निकाला जा रहा है...</translation>
<translation id="2674170444375937751">कà¥à¤¯à¤¾ आप वाकई अपने इतिहास से इन पृषà¥à¤ à¥‹à¤‚ को हटाना चाहते हैं?</translation>
<translation id="2677748264148917807">छोड़ें</translation>
-<translation id="269990154133806163">सरà¥à¤µà¤° ने à¤à¤¸à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया है जिसे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पारदरà¥à¤¶à¤¿à¤¤à¤¾ नीति का उपयोग करके सारà¥à¤µà¤œà¤¨à¤¿à¤• रूप से पà¥à¤°à¤•à¤Ÿ नहीं किया गया था. कà¥à¤› पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‹à¤‚ के लिठयह सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करना आवशà¥à¤¯à¤• है कि वे विशà¥à¤µà¤¸à¤¨à¥€à¤¯ हैं और हमलावरों से सà¥à¤°à¤•à¥à¤·à¤¾ करते हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">पठन सूची</translation>
<translation id="2704283930420550640">मान का पà¥à¤°à¤¾à¤°à¥‚प से मिलान नहीं होता.</translation>
<translation id="2704951214193499422">कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® इस समय आपके कारà¥à¤¡ की पà¥à¤·à¥à¤Ÿà¤¿ नहीं कर सका. कृपया बाद में पà¥à¤¨: पà¥à¤°à¤¯à¤¾à¤¸ करें.</translation>
<translation id="2705137772291741111">इस साइट की सहेजी गई (संचित) कॉपी पढ़ने योगà¥à¤¯ नहीं थी.</translation>
<translation id="2709516037105925701">ऑटोमैटिक भरना</translation>
-<translation id="2712118517637785082">आपने <ph name="DOMAIN" /> पर पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन सरà¥à¤µà¤° दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किठगठपà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° को उसके जारीकरà¥à¤¤à¤¾ ने निरसà¥à¤¤ कर दिया है. इसका अरà¥à¤¥ है कि सरà¥à¤µà¤° दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ सà¥à¤°à¤•à¥à¤·à¤¾ कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल पर बिलà¥à¤•à¥à¤² भी विशà¥à¤µà¤¾à¤¸ नहीं किया जाना चाहिà¤. हो सकता है आप किसी हमलावर से बातचीत कर रहे हों. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">अनà¥à¤®à¤¤à¤¿ मांगें</translation>
<translation id="2713444072780614174">सफ़ेद</translation>
<translation id="2720342946869265578">आस-पास</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">डिवाइस का रिकॉरà¥à¤¡ लापता है</translation>
<translation id="2784949926578158345">कनेकà¥â€à¤¶à¤¨ रीसेट किया गया था.</translation>
<translation id="2794233252405721443">साइट अवरोधित है</translation>
+<translation id="2799020568854403057">आगे आने वाली साइट में नà¥à¤•à¤¸à¤¾à¤¨ पहà¥à¤‚चाने वाले à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ हैं</translation>
+<translation id="2803306138276472711">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को <ph name="SITE" /> पर हाल ही में <ph name="BEGIN_LINK" />मैलवेयर का पता चला<ph name="END_LINK" /> है. आमतौर पर सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ रहने वाली वेबसाइटें कभी-कभी मैलवेयर से संकà¥à¤°à¤®à¤¿à¤¤ हो जाती हैं.</translation>
<translation id="2824775600643448204">पता और खोज बार</translation>
<translation id="2826760142808435982">कनेकà¥à¤¶à¤¨ को <ph name="CIPHER" /> का उपयोग करके à¤à¤¨à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ और पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ किया गया है और यह कà¥à¤‚जी विनिमय तकनीक के रूप में <ph name="KX" /> का उपयोग करता है.</translation>
<translation id="2835170189407361413">फ़ॉरà¥à¤® साफ़ करें</translation>
+<translation id="2856444702002559011">हो सकता है कि हमलावर <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> से आपकी जानकारी (उदाहरण के लिà¤, पासवरà¥à¤¡, संदेश या कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चà¥à¤°à¤¾à¤¨à¥‡ की कोशिश कर रहे हों. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">पà¥à¤¨: लोड ना करें</translation>
<translation id="2900469785430194048">यह वेबपेज दिखाते समय Google Chrome में जगह नहीं बची.</translation>
<translation id="2909946352844186028">नेटवरà¥à¤• में बदलाव का पता चला.</translation>
<translation id="2916038427272391327">दूसरे पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® बंद करें</translation>
<translation id="2922350208395188000">सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की जांच नहीं की जा सकती.</translation>
<translation id="2928905813689894207">बिलिंग पता</translation>
+<translation id="2941952326391522266">यह सरà¥à¤µà¤° यह पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° <ph name="DOMAIN2" /> की ओर से है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="2948083400971632585">आप किसी कनेकà¥à¤¶à¤¨ के लिठकॉनà¥à¤«à¤¼à¤¿à¤—र की गई किसी भी पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ को सेटिंग पेज से अकà¥à¤·à¤® कर सकते हैं.</translation>
<translation id="2955913368246107853">खोज बार बंद करें</translation>
<translation id="2958431318199492670">नेटवरà¥à¤• कॉनà¥à¤«à¤¼à¤¿à¤—रेशन ONC मानक का पालन नहीं करता. कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कà¥à¤› भाग आयात नहीं किठजा सकते हैं.</translation>
-<translation id="29611076221683977"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपके Mac पर à¤à¤¸à¥‡ खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने की कोशिश कर सकते हैं जो आपकी जानकारी (उदाहरण के लिà¤, फ़ोटो, पासवरà¥à¤¡, संदेश और कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) को चà¥à¤°à¤¾à¤¤à¥‡ हैं या उसे हटा देते हैं.</translation>
<translation id="2966678944701946121">खतà¥à¤® होने की तारीख: <ph name="EXPIRATION_DATE_ABBR" />, <ph name="ADDED_TO_AUTOFILL_MONTH" /> को जोड़ा गया</translation>
<translation id="2969319727213777354">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥â€à¤¶à¤¨ सà¥â€à¤¥à¤¾à¤ªà¤¿à¤¤ करने के लिà¤, आपकी घड़ी को सही तरीके से सेट किठजाने की आवशà¥â€à¤¯à¤•à¤¤à¤¾ है. à¤à¤¸à¤¾ इसलिठकà¥â€à¤¯à¥‹à¤‚कि वेबसाइटों दà¥à¤µà¤¾à¤°à¤¾ सà¥â€à¤µà¤¯à¤‚ की पहचान करने के लिठउपयोग किठजाने वाले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° केवल विशिषà¥â€à¤Ÿ समयावधियों के लिठही मानà¥â€à¤¯ होते हैं. चूंकि आपके डिवाइस की घड़ी गलत है, इसलिठGoogle Chrome इन पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‹à¤‚ का सतà¥â€à¤¯à¤¾à¤ªà¤¨ नहीं कर सकता.</translation>
<translation id="2972581237482394796">&amp;फिर से करें</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">मानà¥à¤¯ पता डालें</translation>
<translation id="2986368408720340940">पिकअप का यह तरीका उपलबà¥à¤§ नहीं है. कोई दूसरा तरीका आज़माà¤à¤‚.</translation>
<translation id="2991174974383378012">वेबसाइटों के साथ साà¤à¤¾à¤•à¤°à¤£</translation>
+<translation id="2991571918955627853">आप इस समय <ph name="SITE" /> पर नहीं जा सकते हैं कà¥à¤¯à¥‹à¤‚कि वेबसाइट HSTS का उपयोग करती है. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर कà¥à¤› समय के लिठहोते हैं, इसलिठपेज शायद बाद में ठीक से काम करेगा.</translation>
<translation id="3005723025932146533">सहेजी गई पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ दिखाà¤à¤‚</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> का CVC डालें. आपकी तरफ से पà¥à¤·à¥à¤Ÿà¤¿ हो जाने पर, आपके कारà¥à¤¡ के विवरण इस साइट के साथ साà¤à¤¾ किठजाà¤à¤‚गे.</translation>
<translation id="3010559122411665027">सूची पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿâ€à¤¿ "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">ऑटोमैटिक रूप से बà¥à¤²à¥‰à¤• है</translation>
<translation id="3024663005179499861">गलत नीति पà¥à¤°à¤•à¤¾à¤°</translation>
<translation id="3032412215588512954">कà¥à¤¯à¤¾ आप इस साइट को फिर से लोड करना चाहते हैं?</translation>
<translation id="3037605927509011580">हे भगवान!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{समनà¥à¤µà¤¯à¤¿à¤¤ डिवाइस पर कम से कम 1 आइटम}=1{1 आइटम (समनà¥à¤µà¤¯à¤¿à¤¤ डिवाइस पर और भी)}one{# आइटम (समनà¥à¤µà¤¯à¤¿à¤¤ डिवाइस पर और भी)}other{# आइटम (समनà¥à¤µà¤¯à¤¿à¤¤ डिवाइस पर और भी)}}</translation>
<translation id="3041612393474885105">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° जानकारी</translation>
<translation id="3063697135517575841">Chrome इस समय आपके कारà¥à¤¡ की पà¥à¤·à¥à¤Ÿà¤¿ नहीं कर सका. कृपया बाद में पà¥à¤¨: पà¥à¤°à¤¯à¤¾à¤¸ करें.</translation>
<translation id="3064966200440839136">किसी बाहरी à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ के ज़रिठभà¥à¤—तान करने के लिठगà¥à¤ªà¥à¤¤ मोड छोड़ रहे हैं. जारी रखना चाहते हैं?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{कà¥à¤› नहीं}=1{1 पासवरà¥à¤¡}one{# पासवरà¥à¤¡}other{# पासवरà¥à¤¡}}</translation>
<translation id="3093245981617870298">आप ऑफ़लाइन हैं.</translation>
<translation id="3105172416063519923">à¤à¤¸à¥‡à¤Ÿ आईडी:</translation>
<translation id="3109728660330352905">आपके पास इस पेज को देखने के लिठपà¥à¤°à¤¾à¤§à¤¿à¤•à¤°à¤£ नहीं है.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />कनेकà¥à¤Ÿà¤¿à¤µà¤¿à¤Ÿà¥€ निदान चलाकर देखें<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">उतà¥à¤¤à¤° डीकोड करने में विफल</translation>
<translation id="3150653042067488994">असà¥à¤¥à¤¾à¤¯à¥€ सरà¥à¤µà¤° गड़बड़ी</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">आपके दà¥à¤µà¤¾à¤°à¤¾ गà¥à¤ªà¥à¤¤ टैब में देखे जाने वाले पेज, आपके दà¥à¤µà¤¾à¤°à¤¾ अपने सभी गà¥à¤ªà¥à¤¤ टैब बंद कर देने के बाद आपके बà¥à¤°à¤¾à¤‰à¥›à¤° के इतिहास, कà¥à¤•à¥€ संगà¥à¤°à¤¹, या खोज इतिहास में नहीं रहेंगे. आपके दà¥à¤µà¤¾à¤°à¤¾ डाउनलोड की गईं सभी फ़ाइलें या बनाठगठबà¥à¤•à¤®à¤¾à¤°à¥à¤• रख लिठजाà¤à¤‚गे.</translation>
<translation id="3169472444629675720">तलाश करें</translation>
<translation id="3174168572213147020">दà¥à¤µà¥€à¤ª</translation>
+<translation id="317583078218509884">पेज को पà¥à¤¨: लोड करने के बाद नई साइट अनà¥à¤®à¤¤à¤¿à¤¯à¤¾à¤‚ सेटिंग पà¥à¤°à¤­à¤¾à¤µà¥€ हो जाà¤à¤‚गी.</translation>
<translation id="3176929007561373547">यह सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करने के लिठकि पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° काम कर रहा है,
अपनी पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सेटिंग जांचें या अपने नेटवरà¥à¤• वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• से संपरà¥à¤• करें. यदि आपको विशà¥à¤µà¤¾à¤¸ नहीं हो
कि आप किसी पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° का उपयोग कर रहे हैं, तो:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">पेज को गà¥à¤ªà¥à¤¤ मोड में खोलें</translation>
-<translation id="3202578601642193415">नवीनतम</translation>
+<translation id="320323717674993345">भà¥à¤—तान रदà¥à¤¦ करें</translation>
<translation id="3207960819495026254">बà¥à¤•à¤®à¤¾à¤°à¥à¤• किया गया</translation>
+<translation id="3225919329040284222">सरà¥à¤µà¤° दà¥à¤µà¤¾à¤°à¤¾ कोई पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥â€à¤¤à¥à¤¤ किया गया, जो बिलà¥â€à¤Ÿ-इन अपेकà¥à¤·à¤¾à¤“ं से मिलान नहीं करता. इन अपेकà¥à¤·à¤¾à¤“ं को आपकी सà¥à¤°à¤•à¥à¤·à¤¾ करने के लिठकà¥à¤›, उचà¥â€à¤š-सà¥à¤°à¤•à¥à¤·à¤¾ वेबसाइटों के लिठशामिल किया गया है.</translation>
<translation id="3226128629678568754">पेज को लोड करने के लिठआवशà¥à¤¯à¤• डेटा पà¥à¤¨: सबमिट करने के लिठपà¥à¤¨: लोड करें बटन दबाà¤à¤‚.</translation>
+<translation id="3227137524299004712">माइकà¥à¤°à¥‹à¤«à¤¼à¥‹à¤¨</translation>
<translation id="3228969707346345236">अनà¥à¤µà¤¾à¤¦ विफल हो गया कà¥à¤¯à¥‹à¤‚कि पेज पहले से ही <ph name="LANGUAGE" /> में है.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> का CVC डालें.</translation>
+<translation id="3234666976984236645">इस साइट पर हमेशा महतà¥â€à¤µà¤ªà¥‚रà¥à¤£ सामगà¥à¤°à¥€ का पता लगाà¤à¤‚</translation>
<translation id="3254409185687681395">इस पेज को बà¥à¤•à¤®à¤¾à¤°à¥à¤• करें</translation>
<translation id="3270847123878663523">&amp;पà¥à¤¨: कà¥à¤°à¤®à¤¿à¤¤ करना वापस लाà¤à¤‚</translation>
<translation id="3282497668470633863">कारà¥à¤¡ पर नाम जोड़ें</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">सेटिंग</translation>
<translation id="3345135638360864351">इस साइट को à¤à¤•à¥â€à¤¸à¥‡à¤¸ करने का आपका अनà¥à¤°à¥‹à¤§ <ph name="NAME" /> को नहीं भेजा जा सका. कृपया पà¥à¤¨: पà¥à¤°à¤¯à¤¾à¤¸ करें.</translation>
<translation id="3355823806454867987">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सेटिंग बदलें...</translation>
+<translation id="3361596688432910856">Chrome नीचे दी गई जानकारी को <ph name="BEGIN_EMPHASIS" />सेव नहीं करेगा<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />आपका बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग इतिहास
+ <ph name="LIST_ITEM" />कà¥à¤•à¥€ और साइट डेटा
+ <ph name="LIST_ITEM" />फ़ॉरà¥à¤® में डाली गई जानकारी
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">घड़ी गड़बड़ी</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> और आइटम...</translation>
<translation id="337363190475750230">पà¥à¤°à¤¾à¤µà¤§à¤¾à¤¨ रदà¥à¤¦</translation>
<translation id="3377188786107721145">नीति पारà¥à¤¸ गड़बड़ी</translation>
<translation id="3380365263193509176">अजà¥à¤žà¤¾à¤¤ गड़बड़ी</translation>
<translation id="3380864720620200369">कà¥à¤²à¤¾à¤‡à¤‚ट आईडी:</translation>
<translation id="3391030046425686457">वितरण पता</translation>
<translation id="3395827396354264108">पिकअप का तरीका</translation>
-<translation id="340013220407300675">हो सकता है हमलावर <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> से आपकी जानकारी चà¥à¤°à¤¾à¤¨à¥‡ का पà¥à¤°à¤¯à¤¾à¤¸ कर रहे हों (उदाहरण के लिठपासवरà¥à¤¡, संदेश या कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡).</translation>
<translation id="3422248202833853650">जगह खाली करने के लिठदूसरे पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® से बाहर निकलकर देखें.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> वरà¥à¤¤à¤®à¤¾à¤¨ में पहà¥à¤‚च योगà¥à¤¯ नहीं है.</translation>
+<translation id="3427092606871434483">अनà¥à¤®à¤¤à¤¿ दें (डिफ़ॉलà¥à¤Ÿ)</translation>
<translation id="3427342743765426898">&amp;संपादित करना फिर से करें</translation>
<translation id="3431636764301398940">इस कारà¥à¤¡ को इस डिवाइस पर सहेजें</translation>
<translation id="3435896845095436175">सकà¥à¤·à¤® करें</translation>
<translation id="3447661539832366887">इस डिवाइस के मालिक ने डायनासोर गेम को बंद कर दिया है.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">पà¥à¤°à¤¾à¤ªà¥à¤¤à¤¿ अंतराल:</translation>
<translation id="3462200631372590220">उनà¥à¤¨à¤¤ को छिपाà¤à¤‚</translation>
<translation id="3467763166455606212">कारà¥à¤¡ मालिक का नाम ज़रूरी है</translation>
<translation id="3478058380795961209">समापà¥à¤¤à¤¿ माह</translation>
<translation id="3479539252931486093">कà¥à¤¯à¤¾ यह अनपेकà¥à¤·à¤¿à¤¤ था? <ph name="BEGIN_LINK" />हमें बताà¤à¤‚<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">अभी नहीं</translation>
-<translation id="348000606199325318">कà¥à¤°à¥ˆà¤¶ आईडी <ph name="CRASH_LOCAL_ID" /> (सरà¥à¤µà¤° आईडी: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">हम इस समय आपके अभिभावक तक नहीं पहà¥à¤‚च पा रहे हैं. कृपया पà¥à¤¨: पà¥à¤°à¤¯à¤¾à¤¸ करें.</translation>
<translation id="3528171143076753409">सरà¥à¤µà¤° का पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{सिंक किठहà¥à¤ डिवाइस पर कम से कम 1 आइटम}=1{1 आइटम (सिंक किठहà¥à¤ डिवाइस पर और भी बहà¥à¤¤ कà¥à¤›)}one{# आइटम (सिंक किठहà¥à¤ डिवाइस पर और भी बहà¥à¤¤ कà¥à¤›)}other{# आइटम (सिंक किठहà¥à¤ डिवाइस पर और भी बहà¥à¤¤ कà¥à¤›)}}</translation>
<translation id="3539171420378717834">इस डिवाइस पर इस कारà¥à¤¡ की पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿ रखें</translation>
<translation id="3542684924769048008">इसके लिठपासवरà¥à¤¡ का उपयोग करें:</translation>
+<translation id="3545341443414427877"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से निजी कनेकà¥à¤¶à¤¨ नहीं बनाया जा सका कà¥à¤¯à¥‹à¤‚कि आपके कंपà¥à¤¯à¥‚टर का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">सभी समनà¥à¤µà¤¯à¤¿à¤¤ डेटा को अपने सà¥à¤µà¤¯à¤‚ के समनà¥à¤µà¤¯à¤¨ पासफ़à¥à¤°à¥‡à¤œà¤¼ के साथ à¤à¤¨à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ करें</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> अधिक...</translation>
-<translation id="3555561725129903880">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; उसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° <ph name="DOMAIN2" /> का है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">आपका पà¥à¤°à¤¬à¤‚धक इसे आपके लिठअनवरोधित कर सकता है</translation>
<translation id="3566021033012934673">आपका कनेकà¥à¤¶à¤¨ निजी नहीं है</translation>
+<translation id="3569145463236695319">&lt;p&gt;<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से निजी कनेकà¥à¤¶à¤¨ नहीं बनाया जा सका कà¥à¤¯à¥‹à¤‚कि आपके कंपà¥à¤¯à¥‚टर का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.&lt;/p&gt;
+
+ &lt;p&gt;कृपया &lt;strong&gt;सेटिंग&lt;/strong&gt; à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ के &lt;strong&gt;सामानà¥à¤¯&lt;/strong&gt; अनà¥à¤­à¤¾à¤— से दिनांक और समय à¤à¤¡à¤œà¤¸à¥à¤Ÿ करें.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">नाम जोड़ें</translation>
<translation id="3583757800736429874">&amp;ले जाना फिर से करें</translation>
<translation id="3586931643579894722">विवरण छà¥à¤ªà¤¾à¤à¤‚</translation>
-<translation id="3587482841069643663">सभी</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">खतà¥à¤® होने की मानà¥à¤¯ तारीख डालें</translation>
<translation id="36224234498066874">बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग डेटा साफ़ करें...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° जानकारी</translation>
<translation id="3690164694835360974">लॉगिन सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नहीं है</translation>
<translation id="3693415264595406141">पासवरà¥à¤¡:</translation>
-<translation id="3696411085566228381">कोई नहीं</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">लोड हो रही हैं...</translation>
<translation id="3712624925041724820">लाइसेंस समापà¥à¤¤ हो गà¤</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />पà¥à¤°à¥‰à¤•à¥à¤¸à¥€, फायरवॉल और DNS कॉनà¥à¥žà¤¿à¤—रेशन की जांच करें<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">यदि आप अपनी सà¥à¤°à¤•à¥à¤·à¤¾ में होने वाले जोखिमों को समà¤à¤¤à¥‡ हैं, तो आप खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® निकाले जाने से पहले <ph name="BEGIN_LINK" />इस असà¥à¤°à¤•à¥à¤·à¤¿à¤¤ साइट पर विज़िट<ph name="END_LINK" /> कर सकते हैं.</translation>
<translation id="3739623965217189342">काॅपी किया गया लिंक</translation>
+<translation id="3744899669254331632">आप इस समय <ph name="SITE" /> पर नहीं जा सकते कà¥â€à¤¯à¥‹à¤‚कि वेबसाइट ने à¤à¤¸à¥€ अवà¥â€à¤¯à¤µà¤¸à¥â€à¤¥à¤¿à¤¤ पà¥à¤°à¤®à¤¾à¤£à¤¿à¤•à¤¤à¤¾à¤à¤‚ भेजी थीं जिनà¥â€à¤¹à¥‡à¤‚ कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® संसाधित नहीं कर सकता. नेटवरà¥à¤• की तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚ और हमले आमतौर पर असà¥â€à¤¥à¤¾à¤¯à¥€ होते हैं, इसलिठसंभवत: यह पृषà¥â€à¤  बाद में काम करेगा.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपको सॉफ़à¥à¤Ÿà¤µà¥‡à¤¯à¤° इंसà¥à¤Ÿà¥‰à¤² करने या अपनी वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त जानकारी (उदाहरण के लिà¤, पासवरà¥à¤¡, फ़ोन नंबर या कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) का खà¥à¤²à¤¾à¤¸à¤¾ करने जैसा खतरनाक काम करने के लिठभà¥à¤°à¤®à¤¿à¤¤ कर सकते हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">सरà¥à¤µà¤° गड़बड़ी के कारण अनà¥à¤µà¤¾à¤¦ विफल.</translation>
<translation id="3759461132968374835">आपके पास हाल ही में रिपोरà¥à¤Ÿ किठगठकà¥à¤°à¥ˆà¤¶ नहीं हैं. कà¥à¤°à¥ˆà¤¶ रिपोरà¥à¤Ÿà¤¿à¤‚ग अकà¥à¤·à¤® होने के दौरान होने वाले कà¥à¤°à¥ˆà¤¶ यहां दिखाई नहीं देंगे.</translation>
+<translation id="3778403066972421603">कà¥à¤¯à¤¾ आप इस कारà¥à¤¡ को अपने Google खाते में और इस डिवाइस पर सहेजना चाहते हैं?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> में खतà¥à¤® होगा</translation>
<translation id="382518646247711829">यदि आप पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° का उपयोग करते हैं...</translation>
<translation id="3828924085048779000">खाली पासफ़à¥à¤°à¥‡à¤œà¤¼ की अनà¥à¤®à¤¤à¤¿ नहीं है.</translation>
-<translation id="3845539888601087042">आपके पà¥à¤°à¤µà¥‡à¤¶ किठगठडिवाइस का इतिहास दिखाया जा रहा है. <ph name="BEGIN_LINK" />अधिक जानें<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">वापस</translation>
<translation id="3858027520442213535">दिनांक और समय अपडेट करें</translation>
<translation id="3884278016824448484">विरोधाभासी डिवाइस पहचानकरà¥à¤¤à¤¾</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">यह साइट à¤à¤•à¥à¤¸à¥‡à¤¸ करने का आपका अनà¥à¤°à¥‹à¤§ <ph name="NAME" /> को भेज दिया गया है</translation>
<translation id="3890664840433101773">ईमेल जोड़ें</translation>
<translation id="3901925938762663762">इस कारà¥à¤¡ की समय सीमा समापà¥â€à¤¤ हो गई है</translation>
-<translation id="3933571093587347751">{1,plural, =1{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° संभवत: कल से मानà¥à¤¯ हो. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.}one{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° संभवत: # दिन बाद से मानà¥à¤¯ हो. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.}other{यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° संभवत: # दिन बाद से मानà¥à¤¯ हो. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF दसà¥à¤¤à¤¾à¤µà¥‡à¥› लोड करने में विफल</translation>
+<translation id="3945915738023014686">अपलोड की गई ख़राबी रिपोरà¥à¤Ÿ आईडी <ph name="CRASH_ID" /> (सà¥à¤¥à¤¾à¤¨à¥€à¤¯ कà¥à¤°à¥ˆà¤¶ आईडी: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° में विषय के वैकलà¥à¤ªà¤¿à¤• नाम नहीं बताठगठहैं. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ की ओर से आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="3963721102035795474">रीडर मोड</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{कà¥à¤› नहीं}=1{1 साइट से }one{# साइटों से }other{# साइटों से }}</translation>
<translation id="397105322502079400">गणना की जा रही है...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> अवरà¥à¤¦à¥à¤§ है</translation>
+<translation id="3987940399970879459">1 MB से कम</translation>
<translation id="40103911065039147">{URL_count,plural, =1{आस-पास 1 वेब पेज है}one{आस-पास # वेब पेज हैं}other{आस-पास # वेब पेज हैं}}</translation>
<translation id="4021036232240155012">DNS à¤à¤• नेटवरà¥à¤• सेवा है जो किसी वेबसाइट के नाम को उसके इंटरनेट पते में बदलती है.</translation>
<translation id="4030383055268325496">&amp;जोड़ना वापस लाà¤à¤‚</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ कॉनà¥â€à¤«à¤¼à¤¿à¤—रेशन को .pac सà¥â€à¤•à¥à¤°à¤¿à¤ªà¥â€à¤Ÿ URL का उपयोग करने के लिठसेट किया जाता है, फ़िकà¥â€à¤¸à¥â€à¤¡ पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ सरà¥à¤µà¤° के लिठनहीं.</translation>
<translation id="4098354747657067197">आगे भà¥à¤°à¤¾à¤®à¤• साइट है</translation>
<translation id="4103249731201008433">डिवाइस की कà¥à¤°à¤® संखà¥à¤¯à¤¾ अमानà¥à¤¯ है</translation>
+<translation id="410351446219883937">सà¥à¤µà¤¤à¤ƒ चलाà¤à¤‚</translation>
<translation id="4103763322291513355">काली सूची में डाले गठURL तथा आपके सिसà¥à¤Ÿà¤® वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• दà¥à¤µà¤¾à¤°à¤¾ लागू की गई अनà¥à¤¯ नीतियों को देखने के लिठ&lt;strong&gt;chrome://policy&lt;/strong&gt; पर जाà¤à¤‚.</translation>
-<translation id="4110615724604346410">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° में गड़बड़ियां हैं. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">मैजेंटा</translation>
+<translation id="4116663294526079822">इस साइट पर हमेशा अनà¥à¤®à¤¤à¤¿ दें</translation>
<translation id="4117700440116928470">नीति कà¥à¤·à¥‡à¤¤à¥à¤° समरà¥à¤¥à¤¿à¤¤ नहीं है.</translation>
-<translation id="4118212371799607889">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 अनà¥à¤¯}one{# अनà¥â€à¤¯}other{# अनà¥â€à¤¯}}</translation>
<translation id="4130226655945681476">नेटवरà¥à¤• केबल, मोडेम और राउटर की जांच करें</translation>
+<translation id="413544239732274901">अधिक जानें</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">वैशà¥â€à¤µà¤¿à¤• डिफ़ॉलà¥â€à¤Ÿ का उपयोग करें (पता करें)</translation>
+<translation id="4165986682804962316">साइट सेटिंग</translation>
<translation id="4169947484918424451">कà¥à¤¯à¤¾ आप चाहते हैं कि कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® इस कारà¥à¤¡ को सहेजे?</translation>
<translation id="4171400957073367226">गलत सतà¥à¤¯à¤¾à¤ªà¤¨ हसà¥à¤¤à¤¾à¤•à¥à¤·à¤°</translation>
<translation id="4196861286325780578">&amp;ले जाना फिर से करें</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />फायरवॉल और à¤à¤‚टीवायरस कॉनà¥à¥žà¤¿à¤—रेशन की जांच करें<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{कोई नहीं}=1{1 à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1)}=2{2 à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1, $2)}one{# à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1, $2, $3)}other{# à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">कà¥à¤°à¥ˆà¤¶</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपको à¤à¤¸à¥‡ पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने के लिठभà¥à¤°à¤®à¤¿à¤¤ करने की कोशिश सकते हैं जिनसे आपके बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग अनà¥à¤­à¤µ को नà¥à¤•à¤¸à¤¾à¤¨ पहà¥à¤‚च सकता है (उदाहरण के लिà¤, आपका होमपेज बदलकर या आप जिन साइटों पर जाते हैं उन पर अतिरिकà¥à¤¤ विजà¥à¤žà¤¾à¤ªà¤¨ दिखाकर). <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />नेटवरà¥à¤• निदान चलाकर देखें<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">मानà¥à¤¯</translation>
<translation id="4250431568374086873">इस साइट से आपका कनेकà¥à¤¶à¤¨ पूरी तरह से सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नहीं है</translation>
<translation id="4250680216510889253">नहीं</translation>
<translation id="425582637250725228">हो सकता है कि आपके दà¥à¤µà¤¾à¤°à¤¾ किठगठबदलाव सहेजे ना जाà¤à¤‚.</translation>
<translation id="4258748452823770588">खराब हसà¥à¤¤à¤¾à¤•à¥à¤·à¤°</translation>
+<translation id="4265872034478892965">आपके वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• ने अनà¥à¤®à¤¤à¤¿ दी है</translation>
<translation id="4269787794583293679">(कोई उपयोगकरà¥à¤¤à¤¾ नाम नहीं)</translation>
<translation id="4275830172053184480">अपना डिवाइस पà¥à¤¨: पà¥à¤°à¤¾à¤°à¤‚भ करें</translation>
<translation id="4280429058323657511">, समापà¥à¤¤à¤¿ दिनांक <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को हाल ही में <ph name="SITE" /> पर <ph name="BEGIN_LINK" />हानिकारक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® मिले हैं<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">अभिभावक सà¥à¤à¤¾à¤µ</translation>
<translation id="4304224509867189079">पà¥à¤°à¤µà¥‡à¤¶ करें</translation>
-<translation id="432290197980158659">सरà¥à¤µà¤° ने à¤à¤¸à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया जिसका मिलान अंतरà¥à¤¨à¤¿à¤¹à¤¿à¤¤ अपेकà¥à¤·à¤¾à¤“ं से नहीं होता. आपकी सà¥à¤°à¤•à¥à¤·à¤¾ करने के लिà¤, ये अपेकà¥à¤·à¤¾à¤à¤‚ कà¥à¤› निशà¥à¤šà¤¿à¤¤, उचà¥à¤š-सà¥à¤°à¤•à¥à¤·à¤¾ वेबसाइट के लिठशामिल की गई हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">अवरà¥à¤¦à¥à¤§ करें (डिफ़ॉलà¥à¤Ÿ)</translation>
<translation id="4325863107915753736">लेख ढूंà¥à¤¨à¥‡ में विफल</translation>
<translation id="4326324639298822553">अपना समापà¥à¤¤à¤¿ दिनांक जांचें और फिर से कोशिश करें</translation>
<translation id="4331708818696583467">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नहीं है</translation>
<translation id="4356973930735388585">इस साइट पर मौजूद हमलावर आपके कंपà¥à¤¯à¥‚टर पर à¤à¤¸à¥‡ खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने की कोशिश कर सकते हैं जो आपकी जानकारी (उदाहरण के लिà¤, फ़ोटो, पासवरà¥à¤¡, संदेश और कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चà¥à¤°à¤¾ लेते हैं या उसे हटा देते हैं.</translation>
<translation id="4372948949327679948">अपेकà¥à¤·à¤¿à¤¤ <ph name="VALUE_TYPE" /> मान.</translation>
+<translation id="4377125064752653719">आपने <ph name="DOMAIN" /> तक पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन सरà¥à¤µà¤° दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° को उसके जारीकरà¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ रदà¥à¤¦ कर दिया गया है. इसका अरà¥à¤¥ है कि सरà¥à¤µà¤° दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤¿à¤•à¤¤à¤¾ पर पूरà¥à¤£à¤¤à¤¯à¤¾ विशà¥à¤µà¤¾à¤¸ नहीं करना चाहिà¤. हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों.</translation>
<translation id="4381091992796011497">उपयोगकरà¥à¤¤à¤¾ नाम:</translation>
<translation id="4394049700291259645">अकà¥à¤·à¤® करें</translation>
<translation id="4406896451731180161">खोज परिणाम</translation>
+<translation id="4424024547088906515">यह सरà¥à¤µà¤° यह नहीं पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° Chrome दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¥žà¤¿à¤—रेशन या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ने आपका लॉगिन पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सà¥à¤µà¥€à¤•à¤¾à¤° नहीं किया है या हो सकता है कि पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° उपलबà¥à¤§ नहीं कराया गया हो.</translation>
<translation id="443673843213245140">पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ का उपयोग अकà¥à¤·à¤® है लेकिन कोई सà¥â€à¤ªà¤·à¥à¤Ÿ पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ कॉनà¥à¥žà¤¿à¤—रेशन निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया गया है.</translation>
-<translation id="4492190037599258964">'<ph name="SEARCH_STRING" />' के खोज परिणाम</translation>
<translation id="4506176782989081258">सतà¥â€à¤¯à¤¾à¤ªà¤¨ गड़बड़ी: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">सिसà¥à¤Ÿà¤® वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• से संपरà¥à¤• करें</translation>
<translation id="450710068430902550">वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• के साथ साà¤à¤¾ करना</translation>
<translation id="4515275063822566619">कारà¥à¤¡ और पते Chrome और आपके Google खाते (<ph name="ACCOUNT_EMAIL" />) से मिलते हैं. आप उनà¥à¤¹à¥‡à¤‚ <ph name="BEGIN_LINK" />सेटिंग<ph name="END_LINK" /> में जाकर पà¥à¤°à¤¬à¤‚धित कर सकते हैं.</translation>
<translation id="4522570452068850558">विवरण</translation>
+<translation id="4552089082226364758">फ़à¥à¤²à¥ˆà¤¶</translation>
<translation id="4558551763791394412">अपने à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन अकà¥à¤·à¤® करके देखें.</translation>
<translation id="457875822857220463">वितरण</translation>
<translation id="4587425331216688090">Chrome से पता निकालें?</translation>
-<translation id="4589078953350245614">आपने <ph name="DOMAIN" /> में पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन सरà¥à¤µà¤° ने अमानà¥à¤¯ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" /> से आपके कनेकà¥à¤¶à¤¨ को किसी आधà¥à¤¨à¤¿à¤• सिफ़र सà¥à¤‡à¤Ÿ का उपयोग करके à¤à¤¨à¥â€à¤•à¥à¤°à¤¿à¤ªà¥â€à¤Ÿ किया गया है.</translation>
<translation id="4594403342090139922">&amp;हटाना वापस लाà¤à¤‚</translation>
<translation id="4619615317237390068">अनà¥à¤¯ डिवाइस के टैब</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">यह सरà¥à¤µà¤° यह पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° में तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚ हैं. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="4690462567478992370">अमानà¥à¤¯ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° का उपयोग करना बंद करें</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">आपका कनेकà¥à¤¶à¤¨ बाधित था</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows नेटवरà¥à¤• निदान चलाकर देखें<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">अजà¥à¤žà¤¾à¤¤ गड़बड़ी आई.</translation>
<translation id="4800132727771399293">अपना अवधि समापà¥â€à¤¤à¤¿ दिनांक और CVC जांचें और पà¥à¤¨: पà¥à¤°à¤¯à¤¾à¤¸ करें</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">आप इस समय <ph name="SITE" /> पर विज़िट नहीं कर सकते हैं कà¥à¤¯à¥‹à¤‚कि वेबसाइट ने à¤à¤¸à¥‡ अवà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल भेजे हैं जिनà¥à¤¹à¥‡à¤‚ Google Chrome संसाधित नहीं कर सकता. नेटवरà¥à¤• की तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚ और हमले आमतौर पर असà¥à¤¥à¤¾à¤¯à¥€ होते हैं, इसलिठसंभवत: यह पेज बाद में काम करेगा.</translation>
<translation id="4813512666221746211">नेटवरà¥à¤• गड़बड़ी</translation>
<translation id="4816492930507672669">पेज में फ़िट करें</translation>
<translation id="483020001682031208">दिखाने के लिठकोई जीता-जागता वेब पेज नहीं है</translation>
<translation id="4850886885716139402">देखें</translation>
<translation id="4854362297993841467">वितरण का यह तरीका उपलबà¥à¤§ नहीं है. कोई दूसरा तरीका आज़माà¤à¤‚.</translation>
<translation id="4858792381671956233">आपने अपने अभिभावकों से पूछा था कि इस साइट पर जाना ठीक है या नहीं</translation>
+<translation id="4863764087567530506">यह सामगà¥à¤°à¥€ आपको सॉफ़à¥à¤Ÿà¤µà¥‡à¤¯à¤° इंसà¥â€à¤Ÿà¥‰à¤² करने या वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त जानकारी पà¥à¤°à¤•à¤Ÿ करने के लिठभà¥à¤°à¤®à¤¿à¤¤ कर सकती है. <ph name="BEGIN_LINK" />फिर भी दिखाà¤à¤‚<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">खोज इतिहास</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{1 और वेब पेज}one{# और वेब पेज}other{# और वेब पेज}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">इस पेज का à¤à¤• अजà¥à¤žà¤¾à¤¤ भाषा से <ph name="LANGUAGE_LANGUAGE" /> में अनà¥à¤µà¤¾à¤¦ किया गया है</translation>
<translation id="4923459931733593730">भà¥à¤—तान</translation>
<translation id="4926049483395192435">निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ किया जाना चाहिà¤.</translation>
<translation id="495170559598752135">कà¥à¤°à¤¿à¤¯à¤¾à¤à¤‚</translation>
<translation id="4958444002117714549">सूची विसà¥à¤¤à¥ƒà¤¤ करें</translation>
-<translation id="4962322354953122629">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° Chrome दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">चेतावनियां फिर से सकà¥à¤·à¤® करें</translation>
<translation id="4989809363548539747">यह पà¥à¤²à¤— इन समरà¥à¤¥à¤¿à¤¤ नहीं है</translation>
<translation id="5002932099480077015">यदि सकà¥à¤·à¤® किया हà¥à¤† हो, तो Chrome फ़ॉरà¥à¤® को तेज़ी से भरने के लिठइस डिवाइस पर आपके कारà¥à¤¡ की à¤à¤• पà¥à¤°à¤¤à¤¿ संगà¥à¤°à¤¹à¤¿à¤¤ करेगा.</translation>
<translation id="5018422839182700155">यह पेज खà¥à¤² नहीं पा रहा है</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">अपने वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• की नीतियां देखें</translation>
<translation id="5029568752722684782">सà¥â€à¤ªà¤·à¥â€à¤Ÿ पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿</translation>
<translation id="5031870354684148875">Google अनà¥à¤µà¤¾à¤¦ के बारे में</translation>
+<translation id="5039804452771397117">अनà¥à¤®à¤¤à¤¿ दें</translation>
<translation id="5040262127954254034">निजता</translation>
<translation id="5045550434625856497">ग़लत पासवरà¥à¤¡</translation>
<translation id="5056549851600133418">आपके लिठलेख</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पते की जांच करें<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{कोई कà¥à¤•à¥€ नहीं}=1{1 साइट कà¥à¤•à¥€ का उपयोग करती है. }one{# साइटें कà¥à¤•à¥€ का उपयोग करती हैं. }other{# साइटें कà¥à¤•à¥€ का उपयोग करती हैं. }}</translation>
<translation id="5087286274860437796">सरà¥à¤µà¤° का पà¥à¤°à¤®à¤¾à¤£ पतà¥à¤° इस समय मानà¥à¤¯ नहीं है.</translation>
<translation id="5087580092889165836">कारà¥à¤¡ जोड़ें</translation>
<translation id="5089810972385038852">राजà¥à¤¯</translation>
+<translation id="5094747076828555589">यह सरà¥à¤µà¤° यह नहीं पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° Chromium दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¥žà¤¿à¤—रेशन या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="5095208057601539847">पà¥à¤°à¤¾à¤‚त</translation>
<translation id="5115563688576182185">(64-बिट)</translation>
<translation id="5141240743006678641">समनà¥à¤µà¤¯à¤¿à¤¤ पासवरà¥à¤¡ अपने Google पà¥à¤°à¤®à¤¾à¤£à¤¿à¤•à¤¤à¤¾ के साथ à¤à¤¨à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ करें</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">ईमेल आवशà¥à¤¯à¤• है</translation>
<translation id="5251803541071282808">कà¥à¤²à¤¾à¤‰à¤¡</translation>
<translation id="5277279256032773186">कारà¥à¤¯à¤¸à¥à¤¥à¤² पर Chrome का उपयोग कर रहे हैं? कंपनियां अपने करà¥à¤®à¤šà¤¾à¤°à¤¿à¤¯à¥‹à¤‚ के लिठChrome सेटिंग पà¥à¤°à¤¬à¤‚धित कर सकती हैं. और जानें</translation>
+<translation id="5297526204711817721">इस साइट से आपका कनेकà¥à¤¶à¤¨ निजी नहीं है. VR मोड से किसी भी समय बाहर निकलने के लिà¤, हेडसेट निकालें और वापस जाà¤à¤‚ दबाà¤à¤‚.</translation>
<translation id="5299298092464848405">नीति पारà¥à¤¸ करने में गड़बड़ी</translation>
-<translation id="5300589172476337783">दिखाà¤à¤‚</translation>
<translation id="5308689395849655368">कà¥à¤°à¥ˆà¤¶ की रिपोरà¥à¤Ÿ करना अकà¥à¤·à¤® कर दिया गया है.</translation>
<translation id="5317780077021120954">सहेजें</translation>
<translation id="5327248766486351172">नाम</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपको धोखा देकर आपसे कà¥à¤› जोखिम वाला काम करा सकते हैं, जैसे सॉफ़à¥à¤Ÿà¤µà¥‡à¤¯à¤° इंसà¥à¤Ÿà¥‰à¤² करना या आपकी वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त जानकारी (उदाहरण के लिà¤, पासवरà¥à¤¡, फ़ोन नंबर या कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) पà¥à¤°à¤•à¤Ÿ करना.</translation>
-<translation id="5359637492792381994">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° इस समय मानà¥à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">आप इस समय <ph name="SITE" /> पर नहीं जा सकते हैं कà¥à¤¯à¥‹à¤‚कि उसका पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ कर दिया गया है. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर कà¥à¤› देर के लिठहोते हैं, इसलिठयह पेज शायद बाद में ठीक से काम करेगा.</translation>
<translation id="536296301121032821">नीति सेटिंग संगà¥à¤°à¤¹à¤¿à¤¤ करने में विफल</translation>
<translation id="5386426401304769735">इस साइट की पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° शà¥à¤°à¥ƒà¤‚खला में, SHA-1 का उपयोग करके हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° किया गया पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° शामिल है.</translation>
<translation id="5402410679244714488">समापà¥à¤¤à¤¿ दिनांक: <ph name="EXPIRATION_DATE_ABBR" />, पिछली बार à¤à¤• वरà¥à¤· से पहले उपयोग किया गया</translation>
+<translation id="540969355065856584">यह सरà¥à¤µà¤° यह पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£ पतà¥à¤° इस समय मानà¥à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¥žà¤¿à¤—रेशन या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="5421136146218899937">बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग डेटा साफ़ करें...</translation>
<translation id="5430298929874300616">बà¥à¤•à¤®à¤¾à¤°à¥à¤• निकालें</translation>
<translation id="5431657950005405462">आपकी फ़ाइल नहीं मिली</translation>
-<translation id="5435775191620395718">इस डिवाइस का इतिहास दिखाया जा रहा है. <ph name="BEGIN_LINK" />अधिक जानें<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" पर सà¥à¤•à¥€à¤®à¤¾ सतà¥à¤¯à¤¾à¤ªà¤¨ गड़बड़ी: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">यह <ph name="HOST_NAME" /> पेज पà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं किया जा सकता</translation>
<translation id="5455374756549232013">खराब नीति टाइमसà¥à¤Ÿà¥ˆà¤®à¥à¤ª</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" /> में से <ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">अमानà¥à¤¯</translation>
<translation id="5470861586879999274">&amp;संपादित करना फिर से करें</translation>
<translation id="54817484435770891">मानà¥à¤¯ पता जोड़ें</translation>
<translation id="5492298309214877701">कंपनी, संगठन या विदà¥à¤¯à¤¾à¤²à¤¯ के इंटà¥à¤°à¤¾à¤¨à¥‡à¤Ÿ पर इस साइट का URL à¤à¤• बाहरी वेबसाइट जैसा है.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">इस पते से पिक अप नहीं किया जा सकता. कोई दूसरा पता चà¥à¤¨à¥‡à¤‚.</translation>
<translation id="5572851009514199876">कृपया Chrome शà¥à¤°à¥‚ करके उसमें पà¥à¤°à¤µà¥‡à¤¶ करें ताकि Chrome देख सके कि कà¥à¤¯à¤¾ आपके पास यह साइट à¤à¤•à¥à¤¸à¥‡à¤¸ करने की अनà¥à¤®à¤¤à¤¿ है.</translation>
<translation id="5580958916614886209">अपना समापà¥à¤¤à¤¿ माह जांचें और फिर से कोशिश करें</translation>
+<translation id="5586446728396275693">कोई सहेजा गया पता नहीं है</translation>
+<translation id="5595485650161345191">पता संपादित करें</translation>
<translation id="560412284261940334">पà¥à¤°à¤¬à¤‚धन समरà¥à¤¥à¤¿à¤¤ नहीं</translation>
<translation id="5610142619324316209">कनेकà¥à¤¶à¤¨ की जांच करें</translation>
<translation id="5610807607761827392">आप <ph name="BEGIN_LINK" />सेटिंग<ph name="END_LINK" /> में कारà¥à¤¡ और पते पà¥à¤°à¤¬à¤‚धित कर सकते हैं.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">कà¥à¤¯à¤¾ आप इस साइट को छोड़ना चाहते हैं?</translation>
<translation id="5629630648637658800">नीति सेटिंग लोड करने में विफल</translation>
<translation id="5631439013527180824">अमानà¥à¤¯ डिवाइस पà¥à¤°à¤¬à¤‚धन टोकन</translation>
+<translation id="5633066919399395251">इस समय <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपके कंपà¥à¤¯à¥‚टर पर à¤à¤¸à¥‡ खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने की कोशिश कर सकते हैं जो आपकी जानकारी (उदाहरण के लिà¤, फ़ोटो, पासवरà¥à¤¡, संदेश और कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चà¥à¤°à¤¾à¤¤à¥‡ हैं या उसे हटा देते हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">सà¥à¤¥à¤¾à¤¨</translation>
+<translation id="5659593005791499971">ईमेल</translation>
<translation id="5669703222995421982">खास आपके लिठबनी सामगà¥à¤°à¥€ पाà¤à¤‚</translation>
<translation id="5675650730144413517">यह पेज काम नहीं कर रहा है</translation>
-<translation id="5677928146339483299">अवरोधित</translation>
-<translation id="5694783966845939798">आपने <ph name="DOMAIN" /> पर पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन सरà¥à¤µà¤° ने कमज़ोर हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° à¤à¤²à¥à¤—ोरिदम के उपयोग से हसà¥à¤¤à¤¾à¤•à¥à¤·à¤°à¤¿à¤¤ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° (जैसे कि SHA-1) पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया. इसका अरà¥à¤¥ है कि सरà¥à¤µà¤° दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ सà¥à¤°à¤•à¥à¤·à¤¾ कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल नकली हो सकते हैं और हो सकता है कि सरà¥à¤µà¤° आपका अपेकà¥à¤·à¤¿à¤¤ सरà¥à¤µà¤° ना हो (हो सकता है आप किसी हमलावर से बातचीत कर रहे हों). <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">इस वेबसाइट की पहचान सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ नहीं की गई है.</translation>
+<translation id="5713016350996637505">भà¥à¤°à¤¾à¤®à¤• सामगà¥à¤°à¥€ बà¥à¤²à¥‰à¤• की गई</translation>
<translation id="5720705177508910913">वरà¥à¤¤à¤®à¤¾à¤¨ उपयोगकरà¥à¤¤à¤¾</translation>
<translation id="5732392974455271431">आपके अभिभावक इसे आपके लिठअनवरोधित कर सकते हैं</translation>
<translation id="5763042198335101085">मानà¥à¤¯ ईमेल पता डालें</translation>
<translation id="5765072501007116331">वितरण के तरीके और ज़रूरतें देखने के लिà¤, कोई पता चà¥à¤¨à¥‡à¤‚</translation>
+<translation id="5778550464785688721">MIDI डिवाइस पूरà¥à¤£ नियंतà¥à¤°à¤£</translation>
<translation id="5784606427469807560">आपके कारà¥à¤¡ की पà¥à¤·à¥à¤Ÿà¤¿ करते समय समसà¥â€à¤¯à¤¾ हà¥à¤ˆ. अपना इंटरनेट कनेकà¥â€à¤¶à¤¨ जांचें और पà¥à¤¨: पà¥à¤°à¤¯à¤¾à¤¸ करें.</translation>
<translation id="5785756445106461925">इसके अतिरिकà¥à¤¤, इस पेज में à¤à¤¸à¥‡ अनà¥à¤¯ संसाधन भी शामिल हैं, जो सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नहीं हैं. टà¥à¤°à¤¾à¤‚ज़िट में होने के दौरान ये संसाधन अनà¥à¤¯ लोगों दà¥à¤µà¤¾à¤°à¤¾ देखे जा सकते हैं और पेज का सà¥à¤µà¤°à¥‚प बदलने के लिठकिसी हमवलावर दà¥à¤µà¤¾à¤°à¤¾ इनमें बदलाव किठजा सकते हैं.</translation>
<translation id="5786044859038896871">कà¥à¤¯à¤¾ अपनी कारà¥à¤¡ जानकारी भरना चाहते हैं?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;जोड़ना फिर से करें</translation>
<translation id="5814352347845180253">आप <ph name="SITE" /> और कà¥à¤› अनà¥à¤¯ साइटों से पà¥à¤°à¥€à¤®à¤¿à¤¯à¤® सामगà¥à¤°à¥€ की à¤à¤•à¥à¤¸à¥‡à¤¸ खो सकते हैं.</translation>
<translation id="5838278095973806738">आपको इस साइट पर कोई भी संवेदनशील जानकारी (उदाहरण के लिà¤, पासवरà¥à¤¡ या कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) नहीं डालनी चाहिà¤, कà¥à¤¯à¥‹à¤‚कि उसे हमलावर चà¥à¤°à¤¾ सकते हैं.</translation>
-<translation id="5843436854350372569">आपने <ph name="DOMAIN" /> तक पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन सरà¥à¤µà¤° ने कमज़ोर कà¥à¤‚जी वाला पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥â€à¤¤à¥à¤¤ किया. संभवत: हमलावर ने निजी कà¥à¤‚जी का पता लगा लिया है और हो सकता है कि सरà¥à¤µà¤° आपका अपेकà¥à¤·à¤¿à¤¤ सरà¥à¤µà¤° ना हो (हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों). <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">इस साइट तक नहीं पहà¥à¤‚चा जा सकता</translation>
<translation id="5869522115854928033">सहेजे गठपासवरà¥à¤¡</translation>
<translation id="5872918882028971132">अभिभावक सà¥à¤à¤¾à¤µ</translation>
<translation id="5901630391730855834">पीला</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (सिंक किया गया)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 उपयोग में है}one{# उपयोग में हैं}other{# उपयोग में हैं}}</translation>
<translation id="5926846154125914413">आप कà¥à¤› साइटों से पà¥à¤°à¥€à¤®à¤¿à¤¯à¤® सामगà¥à¤°à¥€ की à¤à¤•à¥à¤¸à¥‡à¤¸ खो सकते हैं.</translation>
<translation id="5959728338436674663">Google को कà¥à¤› <ph name="BEGIN_WHITEPAPER_LINK" />सिसà¥à¤Ÿà¤® संबंधी जानकारी और पेज सामगà¥à¤°à¥€<ph name="END_WHITEPAPER_LINK" /> अपने आप भेजें ताकि खतरनाक à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ और साइटों का पता लगाने में सहायता मिल सके. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">सपà¥à¤¤à¤¾à¤¹</translation>
<translation id="5967867314010545767">इतिहास से निकालें</translation>
<translation id="5975083100439434680">ज़ूम आउट</translation>
<translation id="598637245381783098">भà¥à¤—तान à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ नहीं खोला जा सकता</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{पेज 1}one{पेज #}other{पेज #}}</translation>
<translation id="6017514345406065928">हरा</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर à¤à¤¸à¥‡ भà¥à¤°à¤¾à¤®à¤• à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ इंसà¥à¤Ÿà¥‰à¤² कर सकते हैं जो कà¥à¤› और होने का दावा करते हैं या à¤à¤¸à¤¾ डेटा à¤à¤•à¤¤à¥à¤°à¤¿à¤¤ करते हैं जिसका उपयोग आप पर नज़र रखने के लिठकिया जा सके. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (सिंक किठगà¤)</translation>
<translation id="6027201098523975773">नाम डालें</translation>
<translation id="6040143037577758943">बंद करें</translation>
<translation id="6042308850641462728">अधिक</translation>
+<translation id="6047233362582046994">अगर आप अपनी सà¥à¤°à¤•à¥à¤·à¤¾ में होने वाले जोखिमों को समà¤à¤¤à¥‡ हैं, तो खतरनाक à¤à¤ªà¥à¤²à¤¿à¤•à¥‡à¤¶à¤¨ निकाले जाने से पहले आप <ph name="BEGIN_LINK" />इस साइट पर जा<ph name="END_LINK" /> सकते हैं.</translation>
+<translation id="6051221802930200923">आप इस समय <ph name="SITE" /> पर नहीं जा सकते हैं कà¥à¤¯à¥‹à¤‚कि वेबसाइट पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पिनिंग का उपयोग करती है. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर कà¥à¤› देर के लिठहोते हैं, इसलिठयह पेज शायद बाद में ठीक से काम करेगा.</translation>
<translation id="6060685159320643512">सावधान, ये पà¥à¤°à¤¯à¥‹à¤— नà¥à¤•à¤¸à¤¾à¤¨ पहà¥à¤‚चा सकते हैं</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{कोई नहीं}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">आपने वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤¦à¤¤à¥à¤¤ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° के उपयोग से सामगà¥à¤°à¥€ à¤à¤•à¥à¤¸à¥‡à¤¸ की है. आपके दà¥à¤µà¤¾à¤°à¤¾ <ph name="DOMAIN" /> को पà¥à¤°à¤¦à¤¾à¤¨ किया गया डेटा आपके वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• दà¥à¤µà¤¾à¤°à¤¾ बीच में रोका जा सकता है.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{कà¥à¤› नहीं}=1{1 पासवरà¥à¤¡ (सिंक किया हà¥à¤†)}one{# पासवरà¥à¤¡ (सिंक किठहà¥à¤)}other{# पासवरà¥à¤¡ (सिंक किठहà¥à¤)}}</translation>
<translation id="6146055958333702838">सभी केबल जांचें और आपके दà¥à¤µà¤¾à¤°à¤¾ उपयोग किठजा रहे सभी राउटर, मॉडेम या अनà¥à¤¯ नेटवरà¥à¤•
डिवाइस को रीबूट करें.</translation>
<translation id="614940544461990577">यह आज़माकर देखें:</translation>
<translation id="6151417162996330722">सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की मानà¥â€à¤¯à¤¤à¤¾ अवधि बहà¥à¤¤ लंबी है.</translation>
<translation id="6157877588268064908">शिपिंग के तरीके और ज़रूरतें देखने केे लिà¤, कोई पता चà¥à¤¨à¥‡à¤‚</translation>
+<translation id="6158003235852588289">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को <ph name="SITE" /> पर हाल ही में फ़िशिंग का पता चला है. फ़िशिंग साइटें आपको भà¥à¤°à¤®à¤¿à¤¤ करने के लिठअनà¥à¤¯ वेबसाइटें होने का दावा करती हैं.</translation>
<translation id="6165508094623778733">अधिक जानें</translation>
+<translation id="6169916984152623906">अब आप निजी रूप से बà¥à¤°à¤¾à¤‰à¤œà¤¼ कर सकते हैं और इस डिवाइस का उपयोग करने वाले दूसरे लोगों को आपकी गतिविधि दिखाई नहीं देगी. लेकिन डाउनलोड और बà¥à¤•à¤®à¤¾à¤°à¥à¤• सेव होंगे.</translation>
<translation id="6177128806592000436">इस साइट से आपका कनेकà¥â€à¤¶à¤¨ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नहीं है</translation>
<translation id="6184817833369986695">(समानता रखने वाले लोग: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">अपना इंटरनेट कनेकà¥à¤¶à¤¨ जांचें</translation>
<translation id="6218753634732582820">कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® से पता निकालें?</translation>
+<translation id="6221345481584921695">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को <ph name="SITE" /> पर हाल ही में <ph name="BEGIN_LINK" />मैलवेयर का पता चला<ph name="END_LINK" /> है. आमतौर पर सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ रहने वाली वेबसाइटें कभी-कभी मैलेवयर से संकà¥à¤°à¤®à¤¿à¤¤ हो जाती हैं. दà¥à¤°à¥à¤­à¤¾à¤µà¤¨à¤¾à¤ªà¥‚रà¥à¤£ सामगà¥à¤°à¥€ <ph name="SUBRESOURCE_HOST" /> से आती है, जो कि à¤à¤• जà¥à¤žà¤¾à¤¤ मैलवेयर वितरक है.</translation>
<translation id="6251924700383757765">निजता नीति</translation>
<translation id="6254436959401408446">यह पेज खोलने के लिठज़रूरी जगह नहीं है</translation>
<translation id="625755898061068298">आपने इस साइट के लिठसà¥à¤°à¤•à¥à¤·à¤¾ चेतावनियों को अकà¥à¤·à¤® करना चà¥à¤¨à¤¾ है.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">बà¥à¤•à¤®à¤¾à¤°à¥à¤• संपादित करें</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> का समापà¥à¤¤à¤¿ दिनांक और CVC डालें</translation>
<translation id="6414888972213066896">आपने अपने अभिभावक से पूछा था कि इस साइट पर जाना ठीक है या नहीं</translation>
-<translation id="6416403317709441254">आप इस समय <ph name="SITE" /> पर विज़िट नहीं कर सकते कà¥à¤¯à¥‹à¤‚कि वेबसाइट ने à¤à¤¸à¥‡ अवà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल भेजे हैं जिनà¥à¤¹à¥‡à¤‚ कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® संसाधित नहीं कर सकता. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर असà¥à¤¥à¤¾à¤¯à¥€ होते हैं, इसलिठसंभवत: पेज बाद में काम करेगा. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° को रदà¥à¤¦ किया गया है या नहीं यह जांच करने में असमररà¥à¤¥.</translation>
<translation id="6433490469411711332">संपरà¥à¤• जानकारी संपादित करें</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ने कनेकà¥à¤Ÿ करने से मना कर दिया है.</translation>
<translation id="6446608382365791566">और जानकारी जोड़ें</translation>
+<translation id="6447842834002726250">कà¥à¤•à¥€</translation>
<translation id="6451458296329894277">फ़ारà¥à¤® पà¥à¤¨: जमा करने की दà¥à¤¬à¤¾à¤°à¤¾ पूछें</translation>
<translation id="6456339708790392414">आपका भà¥à¤—तान</translation>
<translation id="6458467102616083041">नीति के दà¥à¤µà¤¾à¤°à¤¾ डिफ़ॉलà¥â€à¤Ÿ खोज अकà¥à¤·à¤® कर दिठजाने के कारण उपेकà¥à¤·à¤¿à¤¤.</translation>
-<translation id="6462969404041126431">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; हो सकता है इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ कर दिया गया हो. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">डिवाइस नीतियां</translation>
<translation id="6477321094435799029">Chrome को इस पेज पर असामानà¥à¤¯ कोड मिला था और उसने आपकी वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त जानकारी (उदाहरण के लिà¤, पासवरà¥à¤¡, फ़ोन नंबर और कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) की सà¥à¤°à¤•à¥à¤·à¤¾ करने के लिठउसे अवरà¥à¤¦à¥à¤§ कर दिया है.</translation>
<translation id="6489534406876378309">कà¥à¤°à¥ˆà¤¶ अपलोड करना पà¥à¤°à¤¾à¤°à¤‚भ करें</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">खतà¥à¤® होने की तारीख: <ph name="EXPIRATION_DATE_ABBR" />, पिछली बार <ph name="LAST_USED_DATE_NO_DETAIL" /> को उपयोग किया गया</translation>
<translation id="6563469144985748109">आपके पà¥à¤°à¤¬à¤‚धक ने अभी तक इसकी सà¥à¤µà¥€à¤•à¥ƒà¤¤à¤¿ नहीं दी है</translation>
<translation id="6569060085658103619">आप à¤à¤• à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन पेज देख रहे हैं</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> से कम</translation>
+<translation id="657639383826808334">यह सामगà¥à¤°à¥€ आपके डिवाइस पर à¤à¤¸à¤¾ खतरनाक सॉफ़à¥à¤Ÿà¤µà¥‡à¤¯à¤° इंसà¥à¤Ÿà¥‰à¤² करने की कोशिश कर सकती है जो आपकी जानकारी चà¥à¤°à¤¾ सकता है या उसे हटा सकता है. <ph name="BEGIN_LINK" />फिर भी दिखाà¤à¤‚<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ तरीका विकलà¥à¤ª</translation>
<translation id="662080504995468778">इसपर रहें</translation>
<translation id="6626291197371920147">मानà¥à¤¯ कारà¥à¤¡ नंबर जोड़ें</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> खोज</translation>
+<translation id="6630809736994426279">इस समय <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपके Mac पर à¤à¤¸à¥‡ खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने की कोशिश कर सकते हैं जो आपकी जानकारी (उदाहरण के लिà¤, फ़ोटो, पासवरà¥à¤¡, संदेश और कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चà¥à¤°à¤¾à¤¤à¥‡ हैं या उसे हटा देते हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">यह नीति हटा दी गई है.</translation>
-<translation id="6652240803263749613">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपके कंपà¥à¤¯à¥‚टर के ऑपरेटिंग सिसà¥à¤Ÿà¤® दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® से फ़ॉरà¥à¤® सà¥à¤à¤¾à¤µ निकालें?</translation>
<translation id="6685834062052613830">पà¥à¤°à¤¸à¥à¤¥à¤¾à¤¨ करें और सेटअप पूरा करें</translation>
<translation id="6710213216561001401">पिछला</translation>
<translation id="6710594484020273272">&lt;खोज शबà¥à¤¦ लिखें&gt;</translation>
<translation id="6711464428925977395">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¤° के साथ कà¥à¤› गलत है या पता गलत है.</translation>
<translation id="6727102863431372879">सेट करें</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{कोई नहीं}=1{1 आइटम}one{# आइटम}other{# आइटम}}</translation>
<translation id="674375294223700098">अजà¥à¤žà¤¾à¤¤ सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° गड़बड़ी.</translation>
<translation id="6753269504797312559">नीति मान</translation>
<translation id="6757797048963528358">आपका डिवाइस निषà¥à¤•à¥à¤°à¤¿à¤¯ हो गया है.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">कसà¥à¤Ÿà¤®à¤¾à¤‡à¤œà¤¼à¥‡à¤¶à¤¨ आईडी</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">कà¥à¤·à¥‡à¤¤à¥à¤° डेटा लोड नहीं हो सका</translation>
+<translation id="6825578344716086703">आपने <ph name="DOMAIN" /> तक पहà¥à¤‚चने की कोशिश की थी, लेकिन सरà¥à¤µà¤° ने कमज़ोर हसà¥à¤¤à¤¾à¤•à¥à¤·à¤° à¤à¤²à¥à¤—ोरिदम (जैसे कि SHA-1) वाला पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया. इसका मतलब है कि सरà¥à¤µà¤° की ओर से पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किठगठसà¥à¤°à¤•à¥à¤·à¤¾ कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल नकली हो सकते हैं और हो सकता है कि सरà¥à¤µà¤° आपका अपेकà¥à¤·à¤¿à¤¤ सरà¥à¤µà¤° न हो (हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों).</translation>
+<translation id="6830728435402077660">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नहीं है</translation>
<translation id="6831043979455480757">अनà¥à¤µà¤¾à¤¦ करें</translation>
<translation id="6839929833149231406">कà¥à¤·à¥‡à¤¤à¥à¤°</translation>
<translation id="6874604403660855544">&amp;जोड़ना फिर से करें</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">आपके कारà¥à¤¡ की पà¥à¤·à¥à¤Ÿà¤¿ हो गई है</translation>
<translation id="6897140037006041989">उपयोगकरà¥à¤¤à¤¾ à¤à¤œà¥‡à¤‚ट</translation>
<translation id="6915804003454593391">उपयोगकरà¥à¤¤à¤¾:</translation>
+<translation id="6945221475159498467">चà¥à¤¨à¥‡à¤‚</translation>
<translation id="6948701128805548767">पिकअप के तरीके और ज़रूरतें देखने के लिà¤, कोई पता चà¥à¤¨à¥‡à¤‚</translation>
<translation id="6957887021205513506">सरà¥à¤µà¤° का पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° फरà¥à¤œà¥€ दिखाई देता है.</translation>
<translation id="6965382102122355670">ठीक</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">फ़िकà¥â€à¤¸à¥â€à¤¡ पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ सरà¥à¤µà¤° और .pac सà¥â€à¤•à¥à¤°à¤¿à¤ªà¥â€à¤Ÿ URL दोनों ही निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ हैं.</translation>
<translation id="6989763994942163495">अतिरिकà¥à¤¤ सेटिंग दिखाà¤à¤‚...</translation>
<translation id="7000990526846637657">कोई इतिहास पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¤¿ नहीं मिली</translation>
-<translation id="7009986207543992532">आपने <ph name="DOMAIN" /> पर पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन सरà¥à¤µà¤° ने à¤à¤¸à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया जिसकी सतà¥à¤¯à¤¾à¤ªà¤¨ अवधि इतनी लंबी है कि वह विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं लगती है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">आपके Google खाते में <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> पर बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग इतिहास के अनà¥à¤¯ रूप उपलबà¥à¤§ हो सकते हैं</translation>
<translation id="7029809446516969842">पासवरà¥à¤¡</translation>
+<translation id="7050187094878475250">आपने <ph name="DOMAIN" /> तक पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया था, लेकिन सरà¥à¤µà¤° ने à¤à¤¸à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥â€à¤¤à¥à¤¤ किया जिसकी मानà¥â€à¤¯à¤¤à¤¾ अवधि विशà¥â€à¤µà¤¸à¤¨à¥€à¤¯ होने के लिठबहà¥à¤¤ लंबी है.</translation>
+<translation id="7053983685419859001">अवरोधित करें</translation>
<translation id="7064851114919012435">संपरà¥à¤• जानकारी</translation>
<translation id="7079718277001814089">इस साइट में मैलवेयर है</translation>
<translation id="7087282848513945231">काउंटी</translation>
-<translation id="7088615885725309056">इससे पà¥à¤°à¤¾à¤¨à¥‡</translation>
<translation id="7090678807593890770"><ph name="LINK" /> के लिठGoogle में खोज करें</translation>
+<translation id="7108819624672055576">किसी à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन ने अनà¥à¤®à¤¤à¤¿ दी है</translation>
<translation id="7119414471315195487">दूसरे टैब या पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® बंद करें</translation>
<translation id="7129409597930077180">इस पते पर शिप नहीं किया जा सकता. कोई दूसरा पता चà¥à¤¨à¥‡à¤‚.</translation>
<translation id="7138472120740807366">वितरण का तरीका</translation>
@@ -665,20 +735,18 @@
<translation id="7220786058474068424">संसाधित हो रहा है</translation>
<translation id="724691107663265825">साइट में आगे मैलवेयर हैं</translation>
<translation id="724975217298816891">अपने कारà¥à¤¡ विवरण अपडेट करने के लिठ<ph name="CREDIT_CARD" /> का समय समापà¥à¤¤à¤¿ दिनांक और CVC डालें. आपकी तरफ से पà¥à¤·à¥à¤Ÿà¤¿ हो जाने पर, आपके कारà¥à¤¡ के विवरण इस साइट के साथ साà¤à¤¾ किठजाà¤à¤‚गे.</translation>
-<translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से à¤à¤• निजी कनेकà¥â€à¤¶à¤¨ सà¥â€à¤¥à¤¾à¤ªà¤¿à¤¤ नहीं किया जा सकता कà¥â€à¤¯à¥‹à¤‚कि आपके कंपà¥â€à¤¯à¥‚टर का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.</translation>
+<translation id="7260504762447901703">à¤à¤•à¥à¤¸à¥‡à¤¸ निरसà¥à¤¤ करें</translation>
<translation id="7275334191706090484">पà¥à¤°à¤¬à¤‚धित बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
<translation id="7298195798382681320">सà¥à¤à¤¾à¤ गà¤</translation>
<translation id="7309308571273880165">कà¥à¤°à¥ˆà¥ˆà¤¶ रिपोरà¥à¤Ÿ <ph name="CRASH_TIME" /> बजे कैपà¥à¤šà¤° की गई (उपयोगकरà¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ अपलोड करने का अनà¥à¤°à¥‹à¤§ किया गया, अभी तक अपलोड नहीं किया गया)</translation>
<translation id="7334320624316649418">&amp;पà¥à¤¨: कà¥à¤°à¤®à¤¿à¤¤ करना फिर से करें</translation>
<translation id="733923710415886693">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पारदरà¥à¤¶à¤¿à¤¤à¤¾ के माधà¥à¤¯à¤® से सरà¥à¤µà¤° के पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° को पà¥à¤°à¤•à¤Ÿ नहीं किया गया.</translation>
-<translation id="7351800657706554155">आप इस समय <ph name="SITE" /> पर विज़िट नहीं कर सकते कà¥à¤¯à¥‹à¤‚कि उसका पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ कर दिया गया है. नेटवरà¥à¤• की गड़बड़ियां और हमले आमतौर पर असà¥à¤¥à¤¾à¤¯à¥€ होते हैं, इसलिठसंभवत: यह पेज बाद में काम करने लगेगा. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">आदेश पंकà¥à¤¤à¤¿</translation>
<translation id="7372973238305370288">खोज परिणाम</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">नहीं</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">कारà¥à¤¡ की पà¥à¤·à¥à¤Ÿà¤¿ करें</translation>
-<translation id="7394102162464064926">कà¥à¤¯à¤¾ आप वाकई इन पृषà¥à¤ à¥‹à¤‚ को अपने इतिहास से हटाना चाहते हैं? शà¥à¤¶à¥à¤¶! गà¥à¤ªà¥à¤¤ मोड <ph name="SHORTCUT_KEY" /> अगली बार उपयोगी हो सकता है.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">पà¥à¤°à¥‹à¥žà¤¾à¤‡à¤² पथ</translation>
<translation id="7424977062513257142">इस वेबपृषà¥â€à¤  पर à¤à¤®à¥â€à¤¬à¥‡à¤¡ किठगठपृषà¥â€à¤  का कहना है:</translation>
@@ -686,6 +754,7 @@
<translation id="7444046173054089907">यह साइट अवरोधित है</translation>
<translation id="7445762425076701745">जिस सरà¥à¤µà¤° से आप कनेकà¥â€à¤Ÿ हैं उसकी पहचान पूरà¥à¤£à¤¤: सतà¥â€à¤¯à¤¾à¤ªà¤¿à¤¤ नहीं की जा सकती. आपने केवल आपके नेटवरà¥à¤• में ही मानà¥â€à¤¯ नाम का उपयोग कर किसी सरà¥à¤µà¤° से कनेकà¥â€à¤Ÿ किया है, जिसकी मानà¥â€à¤¯à¤¤à¤¾ का सतà¥â€à¤¯à¤¾à¤ªà¤¨ कोई बाहà¥à¤¯ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¾à¤§à¤¿à¤•à¤°à¤£ नहीं करता है. जैसा कि कà¥à¤› पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¾à¤§à¤¿à¤•à¤°à¤£ इन नामों के लिठपà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° जारी कर देंगे, और इस पर धà¥à¤¯à¤¾à¤¨ नहीं दिया जाà¤à¤—ा कि यह सà¥à¤¨à¤¿à¤¶à¥â€à¤šà¤¿à¤¤ करने का कोई तरीका नहीं है कि आप नियत वेबसाइट से कनेकà¥â€à¤Ÿ हैं, न कि किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ से.</translation>
<translation id="7451311239929941790">इस समसà¥à¤¯à¤¾ के बारे में <ph name="BEGIN_LINK" />अधिक जानें<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">वैशà¥à¤µà¤¿à¤• डिफ़ॉलà¥à¤Ÿ का उपयोग करें (अवरोधित करें)</translation>
<translation id="7460163899615895653">आपके अनà¥à¤¯ डिवाइस के हाल ही के टैब यहां दिखाई देंगे</translation>
<translation id="7469372306589899959">कारà¥à¤¡ की पà¥à¤·à¥à¤Ÿà¤¿ की जा रही है</translation>
<translation id="7481312909269577407">आगे भेजें</translation>
@@ -693,36 +762,43 @@
<translation id="7508255263130623398">वापस लौटाया हà¥à¤† नीति डिवाइस आईडी खाली है या उसका मिलान वरà¥à¤¤à¤®à¤¾à¤¨ डिवाइस आईडी से नहीं होता है</translation>
<translation id="7514365320538308">डाउनलोड करें</translation>
<translation id="7518003948725431193">इस वेब पते के लिठकोई वेब पेज नहीं मिला था: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">मान</translation>
<translation id="7537536606612762813">आवशà¥à¤¯à¤•</translation>
+<translation id="7542403920425041731">आपकी तरफ से पà¥à¤·à¥à¤Ÿà¤¿ हो जाने पर, आपके कारà¥à¤¡ के विवरण इस साइट के साथ साà¤à¤¾ किठजाà¤à¤‚गे.</translation>
<translation id="7542995811387359312">सà¥à¤µà¤¤à¤ƒ कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡ भरना अकà¥à¤·à¤® किया गया है कà¥à¤¯à¥‹à¤‚कि यह फ़ॉरà¥à¤® किसी सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥à¤¶à¤¨ का उपयोग नहीं करता है.</translation>
<translation id="7543525346216957623">अपने अभिभावक से पूछें</translation>
<translation id="7549584377607005141">इस वेबपेज को आपके दà¥à¤µà¤¾à¤°à¤¾ पहले दरà¥à¤œ किठगठडेटा की आवशà¥à¤¯à¤•à¤¤à¤¾ है, ताकि इसे सही रूप में पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ किया जा सके. आप यह डेटा पà¥à¤¨: भेज सकते हैं, लेकिन à¤à¤¸à¤¾ करके आप इस पेज दà¥à¤µà¤¾à¤°à¤¾ पहले की जा चà¥à¤•à¥€ कोई कारà¥à¤¯à¤µà¤¾à¤¹à¥€ दोहराà¤à¤‚गे.</translation>
<translation id="7552846755917812628">ये टिपà¥à¤¸ आज़माà¤à¤‚:</translation>
<translation id="7554791636758816595">नया टैब</translation>
+<translation id="7567204685887185387">यह सरà¥à¤µà¤° यह पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; हो सकता है इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° धोखे से जारी किया गया हो. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> अनà¥à¤¯}one{<ph name="CONTACT_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> अनà¥à¤¯}other{<ph name="CONTACT_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> अनà¥à¤¯}}</translation>
<translation id="7568593326407688803">यह पृषà¥à¤ <ph name="ORIGINAL_LANGUAGE" />में है कà¥à¤¯à¤¾ आप इसका अनà¥à¤µà¤¾à¤¦ करना चाहेंगे?</translation>
<translation id="7569952961197462199">Chrome से कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡ निकालें?</translation>
<translation id="7569983096843329377">काला</translation>
<translation id="7578104083680115302">Google के साथ सहेजे गठकारà¥à¤¡ का उपयोग करके डिवाइसों में मौजूद साइटों और à¤à¤ªà¥â€à¤¸ पर तà¥à¤°à¤‚त भà¥à¤—तान करें.</translation>
<translation id="7588950540487816470">जीता-जागता वेब</translation>
<translation id="7592362899630581445">सरà¥à¤µà¤° का पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° नाम संबंधी पà¥à¤°à¤¤à¤¿à¤¬à¤‚धों का उलà¥à¤²à¤‚घन करता है.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> से कम</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> वरà¥à¤¤à¤®à¤¾à¤¨ में इस अनà¥à¤°à¥‹à¤§ का पà¥à¤°à¤¬à¤‚धन कर पाने में असमरà¥à¤¥ है.</translation>
<translation id="7600965453749440009">कभी भी <ph name="LANGUAGE" /> का अनà¥à¤µà¤¾à¤¦ न करें</translation>
<translation id="7610193165460212391"><ph name="VALUE" /> मान सीमा से बाहर है.</translation>
<translation id="7613889955535752492">समय-सीमा समापà¥à¤¤: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">आपके पास पहले से à¤à¤¸à¤¾ डेटा है, जिसे आपके Google खाते के पासवरà¥à¤¡ के किसी भिनà¥â€à¤¨ वरà¥à¤¶à¤¨ का उपयोग करके à¤à¤¨à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ किया गया है. कृपया उसे नीचे लिखें.</translation>
-<translation id="7634554953375732414">इस साइट से आपका कनेकà¥â€à¤¶à¤¨ निजी नहीं है.</translation>
<translation id="7637571805876720304">कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® से कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡ निकालें?</translation>
<translation id="765676359832457558">उनà¥à¤¨à¤¤ सेटिंगà¥à¤¸ छिपाà¤à¤‚...</translation>
<translation id="7658239707568436148">अभी नहीं</translation>
+<translation id="7662298039739062396">सेटिंग किसी à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन से नियंतà¥à¤°à¤¿à¤¤ है</translation>
<translation id="7667346355482952095">वापस लौटा हà¥à¤† नीति टोकन खाली है या उसका मिलान वरà¥à¤¤à¤®à¤¾à¤¨ टोकन से नहीं होता</translation>
<translation id="7668654391829183341">अजà¥à¤žà¤¾à¤¤ डिवाइस</translation>
<translation id="7669271284792375604">इस साइट पर मौजूद हमलावर आपके बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग अनà¥à¤­à¤µ को हानि पहà¥à¤‚चा सकने वाले पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने के लिठआपको भà¥à¤°à¤®à¤¿à¤¤ कर सकते हैं (उदाहरण के लिà¤, आपके मà¥à¤–पृषà¥à¤  को बदलकर या आपकी विज़िट की जा रहीं साइट पर अतिरिकà¥à¤¤ विजà¥à¤žà¤¾à¤ªà¤¨ दिखाकर).</translation>
<translation id="7674629440242451245">शानदार नई Chrome सà¥à¤µà¤¿à¤§à¤¾à¤“ं में रूचि है? तो chrome.com/dev पर हमारा डेव चैनल आज़माà¤à¤‚.</translation>
<translation id="7682287625158474539">शिपिंग</translation>
+<translation id="7701040980221191251">कà¥à¤› नहीं</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" /> में आगे बढ़ें (असà¥à¤°à¤•à¥à¤·à¤¿à¤¤)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°</translation>
+<translation id="7716147886133743102">आपके वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• की ओर से अवरोधित है</translation>
<translation id="7716424297397655342">इस साइट को संचय से लोड नहीं किया जा सकता</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">अपà¥à¤°à¤¬à¤‚धित</translation>
<translation id="7755287808199759310">आपका अभिभावक इसे आपके लिठअनवरोधित कर सकता है</translation>
<translation id="7758069387465995638">हो सकता है कि फायरवॉल या à¤à¤‚टीवायरस दà¥à¤µà¤¾à¤°à¤¾ कनेकà¥à¤¶à¤¨ अवरà¥à¤¦à¥à¤§ हो.</translation>
@@ -749,15 +825,15 @@
<translation id="7951415247503192394">(32-बिट)</translation>
<translation id="7956713633345437162">मोबाइल बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
<translation id="7961015016161918242">कभी नहीं</translation>
-<translation id="7962083544045318153">कà¥à¤°à¥ˆà¤¶ आईडी <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">हमेशा <ph name="ORIGINAL_LANGUAGE" /> से <ph name="TARGET_LANGUAGE" /> में अनà¥à¤µà¤¾à¤¦ करें</translation>
<translation id="7995512525968007366">निरà¥à¤¦à¤¿à¤·à¥â€à¤Ÿ नहीं किया गया</translation>
<translation id="800218591365569300">जगह खाली करने के लिठदूसरे टैब या पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® बंद करके देखें.</translation>
<translation id="8012647001091218357">हम इस समय आपके अभिभावकों तक नहीं पहà¥à¤‚च पा रहे हैं. कृपया पà¥à¤¨: पà¥à¤°à¤¯à¤¾à¤¸ करें.</translation>
<translation id="8025119109950072390">इस साइट पर मौजूद हमलावर आपको धोखा देकर आपसे कà¥à¤› जोखिम वाला काम करा सकते हैं, जैसे सॉफ़à¥à¤Ÿà¤µà¥‡à¤¯à¤° इंसà¥à¤Ÿà¥‰à¤² करना या आपकी वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त जानकारी (उदाहरण के लिà¤, पासवरà¥à¤¡, फ़ोन नंबर या कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) पà¥à¤°à¤•à¤Ÿ करना.</translation>
-<translation id="803030522067524905">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को हाल ही में <ph name="SITE" /> पर फ़िशिंग का पता चला है. आपको भà¥à¤°à¤®à¤¿à¤¤ करने के लिठफ़िशिंग साइट अनà¥à¤¯ वेबसाइट होने का दावा करती हैं. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">यह पेज <ph name="SOURCE_LANGUAGE" /> में है. इसका <ph name="TARGET_LANGUAGE" /> में अनà¥à¤µà¤¾à¤¦ करें?</translation>
+<translation id="8037357227543935929">पूछें (डिफ़ॉलà¥à¤Ÿ)</translation>
<translation id="8041089156583427627">सà¥à¤à¤¾à¤µ भेजें</translation>
+<translation id="8041940743680923270">वैशà¥à¤µà¤¿à¤• डिफ़ॉलà¥à¤Ÿ का उपयोग करें (पूछें)</translation>
<translation id="8088680233425245692">लेख देखने में विफल रहा.</translation>
<translation id="8089520772729574115">1 MB से कम</translation>
<translation id="8091372947890762290">सरà¥à¤µà¤° पर सकà¥à¤°à¤¿à¤¯à¤£ लंबित है</translation>
@@ -766,13 +842,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> का सरà¥à¤µà¤° <ph name="BEGIN_ABBR" />DNS पता<ph name="END_ABBR" /> नहीं ढूंà¥à¤¾ जा सका.</translation>
<translation id="8149426793427495338">आपका कंपà¥à¤¯à¥‚टर निषà¥à¤•à¥à¤°à¤¿à¤¯ हो गया है.</translation>
<translation id="8150722005171944719"><ph name="URL" /> पर मौजूद फ़ाइल पढ़ने योगà¥à¤¯ नहीं है. हो सकता है कि इसे निकाल दिया गया हो, कहीं ले जाया गया हो, या फ़ाइल की अनà¥à¤®à¤¤à¤¿à¤¯à¤¾à¤‚ पहà¥à¤‚च रोक रही हों.</translation>
+<translation id="8184538546369750125">वैशà¥à¤µà¤¿à¤• डिफ़ॉलà¥à¤Ÿ का उपयोग करें (अनà¥à¤®à¤¤à¤¿ दें)</translation>
+<translation id="8191494405820426728">सà¥à¤¥à¤¾à¤¨à¥€à¤¯ कà¥à¤°à¥ˆà¤¶ आईडी <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;ले जाना वापस लाà¤à¤‚</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" आईडी वाले à¤à¤•à¥â€à¤¸à¤Ÿà¥‡à¤‚शन का अमानà¥â€à¤¯ अपडेट URL.</translation>
<translation id="8202097416529803614">आदेश सारांश</translation>
<translation id="8218327578424803826">सौंपा गया सà¥â€à¤¥à¤¾à¤¨:</translation>
<translation id="8225771182978767009">जिस वà¥à¤¯à¤•à¥à¤¤à¤¿ ने इस कंपà¥à¤¯à¥‚टर को सेट किया है, उसने इस साइट को अवरà¥à¤¦à¥à¤§ करना चà¥à¤¨à¤¾ है.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपके कंपà¥à¤¯à¥‚टर पर à¤à¤¸à¥‡ खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने की कोशिश कर सकते हैं जो आपकी जानकारी (उदाहरण के लिà¤, फ़ोटो, पासवरà¥à¤¡, संदेश और कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चà¥à¤°à¤¾ लेते हैं या उसे हटा देते हैं.</translation>
<translation id="8241707690549784388">आपके दà¥à¤µà¤¾à¤°à¤¾ खोजे जा रहे पेज ने आपके दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ की गई जानकारी का उपयोग किया है. उस पेज पर वापस जाने से आपके दà¥à¤µà¤¾à¤°à¤¾ की गई किसी कà¥à¤°à¤¿à¤¯à¤¾ को दोहराने की आवशà¥à¤¯à¤•à¤¤à¤¾ हो सकती है. कà¥à¤¯à¤¾ आप जारी रखना चाहते हैं?</translation>
<translation id="8249320324621329438">पिछली बार पà¥à¤°à¤¾à¤ªà¥à¤¤ किया गया:</translation>
<translation id="8253091569723639551">बिलिंग पता आवशà¥à¤¯à¤•</translation>
@@ -780,6 +857,7 @@
<translation id="8289355894181816810">यदि आप सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ नहीं हैं कि इसका कà¥à¤¯à¤¾ मतलब है, तो अपने नेटवरà¥à¤• वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• से संपरà¥à¤• करें.</translation>
<translation id="8293206222192510085">बà¥à¤•à¤®à¤¾à¤°à¥à¤• जोड़ें</translation>
<translation id="8294431847097064396">सà¥à¤°à¥‹à¤¤</translation>
+<translation id="8306404619377842860"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से निजी कनेकà¥à¤¶à¤¨ नहीं बनाया जा सकता कà¥à¤¯à¥‹à¤‚कि आपके डिवाइस का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">नेटवरà¥à¤• कनेकà¥à¤¶à¤¨ में कोई समसà¥à¤¯à¤¾ होने के कारण अनà¥à¤µà¤¾à¤¦ विफल हà¥à¤†.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> का à¤à¤•à¥à¤¸à¥‡à¤¸ असà¥à¤µà¥€à¤•à¥ƒà¤¤ किया गया</translation>
<translation id="834457929814110454">यदि आप अपनी सà¥à¤°à¤•à¥à¤·à¤¾ में होने वाले जोखिमों को समà¤à¤¤à¥‡ हैं, तो खतरनाक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® निकाले जाने से पहले आप <ph name="BEGIN_LINK" />इस साइट पर विज़िट<ph name="END_LINK" /> कर सकते हैं.</translation>
@@ -800,11 +878,9 @@
<translation id="8483780878231876732">कारà¥à¤¡ का उपयोग अपने Google खाते से करने के लिà¤, Chrome में पà¥à¤°à¤µà¥‡à¤¶ करें</translation>
<translation id="8488350697529856933">इस पर लागू होती है</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ने पà¥à¤°à¤¤à¤¿à¤¸à¤¾à¤¦ देने में अतà¥à¤¯à¤§à¤¿à¤• समय लिया.</translation>
-<translation id="852346902619691059">यह सरà¥à¤µà¤° पà¥à¤°à¤®à¤¾à¤£à¤¿à¤¤ नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपके कंपà¥à¤¯à¥‚टर के ऑपरेटिंग सिसà¥à¤Ÿà¤® दà¥à¤µà¤¾à¤°à¤¾ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नहीं है. à¤à¤¸à¤¾ गलत कॉनà¥à¤«à¤¼à¤¿à¤—रेशन के कारण या किसी हमलावर दà¥à¤µà¤¾à¤°à¤¾ आपके कनेकà¥à¤¶à¤¨ में बाधा डालने के कारण हो सकता है. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जानें<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">समापà¥â€à¤¤à¤¿ वरà¥à¤·</translation>
<translation id="8543181531796978784">आप <ph name="BEGIN_ERROR_LINK" />पहचान संबंधी समसà¥â€à¤¯à¤¾ की रिपोरà¥à¤Ÿ<ph name="END_ERROR_LINK" /> कर सकते हैं या यदि आप अपनी सà¥à¤°à¤•à¥à¤·à¤¾ से जà¥à¤¡à¤¼à¥‡ जोखिमों को समà¤à¤¤à¥‡ हैं, तो <ph name="BEGIN_LINK" />इस असà¥à¤°à¤•à¥à¤·à¤¿à¤¤ साइट पर जा<ph name="END_LINK" /> सकते हैं.</translation>
<translation id="8553075262323480129">अनà¥à¤µà¤¾à¤¦ विफल हो गया कà¥à¤¯à¥‹à¤‚कि पेज की भाषा निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं की जा सकी.</translation>
-<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से à¤à¤• निजी कनेकà¥â€à¤¶à¤¨ सà¥â€à¤¥à¤¾à¤ªà¤¿à¤¤ नहीं किया जा सकता कà¥â€à¤¯à¥‹à¤‚कि आपके डिवाइस का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.</translation>
<translation id="8571890674111243710">पेज का अनà¥à¤µà¤¾à¤¦ <ph name="LANGUAGE" /> में कर रहा है...</translation>
<translation id="858637041960032120">फ़ोन नंबर जोड़ें
</translation>
@@ -819,6 +895,7 @@
<translation id="8738058698779197622">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥â€à¤¶à¤¨ सà¥â€à¤¥à¤¾à¤ªà¤¿à¤¤ करने के लिà¤, आपकी घड़ी को ठीक से सेट किठजाने की आवशà¥â€à¤¯à¤•à¤¤à¤¾ है. à¤à¤¸à¤¾ इसलिठकà¥â€à¤¯à¥‹à¤‚कि वेबसाइटों दà¥à¤µà¤¾à¤°à¤¾ सà¥â€à¤µà¤¯à¤‚ की पहचान करने के लिठउपयोग किठजाने वाले पà¥à¤°à¤®à¤¾à¤£ पतà¥à¤° केवल विशिषà¥â€à¤Ÿ समयावधियों के लिठही मानà¥â€à¤¯ होते हैं. चूंकि आपके डिवाइस की घड़ी गलत है, इसलिठकà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® इन पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‹à¤‚ को सतà¥â€à¤¯à¤¾à¤ªà¤¿à¤¤ नहीं कर सकता.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> का &lt;abbr id="dnsDefinition"&gt;DNS पता&lt;/abbr&gt; पà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं किया जा सका. समसà¥à¤¯à¤¾ का निदान किया जा रहा है.</translation>
<translation id="8759274551635299824">इस कारà¥à¤¡ की अवधि खतà¥à¤® हो चà¥à¤•à¥€ है</translation>
+<translation id="8761567432415473239">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग को <ph name="SITE" /> पर हाल ही में <ph name="BEGIN_LINK" />हानिकारक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® मिले हैं<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;हटाना फिर से करें</translation>
<translation id="8800988563907321413">आपके आस-पास के सà¥à¤à¤¾à¤µ यहां दिखाई देंगे</translation>
<translation id="8820817407110198400">बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
@@ -831,29 +908,30 @@
<translation id="8870413625673593573">हाल ही में बंद किठगà¤</translation>
<translation id="8874824191258364635">मानà¥à¤¯ कारà¥à¤¡ संखà¥à¤¯à¤¾ डालें</translation>
<translation id="8876793034577346603">नेटवरà¥à¤• कॉनà¥à¤«à¤¼à¤¿à¤—रेशन पारà¥à¤¸ होने में विफल रहा.</translation>
-<translation id="8877192140621905067">आपकी तरफ से पà¥à¤·à¥à¤Ÿà¤¿ हो जाने पर, आपके कारà¥à¤¡ के विवरण इस साइट के साथ साà¤à¤¾ किठजाà¤à¤‚गे</translation>
<translation id="8889402386540077796">रंग</translation>
<translation id="8891727572606052622">अमानà¥à¤¯ पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ मोड.</translation>
<translation id="889901481107108152">कà¥à¤·à¤®à¤¾ करें, यह पà¥à¤°à¤¯à¥‹à¤— आपके पà¥â€à¤²à¥‡à¤Ÿà¤«à¤¼à¥‰à¤°à¥à¤® पर उपलबà¥à¤§ नहीं है.</translation>
<translation id="8903921497873541725">ज़ूम इन करें</translation>
<translation id="8931333241327730545">कà¥à¤¯à¤¾ आप इस कारà¥à¤¡ को अपने Google खाते में सहेजना चाहते हैं?</translation>
<translation id="8932102934695377596">आपकी घड़ी पीछे है</translation>
-<translation id="8954894007019320973">(जारी.)</translation>
<translation id="8971063699422889582">सरà¥à¤µà¤° के पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° की समय-सीमा समापà¥à¤¤ हो चà¥à¤•à¥€ है.</translation>
<translation id="8986494364107987395">उपयोग संबंधी आंकड़े और कà¥à¤°à¥ˆà¤¶ रिपोरà¥à¤Ÿ अपने आप Google को भेजने की अनà¥à¤®à¤¤à¤¿ दें</translation>
-<translation id="8987927404178983737">माह</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">साइट में आगे हानिकारक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® हैं</translation>
+<translation id="8997023839087525404">सरà¥à¤µà¤° ने à¤à¤• पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया है, जिसे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पारदरà¥à¤¶à¤¿à¤¤à¤¾ पॉलिसी का उपयोग करके सारà¥à¤µà¤œà¤¨à¤¿à¤• रूप से पà¥à¤°à¤•à¤Ÿ नहीं किया गया था. कà¥à¤› पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‹à¤‚ के लिठयह सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करना आवशà¥à¤¯à¤• है कि वे विशà¥à¤µà¤¸à¤¨à¥€à¤¯ हैं और आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾à¤“ं से रकà¥à¤·à¤¾ करते हैं.</translation>
<translation id="9001074447101275817">पà¥à¤°à¥‰à¤•à¥â€à¤¸à¥€ <ph name="DOMAIN" /> के लिठउपयोगकरà¥à¤¤à¤¾ नाम और पासवरà¥à¤¡ की आवशà¥à¤¯à¤•à¤¤à¤¾ है.</translation>
+<translation id="9005998258318286617">PDF दसà¥à¤¤à¤¾à¤µà¥‡à¥› लोड नहीं किया जा सका.</translation>
<translation id="901974403500617787">सिसà¥à¤Ÿà¤®-वà¥à¤¯à¤¾à¤ªà¥€ रूप से लागू होने वाले फ़à¥à¤²à¥ˆà¤— केवल मालिक दà¥à¤µà¤¾à¤°à¤¾ ही सेट किठजा सकते हैं: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">कारà¥à¤¡ बिलिंग पता ज़रूरी है</translation>
<translation id="9020542370529661692">इस पेज का <ph name="TARGET_LANGUAGE" /> में अनà¥à¤µà¤¾à¤¦ कर दिया गया है</translation>
<translation id="9035022520814077154">सà¥à¤°à¤•à¥à¤·à¤¾ गड़बड़ी</translation>
<translation id="9038649477754266430">अधिक तेज़ी से पेज लोड करने के लिठकिसी पूरà¥à¤µà¤¾à¤¨à¥à¤®à¤¾à¤¨ सेवा का उपयोग करें</translation>
<translation id="9039213469156557790">इसके अतिरिकà¥à¤¤, इस पेज में à¤à¤¸à¥‡ अनà¥à¤¯ संसाधन भी शामिल हैं, जो सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नहीं हैं. टà¥à¤°à¤¾à¤‚ज़िट में होने के दौरान ये संसाधन अनà¥à¤¯ लोगों दà¥à¤µà¤¾à¤°à¤¾ देखे जा सकते हैं और पेज का वà¥à¤¯à¤µà¤¹à¤¾à¤° बदलने के लिठकिसी हमवलावर दà¥à¤µà¤¾à¤°à¤¾ इनमें बदलाव किठजा सकते हैं.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> पर मौजूद हमलावर आपको à¤à¤¸à¥‡ पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® इंसà¥à¤Ÿà¥‰à¤² करने के लिठभà¥à¤°à¤®à¤¿à¤¤ कर सकते हैं जिनसे आपके बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤¿à¤‚ग अनà¥à¤­à¤µ को हानि पहà¥à¤‚च सकती है (उदाहरण के लिà¤, आपके मà¥à¤–à¥à¤¯à¤ªà¥ƒà¤·à¥à¤  को बदलकर या आपके दà¥à¤µà¤¾à¤°à¤¾ देखी जाने वाली वेबसाइटों पर अतिरिकà¥à¤¤ विजà¥à¤žà¤¾à¤ªà¤¨ दिखाकर).</translation>
+<translation id="9049981332609050619">आपने <ph name="DOMAIN" /> पर पहà¥à¤‚चने का पà¥à¤°à¤¯à¤¾à¤¸ किया, लेकिन सरà¥à¤µà¤° ने à¤à¤• अमानà¥â€à¤¯ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤°à¤¸à¥à¤¤à¥à¤¤ किया.</translation>
<translation id="9050666287014529139">पासफ़à¥à¤°à¥‡à¤œà¤¼</translation>
<translation id="9065203028668620118">संपादित करें</translation>
<translation id="9068849894565669697">रंग चà¥à¤¨à¥‡à¤‚</translation>
+<translation id="9069693763241529744">किसी à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन से अवरोधित है</translation>
<translation id="9076283476770535406">इसमें वयसà¥à¤• सामगà¥à¤°à¥€ हो सकती है</translation>
<translation id="9078964945751709336">अधिक जानकारी की आवशà¥à¤¯à¤•à¤¤à¤¾ है</translation>
<translation id="9103872766612412690"><ph name="SITE" /> आपकी जानकारी की सà¥à¤°à¤•à¥à¤·à¤¾ करने के लिठआमतौर पर à¤à¤¨à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤¶à¤¨ का उपयोग करती है. जब कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® ने इस बार <ph name="SITE" /> से कनेकà¥à¤Ÿ करने का पà¥à¤°à¤¯à¤¾à¤¸ किया, तो वेबसाइट ने असामानà¥à¤¯ और गलत कà¥à¤°à¥‡à¤¡à¥‡à¤‚शियल वापस भेजे. à¤à¤¸à¤¾ तब हो सकता है जब कोई हमलावर <ph name="SITE" /> होने का दावा करने का पà¥à¤°à¤¯à¤¾à¤¸ कर रहा हो या किसी वाई-फ़ाई पà¥à¤°à¤µà¥‡à¤¶ सà¥à¤•à¥à¤°à¥€à¤¨ ने कनेकà¥à¤¶à¤¨ को बाधित कर दिया हो. आपकी जानकारी अभी भी सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ है कà¥à¤¯à¥‹à¤‚कि किसी भी डेटा के आदान-पà¥à¤°à¤¦à¤¾à¤¨ से पहले ही कà¥à¤°à¥‹à¤®à¤¿à¤¯à¤® ने कनेकà¥à¤¶à¤¨ को रोक दिया था.</translation>
@@ -862,16 +940,21 @@
<translation id="9148507642005240123">&amp;संपादन वापस लाà¤à¤‚</translation>
<translation id="9154194610265714752">अपडेट किया गया</translation>
<translation id="9157595877708044936">सेट अप कर रहा है...</translation>
+<translation id="9169664750068251925">इस साइट पर हमेशा अवरोधित करें</translation>
<translation id="9170848237812810038">&amp;पूरà¥à¤µà¤µà¤¤à¥ करें</translation>
<translation id="917450738466192189">सरà¥à¤µà¤° का पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° अमानà¥à¤¯ है.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> अनà¥à¤¯}one{<ph name="SHIPPING_OPTION_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> अनà¥à¤¯}other{<ph name="SHIPPING_OPTION_PREVIEW" /> और <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> अनà¥à¤¯}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> à¤à¤• असमरà¥à¤¥à¤¿à¤¤ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•à¥‰à¤² का उपयोग करता है.</translation>
<translation id="9205078245616868884">आपका डेटा आपके समनà¥à¤µà¤¯à¤¨ पासफ़à¥à¤°à¥‡à¥› के साथ à¤à¤¨à¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ किया गया है. समनà¥à¤µà¤¯à¤¨ शà¥à¤°à¥‚ करने के लिठइसे डालें.</translation>
<translation id="9207861905230894330">लेख जोड़ने में विफल रहा.</translation>
+<translation id="9219103736887031265">चितà¥à¤°</translation>
<translation id="933612690413056017">कोई इंटरनेट कनेकà¥à¤¶à¤¨ नहीं है</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">फ़ॉरà¥à¤® साफ़ करें</translation>
<translation id="939736085109172342">नया फ़ोलà¥à¤¡à¤°</translation>
<translation id="941721044073577244">à¤à¤¸à¤¾ लगता है कि आपको इस साइट पर जाने की अनà¥à¤®à¤¤à¤¿ नहीं है</translation>
<translation id="969892804517981540">आधिकारिक बिलà¥à¤¡</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{कà¥à¤› नहीं}=1{1 आइटम}one{# आइटम}other{# आइटम}}</translation>
<translation id="988159990683914416">डेवलपर बिलà¥à¤¡</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_hr.xtb b/chromium/components/strings/components_strings_hr.xtb
index 652d3ce159c..bf989497dc9 100644
--- a/chromium/components/strings/components_strings_hr.xtb
+++ b/chromium/components/strings/components_strings_hr.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Zakretanje u smjeru kazaljke na satu</translation>
<translation id="1038842779957582377">nepoznati naziv</translation>
<translation id="1050038467049342496">Zatvorite ostale aplikacije</translation>
-<translation id="1053591932240354961">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer je web-lokacija poslala kodirane vjerodajnice koje Google Chrome ne može obraditi. Mrežne pogreÅ¡ke i napadi uglavnom su privremeni, tako da će ta stranica vjerojatno kasnije funkcionirati. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Poništi dodavanje</translation>
<translation id="10614374240317010">Zaporke se nikad ne spremaju</translation>
<translation id="106701514854093668">Oznake radne površine</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Predmemorija pravila ispravna je</translation>
<translation id="113188000913989374"><ph name="SITE" /> navodi sljedeće:</translation>
<translation id="1132774398110320017">Postavke Automatskog popunjavanja u Chromeu...</translation>
+<translation id="1150979032973867961">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; operativni sustav vaÅ¡eg raÄunala smatra da njegov sigurnosni certifikat nije pouzdan. To može biti uzrokovano pogreÅ¡nom konfiguracijom ili napadom na vaÅ¡u vezu.</translation>
+<translation id="1151972924205500581">Potrebna je zaporka</translation>
<translation id="1152921474424827756">Pristupite <ph name="BEGIN_LINK" />predmemoriranoj kopiji<ph name="END_LINK" /> stranice <ph name="URL" /></translation>
<translation id="1158211211994409885">Host <ph name="HOST_NAME" /> neoÄekivano je prekinuo vezu.</translation>
<translation id="1161325031994447685">Ponovo se povežite s Wi-Fi mrežom</translation>
+<translation id="1165039591588034296">Pogreška</translation>
<translation id="1175364870820465910">&amp;Ispis...</translation>
<translation id="1181037720776840403">Ukloni</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Automatski prijavi<ph name="END_WHITEPAPER_LINK" /> Googleu pojedinosti o mogućim sigurnosnim incidentima. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Više s ove web-lokacije</translation>
<translation id="1206967143813997005">Potpis inicijalima nije ispravan</translation>
<translation id="1209206284964581585">Sakrij za sad</translation>
+<translation id="121201262018556460">PokuÅ¡ali ste doseći domenu <ph name="DOMAIN" />, ali poslužitelj je predstavio certifikat potpisan slabim kljuÄem. NapadaÄ je možda otkrio privatni kljuÄ, a poslužitelj možda nije oÄekivani poslužitelj (možda ste u komunikaciji s napadaÄem).</translation>
<translation id="1219129156119358924">Sigurnost sustava</translation>
<translation id="1227224963052638717">Nepoznato pravilo.</translation>
<translation id="1227633850867390598">Skrivanje vrijednosti</translation>
<translation id="1228893227497259893">Pogrešan identifikator entiteta</translation>
<translation id="1232569758102978740">Neimenovano</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sinkronizirano)</translation>
<translation id="1263231323834454256">Popis za Äitanje</translation>
<translation id="1264126396475825575">Izvješća o rušenju programa generirana <ph name="CRASH_TIME" /> (još nisu prenesena ili zanemarena)</translation>
+<translation id="1281526147609854549">IzdavaÄ: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Blokiran je opasan sadržaj</translation>
<translation id="1285320974508926690">Nikad nemoj prevoditi ovu web-lokaciju</translation>
<translation id="129553762522093515">Nedavno zatvoreno</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />IzbriÅ¡ite kolaÄiće<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Vaše aktivnosti <ph name="BEGIN_EMPHASIS" />i dalje mogu biti vidljive<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />web-lokacijama koje posjećujete
+ <ph name="LIST_ITEM" />vašem poslodavcu ili školi
+ <ph name="LIST_ITEM" />vašem davatelju internetskih usluga.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domena upisa:</translation>
<translation id="1340482604681802745">Adresa preuzimanja</translation>
<translation id="1344211575059133124">Izgleda da ti je za posjet toj web-lokaciji potrebno dopuštenje</translation>
<translation id="1344588688991793829">Postavke automatskog popunjavanja u Chromiumu...</translation>
+<translation id="1348198688976932919">Sljedeća web-lokacija sadrži opasne aplikacije</translation>
<translation id="1374468813861204354">prijedlozi</translation>
<translation id="1375198122581997741">O verziji</translation>
<translation id="1377321085342047638">Broj kartice</translation>
<translation id="139305205187523129">Host <ph name="HOST_NAME" /> nije poslao nikakve podatke.</translation>
<translation id="1407135791313364759">Otvori sve</translation>
<translation id="1413809658975081374">Pogreška privatnosti</translation>
+<translation id="14171126816530869">Identitet za <ph name="ORGANIZATION" />na <ph name="LOCALITY" /> ovjerio je <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Da</translation>
<translation id="1430915738399379752">Ispis</translation>
-<translation id="1442912890475371290">Blokiran je pokušaj <ph name="BEGIN_LINK" />posjeta stranici na domeni <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer web-lokacija upotrebljava prikvaÄivanje certifikata. Mrežne pogreÅ¡ke i napadi uglavnom su privremeni, tako da će ta stranica vjerojatno kasnije funkcionirati. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Prikaži spremljenu kopiju te stranice (tj., onu za koju se zna da je zastarjela).</translation>
<translation id="1517433312004943670">Telefonski je broj obavezan</translation>
<translation id="1519264250979466059">Datum međuverzije</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Za upotrebu te znaÄajke mora biti omogućen JavaScript.</translation>
<translation id="1555130319947370107">Plava</translation>
<translation id="1559528461873125649">Nema takve datoteke ili direktorija</translation>
-<translation id="1559572115229829303">&lt;p&gt;Sigurna veza s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ne može se uspostaviti jer datum i vrijeme na ureÄ‘aju (<ph name="DATE_AND_TIME" />) nisu toÄni.&lt;/p&gt;
-
- &lt;p&gt;Prilagodite datum i vrijeme putem odjeljka &lt;strong&gt;Općenito&lt;/strong&gt; u aplikaciji &lt;strong&gt;Postavke&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Nešto nije u redu s prikazivanjem ove web-stranice.</translation>
<translation id="1592005682883173041">Pristup lokalnim podacima</translation>
+<translation id="1594030484168838125">Odaberi</translation>
<translation id="161042844686301425">Cijan</translation>
+<translation id="1620510694547887537">Fotoaparat</translation>
<translation id="1629803312968146339">Želite li da Chrome spremi tu karticu?</translation>
<translation id="1639239467298939599">UÄitavanje</translation>
<translation id="1640180200866533862">KorisniÄka pravila</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Mrežna konfiguracija nije važeća i nije ju bilo moguće uvesti.</translation>
<translation id="1644574205037202324">Povijest</translation>
<translation id="1645368109819982629">Protokol nije podržan</translation>
+<translation id="1655462015569774233">{1,plural, =1{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao juÄer. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}one{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dan. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}few{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dana. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}other{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dana. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu.}}</translation>
<translation id="1656489000284462475">Preuzimanje</translation>
<translation id="1663943134801823270">Kartice i adrese dolaze iz Chromea. Njima možete upravljati u <ph name="BEGIN_LINK" />Postavkama<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> obiÄno upotrebljava enkripciju radi zaÅ¡tite vaÅ¡ih podataka. Prilikom ovog pokuÅ¡aja povezivanja Google Chromea s web-lokacijom <ph name="SITE" /> ta je web-lokacija vratila neuobiÄajene i netoÄne vjerodajnice. To može znaÄiti da se neki napadaÄ pokuÅ¡ava predstaviti kao <ph name="SITE" /> ili je zaslon za prijavu na Wi-Fi prekinuo vezu. VaÅ¡i su podaci joÅ¡ uvijek sigurni jer je Google Chrome zaustavio povezivanje prije razmjene podataka.</translation>
-<translation id="168328519870909584">NapadaÄi koji se trenutaÄno nalaze na <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu pokuÅ¡ati instalirati opasne aplikacije na vaÅ¡ ureÄ‘aj radi kraÄ‘e ili brisanja vaÅ¡ih podataka (na primjer, fotografija, zaporki, poruka i brojeva kreditnih kartica).</translation>
<translation id="168841957122794586">Certifikat poslužitelja sadrži slab kriptografski kljuÄ!</translation>
+<translation id="1706954506755087368">{1,plural, =1{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan sutra. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu.}one{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan # dan u budućnosti. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu.}few{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan # dana u budućnosti. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu.}other{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan # dana u budućnosti. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264"><ph name="NAME" /> mora dopustiti da posjetiš tu web-lokaciju</translation>
<translation id="1721424275792716183">* Polje je obavezno</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Preuzmi stranicu kasnije</translation>
<translation id="17513872634828108">Otvorene kartice</translation>
<translation id="1753706481035618306">Broj stranice</translation>
+<translation id="1763864636252898013">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; operativni sustav vašeg uređaja smatra da njegov sigurnosni certifikat nije pouzdan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Pokušajte pokrenuti Mrežnu dijagnostiku sustava Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Ažurirajte zaporku za sinkronizaciju.</translation>
<translation id="1787142507584202372">Ovdje se prikazuju vaše otvorene kartice</translation>
+<translation id="1789575671122666129">SkoÄni prozori</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Ime nositelja kartice</translation>
-<translation id="1803678881841855883">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />otkrilo zlonamjerni softver<ph name="END_LINK" /> na web-lokaciji <ph name="SITE" />. Web-lokacije koje su inaÄe sigurne ponekad mogu biti zaražene zlonamjernim softverom. Zlonamjerni sadržaj potjeÄe s hosta <ph name="SUBRESOURCE_HOST" /> koji je poznati distributer zlonamjernog softvera. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Dodano <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Nevažeći zahtjev ili parametri zahtjeva</translation>
<translation id="1826516787628120939">Provjera</translation>
<translation id="1834321415901700177">Ova web-lokacija sadrži štetne programe</translation>
+<translation id="1840414022444569775">Taj se broj kartice već upotrebljava</translation>
<translation id="1842969606798536927">Plaćanje</translation>
<translation id="1871208020102129563">Proxy poslužitelj postavljen je na upotrebu fiksnih proxy poslužitelja, a ne URL .pac skripte.</translation>
<translation id="1871284979644508959">Obavezno polje</translation>
<translation id="187918866476621466">Otvori polazne stranice</translation>
<translation id="1883255238294161206">Sažmi popis</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtriranje</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Nijedna}=1{1 web-lokacija}one{# web-lokacija}few{# web-lokacije}other{# web-lokacija}}</translation>
<translation id="194030505837763158">Posjetite <ph name="LINK" /></translation>
<translation id="1962204205936693436">Oznake s domene <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Pogreška postavljanja u seriju</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Zanemareno jer je nadjaÄano pravilom <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Traženje stranica FiziÄkog weba u blizini</translation>
<translation id="213826338245044447">Mobilne oznake</translation>
-<translation id="2148716181193084225">Danas</translation>
+<translation id="2147827593068025794">Sinkronizacija u pozadini</translation>
<translation id="2154054054215849342">Sinkronizacija nije dostupna za vašu domenu</translation>
<translation id="2154484045852737596">Uredite karticu</translation>
<translation id="2166049586286450108">Potpuni administratorski pristup</translation>
<translation id="2166378884831602661">Web-lokacija ne može pružiti sigurnu vezu</translation>
<translation id="2181821976797666341">Pravila</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresa}one{# adresa}few{# adrese}other{# adresa}}</translation>
+<translation id="2187317261103489799">Otkrij (zadano)</translation>
<translation id="2202020181578195191">Unesite važeću godinu isteka</translation>
<translation id="2212735316055980242">Pravilo nije pronađeno</translation>
<translation id="2213606439339815911">Dohvaćanje unosa...</translation>
+<translation id="2218879909401188352">NapadaÄi koji su trenutaÄno na web-lokaciji <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogli bi instalirati opasne aplikacije koje će oÅ¡tetiti ureÄ‘aj, dodati skrivene troÅ¡kove na raÄun za mobilne usluge ili ukrasti vaÅ¡e osobne podatke. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">RijeÅ¡ite problem s povezivanjem pomoću <ph name="BEGIN_LINK" />dijagnostiÄke aplikacije<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Pošalji sad</translation>
<translation id="225207911366869382">Ta je vrijednost obustavljena za to pravilo.</translation>
<translation id="2262243747453050782">HTTP pogreška</translation>
+<translation id="2270484714375784793">Telefonski broj</translation>
<translation id="2282872951544483773">Nedostupni eksperimenti</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> stavka}one{<ph name="ITEM_COUNT" /> stavka}few{<ph name="ITEM_COUNT" /> stavke}other{<ph name="ITEM_COUNT" /> stavki}}</translation>
<translation id="2292556288342944218">Internetski je pristup blokiran</translation>
<translation id="230155334948463882">Nova kartica?</translation>
-<translation id="2305919008529760154">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat možda lažan. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> zahtijeva korisniÄko ime i zaporku.</translation>
-<translation id="2318774815570432836">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer web-lokacija upotrebljava HSTS. Mrežne pogreÅ¡ke i napadi uglavnom su privremeni, tako da će ta stranica vjerojatno kasnije funkcionirati. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Postavkom upravlja administrator</translation>
<translation id="2354001756790975382">Druge oznake</translation>
+<translation id="2354430244986887761">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />pronašlo štetne aplikacije<ph name="END_LINK" /> na web-lokaciji <ph name="SITE" />.</translation>
<translation id="2355395290879513365">NapadaÄi možda mogu vidjeti slike koje gledate na ovoj web-lokaciji i izmijeniti ih kako bi vas prevarili.</translation>
+<translation id="2356070529366658676">Upitaj</translation>
+<translation id="2359629602545592467">Veći broj</translation>
<translation id="2359808026110333948">Nastavi</translation>
<translation id="2365563543831475020">Izvješće o rušenju programa generirano <ph name="CRASH_TIME" /> još nije preneseno</translation>
<translation id="2367567093518048410">Razina</translation>
-<translation id="2371153335857947666">{1,plural, =1{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao juÄer. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.}one{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dan. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.}few{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dana. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.}other{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat istekao prije # dana. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. Sat vaÅ¡eg raÄunala trenutaÄno je postavljen na <ph name="CURRENT_DATE" />. Je li to u redu? Ako nije, ispravite vrijeme na satu sustava, a zatim osvježite ovu stranicu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nema zamjenskih korisniÄkih suÄelja</translation>
<translation id="2384307209577226199">Zadano pravilo organizacije</translation>
<translation id="2386255080630008482">Opozvan je certifikat poslužitelja.</translation>
<translation id="2392959068659972793">Prikaži pravila bez postavljenih vrijednosti</translation>
<translation id="239429038616798445">Taj naÄin dostave nije dostupan. PokuÅ¡ajte s drugim naÄinom.</translation>
<translation id="2396249848217231973">&amp;Poništi brisanje</translation>
-<translation id="2460160116472764928">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />otkrilo zlonamjerni softver<ph name="END_LINK" /> na web-lokaciji <ph name="SITE" />. Web-lokacije koje su inaÄe sigurne ponekad mogu biti zaražene zlonamjernim softverom. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; njegov sigurnosni certifikat možda je opozvan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="2463739503403862330">Ispuni</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />pokrenuti Mrežnu dijagnostiku<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Nevažeći URL pretraživanja.</translation>
+<translation id="2482878487686419369">Obavijesti</translation>
<translation id="2491120439723279231">Certifikat poslužitelja sadrži pogreške.</translation>
<translation id="2495083838625180221">RaÅ¡Älanjivanje JSON datoteka</translation>
<translation id="2495093607237746763">Ako je potvrđen taj okvir, Chromium će pohraniti kopiju vaše kartice na uređaj radi bržeg ispunjavanja obrazaca.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Natrag</translation>
<translation id="2515629240566999685">provjerite jaÄinu signala na svom podruÄju</translation>
<translation id="2516305470678292029">Zamjenska korisniÄka suÄelja</translation>
+<translation id="2539524384386349900">Otkrij</translation>
<translation id="255002559098805027">Host <ph name="HOST_NAME" /> poslao je nevažeći odgovor.</translation>
-<translation id="2552545117464357659">Novije</translation>
<translation id="2556876185419854533">&amp;Poništi uređivanje</translation>
<translation id="2587730715158995865">IzdavaÄ: <ph name="ARTICLE_PUBLISHER" />. ProÄitajte ovaj Älanak i joÅ¡ <ph name="OTHER_ARTICLE_COUNT" />.</translation>
<translation id="2587841377698384444">ID API-ja direktorija:</translation>
<translation id="2597378329261239068">Ovaj je dokument zaštićen zaporkom. Unesite zaporku.</translation>
<translation id="2609632851001447353">Varijacije</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Nijedna}=1{1 aplikacija ($1)}=2{2 aplikacije ($1, $2)}one{# aplikacija ($1, $2, $3)}few{# aplikacije ($1, $2, $3)}other{# aplikacija ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Sat ide unaprijed</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Pristup datoteci nije dopušten</translation>
<translation id="2653659639078652383">Pošalji</translation>
<translation id="2666117266261740852">Zatvorite ostale kartice ili aplikacije</translation>
+<translation id="2670429602441959756">Ova stranica sadrži znaÄajke koje VR joÅ¡ ne podržava. Izlaz...</translation>
<translation id="2674170444375937751">Jeste li sigurni da te stranice želite izbrisati iz Vaše povijesti?</translation>
<translation id="2677748264148917807">Napusti</translation>
-<translation id="269990154133806163">Poslužitelj je prikazao certifikat koji nije javno otkriven putem pravila Transparentnost certifikata. Taj se zahtjev postavlja za neke certifikate radi provjere njihove pouzdanosti i zaštite od napada. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Popis za Äitanje</translation>
<translation id="2704283930420550640">Vrijednost ne odgovara formatu.</translation>
<translation id="2704951214193499422">Chromium nije uspio potvrditi vašu karticu. Pokušajte ponovo kasnije.</translation>
<translation id="2705137772291741111">Spremljena (predmemorirana) kopija web-lokacije nije Äitljiva.</translation>
<translation id="2709516037105925701">Automatsko popunjavanje</translation>
-<translation id="2712118517637785082">PokuÅ¡ali ste otvoriti <ph name="DOMAIN" />, ali izdavaÄ je povukao certifikat koji je poslužitelj prikazao. To znaÄi da sigurnosne vjerodajnice koje je poslužitelj prikazao nikako ne biste trebali smatrati pouzdanima. Možda komunicirate s napadaÄem. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Traži dopuštenje</translation>
<translation id="2713444072780614174">Bijela</translation>
<translation id="2720342946869265578">U blizini</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Zapis uređaja nije prisutan</translation>
<translation id="2784949926578158345">Veza je ponovo uspostavljena.</translation>
<translation id="2794233252405721443">Web-lokacija blokirana</translation>
+<translation id="2799020568854403057">Sljedeća web-lokacija sadrži štetne aplikacije</translation>
+<translation id="2803306138276472711">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />otkrilo zlonamjerni softver<ph name="END_LINK" /> na <ph name="SITE" />. Web-lokacije koje su inaÄe sigurne ponekad mogu biti zaražene zlonamjernim softverom.</translation>
<translation id="2824775600643448204">Adresna traka i traka za pretraživanje</translation>
<translation id="2826760142808435982">Veza je kriptirana i autentificirana Å¡ifrom <ph name="CIPHER" />, a <ph name="KX" /> služi za mehanizam razmjene kljuÄeva.</translation>
<translation id="2835170189407361413">Obriši obrazac</translation>
+<translation id="2856444702002559011">NapadaÄi možda pokuÅ¡avaju ukrasti vaÅ¡e podatke s web-lokacije <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (na primjer zaporke, poruke ili brojeve kreditnih kartica). <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ne uÄitavaj ponovo</translation>
<translation id="2900469785430194048">Google Chrome ostao je bez memorije dok je pokušavao prikazati ovu web-stranicu.</translation>
<translation id="2909946352844186028">Otkrivena je promjena mreže.</translation>
<translation id="2916038427272391327">Zatvorite ostale programe</translation>
<translation id="2922350208395188000">Certifikat poslužitelja nije moguće provjeriti.</translation>
<translation id="2928905813689894207">Adresa za naplatu</translation>
+<translation id="2941952326391522266">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; njegov je sigurnosni certifikat s domene <ph name="DOMAIN2" />. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="2948083400971632585">Možete onemogućiti sve proxyje konfigurirane za vezu sa stranice postavki.</translation>
<translation id="2955913368246107853">Zatvori traku za traženje</translation>
<translation id="2958431318199492670">Mrežna konfiguracija nije u skladu sa standardima ONC. Dijelove konfiguracije nije moguće uvesti.</translation>
-<translation id="29611076221683977">NapadaÄi koji se trenutaÄno nalaze na <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu pokuÅ¡ati instalirati opasne programe na vaÅ¡ Mac radi kraÄ‘e ili brisanja vaÅ¡ih podataka (na primjer, fotografija, zaporki, poruka i brojeva kreditnih kartica).</translation>
<translation id="2966678944701946121">Istek: <ph name="EXPIRATION_DATE_ABBR" />, dodano <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Za uspostavu sigurne veze sat mora biti toÄno postavljen jer certifikati pomoću kojih se web-lokacije meÄ‘usobno identificiraju vrijede samo odreÄ‘eno vrijeme. Budući da vaÅ¡ sat nije toÄan, Chrome ne može potvrditi te certifikate.</translation>
<translation id="2972581237482394796">&amp;Vrati poništeno</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Unesite važeću adresu</translation>
<translation id="2986368408720340940">Taj naÄin preuzimanja nije dostupan. PokuÅ¡ajte s nekim drugim naÄinom.</translation>
<translation id="2991174974383378012">Dijeljenje s web-lokacijama</translation>
+<translation id="2991571918955627853">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer web-lokacija upotrebljava HSTS. Mrežne pogreÅ¡ke i napadi obiÄno su privremeni, tako da će stranica kasnije vjerojatno funkcionirati.</translation>
<translation id="3005723025932146533">Prikaži spremljenu kopiju</translation>
<translation id="3008447029300691911">Unesite CVC za karticu <ph name="CREDIT_CARD" />. Nakon što ih potvrdite, podaci o kartici dijelit će se s ovom web-lokacijom.</translation>
<translation id="3010559122411665027">Unos popisa "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatski blokirano</translation>
<translation id="3024663005179499861">Pogrešna vrsta pravila</translation>
<translation id="3032412215588512954">Želite li ponovo uÄitati tu web-lokaciju?</translation>
<translation id="3037605927509011580">O, ne!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{najmanje 1 stavka na sinkroniziranim uređajima}=1{1 stavka (i više njih na sinkroniziranim uređajima)}one{# stavka (i više njih na sinkroniziranim uređajima)}few{# stavke (i više njih na sinkroniziranim uređajima)}other{# stavki (i više njih na sinkroniziranim uređajima)}}</translation>
<translation id="3041612393474885105">Podaci o certifikatu</translation>
<translation id="3063697135517575841">Chrome nije uspio potvrditi vašu karticu. Pokušajte ponovo kasnije.</translation>
<translation id="3064966200440839136">NapuÅ¡tate anonimni naÄin rada da biste platili putem vanjske aplikacije. Želite li nastaviti?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Nijedna}=1{1 zaporka}one{# zaporka}few{# zaporke}other{# zaporki}}</translation>
<translation id="3093245981617870298">Izvan mreže ste.</translation>
<translation id="3105172416063519923">ID uređaja:</translation>
<translation id="3109728660330352905">Nemate ovlaštenje za prikaz te stranice.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Pokušajte pokrenuti Dijagnostiku povezivosti<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Dekodiranje odgovora nije uspjelo</translation>
<translation id="3150653042067488994">Privremena pogreška poslužitelja</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Stranice koje pregledavate na anonimnim karticama ne zadržavaju se u povijesti preglednika, pohrani kolaÄića ili povijesti pretraživanja nakon Å¡to zatvorite sve anonimne kartice, ali će se zadržati sve datoteke koje preuzmete ili oznake koje napravite.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Otok</translation>
+<translation id="317583078218509884">Nove postavke dozvola za web-lokacije postat će aktivne nakon ponovnog uÄitavanja stranice.</translation>
<translation id="3176929007561373547">Provjerite postavke proxyja ili se obratite mrežnom administratoru da
biste provjerili je li proxy poslužitelj u funkciji. Ako mislite da ne
biste trebali upotrebljavati proxy poslužitelj:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Otvorite stranicu anonimno</translation>
-<translation id="3202578601642193415">Najnovije</translation>
+<translation id="320323717674993345">Otkaži plaćanje</translation>
<translation id="3207960819495026254">OznaÄeno</translation>
+<translation id="3225919329040284222">Poslužitelj je pokazao certifikat koji ne odgovara ugraÄ‘enim oÄekivanjima. Ta su oÄekivanja ukljuÄena za odreÄ‘ene web-lokacije s visokim stupnjem sigurnosti radi vaÅ¡e zaÅ¡tite.</translation>
<translation id="3226128629678568754">Pritisnite gumb za ponovno uÄitavanje da biste ponovo poslali podatke koji su potrebni za uÄitavanje stranice.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Prijevod nije uspio jer stranica već je na jeziku: <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Unesite CVC za karticu <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Uvijek otkrivaj važan sadržaj na ovoj web-lokaciji</translation>
<translation id="3254409185687681395">OznaÄi ovu stranicu</translation>
<translation id="3270847123878663523">&amp;Poništi promjenu rasporeda</translation>
<translation id="3282497668470633863">Dodajte ime na kartici</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">postavke</translation>
<translation id="3345135638360864351">Slanje zahtjeva za pristup ovoj web-lokaciji korisniku <ph name="NAME" /> nije uspjelo. Pokušaj ponovo.</translation>
<translation id="3355823806454867987">Promijeni proxy postavke...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />neće spremati<ph name="END_EMPHASIS" /> sljedeće informacije:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />vašu povijest pregledavanja
+ <ph name="LIST_ITEM" />kolaÄiće i podatke o web-lokacijama
+ <ph name="LIST_ITEM" />informacije koje unesete u obrasce.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Pogreška sata</translation>
-<translation id="337311366426640088">Još ovoliko stavki: <ph name="ITEM_COUNT" />...</translation>
<translation id="337363190475750230">Dodjela je uklonjena</translation>
<translation id="3377188786107721145">Pogreška pri analizi pravila</translation>
<translation id="3380365263193509176">Nepoznata pogreška</translation>
<translation id="3380864720620200369">ID klijenta:</translation>
<translation id="3391030046425686457">Adresa za dostavu</translation>
<translation id="3395827396354264108">NaÄin preuzimanja</translation>
-<translation id="340013220407300675">NapadaÄi možda pokuÅ¡avaju ukrasti vaÅ¡e podatke s web-lokacije <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (na primjer, zaporke, poruke ili kreditne kartice).</translation>
<translation id="3422248202833853650">Pokušajte zatvoriti ostale programe da biste oslobodili memoriju.</translation>
<translation id="3422472998109090673">Host <ph name="HOST_NAME" /> trenutaÄno nije dostupan.</translation>
+<translation id="3427092606871434483">Dopusti (zadano)</translation>
<translation id="3427342743765426898">&amp;Ponovi uređivanje</translation>
<translation id="3431636764301398940">Spremi tu karticu na ovaj uređaj</translation>
<translation id="3435896845095436175">Omogući</translation>
<translation id="3447661539832366887">Vlasnik tog ureÄ‘aja iskljuÄio je igru s dinosaurima.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Dohvati interval:</translation>
<translation id="3462200631372590220">Sakrij napredno</translation>
<translation id="3467763166455606212">Potrebno je unijeti ime nositelja kartice</translation>
<translation id="3478058380795961209">Mjesec isteka</translation>
<translation id="3479539252931486093">Niste to oÄekivali? <ph name="BEGIN_LINK" />Javite nam<ph name="END_LINK" />.</translation>
<translation id="3479552764303398839">Ne sada</translation>
-<translation id="348000606199325318">ID rušenja <ph name="CRASH_LOCAL_ID" /> (ID poslužitelja: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Nismo uspjeli stupiti u kontakt s tvojim roditeljem. Pokušaj ponovo.</translation>
<translation id="3528171143076753409">Certifikat poslužitelja nije pouzdan.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Najmanje 1 stavka na sinkroniziranim uređajima}=1{1 stavka (i više njih na sinkroniziranim uređajima)}one{# stavka (i više njih na sinkroniziranim uređajima)}few{# stavke (i više njih na sinkroniziranim uređajima)}other{# stavki (i više njih na sinkroniziranim uređajima)}}</translation>
<translation id="3539171420378717834">Zadrži kopiju te kartice na uređaju</translation>
<translation id="3542684924769048008">Upotrijebite zaporku za:</translation>
+<translation id="3545341443414427877">Nije moguće uspostaviti privatnu vezu s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> jer datum i vrijeme raÄunala (<ph name="DATE_AND_TIME" />) nisu toÄni. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Å ifriranje svih sinkroniziranih podataka vlastitom zaporkom za sinkronizaciju</translation>
-<translation id="3549761410225185768">Još <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer sigurnosni certifikat potjeÄe s domene <ph name="DOMAIN2" />. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Voditelj je može deblokirati</translation>
<translation id="3566021033012934673">Vaša veza nije privatna</translation>
+<translation id="3569145463236695319">&lt;p&gt;Nije moguće uspostaviti privatnu vezu s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> jer datum i vrijeme ureÄ‘aja (<ph name="DATE_AND_TIME" />) nisu toÄni.&lt;/p&gt;
+
+ &lt;p&gt;Prilagodite datum i vrijeme u odjeljku &lt;strong&gt;General&lt;/strong&gt; u aplikaciji &lt;strong&gt;Postavke&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Dodajte ime</translation>
<translation id="3583757800736429874">&amp;Ponovi premještanje</translation>
<translation id="3586931643579894722">Sakrij detalje</translation>
-<translation id="3587482841069643663">Sve</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Unesite važeći datum isteka</translation>
<translation id="36224234498066874">Obriši podatke o pregledavanju...</translation>
@@ -321,7 +361,6 @@
<translation id="3681007416295224113">Podaci o certifikatu</translation>
<translation id="3690164694835360974">Prijava nije sigurna</translation>
<translation id="3693415264595406141">Zaporka:</translation>
-<translation id="3696411085566228381">ništa</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">UÄitavanje...</translation>
<translation id="3712624925041724820">Licence su potrošene</translation>
@@ -329,12 +368,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />provjerite proxy, vatrozid i konfiguraciju DNS-a<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Ako ste svjesni sigurnosnih rizika, možete <ph name="BEGIN_LINK" />posjetiti tu nesigurnu web-lokaciju<ph name="END_LINK" /> prije uklanjanja opasnih programa.</translation>
<translation id="3739623965217189342">Veza koju ste kopirali</translation>
+<translation id="3744899669254331632">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer je web-lokacija poslala Å¡ifrirane vjerodajnice koje Chromium ne može obraditi. Mrežne pogreÅ¡ke i napadi obiÄno su privremeni, tako da će stranica kasnije vjerojatno funkcionirati.</translation>
+<translation id="3748148204939282805">NapadaÄi na web-lokaciji <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu vas na prijevaru pokuÅ¡ati navesti da napravite neÅ¡to opasno kao Å¡to je instaliranje softvera ili otkrivanje osobnih podataka (npr. zaporki, telefonskih brojeva ili brojeva kreditnih kartica). <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Prijevod nije uspio zbog poslužiteljske pogreške.</translation>
<translation id="3759461132968374835">Nemate nedavnih izvješća o padu. Ovdje se neće prikazati padovi do kojih je došlo kada je izvješćivanje o padovima onemogućeno.</translation>
+<translation id="3778403066972421603">Želite li spremiti ovu karticu na svoj Google raÄun i na ovaj ureÄ‘aj?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">IstjeÄe <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Ako upotrebljavate proxy poslužitelj...</translation>
<translation id="3828924085048779000">Prazne zaporke nisu dopuštene.</translation>
-<translation id="3845539888601087042">Prikazuje se povijest s uređaja na kojima ste prijavljeni. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Natrag</translation>
<translation id="3858027520442213535">Ažuriraj datum i vrijeme</translation>
<translation id="3884278016824448484">Identifikator uređaja sukobljen je</translation>
@@ -342,11 +384,13 @@
<translation id="3886446263141354045">Zahtjev za pristup toj web-lokaciji poslan je korisniku <ph name="NAME" /></translation>
<translation id="3890664840433101773">Dodajte e-adresu</translation>
<translation id="3901925938762663762">Kartica je istekla</translation>
-<translation id="3933571093587347751">{1,plural, =1{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan sutra. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.}one{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan # dan u budućnosti. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.}few{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan # dana u budućnosti. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.}other{Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer je sigurnosni certifikat navodno izdan # dana u budućnosti. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">UÄitavanje dokumenta PDF nije uspjelo</translation>
+<translation id="3945915738023014686">Preneseno je izvješće o rušenju programa s ID-om <ph name="CRASH_ID" /> (lokalni ID rušenja: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; njegov sigurnosni certifikat ne navodi alternativne nazive predmeta. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="3963721102035795474">NaÄin ÄitaÄa</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Nijedna}=1{S 1 web-lokacije }one{S/sa # web-lokacije }few{S/sa # web-lokacije }other{S/sa # web-lokacija }}</translation>
<translation id="397105322502079400">IzraÄun u tijeku…</translation>
<translation id="3973234410852337861">Host <ph name="HOST_NAME" /> je blokiran</translation>
+<translation id="3987940399970879459">Manje od 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 web-stranica u blizini}one{# web-stranica u blizini}few{# web-stranice u blizini}other{# web-stranica u blizini}}</translation>
<translation id="4021036232240155012">DNS je mrežna usluga koja prevodi naziv web-lokacije u njezinu internetsku adresu.</translation>
<translation id="4030383055268325496">&amp;Poništi dodavanje</translation>
@@ -357,56 +401,63 @@
<translation id="4079302484614802869">Konfiguracija proxy poslužitelja postavljena je za upotrebu URL-a .pac skripte, a ne fiksnih proxy poslužitelja.</translation>
<translation id="4098354747657067197">Pred vama je obmanjujuća web-lokacija</translation>
<translation id="4103249731201008433">Serijski broj uređaja nije važeći</translation>
+<translation id="410351446219883937">Automatska reprodukcija</translation>
<translation id="4103763322291513355">Posjetite &lt;strong&gt;chrome://policy&lt;/strong&gt; da biste vidjeli popis nedopuštenih URL-ova i druga pravila koja je nametnuo vaš administrator sustava.</translation>
-<translation id="4110615724604346410">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer sigurnosni certifikat sadrži pogreške. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Uvijek dopusti na ovoj web-lokaciji</translation>
<translation id="4117700440116928470">Opseg pravila nije podržan.</translation>
-<translation id="4118212371799607889">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer Chromium sigurnosni certifikat ne smatra pouzdanim. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 druga stavka}one{# druga stavka}few{# druge stavke}other{# drugih stavki}}</translation>
<translation id="4130226655945681476">provjerite mrežne kabele, modem i usmjerivaÄ</translation>
+<translation id="413544239732274901">Saznajte više</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Upotrijebi globalnu zadanu postavku (Otkrij)</translation>
+<translation id="4165986682804962316">Postavke web-lokacije</translation>
<translation id="4169947484918424451">Želite li da Chromium spremi tu karticu?</translation>
<translation id="4171400957073367226">Potpis za potvrdu nije ispravan.</translation>
<translation id="4196861286325780578">&amp;Ponovi premještanje</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />provjerite vatrozid i konfiguraciju antivirusnog programa<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ništa}=1{1 aplikacija ($1)}=2{2 aplikacije ($1, $2)}one{# aplikacija ($1, $2, $3)}few{# aplikacije ($1, $2, $3)}other{# aplikacija ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Padovi programa</translation>
+<translation id="422022731706691852">NapadaÄi na web-lokaciji <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu vas pokuÅ¡ati navesti na instaliranje programa koji smanjuju kvalitetu pregledavanja interneta (na primjer, promjenom poÄetne stranice ili prikazivanjem dodatnih oglasa na web-lokacijama koje posjetite). <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Pokušajte pokrenuti Mrežnu dijagnostiku<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Važeći</translation>
<translation id="4250431568374086873">Veza s ovom web-lokacijom nije potpuno sigurna</translation>
<translation id="4250680216510889253">Ne</translation>
<translation id="425582637250725228">Unesene promjene ne mogu se spremiti.</translation>
<translation id="4258748452823770588">Potpis nije valjan</translation>
+<translation id="4265872034478892965">Dopustio administrator</translation>
<translation id="4269787794583293679">(Nema korisniÄkog imena)</translation>
<translation id="4275830172053184480">Ponovo pokrenite svoj uređaj</translation>
<translation id="4280429058323657511">, istek <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />pronašlo štetne programe<ph name="END_LINK" /> na web-lokaciji <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Nadređeni prijedlozi</translation>
<translation id="4304224509867189079">Prijavi se</translation>
-<translation id="432290197980158659">Poslužitelj je prikazao certifikat koji ne odgovara ugraÄ‘enim oÄekivanjima. Ta su oÄekivanja ukljuÄena za odreÄ‘ene web-lokacije visoke razine sigurnosti radi vaÅ¡e zaÅ¡tite. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blokiraj (zadano)</translation>
<translation id="4325863107915753736">Članak nije pronađen</translation>
<translation id="4326324639298822553">Provjerite datum isteka, pa pokušajte ponovo</translation>
<translation id="4331708818696583467">Nije sigurno</translation>
<translation id="4356973930735388585">NapadaÄi na ovoj web-lokaciji mogu pokuÅ¡ati instalirati opasne programe na vaÅ¡e raÄunalo radi kraÄ‘e ili brisanja vaÅ¡ih podataka (na primjer fotografija, zaporki, poruka i brojeva kreditnih kartica).</translation>
<translation id="4372948949327679948">OÄekivana vrijednost vrste <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">PokuÅ¡ali ste doseći domenu <ph name="DOMAIN" />, ali certifikat koji je poslužitelj predstavio povuÄen je od strane izdavaÄa. Prema tome nikako ne biste trebali vjerovati sigurnosnim certifikatima koje predstavlja poslužitelj. Možda komunicirate s napadaÄem.</translation>
<translation id="4381091992796011497">Ime korisnika:</translation>
<translation id="4394049700291259645">Onemogući</translation>
<translation id="4406896451731180161">rezultati pretraživanja</translation>
+<translation id="4424024547088906515">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; Chrome smatra da njegov sigurnosni certifikat nije pouzdan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="4432688616882109544">Host <ph name="HOST_NAME" /> nije prihvatio vaš certifikat za prijavu ili certifikat nije poslan.</translation>
<translation id="443673843213245140">Upotreba proxy poslužitelja onemogućena je, ali odreÄ‘ena je izriÄita konfiguracija proxy poslužitelja.</translation>
-<translation id="4492190037599258964">Rezultati pretraživanja za upit '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Pogreška pri provjeri valjanosti: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4506599922270137252">kontaktirajte administratora sustava</translation>
<translation id="450710068430902550">Dijeljenje s administratorom</translation>
<translation id="4515275063822566619">Kartice i adrese dolaze iz Cromea i vaÅ¡eg Google raÄuna (<ph name="ACCOUNT_EMAIL" />). Njima možete upravljati u <ph name="BEGIN_LINK" />Postavkama<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detalji</translation>
+<translation id="4552089082226364758">Bljeskalica</translation>
<translation id="4558551763791394412">Pokušajte onemogućiti proširenja.</translation>
<translation id="457875822857220463">Dostava</translation>
<translation id="4587425331216688090">Želite li s Chromea ukloniti adresu?</translation>
-<translation id="4589078953350245614">Pokušali ste otvoriti <ph name="DOMAIN" />, ali poslužitelj je prikazao nevažeći certifikat. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Vaša veza s domenom <ph name="DOMAIN" /> kriptirana je modernim kriptografskim paketom.</translation>
<translation id="4594403342090139922">&amp;Poništi brisanje</translation>
<translation id="4619615317237390068">Kartice s drugih uređaja</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; njegov sigurnosni certifikat sadrži pogreške. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
+<translation id="4690462567478992370">Prestani upotrebljavati nevažeći certifikat</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Veza je prekinuta</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />pokrenuti Mrežnu dijagnostiku sustava Windows<ph name="END_LINK" /></translation>
@@ -423,21 +474,24 @@
<translation id="4771973620359291008">Došlo je do nepoznate pogreške.</translation>
<translation id="4800132727771399293">Provjerite datum isteka i CVC pa pokušajte ponovo</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">TrenutaÄno ne možete posjetiti <ph name="SITE" /> jer je web-lokacija poslala kodirane vjerodajnice koje Google Chrome ne može obraditi. Mrežne pogreÅ¡ke i napadi uglavnom su privremeni, tako da će ta stranica vjerojatno kasnije funkcionirati.</translation>
<translation id="4813512666221746211">Pogreška mreže</translation>
<translation id="4816492930507672669">Prilagodi stranici</translation>
<translation id="483020001682031208">Nema nijedne stranice FiziÄkog weba za prikazivanje</translation>
<translation id="4850886885716139402">Prikaz</translation>
<translation id="4854362297993841467">Taj naÄin dostave nije dostupan. PokuÅ¡ajte s nekim drugim naÄinom.</translation>
<translation id="4858792381671956233">Pitao si roditelje smiješ li otvoriti tu web-lokaciju</translation>
+<translation id="4863764087567530506">Ovaj vas sadržaj može na prijevaru pokušati navesti da instalirate softver ili odate svoje osobne podatke. <ph name="BEGIN_LINK" />Ipak prikaži<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Pretraži povijest</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{i još 1 web-stranica}one{i još # web-stranica}few{i još # web-stranice}other{i još # web-stranica}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Ova je stranica prevedena s nepoznatog jezika na <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Plaćanje</translation>
<translation id="4926049483395192435">Mora biti određeno.</translation>
<translation id="495170559598752135">Radnje</translation>
<translation id="4958444002117714549">Proširi popis</translation>
-<translation id="4962322354953122629">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer Chrome sigurnosni certifikat ne smatra pouzdanim. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Ponovo omogući upozorenja</translation>
<translation id="4989809363548539747">Taj dodatak nije podržan</translation>
<translation id="5002932099480077015">Ako je to omogućeno, Chrome će pohraniti kopiju vaše kartice na ovom uređaju radi bržeg ispunjavanja obrazaca.</translation>
<translation id="5018422839182700155">Stranica se ne može otvoriti</translation>
@@ -445,14 +499,15 @@
<translation id="5023310440958281426">Provjerite pravila svojeg administratora</translation>
<translation id="5029568752722684782">Izbriši kopiju</translation>
<translation id="5031870354684148875">O Google Prevoditelju</translation>
+<translation id="5039804452771397117">Dopusti</translation>
<translation id="5040262127954254034">Privatnost</translation>
<translation id="5045550434625856497">Pogrešna zaporka</translation>
<translation id="5056549851600133418">PreporuÄeni Älanci</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />provjerite proxy adresu<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Nema kolaÄića}=1{1 web-lokacija upotrebljava kolaÄiće. }one{# web-lokacija upotrebljava kolaÄiće. }few{# web-lokacije upotrebljavaju kolaÄiće. }other{# web-lokacija upotrebljava kolaÄiće. }}</translation>
<translation id="5087286274860437796">Certifikat poslužitelja trenutaÄno nije važeći.</translation>
<translation id="5087580092889165836">Dodaj karticu</translation>
<translation id="5089810972385038852">Država</translation>
+<translation id="5094747076828555589">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; Chromium smatra da njegov sigurnosni certifikat nije pouzdan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
<translation id="5095208057601539847">Provincija</translation>
<translation id="5115563688576182185">(64-bitni)</translation>
<translation id="5141240743006678641">Å ifriranje sinkroniziranih zaporki s vjerodajnicama za Google</translation>
@@ -468,24 +523,24 @@
<translation id="5222812217790122047">E-pošta (obavezno)</translation>
<translation id="5251803541071282808">Oblak</translation>
<translation id="5277279256032773186">Upotrebljavate li Chrome na poslu? Tvrtke mogu upravljati Chromeovim postavkama za svoje zaposlenike. Saznajte više</translation>
+<translation id="5297526204711817721">Veza s tom web-lokacijom nije privatna. Da biste zatvorili VR naÄin, skinite masku i pritisnite Natrag.</translation>
<translation id="5299298092464848405">Pogreška u pravilu analize</translation>
-<translation id="5300589172476337783">Prikaži</translation>
<translation id="5308689395849655368">Onemogućeno je izvješćivanje o padu.</translation>
<translation id="5317780077021120954">Spremi</translation>
<translation id="5327248766486351172">Naziv</translation>
-<translation id="5337705430875057403">NapadaÄi na <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu vas na prijevaru pokuÅ¡ati navesti da napravite neÅ¡to opasno kao Å¡to je instaliranje softvera ili otkrivanje osobnih podataka (na primjer, zaporki, telefonskih brojeva ili kreditnih kartica).</translation>
-<translation id="5359637492792381994">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer sigurnosni certifikat trenutaÄno nije važeći. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">TrenutaÄno ne možete otvoriti web-lokaciju <ph name="SITE" /> jer je njezin certifikat opozvan. Mrežne pogreÅ¡ke i napadi uglavnom su privremeni i ta bi stranica kasnije trebala funkcionirati.</translation>
<translation id="536296301121032821">Pohrana postavki pravila nije uspjela</translation>
<translation id="5386426401304769735">Lanac certifikata za ovu web-lokaciju sadrži certifikat s SHA-1 potpisom.</translation>
<translation id="5402410679244714488">Istek: <ph name="EXPIRATION_DATE_ABBR" />, posljednja upotreba prije više od godinu dana</translation>
+<translation id="540969355065856584">Poslužitelj nije uspio dokazati da je <ph name="DOMAIN" />; njegov sigurnosni certifikat trenutaÄno nije važeći. Uzrok tomu može biti pogreÅ¡na konfiguracija ili napadaÄ koji je prekinuo vaÅ¡u vezu.</translation>
<translation id="5421136146218899937">Obriši podatke pregledavanja...</translation>
<translation id="5430298929874300616">Ukloni oznaku</translation>
<translation id="5431657950005405462">Datoteka nije pronađena</translation>
-<translation id="5435775191620395718">Prikazuje se povijest s ovog uređaja. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Pogreška provjere sheme na lokaciji "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Tu stranicu na <ph name="HOST_NAME" /> nije moguće pronaći</translation>
<translation id="5455374756549232013">Vremenska oznaka pravila koje nije valjano</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> od <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Nije važeće</translation>
<translation id="5470861586879999274">&amp;Ponovi uređivanje</translation>
<translation id="54817484435770891">Dodajte važeću adresu</translation>
<translation id="5492298309214877701">Web-lokacija na intranetu tvrtke, organizacije ili Å¡kole ima isti URL kao i vanjska web-lokacija.
@@ -502,6 +557,8 @@
<translation id="5571083550517324815">Preuzimanje na toj adresi nije moguće. Odaberite drugu adresu.</translation>
<translation id="5572851009514199876">Pokrenite Chrome i prijavite se na njega kako bi mogao provjeriti imate li dopuštenje za pristup toj web-lokaciji.</translation>
<translation id="5580958916614886209">Provjerite mjesec isteka, pa pokušajte ponovo</translation>
+<translation id="5586446728396275693">Nema nijedne spremljene adrese</translation>
+<translation id="5595485650161345191">Uređivanje adrese</translation>
<translation id="560412284261940334">Upravljanje nije podržano</translation>
<translation id="5610142619324316209">provjerite vezu</translation>
<translation id="5610807607761827392">Karticama i adresama možete upravljati u <ph name="BEGIN_LINK" />Postavkama<ph name="END_LINK" />.</translation>
@@ -509,15 +566,18 @@
<translation id="5622887735448669177">Želite li zatvoriti tu web-lokaciju?</translation>
<translation id="5629630648637658800">UÄitavanje postavki pravila nije uspjelo</translation>
<translation id="5631439013527180824">Token za upravljanje uređajem nije važeći</translation>
+<translation id="5633066919399395251">NapadaÄi koji su trenutaÄno na web-lokaciji <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu pokuÅ¡ati instalirati opasne programe na vaÅ¡e raÄunalo radi kraÄ‘e ili brisanja vaÅ¡ih podataka (na primjer fotografija, zaporki, poruka i brojeva kreditnih kartica). <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Lokacija</translation>
+<translation id="5659593005791499971">E-pošta</translation>
<translation id="5669703222995421982">Predlaganje sadržaja</translation>
<translation id="5675650730144413517">Stranica ne funkcionira</translation>
-<translation id="5677928146339483299">Blokirano</translation>
-<translation id="5694783966845939798">PokuÅ¡ali ste otvoriti <ph name="DOMAIN" />, ali je poslužitelj pružio certifikat potpisan slabim algoritmom potpisa (kao Å¡to je SHA-1). To znaÄi da su sigurnosne vjerodajnice koje je poslužitelj pružio možda krivotvorene, a poslužitelj možda nije onaj koji oÄekujete (možda komunicirate s napadaÄem). <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Identitet ove web lokacije nije ovjeren.</translation>
+<translation id="5713016350996637505">Blokiran je obmanjujući sadržaj</translation>
<translation id="5720705177508910913">TrenutaÄni korisnik:</translation>
<translation id="5732392974455271431">Tvoji je roditelji mogu deblokirati</translation>
<translation id="5763042198335101085">Unesite važeću e-adresu</translation>
<translation id="5765072501007116331">Odaberite adresu za prikaz naÄina dostave i zahtjeva za dostavu.</translation>
+<translation id="5778550464785688721">Potpuni nadzor nad MIDI uređajima</translation>
<translation id="5784606427469807560">Pojavio se problem prilikom potvrđivanja kartice. Provjerite internetsku vezu i pokušajte ponovo.</translation>
<translation id="5785756445106461925">Nadalje, ova stranica sadrži druge resurse koji nisu sigurni. Te resurse mogu vidjeti drugi tijekom prijenosa i napadaÄ ih može izmijeniti kako bi promijenio izgled stranice.</translation>
<translation id="5786044859038896871">Želite li ispuniti podatke o kartici?</translation>
@@ -526,14 +586,14 @@
<translation id="5813119285467412249">&amp;Ponovi dodavanje</translation>
<translation id="5814352347845180253">Možda ćete izgubiti pristup premium sadržaju s web-lokacije <ph name="SITE" /> i nekih drugih web-lokacija.</translation>
<translation id="5838278095973806738">Na ovu web-lokaciju nemojte unositi osjetljive podatke (na primjer, zaporke ili kreditne kartice) jer su je možda ukrali napadaÄi.</translation>
-<translation id="5843436854350372569">PokuÅ¡ali ste otvoriti <ph name="DOMAIN" />, ali poslužitelj je prikazao certifikat sa slabim kljuÄem. Privatni je kljuÄ možda otkriven, a poslužitelj možda nije onaj koji oÄekujete (možda komunicirate s napadaÄem). <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Web-lokacija ne može se dohvatiti</translation>
<translation id="5869522115854928033">Spremljene zaporke</translation>
<translation id="5872918882028971132">Nadređeni prijedlozi</translation>
<translation id="5901630391730855834">Žuta</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sinkronizirano)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 u upotrebi}one{# u upotrebi}few{# u upotrebi}other{# u upotrebi}}</translation>
<translation id="5926846154125914413">Možda ćete izgubiti pristup premium sadržaju s nekih web-lokacija.</translation>
<translation id="5959728338436674663">Automatski šalji Googleu neke <ph name="BEGIN_WHITEPAPER_LINK" />podatke o sustavu i sadržaj stranice<ph name="END_WHITEPAPER_LINK" /> radi otkrivanja opasnih aplikacija i web-lokacija. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Tjedan</translation>
<translation id="5967867314010545767">Ukloni iz povijesti</translation>
<translation id="5975083100439434680">Smanji</translation>
<translation id="598637245381783098">Aplikacija za plaćanje ne može se otvoriti</translation>
@@ -542,21 +602,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1. stranica}one{#. stranica}few{#. stranica}other{#. stranica}}</translation>
<translation id="6017514345406065928">Zelena</translation>
+<translation id="6017850046339264347">NapadaÄi na web-lokaciji <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogli bi instalirati obmanjujuće aplikacije koje se pretvaraju da su neÅ¡to drugo ili prikupljaju podatke na temelju kojih vas je moguće pratiti. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sinkronizirano)</translation>
<translation id="6027201098523975773">Unesite ime</translation>
<translation id="6040143037577758943">Zatvori</translation>
<translation id="6042308850641462728">Više</translation>
+<translation id="6047233362582046994">Ako ste svjesni sigurnosnih rizika, možete <ph name="BEGIN_LINK" />posjetiti ovu web-lokaciju<ph name="END_LINK" /> prije uklanjanja štetnih aplikacija.</translation>
+<translation id="6051221802930200923">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer web-lokacija upotrebljava prikvaÄivanje certifikata. Mrežne pogreÅ¡ke i napadi obiÄno su privremeni, tako da će stranica kasnije vjerojatno funkcionirati.</translation>
<translation id="6060685159320643512">Oprez, ovi eksperimenti mogu ugristi</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ništa}=1{1}one{#}few{#}other{#}}</translation>
+<translation id="6080696365213338172">Pristupili ste sadržaju pomoću certifikata koji je izdao administrator. Administrator može presresti podatke koje dostavljate domeni <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Nijedna}=1{1 zaporka (sinkronizirana)}one{# zaporka (sinkronizirana)}few{# zaporke (sinkronizirane)}other{# zaporki (sinkroniziranih)}}</translation>
<translation id="6146055958333702838">Provjerite kabele i ponovo pokrenite usmjerivaÄe, modeme ili druge mrežne
uređaje koje možda upotrebljavate.</translation>
<translation id="614940544461990577">Pokušajte sljedeće:</translation>
<translation id="6151417162996330722">Certifikat poslužitelja ima predugo razdoblje valjanosti.</translation>
<translation id="6157877588268064908">Odaberite adresu za prikaz naÄina dostave i zahtjeva za dostavu</translation>
+<translation id="6158003235852588289">Google sigurno pregledavanje nedavno je otkrilo krađu identiteta na web-lokaciji <ph name="SITE" />. Web-lokacije za krađu identiteta predstavljaju se kao druge web-lokacije kako bi vas prevarile.</translation>
<translation id="6165508094623778733">Saznajte više</translation>
+<translation id="6169916984152623906">Sada možete pregledavati privatno i ostali korisnici ovog uređaja neće vidjeti vaše aktivnosti. No spremit će se preuzimanja i oznake.</translation>
<translation id="6177128806592000436">Veza s web-lokacijom nije sigurna</translation>
<translation id="6184817833369986695">(skupina: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Provjerite internetsku vezu</translation>
<translation id="6218753634732582820">Želite li ukloniti adresu iz Chromiuma?</translation>
+<translation id="6221345481584921695">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />otkrilo zlonamjerni sadržaj<ph name="END_LINK" /> na <ph name="SITE" />. Web-lokacije koje su inaÄe sigurne ponekad mogu biti zaražene zlonamjernim softverom. Zlonamjerni sadržaj potjeÄe s hosta <ph name="SUBRESOURCE_HOST" /> koji je poznat po distribuciji zlonamjernog softvera.</translation>
<translation id="6251924700383757765">Pravila o privatnosti</translation>
<translation id="6254436959401408446">Nema dovoljno memorije za otvaranje ove stranice</translation>
<translation id="625755898061068298">Onemogućili ste sigurnosna upozorenja za tu web-lokaciju.</translation>
@@ -582,15 +650,14 @@
<translation id="6404511346730675251">Uredi oznaku</translation>
<translation id="6410264514553301377">Unesite datum isteka i CVC za karticu <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Pitao si roditelja smiješ li otvoriti tu web-lokaciju</translation>
-<translation id="6416403317709441254">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer je web-lokacija poslala kodirane vjerodajnice koje Chromium ne može obraditi. Mrežne pogreÅ¡ke i napadi uglavnom su privremeni, tako da će ta stranica vjerojatno kasnije funkcionirati. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Nije moguće provjeriti je li certifikat opozvan.</translation>
<translation id="6433490469411711332">Uređivanje podataka za kontakt</translation>
<translation id="6433595998831338502">Host <ph name="HOST_NAME" /> odbio je povezivanje.</translation>
<translation id="6446608382365791566">Dodajte još podataka</translation>
+<translation id="6447842834002726250">KolaÄići</translation>
<translation id="6451458296329894277">Potvrdi ponovno slanje obrasca</translation>
<translation id="6456339708790392414">Vaše plaćanje</translation>
<translation id="6458467102616083041">Zanemareno jer je zadano pretraživanje onemogućeno pravilom.</translation>
-<translation id="6462969404041126431">Poslužitelj ne može dokazati da je to <ph name="DOMAIN" /> jer bi sigurnosni certifikat mogao biti opozvan. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Pravila uređaja</translation>
<translation id="6477321094435799029">Chrome je otkrio neuobiÄajeni kôd na toj stranici i blokirao ju je radi zaÅ¡tite vaÅ¡ih osobnih podataka (primjerice zaporki, telefonskih brojeva i kreditnih kartica).</translation>
<translation id="6489534406876378309">Pokreni prijenos rušenja</translation>
@@ -602,20 +669,19 @@
<translation id="6556915248009097796">Istek: <ph name="EXPIRATION_DATE_ABBR" />, posljednja upotreba <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Voditelj je još nije odobrio</translation>
<translation id="6569060085658103619">Gledate stranicu proširenja</translation>
-<translation id="6593753688552673085">manje od <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Ovaj sadržaj može pokušati na vaš uređaj instalirati opasan softver koji krade ili briše podatke. <ph name="BEGIN_LINK" />Ipak prikaži<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opcije Å¡ifriranja</translation>
<translation id="662080504995468778">Ostani</translation>
<translation id="6626291197371920147">Dodajte važeći broj kartice</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Pretraživanje</translation>
+<translation id="6630809736994426279">NapadaÄi koji su trenutaÄno na web-lokaciji <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu pokuÅ¡ati instalirati opasne programe na vaÅ¡ Mac radi kraÄ‘e ili brisanja vaÅ¡ih podataka (na primjer fotografija, zaporki, poruka i brojeva kreditnih kartica). <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Ovo je pravilo zastarjelo.</translation>
-<translation id="6652240803263749613">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer operativni sustav raÄunala sigurnosni certifikat ne smatra pouzdanim. Razlog može biti pogreÅ¡na konfiguracija ili napad na vaÅ¡u vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Želite li ukloniti prijedlog iz Chromiuma?</translation>
<translation id="6685834062052613830">Odjavite se i dovršite postavljanje</translation>
<translation id="6710213216561001401">Prethodno</translation>
<translation id="6710594484020273272">&lt;Upišite pojam za pretraživanje&gt;</translation>
<translation id="6711464428925977395">NeÅ¡to nije u redu s proxy poslužiteljem ili adresa nije toÄna.</translation>
<translation id="6727102863431372879">Postavi</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ništa}=1{1 stavka}one{# stavka}few{# stavke}other{# stavki}}</translation>
<translation id="674375294223700098">Nepoznata pogreška certifikata poslužitelja</translation>
<translation id="6753269504797312559">Vrijednost pravila</translation>
<translation id="6757797048963528358">Uređaj je u stanju mirovanja.</translation>
@@ -623,6 +689,8 @@
<translation id="6810899417690483278">ID prilagođavanja</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">UÄitavanje podataka regija nije uspjelo</translation>
+<translation id="6825578344716086703">PokuÅ¡ali ste doseći domenu <ph name="DOMAIN" />, ali poslužitelj je predstavio certifikat potpisan slabim algoritmom potpisa (kao Å¡to je SHA-1). ZnaÄi da su sigurnosne vjerodajnice koje je poslužitelj predstavio možda krivotvorene, a poslužitelj možda nije poslužitelj koji oÄekujete (možda ste u komunikaciji s napadaÄem).</translation>
+<translation id="6830728435402077660">Nije sigurno</translation>
<translation id="6831043979455480757">Prevedi</translation>
<translation id="6839929833149231406">PodruÄje</translation>
<translation id="6874604403660855544">&amp;Ponovi dodavanje</translation>
@@ -630,6 +698,7 @@
<translation id="6895330447102777224">Kartica je potvrđena</translation>
<translation id="6897140037006041989">KorisniÄki agent</translation>
<translation id="6915804003454593391">Korisnik:</translation>
+<translation id="6945221475159498467">Odaberi</translation>
<translation id="6948701128805548767">Odaberite adresu za prikaz naÄina preuzimanja i zahtjeva za preuzimanje</translation>
<translation id="6957887021205513506">Certifikat poslužitelja izgleda kao falsifikat.</translation>
<translation id="6965382102122355670">U redu</translation>
@@ -638,15 +707,16 @@
<translation id="6973656660372572881">Određeni su fiksni proxy poslužitelji i URL .pac skripte.</translation>
<translation id="6989763994942163495">Pokaži napredne postavke...</translation>
<translation id="7000990526846637657">Unosi povijesti nisu pronađeni</translation>
-<translation id="7009986207543992532">PokuÅ¡ali ste otvoriti <ph name="DOMAIN" />, ali poslužitelj je prikazao certifikat Äije je razdoblje valjanosti predugo da bi bilo vjerodostojno. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Na Google raÄunu možda postoje drugi oblici povijesti pregledavanja na stranici <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Zaporke</translation>
+<translation id="7050187094878475250">Pokušali ste pristupiti domeni <ph name="DOMAIN" />, ali je poslužitelj pružio certifikat koji nije pouzdan zbog predugog razdoblja valjanosti.</translation>
+<translation id="7053983685419859001">Blokiraj</translation>
<translation id="7064851114919012435">Podaci za kontakt</translation>
<translation id="7079718277001814089">Ova web-lokacija sadrži zlonamjerni softver</translation>
<translation id="7087282848513945231">Županija</translation>
-<translation id="7088615885725309056">Starije</translation>
<translation id="7090678807593890770">Potražite upit <ph name="LINK" /> na Googleu</translation>
+<translation id="7108819624672055576">Dopustilo proširenje</translation>
<translation id="7119414471315195487">Zatvorite ostale kartice ili programe</translation>
<translation id="7129409597930077180">Dostava na tu adresu nije moguća. Odaberite drugu adresu.</translation>
<translation id="7138472120740807366">NaÄin isporuke</translation>
@@ -664,22 +734,18 @@
<translation id="7220786058474068424">Obrada</translation>
<translation id="724691107663265825">Web-lokacija pred vama sadrži zlonamjerni softver</translation>
<translation id="724975217298816891">Unesite datum isteka i CVC za karticu <ph name="CREDIT_CARD" /> da biste ažurirali podatke o kartici. Nakon što ih potvrdite, podaci o kartici dijelit će se s ovom web-lokacijom.</translation>
-<translation id="725866823122871198">Sigurnu vezu s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nije moguće uspostaviti jer datum i vrijeme na raÄunalu (<ph name="DATE_AND_TIME" />) nisu toÄni.</translation>
+<translation id="7260504762447901703">Opoziv pristupa</translation>
<translation id="7275334191706090484">Upravljane oznake</translation>
<translation id="7298195798382681320">PreporuÄeno</translation>
<translation id="7309308571273880165">Izvješće o rušenju programa generirano <ph name="CRASH_TIME" /> (prijenos zatražio korisnik, još nije preneseno)</translation>
<translation id="7334320624316649418">&amp;Ponovi promjenu rasporeda</translation>
<translation id="733923710415886693">Certifikat poslužitelja nije otkriven putem Transparentnosti certifikata.</translation>
-<translation id="7351800657706554155">TrenutaÄno ne možete otvoriti <ph name="SITE" /> jer je certifikat te web-lokacije opozvan. Mrežne pogreÅ¡ke i napadi uglavnom su privremeni, tako da će stranica vjerojatno kasnije funkcionirati. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Naredbeni redak</translation>
<translation id="7372973238305370288">rezultat pretraživanja</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ne</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Potvrda kartice</translation>
-<translation id="7394102162464064926">Jeste li sigurni da želite izbrisati te stranice iz svoje povijesti?
-
-Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KEY" />.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Putanja profila</translation>
<translation id="7424977062513257142">Ugrađena stranica na ovoj web-lokaciji navodi sljedeće:</translation>
@@ -687,6 +753,7 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="7444046173054089907">Ova je web-lokacija blokirana</translation>
<translation id="7445762425076701745">Identitet poslužitelja s kojim ste se povezali ne može se u potpunosti potvrditi. Povezali ste se s poslužiteljem upotrebom imena koje je valjano samo unutar vaÅ¡e mreže, a za koje vanjsko tijelo za izdavanje certifikata nikako ne može potvrditi vlasniÅ¡tvo. Budući da postoje tijela za izdavanje certifikata koja će izdati certifikat za ta imena bez obzira na sve, nema naÄina da budete sigurni da ste povezani sa željenom web-lokacijom, a ne s napadaÄem.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /> o tom problemu.</translation>
+<translation id="7455133967321480974">Upotrijebi globalnu zadanu vrijednost (blokiraj)</translation>
<translation id="7460163899615895653">Ovdje se prikazuju vaše nedavne kartice s drugih uređaja</translation>
<translation id="7469372306589899959">Potvrđivanje kartice</translation>
<translation id="7481312909269577407">Naprijed</translation>
@@ -694,36 +761,43 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="7508255263130623398">Vraćeni ID ureÄ‘aja pravila prazan je ili ne odgovara trenutaÄnom ID-u ureÄ‘aja</translation>
<translation id="7514365320538308">Preuzmi</translation>
<translation id="7518003948725431193">Za web-adresu nije pronađena web-stranica:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Vrijednost</translation>
<translation id="7537536606612762813">Obavezno</translation>
+<translation id="7542403920425041731">Nakon što ih potvrdite, podaci o kartici dijelit će se s ovom web-lokacijom.</translation>
<translation id="7542995811387359312">Automatsko popunjavanje kreditne kartice onemogućeno je jer se ovaj obrazac ne služi sigurnom vezom.</translation>
<translation id="7543525346216957623">Zamoli roditelja</translation>
<translation id="7549584377607005141">Ova web-stranica zahtijeva podatke koje ste ranije unijeli da bi se pravilno prikazala. Te podatke možete poslati ponovo, ali time ćete ponoviti sve radnje koje je ta stranica prethodno izvela.</translation>
<translation id="7552846755917812628">PokuÅ¡ajte uÄiniti sljedeće:</translation>
<translation id="7554791636758816595">Nova kartica</translation>
+<translation id="7567204685887185387">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; njegov sigurnosni certifikat možda je lažan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Ova je stranica na ovom jeziku:<ph name="ORIGINAL_LANGUAGE" />Želite li je prevesti?</translation>
<translation id="7569952961197462199">Želite li s Chromea ukloniti kreditnu karticu?</translation>
<translation id="7569983096843329377">Crna</translation>
<translation id="7578104083680115302">Plaćajte brzo na web-lokacijama i u aplikacijama na više uređaja karticama koje ste spremili na Google.</translation>
<translation id="7588950540487816470">FiziÄki web</translation>
<translation id="7592362899630581445">Certifikat poslužitelja krÅ¡i ograniÄenja naziva.</translation>
+<translation id="7598391785903975535">Manje od <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Host <ph name="HOST_NAME" /> trenutaÄno ne može obraditi zahtjev.</translation>
<translation id="7600965453749440009">Nikad ne prevodi <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Vrijednost je izvan raspona <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">IstjeÄe: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Već imate podatke koji su kriptirani pomoću druge verzije zaporke vaÅ¡eg Google raÄuna. Unesite je u nastavku.</translation>
-<translation id="7634554953375732414">Veza s web-lokacijom nije privatna.</translation>
<translation id="7637571805876720304">Želite li ukloniti kreditnu karticu iz Chromiuma?</translation>
<translation id="765676359832457558">Skrivanje naprednih postavki...</translation>
<translation id="7658239707568436148">Odustani</translation>
+<translation id="7662298039739062396">Postavkom upravlja proširenje</translation>
<translation id="7667346355482952095">Vraćeni token pravila prazan je ili ne odgovara trenutaÄnom tokenu</translation>
<translation id="7668654391829183341">Nepoznati uređaj</translation>
<translation id="7669271284792375604">NapadaÄi na ovoj web-lokaciji mogu vas pokuÅ¡ati navesti na instaliranje programa koji smanjuju kvalitetu pregledavanja interneta (npr. promjenom poÄetne stranice ili prikazivanjem dodatnih oglasa na web-lokacijama koje posjetite).</translation>
<translation id="7674629440242451245">Zanimaju li vas nove, kul znaÄajke preglednika Chrome? Isprobajte naÅ¡ razvojni kanal na stranici chrome.com/dev.</translation>
<translation id="7682287625158474539">Dostava</translation>
+<translation id="7701040980221191251">Nema</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Idi na web-lokaciju <ph name="SITE" /> (nije sigurno)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certifikat</translation>
+<translation id="7716147886133743102">Blokirao administrator</translation>
<translation id="7716424297397655342">Web-lokacija se ne može uÄitati iz predmemorije</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Nema upravitelja</translation>
<translation id="7755287808199759310">Roditelj je može deblokirati</translation>
<translation id="7758069387465995638">Vezu možda blokira vatrozid ili antivirusni softver.</translation>
@@ -750,15 +824,15 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="7951415247503192394">(32-bitni)</translation>
<translation id="7956713633345437162">Mobilne oznake</translation>
<translation id="7961015016161918242">Nikad</translation>
-<translation id="7962083544045318153">ID rušenja <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Uvijek prevedi <ph name="ORIGINAL_LANGUAGE" /> na <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Nije navedeno</translation>
<translation id="800218591365569300">Pokušajte zatvoriti ostale kartice ili programe da biste oslobodili memoriju.</translation>
<translation id="8012647001091218357">Nismo uspjeli stupiti u kontakt s tvojim roditeljima. Pokušaj ponovo.</translation>
<translation id="8025119109950072390">NapadaÄi na ovoj web-lokaciji mogu vas na prijevaru pokuÅ¡ati navesti da napravite neÅ¡to opasno kao Å¡to je instaliranje softvera ili otkrivanje osobnih podataka (npr. zaporki, telefonskih brojeva ili kreditnih kartica).</translation>
-<translation id="803030522067524905">Google sigurno pregledavanje nedavno je otkrilo krađu identiteta na web-lokaciji <ph name="SITE" />. Web-lokacije za krađu identiteta lažno se predstavljaju kao druge web-lokacije kako bi vas prevarile. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Jezik ove stranice jest <ph name="SOURCE_LANGUAGE" />. Želite li je prevesti na <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Pitaj (zadano)</translation>
<translation id="8041089156583427627">Slanje povratnih informacija</translation>
+<translation id="8041940743680923270">Upotrijebi globalnu zadanu vrijednost (pitaj)</translation>
<translation id="8088680233425245692">Prikaz Älanka nije uspio.</translation>
<translation id="8089520772729574115">manje od 1 MB</translation>
<translation id="8091372947890762290">Aktivacija je na Äekanju na poslužitelju</translation>
@@ -767,13 +841,14 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />DNS adresa<ph name="END_ABBR" /> poslužitelja hosta <ph name="HOST_NAME" /> nije pronađena.</translation>
<translation id="8149426793427495338">RaÄunalo je u stanju mirovanja.</translation>
<translation id="8150722005171944719">Datoteka na adresi <ph name="URL" /> nije Äitljiva. Možda je uklonjena ili premjeÅ¡tena ili dozvole datoteka sprjeÄavaju pristup.</translation>
+<translation id="8184538546369750125">Upotrijebi globalnu zadanu vrijednost (dopusti)</translation>
+<translation id="8191494405820426728">Lokalni ID rušenja <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Poništi premještanje</translation>
<translation id="8201077131113104583">Nevažeći URL ažuriranja za proširenje s ID-om "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Sažetak narudžbe</translation>
<translation id="8218327578424803826">Dodijeljena lokacija:</translation>
<translation id="8225771182978767009">Osoba koja je postavila raÄunalo blokirala je tu web-lokaciju.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">NapadaÄi koji se trenutaÄno nalaze na <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu pokuÅ¡ati instalirati opasne programe na vaÅ¡e raÄunalo radi kraÄ‘e ili brisanja vaÅ¡ih podataka (na primjer, fotografija, zaporki, poruka i brojeva kreditnih kartica).</translation>
<translation id="8241707690549784388">Stranica koju ste tražili koristila je podatke koje ste unijeli. Vraćanje na tu stranicu može dovesti do ponavljanja poduzete radnje. Želite li nastaviti?</translation>
<translation id="8249320324621329438">Zadnje dohvaćanje:</translation>
<translation id="8253091569723639551">Potrebna je adresa za naplatu</translation>
@@ -781,6 +856,7 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="8289355894181816810">Obratite se svojem mrežnom administratoru ako niste sigurni Å¡to to znaÄi.</translation>
<translation id="8293206222192510085">Dodaj oznaku</translation>
<translation id="8294431847097064396">Izvor</translation>
+<translation id="8306404619377842860">Nije moguće uspostaviti privatnu vezu s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> jer datum i vrijeme ureÄ‘aja (<ph name="DATE_AND_TIME" />) nisu toÄni. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte viÅ¡e<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Prijevod nije uspio zbog problema s mrežnom vezom.</translation>
<translation id="8332188693563227489">Pristup hostu <ph name="HOST_NAME" /> je odbijen</translation>
<translation id="834457929814110454">Ako ste svjesni sigurnosnih rizika, možete <ph name="BEGIN_LINK" />posjetiti ovu web-lokaciju<ph name="END_LINK" /> prije uklanjanja štetnih programa.</translation>
@@ -801,11 +877,9 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="8483780878231876732">Da biste upotrebljavali kartice sa svojeg Google raÄuna, prijavite se na Chrome</translation>
<translation id="8488350697529856933">Primjenjuje se na</translation>
<translation id="8498891568109133222">Hostu <ph name="HOST_NAME" /> bilo je potrebno previše vremena za odgovor.</translation>
-<translation id="852346902619691059">Poslužitelj nije mogao dokazati da je to <ph name="DOMAIN" /> jer operativni sustav uređaja sigurnosni certifikat ne smatra pouzdanim. Razlog može biti pogrešna konfiguracija ili napad na vašu vezu. <ph name="BEGIN_LEARN_MORE_LINK" />Saznajte više<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Godina isteka</translation>
<translation id="8543181531796978784">Možete <ph name="BEGIN_ERROR_LINK" />prijaviti problem s otkrivanjem<ph name="END_ERROR_LINK" /> ili, ako razumijete na koje je naÄine ugrožena vaÅ¡a sigurnost, <ph name="BEGIN_LINK" />posjetite nesigurnu web-lokaciju<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Prijevod nije uspio jer nije bilo moguće odrediti jezik stranice.</translation>
-<translation id="8559762987265718583">Sigurnu vezu s domenom <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nije moguće uspostaviti jer datum i vrijeme (<ph name="DATE_AND_TIME" />) na vaÅ¡em ureÄ‘aju nisu toÄni.</translation>
<translation id="8571890674111243710">Prijevod stranice na <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Dodaj tel. broj
</translation>
@@ -820,6 +894,7 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="8738058698779197622">Za uspostavu sigurne veze sat mora biti toÄno postavljen. To je zato Å¡to certifikati koje web-lokacije upotrebljavaju za meÄ‘usobnu identifikaciju vrijede samo odreÄ‘eno vrijeme. Budući da sat na vaÅ¡em ureÄ‘aju nije toÄan, Chromium ne može potvrditi te certifikate.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;DNS adresa&lt;/abbr&gt; hosta <ph name="HOST_NAME" /> nije pronađena. U tijeku je dijagnosticiranje problema.</translation>
<translation id="8759274551635299824">Ta je kartica istekla</translation>
+<translation id="8761567432415473239">Googleovo Sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />pronašlo štetne programe<ph name="END_LINK" /> na web-lokaciji <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Ponovi brisanje</translation>
<translation id="8800988563907321413">Ovdje se prikazuju prijedlozi u blizini za vas</translation>
<translation id="8820817407110198400">Knjižne oznake</translation>
@@ -832,29 +907,30 @@ Psst! Sljedeći bi vam put mogao koristiti anonimni naÄin <ph name="SHORTCUT_KE
<translation id="8870413625673593573">Nedavno zatvoreno</translation>
<translation id="8874824191258364635">Unesite važeći broj kreditne kartice</translation>
<translation id="8876793034577346603">Mrežna konfiguracija nije uspješno analizirana.</translation>
-<translation id="8877192140621905067">Nakon što ih potvrdite, podaci o kartici dijelit će se s ovom web-lokacijom</translation>
<translation id="8889402386540077796">Ton</translation>
<translation id="8891727572606052622">Nevažeći naÄin proxy poslužitelja.</translation>
<translation id="889901481107108152">Nažalost, ovaj eksperiment nije dostupan na vašoj platformi.</translation>
<translation id="8903921497873541725">Povećaj</translation>
<translation id="8931333241327730545">Želite li spremiti tu karticu na Google raÄun?</translation>
<translation id="8932102934695377596">Sat kasni</translation>
-<translation id="8954894007019320973">(Nast.)</translation>
<translation id="8971063699422889582">Istekao je certifikat poslužitelja.</translation>
<translation id="8986494364107987395">Automatski šalji Googleu statistiku o upotrebi i izvješća o padu programa</translation>
-<translation id="8987927404178983737">Mjesec</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Sljedeća web-lokacija sadrži štetne programe</translation>
+<translation id="8997023839087525404">Poslužitelj je prikazao certifikat koji nije javno otkriven putem pravila Transparentnost certifikata. Taj se zahtjev postavlja za neke certifikate radi provjere njihove pouzdanosti i zaštite od napada.</translation>
<translation id="9001074447101275817">Proxy <ph name="DOMAIN" /> zahtijeva korisniÄko ime i zaporku.</translation>
+<translation id="9005998258318286617">UÄitavanje PDF dokumenta nije uspjelo.</translation>
<translation id="901974403500617787">Oznake koje se primjenjuju na razini sustava može postaviti samo vlasnik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Potrebna je adresa za naplatu kartice</translation>
<translation id="9020542370529661692">Ova je stranica prevedena na <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Sigurnosna pogreška</translation>
<translation id="9038649477754266430">Upotreba usluge predviÄ‘anja za brže uÄitavanje stranica</translation>
<translation id="9039213469156557790">Nadalje, ova stranica sadrži druge resurse koji nisu sigurni. Te resurse mogu vidjeti drugi tijekom prijenosa i napadaÄ ih može izmijeniti kako bi promijenio ponaÅ¡anje stranice.</translation>
-<translation id="9040185888511745258">NapadaÄi na web-lokaciji <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogu vas pokuÅ¡ati navesti na instaliranje programa koji smanjuju kvalitetu pregledavanja interneta (na primjer, promjenom poÄetne stranice ili prikazivanjem dodatnih oglasa na web-lokacijama koje posjetite).</translation>
+<translation id="9049981332609050619">Pokušali ste pristupiti domeni <ph name="DOMAIN" />, ali poslužitelj je prikazao nevažeći certifikat.</translation>
<translation id="9050666287014529139">Zaporka</translation>
<translation id="9065203028668620118">Uredi</translation>
<translation id="9068849894565669697">Odaberite boju</translation>
+<translation id="9069693763241529744">Blokiralo proširenje</translation>
<translation id="9076283476770535406">Možda ima sadržaj za odrasle</translation>
<translation id="9078964945751709336">Potrebno je više podataka</translation>
<translation id="9103872766612412690"><ph name="SITE" /> obiÄno upotrebljava enkripciju radi zaÅ¡tite vaÅ¡ih podataka. Prilikom ovog pokuÅ¡aja povezivanja Chromiuma s web-lokacijom <ph name="SITE" /> ta je web-lokacija vratila neuobiÄajene
@@ -864,16 +940,21 @@ i netoÄne vjerodajnice. To može znaÄiti da se neki napadaÄ pokuÅ¡ava predsta
<translation id="9148507642005240123">&amp;Poništi uređivanje</translation>
<translation id="9154194610265714752">Ažurirano</translation>
<translation id="9157595877708044936">Postavljanje...</translation>
+<translation id="9169664750068251925">Uvijek blokiraj na ovoj web-lokaciji</translation>
<translation id="9170848237812810038">&amp;Poništi</translation>
<translation id="917450738466192189">Certifikat poslužitelja nije valjan.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> i još <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419">Host <ph name="HOST_NAME" /> upotrebljava nepodržane protokole.</translation>
<translation id="9205078245616868884">Vaši su podaci šifrirani vašom šifrom za sinkronizaciju. Unesite je da biste pokrenuli sinkronizaciju.</translation>
<translation id="9207861905230894330">Dodavanje Älanka nije uspjelo.</translation>
+<translation id="9219103736887031265">Slike</translation>
<translation id="933612690413056017">Nema internetske veze</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">IZBRIÅ I OBRAZAC</translation>
<translation id="939736085109172342">Nova mapa</translation>
<translation id="941721044073577244">Izgleda da nemate dopuštenje za posjet toj web-lokaciji</translation>
<translation id="969892804517981540">Službeni sastavak</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Nijedna}=1{1 stavka}one{# stavka}few{# stavke}other{# stavki}}</translation>
<translation id="988159990683914416">Sastavak razvojnog programera</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_hu.xtb b/chromium/components/strings/components_strings_hu.xtb
index 338de1073b5..8a35caea656 100644
--- a/chromium/components/strings/components_strings_hu.xtb
+++ b/chromium/components/strings/components_strings_hu.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Forgatás jobbra</translation>
<translation id="1038842779957582377">Ismeretlen név</translation>
<translation id="1050038467049342496">Zárja be a többi alkalmazást</translation>
-<translation id="1053591932240354961">Pillanatnyilag nem tudja felkeresni a(z) <ph name="SITE" /> webhelyet, mivel a webhely olyan titkosított hitelesítési adatokat küldött, amelyeket a Google Chrome nem tud feldolgozni. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal később valószínűleg már működni fog. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Hozzáadás visszavonása</translation>
<translation id="10614374240317010">Az alábbi oldalakról soha ne mentsen jelszavakat</translation>
<translation id="106701514854093668">Asztali könyvjelzők</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Irányelv-gyorsítótár OK</translation>
<translation id="113188000913989374">A(z) <ph name="SITE" /> közlendője:</translation>
<translation id="1132774398110320017">A Chrome Automatikus kitöltési beállításai…</translation>
+<translation id="1150979032973867961">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa az Ön számítógépének operációs rendszere szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
+<translation id="1151972924205500581">Jelszó szükséges</translation>
<translation id="1152921474424827756">A(z) <ph name="URL" /> egy <ph name="BEGIN_LINK" />tárolt változatának<ph name="END_LINK" /> megtekintése</translation>
<translation id="1158211211994409885">A(z) <ph name="HOST_NAME" /> váratlanul megszakította a kapcsolatot.</translation>
<translation id="1161325031994447685">Újracsatlakozás Wi-Fi-hálózathoz</translation>
+<translation id="1165039591588034296">Hiba</translation>
<translation id="1175364870820465910">&amp;Nyomtatás...</translation>
<translation id="1181037720776840403">Eltávolítás</translation>
<translation id="1184214524891303587">A lehetséges biztonsági események adatainak <ph name="BEGIN_WHITEPAPER_LINK" />automatikus jelentése<ph name="END_WHITEPAPER_LINK" /> a Google-nak. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Továbbiak erről a webhelyről</translation>
<translation id="1206967143813997005">Hibás alapértelmezett aláírás</translation>
<translation id="1209206284964581585">Elrejtés most</translation>
+<translation id="121201262018556460">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver egy gyenge kulccsal rendelkező tanúsítványt adott. Egy támadó feltörhette a privát kulcsot, és lehet, hogy a szerver nem a várt kiszolgáló (lehet, hogy Ön egy támadóval kommunikál).</translation>
<translation id="1219129156119358924">Rendszerbiztonság</translation>
<translation id="1227224963052638717">Ismeretlen házirend</translation>
<translation id="1227633850867390598">Érték elrejtése</translation>
<translation id="1228893227497259893">Helytelen entitásazonosító</translation>
<translation id="1232569758102978740">Névtelen</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (szinkronizálva)</translation>
<translation id="1263231323834454256">Olvasási lista</translation>
<translation id="1264126396475825575">Hibajelentés készült: <ph name="CRASH_TIME" /> (még nincs feltöltve vagy mellőzték)</translation>
+<translation id="1281526147609854549">Kibocsátó: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Veszélyes tartalom letiltva</translation>
<translation id="1285320974508926690">Ezt a webhelyet soha ne fordítsa le</translation>
<translation id="129553762522093515">Mostanában bezárt</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Próbálkozzon a cookie-k törlésével<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Tevékenysége <ph name="BEGIN_EMPHASIS" />továbbra is látható maradhat<ph name="END_EMPHASIS" /> a következők számára:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />A megtekintett webhelyek
+ <ph name="LIST_ITEM" />Munkaadója vagy iskolája
+ <ph name="LIST_ITEM" />Internetszolgáltatója
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Regisztrációs domain:</translation>
<translation id="1340482604681802745">Ãtvételi cím</translation>
<translation id="1344211575059133124">Úgy tűnik, hogy a webhely felkereséséhez engedélyére van szükség</translation>
<translation id="1344588688991793829">A Chromium Automatikus kitöltési beállításai…</translation>
+<translation id="1348198688976932919">A felkeresni kívánt webhely veszélyes alkalmazásokat tartalmaz</translation>
<translation id="1374468813861204354">javaslatok</translation>
<translation id="1375198122581997741">A verzióról</translation>
<translation id="1377321085342047638">Kártyaszám</translation>
<translation id="139305205187523129">A(z) <ph name="HOST_NAME" /> nem küldött adatokat.</translation>
<translation id="1407135791313364759">Összes megnyitása</translation>
<translation id="1413809658975081374">Adatvédelmi hiba</translation>
+<translation id="14171126816530869"><ph name="ORGANIZATION" /> identitását <ph name="LOCALITY" /> régióban <ph name="ISSUER" /> ellenőrizte.</translation>
<translation id="1426410128494586442">Igen</translation>
<translation id="1430915738399379752">Nyomtatás</translation>
-<translation id="1442912890475371290">Letiltott kísérlet <ph name="BEGIN_LINK" /> egy oldal felkeresésére a következő domainen: <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Pillanatnyilag nem tudja felkeresni a(z) <ph name="SITE" /> webhelyet, mivel a webhely tanúsítványrögzítést használ. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal később valószínűleg már működni fog. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Az oldal mentett (pl. köztudottan régi) változatának megjelenítése.</translation>
<translation id="1517433312004943670">Telefonszám szükséges</translation>
<translation id="1519264250979466059">Build dátuma</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">A funkció használatához engedélyezni kell a JavaScriptet.</translation>
<translation id="1555130319947370107">Kék</translation>
<translation id="1559528461873125649">Nincs ilyen fájl vagy könyvtár</translation>
-<translation id="1559572115229829303">&lt;p&gt;Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert az eszköz dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
-
- &lt;p&gt;Módosítsa a dátumot és az idÅ‘t a &lt;strong&gt;Beállítások&lt;/strong&gt; alkalmazás &lt;strong&gt;Ãltalános&lt;/strong&gt; részében.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Valami nem sikerült a weboldal megjelenítése során.</translation>
<translation id="1592005682883173041">Helyi adatok elérése</translation>
+<translation id="1594030484168838125">Kiválaszt</translation>
<translation id="161042844686301425">Cián</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Szeretné, hogy a Chrome mentse ezt a kártyát?</translation>
<translation id="1639239467298939599">Betöltés</translation>
<translation id="1640180200866533862">Felhasználói házirendek</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">A hálózati konfiguráció érvénytelen és nem importálható.</translation>
<translation id="1644574205037202324">Előzmények</translation>
<translation id="1645368109819982629">Nem támogatott protokoll</translation>
+<translation id="1655462015569774233">{1,plural, =1{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa tegnap lejárt. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy egy támadó eltérítette az Ön kapcsolódását. Számítógépének órája jelenleg a következőre van állítva: <ph name="CURRENT_DATE" />. Ez megfelelőnek tűnik? Ha nem, állítsa be megfelelően a rendszer óráját, majd frissítse az oldalt.}other{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa # nappal ezelőtt lejárt. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy egy támadó eltérítette az Ön kapcsolódását. Számítógépének órája jelenleg a következőre van állítva: <ph name="CURRENT_DATE" />. Ez megfelelőnek tűnik? Ha nem, állítsa be megfelelően a rendszer óráját, majd frissítse az oldalt.}}</translation>
<translation id="1656489000284462475">Ãtvétel</translation>
<translation id="1663943134801823270">A kártyák és a címek a Chrome-ból származnak. A <ph name="BEGIN_LINK" />Beállításokban<ph name="END_LINK" /> kezelheti őket.</translation>
<translation id="1676269943528358898">A(z) <ph name="SITE" /> webhely rendes esetben titkosítást alkalmaz az Ön adatainak védelme érdekében. Amikor a Google Chrome most csatlakozni próbált, a(z) <ph name="SITE" /> webhely szokatlan és helytelen hitelesítési adatokat küldött vissza. Ez olyankor fordulhat elő, amikor egy támadó megpróbálja magát kiadni a(z) <ph name="SITE" /> webhelynek, vagy valamilyen Wi-Fi-bejelentkezési képernyő megszakította a kapcsolatot. Adatai továbbra is biztonságban vannak, mivel a Google Chrome még azt megelőzően megszakította a kapcsolatot, hogy bármiféle adatcserére sor kerülhetett volna.</translation>
-<translation id="168328519870909584">Előfordulhat, hogy a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhely támadói veszélyes alkalmazásokat kísérelnek meg telepíteni eszközére, amelyek ellopják vagy törlik adatait (például fotóit, jelszavait, üzeneteit és hitelkártyaadatait).</translation>
<translation id="168841957122794586">A szervertanúsítvány gyenge titkosítási kulcsot tartalmaz.</translation>
+<translation id="1706954506755087368">{1,plural, =1{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa elméletileg holnaptól érvényes. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy egy támadó eltérítette az Ön kapcsolódását.}other{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa elméletileg # nap múlva lép érvénybe. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy egy támadó eltérítette az Ön kapcsolódását.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">A webhely felkereséséhez <ph name="NAME" /> engedélyére van szükség</translation>
<translation id="1721424275792716183">* A mező kitöltése kötelező</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Az oldal letöltése később</translation>
<translation id="17513872634828108">Megnyitott lapok</translation>
<translation id="1753706481035618306">Oldalszám</translation>
+<translation id="1763864636252898013">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa az Ön eszközének operációs rendszere szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Próbálkozzon a Windows Hálózati diagnosztika futtatásával<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Kérjük, frissítse szinkronizálási összetett jelszavát.</translation>
<translation id="1787142507584202372">A megnyitott lapok helye</translation>
+<translation id="1789575671122666129">Előugró ablakok</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Kártyatulajdonos neve</translation>
-<translation id="1803678881841855883">A Google Biztonságos Böngészés funkciója nemrég <ph name="BEGIN_LINK" />rosszindulatú programot észlelt<ph name="END_LINK" /> a(z) <ph name="SITE" /> webhelyen. A normál esetben biztonságos webhelyek néha rosszindulatú programokkal fertőzöttek. A rosszindulatú tartalom az ilyen programok következő ismert terjesztőjétől származik: <ph name="SUBRESOURCE_HOST" />. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Hozzáadva: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Érvénytelen kérés vagy kérésparaméter</translation>
<translation id="1826516787628120939">Ellenőrzés</translation>
<translation id="1834321415901700177">A webhely ártalmas programokat tartalmaz</translation>
+<translation id="1840414022444569775">A kártyaszám már használatban van</translation>
<translation id="1842969606798536927">Fizetés</translation>
<translation id="1871208020102129563">A proxy fix proxyszerverek használatára van beállítva, nem pedig .pac típusú szkript URL címének használatára.</translation>
<translation id="1871284979644508959">Kötelező mező</translation>
<translation id="187918866476621466">Kezdőoldalak megnyitása</translation>
<translation id="1883255238294161206">Lista bezárása</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Szűrés</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Nincs}=1{1 webhely}other{# webhely}}</translation>
<translation id="194030505837763158">Ugrás ide: <ph name="LINK" /></translation>
<translation id="1962204205936693436">A(z) <ph name="DOMAIN" /> könyvjelzői</translation>
<translation id="1973335181906896915">Szerializálási hiba</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">A rendszer figyelmen kívül hagyja, mivel a(z) <ph name="POLICY_NAME" /> felülírta.</translation>
<translation id="2138201775715568214">A Fizikai web közeli oldalainak keresése</translation>
<translation id="213826338245044447">Mobil könyvjelzők</translation>
-<translation id="2148716181193084225">Ma</translation>
+<translation id="2147827593068025794">Szinkronizálás a háttérben</translation>
<translation id="2154054054215849342">A szinkronizálás az Ön domainjén nem áll rendelkezésre</translation>
<translation id="2154484045852737596">Kártya szerkesztése</translation>
<translation id="2166049586286450108">Teljes rendszergazdai hozzáférés</translation>
<translation id="2166378884831602661">A webhely nem képes biztonságos kapcsolatot nyújtani</translation>
<translation id="2181821976797666341">Házirendek</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 cím}other{# cím}}</translation>
+<translation id="2187317261103489799">Észlelés (alapértelmezett)</translation>
<translation id="2202020181578195191">Érvényes lejárati évet kell megadnia</translation>
<translation id="2212735316055980242">Nem találhatók irányelvek</translation>
<translation id="2213606439339815911">Bejegyzések lekérése...</translation>
+<translation id="2218879909401188352">A(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhelyen lévő támadók veszélyes alkalmazásokat telepíthetnek, amelyek károsíthatják eszközét, rejtett költségeket okozhatnak a mobiltelefon-számlán, vagy ellophatják személyes adatait. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2230458221926704099">Javítsa meg kapcsolatát a <ph name="BEGIN_LINK" />diagnosztikai alkalmazás<ph name="END_LINK" /> segítségével</translation>
<translation id="2239100178324503013">Küldés most</translation>
<translation id="225207911366869382">Ez az érték elavult ennél a házirendnél.</translation>
<translation id="2262243747453050782">HTTP hiba</translation>
+<translation id="2270484714375784793">Telefonszám</translation>
<translation id="2282872951544483773">Nem elérhető kísérletek</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> elem}other{<ph name="ITEM_COUNT" /> elem}}</translation>
<translation id="2292556288342944218">Az internethez való hozzáférést a rendszer letiltotta</translation>
<translation id="230155334948463882">Új kártya?</translation>
-<translation id="2305919008529760154">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványát csalással állíthatták ki. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">A(z) <ph name="DOMAIN" /> felhasználónevet és jelszót kér.</translation>
-<translation id="2318774815570432836">A(z) <ph name="SITE" /> webhelyet pillanatnyilag nem tudja felkeresni, mert a webhely HSTS-t használ. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal később valószínűleg már működni fog. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">A beállítást a rendszergazda szabályozza</translation>
<translation id="2354001756790975382">További könyvjelzők</translation>
+<translation id="2354430244986887761">A Google Biztonságos Böngészés funkciója nemrég <ph name="BEGIN_LINK" />kártékony alkalmazásokat talált<ph name="END_LINK" /> a(z) <ph name="SITE" /> webhelyen.</translation>
<translation id="2355395290879513365">A felhasználók esetleg láthatják a webhelyen éppen megtekintett képeit, és a képeket módosítva félrevezethetik Önt.</translation>
+<translation id="2356070529366658676">Kérés</translation>
+<translation id="2359629602545592467">Több</translation>
<translation id="2359808026110333948">Folytatás</translation>
<translation id="2365563543831475020">A(z) <ph name="CRASH_TIME" /> időpontban készült hibajelentés nincs feltöltve</translation>
<translation id="2367567093518048410">Szint</translation>
-<translation id="2371153335857947666">{1,plural, =1{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa tegnap lejárt. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy támadó térítette el az Ön kapcsolódását. Számítógépének órája jelenleg a következőre van állítva: <ph name="CURRENT_DATE" />. Ez megfelelőnek tűnik? Ha nem, állítsa be megfelelően a rendszer óráját, majd frissítse az oldalt. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.}other{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa # nappal ezelőtt lejárt. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy támadó térítette el az Ön kapcsolódását. Számítógépének órája jelenleg a következőre van állítva: <ph name="CURRENT_DATE" />. Ez megfelelőnek tűnik? Ha nem, állítsa be megfelelően a rendszer óráját, majd frissítse az oldalt. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nincsenek alternatív kezelőfelületek</translation>
<translation id="2384307209577226199">Vállalati alapértelmezett</translation>
<translation id="2386255080630008482">A szerver tanúsítványát visszavonták.</translation>
<translation id="2392959068659972793">Beállított értékkel nem rendelkező házirendek megjelenítése</translation>
<translation id="239429038616798445">Ez a szállítási mód nem áll rendelkezésre. Próbálkozzon másik móddal.</translation>
<translation id="2396249848217231973">&amp;Törlés visszavonása</translation>
-<translation id="2460160116472764928">A Google Biztonságos Böngészés funkciója nemrég <ph name="BEGIN_LINK" />rosszindulatú programot észlelt<ph name="END_LINK" /> a(z) <ph name="SITE" /> webhelyen. A rendes esetben biztonságos webhelyek néha rosszindulatú programokkal fertőzöttek. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványát visszavonhatták. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
<translation id="2463739503403862330">Kitöltés</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Hálózati diagnosztika futtatása<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Érvénytelen keresési URL</translation>
+<translation id="2482878487686419369">Értesítések</translation>
<translation id="2491120439723279231">A szervezet tanúsítványa hibákat tartalmaz.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2495093607237746763">Ha be van jelölve, a Chromium megőrzi a kártya másolatát ezen az eszközön a gyorsabb űrlapkitöltés érdekében.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Visszalépés</translation>
<translation id="2515629240566999685">A térerő ellenőrzése tartózkodási helyén</translation>
<translation id="2516305470678292029">Alternatív kezelőfelületek</translation>
+<translation id="2539524384386349900">Felismerés</translation>
<translation id="255002559098805027">A(z) <ph name="HOST_NAME" /> érvénytelen választ küldött.</translation>
-<translation id="2552545117464357659">Újabb</translation>
<translation id="2556876185419854533">&amp;Szerkesztés visszavonása</translation>
<translation id="2587730715158995865">Forrás: <ph name="ARTICLE_PUBLISHER" />. Olvassa el ezt és további <ph name="OTHER_ARTICLE_COUNT" /> hírt.</translation>
<translation id="2587841377698384444">Könyvtár API-azonosítója:</translation>
<translation id="2597378329261239068">Ez a dokumentum jelszóval védett. Kérjük, adja meg a jelszót.</translation>
<translation id="2609632851001447353">Változatok</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Nincs}=1{1 alkalmazás ($1)}=2{2 alkalmazás ($1, $2)}other{# alkalmazás ($1, $2 $3)}}</translation>
<translation id="2625385379895617796">Az órája siet</translation>
<translation id="2639739919103226564">Ãllapot:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">A hozzáférés a fájlhoz megtagadva.</translation>
<translation id="2653659639078652383">Elküldés</translation>
<translation id="2666117266261740852">Zárja be a többi lapot vagy alkalmazást</translation>
+<translation id="2670429602441959756">Ez az oldal olyan funkciókat tartalmaz, amelyeket a virtuális valóság még nem támogat. Kilépés a virtuális valóság módból…</translation>
<translation id="2674170444375937751">Biztosan törölni szeretné ezeket az oldalakat az előzmények közül?</translation>
<translation id="2677748264148917807">Lap elhagyása</translation>
-<translation id="269990154133806163">A szerver olyan tanúsítványt mutatott be, amelyet nem A tanúsítványok átláthatósága keretrendszer segítségével hoztak nyilvánosságra. Ez egyes tanúsítványoknál követelmény annak biztosítása érdekében, hogy az adott tanúsítványok megbízhatók, és védelmet nyújtanak a támadók ellen. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Olvasási lista</translation>
<translation id="2704283930420550640">Az érték nem egyezik a formátummal.</translation>
<translation id="2704951214193499422">A Chromium ez alkalommal nem tudta ellenőrizni az Ön kártyáját. Próbálja újra később.</translation>
<translation id="2705137772291741111">A webhely mentett (gyorsítótárazott) példánya nem olvasható.</translation>
<translation id="2709516037105925701">Automatikus kitöltés</translation>
-<translation id="2712118517637785082">A(z) <ph name="DOMAIN" /> webhelyet próbálta megnyitni, de a kiállító visszavonta a szerver által bemutatott tanúsítványt. Ez azt jelenti, hogy a szerver biztonsági tanúsítványában egyáltalán nem lehet megbízni. Lehet, hogy támadóval áll kapcsolatban. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Engedély kérése</translation>
<translation id="2713444072780614174">Fehér</translation>
<translation id="2720342946869265578">A közelben</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Hiányzó eszközrekord</translation>
<translation id="2784949926578158345">A kapcsolat alaphelyzetbe állt.</translation>
<translation id="2794233252405721443">A webhely le van tiltva</translation>
+<translation id="2799020568854403057">A felkeresni kívánt webhely káros alkalmazásokat tartalmaz</translation>
+<translation id="2803306138276472711">A Google – Biztonságos böngészés nemrég <ph name="BEGIN_LINK" />rosszindulatú programot<ph name="END_LINK" /> észlelt a(z) <ph name="SITE" /> webhelyen. A rendes esetben biztonságos webhelyek néha rosszindulatú programokkal fertőzöttek.</translation>
<translation id="2824775600643448204">Cím- és keresősáv</translation>
<translation id="2826760142808435982">A kapcsolat <ph name="KX" /> algoritmust használ kulcscserélő mechanizmusként, kódolása pedig <ph name="CIPHER" /> használatával történt.</translation>
<translation id="2835170189407361413">Űrlap törlése</translation>
+<translation id="2856444702002559011">A támadók megpróbálhatják ellopni a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhelyen lévő adatait (például jelszavait, üzeneteit és hitelkártyaadatait). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2889159643044928134">Ne töltse újra</translation>
<translation id="2900469785430194048">Elfogyott a memória, miközben a Google Chrome megpróbálta megjeleníteni ezt a weboldalt.</translation>
<translation id="2909946352844186028">Változást érzékeltünk a hálózatban.</translation>
<translation id="2916038427272391327">Zárja be a többi programot</translation>
<translation id="2922350208395188000">A szerver tanúsítványát nem sikerült leellenőrizni.</translation>
<translation id="2928905813689894207">Számlázási cím</translation>
+<translation id="2941952326391522266">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a következőről származik: <ph name="DOMAIN2" />. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
<translation id="2948083400971632585">Bármelyik kapcsolatlétesítésre használt proxyt letilthatja a beállítások oldalon.</translation>
<translation id="2955913368246107853">Keresősáv bezárása</translation>
<translation id="2958431318199492670">A hálózati konfiguráció nem felel meg az ONC szabványnak. A konfiguráció egyes részeit nem lehet importálni.</translation>
-<translation id="29611076221683977">Előfordulhat, hogy a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhely támadói veszélyes programokat kísérelnek meg telepíteni Mac számítógépére, amelyek ellopják vagy törlik adatait (például fotóit, jelszavait, üzeneteit és hitelkártyaadatait).</translation>
<translation id="2966678944701946121">Lejárati dátum: <ph name="EXPIRATION_DATE_ABBR" />, hozzáadva: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Biztonságos kapcsolat létrehozásához az órát pontosan be kell állítani. Ez azért szükséges, mert a webhelyek által az azonosításukra használt tanúsítványok csak adott ideig érvényesek. Mivel az eszköz órája nem pontos, a Google Chrome nem tudja ellenőrizni ezeket a tanúsítványokat.</translation>
<translation id="2972581237482394796">&amp;Újra</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Érvényes címet adjon meg</translation>
<translation id="2986368408720340940">Ez az átvételi mód nem áll rendelkezésre. Próbálkozzon másik móddal.</translation>
<translation id="2991174974383378012">Megosztás webhelyekkel</translation>
+<translation id="2991571918955627853">A(z) <ph name="SITE" /> webhelyet pillanatnyilag nem tudja felkeresni, mert a webhely HSTS-t használ. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal működése később valószínűleg helyreáll.</translation>
<translation id="3005723025932146533">Mentett másolat megjelenítése</translation>
<translation id="3008447029300691911">Adja meg a(z) <ph name="CREDIT_CARD" /> kártya CVC-kódját. Az ellenőrzést követően a böngésző megosztja kártyaadatait ezzel a webhellyel.</translation>
<translation id="3010559122411665027">"<ph name="ENTRY_INDEX" />." listabejegyzés: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatikusan letiltva</translation>
<translation id="3024663005179499861">Nem megfelelő irányelvtípus</translation>
<translation id="3032412215588512954">Szeretné újratölteni a webhelyet?</translation>
<translation id="3037605927509011580">A manóba!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{legalább 1 elem van a szinkronizált eszközökön}=1{1 elem (és még több a szinkronizált eszközökön)}other{# elem (és még több a szinkronizált eszközökön)}}</translation>
<translation id="3041612393474885105">Tanúsítvány adatai</translation>
<translation id="3063697135517575841">A Chrome ez alkalommal nem tudta ellenőrizni az Ön kártyáját. Próbálja újra később.</translation>
<translation id="3064966200440839136">Inkognitómód elhagyása külső alkalmazással történő fizetéshez. Folytatja?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Nincs}=1{1 jelszó}other{# jelszó}}</translation>
<translation id="3093245981617870298">Ön jelenleg offline.</translation>
<translation id="3105172416063519923">Tartalomazonosító:</translation>
<translation id="3109728660330352905">Nincs jogosultsága az oldal megjelenítésére.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Próbálkozzon a kapcsolódási diagnosztika futtatásával<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Nem sikerült dekódolni a választ</translation>
<translation id="3150653042067488994">Ãtmeneti szerverhiba</translation>
@@ -247,14 +277,18 @@
<translation id="3167968892399408617">Az inkognitólapon megtekintett oldalak az összes inkognitólap bezárását követően nem szerepelnek majd böngészési előzményei között, a cookie-k gyűjtőhelyén, illetve a keresési előzményekben. A letöltött fájlok és a könyvjelzők azonban megmaradnak.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Sziget</translation>
+<translation id="317583078218509884">Az új webhelyengedélyek az oldal ismételt betöltése után lépnek életbe.</translation>
<translation id="3176929007561373547">Ellenőrizze a proxybeállításokat, vagy kérdezze meg a rendszergazdájától, hogy a proxyszerver működik-e. Ha úgy gondolja, hogy nem használ proxyszervert:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Nyissa meg az oldalt inkognitómódban</translation>
-<translation id="3202578601642193415">Legújabb</translation>
+<translation id="320323717674993345">Fizetés visszavonása</translation>
<translation id="3207960819495026254">Könyvjelzőzött</translation>
+<translation id="3225919329040284222">A szerver tanúsítványa nem felel meg a beépített elvárásoknak. Ezek a beépített elvárások bizonyos nagy biztonságú webhelyekre vonatkoznak az Ön védelme érdekében.</translation>
<translation id="3226128629678568754">Nyomja meg a frissítés gombot az oldal betöltéséhez szükséges adatok újraküldéséhez.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">A fordítás nem sikerült, mert az oldal már ezen a nyelven van: <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Adja meg a(z) <ph name="CREDIT_CARD" /> kártya CVC-kódját</translation>
+<translation id="3234666976984236645">Mindig észlelje a fontos tartalmat ezen a webhelyen</translation>
<translation id="3254409185687681395">Könyvjelző hozzáadása ehhez az oldalhoz</translation>
<translation id="3270847123878663523">&amp;Ãtrendezés visszavonása</translation>
<translation id="3282497668470633863">Adja meg a kártyán szereplő nevet</translation>
@@ -268,42 +302,48 @@
<translation id="3340978935015468852">beállítások</translation>
<translation id="3345135638360864351">A webhelyhez való hozzáférésre irányuló kérelme nem jutott el <ph name="NAME" /> felhasználóhoz. Kérjük, próbálkozzon újra.</translation>
<translation id="3355823806454867987">Proxybeállítások módosítása...</translation>
+<translation id="3361596688432910856">A Chrome <ph name="BEGIN_EMPHASIS" />nem menti<ph name="END_EMPHASIS" /> a következő adatokat:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Böngészési előzmények
+ <ph name="LIST_ITEM" />Cookie-k és webhelyadatok
+ <ph name="LIST_ITEM" />Å°rlapokon megadott adatok
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Órahiba</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> további elem…</translation>
<translation id="337363190475750230">Deaktiválva</translation>
<translation id="3377188786107721145">Irányelv-előfeldolgozási hiba</translation>
<translation id="3380365263193509176">Ismeretlen hiba</translation>
<translation id="3380864720620200369">Ügyfél-azonosító:</translation>
<translation id="3391030046425686457">Szállítási cím</translation>
<translation id="3395827396354264108">Ãtvételi mód</translation>
-<translation id="340013220407300675">A támadók megpróbálhatják ellopni adatait (például jelszavakat, üzeneteket vagy hitelkártyaszámokat) innen: <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />.</translation>
<translation id="3422248202833853650">Próbáljon meg bezárni más programokat memória felszabadítása céljából.</translation>
<translation id="3422472998109090673">A(z) <ph name="HOST_NAME" /> jelenleg nem érhető el.</translation>
+<translation id="3427092606871434483">Engedélyezés (alapértelmezett)</translation>
<translation id="3427342743765426898">&amp;Szerkesztés újra</translation>
<translation id="3431636764301398940">Kártya mentése az eszközre</translation>
<translation id="3435896845095436175">Engedélyezés</translation>
<translation id="3447661539832366887">Az eszköz tulajdonosa kikapcsolta a dinoszauruszos játékot.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Lekérési intervallum:</translation>
<translation id="3462200631372590220">Speciális beállítások elrejtése</translation>
<translation id="3467763166455606212">A kártyatulajdonos nevének megadása kötelező</translation>
<translation id="3478058380795961209">Lejárat hónapja</translation>
<translation id="3479539252931486093">Ez váratlanul érte Önt? <ph name="BEGIN_LINK" />Tudassa velünk.<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ne most</translation>
-<translation id="348000606199325318">Hibaazonosító: <ph name="CRASH_LOCAL_ID" /> (szerverazonosító: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Jelenleg nem tudjuk elérni szüleidet. Próbálkozz újra.</translation>
<translation id="3528171143076753409">A szervezet tanúsítványa nem megbízható.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Legalább 1 elem van a szinkronizált eszközökön}=1{1 elem (és még több a szinkronizált eszközökön)}other{# elem (és még több a szinkronizált eszközökön)}}</translation>
<translation id="3539171420378717834">A kártya másolatának megőrzése az eszközön</translation>
<translation id="3542684924769048008">Jelszó használata a következőre:</translation>
+<translation id="3545341443414427877">Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert a számítógép dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3549644494707163724">Az összes szinkronizált adat titkosítása saját összetett szinkronizálási jelszóval</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> további...</translation>
-<translation id="3555561725129903880">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a(z) <ph name="DOMAIN2" /> domainről származik. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">A letiltást a kezelő oldhatja fel</translation>
<translation id="3566021033012934673">Az Ön kapcsolata nem privát</translation>
+<translation id="3569145463236695319">&lt;p&gt;Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert az eszköz dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
+
+ &lt;p&gt;Módosítsa a dátumot és az idÅ‘t a &lt;strong&gt;Beállítások&lt;/strong&gt; alkalmazás &lt;strong&gt;Ãltalános&lt;/strong&gt; részében.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Név hozzáadása</translation>
<translation id="3583757800736429874">&amp;Ãthelyezés újra</translation>
<translation id="3586931643579894722">Részletek elrejtése</translation>
-<translation id="3587482841069643663">Mind</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Érvényes lejárati dátumot kell megadnia</translation>
<translation id="36224234498066874">Böngészési adatok törlése...</translation>
@@ -320,7 +360,6 @@
<translation id="3681007416295224113">Tanúsítvány adatai</translation>
<translation id="3690164694835360974">A bejelentkezés nem biztonságos</translation>
<translation id="3693415264595406141">Jelszó:</translation>
-<translation id="3696411085566228381">nincs</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Betöltés...</translation>
<translation id="3712624925041724820">Az engedélyek elfogytak</translation>
@@ -328,12 +367,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />A proxy, a tűzfal és a DNS-konfiguráció ellenőrzése<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Ha tisztában van a biztonságát fenyegető kockázatokkal, a veszélyes programok eltávolítása előtt is <ph name="BEGIN_LINK" />felkeresheti a nem biztonságos webhelyet<ph name="END_LINK" />.</translation>
<translation id="3739623965217189342">Ãtmásolt link</translation>
+<translation id="3744899669254331632">Most nem keresheti fel a(z) <ph name="SITE" /> webhelyet, mert az zavaros, a Chromium által nem feldolgozható hitelesítő adatokat küldött. A hálózati hibák és támadások általában ideiglenesek, úgyhogy az oldal később valószínűleg megfelelően fog működni.</translation>
+<translation id="3748148204939282805">A(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhely támadói megpróbálhatják csellel rávenni Önt például arra, hogy veszélyes szoftvert telepítsen, vagy felfedje személyes adatait (jelszavakat, telefonszámokat, hitelkártyaadatokat stb). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="375403751935624634">A fordítás a szerver hibája miatt nem sikerült.</translation>
<translation id="3759461132968374835">Nincs a közelmúltban bejelentett rendszerösszeomlás. A kikapcsolt jelentésküldés során történt összeomlások nem jelennek meg itt.</translation>
+<translation id="3778403066972421603">Szeretné menteni a kártyát Google-fiókjába és az eszközre?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Lejárat dátuma: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Ha proxyszervert használ...</translation>
<translation id="3828924085048779000">Az üres összetett jelszó nem engedélyezett.</translation>
-<translation id="3845539888601087042">Előzmények megjelenítése bejelentkezett eszközeiről. <ph name="BEGIN_LINK" />További információ<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Vissza</translation>
<translation id="3858027520442213535">Dátum és idő frissítése</translation>
<translation id="3884278016824448484">Eszközazonosító-ütközés</translation>
@@ -341,11 +383,13 @@
<translation id="3886446263141354045">Webhely-hozzáférési kérelme elküldve a következő személynek: <ph name="NAME" /></translation>
<translation id="3890664840433101773">E-mail-cím hozzáadása</translation>
<translation id="3901925938762663762">A kártya lejárt</translation>
-<translation id="3933571093587347751">{1,plural, =1{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa állítólag holnaptól érvényes. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.}other{A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa elméletileg # nap múlva lép érvénybe. Ennek oka lehet konfigurációs hiba, de az is lehet, hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF dokumentum betöltése sikertelen</translation>
+<translation id="3945915738023014686">Feltöltött hibajelentés azonosítója: <ph name="CRASH_ID" /> (helyi hibaazonosító: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványában nincs meghatározva a „Subject Alternative Names†mező. Ezt okozhatja konfigurációs hiba, vagy az, hogy egy támadó eltérítette az Ön kapcsolatát.</translation>
<translation id="3963721102035795474">Olvasási mód</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Nincs}=1{ 1 webhelytől }other{# webhelytől }}</translation>
<translation id="397105322502079400">Számítás…</translation>
<translation id="3973234410852337861">A(z) <ph name="HOST_NAME" /> le van tiltva</translation>
+<translation id="3987940399970879459">Kevesebb mint 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 közeli weboldal}other{# közeli weboldal}}</translation>
<translation id="4021036232240155012">A DNS az a hálózati szolgáltatás, amely a webhelynevet az adott webhely internetes címére fordítja le.</translation>
<translation id="4030383055268325496">&amp;Hozzáadás visszavonása</translation>
@@ -356,56 +400,63 @@
<translation id="4079302484614802869">A proxykonfiguráció a .pac típusú szkript URL-cím, nem pedig a fix proxyszerverek használatára van beállítva.</translation>
<translation id="4098354747657067197">Megtévesztő webhely megnyitására készül</translation>
<translation id="4103249731201008433">Az eszköz sorozatszáma érvénytelen</translation>
+<translation id="410351446219883937">Automatikus lejátszás</translation>
<translation id="4103763322291513355">Látogasson el a &lt;strong&gt;chrome://policy&lt;/strong&gt; oldalra a feketelistán lévő URL-ek és egyéb, a rendszergazda által előírt szabályok megtekintéséhez.</translation>
-<translation id="4110615724604346410">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa hibákat tartalmaz. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Mindig engedélyezze ezen az oldalon</translation>
<translation id="4117700440116928470">Az irányelv hatásköre nem támogatott.</translation>
-<translation id="4118212371799607889">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a Chromium szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 egyéb}other{# egyéb}}</translation>
<translation id="4130226655945681476">A hálózati kábelek, a modem és a router ellenőrzése</translation>
+<translation id="413544239732274901">További információ</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Globális alapértelmezés használata (Észlelés)</translation>
+<translation id="4165986682804962316">Webhelybeállítások</translation>
<translation id="4169947484918424451">Szeretné, hogy a Chromium mentse ezt a kártyát?</translation>
<translation id="4171400957073367226">Hibás igazoló aláírás.</translation>
<translation id="4196861286325780578">&amp;Ãthelyezés újra</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />A tűzfal és a vírusirtó konfigurációjának ellenőrzése<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{nincsen}=1{1 alkalmazás ($1)}=2{2 alkalmazás ($1, $2)}other{# alkalmazás ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Összeomlások</translation>
+<translation id="422022731706691852">A(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhelyen lévő támadók megpróbálhatják rávenni Önt olyan programok telepítésére, amelyek károsak a böngészési élmény szempontjából (például módosítják a kezdőlapot vagy plusz hirdetéseket jelenítenek meg a felkeresett webhelyeken). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Próbálkozzon a Hálózati diagnosztika futtatásával<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Érvényes</translation>
<translation id="4250431568374086873">Kapcsolata a webhellyel nem teljesen biztonságos</translation>
<translation id="4250680216510889253">Nem</translation>
<translation id="425582637250725228">Előfordulhat, hogy módosításait nem menti a rendszer.</translation>
<translation id="4258748452823770588">Rossz aláírás</translation>
+<translation id="4265872034478892965">A rendszergazda engedélyezte</translation>
<translation id="4269787794583293679">(Nincs felhasználónév)</translation>
<translation id="4275830172053184480">Indítsa újra az eszközt</translation>
<translation id="4280429058323657511">, lejár: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">A Google Biztonságos Böngészés funkciója nemrég <ph name="BEGIN_LINK" />ártalmas programokat talált<ph name="END_LINK" /> a(z) <ph name="SITE" /> webhelyen. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Szülői javaslatok</translation>
<translation id="4304224509867189079">Bejelentkezés</translation>
-<translation id="432290197980158659">A szerver tanúsítványa nem felel meg a beépített elvárásoknak. Ezek a beépített elvárások bizonyos nagy biztonságú webhelyekre vonatkozóan találhatók meg az Ön védelmének érdekében. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Letiltás (alapértelmezett)</translation>
<translation id="4325863107915753736">Nem sikerült megtalálni a cikket</translation>
<translation id="4326324639298822553">Ellenőrizze a lejárati dátumot, majd próbálja újra</translation>
<translation id="4331708818696583467">Nem biztonságos</translation>
<translation id="4356973930735388585">Előfordulhat, hogy a webhely támadói olyan veszélyes programokat próbálnak telepíteni számítógépére, amelyek ellopják vagy törlik adatait (például fotóit, jelszavait, üzeneteit vagy hitelkártyaadatait).</translation>
<translation id="4372948949327679948">Várt <ph name="VALUE_TYPE" /> érték.</translation>
+<translation id="4377125064752653719">A(z) <ph name="DOMAIN" /> webhelyet próbálta megnyitni, de a kiállító visszavonta a szerver által bemutatott tanúsítványt. Ez azt jelenti, hogy a szerver biztonsági igazolásaiban egyáltalán nem lehet megbízni. Lehet, hogy egy támadóval áll kapcsolatban.</translation>
<translation id="4381091992796011497">Felhasználónév:</translation>
<translation id="4394049700291259645">Kikapcsolás</translation>
<translation id="4406896451731180161">keresési találat</translation>
+<translation id="4424024547088906515">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a Chrome szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
<translation id="4432688616882109544">A(z) <ph name="HOST_NAME" /> nem fogadta el az Ön bejelentkezési tanúsítványát, vagy nem talált ilyet.</translation>
<translation id="443673843213245140">A proxy használata le van tiltva, de kifejezett proxykonfiguráció van megadva.</translation>
-<translation id="4492190037599258964">Találatok a(z) „<ph name="SEARCH_STRING" />†kifejezésre</translation>
<translation id="4506176782989081258">Érvényesítési hiba: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Kapcsolatfelvétel a rendszergazdával</translation>
<translation id="450710068430902550">Megosztás a rendszergazdával</translation>
<translation id="4515275063822566619">A kártyák és a címek a Chrome-ból és az Ön Google-fiókjából (<ph name="ACCOUNT_EMAIL" />) származnak. A <ph name="BEGIN_LINK" />Beállításokban<ph name="END_LINK" /> kezelheti őket.</translation>
<translation id="4522570452068850558">Részletek</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Próbálkozzon a bővítmények letiltásával.</translation>
<translation id="457875822857220463">Szállítás</translation>
<translation id="4587425331216688090">Eltávolítja a címet a Chrome-ból?</translation>
-<translation id="4589078953350245614">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver érvénytelen tanúsítványt mutatott be. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">A(z) <ph name="DOMAIN" /> domainnel való kapcsolata modern kriptográfiával van titkosítva.</translation>
<translation id="4594403342090139922">&amp;Törlés visszavonása</translation>
<translation id="4619615317237390068">Más eszközök lapjai</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa hibákat tartalmaz. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
+<translation id="4690462567478992370">Érvénytelen tanúsítvány használatának befejezése</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Kapcsolata megszakadt</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />A Windows Hálózati diagnosztika futtatása<ph name="END_LINK" /></translation>
@@ -422,21 +473,24 @@
<translation id="4771973620359291008">Ismeretlen hiba történt.</translation>
<translation id="4800132727771399293">Ellenőrizze a lejárati dátumot és a CVC-t, majd próbálja újra</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Pillanatnyilag nem tudja felkeresni a(z) <ph name="SITE" /> webhelyet, mivel az olyan titkosított hitelesítési adatokat küldött, amelyeket a Google Chrome nem tud feldolgozni. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal később valószínűleg már működni fog.</translation>
<translation id="4813512666221746211">Hálózati hiba</translation>
<translation id="4816492930507672669">Igazítás az oldalmérethez</translation>
<translation id="483020001682031208">Nem jeleníthetők meg oldalak a Fizikai webről</translation>
<translation id="4850886885716139402">Nézet</translation>
<translation id="4854362297993841467">Ez a kézbesítési mód nem áll rendelkezésre. Próbálkozzon másik móddal.</translation>
<translation id="4858792381671956233">Megkérdezted a szüleidet, hogy meg szabad-e látogatnod ezt a webhelyet</translation>
+<translation id="4863764087567530506">Lehet, hogy ez a tartalom megpróbálja rávenni Önt valamilyen szoftver telepítésére vagy személyes adatok kiadására. <ph name="BEGIN_LINK" />Megjelenítés mindenképpen<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Keresés az előzmények között</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> és <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{és egy további weboldal}other{és # további weboldal}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Ezt az oldalt lefordították egy ismeretlen nyelvről <ph name="LANGUAGE_LANGUAGE" /> nyelvre</translation>
<translation id="4923459931733593730">Fizetés</translation>
<translation id="4926049483395192435">Meg kell határozni.</translation>
<translation id="495170559598752135">Műveletek</translation>
<translation id="4958444002117714549">Lista részletes nézete</translation>
-<translation id="4962322354953122629">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a Chrome szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Figyelmeztetések újbóli engedélyezése</translation>
<translation id="4989809363548539747">Ez a beépülő modul nem támogatott</translation>
<translation id="5002932099480077015">Ha engedélyezi, a Chrome megőrzi a kártya másolatát ezen az eszközön a gyorsabb űrlapkitöltés érdekében.</translation>
<translation id="5018422839182700155">Nem lehet megnyitni az oldalt</translation>
@@ -444,14 +498,15 @@
<translation id="5023310440958281426">Ellenőrizze rendszergazdai házirendjeit</translation>
<translation id="5029568752722684782">Példány törlése</translation>
<translation id="5031870354684148875">A Google Fordító leírása</translation>
+<translation id="5039804452771397117">Engedélyezés</translation>
<translation id="5040262127954254034">Adatvédelem</translation>
<translation id="5045550434625856497">Helytelen jelszó</translation>
<translation id="5056549851600133418">Cikkek Önnek</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />A proxy címének ellenőrzése<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Nincs cookie}=1{1 webhely használ cookie-kat. }other{# webhely használ cookie-kat. }}</translation>
<translation id="5087286274860437796">A szerver tanúsítványa jelenleg nem érvényes.</translation>
<translation id="5087580092889165836">Kártya hozzáadása</translation>
<translation id="5089810972385038852">Ãllam</translation>
+<translation id="5094747076828555589">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a Chromium szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
<translation id="5095208057601539847">Tartomány</translation>
<translation id="5115563688576182185">(64 bites)</translation>
<translation id="5141240743006678641">A szinkronizált jelszavak titkosítása a Google hitelesítési adataival</translation>
@@ -467,24 +522,24 @@
<translation id="5222812217790122047">Az e-mail-cím megadása kötelező</translation>
<translation id="5251803541071282808">Felhő</translation>
<translation id="5277279256032773186">A munkahelyén használja a Chrome-ot? A cégek kezelhetik a Chrome-beállításokat alkalmazottaik számára. További információ.</translation>
+<translation id="5297526204711817721">Kapcsolata a webhellyel nem privát. Bármikor kiléphet a VR módból, ha leveszi a headsetet, és megnyomja a Vissza gombot.</translation>
<translation id="5299298092464848405">Irányelv-előfeldolgozási hiba</translation>
-<translation id="5300589172476337783">Megjelenítés</translation>
<translation id="5308689395849655368">A hibabejelentés ki van kapcsolva.</translation>
<translation id="5317780077021120954">Mentés</translation>
<translation id="5327248766486351172">Név</translation>
-<translation id="5337705430875057403">A(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhely támadói megpróbálhatják becsapni Önt, hogy például veszélyes szoftvert telepítsen vagy felfedje személyes adatait (jelszavát, telefonszámát, hitelkártyaszámát stb.).</translation>
-<translation id="5359637492792381994">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa jelenleg nem érvényes. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolatát. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Pillanatnyilag nem tudja felkeresni a(z) <ph name="SITE" /> webhelyet, mert a webhely tanúsítványát visszavonták. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal működése később valószínűleg helyreáll.</translation>
<translation id="536296301121032821">Az irányelv-beállítások tárolása sikertelen</translation>
<translation id="5386426401304769735">A webhely tanúsítványlánca SHA-1 titkosítással aláírt tanúsítványt tartalmaz.</translation>
<translation id="5402410679244714488">Lejárati dátum: <ph name="EXPIRATION_DATE_ABBR" />, utolsó használat több mint egy éve</translation>
+<translation id="540969355065856584">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa jelenleg nem érvényes. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolatát.</translation>
<translation id="5421136146218899937">Böngészési adatok törlése...</translation>
<translation id="5430298929874300616">Könyvjelző törlése</translation>
<translation id="5431657950005405462">A fájl nem található</translation>
-<translation id="5435775191620395718">Előzmények megjelenítése erről az eszközről. <ph name="BEGIN_LINK" />További információ<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Sémaérvényesítési hiba a következÅ‘nél: „<ph name="ERROR_PATH" />â€: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Ez a(z) <ph name="HOST_NAME" /> oldal nem található</translation>
<translation id="5455374756549232013">Hibás az irányelv időbélyege</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" />, összesen: <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Érvénytelen</translation>
<translation id="5470861586879999274">&amp;Szerkesztés újra</translation>
<translation id="54817484435770891">Érvényes címet adjon meg</translation>
<translation id="5492298309214877701">Ennek a vállalati, szervezeti vagy iskolai intraneten található webhelynek az URL-címe megegyezik egy külső webhely URL-címével.
@@ -501,6 +556,8 @@
<translation id="5571083550517324815">Ezen a címen nem lehetséges az átvétel. Válasszon másik címet.</translation>
<translation id="5572851009514199876">Indítsa el a Chrome böngészőt és jelentkezzen be, hogy a Chrome ellenőrizni tudja, engedélyezték-e a hozzáférést ehhez a webhelyhez.</translation>
<translation id="5580958916614886209">Ellenőrizze a lejárati hónapot, majd próbálja újra</translation>
+<translation id="5586446728396275693">Nincsenek mentett címek</translation>
+<translation id="5595485650161345191">Cím szerkesztése</translation>
<translation id="560412284261940334">A kezelés nem támogatott</translation>
<translation id="5610142619324316209">A kapcsolat ellenőrzése</translation>
<translation id="5610807607761827392">A kártyákat és a címeket a <ph name="BEGIN_LINK" />Beállítások<ph name="END_LINK" /> menüpontban kezelheti.</translation>
@@ -508,15 +565,18 @@
<translation id="5622887735448669177">Szeretné elhagyni ezt a webhelyet?</translation>
<translation id="5629630648637658800">Az irányelv-beállítások betöltése sikertelen</translation>
<translation id="5631439013527180824">Érvénytelen eszközkezelési token</translation>
+<translation id="5633066919399395251">Előfordulhat, hogy a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhely támadói veszélyes programokat kísérelnek meg telepíteni számítógépére, amelyek ellopják vagy törlik az Ön adatait (például fotóit, jelszavait, üzeneteit és hitelkártyaadatait). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5646376287012673985">Tartózkodási hely</translation>
+<translation id="5659593005791499971">E-mail</translation>
<translation id="5669703222995421982">Személyre szabott tartalmak fogadása</translation>
<translation id="5675650730144413517">Az oldal nem működik</translation>
-<translation id="5677928146339483299">Letiltva</translation>
-<translation id="5694783966845939798">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver gyenge aláírási algoritmust (pl. SHA-1-et) használó tanúsítványt mutatott be. Ez alapján elképzelhető, hogy a szerver által megadott biztonsági tanúsítványt hamisították, és a szerver nem az, amelyikre számított (lehet, hogy éppen a támadóval áll kapcsolatban). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">A webhely valódiságát nem ellenőriztük.</translation>
+<translation id="5713016350996637505">Megtévesztő tartalom letiltva</translation>
<translation id="5720705177508910913">Jelenlegi felhasználó</translation>
<translation id="5732392974455271431">A letiltást a szüleid oldhatják fel</translation>
<translation id="5763042198335101085">Érvényes e-mail-címet adjon meg</translation>
<translation id="5765072501007116331">A kézbesítési módok és követelmények megtekintéséhez válassza ki a címet</translation>
+<translation id="5778550464785688721">MIDI eszközök – teljes hozzáférés</translation>
<translation id="5784606427469807560">A kártya ellenőrzése során hiba történt. Ellenőrizze az internetkapcsolatot, majd próbálkozzon újra.</translation>
<translation id="5785756445106461925">Emellett az oldal azonban más forrásokat is tartalmaz, amelyek nem biztonságosak. Ezeket a forrásokat mások is megtekinthetik átvitel közben, és megváltoztatásukkal a támadók módosíthatják az oldal viselkedését.</translation>
<translation id="5786044859038896871">Ki szeretné tölteni a kártyaadatait?</translation>
@@ -525,14 +585,14 @@
<translation id="5813119285467412249">&amp;Hozzáadás újra</translation>
<translation id="5814352347845180253">Elveszítheti hozzáférését a(z) <ph name="SITE" /> és más webhelyek prémium tartalmaihoz.</translation>
<translation id="5838278095973806738">Ne írjon be semmilyen bizalmas adatot (például jelszót vagy hitelkártyaadatot) a webhelyen, mivel a támadók ellophatják.</translation>
-<translation id="5843436854350372569">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver gyenge kulccsal rendelkező tanúsítványt mutatott be. Előfordulhat, hogy támadó törte fel a privát kulcsot, és lehet, hogy a szerver nem a várt kiszolgáló (lehet, hogy Ön a támadóval áll kapcsolatban). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">A webhely nem érhető el</translation>
<translation id="5869522115854928033">Mentett jelszavak</translation>
<translation id="5872918882028971132">Szülői javaslatok</translation>
<translation id="5901630391730855834">Sárga</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (szinkronizálva)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 van használatban}other{# van használatban}}</translation>
<translation id="5926846154125914413">Elveszítheti hozzáférését az egyes webhelyek prémium tartalmaihoz.</translation>
<translation id="5959728338436674663">Bizonyos <ph name="BEGIN_WHITEPAPER_LINK" />rendszer-információk és oldaltartalmak<ph name="END_WHITEPAPER_LINK" /> automatikus küldése a Google-nak a veszélyes alkalmazások és webhelyek felderítése érdekében. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Hét</translation>
<translation id="5967867314010545767">Eltávolítás az előzmények közül</translation>
<translation id="5975083100439434680">Kicsinyítés</translation>
<translation id="598637245381783098">Nem sikerült megnyitni a fizetőalkalmazást</translation>
@@ -541,21 +601,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1. oldal}other{#. oldal}}</translation>
<translation id="6017514345406065928">Zöld</translation>
+<translation id="6017850046339264347">A(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhelyen lévő támadók megtévesztő alkalmazásokat telepíthetnek, amelyek más alkalmazásnak tettethetik magukat, illetve az Ön nyomon követésére alkalmas adatokat gyűjthetnek. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (szinkronizálva)</translation>
<translation id="6027201098523975773">Adjon meg nevet</translation>
<translation id="6040143037577758943">Bezárás</translation>
<translation id="6042308850641462728">Hosszabban</translation>
+<translation id="6047233362582046994">Ha tisztában van a biztonságát fenyegető kockázatokkal, a káros alkalmazások eltávolítása előtt is <ph name="BEGIN_LINK" />felkeresheti ezt a webhelyet<ph name="END_LINK" />.</translation>
+<translation id="6051221802930200923">Pillanatnyilag nem tudja felkeresni a(z) <ph name="SITE" /> webhelyet, mivel a webhely tanúsítványrögzítést használ. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal működése később valószínűleg helyreáll.</translation>
<translation id="6060685159320643512">Óvatosan, ezek a kísérletek haraphatnak</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{nincsen}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">A tartalmat egy rendszergazda által biztosított tanúsítványon keresztül érte el. A(z) <ph name="DOMAIN" /> számára megadott adatok a rendszergazda számára is elérhetők.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Nincs}=1{1 jelszó (szinkronizálva)}other{# jelszó (szinkronizálva)}}</translation>
<translation id="6146055958333702838">Ellenőrizze a kábeleket, majd indítsa újra a routert, modemet vagy más
hálózati eszközt, amelyet használ.</translation>
<translation id="614940544461990577">Próbálja ki a következőket:</translation>
<translation id="6151417162996330722">A szervertanúsítvány érvényességi ideje túl hosszú.</translation>
<translation id="6157877588268064908">A szállítási módok és követelmények megtekintéséhez válassza ki a címet</translation>
+<translation id="6158003235852588289">A Google Biztonságos Böngészés funkciója nemrég adathalászatot észlelt a következő webhelyen: <ph name="SITE" />. Az adathalász webhelyek más webhelynek tettetik magukat, hogy félrevezessék a felhasználókat.</translation>
<translation id="6165508094623778733">További információ</translation>
+<translation id="6169916984152623906">Most privát módon böngészhet, így az eszközt használó többi személy nem láthatja az Ön tevékenységeit. A letöltéseket és a könyvjelzőket azonban menti a rendszer.</translation>
<translation id="6177128806592000436">Kapcsolata a webhellyel nem biztonságos</translation>
<translation id="6184817833369986695">(kohorsz: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Ellenőrizze az internetkapcsolatot</translation>
<translation id="6218753634732582820">Eltávolítja a címet a Chromiumból?</translation>
+<translation id="6221345481584921695">A Google – Biztonságos böngészés nemrég <ph name="BEGIN_LINK" />rosszindulatú programokat<ph name="END_LINK" /> észlelt a következő webhelyen: <ph name="SITE" />. A rendes esetben biztonságos webhelyek néha rosszindulatú programokkal fertőződnek. A rosszindulatú tartalom az ilyen programok következő ismert terjesztőjétől származik: <ph name="SUBRESOURCE_HOST" />.</translation>
<translation id="6251924700383757765">Adatvédelmi irányelvek</translation>
<translation id="6254436959401408446">Nincs elég memória az oldal megnyitásához</translation>
<translation id="625755898061068298">Úgy döntött, hogy letiltja a biztonsági figyelmeztetéseket ezen a webhelyen.</translation>
@@ -581,15 +649,14 @@
<translation id="6404511346730675251">Könyvjelző szerkesztése</translation>
<translation id="6410264514553301377">Ãrja be a(z) <ph name="CREDIT_CARD" /> kártyán szereplÅ‘ lejárati dátumot és CVC-t</translation>
<translation id="6414888972213066896">Megkérdezted a szülőt, hogy meg szabad-e látogatnod ezt a webhelyet</translation>
-<translation id="6416403317709441254">Pillanatnyilag nem tudja felkeresni a(z) <ph name="SITE" /> webhelyet, mivel az olyan titkosított hitelesítési adatokat küldött, amelyeket a Chromium nem tud feldolgozni. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal később valószínűleg már működni fog. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Nem lehet ellenőrizni, hogy a tanúsítványt visszavonták-e.</translation>
<translation id="6433490469411711332">Kapcsolattartási adatok szerkesztése</translation>
<translation id="6433595998831338502">A(z) <ph name="HOST_NAME" /> visszautasította a csatlakozást.</translation>
<translation id="6446608382365791566">További adatok hozzáadása</translation>
+<translation id="6447842834002726250">Cookie-k</translation>
<translation id="6451458296329894277">Képernyő újraküldésének megerősítése</translation>
<translation id="6456339708790392414">Fizetés</translation>
<translation id="6458467102616083041">A rendszer figyelmen kívül hagyja, mivel az alapértelmezett keresést házirend tiltja le.</translation>
-<translation id="6462969404041126431">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványát visszavonhatták. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Eszközházirendek</translation>
<translation id="6477321094435799029">A Chrome szokatlan kódot észlelt az oldalon, ezért letiltotta az Ön személyes adatainak (például jelszavak, telefonszámok és hitelkártyaszámok) védelme érdekében.</translation>
<translation id="6489534406876378309">Feltöltési összeomlások indítása</translation>
@@ -601,20 +668,19 @@
<translation id="6556915248009097796">Lejárati dátum: <ph name="EXPIRATION_DATE_ABBR" />, utolsó használat: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">A kezelő még nem hagyta jóvá</translation>
<translation id="6569060085658103619">Jelenleg bővítményoldalt tekint meg</translation>
-<translation id="6593753688552673085">kevesebb, mint <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Lehet, hogy ez a tartalom megpróbál valamilyen veszélyes szoftvert telepíteni az eszközére, amely ellophatja vagy törölheti az Ön adatait. <ph name="BEGIN_LINK" />Megjelenítés mindenképpen<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Titkosítási lehetőségek</translation>
<translation id="662080504995468778">Mégse</translation>
<translation id="6626291197371920147">Adjon meg érvényes kártyaszámot</translation>
<translation id="6628463337424475685">Keresés: <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Előfordulhat, hogy a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhely támadói olyan veszélyes programokat kísérelnek meg telepíteni az Ön Mac típusú számítógépére, amelyek ellopják vagy törlik adatait (például fotóit, jelszavait, üzeneteit és hitelkártyaadatait). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6644283850729428850">Ez a házirend már elavult.</translation>
-<translation id="6652240803263749613">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a számítógép operációs rendszere szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Eltávolítja az űrlapjavaslatot a Chromiumból?</translation>
<translation id="6685834062052613830">Kijelentkezés és a beállítás befejezése</translation>
<translation id="6710213216561001401">Előző</translation>
<translation id="6710594484020273272">&lt;Ãrja be a keresési kifejezést&gt;</translation>
<translation id="6711464428925977395">Valami gond van a proxyszerverrel, vagy a cím nem megfelelő.</translation>
<translation id="6727102863431372879">Beállítás</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{nincsen}=1{1 elem}other{# elem}}</translation>
<translation id="674375294223700098">Ismeretlen szervertanúsítvány-hiba.</translation>
<translation id="6753269504797312559">Házirend értéke</translation>
<translation id="6757797048963528358">Eszköze alvó üzemmódba váltott.</translation>
@@ -622,6 +688,8 @@
<translation id="6810899417690483278">Testreszabás-azonosító</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Nem sikerült betölteni a régióadatokat</translation>
+<translation id="6825578344716086703">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver gyenge aláírási algoritmust használó tanúsítványt mutatott be. Ez alapján elképzelhető, hogy a szerver által megadott biztonsági tanúsítványt meghamisították, és a szerver nem az, amelyikre számított (lehet, hogy éppen valamilyen támadóval kommunikál).</translation>
+<translation id="6830728435402077660">Nem biztonságos</translation>
<translation id="6831043979455480757">Fordítás</translation>
<translation id="6839929833149231406">Körzet</translation>
<translation id="6874604403660855544">&amp;Hozzáadás újra</translation>
@@ -629,6 +697,7 @@
<translation id="6895330447102777224">Kártyáját ellenőriztük</translation>
<translation id="6897140037006041989">User agent</translation>
<translation id="6915804003454593391">Felhasználó:</translation>
+<translation id="6945221475159498467">Kiválasztás</translation>
<translation id="6948701128805548767">Az átvételi módok és követelmények megtekintéséhez válassza ki a címet</translation>
<translation id="6957887021205513506">A szerver tanúsítványa hamisítványnak tűnik.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -637,15 +706,16 @@
<translation id="6973656660372572881">Mindkét fix proxyszerver és egy .Pac típusú szkript URL-címe meg van adva.</translation>
<translation id="6989763994942163495">Speciális beállítások megjelenítése...</translation>
<translation id="7000990526846637657">Nincsenek előzménybejegyzések</translation>
-<translation id="7009986207543992532">Ön megpróbálta elérni a(z) <ph name="DOMAIN" /> domaint, de a szerver olyan tanúsítványt mutatott be, amelynek érvényességi ideje túl hosszú ahhoz, hogy megbízható legyen. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Előfordulhat, hogy a böngészési előzmények más formái megtalálhatók Google-fiókjában a <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> címen</translation>
<translation id="7029809446516969842">Jelszavak</translation>
+<translation id="7050187094878475250">Ön megpróbálta elérni a(z) <ph name="DOMAIN" /> domaint, de a szerver olyan tanúsítványt küldött, amelynek érvényességi ideje túl hosszú ahhoz, hogy megbízható legyen.</translation>
+<translation id="7053983685419859001">Letiltás</translation>
<translation id="7064851114919012435">Kapcsolatfelvételi adatok</translation>
<translation id="7079718277001814089">A webhely rosszindulatú programokat tartalmaz</translation>
<translation id="7087282848513945231">Megye</translation>
-<translation id="7088615885725309056">Régebbi</translation>
<translation id="7090678807593890770">Keresés a Google-on a következőre: <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Bővítmény engedélyezi</translation>
<translation id="7119414471315195487">Zárja be a többi lapot vagy programot</translation>
<translation id="7129409597930077180">Erre a címre nem lehetséges a szállítás. Válasszon másik címet.</translation>
<translation id="7138472120740807366">Kézbesítési mód</translation>
@@ -663,22 +733,18 @@
<translation id="7220786058474068424">Feldolgozás alatt</translation>
<translation id="724691107663265825">A megnyíló oldal rosszindulatú programot tartalmaz</translation>
<translation id="724975217298816891">Adja meg a(z) <ph name="CREDIT_CARD" /> kártya lejárati dátumát és CVC-kódját. Az ellenőrzést követően a böngésző megosztja kártyaadatait ezzel a webhellyel.</translation>
-<translation id="725866823122871198">Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert a számítógép dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="7260504762447901703">Hozzáférés visszavonása</translation>
<translation id="7275334191706090484">Kezelt könyvjelzők</translation>
<translation id="7298195798382681320">Ajánlott</translation>
<translation id="7309308571273880165">Hibajelentés készült: <ph name="CRASH_TIME" /> (a felhasználó által kért feltöltés – még nincs feltöltve)</translation>
<translation id="7334320624316649418">&amp;Ãtrendezés újra</translation>
<translation id="733923710415886693">A szerver tanúsítványát nem A tanúsítványok átláthatósága keretrendszeren keresztül hozták nyilvánosságra.</translation>
-<translation id="7351800657706554155">Pillanatnyilag nem tudja felkeresni a(z) <ph name="SITE" /> webhelyet, mert a tanúsítványát visszavonták. A hálózati hibák és támadások rendszerint átmenetiek, ezért az említett oldal később valószínűleg már működni fog. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Parancssor</translation>
<translation id="7372973238305370288">keresési találat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nem</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Kártya igazolása</translation>
-<translation id="7394102162464064926">Biztosan törli ezeket az oldalakat az előzményekből?
-
-Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő alkalommal.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Profil elérési útja</translation>
<translation id="7424977062513257142">A weboldal egy beágyazott oldalának közlendője:</translation>
@@ -686,6 +752,7 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="7444046173054089907">Ez a webhely le van tiltva</translation>
<translation id="7445762425076701745">Nem sikerült teljesen ellenőrizni a szerver azonosságát, amelyhez kapcsolódik. Egy olyan névvel kapcsolódik a szerverhez, amelynek tulajdonjogát egy külső tanúsítványkibocsátó nem ellenőrizheti. Mivel egyes tanúsítványkibocsátók figyelmen kívül hagyják ezeket a neveket, így semmi nem biztosítja, hogy a kívánt webhelyhez kapcsolódik, és nem egy támadó webhelyhez.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />További információk megtekintése<ph name="END_LINK" /> a problémával kapcsolatban.</translation>
+<translation id="7455133967321480974">Globális alapértelmezés használata (Tiltás)</translation>
<translation id="7460163899615895653">A többi eszközön legutoljára megtekintett lapok láthatók itt</translation>
<translation id="7469372306589899959">Kártya igazolása…</translation>
<translation id="7481312909269577407">Előre</translation>
@@ -693,36 +760,43 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="7508255263130623398">A visszakapott házirend eszközazonosítója üres, vagy nem felel meg a jelenlegi eszközazonosítónak</translation>
<translation id="7514365320538308">Letöltés</translation>
<translation id="7518003948725431193">Nem található weboldal az internetcímen:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Érték</translation>
<translation id="7537536606612762813">Kötelező</translation>
+<translation id="7542403920425041731">Az igazolást követően a böngésző megosztja kártyaadatait a webhellyel.</translation>
<translation id="7542995811387359312">Az automatikus bankkártya-kitöltés le van tiltva, mivel ez az űrlap nem biztonságos kapcsolatot használ.</translation>
<translation id="7543525346216957623">Kérd a szülő segítségét</translation>
<translation id="7549584377607005141">Ez a weboldal korábban megadott adatokat kér ahhoz, hogy megfelelően jelenjen meg. Az adatokat újra elküldheti, de ezzel meg fog ismételni minden olyan műveletet, amelyet ez az oldal korábban végrehajtott.</translation>
<translation id="7552846755917812628">Próbálja ki az alábbi tippeket:</translation>
<translation id="7554791636758816595">Új lap</translation>
+<translation id="7567204685887185387">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványát csalással állíthatták ki. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Az oldal nyelve<ph name="ORIGINAL_LANGUAGE" />Kívánja lefordítani?</translation>
<translation id="7569952961197462199">Eltávolítja a hitelkártyát a Chrome-ból?</translation>
<translation id="7569983096843329377">Fekete</translation>
<translation id="7578104083680115302">A Google rendszerében mentett kártyákkal gyorsan fizethet webhelyeken és alkalmazásokban bármelyik eszközén.</translation>
<translation id="7588950540487816470">Fizikai web</translation>
<translation id="7592362899630581445">A szervertanúsítvány sérti a névre vonatkozó megkötéseket.</translation>
+<translation id="7598391785903975535">Kevesebb, mint <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">A(z) <ph name="HOST_NAME" /> jelenleg nem tudja kezelni ezt a kérést.</translation>
<translation id="7600965453749440009">Soha ne fordítsa le a(z) <ph name="LANGUAGE" /> nyelvű szöveget</translation>
<translation id="7610193165460212391">Az érték kívül esik a következő tartományon: <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Lejárat: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Már rendelkezik olyan adattal, amely Google-fiókja jelszavának egy másik verziójával van titkosítva. Kérjük, lentebb adja azt meg.</translation>
-<translation id="7634554953375732414">A webhellyel való kapcsolata nem privát.</translation>
<translation id="7637571805876720304">Eltávolítja a hitelkártyát a Chromiumból?</translation>
<translation id="765676359832457558">Speciális beállítások elrejtése...</translation>
<translation id="7658239707568436148">Mégse</translation>
+<translation id="7662298039739062396">A beállítást bővítmény vezérli</translation>
<translation id="7667346355482952095">A visszaadott irányelvtoken üres vagy nem egyezik az aktuális tokennel</translation>
<translation id="7668654391829183341">Ismeretlen eszköz</translation>
<translation id="7669271284792375604">A webhelyen lévő támadók megpróbálhatják csellel rávenni Önt olyan programok telepítésére, amelyek károsak a böngészési élmény szempontjából (például módosítják a kezdőlapot, vagy plusz hirdetéseket jelenítenek meg a felkeresett webhelyeken).</translation>
<translation id="7674629440242451245">Érdekli néhány remek új Chrome-funkció? Próbálja ki a fejlesztői csatornánkat a chrome.com/dev webhelyen.</translation>
<translation id="7682287625158474539">Szállítási cím</translation>
+<translation id="7701040980221191251">Nincs</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Tovább a(z) <ph name="SITE" /> webhelyre (nem biztonságos)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Tanúsítvány</translation>
+<translation id="7716147886133743102">Rendszergazda tiltja</translation>
<translation id="7716424297397655342">A webhely nem tölthető be a gyorsítótárból</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Nem kezelt</translation>
<translation id="7755287808199759310">A letiltást a szülő oldhatja fel</translation>
<translation id="7758069387465995638">Előfordulhat, hogy a tűzfal vagy a vírusirtó szoftver tiltotta le a kapcsolatot.</translation>
@@ -749,15 +823,15 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="7951415247503192394">(32 bites)</translation>
<translation id="7956713633345437162">Mobil könyvjelzők</translation>
<translation id="7961015016161918242">Soha</translation>
-<translation id="7962083544045318153">Hibaazonosító: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">A(z) <ph name="ORIGINAL_LANGUAGE" /> nyelvű szövegeket mindig fordítsa <ph name="TARGET_LANGUAGE" /> nyelvre</translation>
<translation id="7995512525968007366">Nincs megadva</translation>
<translation id="800218591365569300">Próbáljon meg bezárni más lapokat vagy programokat memória felszabadítása céljából.</translation>
<translation id="8012647001091218357">Jelenleg nem tudjuk elérni szüleidet. Próbálkozz újra.</translation>
<translation id="8025119109950072390">A webhely támadói megpróbálhatják csellel rávenni Önt, hogy például telepítsen egy veszélyes szoftvert, vagy felfedje személyes adatait (jelszavát, telefonszámát, hitelkártyaszámát stb.).</translation>
-<translation id="803030522067524905">A Google Biztonságos Böngészés funkciója nemrég adathalászatot észlelt a következő webhelyen: <ph name="SITE" />. Az adathalász webhelyek más webhelynek tettetik magukat, hogy félrevezessék Önt. <ph name="BEGIN_LEARN_MORE_LINK" />További információ.<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Ez az oldal <ph name="SOURCE_LANGUAGE" /> nyelven van. Lefordítja <ph name="TARGET_LANGUAGE" /> nyelvre?</translation>
+<translation id="8037357227543935929">Kérdezzen rá (alapértelmezés szerint)</translation>
<translation id="8041089156583427627">Visszajelzés küldése</translation>
+<translation id="8041940743680923270">Globális alapértelmezés használata (Megkérdezés)</translation>
<translation id="8088680233425245692">Nem sikerült megtekinteni a cikket.</translation>
<translation id="8089520772729574115">kevesebb mint 1 MB</translation>
<translation id="8091372947890762290">Az aktiválás függőben van a szerveren</translation>
@@ -766,13 +840,14 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="8134994873729925007"><ph name="HOST_NAME" /> szerverének <ph name="BEGIN_ABBR" />DNS-címe<ph name="END_ABBR" /> nem található.</translation>
<translation id="8149426793427495338">Számítógépe alvó üzemmódba váltott.</translation>
<translation id="8150722005171944719">A fájl (<ph name="URL" />) nem olvasható. Lehet, hogy eltávolították, áthelyezték, vagy a fájlengedélyek megakadályozzák a hozzáférést.</translation>
+<translation id="8184538546369750125">Globális alapértelmezés használata (Engedélyezés)</translation>
+<translation id="8191494405820426728">Helyi hibaazonosító: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Ãthelyezés visszavonása</translation>
<translation id="8201077131113104583">A(z) „<ph name="EXTENSION_ID" />†azonosítójú bővítmény frissítési URL-je érvénytelen.</translation>
<translation id="8202097416529803614">Rendelés összegzése</translation>
<translation id="8218327578424803826">Hozzárendelt helyszín:</translation>
<translation id="8225771182978767009">A számítógépet beállító személy a webhely letiltása mellett döntött.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" /> és <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Előfordulhat, hogy a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhely támadói veszélyes programokat kísérelnek meg telepíteni számítógépére, amelyek ellopják vagy törlik adatait (például fotóit, jelszavait, üzeneteit és hitelkártyaadatait).</translation>
<translation id="8241707690549784388">A keresett oldal a megadott információt használta. Ha visszatér arra az oldalra, akkor lehet, hogy az egyszer már megtett mozdulatok ismétlésre kerülnek. Mégis továbblép?</translation>
<translation id="8249320324621329438">Utolsó lekérés:</translation>
<translation id="8253091569723639551">A számlázási cím megadása kötelező</translation>
@@ -780,6 +855,7 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="8289355894181816810">Forduljon a hálózati rendszergazdához, ha nem tudja, hogy ez mit jelent.</translation>
<translation id="8293206222192510085">Könyvjelző hozzáadása</translation>
<translation id="8294431847097064396">Forrás</translation>
+<translation id="8306404619377842860">Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert az eszköz dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8308427013383895095">A fordítás a hálózati kapcsolat problémája miatt nem sikerült.</translation>
<translation id="8332188693563227489">A hozzáférés megtagadva a következőhöz: <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Ha tisztában van a biztonságát fenyegető kockázatokkal, a veszélyes programok eltávolítása előtt is <ph name="BEGIN_LINK" />felkeresheti ezt a webhelyet<ph name="END_LINK" />.</translation>
@@ -800,11 +876,9 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="8483780878231876732">Jelentkezzen be a Chrome-ba, hogy használhassa a kártyákat Google-fiókjából.</translation>
<translation id="8488350697529856933">A következőre érvényes</translation>
<translation id="8498891568109133222">A(z) <ph name="HOST_NAME" /> túl hosszú ideje nem válaszol.</translation>
-<translation id="852346902619691059">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa az eszköz operációs rendszere szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy támadó térítette el az Ön kapcsolódását. <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Lejárat éve</translation>
<translation id="8543181531796978784">Lehetősége van arra, hogy <ph name="BEGIN_ERROR_LINK" />jelentse az észlelési problémát<ph name="END_ERROR_LINK" />, ha pedig tisztában van a biztonságát fenyegető kockázatokkal, <ph name="BEGIN_LINK" />felkeresheti a nem biztonságos webhelyet<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">A fordítás nem sikerült, mivel az oldal nyelvét nem lehet megállapítani.</translation>
-<translation id="8559762987265718583">Nem hozható létre privát kapcsolat a következővel: <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, mert az eszköz dátum- és időbeállítása helytelen (<ph name="DATE_AND_TIME" />).</translation>
<translation id="8571890674111243710">Oldal fordítása erre a nyelvre: <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Szám hozzáadása
</translation>
@@ -819,6 +893,7 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="8738058698779197622">Biztonságos kapcsolat létrehozásához az órát pontosan be kell állítani. Ez azért szükséges, mert a webhelyek által az azonosításukra használt tanúsítványok csak adott ideig érvényesek. Mivel az eszköz órája nem pontos, a Chromium nem tudja ellenőrizni ezeket a tanúsítványokat.</translation>
<translation id="8740359287975076522">A(z) <ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;DNS-címe&lt;/abbr&gt; nem található. A probléma diagnosztizálása folyamatban van.</translation>
<translation id="8759274551635299824">A kártya lejárt</translation>
+<translation id="8761567432415473239">A Google Biztonságos Böngészés nemrég <ph name="BEGIN_LINK" />ártalmas programokat talált<ph name="END_LINK" /> a következő webhelyen: <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Törlés újra</translation>
<translation id="8800988563907321413">A közeli javaslatok helye</translation>
<translation id="8820817407110198400">Könyvjelzők</translation>
@@ -831,29 +906,30 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="8870413625673593573">Mostanában bezárt</translation>
<translation id="8874824191258364635">Érvényes kártyaszámot adjon meg</translation>
<translation id="8876793034577346603">A hálózati konfiguráció előfeldolgozása sikertelen.</translation>
-<translation id="8877192140621905067">Az igazolást követően a böngésző megosztja kártyaadatait a webhellyel</translation>
<translation id="8889402386540077796">Színárnyalat</translation>
<translation id="8891727572606052622">Érvénytelen proxymód.</translation>
<translation id="889901481107108152">Sajnos ez a kísérlet nem érhető el az Ön operációs rendszerén.</translation>
<translation id="8903921497873541725">Nagyítás</translation>
<translation id="8931333241327730545">Menti ezt a kártyát a Google-fiókjába?</translation>
<translation id="8932102934695377596">Késik az órája</translation>
-<translation id="8954894007019320973">(Folyt.)</translation>
<translation id="8971063699422889582">A szerver tanúsítványa lejárt.</translation>
<translation id="8986494364107987395">Használati statisztikák és hibajelentések automatikus küldése a Google-nak</translation>
-<translation id="8987927404178983737">hónap</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">A felkeresni kívánt webhely ártalmas programokat tartalmaz</translation>
+<translation id="8997023839087525404">A szerver olyan tanúsítványt mutatott be, amelyet nem A tanúsítványok átláthatósága keretrendszer segítségével hoztak nyilvánosságra. Ez egyes tanúsítványoknál követelmény annak biztosítása érdekében, hogy az adott tanúsítványok megbízhatók, és védelmet nyújtanak a támadók ellen.</translation>
<translation id="9001074447101275817">A(z) <ph name="DOMAIN" /> proxy felhasználónevet és jelszót kér.</translation>
+<translation id="9005998258318286617">A PDF-dokumentum betöltése sikertelen.</translation>
<translation id="901974403500617787">Rendszerszinten érvényes jelölőket csak a tulajdonos (<ph name="OWNER_EMAIL" />) állíthat be.</translation>
+<translation id="9020200922353704812">A hitelkártyához tartozó számlázási cím megadása kötelező</translation>
<translation id="9020542370529661692">Az oldalt lefordítottuk <ph name="TARGET_LANGUAGE" /> nyelvre.</translation>
<translation id="9035022520814077154">Biztonsági hiba</translation>
<translation id="9038649477754266430">A várható kifejezés szolgáltatás használata az oldalak gyorsabb betöltése érdekében</translation>
<translation id="9039213469156557790">Emellett az oldal más forrásokat is tartalmaz, amelyek nem biztonságosak. Ezeket a forrásokat mások is megtekinthetik átvitel közben, és megváltoztatásukkal a támadók módosíthatják az oldal viselkedését.</translation>
-<translation id="9040185888511745258">A(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhelyen lévő támadók megpróbálhatják rávenni Önt olyan programok telepítésére, amelyek károsak a böngészési élmény szempontjából (például módosítják a kezdőlapot vagy plusz hirdetéseket jelenítenek meg a felkeresett webhelyeken).</translation>
+<translation id="9049981332609050619">Megpróbálta elérni a(z) <ph name="DOMAIN" /> webhelyet, de a szerver érvénytelen tanúsítványt mutatott be.</translation>
<translation id="9050666287014529139">Összetett jelszó</translation>
<translation id="9065203028668620118">Szerkesztés</translation>
<translation id="9068849894565669697">Szín kiválasztása</translation>
+<translation id="9069693763241529744">Bővítmény tiltja</translation>
<translation id="9076283476770535406">Lehet, hogy felnőtt tartalommal rendelkezik</translation>
<translation id="9078964945751709336">Több információra van szükség</translation>
<translation id="9103872766612412690">A(z) <ph name="SITE" /> webhely rendes esetben titkosítást alkalmaz az Ön adatainak védelme érdekében. Amikor a Chromium most csatlakozni próbált, a(z) <ph name="SITE" /> webhely szokatlan és helytelen hitelesítési adatokat küldött vissza.Ez olyankor fordulhat elő, amikor egy támadó megpróbálja magát kiadni a(z) <ph name="SITE" /> webhelynek, vagy valamilyen Wi-Fi-bejelentkezési képernyő megszakította a kapcsolatot. Adatai továbbra is biztonságban vannak, mivel a Chromium még azt megelőzően megszakította a kapcsolatot, hogy bármiféle adatcserére sor kerülhetett volna.</translation>
@@ -862,16 +938,21 @@ Pszt! Az inkognitómód (<ph name="SHORTCUT_KEY" />) hasznos lehet a következő
<translation id="9148507642005240123">&amp;Szerkesztés visszavonása</translation>
<translation id="9154194610265714752">Frissítve</translation>
<translation id="9157595877708044936">Előkészítés...</translation>
+<translation id="9169664750068251925">Mindig tiltsa ezen az oldalon</translation>
<translation id="9170848237812810038">&amp;Visszavonás</translation>
<translation id="917450738466192189">A szerver tanúsítványa érvénytelen.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> és további <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419">A(z) <ph name="HOST_NAME" /> egy nem támogatott protokollt használ.</translation>
<translation id="9205078245616868884">Adatai az összetett szinkronizálási jelszavával vannak titkosítva. Adja meg a jelszót a szinkronizálás megkezdéséhez.</translation>
<translation id="9207861905230894330">A cikk hozzáadása sikertelen.</translation>
+<translation id="9219103736887031265">Képek</translation>
<translation id="933612690413056017">Nincs internetkapcsolat</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ŰRLAP TÖRLÉSE</translation>
<translation id="939736085109172342">Új mappa</translation>
<translation id="941721044073577244">Úgy tűnik, nincs jogosultsága a webhely felkeresésére</translation>
<translation id="969892804517981540">Hivatalos verzió</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Nincs}=1{1 elem}other{# elem}}</translation>
<translation id="988159990683914416">Fejlesztői változat</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_id.xtb b/chromium/components/strings/components_strings_id.xtb
index 468dbe9a02d..4bde6a8b75a 100644
--- a/chromium/components/strings/components_strings_id.xtb
+++ b/chromium/components/strings/components_strings_id.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Putar searah jarum jam</translation>
<translation id="1038842779957582377">nama tidak diketahui</translation>
<translation id="1050038467049342496">Tutup aplikasi lain</translation>
-<translation id="1053591932240354961">Saat ini, Anda tidak dapat mengunjungi <ph name="SITE" /> karena situs web ini mengirimkan kredensial acak yang tidak dapat diproses oleh Google Chrome. Kesalahan dan serangan jaringan biasanya bersifat sementara, jadi laman ini mungkin akan bekerja nanti. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Urungkan Penambahan</translation>
<translation id="10614374240317010">Jangan pernah disimpan</translation>
<translation id="106701514854093668">Bookmark Desktop</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cache kebijakan Oke</translation>
<translation id="113188000913989374"><ph name="SITE" /> menyatakan:</translation>
<translation id="1132774398110320017">Setelan IsiOtomatis Chrome...</translation>
+<translation id="1150979032973867961">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh sistem operasi komputer Anda. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
+<translation id="1151972924205500581">Sandi wajib ada</translation>
<translation id="1152921474424827756">Akses <ph name="BEGIN_LINK" />salinan yang disimpan dalam cache<ph name="END_LINK" /> dari <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> tiba-tiba menutup sambungan.</translation>
<translation id="1161325031994447685">Menyambungkan ulang ke Wi-Fi</translation>
+<translation id="1165039591588034296">Kesalahan</translation>
<translation id="1175364870820465910">&amp;Cetak...</translation>
<translation id="1181037720776840403">Hapus</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Otomatis laporkan<ph name="END_WHITEPAPER_LINK" /> detail kemungkinan insiden keamanan ke Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Lainnya dari situs ini</translation>
<translation id="1206967143813997005">Tanda tangan awal tidak valid</translation>
<translation id="1209206284964581585">Sembunyikan sekarang</translation>
+<translation id="121201262018556460">Anda bermaksud membuka <ph name="DOMAIN" />, namun server menyajikan sertifikat yang berisi kunci yang lemah. Penyerang mungkin telah merusak kunci pribadi, dan server mungkin bukan yang diharapkan (Anda mungkin sedang berkomunikasi dengan penyerang).</translation>
<translation id="1219129156119358924">Keamanan Sistem</translation>
<translation id="1227224963052638717">Kebijakan tidak dikenal.</translation>
<translation id="1227633850867390598">Sembunyikan nilai</translation>
<translation id="1228893227497259893">Pengidentifikasi entitas salah</translation>
<translation id="1232569758102978740">Tanpa Judul</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (disinkronkan)</translation>
<translation id="1263231323834454256">Daftar bacaan</translation>
<translation id="1264126396475825575">Laporan kerusakan diambil pada pukul <ph name="CRASH_TIME" /> (belum diupload atau diabaikan)</translation>
+<translation id="1281526147609854549">Diterbitkan oleh <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Konten berbahaya diblokir</translation>
<translation id="1285320974508926690">Jangan pernah terjemahkan situs ini</translation>
<translation id="129553762522093515">Barusan ditutup</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Coba hapus cookie Anda<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Aktivitas Anda <ph name="BEGIN_EMPHASIS" />mungkin tetap dapat dilihat<ph name="END_EMPHASIS" /> oleh:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Situs yang Anda buka
+ <ph name="LIST_ITEM" />Pihak sekolah atau atasan Anda
+ <ph name="LIST_ITEM" />Internet Service Provider Anda
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domain pendaftaran:</translation>
<translation id="1340482604681802745">Alamat pengambilan</translation>
<translation id="1344211575059133124">Tampaknya Anda memerlukan izin untuk mengunjungi situs ini</translation>
<translation id="1344588688991793829">Setelan IsiOtomatis Chromium...</translation>
+<translation id="1348198688976932919">Situs yang akan dibuka berisi aplikasi berbahaya</translation>
<translation id="1374468813861204354">saran</translation>
<translation id="1375198122581997741">Tentang Versi</translation>
<translation id="1377321085342047638">Nomor Kartu</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> tidak mengirimkan data apa pun.</translation>
<translation id="1407135791313364759">Buka semua</translation>
<translation id="1413809658975081374">Kesalahan privasi</translation>
+<translation id="14171126816530869">Identitas <ph name="ORGANIZATION" /> di <ph name="LOCALITY" /> telah diverifikasi oleh <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ya</translation>
<translation id="1430915738399379752">Cetak</translation>
-<translation id="1442912890475371290">Usaha yang diblokir <ph name="BEGIN_LINK" /> untuk mengunjungi laman di <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Saat ini, Anda tidak dapat mengunjungi <ph name="SITE" /> karena situs web ini menggunakan penyematan sertifikat. Kesalahan dan serangan jaringan biasanya bersifat sementara, jadi laman ini mungkin akan bekerja nanti. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> metode lainnya}other{<ph name="PAYMENT_METHOD_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> metode lainnya}}</translation>
<translation id="1506687042165942984">Tampilkan salinan tersimpan (yang diketahui telah habis masa berlakunya) dari laman ini.</translation>
<translation id="1517433312004943670">Perlu nomor telepon</translation>
<translation id="1519264250979466059">Tanggal Dibuat</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript harus diaktifkan untuk menggunakan fitur ini.</translation>
<translation id="1555130319947370107">Biru</translation>
<translation id="1559528461873125649">Tidak ada file atau direktori tersebut</translation>
-<translation id="1559572115229829303">&lt;p&gt;Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat dibuat karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) perangkat Anda tidak benar.&lt;/p&gt;
-
- &lt;p&gt;Sesuaikan tanggal dan waktu dari bagian &lt;strong&gt;Umum&lt;/strong&gt; aplikasi &lt;strong&gt;Setelan&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Terjadi masalah sewaktu menampilkan laman web ini.</translation>
<translation id="1592005682883173041">Akses Data Lokal</translation>
+<translation id="1594030484168838125">Pilih</translation>
<translation id="161042844686301425">Sian</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Ingin Chrome menyimpan kartu ini?</translation>
<translation id="1639239467298939599">Memuat</translation>
<translation id="1640180200866533862">Kebijakan pengguna</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Konfigurasi cadangan tidak valid dan tidak dapat diimpor.</translation>
<translation id="1644574205037202324">Riwayat</translation>
<translation id="1645368109819982629">Protokol yang tidak didukung</translation>
+<translation id="1655462015569774233">{1,plural, =1{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; masa berlaku sertifikat keamanannya telah berakhir kemarin. Hal ini mungkin disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang memintas sambungan internet Anda. Jam komputer Anda saat ini diatur ke <ph name="CURRENT_DATE" />. Apakah terlihat sesuai? Jika tidak, Anda harus membenarkan jam sistem dan menyegarkan laman ini.}other{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; masa berlaku sertifikat keamanannya telah berakhir # hari yang lalu. Hal ini mungkin disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang memintas sambungan internet Anda. Jam komputer Anda saat ini diatur ke <ph name="CURRENT_DATE" />. Apakah terlihat sesuai? Jika tidak, Anda harus membenarkan jam sistem dan menyegarkan laman ini.}}</translation>
<translation id="1656489000284462475">Pengambilan</translation>
<translation id="1663943134801823270">Kartu dan alamat berasal dari Chrome. Anda dapat mengelolanya di <ph name="BEGIN_LINK" />Setelan<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> biasanya menggunakan enkripsi untuk melindungi informasi Anda. Saat Google Chrome mencoba menyambung ke <ph name="SITE" /> kali ini, situs web mengembalikan kredensial yang salah dan tidak biasa. Hal ini dapat terjadi jika ada penyerang yang berpura-pura menjadi <ph name="SITE" />, atau layar masuk Wi-Fi mengganggu sambungan. Informasi Anda masih aman karena Google Chrome menghentikan sambungan sebelum terjadi pertukaran data apa pun.</translation>
-<translation id="168328519870909584">Saat ini penyerang yang berada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin berusaha memasang program berbahaya di perangkat Anda yang dapat mencuri atau menghapus informasi (misalnya, foto, sandi, pesan, dan kartu kredit).</translation>
<translation id="168841957122794586">Sertifikat server berisi kunci kriptografis yang lemah.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya sepertinya dari esok hari. Hal ini mungkin disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang memintas sambungan internet Anda.}other{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya sepertinya dari # hari mendatang. Hal ini mungkin disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang memintas sambungan internet Anda.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Anda memerlukan izin dari <ph name="NAME" /> untuk mengunjungi situs ini</translation>
<translation id="1721424275792716183">* Kolom wajib diisi</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Download halaman nanti</translation>
<translation id="17513872634828108">Buka tab</translation>
<translation id="1753706481035618306">Nomor laman</translation>
+<translation id="1763864636252898013">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh sistem operasi perangkat Anda. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Coba jalankan Diagnostik Jaringan Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Perbarui frasa sandi sinkronisasi Anda.</translation>
<translation id="1787142507584202372">Tab yang terbuka muncul di sini</translation>
+<translation id="1789575671122666129">Munculan</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nama Pemegang Kartu</translation>
-<translation id="1803678881841855883">Google Penjelajahan Aman baru-baru ini <ph name="BEGIN_LINK" />mendeteksi software perusak<ph name="END_LINK" /> di <ph name="SITE" />. Situs web yang biasanya aman terkadang dapat terinfeksi software perusak. Konten berbahaya tersebut berasal dari <ph name="SUBRESOURCE_HOST" />, sebuah distributor software perusak ternama. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Ditambahkan pada <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Permintaan atau parameter permintaan tidak valid</translation>
<translation id="1826516787628120939">Memeriksa</translation>
<translation id="1834321415901700177">Situs ini berisi program yang berbahaya</translation>
+<translation id="1840414022444569775">Nomor kartu ini telah digunakan</translation>
<translation id="1842969606798536927">Bayar</translation>
<translation id="1871208020102129563">Proxy disetel untuk menggunakan server proxy tetap, bukan URL skrip .pac.</translation>
<translation id="1871284979644508959">Bidang wajib diisi</translation>
<translation id="187918866476621466">Buka halaman awal</translation>
<translation id="1883255238294161206">Ciutkan daftar</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> alamat lainnya}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> alamat lainnya}}</translation>
<translation id="1898423065542865115">Pemfilteran</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Tidak ada}=1{1 situs}other{# situs}}</translation>
<translation id="194030505837763158">Buka <ph name="LINK" /></translation>
<translation id="1962204205936693436">Bookmark <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Kesalahan serialisasi</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Diabaikan karena diganti dengan <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Mencari laman Web Fisik di sekitar</translation>
<translation id="213826338245044447">Bookmark Seluler</translation>
-<translation id="2148716181193084225">Hari ini</translation>
+<translation id="2147827593068025794">Sinkronisasi Latar Belakang</translation>
<translation id="2154054054215849342">Sinkronisasi tidak tersedia untuk domain Anda</translation>
<translation id="2154484045852737596">Edit kartu</translation>
<translation id="2166049586286450108">Akses Penuh Admin</translation>
<translation id="2166378884831602661">Situs ini tidak dapat menyediakan sambungan aman</translation>
<translation id="2181821976797666341">Kebijakan</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 alamat}other{# alamat}}</translation>
+<translation id="2187317261103489799">Deteksi (default)</translation>
<translation id="2202020181578195191">Masukkan tahun habis masa berlaku yang valid</translation>
<translation id="2212735316055980242">Kebijakan tidak ditemukan</translation>
<translation id="2213606439339815911">Mengambil entri...</translation>
+<translation id="2218879909401188352">Saat ini, penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> dapat menginstal aplikasi berbahaya yang dapat merusak perangkat, menambahkan biaya tersembunyi ke tagihan seluler, atau mencuri informasi pribadi Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Perbaiki sambungan menggunakan <ph name="BEGIN_LINK" />aplikasi diagnosis<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Kirim sekarang</translation>
<translation id="225207911366869382">Nilai ini sudah usang untuk kebijakan ini.</translation>
<translation id="2262243747453050782">Kesalahan HTTP</translation>
+<translation id="2270484714375784793">Nomor telepon</translation>
<translation id="2282872951544483773">Eksperimen Tidak Tersedia</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item}other{<ph name="ITEM_COUNT" /> item}}</translation>
<translation id="2292556288342944218">Akses Internet Anda diblokir</translation>
<translation id="230155334948463882">Kartu baru?</translation>
-<translation id="2305919008529760154">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya mungkin telah dikeluarkan secara tidak sah. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut <ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> memerlukan nama pengguna dan sandi.</translation>
-<translation id="2318774815570432836">Saat ini, Anda tidak dapat mengunjungi <ph name="SITE" /> karena situs web tersebut menggunakan HSTS. Kesalahan dan serangan jaringan biasanya bersifat sementara, jadi laman ini mungkin akan bekerja nanti. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Setelan dikontrol oleh administrator Anda</translation>
<translation id="2354001756790975382">Bookmark lain</translation>
+<translation id="2354430244986887761">Baru-baru ini, Google Safe Browsing <ph name="BEGIN_LINK" />menemukan aplikasi berbahaya<ph name="END_LINK" /> di <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Penyerang mungkin dapat melihat gambar yang sedang Anda lihat di situs dan mengelabui Anda dengan memodifikasinya.</translation>
+<translation id="2356070529366658676">Tanya</translation>
+<translation id="2359629602545592467">Beberapa</translation>
<translation id="2359808026110333948">Lanjut</translation>
<translation id="2365563543831475020">Laporan kerusakan yang diambil pada pukul <ph name="CRASH_TIME" /> tidak diupload</translation>
<translation id="2367567093518048410">Tingkat</translation>
-<translation id="2371153335857947666">{1,plural, =1{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; masa berlaku sertifikat keamanannya telah berakhir kemarin. Hal ini dapat disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang mencegat sambungan Anda. Jam komputer Anda saat ini disetel ke <ph name="CURRENT_DATE" />. Apakah sudah sesuai? Jika belum sesuai, Anda harus membenarkan jam sistem dan menyegarkan laman ini. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}other{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; masa berlaku sertifikat keamanannya telah berakhir # hari yang lalu. Hal ini dapat disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang mencegat sambungan Anda. Jam komputer Anda saat ini disetel ke <ph name="CURRENT_DATE" />. Apakah sudah sesuai? Jika belum sesuai, Anda harus membenarkan jam sistem dan menyegarkan laman ini. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Tidak tersedia alternatif UI</translation>
<translation id="2384307209577226199">Default perusahaan</translation>
<translation id="2386255080630008482">Sertifikat server telah dicabut.</translation>
<translation id="2392959068659972793">Tampilkan kebijakan tanpa nilai yang disetel</translation>
<translation id="239429038616798445">Metode pengiriman tidak tersedia. Coba metode lain.</translation>
<translation id="2396249848217231973">&amp;Urungkan penghapusan</translation>
-<translation id="2460160116472764928">Google Penjelajahan Aman baru-baru ini <ph name="BEGIN_LINK" />mendeteksi software perusak<ph name="END_LINK" /> di <ph name="SITE" />. Situs web yang biasanya aman terkadang dapat terinfeksi software perusak. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya mungkin dicabut. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
<translation id="2463739503403862330">Isi</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Jalankan Diagnostik Jaringan<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL penelusuran tidak valid.</translation>
+<translation id="2482878487686419369">Notifikasi</translation>
<translation id="2491120439723279231">Sertifikat server mengandung kesalahan.</translation>
<translation id="2495083838625180221">Pengurai JSON</translation>
<translation id="2495093607237746763">Jika dicentang, Chromium akan menyimpan salinan kartu Anda di perangkat ini untuk pengisian formulir yang lebih cepat.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Kembali</translation>
<translation id="2515629240566999685">Periksa sinyal di area Anda</translation>
<translation id="2516305470678292029">Alternatif UI</translation>
+<translation id="2539524384386349900">Deteksi</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> mengirimkan tanggapan yang tidak valid.</translation>
-<translation id="2552545117464357659">Anyar</translation>
<translation id="2556876185419854533">&amp;Urungkan Pengeditan</translation>
<translation id="2587730715158995865">Dari <ph name="ARTICLE_PUBLISHER" />. Baca artikel ini dan <ph name="OTHER_ARTICLE_COUNT" /> artikel lainnya.</translation>
<translation id="2587841377698384444">ID API Direktori:</translation>
<translation id="2597378329261239068">Dokumen ini dilindungi sandi. Masukkan sandi.</translation>
<translation id="2609632851001447353">Variasi</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Tidak ada}=1{1 aplikasi ($1)}=2{2 aplikasi ($1, $2)}other{# aplikasi ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Setelan jam terlalu cepat</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Akses ke file ditolak</translation>
<translation id="2653659639078652383">Kirim</translation>
<translation id="2666117266261740852">Tutup tab atau aplikasi lain</translation>
+<translation id="2670429602441959756">Halaman ini berisi fitur yang belum didukung dalam VR. Keluar...</translation>
<translation id="2674170444375937751">Yakin ingin menghapus laman ini dari riwayat?</translation>
<translation id="2677748264148917807">Keluar</translation>
-<translation id="269990154133806163">Server menunjukkan sertifikat yang tidak diungkapkan secara publik menggunakan kebijakan Transparansi Sertifikat. Ini adalah persyaratan untuk beberapa sertifikat, guna memastikan bahwa sertifikat tersebut dapat dipercaya dan melindungi dari penyerang. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Daftar Bacaan</translation>
<translation id="2704283930420550640">Nilai tidak sesuai format.</translation>
<translation id="2704951214193499422">Saat ini Chromium tidak dapat mengonfirmasi kartu. Coba lagi nanti.</translation>
<translation id="2705137772291741111">Salinan tersimpan (dalam cache) situs ini tidak dapat dibaca.</translation>
<translation id="2709516037105925701">Isi-Otomatis</translation>
-<translation id="2712118517637785082">Anda berusaha menjangkau <ph name="DOMAIN" />, tetapi sertifikat yang ditunjukkan oleh server telah dicabut oleh penerbitnya. Artinya, kredensial keamanan yang ditunjukkan server tidak dapat dipercaya. Anda mungkin sedang berkomunikasi dengan penyerang. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Minta izin</translation>
<translation id="2713444072780614174">Putih</translation>
<translation id="2720342946869265578">Di Sekitar</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Catatan perangkat hilang</translation>
<translation id="2784949926578158345">Sambungan disetel ulang.</translation>
<translation id="2794233252405721443">Situs diblokir</translation>
+<translation id="2799020568854403057">Situs yang akan dibuka berisi aplikasi berbahaya</translation>
+<translation id="2803306138276472711">Google Safe Browsing baru saja <ph name="BEGIN_LINK" />mendeteksi software perusak<ph name="END_LINK" /> di <ph name="SITE" />. Situs web yang umumnya aman terkadang terinfeksi software perusak.</translation>
<translation id="2824775600643448204">Bilah penelusuran dan alamat</translation>
<translation id="2826760142808435982">Sambungan dienkripsi dan diautentikasi menggunakan <ph name="CIPHER" /> dan menggunakan <ph name="KX" /> sebagai mekanisme pertukaran kunci.</translation>
<translation id="2835170189407361413">Hapus formulir</translation>
+<translation id="2856444702002559011">Penyerang mungkin berusaha mencuri informasi Anda dari <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (misalnya, sandi, pesan, atau kartu kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Jangan Muat Ulang</translation>
<translation id="2900469785430194048">Google Chrome kehabisan memori saat mencoba menampilkan laman web ini.</translation>
<translation id="2909946352844186028">Perubahan jaringan terdeteksi.</translation>
<translation id="2916038427272391327">Tutup program lain</translation>
<translation id="2922350208395188000">Sertifikat server tidak dapat diperiksa.</translation>
<translation id="2928905813689894207">Alamat Penagihan</translation>
+<translation id="2941952326391522266">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya dari <ph name="DOMAIN2" />. Hal ini disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
<translation id="2948083400971632585">Anda dapat menonaktifkan proxy apa pun yang dikonfigurasi untuk sambungan dari laman setelan.</translation>
<translation id="2955913368246107853">Tutup bilah cari</translation>
<translation id="2958431318199492670">Konfigurasi jaringan tidak mematuhi standar ONC. Bagian dari konfigurasi mungkin tidak diimpor.</translation>
-<translation id="29611076221683977">Saat ini penyerang yang berada pada <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin berusaha memasang program berbahaya di Mac yang dapat mencuri atau menghapus informasi Anda (misalnya, foto, sandi, pesan, dan kartu kredit).</translation>
<translation id="2966678944701946121">Habis masa berlaku: <ph name="EXPIRATION_DATE_ABBR" />, ditambahkan pada <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Untuk membuat sambungan aman, jam perlu disetel dengan benar. Itu karena sertifikat yang digunakan situs web untuk mengidentifikasi situs web tersebut hanya valid untuk jangka waktu tertentu. Karena jam perangkat tidak benar, Google Chrome tidak dapat memverifikasi sertifikat ini.</translation>
<translation id="2972581237482394796">&amp;Ulang</translation>
@@ -226,37 +253,44 @@
<translation id="2985398929374701810">Masukkan alamat yang valid</translation>
<translation id="2986368408720340940">Metode pengambilan tidak tersedia. Coba metode lain.</translation>
<translation id="2991174974383378012">Berbagi dengan Situs Web</translation>
+<translation id="2991571918955627853">Anda tidak dapat mengunjungi <ph name="SITE" /> sekarang karena situs menggunakan HSTS. Error jaringan dan serangan biasanya bersifat sementara, sehingga halaman ini mungkin akan berfungsi nanti.</translation>
<translation id="3005723025932146533">Tampilkan salinan yang disimpan</translation>
<translation id="3008447029300691911">Masukkan CVC untuk <ph name="CREDIT_CARD" />. Setelah mengonfirmasi, detail kartu Anda akan dibagikan dengan situs ini.</translation>
<translation id="3010559122411665027">Entri daftar "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Diblokir secara otomatis</translation>
<translation id="3024663005179499861">Jenis kebijakan salah</translation>
<translation id="3032412215588512954">Ingin memuat ulang situs ini?</translation>
<translation id="3037605927509011580">Yah!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{minimal 1 item pada perangkat yang disinkronkan}=1{1 item (dan beberapa di perangkat yang disinkronkan)}other{# item (dan beberapa di perangkat yang disinkronkan)}}</translation>
<translation id="3041612393474885105">Informasi Sertifikat</translation>
<translation id="3063697135517575841">Saat ini Chrome tidak dapat mengonfirmasi kartu. Coba lagi nanti.</translation>
<translation id="3064966200440839136">Keluar dari mode penyamaran untuk membayar melalui aplikasi eksternal. Lanjutkan?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Tidak ada}=1{1 sandi}other{# sandi}}</translation>
<translation id="3093245981617870298">Anda sedang offline.</translation>
<translation id="3105172416063519923">ID Aset:</translation>
<translation id="3109728660330352905">Anda tidak memiliki otorisasi untuk melihat laman ini.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Coba jalankan Diagnostik Konektivitas<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Gagal mendekodekan tanggapan</translation>
<translation id="3150653042067488994">Kesalahan server sementara</translation>
-<translation id="3154506275960390542">Halaman ini berisi formulir yang mungkin tidak dikirim dengan aman. Data yang Anda kirim dapat dilihat oleh orang lain saat dalam proses pengiriman atau dapat diubah oleh penyerang untuk mengubah data yang akan diterima server.</translation>
+<translation id="3154506275960390542">Halaman ini berisi formulir yang mungkin tidak dikirim dengan aman. Data yang Anda kirim dapat dilihat oleh orang lain saat transit atau dapat diubah oleh penyerang untuk mengubah data yang akan diterima server.</translation>
<translation id="3157931365184549694">Pulihkan</translation>
<translation id="3167968892399408617">Halaman yang Anda lihat di tab penyamaran tidak akan disimpan dalam riwayat browser, penyimpanan cookie, atau riwayat penelusuran setelah Anda menutup semua tab penyamaran. File apa pun yang didownload atau bookmark yang dibuat akan tetap tersimpan.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Pulau</translation>
+<translation id="317583078218509884">Setelan izin situs baru akan berlaku setelah laman dimuat ulang.</translation>
<translation id="3176929007561373547">Periksa setelan proxy atau hubungi administrator jaringan untuk
memastikan bahwa server proxy bekerja. Jika Anda tidak yakin harus
menggunakan server proxy:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Buka halaman dalam Mode penyamaran</translation>
-<translation id="3202578601642193415">Terbaru</translation>
+<translation id="320323717674993345">Batalkan Pembayaran</translation>
<translation id="3207960819495026254">Diberi bookmark</translation>
+<translation id="3225919329040284222">Server menunjukkan sertifikat yang tidak sesuai dengan harapan terpasang. Harapan ini disertakan untuk situs web tertentu dengan keamanan tinggi guna melindungi Anda.</translation>
<translation id="3226128629678568754">Tekan tombol muat ulang untuk mengirimkan lagi data yang dibutuhkan untuk memuat laman ini.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Terjemahan gagal karena laman sudah dalam bahasa <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Masukkan CVC untuk <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Selalu deteksi konten penting di situs ini</translation>
<translation id="3254409185687681395">Bookmark laman ini</translation>
<translation id="3270847123878663523">&amp;Urungkan Pengaturan Ulang</translation>
<translation id="3282497668470633863">Tambahkan nama di kartu</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">setelan</translation>
<translation id="3345135638360864351">Permintaan Anda untuk mengakses situs ini tidak dapat dikirimkan ke <ph name="NAME" />. Coba lagi.</translation>
<translation id="3355823806454867987">Ubah setelan proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />tidak akan menyimpan<ph name="END_EMPHASIS" /> informasi berikut:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Riwayat penjelajahan Anda
+ <ph name="LIST_ITEM" />Cookie dan data situs
+ <ph name="LIST_ITEM" />Informasi yang dimasukkan dalam formulir
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Kesalahan jam</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> item lainnya...</translation>
<translation id="337363190475750230">Tidak ditetapkan</translation>
<translation id="3377188786107721145">Kesalahan penguraian kebijakan</translation>
<translation id="3380365263193509176">Kesalahan tidak dikenal</translation>
<translation id="3380864720620200369">ID Klien:</translation>
<translation id="3391030046425686457">Alamat pengiriman</translation>
<translation id="3395827396354264108">Metode pengambilan</translation>
-<translation id="340013220407300675">Penyerang mungkin mencoba mencuri informasi Anda dari <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (misalnya, sandi, pesan, atau kartu kredit).</translation>
<translation id="3422248202833853650">Coba program lain yang ada untuk mengosongkan memori.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> saat ini tidak dapat dijangkau.</translation>
+<translation id="3427092606871434483">Izinkan (default)</translation>
<translation id="3427342743765426898">&amp;Ulangi Pengeditan</translation>
<translation id="3431636764301398940">Simpan kartu ini ke perangkat ini</translation>
<translation id="3435896845095436175">Aktifkan</translation>
<translation id="3447661539832366887">Pemilik perangkat ini menonaktifkan game dinosaurus.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval pengambilan:</translation>
<translation id="3462200631372590220">Sembunyikan lanjutan</translation>
<translation id="3467763166455606212">Diperlukan nama pemegang kartu</translation>
<translation id="3478058380795961209">Bulan Masa Berlaku Habis</translation>
<translation id="3479539252931486093">Apakah hal ini tidak diharapkan? <ph name="BEGIN_LINK" />Beri tahu kami<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Jangan sekarang</translation>
-<translation id="348000606199325318">ID Kerusakan <ph name="CRASH_LOCAL_ID" /> (ID Server: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Orang tua Anda saat ini tidak dapat dihubungi. Coba lagi.</translation>
<translation id="3528171143076753409">Sertifikat server tidak dipercaya.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Minimal 1 item pada perangkat yang disinkronkan}=1{1 item (dan beberapa di perangkat yang disinkronkan)}other{# item (dan beberapa di perangkat yang disinkronkan)}}</translation>
<translation id="3539171420378717834">Menyimpan salinan kartu ini di perangkat ini</translation>
<translation id="3542684924769048008">Gunakan sandi untuk:</translation>
+<translation id="3545341443414427877">Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat diterapkan karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) komputer Anda tidak tepat. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Enkripsikan data yang disinkronkan dengan frasa sandi sinkronisasi Anda</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> lainnya...</translation>
-<translation id="3555561725129903880">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya berasal dari <ph name="DOMAIN2" />. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Pengelola dapat membuka blokirnya untuk Anda</translation>
<translation id="3566021033012934673">Koneksi Anda tidak pribadi</translation>
+<translation id="3569145463236695319">&lt;p&gt;Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat diterapkan karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) perangkat tidak tepat.&lt;/p&gt;
+
+ &lt;p&gt;Harap sesuaikan tanggal dan waktu di bagian &lt;strong&gt;Umum&lt;/strong&gt; pada aplikasi &lt;strong&gt;Setelan&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Tambahkan nama</translation>
<translation id="3583757800736429874">&amp;Ulangi Pemindahan</translation>
<translation id="3586931643579894722">Sembunyikan detail</translation>
-<translation id="3587482841069643663">Semua</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Masukkan tanggal masa berlaku yang valid</translation>
<translation id="36224234498066874">Hapus Data Browsing...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informasi sertifikat</translation>
<translation id="3690164694835360974">Proses masuk tidak aman</translation>
<translation id="3693415264595406141">Sandi:</translation>
-<translation id="3696411085566228381">tidak ada</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Memuat...</translation>
<translation id="3712624925041724820">Lisensi habis</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Periksa proxy, firewall, dan konfigurasi DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Jika Anda memahami risiko terhadap keamanan, Anda dapat <ph name="BEGIN_LINK" />mengunjungi situs tidak aman ini<ph name="END_LINK" /> sebelum program berbahaya tersebut dibuang.</translation>
<translation id="3739623965217189342">Tautan yang Anda salin</translation>
+<translation id="3744899669254331632">Anda tidak dapat mengunjungi <ph name="SITE" /> sekarang karena situs web mengirim kredensial tak beraturan yang tidak dapat diproses Chromium. Kesalahan jaringan dan serangan biasanya bersifat sementara, sehingga laman ini mungkin akan bekerja nanti.</translation>
+<translation id="3748148204939282805">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> dapat mengelabui Anda agar melakukan tindakan yang berbahaya seperti menginstal software atau mengungkap informasi pribadi Anda (misalnya sandi, nomor telepon, atau kartu kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Terjemahan gagal karena kesalahan server.</translation>
<translation id="3759461132968374835">Tidak ada laporan kondisi ngadat saat ini. Kondisi ngadat yang terjadi saat pelaporan kondisi ngadat tidak diaktifkan tidak akan tampil di sini.</translation>
+<translation id="3778403066972421603">Ingin menyimpan kartu ini di Akun Google dan perangkat ini?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Masa berlaku <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Jika Anda menggunakan server proxy...</translation>
<translation id="3828924085048779000">Frasa sandi kosong tidak dibolehkan.</translation>
-<translation id="3845539888601087042">Menampilkan riwayat dari perangkat yang Anda gunakan untuk masuk. <ph name="BEGIN_LINK" />Pelajari lebih lanjut<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Mundur</translation>
<translation id="3858027520442213535">Perbarui tanggal dan waktu</translation>
<translation id="3884278016824448484">Pengenal perangkat bertentangan</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Permintaan Anda untuk mengakses situs ini telah dikirim ke <ph name="NAME" /></translation>
<translation id="3890664840433101773">Tambahkan email</translation>
<translation id="3901925938762663762">Kartu telah habis masa berlakunya</translation>
-<translation id="3933571093587347751">{1,plural, =1{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya sepertinya dari esok hari. Hal ini dapat disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}other{Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya sepertinya dari # hari mendatang. Hal ini dapat disebabkan oleh kesalahan konfigurasi, atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Gagal memuat dokumen PDF</translation>
+<translation id="3945915738023014686">ID Laporan Error yang Diupload <ph name="CRASH_ID" /> (ID Error Lokal: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak menyebutkan Nama Alternatif Subjek. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
<translation id="3963721102035795474">Mode Pembaca</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Tidak ada}=1{Dari 1 situs }other{Dari # situs }}</translation>
<translation id="397105322502079400">Menghitung...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> diblokir.</translation>
+<translation id="3987940399970879459">Kurang dari 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 laman web di sekitar}other{# laman web di sekitar}}</translation>
<translation id="4021036232240155012">DNS adalah layanan jaringan yang menerjemahkan nama situs web ke alamat Internet-nya.</translation>
<translation id="4030383055268325496">&amp;Urungkan penambahan</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Konfigurasi proxy disetel untuk menggunakan URL skrip .pac, bukan server proxy yang tetap.</translation>
<translation id="4098354747657067197">Situs yang akan dibuka berisi penipuan</translation>
<translation id="4103249731201008433">Nomor seri perangkat tidak valid</translation>
+<translation id="410351446219883937">Putar otomatis</translation>
<translation id="4103763322291513355">Kunjungi &lt;strong&gt;chrome://policy&lt;/strong&gt; untuk melihat daftar URL yang masuk daftar hitam dan kebijakan lain yang diterapkan oleh administrator sistem Anda.</translation>
-<translation id="4110615724604346410">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya berisi berbagai kesalahan. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Selalu izinkan di situs ini</translation>
<translation id="4117700440116928470">Lingkup kebijakan tidak didukung.</translation>
-<translation id="4118212371799607889">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh Chromium. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 lainnya}other{# lainnya}}</translation>
<translation id="4130226655945681476">Periksa kabel jaringan, modem, dan router</translation>
+<translation id="413544239732274901">Pelajari lebih lanjut</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Gunakan default global (Deteksi)</translation>
+<translation id="4165986682804962316">Setelan situs</translation>
<translation id="4169947484918424451">Ingin Chromium menyimpan kartu ini?</translation>
<translation id="4171400957073367226">Tanda tangan verifikasi tidak valid</translation>
<translation id="4196861286325780578">&amp;Ulangi pemindahan</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Periksa konfigurasi antivirus dan firewall<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{tidak ada}=1{1 aplikasi ($1)}=2{2 aplikasi ($1, $2)}other{# aplikasi ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Kerusakan</translation>
+<translation id="422022731706691852">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> dapat mengelabui Anda agar menginstal program yang membahayakan pengalaman browsing Anda (misalnya, dengan mengubah halaman beranda atau menampilkan iklan tambahan di situs yang dikunjungi). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Coba jalankan Diagnostik Jaringan<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Valid</translation>
<translation id="4250431568374086873">Sambungan ke situs ini tidak sepenuhnya aman</translation>
<translation id="4250680216510889253">Tidak</translation>
<translation id="425582637250725228">Perubahan yang Anda lakukan mungkin tidak disimpan.</translation>
<translation id="4258748452823770588">Tanda tangan salah</translation>
+<translation id="4265872034478892965">Diizinkan oleh administrator</translation>
<translation id="4269787794583293679">(Tidak ada nama pengguna)</translation>
<translation id="4275830172053184480">Mulai ulang perangkat Anda</translation>
<translation id="4280429058323657511">, kedaluwarsa <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google Penjelajahan Aman baru-baru ini <ph name="BEGIN_LINK" />menemukan program berbahaya<ph name="END_LINK" /> di <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Saran induk</translation>
<translation id="4304224509867189079">Log In</translation>
-<translation id="432290197980158659">Server menunjukkan sertifikat yang tidak sesuai dengan perkiraan yang ada. Perkiraan ini disertakan untuk situs web tertentu dengan keamanan tingkat tinggi untuk melindungi Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blokir (default)</translation>
<translation id="4325863107915753736">Gagal menemukan artikel</translation>
<translation id="4326324639298822553">Periksa tanggal kedaluwarsa dan coba lagi</translation>
<translation id="4331708818696583467">Tidak Aman</translation>
<translation id="4356973930735388585">Penyerang di situs ini mungkin berusaha memasang program berbahaya di komputer Anda yang dapat mencuri atau menghapus informasi (misalnya, foto, sandi, pesan, dan kartu kredit).</translation>
<translation id="4372948949327679948">Nilai <ph name="VALUE_TYPE" /> yang diharapkan.</translation>
+<translation id="4377125064752653719">Anda berusaha menjangkau <ph name="DOMAIN" />, tetapi sertifikat yang disajikan oleh server telah dibatalkan oleh penerbitnya. Artinya informasi rahasia keamanan yang disajikan tidak dapat dipercaya. Anda mungkin sedang berkomunikasi dengan penyerang.</translation>
<translation id="4381091992796011497">Nama Pengguna:</translation>
<translation id="4394049700291259645">Nonaktifkan</translation>
<translation id="4406896451731180161">hasil penelusuran</translation>
+<translation id="4424024547088906515">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh Chrome. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> tidak menerima sertifikat masuk Anda, atau sertifikat masuk mungkin tidak diberikan.</translation>
<translation id="443673843213245140">Penggunaan proxy dinonaktifkan tetapi konfigurasi proxy yang eksplisit ditentukan.</translation>
-<translation id="4492190037599258964">Telusuri hasil untuk '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Kesalahan validasi: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Hubungi admin sistem</translation>
<translation id="450710068430902550">Berbagi dengan Administrator</translation>
<translation id="4515275063822566619">Kartu dan alamat berasal dari Chrome dan Akun Google (<ph name="ACCOUNT_EMAIL" />). Anda dapat mengelolanya di <ph name="BEGIN_LINK" />Setelan<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detail</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Coba nonaktifkan ekstensi.</translation>
<translation id="457875822857220463">Pengiriman</translation>
<translation id="4587425331216688090">Hapus alamat dari Chrome?</translation>
-<translation id="4589078953350245614">Anda berusaha menjangkau <ph name="DOMAIN" />, tetapi server menunjukkan sertifikat yang tidak valid. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Sambungan Anda ke <ph name="DOMAIN" /> dienkripsi menggunakan cipher suite modern.</translation>
<translation id="4594403342090139922">&amp;Urungkan Penghapusan</translation>
<translation id="4619615317237390068">Tab dari perangkat lain</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya berisi kesalahan. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
+<translation id="4690462567478992370">Berhenti menggunakan sertifikat yang tidak valid</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Sambungan Anda terganggu</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Jalankan Diagnostik Jaringan Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Terjadi kesalahan yang tidak diketahui.</translation>
<translation id="4800132727771399293">Periksa tanggal masa berlaku habis dan CVC, lalu coba lagi</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Saat ini Anda tidak dapat mengunjungi <ph name="SITE" /> karena situs web tersebut mengirim kredensial acak yang tidak dapat diproses oleh Google Chrome. Kesalahan jaringan dan serangan biasanya bersifat sementara, jadi laman ini mungkin akan bekerja nanti.</translation>
<translation id="4813512666221746211">Kesalahan jaringan</translation>
<translation id="4816492930507672669">Paskan dengan halaman</translation>
<translation id="483020001682031208">Tidak ada halaman Web Fisik untuk ditampilkan</translation>
<translation id="4850886885716139402">Lihat</translation>
<translation id="4854362297993841467">Metode pengiriman tidak tersedia. Coba metode lain.</translation>
<translation id="4858792381671956233">Kamu telah meminta izin kepada orang tua untuk mengunjungi situs ini</translation>
+<translation id="4863764087567530506">Konten ini mungkin mencoba mengelabui Anda agar menginstal software atau mengungkap informasi pribadi. <ph name="BEGIN_LINK" />Tampilkan saja<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Telusuri riwayat</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{dan 1 laman web lainnya}other{dan # laman web lainnya}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Laman ini telah diterjemahkan dari bahasa yang tidak diketahui ke bahasa <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pembayaran</translation>
<translation id="4926049483395192435">Harus ditentukan.</translation>
<translation id="495170559598752135">Tindakan</translation>
<translation id="4958444002117714549">Luaskan daftar</translation>
-<translation id="4962322354953122629">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh Chrome. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Aktifkan kembali peringatan</translation>
<translation id="4989809363548539747">Plugin ini tidak didukung</translation>
<translation id="5002932099480077015">Jika diaktifkan, Chrome akan menyimpan salinan kartu Anda di perangkat ini untuk pengisian formulir yang lebih cepat.</translation>
<translation id="5018422839182700155">Tidak dapat membuka halaman ini</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Periksa kebijakan administrator Anda</translation>
<translation id="5029568752722684782">Hapus salinan</translation>
<translation id="5031870354684148875">Tentang Google Terjemahan</translation>
+<translation id="5039804452771397117">Izinkan</translation>
<translation id="5040262127954254034">Privasi</translation>
<translation id="5045550434625856497">Sandi salah</translation>
<translation id="5056549851600133418">Artikel untuk Anda</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Periksa alamat proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Tak ada cookie}=1{1 situs menggunakan cookie. }other{# situs menggunakan cookie. }}</translation>
<translation id="5087286274860437796">Sertifikat server saat ini tidak valid.</translation>
<translation id="5087580092889165836">Tambahkan kartu</translation>
<translation id="5089810972385038852">Negara bagian</translation>
+<translation id="5094747076828555589">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh Chromium. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
<translation id="5095208057601539847">Provinsi</translation>
<translation id="5115563688576182185">(64 bit)</translation>
<translation id="5141240743006678641">Enkripsikan sandi yang disinkronkan dengan kredensial Google Anda</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Email wajib diisi</translation>
<translation id="5251803541071282808">Awan</translation>
<translation id="5277279256032773186">Menggunakan Chrome di kantor? Perusahaan dapat mengelola setelan Chrome untuk karyawan mereka. Pelajari lebih lanjut</translation>
+<translation id="5297526204711817721">Sambungan Anda ke situs ini tidak bersifat pribadi. Untuk keluar dari mode VR setiap saat, copot headset dan tekan kembali.</translation>
<translation id="5299298092464848405">Kebijakan kesalahan penguraian</translation>
-<translation id="5300589172476337783">Tampilkan</translation>
<translation id="5308689395849655368">Pelaporan kondisi ngadat dinonaktifkan.</translation>
<translation id="5317780077021120954">Simpan</translation>
<translation id="5327248766486351172">Nama</translation>
-<translation id="5337705430875057403">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> dapat mengelabui Anda agar melakukan hal berbahaya seperti memasang software atau mengungkap informasi pribadi Anda (misalnya, sandi, nomor telepon, atau kartu kredit).</translation>
-<translation id="5359637492792381994">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak valid untuk saat ini. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Anda tidak dapat membuka <ph name="SITE" /> sekarang karena sertifikatnya telah dicabut. Error jaringan dan serangan biasanya bersifat sementara, sehingga halaman ini mungkin akan berfungsi nanti.</translation>
<translation id="536296301121032821">Gagal menyimpan setelan kebijakan</translation>
<translation id="5386426401304769735">Rantai sertifikat untuk situs ini berisi sertifikat yang ditandatangani menggunakan SHA-1.</translation>
<translation id="5402410679244714488">Kedaluwarsa: <ph name="EXPIRATION_DATE_ABBR" />, terakhir digunakan lebih dari setahun yang lalu</translation>
+<translation id="540969355065856584">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya saat ini tidak valid. Hal ini mungkin disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mengganggu sambungan internet Anda.</translation>
<translation id="5421136146218899937">Hapus data browsing...</translation>
<translation id="5430298929874300616">Buang bookmark</translation>
<translation id="5431657950005405462">File Anda tidak ditemukan</translation>
-<translation id="5435775191620395718">Menampilkan riwayat dari perangkat ini. <ph name="BEGIN_LINK" />Pelajari lebih lanjut<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Kesalahan validasi skema di "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Laman <ph name="HOST_NAME" /> ini tidak dapat ditemukan</translation>
<translation id="5455374756549232013">Stempel waktu kebijakan salah</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> dari <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Tidak valid</translation>
<translation id="5470861586879999274">&amp;Ulangi pengeditan</translation>
<translation id="54817484435770891">Tambahkan alamat yang valid</translation>
<translation id="5492298309214877701">Situs yang ada di intranet perusahaan, organisasi, atau sekolah ini memiliki URL yang sama dengan situs web eksternal.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Tidak dapat mengambil dari alamat ini. Pilih alamat lain.</translation>
<translation id="5572851009514199876">Mulai dan login ke Chrome agar Chrome dapat memeriksa apakah Anda diizinkan untuk mengakses situs ini atau tidak.</translation>
<translation id="5580958916614886209">Periksa bulan kedaluwarsa dan coba lagi</translation>
+<translation id="5586446728396275693">Tidak ada alamat yang disimpan</translation>
+<translation id="5595485650161345191">Edit alamat</translation>
<translation id="560412284261940334">Pengelolaan tidak didukung</translation>
<translation id="5610142619324316209">Periksa sambungan</translation>
<translation id="5610807607761827392">Anda dapat mengelola kartu dan alamat di <ph name="BEGIN_LINK" />Setelan<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Ingin keluar dari situs ini?</translation>
<translation id="5629630648637658800">Gagal memuat setelan kebijakan</translation>
<translation id="5631439013527180824">Token pengelolaan perangkat tidak valid</translation>
+<translation id="5633066919399395251">Saat ini, penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin berusaha menginstal program berbahaya di komputer Anda yang dapat mencuri atau menghapus informasi Anda (misalnya, foto, sandi, pesan, dan kartu kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Lokasi</translation>
+<translation id="5659593005791499971">Email</translation>
<translation id="5669703222995421982">Mendapatkan konten hasil personalisasi</translation>
<translation id="5675650730144413517">Halaman ini tidak berfungsi</translation>
-<translation id="5677928146339483299">Dicekal</translation>
-<translation id="5694783966845939798">Anda berusaha menjangkau <ph name="DOMAIN" />, tetapi server menunjukkan sertifikat yang ditandatangani menggunakan algoritme tanda tangan yang lemah (seperti SHA-1). Artinya, kredensial keamanan yang ditunjukkan server mungkin telah dipalsukan, dan server tersebut mungkin bukan server yang diharapkan (Anda mungkin sedang berkomunikasi dengan penyerang). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Identitas situs Web ini belum diverifikasi.</translation>
+<translation id="5713016350996637505">Konten penipuan diblokir</translation>
<translation id="5720705177508910913">Pengguna saat ini</translation>
<translation id="5732392974455271431">Orang tua dapat membuka blokirnya untukmu</translation>
<translation id="5763042198335101085">Masukkan alamat email yang valid</translation>
<translation id="5765072501007116331">Untuk melihat persyaratan dan metode pengiriman, pilih alamat</translation>
+<translation id="5778550464785688721">Kontrol penuh perangkat MIDI</translation>
<translation id="5784606427469807560">Terjadi masalah saat mengonfirmasi kartu. Periksa sambungan internet Anda dan coba lagi.</translation>
<translation id="5785756445106461925">Selain itu, laman ini berisi sumber daya lainnya yang tidak aman. Sumber daya ini dapat dilihat oleh orang lain saat transit dan dapat dimodifikasi oleh penyerang untuk mengubah tampilan perangkat.</translation>
<translation id="5786044859038896871">Ingin mengisi informasi kartu?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Ulangi Penambahan</translation>
<translation id="5814352347845180253">Anda dapat kehilangan akses ke konten premium dari <ph name="SITE" /> dan beberapa situs lain.</translation>
<translation id="5838278095973806738">Jangan masukkan informasi sensitif apa pun di situs ini (misalnya, sandi atau kartu kredit), karena penyerang dapat mencurinya.</translation>
-<translation id="5843436854350372569">Anda mencoba menjangkau <ph name="DOMAIN" />, tetapi server menunjukkan sertifikat yang berisi kunci lemah. Penyerang mungkin telah merusak kunci pribadi dan server tersebut mungkin bukan server yang diharapkan (Anda mungkin sedang berkomunikasi dengan penyerang). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Situs ini tidak dapat dijangkau</translation>
<translation id="5869522115854928033">Sandi tersimpan</translation>
<translation id="5872918882028971132">Saran Induk</translation>
<translation id="5901630391730855834">Kuning</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (disinkronkan)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 terpakai}other{# terpakai}}</translation>
<translation id="5926846154125914413">Anda dapat kehilangan akses ke konten premium dari beberapa situs.</translation>
<translation id="5959728338436674663">Kirim beberapa <ph name="BEGIN_WHITEPAPER_LINK" />informasi sistem dan konten halaman<ph name="END_WHITEPAPER_LINK" /> secara otomatis ke Google untuk membantu mendeteksi aplikasi dan situs berbahaya. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Minggu</translation>
<translation id="5967867314010545767">Hapus dari riwayat</translation>
<translation id="5975083100439434680">Perkecil</translation>
<translation id="598637245381783098">Tidak dapat membuka aplikasi pembayaran</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Halaman 1}other{Halaman #}}</translation>
<translation id="6017514345406065928">Hijau</translation>
+<translation id="6017850046339264347">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> dapat menginstal aplikasi penipuan dengan berpura-pura menjadi sesuatu yang lain atau mengumpulkan data yang dapat digunakan untuk melacak Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (disinkronkan)</translation>
<translation id="6027201098523975773">Masukkan nama</translation>
<translation id="6040143037577758943">Tutup</translation>
<translation id="6042308850641462728">Lainnya</translation>
+<translation id="6047233362582046994">Jika Anda memahami risiko keamanan tersebut, Anda dapat <ph name="BEGIN_LINK" />mengunjungi situs ini<ph name="END_LINK" /> sebelum aplikasi berbahaya tersebut dihapus.</translation>
+<translation id="6051221802930200923">Anda tidak dapat membuka <ph name="SITE" /> sekarang karena situs menggunakan penyematan sertifikat. Error jaringan dan serangan biasanya bersifat sementara, sehingga halaman ini mungkin akan berfungsi nanti.</translation>
<translation id="6060685159320643512">Hati-hati, eksperimen ini dapat menimbulkan masalah</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{tidak ada}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Anda telah mengakses konten menggunakan sertifikat yang diberikan oleh administrator. Data yang diberikan ke <ph name="DOMAIN" /> dapat dicegat oleh administrator Anda.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Tidak ada}=1{1 sandi (disinkronkan)}other{# sandi (disinkronkan)}}</translation>
<translation id="6146055958333702838">Periksa semua kabel dan boot ulang router, modem, atau perangkat
jaringan lain yang mungkin Anda gunakan.</translation>
<translation id="614940544461990577">Coba:</translation>
<translation id="6151417162996330722">Sertifikat server memiliki masa berlaku yang terlalu panjang.</translation>
<translation id="6157877588268064908">Untuk melihat persyaratan dan metode pengiriman, pilih alamat</translation>
+<translation id="6158003235852588289">Google Safe Browsing baru-baru ini mendeteksi phishing di <ph name="SITE" />. Situs phishing berpura-pura menjadi situs lain untuk mengelabui Anda.</translation>
<translation id="6165508094623778733">Pelajari lebih lanjut</translation>
+<translation id="6169916984152623906">Anda kini dapat mengakses secara rahasia, dan orang lain yang menggunakan perangkat ini tidak akan melihat aktivitas Anda. Namun, hasil download dan bookmark akan disimpan.</translation>
<translation id="6177128806592000436">Sambungan Anda ke situs ini tidak aman</translation>
<translation id="6184817833369986695">(kelompok: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Periksa sambungan internet Anda</translation>
<translation id="6218753634732582820">Hapus alamat dari Chromium?</translation>
+<translation id="6221345481584921695">Google Safe Browsing baru saja <ph name="BEGIN_LINK" />mendeteksi software perusak<ph name="END_LINK" /> di <ph name="SITE" />. Situs web yang biasanya aman terkadang terinfeksi software perusak. Konten berbahaya datang dari <ph name="SUBRESOURCE_HOST" />, yang dikenal luas sebagai distributor software perusak.</translation>
<translation id="6251924700383757765">Kebijakan privasi</translation>
<translation id="6254436959401408446">Tidak cukup memori untuk membuka halaman ini</translation>
<translation id="625755898061068298">Anda telah memilih untuk menonaktifkan peringatan keamanan untuk situs ini.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Edit bookmark</translation>
<translation id="6410264514553301377">Masukkan tanggal kedaluwarsa dan CVC <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Kamu telah meminta izin kepada orang tua untuk mengunjungi situs ini</translation>
-<translation id="6416403317709441254">Saat ini, Anda tidak dapat mengunjungi <ph name="SITE" /> karena situs web ini mengirimkan kredensial acak yang tidak dapat diproses oleh Chromium. Kesalahan dan serangan jaringan biasanya bersifat sementara, jadi laman ini mungkin akan bekerja nanti. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Tidak dapat memeriksa apakah sertifikat telah ditarik.</translation>
<translation id="6433490469411711332">Edit info kontak</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> menolak untuk tersambung.</translation>
<translation id="6446608382365791566">Tambahkan informasi lainnya</translation>
+<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">Konfirmasikan Pengiriman Ulang Formulir</translation>
<translation id="6456339708790392414">Pembayaran Anda</translation>
<translation id="6458467102616083041">Diabaikan karena penelusuran default dinonaktifkan oleh kebijakan.</translation>
-<translation id="6462969404041126431">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya mungkin sudah dicabut. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Kebijakan perangkat</translation>
<translation id="6477321094435799029">Chrome mendeteksi kode yang tidak biasa pada halaman ini dan memblokirnya untuk melindungi informasi pribadi Anda (misalnya, sandi, nomor telepon, dan kartu kredit).</translation>
<translation id="6489534406876378309">Mulai mengupload kerusakan</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Habis masa berlaku: <ph name="EXPIRATION_DATE_ABBR" />, terakhir digunakan pada <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Pengelola Anda belum menyetujuinya</translation>
<translation id="6569060085658103619">Anda melihat halaman ekstensi</translation>
-<translation id="6593753688552673085">kurang dari <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Konten ini mungkin mencoba menginstal software berbahaya di perangkat yang mencuri atau menghapus informasi Anda. <ph name="BEGIN_LINK" />Tampilkan saja<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opsi enkripsi</translation>
<translation id="662080504995468778">Tinggal</translation>
<translation id="6626291197371920147">Tambahkan kartu yang valid</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Penelusuran</translation>
+<translation id="6630809736994426279">Saat ini, penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin berusaha menginstal program berbahaya di Mac Anda yang dapat mencuri atau menghapus informasi Anda (misalnya, foto, sandi, pesan, dan kartu kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Kebijakan ini telah usang.</translation>
-<translation id="6652240803263749613">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh sistem operasi komputer. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Hapus saran formulir dari Chromium?</translation>
<translation id="6685834062052613830">Keluar dan selesaikan penyiapan</translation>
<translation id="6710213216561001401">Sebelumnya</translation>
<translation id="6710594484020273272">&lt;Ketik istilah penelusuran&gt;</translation>
<translation id="6711464428925977395">Ada yang salah dengan server proxy, atau alamat tidak benar.</translation>
<translation id="6727102863431372879">Setel</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{tidak ada}=1{1 item}other{# item}}</translation>
<translation id="674375294223700098">Kesalahan sertifikat server tidak dikenal.</translation>
<translation id="6753269504797312559">Nilai kebijakan</translation>
<translation id="6757797048963528358">Perangkat Anda sedang dalam mode tidur.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ID Penyesuaian</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Gagal memuat data region</translation>
+<translation id="6825578344716086703">Anda berusaha menjangkau <ph name="DOMAIN" />, tetapi server menyajikan sertifikat yang ditandatangani menggunakan algoritme tanda tangan yang lemah (seperti SHA-1). Hal ini berarti kredensial keamanan yang disajikan server mungkin telah dipalsukan, dan server tersebut mungkin bukan yang diharapkan (Anda mungkin sedang berkomunikasi dengan penyerang).</translation>
+<translation id="6830728435402077660">Tidak aman</translation>
<translation id="6831043979455480757">Terjemahkan</translation>
<translation id="6839929833149231406">Area</translation>
<translation id="6874604403660855544">&amp;Ulangi penambahan</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Kartu telah dikonfirmasi</translation>
<translation id="6897140037006041989">Agen Pengguna</translation>
<translation id="6915804003454593391">Pengguna:</translation>
+<translation id="6945221475159498467">Pilih</translation>
<translation id="6948701128805548767">Untuk melihat persyaratan dan metode pengambilan, pilih alamat</translation>
<translation id="6957887021205513506">Sertifikat server tampaknya palsu.</translation>
<translation id="6965382102122355670">Oke</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Server proxy tetap dan URL skrip .pac telah ditentukan.</translation>
<translation id="6989763994942163495">Tampilkan setelan lanjutan...</translation>
<translation id="7000990526846637657">Entri riwayat tidak ditemukan</translation>
-<translation id="7009986207543992532">Anda berusaha menjangkau <ph name="DOMAIN" />, tetapi server menunjukkan sertifikat yang masa berlakunya terlalu lama untuk dapat dipercaya. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Akun Google Anda mungkin memiliki bentuk riwayat penjelajahan lainnya di <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Sandi</translation>
+<translation id="7050187094878475250">Anda berusaha menjangkau <ph name="DOMAIN" />, namun server memberikan sertifikat yang masa berlakunya terlalu lama untuk dapat dipercaya.</translation>
+<translation id="7053983685419859001">Blokir</translation>
<translation id="7064851114919012435">Info kontak</translation>
<translation id="7079718277001814089">Situs ini berisi malware</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7088615885725309056">Lawas</translation>
<translation id="7090678807593890770">Telusuri <ph name="LINK" /> di Google</translation>
+<translation id="7108819624672055576">Diizinkan oleh ekstensi</translation>
<translation id="7119414471315195487">Tutup tab atau program lain</translation>
<translation id="7129409597930077180">Tidak dapat mengirim ke alamat ini. Pilih alamat lain.</translation>
<translation id="7138472120740807366">Metode pengiriman</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Dalam proses</translation>
<translation id="724691107663265825">Situs yang akan dibuka berisi software perusak</translation>
<translation id="724975217298816891">Masukkan tanggal habis masa berlaku dan CVC untuk <ph name="CREDIT_CARD" /> guna memperbarui detail kartu. Setelah mengonfirmasi, detail kartu Anda akan dibagikan dengan situs ini.</translation>
-<translation id="725866823122871198">Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat dibuat karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) komputer Anda tidak benar.</translation>
+<translation id="7260504762447901703">Cabut akses</translation>
<translation id="7275334191706090484">Bookmark yang Terkelola</translation>
<translation id="7298195798382681320">Direkomendasikan</translation>
<translation id="7309308571273880165">Laporan kerusakan diambil pada <ph name="CRASH_TIME" /> (upload yang diminta pengguna, belum diupload)</translation>
<translation id="7334320624316649418">&amp;Ulangi pengaturan ulang</translation>
<translation id="733923710415886693">Sertifikat server tidak diungkapkan melalui Transparansi Sertifikat.</translation>
-<translation id="7351800657706554155">Saat ini, Anda tidak dapat mengunjungi <ph name="SITE" /> karena sertifikatnya telah dicabut. Kesalahan dan serangan jaringan biasanya bersifat sementara, jadi laman ini mungkin akan berfungsi nanti. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Baris Perintah</translation>
<translation id="7372973238305370288">hasil penelusuran</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Tidak</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Konfirmasi Kartu</translation>
-<translation id="7394102162464064926">Yakin ingin menghapus laman ini dari riwayat Anda?
-
-Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nanti.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Jalur Profil</translation>
<translation id="7424977062513257142">Laman tersemat di laman web ini menyatakan:</translation>
@@ -688,6 +754,7 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="7444046173054089907">Situs ini diblokir</translation>
<translation id="7445762425076701745">Identitas server yang Anda sambungkan tidak dapat divalidasi sepenuhnya. Anda terhubung ke server menggunakan nama yang hanya valid dalam jaringan Anda, yang mana otoritas sertifikat eksternal sama sekali tidak dapat memvalidasi kepemilikannya. Karena sejumlah otoritas sertifikat akan tetap menerbitkan sertifikat untuk nama tersebut, tidak dapat dipastikan apakah Anda akan tersambung ke situs web yang dimaksudkan dan bahwa tidak akan ada penyerang.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Pelajari lebih lanjut<ph name="END_LINK" /> tentang masalah ini.</translation>
+<translation id="7455133967321480974">Gunakan default global (Cekal)</translation>
<translation id="7460163899615895653">Tab terbaru dari perangkat lain muncul di sini</translation>
<translation id="7469372306589899959">Mengonfirmasi kartu</translation>
<translation id="7481312909269577407">Maju</translation>
@@ -695,36 +762,43 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="7508255263130623398">ID perangkat kebijakan yang dikembalikan kosong atau tidak cocok dengan ID perangkat saat ini</translation>
<translation id="7514365320538308">Download</translation>
<translation id="7518003948725431193">Tidak ada laman web yang ditemukan untuk alamat web:<ph name="URL" /></translation>
+<translation id="7521387064766892559">Javascript</translation>
<translation id="7535087603100972091">Nilai</translation>
<translation id="7537536606612762813">Wajib</translation>
+<translation id="7542403920425041731">Setelah mengonfirmasi, detail kartu Anda akan dibagikan dengan situs ini.</translation>
<translation id="7542995811387359312">Pengisian kartu kredit otomatis dinonaktifkan karena formulir ini tidak menggunakan sambungan aman.</translation>
<translation id="7543525346216957623">Tanyakan kepada orang tua</translation>
<translation id="7549584377607005141">Laman web ini membutuhkan data yang Anda masukkan sebelumnya agar dapat ditampilkan dengan benar. Anda dapat mengirimkan data ini lagi, namun dengan begitu Anda akan mengulangi tindakan apa pun yang sebelumnya dilakukan oleh laman ini.</translation>
<translation id="7552846755917812628">Coba tips berikut:</translation>
<translation id="7554791636758816595">Tab Baru</translation>
+<translation id="7567204685887185387">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya mungkin telah dikeluarkan dengan curang. Hal ini disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> kontak lainnya}other{<ph name="CONTACT_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> kontak lainnya}}</translation>
<translation id="7568593326407688803">Laman ini dalam bahasa<ph name="ORIGINAL_LANGUAGE" />Ingin diterjemahkan?</translation>
<translation id="7569952961197462199">Hapus kartu kredit dari Chrome?</translation>
<translation id="7569983096843329377">Hitam</translation>
<translation id="7578104083680115302">Bayar di situs dan aplikasi di semua perangkat dengan cepat menggunakan kartu yang disimpan dengan Google.</translation>
<translation id="7588950540487816470">Web Fisik</translation>
<translation id="7592362899630581445">Sertifikat server melanggar batasan nama.</translation>
+<translation id="7598391785903975535">Kurang dari <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> saat ini tidak dapat menangani permintaan ini.</translation>
<translation id="7600965453749440009">Jangan pernah terjemahkan bahasa <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Nilai di luar jangkauan <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Masa berlaku habis: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Anda sudah memiliki data yang dienkripsi menggunakan versi sandi Akun Google yang berbeda. Masukkan sandi di bawah.</translation>
-<translation id="7634554953375732414">Sambungan Anda ke situs ini tidak bersifat pribadi.</translation>
<translation id="7637571805876720304">Hapus kartu kredit dari Chromium?</translation>
<translation id="765676359832457558">Sembunyikan setelan lanjutan...</translation>
<translation id="7658239707568436148">Batal</translation>
+<translation id="7662298039739062396">Setelan yang dikontrol oleh ekstensi</translation>
<translation id="7667346355482952095">Token kebijakan yang dikembalikan kosong atau tidak cocok dengan token saat ini</translation>
<translation id="7668654391829183341">Perangkat tidak dikenal</translation>
<translation id="7669271284792375604">Penyerang di situs ini mungkin berusaha mengelabui Anda agar memasang program yang dapat membahayakan pengalaman menjelajah Anda (misalnya dengan mengubah beranda Anda atau menayangkan iklan ekstra pada situs yang dikunjungi).</translation>
<translation id="7674629440242451245">Tertarik dengan fitur Chrome baru yang keren? Coba saluran dev kami di chrome.com/dev.</translation>
<translation id="7682287625158474539">Pengiriman</translation>
+<translation id="7701040980221191251">Tidak ada</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Lanjutkan ke <ph name="SITE" /> (tidak aman)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Sertifikat</translation>
+<translation id="7716147886133743102">Diblokir oleh administrator</translation>
<translation id="7716424297397655342">Situs ini tidak dapat dimuat dari cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Tidak terkelola</translation>
<translation id="7755287808199759310">Orang tua dapat membuka blokirnya untukmu</translation>
<translation id="7758069387465995638">Software antivirus atau firewall mungkin memblokir sambungan.</translation>
@@ -751,15 +825,15 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="7951415247503192394">(32 bit)</translation>
<translation id="7956713633345437162">Bookmark seluler</translation>
<translation id="7961015016161918242">Jangan pernah</translation>
-<translation id="7962083544045318153">ID Kerusakan <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Selalu terjemahkan <ph name="ORIGINAL_LANGUAGE" /> ke <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Tidak Ditentukan</translation>
<translation id="800218591365569300">Coba tutup tab atau program lain untuk mengosongkan memori.</translation>
<translation id="8012647001091218357">Orang tua Anda saat ini tidak dapat dihubungi. Coba lagi.</translation>
<translation id="8025119109950072390">Penyerang di situs ini dapat mengelabui Anda agar melakukan hal yang berbahaya seperti memasang software atau mengungkap informasi pribadi Anda (misalnya sandi, nomor telepon, atau kartu kredit).</translation>
-<translation id="803030522067524905">Google Penjelajahan Aman baru-baru ini mendeteksi aktivitas phishing di <ph name="SITE" />. Situs phishing berpura-pura menjadi situs lain untuk menipu Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Laman ini berbahasa <ph name="SOURCE_LANGUAGE" />. Terjemahkan ke <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Tanyakan (default)</translation>
<translation id="8041089156583427627">Kirim Masukan</translation>
+<translation id="8041940743680923270">Gunakan default global (Tanyakan)</translation>
<translation id="8088680233425245692">Gagal melihat artikel.</translation>
<translation id="8089520772729574115">kurang dari 1 MB</translation>
<translation id="8091372947890762290">Aktivasi ditunda di server</translation>
@@ -768,13 +842,14 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />Alamat DNS<ph name="END_ABBR" /> server <ph name="HOST_NAME" /> tidak dapat ditemukan.</translation>
<translation id="8149426793427495338">Komputer Anda sedang dalam mode tidur.</translation>
<translation id="8150722005171944719">File pada <ph name="URL" /> tidak dapat dibaca. File mungkin telah dihapus, dipindahkan, atau izin file mungkin mencegah akses.</translation>
+<translation id="8184538546369750125">Gunakan default global (Izinkan)</translation>
+<translation id="8191494405820426728">ID Error Lokal <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Urungkan Pemindahan</translation>
<translation id="8201077131113104583">URL pembaruan tidak valid untuk ekstensi dengan ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Ringkasan pesanan</translation>
<translation id="8218327578424803826">Lokasi yang Ditetapkan:</translation>
<translation id="8225771182978767009">Orang yang menyiapkan komputer ini telah memilih untuk memblokir situs ini.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Saat ini penyerang yang berada pada <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin berusaha memasang program berbahaya di komputer Anda yang dapat mencuri dan menghapus informasi Anda (misalnya, foto, sandi, pesan, dan kartu kredit).</translation>
<translation id="8241707690549784388">Laman yang dicari menggunakan informasi yang Anda masukkan. Kembali ke laman tersebut dapat menyebabkan pengulangan tindakan apa pun yang Anda lakukan. Apakah Anda ingin melanjutkan?</translation>
<translation id="8249320324621329438">Terakhir diambil:</translation>
<translation id="8253091569723639551">Perlu alamat penagihan</translation>
@@ -782,6 +857,7 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="8289355894181816810">Hubungi administrator jaringan Anda jika Anda tidak yakin apa maksudnya.</translation>
<translation id="8293206222192510085">Tambahkan Bookmark</translation>
<translation id="8294431847097064396">Sumber</translation>
+<translation id="8306404619377842860">Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat diterapkan karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) perangkat tidak tepat. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Terjemahan gagal karena ada masalah dengan koneksi jaringan.</translation>
<translation id="8332188693563227489">Akses ke <ph name="HOST_NAME" /> ditolak</translation>
<translation id="834457929814110454">Jika Anda memahami risiko terhadap keamanan, Anda dapat <ph name="BEGIN_LINK" />mengunjungi situs ini<ph name="END_LINK" /> sebelum program berbahaya tersebut dibuang.</translation>
@@ -802,11 +878,9 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="8483780878231876732">Untuk menggunakan kartu dari Akun Google Anda, masuk ke Chrome</translation>
<translation id="8488350697529856933">Berlaku untuk</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> membutuhkan terlalu banyak waktu untuk merespons.</translation>
-<translation id="852346902619691059">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh sistem operasi perangkat. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau ada penyerang yang mencegat sambungan Anda. <ph name="BEGIN_LEARN_MORE_LINK" />Pelajari lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Tahun Masa Berlaku Habis</translation>
<translation id="8543181531796978784">Anda dapat <ph name="BEGIN_ERROR_LINK" />melaporkan masalah pendeteksian<ph name="END_ERROR_LINK" /> atau, jika memahami risiko bagi keamanan, Anda dapat <ph name="BEGIN_LINK" />mengunjungi situs yang tidak aman<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Terjemahan gagal karena bahasa laman tidak dapat ditentukan.</translation>
-<translation id="8559762987265718583">Sambungan pribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat dibuat karena tanggal dan waktu (<ph name="DATE_AND_TIME" />) perangkat tidak benar.</translation>
<translation id="8571890674111243710">Menerjemahkan laman ke <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">+ nomor telepon</translation>
<translation id="859285277496340001">Sertifikat tidak menetapkan mekanisme untuk memeriksa apakah sertifikat telah ditarik.</translation>
@@ -820,6 +894,7 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="8738058698779197622">Untuk membuat sambungan aman, jam perlu disetel dengan benar. Hal ini karena sertifikat yang digunakan situs web untuk mengidentifikasi situs web tersebut hanya valid untuk jangka waktu tertentu. Karena jam perangkat tidak benar, Chromium tidak dapat memverifikasi sertifikat ini.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;Alamat DNS&lt;/abbr&gt; <ph name="HOST_NAME" /> tidak dapat ditemukan. Mendiagnosis masalah.</translation>
<translation id="8759274551635299824">Kartu sudah tidak aktif</translation>
+<translation id="8761567432415473239">Google Safe Browsing baru-baru ini <ph name="BEGIN_LINK" />menemukan program berbahaya<ph name="END_LINK" /> di <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Ulangi penghapusan</translation>
<translation id="8800988563907321413">Saran terdekat muncul di sini</translation>
<translation id="8820817407110198400">Bookmark</translation>
@@ -832,29 +907,30 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="8870413625673593573">Barusan Ditutup</translation>
<translation id="8874824191258364635">Masukkan nomor kartu yang valid</translation>
<translation id="8876793034577346603">Konfigurasi jaringan gagal diuraikan.</translation>
-<translation id="8877192140621905067">Setelah mengonfirmasi, detail kartu Anda akan dibagikan dengan situs ini</translation>
<translation id="8889402386540077796">Rona</translation>
<translation id="8891727572606052622">Mode proxy tidak valid.</translation>
<translation id="889901481107108152">Maaf, percobaan ini tidak tersedia di platform Anda.</translation>
<translation id="8903921497873541725">Perbesar</translation>
<translation id="8931333241327730545">Ingin menyimpan kartu ini ke Akun Google Anda?</translation>
<translation id="8932102934695377596">Setelan waktu Anda terlalu lambat</translation>
-<translation id="8954894007019320973">(Lanjutan.)</translation>
<translation id="8971063699422889582">Sertifikat server telah kedaluwarsa.</translation>
<translation id="8986494364107987395">Kirim statistik penggunaan dan laporan kerusakan ke Google secara otomatis</translation>
-<translation id="8987927404178983737">Bulan</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Situs yang akan dibuka berisi program berbahaya</translation>
+<translation id="8997023839087525404">Server menampilkan sertifikat yang tidak diungkapkan ke publik melalui kebijakan Transparansi Sertifikat. Ini adalah persyaratan untuk beberapa sertifikat, untuk memastikan bahwa sertifikat dapat dipercaya agar terlindung dari penyerang.</translation>
<translation id="9001074447101275817">Proxy <ph name="DOMAIN" /> memerlukan nama pengguna dan sandi.</translation>
+<translation id="9005998258318286617">Gagal memuat dokumen PDF.</translation>
<translation id="901974403500617787">Tanda yang berlaku bagi sistem secara luas hanya dapat disetel oleh pemilik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Perlu alamat penagihan kartu</translation>
<translation id="9020542370529661692">Laman ini telah diterjemahkan ke <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Kesalahan keamanan</translation>
<translation id="9038649477754266430">Gunakan layanan prediksi agar halaman dimuat dengan lebih cepat</translation>
<translation id="9039213469156557790">Selain itu, laman ini berisi sumber daya lainnya yang tidak aman. Sumber daya ini dapat dilihat oleh orang lain saat transit dan dapat dimodifikasi oleh penyerang untuk mengubah perilaku laman.</translation>
-<translation id="9040185888511745258">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin berusaha mengelabui Anda agar memasang program yang membahayakan pengalaman penjelajahan (misalnya, dengan mengubah beranda Anda atau menayangkan iklan ekstra pada situs yang Anda kunjungi).</translation>
+<translation id="9049981332609050619">Anda berupaya menjangkau <ph name="DOMAIN" />, tetapi server menyajikan sertifikat yang tidak valid.</translation>
<translation id="9050666287014529139">Frasa sandi</translation>
<translation id="9065203028668620118">Edit</translation>
<translation id="9068849894565669697">Pilih warna</translation>
+<translation id="9069693763241529744">Diblokir oleh ekstensi</translation>
<translation id="9076283476770535406">Situs mungkin berisi konten dewasa</translation>
<translation id="9078964945751709336">Dibutuhkan informasi lebih lanjut</translation>
<translation id="9103872766612412690"><ph name="SITE" /> biasanya menggunakan enkripsi untuk melindungi informasi Anda. Saat Chromium mencoba menyambung ke <ph name="SITE" /> kali ini, situs web mengembalikan kredensial yang salah dan tidak biasa. Hal ini dapat terjadi jika ada penyerang yang berpura-pura menjadi <ph name="SITE" />, atau layar masuk Wi-Fi mengganggu sambungan. Informasi Anda masih aman karena Chromium menghentikan sambungan sebelum terjadi pertukaran data apa pun.</translation>
@@ -863,16 +939,21 @@ Ssst! <ph name="SHORTCUT_KEY" /> mode penyamaran mungkin berguna suatu saat nant
<translation id="9148507642005240123">&amp;Urungkan pengeditan</translation>
<translation id="9154194610265714752">Diperbarui</translation>
<translation id="9157595877708044936">Menyiapkan...</translation>
+<translation id="9169664750068251925">Selalu cekal di situs ini</translation>
<translation id="9170848237812810038">&amp;Urung</translation>
<translation id="917450738466192189">Sertifikat server tidak valid.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> opsi pengiriman lainnya}other{<ph name="SHIPPING_OPTION_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> opsi pengiriman lainnya}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> menggunakan protokol yang tidak didukung.</translation>
<translation id="9205078245616868884">Data Anda dienkripsi dengan frasa sandi sinkronisasi. Masukkan frasa sandi untuk memulai sinkronisasi.</translation>
<translation id="9207861905230894330">Gagal menambahkan artikel.</translation>
+<translation id="9219103736887031265">Gambar</translation>
<translation id="933612690413056017">Tidak ada koneksi Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">HAPUS FORMULIR</translation>
<translation id="939736085109172342">Folder baru</translation>
<translation id="941721044073577244">Tampaknya Anda tidak memiliki izin untuk mengunjungi situs ini</translation>
<translation id="969892804517981540">Pembuatan Resmi</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Tidak ada}=1{1 item}other{# item}}</translation>
<translation id="988159990683914416">Buatan Pengembang</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_it.xtb b/chromium/components/strings/components_strings_it.xtb
index bde7e1935fd..2ccc2d35bd2 100644
--- a/chromium/components/strings/components_strings_it.xtb
+++ b/chromium/components/strings/components_strings_it.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Ruota in senso orario</translation>
<translation id="1038842779957582377">nome sconosciuto</translation>
<translation id="1050038467049342496">Chiudi altre app</translation>
-<translation id="1053591932240354961">Al momento non puoi visitare il sito <ph name="SITE" /> perché ha inviato credenziali criptate che Google Chrome non è in grado di elaborare. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Annulla aggiunta</translation>
<translation id="10614374240317010">Mai salvate</translation>
<translation id="106701514854093668">Preferiti desktop</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cache dei criteri integra</translation>
<translation id="113188000913989374"><ph name="SITE" /> dice:</translation>
<translation id="1132774398110320017">Impostazioni di Compilazione automatica Chrome...</translation>
+<translation id="1150979032973867961">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile dal sistema operativo del computer. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
+<translation id="1151972924205500581">Password obbligatoria</translation>
<translation id="1152921474424827756">Accedi a una <ph name="BEGIN_LINK" />copia memorizzata nella cache<ph name="END_LINK" /> di <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ha chiuso in modo imprevisto la connessione.</translation>
<translation id="1161325031994447685">Riconnessione alla rete Wi-Fi</translation>
+<translation id="1165039591588034296">Errore</translation>
<translation id="1175364870820465910">&amp;Stampa...</translation>
<translation id="1181037720776840403">Rimuovi</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Segnala automaticamente<ph name="END_WHITEPAPER_LINK" /> a Google i dettagli dei possibili problemi di sicurezza. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Altri dal sito</translation>
<translation id="1206967143813997005">Firma iniziale non valida</translation>
<translation id="1209206284964581585">Nascondi per ora</translation>
+<translation id="121201262018556460">Hai tentato di accedere a <ph name="DOMAIN" /> ma il server ha presentato un certificato contenente una chiave debole. Un utente malitenzionato potrebbe avere decifrato la chiave privata e il server potrebbe non essere quello previsto (è possibile che tu stia comunicando con un utente malintenzionato).</translation>
<translation id="1219129156119358924">Sicurezza del sistema</translation>
<translation id="1227224963052638717">Norma sconosciuta.</translation>
<translation id="1227633850867390598">Nascondi valore</translation>
<translation id="1228893227497259893">Identificatore entità errato</translation>
<translation id="1232569758102978740">Senza titolo</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizzati)</translation>
<translation id="1263231323834454256">Elenco di lettura</translation>
<translation id="1264126396475825575">Rapporto sugli arresti anomali generato il giorno <ph name="CRASH_TIME" /> (non ancora caricato o ignorato)</translation>
+<translation id="1281526147609854549">Emesso da <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Contenuti pericolosi bloccati</translation>
<translation id="1285320974508926690">Non tradurre mai questo sito</translation>
<translation id="129553762522093515">Chiuse di recente</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Prova a cancellare i cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">La tua attività <ph name="BEGIN_EMPHASIS" />potrebbe comunque essere visibile<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Ai siti web visitati
+ <ph name="LIST_ITEM" />Al tuo datore di lavoro o alla tua scuola
+ <ph name="LIST_ITEM" />Al tuo provider di servizi Internet
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Dominio registrazione:</translation>
<translation id="1340482604681802745">Indirizzo di ritiro</translation>
<translation id="1344211575059133124">Sembra che ti occorra l'autorizzazione per poter visitare il sito</translation>
<translation id="1344588688991793829">Impostazioni di Compilazione automatica Chromium...</translation>
+<translation id="1348198688976932919">Il sito che stai per visitare contiene app pericolose</translation>
<translation id="1374468813861204354">suggerimenti</translation>
<translation id="1375198122581997741">Informazioni sulla versione</translation>
<translation id="1377321085342047638">Numero carta</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> non ha inviato dati.</translation>
<translation id="1407135791313364759">Apri tutte</translation>
<translation id="1413809658975081374">Errore di privacy</translation>
+<translation id="14171126816530869">L'identità di <ph name="ORGANIZATION" /> con sede a <ph name="LOCALITY" /> è stata verifica da <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Sì</translation>
<translation id="1430915738399379752">Stampa</translation>
-<translation id="1442912890475371290">Tentativo <ph name="BEGIN_LINK" />di visitare una pagina su <ph name="DOMAIN" /><ph name="END_LINK" /> bloccato.</translation>
-<translation id="1491663344921578213">Al momento non puoi visitare il sito <ph name="SITE" /> perché utilizza il blocco dei certificati. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> e <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> altro}other{<ph name="PAYMENT_METHOD_PREVIEW" /> e altri <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Mostra una copia salvata (cioè che è noto sia obsoleta) di questa pagina.</translation>
<translation id="1517433312004943670">Numero di telefono obbligatorio</translation>
<translation id="1519264250979466059">Data build</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript deve essere attivato per utilizzare questa funzione.</translation>
<translation id="1555130319947370107">Blu</translation>
<translation id="1559528461873125649">Nessun file o directory corrispondente</translation>
-<translation id="1559572115229829303">&lt;p&gt;Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del dispositivo (<ph name="DATE_AND_TIME" />) non sono corrette.&lt;/p&gt;
-
- &lt;p&gt;Regola data e ora nella sezione &lt;strong&gt;Generali&lt;/strong&gt; dell'app &lt;strong&gt;Impostazioni&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Si è verificato un problema durante la visualizzazione della pagina web.</translation>
<translation id="1592005682883173041">Accesso ai dati locali</translation>
+<translation id="1594030484168838125">Scegli</translation>
<translation id="161042844686301425">Ciano</translation>
+<translation id="1620510694547887537">Videocamera</translation>
<translation id="1629803312968146339">Vuoi che Chrome salvi questa carta?</translation>
<translation id="1639239467298939599">Caricamento</translation>
<translation id="1640180200866533862">Criteri utente</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">La configurazione di rete non è valida e non può essere importata.</translation>
<translation id="1644574205037202324">Cronologia</translation>
<translation id="1645368109819982629">Protocollo non supportato</translation>
+<translation id="1655462015569774233">{1,plural, =1{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza è scaduto ieri. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. L'orologio del computer è attualmente impostato su <ph name="CURRENT_DATE" />. È corretto? Se è sbagliato, dovresti regolare l'orologio e aggiornare la pagina.}other{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza è scaduto # giorni fa. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. L'orologio del computer è attualmente impostato su <ph name="CURRENT_DATE" />. È corretto? Se è sbagliato, dovresti regolare l'orologio e aggiornare la pagina.}}</translation>
<translation id="1656489000284462475">Ritiro</translation>
<translation id="1663943134801823270">Carte di credito e indirizzi provengono da Chrome. Puoi gestirli in <ph name="BEGIN_LINK" />Impostazioni<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> in genere utilizza la crittografia per proteggere le tue informazioni. Questa volta, quando Google Chrome ha provato a connettersi a <ph name="SITE" />, il sito web ha restituito credenziali insolite e sbagliate. È possibile che un malintenzionato stia cercando di spacciarsi per il sito <ph name="SITE" /> oppure che una schermata di accesso alla rete Wi-Fi abbia interrotto la connessione. Le tue informazioni sono ancora al sicuro perché Google Chrome ha interrotto la connessione prima che avvenissero scambi di dati.</translation>
-<translation id="168328519870909584">I malintenzionati attualmente sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero tentare di installare sul tuo dispositivo app pericolose che scoprono o eliminano i tuoi dati (ad esempio foto, password, messaggi e carte di credito).</translation>
<translation id="168841957122794586">Il certificato del server contiene una chiave crittografica debole.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere attivo da domani. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.}other{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere attivo tra # giorni. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.}}</translation>
<translation id="1710259589646384581">Sistema operativo</translation>
<translation id="1721312023322545264">Ti occorre l'autorizzazione di <ph name="NAME" /> per poter visitare il sito</translation>
<translation id="1721424275792716183">* Campo obbligatorio</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Scarica la pagina più tardi</translation>
<translation id="17513872634828108">Schede aperte</translation>
<translation id="1753706481035618306">Numero di pagina</translation>
+<translation id="1763864636252898013">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile dal sistema operativo del dispositivo. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Prova a eseguire lo strumento Diagnostica di rete Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Aggiorna la tua passphrase di sincronizzazione.</translation>
<translation id="1787142507584202372">Le tue schede aperte vengono visualizzate qui</translation>
+<translation id="1789575671122666129">Popup</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nome del titolare della carta</translation>
-<translation id="1803678881841855883">La funzione Navigazione sicura di Google di recente ha <ph name="BEGIN_LINK" />rilevato malware<ph name="END_LINK" /> sul sito <ph name="SITE" />. I siti web che in genere sono sicuri a volte vengono infettati da malware. I contenuti dannosi provengono da <ph name="SUBRESOURCE_HOST" />, un noto distributore di malware. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Data di aggiunta: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Richiesta o parametri della richiesta non validi</translation>
<translation id="1826516787628120939">Verifica in corso...</translation>
<translation id="1834321415901700177">Il sito contiene programmi dannosi.</translation>
+<translation id="1840414022444569775">Questo numero di carta è già stato usato</translation>
<translation id="1842969606798536927">Paga</translation>
<translation id="1871208020102129563">L'impostazione del proxy prevede l'utilizzo di server proxy fissi, non di un URL script .pac.</translation>
<translation id="1871284979644508959">Campo obbligatorio</translation>
<translation id="187918866476621466">Apri pagine iniziali</translation>
<translation id="1883255238294161206">Comprimi elenco</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> altro}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e altri <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtri</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Nessuno}=1{1 sito}other{# siti}}</translation>
<translation id="194030505837763158">Vai al link: <ph name="LINK" /></translation>
<translation id="1962204205936693436">Segnalibri di <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Errore di serializzazione</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorata perché è stata sostituita da <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Ricerca di pagine Physical Web nelle vicinanze in corso</translation>
<translation id="213826338245044447">Preferiti su disp. mobili</translation>
-<translation id="2148716181193084225">Oggi</translation>
+<translation id="2147827593068025794">Sincronizzazione in background</translation>
<translation id="2154054054215849342">Il servizio di sincronizzazione non è disponibile per il tuo dominio</translation>
<translation id="2154484045852737596">Modifica la carta</translation>
<translation id="2166049586286450108">Accesso amministrativo completo</translation>
<translation id="2166378884831602661">Il sito non può fornire una connessione protetta</translation>
<translation id="2181821976797666341">Criteri</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 indirizzo}other{# indirizzi}}</translation>
+<translation id="2187317261103489799">Rileva (predefinita)</translation>
<translation id="2202020181578195191">Inserisci un anno di scadenza valido</translation>
<translation id="2212735316055980242">Criterio non trovato</translation>
<translation id="2213606439339815911">Recupero voci...</translation>
+<translation id="2218879909401188352">Gli utenti malintenzionati attualmente presenti sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero installare app pericolose che danneggiano il tuo dispositivo, generano addebiti nascosti sulla fattura del cellulare o si impossessano delle tue informazioni personali. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Correggi la connessione con l'<ph name="BEGIN_LINK" />app diagnostica<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Invia ora</translation>
<translation id="225207911366869382">Il valore specificato per la norma è obsoleto.</translation>
<translation id="2262243747453050782">Errore HTTP</translation>
+<translation id="2270484714375784793">Numero di telefono</translation>
<translation id="2282872951544483773">Esperimenti non disponibili</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> elemento}other{<ph name="ITEM_COUNT" /> elementi}}</translation>
<translation id="2292556288342944218">L'accesso a Internet è bloccato</translation>
<translation id="230155334948463882">Nuova carta?</translation>
-<translation id="2305919008529760154">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere stato rilasciato in maniera fraudolenta. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> richiede un nome utente e una password.</translation>
-<translation id="2318774815570432836">Al momento non puoi visitare il sito <ph name="SITE" /> perché utilizza HSTS. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Impostazione controllata dall'amministratore</translation>
<translation id="2354001756790975382">Altri Preferiti</translation>
+<translation id="2354430244986887761">La funzione Navigazione sicura di Google ha recentemente <ph name="BEGIN_LINK" />rilevato app dannose<ph name="END_LINK" /> sul sito <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Gli utenti malintenzionati potrebbero riuscire a vedere le immagini che visualizzi in questo sito e ingannarti modificandole.</translation>
+<translation id="2356070529366658676">Chiedi</translation>
+<translation id="2359629602545592467">Multiple</translation>
<translation id="2359808026110333948">Continua</translation>
<translation id="2365563543831475020">Il rapporto sugli arresti anomali generato il giorno <ph name="CRASH_TIME" /> non è stato caricato</translation>
<translation id="2367567093518048410">Livello</translation>
-<translation id="2371153335857947666">{1,plural, =1{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza è scaduto ieri. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. L'orologio del computer è attualmente impostato su <ph name="CURRENT_DATE" />. È corretto? Se è sbagliato, devi regolare l'orologio di sistema e aggiornare la pagina. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.}other{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza è scaduto # giorni fa. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. L'orologio del computer è attualmente impostato su <ph name="CURRENT_DATE" />. È corretto? Se è sbagliato, devi regolare l'orologio di sistema e aggiornare la pagina. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nessuna alternativa UI disponibile</translation>
<translation id="2384307209577226199">Valore predefinito aziendale</translation>
<translation id="2386255080630008482">Il certificato del server è stato revocato.</translation>
<translation id="2392959068659972793">Mostra norme senza valori</translation>
<translation id="239429038616798445">Questo metodo di spedizione non è disponibile. Prova un metodo diverso.</translation>
<translation id="2396249848217231973">&amp;Annulla eliminazione</translation>
-<translation id="2460160116472764928">La funzione Navigazione sicura di Google di recente ha <ph name="BEGIN_LINK" />rilevato malware<ph name="END_LINK" /> sul sito <ph name="SITE" />. I siti web che in genere sono sicuri a volte vengono infettati da malware. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere revocato. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="2463739503403862330">Compila</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Eseguire lo strumento Diagnostica di rete<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL ricerca non valido.</translation>
+<translation id="2482878487686419369">Notifiche</translation>
<translation id="2491120439723279231">Il certificato del server contiene degli errori.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2495093607237746763">Se questa opzione viene selezionata, Chromium memorizza una copia della carta sul dispositivo per velocizzare la compilazione dei moduli.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Indietro</translation>
<translation id="2515629240566999685">Controllare il segnale nella tua area</translation>
<translation id="2516305470678292029">Alternative UI</translation>
+<translation id="2539524384386349900">Rileva</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ha inviato una risposta non valida.</translation>
-<translation id="2552545117464357659">Più recente</translation>
<translation id="2556876185419854533">&amp;Annulla modifica</translation>
<translation id="2587730715158995865">Da <ph name="ARTICLE_PUBLISHER" />. Leggi questo e altri <ph name="OTHER_ARTICLE_COUNT" /> articoli.</translation>
<translation id="2587841377698384444">ID API directory:</translation>
<translation id="2597378329261239068">Questo documento è protetto da password. Inserisci una password.</translation>
<translation id="2609632851001447353">Varianti</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Nessuna}=1{1 app ($1)}=2{2 app ($1, $2)}other{# app ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">L'orologio è avanti</translation>
<translation id="2639739919103226564">Stato:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">L'accesso al file è stato negato</translation>
<translation id="2653659639078652383">Invia</translation>
<translation id="2666117266261740852">Chiudi altre schede o app</translation>
+<translation id="2670429602441959756">Questa pagina contiene funzioni non ancora supportate nella realtà virtuale. Uscita in corso...</translation>
<translation id="2674170444375937751">Eliminare le pagine dalla cronologia?</translation>
<translation id="2677748264148917807">Esci</translation>
-<translation id="269990154133806163">Il server ha presentato un certificato che non è stato reso pubblico tramite le norme di Certificate Transparency, la cui applicazione costituisce un requisito di alcuni certificati al fine di garantire la loro attendibilità nonché la sicurezza nei confronti dei malintenzionati. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Elenco di lettura</translation>
<translation id="2704283930420550640">Il valore non corrisponde al formato.</translation>
<translation id="2704951214193499422">Al momento non è possibile confermare la carta in Chromium. Riprova più tardi.</translation>
<translation id="2705137772291741111">La copia del sito salvata (nella cache) era illeggibile.</translation>
<translation id="2709516037105925701">Compilazione automatica</translation>
-<translation id="2712118517637785082">Hai tentato di accedere a <ph name="DOMAIN" />, tuttavia il server ha presentato un certificato revocato dall'autorità di certificazione. Ciò significa che le credenziali di sicurezza presentate dal server non sono assolutamente attendibili. Potresti avere stabilito una comunicazione con un malintenzionato. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Chiedi autorizzazione</translation>
<translation id="2713444072780614174">Bianco</translation>
<translation id="2720342946869265578">Qui vicino</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Record del dispositivo mancante</translation>
<translation id="2784949926578158345">La connessione è stata reimpostata.</translation>
<translation id="2794233252405721443">Sito bloccato</translation>
+<translation id="2799020568854403057">Il sito che stai per visitare contiene app dannose</translation>
+<translation id="2803306138276472711">La funzione Navigazione sicura di Google ha <ph name="BEGIN_LINK" />rilevato malware<ph name="END_LINK" /> di recente sul sito <ph name="SITE" />. I siti web che in genere sono sicuri a volte vengono infettati da malware.</translation>
<translation id="2824775600643448204">Barra degli indirizzi e di ricerca</translation>
<translation id="2826760142808435982">La connessione è stata criptata e autenticata utilizzando <ph name="CIPHER" /> e <ph name="KX" /> come meccanismo di scambio delle chiavi.</translation>
<translation id="2835170189407361413">Cancella modulo</translation>
+<translation id="2856444702002559011">Gli utenti malintenzionati potrebbero provare a carpire le tue informazioni da <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (ad esempio, password, messaggi o carte di credito). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Non ricaricare</translation>
<translation id="2900469785430194048">Google Chrome ha esaurito la memoria mentre cercava di visualizzare questa pagina web.</translation>
<translation id="2909946352844186028">È stato rilevato un cambio di rete.</translation>
<translation id="2916038427272391327">Chiudi altri programmi</translation>
<translation id="2922350208395188000">Il certificato del server non può essere verificato.</translation>
<translation id="2928905813689894207">Indirizzo di fatturazione</translation>
+<translation id="2941952326391522266">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza proviene da <ph name="DOMAIN2" />. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="2948083400971632585">Puoi disattivare tutti i proxy configurati per una connessione dalla pagina delle impostazioni.</translation>
<translation id="2955913368246107853">Chiudi la barra di ricerca</translation>
<translation id="2958431318199492670">La configurazione di rete non è conforme allo standard ONC. Parti della configurazione potrebbero non essere importate.</translation>
-<translation id="29611076221683977">I malintenzionati attualmente sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero tentare di installare sul tuo Mac programmi pericolosi che scoprono o eliminano i tuoi dati (ad esempio foto, password, messaggi e carte di credito).</translation>
<translation id="2966678944701946121">Scadenza: <ph name="EXPIRATION_DATE_ABBR" />, data di aggiunta: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Per poter stabilire una connessione protetta, l'orologio deve essere impostato correttamente perché i certificati utilizzati dai siti web per identificarsi sono validi soltanto per determinati periodi di tempo. L'orologio del dispositivo non è impostato sull'orario corretto, pertanto Chrome non può verificare i certificati.</translation>
<translation id="2972581237482394796">&amp;Ripeti</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Inserisci un indirizzo valido</translation>
<translation id="2986368408720340940">Questo metodo di ritiro non è disponibile. Prova un metodo diverso.</translation>
<translation id="2991174974383378012">Condivisione con i siti web</translation>
+<translation id="2991571918955627853">Al momento non puoi visitare il sito web <ph name="SITE" /> perché utilizza HSTS. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi.</translation>
<translation id="3005723025932146533">Mostra copia salvata</translation>
<translation id="3008447029300691911">Inserisci il codice CVC della carta <ph name="CREDIT_CARD" />. Dopo essere stati confermati, i dettagli della carta saranno condivisi con questo sito.</translation>
<translation id="3010559122411665027">Voce "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Bloccata automaticamente</translation>
<translation id="3024663005179499861">Tipo di criterio errato</translation>
<translation id="3032412215588512954">Vuoi ricaricare questo sito?</translation>
<translation id="3037605927509011580">Uffa!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{almeno 1 elemento sui dispositivi sincronizzati}=1{1 elemento (e altri sui dispositivi sincronizzati)}other{# elementi (e altri sui dispositivi sincronizzati)}}</translation>
<translation id="3041612393474885105">Informazioni certificato</translation>
<translation id="3063697135517575841">Al momento non è possibile confermare la carta in Chrome. Riprova più tardi.</translation>
<translation id="3064966200440839136">Per procedere al pagamento tramite un'applicazione esterna, uscirai dalla modalità di navigazione in incognito. Continuare?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Nessuna}=1{1 password}other{# password}}</translation>
<translation id="3093245981617870298">Sei offline.</translation>
<translation id="3105172416063519923">ID asset:</translation>
<translation id="3109728660330352905">Non sei autorizzato a visualizzare questa pagina.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Prova a eseguire lo strumento Diagnostica della connettività<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Decodifica della risposta non riuscita</translation>
<translation id="3150653042067488994">Errore temporaneo del server</translation>
@@ -247,13 +277,17 @@
<translation id="3167968892399408617">Le pagine visualizzate nelle schede in incognito non vengono memorizzate nella cronologia del browser, nell'archivio di cookie o nella cronologia delle ricerche dopo avere chiuso tutte le schede in incognito. I file scaricati o i preferiti creati verranno conservati.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Isola</translation>
+<translation id="317583078218509884">Le nuove impostazioni delle autorizzazioni per i siti avranno effetto una volta ricaricata la pagina.</translation>
<translation id="3176929007561373547">Controlla le impostazioni del proxy o contatta il tuo amministratore di rete per verificare che il server proxy funzioni. Se non ritieni di dover utilizzare un server proxy: <ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Apri la pagina in modalità di navigazione in incognito</translation>
-<translation id="3202578601642193415">Ultimo</translation>
+<translation id="320323717674993345">Annulla pagamento</translation>
<translation id="3207960819495026254">Aggiunto ai Preferiti</translation>
+<translation id="3225919329040284222">Il server ha presentato un certificato che non corrisponde alle previsioni integrate. Queste previsioni sono incluse per determinati siti web con protezione elevata allo scopo di proteggerti.</translation>
<translation id="3226128629678568754">Premi il pulsante Ricarica per inviare di nuovo i dati necessari per caricare la pagina.</translation>
+<translation id="3227137524299004712">Microfono</translation>
<translation id="3228969707346345236">La traduzione non è riuscita perché la pagina è già in <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Inserisci il codice CVC della carta <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Rileva sempre contenuti importanti di questo sito</translation>
<translation id="3254409185687681395">Aggiungi ai Preferiti</translation>
<translation id="3270847123878663523">&amp;Annulla ridisposizione</translation>
<translation id="3282497668470633863">Aggiungi il nome indicato sulla carta</translation>
@@ -267,42 +301,48 @@
<translation id="3340978935015468852">impostazioni</translation>
<translation id="3345135638360864351">Impossibile inviare a <ph name="NAME" /> la richiesta di accesso a questo sito. Riprova.</translation>
<translation id="3355823806454867987">Modifica impostazioni proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />non salverà<ph name="END_EMPHASIS" /> le seguenti informazioni:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Cronologia di navigazione
+ <ph name="LIST_ITEM" />Cookie e dati dei siti
+ <ph name="LIST_ITEM" />Informazioni inserite nei moduli
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Errore dell'orologio</translation>
-<translation id="337311366426640088">Altri <ph name="ITEM_COUNT" /> elementi...</translation>
<translation id="337363190475750230">Deprovisioning effettuato</translation>
<translation id="3377188786107721145">Errore di analisi del criterio</translation>
<translation id="3380365263193509176">Errore sconosciuto</translation>
<translation id="3380864720620200369">ID client:</translation>
<translation id="3391030046425686457">Indirizzo di consegna</translation>
<translation id="3395827396354264108">Metodo di ritiro</translation>
-<translation id="340013220407300675">Gli autori di un attacco potrebbero cercare di rubare le tue informazioni (ad esempio password, messaggi o dati della carta di credito) da <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />.</translation>
<translation id="3422248202833853650">Prova a uscire da altri programmi per liberare spazio nella memoria.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> non è attualmente raggiungibile.</translation>
+<translation id="3427092606871434483">Consenti (predefinita)</translation>
<translation id="3427342743765426898">&amp;Ripeti modifica</translation>
<translation id="3431636764301398940">Salva la carta per questo dispositivo</translation>
<translation id="3435896845095436175">Abilita</translation>
<translation id="3447661539832366887">Il proprietario del dispositivo ha disattivato il gioco dei dinosauri.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Intervallo recupero:</translation>
<translation id="3462200631372590220">Nascondi avanzate</translation>
<translation id="3467763166455606212">Nome titolare carta obbligatorio</translation>
<translation id="3478058380795961209">Mese di scadenza</translation>
<translation id="3479539252931486093">Non era previsto? <ph name="BEGIN_LINK" />Contattaci<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Non adesso</translation>
-<translation id="348000606199325318">ID arresto anomalo <ph name="CRASH_LOCAL_ID" /> (ID server: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">In questo momento, non è possibile raggiungere il tuo genitore. Riprova.</translation>
<translation id="3528171143076753409">Il certificato del server non è affidabile.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Almeno 1 elemento sui dispositivi sincronizzati}=1{1 elemento (e altri sui dispositivi sincronizzati)}other{# elementi (e altri sui dispositivi sincronizzati)}}</translation>
<translation id="3539171420378717834">Conserva una copia di questa carta sul dispositivo</translation>
<translation id="3542684924769048008">Utilizza password per:</translation>
+<translation id="3545341443414427877">Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del computer (<ph name="DATE_AND_TIME" />) sono sbagliate. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Cripta tutti i dati sincronizzati con la tua passphrase di sincronizzazione</translation>
-<translation id="3549761410225185768">Altre <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza proviene da <ph name="DOMAIN2" />. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Il tuo gestore può sbloccarlo per te</translation>
<translation id="3566021033012934673">La connessione non è privata</translation>
+<translation id="3569145463236695319">&lt;p&gt;Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del dispositivo (<ph name="DATE_AND_TIME" />) sono sbagliate.&lt;/p&gt;
+
+ &lt;p&gt;Regola data e ora nella sezione &lt;strong&gt;Generali&lt;/strong&gt; dell'app &lt;strong&gt;Impostazioni&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Aggiungi nome</translation>
<translation id="3583757800736429874">&amp;Ripeti spostamento</translation>
<translation id="3586931643579894722">Nascondi dettagli</translation>
-<translation id="3587482841069643663">Tutti</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Inserisci una data di scadenza valida</translation>
<translation id="36224234498066874">Cancella dati di navigazione...</translation>
@@ -319,7 +359,6 @@
<translation id="3681007416295224113">Informazioni certificato</translation>
<translation id="3690164694835360974">Accesso non sicuro</translation>
<translation id="3693415264595406141">Password:</translation>
-<translation id="3696411085566228381">nessuno</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Caricamento in corso...</translation>
<translation id="3712624925041724820">Licenze esaurite</translation>
@@ -327,12 +366,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Controllare la configurazione del proxy, firewall e DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Se sei consapevole dei rischi per la tua sicurezza, potresti <ph name="BEGIN_LINK" />visitare questo sito non sicuro<ph name="END_LINK" /> senza aspettare che vengano rimossi i programmi pericolosi.</translation>
<translation id="3739623965217189342">Link che hai copiato</translation>
+<translation id="3744899669254331632">Al momento non puoi visitare il sito <ph name="SITE" /> perché tale sito web ha inviato credenziali criptate che Chromium non è riuscito a elaborare. Gli attacchi e gli errori di rete in genere sono temporanei, pertanto è possibile che questa pagina funzioni più tardi.</translation>
+<translation id="3748148204939282805">Gli utenti malintenzionati presenti sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero indurti con l'inganno a effettuare operazioni pericolose, ad esempio a installare software o a rivelare informazioni personali (ad esempio, password, numeri di telefono o carte di credito). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">La traduzione non è riuscita a causa di un errore del server.</translation>
<translation id="3759461132968374835">Non hai segnalato arresti anomali di recente. Quelli che si sono verificati quando la segnalazione degli arresti anomali era disabilitata non verranno visualizzati qui.</translation>
+<translation id="3778403066972421603">Vuoi salvare questa carta nel tuo account Google e su questo dispositivo?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Data di scadenza: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Se utilizzi un server proxy...</translation>
<translation id="3828924085048779000">Non è consentita una passphrase vuota.</translation>
-<translation id="3845539888601087042">È visualizzata la cronologia dei dispositivi su cui hai eseguito l'accesso. <ph name="BEGIN_LINK" />Ulteriori informazioni<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Indietro</translation>
<translation id="3858027520442213535">Aggiorna data e ora</translation>
<translation id="3884278016824448484">Identificativo del dispositivo in conflitto</translation>
@@ -340,11 +382,13 @@
<translation id="3886446263141354045">La tua richiesta di accesso al sito è stata inviata a <ph name="NAME" /></translation>
<translation id="3890664840433101773">Aggiungi email</translation>
<translation id="3901925938762663762">La carta è scaduta</translation>
-<translation id="3933571093587347751">{1,plural, =1{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere attivo da domani. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.}other{Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere attivo tra # giorni. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Caricamento del documento PDF non riuscito</translation>
+<translation id="3945915738023014686">ID rapporto sugli arresti anomali caricato <ph name="CRASH_ID" /> (ID arresto anomalo locale: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non contiene nomi alternativi del soggetto. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="3963721102035795474">Modalità Reader</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Nessuno}=1{Di 1 sito }other{Di # siti }}</translation>
<translation id="397105322502079400">Calcolo in corso...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> è bloccato</translation>
+<translation id="3987940399970879459">Meno di 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{Una pagina web nelle vicinanze}other{# pagine web nelle vicinanze}}</translation>
<translation id="4021036232240155012">DNS è il servizio di rete che traduce il nome di un sito web nel relativo indirizzo Internet.</translation>
<translation id="4030383055268325496">&amp;Annulla aggiunta</translation>
@@ -355,56 +399,63 @@
<translation id="4079302484614802869">L'impostazione della configurazione proxy prevede l'utilizzo di un URL script .pac, non di server proxy fissi.</translation>
<translation id="4098354747657067197">Sito ingannevole in vista</translation>
<translation id="4103249731201008433">Il numero di serie del dispositivo non è valido</translation>
+<translation id="410351446219883937">Riproduzione automatica</translation>
<translation id="4103763322291513355">Visita &lt;strong&gt;chrome://policy&lt;/strong&gt; per visualizzare l'elenco di URL inseriti nella blacklist e altre norme applicate dall'amministratore di sistema.</translation>
-<translation id="4110615724604346410">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza contiene errori. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Consenti sempre su questo sito</translation>
<translation id="4117700440116928470">L'ambito della norma non è supportato.</translation>
-<translation id="4118212371799607889">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile da Chromium. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 altro}other{# altri}}</translation>
<translation id="4130226655945681476">Controllare i cavi di rete, il modem e il router</translation>
+<translation id="413544239732274901">Ulteriori informazioni</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Utilizza impostazioni predefinite globali (Rileva)</translation>
+<translation id="4165986682804962316">Impostazioni sito</translation>
<translation id="4169947484918424451">Vuoi che Chromium salvi questa carta?</translation>
<translation id="4171400957073367226">Firma di verifica non valida</translation>
<translation id="4196861286325780578">&amp;Ripeti spostamento</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Controllare le configurazioni del firewall e antivirus<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{nessuna}=1{1 app ($ 1)}=2{2 app ($ 1, $ 2)}other{# app ($ 1, $ 2, $ 3)}}</translation>
<translation id="4220128509585149162">Arresti anomali</translation>
+<translation id="422022731706691852">Gli utenti malintenzionati presenti sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero cercare di indurti con l'inganno a installare programmi che danneggiano la tua esperienza di navigazione (ad esempio cambiando la tua pagina iniziale o mostrando annunci extra sui siti che visiti). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Prova a eseguire lo strumento Diagnostica di rete<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Valido</translation>
<translation id="4250431568374086873">La connessione a questo sito non è completamente protetta</translation>
<translation id="4250680216510889253">No</translation>
<translation id="425582637250725228">Le modifiche apportate potrebbero non essere salvate.</translation>
<translation id="4258748452823770588">Firma errata</translation>
+<translation id="4265872034478892965">Consentita dall'amministratore</translation>
<translation id="4269787794583293679">(Nessun nome utente)</translation>
<translation id="4275830172053184480">Riavvia il dispositivo</translation>
<translation id="4280429058323657511">, scad.: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">La funzione Navigazione sicura di Google di recente ha <ph name="BEGIN_LINK" />rilevato programmi dannosi<ph name="END_LINK" /> sul sito <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Suggerimenti per i genitori</translation>
<translation id="4304224509867189079">Accedi</translation>
-<translation id="432290197980158659">Il server ha presentato un certificato che non corrisponde alle previsioni integrate. Queste previsioni sono incluse per determinati siti web con protezione elevata allo scopo di proteggerti. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blocca (predefinita)</translation>
<translation id="4325863107915753736">Impossibile trovare l'articolo</translation>
<translation id="4326324639298822553">Controlla la data di scadenza e riprova</translation>
<translation id="4331708818696583467">Non sicuro</translation>
<translation id="4356973930735388585">I malintenzionati su questo sito potrebbero tentare di installare sul tuo computer programmi pericolosi che scoprono o eliminano i tuoi dati (ad esempio foto, password, messaggi e carte di credito).</translation>
<translation id="4372948949327679948">È previsto il valore <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Hai tentato di accedere a <ph name="DOMAIN" /> ma il server ha presentato un certificato revocato dall'autorità di certificazione. Ciò significa che le credenziali di sicurezza presentate dal server non sono assolutamente attendibili. Potresti avere stabilito una comunicazione con un utente malintenzionato.</translation>
<translation id="4381091992796011497">Nome utente:</translation>
<translation id="4394049700291259645">Disabilita</translation>
<translation id="4406896451731180161">risultati di ricerca</translation>
+<translation id="4424024547088906515">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile da Chrome. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> non ha accettato il certificato di accesso oppure non ne è stato fornito uno.</translation>
<translation id="443673843213245140">L'utilizzo di un proxy è stato disattivato ma è stata specificata una configurazione proxy esplicita.</translation>
-<translation id="4492190037599258964">Risultati di ricerca per "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Errore di convalida. <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Contattare l'amministratore di sistema</translation>
<translation id="450710068430902550">Condivisione con l'amministratore</translation>
<translation id="4515275063822566619">Carte di credito e indirizzi provengono da Chrome e dall'account Google (<ph name="ACCOUNT_EMAIL" />). Puoi gestirli in <ph name="BEGIN_LINK" />Impostazioni<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Dettagli</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Prova a disattivare le estensioni.</translation>
<translation id="457875822857220463">Consegna</translation>
<translation id="4587425331216688090">Rimuovere l'indirizzo da Chrome?</translation>
-<translation id="4589078953350245614">Hai tentato di accedere a <ph name="DOMAIN" />, tuttavia il server ha presentato un certificato non valido. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">La connessione a <ph name="DOMAIN" /> è criptata tramite un pacchetto di crittografia moderno.</translation>
<translation id="4594403342090139922">&amp;Annulla eliminazione</translation>
<translation id="4619615317237390068">Schede di altri dispositivi</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza contiene errori. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
+<translation id="4690462567478992370">Interrompi l'utilizzo di un certificato non valido</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">La connessione è stata interrotta</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Eseguire lo strumento Diagnostica di rete Windows<ph name="END_LINK" /></translation>
@@ -421,21 +472,24 @@
<translation id="4771973620359291008">Si è verificato un errore sconosciuto.</translation>
<translation id="4800132727771399293">Controlla la data di scadenza e il codice CVC, poi riprova</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Al momento non puoi visitare il sito web <ph name="SITE" /> perché ha inviato strane credenziali che Google Chrome non riesce a elaborare. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi.</translation>
<translation id="4813512666221746211">Errore di rete</translation>
<translation id="4816492930507672669">Adatta alla pagina</translation>
<translation id="483020001682031208">Nessuna pagina di Physical Web da mostrare</translation>
<translation id="4850886885716139402">Visualizza</translation>
<translation id="4854362297993841467">Questo metodo di consegna non è disponibile. Prova un metodo diverso.</translation>
<translation id="4858792381671956233">Hai chiesto ai tuoi genitori se puoi visitare questo sito</translation>
+<translation id="4863764087567530506">Questi contenuti potrebbero cercare di indurti con l'inganno a installare software o a rivelare informazioni personali. <ph name="BEGIN_LINK" />Mostra comunque<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Cerca nella cronologia</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{e un'altra pagina web}other{e altre # pagine web}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Questa pagina è stata tradotta da una lingua sconosciuta in <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pagamento</translation>
<translation id="4926049483395192435">Deve essere specificato.</translation>
<translation id="495170559598752135">Azioni</translation>
<translation id="4958444002117714549">Espandi elenco</translation>
-<translation id="4962322354953122629">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile da Chrome. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Riattiva avvisi</translation>
<translation id="4989809363548539747">Questo plug-in non è supportato</translation>
<translation id="5002932099480077015">Se questa opzione viene attivata, Chrome memorizza una copia della carta sul dispositivo per velocizzare la compilazione dei moduli.</translation>
<translation id="5018422839182700155">Impossibile aprire questa pagina</translation>
@@ -443,14 +497,15 @@
<translation id="5023310440958281426">Consulta le norme dell'amministratore</translation>
<translation id="5029568752722684782">Cancella copia</translation>
<translation id="5031870354684148875">Informazioni su Google Traduttore</translation>
+<translation id="5039804452771397117">Consenti</translation>
<translation id="5040262127954254034">Privacy</translation>
<translation id="5045550434625856497">Password non corretta</translation>
<translation id="5056549851600133418">Articoli per te</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Controllare l'indirizzo proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Nessun cookie}=1{1 sito usa i cookie. }other{# siti usano i cookie. }}</translation>
<translation id="5087286274860437796">Il certificato del server non è valido in questa fase.</translation>
<translation id="5087580092889165836">Aggiungi carta</translation>
<translation id="5089810972385038852">Provincia</translation>
+<translation id="5094747076828555589">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile da Chromium. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
<translation id="5095208057601539847">Provincia</translation>
<translation id="5115563688576182185">(a 64 bit)</translation>
<translation id="5141240743006678641">Cripta le password sincronizzate con le tue credenziali Google</translation>
@@ -466,24 +521,24 @@
<translation id="5222812217790122047">Email obbligatoria</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Utilizzi Chrome al lavoro? Le aziende possono gestire le impostazioni di Chrome per conto dei propri dipendenti. Ulteriori informazioni</translation>
+<translation id="5297526204711817721">La tua connessione a questo sito non è privata. Per uscire dalla modalità VR in qualsiasi momento, rimuovi l'auricolare e premi Indietro.</translation>
<translation id="5299298092464848405">Errore durante l'analisi del criterio</translation>
-<translation id="5300589172476337783">Mostra</translation>
<translation id="5308689395849655368">La segnalazione degli arresti anomali è disattivata.</translation>
<translation id="5317780077021120954">Salva</translation>
<translation id="5327248766486351172">Nome</translation>
-<translation id="5337705430875057403">I malintenzionati sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero indurti con l'inganno a effettuare operazioni pericolose, come installare software o fornire i tuoi dati personali (ad esempio password, numeri di telefono o carte di credito).</translation>
-<translation id="5359637492792381994">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza al momento non è valido. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Al momento non puoi visitare il sito <ph name="SITE" /> perché il relativo certificato è stato revocato. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi.</translation>
<translation id="536296301121032821">Archiviazione delle impostazioni criterio non riuscita</translation>
<translation id="5386426401304769735">Il certificato di questo sito contiene un certificato che è stato firmato utilizzando SHA-1.</translation>
<translation id="5402410679244714488">Scadenza: <ph name="EXPIRATION_DATE_ABBR" />, ultimo utilizzo oltre un anno fa</translation>
+<translation id="540969355065856584">Questo server non è riuscito a verificare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato valido in questa fase. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che ha intercettato la connessione.</translation>
<translation id="5421136146218899937">Cancella dati di navigazione...</translation>
<translation id="5430298929874300616">Rimuovi preferito</translation>
<translation id="5431657950005405462">Il file non è stato trovato</translation>
-<translation id="5435775191620395718">È visualizzata la cronologia di questo dispositivo. <ph name="BEGIN_LINK" />Ulteriori informazioni<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Errore di convalida dello schema in "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Impossibile trovare la pagina <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">Timestamp del criterio errato</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> di <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Non validi</translation>
<translation id="5470861586879999274">&amp;Ripeti modifica</translation>
<translation id="54817484435770891">Aggiungi un indirizzo valido</translation>
<translation id="5492298309214877701">Il sito nell'Intranet dell'azienda, dell'organizzazione o della scuola ha lo stesso URL del sito web esterno.
@@ -500,6 +555,8 @@
<translation id="5571083550517324815">Impossibile ritirare dall'indirizzo specificato. Seleziona un indirizzo diverso.</translation>
<translation id="5572851009514199876">Accedi a Chrome per consentire al browser di verificare che tu sia autorizzato ad accedere a questo sito.</translation>
<translation id="5580958916614886209">Controlla il mese di scadenza e riprova</translation>
+<translation id="5586446728396275693">Nessun indirizzo salvato</translation>
+<translation id="5595485650161345191">Modifica indirizzo</translation>
<translation id="560412284261940334">Gestione non supportata</translation>
<translation id="5610142619324316209">Verificare la connessione</translation>
<translation id="5610807607761827392">Puoi gestire carte e indirizzi nelle <ph name="BEGIN_LINK" />Impostazioni<ph name="END_LINK" />.</translation>
@@ -507,15 +564,18 @@
<translation id="5622887735448669177">Vuoi uscire da questo sito?</translation>
<translation id="5629630648637658800">Caricamento delle impostazioni criterio non riuscito</translation>
<translation id="5631439013527180824">Token di gestione del dispositivo non valido</translation>
+<translation id="5633066919399395251">Gli utenti malintenzionati attualmente presenti sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero cercare di installare sul tuo computer programmi pericolosi che carpiscono o eliminano le tue informazioni (ad esempio, foto, password, messaggi e carte di credito). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Posizione</translation>
+<translation id="5659593005791499971">Email</translation>
<translation id="5669703222995421982">Ricevi contenuti suggeriti appositamente per te</translation>
<translation id="5675650730144413517">La pagina non funziona</translation>
-<translation id="5677928146339483299">Bloccati</translation>
-<translation id="5694783966845939798">Hai tentato di accedere a <ph name="DOMAIN" />, tuttavia il server ha presentato un certificato firmato utilizzando un algoritmo di firma debole (ad esempio, SHA-1). Ciò significa che le credenziali di sicurezza presentate dal server potrebbero essere state falsificate e il server potrebbe non essere quello previsto (è possibile che tu stia comunicando con un malintenzionato). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">L'identità di questo sito web non è stata verificata.</translation>
+<translation id="5713016350996637505">Contenuti ingannevoli bloccati</translation>
<translation id="5720705177508910913">Utente corrente</translation>
<translation id="5732392974455271431">I tuoi genitori possono sbloccarlo per te</translation>
<translation id="5763042198335101085">Inserisci un indirizzo email valido</translation>
<translation id="5765072501007116331">Seleziona un indirizzo per conoscere i requisiti e i metodi di consegna</translation>
+<translation id="5778550464785688721">Controllo completo di dispositivi MIDI</translation>
<translation id="5784606427469807560">Si è verificato un problema durante la conferma della carta. Controlla la connessione Internet e riprova.</translation>
<translation id="5785756445106461925">Inoltre, questa pagina include altre risorse che non sono sicure. Tali risorse possono essere visualizzate da altri durante il transito dei dati e possono essere modificate da un utente malintenzionato al fine di modificare l'aspetto della pagina.</translation>
<translation id="5786044859038896871">Vuoi inserire automaticamente i dati della carta?</translation>
@@ -524,14 +584,14 @@
<translation id="5813119285467412249">&amp;Ripeti aggiunta</translation>
<translation id="5814352347845180253">Potresti perdere l'accesso ai contenuti premium del sito <ph name="SITE" /> e di altri siti.</translation>
<translation id="5838278095973806738">Non dovresti inserire dati sensibili in questo sito (ad esempio password o carte di credito) perché potrebbero essere intercettati da utenti malintenzionati.</translation>
-<translation id="5843436854350372569">Hai tentato di accedere a <ph name="DOMAIN" />, tuttavia il server ha presentato un certificato contenente una chiave debole. Un malintenzionato potrebbe avere decifrato la chiave privata e il server potrebbe non essere quello previsto (è possibile che tu stia comunicando con un malintenzionato). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Impossibile raggiungere il sito</translation>
<translation id="5869522115854928033">Password salvate</translation>
<translation id="5872918882028971132">Suggerimenti per i genitori</translation>
<translation id="5901630391730855834">Giallo</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sincronizzati)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 in uso}other{# in uso}}</translation>
<translation id="5926846154125914413">Potresti perdere l'accesso ai contenuti premium di alcuni siti.</translation>
<translation id="5959728338436674663">Invia automaticamente a Google <ph name="BEGIN_WHITEPAPER_LINK" />alcune informazioni sul sistema e alcuni contenuti delle pagine<ph name="END_WHITEPAPER_LINK" /> per contribuire a rilevare app e siti pericolosi. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Settimana</translation>
<translation id="5967867314010545767">Rimuovi da cronologia</translation>
<translation id="5975083100439434680">Diminuisci lo zoom</translation>
<translation id="598637245381783098">Impossibile aprire l'app per i pagamenti</translation>
@@ -540,20 +600,28 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Pagina 1}other{Pagina #}}</translation>
<translation id="6017514345406065928">Verde</translation>
+<translation id="6017850046339264347">Gli utenti malintenzionati presenti sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero installare app ingannevoli che si spacciano per qualcos'altro o raccolgono dati che potrebbero essere usati per monitorare la tua attività. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sincronizzati)</translation>
<translation id="6027201098523975773">Inserisci un nome</translation>
<translation id="6040143037577758943">Chiudi</translation>
<translation id="6042308850641462728">Più</translation>
+<translation id="6047233362582046994">Se sei consapevole dei rischi per la tua sicurezza, potresti <ph name="BEGIN_LINK" />visitare questo sito<ph name="END_LINK" /> senza aspettare che vengano rimosse le app dannose.</translation>
+<translation id="6051221802930200923">Al momento non puoi visitare il sito web <ph name="SITE" /> perché utilizza il blocco dei certificati. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi.</translation>
<translation id="6060685159320643512">Attenzione, prova questi esperimenti a tuo rischio e pericolo</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{nessuna}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Hai raggiunto i contenuti utilizzando un certificato fornito dall'amministratore. I dati che fornisci a <ph name="DOMAIN" /> possono essere intercettati dal tuo amministratore.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Nessuna}=1{1 password (sincronizzata)}other{# password (sincronizzate)}}</translation>
<translation id="6146055958333702838">Controlla eventuali cavi e riavvia eventuali router, modem o altri dispositivi di rete in uso.</translation>
<translation id="614940544461990577">Prova a:</translation>
<translation id="6151417162996330722">Il certificato del server ha un periodo di validità troppo lungo.</translation>
<translation id="6157877588268064908">Seleziona un indirizzo per conoscere i requisiti e i metodi di spedizione</translation>
+<translation id="6158003235852588289">La funzione Navigazione sicura di Google ha rilevato di recente attività di phishing sul sito <ph name="SITE" />. I siti di phishing si spacciano per altri siti web per ingannarti.</translation>
<translation id="6165508094623778733">Ulteriori informazioni</translation>
+<translation id="6169916984152623906">Ora puoi navigare in privato. Le altre persone che usano questo dispositivo non vedranno le tue attività, ma i download e i preferiti verranno salvati.</translation>
<translation id="6177128806592000436">La tua connessione a questo sito non è protetta</translation>
<translation id="6184817833369986695">(coorte: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Controlla la connessione a Internet</translation>
<translation id="6218753634732582820">Rimuovere l'indirizzo da Chromium?</translation>
+<translation id="6221345481584921695">La funzione Navigazione sicura di Google ha <ph name="BEGIN_LINK" />rilevato malware<ph name="END_LINK" /> di recente sul sito <ph name="SITE" />. I siti web che in genere sono sicuri a volte vengono infettati da malware. I contenuti dannosi provengono da <ph name="SUBRESOURCE_HOST" />, un noto distributore di malware.</translation>
<translation id="6251924700383757765">Norme sulla privacy</translation>
<translation id="6254436959401408446">Impossibile aprire la pagina. Memoria insufficiente.</translation>
<translation id="625755898061068298">Hai scelto di disattivare gli avvisi di sicurezza per questo sito.</translation>
@@ -579,15 +647,14 @@
<translation id="6404511346730675251">Modifica preferito</translation>
<translation id="6410264514553301377">Inserisci la data di scadenza e il codice CVC della carta <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Hai chiesto ai tuoi genitori l'autorizzazione per visitare questo sito</translation>
-<translation id="6416403317709441254">Al momento non puoi visitare il sito <ph name="SITE" /> perché ha inviato credenziali criptate che Chromium non è in grado di elaborare. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe funzionare più tardi. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Impossibile controllare se il certificato è stato revocato.</translation>
<translation id="6433490469411711332">Modifica informazioni di contatto</translation>
<translation id="6433595998831338502">Connessione negata da <ph name="HOST_NAME" />.</translation>
<translation id="6446608382365791566">Aggiungi altre informazioni</translation>
+<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">Conferma reinvio modulo</translation>
<translation id="6456339708790392414">Il tuo pagamento</translation>
<translation id="6458467102616083041">Ignorato perché la ricerca predefinita è stata disattivata secondo la norma.</translation>
-<translation id="6462969404041126431">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere stato revocato. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Norme dispositivo</translation>
<translation id="6477321094435799029">Chrome ha rilevato un codice insolito su questa pagina e l'ha bloccata per proteggere le tue informazioni personali (ad esempio password, numeri di telefono e carte di credito).</translation>
<translation id="6489534406876378309">Avvia caricamento arresti anomali</translation>
@@ -599,20 +666,19 @@
<translation id="6556915248009097796">Scadenza: <ph name="EXPIRATION_DATE_ABBR" />, ultimo utilizzo: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Il tuo gestore non ha ancora approvato la richiesta</translation>
<translation id="6569060085658103619">È visualizzata la pagina di un'estensione</translation>
-<translation id="6593753688552673085">meno di <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Questi contenuti potrebbero cercare di installare sul tuo dispositivo software pericoloso che si impossessa delle tue informazioni o le elimina. <ph name="BEGIN_LINK" />Mostra comunque<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opzioni di crittografia</translation>
<translation id="662080504995468778">Rimani</translation>
<translation id="6626291197371920147">Aggiungi un numero di carta valido</translation>
<translation id="6628463337424475685">Ricerca <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Gli utenti malintenzionati attualmente presenti sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero cercare di installare sul tuo Mac programmi pericolosi che carpiscono o eliminano le tue informazioni (ad esempio, foto, password, messaggi e carte di credito). <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Questa norma è obsoleta.</translation>
-<translation id="6652240803263749613">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile dal sistema operativo del computer. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Rimuovere il suggerimento per i moduli da Chromium?</translation>
<translation id="6685834062052613830">Esci e completa la configurazione</translation>
<translation id="6710213216561001401">Indietro</translation>
<translation id="6710594484020273272">&lt;Digita un termine di ricerca&gt;</translation>
<translation id="6711464428925977395">Si è verificato un problema con il server proxy oppure l'indirizzo non è corretto.</translation>
<translation id="6727102863431372879">Imposta</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{nessuno}=1{1 elemento}other{# elementi}}</translation>
<translation id="674375294223700098">Errore sconosciuto del certificato del server.</translation>
<translation id="6753269504797312559">Valore norma</translation>
<translation id="6757797048963528358">Il dispositivo è entrato in modalità sospensione.</translation>
@@ -620,6 +686,8 @@
<translation id="6810899417690483278">ID personalizzazione</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Impossibile caricare i dati sull'area geografica</translation>
+<translation id="6825578344716086703">Hai tentato di accedere al sito <ph name="DOMAIN" />, ma il server ha presentato un certificato firmato utilizzando un algoritmo di firma debole (ad esempio SHA-1). Ciò significa che le credenziali di sicurezza presentate dal server potrebbero essere state falsificate e il server potrebbe non essere quello previsto (è possibile che tu stia comunicando con un malintenzionato).</translation>
+<translation id="6830728435402077660">Non sicuro</translation>
<translation id="6831043979455480757">Traduci</translation>
<translation id="6839929833149231406">Area</translation>
<translation id="6874604403660855544">&amp;Ripeti aggiunta</translation>
@@ -627,6 +695,7 @@
<translation id="6895330447102777224">La carta è stata confermata</translation>
<translation id="6897140037006041989">User-agent</translation>
<translation id="6915804003454593391">Utente:</translation>
+<translation id="6945221475159498467">Seleziona</translation>
<translation id="6948701128805548767">Seleziona un indirizzo per conoscere i requisiti e i metodi di ritiro</translation>
<translation id="6957887021205513506">Il certificato del server risulta essere un falso.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -635,15 +704,16 @@
<translation id="6973656660372572881">Sono stati specificati sia i server proxy fissi che un URL script .pac.</translation>
<translation id="6989763994942163495">Mostra impostazioni avanzate...</translation>
<translation id="7000990526846637657">Nessuna voce della cronologia trovata</translation>
-<translation id="7009986207543992532">Hai tentato di accedere a <ph name="DOMAIN" />, tuttavia il server ha presentato un certificato il cui periodo di validità è troppo lungo per essere considerato attendibile. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Il tuo account Google potrebbe avere altre forme di cronologia di navigazione all'indirizzo <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Password</translation>
+<translation id="7050187094878475250">Hai tentato di visitare il sito <ph name="DOMAIN" />, ma il server ha presentato un certificato con periodo di validità troppo lungo per poter essere ritenuto attendibile.</translation>
+<translation id="7053983685419859001">Blocca</translation>
<translation id="7064851114919012435">Informazioni di contatto</translation>
<translation id="7079718277001814089">Questo sito contiene malware</translation>
<translation id="7087282848513945231">Contea</translation>
-<translation id="7088615885725309056">Meno recente</translation>
<translation id="7090678807593890770">Cerca <ph name="LINK" /> con Google</translation>
+<translation id="7108819624672055576">Consentita da un'estensione</translation>
<translation id="7119414471315195487">Chiudi altri programmi o schede</translation>
<translation id="7129409597930077180">Impossibile spedire all'indirizzo specificato. Seleziona un indirizzo diverso.</translation>
<translation id="7138472120740807366">Metodo di consegna</translation>
@@ -661,22 +731,18 @@
<translation id="7220786058474068424">Elaborazione in corso</translation>
<translation id="724691107663265825">Il sito che stai per visitare contiene malware</translation>
<translation id="724975217298816891">Inserisci la data di scadenza e il codice CVC della carta <ph name="CREDIT_CARD" /> per aggiornare i relativi dettagli. Dopo essere stati confermati, i dettagli della carta saranno condivisi con questo sito.</translation>
-<translation id="725866823122871198">Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del computer (<ph name="DATE_AND_TIME" />) sono sbagliate.</translation>
+<translation id="7260504762447901703">Revoca accesso</translation>
<translation id="7275334191706090484">Preferiti gestiti</translation>
<translation id="7298195798382681320">Consigliate</translation>
<translation id="7309308571273880165">Rapporto sugli arresti anomali generato <ph name="CRASH_TIME" /> (caricamento richiesto dall'utente, ma non ancora eseguito)</translation>
<translation id="7334320624316649418">&amp;Ripeti ridisposizione</translation>
<translation id="733923710415886693">Il certificato del server non è stato reso pubblico tramite Certificate Transparency.</translation>
-<translation id="7351800657706554155">Al momento non puoi visitare il sito <ph name="SITE" /> perché il relativo certificato è stato revocato. In genere gli errori di rete e gli attacchi sono temporanei, pertanto questa pagina potrebbe riprendere a funzionare più tardi. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Riga di comando</translation>
<translation id="7372973238305370288">risultato della ricerca</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">No</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Conferma della carta</translation>
-<translation id="7394102162464064926">Vuoi eliminare queste pagine dalla tua cronologia?
-
-Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in incognito (<ph name="SHORTCUT_KEY" />).</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Percorso profilo</translation>
<translation id="7424977062513257142">Una pagina incorporata in questa pagina web dice:</translation>
@@ -684,6 +750,7 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="7444046173054089907">Questo sito è bloccato</translation>
<translation id="7445762425076701745">Impossibile convalidare completamente l'identità del server a cui sei collegato. Sei collegato a un server con un nome valido soltanto nella tua rete, di cui un'autorità di certificazione esterna non può convalidare in alcun modo la proprietà. Poiché alcune autorità di certificazione emettono comunque certificati per questi nomi, non è in alcun modo possibile garantire che tu sia collegato al sito web desiderato anziché a un sito dannoso.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Leggere ulteriori informazioni<ph name="END_LINK" /> sul problema.</translation>
+<translation id="7455133967321480974">Usa predefinita globale (Blocca)</translation>
<translation id="7460163899615895653">Le schede recenti di altri dispositivi sono mostrate qui</translation>
<translation id="7469372306589899959">Conferma della carta…</translation>
<translation id="7481312909269577407">Avanti</translation>
@@ -691,36 +758,43 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="7508255263130623398">L'ID dispositivo della norma restituito è vuoto o non corrisponde all'ID dispositivo corrente</translation>
<translation id="7514365320538308">Scarica</translation>
<translation id="7518003948725431193">Nessuna pagina web trovata per l'indirizzo web: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valore</translation>
<translation id="7537536606612762813">Obbligatoria</translation>
+<translation id="7542403920425041731">Dopo essere stati confermati, i dati della carta saranno condivisi con questo sito.</translation>
<translation id="7542995811387359312">La compilazione automatica della carta di credito è disattivata perché questo modulo non utilizza una connessione sicura.</translation>
<translation id="7543525346216957623">Chiedi a uno dei tuoi genitori</translation>
<translation id="7549584377607005141">Questa pagina web richiede dati che hai inserito in precedenza per poter essere visualizzata correttamente. Puoi inviare di nuovo i dati, ma in questo caso ripeterai l'azione precedentemente eseguita nella pagina.</translation>
<translation id="7552846755917812628">Prova i seguenti suggerimenti:</translation>
<translation id="7554791636758816595">Nuova scheda</translation>
+<translation id="7567204685887185387">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza potrebbe essere stato emesso in modo fraudolento. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> e <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> altro}other{<ph name="CONTACT_PREVIEW" /> e altri <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Questa pagina è in<ph name="ORIGINAL_LANGUAGE" />Vuoi tradurla?</translation>
<translation id="7569952961197462199">Rimuovere la carta di credito da Chrome?</translation>
<translation id="7569983096843329377">Nero</translation>
<translation id="7578104083680115302">Paga velocemente su siti e app su più dispositivi utilizzando le carte salvate su Google.</translation>
<translation id="7588950540487816470">Physical Web</translation>
<translation id="7592362899630581445">Il certificato del server vìola i vincoli relativi ai nomi.</translation>
+<translation id="7598391785903975535">Meno di <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> al momento non è in grado di gestire la richiesta.</translation>
<translation id="7600965453749440009">Non tradurre mai <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Il valore non è compreso nell'intervallo (<ph name="VALUE" />).</translation>
<translation id="7613889955535752492">Scadenza: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Hai già dati criptati con una versione diversa della password del tuo account Google. Inseriscila qui di seguito.</translation>
-<translation id="7634554953375732414">La tua connessione a questo sito non è privata.</translation>
<translation id="7637571805876720304">Rimuovere la carta di credito da Chromium?</translation>
<translation id="765676359832457558">Nascondi impostazioni avanzate...</translation>
<translation id="7658239707568436148">Annulla</translation>
+<translation id="7662298039739062396">Impostazione controllata da un'estensione</translation>
<translation id="7667346355482952095">Il token della norma restituito è vuoto o non corrisponde al token corrente</translation>
<translation id="7668654391829183341">Dispositivo sconosciuto</translation>
<translation id="7669271284792375604">I malintenzionati su questo sito potrebbero cercare di indurti con l'inganno a installare programmi che danneggiano la tua navigazione (ad esempio cambiando la tua pagina iniziale o mostrando annunci extra sui siti che visiti).</translation>
<translation id="7674629440242451245">Ti interessano le nuove e straordinarie funzioni di Chrome? Prova il nostro canale Dev all'indirizzo chrome.com/dev.</translation>
<translation id="7682287625158474539">Spedizione</translation>
+<translation id="7701040980221191251">Nessuno</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Procedi su <ph name="SITE" /> (non sicuro)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificato</translation>
+<translation id="7716147886133743102">Bloccata dall'amministratore</translation>
<translation id="7716424297397655342">Impossibile caricare il sito dalla cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Non gestito</translation>
<translation id="7755287808199759310">Il tuo genitore può sbloccarlo per te</translation>
<translation id="7758069387465995638">Il software antivirus o il firewall potrebbe avere bloccato la connessione.</translation>
@@ -747,15 +821,15 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="7951415247503192394">(a 32 bit)</translation>
<translation id="7956713633345437162">Preferiti su disp. mobili</translation>
<translation id="7961015016161918242">Mai</translation>
-<translation id="7962083544045318153">ID arresto anomalo: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Traduci sempre <ph name="ORIGINAL_LANGUAGE" /> in <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Non specificato</translation>
<translation id="800218591365569300">Prova a chiudere altri programmi o schede per liberare spazio in memoria.</translation>
<translation id="8012647001091218357">In questo momento, non è possibile raggiungere i tuoi genitori. Riprova.</translation>
<translation id="8025119109950072390">I malintenzionati su questo sito potrebbero indurti con l'inganno a effettuare operazioni pericolose, come installare software o fornire i tuoi dati personali (ad esempio password, numeri di telefono o carte di credito).</translation>
-<translation id="803030522067524905">La funzione Navigazione sicura di Google di recente ha rilevato phishing sul sito <ph name="SITE" />. I siti di phishing fingono di essere altri siti web per ingannarti. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Questa pagina è in <ph name="SOURCE_LANGUAGE" />. Tradurla in <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Chiedi (predefinita)</translation>
<translation id="8041089156583427627">Invia feedback</translation>
+<translation id="8041940743680923270">Usa predefinita globale (Chiedi)</translation>
<translation id="8088680233425245692">Impossibile visualizzare l'articolo.</translation>
<translation id="8089520772729574115">meno di 1 MB</translation>
<translation id="8091372947890762290">Attivazione in attesa sul server</translation>
@@ -764,13 +838,14 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="8134994873729925007">Impossibile trovare l'<ph name="BEGIN_ABBR" />indirizzo DNS<ph name="END_ABBR" /> del server <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Il computer è entrato in modalità sospensione.</translation>
<translation id="8150722005171944719">Il file all'indirizzo <ph name="URL" /> non è leggibile. Potrebbe essere stato rimosso, spostato oppure delle autorizzazioni del file potrebbero impedire l'accesso.</translation>
+<translation id="8184538546369750125">Usa predefinita globale (Consenti)</translation>
+<translation id="8191494405820426728">ID arresto anomalo locale: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Annulla spostamento</translation>
<translation id="8201077131113104583">URL di aggiornamento non valido per l'estensione con ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Riepilogo dell’ordine</translation>
<translation id="8218327578424803826">Posizione assegnata:</translation>
<translation id="8225771182978767009">La persona che ha configurato il computer ha deciso di bloccare questo sito.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">I malintenzionati attualmente sul sito <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero tentare di installare sul tuo computer programmi pericolosi che scoprono o eliminano i tuoi dati (ad esempio foto, password, messaggi e carte di credito).</translation>
<translation id="8241707690549784388">La pagina a cui stai tentando di accedere utilizzava informazioni inserite da te. Tornando a quella pagina, è possibile che eventuali azioni che hai eseguito vengano ripetute. Continuare?</translation>
<translation id="8249320324621329438">Ultimo recupero:</translation>
<translation id="8253091569723639551">Indirizzo di fatturazione obbligatorio</translation>
@@ -778,6 +853,7 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="8289355894181816810">Contatta l'amministratore di rete se non sei sicuro del significato.</translation>
<translation id="8293206222192510085">Aggiunta preferito</translation>
<translation id="8294431847097064396">Origine</translation>
+<translation id="8306404619377842860">Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del dispositivo (<ph name="DATE_AND_TIME" />) sono sbagliate. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">La traduzione non è riuscita a causa di un problema con la connessione di rete.</translation>
<translation id="8332188693563227489">Accesso a <ph name="HOST_NAME" /> negato</translation>
<translation id="834457929814110454">Se sei consapevole dei rischi per la tua sicurezza, potresti <ph name="BEGIN_LINK" />visitare questo sito<ph name="END_LINK" /> senza aspettare che vengano rimossi i programmi pericolosi.</translation>
@@ -798,11 +874,9 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="8483780878231876732">Accedi a Chrome per usare le carte memorizzate nel tuo account Google</translation>
<translation id="8488350697529856933">Si applica a</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ha impiegato troppo tempo a rispondere.</translation>
-<translation id="852346902619691059">Questo server non è riuscito a verificare che si tratti di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile dal sistema operativo del dispositivo. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione. <ph name="BEGIN_LEARN_MORE_LINK" />Ulteriori informazioni<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Anno di scadenza</translation>
<translation id="8543181531796978784">Puoi <ph name="BEGIN_ERROR_LINK" />segnalare un problema di rilevamento<ph name="END_ERROR_LINK" /> oppure, se sei consapevole dei rischi per la tua sicurezza, <ph name="BEGIN_LINK" />visita questo sito non sicuro<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">La traduzione non è riuscita perché non è stato possibile determinare la lingua della pagina.</translation>
-<translation id="8559762987265718583">Impossibile stabilire una connessione privata con il sito <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> perché data e ora del dispositivo (<ph name="DATE_AND_TIME" />) sono sbagliate.</translation>
<translation id="8571890674111243710">Traduzione della pagina in <ph name="LANGUAGE" /> in corso...</translation>
<translation id="858637041960032120">Aggiungi telefono</translation>
<translation id="859285277496340001">Il certificato non specifica un meccanismo per il controllo della sua revoca.</translation>
@@ -816,6 +890,7 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="8738058698779197622">Per poter stabilire una connessione protetta, l'orologio deve essere impostato correttamente perché i certificati utilizzati dai siti web per identificarsi sono validi soltanto per determinati periodi di tempo. L'orologio del dispositivo è sbagliato, pertanto Chromium non può verificare i certificati.</translation>
<translation id="8740359287975076522">Impossibile trovare l'&lt;abbr id="dnsDefinition"&gt;indirizzo DNS&lt;/abbr&gt; di <ph name="HOST_NAME" />. Stiamo analizzando il problema.</translation>
<translation id="8759274551635299824">La carta è scaduta</translation>
+<translation id="8761567432415473239">La funzione Navigazione sicura di Google <ph name="BEGIN_LINK" />ha trovato di recente programmi dannosi<ph name="END_LINK" /> su <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Ripeti eliminazione</translation>
<translation id="8800988563907321413">I suggerimenti Qui vicino vengono visualizzati qui</translation>
<translation id="8820817407110198400">Preferiti</translation>
@@ -828,29 +903,30 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="8870413625673593573">Chiusi di recente</translation>
<translation id="8874824191258364635">Inserisci un numero di carta di credito valido</translation>
<translation id="8876793034577346603">Analisi della configurazione di rete non riuscita.</translation>
-<translation id="8877192140621905067">Dopo essere stati confermati, i dettagli della carta saranno condivisi con questo sito</translation>
<translation id="8889402386540077796">Tonalità</translation>
<translation id="8891727572606052622">Modalità proxy non valida.</translation>
<translation id="889901481107108152">Spiacenti, questo esperimento non è disponibile sulla tua piattaforma.</translation>
<translation id="8903921497873541725">Aumenta lo zoom</translation>
<translation id="8931333241327730545">Vuoi salvare la scheda nel tuo account Google?</translation>
<translation id="8932102934695377596">L'orologio è indietro</translation>
-<translation id="8954894007019320973">(Continua)</translation>
<translation id="8971063699422889582">Il certificato del server è scaduto.</translation>
<translation id="8986494364107987395">Invia automaticamente a Google statistiche sull'utilizzo e rapporti sugli arresti anomali</translation>
-<translation id="8987927404178983737">Mese</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Il sito che stai per visitare contiene programmi dannosi</translation>
+<translation id="8997023839087525404">Il server ha presentato un certificato che non è stato reso pubblico tramite le norme di Certificate Transparency, la cui applicazione costituisce un requisito di alcuni certificati al fine di garantire la loro attendibilità nonché la sicurezza nei confronti dei malintenzionati.</translation>
<translation id="9001074447101275817">Il proxy <ph name="DOMAIN" /> richiede un nome utente e una password.</translation>
+<translation id="9005998258318286617">Impossibile caricare il documento PDF.</translation>
<translation id="901974403500617787">I contrassegni che si applicano a livello di sistema possono essere impostati solo dal proprietario: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Indirizzo di fatturazione della carta obbligatorio</translation>
<translation id="9020542370529661692">Questa pagina è stata tradotta in <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Errore di sicurezza</translation>
<translation id="9038649477754266430">Utilizza un servizio di previsione per velocizzare il caricamento delle pagine</translation>
<translation id="9039213469156557790">Inoltre, questa pagina include altre risorse che non sono sicure. Tali risorse possono essere visualizzate da altri durante il transito dei dati e possono essere modificate da un utente malintenzionato al fine di modificare il comportamento della pagina.</translation>
-<translation id="9040185888511745258">I malintenzionati su <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> potrebbero cercare di indurti con l'inganno a installare programmi che danneggiano la tua navigazione (ad esempio cambiando la tua pagina iniziale o mostrando annunci extra sui siti che visiti).</translation>
+<translation id="9049981332609050619">Hai tentato di connetterti a <ph name="DOMAIN" />, ma il server ha presentato un certificato scaduto.</translation>
<translation id="9050666287014529139">Passphrase</translation>
<translation id="9065203028668620118">Modifica</translation>
<translation id="9068849894565669697">Seleziona colore</translation>
+<translation id="9069693763241529744">Bloccata da un'estensione</translation>
<translation id="9076283476770535406">Può includere contenuti per adulti</translation>
<translation id="9078964945751709336">Sono necessarie maggiori informazioni</translation>
<translation id="9103872766612412690"><ph name="SITE" /> in genere utilizza la crittografia per proteggere le tue informazioni. Questa volta, quando Chromium ha provato a connettersi a <ph name="SITE" />, il sito web ha restituito credenziali insolite e sbagliate. È possibile che un malintenzionato stia cercando di spacciarsi per il sito <ph name="SITE" /> oppure che una schermata di accesso alla rete Wi-Fi abbia interrotto la connessione. Le tue informazioni sono ancora al sicuro perché Chromium ha interrotto la connessione prima che avvenissero scambi di dati.</translation>
@@ -859,16 +935,21 @@ Psst! La prossima volta potrebbe esserti utile la modalità di navigazione in in
<translation id="9148507642005240123">&amp;Annulla modifica</translation>
<translation id="9154194610265714752">Aggiornato</translation>
<translation id="9157595877708044936">Configurazione in corso...</translation>
+<translation id="9169664750068251925">Blocca sempre su questo sito</translation>
<translation id="9170848237812810038">&amp;Annulla</translation>
<translation id="917450738466192189">Il certificato del server non è valido.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> e <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> altra}other{<ph name="SHIPPING_OPTION_PREVIEW" /> e altre <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> utilizza un protocollo non supportato.</translation>
<translation id="9205078245616868884">I tuoi dati vengono criptati con la tua passphrase di sincronizzazione. Inseriscila per avviare la sincronizzazione.</translation>
<translation id="9207861905230894330">Impossibile aggiungere l'articolo.</translation>
+<translation id="9219103736887031265">Immagini</translation>
<translation id="933612690413056017">Connessione Internet assente</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CANCELLA MODULO</translation>
<translation id="939736085109172342">Nuova cartella</translation>
<translation id="941721044073577244">Sembra che tu non sia autorizzato a visitare questo sito</translation>
<translation id="969892804517981540">Build ufficiale</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Nessuno}=1{1 elemento}other{# elementi}}</translation>
<translation id="988159990683914416">Build</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_iw.xtb b/chromium/components/strings/components_strings_iw.xtb
index 974914f8c34..291fded5a0b 100644
--- a/chromium/components/strings/components_strings_iw.xtb
+++ b/chromium/components/strings/components_strings_iw.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">סובב בכיוון השעון</translation>
<translation id="1038842779957582377">×©× ×œ× ×™×“×•×¢</translation>
<translation id="1050038467049342496">סגירת ×™×™×©×•×ž×™× ×חרי×</translation>
-<translation id="1053591932240354961">â€×œ× ניתן לבקר עכשיו ב×תר <ph name="SITE" /> מכיוון ×©×”×•× ×©×œ×— ××™×©×•×¨×™× ×œ× ×ª×§×™× ×™× ×©-Google Chrome ×ינו יכול לעבד. שגי×ות רשת ותקיפות נמשכות בדרך כלל זמן מוגבל, ולכן סביר להניח שדף ×–×” יחזור לפעול מ×וחר יותר. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;ביטול הוספה</translation>
<translation id="10614374240317010">×¤×¨×™×˜×™× ×©××£ ×¤×¢× ×œ× × ×©×ž×¨×•</translation>
<translation id="106701514854093668">סימניות שולחן עבודה</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">המטמון של המדיניות תקין</translation>
<translation id="113188000913989374"><ph name="SITE" /> ×ומר:</translation>
<translation id="1132774398110320017">â€×”גדרות מילוי ×וטומטי של Chrome...</translation>
+<translation id="1150979032973867961">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />. ×ישור ×”×בטחה שלו ×œ× × ×—×©×‘ כמהימן על ידי מערכת ההפעלה של המחשב. ייתכן שהסיבה לכך ×”×™× ×ª×¦×•×¨×” שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
+<translation id="1151972924205500581">נדרשת סיסמה</translation>
<translation id="1152921474424827756">גש ×ל <ph name="BEGIN_LINK" />עותק בקובץ שמור<ph name="END_LINK" /> של <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> סגר ×ת החיבור ב×ופן בלתי צפוי.</translation>
<translation id="1161325031994447685">â€×œ×”תחבר מחדש ×ל ×”-Wi-Fi</translation>
+<translation id="1165039591588034296">שגי××”</translation>
<translation id="1175364870820465910">הדפס...</translation>
<translation id="1181037720776840403">הסר</translation>
<translation id="1184214524891303587">â€<ph name="BEGIN_WHITEPAPER_LINK" />שלח ב×ופן ×וטומטי<ph name="END_WHITEPAPER_LINK" /> ×ל Google דיווח על בעיות ×בטחה ×פשריות. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">עוד מ×תר ×–×”</translation>
<translation id="1206967143813997005">חתימה ר×שונית ×œ× ×—×•×§×™×ª</translation>
<translation id="1209206284964581585">הסתר בינתיי×</translation>
+<translation id="121201262018556460">ניסית להגיע ×ל <ph name="DOMAIN" />, ×ך השרת הציג ×ישור המכיל מפתח חלש. ייתכן שתוקף פרץ ×ת המפתח הפרטי, והשרת ×ינו השרת שרצית (ייתכן ש×תה מתקשר ×¢× ×ª×•×§×£).</translation>
<translation id="1219129156119358924">×בטחת מערכת</translation>
<translation id="1227224963052638717">מדיניות ×œ× ×™×“×•×¢×”.</translation>
<translation id="1227633850867390598">הסתר ערך</translation>
<translation id="1228893227497259893">מזהה יישות שגוי</translation>
<translation id="1232569758102978740">×œ×œ× ×©×</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (מסונכרני×)</translation>
<translation id="1263231323834454256">רשימת קרי××”</translation>
<translation id="1264126396475825575">דוח הקריסה תועד ב-<ph name="CRASH_TIME" /> (עדיין ×œ× ×”×¢×œ×™×ª ×ותו ×ו בחרת ×œ×”×ª×¢×œ× ×ž×ž× ×•)</translation>
+<translation id="1281526147609854549">הונפק על-ידי <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">תוכן מסוכן נחס×</translation>
<translation id="1285320974508926690">×œ×¢×•×œ× ×ל ×ª×ª×¨×’× ×תר ×–×”</translation>
<translation id="129553762522093515">נסגרו ל×חרונה</translation>
<translation id="129863573139666797">â€<ph name="BEGIN_LINK" />נסה לנקות ×ת קובצי ×”-Cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">הפעילות שלך <ph name="BEGIN_EMPHASIS" />עדיין עשויה להיות מוצגת<ph name="END_EMPHASIS" /> בפני:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />××ª×¨×™× ×©××œ×™×”× × ×›× ×¡×ª
+ <ph name="LIST_ITEM" />המעסיק שלך ×ו בית הספר
+ <ph name="LIST_ITEM" />ספק ×”×ינטרנט שלך
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">דומיין הרשמה:</translation>
<translation id="1340482604681802745">כתובת ×יסוף</translation>
<translation id="1344211575059133124">נר××” ש×תה זקוק להרש××” כדי לבקר ב×תר ×”×–×”</translation>
<translation id="1344588688991793829">â€×”גדרות מילוי ×וטומטי של Chromium...</translation>
+<translation id="1348198688976932919">×”×תר ש×תה עומד לעבור ×ליו מכיל ×™×™×©×•×ž×™× ×ž×¡×•×›× ×™×</translation>
<translation id="1374468813861204354">הצעות</translation>
<translation id="1375198122581997741">מידע על הגרסה</translation>
<translation id="1377321085342047638">מספר כרטיס</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ×œ× ×©×œ×— נתוני×.</translation>
<translation id="1407135791313364759">פתח הכל</translation>
<translation id="1413809658975081374">שגי×ת פרטיות</translation>
+<translation id="14171126816530869">זהות <ph name="ORGANIZATION" /> ב-<ph name="LOCALITY" /> ×ומתה על ידי <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">כן</translation>
<translation id="1430915738399379752">הדפס</translation>
-<translation id="1442912890475371290">× ×—×¡× × ×™×¡×™×•×Ÿ <ph name="BEGIN_LINK" /> לביקור בדף ב-<ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">×œ× × ×™×ª×Ÿ לבקר עכשיו ב×תר <ph name="SITE" /> מכיוון ×©×”×•× ×ž×©×ª×ž×© בהצמדת ×ישורי×. שגי×ות רשת ותקיפות מתרחשות בדרך כלל לזמן מוגבל, ולכן סביר להניח שדף ×–×” יחזור לפעול מ×וחר יותר. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> נוסף}two{<ph name="PAYMENT_METHOD_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> נוספי×}many{<ph name="PAYMENT_METHOD_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> נוספי×}other{<ph name="PAYMENT_METHOD_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> נוספי×}}</translation>
<translation id="1506687042165942984">הצג עותק שמור (כלומר, ידוע ×©×”×•× ×¢×“×›× ×™) של הדף ×”×–×”.</translation>
<translation id="1517433312004943670">יש צורך במספר טלפון</translation>
<translation id="1519264250979466059">â€×ª×ריך ×”-Build</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">â€JavaScript צריך להיות מופעל כדי להשתמש בתכונה זו.</translation>
<translation id="1555130319947370107">כחול</translation>
<translation id="1559528461873125649">×ין קובץ ×ו ספרייה ×‘×©× ×–×”</translation>
-<translation id="1559572115229829303">â€&lt;p&gt;×œ× × ×™×ª×Ÿ ליצור חיבור פרטי ×ל <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ×ž×©×•× ×©×”×ª×ריך והשעה במכשיר שלך (<ph name="DATE_AND_TIME" />) שגויי×.&lt;/p&gt;
-
- &lt;p&gt;שנה ×ת הת×ריך והשעה בקטע &lt;strong&gt;כללי&lt;/strong&gt; ב×פליקציה &lt;strong&gt;הגדרות&lt;/strong&gt;â€.&lt;/p&gt;</translation>
<translation id="1583429793053364125">משהו השתבש בעת הצגת דף ×ינטרנט ×–×”.</translation>
<translation id="1592005682883173041">גישה ×œ× ×ª×•× ×™× ×ž×§×•×ž×™×™×</translation>
+<translation id="1594030484168838125">בחר</translation>
<translation id="161042844686301425">צי×ן</translation>
+<translation id="1620510694547887537">מצלמה</translation>
<translation id="1629803312968146339">â€×”×× ×ª×¨×¦×” ש-Chrome ישמור ×ת הכרטיס ×”×–×”?</translation>
<translation id="1639239467298939599">טוען</translation>
<translation id="1640180200866533862">מדיניות משתמשי×</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">תצורת הרשת ××™× ×” חוקית ×•×œ× × ×™×ª×Ÿ ×œ×™×™×‘× ×ותה.</translation>
<translation id="1644574205037202324">היסטוריה</translation>
<translation id="1645368109819982629">פרוטוקול ×œ× × ×ª×ž×š</translation>
+<translation id="1655462015569774233">{1,plural, =1{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג ×תמול. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר כעת בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”.}two{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג לפני יומיי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר כעת בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”.}many{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג לפני # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר כעת בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”.}other{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג לפני # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר כעת בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”.}}</translation>
<translation id="1656489000284462475">×יסוף</translation>
<translation id="1663943134801823270">â€×”×›×¨×˜×™×¡×™× ×•×”×›×ª×•×‘×•×ª × ×œ×§×—×™× ×ž-Chrome. ×פשר לנהל ××•×ª× ×‘<ph name="BEGIN_LINK" />הגדרות<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">â€×”×תר <ph name="SITE" /> משתמש בדרך כלל בהצפנה כדי להגן על המידע שלך. ×›×שר Google Chrome ניסה ×”×¤×¢× ×œ×”×ª×—×‘×¨ ל-<ph name="SITE" />, ×”×תר שלח חזרה ××™×©×•×¨×™× ×—×¨×™×’×™× ×•×©×’×•×™×™×. ייתכן שתוקף מנסה להתחזות ל×תר <ph name="SITE" />, ×ו שמסך כניסה ל-Wi-Fi הפריע לחיבור. המידע שלך עדיין מ×ובטח מכיוון ש-Google Chrome הפסיק ×ת החיבור לפני חילופי הנתוני×.</translation>
-<translation id="168328519870909584">×ª×•×§×¤×™× ×”× ×ž×¦××™× ×›×¢×ª ב-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×©×•×™×™× ×œ× ×¡×•×ª להתקין במכשיר שלך ×פליקציות מסוכנות שגונבות ×ו מוחקות מידע (לדוגמה, תמונות, סיסמ×ות, הודעות וכרטיסי ×שר××™).</translation>
<translation id="168841957122794586">×ישור השרת מכיל מפתח הצפנה חלש.</translation>
+<translation id="1706954506755087368">{1,plural, =1{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק מחר. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך.}two{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק בעוד יומיי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך.}many{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק בעוד # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך.}other{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק בעוד # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך.}}</translation>
<translation id="1710259589646384581">מערכת הפעלה</translation>
<translation id="1721312023322545264">עליך לפנות ×ל <ph name="NAME" /> לקבלת הרש××” לביקור ב×תר ×”×–×”</translation>
<translation id="1721424275792716183">* זהו שדה חובה</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">הורד ×ת הדף מ×וחר יותר</translation>
<translation id="17513872634828108">כרטיסיות פתוחות</translation>
<translation id="1753706481035618306">מספר דף</translation>
+<translation id="1763864636252898013">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />. ×ישור ×”×בטחה שלו ×œ× × ×—×©×‘ כמהימן על ידי מערכת ההפעלה של המכשיר. ייתכן שהסיבה לכך ×”×™× ×ª×¦×•×¨×” שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
<translation id="1768211456781949159">â€<ph name="BEGIN_LINK" />נסה להפעיל ×ת ×בחון הרשת של Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">עדכן ×ת משפט-הסיסמה של הסינכרון.</translation>
<translation id="1787142507584202372">×›×ן מופיעות הכרטיסיות ש×תה פותח</translation>
+<translation id="1789575671122666129">חלונות קופצי×</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">×©× ×‘×¢×œ הכרטיס</translation>
-<translation id="1803678881841855883">â€×’לישה בטוחה של Google <ph name="BEGIN_LINK" />זיהתה ל×חרונה תוכנה זדונית<ph name="END_LINK" /> ב-<ph name="SITE" />. ×œ×¢×™×ª×™× ×§×•×¨×” ש××ª×¨×™× ×‘×˜×•×—×™× × ×“×‘×§×™× ×‘×ª×•×›× ×” זדונית. מקור התוכן הזדוני ×”×•× <ph name="SUBRESOURCE_HOST" />. זהו מפיץ ידוע של תוכנה זדונית. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">ת×ריך הוספה: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">הבקשה ×ו ×”×¤×¨×ž×˜×¨×™× ×©×œ הבקשה ××™× × ×—×•×§×™×™×</translation>
<translation id="1826516787628120939">מתבצעת בדיקה</translation>
<translation id="1834321415901700177">×”×תר ×”×–×” מכיל תוכניות מזיקות</translation>
+<translation id="1840414022444569775">מספר הכרטיס ×”×–×” כבר × ×ž×¦× ×‘×©×™×ž×•×©</translation>
<translation id="1842969606798536927">של×</translation>
<translation id="1871208020102129563">â€×©×¨×ª ×”-Proxy מוגדר להשתמש בשרתי Proxy קבועי×, ×œ× ×‘×›×ª×•×‘×ª ×תר של סקריפט ‎.Pac</translation>
<translation id="1871284979644508959">שדה חובה</translation>
<translation id="187918866476621466">פתח דפי פתיחה</translation>
<translation id="1883255238294161206">כווץ רשימה</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספת}two{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספות}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספות}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> נוספות}}</translation>
<translation id="1898423065542865115">סינון</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{לל×}=1{×תר ×חד}two{שני ×תרי×}many{# ×תרי×}other{# ×תרי×}}</translation>
<translation id="194030505837763158">עבור ל-<ph name="LINK" /></translation>
<translation id="1962204205936693436">סימניות של <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">שגי××” בעריכה בסידרה</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">המערכת התעלמה ×ž×©×•× ×©×”×ž×“×™× ×™×•×ª בוטלה על ידי <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">מחפש ×“×¤×™× ×©×œ ×”×ינטרנט הווירטופיזי בקרבת מקו×</translation>
<translation id="213826338245044447">סימניות לנייד</translation>
-<translation id="2148716181193084225">היו×</translation>
+<translation id="2147827593068025794">סינכרון ברקע</translation>
<translation id="2154054054215849342">סנכרון ×ינו זמין בדומיין שלך</translation>
<translation id="2154484045852737596">עריכת כרטיס</translation>
<translation id="2166049586286450108">גישה מל××” של מנהל המערכת</translation>
<translation id="2166378884831602661">×תר ×–×” ×œ× ×™×›×•×œ לספק חיבור מ×ובטח</translation>
<translation id="2181821976797666341">מדיניות</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{כתובת ×חת}two{שתי כתובות}many{# כתובות}other{# כתובות}}</translation>
+<translation id="2187317261103489799">זהה (ברירת מחדל)</translation>
<translation id="2202020181578195191">עליך להזין שנת תפוגה חוקית</translation>
<translation id="2212735316055980242">×œ× × ×ž×¦××” מדיניות</translation>
<translation id="2213606439339815911">מ×חזר רשומות...</translation>
+<translation id="2218879909401188352">×ª×•×§×¤×™× ×©×ž×©×ª×ž×©×™× ×¢×›×©×™×• ב-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×œ×•×œ×™× ×œ×”×ª×§×™×Ÿ ×™×™×©×•×ž×™× ×ž×¡×•×›× ×™× ×•×œ×’×¨×•× × ×–×§ למכשיר שלך, להגדיל ×ת ×”×—×™×•×‘×™× ×©×œ×š על החבילה לנייד ×ו לגנוב ×ת המידע ×”×ישי שלך. <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">תקן ×ת החיבור ב×מצעות <ph name="BEGIN_LINK" />×פליקציית הבדיקה<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">שלח עכשיו</translation>
<translation id="225207911366869382">ערך ×–×” ×”×•×¦× ×ž×©×™×ž×•×© עבור מדיניות זו.</translation>
<translation id="2262243747453050782">â€×©×’×™×ת HTTP</translation>
+<translation id="2270484714375784793">מספר טלפון</translation>
<translation id="2282872951544483773">× ×™×¡×•×™×™× ×œ× ×–×ž×™× ×™×</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{פריט <ph name="ITEM_COUNT" />}two{<ph name="ITEM_COUNT" /> פריטי×}many{<ph name="ITEM_COUNT" /> פריטי×}other{<ph name="ITEM_COUNT" /> פריטי×}}</translation>
<translation id="2292556288342944218">הגישה ל×ינטרנט חסומה</translation>
<translation id="230155334948463882">כרטיס חדש?</translation>
-<translation id="2305919008529760154">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ייתכן ש×ישור ×”×בטחה שלו מזויף. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> דורש ×©× ×ž×©×ª×ž×© וסיסמה.</translation>
-<translation id="2318774815570432836">â€×œ× ניתן לבקר עכשיו ב×תר <ph name="SITE" /> מכיוון ×©×”×•× ×ž×©×ª×ž×© ב-HSTSâ€. שגי×ות רשת ותקיפות מתרחשות בדרך כלל לזמן מוגבל, ולכן סביר להניח שדף ×–×” יחזור לפעול מ×וחר יותר. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">ההגדרה נשלטת על-ידי מנהל המערכת</translation>
<translation id="2354001756790975382">סימניות ×חרות</translation>
+<translation id="2354430244986887761">â€×”תכונה 'גלישה בטוחה' של Google <ph name="BEGIN_LINK" />מצ××” ל×חרונה ×™×™×©×•×ž×™× ×ž×–×™×§×™×<ph name="END_LINK" /> ב×תר <ph name="SITE" />.</translation>
<translation id="2355395290879513365">ייתכן ×©×ª×•×§×¤×™× ×™×•×›×œ×• לר×ות ×ת התמונות שבהן ×תה צופה ב×תר ×–×”, ול×חר מכן ×”× ×™× ×¡×• להונות ×ותך על ידי שינוי התמונות.</translation>
+<translation id="2356070529366658676">ש×ל</translation>
+<translation id="2359629602545592467">מטבעות מרובי×</translation>
<translation id="2359808026110333948">המשך</translation>
<translation id="2365563543831475020">דוח הקריסה שתועד ב-<ph name="CRASH_TIME" /> ×œ× ×”×•×¢×œ×”</translation>
<translation id="2367567093518048410">רמה</translation>
-<translation id="2371153335857947666">{1,plural, =1{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג ×תמול. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר עכשיו בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}two{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג לפני יומיי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר עכשיו בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}many{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג לפני # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר עכשיו בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}other{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; התוקף של ×ישור ×”×בטחה שלו פג לפני # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. הת×ריך המוגדר עכשיו בשעון המחשב שלך ×”×•× <ph name="CURRENT_DATE" />. ×”×× ×–×” נכון? ×× ×œ×, עליך לכוון ×ת שעון המערכת ול×חר מכן לרענן ×ת הדף ×”×–×”. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">×ין חלופות זמינות עבור ממשק המשתמש</translation>
<translation id="2384307209577226199">ברירת מחדל של ×רגון</translation>
<translation id="2386255080630008482">×ישור השרת נשלל.</translation>
<translation id="2392959068659972793">הצגת מדיניות ×œ×œ× ×¢×¨×š מוגדר</translation>
<translation id="239429038616798445">שיטת המשלוח הזו ×œ× ×–×ž×™× ×”. עליך לבחור שיטה ×חרת.</translation>
<translation id="2396249848217231973">&amp;ביטול מחיקה</translation>
-<translation id="2460160116472764928">â€×’לישה בטוחה של Google <ph name="BEGIN_LINK" />זיהתה ל×חרונה תוכנה זדונית<ph name="END_LINK" /> ב-<ph name="SITE" />. ×œ×¢×™×ª×™× ×§×•×¨×” ש××ª×¨×™× ×‘×˜×•×—×™× × ×“×‘×§×™× ×‘×ª×•×›× ×” זדונית. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />. ייתכן ש×ישור ×”×בטחה שלו בוטל. הסיבה לכך עשויה להיות הגדרה שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
<translation id="2463739503403862330">מל×</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />מפעיל ×ת ×בחון הרשת<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">כתובת ×תר ×œ× ×—×•×§×™×ª של חיפוש</translation>
+<translation id="2482878487686419369">התר×ות</translation>
<translation id="2491120439723279231">×ישור השרת מכיל שגי×ות.</translation>
<translation id="2495083838625180221">â€×ž× ×ª×— JSON</translation>
<translation id="2495093607237746763">â€×× ×”×פשרות תסומן, Chromium ישמור עותק של הכרטיס במכשיר ×”×–×” כדי ×œ×ž×œ× ×˜×¤×¡×™× ×‘×ž×”×™×¨×•×ª רבה יותר.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">חזור</translation>
<translation id="2515629240566999685">לבדוק ×ת ×”×ות ב×זור שלך</translation>
<translation id="2516305470678292029">חלופות לממשק משתמש</translation>
+<translation id="2539524384386349900">×–×”×”</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> שלח תגובה ×œ× ×—×•×§×™×ª.</translation>
-<translation id="2552545117464357659">חדש יותר</translation>
<translation id="2556876185419854533">&amp;ביטול עריכה</translation>
<translation id="2587730715158995865">מ-<ph name="ARTICLE_PUBLISHER" />. לקרי×ת כתבה זו ו-<ph name="OTHER_ARTICLE_COUNT" /> כתבות נוספות.</translation>
<translation id="2587841377698384444">â€×ž×–×”×” ממשק API של ספרייה:</translation>
<translation id="2597378329261239068">מסמך ×–×” מוגן ב×מצעות סיסמה. הזן סיסמה.</translation>
<translation id="2609632851001447353">ורי×ציות</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{לל×}=1{×פליקציה ×חת (1â€$)}=2{שתי ×פליקציות ($1, $2)}many{# ×פליקציות ($1, $2, $3)}other{# ×פליקציות ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">השעון שלך מקדי×</translation>
<translation id="2639739919103226564">סטטוס:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">הגישה לקובץ נדחתה</translation>
<translation id="2653659639078652383">שלח</translation>
<translation id="2666117266261740852">סגירת כרטיסיות ×ו ×™×™×©×•×ž×™× ×חרי×</translation>
+<translation id="2670429602441959756">â€×”דף ×”×–×” מכיל תכונות שעדיין ×ינן נתמכות ב-VR. ××™ ×פשר להיש×ר ×›×ן...</translation>
<translation id="2674170444375937751">×”×× ×תה בטוח שברצונך להסיר ×“×¤×™× ×לו מההיסטוריה שלך?</translation>
<translation id="2677748264148917807">צ×</translation>
-<translation id="269990154133806163">השרת הציג ×ישור ×©×œ× × ×—×©×£ ב×ופן ציבורי על פי מדיניות שקיפות ×”×ישורי×. החשיפה הזו ×”×™× ×“×¨×™×©×ª חובה בחלק מה×ישורי×, כדי להבטיח ×©×”× ×ž×”×™×ž× ×™× ×•×›×“×™ להגן מפני תוקפי×. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">רשימת קרי××”</translation>
<translation id="2704283930420550640">הערך ×œ× ×ª×•×× ×œ×¤×•×¨×ž×˜.</translation>
<translation id="2704951214193499422">â€×œ-Chromium ×ין כרגע ×פשרות ל×שר ×ת הכרטיס. נסה שוב מ×וחר יותר.</translation>
<translation id="2705137772291741111">העותק השמור (בקובץ השמור) של ×”×תר ×”×–×” ×”×™×” בלתי קרי×.</translation>
<translation id="2709516037105925701">מילוי ×וטומטי</translation>
-<translation id="2712118517637785082">ניסית להגיע ×ל <ph name="DOMAIN" />, ×ך ×”×ישור שהשרת הציג בוטל על-ידי המנפיק שלו. פירוש הדבר ×”×•× ×©×ין לתת ×מון ב×ישורי ×”×בטחה שהשרת הציג. ייתכן ש×תה מתקשר ×¢× ×ª×•×§×£. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">בקש רשות</translation>
<translation id="2713444072780614174">לבן</translation>
<translation id="2720342946869265578">קרוב</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">חסרה רשומת מכשיר</translation>
<translation id="2784949926578158345">החיבור עבר ×יפוס.</translation>
<translation id="2794233252405721443">×תר חסו×</translation>
+<translation id="2799020568854403057">×”×תר ש×תה עומד לעבור ×ליו מכיל ×™×™×©×•×ž×™× ×ž×–×™×§×™×</translation>
+<translation id="2803306138276472711">â€×œ×חרונה, 'גלישה בטוחה של Googleâ€' <ph name="BEGIN_LINK" />זיהתה תוכנה זדונית<ph name="END_LINK" /> ב×תר <ph name="SITE" />. ××ª×¨×™× ×©×‘×“×¨×š כלל × ×—×©×‘×™× ×œ×‘×˜×•×—×™× × ×“×‘×§×™× ×œ×¢×ª×™× ×‘×ª×•×›× ×” זדונית.</translation>
<translation id="2824775600643448204">סרגל חיפוש וכתובות</translation>
<translation id="2826760142808435982">החיבור מוצפן ומ×ומת ב×מצעות <ph name="CIPHER" /> ומשתמש ב-<ph name="KX" /> כמנגנון להחלפת מפתחות.</translation>
<translation id="2835170189407361413">נקה טופס</translation>
+<translation id="2856444702002559011">ייתכן ×©×ª×•×§×¤×™× ×ž× ×¡×™× ×œ×’× ×•×‘ ×ת ×”×¤×¨×˜×™× ×©×œ×š מה×תר <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (לדוגמה, סיסמ×ות, הודעות ×ו כרטיסי ×שר××™). <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">×ל תטען מחדש</translation>
<translation id="2900469785430194048">â€×זל הזיכרון הזמין ל-Google Chrome בניסיון להציג ×ת דף ×”×ינטרנט ×”×–×”.</translation>
<translation id="2909946352844186028">×ותר שינוי ברשת.</translation>
<translation id="2916038427272391327">סגירת תוכניות ×חרות</translation>
<translation id="2922350208395188000">×œ× × ×™×ª×Ÿ לבדוק ×ת ×ישור השרת.</translation>
<translation id="2928905813689894207">כתובת לחיוב</translation>
+<translation id="2941952326391522266">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />. ×ישור ×”×בטחה שלו ×”×•× ×ž-<ph name="DOMAIN2" />. ייתכן שהסיבה לכך ×”×™× ×ª×¦×•×¨×” שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
<translation id="2948083400971632585">â€× ×™×ª×Ÿ להשבית כל שרת proxy המוגדר לחיבור מדף ההגדרות.</translation>
<translation id="2955913368246107853">סגור ×ת חלונית החיפוש</translation>
<translation id="2958431318199492670">â€×ª×¦×•×¨×ª הרשת ××™× ×” תו×מת לתקן ONC. ייתכן ×©×—×œ×§×™× ×ž×”×ª×¦×•×¨×” ×œ× ×™×™×›×œ×œ×• בייבו×.</translation>
-<translation id="29611076221683977">â€×ª×•×§×¤×™× הנמצ××™× ×›×¢×ª ב-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×©×•×™×™× ×œ× ×¡×•×ª להתקין ב-Mac שלך תכניות מסוכנות שגונבות ×ו מוחקות מידע (לדוגמה, תמונות, סיסמ×ות, הודעות וכרטיסי ×שר××™).</translation>
<translation id="2966678944701946121">ת×ריך תפוגה: <ph name="EXPIRATION_DATE_ABBR" />, ת×ריך הוספה: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">â€×›×“×™ ליצור חיבור מ×ובטח, השעון צריך להיות מוגדר כהלכה. הסיבה לכך ×”×™× ×©×”××™×©×•×¨×™× ×©×‘××ž×¦×¢×•×ª× ××ª×¨×™× ×ž×–×”×™× ×ת ×¢×¦×ž× ×ª×§×¤×™× ×¨×§ למשך פרקי זמן מסוימי×. מ×חר שהשעון במכשיר שלך שגוי, Google Chrome ×œ× ×™×›×•×œ ל×מת ×ת ×”××™×©×•×¨×™× ×”×לה.</translation>
<translation id="2972581237482394796">&amp;בצע שנית</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">עליך להזין כתובת חוקית</translation>
<translation id="2986368408720340940">שיטת ×”×יסוף הזו ××™× ×” זמינה. עליך לבחור שיטה ×חרת.</translation>
<translation id="2991174974383378012">שיתוף ×¢× ×תרי×</translation>
+<translation id="2991571918955627853">â€× ×›×•×Ÿ לעכשיו ××™ ×פשר לבקר ב×תר <ph name="SITE" /> מ×חר שנעשה בו שימוש ב-HSTS. שגי×ות רשת ומתקפות הן בדרך כלל זמניות, כך שהדף ×”×–×” יחזור כנר××” לפעול מ×וחר יותר.</translation>
<translation id="3005723025932146533">הצג עותק שמור</translation>
<translation id="3008447029300691911">הזן ×ת קוד ×”×ימות של הכרטיס <ph name="CREDIT_CARD" />. ברגע שת×שר, פרטי הכרטיס שלך ישותפו ×¢× ×”×תר ×”×–×”.</translation>
<translation id="3010559122411665027">רשומה ברשימה "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">נחסמה ×וטומטית</translation>
<translation id="3024663005179499861">סוג המדיניות שגוי</translation>
<translation id="3032412215588512954">×”×× ×‘×¨×¦×•× ×š לטעון מחדש ×ת ×”×תר?</translation>
<translation id="3037605927509011580">×וי, ל×!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{לפחות פריט ×חד ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×}=1{פריט ×חד (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}two{שני ×¤×¨×™×˜×™× (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}many{# ×¤×¨×™×˜×™× (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}other{# ×¤×¨×™×˜×™× (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}}</translation>
<translation id="3041612393474885105">פרטי ×ישור</translation>
<translation id="3063697135517575841">â€Chrome ×œ× ×”×¦×œ×™×— ל×שר ×ת הכרטיס שלך הפע×. נסה שוב מ×וחר יותר.</translation>
<translation id="3064966200440839136">בחרת לצ×ת ממצב גלישה בסתר כדי ×œ×©×œ× ×‘×מצעות ×™×™×©×•× ×—×™×¦×•× ×™. להמשיך?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{לל×}=1{סיסמה ×חת}two{שתי סיסמ×ות}many{# סיסמ×ות}other{# סיסמ×ות}}</translation>
<translation id="3093245981617870298">×תה במצב ×œ× ×ž×§×•×•×Ÿ.</translation>
<translation id="3105172416063519923">מזהה נכס:</translation>
<translation id="3109728660330352905">×ין לך הרש××” להציג ×ת הדף ×”×–×”.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />נסה להפעיל ×ת ×בחון הקישוריות<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">פענוח התגובה נכשל</translation>
<translation id="3150653042067488994">שגי×ת שרת זמנית</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">â€×“×¤×™× ×©×תה מציג בכרטיסיות גלישה בסתר ×œ× ×™×™×©×רו בהיסטוריית הדפדפן, ב×חסון קובצי ×”-Cookie ×ו בהיסטוריית ×”×—×™×¤×•×©×™× ×œ×חר שתסגור ×ת כל כרטיסיות הגלישה בסתר. ×§×‘×¦×™× ×©×”×•×¨×“×ª ×ו סימניות שיצרת יישמרו.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">××™</translation>
+<translation id="317583078218509884">הגדרות חדשות של ×ישורי ×תר ייכנסו לתוקף ל×חר טעינה מחדש של הדף.</translation>
<translation id="3176929007561373547">â€×‘דוק ×ת הגדרות שרת ×”-proxy ×ו פנה למנהל הרשת
כדי ×œ×•×•×“× ×©×©×¨×ª ×”-proxy פועל. ×× ×ינך סבור שעליך
להשתמש בשרת proxy:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">פתיחת דף במצב גלישה בסתר</translation>
-<translation id="3202578601642193415">החדש ביותר</translation>
+<translation id="320323717674993345">בטל תשלו×</translation>
<translation id="3207960819495026254">מסומן בסימניה</translation>
+<translation id="3225919329040284222">השרת הציג ×ישור ש×ינו תו×× ×ת הציפיות המובנות. ציפיות ×לה נכללות עבור ×תרי ×ינטרנט ×ž×¡×•×™×ž×™× ×‘×¢×œ×™ ×בטחה גבוהה כדי להגן עליך.</translation>
<translation id="3226128629678568754">לחץ על לחצן הטעינה מחדש כדי לשלוח מחדש ×ת ×”× ×ª×•× ×™× ×”×“×¨×•×©×™× ×œ×˜×¢×™× ×ª הדף.</translation>
+<translation id="3227137524299004712">מיקרופון</translation>
<translation id="3228969707346345236">×”×ª×¨×’×•× × ×›×©×œ כיוון שהדף כבר ב<ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">הזן ×ת קוד ×”×ימות של הכרטיס <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">×–×”×” תמיד תוכן חשוב ב×תר ×–×”</translation>
<translation id="3254409185687681395">הוסף ×ת הדף לסימניות</translation>
<translation id="3270847123878663523">&amp;ביטול של שינוי סדר</translation>
<translation id="3282497668470633863">הוספה של ×”×©× ×”×ž×•×¤×™×¢ בכרטיס</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">הגדרות</translation>
<translation id="3345135638360864351">×œ× × ×™×ª×Ÿ ×”×™×” לשלוח ×ל <ph name="NAME" /> ×ת הבקשה שלך לגשת ל×תר ×”×–×”. נסה שוב.</translation>
<translation id="3355823806454867987">â€×©× ×” הגדרות שרת Proxy...</translation>
+<translation id="3361596688432910856">â€Chrome <ph name="BEGIN_EMPHASIS" />×œ× ×™×©×ž×•×¨<ph name="END_EMPHASIS" /> ×ת המידע הב×:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />היסטוריית הגלישה שלך
+ <ph name="LIST_ITEM" />קובצי Cookie ונתוני ×תרי×
+ <ph name="LIST_ITEM" />מידע שהוזן בטפסי×
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">שגי×ת שעון</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> ×¤×¨×™×˜×™× × ×•×¡×¤×™×...</translation>
<translation id="337363190475750230">ניהול התצורה בוטל</translation>
<translation id="3377188786107721145">שגי××” בניתוח המדיניות</translation>
<translation id="3380365263193509176">שגי××” ×œ× ×™×“×•×¢×”</translation>
<translation id="3380864720620200369">מספר לקוח:</translation>
<translation id="3391030046425686457">כתובת למשלוח</translation>
<translation id="3395827396354264108">שיטת ×יסוף</translation>
-<translation id="340013220407300675">ייתכן ×©×ª×•×§×¤×™× ×ž× ×¡×™× ×œ×’× ×•×‘ ×ת המידע שלך מ-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (לדוגמה: סיסמ×ות, הודעות ×ו כרטיסי ×שר××™).</translation>
<translation id="3422248202833853650">מומלץ לצ×ת מתוכניות ×חרות וכך לפנות ×ž×§×•× ×‘×–×™×›×¨×•×Ÿ.</translation>
<translation id="3422472998109090673">×œ× × ×™×ª×Ÿ לגשת כרגע ×ל <ph name="HOST_NAME" />.</translation>
+<translation id="3427092606871434483">התר (ברירת מחדל)</translation>
<translation id="3427342743765426898">&amp;ביצוע מחדש של עריכה</translation>
<translation id="3431636764301398940">שמור כרטיס זה במכשיר הנוכחי</translation>
<translation id="3435896845095436175">הפעל</translation>
<translation id="3447661539832366887">×”×‘×¢×œ×™× ×©×œ המכשיר ×”×–×” כיבה ×ת משחק הדינוז×ורי×.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">מרווח ×חזור:</translation>
<translation id="3462200631372590220">הסתר ×¤×¨×˜×™× ×ž×ª×§×“×ž×™×</translation>
<translation id="3467763166455606212">עליך לציין ×ת ×©× ×‘×¢×œ הכרטיס</translation>
<translation id="3478058380795961209">חודש פקיעת התוקף</translation>
<translation id="3479539252931486093">×”×× ×–×” קרה ב×ופן בלתי צפוי? <ph name="BEGIN_LINK" />ספר לנו על כך<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">×œ× ×¢×›×©×™×•</translation>
-<translation id="348000606199325318">מזהה קריסה <ph name="CRASH_LOCAL_ID" /> (מזהה שרת: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">×œ× ×”×¦×œ×—× ×• ליצור קשר ×¢× ×”×”×•×¨×” שלך. נסה שוב מ×וחר יותר.</translation>
<translation id="3528171143076753409">×ישור השרת ×ינו מהימן.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{לפחות פריט ×חד ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×}=1{פריט ×חד (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}two{שני ×¤×¨×™×˜×™× (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}many{# ×¤×¨×™×˜×™× (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}other{# ×¤×¨×™×˜×™× (×•×¤×¨×™×˜×™× × ×•×¡×¤×™× ×‘×ž×›×©×™×¨×™× ×ž×¡×•× ×›×¨× ×™×)}}</translation>
<translation id="3539171420378717834">שמור עותק של הכרטיס הזה במכשיר הזה</translation>
<translation id="3542684924769048008">השתמש בסיסמה עבור:</translation>
+<translation id="3545341443414427877">××™ ×פשר ליצור חיבור פרטי ל×תר <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, מ×חר שהת×ריך והשעה של המחשב שלך (<ph name="DATE_AND_TIME" />) ×œ× × ×›×•× ×™×. <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">הצפן ×ת כל ×”× ×ª×•× ×™× ×”×ž×¡×•× ×›×¨× ×™× ×‘×מצעות משפט הסיסמה שלך לסנכרון</translation>
-<translation id="3549761410225185768">עוד <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו נופק על-ידי <ph name="DOMAIN2" />. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">המנהל שלך יכול לבטל בשבילך ×ת החסימה</translation>
<translation id="3566021033012934673">החיבור שלך ×ינו פרטי</translation>
+<translation id="3569145463236695319">â€&lt;p&gt;××™ ×פשר ליצור חיבור פרטי ל×תר <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, מ×חר שהת×ריך והשעה של המכשיר שלך (<ph name="DATE_AND_TIME" />) ×œ× × ×›×•× ×™×.&lt;/p&gt;
+
+ &lt;p&gt;הת×× ×ת הת×ריך והשעה מהקטע &lt;strong&gt;כללי&lt;/strong&gt; של ×פליקציית ×”&lt;strong&gt;הגדרות&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">הוסף ש×</translation>
<translation id="3583757800736429874">&amp;ביצוע מחדש של העברה</translation>
<translation id="3586931643579894722">הסתר פרטי×</translation>
-<translation id="3587482841069643663">הכל</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">עליך להזין ת×ריך תפוגה חוקי</translation>
<translation id="36224234498066874">נקה נתוני גלישה...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">פרטי ×ישור</translation>
<translation id="3690164694835360974">ההתחברות ××™× ×” מ×ובטחת</translation>
<translation id="3693415264595406141">סיסמה:</translation>
-<translation id="3696411085566228381">לל×</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">טוען...</translation>
<translation id="3712624925041724820">×ין מספיק רישיונות</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159">â€<ph name="BEGIN_LINK" />לבדוק ×ת תצורת ×”-DNS, חומת ×”×ש ושרת ×”-Proxy<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">×× ×תה מבין ×ת ×”×¡×™×›×•× ×™× ×‘× ×•×’×¢ ל×בטחה שלך, תוכל <ph name="BEGIN_LINK" />להיכנס ל×תר ×œ× ×‘×˜×•×— ×–×”<ph name="END_LINK" /> לפני הסרת התכניות המסוכנות.</translation>
<translation id="3739623965217189342">קישור שהעתקת</translation>
+<translation id="3744899669254331632">â€×ינך יכול לבקר כרגע ב-<ph name="SITE" /> מפני שה×תר שלח פרטי כניסה ×ž×¢×•×¨×‘×œ×™× ×©-Chromium ×ינו יכול לעבד. שגי×ות רשת והתקפות הן בדרך כלל זמניות, לכן סביר להניח שדף ×–×” יפעל כהלכה בהמשך.</translation>
+<translation id="3748148204939282805">×ª×•×§×¤×™× ×‘×תר <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×œ×•×œ×™× ×œ×”×•× ×•×ª ×ותך כדי ×œ×’×¨×•× ×œ×š לבצע פעולות מסוכנות, כמו התקנת תוכנה ×ו חשיפת מידע ×ישי (לדוגמה, סיסמ×ות, מספרי טלפון ×ו כרטיסי ×שר××™). <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">×”×ª×¨×’×•× × ×›×©×œ עקב שגי×ת שרת.</translation>
<translation id="3759461132968374835">×œ× ×”×ª×§×‘×œ×• ×“×™×•×•×—×™× ×¢×œ קריסות ל×חרונה. קריסות שהתרחשו בזמן ש×פשרות הדיווח על קריסות היתה מושבתת ×œ× ×™×•×¤×™×¢×• ×›×ן.</translation>
+<translation id="3778403066972421603">â€×”×× ×‘×¨×¦×•× ×š לשמור ×ת הכרטיס בחשבון Google שלך ובמכשיר ×”×–×”?</translation>
+<translation id="3783418713923659662">מ×סטרק×רד</translation>
<translation id="3787705759683870569">ת×ריך תפוגה: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">â€×× ×תה משתמש בשרת Proxy...</translation>
<translation id="3828924085048779000">×ין ×פשרות להשתמש במשפט-סיסמה ריק.</translation>
-<translation id="3845539888601087042">מציג היסטוריה ×ž×”×ž×›×©×™×¨×™× ×©×‘×”× ×תה מחובר לחשבון. <ph name="BEGIN_LINK" />למידע נוסף<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">חזור</translation>
<translation id="3858027520442213535">עדכן ×ת הת×ריך והשעה</translation>
<translation id="3884278016824448484">מזהה מכשיר מתנגש</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">הבקשה שלך לגשת ל×תר ×”×–×” נשלחה ×ל <ph name="NAME" /></translation>
<translation id="3890664840433101773">הוספת כתובת ×ימייל</translation>
<translation id="3901925938762663762">תוקף הכרטיס פג</translation>
-<translation id="3933571093587347751">{1,plural, =1{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק מחר. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}two{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק בעוד יומיי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}many{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק בעוד # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}other{השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×מור להיכנס לתוקף רק בעוד # ימי×. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">â€×”טעינה של מסמך PDF נכשלה</translation>
+<translation id="3945915738023014686">מזהה דוח הקריסה שהועלה <ph name="CRASH_ID" /> (מזהה קריסה מקומי: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">â€×”שרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×œ× ×ž×¦×™×™×Ÿ ערכי Subject Alternative Name. ייתכן שהסיבה לכך ×”×™× ×ª×¦×•×¨×” שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
<translation id="3963721102035795474">מצב קור×</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{לל×}=1{מ×תר ×חד }two{משני ××ª×¨×™× }many{מ-# ××ª×¨×™× }other{מ-# ××ª×¨×™× }}</translation>
<translation id="397105322502079400">מחשב...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> חסו×</translation>
+<translation id="3987940399970879459">â€×¤×—ות מ-‎1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{דף ×ינטרנט קרוב ×חד}two{# דפי ×ינטרנט קרובי×}many{# דפי ×ינטרנט קרובי×}other{# דפי ×ינטרנט קרובי×}}</translation>
<translation id="4021036232240155012">â€DNS ×”×•× ×©×™×¨×•×ª הרשת ×©×ž×ª×¨×’× ×©× ×©×œ ×תר לכתובת ×”×ינטרנט שלו.</translation>
<translation id="4030383055268325496">&amp;ביטול הוספה</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">â€×ª×¦×•×¨×ª ×”-Proxy מוגדרת להשתמש בכתובת ×תר של סקריפט מסוג ‎.Pac ×•×œ× ×‘×©×¨×ª×™ Proxy קבועי×.</translation>
<translation id="4098354747657067197">זהירות, ×תר מטעה</translation>
<translation id="4103249731201008433">המספר הסידורי של המכשיר ×ינו חוקי</translation>
+<translation id="410351446219883937">הפעלה ×וטומטית</translation>
<translation id="4103763322291513355">â€×”יכנס לכתובת &lt;strong&gt;chrome://policy&lt;/strong&gt; כדי לר×ות רשימה של כתובות ××ª×¨×™× ×©× ×ž× ×¢×” ××œ×™×”× ×”×’×™×©×”, כמו ×’× ×ª×§× ×•× ×™× ××—×¨×™× ×©× ×כפו על ידי מנהל המערכת שלך.</translation>
-<translation id="4110615724604346410">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו מכיל שגי×ות. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">מגנטה</translation>
+<translation id="4116663294526079822">×פשר תמיד ב×תר ×–×”</translation>
<translation id="4117700440116928470">היקף המדיניות ×ינו נתמך.</translation>
-<translation id="4118212371799607889">â€×”שרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; Chromium ×ינו בוטח ב×ישור ×”×בטחה שלו. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{×חד נוסף}two{×©× ×™×™× × ×•×¡×¤×™×}many{# נוספי×}other{# נוספי×}}</translation>
<translation id="4130226655945681476">בדוק ×ת כבלי הרשת, ×ת ×”×ž×•×“× ×•×ת הנתב</translation>
+<translation id="413544239732274901">מידע נוסף</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">השתמש בברירת מחדל גלובלית (זיהוי)</translation>
+<translation id="4165986682804962316">הגדרות ×תרי×</translation>
<translation id="4169947484918424451">â€×”×× ×ª×¨×¦×” ש-Chromium ישמור ×ת הכרטיס ×”×–×”?</translation>
<translation id="4171400957073367226">חתימת ×ימות ×œ× ×—×•×§×™×ª</translation>
<translation id="4196861286325780578">&amp;ביצוע מחדש של העברה</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />לבדוק ×ת תצורת ×”×נטי-וירוס וחומת ×”×ש<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{לל×}=1{×פליקציה ×חת ($1)}=2{שתי ×פליקציות ($1, $2)}many{# ×פליקציות ($1, $2, $3)}other{# ×פליקציות ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">קריסה</translation>
+<translation id="422022731706691852">×ª×•×§×¤×™× ×‘×תר <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×œ×•×œ×™× ×œ×”×•× ×•×ª ×ותך כדי ×œ×’×¨×•× ×œ×š להתקין תוכנות שיפגעו בחוויית הגלישה שלך (למשל, על-ידי החלפת דף הבית ×ו הצגת מודעות נוספות ב××ª×¨×™× ×©×ª×™×›× ×¡ ×ליה×). <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />נסה להפעיל ×ת ×בחון הרשת<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">תקף</translation>
<translation id="4250431568374086873">החיבור שלך ל×תר ×”×–×” ×œ× ×ž×ובטח בצורה מל××”</translation>
<translation id="4250680216510889253">ל×</translation>
<translation id="425582637250725228">ייתכן ×©×”×©×™× ×•×™×™× ×©×‘×™×¦×¢×ª ×œ× ×™×™×©×ž×¨×•.</translation>
<translation id="4258748452823770588">חתימה שגויה</translation>
+<translation id="4265872034478892965">×ושרה על-ידי מנהל המערכת</translation>
<translation id="4269787794583293679">(×ין ×©× ×ž×©×ª×ž×©)</translation>
<translation id="4275830172053184480">הפעלת המכשיר מחדש</translation>
<translation id="4280429058323657511">, בתוקף עד <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">â€×”גלישה הבטוחה של Google <ph name="BEGIN_LINK" />מצ××” ל×חרונה תוכניות מזיקות<ph name="END_LINK" /> ב-<ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">הצעות להורי×</translation>
<translation id="4304224509867189079">היכנס</translation>
-<translation id="432290197980158659">השרת הציג ×ישור ש×ינו עומד בציפיות המובנות במערכת. הציפיות ×”×לה מוגדרות על מנת ל×פשר גישה רק ×ל ××ª×¨×™× ×‘×¢×œ×™ רמת ×בטחה גבוהה כדי לשמור על ביטחונך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">×—×¡×•× (ברירת מחדל)</translation>
<translation id="4325863107915753736">×œ× × ×™×ª×Ÿ ×”×™×” ×œ×ž×¦×•× ×ת הפריט</translation>
<translation id="4326324639298822553">בדוק ×ת ת×ריך התפוגה ונסה שוב</translation>
<translation id="4331708818696583467">×œ× ×ž×ובטח</translation>
<translation id="4356973930735388585">×ª×•×§×¤×™× ×‘×תר ×”×–×” ×¢×©×•×™×™× ×œ× ×¡×•×ª להתקין במחשב שלך תוכניות מסוכנות שגונבות ×ו מוחקות מידע שלך (לדוגמה: תמונות, סיסמ×ות, הודעות ופרטי כרטיסי ×שר××™).</translation>
<translation id="4372948949327679948">צפוי ערך מסוג <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">ניסית להשיג ×ת <ph name="DOMAIN" />, ×ך ×”×ישור שהשרת הציג בוטל על ידי המנפיק שלו. פירוש הדבר ש×ין כל ×פשרות לתת ×מון ב×ישורי ×”×בטחה שהשרת הציג. ייתכן ש×תה מתקשר ×¢× ×ª×•×§×£.</translation>
<translation id="4381091992796011497">×©× ×ž×©×ª×ž×©:</translation>
<translation id="4394049700291259645">השבת</translation>
<translation id="4406896451731180161">תוצ×ות חיפוש</translation>
+<translation id="4424024547088906515">â€×”שרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />. ×ישור ×”×בטחה שלו ×œ× × ×—×©×‘ כמהימן על ידי Chrome. ייתכן שהסיבה לכך ×”×™× ×ª×¦×•×¨×” שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ×œ× ×ישר ×ת ×ישור ההתחברות שלך, ×ו ×©×œ× ×¡×•×¤×§ ×ישור התחברות.</translation>
<translation id="443673843213245140">â€×”שימוש בשרת Proxy הושבת, ×ך צויינה תצורת שרת Proxy מפורשת.</translation>
-<translation id="4492190037599258964">תוצ×ות החיפוש עבור '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">שגי×ת ×ימות: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">לפנות ×ל מנהל המערכת</translation>
<translation id="450710068430902550">שיתוף ×¢× ×ž× ×”×œ מערכת</translation>
<translation id="4515275063822566619">â€×”×›×¨×˜×™×¡×™× ×•×”×›×ª×•×‘×•×ª ×œ×§×•×—×™× ×ž-Chrome ומחשבון Google שלך (<ph name="ACCOUNT_EMAIL" />). ×פשר לנהל ××•×ª× ×‘<ph name="BEGIN_LINK" />הגדרות<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">פרטי×</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">נסה להשבית ×ת התוספי×.</translation>
<translation id="457875822857220463">משלוח</translation>
<translation id="4587425331216688090">â€×”×× ×œ×”×¡×™×¨ ×ת הכתובת מ-Chrome?</translation>
-<translation id="4589078953350245614">ניסית להגיע ×ל <ph name="DOMAIN" />, ×ך השרת הציג ×ישור ×œ× ×—×•×§×™. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">החיבור שלך ×ל <ph name="DOMAIN" /> מוצפן ב×מצעות חבילת צופן מתקדמת.</translation>
<translation id="4594403342090139922">&amp;ביטול מחיקה</translation>
<translation id="4619615317237390068">כרטיסיות ×ž×ž×›×©×™×¨×™× ×חרי×</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו מכיל שגי×ות. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
+<translation id="4690462567478992370">הפסק להשתמש ב×ישור ×œ× ×—×•×§×™</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">החיבור נקטע</translation>
<translation id="4722547256916164131">â€<ph name="BEGIN_LINK" />מפעיל ×ת ×בחון הרשת של Windows<ph name="END_LINK" /></translation>
@@ -428,21 +479,24 @@
Del</translation>
<translation id="4800132727771399293">â€×‘דוק ×ת ת×ריך התפוגה ו×ת ×”-CVC ונסה שוב</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">â€×œ× ניתן לבקר כעת ב×תר <ph name="SITE" /> מכיוון שה×תר שלח ××™×©×•×¨×™× ×ž×©×•×‘×©×™× ×©-Google Chrome ×ינו יכול לעבד. שגי×ות רשת ותקיפות מתרחשות בדרך כלל לזמן מוגבל, כך שסביר להניח שהדף ×”×–×” יפעל מ×וחר יותר.</translation>
<translation id="4813512666221746211">שגי×ת רשת</translation>
<translation id="4816492930507672669">הת×מה לדף</translation>
<translation id="483020001682031208">×ין ×“×¤×™× ×©×œ ×”×ינטרנט הווירטופיזי ×©×–×ž×™× ×™× ×œ×”×¦×’×”</translation>
<translation id="4850886885716139402">הצג</translation>
<translation id="4854362297993841467">שיטת המסירה הזו ××™× ×” זמינה. עליך לבחור שיטה ×חרת.</translation>
<translation id="4858792381671956233">ש×לת ×ת ×”×”×•×¨×™× ×©×œ×š ×× ×תה יכול לגשת ל×תר ×”×–×”</translation>
+<translation id="4863764087567530506">ייתכן שהתוכן ×”×–×” ינסה להטעות ×ותך כדי ×œ×’×¨×•× ×œ×š להתקין תוכנות ×ו לחשוף מידע ×ישי. <ph name="BEGIN_LINK" />הצג בכל ×–×ת<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">חפש בהיסטוריה</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ועוד דף ×ינטרנט ×חד}two{ועוד # דפי ×ינטרנט}many{ועוד # דפי ×ינטרנט}other{ועוד # דפי ×ינטרנט}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">דף ×–×” ×ª×•×¨×’× ×ž×©×¤×” ×œ× ×™×“×•×¢×” ל<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">תשלו×</translation>
<translation id="4926049483395192435">יש לציין ערך זה.</translation>
<translation id="495170559598752135">פעולות</translation>
<translation id="4958444002117714549">הרחב רשימה</translation>
-<translation id="4962322354953122629">â€×”שרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; Chrome ×ינו סומך על ×ישור ×”×בטחה שלו. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">הפעל מחדש ×זהרות</translation>
<translation id="4989809363548539747">הפל×גין ×”×–×” ×ינו נתמך</translation>
<translation id="5002932099480077015">â€×× ×”×פשרות הזו תופעל, Chrome ×™×חסן עותק של הכרטיס שלך במכשיר ×”×–×” למילוי מהיר יותר של טפסי×.</translation>
<translation id="5018422839182700155">×œ× × ×™×ª×Ÿ לפתוח ×ת הדף</translation>
@@ -450,14 +504,15 @@ Del</translation>
<translation id="5023310440958281426">בדוק ×ת תקנון מנהל המערכת שלך</translation>
<translation id="5029568752722684782">נקה ×ת העותק</translation>
<translation id="5031870354684148875">â€×ž×™×“×¢ על Google Translate</translation>
+<translation id="5039804452771397117">×פשר</translation>
<translation id="5040262127954254034">פרטיות</translation>
<translation id="5045550434625856497">סיסמה שגויה</translation>
<translation id="5056549851600133418">מ××ž×¨×™× ×©×¢×©×•×™×™× ×œ×¢× ×™×™×Ÿ ×ותך</translation>
<translation id="5070335125961472645">â€<ph name="BEGIN_LINK" />לבדוק ×ת כתובת שרת ×”-Proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{â€×ין קובצי Cookie}=1{â€×תר ×חד משתמש בקובצי Cookie. }two{â€# ××ª×¨×™× ×ž×©×ª×ž×©×™× ×‘×§×•×‘×¦×™ Cookie. }many{â€# ××ª×¨×™× ×ž×©×ª×ž×©×™× ×‘×§×•×‘×¦×™ Cookie. }other{â€# ××ª×¨×™× ×ž×©×ª×ž×©×™× ×‘×§×•×‘×¦×™ Cookie. }}</translation>
<translation id="5087286274860437796">×”×ישור של השרת ×ינו תקף כעת.</translation>
<translation id="5087580092889165836">הוסף כרטיס</translation>
<translation id="5089810972385038852">מדינה</translation>
+<translation id="5094747076828555589">â€×”שרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />. ×ישור ×”×בטחה שלו ×œ× × ×—×©×‘ כמהימן על ידי Chromium. ייתכן שהסיבה לכך ×”×™× ×ª×¦×•×¨×” שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
<translation id="5095208057601539847">פרובינציה</translation>
<translation id="5115563688576182185">(64 סיביות)</translation>
<translation id="5141240743006678641">â€×”צפן סיסמ×ות מסונכרנות ב×מצעות פרטי הכניסה שלך ל-Google</translation>
@@ -473,24 +528,24 @@ Del</translation>
<translation id="5222812217790122047">×ימייל (חובה)</translation>
<translation id="5251803541071282808">ענן</translation>
<translation id="5277279256032773186">â€×ž×©×ª×ž×© ב-Chrome בעבודה? ×¢×¡×§×™× ×™×›×•×œ×™× ×œ× ×”×œ ×ת ההגדרות של Chrome עבור העובדי×. למידע נוסף</translation>
+<translation id="5297526204711817721">â€×”חיבור שלך ל×תר ×–×” ×ינו פרטי. כדי לצ×ת ממצב VR בכל שלב, הסר ×ת ×”×וזניות ולחץ על 'הקוד×'.</translation>
<translation id="5299298092464848405">שגי××” בניתוח המדיניות</translation>
-<translation id="5300589172476337783">הצג</translation>
<translation id="5308689395849655368">דיווח קריסות מושבת.</translation>
<translation id="5317780077021120954">שמור</translation>
<translation id="5327248766486351172">ש×</translation>
-<translation id="5337705430875057403">×ª×•×§×¤×™× ×‘-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×©×•×™×™× ×œ×’×¨×•× ×œ×š לבצע פעולות מסוכנות, כמו התקנת תוכנה ×ו חשיפה של מידע ×ישי (למשל: סיסמ×ות, מספרי טלפון ×ו כרטיסי ×שר××™).</translation>
-<translation id="5359637492792381994">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×ינו חוקי כעת. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">נכון לעכשיו ××™ ×פשר לבקר ב×תר <ph name="SITE" /> מ×חר שה×ישור שלו בוטל. שגי×ות רשת ומתקפות הן בדרך כלל זמניות, כך שהדף ×”×–×” יחזור כנר××” לפעול מ×וחר יותר.</translation>
<translation id="536296301121032821">×חסון הגדרות המדיניות נכשל</translation>
<translation id="5386426401304769735">â€×©×¨×©×¨×ª ×”××™×©×•×¨×™× ×©×œ ×”×תר ×”×–×” כוללת ×ישור ×©× ×—×ª× ×‘×מצעות SHA-1.</translation>
<translation id="5402410679244714488">ת×ריך תפוגה: <ph name="EXPIRATION_DATE_ABBR" />, שימוש ×חרון ×”×™×” לפני שנה</translation>
+<translation id="540969355065856584">שרת ×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ×ישור ×”×בטחה שלו ×ינו תקף כעת. הסיבה לכך עשויה להיות תצורה שגויה ×ו שתוקף מיירט ×ת החיבור שלך.</translation>
<translation id="5421136146218899937">נקה נתוני גלישה...</translation>
<translation id="5430298929874300616">הסר סימניה</translation>
<translation id="5431657950005405462">הקובץ ×œ× × ×ž×¦×</translation>
-<translation id="5435775191620395718">מציג היסטוריה מהמכשיר הזה. <ph name="BEGIN_LINK" />למידע נוסף<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">שגי×ת ×ימות סכימה ב-"<ph name="ERROR_PATH" />"â€: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">×œ× × ×™×ª×Ÿ ×œ×ž×¦×•× ×ת הדף של <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">חותמת הזמן של המדיניות שגויה</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> מתוך <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">×œ× ×—×•×§×™</translation>
<translation id="5470861586879999274">&amp;ביצוע מחדש של עריכה</translation>
<translation id="54817484435770891">הוספה של כתובת חוקית</translation>
<translation id="5492298309214877701">כתובת ×”×תר ×”×–×” ב×ינטר×נט של החברה, ×”×רגון ×ו מוסד הלימודי×, ×–×”×” לכתובת
@@ -508,6 +563,8 @@ Del</translation>
<translation id="5571083550517324815">×œ× × ×™×ª×Ÿ לבצע ×יסוף מהכתובת הזו. עליך לבחור כתובת ×חרת.</translation>
<translation id="5572851009514199876">â€×ª×—ילה היכנס לחשבונך ב-Chrome כדי ל×פשר ל-Chrome לבדוק ×× ×™×© לך הרש××” לגשת ל×תר ×”×–×”.</translation>
<translation id="5580958916614886209">בדוק ×ת חודש התפוגה ונסה שוב</translation>
+<translation id="5586446728396275693">×œ× × ×©×ž×¨×• כתובות</translation>
+<translation id="5595485650161345191">ערוך כתובת</translation>
<translation id="560412284261940334">ניהול ×ינו נתמך</translation>
<translation id="5610142619324316209">לבדוק ×ת החיבור</translation>
<translation id="5610807607761827392">ב<ph name="BEGIN_LINK" />הגדרות<ph name="END_LINK" /> תוכל לנהל ×ת ×”×פשרויות של ×›×¨×˜×™×¡×™× ×•×›×ª×•×‘×•×ª.</translation>
@@ -515,15 +572,18 @@ Del</translation>
<translation id="5622887735448669177">×”×× ×‘×¨×¦×•× ×š לעזוב ×ת ×”×תר?</translation>
<translation id="5629630648637658800">טעינת הגדרות המדיניות נכשלה</translation>
<translation id="5631439013527180824">×סימון ניהול המכשיר ×ינו חוקי</translation>
+<translation id="5633066919399395251">×ª×•×§×¤×™× ×©× ×ž×¦××™× ×›×¨×’×¢ ב×תר <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×œ×•×œ×™× ×œ×”×ª×§×™×Ÿ במחשב שלך תוכנות מסוכנות שגונבות מידע ×ו מוחקות ×ותו (למשל, תמונות, סיסמ×ות, הודעות וכרטיסי ×שר××™). <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">מיקו×</translation>
+<translation id="5659593005791499971">×ימייל</translation>
<translation id="5669703222995421982">הת×מה ×ישית של תוכן</translation>
<translation id="5675650730144413517">הדף ×”×–×” ×œ× ×¢×•×‘×“</translation>
-<translation id="5677928146339483299">במצב חסו×</translation>
-<translation id="5694783966845939798">â€× ×™×¡×™×ª להיכנס ×ל <ph name="DOMAIN" />, ×בל השרת הציג ×ישור ×©× ×—×ª× ×‘×מצעות ××œ×’×•×¨×™×ª× ×—×ª×™×ž×” ברמת ×בטחה חלשה (כגון SHA-1). כלומר, ייתכן ש×ישורי ×”×בטחה שהשרת הציג מזויפי×, ×•×©×œ× ×ž×“×•×‘×¨ בשרת שציפית לו (ייתכן ש×תה מתקשר ×¢× ×ª×•×§×£). <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">הזהות של ×תר ×–×” ×œ× ×ומתה.</translation>
+<translation id="5713016350996637505">תוכן מטעה נחס×</translation>
<translation id="5720705177508910913">משתמש נוכחי:</translation>
<translation id="5732392974455271431">×”×”×•×¨×™× ×©×œ×š ×™×›×•×œ×™× ×œ×‘×˜×œ בשבילך ×ת החסימה</translation>
<translation id="5763042198335101085">עליך להזין כתובת ×ימייל חוקית</translation>
<translation id="5765072501007116331">עליך לבחור כתובת כדי לר×ות שיטות מסירה ודרישות</translation>
+<translation id="5778550464785688721">â€×©×œ×™×˜×” מל××” במכשירי MIDI</translation>
<translation id="5784606427469807560">הייתה בעיה ב×ישור הכרטיס. בדוק ×ת החיבור ל×ינטרנט ונסה שוב.</translation>
<translation id="5785756445106461925">כמו כן, דף ×–×” כולל מש××‘×™× × ×•×¡×¤×™× ×©××™× × ×ž×ובטחי×. ×’×•×¨×ž×™× ××—×¨×™× ×¢×œ×•×œ×™× ×œ×¨×ות ×ת המש××‘×™× ×”×לה במהלך העברת×, ותוקף עלול לשנות ××•×ª× ×‘×ופן שישנה ×ת מר××” הדף.</translation>
<translation id="5786044859038896871">×”×× ×‘×¨×¦×•× ×š ×œ×ž×œ× ×ת פרטי הכרטיס שלך?</translation>
@@ -532,14 +592,14 @@ Del</translation>
<translation id="5813119285467412249">&amp;ביצוע מחדש של הוספה</translation>
<translation id="5814352347845180253">×תה עשוי ל×בד גישה ×ל תוכן ×¤×¨×ž×™×•× ×ž-<ph name="SITE" /> ומ××ª×¨×™× ×חרי×.</translation>
<translation id="5838278095973806738">×ין להזין מידע רגיש ב×תר ×”×–×” (כמו סיסמ×ות ×ו מספרי כרטיסי ×שר××™), מ×חר ×©×ª×•×§×¤×™× ×¢×œ×•×œ×™× ×œ×§×‘×œ ×ליו גישה.</translation>
-<translation id="5843436854350372569">ניסית להגיע ×ל <ph name="DOMAIN" />, ×בל השרת הציג ×ישור המכיל מפתח חלש. ייתכן שתוקף פרץ ×ת המפתח הפרטי וזהו ×ינו השרת ש×תה מצפה לו (ייתכן ש×תה מתקשר ×¢× ×ª×•×§×£). <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">×œ× × ×™×ª×Ÿ לגשת ל×תר ×”×–×”</translation>
<translation id="5869522115854928033">סיסמ×ות שמורות</translation>
<translation id="5872918882028971132">הצעות להורי×</translation>
<translation id="5901630391730855834">צהוב</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (מסונכרני×)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{×חד × ×ž×¦× ×‘×©×™×ž×•×©}two{×©× ×™×™× × ×ž×¦××™× ×‘×©×™×ž×•×©}many{# נמצ××™× ×‘×©×™×ž×•×©}other{# נמצ××™× ×‘×©×™×ž×•×©}}</translation>
<translation id="5926846154125914413">×תה עשוי ל×בד גישה ×ל תוכן ×¤×¨×ž×™×•× ×ž××ª×¨×™× ×ž×¡×•×™×ž×™×.</translation>
<translation id="5959728338436674663">â€×©×œ×— ב×ופן ×וטומטי <ph name="BEGIN_WHITEPAPER_LINK" />חלק מפרטי המערכת ותוכן הדף<ph name="END_WHITEPAPER_LINK" /> ×ל Google כדי לעזור בזיהוי של ×פליקציות ו××ª×¨×™× ×ž×¡×•×›× ×™×. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">שבוע</translation>
<translation id="5967867314010545767">הסר מההיסטוריה</translation>
<translation id="5975083100439434680">התרחק</translation>
<translation id="598637245381783098">×œ× × ×™×ª×Ÿ לפתוח ×ת ×פליקציית התשלומי×</translation>
@@ -548,21 +608,29 @@ Del</translation>
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{דף 1}two{דף #}many{דף #}other{דף #}}</translation>
<translation id="6017514345406065928">ירוק</translation>
+<translation id="6017850046339264347">×ª×•×§×¤×™× ×©×ž×©×ª×ž×©×™× ×‘-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×œ×•×œ×™× ×œ×”×ª×§×™×Ÿ ×™×™×©×•×ž×™× ×ž×˜×¢×™× ×©×ž×ª×—×–×™× ×œ××—×¨×™× ×ו ל×סוף × ×ª×•× ×™× ×©×פשר להשתמש ×‘×”× ×›×“×™ לעקוב ×חריך. <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (מסונכרני×)</translation>
<translation id="6027201098523975773">עליך להזין ש×</translation>
<translation id="6040143037577758943">סגור</translation>
<translation id="6042308850641462728">עוד</translation>
+<translation id="6047233362582046994">×× ×תה מבין ×ת סיכוני ×”×בטחה, תוכל <ph name="BEGIN_LINK" />להיכנס ל×תר ×”×–×”<ph name="END_LINK" /> לפני הסרת ×”×™×™×©×•×ž×™× ×”×ž×–×™×§×™×.</translation>
+<translation id="6051221802930200923">נכון לעכשיו ××™ ×פשר לבקר ב×תר <ph name="SITE" />, מ×חר שב×תר ×”×–×” נעשה שימוש בנעיצת ×ישורי×. שגי×ות רשת ומתקפות הן בדרך כלל זמניות, כך שהדף ×”×–×” יחזור כנר××” לפעול מ×וחר יותר.</translation>
<translation id="6060685159320643512">זהירות, × ×™×¡×•×™×™× ×לה ×¢×œ×•×œ×™× ×œ× ×©×•×š</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{לל×}=1{×חת}two{שתיי×}many{#}other{#}}</translation>
+<translation id="6080696365213338172">ניגשת לתוכן ב×מצעות ×ישור שהוענק על ידי מנהל מערכת. מנהל המערכת שלך עשוי ליירט × ×ª×•× ×™× ×©×ª×¡×¤×§ ל-<ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{לל×}=1{סיסמה ×חת (מסונכרנת)}two{שתי סיסמ×ות (מסונכרנות)}many{# סיסמ×ות (מסונכרנות)}other{# סיסמ×ות (מסונכרנות)}}</translation>
<translation id="6146055958333702838">בדוק ×ת ×”×›×‘×œ×™× ×•×”×¤×¢×œ מחדש ×ת הנתבי×, ×”×ž×•×“×ž×™× ×•×©×ר התקני הרשת
ש×תה משתמש בה×.</translation>
<translation id="614940544461990577">נסה:</translation>
<translation id="6151417162996330722">תקופת התוקף של ×ישור השרת ×רוכה מדי.</translation>
<translation id="6157877588268064908">עליך לבחור כתובת כדי לר×ות שיטות משלוח ודרישות</translation>
+<translation id="6158003235852588289">â€×”גלישה הבטוחה של Google זיהתה ל×חרונה דיוג ב×תר <ph name="SITE" />. ×תרי דיוג ×ž×ª×—×–×™× ×œ××ª×¨×™× ××—×¨×™× ×‘×ž×˜×¨×” להונות ×ותך.</translation>
<translation id="6165508094623778733">למידע נוסף</translation>
+<translation id="6169916984152623906">עכשיו ב×פשרותך לגלוש ב×ופן פרטי, ו×× ×©×™× ××—×¨×™× ×©×ž×©×ª×ž×©×™× ×‘×ž×›×©×™×¨ ×”×–×” ×œ× ×™×¨×ו ×ת הפעילות שלך. ×¢× ×–×ת, עדיין תתבצע שמירה של הורדות וסימניות.</translation>
<translation id="6177128806592000436">החיבור שלך ל×תר ×”×–×” ×œ× ×ž×ובטח</translation>
<translation id="6184817833369986695">(קבוצה: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">בדוק ×ת חיבור ×”×ינטרנט</translation>
<translation id="6218753634732582820">â€×”×× ×œ×”×¡×™×¨ מ-Chromium ×ת הכתובת?</translation>
+<translation id="6221345481584921695">â€×œ×חרונה, 'גלישה בטוחה של Google' â€<ph name="BEGIN_LINK" />זיהתה תוכנה זדונית<ph name="END_LINK" /> ב-<ph name="SITE" />. ××ª×¨×™× ×©×‘×“×¨×š כלל × ×—×©×‘×™× ×œ×‘×˜×•×—×™× × ×“×‘×§×™× ×œ×¢×ª×™× ×‘×ª×•×›× ×” זדונית. התוכן הזדוני מגיע מ-<ph name="SUBRESOURCE_HOST" />, מפיץ ידוע של תוכנות זדוניות.</translation>
<translation id="6251924700383757765">מדיניות פרטיות</translation>
<translation id="6254436959401408446">×ין מספיק זיכרון כדי לפתוח ×ת הדף</translation>
<translation id="625755898061068298">בחרת להשבית ×ת ×זהרות ×”×בטחה ל×תר ×”×–×”.</translation>
@@ -588,15 +656,14 @@ Del</translation>
<translation id="6404511346730675251">ערוך סימניה</translation>
<translation id="6410264514553301377">הזן ×ת ת×ריך התפוגה ו×ת קוד ×”×ימות של <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">ש×לת ×חד מהוריך ×× ×תה יכול לבקר ב×תר ×”×–×”</translation>
-<translation id="6416403317709441254">â€×œ× ניתן לבקר עכשיו ב-<ph name="SITE" /> מכיוון שה×תר שלח ××™×©×•×¨×™× ×œ× ×ª×§×™× ×™× ×©-Chromium ×œ× ×ž×¦×œ×™×— לעבד. שגי×ות רשת ותקיפות מתרחשות בדרך כלל לזמן מוגבל, ולכן סביר להניח שדף ×–×” יחזור לפעול מ×וחר יותר. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">×œ× × ×™×ª×Ÿ לבדוק ×× ×”×ישור נשלל.</translation>
<translation id="6433490469411711332">עריכת ×”×¤×¨×˜×™× ×œ×™×¦×™×¨×ª קשר</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> סירב להתחבר.</translation>
<translation id="6446608382365791566">הוסף מידע</translation>
+<translation id="6447842834002726250">â€×§×•×‘צי Cookie</translation>
<translation id="6451458296329894277">×שר שליחה-מחדש של הטופס</translation>
<translation id="6456339708790392414">×”×ª×©×œ×•× ×©×œ×š</translation>
<translation id="6458467102616083041">המערכת התעלמה מערך מדיניות ×–×”, ×ž×©×•× ×©×œ×¤×™ המדיניות, חיפוש ברירת המחדל מושבת.</translation>
-<translation id="6462969404041126431">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; ייתכן ש×ישור ×”×בטחה שלו בוטל. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">מדיניות המכשיר</translation>
<translation id="6477321094435799029">â€Chrome ×–×™×”×” קוד חריג בדף ×”×–×” ×•×—×¡× ×ותו כדי להגן על המידע הפרטי שלך (כגון סיסמ×ות, מספרי טלפון ומספרי כרטיסי ×שר××™).</translation>
<translation id="6489534406876378309">התחל להעלות קריסות</translation>
@@ -608,20 +675,19 @@ Del</translation>
<translation id="6556915248009097796">ת×ריך תפוגה: <ph name="EXPIRATION_DATE_ABBR" />, שימוש ×חרון: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">המנהל שלך עדיין ×œ× ×ישר ×–×ת</translation>
<translation id="6569060085658103619">×תה מציג דף של תוסף</translation>
-<translation id="6593753688552673085">פחות מ-<ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">ייתכן שהתוכן ×”×–×” מכיל ××ž×¦×¢×™× ×©×™× ×¡×• להתקין תוכנה מסוכנת, שגונבת ×ו מוחקת ×ת המידע שלך. <ph name="BEGIN_LINK" />הצג בכל ×–×ת<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">×פשרויות הצפנה</translation>
<translation id="662080504995468778">היש×ר</translation>
<translation id="6626291197371920147">הוסף מספר כרטיס חוקי</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> חיפוש</translation>
+<translation id="6630809736994426279">â€×ª×•×§×¤×™× שנמצ××™× ×›×¨×’×¢ ב×תר <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×œ×•×œ×™× ×œ×”×ª×§×™×Ÿ במחשב ×”-MAC שלך תוכנות מסוכנות שגונבות מידע ×ו מוחקות ×ותו (לדוגמה, תמונות, סיסמ×ות, הודעות וכרטיסי ×שר××™). <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">מדיניות זו ××™× ×” בתוקף.</translation>
-<translation id="6652240803263749613">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; מערכת ההפעלה של המחשב ×œ× ×¡×•×ž×›×ª על ×ישור ×”×בטחה שלו. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">â€×”×× ×œ×”×¡×™×¨ מ-Chromium הצעות לטפסי×?</translation>
<translation id="6685834062052613830">×¦× ×•×”×©×œ× ×ת ההגדרה</translation>
<translation id="6710213216561001401">הקוד×</translation>
<translation id="6710594484020273272">&lt;הקלד מונח חיפוש&gt;</translation>
<translation id="6711464428925977395">â€×ž×©×”ו ×ינו תקין בשרת ×”-proxy, ×ו שהכתובת שגויה.</translation>
<translation id="6727102863431372879">הגדר</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{לל×}=1{פריט ×חד}two{שני פריטי×}many{# פריטי×}other{# פריטי×}}</translation>
<translation id="674375294223700098">שגי×ת ×ישור שרת ×œ× ×™×“×•×¢.</translation>
<translation id="6753269504797312559">ערך מדיניות</translation>
<translation id="6757797048963528358">המכשיר עבר למצב שינה.</translation>
@@ -629,6 +695,8 @@ Del</translation>
<translation id="6810899417690483278">מזהה של הת×מה ×ישית</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">נכשלה הטעינה של נתוני ×”×זורי×</translation>
+<translation id="6825578344716086703">â€× ×™×¡×™×ª להגיע ×ל <ph name="DOMAIN" />, ×בל השרת הציג ×ישור ×©× ×—×ª× ×‘×מצעות ××œ×’×•×¨×™×ª× ×—×ª×™×ž×” חלש (כמו SHA-1). המשמעות ×”×™× ×©×¤×¨×˜×™ ×”×בטחה שהוצגו על-ידי השרת ×¢×œ×•×œ×™× ×œ×”×™×•×ª מזויפי×, וייתכן שהשרת ×”×•× ×œ× ×”×©×¨×ª שציפית לו (ייתכן שנוצר קשר בינך לבין התוקף).</translation>
+<translation id="6830728435402077660">×œ× ×ž×ובטח</translation>
<translation id="6831043979455480757">תרג×</translation>
<translation id="6839929833149231406">×זור</translation>
<translation id="6874604403660855544">&amp;ביצוע מחדש של הוספה</translation>
@@ -636,6 +704,7 @@ Del</translation>
<translation id="6895330447102777224">הכרטיס שלך מ×ושר</translation>
<translation id="6897140037006041989">User agent</translation>
<translation id="6915804003454593391">משתמש:</translation>
+<translation id="6945221475159498467">בחר</translation>
<translation id="6948701128805548767">עליך לבחור כתובת כדי לר×ות שיטות ×יסוף ודרישות</translation>
<translation id="6957887021205513506">נר××” שה×ישור של השרת מזויף.</translation>
<translation id="6965382102122355670">×ישור</translation>
@@ -644,15 +713,16 @@ Del</translation>
<translation id="6973656660372572881">â€×¦×•×™× ×• שרתי Proxy ×§×‘×•×¢×™× ×•×›×ª×•×‘×ª ×תר של הסקריפט מסוג ‎.Pac</translation>
<translation id="6989763994942163495">הצג הגדרות מתקדמות...</translation>
<translation id="7000990526846637657">×œ× × ×ž×¦×ו רשומות היסטוריה</translation>
-<translation id="7009986207543992532">ניסית להגיע ×ל <ph name="DOMAIN" />, ×בל השרת הציג ×ישור ×¢× ×ª×§×•×¤×ª תוקף ×רוכה ב×ופן מחשיד. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">â€×™×™×ª×›×Ÿ שלחשבון Google שלך יש ×¡×•×’×™× ××—×¨×™× ×©×œ היסטוריית גלישה ×©×–×ž×™× ×™× ×‘×›×ª×•×‘×ª <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">סיסמ×ות</translation>
+<translation id="7050187094878475250">ניסית להגיע ×ל <ph name="DOMAIN" />, ×ך השרת הציג ×ישור שתקופת התוקף שלו ×רוכה מדי ולכן ×ינו מהימן.</translation>
+<translation id="7053983685419859001">חסו×</translation>
<translation id="7064851114919012435">×¤×¨×˜×™× ×œ×™×¦×™×¨×ª קשר</translation>
<translation id="7079718277001814089">×”×תר ×”×–×” מכיל תוכנה זדונית</translation>
<translation id="7087282848513945231">מחוז (בבריטניה וב×ירלנד)</translation>
-<translation id="7088615885725309056">ישן יותר</translation>
<translation id="7090678807593890770">â€×—פש ב-Google ×ת <ph name="LINK" /></translation>
+<translation id="7108819624672055576">×ושרה על-ידי תוסף</translation>
<translation id="7119414471315195487">סגירת כרטיסיות ×ו תוכניות ×חרות</translation>
<translation id="7129409597930077180">×œ× × ×™×ª×Ÿ לבצע משלוח לכתובת הזו. עליך לבחור כתובת ×חרת.</translation>
<translation id="7138472120740807366">שיטת מסירה</translation>
@@ -670,22 +740,18 @@ Del</translation>
<translation id="7220786058474068424">מעבד</translation>
<translation id="724691107663265825">×”×תר שלפניך מכיל תוכנה זדונית</translation>
<translation id="724975217298816891">הזן ×ת ת×ריך התפוגה ו×ת קוד ×”×ימות של <ph name="CREDIT_CARD" /> כדי לעדכן ×ת פרטי הכרטיס. ברגע שת×שר, פרטי הכרטיס שלך ישותפו ×¢× ×”×תר ×”×–×”.</translation>
-<translation id="725866823122871198">×œ× × ×™×ª×Ÿ ליצור חיבור פרטי ×ל <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> מפני שהת×ריך והשעה (<ph name="DATE_AND_TIME" />) במחשב שלך שגויי×.</translation>
+<translation id="7260504762447901703">בטל גישה</translation>
<translation id="7275334191706090484">סימניות מנוהלות</translation>
<translation id="7298195798382681320">מומלצי×</translation>
<translation id="7309308571273880165">דוח הקריסה תועד ב<ph name="CRASH_TIME" /> (המשתמש ביקש העל××”, הדוח עדיין ×œ× ×”×•×¢×œ×”)</translation>
<translation id="7334320624316649418">&amp;ביצוע מחדש של שינוי סדר</translation>
<translation id="733923710415886693">×ישור השרת ×œ× × ×—×©×£ דרך 'שקיפות ×ישורי×'.</translation>
-<translation id="7351800657706554155">×œ× × ×™×ª×Ÿ להיכנס כרגע ל×תר <ph name="SITE" /> ×›×™ ×”×ישור שלו בוטל. שגי×ות רשת ומתקפות הן בדרך כלל זמניות, כך שהדף ×”×–×” ככל הנר××” יחזור לפעול מ×וחר יותר. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">שורת פקודה </translation>
<translation id="7372973238305370288">תוצ×ת חיפוש</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ל×</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">×שר ×ת הכרטיס</translation>
-<translation id="7394102162464064926">×”×× ×תה בטוח שברצונך למחוק ×ת ×”×“×¤×™× ×”×לה מההיסטוריה?
-
-שששש...! מצב גלישה בסתר <ph name="SHORTCUT_KEY" /> עשוי להיות שימושי ×‘×¤×¢× ×”×‘××”.</translation>
<translation id="7400418766976504921">כתובת ×תר</translation>
<translation id="7419106976560586862">נתיב פרופיל</translation>
<translation id="7424977062513257142">דף המוטמע בדף ×ינטרנט ×–×” ×ומר:</translation>
@@ -693,6 +759,7 @@ Del</translation>
<translation id="7444046173054089907">×”×תר ×”×–×” חסו×</translation>
<translation id="7445762425076701745">×œ× × ×™×ª×Ÿ ל×מת לגמרי ×ת הזהות של השרת ש×ליו ×תה מחובר. ×תה מחובר לשרת ב×מצעות ×©× ×©×§×™×™× ×¨×§ ברשת שלך, ושלרשות ××™×©×•×¨×™× ×—×™×¦×•× ×™×ª ×ין דרך ל×מת ×ת בעלותך עליו. מכיוון שחלק מרשויות ×”××™×©×•×¨×™× ×™× ×¤×™×§×• ××™×©×•×¨×™× ×œ×©×ž×•×ª ×לה ×œ×œ× ×§×©×¨, ×ין דרך להבטיח ש×תה מחובר ל×תר המיועד ו×ינך ×’×•×¨× ×ª×•×§×£.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />למידע נוסף<ph name="END_LINK" /> על בעיה זו.</translation>
+<translation id="7455133967321480974">השתמש בברירת המחדל הכללית (חסו×)</translation>
<translation id="7460163899615895653">הכרטיסיות ×”×חרונות שפתחת ×‘×ž×›×©×™×¨×™× ××—×¨×™× ×ž×•×¦×’×•×ª ×›×ן</translation>
<translation id="7469372306589899959">מ×שר ×ת הכרטיס</translation>
<translation id="7481312909269577407">קדימה</translation>
@@ -700,36 +767,43 @@ Del</translation>
<translation id="7508255263130623398">מזהה המכשיר במדיניות שהוחזר ריק ×ו ש×ינו תו×× ×ת מזהה המכשיר הנוכחי</translation>
<translation id="7514365320538308">הורד</translation>
<translation id="7518003948725431193">×œ× × ×ž×¦× ×“×£ ×ינטרנט עבור כתובת ×”×ינטרנט: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">ערך</translation>
<translation id="7537536606612762813">הכרחי</translation>
+<translation id="7542403920425041731">ברגע שת×שר, פרטי הכרטיס שלך ישותפו ×¢× ×”×תר ×”×–×”.</translation>
<translation id="7542995811387359312">מילוי ×וטומטי של פרטי כרטיס ×שר××™ מושבת כיוון שטופס ×–×” ×ינו משתמש בחיבור מ×ובטח.</translation>
<translation id="7543525346216957623">יש לבקש רשות מההורי×</translation>
<translation id="7549584377607005141">דף ×ינטרנט ×–×” זקוק ×œ× ×ª×•× ×™× ×©×”×–× ×ª ×§×•×“× ×œ×›×Ÿ כדי ×©×”×•× ×™×•×¦×’ כר×וי. ×תה יכול לשלוח שוב ×ת הנתוני×, ×ך פעולה זו ×ª×’×¨×•× ×œ×—×–×¨×” על כל פעולה שדף ×–×” ביצע בעבר.</translation>
<translation id="7552846755917812628">×ולי ×”×˜×™×¤×™× ×”×לו יעזרו לך:</translation>
<translation id="7554791636758816595">כרטיסייה חדשה</translation>
+<translation id="7567204685887185387">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />. ייתכן ש×ישור ×”×בטחה שלו נופק כהונ××”. הסיבה לכך עשויה להיות הגדרה שגויה ×ו תוקף המיירט ×ת החיבור שלך.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ונוסף}two{<ph name="CONTACT_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ונוספי×}many{<ph name="CONTACT_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ונוספי×}other{<ph name="CONTACT_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ונוספי×}}</translation>
<translation id="7568593326407688803">זהו דף ב<ph name="ORIGINAL_LANGUAGE" />×”×× ×‘×¨×¦×•× ×š ×œ×ª×¨×’× ×ותו?</translation>
<translation id="7569952961197462199">â€×”×× ×œ×”×¡×™×¨ ×ת כרטיס ×”×שר××™ מ-Chrome?</translation>
<translation id="7569983096843329377">שחור</translation>
<translation id="7578104083680115302">â€×©×œ× במהירות ב××ª×¨×™× ×•×‘×פליקציות בכל ×”×ž×›×©×™×¨×™× ×‘×מצעות ×›×¨×˜×™×¡×™× ×©×©×ž×¨×ª ב-Google.</translation>
<translation id="7588950540487816470">×”×ינטרנט הווירטופיזי</translation>
<translation id="7592362899630581445">×ישור השרת מפר ×ת ×ילוצי השמות.</translation>
+<translation id="7598391785903975535">פחות מ-<ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ×œ× ×™×›×•×œ לטפל כרגע בבקשה הזו.</translation>
<translation id="7600965453749440009">×ל ×ª×ª×¨×’× ×œ×¢×•×œ× <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">הערך מחוץ לטווח <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">תפוגה: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">â€×™×© לך כבר × ×ª×•× ×™× ×©×”×•×¦×¤× ×• ב×מצעות גירסה ×חרת של סיסמת חשבון Google שלך. הזן ×ותה למטה.</translation>
-<translation id="7634554953375732414">החיבור שלך ל×תר ×–×” ×ינו פרטי.</translation>
<translation id="7637571805876720304">â€×”×× ×œ×”×¡×™×¨ מ-Chromium ×ת כרטיס ×”×שר××™?</translation>
<translation id="765676359832457558">הסתר הגדרות מתקדמות...</translation>
<translation id="7658239707568436148">ביטול</translation>
+<translation id="7662298039739062396">ההגדרה נשלטת על-ידי תוסף</translation>
<translation id="7667346355482952095">×סימון המדיניות שהוחזר ×”×•× ×¨×™×§ ×ו ש×ינו תו×× ×œ×סימון הנוכחי</translation>
<translation id="7668654391829183341">מכשיר ×œ× ×™×“×•×¢</translation>
<translation id="7669271284792375604">×ª×•×§×¤×™× ×‘×תר ×”×–×” ×¢×©×•×™×™× ×œ×’×¨×•× ×œ×š, בדרכי מרמה, להתקין תוכניות שיפגעו בחוויית הגלישה שלך (לדוגמה, על ידי שינוי דף הבית ×ו הצגת מודעות נוספות ב××ª×¨×™× ×©×‘×”× ×תה מבקר).</translation>
<translation id="7674629440242451245">â€×ž×¢×•× ×™×™×Ÿ בתכונות חדשות ומגניבות של Chrome? נסה ×ת הערוץ שלנו ×œ×ž×¤×ª×—×™× ×‘×›×ª×•×‘×ª chrome.com/dev.</translation>
<translation id="7682287625158474539">משלוח</translation>
+<translation id="7701040980221191251">לל×</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />המשך ×ל <ph name="SITE" /> (×œ× ×‘×˜×•×—)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">×ישור</translation>
+<translation id="7716147886133743102">נחסמה על-ידי מנהל המערכת</translation>
<translation id="7716424297397655342">×œ× × ×™×ª×Ÿ לטעון ×ת ×”×תר ×”×–×” מהמטמון</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">×œ×œ× × ×™×”×•×œ</translation>
<translation id="7755287808199759310">×חד ×ž×”×”×•×¨×™× ×©×œ×š יכול לבטל בשבילך ×ת החסימה</translation>
<translation id="7758069387465995638">ייתכן שחומת ×ש ×ו תוכנת ×נטי-וירוס חסמו ×ת החיבור.</translation>
@@ -756,15 +830,15 @@ Del</translation>
<translation id="7951415247503192394">(32 סיביות)</translation>
<translation id="7956713633345437162">סימניות לנייד</translation>
<translation id="7961015016161918242">××£ פע×</translation>
-<translation id="7962083544045318153">מזהה קריסה <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">×ª×¨×’× ×ª×ž×™×“ <ph name="ORIGINAL_LANGUAGE" /> ל<ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">×œ× ×¦×•×™×Ÿ</translation>
<translation id="800218591365569300">מומלץ לסגור כרטיסיות ×ו תוכניות ×חרות וכך לפנות ×ž×§×•× ×‘×–×™×›×¨×•×Ÿ.</translation>
<translation id="8012647001091218357">×œ× ×”×¦×œ×—× ×• ליצור קשר ×¢× ×”×”×•×¨×™× ×©×œ×š. נסה שוב מ×וחר יותר.</translation>
<translation id="8025119109950072390">×ª×•×§×¤×™× ×‘×תר ×”×–×” ×¢×©×•×™×™× ×œ×’×¨×•× ×œ×š, בדרכי מרמה, לבצע פעולות מסוכנות כמו התקנת תוכנה ×ו חשיפה של מידע ×ישי (לדוגמה: סיסמ×ות, מספרי טלפון ×ו פרטי כרטיסי ×שר××™).</translation>
-<translation id="803030522067524905">â€×”גלישה הבטוחה של Google זיהתה ל×חרונה דיוג ב×תר <ph name="SITE" />. ×תרי דיוג ×ž×ª×—×–×™× ×œ××ª×¨×™× ××—×¨×™× ×›×“×™ להטעות ×ותך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">דף ×–×” מוצג ב<ph name="SOURCE_LANGUAGE" />. ×”×× ×œ×ª×¨×’× ×ותו ל<ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">ש×ל (ברירת מחדל)</translation>
<translation id="8041089156583427627">שלח משוב</translation>
+<translation id="8041940743680923270">השתמש בברירת המחדל הכללית (ש×ל)</translation>
<translation id="8088680233425245692">הצגת הפריט נכשלה.</translation>
<translation id="8089520772729574115">â€×¤×—ות מ-‎1 MB</translation>
<translation id="8091372947890762290">ההפעלה ממתינה בשרת</translation>
@@ -773,13 +847,14 @@ Del</translation>
<translation id="8134994873729925007">â€×œ× ניתן ×”×™×” ×œ×ž×¦×•× ×ת <ph name="BEGIN_ABBR" />כתובת ×”-DNS<ph name="END_ABBR" /> של השרת של <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">המחשב עבר למצב שינה.</translation>
<translation id="8150722005171944719">הקובץ ×”× ×ž×¦× ×‘-<ph name="URL" /> ×œ× × ×™×ª×Ÿ לקרי××”. ייתכן שהקובץ הוסר ×ו הועבר, ×ו שהרש×ות הקובץ מונעות גישה ×ליו.</translation>
+<translation id="8184538546369750125">השתמש בברירת המחדל הכללית (×פשר)</translation>
+<translation id="8191494405820426728">מזהה קריסה מקומי <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;ביטול העברה</translation>
<translation id="8201077131113104583">כתובת ×תר ×œ× ×—×•×§×™×ª לעדכון עבור תוסף ×¢× ×”×ž×–×”×” "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">×¡×™×›×•× ×”×–×ž× ×”</translation>
<translation id="8218327578424803826">×ž×™×§×•× ×ž×•×§×¦×”:</translation>
<translation id="8225771182978767009">×”××“× ×©×”×’×“×™×¨ ×ת המחשב ×”×–×” בחר ×œ×—×¡×•× ×ת ×”×תר ×”×–×”.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">×ª×•×§×¤×™× ×”× ×ž×¦××™× ×›×¢×ª ב-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×©×•×™×™× ×œ× ×¡×•×ª להתקין במחשב שלך תכניות מסוכנות שגונבות ×ו מוחקות מידע שלך (לדוגמה, תמונות, סיסמ×ות, הודעות וכרטיסי ×שר××™).</translation>
<translation id="8241707690549784388">הדף ש×תה מחפש השתמש במידע שהזנת. החזרה לדף ×–×” עלולה ×œ×’×¨×•× ×œ×›×¤×™×œ×•×ª בפעולות שביצעת. ×”×× ×‘×¨×¦×•× ×š להמשיך?</translation>
<translation id="8249320324621329438">×וחזר ל×חרונה:</translation>
<translation id="8253091569723639551">יש להזין כתובת לחיוב</translation>
@@ -787,6 +862,7 @@ Del</translation>
<translation id="8289355894181816810">פנה ×ל מנהל הרשת ×× ×ינך יודע מה ×–×” ×ומר.</translation>
<translation id="8293206222192510085">הוסף סימניה</translation>
<translation id="8294431847097064396">מקור</translation>
+<translation id="8306404619377842860">××™ ×פשר ליצור חיבור פרטי ×ל <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> מ×חר שהת×ריך והשעה של המכשיר שלך (<ph name="DATE_AND_TIME" />) ×œ× × ×›×•× ×™×. <ph name="BEGIN_LEARN_MORE_LINK" />מידע נוסף<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">×”×ª×¨×’×•× × ×›×©×œ עקב בעיה בחיבור הרשת.</translation>
<translation id="8332188693563227489">הגישה ל-<ph name="HOST_NAME" /> נדחתה</translation>
<translation id="834457929814110454">×× ×תה מבין ×ת סיכוני ×”×בטחה, תוכל <ph name="BEGIN_LINK" />להיכנס ל×תר ×œ× ×‘×˜×•×— ×–×”<ph name="END_LINK" /> לפני הסרת התכניות המסוכנות.</translation>
@@ -807,11 +883,9 @@ Del</translation>
<translation id="8483780878231876732">â€×›×“×™ להשתמש ×‘×›×¨×˜×™×¡×™× ×ž×—×©×‘×•×Ÿ Google, היכנס ×ל Chrome</translation>
<translation id="8488350697529856933">חל על</translation>
<translation id="8498891568109133222">ל-<ph name="HOST_NAME" /> נדרש זמן רב מדי להגיב.</translation>
-<translation id="852346902619691059">השרת ×”×–×” ×œ× ×”×¦×œ×™×— להוכיח ×©×”×•× <ph name="DOMAIN" />; מערכת ההפעלה של המכשיר ×œ× ×¡×•×ž×›×ª על ×ישור ×”×בטחה שלו. ייתכן שהסיבה לכך ×”×™× ×”×’×“×¨×” שגויה ×ו שתוקף מיירט ×ת החיבור שלך. <ph name="BEGIN_LEARN_MORE_LINK" />למידע נוסף<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">שנת פקיעת התוקף</translation>
<translation id="8543181531796978784">ב×פשרותך <ph name="BEGIN_ERROR_LINK" />לדווח על בעיית זיהוי<ph name="END_ERROR_LINK" /> ×ו, ×× ×תה מבין ×ת סיכוני ×”×בטחה, <ph name="BEGIN_LINK" />להיכנס ל×תר ×”×–×”, ש×ינו מ×ובטח<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">×”×ª×¨×’×•× × ×›×©×œ כיוון ×©×œ× ×”×™×™×ª×” ×פשרות לקבוע ×ת שפת הדף.</translation>
-<translation id="8559762987265718583">×œ× × ×™×ª×Ÿ ליצור חיבור פרטי ×ל <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> מפני שהת×ריך והשעה (<ph name="DATE_AND_TIME" />) במכשיר שלך שגויי×.</translation>
<translation id="8571890674111243710">×ž×ª×¨×’× ×“×£ ל<ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">הוסף מספר טלפון
</translation>
@@ -826,6 +900,7 @@ Del</translation>
<translation id="8738058698779197622">â€×›×“×™ ליצור חיבור מ×ובטח, השעון צריך להיות מוגדר כהלכה. הסיבה לכך ×”×™× ×©×”××™×©×•×¨×™× ×©×‘×”× ××ª×¨×™× ×ž×©×ª×ž×©×™× ×›×“×™ לזהות ×ת ×¢×¦×ž× ×ª×§×¤×™× ×¨×§ למשך פרקי זמן מסוימי×. מ×חר שהשעון במכשיר שלך שגוי, Chromium ×œ× ×™×›×•×œ ל×מת ×ת ×”××™×©×•×¨×™× ×”×לו.</translation>
<translation id="8740359287975076522">â€×œ× ניתן ×”×™×” ×œ×ž×¦×•× ×ת &lt;abbr id="dnsDefinition"&gt;כתובת ×”-DNS&lt;/abbr&gt; של <ph name="HOST_NAME" />. מ×בחן ×ת הבעיה.</translation>
<translation id="8759274551635299824">פג תוקפו של הכרטיס</translation>
+<translation id="8761567432415473239">â€×’לישה בטוחה של Google <ph name="BEGIN_LINK" />×יתרה ל×חרונה תוכניות מזיקות<ph name="END_LINK" /> ב×תר <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;ביצוע מחדש של מחיקה</translation>
<translation id="8800988563907321413">×›×ן מופיעות הצעות עבורך למקומות קרובי×</translation>
<translation id="8820817407110198400">סימניות</translation>
@@ -838,29 +913,30 @@ Del</translation>
<translation id="8870413625673593573">נסגרו ל×חרונה</translation>
<translation id="8874824191258364635">עליך להזין מספר כרטיס חוקי</translation>
<translation id="8876793034577346603">ניתוח תצורת הרשת נכשל.</translation>
-<translation id="8877192140621905067">ברגע שת×שר, פרטי הכרטיס שלך ישותפו ×¢× ×”×תר ×”×–×”</translation>
<translation id="8889402386540077796">גוון</translation>
<translation id="8891727572606052622">â€×ž×¦×‘ שרת Proxy ×œ× ×—×•×§×™.</translation>
<translation id="889901481107108152">מצטערי×, ניסוי ×–×” ×ינו זמין בפלטפורמה שלך.</translation>
<translation id="8903921497873541725">התקרב</translation>
<translation id="8931333241327730545">â€×”×× ×‘×¨×¦×•× ×š לשמור ×ת הכרטיס ×”×–×” בחשבון Google שלך?</translation>
<translation id="8932102934695377596">השעון שלך מ×חר</translation>
-<translation id="8954894007019320973">(המשך)</translation>
<translation id="8971063699422889582">פג תוקפו של ×ישור השרת.</translation>
<translation id="8986494364107987395">â€×©×œ×— ל-Google דוחות קריסה וסטטיסטיקת שימוש ב×ופן ×וטומטי</translation>
-<translation id="8987927404178983737">חודש</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">×”×תר ש×תה עומד לעבור ×ליו מכיל תוכניות מזיקות</translation>
+<translation id="8997023839087525404">השרת הציג ×ישור ×©×œ× × ×—×©×£ ב×ופן ציבורי בעזרת מדיניות 'שקיפות ×ישורי×'. זוהי דרישה עבור חלק מה×ישורי×, ומטרתה ×œ×•×•×“× ×©×”× ×ž×”×™×ž× ×™× ×•×›×“×™ להגן מפני תוקפי×.</translation>
<translation id="9001074447101275817">â€×©×¨×ª ×”-proxy â€<ph name="DOMAIN" /> מצריך ×©× ×ž×©×ª×ž×© וסיסמה.</translation>
+<translation id="9005998258318286617">â€×”טעינה של מסמך ×”-PDF נכשלה.</translation>
<translation id="901974403500617787">רק ×”×‘×¢×œ×™× ×™×›×•×œ להגדיר ×¡×™×ž×•× ×™× ×”×—×œ×™× ×¢×œ כל המערכת: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">יש להזין ×ת הכתובת לחיוב של הכרטיס</translation>
<translation id="9020542370529661692">הדף ×”×–×” ×ª×•×¨×’× ×œ<ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">שגי×ת ×בטחה</translation>
<translation id="9038649477754266430">השתמש בשירות חיזוי כדי לטעון ×“×¤×™× ×ž×”×¨ יותר</translation>
<translation id="9039213469156557790">כמו כן, דף ×–×” כולל מש××‘×™× × ×•×¡×¤×™× ×©××™× × ×ž×ובטחי×. ×’×•×¨×ž×™× ××—×¨×™× ×¢×œ×•×œ×™× ×œ×¨×ות ×ת המש××‘×™× ×”×לה במהלך העברת×, ותוקף עלול לשנות ××•×ª× ×‘×ופן שישנה ×ת התנהגות הדף.</translation>
-<translation id="9040185888511745258">×ª×•×§×¤×™× ×‘-<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ×¢×©×•×™×™× ×œ× ×¡×•×ª ×œ×”×¢×¨×™× ×¢×œ×™×š ×•×œ×’×¨×•× ×œ×š להתקין תוכניות שיפגעו בחוויית הגלישה שלך (לדוגמה, על ידי שינוי דף הבית ×ו הצגת מודעות נוספות ב××ª×¨×™× ×©×‘×”× ×תה מבקר).</translation>
+<translation id="9049981332609050619">ניסית להגיע ל-<ph name="DOMAIN" />, ×ך השרת הציג ×ישור ×œ× ×—×•×§×™.</translation>
<translation id="9050666287014529139">משפט-סיסמה</translation>
<translation id="9065203028668620118">ערוך</translation>
<translation id="9068849894565669697">בחירת צבע</translation>
+<translation id="9069693763241529744">נחסמה על-ידי תוסף</translation>
<translation id="9076283476770535406">ייתכן שה×תר מכיל תוכן למבוגרי×</translation>
<translation id="9078964945751709336">נדרש מידע נוסף</translation>
<translation id="9103872766612412690">â€×”×תר <ph name="SITE" /> משתמש בדרך כלל בהצפנה כדי להגן על המידע שלך. ×›×שר Chromium ניסה ×”×¤×¢× ×œ×”×ª×—×‘×¨ ל-<ph name="SITE" />, ×”×תר שלח חזרה ××™×©×•×¨×™× ×—×¨×™×’×™× ×•×©×’×•×™×™×. ייתכן שתוקף מנסה להתחזות ל×תר <ph name="SITE" />, ×ו שמסך כניסה ל-Wi-Fi הפריע לחיבור. המידע שלך עדיין מ×ובטח מכיוון ש-Chromium הפסיק ×ת החיבור לפני חילופי הנתוני×.</translation>
@@ -869,16 +945,21 @@ Del</translation>
<translation id="9148507642005240123">&amp;ביטול עריכה</translation>
<translation id="9154194610265714752">עודכן</translation>
<translation id="9157595877708044936">מגדיר...</translation>
+<translation id="9169664750068251925">×—×¡×•× ×ª×ž×™×“ ב×תר ×–×”</translation>
<translation id="9170848237812810038">&amp;ביטול</translation>
<translation id="917450738466192189">×ישור השרת ×œ× ×—×•×§×™.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> נוספת}two{<ph name="SHIPPING_OPTION_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> נוספות}many{<ph name="SHIPPING_OPTION_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> נוספות}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ו-<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> נוספות}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> משתמש בפרוטוקול ש×ינו נתמך.</translation>
<translation id="9205078245616868884">×”× ×ª×•× ×™× ×©×œ×š ×ž×•×¦×¤× ×™× ×‘×מצעות ביטוי הסיסמה לסינכרון. הזן ×ותו כדי להתחיל בסינכרון.</translation>
<translation id="9207861905230894330">הוספת הפריט נכשלה.</translation>
+<translation id="9219103736887031265">תמונות</translation>
<translation id="933612690413056017">×ין חיבור ל×ינטרנט</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">נקה ×ת הטופס</translation>
<translation id="939736085109172342">תיקייה חדשה</translation>
<translation id="941721044073577244">נר××” ש×ין לך הרש××” לבקר ב×תר ×”×–×”</translation>
<translation id="969892804517981540">גירסה רשמית</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{לל×}=1{פריט ×חד}two{שני פריטי×}many{# פריטי×}other{# פריטי×}}</translation>
<translation id="988159990683914416">גירסת מפתחי×</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ja.xtb b/chromium/components/strings/components_strings_ja.xtb
index faad5f9d0ff..7a3d37dd1c9 100644
--- a/chromium/components/strings/components_strings_ja.xtb
+++ b/chromium/components/strings/components_strings_ja.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">時計回りã«å›žè»¢</translation>
<translation id="1038842779957582377">ä¸æ˜Žãªåå‰</translation>
<translation id="1050038467049342496">ä»–ã®ã‚¢ãƒ—リを終了ã™ã‚‹</translation>
-<translation id="1053591932240354961"><ph name="SITE" /> ã‹ã‚‰ã€Google Chrome ã§å‡¦ç†ã§ããªã„æš—å·åŒ–ã•ã‚ŒãŸèªè¨¼æƒ…å ±ãŒè¿”ã•ã‚ŒãŸãŸã‚ã€ç¾åœ¨ã“ã®ã‚¦ã‚§ãƒ–サイトã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやä¸æ­£ãªæ“作ã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚å°‘ã—時間をãŠãã¨ã€ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">追加ã®å–り消ã—(&amp;U)</translation>
<translation id="10614374240317010">常ã«ä¿å­˜ã—ãªã„</translation>
<translation id="106701514854093668">パソコンã®ãƒ–ックマーク</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">ãƒãƒªã‚·ãƒ¼ キャッシュã¯æ­£å¸¸ã§ã™</translation>
<translation id="113188000913989374"><ph name="SITE" /> ã®å†…容:</translation>
<translation id="1132774398110320017">Chrome ã®è‡ªå‹•å…¥åŠ›è¨­å®š...</translation>
+<translation id="1150979032973867961">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ã€ã”使用ã®ãƒ‘ソコンã®ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚° システムã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
+<translation id="1151972924205500581">パスワードを入力ã—ã¦ãã ã•ã„</translation>
<translation id="1152921474424827756"><ph name="URL" /> ã®<ph name="BEGIN_LINK" />キャッシュ コピー<ph name="END_LINK" />ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¾ã™</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ã«ã‚ˆã‚Šé€”中ã§æŽ¥ç¶šãŒåˆ‡æ–­ã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="1161325031994447685">Wi-Fi ã«å†åº¦æŽ¥ç¶šã™ã‚‹</translation>
+<translation id="1165039591588034296">エラー</translation>
<translation id="1175364870820465910">å°åˆ·(&amp;P)...</translation>
<translation id="1181037720776840403">削除</translation>
<translation id="1184214524891303587">セキュリティã«é–¢ã™ã‚‹äº‹è±¡ã«ã¤ã„ã¦ã®è©³ç´°ã‚’ Google ã«<ph name="BEGIN_WHITEPAPER_LINK" />自動é€ä¿¡<ph name="END_WHITEPAPER_LINK" />ã™ã‚‹ã€‚<ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">ã“ã®ã‚µã‚¤ãƒˆã‹ã‚‰ã®ä»–ã®å±¥æ­´</translation>
<translation id="1206967143813997005">最åˆã®ç½²åã«å•é¡ŒãŒã‚ã‚Šã¾ã™</translation>
<translation id="1209206284964581585">今ã¯è¡¨ç¤ºã—ãªã„</translation>
+<translation id="121201262018556460"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã«ã¯è„†å¼±ãªæš—å·éµãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚悪æ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ç§˜å¯†éµãŒç ´ã‚‰ã‚ŒãŸå¯èƒ½æ€§ãŒã‚ã‚Šã€ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ãŸã‚µãƒ¼ãƒãƒ¼ã¨ã¯ç•°ãªã‚‹ã‚µãƒ¼ãƒãƒ¼ã§ã‚ã‚‹ãŠãã‚ŒãŒã‚ã‚Šã¾ã™ï¼ˆæ‚ªæ„ã®ã‚るユーザーã¨é€šä¿¡ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼‰ã€‚</translation>
<translation id="1219129156119358924">システム セキュリティ</translation>
<translation id="1227224963052638717">ä¸æ˜Žãªãƒãƒªã‚·ãƒ¼ã€‚</translation>
<translation id="1227633850867390598">値をéžè¡¨ç¤º</translation>
<translation id="1228893227497259893">エンティティ識別å­ãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“</translation>
<translation id="1232569758102978740">無題</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />(åŒæœŸæ¸ˆã¿ï¼‰</translation>
<translation id="1263231323834454256">リーディング リスト</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" /> ã«ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ レãƒãƒ¼ãƒˆãŒä½œæˆã•ã‚Œã¾ã—ãŸï¼ˆã¾ã ã‚¢ãƒƒãƒ—ロードã•ã‚Œã¦ãŠã‚‰ãšã€ç„¡è¦–ã®æŒ‡å®šã‚‚ã‚ã‚Šã¾ã›ã‚“)</translation>
+<translation id="1281526147609854549">発行元: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">å±é™ºãªã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒãƒ–ロックã•ã‚Œã¾ã—ãŸ</translation>
<translation id="1285320974508926690">ã“ã®ã‚µã‚¤ãƒˆã¯ç¿»è¨³ã—ãªã„</translation>
<translation id="129553762522093515">最近閉ã˜ãŸã‚¿ãƒ–</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Cookie を消去ã—ã¦ã¿ã¦ãã ã•ã„<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">ãŸã ã—ã€æ¬¡ã®ç›¸æ‰‹ã«<ph name="BEGIN_EMPHASIS" />ã‚ãªãŸã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティãŒçŸ¥ã‚‰ã‚Œã‚‹<ph name="END_EMPHASIS" />å¯èƒ½æ€§ã¯ã‚ã‚Šã¾ã™ã€‚
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />訪å•å…ˆã®ã‚¦ã‚§ãƒ–サイト
+ <ph name="LIST_ITEM" />雇用主ã¾ãŸã¯å­¦æ ¡
+ <ph name="LIST_ITEM" />ã”利用ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆ サービス プロãƒã‚¤ãƒ€
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">登録ドメイン:</translation>
<translation id="1340482604681802745">引å–å…ˆä½æ‰€</translation>
<translation id="1344211575059133124">ã“ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯è¨±å¯ãŒå¿…è¦ã§ã™</translation>
<translation id="1344588688991793829">Chromium ã®è‡ªå‹•å…¥åŠ›è¨­å®š...</translation>
+<translation id="1348198688976932919">アクセス先ã®ã‚µã‚¤ãƒˆã«ã¯å±é™ºãªã‚¢ãƒ—リãŒã‚ã‚Šã¾ã™</translation>
<translation id="1374468813861204354">ヒント</translation>
<translation id="1375198122581997741">ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±</translation>
<translation id="1377321085342047638">カード番å·</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ãŒé€ä¿¡ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="1407135791313364759">ã™ã¹ã¦é–‹ã</translation>
<translation id="1413809658975081374">プライãƒã‚·ãƒ¼ エラー</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" /> ã® <ph name="ORGANIZATION" /> ã® ID ã¯ã€<ph name="ISSUER" /> ã«ã‚ˆã£ã¦ç¢ºèªæ¸ˆã¿ã§ã™ã€‚</translation>
<translation id="1426410128494586442">ã¯ã„</translation>
<translation id="1430915738399379752">å°åˆ·</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> ã®ãƒšãƒ¼ã‚¸ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹<ph name="END_LINK" />ãŒãƒ–ロックã•ã‚Œã¾ã—ãŸã€‚</translation>
-<translation id="1491663344921578213"><ph name="SITE" /> ã§ã¯è¨¼æ˜Žæ›¸ã®ãƒ”ン留ã‚ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ç¾åœ¨ã“ã®ã‚¦ã‚§ãƒ–サイトã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやä¸æ­£ãªæ“作ã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚å°‘ã—時間をãŠãã¨ã€ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> 件)}other{<ph name="PAYMENT_METHOD_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> 件)}}</translation>
<translation id="1506687042165942984">ã“ã®ãƒšãƒ¼ã‚¸ã®ä¿å­˜ã•ã‚Œã¦ã„るコピー(å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’表示ã—ã¾ã™ã€‚</translation>
<translation id="1517433312004943670">電話番å·ãŒå¿…è¦ã§ã™</translation>
<translation id="1519264250979466059">ビルド日</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">ã“ã®æ©Ÿèƒ½ã‚’使用ã™ã‚‹ã«ã¯ JavaScript を有効ã«ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="1555130319947370107">é’</translation>
<translation id="1559528461873125649">該当ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒã‚ã‚Šã¾ã›ã‚“</translation>
-<translation id="1559572115229829303">&lt;p&gt;デãƒã‚¤ã‚¹ã®æ—¥æ™‚(<ph name="DATE_AND_TIME" />)ãŒæ­£ã—ããªã„ãŸã‚ã€<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ã¸ã®ãƒ—ライベート接続を確立ã§ãã¾ã›ã‚“。&lt;/p&gt;
-
- &lt;p&gt;&lt;strong&gt;設定&lt;/strong&gt;アプリ㮠[&lt;strong&gt;全般&lt;/strong&gt;] セクションã§æ—¥æ™‚を調整ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
<translation id="1583429793053364125">ã“ã®ã‚¦ã‚§ãƒ–ページを表示中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</translation>
<translation id="1592005682883173041">ローカルデータã¸ã®ã‚¢ã‚¯ã‚»ã‚¹</translation>
+<translation id="1594030484168838125">é¸æŠž</translation>
<translation id="161042844686301425">シアン</translation>
+<translation id="1620510694547887537">カメラ</translation>
<translation id="1629803312968146339">Chrome ã«ã“ã®ã‚«ãƒ¼ãƒ‰ã‚’ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ</translation>
<translation id="1639239467298939599">読ã¿è¾¼ã¿ä¸­</translation>
<translation id="1640180200866533862">ユーザー ãƒãƒªã‚·ãƒ¼</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨­å®šãŒç„¡åŠ¹ãªãŸã‚インãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="1644574205037202324">履歴</translation>
<translation id="1645368109819982629">サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„プロトコルã§ã™</translation>
+<translation id="1655462015569774233">{1,plural, =1{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã®æœ‰åŠ¹æœŸé™ãŒæ˜¨æ—¥ä»˜ã‘ã§åˆ‡ã‚Œã¦ã„ã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚パソコンã®æ™‚計ã¯ç¾åœ¨ <ph name="CURRENT_DATE" />ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®æ™‚刻ãŒæ­£ã—ããªã„å ´åˆã¯ã€ã‚·ã‚¹ãƒ†ãƒ ã®æ™‚計を修正ã—ãŸå¾Œã“ã®ãƒšãƒ¼ã‚¸ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。}other{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã®æœ‰åŠ¹æœŸé™ãŒ # æ—¥å‰ã«åˆ‡ã‚Œã¦ã„ã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚パソコンã®æ™‚計ã¯ç¾åœ¨ <ph name="CURRENT_DATE" />ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®æ™‚刻ãŒæ­£ã—ããªã„å ´åˆã¯ã€ã‚·ã‚¹ãƒ†ãƒ ã®æ™‚計を修正ã—ãŸå¾Œã“ã®ãƒšãƒ¼ã‚¸ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。}}</translation>
<translation id="1656489000284462475">引å–</translation>
<translation id="1663943134801823270">Chrome ã«ä¿å­˜ã•ã‚Œã¦ã„るクレジット カードã¨ä½æ‰€ã§ã™ã€‚[<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />] ã§ç®¡ç†ã§ãã¾ã™ã€‚</translation>
<translation id="1676269943528358898"><ph name="SITE" /> ã§ã¯é€šå¸¸ã€æš—å·åŒ–ã—ã¦æƒ…報をä¿è­·ã—ã¦ã„ã¾ã™ã€‚今回ã€Google Chrome ã‹ã‚‰ <ph name="SITE" /> ã¸ã®æŽ¥ç¶šè©¦è¡Œæ™‚ã«ã€ã“ã®ã‚¦ã‚§ãƒ–サイトã‹ã‚‰ã„ã¤ã‚‚ã¨ã¯ç•°ãªã‚‹èª¤ã£ãŸèªè¨¼æƒ…å ±ãŒè¿”ã•ã‚Œã¾ã—ãŸã€‚悪æ„ã®ã‚るユーザー㌠<ph name="SITE" /> ã«ãªã‚Šã™ã¾ãã†ã¨ã—ã¦ã„ã‚‹ã‹ã€Wi-Fi ログイン画é¢ã§æŽ¥ç¶šãŒä¸­æ–­ã•ã‚ŒãŸå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚データã®ã‚„ã‚Šå–ã‚ŠãŒè¡Œã‚れるå‰ã« Google Chrome ã«ã‚ˆã£ã¦æŽ¥ç¶šãŒåœæ­¢ã•ã‚ŒãŸãŸã‚ã€æƒ…å ±ã¯å¼•ã続ãä¿è­·ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
-<translation id="168328519870909584"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ç¾åœ¨ã€æ‚ªæ„ã®ã‚るユーザーãŒã€ãŠä½¿ã„ã®ãƒ‡ãƒã‚¤ã‚¹ã«å±é™ºãªã‚¢ãƒ—リ(写真ã€ãƒ‘スワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード番å·ãªã©ã‚’ç›—ã¿å–ã‚‹ã‹å‰Šé™¤ã™ã‚‹ã‚¢ãƒ—リ)をインストールã—よã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="168841957122794586">サーãƒãƒ¼è¨¼æ˜Žæ›¸ã«è„†å¼±ãªæš—å·éµãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚</translation>
+<translation id="1706954506755087368">{1,plural, =1{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã¯ãŠãらã明日以é™ã«åˆ©ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚}other{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã¯ãŠãらã # 日後ã‹ã‚‰åˆ©ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">ã“ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ <ph name="NAME" /> ã•ã‚“ã®è¨±å¯ãŒå¿…è¦ã§ã™</translation>
<translation id="1721424275792716183">* 必須欄ã§ã™</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">後ã§ãƒšãƒ¼ã‚¸ã‚’ダウンロード</translation>
<translation id="17513872634828108">é–‹ã„ã¦ã„るタブ</translation>
<translation id="1753706481035618306">ページ番å·</translation>
+<translation id="1763864636252898013">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ã€ã”使用ã®ãƒ‡ãƒã‚¤ã‚¹ã®ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚° システムã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨ºæ–­ãƒ„ールを実行ã—ã¦ã¿ã¦ãã ã•ã„<ph name="END_LINK" />。</translation>
<translation id="1783075131180517613">åŒæœŸãƒ‘スフレーズを更新ã—ã¦ãã ã•ã„。</translation>
<translation id="1787142507584202372">最近開ã„ãŸã‚¿ãƒ–ãŒã“ã“ã«è¡¨ç¤ºã•ã‚Œã¾ã™</translation>
+<translation id="1789575671122666129">ãƒãƒƒãƒ—アップ</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">カードå義人</translation>
-<translation id="1803678881841855883"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Šã€<ph name="BEGIN_LINK" />ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ãŒæ¤œå‡º<ph name="END_LINK" />ã•ã‚Œã¾ã—ãŸã€‚通常ã¯å®‰å…¨ãªã‚¦ã‚§ãƒ–サイトã§ã‚ã£ã¦ã‚‚ã€ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã«æ„ŸæŸ“ã—ã¦ã„ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚今回ã®æ‚ªæ„ã®ã‚るコンテンツã¯ã€ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®æ—¢çŸ¥ã®é…布元ã§ã‚る「<ph name="SUBRESOURCE_HOST" />ã€ã‹ã‚‰é€ã‚‰ã‚Œã¦ãã¾ã—ãŸã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">追加日: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">無効ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆã¾ãŸã¯ãƒªã‚¯ã‚¨ã‚¹ãƒˆ パラメータã§ã™</translation>
<translation id="1826516787628120939">確èªä¸­</translation>
<translation id="1834321415901700177">ã“ã®ã‚µã‚¤ãƒˆã«ã¯æœ‰å®³ãªãƒ—ログラムãŒå«ã¾ã‚Œã¦ã„ã¾ã™</translation>
+<translation id="1840414022444569775">ã“ã®ã‚«ãƒ¼ãƒ‰ç•ªå·ã¯ã™ã§ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™</translation>
<translation id="1842969606798536927">ãŠæ”¯æ‰•ã„</translation>
<translation id="1871208020102129563">プロキシ㯠.pac スクリプト URL ã§ã¯ãªã固定プロキシ サーãƒãƒ¼ã‚’使用ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="1871284979644508959">必須フィールド</translation>
<translation id="187918866476621466">起動ページを開ã</translation>
<translation id="1883255238294161206">リストを折りãŸãŸã‚€</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 件)}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 件)}}</translation>
<translation id="1898423065542865115">フィルタ</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{ãªã—}=1{1 件ã®ã‚µã‚¤ãƒˆ}other{# 件ã®ã‚µã‚¤ãƒˆ}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> ã«ç§»å‹•ã—ã¾ã™</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> ã®ãƒ–ックマーク</translation>
<translation id="1973335181906896915">シリアル化エラーã§ã™</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> ã«ã‚ˆã£ã¦ä¸Šæ›¸ãã•ã‚Œã‚‹ãŸã‚無視ã•ã‚Œã¾ã™ã€‚</translation>
<translation id="2138201775715568214">è¿‘ãã®ãƒ•ã‚£ã‚¸ã‚«ãƒ« ウェブページを探ã—ã¦ã„ã¾ã™</translation>
<translation id="213826338245044447">モãƒã‚¤ãƒ«ã®ãƒ–ックマーク</translation>
-<translation id="2148716181193084225">今日</translation>
+<translation id="2147827593068025794">ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰åŒæœŸ</translation>
<translation id="2154054054215849342">ãŠä½¿ã„ã®ãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã¯åŒæœŸæ©Ÿèƒ½ã‚’ã”利用ã„ãŸã ã‘ã¾ã›ã‚“</translation>
<translation id="2154484045852737596">カードを編集</translation>
<translation id="2166049586286450108">ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ã¸ã®ç®¡ç†è€…アクセス</translation>
<translation id="2166378884831602661">ã“ã®ã‚µã‚¤ãƒˆã¯å®‰å…¨ã«æŽ¥ç¶šã§ãã¾ã›ã‚“</translation>
<translation id="2181821976797666341">ãƒãƒªã‚·ãƒ¼</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 件ã®ã‚¢ãƒ‰ãƒ¬ã‚¹}other{# 件ã®ã‚¢ãƒ‰ãƒ¬ã‚¹}}</translation>
+<translation id="2187317261103489799">検出(デフォルト)</translation>
<translation id="2202020181578195191">有効期é™ï¼ˆå¹´ï¼‰ã‚’æ­£ã—ã„å½¢å¼ã§å…¥åŠ›ã—ã¦ãã ã•ã„</translation>
<translation id="2212735316055980242">ãƒãƒªã‚·ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“</translation>
<translation id="2213606439339815911">エントリをå–å¾—ã—ã¦ã„ã¾ã™...</translation>
+<translation id="2218879909401188352"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ç¾åœ¨ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦å±é™ºãªã‚¢ãƒ—リ(端末ã«å•é¡Œã‚’生ã˜ãŸã‚Šã€ãƒ¢ãƒã‚¤ãƒ«åˆ©ç”¨æ–™ã«ä¸æ˜Žçž­ãªè«‹æ±‚を加ãˆãŸã‚Šã€å€‹äººæƒ…報を抜ãå–ã£ãŸã‚Šã™ã‚‹ã‚¢ãƒ—リ)ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />診断アプリ<ph name="END_LINK" />を使用ã—ã¦æŽ¥ç¶šã‚’修正ã—ã¦ãã ã•ã„</translation>
<translation id="2239100178324503013">é€ä¿¡</translation>
<translation id="225207911366869382">ã“ã®å€¤ã¯ã€ã“ã®ãƒãƒªã‚·ãƒ¼ã§ã¯ã‚µãƒãƒ¼ãƒˆãŒçµ‚了ã—ã¦ã„ã¾ã™ã€‚</translation>
<translation id="2262243747453050782">HTTP エラーã§ã™</translation>
+<translation id="2270484714375784793">電話番å·</translation>
<translation id="2282872951544483773">利用ã§ããªã„試験é‹ç”¨æ©Ÿèƒ½</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> 件ã®ã‚¢ã‚¤ãƒ†ãƒ }other{<ph name="ITEM_COUNT" /> 件ã®ã‚¢ã‚¤ãƒ†ãƒ }}</translation>
<translation id="2292556288342944218">インターãƒãƒƒãƒˆ アクセスãŒãƒ–ロックã•ã‚Œã¦ã„ã¾ã™</translation>
<translation id="230155334948463882">カード情報を更新</translation>
-<translation id="2305919008529760154">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ä¸æ­£ã«ç™ºè¡Œã•ã‚ŒãŸã‚‚ã®ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> ã«ã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¨ãƒ‘スワードãŒå¿…è¦ã§ã™ã€‚</translation>
-<translation id="2318774815570432836"><ph name="SITE" /> ã§ã¯ HSTS ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ç¾åœ¨ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやä¸æ­£ãªæ“作ã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚å°‘ã—時間をãŠãã¨ã€ã¾ãŸãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">管ç†è€…ãŒæŒ‡å®šã™ã‚‹è¨­å®š</translation>
<translation id="2354001756790975382">ãã®ä»–ã®ãƒ–ックマーク</translation>
+<translation id="2354430244986887761"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Š<ph name="BEGIN_LINK" />有害ãªã‚¢ãƒ—リãŒæ¤œå‡º<ph name="END_LINK" />ã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="2355395290879513365">ã“ã®ã‚µã‚¤ãƒˆã§ç›®ã«ã™ã‚‹ç”»åƒã¯ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦å·®ã—替ãˆã‚‰ã‚ŒãŸã‚‚ã®ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
+<translation id="2356070529366658676">確èªã™ã‚‹</translation>
+<translation id="2359629602545592467">複数</translation>
<translation id="2359808026110333948">続行</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> ã«ä½œæˆã•ã‚ŒãŸã‚¯ãƒ©ãƒƒã‚·ãƒ¥ レãƒãƒ¼ãƒˆã¯ã‚¢ãƒƒãƒ—ロードã•ã‚Œã¾ã›ã‚“ã§ã—ãŸ</translation>
<translation id="2367567093518048410">レベル</translation>
-<translation id="2371153335857947666">{1,plural, =1{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã®æœ‰åŠ¹æœŸé™ãŒæ˜¨æ—¥ä»˜ã‘ã§åˆ‡ã‚Œã¦ã„ã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚パソコンã®æ™‚計ã¯ç¾åœ¨ <ph name="CURRENT_DATE" />ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®æ™‚刻ãŒæ­£ã—ããªã„å ´åˆã¯ã€ã‚·ã‚¹ãƒ†ãƒ ã®æ™‚計を修正ã—ã¦ã€ã“ã®ãƒšãƒ¼ã‚¸ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" />}other{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã®æœ‰åŠ¹æœŸé™ãŒ # æ—¥å‰ã«åˆ‡ã‚Œã¦ã„ã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚パソコンã®æ™‚計ã¯ç¾åœ¨ <ph name="CURRENT_DATE" />ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®æ™‚刻ãŒæ­£ã—ããªã„å ´åˆã¯ã€ã‚·ã‚¹ãƒ†ãƒ ã®æ™‚計を修正ã—ã¦ã€ã“ã®ãƒšãƒ¼ã‚¸ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">代替ユーザーインターフェースã¯ã‚ã‚Šã¾ã›ã‚“</translation>
<translation id="2384307209577226199">ä¼æ¥­ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆ</translation>
<translation id="2386255080630008482">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ã¯å–り消ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="2392959068659972793">値ãŒè¨­å®šã•ã‚Œã¦ã„ãªã„ãƒãƒªã‚·ãƒ¼ã‚’表示ã™ã‚‹</translation>
<translation id="239429038616798445">ã“ã®é…é€æ–¹æ³•ã¯ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。別ã®æ–¹æ³•ã‚’é¸æŠžã—ã¦ãã ã•ã„。</translation>
<translation id="2396249848217231973">削除ã®å–り消ã—(&amp;U)</translation>
-<translation id="2460160116472764928"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Šã€<ph name="BEGIN_LINK" />ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ãŒæ¤œå‡º<ph name="END_LINK" />ã•ã‚Œã¾ã—ãŸã€‚通常ã¯å®‰å…¨ãªã‚¦ã‚§ãƒ–サイトã§ã‚ã£ã¦ã‚‚ã€ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã«æ„ŸæŸ“ã—ã¦ã„ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯å–り消ã•ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
<translation id="2463739503403862330">入力ã™ã‚‹</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨ºæ–­ãƒ„ールを実行ã™ã‚‹<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">検索 URL ãŒç„¡åŠ¹ã§ã™ã€‚</translation>
+<translation id="2482878487686419369">通知</translation>
<translation id="2491120439723279231">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ã«ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="2495083838625180221">JSON パーサー</translation>
<translation id="2495093607237746763">ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’オンã«ã™ã‚‹ã¨ã€Chromium ãŒã‚«ãƒ¼ãƒ‰æƒ…報をã“ã®ç«¯æœ«ã«ä¿å­˜ã™ã‚‹ãŸã‚フォームã«ã™ã°ã‚„ã入力ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">戻る</translation>
<translation id="2515629240566999685">電波状æ³ã‚’確èªã™ã‚‹</translation>
<translation id="2516305470678292029">代替ユーザーインターフェース</translation>
+<translation id="2539524384386349900">検出</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ã‹ã‚‰ç„¡åŠ¹ãªå¿œç­”ãŒé€ä¿¡ã•ã‚Œã¾ã—ãŸã€‚</translation>
-<translation id="2552545117464357659">æ–°ã—ã„</translation>
<translation id="2556876185419854533">編集ã®å–り消ã—(&amp;U)</translation>
<translation id="2587730715158995865">公開元: <ph name="ARTICLE_PUBLISHER" />。ã“ã®è¨˜äº‹ã¨ä»– <ph name="OTHER_ARTICLE_COUNT" /> 件ã®è¨˜äº‹ã‚’読むã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">ã“ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã¯ãƒ‘スワードã§ä¿è­·ã•ã‚Œã¦ã„ã¾ã™ã€‚パスワードを入力ã—ã¦ãã ã•ã„。</translation>
<translation id="2609632851001447353">ãƒãƒªã‚¨ãƒ¼ã‚·ãƒ§ãƒ³</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{ãªã—}=1{1 個ã®ã‚¢ãƒ—リ($1)}=2{2 個ã®ã‚¢ãƒ—リ($1ã€$2)}other{# 個ã®ã‚¢ãƒ—リ($1ã€$2ã€$3)}}</translation>
<translation id="2625385379895617796">時計ãŒé€²ã‚“ã§ã„ã¾ã™</translation>
<translation id="2639739919103226564">ステータス:</translation>
+<translation id="2649204054376361687"><ph name="COUNTRY" /> <ph name="CITY" /></translation>
<translation id="2650446666397867134">ファイルã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•ã‚Œã¾ã—ãŸ</translation>
<translation id="2653659639078652383">é€ä¿¡</translation>
<translation id="2666117266261740852">ä»–ã®ã‚¿ãƒ–やアプリを閉ã˜ã‚‹</translation>
+<translation id="2670429602441959756">ã“ã®ãƒšãƒ¼ã‚¸ã«ã¯ VR ã§ã¾ã ã”利用ã„ãŸã ã‘ãªã„機能ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚VR モードを終了ã—ã¾ã™...</translation>
<translation id="2674170444375937751">履歴ã‹ã‚‰ã“れらã®ãƒšãƒ¼ã‚¸ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</translation>
<translation id="2677748264148917807">ã“ã®ãƒšãƒ¼ã‚¸ã‚’離れる</translation>
-<translation id="269990154133806163">サーãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã¯ã€è¨¼æ˜Žæ›¸ã®é€æ˜Žæ€§ãƒãƒªã‚·ãƒ¼ã‚’介ã—ã¦å…¬é–‹ã•ã‚Œã¦ã„ã¾ã›ã‚“。一部ã®è¨¼æ˜Žæ›¸ã¯ã€ä¿¡é ¼æ€§ã®ç¢ºä¿ã¨æ”»æ’ƒè€…ã‹ã‚‰ã®ä¿è­·ã®ãŸã‚ã€è¨¼æ˜Žæ›¸ã®é€æ˜Žæ€§ãƒãƒªã‚·ãƒ¼ã‚’介ã—ã¦å…¬é–‹ã•ã‚Œã‚‹ã“ã¨ãŒè¦ä»¶ã¨ãªã£ã¦ã„ã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">リーディング リスト</translation>
<translation id="2704283930420550640">値ãŒæœ‰åŠ¹ãªå½¢å¼ã§ã¯ã‚ã‚Šã¾ã›ã‚“。</translation>
<translation id="2704951214193499422">Chromium ã§ã‚«ãƒ¼ãƒ‰ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="2705137772291741111">ã“ã®ã‚µã‚¤ãƒˆã®ä¿å­˜ï¼ˆã‚­ãƒ£ãƒƒã‚·ãƒ¥ï¼‰ã•ã‚ŒãŸã‚³ãƒ”ーを読ã¿å–ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="2709516037105925701">自動入力</translation>
-<translation id="2712118517637785082"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã¯ç™ºè¡Œå…ƒã«ã‚ˆã‚Šå–り消ã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯ã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£èªè¨¼æƒ…å ±ãŒä¿¡é ¼ã§ããªã„ã“ã¨ã‚’示ã—ã¦ãŠã‚Šã€æ‚ªæ„ã®ã‚るユーザーã¨é€šä¿¡ã—よã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">権é™ã‚’リクエスト</translation>
<translation id="2713444072780614174">白</translation>
<translation id="2720342946869265578">周辺</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">デãƒã‚¤ã‚¹ レコードãŒã‚ã‚Šã¾ã›ã‚“</translation>
<translation id="2784949926578158345">接続ãŒãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="2794233252405721443">サイトãŒãƒ–ロックã•ã‚Œã¦ã„ã¾ã™</translation>
+<translation id="2799020568854403057">アクセス先ã®ã‚µã‚¤ãƒˆã«ã¯æœ‰å®³ãªã‚¢ãƒ—リãŒã‚ã‚Šã¾ã™</translation>
+<translation id="2803306138276472711"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Šã€<ph name="BEGIN_LINK" />ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ<ph name="END_LINK" />。通常ã¯å®‰å…¨ãªã‚¦ã‚§ãƒ–サイトã§ã‚ã£ã¦ã‚‚ã€ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã«æ„ŸæŸ“ã—ã¦ã„ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="2824775600643448204">アドレス検索ãƒãƒ¼</translation>
<translation id="2826760142808435982">接続㯠<ph name="CIPHER" /> を使用ã—ã¦æš—å·åŒ–ãŠã‚ˆã³èªè¨¼ã•ã‚Œã¦ãŠã‚Šã€<ph name="KX" /> ãŒéµäº¤æ›ãƒ¡ã‚«ãƒ‹ã‚ºãƒ ã¨ã—ã¦ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="2835170189407361413">フォームをクリア</translation>
+<translation id="2856444702002559011"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€ãƒ‘スワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードãªã©ã®æƒ…å ±ãŒç›—ã¾ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">å†èª­ã¿è¾¼ã¿ã‚’中止</translation>
<translation id="2900469785430194048">ã“ã®ã‚¦ã‚§ãƒ–ページを表示ã—よã†ã¨ã—ã¾ã—ãŸãŒã€Google Chrome ã®ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚</translation>
<translation id="2909946352844186028">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã®å¤‰æ›´ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="2916038427272391327">ä»–ã®ãƒ—ログラムを終了ã™ã‚‹</translation>
<translation id="2922350208395188000">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ã‚’確èªã§ãã¾ã›ã‚“。</translation>
<translation id="2928905813689894207">請求先ä½æ‰€</translation>
+<translation id="2941952326391522266">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ <ph name="DOMAIN2" /> ã‹ã‚‰ç™ºè¡Œã•ã‚Œã¦ã„ã¾ã™ã€‚原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
<translation id="2948083400971632585">接続用ã«è¨­å®šã•ã‚ŒãŸãƒ—ロキシã¯ã€è¨­å®šãƒšãƒ¼ã‚¸ã§ç„¡åŠ¹ã«ã§ãã¾ã™ã€‚</translation>
<translation id="2955913368246107853">検索ãƒãƒ¼ã‚’é–‰ã˜ã‚‹</translation>
<translation id="2958431318199492670">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨­å®šãŒ ONC 標準ã«æº–æ‹ ã—ã¦ã„ã¾ã›ã‚“。設定ã®ä¸€éƒ¨ãŒã‚¤ãƒ³ãƒãƒ¼ãƒˆã•ã‚Œãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
-<translation id="29611076221683977"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ç¾åœ¨ã€æ‚ªæ„ã®ã‚るユーザーãŒã€ãŠä½¿ã„ã® Mac ã«å±é™ºãªãƒ—ログラム(写真ã€ãƒ‘スワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード番å·ãªã©ã‚’ç›—ã¿å–ã‚‹ã‹å‰Šé™¤ã™ã‚‹ãƒ—ログラム)をインストールã—よã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="2966678944701946121">有効期é™: <ph name="EXPIRATION_DATE_ABBR" />ã€è¿½åŠ æ—¥: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">安全ãªæŽ¥ç¶šã‚’確立ã™ã‚‹ã«ã¯ã€æ™‚計ãŒæ­£ã—ã設定ã•ã‚Œã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ã“ã‚Œã¯ã€ã‚¦ã‚§ãƒ–サイトãŒè‡ªèº«ã‚’証明ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹è¨¼æ˜Žæ›¸ã«ã¯æœ‰åŠ¹æœŸé™ãŒã‚ã‚‹ãŸã‚ã§ã™ã€‚デãƒã‚¤ã‚¹ã®æ™‚計ãŒæ­£ã—ããªã„ãŸã‚ã€Google Chrome ã§ã“れらã®è¨¼æ˜Žæ›¸ã‚’確èªã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。</translation>
<translation id="2972581237482394796">ã‚„ã‚Šç›´ã—(&amp;R)</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">有効ãªä½æ‰€ã‚’入力ã—ã¦ãã ã•ã„</translation>
<translation id="2986368408720340940">ã“ã®å—ã‘å–り方法ã¯ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。別ã®æ–¹æ³•ã‚’é¸æŠžã—ã¦ãã ã•ã„。</translation>
<translation id="2991174974383378012">ウェブサイトã¨ã®å…±æœ‰</translation>
+<translation id="2991571918955627853"><ph name="SITE" /> ã§ã¯ HSTS ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ç¾åœ¨ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã¸ã®æ”»æ’ƒã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚ã—ã°ã‚‰ãã™ã‚‹ã¨ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚</translation>
<translation id="3005723025932146533">ä¿å­˜æ¸ˆã¿ã®ã‚³ãƒ”ーを表示</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> ã® CVC を入力ã—ã¾ã™ã€‚確èªã‚’è¡Œã†ã¨ã€ã‚«ãƒ¼ãƒ‰ã®è©³ç´°ãŒã“ã®ã‚µã‚¤ãƒˆã¨å…±æœ‰ã•ã‚Œã¾ã™ã€‚</translation>
<translation id="3010559122411665027">リスト エントリ「<ph name="ENTRY_INDEX" />ã€: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">自動ブロックã•ã‚Œã¾ã—ãŸ</translation>
<translation id="3024663005179499861">ãƒãƒªã‚·ãƒ¼ タイプãŒé–“é•ã£ã¦ã„ã¾ã™</translation>
<translation id="3032412215588512954">ã“ã®ã‚µã‚¤ãƒˆã‚’å†èª­ã¿è¾¼ã¿ã—ã¾ã™ã‹ï¼Ÿ</translation>
<translation id="3037605927509011580">エラー</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{åŒæœŸãƒ‡ãƒã‚¤ã‚¹ã§ 1 件以上ã®ã‚¢ã‚¤ãƒ†ãƒ }=1{1 件ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼ˆåŒæœŸãƒ‡ãƒã‚¤ã‚¹ã§ã¯ãれ以上ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼‰}other{# 件ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼ˆåŒæœŸãƒ‡ãƒã‚¤ã‚¹ã§ã¯ãれ以上ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼‰}}</translation>
<translation id="3041612393474885105">証明書情報</translation>
<translation id="3063697135517575841">Chrome ã§ã‚«ãƒ¼ãƒ‰ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="3064966200440839136">外部アプリケーションを経由ã—ãŸãŠæ”¯æ‰•ã„ã®å‡¦ç†ã«é€²ã‚€ãŸã‚ã€ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆ モードを解除ã—ã¾ã™ã€‚続行ã—ã¾ã™ã‹ï¼Ÿ</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{ãªã—}=1{1 個ã®ãƒ‘スワード}other{# 個ã®ãƒ‘スワード}}</translation>
<translation id="3093245981617870298">ç¾åœ¨ã‚ªãƒ•ãƒ©ã‚¤ãƒ³ã§ã™ã€‚</translation>
<translation id="3105172416063519923">アセット ID:</translation>
<translation id="3109728660330352905">ã“ã®ãƒšãƒ¼ã‚¸ã‚’表示ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。</translation>
+<translation id="3120730422813725195">ELO</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />接続診断ツールを実行ã—ã¦ã¿ã¦ãã ã•ã„<ph name="END_LINK" />。</translation>
<translation id="3145945101586104090">応答をデコードã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
<translation id="3150653042067488994">一時的ãªã‚µãƒ¼ãƒãƒ¼ エラーã§ã™</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">シークレット タブã§è¡¨ç¤ºã—ãŸãƒšãƒ¼ã‚¸ã®è¨˜éŒ²ã¯ã€ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆ タブをã™ã¹ã¦é–‰ã˜ãŸå¾Œã€ãƒ–ラウザã®å±¥æ­´ã€Cookie ã®ä¿å­˜å ´æ‰€ã€æ¤œç´¢å±¥æ­´ã‹ã‚‰æ¶ˆåŽ»ã•ã‚Œã¾ã™ã€‚ãŸã ã—ã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚„作æˆã—ãŸãƒ–ックマークã¯ä¿å­˜ã•ã‚Œã¾ã™ã€‚</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">島</translation>
+<translation id="317583078218509884">サイトã®æ–°ã—ã„権é™è¨­å®šã¯ãƒšãƒ¼ã‚¸ã®å†èª­ã¿è¾¼ã¿å¾Œã«æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚</translation>
<translation id="3176929007561373547">プロキシã®è¨­å®šã‚’確èªã™ã‚‹ã‹ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ç®¡ç†è€…ã«å•ã„åˆã‚ã›ã¦ã€ãƒ—ロキシ サーãƒãƒ¼ãŒæ­£å¸¸ã«
動作ã—ã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¦ãã ã•ã„。プロキシ サーãƒãƒ¼ã‚’使用ã—ã¦ã„ãªã„å ´åˆã¯
次ã®æ–¹æ³•ã‚’ãŠè©¦ã—ãã ã•ã„。
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">ページをシークレット モードã§é–‹ã</translation>
-<translation id="3202578601642193415">最新</translation>
+<translation id="320323717674993345">支払ã„をキャンセル</translation>
<translation id="3207960819495026254">ブックマークã—ã¾ã—ãŸ</translation>
+<translation id="3225919329040284222">サーãƒãƒ¼ã®æ示ã—ãŸè¨¼æ˜Žæ›¸ãŒã€çµ„ã¿è¾¼ã¾ã‚Œã¦ã„る想定ã®è¨¼æ˜Žæ›¸ã¨ä¸€è‡´ã—ã¾ã›ã‚“。ã“れらã®æƒ³å®šã®è¨¼æ˜Žæ›¸ã¯ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ä¿è­·ã®ãŸã‚ã€ç‰¹å®šã®å®‰å…¨æ€§ã®é«˜ã„ウェブサイトã«ã¤ã„ã¦ç”¨æ„ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="3226128629678568754">ページã®èª­ã¿è¾¼ã¿ã«å¿…è¦ãªãƒ‡ãƒ¼ã‚¿ã‚’å†é€ä¿¡ã™ã‚‹ã«ã¯ã€å†èª­ã¿è¾¼ã¿ãƒœã‚¿ãƒ³ã‚’押ã—ã¦ãã ã•ã„。</translation>
+<translation id="3227137524299004712">マイク</translation>
<translation id="3228969707346345236">ã“ã®ãƒšãƒ¼ã‚¸ã¯æ—¢ã«<ph name="LANGUAGE" />ãªã®ã§ã€ç¿»è¨³ã§ãã¾ã›ã‚“。</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> 㮠CVC を入力</translation>
+<translation id="3234666976984236645">ã“ã®ã‚µã‚¤ãƒˆã®é‡è¦ãªã‚³ãƒ³ãƒ†ãƒ³ãƒ„を常ã«æ¤œå‡º</translation>
<translation id="3254409185687681395">ã“ã®ãƒšãƒ¼ã‚¸ã‚’ブックマークã«è¿½åŠ ã—ã¾ã™</translation>
<translation id="3270847123878663523">é †åºå¤‰æ›´ã®å–り消ã—(&amp;U)</translation>
<translation id="3282497668470633863">å義人åを追加</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">設定</translation>
<translation id="3345135638360864351">ã“ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’ <ph name="NAME" /> ã«é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="3355823806454867987">プロキシ設定ã®å¤‰æ›´...</translation>
+<translation id="3361596688432910856">Chrome ã«ã¯ã€<ph name="BEGIN_EMPHASIS" />次ã®æƒ…å ±ã¯<ph name="END_EMPHASIS" />ä¿å­˜ã•ã‚Œã¾ã›ã‚“。
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />閲覧履歴
+ <ph name="LIST_ITEM" />Cookie ã¨ã‚µã‚¤ãƒˆãƒ‡ãƒ¼ã‚¿
+ <ph name="LIST_ITEM" />フォームã«å…¥åŠ›ã—ãŸæƒ…å ±
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">時計ã®ã‚¨ãƒ©ãƒ¼</translation>
-<translation id="337311366426640088">ä»– <ph name="ITEM_COUNT" /> 件ã®ã‚¢ã‚¤ãƒ†ãƒ ...</translation>
<translation id="337363190475750230">プロビジョニングãŒè§£é™¤ã•ã‚Œã¾ã—ãŸ</translation>
<translation id="3377188786107721145">ãƒãƒªã‚·ãƒ¼è§£æžã‚¨ãƒ©ãƒ¼ã§ã™</translation>
<translation id="3380365263193509176">ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼</translation>
<translation id="3380864720620200369">クライアント ID:</translation>
<translation id="3391030046425686457">é…é€å…ˆä½æ‰€</translation>
<translation id="3395827396354264108">å—ã‘å–り方法</translation>
-<translation id="340013220407300675">攻撃者ãŒã€<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上ã®ã‚ãªãŸã®æƒ…報(パスワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード情報ãªã©ï¼‰ã‚’ä¸æ­£ã«å–å¾—ã—よã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="3422248202833853650">メモリを解放ã™ã‚‹ãŸã‚ã«ã€ä»–ã®ãƒ—ログラムを終了ã—ã¦ã¿ã¦ãã ã•ã„。</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> ã¯ç¾åœ¨ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。</translation>
+<translation id="3427092606871434483">許å¯ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆï¼‰</translation>
<translation id="3427342743765426898">編集ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
<translation id="3431636764301398940">ã“ã®ã‚«ãƒ¼ãƒ‰æƒ…報をã“ã®ç«¯æœ«ã«ä¿å­˜ã™ã‚‹</translation>
<translation id="3435896845095436175">有効ã«ã™ã‚‹</translation>
<translation id="3447661539832366887">ã“ã®ãƒ‡ãƒã‚¤ã‚¹ã®æ‰€æœ‰è€…ãŒæ竜ゲームを無効ã«ã—ã¦ã„ã¾ã™ã€‚</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">å–å¾—é–“éš”:</translation>
<translation id="3462200631372590220">詳細情報を表示ã—ãªã„</translation>
<translation id="3467763166455606212">カードå義人ã¯å¿…é ˆã§ã™</translation>
<translation id="3478058380795961209">有効期é™ï¼ˆæœˆï¼‰</translation>
<translation id="3479539252931486093">想定外ã®å‹•ä½œã§ã‚ã‚‹å ´åˆã¯ã€<ph name="BEGIN_LINK" />å•é¡Œã‚’報告<ph name="END_LINK" />ã—ã¦ãã ã•ã„。</translation>
<translation id="3479552764303398839">後ã§</translation>
-<translation id="348000606199325318">クラッシュ ID <ph name="CRASH_LOCAL_ID" />(サーãƒãƒ¼ ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">ç¾åœ¨ã€ä¿è­·è€…ã«ãŸãšã­ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。もã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="3528171143076753409">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ã‚’ä¿¡é ¼ã§ãã¾ã›ã‚“。</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{åŒæœŸãƒ‡ãƒã‚¤ã‚¹ã§ 1 件以上ã®ã‚¢ã‚¤ãƒ†ãƒ }=1{1 件ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼ˆåŒæœŸãƒ‡ãƒã‚¤ã‚¹ã§ã¯ãれ以上ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼‰}other{# 件ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼ˆåŒæœŸãƒ‡ãƒã‚¤ã‚¹ã§ã¯ãれ以上ã®ã‚¢ã‚¤ãƒ†ãƒ ï¼‰}}</translation>
<translation id="3539171420378717834">ã“ã®ãƒ‡ãƒã‚¤ã‚¹ã«ã“ã®ã‚«ãƒ¼ãƒ‰æƒ…å ±ã®ã‚³ãƒ”ーをä¿å­˜ã™ã‚‹</translation>
<translation id="3542684924769048008">次ã®ãƒ‘スワードを使用:</translation>
+<translation id="3545341443414427877">ãŠä½¿ã„ã®ãƒ‘ソコンã®æ—¥æ™‚(<ph name="DATE_AND_TIME" />)ãŒæ­£ã—ããªã„ãŸã‚ã€<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ã¸ã®ãƒ—ライベート接続を確立ã§ãã¾ã›ã‚“。<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">åŒæœŸãƒ‘スフレーズã§åŒæœŸãƒ‡ãƒ¼ã‚¿ã‚’ã™ã¹ã¦æš—å·åŒ–ã™ã‚‹</translation>
-<translation id="3549761410225185768">ä»– <ph name="NUM_TABS_MORE" /> 個ã®ã‚¿ãƒ–...</translation>
-<translation id="3555561725129903880">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ <ph name="DOMAIN2" /> ã‹ã‚‰ç™ºè¡Œã•ã‚Œã¦ã„ã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">ブロックã®è§£é™¤ã¯ç®¡ç†è€…ãŒè¡Œã†ã“ã¨ãŒã§ãã¾ã™</translation>
<translation id="3566021033012934673">ã“ã®æŽ¥ç¶šã§ã¯ãƒ—ライãƒã‚·ãƒ¼ãŒä¿è­·ã•ã‚Œã¾ã›ã‚“</translation>
+<translation id="3569145463236695319">&lt;p&gt;ãŠä½¿ã„ã®ç«¯æœ«ã®æ—¥æ™‚(<ph name="DATE_AND_TIME" />)ãŒæ­£ã—ããªã„ãŸã‚ã€<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ã¸ã®ãƒ—ライベート接続を確立ã§ãã¾ã›ã‚“。&lt;/p&gt;
+
+ &lt;p&gt;&lt;strong&gt;設定&lt;/strong&gt;アプリ㮠[&lt;strong&gt;全般&lt;/strong&gt;] ã§æ—¥æ™‚を調整ã—ã¦ãã ã•ã„。&lt;/p&gt;<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="COUNTRY" /> <ph name="STATE" /> <ph name="CITY" /></translation>
<translation id="3582930987043644930">åå‰ã‚’追加</translation>
<translation id="3583757800736429874">移動ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
<translation id="3586931643579894722">詳細をéžè¡¨ç¤º</translation>
-<translation id="3587482841069643663">ã™ã¹ã¦</translation>
<translation id="3600246354004376029"><ph name="TITLE" />ã€<ph name="DOMAIN" />ã€<ph name="TIME" /></translation>
<translation id="3615877443314183785">有効期é™ï¼ˆæ—¥ï¼‰ã‚’入力ã—ã¦ãã ã•ã„</translation>
<translation id="36224234498066874">閲覧履歴を消去...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">証明書情報</translation>
<translation id="3690164694835360974">ログイン情報ã¯ä¿è­·ã•ã‚Œã¾ã›ã‚“</translation>
<translation id="3693415264595406141">パスワード:</translation>
-<translation id="3696411085566228381">ãªã—</translation>
<translation id="3704609568417268905"><ph name="TIME" />ã€<ph name="TITLE" />(<ph name="DOMAIN" />)を<ph name="BOOKMARKED" /></translation>
<translation id="370665806235115550">読ã¿è¾¼ã‚“ã§ã„ã¾ã™...</translation>
<translation id="3712624925041724820">ライセンスを使ã„切りã¾ã—ãŸ</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />プロキシã€ãƒ•ã‚¡ã‚¤ã‚¢ã‚¦ã‚©ãƒ¼ãƒ«ã€DNS ã®è¨­å®šã‚’確èªã™ã‚‹<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">å±é™ºãªãƒ—ログラムãŒå‰Šé™¤ã•ã‚Œã‚‹ã‚ˆã‚Šå‰ã«<ph name="BEGIN_LINK" />ã“ã®å®‰å…¨ã§ãªã„サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹<ph name="END_LINK" />å ´åˆã¯ã€ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ä¸Šã®ãƒªã‚¹ã‚¯ã«ã¤ã„ã¦ã”承知ãŠããã ã•ã„。</translation>
<translation id="3739623965217189342">コピーã—ãŸãƒªãƒ³ã‚¯</translation>
+<translation id="3744899669254331632"><ph name="SITE" /> ã‹ã‚‰é€ä¿¡ã•ã‚ŒãŸæš—å·åŒ–済ã¿ã®èªè¨¼æƒ…報を Chromium ã§å‡¦ç†ã§ããªã„ãŸã‚ã€ç¾åœ¨ã“ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã¸ã®æ”»æ’ƒã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚ã—ã°ã‚‰ãã™ã‚‹ã¨ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚„個人情報(パスワードã€é›»è©±ç•ªå·ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードãªã©ï¼‰ã®å…¥åŠ›ã¨ã„ã£ãŸå±é™ºãªæ“作を行ã†ã‚ˆã†èª˜å°Žã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">サーãƒãƒ¼ エラーã®ãŸã‚翻訳ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="3759461132968374835">最近発生ã—ãŸéšœå®³ã¯ã‚ã‚Šã¾ã›ã‚“。障害レãƒãƒ¼ãƒˆãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã‚‹ã¨ãã«ç™ºç”Ÿã—ãŸéšœå®³ã¯ã€ã“ã“ã«ã¯è¡¨ç¤ºã•ã‚Œã¾ã›ã‚“。</translation>
+<translation id="3778403066972421603">ã“ã®ã‚«ãƒ¼ãƒ‰ã‚’ Google アカウントã¨ã“ã®ç«¯æœ«ã«ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">有効期é™: <ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">プロキシ サーãƒãƒ¼ã‚’使用ã—ã¦ã„ã‚‹å ´åˆ...</translation>
<translation id="3828924085048779000">パスフレーズã¯å¿…ãšæŒ‡å®šã—ã¦ãã ã•ã„。</translation>
-<translation id="3845539888601087042">ログインã—ã¦ã„る端末ã®å±¥æ­´ã‚’表示ã—ã¦ã„ã¾ã™ã€‚<ph name="BEGIN_LINK" />詳細<ph name="END_LINK" /></translation>
<translation id="385051799172605136">戻る</translation>
<translation id="3858027520442213535">日時を更新</translation>
<translation id="3884278016824448484">競åˆã™ã‚‹ãƒ‡ãƒã‚¤ã‚¹è­˜åˆ¥å­ã§ã™</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">ã“ã®ã‚µã‚¤ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ リクエストを <ph name="NAME" /> ã•ã‚“ã«é€ä¿¡ã—ã¾ã—ãŸ</translation>
<translation id="3890664840433101773">メールを追加</translation>
<translation id="3901925938762663762">カードã®æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚Œã¦ã„ã¾ã™</translation>
-<translation id="3933571093587347751">{1,plural, =1{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã¯ãŠãらã明日以é™ã«åˆ©ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" />}other{ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚セキュリティ証明書ã¯ãŠãらã # 日後ã‹ã‚‰åˆ©ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">PDF ドキュメントを読ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
+<translation id="3945915738023014686">クラッシュ レãƒãƒ¼ãƒˆ ID <ph name="CRASH_ID" /> ãŒã‚¢ãƒƒãƒ—ロードã•ã‚Œã¾ã—ãŸï¼ˆãƒ­ãƒ¼ã‚«ãƒ«ã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã§ SAN(サブジェクトã®åˆ¥å)ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。設定ãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦æŽ¥ç¶šãŒå¦¨å®³ã•ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="3963721102035795474">リーダーモード</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{ãªã—}=1{1 件ã®ã‚µã‚¤ãƒˆã‹ã‚‰}other{# 件ã®ã‚µã‚¤ãƒˆã‹ã‚‰}}</translation>
<translation id="397105322502079400">計算ã—ã¦ã„ã¾ã™...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> ã¯ãƒ–ロックã•ã‚Œã¦ã„ã¾ã™</translation>
+<translation id="3987940399970879459">1 MB 未満</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 件ã®è¿‘ãã®ã‚¦ã‚§ãƒ–ページ}other{# 件ã®è¿‘ãã®ã‚¦ã‚§ãƒ–ページ}}</translation>
<translation id="4021036232240155012">DNS ã¯ã‚¦ã‚§ãƒ–サイトã®åå‰ã‚’インターãƒãƒƒãƒˆ アドレスã«å¤‰æ›ã™ã‚‹ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ サービスã§ã™ã€‚</translation>
<translation id="4030383055268325496">追加ã®å–り消ã—(&amp;U)</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">プロキシã¯å›ºå®šãƒ—ロキシ サーãƒãƒ¼ã§ã¯ãªã .pac スクリプト URL を使用ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="4098354747657067197">å½ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¦ã„ã¾ã™</translation>
<translation id="4103249731201008433">デãƒã‚¤ã‚¹ã®ã‚·ãƒªã‚¢ãƒ«ç•ªå·ãŒç„¡åŠ¹ã§ã™</translation>
+<translation id="410351446219883937">自動å†ç”Ÿ</translation>
<translation id="4103763322291513355">&lt;strong&gt;chrome://policy&lt;/strong&gt; ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€ãƒ–ラックリストã«ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹ URL ã¨ã‚·ã‚¹ãƒ†ãƒ ç®¡ç†è€…ãŒè¨­å®šã—ãŸä»–ã®ãƒãƒªã‚·ãƒ¼ã‚’確èªã§ãã¾ã™ã€‚</translation>
-<translation id="4110615724604346410">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã«ã¯ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">マゼンタ</translation>
+<translation id="4116663294526079822">ã“ã®ã‚µã‚¤ãƒˆã§ã¯å¸¸ã«è¨±å¯</translation>
<translation id="4117700440116928470">ãƒãƒªã‚·ãƒ¼ã®é©ç”¨ç¯„囲ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。</translation>
-<translation id="4118212371799607889">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ Chromium ã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{他 1 件}other{他 # 件}}</translation>
<translation id="4130226655945681476">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ ケーブルã€ãƒ¢ãƒ‡ãƒ ã€ãƒ«ãƒ¼ã‚¿ãƒ¼ã‚’確èªã™ã‚‹</translation>
+<translation id="413544239732274901">詳細</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">全体ã®æ—¢å®šå€¤ã‚’使用(検出)</translation>
+<translation id="4165986682804962316">サイトã®è¨­å®š</translation>
<translation id="4169947484918424451">Chromium ã«ã“ã®ã‚«ãƒ¼ãƒ‰ã‚’ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ</translation>
<translation id="4171400957073367226">確èªç”¨ã®ç½²åã«å•é¡ŒãŒã‚ã‚Šã¾ã™</translation>
<translation id="4196861286325780578">移動ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ファイアウォールã¨ã‚¦ã‚¤ãƒ«ã‚¹å¯¾ç­–ã®è¨­å®šã‚’確èªã™ã‚‹<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ãªã—}=1{1 個ã®ã‚¢ãƒ—リ($1)}=2{2 個ã®ã‚¢ãƒ—リ($1ã€$2)}other{# 個ã®ã‚¢ãƒ—リ($1ã€$2ã€$3)}}</translation>
<translation id="4220128509585149162">クラッシュ</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€ä»Šå¾Œã®é–²è¦§ã«æ‚ªå½±éŸ¿ã‚’åŠã¼ã™ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ï¼ˆãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã‚’変更ã—ãŸã‚Šã€ã‚¢ã‚¯ã‚»ã‚¹å…ˆã®ã‚µã‚¤ãƒˆã§è¿½åŠ ã®åºƒå‘Šã‚’表示ã—ãŸã‚Šã™ã‚‹ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ï¼‰ã‚’インストールã™ã‚‹ã‚ˆã†èª˜å°Žã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨ºæ–­ãƒ„ールを実行ã—ã¦ã¿ã¦ãã ã•ã„<ph name="END_LINK" />。</translation>
+<translation id="4235360514405112390">有効</translation>
<translation id="4250431568374086873">ã“ã®ã‚µã‚¤ãƒˆã¸ã®æŽ¥ç¶šã¯å®Œå…¨ã«ã¯ä¿è­·ã•ã‚Œã¦ã„ã¾ã›ã‚“</translation>
<translation id="4250680216510889253">ã„ã„ãˆ</translation>
<translation id="425582637250725228">è¡Œã£ãŸå¤‰æ›´ãŒä¿å­˜ã•ã‚Œãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="4258748452823770588">ç½²åãŒä¸é©åˆ‡ã§ã™</translation>
+<translation id="4265872034478892965">管ç†è€…ã«ã‚ˆã£ã¦è¨±å¯</translation>
<translation id="4269787794583293679">(ユーザーåãªã—)</translation>
<translation id="4275830172053184480">デãƒã‚¤ã‚¹ã®å†èµ·å‹•</translation>
<translation id="4280429058323657511">ã€æœ‰åŠ¹æœŸé™: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Š<ph name="BEGIN_LINK" />有害ãªãƒ—ログラムãŒæ¤œå‡º<ph name="END_LINK" />ã•ã‚Œã¾ã—ãŸã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">ä¿è­·è€…ã‹ã‚‰ã®ãŠã™ã™ã‚</translation>
<translation id="4304224509867189079">ログイン</translation>
-<translation id="432290197980158659">サーãƒãƒ¼ã®æ示ã—ãŸè¨¼æ˜Žæ›¸ãŒã€çµ„ã¿è¾¼ã¾ã‚Œã¦ã„る想定ã®è¨¼æ˜Žæ›¸ã¨ä¸€è‡´ã—ã¾ã›ã‚“。ã“れらã®æƒ³å®šã®è¨¼æ˜Žæ›¸ã¯ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ä¿è­·ã®ãŸã‚ã€ç‰¹å®šã®å®‰å…¨æ€§ã®é«˜ã„ウェブサイトã«ã¤ã„ã¦ç”¨æ„ã•ã‚Œã¦ã„ã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">ブロック(デフォルト)</translation>
<translation id="4325863107915753736">記事ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ</translation>
<translation id="4326324639298822553">有効期é™ã®ã€Œæ—¥ã€ã‚’確èªã—ã¦ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„</translation>
<translation id="4331708818696583467">ä¿è­·ã•ã‚Œã¦ã„ãªã„通信</translation>
<translation id="4356973930735388585">ã“ã®ã‚µã‚¤ãƒˆã‚’利用ã™ã‚‹ã¨ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€å±é™ºãªãƒ—ログラム(写真ã€ãƒ‘スワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード番å·ãªã©ã®æƒ…報を盗ã¿å–ã‚‹ã‹å‰Šé™¤ã™ã‚‹ãƒ—ログラム)ãŒãŠä½¿ã„ã®ãƒ‘ソコンã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="4372948949327679948"><ph name="VALUE_TYPE" /> 値ãŒæƒ³å®šã•ã‚Œã¾ã™ã€‚</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã¯ç™ºè¡Œå…ƒã«ã‚ˆã‚Šå–り消ã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯ã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£èªè¨¼æƒ…å ±ãŒä¿¡é ¼ã§ããªã„ã“ã¨ã‚’示ã—ã¦ãŠã‚Šã€æ‚ªæ„ã®ã‚るユーザーã¨é€šä¿¡ã—よã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="4381091992796011497">ユーザーå:</translation>
<translation id="4394049700291259645">無効ã«ã™ã‚‹</translation>
<translation id="4406896451731180161">検索çµæžœ</translation>
+<translation id="4424024547088906515">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ Chrome ã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ã§ãƒ­ã‚°ã‚¤ãƒ³è¨¼æ˜Žæ›¸ãŒæ‰¿èªã•ã‚Œãªã‹ã£ãŸã‹ã€ãƒ­ã‚°ã‚¤ãƒ³è¨¼æ˜Žæ›¸ãŒæ示ã•ã‚Œã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="443673843213245140">プロキシã®ä½¿ç”¨ã¯ç„¡åŠ¹ã§ã™ãŒã€ãƒ—ロキシã®è¨­å®šãŒæ˜Žç¤ºçš„ã«æŒ‡å®šã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
-<translation id="4492190037599258964">「<ph name="SEARCH_STRING" />ã€ã®æ¤œç´¢çµæžœ</translation>
<translation id="4506176782989081258">検証エラー: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">システム管ç†è€…ã«å•ã„åˆã‚ã›ã‚‹</translation>
<translation id="450710068430902550">管ç†è€…ã¨ã®å…±æœ‰</translation>
<translation id="4515275063822566619">Chrome 㨠Google アカウント(<ph name="ACCOUNT_EMAIL" />)ã«ä¿å­˜ã•ã‚Œã¦ã„るクレジット カードã¨ä½æ‰€ã§ã™ã€‚[<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />] ã§ç®¡ç†ã§ãã¾ã™ã€‚</translation>
<translation id="4522570452068850558">詳細</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">拡張機能を無効ã«ã—ã¦ã¿ã¦ãã ã•ã„。</translation>
<translation id="457875822857220463">é…é€</translation>
<translation id="4587425331216688090">Chrome ã‹ã‚‰ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</translation>
-<translation id="4589078953350245614"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰ç„¡åŠ¹ãªè¨¼æ˜Žæ›¸ãŒæ示ã•ã‚Œã¾ã—ãŸã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459"><ph name="DOMAIN" /> ã¸ã®æŽ¥ç¶šã¯æ–°ã—ã„æš—å·ã‚¹ã‚¤ãƒ¼ãƒˆã«ã‚ˆã‚Šæš—å·åŒ–ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="4594403342090139922">削除ã®å–り消ã—(&amp;U)</translation>
<translation id="4619615317237390068">ä»–ã®ãƒ‡ãƒã‚¤ã‚¹ã‹ã‚‰ã®ã‚¿ãƒ–</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã«ã¯ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
+<translation id="4690462567478992370">無効ãªè¨¼æ˜Žæ›¸ã®ä½¿ç”¨ã‚’ã‚„ã‚ã‚‹</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">接続ãŒä¸­æ–­ã•ã‚Œã¾ã—ãŸ</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨ºæ–­ãƒ„ールを実行ã™ã‚‹<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</translation>
<translation id="4800132727771399293">有効期é™ã¨ CVC を確èªã—ã¦ã‹ã‚‰ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102"><ph name="SITE" /> ã‹ã‚‰ã€Google Chrome ã§å‡¦ç†ã§ããªã„æš—å·åŒ–ã•ã‚ŒãŸèªè¨¼æƒ…å ±ãŒè¿”ã•ã‚ŒãŸãŸã‚ã€ç¾åœ¨ã“ã®ã‚¦ã‚§ãƒ–サイトã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやä¸æ­£ãªæ“作ã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚å°‘ã—時間をãŠãã¨ã€ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="4813512666221746211">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラー</translation>
<translation id="4816492930507672669">ページサイズã«åˆã‚ã›ã‚‹</translation>
<translation id="483020001682031208">表示ã§ãるフィジカル ウェブã®ãƒšãƒ¼ã‚¸ã¯ã‚ã‚Šã¾ã›ã‚“</translation>
<translation id="4850886885716139402">表示</translation>
<translation id="4854362297993841467">ã“ã®é…é”方法ã¯ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。別ã®æ–¹æ³•ã‚’é¸æŠžã—ã¦ãã ã•ã„。</translation>
<translation id="4858792381671956233">ã“ã®ã‚µã‚¤ãƒˆã‚’é–‹ã„ã¦ã‚‚よã„ã‹ã®å•ã„åˆã‚ã›ã‚’ä¿è­·è€…ã«é€ä¿¡ã—ã¾ã—ãŸ</translation>
+<translation id="4863764087567530506">アクセス先ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã¯ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’ã ã¾ã—ã¦ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã‚’インストールã•ã›ã‚ˆã†ã¨ã—ãŸã‚Šã€å€‹äººæƒ…報をå±é™ºã«ã•ã‚‰ã—ãŸã‚Šã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LINK" />å±é™ºæ€§ã‚’ç†è§£ã—ãŸã†ãˆã§è¡¨ç¤ºã™ã‚‹<ph name="END_LINK" /></translation>
<translation id="4880827082731008257">履歴を検索</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />ã€<ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ä»– 1 件ã®ã‚¦ã‚§ãƒ–ページ}other{ä»– # 件ã®ã‚¦ã‚§ãƒ–ページ}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">ã“ã®ãƒšãƒ¼ã‚¸ã¯ã€ä¸æ˜Žãªè¨€èªžã‹ã‚‰<ph name="LANGUAGE_LANGUAGE" />ã«ç¿»è¨³ã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="4923459931733593730">ãŠæ”¯æ‰•ã„</translation>
<translation id="4926049483395192435">指定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="495170559598752135">æ“作</translation>
<translation id="4958444002117714549">リストを展開ã™ã‚‹</translation>
-<translation id="4962322354953122629">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ Chrome ã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">警告をå†åº¦æœ‰åŠ¹ã«ã™ã‚‹</translation>
<translation id="4989809363548539747">ã“ã®ãƒ—ラグインã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“</translation>
<translation id="5002932099480077015">有効ã«ã™ã‚‹ã¨ã€Chrome ã§ã¯ã“ã®ç«¯æœ«ã«ã‚«ãƒ¼ãƒ‰ã®ã‚³ãƒ”ーãŒä¿å­˜ã•ã‚Œã¾ã™ã€‚ã“ã‚Œã«ã‚ˆã‚Šã€ãƒ•ã‚©ãƒ¼ãƒ ã«ã™ã°ã‚„ã入力ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚</translation>
<translation id="5018422839182700155">ã“ã®ãƒšãƒ¼ã‚¸ã‚’é–‹ã‘ã¾ã›ã‚“</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">管ç†è€…ã®ãƒãƒªã‚·ãƒ¼ã‚’確èªã—ã¦ãã ã•ã„</translation>
<translation id="5029568752722684782">コピーを消去</translation>
<translation id="5031870354684148875">Google 翻訳ã«ã¤ã„ã¦</translation>
+<translation id="5039804452771397117">許å¯</translation>
<translation id="5040262127954254034">プライãƒã‚·ãƒ¼</translation>
<translation id="5045550434625856497">パスワードãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“</translation>
<translation id="5056549851600133418">ãŠã™ã™ã‚ã®è¨˜äº‹</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />プロキシ アドレスを確èªã™ã‚‹<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Cookie ã¯ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã›ã‚“。}=1{1 件ã®ã‚µã‚¤ãƒˆã§ Cookie ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚}other{# 件ã®ã‚µã‚¤ãƒˆã§ Cookie ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚}}</translation>
<translation id="5087286274860437796">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ãŒç¾åœ¨æœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。</translation>
<translation id="5087580092889165836">カードを追加</translation>
<translation id="5089810972385038852">都é“府県 / å·ž</translation>
+<translation id="5094747076828555589">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ Chromium ã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
<translation id="5095208057601539847">地方</translation>
<translation id="5115563688576182185">(64 ビット)</translation>
<translation id="5141240743006678641">Google ã®èªè¨¼æƒ…å ±ã§åŒæœŸãƒ‘スワードを暗å·åŒ–ã™ã‚‹</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">メールアドレスã¯å¿…é ˆã§ã™</translation>
<translation id="5251803541071282808">クラウド</translation>
<translation id="5277279256032773186">会社㧠Chrome を使用ã™ã‚‹å ´åˆã¯ã€å¾“業員用㫠Chrome ã®è¨­å®šã‚’管ç†ã§ãã¾ã™ã€‚詳細</translation>
+<translation id="5297526204711817721">ã“ã®ã‚µã‚¤ãƒˆã¸ã®æŽ¥ç¶šã§ã¯ãƒ—ライãƒã‚·ãƒ¼ãŒä¿è­·ã•ã‚Œã¾ã›ã‚“。VR モードを終了ã™ã‚‹ã«ã¯ã€ãƒ˜ãƒƒãƒ‰ã‚»ãƒƒãƒˆã‚’外ã—ã¦ã€Œæˆ»ã‚‹ã€ã‚’押ã—ã¾ã™ã€‚</translation>
<translation id="5299298092464848405">ãƒãƒªã‚·ãƒ¼ã®è§£æžä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ</translation>
-<translation id="5300589172476337783">表示</translation>
<translation id="5308689395849655368">障害レãƒãƒ¼ãƒˆãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚</translation>
<translation id="5317780077021120954">ä¿å­˜</translation>
<translation id="5327248766486351172">åå‰</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚„個人情報(パスワードã€é›»è©±ç•ªå·ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードãªã©ï¼‰ã®å…¥åŠ›ã¨ã„ã£ãŸå±é™ºãªæ“作を行ã†ã‚ˆã†èª˜å°Žã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
-<translation id="5359637492792381994">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ç¾åœ¨æœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。設定ãŒä¸é©åˆ‡ã‹ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦æŽ¥ç¶šãŒå¦¨å®³ã•ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791"><ph name="SITE" /> ã¯è¨¼æ˜Žæ›¸ãŒå¤±åŠ¹ã—ã¦ã„ã‚‹ãŸã‚ã€ç¾åœ¨ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã¸ã®æ”»æ’ƒã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚ã—ã°ã‚‰ãã™ã‚‹ã¨ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚</translation>
<translation id="536296301121032821">ãƒãƒªã‚·ãƒ¼è¨­å®šã‚’ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ</translation>
<translation id="5386426401304769735">ã“ã®ã‚µã‚¤ãƒˆã®è¨¼æ˜Žæ›¸ãƒã‚§ãƒ¼ãƒ³ã«ã¯ SHA-1 を使ã£ã¦ç½²åã•ã‚ŒãŸè¨¼æ˜Žæ›¸ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="5402410679244714488">有効期é™: <ph name="EXPIRATION_DATE_ABBR" />ã€æœ€çµ‚使用日: 1 年以上å‰</translation>
+<translation id="540969355065856584">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ç¾åœ¨æœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。設定ãŒä¸é©åˆ‡ã‹ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦æŽ¥ç¶šãŒå¦¨å®³ã•ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="5421136146218899937">閲覧履歴データã®æ¶ˆåŽ»...</translation>
<translation id="5430298929874300616">ブックマークを削除</translation>
<translation id="5431657950005405462">ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ</translation>
-<translation id="5435775191620395718">ã“ã®ç«¯æœ«ã®å±¥æ­´ã‚’表示ã—ã¦ã„ã¾ã™ã€‚<ph name="BEGIN_LINK" />詳細<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">「<ph name="ERROR_PATH" />ã€ã§ã‚¹ã‚­ãƒ¼ãƒžç¢ºèªã‚¨ãƒ©ãƒ¼: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">ã“ã® <ph name="HOST_NAME" /> ページãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“</translation>
<translation id="5455374756549232013">ãƒãƒªã‚·ãƒ¼ã®ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ãŒä¸é©åˆ‡ã§ã™</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> / <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">無効</translation>
<translation id="5470861586879999274">編集ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
<translation id="54817484435770891">有効ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’追加</translation>
<translation id="5492298309214877701">ã“ã®ã‚µã‚¤ãƒˆã¯ä¼æ¥­ã€å›£ä½“ã€ã¾ãŸã¯å­¦æ ¡ã®ã‚¤ãƒ³ãƒˆãƒ©ãƒãƒƒãƒˆä¸Šã«ã‚ã‚Šã¾ã™ãŒã€å¤–部ã®ã‚¦ã‚§ãƒ–サイトã¨åŒã˜ URL ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">ã“ã®ä½æ‰€ã§ã®å—ã‘å–ã‚Šã¯ã§ãã¾ã›ã‚“。別ã®ä½æ‰€ã‚’é¸æŠžã—ã¦ãã ã•ã„。</translation>
<translation id="5572851009514199876">ã“ã®ã‚µã‚¤ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’ Chrome ã§ç¢ºèªã§ãるよã†ã«ã€Chrome ã‚’èµ·å‹•ã—ã¦ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ãã ã•ã„。</translation>
<translation id="5580958916614886209">有効期é™ã®ã€Œæœˆã€ã‚’確èªã—ã¦ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„</translation>
+<translation id="5586446728396275693">ä¿å­˜ã•ã‚Œã¦ã„ã‚‹ä½æ‰€ãŒã‚ã‚Šã¾ã›ã‚“</translation>
+<translation id="5595485650161345191">ä½æ‰€ã®ç·¨é›†</translation>
<translation id="560412284261940334">管ç†ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“</translation>
<translation id="5610142619324316209">接続を確èªã™ã‚‹</translation>
<translation id="5610807607761827392">カードã¨ä½æ‰€ã¯ [<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />] ã§ç®¡ç†ã§ãã¾ã™ã€‚</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">ã“ã®ã‚µã‚¤ãƒˆã‚’離れã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</translation>
<translation id="5629630648637658800">ãƒãƒªã‚·ãƒ¼è¨­å®šã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ</translation>
<translation id="5631439013527180824">無効ãªãƒ‡ãƒã‚¤ã‚¹ç®¡ç†ãƒˆãƒ¼ã‚¯ãƒ³ã§ã™</translation>
+<translation id="5633066919399395251"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ç¾åœ¨ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€ãŠä½¿ã„ã®ãƒ‘ソコン上ã«å±é™ºãªãƒ—ログラム(写真ã€ãƒ‘スワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードãªã©ã®æƒ…報を盗んã ã‚Šå‰Šé™¤ã—ãŸã‚Šã™ã‚‹ãƒ—ログラム)ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">ç¾åœ¨åœ°</translation>
+<translation id="5659593005791499971">メール</translation>
<translation id="5669703222995421982">自分å‘ã‘ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„を表示</translation>
<translation id="5675650730144413517">ã“ã®ãƒšãƒ¼ã‚¸ã¯å‹•ä½œã—ã¦ã„ã¾ã›ã‚“</translation>
-<translation id="5677928146339483299">ブロック</translation>
-<translation id="5694783966845939798"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ãŒè„†å¼±ãªç½²åアルゴリズム(SHA-1 ãªã©ï¼‰ã‚’使用ã—ã¦ç½²åã•ã‚Œã¦ã„ã¾ã™ã€‚サーãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£èªè¨¼æƒ…å ±ã¯å½è£…ã•ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã€ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ãŸã‚µãƒ¼ãƒãƒ¼ã¨ã¯ç•°ãªã‚‹ã‚µãƒ¼ãƒãƒ¼ã§ã‚ã‚‹ãŠãã‚ŒãŒã‚ã‚Šã¾ã™ï¼ˆæ‚ªæ„ã®ã‚るユーザーã¨é€šä¿¡ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼‰ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">ã“ã®ã‚¦ã‚§ãƒ–サイト㮠ID ã¯ç¢ºèªã•ã‚Œã¦ã„ã¾ã›ã‚“。</translation>
+<translation id="5713016350996637505">ä¸æ­£ã®å¯èƒ½æ€§ãŒã‚るコンテンツãŒãƒ–ロックã•ã‚Œã¾ã—ãŸ</translation>
<translation id="5720705177508910913">ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼</translation>
<translation id="5732392974455271431">ブロックã®è§£é™¤ã¯ä¿è­·è€…ãŒè¡Œã†ã“ã¨ãŒã§ãã¾ã™</translation>
<translation id="5763042198335101085">有効ãªãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入力ã—ã¦ãã ã•ã„</translation>
<translation id="5765072501007116331">é…é”方法ã¨è¦ä»¶ã‚’確èªã™ã‚‹ã«ã¯ã€ä½æ‰€ã‚’é¸æŠžã—ã¦ãã ã•ã„</translation>
+<translation id="5778550464785688721">MIDI デãƒã‚¤ã‚¹ã®ãƒ•ãƒ« コントロール</translation>
<translation id="5784606427469807560">カードã®ç¢ºèªä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚インターãƒãƒƒãƒˆæŽ¥ç¶šã‚’確èªã—ã¦ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="5785756445106461925">加ãˆã¦ã€ã“ã®ãƒšãƒ¼ã‚¸ã«ã¯å®‰å…¨ã§ãªã„ä»–ã®ãƒªã‚½ãƒ¼ã‚¹ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®ãƒªã‚½ãƒ¼ã‚¹ã¯é€ä¿¡ä¸­ã«ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‹ã‚‰è¦‹ã‚‰ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã¾ãŸã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦æ”¹å¤‰ã•ã‚Œãƒšãƒ¼ã‚¸ã®è¦‹ãŸç›®ãŒå¤‰ã‚ã‚‹å¯èƒ½æ€§ã‚‚ã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="5786044859038896871">カード情報を入力ã—ã¾ã™ã‹ï¼Ÿ</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">追加ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
<translation id="5814352347845180253"><ph name="SITE" /> ã¨ä»–ã®ä¸€éƒ¨ã®ã‚µã‚¤ãƒˆã®ãƒ—レミアム コンテンツã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªããªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="5838278095973806738">ã“ã®ã‚µã‚¤ãƒˆã§ã¯æ©Ÿå¯†æƒ…報(パスワードã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードãªã©ï¼‰ã‚’入力ã—ãªã„ã§ãã ã•ã„。悪æ„ã®ã‚るユーザーã«æƒ…å ±ãŒç›—ã¾ã‚Œã‚‹æã‚ŒãŒã‚ã‚Šã¾ã™ã€‚</translation>
-<translation id="5843436854350372569"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã«ã¯è„†å¼±ãªæš—å·éµãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚悪æ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ç§˜å¯†éµãŒç ´ã‚‰ã‚ŒãŸå¯èƒ½æ€§ãŒã‚ã‚Šã€ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ãŸã‚µãƒ¼ãƒãƒ¼ã¨ã¯ç•°ãªã‚‹ã‚µãƒ¼ãƒãƒ¼ã§ã‚ã‚‹ãŠãã‚ŒãŒã‚ã‚Šã¾ã™ï¼ˆæ‚ªæ„ã®ã‚るユーザーã¨é€šä¿¡ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼‰ã€‚<ph name="BEGIN_LEARN_MORE_LINK" /><ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">ã“ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“</translation>
<translation id="5869522115854928033">ä¿å­˜ã—ãŸãƒ‘スワード</translation>
<translation id="5872918882028971132">ä¿è­·è€…ã‹ã‚‰ã®ãŠã™ã™ã‚</translation>
<translation id="5901630391730855834">黄</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" />(åŒæœŸæ¸ˆã¿ï¼‰</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 個ãŒä½¿ç”¨ä¸­}other{# 個ãŒä½¿ç”¨ä¸­}}</translation>
<translation id="5926846154125914413">一部ã®ã‚µã‚¤ãƒˆã®ãƒ—レミアム コンテンツã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªããªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="5959728338436674663">å±é™ºãªã‚¢ãƒ—リやサイトã®æ¤œå‡ºã«å½¹ç«‹ã¦ã‚‹ãŸã‚ã«ä¸€éƒ¨ã®<ph name="BEGIN_WHITEPAPER_LINK" />システム情報やページã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„<ph name="END_WHITEPAPER_LINK" />ã‚’ Google ã«è‡ªå‹•é€ä¿¡ã™ã‚‹ã€‚<ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">週</translation>
<translation id="5967867314010545767">履歴ã‹ã‚‰å‰Šé™¤</translation>
<translation id="5975083100439434680">縮å°ã™ã‚‹</translation>
<translation id="598637245381783098">ãŠæ”¯æ‰•ã„アプリを開ã‘ã¾ã›ã‚“</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{ページ 1}other{ページ #}}</translation>
<translation id="6017514345406065928">ç·‘</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦è©æ¬ºçš„ãªã‚¢ãƒ—リ(他ã®ã‚‚ã®ã«æˆã‚Šã™ã¾ã—ãŸã‚Šã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®è¿½è·¡ãªã©ã«ä½¿ç”¨å¯èƒ½ãªãƒ‡ãƒ¼ã‚¿ã‚’åŽé›†ã—ãŸã‚Šã™ã‚‹ã‚¢ãƒ—リ)ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />ã€<ph name="TYPE_3" />(åŒæœŸæ¸ˆã¿ï¼‰</translation>
<translation id="6027201098523975773">åå‰ã‚’入力ã—ã¦ãã ã•ã„</translation>
<translation id="6040143037577758943">é–‰ã˜ã‚‹</translation>
<translation id="6042308850641462728">ã‚‚ã£ã¨è¦‹ã‚‹</translation>
+<translation id="6047233362582046994">有害ãªã‚¢ãƒ—リãŒã¾ã å­˜åœ¨ã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ã«ã‚‚ã‹ã‹ã‚らãš<ph name="BEGIN_LINK" />ã“ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹<ph name="END_LINK" />å ´åˆã¯ã€ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ä¸Šã®å±é™ºæ€§ã‚’ã‚らã‹ã˜ã‚ã”èªè­˜ãã ã•ã„。</translation>
+<translation id="6051221802930200923"><ph name="SITE" /> ã§ã¯è¨¼æ˜Žæ›¸ãƒ”ンニングãŒä½¿ç”¨ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ç¾åœ¨ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã¸ã®æ”»æ’ƒã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚ã—ã°ã‚‰ãã™ã‚‹ã¨ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚</translation>
<translation id="6060685159320643512">ã“れらã®è©¦é¨“é‹ç”¨ç‰ˆã¯å•é¡ŒãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ãŸã‚ã€ã”利用ã®éš›ã«ã¯å分ã”注æ„ãã ã•ã„</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ãªã—}=1{1 件}other{# 件}}</translation>
+<translation id="6080696365213338172">管ç†è€…ãŒæä¾›ã™ã‚‹è¨¼æ˜Žæ›¸ã‚’使用ã—ã¦ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã„ã¾ã™ã€‚<ph name="DOMAIN" /> ã«æä¾›ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ã¯ç®¡ç†è€…ã«ã‚ˆã£ã¦å‚å—ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{ãªã—}=1{1 個ã®ãƒ‘スワード(åŒæœŸæ¸ˆã¿ï¼‰}other{# 個ã®ãƒ‘スワード(åŒæœŸæ¸ˆã¿ï¼‰}}</translation>
<translation id="6146055958333702838">ケーブルを確èªã—ã€ä½¿ç”¨ã—ã¦ã„ã‚‹ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ デãƒã‚¤ã‚¹ï¼ˆãƒ«ãƒ¼ã‚¿ãƒ¼ã€ãƒ¢ãƒ‡ãƒ ãªã©ï¼‰ã‚’
å†èµ·å‹•ã—ã¦ãã ã•ã„。</translation>
<translation id="614940544461990577">次をãŠè©¦ã—ãã ã•ã„:</translation>
<translation id="6151417162996330722">サーãƒãƒ¼è¨¼æ˜Žæ›¸ã®æœ‰åŠ¹æœŸé™ãŒé•·ã™ãŽã¾ã™ã€‚</translation>
<translation id="6157877588268064908">é…é€æ–¹æ³•ã¨è¦ä»¶ã‚’確èªã™ã‚‹ã«ã¯ã€ä½æ‰€ã‚’é¸æŠžã—ã¦ãã ã•ã„</translation>
+<translation id="6158003235852588289"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Šã€ãƒ•ã‚£ãƒƒã‚·ãƒ³ã‚°è¡Œç‚ºãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸã€‚フィッシング サイトã¯ã€ä»–ã®ã‚¦ã‚§ãƒ–サイトã«ãªã‚Šã™ã¾ã—ã¦ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’欺ã“ã†ã¨ã™ã‚‹ã‚µã‚¤ãƒˆã§ã™ã€‚</translation>
<translation id="6165508094623778733">詳ã—ã見る</translation>
+<translation id="6169916984152623906">ç¾åœ¨ã€ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆ モードã§é–²è¦§ã—ã¦ã„ã¾ã™ã€‚ã‚ãªãŸã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ティã¯ã€ã“ã®ç«¯æœ«ã‚’利用ã™ã‚‹ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã¯è¡¨ç¤ºã•ã‚Œã¾ã›ã‚“。ãŸã ã—ã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒ–ックマークã¯é€šå¸¸ã©ãŠã‚Šä¿å­˜ã•ã‚Œã¾ã™ã€‚</translation>
<translation id="6177128806592000436">ã“ã®ã‚µã‚¤ãƒˆã¸ã®æŽ¥ç¶šã¯ä¿è­·ã•ã‚Œã¦ã„ã¾ã›ã‚“</translation>
<translation id="6184817833369986695">(コホート: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">インターãƒãƒƒãƒˆæŽ¥ç¶šã‚’確èªã—ã¦ãã ã•ã„</translation>
<translation id="6218753634732582820">Chromium ã‹ã‚‰ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</translation>
+<translation id="6221345481584921695"><ph name="BEGIN_LINK" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Šã€<ph name="END_LINK" />ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ<ph name="SITE" />。通常ã¯å®‰å…¨ãªã‚¦ã‚§ãƒ–サイトã§ã‚ã£ã¦ã‚‚ã€ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã«æ„ŸæŸ“ã—ã¦ã„ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚今回ã®æ‚ªæ„ã®ã‚るコンテンツã¯ã€ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®æ—¢çŸ¥ã®é…布元ã§ã‚る「<ph name="SUBRESOURCE_HOST" />ã€ã‹ã‚‰ã‚‚ãŸã‚‰ã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="6251924700383757765">プライãƒã‚·ãƒ¼ ãƒãƒªã‚·ãƒ¼</translation>
<translation id="6254436959401408446">メモリãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã€ã“ã®ãƒšãƒ¼ã‚¸ã‚’é–‹ã‘ã¾ã›ã‚“</translation>
<translation id="625755898061068298">ã“ã®ã‚µã‚¤ãƒˆã«é–¢ã™ã‚‹ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è­¦å‘Šã‚’無効ã«ã™ã‚‹ã‚ˆã†ã«æŒ‡å®šã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">ブックマークを編集</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> ã®æœ‰åŠ¹æœŸé™ã¨ CVC を入力</translation>
<translation id="6414888972213066896">ã“ã®ã‚µã‚¤ãƒˆã‚’é–‹ã„ã¦ã‚‚よã„ã‹ã®å•ã„åˆã‚ã›ã‚’ä¿è­·è€…ã«é€ä¿¡ã—ã¾ã—ãŸ</translation>
-<translation id="6416403317709441254"><ph name="SITE" /> ã‹ã‚‰é€ä¿¡ã•ã‚ŒãŸæš—å·åŒ–済ã¿ã®èªè¨¼æƒ…報を Chromium ã§å‡¦ç†ã§ããªã„ãŸã‚ã€ç¾åœ¨ã“ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやä¸æ­£ãªæ“作ã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚å°‘ã—時間をãŠãã¨ã€ã¾ãŸãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">証明書ãŒå–り消ã•ã‚ŒãŸã‹ã©ã†ã‹ã‚’確èªã§ãã¾ã›ã‚“。</translation>
<translation id="6433490469411711332">連絡先情報ã®ç·¨é›†</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ã§æŽ¥ç¶šãŒæ‹’å¦ã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="6446608382365791566">ä»–ã®æƒ…報を追加</translation>
+<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">フォームå†é€ä¿¡ã®ç¢ºèª</translation>
<translation id="6456339708790392414">ãŠæ”¯æ‰•ã„</translation>
<translation id="6458467102616083041">ãƒãƒªã‚·ãƒ¼ã«ã‚ˆã£ã¦ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¤œç´¢ãŒç„¡åŠ¹ã«ã•ã‚Œã¦ã„ã‚‹ãŸã‚無視ã•ã‚Œã¾ã™ã€‚</translation>
-<translation id="6462969404041126431">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯å–り消ã•ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">デãƒã‚¤ã‚¹ ãƒãƒªã‚·ãƒ¼</translation>
<translation id="6477321094435799029">ã“ã®ãƒšãƒ¼ã‚¸ã§é€šå¸¸ã¨ç•°ãªã‚‹ã‚³ãƒ¼ãƒ‰ã‚’検出ã—ãŸãŸã‚ã€å€‹äººæƒ…報(例: パスワードã€é›»è©±ç•ªå·ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード番å·ï¼‰ã‚’ä¿è­·ã™ã‚‹ãŸã‚ã«ã€ãƒšãƒ¼ã‚¸ã‚’ブロックã—ã¾ã—ãŸã€‚</translation>
<translation id="6489534406876378309">クラッシュã®ã‚¢ãƒƒãƒ—ロードを開始</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">有効期é™: <ph name="EXPIRATION_DATE_ABBR" />ã€æœ€çµ‚使用日: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">管ç†è€…ãŒã¾ã ã‚µã‚¤ãƒˆã‚’é–‹ãã“ã¨ã‚’許å¯ã—ã¦ã„ã¾ã›ã‚“</translation>
<translation id="6569060085658103619">拡張機能ã®ãƒšãƒ¼ã‚¸ã‚’表示ã—ã¦ã„ã¾ã™</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> 未満</translation>
+<translation id="657639383826808334">アクセス先ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«ã‚ˆã£ã¦ã€å€‹äººæƒ…報を入手ã—ãŸã‚Šå‰Šé™¤ã—ãŸã‚Šã™ã‚‹å±é™ºãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LINK" />å±é™ºæ€§ã‚’ç†è§£ã—ãŸã†ãˆã§è¡¨ç¤ºã™ã‚‹<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">æš—å·åŒ–オプション</translation>
<translation id="662080504995468778">ã¨ã©ã¾ã‚‹</translation>
<translation id="6626291197371920147">有効ãªã‚«ãƒ¼ãƒ‰ç•ªå·ã‚’追加</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> 検索</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ç¾åœ¨ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€ãŠä½¿ã„ã® Mac 上ã«å±é™ºãªãƒ—ログラム(写真ã€ãƒ‘スワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードãªã©ã®æƒ…報を盗んã ã‚Šå‰Šé™¤ã—ãŸã‚Šã™ã‚‹ãƒ—ログラム)ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">ã“ã®ãƒãƒªã‚·ãƒ¼ã¯å»ƒæ­¢ã•ã‚Œã¾ã—ãŸã€‚</translation>
-<translation id="6652240803263749613">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ã€ã”使用ã®ãƒ‘ソコンã®ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚° システムã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Chromium ã‹ã‚‰å€™è£œã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</translation>
<translation id="6685834062052613830">ログアウトã—ã¦è¨­å®šã‚’完了ã—ã¦ãã ã•ã„</translation>
<translation id="6710213216561001401">å‰ã¸</translation>
<translation id="6710594484020273272">&lt;検索キーワードを入力&gt;</translation>
<translation id="6711464428925977395">プロキシ サーãƒãƒ¼ã«å•é¡ŒãŒã‚ã‚‹ã€ã¾ãŸã¯ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“。</translation>
<translation id="6727102863431372879">設定</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ãªã—}=1{1 件ã®ã‚¢ã‚¤ãƒ†ãƒ }other{# 件ã®ã‚¢ã‚¤ãƒ†ãƒ }}</translation>
<translation id="674375294223700098">ä¸æ˜Žãªã‚µãƒ¼ãƒãƒ¼è¨¼æ˜Žæ›¸ã‚¨ãƒ©ãƒ¼</translation>
<translation id="6753269504797312559">ãƒãƒªã‚·ãƒ¼ã®å€¤</translation>
<translation id="6757797048963528358">デãƒã‚¤ã‚¹ãŒã‚¹ãƒªãƒ¼ãƒ—状態ã§ã™ã€‚</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">カスタム ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">地域データを読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ</translation>
+<translation id="6825578344716086703"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€è„†å¼±ãªç½²åアルゴリズム(SHA-1 ãªã©ï¼‰ã‚’使用ã—ã¦ç½²åã•ã‚ŒãŸè¨¼æ˜Žæ›¸ãŒã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰æ示ã•ã‚Œã¾ã—ãŸã€‚ã“ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£èªè¨¼æƒ…å ±ã¯å½è£…ã•ã‚ŒãŸã‚‚ã®ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã€ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ãŸã‚µãƒ¼ãƒãƒ¼ã¨ã¯åˆ¥ã®ã‚µãƒ¼ãƒãƒ¼ãŒå¿œç­”ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼ˆæ‚ªæ„ã®ã‚るユーザーã¨é€šä¿¡ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼‰ã€‚</translation>
+<translation id="6830728435402077660">ä¿è­·ã•ã‚Œã¦ã„ã¾ã›ã‚“</translation>
<translation id="6831043979455480757">翻訳</translation>
<translation id="6839929833149231406">地域</translation>
<translation id="6874604403660855544">追加ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">カードを確èªã—ã¾ã—ãŸ</translation>
<translation id="6897140037006041989">ユーザー エージェント</translation>
<translation id="6915804003454593391">ユーザー:</translation>
+<translation id="6945221475159498467">é¸æŠž</translation>
<translation id="6948701128805548767">å—ã‘å–り方法ã¨è¦ä»¶ã‚’確èªã™ã‚‹ã«ã¯ã€ä½æ‰€ã‚’é¸æŠžã—ã¦ãã ã•ã„</translation>
<translation id="6957887021205513506">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ãŒå½é€ ã•ã‚ŒãŸã‚‚ã®ã®ã‚ˆã†ã§ã™ã€‚</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">固定プロキシ サーãƒãƒ¼ã¨ .pac スクリプト URL ã®ä¸¡æ–¹ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="6989763994942163495">詳細設定を表示...</translation>
<translation id="7000990526846637657">履歴項目ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“</translation>
-<translation id="7009986207543992532"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã«æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã®æœ‰åŠ¹æœŸé™ãŒé•·ã™ãŽã¦ä¿¡é ¼æ€§ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">中国銀è¯</translation>
<translation id="7012372675181957985">Google アカウントã§ã®ä»–ã®å½¢å¼ã®é–²è¦§å±¥æ­´ãŒ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> ã«æ®‹ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™</translation>
<translation id="7029809446516969842">パスワード</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã«æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã®æœ‰åŠ¹æœŸé™ãŒé•·ã™ãŽã¦ä¿¡é ¼æ€§ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
+<translation id="7053983685419859001">ブロック</translation>
<translation id="7064851114919012435">連絡先情報</translation>
<translation id="7079718277001814089">ã“ã®ã‚µã‚¤ãƒˆã«ã¯ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ãŒå«ã¾ã‚Œã¦ã„ã¾ã™</translation>
<translation id="7087282848513945231">郡</translation>
-<translation id="7088615885725309056">å¤ã„</translation>
<translation id="7090678807593890770"><ph name="LINK" /> ã‚’ Google ã§æ¤œç´¢ã—ã¦ãã ã•ã„</translation>
+<translation id="7108819624672055576">拡張機能ã«ã‚ˆã£ã¦è¨±å¯</translation>
<translation id="7119414471315195487">ä»–ã®ã‚¿ãƒ–やプログラムを閉ã˜ã‚‹</translation>
<translation id="7129409597930077180">ã“ã®ä½æ‰€ã«ã¯é…é€ã§ãã¾ã›ã‚“。別ã®ä½æ‰€ã‚’é¸æŠžã—ã¦ãã ã•ã„。</translation>
<translation id="7138472120740807366">é…é”方法</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">処ç†ã—ã¦ã„ã¾ã™</translation>
<translation id="724691107663265825">アクセス先ã®ã‚µã‚¤ãƒˆã§ä¸æ­£ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã‚’検出ã—ã¾ã—ãŸ</translation>
<translation id="724975217298816891">カードã®è©³ç´°ã‚’æ›´æ–°ã™ã‚‹ã«ã¯ <ph name="CREDIT_CARD" /> ã®æœ‰åŠ¹æœŸé™ã¨ CVC を入力ã—ã¾ã™ã€‚確èªã‚’è¡Œã†ã¨ã€ã‚«ãƒ¼ãƒ‰ã®è©³ç´°ãŒã“ã®ã‚µã‚¤ãƒˆã¨å…±æœ‰ã•ã‚Œã¾ã™ã€‚</translation>
-<translation id="725866823122871198">パソコンã®æ—¥æ™‚(<ph name="DATE_AND_TIME" />)ãŒæ­£ã—ããªã„ãŸã‚ã€<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ã¸ã®ãƒ—ライベート接続を確立ã§ãã¾ã›ã‚“。</translation>
+<translation id="7260504762447901703">アクセス権をå–り消ã—ã¾ã™</translation>
<translation id="7275334191706090484">管ç†å¯¾è±¡ã®ãƒ–ックマーク</translation>
<translation id="7298195798382681320">推奨</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> ã«ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ レãƒãƒ¼ãƒˆãŒä½œæˆã•ã‚Œã¾ã—ãŸï¼ˆãƒ¦ãƒ¼ã‚¶ãƒ¼ã‹ã‚‰ã‚¢ãƒƒãƒ—ロードãŒãƒªã‚¯ã‚¨ã‚¹ãƒˆã•ã‚Œã¾ã—ãŸãŒã€ã¾ã ã‚¢ãƒƒãƒ—ロードã•ã‚Œã¦ã„ã¾ã›ã‚“)</translation>
<translation id="7334320624316649418">é †åºå¤‰æ›´ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
<translation id="733923710415886693">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ã¯ã€è¨¼æ˜Žæ›¸ã®é€æ˜Žæ€§ãƒãƒªã‚·ãƒ¼ã‚’介ã—ã¦å…¬é–‹ã•ã‚Œã¦ã„ã¾ã›ã‚“。</translation>
-<translation id="7351800657706554155">証明書ãŒå–り消ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ç¾åœ¨ <ph name="SITE" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。通常ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ エラーやä¸æ­£ãªæ“作ã¯ä¸€æ™‚çš„ãªã‚‚ã®ã§ã™ã€‚å°‘ã—時間をãŠãã¨ã€ã¾ãŸãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">コマンドライン</translation>
<translation id="7372973238305370288">検索çµæžœ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ã„ã„ãˆ</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">カードã®ç¢ºèª</translation>
-<translation id="7394102162464064926">履歴ã‹ã‚‰ã“れらã®ãƒšãƒ¼ã‚¸ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ
-
-次回ã‹ã‚‰ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆ モード(<ph name="SHORTCUT_KEY" />)をãŠã™ã™ã‚ã—ã¾ã™ã€‚</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">プロフィール パス</translation>
<translation id="7424977062513257142">ã“ã®ã‚¦ã‚§ãƒ–ページã«åŸ‹ã‚è¾¼ã¾ã‚Œã¦ã„るページã®å†…容:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">ã“ã®ã‚µã‚¤ãƒˆã¯ãƒ–ロックã•ã‚Œã¦ã„ã¾ã™</translation>
<translation id="7445762425076701745">接続ã—ã¦ã‚‹ã‚µãƒ¼ãƒãƒ¼ã®èº«å…ƒã«ã¤ã„ã¦ã€å分ãªæ¤œè¨¼ãŒã§ãã¾ã›ã‚“。接続ã—ã¦ã„るサーãƒãƒ¼ã¯ã€ãã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯å†…ã§ã®ã¿æœ‰åŠ¹ãªåå‰ã‚’使用ã—ã¦ãŠã‚Šã€å¤–部èªè¨¼å±€ãŒãã®æ‰€æœ‰æ¨©ã‚’検証ã™ã‚‹æ–¹æ³•ã¯ã‚ã‚Šã¾ã›ã‚“。ã“ã†ã—ãŸåå‰ã§è¨¼æ˜Žæ›¸ã‚’発行ã™ã‚‹èªè¨¼å±€ã‚‚ã‚ã‚‹ã®ã§ã€æŽ¥ç¶šå…ˆãŒæ„図ã—ãŸã‚¦ã‚§ãƒ–サイトã‹ã€æ‚ªæ„ã®ã‚るユーザーã®ã‚µã‚¤ãƒˆã‹ã¯ç¢ºèªã§ãã¾ã›ã‚“。</translation>
<translation id="7451311239929941790">ã“ã®å•é¡Œã«ã¤ã„ã¦<ph name="BEGIN_LINK" />詳細を確èª<ph name="END_LINK" />ã™ã‚‹</translation>
+<translation id="7455133967321480974">グローãƒãƒ«ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ï¼ˆ[ブロック])を使用</translation>
<translation id="7460163899615895653">ä»–ã®ç«¯æœ«ã§æœ€è¿‘使ã£ãŸã‚¿ãƒ–ãŒã“ã“ã«è¡¨ç¤ºã•ã‚Œã¾ã™</translation>
<translation id="7469372306589899959">カードを確èªä¸­ã§ã™</translation>
<translation id="7481312909269577407">進む</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">è¿”ã•ã‚ŒãŸãƒãƒªã‚·ãƒ¼ã®ç«¯æœ« ID ãŒç©ºã§ã‚ã‚‹ã‹ã€ç¾åœ¨ã®ç«¯æœ« ID ã¨ä¸€è‡´ã—ã¾ã›ã‚“</translation>
<translation id="7514365320538308">ダウンロード</translation>
<translation id="7518003948725431193">次㮠URL ã®ã‚¦ã‚§ãƒ–ページã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ:<ph name="URL" /></translation>
+<translation id="7521387064766892559">Javascript</translation>
<translation id="7535087603100972091">値</translation>
<translation id="7537536606612762813">å¿…é ˆ</translation>
+<translation id="7542403920425041731">確èªã™ã‚‹ã¨ã€ã‚«ãƒ¼ãƒ‰ã®æƒ…å ±ãŒã“ã®ã‚µã‚¤ãƒˆã«å…±æœ‰ã•ã‚Œã¾ã™ã€‚</translation>
<translation id="7542995811387359312">ã“ã®ãƒ•ã‚©ãƒ¼ãƒ ã¯å®‰å…¨ãªæŽ¥ç¶šã‚’使用ã—ã¦ã„ãªã„ãŸã‚ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆã‚«ãƒ¼ãƒ‰ã®è‡ªå‹•å…¥åŠ›ãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚</translation>
<translation id="7543525346216957623">ä¿è­·è€…ã«é ¼ã‚“ã§ãã ã•ã„</translation>
<translation id="7549584377607005141">ã“ã®ã‚¦ã‚§ãƒ–ページを正ã—ã表示ã™ã‚‹ã«ã¯ã€å…ˆã»ã©å…¥åŠ›ã—ãŸãƒ‡ãƒ¼ã‚¿ãŒå¿…è¦ã§ã™ã€‚データã¯å†é€ä¿¡ã§ãã¾ã™ãŒã€ã“ã®ãƒšãƒ¼ã‚¸ã§å…ˆã»ã©è¡Œã£ãŸæ“作を繰り返ã™ã“ã¨ã«ãªã‚Šã¾ã™ã€‚</translation>
<translation id="7552846755917812628">次ã®ã“ã¨ã‚’ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="7554791636758816595">æ–°ã—ã„タブ</translation>
+<translation id="7567204685887185387">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ä¸æ­£ã«ç™ºè¡Œã•ã‚ŒãŸã‚‚ã®ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚原因ã¨ã—ã¦ã¯ã€ä¸é©åˆ‡ãªè¨­å®šã‚„ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã‚‹æŽ¥ç¶šå¦¨å®³ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> 件)}other{<ph name="CONTACT_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> 件)}}</translation>
<translation id="7568593326407688803">ã“ã‚Œã¯<ph name="ORIGINAL_LANGUAGE" />ã®ãƒšãƒ¼ã‚¸ã§ã™ã€‚翻訳ã—ã¾ã™ã‹ï¼Ÿ</translation>
<translation id="7569952961197462199">Chrome ã‹ã‚‰ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</translation>
<translation id="7569983096843329377">é»’</translation>
<translation id="7578104083680115302">ã©ã®ç«¯æœ«ã§ã‚‚ã€Google ã«ä¿å­˜ã—ãŸã‚«ãƒ¼ãƒ‰ã‚’使ã£ã¦ã‚µã‚¤ãƒˆã‚„アプリã®æ”¯æ‰•ã„ã‚’ã™ã°ã‚„ãè¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
<translation id="7588950540487816470">フィジカルウェブ</translation>
<translation id="7592362899630581445">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ãŒåå‰ã®åˆ¶ç´„ã«é•åã—ã¦ã„ã¾ã™ã€‚</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> 未満</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ã§ã¯ç¾åœ¨ã“ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’処ç†ã§ãã¾ã›ã‚“。</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" />を翻訳ã—ãªã„</translation>
<translation id="7610193165460212391">値(<ph name="VALUE" />)ãŒç¯„囲外ã§ã™ã€‚</translation>
<translation id="7613889955535752492">有効期é™: <ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">別㮠Google アカウント パスワードを使ã£ã¦æš—å·åŒ–ã—ãŸãƒ‡ãƒ¼ã‚¿ãŒæ—¢ã«ã‚ã‚Šã¾ã™ã€‚パスワードを以下ã«å…¥åŠ›ã—ã¦ãã ã•ã„。</translation>
-<translation id="7634554953375732414">ã“ã®ã‚µã‚¤ãƒˆã¸ã®æŽ¥ç¶šã¯ãƒ—ライベート接続ã§ã¯ã‚ã‚Šã¾ã›ã‚“。</translation>
<translation id="7637571805876720304">Chromium ã‹ã‚‰ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カードを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ</translation>
<translation id="765676359832457558">詳細設定を表示ã—ãªã„...</translation>
<translation id="7658239707568436148">キャンセル</translation>
+<translation id="7662298039739062396">拡張機能ã«ã‚ˆã£ã¦æŒ‡å®šã•ã‚Œã‚‹è¨­å®š</translation>
<translation id="7667346355482952095">è¿”ã•ã‚ŒãŸãƒãƒªã‚·ãƒ¼ã®ãƒˆãƒ¼ã‚¯ãƒ³ãŒç©ºã§ã‚ã‚‹ã‹ã€ç¾åœ¨ã®ãƒˆãƒ¼ã‚¯ãƒ³ã¨ä¸€è‡´ã—ã¾ã›ã‚“</translation>
<translation id="7668654391829183341">ä¸æ˜Žãªãƒ‡ãƒã‚¤ã‚¹</translation>
<translation id="7669271284792375604">ã“ã®ã‚µã‚¤ãƒˆã‚’利用ã™ã‚‹ã¨ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€é–²è¦§æ™‚ã®ã‚¨ã‚¯ã‚¹ãƒšãƒªã‚¨ãƒ³ã‚¹ã‚’æãªã†ãƒ—ログラム(ホームページを改ã–ã‚“ã™ã‚‹ã€ã‚¢ã‚¯ã‚»ã‚¹å…ˆã®ã‚µã‚¤ãƒˆã«è¿½åŠ ã®åºƒå‘Šã‚’表示ã™ã‚‹ãªã©ã®ãƒ—ログラム)をインストールã™ã‚‹ã‚ˆã†èª˜å°Žã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="7674629440242451245">Chrome ã®æ–°ã—ã„機能ã«é–¢å¿ƒã‚’ãŠæŒã¡ã§ã—ãŸã‚‰ã€chrome.com/dev ã‹ã‚‰ Dev ãƒãƒ£ãƒ³ãƒãƒ«ã‚’ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="7682287625158474539">発é€å…ˆ</translation>
+<translation id="7701040980221191251">ãªã—</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ï¼ˆå®‰å…¨ã§ã¯ã‚ã‚Šã¾ã›ã‚“)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">証明書</translation>
+<translation id="7716147886133743102">管ç†è€…ã«ã‚ˆã£ã¦ãƒ–ロック</translation>
<translation id="7716424297397655342">ã“ã®ã‚µã‚¤ãƒˆã‚’キャッシュã‹ã‚‰èª­ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">管ç†ã•ã‚Œã¦ã„ã¾ã›ã‚“</translation>
<translation id="7755287808199759310">ブロックã®è§£é™¤ã¯ä¿è­·è€…ãŒè¡Œã†ã“ã¨ãŒã§ãã¾ã™</translation>
<translation id="7758069387465995638">ファイアウォールã¾ãŸã¯ã‚¦ã‚¤ãƒ«ã‚¹å¯¾ç­–ソフトウェアã«ã‚ˆã£ã¦æŽ¥ç¶šãŒãƒ–ロックã•ã‚ŒãŸå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32 ビット)</translation>
<translation id="7956713633345437162">モãƒã‚¤ãƒ«ã®ãƒ–ックマーク</translation>
<translation id="7961015016161918242">使用ã—ãªã„</translation>
-<translation id="7962083544045318153">クラッシュ ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">常ã«<ph name="ORIGINAL_LANGUAGE" />ã‹ã‚‰<ph name="TARGET_LANGUAGE" />ã«ç¿»è¨³ã™ã‚‹</translation>
<translation id="7995512525968007366">指定ãªã—</translation>
<translation id="800218591365569300">メモリを解放ã™ã‚‹ãŸã‚ã«ã€ä»–ã®ã‚¿ãƒ–やプログラムを閉ã˜ã¦ã¿ã¦ãã ã•ã„。</translation>
<translation id="8012647001091218357">ç¾åœ¨ã€ä¿è­·è€…ã«ãŸãšã­ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。もã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。</translation>
<translation id="8025119109950072390">ã“ã®ã‚µã‚¤ãƒˆã‚’利用ã™ã‚‹ã¨ã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦ã€ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚„個人情報(例: パスワードã€é›»è©±ç•ªå·ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード番å·ï¼‰ã®å…¥åŠ›ãªã©ã®å±é™ºãªæ“作を行ã†ã‚ˆã†èª˜å°Žã•ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
-<translation id="803030522067524905"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Šã€ãƒ•ã‚£ãƒƒã‚·ãƒ³ã‚°è¡Œç‚ºãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸã€‚フィッシング サイトã¯ã€ä»–ã®ã‚¦ã‚§ãƒ–サイトã«ãªã‚Šã™ã¾ã—ã¦ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’欺ã“ã†ã¨ã™ã‚‹ã‚µã‚¤ãƒˆã§ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">ã“ã®ãƒšãƒ¼ã‚¸ã®è¨€èªžã¯<ph name="SOURCE_LANGUAGE" />ã§ã™ã€‚<ph name="TARGET_LANGUAGE" />ã«ç¿»è¨³ã—ã¾ã™ã‹ï¼Ÿ</translation>
+<translation id="8037357227543935929">確èªï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆï¼‰</translation>
<translation id="8041089156583427627">フィードãƒãƒƒã‚¯ã‚’é€ä¿¡</translation>
+<translation id="8041940743680923270">グローãƒãƒ«ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ï¼ˆ[確èª])を使用</translation>
<translation id="8088680233425245692">記事を表示ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="8089520772729574115">1 MB 未満</translation>
<translation id="8091372947890762290">サーãƒãƒ¼ã§æœ‰åŠ¹åŒ–ãŒä¿ç•™ã«ãªã£ã¦ã„ã¾ã™</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> ã®ã‚µãƒ¼ãƒãƒ¼ã® <ph name="BEGIN_ABBR" />DNS アドレス<ph name="END_ABBR" />ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="8149426793427495338">パソコンãŒã‚¹ãƒªãƒ¼ãƒ—状態ã§ã™ã€‚</translation>
<translation id="8150722005171944719"><ph name="URL" /> ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’読むã“ã¨ãŒã§ãã¾ã›ã‚“。削除ã•ã‚ŒãŸã‹ç§»å‹•ã•ã‚ŒãŸå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ファイルã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚»ã‚¹æ¨©ãŒãªã„å ´åˆã‚‚ã‚ã‚Šã¾ã™ã€‚</translation>
+<translation id="8184538546369750125">グローãƒãƒ«ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ï¼ˆ[許å¯])を使用</translation>
+<translation id="8191494405820426728">ローカルã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">移動ã®å–り消ã—(&amp;U)</translation>
<translation id="8201077131113104583">ID「<ph name="EXTENSION_ID" />ã€ã®æ‹¡å¼µæ©Ÿèƒ½ã«å¯¾ã™ã‚‹ç„¡åŠ¹ãªæ›´æ–° URL ã§ã™ã€‚</translation>
<translation id="8202097416529803614">ã”注文概è¦</translation>
<translation id="8218327578424803826">割り当ã¦ã‚‰ã‚ŒãŸå ´æ‰€:</translation>
<translation id="8225771182978767009">ã“ã®ã‚µã‚¤ãƒˆã¯ã€ã“ã®ãƒ‘ソコンを設定ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã‚ˆã£ã¦ãƒ–ロックã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />ã€<ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã§ã¯ç¾åœ¨ã€æ‚ªæ„ã®ã‚るユーザーãŒã€ãŠä½¿ã„ã®ãƒ‘ソコンã«å±é™ºãªãƒ—ログラム(写真ã€ãƒ‘スワードã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã€ã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード番å·ãªã©ã‚’ç›—ã¿å–ã‚‹ã‹å‰Šé™¤ã™ã‚‹ãƒ—ログラム)をインストールã—よã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</translation>
<translation id="8241707690549784388">検索ã—ã¦ã„るページã¯ã€å…¥åŠ›ã—ãŸæƒ…報を使用ã—ã¦ã„ã¾ã™ã€‚ã“ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã£ãŸå ´åˆã€æ“作ã®ã‚„ã‚Šç›´ã—ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚続行ã—ã¾ã™ã‹ï¼Ÿ</translation>
<translation id="8249320324621329438">å‰å›žã®å–å¾—:</translation>
<translation id="8253091569723639551">請求先ä½æ‰€ãŒå¿…è¦ã§ã™</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">確èªæ–¹æ³•ãŒã‚ã‹ã‚‰ãªã„å ´åˆã¯ã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ç®¡ç†è€…ã¾ã§ãŠå•ã„åˆã‚ã›ãã ã•ã„。</translation>
<translation id="8293206222192510085">ブックマークã®è¿½åŠ </translation>
<translation id="8294431847097064396">ソース</translation>
+<translation id="8306404619377842860">ãŠä½¿ã„ã®ç«¯æœ«ã®æ—¥æ™‚(<ph name="DATE_AND_TIME" />)ãŒæ­£ã—ããªã„ãŸã‚ã€<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ã¸ã®ãƒ—ライベート接続を確立ã§ãã¾ã›ã‚“。<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šã«å•é¡ŒãŒã‚ã£ãŸãŸã‚翻訳ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•ã‚Œã¾ã—ãŸ</translation>
<translation id="834457929814110454">有害ãªãƒ—ログラムãŒå‰Šé™¤ã•ã‚Œã‚‹ã‚ˆã‚Šå‰ã«<ph name="BEGIN_LINK" />ã“ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹<ph name="END_LINK" />å ´åˆã¯ã€ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ä¸Šã®ãƒªã‚¹ã‚¯ã«ã¤ã„ã¦ã”承知ãŠããã ã•ã„。</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">Google アカウントã«ä¿å­˜ã—ãŸã‚«ãƒ¼ãƒ‰ã‚’使用ã™ã‚‹ã«ã¯ Chrome ã«ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ãã ã•ã„</translation>
<translation id="8488350697529856933">é©ç”¨å…ˆ</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ã‹ã‚‰ã®å¿œç­”時間ãŒé•·ã™ãŽã¾ã™ã€‚</translation>
-<translation id="852346902619691059">ã“ã®ã‚µãƒ¼ãƒãƒ¼ãŒ <ph name="DOMAIN" /> ã§ã‚ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯ã€ã”使用ã®ãƒ‡ãƒã‚¤ã‚¹ã®ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚° システムã«ã‚ˆã£ã¦ä¿¡é ¼ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“。原因ã¨ã—ã¦ã€è¨­å®šãŒä¸é©åˆ‡ã§ã‚ã‚‹ã‹ã€æ‚ªæ„ã®ã‚るユーザーãŒæŽ¥ç¶šã‚’妨害ã—ã¦ã„ã‚‹ã“ã¨ãŒè€ƒãˆã‚‰ã‚Œã¾ã™ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />詳細<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">有効期é™ï¼ˆå¹´ï¼‰</translation>
<translation id="8543181531796978784"><ph name="BEGIN_ERROR_LINK" />検出ã®å•é¡Œã‚’ã”報告<ph name="END_ERROR_LINK" />ãã ã•ã„。<ph name="BEGIN_LINK" />安全ã§ãªã„ã“ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹<ph name="END_LINK" />ã™ã‚‹å ´åˆã¯ã€ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ä¸Šã®ãƒªã‚¹ã‚¯ãŒã‚ã‚‹ã“ã¨ã‚’ã”承知ãŠããã ã•ã„。</translation>
<translation id="8553075262323480129">ページã®è¨€èªžã‚’検出ã§ããªã„ãŸã‚翻訳ã§ãã¾ã›ã‚“。</translation>
-<translation id="8559762987265718583">デãƒã‚¤ã‚¹ã®æ—¥æ™‚(<ph name="DATE_AND_TIME" />)ãŒæ­£ã—ããªã„ãŸã‚ã€<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ã¸ã®ãƒ—ライベート接続を確立ã§ãã¾ã›ã‚“。</translation>
<translation id="8571890674111243710">ページを<ph name="LANGUAGE" />ã«ç¿»è¨³ã—ã¦ã„ã¾ã™...</translation>
<translation id="858637041960032120">電話番å·ã‚’追加
</translation>
@@ -821,6 +895,7 @@
<translation id="8738058698779197622">安全ãªæŽ¥ç¶šã‚’確立ã™ã‚‹ã«ã¯æ™‚計ãŒæ­£ã—ã設定ã•ã‚Œã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ã“ã®ç†ç”±ã¯ã€æœ¬ç‰©ã®ã‚¦ã‚§ãƒ–サイトã§ã‚ã‚‹ã“ã¨ã‚’示ã™ãŸã‚ã«ã‚¦ã‚§ãƒ–サイトã§ä½¿ç”¨ã•ã‚Œã‚‹è¨¼æ˜Žæ›¸ã«ã¯ã€æœ‰åŠ¹æœŸé–“(発効日時ã¨å¤±åŠ¹æ—¥æ™‚)ãŒè¨­å®šã•ã‚Œã¦ã„ã‚‹ãŸã‚ã§ã™ã€‚デãƒã‚¤ã‚¹ã®æ™‚計ãŒæ­£ã—ããªã„ãŸã‚ã€Chromium ã§ã¯ã“れらã®è¨¼æ˜Žæ›¸ã‚’確èªã§ãã¾ã›ã‚“。</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> ã® &lt;abbr id="dnsDefinition"&gt;DNS アドレス&lt;/abbr&gt;ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚å•é¡Œã‚’診断ã—ã¦ã„ã¾ã™ã€‚</translation>
<translation id="8759274551635299824">ã“ã®ã‚«ãƒ¼ãƒ‰ã¯æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚Œã¦ã„ã¾ã™</translation>
+<translation id="8761567432415473239"><ph name="SITE" /> ã§ã¯æœ€è¿‘ã€Google セーフ ブラウジングã«ã‚ˆã‚Š<ph name="BEGIN_LINK" />有害ãªãƒ—ログラムãŒæ¤œå‡º<ph name="END_LINK" />ã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="8790007591277257123">削除ã®ã‚„ã‚Šç›´ã—(&amp;R)</translation>
<translation id="8800988563907321413">周辺ã®ãŠã™ã™ã‚ã®å ´æ‰€ãŒã“ã“ã«è¡¨ç¤ºã•ã‚Œã¾ã™</translation>
<translation id="8820817407110198400">ブックマーク</translation>
@@ -833,29 +908,30 @@
<translation id="8870413625673593573">最近閉ã˜ãŸã‚¿ãƒ–</translation>
<translation id="8874824191258364635">有効ãªã‚¯ãƒ¬ã‚¸ãƒƒãƒˆ カード番å·ã‚’入力ã—ã¦ãã ã•ã„</translation>
<translation id="8876793034577346603">ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯è¨­å®šã‚’解æžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
-<translation id="8877192140621905067">確èªã‚’è¡Œã†ã¨ã€ã‚«ãƒ¼ãƒ‰ã®è©³ç´°ãŒã“ã®ã‚µã‚¤ãƒˆã¨å…±æœ‰ã•ã‚Œã¾ã™</translation>
<translation id="8889402386540077796">色調</translation>
<translation id="8891727572606052622">プロキシ モードãŒç„¡åŠ¹ã§ã™ã€‚</translation>
<translation id="889901481107108152">ã“ã®è©¦é¨“é‹ç”¨æ©Ÿèƒ½ã¯ã€ãŠä½¿ã„ã®ãƒ—ラットフォームã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。</translation>
<translation id="8903921497873541725">拡大ã™ã‚‹</translation>
<translation id="8931333241327730545">ã“ã®ã‚«ãƒ¼ãƒ‰ã‚’ Google アカウントã«ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ</translation>
<translation id="8932102934695377596">時計ãŒé…ã‚Œã¦ã„ã¾ã™</translation>
-<translation id="8954894007019320973">(続ã)</translation>
<translation id="8971063699422889582">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ã®æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="8986494364107987395">使用統計データã¨éšœå®³ãƒ¬ãƒãƒ¼ãƒˆã‚’ Google ã«è‡ªå‹•é€ä¿¡ã™ã‚‹</translation>
-<translation id="8987927404178983737">月</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ã“ã®å…ˆã®ã‚µã‚¤ãƒˆã«ã¯æœ‰å®³ãªãƒ—ログラムãŒã‚ã‚Šã¾ã™</translation>
+<translation id="8997023839087525404">サーãƒãƒ¼ã‹ã‚‰æ示ã•ã‚ŒãŸè¨¼æ˜Žæ›¸ã¯ã€è¨¼æ˜Žæ›¸ã®é€æ˜Žæ€§ãƒãƒªã‚·ãƒ¼ã‚’介ã—ã¦å…¬é–‹ã•ã‚Œã¦ã„ã¾ã›ã‚“。一部ã®è¨¼æ˜Žæ›¸ã¯ã€ä¿¡é ¼æ€§ã®ç¢ºä¿ã¨æ”»æ’ƒè€…ã‹ã‚‰ã®ä¿è­·ã®ãŸã‚ã€è¨¼æ˜Žæ›¸ã®é€æ˜Žæ€§ãƒãƒªã‚·ãƒ¼ã‚’介ã—ã¦å…¬é–‹ã•ã‚Œã‚‹ã“ã¨ãŒè¦ä»¶ã¨ãªã£ã¦ã„ã¾ã™ã€‚</translation>
<translation id="9001074447101275817">プロキシ <ph name="DOMAIN" /> ã«ã¯ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¨ãƒ‘スワードを指定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</translation>
+<translation id="9005998258318286617">PDF ドキュメントを読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
<translation id="901974403500617787">システム全体ã«é©ç”¨ã•ã‚Œã‚‹ãƒ•ãƒ©ã‚°ã¯æ‰€æœ‰è€…(<ph name="OWNER_EMAIL" />)ã®ã¿ãŒè¨­å®šã§ãã¾ã™ã€‚</translation>
+<translation id="9020200922353704812">カードã®è«‹æ±‚å…ˆä½æ‰€ã‚’入力ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™</translation>
<translation id="9020542370529661692">ã“ã®ãƒšãƒ¼ã‚¸ã¯<ph name="TARGET_LANGUAGE" />ã«ç¿»è¨³ã•ã‚Œã¦ã„ã¾ã™</translation>
<translation id="9035022520814077154">セキュリティ エラー</translation>
<translation id="9038649477754266430">予測サービスを使用ã—ã¦ãƒšãƒ¼ã‚¸ã‚’より迅速ã«èª­ã¿è¾¼ã‚€</translation>
<translation id="9039213469156557790">加ãˆã¦ã€ã“ã®ãƒšãƒ¼ã‚¸ã«ã¯å®‰å…¨ã§ãªã„ä»–ã®ãƒªã‚½ãƒ¼ã‚¹ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®ãƒªã‚½ãƒ¼ã‚¹ã¯é€ä¿¡ä¸­ã«ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‹ã‚‰è¦‹ã‚‰ã‚Œã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã¾ãŸã€æ‚ªæ„ã®ã‚るユーザーã«ã‚ˆã£ã¦æ”¹å¤‰ã•ã‚Œãƒšãƒ¼ã‚¸ã®å‹•ä½œãŒå¤‰ã‚ã‚‹å¯èƒ½æ€§ã‚‚ã‚ã‚Šã¾ã™ã€‚</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ã®æ”»æ’ƒè€…ãŒã€é–²è¦§ç’°å¢ƒã‚’æãªã†ãƒ—ログラムをインストールã•ã›ã‚ˆã†ã¨ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼ˆãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã‚’改ã–ã‚“ã™ã‚‹ã€ã‚¢ã‚¯ã‚»ã‚¹å…ˆã®ã‚µã‚¤ãƒˆã«è¿½åŠ ã®åºƒå‘Šã‚’表示ã™ã‚‹ãªã©ï¼‰ã€‚</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" /> ã«ã‚¢ã‚¯ã‚»ã‚¹ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰ç„¡åŠ¹ãªè¨¼æ˜Žæ›¸ãŒæ示ã•ã‚Œã¾ã—ãŸã€‚</translation>
<translation id="9050666287014529139">パスフレーズ</translation>
<translation id="9065203028668620118">編集</translation>
<translation id="9068849894565669697">色ã®é¸æŠž</translation>
+<translation id="9069693763241529744">拡張機能ã«ã‚ˆã£ã¦ãƒ–ロック</translation>
<translation id="9076283476770535406">æˆäººå‘ã‘コンテンツãŒå«ã¾ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™</translation>
<translation id="9078964945751709336">ãã®ä»–ã®æƒ…å ±ãŒå¿…è¦ã§ã™</translation>
<translation id="9103872766612412690"><ph name="SITE" /> ã§ã¯é€šå¸¸ã€æš—å·åŒ–ã—ã¦æƒ…報をä¿è­·ã—ã¦ã„ã¾ã™ã€‚今回ã€Chromium ã‹ã‚‰ <ph name="SITE" /> ã¸ã®æŽ¥ç¶šè©¦è¡Œæ™‚ã«ã€ã“ã®ã‚¦ã‚§ãƒ–サイトã‹ã‚‰ã„ã¤ã‚‚ã¨ã¯ç•°ãªã‚‹èª¤ã£ãŸèªè¨¼æƒ…å ±ãŒè¿”ã•ã‚Œã¾ã—ãŸã€‚悪æ„ã®ã‚るユーザー㌠<ph name="SITE" /> ã«ãªã‚Šã™ã¾ãã†ã¨ã—ã¦ã„ã‚‹ã‹ã€Wi-Fi ログイン画é¢ã§æŽ¥ç¶šãŒä¸­æ–­ã•ã‚ŒãŸå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚データã®ã‚„ã‚Šå–ã‚ŠãŒè¡Œã‚れるå‰ã« Chromium ã«ã‚ˆã£ã¦æŽ¥ç¶šãŒåœæ­¢ã•ã‚ŒãŸãŸã‚ã€æƒ…å ±ã¯å¼•ã続ãä¿è­·ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
@@ -864,16 +940,21 @@
<translation id="9148507642005240123">編集ã®å–り消ã—(&amp;U)</translation>
<translation id="9154194610265714752">更新完了</translation>
<translation id="9157595877708044936">セットアップ中...</translation>
+<translation id="9169664750068251925">ã“ã®ã‚µã‚¤ãƒˆã§ã¯å¸¸ã«ãƒ–ロック</translation>
<translation id="9170848237812810038">å–消(&amp;U)</translation>
<translation id="917450738466192189">サーãƒãƒ¼ã®è¨¼æ˜Žæ›¸ãŒç„¡åŠ¹ã§ã™ã€‚</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> 件)}other{<ph name="SHIPPING_OPTION_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> 件)}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> ã§ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„プロトコルãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚</translation>
<translation id="9205078245616868884">データã¯åŒæœŸãƒ‘スフレーズã§æš—å·åŒ–ã•ã‚Œã¾ã™ã€‚åŒæœŸã‚’開始ã™ã‚‹ã«ã¯ã€åŒæœŸãƒ‘スフレーズを入力ã—ã¦ãã ã•ã„。</translation>
<translation id="9207861905230894330">記事を追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
+<translation id="9219103736887031265">ç”»åƒ</translation>
<translation id="933612690413056017">インターãƒãƒƒãƒˆæŽ¥ç¶šãŒã‚ã‚Šã¾ã›ã‚“</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">フォームをクリア</translation>
<translation id="939736085109172342">æ–°ã—ã„フォルダ</translation>
<translation id="941721044073577244">ã“ã®ã‚µã‚¤ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒè¨±å¯ã•ã‚Œã¦ã„ãªã„よã†ã§ã™</translation>
<translation id="969892804517981540">Official Build</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{ãªã—}=1{1 件ã®ã‚¢ã‚¤ãƒ†ãƒ }other{# 件ã®ã‚¢ã‚¤ãƒ†ãƒ }}</translation>
<translation id="988159990683914416">Developer Build</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_kn.xtb b/chromium/components/strings/components_strings_kn.xtb
index c7f54c81361..e6156d7a658 100644
--- a/chromium/components/strings/components_strings_kn.xtb
+++ b/chromium/components/strings/components_strings_kn.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">ಪà³à²°à²¦à²•à³à²·à²¿à²£à²¾à²•à²¾à²°à²¦à²²à³à²²à²¿ ತಿರà³à²—ಿಸà³</translation>
<translation id="1038842779957582377">ಆಜà³à²žà²¾à²¤ ಹೆಸರà³</translation>
<translation id="1050038467049342496">ಇತರ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€à²—ಳನà³à²¨à³ ಮà³à²šà³à²šà²¿</translation>
-<translation id="1053591932240354961">Google Chrome ಪà³à²°à²•à³à²°à²¿à²¯à³†à²—ೊಳಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²à²¦ ಅವà³à²¯à²µà²¸à³à²¥à²¿à²¤ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³ ಕಳà³à²¹à²¿à²¸à²¿à²¦ ಕಾರಣ ಇದೀಗ ನೀವೠ<ph name="SITE" /> ಭೇಟಿ ಮಾಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ದಾಳಿಗಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ನಂತರ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;ಸೇರಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸಿ</translation>
<translation id="10614374240317010">ಉಳಿಸಿಯೇ ಇಲà³à²²</translation>
<translation id="106701514854093668">ಡೆಸà³à²•à³â€Œà²Ÿà²¾à²ªà³ ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳà³</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">ನೀತಿಯ ಸಂಗà³à²°à²¹ ಸರಿಯಾಗಿದೆ</translation>
<translation id="113188000913989374"><ph name="SITE" /> ಹೀಗೆ ಹೇಳà³à²¤à³à²¤à²¦à³†:</translation>
<translation id="1132774398110320017">Chrome ಸà³à²µà²¯à²‚ತà³à²‚ಬà³à²µà²¿à²•à³† ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳà³...</translation>
+<translation id="1150979032973867961">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ನಿಮà³à²® ಸಾಧನದ ಆಪರೇಟಿಂಗೠಸಿಸà³à²Ÿà²‚‌ ಪà³à²°à²•à²¾à²° ವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²—ಿಲà³à²². ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
+<translation id="1151972924205500581">ಪಾಸà³â€Œà²µà²°à³à²¡à³ ಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
<translation id="1152921474424827756"><ph name="URL" /> ನ <ph name="BEGIN_LINK" />ಸಂಗà³à²°à²¹à²¿à²¸à²²à²¾à²—ಿರà³à²µ ನಕಲನà³à²¨à³<ph name="END_LINK" /> ಪà³à²°à²µà³‡à²¶à²¿à²¸à²¿</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ಅನಿರೀಕà³à²·à²¿à²¤à²µà²¾à²—ಿ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಮà³à²šà³à²šà²¿à²¦à³†.</translation>
<translation id="1161325031994447685">ವೈ-ಫೈಗೆ ಮರà³à²¸à²‚ಪರà³à²•à²¿à²¸à²²à²¾à²—à³à²¤à³à²¤à²¿à²¦à³†</translation>
+<translation id="1165039591588034296">ದೋಷ</translation>
<translation id="1175364870820465910">&amp;ಮà³à²¦à³à²°à²¿à²¸à²¿...</translation>
<translation id="1181037720776840403">ತೆಗೆದà³à²¹à²¾à²•à³</translation>
<translation id="1184214524891303587">ಸಂಭಾವà³à²¯ ಸà³à²°à²•à³à²·à²¤à³† ಸಂಬಂಧಿಸಿದ ಘಟನೆಗಳ ವಿವರಗಳನà³à²¨à³ Google ಗೆ <ph name="BEGIN_WHITEPAPER_LINK" />ಸà³à²µà²¯à²‚ಚಾಲಿತವಾಗಿ ವರದಿಮಾಡಿ<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">ಈ ಸೈಟà³â€Œà²¨à²¿à²‚ದ ಇನà³à²¨à²·à³à²Ÿà³</translation>
<translation id="1206967143813997005">ತಪà³à²ªà³ ಪà³à²°à²¾à²°à²‚ಭಿಕ ಸಹಿ</translation>
<translation id="1209206284964581585">ಸದà³à²¯à²•à³à²•à³† ಮರೆಮಾಡಿ</translation>
+<translation id="121201262018556460">ನೀವೠ<ph name="DOMAIN" /> ಅನà³à²¨à³ ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²¦à³à²¦à³€à²°à²¿, ಆದರೆ ದà³à²°à³à²¬à²² ಕೀಲಿಯನà³à²¨à³ ಹೊಂದಿರà³à²µ ಸರà³à²µà²°à³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಒದಗಿಸಿದೆ. ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಖಾಸಗಿ ಕೀಲಿಯನà³à²¨à³ ಮà³à²°à²¿à²¦à³à²¹à²¾à²•à²¿à²°à²¬à²¹à³à²¦à³, ಮತà³à²¤à³ ನೀವೠನಿರೀಕà³à²·à²¿à²¸à²¿à²¦ ಸರà³à²µà²°à³ ಅದಾಗಿರದೇ ಇರಬಹà³à²¦à³. (ನೀವೠದಾಳಿಕೋರರೊಂದಿಗೆ ಸಂವಹನ ಮಾಡà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³)</translation>
<translation id="1219129156119358924">ಸಿಸà³à²Ÿà²‚ ಭದà³à²°à²¤à³†</translation>
<translation id="1227224963052638717">ಅಪರಿಚಿತ ನೀತಿ.</translation>
<translation id="1227633850867390598">ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಮರೆಮಾಡಿ</translation>
<translation id="1228893227497259893">ತಪà³à²ªà²¾à²¦ ಅಸà³à²¤à²¿à²¤à³à²µà²¦ ಗà³à²°à³à²¤à³</translation>
<translation id="1232569758102978740">ಶೀರà³à²·à²¿à²•à³†à²°à²¹à²¿à²¤</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (ಸಿಂಕೠಮಾಡಲಾಗಿದೆ)</translation>
<translation id="1263231323834454256">ಓದà³à²µ ಪಟà³à²Ÿà²¿</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" /> ನಲà³à²²à²¿ ಕà³à²°à³à²¯à²¾à²¶à³ ವರದಿಯನà³à²¨à³ ಸೆರೆಹಿಡಿಯಲಾಗಿದೆ (ಇನà³à²¨à³‚ ಅಪà³â€Œà²²à³‹à²¡à³ ಮಾಡಲಾಗಿಲà³à²² ಅಥವಾ ನಿರà³à²²à²•à³à²·à²¿à²¸à²²à²¾à²—ಿಲà³à²²)</translation>
+<translation id="1281526147609854549"><ph name="ISSUER" /> ಇವರಿಂದ ನೀಡಲಾಗಿದೆ</translation>
+<translation id="1283919782143846010">ಅಪಾಯಕಾರಿ ವಿಷಯವನà³à²¨à³ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="1285320974508926690">ಈ ಸೈಟೠಅನà³à²¨à³ ಎಂದಿಗೂ ಭಾಷಾಂತರಿಸದಿರಿ</translation>
<translation id="129553762522093515">ಇತà³à²¤à³€à²šà³†à²—ೆ ಮà³à²šà³à²šà²²à²¾à²—ಿರà³à²µà³à²¦à³</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />ನಿಮà³à²® ಕà³à²•à³€à²—ಳನà³à²¨à³ ತೆರವà³à²—ೊಳಿಸಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">ನಿಮà³à²® ಚಟà³à²µà²Ÿà²¿à²•à³†à²—ಳೠ<ph name="BEGIN_EMPHASIS" />ಇನà³à²¨à³‚ ಇವರಿಗೆ ಕಾಣಿಸಿಕೊಳà³à²³à²¬à²¹à³à²¦à³<ph name="END_EMPHASIS" /> :
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />ನೀವೠಭೇಟಿ ನೀಡಿದ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳà³
+ <ph name="LIST_ITEM" />ನಿಮà³à²® ಉದà³à²¯à³‹à²—ದಾತರೠಅಥವಾ ಶಾಲೆ
+ <ph name="LIST_ITEM" />ನಿಮಗೆ ಇಂಟರà³à²¨à³†à²Ÿà³ ಸೇವೆ ಒದಗಿಸà³à²µà²µà²°à³
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">ಡೊಮೇನೠದಾಖಲಾತಿ:</translation>
<translation id="1340482604681802745">ಪಿಕಪೠವಿಳಾಸ</translation>
<translation id="1344211575059133124">ಈ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ ನೀಡಲೠನೀವೠಅನà³à²®à²¤à²¿ ಪಡೆಯಬೇಕೆಂದೠತೋರà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="1344588688991793829">Chromium ಸà³à²µà²¯à²‚ತà³à²‚ಬà³à²µà²¿à²•à³† ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳà³...</translation>
+<translation id="1348198688976932919">ಮà³à²‚ದಿರà³à²µ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿ ಅಪಾಯಕಾರಿ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳಿವೆ</translation>
<translation id="1374468813861204354">ಸಲಹೆಗಳà³</translation>
<translation id="1375198122581997741">ಆವೃತà³à²¤à²¿à²¯ ಕà³à²°à²¿à²¤à³</translation>
<translation id="1377321085342047638">ಕಾರà³à²¡à³ ಸಂಖà³à²¯à³†</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ಯಾವà³à²¦à³‡ ಡೇಟಾ ಕಳà³à²¹à²¿à²¸à²²à²¾à²—ಿಲà³à²².</translation>
<translation id="1407135791313364759">ಎಲà³à²²à²µà²¨à³à²¨à³‚ ತೆರೆಯಿರಿ</translation>
<translation id="1413809658975081374">ಗೌಪà³à²¯à²¤à³† ದೋಷ</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" /> ಯಲà³à²²à²¿à²°à³à²µ <ph name="ORGANIZATION" /> ಗà³à²°à³à²¤à²¨à³à²¨à³ <ph name="ISSUER" /> ನಿಂದ ಪರಿಶೀಲಿಸಲಾಗಿದೆ.</translation>
<translation id="1426410128494586442">ಹೌದà³</translation>
<translation id="1430915738399379752">ಮà³à²¦à³à²°à²¿à²¸à³</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /> <ph name="DOMAIN" /> ನಲà³à²²à²¿ ಪà³à²Ÿà²•à³à²•à³† ಭೇಟಿ ನೀಡà³à²µ<ph name="END_LINK" /> ಪà³à²°à²¯à²¤à³à²¨à²µà²¨à³à²¨à³ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ.</translation>
-<translation id="1491663344921578213">ವೆಬà³â€Œà²¸à³ˆà²Ÿà³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಪಿನೠಮಾಡà³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ಬಳಸà³à²µ ಕಾರಣ ಇದೀಗ ನೀವೠ<ph name="SITE" /> ಭೇಟಿ ಮಾಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ದಾಳಿಗಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ನಂತರ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ಇನà³à²¨à²·à³à²Ÿà³}one{<ph name="PAYMENT_METHOD_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ಇನà³à²¨à²·à³à²Ÿà³}other{<ph name="PAYMENT_METHOD_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ಇನà³à²¨à²·à³à²Ÿà³}}</translation>
<translation id="1506687042165942984">ಈ ಪà³à²Ÿà²¦ ಉಳಿಸಲಾದ (ಉದಾ. ಹಳೆಯದೠಎಂದೠಕರೆಯಲಾಗà³à²µ) ನಕಲನà³à²¨à³ ತೋರಿಸಿ.</translation>
<translation id="1517433312004943670">ಫೋನೠಸಂಖà³à²¯à³† ಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
<translation id="1519264250979466059">ಬಿಲà³à²¡à³ ಡೇಟಾ</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">ಈ ವೈಶಿಷà³à²Ÿà³à²¯à²µà²¨à³à²¨à³ ಬಳಸಲೠJavaScript ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸಬೇಕà³.</translation>
<translation id="1555130319947370107">ನೀಲಿ</translation>
<translation id="1559528461873125649">ಆ ರೀತಿಯ ಯಾವà³à²¦à³‡ ಫೈಲೠಅಥವಾ ಡೈರೆಕà³à²Ÿà²°à²¿ ಇಲà³à²²</translation>
-<translation id="1559572115229829303">&lt;p&gt;ನಿಮà³à²® ಸಾಧನದ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯ (<ph name="DATE_AND_TIME" />) ತಪà³à²ªà²¾à²—ಿರà³à²µ ಕಾರಣ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಗೆ ಖಾಸಗಿ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—à³à²µà³à²¦à²¿à²²à³à²².&lt;/p&gt;
-
- &lt;p&gt;ದಯವಿಟà³à²Ÿà³ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²¨ &lt;strong&gt;ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳà³&lt;/strong&gt; ವಿಭಾಗದ &lt;strong&gt;ಸಾಮಾನà³à²¯&lt;/strong&gt; ದಿಂದ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯವನà³à²¨à³ ಹೊಂದಿಸಿ.&lt;/p&gt;</translation>
<translation id="1583429793053364125">ಈ ವೆಬà³â€Œà²ªà³à²Ÿà²µà²¨à³à²¨à³ ಪà³à²°à²¦à²°à³à²¶à²¿à²¸à³à²µà²¾à²— ಯಾವà³à²¦à³‹ ತಪà³à²ªà³ ಸಂಭವಿಸಿದೆ.</translation>
<translation id="1592005682883173041">ಸà³à²¥à²³à³€à²¯ ಡೇಟಾ ಪà³à²°à²µà³‡à²¶</translation>
+<translation id="1594030484168838125">ಆರಿಸಿ</translation>
<translation id="161042844686301425">ಹಸಿರà³à²¨à³€à²²à²¿</translation>
+<translation id="1620510694547887537">ಕà³à²¯à²¾à²®à²°à²¾</translation>
<translation id="1629803312968146339">ಈ ಕಾರà³à²¡à³ ಅನà³à²¨à³ Chrome ಉಳಿಸಬೇಕೆಂದೠನೀವೠಬಯಸà³à²µà²¿à²°à²¾?</translation>
<translation id="1639239467298939599">ಲೋಡೠಆಗà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="1640180200866533862">ಬಳಕೆದಾರನ ನೀತಿಗಳà³</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">ನೆಟà³â€Œà²µà²°à³à²•à³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œ ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ ಹಾಗೂ ಆಮದೠಮಾಡಲಾಗà³à²µà³à²¦à²¿à²²à³à²².</translation>
<translation id="1644574205037202324">ಇತಿಹಾಸ</translation>
<translation id="1645368109819982629">ಬೆಂಬಲವಿಲà³à²²à²¦ ಪà³à²°à³†à³‚ಟೋಕಾಲà³</translation>
+<translation id="1655462015569774233">{1,plural, =1{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²¦ ಅವಧಿಯೠನಿನà³à²¨à³† ಮà³à²—ಿದಿದೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ಗಡಿಯಾರವನà³à²¨à³ ಪà³à²°à²¸à³à²¤à³à²¤ <ph name="CURRENT_DATE" /> ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಅದೠಸರಿಯಾಗಿದೆಯೇ? ಇಲà³à²²à²¦à²¿à²¦à³à²¦à²°à³†, ನಿಮà³à²® ಸಿಸà³à²Ÿà²‚ನ ಗಡಿಯಾರವನà³à²¨à³ ನೀವೠಸರಿಪಡಿಸಿ ಹಾಗೂ ನಂತರ ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ರಿಫà³à²°à³†à²¶à³ ಮಾಡಿ.}one{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²¦ ಅವಧಿಯೠ# ದಿನಗಳ ಹಿಂದೆ ಮà³à²—ಿದಿದೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ಗಡಿಯಾರವನà³à²¨à³ ಪà³à²°à²¸à³à²¤à³à²¤ <ph name="CURRENT_DATE" /> ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಅದೠಸರಿಯಾಗಿದೆಯೇ? ಇಲà³à²²à²¦à²¿à²¦à³à²¦à²°à³†, ನಿಮà³à²® ಸಿಸà³à²Ÿà²‚ನ ಗಡಿಯಾರವನà³à²¨à³ ನೀವೠಸರಿಪಡಿಸಿ ಹಾಗೂ ನಂತರ ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ರಿಫà³à²°à³†à²¶à³ ಮಾಡಿ.}other{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²¦ ಅವಧಿಯೠ# ದಿನಗಳ ಹಿಂದೆ ಮà³à²—ಿದಿದೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ಗಡಿಯಾರವನà³à²¨à³ ಪà³à²°à²¸à³à²¤à³à²¤ <ph name="CURRENT_DATE" /> ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಅದೠಸರಿಯಾಗಿದೆಯೇ? ಇಲà³à²²à²¦à²¿à²¦à³à²¦à²°à³†, ನಿಮà³à²® ಸಿಸà³à²Ÿà²‚ನ ಗಡಿಯಾರವನà³à²¨à³ ನೀವೠಸರಿಪಡಿಸಿ ಹಾಗೂ ನಂತರ ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ರಿಫà³à²°à³†à²¶à³ ಮಾಡಿ.}}</translation>
<translation id="1656489000284462475">ಪಿಕಪà³</translation>
<translation id="1663943134801823270">ಕಾರà³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ವಿಳಾಸಗಳನà³à²¨à³ Chrome ನಿಂದ ಪಡೆಯಲಾಗಿದೆ. ನೀವೠಅವà³à²—ಳನà³à²¨à³ <ph name="BEGIN_LINK" />ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳಲà³à²²à²¿<ph name="END_LINK" /> ನಿರà³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> ಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ನಿಮà³à²® ಮಾಹಿತಿಯನà³à²¨à³ ಸಂರಕà³à²·à²¿à²¸à²²à³ ಎನà³â€Œà²•à³à²°à²¿à²ªà³à²¶à²¨à³ ಪà³à²°à²¯à³‹à²œà²¨à²µà²¨à³à²¨à³ ಬಳಸಿಕೊಳà³à²³à³à²¤à³à²¤à²¦à³†. ಈ ಸಂದರà³à²­à²¦à²²à³à²²à²¿ Google Chrome <ph name="SITE" /> ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ೆ ಸಂಪರà³à²•à²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²¦à²¾à²—, ಆ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œâ€Œ ಅಸಹಜ ಮತà³à²¤à³ ತಪà³à²ªà³ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಹಿಂತಿರà³à²—ಿಸಿದೆ. ದಾಳಿಕೋರರೠ<ph name="SITE" /> ರೂಪದಲà³à²²à²¿ ಸೋಗೠಹಾಕಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à³à²µà²¾à²— ಅಥವಾ ವೈ-ಫೈ ಸೈನà³-ಇನೠಪರದೆಯೠಸಂಪರà³à²•à²•à³à²•à³† ಅಡà³à²¡à²¿à²¯à³à²‚ಟೠಮಾಡಿದಾಗ ಇದೠಕಂಡà³à²¬à²°à²¬à²¹à³à²¦à³. ಯಾವà³à²¦à³‡ ಡೇಟಾವನà³à²¨à³ ವಿನಿಮಯ ಮಾಡಿಕೊಳà³à²³à³à²µ ಮೊದಲೇ Google Chrome ಸಂಪರà³à²• ಕಡಿತಗೊಳಿಸಿರà³à²µ ಕಾರಣ, ನಿಮà³à²® ಮಾಹಿತಿ ಈಗಲೂ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿದೆ.</translation>
-<translation id="168328519870909584"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಲà³à²²à²¿à²°à³à²µ ದಾಳಿಕೋರರೠನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ ಮಾಹಿತಿ (ಉದಾಹರಣೆಗೆ, ಫೋಟೋಗಳà³, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ಮಾಹಿತಿಗಳà³) ಕದಿಯಲೠಇಲà³à²²à²µà³‡ ಅಳಿಸಲೠಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³.</translation>
<translation id="168841957122794586">ಸರà³à²µà²°à³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ದà³à²°à³à²¬à²² ಕà³à²°à²¿à²ªà³à²Ÿà³‹à²—à³à²°à²¾à²«à²¿à²•à³ ಕೀಯನà³à²¨à³ ಹೊಂದಿದೆ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ; ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಬಹà³à²¶à²ƒ ನಾಳೆಯಿಂದ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.}one{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಬಹà³à²¶à²ƒ ಭವಿಷà³à²¯à²¦à²²à³à²²à²¿ # ದಿನಗಳಲà³à²²à²¿ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.}other{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಬಹà³à²¶à²ƒ ಭವಿಷà³à²¯à²¦à²²à³à²²à²¿ # ದಿನಗಳಲà³à²²à²¿ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">ಈ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ ನೀಡಲೠನಿಮಗೆ <ph name="NAME" /> ಅವರ ಅನà³à²®à²¤à²¿à²¯ ಅಗತà³à²¯à²µà²¿à²°à³à²¤à³à²¤à²¦à³†</translation>
<translation id="1721424275792716183">* ಈ ಫೀಲà³à²¡à³ ಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">ನಂತರ ಪà³à²Ÿ ಡೌನà³â€Œà²²à³‹à²¡à³ ಮಾಡಿ</translation>
<translation id="17513872634828108">ತೆರೆದ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳà³</translation>
<translation id="1753706481035618306">ಪà³à²Ÿ ಸಂಖà³à²¯à³†</translation>
+<translation id="1763864636252898013">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ನಿಮà³à²® ಸಾಧನದ ಆಪರೇಟಿಂಗೠಸಿಸà³à²Ÿà²‚‌ ಪà³à²°à²•à²¾à²° ವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²—ಿಲà³à²². ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows ನೆಟà³â€Œà²µà²°à³à²•à³ ಡಯಾಗà³à²¨à²¾à²¸à³à²Ÿà²¿à²•à³à²¸à³â€Œ ರನೠಮಾಡಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿â€Œ<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">ದಯವಿಟà³à²Ÿà³ ನಿಮà³à²® ಸಿಂಕೠಪಾಸà³â€Œà²«à³à²°à³‡à²¸à³ ಅನà³à²¨à³ ನವೀಕರಿಸಿ.</translation>
<translation id="1787142507584202372">ನಿಮà³à²® ತೆರೆಯಲಾದ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳೠಇಲà³à²²à²¿ ಗೋಚರಿಸà³à²¤à³à²¤à²¦à³†</translation>
+<translation id="1789575671122666129">ಪಾಪà³â€Œà²…ಪà³â€Œà²—ಳà³</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">ಕಾರà³à²¡à³â€Œà²¹à³‹à²²à³à²¡à²°à³ ಹೆಸರà³</translation>
-<translation id="1803678881841855883">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à³ ಮಾಡà³à²µà²¿à²•à³† ಇತà³à²¤à³€à²šà³†à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ <ph name="BEGIN_LINK" />ಮಾಲà³â€Œà²µà³‡à²°à³ ಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³†<ph name="END_LINK" />. ಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿರà³à²µ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳೠಕೆಲವೊಮà³à²®à³† ಮಾಲà³â€Œà²µà³‡à²°à³ ದಾಳಿಗೆ ತà³à²¤à³à²¤à²¾à²—ಿರà³à²¤à³à²¤à²µà³†. ದà³à²°à³à²¦à³à²¦à³‡à²¶à²ªà³‚ರಿತ ವಿಷಯವೠಚಿರಪರಿಚಿತ ಮಾಲà³â€Œà²µà³‡à²°à³ <ph name="SUBRESOURCE_HOST" /> ವಿತರಕರಿಂದ ಬರà³à²¤à³à²¤à²µà³†. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440"><ph name="ADDED_TO_AUTOFILL_MONTH" /> ಸೇರಿಸಲಾಗಿದೆ</translation>
<translation id="1821930232296380041">ಅಮಾನà³à²¯à²µà²¾à²¦ ವಿನಂತಿ ಅಥವಾ ವಿನಂತಿ ಪà³à²¯à²¾à²°à²¾à²®à³€à²Ÿà²°à³â€Œà²—ಳà³</translation>
<translation id="1826516787628120939">ಪರಿಶೀಲಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="1834321415901700177">ಈ ಸೈಟೠಹಾನಿಕಾರಕ ಪà³à²°à³†à³‚ೕಗà³à²°à²¾à²‚ಗಳನà³à²¨à³ ಹೊಂದಿದೆ</translation>
+<translation id="1840414022444569775">ಈ ಕಾರà³à²¡à³ ಸಂಖà³à²¯à³†à²¯à²¨à³à²¨à³ ಈಗಾಗಲೇ ಬಳಸಲಾಗಿದೆ</translation>
<translation id="1842969606798536927">ಪಾವತಿಸಿ</translation>
<translation id="1871208020102129563">.pac ಸà³à²•à³à²°à²¿à²ªà³à²Ÿà³ URL ಅಲà³à²²à²¦à³†, ನಿಗಧಿತ ಪà³à²°à²¾à²•à³à²¸à²¿ ಸರà³à²µà²°à³â€Œà²—ಳನà³à²¨à³ ಬಳಸಲೠಪà³à²°à²¾à²•à³à²¸à²¿à²¯à²¨à³à²¨à³ ಹೊಂದಿಸಲಾಗಿದೆ.</translation>
<translation id="1871284979644508959">ಅಗತà³à²¯ ಕà³à²·à³†à³•à²¤à³à²°</translation>
<translation id="187918866476621466">ಆರಂಭಿಕ ಪà³à²Ÿà²—ಳನà³à²¨à³ ತೆರೆಯಿರಿ</translation>
<translation id="1883255238294161206">ಪಟà³à²Ÿà²¿à²¯à²¨à³à²¨à³ ಸಂಕà³à²šà²¿à²¸à²¿</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ಇನà³à²¨à²·à³à²Ÿà³}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ಇನà³à²¨à²·à³à²Ÿà³}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ಇನà³à²¨à²·à³à²Ÿà³}}</translation>
<translation id="1898423065542865115">ಫಿಲà³à²Ÿà²°à²¿à²‚ಗà³</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 ಸೈಟà³}one{# ಸೈಟà³â€Œà²—ಳà³}other{# ಸೈಟà³â€Œà²—ಳà³}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> ಗೆ ಹೋಗಿ</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳà³</translation>
<translation id="1973335181906896915">ಅನà³à²•à³à²°à²®à²—ೊಳಿಸà³à²µà²¿à²•à³†à²¯ ದೋಷ</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> ರಿಂದ ಅತಿಕà³à²°à²®à²¿à²¸à²²à²¾à²—ಿರà³à²µ ಕಾರಣ ಇದನà³à²¨à³ ನಿರà³à²²à²•à³à²·à²¿à²¸à²²à²¾à²—ಿದೆ.</translation>
<translation id="2138201775715568214">ಹತà³à²¤à²¿à²°à²¦ ಪà³à²°à²¤à³à²¯à²•à³à²· ವೆಬೠಪà³à²Ÿà²—ಳನà³à²¨à³ ಹà³à²¡à³à²•à²²à²¾à²—à³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="213826338245044447">ಮೊಬೈಲೠಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳà³</translation>
-<translation id="2148716181193084225">ಇಂದà³</translation>
+<translation id="2147827593068025794">ಹಿನà³à²¨à³†à²²à³† ಸಿಂಕà³</translation>
<translation id="2154054054215849342">ಸಿಂಕೠಸೇವೆಯೠನಿಮà³à²® ಡೊಮೇನà³â€Œà²—ೆ ಲಭà³à²¯à²µà²¿à²²à³à²²</translation>
<translation id="2154484045852737596">ಕಾರà³à²¡à³ ಎಡಿಟೠಮಾಡಿ</translation>
<translation id="2166049586286450108">ಪೂರà³à²£ ನಿರà³à²µà²¾à²¹à²• ಪà³à²°à²µà³‡à²¶</translation>
<translation id="2166378884831602661">ಈ ಸೈಟà³â€Œà²—ೆ ಸà³à²°à²•à³à²·à²¿à²¤ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಒದಗಿಸಲಾಗà³à²µà³à²¦à²¿à²²à³à²²</translation>
<translation id="2181821976797666341">ನಿಯಮಗಳà³</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 ವಿಳಾಸ}one{# ವಿಳಾಸಗಳà³}other{# ವಿಳಾಸಗಳà³}}</translation>
+<translation id="2187317261103489799">ಪತà³à²¤à³† ಮಾಡಿ (ಡಿಫಾಲà³à²Ÿà³)</translation>
<translation id="2202020181578195191">ಮಾನà³à²¯à²µà²¾à²¦ ಅವಧಿ-ಮà³à²•à³à²¤à²¾à²¯ ವರà³à²·à²µà²¨à³à²¨à³ ನಮೂದಿಸಿ</translation>
<translation id="2212735316055980242">ನೀತಿ ಕಂಡೠಬಂದಿಲà³à²²</translation>
<translation id="2213606439339815911">ನಮೂದà³à²—ಳನà³à²¨à³ ಪಡೆಯಲಾಗà³à²¤à³à²¤à²¿à²¦à³†...</translation>
+<translation id="2218879909401188352">ದಾಳಿಕೋರರೠಪà³à²°à²¸à³à²¤à³à²¤ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಲà³à²²à²¿à²¦à³à²¦à²¾à²°à³† ಮತà³à²¤à³ ನಿಮà³à²® ಸಾಧನಕà³à²•à³† ಹಾನಿಯನà³à²¨à³à²‚ಟೠಮಾಡà³à²µ ಅಪಾಯಕಾರಿ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²¬à²¹à³à²¦à³, ನಿಮà³à²® ಮೊಬೈಲೠಬಿಲà³â€Œà²—ೆ ಮರೆಮಾಡಿದ ಶà³à²²à³à²•à²—ಳನà³à²¨à³ ಸೇರಿಸಬಹà³à²¦à³, ಅಥವಾ ನಿಮà³à²® ವೈಯಕà³à²¤à²¿à²• ಮಾಹಿತಿಯನà³à²¨à³ ಕದಿಯಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />ಡಯಾಗà³à²¨à²¸à³à²Ÿà²¿à²•à³à²¸à³â€Œâ€Œ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œ<ph name="END_LINK" /> ಬಳಸಿಕೊಂಡೠನಿಮà³à²® ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸರಿಪಡಿಸಿ</translation>
<translation id="2239100178324503013">ಈಗ ಕಳà³à²¹à²¿à²¸à²¿</translation>
<translation id="225207911366869382">ಈ ನೀತಿಗಾಗಿ ಈ ಮೌಲà³à²¯à²µà²¨à³à²¨à³ ಅಸಮà³à²®à²¤à²¿à²¸à²²à²¾à²—ಿದೆ.</translation>
<translation id="2262243747453050782">HTTP ದೋಷ</translation>
+<translation id="2270484714375784793">ಫೋನೠಸಂಖà³à²¯à³†</translation>
<translation id="2282872951544483773">ಲಭà³à²¯à²µà²¿à²²à³à²²à²¦ ಪà³à²°à²¯à³‹à²—ಗಳà³</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> à²à²Ÿà²‚}one{<ph name="ITEM_COUNT" /> à²à²Ÿà²‚ಗಳà³}other{<ph name="ITEM_COUNT" /> à²à²Ÿà²‚ಗಳà³}}</translation>
<translation id="2292556288342944218">ನಿಮà³à²® ಇಂಟರà³à²¨à³†à²Ÿà³ ಪà³à²°à²µà³‡à²¶ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="230155334948463882">ಹೊಸ ಕಾರà³à²¡à³?</translation>
-<translation id="2305919008529760154">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ನಕಲಿ ಇರಬಹà³à²¦à³. ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> ಗೆ ಬಳಕೆದಾರಹೆಸರೠಮತà³à²¤à³ ಪಾಸà³â€Œà²µà²°à³à²¡à³ ಅಗತà³à²¯à²µà²¿à²¦à³†.</translation>
-<translation id="2318774815570432836">ವೆಬà³â€Œà²¸à³ˆà²Ÿà³ HSTS ಬಳಸà³à²µ ಕಾರಣ ಇದೀಗ ನೀವೠ<ph name="SITE" /> ಗೆ ಭೇಟಿ ಮಾಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ದಾಳಿಗಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ನಂತರ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">ನಿಮà³à²® ನಿರà³à²µà²¾à²¹à²•à²¦à²¿à²‚ದ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳನà³à²¨à³ ನಿಯಂತà³à²°à²¿à²¸à²²à²¾à²—ಿದೆ</translation>
<translation id="2354001756790975382">ಇತರ ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳà³</translation>
+<translation id="2354430244986887761">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à²¿à²‚ಗà³â€Œ ಇತà³à²¤à³€à²šà²¿à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ <ph name="BEGIN_LINK" />ಹಾನಿಕಾರಕ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಕಂಡà³à²¹à²¿à²¡à²¿à²¦à²¿à²¦à³†<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">ಈ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿ ನೀವೠನೋಡà³à²¤à³à²¤à²¿à²°à³à²µ ಚಿತà³à²°à²—ಳನà³à²¨à³ ವೀಕà³à²·à²¿à²¸à²²à³ ಮತà³à²¤à³ ಅವà³à²—ಳನà³à²¨à³ ಮಾರà³à²ªà²¡à²¿à²¸à³à²µ ಮೂಲಕ ನಿಮà³à²®à²¨à³à²¨à³ ವಂಚಿಸಲೠದಾಳಿಕೋರರಿಗೆ ಸಾಧà³à²¯à²µà²¾à²—à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³.</translation>
+<translation id="2356070529366658676">ಕೇಳಿ</translation>
+<translation id="2359629602545592467">ಬಹà³</translation>
<translation id="2359808026110333948">ಮà³à²‚ದà³à²µà²°à²¿à²¸à³</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> ನಲà³à²²à²¿ ಸೆರೆಹಿಡಿಯಲಾದ ಕà³à²°à³à²¯à²¾à²¶à³ ವರದಿಯನà³à²¨à³ ಅಪà³â€Œà²²à³‹à²¡à³ ಮಾಡಲಾಗಿಲà³à²²</translation>
<translation id="2367567093518048410">ಹಂತ</translation>
-<translation id="2371153335857947666">{1,plural, =1{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²¦ ಅವಧಿಯೠನಿನà³à²¨à³† ಮà³à²—ಿದಿದೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ಗಡಿಯಾರವನà³à²¨à³ ಪà³à²°à²¸à³à²¤à³à²¤ <ph name="CURRENT_DATE" /> ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಅದೠಸರಿಯಾಗಿದೆಯೇ? ಇಲà³à²²à²¦à²¿à²¦à³à²¦à²°à³†, ನಿಮà³à²® ಸಿಸà³à²Ÿà²‚ನ ಗಡಿಯಾರವನà³à²¨à³ ನೀವೠಸರಿಪಡಿಸಿ ಹಾಗೂ ನಂತರ ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ರಿಫà³à²°à³†à²¶à³ ಮಾಡಿ. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.}one{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²¦ ಅವಧಿಯೠ# ದಿನಗಳ ಹಿಂದೆ ಮà³à²—ಿದಿದೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ಗಡಿಯಾರವನà³à²¨à³ ಪà³à²°à²¸à³à²¤à³à²¤ <ph name="CURRENT_DATE" /> ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಅದೠಸರಿಯಾಗಿದೆಯೇ? ಇಲà³à²²à²¦à²¿à²¦à³à²¦à²°à³†, ನಿಮà³à²® ಸಿಸà³à²Ÿà²‚ನ ಗಡಿಯಾರವನà³à²¨à³ ನೀವೠಸರಿಪಡಿಸಿ ಹಾಗೂ ನಂತರ ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ರಿಫà³à²°à³†à²¶à³ ಮಾಡಿ. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.}other{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²¦ ಅವಧಿಯೠ# ದಿನಗಳ ಹಿಂದೆ ಮà³à²—ಿದಿದೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ಗಡಿಯಾರವನà³à²¨à³ ಪà³à²°à²¸à³à²¤à³à²¤ <ph name="CURRENT_DATE" /> ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ಅದೠಸರಿಯಾಗಿದೆಯೇ? ಇಲà³à²²à²¦à²¿à²¦à³à²¦à²°à³†, ನಿಮà³à²® ಸಿಸà³à²Ÿà²‚ನ ಗಡಿಯಾರವನà³à²¨à³ ನೀವೠಸರಿಪಡಿಸಿ ಹಾಗೂ ನಂತರ ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ರಿಫà³à²°à³†à²¶à³ ಮಾಡಿ. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">ಯಾವà³à²¦à³‡ UI ಪರà³à²¯à²¾à²¯à²—ಳೠಲಭà³à²¯à²µà²¿à²²à³à²²</translation>
<translation id="2384307209577226199">ಎಂಟರà³â€Œà²ªà³à²°à³ˆà²¸à³ ಡಿಫಾಲà³à²Ÿà³</translation>
<translation id="2386255080630008482">ಸರà³à²µà²°à³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಹಿಂಪಡೆಯಲಾಗಿದೆ.</translation>
<translation id="2392959068659972793">ಯಾವà³à²¦à³‡ ಮೌಲà³à²¯ ಹೊಂದಿಸಿಲà³à²²à²¦ ನೀತಿಗಳನà³à²¨à³ ತೋರಿಸಿ</translation>
<translation id="239429038616798445">ಈ ಶಿಪà³à²ªà²¿à²‚ಗೠವಿಧಾನ ಲಭà³à²¯à²µà²¿à²²à³à²². ಬೇರೊಂದೠವಿಧಾನವನà³à²¨à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="2396249848217231973">&amp;ಅಳಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸà³</translation>
-<translation id="2460160116472764928">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à³ ಮಾಡà³à²µà²¿à²•à³† ಇತà³à²¤à³€à²šà³†à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ <ph name="BEGIN_LINK" />ಮಾಲà³â€Œà²µà³‡à²°à³ ಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³†<ph name="END_LINK" />. ಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿರà³à²µ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳೠಕೆಲವೊಮà³à²®à³† ಮಾಲà³â€Œà²µà³‡à²°à³ ದಾಳಿಗೆ ತà³à²¤à³à²¤à²¾à²—ಿರà³à²¤à³à²¤à²µà³†. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಹಿಂತೆಗೆದà³à²•à³Šà²³à³à²³à²²à²¾à²—ಿರಬಹà³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
<translation id="2463739503403862330">ಭರà³à²¤à²¿ ಮಾಡà³</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />ನೆಟà³â€Œà²µà²°à³à²•à³ ಡಯಾಗà³à²¨à²¾à²¸à³à²Ÿà²¿à²•à³à²¸à³â€Œ ರನೠಆಗà³à²¤à³à²¤à²¿à²¦à³†<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">ಅಮಾನà³à²¯à²µà²¾à²¦ ಹà³à²¡à³à²•à²¾à²Ÿ URL.</translation>
+<translation id="2482878487686419369">ಸೂಚನೆಗಳà³</translation>
<translation id="2491120439723279231">ಸರà³à²µà²°à³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ದೋಷಗಳನà³à²¨à³ ಹೊಂದಿದೆ.</translation>
<translation id="2495083838625180221">JSON ವಿಶà³à²²à³‡à²·à²•</translation>
<translation id="2495093607237746763">ಪರಿಶೀಲಿಸಿದರೆ, ವೇಗವಾಗಿ ಫಾರà³à²®à³ ಭರà³à²¤à²¿ ಮಾಡಲೠChromium ಈ ಸಾಧನದಲà³à²²à²¿ ನಿಮà³à²® ಕಾರà³à²¡à³â€Œà²¨ ಪà³à²°à²¤à²¿à²¯à²¨à³à²¨à³ ಸಂಗà³à²°à²¹à²¿à²¸à³à²¤à³à²¤à²¦à³†.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">ಹಿಂದಿರà³à²—ಿ</translation>
<translation id="2515629240566999685">ನಿಮà³à²® ಪà³à²°à²¦à³†à³•à²¶à²¦à²²à³à²²à²¿à²¨ ಸಿಗà³à²¨à²²à³ ಪರಿಶೀಲಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="2516305470678292029">UI ಪರà³à²¯à²¾à²¯à²—ಳà³</translation>
+<translation id="2539524384386349900">ಪತà³à²¤à³† ಮಾಡà³</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ಅಮಾನà³à²¯ ಪà³à²°à²¤à²¿à²•à³à²°à²¿à²¯à³† ಕಳà³à²¹à²¿à²¸à²¿à²¦à³†.</translation>
-<translation id="2552545117464357659">ನವೀನ</translation>
<translation id="2556876185419854533">&amp;ಸಂಪಾದಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸಿ</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> ಅವರಿಂದ. ಇದನà³à²¨à³ ಮತà³à²¤à³ ಇತರ <ph name="OTHER_ARTICLE_COUNT" /> ಸà³à²¦à³à²¦à²¿à²—ಳನà³à²¨à³ ಓದಿ.</translation>
<translation id="2587841377698384444">ಡೈರೆಕà³à²Ÿà²°à²¿ API ID:</translation>
<translation id="2597378329261239068">ಈ ಡಾಕà³à²¯à³à²®à³†à²‚ಟà³â€Œ ಅನà³à²¨à³ ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²¨à²¿à²‚ದ ರಕà³à²·à²¿à²¸à²²à²¾à²—ಿದೆ. ದಯವಿಟà³à²Ÿà³ ಪಾಸà³â€Œà²µà²°à³à²¡à³ ಅನà³à²¨à³ ನಮೂದಿಸಿ.</translation>
<translation id="2609632851001447353">ಪರಿವರà³à²¤à²¨à³†à²—ಳà³</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œ ($1)}=2{2 ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳೠ($1, $2)}one{# ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳೠ($1, $2, $3)}other{# ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳೠ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">ನಿಮà³à²® ಗಡಿಯಾರವೠಮà³à²‚ದೆ ಇದೆ</translation>
<translation id="2639739919103226564">ಸà³à²¥à²¿à²¤à²¿: </translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ಫೈಲà³â€Œà²—ೆ ಪà³à²°à²µà³‡à²¶à²µà²¨à³à²¨à³ ನಿರಾಕರಿಸಲಾಗಿದೆ</translation>
<translation id="2653659639078652383">ಸಲà³à²²à²¿à²¸à³</translation>
<translation id="2666117266261740852">ಇತರ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳೠಅಥವಾ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€à²—ಳನà³à²¨à³ ಮà³à²šà³à²šà²¿</translation>
+<translation id="2670429602441959756">VR ನಲà³à²²à²¿ ಇನà³à²¨à³‚ ಬೆಂಬಲಿಸದ ವೈಶಿಷà³à²Ÿà³à²¯à²—ಳನà³à²¨à³ ಈ ಪà³à²Ÿà²µà³ ಒಳಗೊಂಡಿದೆ. ನಿರà³à²—ಮಿಸà³à²¤à³à²¤à²¿à²¦à³†...</translation>
<translation id="2674170444375937751">ನಿಮà³à²® ಇತಿಹಾಸದಿಂದ ನೀವೠಈ ಪà³à²Ÿà²—ಳನà³à²¨à³ ಖಚಿತವಾಗಿ ಅಳಿಸಲೠಬಯಸà³à²¤à³à²¤à²¿à²¦à³à²¦à³€à²°à²¾?</translation>
<translation id="2677748264148917807">ತೊರೆಯಿರಿ</translation>
-<translation id="269990154133806163">ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಪಾರದರà³à²¶à²•à²¤à³† ನೀತಿಯನà³à²¨à³ ಬಳಸಿಕೊಂಡೠಸಾರà³à²µà²œà²¨à²¿à²•à²µà²¾à²—ಿ ಬಹಿರಂಗಗೊಳಿಸದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦à³†. ಇದೠಅವà³à²—ಳೠವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²—ಿವೆ ಮತà³à²¤à³ ಆಕà³à²°à²®à²£à²•à²¾à²°à²° ವಿರà³à²¦à³à²§ ರಕà³à²·à²£à³†à²¯à²¨à³à²¨à³ ನೀಡà³à²¤à³à²¤à²µà³† ಎಂಬà³à²¦à²¨à³à²¨à³ ಖಚಿತಪಡಿಸಿಕೊಳà³à²³à²²à³ ಕೆಲವೠಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳಿಗೆ ಅಗತà³à²¯à²µà²¾à²—ಿದೆ. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">ಓದà³à²µ ಪಟà³à²Ÿà²¿</translation>
<translation id="2704283930420550640">ಮೌಲà³à²¯à²µà³ ಸà³à²µà²°à³‚ಪಕà³à²•à³† ಹೊಂದಿಕೆಯಾಗà³à²µà³à²¦à²¿à²²à³à²².</translation>
<translation id="2704951214193499422">ಈ ಸಮಯದಲà³à²²à²¿ Chromium ಗೆ ನಿಮà³à²® ಕಾರà³à²¡à³ ಖಚಿತಪಡಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²². ದಯವಿಟà³à²Ÿà³ ನಂತರ ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="2705137772291741111">ಈ ಸೈಟà³â€Œà²¨ ಉಳಿಸಿದ (ಸಂಗà³à²°à²¹à²µà²¾à²—ಿರà³à²µ) ನಕಲನà³à²¨à³ ಓದಲಾಗà³à²¤à³à²¤à²¿à²²à³à²².</translation>
<translation id="2709516037105925701">ಸà³à²µà²¯à²‚ತà³à²‚ಬà³à²µà²¿à²•à³†</translation>
-<translation id="2712118517637785082">ನೀವೠ<ph name="DOMAIN" /> ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿, ಆದರೆ ಸರà³à²µà²°à³ ನೀಡಿದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಅದನà³à²¨à³ ನೀಡಿದವರೠಹಿಂತೆಗೆದà³à²•à³Šà²‚ಡಿದà³à²¦à²¾à²°à³†. ಇದರರà³à²¥ ಸರà³à²µà²°à³ ಒದಗಿಸಿದ ಸà³à²°à²•à³à²·à²¤à²¾ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಯಾವ ಕಾರಣಕà³à²•à³‚ ನಂಬಲಾಗà³à²µà³à²¦à²¿à²²à³à²². ನೀವೠಆಕà³à²°à²®à²£à²•à²¾à²°à²° ಜೊತೆಗೆ ಸಂವಹನ ಮಾಡà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">ಅನà³à²®à²¤à²¿ ಕೇಳಿ</translation>
<translation id="2713444072780614174">ಬಿಳಿ</translation>
<translation id="2720342946869265578">ಸಮೀಪ ಸಾಧನ</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ಸಾಧನದ ರೆಕಾರà³à²¡à³ ಕಾಣೆಯಾಗಿದೆ</translation>
<translation id="2784949926578158345">ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ರೀಸೆಟೠಮಾಡಲಾಗಿದೆ.</translation>
<translation id="2794233252405721443">ಸೈಟೠನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
+<translation id="2799020568854403057">ಮà³à²‚ದಿರà³à²µ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿ ಹಾನಿಕಾರಕ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳಿವೆ</translation>
+<translation id="2803306138276472711">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à²¿à²‚ಗೠಇತà³à²¤à³€à²šà³†à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ <ph name="BEGIN_LINK" />ಮಾಲà³â€Œà²µà³‡à²°à³ ಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³†<ph name="END_LINK" />. ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿದà³à²¦à²°à³‚, ಕೆಲವೊಮà³à²®à³† ಮಾಲà³â€Œà²µà³‡à²°à³â€Œà²—ೆ ತà³à²¤à³à²¤à²¾à²—ಿರà³à²¤à³à²¤à²µà³†.</translation>
<translation id="2824775600643448204">ವಿಳಾಸ ಹಾಗೂ ಹà³à²¡à³à²•à²¾à²Ÿ ಪಟà³à²Ÿà²¿</translation>
<translation id="2826760142808435982"><ph name="CIPHER" /> ಬಳಸಿಕೊಂಡೠಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಎನà³â€Œà²•à³à²°à²¿à²ªà³à²Ÿà³ ಮಾಡಲಾಗಿದೆ ಮತà³à²¤à³ ದೃಢೀಕರಿಸಲಾಗಿದೆ ಮತà³à²¤à³ <ph name="KX" /> ಅನà³à²¨à³ ಕೀ ವಿನಿಮಯ ಯಾಂತà³à²°à²¿à²•à²¤à³†à²¯à²‚ತೆ ಬಳಸà³à²¤à³à²¤à²¦à³†.</translation>
<translation id="2835170189407361413">ಫಾರà³à²®à³ ತೆರವà³à²—ೊಳಿಸà³</translation>
+<translation id="2856444702002559011">ದಾಳಿಕೋರರೠ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಿಂದ ನಿಮà³à²® ಮಾಹಿತಿಯನà³à²¨à³ ಕದಿಯಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³ (ಉದಾಹರಣೆಗೆ, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³, ಸಂದೇಶಗಳೠಅಥವಾ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³â€Œà²—ಳà³). <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">ಮರà³à²²à³‹à²¡à³ ಮಾಡಬೇಡ</translation>
<translation id="2900469785430194048">ಈ ವೆಬà³â€Œà²ªà³à²Ÿ ಪà³à²°à²¦à²°à³à²¶à²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²µà²¾à²— Google Chrome ಮೆಮೊರಿ ಖಾಲಿಯಾಗಿದೆ.</translation>
<translation id="2909946352844186028">ನೆಟà³â€Œà²µà²°à³à²•à³ ಬದಲಾವಣೆಯನà³à²¨à³ ಪತà³à²¤à³† ಮಾಡಲಾಗಿದೆ.</translation>
<translation id="2916038427272391327">ಇತರ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಮà³à²šà³à²šà²¿</translation>
<translation id="2922350208395188000">ಸರà³à²µà²°à³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಪರಿಶೀಲಿಸಲಾಗà³à²µà³à²¦à²¿à²²à³à²².</translation>
<translation id="2928905813689894207">ಬಿಲà³à²²à²¿à²‚ಗೠವಿಳಾಸ</translation>
+<translation id="2941952326391522266">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ <ph name="DOMAIN2" /> ದಿಂದ ಆಗಿದೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
<translation id="2948083400971632585">ಸಂಪರà³à²•à²•à³à²•à²¾à²—ಿ ಕಾನà³à²«à²¿à²—ರೠಮಾಡಲಾಗಿರà³à²µ ಯಾವà³à²¦à³‡ ಪà³à²°à²¾à²•à³à²¸à²¿à²—ಳನà³à²¨à³ ನೀವೠಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳ ಪà³à²Ÿà²¦à²¿à²‚ದ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಬಹà³à²¦à³.</translation>
<translation id="2955913368246107853">ಹà³à²¡à³à²•à²¿ ಬಾರೠಅನà³à²¨à³ ಮà³à²šà³à²šà²¿</translation>
<translation id="2958431318199492670">ONC ಪà³à²°à²®à²¾à²£à²¿à²¤à²•à³à²•à³† ನೆಟà³â€Œà²µà²°à³à²•à³ ಕಾನà³à²«à²¿à²—ರೇಶನೠಅನà³à²¸à²°à²£à³†à²¯à²¾à²—à³à²µà³à²¦à²¿à²²à³à²². ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨ ಭಾಗಗಳನà³à²¨à³ ಆಮದೠಮಾಡಲಾಗದಿರಬಹà³à²¦à³.</translation>
-<translation id="29611076221683977"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಲà³à²²à²¿à²°à³à²µ ದಾಳಿಕೋರರೠನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ ಮಾಹಿತಿ (ಉದಾಹರಣೆಗೆ, ಫೋಟೋಗಳà³, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ಮಾಹಿತಿಗಳà³) ಕದಿಯಲೠಇಲà³à²²à²µà³‡ ಅಳಿಸಲೠಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³.</translation>
<translation id="2966678944701946121">ಅವಧಿ ಮೀರà³à²µ ಸಮಯ: <ph name="EXPIRATION_DATE_ABBR" />, <ph name="ADDED_TO_AUTOFILL_MONTH" /> ಸೇರಿಸಲಾಗಿದೆ</translation>
<translation id="2969319727213777354">ಸà³à²°à²•à³à²·à²¿à²¤ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³, ನಿಮà³à²® ಗಡಿಯಾರವನà³à²¨à³ ಸರಿಯಾಗಿ ಹೊಂದಿಸಬೇಕಾದ ಅಗತà³à²¯à²µà²¿à²¦à³†. ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳೠತಮà³à²®à²¨à³à²¨à³ ಗà³à²°à³à²¤à²¿à²¸à²²à³ ಬಳಸà³à²µ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳೠನಿರà³à²¦à²¿à²·à³à²Ÿ ಅವಧಿಗಳಲà³à²²à²¿ ಮಾತà³à²° ಮಾನà³à²¯à²µà²¾à²—ಿರà³à²µ ಕಾರಣ ಹೀಗಾಗà³à²¤à³à²¤à²¦à³†. ನಿಮà³à²® ಸಾಧನದ ಗಡಿಯಾರವೠತಪà³à²ªà²¾à²—ಿರà³à²µ ಕಾರಣ, Google Chrome ಗೆ ಈ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳನà³à²¨à³ ಪರಿಶೀಲಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—à³à²µà³à²¦à²¿à²²à³à²².</translation>
<translation id="2972581237482394796">&amp;ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">ಮಾನà³à²¯ ವಿಳಾಸವನà³à²¨à³ ನಮೂದಿಸಿ</translation>
<translation id="2986368408720340940">ಈ ಪಿಕಪೠವಿಧಾನ ಲಭà³à²¯à²µà²¿à²²à³à²². ಬೇರೊಂದೠವಿಧಾನವನà³à²¨à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="2991174974383378012">ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳ ಜೊತೆಗೆ ಹಂಚಿಕೊಳà³à²³à³à²µà³à²¦à³</translation>
+<translation id="2991571918955627853">ವೆಬà³â€Œà²¸à³ˆà²Ÿà³ HSTS ಅನà³à²¨à³ ಬಳಸà³à²µ ಕಾರಣದಿಂದ ನೀವೠಸದà³à²¯à²•à³à²•à³† <ph name="SITE" /> ಅನà³à²¨à³ ಭೇಟಿ ನೀಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ಆಕà³à²°à²®à²£à²—ಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿವೆ, ಹಾಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ಸà³à²µà²²à³à²ª ಸಮಯದ ನಂತರ ಕಾರà³à²¯ ನಿರà³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
<translation id="3005723025932146533">ಉಳಿಸಲಾದ ನಕಲನà³à²¨à³ ತೋರಿಸà³</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> ಗೆ CVC ಅನà³à²¨à³ ನಮೂದಿಸಿ. ನೀವೠಒಮà³à²®à³† ಖಚಿತಪಡಿಸಿದರೆ, ನಿಮà³à²® ಕಾರà³à²¡à³ ವಿವರಗಳನà³à²¨à³ ಈ ಸೈಟೠಜೊತೆಗೆ ಹಂಚಿಕೊಳà³à²³à²²à²¾à²—à³à²¤à³à²¤à²¦à³†.</translation>
<translation id="3010559122411665027">ಪಟà³à²Ÿà²¿ ನಮೂದೠ"<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">ಸà³à²µà²¯à²‚ಚಾಲಿತವಾಗಿ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="3024663005179499861">ತಪà³à²ªà²¾à²¦ ನೀತಿಯ ಪà³à²°à²•à²¾à²°</translation>
<translation id="3032412215588512954">ನೀವೠಈ ಸೈಟೠಮರà³à²²à³‹à²¡à³ ಮಾಡಲೠಬಯಸà³à²µà²¿à²°à²¾?</translation>
<translation id="3037605927509011580">ಓಹà³, ಹೋಯà³à²¤à³!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಕನಿಷà³à²Ÿ 1 à²à²Ÿà²‚}=1{1 à²à²Ÿà²‚ (ಮತà³à²¤à³ ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಇನà³à²¨à²·à³à²Ÿà³)}one{# à²à²Ÿà²‚ಗಳೠ(ಮತà³à²¤à³ ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಇನà³à²¨à²·à³à²Ÿà³)}other{# à²à²Ÿà²‚ಗಳೠ(ಮತà³à²¤à³ ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಇನà³à²¨à²·à³à²Ÿà³)}}</translation>
<translation id="3041612393474885105">ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಮಾಹಿತಿ</translation>
<translation id="3063697135517575841">ಈ ಸಮಯದಲà³à²²à²¿ Chrome ಗೆ ನಿಮà³à²® ಕಾರà³à²¡à³ ಅನà³à²¨à³ ಖಚಿತಪಡಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²². ದಯವಿಟà³à²Ÿà³ ನಂತರ ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="3064966200440839136">ಬಾಹà³à²¯ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œâ€Œ ಮೂಲಕರ ಪಾವತಿಸಲೠಅದೃಶà³à²¯ ಮೋಡà³â€Œâ€Œ ತೊರೆಯಲಾಗà³à²¤à³à²¤à²¿à²¦à³†. ಮà³à²‚ದà³à²µà²°à²¿à²¸à³à²µà³à²¦à³‡?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œ}one{# ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³}other{# ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³}}</translation>
<translation id="3093245981617870298">ನೀವೠಆಫà³â€Œà²²à³ˆà²¨à³â€Œà²¨à²²à³à²²à²¿à²°à³à²µà²¿à²°à²¿.</translation>
<translation id="3105172416063519923">ಸà³à²µà²¤à³à²¤à³ ID:</translation>
<translation id="3109728660330352905">ಈ ಪà³à²Ÿ ವೀಕà³à²·à²¿à²¸à³à²µ ಅಧಿಕಾರ ನಿಮಗಿಲà³à²²</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />ಸಂಪರà³à²• ಡಯಾಗà³à²¨à²¾à²¸à³à²Ÿà²¿à²•à³à²¸à³ ರನೠಮಾಡಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿â€Œ<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">ಪà³à²°à²¤à²¿à²•à³à²°à²¿à²¯à³†à²¯à²¨à³à²¨à³ ಡೀಕೋಡೠಮಾಡಲೠವಿಫಲವಾಗಿದೆ</translation>
<translation id="3150653042067488994">ತಾತà³à²•à²¾à²²à²¿à²• ಸರà³à²µà²°à³ ದೋಷ</translation>
@@ -247,14 +277,18 @@
<translation id="3167968892399408617">ನಿಮà³à²® ಎಲà³à²²à²¾ ಅಪರಿಚಿತ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳನà³à²¨à³ ಮà³à²šà³à²šà²¿à²¦ ಬಳಿಕ ನೀವೠಅಪರಿಚಿತ ಮೋಡà³â€Œà²¨à²²à³à²²à²¿ ವೀಕà³à²·à²¿à²¸à²¿à²¦ ಪà³à²Ÿà²—ಳೠಬà³à²°à³Œà²¸à²°à³ ಇತಿಹಾಸದಲà³à²²à²¿, ಕà³à²•à³€ ಸಂಗà³à²°à²¹à²¦à²²à³à²²à²¿ ಅಥವಾ ಹà³à²¡à³à²•à²¾à²Ÿ ಇತಿಹಾಸದಲà³à²²à²¿ ಉಳಿಯà³à²µà³à²¦à²¿à²²à³à²². ನೀವೠಡೌನà³â€Œà²²à³‹à²¡à³ ಮಾಡà³à²µ ಯಾವà³à²¦à³‡ ಫೈಲà³â€Œà²—ಳೠಇಲà³à²²à²µà³‡ ನೀವೠರಚಿಸà³à²µ ಯಾವà³à²¦à³‡ ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳನà³à²¨à³ ಹಾಗೆಯೇ ಇರಿಸಲಾಗà³à²¤à³à²¤à²¦à³†.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ದà³à²µà³€à²ª</translation>
+<translation id="317583078218509884">ಪà³à²Ÿà²µà²¨à³à²¨à³ ಮರà³à²²à³‹à²¡à³ ಮಾಡಿದ ನಂತರ ಹೊಸ ಸೈಟೠಅನà³à²®à²¤à²¿à²—ಳ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳೠಪರಿಣಾಮಬೀರà³à²¤à³à²¤à²¦à³†.</translation>
<translation id="3176929007561373547">ಪà³à²°à²¾à²•à³à²¸à²¿ ಸರà³à²µà²°à³ ಕಾರà³à²¯à²µà²¨à²¿à²°à³à²µà²¹à²¿à²¸à³à²¤à³à²¤à²¿à²¦à³†à²¯à³‡ ಎಂಬà³à²¦à²¨à³à²¨à³ ಖಚಿತಪಡಿಸಿಕೊಳà³à²³à²²à³ ನಿಮà³à²® ಪà³à²°à²¾à²•à³à²¸à²¿ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳನà³à²¨à³ ಪರಿಶೀಲಿಸಿ ಮತà³à²¤à³ ನಿಮà³à²® ನೆಟà³â€Œà²µà²°à³à²•à³ ನಿರà³à²µà²¾à²¹à²•à²°à²¨à³à²¨à³ ಸಂಪರà³à²•à²¿à²¸à²¿. ನೀವೠಪà³à²°à²¾à²•à³à²¸à²¿ ಸರà³à²µà²°à³ ಅನà³à²¨à³ ಬಳಸà³à²¤à³à²¤à²¿à²²à³à²² ಎಂಬ ಅನà³à²®à²¾à²¨ ನಿಮಗಿದà³à²¦à²°à³†:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">ಪà³à²Ÿà²µà²¨à³à²¨à³ ಅದೃಶà³à²¯ ಮೋಡà³â€Œà²¨à²²à³à²²à²¿ ತೆರೆಯಿರಿ</translation>
-<translation id="3202578601642193415">ನವನವೀನ</translation>
+<translation id="320323717674993345">ಪಾವತಿಯನà³à²¨à³ ರದà³à²¦à³à²®à²¾à²¡à²¿</translation>
<translation id="3207960819495026254">ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œ ಮಾಡಲಾಗಿದೆ</translation>
+<translation id="3225919329040284222">ಆಂತರಿಕ ಮಾನದಂಡಗಳಿಗೆ ಹೊಂದಿಕೆಯಾಗದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಹಾಜರಿಪಡಿಸಿದೆ. ನಿಮà³à²® ಸà³à²°à²•à³à²·à²¤à³†à²¯ ಸಲà³à²µà²¾à²—ಿ ಕೆಲವೠಹೆಚà³à²šà³ ಸà³à²°à²•à³à²·à²¿à²¤ ವೆಬೠಸೈಟà³â€Œà²—ಳಲà³à²²à²¿ ಈ ಮಾನದಂಡಗಳನà³à²¨à³ ಸೇರà³à²ªà²¡à³†à²—ೊಳಿಸಲಾಗಿದೆ.</translation>
<translation id="3226128629678568754">ಪà³à²Ÿà²µà²¨à³à²¨à³ ಲೋಡೠಮಾಡà³à²µà³à²¦à²•à³à²•à³† ಅಗತà³à²¯à²µà²¿à²°à³à²µ ಡೇಟಾವನà³à²¨à³ ಮರà³à²¸à²²à³à²²à²¿à²¸à²²à³ ಮರà³à²²à³‹à²¡à³ ಬಟನೠಒತà³à²¤à²¿à²°à²¿.</translation>
+<translation id="3227137524299004712">ಮೈಕà³à²°à³‹à²«à³‹à²¨à³</translation>
<translation id="3228969707346345236">ಪà³à²Ÿà²µà³ ಈಗಾಗಲೇ <ph name="LANGUAGE" /> ರಲà³à²²à²¿ ಇರà³à²µà³à²¦à²° ಕಾರಣ ಭಾಷಾಂತರವೠವಿಫಲವಾಗಿದೆ.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> ಗೆ CVC ಅನà³à²¨à³ ನಮೂದಿಸಿ</translation>
+<translation id="3234666976984236645">ಈ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿ ಯಾವಾಗೂ ಮà³à²–à³à²¯ ವಿಷಯವನà³à²¨à³ ಹà³à²¡à³à²•à²¿</translation>
<translation id="3254409185687681395">ಈ ಪà³à²Ÿ ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³ ಮಾಡಿ</translation>
<translation id="3270847123878663523">&amp;ಮರà³à²•à³à²°à²®à²—ೊಳಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸà³</translation>
<translation id="3282497668470633863">ಕಾರà³à²¡à³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ ಹೆಸರನà³à²¨à³ ಸೇರಿಸಿ</translation>
@@ -268,42 +302,46 @@
<translation id="3340978935015468852">ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳà³</translation>
<translation id="3345135638360864351">ಈ ಸೈಟೠಅನà³à²¨à³ ಪà³à²°à²µà³‡à²¶à²¿à²¸à²²à³ ನೀವೠಸಲà³à²²à²¿à²¸à²¿à²¦ ವಿನಂತಿಯನà³à²¨à³ <ph name="NAME" /> ಗೆ ಕಳà³à²¹à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²². ದಯವಿಟà³à²Ÿà³ ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="3355823806454867987">ಪà³à²°à²¾à²•à³à²¸à²¿ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳನà³à²¨à³ ಬದಲಿಸಿ...</translation>
+<translation id="3361596688432910856">ಈ ಮà³à²‚ದಿನ ಮಾಹಿತಿಯನà³à²¨à³ Chrome ಗೆ <ph name="BEGIN_EMPHASIS" />ಉಳಿಸಲೠಆಗà³à²µà³à²¦à²¿à²²à³à²²<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />ನಿಮà³à²® ಬà³à²°à³Œà²¸à²¿à²‚ಗೠಇತಿಹಾಸ
+ <ph name="LIST_ITEM" />ಕà³à²•à³€à²¸à³ ಮತà³à²¤à³ ಸೈಟೠಡೇಟಾ
+ <ph name="LIST_ITEM" />ಫಾರà³à²®à³â€Œà²—ಳಲà³à²²à²¿ ನಮೂದಿಸಿದ ಮಾಹಿತಿ
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">ಗಡಿಯಾರ ದೋಷ</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> ಇನà³à²¨à²·à³à²Ÿà³ à²à²Ÿà²‚ಗಳà³...</translation>
<translation id="337363190475750230">ಅನà³à²®à²¤à²¿ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="3377188786107721145">ನೀತಿಯ ಪಾರà³à²¸à³ ದೋಷ</translation>
<translation id="3380365263193509176">ಅಪರಿಚಿತ ದೋಷ</translation>
<translation id="3380864720620200369">ಕà³à²²à³ˆà²‚ಟೠID:</translation>
<translation id="3391030046425686457">ವಿತರಣೆಯ ವಿಳಾಸಗಳà³</translation>
<translation id="3395827396354264108">ಪಿಕಪೠವಿಧಾನ</translation>
-<translation id="340013220407300675"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ರಿಂದ ದಾಳಿಕೋರರೠನಿಮà³à²® ಮಾಹಿತಿಯನà³à²¨à³ ಕಳà³à²³à²¤à²¨ ಮಾಡಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³ (ಉದಾಹರಣೆಗೆ, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³, ಸಂದೇಶಗಳà³, ಅಥವಾ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³â€Œà²—ಳà³).</translation>
<translation id="3422248202833853650">ಮೆಮೊರಿ ಮà³à²•à³à²¤à²—ೊಳಿಸಲೠಇತರ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ನಿರà³à²—ಮಿಸಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> ಅನà³à²¨à³ ಪà³à²°à²¸à³à²¤à³à²¤ ತಲà³à²ªà²²à²¾à²—à³à²¤à³à²¤à²¿à²²à³à²².</translation>
+<translation id="3427092606871434483">ಅನà³à²®à²¤à²¿à²¸à²¿ (ಡಿಫಾಲà³à²Ÿà³)</translation>
<translation id="3427342743765426898">&amp;ಸಂಪಾದಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
<translation id="3431636764301398940">ಈ ಸಾಧನಕà³à²•à³† ಈ ಕಾರà³à²¡à³ ಉಳಿಸಿ</translation>
<translation id="3435896845095436175">ಸಕà³à²°à²¿à²¯à²—ೊಳಿಸà³</translation>
<translation id="3447661539832366887">ಈ ಸಾಧನದ ಮಾಲೀಕರೠಡೈನೊಸಾರೠಆಟವನà³à²¨à³ ಆಫೠಮಾಡಿದà³à²¦à²¾à²°à³†.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">ವಿರಾಮವನà³à²¨à³ ಪಡೆಯಿರಿ:</translation>
<translation id="3462200631372590220">ಸà³à²§à²¾à²°à²¿à²¤ ಆಯà³à²•à³†à²®à²¾à²¡à²¿</translation>
<translation id="3467763166455606212">ಕಾರà³à²¡à³â€Œà²¹à³‹à²²à³à²¡à²°à³ ಹೆಸರೠಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
<translation id="3478058380795961209">ಮà³à²•à³à²¤à²¾à²¯à²¦ ತಿಂಗಳà³</translation>
<translation id="3479539252931486093">ಇದೠಅನಿರೀಕà³à²·à²¿à²¤à²µà³†à³•? <ph name="BEGIN_LINK" />ನಮಗೆ ತಿಳಿಸಿ<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">ಈಗ ಬೇಡ</translation>
-<translation id="348000606199325318">ಕà³à²°à³à²¯à²¾à²¶à³ à²à²¡à²¿ <ph name="CRASH_LOCAL_ID" /> (ಸರà³à²µà²°à³ à²à²¡à²¿: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">ಈ ಕà³à²·à²£à²¦à²²à³à²²à²¿ ನಿಮà³à²® ಪೋಷಕರನà³à²¨à³ ತಲà³à²ªà²²à³ ನಮಗೆ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²². ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="3528171143076753409">ಸರà³à²µà²°à³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ನಂಬಲರà³à²¹à²µà²¾à²—ಿಲà³à²².</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಕನಿಷà³à²  1 à²à²Ÿà²‚}=1{1 à²à²Ÿà²‚ (ಮತà³à²¤à³ ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಇನà³à²¨à²·à³à²Ÿà³ à²à²Ÿà²‚ಗಳà³)}one{# à²à²Ÿà²‚ಗಳೠ(ಮತà³à²¤à³ ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಇನà³à²¨à²·à³à²Ÿà³ à²à²Ÿà²‚ಗಳà³)}other{# à²à²Ÿà²‚ಗಳೠ(ಮತà³à²¤à³ ಸಿಂಕೠಮಾಡಿದ ಸಾಧನಗಳಲà³à²²à²¿ ಇನà³à²¨à²·à³à²Ÿà³ à²à²Ÿà²‚ಗಳà³)}}</translation>
<translation id="3539171420378717834">ಈ ಸಾಧನದಲà³à²²à²¿ ಈ ಕಾರà³à²¡à³â€Œà²¨ ನಕಲನà³à²¨à³ ಇರಿಸಿಕೊಳà³à²³à²¿</translation>
<translation id="3542684924769048008">ಇದಕà³à²•à³† ಪಾಸà³â€Œà²µà²°à³à²¡à³ ಬಳಸಿ:</translation>
+<translation id="3545341443414427877">ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯ <ph name="DATE_AND_TIME" /> ತಪà³à²ªà²¾à²—ಿರà³à²µ ಕಾರಣದಿಂದ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಗೆ ಖಾಸಗಿ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¿à²²à³à²². <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">ನಿಮà³à²® ಸà³à²µà²‚ತ ಸಿಂಕೠಪಾಸà³â€Œà²«à³à²°à³‡à²¸à³â€Œà²¨à³†à³‚ಂದಿಗೆ ಸಿಂಕೠಆದ ಎಲà³à²²à²¾ ಡೇಟಾವನà³à²¨à³ ಎನà³â€Œà²•à³à²°à²¿à²ªà³à²Ÿà³ ಮಾಡಿ</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> ಇನà³à²¨à²·à³à²Ÿà³...</translation>
-<translation id="3555561725129903880">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ <ph name="DOMAIN2" /> ರಿಂದ ಆಗಿರಬಹà³à²¦à³. ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">ನಿಮà³à²® ಮà³à²¯à²¾à²¨à³†à³•à²œà²°à³ ನಿಮಗಾಗಿ ಅದನà³à²¨à³ ಅನಿರà³à²¬à²‚ಧಿಸಬಹà³à²¦à²¾à²—ಿದೆ</translation>
<translation id="3566021033012934673">ನಿಮà³à²® ಸಂಪರà³à²•à²µà³ ಖಾಸಗಿಯಲà³à²²</translation>
+<translation id="3569145463236695319">&lt;p&gt;ನಿಮà³à²® ಸಾಧನದ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯ (<ph name="DATE_AND_TIME" />) ತಪà³à²ªà²¾à²—ಿರà³à²µ ಕಾರಣದಿಂದ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಗೆ ಖಾಸಗಿ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¿à²²à³à²².&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ಸಾಮಾನà³à²¯&lt;/strong&gt; ವಿಭಾಗದ &lt;strong&gt;ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳ&lt;/strong&gt; ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²¨à²¿à²‚ದ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯವನà³à²¨à³ ಹೊಂದಿಸಿ.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">ಹೆಸರೠಸೇರಿಸಿ</translation>
<translation id="3583757800736429874">&amp;ಸರಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
<translation id="3586931643579894722">ವಿವರಗಳನà³à²¨à³ ಮರೆಮಾಡಿ</translation>
-<translation id="3587482841069643663">ಎಲà³à²²</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">ಮಾನà³à²¯à²µà²¾à²¦ ಅವಧಿ-ಮà³à²•à³à²¤à²¾à²¯ ದಿನಾಂಕವನà³à²¨à³ ನಮೂದಿಸಿ</translation>
<translation id="36224234498066874">ಬà³à²°à³Œà²¸à³ ಆಗà³à²¤à³à²¤à²¿à²°à³à²µ ಡೇಟಾವನà³à²¨à³ ತೆರವà³à²—ೊಳಿಸಿ...</translation>
@@ -319,7 +357,6 @@
<translation id="3681007416295224113">ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಮಾಹಿತಿ</translation>
<translation id="3690164694835360974">ಲಾಗಿನೠಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿಲà³à²²</translation>
<translation id="3693415264595406141">ಪಾಸà³â€Œà²µà²°à³à²¡à³:</translation>
-<translation id="3696411085566228381">ಯಾವà³à²¦à³‚ ಇಲà³à²²</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ಲೋಡೠಆಗà³à²¤à³à²¤à²¿à²¦à³†...</translation>
<translation id="3712624925041724820">ಪರವಾನಗಿಗಳೠಬರಿದಾಗಿವೆ</translation>
@@ -327,12 +364,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ಪà³à²°à²¾à²•à³à²¸à²¿, ಫೈರà³â€Œà²µà²¾à²²à³ ಮತà³à²¤à³ DNS ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œâ€Œ ಪರಿಶೀಲಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">ನಿಮà³à²® ಸà³à²°à²•à³à²·à²¤à³† ಅಪಾಯಗಳೠನಿಮಗೆ ಅರà³à²¥à²µà²¾à²—ಿದà³à²¦à²°à³†, ಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à²•à³à²•à³‚ ಮೊದಲೠನೀವೠ<ph name="BEGIN_LINK" />ಈ ಅಸà³à²°à²•à³à²·à²¿à²¤ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ ನೀಡಬಹà³à²¦à³<ph name="END_LINK" />.</translation>
<translation id="3739623965217189342">ನೀವೠನಕಲಿಸಿದ ಲಿಂಕà³</translation>
+<translation id="3744899669254331632">ನೀವೠಇದೀಗ <ph name="SITE" /> ಗೆ ಭೇಟಿ ನೀಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²² à²à²•à³†à²‚ದರೆ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³ Chromium ಗೆ ಪà³à²°à²•à³à²°à²¿à²¯à³†à²—ೊಳಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ದ ಅವà³à²¯à²µà²¸à³à²¥à²¿à²¤ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಕಳà³à²¹à²¿à²¸à²¿à²¦à³†. ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ಆಕà³à²°à²®à²£à²—ಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಆದà³à²¦à²°à²¿à²‚ದ ಈ ಪà³à²Ÿà²µà³ ಬಹà³à²¶à²ƒ ನಂತರ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಲà³à²²à²¿à²¨ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಸಾಫà³à²Ÿà³â€Œà²µà³‡à²°à³ ಸà³à²¥à²¾à²ªà²¿à²¸à³à²µà²¿à²•à³† ಅಥವಾ ನಿಮà³à²® ವೈಯಕà³à²¤à²¿à²• ಮಾಹಿತಿಯನà³à²¨à³ ಬಹಿರಂಗ ಪಡಿಸà³à²µà²‚ತಹ ಅಪಾಯಕಾರಿಯಾಗಿ à²à²¨à²¾à²¦à²°à³‚ ಮಾಡà³à²µà²‚ತಹ ಮೋಸವನà³à²¨à³ ಮಾಡಬಹà³à²¦à³ (ಉದಾಹರಣೆಗೆ, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³, ಫೋನà³â€Œ ಸಂಖà³à²¯à³†à²—ಳೠಅಥವಾ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³â€Œà²—ಳà³). <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">ಸರà³à²µà²°à³ ದೋಷದ ಕಾರಣ ಅನà³à²µà²¾à²¦à²µà³ ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="3759461132968374835">ಇತà³à²¤à³€à²šà³†à²—ೆ ನೀವೠಯಾವà³à²¦à³‡ ಕà³à²°â€à³à²¯à²¾à²¶à³â€Œà²—ಳನà³à²¨à³ ವರದಿ ಮಾಡಿಲà³à²². ಕà³à²°â€à³à²¯à²¾à²¶à³â€Œâ€Œ ಅನà³à²¨à³ ವರದಿಮಾಡà³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ಉಂಟಾಗಿರà³à²µ ಕà³à²°â€à³à²¯à²¾à²¶à³â€Œà²—ಳೠಇಲà³à²²à²¿ ಗೋಚರಿಸà³à²µà³à²¦à²¿à²²à³à²².</translation>
+<translation id="3778403066972421603">ಈ ಕಾರà³à²¡à³â€Œ ಅನà³à²¨à³ ನಿಮà³à²® Google ಖಾತೆ ಮತà³à²¤à³ ಈ ಸಾಧನದಲà³à²²à²¿ ಉಳಿಸಲೠಬಯಸà³à²µà²¿à²°à²¾?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">ಅವಧಿ-ಮà³à²•à³à²¤à²¾à²¯ <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">ನೀವೠಪà³à²°à²¾à²•à³à²¸à²¿ ಸರà³à²µà²°à³ ಬಳಸಿದರೆ...</translation>
<translation id="3828924085048779000">ಖಾಲಿ ಪಾಸà³â€Œà²«à³à²°à³‡à²¸à³ ಅನà³à²¨à³ ಅನà³à²®à²¤à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²².</translation>
-<translation id="3845539888601087042">ನಿಮà³à²® ಸೈನà³-ಇನೠಮಾಡಿದ ಸಾಧನಗಳಿಂದ ಇತಿಹಾಸವನà³à²¨à³ ತೋರಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†. <ph name="BEGIN_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">ಹಿಂದೆ</translation>
<translation id="3858027520442213535">ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯವನà³à²¨à³ ನವೀಕರಿಸಿ</translation>
<translation id="3884278016824448484">ಸಂಘರà³à²·à²—ೊಳà³à²³à³à²¤à³à²¤à²¿à²°à³à²µ ಸಾಧನ ಗà³à²°à³à²¤à²¿à²¸à³à²µà²¿à²•à³†</translation>
@@ -340,11 +380,13 @@
<translation id="3886446263141354045">ಈ ಸೈಟà³â€Œà²—ೆ ಪà³à²°à²µà³‡à²¶à²¿à²¸à³à²µ ನಿಮà³à²® ವಿನಂತಿಯನà³à²¨à³ <ph name="NAME" /> ಅವರಿಗೆ ಕಳà³à²¹à²¿à²¸à²²à²¾à²—ಿದೆ</translation>
<translation id="3890664840433101773">ಇಮೇಲೠಸೇರಿಸಿ</translation>
<translation id="3901925938762663762">ಕಾರà³à²¡à³ ಅವಧಿಯೠಮà³à²—ಿದಿದೆ</translation>
-<translation id="3933571093587347751">{1,plural, =1{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ; ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಬಹà³à²¶à²ƒ ನಾಳೆಯಿಂದ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.}one{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಬಹà³à²¶à²ƒ ಭವಿಷà³à²¯à²¦à²²à³à²²à²¿ # ದಿನಗಳಲà³à²²à²¿ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.}other{ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಬಹà³à²¶à²ƒ ಭವಿಷà³à²¯à²¦à²²à³à²²à²¿ # ದಿನಗಳಲà³à²²à²¿ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF ಡಾಕà³à²¯à³à²®à³†à²‚ಟೠಅನà³à²¨à³ ಲೋಡೠಮಾಡಲೠವಿಫಲವಾಗಿದೆ</translation>
+<translation id="3945915738023014686">ಕà³à²°à³à²¯à²¾à²·à³ ವರದಿ à²à²¡à²¿ <ph name="CRASH_ID" />(ಸà³à²¥à²³à³€à²¯ ಕà³à²°à³à²¯à²¾à²·à³ à²à²¡à²¿: <ph name="CRASH_LOCAL_ID" />) ಅನà³à²¨à³ ಅಪà³â€Œà²²à³‹à²¡à³ ಮಾಡಲಾಗಿದೆ</translation>
+<translation id="3949571496842715403">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£ ಪತà³à²°à²µà³ ವಿಷಯವಸà³à²¤à³ ಪರà³à²¯à²¾à²¯ ಹೆಸರà³à²—ಳನà³à²¨à³ ನಿರà³à²¦à²¿à²·à³à²Ÿà²ªà²¡à²¿à²¸à²¿à²²à³à²². ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
<translation id="3963721102035795474">ರೀಡರà³â€Œ ಮೋಡà³â€Œ</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 ಸೈಟà³â€Œà²¨à²¿à²‚ದ }one{# ಸೈಟà³â€Œà²—ಳಿಂದ }other{# ಸೈಟà³â€Œà²—ಳಿಂದ }}</translation>
<translation id="397105322502079400">ಎಣಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> ಅನà³à²¨à³ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
+<translation id="3987940399970879459">1 MB ಗಿಂತ ಕಡಿಮೆ</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ಹತà³à²¤à²¿à²°à²¦ 1 ವೆಬೠಪà³à²Ÿ}one{ಹತà³à²¤à²¿à²°à²¦ # ವೆಬೠಪà³à²Ÿà²—ಳà³}other{ಹತà³à²¤à²¿à²°à²¦ # ವೆಬೠಪà³à²Ÿà²—ಳà³}}</translation>
<translation id="4021036232240155012">DNS ಎನà³à²¨à³à²µà³à²¦à³ ನೆಟà³â€Œà²µà²°à³à²•à³ ಸೇವೆಯಾಗಿದà³à²¦à³ ಇದೠವೆಬà³â€Œà²¸à³ˆà²Ÿà³ ಹೆಸರನà³à²¨à³ ಅದರ ಇಂಟರà³à²¨à³†à²Ÿà³ ವಿಳಾಸವಾಗಿ ಪರಿವರà³à²¤à²¿à²¸à³à²¤à³à²¤à²¦à³†.</translation>
<translation id="4030383055268325496">&amp;ಸೇರಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸಿ</translation>
@@ -355,56 +397,63 @@
<translation id="4079302484614802869">ಪà³à²°à²¾à²•à³à²¸à²¿ ಕಾನà³à²«à²¿à²—ರೇಶನೠಅನà³à²¨à³ .pac ಸà³à²•à³à²°à²¿à²ªà³à²Ÿà³ URL ಬಳಸà³à²µà²‚ತೆ ಹೊಂದಿಸಲಾಗಿದೆ, ಹೊಂದಿಸಿದ ಪà³à²°à²¾à²•à³à²¸à²¿ ಸರà³à²µà²°à³â€Œà²—ಳಲà³à²².</translation>
<translation id="4098354747657067197">ವಂಚನೆಯ ಸೈಟೠಮà³à²‚ದಿದೆ</translation>
<translation id="4103249731201008433">ಸಾಧನದ ಸರಣಿಯ ಸಂಖà³à²¯à³† ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ</translation>
+<translation id="410351446219883937">ಆಟೋಪà³à²²à³‡</translation>
<translation id="4103763322291513355">ನಿಮà³à²® ಸಿಸà³à²Ÿà²‚ ನಿರà³à²µà²¾à²¹à²•à²°à³ ವಿಧಿಸಿರà³à²µ ಕಪà³à²ªà³à²ªà²Ÿà³à²Ÿà²¿à²¯ URLಗಳೠಮತà³à²¤à³ ಇತರ ನೀತಿಗಳನà³à²¨à³ ವೀಕà³à²·à²¿à²¸à²²à³ &lt;strong&gt;chrome://policy&lt;/strong&gt; ಗೆ ಭೇಟಿ ನೀಡಿ.</translation>
-<translation id="4110615724604346410">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ದೋಷಗಳನà³à²¨à³ ಹೊಂದಿರಬಹà³à²¦à³. ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">ಮಜೆಂತಾ</translation>
+<translation id="4116663294526079822">ಈ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿ ಯಾವಾಗಲೂ ಅನà³à²®à²¤à²¿à²¸à²¿</translation>
<translation id="4117700440116928470">ನೀತಿಯ ವà³à²¯à²¾à²ªà³à²¤à²¿à²¯à³ ಬೆಂಬಲಿತವಾಗಿಲà³à²².</translation>
-<translation id="4118212371799607889">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ Chromium ನಿಂದ ವಿಶà³à²µà²¾à²¸à²¹à³Šà²‚ದಿಲà³à²². ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 ಇತರೆ}one{# ಇತರೆ}other{# ಇತರೆ}}</translation>
<translation id="4130226655945681476">ನೆಟà³â€Œà²µà²°à³à²•à³ ಕೇಬಲà³â€Œà²—ಳà³, ಮೊಡೆಮೠಮತà³à²¤à³ ರೂಟರೠಪರಿಶೀಲಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†</translation>
+<translation id="413544239732274901">ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">ಜಾಗತಿಕ ಡಿಫಾಲà³à²Ÿà³ ಬಳಸಿ (ಪತà³à²¤à³† ಮಾಡಿ)</translation>
+<translation id="4165986682804962316">ಸೈಟೠಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳà³</translation>
<translation id="4169947484918424451">ಈ ಕಾರà³à²¡à³ ಅನà³à²¨à³ Chromium ಉಳಿಸಬೇಕೆಂದೠನೀವೠಬಯಸà³à²µà²¿à²°à²¾?</translation>
<translation id="4171400957073367226">ತಪà³à²ªà³ ಪರಿಶೀಲನೆ ಸಹಿ</translation>
<translation id="4196861286325780578">&amp;ಸರಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ಫೈರà³â€Œà²µà²¾à²²à³ ಮತà³à²¤à³ ಆಂಟಿವೈರಸೠಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œâ€Œà²—ಳನà³à²¨à³ ಪರಿಶೀಲಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œ ($1)}=2{2 ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳೠ($1, $2)}one{# ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳೠ($1, $2, $3)}other{# ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳೠ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">ವಿಫಲತೆಗಳà³</translation>
+<translation id="422022731706691852">ನಿಮà³à²® ಬà³à²°à³Œà²¸à²¿à²‚ಗà³â€Œ ಅನà³à²­à²µà²µà²¨à³à²¨à³ ಹಾನಿಮಾಡಲೠಸà³à²¥à²¾à²ªà²¿à²¸à²²à²¾à²—à³à²µ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳಲà³à²²à²¿ ನಿಮà³à²®à²¨à³à²¨à³ ವಂಚಿಸಲೠಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ಮೇಲೆ ದಾಳಿ ಮಾಡಬಹà³à²¦à³ (ಉದಾಹರಣೆಗೆ, ನಿಮà³à²® ಮà³à²–ಪà³à²Ÿà²µà²¨à³à²¨à³ ಬದಲಾಯಿಸಲಾಗà³à²¤à³à²¤à²¦à³† ಅಥವಾ ನೀವೠಭೇಟಿ ನೀಡà³à²µ ಸೈಟà³â€Œà²—ಳಲà³à²²à²¿ ಹೆಚà³à²šà²¿à²¨ ಜಾಹೀರಾತà³à²—ಳನà³à²¨à³ ತೋರಿಸಲಾಗà³à²¤à³à²¤à²¦à³†). <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />ನೆಟà³â€Œà²µà²°à³à²•à³ ಡಯಾಗà³à²¨à²¾à²¸à³à²Ÿà²¿à²•à³à²¸à³â€Œ ರನೠಮಾಡಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">ಮಾನà³à²¯à²µà²¾à²—ಿದೆ</translation>
<translation id="4250431568374086873">ಈ ಸೈಟà³â€Œà²—ೆ ನಿಮà³à²® ಸಂಪರà³à²•à²µà³ ಸಂಪೂರà³à²£à²µà²¾à²—ಿ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿಲà³à²²</translation>
<translation id="4250680216510889253">ಇಲà³à²²</translation>
<translation id="425582637250725228">ನೀವೠಮಾಡಿದ ಬದಲಾವಣೆಗಳನà³à²¨à³ ಉಳಿಸಲಾಗದೇ ಇರಬಹà³à²¦à³.</translation>
<translation id="4258748452823770588">ತಪà³à²ªà²¾à²¦ ಸಹಿ</translation>
+<translation id="4265872034478892965">ನಿಮà³à²® ನಿರà³à²µà²¾à²¹à²•à²°à²¿à²‚ದ ಅನà³à²®à²¤à²¿à²¸à²²à²¾à²—ಿದೆ</translation>
<translation id="4269787794583293679">(ಯಾವà³à²¦à³ ಬಳಕೆದಾರಹೆಸರಿಲà³à²²)</translation>
<translation id="4275830172053184480">ನಿಮà³à²® ಸಾಧನವನà³à²¨à³ ಮರà³à²ªà³à²°à²¾à²°à²‚ಭಿಸಿ</translation>
<translation id="4280429058323657511">, ಅವಧಿ ಮà³à²•à³à²¤à²¾à²¯ <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à³ ಮಾಡà³à²µà²¿à²•à³† ಇತà³à²¤à³€à²šà³†à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ <ph name="BEGIN_LINK" />ಹಾನಿಕಾರಕ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³†<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">ಪೋಷಕ ಸಲಹೆಗಳà³</translation>
<translation id="4304224509867189079">ಲಾಗೠಇನà³</translation>
-<translation id="432290197980158659">ಅಂತರà³â€Œà²¨à²¿à²°à³à²®à²¿à²¤ ನಿರೀಕà³à²·à³†à²—ಳಿಗೆ ಹೊಂದಿಕೆಯಾಗದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦à³†. ಈ ನಿರೀಕà³à²·à³†à²—ಳೠನಿಮà³à²®à²¨à³à²¨à³ ರಕà³à²·à²¿à²¸à³à²µ ಸಲà³à²µà²¾à²—ಿ ಕೆಲವೠಉನà³à²¨à²¤ ಸà³à²°à²•à³à²·à²¤à²¾ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳನà³à²¨à³ ಒಳಗೊಂಡಿವೆ. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">ನಿರà³à²¬à²‚ಧಿಸೠ(ಡಿಫಾಲà³à²Ÿà³)</translation>
<translation id="4325863107915753736">ಲೇಖನ ಕಂಡà³à²¬à²°à²²à²¿à²²à³à²²</translation>
<translation id="4326324639298822553">ನಿಮà³à²® ಮà³à²•à³à²¤à²¾à²¯ ದಿನಾಂಕವನà³à²¨à³ ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿</translation>
<translation id="4331708818696583467">ಸà³à²°à²•à³à²·à²¿à²¤à²µà²²à³à²²</translation>
<translation id="4356973930735388585">ಈ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ ದಾಳಿಕೋರರೠನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ ಮಾಹಿತಿ (ಉದಾಹರಣೆಗೆ, ಫೋಟೋಗಳà³, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ಮಾಹಿತಿಗಳà³) ಕದಿಯಲೠಇಲà³à²²à²µà³‡ ಅಳಿಸಲೠಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³.</translation>
<translation id="4372948949327679948">ನಿರೀಕà³à²·à²¿à²¤ <ph name="VALUE_TYPE" /> ಮೌಲà³à²¯.</translation>
+<translation id="4377125064752653719">ನೀವೠ<ph name="DOMAIN" /> ಅನà³à²¨à³ ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²¦à²¿à²°à²¿, ಆದರೆ ಸರà³à²µà²°à³ ನೀಡಿದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಅದರ ನೀಡà³à²µà²µà²°à³ ಹಿಂತೆಗೆದà³à²•à³Šà²‚ಡಿದà³à²¦à²¾à²°à³†. ಇದರರà³à²¥ ಸರà³à²µà²°à³ ನೀಡಿದ ಸà³à²°à²•à³à²·à²¤à³† ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಖಂಡಿತವಾಗಿ ನಂಬಲಾಗà³à²µà³à²¦à²¿à²²à³à²². ನೀವೠಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³Šà²‚ದಿಗೆ ಸಂವಹಿಸà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³.</translation>
<translation id="4381091992796011497">ಬಳಕೆದಾರ ಹೆಸರೠ:</translation>
<translation id="4394049700291259645">ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಿ</translation>
<translation id="4406896451731180161">ಹà³à²¡à³à²•à²¾à²Ÿà²¦ ಫಲಿತಾಂಶಗಳà³</translation>
+<translation id="4424024547088906515">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ Chrome ಪಾಲಿಗೆ ವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²—ಿಲà³à²². ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ನಿಮà³à²® ಲಾಗಿನೠಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸà³à²µà³€à²•à²°à²¿à²¸à²²à²¿à²²à³à²² ಅಥವಾ ಅದನà³à²¨à³ ಒದಗಿಸದೆ ಇರಬಹà³à²¦à³.</translation>
<translation id="443673843213245140">ಪà³à²°à²¾à²•à³à²¸à²¿à²¯ ಬಳಕೆಯನà³à²¨à³ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಲಾಗಿದೆ ಆದರೆ ಬಹಿರಂಗ ಪà³à²°à²¾à²•à³à²¸à²¿ ಕಾನà³à²«à²¿à²—ರೇಶನೠಅನà³à²¨à³ ನಿರà³à²¦à²¿à²·à³à²Ÿà²ªà²¡à²¿à²¸à²²à²¾à²—ಿದೆ.</translation>
-<translation id="4492190037599258964"><ph name="SEARCH_STRING" />' ಕà³à²°à²¿à²¤ ಹà³à²¡à³à²•à²¾à²Ÿ ಫಲಿತಾಂಶಗಳà³</translation>
<translation id="4506176782989081258">ಮೌಲà³à²¯à³€à²•à²°à²¿à²¸à³à²µà²¿à²•à³†à²¯ ದೋಷ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">ಸಿಸà³à²Ÿà²‚ ನಿರà³à²µà²¾à²¹à²•à²°à²¨à³à²¨à³ ಸಂಪರà³à²•à²¿à²¸à²²à²¾à²—à³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="450710068430902550">ನಿರà³à²µà²¾à²¹à²•à²°à³Šà²‚ದಿಗೆ ಹಂಚಿಕೊಳà³à²³à³à²µà³à²¦à³</translation>
<translation id="4515275063822566619">ಕಾರà³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ವಿಳಾಸಗಳನà³à²¨à³ ನಿಮà³à²® Chrome ಮತà³à²¤à³ ನಿಮà³à²® Google ಖಾತೆಯಿಂದ (<ph name="ACCOUNT_EMAIL" />) ಪಡೆಯಲಾಗಿದೆ. ನೀವೠಅವà³à²—ಳನà³à²¨à³ <ph name="BEGIN_LINK" />ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳಲà³à²²à²¿<ph name="END_LINK" /> ನಿರà³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
<translation id="4522570452068850558">ವಿವರಗಳà³</translation>
+<translation id="4552089082226364758">ಫà³à²²à³à²¯à²¾à²¶à³â€Œ</translation>
<translation id="4558551763791394412">ನಿಮà³à²® ವಿಸà³à²¤à²°à²£à³†à²—ಳನà³à²¨à³ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="457875822857220463">ವಿತರಣೆ</translation>
<translation id="4587425331216688090">Chrome ನಿಂದ ವಿಳಾಸವನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à³‡?</translation>
-<translation id="4589078953350245614">ನೀವೠ<ph name="DOMAIN" /> ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿, ಆದರೆ ಮಾನà³à²¯à²µà²²à³à²²à²¦ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦à³†. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">ಆಧà³à²¨à²¿à²• ಸೈಫರೠಸೂಟೠಬಳಸà³à²µ ಮೂಲಕ <ph name="DOMAIN" /> ಗೆ ನಿಮà³à²® ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಎನà³â€Œà²•à³à²°à²¿à²ªà³à²Ÿà³ ಮಾಡಲಾಗಿದೆ.</translation>
<translation id="4594403342090139922">&amp;ಅಳಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸಿ</translation>
<translation id="4619615317237390068">ಇತರ ಸಾಧನಗಳಿಂದ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳà³</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²¦à²²à³à²²à²¿ ಸಾಕಷà³à²Ÿà³ ದೋಷಗಳಿವೆ. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
+<translation id="4690462567478992370">ಅಮಾನà³à²¯ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಬಳಸಿಕೊಂಡೠನಿಲà³à²²à²¿à²¸à²¿</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">ನಿಮà³à²® ಸಂಪರà³à²•à²•à³à²•à³† ಅಡà³à²¡à²¿à²¯à²¾à²—ಿದೆ</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows ನೆಟà³â€Œà²µà²°à³à²•à³ ಡಯಾಗà³à²¨à²¾à²¸à³à²Ÿà²¿à²•à³à²¸à³ ರನೠಮಾಡಲಾಗà³à²¤à³à²¤à²¿à²¦à³†<ph name="END_LINK" /></translation>
@@ -421,21 +470,24 @@
<translation id="4771973620359291008">ಅಪರಿಚಿತ ದೋಷವೊಂದೠಎದà³à²°à²¾à²—ಿದೆ.</translation>
<translation id="4800132727771399293">ನಿಮà³à²® ಮà³à²•à³à²¤à²¾à²¯à²¦ ದಿನಾಂಕ ಮತà³à²¤à³ CVC ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">ನಿಮಗೆ ಸದà³à²¯à²•à³à²•à³† <ph name="SITE" /> ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œâ€Œà²—ೆ ಭೇಟಿ ನೀಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². à²à²•à³†à²‚ದರೆ, ಈ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œâ€Œ Google Chrome ಪà³à²°à²•à³à²°à²¿à²¯à³†à²—ೊಳಿಸಲೠಸಾಧà³à²¯à²µà²¾à²—ದಂಥ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ರವಾನಿಸಿದೆ. ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ಆಕà³à²°à²®à²£à²—ಳೠತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†. ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ಬಹà³à²¶à²ƒ ನಂತರ ಕಾರà³à²¯ ನಿರà³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
<translation id="4813512666221746211">ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷ</translation>
<translation id="4816492930507672669">ಪà³à²Ÿà²•à³à²•à³† ಹೊಂದಿಸà³</translation>
<translation id="483020001682031208">ತೋರಿಸಲೠಯಾವà³à²¦à³‡ ಬೌದà³à²§à²¿à²• ವೆಬೠಪà³à²Ÿà²—ಳಿಲà³à²²</translation>
<translation id="4850886885716139402">ವೀಕà³à²·à²£à³†</translation>
<translation id="4854362297993841467">ಈ ವಿತರಣೆಯ ವಿಧಾನ ಲಭà³à²¯à²µà²¿à²²à³à²². ಬೇರೊಂದೠವಿಧಾನವನà³à²¨à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="4858792381671956233">ಈ ಸೈಟೠಅನà³à²¨à³ ಭೇಟಿ ಮಾಡಬಹà³à²¦à³ ಎಂದೠನಿಮà³à²® ಪೋಷಕರಿಗೆ ನೀವೠಕೇಳಿರà³à²µà²¿à²°à²¿.</translation>
+<translation id="4863764087567530506">ಈ ಕಂಟೆಂಟà³â€Œ ಸಾಫà³à²Ÿà³â€Œà²µà³‡à²°à³ ಸà³à²¥à²¾à²ªà²¿à²¸à³à²µà²¿à²•à³† ಅಥವಾ ನಿಮà³à²® ವೈಯಕà³à²¤à²¿à²• ಮಾಹಿತಿಯನà³à²¨à³ ಬಹಿರಂಗ ಪಡಿಸಿ ಮೋಸಗೊಳಿಸಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³. <ph name="BEGIN_LINK" />ಹೇಗಿದà³à²¦à²°à³‚ ತೋರಿಸಿ<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">ಹà³à²¡à³à²•à²¾à²Ÿ ಇತಿಹಾಸ</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ಮತà³à²¤à³ 1 ಹೆಚà³à²šà²¿à²¨ ವೆಬೠಪà³à²Ÿ}one{ಮತà³à²¤à³ # ಹೆಚà³à²šà²¿à²¨ ವೆಬೠಪà³à²Ÿà²—ಳà³}other{ಮತà³à²¤à³ # ಹೆಚà³à²šà²¿à²¨ ವೆಬೠಪà³à²Ÿà²—ಳà³}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">ಗೊತà³à²¤à²¿à²²à³à²²à²¦ ಭಾಷೆಯಿಂದ <ph name="LANGUAGE_LANGUAGE" /> ಗೆ ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ಭಾಷಾಂತರಿಸಲಾಗಿದೆ</translation>
<translation id="4923459931733593730">ಪಾವತಿ</translation>
<translation id="4926049483395192435">ನಿರà³à²¦à²¿à²·à³à²Ÿà²ªà²¡à²¿à²¸à²¬à³‡à²•à²¾à²—ಿದೆ.</translation>
<translation id="495170559598752135">ಕà³à²°à²¿à²¯à³†à²—ಳà³</translation>
<translation id="4958444002117714549">ಪಟà³à²Ÿà²¿à²¯à²¨à³à²¨à³ ವಿಸà³à²¤à²°à²¿à²¸à²¿</translation>
-<translation id="4962322354953122629">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ Chrome ನಿಂದ ವಿಶà³à²µà²¾à²¸à²¹à³Šà²‚ದಿಲà³à²². ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">ಎಚà³à²šà²°à²¿à²•à³†à²—ಳನà³à²¨à³ ಮರà³à²¸à²•à³à²°à²¿à²¯à²—ೊಳಿಸಿ</translation>
<translation id="4989809363548539747">ಈ ಪà³à²²à²—ಿನೠಬೆಂಬಲಿಸà³à²µà³à²¦à²¿à²²à³à²²</translation>
<translation id="5002932099480077015">ಸಕà³à²°à²¿à²¯à²µà²¾à²—ಿದà³à²¦à²°à³†, ವೇಗವಾಗಿ ಫಾರà³à²®à³ ಭರà³à²¤à²¿ ಮಾಡಲೠChrome ಈ ಸಾಧನದಲà³à²²à²¿ ನಿಮà³à²® ಕಾರà³à²¡à³â€Œà²¨ ಪà³à²°à²¤à²¿à²¯à²¨à³à²¨à³ ಸಂಗà³à²°à²¹à²¿à²¸à³à²¤à³à²¤à²¦à³†.</translation>
<translation id="5018422839182700155">ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ತೆರೆಯಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²</translation>
@@ -443,14 +495,15 @@
<translation id="5023310440958281426">ನಿಮà³à²® ನಿರà³à²µà²¾à²¹à²• ನೀತಿಗಳನà³à²¨à³ ಪರಿಶೀಲಿಸಿ</translation>
<translation id="5029568752722684782">ನಕಲೠತೆರವà³à²—ೊಳಿಸà³</translation>
<translation id="5031870354684148875">Google ಅನà³à²µà²¾à²¦à²¦ ಕà³à²°à²¿à²¤à³</translation>
+<translation id="5039804452771397117">ಅನà³à²®à²¤à²¿à²¸à²¿</translation>
<translation id="5040262127954254034">ಗೌಪà³à²¯à²¤à³†</translation>
<translation id="5045550434625856497">ತಪà³à²ªà³ ಪಾಸà³â€Œà²µà²°à³à²¡à³</translation>
<translation id="5056549851600133418">ನಿಮಗಾಗಿ ಲೇಖನಗಳà³</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />ಪà³à²°à²¾à²•à³à²¸à²¿ ವಿಳಾಸವನà³à²¨à³ ಪರಿಶೀಲಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{ಯಾವà³à²¦à³‡ ಕà³à²•à³€à²—ಳಿಲà³à²²}=1{1 ಸೈಟೠಕà³à²•à³€à²—ಳನà³à²¨à³ ಬಳಸà³à²¤à³à²¤à²¦à³†. }one{# ಸೈಟà³â€Œà²—ಳೠಕà³à²•à³€à²—ಳನà³à²¨à³ ಬಳಸà³à²¤à³à²¤à²µà³†. }other{# ಸೈಟà³â€Œà²—ಳೠಕà³à²•à³€à²—ಳನà³à²¨à³ ಬಳಸà³à²¤à³à²¤à²µà³†. }}</translation>
<translation id="5087286274860437796">ಈ ಸಮಯದಲà³à²²à²¿ ಸರà³à²µà²°à³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಮಾನà³à²¯à²µà²¾à²—ಿಲà³à²².</translation>
<translation id="5087580092889165836">ಕಾರà³à²¡à³ ಸೇರಿಸಿ</translation>
<translation id="5089810972385038852">ರಾಜà³à²¯</translation>
+<translation id="5094747076828555589">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ Chromium ಮೂಲಕ ವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²—ಿಲà³à²². ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
<translation id="5095208057601539847">ಪà³à²°à²¾à²‚ತà³à²¯</translation>
<translation id="5115563688576182185">(64-ಬಿಟà³)</translation>
<translation id="5141240743006678641">ನಿಮà³à²® Google ರà³à²œà³à²µà²¾à²¤à³à²—ಳ ಜೊತೆಗೆ ಸಿಂಕೠಮಾಡಿದ ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳನà³à²¨à³ ಎನà³â€Œà²•à³à²°à²¿à²«à³à²Ÿà³ ಮಾಡಿ</translation>
@@ -466,24 +519,24 @@
<translation id="5222812217790122047">ಇಮೇಲೠಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
<translation id="5251803541071282808">ಮೇಘ</translation>
<translation id="5277279256032773186">ಕೆಲಸದಲà³à²²à²¿ Chrome ಬಳಸà³à²¤à³à²¤à²¿à²°à³à²µà²¿à²°à²¾? ತಮà³à²® ಉದà³à²¯à³‹à²—ಿಗಳಿಗಾಗಿ ವà³à²¯à²µà²¹à²¾à²°à²—ಳಲà³à²²à²¿ Chrome ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳೠನಿರà³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ</translation>
+<translation id="5297526204711817721">ಈ ಸೈಟà³â€Œà²—ೆ ನಿಮà³à²® ಸಂಪರà³à²•à²µà³ ಖಾಸಗಿಯಾಗಿಲà³à²². ಯಾವ ಸಮಯದಲà³à²²à²¾à²¦à²°à³‚ VR ಮೋಡà³â€Œâ€Œà²¨à²¿à²‚ದ ನಿರà³à²—ಮಿಸಲà³, ಹೆಡà³â€Œà²¸à³†à²Ÿà³ ತೆಗೆದà³à²¹à²¾à²•à²¿ ಮತà³à²¤à³ ಹಿಂದೆ ಒತà³à²¤à²¿à²°à²¿.</translation>
<translation id="5299298092464848405">ನೀತಿಯ ಪಾರà³à²¸à²¿à²‚ಗà³â€Œà²¨à²²à³à²²à²¿ ದೋಷ</translation>
-<translation id="5300589172476337783">ಪà³à²°à²¦à²°à³à²¶à²¿à²¸à²¿</translation>
<translation id="5308689395849655368">ಕà³à²°â€à³à²¯à²¾à²¶à³â€Œâ€Œ ವರದಿಯನà³à²¨à³ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಲಾಗಿದೆ.</translation>
<translation id="5317780077021120954">ಉಳಿಸà³</translation>
<translation id="5327248766486351172">ಹೆಸರà³</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಲà³à²²à²¿à²¨ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಸಾಫà³à²Ÿà³â€Œà²µà³‡à²°à³ ಸà³à²¥à²¾à²ªà²¿à²¸à³à²µà²¿à²•à³† ಅಥವಾ ನಿಮà³à²® ವೈಯಕà³à²¤à²¿à²• ಮಾಹಿತಿಯನà³à²¨à³ ಬಹಿರಂಗ ಪಡಿಸà³à²µà²‚ತಹ ಅಪಾಯಕಾರಿಯಾಗಿ à²à²¨à²¾à²¦à²°à³‚ ಮಾಡà³à²µà²‚ತಹ ಮೋಸವನà³à²¨à³ ಮಾಡಬಹà³à²¦à³ (ಉದಾಹರಣೆಗೆ, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³, ಫೋನà³â€Œ ಸಂಖà³à²¯à³†à²—ಳà³, ಅಥವಾ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³â€Œà²—ಳà³).</translation>
-<translation id="5359637492792381994">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ಈ ಸಮಯದಲà³à²²à²¿ ಮಾನà³à²¯à²µà²¾à²—ಿಲà³à²². ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">ಸದà³à²¯à²•à³à²•à³† ನೀವೠ<ph name="SITE" /> ಗೆ ಭೇಟಿ ನೀಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². à²à²•à³†à²‚ದರೆ ಇದರ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಹಿಂಪಡೆದà³à²•à³Šà²³à³à²³à²²à²¾à²—ಿದೆ. ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ಆಕà³à²°à²®à²£à²—ಳೠತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ಸà³à²µà²²à³à²ª ಸಮಯದ ನಂತರ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
<translation id="536296301121032821">ನೀತಿಯ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳನà³à²¨à³ ಸಂಗà³à²°à²¹à²¿à²¸à³à²µà²²à³à²²à²¿ ವಿಫಲವಾಗಿದೆ</translation>
<translation id="5386426401304769735">ಈ ಸೈಟà³â€Œà²—ೆ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಸರಣಿಯೠSHA-1 ಬಳಸಿಕೊಂಡೠಸಹಿ ಮಾಡಲಾದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಒಳಗೊಂಡಿರà³à²¤à³à²¤à²¦à³†.</translation>
<translation id="5402410679244714488">ಅವಧಿ ಮೀರà³à²µ ಸಮಯ: <ph name="EXPIRATION_DATE_ABBR" />, ಕೊನೆಯದಾಗಿ ಸà³à²®à²¾à²°à³ ಒಂದೠವರà³à²·à²¦ ಹಿಂದೆ ಬಳಸಲಾಗಿದೆ</translation>
+<translation id="540969355065856584">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಈ ಸಮಯದಲà³à²²à²¿ ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ಮಾನà³à²¯à²µà²¾à²—ಿಲà³à²². ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
<translation id="5421136146218899937">ಬà³à²°à³Œà²¸à²¿à²‚ಗೠಡೇಟಾವನà³à²¨à³ ತೆರವà³à²—ೊಳಿಸಿ...</translation>
<translation id="5430298929874300616">ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œ ತೆಗೆದà³à²¹à²¾à²•à²¿</translation>
<translation id="5431657950005405462">ನಿಮà³à²® ಫೈಲೠಕಂಡà³à²¬à²‚ದಿಲà³à²²</translation>
-<translation id="5435775191620395718">ಈ ಸಾಧನದಿಂದ ಇತಿಹಾಸವನà³à²¨à³ ತೋರಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†. <ph name="BEGIN_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" ನಲà³à²²à²¿ ಸà³à²•à³€à²®à²¾ ಮೌಲà³à²µà³€à²•à²°à²£ ದೋಷ: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">ಈ <ph name="HOST_NAME" /> ಪà³à²Ÿ ಕಂಡà³à²¬à²°à³à²µà³à²¦à²¿à²²à³à²²</translation>
<translation id="5455374756549232013">ತಪà³à²ªà²¾à²¦ ನೀತಿಯ ಸಮಯಸà³à²Ÿà³à²¯à²¾à²‚ಪà³</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" /> ರಲà³à²²à²¿ <ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">ಅಮಾನà³à²¯</translation>
<translation id="5470861586879999274">&amp;ಸಂಪಾದಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
<translation id="54817484435770891">ಮಾನà³à²¯à²µà²¾à²¦ ವಿಳಾಸ ಸೇರಿಸಿ</translation>
<translation id="5492298309214877701">ಬಾಹà³à²¯ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œâ€Œà²¨ URL ಅನà³à²¨à³‡ ಕಂಪನಿ, ಸಂಸà³à²¥à³† ಅಥವಾ ಶಾಲೆಯ ಇಂಟà³à²°à²¾à²¨à³†à²Ÿà³â€Œà²¨à²²à³à²²à²¿à²¨ ಈ ಸೈಟೠಹೊಂದಿದೆ.
@@ -500,6 +553,8 @@
<translation id="5571083550517324815">ಈ ವಿಳಾಸದಿಂದ ಪಿಕಪೠಮಾಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². ಬೇರೊಂದೠವಿಳಾಸವನà³à²¨à³ ಆಯà³à²•à³† ಮಾಡಿ.</translation>
<translation id="5572851009514199876">ದಯವಿಟà³à²Ÿà³ Chrome ಪà³à²°à²¾à²°à²‚ಭಿಸಿ ಮತà³à²¤à³ ಸೈನೠಇನೠಮಾಡಿ ಈ ಮೂಲಕ ಈ ಸೈಟà³â€Œà²—ೆ ಪà³à²°à²µà³‡à²¶à²¿à²¸à²²à³ ನಿಮಗೆ ಅನà³à²®à²¤à²¿à²¸à²²à²¾à²—ಿದೆಯೇ ಎಂಬà³à²¦à²¨à³à²¨à³ Chrome ಪರಿಶೀಲಿಸಬಹà³à²¦à³.</translation>
<translation id="5580958916614886209">ನಿಮà³à²® ಮà³à²•à³à²¤à²¾à²¯ ತಿಂಗಳನà³à²¨à³ ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿</translation>
+<translation id="5586446728396275693">ಯಾವà³à²¦à³‡ ಉಳಿಸಲಾದ ವಿಳಾಸಗಳಿಲà³à²²</translation>
+<translation id="5595485650161345191">ವಿಳಾಸ ಎಡಿಟೠಮಾಡಿ</translation>
<translation id="560412284261940334">ನಿರà³à²µà²¾à²¹à²• ಬೆಂಬಲಿಸà³à²µà³à²¦à²¿à²²à³à²²</translation>
<translation id="5610142619324316209">ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಪರಿಶೀಲಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="5610807607761827392">ನೀವೠಕಾರà³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ವಿಳಾಸಗಳನà³à²¨à³ <ph name="BEGIN_LINK" />ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳಲà³à²²à²¿<ph name="END_LINK" /> ನಿರà³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
@@ -507,15 +562,18 @@
<translation id="5622887735448669177">ನೀವೠಈ ಸೈಟೠತೊರೆಯಲೠಬಯಸà³à²¤à³à²¤à³€à²°à²¾?</translation>
<translation id="5629630648637658800">ನೀತಿಯ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳನà³à²¨à³ ಲೋಡೠಮಾಡà³à²µà²²à³à²²à²¿ ವಿಫಲವಾಗಿದೆ</translation>
<translation id="5631439013527180824">ಅಮಾನà³à²¯à²µà²¾à²¦ ಸಾಧನ ನಿರà³à²µà²¹à²£à³† ಟೋಕನà³</translation>
+<translation id="5633066919399395251"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನ ದಾಳಿಕೋರರೠನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨à²²à³à²²à²¿ ಮಾಹಿತಿಯನà³à²¨à³ (ಉದಾಹರಣೆಗೆ, ಫೋಟೋಗಳà³, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ಮಾಹಿತಿಗಳà³) ಕದಿಯಲೠಇಲà³à²²à²µà³‡ ಅಳಿಸಲೠಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">ಸà³à²¥à²³</translation>
+<translation id="5659593005791499971">ಇಮೇಲà³</translation>
<translation id="5669703222995421982">ವೈಯಕà³à²¤à³€à²•à²°à²¿à²¸à²²à²¾à²¦ ವಿಷಯವನà³à²¨à³ ಪಡೆಯಿರಿ</translation>
<translation id="5675650730144413517">ಈ ಪà³à²Ÿ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à³à²¤à³à²¤à²¿à²²à³à²²</translation>
-<translation id="5677928146339483299">ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
-<translation id="5694783966845939798">ನೀವೠ<ph name="DOMAIN" /> ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿, ಆದರೆ ದà³à²°à³à²¬à²² ಸಹಿ ಅಲà³à²—ಾರಿದಮೠಬಳಸಿಕೊಂಡೠಸಹಿ ಮಾಡಿದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦à³† (SHA-1 ನಂತೆಯೇ). ಇದರರà³à²¥ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦ ಸà³à²°à²•à³à²·à²¤à²¾ ರà³à²œà³à²µà²¾à²¤à³à²—ಳೠನಕಲಿ ಆಗಿರಬಹà³à²¦à³ ಮತà³à²¤à³ ನೀವೠನಿರೀಕà³à²·à²¿à²¸à²¿à²¦ ಸರà³à²µà²°à³ ಅದಾಗಿರದೇ ಇರಬಹà³à²¦à³ (ನೀವೠಆಕà³à²°à²®à²£à²•à²¾à²°à²° ಜೊತೆಗೆ ಸಂವಹನ ಮಾಡà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³). <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">ಈ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²¨ ಗà³à²°à³à²¤à²¿à²¸à³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ಇನà³à²¨à³‚ ಪರಿಶೀಲಿಸಲಾಗಿಲà³à²².</translation>
+<translation id="5713016350996637505">ವಂಚನೀಯ ವಿಷಯವನà³à²¨à³ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="5720705177508910913">ಪà³à²°à²¸à³à²¤à³à²¤ ಬಳಕೆದಾರ</translation>
<translation id="5732392974455271431">ನಿಮà³à²® ಪೋಷಕರೠನಿಮಗಾಗಿ ಅದನà³à²¨à³ ಅನಿರà³à²¬à²‚ಧಿಸಬಹà³à²¦à²¾à²—ಿದೆ</translation>
<translation id="5763042198335101085">ಮಾನà³à²¯à²µà²¾à²¦ ಇಮೇಲೠವಿಳಾಸವನà³à²¨à³ ನಮೂದಿಸಿ</translation>
<translation id="5765072501007116331">ವಿತರಣೆಯ ವಿಧಾನಗಳೠಹಾಗೂ ಆವಶà³à²¯à²•à²¤à³†à²—ಳನà³à²¨à³ ನೋಡಲà³, ಒಂದೠವಿಳಾಸವನà³à²¨à³ ಆಯà³à²•à³† ಮಾಡಿ</translation>
+<translation id="5778550464785688721">MIDI ಸಾಧನಗಳೠಸಂಪೂರà³à²£ ನಿಯಂತà³à²°à²£</translation>
<translation id="5784606427469807560">ನಿಮà³à²® ಕಾರà³à²¡à³ ಅನà³à²¨à³ ದೃಢೀಕರಿಸà³à²µà²²à³à²²à²¿ ಸಮಸà³à²¯à³† ಇದೆ. ನಿಮà³à²® ಇಂಟರà³à²¨à³†à²Ÿà³ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="5785756445106461925">ಅಲà³à²²à²¦à³‡, ಸà³à²°à²•à³à²·à²¿à²¤à²µà²²à³à²²à²¦ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಈ ಪà³à²Ÿ ಒಳಗೊಂಡಿದೆ. ಪà³à²°à²¯à²¾à²£à²¦ ಸಂದರà³à²­à²¦à²²à³à²²à²¿ ಈ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಇತರರೂ ವೀಕà³à²·à²¿à²¸à²¬à²¹à³à²¦à²¾à²—ಿದೆ ಮತà³à²¤à³ ಪà³à²Ÿà²¦ ನೋಟವೇ ಬದಲಾಗà³à²µà²‚ತೆ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಅದನà³à²¨à³ ತಿದà³à²¦à²¬à²¹à³à²¦à²¾à²—ಿದೆ.</translation>
<translation id="5786044859038896871">ನಿಮà³à²® ಕಾರà³à²¡à³ ಮಾಹಿತಿ ಭರà³à²¤à²¿ ಮಾಡಲೠನೀವೠಬಯಸà³à²µà²¿à²°à²¾?</translation>
@@ -524,14 +582,14 @@
<translation id="5813119285467412249">&amp;ಸೇರಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
<translation id="5814352347845180253"><ph name="SITE" /> ಮತà³à²¤à³ ಕೆಲವೠಇತರ ಸೈಟà³â€Œà²—ಳಿಂದ ಪà³à²°à³€à²®à²¿à²¯à²‚ ವಿಷಯಕà³à²•à³† ಪà³à²°à²µà³‡à²¶à²µà²¨à³à²¨à³ ನೀವೠಕಳೆದà³à²•à³Šà²³à³à²³à²¬à²¹à³à²¦à³.</translation>
<translation id="5838278095973806738">ಈ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿ ನೀವೠಯಾವà³à²¦à³‡ ಸೂಕà³à²·à³à²® ಮಾಹಿತಿಯನà³à²¨à³ (ಉದಾಹರಣೆಗೆ, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠಅಥವಾ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³â€Œà²—ಳà³) ನಮೂದಿಸಬಾರದà³, à²à²•à³†à²‚ದರೆ ಅದೠದಾಳಿಕೋರರ ಮೂಲಕ ಕಳà³à²µà²¾à²—ಬಹà³à²¦à³.</translation>
-<translation id="5843436854350372569">ನೀವೠ<ph name="DOMAIN" /> ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿, ಆದರೆ ದà³à²°à³à²¬à²² ಕೀಯನà³à²¨à³ ಹೊಂದಿರà³à²µ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦à³†. ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಖಾಸಗಿ ಕೀಯನà³à²¨à³ ನಾಶ ಪಡಿಸಿರಬಹà³à²¦à³ ಮತà³à²¤à³ ನೀವೠನಿರೀಕà³à²·à²¿à²¸à²¿à²¦ ಸರà³à²µà²°à³ ಅದಾಗಿರದೇ ಇರಬಹà³à²¦à³ (ನೀವೠಆಕà³à²°à²®à²£à²•à²¾à²°à²° ಜೊತೆಗೆ ಸಂವಹನ ಮಾಡà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³). <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">ಈ ಸೈಟೠತಲà³à²ªà²²à²¾à²—à³à²µà³à²¦à²¿à²²à³à²²</translation>
<translation id="5869522115854928033">ಉಳಿಸಲಾದ ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³</translation>
<translation id="5872918882028971132">ಪೋಷಕ ಸಲಹೆಗಳà³</translation>
<translation id="5901630391730855834">ಹಳದಿ</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (ಸಿಂಕà³â€Œ ಮಾಡಲಾಗಿದೆ)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 ಬಳಕೆಯಲà³à²²à²¿à²¦à³†}one{# ಬಳಕೆಯಲà³à²²à²¿à²¦à³†}other{# ಬಳಕೆಯಲà³à²²à²¿à²¦à³†}}</translation>
<translation id="5926846154125914413">ಕೆಲವೠಸೈಟà³â€Œà²—ಳ ಪà³à²°à³€à²®à²¿à²¯à²‚ ವಿಷಯಕà³à²•à³† ಪà³à²°à²µà³‡à²¶à²µà²¨à³à²¨à³ ನೀವೠಕಳೆದà³à²•à³Šà²³à³à²³à²¬à²¹à³à²¦à³.</translation>
<translation id="5959728338436674663">ಅಪಾಯಕಾರಿ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳೠಮತà³à²¤à³ ಸೈಟà³â€Œà²—ಳ ಪತà³à²¤à³†à²—ೆ ಸಹಾಯ ಮಾಡಲೠGoogle ಗೆ ಕೆಲವೠ<ph name="BEGIN_WHITEPAPER_LINK" />ಸಿಸà³à²Ÿà²‚ ಮಾಹಿತಿ ಮತà³à²¤à³ ಪà³à²Ÿ ವಿಷಯ<ph name="END_WHITEPAPER_LINK" />ವನà³à²¨à³ ಸà³à²µà²¯à²‚ಚಾಲಿತವಾಗಿ ಕಳà³à²¹à²¿à²¸à²¿. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">ವಾರ</translation>
<translation id="5967867314010545767">ಇತಿಹಾಸದಿಂದ ತೆಗೆದà³à²¹à²¾à²•à²¿</translation>
<translation id="5975083100439434680">à²à³‚ಮೠಔಟà³</translation>
<translation id="598637245381783098">ಪಾವತಿ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³ ತೆರೆಯಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²</translation>
@@ -540,20 +598,28 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{ಪà³à²Ÿ 1}one{ಪà³à²Ÿ #}other{ಪà³à²Ÿ #}}</translation>
<translation id="6017514345406065928">ಹಸಿರà³</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಲà³à²²à²¿à²¨ ದಾಳಿಕೋರರೠವಂಚನೆಯ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²¿, ನಿಮà³à²®à²¨à³à²¨à³ ಟà³à²°à³à²¯à²¾à²•à³ ಮಾಡಲೠಬಳಸಬಹà³à²¦à²¾à²¦ ಬೇರೆ ಯಾವà³à²¦à²¾à²¦à²°à³‚ ಮಾಹಿತಿ ಅಥವಾ ಡೇಟಾ ಸಂಗà³à²°à²¹à²¿à²¸à³à²µ ಸಾಧà³à²¯à²µà²¿à²¦à³†. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (ಸಿಂಕà³â€Œ ಮಾಡಲಾಗಿದೆ)</translation>
<translation id="6027201098523975773">ಹೆಸರೠನಮೂದಿಸಿ</translation>
<translation id="6040143037577758943">ಮà³à²šà³à²šà²¿à²°à²¿</translation>
<translation id="6042308850641462728">ಇನà³à²¨à²·à³à²Ÿà³</translation>
+<translation id="6047233362582046994">ನಿಮà³à²® ಸà³à²°à²•à³à²·à²¤à³† ಅಪಾಯಗಳೠನಿಮಗೆ ಅರà³à²¥à²µà²¾à²—ಿದà³à²¦à²°à³†, ಅಪಾಯಕಾರಿ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à²•à³à²•à³‚ ಮೊದಲೠನೀವೠ<ph name="BEGIN_LINK" />ಈ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ<ph name="END_LINK" /> ನೀಡಬಹà³à²¦à³.</translation>
+<translation id="6051221802930200923">ನೀವೠಸದà³à²¯à²•à³à²•à³† <ph name="SITE" /> ಗೆ ಭೇಟಿ ನೀಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². à²à²•à³†à²‚ದರೆ, ವೆಬà³â€Œà²¸à³ˆà²Ÿà³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಪಿನೠಮಾಡà³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ಬಳಸà³à²¤à³à²¤à²¦à³†. ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ಆಕà³à²°à²®à²£à²—ಳೠತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ಸà³à²µà²²à³à²ª ಸಮಯದ ನಂತರ ಕಾರà³à²¯ ನಿರà³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³.</translation>
<translation id="6060685159320643512">ಜಾಗà³à²°à²¤à³†, ಈ ಪà³à²°à²¯à³‹à²—ಗಳೠವಿಫಲವಾಗಬಹà³à²¦à³</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">ನಿರà³à²µà²¾à²¹à²•à²°à³-ಒದಗಿಸಿದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಬಳಸಿಕೊಂಡೠನೀವೠವಿಷಯವನà³à²¨à³ ಪà³à²°à²µà³‡à²¶à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿. <ph name="DOMAIN" /> ಗೆ ನೀವೠಒದಗಿಸà³à²µ ಡೇಟಾವನà³à²¨à³ ನಿಮà³à²® ನಿರà³à²µà²¾à²¹à²•à²°à³ ತಡೆಹಿಡಿಯಬಹà³à²¦à²¾à²—ಿದೆ.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 ಪಾಸà³â€Œà²µà²°à³à²¡à³ (ಸಿಂಕೠಮಾಡಲಾಗಿದೆ)}one{# ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠ(ಸಿಂಕೠಮಾಡಲಾಗಿದೆ)}other{# ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠ(ಸಿಂಕೠಮಾಡಲಾಗಿದೆ)}}</translation>
<translation id="6146055958333702838">ಯಾವà³à²¦à³‡ ಕೇಬಲà³â€Œà²—ಳನà³à²¨à³ ಪರಿಶೀಲಿಸಿ. ನೀವೠಬಳಸà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à²¾à²¦ ಯಾವà³à²¦à³‡ ರೂಟರà³â€Œà²—ಳà³, ಮೋಡೆಮà³â€Œà²—ಳೠಅಥವಾ ಇತರ ನೆಟà³â€Œà²µà²°à³à²•à³ ಸಾಧನಗಳನà³à²¨à³ ರೀಬೂಟೠಮಾಡಿ.</translation>
<translation id="614940544461990577">ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿:</translation>
<translation id="6151417162996330722">ಸರà³à²µà²°à³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ತà³à²‚ಬಾ ಉದà³à²¦à²µà²¾à²¦ ವಾಯಿದೆ ಅವಧಿಯನà³à²¨à³ ಹೊಂದಿದೆ.</translation>
<translation id="6157877588268064908">ಶಿಪà³à²ªà²¿à²‚ಗೠವಿಧಾನಗಳೠಹಾಗೂ ಆವಶà³à²¯à²•à²¤à³†à²—ಳನà³à²¨à³ ನೋಡಲà³, ಒಂದೠವಿಳಾಸವನà³à²¨à³ ಆಯà³à²•à³† ಮಾಡಿ</translation>
+<translation id="6158003235852588289">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à²¿à²‚ಗೠಇತà³à²¤à³€à²šà³†à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ ಫಿಶಿಂಗೠಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³†. ಫಿಶಿಂಗೠಸೈಟà³â€Œà²—ಳೠನಿಮà³à²®à²¨à³à²¨à³ ಮೋಸಗೊಳಿಸಲೠಇತರ ಸೈಟà³â€Œà²—ಳಂತೆ ನಟಿಸà³à²¤à³à²¤à²µà³†.</translation>
<translation id="6165508094623778733">ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ</translation>
+<translation id="6169916984152623906">ನೀವೀಗ ಖಾಸಗಿಯಾಗಿ ಬà³à²°à³Œà²¸à³ ಮಾಡಬಹà³à²¦à³. ಈ ಸಾಧನವನà³à²¨à³ ಬಳಸà³à²µ ಬೇರೆ ಯಾರಿಗೂ ನಿಮà³à²® ಚಟà³à²µà²Ÿà²¿à²•à³† ಕಾಣಿಸà³à²µà³à²¦à²¿à²²à³à²². ಆದರೂ, ಡೌನà³â€Œà²²à³‹à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳೠಉಳಿದಿರà³à²¤à³à²¤à²µà³†.</translation>
<translation id="6177128806592000436">ಈ ಸೈಟà³â€Œà²—ೆ ನಿಮà³à²® ಸಂಪರà³à²•à²µà³ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿಲà³à²²</translation>
<translation id="6184817833369986695">(ಸಂಘ: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">ನಿಮà³à²® ಇಂಟರà³à²¨à³†à²Ÿà³ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಪರಿಶೀಲಿಸಿ</translation>
<translation id="6218753634732582820">Chromium ನಿಂದ ವಿಳಾಸವನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à³‡?</translation>
+<translation id="6221345481584921695">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à²¿à²‚ಗೠಇತà³à²¤à³€à²šà³†à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ <ph name="BEGIN_LINK" />ಮಾಲà³â€Œà²µà³‡à²°à³ ಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³†<ph name="END_LINK" />. ಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿರà³à²µ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳೠಕೆಲವೊಮà³à²®à³† ಮಾಲà³â€Œà²µà³‡à²°à³ ಸೋಂಕಿಗೆ ತà³à²¤à³à²¤à²¾à²—ಿರà³à²¤à³à²¤à²µà³†. ದà³à²°à³à²¦à³à²¦à³‡à²¶à²ªà³‚ರಿತ ಸಂಗತಿಗಳೠಮಾಲà³â€Œà²µà³‡à²°à³ ವಿತರಕರಾದ <ph name="SUBRESOURCE_HOST" /> ರಿಂದ ಬರà³à²¤à³à²¤à²µà³†.</translation>
<translation id="6251924700383757765">ಗೌಪà³à²¯à²¤à²¾ ನೀತಿ</translation>
<translation id="6254436959401408446">ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ ತೆರೆಯಲೠಸಾಕಷà³à²Ÿà³ ಮೆಮೊರಿ ಇಲà³à²²</translation>
<translation id="625755898061068298">ಈ ಸೈಟà³â€Œà²—ೆ ನೀವೠಸà³à²°à²•à³à²·à²¤à³† ಎಚà³à²šà²°à²¿à²•à³†à²—ಳನà³à²¨à³ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಲೠಆಯà³à²•à³† ಮಾಡಿರà³à²µà²¿à²°à²¿.</translation>
@@ -579,15 +645,14 @@
<translation id="6404511346730675251">ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳನà³à²¨à³ ಎಡಿಟೠಮಾಡಿ</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> ಗೆ ಮà³à²•à³à²¤à²¾à²¯ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಿವಿಸಿ ಅನà³à²¨à³ ನಮೂದಿಸಿ</translation>
<translation id="6414888972213066896">ಈ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ ನೀಡà³à²µà³à²¦à³ ಸರಿಯೇ ಎಂದೠನೀವೠನಿಮà³à²® ಪೋಷಕರನà³à²¨à³ ಕೇಳಿರà³à²µà²¿à²°à²¿</translation>
-<translation id="6416403317709441254">Chromium ಪà³à²°à²•à³à²°à²¿à²¯à³†à²—ೊಳಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²²à²¦ ಅವà³à²¯à²µà²¸à³à²¥à²¿à²¤ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³ ಕಳà³à²¹à²¿à²¸à²¿à²¦ ಕಾರಣ ಇದೀಗ ನೀವೠ<ph name="SITE" /> ಭೇಟಿ ಮಾಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ದಾಳಿಗಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ನಂತರ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಹಿಂತೆಗೆದà³à²•à³Šà²³à³à²³à²²à²¾à²—ಿದೆಯೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಪರಿಶೀಲಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²².</translation>
<translation id="6433490469411711332">ಸಂಪರà³à²• ಮಾಹಿತಿ ಎಡಿಟೠಮಾಡಿ</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ಸಂಪರà³à²•à²—ೊಳà³à²³à²²à³ ನಿರಾಕರಿಸಿದೆ.</translation>
<translation id="6446608382365791566">ಇನà³à²¨à²·à³à²Ÿà³ ಮಾಹಿತಿಯನà³à²¨à³ ಸೇರಿಸಿ</translation>
+<translation id="6447842834002726250">ಕà³à²•à³€à²¸à³</translation>
<translation id="6451458296329894277">ಮರà³à²¸à²²à³à²²à²¿à²•à³† ಫಾರà³à²®à³ ಅನà³à²¨à³ ಖಚಿತಪಡಿಸಿಕೊಳà³à²³à²¿</translation>
<translation id="6456339708790392414">ನಿಮà³à²® ಪಾವತಿ</translation>
<translation id="6458467102616083041">ಡಿಫಾಲà³à²Ÿà³ ಹà³à²¡à³à²•à²¾à²Ÿà²µà²¨à³à²¨à³ ನೀತಿಯಿಂದ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಲಾಗಿರà³à²µà³à²¦à²°à²¿à²‚ದ ನಿರà³à²²à²•à³à²·à²¿à²¸à²²à²¾à²—ಿದೆ.</translation>
-<translation id="6462969404041126431">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಹಿಂಪಡೆದà³à²•à³Šà²‚ಡಿರಬಹà³à²¦à³. ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">ಸಾಧನ ನೀತಿಗಳà³</translation>
<translation id="6477321094435799029">ಈ ಪà³à²Ÿà²¦à²²à³à²²à²¿ ಅಸಹಜ ಕೋಡೠಅನà³à²¨à³ Chrome ಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³† ಮತà³à²¤à³ ನಿಮà³à²® ವೈಯಕà³à²¤à²¿à²• ಮಾಹಿತಿಯನà³à²¨à³ (ಉದಾಹರಣೆಗೆ, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³, ಫೋನà³â€Œ ಸಂಖà³à²¯à³†à²—ಳೠಮತà³à²¤à³ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³â€Œà²—ಳà³) ರಕà³à²·à²¿à²¸à²²à³ ಅದನà³à²¨à³ ನಿರà³à²¬à²‚ಧಿಸಿದೆ.</translation>
<translation id="6489534406876378309">ವಿಫಲತೆಗಳನà³à²¨à³ ಅಪà³â€Œà²²à³‹à²¡à³â€Œ ಮಾಡà³à²µà³à²¦à²¨à³à²¨à³ ಪà³à²°à²¾à²°à²‚ಭಿಸà³</translation>
@@ -599,20 +664,19 @@
<translation id="6556915248009097796">ಅವಧಿ ಮೀರà³à²µ ಸಮಯ: <ph name="EXPIRATION_DATE_ABBR" />, <ph name="LAST_USED_DATE_NO_DETAIL" /> ಅಂತಿಮವಾಗಿ ಬಳಸಲಾಗಿದೆ</translation>
<translation id="6563469144985748109">ನಿಮà³à²® ಮà³à²¯à²¾à²¨à³†à³•à²œà²°à³ ಇನà³à²¨à³‚ ಇದನà³à²¨à³ ಅಂಗೀಕರಿಸಿಲà³à²²</translation>
<translation id="6569060085658103619">ನೀವೠವಿಸà³à²¤à²°à²£à³† ಪà³à²Ÿà²µà²¨à³à²¨à³ ವೀಕà³à²·à²¿à²¸à³à²¤à³à²¤à²¿à²°à³à²µà²¿à²°à²¿</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> ಗಿಂತ ಕಡಿಮೆ</translation>
+<translation id="657639383826808334">ಈ ಕಂಟೆಂಟà³â€Œ ನಿಮà³à²® ಸಾಧನದಲà³à²²à²¿à²°à³à²µ ಮಾಹಿತಿಯನà³à²¨à³ ಕದಿಯಲೠಇಲà³à²²à²µà³‡ ಅಳಿಸಲೠಅಪಾಯಕಾರಿ ಸಾಫà³à²Ÿà³â€Œà²µà³‡à²°à³â€Œà²—ಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³. <ph name="BEGIN_LINK" />ಹೇಗಿದà³à²¦à²°à³‚ ತೋರಿಸಿ<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">ಎನà³â€Œà²•à³à²°à²¿à²«à³à²¶à²¨à³ ಆಯà³à²•à³†à²—ಳà³</translation>
<translation id="662080504995468778">ಉಳಿಯಿರಿ</translation>
<translation id="6626291197371920147">ಮಾನà³à²¯à²µà²¾à²¦ ಕಾರà³à²¡à³ ಸಂಖà³à²¯à³†à²¯à²¨à³à²¨à³ ಸೇರಿಸಿ</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> ಹà³à²¡à³à²•à²¾à²Ÿ</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನ ದಾಳಿಕೋರರೠನಿಮà³à²® Macನಲà³à²²à²¿ ಮಾಹಿತಿಯನà³à²¨à³ (ಉದಾಹರಣೆಗೆ, ಫೋಟೋಗಳà³, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³, ಸಂದೇಶಗಳೠಮತà³à²¤à³ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ಮಾಹಿತಿಗಳà³) ಕದಿಯಲೠಇಲà³à²²à²µà³‡ ಅಳಿಸಲೠಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">ಈ ನೀತಿಯನà³à²¨à³ ವಿನಂತಿಸಲಾಗಿದೆ.</translation>
-<translation id="6652240803263749613">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ಆಪರೇಟಿಂಗೠಸಿಸà³à²Ÿà²‚ನಿಂದ ವಿಶà³à²µà²¾à²¸à²¹à³Šà²‚ದಿಲà³à²². ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Chromium ನಿಂದ ಫಾರà³à²®à³ ಸಲಹೆಯನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à³‡?</translation>
<translation id="6685834062052613830">ಸೈನà³â€Œ ಔಟà³â€Œ ಮಾಡಿ ಹಾಗೂ ಸೆಟಪೠಪೂರà³à²£à²—ೊಳಿಸಿ</translation>
<translation id="6710213216561001401">ಹಿಂದೆ</translation>
<translation id="6710594484020273272">&lt;ಹà³à²¡à³à²•à²¾à²Ÿà²¦ ಪದ ಟೈಪೠಮಾಡಿ&gt;</translation>
<translation id="6711464428925977395">ಪà³à²°à²¾à²•à³à²¸à²¿ ಸರà³à²µà²°à³â€Œâ€Œà²¨à²²à³à²²à²¿ à²à²¨à³‹ ದೋಷವಿದೆ ಅಥವಾ ವಿಳಾಸವೠತಪà³à²ªà²¾à²—ಿದೆ.</translation>
<translation id="6727102863431372879">ಹೊಂದಿಸà³</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 à²à²Ÿà²‚}one{# à²à²Ÿà²‚ಗಳà³}other{# à²à²Ÿà²‚ಗಳà³}}</translation>
<translation id="674375294223700098">ಅಪರಿಚಿತ ಸರà³à²µà²°à³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ದೋಷ.</translation>
<translation id="6753269504797312559">ನೀತಿ ಮೌಲà³à²¯</translation>
<translation id="6757797048963528358">ನಿಮà³à²® ಸಾಧನವೠನಿದà³à²°à²¾à²µà²¸à³à²¥à³†à²—ೆ ಹೋಗಿದೆ.</translation>
@@ -620,6 +684,8 @@
<translation id="6810899417690483278">ಕಸà³à²Ÿà²®à³ˆà²¸à³‡à²¶à²¨à³ à²à²¡à²¿</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">ಪà³à²°à²¦à³†à³•à²¶à²—ಳ ಡೇಟಾವನà³à²¨à³ ಲೋಡೠಮಾಡಲೠವಿಫಲವಾಗಿದೆ</translation>
+<translation id="6825578344716086703">ನೀವೠ<ph name="DOMAIN" /> ಅನà³à²¨à³ ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²¦à²¿à²°à²¿, ಆದರೆ ದà³à²°à³à²¬à²² ಸಹಿ ಅಲà³à²—ಾರಿದಮೠ(SHA-1 ಅದರಂತೆ) ಬಳಸಿಕೊಂಡೠಸಹಿ ಮಾಡಿದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಒದಗಿಸಿದೆ. ಇದರರà³à²¥ ಸರà³à²µà²°à³ ಒದಗಿಸಿದ ಸà³à²°à²•à³à²·à²¤à³† ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳನà³à²¨à³ ಖೋಟಾ ತಯಾರಿಸಿರಬಹà³à²¦à³, ಮತà³à²¤à³ ನೀವೠನಿರೀಕà³à²·à²¿à²¸à²¿à²¦ ಸರà³à²µà²°à³ ಅದಾಗಿರದೇ ಇರಬಹà³à²¦à³ (ನೀವೠದಾಳಿಕೋರರೊಂದಿಗೆ ಸಂವಹನ ಮಾಡà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³).</translation>
+<translation id="6830728435402077660">ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿಲà³à²²</translation>
<translation id="6831043979455480757">ಅನà³à²µà²¾à²¦à²¿à²¸à³</translation>
<translation id="6839929833149231406">ಪà³à²°à²¦à³‡à²¶</translation>
<translation id="6874604403660855544">&amp;ಸೇರಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
@@ -627,6 +693,7 @@
<translation id="6895330447102777224">ನಿಮà³à²® ಕಾರà³à²¡à³ ಅನà³à²¨à³ ದೃಢೀಕರಿಸಲಾಗಿದೆ</translation>
<translation id="6897140037006041989">ಬಳಕೆದಾರ à²à²œà³†à²‚ಟà³</translation>
<translation id="6915804003454593391">ಬಳಕೆದಾರ:</translation>
+<translation id="6945221475159498467">ಆಯà³à²•à³†à²®à²¾à²¡à²¿</translation>
<translation id="6948701128805548767">ಪಿಕಪೠವಿಧಾನಗಳೠಹಾಗೂ ಆವಶà³à²¯à²•à²¤à³†à²—ಳನà³à²¨à³ ನೋಡಲà³, ಒಂದೠವಿಳಾಸವನà³à²¨à³ ಆಯà³à²•à³† ಮಾಡಿ</translation>
<translation id="6957887021205513506">ಸರà³à²µà²°à³â€Œà²—ಳ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ನಕಲಿಯಾಗಿ ಗೋಚರಿಸà³à²¤à³à²¤à²¦à³†.</translation>
<translation id="6965382102122355670">ಸರಿ</translation>
@@ -635,15 +702,16 @@
<translation id="6973656660372572881">ಹೊಂದಿಸಿದ ಪà³à²°à²¾à²•à³à²¸à²¿ ಸರà³à²µà²°à³â€Œà²—ಳೠಮತà³à²¤à³ .pac ಸà³à²•à³à²°à²¿à²ªà³à²Ÿà³ URL ಎರಡನà³à²¨à³‚ ನಿರà³à²¦à²¿à²·à³à²Ÿà²ªà²¡à²¿à²¸à²²à²¾à²—ಿದೆ.</translation>
<translation id="6989763994942163495">ಸà³à²§à²¾à²°à²¿à²¤ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳನà³à²¨à³ ತೋರಿಸà³...</translation>
<translation id="7000990526846637657">ಯಾವà³à²¦à³‡ ಇತಿಹಾಸ ದಾಖಲೆಗಳೠಕಂಡà³à²¬à²‚ದಿಲà³à²²</translation>
-<translation id="7009986207543992532">ನೀವೠ<ph name="DOMAIN" /> ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿, ಆದರೆ ವಾಯಿದೆ ಅವಧಿ ದೀರà³à²˜à²µà²¾à²—ಿರà³à²µ ವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²¦ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦à³†. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">ನಿಮà³à²® Google ಖಾತೆಯೠ<ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> ನಲà³à²²à²¿ ಬà³à²°à³Œà²¸à²¿à²‚ಗೠಇತಿಹಾಸದ ಇತರ ಪà³à²°à²•à²¾à²°à²—ಳನà³à²¨à³ ಹೊಂದಿರಬಹà³à²¦à³</translation>
<translation id="7029809446516969842">ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³</translation>
+<translation id="7050187094878475250">ನೀವೠ<ph name="DOMAIN" /> ಅನà³à²¨à³ ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿, ಆದರೆ ಸರà³à²µà²°à³ ವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²—ಿರಲೠತà³à²‚ಬ ಉದà³à²¦à²µà²¾à²¦ ವಾಯಿದೆ ಅವಧಿಯನà³à²¨à³ ಹೊಂದಿರà³à²µ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸಲà³à²²à²¿à²¸à²¿à²¦à³†.</translation>
+<translation id="7053983685419859001">ನಿರà³à²¬à²‚ಧಿಸà³</translation>
<translation id="7064851114919012435">ಸಂಪರà³à²• ಮಾಹಿತಿ</translation>
<translation id="7079718277001814089">ಈ ಸೈಟೠಮಾಲà³â€Œâ€Œà²µà³‡à²°à³ ಹೊಂದಿದೆ</translation>
<translation id="7087282848513945231">ರಾಷà³à²Ÿà³à²°</translation>
-<translation id="7088615885725309056">ಹಳೆಯದà³</translation>
<translation id="7090678807593890770"><ph name="LINK" /> ಗೆ Google ಹà³à²¡à³à²•à²¾à²Ÿ</translation>
+<translation id="7108819624672055576">ವಿಸà³à²¤à²°à²£à³†à²¯ ಮೂಲಕ ಅನà³à²®à²¤à²¿à²¸à²²à²¾à²—ಿದೆ</translation>
<translation id="7119414471315195487">ಇತರ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳನà³à²¨à³ ಅಥವಾ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಮà³à²šà³à²šà²¿</translation>
<translation id="7129409597930077180">ಈ ವಿಳಾಸಕà³à²•à³† ರವಾನಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²². ಬೇರೊಂದೠವಿಳಾಸವನà³à²¨à³ ಆಯà³à²•à³† ಮಾಡಿ.</translation>
<translation id="7138472120740807366">ವಿತರಣೆ ವಿಧಾನ</translation>
@@ -661,22 +729,18 @@
<translation id="7220786058474068424">ಪà³à²°à²•à³à²°à²¿à²¯à³†à²—ೊಳಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="724691107663265825">ಮà³à²‚ದಿರà³à²µ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿ ಮಾಲà³â€Œà²µà³‡à²°à³ ಇದೆ</translation>
<translation id="724975217298816891">ನಿಮà³à²® ಕಾರà³à²¡à³â€Œ ವಿವರಗಳನà³à²¨à³ ಅಪà³â€Œà²¡à³‡à²Ÿà³â€Œ ಮಾಡಲೠ<ph name="CREDIT_CARD" /> ಗೆ ಮà³à²•à³à²¤à²¾à²¯ ದಿನಾಂಕ ಮತà³à²¤à³ CVC ಅನà³à²¨à³ ನಮೂದಿಸಿ. ನೀವೠಒಮà³à²®à³† ಖಚಿತಪಡಿಸಿದರೆ, ನಿಮà³à²® ಕಾರà³à²¡à³ ವಿವರಗಳನà³à²¨à³ ಈ ಸೈಟೠಜೊತೆಗೆ ಹಂಚಿಕೊಳà³à²³à²²à²¾à²—à³à²¤à³à²¤à²¦à³†.</translation>
-<translation id="725866823122871198">ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯ (<ph name="DATE_AND_TIME" />) ತಪà³à²ªà²¾à²—ಿರà³à²µà³à²¦à²°à²¿à²‚ದ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಗೆ ಖಾಸಗಿ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¿à²²à³à²².</translation>
+<translation id="7260504762447901703">ಪà³à²°à²µà³‡à²¶à²µà²¨à³à²¨à³ ಹಿಂತೆಗೆದà³à²•à³Šà²³à³à²³à²¿</translation>
<translation id="7275334191706090484">ನಿರà³à²µà²¹à²¿à²¸à²¿à²¦ ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳà³</translation>
<translation id="7298195798382681320">ಶಿಫಾರಸೠಮಾಡಲಾಗಿದೆ</translation>
<translation id="7309308571273880165">ಕà³à²°à³à²¯à²¾à²¶à³ ವರದಿಯನà³à²¨à³ <ph name="CRASH_TIME" /> ರಲà³à²²à²¿ ಸೆರೆಹಿಡಿಯಲಾಗಿದೆ (ಬಳಕೆದಾರರ ಮೂಲಕ ವಿನಂತಿಸಲಾದ ಅಪà³â€Œà²²à³‹à²¡à³ ಅನà³à²¨à³, ಇನà³à²¨à³‚ ಅಪà³â€Œà²²à³‹à²¡à³ ಮಾಡಿಲಾಗಿಲà³à²²)</translation>
<translation id="7334320624316649418">&amp;ಮರà³à²•à³à²°à²®à²—ೊಳಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
<translation id="733923710415886693">ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಪಾರದರà³à²¶à²•à²¤à³†à²¯ ಮೂಲಕ ಸರà³à²µà²°à³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಬಹಿರಂಗಪಡಿಸಲಾಗಿಲà³à²².</translation>
-<translation id="7351800657706554155">ಇದೀಗ ನೀವೠ<ph name="SITE" /> ಗೆ ಭೇಟಿ ಮಾಡಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²² à²à²•à³†à²‚ದರೆ ಇದರ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಹಿಂಪಡೆಯಲಾಗಿದೆ. ನೆಟà³â€Œà²µà²°à³à²•à³ ದೋಷಗಳೠಮತà³à²¤à³ ದಾಳಿಗಳೠಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ತಾತà³à²•à²¾à²²à²¿à²•à²µà²¾à²—ಿರà³à²¤à³à²¤à²µà³†, ಹೀಗಾಗಿ ಈ ಪà³à²Ÿà²µà³ ನಂತರ ಕಾರà³à²¯à²¨à²¿à²°à³à²µà²¹à²¿à²¸à²¬à²¹à³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">ಆದೇಶ ಸಾಲà³</translation>
<translation id="7372973238305370288">ಹà³à²¡à³à²•à²¾à²Ÿ ಫಲಿತಾಂಶ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ಬೇಡ</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">ಕಾರà³à²¡à³ ಅನà³à²¨à³ ದೃಢೀಕರಿಸಿ</translation>
-<translation id="7394102162464064926">ನಿಮà³à²® ಇತಿಹಾಸದಿಂದ ಈ ಪà³à²Ÿà²—ಳನà³à²¨à³ ಅಳಿಸà³à²µà³à²¦à³ ಖಚಿತವೇ?
-
-ಛೆ! ಅದೃಶà³à²¯ ಮೋಡೠ<ph name="SHORTCUT_KEY" /> ಮà³à²‚ದಿನ ಬಾರಿಯಾದರೂ ಸಮಯಕà³à²•à³† ಸರಿಯಾಗಿ ಸಹಾಯಕà³à²•à³† ಬರಬಹà³à²¦à³.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">ಪà³à²°à³Šà²«à³ˆà²²à³ ಹಾದಿ</translation>
<translation id="7424977062513257142">ಈ ವೆಬà³â€Œà²ªà³à²Ÿà²¦à²²à³à²²à²¿ ಎಂಬೆಡೠಮಾಡಲಾದ ಪà³à²Ÿà²µà³ ಹೀಗೆ ಹೇಳà³à²¤à³à²¤à²¦à³†:</translation>
@@ -684,6 +748,7 @@
<translation id="7444046173054089907">ಈ ಸೈಟೠನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="7445762425076701745">ನೀವೠಸಂಪರà³à²• ಮಾಡಿರà³à²µ ಸರà³à²µà²°à³â€Œà²¨ ಗà³à²°à³à²¤à²¨à³à²¨à³ ಸಂಪೂರà³à²£à²µà²¾à²—ಿ ಮೌಲà³à²¯à³€à²•à²°à²¿à²¸à²²à²¾à²—à³à²µà³à²¦à²¿à²²à³à²². ನೀವೠನಿಮà³à²® ನೆಟà³â€Œà²µà²°à³à²•à³â€Œà²¨à²²à³à²²à²¿à²¯à³‡ ಮಾನà³à²¯à²µà²¿à²°à³à²µ ಹೆಸರನà³à²¨à³ ಮಾತà³à²° ಬಳಸಿಕೊಂಡೠಸಂಪರà³à²• ಹೊಂದಿರà³à²µà²¿à²°à²¿, ಇದರ ಮಾಲಿಕತà³à²µà²µà²¨à³à²¨à³ ಮೌಲà³à²¯à³€à²•à²°à²¿à²¸à³à²µ ಯಾವ ಅವಕಾಶವನà³à²¨à³‚ ಬಾಹà³à²¯ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಪà³à²°à²¾à²§à²¿à²•à²¾à²°à²µà³ ಹೊಂದಿಲà³à²². ಕೆಲವೠಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಪà³à²°à²¾à²§à²¿à²•à²¾à²°à²—ಳà³, ಯಾವà³à²¦à³‡ ಹೆಸರನà³à²¨à³ ಪರಿಗಣಿಸದೇ, ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳನà³à²¨à³ ಬಿಡà³à²—ಡೆ ಮಾಡà³à²µ ಕಾರಣದಿಂದಾಗಿ, ನೀವೠಉದà³à²¦à³‡à²¶à²¿à²¤ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ೆ ಸಂಪರà³à²•à²¿à²¸à²¿à²°à³à²µà²¿à²°à³‡ ಹೊರತೠದಾಳಿ ಮಾಡಲೠಅಲà³à²² ಎಂದೠಖಚಿತಪಡಿಸಿಕೊಳà³à²³à³à²µ ಯಾವ ಅವಕಾಶವೂ ಇಲà³à²².</translation>
<translation id="7451311239929941790">ಈ ಸಮಸà³à²¯à³†à²¯ ಕà³à²°à²¿à²¤à³ <ph name="BEGIN_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯà³à²µà²¿à²•à³†<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">ಜಾಗತಿಕ ಡಿಫಾಲà³à²Ÿà³ ಬಳಸಿ (ನಿರà³à²¬à²‚ಧಿಸಿ)</translation>
<translation id="7460163899615895653">ಇತರ ಸಾಧನಗಳಿಂದ ನಿಮà³à²® ಇತà³à²¤à²¿à³•à²šà²¿à²¨ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳೠಇಲà³à²²à²¿ ಗೋಚರಿಸà³à²¤à³à²¤à²µà³†</translation>
<translation id="7469372306589899959">ಕಾರà³à²¡à³â€Œ ದೃಢೀಕರಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="7481312909269577407">ಫಾರà³à²µà²°à³à²¡à³</translation>
@@ -691,36 +756,43 @@
<translation id="7508255263130623398">ಹಿಂತಿರà³à²—ಿಸಲಾದ ನೀತಿಯ ಸಾಧನ à²à²¡à²¿ ಖಾಲಿ ಇದೆ ಅಥವಾ ಪà³à²°à²¸à³à²¤à³à²¤ ಸಾಧನ à²à²¡à²¿à²—ೆ ಹೊಂದಾಣಿಕೆಯಾಗà³à²µà³à²¦à²¿à²²à³à²²</translation>
<translation id="7514365320538308">ಡೌನà³â€Œà²²à³‹à²¡à³</translation>
<translation id="7518003948725431193">ಈ ವೆಬೠವಿಳಾಸಕà³à²•à²¾à²—ಿ ಯಾವà³à²¦à³‡ ವೆಬೠಪà³à²Ÿà²µà³ ಕಂಡà³à²¬à²°à²²à²¿à²²à³à²²: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">ಮೌಲà³à²¯</translation>
<translation id="7537536606612762813">ಕಡà³à²¡à²¾à²¯</translation>
+<translation id="7542403920425041731">ನೀವೠಒಮà³à²®à³† ಖಚಿತಪಡಿಸಿದರೆ, ನಿಮà³à²® ಕಾರà³à²¡à³ ವಿವರಗಳನà³à²¨à³ ಈ ಸೈಟೠಜೊತೆಗೆ ಹಂಚಿಕೊಳà³à²³à²²à²¾à²—à³à²¤à³à²¤à²¦à³†.</translation>
<translation id="7542995811387359312">ಈ ಫಾರà³à²®à³ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²¦ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಬಳಸà³à²¤à³à²¤à²¿à²²à³à²²à²µà²¾à²¦ ಕಾರಣ ಸà³à²µà²¯à²‚ಚಾಲಿತ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ಭರà³à²¤à²¿ ಮಾಡà³à²µà²¿à²•à³†à²¯à²¨à³à²¨à³ ನಿಷà³à²•à³à²°à²¿à²¯à²—ೊಳಿಸಲಾಗಿದೆ.</translation>
<translation id="7543525346216957623">ನಿಮà³à²® ಪೋಷಕರಿಗೆ ಕೇಳಿ</translation>
<translation id="7549584377607005141">ಈ ವೆಬà³â€Œà²ªà³à²Ÿà²µà³ ಸರಿಯಾಗಿ ಪà³à²°à²¦à²°à³à²¶à²¨à²—ೊಳà³à²³à²²à³ ಈ ಮೊದಲೠನೀವೠನಮೂದಿಸಿದ ಡೇಟಾದ ಅಗತà³à²¯à²µà²¿à²¦à³†. ನೀವೠಈ ಡೇಟಾವನà³à²¨à³ ಮತà³à²¤à³† ಕಳà³à²¹à²¿à²¸à²¬à²¹à³à²¦à³, ಆದರೆ ಹಾಗೆ ಮಾಡà³à²µà³à²¦à²°à²¿à²‚ದ ಈ ಪà³à²Ÿà²µà³ ಈ ಮೊದಲೠಪೂರೈಸಿದ ಯಾವà³à²¦à³‡ ಕà³à²°à²¿à²¯à³†à²¯à²¨à³à²¨à³ ನೀವೠಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¸à³à²¤à³à²¤à³€à²°à²¿.</translation>
<translation id="7552846755917812628">ಕೆಳಗಿನ ಸಲಹೆಗಳನà³à²¨à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿:</translation>
<translation id="7554791636758816595">ಹೊಸ ಟà³à²¯à²¾à²¬à³</translation>
+<translation id="7567204685887185387">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ವಂಚನೆಯಿಂದ ನೀಡಿರಬಹà³à²¦à³. ಇದೠತಪà³à²ªà³ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ಇನà³à²¨à²·à³à²Ÿà³}one{<ph name="CONTACT_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ಇನà³à²¨à²·à³à²Ÿà³}other{<ph name="CONTACT_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ಇನà³à²¨à²·à³à²Ÿà³}}</translation>
<translation id="7568593326407688803">ಈ ಪà³à²Ÿà²µà³<ph name="ORIGINAL_LANGUAGE" />ನಲà³à²²à²¿à²¦à³† ನೀವೠಅದನà³à²¨à³ ಭಾಷಾಂತರಿಸಲೠಬಯಸà³à²µà²¿à²°à²¾?</translation>
<translation id="7569952961197462199">Chrome ನಿಂದ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à³‡?</translation>
<translation id="7569983096843329377">ಕಪà³à²ªà³</translation>
<translation id="7578104083680115302">Google ನೊಂದಿಗೆ ನೀವೠಉಳಿಸಲಾದ ಕಾರà³à²¡à³â€Œà²—ಳನà³à²¨à³ ಬಳಸಿಕೊಂಡೠಸಾಧನಗಳಾದà³à²¯à²‚ತ ಸೈಟà³â€Œà²—ಳೠಮತà³à²¤à³ ಅಪà³à²²à²¿à²•à³‡à²¶à²¨à³â€Œà²—ಳಲà³à²²à²¿ ತà³à²µà²°à²¿à²¤à²µà²¾à²—ಿ ಪಾವತಿಸಿ.</translation>
<translation id="7588950540487816470">ಭೌತಿಕ ವೆಬà³</translation>
<translation id="7592362899630581445">ಸರà³à²µà²°à³ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ಹೆಸರಿನ ನಿರà³à²¬à²‚ಧನೆಗಳನà³à²¨à³ ಉಲà³à²²à²‚ಘಿಸà³à²¤à³à²¤à²¦à³†.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> ಗಿಂತ ಕಡಿಮೆ</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ಗೆ ಪà³à²°à²¸à³à²¤à³à²¤ ಈ ವಿನಂತಿಯನà³à²¨à³ ನಿರà³à²µà²¹à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—à³à²¤à³à²¤à²¿à²²à³à²².</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> ಅನà³à²¨à³ ಎಂದಿಗೂ ಅನà³à²µà²¾à²¦à²¿à²¸à²¬à³‡à²¡</translation>
<translation id="7610193165460212391">ಮೌಲà³à²¯à²µà³ ವà³à²¯à²¾à²ªà³à²¤à²¿à²¯à²¿à²‚ದ <ph name="VALUE" /> ಹೊರಗಿದೆ.</translation>
<translation id="7613889955535752492">ಅವಧಿ ಮೀರà³à²µ ಸಮಯ: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">ನಿಮà³à²® Google ಖಾತೆಯ ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²¨ ಬೇರೆ ಆವೃತà³à²¤à²¿à²¯à²¨à³à²¨à³ ಬಳಸಿಕೊಂಡೠಎನà³â€Œà²•à³à²°à²¿à²ªà³à²Ÿà³ ಮಾಡಲಾದ ಡೇಟಾವನà³à²¨à³ ನೀವೠಈಗಾಗಲೇ ಹೊಂದಿರà³à²µà²¿à²°à²¿. ದಯವಿಟà³à²Ÿà³ ಕೆಳಗೆ ಇದನà³à²¨à³ ನಮೂದಿಸಿ.</translation>
-<translation id="7634554953375732414">ಈ ಸೈಟà³â€Œà²—ೆ ನಿಮà³à²® ಸಂಪರà³à²•à²µà³ ಖಾಸಗಿಯಾಗಿಲà³à²².</translation>
<translation id="7637571805876720304">Chromium ನಿಂದ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à³‡?</translation>
<translation id="765676359832457558">ಸà³à²§à²¾à²°à²¿à²¤ ಸೆಟà³à²Ÿà²¿à²‚ಗà³â€Œà²—ಳನà³à²¨à³ ಮರೆಮಾಡà³...</translation>
<translation id="7658239707568436148">ರದà³à²¦à³à²®à²¾à²¡à²¿</translation>
+<translation id="7662298039739062396">ವಿಸà³à²¤à²°à²£à³†à²¯ ಮೂಲಕ ಸೆಟà³à²Ÿà²¿à²‚ಗೠನಿಯಂತà³à²°à²¿à²¸à²²à³à²ªà²Ÿà³à²Ÿà²¿à²¦à³†</translation>
<translation id="7667346355482952095">ಹಿಂತಿರà³à²—ಿಸಲಾದ ನೀತಿಯ ಟೋಕನà³â€Œ ಖಾಲಿ ಇದೆ ಅಥವಾ ಪà³à²°à²¸à³à²¤à³à²¤ ಟೋಕನà³â€Œà²—ೆ ಹೊಂದಾಣಿಕೆಯಾಗà³à²µà³à²¦à²¿à²²à³à²²</translation>
<translation id="7668654391829183341">ಅಪರಿಚಿತ ಸಾಧನ</translation>
<translation id="7669271284792375604">ನಿಮà³à²® ಬà³à²°à³Œà²¸à²¿à²‚ಗà³â€Œ ಅನà³à²­à²µà²µà²¨à³à²¨à³ ಹಾನಿಮಾಡಲೠಸà³à²¥à²¾à²ªà²¿à²¸à²²à²¾à²—à³à²µ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳಲà³à²²à²¿ ನಿಮà³à²®à²¨à³à²¨à³ ವಂಚಿಸಲೠಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಈ ಸೈಟà³â€Œ ಮೇಲೆ ದಾಳಿ ಮಾಡಬಹà³à²¦à³ (ಉದಾಹರಣೆಗೆ, ನಿಮà³à²® ಮà³à²–ಪà³à²Ÿà²µà²¨à³à²¨à³ ಬದಲಾಯಿಸಲಾಗà³à²¤à³à²¤à²¦à³† ಅಥವಾ ನೀವೠಭೇಟಿ ನೀಡà³à²µ ಸೈಟà³â€Œà²—ಳಲà³à²²à²¿ ಹೆಚà³à²šà²¿à²¨ ಜಾಹೀರಾತà³à²—ಳನà³à²¨à³ ತೋರಿಸಲಾಗà³à²¤à³à²¤à²¦à³†).</translation>
<translation id="7674629440242451245">ಉತà³à²¤à²®à²µà²¾à²¦ ಹೊಸ Chrome ವೈಶಿಷà³à²Ÿà³à²¯à²—ಳಲà³à²²à²¿ ಆಸಕà³à²¤à²¿ ಇದೆಯೇ? chrome.com/dev ನಲà³à²²à²¿ ನಮà³à²® dev ಚಾನಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="7682287625158474539">ಶಿಪà³à²ªà²¿à²‚ಗà³</translation>
+<translation id="7701040980221191251">ಯಾವà³à²¦à³‚ ಇಲà³à²²</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" /> ಗೆ (ಅಸà³à²°à²•à³à²·à²¿à²¤) ಮà³à²‚ದà³à²µà²°à³†à²¸à³<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°</translation>
+<translation id="7716147886133743102">ನಿಮà³à²® ನಿರà³à²µà²¾à²¹à²•à²°à²¿à²‚ದ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="7716424297397655342">ಸಂಗà³à²°à²¹à²¦à²¿à²‚ದ ಈ ಸೈಟೠಲೋಡೠಮಾಡಲಾಗà³à²µà³à²¦à²¿à²²à³à²²</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">ನಿರà³à²µà²¹à²£à³†à²¯à²²à³à²²à²¿à²²à³à²²</translation>
<translation id="7755287808199759310">ನಿಮà³à²® ಪೋಷಕರೠನಿಮಗಾಗಿ ಅದನà³à²¨à³ ಅನಿರà³à²¬à²‚ಧಿಸಬಹà³à²¦à²¾à²—ಿದೆ</translation>
<translation id="7758069387465995638">ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಫೈರà³â€Œà²µà²¾à²²à³ ಅಥವಾ ಆಂಟಿವೈರಸೠಸಾಫà³à²Ÿà³â€Œà²µà³‡à²°à³ ನಿರà³à²¬à²‚ಧಿಸಿರಬಹà³à²¦à³.</translation>
@@ -747,15 +819,15 @@
<translation id="7951415247503192394">(32-ಬಿಟà³)</translation>
<translation id="7956713633345437162">ಮೊಬೈಲೠಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳà³</translation>
<translation id="7961015016161918242">ಎಂದಿಗೂ ಇಲà³à²²</translation>
-<translation id="7962083544045318153">ಕà³à²°à³à²¯à²¾à²¶à³ à²à²¡à²¿ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">ಯಾವಾಗಲೂ <ph name="ORIGINAL_LANGUAGE" /> ಅನà³à²¨à³ <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನà³à²µà²¾à²¦à²¿à²¸à²¿</translation>
<translation id="7995512525968007366">ನಿರà³à²¦à²¿à²·à³à²Ÿà²ªà²¡à²¿à²¸à²²à²¾à²—ಿಲà³à²²</translation>
<translation id="800218591365569300">ಮೆಮೊರಿ ಮà³à²•à³à²¤à²—ೊಳಿಸಲೠಇತರ ಟà³à²¯à²¾à²¬à³â€Œà²—ಳನà³à²¨à³ ಅಥವಾ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಮà³à²šà³à²šà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="8012647001091218357">ಈ ಕà³à²·à²£à²¦à²²à³à²²à²¿ ನಿಮà³à²® ಪೋಷಕರನà³à²¨à³ ತಲà³à²ªà²²à³ ನಮಗೆ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²². ಮತà³à²¤à³† ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿.</translation>
<translation id="8025119109950072390">ಈ ಸೈಟà³â€Œà²¨à²²à³à²²à²¿à²¨ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಸಾಫà³à²Ÿà³â€Œà²µà³‡à²°à³ ಸà³à²¥à²¾à²ªà²¿à²¸à³à²µà²¿à²•à³† ಅಥವಾ ನಿಮà³à²® ವೈಯಕà³à²¤à²¿à²• ಮಾಹಿತಿಯನà³à²¨à³ ಬಹಿರಂಗ ಪಡಿಸà³à²µà²‚ತಹ ಅಪಾಯಕಾರಿಯಾಗಿ à²à²¨à²¾à²¦à²°à³‚ ಮಾಡà³à²µà²‚ತಹ ಮೋಸವನà³à²¨à³ ಮಾಡಬಹà³à²¦à³ (ಉದಾಹರಣೆಗೆ, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳà³, ಫೋನà³â€Œ ಸಂಖà³à²¯à³†à²—ಳೠಅಥವಾ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³â€Œà²—ಳà³).</translation>
-<translation id="803030522067524905">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à³ ಮಾಡà³à²µà²¿à²•à³† ಇತà³à²¤à³€à²šà³†à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ ಫಿಶಿಂಗೠಪತà³à²¤à³†à²¹à²šà³à²šà²¿à²¦à³†. ಫಿಶಿಂಗೠಸೈಟà³â€Œà²—ಳೠನಿಮà³à²®à²¨à³à²¨à³ ಮೋಸಗೊಳಿಸಲೠಇತರ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳಂತೆ ಸೋಗೠಹಾಕà³à²¤à³à²¤à²µà³†. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">ಈ ಪà³à²Ÿà²µà³ <ph name="SOURCE_LANGUAGE" /> ನಲà³à²²à²¿ ಇದೆ. ಇದನà³à²¨à³ <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನà³à²µà²¾à²¦à²¿à²¸à³à²µà³à²¦à³‡?</translation>
+<translation id="8037357227543935929">ಕೇಳೠ(ಡಿಫಾಲà³à²Ÿà³)</translation>
<translation id="8041089156583427627">ಪà³à²°à²¤à²¿à²•à³à²°à²¿à²¯à³† ಕಳà³à²¹à²¿à²¸à²¿</translation>
+<translation id="8041940743680923270">ಜಾಗತಿಕ ಡಿಫಾಲà³à²Ÿà³ ಬಳಸಿ (ಕೇಳಿ)</translation>
<translation id="8088680233425245692">ಲೇಖನವನà³à²¨à³ ವೀಕà³à²·à²¿à²¸à²²à³ ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="8089520772729574115">1 MB ಗಿಂತ ಕಡಿಮೆ</translation>
<translation id="8091372947890762290">ಸರà³à²µà²°à³â€Œà²¨à²²à³à²²à²¿ ಸಕà³à²°à²¿à²¯à²¤à³† ಬಾಕಿ ಉಳಿದಿದೆ</translation>
@@ -764,13 +836,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> ಅವರ ಸರà³à²µà²°à³â€Œ <ph name="BEGIN_ABBR" />DNS ವಿಳಾಸ<ph name="END_ABBR" /> ಕಂಡà³à²¬à²‚ದಿಲà³à²².</translation>
<translation id="8149426793427495338">ನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರೠನಿದà³à²°à²¾à²µà²¸à³à²¥à³†à²—ೆ ಹೋಗಿದೆ.</translation>
<translation id="8150722005171944719"><ph name="URL" /> ನಲà³à²²à²¿à²¨ ಫೈಲೠಓದà³à²µà²‚ತಿರà³à²µà³à²¦à²¿à²²à³à²². ಇದನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à²¬à²¹à³à²¦à³, ಚಲಿಸಬಹà³à²¦à³, ಅಥವಾ ಫೈಲೠಅನà³à²®à²¤à²¿à²—ಳೠಪà³à²°à²µà³‡à²¶à²µà²¨à³à²¨à³ ತಡೆಗಟà³à²Ÿà³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³.</translation>
+<translation id="8184538546369750125">ಜಾಗತಿಕ ಡಿಫಾಲà³à²Ÿà³ ಬಳಸಿ (ಅನà³à²®à²¤à²¿à²¸à²¿)</translation>
+<translation id="8191494405820426728"><ph name="CRASH_LOCAL_ID" /> ಸà³à²¥à²³à³€à²¯ ಕà³à²°à³à²¯à²¾à²¶à³ à²à²¡à²¿</translation>
<translation id="8194797478851900357">&amp;ಸರಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸà³</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ID ಜೊತೆಗಿನ ವಿಸà³à²¤à²°à²£à³†à²—ೆ ಅಮಾನà³à²¯à²µà²¾à²¦ ಅಪà³â€Œà²¡à³‡à²Ÿà³â€Œâ€Œ URL.</translation>
<translation id="8202097416529803614">ಆರà³à²¡à²°à³ ಸಾರಾಂಶ</translation>
<translation id="8218327578424803826">ನಿಯೋಜಿಸಲಾದ ಸà³à²¥à²³:</translation>
<translation id="8225771182978767009">ಈ ಕಂಪà³à²¯à³‚ಟರೠಹೊಂದಿಸಿರà³à²µ ವà³à²¯à²•à³à²¤à²¿à²¯à³ ಈ ಸೈಟೠನಿರà³à²¬à²‚ಧಿಸಲೠಆಯà³à²•à³†à²®à²¾à²¡à²¿à²¦à³à²¦à²¾à²°à³†.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ನಲà³à²²à²¿à²°à³à²µ ದಾಳಿಕೋರರೠನಿಮà³à²® ಕಂಪà³à²¯à³‚ಟರà³â€Œà²¨à²²à³à²²à²¿à²°à³à²µ ಮಾಹಿತಿ (ಉದಾಹರಣೆಗೆ, ಫೋಟೋಗಳà³, ಪಾಸà³â€Œà²µà²°à³à²¡à³â€Œà²—ಳೠಮತà³à²¤à³ ಕà³à²°à³†à²¡à²¿à²Ÿà³ ಕಾರà³à²¡à³ ಮಾಹಿತಿಗಳà³) ಕದಿಯಲೠಇಲà³à²²à²µà³‡ ಅಳಿಸಲೠಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à²¬à²¹à³à²¦à³.</translation>
<translation id="8241707690549784388">ನೀವೠಎದà³à²°à³ ನೋಡà³à²¤à³à²¤à²¿à²°à³à²µ ಪà³à²Ÿ ನೀವೠನಮೂದಿಸಿದ ಮಾಹಿತಿಯನà³à²¨à³ ಬಳಸಿದೆ. ಆ ಪà³à²Ÿà²•à³à²•à³† ಹಿಂದಿರà³à²—à³à²µà³à²¦à²°à²¿à²‚ದ ನೀವೠಮಾಡಿದ ಯಾವà³à²¦à³‡ ಕà³à²°à²¿à²¯à³† ಪà³à²¨à²°à²¾à²µà²°à³à²¤à²¿à²¸à³à²µà²‚ತೆ ಮಾಡà³à²¤à³à²¤à²¦à³†. ನೀವೠಮà³à²‚ದà³à²µà²°à²¿à²¸à²²à³ ಬಯಸà³à²¤à³à²¤à³€à²°à²¾?</translation>
<translation id="8249320324621329438">ಕಳೆದ ಬಾರಿ ಪಡೆದಿರà³à²µà³à²¦à³:</translation>
<translation id="8253091569723639551">ಬಿಲà³à²²à²¿à²‚ಗೠವಿಳಾಸ ಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
@@ -778,6 +851,7 @@
<translation id="8289355894181816810">ಇದರ ಅರà³à²¥à²µà³‡à²¨à³†à²‚ದೠನಿಮಗೆ ಖಚಿತವಾಗದಿದà³à²¦à²°à³† ನಿಮà³à²® ನೆಟà³â€Œà²µà²°à³à²•à³ ನಿರà³à²µà²¾à²¹à²•à²°à²¨à³à²¨à³ ಸಂಪರà³à²•à²¿à²¸à²¿.</translation>
<translation id="8293206222192510085">ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³ ಸೇರಿಸà³</translation>
<translation id="8294431847097064396">ಮೂಲ</translation>
+<translation id="8306404619377842860"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಖಾಸಗಿ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¿à²²à³à²² à²à²•à³†à²‚ದರೆ ನಿಮà³à²® ಸಾಧನದ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯ (<ph name="DATE_AND_TIME" />) ತಪà³à²ªà²¾à²—ಿದೆ. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">ನೆಟà³â€Œà²µà²°à³à²•à³ ಸಂಪರà³à²•à²¦à²²à³à²²à²¿à²¨ ಸಮಸà³à²¯à³†à²¯à²¿à²‚ದಾಗಿ ಭಾಷಾಂತರವೠವಿಫಲವಾಗಿದೆ.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ಗೆ ಪà³à²°à²µà³‡à²¶à²µà²¨à³à²¨à³ ನಿರಾಕರಿಸಲಾಗಿದೆ</translation>
<translation id="834457929814110454">ನಿಮà³à²® ಸà³à²°à²•à³à²·à²¤à³† ಅಪಾಯಗಳೠನಿಮಗೆ ಅರà³à²¥à²µà²¾à²—ಿದà³à²¦à²°à³†, ಅಪಾಯಕಾರಿ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ತೆಗೆದà³à²¹à²¾à²•à³à²µà³à²¦à²•à³à²•à³‚ ಮೊದಲೠನೀವೠ<ph name="BEGIN_LINK" />ಈ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ<ph name="END_LINK" /> ನೀಡಬಹà³à²¦à³.</translation>
@@ -798,11 +872,9 @@
<translation id="8483780878231876732">ನಿಮà³à²® Google ಖಾತೆಯಿಂದ ಕಾರà³à²¡à³â€Œà²—ಳನà³à²¨à³ ಬಳಸಲà³, Chrome ಗೆ ಸೈನೠಇನೠಮಾಡಿ</translation>
<translation id="8488350697529856933">ಇದಕà³à²•à³† ಅನà³à²µà²¯à²¿à²¸à²²à²¾à²—à³à²¤à³à²¤à²¦à³†</translation>
<translation id="8498891568109133222">ಪà³à²°à²¤à²¿à²•à³à²°à²¿à²¯à²¿à²¸à²²à³ <ph name="HOST_NAME" /> ಹೆಚà³à²šà³ ಸಮಯ ತೆಗೆದà³à²•à³Šà²‚ಡಿದೆ.</translation>
-<translation id="852346902619691059">ಈ ಸರà³à²µà²°à³ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬà³à²¦à²¨à³à²¨à³ ಸಾಬೀತà³à²ªà²¡à²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¾à²—ಲಿಲà³à²²; ಅದರ ಸà³à²°à²•à³à²·à²¤à²¾ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ನಿಮà³à²® ಸಾಧನದ ಆಪರೇಟಿಂಗೠಸಿಸà³à²Ÿà²‚ನಿಂದ ವಿಶà³à²µà²¾à²¸à²¹à³Šà²‚ದಿಲà³à²². ಇದೠತಪà³à²ªà²¾à²¦ ಕಾನà³à²«à²¿à²—ರೇಶನà³â€Œà²¨à²¿à²‚ದ ಅಥವಾ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ನಿಮà³à²® ಸಂಪರà³à²•à²¦à²²à³à²²à²¿ ಒಳನà³à²¸à³à²³à²¿à²°à³à²µà³à²¦à²°à²¿à²‚ದ ಆಗಿರಬಹà³à²¦à³. <ph name="BEGIN_LEARN_MORE_LINK" />ಇನà³à²¨à²·à³à²Ÿà³ ತಿಳಿಯಿರಿ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">ಮà³à²•à³à²¤à²¾à²¯à²¦ ವರà³à²·</translation>
<translation id="8543181531796978784">ನೀವೠ<ph name="BEGIN_ERROR_LINK" />ಪತà³à²¤à³† ಹಚà³à²šà³à²µà²¿à²•à³† ಸಮಸà³à²¯à³†à²¯à²¨à³à²¨à³ ವರದಿ ಮಾಡಬಹà³à²¦à³<ph name="END_ERROR_LINK" /> ಅಥವಾ ನಿಮà³à²® ಭದà³à²°à²¤à³†à²¯ ಅಪಾಯಗಳ ಕà³à²°à²¿à²¤à³ ನಿಮಗೆ ಅರà³à²¥à²µà²¾à²—ಿದà³à²¦à²°à³†, <ph name="BEGIN_LINK" />ಈ ಅಸà³à²°à²•à³à²·à²¿à²¤ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ ನೀಡಿ<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">ಪà³à²Ÿà²¦ ಭಾಷೆಯನà³à²¨à³ ಗà³à²°à³à²¤à²¿à²¸à²²à³ ಅಸಾಧà³à²¯à²µà²¾à²¦ ಕಾರಣ ಭಾಷಾಂತರವೠವಿಫಲವಾಗಿದೆ.</translation>
-<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ಗೆ ಖಾಸಗಿ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³ ಸಾಧà³à²¯à²µà²¿à²²à³à²² à²à²•à³†à²‚ದರೆ ನಿಮà³à²® ಸಾಧನದ ದಿನಾಂಕ ಮತà³à²¤à³ ಸಮಯ (<ph name="DATE_AND_TIME" />) ತಪà³à²ªà²¾à²—ಿದೆ.</translation>
<translation id="8571890674111243710"><ph name="LANGUAGE" /> ಗೆ ಪà³à²Ÿà²µà²¨à³à²¨à³ ಭಾಷಾಂತರಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†...</translation>
<translation id="858637041960032120">ಫೋನೠಸಂ. ಸೇರಿಸಿ
</translation>
@@ -817,6 +889,7 @@
<translation id="8738058698779197622">ಸà³à²°à²•à³à²·à²¿à²¤ ಸಂಪರà³à²•à²µà²¨à³à²¨à³ ಸà³à²¥à²¾à²ªà²¿à²¸à²²à³, ನಿಮà³à²® ಗಡಿಯಾರವನà³à²¨à³ ಸರಿಯಾಗಿ ಹೊಂದಿಸà³à²µ ಅಗತà³à²¯à²µà²¿à²¦à³†. ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ಳೠತಮà³à²®à²¨à³à²¨à³ ಗà³à²°à³à²¤à²¿à²¸à²²à³ ಬಳಸà³à²µ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳೠಸಮಯದ ನಿರà³à²¦à²¿à²·à³à²Ÿ ಅವಧಿಗಳಲà³à²²à²¿ ಮಾತà³à²° ಮಾನà³à²¯à²µà²¾à²—ಿರà³à²µ ಕಾರಣ ಹೀಗಾಗà³à²¤à³à²¤à²¦à³†. ನಿಮà³à²® ಸಾಧನದ ಗಡಿಯಾರವೠತಪà³à²ªà²¾à²—ಿರà³à²µ ಕಾರಣ, Chromium ಗೆ ಈ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳನà³à²¨à³ ಪರಿಶೀಲಿಸಲೠಸಾಧà³à²¯à²µà²¿à²²à³à²².</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> ನ &lt;abbr id="dnsDefinition"&gt;DNS ವಿಳಾಸ&lt;/abbr&gt; ಕಂಡà³à²¬à²°à²²à²¿à²²à³à²². ಸಮಸà³à²¯à³†à²¯à²¨à³à²¨à³ ಪತà³à²¤à³†à²¹à²šà³à²šà²²à²¾à²—à³à²¤à³à²¤à²¿à²¦à³†.</translation>
<translation id="8759274551635299824">ಈ ಕಾರà³à²¡à³â€Œà²¨ ಅವಧಿ ಮà³à²•à³à²¤à²¾à²¯à²µà²¾à²—ಿದೆ</translation>
+<translation id="8761567432415473239">Google ಸà³à²°à²•à³à²·à²¿à²¤ ಬà³à²°à³Œà²¸à²¿à²‚ಗà³â€Œ ಇತà³à²¤à³€à²šà²¿à²—ೆ <ph name="SITE" /> ನಲà³à²²à²¿ <ph name="BEGIN_LINK" />ಹಾನಿಕಾರಕ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳನà³à²¨à³ ಕಂಡà³à²¹à²¿à²¡à²¿à²¦à²¿à²¦à³†<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;ಅಳಿಸà³à²µà³à²¦à²¨à³à²¨à³ ಮತà³à²¤à³†à²®à²¾à²¡à³</translation>
<translation id="8800988563907321413">ನಿಮà³à²® ಸಮೀಪದ ವೆಬೠಪà³à²Ÿà²¦ ಸಲಹೆಗಳೠಇಲà³à²²à²¿ ಗೋಚರಿಸà³à²¤à³à²¤à²µà³†</translation>
<translation id="8820817407110198400">ಬà³à²•à³â€Œà²®à²¾à²°à³à²•à³â€Œà²—ಳà³</translation>
@@ -829,29 +902,30 @@
<translation id="8870413625673593573">ಇತà³à²¤à³€à²šà³†à²—ೆ ಮà³à²šà³à²šà²¿à²°à³à²µà³à²¦à³</translation>
<translation id="8874824191258364635">ಮಾನà³à²¯à²µà²¾à²¦ ಕಾರà³à²¡à³ ಸಂಖà³à²¯à³†à²¯à²¨à³à²¨à³ ನಮೂದಿಸಿ</translation>
<translation id="8876793034577346603">ಪಾರà³à²¸à³ ಮಾಡಬೇಕಾಗಿರà³à²µ ನೆಟà³â€Œà²µà²°à³à²•à³ ಕಾನà³à²«à²¿à²—ರೇಶನೠವಿಫಲವಾಗಿದೆ.</translation>
-<translation id="8877192140621905067">ನೀವೠಒಮà³à²®à³† ಖಚಿತಪಡಿಸಿದರೆ, ನಿಮà³à²® ಕಾರà³à²¡à³ ವಿವರಗಳನà³à²¨à³ ಈ ಸೈಟೠಜೊತೆಗೆ ಹಂಚಿಕೊಳà³à²³à²²à²¾à²—à³à²¤à³à²¤à²¦à³†</translation>
<translation id="8889402386540077796">ವರà³à²£</translation>
<translation id="8891727572606052622">ಅಮಾನà³à²¯à²µà²¾à²¦ ಪà³à²°à²¾à²•à³à²¸à²¿ ಮೋಡà³.</translation>
<translation id="889901481107108152">ಕà³à²·à²®à²¿à²¸à²¿, ಈ ಪà³à²°à²¯à³‹à²—ವೠನಿಮà³à²® ಪà³à²²à³à²¯à²¾à²Ÿà³â€Œà²«à²¾à²°à³à²®à³â€Œà²¨à²²à³à²²à²¿ ಲಭà³à²¯à²µà²¿à²²à³à²².</translation>
<translation id="8903921497873541725">à²à³‚ಮೠಇನà³</translation>
<translation id="8931333241327730545">ಈ ಕಾರà³à²¡à²¨à³à²¨à³ ನಿಮà³à²® Google ಖಾತೆನಲà³à²²à²¿ ಉಳಿಸಲೠಬಯಸà³à²µà²¿à²°à²¾?</translation>
<translation id="8932102934695377596">ನಿಮà³à²® ಗಡಿಯಾರ ಹಿಂದೆ ಇದೆ</translation>
-<translation id="8954894007019320973">(ಮà³à²‚ದà³.)</translation>
<translation id="8971063699422889582">ಸರà³à²µà²°à³â€Œà²¨ ಪà³à²°à²•à²®à²¾à²£à²ªà²¤à³à²°à²¦ ಅವಧಿ ಮà³à²•à³à²¤à²¾à²¯à²—ೊಂಡಿದೆ.</translation>
<translation id="8986494364107987395">ಬಳಕೆಯ ಅಂಕಿಅಂಶಗಳನà³à²¨à³ ಮತà³à²¤à³ ಕà³à²°à²¾à²¶à³ ವರದಿಗಳನà³à²¨à³ Google ಗೆ ಸà³à²µà²¯à²‚ಚಾಲಿತವಾಗಿ ರವಾನಿಸà³</translation>
-<translation id="8987927404178983737">ತಿಂಗಳà³</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ಈ ಮà³à²‚ದಕà³à²•à³† ಸೈಟೠಹಾನಿಕಾರಕ ಪà³à²°à³†à³‚ೕಗà³à²°à²¾à²‚ಗಳನà³à²¨à³ ಹೊಂದಿದೆ</translation>
+<translation id="8997023839087525404">ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²° ಪಾರದರà³à²¶à²•à²¤à³† ನೀತಿಯನà³à²¨à³ ಬಳಸಿಕೊಂಡೠಸಾರà³à²µà²œà²¨à²¿à²•à²µà²¾à²—ಿ ಬಹಿರಂಗಗೊಳಿಸದ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ಸರà³à²µà²°à³ ಪà³à²°à²¸à³à²¤à³à²¤à²ªà²¡à²¿à²¸à²¿à²¦à³†. ಇದೠಅವà³à²—ಳೠವಿಶà³à²µà²¾à²¸à²¾à²°à³à²¹à²µà²¾à²—ಿವೆ ಮತà³à²¤à³ ಆಕà³à²°à²®à²£à²—ಾರರ ವಿರà³à²¦à³à²§ ರಕà³à²·à²£à³†à²¯à²¨à³à²¨à³ ನೀಡà³à²¤à³à²¤à²µà³† ಎಂಬà³à²¦à²¨à³à²¨à³ ಖಚಿತಪಡಿಸಿಕೊಳà³à²³à²²à³ ಕೆಲವೠಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²—ಳಿಗೆ ಅಗತà³à²¯à²µà²¾à²—ಿದೆ.</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> ಪà³à²°à²¾à²•à³à²¸à²¿à²—ೆ ಬಳಕೆದಾರಹೆಸರೠಮತà³à²¤à³ ಪಾಸà³â€Œà²µà²°à³à²¡à³ ಅಗತà³à²¯à²µà²¿à²°à³à²¤à³à²¤à²¦à³†.</translation>
+<translation id="9005998258318286617">PDF ಡಾಕà³à²¯à³à²®à³†à²‚ಟೠಅನà³à²¨à³ ಲೋಡೠಮಾಡಲೠವಿಫಲವಾಗಿದೆ.</translation>
<translation id="901974403500617787">ಸಿಸà³à²Ÿà²‚ನಾದà³à²¯à²‚ತ ಅನà³à²µà²¯à²µà²¾à²—à³à²µ ಫà³à²²à³à²¯à²¾à²—à³â€Œà²—ಳನà³à²¨à³ ಮಾಲೀಕರಿಂದ ಮಾತà³à²° ಹೊಂದಿಸಲೠಸಾಧà³à²¯: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">ಕಾರà³à²¡à³â€Œ ಬಿಲà³à²²à²¿à²‚ಗೠವಿಳಾಸದ ಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
<translation id="9020542370529661692">ಈ ಪà³à²Ÿà²µà²¨à³à²¨à³ <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನà³à²µà²¾à²¦à²¿à²¸à²²à²¾à²—ಿದೆ</translation>
<translation id="9035022520814077154">ಭದà³à²°à²¤à²¾ ದೋಷ</translation>
<translation id="9038649477754266430">ಪà³à²Ÿà²—ಳನà³à²¨à³ ಹೆಚà³à²šà³ ವೇಗವಾಗಿ ಲೋಡೠಮಾಡಲೠಮà³à²¨à³à²¨à³‹à²Ÿà²—ಳನà³à²¨à³ ಬಳಸಿ</translation>
<translation id="9039213469156557790">ಅಲà³à²²à²¦à³‡, ಸà³à²°à²•à³à²·à²¿à²¤à²µà²²à³à²²à²¦ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಈ ಪà³à²Ÿ ಹೊಂದಿದೆ. ಸà³à²¥à²¿à²¤à³à²¯à²‚ತರಗೊಳà³à²³à³à²µ ಸಂದರà³à²­à²¦à²²à³à²²à²¿ ಈ ಸಂಪನà³à²®à³‚ಲಗಳನà³à²¨à³ ಇತರರೂ ವೀಕà³à²·à²¿à²¸à²¬à²¹à³à²¦à²¾à²—ಿದೆ ಮತà³à²¤à³ ಪà³à²Ÿà²¦ ಹೊರನೋಟವೇ ಬದಲಾಗà³à²µà²‚ತೆ ಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ ಅದನà³à²¨à³ ತಿದà³à²¦à²¬à²¹à³à²¦à²¾à²—ಿದೆ.</translation>
-<translation id="9040185888511745258">ನಿಮà³à²® ಬà³à²°à³Œà²¸à²¿à²‚ಗà³â€Œ ಅನà³à²­à²µà²µà²¨à³à²¨à³ ಹಾನಿಮಾಡಲೠಸà³à²¥à²¾à²ªà²¿à²¸à²²à²¾à²—à³à²µ ಪà³à²°à³‹à²—à³à²°à²¾à²‚ಗಳಲà³à²²à²¿ ನಿಮà³à²®à²¨à³à²¨à³ ವಂಚಿಸಲೠಆಕà³à²°à²®à²£à²•à²¾à²°à²°à³ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ಮೇಲೆ ದಾಳಿ ಮಾಡಬಹà³à²¦à³ (ಉದಾಹರಣೆಗೆ, ನಿಮà³à²® ಮà³à²–ಪà³à²Ÿà²µà²¨à³à²¨à³ ಬದಲಾಯಿಸಲಾಗà³à²¤à³à²¤à²¦à³† ಅಥವಾ ನೀವೠಭೇಟಿ ನೀಡà³à²µ ಸೈಟà³â€Œà²—ಳಲà³à²²à²¿ ಹೆಚà³à²šà²¿à²¨ ಜಾಹೀರಾತà³à²—ಳನà³à²¨à³ ತೋರಿಸಲಾಗà³à²¤à³à²¤à²¦à³†).</translation>
+<translation id="9049981332609050619">ನೀವೠ<ph name="DOMAIN" /> ಅನà³à²¨à³ ತಲà³à²ªà²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²°à³à²µà²¿à²°à²¿, ಆದರೆ ಸರà³à²µà²°à³ ಅಮಾನà³à²¯ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà²¨à³à²¨à³ ನೀಡಿದೆ.</translation>
<translation id="9050666287014529139">ಪಾಸà³â€Œà²«à³à²°à³‡à²¸à³</translation>
<translation id="9065203028668620118">ಎಡಿಟà³</translation>
<translation id="9068849894565669697">ಬಣà³à²£à²µà²¨à³à²¨à³ ಆಯà³à²•à³†à²®à²¾à²¡à²¿</translation>
+<translation id="9069693763241529744">ವಿಸà³à²¤à²°à²£à³†à²¯ ಮೂಲಕ ನಿರà³à²¬à²‚ಧಿಸಲಾಗಿದೆ</translation>
<translation id="9076283476770535406">ಇದೠಪà³à²°à²¬à³à²¦à³à²§ ವಿಷಯವನà³à²¨à³ ಹೊಂದಿರಬಹà³à²¦à³</translation>
<translation id="9078964945751709336">ಇನà³à²¨à²·à³à²Ÿà³ ಮಾಹಿತಿಯ ಅಗತà³à²¯à²µà²¿à²¦à³†</translation>
<translation id="9103872766612412690"><ph name="SITE" /> ಸಾಮಾನà³à²¯à²µà²¾à²—ಿ ನಿಮà³à²® ಮಾಹಿತಿಯನà³à²¨à³ ಸಂರಕà³à²·à²¿à²¸à²²à³ ಎನà³â€Œà²•à³à²°à²¿à²ªà³à²¶à²¨à³ ಪà³à²°à²¯à³‹à²œà²¨à²µà²¨à³à²¨à³ ಬಳಸಿಕೊಳà³à²³à³à²¤à³à²¤à²¦à³†. ಈ ಸಂದರà³à²­à²¦à²²à³à²²à²¿ Chromium <ph name="SITE" /> ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œà²—ೆ ಸಂಪರà³à²•à²¿à²¸à²²à³ ಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à²¿à²¦à²¾à²—, ಆ ವೆಬà³â€Œà²¸à³ˆà²Ÿà³â€Œâ€Œ ಅಸಹಜ ಮತà³à²¤à³ ತಪà³à²ªà³ ರà³à²œà³à²µà²¾à²¤à³à²—ಳನà³à²¨à³ ಹಿಂತಿರà³à²—ಿಸಿದೆ. ದಾಳಿಕೋರರೠ<ph name="SITE" /> ರೂಪದಲà³à²²à²¿ ಸೋಗೠಹಾಕಲೠಪà³à²°à²¯à²¤à³à²¨à²¿à²¸à³à²¤à³à²¤à²¿à²°à³à²µà²¾à²— ಅಥವಾ ವೈ-ಫೈ ಸೈನà³-ಇನೠಪರದೆಯೠಸಂಪರà³à²•à²•à³à²•à³† ಅಡà³à²¡à²¿à²¯à³à²‚ಟೠಮಾಡಿದಾಗ ಇದೠಕಂಡà³à²¬à²°à²¬à²¹à³à²¦à³. ಯಾವà³à²¦à³‡ ಡೇಟಾವನà³à²¨à³ ವಿನಿಮಯ ಮಾಡಿಕೊಳà³à²³à³à²µ ಮೊದಲೇ Chromium ಸಂಪರà³à²• ಕಡಿತಗೊಳಿಸಿರà³à²µ ಕಾರಣ, ನಿಮà³à²® ಮಾಹಿತಿ ಈಗಲೂ ಸà³à²°à²•à³à²·à²¿à²¤à²µà²¾à²—ಿದೆ.</translation>
@@ -860,16 +934,21 @@
<translation id="9148507642005240123">&amp;ಸಂಪಾದಿಸà³à²µà³à²¦à²¨à³à²¨à³ ರದà³à²¦à³à²—ೊಳಿಸಿ</translation>
<translation id="9154194610265714752">ಅಪà³â€Œà²¡à³‡à²Ÿà³â€Œ ಮಾಡಲಾಗಿದೆ</translation>
<translation id="9157595877708044936">ಹೊಂದಿಸಲಾಗà³à²¤à³à²¤à²¿à²¦à³†...</translation>
+<translation id="9169664750068251925">ಈ ಸೈಟೠಅನà³à²¨à³ ಯಾವಾಗಲೂ ನಿರà³à²¬à²‚ಧಿಸà³</translation>
<translation id="9170848237812810038">&amp;ರದà³à²¦à³à²®à²¾à²¡à³</translation>
<translation id="917450738466192189">ಸರà³à²µà²°à³â€Œà²¨ ಪà³à²°à²®à²¾à²£à²ªà²¤à³à²°à²µà³ ಅಮಾನà³à²¯à²µà²¾à²—ಿದೆ.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ಇನà³à²¨à²·à³à²Ÿà³}one{<ph name="SHIPPING_OPTION_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ಇನà³à²¨à²·à³à²Ÿà³}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ಮತà³à²¤à³ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ಇನà³à²¨à²·à³à²Ÿà³}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> ಬೆಂಬಲಿತವಲà³à²²à²¦ ಪà³à²°à³‹à²Ÿà³‹à²•à²¾à²²à³ ಬಳಸà³à²¤à³à²¤à²¿à²¦à³†.</translation>
<translation id="9205078245616868884">ನಿಮà³à²® ಡೇಟಾವನà³à²¨à³ ನಿಮà³à²® ಸಿಂಕೠಪಾಸà³â€Œà²«à³à²°à³‡à²¸à³â€Œà²¨à³†à³‚ಂದಿಗೆ ಎನà³â€Œà²•à³à²°à²¿à²ªà³à²Ÿà³ ಮಾಡಲಾಗಿದೆ. ಸಿಂಕೠಪà³à²°à²¾à²°à²‚ಭಿಸಲೠಅದನà³à²¨à³ ನಮೂದಿಸಿ.</translation>
<translation id="9207861905230894330">ಲೇಖನವನà³à²¨à³ ಸೇರಿಸಲೠವಿಫಲವಾಗಿದೆ.</translation>
+<translation id="9219103736887031265">ಚಿತà³à²°à²—ಳà³</translation>
<translation id="933612690413056017">ಯಾವà³à²¦à³‡ ಇಂಟರà³à²¨à³†à²Ÿà³ ಸಂಪರà³à²•à²µà²¿à²²à³à²²</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ಫಾರà³à²®à³ ತೆರವà³à²—ೊಳಿಸಿ</translation>
<translation id="939736085109172342">ಹೊಸ ಫೋಲà³à²¡à²°à³</translation>
<translation id="941721044073577244">ಈ ಸೈಟà³â€Œà²—ೆ ಭೇಟಿ ನೀಡಲೠನಿಮಗೆ ಅನà³à²®à²¤à²¿ ಇಲà³à²² ಎಂದೠತೋರà³à²¤à³à²¤à²¿à²¦à³†</translation>
<translation id="969892804517981540">ಅಧಿಕೃತವಾಗಿ ನಿರà³à²®à²¿à²¸à²¿</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{ಯಾವà³à²¦à³‚ ಇಲà³à²²}=1{1 à²à²Ÿà²‚}one{# à²à²Ÿà²‚ಗಳà³}other{# à²à²Ÿà²‚ಗಳà³}}</translation>
<translation id="988159990683914416">ಡೆವಲಪರೠಬಿಲà³à²¡à³</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ko.xtb b/chromium/components/strings/components_strings_ko.xtb
index 69df7f43047..1d70dfa7908 100644
--- a/chromium/components/strings/components_strings_ko.xtb
+++ b/chromium/components/strings/components_strings_ko.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">시계 방향으로 회전</translation>
<translation id="1038842779957582377">ì•Œ 수 없는 ì´ë¦„</translation>
<translation id="1050038467049342496">다른 앱 닫기</translation>
-<translation id="1053591932240354961">현재 <ph name="SITE" />ì—ì„œ Chromeì´ ì²˜ë¦¬í•  수 없는 ì•”í˜¸í™”ëœ ìžê²©ì¦ëª… 정보를 전송했기 ë•Œë¬¸ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ìž ì‹œ 후 페ì´ì§€ê°€ ì •ìƒí™”ë  ê²ƒìž…ë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">추가 실행 취소(&amp;U)</translation>
<translation id="10614374240317010">비밀번호를 저장하지 ì•Šì€ ì‚¬ì´íŠ¸</translation>
<translation id="106701514854093668">ë°ìŠ¤í¬í†± ë¶ë§ˆí¬</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">ì •ì±… ìºì‹œ 확ì¸</translation>
<translation id="113188000913989374"><ph name="SITE" /> ë‚´ìš©:</translation>
<translation id="1132774398110320017">Chrome ìžë™ì™„성 설정...</translation>
+<translation id="1150979032973867961">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 ì»´í“¨í„°ì˜ ìš´ì˜ì²´ì œì—ì„œ 신뢰하는 보안 ì¸ì¦ì„œê°€ 아닙니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
+<translation id="1151972924205500581">비밀번호를 입력해야 합니다.</translation>
<translation id="1152921474424827756"><ph name="URL" />ì˜ <ph name="BEGIN_LINK" />ìºì‹œëœ 사본<ph name="END_LINK" />ì— ì•¡ì„¸ìŠ¤</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" />와(ê³¼)ì˜ ì—°ê²°ì´ ì˜ˆê¸°ì¹˜ 않게 종료ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="1161325031994447685">Wi-Fiì— ë‹¤ì‹œ ì—°ê²°</translation>
+<translation id="1165039591588034296">오류</translation>
<translation id="1175364870820465910">ì¸ì‡„(&amp;P)</translation>
<translation id="1181037720776840403">삭제</translation>
<translation id="1184214524891303587">ë°œìƒ ê°€ëŠ¥ì„±ì´ ìžˆëŠ” 보안 ë¬¸ì œì˜ ì„¸ë¶€ì •ë³´ë¥¼ Googleì— <ph name="BEGIN_WHITEPAPER_LINK" />ìžë™ìœ¼ë¡œ ë³´ê³ <ph name="END_WHITEPAPER_LINK" />합니다. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">ì´ ì‚¬ì´íŠ¸ì—ì„œ ë”보기</translation>
<translation id="1206967143813997005">ìž˜ëª»ëœ ì´ˆê¸° 서명</translation>
<translation id="1209206284964581585">지금 숨기기</translation>
+<translation id="121201262018556460"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했으나 서버가 ì•ˆì „ì„±ì´ ë‚®ì€ í‚¤ê°€ í¬í•¨ëœ ì¸ì¦ì„œë¥¼ 전달했습니다. 공격ìžê°€ 비공개 키를 ì†ìƒì‹œì¼°ì„ 수 있으며 서버를 가장한 공격ìžì™€ 통신 ì¤‘ì¼ ìˆ˜ 있습니다.</translation>
<translation id="1219129156119358924">시스템 보안</translation>
<translation id="1227224963052638717">알 수 없는 정책입니다.</translation>
<translation id="1227633850867390598">값 숨기기</translation>
<translation id="1228893227497259893">ìž˜ëª»ëœ ê°œì²´ ì‹ë³„ìž</translation>
<translation id="1232569758102978740">제목 ì—†ìŒ</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" />(ë™ê¸°í™”ë¨)</translation>
<translation id="1263231323834454256">ì½ê¸° 목ë¡</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" />ì— ìº¡ì²˜ëœ ë¹„ì •ìƒ ì¢…ë£Œ ë³´ê³ ì„œ(ì•„ì§ ì—…ë¡œë“œ ë˜ëŠ” 무시ë˜ì§€ ì•ŠìŒ)</translation>
+<translation id="1281526147609854549">발급 기관: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">위험한 콘í…츠가 차단ë¨</translation>
<translation id="1285320974508926690">ì´ ì‚¬ì´íŠ¸ 번역 안함</translation>
<translation id="129553762522093515">ìµœê·¼ì— ë‹«ì€ íƒ­</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />쿠키 삭제해 보기<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">다ìŒì˜ 관계ìžëŠ” ë‚´ í™œë™ ë‚´ì—­ì„ <ph name="BEGIN_EMPHASIS" />확ì¸í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤<ph name="END_EMPHASIS" />.
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />방문한 웹사ì´íŠ¸
+ <ph name="LIST_ITEM" />고용주 ë˜ëŠ” í•™êµ
+ <ph name="LIST_ITEM" />ì¸í„°ë„· 서비스 제공업체
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">ë“±ë¡ ë„ë©”ì¸:</translation>
<translation id="1340482604681802745">수령 주소</translation>
<translation id="1344211575059133124">ì´ ì‚¬ì´íŠ¸ë¥¼ 방문하려면 ê¶Œí•œì´ í•„ìš”í•œ 것 같습니다.</translation>
<translation id="1344588688991793829">Chromium ìžë™ì™„성 설정...</translation>
+<translation id="1348198688976932919">방문하려는 사ì´íŠ¸ì— 위험한 ì•±ì´ ìžˆìŠµë‹ˆë‹¤.</translation>
<translation id="1374468813861204354">제안사항</translation>
<translation id="1375198122581997741">버전 정보</translation>
<translation id="1377321085342047638">카드 번호</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" />ì—ì„œ 전송한 ë°ì´í„°ê°€ 없습니다.</translation>
<translation id="1407135791313364759">ëª¨ë‘ ì—´ê¸°</translation>
<translation id="1413809658975081374">ê°œì¸ì •ë³´ 보호 오류</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" />ì— ìœ„ì¹˜í•œ <ph name="ORGANIZATION" />ì˜ ì£¼ì†Œë¥¼ <ph name="ISSUER" />ì´(ê°€) 확ì¸í–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="1426410128494586442">예</translation>
<translation id="1430915738399379752">ì¸ì‡„</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> 페ì´ì§€ë¥¼ 방문<ph name="END_LINK" />하려는 ì‹œë„ê°€ 차단ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
-<translation id="1491663344921578213">현재 <ph name="SITE" />ì—ì„œ ì¸ì¦ì„œ ê³ ì •ì„ ì‚¬ìš©í•˜ê¸° ë•Œë¬¸ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ìž ì‹œ 후 페ì´ì§€ê°€ ì •ìƒí™”ë  ê²ƒìž…ë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />개}other{<ph name="PAYMENT_METHOD_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />개}}</translation>
<translation id="1506687042165942984">ì˜¤ëž˜ëœ ê²ƒìœ¼ë¡œ 알려진 ì´ íŽ˜ì´ì§€ì˜ ì €ìž¥ëœ ì‚¬ë³¸ì„ í‘œì‹œí•©ë‹ˆë‹¤.</translation>
<translation id="1517433312004943670">전화번호 필요</translation>
<translation id="1519264250979466059">ìƒì„± 날짜</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">ì´ ê¸°ëŠ¥ì„ ì´ìš©í•˜ë ¤ë©´ ìžë°”스í¬ë¦½íŠ¸ë¥¼ 사용하ë„ë¡ ì„¤ì •í•´ì•¼ 합니다.</translation>
<translation id="1555130319947370107">파란색</translation>
<translation id="1559528461873125649">해당 파ì¼ì´ë‚˜ 디렉토리가 없습니다.</translation>
-<translation id="1559572115229829303">&lt;p&gt;ê¸°ê¸°ì˜ ë‚ ì§œì™€ 시간(<ph name="DATE_AND_TIME" />)ì´ ìž˜ëª»ë˜ì–´ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />ì— ë¹„ê³µê°œë¡œ ì—°ê²°í•  수 없습니다.&lt;/p&gt;
-
- &lt;p&gt;&lt;strong&gt;설정&lt;/strong&gt; ì•±ì˜ &lt;strong&gt;ì¼ë°˜&lt;/strong&gt; 섹션ì—ì„œ 날짜와 ì‹œê°„ì„ ë§žì¶”ì„¸ìš”.&lt;/p&gt;</translation>
<translation id="1583429793053364125">ì´ ì›¹íŽ˜ì´ì§€ë¥¼ 표시하는 ë„중 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="1592005682883173041">로컬 ë°ì´í„° 액세스</translation>
+<translation id="1594030484168838125">ì„ íƒ</translation>
<translation id="161042844686301425">ì²­ë¡ìƒ‰</translation>
+<translation id="1620510694547887537">ì¹´ë©”ë¼</translation>
<translation id="1629803312968146339">Chromeì—ì„œ ì´ ì¹´ë“œë¥¼ 저장하ë„ë¡ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</translation>
<translation id="1639239467298939599">로드 중</translation>
<translation id="1640180200866533862">ì‚¬ìš©ìž ì •ì±…</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">ë„¤íŠ¸ì›Œí¬ êµ¬ì„±ì´ ìž˜ëª»ë˜ì–´ 가져올 수 없습니다.</translation>
<translation id="1644574205037202324">방문 기ë¡</translation>
<translation id="1645368109819982629">지ì›ë˜ì§€ 않는 프로토콜</translation>
+<translation id="1655462015569774233">{1,plural, =1{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ ì–´ì œ 만료ë˜ì–´ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. 현재 ì»´í“¨í„°ì˜ ì‹œê³„ê°€ <ph name="CURRENT_DATE" />ë¡œ 설정ë˜ì–´ 있습니다. ì‹œê°„ì´ ì •í™•í•˜ì§€ 않으면 시스템 시계를 수정한 ë’¤ ì´ íŽ˜ì´ì§€ë¥¼ 새로고침하세요.}other{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ #ì¼ ì „ì— ë§Œë£Œë˜ì–´ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. 현재 ì»´í“¨í„°ì˜ ì‹œê³„ê°€ <ph name="CURRENT_DATE" />ë¡œ 설정ë˜ì–´ 있습니다. ì‹œê°„ì´ ì •í™•í•˜ì§€ 않으면 시스템 시계를 수정한 ë’¤ ì´ íŽ˜ì´ì§€ë¥¼ 새로고침하세요.}}</translation>
<translation id="1656489000284462475">수령</translation>
<translation id="1663943134801823270">카드와 주소는 Chromeì—ì„œ 가져왔습니다. ì´ ì •ë³´ëŠ” <ph name="BEGIN_LINK" />설정<ph name="END_LINK" />ì—ì„œ 관리할 수 있습니다.</translation>
<translation id="1676269943528358898"><ph name="SITE" />ì—서는 ì‚¬ìš©ìž ì •ë³´ë¥¼ 보호하기 위해 ì¼ë°˜ì ìœ¼ë¡œ 암호화를 사용합니다. ì´ë²ˆì— Chromeì—ì„œ <ph name="SITE" />ì— ì—°ê²°ì„ ì‹œë„í–ˆì„ ë•Œ 웹사ì´íŠ¸ì—ì„œ 비정ìƒì ì´ê³  ìž˜ëª»ëœ ì‚¬ìš©ìž ì¸ì¦ 정보를 반환했습니다. ì´ëŠ” 공격ìžê°€ <ph name="SITE" />ì¸ ê²ƒì²˜ëŸ¼ 가장하려고 하거나 Wi-Fi ë¡œê·¸ì¸ í™”ë©´ì´ ì—°ê²°ì„ ë°©í•´í–ˆê¸° ë•Œë¬¸ì¼ ìˆ˜ 있습니다. ë°ì´í„° êµí™˜ì´ ë°œìƒí•˜ê¸° ì „ì— Chromeì—ì„œ ì—°ê²°ì„ ì¤‘ë‹¨í–ˆê¸° ë•Œë¬¸ì— ì‚¬ìš©ìž ì •ë³´ëŠ” 안전합니다.</translation>
-<translation id="168328519870909584">현재 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì˜ ê³µê²©ìžê°€ 사용 ì¤‘ì¸ ê¸°ê¸°ì— ì‚¬ìš©ìž ì •ë³´(예: 사진, 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ)를 ë„용하거나 삭제하는 위험한 ì•±ì„ ì„¤ì¹˜í•˜ë ¤ê³  ì‹œë„í•  수 있습니다.</translation>
<translation id="168841957122794586">서버 ì¸ì¦ì„œì— ì•ˆì „ì„±ì´ ë‚®ì€ ì•”í˜¸í™” 키가 í¬í•¨ë˜ì–´ 있습니다.</translation>
+<translation id="1706954506755087368">{1,plural, =1{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ ë‚´ì¼ ë°œíš¨ë  ì˜ˆì •ì´ë©° ì´ì— ë”°ë¼ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.}other{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ #ì¼ í›„ ë°œíš¨ë  ì˜ˆì •ì´ë©° ì´ì— ë”°ë¼ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">ì´ ì‚¬ì´íŠ¸ë¥¼ 방문하려면 <ph name="NAME" />님으로부터 ê¶Œí•œì„ ë°›ì•„ì•¼ 합니다.</translation>
<translation id="1721424275792716183">* 필수 입력란</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">페ì´ì§€ ë‚˜ì¤‘ì— ë‹¤ìš´ë¡œë“œ</translation>
<translation id="17513872634828108">열린 탭</translation>
<translation id="1753706481035618306">페ì´ì§€ 번호</translation>
+<translation id="1763864636252898013">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 ê¸°ê¸°ì˜ ìš´ì˜ì²´ì œì—ì„œ 신뢰하는 보안 ì¸ì¦ì„œê°€ 아닙니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows ë„¤íŠ¸ì›Œí¬ ì§„ë‹¨ í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰<ph name="END_LINK" />í•´ 보세요.</translation>
<translation id="1783075131180517613">ë™ê¸°í™” 암호를 ì—…ë°ì´íŠ¸í•˜ì„¸ìš”.</translation>
<translation id="1787142507584202372">열린 íƒ­ì´ ì—¬ê¸°ì— í‘œì‹œë©ë‹ˆë‹¤.</translation>
+<translation id="1789575671122666129">íŒì—…</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">ì¹´ë“œ ì†Œìœ ìž ì´ë¦„</translation>
-<translation id="1803678881841855883">Google 세ì´í”„ 브ë¼ìš°ì§•ì´ 최근 <ph name="SITE" />ì—ì„œ <ph name="BEGIN_LINK" />멀웨어를 ê°ì§€<ph name="END_LINK" />했습니다. ì•ˆì „í•˜ë˜ ì›¹ì‚¬ì´íŠ¸ë„ ë©€ì›¨ì–´ì— ê°ì—¼ë˜ëŠ” 경우가 있습니다. 악성 콘í…ì¸ ì˜ ì¶œì²˜ëŠ” 알려진 멀웨어 ë°°í¬ìžì¸ <ph name="SUBRESOURCE_HOST" />입니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">추가ì¼: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">ìž˜ëª»ëœ ìš”ì²­ ë˜ëŠ” 요청 매개변수</translation>
<translation id="1826516787628120939">í™•ì¸ ì¤‘</translation>
<translation id="1834321415901700177">ì´ ì‚¬ì´íŠ¸ì— 유해한 í”„ë¡œê·¸ëž¨ì´ ìžˆìŠµë‹ˆë‹¤.</translation>
+<translation id="1840414022444569775">ì´ë¯¸ ì‚¬ìš©ëœ ì¹´ë“œ 번호입니다.</translation>
<translation id="1842969606798536927">결제하기</translation>
<translation id="1871208020102129563">프ë¡ì‹œê°€ .pac 스í¬ë¦½íŠ¸ URLì´ ì•„ë‹Œ ê³ ì • 프ë¡ì‹œ 서버를 사용하ë„ë¡ ì„¤ì •ë©ë‹ˆë‹¤.</translation>
<translation id="1871284979644508959">필수 입력란</translation>
<translation id="187918866476621466">시작 페ì´ì§€ 열기</translation>
<translation id="1883255238294161206">접기 목ë¡</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />개}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />개}}</translation>
<translation id="1898423065542865115">í•„í„°ë§</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{ì—†ìŒ}=1{사ì´íŠ¸ 1ê°œ}other{사ì´íŠ¸ #ê°œ}}</translation>
<translation id="194030505837763158"><ph name="LINK" />(으)ë¡œ ì´ë™</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> ë¶ë§ˆí¬</translation>
<translation id="1973335181906896915">ì¼ë ¨í™” 오류</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701"><ph name="POLICY_NAME" />ì´(ê°€) ìš°ì„  ì ìš©ë˜ì—ˆê¸° ë•Œë¬¸ì— ë¬´ì‹œë©ë‹ˆë‹¤.</translation>
<translation id="2138201775715568214">주변 피지컬 웹페ì´ì§€ 검색 중</translation>
<translation id="213826338245044447">ëª¨ë°”ì¼ ë¶ë§ˆí¬</translation>
-<translation id="2148716181193084225">오늘</translation>
+<translation id="2147827593068025794">백그ë¼ìš´ë“œ ë™ê¸°í™”</translation>
<translation id="2154054054215849342">ë„ë©”ì¸ì— 대해 ë™ê¸°í™”를 사용할 수 없습니다.</translation>
<translation id="2154484045852737596">카드 수정</translation>
<translation id="2166049586286450108">ì „ì²´ ê´€ë¦¬ìž ì•¡ì„¸ìŠ¤</translation>
<translation id="2166378884831602661">사ì´íŠ¸ì— 보안 ì—°ê²°í•  수 ì—†ìŒ</translation>
<translation id="2181821976797666341">ì •ì±…</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{주소 1개}other{주소 #개}}</translation>
+<translation id="2187317261103489799">ê°ì§€(기본값)</translation>
<translation id="2202020181578195191">올바른 만료 ì—°ë„를 입력하세요.</translation>
<translation id="2212735316055980242">ì •ì±…ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ</translation>
<translation id="2213606439339815911">í•­ëª©ì„ ê°€ì ¸ì˜¤ëŠ” 중...</translation>
+<translation id="2218879909401188352">현재 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì— ìžˆëŠ” 공격ìžëŠ” 기기를 ì†ìƒì‹œí‚¤ê±°ë‚˜, ëª¨ë°”ì¼ ìš”ê¸ˆì— ëª°ëž˜ 추가 ìš”ê¸ˆì„ ë¶€ê³¼í•˜ê±°ë‚˜, ê°œì¸ì •ë³´ë¥¼ ë„용하는 위험한 ì•±ì„ ì„¤ì¹˜í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />진단 앱<ph name="END_LINK" />ì„ ì‚¬ìš©í•˜ì—¬ ì—°ê²° 문제를 해결하세요.</translation>
<translation id="2239100178324503013">지금 보내기</translation>
<translation id="225207911366869382">ì´ ê°’ì€ ì´ ì •ì±…ì— ì‚¬ìš©ë˜ì§€ 않습니다.</translation>
<translation id="2262243747453050782">HTTP 오류</translation>
+<translation id="2270484714375784793">전화번호</translation>
<translation id="2282872951544483773">사용할 수 없는 실험</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{항목 <ph name="ITEM_COUNT" />개}other{항목 <ph name="ITEM_COUNT" />개}}</translation>
<translation id="2292556288342944218">ì¸í„°ë„· 액세스가 차단ë¨</translation>
<translation id="230155334948463882">새 ì¹´ë“œì¸ê°€ìš”?</translation>
-<translation id="2305919008529760154">서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. 보안 ì¸ì¦ì„œê°€ 부정한 ë°©ì‹ìœ¼ë¡œ 발급ë˜ì—ˆì„ 수 있습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" />ì— ì‚¬ìš©ìž ì´ë¦„ê³¼ 비밀번호를 입력해야 합니다.</translation>
-<translation id="2318774815570432836"><ph name="SITE" />ì—ì„œ HSTS를 사용하고 있기 ë•Œë¬¸ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ìž ì‹œ 후 페ì´ì§€ê°€ ì •ìƒí™”ë  ê²ƒìž…ë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">관리ìžê°€ 제어하는 설정</translation>
<translation id="2354001756790975382">기타 ë¶ë§ˆí¬</translation>
+<translation id="2354430244986887761">Google 세ì´í”„ 브ë¼ìš°ì§•ì´ 최근 <ph name="SITE" />ì—ì„œ <ph name="BEGIN_LINK" />유해한 ì•±ì„ ë°œê²¬<ph name="END_LINK" />했습니다.</translation>
<translation id="2355395290879513365">공격ìžëŠ” 사용ìžê°€ ì´ ì‚¬ì´íŠ¸ì—ì„œ ë³´ê³  있는 ì´ë¯¸ì§€ë¥¼ ë³¼ 수 있으며 ì´ë¯¸ì§€ë¥¼ 수정하여 사용ìžë¥¼ ì†ì¼ 수 있습니다.</translation>
+<translation id="2356070529366658676">확ì¸</translation>
+<translation id="2359629602545592467">복수</translation>
<translation id="2359808026110333948">계ì†</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" />ì— ìº¡ì²˜ëœ ë¹„ì •ìƒ ì¢…ë£Œ 보고서가 업로드ë˜ì§€ 않았습니다.</translation>
<translation id="2367567093518048410">수준</translation>
-<translation id="2371153335857947666">{1,plural, =1{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ ì–´ì œ 만료ë˜ì–´ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. 현재 ì»´í“¨í„°ì˜ ì‹œê³„ê°€ <ph name="CURRENT_DATE" />ë¡œ 설정ë˜ì–´ 있습니다. ì‹œê°„ì´ ì •í™•í•˜ì§€ 않으면 시스템 시계를 수정한 ë’¤ ì´ íŽ˜ì´ì§€ë¥¼ 새로고침하세요. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" />}other{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ #ì¼ ì „ì— ë§Œë£Œë˜ì–´ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. 현재 ì»´í“¨í„°ì˜ ì‹œê³„ê°€ <ph name="CURRENT_DATE" />ë¡œ 설정ë˜ì–´ 있습니다. ì‹œê°„ì´ ì •í™•í•˜ì§€ 않으면 시스템 시계를 수정한 ë’¤ ì´ íŽ˜ì´ì§€ë¥¼ 새로고침하세요. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">사용 가능한 대체 UI ì—†ìŒ</translation>
<translation id="2384307209577226199">엔터프ë¼ì´ì¦ˆ 기본값</translation>
<translation id="2386255080630008482">서버 ì¸ì¦ì„œê°€ í기ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="2392959068659972793">ê°’ì´ ì„¤ì •ë˜ì§€ ì•Šì€ ì •ì±… 표시</translation>
<translation id="239429038616798445">사용할 수 없는 배송 방법입니다. 다른 ë°©ë²•ì„ ì„ íƒí•˜ì„¸ìš”.</translation>
<translation id="2396249848217231973">삭제 실행 취소(&amp;U)</translation>
-<translation id="2460160116472764928">Google 세ì´í”„ 브ë¼ìš°ì§•ì´ 최근 <ph name="SITE" />ì—ì„œ <ph name="BEGIN_LINK" />멀웨어를 ê°ì§€<ph name="END_LINK" />했습니다. ì•ˆì „í•˜ë˜ ì›¹ì‚¬ì´íŠ¸ë„ ë©€ì›¨ì–´ì— ê°ì—¼ë˜ëŠ” 경우가 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ ì·¨ì†Œë  ìˆ˜ 있습니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
<translation id="2463739503403862330">ìž…ë ¥</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />ë„¤íŠ¸ì›Œí¬ ì§„ë‹¨ 프로그램 실행<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">검색 URLì´ ìž˜ëª»ë¨</translation>
+<translation id="2482878487686419369">알림</translation>
<translation id="2491120439723279231">서버 ì¸ì¦ì„œì— 오류가 있습니다.</translation>
<translation id="2495083838625180221">JSON 파서</translation>
<translation id="2495093607237746763">ì„ íƒí•˜ë©´ ì´ ê¸°ê¸°ì— ì¹´ë“œ ì‚¬ë³¸ì´ ì €ìž¥ë˜ì–´ Chromiumì—ì„œ ì–‘ì‹ì„ ë” ë¹ ë¥´ê²Œ 입력할 수 있습니다.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">뒤로 ì´ë™</translation>
<translation id="2515629240566999685">현재 ì§€ì—­ì˜ ì‹ í˜¸ 확ì¸</translation>
<translation id="2516305470678292029">대체 UI</translation>
+<translation id="2539524384386349900">ê°ì§€</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" />ì—ì„œ ìž˜ëª»ëœ ì‘ë‹µì„ ì „ì†¡í–ˆìŠµë‹ˆë‹¤.</translation>
-<translation id="2552545117464357659">ì´ì „</translation>
<translation id="2556876185419854533">수정 실행 취소(&amp;U)</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" />ì—ì„œ 제공한 기사입니다. <ph name="OTHER_ARTICLE_COUNT" />ê°œì˜ ë‹¤ë¥¸ ë‰´ìŠ¤ë„ ì½ì–´ 보세요.</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">문서가 비밀번호로 보호ë˜ê³  있습니다. 비밀번호를 입력하세요.</translation>
<translation id="2609632851001447353">유사 버전</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{ì—†ìŒ}=1{앱 1ê°œ($1)}=2{앱 2ê°œ($1, $2)}other{앱 #ê°œ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">ì‹œê°„ì´ ë„ˆë¬´ 먼 미래로 설정ë˜ì–´ 있습니다.</translation>
<translation id="2639739919103226564">ìƒíƒœ:</translation>
+<translation id="2649204054376361687"><ph name="COUNTRY" />, <ph name="CITY" /></translation>
<translation id="2650446666397867134">íŒŒì¼ ì•¡ì„¸ìŠ¤ 거부ë¨</translation>
<translation id="2653659639078652383">제출</translation>
<translation id="2666117266261740852">다른 탭 ë˜ëŠ” 앱 닫기</translation>
+<translation id="2670429602441959756">ì´ íŽ˜ì´ì§€ì—는 ì•„ì§ VRì—ì„œ 지ì›ë˜ì§€ 않는 ê¸°ëŠ¥ì´ ìžˆìŠµë‹ˆë‹¤. 종료합니다...</translation>
<translation id="2674170444375937751">방문 기ë¡ì—ì„œ ì´ íŽ˜ì´ì§€ë¥¼ 삭제하시겠습니까?</translation>
<translation id="2677748264148917807">나가기</translation>
-<translation id="269990154133806163">서버ì—ì„œ ì¸ì¦ì„œ 투명성 ì •ì±…ì„ ì‚¬ìš©í•˜ì—¬ ê³µê°œëœ ì¸ì¦ì„œê°€ ì•„ë‹Œ 다른 비공개 ì¸ì¦ì„œë¥¼ 제시했습니다. ì¸ì¦ì„œ 투명성 ì •ì±…ì€ ì¸ì¦ì„œê°€ 신뢰할 수 있으며 공격ìžë¡œë¶€í„° 사용ìžë¥¼ 보호하고 있ìŒì„ 보장하기 위한 것으로 ì¼ë¶€ ì¸ì¦ì„œì˜ 경우 필수사항입니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">ì½ê¸° 목ë¡</translation>
<translation id="2704283930420550640">ê°’ì´ í˜•ì‹ê³¼ ì¼ì¹˜í•˜ì§€ 않습니다.</translation>
<translation id="2704951214193499422">현재 Chromiumì—ì„œ 카드를 확ì¸í•  수 없습니다. ë‚˜ì¤‘ì— ë‹¤ì‹œ ì‹œë„í•´ 주세요.</translation>
<translation id="2705137772291741111">사ì´íŠ¸ì˜ 저장ëœ(ìºì‹œëœ) ì‚¬ë³¸ì„ ì½ì„ 수 없습니다.</translation>
<translation id="2709516037105925701">ìžë™ì™„성</translation>
-<translation id="2712118517637785082"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했으나 발행기관ì—ì„œ 서버가 제시한 ì¸ì¦ì„œë¥¼ í기했습니다. ì´ëŠ” 서버가 제시한 보안 ìžê²©ì¦ëª… 정보는 절대 신뢰할 수 ì—†ìŒì„ ì˜ë¯¸í•©ë‹ˆë‹¤. 현재 해커와 통신 ì¤‘ì¼ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">권한 요청</translation>
<translation id="2713444072780614174">í°ìƒ‰</translation>
<translation id="2720342946869265578">근처</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">기기 ê¸°ë¡ ì—†ìŒ</translation>
<translation id="2784949926578158345">ì—°ê²°ì´ ìž¬ì„¤ì •ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="2794233252405721443">ì°¨ë‹¨ëœ ì‚¬ì´íŠ¸</translation>
+<translation id="2799020568854403057">방문하려는 사ì´íŠ¸ì— 유해한 ì•±ì´ ìžˆìŠµë‹ˆë‹¤.</translation>
+<translation id="2803306138276472711">최근 Google 세ì´í”„ 브ë¼ìš°ì§•ì´ <ph name="SITE" />ì—ì„œ <ph name="BEGIN_LINK" />멀웨어를 ê°ì§€<ph name="END_LINK" />했습니다. í‰ì†Œì— 안전한 웹사ì´íŠ¸ë„ ë©€ì›¨ì–´ì— ê°ì—¼ë  때가 있습니다.</translation>
<translation id="2824775600643448204">주소창 ë° ê²€ìƒ‰ì°½</translation>
<translation id="2826760142808435982">ì´ ì—°ê²°ì€ <ph name="CIPHER" />ì„(를) 사용하여 암호화ë˜ê³  ì¸ì¦ë˜ë©° <ph name="KX" />ì„(를) 키 êµí™˜ 매커니즘으로 사용합니다.</translation>
<translation id="2835170189407361413">ì„œì‹ ì§€ìš°ê¸°</translation>
+<translation id="2856444702002559011">해커가 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì—ì„œ ì •ë³´(예: 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ 등)를 ë„용하려고 ì‹œë„ ì¤‘ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">새로고침 안함</translation>
<translation id="2900469785430194048">ì´ ì›¹íŽ˜ì´ì§€ë¥¼ 표시하려고 했으나 Chrome 메모리가 부족합니다.</translation>
<translation id="2909946352844186028">ë„¤íŠ¸ì›Œí¬ ë³€ê²½ì´ ê°ì§€ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="2916038427272391327">다른 프로그램 닫기</translation>
<translation id="2922350208395188000">서버 ì¸ì¦ì„œë¥¼ 확ì¸í•  수 없습니다.</translation>
<translation id="2928905813689894207">청구서 수신 주소</translation>
+<translation id="2941952326391522266">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ <ph name="DOMAIN2" />ì—ì„œ 제공한 것입니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
<translation id="2948083400971632585">설정 페ì´ì§€ì˜ ì—°ê²°ì„ êµ¬ì„±í•˜ëŠ” 프ë¡ì‹œë¥¼ 사용 중지할 수 있습니다.</translation>
<translation id="2955913368246107853">검색 바 닫기</translation>
<translation id="2958431318199492670">ë„¤íŠ¸ì›Œí¬ ì„¤ì •ì´ ONC í‘œì¤€ì„ ì¤€ìˆ˜í•˜ì§€ 않습니다. ì¼ë¶€ ì„¤ì •ì„ ê°€ì ¸ì˜¬ 수 없습니다.</translation>
-<translation id="29611076221683977">현재 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì˜ ê³µê²©ìžê°€ ì‚¬ìš©ìž ì •ë³´(예: 사진, 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ)를 ë„용하거나 삭제하는 위험한 í”„ë¡œê·¸ëž¨ì„ Macì— ì„¤ì¹˜í•˜ë ¤ê³  ì‹œë„í•  수 있습니다.</translation>
<translation id="2966678944701946121">만료: <ph name="EXPIRATION_DATE_ABBR" />, 추가ì¼: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">보안 ì—°ê²°ì„ ì„¤ì •í•˜ë ¤ë©´ 시계가 올바로 설정ë˜ì–´ 있어야 합니다. 웹사ì´íŠ¸ê°€ ìžì‹ ì„ ì‹ë³„하는 ë° ì‚¬ìš©í•˜ëŠ” ì¸ì¦ì„œëŠ” 특정 기간ì—만 유효하기 때문입니다. ê¸°ê¸°ì˜ ì‹œê³„ê°€ 잘못 설정ë˜ì–´ Chromeì—ì„œ ì´ ì¸ì¦ì„œë¥¼ 확ì¸í•  수 없습니다.</translation>
<translation id="2972581237482394796">다시 실행(&amp;R)</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">올바른 주소를 입력하세요.</translation>
<translation id="2986368408720340940">사용할 수 없는 수령 방법입니다. 다른 ë°©ë²•ì„ ì„ íƒí•˜ì„¸ìš”.</translation>
<translation id="2991174974383378012">웹사ì´íŠ¸ì™€ 공유</translation>
+<translation id="2991571918955627853">웹사ì´íŠ¸ì—ì„œ HSTS를 사용하므로 ì§€ê¸ˆì€ <ph name="SITE" />ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ì²´ë¡œ ì¼ì‹œì ì¸ 문제ì´ê¸° ë•Œë¬¸ì— ë‚˜ì¤‘ì— ì´ íŽ˜ì´ì§€ê°€ ì •ìƒì ìœ¼ë¡œ ìž‘ë™í•  수 있습니다.</translation>
<translation id="3005723025932146533">ì €ìž¥ëœ ì‚¬ë³¸ 표시</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> ì¹´ë“œì˜ CVC를 입력하세요. 카드를 확ì¸í•˜ë©´ ì¹´ë“œ 세부정보가 ì´ ì‚¬ì´íŠ¸ì™€ 공유ë©ë‹ˆë‹¤.</translation>
<translation id="3010559122411665027">ëª©ë¡ í•­ëª© '<ph name="ENTRY_INDEX" />': <ph name="ERROR" /></translation>
+<translation id="301521992641321250">ìžë™ìœ¼ë¡œ 차단ë¨</translation>
<translation id="3024663005179499861">ìž˜ëª»ëœ ì •ì±… 유형</translation>
<translation id="3032412215588512954">ì´ ì‚¬ì´íŠ¸ë¥¼ 새로고침하시겠습니까?</translation>
<translation id="3037605927509011580">ì•—, ì´ëŸ°!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{ë™ê¸°í™”ëœ ê¸°ê¸°ì— ìµœì†Œ 1ê°œ}=1{1ê°œ(ë™ê¸°í™”ëœ ê¸°ê¸°ì—는 ê·¸ ì´ìƒ)}other{#ê°œ(ë™ê¸°í™”ëœ ê¸°ê¸°ì—는 ê·¸ ì´ìƒ)}}</translation>
<translation id="3041612393474885105">ì¸ì¦ì„œ ì •ë³´</translation>
<translation id="3063697135517575841">현재 Chromeì—ì„œ 카드를 확ì¸í•  수 없습니다. ë‚˜ì¤‘ì— ë‹¤ì‹œ ì‹œë„í•´ 주세요.</translation>
<translation id="3064966200440839136">ì‹œí¬ë¦¿ 모드를 종료하고 외부 애플리케ì´ì…˜ì—ì„œ 결제합니다. 계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{ì—†ìŒ}=1{비밀번호 1ê°œ}other{비밀번호 #ê°œ}}</translation>
<translation id="3093245981617870298">오프ë¼ì¸ ìƒíƒœìž…니다.</translation>
<translation id="3105172416063519923">ì• ì…‹ ID:</translation>
<translation id="3109728660330352905">ì´ íŽ˜ì´ì§€ë¥¼ ë³¼ 수 있는 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />ì—°ê²° 진단 í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰<ph name="END_LINK" />í•´ 보세요.</translation>
<translation id="3145945101586104090">ì‘답 디코딩 실패</translation>
<translation id="3150653042067488994">ì¼ì‹œì ì¸ 서버 오류</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">ì‹œí¬ë¦¿ íƒ­ì„ ëª¨ë‘ ë‹«ìœ¼ë©´ ì‹œí¬ë¦¿ 탭ì—ì„œ 보는 페ì´ì§€ëŠ” 브ë¼ìš°ì €ì˜ 방문 기ë¡, 쿠키 저장소, 검색 ê¸°ë¡ ì–´ë””ì—ë„ ë‚¨ì§€ 않습니다. 단, 다운로드한 파ì¼ì´ë‚˜ ìƒì„±í•œ ë¶ë§ˆí¬ëŠ” 유지ë©ë‹ˆë‹¤.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">섬</translation>
+<translation id="317583078218509884">새 사ì´íŠ¸ 권한 ì„¤ì •ì€ íŽ˜ì´ì§€ë¥¼ 새로고침한 다ìŒì— ì ìš©ë©ë‹ˆë‹¤.</translation>
<translation id="3176929007561373547">프ë¡ì‹œ ì„¤ì •ì„ í™•ì¸í•˜ê±°ë‚˜ ë„¤íŠ¸ì›Œí¬ ê´€ë¦¬ìžì—게 문ì˜í•˜ì—¬
프ë¡ì‹œ 서버가 ìž‘ë™í•˜ëŠ”지 확ì¸í•˜ì„¸ìš”. 프ë¡ì‹œ 서버를 사용하지 않으려면
ë‹¤ìŒ ë‹¨ê³„ë¥¼ 따르세요.
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">ì‹œí¬ë¦¿ 모드ì—ì„œ 페ì´ì§€ 열기</translation>
-<translation id="3202578601642193415">최근</translation>
+<translation id="320323717674993345">결제 취소</translation>
<translation id="3207960819495026254">ë¶ë§ˆí¬ë¨</translation>
+<translation id="3225919329040284222">서버가 ë‚´ìž¥ëœ ê¸°ëŒ€ì¹˜ì™€ ì¼ì¹˜í•˜ì§€ 않는 ì¸ì¦ì„œë¥¼ 전달했습니다. ì´ëŸ¬í•œ 기대치는 사용ìžë¥¼ 보호하기 위해 ë³´ì•ˆì´ ì—„ê²©í•œ 특정 웹사ì´íŠ¸ì— í¬í•¨ë©ë‹ˆë‹¤.</translation>
<translation id="3226128629678568754">페ì´ì§€ ë¡œë“œì— í•„ìš”í•œ ë°ì´í„°ë¥¼ 다시 제출하려면 새로고침 ë²„íŠ¼ì„ ëˆ„ë¦…ë‹ˆë‹¤.</translation>
+<translation id="3227137524299004712">마ì´í¬</translation>
<translation id="3228969707346345236">페ì´ì§€ê°€ <ph name="LANGUAGE" />(으)ë¡œ ë˜ì–´ 있으므로 번역하지 못했습니다.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> ì¹´ë“œì˜ CVC를 입력하세요.</translation>
+<translation id="3234666976984236645">ì´ ì‚¬ì´íŠ¸ì—ì„œ 중요한 콘í…츠 í•­ìƒ ê°ì§€</translation>
<translation id="3254409185687681395">현재 페ì´ì§€ë¥¼ ë¶ë§ˆí¬ì— 추가</translation>
<translation id="3270847123878663523">재정렬 실행 취소(&amp;U)</translation>
<translation id="3282497668470633863">ì¹´ë“œ ëª…ì˜ ì¶”ê°€</translation>
@@ -270,45 +304,51 @@
<translation id="3340978935015468852">설정</translation>
<translation id="3345135638360864351">ì´ ì‚¬ì´íŠ¸ì— 대한 액세스 ìš”ì²­ì„ <ph name="NAME" />님ì—게 보내지 못했습니다. ë‚˜ì¤‘ì— ë‹¤ì‹œ ì‹œë„í•´ 주세요.</translation>
<translation id="3355823806454867987">프ë¡ì‹œ 설정 변경...</translation>
+<translation id="3361596688432910856">Chromeì— ë‹¤ìŒ ì •ë³´ê°€ <ph name="BEGIN_EMPHASIS" />저장ë˜ì§€ 않습니다<ph name="END_EMPHASIS" />.
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />방문 기ë¡
+ <ph name="LIST_ITEM" />쿠키 ë° ì‚¬ì´íŠ¸ ë°ì´í„°
+ <ph name="LIST_ITEM" />ì–‘ì‹ì— 입력한 ì •ë³´
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">시계 오류</translation>
-<translation id="337311366426640088">항목 <ph name="ITEM_COUNT" />ê°œ ë”보기...</translation>
<translation id="337363190475750230">사용 중단ë¨</translation>
<translation id="3377188786107721145">정책 파싱 오류</translation>
<translation id="3380365263193509176">ì•Œ 수 없는 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="3380864720620200369">í´ë¼ì´ì–¸íŠ¸ ID:</translation>
<translation id="3391030046425686457">배송지 주소</translation>
<translation id="3395827396354264108">수령 방법</translation>
-<translation id="340013220407300675">공격ìžê°€ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì—ì„œ 사용ìžì˜ 정보를 ë„용하려고 ì‹œë„í•  수 있습니다(예: 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ ì •ë³´).</translation>
<translation id="3422248202833853650">다른 í”„ë¡œê·¸ëž¨ì„ ì¢…ë£Œí•˜ì—¬ 메모리를 확보하세요.</translation>
<translation id="3422472998109090673">현재 <ph name="HOST_NAME" />ì— ì—°ê²°í•  수 없습니다.</translation>
+<translation id="3427092606871434483">허용(기본값)</translation>
<translation id="3427342743765426898">수정 다시 실행(&amp;R)</translation>
<translation id="3431636764301398940">ê¸°ê¸°ì— ì¹´ë“œ 저장</translation>
<translation id="3435896845095436175">사용</translation>
<translation id="3447661539832366887">ì´ ê¸°ê¸°ì˜ ì†Œìœ ìžê°€ 공룡 ê²Œìž„ì„ ì‚¬ìš© 중지했습니다.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">가져오기 간격:</translation>
<translation id="3462200631372590220">세부정보 숨기기</translation>
<translation id="3467763166455606212">ì¹´ë“œ ì†Œìœ ìž ì´ë¦„ì„ ìž…ë ¥í•´ì•¼ 합니다.</translation>
<translation id="3478058380795961209">만료 월</translation>
<translation id="3479539252931486093">예기치 ì•Šì€ ë¬¸ì œê°€ ë°œìƒí–ˆë‚˜ìš”? <ph name="BEGIN_LINK" />Googleì— ì•Œë¦¬ê¸°<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">나중ì—</translation>
-<translation id="348000606199325318">ë¹„ì •ìƒ ì¢…ë£Œ ID <ph name="CRASH_LOCAL_ID" />(서버 ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">현재 부모님께 ì—°ë½í•  수 없습니다. ë‚˜ì¤‘ì— ë‹¤ì‹œ ì‹œë„í•´ 주세요.</translation>
<translation id="3528171143076753409">ì„œë²„ì˜ ì¸ì¦ì„œë¥¼ 신뢰할 수 없습니다.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{ë™ê¸°í™”ëœ ê¸°ê¸°ì— í•­ëª© 1ê°œ ì´ìƒ}=1{항목 1ê°œ(ë™ê¸°í™”ëœ ê¸°ê¸°ì—는 ê·¸ ì´ìƒ)}other{항목 #ê°œ(ë™ê¸°í™”ëœ ê¸°ê¸°ì—는 ê·¸ ì´ìƒ)}}</translation>
<translation id="3539171420378717834">ì¹´ë“œ ì‚¬ë³¸ì„ ì´ ê¸°ê¸°ì— ì €ìž¥</translation>
<translation id="3542684924769048008">비밀번호 사용 항목:</translation>
+<translation id="3545341443414427877">ì»´í“¨í„°ì˜ ë‚ ì§œì™€ 시간(<ph name="DATE_AND_TIME" />)ì´ ìž˜ëª»ë˜ì—ˆìœ¼ë¯€ë¡œ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />ì— ë¹„ê³µê°œë¡œ ì—°ê²°í•  수 없습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">ë‚˜ë§Œì˜ ë™ê¸°í™” 암호로 모든 ë™ê¸°í™” ë°ì´í„° 암호화</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" />ê°œ ë”보기</translation>
-<translation id="3555561725129903880">보안 ì¸ì¦ì„œì˜ 출처가 <ph name="DOMAIN2" />ì´ë¯€ë¡œ 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">관리ìžê°€ 차단 해제할 수 있습니다.</translation>
<translation id="3566021033012934673">ì—°ê²°ì´ ë¹„ê³µê°œë¡œ 설정ë˜ì–´ 있지 않습니다.</translation>
+<translation id="3569145463236695319">&lt;p&gt;ê¸°ê¸°ì˜ ë‚ ì§œì™€ 시간(<ph name="DATE_AND_TIME" />)ì´ ìž˜ëª»ë˜ì—ˆìœ¼ë¯€ë¡œ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />ì— ë¹„ê³µê°œë¡œ ì—°ê²°í•  수 없습니다.&lt;/p&gt;
+
+ &lt;p&gt;&lt;strong&gt;설정&lt;/strong&gt; ì•±ì˜ &lt;strong&gt;ì¼ë°˜&lt;/strong&gt; 섹션ì—ì„œ 날짜와 ì‹œê°„ì„ ë§žì¶”ì„¸ìš”.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="COUNTRY" /> <ph name="STATE" />, <ph name="CITY" /></translation>
<translation id="3582930987043644930">ì´ë¦„ 추가</translation>
<translation id="3583757800736429874">ì´ë™ 다시 실행(&amp;R)</translation>
<translation id="3586931643579894722">세부정보 숨기기</translation>
-<translation id="3587482841069643663">ì „ì²´</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">올바른 만료ì¼ì„ 입력하세요.</translation>
-<translation id="36224234498066874">ì¸í„°ë„· 사용정보 ì‚­ì œ...</translation>
+<translation id="36224234498066874">ì¸í„°ë„· 사용 ê¸°ë¡ ì‚­ì œ...</translation>
<translation id="362276910939193118">방문 ê¸°ë¡ ì „ì²´ 보기</translation>
<translation id="3623476034248543066">값 표시</translation>
<translation id="3630155396527302611">ì´ë¯¸ ë„¤íŠ¸ì›Œí¬ ì•¡ì„¸ìŠ¤ê°€ í—ˆìš©ëœ í”„ë¡œê·¸ëž¨ìœ¼ë¡œ ë˜ì–´ 있는 경우
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">ì¸ì¦ì„œ ì •ë³´</translation>
<translation id="3690164694835360974">로그ì¸ì´ 안전하지 ì•ŠìŒ</translation>
<translation id="3693415264595406141">비밀번호:</translation>
-<translation id="3696411085566228381">ì—†ìŒ</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">로드 중...</translation>
<translation id="3712624925041724820">ë¼ì´ì„ ìŠ¤ 만료ë¨</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />프ë¡ì‹œ, 방화벽, DNS 설정 확ì¸<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">보안 관련 ìœ„í—˜ì„ ì´í•´í•œë‹¤ë©´ 위험한 í”„ë¡œê·¸ëž¨ì´ ì‚­ì œë˜ê¸° ì „ì— <ph name="BEGIN_LINK" />안전하지 ì•Šì€ ì‚¬ì´íŠ¸<ph name="END_LINK" />ì— ë°©ë¬¸í•´ë„ ë©ë‹ˆë‹¤.</translation>
<translation id="3739623965217189342">복사한 ë§í¬</translation>
+<translation id="3744899669254331632">웹사ì´íŠ¸ê°€ Chromiumì´ ì²˜ë¦¬í•  수 없는 ì•”í˜¸í™”ëœ ì‚¬ìš©ìž ì¸ì¦ 정보를 전송하였으므로 ì§€ê¸ˆì€ <ph name="SITE" />ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ì²´ë¡œ ì¼ì‹œì ì¸ 문제ì´ê¸° ë•Œë¬¸ì— ì´í›„ì—는 ì´ íŽ˜ì´ì§€ê°€ 제대로 ìž‘ë™í•  ê°€ëŠ¥ì„±ì´ ë†’ìŠµë‹ˆë‹¤.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì˜ ê³µê²©ìžê°€ 소프트웨어를 설치하거나 ê°œì¸ì •ë³´(예: 비밀번호, 전화번호, ì‹ ìš©ì¹´ë“œ)를 공개하는 ë“±ì˜ ìœ„í—˜í•œ í–‰ë™ì„ 하ë„ë¡ ì‚¬ìš©ìžë¥¼ ì†ì¼ 수 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">서버 오류가 ë°œìƒí•˜ì—¬ 번역하지 못했습니다.</translation>
<translation id="3759461132968374835">ìµœê·¼ì— ë³´ê³ ëœ ë¹„ì •ìƒ ì¢…ë£Œê°€ 없습니다. ë¹„ì •ìƒ ì¢…ë£Œ 보고를 사용 ì¤‘ì§€í–ˆì„ ë•Œ ë°œìƒí•œ ë¹„ì •ìƒ ì¢…ë£ŒëŠ” ì—¬ê¸°ì— í‘œì‹œë˜ì§€ 않습니다.</translation>
+<translation id="3778403066972421603">ì´ ì¹´ë“œë¥¼ Google 계정과 ì´ ê¸°ê¸°ì— ì €ìž¥í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">만료: <ph name="EXPIRATION_YEAR" />년 <ph name="EXPIRATION_MONTH" />월</translation>
<translation id="382518646247711829">프ë¡ì‹œ 서버를 사용하는 경우</translation>
<translation id="3828924085048779000">암호를 빈 칸으로 ë‘어서는 안 ë©ë‹ˆë‹¤.</translation>
-<translation id="3845539888601087042">로그ì¸í•œ ê¸°ê¸°ì˜ ë°©ë¬¸ 기ë¡ì„ 표시합니다. <ph name="BEGIN_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LINK" /></translation>
<translation id="385051799172605136">뒤로</translation>
<translation id="3858027520442213535">시간과 날짜 ì—…ë°ì´íŠ¸</translation>
<translation id="3884278016824448484">기기 ì‹ë³„ìž ì¶©ëŒ</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">사용ìžì˜ 사ì´íŠ¸ 액세스 ìš”ì²­ì´ <ph name="NAME" />님ì—게 전송ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="3890664840433101773">ì´ë©”ì¼ ì¶”ê°€</translation>
<translation id="3901925938762663762">ë§Œë£Œëœ ì¹´ë“œìž…ë‹ˆë‹¤.</translation>
-<translation id="3933571093587347751">{1,plural, =1{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ ë‚´ì¼ë¶€í„° 유효하므로 현재 <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" />}other{ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ #ì¼ í›„ë¶€í„° 유효하므로 현재 <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">PDF 문서를 로드하지 못했습니다.</translation>
+<translation id="3945915738023014686">ë¹„ì •ìƒ ì¢…ë£Œ ë³´ê³ ì„œ ID <ph name="CRASH_ID" /> 업로드ë¨(로컬 ë¹„ì •ìƒ ì¢…ë£Œ ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">보안 ì¸ì¦ì„œì— 주체 대체 ì´ë¦„(SAN)ì´ ì§€ì •ë˜ì–´ 있지 ì•Šì•„ ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. 서버를 잘못 설정했거나 공격ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤.</translation>
<translation id="3963721102035795474">ë¦¬ë” ëª¨ë“œ</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{ì—†ìŒ}=1{사ì´íŠ¸ 1ê°œ }other{사ì´íŠ¸ #ê°œ }}</translation>
<translation id="397105322502079400">계산 중...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" />ì´(ê°€) 차단ë¨</translation>
+<translation id="3987940399970879459">1MB 미만</translation>
<translation id="40103911065039147">{URL_count,plural, =1{주변 웹페ì´ì§€ 1ê°œ}other{주변 웹페ì´ì§€ #ê°œ}}</translation>
<translation id="4021036232240155012">DNS는 웹사ì´íŠ¸ ì´ë¦„ì„ ì¸í„°ë„· 주소로 변환하는 ë„¤íŠ¸ì›Œí¬ ì„œë¹„ìŠ¤ìž…ë‹ˆë‹¤.</translation>
<translation id="4030383055268325496">추가 실행 취소(&amp;U)</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">프ë¡ì‹œ ì„¤ì •ì´ ê³ ì • 프ë¡ì‹œ 서버가 ì•„ë‹Œ .pac 스í¬ë¦½íŠ¸ URLì„ ì‚¬ìš©í•˜ë„ë¡ ì„¤ì •ë©ë‹ˆë‹¤.</translation>
<translation id="4098354747657067197">사기성 사ì´íŠ¸ 주ì˜</translation>
<translation id="4103249731201008433">기기 ì¼ë ¨ë²ˆí˜¸ê°€ 잘못ë¨</translation>
+<translation id="410351446219883937">ìžë™ìž¬ìƒ</translation>
<translation id="4103763322291513355">ì°¨ë‹¨ëœ URL ë° ì‹œìŠ¤í…œ 관리ìžê°€ 설정한 기타 ì •ì±… 목ë¡ì„ 확ì¸í•˜ë ¤ë©´ &lt;strong&gt;chrome://policy&lt;/strong&gt;를 방문하세요.</translation>
-<translation id="4110615724604346410">보안 ì¸ì¦ì„œì— 오류가 있어서 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">ìží™ìƒ‰</translation>
+<translation id="4116663294526079822">ì´ ì‚¬ì´íŠ¸ì—ì„œ í•­ìƒ í—ˆìš©</translation>
<translation id="4117700440116928470">지ì›ë˜ì§€ 않는 ì •ì±… 범위입니다.</translation>
-<translation id="4118212371799607889">Chromiumì—ì„œ 신뢰하지 않는 기관ì—ì„œ 발행한 ì¸ì¦ì„œë¥¼ 제공하여 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{외 1개}other{외 #개}}</translation>
<translation id="4130226655945681476">ë„¤íŠ¸ì›Œí¬ ì¼€ì´ë¸”, 모뎀, ë¼ìš°í„° 확ì¸</translation>
+<translation id="413544239732274901">ìžì„¸ížˆ 알아보기</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">글로벌 기본값 사용(ê°ì§€)</translation>
+<translation id="4165986682804962316">사ì´íŠ¸ 설정</translation>
<translation id="4169947484918424451">Chromiumì—ì„œ ì´ ì¹´ë“œë¥¼ 저장하ë„ë¡ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</translation>
<translation id="4171400957073367226">ìž˜ëª»ëœ ì¸ì¦ 서명입니다.</translation>
<translation id="4196861286325780578">ì´ë™ 다시 실행(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />방화벽 ë° ë°”ì´ëŸ¬ìŠ¤ 백신 소프트웨어 설정 확ì¸<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ì—†ìŒ}=1{앱 1ê°œ($1)}=2{앱 2ê°œ($1, $2)}other{앱 #ê°œ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">ë¹„ì •ìƒ ì¢…ë£Œ</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì— ìžˆëŠ” 공격ìžê°€ 브ë¼ìš°ì € í™˜ê²½ì— ì•…ì˜í–¥ì„ 미치는 í”„ë¡œê·¸ëž¨ì„ ì„¤ì¹˜í•˜ë„ë¡ ì†ìž„수(예: 방문하는 사ì´íŠ¸ì˜ 홈페ì´ì§€ë¥¼ 변경하거나 추가로 광고를 표시)를 ì‹œë„í•  수 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />ë„¤íŠ¸ì›Œí¬ ì§„ë‹¨ í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰<ph name="END_LINK" />í•´ 보세요.</translation>
+<translation id="4235360514405112390">유효</translation>
<translation id="4250431568374086873">ì´ ì‚¬ì´íŠ¸ì— 대한 ì—°ê²°ì€ ì™„ë²½í•˜ê²Œ ë³´ì•ˆì´ ë˜ì§€ 않습니다.</translation>
<translation id="4250680216510889253">아니요</translation>
<translation id="425582637250725228">ë³€ê²½ì‚¬í•­ì´ ì €ìž¥ë˜ì§€ ì•Šì„ ìˆ˜ 있습니다.</translation>
<translation id="4258748452823770588">ìž˜ëª»ëœ ì„œëª…</translation>
+<translation id="4265872034478892965">관리ìžê°€ 허용함</translation>
<translation id="4269787794583293679">(ì‚¬ìš©ìž ì´ë¦„ ì—†ìŒ)</translation>
<translation id="4275830172053184480">기기 다시 시작</translation>
<translation id="4280429058323657511">, ë§Œë£Œì¼ <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google 세ì´í”„ 브ë¼ìš°ì§•ì´ ìµœê·¼ì— <ph name="SITE" />ì—ì„œ <ph name="BEGIN_LINK" />유해한 í”„ë¡œê·¸ëž¨ì„ ì°¾ì•˜ìŠµë‹ˆë‹¤<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">ìƒìœ„ 추천</translation>
<translation id="4304224509867189079">로그ì¸</translation>
-<translation id="432290197980158659">서버가 ë‚´ìž¥ëœ ê¸°ì¤€ì— ì¼ì¹˜í•˜ì§€ 않는 ì¸ì¦ì„œë¥¼ 제시했습니다. ì´ëŸ¬í•œ ê¸°ì¤€ì€ ë³´ì•ˆì´ ì—„ê²©í•œ 특정 웹사ì´íŠ¸ì—ì„œ 사용ìžë¥¼ 보호하기 위해 ì ìš©ë©ë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">차단(기본값)</translation>
<translation id="4325863107915753736">ë„움ë§ì„ 찾지 못했습니다.</translation>
<translation id="4326324639298822553">만료ì¼ì„ 확ì¸í•œ 후 다시 ì‹œë„í•´ 주세요.</translation>
<translation id="4331708818696583467">안전하지 ì•ŠìŒ</translation>
<translation id="4356973930735388585">ì´ ì‚¬ì´íŠ¸ì˜ 공격ìžê°€ ì‚¬ìš©ìž ì •ë³´(예: 사진, 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ)를 ë„용하거나 삭제하는 위험한 í”„ë¡œê·¸ëž¨ì„ ì»´í“¨í„°ì— ì„¤ì¹˜í•˜ë ¤ê³  ì‹œë„í•  수 있습니다.</translation>
<translation id="4372948949327679948">ì˜ˆìƒ <ph name="VALUE_TYPE" /> 값입니다.</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했으나 발행기관ì—ì„œ 서버가 전달한 ì¸ì¦ì„œë¥¼ í기했습니다. ì´ëŠ” 서버가 제시한 보안 ìžê²©ì¦ëª… 정보를 신뢰할 수 ì—†ìŒì„ ì˜ë¯¸í•©ë‹ˆë‹¤. 사용ìžëŠ” 현재 공격ìžì™€ 통신 ì¤‘ì¼ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤.</translation>
<translation id="4381091992796011497">ì‚¬ìš©ìž ì´ë¦„:</translation>
<translation id="4394049700291259645">사용 중지</translation>
<translation id="4406896451731180161">검색결과</translation>
+<translation id="4424024547088906515">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 Chromeì—ì„œ 신뢰하는 보안 ì¸ì¦ì„œê°€ 아닙니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" />ì—ì„œ ë¡œê·¸ì¸ ì¸ì¦ì„œë¥¼ 승ì¸í•˜ì§€ 않았거나 ë¡œê·¸ì¸ ì¸ì¦ì„œê°€ 제공ë˜ì§€ ì•Šì•˜ì„ ìˆ˜ 있습니다.</translation>
<translation id="443673843213245140">프ë¡ì‹œ ì‚¬ìš©ì€ ì¤‘ì§€ë˜ì—ˆì§€ë§Œ ëª…ì‹œì  í”„ë¡ì‹œ ì„¤ì •ì´ ì§€ì •ë˜ì–´ 있습니다.</translation>
-<translation id="4492190037599258964">'<ph name="SEARCH_STRING" />'ì— ëŒ€í•œ 검색결과</translation>
<translation id="4506176782989081258">유효성 검사 오류 <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">시스템 관리ìžì—게 문ì˜</translation>
<translation id="450710068430902550">관리ìžì™€ 공유</translation>
<translation id="4515275063822566619">카드와 주소는 Chrome ë° Google 계정(<ph name="ACCOUNT_EMAIL" />)ì—ì„œ 가져왔습니다. ì´ ì •ë³´ëŠ” <ph name="BEGIN_LINK" />설정<ph name="END_LINK" />ì—ì„œ 관리할 수 있습니다.</translation>
<translation id="4522570452068850558">세부정보</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">확장 프로그램 사용 중지해 보기</translation>
<translation id="457875822857220463">배송</translation>
<translation id="4587425331216688090">Chromeì—ì„œ 주소를 삭제하시겠습니까?</translation>
-<translation id="4589078953350245614"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ê³  ì‹œë„했지만 서버ì—ì„œ ìž˜ëª»ëœ ì¸ì¦ì„œë¥¼ 제시했습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459"><ph name="DOMAIN" />ì— ëŒ€í•œ ì—°ê²°ì€ ìµœì‹  암호화 ê¸°ìˆ ì„ ì‚¬ìš©í•˜ì—¬ 암호화ë©ë‹ˆë‹¤.</translation>
<translation id="4594403342090139922">삭제 실행 취소(&amp;U)</translation>
<translation id="4619615317237390068">다른 ê¸°ê¸°ì˜ íƒ­</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œì— 오류가 있습니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
+<translation id="4690462567478992370">유효하지 ì•Šì€ ì¸ì¦ì„œ 사용 중단</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">ì—°ê²°ì´ ëŠê¹€</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows ë„¤íŠ¸ì›Œí¬ ì§„ë‹¨ 프로그램 실행<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">ì•Œ 수 없는 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="4800132727771399293">유효기간과 CVC를 확ì¸í•œ 후 다시 ì‹œë„í•´ 주세요.</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">현재 <ph name="SITE" />ì—ì„œ Chromeì´ ì²˜ë¦¬í•  수 없는 ì•”í˜¸í™”ëœ ìžê²©ì¦ëª… 정보를 전송했기 ë•Œë¬¸ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ìž ì‹œ 후 페ì´ì§€ê°€ ì •ìƒí™”ë  ê²ƒìž…ë‹ˆë‹¤.</translation>
<translation id="4813512666221746211">ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜</translation>
<translation id="4816492930507672669">페ì´ì§€ 맞춤</translation>
<translation id="483020001682031208">표시할 피지컬 웹 페ì´ì§€ê°€ 없습니다.</translation>
<translation id="4850886885716139402">보기</translation>
<translation id="4854362297993841467">사용할 수 없는 배달 방법입니다. 다른 ë°©ë²•ì„ ì„ íƒí•˜ì„¸ìš”.</translation>
<translation id="4858792381671956233">ì´ ì‚¬ì´íŠ¸ë¥¼ ë°©ë¬¸í•´ë„ ê´œì°®ì€ì§€ 부모님께 문ì˜í–ˆìŠµë‹ˆë‹¤.</translation>
+<translation id="4863764087567530506">ì´ ì½˜í…츠는 사용ìžë¥¼ ì†ì—¬ 소프트웨어를 설치하거나 ê°œì¸ì •ë³´ë¥¼ 유출할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. <ph name="BEGIN_LINK" />표시하기<ph name="END_LINK" /></translation>
<translation id="4880827082731008257">ê¸°ë¡ ê²€ìƒ‰</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{외 웹페ì´ì§€ 1ê°œ}other{외 웹페ì´ì§€ #ê°œ}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">페ì´ì§€ê°€ ì•Œ 수 없는 언어ì—ì„œ <ph name="LANGUAGE_LANGUAGE" />(으)ë¡œ 번역ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="4923459931733593730">결제</translation>
<translation id="4926049483395192435">지정해야 합니다.</translation>
<translation id="495170559598752135">ìž‘ì—…</translation>
<translation id="4958444002117714549">펼치기 목ë¡</translation>
-<translation id="4962322354953122629">Chromeì—ì„œ 신뢰하지 않는 기관ì—ì„œ 발행한 ì¸ì¦ì„œë¥¼ 제공하여 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">경고 다시 사용</translation>
<translation id="4989809363548539747">ì´ í”ŒëŸ¬ê·¸ì¸ì€ 지ì›ë˜ì§€ 않습니다.</translation>
<translation id="5002932099480077015">ì„ íƒí•˜ë©´ Chromeì—ì„œ ì–‘ì‹ì„ ë” ë¹ ë¥´ê²Œ 작성할 수 있ë„ë¡ ì´ ê¸°ê¸°ì— ì¹´ë“œ ì‚¬ë³¸ì„ ì €ìž¥í•©ë‹ˆë‹¤.</translation>
<translation id="5018422839182700155">ì´ íŽ˜ì´ì§€ë¥¼ ì—´ 수 ì—†ìŒ</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">ê´€ë¦¬ìž ì •ì±…ì„ í™•ì¸í•˜ì„¸ìš”.</translation>
<translation id="5029568752722684782">사본 지우기</translation>
<translation id="5031870354684148875">Google 번역 정보</translation>
+<translation id="5039804452771397117">허용</translation>
<translation id="5040262127954254034">ê°œì¸ì •ë³´</translation>
<translation id="5045550434625856497">비밀번호가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="5056549851600133418">추천 ë„움ë§</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />프ë¡ì‹œ 주소 확ì¸<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{쿠키를 사용하는 사ì´íŠ¸ ì—†ìŒ}=1{사ì´íŠ¸ 1ê°œì—ì„œ 쿠키를 사용합니다. }other{사ì´íŠ¸ #ê°œì—ì„œ 쿠키를 사용합니다. }}</translation>
<translation id="5087286274860437796">ì„œë²„ì˜ ì¸ì¦ì„œê°€ 현재 유효하지 않습니다.</translation>
<translation id="5087580092889165836">카드 추가</translation>
<translation id="5089810972385038852">주</translation>
+<translation id="5094747076828555589">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 Chromiumì—ì„œ 신뢰하는 보안 ì¸ì¦ì„œê°€ 아닙니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
<translation id="5095208057601539847">주/ë„</translation>
<translation id="5115563688576182185">(64비트)</translation>
<translation id="5141240743006678641">ë™ê¸°í™” 비밀번호를 Google ìžê²©ì¦ëª…으로 암호화</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">ì´ë©”ì¼ì€ 필수입니다.</translation>
<translation id="5251803541071282808">í´ë¼ìš°ë“œ</translation>
<translation id="5277279256032773186">ì§ìž¥ì—ì„œ Chromeì„ ì‚¬ìš©í•˜ì‹œë‚˜ìš”? ê¸°ì—…ì€ ì§ì›ì˜ Chrome ì„¤ì •ì„ ê´€ë¦¬í•  수 있습니다. ìžì„¸ížˆ 알아보기</translation>
+<translation id="5297526204711817721">ì´ ì‚¬ì´íŠ¸ì— 대한 ì—°ê²°ì€ ë¹„ê³µê°œê°€ 아닙니다. 언제든지 VR 모드를 종료하려면 í—¤ë“œì…‹ì„ ì œê±°í•œ 후 뒤로를 누르세요.</translation>
<translation id="5299298092464848405">ì •ì±…ì„ íŒŒì‹±í•˜ëŠ” 중 오류 ë°œìƒ</translation>
-<translation id="5300589172476337783">표시</translation>
<translation id="5308689395849655368">ë¹„ì •ìƒ ì¢…ë£Œ ë³´ê³ ê°€ 사용 중지ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="5317780077021120954">저장</translation>
<translation id="5327248766486351172">ì´ë¦„</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 공격ìžê°€ 소프트웨어를 설치하거나 ê°œì¸ì •ë³´(예: 비밀번호, 전화번호, ì‹ ìš©ì¹´ë“œ ì •ë³´)를 공개하는 ë“±ì˜ ìœ„í—˜í•œ í–‰ë™ì„ 하ë„ë¡ ì‚¬ìš©ìžë¥¼ ì†ì¼ 수 있습니다.</translation>
-<translation id="5359637492792381994">현재 ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ 유효하지 ì•Šì•„ 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">ì¸ì¦ì„œê°€ 취소ë˜ì—ˆê¸° ë•Œë¬¸ì— í˜„ìž¬ <ph name="SITE" />ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ë‚˜ì¤‘ì— ì´ íŽ˜ì´ì§€ê°€ ì •ìƒì ìœ¼ë¡œ ìž‘ë™í•  수 있습니다.</translation>
<translation id="536296301121032821">정책 설정 저장 실패</translation>
<translation id="5386426401304769735">ì´ ì‚¬ì´íŠ¸ì˜ ì¸ì¦ì„œ ì²´ì¸ì€ SHA-1ì„ ì‚¬ìš©í•˜ì—¬ ì„œëª…ëœ ì¸ì¦ì„œë¥¼ í¬í•¨í•©ë‹ˆë‹¤.</translation>
<translation id="5402410679244714488">만료: <ph name="EXPIRATION_DATE_ABBR" />, 최소 1ë…„ ì „ì— ë§ˆì§€ë§‰ìœ¼ë¡œ 사용ë¨</translation>
+<translation id="540969355065856584">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없습니다. ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ 현재 유효하지 않습니다. 서버를 잘못 설정했거나 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
<translation id="5421136146218899937">ì¸í„°ë„· 사용 ê¸°ë¡ ì‚­ì œ...</translation>
<translation id="5430298929874300616">ë¶ë§ˆí¬ ì‚­ì œ</translation>
<translation id="5431657950005405462">파ì¼ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ</translation>
-<translation id="5435775191620395718">ì´ ê¸°ê¸°ì˜ ë°©ë¬¸ 기ë¡ì„ 표시합니다. <ph name="BEGIN_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">'<ph name="ERROR_PATH" />'ì—ì„œ 스키마 유효성 검사 오류: <ph name="ERROR" /></translation>
<translation id="5452270690849572955"><ph name="HOST_NAME" /> 페ì´ì§€ë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ</translation>
<translation id="5455374756549232013">ìž˜ëª»ëœ ì •ì±… 타임스탬프</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" />/<ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">ìž˜ëª»ëœ ë°ì´í„°</translation>
<translation id="5470861586879999274">수정 다시 실행(&amp;R)</translation>
<translation id="54817484435770891">유효한 주소 추가</translation>
<translation id="5492298309214877701">회사, ì¡°ì§, í•™êµ ì¸íŠ¸ë¼ë„·ì˜ 해당 사ì´íŠ¸ê°€ 외부 웹사ì´íŠ¸ì™€ ë™ì¼í•œ URLì„ ê°–ê³  있습니다.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">ì´ ì£¼ì†Œì—ì„œ 수령할 수 없습니다. 다른 주소를 ì„ íƒí•˜ì„¸ìš”.</translation>
<translation id="5572851009514199876">ì´ ì‚¬ì´íŠ¸ì— 액세스할 수 있는지 확ì¸í•  수 있ë„ë¡ Chromeì„ ì‹œìž‘í•˜ê³  로그ì¸í•˜ì„¸ìš”.</translation>
<translation id="5580958916614886209">유효기간 ì›”ì„ í™•ì¸í•œ 후 다시 ì‹œë„í•´ 주세요.</translation>
+<translation id="5586446728396275693">ì €ìž¥ëœ ì£¼ì†Œ ì—†ìŒ</translation>
+<translation id="5595485650161345191">주소 수정</translation>
<translation id="560412284261940334">관리가 지ì›ë˜ì§€ ì•ŠìŒ</translation>
<translation id="5610142619324316209">ì—°ê²° 확ì¸</translation>
<translation id="5610807607761827392"><ph name="BEGIN_LINK" />설정<ph name="END_LINK" />ì—ì„œ 카드와 주소를 관리할 수 있습니다.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">ì´ ì‚¬ì´íŠ¸ì—ì„œ 나가시겠습니까?</translation>
<translation id="5629630648637658800">정책 설정 로드 실패</translation>
<translation id="5631439013527180824">ìž˜ëª»ëœ ê¸°ê¸° 관리 토í°</translation>
+<translation id="5633066919399395251">현재 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì˜ ê³µê²©ìžê°€ ì‚¬ìš©ìž ì •ë³´(예: 사진, 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ)를 ë„용하거나 삭제하는 위험한 í”„ë¡œê·¸ëž¨ì„ ì»´í“¨í„°ì— ì„¤ì¹˜í•˜ë ¤ê³  ì‹œë„í•  수 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">위치</translation>
+<translation id="5659593005791499971">ì´ë©”ì¼</translation>
<translation id="5669703222995421982">내게 맞는 콘í…츠 추천 받기</translation>
<translation id="5675650730144413517">페ì´ì§€ê°€ ìž‘ë™í•˜ì§€ 않습니다.</translation>
-<translation id="5677928146339483299">차단ë¨</translation>
-<translation id="5694783966845939798"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했으나 서버ì—ì„œ ì•ˆì „ì„±ì´ ë‚®ì€ ì„œëª… ì•Œê³ ë¦¬ì¦˜ì„ ì‚¬ìš©í•˜ì—¬ ì„œëª…ëœ ì¸ì¦ì„œë¥¼ 제시했습니다. ì´ëŠ” 서버ì—ì„œ 제시한 보안 ì‚¬ìš©ìž ì¸ì¦ ì •ë³´ê°€ 위조ë˜ì—ˆì„ 수 있으며 서버를 가장한 공격ìžì™€ 통신 ì¤‘ì¼ ìˆ˜ 있ìŒì„ ì˜ë¯¸í•©ë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">ì´ ì›¹ì‚¬ì´íŠ¸ì˜ 주소가 확ì¸ë˜ì§€ 않았습니다.</translation>
+<translation id="5713016350996637505">사기성 콘í…츠 차단ë¨</translation>
<translation id="5720705177508910913">현재 사용ìž</translation>
<translation id="5732392974455271431">ë¶€ëª¨ë‹˜ì´ ì°¨ë‹¨ 해제할 수 있습니다.</translation>
<translation id="5763042198335101085">올바른 ì´ë©”ì¼ ì£¼ì†Œë¥¼ 입력하세요.</translation>
<translation id="5765072501007116331">배달 방법과 ìš”êµ¬ì‚¬í•­ì„ í™•ì¸í•˜ë ¤ë©´ 주소를 ì„ íƒí•˜ì„¸ìš”.</translation>
+<translation id="5778550464785688721">MIDI 기기 전체 제어</translation>
<translation id="5784606427469807560">ì¹´ë“œ í™•ì¸ ì¤‘ì— ë¬¸ì œê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤. ì¸í„°ë„· ì—°ê²°ì„ í™•ì¸í•˜ê³  다시 ì‹œë„하세요.</translation>
<translation id="5785756445106461925">ë˜í•œ ì´ íŽ˜ì´ì§€ì—는 안전하지 ì•Šì€ ë‹¤ë¥¸ 리소스가 í¬í•¨ë˜ì–´ 있습니다. ì´ëŸ¬í•œ 리소스는 전송 ì¤‘ì— ë‹¤ë¥¸ ì‚¬ëžŒì´ ë³¼ 수 있으며 페ì´ì§€ì˜ ëª¨ì–‘ì„ ë³€ê²½í•˜ê¸° 위해 공격ìžê°€ 수정할 수 있습니다.</translation>
<translation id="5786044859038896871">카드 정보를 입력하시겠습니까?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">추가 다시 실행(&amp;R)</translation>
<translation id="5814352347845180253"><ph name="SITE" /> ë° ê¸°íƒ€ ì¼ë¶€ 사ì´íŠ¸ì˜ 프리미엄 콘í…츠를 액세스하지 못할 수 있습니다.</translation>
<translation id="5838278095973806738">공격ìžì— ì˜í•´ ë„난당할 수 있으므로 ì´ ì‚¬ì´íŠ¸ì— 비밀번호나 ì‹ ìš©ì¹´ë“œ 등 민ê°í•œ 정보를 입력해서는 안 ë©ë‹ˆë‹¤.</translation>
-<translation id="5843436854350372569"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했으나 서버가 ì•ˆì „ì„±ì´ ë‚®ì€ í‚¤ê°€ í¬í•¨ëœ ì¸ì¦ì„œë¥¼ 제시했습니다. 공격ìžê°€ 비공개 키를 ì†ìƒì‹œì¼°ì„ 수 있으며 서버를 가장한 공격ìžì™€ 통신 ì¤‘ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">사ì´íŠ¸ì— ì—°ê²°í•  수 ì—†ìŒ</translation>
<translation id="5869522115854928033">ì €ìž¥ëœ ë¹„ë°€ë²ˆí˜¸</translation>
<translation id="5872918882028971132">ìƒìœ„ 추천</translation>
<translation id="5901630391730855834">노란색</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" />(ë™ê¸°í™”ë¨)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1개 사용 중}other{#개 사용 중}}</translation>
<translation id="5926846154125914413">ì¼ë¶€ 사ì´íŠ¸ì˜ 프리미엄 콘í…츠를 액세스하지 못할 수 있습니다.</translation>
<translation id="5959728338436674663">위험한 앱과 사ì´íŠ¸ë¥¼ ê°ì§€í•  수 있ë„ë¡ ì¼ë¶€ <ph name="BEGIN_WHITEPAPER_LINK" />시스템 정보와 페ì´ì§€ 콘í…츠<ph name="END_WHITEPAPER_LINK" />를 Googleë¡œ ìžë™ 전송합니다. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">주</translation>
<translation id="5967867314010545767">기ë¡ì—ì„œ ì‚­ì œ</translation>
<translation id="5975083100439434680">축소</translation>
<translation id="598637245381783098">ê²°ì œ ì•±ì„ ì—´ 수 없습니다.</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1페ì´ì§€}other{#페ì´ì§€}}</translation>
<translation id="6017514345406065928">녹색</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì— ìžˆëŠ” 공격ìžëŠ” 다른 ì•±ì¸ ê²ƒì²˜ëŸ¼ 가장하거나 사용ìžë¥¼ 추ì í•˜ëŠ” ë° ì‚¬ìš©ë  ìˆ˜ 있는 ë°ì´í„°ë¥¼ 수집하는 사기성 ì•±ì„ ì„¤ì¹˜í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" />(ë™ê¸°í™”ë¨)</translation>
<translation id="6027201098523975773">ì´ë¦„ì„ ìž…ë ¥í•˜ì„¸ìš”.</translation>
<translation id="6040143037577758943">닫기</translation>
<translation id="6042308850641462728">ë”보기</translation>
+<translation id="6047233362582046994">유해한 ì•±ì´ ì‚­ì œë˜ê¸° ì „ì— <ph name="BEGIN_LINK" />ì´ ì‚¬ì´íŠ¸ë¥¼ 방문<ph name="END_LINK" />하는 경우 ë³´ì•ˆìƒ ìœ„í—˜ì„ ë°˜ë“œì‹œ ì´í•´í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.</translation>
+<translation id="6051221802930200923">현재 <ph name="SITE" />ì—ì„œ ì¸ì¦ì„œ ê³ ì •ì„ ì‚¬ìš©í•˜ê¸° ë•Œë¬¸ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ë‚˜ì¤‘ì— ì´ íŽ˜ì´ì§€ê°€ ì •ìƒì ìœ¼ë¡œ ìž‘ë™í•  수 있습니다.</translation>
<translation id="6060685159320643512">ì´ëŸ¬í•œ 실험실 ê¸°ëŠ¥ì€ ë¬¸ì œë¥¼ ì¼ìœ¼í‚¬ 수 있습니다.</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ì—†ìŒ}=1{1ê°œ}other{#ê°œ}}</translation>
+<translation id="6080696365213338172">ê´€ë¦¬ìž ì œê³µ ì¸ì¦ì„œë¥¼ 사용하여 콘í…ì¸ ì— ì•¡ì„¸ìŠ¤í–ˆìŠµë‹ˆë‹¤. 사용ìžê°€ <ph name="DOMAIN" />ì— ì œê³µí•œ ë°ì´í„°ê°€ 관리ìžì— ì˜í•´ ì°¨ë‹¨ë  ìˆ˜ 있습니다.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{ì—†ìŒ}=1{비밀번호 1ê°œ(ë™ê¸°í™”ë¨)}other{비밀번호 #ê°œ(ë™ê¸°í™”ë¨)}}</translation>
<translation id="6146055958333702838">ì¼€ì´ë¸”ì„ í™•ì¸í•˜ê³  사용 ì¤‘ì¸ ë¼ìš°í„°, 모뎀 ë˜ëŠ” 기타 ë„¤íŠ¸ì›Œí¬ ê¸°ê¸°ë¥¼
재부팅하시기 ë°”ëžë‹ˆë‹¤.</translation>
<translation id="614940544461990577">다ìŒì„ ì‹œë„:</translation>
<translation id="6151417162996330722">서버 ì¸ì¦ì„œì˜ 유효 ê¸°ê°„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤.</translation>
<translation id="6157877588268064908">배송 방법과 ìš”êµ¬ì‚¬í•­ì„ í™•ì¸í•˜ë ¤ë©´ 주소를 ì„ íƒí•˜ì„¸ìš”.</translation>
+<translation id="6158003235852588289">Google 세ì´í”„ 브ë¼ìš°ì§•ì´ 최근 <ph name="SITE" />ì—ì„œ í”¼ì‹±ì„ ê°ì§€í–ˆìŠµë‹ˆë‹¤. 피싱 사ì´íŠ¸ëŠ” 사용ìžë¥¼ ì†ì´ê¸° 위해 다른 웹사ì´íŠ¸ì¸ 것처럼 가장합니다.</translation>
<translation id="6165508094623778733">ìžì„¸ížˆ 알아보기</translation>
+<translation id="6169916984152623906">ì´ì œ 비공개로 ì¸í„°ë„·ì„ 사용할 수 있으며, ì´ ê¸°ê¸°ë¥¼ 사용하는 다른 사용ìžê°€ ë‚´ 활ë™ì„ ë³¼ 수 없습니다. 하지만 다운로드한 항목과 ë¶ë§ˆí¬ëŠ” 저장ë©ë‹ˆë‹¤.</translation>
<translation id="6177128806592000436">ì´ ì‚¬ì´íŠ¸ì— 대한 ì—°ê²°ì€ ì•ˆì „í•˜ì§€ 않습니다.</translation>
<translation id="6184817833369986695">(집단: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">ì¸í„°ë„· ì—°ê²°ì„ í™•ì¸í•˜ì„¸ìš”.</translation>
<translation id="6218753634732582820">Chromiumì—ì„œ 주소를 삭제하시겠습니까?</translation>
+<translation id="6221345481584921695">Google 세ì´í”„ 브ë¼ìš°ì§•ì´ 최근 <ph name="SITE" />ì—ì„œ <ph name="BEGIN_LINK" />멀웨어를 ê°ì§€<ph name="END_LINK" />했습니다. í‰ì†Œì— 안전한 웹사ì´íŠ¸ë„ ë©€ì›¨ì–´ì— ê°ì—¼ë  수가 있습니다. 악성 콘í…ì¸ ì˜ ì¶œì²˜ëŠ” 알려진 멀웨어 ë°°í¬ìžì¸ <ph name="SUBRESOURCE_HOST" />입니다.</translation>
<translation id="6251924700383757765">ê°œì¸ì •ë³´ì²˜ë¦¬ë°©ì¹¨</translation>
<translation id="6254436959401408446">페ì´ì§€ë¥¼ 열기 위한 메모리가 충분하지 ì•ŠìŒ</translation>
<translation id="625755898061068298">ì´ ì‚¬ì´íŠ¸ì— 대한 보안 경고를 사용하지 ì•Šë„ë¡ ì„ íƒí–ˆìŠµë‹ˆë‹¤.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">ë¶ë§ˆí¬ 수정</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" />ì˜ ë§Œë£Œì¼ê³¼ CVC를 입력하세요.</translation>
<translation id="6414888972213066896">ì´ ì‚¬ì´íŠ¸ë¥¼ ë°©ë¬¸í•´ë„ ê´œì°®ì€ì§€ 부모님께 문ì˜í–ˆìŠµë‹ˆë‹¤.</translation>
-<translation id="6416403317709441254">현재 <ph name="SITE" />ì—ì„œ 처리할 수 없는 ì•”í˜¸í™”ëœ ìžê²©ì¦ëª… 정보를 전송했기 ë•Œë¬¸ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ìž ì‹œ 후 페ì´ì§€ê°€ ì •ìƒí™”ë  ê²ƒìž…ë‹ˆë‹¤. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">ì¸ì¦ì„œê°€ 취소ë˜ì—ˆëŠ”지 확ì¸í•  수 없습니다.</translation>
<translation id="6433490469411711332">ì—°ë½ì²˜ ì •ë³´ 수정</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" />ì—ì„œ ì—°ê²°ì„ ê±°ë¶€í–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="6446608382365791566">ìžì„¸í•œ ì •ë³´ 추가</translation>
+<translation id="6447842834002726250">쿠키</translation>
<translation id="6451458296329894277">ì–‘ì‹ ë‹¤ì‹œ 제출 확ì¸</translation>
<translation id="6456339708790392414">결제</translation>
<translation id="6458467102616083041">ì •ì±…ì— ì˜í•´ 기본 ê²€ìƒ‰ì˜ ì‚¬ìš©ì´ ì¤‘ì§€ë˜ì—ˆê¸° ë•Œë¬¸ì— ë¬´ì‹œë¨</translation>
-<translation id="6462969404041126431">보안 ì¸ì¦ì„œê°€ 취소ë˜ì—ˆì„ 수 있어서 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">기기 정책</translation>
<translation id="6477321094435799029">Chromeì´ ì´ íŽ˜ì´ì§€ì—ì„œ 비정ìƒì ì¸ 코드를 ê°ì§€í–ˆìœ¼ë©° ê°œì¸ì •ë³´(예: 비밀번호, 전화번호, ì‹ ìš©ì¹´ë“œ) 보호를 위해 차단했습니다.</translation>
<translation id="6489534406876378309">ë¹„ì •ìƒ ì¢…ë£Œ 업로드 시작하기</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">만료: <ph name="EXPIRATION_DATE_ABBR" />, 마지막 사용ì¼: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">관리ìžê°€ ì•„ì§ ìŠ¹ì¸í•˜ì§€ 않았습니다.</translation>
<translation id="6569060085658103619">확장 프로그램 페ì´ì§€ë¥¼ 보는 중</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> 미만</translation>
+<translation id="657639383826808334">ì´ ì½˜í…츠는 사용ìžì˜ 정보를 ë„용하거나 삭제하는 위험한 소프트웨어를 ê¸°ê¸°ì— ì„¤ì¹˜í•˜ë ¤ í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. <ph name="BEGIN_LINK" />표시하기<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">암호화 옵션</translation>
<translation id="662080504995468778">머무르기</translation>
<translation id="6626291197371920147">유효한 카드 번호 추가</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> 검색</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì˜ ê³µê²©ìžê°€ ì‚¬ìš©ìž ì •ë³´(예: 사진, 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ)를 ë„용하거나 삭제하는 위험한 í”„ë¡œê·¸ëž¨ì„ Macì— ì„¤ì¹˜í•˜ë ¤ê³  ì‹œë„í•  수 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">ì´ ì •ì±…ì€ ì‚¬ìš©ë˜ì§€ 않습니다.</translation>
-<translation id="6652240803263749613">ì»´í“¨í„°ì˜ ìš´ì˜ì²´ì œì—ì„œ 보안 ì¸ì¦ì„œë¥¼ 신뢰하지 ì•Šì•„ì„œ 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Chromiumì—ì„œ ìžë™ì™„성 항목 ì¶”ì²œì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?</translation>
<translation id="6685834062052613830">로그아웃 후 설정 완료</translation>
<translation id="6710213216561001401">ì´ì „</translation>
<translation id="6710594484020273272">&lt;검색어 입력&gt;</translation>
<translation id="6711464428925977395">프ë¡ì‹œ ì„œë²„ì— ë¬¸ì œê°€ ë°œìƒí–ˆê±°ë‚˜ 주소가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="6727102863431372879">설정</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ì—†ìŒ}=1{항목 1ê°œ}other{항목 #ê°œ}}</translation>
<translation id="674375294223700098">ì•Œ 수 없는 서버 ì¸ì¦ì„œ 오류입니다.</translation>
<translation id="6753269504797312559">ì •ì±… ê°’</translation>
<translation id="6757797048963528358">기기가 절전 모드 ìƒíƒœìž…니다.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">맞춤설정 ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">지역 ë°ì´í„°ë¥¼ 로드하지 못했습니다.</translation>
+<translation id="6825578344716086703"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했으나 서버ì—ì„œ ì•ˆì „ì„±ì´ ë‚®ì€ ì„œëª… ì•Œê³ ë¦¬ì¦˜ì„ ì‚¬ìš©í•˜ì—¬ ì„œëª…ëœ ì¸ì¦ì„œ(예: SHA-1)를 전달했습니다. ì´ëŠ” 서버ì—ì„œ 전달한 보안 ì‚¬ìš©ìž ì¸ì¦ ì •ë³´ê°€ 위조ë˜ì—ˆì„ 수 있으며 사용하려는 서버가 ì•„ë‹˜ì„ ì˜ë¯¸í•©ë‹ˆë‹¤. 서버를 가장한 공격ìžì™€ 통신 ì¤‘ì¼ ìˆ˜ 있습니다.</translation>
+<translation id="6830728435402077660">안전하지 ì•ŠìŒ</translation>
<translation id="6831043979455480757">번역</translation>
<translation id="6839929833149231406">지역</translation>
<translation id="6874604403660855544">추가 다시 실행(&amp;R)</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">카드가 확ì¸ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="6897140037006041989">ì‚¬ìš©ìž ì—ì´ì „트</translation>
<translation id="6915804003454593391">사용ìž:</translation>
+<translation id="6945221475159498467">ì„ íƒ</translation>
<translation id="6948701128805548767">수령 방법과 ìš”êµ¬ì‚¬í•­ì„ í™•ì¸í•˜ë ¤ë©´ 주소를 ì„ íƒí•˜ì„¸ìš”.</translation>
<translation id="6957887021205513506">ì„œë²„ì˜ ì¸ì¦ì„œê°€ ìœ„ì¡°ëœ ê²ƒ 같습니다.</translation>
<translation id="6965382102122355670">확ì¸</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">ê³ ì • 프ë¡ì‹œ 서버와 .pac 스í¬ë¦½íŠ¸ URLì´ ëª¨ë‘ ì§€ì •ë˜ì–´ 있습니다.</translation>
<translation id="6989763994942163495">고급 설정 표시</translation>
<translation id="7000990526846637657">기ë¡ì´ 없습니다.</translation>
-<translation id="7009986207543992532"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했으나 서버ì—ì„œ ì¸ì¦ ê¸°ê°„ì´ ë„ˆë¬´ 길어서 신뢰할 수 없는 ì¸ì¦ì„œë¥¼ 제시했습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Google ê³„ì •ì— ë‹¤ë¥¸ 형ì‹ì˜ íƒìƒ‰ 기ë¡ì´ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />ì— ë‚¨ì•„ìžˆì„ ìˆ˜ 있습니다.</translation>
<translation id="7029809446516969842">비밀번호</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ê³  했지만 서버가 제시한 ì¸ì¦ì„œì˜ 유효 ê¸°ê°„ì´ ë„ˆë¬´ 길어서 신뢰할 수 없습니다.</translation>
+<translation id="7053983685419859001">차단</translation>
<translation id="7064851114919012435">ì—°ë½ì²˜ ì •ë³´</translation>
<translation id="7079718277001814089">ì´ ì‚¬ì´íŠ¸ì— 멀웨어가 있습니다.</translation>
<translation id="7087282848513945231">ì¹´ìš´í‹°</translation>
-<translation id="7088615885725309056">다ìŒ</translation>
<translation id="7090678807593890770">Googleì—ì„œ <ph name="LINK" /> 검색</translation>
+<translation id="7108819624672055576">확장 프로그램ì—ì„œ 허용</translation>
<translation id="7119414471315195487">다른 탭 ë˜ëŠ” 프로그램 닫기</translation>
<translation id="7129409597930077180">ì´ ì£¼ì†Œë¡œ 배송할 수 없습니다. 다른 주소를 ì„ íƒí•˜ì„¸ìš”.</translation>
<translation id="7138472120740807366">배달 방법</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">처리 중</translation>
<translation id="724691107663265825">ë‹¤ìŒ ì‚¬ì´íŠ¸ì— 멀웨어가 있습니다.</translation>
<translation id="724975217298816891">ì¹´ë“œ 세부정보를 ì—…ë°ì´íŠ¸í•˜ë ¤ë©´ <ph name="CREDIT_CARD" /> ì¹´ë“œì˜ ë§Œë£Œì¼ê³¼ CVC를 입력하세요. 카드를 확ì¸í•˜ë©´ ì¹´ë“œ 세부정보가 ì´ ì‚¬ì´íŠ¸ì™€ 공유ë©ë‹ˆë‹¤.</translation>
-<translation id="725866823122871198">ì»´í“¨í„°ì˜ ë‚ ì§œì™€ 시간(<ph name="DATE_AND_TIME" />)ì´ ìž˜ëª»ë˜ì–´ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />ì— ëŒ€í•œ 비공개 ì—°ê²°ì„ ì„¤ì •í•  수 없습니다.</translation>
+<translation id="7260504762447901703">액세스 취소</translation>
<translation id="7275334191706090484">관리 ë¶ë§ˆí¬</translation>
<translation id="7298195798382681320">권장</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" />ì— ìº¡ì²˜ëœ ë¹„ì •ìƒ ì¢…ë£Œ ë³´ê³ ì„œ(사용ìžê°€ 업로드를 요청했으나 ì•„ì§ ì—…ë¡œë“œë˜ì§€ ì•ŠìŒ)</translation>
<translation id="7334320624316649418">재정렬 다시 실행(&amp;R)</translation>
<translation id="733923710415886693">서버 ì¸ì¦ì„œê°€ ì¸ì¦ì„œ 투명성 ì •ì±…ì„ ì‚¬ìš©í•˜ì—¬ 공개ë˜ì§€ 않았습니다.</translation>
-<translation id="7351800657706554155">ì´ ì¸ì¦ì„œê°€ 취소ë˜ì—ˆê¸° ë•Œë¬¸ì— í˜„ìž¬ <ph name="SITE" />ì— ë°©ë¬¸í•  수 없습니다. ë„¤íŠ¸ì›Œí¬ ì˜¤ë¥˜ì™€ ê³µê²©ì€ ëŒ€ë¶€ë¶„ ì¼ì‹œì ì´ë¯€ë¡œ ìž ì‹œ 후 페ì´ì§€ê°€ ìž‘ë™ë  것입니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">명령줄</translation>
<translation id="7372973238305370288">검색결과</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">안함</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">ì¹´ë“œ 확ì¸</translation>
-<translation id="7394102162464064926">ì´ íŽ˜ì´ì§€ë¥¼ 방문 기ë¡ì—ì„œ 삭제하시겠습니까?
-
-다ìŒì—는 ì‹œí¬ë¦¿ 모드(<ph name="SHORTCUT_KEY" />)를 사용해 보세요.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">프로필 경로</translation>
<translation id="7424977062513257142">ì´ ì›¹íŽ˜ì´ì§€ì— ì‚½ìž…ëœ íŽ˜ì´ì§€ ë‚´ìš©:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">ì°¨ë‹¨ëœ ì‚¬ì´íŠ¸</translation>
<translation id="7445762425076701745">연결하려는 서버 ID를 확ì¸í•  수 없습니다. 외부 ì¸ì¦ 기관ì—ì„œ ì†Œìœ ê¶Œì„ í™•ì¸í•  수 없으므로 네트워í¬ì—ì„œ 유효한 ì´ë¦„ì„ ì‚¬ìš©í•˜ì—¬ ì„œë²„ì— ì—°ê²°ë©ë‹ˆë‹¤. ì¼ë¶€ ì¸ì¦ 기관ì—서는 ì´ëŸ¬í•œ ì´ë¦„ì— ëŒ€í•´ ê´€ê³„ì—†ì´ ì¸ì¦ì„œë¥¼ 발급하기 ë•Œë¬¸ì— ê³µê²©ìžê°€ ì•„ë‹ˆë¼ ì˜ë„í•œ 웹사ì´íŠ¸ì— ì—°ê²°ë˜ì–´ 있는지 확ì¸í•  수 없습니다.</translation>
<translation id="7451311239929941790">ì´ ë¬¸ì œë¥¼ <ph name="BEGIN_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LINK" /></translation>
+<translation id="7455133967321480974">전체 기본값 사용(차단)</translation>
<translation id="7460163899615895653">다른 기기ì—ì„œ ìµœê·¼ì— ì‚¬ìš©í•œ íƒ­ì´ ì—¬ê¸°ì— í‘œì‹œë©ë‹ˆë‹¤.</translation>
<translation id="7469372306589899959">ì¹´ë“œ í™•ì¸ ì¤‘</translation>
<translation id="7481312909269577407">앞으로</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">ë°˜í™˜ëœ ì •ì±… 기기 IDê°€ 비었거나 현재 기기 ID와 ì¼ì¹˜í•˜ì§€ ì•ŠìŒ</translation>
<translation id="7514365320538308">다운로드</translation>
<translation id="7518003948725431193">ë‹¤ìŒ ì›¹ 주소(<ph name="URL" />)ì— ëŒ€í•´ ë°œê²¬ëœ ì›¹íŽ˜ì´ì§€ê°€ 없습니다.</translation>
+<translation id="7521387064766892559">ìžë°”스í¬ë¦½íŠ¸</translation>
<translation id="7535087603100972091">ê°’</translation>
<translation id="7537536606612762813">필수</translation>
+<translation id="7542403920425041731">확ì¸í•˜ë©´ ì¹´ë“œ 세부정보가 ì´ ì‚¬ì´íŠ¸ì™€ 공유ë©ë‹ˆë‹¤.</translation>
<translation id="7542995811387359312">ì–‘ì‹ì— 보안 ì—°ê²°ì´ ì‚¬ìš©ë˜ì§€ ì•Šì•„ ì‹ ìš©ì¹´ë“œ ìžë™ 채우기가 사용 중지ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="7543525346216957623">부모님께 물어보세요.</translation>
<translation id="7549584377607005141">ì´ ì›¹íŽ˜ì´ì§€ë¥¼ 제대로 표시하려면 ì´ì „ì— ìž…ë ¥í•œ ë°ì´í„°ê°€ 필요합니다. ì´ ë°ì´í„°ë¥¼ 다시 보낼 수 있지만 ì´ ê²½ìš° 해당 페ì´ì§€ì—ì„œ ì´ì „ì— ìˆ˜í–‰í•œ ìž‘ì—…ì´ ë°˜ë³µë©ë‹ˆë‹¤.</translation>
<translation id="7552846755917812628">ë‹¤ìŒ ë„움ë§ì„ 확ì¸í•´ 보세요.</translation>
<translation id="7554791636758816595">새 탭</translation>
+<translation id="7567204685887185387">ì´ ì„œë²„ê°€ <ph name="DOMAIN" />ìž„ì„ ìž…ì¦í•  수 없으며 ì„œë²„ì˜ ë³´ì•ˆ ì¸ì¦ì„œê°€ 부정한 ë°©ì‹ìœ¼ë¡œ 발행ë˜ì—ˆì„ 수 있습니다. 서버를 잘못 설정했거나 불법 사용ìžê°€ ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />개}other{<ph name="CONTACT_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />개}}</translation>
<translation id="7568593326407688803">ì´ íŽ˜ì´ì§€ëŠ”<ph name="ORIGINAL_LANGUAGE" />ë¡œ ë˜ì–´ 있습니다. 번역하시겠습니까?</translation>
<translation id="7569952961197462199">Chromeì—ì„œ 신용카드를 삭제하시겠습니까?</translation>
<translation id="7569983096843329377">검정색</translation>
<translation id="7578104083680115302">Googleì— ì €ìž¥í•œ 카드를 사용하여 ì–´ë–¤ 기기ì—서든지 사ì´íŠ¸ ë° ì•±ì—ì„œ 빠르게 지불할 수 있습니다.</translation>
<translation id="7588950540487816470">피지컬 웹</translation>
<translation id="7592362899630581445">ì„œë²„ì˜ ì¸ì¦ì„œê°€ ì´ë¦„ 제약 ì¡°ê±´ì„ ìœ„ë°˜í•©ë‹ˆë‹¤.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> 미만</translation>
<translation id="759889825892636187">현재 <ph name="HOST_NAME" />ì—ì„œ ìš”ì²­ì„ ì²˜ë¦¬í•  수 없습니다.</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> 번역 안함</translation>
<translation id="7610193165460212391">ê°’(<ph name="VALUE" />)ì´ ë²”ìœ„ë¥¼ 벗어났습니다.</translation>
<translation id="7613889955535752492">만료ì¼: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">다른 Google 계정 비밀번호 ë²„ì „ì„ ì‚¬ìš©í•˜ì—¬ ì•”í˜¸í™”ëœ ë°ì´í„°ê°€ ì´ë¯¸ 있습니다. ì•„ëž˜ì— ì•”í˜¸ë¥¼ 입력하시기 ë°”ëžë‹ˆë‹¤.</translation>
-<translation id="7634554953375732414">ì´ ì‚¬ì´íŠ¸ì— 대한 ì—°ê²°ì€ ë¹„ê³µê°œê°€ 아닙니다.</translation>
<translation id="7637571805876720304">Chromiumì—ì„œ 신용카드를 삭제하시겠습니까?</translation>
<translation id="765676359832457558">고급 설정 숨기기</translation>
<translation id="7658239707568436148">취소</translation>
+<translation id="7662298039739062396">확장 프로그램ì—ì„œ 관리ë˜ëŠ” 설정</translation>
<translation id="7667346355482952095">ë°˜í™˜ëœ ì •ì±… 토í°ì´ 비었거나 현재 토í°ê³¼ ì¼ì¹˜í•˜ì§€ ì•ŠìŒ</translation>
<translation id="7668654391829183341">알 수 없는 기기</translation>
<translation id="7669271284792375604">ì´ ì‚¬ì´íŠ¸ì˜ 공격ìžê°€ ì¸í„°ë„· 사용 í™˜ê²½ì— ì•…ì˜í–¥ì„ 미치는 í”„ë¡œê·¸ëž¨ì„ ì„¤ì¹˜í•˜ë„ë¡ ì†ìž„수(예를 들어, 방문하는 사ì´íŠ¸ì˜ 홈페ì´ì§€ë¥¼ 변경하거나 추가로 광고를 표시)를 ì‹œë„í•  수 있습니다.</translation>
<translation id="7674629440242451245">Chromeì˜ ë©‹ì§„ 새 ê¸°ëŠ¥ì— ê´€ì‹¬ì´ ìžˆìœ¼ì‹­ë‹ˆê¹Œ? chrome.com/dev 페ì´ì§€ì—ì„œ ê°œë°œìž ì±„ë„ì— ë°©ë¬¸í•´ 보세요.</translation>
<translation id="7682287625158474539">배송</translation>
+<translation id="7701040980221191251">ì—†ìŒ</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" />(안전하지 ì•ŠìŒ)<ph name="END_LINK" />(으)ë¡œ ì´ë™</translation>
+<translation id="7714464543167945231">ì¸ì¦ì„œ</translation>
+<translation id="7716147886133743102">관리ìžê°€ 차단함</translation>
<translation id="7716424297397655342">ì´ ì‚¬ì´íŠ¸ë¥¼ ìºì‹œì—ì„œ 로드할 수 ì—†ìŒ</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">관리ë˜ì§€ ì•ŠìŒ</translation>
<translation id="7755287808199759310">ë¶€ëª¨ë‹˜ì´ ì°¨ë‹¨ 해제할 수 있습니다.</translation>
<translation id="7758069387465995638">방화벽ì´ë‚˜ ë°”ì´ëŸ¬ìŠ¤ 백신 소프트웨어가 ì—°ê²°ì„ ì°¨ë‹¨í–ˆì„ ìˆ˜ 있습니다.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32비트)</translation>
<translation id="7956713633345437162">ëª¨ë°”ì¼ ë¶ë§ˆí¬</translation>
<translation id="7961015016161918242">사용하지 ì•ŠìŒ</translation>
-<translation id="7962083544045318153">ë¹„ì •ìƒ ì¢…ë£Œ ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" />를 í•­ìƒ <ph name="TARGET_LANGUAGE" />ë¡œ 번역</translation>
<translation id="7995512525968007366">지정ë˜ì§€ ì•ŠìŒ</translation>
<translation id="800218591365569300">다른 탭ì´ë‚˜ í”„ë¡œê·¸ëž¨ì„ ì¢…ë£Œí•˜ì—¬ 메모리를 확보하세요.</translation>
<translation id="8012647001091218357">현재 부모님께 ì—°ë½í•  수 없습니다. ë‚˜ì¤‘ì— ë‹¤ì‹œ ì‹œë„í•´ 주세요.</translation>
<translation id="8025119109950072390">ì´ ì‚¬ì´íŠ¸ì˜ 공격ìžê°€ 소프트웨어를 설치하거나 ê°œì¸ì •ë³´(예: 비밀번호, 전화번호, ì‹ ìš©ì¹´ë“œ)를 공개하는 ë“±ì˜ ìœ„í—˜í•œ í–‰ë™ì„ 하ë„ë¡ ì‚¬ìš©ìžë¥¼ ì†ì¼ 수 있습니다.</translation>
-<translation id="803030522067524905">Google 세ì´í”„ 브ë¼ìš°ì§•ì´ 최근 <ph name="SITE" />ì—ì„œ í”¼ì‹±ì„ ê°ì§€í–ˆìŠµë‹ˆë‹¤. 피싱 사ì´íŠ¸ëŠ” 사용ìžë¥¼ ì†ì´ê¸° 위해 다른 웹사ì´íŠ¸ì¸ 것처럼 위장합니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">ì´ íŽ˜ì´ì§€ëŠ” <ph name="SOURCE_LANGUAGE" />ë¡œ ë˜ì–´ 있습니다. <ph name="TARGET_LANGUAGE" />ë¡œ 번역하시겠습니까?</translation>
+<translation id="8037357227543935929">요청(기본값)</translation>
<translation id="8041089156583427627">ì˜ê²¬ 보내기</translation>
+<translation id="8041940743680923270">전체 기본값 사용(요청)</translation>
<translation id="8088680233425245692">ê¸€ì„ ì¡°íšŒí•˜ì§€ 못했습니다.</translation>
<translation id="8089520772729574115">1MB 미만</translation>
<translation id="8091372947890762290">활성화 ìš”ì²­ì´ ì„œë²„ì—ì„œ 대기 중</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" />ì˜ ì„œë²„ <ph name="BEGIN_ABBR" />DNS 주소<ph name="END_ABBR" />를 ì°¾ì„ ìˆ˜ 없습니다.</translation>
<translation id="8149426793427495338">컴퓨터가 절전 모드 ìƒíƒœìž…니다.</translation>
<translation id="8150722005171944719"><ph name="URL" />ì˜ íŒŒì¼ì„ ì½ì„ 수 없습니다. ì‚­ì œ ë˜ëŠ” ì´ë™ë˜ì—ˆê±°ë‚˜ íŒŒì¼ ì‚¬ìš© ê¶Œí•œì´ ì•¡ì„¸ìŠ¤ë¥¼ 차단할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤.</translation>
+<translation id="8184538546369750125">전체 기본값 사용(허용)</translation>
+<translation id="8191494405820426728">로컬 ë¹„ì •ìƒ ì¢…ë£Œ ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">ì´ë™ 실행 취소(&amp;U)</translation>
<translation id="8201077131113104583">IDê°€ '<ph name="EXTENSION_ID" />'ì¸ í™•ìž¥ í”„ë¡œê·¸ëž¨ì— ëŒ€í•œ ìž˜ëª»ëœ ì—…ë°ì´íŠ¸ URL</translation>
<translation id="8202097416529803614">주문 요약</translation>
<translation id="8218327578424803826">ì§€ì •ëœ ìœ„ì¹˜:</translation>
<translation id="8225771182978767009">컴퓨터를 설정한 사용ìžê°€ ì´ ì‚¬ì´íŠ¸ë¥¼ 차단했습니다.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">현재 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì˜ ê³µê²©ìžê°€ ì‚¬ìš©ìž ì •ë³´(예: 사진, 비밀번호, 메시지, ì‹ ìš©ì¹´ë“œ)를 ë„용하거나 삭제하는 위험한 í”„ë¡œê·¸ëž¨ì„ ì»´í“¨í„°ì— ì„¤ì¹˜í•˜ë ¤ê³  ì‹œë„í•  수 있습니다.</translation>
<translation id="8241707690549784388">찾고 있는 페ì´ì§€ì—ì„œ 사용ìžê°€ 입력한 정보를 사용했습니다. 해당 페ì´ì§€ë¡œ ëŒì•„가면 기존 ìž‘ì—…ì„ ë°˜ë³µí•  수 있습니다. 계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</translation>
<translation id="8249320324621329438">마지막으로 가져온 시간:</translation>
<translation id="8253091569723639551">청구지 주소 필요</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">잘 모르는 경우 ë„¤íŠ¸ì›Œí¬ ê´€ë¦¬ìžì—게 문ì˜í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.</translation>
<translation id="8293206222192510085">ë¶ë§ˆí¬ 추가</translation>
<translation id="8294431847097064396">출처</translation>
+<translation id="8306404619377842860">ê¸°ê¸°ì˜ ë‚ ì§œì™€ 시간(<ph name="DATE_AND_TIME" />)ì´ ìž˜ëª»ë˜ì—ˆìœ¼ë¯€ë¡œ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />ì— ë¹„ê³µê°œë¡œ ì—°ê²°í•  수 없습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">ë„¤íŠ¸ì›Œí¬ ì—°ê²° 문제로 ì¸í•´ ë²ˆì—­ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" />ì— ëŒ€í•œ 액세스가 거부ë¨</translation>
<translation id="834457929814110454">보안 관련 ìœ„í—˜ì„ ì´í•´í•œë‹¤ë©´ 악성 í”„ë¡œê·¸ëž¨ì´ ì‚­ì œë˜ê¸° ì „ì— <ph name="BEGIN_LINK" />ì´ ì‚¬ì´íŠ¸ë¥¼ 방문<ph name="END_LINK" />í•´ë„ ë©ë‹ˆë‹¤.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">Google 계정ì—ì„œ 카드를 사용하려면 Chromeì— ë¡œê·¸ì¸í•˜ì„¸ìš”.</translation>
<translation id="8488350697529856933">ì ìš© 대ìƒ</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" />ì—ì„œ ì‘답하는 ë° ì‹œê°„ì´ ë„ˆë¬´ 오래 걸립니다.</translation>
-<translation id="852346902619691059">ê¸°ê¸°ì˜ ìš´ì˜ì²´ì œì—ì„œ 보안 ì¸ì¦ì„œë¥¼ 신뢰하지 ì•Šì•„ì„œ 서버 ë„ë©”ì¸ì´ <ph name="DOMAIN" />ìž„ì„ ì¦ëª…í•  수 없습니다. ì„¤ì •ì´ ìž˜ëª»ë˜ì—ˆê±°ë‚˜ 해커가 ì—°ê²°ì„ ê°€ë¡œì±„ê³  있기 ë•Œë¬¸ì¼ ìˆ˜ 있습니다. <ph name="BEGIN_LEARN_MORE_LINK" />ìžì„¸ížˆ 알아보기<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">만료 ì—°ë„</translation>
<translation id="8543181531796978784"><ph name="BEGIN_ERROR_LINK" />ê°ì§€ 문제를 ì‹ ê³ <ph name="END_ERROR_LINK" />í•  수 있으며, ë³´ì•ˆì— ë¯¸ì¹˜ëŠ” ìœ„í—˜ì„ ê°ìˆ˜í•œë‹¤ë©´ <ph name="BEGIN_LINK" />ì´ ì•ˆì „í•˜ì§€ ì•Šì€ ì‚¬ì´íŠ¸ë¥¼ 방문<ph name="END_LINK" />í•  수 있습니다.</translation>
<translation id="8553075262323480129">페ì´ì§€ì˜ 언어를 ê²°ì •í•  수 없으므로 번역하지 못했습니다.</translation>
-<translation id="8559762987265718583">ê¸°ê¸°ì˜ ë‚ ì§œì™€ 시간(<ph name="DATE_AND_TIME" />)ì´ ìž˜ëª»ë˜ì–´ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />ì— ëŒ€í•œ 비공개 ì—°ê²°ì„ ì„¤ì •í•  수 없습니다.</translation>
<translation id="8571890674111243710">페ì´ì§€ë¥¼ <ph name="LANGUAGE" />(으)ë¡œ 번역 중...</translation>
<translation id="858637041960032120">번호 추가</translation>
<translation id="859285277496340001">ì¸ì¦ì„œëŠ” 취소 여부를 확ì¸í•˜ëŠ” ë§¤ì»¤ë‹ˆì¦˜ì„ ì§€ì •í•˜ì§€ 않습니다.</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">보안 ì—°ê²°ì„ ì„¤ì •í•˜ë ¤ë©´ 시계가 올바로 설정ë˜ì–´ 있어야 합니다. 웹사ì´íŠ¸ê°€ ìžì‹ ì„ ì‹ë³„하는 ë° ì‚¬ìš©í•˜ëŠ” ì¸ì¦ì„œê°€ 특정 기간ì—만 유효하기 때문입니다. ê¸°ê¸°ì˜ ì‹œê³„ê°€ 잘못 설정ë˜ì–´ Chromiumì—ì„œ ì´ ì¸ì¦ì„œë¥¼ 확ì¸í•  수 없습니다.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" />ì˜ &lt;abbr id="dnsDefinition"&gt;DNS 주소&lt;/abbr&gt;를 ì°¾ì„ ìˆ˜ 없습니다. 문제를 진단하는 중입니다.</translation>
<translation id="8759274551635299824">ë§Œë£Œëœ ì¹´ë“œìž…ë‹ˆë‹¤.</translation>
+<translation id="8761567432415473239">Google 세ì´í”„ 브ë¼ìš°ì§• ê²°ê³¼ <ph name="SITE" />ì—ì„œ 최근 <ph name="BEGIN_LINK" />악성 í”„ë¡œê·¸ëž¨ì´ ë°œê²¬<ph name="END_LINK" />ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="8790007591277257123">삭제 다시 실행(&amp;R)</translation>
<translation id="8800988563907321413">근처 추천 í•­ëª©ì´ ì—¬ê¸°ì— í‘œì‹œë©ë‹ˆë‹¤.</translation>
<translation id="8820817407110198400">ë¶ë§ˆí¬</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">ìµœê·¼ì— ë‹«ì€ íƒ­</translation>
<translation id="8874824191258364635">올바른 카드 번호를 입력하세요.</translation>
<translation id="8876793034577346603">ë„¤íŠ¸ì›Œí¬ ì„¤ì •ì„ íŒŒì‹±í•˜ì§€ 못했습니다.</translation>
-<translation id="8877192140621905067">카드를 확ì¸í•˜ë©´ ì¹´ë“œ 세부정보가 ì´ ì‚¬ì´íŠ¸ì™€ 공유ë©ë‹ˆë‹¤.</translation>
<translation id="8889402386540077796">색조</translation>
<translation id="8891727572606052622">프ë¡ì‹œ 모드가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="889901481107108152">죄송합니다. 현재 플랫í¼ì—ì„œ 사용할 수 없는 실험실 기능입니다.</translation>
<translation id="8903921497873541725">확대</translation>
<translation id="8931333241327730545">ì´ ì¹´ë“œë¥¼ Google ê³„ì •ì— ì €ìž¥í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</translation>
<translation id="8932102934695377596">ì‹œê°„ì´ ë„ˆë¬´ 먼 과거로 설정ë˜ì–´ 있습니다.</translation>
-<translation id="8954894007019320973">(계ì†)</translation>
<translation id="8971063699422889582">서버 ì¸ì¦ì„œê°€ 만료ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="8986494364107987395">사용 통계 ë° ë¹„ì •ìƒ ì¢…ë£Œ 보고서를 Googleì— ìžë™ìœ¼ë¡œ 보내기</translation>
-<translation id="8987927404178983737">ì›”</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">방문하려는 사ì´íŠ¸ì— 유해한 í”„ë¡œê·¸ëž¨ì´ ìžˆìŠµë‹ˆë‹¤.</translation>
+<translation id="8997023839087525404">서버ì—ì„œ ì¸ì¦ì„œ 투명성 ì •ì±…ì„ ì‚¬ìš©í•˜ì—¬ 공개ë˜ì§€ ì•Šì€ ì¸ì¦ì„œë¥¼ 제시했습니다. ì¸ì¦ì„œ 투명성 ì •ì±…ì€ ì¸ì¦ì„œê°€ 신뢰할 수 있으며 공격ìžë¡œë¶€í„° 사용ìžë¥¼ 보호하고 있ìŒì„ 보장하기 위한 것으로 ì¼ë¶€ ì¸ì¦ì„œì˜ 경우 필수사항입니다.</translation>
<translation id="9001074447101275817">프ë¡ì‹œ <ph name="DOMAIN" />ì— ì‚¬ìš©ìž ì´ë¦„ ë° ë¹„ë°€ë²ˆí˜¸ë¥¼ 입력해야 합니다.</translation>
+<translation id="9005998258318286617">PDF 문서를 로드하지 못했습니다.</translation>
<translation id="901974403500617787">시스템 ì „ì²´ì— ì ìš©ë˜ëŠ” 플래그는 소유ìž(<ph name="OWNER_EMAIL" />)만 설정할 수 있습니다.</translation>
+<translation id="9020200922353704812">카드 청구서 수신 주소가 필요함</translation>
<translation id="9020542370529661692">ì´ íŽ˜ì´ì§€ëŠ” <ph name="TARGET_LANGUAGE" />ë¡œ 번역ë˜ì—ˆìŠµë‹ˆë‹¤.</translation>
<translation id="9035022520814077154">보안 오류</translation>
<translation id="9038649477754266430">빠른 페ì´ì§€ 로드를 위해 ì˜ˆìƒ ê²€ìƒ‰ì–´ 서비스 사용</translation>
<translation id="9039213469156557790">ë˜í•œ ì´ íŽ˜ì´ì§€ì—는 안전하지 ì•Šì€ ë‹¤ë¥¸ 리소스가 í¬í•¨ë˜ì–´ 있습니다. ì´ëŸ¬í•œ 리소스는 전송 ì¤‘ì— ë‹¤ë¥¸ ì‚¬ëžŒì´ ë³¼ 수 있으며 페ì´ì§€ì˜ ìž‘ë™ì„ 변경하기 위해 공격ìžê°€ 수정할 수 있습니다.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />ì— ìžˆëŠ” 해커가 브ë¼ìš°ì € í™˜ê²½ì— ì•…ì˜í–¥ì„ 미치는 í”„ë¡œê·¸ëž¨ì„ ì„¤ì¹˜í•˜ë„ë¡ ì†ìž„수(예를 들어, 방문하는 사ì´íŠ¸ì˜ 홈페ì´ì§€ë¥¼ 변경하거나 추가로 광고를 표시)를 ì‹œë„í•  수 있습니다.</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" />ì— ì ‘ì†í•˜ë ¤ 했지만 서버가 ìž˜ëª»ëœ ì¸ì¦ì„œë¥¼ 전달했습니다.</translation>
<translation id="9050666287014529139">암호</translation>
<translation id="9065203028668620118">수정</translation>
<translation id="9068849894565669697">ìƒ‰ìƒ ì„ íƒ</translation>
+<translation id="9069693763241529744">확장 프로그램ì—ì„œ 차단함</translation>
<translation id="9076283476770535406">성ì¸ìš© 콘í…츠가 í¬í•¨ë˜ì–´ ìžˆì„ ìˆ˜ 있습니다.</translation>
<translation id="9078964945751709336">ìžì„¸í•œ ì •ë³´ í•„ìš”</translation>
<translation id="9103872766612412690"><ph name="SITE" />ì—서는 ì‚¬ìš©ìž ì •ë³´ë¥¼ 보호하기 위해 ì¼ë°˜ì ìœ¼ë¡œ 암호화를 사용합니다. ì´ë²ˆì— Chromiumì—ì„œ <ph name="SITE" />ì— ì—°ê²°ì„ ì‹œë„í–ˆì„ ë•Œ 웹사ì´íŠ¸ì—ì„œ 비정ìƒì ì´ê³  ìž˜ëª»ëœ ì‚¬ìš©ìž ì¸ì¦ 정보를 반환했습니다. ì´ëŠ” 공격ìžê°€ <ph name="SITE" />ì¸ ê²ƒì²˜ëŸ¼ 가장하려고 하거나 Wi-Fi ë¡œê·¸ì¸ í™”ë©´ì´ ì—°ê²°ì„ ë°©í•´í–ˆê¸° ë•Œë¬¸ì¼ ìˆ˜ 있습니다. ë°ì´í„° êµí™˜ì´ ë°œìƒí•˜ê¸° ì „ì— Chromiumì—ì„œ ì—°ê²°ì„ ì¤‘ë‹¨í–ˆìœ¼ë¯€ë¡œ ì‚¬ìš©ìž ì •ë³´ëŠ” 안전합니다.</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">수정 실행 취소(&amp;U)</translation>
<translation id="9154194610265714752">ì—…ë°ì´íŠ¸ë¨</translation>
<translation id="9157595877708044936">설정 중...</translation>
+<translation id="9169664750068251925">ì´ ì‚¬ì´íŠ¸ì—ì„œ í•­ìƒ ì°¨ë‹¨</translation>
<translation id="9170848237812810038">실행 취소(&amp;U)</translation>
<translation id="917450738466192189">ì„œë²„ì˜ ì¸ì¦ì„œê°€ 유효하지 않습니다.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />개}other{<ph name="SHIPPING_OPTION_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />개}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" />ì—ì„œ 지ì›ë˜ì§€ 않는 í”„ë¡œí† ì½œì„ ì‚¬ìš©í•©ë‹ˆë‹¤.</translation>
<translation id="9205078245616868884">ë™ê¸°í™” 암호로 ë°ì´í„°ê°€ 암호화ë˜ì–´ 있습니다. ë™ê¸°í™”를 시작하려면 입력하세요.</translation>
<translation id="9207861905230894330">ê¸€ì„ ì¶”ê°€í•˜ì§€ 못했습니다.</translation>
+<translation id="9219103736887031265">ì´ë¯¸ì§€</translation>
<translation id="933612690413056017">ì¸í„°ë„·ì— ì—°ê²°ë˜ì§€ ì•ŠìŒ</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ì–‘ì‹ ì§€ìš°ê¸°</translation>
<translation id="939736085109172342">새 í´ë”</translation>
<translation id="941721044073577244">ì´ ì‚¬ì´íŠ¸ë¥¼ 방문할 수 있는 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤.</translation>
<translation id="969892804517981540">ê³µì‹ ë¹Œë“œ</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{ì—†ìŒ}=1{항목 1ê°œ}other{항목 #ê°œ}}</translation>
<translation id="988159990683914416">ê°œë°œìž ë¹Œë“œ</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_lt.xtb b/chromium/components/strings/components_strings_lt.xtb
index 18ca8f6ef11..d21a7e1925d 100644
--- a/chromium/components/strings/components_strings_lt.xtb
+++ b/chromium/components/strings/components_strings_lt.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Pasukti pagal laikrodžio rodyklę</translation>
<translation id="1038842779957582377">nežinomas pavadinimas</translation>
<translation id="1050038467049342496">Uždarykite kitas programas</translation>
-<translation id="1053591932240354961">Šiuo metu negalite apsilankyti <ph name="SITE" />, nes svetainė atsiuntė užšifruotus prisijungimo duomenis, kurių „Google Chrome“ negali apdoroti. Tinklo klaidos ir išpuoliai dažniausiai yra laikini, todėl šis puslapis tikriausiai veiks vėliau. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Anuliuoti pridÄ—jimÄ…</translation>
<translation id="10614374240317010">Niekada neišsaugota</translation>
<translation id="106701514854093668">Žymės staliniame kompiuteryje</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Gera politikos talpykla</translation>
<translation id="113188000913989374"><ph name="SITE" /> sakoma:</translation>
<translation id="1132774398110320017">„Chrome“ automatinio pildymo nustatymai...</translation>
+<translation id="1150979032973867961">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas nėra patikimas kompiuterio operacinei sistemai. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
+<translation id="1151972924205500581">Būtinas slaptažodis</translation>
<translation id="1152921474424827756">Pasiekite <ph name="BEGIN_LINK" />talpykloje saugomÄ… <ph name="URL" /> kopijÄ…<ph name="END_LINK" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> netikėtai nutraukė ryšį.</translation>
<translation id="1161325031994447685">Iš naujo prisijungti prie „Wi-Fi“</translation>
+<translation id="1165039591588034296">Klaida</translation>
<translation id="1175364870820465910">&amp;Spausdinti...</translation>
<translation id="1181037720776840403">Pašalinti</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Automatiškai pateikti<ph name="END_WHITEPAPER_LINK" /> išsamią informaciją apie galimas saugos problemas sistemoje „Google“. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Daugiau iš šios svetainės</translation>
<translation id="1206967143813997005">Netinkamas pirminis parašas</translation>
<translation id="1209206284964581585">SlÄ—pti dabar</translation>
+<translation id="121201262018556460">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė nesudėtingą raktą turintį sertifikatą. Užpuolikas galėjo nulaužti privatųjį raktą, o šis serveris gali būti ne tas, kurio tikėjotės (gali būti, kad bendraujate su užpuoliku).</translation>
<translation id="1219129156119358924">Sistemos sauga</translation>
<translation id="1227224963052638717">Nežinoma politika.</translation>
<translation id="1227633850867390598">SlÄ—pti vertÄ™</translation>
<translation id="1228893227497259893">Netinkamas subjekto identifikatorius</translation>
<translation id="1232569758102978740">Be pavadinimo</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sinchronizuota)</translation>
<translation id="1263231323834454256">Skaitymo sąrašas</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" /> užfiksuota strigÄių ataskaita (dar neįkelta ar nepaisoma)</translation>
+<translation id="1281526147609854549">Išdavė „<ph name="ISSUER" />“</translation>
+<translation id="1283919782143846010">Pavojingas turinys užblokuotas</translation>
<translation id="1285320974508926690">Niekada neversti Å¡ios svetainÄ—s</translation>
<translation id="129553762522093515">Neseniai uždarytas</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Pabandykite išvalyti slapukus<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Veiklą <ph name="BEGIN_EMPHASIS" />vis tiek gali peržiūrėti<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />lankomos svetainÄ—s;
+ <ph name="LIST_ITEM" />darbdavys arba mokykla;
+ <ph name="LIST_ITEM" />interneto paslaugų teikėjas.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Registracijos domenas:</translation>
<translation id="1340482604681802745">PaÄ—mimo adresas</translation>
<translation id="1344211575059133124">Panašu, kad jums reikia leidimo, jei norite apsilankyti šioje svetainėje</translation>
<translation id="1344588688991793829">„Chromium“ automatinio pildymo nustatymai...</translation>
+<translation id="1348198688976932919">Pateiktoje svetainėje yra pavojingų programų</translation>
<translation id="1374468813861204354">pasiūlymai</translation>
<translation id="1375198122581997741">Apie versijÄ…</translation>
<translation id="1377321085342047638">Kort. Nr.</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> neišsiuntė jokių duomenų.</translation>
<translation id="1407135791313364759">Atidaryti viskÄ…</translation>
<translation id="1413809658975081374">Privatumo klaida</translation>
+<translation id="14171126816530869"><ph name="ORGANIZATION" /> identiškumą <ph name="LOCALITY" /> patikrino <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Taip</translation>
<translation id="1430915738399379752">Spausdinti</translation>
-<translation id="1442912890475371290">Užblokuotas bandymas <ph name="BEGIN_LINK" />apsilankyti puslapyje, esanÄiame <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Šiuo metu negalite apsilankyti <ph name="SITE" />, nes svetainėje naudojamas sertifikatų prisegimas. Tinklo klaidos ir išpuoliai dažniausiai yra laikini, todėl šis puslapis tikriausiai veiks vėliau. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}many{<ph name="PAYMENT_METHOD_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Rodyti išsaugotą šio puslapio kopiją (kuri yra pasenusi).</translation>
<translation id="1517433312004943670">BÅ«tinas telefono numeris</translation>
<translation id="1519264250979466059">Sukūrimo data</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Norint naudoti šią funkciją, reikia įgalinti „JavaScript“.</translation>
<translation id="1555130319947370107">MÄ—lyna</translation>
<translation id="1559528461873125649">NÄ—ra tokio failo ar katalogo</translation>
-<translation id="1559572115229829303">&lt;p&gt;Nepavyksta užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes įrenginio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami.&lt;/p&gt;
-
- &lt;p&gt;Koreguokite datÄ… ir laikÄ… programos &lt;strong&gt;Settings&lt;/strong&gt; skiltyje &lt;strong&gt;General&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Rodant šį tinklalapį įvyko nenumatyta klaida.</translation>
<translation id="1592005682883173041">Prieiga prie vietinių duomenų</translation>
+<translation id="1594030484168838125">Pasirinkti</translation>
<translation id="161042844686301425">Žydra</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Ar norite, kad „Chrome“ išsaugotų šią kortelę?</translation>
<translation id="1639239467298939599">Įkeliama</translation>
<translation id="1640180200866533862">Naudotojo politika</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Tinklo konfigūracija netinkama ir jos neįmanoma importuoti.</translation>
<translation id="1644574205037202324">Istorija</translation>
<translation id="1645368109819982629">Nepalaikomas protokolas</translation>
+<translation id="1655462015569774233">{1,plural, =1{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi vakar. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}one{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dieną. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}few{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienas. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}many{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienos. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}other{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienų. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar tai tinkama? Jei netinkama, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį.}}</translation>
<translation id="1656489000284462475">PaÄ—mimas</translation>
<translation id="1663943134801823270">Kortelės ir adresai naudojami iš „Chrome“. Juos galite tvarkyti nuėję į <ph name="BEGIN_LINK" />Nustatymus<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Svetainėje <ph name="SITE" /> įprastai naudojama šifruotė informacijai apsaugoti. Šį kartą „Google Chrome“ bandant prisijungti prie <ph name="SITE" />, ji pateikė neįprastus ir netinkamus prisijungimo duomenis. Gali būti, kad užpuolėjas bando apsimesti svetaine <ph name="SITE" /> arba „Wi-Fi“ prisijungimo ekrane nutrūko ryšys. Jūsų informacija vis tiek liko apsaugota, nes „Google Chrome“ sustabdė prisijungimą prieš apsikeitimą bet kokiais duomenimis.</translation>
-<translation id="168328519870909584">Šiuo metu svetainės <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolėjai gali jūsų įrenginyje bandyti įdiegti pavojingas programas, kurios vagia arba ištrina informaciją (pvz., nuotraukas, slaptažodžius, pranešimus ir kredito kortelių numerius).</translation>
<translation id="168841957122794586">Serverio sertifikate yra nesudÄ—tingas kriptografinis raktas.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios nuo rytojaus. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko.}one{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienos. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko.}few{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienų. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko.}many{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienos. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko.}other{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienų. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Turite gauti <ph name="NAME" /> leidimÄ… apsilankyti Å¡ioje svetainÄ—je</translation>
<translation id="1721424275792716183">* Būtina užpildyti lauką</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Atsisiųsti puslapį vėliau</translation>
<translation id="17513872634828108">Atidaryti skirtukai</translation>
<translation id="1753706481035618306">Puslapio numeris</translation>
+<translation id="1763864636252898013">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas nėra patikimas įrenginio operacinei sistemai. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Pabandykite paleisti „Windows Network Diagnostics“<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Atnaujinkite sinchronizavimo slaptafrazÄ™.</translation>
<translation id="1787142507584202372">Atidaryti skirtukai bus rodomi Äia</translation>
+<translation id="1789575671122666129">IÅ¡Å¡okantieji langai</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">KortelÄ—s savininko vardas</translation>
-<translation id="1803678881841855883">„Google“ saugaus narÅ¡ymo funkcija <ph name="BEGIN_LINK" />aptiko kenkÄ—jiÅ¡kÄ… programÄ…<ph name="END_LINK" /> svetainÄ—je <ph name="SITE" />. SvetainÄ—s, kurios paprastai yra saugios, kartais užkreÄiamos kenkÄ—jiÅ¡komis programomis. KenkÄ—jiÅ¡kÄ… turinį platina <ph name="SUBRESOURCE_HOST" /> – žinomas kenkÄ—jiÅ¡kų programų platintojas. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">PridÄ—ta <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Netinkama užklausa arba jos parametrai</translation>
<translation id="1826516787628120939">Tikrinama</translation>
<translation id="1834321415901700177">Šioje svetainėje yra kenkėjiškų programų</translation>
+<translation id="1840414022444569775">Å is kortelÄ—s numeris jau naudojamas</translation>
<translation id="1842969606798536927">MokÄ—ti</translation>
<translation id="1871208020102129563">Įgaliotasis serveris nustatytas naudoti fiksuotų įgaliotųjų serverių, o ne .pac scenarijaus URL.</translation>
<translation id="1871284979644508959">BÅ«tinas laukas</translation>
<translation id="187918866476621466">Atidaryti paleidimo puslapius</translation>
<translation id="1883255238294161206">Sutraukti sąrašą</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtravimas</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Nėra}=1{1 svetainė}one{# svetainė}few{# svetainės}many{# svetainės}other{# svetainių}}</translation>
<translation id="194030505837763158">Apsilankykite <ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> žymės</translation>
<translation id="1973335181906896915">Serijinio rengimo klaida</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Nepaisoma, nes buvo pakeista taikant „<ph name="POLICY_NAME" />“.</translation>
<translation id="2138201775715568214">Ieškoma fizinių tinklalapių netoliese</translation>
<translation id="213826338245044447">Žymės mobiliesiems</translation>
-<translation id="2148716181193084225">Å iandien</translation>
+<translation id="2147827593068025794">Fono sinchronizavimas</translation>
<translation id="2154054054215849342">Sinchronizavimo paslauga nepasiekiama jūsų domenui</translation>
<translation id="2154484045852737596">KortelÄ—s informacijos redagavimas</translation>
<translation id="2166049586286450108">VisateisÄ— administratoriaus prieiga</translation>
<translation id="2166378884831602661">Ši svetainė negali užtikrinti saugaus ryšio</translation>
<translation id="2181821976797666341">Politika</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresas}one{# adresas}few{# adresai}many{# adreso}other{# adresų}}</translation>
+<translation id="2187317261103489799">Aptikti (numatytoji parinktis)</translation>
<translation id="2202020181578195191">Įveskite tinkamus galiojimo laiko pabaigos metus</translation>
<translation id="2212735316055980242">Politika nerasta</translation>
<translation id="2213606439339815911">Gaunami įrašai...</translation>
+<translation id="2218879909401188352">Šiuo metu užpuolikai svetainėje <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> gali įdiegti pavojingų programų, kurios gali būti žalingos įrenginiui, atlikti nepageidaujamų veiksmų, dėl kurių padidės mobiliojo telefono sąskaita, arba pavogti asmens informaciją. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Išspręskite ryšio problemas naudodami <ph name="BEGIN_LINK" />diagnostikos programą<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Siųsti dabar</translation>
<translation id="225207911366869382">Pagal Å¡iÄ… politikÄ… Å¡i vertÄ— nepatvirtinta.</translation>
<translation id="2262243747453050782">HTTP klaida</translation>
+<translation id="2270484714375784793">Telefono numeris</translation>
<translation id="2282872951544483773">Nepasiekiami eksperimentai</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> elementas}one{<ph name="ITEM_COUNT" /> elementas}few{<ph name="ITEM_COUNT" /> elementai}many{<ph name="ITEM_COUNT" /> elemento}other{<ph name="ITEM_COUNT" /> elementų}}</translation>
<translation id="2292556288342944218">Interneto prieiga užblokuota</translation>
<translation id="230155334948463882">Nauja kortelÄ—?</translation>
-<translation id="2305919008529760154">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas galėjo būti išduotas neteisėtai. Taip gali būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> būtina įvesti naudotojo vardą ir slaptažodį.</translation>
-<translation id="2318774815570432836">Šiuo metu negalite apsilankyti <ph name="SITE" />, nes svetainėje naudojama HSTS. Tinklo klaidos ir išpuoliai dažniausiai yra laikini, todėl šis puslapis tikriausiai veiks vėliau. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">NustatymÄ… valdo administratorius</translation>
<translation id="2354001756790975382">Kitos žymės</translation>
+<translation id="2354430244986887761">„Google“ saugaus naršymo technologija svetainėje <ph name="SITE" /> neseniai <ph name="BEGIN_LINK" />aptiko kenkėjiškų programų<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">Užpuolikai galbūt galės matyti, kuriuos šios svetainės vaizdus peržiūrite, ir juos pakeis siekdami jus suklaidinti.</translation>
+<translation id="2356070529366658676">Paklausti</translation>
+<translation id="2359629602545592467">Kelios</translation>
<translation id="2359808026110333948">Tęsti</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> užfiksuota strigÄių ataskaita nebuvo įkelta</translation>
<translation id="2367567093518048410">Lygis</translation>
-<translation id="2371153335857947666">{1,plural, =1{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi vakar. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar šis laikas tinkamas? Jeigu ne, turėtumėte pakoreguoti sistemos laikrodį ir atnaujinti šį puslapį. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}one{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dieną. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar šis laikas tinkamas? Jeigu ne, turėtumėte pakoreguoti sistemos laikrodį ir atnaujinti šį puslapį. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}few{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienas. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar šis laikas tinkamas? Jeigu ne, turėtumėte pakoreguoti sistemos laikrodį ir atnaujinti šį puslapį. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}many{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienos. Taip gali būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar šis laikas tinkamas? Jei jis netinkamas, turėtumėte koreguoti sistemos laikrodį ir atnaujinti šį puslapį. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}other{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikato galiojimas baigėsi prieš # dienų. Taip gali būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. Šiuo metu kompiuterio laikrodis nustatytas į <ph name="CURRENT_DATE" />. Ar šis laikas tinkamas? Jeigu ne, turėtumėte pakoreguoti sistemos laikrodį ir atnaujinti šį puslapį. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nėra jokių galimų NS alternatyvų</translation>
<translation id="2384307209577226199">Numatytieji įmonės nustatymai</translation>
<translation id="2386255080630008482">Serverio sertifikatas panaikintas.</translation>
<translation id="2392959068659972793">Rodyti politikÄ… su nenustatyta verte</translation>
<translation id="239429038616798445">Å is pristatymo metodas nepasiekiamas. IÅ¡bandykite kitÄ… metodÄ….</translation>
<translation id="2396249848217231973">&amp;Anuliuoti ištrynimą</translation>
-<translation id="2460160116472764928">„Google“ saugaus narÅ¡ymo funkcija neseniai <ph name="BEGIN_LINK" />aptiko kenkÄ—jiÅ¡kÄ… programÄ…<ph name="END_LINK" /> svetainÄ—je <ph name="SITE" />. Kartais svetainÄ—s, kurios paprastai yra saugios, užkreÄiamos kenkÄ—jiÅ¡komis programomis. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas gali būti atšauktas. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="2463739503403862330">Užpildyti</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Paleistas įrankis „Windows Network Diagnostics“<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Netinkamas paieškos URL.</translation>
+<translation id="2482878487686419369">Pranešimai</translation>
<translation id="2491120439723279231">Serverio sertifikate yra klaidų.</translation>
<translation id="2495083838625180221">JSON analizavimo įrankis</translation>
<translation id="2495093607237746763">Jei pažymÄ—ta, „Chromium“ iÅ¡saugos kortelÄ—s kopijÄ… įrenginyje, kad galÄ—tumÄ—te greiÄiau užpildyti formas.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Grįžti</translation>
<translation id="2515629240566999685">Patikrinti signalo stiprumÄ… savo srityje</translation>
<translation id="2516305470678292029">NS alternatyvos</translation>
+<translation id="2539524384386349900">Aptikti</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> išsiuntė netinkamą atsaką.</translation>
-<translation id="2552545117464357659">Naujesnis</translation>
<translation id="2556876185419854533">&amp;Anuliuoti redagavimÄ…</translation>
<translation id="2587730715158995865">Nuo „<ph name="ARTICLE_PUBLISHER" />“. Skaitykite šią ir kitas istorijas (<ph name="OTHER_ARTICLE_COUNT" />).</translation>
<translation id="2587841377698384444">Katalogo API ID:</translation>
<translation id="2597378329261239068">Šis dokumentas apsaugotas slaptažodžiu. Įveskite slaptažodį.</translation>
<translation id="2609632851001447353">Variantai</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Nėra}=1{1 programa („$1“)}=2{2 programos („$1“, „$2“)}one{# programa („$1“, „$2“, „$3“)}few{# programos („$1“, „$2“, „$3“)}many{# programos („$1“, „$2“, „$3“)}other{# programų („$1“, „$2“, „$3“)}}</translation>
<translation id="2625385379895617796">Jūsų laikrodis skuba</translation>
<translation id="2639739919103226564">BÅ«sena:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Prieiga prie failo atmesta</translation>
<translation id="2653659639078652383">Pateikti</translation>
<translation id="2666117266261740852">Uždarykite kitus skirtukus arba programas</translation>
+<translation id="2670429602441959756">Šiame puslapyje yra funkcijų, kurios dar nepalaikomos VR. Išeinama...</translation>
<translation id="2674170444375937751">Ar tikrai norite pašalinti šiuos puslapius iš savo istorijos?</translation>
<translation id="2677748264148917807">IÅ¡eiti</translation>
-<translation id="269990154133806163">Serveris pateikė sertifikatą, kuris nebuvo viešai atskleistas naudojant sertifikato skaidrumo politiką. Tai yra tam tikriems sertifikatams taikomas reikalavimas, siekiant užtikrinti, kad jie patikimi ir apsaugo nuo užpuolikų. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Skait. sąraš.</translation>
<translation id="2704283930420550640">VertÄ— neatitinka formato.</translation>
<translation id="2704951214193499422">Šiuo metu „Chromium“ negali patvirtinti jūsų kortelės. Vėliau bandykite dar kartą.</translation>
<translation id="2705137772291741111">IÅ¡saugotos (talpykloje esanÄios) Å¡ios svetainÄ—s kopijos negalima skaityti.</translation>
<translation id="2709516037105925701">Automatinis pildymas</translation>
-<translation id="2712118517637785082">Bandėte pasiekti <ph name="DOMAIN" />, bet sertifikatą, kurį pateikė serveris, anuliavo jo išdavėjas. Tai reiškia, kad serverio pateikti saugos prisijungimo duomenys yra visiškai nepatikimi. Gali būti, kad bendraujate su užpuoliku. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Prašyti leidimo</translation>
<translation id="2713444072780614174">Balta</translation>
<translation id="2720342946869265578">Netoliese</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Trūksta įrenginio įrašo</translation>
<translation id="2784949926578158345">Ryšys atkurtas.</translation>
<translation id="2794233252405721443">Svetainė užblokuota</translation>
+<translation id="2799020568854403057">Pateiktoje svetainėje yra kenkėjiškų programų</translation>
+<translation id="2803306138276472711">„Google“ saugaus narÅ¡ymo sistema neseniai <ph name="BEGIN_LINK" />aptiko kenkÄ—jiÅ¡kų programų<ph name="END_LINK" /> svetainÄ—je <ph name="SITE" />. Kartais svetainÄ—s, kurios paprastai yra saugios, užkreÄiamos kenkÄ—jiÅ¡komis programomis.</translation>
<translation id="2824775600643448204">Adreso ir paieškos juosta</translation>
<translation id="2826760142808435982">Ryšys užšifruotas ir tapatybė nustatyta naudojant <ph name="CIPHER" />. <ph name="KX" /> naudojamas kaip pagrindinis mainų mechanizmas.</translation>
<translation id="2835170189407361413">Valyti formÄ…</translation>
+<translation id="2856444702002559011">Užpuolikai gali bandyti pavogti jūsų informaciją iš <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (pvz., slaptažodžius, pranešimus ar kredito kortelių duomenis). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Neįkelti iš naujo</translation>
<translation id="2900469785430194048">„Google Chrome“ trūksta atminties šiam tinklalapiui pateikti.</translation>
<translation id="2909946352844186028">Aptiktas tinklo pasikeitimas.</translation>
<translation id="2916038427272391327">Uždarykite kitas programas</translation>
<translation id="2922350208395188000">Neįmanoma patikrinti serverio sertifikato.</translation>
<translation id="2928905813689894207">Atsiskaitymo adresas</translation>
+<translation id="2941952326391522266">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas yra iš <ph name="DOMAIN2" />. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="2948083400971632585">Galite neleisti visų tarpinių serverių, jungimasis prie kurių sukonfigūruotas nustatymų puslapyje.</translation>
<translation id="2955913368246107853">Uždaryti paieškos juostą</translation>
<translation id="2958431318199492670">Tinklo konfigūracija neatitinka ONC standarto. Kai kurių konfigūracijos dalių neįmanoma importuoti.</translation>
-<translation id="29611076221683977">Šiuo metu svetainės <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolėjai gali jūsų „Mac“ įrenginyje bandyti įdiegti pavojingas programas, kurios vagia arba ištrina informaciją (pvz., nuotraukas, slaptažodžius, pranešimus ir kredito kortelių numerius).</translation>
<translation id="2966678944701946121">Galiojimo laiko pabaiga: <ph name="EXPIRATION_DATE_ABBR" />, pridÄ—ta <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Kad užmegztumėte saugų ryšį, turėsite tinkamai nustatyti laikrodį. To reikia, nes svetainių tapatybei įrodyti naudojami sertifikatai galioja tik tam tikru laikotarpiu. Įrenginio laikrodis nustatytas netinkamai, todėl „Google Chrome“ negali patvirtinti šių sertifikatų.</translation>
<translation id="2972581237482394796">&amp;Atlikti iš naujo</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Įveskite tinkamą adresą</translation>
<translation id="2986368408720340940">Å is paÄ—mimo metodas nepasiekiamas. IÅ¡bandykite kitÄ… metodÄ….</translation>
<translation id="2991174974383378012">Bendrinimas su svetainÄ—mis</translation>
+<translation id="2991571918955627853">Negalite dabar apsilankyti <ph name="SITE" />, nes svetainėje naudojama HSTS. Tinklo klaidos ir užpuolimai dažniausiai yra laikini, todėl šis puslapis vėliau tikriausiai veiks.</translation>
<translation id="3005723025932146533">Rodyti išsaugotą kopiją</translation>
<translation id="3008447029300691911">Įveskite „<ph name="CREDIT_CARD" />“ kortelės saugos kodą (CVC). Kai patvirtinsite, išsami kortelės informacija bus bendrinama su šia svetaine.</translation>
<translation id="3010559122411665027">Sąrašo įrašas „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatiškai užblokuota</translation>
<translation id="3024663005179499861">Netinkamas politikos tipas</translation>
<translation id="3032412215588512954">Ar norite iš naujo įkelti šią svetainę?</translation>
<translation id="3037605927509011580">Oi!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{mažiausiai 1 elementas sinchronizuotuose įrenginiuose}=1{1 elementas (ir dar daugiau sinchronizuotuose įrenginiuose)}one{# elementas (ir dar daugiau sinchronizuotuose įrenginiuose)}few{# elementai (ir dar daugiau sinchronizuotuose įrenginiuose)}many{# elemento (ir dar daugiau sinchronizuotuose įrenginiuose)}other{# elementų (ir dar daugiau sinchronizuotuose įrenginiuose)}}</translation>
<translation id="3041612393474885105">Sertifikato informacija</translation>
<translation id="3063697135517575841">Šiuo metu „Chrome“ negali patvirtinti jūsų kortelės. Vėliau bandykite dar kartą.</translation>
<translation id="3064966200440839136">Išjungiate inkognito režimą, kad galėtumėte sumokėti naudodami išorinę programą. Tęsti?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Nėra}=1{1 slaptažodis}one{# slaptažodis}few{# slaptažodžiai}many{# slaptažodžio}other{# slaptažodžių}}</translation>
<translation id="3093245981617870298">Esate neprisijungÄ™.</translation>
<translation id="3105172416063519923">IÅ¡tekliaus ID:</translation>
<translation id="3109728660330352905">Neturite prieigos teisės žiūrėti šį puslapį.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Pabandykite paleisti ryšio diagnostikos įrankį<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Iššifruojant atsakymą įvyko klaida</translation>
<translation id="3150653042067488994">Laikina serverio klaida</translation>
@@ -247,17 +277,21 @@
<translation id="3167968892399408617">Puslapiai, kuriuos peržiūrite inkognito skirtukų lapuose, nebus rodomi naršyklės istorijoje, slapukų saugykloje ar paieškos istorijoje, kai uždarysite visus inkognito skirtukų lapus. Visi atsisiųsti failai ar sukurtos žymės išliks.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Sala</translation>
+<translation id="317583078218509884">Nauji svetainės leidimų nustatymai pradės galioti iš naujo įkėlus puslapį.</translation>
<translation id="3176929007561373547">Patikrinkite tarpinio serverio nustatymus arba susisiekite su tinklo
administratoriumi, kad įsitikintumėte, jog tarpinis
serveris veikia. Jei manote, kad tarpinio serverio
naudoti nereikia:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Atidarykite puslapį inkognito režimu</translation>
-<translation id="3202578601642193415">Naujausia</translation>
+<translation id="320323717674993345">Atšaukti mokėjimą</translation>
<translation id="3207960819495026254">Pažymėta</translation>
+<translation id="3225919329040284222">Serveris pateikė sertifikatą, kuris neatitinka numatytų reikalavimų. Šie reikalavimai taikomi tam tikrose itin saugiose svetainėse, kad jūs būtumėte saugūs.</translation>
<translation id="3226128629678568754">Spustelėkite įkėlimo iš naujo mygtuką, kad iš naujo pateiktumėte duomenis, reikalingus puslapiui įkelti.</translation>
+<translation id="3227137524299004712">Mikrofonas</translation>
<translation id="3228969707346345236">IÅ¡versti nepavyko, nes puslapis jau yra <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Įveskite „<ph name="CREDIT_CARD" />“ kortelės saugos kodą (CVC)</translation>
+<translation id="3234666976984236645">Visada aptikti svarbų turinį šioje svetainėje</translation>
<translation id="3254409185687681395">Įtraukti šį puslapį į žymes</translation>
<translation id="3270847123878663523">&amp;Anuliuoti pertvarkymÄ…</translation>
<translation id="3282497668470633863">Ant kortelÄ—s pateikto vardo pridÄ—jimas</translation>
@@ -271,42 +305,48 @@
<translation id="3340978935015468852">nustatymų</translation>
<translation id="3345135638360864351">Nepavyko <ph name="NAME" /> išsiųsti jūsų prieigos prie šios svetainės užklausos. Bandykite dar kartą.</translation>
<translation id="3355823806454867987">Pakeisti įgaliotojo serverio nustatymus...</translation>
+<translation id="3361596688432910856">„Chrome“ <ph name="BEGIN_EMPHASIS" />nesaugos<ph name="END_EMPHASIS" /> šios informacijos:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />naršymo istorijos;
+ <ph name="LIST_ITEM" />slapukų ir svetainių duomenų;
+ <ph name="LIST_ITEM" />formose įvestos informacijos.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Laikrodžio klaida</translation>
-<translation id="337311366426640088">Dar elementų: <ph name="ITEM_COUNT" />...</translation>
<translation id="337363190475750230">Teikimas nutrauktas</translation>
<translation id="3377188786107721145">Politikos analizÄ—s klaida</translation>
<translation id="3380365263193509176">Nežinoma klaida</translation>
<translation id="3380864720620200369">Kliento ID:</translation>
<translation id="3391030046425686457">Pristatymo adresas</translation>
<translation id="3395827396354264108">PaÄ—mimo metodas</translation>
-<translation id="340013220407300675">Atakas vykdanÄios programos gali bandyti pavogti informacijÄ… iÅ¡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (pavyzdžiui, slaptažodžius, praneÅ¡imus arba kredito kortelių informacijÄ…).</translation>
<translation id="3422248202833853650">Pabandykite išeiti iš kitų programų, kad atlaisvintumėte atminties.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> Å¡iuo metu nepasiekiama.</translation>
+<translation id="3427092606871434483">Leisti (numatytoji parinktis)</translation>
<translation id="3427342743765426898">&amp;Redaguoti dar kartÄ…</translation>
<translation id="3431636764301398940">Išsaugoti šią kortelę šiame įrenginyje</translation>
<translation id="3435896845095436175">Įgalinti</translation>
<translation id="3447661539832366887">Įrenginio savininkas išjungė dinozauro žaidimą.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Gauti intervalÄ…:</translation>
<translation id="3462200631372590220">Slėpti išsamią informaciją</translation>
<translation id="3467763166455606212">BÅ«tina nurodyti kortelÄ—s savininko vardÄ… ir pavardÄ™</translation>
<translation id="3478058380795961209">Gal. pab. mÄ—nuo</translation>
<translation id="3479539252931486093">Ar tai buvo netikėta? <ph name="BEGIN_LINK" />Praneškime mums apie tai<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ne dabar</translation>
-<translation id="348000606199325318">Strigties ID <ph name="CRASH_LOCAL_ID" /> (serverio ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Šiuo metu nepavyko susisiekti su jūsų tėvu. Bandykite dar kartą.</translation>
<translation id="3528171143076753409">Serverio sertifikatas nepatikimas.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Mažiausiai 1 elementas sinchronizuotuose įrenginiuose}=1{1 elementas (ir daugiau sinchronizuotuose įrenginiuose)}one{# elementas (ir daugiau sinchronizuotuose įrenginiuose)}few{# elementai (ir daugiau sinchronizuotuose įrenginiuose)}many{# elemento (ir daugiau sinchronizuotuose įrenginiuose)}other{# elementų (ir daugiau sinchronizuotuose įrenginiuose)}}</translation>
<translation id="3539171420378717834">Išsaugoti kortelės kopiją įrenginyje</translation>
<translation id="3542684924769048008">Slaptažodį naudoti:</translation>
+<translation id="3545341443414427877">Nepavyksta užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes kompiuterio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Å ifruoti visus sinchronizuotus duomenis naudojant sinchronizavimo slaptafrazÄ™</translation>
-<translation id="3549761410225185768">Dar <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas yra iš <ph name="DOMAIN2" />. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Jūsų valdytojas gali atblokuoti ją už jus</translation>
<translation id="3566021033012934673">Jūsų ryšys nėra privatus</translation>
+<translation id="3569145463236695319">&lt;p&gt;Nepavyksta užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes įrenginio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami.&lt;/p&gt;
+
+ &lt;p&gt;Koreguokite datą ir laiką programos &lt;strong&gt;Settings&lt;/strong&gt; skiltyje &lt;strong&gt;General&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">PridÄ—ti vardÄ…</translation>
<translation id="3583757800736429874">&amp;Perkelti dar kartÄ…</translation>
<translation id="3586931643579894722">Slėpti išsamią informaciją</translation>
-<translation id="3587482841069643663">Visi</translation>
<translation id="3600246354004376029">„<ph name="TITLE" />“, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Įveskite tinkamą galiojimo laiko pabaigos datą</translation>
<translation id="36224234498066874">Išvalyti naršymo duomenis...</translation>
@@ -323,7 +363,6 @@
<translation id="3681007416295224113">Sertifikato informacija</translation>
<translation id="3690164694835360974">Prisijungimas nesaugus</translation>
<translation id="3693415264595406141">Slaptažodis:</translation>
-<translation id="3696411085566228381">nÄ—ra</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Įkeliama...</translation>
<translation id="3712624925041724820">Licencijos baigÄ—si</translation>
@@ -331,12 +370,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Patikrinti tarpinio serverio, užkardos ir DNS konfigūraciją<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Jei suprantate, kokia rizika gali kilti jūsų saugai, galite <ph name="BEGIN_LINK" />apsilankyti šioje nesaugioje svetainėje<ph name="END_LINK" />, kol iš jos dar nepašalintos pavojingos programos.</translation>
<translation id="3739623965217189342">Nukopijuota nuoroda</translation>
+<translation id="3744899669254331632">Negalite dabar apsilankyti svetainėje <ph name="SITE" />, nes ji atsiuntė užšifruotus prisijungimo duomenis, kurių „Chromium“ negali apdoroti. Tinklo klaidos ir užpuolimai dažniausiai yra laikini, todėl šis puslapis vėliau tikriausiai veiks.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolikai gali bandyti apgaule priversti jus atlikti pavojingus veiksmus, pvz., įdiegti programinę įrangą ar atskleisti asmens informaciją (pvz., slaptažodžius, telefonų numerius ar kredito kortelių duomenis). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Vertimas nepavyko dÄ—l serverio klaidos.</translation>
<translation id="3759461132968374835">NÄ—ra strigÄių, apie kurias buvo neseniai praneÅ¡ta. Strigtys, įvykusios tuo metu, kai strigÄių ataskaitų teikimas buvo iÅ¡jungtas, Äia rodomos nebus.</translation>
+<translation id="3778403066972421603">Ar norite išsaugoti šią kortelę „Google“ paskyroje ir šiame įrenginyje?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Galiojimo laikas baigiasi <ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Jei naudojate tarpinį serverį…</translation>
<translation id="3828924085048779000">Neleidžiama naudoti tuÅ¡Äios slaptafrazÄ—s.</translation>
-<translation id="3845539888601087042">Rodoma įrenginių, kuriuose esate prisijungę, istorija. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Grįžti</translation>
<translation id="3858027520442213535">Atnaujinti datÄ… ir laikÄ…</translation>
<translation id="3884278016824448484">Nesuderinamas įrenginio identifikatorius</translation>
@@ -344,11 +386,13 @@
<translation id="3886446263141354045">Jūsų užklausa pasiekti šią svetainę išsiųsta <ph name="NAME" />.</translation>
<translation id="3890664840433101773">Pridėti el. pašto adresą</translation>
<translation id="3901925938762663762">KortelÄ— nebegalioja</translation>
-<translation id="3933571093587347751">{1,plural, =1{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios nuo rytojaus. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}one{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienos. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}few{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienų. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}many{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienos. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}other{Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas įsigalios po # dienų. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Nepavyko įkelti PDF dokumento</translation>
+<translation id="3945915738023014686">Įkeltos strigties ataskaitos ID: <ph name="CRASH_ID" /> (vietinės strigties ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikate nenurodomi temos alternatyvūs pavadinimai. Tai gali būti dėl netinkamos konfigūracijos arba dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="3963721102035795474">Skaitytojo režimas</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Nėra}=1{Iš 1 svetainės }one{Iš # svetainės }few{Iš # svetainių }many{Iš # svetainės }other{Iš # svetainių }}</translation>
<translation id="397105322502079400">SkaiÄiuojama...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> užblokuota.</translation>
+<translation id="3987940399970879459">Mažiau nei 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 tinklalapis netoliese}one{# tinklalapis netoliese}few{# tinklalapiai netoliese}many{# tinklalapio netoliese}other{# tinklalapių netoliese}}</translation>
<translation id="4021036232240155012">DNS – tai tinklo paslauga, verÄianti svetainÄ—s pavadinimÄ… į interneto adresÄ….</translation>
<translation id="4030383055268325496">&amp;Anuliuoti pridÄ—jimÄ…</translation>
@@ -359,56 +403,63 @@
<translation id="4079302484614802869">Įgaliotojo serverio konfigūracijoje nustatyta naudoti .pac scenarijaus URL, o ne fiksuotus įgaliotuosius serverius.</translation>
<translation id="4098354747657067197">Ketinate apsilankyti apgaulingoje svetainÄ—je</translation>
<translation id="4103249731201008433">Netinkamas įrenginio serijos numeris</translation>
+<translation id="410351446219883937">Automatinis paleidimas</translation>
<translation id="4103763322291513355">Apsilankykite &lt;strong&gt;chrome://policy&lt;/strong&gt;, kad peržiūrėtumėte į juodąjį sąrašą įtrauktų URL sąrašą ir kitą politiką, kurią priverstinai paleido sistemos administratorius.</translation>
-<translation id="4110615724604346410">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikate yra klaidų. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">PurpurinÄ—</translation>
+<translation id="4116663294526079822">Visada leisti Å¡ioje svetainÄ—je</translation>
<translation id="4117700440116928470">Politikos aprÄ—ptis nepalaikoma.</translation>
-<translation id="4118212371799607889">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; „Chromium“ negali pasitikėti jo saugos sertifikatu. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{Dar 1}one{Dar #}few{Dar #}many{Dar #}other{Dar #}}</translation>
<translation id="4130226655945681476">Patikrinti tinklo laidus, modemą ir maršruto parinktuvą</translation>
+<translation id="413544239732274901">Sužinokite daugiau</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Naudoti visuotinį numatytąjį nustatymą (nustatyti)</translation>
+<translation id="4165986682804962316">SvetainÄ—s nustatymai</translation>
<translation id="4169947484918424451">Ar norite, kad „Chromium“ išsaugotų šią kortelę?</translation>
<translation id="4171400957073367226">Netinkamas patvirtinimo parašas</translation>
<translation id="4196861286325780578">&amp;Perkelti dar kartÄ…</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Patikrinti užkardos ir antivirusinės sistemos konfigūracijas<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{nėra}=1{1 programa („$1“)}=2{2 programos („$1“, „$2“)}one{# programa („$1“, „$2“, „$3“)}few{# programos („$1“, „$2“, „$3“)}many{# programos („$1“, „$2“, „$3“)}other{# programų („$1“, „$2“, „$3“)}}</translation>
<translation id="4220128509585149162">Gedimai</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolikai gali bandyti apgaule priversti jus įdiegti narÅ¡ymo funkcijas trikdanÄių programų (pvz., pakeitÄ™ pagrindinį puslapį ar rodydami papildomų skelbimų svetainÄ—se, kuriose lankotÄ—s). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Pabandykite paleisti „Windows Network Diagnostics“<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Tinkamas</translation>
<translation id="4250431568374086873">Ryšys su šia svetaine nėra visiškai saugus</translation>
<translation id="4250680216510889253">Ne</translation>
<translation id="425582637250725228">Atlikti pakeitimai gali nebūti išsaugoti.</translation>
<translation id="4258748452823770588">Netinkamas parašas</translation>
+<translation id="4265872034478892965">Leidžia jūsų administratorius</translation>
<translation id="4269787794583293679">(NÄ—ra naudotojo vardo)</translation>
<translation id="4275830172053184480">Iš naujo paleisti įrenginį</translation>
<translation id="4280429058323657511">, gal. pab. <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">„Google“ saugaus naršymo funkcija neseniai <ph name="BEGIN_LINK" />aptiko žalingų programų<ph name="END_LINK" /> svetainėje <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Pasiūlymai tėvams</translation>
<translation id="4304224509867189079">Prisijungti</translation>
-<translation id="432290197980158659">Serveris pateikė sertifikatą, kuris neatitinka integruotų reikalavimų. Šie reikalavimai taikomi tam tikrose aukšto saugos lygio svetainėse, kad būtumėte saugūs. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Užblokuoti (numatytoji parinktis)</translation>
<translation id="4325863107915753736">Nepavyko rasti straipsnio</translation>
<translation id="4326324639298822553">Patikrinkite galiojimo pabaigos datÄ… ir bandykite dar kartÄ…</translation>
<translation id="4331708818696583467">Nesaugi</translation>
<translation id="4356973930735388585">Šios svetainės užpuolėjai gali jūsų kompiuteryje bandyti įdiegti pavojingas programas, kurios vagia arba ištrina informaciją (pvz., nuotraukas, slaptažodžius, pranešimus ir kredito kortelių numerius).</translation>
<translation id="4372948949327679948">Numatyta „<ph name="VALUE_TYPE" />“ vertė.</translation>
+<translation id="4377125064752653719">Bandėte pasiekti svetainę „<ph name="DOMAIN" />“, bet sertifikatą, kurį pateikė serveris, anuliavo jo išdavėjas. Tai reiškia, kad saugos kredencialais, kuriuos pateikė serveris, visiškai negalima pasitikėti. Galbūt bendraujate su užpuoliku.</translation>
<translation id="4381091992796011497">Naudotojo vardas:</translation>
<translation id="4394049700291259645">Neleisti</translation>
<translation id="4406896451731180161">paieškos rezultatai</translation>
+<translation id="4424024547088906515">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas nėra patikimas „Chrome“. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> nepriėmė jūsų prisijungimo sertifikato arba prisijungimo sertifikatas nebuvo pateiktas.</translation>
<translation id="443673843213245140">Įgaliotojo serverio naudojimas neleidžiamas, bet nurodyta aiški įgaliotojo serverio konfigūracija.</translation>
-<translation id="4492190037599258964">„<ph name="SEARCH_STRING" />“ paieškos rezultatai</translation>
<translation id="4506176782989081258">Tikrinimo klaida: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Susisiekti su sistemos administratoriumi</translation>
<translation id="450710068430902550">Bendrinimas su administratoriumi</translation>
<translation id="4515275063822566619">Kortelės ir adresai naudojami iš „Chrome“ ir jūsų „Google“ paskyros (<ph name="ACCOUNT_EMAIL" />). Galite juos tvarkyti skiltyje <ph name="BEGIN_LINK" />Nustatymai<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">IÅ¡sami informacija</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Pabandykite išjungti plėtinius.</translation>
<translation id="457875822857220463">Pristatymas</translation>
<translation id="4587425331216688090">Pašalinti adresą iš „Chrome“?</translation>
-<translation id="4589078953350245614">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė netinkamą sertifikatą. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Ryšys su <ph name="DOMAIN" /> užšifruotas naudojant modernų šifravimo paketą.</translation>
<translation id="4594403342090139922">&amp;Anuliuoti ištrynimą</translation>
<translation id="4619615317237390068">Skirtukai iš kitų įrenginių</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikate yra klaidų. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
+<translation id="4690462567478992370">Nebenaudoti negaliojanÄio sertifikato</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Ryšys nutrauktas</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Paleistas įrankis „Windows Network Diagnostics“<ph name="END_LINK" />.</translation>
@@ -425,21 +476,24 @@
<translation id="4771973620359291008">Įvyko nežinoma klaida.</translation>
<translation id="4800132727771399293">Patikrinkite kortelÄ—s galiojimo pabaigos datÄ… bei saugos kodÄ… (CVC) ir bandykite dar kart</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Negalite dabar apsilankyti svetainėje <ph name="SITE" />, nes ji atsiuntė užšifruotus prisijungimo duomenis, kurių „Google Chrome“ negali apdoroti. Tinklo klaidos ir užpuolimai dažniausiai yra laikini, todėl šis puslapis vėliau tikriausiai veiks.</translation>
<translation id="4813512666221746211">Tinklo klaida</translation>
<translation id="4816492930507672669">Pritaikyti pagal puslapį</translation>
<translation id="483020001682031208">Nėra rodytinų Fizinio žiniatinklio puslapių</translation>
<translation id="4850886885716139402">Žiūrėti</translation>
<translation id="4854362297993841467">Å is pristatymo metodas nepasiekiamas. IÅ¡bandykite kitÄ… metodÄ….</translation>
<translation id="4858792381671956233">Paprašėte tėvų leidimo apsilankyti šiame puslapyje</translation>
+<translation id="4863764087567530506">Šiuo turiniu gali būti bandoma apgaule priversti jus įdiegti programinę įrangą arba atskleisti asmens informaciją. <ph name="BEGIN_LINK" />Rodyti vis tiek<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Ieškoti istorijoje</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ir dar 1 tinklalapis}one{ir dar # tinklalapis}few{ir dar # tinklalapiai}many{ir dar # tinklalapio}other{ir dar # tinklalapių}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Šis puslapis išverstas iš nežinomos kalbos į <ph name="LANGUAGE_LANGUAGE" /> k.</translation>
<translation id="4923459931733593730">MokÄ—jimas</translation>
<translation id="4926049483395192435">Turi būti nurodyta.</translation>
<translation id="495170559598752135">Veiksmai</translation>
<translation id="4958444002117714549">Išskleisti sąrašą</translation>
-<translation id="4962322354953122629">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; „Chrome“ negali pasitikėti jo saugos sertifikatu. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Iš naujo įgalinti įspėjimus</translation>
<translation id="4989809363548539747">Å is papildinys nepalaikomas</translation>
<translation id="5002932099480077015">Jei Å¡is nustatymas įgalintas, „Chrome“ saugos kortelÄ—s kopijÄ… Å¡iame įrenginyje, kad bÅ«tų galima greiÄiau užpildyti formas.</translation>
<translation id="5018422839182700155">Negalima atidaryti Å¡io puslapio</translation>
@@ -447,14 +501,15 @@
<translation id="5023310440958281426">Patikrinkite savo administratoriaus politikÄ…</translation>
<translation id="5029568752722684782">IÅ¡valyti kopijÄ…</translation>
<translation id="5031870354684148875">Apie „Google“ vertėją</translation>
+<translation id="5039804452771397117">Leisti</translation>
<translation id="5040262127954254034">Privatumas</translation>
<translation id="5045550434625856497">Neteisingas slaptažodis</translation>
<translation id="5056549851600133418">Jums skirti straipsniai</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Patikrinti tarpinio serverio adresÄ…<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Nėra jokių slapukų}=1{1 svetainė naudoja slapukus. }one{# svetainė naudoja slapukus. }few{# svetainės naudoja slapukus. }many{# svetainės naudoja slapukus. }other{# svetainių naudoja slapukus. }}</translation>
<translation id="5087286274860437796">Å iuo metu serverio sertifikatas negalioja.</translation>
<translation id="5087580092889165836">PridÄ—ti kortelÄ™</translation>
<translation id="5089810972385038852">Valstija</translation>
+<translation id="5094747076828555589">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas nėra patikimas „Chromium“. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="5095208057601539847">Provincija</translation>
<translation id="5115563688576182185">(64 bitų)</translation>
<translation id="5141240743006678641">Šifruoti sinchronizuotus slaptažodžius naudojant „Google“ prisijungimo duomenis</translation>
@@ -470,24 +525,24 @@
<translation id="5222812217790122047">Būtina nurodyti el. paštą</translation>
<translation id="5251803541071282808">Debesis</translation>
<translation id="5277279256032773186">Naudojate „Chrome“ darbe? Įmonės gali tvarkyti darbuotojų „Chrome“ nustatymus. Sužinokite daugiau</translation>
+<translation id="5297526204711817721">Ryšys su šia svetaine nėra privatus. Kad galėtumėte bet kada išeiti iš virtualiosios realybės režimo, pašalinkite ausines ir paspauskite „Atgal“.</translation>
<translation id="5299298092464848405">Analizuojant politiką įvyko klaida</translation>
-<translation id="5300589172476337783">Rodyti</translation>
<translation id="5308689395849655368">StrigÄių ataskaitų teikimas neleidžiamas.</translation>
<translation id="5317780077021120954">IÅ¡saugoti</translation>
<translation id="5327248766486351172">Pavadinimas</translation>
-<translation id="5337705430875057403">Svetainės <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolėjai gali bandyti apgaulingai priversti atlikti pavojingus veiksmus, pvz., įdiegti programinę įrangą ar atskleisti asmeninę informaciją (pvz., slaptažodžius, telefonų numerius ar kredito kortelių informaciją).</translation>
-<translation id="5359637492792381994">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas šiuo metu negalioja. Taip gali būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Negalite dabar apsilankyti svetainėje <ph name="SITE" />, nes jos sertifikatas buvo anuliuotas. Tinklo klaidos ir užpuolimai dažniausiai yra laikini, todėl šis puslapis vėliau tikriausiai veiks.</translation>
<translation id="536296301121032821">Išsaugant politikos nustatymus įvyko klaida</translation>
<translation id="5386426401304769735">Šios svetainės sertifikatų grandinėje yra sertifikatas, pasirašytas naudojant SHA-1.</translation>
<translation id="5402410679244714488">Gal. l. pab.: <ph name="EXPIRATION_DATE_ABBR" />, pask. k. naudota daugiau nei prieš metus</translation>
+<translation id="540969355065856584">Šiam serveriui nepavyko patvirtinti, kad jis yra <ph name="DOMAIN" />; šiuo metu jo saugos sertifikatas negalioja. Tai gali būti dėl netinkamos konfigūracijos arba dėl ryšį pertraukusio užgrobėjo.</translation>
<translation id="5421136146218899937">Išvalyti naršymo duomenis...</translation>
<translation id="5430298929874300616">Pašalinti žymę</translation>
<translation id="5431657950005405462">Failas nerastas</translation>
-<translation id="5435775191620395718">Rodoma šio įrenginio istorija. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Schemos patvirtinimo klaida „<ph name="ERROR_PATH" />“: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Nepavyksta rasti Å¡io <ph name="HOST_NAME" /> puslapio</translation>
<translation id="5455374756549232013">Bloga politikos laiko žymė</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> iš <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Netinkama</translation>
<translation id="5470861586879999274">&amp;Redaguoti dar kartÄ…</translation>
<translation id="54817484435770891">Tinkamo adreso pridÄ—jimas</translation>
<translation id="5492298309214877701">Šios svetainės URL įmonės, organizacijos ar mokyklos intranete toks pat kaip išorinės svetainės URL.
@@ -504,6 +559,8 @@
<translation id="5571083550517324815">Negalima paimti Å¡iuo adresu. Pasirinkite kitÄ… adresÄ….</translation>
<translation id="5572851009514199876">Pirmiausia prisijunkite prie „Chrome“, kad „Chrome“ galėtų patikrinti, ar jums leidžiama pasiekti šią svetainę.</translation>
<translation id="5580958916614886209">Patikrinkite galiojimo pabaigos mėnesį ir bandykite dar kartą</translation>
+<translation id="5586446728396275693">Nėra išsaugotų adresų</translation>
+<translation id="5595485650161345191">Adreso redagavimas</translation>
<translation id="560412284261940334">Tvarkymas nepalaikomas</translation>
<translation id="5610142619324316209">Patikrinti ryšį</translation>
<translation id="5610807607761827392">Korteles ir adresus galite tvarkyti skiltyje <ph name="BEGIN_LINK" />Nustatymai<ph name="END_LINK" />.</translation>
@@ -511,15 +568,18 @@
<translation id="5622887735448669177">Ar norite išeiti iš šios svetainės?</translation>
<translation id="5629630648637658800">Įkeliant politikos nustatymus įvyko klaida</translation>
<translation id="5631439013527180824">Netinkamas įrenginio tvarkymo prieigos raktas</translation>
+<translation id="5633066919399395251">Šiuo metu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolikai gali jūsų kompiuteryje bandyti įdiegti pavojingas programas, kurios vagia arba ištrina informaciją (pvz., nuotraukas, slaptažodžius, pranešimus ir kredito kortelių duomenis). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">VietovÄ—</translation>
+<translation id="5659593005791499971">El. paštas</translation>
<translation id="5669703222995421982">Suasmeninto turinio gavimas</translation>
<translation id="5675650730144413517">Å is puslapis neveikia</translation>
-<translation id="5677928146339483299">Užblokuota</translation>
-<translation id="5694783966845939798">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė sertifikatą, kuris pasirašytas naudojant nesudėtingą parašo algoritmą (pvz., SHA-1). Tai reiškia, kad serverio pateikti saugos prisijungimo duomenys galėjo būti suklastoti ir serveris gali būti ne tas, kurio tikėjotės (gali būti, kad bendraujate su užpuoliku). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Å io tinklalapio tapatybÄ— nenustatyta.</translation>
+<translation id="5713016350996637505">Klaidinantis turinys užblokuotas</translation>
<translation id="5720705177508910913">Dabartinis naudotojas</translation>
<translation id="5732392974455271431">Jūsų tėvai gali atblokuoti ją už jus</translation>
<translation id="5763042198335101085">Įveskite galiojantį el. pašto adresą</translation>
<translation id="5765072501007116331">Jei norite peržiūrėti pristatymo metodus ir reikalavimus, pasirinkite adresą.</translation>
+<translation id="5778550464785688721">MIDI įrenginių visateisis valdymas</translation>
<translation id="5784606427469807560">Patvirtinant kortelę kilo problema. Patikrinkite interneto ryšį ir bandykite dar kartą.</translation>
<translation id="5785756445106461925">Be to, šiame puslapyje yra kitų nesaugių išteklių. Perduodant duomenis šiuos išteklius gali peržiūrėti kiti asmenys ir keisti atakuojanti programa, siekianti pakeisti puslapio išvaizdą.</translation>
<translation id="5786044859038896871">Ar norite, kad būtų įvesta jūsų kredito kortelės informacija?</translation>
@@ -528,14 +588,14 @@
<translation id="5813119285467412249">&amp;PridÄ—ti dar kartÄ…</translation>
<translation id="5814352347845180253">Galite prarasti prieigÄ… prie aukÅ¡Äiausios kokybÄ—s turinio iÅ¡ <ph name="SITE" /> ir kelių kitų svetainių.</translation>
<translation id="5838278095973806738">Šioje svetainėje neturėtumėte pateikti neskelbtinos informacijos (pvz., slaptažodžių ar kredito kortelių numerių), nes ją gali pavogti užpuolikai.</translation>
-<translation id="5843436854350372569">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė nesudėtingą raktą turintį sertifikatą. Užpuolikas galėjo užvaldyti privatų raktą, o šis serveris gali būti ne tas, kurio tikėjotės (gali būti, kad bendraujate su užpuoliku). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Nepavyksta pasiekti Å¡ios svetainÄ—s</translation>
<translation id="5869522115854928033">Išsaugoti slaptažodžiai</translation>
<translation id="5872918882028971132">Pasiūlymai tėvams</translation>
<translation id="5901630391730855834">Geltona</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sinchronizuota)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{Naudojamas 1 slapukas}one{Naudojamas # slapukas}few{Naudojami # slapukai}many{Naudojama # slapuko}other{Naudojama # slapukų}}</translation>
<translation id="5926846154125914413">Galite prarasti prieigÄ… prie aukÅ¡Äiausios kokybÄ—s turinio iÅ¡ kelių svetainių.</translation>
<translation id="5959728338436674663">Automatiškai siųsti tam tikrą <ph name="BEGIN_WHITEPAPER_LINK" />sistemos informaciją ir puslapio turinį<ph name="END_WHITEPAPER_LINK" /> į sistemą „Google“ siekiant padėti aptikti pavojingas programas ir svetaines. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">SavaitÄ—</translation>
<translation id="5967867314010545767">Pašalinti iš istorijos</translation>
<translation id="5975083100439434680">Tolinti</translation>
<translation id="598637245381783098">Nepavyksta atidaryti mokÄ—jimo programos</translation>
@@ -544,21 +604,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1 puslapis}one{# puslapis}few{# puslapiai}many{# puslapio}other{# puslapių}}</translation>
<translation id="6017514345406065928">Žalia</translation>
+<translation id="6017850046339264347">UžgrobÄ—jai svetainÄ—je <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> gali įdiegti klaidinanÄių programų, kurios apsimeta kitomis programomis, arba rinkti duomenis, naudojamus jums stebÄ—ti. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sinchronizuota)</translation>
<translation id="6027201098523975773">Įveskite pavadinimą</translation>
<translation id="6040143037577758943">Uždaryti</translation>
<translation id="6042308850641462728">Daugiau</translation>
+<translation id="6047233362582046994">Jei suprantate, kokia rizika gali kilti jūsų saugai, galite <ph name="BEGIN_LINK" />apsilankyti šioje svetainėje<ph name="END_LINK" />, kol iš jos dar nepašalintos kenkėjiškos programos.</translation>
+<translation id="6051221802930200923">Šiuo metu negalite apsilankyti <ph name="SITE" />, nes svetainėje naudojamas sertifikatų prisegimas. Tinklo klaidos ir užpuolimai dažniausiai yra laikini, todėl šis puslapis vėliau tikriausiai veiks.</translation>
<translation id="6060685159320643512">Atsargiai, šie bandymai gali būti pavojingi</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{nÄ—ra}=1{1}one{#}few{#}many{#}other{#}}</translation>
+<translation id="6080696365213338172">Pasiekėte turinį naudodami administratoriaus pateiktą sertifikatą. Duomenys, kuriuos pateikiate <ph name="DOMAIN" />, gali būti perimti administratoriaus.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Nėra}=1{1 slaptažodis (sinchronizuotas)}one{# slaptažodis (sinchronizuotas)}few{# slaptažodžiai (sinchronizuoti)}many{# slaptažodžio (sinchronizuota)}other{# slaptažodžių (sinchronizuota)}}</translation>
<translation id="6146055958333702838">Patikrinkite laidus ir iš naujo paleiskite maršruto parinktuvus, modemus ar kitus
naudojamus tinklo įrenginius.</translation>
<translation id="614940544461990577">Pabandykite atlikti toliau nurodytus veiksmus.</translation>
<translation id="6151417162996330722">Serverio sertifikato galiojimo laikotarpis per ilgas.</translation>
<translation id="6157877588268064908">Jei norite peržiūrėti pristatymo metodus ir reikalavimus, pasirinkite adresą.</translation>
+<translation id="6158003235852588289">„Google“ saugaus narÅ¡ymo sistema neseniai aptiko sukÄiavimÄ… svetainÄ—je <ph name="SITE" />. SukÄiavimo svetainÄ—s apsimeta kitomis svetainÄ—mis, kad jus apgautų.</translation>
<translation id="6165508094623778733">Sužinokite daugiau</translation>
+<translation id="6169916984152623906">Dabar galite narÅ¡yti privaÄiai, o kiti šį įrenginį naudojantys žmonÄ—s nematys jÅ«sų veiklos. TaÄiau atsisiuntimai ir žymÄ—s bus iÅ¡saugoti.</translation>
<translation id="6177128806592000436">Ryšys su šia svetaine nėra saugus</translation>
<translation id="6184817833369986695">(grupÄ—: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Patikrinkite interneto ryšį</translation>
<translation id="6218753634732582820">Pašalinti adresą iš „Chromium“?</translation>
+<translation id="6221345481584921695">„Google“ saugaus narÅ¡ymo sistema neseniai <ph name="BEGIN_LINK" />aptiko kenkÄ—jiÅ¡kÄ… programÄ…<ph name="END_LINK" /> svetainÄ—je <ph name="SITE" />. SvetainÄ—s, kurios paprastai yra saugios, kartais užkreÄiamos kenkÄ—jiÅ¡komis programomis. KenkÄ—jiÅ¡kas turinys gautas iÅ¡ <ph name="SUBRESOURCE_HOST" />, žinomo kenkÄ—jiÅ¡kų programų platintojo.</translation>
<translation id="6251924700383757765">Privatumo politika</translation>
<translation id="6254436959401408446">Nepakanka atminties, kad būtų galima atidaryti šį puslapį</translation>
<translation id="625755898061068298">Pasirinkote išjungti šios svetainės saugos įspėjimus.</translation>
@@ -584,15 +652,14 @@
<translation id="6404511346730675251">Redaguoti žymę</translation>
<translation id="6410264514553301377">įveskite „<ph name="CREDIT_CARD" />“ galiojimo pabaigos datą ir kortelės saugos kodą (CVC)</translation>
<translation id="6414888972213066896">Paprašėte vieno iš tėvų leidimo apsilankyti šiame puslapyje</translation>
-<translation id="6416403317709441254">Šiuo metu negalite apsilankyti <ph name="SITE" />, nes svetainė atsiuntė užšifruotus prisijungimo duomenis, kurių „Chromium“ negali apdoroti. Tinklo klaidos ir išpuoliai dažniausiai yra laikini, todėl šis puslapis tikriausiai veiks vėliau. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Nepavyksta patikrinti, ar sertifikatas buvo panaikintas.</translation>
<translation id="6433490469411711332">KontaktinÄ—s informacijos redagavimas</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> atsisakÄ— prisijungti.</translation>
<translation id="6446608382365791566">Daugiau informacijos pridÄ—jimas</translation>
+<translation id="6447842834002726250">Slapukai</translation>
<translation id="6451458296329894277">Patvirtinkite pakartotinÄ… formos pateikimÄ…</translation>
<translation id="6456339708790392414">Jūsų mokėjimas</translation>
<translation id="6458467102616083041">Nepaisoma, nes numatytoji paieška neleidžiama pagal politiką.</translation>
-<translation id="6462969404041126431">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; gali būti, kad jo saugos sertifikatas atšauktas. Taip galėjo nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Įrenginio politika</translation>
<translation id="6477321094435799029">„Chrome“ šiame puslapyje aptiko neįprastą kodą ir jį užblokavo, kad apsaugotų asmens informaciją (pvz., slaptažodžius, telefonų numerius ir kredito korteles).</translation>
<translation id="6489534406876378309">Pradėti įkelti strigtis</translation>
@@ -604,20 +671,19 @@
<translation id="6556915248009097796">Galiojimo laiko pabaiga: <ph name="EXPIRATION_DATE_ABBR" />, paskutinį kartą naudota <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Jūsų valdytojas dar jos nepatvirtino</translation>
<translation id="6569060085658103619">Peržiūrite plėtinio puslapį</translation>
-<translation id="6593753688552673085">mažiau nei <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Šiuo turiniu gali būti bandoma priversti jus įrenginyje įdiegti pavojingą programinę įrangą, kuri vagia arba ištrina jūsų informaciją. <ph name="BEGIN_LINK" />Rodyti vis tiek<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Å ifravimo parinktys</translation>
<translation id="662080504995468778">Likti</translation>
<translation id="6626291197371920147">GaliojanÄios kortelÄ—s numerio pridÄ—jimas</translation>
<translation id="6628463337424475685">„<ph name="ENGINE" />“ paieška</translation>
+<translation id="6630809736994426279">Šiuo metu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolikai gali jūsų „Mac“ įrenginyje bandyti įdiegti pavojingas programas, kurios vagia arba ištrina informaciją (pvz., nuotraukas, slaptažodžius, pranešimus ir kredito kortelių duomenis). <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Å i politika nepatvirtinta.</translation>
-<translation id="6652240803263749613">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; kompiuterio operacinė sistema negali pasitikėti jo saugos sertifikatu. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Pašalinti formos pasiūlymą iš „Chromium“?</translation>
<translation id="6685834062052613830">Atsijunkite ir užbaikite sąranką</translation>
<translation id="6710213216561001401">Ankstesnis</translation>
<translation id="6710594484020273272">&lt;Įveskite paieškos terminą&gt;</translation>
<translation id="6711464428925977395">Kažkas negerai su tarpiniu serveriu arba adresas netinkamas.</translation>
<translation id="6727102863431372879">Nustatyti</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{nėra}=1{1 elementas}one{# elementas}few{# elementai}many{# elemento}other{# elementų}}</translation>
<translation id="674375294223700098">Nežinoma serverio sertifikato klaida.</translation>
<translation id="6753269504797312559">Politikos vertÄ—</translation>
<translation id="6757797048963528358">Įjungta įrenginio miego būsena.</translation>
@@ -625,6 +691,8 @@
<translation id="6810899417690483278">Tinkinimo ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Nepavyko įkelti regionų duomenų</translation>
+<translation id="6825578344716086703">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė sertifikatą, kuris pasirašytas naudojant nesudėtingą parašo algoritmą (pvz., SHA-1). Tai reiškia, kad serverio pateikti saugos prisijungimo duomenys galėjo būti suklastoti ir serveris gali būti ne tas, kurio tikėjotės (gali būti, kad bendraujate su užpuoliku).</translation>
+<translation id="6830728435402077660">Nesaugu</translation>
<translation id="6831043979455480757">VertÄ—jas</translation>
<translation id="6839929833149231406">Sritis</translation>
<translation id="6874604403660855544">&amp;PridÄ—ti dar kartÄ…</translation>
@@ -632,6 +700,7 @@
<translation id="6895330447102777224">KortelÄ— patvirtinta</translation>
<translation id="6897140037006041989">Naudotojo atstovas</translation>
<translation id="6915804003454593391">Naudotojas:</translation>
+<translation id="6945221475159498467">Pasirinkti</translation>
<translation id="6948701128805548767">Jei norite peržiūrėti paėmimo metodus ir reikalavimus, pasirinkite adresą</translation>
<translation id="6957887021205513506">Panašu, kad serverio sertifikatas yra suklastotas.</translation>
<translation id="6965382102122355670">Gerai</translation>
@@ -640,15 +709,16 @@
<translation id="6973656660372572881">Nurodyti fiksuoti įgaliotieji serveriai ir .pac scenarijaus URL.</translation>
<translation id="6989763994942163495">Rodyti išplėstinius nustatymus...</translation>
<translation id="7000990526846637657">Nerasta jokių istorijos įrašų</translation>
-<translation id="7009986207543992532">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė sertifikatą, kurio galiojimo laikotarpis per ilgas, kad juo būtų galima pasitikėti. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Adresu <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> gali būti pateikta kitų formų jūsų „Google“ paskyros naršymo istorija</translation>
<translation id="7029809446516969842">Slaptažodžiai</translation>
+<translation id="7050187094878475250">Bandėte pasiekti <ph name="DOMAIN" />, bet serveris pateikė sertifikatą, kurio galiojimo laikotarpis per ilgas, kad būtų patikimas.</translation>
+<translation id="7053983685419859001">Blokuoti</translation>
<translation id="7064851114919012435">KontaktinÄ— informacija</translation>
<translation id="7079718277001814089">Šioje svetainėje yra kenkėjiškų programų</translation>
<translation id="7087282848513945231">Apygarda</translation>
-<translation id="7088615885725309056">AnkstesnÄ—</translation>
<translation id="7090678807593890770">Sistemoje „Google“ atlikite paiešką pagal užklausą „<ph name="LINK" />“</translation>
+<translation id="7108819624672055576">Leidžiama pagal plėtinį</translation>
<translation id="7119414471315195487">Uždarykite kitus skirtukus ir programas</translation>
<translation id="7129409597930077180">Negalima pristatyti Å¡iuo adresu. Pasirinkite kitÄ… adresÄ….</translation>
<translation id="7138472120740807366">Pristatymo metodas</translation>
@@ -666,22 +736,18 @@
<translation id="7220786058474068424">Apdorojama</translation>
<translation id="724691107663265825">Svetainėje, kurioje ketinate apsilankyti, yra kenkėjiškų programų</translation>
<translation id="724975217298816891">Jei norite atnaujinti išsamią kortelės informaciją, įveskite „<ph name="CREDIT_CARD" />“ galiojimo pabaigos datą ir kortelės saugos kodą (CVC). Kai patvirtinsite, išsami kortelės informacija bus bendrinama su šia svetaine.</translation>
-<translation id="725866823122871198">Nepavyksta užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes kompiuterio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami.</translation>
+<translation id="7260504762447901703">Anuliuoti prieigÄ…</translation>
<translation id="7275334191706090484">Tvarkomos žymės</translation>
<translation id="7298195798382681320">Rekomenduojama</translation>
<translation id="7309308571273880165">StrigÄių ataskaita užfiksuota <ph name="CRASH_TIME" /> (įkÄ—limo užklausÄ… pateikÄ— naudotojas, dar neįkelta)</translation>
<translation id="7334320624316649418">&amp;Pertvarkyti dar kartÄ…</translation>
<translation id="733923710415886693">Serverio sertifikatas nebuvo atskleistas taikant sertifikato skaidrumÄ….</translation>
-<translation id="7351800657706554155">Šiuo metu negalite apsilankyti svetainėje <ph name="SITE" />, nes jos sertifikatas anuliuotas. Tinklo klaidos ir išpuoliai dažniausiai laikini, todėl šis puslapis tikriausiai veiks vėliau. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Komandos eilutÄ—</translation>
<translation id="7372973238305370288">paieškos rezultatas</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ne</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">KortelÄ—s patvirtinimas</translation>
-<translation id="7394102162464064926">Ar tikrai norite ištrinti šiuos puslapius iš savo istorijos?
-
-Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORTCUT_KEY" />).</translation>
<translation id="7400418766976504921">URL adresas</translation>
<translation id="7419106976560586862">Profilio kelias</translation>
<translation id="7424977062513257142">Šiame tinklalapyje įterptame puslapyje sakoma:</translation>
@@ -689,6 +755,7 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="7444046173054089907">Ši svetainė užblokuota</translation>
<translation id="7445762425076701745">Nepavyksta visiÅ¡kai patvirtinti serverio, prie kurio esate prisijungÄ™, tapatybÄ—s. Prie serverio esate prisijungÄ™ naudodami tik tinklui galiojantį vardÄ…, kurio nuosavybÄ—s teisių iÅ¡orinÄ— sertifikatÄ… iÅ¡duodanti institucija negali patvirtinti. Nors kai kurios sertifikatus iÅ¡duodanÄios institucijos vis tiek iÅ¡duos sertifikatus pagal Å¡iuos vardus, niekaip nebus galima užtikrinti, kad bÅ«site prisijungÄ™ prie numatytos svetainÄ—s, o ne prie užpuolÄ—jo.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /> apie šią problemą.</translation>
+<translation id="7455133967321480974">Naudoti visuotinį numatytąjį nustatymą (blokuoti)</translation>
<translation id="7460163899615895653">Naujausi kitų įrenginių skirtukai rodomi Äia</translation>
<translation id="7469372306589899959">KortelÄ— patvirtinama</translation>
<translation id="7481312909269577407">Persiųsti</translation>
@@ -696,36 +763,43 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="7508255263130623398">Sugrąžinto politikos įrenginio ID nenurodytas arba neatitinka dabartinio įrenginio ID</translation>
<translation id="7514365320538308">Atsisiųsti</translation>
<translation id="7518003948725431193">Nerasta nė vieno tinklalapio šiuo žiniatinklio adresu: <ph name="URL" /></translation>
+<translation id="7521387064766892559">„JavaScript“</translation>
<translation id="7535087603100972091">Reikšmė</translation>
<translation id="7537536606612762813">Privaloma</translation>
+<translation id="7542403920425041731">Kai patvirtinsite, išsami kortelės informacija bus bendrinama su šia svetaine.</translation>
<translation id="7542995811387359312">Automatinis kredito kortelės informacijos pildymas neleidžiamas, nes šiai formai nenaudojamas saugus ryšys.</translation>
<translation id="7543525346216957623">Paprašykite vieno iš tėvų</translation>
<translation id="7549584377607005141">Jei norite, kad Å¡is tinklalapis bÅ«tų tinkamai pateikiamas, reikalingi anksÄiau įvesti duomenys. Galite nusiųsti Å¡iuos duomenis iÅ¡ naujo, bet taip pakartosite visus anksÄiau Å¡iame puslapyje įvykdytus veiksmus.</translation>
<translation id="7552846755917812628">IÅ¡bandykite toliau pateiktus patarimus.</translation>
<translation id="7554791636758816595">Naujas skirtukas</translation>
+<translation id="7567204685887185387">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas gali būti neteisėtai išduotas. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}many{<ph name="CONTACT_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Šis puslapis yra<ph name="ORIGINAL_LANGUAGE" />Ar norėtumėte jį išversti?</translation>
<translation id="7569952961197462199">Pašalinti kredito kortelės informaciją iš „Chrome“?</translation>
<translation id="7569983096843329377">Juoda</translation>
<translation id="7578104083680115302">Greitai mokėkite svetainėse ir programose įvairiuose įrenginiuose naudodami korteles, kurias išsaugojote „Google“.</translation>
<translation id="7588950540487816470">Fizinis žiniatinklis</translation>
<translation id="7592362899630581445">Serverio sertifikatas pažeidžia pavadinimų apribojimus.</translation>
+<translation id="7598391785903975535">Mažiau nei <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> šiuo metu negalima apdoroti šios užklausos.</translation>
<translation id="7600965453749440009">Niekada neversti <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Vertė nepatenka į diapazoną <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Galioja iki: <ph name="EXPIRATION_YEAR" />-<ph name="EXPIRATION_MONTH" /></translation>
<translation id="7615602087246926389">Jau turite duomenų, kurie šifruojami naudojant kitos versijos „Google“ paskyros slaptažodį. Įveskite juos toliau.</translation>
-<translation id="7634554953375732414">Jūsų ryšys su šia svetaine nėra privatus.</translation>
<translation id="7637571805876720304">Pašalinti kredito kortelės informaciją iš „Chromium“?</translation>
<translation id="765676359832457558">Slėpti išplėstinius nustatymus...</translation>
<translation id="7658239707568436148">Atšaukti</translation>
+<translation id="7662298039739062396">Nustatymas valdomas pagal plėtinį</translation>
<translation id="7667346355482952095">Sugrąžintas politikos prieigos raktas yra tuÅ¡Äias arba neatitinka dabartinio prieigos rakto</translation>
<translation id="7668654391829183341">Nežinomas įrenginys</translation>
<translation id="7669271284792375604">Å ios svetainÄ—s užgrobÄ—jai gali bandyti apgaule priversti jus įdiegti narÅ¡ymo funkcijas trikdanÄių programų (pvz., pakeitÄ™ pagrindinį puslapį ar rodydami papildomų skelbimų svetainÄ—se, kuriose lankotÄ—s).</translation>
<translation id="7674629440242451245">Domina naujos „Chrome“ funkcijos? Išbandykite mūsų kuriamą kanalą adresu chrome.com/dev.</translation>
<translation id="7682287625158474539">Pristatymas</translation>
+<translation id="7701040980221191251">Nieko</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Eiti į svetainę <ph name="SITE" /> (nesaugu)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Sertifikatas</translation>
+<translation id="7716147886133743102">Užblokavo jūsų administratorius</translation>
<translation id="7716424297397655342">Nepavyksta įkelti šios svetainės iš talpyklos</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Netvarkoma</translation>
<translation id="7755287808199759310">Jūsų tėtis ar mama gali ją atblokuoti už jus</translation>
<translation id="7758069387465995638">Gali būti, kad užkarda arba antivirusinė programinė įranga užblokavo ryšį.</translation>
@@ -752,15 +826,15 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="7951415247503192394">(32 bitų)</translation>
<translation id="7956713633345437162">Žymės mobiliesiems</translation>
<translation id="7961015016161918242">Niekada</translation>
-<translation id="7962083544045318153">Strigties ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Visada versti iš <ph name="ORIGINAL_LANGUAGE" /> į <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Nenurodytas</translation>
<translation id="800218591365569300">Pabandykite uždaryti skirtukus arba kitas programas, kad atlaisvintumėte atminties.</translation>
<translation id="8012647001091218357">Šiuo metu nepavyko susisiekti su jūsų tėvais. Bandykite dar kartą.</translation>
<translation id="8025119109950072390">Šios svetainės užpuolėjai gali bandyti apgaulingai priversti atlikti pavojingus veiksmus, pvz., įdiegti programinę įrangą ar atskleisti asmens informaciją (pvz., slaptažodžius, telefonų numerius ar kredito kortelių informaciją).</translation>
-<translation id="803030522067524905">„Google“ saugaus narÅ¡ymo funkcija neseniai aptiko, kad svetainÄ—je <ph name="SITE" /> sukÄiaujama. SukÄiavimo svetainÄ—s apsimeta kitomis svetainÄ—mis, kad jus apgautų. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Šis puslapis yra <ph name="SOURCE_LANGUAGE" /> k. Išversti į <ph name="TARGET_LANGUAGE" /> k.?</translation>
+<translation id="8037357227543935929">Klausti (numatytoji parinktis)</translation>
<translation id="8041089156583427627">Siųsti atsiliepimą</translation>
+<translation id="8041940743680923270">Naudoti visuotinį numatytąjį nustatymą (klausti)</translation>
<translation id="8088680233425245692">Nepavyko peržiūrėti straipsnio.</translation>
<translation id="8089520772729574115">mažiau nei 1 MB</translation>
<translation id="8091372947890762290">Laukiama aktyvinimo serveryje</translation>
@@ -769,13 +843,14 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="8134994873729925007">Nepavyko rasti <ph name="HOST_NAME" /> serverio <ph name="BEGIN_ABBR" />DNS adreso<ph name="END_ABBR" />.</translation>
<translation id="8149426793427495338">Įjungta kompiuterio miego būsena.</translation>
<translation id="8150722005171944719"><ph name="URL" /> nurodyto failo negalima skaityti. Gali būti, kad jis pašalintas, perkeltas arba neleidžiama prieiga prie jo dėl failo leidimų.</translation>
+<translation id="8184538546369750125">Naudoti visuotinį numatytąjį nustatymą (leisti)</translation>
+<translation id="8191494405820426728">VietinÄ—s strigties ID: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Anuliuoti perkÄ—limÄ…</translation>
<translation id="8201077131113104583">Netinkamas plėtinio, kurio ID „<ph name="EXTENSION_ID" />“, atnaujinimo URL.</translation>
<translation id="8202097416529803614">Užsakymo suvestinė</translation>
<translation id="8218327578424803826">Priskirta vieta:</translation>
<translation id="8225771182978767009">Šį kompiuterį nustatęs asmuo pasirinko blokuoti šią svetainę.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Šiuo metu svetainės <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> užpuolėjai gali jūsų kompiuteryje bandyti įdiegti pavojingas programas, kurios vagia arba ištrina informaciją (pvz., nuotraukas, slaptažodžius, pranešimus ir kredito kortelių numerius).</translation>
<translation id="8241707690549784388">Jūsų ieškomas puslapis ieškojo informacijos, kurią įvedėte. Grįžus į tą puslapį bet kokie jūsų atliekami veiksmai gali būti kartojami. Ar norite tęsti?</translation>
<translation id="8249320324621329438">Paskutinį kartą gauta:</translation>
<translation id="8253091569723639551">BÅ«tina pateikti atsiskaitymo adresÄ…</translation>
@@ -783,6 +858,7 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="8289355894181816810">Jei nesate tikri, ką tai reiškia, susisiekite su tinklo administratoriumi.</translation>
<translation id="8293206222192510085">Pridėti žymę</translation>
<translation id="8294431847097064396">Å altinis</translation>
+<translation id="8306404619377842860">Nepavyko užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes įrenginio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Vertimas nepavyko dėl tinklo ryšio problemos.</translation>
<translation id="8332188693563227489">Prieiga prie <ph name="HOST_NAME" /> atmesta</translation>
<translation id="834457929814110454">Jei suprantate, kokia rizika gali kilti jūsų saugai, galite <ph name="BEGIN_LINK" />apsilankyti šioje svetainėje<ph name="END_LINK" />, kol iš jos dar nepašalintos kenkėjiškos programos.</translation>
@@ -803,11 +879,9 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="8483780878231876732">Jei norite naudoti korteles iš „Google“ paskyros, prisijunkite prie „Chrome“</translation>
<translation id="8488350697529856933">Taikoma</translation>
<translation id="8498891568109133222">Per ilgai laukta <ph name="HOST_NAME" /> atsako.</translation>
-<translation id="852346902619691059">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; įrenginio operacinė sistema negali pasitikėti jo saugos sertifikatu. Taip galėjo būti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užpuoliko. <ph name="BEGIN_LEARN_MORE_LINK" />Sužinokite daugiau<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Gal. pab. metai</translation>
<translation id="8543181531796978784">Galite <ph name="BEGIN_ERROR_LINK" />pranešti apie aptikimo problemą<ph name="END_ERROR_LINK" /> arba, jei suprantate saugos riziką, galite <ph name="BEGIN_LINK" />apsilankyti šioje nesaugioje svetainėje<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">IÅ¡versti negalima, nes nepavyko nustatyti puslapio kalbos.</translation>
-<translation id="8559762987265718583">Nepavyksta užmegzti privataus ryšio su <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, nes įrenginio data ir laikas (<ph name="DATE_AND_TIME" />) yra netinkami.</translation>
<translation id="8571890674111243710">Puslapis verÄiamas į <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">PridÄ—ti tel. nr.
</translation>
@@ -822,6 +896,7 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="8738058698779197622">Jei norite užmegzti saugų ryšį, turėsite tinkamai nustatyti laikrodį. To reikalaujama todėl, kad svetainių tapatybei įrodyti naudojami sertifikatai galioja tik tam tikrą laikotarpį. Kadangi įrenginio laikrodis nustatytas netinkamai, „Chromium“ negali tinkamai patvirtinti sertifikatų.</translation>
<translation id="8740359287975076522">Nepavyko rasti <ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;DNS adreso&lt;/abbr&gt;. Nustatoma problema.</translation>
<translation id="8759274551635299824">Å i kortelÄ— nebegalioja</translation>
+<translation id="8761567432415473239">„Google“ saugaus naršymo funkcija neseniai <ph name="BEGIN_LINK" />rado kenkėjiškų programų<ph name="END_LINK" /> <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;IÅ¡trinti dar kartÄ…</translation>
<translation id="8800988563907321413">Netoliese esantys pasiÅ«lymai jums rodomi Äia</translation>
<translation id="8820817407110198400">Žymės</translation>
@@ -834,29 +909,30 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="8870413625673593573">Neseniai uždaryta</translation>
<translation id="8874824191258364635">Įveskite tinkamą kortelės numerį</translation>
<translation id="8876793034577346603">Analizuojant tinklo konfigūraciją įvyko klaida.</translation>
-<translation id="8877192140621905067">Kai patvirtinsite, išsami kortelės informacija bus bendrinama su šia svetaine</translation>
<translation id="8889402386540077796">Spalva</translation>
<translation id="8891727572606052622">Netinkamas įgaliotojo serverio režimas.</translation>
<translation id="889901481107108152">Deja, Å¡is eksperimentas negalimas platformoje.</translation>
<translation id="8903921497873541725">Artinti</translation>
<translation id="8931333241327730545">Ar norite išsaugoti šios kortelės informaciją „Google“ paskyroje?</translation>
<translation id="8932102934695377596">Jūsų laikrodis atsilieka</translation>
-<translation id="8954894007019320973">(Tęsinys)</translation>
<translation id="8971063699422889582">BaigÄ—si serverio sertifikato galiojimo laikas.</translation>
<translation id="8986494364107987395">AutomatiÅ¡kai siųsti naudojimo statistikÄ… ir strigÄių ataskaitas „Google“</translation>
-<translation id="8987927404178983737">MÄ—nuo</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Pateiktoje svetainėje yra kenkėjiškų programų</translation>
+<translation id="8997023839087525404">Serveris pateikė sertifikatą, kuris nebuvo viešai atskleistas naudojant sertifikato skaidrumo politiką. Tai yra tam tikriems sertifikatams taikomas reikalavimas, siekiant užtikrinti, jog jie patikimi ir apsaugo nuo įsilaužėlių.</translation>
<translation id="9001074447101275817">Tarpiniame serveryje <ph name="DOMAIN" /> būtina įvesti naudotojo vardą ir slaptažodį.</translation>
+<translation id="9005998258318286617">PDF dokumento įkelti nepavyko.</translation>
<translation id="901974403500617787">Visoje sistemoje taikomas žymas gali nustatyti tik savininkas: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">BÅ«tina pateikti kortelÄ—s atsiskaitymo adresÄ…</translation>
<translation id="9020542370529661692">Šis puslapis išverstas į <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Saugos klaida</translation>
<translation id="9038649477754266430">Naudokite numatymo paslaugÄ…, kad puslapiai bÅ«tų įkeliami greiÄiau</translation>
<translation id="9039213469156557790">Be to, šiame puslapyje yra kitų nesaugių išteklių. Perduodant duomenis šiuos išteklius gali peržiūrėti kiti asmenys ir keisti atakuojanti programa, siekianti pakeisti puslapio veikimą.</translation>
-<translation id="9040185888511745258">UžgrobÄ—jai <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> gali bandyti apgaule priversti jus įdiegti narÅ¡ymo funkcijas trikdanÄių programų (pvz., pakeitÄ™ pagrindinį puslapį ar rodydami papildomų skelbimų svetainÄ—se, kuriose lankotÄ—s).</translation>
+<translation id="9049981332609050619">BandÄ—te pasiekti <ph name="DOMAIN" />, bet serveris pateikÄ— neteisingÄ… sertifikatÄ….</translation>
<translation id="9050666287014529139">SlaptafrazÄ—</translation>
<translation id="9065203028668620118">Redaguoti</translation>
<translation id="9068849894565669697">Pasirinkite spalvÄ…</translation>
+<translation id="9069693763241529744">Užblokuota pagal plėtinį</translation>
<translation id="9076283476770535406">Joje gali būti suaugusiesiems skirto turinio</translation>
<translation id="9078964945751709336">BÅ«tina pateikti daugiau informacijos</translation>
<translation id="9103872766612412690">Svetainėje <ph name="SITE" /> įprastai naudojama šifruotė informacijai apsaugoti. Šį kartą „Chromium“ bandant prisijungti prie <ph name="SITE" />, ji pateikė neįprastus ir netinkamus prisijungimo duomenis. Gali būti, kad užpuolėjas bando apsimesti svetaine <ph name="SITE" /> arba „Wi-Fi“ prisijungimo ekrane nutrūko ryšys. Jūsų informacija vis tiek liko apsaugota, nes „Chromium“ sustabdė prisijungimą prieš apsikeitimą bet kokiais duomenimis.</translation>
@@ -865,16 +941,21 @@ Ei! Kitą kartą gali būti naudinga naudoti inkognito režimą (<ph name="SHORT
<translation id="9148507642005240123">&amp;Anuliuoti redagavimÄ…</translation>
<translation id="9154194610265714752">Atnaujinta</translation>
<translation id="9157595877708044936">Nustatoma...</translation>
+<translation id="9169664750068251925">Visada blokuoti Å¡ioje svetainÄ—je</translation>
<translation id="9170848237812810038">&amp;Atšaukti</translation>
<translation id="917450738466192189">Serverio sertifikatas negalioja.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}many{<ph name="SHIPPING_OPTION_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ir dar <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> naudojamas nepalaikomas protokolas.</translation>
<translation id="9205078245616868884">Duomenys užšifruoti naudojant sinchronizavimo slaptafrazę. Įveskite ją, kad pradėtumėte sinchronizuoti.</translation>
<translation id="9207861905230894330">Nepavyko pridÄ—ti straipsnio.</translation>
+<translation id="9219103736887031265">Vaizdai</translation>
<translation id="933612690413056017">Nėra interneto ryšio</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CLEAR FORM</translation>
<translation id="939736085109172342">Naujas aplankas</translation>
<translation id="941721044073577244">Panašu, kad neturite leidimo apsilankyti šioje svetainėje</translation>
<translation id="969892804517981540">Oficialiai pagaminta</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Nėra}=1{1 elementas}one{# elementas}few{# elementai}many{# elemento}other{# elementų}}</translation>
<translation id="988159990683914416">Vykdymo programa sukurta</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_lv.xtb b/chromium/components/strings/components_strings_lv.xtb
index a557ff22596..eeccee59448 100644
--- a/chromium/components/strings/components_strings_lv.xtb
+++ b/chromium/components/strings/components_strings_lv.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Pagriezt pulksteņrÄdÄ«tÄju kustÄ«bas virzienÄ</translation>
<translation id="1038842779957582377">nezinÄms nosaukums</translation>
<translation id="1050038467049342496">Aizveriet citas lietotnes</translation>
-<translation id="1053591932240354961">Å obrÄ«d nevarat apmeklÄ“t vietni <ph name="SITE" />, jo no tÄs tika nosÅ«tÄ«ti sajaukti akreditÄcijas dati, kurus nevar apstrÄdÄt pÄrlÅ«kÄ Google Chrome. TÄ«kla kļūdas un brÄ«dinÄjumi parasti ir Ä«slaicÄ«gi, tÄpÄ“c Å¡Ä« lapa vÄ“lÄk, visticamÄk, darbosies. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Pievienošanas atsaukšana</translation>
<translation id="10614374240317010">Netiek saglabÄtas</translation>
<translation id="106701514854093668">Datora grÄmatzÄ«mes</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Politikas keÅ¡atmiņa ir labÄ stÄvoklÄ«.</translation>
<translation id="113188000913989374">Vietnē <ph name="SITE" /> ir rakstīts:</translation>
<translation id="1132774398110320017">Chrome automÄtiskÄs aizpildes iestatÄ«jumi...</translation>
+<translation id="1150979032973867961">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄts netiek uzskatÄ«ts par uzticamu jÅ«su datora operÄ“tÄjsistÄ“mÄ. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
+<translation id="1151972924205500581">Nepieciešama parole</translation>
<translation id="1152921474424827756">Piekļūstiet vietnes <ph name="URL" /> <ph name="BEGIN_LINK" />keÅ¡atmiÅ†Ä saglabÄtajai kopijai<ph name="END_LINK" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> negaidÄ«ti pÄrtrauca savienojumu.</translation>
<translation id="1161325031994447685">AtkÄrtoti izveidojiet savienojumu ar Wi-Fi tÄ«klu.</translation>
+<translation id="1165039591588034296">Kļūda</translation>
<translation id="1175364870820465910">DrukÄt...</translation>
<translation id="1181037720776840403">Noņemt</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />AutomÄtiski nosÅ«tÄ«t<ph name="END_WHITEPAPER_LINK" /> Google serveriem informÄciju par iespÄ“jamÄm droÅ¡Ä«bas problÄ“mÄm. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">VairÄk no Å¡Ä«s vietnes</translation>
<translation id="1206967143813997005">SÄkotnÄ“jais paraksts nav derÄ«gs</translation>
<translation id="1209206284964581585">PagaidÄm slÄ“pt</translation>
+<translation id="121201262018556460">JÅ«s centÄties sasniegt <ph name="DOMAIN" />, bet servera uzrÄdÄ«tais sertifikÄts satur vÄju atslÄ“gu. IespÄ“jams, uzbrucÄ“js ir uzlauzis privÄto atslÄ“gu un serveris var nebÅ«t tas, ko centÄties sasniegt (iespÄ“jams, jÅ«s sazinÄties ar uzbrucÄ“ju).</translation>
<translation id="1219129156119358924">Sistēmas drošība</translation>
<translation id="1227224963052638717">NezinÄma politika.</translation>
<translation id="1227633850867390598">Slēpt vērtību</translation>
<translation id="1228893227497259893">Nepareizs vienības identifikators</translation>
<translation id="1232569758102978740">Bez nosaukuma</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (veikta sinhronizÄcija)</translation>
<translation id="1263231323834454256">Lasīšanas saraksts</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" /> notverts ziņojums par avÄriju (vÄ“l nav augÅ¡upielÄdÄ“ts vai ignorÄ“ts)</translation>
+<translation id="1281526147609854549">Izsniedza <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Bloķēts bīstams saturs</translation>
<translation id="1285320974508926690">Nekad netulkot Å¡o vietni</translation>
<translation id="129553762522093515">Nesen aizvērtas</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Dzēsiet sīkfailus<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">IespÄ“jams, jÅ«su darbÄ«bas <ph name="BEGIN_EMPHASIS" />joprojÄm bÅ«s redzamas<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />jÅ«su apmeklÄ“tajÄm vietnÄ“m;
+ <ph name="LIST_ITEM" />jÅ«su darba devÄ“jam vai mÄcÄ«bu iestÄdei;
+ <ph name="LIST_ITEM" />jūsu interneta pakalpojumu sniedzējam.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">ReÄ£istrÄcijas domÄ“ns:</translation>
<translation id="1340482604681802745">Saņemšanas adrese</translation>
<translation id="1344211575059133124">Šķiet, ka jums ir nepieciešama atļauja apmeklēt šo vietni</translation>
<translation id="1344588688991793829">Chromium automÄtiskÄs aizpildes iestatÄ«jumi...</translation>
+<translation id="1348198688976932919">Vietnē, kas tiks atvērta, ir bīstamas lietotnes</translation>
<translation id="1374468813861204354">ieteikumus</translation>
<translation id="1375198122581997741">Par versiju</translation>
<translation id="1377321085342047638">Kartes numurs</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> nenosÅ«tÄ«ja nekÄdus datus.</translation>
<translation id="1407135791313364759">Atvērt visas</translation>
<translation id="1413809658975081374">KonfidencialitÄtes kļūda</translation>
+<translation id="14171126816530869"><ph name="ORGANIZATION" />identitÄti<ph name="LOCALITY" />apstiprinÄja<ph name="ISSUER" /></translation>
<translation id="1426410128494586442">JÄ</translation>
<translation id="1430915738399379752">DrukÄt</translation>
-<translation id="1442912890475371290">Tika bloÄ·Ä“ts mÄ“Ä£inÄjums <ph name="BEGIN_LINK" />apmeklÄ“t lapu domÄ“nÄ <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Å obrÄ«d nevarat apmeklÄ“t vietni <ph name="SITE" />, jo tajÄ tiek izmantota sertifikÄtu piesprauÅ¡ana. TÄ«kla kļūdas un brÄ«dinÄjumi parasti ir Ä«slaicÄ«gi, tÄpÄ“c Å¡Ä« lapa vÄ“lÄk, visticamÄk, darbosies. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}zero{<ph name="PAYMENT_METHOD_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">RÄdÄ«t saglabÄtu (t.i., novecojuÅ¡u) Å¡Ä«s lapas versiju.</translation>
<translation id="1517433312004943670">JÄnorÄda tÄlruņa numurs</translation>
<translation id="1519264250979466059">Būvējuma datums</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Lai izmantotu Å¡o funkciju, ir jÄbÅ«t iespÄ“jotai valodai JavaScript.</translation>
<translation id="1555130319947370107">Zila</translation>
<translation id="1559528461873125649">Nav tÄda faila vai direktorija</translation>
-<translation id="1559572115229829303">&lt;p&gt;Nevar izveidot privÄtu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jÅ«su ierÄ«ces datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizi.&lt;/p&gt;
-
- &lt;p&gt;LÅ«dzu, koriģējiet datumu un laiku lietotnes &lt;strong&gt;IestatÄ«jumi&lt;/strong&gt; sadaÄ¼Ä &lt;strong&gt;VispÄrÄ«gi&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Å Ä«s tÄ«mekļa lapas rÄdÄ«Å¡anas laikÄ radÄs kļūda.</translation>
<translation id="1592005682883173041">Piekļuve lokÄlajiem datiem</translation>
+<translation id="1594030484168838125">Izvēlēties</translation>
<translation id="161042844686301425">CiÄnzila</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Vai vÄ“laties, lai Chrome saglabÄtu Å¡o karti?</translation>
<translation id="1639239467298939599">Notiek ielÄde</translation>
<translation id="1640180200866533862">LietotÄja politikas</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">TÄ«kla konfigurÄcija nav derÄ«ga, un to nevarÄ“ja importÄ“t.</translation>
<translation id="1644574205037202324">VÄ“sture</translation>
<translation id="1645368109819982629">Neatbalstīts protokols</translation>
+<translation id="1655462015569774233">{1,plural, =1{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs vakar. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu.}zero{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs pirms # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu.}one{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs pirms # dienas. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu.}other{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs pirms # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu.}}</translation>
<translation id="1656489000284462475">InformÄcija par saņemÅ¡anu</translation>
<translation id="1663943134801823270">Kartes un adreses tiek iegÅ«tas no Chrome. Varat pÄrvaldÄ«t tÄs <ph name="BEGIN_LINK" />iestatÄ«jumos<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">VietnÄ“ <ph name="SITE" /> informÄcijas aizsargÄÅ¡anai parasti tiek izmantota Å¡ifrÄ“Å¡ana. Kad pÄrlÅ«kÄ Google Chrome tika mÄ“Ä£inÄts izveidot savienojumu ar vietni <ph name="SITE" />, Å¡oreiz tÄ nosÅ«tÄ«ja neparastus un nepareizus akreditÄcijas datus. IespÄ“jams, tas notika, jo uzbrucÄ“js mÄ“Ä£inÄja uzdoties par vietni <ph name="SITE" />, vai arÄ« Wi-Fi pierakstÄ«Å¡anÄs ekrÄns pÄrtrauc savienojumu. JÅ«su informÄcija joprojÄm ir droÅ¡Ä«bÄ, jo pÄrlÅ«ks Google Chrome pÄrtrauca savienojumu, pirms tika veikta jebkÄdu datu apmaiņa.</translation>
-<translation id="168328519870909584">UzbrucÄ“ji, kuri paÅ¡laik atrodas vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, iespÄ“jams, mÄ“Ä£inÄs jÅ«su ierÄ«cÄ“ instalÄ“t bÄ«stamas lietotnes, kuras zog vai dzÄ“Å¡ jÅ«su informÄciju (piemÄ“ram, fotoattÄ“lus, paroles, ziņojumus un kredÄ«tkarÅ¡u informÄciju).</translation>
<translation id="168841957122794586">Servera sertifikÄts ietver vÄju kriptogrÄfisko atslÄ“gu.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties rÄ«t. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu.}zero{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties pÄ“c # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu.}one{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties pÄ“c # dienas. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu.}other{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties pÄ“c # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu.}}</translation>
<translation id="1710259589646384581">OperÄ“tÄjsistÄ“ma</translation>
<translation id="1721312023322545264">Jums ir nepieciešama atļauja no <ph name="NAME" />, lai apmeklētu šo vietni</translation>
<translation id="1721424275792716183">* ObligÄts lauks</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">LejupielÄdÄ“t lapu vÄ“lÄk</translation>
<translation id="17513872634828108">Atvērt cilnes</translation>
<translation id="1753706481035618306">Lapas numurs</translation>
+<translation id="1763864636252898013">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄts netiek uzskatÄ«ts par uzticamu jÅ«su ierÄ«ces operÄ“tÄjsistÄ“mÄ. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Mēģiniet palaist Windows tīkla diagnostiku<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Atjauniniet savu sinhronizÄcijas ieejas frÄzi.</translation>
<translation id="1787142507584202372">Å eit tiks parÄdÄ«tas jÅ«su atvÄ“rtÄs cilnes</translation>
+<translation id="1789575671122666129">Uznirstošie logi</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Kartes Ä«paÅ¡nieka vÄrds, uzvÄrds</translation>
-<translation id="1803678881841855883">Nesen Google droÅ¡ajÄ pÄrlÅ«koÅ¡anÄ <ph name="BEGIN_LINK" />tika konstatÄ“ta ļaunprÄtÄ«ga programmatÅ«ra<ph name="END_LINK" /> vietnÄ“ <ph name="SITE" />. Vietnes, kas parasti ir droÅ¡as, dažkÄrt var tikt inficÄ“tas ar ļaunprÄtÄ«gu programmatÅ«ru. Ä»aunprÄtÄ«gÄ programmatÅ«ra nÄk no <ph name="SUBRESOURCE_HOST" />, kas ir zinÄms ļaunprÄtÄ«gas programmatÅ«ras izplatÄ«tÄjs. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Pievienota: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">PieprasÄ«jums vai tÄ parametri nebija derÄ«gi.</translation>
<translation id="1826516787628120939">PÄrbaude</translation>
<translation id="1834321415901700177">Å Ä« vietne satur kaitnieciskas programmas</translation>
+<translation id="1840414022444569775">Å is kartes numurs jau tiek izmantots.</translation>
<translation id="1842969606798536927">MaksÄt</translation>
<translation id="1871208020102129563">Starpniekserveris ir iestatīts, lai tas lietotu fiksētus starpniekserverus, nevis .pac skripta URL.</translation>
<translation id="1871284979644508959">ObligÄtais lauks</translation>
<translation id="187918866476621466">AtvÄ“rt sÄkumlapas</translation>
<translation id="1883255238294161206">Sakļaut sarakstu</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}zero{<ph name="SHIPPING_ADDRESS_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtrēšana</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Nav}=1{1 vietne}zero{# vietnes}one{# vietne}other{# vietnes}}</translation>
<translation id="194030505837763158">Apmeklējiet vietni <ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> grÄmatzÄ«mes</translation>
<translation id="1973335181906896915">RadÄs serializÄ“Å¡anas kļūda.</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorēta, jo to atcēla politika <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Notiek tuvumÄ esoÅ¡u fiziskÄ tÄ«mekļa lapu meklÄ“Å¡ana</translation>
<translation id="213826338245044447">MobilÄs grÄmatzÄ«mes</translation>
-<translation id="2148716181193084225">Å odien</translation>
+<translation id="2147827593068025794">SinhronizÄcija fonÄ</translation>
<translation id="2154054054215849342">SinhronizÄcija jÅ«su domÄ“nam nav pieejama.</translation>
<translation id="2154484045852737596">Kartes informÄcijas rediģēšana</translation>
<translation id="2166049586286450108">Pilna administratora piekļuve</translation>
<translation id="2166378884831602661">Šī vietne nevar garantēt drošu savienojumu</translation>
<translation id="2181821976797666341">Politikas</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adrese}zero{# adreses}one{# adrese}other{# adreses}}</translation>
+<translation id="2187317261103489799">Noteikt (pēc noklusējuma)</translation>
<translation id="2202020181578195191">Ievadiet derīgu gadu</translation>
<translation id="2212735316055980242">Politika netika atrasta.</translation>
<translation id="2213606439339815911">Notiek ierakstu ienešana...</translation>
+<translation id="2218879909401188352">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> varÄ“tu instalÄ“t bÄ«stamas lietotnes, kas bojÄ jÅ«su ierÄ«ci, rada slÄ“ptas izmaksas mobilÄ tÄlruņa rÄ“Ä·inÄ vai zog jÅ«su personas informÄciju. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2230458221926704099">Labojiet savienojumu, izmantojot <ph name="BEGIN_LINK" />diagnostikas lietotni<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Sūtīt tūlīt</translation>
<translation id="225207911366869382">Šī vērtība vairs netiek atbalstīta šai politikai.</translation>
<translation id="2262243747453050782">HTTP kļūda</translation>
+<translation id="2270484714375784793">TÄlruņa numurs</translation>
<translation id="2282872951544483773">Nepieejamie eksperimenti</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> vienums}zero{<ph name="ITEM_COUNT" /> vienumi}one{<ph name="ITEM_COUNT" /> vienums}other{<ph name="ITEM_COUNT" /> vienumi}}</translation>
<translation id="2292556288342944218">Piekļuve internetam ir bloķēta</translation>
<translation id="230155334948463882">Vai jums ir jauna karte?</translation>
-<translation id="2305919008529760154">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts, iespÄ“jams, ir izveidots krÄpnieciski. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">VietnÄ“ <ph name="DOMAIN" /> ir jÄievada lietotÄjvÄrds un parole.</translation>
-<translation id="2318774815570432836">Å obrÄ«d nevarat apmeklÄ“t vietni <ph name="SITE" />, jo tajÄ tiek izmantota politika HSTS. TÄ«kla kļūdas un uzbrukumi parasti ir Ä«slaicÄ«gi, tÄpÄ“c Å¡Ä« lapa vÄ“lÄk, visticamÄk, darbosies. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Iestatījumu kontrolē jūsu administrators</translation>
<translation id="2354001756790975382">Citas grÄmatzÄ«mes</translation>
+<translation id="2354430244986887761">Izmantojot Google droÅ¡o pÄrlÅ«koÅ¡anu, nesen <ph name="BEGIN_LINK" />tika atrastas kaitÄ«gas lietotnes<ph name="END_LINK" /> vietnÄ“ <ph name="SITE" />.</translation>
<translation id="2355395290879513365">UzbrucÄ“ji var skatÄ«t attÄ“lus, kurus skatÄt Å¡ajÄ vietnÄ“, un apmÄnÄ«t jÅ«s, pÄrveidojot Å¡os attÄ“lus.</translation>
+<translation id="2356070529366658676">VaicÄt</translation>
+<translation id="2359629602545592467">VairÄkas</translation>
<translation id="2359808026110333948">TurpinÄt</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> notverts ziņojums par avÄriju; netika lejupielÄdÄ“ts</translation>
<translation id="2367567093518048410">LÄ«menis</translation>
-<translation id="2371153335857947666">{1,plural, =1{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs vakar. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}zero{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs pirms # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}one{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs pirms # dienas. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}other{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄta derÄ«guma termiņš beidzÄs pirms # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. JÅ«su datora pulkstenÄ« paÅ¡laik ir iestatÄ«ts Å¡Äds datums: <ph name="CURRENT_DATE" />. Vai tas ir pareizs? Ja datums nav pareizs, mainiet sistÄ“mas pulksteni un pÄ“c tam atsvaidziniet Å¡o lapu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nav pieejamas alternatÄ«vas lietotÄja saskarnes</translation>
<translation id="2384307209577226199">Uzņēmuma noklusējuma politika</translation>
<translation id="2386255080630008482">Servera sertifikÄts ir atsaukts.</translation>
<translation id="2392959068659972793">RÄdÄ«t politikas, kuru vÄ“rtÄ«ba nav iestatÄ«ta</translation>
<translation id="239429038616798445">Šis nosūtīšanas veids nav pieejams. Izmēģiniet citu veidu.</translation>
<translation id="2396249848217231973">&amp;Atsaukt dzēšanu</translation>
-<translation id="2460160116472764928">Nesen Google droÅ¡ajÄ pÄrlÅ«koÅ¡anÄ <ph name="BEGIN_LINK" />tika konstatÄ“ta ļaunprÄtÄ«ga programmatÅ«ra<ph name="END_LINK" /> vietnÄ“ <ph name="SITE" />. Vietnes, kuras parasti ir droÅ¡as, var tikt inficÄ“tas ar ļaunprÄtÄ«gu programmatÅ«ru. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄts, iespÄ“jams, ir atsaukts. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
<translation id="2463739503403862330">Aizpildīt</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Palaist tīkla diagnostiku<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Nederīgs meklēšanas URL.</translation>
+<translation id="2482878487686419369">Paziņojumi</translation>
<translation id="2491120439723279231">Servera sertifikÄtÄ ir kļūdas.</translation>
<translation id="2495083838625180221">JSON parsÄ“tÄjs</translation>
<translation id="2495093607237746763">Ja Å¡Ä« izvÄ“les rÅ«tiņa ir atzÄ«mÄ“ta, pÄrlÅ«ks Chromium saglabÄs jÅ«su kartes informÄciju Å¡ajÄ ierÄ«cÄ“, lai nodroÅ¡inÄtu ÄtrÄku veidlapu aizpildi.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Doties atpakaļ</translation>
<translation id="2515629240566999685">PÄrbaudiet signÄlu savÄ apkaimÄ“.</translation>
<translation id="2516305470678292029">AlternatÄ«vas lietotÄja saskarnes</translation>
+<translation id="2539524384386349900">Noteikt</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> nosūtīja nederīgu atbildi.</translation>
-<translation id="2552545117464357659">JaunÄka</translation>
<translation id="2556876185419854533">&amp;Labojuma atsaukšana</translation>
<translation id="2587730715158995865">No: <ph name="ARTICLE_PUBLISHER" />. Lasiet šo un vēl <ph name="OTHER_ARTICLE_COUNT" /> rakstus.</translation>
<translation id="2587841377698384444">Direktorija API ID:</translation>
<translation id="2597378329261239068">Å is dokuments ir aizsargÄts ar paroli. LÅ«dzu, ievadiet paroli.</translation>
<translation id="2609632851001447353">Varianti</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Nav}=1{1 lietotne ($1)}=2{2 lietotnes ($1, $2)}zero{# lietotnes ($1, $2, $3)}one{# lietotne ($1, $2, $3)}other{# lietotnes ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">NorÄdÄ«tais laiks ir pÄrÄk tÄlu nÄkotnÄ“</translation>
<translation id="2639739919103226564">Statuss:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Piekļuve failam tika noraidīta.</translation>
<translation id="2653659639078652383">Iesniegt</translation>
<translation id="2666117266261740852">Aizveriet citas cilnes vai lietotnes</translation>
+<translation id="2670429602441959756">Å ajÄ lapÄ ir funkcijas, kas vÄ“l netiek atbalstÄ«tas virtuÄlajÄ realitÄtÄ“. Notiek aizvÄ“rÅ¡ana...</translation>
<translation id="2674170444375937751">Vai tieÅ¡Äm vÄ“laties dzÄ“st Å¡Ä«s lapas no savas vÄ“stures?</translation>
<translation id="2677748264148917807">Iziet</translation>
-<translation id="269990154133806163">Serveris uzrÄdÄ«ja sertifikÄtu, kas netika publiski atklÄts, izmantojot Certificate Transparency politiku. Å Ä« ir prasÄ«ba noteiktiem sertifikÄtiem, lai nodroÅ¡inÄtu to uzticamÄ«bu un aizsardzÄ«bu pret uzbrucÄ“jiem. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Atvērt sarakstu</translation>
<translation id="2704283930420550640">VÄ“rtÄ«ba neatbilst formÄtam.</translation>
<translation id="2704951214193499422">PÄrlÅ«kÄ Chromium paÅ¡laik nevar apstiprinÄt jÅ«su karti. LÅ«dzu, vÄ“lÄk mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="2705137772291741111">Nevar nolasÄ«t Å¡Ä«s vietnes saglabÄto (keÅ¡atmiÅ†Ä ievietoto) kopiju.</translation>
<translation id="2709516037105925701">AutomÄtiskÄ aizpilde</translation>
-<translation id="2712118517637785082">JÅ«s mÄ“Ä£inÄjÄt sasniegt domÄ“nu <ph name="DOMAIN" />, bet izdevÄ“js atsauca servera uzrÄdÄ«to sertifikÄtu. Tas nozÄ«mÄ“, ka servera uzrÄdÄ«tie droÅ¡Ä«bas akreditÄcijas dati nemaz nav uzticami. IespÄ“jams, jÅ«s sazinÄties ar uzbrucÄ“ju. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Lūgt atļauju</translation>
<translation id="2713444072780614174">Balta</translation>
<translation id="2720342946869265578">TuvumÄ</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Trūkst ierīces ieraksta.</translation>
<translation id="2784949926578158345">Savienojums tika atiestatīts.</translation>
<translation id="2794233252405721443">Vietne bloÄ·Ä“ta</translation>
+<translation id="2799020568854403057">Å ajÄ vietnÄ“, kas tiks atvÄ“rta, ir kaitÄ«gas lietotnes</translation>
+<translation id="2803306138276472711">Google droÅ¡Äs pÄrlÅ«koÅ¡anas tehnoloÄ£ija vietnÄ“ <ph name="SITE" /> nesen <ph name="BEGIN_LINK" />konstatÄ“ja ļaunprÄtÄ«gu programmatÅ«ru<ph name="END_LINK" />. Vietnes, kuras parasti ir droÅ¡as, dažkÄrt tiek inficÄ“tas ar ļaunprÄtÄ«gu programmatÅ«ru.</translation>
<translation id="2824775600643448204">Adreses un meklēšanas josla</translation>
<translation id="2826760142808435982">Savienojums ir Å¡ifrÄ“ts un autentificÄ“ts, izmantojot <ph name="CIPHER" />, un tajÄ tiek izmantots <ph name="KX" /> kÄ atslÄ“gu apmaiņas mehÄnisms.</translation>
<translation id="2835170189407361413">Notīrīt veidlapu</translation>
+<translation id="2856444702002559011">IespÄ“jams, uzbrucÄ“ji mÄ“Ä£ina nozagt jÅ«su informÄciju no vietnes <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (piemÄ“ram, paroles, ziņojumus vai kredÄ«tkarÅ¡u datus). <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2889159643044928134">NeielÄdÄ“t atkÄrtoti</translation>
<translation id="2900469785430194048">MÄ“Ä£inot parÄdÄ«t Å¡o tÄ«mekļa lapu, pÄrlÅ«ka Google Chrome atmiÅ†Ä nepietika vietas.</translation>
<translation id="2909946352844186028">Konstatētas tīkla izmaiņas.</translation>
<translation id="2916038427272391327">Aizveriet citas programmas</translation>
<translation id="2922350208395188000">Servera sertifikÄtu nevar pÄrbaudÄ«t.</translation>
<translation id="2928905813689894207">Norēķinu adrese</translation>
+<translation id="2941952326391522266">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄts ir saistÄ«ts ar domÄ“nu <ph name="DOMAIN2" />. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
<translation id="2948083400971632585">IestatÄ«jumu lapÄ varat atspÄ“jot jebkurus starpniekserverus, kas konfigurÄ“ti savienojuma izveidei.</translation>
<translation id="2955913368246107853">Aizvērt atrašanas joslu</translation>
<translation id="2958431318199492670">TÄ«kla konfigurÄcija neatbilst standartam ONC. IespÄ“jams, konfigurÄcijas daļas netiks importÄ“tas.</translation>
-<translation id="29611076221683977">PaÅ¡laik vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> esoÅ¡ie uzbrucÄ“ji jÅ«su Mac datorÄ var mÄ“Ä£inÄt instalÄ“t bÄ«stamas programmas, kuras var nozagt vai dzÄ“st jÅ«su informÄciju (piemÄ“ram, fotoattÄ“lus, paroles, ziņojumus un informÄciju par kredÄ«tkartÄ“m).</translation>
<translation id="2966678944701946121">Derīguma termiņš: <ph name="EXPIRATION_DATE_ABBR" />; pievienota: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Lai izveidotu droÅ¡u savienojumu, ir jÄiestata pareizs pulksteņa laiks. Tas ir nepiecieÅ¡ams, jo sertifikÄti, kurus vietnes izmanto, lai tiktu identificÄ“tas, ir derÄ«gi tikai noteiktos laika periodos. TÄ kÄ jÅ«su ierÄ«ces pulkstenis nav pareizs, Google Chrome nevar verificÄ“t Å¡os sertifikÄtus.</translation>
<translation id="2972581237482394796">&amp;PÄratsaukt</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Ievadiet derīgu adresi</translation>
<translation id="2986368408720340940">Šis saņemšanas veids nav pieejams. Izmēģiniet citu veidu.</translation>
<translation id="2991174974383378012">Kopīgošana ar vietnēm</translation>
+<translation id="2991571918955627853">PaÅ¡laik nevarat apmeklÄ“t vietni <ph name="SITE" />, jo tÄ izmanto HSTS. TÄ kÄ tÄ«kla kļūdas un uzbrukumi parasti ir Ä«slaicÄ«gi, visticamÄk, Å¡Ä« lapa vÄ“lÄk darbosies.</translation>
<translation id="3005723025932146533">RÄdÄ«t saglabÄto versiju</translation>
<translation id="3008447029300691911">Ievadiet kredÄ«tkartes <ph name="CREDIT_CARD" /> CVC. PÄ“c apstiprinÄÅ¡anas kartes informÄcija tiks kopÄ«gota ar Å¡o vietni.</translation>
<translation id="3010559122411665027">Saraksta ieraksts “<ph name="ENTRY_INDEX" />â€: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">AutomÄtiski bloÄ·Ä“ta</translation>
<translation id="3024663005179499861">Politikas tips nav pareizs.</translation>
<translation id="3032412215588512954">Vai vÄ“laties atkÄrtoti ielÄdÄ“t Å¡o vietni?</translation>
<translation id="3037605927509011580">Cilnes avÄrija.</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{vismaz 1 vienums sinhronizÄ“tÄs ierÄ«cÄ“s}=1{1 vienums (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}zero{# vienumi (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}one{# vienums (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}other{# vienumi (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}}</translation>
<translation id="3041612393474885105">SertifikÄta informÄcija</translation>
<translation id="3063697135517575841">PÄrlÅ«kÄ Chrome paÅ¡laik nevar apstiprinÄt jÅ«su karti. LÅ«dzu, vÄ“lÄk mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="3064966200440839136">Ja maksÄÅ¡anai tiks izmantota ÄrÄ“ja lietojumprogramma, tiks aizvÄ“rts inkognito režīms. Vai turpinÄt?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Nav}=1{1 parole}zero{# paroles}one{# parole}other{# paroles}}</translation>
<translation id="3093245981617870298">Esat bezsaistē</translation>
<translation id="3105172416063519923">Līdzekļa ID:</translation>
<translation id="3109728660330352905">Jums nav pilnvaru, lai skatītu šo lapu.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Mēģiniet palaist savienojamības diagnostiku<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">NeizdevÄs atÅ¡ifrÄ“t atbildi.</translation>
<translation id="3150653042067488994">Īslaicīga servera kļūda</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Lapas, ko skatÄt inkognito režīma cilnÄ“s, nebÅ«s redzamas pÄrlÅ«ka vÄ“sturÄ“, sÄ«kfailu krÄtuvÄ“ vai meklÄ“Å¡anas vÄ“sturÄ“, kad aizvÄ“rsiet visas inkognito režīma cilnes. TomÄ“r tiks saglabÄti visi lejupielÄdÄ“tie faili un izveidotÄs grÄmatzÄ«mes.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Sala</translation>
+<translation id="317583078218509884">Jaunie vietnes atļauju iestatÄ«jumi stÄsies spÄ“kÄ, atkÄrtoti ielÄdÄ“jot Å¡o lapu.</translation>
<translation id="3176929007561373547">PÄrbaudiet starpniekservera iestatÄ«jumus vai sazinieties ar tÄ«kla administratoru, lai
pÄrliecinÄtos, vai starpniekserveris darbojas. Ja uzskatÄt, ka jums nav jÄizmanto
starpniekserveris,
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Atveriet lapu inkognito režīmÄ</translation>
-<translation id="3202578601642193415">JaunÄkÄ</translation>
+<translation id="320323717674993345">Atcelt maksÄjumu</translation>
<translation id="3207960819495026254">AtzÄ«mÄ“ts kÄ grÄmatzÄ«me</translation>
+<translation id="3225919329040284222">Serveris uzrÄdÄ«ja sertifikÄtu, kas neatbilst iebÅ«vÄ“tajÄm cerÄ«bÄm. Å Ä«s cerÄ«bas ir ietvertas konkrÄ“tÄm, augstas droÅ¡Ä«bas vietnÄ“m, lai aizsargÄtu jÅ«s.</translation>
<translation id="3226128629678568754">Nospiediet atkÄrtotas ielÄdes pogu, lai atkÄrtoti iesniegtu datus, kas nepiecieÅ¡ami lapas ielÄdei.</translation>
+<translation id="3227137524299004712">Mikrofons</translation>
<translation id="3228969707346345236">TulkoÅ¡ana neizdevÄs, jo lapa jau ir <ph name="LANGUAGE" /> valodÄ.</translation>
<translation id="323107829343500871">Ievadiet kredītkartes <ph name="CREDIT_CARD" /> CVC</translation>
+<translation id="3234666976984236645">VienmÄ“r noteikt nozÄ«mÄ«gu saturu Å¡ajÄ vietnÄ“</translation>
<translation id="3254409185687681395">GrÄmatot Å¡o lapu</translation>
<translation id="3270847123878663523">&amp;PÄrkÄrtoÅ¡anas atsaukÅ¡ana</translation>
<translation id="3282497668470633863">Pievienot vÄrdu un uzvÄrdu uz kartes</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">Iestatījumi</translation>
<translation id="3345135638360864351">LietotÄjam <ph name="NAME" /> nevarÄ“ja nosÅ«tÄ«t jÅ«su pieprasÄ«jumu piekļūt Å¡ai vietnei. LÅ«dzu, mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="3355823806454867987">Mainīt starpniekservera iestatījumus...</translation>
+<translation id="3361596688432910856">PÄrlÅ«kÄ Chrome <ph name="BEGIN_EMPHASIS" />netiks saglabÄta<ph name="END_EMPHASIS" /> Å¡Äda informÄcija:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />jÅ«su pÄrlÅ«koÅ¡anas vÄ“sture;
+ <ph name="LIST_ITEM" />sīkfaili un vietņu dati;
+ <ph name="LIST_ITEM" />veidlapÄs ievadÄ«tÄ informÄcija.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Pulksteņa kļūda</translation>
-<translation id="337311366426640088">Vēl <ph name="ITEM_COUNT" /> vienumi...</translation>
<translation id="337363190475750230">Tika noņemta piekļuve</translation>
<translation id="3377188786107721145">RadÄs politikas parsÄ“Å¡anas kļūda.</translation>
<translation id="3380365263193509176">NezinÄma kļūda</translation>
<translation id="3380864720620200369">Klienta ID:</translation>
<translation id="3391030046425686457">PiegÄdes adrese</translation>
<translation id="3395827396354264108">Saņemšanas veids</translation>
-<translation id="340013220407300675">UzbrucÄ“ji var mÄ“Ä£inÄt nozagt jÅ«su informÄciju no vietnes <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (piemÄ“ram, paroles, ziņojumus vai kredÄ«tkarÅ¡u datus).</translation>
<translation id="3422248202833853650">Aizveriet citas programmas, lai atbrÄ«votu vietu atmiņÄ.</translation>
<translation id="3422472998109090673">Vietne <ph name="HOST_NAME" /> pašlaik nav sasniedzama.</translation>
+<translation id="3427092606871434483">Atļaut (pēc noklusējuma)</translation>
<translation id="3427342743765426898">&amp;Labojuma atsaukuma atcelšana</translation>
<translation id="3431636764301398940">SaglabÄt Å¡o karti Å¡ajÄ ierÄ«cÄ“</translation>
<translation id="3435896845095436175">Iespējot</translation>
<translation id="3447661539832366887">Šīs ierīces īpašnieks ir izslēdzis dinozauru spēli.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">PirmsielÄdes intervÄls:</translation>
<translation id="3462200631372590220">SlÄ“pt papildu informÄciju</translation>
<translation id="3467763166455606212">JÄnorÄda kartes Ä«paÅ¡nieka vÄrds un uzvÄrds</translation>
<translation id="3478058380795961209">Der. term. mēn.</translation>
<translation id="3479539252931486093">Vai tas bija negaidīti? <ph name="BEGIN_LINK" />Informējiet mūs<ph name="END_LINK" />!</translation>
<translation id="3479552764303398839">VÄ“lÄk</translation>
-<translation id="348000606199325318">AvÄrijas ID <ph name="CRASH_LOCAL_ID" /> (servera ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">MÄ“s nevarÄ“jÄm sasniegt jÅ«su mÄti/tÄ“vu. LÅ«dzu, mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="3528171143076753409">Servera sertifikÄts nav uzticams.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Vismaz 1 vienums sinhronizÄ“tÄs ierÄ«cÄ“s}=1{1 vienums (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}zero{# vienumi (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}one{# vienums (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}other{# vienumi (un vÄ“l citi sinhronizÄ“tÄs ierÄ«cÄ“s)}}</translation>
<translation id="3539171420378717834">SaglabÄt Å¡Ä«s kartes kopiju Å¡ajÄ ierÄ«cÄ“</translation>
<translation id="3542684924769048008">Izmantot paroli:</translation>
+<translation id="3545341443414427877">Nevar izveidot privÄtu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jÅ«su datorÄ iestatÄ«tais datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizs. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3549644494707163724">Å ifrÄ“t visus sinhronizÄ“tos datus, izmantojot sinhronizÄcijas ieejas frÄzi</translation>
-<translation id="3549761410225185768">Vēl <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts ir no domÄ“na <ph name="DOMAIN2" />. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Lai atbloÄ·Ä“tu, vÄ“rsieties pie pÄrvaldnieka</translation>
<translation id="3566021033012934673">JÅ«su savienojums nav privÄts</translation>
+<translation id="3569145463236695319">&lt;p&gt;Nevar izveidot privÄtu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jÅ«su ierÄ«cÄ“ iestatÄ«tais datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizs.&lt;/p&gt;
+
+ &lt;p&gt;LÅ«dzu, mainiet datumu un laiku lietotnes &lt;strong&gt;IestatÄ«jumi&lt;/strong&gt; sadaÄ¼Ä &lt;strong&gt;VispÄrÄ«gi&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Pievienojiet vÄrdu.</translation>
<translation id="3583757800736429874">&amp;PÄrvietoÅ¡anas atsaukuma atcelÅ¡ana</translation>
<translation id="3586931643579894722">Slēpt detaļas</translation>
-<translation id="3587482841069643663">Visi</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Ievadiet derīgu datumu</translation>
<translation id="36224234498066874">DzÄ“st pÄrlÅ«koÅ¡anas datus...</translation>
@@ -321,7 +361,6 @@
<translation id="3681007416295224113">SertifikÄta informÄcija</translation>
<translation id="3690164694835360974">PieteikÅ¡anÄs nav droÅ¡a</translation>
<translation id="3693415264595406141">Parole:</translation>
-<translation id="3696411085566228381">nav</translation>
<translation id="3704609568417268905"><ph name="TIME" />, <ph name="BOOKMARKED" />, <ph name="TITLE" />, <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Notiek ielÄde...</translation>
<translation id="3712624925041724820">Nav pietiekami daudz licenÄu.</translation>
@@ -329,12 +368,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />PÄrbaudiet starpniekserveri, ugunsmÅ«ri un DNS konfigurÄciju<ph name="END_LINK" />.</translation>
<translation id="3736520371357197498">Ja apzinÄties droÅ¡Ä«bas risku, varat <ph name="BEGIN_LINK" />apmeklÄ“t Å¡o nedroÅ¡o vietni<ph name="END_LINK" />, pirms ir noņemtas bÄ«stamÄs programmas.</translation>
<translation id="3739623965217189342">JÅ«su kopÄ“tÄ saite</translation>
+<translation id="3744899669254331632">PaÅ¡laik jÅ«s nevarat apmeklÄ“t vietni <ph name="SITE" />, jo Å¡Ä« vietne nosÅ«tÄ«ja kodÄ“tus akreditÄcijas datus, kurus Chromium nevar apstrÄdÄt. TÄ kÄ tÄ«kla kļūdas un uzbrukumi parasti ir Ä«slaicÄ«ga problÄ“ma, iespÄ“jams, vÄ“lÄk Å¡Ä« lapa atkal darbosies.</translation>
+<translation id="3748148204939282805">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> var mudinÄt jÅ«s veikt bÄ«stamas darbÄ«bas, piemÄ“ram, instalÄ“t programmatÅ«ru vai atklÄt personas informÄciju (piemÄ“ram, paroles, tÄlruņa numurus vai kredÄ«tkarÅ¡u datus). <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="375403751935624634">Tulkojums neizdevÄs servera kļūdas dēļ.</translation>
<translation id="3759461132968374835">PÄ“dÄ“jÄ laikÄ neesat ziņojis par avÄrijÄm. Å eit nebÅ«s redzamas avÄrijas, kas radÄs laikÄ, kad avÄriju pÄrskatu izveide bija atspÄ“jota.</translation>
+<translation id="3778403066972421603">Vai vÄ“laties saglabÄt Å¡o karti savÄ Google kontÄ un Å¡ajÄ ierÄ«cÄ“?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Derīguma termiņš: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Ja izmantojat starpniekserveri...</translation>
<translation id="3828924085048779000">TukÅ¡a ieejas frÄze nav atļauta.</translation>
-<translation id="3845539888601087042">Tiek rÄdÄ«ta vÄ“sture no ierÄ«cÄ“m, kurÄs esat pierakstÄ«jies. <ph name="BEGIN_LINK" />Uzziniet vairÄk<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Atpakaļ</translation>
<translation id="3858027520442213535">AtjauninÄt datumu un laiku</translation>
<translation id="3884278016824448484">Ierīces identifikators rada konfliktu.</translation>
@@ -342,11 +384,13 @@
<translation id="3886446263141354045">PieprasÄ«jums piekļūt Å¡ai vietnei ir nosÅ«tÄ«ts lietotÄjam <ph name="NAME" /></translation>
<translation id="3890664840433101773">E-pasta adreses pievienošana</translation>
<translation id="3901925938762663762">Kartes derīguma termiņš ir beidzies.</translation>
-<translation id="3933571093587347751">{1,plural, =1{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties rÄ«t. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}zero{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties pÄ“c # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}one{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties pÄ“c # dienas. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}other{Å is serveris nevarÄ“ja pierÄdÄ«t, ka ir <ph name="DOMAIN" />; Å¡Ä·iet, ka tÄ droÅ¡Ä«bas sertifikÄts sÄks darboties pÄ“c # dienÄm. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">NeizdevÄs ielÄdÄ“t PDF dokumentu</translation>
+<translation id="3945915738023014686">AugÅ¡upielÄdÄ“tÄ avÄrijas ziņojuma ID <ph name="CRASH_ID" /> (vietÄ“jais avÄrijas ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄtÄ nav norÄdÄ«ti temata citi nosaukumi. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ļaunprÄtÄ«gi izmanto jÅ«su savienojumu.</translation>
<translation id="3963721102035795474">LasÄ«tÄja režīms</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Nav}=1{No 1 vietnes }zero{No # vietnēm }one{No # vietnes }other{No # vietnēm }}</translation>
<translation id="397105322502079400">Aprēķina...</translation>
<translation id="3973234410852337861">Vietne <ph name="HOST_NAME" /> ir bloÄ·Ä“ta</translation>
+<translation id="3987940399970879459">MazÄk nekÄ 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{TuvumÄ ir 1 tÄ«mekļa lapa}zero{TuvumÄ ir # tÄ«mekļa lapas}one{TuvumÄ ir # tÄ«mekļa lapa}other{TuvumÄ ir # tÄ«mekļa lapas}}</translation>
<translation id="4021036232240155012">DNS ir tÄ«kla pakalpojums, kurÄ vietnes nosaukums tiek tulkots uz tÄs interneta adresi.</translation>
<translation id="4030383055268325496">&amp;Atsaukt pievienošanu</translation>
@@ -357,56 +401,63 @@
<translation id="4079302484614802869">Starpniekserveris ir iestatīts, lai tas lietotu .pac skripta URL, nevis fiksētus starpniekserverus.</translation>
<translation id="4098354747657067197">Maldinoša vietne</translation>
<translation id="4103249731201008433">Ierīces sērijas numurs nav derīgs.</translation>
+<translation id="410351446219883937">AutomÄtiskÄ atskaņoÅ¡ana</translation>
<translation id="4103763322291513355">ApmeklÄ“jiet vietni &lt;strong&gt;chrome://policy&lt;/strong&gt;, lai skatÄ«tu melnajÄ sarakstÄ iekļautos vietrÄžus URL, kÄ arÄ« citas politikas, ko noteicis sistÄ“mas administrators.</translation>
-<translation id="4110615724604346410">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄtÄ ir kļūdas. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Fuksīnsarkana</translation>
+<translation id="4116663294526079822">VienmÄ“r atļaut Å¡ajÄ vietnÄ“</translation>
<translation id="4117700440116928470">Politikas diapazons netiek atbalstīts.</translation>
-<translation id="4118212371799607889">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts nav uzticams pÄrlÅ«kÄ Chromium. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{vēl 1}zero{vēl #}one{vēl #}other{vēl #}}</translation>
<translation id="4130226655945681476">PÄrbaudiet tÄ«kla kabeļus, modemu un marÅ¡rutÄ“tÄju</translation>
+<translation id="413544239732274901">UzzinÄt vairÄk</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Izmantot globÄlo noklusÄ“juma vÄ“rtÄ«bu (noteikt)</translation>
+<translation id="4165986682804962316">Vietnes iestatījumi</translation>
<translation id="4169947484918424451">Vai vÄ“laties, lai Chromium saglabÄtu Å¡o karti?</translation>
<translation id="4171400957073367226">VerifikÄcijas paraksts nav derÄ«gs.</translation>
<translation id="4196861286325780578">&amp;Atcelt pÄrvietoÅ¡anas atsaukÅ¡anu</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />PÄrbaudiet ugunsmÅ«ri un pretvÄ«rusu programmu konfigurÄcijas<ph name="END_LINK" />.</translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{nav}=1{1 lietotne ($1)}=2{2 lietotnes ($1, $2)}zero{# lietotnes ($1, $2, $3)}one{# lietotne ($1, $2, $3)}other{# lietotnes ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">AvÄrijas</translation>
+<translation id="422022731706691852">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> var mudinÄt jÅ«s instalÄ“t programmas, kas var negatÄ«vi ietekmÄ“t pÄrlÅ«koÅ¡anas pieredzi (piemÄ“ram, mainot sÄkumlapu vai rÄdot papildu reklÄmas jÅ«su apmeklÄ“tajÄs vietnÄ“s). <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Mēģiniet palaist tīkla diagnostiku<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Derīgs</translation>
<translation id="4250431568374086873">Jūsu savienojums ar šo vietni nav pavisam drošs.</translation>
<translation id="4250680216510889253">NÄ“</translation>
<translation id="425582637250725228">VeiktÄs izmaiņas, iespÄ“jams, netiks saglabÄtas.</translation>
<translation id="4258748452823770588">Paraksts nav derīgs.</translation>
+<translation id="4265872034478892965">AtļÄva jÅ«su administrators</translation>
<translation id="4269787794583293679">(Nav lietotÄjvÄrda)</translation>
<translation id="4275830172053184480">Ierīces restartēšana</translation>
<translation id="4280429058323657511">, derīga līdz <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google droÅ¡ajÄ pÄrlÅ«koÅ¡anÄ nesen <ph name="BEGIN_LINK" />tika atrastas kaitÄ«gas programmas<ph name="END_LINK" /> vietnÄ“ <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">VecÄku ieteikumi</translation>
<translation id="4304224509867189079">PieteikÅ¡anÄs</translation>
-<translation id="432290197980158659">Serveris uzrÄdÄ«ja sertifikÄtu, kas neatbilst iebÅ«vÄ“tajÄm prasÄ«bÄm. Å Ä«s prasÄ«bas ir paredzÄ“tas noteiktÄm augsta droÅ¡Ä«bas lÄ«meņa vietnÄ“m, lai jÅ«s aizsargÄtu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Bloķēt (pēc noklusējuma)</translation>
<translation id="4325863107915753736">Rakstu neizdevÄs atrast.</translation>
<translation id="4326324639298822553">PÄrbaudiet derÄ«guma termiņa datumu un mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="4331708818696583467">Nav droši</translation>
<translation id="4356973930735388585">Å ajÄ vietnÄ“ esoÅ¡ie uzbrucÄ“ji jÅ«su datorÄ var mÄ“Ä£inÄt instalÄ“t bÄ«stamas programmas, kuras var nozagt vai dzÄ“st jÅ«su informÄciju (piemÄ“ram, fotoattÄ“lus, paroles, ziņojumus un informÄciju par kredÄ«tkartÄ“m).</translation>
<translation id="4372948949327679948">Tika gaidīta vērtība <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">JÅ«s mÄ“Ä£inÄjÄt sasniegt <ph name="DOMAIN" />, bet izdevÄ“js atsauca servera uzrÄdÄ«to sertifikÄtu. Tas nozÄ«mÄ“, ka servera uzrÄdÄ«tie droÅ¡Ä«bas akreditÄcijas dati itin nemaz nav uzticami. IespÄ“jams, jÅ«s sazinÄties ar uzbrucÄ“ju.</translation>
<translation id="4381091992796011497">LietotÄjvÄrds:</translation>
<translation id="4394049700291259645">Atspējot</translation>
<translation id="4406896451731180161">meklÄ“Å¡anas rezultÄti</translation>
+<translation id="4424024547088906515">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄts netiek uzskatÄ«ts par uzticamu pÄrlÅ«kÄ Chrome. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> nepieņēma jÅ«su pieteikÅ¡anÄs sertifikÄtu, vai arÄ« pieteikÅ¡anÄs sertifikÄts netika iesniegts.</translation>
<translation id="443673843213245140">Starpniekservera lietoÅ¡ana ir atspÄ“jota, bet ir norÄdÄ«ta atklÄta starpniekservera konfigurÄcija.</translation>
-<translation id="4492190037599258964">VaicÄjuma “<ph name="SEARCH_STRING" />†meklÄ“Å¡anas rezultÄti</translation>
<translation id="4506176782989081258">ValidÄcijas kļūda: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Sazinieties ar sistēmas administratoru.</translation>
<translation id="450710068430902550">Kopīgošana ar administratoru</translation>
<translation id="4515275063822566619">Kartes un adreses tiek iegÅ«tas no Chrome un jÅ«su Google konta (<ph name="ACCOUNT_EMAIL" />). Varat tÄs pÄrvaldÄ«t <ph name="BEGIN_LINK" />iestatÄ«jumos<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">InformÄcija</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">AtspÄ“jojiet paplaÅ¡inÄjumus.</translation>
<translation id="457875822857220463">PiegÄde</translation>
<translation id="4587425331216688090">Vai noņemt adresi no pÄrlÅ«ka Chrome?</translation>
-<translation id="4589078953350245614">JÅ«s mÄ“Ä£inÄjÄt sasniegt domÄ“nu <ph name="DOMAIN" />, taÄu serveris uzrÄdÄ«ja nederÄ«gu sertifikÄtu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Savienojums ar domēnu <ph name="DOMAIN" /> ir šifrēts, izmantojot mūsdienīgu šifra komplektu.</translation>
<translation id="4594403342090139922">&amp;Dzēšanas atsaukšana</translation>
<translation id="4619615317237390068">Cilnes no citÄm ierÄ«cÄ“m</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄtÄ ir kļūdas. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
+<translation id="4690462567478992370">PÄrtraukt nederÄ«ga sertifikÄta izmantoÅ¡anu</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Savienojums tika pÄrtraukts</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Palaist Windows tīkla diagnostiku<ph name="END_LINK" /></translation>
@@ -423,21 +474,24 @@
<translation id="4771973620359291008">RadÄs nezinÄma kļūda.</translation>
<translation id="4800132727771399293">PÄrbaudiet derÄ«guma termiņu un CVC kodu un mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">PaÅ¡laik nevarat apmeklÄ“t vietni <ph name="SITE" />, jo tÄ nosÅ«tÄ«ja bojÄtus akreditÄcijas datus, ko nevar apstrÄdÄt pÄrlÅ«kÄ Google Chrome. TÄ«kla kļūdas un uzbrukumi parasti ir Ä«slaicÄ«gi, tÄpÄ“c Å¡Ä« lapa vÄ“lÄk, visticamÄk, darbosies.</translation>
<translation id="4813512666221746211">Tīkla kļūda</translation>
<translation id="4816492930507672669">IetilpinÄt lapÄ</translation>
<translation id="483020001682031208">Nav nevienas fiziskÄ tÄ«mekļa lapas, ko parÄdÄ«t.</translation>
<translation id="4850886885716139402">Skatīt</translation>
<translation id="4854362297993841467">Å is piegÄdes veids nav pieejams. IzmÄ“Ä£iniet citu veidu.</translation>
<translation id="4858792381671956233">JÅ«s lÅ«dzÄt vecÄkiem atļauju apmeklÄ“t Å¡o lapu</translation>
+<translation id="4863764087567530506">Ar Å¡o saturu jÅ«s var maldinÄt, lai jÅ«s instalÄ“tu programmatÅ«ru vai atklÄtu personas informÄciju. <ph name="BEGIN_LINK" />TÄpat rÄdÄ«t<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Meklēšanas vēsture</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{un vēl 1 tīmekļa lapa}zero{un vēl # tīmekļa lapas}one{un vēl # tīmekļa lapa}other{un vēl # tīmekļa lapas}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Å Ä« lapa ir tulkota no nezinÄmas valodas valodÄ: <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">MaksÄjums</translation>
<translation id="4926049483395192435">JÄbÅ«t norÄdÄ«tai.</translation>
<translation id="495170559598752135">Darbības</translation>
<translation id="4958444002117714549">Izvērst sarakstu</translation>
-<translation id="4962322354953122629">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts nav uzticams pÄrlÅ«kÄ Chrome. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">AtkÄrtoti iespÄ“jot brÄ«dinÄjumus</translation>
<translation id="4989809363548539747">Šis spraudnis netiek atbalstīts</translation>
<translation id="5002932099480077015">IespÄ“jojot Å¡o opciju, Chrome saglabÄs jÅ«su kartes informÄciju Å¡ajÄ ierÄ«cÄ“, lai jÅ«s varÄ“tu ÄtrÄk aizpildÄ«t veidlapas.</translation>
<translation id="5018422839182700155">Nevar atvērt šo lapu</translation>
@@ -445,14 +499,15 @@
<translation id="5023310440958281426">Administratora politiku pÄrbaude</translation>
<translation id="5029568752722684782">Dzēst kopiju</translation>
<translation id="5031870354684148875">Par Google tulkotÄju</translation>
+<translation id="5039804452771397117">Atļaut</translation>
<translation id="5040262127954254034">KonfidencialitÄte</translation>
<translation id="5045550434625856497">Nepareiza parole</translation>
<translation id="5056549851600133418">Jums piemeklēti raksti</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />PÄrbaudiet starpniekservera adresi<ph name="END_LINK" />.</translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Nav sīkfailu.}=1{1 vietne izmanto sīkfailus. }zero{# vietnes izmanto sīkfailus. }one{# vietne izmanto sīkfailus. }other{# vietnes izmanto sīkfailus. }}</translation>
<translation id="5087286274860437796">Servera sertifikÄts Å¡obrÄ«d nav derÄ«gs.</translation>
<translation id="5087580092889165836">Pievienot karti</translation>
<translation id="5089810972385038852">Å tats</translation>
+<translation id="5094747076828555589">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄts netiek uzskatÄ«ts par uzticamu Chromium sistÄ“mÄ. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
<translation id="5095208057601539847">Province</translation>
<translation id="5115563688576182185">(64 bitu)</translation>
<translation id="5141240743006678641">Å ifrÄ“t sinhronizÄ“tÄs paroles, izmantojot Google akreditÄcijas datus</translation>
@@ -468,24 +523,24 @@
<translation id="5222812217790122047">JÄnorÄda e-pasta adrese.</translation>
<translation id="5251803541071282808">MÄkonis</translation>
<translation id="5277279256032773186">Vai izmantojat Chrome darbÄ? Uzņēmumi var pÄrvaldÄ«t darbinieku Chrome iestatÄ«jumus. Uzziniet vairÄk.</translation>
+<translation id="5297526204711817721">Savienojums ar Å¡o vietni nav privÄts. Lai izietu no virtuÄlÄs realitÄtes režīma, noņemiet austiņas un nospiediet Atpakaļ.</translation>
<translation id="5299298092464848405">ParsÄ“jot politiku, radÄs kļūda.</translation>
-<translation id="5300589172476337783">RÄdÄ«t</translation>
<translation id="5308689395849655368">AvÄriju pÄrskatu izveide ir atspÄ“jota.</translation>
<translation id="5317780077021120954">SaglabÄt</translation>
<translation id="5327248766486351172">Nosaukums</translation>
-<translation id="5337705430875057403">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> var pamudinÄt jÅ«s veikt bÄ«stamas darbÄ«bas, piemÄ“ram, instalÄ“t programmatÅ«ru vai atklÄt savu personas informÄciju (t.i., paroles, tÄlruņa numurus vai informÄciju par kredÄ«tkartÄ“m).</translation>
-<translation id="5359637492792381994">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts Å¡obrÄ«d nav uzticams. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu.<ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">PaÅ¡laik nevarat apmeklÄ“t vietni <ph name="SITE" />, jo tÄs sertifikÄts ir atsaukts. TÄ kÄ tÄ«kla kļūdas un uzbrukumi parasti ir Ä«slaicÄ«gi, visticamÄk, Å¡Ä« lapa vÄ“lÄk darbosies.</translation>
<translation id="536296301121032821">NeizdevÄs saglabÄt politikas iestatÄ«jumus.</translation>
<translation id="5386426401304769735">Å Ä«s vietnes sertifikÄtu Ä·Ä“dÄ“ ir iekļauts sertifikÄts, kas ir parakstÄ«ts, izmantojot SHA-1.</translation>
<translation id="5402410679244714488">DerÄ«guma termiņš: <ph name="EXPIRATION_DATE_ABBR" />, pÄ“dÄ“joreiz izmantota pirms vairÄk nekÄ gada</translation>
+<translation id="540969355065856584">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts Å¡obrÄ«d nav derÄ«gs. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ļaunprÄtÄ«gi izmanto jÅ«su savienojumu.</translation>
<translation id="5421136146218899937">NotÄ«rÄ«t pÄrlÅ«koÅ¡anas datus</translation>
<translation id="5430298929874300616">Noņemt grÄmatzÄ«mi</translation>
<translation id="5431657950005405462">Fails nav atrasts</translation>
-<translation id="5435775191620395718">Tiek rÄdÄ«ta vÄ“sture no Å¡Ä«s ierÄ«ces. <ph name="BEGIN_LINK" />Uzziniet vairÄk<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Å eit tika atklÄta shÄ“mas validÄ“Å¡anas kļūda: <ph name="ERROR_PATH" />. Kļūdas ziņojums: <ph name="ERROR" />.</translation>
<translation id="5452270690849572955">Å o vietnes <ph name="HOST_NAME" /> lapu nevar atrast</translation>
<translation id="5455374756549232013">Politikas laikspiedols nav derīgs.</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> no <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Nav derīgi</translation>
<translation id="5470861586879999274">&amp;Atcelt labojuma atsaukšanu</translation>
<translation id="54817484435770891">Derīgas adreses pievienošana</translation>
<translation id="5492298309214877701">Å ai vietnei uzņēmuma, organizÄcijas vai skolas iekÅ¡tÄ«klÄ ir tÄds pats URL kÄ ÄrÄ“jai vietnei.
@@ -502,6 +557,8 @@
<translation id="5571083550517324815">Nevar saņemt sÅ«tÄ«jumu Å¡ajÄ adresÄ“. Atlasiet citu adresi.</translation>
<translation id="5572851009514199876">LÅ«dzu, palaidiet pÄrlÅ«ku Chrome un pierakstieties tajÄ, lai pÄrlÅ«kÄ Chrome varÄ“tu pÄrbaudÄ«t, vai jums ir atļauja piekļūt Å¡ai vietnei.</translation>
<translation id="5580958916614886209">PÄrbaudiet derÄ«guma termiņa mÄ“nesi un mÄ“Ä£iniet vÄ“lreiz.</translation>
+<translation id="5586446728396275693">Nav saglabÄtu adreÅ¡u.</translation>
+<translation id="5595485650161345191">Rediģēt adresi</translation>
<translation id="560412284261940334">PÄrvaldÄ«Å¡ana netiek atbalstÄ«ta.</translation>
<translation id="5610142619324316209">PÄrbaudiet savienojumu.</translation>
<translation id="5610807607761827392">Varat pÄrvaldÄ«t karÅ¡u un adreÅ¡u informÄciju sadaÄ¼Ä <ph name="BEGIN_LINK" />IestatÄ«jumi<ph name="END_LINK" />.</translation>
@@ -509,15 +566,18 @@
<translation id="5622887735448669177">Vai vēlaties pamest šo vietni?</translation>
<translation id="5629630648637658800">NeizdevÄs ielÄdÄ“t politikas iestatÄ«jumus.</translation>
<translation id="5631439013527180824">IerÄ«ces pÄrvaldÄ«bas marÄ·ieris nav derÄ«gs.</translation>
+<translation id="5633066919399395251">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> var mÄ“Ä£inÄt jÅ«su datorÄ instalÄ“t bÄ«stamas programmas, kas zog vai izdzÄ“Å¡ informÄciju (piemÄ“ram, fotoattÄ“lus, paroles, ziņojumus un kredÄ«tkarÅ¡u datus). <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5646376287012673985">AtraÅ¡anÄs vieta</translation>
+<translation id="5659593005791499971">E-pasts</translation>
<translation id="5669703222995421982">Saņemiet personalizētu saturu</translation>
<translation id="5675650730144413517">Å Ä« lapa nedarbojas</translation>
-<translation id="5677928146339483299">BloÄ·Ä“ts</translation>
-<translation id="5694783966845939798">JÅ«s mÄ“Ä£inÄjÄt sasniegt domÄ“nu <ph name="DOMAIN" />, bet serveris uzrÄdÄ«ja sertifikÄtu, kas ir parakstÄ«ts, izmantojot vÄju paraksta algoritmu (piemÄ“ram, SHA-1). Tas nozÄ«mÄ“, ka servera norÄdÄ«tie droÅ¡Ä«bas akreditÄcijas dati var bÅ«t viltoti un Å¡is serveris var nebÅ«t tas serveris, kuru mÄ“Ä£inÄt sasniegt (iespÄ“jams, jÅ«s sazinÄties ar uzbrucÄ“ju). <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">TÄ«mekļa vietnes identitÄte nav apstiprinÄta.</translation>
+<translation id="5713016350996637505">Maldinošs saturs bloķēts</translation>
<translation id="5720705177508910913">PaÅ¡reizÄ“jais lietotÄjs</translation>
<translation id="5732392974455271431">Lai atbloÄ·Ä“tu, vÄ“rsieties pie vecÄkiem</translation>
<translation id="5763042198335101085">Ievadiet derīgu e-pasta adresi</translation>
<translation id="5765072501007116331">Lai skatÄ«tu piegÄdes veidus un prasÄ«bas, atlasiet adresi.</translation>
+<translation id="5778550464785688721">PilnÄ«ga MIDI ierÄ«Äu pÄrvaldÄ«ba</translation>
<translation id="5784606427469807560">Apstiprinot karti, radÄs problÄ“ma. PÄrbaudiet interneta savienojumu un mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="5785756445106461925">TurklÄt Å¡ajÄ lapÄ ir citi resursi, kas nav droÅ¡i. KamÄ“r Å¡ie resursi tiek pÄrsÅ«tÄ«ti, tos var aplÅ«kot citi, kÄ arÄ« uzbrucÄ“js var tos pÄrveidot, lai mainÄ«tu lapas izskatu.</translation>
<translation id="5786044859038896871">Vai vÄ“laties aizpildÄ«t laukus ar kartes informÄciju?</translation>
@@ -526,14 +586,14 @@
<translation id="5813119285467412249">&amp;Pievienošanas atsaukuma atcelšana</translation>
<translation id="5814352347845180253">Varat zaudÄ“t piekļuvi maksas saturam no vietnes <ph name="SITE" /> un dažÄm citÄm vietnÄ“m.</translation>
<translation id="5838278095973806738">Neievadiet Å¡ajÄ vietnÄ“ sensitÄ«vu informÄciju (piemÄ“ram, paroles vai kredÄ«tkartes), jo to var nozagt uzbrucÄ“ji.</translation>
-<translation id="5843436854350372569">JÅ«s mÄ“Ä£inÄjÄt sasniegt domÄ“nu <ph name="DOMAIN" />, taÄu serveris uzrÄdÄ«ja sertifikÄtu ar nedroÅ¡u atslÄ“gu. IespÄ“jams, uzbrucÄ“js ir uzlauzis privÄto atslÄ“gu un Å¡is serveris var nebÅ«t tas serveris, kuru mÄ“Ä£inÄt sasniegt (iespÄ“jams, jÅ«s sazinÄties ar uzbrucÄ“ju). <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Å Ä« vietne nav sasniedzama</translation>
<translation id="5869522115854928033">SaglabÄtÄs paroles</translation>
<translation id="5872918882028971132">VecÄku ieteikumi</translation>
<translation id="5901630391730855834">Dzeltena</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (veikta sinhronizÄcija)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 tiek lietots}zero{# tiek lietoti}one{# tiek lietots}other{# tiek lietoti}}</translation>
<translation id="5926846154125914413">Varat zaudÄ“t piekļuvi maksas saturam no noteiktÄm vietnÄ“m.</translation>
<translation id="5959728338436674663">AutomÄtiski sÅ«tÄ«t Google serveriem noteiktu <ph name="BEGIN_WHITEPAPER_LINK" />sistÄ“mas informÄciju un lapu saturu<ph name="END_WHITEPAPER_LINK" />, lai palÄ«dzÄ“tu noteikt bÄ«stamas lietotnes un vietnes. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Nedēļa</translation>
<translation id="5967867314010545767">Noņemt no vēstures</translation>
<translation id="5975083100439434680">TÄlinÄt</translation>
<translation id="598637245381783098">Nevar atvÄ“rt maksÄjumu lietotni</translation>
@@ -542,21 +602,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1. lapa}zero{#. lapa}one{#. lapa}other{#. lapa}}</translation>
<translation id="6017514345406065928">Zaļa</translation>
+<translation id="6017850046339264347">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> varÄ“tu instalÄ“t maldinoÅ¡as lietotnes, kas uzdodas par citu saturu, vai ievÄkt datus, ko izmantot jÅ«su izsekoÅ¡anai. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (veikta sinhronizÄcija)</translation>
<translation id="6027201098523975773">Ievadiet vÄrdu</translation>
<translation id="6040143037577758943">Aizvērt</translation>
<translation id="6042308850641462728">VairÄk</translation>
+<translation id="6047233362582046994">Ja apzinÄties droÅ¡Ä«bas risku, varat arÄ« <ph name="BEGIN_LINK" />apmeklÄ“t Å¡o vietni<ph name="END_LINK" />, pirms ir noņemtas kaitÄ«gÄs lietotnes.</translation>
+<translation id="6051221802930200923">PaÅ¡laik nevarat apmeklÄ“t vietni <ph name="SITE" />, jo tajÄ tiek izmantota sertifikÄtu piesprauÅ¡ana. TÄ kÄ tÄ«kla kļūdas un uzbrukumi parasti ir Ä«slaicÄ«gi, visticamÄk, Å¡Ä« lapa vÄ“lÄk darbosies.</translation>
<translation id="6060685159320643512">Esiet uzmanīgs! Šie eksperimenti var jums kaitēt</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{nav}=1{1}zero{#}one{#}other{#}}</translation>
+<translation id="6080696365213338172">JÅ«s esat piekļuvis saturam, izmantojot administratora izsniegtu sertifikÄtu. Datus, kurus sniedzat domÄ“nÄ <ph name="DOMAIN" />, var pÄrtvert jÅ«su administrators.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Nav}=1{1 parole (sinhronizēta)}zero{# paroles (sinhronizētas)}one{# parole (sinhronizēta)}other{# paroles (sinhronizētas)}}</translation>
<translation id="6146055958333702838">PÄrbaudiet vadus un atkÄrtoti palaidiet marÅ¡rutÄ“tÄjus, modemus vai citas
izmantotÄs tÄ«kla ierÄ«ces.</translation>
<translation id="614940544461990577">Veiciet tÄlÄk norÄdÄ«tÄs darbÄ«bas.</translation>
<translation id="6151417162996330722">Å Ä« servera sertifikÄta derÄ«guma periods ir pÄrÄk ilgs.</translation>
<translation id="6157877588268064908">Lai skatītu nosūtīšanas veidus un prasības, atlasiet adresi.</translation>
+<translation id="6158003235852588289">Google droÅ¡Ä pÄrlÅ«koÅ¡ana nesen konstatÄ“ja pikÅ¡Ä·erÄ“Å¡anu vietnÄ“ <ph name="SITE" />. PikÅ¡Ä·erÄ“Å¡anas vietnes uzdodas par citÄm vietnÄ“m, lai jÅ«s maldinÄtu.</translation>
<translation id="6165508094623778733">Uzziniet vairÄk</translation>
+<translation id="6169916984152623906">Tagad varat privÄti pÄrlÅ«kot saturu, un citas personas, kas izmanto Å¡o ierÄ«ci, nevarÄ“s redzÄ“t jÅ«su darbÄ«bas. TomÄ“r lejupielÄdes un grÄmatzÄ«mes tiks saglabÄtas.</translation>
<translation id="6177128806592000436">Savienojums ar šo vietni nav drošs.</translation>
<translation id="6184817833369986695">(personu grupa: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Interneta savienojuma pÄrbaude</translation>
<translation id="6218753634732582820">Vai noņemt adresi no pÄrlÅ«ka Chromium?</translation>
+<translation id="6221345481584921695">Google droÅ¡Äs pÄrlÅ«koÅ¡anas tehnoloÄ£ija vietnÄ“ <ph name="SITE" /> nesen <ph name="BEGIN_LINK" />konstatÄ“ja ļaunprÄtÄ«gu programmatÅ«ru<ph name="END_LINK" />. Vietnes, kuras parasti ir droÅ¡as, dažkÄrt tiek inficÄ“tas ar ļaunprÄtÄ«gu programmatÅ«ru. Ä»aunprÄtÄ«gÄ satura avots ir <ph name="SUBRESOURCE_HOST" /> — plaÅ¡i zinÄms ļaunprÄtÄ«gÄs programmatÅ«ras izplatÄ«tÄjs.</translation>
<translation id="6251924700383757765">KonfidencialitÄtes politika</translation>
<translation id="6254436959401408446">Nav pietiekami daudz vietas atmiņÄ, lai atvÄ“rtu Å¡o lapu</translation>
<translation id="625755898061068298">JÅ«s izvÄ“lÄ“jÄties atspÄ“jot droÅ¡Ä«bas brÄ«dinÄjumus Å¡ai vietnei.</translation>
@@ -582,15 +650,14 @@
<translation id="6404511346730675251">Rediģēt grÄmatzÄ«mi</translation>
<translation id="6410264514553301377">Ievadiet kredītkartes <ph name="CREDIT_CARD" /> derīguma termiņu un CVC.</translation>
<translation id="6414888972213066896">JÅ«s lÅ«dzÄt vienam no vecÄkiem atļauju apmeklÄ“t Å¡o vietni</translation>
-<translation id="6416403317709441254">Å obrÄ«d nevarat apmeklÄ“t vietni <ph name="SITE" />, jo no tÄs tika nosÅ«tÄ«ti sajaukti akreditÄcijas dati, kurus nevar apstrÄdÄt pÄrlÅ«kÄ Chromium. TÄ«kla kļūdas un brÄ«dinÄjumi parasti ir Ä«slaicÄ«gi, tÄpÄ“c Å¡Ä« lapa vÄ“lÄk, visticamÄk, darbosies. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Nevar pÄrbaudÄ«t, vai sertifikÄts ir atsaukts.</translation>
<translation id="6433490469411711332">KontaktinformÄcijas rediģēšana</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> noraidīja savienojuma izveidi.</translation>
<translation id="6446608382365791566">Papildu informÄcijas pievienoÅ¡ana</translation>
+<translation id="6447842834002726250">SÄ«kfaili</translation>
<translation id="6451458296329894277">ApstiprinÄt veidlapas atkÄrtotu iesniegÅ¡anu</translation>
<translation id="6456339708790392414">MaksÄjums</translation>
<translation id="6458467102616083041">Ignorēta, jo ar politiku ir atspējota noklusējuma meklēšana.</translation>
-<translation id="6462969404041126431">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts, iespÄ“jams, ir atsaukts. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Ierīces politikas</translation>
<translation id="6477321094435799029">PÄrlÅ«kÄ Chrome tika noteikts, ka Å¡ajÄ lapÄ ir neparasts kods. Lapa tika bloÄ·Ä“ta, lai aizsargÄtu jÅ«su personas informÄciju (piemÄ“ram, paroles, tÄlruņa numurus un kredÄ«tkarÅ¡u informÄciju).</translation>
<translation id="6489534406876378309">SÄkt avÄriju datu augÅ¡upielÄdi</translation>
@@ -602,20 +669,19 @@
<translation id="6556915248009097796">Derīguma termiņš: <ph name="EXPIRATION_DATE_ABBR" />; pēdējoreiz izmantota: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">JÅ«su vadÄ«tÄjs vÄ“l nav to apstiprinÄjis</translation>
<translation id="6569060085658103619">JÅ«s skatÄt paplaÅ¡inÄjumu lapu.</translation>
-<translation id="6593753688552673085">mazÄk nekÄ <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Ar Å¡o saturu var jÅ«s maldinÄt, lai jÅ«s instalÄ“tu bÄ«stamu programmatÅ«ru savÄ ierÄ«cÄ“, vai var tikt nozagta vai izdzÄ“sta jÅ«su informÄcija. <ph name="BEGIN_LINK" />TÄpat rÄdÄ«t<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Šifrēšanas opcijas</translation>
<translation id="662080504995468778">Palikt</translation>
<translation id="6626291197371920147">Derīga kartes numura pievienošana</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> meklēšana</translation>
+<translation id="6630809736994426279">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> var mÄ“Ä£inÄt jÅ«su Mac datorÄ instalÄ“t bÄ«stamas programmas, kas zog vai izdzÄ“Å¡ informÄciju (piemÄ“ram, fotoattÄ“lus, paroles, ziņojumus un kredÄ«tkarÅ¡u datus). <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6644283850729428850">Å Ä« politika ir izbeigta.</translation>
-<translation id="6652240803263749613">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts nav uzticams jÅ«su datora operÄ“tÄjsistÄ“mÄ. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Vai noņemt veidlapas ieteikumu no pÄrlÅ«ka Chromium?</translation>
<translation id="6685834062052613830">Izrakstieties un pabeidziet iestatīšanu</translation>
<translation id="6710213216561001401">Iepriekšējais</translation>
<translation id="6710594484020273272">&lt;Ierakstiet meklēšanas vienumu&gt;</translation>
<translation id="6711464428925977395">StarpniekserverÄ« radÄs kļūda, vai arÄ« adrese nav pareiza.</translation>
<translation id="6727102863431372879">Iestatīt</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{nav}=1{1 vienums}zero{# vienumi}one{# vienums}other{# vienumi}}</translation>
<translation id="674375294223700098">NezinÄma servera sertifikÄta kļūda.</translation>
<translation id="6753269504797312559">Politikas vērtība</translation>
<translation id="6757797048963528358">IerÄ«ce tika pÄrslÄ“gta miega režīmÄ.</translation>
@@ -623,6 +689,8 @@
<translation id="6810899417690483278">PielÄgoÅ¡anas ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">NeizdevÄs ielÄdÄ“t reÄ£ionu datus</translation>
+<translation id="6825578344716086703">JÅ«s mÄ“Ä£inÄjÄt sasniegt domÄ“nu <ph name="DOMAIN" />, bet serveris uzrÄdÄ«ja sertifikÄtu, kas ir parakstÄ«ts, izmantojot vÄju paraksta algoritmu (piemÄ“ram, SHA-1). Tas nozÄ«mÄ“, ka servera norÄdÄ«tie droÅ¡Ä«bas akreditÄcijas dati var bÅ«t viltoti un Å¡is serveris var nebÅ«t tas serveris, kuru mÄ“Ä£inÄt sasniegt (iespÄ“jams, jÅ«s sazinÄties ar uzbrucÄ“ju).</translation>
+<translation id="6830728435402077660">Nav droši</translation>
<translation id="6831043979455480757">Tulkot</translation>
<translation id="6839929833149231406">Apgabals</translation>
<translation id="6874604403660855544">&amp;Atcelt pievienošanas atsaukšanu</translation>
@@ -630,6 +698,7 @@
<translation id="6895330447102777224">Karte ir apstiprinÄta</translation>
<translation id="6897140037006041989">LietotÄja aÄ£ents</translation>
<translation id="6915804003454593391">LietotÄjs:</translation>
+<translation id="6945221475159498467">Atlasīt</translation>
<translation id="6948701128805548767">Lai skatītu saņemšanas veidus un prasības, atlasiet adresi.</translation>
<translation id="6957887021205513506">Å Ä·iet, ka servera sertifikÄts ir viltojums.</translation>
<translation id="6965382102122355670">Labi</translation>
@@ -638,15 +707,16 @@
<translation id="6973656660372572881">Ir norÄdÄ«ti gan fiksÄ“ti starpniekserveri, gan .pac skripta URL.</translation>
<translation id="6989763994942163495">RÄdÄ«t papildu iestatÄ«jumus...</translation>
<translation id="7000990526846637657">Netika atrasts neviens vēstures ieraksts.</translation>
-<translation id="7009986207543992532">JÅ«s mÄ“Ä£inÄjÄt sasniegt domÄ“nu <ph name="DOMAIN" />, taÄu serveris uzrÄdÄ«ja sertifikÄtu, kura derÄ«guma periods ir pÄrÄk ilgs, lai bÅ«tu uzticams. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">JÅ«su Google kontam var bÅ«t cita veida pÄrlÅ«koÅ¡anas vÄ“stures dati vietnÄ“ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />.</translation>
<translation id="7029809446516969842">Paroles</translation>
+<translation id="7050187094878475250">JÅ«s mÄ“Ä£inÄjÄt sasniegt domÄ“nu <ph name="DOMAIN" />, bet serveris uzrÄdÄ«ja sertifikÄtu, kura derÄ«guma periods ir pÄrÄk ilgs, lai bÅ«tu uzticams.</translation>
+<translation id="7053983685419859001">BloÄ·Ä“t</translation>
<translation id="7064851114919012435">KontaktinformÄcija</translation>
<translation id="7079718277001814089">Å Ä« vietne satur ļaunprÄtÄ«gu programmatÅ«ru</translation>
<translation id="7087282848513945231">GrÄfiste</translation>
-<translation id="7088615885725309056">VecÄka</translation>
<translation id="7090678807593890770">Veiciet Google meklÄ“Å¡anu, izmantojot vaicÄjumu “<ph name="LINK" />â€</translation>
+<translation id="7108819624672055576">AtļÄva paplaÅ¡inÄjums</translation>
<translation id="7119414471315195487">Aizveriet citas cilnes vai programmas</translation>
<translation id="7129409597930077180">Nevar nosūtīt uz šo adresi. Atlasiet citu adresi.</translation>
<translation id="7138472120740807366">PiegÄdes veids</translation>
@@ -664,22 +734,18 @@
<translation id="7220786058474068424">Notiek apstrÄde</translation>
<translation id="724691107663265825">VietnÄ“ ir ļaunprÄtÄ«ga programmatÅ«ra</translation>
<translation id="724975217298816891">Lai atjauninÄtu kartes informÄciju, ievadiet kredÄ«tkartes <ph name="CREDIT_CARD" /> derÄ«guma termiņu un CVC. PÄ“c apstiprinÄÅ¡anas kartes informÄcija tiks kopÄ«gota ar Å¡o vietni.</translation>
-<translation id="725866823122871198">Nevar izveidot privÄtu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jÅ«su datora datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizs.</translation>
+<translation id="7260504762447901703">Atsaukt piekļuvi</translation>
<translation id="7275334191706090484">PÄrvaldÄ«tÄs grÄmatzÄ«mes</translation>
<translation id="7298195798382681320">Ieteicams</translation>
<translation id="7309308571273880165">AvÄrijas pÄrskats notverts: <ph name="CRASH_TIME" /> (augÅ¡upielÄdi pieprasÄ«jis lietotÄjs; augÅ¡upielÄde vÄ“l nav veikta)</translation>
<translation id="7334320624316649418">&amp;Atcelt pÄrkÄrtoÅ¡anas atsaukÅ¡anu</translation>
<translation id="733923710415886693">Servera sertifikÄts netika atklÄts, izmantojot Certificate Transparency.</translation>
-<translation id="7351800657706554155">PaÅ¡laik nevarat apmeklÄ“t vietni <ph name="SITE" />, jo Å¡is sertifikÄts ir atsaukts. TÄ«kla kļūdas un uzbrukumi parasti ir Ä«slaicÄ«gi, tÄpÄ“c Å¡Ä« lapa ,visticamÄk, vÄ“lÄk darbosies. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Komandrinda</translation>
<translation id="7372973238305370288">meklÄ“Å¡anas rezultÄts</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">NÄ“</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Kartes apstiprinÄÅ¡ana</translation>
-<translation id="7394102162464064926">Vai tieÅ¡Äm vÄ“laties dzÄ“st Å¡Ä«s lapas no vÄ“stures?
-
-NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />).</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Profila ceļš</translation>
<translation id="7424977062513257142">Å ajÄ vietnÄ“ iegultÄ lapÄ ir rakstÄ«ts:</translation>
@@ -687,6 +753,7 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="7444046173054089907">Å Ä« vietne ir bloÄ·Ä“ta</translation>
<translation id="7445762425076701745">Nevar pilnÄ«bÄ apstiprinÄt servera identifikÄcijas datus, ar kuru esat savienots. Jums ir izveidots savienojums ar serveri, izmantojot nosaukumu, kas ir derÄ«gs tikai jÅ«su tÄ«klÄ, kam ÄrÄ“jÄ sertifikÄta izdevÄ“jiestÄde nekÄdÄ veidÄ nevar apstiprinÄt Ä«paÅ¡umtiesÄ«bas. TÄ kÄ dažas sertifikÄta izdevÄ“jiestÄdes tÄpat izsniegs sertifikÄtus Å¡Ädiem nosaukumiem, nav iespÄ“jams garantÄ“t, ka jÅ«s esat savienots ar vajadzÄ«go vietni, nevis uzbrucÄ“ju.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />UzzinÄt vairÄk<ph name="END_LINK" /> par Å¡o problÄ“mu.</translation>
+<translation id="7455133967321480974">Izmantot globÄlo noklusÄ“jumu (BloÄ·Ä“t)</translation>
<translation id="7460163899615895653">JÅ«su nesen izmantotÄs cilnes no citÄm ierÄ«cÄ“m tiek rÄdÄ«tas Å¡eit</translation>
<translation id="7469372306589899959">Notiek kartes apstiprinÄÅ¡ana</translation>
<translation id="7481312909269577407">PÄrsÅ«tÄ«t</translation>
@@ -694,36 +761,43 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="7508255263130623398">Atgrieztais politikas ierīces ID ir tukšs vai neatbilst pašreizējam ierīces ID.</translation>
<translation id="7514365320538308">LejupielÄdÄ“t</translation>
<translation id="7518003948725431193">Å ÄdÄ tÄ«mekļa adresÄ“ netika atrasta neviena tÄ«mekļa lapa: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Vērtība</translation>
<translation id="7537536606612762813">ObligÄti</translation>
+<translation id="7542403920425041731">PÄ“c apstiprinÄjuma jÅ«su kartes informÄcija tiks kopÄ«gota ar Å¡o vietni.</translation>
<translation id="7542995811387359312">AutomÄtiska kredÄ«tkartes numura ievadÄ«Å¡ana ir atspÄ“jota, jo Å¡ai veidlapai netiek izmantots droÅ¡s savienojums.</translation>
<translation id="7543525346216957623">LÅ«dziet kÄdam no vecÄkiem</translation>
<translation id="7549584377607005141">Lai tÄ«mekļa lapu varÄ“tu attÄ“lot pareizi, tai nepiecieÅ¡ami jÅ«su iepriekÅ¡ ievadÄ«tie dati. Varat atkÄrtoti nosÅ«tÄ«t Å¡os datus, taÄu tÄdÄ gadÄ«jumÄ tiks atkÄrtota ikviena darbÄ«ba, ko pirms tam veica lapa.</translation>
<translation id="7552846755917812628">Izmantojiet tÄlÄk sniegtos padomus.</translation>
<translation id="7554791636758816595">Jauna cilne</translation>
+<translation id="7567204685887185387">Å is serveris nevarÄ“ja pierÄdÄ«t, ka Å¡Ä« ir vietne <ph name="DOMAIN" />; tÄs droÅ¡Ä«bas sertifikÄts, iespÄ“jams, ir izveidots krÄpnieciski. IespÄ“jams, tas ir nepareizas konfigurÄcijas dēļ vai arÄ« kÄds ir ļaunprÄtÄ«gi izmantojis jÅ«su savienojumu.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}zero{<ph name="CONTACT_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Å Ä« lapa ir rakstÄ«ta<ph name="ORIGINAL_LANGUAGE" />valodÄ. Vai vÄ“laties to tulkot?</translation>
<translation id="7569952961197462199">Vai noņemt kredÄ«tkarti no pÄrlÅ«ka Chrome?</translation>
<translation id="7569983096843329377">Melna</translation>
<translation id="7578104083680115302">Ä€tri apmaksÄjiet pirkumus vietnÄ“s un lietotnÄ“s no dažÄdÄm ierÄ«cÄ“m, izmantojot kartes, ko esat saglabÄjis Google sistÄ“mÄ.</translation>
<translation id="7588950540487816470">Fiziskais tīmeklis</translation>
<translation id="7592362899630581445">Servera sertifikÄtÄ ir pÄrkÄpti nosaukuma ierobežojumi.</translation>
+<translation id="7598391785903975535">MazÄk nekÄ <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> paÅ¡laik nevar apstrÄdÄt Å¡o pieprasÄ«jumu.</translation>
<translation id="7600965453749440009">Nekad netulkot saturu, kas rakstÄ«ts <ph name="LANGUAGE" /> valodÄ</translation>
<translation id="7610193165460212391">VÄ“rtÄ«ba pÄrsniedz diapazonu: <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Derīguma termiņš: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Jums jau ir dati, kas šifrēti, izmantojot citu Google konta paroles versiju. Ievadiet to šeit.</translation>
-<translation id="7634554953375732414">JÅ«su savienojums ar Å¡o vietni nav privÄts.</translation>
<translation id="7637571805876720304">Vai noņemt kredÄ«tkarti no pÄrlÅ«ka Chromium?</translation>
<translation id="765676359832457558">Slēpt papildu iestatījumus...</translation>
<translation id="7658239707568436148">Atcelt</translation>
+<translation id="7662298039739062396">IestatÄ«jumu kontrolÄ“ paplaÅ¡inÄjums</translation>
<translation id="7667346355482952095">Atgrieztais politikas marķieris ir tukšs vai neatbilst pašreizējam marķierim</translation>
<translation id="7668654391829183341">NezinÄma ierÄ«ce</translation>
<translation id="7669271284792375604">UzbrucÄ“ji Å¡ajÄ vietnÄ“ var mudinÄt jÅ«s uz tÄdu programmu instalÄ“Å¡anu, kuras traucÄ“ pÄrlÅ«koÅ¡anu (piemÄ“ram, mainot sÄkumlapu vai apmeklÄ“tajÄs vietnÄ“s rÄdot papildu reklÄmas).</translation>
<translation id="7674629440242451245">Vai jÅ«s interesÄ“ jaunas Chrome funkcijas? IzmÄ“Ä£iniet izstrÄdÄtÄja versiju vietnÄ“ chrome.com/dev.</translation>
<translation id="7682287625158474539">PiegÄde</translation>
+<translation id="7701040980221191251">Neviens</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Apmeklēt vietni <ph name="SITE" /> (nav droša)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">SertifikÄts</translation>
+<translation id="7716147886133743102">Bloķēja jūsu administrators</translation>
<translation id="7716424297397655342">Å o vietni nevar ielÄdÄ“t no keÅ¡atmiņas</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Netiek pÄrvaldÄ«ts</translation>
<translation id="7755287808199759310">Lai atbloÄ·Ä“tu, vÄ“sieties pie vecÄka</translation>
<translation id="7758069387465995638">Iespējams, savienojumu ir bloķējis ugunsmūris vai pretvīrusu programmatūra.</translation>
@@ -750,15 +824,15 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="7951415247503192394">(32 bitu)</translation>
<translation id="7956713633345437162">MobilÄs grÄmatzÄ«mes</translation>
<translation id="7961015016161918242">Nekad</translation>
-<translation id="7962083544045318153">AvÄrijas ID: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">VienmÄ“r tulkot no <ph name="ORIGINAL_LANGUAGE" /> valodas <ph name="TARGET_LANGUAGE" /> valodÄ</translation>
<translation id="7995512525968007366">Nav norÄdÄ«ts</translation>
<translation id="800218591365569300">Aizveriet citas cilnes vai programmas, lai atbrÄ«votu vietu atmiņÄ.</translation>
<translation id="8012647001091218357">MÄ“s nevarÄ“jÄm sasniegt jÅ«su vecÄkus. LÅ«dzu, mÄ“Ä£iniet vÄ“lreiz.</translation>
<translation id="8025119109950072390">UzbrucÄ“ji Å¡ajÄ vietnÄ“ var mudinÄt jÅ«s veikt bÄ«stamas darbÄ«bas, piemÄ“ram, instalÄ“t programmatÅ«ru vai atklÄt savu personas informÄciju (piemÄ“ram, paroles, tÄlruņa numurus vai informÄciju par kredÄ«tkartÄ“m).</translation>
-<translation id="803030522067524905">Nesen Google droÅ¡ajÄ pÄrlÅ«koÅ¡anÄ tika konstatÄ“ta pikÅ¡Ä·erÄ“Å¡ana vietnÄ“ <ph name="SITE" />. PikÅ¡Ä·erÄ“Å¡anas vietnes uzdodas par citÄm vietnÄ“m, lai jÅ«s maldinÄtu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Å Ä« lapas saturs ir Å¡ÄdÄ valodÄ: <ph name="SOURCE_LANGUAGE" />. Vai tulkot Å¡ÄdÄ valodÄ: <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">VaicÄt (pÄ“c noklusÄ“juma)</translation>
<translation id="8041089156583427627">Sūtīt atsauksmes</translation>
+<translation id="8041940743680923270">Izmantot globÄlo noklusÄ“jumu (VaicÄt)</translation>
<translation id="8088680233425245692">Rakstu neizdevÄs skatÄ«t.</translation>
<translation id="8089520772729574115">mazÄk nekÄ 1 MB</translation>
<translation id="8091372947890762290">AktivizÄcija vÄ“l nav apstiprinÄta serverÄ«.</translation>
@@ -767,13 +841,14 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="8134994873729925007">Nevarēja atrast <ph name="HOST_NAME" /> servera <ph name="BEGIN_ABBR" />DNS adresi<ph name="END_ABBR" />.</translation>
<translation id="8149426793427495338">Dators tika pÄrslÄ“gts miega režīmÄ.</translation>
<translation id="8150722005171944719">VietnÄ“ <ph name="URL" /> esoÅ¡o failu nevar nolasÄ«t. IespÄ“jams, tas ir noņemts vai pÄrvietots vai piekļuvei nepiecieÅ¡amas atļaujas.</translation>
+<translation id="8184538546369750125">Izmantot globÄlo noklusÄ“jumu (Atļaut)</translation>
+<translation id="8191494405820426728">VietÄ“jais avÄrijas ID: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;PÄrvietoÅ¡anas atsaukÅ¡ana</translation>
<translation id="8201077131113104583">NederÄ«gs atjauninÄÅ¡anas URL paplaÅ¡inÄjumam ar ID “<ph name="EXTENSION_ID" />â€.</translation>
<translation id="8202097416529803614">Pasūtījuma kopsavilkums</translation>
<translation id="8218327578424803826">PieÅ¡Ä·irtÄ atraÅ¡anÄs vieta:</translation>
<translation id="8225771182978767009">Persona, kura iestatÄ«ja Å¡o datoru, izvÄ“lÄ“jÄs bloÄ·Ä“t Å¡o vietni.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">PaÅ¡laik vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> esoÅ¡ie uzbrucÄ“ji jÅ«su datorÄ var mÄ“Ä£inÄt instalÄ“t bÄ«stamas programmas, kuras var nozagt vai dzÄ“st jÅ«su informÄciju (piemÄ“ram, fotoattÄ“lus, paroles, ziņojumus un informÄciju par kredÄ«tkartÄ“m).</translation>
<translation id="8241707690549784388">Lapa, ko meklÄ“jÄt, izmantoja jÅ«su ievadÄ«to informÄciju. AtgrieÅ¡anÄs lapÄ var radÄ«t jebkuras jÅ«su darbÄ«bas atkÄrtojumu. Vai vÄ“laties turpinÄt?</translation>
<translation id="8249320324621329438">PÄ“dÄ“jÄs pirmsielÄdes laiks:</translation>
<translation id="8253091569723639551">JÄnorÄda norÄ“Ä·inu adrese.</translation>
@@ -781,6 +856,7 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="8289355894181816810">Sazinieties ar tÄ«kla administratoru, ja neesat pÄrliecinÄts, ko tas nozÄ«mÄ“.</translation>
<translation id="8293206222192510085">Pievienot grÄmatzÄ«mi</translation>
<translation id="8294431847097064396">Avots</translation>
+<translation id="8306404619377842860">Nevar izveidot privÄtu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jÅ«su ierÄ«cÄ“ iestatÄ«tais datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizs. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8308427013383895095">TulkoÅ¡ana neizdevÄs, jo radÄs problÄ“ma ar tÄ«kla savienojumu.</translation>
<translation id="8332188693563227489">Piekļuve vietnei <ph name="HOST_NAME" /> tika noraidīta</translation>
<translation id="834457929814110454">Ja apzinÄties droÅ¡Ä«bas risku, varat arÄ« <ph name="BEGIN_LINK" />apmeklÄ“t Å¡o vietni<ph name="END_LINK" />, pirms ir noņemtas kaitÄ«gÄs programmas.</translation>
@@ -801,11 +877,9 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="8483780878231876732">Lai izmantotu kartes no sava Google konta, pierakstieties pÄrlÅ«kÄ Chrome!</translation>
<translation id="8488350697529856933">Attiecas uz</translation>
<translation id="8498891568109133222">Vietne <ph name="HOST_NAME" /> pÄrÄk ilgi nereaģēja.</translation>
-<translation id="852346902619691059">Å is serveris nevarÄ“ja pierÄdÄ«t, ka tas ir domÄ“ns <ph name="DOMAIN" />; tÄ droÅ¡Ä«bas sertifikÄts nav uzticams jÅ«su ierÄ«ces operÄ“tÄjsistÄ“mÄ. Å Ä« problÄ“ma var rasties nepareizas konfigurÄcijas dēļ vai tÄdēļ, ka kÄds uzbrucÄ“js ir pÄrtvÄ“ris jÅ«su savienojumu. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairÄk<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Der. term. gads</translation>
<translation id="8543181531796978784">JÅ«s varat <ph name="BEGIN_ERROR_LINK" />ziņot par noteikÅ¡anas problÄ“mu<ph name="END_ERROR_LINK" /> vai, ja apzinÄties droÅ¡Ä«bas riskus, <ph name="BEGIN_LINK" />apmeklÄ“t Å¡o nedroÅ¡o vietni<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">TulkoÅ¡ana neizdevÄs, jo lapas valoda nav nosakÄma.</translation>
-<translation id="8559762987265718583">Nevar izveidot privÄtu savienojumu ar <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, jo jÅ«su ierÄ«ces datums un laiks (<ph name="DATE_AND_TIME" />) nav pareizs.</translation>
<translation id="8571890674111243710">Notiek lapas tulkošana uz <ph name="LANGUAGE" /> valodu...</translation>
<translation id="858637041960032120">Piev. tÄlr. nr.
</translation>
@@ -820,6 +894,7 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="8738058698779197622">Lai izveidotu droÅ¡u savienojumu, ir jÄiestata pareizs pulksteņa laiks. Tas ir nepiecieÅ¡ams, jo sertifikÄti, kurus vietnes izmanto, lai tiktu identificÄ“tas, ir derÄ«gi tikai noteiktos laika periodos. TÄ kÄ jÅ«su ierÄ«ces pulkstenis nav pareizi iestatÄ«ts, Chromium nevar verificÄ“t Å¡os sertifikÄtus.</translation>
<translation id="8740359287975076522">Nevarēja atrast <ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;DNS adresi&lt;/abbr&gt;. Notiek problēmas diagnosticēšana.</translation>
<translation id="8759274551635299824">Kartes derīguma termiņš ir beidzies</translation>
+<translation id="8761567432415473239">Google droÅ¡Äs pÄrlÅ«koÅ¡anas tehnoloÄ£ija nesen vietnÄ“ <ph name="SITE" /> <ph name="BEGIN_LINK" />atklÄja kaitÄ«gas programmas<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;Atcelt dzēšanas atsaukšanu</translation>
<translation id="8800988563907321413">Å eit tiks parÄdÄ«ti funkcijas TuvumÄ ieteikumi</translation>
<translation id="8820817407110198400">GrÄmatzÄ«mes</translation>
@@ -832,29 +907,30 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="8870413625673593573">Nesen aizvērtas</translation>
<translation id="8874824191258364635">Ievadiet derīgu kartes numuru</translation>
<translation id="8876793034577346603">NeizdevÄs parsÄ“t tÄ«kla konfigurÄciju.</translation>
-<translation id="8877192140621905067">PÄ“c apstiprinÄÅ¡anas kartes informÄcija tiks kopÄ«gota ar Å¡o vietni.</translation>
<translation id="8889402386540077796">NokrÄsa</translation>
<translation id="8891727572606052622">Nederīgs starpniekservera režīms.</translation>
<translation id="889901481107108152">Diemžēl Å¡is eksperiments nav pieejams jÅ«su platformÄ.</translation>
<translation id="8903921497873541725">TuvinÄt</translation>
<translation id="8931333241327730545">Vai vÄ“laties saglabÄt Å¡o karti savÄ Google kontÄ?</translation>
<translation id="8932102934695377596">NorÄdÄ«tais laiks ir pÄrÄk tÄlu pagÄtnÄ“</translation>
-<translation id="8954894007019320973">(turpin.)</translation>
<translation id="8971063699422889582">Servera sertifikÄtam ir beidzies derÄ«guma termiņš.</translation>
<translation id="8986494364107987395">AutomÄtiski sÅ«tÄ«t lietoÅ¡anas statistiku un avÄriju pÄrskatus uzņēmumam Google</translation>
-<translation id="8987927404178983737">MÄ“nesis</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Vietnē, kura tiks atvērta, ir kaitīgas programmas</translation>
+<translation id="8997023839087525404">Serveris uzrÄdÄ«ja sertifikÄtu, kas netika publiski atklÄts, izmantojot Certificate Transparency politiku. Å Ä« ir prasÄ«ba noteiktiem sertifikÄtiem, lai nodroÅ¡inÄtu to uzticamÄ«bu un aizsardzÄ«bu pret uzbrucÄ“jiem.</translation>
<translation id="9001074447101275817">Starpniekserveris <ph name="DOMAIN" /> pieprasa lietotÄjvÄrdu un paroli.</translation>
+<translation id="9005998258318286617">NeizdevÄs ielÄdÄ“t PDF dokumentu.</translation>
<translation id="901974403500617787">Atzīmes, kas attiecas uz visu sistēmu, var iestatīt tikai īpašnieks: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">JÄnorÄda kartes norÄ“Ä·inu adrese</translation>
<translation id="9020542370529661692">Å Ä« lapa ir tulkota <ph name="TARGET_LANGUAGE" /> valodÄ.</translation>
<translation id="9035022520814077154">Drošības kļūda</translation>
<translation id="9038649477754266430">Ieteikumu pakalpojuma izmantoÅ¡ana ÄtrÄkai lapu ielÄdei</translation>
<translation id="9039213469156557790">TurklÄt Å¡ajÄ lapÄ ir citi resursi, kas nav droÅ¡i. KamÄ“r Å¡ie resursi tiek pÄrsÅ«tÄ«ti, tos var aplÅ«kot citi, kÄ arÄ« uzbrucÄ“js var tos pÄrveidot, lai mainÄ«tu lapas uzvedÄ«bu.</translation>
-<translation id="9040185888511745258">UzbrucÄ“ji vietnÄ“ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, iespÄ“jams, mudinÄs jÅ«s uz tÄdu programmu instalÄ“Å¡anu, kuras traucÄ“ pÄrlÅ«koÅ¡anu (piemÄ“ram, mainot sÄkumlapu vai apmeklÄ“tajÄs vietnÄ“s rÄdot papildu reklÄmas).</translation>
+<translation id="9049981332609050619">JÅ«s centÄties piekļūt <ph name="DOMAIN" />, bet serveris piedÄvÄja nederÄ«gu sertifikÄtu.</translation>
<translation id="9050666287014529139">Ieejas frÄze</translation>
<translation id="9065203028668620118">Labot</translation>
<translation id="9068849894565669697">KrÄsas izvÄ“le</translation>
+<translation id="9069693763241529744">BloÄ·Ä“ja paplaÅ¡inÄjums</translation>
<translation id="9076283476770535406">Vietnē var būt pieaugušajiem paredzēts saturs</translation>
<translation id="9078964945751709336">NepiecieÅ¡ama plaÅ¡Äka informÄcija.</translation>
<translation id="9103872766612412690">VietnÄ“ <ph name="SITE" /> informÄcijas aizsargÄÅ¡anai parasti tiek izmantota Å¡ifrÄ“Å¡ana. Kad pÄrlÅ«kÄ Chromium tika mÄ“Ä£inÄts izveidot savienojumu ar vietni <ph name="SITE" />, Å¡oreiz tÄ nosÅ«tÄ«ja neparastus un nepareizus akreditÄcijas datus. IespÄ“jams, tas notika, jo uzbrucÄ“js mÄ“Ä£inÄja uzdoties par vietni <ph name="SITE" />, vai arÄ« Wi-Fi pierakstÄ«Å¡anÄs ekrÄns pÄrtrauca savienojumu. JÅ«su informÄcija joprojÄm ir droÅ¡Ä«bÄ, jo pÄrlÅ«ks Chromium pÄrtrauca savienojumu, pirms tika veikta jebkÄdu datu apmaiņa.</translation>
@@ -863,16 +939,21 @@ NÄkamreiz jums varÄ“tu noderÄ“t inkognito režīms (<ph name="SHORTCUT_KEY" />)
<translation id="9148507642005240123">&amp;Atsaukt labojumu</translation>
<translation id="9154194610265714752">AtjauninÄts</translation>
<translation id="9157595877708044936">Notiek uzstÄdÄ«Å¡ana...</translation>
+<translation id="9169664750068251925">VienmÄ“r bloÄ·Ä“t Å¡ajÄ vietnÄ“</translation>
<translation id="9170848237812810038">&amp;Atsaukt</translation>
<translation id="917450738466192189">Servera sertifikÄts ir nederÄ«gs.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}zero{<ph name="SHIPPING_OPTION_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> un vēl <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> izmanto neatbalstītu protokolu.</translation>
<translation id="9205078245616868884">JÅ«su dati ir Å¡ifrÄ“ti, izmantojot jÅ«su sinhronizÄcijas ieejas frÄzi. Lai sÄktu sinhronizÄciju, ievadiet ieejas frÄzi.</translation>
<translation id="9207861905230894330">Rakstu neizdevÄs pievienot.</translation>
+<translation id="9219103736887031265">Attēli</translation>
<translation id="933612690413056017">Nav interneta savienojuma</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">NOTĪRĪT VEIDLAPU</translation>
<translation id="939736085109172342">Jauna mape</translation>
<translation id="941721044073577244">Šķiet, ka jums nav atļaujas apmeklēt šo vietni</translation>
<translation id="969892804517981540">OficiÄlÄ UzbÅ«ve</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Nav}=1{1 vienums}zero{# vienumi}one{# vienums}other{# vienumi}}</translation>
<translation id="988159990683914416">AttÄ«stÄ«tÄja konstrukcija</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ml.xtb b/chromium/components/strings/components_strings_ml.xtb
index d88923ff138..fffe401c9f8 100644
--- a/chromium/components/strings/components_strings_ml.xtb
+++ b/chromium/components/strings/components_strings_ml.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">ഘടികാരദിശയിൽ‌ തിരികàµà´•àµà´•</translation>
<translation id="1038842779957582377">à´…à´œàµà´žà´¾à´¤ നാമം</translation>
<translation id="1050038467049342496">മറàµà´±àµ ആപàµà´ªàµà´•àµ¾ à´…à´Ÿà´¯àµâ€Œà´•àµà´•àµà´•</translation>
-<translation id="1053591932240354961">Google Chrome-നൠപàµà´°àµ‹à´¸à´¸àµà´¸àµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´•à´¾à´¤àµà´¤ രൂപമാറàµà´±à´‚ വരàµà´¤àµà´¤à´¿à´¯ à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ വെബàµà´¸àµˆà´±àµà´±àµ അയയàµâ€Œà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ <ph name="SITE" /> സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´².നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´• à´ªàµà´°à´¶àµâ€Œà´¨à´™àµà´™àµ¾ ആയതിനാൽ, à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;ചേർകàµà´•àµà´¨àµà´¨à´¤àµ പഴയപടിയാകàµà´•àµà´•</translation>
<translation id="10614374240317010">à´’à´°à´¿à´•àµà´•à´²àµà´‚ സംരകàµà´·à´¿à´šàµà´šà´¿à´²àµà´²</translation>
<translation id="106701514854093668">ഡെസàµâ€Œà´•àµâ€Œà´Ÿàµ‹à´ªàµà´ªàµ à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´•àµ¾</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">നയ കാഷെ ശരി</translation>
<translation id="113188000913989374"><ph name="SITE" /> സൈറàµà´±àµ പറയàµà´¨àµà´¨à´¤àµ:</translation>
<translation id="1132774398110320017">Chrome à´“à´Ÿàµà´Ÿàµ‹à´«à´¿àµ½ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾...</translation>
+<translation id="1150979032973867961">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´· സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† à´“à´ªàµà´ªà´±àµ‡à´±àµà´±à´¿à´‚ഗൠസിസàµâ€Œà´±àµà´±à´¤àµà´¤à´¿à´¨àµ പരിചയമിലàµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
+<translation id="1151972924205500581">പാസàµâ€à´µàµ‡à´¡àµ ആവശàµà´¯à´®à´¾à´£àµ</translation>
<translation id="1152921474424827756"><ph name="URL" />-à´¨àµà´±àµ† <ph name="BEGIN_LINK" />കാഷെ ചെയàµâ€Œà´¤ പകർപàµà´ªàµ<ph name="END_LINK" /> ആകàµâ€Œà´¸à´¸àµà´¸àµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> à´…à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿ കണകàµà´·àµ» à´…à´Ÿà´šàµà´šàµ.</translation>
<translation id="1161325031994447685">Wi-Fi-ലേകàµà´•àµ വീണàµà´Ÿàµà´‚ കണകàµà´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨àµ</translation>
+<translation id="1165039591588034296">പിശകàµ</translation>
<translation id="1175364870820465910">&amp;à´…à´šàµà´šà´Ÿà´¿à´•àµà´•àµ‚...</translation>
<translation id="1181037720776840403">നീകàµà´•à´‚ചെയàµà´¯àµ‚</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />à´¸àµà´°à´•àµà´·à´¯àµ† ബാധികàµà´•à´¾àµ» സാധàµà´¯à´¤à´¯àµà´³àµà´³ കാരàµà´¯à´™àµà´™à´³àµà´Ÿàµ† വിശദാംശങàµà´™àµ¾<ph name="END_WHITEPAPER_LINK" /> à´¸àµà´µà´¯à´®àµ‡à´µ Google-ൽ റിപàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨àµ. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">à´ˆ സൈറàµà´±à´¿àµ½ നിനàµà´¨àµà´‚ കൂടàµà´¤àµ½</translation>
<translation id="1206967143813997005">à´ªàµà´°à´¾à´°à´‚à´­ സിഗàµà´¨àµ‡à´šàµà´šàµ¼ ശരിയലàµà´²</translation>
<translation id="1209206284964581585">ഇപàµà´ªàµ‹à´´à´¤àµà´¤àµ‡à´¯àµâ€Œà´•àµà´•àµ മറയàµâ€Œà´•àµà´•àµà´•</translation>
+<translation id="121201262018556460">നിങàµà´™à´³àµâ€â€Œ <ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµâ€ à´Žà´¤àµà´¤à´¾à´¨àµâ€â€Œ à´¶àµà´°à´®à´¿à´šàµà´šàµ, പകàµà´·àµ† സെർവർ ഹാജരാകàµà´•à´¿à´¯ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿àµ½ ഒരൠദàµàµ¼à´¬à´²à´®à´¾à´¯ കീ ഉൾപàµà´ªàµ†à´Ÿàµà´¨àµà´¨àµ. ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµà´•àµ à´¸àµà´µà´•à´¾à´°àµà´¯ കീ നശിപàµà´ªà´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•à´¾à´‚, കൂടാതെ സെർവർ നിങàµà´™àµ¾ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š സെർവർ ആയിരികàµà´•à´¿à´²àµà´² (നിങàµà´™àµ¾ ആശയവിനിമയം നടതàµà´¤àµà´¨àµà´¨à´¤àµ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµà´®à´¾à´¯à´¿à´Ÿàµà´Ÿà´¾à´•à´¾à´‚).</translation>
<translation id="1219129156119358924">സിസàµâ€Œà´±àµà´±à´‚ à´¸àµà´°à´•àµà´·</translation>
<translation id="1227224963052638717">അറിയപàµà´ªàµ†à´Ÿà´¾à´¤àµà´¤ നയം.</translation>
<translation id="1227633850867390598">മൂലàµà´¯à´‚ മറയàµâ€Œà´•àµà´•àµà´•</translation>
<translation id="1228893227497259893">തെറàµà´±à´¾à´¯ à´Žà´¨àµà´±à´¿à´±àµà´±à´¿ à´à´¡à´¨àµà´±à´¿à´«à´¯àµ¼</translation>
<translation id="1232569758102978740">ശീരàµâ€à´·à´•à´®à´¿à´²àµà´²à´¾à´¤àµà´¤</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´šàµ)</translation>
<translation id="1263231323834454256">വായനാ ലിസàµà´±àµà´±àµ</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" />-നൠകàµà´¯à´¾à´ªàµâ€Œà´šàµà´šàµ¼ ചെയàµâ€Œà´¤ à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµ (ഇതàµà´µà´°àµ† à´…à´ªàµâ€Œà´²àµ‹à´¡àµà´šàµ†à´¯àµâ€Œà´¤à´¿à´Ÿàµà´Ÿàµ‹ അവഗണിചàµà´šà´¿à´Ÿàµà´Ÿàµ‹ ഇലàµà´²)</translation>
+<translation id="1281526147609854549"><ph name="ISSUER" /> ഇഷàµà´¯àµ‚ ചെയàµâ€Œà´¤à´¤àµ</translation>
+<translation id="1283919782143846010">അപകടകരമായ ഉളàµà´³à´Ÿà´•àµà´•à´‚ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="1285320974508926690">à´ˆ സൈറàµà´±àµ à´’à´°à´¿à´•àµà´•à´²àµà´‚ വിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ ചെയàµà´¯à´°àµà´¤àµ</translation>
<translation id="129553762522093515">സമീപകാലതàµà´¤àµ à´…à´Ÿà´šàµà´šà´µ</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />നിങàµà´™à´³àµà´Ÿàµ† à´•àµà´•àµà´•à´¿à´•àµ¾ മായàµâ€Œà´•àµà´•àµà´¨àµà´¨à´¤àµ പരീകàµà´·à´¿à´•àµà´•àµà´•<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">നിങàµà´™à´³àµà´Ÿàµ† ആകàµâ€Œà´±àµà´±à´¿à´µà´¿à´±àµà´±à´¿ ഇനിപàµà´ªà´±à´¯àµà´¨àµà´¨à´µà´¯àµâ€Œà´•àµà´•àµ <ph name="BEGIN_EMPHASIS" />à´¤àµà´Ÿàµ¼à´¨àµà´¨àµà´‚ ദൃശàµà´¯à´®à´¾à´¯àµ‡à´•àµà´•àµà´‚<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />നിങàµà´™àµ¾ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´¨àµà´¨ വെബàµâ€Œà´¸àµˆà´±àµà´±àµà´•àµ¾à´•àµà´•àµ
+ <ph name="LIST_ITEM" />നിങàµà´™à´³àµà´Ÿàµ† നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµà´Ÿàµà´°àµ‡à´±àµà´±à´±à´¿à´¨àµ
+ <ph name="LIST_ITEM" />നിങàµà´™à´³àµà´Ÿàµ† ഇനàµà´±àµ¼à´¨àµ†à´±àµà´±àµ സേവന ദാതാവിനàµ
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">എൻറോൾമെനàµà´±àµ ഡൊമെയàµàµ»:</translation>
<translation id="1340482604681802745">പികàµà´•à´ªàµà´ªàµ വിലാസം</translation>
<translation id="1344211575059133124">à´ˆ സൈറàµà´±àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾àµ» നിങàµà´™àµ¾à´•àµà´•àµ à´…à´¨àµà´®à´¤à´¿ ആവശàµà´¯à´®à´¾à´£àµ†à´¨àµà´¨àµ തോനàµà´¨àµà´¨àµà´¨àµ</translation>
<translation id="1344588688991793829">Chromium à´“à´Ÿàµà´Ÿàµ‹à´«à´¿àµ½ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾...</translation>
+<translation id="1348198688976932919">നിങàµà´™àµ¾ പോകàµà´¨àµà´¨ സൈറàµà´±à´¿àµ½ അപകടകരമായ ആപàµà´ªàµà´•àµ¾ ഉണàµà´Ÿàµ</translation>
<translation id="1374468813861204354">നിർദàµà´¦àµ‡à´¶à´™àµà´™àµ¾</translation>
<translation id="1375198122581997741">പതിപàµà´ªà´¿à´¨àµ† à´•àµà´±à´¿à´šàµà´šàµ</translation>
<translation id="1377321085342047638">കാർഡൠനമàµà´ªàµ¼</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ഡാറàµà´±à´¯àµŠà´¨àµà´¨àµà´‚ അയചàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´².</translation>
<translation id="1407135791313364759">à´Žà´²àµà´²à´¾à´‚ à´¤àµà´±à´•àµà´•àµà´•</translation>
<translation id="1413809658975081374">à´¸àµà´µà´•à´¾à´°àµà´¯ പിശകàµ</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" /> ലെ <ph name="ORGANIZATION" /> à´¨àµà´±àµ† à´µàµà´¯à´•àµà´¤à´¿à´¤àµà´µà´‚ <ph name="ISSUER" /> പരിശോധിചàµà´šàµ.</translation>
<translation id="1426410128494586442">അതെ</translation>
<translation id="1430915738399379752">à´…à´šàµà´šà´Ÿà´¿à´•àµà´•àµà´•</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ† ഒരൠപേജൠസനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨àµà´³àµà´³ <ph name="END_LINK" /> à´¶àµà´°à´®à´‚ തടഞàµà´žàµ.</translation>
-<translation id="1491663344921578213">വെബàµà´¸àµˆà´±àµà´±àµ, സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ പിനàµà´¨à´¿à´‚ഗൠഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ <ph name="SITE" /> സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´• à´ªàµà´°à´¶àµâ€Œà´¨à´™àµà´™à´³à´¾à´¯à´¤à´¿à´¨à´¾àµ½, à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> à´Žà´£àµà´£à´µàµà´‚}other{<ph name="PAYMENT_METHOD_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> à´Žà´£àµà´£à´µàµà´‚}}</translation>
<translation id="1506687042165942984">à´ˆ പേജിനàµà´±àµ† സംരകàµà´·à´¿à´šàµà´š (അതായതàµ. അതൠകാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿà´¤à´¾à´¯à´¿ അറിയികàµà´•àµà´¨àµà´¨àµ) പകർപàµà´ªàµ കാണികàµà´•àµà´•</translation>
<translation id="1517433312004943670">ഫോൺ നമàµà´ªàµ¼ ആവശàµà´¯à´®à´¾à´£àµ</translation>
<translation id="1519264250979466059">ബിൽഡൠതീയതി</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">à´ˆ ഫീചàµà´šàµ¼ ഉപയോഗികàµà´•à´¾àµ» JavaScript à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´•àµà´·à´®à´®à´¾à´•àµà´•à´¿à´¯à´¿à´°à´¿à´•àµà´•à´£à´‚.</translation>
<translation id="1555130319947370107">നീല</translation>
<translation id="1559528461873125649">à´…à´¤àµà´¤à´°à´¤àµà´¤à´¿à´²àµà´³àµà´³ ഫയലോ ഡയറകàµà´Ÿà´±à´¿à´¯àµ‹ ഇലàµà´²</translation>
-<translation id="1559572115229829303">&lt;p&gt;നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† തീയതിയàµà´‚ സമയവàµà´‚ (<ph name="DATE_AND_TIME" />) തെറàµà´±à´¾à´¯à´¤à´¿à´¨à´¾àµ½ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµ ഒരൠസàµà´µà´•à´¾à´°àµà´¯ കണകàµà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´².&lt;/p&gt;
-
- &lt;p&gt;&lt;strong&gt;à´•àµà´°à´®àµ€à´•à´°à´£&lt;/strong&gt; ആപàµà´ªà´¿à´¨àµà´±àµ† &lt;strong&gt;പൊതàµà´µà´¾à´¯à´µ&lt;/strong&gt; വിഭാഗതàµà´¤à´¿àµ½ നിനàµà´¨àµ തീയതിയàµà´‚ സമയവàµà´‚ à´•àµà´°à´®àµ€à´•à´°à´¿à´•àµà´•àµà´•.&lt;/p&gt;</translation>
<translation id="1583429793053364125">à´ˆ വെബàµâ€Œà´ªàµ‡à´œàµ à´ªàµà´°à´¦àµ¼à´¶à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´®àµà´ªàµ‹àµ¾ à´Žà´¨àµà´¤àµ‹ à´•àµà´´à´ªàµà´ªà´‚ സംഭവിചàµà´šàµ.</translation>
<translation id="1592005682883173041">à´ªàµà´°à´¾à´¦àµ‡à´¶à´¿à´• ഡാറàµà´± ആകàµâ€Œà´¸à´¸àµà´¸àµ</translation>
+<translation id="1594030484168838125">തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•</translation>
<translation id="161042844686301425">സിയാൻ</translation>
+<translation id="1620510694547887537">à´•àµà´¯à´¾à´®à´±</translation>
<translation id="1629803312968146339">Chrome à´ˆ കാർഡൠസംരകàµà´·à´¿à´•àµà´•à´£àµ‹?</translation>
<translation id="1639239467298939599">ലോഡàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨àµ</translation>
<translation id="1640180200866533862">ഉപയോകàµà´¤àµƒ നയങàµà´™àµ¾</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ കോൺഫിഗറേഷൻ അസാധàµà´µà´¾à´¯à´¤à´¿à´¨à´¾àµ½ ഇമàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµà´šàµ†à´¯àµà´¯à´¾àµ» à´•à´´à´¿à´žàµà´žà´¿à´²àµà´².</translation>
<translation id="1644574205037202324">à´šà´°à´¿à´¤àµà´°à´‚</translation>
<translation id="1645368109819982629">à´ªàµà´°àµ‡à´¾à´Ÿàµà´Ÿàµ‡à´¾à´•àµà´•àµ‡à´¾àµ¾ പിനàµà´¤àµà´£à´¯àµâ€Œà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²</translation>
+<translation id="1655462015569774233">{1,plural, =1{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ഇനàµà´¨à´²àµ† കാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ നിലവിൽ <ph name="CURRENT_DATE" /> à´Žà´¨àµà´¨àµ സജàµà´œà´®à´¾à´•àµà´•à´¿. അതൠശരിയാണോ? à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½, നിങàµà´™àµ¾ സിസàµà´±àµà´±à´¤àµà´¤à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ ശരിയാകàµà´•à´¿ à´ˆ പേജൠപàµà´¤àµà´•àµà´•àµà´•.}other{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; ഇതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ # ദിവസം à´®àµà´®àµà´ªàµ കാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ നിലവിൽ <ph name="CURRENT_DATE" /> à´Žà´¨àµà´¨àµ സജàµà´œà´®à´¾à´•àµà´•à´¿. അതൠശരിയാണോ? à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½, നിങàµà´™àµ¾ സിസàµà´±àµà´±à´¤àµà´¤à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ ശരിയാകàµà´•à´¿ à´ˆ പേജൠപàµà´¤àµà´•àµà´•àµà´•.}}</translation>
<translation id="1656489000284462475">പികàµà´•à´ªàµà´ªàµ</translation>
<translation id="1663943134801823270">കാർഡàµà´•à´³àµà´‚ വിലാസങàµà´™à´³àµà´‚ Chrome-ൽ നിനàµà´¨àµà´³àµà´³à´¤à´¾à´£àµ. നിങàµà´™àµ¾à´•àµà´•àµ à´…à´µ <ph name="BEGIN_LINK" />à´•àµà´°à´®àµ€à´•à´°à´£à´¤àµà´¤à´¿àµ½<ph name="END_LINK" /> മാനേജàµà´šàµ†à´¯àµà´¯à´¾à´‚.</translation>
<translation id="1676269943528358898">നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ പരിരകàµà´·à´¿à´•àµà´•à´¾àµ» സാധാരണയായി <ph name="SITE" />, എൻകàµà´°à´¿à´ªàµâ€Œà´·àµ» ഉപയോഗികàµà´•àµà´¨àµà´¨àµ. ഇപàµà´ªàµ‹àµ¾ <ph name="SITE" /> സൈറàµà´±à´¿à´²àµ‡à´•àµà´•àµ കണകàµâ€Œà´±àµà´±àµà´šàµ†à´¯àµà´¯à´¾àµ» Google Chrome à´¶àµà´°à´®à´¿à´šàµà´šà´ªàµà´ªàµ‹àµ¾, അസാധാരണമായതàµà´‚ തെറàµà´±à´¾à´¯à´¤àµà´®à´¾à´¯ à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ വെബàµâ€Œà´¸àµˆà´±àµà´±àµ തിരികെ അയചàµà´šàµ. ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿, <ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¾à´¯à´¿ ഭാവികàµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´•àµà´•àµà´®àµà´ªàµ‹à´´àµ‹ Wi-Fi സൈൻ ഇൻ à´¸àµâ€Œà´•àµà´°àµ€àµ», കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´®àµà´ªàµ‹à´´àµ‹ ആണൠഇങàµà´™à´¨àµ† സംഭവികàµà´•à´¾à´¨à´¿à´Ÿà´¯àµà´³àµà´³à´¤àµ. à´à´¤àµ†à´™àµà´•à´¿à´²àµà´‚ ഡാറàµà´± കൈമാറàµà´¨àµà´¨à´¤à´¿à´¨àµà´®àµà´®àµà´ªàµ Google Chrome കണകàµà´·àµ» അവസാനിപàµà´ªà´¿à´šàµà´šà´¤à´¿à´¨à´¾àµ½, നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ à´¤àµà´Ÿàµ¼à´¨àµà´¨àµà´‚ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿à´°à´¿à´•àµà´•àµà´‚.</translation>
-<translation id="168328519870909584"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ† ആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, ഫോടàµà´Ÿàµ‹à´•àµ¾, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ പോലàµà´³àµà´³à´µ) മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾à´¨àµ‹ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•à´¾à´¨àµ‹ ഉപകരണതàµà´¤à´¿àµ½ അപകടകരമായ ആപàµà´ªàµà´•àµ¾ ഇൻസàµà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚.</translation>
<translation id="168841957122794586">സെർവർ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿àµ½ ഒരൠദàµàµ¼à´¬à´²à´®à´¾à´¯ ഗൂഢഭാഷ കീ ഉൾപàµà´ªàµ†à´Ÿàµà´¨àµà´¨àµ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ഇനàµà´¨à´²àµ† à´®àµà´¤àµ½ സാധàµà´µà´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.}other{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ # ദിവസം à´®àµà´¤àµ½ സാധàµà´µà´¾à´¯à´¿à´°à´¿à´•àµà´•à´¿à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">à´ˆ സൈറàµà´±àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾àµ» നിങàµà´™àµ¾à´•àµà´•àµ <ph name="NAME" /> à´Žà´¨àµà´¨à´¯à´¾à´³à´¿àµ½ നിനàµà´¨àµà´³àµà´³ à´…à´¨àµà´®à´¤à´¿ ആവശàµà´¯à´®à´¾à´£àµ</translation>
<translation id="1721424275792716183">* ഫീൽഡൠആവശàµà´¯à´®à´¾à´£àµ</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">പേജൠപിനàµà´¨àµ€à´Ÿàµ ഡൗൺലോഡàµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="17513872634828108">à´“à´ªàµà´ªàµº ടാബàµà´•àµ¾</translation>
<translation id="1753706481035618306">പേജൠനമàµà´ªàµ¼</translation>
+<translation id="1763864636252898013">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´· സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† à´“à´ªàµà´ªà´±àµ‡à´±àµà´±à´¿à´‚ഗൠസിസàµâ€Œà´±àµà´±à´¤àµà´¤à´¿à´¨àµ പരിചയമിലàµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ ഡയഗണോസàµâ€Œà´±àµà´±à´¿à´•àµâ€Œà´¸àµ റൺ ചെയàµâ€Œà´¤àµà´¨àµ‹à´•àµà´•àµ‚<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">നിങàµà´™à´³àµà´Ÿàµ† സമനàµà´µà´¯ പാസàµâ€Œà´«àµà´°àµ‡à´¸àµ ദയവായി à´…à´ªàµâ€Œà´¡àµ‡à´±àµà´±àµ ചെയàµà´¯àµà´•.</translation>
<translation id="1787142507584202372">നിങàµà´™àµ¾ നിലവിൽ à´¤àµà´±à´¨àµà´¨à´¿à´Ÿàµà´Ÿàµà´³àµà´³ ടാബàµà´•àµ¾ ഇവിടെ ദൃശàµà´¯à´®à´¾à´•àµà´‚</translation>
+<translation id="1789575671122666129">പോപàµà´ªàµà´…à´ªàµà´ªàµà´•àµ¾</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">കാർഡൠഉടമയàµà´Ÿàµ† പേരàµ</translation>
-<translation id="1803678881841855883"><ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ <ph name="BEGIN_LINK" />മാൽവേർ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿<ph name="END_LINK" /> . സാധാരണ നിലയിൽ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯ വെബàµà´¸àµˆà´±àµà´±àµà´•à´³à´¿àµ½ ചിലപàµà´ªàµ‹àµ¾ മാൽവേർ ഉണàµà´Ÿà´¾à´¯àµ‡à´•àµà´•à´¾à´‚. അറിയപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ മാൽ‌വേർ വിതരണകàµà´•à´¾à´°à´¾à´¯ <ph name="SUBRESOURCE_HOST" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ നിനàµà´¨à´¾à´£àµ ദോഷകരമായ ഉളàµà´³à´Ÿà´•àµà´•à´‚ വരàµà´¨àµà´¨à´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440"><ph name="ADDED_TO_AUTOFILL_MONTH" />-നൠചേർതàµà´¤àµ</translation>
<translation id="1821930232296380041">à´…à´­àµà´¯àµ¼à´¤àµà´¥à´¨ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ à´…à´­àµà´¯àµ¼à´¤àµà´¥à´¨ പാരാമീറàµà´±à´±àµà´•àµ¾ അസാധàµà´µà´¾à´£àµ</translation>
<translation id="1826516787628120939">പരിശോധികàµà´•àµà´¨àµà´¨àµ</translation>
<translation id="1834321415901700177">à´ˆ സൈറàµà´±à´¿àµ½ ദോഷകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ à´…à´Ÿà´™àµà´™à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
+<translation id="1840414022444569775">à´ˆ കാർഡൠ‌നമàµà´ªàµ¼ à´®àµà´®àµà´ªàµ ഉപയോഗിചàµà´šà´¿à´Ÿàµà´Ÿàµà´£àµà´Ÿàµ</translation>
<translation id="1842969606798536927">പണമടയàµâ€Œà´•àµà´•àµà´•</translation>
<translation id="1871208020102129563">à´¸àµà´¥à´¿à´°à´®à´¾à´¯ à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സെർവറàµà´•àµ¾ ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സജàµà´œàµ€à´•à´°à´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ, ഒരൠ.pac à´¸àµâ€Œà´•àµà´°à´¿à´ªàµà´±àµà´±àµ URL ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´²àµà´².</translation>
<translation id="1871284979644508959">നിർബനàµà´§à´®à´¾à´¯àµà´‚ പൂരിപàµà´ªà´¿à´•àµà´•à´£à´‚</translation>
<translation id="187918866476621466">ആരംഭ പേജàµà´•àµ¾ à´¤àµà´±à´•àµà´•àµà´•</translation>
<translation id="1883255238294161206">ലിസàµà´±àµà´±àµ à´šàµà´°àµà´•àµà´•àµà´•</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> à´Žà´£àµà´£à´µàµà´‚}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> à´Žà´£àµà´£à´µàµà´‚}}</translation>
<translation id="1898423065542865115">ഫിൽടàµà´Ÿàµ¼ ചെയàµà´¯àµà´¨àµà´¨àµ</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠസൈറàµà´±àµ}other{# സൈറàµà´±àµà´•àµ¾}}</translation>
<translation id="194030505837763158"><ph name="LINK" />-ലേകàµà´•àµ പോകàµà´•</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´•àµ¾</translation>
<translation id="1973335181906896915">സീരിയലൈസേഷൻ പിശകàµ</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701"> <ph name="POLICY_NAME" /> à´Žà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ മറികടനàµà´¨à´¤à´¿à´¨à´¾àµ½ ഇതൠഅവഗണിചàµà´šàµ.</translation>
<translation id="2138201775715568214">വിളിപàµà´ªà´¾à´Ÿà´°à´¿à´•àµ†à´¯àµà´³àµà´³ ഫിസികàµà´•àµ½ വെബൠപേജàµà´•àµ¾ തിരയàµà´¨àµà´¨àµ</translation>
<translation id="213826338245044447">മൊബൈൽ à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´•àµ¾</translation>
-<translation id="2148716181193084225">ഇനàµà´¨àµ</translation>
+<translation id="2147827593068025794">പശàµà´šà´¾à´¤àµà´¤à´²à´‚ സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´•àµà´•àµ½</translation>
<translation id="2154054054215849342">നിങàµà´™à´³àµà´Ÿàµ† ഡൊമെയàµâ€Œà´¨à´¿à´¨àµ വേണàµà´Ÿà´¿ സമനàµà´µà´¯à´‚ ലഭàµà´¯à´®à´²àµà´²</translation>
<translation id="2154484045852737596">കാർഡൠഎഡിറàµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="2166049586286450108">പൂർണàµà´£à´®à´¾à´¯ à´…à´¡àµâ€Œà´®à´¿àµ» ആകàµâ€Œà´¸à´¸àµà´¸àµ</translation>
<translation id="2166378884831602661">à´ˆ സൈറàµà´±à´¿à´¨àµ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯ കണകàµà´·àµ» നൽകാനാകിലàµà´²</translation>
<translation id="2181821976797666341">നയങàµà´™àµ¾</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{ഒരൠവിലാസം}other{# വിലാസങàµà´™àµ¾}}</translation>
+<translation id="2187317261103489799">à´•à´£àµà´Ÿàµ†à´¤àµà´¤àµà´• (ഡിഫോൾടàµà´Ÿàµ)</translation>
<translation id="2202020181578195191">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ ശരിയായ വർഷം നലàµâ€à´•àµà´•</translation>
<translation id="2212735316055980242">നയം à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿à´¯à´¿à´²àµà´²</translation>
<translation id="2213606439339815911">എൻടàµà´°à´¿à´•àµ¾ ലഭàµà´¯à´®à´¾à´•àµà´•àµà´¨àµà´¨àµ...</translation>
+<translation id="2218879909401188352">നിലവിൽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµà´³àµà´³ à´…à´•àµà´°à´®à´¿à´•àµ¾à´•àµà´•àµ നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണം കേടàµà´µà´°àµà´¤àµà´¤àµà´¨àµà´¨ ആപàµà´ªàµà´•àµ¾ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¾à´¨àµ‹ മൊബൈൽ ബിലàµà´²à´¿à´²àµ‡à´•àµà´•àµ നിങàµà´™à´³à´±à´¿à´¯à´¾à´¤àµ† നിരകàµà´•àµà´•àµ¾ ചേർകàµà´•à´¾à´¨àµ‹ നിങàµà´™à´³àµà´Ÿàµ† à´µàµà´¯à´•àµà´¤à´¿à´—à´¤ വിവരങàµà´™àµ¾ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾à´¨àµ‹ à´•à´´à´¿à´¯àµà´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />ഡയഗണോസàµâ€Œà´±àµà´±à´¿à´•àµâ€Œà´¸àµ ആപàµà´ªàµ<ph name="END_LINK" /> ഉപയോഗിചàµà´šàµ കണകഷൻ à´ªàµà´°à´¶àµâ€Œà´¨à´‚ പരിഹരികàµà´•àµà´•</translation>
<translation id="2239100178324503013">ഇപàµà´ªàµ‹àµ¾ അയയàµâ€Œà´•àµà´•àµà´•</translation>
<translation id="225207911366869382">à´ˆ നയതàµà´¤à´¿à´¨à´¾à´¯à´¿ à´ˆ മൂലàµà´¯à´¤àµà´¤àµ† ഒഴിവാകàµà´•à´¿.</translation>
<translation id="2262243747453050782">HTTP പിശകàµ</translation>
+<translation id="2270484714375784793">ഫോൺ നമàµà´ªàµ¼</translation>
<translation id="2282872951544483773">ലഭàµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤ പരീകàµà´·à´£à´™àµà´™àµ¾</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> ഇനം}other{<ph name="ITEM_COUNT" /> ഇനങàµà´™àµ¾}}</translation>
<translation id="2292556288342944218">നിങàµà´™à´³àµà´Ÿàµ† ഇനàµà´±àµ¼à´¨àµ†à´±àµà´±àµ ആകàµâ€Œà´¸à´¸àµà´¸àµ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="230155334948463882">à´ªàµà´¤à´¿à´¯ കാർഡാണോ?</translation>
-<translation id="2305919008529760154">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ à´µàµà´¯à´¾à´œà´®à´¾à´¯à´¿ നൽകിയതായിരികàµà´•à´¾à´‚. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨àµ ഒരൠഉപയോകàµà´¤àµƒà´¨à´¾à´®à´µàµà´‚ പാസàµâ€Œà´µàµ‡à´¡àµà´‚ വേണം.</translation>
-<translation id="2318774815570432836">വെബàµà´¸àµˆà´±àµà´±àµ HSTS ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•àµ ഇപàµà´ªàµ‹àµ¾ <ph name="SITE" /> സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´• à´ªàµà´°à´¶àµâ€Œà´¨à´™àµà´™à´³à´¾à´¯à´¤à´¿à´¨à´¾àµ½ à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">à´•àµà´°à´®àµ€à´•à´°à´£à´‚ നിയനàµà´¤àµà´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ നിങàµà´™à´³àµà´Ÿàµ† à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±à´±à´¾à´£àµ</translation>
<translation id="2354001756790975382">മറàµà´±àµ à´¬àµà´•àµâ€Œà´®à´¾à´°àµâ€à´•àµà´•àµà´•à´³àµâ€</translation>
+<translation id="2354430244986887761">Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ <ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ <ph name="BEGIN_LINK" />ദോഷകരമായ ആപàµà´ªàµà´•àµ¾ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">നിങàµà´™àµ¾ à´ˆ സൈറàµà´±à´¿àµ½ തിരയàµà´¨àµà´¨ à´šà´¿à´¤àµà´°à´™àµà´™àµ¾ കാണാനàµà´‚ അവയിൽ മാറàµà´±à´‚ വരàµà´¤àµà´¤à´¿ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾à´¨àµà´‚ à´…à´•àµà´°à´®à´•à´¾à´°à´¿à´•àµ¾à´•àµà´•àµ à´•à´´à´¿à´žàµà´žàµ‡à´•àµà´•à´¾à´‚.</translation>
+<translation id="2356070529366658676">ചോദികàµà´•àµà´•</translation>
+<translation id="2359629602545592467">à´’à´¨àµà´¨à´¿à´²à´§à´¿à´•à´‚</translation>
<translation id="2359808026110333948">à´¤àµà´Ÿà´°àµ‚</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" />-നൠകàµà´¯à´¾à´ªàµâ€Œà´šàµà´šàµ¼ ചെയàµâ€Œà´¤ à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµ à´…à´ªàµâ€Œà´²àµ‹à´¡àµà´šàµ†à´¯àµâ€Œà´¤à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²</translation>
<translation id="2367567093518048410">നില</translation>
-<translation id="2371153335857947666">{1,plural, =1{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ഇനàµà´¨à´²àµ† കാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ നിലവിൽ <ph name="CURRENT_DATE" /> à´Žà´¨àµà´¨àµ സജàµà´œà´®à´¾à´•àµà´•à´¿. അതൠശരിയാണോ? à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½, നിങàµà´™àµ¾ സിസàµà´±àµà´±à´¤àµà´¤à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ ശരിയാകàµà´•à´¿ à´ˆ പേജൠപàµà´¤àµà´•àµà´•àµà´•. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.}other{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; ഇതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ # ദിവസം à´®àµà´®àµà´ªàµ കാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ നിലവിൽ <ph name="CURRENT_DATE" /> à´Žà´¨àµà´¨àµ സജàµà´œà´®à´¾à´•àµà´•à´¿. അതൠശരിയാണോ? à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½, നിങàµà´™àµ¾ സിസàµà´±àµà´±à´¤àµà´¤à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ ശരിയാകàµà´•à´¿ à´ˆ പേജൠപàµà´¤àµà´•àµà´•àµà´•. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">UI ഇതരമാർഗങàµà´™à´³àµŠà´¨àµà´¨àµà´‚ ലഭàµà´¯à´®à´²àµà´²</translation>
<translation id="2384307209577226199">à´Žà´¨àµà´±à´°àµâ€à´ªàµà´°àµˆà´¸àµ ഡിഫോൾടàµà´Ÿàµ</translation>
<translation id="2386255080630008482">സെരàµâ€à´µà´±à´¿à´¨àµâ€à´±àµ† സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ അസാധàµà´µà´¾à´•àµà´•à´¿.</translation>
<translation id="2392959068659972793">മൂലàµà´¯à´®àµŠà´¨àµà´¨àµà´‚ സജàµà´œà´®à´¾à´•àµà´•à´¾à´¤àµà´¤ നയങàµà´™àµ¾ കാണികàµà´•àµà´•</translation>
<translation id="239429038616798445">à´ˆ à´·à´¿à´ªàµà´ªà´¿à´‚ഗൠരീതി ലഭàµà´¯à´®à´²àµà´². മറàµà´±àµŠà´°àµ രീതി പരീകàµà´·à´¿à´•àµà´•àµà´•.</translation>
<translation id="2396249848217231973">&amp;ഇലàµà´²à´¾à´¤à´¾à´•àµà´•àµ½ പഴയപടിയാകàµà´•àµà´•</translation>
-<translation id="2460160116472764928"><ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ <ph name="BEGIN_LINK" />മാൽവേർ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿<ph name="END_LINK" />. സാധാരണ നിലയിൽ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯ വെബàµà´¸àµˆà´±àµà´±àµà´•à´³à´¿àµ½ ചിലപàµà´ªàµ‹àµ¾ മാൽവേർ ഉണàµà´Ÿà´¾à´¯à´¿à´°à´¿à´•àµà´•à´¾à´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; സെർവറിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ റദàµà´¦à´¾à´•àµà´•à´¿à´¯à´¿à´°à´¿à´•àµà´•à´¾à´‚. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
<translation id="2463739503403862330">പൂരിപàµà´ªà´¿à´•àµà´•àµà´•</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ ഡയഗണോസàµâ€Œà´±àµà´±à´¿à´•àµâ€Œà´¸àµ റൺ ചെയàµà´¯àµà´¨àµà´¨àµ<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">തിരയൽ URL അസാധàµà´µà´¾à´£àµ.</translation>
+<translation id="2482878487686419369">വിജàµà´žà´¾à´ªà´¨à´™àµà´™à´³àµâ€â€Œ</translation>
<translation id="2491120439723279231">സെരàµâ€à´µà´±à´¿à´¨àµâ€à´±àµ† സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´²àµâ€ പിശകàµà´•à´³àµâ€ à´…à´Ÿà´™àµà´™à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ.</translation>
<translation id="2495083838625180221">JSON പാഴàµâ€Œà´¸àµ¼</translation>
<translation id="2495093607237746763">പരിശോധിചàµà´šàµ†à´™àµà´•à´¿àµ½, വേഗതàµà´¤à´¿àµ½ ഫോം പൂരിപàµà´ªà´¿à´•àµà´•à´¾àµ» Chromium à´ˆ ഉപകരണതàµà´¤à´¿àµ½ നിങàµà´™à´³àµà´Ÿàµ† കാർഡിനàµà´±àµ† ഒരൠപകർപàµà´ªàµ സൂകàµà´·à´¿à´•àµà´•àµà´‚.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">പിനàµà´¨à´¿à´²àµ‡à´•àµà´•àµ പോകàµà´•</translation>
<translation id="2515629240566999685">നിങàµà´™à´³àµà´Ÿàµ† à´à´°à´¿à´¯à´¯à´¿à´²àµ† സിഗàµâ€Œà´¨àµ½ പരിശോധികàµà´•àµà´¨àµà´¨àµ</translation>
<translation id="2516305470678292029">UI ഇതരമാർഗങàµà´™àµ¾</translation>
+<translation id="2539524384386349900">à´•à´£àµà´Ÿàµ†à´¤àµà´¤àµà´•</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" />, അസാധàµà´µà´¾à´¯ ഒരൠപàµà´°à´¤à´¿à´•à´°à´£à´‚ അയചàµà´šàµ.</translation>
-<translation id="2552545117464357659">à´à´±àµà´±à´µàµà´‚ à´ªàµà´¤à´¿à´¯</translation>
<translation id="2556876185419854533">&amp;à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ പഴയപടിയാകàµà´•àµà´•</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> à´Žà´¨àµà´¨à´¯à´¾à´³àµà´Ÿàµ† ലേഖനം. ഇതàµà´‚ മറàµà´±àµ <ph name="OTHER_ARTICLE_COUNT" /> ലേഖനങàµà´™à´³àµà´‚ വായികàµà´•àµà´•.</translation>
<translation id="2587841377698384444">ഡയറകàµâ€Œà´Ÿà´±à´¿ API à´à´¡à´¿:</translation>
<translation id="2597378329261239068">à´ˆ à´ªàµà´°à´®à´¾à´£à´‚ പാസàµâ€Œà´µàµ‡à´¡àµ പരിരകàµà´·à´¿à´¤à´®à´¾à´£àµ. ദയവായി ഒരൠപാസàµâ€Œà´µàµ‡à´¡àµ നലàµâ€â€Œà´•àµà´•.</translation>
<translation id="2609632851001447353">വേരിയേഷനàµà´•àµ¾</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠആപàµà´ªàµ ($1)}=2{2 ആപàµâ€Œà´¸àµ ($1, $2)}other{# ആപàµâ€Œà´¸àµ ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">നിങàµà´™à´³àµà´Ÿàµ† à´•àµà´²àµ‹à´•àµà´•àµ വളരെ à´®àµà´®àµà´ªà´¿à´²à´¾à´£àµ</translation>
<translation id="2639739919103226564">നില:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ഫയലിലേകàµà´•àµà´³àµà´³ ആകàµâ€Œà´¸à´¸àµà´¸àµ നിരസിചàµà´šàµ</translation>
<translation id="2653659639078652383">സമരàµâ€à´ªàµà´ªà´¿à´•àµà´•àµ‚</translation>
<translation id="2666117266261740852">മറàµà´±àµ ടാബàµà´•à´³àµ‹ ആപàµâ€Œà´¸àµà´•à´³àµ‹ à´…à´Ÿà´¯àµâ€Œà´•àµà´•àµà´•</translation>
+<translation id="2670429602441959756">à´ˆ പേജിൽ VR-നൠഅനàµà´¯àµ‹à´œàµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤ ഫീചàµà´šà´±àµà´•àµ¾ à´…à´Ÿà´™àµà´™à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ. à´ªàµà´±à´¤àµà´¤àµà´•à´Ÿà´•àµà´•àµà´¨àµà´¨àµ...</translation>
<translation id="2674170444375937751">നിങàµà´™à´³àµà´Ÿàµ† à´šà´°à´¿à´¤àµà´°à´¤àµà´¤à´¿à´²àµâ€ നിനàµà´¨àµà´‚ à´ˆ പേജàµà´•à´³àµâ€ മായàµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ നിങàµà´™à´³àµâ€ താലàµà´ªà´°àµà´¯à´®àµà´£àµà´Ÿàµ‹?</translation>
<translation id="2677748264148917807">ഉപേകàµà´·à´¿à´•àµà´•àµà´•</translation>
-<translation id="269990154133806163">സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ à´¸àµà´¤à´¾à´°àµà´¯à´¤à´¾ നയം ഉപയോഗിചàµà´šàµ സെർവർ, à´Žà´²àµà´²à´¾à´µàµ¼à´•àµà´•àµà´®à´¾à´¯à´¿ വെളàµà´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¿à´¯à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²à´¾à´¤àµà´¤ ഒരൠസർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ലഭàµà´¯à´®à´¾à´•àµà´•à´¿. à´šà´¿à´² സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµà´•àµ¾ വിശàµà´µà´¾à´¸à´¯àµ‹à´—àµà´¯à´®à´¾à´£àµ†à´¨àµà´¨àµà´‚ à´…à´•àµà´°à´®à´•à´¾à´°à´¿à´•à´³à´¿àµ½ നിനàµà´¨àµà´‚ പരിരകàµà´·à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¾à´£àµ†à´¨àµà´¨àµà´‚ ഉറപàµà´ªà´¾à´•àµà´•à´¾àµ» അവയàµâ€Œà´•àµà´•àµ ഇതൠആവശàµà´¯à´®à´¾à´£àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">വായനാ ലിസàµà´±àµà´±àµ</translation>
<translation id="2704283930420550640">മൂലàµà´¯à´‚ ഫോർമാറàµà´±àµà´®à´¾à´¯à´¿ പൊരàµà´¤àµà´¤à´ªàµà´ªàµ†à´Ÿàµà´¨àµà´¨à´¿à´²àµà´².</translation>
<translation id="2704951214193499422">Chromium-à´¤àµà´¤à´¿à´¨àµ ഇപàµà´ªàµ‹àµ¾ നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠസàµà´¥à´¿à´°àµ€à´•à´°à´¿à´•àµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´². പിനàµà´¨àµ€à´Ÿàµ വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´•àµà´•àµà´•.</translation>
<translation id="2705137772291741111">à´ˆ സൈറàµà´±à´¿à´¨àµà´±àµ† സംരകàµà´·à´¿à´šàµà´š (കാഷെ ചെയàµâ€Œà´¤) പതിപàµà´ªàµ വായികàµà´•à´¾à´¨à´¾à´•à´¾à´¤àµà´¤à´¤à´¾à´£àµ.</translation>
<translation id="2709516037105925701">à´“à´Ÿàµà´Ÿàµ‹à´«à´¿à´²àµâ€</translation>
-<translation id="2712118517637785082">നിങàµà´™àµ¾â€Œ <ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¿àµ½â€Œ à´Žà´¤àµà´¤à´¾à´¨àµâ€â€Œ à´¶àµà´°à´®à´¿à´šàµà´šàµ, പകàµà´·àµ‡ സെർവർ‌ നൽകിയ സർ‌ടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† അതിനàµà´±àµ† ഇഷàµà´¯àµ‚വർ റദàµà´¦à´¾à´•àµà´•à´¿. സെർവർ നൽ‌കിയ à´¸àµà´°à´•àµà´·à´¾ à´•àµà´°àµ†à´¡à´¨àµâ€â€Œà´·àµà´¯à´²àµà´•àµ¾ തികചàµà´šàµà´‚ വിശàµà´µà´¾â€à´¸à´¯àµ‹à´—àµà´¯à´®à´²àµà´² à´Žà´¨àµà´¨à´¾à´£àµ ഇതിനരàµâ€â€Œà´¤àµà´¥à´‚. നിങàµà´™àµ¾ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµà´®à´¾à´¯à´¿à´Ÿàµà´Ÿà´¾à´•à´¾à´‚ ആശയവിനിമയം നടതàµà´¤àµà´¨àµà´¨à´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">à´…à´¨àµà´®à´¤à´¿ ചോദികàµà´•àµà´•</translation>
<translation id="2713444072780614174">വെളàµà´³</translation>
<translation id="2720342946869265578">സമീപമàµà´³àµà´³à´µ</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ഉപകരണ റെകàµà´•àµ‹àµ¼à´¡àµ കാണàµà´¨àµà´¨à´¿à´²àµà´²</translation>
<translation id="2784949926578158345">കണകàµà´·à´¨àµâ€ à´ªàµà´¨à´ƒà´¸à´œàµà´œà´®à´¾à´•àµà´•à´¿à´¯à´¤à´¾à´£àµ.</translation>
<translation id="2794233252405721443">സൈറàµà´±àµ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
+<translation id="2799020568854403057">നിങàµà´™àµ¾ പോകàµà´¨àµà´¨ സൈറàµà´±à´¿àµ½ ദോഷകരമായ ആപàµà´ªàµà´•à´³àµà´£àµà´Ÿàµ</translation>
+<translation id="2803306138276472711"><ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ <ph name="BEGIN_LINK" />മാൽവെയർ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿<ph name="END_LINK" />. സാധാരണ നിലയിൽ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯ വെബàµà´¸àµˆà´±àµà´±àµà´•à´³à´¿àµ½ ചിലപàµà´ªàµ‹àµ¾ മാൽവെയർ ഉണàµà´Ÿà´¾à´¯àµ‡à´•àµà´•à´¾à´‚.</translation>
<translation id="2824775600643448204">വിലാസവàµà´‚ തിരയൽ ബാറàµà´‚</translation>
<translation id="2826760142808435982"><ph name="CIPHER" /> ഉപയോഗിചàµà´šàµ കണകàµà´·àµ» എൻകàµà´°à´¿à´ªàµâ€Œà´±àµà´±àµà´šàµ†à´¯àµâ€Œà´¤àµ à´ªàµà´°à´¾à´®à´¾à´£àµ€à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ, à´’à´ªàµà´ªà´‚ à´ªàµà´°à´§à´¾à´¨ à´Žà´•àµâ€Œà´¸àµ‡à´žàµà´šàµ മെകàµà´•à´¾à´¨à´¿à´¸à´®à´¾à´¯à´¿ <ph name="KX" /> ഉപയോഗികàµà´•àµà´¨àµà´¨àµ.</translation>
<translation id="2835170189407361413">ഫോം മായàµâ€Œà´•àµà´•àµà´•</translation>
+<translation id="2856444702002559011"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ നിനàµà´¨àµ നിങàµà´™à´³àµà´Ÿàµ† വിവരം മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾àµ» à´…à´•àµà´°à´®à´¿à´•àµ¾ à´¶àµà´°à´®à´¿à´•àµà´•àµà´¨àµà´¨àµà´£àµà´Ÿà´¾à´µà´¾à´‚ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾). <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">റീലോഡàµà´šàµ†à´¯àµà´¯à´°àµà´¤àµ</translation>
<translation id="2900469785430194048">à´ˆ വെബàµâ€Œà´ªàµ‡à´œàµ à´ªàµà´°à´¦àµ¼à´¶à´¿à´ªàµà´ªà´¿à´•àµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¿à´Ÿà´¯à´¿àµ½ Google Chrome-à´¨àµà´±àµ† മെമàµà´®à´±à´¿ നിറഞàµà´žàµ.</translation>
<translation id="2909946352844186028">ഒരൠനെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ മാറàµà´±à´‚ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿.</translation>
<translation id="2916038427272391327">മറàµà´±àµ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ à´…à´Ÿà´¯àµâ€Œà´•àµà´•àµà´•</translation>
<translation id="2922350208395188000">സെരàµâ€à´µà´±à´¿à´¨àµâ€à´±àµ† സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ പരിശോധികàµà´•à´¾à´¨àµâ€ കഴിയിലàµà´².</translation>
<translation id="2928905813689894207">ബിലàµà´²à´¿à´‚ഗൠവിലാസം</translation>
+<translation id="2941952326391522266">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; <ph name="DOMAIN2" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ നിനàµà´¨àµà´³àµà´³à´¤à´¾à´£àµ അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
<translation id="2948083400971632585">കണകàµà´·à´¨à´¾à´¯à´¿ കോൺഫിഗർ ചെയàµâ€Œà´¤ à´à´¤àµŠà´°àµ à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿à´•à´³àµà´‚ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾ പേജിൽ നിനàµà´¨àµ നിങàµà´™àµ¾à´•àµà´•àµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´°à´¹à´¿à´¤à´®à´¾à´•àµà´•à´¾à´¨à´¾à´•àµà´‚.</translation>
<translation id="2955913368246107853">ഫൈനàµâ€à´¡àµ ബാരàµâ€ à´…à´Ÿà´¯àµà´•àµà´•àµà´•</translation>
<translation id="2958431318199492670">നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ കോൺഫിഗറേഷൻ ONC à´¸àµà´±àµà´±à´¾àµ»à´¡àµ‡àµ¼à´¡à´¿à´¨àµ à´…à´¨àµà´¸àµƒà´¤à´®à´¾à´¯à´¿ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´². കോൺഫിഗറേഷൻ ഭാഗങàµà´™àµ¾ ഇമàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµà´šàµ†à´¯àµâ€Œà´¤àµ‡à´•àµà´•à´¿à´²àµà´².</translation>
-<translation id="29611076221683977"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ† നിലവിലàµà´³àµà´³ à´…à´•àµà´°à´®à´•à´¾à´°à´¿à´•àµ¾ നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•à´¾à´¨àµ‹ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾à´¨àµ‹ ഇടയàµà´³àµà´³ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, ഫോടàµà´Ÿàµ‹à´•àµ¾, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ à´®àµà´¤à´²à´¾à´¯à´µ) അപകടകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ Mac-ൽ ഇൻസàµâ€Œà´±àµà´±à´¾à´³àµà´šàµ†à´¯àµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚.</translation>
<translation id="2966678944701946121">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ തീയതി: <ph name="EXPIRATION_DATE_ABBR" />, <ph name="ADDED_TO_AUTOFILL_MONTH" />-നൠചേർതàµà´¤àµ</translation>
<translation id="2969319727213777354">ഒരൠസàµà´°à´•àµà´·à´¿à´¤ കണകàµà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ, നിങàµà´™à´³àµà´Ÿàµ† à´•àµà´²àµ‹à´•àµà´•àµ ശരിയായി സജàµà´œàµ€à´•à´°à´¿à´•àµà´•àµ‡à´£àµà´Ÿà´¤àµà´£àµà´Ÿàµ. വെബàµâ€Œà´¸àµˆà´±àµà´±àµà´•àµ¾ à´¸àµà´µà´¯à´‚ തിരിചàµà´šà´±à´¿à´¯àµà´¨àµà´¨à´¤à´¿à´¨àµ ഉപയോഗികàµà´•àµà´¨àµà´¨ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµà´•àµ¾, നിർദàµà´¦à´¿à´·àµâ€Œà´Ÿ സമയ പരിധിയിൽ മാതàµà´°à´‚ സാധàµà´¤à´¯àµà´³àµà´³à´¤à´¿à´¨à´¾à´²à´¾à´£à´¿à´¤àµ. നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ തെറàµà´±à´¾à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½, Google Chrome-നൠഈ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµà´•àµ¾ പരിശോധിചàµà´šàµà´±à´ªàµà´ªà´¿à´•àµà´•à´¾à´¨à´¾à´µà´¿à´²àµà´².</translation>
<translation id="2972581237482394796">&amp;വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">ശരിയായ വിലാസം നലàµâ€à´•àµà´•</translation>
<translation id="2986368408720340940">à´ˆ പികàµà´•à´ªàµà´ªàµ രീതി ലഭàµà´¯à´®à´²àµà´². മറàµà´±àµŠà´°àµ രീതി പരീകàµà´·à´¿à´•àµà´•àµà´•.</translation>
<translation id="2991174974383378012">വെബàµâ€Œà´¸àµˆà´±àµà´±àµà´•à´³àµà´®à´¾à´¯à´¿ പങàµà´•à´¿à´Ÿàµà´¨àµà´¨àµ</translation>
+<translation id="2991571918955627853">വെബàµâ€Œà´¸àµˆà´±àµà´±àµ HSTS ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•àµ ഇപàµà´ªàµ‹àµ¾ <ph name="SITE" /> സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´• à´ªàµà´°à´¶àµâ€Œà´¨à´™àµà´™à´³à´¾à´¯à´¤à´¿à´¨à´¾àµ½ à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚.</translation>
<translation id="3005723025932146533">സംരകàµà´·à´¿à´šàµà´š പകർപàµà´ªàµ കാണികàµà´•àµà´•</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" />-à´¨àµà´±àµ† CVC നൽകàµà´•. à´¸àµà´¥à´¿à´°àµ€à´•à´°à´¿à´šàµà´šàµ à´•à´´à´¿à´žàµà´žà´¾àµ½, നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠവിശദാംശങàµà´™àµ¾ à´ˆ സൈറàµà´±àµà´®à´¾à´¯à´¿ പങàµà´•à´¿à´Ÿàµà´‚.</translation>
<translation id="3010559122411665027">ലിസàµà´±àµà´±àµ എൻടàµà´°à´¿ "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">à´¸àµà´µà´¯à´®àµ‡à´µ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="3024663005179499861">തെറàµà´±à´¾à´¯ നയ തരം</translation>
<translation id="3032412215588512954">à´ˆ സൈറàµà´±àµ റീലോഡàµà´šàµ†à´¯àµà´¯à´£àµ‹?</translation>
<translation id="3037605927509011580">à´•à´·àµà´Ÿà´‚!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´š ഉപകരണങàµà´™à´³à´¿àµ½ ഒരൠഇനമെങàµà´•à´¿à´²àµà´‚}=1{ഒരൠഇനം (à´’à´ªàµà´ªà´‚ സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´š ഉപകരണങàµà´™à´³à´¿àµ½ അതിൽ കൂടàµà´¤à´²àµà´‚)}other{# ഇനങàµà´™àµ¾ (à´’à´ªàµà´ªà´‚ സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´š ഉപകരണങàµà´™à´³à´¿àµ½ അതിൽ കൂടàµà´¤à´²àµà´‚)}}</translation>
<translation id="3041612393474885105">സരàµâ€â€Œà´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ വിവരങàµà´™à´³àµâ€â€Œ</translation>
<translation id="3063697135517575841">Chrome-നൠഇപàµà´ªàµ‹àµ¾ നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠസàµà´¥à´¿à´°àµ€à´•à´°à´¿à´•àµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´². പിനàµà´¨àµ€à´Ÿàµ വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´•àµà´•àµà´•.</translation>
<translation id="3064966200440839136">ഒരൠഎകàµâ€Œà´¸àµâ€Œà´±àµà´±àµ‡à´£àµ½ à´…à´ªàµà´²à´¿à´•àµà´•àµ‡à´·àµ» വഴി പണമടയàµâ€Œà´•àµà´•à´¾àµ» അദൃശàµà´¯à´¤à´¾ സംവിധാനം ഒഴിവാകàµà´•àµà´¨àµà´¨àµ. à´¤àµà´Ÿà´°à´£àµ‹?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠപാസàµâ€Œà´µàµ‡à´¡àµ}other{# പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾}}</translation>
<translation id="3093245981617870298">നിങàµà´™àµ¾ à´“à´«àµâ€Œà´²àµˆà´¨à´¿à´²à´¾à´£àµ.</translation>
<translation id="3105172416063519923">അസറàµà´±àµ à´à´¡à´¿:</translation>
<translation id="3109728660330352905">നിങàµà´™àµ¾à´•àµà´•àµ à´ˆ പേജൠകാണാനàµà´³àµà´³ അംഗീകാരമിലàµà´².</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />കണകàµâ€Œà´±àµà´±à´¿à´µà´¿à´±àµà´±à´¿ ഡയഗണോസàµâ€Œà´±àµà´±à´¿à´•àµâ€Œà´¸àµ റൺ ചെയàµâ€Œà´¤àµà´¨àµ‹à´•àµà´•àµ‚<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">à´ªàµà´°à´¤à´¿à´•à´°à´£à´‚ ഡീകോഡൠചെയàµà´¯àµà´¨àµà´¨à´¤àµ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
<translation id="3150653042067488994">താൽകàµà´•à´¾à´²à´¿à´•à´®à´¾à´¯ സെർവർ പിശകàµ</translation>
@@ -247,15 +277,19 @@
<translation id="3167968892399408617">ആൾമാറാടàµà´Ÿ ടാബàµà´•à´³à´¿àµ½ നിങàµà´™àµ¾ കാണàµà´¨àµà´¨ പേജàµà´•àµ¾, ആൾമാറാടàµà´Ÿ ടാബàµà´•àµ¾ à´Žà´²àµà´²à´¾à´‚ à´…à´Ÿà´šàµà´šà´¤à´¿à´¨àµà´¶àµ‡à´·à´‚ à´¬àµà´°àµ—സർ à´šà´°à´¿à´¤àµà´°à´¤àµà´¤à´¿à´²àµ‹ à´•àµà´•àµà´•à´¿ à´¸àµà´±àµà´±àµ‹à´±à´¿à´²àµ‹ തിരയൽ à´šà´°à´¿à´¤àµà´°à´¤àµà´¤à´¿à´²àµ‹ ഉണàµà´Ÿà´¾à´•à´¿à´²àµà´². നിങàµà´™àµ¾ ഡൗൺലോഡàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨ ഫയലàµà´•à´³àµ‹ സൃഷàµâ€Œà´Ÿà´¿à´•àµà´•àµà´¨àµà´¨ à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´•à´³àµ‹ à´Žà´²àµà´²à´¾à´‚ സൂകàµà´·à´¿à´•àµà´•àµà´‚.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">à´à´²à´¨àµâ€à´¡àµ</translation>
+<translation id="317583078218509884">à´ªàµà´¤à´¿à´¯ സൈറàµà´±àµ à´…à´¨àµà´®à´¤à´¿ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾ പേജൠവീണàµà´Ÿàµà´‚ ലോഡàµà´šàµ†à´¯àµâ€Œà´¤à´¤à´¿à´¨àµà´¶àµ‡à´·à´‚ à´ªàµà´°à´¾à´¬à´²àµà´¯à´¤àµà´¤à´¿àµ½ വരàµà´‚.</translation>
<translation id="3176929007561373547">à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സെർവർ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´¨àµà´¨àµà´µàµ†à´¨àµà´¨àµ ഉറപàµà´ªà´¾à´•àµà´•à´¾àµ»
നിങàµà´™à´³àµà´Ÿàµ† à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ à´•àµà´°à´®àµ€à´•à´°à´£à´‚ പരിശോധികàµà´•àµà´•à´¯àµ‹ നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±à´±àµ† ബനàµà´§à´ªàµà´ªàµ†à´Ÿàµà´•à´¯àµ‹ ചെയàµà´¯àµà´•. നിങàµà´™àµ¾ ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤àµ ഒരൠപàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സെർവറാണെനàµà´¨àµ à´•à´°àµà´¤àµà´¨àµà´¨à´¿à´²àµà´²àµ†à´™àµà´•à´¿àµ½:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">അദൃശàµà´¯à´¤à´¾ സംവിധാനതàµà´¤à´¿àµ½ പേജൠതàµà´±à´•àµà´•àµà´•</translation>
-<translation id="3202578601642193415">à´à´±àµà´±à´µàµà´‚ à´ªàµà´¤à´¿à´¯</translation>
+<translation id="320323717674993345">പേയàµâ€Œà´®àµ†à´¨àµà´±àµ റദàµà´¦à´¾à´•àµà´•àµà´•</translation>
<translation id="3207960819495026254">à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
+<translation id="3225919329040284222">ബിൽടàµà´Ÿàµ-ഇൻ à´ªàµà´°à´¤àµ€à´•àµà´·à´•à´³àµâ€à´•àµà´•àµ പൊരàµà´¤àµà´¤à´ªàµà´ªàµ†à´Ÿà´¾à´¤àµà´¤ സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¾à´£àµ സെരàµâ€à´µà´°àµâ€ അവതരിപàµà´ªà´¿à´šàµà´šà´¤àµ. നിങàµà´™à´³àµ† സംരകàµà´·à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•à´¾à´¯àµà´³àµà´³ നിശàµà´šà´¿à´¤, ഉനàµà´¨à´¤-à´¸àµà´°à´•àµà´·à´¾ വെബàµâ€Œà´¸àµˆà´±àµà´±àµà´•àµ¾à´•àµà´•à´¾à´¯à´¾à´£àµ à´ˆ à´ªàµà´°à´¤àµ€à´•àµà´·à´•àµ¾ ഉൾപàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ.</translation>
<translation id="3226128629678568754">പേജൠലോഡàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´µà´¶àµà´¯à´®à´¾à´¯ ഡാറàµà´± വീണàµà´Ÿàµà´‚ സമർപàµà´ªà´¿à´•àµà´•à´¾àµ» വീണàµà´Ÿàµà´‚ ലോഡàµà´šàµ†à´¯àµà´¯àµà´• ബടàµà´Ÿàµº അമർതàµà´¤àµà´•.</translation>
+<translation id="3227137524299004712">മൈകàµà´°àµ‹à´«àµ‹àµº</translation>
<translation id="3228969707346345236"><ph name="LANGUAGE" /> à´²àµâ€â€Œ à´ˆ പേജൠഇതിനകം ഉളàµà´³à´¤à´¿à´¨à´¾à´²àµâ€â€Œ വിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" />-à´¨àµà´±àµ† CVC നൽകàµà´•</translation>
+<translation id="3234666976984236645">à´ˆ സൈറàµà´±à´¿àµ½ à´Žà´ªàµà´ªàµ‹à´´àµà´‚ à´ªàµà´°à´§à´¾à´¨ ഉളàµà´³à´Ÿà´•àµà´•à´‚ à´•à´£àµà´Ÿàµ†à´¤àµà´¤àµà´•</translation>
<translation id="3254409185687681395">à´ˆ പേജൠബàµà´•àµâ€Œà´®à´¾à´°àµâ€à´•àµà´•àµ ചെയàµà´¯àµà´•</translation>
<translation id="3270847123878663523">&amp;à´ªàµà´¨à´ƒà´•àµà´°à´®àµ€à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ പഴയപടിയാകàµà´•àµà´•</translation>
<translation id="3282497668470633863">കാർഡിലെ പേരൠചേർകàµà´•àµà´•</translation>
@@ -269,42 +303,48 @@
<translation id="3340978935015468852">à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾</translation>
<translation id="3345135638360864351">à´ˆ സൈറàµà´±àµ ആകàµâ€Œà´¸à´¸àµà´¸àµ ചെയàµà´¯à´¾à´¨àµà´³àµà´³ നിങàµà´™à´³àµà´Ÿàµ† à´…à´­àµà´¯àµ¼à´¤àµà´¥à´¨, <ph name="NAME" /> à´Žà´¨àµà´¨à´¯à´¾àµ¾à´•àµà´•àµ അയയàµâ€Œà´•àµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´². വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´•àµà´•àµà´•.</translation>
<translation id="3355823806454867987">à´ªàµà´°àµ‹à´•àµà´¸à´¿ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™à´³àµâ€ മാറàµà´±àµà´•...</translation>
+<translation id="3361596688432910856">Chrome ഇനിപàµà´ªà´±à´¯àµà´¨àµà´¨ വിവരങàµà´™àµ¾ <ph name="BEGIN_EMPHASIS" />സംരകàµà´·à´¿à´•àµà´•à´¿à´²àµà´²<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />നിങàµà´™à´³àµà´Ÿàµ† à´¬àµà´°àµ—സിംഗൠചരിതàµà´°à´‚
+ <ph name="LIST_ITEM" />à´•àµà´•àµà´•à´¿à´•à´³àµà´‚ സൈറàµà´±àµ ഡാറàµà´±à´¯àµà´‚
+ <ph name="LIST_ITEM" />ഫോമàµà´•à´³à´¿àµ½ നൽകàµà´¨àµà´¨ വിവരങàµà´™àµ¾
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">à´•àµà´²àµ‹à´•àµà´•à´¿à´²àµ† പിശകàµ</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> ഇനങàµà´™àµ¾ കൂടി...</translation>
<translation id="337363190475750230">à´¡à´¿à´ªàµà´°àµŠà´µà´¿à´·àµ» ചെയàµâ€Œà´¤àµ</translation>
<translation id="3377188786107721145">നയം പാഴàµâ€Œà´¸àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤à´¿àµ½ പിശകàµ</translation>
<translation id="3380365263193509176">à´…à´œàµà´žà´¾à´¤à´®à´¾à´¯ പിശകàµ</translation>
<translation id="3380864720620200369">à´•àµà´²à´¯à´¨àµà´±àµ ID:</translation>
<translation id="3391030046425686457">ഡെലിവർ ചെയàµà´¯àµ‡à´£àµà´Ÿ വിലാസം</translation>
<translation id="3395827396354264108">പികàµà´•à´ªàµà´ªàµ രീതി</translation>
-<translation id="340013220407300675">ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµ¾ നിങàµà´™à´³àµà´Ÿàµ† വിവരം <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ നിനàµà´¨àµ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´•àµà´•à´¾à´‚ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾).</translation>
<translation id="3422248202833853650">ഇടം സൃഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾àµ» മറàµà´±àµ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•à´³à´¿àµ½ നിനàµà´¨àµ à´ªàµà´±à´¤àµà´¤àµà´•à´Ÿà´•àµà´•àµà´¨àµà´¨à´¤àµ പരീകàµà´·à´¿à´•àµà´•àµ‚.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> നിലവിൽ ലഭàµà´¯à´®à´²àµà´².</translation>
+<translation id="3427092606871434483">à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´• (ഡിഫോൾടàµà´Ÿàµ)</translation>
<translation id="3427342743765426898">&amp;à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
<translation id="3431636764301398940">à´ˆ ഉപകരണതàµà´¤à´¿àµ½ à´ˆ കാർഡൠസംരകàµà´·à´¿à´•àµà´•àµà´•</translation>
<translation id="3435896845095436175">തയàµà´¯à´¾à´±à´¾à´•àµà´•àµà´•</translation>
<translation id="3447661539832366887">à´ˆ ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† ഉടമ ദിനോസർ ഗെയിം ഓഫാകàµà´•à´¿.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">ഇടവേള ലഭàµà´¯à´®à´¾à´•àµà´•àµà´•:</translation>
<translation id="3462200631372590220">വിപàµà´²à´®à´¾à´¯à´µ മറയàµà´•àµà´•àµà´•</translation>
<translation id="3467763166455606212">കാർഡൠഉടമയàµà´Ÿàµ† പേരൠആവശàµà´¯à´®à´¾à´£àµ</translation>
<translation id="3478058380795961209">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ മാസം</translation>
<translation id="3479539252931486093">ഇതൠഅപàµà´°à´¤àµ€à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿à´°àµà´¨àµà´¨àµ‹? <ph name="BEGIN_LINK" />à´žà´™àµà´™à´³àµ† അറിയികàµà´•àµà´•<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">ഇപàµà´ªàµ‹à´´à´²àµà´²</translation>
-<translation id="348000606199325318">à´•àµà´°à´¾à´·àµ à´à´¡à´¿, <ph name="CRASH_LOCAL_ID" /> (സെർവർ à´à´¡à´¿: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">ഇപàµà´ªàµ‹àµ¾ à´žà´™àµà´™àµ¾à´•àµà´•àµ നിങàµà´™à´³àµà´Ÿàµ† à´°à´•àµà´·à´•àµ¼à´¤àµà´¤à´¾à´µà´¿à´¨àµ† ബനàµà´§à´ªàµà´ªàµ†à´Ÿà´¾à´¨à´¾à´¯à´¿à´²àµà´². വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´•àµà´•àµà´•.</translation>
<translation id="3528171143076753409">സെരàµâ€à´µà´±à´¿à´¨àµâ€à´±àµ† സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ വിശàµà´µà´¾à´¸à´¯àµ‹à´—àµà´¯à´®à´²àµà´².</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´š ഉപകരണങàµà´™à´³à´¿àµ½ ഒരൠഇനമെങàµà´•à´¿à´²àµà´‚}=1{ഒരൠഇനം (à´’à´ªàµà´ªà´‚ സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´š ഉപകരണങàµà´™à´³à´¿àµ½ അതിൽ കൂടàµà´¤à´²àµà´‚)}other{# ഇനങàµà´™àµ¾ (à´’à´ªàµà´ªà´‚ സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´š ഉപകരണങàµà´™à´³à´¿àµ½ അതിൽ കൂടàµà´¤à´²àµà´‚)}}</translation>
<translation id="3539171420378717834">à´ˆ ഉപകരണതàµà´¤à´¿àµ½ à´ˆ കാർഡിനàµà´±àµ† ഒരൠപകർപàµà´ªàµ സൂകàµà´·à´¿à´•àµà´•àµà´•</translation>
<translation id="3542684924769048008">ഇതിനായി പാസàµâ€Œà´µàµ‡à´¡àµ ഉപയോഗികàµà´•àµà´•:</translation>
+<translation id="3545341443414427877">നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† തീയതിയàµà´‚ സമയവàµà´‚ (<ph name="DATE_AND_TIME" />) തെറàµà´±à´¾à´¯à´¤à´¿à´¨à´¾àµ½ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ à´¸àµà´µà´•à´¾à´°àµà´¯ കണകàµà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•à´¾à´¨à´¾à´µà´¿à´²àµà´². <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">നിങàµà´™à´³àµà´Ÿàµ† à´¸àµà´µà´¨àµà´¤à´‚ പാസàµâ€Œà´«àµà´°àµ†à´¯àµâ€Œà´¸àµ ഉപയോഗിചàµà´šàµ à´Žà´²àµà´²à´¾ സമനàµà´µà´¿à´¤ ഡാറàµà´±à´¯àµà´‚ എൻകàµà´°à´¿à´ªàµà´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> à´Žà´£àµà´£à´‚ കൂടി...</translation>
-<translation id="3555561725129903880">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ <ph name="DOMAIN2" /> à´Žà´¨àµà´¨ ഡൊമെയàµâ€Œà´¨à´¿àµ½ നിനàµà´¨àµà´³àµà´³à´¤à´¾à´£àµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">നിങàµà´™àµ¾à´•àµà´•àµ വേണàµà´Ÿà´¿ ഇതൠഅൺബàµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµà´¯à´¾àµ» മാനേജർകàµà´•àµ à´•à´´à´¿à´¯àµà´‚</translation>
<translation id="3566021033012934673">നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·àµ» à´¸àµà´µà´•à´¾à´°àµà´¯à´®à´²àµà´²</translation>
+<translation id="3569145463236695319">&lt;p&gt;നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† തീയതിയàµà´‚ സമയവàµà´‚ (<ph name="DATE_AND_TIME" />) തെറàµà´±à´¾à´¯à´¤à´¿à´¨à´¾àµ½ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ à´¸àµà´µà´•à´¾à´°àµà´¯ കണകàµà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•à´¾à´¨à´¾à´µà´¿à´²àµà´².&lt;/p&gt;
+
+ &lt;p&gt;&lt;strong&gt;à´•àµà´°à´®àµ€à´•à´°à´£&lt;/strong&gt; ആപàµà´ªà´¿à´¨àµà´±àµ† &lt;strong&gt;പൊതàµà´µà´¾à´¯&lt;/strong&gt; വിഭാഗതàµà´¤à´¿àµ½ നിനàµà´¨àµ തീയതിയàµà´‚ സമയവàµà´‚ à´•àµà´°à´®àµ€à´•à´°à´¿à´•àµà´•àµà´•.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">പേരൠചേർകàµà´•àµà´•</translation>
<translation id="3583757800736429874">&amp;നീകàµà´•àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
<translation id="3586931643579894722">വിശദാംശങàµà´™àµ¾ മറയàµâ€Œà´•àµà´•àµà´•â€â€Œ</translation>
-<translation id="3587482841069643663">à´Žà´²àµà´²à´¾à´‚</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ ശരിയായ തീയതി നലàµâ€à´•àµà´•</translation>
<translation id="36224234498066874">à´¬àµà´°àµŒà´¸à´¿à´‚ഗൠഡാറàµà´± മായàµâ€Œà´•àµà´•àµà´•...</translation>
@@ -321,7 +361,6 @@
<translation id="3681007416295224113">സരàµâ€â€Œà´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ വിവരങàµà´™à´³àµâ€â€Œ</translation>
<translation id="3690164694835360974">ലോഗിൻ ചെയàµà´¯àµà´¨àµà´¨à´¤àµ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²</translation>
<translation id="3693415264595406141">പാസàµâ€Œà´µàµ‡à´¡àµ:</translation>
-<translation id="3696411085566228381">à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ലോഡàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨àµ...</translation>
<translation id="3712624925041724820">ലൈസൻസàµà´•àµ¾ കാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
@@ -329,12 +368,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿à´¯àµà´‚ ഫയർവാളàµà´‚ DNS കോൺഫിഗറേഷനàµà´‚ പരിശോധികàµà´•àµà´¨àµà´¨àµ<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">നിങàµà´™à´³àµà´Ÿàµ† à´¸àµà´°à´•àµà´·à´¯àµ† ബാധിചàµà´šàµ‡à´•àµà´•à´¾à´µàµà´¨àµà´¨ അപകട സാധàµà´¯à´¤à´•à´³àµ†à´•àµà´•àµà´±à´¿à´šàµà´šàµ മനസàµà´¸à´¿à´²à´¾à´•àµà´•àµà´•à´¯à´¾à´£àµ†à´™àµà´•à´¿àµ½à´ªàµà´ªàµ‹à´²àµà´‚, à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ നീകàµà´•à´‚ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´¨àµ à´®àµà´®àµà´ªàµ <ph name="BEGIN_LINK" />à´ˆ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²à´¾à´¤àµà´¤ സൈറàµà´±àµ<ph name="END_LINK" /> നിങàµà´™àµ¾à´•àµà´•àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´‚ (à´¶àµà´ªà´¾àµ¼à´¶à´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¿à´²àµà´²).</translation>
<translation id="3739623965217189342">നിങàµà´™àµ¾ പകർതàµà´¤à´¿à´¯ ലിങàµà´•àµ</translation>
+<translation id="3744899669254331632">Chromium-നൠപàµà´°àµ‹à´¸à´¸àµà´¸àµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´•à´¾à´¤àµà´¤ രൂപമാറàµà´±à´‚ വരàµà´¤àµà´¤à´¿à´¯ à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ വെബàµà´¸àµˆà´±àµà´±àµ അയയàµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ <ph name="SITE" /> സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´•à´®à´¾à´¯à´¤à´¿à´¨à´¾àµ½ à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨ സൈറàµà´±à´¿à´²àµ† ആകàµà´°à´®à´¿à´•àµ¾, സോഫàµâ€Œà´±àµà´±àµâ€Œà´µà´¯à´±àµà´•àµ¾ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯àµà´¨àµà´¨à´¤àµ‹, à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ നിങàµà´™à´³àµà´Ÿàµ† à´¸àµà´µà´•à´¾à´°àµà´¯ വിവരങàµà´™àµ¾ വെളിപàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ‹ (ഉദാഹരണതàµà´¤à´¿à´¨àµ പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, ഫോൺ നമàµà´ªà´±àµà´•àµ¾ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ à´•àµà´°à´¡à´¿à´±àµà´±àµ ‌കാർഡàµà´•àµ¾) പോലെയàµà´³àµà´³ അപകടകരമായ കാരàµà´¯à´™àµà´™àµ¾ ചെയàµà´¯à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨ രീതിയിൽ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">ഒരൠസെരàµâ€à´µà´°àµâ€ പിശകൠകാരണം വിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
<translation id="3759461132968374835">നിങàµà´™à´³àµâ€à´•àµà´•àµ സമീപകാലതàµà´¤àµ റിപàµà´ªàµ‹à´°àµâ€à´Ÿàµà´Ÿàµà´šàµ†à´¯àµà´¤ à´•àµà´°à´¾à´·àµà´•à´³àµŠà´¨àµà´¨àµà´®à´¿à´²àµà´². à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹à´°àµâ€à´Ÿàµà´Ÿàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨ സമയതàµà´¤àµ സംഭവിചàµà´š à´•àµà´°à´¾à´·àµà´•à´³àµ† à´…à´ªàµà´°à´¾à´ªàµà´¤à´®à´¾à´•àµà´•à´¿, ഇവിടെ ദൃശàµà´¯à´®à´¾à´•à´¿à´²àµà´².</translation>
+<translation id="3778403066972421603">à´ˆ കാർഡൠനിങàµà´™à´³àµà´Ÿàµ† Google à´…à´•àµà´•àµ—à´£àµà´Ÿà´¿à´²àµà´‚ à´ˆ ഉപകരണതàµà´¤à´¿à´²àµà´‚ സംരകàµà´·à´¿à´•àµà´•à´£àµ‹?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" />-ൽ അവസാനികàµà´•àµà´¨àµà´¨àµ</translation>
<translation id="382518646247711829">നിങàµà´™àµ¾ ഒരൠപàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സെർവർ ഉപയോഗികàµà´•àµà´¨àµà´¨àµ†à´™àµà´•à´¿àµ½...</translation>
<translation id="3828924085048779000">ശൂനàµà´¯ പാസàµà´«àµà´°àµ†à´¯àµà´¸àµ à´…à´¨àµà´µà´¦à´¨àµ€à´¯à´®à´²àµà´².</translation>
-<translation id="3845539888601087042">നിങàµà´™àµ¾ സൈൻ ഇൻ ചെയàµâ€Œà´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨ ഉപകരണങàµà´™à´³à´¿àµ½ നിനàµà´¨àµà´³àµà´³ à´šà´°à´¿à´¤àµà´°à´‚ കാണികàµà´•àµà´¨àµà´¨àµ. <ph name="BEGIN_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">പിനàµà´¨àµ‹à´Ÿàµà´Ÿàµ</translation>
<translation id="3858027520442213535">തീയതിയàµà´‚ സമയവàµà´‚ à´…à´ªàµâ€Œà´¡àµ‡à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="3884278016824448484">വിരàµà´¦àµà´§ ഉപകരണ à´à´¡à´¨àµà´±à´¿à´«à´¯àµ¼</translation>
@@ -342,11 +384,13 @@
<translation id="3886446263141354045"><ph name="NAME" /> à´Žà´¨àµà´¨à´¯à´¾àµ¾à´•àµà´•àµ à´ˆ സൈറàµà´±àµ ആകàµâ€Œà´¸à´¸àµ ചെയàµà´¯à´¾à´¨àµà´³àµà´³ നിങàµà´™à´³àµà´Ÿàµ† à´…à´­àµà´¯àµ¼à´¤àµà´¥à´¨ അയചàµà´šàµ</translation>
<translation id="3890664840433101773">ഇമെയിലàµâ€â€Œ ചേരàµâ€â€Œà´•àµà´•àµà´•</translation>
<translation id="3901925938762663762">കാർഡൠകാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
-<translation id="3933571093587347751">{1,plural, =1{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ഇനàµà´¨à´²àµ† à´®àµà´¤àµ½ സാധàµà´µà´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.}other{à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ # ദിവസം à´®àµà´¤àµ½ സാധàµà´µà´¾à´¯à´¿à´°à´¿à´•àµà´•à´¿à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF à´ªàµà´°à´®à´¾à´£à´‚ ലോഡàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
+<translation id="3945915738023014686"><ph name="CRASH_ID" /> à´Žà´¨àµà´¨ à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµ à´à´¡à´¿ à´…à´ªàµâ€Œà´²àµ‹à´¡àµà´šàµ†à´¯àµâ€Œà´¤àµ (ലോകàµà´•àµ½ à´•àµà´°à´¾à´·àµ à´à´¡à´¿: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ വിഷയേതര നാമങàµà´™àµ¾ à´µàµà´¯à´•àµà´¤à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
<translation id="3963721102035795474">റീഡർ മോഡàµ</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠസൈറàµà´±à´¿àµ½ നിനàµà´¨àµ }other{# സൈറàµà´±àµà´•à´³à´¿àµ½ നിനàµà´¨àµ }}</translation>
<translation id="397105322502079400">കണകàµà´•à´¾à´•àµà´•àµà´¨àµà´¨àµ...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
+<translation id="3987940399970879459">ഒരൠMB-യിൽ à´•àµà´±à´µà´¾à´£àµ</translation>
<translation id="40103911065039147">{URL_count,plural, =1{സമീപതàµà´¤àµ ഒരൠവെബàµâ€Œà´ªàµ‡à´œàµà´£àµà´Ÿàµ}other{സമീപതàµà´¤àµ # വെബàµâ€Œà´ªàµ‡à´œàµà´•à´³àµà´£àµà´Ÿàµ}}</translation>
<translation id="4021036232240155012">ഒരൠവെബàµâ€Œà´¸àµˆà´±àµà´±à´¿à´¨àµà´±àµ† പേരൠഅതിനàµà´±àµ† ഇനàµà´±àµ¼à´¨àµ†à´±àµà´±àµ വിലാസതàµà´¤à´¿à´²àµ‡à´•àµà´•àµ വിവർതàµà´¤à´¨à´‚ ചെയàµà´¯àµà´¨àµà´¨ നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ സേവനമാണൠDNS.</translation>
<translation id="4030383055268325496">&amp;ചേർകàµà´•àµà´¨àµà´¨à´¤àµ പഴയപടിയാകàµà´•àµà´•</translation>
@@ -357,56 +401,63 @@
<translation id="4079302484614802869">à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ കോൺഫിഗറേഷൻ .pac à´¸àµâ€Œà´•àµà´°à´¿à´ªàµà´±àµà´±àµ URL ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ സജàµà´œàµ€à´•à´°à´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ, à´¸àµà´¥à´¿à´°à´®à´¾à´¯ à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സെർവറàµà´•àµ¾ ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´²àµà´².</translation>
<translation id="4098354747657067197">വഞàµà´šà´¨à´¾à´ªà´°à´®à´¾à´¯ സൈറàµà´±àµ ഉണàµà´Ÿàµ</translation>
<translation id="4103249731201008433">ഉപകരണ സീരിയൽ നമàµà´ªàµ¼ അസാധàµà´µà´¾à´£àµ</translation>
+<translation id="410351446219883937">à´¸àµà´µà´¯à´‚ à´ªàµà´²àµ‡à´šàµ†à´¯àµà´¯àµ½</translation>
<translation id="4103763322291513355">à´¬àµà´²à´¾à´•àµà´•àµâ€Œà´²à´¿à´¸àµà´±àµà´±à´¿àµ½à´ªàµà´ªàµ†à´Ÿàµà´Ÿ URL-à´•à´³àµà´Ÿàµ† ലിസàµà´±àµà´±àµà´‚ നിങàµà´™à´³àµà´Ÿàµ† സിസàµà´±àµà´±à´‚ à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±àµ¼ നടപàµà´ªà´¿à´²à´¾à´•àµà´•à´¿à´¯ മറàµà´±àµ നയങàµà´™à´³àµà´‚ കാണàµà´¨àµà´¨à´¤à´¿à´¨àµ &lt;strong&gt;chrome://policy&lt;/strong&gt; സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´•.</translation>
-<translation id="4110615724604346410">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿àµ½ പിശകàµà´•à´³àµà´£àµà´Ÿàµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">മജനàµà´¤</translation>
+<translation id="4116663294526079822">à´ˆ സൈറàµà´±à´¿àµ½ à´Žà´²àµà´²à´¾à´¯àµâ€Œà´ªàµà´ªàµ‹à´´àµà´‚ à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´•</translation>
<translation id="4117700440116928470">നയ à´¸àµâ€Œà´•àµ‹à´ªàµà´ªàµ പിനàµà´¤àµà´£à´¯àµà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´².</translation>
-<translation id="4118212371799607889">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† Chromium വിശàµà´µà´¸à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{മറàµà´±àµŠà´°àµ†à´£àµà´£à´‚}other{മറàµà´±àµ # à´Žà´£àµà´£à´‚}}</translation>
<translation id="4130226655945681476">നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ കേബിളàµà´•à´³àµà´‚ മോഡവàµà´‚ റൂടàµà´Ÿà´±àµà´‚ പരിശോധികàµà´•àµà´¨àµà´¨àµ</translation>
+<translation id="413544239732274901">കൂടàµà´¤à´²à´±à´¿à´¯àµà´•</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">ആഗോള à´¸àµà´¥à´¿à´°à´¶àµˆà´²à´¿ ഉപയോഗികàµà´•àµà´• (à´•à´£àµà´Ÿàµ†à´¤àµà´¤àµà´•)</translation>
+<translation id="4165986682804962316">സൈറàµà´±àµ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾</translation>
<translation id="4169947484918424451">Chromium à´ˆ കാർഡൠസംരകàµà´·à´¿à´•àµà´•à´£àµ‹?</translation>
<translation id="4171400957073367226">മോശം പരിശോധിചàµà´šàµà´±à´ªàµà´ªà´¿à´•àµà´•àµ½ സിഗàµâ€Œà´¨àµ‡à´šàµà´šàµ¼</translation>
<translation id="4196861286325780578">&amp;നീകàµà´•àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ഫയർവാളàµà´‚ ആനàµà´±à´¿à´µàµˆà´±à´¸àµ കോൺഫിഗറേഷനàµà´•à´³àµà´‚ പരിശോധികàµà´•àµà´¨àµà´¨àµ<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠആപàµà´ªàµ ($1)}=2{2 ആപàµâ€Œà´¸àµ ($1, $2)}other{# ആപàµâ€Œà´¸àµ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">à´•àµà´°à´¾à´·àµà´•à´³àµâ€</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨ സൈറàµà´±à´¿à´²àµ† ആകàµà´°à´®à´¿à´•àµ¾, à´¬àµà´°àµ—സർ à´…à´¨àµà´­à´µà´¤àµà´¤àµ† ദോഷകരമായി ബാധികàµà´•àµà´¨àµà´¨ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¿à´•àµà´•àµà´¨àµà´¨ വിധതàµà´¤à´¿àµ½ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•àµà´‚ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, നിങàµà´™à´³àµà´Ÿàµ† ഹോംപേജൠമാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµ‚ടെ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´¨àµà´¨ സൈറàµà´±àµà´•à´³à´¿àµ½ അധിക പരസàµà´¯à´™àµà´™àµ¾ കാണികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµ‚ടെ). <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ ഡയഗണോസàµâ€Œà´±àµà´±à´¿à´•àµâ€Œà´¸àµ റൺ ചെയàµâ€Œà´¤àµà´¨àµ‹à´•àµà´•àµ‚<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">സാധàµà´¤</translation>
<translation id="4250431568374086873">à´ˆ സൈറàµà´±à´¿à´²àµà´³àµà´³ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·àµ» പൂർണàµà´£à´®à´¾à´¯àµà´‚ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²</translation>
<translation id="4250680216510889253">ഇലàµà´²</translation>
<translation id="425582637250725228">നിങàµà´™àµ¾ വരàµà´¤àµà´¤à´¿à´¯ മാറàµà´±à´™àµà´™àµ¾ സംരകàµà´·à´¿à´•àµà´•à´ªàµà´ªàµ†à´Ÿàµà´Ÿà´¿à´°à´¿à´•àµà´•à´¾à´¨à´¿à´Ÿà´¯à´¿à´²àµà´².</translation>
<translation id="4258748452823770588">മോശം സിഗàµâ€Œà´¨àµ‡à´šàµà´šàµ¼</translation>
+<translation id="4265872034478892965">നിങàµà´™à´³àµà´Ÿàµ† à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´Ÿàµà´°àµ‡à´±àµà´±àµ¼ à´…à´¨àµà´µà´¦à´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
<translation id="4269787794583293679">(ഉപയോകàµà´¤àµƒà´¨à´¾à´®à´®à´¿à´²àµà´²)</translation>
<translation id="4275830172053184480">നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണം à´ªàµà´¨à´°à´¾à´°à´‚à´­à´¿à´•àµà´•àµà´•</translation>
<translation id="4280429058323657511">, <ph name="EXPIRATION_DATE_ABBR" />-നൠകാലാവധി തീരàµà´¨àµà´¨àµ</translation>
-<translation id="4295944351946828969"><ph name="SITE" /> à´Žà´¨àµà´¨ സൈറàµà´±à´¿àµ½ Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ <ph name="BEGIN_LINK" />ദോഷകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">പാരനàµà´±àµ നിർദàµà´¦àµ‡à´¶à´™àµà´™àµ¾</translation>
<translation id="4304224509867189079">ലോഗൠഇനàµâ€ ചെയàµà´¯àµà´•</translation>
-<translation id="432290197980158659">സെർവർ നൽകിയ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ à´…à´¨àµà´¤àµ¼à´¨à´¿àµ¼à´®àµà´®à´¿à´¤ ആവശàµà´¯à´•à´¤à´•à´³àµà´®à´¾à´¯à´¿ യോജികàµà´•àµà´¨àµà´¨à´¿à´²àµà´². നിങàµà´™à´³àµ† പരിരകàµà´·à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿ ഉയർനàµà´¨ à´¸àµà´°à´•àµà´·à´¯àµà´³àµà´³ à´šà´¿à´² വെബàµà´¸àµˆà´±àµà´±àµà´•àµ¾à´•àµà´•à´¾à´¯à´¾à´£àµ à´ˆ ആവശàµà´¯à´•à´¤à´•à´³àµ† ഉൾപàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµà´¯àµà´• (ഡിഫോൾടàµà´Ÿàµ)</translation>
<translation id="4325863107915753736">ലേഖനം à´•à´£àµà´Ÿàµ†à´¤àµà´¤àµà´¨àµà´¨à´¤àµ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
<translation id="4326324639298822553">കാലാവധി തീരàµà´¨àµà´¨ തീയതി പരിശോധിചàµà´šàµ വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´šàµà´šàµà´¨àµ‹à´•àµà´•àµ‚</translation>
<translation id="4331708818696583467">à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²</translation>
<translation id="4356973930735388585">à´ˆ സൈറàµà´±à´¿à´²àµ† ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµ¾ നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾à´¨àµ‹ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•à´¾à´¨àµ‹ ഇടയàµà´³àµà´³ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, ഫോടàµà´Ÿàµ‹à´•àµ¾, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ à´Žà´¨àµà´¨à´¿à´µ) അപകടകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿àµ½ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚.</translation>
<translation id="4372948949327679948">à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š <ph name="VALUE_TYPE" /> മൂലàµà´¯à´‚.</translation>
+<translation id="4377125064752653719">നിങàµà´™à´³àµâ€â€Œ <ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµâ€â€Œ à´Žà´¤àµà´¤à´¾à´¨àµâ€â€Œ à´¶àµà´°à´®à´¿à´šàµà´šàµ, പകàµà´·àµ‡ സെരàµâ€â€Œà´µà´°àµâ€â€Œ നൽകിയ സരàµâ€â€Œà´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ അതൠനലàµâ€â€Œà´•à´¿à´¯ ആളàµâ€â€Œ അസാധàµà´µà´¾à´•àµà´•à´¿. സെരàµâ€â€Œà´µà´°àµâ€â€Œ നലàµâ€â€Œà´•à´¿à´¯ à´¸àµà´°à´•àµà´·à´¾ à´•àµà´°àµ†à´¡à´¨àµâ€â€Œà´·àµà´¯à´²àµà´•à´³àµâ€â€Œ തികചàµà´šàµà´‚ വിശàµà´µà´¾â€à´¸à´¯àµ‹à´—àµà´¯à´®à´²àµà´² à´Žà´¨àµà´¨à´¾à´£àµ ഇതിനരàµâ€â€Œà´¤àµà´¥à´‚. നിങàµà´™à´³àµâ€â€Œ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµà´®à´¾à´¯à´¿à´Ÿàµà´Ÿà´¾à´•à´¾à´‚ ആശയവിനിമയം നടതàµà´¤àµà´¨àµà´¨à´¤àµ.</translation>
<translation id="4381091992796011497">ഉപയോകàµà´¤àµƒ നാമം:</translation>
<translation id="4394049700291259645">à´…à´ªàµà´°à´¾à´ªàµâ€Œà´¤à´®à´¾à´•àµà´•àµà´•</translation>
<translation id="4406896451731180161">തിരയൽ ഫലങàµà´™àµ¾</translation>
+<translation id="4424024547088906515">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ Chrome-നൠപരിചയമിലàµà´²à´¾à´¤àµà´¤à´¤à´¾à´£àµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" />, നിങàµà´™à´³àµà´Ÿàµ† ലോഗിൻ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ അംഗീകരിചàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´², à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ à´…à´™àµà´™à´¨àµ†à´¯àµŠà´°àµ†à´£àµà´£à´‚ നൽകിയിടàµà´Ÿà´¿à´²àµà´²à´¾à´¯à´¿à´°à´¿à´•àµà´•à´¾à´‚.</translation>
<translation id="443673843213245140">à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ ഉപയോഗം à´…à´ªàµà´°à´¾à´ªàµâ€Œà´¤à´®à´¾à´•àµà´•à´¿ പകàµà´·àµ† ഒരൠവàµà´¯à´•àµà´¤à´®à´¾à´¯ à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ കോൺഫിഗറേഷൻ നിർദàµà´¦àµ‡à´¶à´¿à´šàµà´šàµ.</translation>
-<translation id="4492190037599258964">'<ph name="SEARCH_STRING" />' à´¨àµà´³àµà´³ തിരയൽ ഫലങàµà´™à´³àµâ€</translation>
<translation id="4506176782989081258">മൂലàµà´¯à´¨à´¿àµ¼à´£àµà´£à´¯ പിശകàµ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">സിസàµà´±àµà´±à´‚ à´…à´¡àµâ€Œà´®à´¿à´¨àµ† ബനàµà´§à´ªàµà´ªàµ†à´Ÿàµà´¨àµà´¨àµ</translation>
<translation id="450710068430902550">à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±à´±àµà´®à´¾à´¯à´¿ പങàµà´•à´¿à´Ÿàµà´¨àµà´¨àµ</translation>
<translation id="4515275063822566619">കാർഡàµà´•à´³àµà´‚ വിലാസങàµà´™à´³àµà´‚ Chrome-ൽ നിനàµà´¨àµà´‚ നിങàµà´™à´³àµà´Ÿàµ† അ‌കàµà´•àµ—à´£àµà´Ÿà´¿àµ½ (<ph name="ACCOUNT_EMAIL" />) നിനàµà´¨àµà´®àµà´³àµà´³à´¤àµà´®à´¾à´£àµ. നിങàµà´™àµ¾à´•àµà´•àµ ഇവ <ph name="BEGIN_LINK" />à´•àµà´°à´®àµ€à´•à´°à´£à´¤àµà´¤à´¿àµ½<ph name="END_LINK" /> മാനേജàµà´šàµ†à´¯àµà´¯à´¾à´‚.</translation>
<translation id="4522570452068850558">വിശദാംശങàµà´™àµ¾â€Œ</translation>
+<translation id="4552089082226364758">à´«àµà´²à´¾à´·àµ</translation>
<translation id="4558551763791394412">നിങàµà´™à´³àµà´Ÿàµ† വിപàµà´²àµ€à´•à´°à´£à´™àµà´™àµ¾ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´°à´¹à´¿à´¤à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤àµ പരീകàµà´·à´¿à´•àµà´•àµà´•.</translation>
<translation id="457875822857220463">ഡെലിവറി വിവരങàµà´™àµ¾</translation>
<translation id="4587425331216688090">Chrome-ൽ നിനàµà´¨àµ വിലാസം നീകàµà´•à´‚ചെയàµà´¯à´£àµ‹?</translation>
-<translation id="4589078953350245614">നിങàµà´™àµ¾ <ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¿àµ½ à´Žà´¤àµà´¤à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ†à´™àµà´•à´¿à´²àµà´‚ സെർവർ അസാധàµà´µà´¾à´¯ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¾à´£àµ നൽകിയതàµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† ആധàµà´¨à´¿à´• സൈഫർ à´¸àµà´¯àµ‚à´Ÿàµà´Ÿàµ ഉപയോഗിചàµà´šàµ എൻകàµà´°à´¿à´ªàµà´±àµà´±àµà´šàµ†à´¯àµâ€Œà´¤à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ.</translation>
<translation id="4594403342090139922">&amp;ഇലàµà´²à´¾à´¤à´¾à´•àµà´•àµà´¨àµà´¨à´¤àµ പഴയപടിയാകàµà´•àµà´•</translation>
<translation id="4619615317237390068">മറàµà´±àµ ഉപകരണങàµà´™à´³à´¿àµ½ നിനàµà´¨àµà´³àµà´³ ടാബàµà´•àµ¾</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿àµ½ പിശകàµà´•àµ¾ à´…à´Ÿà´™àµà´™à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
+<translation id="4690462567478992370">അസാധàµà´µà´¾à´¯ ഒരൠസർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤àµ നിർതàµà´¤àµà´•</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·àµ» തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ ഡയഗണോസàµâ€Œà´±àµà´±à´¿à´•àµâ€Œà´¸àµ റൺ ചെയàµà´¯àµà´¨àµà´¨àµ<ph name="END_LINK" /></translation>
@@ -423,21 +474,24 @@
<translation id="4771973620359291008">ഒരൠഅജàµà´žà´¾à´¤ പിശകൠസംഭവിചàµà´šàµ.</translation>
<translation id="4800132727771399293">നിങàµà´™à´³àµà´Ÿàµ† കാലഹരണ തീയതിയàµà´‚ CVC à´¯àµà´‚ പരിശോധിചàµà´šàµ വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´•àµà´•àµà´•</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Google Chrome-നൠപàµà´°àµ‹à´¸à´¸àµà´¸àµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´•à´¾à´¤àµà´¤ രൂപമാറàµà´±à´‚ വരàµà´¤àµà´¤à´¿à´¯ à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ വെബàµà´¸àµˆà´±àµà´±àµ അയയàµà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ <ph name="SITE" /> സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´².നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´•à´®à´¾à´¯à´¤à´¿à´¨à´¾àµ½, à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚.</translation>
<translation id="4813512666221746211">നെറàµà´±àµâ€Œà´µà´°àµâ€à´•àµà´•àµ പിശകàµ</translation>
<translation id="4816492930507672669">പേജിനൠയàµà´•àµà´¤à´®à´¾à´•àµà´•àµà´•</translation>
<translation id="483020001682031208">കാണികàµà´•à´¾àµ» à´ªàµà´°à´¤àµà´¯à´•àµà´· വെബൠപേജàµà´•à´³à´¿à´²àµà´²</translation>
<translation id="4850886885716139402">കാണàµà´•</translation>
<translation id="4854362297993841467">à´ˆ ഡെലിവറി രീതി ലഭàµà´¯à´®à´²àµà´². മറàµà´±àµŠà´°àµ രീതി പരീകàµà´·à´¿à´•àµà´•àµà´•.</translation>
<translation id="4858792381671956233">à´ˆ സൈറàµà´±àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ നിങàµà´™àµ¾ à´°à´•àµà´·à´¿à´¤à´¾à´•àµà´•à´³àµ‹à´Ÿàµ à´…à´¨àµà´®à´¤à´¿ ആവശàµà´¯à´ªàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
+<translation id="4863764087567530506">നിങàµà´™àµ¾ സോഫàµâ€Œà´±àµà´±àµâ€Œà´µàµ†à´¯à´±àµà´•àµ¾ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¾à´¨àµ‹ à´µàµà´¯à´•àµà´¤à´¿à´—à´¤ വിവരങàµà´™àµ¾ വെളിപàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¾à´¨àµ‹ വേണàµà´Ÿà´¿, à´ˆ ഉളàµà´³à´Ÿà´•àµà´•à´‚ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚. <ph name="BEGIN_LINK" />à´Žà´¨àµà´¤à´¾à´¯à´¾à´²àµà´‚ കാണികàµà´•àµà´•<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">തിരയൽ à´šà´°à´¿à´¤àµà´°à´‚</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ഒരൠവെബàµâ€Œà´ªàµ‡à´œàµ കൂടിയàµà´£àµà´Ÿàµ}other{# വെബàµâ€Œà´ªàµ‡à´œàµà´•àµ¾ കൂടിയàµà´£àµà´Ÿàµ}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">à´ˆ പേജിനെ അറിയപàµà´ªàµ†à´Ÿà´¾à´¤àµà´¤ ഒരൠഭാഷയിലàµâ€â€Œ നിനàµà´¨àµà´‚ <ph name="LANGUAGE_LANGUAGE" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµ വിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ ചെയàµà´¤àµ</translation>
<translation id="4923459931733593730">പേയàµâ€Œà´®àµ†à´¨àµà´±àµ രീതി</translation>
<translation id="4926049483395192435">à´µàµà´¯à´•àµà´¤à´®à´¾à´•àµà´•àµ‡à´£àµà´Ÿà´¤à´¾à´£àµ.</translation>
<translation id="495170559598752135">à´ªàµà´°à´µà´°àµâ€à´¤àµà´¤à´¨à´™àµà´™à´³àµâ€</translation>
<translation id="4958444002117714549">ലിസàµà´±àµà´±àµ വിപàµà´²àµ€à´•à´°à´¿à´•àµà´•àµà´•</translation>
-<translation id="4962322354953122629">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† Chrome വിശàµà´µà´¸à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">à´®àµà´¨àµà´¨à´±à´¿à´¯à´¿à´ªàµà´ªàµà´•àµ¾ വീണàµà´Ÿàµà´‚ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´•àµà´·à´®à´®à´¾à´•àµà´•àµà´•</translation>
<translation id="4989809363548539747">à´ˆ à´ªàµà´²à´—ിൻ പിനàµà´¤àµà´£à´¯àµâ€Œà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²</translation>
<translation id="5002932099480077015">à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´•àµà´·à´®à´®à´¾à´•àµà´•à´¿à´¯àµ†à´™àµà´•à´¿àµ½, വേഗതàµà´¤à´¿àµ½ ഫോം പൂരിപàµà´ªà´¿à´•àµà´•à´¾àµ» Chrome à´ˆ ഉപകരണതàµà´¤à´¿àµ½ നിങàµà´™à´³àµà´Ÿàµ† കാർഡിനàµà´±àµ† ഒരൠപകർപàµà´ªàµ സൂകàµà´·à´¿à´•àµà´•àµà´‚.</translation>
<translation id="5018422839182700155">à´ˆ പേജൠതàµà´±à´•àµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²</translation>
@@ -445,14 +499,15 @@
<translation id="5023310440958281426">നിങàµà´™à´³àµà´Ÿàµ† à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµà´Ÿàµà´°àµ‡à´±àµà´±à´±àµà´Ÿàµ† നയങàµà´™àµ¾ പരിശോധികàµà´•àµà´•</translation>
<translation id="5029568752722684782">പകർപàµà´ªàµ മായàµâ€Œà´•àµà´•àµà´•</translation>
<translation id="5031870354684148875">Google വിവരàµâ€à´¤àµà´¤à´¨à´‚ à´Žà´¨àµà´¨à´¤à´¿à´¨àµ†à´•àµà´•àµà´±à´¿à´šàµà´šàµ </translation>
+<translation id="5039804452771397117">à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµ‚</translation>
<translation id="5040262127954254034">à´¸àµà´µà´•à´¾à´°àµà´¯à´¤</translation>
<translation id="5045550434625856497">ശരിയലàµà´²à´¾à´¤àµà´¤ രഹസàµà´¯à´µà´¾à´•àµà´•àµ</translation>
<translation id="5056549851600133418">നിങàµà´™àµ¾à´•àµà´•àµà´³àµà´³ ലേഖനങàµà´™àµ¾</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ വിലാസം പരിശോധികàµà´•àµà´¨àµà´¨àµ<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{à´•àµà´•àµà´•à´¿à´•à´³à´¿à´²àµà´²}=1{ഒരൠസൈറàµà´±àµ à´•àµà´•àµà´•à´¿à´•àµ¾ ഉപയോഗികàµà´•àµà´¨àµà´¨àµ. }other{# സൈറàµà´±àµà´•àµ¾, à´•àµà´•àµà´•à´¿à´•àµ¾ ഉപയോഗികàµà´•àµà´¨àµà´¨àµ. }}</translation>
<translation id="5087286274860437796">സെർവറിനàµà´±àµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ ഇപàµà´ªàµ‹àµ¾ സാധàµà´¤à´¯à´¿à´²àµà´².</translation>
<translation id="5087580092889165836">കാർഡൠചേർകàµà´•àµà´•</translation>
<translation id="5089810972385038852">à´¸àµà´±àµà´±àµ‡à´±àµà´±àµ</translation>
+<translation id="5094747076828555589">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´· സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† Chromium-à´¤àµà´¤à´¿à´¨àµà´¨àµ പരിചയമിലàµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
<translation id="5095208057601539847">à´ªàµà´°à´µà´¿à´¶àµà´¯</translation>
<translation id="5115563688576182185">(64-ബിറàµà´±àµ)</translation>
<translation id="5141240743006678641">Google à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ ഉപയോഗിചàµà´šàµ സമനàµà´µà´¿à´¤ പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾ എൻകàµà´°à´¿à´ªàµà´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
@@ -468,24 +523,24 @@
<translation id="5222812217790122047">ഇമെയിൽ ആവശàµà´¯à´®à´¾à´£àµ</translation>
<translation id="5251803541071282808">à´•àµà´²àµ—à´¡àµ</translation>
<translation id="5277279256032773186">ജോലിസàµà´¥à´²à´¤àµà´¤àµà´³àµà´³ Chrome ഉപയോഗികàµà´•àµà´•à´¯à´¾à´£àµ‹? ബിസിനസൠസàµà´¥à´¾à´ªà´¨à´™àµà´™àµ¾à´•àµà´•àµ അവരàµà´Ÿàµ† ജീവനകàµà´•à´¾àµ¼à´•àµà´•àµ വേണàµà´Ÿà´¿ Chrome à´•àµà´°à´®àµ€à´•à´°à´£à´‚ മാനേജàµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´•àµà´‚. കൂടàµà´¤à´²à´±à´¿à´¯àµà´•</translation>
+<translation id="5297526204711817721">à´ˆ സൈറàµà´±à´¿à´²àµ† നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·àµ» à´¸àµà´µà´•à´¾à´°àµà´¯à´®à´²àµà´². à´Žà´ªàµà´ªàµ‹àµ¾ വേണമെങàµà´•à´¿à´²àµà´‚ VR മോഡിൽ നിനàµà´¨àµ à´ªàµà´±à´¤àµà´¤àµà´•à´Ÿà´•àµà´•à´¾àµ», ഹെഡàµâ€Œà´¸àµ†à´±àµà´±àµ നീകàµà´•à´‚ചെയàµâ€Œà´¤ ശേഷം 'തിരികെ പോകàµà´•' അമർതàµà´¤àµà´•.</translation>
<translation id="5299298092464848405">നയം പാഴàµâ€Œà´¸àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤à´¿àµ½ പിശകàµ</translation>
-<translation id="5300589172476337783">കാണികàµà´•àµà´•</translation>
<translation id="5308689395849655368">à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹à´°àµâ€à´Ÿàµà´Ÿàµà´šàµ†à´¯àµà´¯à´²àµâ€ à´…à´ªàµà´°à´¾à´ªàµà´¤à´®à´¾à´•àµà´•à´¿.</translation>
<translation id="5317780077021120954">സംരകàµà´·à´¿à´•àµà´•àµà´•</translation>
<translation id="5327248766486351172">പേരàµ</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ† ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµ¾ സോഫàµà´±àµà´±àµâ€Œà´µàµ†à´¯àµ¼ ഇൻസàµà´±àµà´±à´¾à´³àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ‹ à´¸àµà´µà´•à´¾à´°àµà´¯ വിവരങàµà´™àµ¾ വെളിപàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ‹ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, ഫോൺ നമàµà´ªà´±àµà´•àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ à´¤àµà´Ÿà´™àµà´™à´¿à´¯ വിവരങàµà´™àµ¾) പോലàµà´³àµà´³ അപകടകരമായ കാരàµà´¯à´™àµà´™àµ¾ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´¨àµ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾à´‚.</translation>
-<translation id="5359637492792381994">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ഇപàµà´ªàµ‹àµ¾ സാധàµà´µà´¾à´¯à´¤à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ റദàµà´¦à´¾à´•àµà´•à´¿à´¯à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ <ph name="SITE" /> സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണ താൽകàµà´•à´¾à´²à´¿à´•à´®à´¾à´¯à´¿à´°à´¿à´•àµà´•àµà´‚, അതിനാൽ à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚.</translation>
<translation id="536296301121032821">നയ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾ സംഭരികàµà´•àµà´¨àµà´¨à´¤à´¿àµ½ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
<translation id="5386426401304769735">à´ˆ സൈറàµà´±à´¿à´¨àµà´±àµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ചെയിനിൽ SHA-1 ഉപയോഗിചàµà´šàµ സൈൻ ചെയàµâ€Œà´¤ ഒരൠസർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ à´…à´Ÿà´™àµà´™à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ.</translation>
<translation id="5402410679244714488">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ തീയതി: <ph name="EXPIRATION_DATE_ABBR" />, അവസാനമായി ഉപയോഗിചàµà´šà´¤àµ ഒരൠവർഷം à´®àµà´®àµà´ªà´¾à´£àµ</translation>
+<translation id="540969355065856584">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´· സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ ഇപàµà´ªàµ‹àµ¾ സാധàµà´¤à´¯àµà´³àµà´³à´¤à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
<translation id="5421136146218899937">à´¬àµà´°àµ—സിംഗൠഡാറàµà´± മായàµâ€Œà´•àµà´•àµà´•...</translation>
<translation id="5430298929874300616">à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµ നീകàµà´•à´‚ചെയàµà´¯àµà´•</translation>
<translation id="5431657950005405462">നിങàµà´™à´³àµà´Ÿàµ† ഫയൽ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿à´¯à´¿à´²àµà´²</translation>
-<translation id="5435775191620395718">à´ˆ ഉപകരണതàµà´¤à´¿àµ½ നിനàµà´¨àµà´³àµà´³ à´šà´°à´¿à´¤àµà´°à´‚ കാണികàµà´•àµà´¨àµà´¨àµ. <ph name="BEGIN_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" à´Žà´¨àµà´¨à´¤à´¿àµ½ à´¸àµâ€Œà´•àµ€à´® മൂലàµà´²àµà´¯à´¨à´¿àµ¼à´£àµà´£à´¯ പിശകàµ: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">à´ˆ <ph name="HOST_NAME" /> പേജൠകണàµà´Ÿàµ†à´¤àµà´¤à´¾à´¨à´¾à´¯à´¿à´²àµà´²</translation>
<translation id="5455374756549232013">മോശം നയ ടൈംസàµà´±àµà´±à´¾à´®àµà´ªàµ</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" /> à´¨àµà´±àµ† <ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">അസാധàµà´µà´¾à´£àµ</translation>
<translation id="5470861586879999274">&amp;à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
<translation id="54817484435770891">ശരിയായ വിലാസം ചേർകàµà´•àµà´•</translation>
<translation id="5492298309214877701">à´•à´®àµà´ªà´¨à´¿, ഓർഗനൈസേഷൻ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ à´¸àµâ€Œà´•àµ‚ൾ ഇൻടàµà´°à´¾à´¨àµ†à´±àµà´±à´¿à´²àµ† à´ˆ സൈറàµà´±à´¿à´¨àµ, ബാഹàµà´¯ വെബàµâ€Œà´¸àµˆà´±àµà´±à´¿à´¨àµ സമാനമായ URL ആണàµà´³àµà´³à´¤àµ.
@@ -502,6 +557,8 @@
<translation id="5571083550517324815">à´ˆ വിലാസതàµà´¤à´¿àµ½ നിനàµà´¨àµ പികàµà´•àµà´…à´ªàµà´ªàµ ചെയàµà´¯à´¾àµ» കഴിയിലàµà´². മറàµà´±àµŠà´°àµ വിലാസം തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•.</translation>
<translation id="5572851009514199876">ആരംഭിചàµà´šàµ Chrome-ൽ സൈൻ ഇൻ ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´²àµ‚ടെ, നിങàµà´™àµ¾à´•àµà´•àµ à´ˆ സൈറàµà´±àµ ആകàµâ€Œà´¸à´¸àµ ചെയàµà´¯à´¾àµ» à´…à´¨àµà´µà´¾à´¦à´®àµà´£àµà´Ÿàµ‹à´¯àµ†à´¨àµà´¨àµ Chrome-നൠപരിശോധികàµà´•à´¾à´¨à´¾à´µàµà´‚.</translation>
<translation id="5580958916614886209">കാലാവധി തീരàµà´¨àµà´¨ മാസം പരിശോധിചàµà´šàµ വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´šàµà´šàµà´¨àµ‹à´•àµà´•àµ‚</translation>
+<translation id="5586446728396275693">സംരകàµà´·à´¿à´šàµà´š വിലാസങàµà´™à´³àµŠà´¨àµà´¨àµà´®à´¿à´²àµà´²</translation>
+<translation id="5595485650161345191">വിലാസം à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="560412284261940334">മാനേജàµà´®àµ†à´¨àµà´±àµ പിനàµà´¤àµà´£à´¯àµâ€Œà´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²</translation>
<translation id="5610142619324316209">കണകàµà´·àµ» പരിശോധികàµà´•àµà´¨àµà´¨àµ</translation>
<translation id="5610807607761827392">നിങàµà´™àµ¾à´•àµà´•àµ <ph name="BEGIN_LINK" />à´•àµà´°à´®àµ€à´•à´°à´£à´¤àµà´¤à´¿àµ½<ph name="END_LINK" /> കാർഡàµà´•à´³àµà´‚ വിലാസങàµà´™à´³àµà´‚ മാനേജàµà´šàµ†à´¯àµà´¯à´¾à´‚.</translation>
@@ -509,15 +566,18 @@
<translation id="5622887735448669177">നിങàµà´™àµ¾à´•àµà´•àµ à´ˆ സൈറàµà´±àµ വിടണോ?</translation>
<translation id="5629630648637658800">നയ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾ ലോഡàµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤à´¿àµ½ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
<translation id="5631439013527180824">ഉപകരണ മാനേജàµà´®àµ†à´¨àµà´±àµ ടോകàµà´•àµº അസാധàµà´µà´¾à´£àµ</translation>
+<translation id="5633066919399395251"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨ സൈറàµà´±à´¿à´²àµ† നിലവിലàµà´³àµà´³ ആകàµà´°à´®à´¿à´•àµ¾ നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾à´¨àµ‹ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•à´¾à´¨àµ‹ ഇടയàµà´³àµà´³ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, ഫോടàµà´Ÿàµ‹à´•àµ¾, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ à´Žà´¨àµà´¨à´¿à´µ) അപകടകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿àµ½ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">à´¸àµà´¥à´¾à´¨à´‚</translation>
+<translation id="5659593005791499971">ഇമെയിലàµâ€</translation>
<translation id="5669703222995421982">à´µàµà´¯à´•àµà´¤à´¿à´ªà´°à´®à´¾à´•àµà´•à´¿à´¯ ഉളàµà´³à´Ÿà´•àµà´•à´‚ à´¸àµà´µà´¨àµà´¤à´®à´¾à´•àµà´•àµà´•</translation>
<translation id="5675650730144413517">à´ˆ പേജൠപàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´²</translation>
-<translation id="5677928146339483299">തടഞàµà´žàµ</translation>
-<translation id="5694783966845939798">നിങàµà´™à´³àµâ€â€Œ <ph name="DOMAIN" /> ഡൊമെയàµâ€Œàµ» ആകàµâ€Œà´¸à´¸àµ ചെയàµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ, à´Žà´¨àµà´¨à´¾àµ½ à´¦àµàµ¼à´¬à´²à´®à´¾à´¯ സിഗàµâ€Œà´¨àµ‡à´šàµà´šà´°àµâ€â€Œ à´…à´²àµâ€â€Œà´—രിതം (SHA-1 പോലàµà´³àµà´³à´¤àµ) ഉപയോഗിചàµà´šàµ സൈൻ ചെയàµâ€Œà´¤ സരàµâ€â€Œà´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¾à´£àµ സെരàµâ€â€Œà´µà´°àµâ€â€Œ നലàµâ€â€Œà´•à´¿à´¯à´¤àµ. ഇതിനരàµâ€â€Œà´¤àµà´¥à´‚ സെരàµâ€â€Œà´µà´°àµâ€â€Œ നലàµâ€â€Œà´•à´¿à´¯ à´¸àµà´°à´•àµà´·à´¾ à´•àµà´°àµ†à´¡à´¨àµâ€â€Œà´·àµà´¯à´²àµà´•à´³àµâ€â€Œ à´µàµà´¯à´¾à´œà´®à´¾à´•à´¾à´®àµ†à´¨àµà´¨àµà´‚ സെരàµâ€â€Œà´µà´°àµâ€â€Œ നിങàµà´™à´³àµâ€â€Œ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š സെരàµâ€â€Œà´µà´±à´¾à´¯à´¿à´°à´¿à´•àµà´•à´¿à´²àµà´²àµ†à´¨àµà´¨àµà´®à´¾à´£àµ (നിങàµà´™à´³àµâ€â€Œ ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµà´®à´¾à´¯à´¿à´Ÿàµà´Ÿà´¾à´•à´¾à´‚ ആശയവിനിമയം നടതàµà´¤àµà´¨àµà´¨à´¤àµ). <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">à´ˆ വെബàµà´¸àµˆà´±àµà´±à´¿à´¨àµà´±àµ† à´µàµà´¯à´•àµà´¤à´¿à´¤àµà´µà´‚ പരിശോധിചàµà´šà´¿à´Ÿàµà´Ÿà´¿à´²àµà´².</translation>
+<translation id="5713016350996637505">തെറàµà´±à´¿à´¦àµà´§à´°à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨ ഉളàµà´³à´Ÿà´•àµà´•à´‚ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="5720705177508910913">നിലവിലെ ഉപയോകàµà´¤à´¾à´µàµ</translation>
<translation id="5732392974455271431">നിങàµà´™àµ¾à´•àµà´•àµ വേണàµà´Ÿà´¿ ഇതൠഅൺബàµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµà´¯à´¾àµ» à´°à´•àµà´·à´¿à´¤à´¾à´•àµà´•àµ¾à´•àµà´•àµ à´•à´´à´¿à´¯àµà´‚</translation>
<translation id="5763042198335101085">ശരിയായ ഇമെയിൽ വിലാസം നൽകàµà´•</translation>
<translation id="5765072501007116331">ഡെലിവറി രീതികളàµà´‚ ആവശàµà´¯à´•à´¤à´•à´³àµà´‚ കാണാൻ ഒരൠവിലാസം തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•</translation>
+<translation id="5778550464785688721">MIDI ഉപകരണങàµà´™à´³àµà´Ÿàµ† പൂർണ നിയനàµà´¤àµà´°à´£à´‚</translation>
<translation id="5784606427469807560">നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠസàµà´¥à´¿à´°àµ€à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿àµ½ à´ªàµà´°à´¶àµâ€Œà´¨à´®àµà´£àµà´Ÿà´¾à´¯à´¿. ഇനàµà´±àµ¼à´¨àµ†à´±àµà´±àµ കണകàµà´·àµ» പരിശോധിചàµà´šàµ, വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´•àµà´•àµà´•.</translation>
<translation id="5785756445106461925">കൂടാതെ, à´ˆ പേജിൽ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²à´¾à´¤àµà´¤ മറàµà´±àµ ഉറവിടങàµà´™àµ¾ ഉൾപàµà´ªàµ†à´Ÿàµà´¨àµà´¨àµ. à´ˆ ഉറവിടങàµà´™àµ¾ കൈമാറàµà´¨àµà´¨à´¤à´¿à´¨à´¿à´Ÿàµ† മറàµà´±àµà´³àµà´³à´µàµ¼à´•àµà´•àµ കാണാനàµà´‚ പേജിനàµà´±àµ† രൂപം മാറàµà´±àµà´¨àµà´¨ തരതàµà´¤à´¿àµ½ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµâ€Œà´•àµà´•àµ പരിഷàµâ€Œà´•àµà´•à´°à´¿à´•àµà´•à´¾à´¨àµà´®à´¾à´¯àµ‡à´•àµà´•àµà´‚.</translation>
<translation id="5786044859038896871">നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠവിവരം പൂരിപàµà´ªà´¿à´•àµà´•à´£àµ‹?</translation>
@@ -526,14 +586,14 @@
<translation id="5813119285467412249">&amp;ചേർകàµà´•àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
<translation id="5814352347845180253">നിങàµà´™àµ¾à´•àµà´•àµ, <ph name="SITE" /> സൈറàµà´±à´¿àµ½ നിനàµà´¨àµà´‚ മറàµà´±àµà´¸àµˆà´±àµà´±àµà´•à´³à´¿àµ½ നിനàµà´¨àµà´®àµà´³àµà´³ à´ªàµà´°àµ€à´®à´¿à´¯à´‚ ഉളàµà´³à´Ÿà´•àµà´•à´¤àµà´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ ആകàµâ€Œà´¸à´¸àµ നഷàµâ€Œà´Ÿà´®à´¾à´¯àµ‡à´•àµà´•à´¾à´‚.</translation>
<translation id="5838278095973806738">à´…à´•àµà´°à´®à´•à´¾à´°à´¿à´•àµ¾ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾àµ» സാധàµà´¯à´¤à´¯àµà´³àµà´³à´¤à´¿à´¨à´¾àµ½ à´ˆ സൈറàµà´±à´¿àµ½ നിങàµà´™à´³àµà´Ÿàµ† രഹസàµà´¯ വിവരങàµà´™à´³àµŠà´¨àµà´¨àµà´‚ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, പാസàµâ€Œà´µàµ‡à´¡àµà´•à´³àµ‹ à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•à´³àµ‹ പോലàµà´³àµà´³à´µ) നൽകരàµà´¤àµ.</translation>
-<translation id="5843436854350372569">നിങàµà´™à´³àµâ€â€Œ <ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµâ€ à´Žà´¤àµà´¤à´¾à´¨àµâ€â€Œ à´¶àµà´°à´®à´¿à´šàµà´šàµ, പകàµà´·àµ† സെർവർ ഹാജരാകàµà´•à´¿à´¯ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿àµ½ à´¦àµàµ¼à´¬à´²à´®à´¾à´¯ കീ ഉൾപàµà´ªàµ†à´Ÿàµà´¨àµà´¨àµ. ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ à´¸àµà´µà´•à´¾à´°àµà´¯ കീ നശിപàµà´ªà´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•à´¾à´‚, കൂടാതെ സെർവർ നിങàµà´™àµ¾ à´ªàµà´°à´¤àµ€à´•àµà´·à´¿à´šàµà´š സെർവർ ആയിരികàµà´•à´¿à´²àµà´² (നിങàµà´™àµ¾ ആശയവിനിമയം നടതàµà´¤àµà´¨àµà´¨à´¤àµ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµà´®à´¾à´¯à´¿à´Ÿàµà´Ÿà´¾à´•à´¾à´‚). <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">à´ˆ സൈറàµà´±àµ ലഭàµà´¯à´®à´¾à´•àµà´•à´¾à´¨à´¾à´•àµà´¨àµà´¨à´¿à´²àµà´²</translation>
<translation id="5869522115854928033">സംരകàµà´·à´¿à´šàµà´š പാസàµâ€Œà´µàµ‡à´¡àµà´•à´³àµâ€</translation>
<translation id="5872918882028971132">പാരനàµà´±àµ നിർദàµà´¦àµ‡à´¶à´™àµà´™àµ¾</translation>
<translation id="5901630391730855834">മഞàµà´ž</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´šà´¤àµ)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ഒരെണàµà´£à´‚ ഉപയോഗതàµà´¤à´¿à´²àµà´£àµà´Ÿàµ}other{# à´Žà´£àµà´£à´‚ ഉപയോഗതàµà´¤à´¿à´²àµà´£àµà´Ÿàµ}}</translation>
<translation id="5926846154125914413">നിങàµà´™àµ¾à´•àµà´•àµ à´šà´¿à´² സൈറàµà´±àµà´•à´³à´¿àµ½ നിനàµà´¨àµà´³àµà´³ à´ªàµà´°àµ€à´®à´¿à´¯à´‚ ഉളàµà´³à´Ÿà´•àµà´•à´¤àµà´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ ആകàµâ€Œà´¸à´¸àµ നഷàµâ€Œà´Ÿà´®à´¾à´¯àµ‡à´•àµà´•à´¾à´‚.</translation>
<translation id="5959728338436674663">അപകടകരമായ ആപàµâ€Œà´¸àµà´•à´³àµà´‚ സൈറàµà´±àµà´•à´³àµà´‚ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¾àµ» സഹായികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµâ€Œ à´šà´¿à´² <ph name="BEGIN_WHITEPAPER_LINK" />സിസàµâ€Œà´±àµà´±à´‚ വിവരങàµà´™à´³àµà´‚ പേജàµâ€Œ ഉളàµà´³à´Ÿà´•àµà´•à´µàµà´‚<ph name="END_WHITEPAPER_LINK" /> Google-à´¨àµâ€Œ à´¸àµà´µà´¯à´®àµ‡à´µ അയയàµâ€Œà´•àµà´•àµà´•. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">ആഴàµâ€Œà´š</translation>
<translation id="5967867314010545767">à´šà´°à´¿à´¤àµà´°à´¤àµà´¤à´¿àµ½ നിനàµà´¨àµà´‚ നീകàµà´•à´‚ചെയàµà´¯àµà´•</translation>
<translation id="5975083100439434680">സൂം ഔടàµà´Ÿàµ</translation>
<translation id="598637245381783098">പേയàµâ€Œà´®àµ†à´¨àµà´±àµ ആപàµà´ªàµ à´¤àµà´±à´•àµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²</translation>
@@ -542,21 +602,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{പേജൠ1}other{പേജൠ#}}</translation>
<translation id="6017514345406065928">പചàµà´š</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµà´³àµà´³ à´…à´•àµà´°à´®à´¿à´•àµ¾, മറàµà´±àµ†à´¨àµà´¤àµ†à´™àµà´•à´¿à´²àµà´®à´¾à´£àµ†à´¨àµà´¨ à´µàµà´¯à´¾à´œàµ‡à´¨ തെറàµà´±à´¿à´¦àµà´§à´°à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨ ആപàµà´ªàµà´•àµ¾ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¾à´‚ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ ഡാറàµà´± ശേഖരിചàµà´šàµ നിങàµà´™à´³àµ† à´Ÿàµà´°à´¾à´•àµà´•àµà´šàµ†à´¯àµà´¯à´¾àµ» ഉപയോഗികàµà´•à´¾à´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´šà´¤àµ)</translation>
<translation id="6027201098523975773">ഒരൠപേരൠനൽകàµà´•</translation>
<translation id="6040143037577758943">à´…à´Ÿà´¯àµà´•àµà´•àµà´•</translation>
<translation id="6042308850641462728">കൂടàµà´¤àµ½</translation>
+<translation id="6047233362582046994">നിങàµà´™à´³àµà´Ÿàµ† à´¸àµà´°à´•àµà´·à´¯àµ† ബാധികàµà´•à´¾à´¨à´¿à´Ÿà´¯àµà´£àµà´Ÿàµ†à´¨àµà´¨àµ മനസàµà´¸à´¿à´²à´¾à´•àµà´•àµà´•à´¯à´¾à´£àµ†à´™àµà´•à´¿àµ½, ദോഷകരമായ ആപàµà´ªàµà´•àµ¾ നീകàµà´•à´‚ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´¨àµ à´®àµà´®àµà´ªàµ <ph name="BEGIN_LINK" />à´ˆ സൈറàµà´±àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´•<ph name="END_LINK" />.</translation>
+<translation id="6051221802930200923"><ph name="SITE" /> à´Žà´¨àµà´¨ വെബàµâ€Œà´¸àµˆà´±àµà´±àµ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ പിനàµà´¨à´¿à´‚ഗൠഉപയോഗികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ അതൠസനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´•à´®à´¾à´¯à´¿à´°à´¿à´•àµà´•àµà´‚, അതിനാൽ à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚.</translation>
<translation id="6060685159320643512">à´¶àµà´°à´¦àµà´§à´¿à´•àµà´•àµ‚, à´ˆ പരീകàµà´·à´£à´™àµà´™à´³àµâ€ പാളിയേകàµà´•à´¾à´‚†</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±àµ¼ നൽകിയ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ഉപയോഗിചàµà´šàµ നിങàµà´™àµ¾ ഉളàµà´³à´Ÿà´•àµà´•à´‚ ആകàµâ€Œà´¸à´¸àµà´¸àµà´šàµ†à´¯àµâ€Œà´¤àµ. നിങàµà´™àµ¾ <ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµ നൽകàµà´¨àµà´¨ ഡാറàµà´± à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±àµ¼à´•àµà´•àµ തടയാനാവàµà´‚.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠപാസàµâ€Œà´µàµ‡à´¡àµ (സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´šà´¤àµ)}other{# പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾ (സമനàµà´µà´¯à´¿à´ªàµà´ªà´¿à´šàµà´šà´¤àµ)}}</translation>
<translation id="6146055958333702838">à´Žà´²àµà´²à´¾ കേബിളàµà´•à´³àµà´‚ പരിശോധികàµà´•àµà´• à´’à´ªàµà´ªà´‚ à´à´¤àµ†à´™àµà´•à´¿à´²àµà´‚ റൂടàµà´Ÿà´±àµà´•àµ¾, മോഡങàµà´™àµ¾ നിങàµà´™àµ¾ ഉപയോഗികàµà´•à´¾à´¨à´¿à´Ÿà´¯àµà´³àµà´³
മറàµà´±àµ നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ ഉപകരണങàµà´™àµ¾ à´Žà´¨àµà´¨à´¿à´µ റീബൂടàµà´Ÿàµà´šàµ†à´¯àµà´¯àµà´•.</translation>
<translation id="614940544461990577">പരീകàµà´·à´¿à´šàµà´šàµà´¨àµ‹à´•àµà´•àµ‚:</translation>
<translation id="6151417162996330722">സെർവർ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ ദൈർഘàµà´¯à´®àµ‡à´±à´¿à´¯ ഒരൠകാലയളവൠഉണàµà´Ÿàµ.</translation>
<translation id="6157877588268064908">à´·à´¿à´ªàµà´ªà´¿à´‚ഗൠരീതികളàµà´‚ ആവശàµà´¯à´•à´¤à´•à´³àµà´‚ കാണാൻ ഒരൠവിലാസം തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•</translation>
+<translation id="6158003235852588289"><ph name="SITE" />-ൽ Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ ഫിഷിംഗൠകണàµà´Ÿàµ†à´¤àµà´¤à´¿. നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾àµ» ഫിഷിംഗൠസൈറàµà´±àµà´•àµ¾ മറàµà´±àµ വെബàµâ€Œà´¸àµˆà´±àµà´±àµà´•à´³à´¾à´¯à´¿ നടികàµà´•àµà´¨àµà´¨à´¤à´¾à´£àµ.</translation>
<translation id="6165508094623778733">കൂടàµà´¤àµ½â€ മനസിലാകàµà´•àµà´•</translation>
+<translation id="6169916984152623906">നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ à´¸àµà´µà´•à´¾à´°àµà´¯à´®à´¾à´¯à´¿ à´¬àµà´°àµ—സൠചെയàµà´¯à´¾à´‚, à´ˆ ഉപകരണം ഉപയോഗികàµà´•àµà´¨àµà´¨ മറàµà´±àµ ആളàµà´•àµ¾à´•àµà´•àµ നിങàµà´™à´³àµà´Ÿàµ† ആകàµâ€Œà´±àµà´±à´¿à´µà´¿à´±àµà´±à´¿ കാണാനാവിലàµà´². à´Žà´¨àµà´¨à´¾àµ½ ഡൗൺലോഡàµà´•à´³àµà´‚ à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´•à´³àµà´‚ സംരകàµà´·à´¿à´•àµà´•à´ªàµà´ªàµ†à´Ÿàµà´‚.</translation>
<translation id="6177128806592000436">à´ˆ സൈറàµà´±à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·àµ» à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²</translation>
<translation id="6184817833369986695">(സമാന വിഭാഗതàµà´¤à´¿àµ½à´ªàµà´ªàµ†à´Ÿàµà´Ÿà´µ: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">നിങàµà´™à´³àµà´Ÿàµ† ഇനàµà´±àµ¼à´¨àµ†à´±àµà´±àµ കണകàµà´·àµ» പരിശോധികàµà´•àµà´•</translation>
<translation id="6218753634732582820">Chromium-à´¤àµà´¤à´¿àµ½ നിനàµà´¨àµ വിലാസം നീകàµà´•à´‚ചെയàµà´¯à´£àµ‹?</translation>
+<translation id="6221345481584921695"><ph name="BEGIN_LINK" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ <ph name="END_LINK" />മാൽവെയർ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿<ph name="SITE" /> . സാധാരണ നിലയിൽ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯ വെബàµà´¸àµˆà´±àµà´±àµà´•à´³à´¿àµ½ ചിലപàµà´ªàµ‹àµ¾ മാൽവെയർ ഉണàµà´Ÿà´¾à´¯à´¿à´°à´¿à´•àµà´•à´¾à´‚. ഒരൠഅറിയപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ മാൽ‌വെയർ വിതരണകàµà´•à´¾à´°à´¾à´¯ <ph name="SUBRESOURCE_HOST" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ നിനàµà´¨à´¾à´£àµ ദോഷകരമായ ഉളàµà´³à´Ÿà´•àµà´•à´‚ വരàµà´¨àµà´¨à´¤àµ.</translation>
<translation id="6251924700383757765">à´¸àµà´µà´•à´¾à´°àµà´¯à´¤ നയം</translation>
<translation id="6254436959401408446">à´ˆ പേജൠതàµà´±à´•àµà´•à´¾àµ» മതിയായ മെമàµà´®à´±à´¿ ഇലàµà´²</translation>
<translation id="625755898061068298">നിങàµà´™àµ¾ à´ˆ സൈറàµà´±à´¿à´¨àµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ à´®àµà´¨àµà´¨à´±à´¿à´¯à´¿à´ªàµà´ªàµà´•àµ¾ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´°à´¹à´¿à´¤à´®à´¾à´•àµà´•à´¾àµ» തീരàµà´®à´¾à´¨à´¿à´šàµà´šàµ.</translation>
@@ -582,15 +650,14 @@
<translation id="6404511346730675251">à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµ à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" />-à´¨àµà´±àµ† കാലാവധി തീരàµà´¨àµà´¨ തീയതിയàµà´‚ CVC-à´¯àµà´‚ നൽകàµà´•</translation>
<translation id="6414888972213066896">à´ˆ സൈറàµà´±àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ നിങàµà´™àµ¾ à´°à´•àµà´·à´¿à´¤à´¾à´µà´¿à´¨àµ‹à´Ÿàµ à´…à´¨àµà´®à´¤à´¿ ആവശàµà´¯à´ªàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
-<translation id="6416403317709441254">Chrome-നൠപàµà´°àµ‹à´¸à´¸àµà´¸àµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´•à´¾à´¤àµà´¤ രൂപമാറàµà´±à´‚ വരàµà´¤àµà´¤à´¿à´¯ à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ വെബàµà´¸àµˆà´±àµà´±àµ അയയàµâ€Œà´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ <ph name="SITE" /> സൈറàµà´±àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´• à´ªàµà´°à´¶àµâ€Œà´¨à´™àµà´™à´³à´¾à´¯à´¤à´¿à´¨à´¾àµ½ à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ അസാധàµà´µà´¾à´•àµà´•à´¿à´¯àµ‹ à´Žà´¨àµà´¨àµ പരിശോധികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´¯à´¿à´²àµà´².</translation>
<translation id="6433490469411711332">കോൺടാകàµâ€Œà´±àµà´±àµ വിവരം à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> കണകàµâ€Œà´±àµà´±àµà´šàµ†à´¯àµà´¯àµ½ നിരസിചàµà´šàµ.</translation>
<translation id="6446608382365791566">കൂടàµà´¤àµ½ വിവരങàµà´™àµ¾ ചേർകàµà´•àµà´•</translation>
+<translation id="6447842834002726250">à´•àµà´•àµà´•à´¿à´•à´³àµâ€</translation>
<translation id="6451458296329894277">വീണàµà´Ÿàµà´‚ സമരàµâ€à´ªàµà´ªà´¿à´•àµà´•à´²àµâ€ അപേകàµà´· ഉറപàµà´ªà´¾à´•àµà´•àµà´•</translation>
<translation id="6456339708790392414">നിങàµà´™à´³àµà´Ÿàµ† പേയàµà´®àµ†à´¨àµà´±àµ</translation>
<translation id="6458467102616083041">à´¸àµà´¥à´¿à´°à´¸àµà´¥à´¿à´¤à´¿ തിരയൽ നയ à´ªàµà´°à´•à´¾à´°à´‚ ദൃശàµà´¯à´®à´¾à´¯à´¤à´¿à´¨à´¾àµ½ അവഗണികàµà´•à´ªàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
-<translation id="6462969404041126431">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ റദàµà´¦à´¾à´•àµà´•à´¿à´¯à´¿à´°à´¿à´•àµà´•à´¾à´‚. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">ഉപകരണ നയങàµà´™àµ¾</translation>
<translation id="6477321094435799029">Chrome, à´ˆ പേജിൽ അസാധാരണമായ കോഡൠകണàµà´Ÿàµ†à´¤àµà´¤à´¿à´¯à´¤à´¿à´¨à´¾àµ½ നിങàµà´™à´³àµà´Ÿàµ† à´µàµà´¯à´•àµà´¤à´¿à´—à´¤ വിവരങàµà´™àµ¾ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, പാസàµâ€Œà´µàµ‡à´¡àµà´•à´³àµà´‚ ഫോൺ നമàµà´ªà´±àµà´•à´³àµà´‚ à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•à´³àµà´‚ പോലàµà´³àµà´³à´µ) പരിരകàµà´·à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ അതിനെ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ.</translation>
<translation id="6489534406876378309">à´•àµà´°à´¾à´·àµà´•àµ¾ à´…à´ªàµâ€Œà´²àµ‹à´¡àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ ആരംഭികàµà´•àµà´•</translation>
@@ -602,20 +669,19 @@
<translation id="6556915248009097796">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ തീയതി: <ph name="EXPIRATION_DATE_ABBR" />, <ph name="LAST_USED_DATE_NO_DETAIL" />-നൠഅവസാനമായി ഉപയോഗിചàµà´šàµ</translation>
<translation id="6563469144985748109">നിങàµà´™à´³àµà´Ÿàµ† മാനേജർ ഇതàµà´µà´°àµ† അംഗീകാരം നൽകിയിടàµà´Ÿà´¿à´²àµà´²</translation>
<translation id="6569060085658103619">നിങàµà´™àµ¾ ഒരൠവിപàµà´²àµ€à´•à´°à´£ പേജാണൠകാണàµà´¨àµà´¨à´¤àµ</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" />-യിൽ താഴെ</translation>
+<translation id="657639383826808334">à´ˆ ഉളàµà´³à´Ÿà´•àµà´•à´‚, നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•àµà´•à´¯àµ‹ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•àµà´¯àµ‹ ചെയàµà´¯àµà´¨àµà´¨ തരതàµà´¤à´¿à´²àµà´³àµà´³ സോഫàµâ€Œà´±àµà´±àµâ€Œà´µàµ†à´¯à´±àµà´•àµ¾ ഉപകരണതàµà´¤à´¿àµ½ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾à´šàµ†à´¯àµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´•àµà´•à´¾à´¨à´¿à´Ÿà´¯àµà´£àµà´Ÿàµ. <ph name="BEGIN_LINK" />à´Žà´¨àµà´¤à´¾à´¯à´¾à´²àµà´‚ കാണികàµà´•àµà´•<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">എൻകàµà´°à´¿à´ªàµâ€Œà´·àµ» à´“à´ªàµâ€Œà´·à´¨àµà´•àµ¾</translation>
<translation id="662080504995468778">à´¤àµà´Ÿà´°àµà´•</translation>
<translation id="6626291197371920147">ശരിയായ കാർഡൠനമàµà´ªàµ¼ ചേർകàµà´•àµà´•</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> തിരയൽ</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨ സൈറàµà´±à´¿à´²àµ† നിലവിലàµà´³àµà´³ ആകàµà´°à´®à´¿à´•àµ¾ നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•à´¾à´¨àµ‹ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾à´¨àµ‹ ഇടയàµà´³àµà´³ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, ഫോടàµà´Ÿàµ‹à´•àµ¾, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ à´®àµà´¤à´²à´¾à´¯à´µ) അപകടകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ Mac-ൽ ഇൻസàµâ€Œà´±àµà´±à´¾à´³àµà´šàµ†à´¯àµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">à´ˆ നയം ഒഴിവാകàµà´•à´¿.</translation>
-<translation id="6652240803263749613">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† à´“à´ªàµà´ªà´±àµ‡à´±àµà´±à´¿à´‚ഗൠസിസàµà´±àµà´±à´‚ വിശàµà´µà´¸à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Chromium-à´¤àµà´¤à´¿àµ½ നിനàµà´¨àµ ഫോം നിർദàµà´¦àµ‡à´¶à´‚ നീകàµà´•à´‚ചെയàµà´¯à´£àµ‹?</translation>
<translation id="6685834062052613830">സൈൻ ഔടàµà´Ÿàµ ചെയàµâ€Œà´¤àµ, സജàµà´œà´®à´¾à´•àµà´•àµ½ പൂർതàµà´¤à´¿à´¯à´¾à´•àµà´•àµà´•</translation>
<translation id="6710213216561001401">à´•à´´à´¿à´žàµà´ž</translation>
<translation id="6710594484020273272">&lt;തിരയൽ പദം നൽകàµà´•&gt;</translation>
<translation id="6711464428925977395">à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സെർവറിൽ à´Žà´¨àµà´¤àµ‹ à´ªàµà´°à´¶àµâ€Œà´¨à´®àµà´£àµà´Ÿàµ, à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ വിലാസം തെറàµà´±à´¾à´£àµ.</translation>
<translation id="6727102863431372879">സജàµà´œà´®à´¾à´•àµà´•àµà´•</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠഇനം}other{# ഇനങàµà´™àµ¾}}</translation>
<translation id="674375294223700098">അറിയപàµà´ªàµ†à´Ÿà´¾à´¤àµà´¤ സെരàµâ€à´µà´°àµâ€ സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ പിശകàµ.</translation>
<translation id="6753269504797312559">നയ മൂലàµà´¯à´‚</translation>
<translation id="6757797048963528358">നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണം à´¸àµà´·àµà´ªàµâ€Œà´¤à´¿à´¯à´¿à´²à´¾à´¯à´¿.</translation>
@@ -623,6 +689,8 @@
<translation id="6810899417690483278">ഇഷàµâ€Œà´Ÿà´¾à´¨àµà´¸àµƒà´¤à´®à´¾à´•àµà´•àµ½ à´à´¡à´¿</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">à´ªàµà´°à´¦àµ‡à´¶à´™àµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ ലോഡàµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´¯à´¿à´²àµà´²</translation>
+<translation id="6825578344716086703">നിങàµà´™àµ¾ <ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ à´Žà´¤àµà´¤à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ, പകàµà´·àµ‡ ഒരൠദàµàµ¼à´¬à´²à´®à´¾à´¯ സിഗàµâ€Œà´¨àµ‡à´šàµà´šàµ¼ അൽഗോരിതം ഉപയോഗിചàµà´šàµ à´’à´ªàµà´ªà´¿à´Ÿàµà´Ÿ ഒരൠസർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ സെർവർ നൽകി. ഇതിനർതàµà´¥à´‚ സെർവർ നൽകിയ à´¸àµà´°à´•àµà´·à´¾ à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ à´µàµà´¯à´¾à´œà´®à´¾à´•à´¾à´®àµ†à´¨àµà´¨àµà´‚ നിങàµà´™àµ¾ ഉദàµà´¦àµ‡à´¶à´¿à´šàµà´š സെർവർ ആയിരികàµà´•à´¿à´²àµà´² à´Žà´¨àµà´¨àµà´®à´¾à´£àµ (നിങàµà´™àµ¾ ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµà´®à´¾à´¯à´¿à´Ÿàµà´Ÿà´¾à´•à´¾à´‚ ആശയവിനിമയം നടതàµà´¤àµà´¨àµà´¨à´¤àµ).</translation>
+<translation id="6830728435402077660">à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²</translation>
<translation id="6831043979455480757">വിവർതàµà´¤à´¨à´‚ ചെയàµà´¯àµà´•</translation>
<translation id="6839929833149231406">à´à´°à´¿à´¯</translation>
<translation id="6874604403660855544">&amp;ചേർകàµà´•àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
@@ -630,6 +698,7 @@
<translation id="6895330447102777224">നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠസàµà´¥à´¿à´°àµ€à´•à´°à´¿à´šàµà´šàµ</translation>
<translation id="6897140037006041989">ഉപയോകàµà´¤àµƒ à´à´œà´¨àµâ€à´±àµ</translation>
<translation id="6915804003454593391">ഉപയോകàµà´¤à´¾à´µàµ:</translation>
+<translation id="6945221475159498467">തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•</translation>
<translation id="6948701128805548767">പികàµà´•àµà´…à´ªàµà´ªàµ രീതികളàµà´‚ ആവശàµà´¯à´•à´¤à´•à´³àµà´‚ കാണാൻ ഒരൠവിലാസം തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•</translation>
<translation id="6957887021205513506">സെർവറിനàµà´±àµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ വിശàµà´µà´¸à´¿à´•àµà´•à´¾àµ» കൊളàµà´³à´¾à´¤àµà´¤ à´’à´¨àµà´¨à´¾à´¯à´¿ തോനàµà´¨àµà´¨àµà´¨àµ.</translation>
<translation id="6965382102122355670">ശരി</translation>
@@ -638,15 +707,16 @@
<translation id="6973656660372572881">à´¸àµà´¥à´¿à´°à´®à´¾à´¯ à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ സെർവറàµà´•à´³àµà´‚ ഒരൠസàµâ€Œà´•àµà´°à´¿à´ªàµà´±àµà´±àµ URL-ഉം à´µàµà´¯à´•àµà´¤à´®à´¾à´•àµà´•à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ.</translation>
<translation id="6989763994942163495">വിപàµà´²à´®à´¾à´¯ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾ കാണികàµà´•àµà´•...</translation>
<translation id="7000990526846637657">à´šà´°à´¿à´¤àµà´° എൻടàµà´°à´¿à´•à´³àµŠà´¨àµà´¨àµà´‚ à´•à´£àµà´Ÿà´¿à´²àµà´²</translation>
-<translation id="7009986207543992532">നിങàµà´™àµ¾ <ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¿àµ½ à´Žà´¤àµà´¤à´¿à´šàµà´šàµ‡à´°à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ†à´™àµà´•à´¿à´²àµà´‚, വിശàµà´µà´¾à´¸à´¯àµ‹à´—àµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤ തരതàµà´¤à´¿àµ½ ദൈർഘàµà´¯à´®àµ‡à´±à´¿à´¯ സാധàµà´¤à´¾ കാലയളവàµà´³àµà´³ ഒരൠസർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ സെർവർ നൽകി. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">ചൈന UnionPay</translation>
<translation id="7012372675181957985">നിങàµà´™à´³àµà´Ÿàµ† Google à´…à´•àµà´•àµ—à´£àµà´Ÿà´¿à´¨àµ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ മറàµà´±àµ തരതàµà´¤à´¿à´²àµà´³àµà´³ à´¬àµà´°àµ—സിംഗൠചരിതàµà´°à´®àµà´£àµà´Ÿà´¾à´¯à´¿à´°à´¿à´•àµà´•à´¾à´‚</translation>
<translation id="7029809446516969842">പാസàµâ€Œà´µàµ‡à´¡àµà´•à´³àµâ€</translation>
+<translation id="7050187094878475250">നിങàµà´™àµ¾ <ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ†à´¤àµà´¤à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ, à´Žà´¨àµà´¨à´¾àµ½ തീരെ വിശàµà´µà´¾à´¸à´¯àµ‹à´—àµà´¯à´®à´²àµà´²à´¾à´¤àµà´¤ ഒരൠകാലാവധിയàµà´³àµà´³ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¾à´£àµ സെർവർ കാണികàµà´•àµà´¨àµà´¨à´¤àµ.</translation>
+<translation id="7053983685419859001">തടയàµà´•</translation>
<translation id="7064851114919012435">കോണàµâ€à´Ÿà´¾à´•àµà´±àµà´±àµ വിവരം</translation>
<translation id="7079718277001814089">à´ˆ സൈറàµà´±à´¿àµ½ മാൽവെയർ à´…à´Ÿà´™àµà´™à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
<translation id="7087282848513945231">രാജàµà´¯à´‚</translation>
-<translation id="7088615885725309056">വളരെ പഴയ</translation>
<translation id="7090678807593890770">Google-ൽ <ph name="LINK" /> തിരയàµà´•</translation>
+<translation id="7108819624672055576">ഒരൠവിപàµà´²àµ€à´•à´°à´£à´‚ à´®àµà´–േന അവദിചàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
<translation id="7119414471315195487">മറàµà´±àµ ടാബàµà´•à´³àµ‹ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•à´³àµ‹ à´…à´Ÿà´¯àµâ€Œà´•àµà´•àµà´•</translation>
<translation id="7129409597930077180">à´ˆ വിലാസതàµà´¤à´¿à´²àµ‡à´•àµà´•àµ à´·à´¿à´ªàµà´ªàµ ചെയàµà´¯à´¾àµ» കഴിയിലàµà´². മറàµà´±àµŠà´°àµ വിലാസം തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•.</translation>
<translation id="7138472120740807366">ഡെലിവറി രീതി</translation>
@@ -664,22 +734,18 @@
<translation id="7220786058474068424">à´ªàµà´°àµ‹à´¸à´¸àµà´¸àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨àµ</translation>
<translation id="724691107663265825">സൈറàµà´±à´¿àµ½ മാൽവെയർ à´…à´Ÿà´™àµà´™à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
<translation id="724975217298816891">നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠവിശദാംശങàµà´™àµ¾ à´…à´ªàµâ€Œà´¡àµ‡à´±àµà´±àµà´šàµ†à´¯àµà´¯à´¾àµ» <ph name="CREDIT_CARD" />-à´¨àµà´±àµ† കാലാവധി തീരàµà´¨àµà´¨ തീയതിയàµà´‚ CVC-à´¯àµà´‚ നൽകàµà´•. à´¸àµà´¥à´¿à´°àµ€à´•à´°à´¿à´šàµà´šàµ à´•à´´à´¿à´žàµà´žà´¾àµ½, à´ˆ സൈറàµà´±àµà´®à´¾à´¯à´¿ കാർഡൠവിശദാംശങàµà´™àµ¾ പങàµà´•à´¿à´Ÿàµà´‚.</translation>
-<translation id="725866823122871198">നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿à´¨àµà´±àµ† തീയതിയàµà´‚ സമയവàµà´‚ (<ph name="DATE_AND_TIME" />) തെറàµà´±à´¾à´¯à´¤à´¿à´¨à´¾àµ½ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ à´¸àµà´µà´•à´¾à´°àµà´¯ കണകàµà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•à´¾à´¨à´¾à´µà´¿à´²àµà´².</translation>
+<translation id="7260504762447901703">ആകàµâ€Œà´¸à´¸àµà´¸àµ റദàµà´¦à´¾à´•àµà´•àµà´•</translation>
<translation id="7275334191706090484">നിയനàµà´¤àµà´°à´¿à´¤ à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´•àµ¾</translation>
<translation id="7298195798382681320">à´¶àµà´ªà´¾àµ¼à´¶à´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" />-നൠകàµà´¯à´¾à´ªàµâ€Œà´šàµ¼ ചെയàµâ€Œà´¤ à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµà´•àµ¾ (ഉപയോകàµà´¤à´¾à´µàµ à´…à´­àµà´¯àµ¼à´¤àµà´¥à´¿à´šàµà´š à´…à´ªàµâ€Œà´²àµ‹à´¡àµ, ഇതàµà´µà´°àµ† à´…à´ªàµâ€Œà´²àµ‹à´¡àµà´šàµ†à´¯àµâ€Œà´¤à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²)</translation>
<translation id="7334320624316649418">&amp;à´ªàµà´¨à´ƒà´•àµà´°à´®àµ€à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
<translation id="733923710415886693">സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ à´¸àµà´¤à´¾à´°àµà´¯à´¤à´¯à´¿à´²àµ‚ടെ സെർവറàµà´Ÿàµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ വെളിപàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¿à´¯à´¿à´Ÿàµà´Ÿà´¿à´²àµà´².</translation>
-<translation id="7351800657706554155"><ph name="SITE" /> സൈറàµà´±à´¿à´¨àµà´±àµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ റദàµà´¦à´¾à´•àµà´•à´¿à´¯à´¤à´¿à´¨à´¾àµ½ നിങàµà´™àµ¾à´•àµà´•à´¿à´ªàµà´ªàµ‹àµ¾ ഇതൠസനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¿à´²àµà´². നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ പിശകàµà´•à´³àµà´‚ ആകàµà´°à´®à´£à´™àµà´™à´³àµà´‚ സാധാരണയായി താൽകàµà´•à´¾à´²à´¿à´• à´ªàµà´°à´¶àµâ€Œà´¨à´™àµà´™à´³à´¾à´¯à´¤à´¿à´¨à´¾àµ½, à´ˆ പേജൠമികàµà´•à´µà´¾à´±àµà´‚ പിനàµà´¨àµ€à´Ÿàµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¿à´•àµà´•àµà´‚. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">കമാനàµâ€à´±àµ ലൈനàµâ€â€Œ</translation>
<translation id="7372973238305370288">തിരയൽ ഫലം</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">വേണàµà´Ÿ</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">കാർഡൠസàµà´¥à´¿à´°àµ€à´•à´°à´¿à´•àµà´•àµà´•</translation>
-<translation id="7394102162464064926">നിങàµà´™à´³àµà´Ÿàµ† à´šà´°à´¿à´¤àµà´°à´¤àµà´¤à´¿àµ½ നിനàµà´¨àµ à´ˆ പേജàµà´•àµ¾ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•à´£à´®àµ†à´¨àµà´¨àµ തീർചàµà´šà´¯à´¾à´£àµ‹?
-
-à´¶àµà´°à´¦àµà´§à´¿à´•àµà´•àµ‚! ആൾമാറാടàµà´Ÿ മോഡൠ<ph name="SHORTCUT_KEY" /> à´…à´Ÿàµà´¤àµà´¤ തവണ കൈകാരàµà´¯à´‚ ചെയàµà´¯àµà´¨àµà´¨à´¤àµ à´Žà´³àµà´ªàµà´ªà´®àµà´³àµà´³à´¤à´¾à´•à´¾à´¨à´¿à´Ÿà´¯àµà´£àµà´Ÿàµ.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">à´ªàµà´°àµŠà´«àµˆàµ½ പാത</translation>
<translation id="7424977062513257142">à´ˆ വെബàµâ€Œà´¸àµˆà´±àµà´±à´¿à´²àµ† ഒരൠഎംബഡൠചെയàµâ€Œà´¤ പേജൠപറയàµà´¨àµà´¨à´¤àµ:</translation>
@@ -687,6 +753,7 @@
<translation id="7444046173054089907">à´ˆ സൈറàµà´±àµ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="7445762425076701745">നിങàµà´™à´³àµâ€ ബനàµà´§à´¿à´ªàµà´ªà´¿à´šàµà´š സെരàµâ€à´µà´±à´¿à´¨àµâ€à´±àµ† à´à´¡à´¨àµâ€à´±à´¿à´±àµà´±à´¿ പൂരàµâ€à´£àµà´£à´®à´¾à´¯à´¿ സാധൂകരികàµà´•à´¾à´¨àµâ€ കഴിയിലàµà´². നിങàµà´™à´³àµà´Ÿàµ† നെറàµà´±àµâ€à´µà´°àµâ€à´•àµà´•à´¿à´²àµâ€ മാതàµà´°à´‚ സാധàµà´µà´¾à´¯ ഒരൠനാമം ഉപയോഗികàµà´•àµà´¨àµà´¨ സെരàµâ€à´µà´±à´¿à´²àµ‡à´•àµà´•àµ നിങàµà´™à´³àµâ€ ബനàµà´§à´¿à´ªàµà´ªà´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ, അതിനàµâ€à´±àµ† ഉടമസàµà´¥à´¾à´µà´•à´¾à´¶à´‚ ഒരൠബാഹàµà´¯ അതോറിറàµà´±à´¿à´¯àµà´•àµà´•àµ à´’à´°à´¿à´•àµà´•à´²àµà´‚ സാധൂകരികàµà´•à´¾à´¨àµâ€ കഴിയിലàµà´². à´šà´¿à´² സാകàµâ€à´·àµà´¯à´ªà´¤àµà´° അതോറിറàµà´±à´¿à´•à´³àµâ€ à´ˆ നാമങàµà´™à´³àµ† കണകàµà´•à´¾à´•àµà´•à´¾à´¤àµ† സാകàµâ€à´·àµà´¯à´ªà´¤àµà´°à´™àµà´™à´³àµâ€ നലàµâ€à´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµâ€, ഉദàµà´¦àµ‡à´¶à´¿à´šàµà´š വെബàµà´¸àµˆà´±àµà´±à´¿à´²àµ‡à´•àµà´•à´¾à´£àµ നിങàµà´™à´³àµâ€ ബനàµà´§à´¿à´ªàµà´ªà´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤àµ†à´¨àµà´¨àµà´‚ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯à´²àµà´²àµ†à´¨àµà´¨àµà´‚ ഉറപàµà´ªà´¾à´•àµà´•à´¾à´¨àµâ€ ഒരൠമാരàµâ€à´—àµà´—à´µàµà´®à´¿à´²àµà´².</translation>
<translation id="7451311239929941790">à´ˆ à´ªàµà´°à´¶àµâ€Œà´¨à´¤àµà´¤àµ†à´•àµà´•àµà´±à´¿à´šàµà´šàµ <ph name="BEGIN_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´¨àµà´¨àµ<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">à´—àµà´²àµ‹à´¬àµ½ ഡിഫോൾടàµà´Ÿàµ ഉപയോഗികàµà´•àµà´• (തടയàµà´•)</translation>
<translation id="7460163899615895653">മറàµà´±àµ ഉപകരണങàµà´™à´³à´¿àµ½ നിനàµà´¨àµà´³àµà´³ à´…à´Ÿàµà´¤àµà´¤à´¿à´Ÿàµ†à´¯àµà´³àµà´³ നിങàµà´™à´³àµà´Ÿàµ† ടാബàµà´•àµ¾ ഇവിടെ ദൃശàµà´¯à´®à´¾à´•àµà´‚</translation>
<translation id="7469372306589899959">കാർഡൠസàµà´¥à´¿à´°àµ€à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
<translation id="7481312909269577407">à´®àµà´¨àµà´¨àµ‹à´Ÿàµà´Ÿàµ</translation>
@@ -694,36 +761,43 @@
<translation id="7508255263130623398">നൽകിയ നയ ഉപകരണ à´à´¡à´¿ ശൂനàµà´¯à´®à´¾à´£àµ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ നിലവിലെ ഉപകരണ à´à´¡à´¿à´¯àµà´®à´¾à´¯à´¿ യോജികàµà´•àµà´¨àµà´¨à´¿à´²àµà´²</translation>
<translation id="7514365320538308">ഡൗൺലോഡàµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="7518003948725431193">വെബൠവിലാസതàµà´¤à´¿à´¨à´¾à´¯à´¿ വെബàµâ€Œà´ªàµ‡à´œàµŠà´¨àµà´¨àµà´‚ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿à´¯à´¿à´²àµà´²: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">മൂലàµà´¯à´‚</translation>
<translation id="7537536606612762813">നിർബനàµà´§à´¿à´¤à´‚</translation>
+<translation id="7542403920425041731">à´¸àµà´¥à´¿à´°àµ€à´•à´°à´¿à´šàµà´šàµà´•à´´à´¿à´žàµà´žà´¾àµ½, നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠവിശദാംശങàµà´™àµ¾ à´ˆ സൈറàµà´±àµà´®à´¾à´¯à´¿ പങàµà´•à´¿à´Ÿàµà´‚.</translation>
<translation id="7542995811387359312">à´ˆ ഫോം ഒരൠസàµà´°à´•àµà´·à´¿à´¤ കണകàµà´·à´¨àµâ€ ഉപയോഗികàµà´•à´¾à´¤àµà´¤à´¤à´¿à´¨à´¾à´²àµâ€ à´¸àµà´µà´ªàµà´°àµ‡à´°à´¿à´¤ à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാരàµâ€à´¡àµ പൂരിപàµà´ªà´¿à´•àµà´•à´²àµâ€ à´…à´ªàµà´°à´¾à´ªàµà´¤à´®à´¾à´•àµà´•à´¿.</translation>
<translation id="7543525346216957623">നിങàµà´™à´³àµà´Ÿàµ† à´°à´•àµà´·à´¿à´¤à´¾à´µà´¿à´¨àµ‹à´Ÿàµâ€Œ ആവശàµà´¯à´ªàµà´ªàµ†à´Ÿàµà´•</translation>
<translation id="7549584377607005141">ശരിയായി à´ªàµà´°à´¦àµ¼à´¶à´¿à´ªàµà´ªà´¿à´•àµà´•à´¾àµ» à´ˆ വെബàµâ€Œ പേജിനൠനിങàµà´™àµ¾ à´®àµà´®àµà´ªàµ നൽകിയ ഡാറàµà´± ആവശàµà´¯à´®à´¾à´£àµ. നിങàµà´™àµ¾à´•àµà´•àµ à´ˆ ഡാറàµà´± വീണàµà´Ÿàµà´‚ അയയàµâ€Œà´•àµà´•à´¾à´¨à´¾à´•àµà´®àµ†à´™àµà´•à´¿à´²àµà´‚, à´…à´™àµà´™à´¨àµ† ചെയàµà´¯àµà´¨àµà´¨à´¤àµ à´ˆ പേജിൽ à´®àµà´®àµà´ªàµ ചെയàµâ€Œà´¤ à´à´¤àµ à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´µàµà´‚ നിങàµà´™àµ¾à´•àµà´•àµ ആവർതàµà´¤à´¿à´•àµà´•àµ‡à´£àµà´Ÿà´¤à´¾à´¯à´¿ വരàµà´‚.</translation>
<translation id="7552846755917812628">ഇനിപàµà´ªà´±à´¯àµà´¨àµà´¨ à´¨àµà´±àµà´™àµà´™àµà´•àµ¾ പരീകàµà´·à´¿à´•àµà´•àµ‚:</translation>
<translation id="7554791636758816595">à´ªàµà´¤à´¿à´¯ ടാബàµ</translation>
+<translation id="7567204685887185387">à´ˆ സെർവറിനൠഅതൠ<ph name="DOMAIN" /> ആണെനàµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; സെർവറിനàµà´±àµ† à´¸àµà´°à´•àµà´· സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ വഞàµà´šà´¨à´¾à´ªà´°à´®à´¾à´¯à´¿ ഇഷàµà´¯àµ‚ ചെയàµâ€Œà´¤à´¿à´°à´¿à´•àµà´•à´¾à´‚. തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠഅകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ കൊണàµà´Ÿàµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> à´Žà´£àµà´£à´µàµà´‚}other{<ph name="CONTACT_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> à´Žà´£àµà´£à´µàµà´‚}}</translation>
<translation id="7568593326407688803">à´ˆ പേജàµ<ph name="ORIGINAL_LANGUAGE" />ലാണൠനിങàµà´™à´³à´¤àµ വിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ ചെയàµà´¯à´¾à´¨àµâ€â€Œ താലàµâ€â€Œà´ªàµà´ªà´°àµà´¯à´ªàµà´ªàµ†à´Ÿàµà´¨àµà´¨àµ‹?</translation>
<translation id="7569952961197462199">Chrome-ൽ നിനàµà´¨àµ à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡൠനീകàµà´•à´‚ചെയàµà´¯à´£àµ‹?</translation>
<translation id="7569983096843329377">à´•à´±àµà´ªàµà´ªàµ</translation>
<translation id="7578104083680115302">നിങàµà´™àµ¾ Google-ൽ സംരകàµà´·à´¿à´šàµà´š കാർഡàµà´•àµ¾ ഉപയോഗിചàµà´šàµ ഉപകരണങàµà´™à´³à´¿à´²àµà´Ÿà´¨àµ€à´³à´®àµà´³àµà´³ സൈറàµà´±àµà´•à´³à´¿à´²àµà´‚ ആപàµâ€Œà´¸à´¿à´²àµà´‚ പെടàµà´Ÿàµ†à´¨àµà´¨àµ പണമടയàµâ€Œà´•àµà´•àµà´•.</translation>
<translation id="7588950540487816470">ഫിസികàµà´•àµ½ വെബàµ</translation>
<translation id="7592362899630581445">സെർവറിനàµà´±àµ† സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ പേരിനàµà´±àµ† പരിധി ലംഘികàµà´•àµà´¨àµà´¨àµ.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" />-യിൽ താഴെ</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" />-നൠനിലവിൽ à´ˆ à´…à´­àµà´¯àµ¼à´¤àµà´¥à´¨ കൈകാരàµà´¯à´‚ ചെയàµà´¯à´¾à´¨à´¾à´•àµà´¨àµà´¨à´¿à´²àµà´².</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> à´’à´°à´¿à´•àµà´•à´²àµà´‚ വിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ ചെയàµà´¯à´°àµà´¤àµ</translation>
<translation id="7610193165460212391">മൂലàµà´¯à´‚ പരിധികàµà´•àµ à´ªàµà´±à´¤àµà´¤à´¾à´£àµ <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨à´¤àµ: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">നിങàµà´™àµ¾à´•àµà´•àµ ഇതിനകം കൈവശമàµà´³àµà´³ എൻകàµà´°à´¿à´ªàµâ€Œà´±àµà´±àµ ചെയàµà´¤ ഡാറàµà´± നിങàµà´™à´³àµà´Ÿàµ† Google à´…à´•àµà´•àµ—à´£àµà´Ÿàµ പാസàµâ€Œà´µàµ‡à´¡à´¿à´¨àµà´±àµ† ഒരൠവàµà´¯à´¤àµà´¯à´¸àµà´¤ പതിപàµà´ªàµ ഉപയോഗികàµà´•àµà´¨àµà´¨àµ. ദയവായി അതൠതാഴെ നൽകàµà´•.</translation>
-<translation id="7634554953375732414">à´ˆ സൈറàµà´±à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·àµ» à´¸àµà´µà´•à´¾à´°àµà´¯à´®à´²àµà´².</translation>
<translation id="7637571805876720304">Chromium-à´¤àµà´¤à´¿àµ½ നിനàµà´¨àµ à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡൠനീകàµà´•à´‚ചെയàµà´¯à´£àµ‹?</translation>
<translation id="765676359832457558">വിപàµà´²à´®à´¾à´¯ à´•àµà´°à´®àµ€à´•à´°à´£à´™àµà´™àµ¾ മറയàµâ€Œà´•àµà´•àµà´•...</translation>
<translation id="7658239707568436148">റദàµà´¦à´¾à´•àµà´•àµ‚</translation>
+<translation id="7662298039739062396">à´•àµà´°à´®àµ€à´•à´°à´£à´‚ ഒരൠവിപàµà´²àµ€à´•à´°à´£à´‚ à´®àµà´–േന നിയനàµà´¤àµà´°à´¿à´šàµà´šà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ</translation>
<translation id="7667346355482952095">നൽകിയ നയ ടോകàµà´•àµº ശൂനàµà´¯à´®à´¾à´£àµ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ നിലവിലെ ടോകàµà´•à´£àµà´®à´¾à´¯à´¿ യോജികàµà´•àµà´¨àµà´¨à´¿à´²àµà´²</translation>
<translation id="7668654391829183341">à´…à´œàµà´žà´¾à´¤à´®à´¾à´¯ ഉപകരണം</translation>
<translation id="7669271284792375604">à´ˆ സൈറàµà´±à´¿à´²àµ† ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµ¾, à´¬àµà´°àµ—സർ à´…à´¨àµà´­à´µà´¤àµà´¤àµ† ദോഷകരമായി ബാധികàµà´•àµà´¨àµà´¨ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ ഇൻസàµâ€Œà´±àµà´±à´¾àµ¾ ചെയàµà´¯à´¿à´•àµà´•àµà´¨àµà´¨ വിധതàµà´¤à´¿àµ½ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•àµà´‚ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, നിങàµà´™à´³àµà´Ÿàµ† ഹോംപേജൠമാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµ‚ടെയോ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´¨àµà´¨ സൈറàµà´±àµà´•à´³à´¿àµ½ കൂടàµà´¤àµ½ പരസàµà´¯à´™àµà´™àµ¾ കാണികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµ‚ടെയോ).</translation>
<translation id="7674629440242451245">à´ªàµà´¤à´¿à´¯ Chrome-à´¨àµà´±àµ† രസകരമായ സവിശേഷതകളിൽ താൽപàµà´ªà´°àµà´¯à´®àµà´£àµà´Ÿàµ‹? chrome.com/dev-ൽ à´žà´™àµà´™à´³àµà´Ÿàµ† ഡെവലപàµà´ªàµ¼ ചാനൽ പരീകàµà´·à´¿à´šàµà´šàµà´¨àµ‹à´•àµà´•àµà´•.</translation>
<translation id="7682287625158474539">à´·à´¿à´ªàµà´ªà´¿à´‚à´—àµ</translation>
+<translation id="7701040980221191251">à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /> <ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµ പോകàµà´• (à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">സരàµâ€â€Œà´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ</translation>
+<translation id="7716147886133743102">നിങàµà´™à´³àµà´Ÿàµ† അ‌ഡàµâ€Œà´®à´¿à´¨à´¿â€Œà´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±àµ¼ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="7716424297397655342">à´ˆ സൈറàµà´±àµ കാഷെയിൽ നിനàµà´¨àµ ലോഡàµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´•à´¿à´²àµà´²</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">നിയനàµà´¤àµà´°à´¿à´•àµà´•à´¾à´¨à´¾à´•à´¾à´¤àµà´¤à´¤àµ</translation>
<translation id="7755287808199759310">നിങàµà´™àµ¾à´•àµà´•àµ വേണàµà´Ÿà´¿ ഇതൠഅൺബàµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµà´¯à´¾àµ» à´°à´•àµà´·à´¿à´¤à´¾à´µà´¿à´¨àµ à´•à´´à´¿à´¯àµà´‚</translation>
<translation id="7758069387465995638">ഫയർവാളോ ആനàµà´±à´¿ വൈറസൠസോഫàµâ€Œà´±àµà´±àµâ€Œà´µàµ†à´¯à´±àµ‹ കണകàµà´·àµ» à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤à´¿à´Ÿàµà´Ÿàµà´£àµà´Ÿà´¾à´•à´¾à´‚.</translation>
@@ -750,15 +824,15 @@
<translation id="7951415247503192394">(32-ബിറàµà´±àµ)</translation>
<translation id="7956713633345437162">മൊബൈൽ à´¬àµà´•àµà´•àµâ€Œà´®à´¾àµ¼à´•àµà´•àµà´•àµ¾</translation>
<translation id="7961015016161918242">à´’à´°à´¿à´•àµà´•à´²àµà´‚</translation>
-<translation id="7962083544045318153">à´•àµà´°à´¾à´·àµ à´à´¡à´¿, <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">à´Žà´²àµà´²à´¾à´¯àµâ€Œà´ªàµà´ªàµ‹à´´àµà´‚ <ph name="ORIGINAL_LANGUAGE" /> നെ <ph name="TARGET_LANGUAGE" /> ലേകàµà´•àµ വിവർതàµà´¤à´¨à´‚ ചെയàµà´¯àµà´•</translation>
<translation id="7995512525968007366">à´µàµà´¯à´•àµà´¤à´®à´¾à´•àµà´•à´¿à´¯à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²</translation>
<translation id="800218591365569300">ഇടം സൃഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾àµ» മറàµà´±àµ ടാബàµà´•à´³àµ‹ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•à´³àµ‹ à´…à´Ÿà´¯àµâ€Œà´•àµà´•àµà´¨àµà´¨à´¤àµ പരീകàµà´·à´¿à´•àµà´•àµ‚.</translation>
<translation id="8012647001091218357">ഇപàµà´ªàµ‹àµ¾ à´žà´™àµà´™àµ¾à´•àµà´•àµ നിങàµà´™à´³àµà´Ÿàµ† à´°à´•àµà´·à´•àµ¼à´¤àµà´¤à´¾à´•àµà´•à´³àµ† ബനàµà´§à´ªàµà´ªàµ†à´Ÿà´¾à´¨à´¾à´¯à´¿à´²àµà´². വീണàµà´Ÿàµà´‚ à´¶àµà´°à´®à´¿à´•àµà´•àµà´•.</translation>
<translation id="8025119109950072390">à´ˆ സൈറàµà´±à´¿à´²àµ† ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµ¾ സോഫàµâ€Œà´±àµà´±àµâ€Œà´µàµ†à´¯àµ¼ ഇൻസàµà´±àµà´±à´¾àµ¾ ചെയàµà´¯àµà´¨àµà´¨à´¤àµ‹ à´µàµà´¯à´•àµà´¤à´¿à´ªà´°à´®à´¾à´¯ വിവരങàµà´™àµ¾ വെളിപàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤àµ‹ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, ഫോൺ നമàµà´ªà´±àµà´•àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ à´Žà´¨àµà´¨àµ€ വിവരങàµà´™àµ¾) പോലàµà´³àµà´³ അപകടകരമായ കാരàµà´¯à´™àµà´™àµ¾ ചെയàµà´¯à´¿à´ªàµà´ªà´¿à´•àµà´•àµà´¨àµà´¨ തരതàµà´¤à´¿àµ½ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚.</translation>
-<translation id="803030522067524905"><ph name="SITE" /> à´Žà´¨àµà´¨ സൈറàµà´±à´¿àµ½ Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠഈയിടെ ഫിഷിംഗൠകണàµà´Ÿàµ†à´¤àµà´¤à´¿. നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾àµ» ഫിഷിംഗൠസൈറàµà´±àµà´•àµ¾ മറàµà´±àµ വെബàµà´¸àµˆà´±àµà´±àµà´•à´³à´¾à´¯à´¿ നടികàµà´•àµà´¨àµà´¨à´¤à´¾à´£àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">à´ˆ പേജൠ<ph name="SOURCE_LANGUAGE" />-ലാണàµ. <ph name="TARGET_LANGUAGE" />-ലേകàµà´•àµ വിവർതàµà´¤à´¨à´‚ ചെയàµà´¯à´£àµ‹?</translation>
+<translation id="8037357227543935929">ചോദികàµà´•àµà´• (ഡിഫോൾടàµà´Ÿàµ)</translation>
<translation id="8041089156583427627">ഫീഡàµà´¬à´¾à´•àµà´•àµ അയയàµà´•àµà´•àµà´•</translation>
+<translation id="8041940743680923270">à´—àµà´²àµ‹à´¬àµ½ ഡിഫോൾടàµà´Ÿàµ ഉപയോഗികàµà´•àµà´• (ചോദികàµà´•àµà´•)</translation>
<translation id="8088680233425245692">ലേഖനം കാണàµà´¨àµà´¨à´¤àµ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
<translation id="8089520772729574115">ഒരൠMB-യിൽ à´•àµà´±à´µà´¾à´£àµ</translation>
<translation id="8091372947890762290">സെർവറിൽ സജീവമാകàµà´•àµ½ തീർപàµà´ªà´¾à´•àµà´•à´¿à´¯à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²</translation>
@@ -767,13 +841,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> à´Žà´¨àµà´¨à´¤à´¿à´¨àµà´±àµ† സെർവർ <ph name="BEGIN_ABBR" />DNS വിലാസം<ph name="END_ABBR" /> à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¾à´¨à´¾à´¯à´¿à´²àµà´².</translation>
<translation id="8149426793427495338">നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿàµ¼ à´¸àµà´·àµà´ªàµâ€Œà´¤à´¿à´¯à´¿à´²à´¾à´¯à´¿.</translation>
<translation id="8150722005171944719"><ph name="URL" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ† ഫയൽ റീഡàµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´µàµà´¨àµà´¨à´¿à´²àµà´². അതൠനീകàµà´•à´‚ചെയàµâ€Œà´¤à´¿à´°à´¿à´•àµà´•àµà´•à´¯àµ‹, നീകàµà´•à´¿à´¯à´¿à´°à´¿à´•àµà´•àµà´•à´¯àµ‹ ഫയൽ à´…à´¨àµà´®à´¤à´¿à´•àµ¾ ആകàµâ€Œà´¸à´¸àµà´¸àµ തടയàµà´•à´¯àµ‹ ചെയàµà´¯àµà´¨àµà´¨àµà´£àµà´Ÿà´¾à´•à´¾à´‚.</translation>
+<translation id="8184538546369750125">à´—àµà´²àµ‹à´¬àµ½ ഡിഫോൾടàµà´Ÿàµ ഉപയോഗികàµà´•àµà´• (à´…à´¨àµà´µà´¦à´¿à´•àµà´•àµà´•)</translation>
+<translation id="8191494405820426728">ലോകàµà´•àµ½ à´•àµà´°à´¾à´·àµ à´à´¡à´¿ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;നീകàµà´•àµà´¨àµà´¨à´¤àµ പഴയപടിയാകàµà´•àµà´•</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" à´Žà´¨àµà´¨ à´à´¡à´¿à´¯àµà´³àµà´³ വിപàµà´²àµ€à´•à´°à´£à´¤àµà´¤à´¿à´¨àµà´±àµ† à´…à´ªàµâ€Œà´¡àµ‡à´±àµà´±àµ URL അസാധàµà´µà´¾à´£àµ.</translation>
<translation id="8202097416529803614">ഓർഡർ സംഗàµà´°à´¹à´‚</translation>
<translation id="8218327578424803826">നൽകിയിരികàµà´•àµà´¨àµà´¨ ലൊകàµà´•àµ‡à´·àµ»:</translation>
<translation id="8225771182978767009">à´ˆ à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿàµ¼ സജàµà´œà´®à´¾à´•àµà´•à´¿à´¯ à´µàµà´¯à´•àµà´¤à´¿, à´ˆ സൈറàµà´±àµ à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµà´¯à´¾àµ» തീരàµà´®à´¾à´¨à´¿à´šàµà´šà´¿à´°àµà´¨àµà´¨àµ.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ† നിലവിലàµà´³àµà´³ ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµ¾ നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ ഇലàµà´²à´¾à´¤à´¾à´•àµà´•à´¾à´¨àµ‹ മോഷàµâ€Œà´Ÿà´¿à´•àµà´•à´¾à´¨àµ‹ ഇടയàµà´³àµà´³ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, ഫോടàµà´Ÿàµ‹à´•àµ¾, പാസàµâ€Œà´µàµ‡à´¡àµà´•àµ¾, സനàµà´¦àµ‡à´¶à´™àµà´™àµ¾, à´•àµà´°àµ†à´¡à´¿à´±àµà´±àµ കാർഡàµà´•àµ¾ പോലàµà´³àµà´³à´µ) അപകടകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ നിങàµà´™à´³àµà´Ÿàµ† à´•à´®àµà´ªàµà´¯àµ‚à´Ÿàµà´Ÿà´±à´¿àµ½ ഇൻസàµâ€Œà´±àµà´±à´¾à´³àµà´šàµ†à´¯àµà´¯à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•à´¾à´‚.</translation>
<translation id="8241707690549784388">നിങàµà´™à´³àµâ€ à´…à´¨àµà´µàµ‡à´·à´¿à´•àµà´•àµà´¨àµà´¨ പേജൠനിങàµà´™à´³àµâ€ രേഖപàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¿à´¯ വിവരങàµà´™à´³àµâ€ ഉപയോഗികàµà´•àµà´¨àµà´¨àµ. à´† പേജിലേകàµà´•àµ മടങàµà´™àµà´¨àµà´¨à´¤àµ നിങàµà´™à´³àµâ€ ആവരàµâ€à´¤àµà´¤à´¿à´•àµà´•à´¾à´µàµà´¨àµà´¨ à´à´¤àµ†à´™àµà´•à´¿à´²àµà´‚ à´ªàµà´°à´µàµƒà´¤àµà´¤à´¿à´•àµà´•àµ കാരണമായേകàµà´•àµà´‚. à´¤àµà´Ÿà´°à´¾à´¨àµâ€ നിങàµà´™à´³àµâ€ ആഗàµà´°à´¹à´¿à´•àµà´•àµà´¨àµà´¨àµà´£àµà´Ÿàµ‹?</translation>
<translation id="8249320324621329438">അവസാനം ലഭàµà´¯à´®à´¾à´¯à´¤àµ:</translation>
<translation id="8253091569723639551">ബിലàµà´²à´¿à´‚ഗൠവിലാസം ആവശàµà´¯à´®à´¾à´£àµ</translation>
@@ -781,6 +856,7 @@
<translation id="8289355894181816810">ഇതൠഅർതàµà´¥à´®à´¾à´•àµà´•àµà´¨àµà´¨à´¤àµ à´Žà´¨àµà´¤à´¾à´£àµ†à´¨àµà´¨àµ നിങàµà´™àµ¾à´•àµà´•àµ ഉറപàµà´ªà´¿à´²àµà´²àµ†à´™àµà´•à´¿àµ½ നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ à´…à´¡àµâ€Œà´®à´¿à´¨à´¿à´¸àµâ€Œà´Ÿàµà´°àµ‡à´±àµà´±à´±àµ† ബനàµà´§à´ªàµà´ªàµ†à´Ÿàµà´•.</translation>
<translation id="8293206222192510085">à´¬àµà´•àµà´•àµâ€Œà´®à´¾à´°àµâ€â€Œà´•àµà´•àµ ചേരàµâ€â€Œà´•àµà´•àµà´•</translation>
<translation id="8294431847097064396">ഉറവിടം</translation>
+<translation id="8306404619377842860">നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† തീയതിയàµà´‚ സമയവàµà´‚ <ph name="DATE_AND_TIME" /> തെറàµà´±à´¾à´¯à´¤à´¿à´¨à´¾àµ½, <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ ഒരൠസàµà´µà´•à´¾à´°àµà´¯ കണകàµâ€Œà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´². <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">നെറàµà´±àµà´µà´°àµâ€à´•àµà´•àµ കണകàµà´·à´¨à´¿à´²àµ† ഒരൠപിശകൠകാരണം വിവരàµâ€à´¤àµà´¤à´¨à´‚ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ഹോസàµâ€Œà´±àµà´±à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ ആകàµâ€Œà´¸à´¸àµà´¸àµ നിരസിചàµà´šàµ</translation>
<translation id="834457929814110454">നിങàµà´™à´³àµà´Ÿàµ† à´¸àµà´°à´•àµà´·à´¯àµ† ബാധികàµà´•à´¾à´¨à´¿à´Ÿà´¯àµà´£àµà´Ÿàµ†à´¨àµà´¨àµ മനസàµà´¸à´¿à´²à´¾à´•àµà´•àµà´•à´¯à´¾à´£àµ†à´™àµà´•à´¿àµ½, ദോഷകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ നീകàµà´•à´‚ചെയàµà´¯àµà´¨àµà´¨à´¤à´¿à´¨àµ à´®àµà´®àµà´ªàµ <ph name="BEGIN_LINK" />à´ˆ സൈറàµà´±àµ നിങàµà´™àµ¾à´•àµà´•àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾à´‚<ph name="END_LINK" />.</translation>
@@ -801,11 +877,9 @@
<translation id="8483780878231876732">നിങàµà´™à´³àµà´Ÿàµ† Google à´…à´•àµà´•àµ—à´£àµà´Ÿà´¿àµ½ നിനàµà´¨àµ കാർഡàµà´•àµ¾ ഉപയോഗികàµà´•à´¾àµ», Chrome-ൽ സൈൻ ഇൻ ചെയàµà´¯àµà´•</translation>
<translation id="8488350697529856933">ഇതിനൠബാധകമാകàµà´•àµà´¨àµà´¨àµ</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> à´ªàµà´°à´¤à´¿à´•à´°à´¿à´•àµà´•à´¾àµ» കൂടàµà´¤àµ½ സമയമെടàµà´¤àµà´¤àµ.</translation>
-<translation id="852346902619691059">à´ˆ സെർവറിനൠഇതൠ<ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¾à´£àµ†à´¨àµà´¨àµ തെളിയികàµà´•à´¾à´¨à´¾à´¯à´¿à´²àµà´²; അതിനàµà´±àµ† à´¸àµà´°à´•àµà´·à´¾ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±à´¿à´¨àµ† നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† à´“à´ªàµà´ªà´±àµ‡à´±àµà´±à´¿à´‚ഗൠസിസàµà´±àµà´±à´‚ വിശàµà´µà´¸à´¿à´•àµà´•àµà´¨àµà´¨à´¿à´²àµà´². തെറàµà´±à´¾à´¯ കോൺഫിഗറേഷൻ കാരണമോ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ നിങàµà´™à´³àµà´Ÿàµ† കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´¨àµà´¨à´¤à´¿à´¨à´¾à´²àµ‹ ആയിരികàµà´•à´¾à´‚ ഇതൠസംഭവിചàµà´šà´¤àµ. <ph name="BEGIN_LEARN_MORE_LINK" />കൂടàµà´¤à´²à´±à´¿à´¯àµà´•<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">കാലഹരണപàµà´ªàµ†à´Ÿàµà´¨àµà´¨ വർഷം</translation>
<translation id="8543181531796978784">നിങàµà´™àµ¾à´•àµà´•àµ <ph name="BEGIN_ERROR_LINK" />à´¸àµà´°à´•àµà´·à´¾à´ªàµà´°à´¶àµâ€Œà´¨à´‚ റിപàµà´ªàµ‹àµ¼à´Ÿàµà´Ÿàµà´šàµ†à´¯àµà´¯à´¾à´‚<ph name="END_ERROR_LINK" /> à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½, à´¸àµà´°à´•àµà´·à´¯àµ† ബാധിചàµà´šàµ‡à´•àµà´•à´¾à´µàµà´¨àµà´¨ അപകട സാധàµà´¯à´¤à´•à´³àµ†à´•àµà´•àµà´±à´¿à´šàµà´šàµ ബോധàµà´¯à´®àµà´£àµà´Ÿàµ†à´™àµà´•à´¿àµ½ <ph name="BEGIN_LINK" />à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²à´¾à´¤àµà´¤ à´ˆ സൈറàµà´±àµ<ph name="END_LINK" />സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´•.</translation>
<translation id="8553075262323480129">പേജിനàµâ€à´±àµ† ഭാഷ നിരàµâ€â€Œà´£àµà´£à´¯à´¿à´•àµà´•à´¾à´¨àµâ€â€Œ കഴിയാതàµà´¤à´¤à´¿à´¨à´¾à´²àµâ€â€Œ വിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
-<translation id="8559762987265718583">നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† തീയതിയàµà´‚ സമയവàµà´‚ (<ph name="DATE_AND_TIME" />) തെറàµà´±à´¾à´¯à´¤à´¿à´¨à´¾àµ½ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ‡à´•àµà´•àµà´³àµà´³ à´¸àµà´µà´•à´¾à´°àµà´¯ കണകàµà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•à´¾à´¨à´¾à´µà´¿à´²àµà´².</translation>
<translation id="8571890674111243710"><ph name="LANGUAGE" /> ലേകàµà´•àµ പേജൠവിവരàµâ€â€Œà´¤àµà´¤à´¨à´‚ ചെയàµà´¯àµà´¨àµà´¨àµ...</translation>
<translation id="858637041960032120">ഫോൺ നം. ചേർകàµà´•àµ‚
</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">ഒരൠസàµà´°à´•àµà´·à´¿à´¤ കണകàµà´·àµ» à´¸àµà´¥à´¾à´ªà´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ, നിങàµà´™à´³àµà´Ÿàµ† à´•àµà´²àµ‹à´•àµà´•àµ ശരിയായി സജàµà´œàµ€à´•à´°à´¿à´•àµà´•àµ‡à´£àµà´Ÿà´¤àµà´£àµà´Ÿàµ. വെബàµâ€Œà´¸àµˆà´±àµà´±àµà´•àµ¾ à´¸àµà´µà´¯à´‚ തിരിചàµà´šà´±à´¿à´¯àµà´¨àµà´¨à´¤à´¿à´¨àµ ഉപയോഗികàµà´•àµà´¨àµà´¨ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµà´•àµ¾, നിർദàµà´¦à´¿à´·àµâ€Œà´Ÿ സമയ പരിധിയàµâ€Œà´•àµà´•àµ മാതàµà´°à´®à´¾à´¯à´¿ സാധàµà´¤à´¯àµà´³àµà´³à´¤à´¿à´¨à´¾à´²à´¾à´£à´¿à´¤àµ. നിങàµà´™à´³àµà´Ÿàµ† ഉപകരണതàµà´¤à´¿à´¨àµà´±àµ† à´•àµà´²àµ‹à´•àµà´•àµ തെറàµà´±à´¾à´¯à´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¿à´¨à´¾àµ½, Chromium-നൠഈ സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµà´•àµ¾ പരിശോധിചàµà´šàµà´±à´ªàµà´ªà´¿à´•àµà´•à´¾à´¨à´¾à´µà´¿à´²àµà´².</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> ഹോസàµâ€Œà´±àµà´±à´¿à´¨àµà´±àµ† &lt;abbr id="dnsDefinition"&gt;DNS വിലാസം&lt;/abbr&gt; à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¾à´¨à´¾à´¯à´¿à´²àµà´². à´ªàµà´°à´¶àµâ€Œà´¨à´‚ നിർണàµà´£à´¯à´¿à´•àµà´•àµà´¨àµà´¨àµ.</translation>
<translation id="8759274551635299824">à´ˆ കാർഡൠകാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
+<translation id="8761567432415473239">Google à´¸àµà´°à´•àµà´·à´¿à´¤ à´¬àµà´°àµ—സിംഗൠ<ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¿àµ½ ഈയിടെ <ph name="BEGIN_LINK" />ദോഷകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ à´•à´£àµà´Ÿàµ†à´¤àµà´¤à´¿<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;ഇലàµà´²à´¾à´¤à´¾à´•àµà´•àµà´¨àµà´¨à´¤àµ വീണàµà´Ÿàµà´‚ ചെയàµà´¯àµà´•</translation>
<translation id="8800988563907321413">നിങàµà´™à´³àµà´Ÿàµ† സമീപതàµà´¤àµà´³àµà´³ നിർദàµà´¦àµ‡à´¶à´™àµà´™àµ¾ ഇവിടെ ദൃശàµà´¯à´®à´¾à´•àµà´‚</translation>
<translation id="8820817407110198400">à´¬àµà´•àµà´•àµâ€Œà´®à´¾à´°àµâ€à´•àµà´•àµà´•à´³àµâ€</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">സമീപകാലതàµà´¤àµ à´…à´Ÿà´šàµà´šà´µ</translation>
<translation id="8874824191258364635">ശരിയായ കാർഡൠനമàµà´ªàµ¼ നൽകàµà´•</translation>
<translation id="8876793034577346603">നെറàµà´±àµâ€Œà´µàµ¼à´•àµà´•àµ കോൺഫിഗറേഷൻ പാഴàµâ€Œà´¸àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤à´¿àµ½ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ</translation>
-<translation id="8877192140621905067">à´¸àµà´¥à´¿à´°àµ€à´•à´°à´¿à´šàµà´šàµ à´•à´´à´¿à´žàµà´žà´¾àµ½, നിങàµà´™à´³àµà´Ÿàµ† കാർഡൠവിശദാംശങàµà´™àµ¾ à´ˆ സൈറàµà´±àµà´®à´¾à´¯à´¿ പങàµà´•à´¿à´Ÿàµà´‚</translation>
<translation id="8889402386540077796">à´¹àµà´¯àµ‚</translation>
<translation id="8891727572606052622">അസാധàµà´µà´¾à´¯ à´ªàµà´°àµ‹à´•àµà´¸à´¿ മോഡàµ</translation>
<translation id="889901481107108152">à´•àµà´·à´®à´¿à´•àµà´•à´£à´‚, à´ˆ പരീകàµà´·à´£à´‚ നിങàµà´™à´³àµà´Ÿàµ† à´ªàµà´²à´¾à´±àµà´±àµà´«àµ‹à´®à´¿àµ½ ലഭàµà´¯à´®à´²àµà´².</translation>
<translation id="8903921497873541725">സൂം ഇനàµâ€</translation>
<translation id="8931333241327730545">à´ˆ കാർഡൠനിങàµà´™à´³àµà´Ÿàµ† Google à´…à´•àµà´•àµ—à´£àµà´Ÿà´¿àµ½ സംരകàµà´·à´¿à´•àµà´•à´£àµ‹?</translation>
<translation id="8932102934695377596">നിങàµà´™à´³àµà´Ÿàµ† à´•àµà´²àµ‹à´•àµà´•àµ വളരെ പിനàµà´¨à´¿à´²à´¾à´£àµ</translation>
-<translation id="8954894007019320973">(à´¤àµà´Ÿà´°àµâ€.)</translation>
<translation id="8971063699422889582">സെരàµâ€à´µà´±à´¿à´¨àµâ€à´±àµ† സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ കാലഹരണപàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
<translation id="8986494364107987395">Google ലേകàµà´•àµ à´¸àµà´µà´ªàµà´°àµ‡à´°à´¿à´¤à´®à´¾à´¯à´¿ ഉപയോഗ à´¸àµà´¥à´¿à´¤à´¿à´µà´¿à´µà´°à´•àµà´•à´£à´•àµà´•àµà´•à´³àµà´‚ à´•àµà´°à´¾à´·àµ റിപàµà´ªàµ‹à´°àµâ€à´Ÿàµà´Ÿàµà´•à´³àµà´‚ അയയàµà´•àµà´•àµà´•</translation>
-<translation id="8987927404178983737">മാസം</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">നിങàµà´™àµ¾ പോകാനിരികàµà´•àµà´¨àµà´¨ സൈറàµà´±à´¿àµ½ ദോഷകരമായ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•à´³àµà´£àµà´Ÿàµ</translation>
+<translation id="8997023839087525404">സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ à´¸àµà´¤à´¾à´°àµà´¯à´¤à´¾ നയം ഉപയോഗിചàµà´šàµ സെർവർ, à´Žà´²àµà´²à´¾à´µàµ¼à´•àµà´•àµà´®à´¾à´¯à´¿ വെളàµà´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤à´¿à´¯à´¿à´Ÿàµà´Ÿà´¿à´²àµà´²à´¾à´¤àµà´¤ ഒരൠസർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ ലഭàµà´¯à´®à´¾à´•àµà´•à´¿. à´šà´¿à´² സർടàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµà´•àµ¾ വിശàµà´µà´¾à´¸à´¯àµ‹à´—àµà´¯à´®à´¾à´£àµ†à´¨àµà´¨àµà´‚ à´…à´•àµà´°à´®à´•à´¾à´°à´¿à´•à´³à´¿àµ½ നിനàµà´¨àµà´‚ പരിരകàµà´·à´¿à´•àµà´•àµà´¨àµà´¨à´¤à´¾à´£àµ†à´¨àµà´¨àµà´‚ ഉറപàµà´ªà´¾à´•àµà´•à´¾àµ» അവയàµâ€Œà´•àµà´•àµ ഇതൠആവശàµà´¯à´®à´¾à´£àµ.</translation>
<translation id="9001074447101275817">à´ªàµà´°àµ‹à´•àµâ€Œà´¸à´¿ <ph name="DOMAIN" /> ഡൊമെയàµâ€Œà´¨à´¿à´¨àµ ഉപയോകàµà´¤àµƒà´¨à´¾à´®à´µàµà´‚ പാസàµâ€Œà´µàµ‡à´¡àµà´‚ ആവശàµà´¯à´®à´¾à´£àµ.</translation>
+<translation id="9005998258318286617">PDF ഡോകàµà´¯àµà´®àµ†à´¨àµà´±àµ ലോഡàµà´šàµ†à´¯àµà´¯à´¾à´¨à´¾à´¯à´¿à´²àµà´².</translation>
<translation id="901974403500617787">ഉടമയàµâ€Œà´•àµà´•àµ മാതàµà´°à´®àµ‡ സിസàµà´±àµà´±à´¤àµà´¤à´¿à´²à´¾à´•à´®à´¾à´¨à´‚ ബാധകമാകàµà´•à´¾à´µàµà´¨àµà´¨ à´«àµà´²à´¾à´—ൠസജàµà´œà´®à´¾à´•àµà´•à´¾à´¨à´¾à´•àµ‚: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">കാർഡൠബിലàµà´²à´¿à´‚ഗൠവിലാസം ആവശàµà´¯à´®à´¾à´£àµ</translation>
<translation id="9020542370529661692">à´ˆ പേജൠ<ph name="TARGET_LANGUAGE" />-ലേകàµà´•àµ വിവർതàµà´¤à´¨à´‚ ചെയàµâ€Œà´¤àµ</translation>
<translation id="9035022520814077154">à´¸àµà´°à´•àµà´· പിശകàµ</translation>
<translation id="9038649477754266430">പേജàµà´•àµ¾ കൂടàµà´¤àµ½ വേഗതàµà´¤à´¿àµ½ ലോഡàµà´šàµ†à´¯àµà´¯à´¾àµ» ഒരൠപàµà´°à´µà´šà´¨ സേവനം ഉപയോഗികàµà´•àµà´•</translation>
<translation id="9039213469156557790">à´ˆ പേജിൽ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´²àµà´²à´¾à´¤àµà´¤ മറàµà´±àµ ഉറവിടങàµà´™àµ¾ ഉൾപàµà´ªàµ†à´Ÿàµà´¨àµà´¨àµ. à´ˆ ഉറവിടങàµà´™àµ¾ കൈമാറàµà´¨àµà´¨à´¤à´¿à´¨à´¿à´Ÿàµ† മറàµà´±àµà´³àµà´³à´µàµ¼à´•àµà´•àµ കാണാനàµà´‚ പേജിനàµà´±àµ† à´ªàµà´°à´µàµ¼à´¤àµà´¤à´¨à´°àµ€à´¤à´¿ മാറàµà´±àµà´¨àµà´¨ തരതàµà´¤à´¿àµ½ ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿à´¯àµâ€Œà´•àµà´•àµ പരിഷàµâ€Œà´•àµà´•à´°à´¿à´•àµà´•à´¾à´¨àµà´®à´¾à´¯àµ‡à´•àµà´•àµà´‚.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµ† ആകàµà´°à´®à´£à´•à´¾à´°à´¿à´•àµ¾, à´¬àµà´°àµ—സർ à´…à´¨àµà´­à´µà´¤àµà´¤àµ† ദോഷകരമായി ബാധികàµà´•àµà´¨àµà´¨ à´ªàµà´°àµ‹à´—àµà´°à´¾à´®àµà´•àµ¾ ഇൻസàµà´±àµà´±à´¾à´³àµà´šàµ†à´¯àµà´¯à´¿à´•àµà´•àµà´¨àµà´¨ വിധതàµà´¤à´¿àµ½ നിങàµà´™à´³àµ† കബളിപàµà´ªà´¿à´•àµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´šàµà´šàµ‡à´•àµà´•àµà´‚ (ഉദാഹരണതàµà´¤à´¿à´¨àµ, നിങàµà´™à´³àµà´Ÿàµ† ഹോംപേജൠമാറàµà´±àµà´¨àµà´¨à´¤à´¿à´²àµ‚ടെ à´…à´²àµà´²àµ†à´™àµà´•à´¿àµ½ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•àµà´¨àµà´¨ സൈറàµà´±àµà´•à´³à´¿àµ½ അധിക പരസàµà´¯à´™àµà´™àµ¾ കാണികàµà´•àµà´¨àµà´¨à´¤à´¿à´²àµ‚ടെ).</translation>
+<translation id="9049981332609050619">നിങàµà´™à´³àµâ€ <ph name="DOMAIN" /> à´Žà´¨àµà´¨à´¤à´¿à´²àµâ€ à´Žà´¤àµà´¤à´¾à´¨àµâ€ à´¶àµà´°à´®à´¿à´šàµà´šàµ, പകàµà´·àµ‡ സെരàµâ€à´µà´°àµâ€ ഒരൠഅസാധàµà´µà´¾à´¯ സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ അവതരിപàµà´ªà´¿à´šàµà´šàµ.</translation>
<translation id="9050666287014529139">പാസàµà´«àµà´°àµ†à´¯àµà´¸àµ</translation>
<translation id="9065203028668620118">à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´•</translation>
<translation id="9068849894565669697">വർണàµà´£à´‚ തിരഞàµà´žàµ†à´Ÿàµà´•àµà´•àµà´•</translation>
+<translation id="9069693763241529744">ഒരൠവിപàµà´²àµ€à´•à´°à´£à´‚ à´®àµà´–േന à´¬àµà´²àµ‹à´•àµà´•àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="9076283476770535406">ഇതിൽ à´®àµà´¤à´¿àµ¼à´¨àµà´¨à´µàµ¼à´•àµà´•àµà´³àµà´³ ഉളàµà´³à´Ÿà´•àµà´•à´‚ ഉണàµà´Ÿà´¾à´¯à´¿à´°à´¿à´•àµà´•à´¾à´‚</translation>
<translation id="9078964945751709336">കൂടàµà´¤àµ½ വിവരങàµà´™àµ¾ ആവശàµà´¯à´®à´¾à´£àµ</translation>
<translation id="9103872766612412690">നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ പരിരകàµà´·à´¿à´•àµà´•à´¾àµ» സാധാരണയായി <ph name="SITE" />, എൻകàµà´°à´¿à´ªàµâ€Œà´·àµ» ഉപയോഗികàµà´•àµà´¨àµà´¨àµ. ഇപàµà´ªàµ‹àµ¾ <ph name="SITE" /> സൈറàµà´±à´¿à´²àµ‡à´•àµà´•àµ കണകàµâ€Œà´±àµà´±àµà´šàµ†à´¯àµà´¯à´¾àµ» Chromium à´¶àµà´°à´®à´¿à´šàµà´šà´ªàµà´ªàµ‹àµ¾, അസാധാരണമായതàµà´‚ തെറàµà´±à´¾à´¯à´¤àµà´®à´¾à´¯ à´•àµà´°àµ†à´¡àµ»à´·àµà´¯à´²àµà´•àµ¾ വെബàµâ€Œà´¸àµˆà´±àµà´±àµ തിരികെ അയചàµà´šàµ. ഒരൠആകàµà´°à´®à´£à´•à´¾à´°à´¿ <ph name="SITE" /> à´Žà´¨àµà´¨à´¤à´¾à´¯à´¿ ഭാവികàµà´•à´¾àµ» à´¶àµà´°à´®à´¿à´•àµà´•àµà´®àµà´ªàµ‹à´´àµ‹ Wi-Fi സൈൻ ഇൻ à´¸àµâ€Œà´•àµà´°àµ€àµ», കണകàµà´·à´¨àµ† തടസàµà´¸à´ªàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´®àµà´ªàµ‹à´´àµ‹ ആണൠഇങàµà´™à´¨àµ† സംഭവികàµà´•à´¾à´¨à´¿à´Ÿà´¯àµà´³àµà´³à´¤àµ. à´à´¤àµ†à´™àµà´•à´¿à´²àµà´‚ ഡാറàµà´± കൈമാറàµà´¨àµà´¨à´¤à´¿à´¨àµà´®àµà´®àµà´ªàµ Chromium കണകàµà´·àµ» അവസാനിപàµà´ªà´¿à´šàµà´šà´¤à´¿à´¨à´¾àµ½, നിങàµà´™à´³àµà´Ÿàµ† വിവരങàµà´™àµ¾ à´¤àµà´Ÿàµ¼à´¨àµà´¨àµà´‚ à´¸àµà´°à´•àµà´·à´¿à´¤à´®à´¾à´¯à´¿à´°à´¿à´•àµà´•àµà´‚.</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">&amp;à´Žà´¡à´¿à´±àµà´±àµà´šàµ†à´¯àµà´¯àµà´¨àµà´¨à´¤àµ പഴയപടിയാകàµà´•àµà´•</translation>
<translation id="9154194610265714752">à´…à´ªàµâ€Œà´¡àµ‡à´±àµà´±àµà´šàµ†à´¯àµâ€Œà´¤àµ</translation>
<translation id="9157595877708044936">സജàµà´œàµ€à´•à´°à´¿à´•àµà´•àµà´¨àµà´¨àµ...</translation>
+<translation id="9169664750068251925">à´ˆ സൈറàµà´±à´¿àµ½ à´Žà´²àµà´²à´¾à´¯àµâ€Œà´ªàµà´ªàµ‹à´´àµà´‚ തടയàµà´•</translation>
<translation id="9170848237812810038">â€&amp;പൂരàµâ€à´µà´¾à´µà´¸àµà´¥à´¯à´¿à´²à´¾à´•àµà´•àµà´•</translation>
<translation id="917450738466192189">സെരàµâ€à´µà´±à´¿à´¨àµâ€à´±àµ† സരàµâ€à´Ÿàµà´Ÿà´¿à´«à´¿à´•àµà´•à´±àµà´±àµ അസാധàµà´µà´¾à´£àµ.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> à´Žà´£àµà´£à´µàµà´‚}other{<ph name="SHIPPING_OPTION_PREVIEW" /> à´Žà´¨àµà´¨à´¤àµà´‚ മറàµà´±àµ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> à´Žà´£àµà´£à´µàµà´‚}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> പിനàµà´¤àµà´£à´¯àµâ€Œà´•àµà´•à´¾à´¤àµà´¤ ഒരൠപàµà´°àµ‹à´Ÿàµà´Ÿàµ‹à´•àµà´•àµ‹à´³à´¾à´£àµ ഉപയോഗികàµà´•àµà´¨àµà´¨à´¤àµ.</translation>
<translation id="9205078245616868884">നിങàµà´™à´³àµà´Ÿàµ† സമനàµà´µà´¯ പാസàµâ€Œà´«àµà´°àµ†à´¯àµâ€Œà´¸àµ ഉപയോഗിചàµà´šàµ ഡാറàµà´± എൻകàµà´°à´¿à´ªàµâ€Œà´±àµà´±àµà´šàµ†à´¯àµâ€Œà´¤àµ. സമനàµà´µà´¯à´‚ ആരംഭികàµà´•àµà´¨àµà´¨à´¤à´¿à´¨àµ ഇതൠനൽകàµà´•.</translation>
<translation id="9207861905230894330">ലേഖനം ചേർകàµà´•àµà´¨àµà´¨à´¤àµ പരാജയപàµà´ªàµ†à´Ÿàµà´Ÿàµ.</translation>
+<translation id="9219103736887031265">à´šà´¿à´¤àµà´°à´™àµà´™àµ¾â€Œ</translation>
<translation id="933612690413056017">ഇനàµà´±àµ¼à´¨àµ†à´±àµà´±àµâ€Œ കണകàµà´·à´¨à´¿à´²àµà´²</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ഫോം മായàµâ€Œà´•àµà´•àµà´•</translation>
<translation id="939736085109172342">à´ªàµà´¤à´¿à´¯ ഫോളàµâ€à´¡à´°àµâ€</translation>
<translation id="941721044073577244">à´ˆ സൈറàµà´±àµ സനàµà´¦àµ¼à´¶à´¿à´•àµà´•à´¾àµ» നിങàµà´™àµ¾à´•àµà´•àµ à´…à´¨àµà´®à´¤à´¿à´¯à´¿à´²àµà´²àµ†à´¨àµà´¨àµ തോനàµà´¨àµà´¨àµà´¨àµ</translation>
<translation id="969892804517981540">ഔദàµà´¯àµ‹à´—à´¿à´• ബിലàµâ€à´¡àµ</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{à´’à´¨àµà´¨àµà´®à´¿à´²àµà´²}=1{ഒരൠഇനം}other{# ഇനങàµà´™àµ¾}}</translation>
<translation id="988159990683914416">വികാസക പതിപàµà´ªàµ</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_mr.xtb b/chromium/components/strings/components_strings_mr.xtb
index ee40a5f4c32..25c25ede970 100644
--- a/chromium/components/strings/components_strings_mr.xtb
+++ b/chromium/components/strings/components_strings_mr.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">घडà¥à¤¯à¤¾à¤³à¤¾à¤šà¥à¤¯à¤¾ दिशेने फिरवा</translation>
<translation id="1038842779957582377">अजà¥à¤žà¤¾à¤¤ नाव</translation>
<translation id="1050038467049342496">अनà¥à¤¯ अॅपà¥à¤¸ बंद करा</translation>
-<translation id="1053591932240354961">Google Chrome पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ करू शकत नाही असे न समजणारे कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤² वेबसाइटने पाठविलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ आपण आतà¥à¤¤à¤¾ <ph name="SITE" /> ला भेट देऊ शकत नाही. नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€ आणि आकà¥à¤°à¤®à¤£ सामानà¥à¤¯à¤¤à¤ƒ तातà¥à¤ªà¥à¤°à¤¤à¥‡ असतात, यामà¥à¤³à¥‡ हे पृषà¥à¤  कदाचित नंतर कारà¥à¤¯ करेल. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;जोडा पूरà¥à¤µà¤µà¤¤ करा</translation>
<translation id="10614374240317010">कधीही जतन न केलेले</translation>
<translation id="106701514854093668">डेसà¥â€à¤•à¤Ÿà¥‰à¤ª बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">धोरण कॅश ठीक</translation>
<translation id="113188000913989374"><ph name="SITE" /> मà¥à¤¹à¤£à¤¤à¥‡:</translation>
<translation id="1132774398110320017">Chrome सà¥à¤µà¤¯à¤‚भरण सेटिंगà¥à¤œ...</translation>
+<translation id="1150979032973867961">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपलà¥à¤¯à¤¾ संगणकाचà¥à¤¯à¤¾ ऑपरेटिंग पà¥à¤°à¤£à¤¾à¤²à¥€à¤¦à¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
+<translation id="1151972924205500581">संकेतशबà¥à¤¦ आवशà¥à¤¯à¤•</translation>
<translation id="1152921474424827756"><ph name="URL" /> चà¥à¤¯à¤¾ <ph name="BEGIN_LINK" />कॅश केलेलà¥à¤¯à¤¾ कॉपीवर<ph name="END_LINK" /> पà¥à¤°à¤µà¥‡à¤¶ करा</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> नी कनेकà¥à¤¶à¤¨ अनपेकà¥à¤·à¤¿à¤¤à¤°à¤¿à¤¤à¥à¤¯à¤¾ बंद केले.</translation>
<translation id="1161325031994447685">Wi-Fi शी पà¥à¤¨à¥à¤¹à¤¾ कनेकà¥à¤Ÿ करीत आहे</translation>
+<translation id="1165039591588034296">तà¥à¤°à¥à¤Ÿà¥€</translation>
<translation id="1175364870820465910">&amp;मà¥à¤¦à¥à¤°à¤£...</translation>
<translation id="1181037720776840403">काढा</translation>
<translation id="1184214524891303587">Google कडे संभावà¥à¤¯ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ घटनांचà¥à¤¯à¤¾ तपशीलांचा <ph name="BEGIN_WHITEPAPER_LINK" />सà¥à¤µà¤¯à¤‚चलितपणे अहवाल दà¥à¤¯à¤¾.<ph name="END_WHITEPAPER_LINK" /> <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">या साइटकडून अधिक</translation>
<translation id="1206967143813997005">खराब पà¥à¤°à¤¾à¤°à¤‚भिक सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€</translation>
<translation id="1209206284964581585">आतासाठी लपवा</translation>
+<translation id="121201262018556460">आपण <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केलात, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ à¤à¤• कमकà¥à¤µà¤¤ की असलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले. आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ गोपनीय की तोडलेली असू शकते आणि सरà¥à¤µà¥à¤¹à¤° हे आपलà¥à¤¯à¤¾à¤²à¤¾ अपेकà¥à¤·à¤¿à¤¤ असणारे सरà¥à¤µà¥à¤¹à¤° नसू शकते (आपण कदाचित आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¶à¥€ संपà¥à¤°à¥‡à¤·à¤£ करत असाल).</translation>
<translation id="1219129156119358924">सिसà¥à¤Ÿà¥€à¤® सà¥à¤°à¤•à¥à¤·à¤¾</translation>
<translation id="1227224963052638717">अजà¥à¤žà¤¾à¤¤ धोरण.</translation>
<translation id="1227633850867390598">मूलà¥à¤¯ लपवा</translation>
<translation id="1228893227497259893">चà¥à¤•à¥€à¤šà¤¾ असà¥à¤¤à¤¿à¤¤à¥à¤µ ओळखकरà¥à¤¤à¤¾</translation>
<translation id="1232569758102978740">अशीरà¥à¤·à¤•à¤¾à¤‚कित</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (सिंक केलेले)</translation>
<translation id="1263231323834454256">वाचन सूची</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" /> वाजता कà¥à¤°à¥…श अहवाल कॅपà¥à¤šà¤° केला (अदà¥à¤¯à¤¾à¤ª अपलोड केलेला नाही किंवा दà¥à¤°à¥à¤²à¤•à¥à¤· केले)</translation>
+<translation id="1281526147609854549"><ph name="ISSUER" /> ने दिलेले</translation>
+<translation id="1283919782143846010">धोकादायक आशय बà¥à¤²à¥‰à¤• केला</translation>
<translation id="1285320974508926690">या साइटचा कधीही भाषांतर करॠनका</translation>
<translation id="129553762522093515">अलीकडे बंद केलेले</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />आपलà¥à¤¯à¤¾ कà¥à¤•à¥€à¤œ साफ करून पहा<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">आपले पà¥à¤¢à¥€à¤² कà¥à¤°à¤¿à¤¯à¤¾à¤•à¤²à¤¾à¤ª <ph name="BEGIN_EMPHASIS" />अदà¥à¤¯à¤¾à¤ª दिसतील<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />आपण पाहत असलेलà¥à¤¯à¤¾ वेबसाइट
+ <ph name="LIST_ITEM" />आपला नियोकà¥à¤¤à¤¾ किंवा शाळा
+ <ph name="LIST_ITEM" />आपला इंटरनेट सेवा पà¥à¤°à¤¦à¤¾à¤¤à¤¾
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">नावनोंदणी डोमेन:</translation>
<translation id="1340482604681802745">घेणà¥à¤¯à¤¾à¤šà¤¾ पतà¥à¤¤à¤¾</translation>
<translation id="1344211575059133124">या साइटला भेट देणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आपलà¥à¤¯à¤¾à¤²à¤¾ परवानगीची आवशà¥à¤¯à¤•à¤¤à¤¾ आहे असे दिसते</translation>
<translation id="1344588688991793829">Chromium सà¥à¤µà¤¯à¤‚भरण सेटिंगà¥à¤œ...</translation>
+<translation id="1348198688976932919">पà¥à¤¢à¥€à¤² साइटमधà¥à¤¯à¥‡ धोकादायक अॅप आहे</translation>
<translation id="1374468813861204354">सूचना</translation>
<translation id="1375198122581997741">आवृतà¥à¤¤à¥€à¤¬à¤¦à¥à¤¦à¤²</translation>
<translation id="1377321085342047638">कारà¥à¤¡ नंबर</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> नी कोणताही डेटा पाठविला नाही.</translation>
<translation id="1407135791313364759">सरà¥à¤µ उघडा</translation>
<translation id="1413809658975081374">गोपनीयता तà¥à¤°à¥à¤Ÿà¥€</translation>
+<translation id="14171126816530869"><ph name="ISSUER" /> दà¥à¤µà¤¾à¤°à¥‡ <ph name="LOCALITY" /> सà¥à¤¥à¤¿à¤¤ <ph name="ORGANIZATION" /> ची ओळख सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ केली गेली आहे.</translation>
<translation id="1426410128494586442">होय</translation>
<translation id="1430915738399379752">मà¥à¤¦à¥à¤°à¤£</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /> <ph name="DOMAIN" /> वरील à¤à¤•à¤¾ पृषà¥à¤ à¤¾à¤¸ भेट देणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€à¤šà¤¾<ph name="END_LINK" /> पà¥à¤°à¤¯à¤¤à¥à¤¨ अवरोधित केला.</translation>
-<translation id="1491663344921578213">वेबसाइट पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पिनिंग वापरत असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ आपण <ph name="SITE" /> ला आतà¥à¤¤à¤¾ भेट देऊ शकत नाही. नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€ आणि आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ सामानà¥à¤¯à¤¤à¤ƒ तातà¥à¤ªà¥à¤°à¤¤à¥‡ असतात, यामà¥à¤³à¥‡ हे पृषà¥à¤  कदाचित नंतर कारà¥à¤¯ करेल. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">या पृषà¥à¤ à¤¾à¤šà¥€ जतन केलेली (उदा. कालबाहà¥à¤¯ होणारे जà¥à¤žà¤¾à¤¤) पà¥à¤°à¤¤ दरà¥à¤¶à¤µà¤¾.</translation>
<translation id="1517433312004943670">फोन नंबर आवशà¥à¤¯à¤• आहे</translation>
<translation id="1519264250979466059">बिलà¥à¤¡ तारीख</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">हे वैशिषà¥â€à¤Ÿà¥à¤¯ वापरणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ JavaScript सकà¥à¤·à¤® करणे आवशà¥â€à¤¯à¤• आहे.</translation>
<translation id="1555130319947370107">निळा</translation>
<translation id="1559528461873125649">अशी कोणतीही फाइल किंवा निरà¥à¤¦à¥‡à¤¶à¤¿à¤•à¤¾ नाही</translation>
-<translation id="1559572115229829303">&lt;p&gt;आपलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¥€ तारीख आणि वेळ (<ph name="DATE_AND_TIME" />) चà¥à¤•à¥€à¤šà¥€ असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> सह खाजगी कनेकà¥à¤¶à¤¨ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ केले जाऊ शकत नाही.&lt;/p&gt;
-
- &lt;p&gt;कृपया &lt;strong&gt;सेटिंगà¥à¤œ&lt;/strong&gt; अॅपचà¥à¤¯à¤¾ &lt;strong&gt;सरà¥à¤µà¤¸à¤¾à¤§à¤¾à¤°à¤£&lt;/strong&gt; विभागातील तारीख आणि वेळ समायोजित करा.&lt;/p&gt;</translation>
<translation id="1583429793053364125">हे वेबपृषà¥â€à¤  पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ करताना काहीतरी चूक à¤à¤¾à¤²à¥€.</translation>
<translation id="1592005682883173041">सà¥à¤¥à¤¾à¤¨à¤¿à¤• डेटा पà¥à¤°à¤µà¥‡à¤¶</translation>
+<translation id="1594030484168838125">निवडा</translation>
<translation id="161042844686301425">निळसर</translation>
+<translation id="1620510694547887537">कॅमेरा</translation>
<translation id="1629803312968146339">Chrome ने हे कारà¥à¤¡ जतन करावे असे आपण इचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="1639239467298939599">लोड करीत आहे</translation>
<translation id="1640180200866533862">वापरकरà¥à¤¤à¤¾ धोरणे</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">नेटवरà¥à¤• कॉनà¥à¤«à¤¿à¤—रेशन अवैध आहे आणि आयात केले जाऊ शकले नाही.</translation>
<translation id="1644574205037202324">इतिहास</translation>
<translation id="1645368109819982629">असमरà¥à¤¥à¤¿à¤¤ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•à¥‰à¤²</translation>
+<translation id="1655462015569774233">{1,plural, =1{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° काल कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. आपले संगणक सधà¥à¤¯à¤¾ <ph name="CURRENT_DATE" /> वर सेट आहे. ते योगà¥à¤¯ दिसते आहे? नसलà¥à¤¯à¤¾à¤¸, आपण आपलà¥à¤¯à¤¾ सिसà¥à¤Ÿà¥€à¤®à¤šà¥‡ घडà¥à¤¯à¤¾à¤³ दà¥à¤°à¥‚सà¥à¤¤ करावे आणि तà¥à¤¯à¤¾à¤¨à¤‚तर हे पृषà¥à¤  रीफà¥à¤°à¥‡à¤¶ करा.}one{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" />असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° # दिवसांपूरà¥à¤µà¥€ कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. आपले संगणक सधà¥à¤¯à¤¾ <ph name="CURRENT_DATE" /> वर सेट आहे. ते योगà¥à¤¯ दिसते आहे? नसलà¥à¤¯à¤¾à¤¸, आपण आपलà¥à¤¯à¤¾ सिसà¥à¤Ÿà¥€à¤®à¤šà¥‡ घडà¥à¤¯à¤¾à¤³ दà¥à¤°à¥‚सà¥à¤¤ करावे आणि तà¥à¤¯à¤¾à¤¨à¤‚तर हे पृषà¥à¤  रीफà¥à¤°à¥‡à¤¶ करा.}other{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" />असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° # दिवसांपूरà¥à¤µà¥€ कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. आपले संगणक सधà¥à¤¯à¤¾ <ph name="CURRENT_DATE" /> वर सेट आहे. ते योगà¥à¤¯ दिसते आहे? नसलà¥à¤¯à¤¾à¤¸, आपण आपलà¥à¤¯à¤¾ सिसà¥à¤Ÿà¥€à¤®à¤šà¥‡ घडà¥à¤¯à¤¾à¤³ दà¥à¤°à¥‚सà¥à¤¤ करावे आणि तà¥à¤¯à¤¾à¤¨à¤‚तर हे पृषà¥à¤  रीफà¥à¤°à¥‡à¤¶ करा.}}</translation>
<translation id="1656489000284462475">घेणे</translation>
<translation id="1663943134801823270">कारà¥à¤¡ आणि पतà¥à¤¤à¥‡ Chrome कडील आहेत. आपण तà¥à¤¯à¤¾à¤‚ना <ph name="BEGIN_LINK" />सेटिंगà¥â€à¤œ<ph name="END_LINK" /> मधून वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ करू शकता.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> आपली माहिती संरकà¥à¤·à¤¿à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ सामानà¥à¤¯à¤¤à¤ƒ कूटबदà¥à¤§à¥€à¤•à¤°à¤£ वापरते. Google Chrome ने यावेळी <ph name="SITE" /> शी कनेकà¥â€à¤Ÿ करणà¥â€à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला तेवà¥â€à¤¹à¤¾, वेबसाइटने असामानà¥à¤¯ आणि अयोगà¥à¤¯ कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤² परत पाठविले. à¤à¤•à¤¤à¤° आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ <ph name="SITE" /> असलà¥à¤¯à¤¾à¤šà¥€ बतावणी करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करतो तेवà¥â€à¤¹à¤¾ किंवा Wi-Fi साइन इन सà¥à¤•à¥à¤°à¥€à¤¨à¤¨à¥‡ कनेकà¥à¤¶à¤¨à¤®à¤§à¥à¤¯à¥‡ वà¥à¤¯à¤¤à¥à¤¯à¤¯ आणले तेवà¥â€à¤¹à¤¾ हे घडू शकते. कोणतà¥à¤¯à¤¾à¤¹à¥€ डेटाची अदलाबदल करणà¥à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€ Google Chrome ने कनेकà¥à¤¶à¤¨ थांबविलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ आपली माहिती अदà¥à¤¯à¤¾à¤ª सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ आहे.</translation>
-<translation id="168328519870909584">सधà¥â€à¤¯à¤¾ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वर असलेले आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ आपली माहिती (उदाहरणारà¥à¤¥, फोटो, संकेतशबà¥à¤¦, संदेश आणि कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चोरणारे किंवा हटविणारे धोकादायक अâ€à¥…पà¥â€à¤¸ कदाचित आपलà¥à¤¯à¤¾ डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¤µà¤° सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतात.</translation>
<translation id="168841957122794586">सरà¥à¤µà¥à¤¹à¤° पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¤¾à¤¤ à¤à¤• कमकà¥à¤µà¤¤ कà¥à¤°à¤¿à¤ªà¥à¤Ÿà¥‹à¤—à¥à¤°à¤¾à¤«à¤¿à¤• की आहे.</translation>
+<translation id="1706954506755087368">{1,plural, =1{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° उदà¥à¤¯à¤¾à¤ªà¤¾à¤¸à¥‚न मानले जाईल. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.}one{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤¢à¥€à¤² # दिवसांपासून मानले जाईल. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.}other{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤¢à¥€à¤² # दिवसांपासून मानले जाईल. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">या साइटला भेट देणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आपलà¥à¤¯à¤¾à¤²à¤¾ <ph name="NAME" /> कडील परवानगी आवशà¥à¤¯à¤• आहे</translation>
<translation id="1721424275792716183">* फीलà¥à¤¡ आवशà¥à¤¯à¤• आहे</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">पृषà¥à¤  नंतर डाउनलोड करा</translation>
<translation id="17513872634828108">खà¥à¤²à¥‡ टॅब</translation>
<translation id="1753706481035618306">पृषà¥à¤  कà¥à¤°à¤®à¤¾à¤‚क</translation>
+<translation id="1763864636252898013">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¥à¤¯à¤¾ ऑपरेटिंग पà¥à¤°à¤£à¤¾à¤²à¥€à¤¦à¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows नेटवरà¥à¤• निदान चालवून पहा<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">कृपया आपले संंकालित सांकेतिक वाकà¥à¤¯à¤¾à¤‚श अदà¥à¤¯à¤¤à¤¨à¤¿à¤¤ करा.</translation>
<translation id="1787142507584202372">आपले खà¥à¤²à¥‡ टॅब येथे दिसतात</translation>
+<translation id="1789575671122666129">पॉपअप</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">कारà¥à¤¡à¤§à¤¾à¤°à¤•à¤¾à¤šà¥‡ नाव</translation>
-<translation id="1803678881841855883">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚गला अलीकडे <ph name="SITE" /> वर <ph name="BEGIN_LINK" />मालवेअर आढळले आहे<ph name="END_LINK" />. सामानà¥à¤¯à¤¤à¤ƒ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ असलेलà¥à¤¯à¤¾ वेबसाइट काहीवेळा मालवेअरमà¥à¤³à¥‡ संकà¥à¤°à¤®à¤¿à¤¤ à¤à¤¾à¤²à¥‡à¤²à¥à¤¯à¤¾ असतात. à¤à¤• जà¥à¤žà¤¾à¤¤ मालवेअर वितरक असलेलà¥à¤¯à¤¾, <ph name="SUBRESOURCE_HOST" /> कडून दà¥à¤°à¥à¤­à¤¾à¤µà¤¨à¤¾à¤ªà¥‚रà¥à¤£ सामगà¥à¤°à¥€ येते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">जोडले: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">अवैध विनंती किंवा विनंती मापदंड</translation>
<translation id="1826516787628120939">तपासत आहे</translation>
<translation id="1834321415901700177">या साइटमधà¥à¤¯à¥‡ धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® आहेत</translation>
+<translation id="1840414022444569775">हा कारà¥à¤¡ नंबर आधी वापरला गेला आहे</translation>
<translation id="1842969606798536927">देय दà¥à¤¯à¤¾</translation>
<translation id="1871208020102129563">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ निशà¥à¤šà¤¿à¤¤ पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° वापरणà¥â€à¤¯à¤¾à¤¸ सेट करणà¥â€à¤¯à¤¾à¤¤ आले आहे, .pac सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ URL नवà¥à¤¹à¥‡.</translation>
<translation id="1871284979644508959">आवशà¥à¤¯à¤• फीलà¥à¤¡</translation>
<translation id="187918866476621466">पà¥à¤°à¤¾à¤°à¤‚भ पृषà¥à¤  उघडा</translation>
<translation id="1883255238294161206">सूची संकà¥à¤šà¤¿à¤¤ करा</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">फिलà¥à¤Ÿà¤° करणे</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{काहीही नाही}=1{1 साइट}one{# साइट}other{# साइट}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> दà¥à¤µà¥à¤¯à¤¾à¤•à¤¡à¥‡ जा</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
<translation id="1973335181906896915">कà¥à¤°à¤®à¥€à¤•à¤°à¤£ तà¥à¤°à¥à¤Ÿà¥€</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">दà¥à¤°à¥à¤²à¤•à¥à¤· केले कारण ते <ph name="POLICY_NAME" /> कडून अधिलिखित à¤à¤¾à¤²à¥‡ होते.</translation>
<translation id="2138201775715568214">जवळपासची वासà¥à¤¤à¤µà¤¿à¤• वेब पृषà¥à¤ à¥‡ शोधत आहात</translation>
<translation id="213826338245044447">Mobile बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
-<translation id="2148716181193084225">आज</translation>
+<translation id="2147827593068025794">पारà¥à¤¶à¥à¤µà¤­à¥‚मी संकालन</translation>
<translation id="2154054054215849342">आपलà¥à¤¯à¤¾ डोमेनसाठी संकालन उपलबà¥à¤§ नाही</translation>
<translation id="2154484045852737596">कारà¥à¤¡ संपादित करा</translation>
<translation id="2166049586286450108">पूरà¥à¤£ पà¥à¤°à¤¶à¤¾à¤¸à¤¨ पà¥à¤°à¤µà¥‡à¤¶</translation>
<translation id="2166378884831602661">ही साइट सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥à¤¶à¤¨ पà¥à¤°à¤¦à¤¾à¤¨ करू शकत नाही</translation>
<translation id="2181821976797666341">धोरणे</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 पतà¥à¤¤à¤¾}one{# पतà¥à¤¤à¤¾}other{# पतà¥à¤¤à¥‡}}</translation>
+<translation id="2187317261103489799">शोधा (डीफॉलà¥à¤Ÿ)</translation>
<translation id="2202020181578195191">वैध समापà¥à¤¤à¥€ वरà¥à¤· पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा</translation>
<translation id="2212735316055980242">धोरण आढळले नाही</translation>
<translation id="2213606439339815911">पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¥à¤¯à¤¾ आणत आहे...</translation>
+<translation id="2218879909401188352">सधà¥à¤¯à¤¾ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />वर असलेले आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ तà¥à¤®à¤šà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤²à¤¾ हानी पोहोचवणारे धोकादायक अॅप इंसà¥à¤Ÿà¥‰à¤² करू शकतात, तà¥à¤®à¤šà¥à¤¯à¤¾ मोबाइल बिलामधà¥à¤¯à¥‡ लपलेले शà¥à¤²à¥à¤• जोडू शकतात किंवा तà¥à¤®à¤šà¥€ वैयकà¥à¤¤à¤¿à¤• माहिती चोरू शकतात. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />निदान अॅप<ph name="END_LINK" /> वापरून आपलà¥à¤¯à¤¾ कनेकà¥à¤¶à¤¨à¤šà¥‡ निराकरण करा</translation>
<translation id="2239100178324503013">आता पाठवा</translation>
<translation id="225207911366869382">हे मूलà¥à¤¯ या धोरणासाठी नापसंत करणà¥â€à¤¯à¤¾à¤¤ आले आहे.</translation>
<translation id="2262243747453050782">HTTP तà¥à¤°à¥à¤Ÿà¥€</translation>
+<translation id="2270484714375784793">फोन नंबर</translation>
<translation id="2282872951544483773">अनà¥à¤ªà¤²à¤¬à¥à¤§ पà¥à¤°à¤¯à¥‹à¤—</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> आयटम}one{<ph name="ITEM_COUNT" /> आयटम}other{<ph name="ITEM_COUNT" /> आयटम}}</translation>
<translation id="2292556288342944218">आपला इंटरनेट पà¥à¤°à¤µà¥‡à¤¶ अवरोधित केला आहे</translation>
<translation id="230155334948463882">नवीन कारà¥à¤¡?</translation>
-<translation id="2305919008529760154">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° फसवणà¥à¤•à¥€à¤¨à¥‡ जारी केले असावे. हे कदाचित चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ आपलà¥à¤¯à¤¾ कनेकà¥à¤¶à¤¨à¤®à¤§à¥à¤¯à¥‡ वà¥à¤¯à¤¤à¥à¤¯à¤¯ आणत असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असावे. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> साठी वापरकरà¥à¤¤à¤¾à¤¨à¤¾à¤µ आणि संकेतशबà¥à¤¦ आवशà¥à¤¯à¤• आहेत.</translation>
-<translation id="2318774815570432836">आपण <ph name="SITE" /> ला आतà¥à¤¤à¤¾ भेट देऊ शकत नाही कारण वेबसाइट HSTS वापरते. नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€ आणि आकà¥à¤°à¤®à¤£à¥‡ सामानà¥à¤¯à¤¤à¤ƒ तातà¥à¤ªà¥à¤°à¤¤à¥€ असतात, यामà¥à¤³à¥‡ हे पृषà¥à¤  कदाचित नंतर कारà¥à¤¯ करेल. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">सेटिंग तà¥à¤®à¤šà¥à¤¯à¤¾ पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¨à¥‡ नियंतà¥à¤°à¤¿à¤¤ केलेली आहे</translation>
<translation id="2354001756790975382">इतर बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
+<translation id="2354430244986887761">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚गला अलीकडे <ph name="SITE" />मधà¥à¤¯à¥‡ <ph name="BEGIN_LINK" />हानिकारक अॅपà¥à¤¸ सापडले<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">आपण या साइटवर पाहत असलेलà¥à¤¯à¤¾ पà¥à¤°à¤¤à¤¿à¤®à¤¾ पाहणà¥à¤¯à¤¾à¤¸ आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ सकà¥à¤·à¤® असू शकतात आणि तà¥à¤¯à¤¾à¤¤ सà¥à¤§à¤¾à¤°à¤£à¤¾ करून आपली फसवणूक करू शकतात.</translation>
+<translation id="2356070529366658676">विचारा</translation>
+<translation id="2359629602545592467">अनेक</translation>
<translation id="2359808026110333948">सà¥à¤°à¥‚ ठेवा</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> वाजता कॅपà¥à¤šà¤° केलेला कà¥à¤°à¥…श अहवाल अपलोड केला नाही</translation>
<translation id="2367567093518048410">दरà¥à¤œà¤¾</translation>
-<translation id="2371153335857947666">{1,plural, =1{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° काल कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. आपलà¥à¤¯à¤¾ संगणकाचे घडà¥à¤¯à¤¾à¤³ सधà¥à¤¯à¤¾ <ph name="CURRENT_DATE" /> वर सेट आहे. ते बरोबर आहे? नसलà¥à¤¯à¤¾à¤¸, आपण आपलà¥à¤¯à¤¾ सिसà¥à¤Ÿà¥€à¤®à¤šà¥‡ घडà¥à¤¯à¤¾à¤³ दà¥à¤°à¥‚सà¥à¤¤ आणि तà¥à¤¯à¤¾à¤¨à¤‚तर हे पृषà¥à¤  रीफà¥à¤°à¥‡à¤¶ करणे आवशà¥à¤¯à¤• आहे. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.}one{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" />असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° # दिवसांपूरà¥à¤µà¥€ कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. आपलà¥à¤¯à¤¾ संगणकाचे घडà¥à¤¯à¤¾à¤³ सधà¥à¤¯à¤¾ <ph name="CURRENT_DATE" /> वर सेट आहे. ते बरोबर आहे? नसलà¥à¤¯à¤¾à¤¸, आपण आपलà¥à¤¯à¤¾ सिसà¥à¤Ÿà¥€à¤®à¤šà¥‡ घडà¥à¤¯à¤¾à¤³ दà¥à¤°à¥‚सà¥à¤¤ आणि तà¥à¤¯à¤¾à¤¨à¤‚तर हे पृषà¥à¤  रीफà¥à¤°à¥‡à¤¶ करणे आवशà¥à¤¯à¤• आहे. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.}other{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" />असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° # दिवसांपूरà¥à¤µà¥€ कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. आपलà¥à¤¯à¤¾ संगणकाचे घडà¥à¤¯à¤¾à¤³ सधà¥à¤¯à¤¾ <ph name="CURRENT_DATE" /> वर सेट आहे. ते बरोबर आहे? नसलà¥à¤¯à¤¾à¤¸, आपण आपलà¥à¤¯à¤¾ सिसà¥à¤Ÿà¥€à¤®à¤šà¥‡ घडà¥à¤¯à¤¾à¤³ दà¥à¤°à¥‚सà¥à¤¤ आणि तà¥à¤¯à¤¾à¤¨à¤‚तर हे पृषà¥à¤  रीफà¥à¤°à¥‡à¤¶ करणे आवशà¥à¤¯à¤• आहे. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">कोणतेही UI विकलà¥à¤ª उपलबà¥à¤§ नाहीत</translation>
<translation id="2384307209577226199">à¤à¤‚टरपà¥à¤°à¤¾à¤‡à¤ डीफॉलà¥à¤Ÿ</translation>
<translation id="2386255080630008482">सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ केले गेले.</translation>
<translation id="2392959068659972793">कोणतेही मूलà¥à¤¯ सेट केलà¥à¤¯à¤¾à¤¶à¤¿à¤µà¤¾à¤¯ धोरणे दरà¥à¤¶à¤µà¤¾</translation>
<translation id="239429038616798445">ही शिपिंग पदà¥à¤§à¤¤ उपलबà¥à¤§ नाही. वेगळी पदà¥à¤§à¤¤ वापरून पहा.</translation>
<translation id="2396249848217231973">&amp;हटवा पूरà¥à¤µà¤µà¤¤ करा</translation>
-<translation id="2460160116472764928">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚गला अलीकडे <ph name="SITE" /> वर <ph name="BEGIN_LINK" />मालवेअर आढळले आहे<ph name="END_LINK" />. सामानà¥à¤¯à¤¤à¤ƒ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ असलेलà¥à¤¯à¤¾ वेबसाइट काहीवेळा मालवेअरमà¥à¤³à¥‡ संकà¥à¤°à¤®à¤¿à¤¤ à¤à¤¾à¤²à¥‡à¤²à¥à¤¯à¤¾ असतात. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° कदाचित रदà¥à¤¦ केले असू शकते. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
<translation id="2463739503403862330">भरून टाका</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />नेटवरà¥à¤• निदान चालविणे<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">अवैध शोध URL.</translation>
+<translation id="2482878487686419369">सूचना</translation>
<translation id="2491120439723279231">सरà¥à¤µà¥à¤¹à¤°à¤šà¥à¤¯à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¥€ आहेत.</translation>
<translation id="2495083838625180221">JSON विशà¥à¤²à¥‡à¤·à¤•</translation>
<translation id="2495093607237746763">चेक केलà¥à¤¯à¤¾à¤¸, अधिक जलद फॉरà¥à¤® भरणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ या डिवà¥à¤¹à¤¾à¤‡à¤¸à¤µà¤° Chromium आपलà¥à¤¯à¤¾ कारà¥à¤¡à¤šà¥€ à¤à¤• पà¥à¤°à¤¤ संचयित करेल.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">परत जा</translation>
<translation id="2515629240566999685">आपलà¥à¤¯à¤¾ कà¥à¤·à¥‡à¤¤à¥à¤°à¤¾à¤¤à¥€à¤² सिगà¥à¤¨à¤² तपासणे</translation>
<translation id="2516305470678292029">UI विकलà¥à¤ª</translation>
+<translation id="2539524384386349900">शोधा</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> नी à¤à¤• अवैध पà¥à¤°à¤¤à¤¿à¤¸à¤¾à¤¦ पाठविला.</translation>
-<translation id="2552545117464357659">थोडे नवीन</translation>
<translation id="2556876185419854533">&amp; संपादित करा पूरà¥à¤µà¤µà¤¤ करा</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> कडील. हे आणि अनà¥à¤¯ <ph name="OTHER_ARTICLE_COUNT" /> कथा वाचा.</translation>
<translation id="2587841377698384444">शबà¥à¤¦à¤•à¥‹à¤¶ API आयडी:</translation>
<translation id="2597378329261239068">हा दसà¥à¤¤à¤à¤µà¤œ संकेतशबà¥à¤¦ संरकà¥à¤·à¤¿à¤¤ आहे. कृपया संकेतशबà¥à¤¦ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा.</translation>
<translation id="2609632851001447353">तफावत</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{काहीही नाही}=1{1 अâ€à¥…प ($1)}=2{2 अâ€à¥…पà¥à¤¸ ($1, $2)}one{# अâ€à¥…पॠ($1, $2, $3)}other{# अâ€à¥…पà¥à¤¸ ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">आपले घडà¥à¤¯à¤¾à¤³ पà¥à¤¢à¥‡ आहे</translation>
<translation id="2639739919103226564">सà¥à¤¥à¤¿à¤¤à¥€:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">फाइलवरील पà¥à¤°à¤µà¥‡à¤¶ नाकारणà¥à¤¯à¤¾à¤¤ आला</translation>
<translation id="2653659639078652383">सबमिट करा</translation>
<translation id="2666117266261740852">इतर टॅब किंवा अॅपà¥à¤¸ बंद करा</translation>
+<translation id="2670429602441959756">या पेजमधà¥à¤¯à¥‡ अदà¥à¤¯à¤¾à¤ª VR मधà¥à¤¯à¥‡ समरà¥à¤¥à¤¿à¤¤ नसलेले वैशिषà¥à¤Ÿà¥à¤¯à¥‡ सामावलेली आहेत. बाहेर पडत आहे...</translation>
<translation id="2674170444375937751">आपली खातà¥à¤°à¥€ आहे की आपण ही पृषà¥à¤ à¥‡ आपलà¥â€à¤¯à¤¾ इतिहासातून हटवू इचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="2677748264148917807">सोडा</translation>
-<translation id="269990154133806163">सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पारदरà¥à¤¶à¤•à¤¤à¤¾ धोरणाचा वापर करून सारà¥à¤µà¤œà¤¨à¤¿à¤•à¤°à¤¿à¤¤à¥à¤¯à¤¾ उघड न केलेले à¤à¤• पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले. काही पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ आहेत आणि आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤‚विरूदà¥à¤§ संरकà¥à¤·à¤£ करतात हे सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ तà¥à¤¯à¤¾à¤‚चà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ ही à¤à¤• आवशà¥à¤¯à¤•à¤¤à¤¾ आहे. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">वाचन सूची</translation>
<translation id="2704283930420550640">मूलà¥à¤¯ सà¥à¤µà¤°à¥à¤ªà¤¨à¤¾à¤¶à¥€ जà¥à¤³à¤¤ नाही.</translation>
<translation id="2704951214193499422">Chromium यावेळी आपलà¥à¤¯à¤¾ कारà¥à¤¡à¤šà¥€ पà¥à¤·à¥à¤Ÿà¥€ करणà¥à¤¯à¤¾à¤¤ अकà¥à¤·à¤® होते. कृपया नंतर पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.</translation>
<translation id="2705137772291741111">या साइटची जतन (कॅश केलेली) केलेली पà¥à¤°à¤¤ वाचणà¥à¤¯à¤¾à¤œà¥‹à¤—ी नवà¥à¤¹à¤¤à¥€.</translation>
<translation id="2709516037105925701">ऑटोफिल</translation>
-<translation id="2712118517637785082">आपण <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ सादर केलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° तà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ जारीकरà¥à¤¤à¥à¤¯à¤¾à¤¦à¥à¤µà¤¾à¤°à¥‡ मागे घेतले गेले आहे. याचा अरà¥à¤¥ सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ सादर केलेलà¥à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤²à¤µà¤° अजिबात विशà¥à¤µà¤¾à¤¸ ठेऊ नये. आपण कदाचित आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¶à¥€ संपà¥à¤°à¥‡à¤·à¤£ करत आहात. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">परवानगी मागा</translation>
<translation id="2713444072780614174">पांढरा</translation>
<translation id="2720342946869265578">जवळपास</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">डिवà¥à¤¹à¤¾à¤‡à¤¸ रेकॉरà¥à¤¡ गहाळ</translation>
<translation id="2784949926578158345">कनेकà¥à¤¶à¤¨ रीसेट केले.</translation>
<translation id="2794233252405721443">साइट अवरोधित केली</translation>
+<translation id="2799020568854403057">पà¥à¤¢à¥€à¤² साइटमधà¥à¤¯à¥‡ हानिकारक अॅप आहे</translation>
+<translation id="2803306138276472711">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚गला अलीकडे <ph name="SITE" /> वर <ph name="BEGIN_LINK" />मालवेअर आढळले आहे<ph name="END_LINK" />. सामानà¥à¤¯à¤¤à¤ƒ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ असलेलà¥à¤¯à¤¾ वेबसाइट काहीवेळा मालवेअरमà¥à¤³à¥‡ संकà¥à¤°à¤®à¤¿à¤¤ à¤à¤¾à¤²à¥‡à¤²à¥à¤¯à¤¾ असतात.</translation>
<translation id="2824775600643448204">पतà¥à¤¤à¤¾ आणि शोध बार</translation>
<translation id="2826760142808435982">कनेकà¥à¤¶à¤¨ <ph name="CIPHER" /> वापरून आणि की विनिमय तंतà¥à¤° मà¥à¤¹à¤£à¥‚न <ph name="KX" /> वापर कूटबदà¥à¤§ आणि पà¥à¤°à¤®à¤¾à¤£à¥€à¤•à¥ƒà¤¤ केले आहे.</translation>
<translation id="2835170189407361413">फॉरà¥à¤® कà¥à¤²à¤¿à¤…र करा</translation>
+<translation id="2856444702002559011">हलà¥à¤²à¥‡à¤–ोर कदाचित तà¥à¤®à¤šà¥€ माहिती (उदाहरणारà¥à¤¥ पासवरà¥à¤¡, संदेश किंवा कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> मधून चोरणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करत असतील. <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">रीलोड करॠनका</translation>
<translation id="2900469785430194048">हे वेबपृषà¥à¤  पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करताना Google Chrome ची मेमरी संपली आहे.</translation>
<translation id="2909946352844186028">à¤à¤• नेटवरà¥à¤• बदल आढळला.</translation>
<translation id="2916038427272391327">अनà¥à¤¯ पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® बंद करा</translation>
<translation id="2922350208395188000">सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° तपासणे शकà¥à¤¯ नाही.</translation>
<translation id="2928905813689894207">बिलिंग पतà¥à¤¤à¤¾</translation>
+<translation id="2941952326391522266">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° <ph name="DOMAIN2" /> वरील आहे. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
<translation id="2948083400971632585">आपण सेटिंगà¥à¤œ पृषà¥à¤ à¤¾à¤µà¤°à¥‚न à¤à¤•à¤¾ कनेकà¥à¤¶à¤¨à¤¸à¤¾à¤ à¥€ कॉनà¥à¤«à¤¿à¤—र केलेले कोणतेही पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ अकà¥à¤·à¤® करू शकता.</translation>
<translation id="2955913368246107853">शोध बार बंद करा</translation>
<translation id="2958431318199492670">नेटवरà¥à¤• कॉनà¥à¤«à¤¿à¤—रेशन ONC मानकाचे पालन करत नाही. कॉनà¥à¤«à¤¿à¤—रेशनचे भाग आयात केले जाऊ शकत नाहीत.</translation>
-<translation id="29611076221683977"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वरील आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ सधà¥à¤¯à¤¾ कदाचित आपली माहिती (उदाहरणारà¥à¤¥, फोटो, संकेतशबà¥à¤¦, संदेश आणि कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चोरणारे आणि हटविणारे धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® आपलà¥à¤¯à¤¾ Mac वर सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतात.</translation>
<translation id="2966678944701946121">कालबाहà¥à¤¯à¤¤à¤¾: <ph name="EXPIRATION_DATE_ABBR" />, जोडले: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">à¤à¤• सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥â€à¤¶à¤¨ सà¥â€à¤¥à¤¾à¤ªà¤¿à¤¤ करणà¥â€à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€, आपले घडà¥â€à¤¯à¤¾à¤³ योगà¥à¤¯à¤°à¤¿à¤¤à¥à¤¯à¤¾ सेट केले असणे आवशà¥à¤¯à¤• आहे. वेबसाइट तà¥à¤¯à¤¾à¤‚ना सà¥â€à¤µà¤¤:ला ओळखणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ वापरतात ती पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‡ केवळ निरà¥à¤¦à¤¿à¤·à¥â€à¤Ÿ केलेलà¥â€à¤¯à¤¾ कालावधीसाठी वैध असलà¥à¤¯à¤¾à¤¨à¥‡ हे असू शकते. आपलà¥â€à¤¯à¤¾ डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¤šà¥‡ घडà¥â€à¤¯à¤¾à¤³ चà¥à¤•à¥€à¤šà¥‡ असलà¥â€à¤¯à¤¾à¤®à¥à¤³à¥‡, Google Chrome ही पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‡ सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ करू शकत नाही.</translation>
<translation id="2972581237482394796">&amp;पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">वैध पतà¥à¤¤à¤¾ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा</translation>
<translation id="2986368408720340940">ही पिकअप पदà¥à¤§à¤¤ उपलबà¥à¤§ नाही. वेगळी पदà¥à¤§à¤¤ वापरून पहा.</translation>
<translation id="2991174974383378012">वेबसाइटसह शेअर करीत आहे</translation>
+<translation id="2991571918955627853">ही वेबसाइट HSTS वापरत असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ तà¥à¤®à¥à¤¹à¥€ <ph name="SITE" /> आतà¥à¤¤à¤¾ पाहू शकत नाही. नेटवरà¥à¤• à¤à¤°à¤° आणि आकà¥à¤°à¤®à¤£à¥‡ शकà¥à¤¯à¤¤à¥‹ तातà¥à¤ªà¥à¤°à¤¤à¥€ असतात, तà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ हे पेज नंतर पाहता येईल.</translation>
<translation id="3005723025932146533">जतन केलेली पà¥à¤°à¤¤ दरà¥à¤¶à¤µà¤¾</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> साठी CVC पà¥à¤°à¤µà¤¿à¤·à¥â€à¤Ÿ करा. आपण पà¥à¤·à¥à¤Ÿà¥€ केलà¥à¤¯à¤¾à¤µà¤°, आपले कारà¥à¤¡ तपशील या साइटसह सामायिक केले जातील.</translation>
<translation id="3010559122411665027">सूची पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¥€ "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">आपोआप बà¥à¤²à¥‰à¤• केलेले</translation>
<translation id="3024663005179499861">चà¥à¤•à¥€à¤šà¤¾ धोरण पà¥à¤°à¤•à¤¾à¤°</translation>
<translation id="3032412215588512954">आपण ही साइट पà¥à¤¨à¥à¤¹à¤¾ रीलोड करू इचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="3037605927509011580">चà¥à¤šà¤•!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{संकालित डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸à¤µà¤° किमान 1 आयटम}=1{1 आयटम (आणि संकालित डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸à¤µà¤° आणखी)}one{# आयटम (आणि संकालित डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸à¤µà¤° आणखी)}other{# आयटम (आणि संकालित डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸à¤µà¤° आणखी)}}</translation>
<translation id="3041612393474885105">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° माहिती...</translation>
<translation id="3063697135517575841">Chrome यावेळी आपलà¥à¤¯à¤¾ कारà¥à¤¡à¤šà¥€ पà¥à¤·à¥à¤Ÿà¥€ करणà¥à¤¯à¤¾à¤¤ अकà¥à¤·à¤® होते. कृपया नंतर पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.</translation>
<translation id="3064966200440839136">बाहà¥à¤¯ अनà¥à¤ªà¥à¤°à¤¯à¥‹à¤— दà¥à¤µà¤¾à¤°à¥‡ देय देणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ गà¥à¤ªà¥à¤¤ मोड सोडत आहे. सà¥à¤°à¥ ठेवायचे?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{काहीही नाही}=1{1 पासवरà¥à¤¡}one{# पासवरà¥à¤¡}other{# पासवरà¥à¤¡}}</translation>
<translation id="3093245981617870298">आपण ऑफलाइन आहात.</translation>
<translation id="3105172416063519923">मालमतà¥à¤¤à¤¾ आयडी:</translation>
<translation id="3109728660330352905">हे पृषà¥à¤  पाहणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आपण पà¥à¤°à¤¾à¤§à¤¿à¤•à¥ƒà¤¤ नाही.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />कनेकà¥à¤Ÿà¤¿à¤µà¥à¤¹à¤¿à¤Ÿà¥€ निदान चालवून पहा<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">पà¥à¤°à¤¤à¤¿à¤¸à¤¾à¤¦ डीकोड करणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€</translation>
<translation id="3150653042067488994">तातà¥à¤ªà¥à¤°à¤¤à¥€ सरà¥à¤µà¥à¤¹à¤° तà¥à¤°à¥à¤Ÿà¥€</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">गà¥à¤ªà¥à¤¤ मोडमधà¥â€à¤¯à¥‡ आपण पाहता ती पृषà¥â€à¤ à¥‡ आपण आपले सरà¥à¤µ गà¥à¤ªà¥à¤¤ टॅब बंद केलà¥â€à¤¯à¤¾à¤¨à¤‚तर आपला बà¥à¤°à¤¾à¤‰à¤à¤° इतिहास, कà¥à¤•à¥€ सà¥à¤Ÿà¥‹à¤…र किंवा शोध इतिहासामधà¥â€à¤¯à¥‡ असणार नाहीत. आपण डाउनलोड करता तà¥à¤¯à¤¾ कोणतà¥à¤¯à¤¾à¤¹à¥€ फायली किंवा आपण केलेले बà¥à¤•à¤®à¤¾à¤°à¥à¤• ठेवले जातील.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">बेट</translation>
+<translation id="317583078218509884">पृषà¥â€à¤  रीलोड केलà¥â€à¤¯à¤¾à¤¨à¤‚तर नवीन साइट परवानगà¥à¤¯à¤¾ सेटिंगà¥â€à¤œ पà¥à¤°à¤­à¤¾à¤µà¥€ होतील.</translation>
<translation id="3176929007561373547">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° कारà¥à¤¯ करीत आहे हे सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आपलà¥à¤¯à¤¾ पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सेटिंगà¥à¤œ तपासा
किंवा आपलà¥à¤¯à¤¾ नेटवरà¥à¤• पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¶à¥€ संपरà¥à¤• साधा. आपण पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° वापरत
आहात यावर आपला विशà¥à¤µà¤¾à¤¸ नसलà¥à¤¯à¤¾à¤¸:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">गà¥à¤ªà¥à¤¤ मोडमधà¥â€à¤¯à¥‡ पृषà¥à¤  उघडा</translation>
-<translation id="3202578601642193415">नवीनâ€à¤¤à¤®</translation>
+<translation id="320323717674993345">पेमेंट रदà¥à¤¦ करा</translation>
<translation id="3207960819495026254">बà¥à¤•à¤®à¤¾à¤°à¥à¤• केलेली</translation>
+<translation id="3225919329040284222">सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ असे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले आहे जे अंगभूत अपेकà¥à¤·à¤¾à¤‚शी जà¥à¤³à¤¤ नाही. या अपेकà¥à¤·à¤¾ आपलà¥à¤¯à¤¾à¤²à¤¾ संरकà¥à¤·à¤¿à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ विशिषà¥à¤Ÿ, उचà¥à¤š-सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¥‡à¤šà¥à¤¯à¤¾ वेबसाइटसाठी समाविषà¥à¤Ÿ केलà¥à¤¯à¤¾ आहेत.</translation>
<translation id="3226128629678568754">पृषà¥à¤  लोड करणà¥à¤¯à¤¾à¤¸ आवशà¥à¤¯à¤• असलेला डेटा पà¥à¤¨à¥à¤¹à¤¾ सबमिट करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ रीलोड बटण दाबा.</translation>
+<translation id="3227137524299004712">मायकà¥à¤°à¥‹à¤«à¥‹à¤¨</translation>
<translation id="3228969707346345236">वà¥à¤¯à¤µà¤¹à¤¾à¤° अयशसà¥à¤µà¥€ à¤à¤¾à¤²à¤¾ कारण पृषà¥à¤  पूरà¥à¤µà¥€à¤ªà¤¾à¤¸à¥‚न <ph name="LANGUAGE" /> मधà¥à¤¯à¥‡ आहे.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> साठी CVC पà¥à¤°à¤µà¤¿à¤·à¥â€à¤Ÿ करा</translation>
+<translation id="3234666976984236645">नेहमी या साइटवर महतà¥à¤¤à¥à¤µà¤¾à¤šà¥€ सामगà¥à¤°à¥€ शोधा</translation>
<translation id="3254409185687681395">या पृषà¥à¤ à¤¾à¤¸ बà¥à¤•à¤®à¤¾à¤°à¥à¤• करा</translation>
<translation id="3270847123878663523">&amp;पà¥à¤¨à¤°à¥à¤•à¥à¤°à¤®à¤¿à¤¤ करा पूरà¥à¤µà¤µà¤¤ करा</translation>
<translation id="3282497668470633863">कारà¥à¤¡à¤µà¤° नाव जोडा</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">सेटिंगà¥à¤œ</translation>
<translation id="3345135638360864351">या साइटवर पà¥à¤°à¤µà¥‡à¤¶ करणà¥à¤¯à¤¾à¤šà¥€ आपली विनंती <ph name="NAME" /> कडे पाठविली जाऊ शकली नाही. कृपया पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.</translation>
<translation id="3355823806454867987">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सेटिंगà¥à¤œ बदला...</translation>
+<translation id="3361596688432910856">Chrome पà¥à¤¢à¥€à¤² माहिती <ph name="BEGIN_EMPHASIS" />सेवà¥à¤¹ करणार नाही<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />आपला बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग इतिहास
+ <ph name="LIST_ITEM" />कà¥à¤•à¥€à¤œ आणि साइट डेटा
+ <ph name="LIST_ITEM" />फॉरà¥à¤®à¤®à¤§à¥à¤¯à¥‡ टाकलेली माहिती
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">घडà¥à¤¯à¤¾à¤³ तà¥à¤°à¥à¤Ÿà¥€</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> अधिक आयटम...</translation>
<translation id="337363190475750230">तरतूद रदà¥à¤¦ केली</translation>
<translation id="3377188786107721145">धोरण विशà¥à¤²à¥‡à¤·à¤£ तà¥à¤°à¥à¤Ÿà¥€</translation>
<translation id="3380365263193509176">अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¥€</translation>
<translation id="3380864720620200369">कà¥à¤²à¤¾à¤¯à¤‚ट आयडी:</translation>
<translation id="3391030046425686457">वितरण पतà¥à¤¤à¤¾</translation>
<translation id="3395827396354264108">पिकअप पदà¥à¤§à¤¤</translation>
-<translation id="340013220407300675">आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ कदाचित <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वरून आपली माहिती चोरणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करत असू शकतात (उदाहरणारà¥à¤¥, संकेतशबà¥à¤¦, संदेश किंवा कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡).</translation>
<translation id="3422248202833853650">मेमरी मोकळी करणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ अनà¥à¤¯ पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® मधून बाहर पडणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> सधà¥à¤¯à¤¾ आवाकà¥à¤¯à¤¾à¤¬à¤¾à¤¹à¥‡à¤° आहे.</translation>
+<translation id="3427092606871434483">अनà¥à¤®à¤¤à¥€ दà¥à¤¯à¤¾ (डीफॉलà¥à¤Ÿ)</translation>
<translation id="3427342743765426898">&amp;संपादित करा पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
<translation id="3431636764301398940">या डिवà¥à¤¹à¤¾à¤‡à¤¸à¤µà¤° हे कारà¥à¤¡ जतन करा</translation>
<translation id="3435896845095436175">सकà¥à¤·à¤® करा</translation>
<translation id="3447661539832366887">या डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¥à¤¯à¤¾ मालकाने डायनासोर गेम बंद केला आहे.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">मधà¥à¤¯à¤‚तर पà¥à¤°à¤¾à¤ªà¥à¤¤ करा:</translation>
<translation id="3462200631372590220">पà¥à¤°à¤—त लपवा</translation>
<translation id="3467763166455606212">कारà¥à¤¡à¤§à¤¾à¤°à¤•à¤¾à¤šà¥‡ नाव आवशà¥à¤¯à¤•</translation>
<translation id="3478058380795961209">कालबाहà¥à¤¯à¤¤à¤¾ महिना:</translation>
<translation id="3479539252931486093">हे अनपेकà¥à¤·à¤¿à¤¤ होते? <ph name="BEGIN_LINK" />आमà¥à¤¹à¤¾à¤²à¤¾ कळवा<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">सधà¥à¤¯à¤¾ नाही</translation>
-<translation id="348000606199325318">कà¥à¤°à¥…श आयडी <ph name="CRASH_LOCAL_ID" /> (सरà¥à¤µà¥à¤¹à¤° आयडी: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">याकà¥à¤·à¤£à¥€ आमà¥à¤¹à¥€ आपलà¥à¤¯à¤¾ पालकांपरà¥à¤¯à¤‚त पोहोचू शकलो नाही. कृपया पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.</translation>
<translation id="3528171143076753409">सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° विशà¥à¤µà¤¾à¤¸à¤¨à¥€à¤¯ नाही.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{ सिंक केलेलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤µà¤° किमान 1 आयटम}=1{1 आयटम (सिंक केलेलà¥à¤¯à¤¾ डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¤µà¤° आणखी काही)}one{# आयटम (सिंक केलेलà¥à¤¯à¤¾ डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¤µà¤° आणखी काही)}other{# आयटम (सिंक केलेलà¥à¤¯à¤¾ डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¤µà¤° आणि आणखी काही)}}</translation>
<translation id="3539171420378717834">या डिवà¥à¤¹à¤¾à¤‡à¤¸à¤µà¤° या कारà¥à¤¡à¤šà¥€ à¤à¤• पà¥à¤°à¤¤ ठेवा</translation>
<translation id="3542684924769048008">यासाठी संकेतशबà¥à¤¦ वापरा:</translation>
+<translation id="3545341443414427877">तà¥à¤®à¤šà¥à¤¯à¤¾ काà¤à¤ªà¥à¤¯à¥à¤Ÿà¤°à¤šà¥€ तारीख आणि वेळ (<ph name="DATE_AND_TIME" />) चà¥à¤•à¥€à¤šà¥€ असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> साठी à¤à¤• खासगी कनेकà¥à¤¶à¤¨ तयार करू शकत नाही. <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">आपलà¥à¤¯à¤¾ सà¥à¤µà¤¤à¤ƒà¤šà¥à¤¯à¤¾ वाकà¥à¤¯à¤¾à¤‚शासह सरà¥à¤µ संंकालित केलेला डेटा कूटबदà¥à¤§ करा</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> अधिक...</translation>
-<translation id="3555561725129903880">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचे सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° <ph name="DOMAIN2" /> कडून आलेले आहे. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">आपला वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤• आपलà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ ती अनावरोधित करू शकतो</translation>
<translation id="3566021033012934673">आपले कनेकà¥à¤¶à¤¨ खाजगी नाही</translation>
+<translation id="3569145463236695319">&lt;p&gt;तà¥à¤®à¤šà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¥€ तारीख आणि वेळ (<ph name="DATE_AND_TIME" />) चà¥à¤•à¥€à¤šà¥€ असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> साठी à¤à¤• खाजगी कनेकà¥à¤¶à¤¨ तयार करू शकत नाही.&lt;/p&gt;
+
+ &lt;p&gt;कृपया अâ€à¥…पचà¥à¤¯à¤¾ &lt;strong&gt;सेटिंगà¥à¤œ&lt;/strong&gt; मधील &lt;strong&gt;सामानà¥à¤¯&lt;/strong&gt; विभागातून तारीख आणि वेळ नीट करा.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">नाव जोडा</translation>
<translation id="3583757800736429874">&amp;हलवा पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
<translation id="3586931643579894722">तपशील लपवा</translation>
-<translation id="3587482841069643663">सरà¥à¤µ</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">वैध समापà¥à¤¤à¥€ दिनांक पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा</translation>
<translation id="36224234498066874">बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग डेटा साफ करा...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° माहिती...</translation>
<translation id="3690164694835360974">लॉग इन सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नाही</translation>
<translation id="3693415264595406141">संकेतशबà¥à¤¦:</translation>
-<translation id="3696411085566228381">काहीही नाही</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">लोड करीत आहे...</translation>
<translation id="3712624925041724820">परवाने संपà¥à¤·à¥à¤Ÿà¤¾à¤¤</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />पà¥à¤°à¥‰à¤•à¥à¤¸à¥€, फायरवॉल आणि DNS कॉनà¥à¤«à¤¿à¤—रेशन तपासणे<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">आपलà¥à¤¯à¤¾à¤²à¤¾ आपलà¥à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¥‡à¤šà¥à¤¯à¤¾ जोखमी समजत असलà¥à¤¯à¤¾à¤¸, धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® काढणà¥à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€ आपण <ph name="BEGIN_LINK" />या असà¥à¤°à¤•à¥à¤·à¤¿à¤¤ साइटला भेट देऊ शकता<ph name="END_LINK" />.</translation>
<translation id="3739623965217189342">आपण कॉपी केलेलà¥à¤¯à¤¾à¤šà¤¾ दà¥à¤µà¤¾ जोडा</translation>
+<translation id="3744899669254331632">Chromium पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ करू शकत नसलेले सरमिसळ केलेले कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥â€à¤¶à¤¿à¤¯à¤² वेबसाइटने पाठविलà¥â€à¤¯à¤¾à¤¨à¥‡ आपण आतà¥à¤¤à¤¾ <ph name="SITE" /> ला भेट देऊ शकत नाही. नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€ आणि आकà¥à¤°à¤®à¤£ सहसा तातà¥à¤ªà¥à¤°à¤¤à¥‡ आहेत तà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ संभवत: हे पृषà¥â€à¤  नंतर कारà¥à¤¯ करेल.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वरील हलà¥à¤²à¥‡à¤–ोर कदाचित तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ सॉफà¥à¤Ÿà¤µà¥‡à¤…र इंसà¥à¤Ÿà¥‰à¤² करणे किंवा तà¥à¤®à¤šà¥€ वैयकà¥à¤¤à¤¿à¤• माहिती (उदाहरणारà¥à¤¥, पासवरà¥à¤¡, फोन नंबर किंवा कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡à¥‡) उघड करणे यासारखà¥à¤¯à¤¾ काही धोकादायक गोषà¥à¤Ÿà¥€ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ फसवू शकतात. <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">सरà¥à¤µà¥à¤¹à¤° तà¥à¤°à¥à¤Ÿà¥€à¤®à¥à¤³à¥‡ भाषांतर अयशसà¥à¤µà¥€ à¤à¤¾à¤²à¤¾.</translation>
<translation id="3759461132968374835">आपण अलीकडे कोणतेही कà¥à¤°à¥…श नोंदवले नाहीत. कà¥à¤°à¥…श नोंदवणे अकà¥à¤·à¤® असताना à¤à¤¾à¤²à¥‡à¤²à¥‡ कà¥à¤°à¥…श येथे दिसून येणार नाहीत.</translation>
+<translation id="3778403066972421603">तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ हे कारà¥à¤¡ तà¥à¤®à¤šà¥à¤¯à¤¾ Google खातà¥à¤¯à¤¾à¤®à¤§à¥à¤¯à¥‡ आणि या डिवà¥à¤¹à¤¾à¤‡à¤¸à¤µà¤° सेवà¥à¤¹ करायचे आहे का?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">समापà¥à¤¤ होते: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">आपण पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° वापरत असलà¥à¤¯à¤¾à¤¸...</translation>
<translation id="3828924085048779000">रिकà¥à¤¤ सांकेतिक वाकà¥à¤¯à¤¾à¤‚शाची परवानगी नाही.</translation>
-<translation id="3845539888601087042">आपलà¥à¤¯à¤¾ साइन-इन केलेलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸ वरील इतिहास दरà¥à¤¶à¤µà¤¿à¤¤ आहे. <ph name="BEGIN_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">मागील</translation>
<translation id="3858027520442213535">तारीख आणि वेळ अदà¥à¤¯à¤¤à¤¨à¤¿à¤¤ करा</translation>
<translation id="3884278016824448484">संघरà¥à¤· करणारा डिवà¥à¤¹à¤¾à¤‡à¤¸ अभिजà¥à¤žà¤¾à¤ªà¤•</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">या साइटवर पà¥à¤°à¤µà¥‡à¤¶ करणà¥à¤¯à¤¾à¤šà¥€ आपली विनंती <ph name="NAME" /> कडे पाठविली गेली आहे</translation>
<translation id="3890664840433101773">ईमेल जोडा</translation>
<translation id="3901925938762663762">कारà¥à¤¡ कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡ आहे</translation>
-<translation id="3933571093587347751">{1,plural, =1{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° उदà¥à¤¯à¤¾à¤ªà¤¾à¤¸à¥‚न मानले जाईल. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.}one{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤¢à¥€à¤² # दिवसांपासून मानले जाईल. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.}other{हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पà¥à¤¢à¥€à¤² # दिवसांपासून मानले जाईल. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF दसà¥à¤¤à¤à¤µà¤œ लोड करणे अयशसà¥à¤µà¥€</translation>
+<translation id="3945915738023014686">कà¥à¤°à¥…श तकà¥à¤°à¤¾à¤° आयडी अपलोड केला<ph name="CRASH_ID" /> (सà¥à¤¥à¤¾à¤¨à¤¿à¤• कà¥à¤°à¥…श आयडी: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">हा सरà¥à¤µà¥à¤¹à¤° <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° विषय परà¥à¤¯à¤¾à¤¯à¥€ नावांचा उलà¥à¤²à¥‡à¤– करत नाही. हे कदाचित चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉंफिगरेशनमà¥à¤³à¥‡ होत आहे किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ तà¥à¤®à¤šà¥à¤¯à¤¾ कनेकà¥à¤¶à¤¨à¤®à¤§à¥à¤¯à¥‡ अडथळा आणत आहे.</translation>
<translation id="3963721102035795474">वाचक मोड</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{काहीही नाही}=1{1 साइटकडून }one{# साइटकडून }other{# साइटकडून }}</translation>
<translation id="397105322502079400">गणना करत आहे...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> अवरोधित केले आहे</translation>
+<translation id="3987940399970879459">1 MB पेकà¥à¤·à¤¾ कमी</translation>
<translation id="40103911065039147">{URL_count,plural, =1{जवळपास 1 वेब पृषà¥â€à¤ }one{जवळपास # वेब पृषà¥â€à¤ }other{जवळपास # वेब पृषà¥à¤ à¥‡}}</translation>
<translation id="4021036232240155012">DNS ही नेटवरà¥à¤• सेवा आहे जी वेबसाइटचे नाव तिचà¥à¤¯à¤¾ इंटरनेट पतà¥à¤¤à¥à¤¯à¤¾à¤®à¤§à¥â€à¤¯à¥‡ भाषांतरित करते.</translation>
<translation id="4030383055268325496">&amp;जोडा पूरà¥à¤µà¤µà¤¤ करा</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ कॉनà¥à¤«à¤¿à¤—रेशन .pac सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ URL वापरणà¥â€à¤¯à¤¾à¤¸ सेट करणà¥â€à¤¯à¤¾à¤¤ आले आहे, निशà¥à¤šà¤¿à¤¤ पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° नवà¥à¤¹à¥‡.</translation>
<translation id="4098354747657067197">भà¥à¤°à¤¾à¤®à¤• साइट पà¥à¤¢à¥‡ आहे</translation>
<translation id="4103249731201008433">डिवà¥à¤¹à¤¾à¤‡à¤¸ सिरीयल कà¥à¤°à¤®à¤¾à¤‚क अवैध आहे</translation>
+<translation id="410351446219883937">ऑटोपà¥à¤²à¥‡</translation>
<translation id="4103763322291513355">आपलà¥à¤¯à¤¾ सिसà¥à¤Ÿà¥€à¤® पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¦à¥à¤µà¤¾à¤°à¥‡ पà¥à¤°à¤µà¤°à¥à¤¤à¤¿à¤¤ काळà¥à¤¯à¤¾à¤¸à¥‚चीतील URLs आणि अनà¥à¤¯ धोरणांची सूची पाहणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ &lt;strong&gt;chrome://policy&lt;/strong&gt; ला भेट दà¥à¤¯à¤¾.</translation>
-<translation id="4110615724604346410">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचà¥à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¤¾à¤®à¤§à¥à¤¯à¥‡ तà¥à¤°à¥à¤Ÿà¥€ आहेत. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">किरमिजी</translation>
+<translation id="4116663294526079822">या साइटवर नेहमी अनà¥à¤®à¤¤à¥€ दà¥à¤¯à¤¾</translation>
<translation id="4117700440116928470">धोरण ककà¥à¤·à¤¾ समरà¥à¤¥à¤¿à¤¤ नाही.</translation>
-<translation id="4118212371799607889">हा सरà¥à¤µà¥à¤¹à¤° <ph name="DOMAIN" /> हे असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचे सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° Chromium दà¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही; हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{अनà¥à¤¯ 1}one{अनà¥à¤¯ #}other{अनà¥à¤¯ #}}</translation>
<translation id="4130226655945681476">नेटवरà¥à¤• केबल, मोडेम आणि राउटर तपासत आहे</translation>
+<translation id="413544239732274901">आणखी जाणून घà¥à¤¯à¤¾</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">जागतिक डीफॉलà¥â€à¤Ÿ (शोधणे) वापरा</translation>
+<translation id="4165986682804962316">साइट सेटिंगà¥à¤œ</translation>
<translation id="4169947484918424451">Chromium ने हे कारà¥à¤¡ जतन करावे असे आपण इचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="4171400957073367226">खराब सतà¥à¤¯à¤¾à¤ªà¤¨ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€</translation>
<translation id="4196861286325780578">&amp;हलवा पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />फायरवॉल आणि अà¤à¤Ÿà¥€à¤µà¥à¤¹à¤¾à¤¯à¤°à¤¸ कॉनà¥à¤«à¤¿à¤—रेशन तपासणे<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{काहीही नाही}=1{1 अâ€à¥…प ($1)}=2{2 अâ€à¥…पà¥à¤¸ ($1, $2)}one{# अâ€à¥…पà¥à¤¸ ($1, $2, $3)}other{# अâ€à¥…पà¥à¤¸ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">कà¥à¤°à¥…श होते</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वरील हलà¥à¤²à¥‡à¤–ोर कदाचित तà¥à¤®à¤šà¥à¤¯à¤¾ बà¥à¤°à¤¾à¤‰à¤ करणà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ अनà¥à¤­à¤µà¤¾à¤²à¤¾ हानिकारक असे पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® (उदाहरणारà¥à¤¥, तà¥à¤®à¤šà¥‡ होमपेज बदलणे किंवा तà¥à¤®à¥à¤¹à¥€ भेट दिलेलà¥à¤¯à¤¾ साइटवर जासà¥à¤¤à¥€à¤šà¥à¤¯à¤¾ जाहिराती दाखवणे) इंसà¥à¤Ÿà¥‰à¤² करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ फसवणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतात. <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />नेटवरà¥à¤• निदान चालवून पहा<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">वैध</translation>
<translation id="4250431568374086873">या साइटवरील आपले कनेकà¥à¤¶à¤¨ पूरà¥à¤£à¤ªà¤£à¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नाही</translation>
<translation id="4250680216510889253">नाही</translation>
<translation id="425582637250725228">आपण केलेले बदल कदाचित जतन केले जाणार नाहीत.</translation>
<translation id="4258748452823770588">खराब सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€</translation>
+<translation id="4265872034478892965">तà¥à¤®à¤šà¥à¤¯à¤¾ पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤•à¤¡à¥‚न अनà¥à¤®à¤¤à¥€ असलेले</translation>
<translation id="4269787794583293679">(वापरकरà¥à¤¤à¤¾à¤¨à¤¾à¤µ नाही)</translation>
<translation id="4275830172053184480">आपला डिवà¥à¤¹à¤¾à¤‡à¤¸ रीसà¥à¤Ÿà¤¾à¤°à¥à¤Ÿ करा</translation>
<translation id="4280429058323657511">, कालबाहà¥à¤¯à¤¤à¤¾ <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚गला <ph name="SITE" /> वर <ph name="BEGIN_LINK" />हानिकारक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® आढळले<ph name="END_LINK" /> <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">पालक सूचना</translation>
<translation id="4304224509867189079">लॉग इन</translation>
-<translation id="432290197980158659">सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले जे अंगभूत अपेकà¥à¤·à¤¾à¤‚शी जà¥à¤³à¤¤ नाही. या अपेकà¥à¤·à¤¾ आपलà¥à¤¯à¤¾à¤²à¤¾ संरकà¥à¤·à¤¿à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ विशिषà¥à¤Ÿ, उचà¥à¤š-सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¥‡à¤šà¥à¤¯à¤¾ वेबसाइटसाठी समाविषà¥à¤Ÿ केलà¥à¤¯à¤¾ आहेत. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">अवरोधित करा (डीफॉलà¥à¤Ÿ)</translation>
<translation id="4325863107915753736">लेख शोधणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€</translation>
<translation id="4326324639298822553">आपली कालबाहà¥à¤¯à¤¤à¤¾ तारीख तपासा आणि पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा</translation>
<translation id="4331708818696583467">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नाही</translation>
<translation id="4356973930735388585">या साइट वरील आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ आपली माहिती (उदाहरणारà¥à¤¥, फोटो, संकेतशबà¥à¤¦, संदेश आणि कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चोरणारे किंवा हटविणारे धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® आपलà¥à¤¯à¤¾ संगणकावर सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणà¥â€à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतात.</translation>
<translation id="4372948949327679948">अपेकà¥à¤·à¤¿à¤¤ <ph name="VALUE_TYPE" /> मूलà¥à¤¯.</translation>
+<translation id="4377125064752653719">आपण <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ सादर केलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° तà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ जारीकरà¥à¤¤à¥à¤¯à¤¾à¤¦à¥à¤µà¤¾à¤°à¥‡ मागे घेतले गेले आहे. याचा अरà¥à¤¥ सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ सादर केलेलà¥à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¤¾ कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤²à¤µà¤° अजिबात ठेवला जाऊ नये. आपण कदाचित आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¶à¥€ संपà¥à¤°à¥‡à¤·à¤£ करत आहात.</translation>
<translation id="4381091992796011497">वापरकरà¥à¤¤à¤¾ नाव:</translation>
<translation id="4394049700291259645">अकà¥à¤·à¤® करा</translation>
<translation id="4406896451731180161">शोध परिणाम</translation>
+<translation id="4424024547088906515">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° Chrome दà¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ने आपले लॉग इन पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सà¥à¤µà¥€à¤•à¤¾à¤°à¤²à¥‡ नाही किंवा कदाचित पà¥à¤°à¤¦à¤¾à¤¨ केले गेले नसावे.</translation>
<translation id="443673843213245140">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€à¤šà¤¾ वापर अकà¥à¤·à¤® करणà¥â€à¤¯à¤¾à¤¤ आला आहे पण à¤à¤• सà¥à¤¸à¥à¤ªà¤·à¥â€à¤Ÿ पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ कॉनà¥â€à¤«à¤¿à¤—रेशन निरà¥à¤¦à¤¿à¤·à¥â€à¤Ÿ करणà¥â€à¤¯à¤¾à¤¤ आले आहे.</translation>
-<translation id="4492190037599258964">'<ph name="SEARCH_STRING" />' साठी शोध परिणाम</translation>
<translation id="4506176782989081258">पà¥à¤°à¤®à¤¾à¤£à¥€à¤•à¤°à¤£ तà¥à¤°à¥à¤Ÿà¥€: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">सिसà¥à¤Ÿà¥€à¤® पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¶à¥€ संपरà¥à¤• साधणे</translation>
<translation id="450710068430902550">पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¸à¤¹ सामायिक करीत आहे</translation>
<translation id="4515275063822566619">कारà¥à¤¡ आणि पतà¥à¤¤à¥‡ Chrome आणि आपलà¥à¤¯à¤¾ Google खातà¥à¤¯à¤¾à¤•à¤¡à¥€à¤² (<ph name="ACCOUNT_EMAIL" />) आहेत. आपण तà¥à¤¯à¤¾à¤‚ना <ph name="BEGIN_LINK" />सेटिंगà¥â€à¤œ<ph name="END_LINK" /> मधून वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ करू शकता.</translation>
<translation id="4522570452068850558">तपशील</translation>
+<translation id="4552089082226364758">फà¥à¤²à¥…श</translation>
<translation id="4558551763791394412">आपले विसà¥à¤¤à¤¾à¤° अकà¥à¤·à¤® करून पहा.</translation>
<translation id="457875822857220463">वितरण</translation>
<translation id="4587425331216688090">Chrome मधून पतà¥à¤¤à¤¾ काढायचा?</translation>
-<translation id="4589078953350245614">आपण <ph name="DOMAIN" /> येथे पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ अवैध पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">आपले <ph name="DOMAIN" /> वरील कनेकà¥à¤¶à¤¨ आधà¥à¤¨à¤¿à¤• सायफर सूट वापरून कूटबदà¥à¤§ केलेले आहे.</translation>
<translation id="4594403342090139922">&amp;हटवा पूरà¥à¤µà¤µà¤¤ करा</translation>
<translation id="4619615317237390068">अनà¥à¤¯ डिवà¥à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸à¤®à¤§à¥€à¤² टॅब</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¥€ आहेत. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
+<translation id="4690462567478992370">अवैध पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° वापरणे थांबवा</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">आपलà¥à¤¯à¤¾ कनेकà¥à¤¶à¤¨à¤®à¤§à¥à¤¯à¥‡ वà¥à¤¯à¤¤à¥à¤¯à¤¯ आला</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows नेटवरà¥à¤• निदान चालविणे<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">à¤à¤• अजà¥à¤žà¤¾à¤¤ तà¥à¤°à¥à¤Ÿà¥€ आली आहे.</translation>
<translation id="4800132727771399293">आपली कालबाहà¥à¤¯à¤¤à¤¾ तारीख आणि CVC तपासा आणि पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Google Chrome पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ करू शकत नाही असे न समजणारे कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤² वेबसाइटने पाठविलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ आपण आतà¥à¤¤à¤¾ <ph name="SITE" /> ला भेट देऊ शकत नाही. नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€ आणि आकà¥à¤°à¤®à¤£ सामानà¥à¤¯à¤¤à¤ƒ तातà¥à¤ªà¥à¤°à¤¤à¥‡ असतात, यामà¥à¤³à¥‡ हे पृषà¥à¤  कदाचित नंतर कारà¥à¤¯ करेल.</translation>
<translation id="4813512666221746211">नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€</translation>
<translation id="4816492930507672669">पृषà¥â€à¤ à¤¾à¤¨à¥à¤°à¥à¤ª करा</translation>
<translation id="483020001682031208">दरà¥à¤¶à¤µà¤¿à¤£à¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ कोणतीही वासà¥à¤¤à¤µà¤¿à¤• वेब पृषà¥à¤ à¥‡ नाहीत</translation>
<translation id="4850886885716139402">पहा</translation>
<translation id="4854362297993841467">ही वितरण पदà¥à¤§à¤¤ उपलबà¥à¤§ नाही. वेगळी पदà¥à¤§à¤¤ वापरून पहा.</translation>
<translation id="4858792381671956233">या साइटला भेट देणे ठीक आहे का ते आपण आपलà¥â€à¤¯à¤¾ पालकांना विचारले</translation>
+<translation id="4863764087567530506">हा आशय सॉफà¥à¤Ÿà¤µà¥‡à¤…र इंसà¥à¤Ÿà¥‰à¤² करणे किंवा वैयकà¥à¤¤à¤¿à¤• माहिती उघड करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ फसवणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकते. <ph name="BEGIN_LINK" />तरीही दाखवा<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">इतिहास शोध</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{आणि 1 आणखी वेब पृषà¥à¤ }one{आणि # आणखी वेब पृषà¥â€à¤ }other{आणि # आणखी वेब पृषà¥à¤ à¥‡}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">हे पृषà¥à¤  अजà¥à¤žà¤¾à¤¤ भाषेतून <ph name="LANGUAGE_LANGUAGE" /> मधà¥à¤¯à¥‡ अनà¥à¤µà¤¾à¤¦à¤¿à¤¤ करणà¥à¤¯à¤¾à¤¤ आले</translation>
<translation id="4923459931733593730">देयक</translation>
<translation id="4926049483395192435">निरà¥à¤¦à¤¿à¤·à¥â€à¤Ÿ केले जाणे आवशà¥â€à¤¯à¤• आहे.</translation>
<translation id="495170559598752135">कà¥à¤°à¤¿à¤¯à¤¾</translation>
<translation id="4958444002117714549">सूची विसà¥à¤¤à¥ƒà¤¤ करा</translation>
-<translation id="4962322354953122629">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचे सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° Chrome दà¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही; हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">चेतावणà¥à¤¯à¤¾ पà¥à¤¨à¥à¤¹à¤¾ सकà¥à¤·à¤® करा</translation>
<translation id="4989809363548539747">हे पà¥à¤²à¤—िन समरà¥à¤¥à¤¿à¤¤ नाही</translation>
<translation id="5002932099480077015">सकà¥à¤·à¤® केलà¥â€à¤¯à¤¾à¤¸, Chrome जलदपणे फॉरà¥à¤® भरणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आपलà¥â€à¤¯à¤¾ कारà¥à¤¡à¤šà¥€ à¤à¤• पà¥à¤°à¤¤ या डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¤µà¤° संगà¥à¤°à¤¹à¤¿à¤¤ करेल.</translation>
<translation id="5018422839182700155">हे पृषà¥â€à¤  उघडू शकत नाही</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">आपलà¥à¤¯à¤¾ पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤šà¥€ धोरणे तपासा</translation>
<translation id="5029568752722684782">कॉपी साफ करा</translation>
<translation id="5031870354684148875">Google भाषांतर बदà¥à¤¦à¤²</translation>
+<translation id="5039804452771397117">परवानगी दà¥à¤¯à¤¾</translation>
<translation id="5040262127954254034">गोपनीयता</translation>
<translation id="5045550434625856497">अयोगà¥à¤¯ संकेतशबà¥à¤¦</translation>
<translation id="5056549851600133418">आपलà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ लेख</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ पतà¥à¤¤à¤¾ तपासणे<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{कà¥à¤•à¥€à¤œ नाहीत}=1{1 साइट कà¥à¤•à¥€à¤œ वापरते. }one{# साइट कà¥à¤•à¥€à¤œ वापरते. }other{# साइट कà¥à¤•à¥€à¤œ वापरतात. }}</translation>
<translation id="5087286274860437796">यावेळी सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° वैध नाही.</translation>
<translation id="5087580092889165836">कारà¥à¤¡ जोडा</translation>
<translation id="5089810972385038852">राजà¥à¤¯</translation>
+<translation id="5094747076828555589">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° Chromium दà¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
<translation id="5095208057601539847">पà¥à¤°à¤¾à¤‚त</translation>
<translation id="5115563688576182185">(64-बिट)</translation>
<translation id="5141240743006678641">आपलà¥à¤¯à¤¾ Google कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤²à¤¸à¤¹ संंकालित केलेले संकेतशबà¥à¤¦ कूटबदà¥à¤§ करा</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">ईमेल आवशà¥à¤¯à¤• आहे</translation>
<translation id="5251803541071282808">कà¥à¤²à¤¾à¤‰à¤¡</translation>
<translation id="5277279256032773186">कारà¥à¤¯à¤¸à¥à¤¥à¤¾à¤¨à¥€ Chrome वापरत आहात? वà¥à¤¯à¤µà¤¸à¤¾à¤¯ तà¥à¤¯à¤¾à¤‚चà¥à¤¯à¤¾ करà¥à¤®à¤šà¤¾à¤°à¥â€à¤¯à¤¾à¤‚ंसाठी Chrome सेटिंगà¥à¤œ वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ करू शकतात. अधिक जाणनू घà¥à¤¯à¤¾</translation>
+<translation id="5297526204711817721">या साइटवरील आपले कनेकà¥à¤¶à¤¨ खाजगी नाही. VR मोड मधून बाहेर पडणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€, हेडसेट काढा आणि मागे दाबा.</translation>
<translation id="5299298092464848405">धोरण विशà¥à¤²à¥‡à¤·à¤¿à¤¤ करताना तà¥à¤°à¥à¤Ÿà¥€</translation>
-<translation id="5300589172476337783">दरà¥à¤¶à¤µà¤¾</translation>
<translation id="5308689395849655368">कà¥à¤°à¥…श अहवाल अकà¥à¤·à¤® केला गेला आहे.</translation>
<translation id="5317780077021120954">जतन करा</translation>
<translation id="5327248766486351172">नाव</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वरील आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ सॉफà¥â€à¤Ÿà¤µà¥‡à¤…र सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणे किंवा आपली वैवकà¥à¤¤à¤¿à¤• माहिती (उदाहरणारà¥à¤¥, संकेतशबà¥à¤¦, फोन नंबर किंवा कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) उघड करणे यासारखे काहीतरी धोकादायक करणà¥â€à¤¯à¤¾à¤®à¤§à¥â€à¤¯à¥‡ आपलà¥â€à¤¯à¤¾à¤²à¤¾ यà¥à¤•à¥à¤¤à¥€à¤¨à¥‡ गà¥à¤‚तवू शकतात.</translation>
-<translation id="5359637492792381994">हा सरà¥à¤µà¥à¤¹à¤° <ph name="DOMAIN" /> हे असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचे सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° यावेळी वैध नाही हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">तà¥à¤®à¥à¤¹à¥€ आतà¥à¤¤à¤¾ <ph name="SITE" /> ला भेट देऊ शकत नाही कारण तिचे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ केले गेले आहे. नेटवरà¥à¤• à¤à¤°à¤° आणि आकà¥à¤°à¤®à¤£à¥‡ शकà¥à¤¯à¤¤à¥‹ तातà¥à¤ªà¥à¤°à¤¤à¥€ असतात, तà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ हे पेज नंतर पाहता येईल.</translation>
<translation id="536296301121032821">धोरण सेटिंगà¥à¤œ संचयित करणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€</translation>
<translation id="5386426401304769735">या साइटसाठी असलेलà¥à¤¯à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° शà¥à¤°à¥ƒà¤‚खलेत SHA-1 वापरून सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ केलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° असते.</translation>
<translation id="5402410679244714488">कालबाहà¥à¤¯à¤¤à¤¾: <ph name="EXPIRATION_DATE_ABBR" />, à¤à¤•à¤¾ वरà¥à¤·à¤¾à¤ªà¥‚रà¥à¤µà¥€ अखेरचे वापरले</translation>
+<translation id="540969355065856584">हा सरà¥à¤µà¥à¤¹à¤° <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° यावेळी वैध नाही. हे कदाचित चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित करीत असलà¥â€à¤¯à¤¾à¤®à¥à¤³à¥‡ होऊ शकते.</translation>
<translation id="5421136146218899937">बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग डेटा साफ करा...</translation>
<translation id="5430298929874300616">बà¥à¤•à¤®à¤¾à¤°à¥à¤• काढा</translation>
<translation id="5431657950005405462">आपली फाईल आढळली नाही</translation>
-<translation id="5435775191620395718">या डिवà¥à¤¹à¤¾à¤‡à¤¸ वरील इतिहास दरà¥à¤¶à¤µà¤¿à¤¤ आहे. <ph name="BEGIN_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" वर सà¥à¤•à¥€à¤®à¤¾ पà¥à¤°à¤®à¤¾à¤£à¥€à¤•à¤°à¤£ तà¥à¤°à¥à¤Ÿà¥€: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">हे <ph name="HOST_NAME" /> पृषà¥à¤  शोधले जाऊ शकत नाही</translation>
<translation id="5455374756549232013">खराब धोरण टाइमसà¥à¤Ÿà¤à¤ª</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" /> पैकी <ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">अवैध</translation>
<translation id="5470861586879999274">&amp;संपादित करा पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
<translation id="54817484435770891">वैध पतà¥à¤¤à¤¾ जोडा</translation>
<translation id="5492298309214877701">कंपनी, संसà¥à¤¥à¤¾ किंवा शाळा इंटà¥à¤°à¤¾à¤¨à¥‡à¤Ÿ वरील या साइटची URL बाहà¥à¤¯ वेबसाइटसारखीच आहे.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">या पतà¥à¤¤à¥à¤¯à¤¾à¤µà¤°à¥‚न पिक अप करू शकत नाही. वेगळा पतà¥à¤¤à¤¾ निवडा.</translation>
<translation id="5572851009514199876">कृपया पà¥à¤°à¤¾à¤°à¤‚भ करा आणि Chrome मधà¥â€à¤¯à¥‡ साइन इन करा जेणेकरून आपलà¥à¤¯à¤¾à¤²à¤¾ या साइटमधà¥à¤¯à¥‡ पà¥à¤°à¤µà¥‡à¤¶ करणà¥â€à¤¯à¤¾à¤šà¥€ अनà¥à¤®à¤¤à¥€ आहे किंवा नाही ते Chrome तपासू शकेल.</translation>
<translation id="5580958916614886209">आपला कालबाहà¥à¤¯à¤¤à¤¾ महिना तपासा आणि पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा</translation>
+<translation id="5586446728396275693">कोणतेही सेवà¥à¤¹ केलेले अॅडà¥à¤°à¥‡à¤¸ नाही</translation>
+<translation id="5595485650161345191">पतà¥à¤¤à¤¾ संपादित करा</translation>
<translation id="560412284261940334">वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¨ समरà¥à¤¥à¤¿à¤¤ नाही</translation>
<translation id="5610142619324316209">कनेकà¥à¤¶à¤¨ तपासणे</translation>
<translation id="5610807607761827392">आपण कारà¥à¤¡ आणि पतà¥à¤¤à¥‡ <ph name="BEGIN_LINK" />सेटिंगà¥à¤œ<ph name="END_LINK" /> मधà¥à¤¯à¥‡ वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ करू शकता.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">आपण ही साइट सोडू इचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="5629630648637658800">धोरण सेटिंगà¥à¤œ लोड करणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€</translation>
<translation id="5631439013527180824">अवैध डिवà¥à¤¹à¤¾à¤‡à¤¸ वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¨ टोकन</translation>
+<translation id="5633066919399395251">सधà¥à¤¯à¤¾ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वर असलेले हलà¥à¤²à¥‡à¤–ोर कदाचित तà¥à¤®à¤šà¥à¤¯à¤¾ कॉंपà¥à¤¯à¥à¤Ÿà¤°à¤®à¤§à¥€à¤² तà¥à¤®à¤šà¥€ माहिती चोरू किंवा हटवू शकणारे धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® (उदाहरणारà¥à¤¥, फोटो, पासवरà¥à¤¡, संदेश आणि कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡à¥‡) इंसà¥à¤Ÿà¥‰à¤² करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतील. <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">सà¥à¤¥à¤¾à¤¨</translation>
+<translation id="5659593005791499971">ईमेल</translation>
<translation id="5669703222995421982">वैयकà¥à¤¤à¥€à¤•à¥ƒà¤¤ सामगà¥à¤°à¥€ मिळवा</translation>
<translation id="5675650730144413517">हे पृषà¥à¤  कारà¥à¤¯ करीत नाही</translation>
-<translation id="5677928146339483299">अवरोधित</translation>
-<translation id="5694783966845939798">आपण <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ à¤à¤–ादà¥à¤¯à¤¾ कमकà¥à¤µà¤¤ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ अलà¥à¤—ोरिदम (जसे की SHA-1) चा वापर करून सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€à¤•à¥ƒà¤¤ केलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले. याचा अरà¥à¤¥ असा आहे की सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ सादर केलेले सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤² बनावटी असू शकतात आणि हा सरà¥à¤µà¥à¤¹à¤° आपलà¥à¤¯à¤¾à¤²à¤¾ अपेकà¥à¤·à¤¿à¤¤ असलेला सरà¥à¤µà¥à¤¹à¤° नसू शकतो (आपण कदाचित à¤à¤–ादà¥à¤¯à¤¾ आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¸à¤¹ संपà¥à¤°à¥‡à¤·à¤£ करीत आहात). <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">या वेबसाइटची ओळख सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ केली गेली नाही.</translation>
+<translation id="5713016350996637505">फसवणारा आशय बà¥à¤²à¥‰à¤• केला</translation>
<translation id="5720705177508910913">वरà¥à¤¤à¤®à¤¾à¤¨ वापरकरà¥à¤¤à¤¾</translation>
<translation id="5732392974455271431">आपले पालक आपलà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ ती अनावरोधित करू शकतात</translation>
<translation id="5763042198335101085">वैध ईमेल पतà¥à¤¤à¤¾ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा</translation>
<translation id="5765072501007116331">वितरण पदà¥à¤§à¤¤à¥€ आणि आवशà¥à¤¯à¤•à¤¤à¤¾ पाहणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€, à¤à¤• पतà¥à¤¤à¤¾ निवडा</translation>
+<translation id="5778550464785688721">MIDI डिवà¥à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸ पूरà¥à¤£ नियंतà¥à¤°à¤£</translation>
<translation id="5784606427469807560">आपलà¥à¤¯à¤¾ कारà¥à¤¡à¤šà¥€ पà¥à¤·à¥à¤Ÿà¥€ करताना समसà¥à¤¯à¤¾ आली. आपले इंटरनेट कनेकà¥à¤¶à¤¨ तपासा आणि पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.</translation>
<translation id="5785756445106461925">पà¥à¤¢à¥‡, या पृषà¥à¤ à¤¾à¤¤ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नसलेली इतर संसाधने समाविषà¥à¤Ÿ आहेत. ही संसाधने संकà¥à¤°à¤®à¤£à¤¾à¤¤ असताना इतरांदà¥à¤µà¤¾à¤°à¥‡ पाहिली जाऊ शकतात आणि पृषà¥à¤ à¤¾à¤šà¥‡ सà¥à¤µà¤°à¥‚प बदलणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¦à¥à¤µà¤¾à¤°à¥‡ सà¥à¤§à¤¾à¤°à¤¿à¤¤ केली जाऊ शकतात.</translation>
<translation id="5786044859038896871">आपण आपली कारà¥à¤¡ माहिती भरू इचà¥à¤›à¤¿à¤¤ आहात?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;जोडा पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
<translation id="5814352347845180253">आपण <ph name="SITE" /> आणि काही अनà¥à¤¯ साइट मधील पà¥à¤°à¥€à¤®à¤¿à¤¯à¤® सामगà¥à¤°à¥€ मधील पà¥à¤°à¤µà¥‡à¤¶ कदाचित गमवाल.</translation>
<translation id="5838278095973806738">या साइटवर कोणतीही संवेदनशील माहिती (उदाहरणारà¥à¤¥, संकेतशबà¥à¤¦ किंवा कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करू नका, कारण आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ ती चोरू शकतात.</translation>
-<translation id="5843436854350372569">आपण <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ à¤à¤• कमकà¥à¤µà¤¤ की असलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले. आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ खाजगी की तोडलेली असू शकते आणि सरà¥à¤µà¥à¤¹à¤° हे आपलà¥à¤¯à¤¾à¤²à¤¾ अपेकà¥à¤·à¤¿à¤¤ असणारे सरà¥à¤µà¥à¤¹à¤° नसू शकते (आपण कदाचित आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¶à¥€ संपà¥à¤°à¥‡à¤·à¤£ करत असाल) <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">या साइटवर पोहचणे शकà¥à¤¯ नाही</translation>
<translation id="5869522115854928033">जतन केलेले संकेतशबà¥à¤¦</translation>
<translation id="5872918882028971132">पालक सूचना</translation>
<translation id="5901630391730855834">पिवळा</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (सिंक केलेले)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 वापरात आहे}one{# वापरात आहे}other{# वापरात आहेत}}</translation>
<translation id="5926846154125914413">आपण काही साइट मधील पà¥à¤°à¥€à¤®à¤¿à¤¯à¤® सामगà¥à¤°à¥€ मधील पà¥à¤°à¤µà¥‡à¤¶ कदाचित गमवाल.</translation>
<translation id="5959728338436674663">धोकादायक अॅपà¥à¤¸ आणि साइट शोधणà¥à¤¯à¤¾à¤¤ मदत करणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ काही <ph name="BEGIN_WHITEPAPER_LINK" />सिसà¥à¤Ÿà¥€à¤® माहिती आणि पृषà¥à¤  सामगà¥à¤°à¥€<ph name="END_WHITEPAPER_LINK" /> सà¥à¤µà¤¯à¤‚चलितपणे Google कडे पाठवा. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">आठवडा</translation>
<translation id="5967867314010545767">इतिहासातून काढा</translation>
<translation id="5975083100439434680">à¤à¥‚म कमी करा</translation>
<translation id="598637245381783098">पेमेंट अॅप उघडू शकत नाही</translation>
@@ -543,22 +603,30 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{पृषà¥à¤  1}one{पृषà¥à¤  #}other{पृषà¥à¤ à¥‡ #}}</translation>
<translation id="6017514345406065928">हिरवा</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />वर असलेले आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ फसवणारे अॅपà¥à¤¸ इंसà¥à¤Ÿà¥‰à¤² करू शकतात जे दà¥à¤¸à¤°à¥‡ काहीतरी असलà¥à¤¯à¤¾à¤šà¥‡ भासवू शकतात किंवा तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ शोधणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ डेटा वापरू शकतात. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (सिंक केलेले)</translation>
<translation id="6027201098523975773">नाव पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा</translation>
<translation id="6040143037577758943">बंद करा</translation>
<translation id="6042308850641462728">अधिक</translation>
+<translation id="6047233362582046994">तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ तà¥à¤®à¤šà¥à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¥‡à¤²à¤¾ असणारा धोका समजत असलà¥à¤¯à¤¾à¤¸, हानिकारक अॅपà¥à¤¸ काढले जाणà¥à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€ तà¥à¤®à¥à¤¹à¥€ <ph name="BEGIN_LINK" />या साइटला भेट देऊ शकता<ph name="END_LINK" />.</translation>
+<translation id="6051221802930200923">ही वेबसाइट पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पिनिंग वापरत असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ तà¥à¤®à¥à¤¹à¥€ आतà¥à¤¤à¤¾ <ph name="SITE" /> पाहू शकणार नाही. नेटवरà¥à¤• à¤à¤°à¤° आणि आकà¥à¤°à¤®à¤£à¥‡ शकà¥à¤¯à¤¤à¥‹ तातà¥à¤ªà¥à¤°à¤¤à¥€ असतात, तà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ हे पेज नंतर पाहता येईल.</translation>
<translation id="6060685159320643512">सावधगिरी बाळगा, या पà¥à¤°à¤¯à¥‹à¤—ांमà¥à¤³à¥‡ हानी होऊ शकते</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{काहीही नाही}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">आपण पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¨à¥‡-पà¥à¤°à¤¦à¤¾à¤¨ केलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° वापरून सामगà¥à¤°à¥€à¤®à¤§à¥à¤¯à¥‡ पà¥à¤°à¤µà¥‡à¤¶ केला. आपण <ph name="DOMAIN" /> वर पà¥à¤°à¤¦à¤¾à¤¨ करता तो डेटा आपलà¥à¤¯à¤¾ पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¦à¥à¤µà¤¾à¤°à¥‡ अंतःखंडित केला जाऊ शकतो.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{काहीही नाही}=1{1 पासवरà¥à¤¡ (सिंक केलेला)}one{# पासवरà¥à¤¡ (सिंक केलेला)}other{# पासवरà¥à¤¡ (सिंक केलेले)}}</translation>
<translation id="6146055958333702838">कोणतà¥à¤¯à¤¾à¤¹à¥€ केबल तपासा आणि कोणतेही राउटर, मोडेम किंवा आपण
वापरत असलेले
अनà¥à¤¯ नेटवरà¥à¤• डिवà¥à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸ रीबूट करा.</translation>
<translation id="614940544461990577">हे करून पहा:</translation>
<translation id="6151417162996330722">सरà¥à¤µà¥à¤¹à¤° पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¤¾à¤¸ वैधता कालावधी आहे जो खूप मोठा आहे.</translation>
<translation id="6157877588268064908">शिपिंग पदà¥à¤§à¤¤à¥€ आणि आवशà¥à¤¯à¤•à¤¤à¤¾ पाहणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€, à¤à¤• पतà¥à¤¤à¤¾ निवडा</translation>
+<translation id="6158003235852588289">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤ करणà¥à¤¯à¤¾à¤²à¤¾ अलीकडे <ph name="SITE" />वर फिशिंग आढळले. फिशिंग साइट तà¥à¤®à¥à¤¹à¤¾à¤²à¤¾ फसवणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ दà¥à¤¸à¤°à¥â€à¤¯à¤¾ वेबसाइट असलà¥à¤¯à¤¾à¤šà¥‡ दाखवतात.</translation>
<translation id="6165508094623778733">अधिक जाणून घà¥à¤¯à¤¾</translation>
+<translation id="6169916984152623906">आता आपण खाजगीरितà¥à¤¯à¤¾ बà¥à¤°à¤¾à¤‰à¤ करू शकता आणि हे डिवà¥à¤¹à¤¾à¤‡à¤¸ वापरणारे इतर लोक आपले कà¥à¤°à¤¿à¤¯à¤¾à¤•à¤²à¤¾à¤ª पाहू शकणार नाहीत. तथापि, डाउनलोड आणि बà¥à¤•à¤®à¤¾à¤°à¥à¤• सेवà¥à¤¹ केले जातील.</translation>
<translation id="6177128806592000436">या साइटवरील आपले कनेकà¥à¤¶à¤¨ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नाही</translation>
<translation id="6184817833369986695">(cohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">आपले इंटरनेट कनेकà¥à¤¶à¤¨ तपासा</translation>
<translation id="6218753634732582820">Chromium वरून पतà¥à¤¤à¤¾ काढायचा?</translation>
+<translation id="6221345481584921695">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚गला अलीकडे <ph name="SITE" /> वर <ph name="BEGIN_LINK" />मालवेअर आढळले आहे<ph name="END_LINK" />. सामानà¥à¤¯à¤¤à¤ƒ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ असलेलà¥à¤¯à¤¾ वेबसाइट काहीवेळा मालवेअरमà¥à¤³à¥‡ संकà¥à¤°à¤®à¤¿à¤¤ à¤à¤¾à¤²à¥‡à¤²à¥à¤¯à¤¾ असतात. à¤à¤• जà¥à¤žà¤¾à¤¤ मालवेअर वितरक असलेलà¥à¤¯à¤¾, <ph name="SUBRESOURCE_HOST" /> कडून दà¥à¤°à¥à¤­à¤¾à¤µà¤¨à¤¾à¤ªà¥‚रà¥à¤£ सामगà¥à¤°à¥€ येते.</translation>
<translation id="6251924700383757765">गोपनीयता धोरण</translation>
<translation id="6254436959401408446">हे पृषà¥â€à¤  उघडणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ पà¥à¤°à¥‡à¤¶à¥€ मेमरी नाही</translation>
<translation id="625755898061068298">आपण या साइटसाठी सà¥à¤°à¤•à¥à¤·à¤¾ चेतावणी अकà¥à¤·à¤® करणे निवडले आहे.</translation>
@@ -584,15 +652,14 @@
<translation id="6404511346730675251">बà¥à¤•à¤®à¤¾à¤°à¥à¤• संपादित करा</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> साठी कालबाहà¥à¤¯à¤¤à¤¾ तारीख आणि CVC पà¥à¤°à¤µà¤¿à¤·à¥â€à¤Ÿ करा</translation>
<translation id="6414888972213066896">या साइटला भेट देणे ठीक आहे का ते आपण आपलà¥â€à¤¯à¤¾ पालकास विचारले</translation>
-<translation id="6416403317709441254">Chromium पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ करू शकत नसलेले न समजणारे कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤² वेबसाइटने पाठविलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ आपण आतà¥à¤¤à¤¾ <ph name="SITE" /> ला भेट देऊ शकत नाही. नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€ आणि आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ सामानà¥à¤¯à¤¤à¤ƒ तातà¥à¤ªà¥à¤°à¤¤à¥‡ असतात, यामà¥à¤³à¥‡ हे पृषà¥à¤  कदाचित नंतर कारà¥à¤¯ करेल. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° मागे घेतले की नाही हे तपासणà¥à¤¯à¤¾à¤¤ अकà¥à¤·à¤®.</translation>
<translation id="6433490469411711332">संपरà¥à¤• माहिती संपादित करा</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> नी कनेकà¥à¤Ÿ करणà¥à¤¯à¤¾à¤¸ नकार दिला.</translation>
<translation id="6446608382365791566">अधिक माहिती जोडा</translation>
+<translation id="6447842834002726250">कà¥à¤•à¥€à¤œ</translation>
<translation id="6451458296329894277">फॉरà¥à¤® रीसबमिशनची पà¥à¤·à¥à¤Ÿà¥€ करा</translation>
<translation id="6456339708790392414">आपले देयक</translation>
<translation id="6458467102616083041">धोरणानà¥à¤¸à¤¾à¤° डीफॉलà¥à¤Ÿ शोध अकà¥à¤·à¤® केलà¥à¤¯à¤¾à¤¨à¥‡ दà¥à¤°à¥à¤²à¤•à¥à¤· करणà¥â€à¤¯à¤¾à¤¤ आले.</translation>
-<translation id="6462969404041126431">हा सरà¥à¤µà¥à¤¹à¤° <ph name="DOMAIN" /> हे असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचे सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ केले असावे. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">डिवà¥à¤¹à¤¾à¤‡à¤¸ धोरणे</translation>
<translation id="6477321094435799029">Chrome ला या पृषà¥â€à¤ à¤¾à¤µà¤° असमानà¥à¤¯ कोड सापडला आहे आणि आपली वैयकà¥à¤¤à¤¿à¤• माहिती (उदा, संकेतशबà¥à¤¦, फोन नंबर आणि कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) संरकà¥à¤·à¤¿à¤¤ करणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ अवरोधित केला आहे.</translation>
<translation id="6489534406876378309">कà¥à¤°à¥…श अपलोड करणे पà¥à¤°à¤¾à¤°à¤‚भ करा</translation>
@@ -604,20 +671,19 @@
<translation id="6556915248009097796">कालबाहà¥à¤¯à¤¤à¤¾: <ph name="EXPIRATION_DATE_ABBR" />, अखेरचे वापरले: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">आपलà¥à¤¯à¤¾ वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤•à¤¾à¤¨à¥‡ अदà¥à¤¯à¤¾à¤ª ती मंजूर केली नाही</translation>
<translation id="6569060085658103619">आपण à¤à¤• विसà¥à¤¤à¤¾à¤° पृषà¥à¤  पाहत आहात</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> पेकà¥à¤·à¤¾ कमी</translation>
+<translation id="657639383826808334">हा आशय तà¥à¤®à¤šà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤µà¤° धोकादायक सॉफà¥à¤Ÿà¤µà¥‡à¤…र इंसà¥à¤Ÿà¥‰à¤² करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करेल जे तà¥à¤®à¤šà¥€ माहिती चोरेल किंवा मिटवेल. <ph name="BEGIN_LINK" />तरीही दाखवा<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">कूटबदà¥à¤§à¤¤à¤¾ परà¥à¤¯à¤¾à¤¯</translation>
<translation id="662080504995468778">यावर रहा</translation>
<translation id="6626291197371920147">वैध कारà¥à¤¡ नंबर जोडा</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> शोध</translation>
+<translation id="6630809736994426279">सधà¥à¤¯à¤¾ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वर असलेले हलà¥à¤²à¥‡à¤–ोर कदाचित तà¥à¤®à¤šà¥à¤¯à¤¾ मॅकमधील तà¥à¤®à¤šà¥€ माहिती चोरू किंवा हटवू शकणारे धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® (उदाहरणारà¥à¤¥, फोटो, पासवरà¥à¤¡, संदेश आणि कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡à¥‡) इंसà¥à¤Ÿà¥‰à¤² करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतील. <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">हे धोरण नापसंत आहे.</translation>
-<translation id="6652240803263749613">हा सरà¥à¤µà¥à¤¹à¤° <ph name="DOMAIN" /> हे असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचे सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपलà¥à¤¯à¤¾ संगणकाचà¥à¤¯à¤¾ ऑपरेटिंग पà¥à¤°à¤£à¤¾à¤²à¥€à¤¦à¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही; हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Chromium वरून फॉरà¥à¤® सूचना काढायचà¥à¤¯à¤¾?</translation>
<translation id="6685834062052613830">साइन आउट करा आणि सेटअप पूरà¥à¤£ करा</translation>
<translation id="6710213216561001401">मागील</translation>
<translation id="6710594484020273272">&lt;शोध संजà¥à¤žà¤¾ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा&gt;</translation>
<translation id="6711464428925977395">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤°à¤®à¤§à¥à¤¯à¥‡ काहीतरी चà¥à¤•à¥€à¤šà¥‡ आहे किंवा पतà¥à¤¤à¤¾ चà¥à¤•à¥€à¤šà¤¾ आहे.</translation>
<translation id="6727102863431372879">सेट करा</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{काहीही नाही}=1{1 आयटम}one{# आयटम}other{# आयटम}}</translation>
<translation id="674375294223700098">अजà¥à¤žà¤¾à¤¤ सरà¥à¤µà¥à¤¹à¤° पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° तà¥à¤°à¥à¤Ÿà¥€.</translation>
<translation id="6753269504797312559">धोरण मूलà¥à¤¯</translation>
<translation id="6757797048963528358">आपले डिवà¥à¤¹à¤¾à¤‡à¤¸ निषà¥à¤•à¥à¤°à¥€à¤¯ à¤à¤¾à¤²à¥‡.</translation>
@@ -625,6 +691,8 @@
<translation id="6810899417690483278">सानà¥à¤•à¥‚लीकरण आयडी</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">पà¥à¤°à¤¦à¥‡à¤¶ डेटा लोड करणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€</translation>
+<translation id="6825578344716086703">तà¥à¤®à¥à¤¹à¥€ <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ à¤à¤•à¤¾ कमकà¥à¤µà¤¤ सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€ अलà¥à¤—ोरिदमचा (जसे SHA-1) वापर करून सà¥à¤µà¤¾à¤•à¥à¤·à¤°à¥€à¤•à¥ƒà¤¤ केलेले पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले. याचा अरà¥à¤¥ असा आहे की सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ सादर केलेली सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤² बनावट असू शकतात आणि हा सरà¥à¤µà¥à¤¹à¤° तà¥à¤®à¥à¤¹à¥€ अपेकà¥à¤·à¤¾ करीत असलेला नसेल. (तà¥à¤®à¥à¤¹à¥€ कदाचित à¤à¤–ादà¥à¤¯à¤¾ हलà¥à¤²à¥‡à¤–ोराशी संभाषण करत आहात).</translation>
+<translation id="6830728435402077660">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नाही</translation>
<translation id="6831043979455480757">भाषांतर करा</translation>
<translation id="6839929833149231406">कà¥à¤·à¥‡à¤¤à¥à¤°</translation>
<translation id="6874604403660855544">&amp;जोडा पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
@@ -632,6 +700,7 @@
<translation id="6895330447102777224">आपलà¥à¤¯à¤¾ कारà¥à¤¡à¤šà¥€ पà¥à¤·à¥à¤Ÿà¥€ केली</translation>
<translation id="6897140037006041989">वापरकरà¥à¤¤à¤¾ à¤à¤œà¤‚ट</translation>
<translation id="6915804003454593391">वापरकरà¥à¤¤à¤¾:</translation>
+<translation id="6945221475159498467">निवडा</translation>
<translation id="6948701128805548767">पिकअप पदà¥à¤§à¤¤à¥€ आणि आवशà¥à¤¯à¤•à¤¤à¤¾ पाहणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€, à¤à¤• पतà¥à¤¤à¤¾ निवडा</translation>
<translation id="6957887021205513506">सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° खोटे असलà¥à¤¯à¤¾à¤šà¥‡ दिसून येते.</translation>
<translation id="6965382102122355670">ठीक आहे</translation>
@@ -640,15 +709,16 @@
<translation id="6973656660372572881">निशà¥à¤šà¤¿à¤¤ पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ सरà¥à¤µà¥à¤¹à¤° आणि .pac सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ URL निरà¥à¤¦à¤¿à¤·à¥â€à¤Ÿ करणà¥â€à¤¯à¤¾à¤¤ आले आहेत.</translation>
<translation id="6989763994942163495">पà¥à¤°à¤—त सेटिंगà¥à¤œ दरà¥à¤¶à¤µà¤¾...</translation>
<translation id="7000990526846637657">कोणतà¥à¤¯à¤¾à¤¹à¥€ इतिहास पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿà¥€ सापडलà¥à¤¯à¤¾ नाहीत</translation>
-<translation id="7009986207543992532">आपण <ph name="DOMAIN" /> येथे पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ असे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले जà¥à¤¯à¤¾à¤šà¤¾ वैधता कालावधी विशà¥à¤µà¤¾à¤¸à¤¾à¤°à¥à¤¹à¤¤à¥‡à¤¸à¤¾à¤ à¥€ खूप मोठा आहे. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">आपलà¥à¤¯à¤¾ Google खातà¥à¤¯à¤¾à¤¤ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> वर बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग इतिहासाची अनà¥à¤¯ सà¥à¤µà¤°à¥‚पे असू शकतात</translation>
<translation id="7029809446516969842">संकेतशबà¥à¤¦</translation>
+<translation id="7050187094878475250">आपण <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ à¤à¤• पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले आहे जà¥à¤¯à¤¾à¤šà¤¾ वैधता कालावधी हा विशà¥à¤µà¤¾à¤¸à¤¾à¤°à¥à¤¹à¤¤à¥‡à¤¸à¤¾à¤ à¥€ खूप मोठा आहे.</translation>
+<translation id="7053983685419859001">अवरोधित करा</translation>
<translation id="7064851114919012435">संपरà¥à¤• माहिती</translation>
<translation id="7079718277001814089">या साइटमधà¥à¤¯à¥‡ मालवेयर आहे</translation>
<translation id="7087282848513945231">परगणा</translation>
-<translation id="7088615885725309056">थोडा जà¥à¤¨à¤¾</translation>
<translation id="7090678807593890770">Google वर <ph name="LINK" /> शोधा</translation>
+<translation id="7108819624672055576">à¤à¤•à¤¾ विसà¥à¤¤à¤¾à¤°à¤¾à¤¨à¥‡ परवानगी दिलेले</translation>
<translation id="7119414471315195487">अनà¥à¤¯ टॅब आणि पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® बंद करा</translation>
<translation id="7129409597930077180">या पतà¥à¤¤à¥à¤¯à¤¾à¤µà¤° पाठवू शकत नाही. वेगळा पतà¥à¤¤à¤¾ निवडा.</translation>
<translation id="7138472120740807366">वितरण पदà¥à¤§à¤¤</translation>
@@ -666,22 +736,18 @@
<translation id="7220786058474068424">पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ करत आहे</translation>
<translation id="724691107663265825">साइटमधà¥à¤¯à¥‡ पà¥à¤¢à¥‡ मालवेअर आहे</translation>
<translation id="724975217298816891">आपले कारà¥à¤¡ तपशील अदà¥à¤¯à¤¤à¤¨à¤¿à¤¤ करणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ <ph name="CREDIT_CARD" /> करिता कालबाहà¥à¤¯à¤¤à¤¾ तारीख आणि CVC पà¥à¤°à¤µà¤¿à¤·à¥â€à¤Ÿ करा. आपण पà¥à¤·à¥à¤Ÿà¥€ केलà¥à¤¯à¤¾à¤µà¤°, आपले कारà¥à¤¡ तपशील या साइटसह सामायिक केले जातील.</translation>
-<translation id="725866823122871198">आपलà¥à¤¯à¤¾ संगणकाची तारीख आणि वेळ (<ph name="DATE_AND_TIME" />) चà¥à¤•à¥€à¤šà¥€ असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> सह खाजगी कनेकà¥à¤¶à¤¨ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ केले जाऊ शकत नाही.</translation>
+<translation id="7260504762447901703">पà¥à¤°à¤µà¥‡à¤¶ रदà¥à¤¦ करा</translation>
<translation id="7275334191706090484">वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ केलेले बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
<translation id="7298195798382681320">शिफारस केलेले</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> वाजता कà¥à¤°à¥…श अहवाल कॅपà¥à¤šà¤° केला (वापरकरà¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ विनंती केलेले अपलोड, अदà¥à¤¯à¤¾à¤ª अपलोड केलेले नाही)</translation>
<translation id="7334320624316649418">&amp;पà¥à¤¨à¤°à¥à¤•à¥à¤°à¤®à¤¿à¤¤ करा पà¥à¤¨à¥à¤¹à¤¾ करा</translation>
<translation id="733923710415886693">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पारदरà¥à¤¶à¤•à¤¤à¥‡à¤¦à¥à¤µà¤¾à¤°à¥‡ सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° उघड केले नाही.</translation>
-<translation id="7351800657706554155">हे पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ केले गेलà¥à¤¯à¤¾à¤¨à¥‡ आपण आतà¥à¤¤à¤¾ <ph name="SITE" /> ला भेट देऊ शकत नाही. नेटवरà¥à¤• तà¥à¤°à¥à¤Ÿà¥€ आणि आकà¥à¤°à¤®à¤£à¥‡ सामानà¥à¤¯à¤¤à¤ƒ तातà¥à¤ªà¥à¤°à¤¤à¥€ असतात, तà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ हे पृषà¥à¤  कदाचित नंतर कारà¥à¤¯ करेल. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">कमांड लाइन</translation>
<translation id="7372973238305370288">शोध परिणाम</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">नाही</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">कारà¥à¤¡à¤šà¥€ पà¥à¤·à¥à¤Ÿà¥€ करा</translation>
-<translation id="7394102162464064926">आपलà¥à¤¯à¤¾à¤²à¤¾ खातà¥à¤°à¥€ आहे की आपण आपलà¥à¤¯à¤¾ इतिहासामधून ही पृषà¥à¤ à¥‡ हटवू इचà¥à¤›à¤¿à¤¤à¤¾?
-
-हं! गà¥à¤ªà¥à¤¤ मोड <ph name="SHORTCUT_KEY" /> पà¥à¤¢à¥€à¤² वेळी आटोपशीर होऊ शकतो.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">पà¥à¤°à¥‹à¤«à¤¾à¤‡à¤² पथ</translation>
<translation id="7424977062513257142">या वेबपृषà¥à¤ à¤¾à¤µà¤°à¥€à¤² à¤à¤®à¥à¤¬à¥‡à¤¡ केलेले पृषà¥à¤  मà¥à¤¹à¤£à¤¤à¥‡:</translation>
@@ -689,6 +755,7 @@
<translation id="7444046173054089907">ही साइट अवरोधित केली आहे</translation>
<translation id="7445762425076701745">आपण कनेकà¥à¤Ÿ केलेलà¥à¤¯à¤¾ सरà¥à¤µà¥à¤¹à¤°à¤šà¥€ ओळख पूरà¥à¤£à¤ªà¤£à¥‡ सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ करणे शकà¥à¤¯ नाही. आपण सरà¥à¤µà¥à¤¹à¤°à¤¶à¥€ फकà¥à¤¤ आपलà¥â€à¤¯à¤¾ डोमेनमधà¥à¤¯à¥‡ वैध असलेले नाव वापरून कनेकà¥à¤Ÿ केलेले आहे, जà¥à¤¯à¤¾à¤šà¥€ मालकी सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ बाहà¥à¤¯ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° अधिकृततेला परवानगी नाही. काही पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° अधिकारी तरीही या नावांसाठी पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° जारी करतील, हे सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करणà¥à¤¯à¤¾à¤šà¤¾ काहीही मारà¥à¤— नाही की आपण इचà¥à¤›à¤¿à¤¤ वेबसाइटशी कनेकà¥à¤Ÿ केले आहे आणि आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¶à¥€ नाही.</translation>
<translation id="7451311239929941790">या समसà¥à¤¯à¥‡à¤µà¤¿à¤·à¤¯à¥€ <ph name="BEGIN_LINK" />अधिक जाणून घेणे<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">सारà¥à¤µà¤¤à¥à¤°à¤¿à¤• डीफॉलà¥â€à¤Ÿ वापरा (अवरोधित करा)</translation>
<translation id="7460163899615895653">अनà¥à¤¯ डिवà¥à¤¹à¤¾à¤‡à¤¸ वरील आपले अलीकडील टॅब येथे दिसतात</translation>
<translation id="7469372306589899959">कारà¥à¤¡à¤šà¥€ पà¥à¤·à¥à¤Ÿà¥€ करीत आहे</translation>
<translation id="7481312909269577407">पà¥à¤¢à¥€à¤²</translation>
@@ -696,36 +763,43 @@
<translation id="7508255263130623398">परत केलेला धोरण डिवà¥à¤¹à¤¾à¤‡à¤¸ आयडी रिकà¥à¤¤ आहे किंवा वरà¥à¤¤à¤®à¤¾à¤¨ डिवà¥à¤¹à¤¾à¤‡à¤¸ आयडी शी जà¥à¤³à¤¤ नाही</translation>
<translation id="7514365320538308">डाउनलोड करा</translation>
<translation id="7518003948725431193">या वेबपतà¥à¤¤à¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ वेबपृषà¥à¤  आढळले नाही: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">मूलà¥à¤¯</translation>
<translation id="7537536606612762813">अनिवारà¥à¤¯</translation>
+<translation id="7542403920425041731">तà¥à¤®à¥à¤¹à¥€ निशà¥à¤šà¤¿à¤¤ केलà¥à¤¯à¤¾à¤µà¤°, तà¥à¤®à¤šà¥‡ कारà¥à¤¡ तपशील या साइटसह शेअर केले जातील.</translation>
<translation id="7542995811387359312">सà¥à¤µà¤¯à¤‚चलित कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡ भरणे अकà¥à¤·à¤® à¤à¤¾à¤²à¥‡ आहे कारण हा फॉरà¥à¤® सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥à¤¶à¤¨ वापरत नाही.</translation>
<translation id="7543525346216957623">आपलà¥à¤¯à¤¾ पालकास विचारा</translation>
<translation id="7549584377607005141">हे वेबपृषà¥à¤  योगà¥à¤¯à¤°à¤¿à¤¤à¥€à¤¨à¥‡ पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ केले जाणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आपण पूरà¥à¤µà¥€ पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ केलेला डेटा आवशà¥à¤¯à¤• आहे. आपण हा डेटा पà¥à¤¨à¥à¤¹à¤¾ पाठवू शकता, परंतॠअसे केलà¥à¤¯à¤¾à¤¨à¥‡ या पृषà¥à¤ à¤¾à¤¨à¥‡ मागे केलेली कोणतà¥à¤¯à¤¾à¤¹à¥€ कà¥à¤°à¤¿à¤¯à¥‡à¤šà¥€ पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¥à¤¤à¥€ आपण कराल.</translation>
<translation id="7552846755917812628">खालील टिपा वापरून पहा:</translation>
<translation id="7554791636758816595">नवीन टॅब</translation>
+<translation id="7567204685887185387">हा सरà¥à¤µà¥à¤¹à¤° हे <ph name="DOMAIN" /> असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; तà¥à¤¯à¤¾à¤šà¥‡ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° कदाचित लबाडीने जारी केले असावे. हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">हे पृषà¥à¤ <ph name="ORIGINAL_LANGUAGE" />मधà¥à¤¯à¥‡ आहे आपण याचा भाषांतर करॠइचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="7569952961197462199">Chrome मधून कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡ काढायचे?</translation>
<translation id="7569983096843329377">काळा</translation>
<translation id="7578104083680115302">आपण Google सह जतन केलेलà¥à¤¯à¤¾ कारà¥à¤¡à¤šà¤¾ वापर करून डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¥‡à¤¸à¤µà¤°à¥‚न दà¥à¤°à¥à¤¤à¤ªà¤£à¥‡ साइट आणि अॅपà¥à¤¸à¤µà¤° देय दà¥à¤¯à¤¾.</translation>
<translation id="7588950540487816470">भौतिक वेब</translation>
<translation id="7592362899630581445">सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° नाव मरà¥à¤¯à¤¾à¤¦à¤¾à¤‚चे उलà¥à¤²à¤‚घन करते.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> पेकà¥à¤·à¤¾ कमी</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> सधà¥à¤¯à¤¾ ही विनंती हाताळणà¥à¤¯à¤¾à¤¤ अकà¥à¤·à¤® आहे.</translation>
<translation id="7600965453749440009">कधीही <ph name="LANGUAGE" /> चा भाषांतर करॠनका</translation>
<translation id="7610193165460212391">मूलà¥à¤¯ <ph name="VALUE" /> शà¥à¤°à¥‡à¤£à¥€à¤šà¥à¤¯à¤¾ बाहेर आहे.</translation>
<translation id="7613889955535752492">कालबाहà¥à¤¯: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">आपलà¥à¤¯à¤¾à¤•à¤¡à¥‡ आधीपासूनच डेटा आहे जो आपलà¥à¤¯à¤¾ Google खाते संकेतशबà¥à¤¦à¤¾à¤šà¥€ विभिनà¥à¤¨ आवृतà¥à¤¤à¥€ वापरà¥à¤¨ कूटबदà¥à¤§ करणà¥â€à¤¯à¤¾à¤¤ आला आहे. कृपया तो खाली पà¥à¤°à¤µà¤¿à¤·à¥â€à¤Ÿ करा.</translation>
-<translation id="7634554953375732414">या साइटवर आपले कनेकà¥à¤¶à¤¨ खाजगी नाही.</translation>
<translation id="7637571805876720304">Chromium वरून कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡ काढायचे?</translation>
<translation id="765676359832457558">पà¥à¤°à¤—त सेटिंगà¥à¤œ लपवा...</translation>
<translation id="7658239707568436148">रदà¥à¤¦ करा</translation>
+<translation id="7662298039739062396">सेटिंग à¤à¤•à¤¾ विसà¥à¤¤à¤¾à¤°à¤¾à¤¦à¥à¤µà¤¾à¤°à¥‡ नियंतà¥à¤°à¤¿à¤¤ केली आहेत</translation>
<translation id="7667346355482952095">परत केलेले धोरण टोकन रिकà¥à¤¤ आहे किंवा वरà¥à¤¤à¤®à¤¾à¤¨ टोकनशी जà¥à¤³à¤¤ नाही</translation>
<translation id="7668654391829183341">अजà¥à¤žà¤¾à¤¤ डिवà¥à¤¹à¤¾à¤‡à¤¸</translation>
<translation id="7669271284792375604">या साइट वरील आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ कदाचित आपलà¥à¤¯à¤¾ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग अनà¥à¤­à¤µà¤¾à¤¸ हानी पोहोचविणारे पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® (उदाहरणारà¥à¤¥, आपले मà¥à¤–à¥à¤¯à¤ªà¥ƒà¤·à¥à¤  बदलून किंवा आपण भेट देता तà¥à¤¯à¤¾ साइटवर अतिरिकà¥à¤¤ जाहिराती दरà¥à¤¶à¤µà¥‚न) सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करून आपली फसवणूक करणà¥â€à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतात.</translation>
<translation id="7674629440242451245">छान नवीन Chrome वैशिषà¥à¤Ÿà¥à¤¯à¤¾à¤‚मधà¥à¤¯à¥‡ सà¥à¤µà¤¾à¤°à¤¸à¥à¤¯ आहे? chrome.com/dev येथे आमचे dev चॅनेल वापरून पहा.</translation>
<translation id="7682287625158474539">शिपिंग</translation>
+<translation id="7701040980221191251">काहीही नाही</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /> <ph name="SITE" /> (असà¥à¤°à¤•à¥à¤·à¤¿à¤¤) वर सà¥à¤°à¥ ठेवा<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°</translation>
+<translation id="7716147886133743102">तà¥à¤®à¤šà¥à¤¯à¤¾ पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¨à¥‡ बà¥à¤²à¥‰à¤• केलेले</translation>
<translation id="7716424297397655342">ही साइट कॅश मधून लोड करणे शकà¥à¤¯ नाही</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ न केलेले</translation>
<translation id="7755287808199759310">आपले पालक आपलà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ ती अनावरोधित करू शकतात</translation>
<translation id="7758069387465995638">फायरवॉल किंवा अà¤à¤Ÿà¥€à¤µà¥à¤¹à¤¾à¤¯à¤°à¤¸ सॉफà¥à¤Ÿà¤µà¥‡à¤…रने कदाचित कनेकà¥à¤¶à¤¨ अवरोधित केले असावे.</translation>
@@ -752,15 +826,15 @@
<translation id="7951415247503192394">(32-बिट)</translation>
<translation id="7956713633345437162">Mobile बà¥à¤•à¤®à¤¾à¤°à¥à¤•</translation>
<translation id="7961015016161918242">कधीही नाही</translation>
-<translation id="7962083544045318153">कà¥à¤°à¥…श आयडी <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893"> नेहमी <ph name="ORIGINAL_LANGUAGE" /> मधून <ph name="TARGET_LANGUAGE" /> मधà¥à¤¯à¥‡ भाषांतर करा</translation>
<translation id="7995512525968007366">निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ केलेले नाही</translation>
<translation id="800218591365569300">मेमरी मोकळी करणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ अनà¥à¤¯ टॅब किंवा पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® बंद करून पहा.</translation>
<translation id="8012647001091218357">आमà¥à¤¹à¥€ याकà¥à¤·à¤£à¥€ आपलà¥à¤¯à¤¾ पालकांपरà¥à¤¯à¤‚त पोहोचू शकलो नाही. कृपया पà¥à¤¨à¥à¤¹à¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करा.</translation>
<translation id="8025119109950072390">या साइट वरील आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ सॉफà¥â€à¤Ÿà¤µà¥‡à¤…र सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणे किंवा आपली वैयकà¥à¤¤à¤¿à¤• माहिती (उदाहरणारà¥à¤¥, संकेतशबà¥à¤¦, फोन नंबर किंवा कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) उघड करणे यासारखे काहीतरी धोकादायक करणà¥â€à¤¯à¤¾à¤®à¤§à¥â€à¤¯à¥‡ आपलà¥â€à¤¯à¤¾à¤²à¤¾ यà¥à¤•à¥à¤¤à¥€à¤¨à¥‡ गà¥à¤‚तवू शकतात.</translation>
-<translation id="803030522067524905">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग ला अलीकडे <ph name="SITE" /> वर फिशिंग आढळले. आपली फसवणूक करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ अनà¥à¤¯ वेबसाइट असलà¥à¤¯à¤¾à¤šà¥€ बतावणी फिशिंग साइट करतात. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">हे पृषà¥â€à¤  <ph name="SOURCE_LANGUAGE" /> मधà¥à¤¯à¥‡ आहे. तà¥à¤¯à¤¾à¤¸ <ph name="TARGET_LANGUAGE" /> मधà¥à¤¯à¥‡ भाषांतरीत करायचे?</translation>
+<translation id="8037357227543935929">विचारा (डीफॉलà¥à¤Ÿ)</translation>
<translation id="8041089156583427627">अभिपà¥à¤°à¤¾à¤¯ पाठवा</translation>
+<translation id="8041940743680923270">सारà¥à¤µà¤¤à¥à¤°à¤¿à¤• डीफॉलà¥â€à¤Ÿ वापरा (विचारा)</translation>
<translation id="8088680233425245692">लेख पाहणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€.</translation>
<translation id="8089520772729574115">1 MB पेकà¥à¤·à¤¾ कमी</translation>
<translation id="8091372947890762290">सकà¥à¤°à¤¿à¤¯à¤•à¤°à¤£ सरà¥à¤µà¥à¤¹à¤°à¤µà¤° पà¥à¤°à¤²à¤‚बित आहे</translation>
@@ -769,13 +843,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" />चे सरà¥à¤µà¥à¤¹à¤° <ph name="BEGIN_ABBR" />DNS पतà¥à¤¤à¤¾<ph name="END_ABBR" /> शोधणे शकà¥à¤¯ à¤à¤¾à¤²à¥‡ नाही.</translation>
<translation id="8149426793427495338">आपला संगणक निषà¥à¤•à¥à¤°à¥€à¤¯ à¤à¤¾à¤²à¤¾.</translation>
<translation id="8150722005171944719"><ph name="URL" /> येथील फाइल वाचनीय नाही. ती काढून टाकलेली, हलविलेली असू शकते किंवा फाइल परवानगà¥à¤¯à¤¾ पà¥à¤°à¤µà¥‡à¤¶ पà¥à¤°à¤¤à¤¿à¤¬à¤‚धित करत असू शकतात.</translation>
+<translation id="8184538546369750125">सारà¥à¤µà¤¤à¥à¤°à¤¿à¤• डीफॉलà¥â€à¤Ÿ वापरा (अनà¥à¤®à¤¤à¥€ दà¥à¤¯à¤¾)</translation>
+<translation id="8191494405820426728">सà¥à¤¥à¤¾à¤¨à¤¿à¤• कà¥à¤°à¥…श आयडी <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;हलवा पूरà¥à¤µà¤µà¤¤ करा</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" आयडी असलेलà¥à¤¯à¤¾ विसà¥à¤¤à¤¾à¤°à¤¾à¤¸à¤¾à¤ à¥€ अवैध अदà¥à¤¯à¤¤à¤¨ URL.</translation>
<translation id="8202097416529803614">ऑरà¥à¤¡à¤° सारांश</translation>
<translation id="8218327578424803826">नियà¥à¤•à¥à¤¤ केलेले सà¥à¤¥à¤¾à¤¨:</translation>
<translation id="8225771182978767009">जà¥à¤¯à¤¾ वà¥à¤¯à¤•à¥à¤¤à¥€à¤¨à¥‡ हा संगणक सेट केला तà¥à¤¯à¤¾ वà¥à¤¯à¤•à¥à¤¤à¥€à¤¨à¥‡ ही साइट अवरोधित करणà¥à¤¯à¤¾à¤šà¥‡ निवडले आहे.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वरील आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ सधà¥à¤¯à¤¾ कदाचित आपलà¥à¤¯à¤¾ संगणकावर आपली माहिती (उदाहरणारà¥à¤¥, फोटो, संकेतशबà¥à¤¦, संदेश आणि कà¥à¤°à¥‡à¤¡à¤¿à¤Ÿ कारà¥à¤¡) चोरणारे किंवा हटविणारे धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करत असू शकतात.</translation>
<translation id="8241707690549784388">आपण जे पृषà¥à¤  शोधत आहत ते आपण पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ केलेली माहिती वापरत आहे. तà¥à¤¯à¤¾ पृषà¥à¤ à¤¾à¤•à¤¡à¥‡ परत गेलà¥à¤¯à¤¾à¤¸ कदाचित आपण केलेलà¥à¤¯à¤¾ कोणतà¥à¤¯à¤¾à¤¹à¥€ कà¥à¤°à¤¿à¤¯à¥‡à¤šà¥€ पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¥à¤¤à¥€ होईल. आपण सà¥à¤°à¥‚ ठेवू इचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="8249320324621329438">अंतिम पà¥à¤°à¤¾à¤ªà¥à¤¤ केलेले:</translation>
<translation id="8253091569723639551">बिलिंग पतà¥à¤¤à¤¾ आवशà¥à¤¯à¤• आहे</translation>
@@ -783,6 +858,7 @@
<translation id="8289355894181816810">याचा निशà¥à¤šà¤¿à¤¤ अरà¥à¤¥ आपलà¥à¤¯à¤¾à¤²à¤¾ माहिती नसलà¥à¤¯à¤¾à¤¸ आपलà¥à¤¯à¤¾ नेटवरà¥à¤• पà¥à¤°à¤¶à¤¾à¤¸à¤•à¤¾à¤¶à¥€ संपरà¥à¤• साधा.</translation>
<translation id="8293206222192510085">बà¥à¤•à¤®à¤¾à¤°à¥à¤• जोडा</translation>
<translation id="8294431847097064396">सà¥à¤°à¥‹à¤¤</translation>
+<translation id="8306404619377842860">तà¥à¤®à¤šà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¥€ तारीख आणि वेळ (<ph name="DATE_AND_TIME" />)चà¥à¤•à¥€à¤šà¥€ असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> साठी खाजगी कनेकà¥à¤¶à¤¨ तयार करू शकत नाही. <ph name="BEGIN_LEARN_MORE_LINK" />आणखी जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">नेटवरà¥à¤• कनेकà¥à¤¶à¤¨à¤¸à¤¹ समसà¥à¤¯à¤¾ असलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ भाषांतर अयशसà¥à¤µà¥€ à¤à¤¾à¤²à¤¾.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> मधील पà¥à¤°à¤µà¥‡à¤¶ नाकारला</translation>
<translation id="834457929814110454">आपलà¥à¤¯à¤¾à¤²à¤¾ आपलà¥à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¥‡à¤šà¥à¤¯à¤¾ जोखमी समजत असलà¥à¤¯à¤¾à¤¸, धोकादायक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® काढले जाणà¥à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€ आपण <ph name="BEGIN_LINK" />या असà¥à¤°à¤•à¥à¤·à¤¿à¤¤ साइटला भेट देऊ शकता<ph name="END_LINK" />.</translation>
@@ -803,11 +879,9 @@
<translation id="8483780878231876732">आपलà¥à¤¯à¤¾ Google खातà¥à¤¯à¤¾à¤µà¤°à¥‚न कारà¥à¤¡ वापरणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ Chrome मधà¥à¤¯à¥‡ साइन इन करा</translation>
<translation id="8488350697529856933">यावर लागू होते</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> नी पà¥à¤°à¤¤à¤¿à¤¸à¤¾à¤¦ देणà¥à¤¯à¤¾à¤¤ बराच वेळ घेतला.</translation>
-<translation id="852346902619691059">हा सरà¥à¤µà¥à¤¹à¤° <ph name="DOMAIN" /> हे असलà¥à¤¯à¤¾à¤šà¥‡ सिदà¥à¤§ करू शकला नाही; याचे सà¥à¤°à¤•à¥à¤·à¤¾ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° आपलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¥à¤¯à¤¾ ऑपरेटिंग पà¥à¤°à¤£à¤¾à¤²à¥€à¤¦à¥à¤µà¤¾à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ नाही; हे कदाचित à¤à¤•à¤¾ चà¥à¤•à¥€à¤šà¥à¤¯à¤¾ कॉनà¥à¤«à¤¿à¤—रेशनमà¥à¤³à¥‡ किंवा आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¨à¥‡ आपले कनेकà¥à¤¶à¤¨ आंतरखंडित केलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ à¤à¤¾à¤²à¥‡ असू शकते. <ph name="BEGIN_LEARN_MORE_LINK" />अधिक जाणून घà¥à¤¯à¤¾<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">कालबाहà¥à¤¯ होणà¥à¤¯à¤¾à¤šà¥‡ वरà¥à¤·</translation>
<translation id="8543181531796978784">आपण <ph name="BEGIN_ERROR_LINK" />ओळखणà¥â€à¤¯à¤¾à¤šà¥à¤¯à¤¾ समसà¥â€à¤¯à¥‡à¤šà¤¾ अहवाल<ph name="END_ERROR_LINK" /> देऊ शकता किंवा आपलà¥â€à¤¯à¤¾ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¥‡à¤¸ असणारà¥â€à¤¯à¤¾ जोखीम आपण समजत असलà¥â€à¤¯à¤¾à¤¸, <ph name="BEGIN_LINK" />या असà¥à¤°à¤•à¥à¤·à¤¿à¤¤ साइटला भेट दà¥à¤¯à¤¾<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">भाषांतर करणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€ कारण पृषà¥à¤ à¤¾à¤šà¥€ भाषा निरà¥à¤§à¤¾à¤°à¤¿à¤¤ करणे शकà¥à¤¯ नाही.</translation>
-<translation id="8559762987265718583">आपलà¥à¤¯à¤¾ डिवà¥à¤¹à¤¾à¤‡à¤¸à¤šà¥€ तारीख आणि वेळ (<ph name="DATE_AND_TIME" />) चà¥à¤•à¥€à¤šà¥€ असलà¥à¤¯à¤¾à¤¨à¥‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> सह खाजगी कनेकà¥à¤¶à¤¨ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ केले जाऊ शकले नाही.</translation>
<translation id="8571890674111243710"><ph name="LANGUAGE" /> मधà¥à¤¯à¥‡ पृषà¥à¤  अनà¥à¤µà¤¾à¤¦à¤¿à¤¤ करत आहे...</translation>
<translation id="858637041960032120">फोन नंबर जोडा</translation>
<translation id="859285277496340001">पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° निरसà¥à¤¤ à¤à¤¾à¤²à¥‡ आहे किंवा नाही हे तपासणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ पà¥à¤°à¤£à¤¾à¤²à¥€ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ करत नाही.</translation>
@@ -821,6 +895,7 @@
<translation id="8738058698779197622">à¤à¤• सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ कनेकà¥â€à¤¶à¤¨ सà¥â€à¤¥à¤¾à¤ªà¤¿à¤¤ करणà¥â€à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€, आपले घडà¥â€à¤¯à¤¾à¤³ योगà¥à¤¯à¤°à¤¿à¤¤à¥à¤¯à¤¾ सेट केले असणे आवशà¥à¤¯à¤• आहे. कारण वेबसाइट तà¥à¤¯à¤¾à¤‚ना सà¥â€à¤µà¤¤:ला ओळखणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ वापरतात ती पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‡ केवळ निरà¥à¤¦à¤¿à¤·à¥â€à¤Ÿ केलेलà¥â€à¤¯à¤¾ कालावधीसाठी वैध असतात. आपलà¥â€à¤¯à¤¾ डिवà¥â€à¤¹à¤¾à¤‡à¤¸à¤šà¥‡ घडà¥â€à¤¯à¤¾à¤³ चà¥à¤•à¥€à¤šà¥‡ असलà¥â€à¤¯à¤¾à¤®à¥à¤³à¥‡, Chromium ही पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‡ सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ करू शकत नाही.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" />चा &lt;abbr id="dnsDefinition"&gt;DNS पतà¥à¤¤à¤¾&lt;/abbr&gt; शोधणे शकà¥à¤¯ à¤à¤¾à¤²à¥‡ नाही. समसà¥à¤¯à¥‡à¤šà¥‡ निराकरण करीत आहे.</translation>
<translation id="8759274551635299824">या कारà¥à¤¡à¤šà¥€ मà¥à¤¦à¤¤ संपली आहे</translation>
+<translation id="8761567432415473239">Google सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग ला <ph name="SITE" /> वर अलीकडे <ph name="BEGIN_LINK" />हानिकारक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® आढळले आहेत<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;पà¥à¤¨à¥à¤¹à¤¾ करा हटवा</translation>
<translation id="8800988563907321413">आपलà¥à¤¯à¤¾ जवळपासचà¥à¤¯à¤¾ सूचना येथे दिसतात</translation>
<translation id="8820817407110198400">Bookmarks</translation>
@@ -833,29 +908,30 @@
<translation id="8870413625673593573">अलीकडे बंद</translation>
<translation id="8874824191258364635">वैध कारà¥à¤¡ नंबर पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा</translation>
<translation id="8876793034577346603">विशà¥à¤²à¥‡à¤·à¤£ करणà¥à¤¯à¤¾à¤¤ नेटवरà¥à¤• कॉनà¥à¤«à¤¿à¤—रेशन अयशसà¥à¤µà¥€.</translation>
-<translation id="8877192140621905067">आपण पà¥à¤·à¥à¤Ÿà¥€ केलà¥à¤¯à¤¾à¤µà¤°, आपले कारà¥à¤¡ तपशील या साइटसह सामायिक केले जातील</translation>
<translation id="8889402386540077796">रंगछटा</translation>
<translation id="8891727572606052622">अवैध पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ मोड.</translation>
<translation id="889901481107108152">कà¥à¤·à¤®à¤¸à¥à¤µ, हा पà¥à¤°à¤¯à¥‹à¤— आपलà¥à¤¯à¤¾ पà¥à¤²à¥…टफॉरà¥à¤®à¤µà¤° उपलबà¥à¤§ नाही.</translation>
<translation id="8903921497873541725">à¤à¥‚म वाढवा</translation>
<translation id="8931333241327730545">आपण आपलà¥à¤¯à¤¾ Google खातà¥à¤¯à¤¾à¤¤ हे कारà¥à¤¡ जतन करू इचà¥à¤›à¤¿à¤¤à¤¾?</translation>
<translation id="8932102934695377596">आपले घडà¥à¤¯à¤¾à¤³ मागे आहे</translation>
-<translation id="8954894007019320973">(सà¥à¤°à¥‚)</translation>
<translation id="8971063699422889582">सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° कालबाहà¥à¤¯ à¤à¤¾à¤²à¥‡ आहे.</translation>
<translation id="8986494364107987395">Google ला वापर आकडेवारी आणि कà¥à¤°à¥…श अहवाल सà¥à¤µà¤¯à¤‚चलितपणे पाठवा</translation>
-<translation id="8987927404178983737">महिना</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">पà¥à¤¢à¥‡ असणारà¥â€à¤¯à¤¾ साइटमधà¥à¤¯à¥‡ हानिकारक पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® आहेत</translation>
+<translation id="8997023839087525404">सरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° पारदरà¥à¤¶à¤•à¤¤à¤¾ धोरणाचा वापर करून सारà¥à¤µà¤œà¤¨à¤¿à¤•à¤°à¤¿à¤¤à¥à¤¯à¤¾ उघड न केलेले à¤à¤• पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले. काही पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°à¥‡ विशà¥à¤µà¤¸à¤¨à¥€à¤¯ आहेत आणि आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤‚विरूदà¥à¤§ संरकà¥à¤·à¤£ करतात हे सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करणà¥â€à¤¯à¤¾à¤¸à¤¾à¤ à¥€ तà¥à¤¯à¤¾à¤‚चà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ ही à¤à¤• आवशà¥à¤¯à¤•à¤¤à¤¾ आहे.</translation>
<translation id="9001074447101275817">पà¥à¤°à¥‰à¤•à¥à¤¸à¥€ <ph name="DOMAIN" /> ला वापरकरà¥à¤¤à¤¾à¤¨à¤¾à¤µ आणि संकेतशबà¥à¤¦ आवशà¥à¤¯à¤• आहेत.</translation>
+<translation id="9005998258318286617">PDF दसà¥à¤¤à¤à¤µà¤œ लोड करणà¥à¤¯à¤¾à¤¤ अपयश आले.</translation>
<translation id="901974403500617787">सिसà¥à¤Ÿà¥€à¤®-वà¥à¤¯à¤¾à¤ªà¥à¤¤ लागू होणारी धà¥à¤µà¤œà¤¾à¤‚कने केवळ मालकादà¥à¤µà¤¾à¤°à¥‡ सेट केली जाऊ शकतात: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">कारà¥à¤¡ बिलिंग पतà¥à¤¤à¤¾ आवशà¥à¤¯à¤• आहे</translation>
<translation id="9020542370529661692">हे पृषà¥à¤  <ph name="TARGET_LANGUAGE" /> मधà¥à¤¯à¥‡ भाषांतरित केले गेले आहे.</translation>
<translation id="9035022520814077154">सà¥à¤°à¤•à¥à¤·à¤¿à¤¤à¤¤à¤¾ तà¥à¤°à¥à¤Ÿà¥€</translation>
<translation id="9038649477754266430">पृषà¥à¤ à¥‡ अधिक दà¥à¤°à¥à¤¤à¤ªà¤£à¥‡ लोड करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ पूरà¥à¤µà¤¾à¤¨à¥à¤®à¤¾à¤¨ सेवेचा वापर करा</translation>
<translation id="9039213469156557790">पà¥à¤¢à¥‡, या पृषà¥à¤ à¤¾à¤¤ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ नसलेली इतर संसाधने समाविषà¥à¤Ÿ आहेत. ही संसाधने संकà¥à¤°à¤®à¤£à¤¾à¤¤ असताना इतरांदà¥à¤µà¤¾à¤°à¥‡ पाहिली जाऊ शकतात आणि पृषà¥à¤ à¤¾à¤šà¥‡ वरà¥à¤¤à¤¨ बदलणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥à¤¯à¤¾à¤¦à¥à¤µà¤¾à¤°à¥‡ सà¥à¤§à¤¾à¤°à¤¿à¤¤ केली जाऊ शकतात.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> वरील आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¥‡ कदाचित आपलà¥à¤¯à¤¾ बà¥à¤°à¤¾à¤‰à¤à¤¿à¤‚ग अनà¥à¤­à¤µà¤¾à¤¸ हानी पोहोचविणारे पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® (उदाहरणारà¥à¤¥, आपले मà¥à¤–à¥à¤¯à¤ªà¥ƒà¤·à¥à¤  बदलून किंवा आपण भेट देता तà¥à¤¯à¤¾ साइटवर अतिरिकà¥à¤¤ जाहिराती दरà¥à¤¶à¤µà¥‚न) सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ आपली फसवणूक पà¥à¤°à¤¯à¤¤à¥à¤¨ करू शकतात.</translation>
+<translation id="9049981332609050619">आपण <ph name="DOMAIN" /> वर पोहोचणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला, परंतॠसरà¥à¤µà¥à¤¹à¤°à¤¨à¥‡ अवैध पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° सादर केले आहे.</translation>
<translation id="9050666287014529139">सांकेतिक वाकà¥à¤¯à¤¾à¤‚श</translation>
<translation id="9065203028668620118">संपादन</translation>
<translation id="9068849894565669697">रंग निवडा</translation>
+<translation id="9069693763241529744">à¤à¤• विसà¥à¤¤à¤¾à¤°à¤¾à¤¨à¥‡ बà¥à¤²à¥‰à¤• केलेले</translation>
<translation id="9076283476770535406">कदाचित तिचà¥à¤¯à¤¾à¤®à¤§à¥à¤¯à¥‡ पà¥à¤°à¥Œà¤¢ सामगà¥à¤°à¥€ असू शकते</translation>
<translation id="9078964945751709336">अधिक माहिती आवशà¥à¤¯à¤• आहे</translation>
<translation id="9103872766612412690"><ph name="SITE" /> आपली माहिती संरकà¥à¤·à¤¿à¤¤ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ सामानà¥à¤¯à¤¤à¤ƒ कूटबदà¥à¤§à¥€à¤•à¤°à¤£ वापरते. Chromium ने यावेळी <ph name="SITE" /> शी कनेकà¥â€à¤Ÿ करणà¥â€à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ केला तेवà¥â€à¤¹à¤¾, वेबसाइटने असामानà¥à¤¯ आणि अयोगà¥à¤¯ कà¥à¤°à¥‡à¤¡à¥‡à¤¨à¥à¤¶à¤¿à¤¯à¤² परत पाठविले. à¤à¤•à¤¤à¤° आकà¥à¤°à¤®à¤£à¤•à¤°à¥à¤¤à¤¾ <ph name="SITE" /> असलà¥à¤¯à¤¾à¤šà¥€ बतावणी करणà¥à¤¯à¤¾à¤šà¤¾ पà¥à¤°à¤¯à¤¤à¥à¤¨ करतो तेवà¥â€à¤¹à¤¾ किंवा Wi-Fi साइन इन सà¥à¤•à¥à¤°à¥€à¤¨à¤¨à¥‡ कनेकà¥à¤¶à¤¨à¤®à¤§à¥à¤¯à¥‡ वà¥à¤¯à¤¤à¥à¤¯à¤¯ आणले तेवà¥â€à¤¹à¤¾ हे घडू शकते. कोणतà¥à¤¯à¤¾à¤¹à¥€ डेटाची अदलाबदल करणà¥à¤¯à¤¾à¤ªà¥‚रà¥à¤µà¥€ Chromium ने कनेकà¥à¤¶à¤¨ थांबविलà¥à¤¯à¤¾à¤®à¥à¤³à¥‡ आपली माहिती अदà¥à¤¯à¤¾à¤ª सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ आहे.</translation>
@@ -864,16 +940,21 @@
<translation id="9148507642005240123">&amp;संपादित करा पूरà¥à¤µà¤µà¤¤ करा</translation>
<translation id="9154194610265714752">अदà¥à¤¯à¤¤à¤¨à¤¿à¤¤ केलेले</translation>
<translation id="9157595877708044936">सेट अप करीत आहे...</translation>
+<translation id="9169664750068251925">या साइटवर नेहमी अवरोधित करा</translation>
<translation id="9170848237812810038">&amp;पूरà¥à¤µà¤µà¤¤ करा</translation>
<translation id="917450738466192189">सरà¥à¤µà¥à¤¹à¤°à¤šà¥‡ पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤° अवैध आहे.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> आणि आणखी <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> असमरà¥à¤¥à¤¿à¤¤ पà¥à¤°à¥‹à¤Ÿà¥‹à¤•à¥‰à¤² वापरतो.</translation>
<translation id="9205078245616868884">आपला डेटा आपलà¥à¤¯à¤¾ संकालन सांकेतिक वाकà¥à¤¯à¤¾à¤‚शासह कूटबदà¥à¤§ केला जातो. संकालन सà¥à¤°à¥ करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ तो पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करा.</translation>
<translation id="9207861905230894330">लेख जोडणà¥à¤¯à¤¾à¤¤ अयशसà¥à¤µà¥€.</translation>
+<translation id="9219103736887031265">पà¥à¤°à¤¤à¤¿à¤®à¤¾</translation>
<translation id="933612690413056017">इंटरनेट कनेकà¥à¤¶à¤¨ नाही</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">फॉरà¥à¤® साफ करा</translation>
<translation id="939736085109172342">नवीन फोलà¥â€à¤¡à¤°</translation>
<translation id="941721044073577244">आपलà¥à¤¯à¤¾à¤²à¤¾ या साइटला भेट देणà¥à¤¯à¤¾à¤šà¥€ परवानगी नाही असे दिसते</translation>
<translation id="969892804517981540">अधिकृत बिलà¥à¤¡</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{काहीही नाही}=1{1 आयटम}one{# आयटम}other{# आयटम}}</translation>
<translation id="988159990683914416">विकसक बिलà¥à¤¡</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ms.xtb b/chromium/components/strings/components_strings_ms.xtb
index f92a55c09e7..15a927a190a 100644
--- a/chromium/components/strings/components_strings_ms.xtb
+++ b/chromium/components/strings/components_strings_ms.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Putar ikut arah jam</translation>
<translation id="1038842779957582377">nama tidak diketahui</translation>
<translation id="1050038467049342496">Tutup apl lain</translation>
-<translation id="1053591932240354961">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana tapak web ini menghantar bukti kelayakan yang dicampuradukkan sehingga tidak dapat diproses oleh Google Chrome. Ralat rangkaian dan serangan biasanya bersifat sementara, oleh itu halaman ini mungkin akan berfungsi sebentar lagi. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Buat Asal Tambahkan</translation>
<translation id="10614374240317010">Tidak pernah disimpan</translation>
<translation id="106701514854093668">Penanda Halaman Desktop</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cache dasar OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> menyatakan:</translation>
<translation id="1132774398110320017">Tetapan Auto Isi Chrome...</translation>
+<translation id="1150979032973867961">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh sistem pengendalian komputer anda. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
+<translation id="1151972924205500581">Kata laluan diperlukan</translation>
<translation id="1152921474424827756">Akses <ph name="BEGIN_LINK" />salinan cache<ph name="END_LINK" /> <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> menutup sambungan tanpa di jangka.</translation>
<translation id="1161325031994447685">Menyambung semula kepada Wi-Fi</translation>
+<translation id="1165039591588034296">Ralat</translation>
<translation id="1175364870820465910">&amp;Cetak...</translation>
<translation id="1181037720776840403">Buang</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Laporkan secara automatik<ph name="END_WHITEPAPER_LINK" /> tentang butiran kemungkinan insiden keselamatan kepada Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Lagi dari tapak ini</translation>
<translation id="1206967143813997005">Tandatangan awal tidak sah</translation>
<translation id="1209206284964581585">Sorok sementara</translation>
+<translation id="121201262018556460">Anda cuba untuk mencapai <ph name="DOMAIN" /> , tetapi pelayan memberi sijil yang mengandungi kunci yang lemah, Penyerang mungkin telah merosakkan kunci peribadi dan pelayan tersebut mungkin bukan pelayan yang anda jangkakan (anda mungkin berkomunikasi dengan penyerang).</translation>
<translation id="1219129156119358924">Keselamatan Sistem</translation>
<translation id="1227224963052638717">Dasar tidak diketahui.</translation>
<translation id="1227633850867390598">Sembunyikan nilai</translation>
<translation id="1228893227497259893">Pengecam entiti yang salah</translation>
<translation id="1232569758102978740">Tidak Bertajuk</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (disegerakkan)</translation>
<translation id="1263231323834454256">Senarai bacaan</translation>
<translation id="1264126396475825575">Laporan ranap sistem dirakam pada <ph name="CRASH_TIME" /> (belum dimuat naik atau diabaikan)</translation>
+<translation id="1281526147609854549">Dikeluarkan oleh <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Kandungan berbahaya disekat</translation>
<translation id="1285320974508926690">Jangan sekali-kali menterjemahkan tapak ini</translation>
<translation id="129553762522093515">Ditutup baru-baru ini</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Cuba kosongkan kuki anda<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Aktiviti anda <ph name="BEGIN_EMPHASIS" />mungkin masih boleh dilihat<ph name="END_EMPHASIS" /> oleh:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Tapak web yang anda lawati
+ <ph name="LIST_ITEM" />Majikan atau institusi pengajian anda
+ <ph name="LIST_ITEM" />Penyedia perkhidmatan Internet anda
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domain pendaftaran:</translation>
<translation id="1340482604681802745">Alamat pengambilan</translation>
<translation id="1344211575059133124">Nampaknya anda memerlukan kebenaran untuk melawat tapak ini</translation>
<translation id="1344588688991793829">Tetapan Auto Isi Chromium...</translation>
+<translation id="1348198688976932919">Tapak yang akan disemak imbas mengandungi apl berbahaya</translation>
<translation id="1374468813861204354">cadangan</translation>
<translation id="1375198122581997741">Mengenai Versi</translation>
<translation id="1377321085342047638">Nombor Kad</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> tidak menghantar sebarang data.</translation>
<translation id="1407135791313364759">Buka semua</translation>
<translation id="1413809658975081374">Ralat privasi</translation>
+<translation id="14171126816530869">Identiti <ph name="ORGANIZATION" /> di <ph name="LOCALITY" /> telah disahkan oleh <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ya</translation>
<translation id="1430915738399379752">Cetak</translation>
-<translation id="1442912890475371290">Percubaan <ph name="BEGIN_LINK" />untuk melawat halaman di <ph name="DOMAIN" /><ph name="END_LINK" /> disekat.</translation>
-<translation id="1491663344921578213">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana tapak web ini menggunakan penyematan sijil. Ralat rangkaian dan serangan biasanya bersifat sementara, oleh itu halaman ini mungkin akan berfungsi sebentar lagi. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> lagi}other{<ph name="PAYMENT_METHOD_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> lagi}}</translation>
<translation id="1506687042165942984">Tunjukkan salinan yang disimpan (iaitu diketahui telah lapuk) bagi halaman ini.</translation>
<translation id="1517433312004943670">Nombor telefon diperlukan</translation>
<translation id="1519264250979466059">Tarikh Bina</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Javascript mesti didayakan untuk menggunakan ciri ini.</translation>
<translation id="1555130319947370107">Biru</translation>
<translation id="1559528461873125649">Tiada fail atau direktori sedemikian</translation>
-<translation id="1559572115229829303">&lt;p&gt;Sambungan peribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak boleh diwujudkan kerana tarikh dan masa peranti anda (<ph name="DATE_AND_TIME" />) tidak betul.&lt;/p&gt;
-
- &lt;p&gt;Sila laraskan tarikh dan masa daripada bahagian &lt;strong&gt;Umum&lt;/strong&gt; bagi apl &lt;strong&gt;Tetapan&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Kesilapan berlaku semasa memaparkan halaman web ini.</translation>
<translation id="1592005682883173041">Akses Data Setempat</translation>
+<translation id="1594030484168838125">Pilih</translation>
<translation id="161042844686301425">Sian</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Adakah anda mahu Chrome menyimpan kad ini?</translation>
<translation id="1639239467298939599">Memuatkan</translation>
<translation id="1640180200866533862">Dasar pengguna</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Konfigurasi rangkaian tidak sah dan tidak boleh diimport.</translation>
<translation id="1644574205037202324">Sejarah</translation>
<translation id="1645368109819982629">Protokol tidak disokong</translation>
+<translation id="1655462015569774233">{1,plural, =1{Pelayan ini tidak dapat membuktikan bahawa <ph name="DOMAIN" />; sijil keselamatannya tamat tempoh semalam. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. Jam komputer anda ditetapkan kepada <ph name="CURRENT_DATE" /> pada masa ini. Adakah itu betul? Jika tidak, anda perlu membetulkan jam sistem anda dan kemudian muat semula halaman ini.}other{Pelayan ini tidak dapat membuktikan bahawa <ph name="DOMAIN" />; sijil keselamatannya tamat tempoh # hari yang lalu. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. Jam komputer anda ditetapkan kepada <ph name="CURRENT_DATE" /> pada masa ini. Adakah itu betul? Jika tidak, anda perlu membetulkan jam sistem anda dan kemudian muat semula halaman ini.}}</translation>
<translation id="1656489000284462475">Pengambilan</translation>
<translation id="1663943134801823270">Kad dan alamat adalah daripada Chrome. Anda boleh mengurus kad dan alamat ini dalam <ph name="BEGIN_LINK" />Tetapan<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> biasanya menggunakan penyulitan untuk melindungi maklumat anda. Apabila Google Chrome cuba menyambung ke <ph name="SITE" /> pada kali ini, tapak web tersebut mengembalikan bukti kelayakan yang luar biasa dan salah. Hal ini boleh berlaku apabila penyerang sedang cuba menyamar sebagai <ph name="SITE" /> atau skrin log masuk Wi-Fi telah memutuskan sambungan. Maklumat anda masih selamat kerana Google Chrome menghentikan sambungan sebelum sebarang pertukaran data berlaku.</translation>
-<translation id="168328519870909584">Penyerang yang kini berada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin cuba memasang apl berbahaya pada peranti anda yang mencuri atau memadamkan maklumat anda (sebagai contoh, foto, kata laluan, mesej dan kad kredit).</translation>
<translation id="168841957122794586">Sijil pelayan mengandungi kunci kriptografi yang lemah.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />;sijil keselamatannya sepatutnya bermula esok. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda.}other{Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya sepatutnya bermula # hari lagi. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Anda memerlukan kebenaran daripada <ph name="NAME" /> untuk melawat tapak ini</translation>
<translation id="1721424275792716183">* Medan perlu diisi</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Muat turun halaman kemudian</translation>
<translation id="17513872634828108">Buka tab</translation>
<translation id="1753706481035618306">Nombor halaman</translation>
+<translation id="1763864636252898013">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh sistem pengendalian peranti anda. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Cuba jalankan Diagnostik Rangkaian Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Sila kemas kini frasa laluan segerak anda.</translation>
<translation id="1787142507584202372">Tab yang dibuka dipaparkan di sini</translation>
+<translation id="1789575671122666129">Pop timbul</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nama Pemegang Kad</translation>
-<translation id="1803678881841855883">Penyemakan Imbas Selamat Google <ph name="BEGIN_LINK" />mengesan perisian hasad<ph name="END_LINK" /> di <ph name="SITE" /> baru-baru ini. Tapak web yang lazimnya selamat, kadangkala dijangkiti perisian hasad. Kandungan hasad berasal daripada <ph name="SUBRESOURCE_HOST" />, iaitu pengedar perisian hasad yang diketahui. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Ditambahkan <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Permintaan atau parameter permintaan tidak sah</translation>
<translation id="1826516787628120939">Menyemak</translation>
<translation id="1834321415901700177">Tapak ini mengandungi atur cara berbahaya</translation>
+<translation id="1840414022444569775">Nombor kad ini sudah digunakan</translation>
<translation id="1842969606798536927">Bayar</translation>
<translation id="1871208020102129563">Proksi ditetapkan untuk menggunakan pelayan proksi tetap, bukannya URL skrip .pac.</translation>
<translation id="1871284979644508959">Medan yang diperlukan</translation>
<translation id="187918866476621466">Buka halaman permulaan</translation>
<translation id="1883255238294161206">Runtuhkan senarai</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> lagi}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> lagi}}</translation>
<translation id="1898423065542865115">Penapisan</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Tiada}=1{1 tapak}other{# tapak}}</translation>
<translation id="194030505837763158">Pergi ke <ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> Penanda halaman</translation>
<translation id="1973335181906896915">Ralat penyirian</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Diabaikan kerana ia telah diatasi oleh <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Mencari halaman Web Fizikal yang berdekatan</translation>
<translation id="213826338245044447">Penanda Halaman Mudah Alih</translation>
-<translation id="2148716181193084225">Hari ini</translation>
+<translation id="2147827593068025794">Penyegerakan Latar Belakang</translation>
<translation id="2154054054215849342">Penyegerakan tidak tersedia untuk domain anda</translation>
<translation id="2154484045852737596">Edit kad</translation>
<translation id="2166049586286450108">Akses Penuh Pentadbir</translation>
<translation id="2166378884831602661">Tapak ini tidak dapat menyediakan sambungan yang selamat</translation>
<translation id="2181821976797666341">Dasar</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 alamat}other{# alamat}}</translation>
+<translation id="2187317261103489799">Kesan (lalai)</translation>
<translation id="2202020181578195191">Masukkan tahun tamat tempoh yang sah</translation>
<translation id="2212735316055980242">Dasar tidak dijumpai</translation>
<translation id="2213606439339815911">Mengambil entri…</translation>
+<translation id="2218879909401188352">Penyerang yang berada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> boleh memasang apl berbahaya yang boleh merosakkan peranti anda, menambahkan caj yang tersembunyi pada bil mudah alih anda atau mencuri maklumat peribadi anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Betulkan sambungan anda menggunakan <ph name="BEGIN_LINK" />apl diagnostik<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Hantar sekarang</translation>
<translation id="225207911366869382">Nilai ini tidak lagi digunakan untuk dasar ini.</translation>
<translation id="2262243747453050782">Ralat HTTP</translation>
+<translation id="2270484714375784793">Nombor telefon</translation>
<translation id="2282872951544483773">Eksperimen Tidak Tersedia</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item}other{<ph name="ITEM_COUNT" /> item}}</translation>
<translation id="2292556288342944218">Akses Internet anda disekat</translation>
<translation id="230155334948463882">Kad baharu?</translation>
-<translation id="2305919008529760154">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya mungkin telah dikeluarkan secara penipuan. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> memerlukan nama pengguna dan kata laluan.</translation>
-<translation id="2318774815570432836">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana tapak web ini menggunakan HSTS. Ralat rangkaian dan serangan biasanya bersifat sementara, oleh itu halaman ini mungkin akan berfungsi sebentar lagi. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Tetapan dikawal oleh pentadbir anda</translation>
<translation id="2354001756790975382">Penanda halaman lain</translation>
+<translation id="2354430244986887761">Penyemakan Imbas Selamat Google <ph name="BEGIN_LINK" />menemui apl yang memudaratkan<ph name="END_LINK" /> di <ph name="SITE" /> baru-baru ini.</translation>
<translation id="2355395290879513365">Penyerang mungkin dapat melihat imej yang anda lihat di tapak ini dan menipu anda dengan mengubah suainya.</translation>
+<translation id="2356070529366658676">Tanya</translation>
+<translation id="2359629602545592467">Berbilang</translation>
<translation id="2359808026110333948">Teruskan</translation>
<translation id="2365563543831475020">Laporan ranap sistem yang dirakam pada <ph name="CRASH_TIME" /> tidak dimuat naik</translation>
<translation id="2367567093518048410">Tahap</translation>
-<translation id="2371153335857947666">{1,plural, =1{Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya tamat tempoh semalam. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. Jam komputer anda ditetapkan kepada <ph name="CURRENT_DATE" /> pada masa ini. Adakah itu betul? Jika tidak, anda perlu membetulkan jam sistem anda dan kemudian muatkan semula halaman ini. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}other{Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya tamat tempoh # hari yang lalu. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. Jam komputer anda ditetapkan kepada <ph name="CURRENT_DATE" /> pada masa ini. Adakah itu betul? Jika tidak, anda perlu membetulkan jam sistem anda dan kemudian muatkan semula halaman ini. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Tiada alternatif UI tersedia</translation>
<translation id="2384307209577226199">Lalai perusahaan</translation>
<translation id="2386255080630008482">Sijil pelayan telah dibatalkan.</translation>
<translation id="2392959068659972793">Paparkan dasar tanpa nilai yang ditetapkan</translation>
<translation id="239429038616798445">Kaedah penghantaran ini tidak tersedia. Cuba kaedah lain.</translation>
<translation id="2396249848217231973">&amp;Buat asal pemadaman</translation>
-<translation id="2460160116472764928">Penyemakan Imbas Selamat <ph name="BEGIN_LINK" />mengesan perisian hasad <ph name="END_LINK" /> di <ph name="SITE" /> baru-baru ini. Tapak web yang biasanya selamat, kadangkala dijangkiti perisian hasad. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya mungkin dibatalkan. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
<translation id="2463739503403862330">Isi</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Jalankan Diagnostik Rangkaian<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL carian tidak sah.</translation>
+<translation id="2482878487686419369">Pemberitahuan</translation>
<translation id="2491120439723279231">Sijil pelayan mengandungi ralat.</translation>
<translation id="2495083838625180221">Penghurai JSON</translation>
<translation id="2495093607237746763">Jika ditandai, Chromium akan menyimpan salinan kad anda pada peranti ini untuk pengisian borang yang lebih cepat.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Kembali</translation>
<translation id="2515629240566999685">Semak isyarat di kawasan anda</translation>
<translation id="2516305470678292029">Alternatif UI</translation>
+<translation id="2539524384386349900">Kesan</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> menghantar balasan yang tidak sah.</translation>
-<translation id="2552545117464357659">Lebih baharu</translation>
<translation id="2556876185419854533">&amp;Buat Asal Edit</translation>
<translation id="2587730715158995865">Daripada <ph name="ARTICLE_PUBLISHER" />. Baca artikel ini dan <ph name="OTHER_ARTICLE_COUNT" /> cerita lain.</translation>
<translation id="2587841377698384444">ID API Direktori:</translation>
<translation id="2597378329261239068">Dokumen ini dilindungi kata laluan. Sila masukkan kata laluan.</translation>
<translation id="2609632851001447353">Variasi</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Tiada}=1{1 apl ($1)}=2{2 apl ($1, $2)}other{# apl ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Jam anda lebih awal</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Akses ke fail dinafikan</translation>
<translation id="2653659639078652383">Serah</translation>
<translation id="2666117266261740852">Tutup tab atau apl lain</translation>
+<translation id="2670429602441959756">Halaman ini mengandungi ciri yang belum disokong dalam VR. Meninggalkan halaman...</translation>
<translation id="2674170444375937751">Adakah anda pasti anda mahu memadamkan halaman ini daripada sejarah anda?</translation>
<translation id="2677748264148917807">Tinggalkan</translation>
-<translation id="269990154133806163">Pelayan memberikan sijil yang tidak didedahkan kepada umum menggunakan dasar Ketelusan Sijil. Ini merupakan keperluan bagi sesetengah sijil, untuk memastikan bahawa sijil itu boleh dipercayai dan menyediakan perlindungan daripada penyerang.<ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Senarai Bacaan</translation>
<translation id="2704283930420550640">Nilai tidak sepadan dengan format.</translation>
<translation id="2704951214193499422">Chromium tidak dapat mengesahkan kad anda pada masa ini. Sila cuba lagi nanti.</translation>
<translation id="2705137772291741111">Salinan tapak ini yang disimpan (cache) tidak boleh dibaca.</translation>
<translation id="2709516037105925701">Autoisi</translation>
-<translation id="2712118517637785082">Anda cuba mencapai <ph name="DOMAIN" />, tetapi sijil yang diberi pelayan telah dibatalkan oleh pengeluarnya. Ini bermakna bukti kelayakan keselamatan yang diberi pelayan sememangnya tidak boleh dipercayai. Anda mungkin berkomunikasi dengan penyerang. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Minta kebenaran</translation>
<translation id="2713444072780614174">Putih</translation>
<translation id="2720342946869265578">Berdekatan</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Tiada rekod peranti</translation>
<translation id="2784949926578158345">Sambungan ditetapkan semula.</translation>
<translation id="2794233252405721443">Tapak disekat</translation>
+<translation id="2799020568854403057">Tapak yang akan disemak imbas mengandungi apl yang memudaratkan</translation>
+<translation id="2803306138276472711">Penyemakan Selamat Google <ph name="BEGIN_LINK" />mengesan perisian hasad<ph name="END_LINK" /> pada <ph name="SITE" /> baru-baru ini. Tapak web yang biasanya selamat kadangkala dijangkiti oleh perisian hasad.</translation>
<translation id="2824775600643448204">Bar alamat dan carian</translation>
<translation id="2826760142808435982">Sambungan disulitkan dan disahkan menggunakan <ph name="CIPHER" /> dan menggunakan <ph name="KX" /> sebagai mekanisme pertukaran kunci.</translation>
<translation id="2835170189407361413">Kosongkan borang</translation>
+<translation id="2856444702002559011">Penyerang mungkin akan cuba mencuri maklumat anda daripada <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (contohnya, kata laluan, mesej atau kad kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Jangan Muat Semula</translation>
<translation id="2900469785430194048">Google Chrome kehabisan memori semasa cuba memaparkan halaman web ini.</translation>
<translation id="2909946352844186028">Perubahan rangkaian dikesan.</translation>
<translation id="2916038427272391327">Tutup atur cara lain</translation>
<translation id="2922350208395188000">Sijil pelayan tidak boleh diperiksa.</translation>
<translation id="2928905813689894207">Alamat Pengebilan</translation>
+<translation id="2941952326391522266">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya adalah dari <ph name="DOMAIN2" />. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
<translation id="2948083400971632585">Anda boleh melumpuhkan sebarang proksi yang dikonfigurasi untuk sambungan dari halaman tetapan.</translation>
<translation id="2955913368246107853">Tutup bar cari</translation>
<translation id="2958431318199492670">Konfigurasi rangkaian tidak mematuhi piawaian ONC. Sebahagian konfigurasi tidak boleh diimport.</translation>
-<translation id="29611076221683977">Penyerang yang ada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pada masa ini mungkin cuba memasang program berbahaya pada Mac anda yang boleh mencuri atau memadamkan maklumat anda (contohnya foto, kata laluan, mesej dan kad kredit).</translation>
<translation id="2966678944701946121">Tamat: <ph name="EXPIRATION_DATE_ABBR" />, ditambahkan <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Untuk mewujudkan sambungan yang selamat, jam anda perlu ditetapkan dengan betul. Perkara ini perlu dilakukan kerana sijil yang digunakan laman web untuk mengenal pastinya hanya sah untuk tempoh masa yang tertentu. Memandangkan jam peranti anda tidak betul, Google Chrome tidak boleh mengesahkan sijil ini.</translation>
<translation id="2972581237482394796">&amp;Buat Semula</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Masukkan alamat yang sah</translation>
<translation id="2986368408720340940">Kaedah pengambilan ini tidak tersedia. Cuba kaedah lain.</translation>
<translation id="2991174974383378012">Berkongsi dengan Tapak Web</translation>
+<translation id="2991571918955627853">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana tapak web ini menggunakan HSTS. Ralat dan serangan rangkaian biasanya sementara. Oleh sebab itu, halaman ini mungkin akan berfungsi semula kemudian.</translation>
<translation id="3005723025932146533">Paparkan salinan disimpan</translation>
<translation id="3008447029300691911">Masukkan CVC untuk <ph name="CREDIT_CARD" />. Setelah anda mengesahkan, butiran kad anda akan dikongsi dengan tapak ini.</translation>
<translation id="3010559122411665027">Masukan senarai "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Disekat secara automatik</translation>
<translation id="3024663005179499861">Jenis dasar salah</translation>
<translation id="3032412215588512954">Adakah anda ingin memuat semula tapak ini?</translation>
<translation id="3037605927509011580">Oh, Tidak!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{sekurang-kurangnya 1 item pada peranti yang disegerakkan}=1{1 item (dan beberapa lagi pada peranti yang disegerakkan)}other{# item (dan beberapa lagi pada peranti yang disegerakkan)}}</translation>
<translation id="3041612393474885105">Maklumat Sijil</translation>
<translation id="3063697135517575841">Chrome tidak dapat mengesahkan kad anda pada masa ini. Sila cuba sebentar lagi.</translation>
<translation id="3064966200440839136">Meninggalkan mod inkognito untuk membayar melalui aplikasi luar. Teruskan?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Tiada}=1{1 kata laluan}other{# kata laluan}}</translation>
<translation id="3093245981617870298">Anda di luar talian.</translation>
<translation id="3105172416063519923">ID Aset:</translation>
<translation id="3109728660330352905">Anda tidak mempunyai kebenaran untuk melihat halaman ini.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Cuba jalankan Diagnostik Sambungan<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Gagal menyahkod balasan</translation>
<translation id="3150653042067488994">Ralat pelayan sementara</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Halaman yang anda lihat dalam tab inkognito tidak akan kekal dalam sejarah, simpanan kuki atau sejarah carian penyemak imbas anda selepas anda menutup semua tab inkognito anda. Sebarang fail yang anda muat turun atau penanda halaman yang anda buat akan disimpan.</translation>
<translation id="3169472444629675720">Temui</translation>
<translation id="3174168572213147020">Pulau</translation>
+<translation id="317583078218509884">Tetapan kebenaran tapak baharu akan dilaksanakan selepas memuatkan semula halaman.</translation>
<translation id="3176929007561373547">Semak tetapan proksi anda atau hubungi pentadbir rangkaian anda untuk
memastikan pelayan proksi berfungsi. Jika anda tidak percaya anda perlu
menggunakan pelayan proksi:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Buka halaman dalam mod Inkognito</translation>
-<translation id="3202578601642193415">Terbaru</translation>
+<translation id="320323717674993345">Batal Pembayaran</translation>
<translation id="3207960819495026254">Ditandai halaman</translation>
+<translation id="3225919329040284222">Pelayan memberikan sijil yang tidak sepadan dengan jangkaan terbina dalam. Jangkaan ini disertakan untuk tapak web dengan keselamatan tinggi tertentu untuk melindungi anda.</translation>
<translation id="3226128629678568754">Tekan butang muat semula untuk menyerahkan kembali data yang diperlukan untuk memuatkan halaman.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Gagal terjemah kerana halaman sudah dalam <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Masukkan CVC untuk <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Sentiasa kesan kandungan penting di tapak web ini</translation>
<translation id="3254409185687681395">Tanda halaman ini</translation>
<translation id="3270847123878663523">&amp;Buat asal Susun semula</translation>
<translation id="3282497668470633863">Tambahkan nama pada kad</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">tetapan</translation>
<translation id="3345135638360864351">Permintaan anda untuk mengakses tapak web ini tidak boleh dihantar kepada <ph name="NAME" />. Sila cuba lagi.</translation>
<translation id="3355823806454867987">Tukar tetapan proksi...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />tidak akan menyimpan<ph name="END_EMPHASIS" /> maklumat berikut:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Sejarah semak imbas anda
+ <ph name="LIST_ITEM" />Kuki dan data tapak
+ <ph name="LIST_ITEM" />Maklumat yang dimasukkan dalam borang
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Ralat Jam</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> item lagi...</translation>
<translation id="337363190475750230">Nyahperuntukkan</translation>
<translation id="3377188786107721145">Ralat menghuraikan dasar</translation>
<translation id="3380365263193509176">Ralat tidak diketahui</translation>
<translation id="3380864720620200369">ID Pelanggan:</translation>
<translation id="3391030046425686457">Alamat penghantaran</translation>
<translation id="3395827396354264108">Kaedah pengambilan</translation>
-<translation id="340013220407300675">Penyerang mungkin akan cuba mencuri maklumat anda daripada <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (sebagai contoh, kata laluan, mesej atau kad kredit).</translation>
<translation id="3422248202833853650">Cuba keluar daripada atur cara lain untuk mengosongkan memori.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> tidak dapat dicapai pada masa ini.</translation>
+<translation id="3427092606871434483">Benarkan (lalai)</translation>
<translation id="3427342743765426898">&amp;Buat Semula Edit</translation>
<translation id="3431636764301398940">Simpan kad ini pada peranti ini</translation>
<translation id="3435896845095436175">Dayakan</translation>
<translation id="3447661539832366887">Pemilik peranti ini telah mematikan permainan dinosaur.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Selang masa ambil:</translation>
<translation id="3462200631372590220">Menyembunyikan butiran</translation>
<translation id="3467763166455606212">Nama pemegang kad diperlukan</translation>
<translation id="3478058380795961209">Bulan Tamat Tempoh</translation>
<translation id="3479539252931486093">Adakah hal ini tidak dijangka? <ph name="BEGIN_LINK" />Beritahu kami<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Bukan sekarang</translation>
-<translation id="348000606199325318">ID Ranap Sistem <ph name="CRASH_LOCAL_ID" /> (ID Pelayan: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Kami tidak dapat menghubungi ibu bapa anda pada masa ini. Sila cuba lagi.</translation>
<translation id="3528171143076753409">Sijil pelayan tidak dipercayai.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Sekurang-kurangnya 1 item pada peranti yang disegerakkan}=1{1 item (dan beberapa lagi pada peranti yang disegerakkan)}other{# item (dan beberapa lagi pada peranti yang disegerakkan)}}</translation>
<translation id="3539171420378717834">Simpan salinan kad ini pada peranti ini</translation>
<translation id="3542684924769048008">Gunakan kata laluan untuk:</translation>
+<translation id="3545341443414427877">Sambungan peribadi kepada <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat diwujudkan kerana tarikh dan masa komputer anda (<ph name="DATE_AND_TIME" />) tidak betul. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Sulitkan semua data yang disegerakkan dengan ungkapan laluan segerak anda sendiri</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> lagi...</translation>
-<translation id="3555561725129903880">Pelayan ini tidak dapat membuktikan bahawa iitu <ph name="DOMAIN" />; sijil keselamatannya berasal daripada <ph name="DOMAIN2" />. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Pengurus anda boleh menyahsekatnya untuk anda</translation>
<translation id="3566021033012934673">Sambungan anda tidak diperibadikan</translation>
+<translation id="3569145463236695319">&lt;p&gt;Sambungan peribadi kepada <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat diwujudkan kerana tarikh dan masa peranti anda (<ph name="DATE_AND_TIME" />) tidak betul.&lt;/p&gt;
+
+ &lt;p&gt;Sila laraskan tarikh dan masa daripada bahagian &lt;strong&gt;Umum&lt;/strong&gt; apl &lt;strong&gt;Tetapan&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Tambah nama</translation>
<translation id="3583757800736429874">&amp;Buat Semula Pindahkan</translation>
<translation id="3586931643579894722">Sembunyikan butiran</translation>
-<translation id="3587482841069643663">Semua</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Masukkan tarikh tamat tempoh yang sah</translation>
<translation id="36224234498066874">Kosongkan Data Penyemakan Imbas...</translation>
@@ -323,7 +363,6 @@
<translation id="3681007416295224113">Maklumat sijil</translation>
<translation id="3690164694835360974">Log masuk tidak selamat</translation>
<translation id="3693415264595406141">Kata laluan:</translation>
-<translation id="3696411085566228381">tiada</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Memuatkan...</translation>
<translation id="3712624925041724820">Kehabisan lesen</translation>
@@ -331,12 +370,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Menyemak proksi, tembok api dan konfigurasi DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Jika anda memahami risiko terhadap keselamatan anda, anda boleh <ph name="BEGIN_LINK" />melawati tapak web yang tidak selamat ini<ph name="END_LINK" /> sebelum program berbahaya dialih keluar.</translation>
<translation id="3739623965217189342">Pautan yang anda salin</translation>
+<translation id="3744899669254331632">Anda tidak boleh melawat <ph name="SITE" /> sekarang kerana tapak web telah menghantar bukti kelayakan hancur yang tidak boleh diproses oleh Chromium. Ralat dan serangan rangkaian biasanya sementara. Oleh itu halaman ini mungkin akan berfungsi kemudian.</translation>
+<translation id="3748148204939282805">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin memperdaya anda agar melakukan sesuatu yang berbahaya seperti memasang perisian atau mendedahkan maklumat peribadi anda (contohnya, kata laluan, nombor telefon atau kad kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Gagal menterjemah disebabkan ralat pelayan.</translation>
<translation id="3759461132968374835">Tiada laporan nahas yang dibuat baru-baru ini. Nahas yang berlaku apabila laporan nahas dilumpuhkan tidak akan kelihatan di sini.</translation>
+<translation id="3778403066972421603">Adakah anda ingin menyimpan maklumat kad ini ke Akaun Google anda dan pada peranti ini?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Tamat tempoh pada <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Jika anda menggunakan pelayan proksi...</translation>
<translation id="3828924085048779000">Kosongkan frasa laluan adalah tidak dibenarkan.</translation>
-<translation id="3845539888601087042">Menunjukkan sejarah daripada peranti anda yang dilog masuk. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Kembali</translation>
<translation id="3858027520442213535">Kemas kini tarikh dan masa</translation>
<translation id="3884278016824448484">Pengecam peranti bercanggah</translation>
@@ -344,11 +386,13 @@
<translation id="3886446263141354045">Permintaan anda untuk mengakses tapak ini telah dihantar kepada <ph name="NAME" />.</translation>
<translation id="3890664840433101773">Tambah e-mel</translation>
<translation id="3901925938762663762">Kad telah tamat tempoh</translation>
-<translation id="3933571093587347751">{1,plural, =1{Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya sepatutnya bermula esok. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}other{Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya sepatutnya bermula # hari lagi. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Gagal untuk memuatkan dokumen PDF</translation>
+<translation id="3945915738023014686">ID Laporan Ranap Yang Dimuat Naik <ph name="CRASH_ID" /> (ID Ranap Setempat: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak menyatakan Nama Alternatif Subjek. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang memintasi sambungan anda.</translation>
<translation id="3963721102035795474">Mod Pembaca</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Tiada}=1{Daripada 1 tapak }other{Daripada # tapak }}</translation>
<translation id="397105322502079400">Mengira...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> disekat</translation>
+<translation id="3987940399970879459">Kurang daripada 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 halaman web berdekatan}other{# halaman web berdekatan}}</translation>
<translation id="4021036232240155012">DNS ialah perkhidmatan rangkaian yang menterjemahkan nama tapak web kepada alamat Internetnya.</translation>
<translation id="4030383055268325496">&amp;Buat asal tambahkan</translation>
@@ -359,56 +403,63 @@
<translation id="4079302484614802869">Konfigurasi proksi ditetapkan kepada penggunaaan URL skrip .pac, bukannya pelayan proksi tetap.</translation>
<translation id="4098354747657067197">Tapak menipu di hadapan</translation>
<translation id="4103249731201008433">Nombor siri peranti tidak sah</translation>
+<translation id="410351446219883937">Automain</translation>
<translation id="4103763322291513355">Lawati &lt;strong&gt;chrome://policy&lt;/strong&gt; untuk melihat senarai URL yang disenarai hitam dan dasar lain yang dikuatkuasakan oleh pentadbir sistem anda.</translation>
-<translation id="4110615724604346410">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya mengandungi ralat. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Sentiasa benarkan di tapak ini</translation>
<translation id="4117700440116928470">Skop dasar tidak disokong.</translation>
-<translation id="4118212371799607889">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh Chromium. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 yang lain}other{# yang lain}}</translation>
<translation id="4130226655945681476">Memeriksa kabel rangkaian, modem dan penghala</translation>
+<translation id="413544239732274901">Ketahui lebih lanjut</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Gunakan lalai global (Kesan)</translation>
+<translation id="4165986682804962316">Tetapan tapak</translation>
<translation id="4169947484918424451">Adakah anda mahu Chromium menyimpan kad ini?</translation>
<translation id="4171400957073367226">Tandatangan pengesahan tidak sah</translation>
<translation id="4196861286325780578">&amp;Buat semula pindahkan</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Menyemak konfigurasi tembok api dan antivirus<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{tiada}=1{1 apl ($1)}=2{2 apl ($1, $2)}other{# apl ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Nahas</translation>
+<translation id="422022731706691852">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin cuba memperdaya anda agar memasang atur cara yang membahayakan pengalaman penyemakan imbas anda (contohnya, dengan menukar halaman utama anda atau menunjukkan iklan tambahan pada tapak yang anda lawati). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Cuba jalankan Diagnostik Rangkaian<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Sah</translation>
<translation id="4250431568374086873">Sambungan anda ke tapak ini tidak selamat sepenuhnya</translation>
<translation id="4250680216510889253">Tidak</translation>
<translation id="425582637250725228">Perubahan yang anda buat mungkin tidak disimpan.</translation>
<translation id="4258748452823770588">Tandatangan tidak elok</translation>
+<translation id="4265872034478892965">Dibenarkan oleh pentadbir anda</translation>
<translation id="4269787794583293679">(Tiada nama pengguna)</translation>
<translation id="4275830172053184480">Mulakan semula peranti anda</translation>
<translation id="4280429058323657511">, tamat tempoh <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Penyemakan Imbas Selamat Google <ph name="BEGIN_LINK" />menemui atur cara berbahaya<ph name="END_LINK" /> di <ph name="SITE" /> baru-baru ini. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Cadangan ibu bapa</translation>
<translation id="4304224509867189079">Log Masuk</translation>
-<translation id="432290197980158659">Pelayan memberikan sijil yang tidak sepadan dengan jangkaan terbina dalam. Jangkaan ini disertakan untuk tapak web keselamatan tinggi yang tertentu untuk melindungi anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Sekat (lalai)</translation>
<translation id="4325863107915753736">Gagal menemui artikel</translation>
<translation id="4326324639298822553">Semak tarikh tamat tempoh anda dan cuba lagi</translation>
<translation id="4331708818696583467">Tidak Selamat</translation>
<translation id="4356973930735388585">Penyerang pada tapak ini mungkin cuba memasang atur cara berbahaya pada komputer anda yang mencuri atau memadamkan maklumat anda (sebagai contoh, foto, kata laluan, mesej dan kad kredit).</translation>
<translation id="4372948949327679948">Nilai <ph name="VALUE_TYPE" /> yang dijangka.</translation>
+<translation id="4377125064752653719">Anda cuba untuk mencapai <ph name="DOMAIN" />, tetapi sijil yang diberi pelayan telah dibatalkan oleh pengeluarnya. Ini bermakna bahawa bukti kelayakan keselamatan yang diberi pelayan sememangnya tidak harus dipercayai. Anda mungkin berkomunikasi dengan penyerang.</translation>
<translation id="4381091992796011497">Nama Pengguna:</translation>
<translation id="4394049700291259645">Lumpuhkan</translation>
<translation id="4406896451731180161">hasil carian</translation>
+<translation id="4424024547088906515">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh Chrome. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang memintasi sambungan anda.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> tidak menerima sijil log masuk anda atau sijil log masuk mungkin tidak diberikan.</translation>
<translation id="443673843213245140">Penggunaan proksi dilumpuhkan tetapi konfigurasi proksi yang jelas dinyatakan.</translation>
-<translation id="4492190037599258964">Hasil carian untuk '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Ralat pengesahan: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Menghubungi pentadbir sistem</translation>
<translation id="450710068430902550">Berkongsi dengan Pentadbir</translation>
<translation id="4515275063822566619">Kad dan alamat adalah daripada Chrome dan Akaun Google anda (<ph name="ACCOUNT_EMAIL" />). Anda boleh mengurus kad dan alamat ini dalam <ph name="BEGIN_LINK" />Tetapan<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Butiran</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Cuba lumpuhkan sambungan anda.</translation>
<translation id="457875822857220463">Penghantaran</translation>
<translation id="4587425331216688090">Alih keluar alamat daripada Chrome?</translation>
-<translation id="4589078953350245614">Anda cuba mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil yang tidak sah. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Sambungan anda ke <ph name="DOMAIN" /> disulitkan menggunakan suit sifer moden.</translation>
<translation id="4594403342090139922">&amp;Buat asal Pemadaman</translation>
<translation id="4619615317237390068">Tab daripada peranti lain</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya mengandungi ralat. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda.</translation>
+<translation id="4690462567478992370">Berhenti menggunakan sijil tidak sah</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Sambungan anda tergendala</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Jalankan Diagnostik Rangkaian Windows<ph name="END_LINK" /></translation>
@@ -425,21 +476,24 @@
<translation id="4771973620359291008">Ralat tidak diketahui telah berlaku.</translation>
<translation id="4800132727771399293">Semak tarikh tamat tempoh serta CVC anda dan cuba lagi</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana tapak web ini menghantar bukti kelayakan yang dicampuradukkan yang tidak boleh diproses oleh Google Chrome. Ralat rangkaian dan serangan biasanya bersifat sementara, oleh itu halaman ini mungkin akan berfungsi sebentar lagi.</translation>
<translation id="4813512666221746211">Ralat rangkaian</translation>
<translation id="4816492930507672669">Muat halaman</translation>
<translation id="483020001682031208">Tiada halaman Web Fizikal yang hendak dipaparkan</translation>
<translation id="4850886885716139402">Lihat</translation>
<translation id="4854362297993841467">Kaedah penghantaran ini tidak tersedia. Cuba kaedah lain.</translation>
<translation id="4858792381671956233">Anda telah bertanya kepada ibu bapa anda sama ada OK untuk melawat tapak ini</translation>
+<translation id="4863764087567530506">Kandungan ini mungkin menggunakan tipu muslihat supaya anda memasang perisian atau mendedahkan maklumat peribadi. <ph name="BEGIN_LINK" />Tunjukkan juga<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Sejarah carian</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{dan 1 lagi halaman web}other{dan # lagi halaman web}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Halaman ini diterjemahkan dari bahasa yang tidak diketahui ke <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pembayaran</translation>
<translation id="4926049483395192435">Mesti ditentukan.</translation>
<translation id="495170559598752135">Tindakan</translation>
<translation id="4958444002117714549">Kembangkan senarai</translation>
-<translation id="4962322354953122629">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh Chrome. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Dayakan semula amaran</translation>
<translation id="4989809363548539747">Pemalam ini tidak disokong</translation>
<translation id="5002932099480077015">Jika didayakan, Chrome akan menyimpan salinan kad anda pada peranti ini untuk pengisian borang yang lebih cepat.</translation>
<translation id="5018422839182700155">Tidak dapat membuka halaman ini</translation>
@@ -447,14 +501,15 @@
<translation id="5023310440958281426">Semak dasar pentadbir anda</translation>
<translation id="5029568752722684782">Hapuskan salinan</translation>
<translation id="5031870354684148875">Perihal Google Terjemah</translation>
+<translation id="5039804452771397117">Benarkan</translation>
<translation id="5040262127954254034">Privasi</translation>
<translation id="5045550434625856497">Kata laluan tidak sah</translation>
<translation id="5056549851600133418">Artikel untuk anda</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Menyemak alamat proksi<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Tiada kuki}=1{1 tapak menggunakan kuki. }other{# tapak menggunakan kuki. }}</translation>
<translation id="5087286274860437796">Sijil pelayan tidak sah pada masa ini.</translation>
<translation id="5087580092889165836">Tambah kad</translation>
<translation id="5089810972385038852">Negeri</translation>
+<translation id="5094747076828555589">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh Chromium. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
<translation id="5095208057601539847">Wilayah</translation>
<translation id="5115563688576182185">(64-bit)</translation>
<translation id="5141240743006678641">Sulitkan kata laluan yang disegerakkan dengan bukti kelayakan Google anda</translation>
@@ -470,24 +525,24 @@
<translation id="5222812217790122047">E-mel diperlukan</translation>
<translation id="5251803541071282808">Awan</translation>
<translation id="5277279256032773186">Menggunakan Chrome di tempat kerja? Perniagaan boleh mengurus tetapan Chrome untuk pekerja mereka. Ketahui lebih lanjut</translation>
+<translation id="5297526204711817721">Sambungan anda ke tapak ini tidak peribadi. Untuk keluar daripada mod VR pada bila-bila masa, tanggalkan set kepala dan tekan kembali.</translation>
<translation id="5299298092464848405">Ralat semasa menghuraikan dasar</translation>
-<translation id="5300589172476337783">Paparkan</translation>
<translation id="5308689395849655368">Pelaporan nahas dilumpuhkan.</translation>
<translation id="5317780077021120954">Simpan</translation>
<translation id="5327248766486351172">Nama</translation>
-<translation id="5337705430875057403">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin menipu anda supaya melakukan sesuatu yang berbahaya seperti memasang perisian atau mendedahkan maklumat peribadi anda (contohnya, kata laluan, nombor telefon atau kad kredit).</translation>
-<translation id="5359637492792381994">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya tidak sah pada masa ini. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana sijil tapak ini telah ditarik balik. Ralat dan serangan rangkaian biasanya bersifat sementara. Oleh sebab itu, halaman ini mungkin akan berfungsi semula kemudian.</translation>
<translation id="536296301121032821">Gagal menyimpan tetapan dasar</translation>
<translation id="5386426401304769735">Rantaian sijil untuk tapak ini mengandungi sijil yang ditandatangani menggunakan SHA-1.</translation>
<translation id="5402410679244714488">Tamat: <ph name="EXPIRATION_DATE_ABBR" />, terakhir digunakan lebih setahun lalu</translation>
+<translation id="540969355065856584">Pelayan ini tidak dapat membuktikan bahawa pelayan adalah <ph name="DOMAIN" />; sijil keselamatan pelayan tidak sah pada masa ini. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang memintas sambungan anda.</translation>
<translation id="5421136146218899937">Kosongkan data semakan imbas...</translation>
<translation id="5430298929874300616">Alih keluar penanda halaman</translation>
<translation id="5431657950005405462">Fail anda tidak ditemui</translation>
-<translation id="5435775191620395718">Menunjukkan sejarah daripada peranti ini. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Ralat pengesahan skema di "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Halaman <ph name="HOST_NAME" /> ini tidak ditemui</translation>
<translation id="5455374756549232013">Cap waktu dasar tidak elok</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> daripada <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Tidak sah</translation>
<translation id="5470861586879999274">&amp;Buat semula edit</translation>
<translation id="54817484435770891">Tambahkan alamat yang sah</translation>
<translation id="5492298309214877701">Tapak ini yang berada di intranet syarikat, organisasi atau sekolah mempunyai URL yang sama dengan tapak web luar.
@@ -504,6 +559,8 @@
<translation id="5571083550517324815">Tidak boleh mengambil dari alamat ini. Pilih alamat lain.</translation>
<translation id="5572851009514199876">Sila mulakan dan log masuk ke Chrome supaya Chrome boleh menyemak sama ada anda dibenarkan mengakses tapak ini.</translation>
<translation id="5580958916614886209">Semak bulan tamat tempoh anda dan cuba lagi</translation>
+<translation id="5586446728396275693">Tiada alamat yang disimpan</translation>
+<translation id="5595485650161345191">Edit alamat</translation>
<translation id="560412284261940334">Pengurusan tidak disokong</translation>
<translation id="5610142619324316209">Menyemak sambungan</translation>
<translation id="5610807607761827392">Anda boleh mengurus kad dan alamat dalam <ph name="BEGIN_LINK" />Tetapan<ph name="END_LINK" />.</translation>
@@ -511,15 +568,18 @@
<translation id="5622887735448669177">Adakah anda ingin meninggalkan tapak ini?</translation>
<translation id="5629630648637658800">Gagal memuatkan tetapan dasar</translation>
<translation id="5631439013527180824">Token pengurusan peranti tidak sah</translation>
+<translation id="5633066919399395251">Penyerang yang sedang berada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin cuba memasang atur cara berbahaya pada komputer anda. Atur cara tersebut boleh mencuri atau memadamkan maklumat anda (contohnya, foto, kata laluan, mesej dan kad kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Lokasi</translation>
+<translation id="5659593005791499971">E-mel</translation>
<translation id="5669703222995421982">Dapatkan kandungan yang diperibadikan</translation>
<translation id="5675650730144413517">Halaman ini tidak berfungsi</translation>
-<translation id="5677928146339483299">Disekat</translation>
-<translation id="5694783966845939798">Anda cuba mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil yang ditandatangani menggunakan algoritma tandatangan yang lemah (seperti SHA-1). Ini bermakna bukti kelayakan keselamatan yang diberikan oleh pelayan mungkin dipalsukan dan pelayan tersebut mungkin bukan pelayan yang anda jangkakan (anda mungkin berkomunikasi dengan penyerang). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Identiti tapak web ini belum disahkan.</translation>
+<translation id="5713016350996637505">Kandungan mengelirukan disekat</translation>
<translation id="5720705177508910913">Pengguna semasa</translation>
<translation id="5732392974455271431">Ibu bapa anda boleh menyahsekatnya untuk anda</translation>
<translation id="5763042198335101085">Masukkan alamat e-mel yang sah</translation>
<translation id="5765072501007116331">Pilih alamat untuk melihat kaedah dan syarat penghantaran</translation>
+<translation id="5778550464785688721">Kawalan penuh peranti MIDI</translation>
<translation id="5784606427469807560">Terdapat masalah mengesahkan kad anda. Semak sambungan Internet anda dan cuba lagi.</translation>
<translation id="5785756445106461925">Selain itu, halaman ini mengandungi sumber lain yang tidak selamat. Sumber ini boleh dilihat oleh orang lain semasa dalam transit dan boleh diubah oleh penyerang untuk menukar penampilan halaman.</translation>
<translation id="5786044859038896871">Adakah anda ingin mengisi maklumat kad anda?</translation>
@@ -528,14 +588,14 @@
<translation id="5813119285467412249">&amp;Buat Semula Tambahkan</translation>
<translation id="5814352347845180253">Anda mungkin kehilangan akses kepada kandungan premium daripada <ph name="SITE" /> dan sesetengah tapak web lain.</translation>
<translation id="5838278095973806738">Anda tidak seharusnya memasukkan sebarang maklumat sensitif pada tapak ini (contohnya, kata laluan atau maklumat kad kredit) kerana maklumat ini boleh dicuri oleh penyerang.</translation>
-<translation id="5843436854350372569">Anda cuba mencapai <ph name="DOMAIN" />, tetapi pelayan memberi sijil yang mengandungi kunci yang lemah, Penyerang mungkin telah merosakkan kunci peribadi dan pelayan tersebut mungkin bukan pelayan yang anda jangkakan (anda mungkin berkomunikasi dengan penyerang). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Tapak ini tidak dapat dicapai</translation>
<translation id="5869522115854928033">Kata laluan disimpan</translation>
<translation id="5872918882028971132">Cadangan Ibu Bapa</translation>
<translation id="5901630391730855834">Kuning</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (disegerakkan)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 sedang digunakan}other{# sedang digunakan}}</translation>
<translation id="5926846154125914413">Anda mungkin kehilangan akses kepada kandungan premium daripada sesetengah tapak web.</translation>
<translation id="5959728338436674663">Hantar secara automatik beberapa <ph name="BEGIN_WHITEPAPER_LINK" />maklumat sistem dan kandungan halaman<ph name="END_WHITEPAPER_LINK" /> kepada Google untuk membantu anda mengesan apl dan tapak yang berbahaya. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Minggu</translation>
<translation id="5967867314010545767">Buang daripada sejarah</translation>
<translation id="5975083100439434680">Zum keluar</translation>
<translation id="598637245381783098">Tidak dapat membuka apl pembayaran</translation>
@@ -544,21 +604,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Halaman 1}other{Halaman #}}</translation>
<translation id="6017514345406065928">Hijau</translation>
+<translation id="6017850046339264347">Penyerang di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> boleh memasang apl yang mengelirukan yang menyamar menjadi sesuatu yang lain atau mengumpul data yang boleh digunakan untuk menjejak anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (disegerakkan)</translation>
<translation id="6027201098523975773">Masukkan nama</translation>
<translation id="6040143037577758943">Tutup</translation>
<translation id="6042308850641462728">Lagi</translation>
+<translation id="6047233362582046994">Jika anda memahami risiko terhadap keselamatan anda, anda boleh <ph name="BEGIN_LINK" />melawat tapak ini<ph name="END_LINK" /> sebelum program yang berbahaya ini dialih keluar.</translation>
+<translation id="6051221802930200923">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana tapak web ini menggunakan penyematan sijil. Ralat dan serangan rangkaian biasanya bersifat sementara. Oleh sebab itu, halaman ini mungkin akan berfungsi semula kemudian.</translation>
<translation id="6060685159320643512">Berhati-hati, percubaan ini mungkin memudaratkan</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{tiada}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Anda telah mengakses kandungan menggunakan perakuan yang disediakan oleh pentadbir. Data yang anda berikan kepada <ph name="DOMAIN" /> boleh dipintas oleh pentadbir anda.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Tiada}=1{1 kata laluan (disegerakkan)}other{# kata laluan (disegerakkan)}}</translation>
<translation id="6146055958333702838">Periksa mana-mana kabel dan but semula mana-mana penghala, modem atau peranti
rangkaian lain yang mungkin anda gunakan.</translation>
<translation id="614940544461990577">Cuba:</translation>
<translation id="6151417162996330722">Sijil pelayan mempunyai tempoh sah yang terlalu panjang.</translation>
<translation id="6157877588268064908">Pilih alamat untuk melihat kaedah dan syarat penghantaran</translation>
+<translation id="6158003235852588289">Penyemakan Imbas Selamat Google mengesan pancingan data di <ph name="SITE" /> baru-baru ini. Tapak pancingan data menyamar sebagai tapak web lain untuk menipu anda.</translation>
<translation id="6165508094623778733">Ketahui lebih lanjut</translation>
+<translation id="6169916984152623906">Kini, anda boleh menyemak imbas secara sulit dan orang lain yang menggunakan peranti ini tidak akan melihat aktiviti anda. Namun begitu, muat turun dan penanda halaman akan disimpan.</translation>
<translation id="6177128806592000436">Sambungan anda ke tapak ini tidak selamat</translation>
<translation id="6184817833369986695">(kohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Semak sambungan Internet anda</translation>
<translation id="6218753634732582820">Alih keluar alamat daripada Chromium?</translation>
+<translation id="6221345481584921695">Penyemakan Selamat Google <ph name="BEGIN_LINK" />telah mengesan perisian hasad<ph name="END_LINK" /> pada <ph name="SITE" /> baru-baru ini. Tapak web yang lazimnya selamat kadangkala dijangkiti oleh perisian hasad. Kandungan berniat jahat datang dari <ph name="SUBRESOURCE_HOST" />, pengedar perisian hasad yang diketahui.</translation>
<translation id="6251924700383757765">Dasar privasi</translation>
<translation id="6254436959401408446">Memori tidak mencukupi untuk membuka halaman ini</translation>
<translation id="625755898061068298">Anda telah memilih untuk melumpuhkan amaran keselamatan bagi tapak ini.</translation>
@@ -584,15 +652,14 @@
<translation id="6404511346730675251">Edit penanda halaman</translation>
<translation id="6410264514553301377">Masukkan tarikh tamat tempoh dan CVC untuk <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Anda telah bertanya kepada ibu bapa anda sama ada OK untuk melawat tapak ini</translation>
-<translation id="6416403317709441254">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana tapak web ini menghantar bukti kelayakan yang dicampuradukkan sehingga tidak dapat diproses oleh Chromium. Ralat rangkaian dan serangan biasanya bersifat sementara, oleh itu halaman ini mungkin akan berfungsi sebentar lagi. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Tidak dapat memeriksa sama ada sijil telah dibatalkan.</translation>
<translation id="6433490469411711332">Edit maklumat hubungan</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> enggan menyambung.</translation>
<translation id="6446608382365791566">Tambahkan maklumat lanjut</translation>
+<translation id="6447842834002726250">Kuki</translation>
<translation id="6451458296329894277">Sahkan Penyerahan Semula Borang</translation>
<translation id="6456339708790392414">Pembayaran Anda</translation>
<translation id="6458467102616083041">Diabaikan kerana carian lalai dilumpuhkan oleh dasar.</translation>
-<translation id="6462969404041126431">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya telah dibatalkan. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Dasar peranti</translation>
<translation id="6477321094435799029">Chrome mengesan kod luar biasa pada halaman ini dan menyekatnya untuk melindungi maklumat peribadi anda (contohnya, kata laluan, nombor telefon dan maklumat kad kredit).</translation>
<translation id="6489534406876378309">Mulakan muat naik ranap sistem</translation>
@@ -604,20 +671,19 @@
<translation id="6556915248009097796">Tamat: <ph name="EXPIRATION_DATE_ABBR" />, kali terakhir digunakan <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Pengurus anda belum meluluskannya</translation>
<translation id="6569060085658103619">Anda sedang melihat halaman sambungan</translation>
-<translation id="6593753688552673085">kurang daripada <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Kandungan ini mungkin cuba memasang perisian berbahaya pada peranti anda yang akan mencuri atau memadamkan maklumat anda. <ph name="BEGIN_LINK" />Tunjukkan juga<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Pilihan penyulitan</translation>
<translation id="662080504995468778">Kekal di sini</translation>
<translation id="6626291197371920147">Tambahkan nombor kad yang sah</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Carian</translation>
+<translation id="6630809736994426279">Penyerang yang sedang berada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin cuba memasang atur cara berbahaya pada komputer Mac anda. Atur cara tersebut boleh mencuri atau memadamkan maklumat anda (contohnya, foto, kata laluan, mesej dan kad kredit). <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Dasar ini telah dikecam.</translation>
-<translation id="6652240803263749613">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh sistem pengendalian komputer anda. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Alih keluar cadangan borang daripada Chromium?</translation>
<translation id="6685834062052613830">Log keluar dan selesaikan persediaan</translation>
<translation id="6710213216561001401">Sebelumnya</translation>
<translation id="6710594484020273272">&lt;Taip istilah carian&gt;</translation>
<translation id="6711464428925977395">Ada sesuatu yang tidak kena dengan pelayan proksi atau alamat tidak betul.</translation>
<translation id="6727102863431372879">Tetapkan</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{tiada}=1{1 item}other{# item}}</translation>
<translation id="674375294223700098">Ralat sijil pelayan tidak diketahui.</translation>
<translation id="6753269504797312559">Nilai dasar</translation>
<translation id="6757797048963528358">Peranti anda tidak aktif.</translation>
@@ -625,6 +691,8 @@
<translation id="6810899417690483278">ID Penyesuaian</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Gagal memuatkan data rantau</translation>
+<translation id="6825578344716086703">Anda cuba untuk mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil yang ditandatangani menggunakan algoritma tandatangan yang lemah (seperti SHA-1). Ini bermakna bahawa bukti kelayakan keselamatan yang diberi pelayan mungkin dipalsukan dan pelayan tersebut bukan seperti yang anda jangkakan (anda mungkin berkomunikasi dengan penyerang).</translation>
+<translation id="6830728435402077660">Tidak selamat</translation>
<translation id="6831043979455480757">Terjemah</translation>
<translation id="6839929833149231406">Kawasan</translation>
<translation id="6874604403660855544">&amp;Buat semula tambahkan</translation>
@@ -632,6 +700,7 @@
<translation id="6895330447102777224">Kad anda telah disahkan</translation>
<translation id="6897140037006041989">Ejen Pengguna</translation>
<translation id="6915804003454593391">Pengguna:</translation>
+<translation id="6945221475159498467">Pilih</translation>
<translation id="6948701128805548767">Pilih alamat untuk melihat kaedah dan syarat pengambilan</translation>
<translation id="6957887021205513506">Sijil pelayan rupanya adalah pemalsuan.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -640,15 +709,16 @@
<translation id="6973656660372572881">Pelayan proksi tetap dan juga URL skrip .pac tidak ditetapkan.</translation>
<translation id="6989763994942163495">Paparkan tetapan lanjutan...</translation>
<translation id="7000990526846637657">Tiada masukan sejarah ditemui</translation>
-<translation id="7009986207543992532">Anda cuba mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil yang tempoh sahnya terlalu panjang untuk dipercayai. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Akaun Google anda mungkin mempunyai sejarah penyemakan imbas dalam bentuk lain di <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Kata laluan</translation>
+<translation id="7050187094878475250">Anda cuba untuk mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil yang tempoh sahnya terlalu panjang untuk boleh dipercayai.</translation>
+<translation id="7053983685419859001">Sekat</translation>
<translation id="7064851114919012435">Maklumat hubungan</translation>
<translation id="7079718277001814089">Tapak ini mengandungi perisian hasad</translation>
<translation id="7087282848513945231">Daerah</translation>
-<translation id="7088615885725309056">Lebih lama</translation>
<translation id="7090678807593890770">Cari <ph name="LINK" /> di Google</translation>
+<translation id="7108819624672055576">Dibenarkan oleh sambungan</translation>
<translation id="7119414471315195487">Tutup tab atau atur cara lain</translation>
<translation id="7129409597930077180">Tidak dapat menghantar ke alamat ini. Pilih alamat lain.</translation>
<translation id="7138472120740807366">Kaedah penghantaran</translation>
@@ -666,22 +736,18 @@
<translation id="7220786058474068424">Memproses</translation>
<translation id="724691107663265825">Tapak di hadapan mengandungi perisian hasad</translation>
<translation id="724975217298816891">Masukkan tarikh tamat tempoh dan CVC untuk <ph name="CREDIT_CARD" /> bagi mengemas kini butiran kad anda. Setelah anda mengesahkan, butiran kad anda akan dikongsi dengan tapak ini.</translation>
-<translation id="725866823122871198">Sambungan peribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak boleh diwujudkan kerana tarikh dan masa komputer anda (<ph name="DATE_AND_TIME" />) tidak betul.</translation>
+<translation id="7260504762447901703">Batalkan akses</translation>
<translation id="7275334191706090484">Penanda Halaman Terurus</translation>
<translation id="7298195798382681320">Disyorkan</translation>
<translation id="7309308571273880165">Laporan ranap sistem dirakam pada <ph name="CRASH_TIME" /> (muat naik diminta oleh pengguna, belum dimuat naik lagi)</translation>
<translation id="7334320624316649418">&amp;Buat semula susun semula</translation>
<translation id="733923710415886693">Sijil pelayan tidak didedahkan melalui Ketelusan Sijil.</translation>
-<translation id="7351800657706554155">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana sijilnya telah dibatalkan. Ralat rangkaian dan serangan biasanya bersifat sementara, maka halaman ini mungkin akan berfungsi sebentar lagi. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Baris Perintah</translation>
<translation id="7372973238305370288">hasil carian</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Tidak</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Sahkan Kad</translation>
-<translation id="7394102162464064926">Anda pasti mahu memadamkan halaman ini daripada sejarah anda?
-
-Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa akan datang.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Laluan Profil</translation>
<translation id="7424977062513257142">Halaman terbenam pada halaman web ini menyatakan:</translation>
@@ -689,6 +755,7 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="7444046173054089907">Tapak ini disekat</translation>
<translation id="7445762425076701745">Identiti pelayan yang disambungkan kepada anda tidak dapat disahkan sepenuhnya. Anda disambungkan ke pelayan menggunakan nama yang sah dalam rangkaian anda sahaja, apabila pihak berkuasa sijil luaran tiada cara untuk mengesahkan pemilikan. Oleh kerana beberapa pihak berkuasa sijil juga akan terus mengeluarkan sijil untuk nama ini, tiada cara untuk memastikan anda disambungkan ke tapak web yang diingini dan bukannya penyerang.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /> tentang masalah ini.</translation>
+<translation id="7455133967321480974">Gunakan lalai global (Sekat)</translation>
<translation id="7460163899615895653">Tab terbaharu anda daripada peranti lain dipaparkan di sini</translation>
<translation id="7469372306589899959">Mengesahkan kad</translation>
<translation id="7481312909269577407">Majukan</translation>
@@ -696,36 +763,43 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="7508255263130623398">Id peranti yang dikembalikan kosong atau tidak sepadan dengan id peranti semasa</translation>
<translation id="7514365320538308">Muat Turun</translation>
<translation id="7518003948725431193">Tiada halaman web dijumpai untuk alamat web: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Nilai</translation>
<translation id="7537536606612762813">Wajib</translation>
+<translation id="7542403920425041731">Setelah anda mengesahkan, butiran kad anda akan dikongsi dengan tapak ini.</translation>
<translation id="7542995811387359312">Pengisian kad kredit automatik dilumpuhkan kerana borang ini tidak menggunakan sambungan selamat.</translation>
<translation id="7543525346216957623">Tanya ibu bapa anda</translation>
<translation id="7549584377607005141">Halaman web ini memerlukan data yang anda masukkan sebelum ini agar dapat dipaparkan dengan betul. Anda boleh menghantar data ini semula, tetapi dengan berbuat demikian anda akan mengulangi sebarang tindakan terdahulu yang telah dilakukan oleh halaman ini.</translation>
<translation id="7552846755917812628">Cuba petua berikut:</translation>
<translation id="7554791636758816595">Tab Baharu</translation>
+<translation id="7567204685887185387">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya mungkin telah dikeluarkan melalui penipuan. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> lagi}other{<ph name="CONTACT_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> lagi}}</translation>
<translation id="7568593326407688803">Halaman ini adalah dalam<ph name="ORIGINAL_LANGUAGE" />Adakah anda ingin menterjemahkannya?</translation>
<translation id="7569952961197462199">Alih keluar kad kredit daripada Chrome?</translation>
<translation id="7569983096843329377">Hitam</translation>
<translation id="7578104083680115302">Bayar dengan cepat di tapak dan apl merentas peranti menggunakan kad yang telah disimpan dengan Google.</translation>
<translation id="7588950540487816470">Web Fizikal</translation>
<translation id="7592362899630581445">Sijil pelayan melanggar kekangan nama.</translation>
+<translation id="7598391785903975535">Kurang daripada <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> tidak dapat mengendalikan permintaan ini pada masa ini.</translation>
<translation id="7600965453749440009">Jangan sekali-kali terjemahkan <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Nilai berada di luar julat <ph name="VALUE" /></translation>
<translation id="7613889955535752492">Tamat: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Anda sudah mempunyai data yang disulitkan menggunakan versi kata laluan Akaun Google anda yang berbeza. Sila masukkannya di bawah.</translation>
-<translation id="7634554953375732414">Sambungan anda ke tapak ini tidak berciri peribadi.</translation>
<translation id="7637571805876720304">Alih keluar kad kredit daripada Chromium?</translation>
<translation id="765676359832457558">Sembunyikan tetapan lanjutan...</translation>
<translation id="7658239707568436148">Batal</translation>
+<translation id="7662298039739062396">Tetapan dikawal oleh sambungan</translation>
<translation id="7667346355482952095">Token dasar yang dikembalikan kosong atau tidak sepadan dengan token semasa</translation>
<translation id="7668654391829183341">Peranti tidak diketahui</translation>
<translation id="7669271284792375604">Penyerang pada tapak ini mungkin cuba menipu dengan meminta anda memasang atur cara yang membahayakan pengalaman penyemakan imbas anda (contohnya, dengan menukar halaman utama anda atau menunjukkan iklan tambahan pada laman yang anda lawati).</translation>
<translation id="7674629440242451245">Berminat dengan ciri Chrome baharu yang hebat? Cuba saluran pembangun kami di chrome.com/dev.</translation>
<translation id="7682287625158474539">Penghantaran</translation>
+<translation id="7701040980221191251">Tiada</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Teruskan ke <ph name="SITE" /> (tidak selamat)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Sijil</translation>
+<translation id="7716147886133743102">Disekat oleh pentadbir anda</translation>
<translation id="7716424297397655342">Tapak ini tidak dapat dimuatkan daripada cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Tidak Diurus</translation>
<translation id="7755287808199759310">Ibu bapa anda boleh menyahsekatnya untuk anda</translation>
<translation id="7758069387465995638">Tembok api atau perisian antivirus mungkin telah menyekat sambungan.</translation>
@@ -752,15 +826,15 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Penanda halaman mudah alih</translation>
<translation id="7961015016161918242">Tidak sama sekali</translation>
-<translation id="7962083544045318153">ID Ranap Sistem <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Sentiasa terjemahkan <ph name="ORIGINAL_LANGUAGE" /> ke <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Tidak Ditentukan</translation>
<translation id="800218591365569300">Cuba tutup tab atau atur cara lain untuk mengosongkan memori.</translation>
<translation id="8012647001091218357">Kami tidak dapat menghubungi ibu bapa anda pada masa ini. Sila cuba lagi.</translation>
<translation id="8025119109950072390">Penyerang pada tapak ini mungkin menipu anda supaya melakukan sesuatu yang berbahaya seperti memasang perisian atau mendedahkan maklumat peribadi anda (contohnya, kata laluan, nombor telefon atau maklumat kad kredit).</translation>
-<translation id="803030522067524905">Penyemakan Imbas Selamat Google mengesan pancingan data di <ph name="SITE" /> baru-baru ini. Tapak pancingan data menyamar menjadi tapak web lain untuk menipu anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Halaman ini dalam <ph name="SOURCE_LANGUAGE" />. Terjemahkannya kepada <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Tanya (lalai)</translation>
<translation id="8041089156583427627">Hantar Maklum Balas</translation>
+<translation id="8041940743680923270">Gunakan lalai global (Tanya)</translation>
<translation id="8088680233425245692">Gagal melihat artikel.</translation>
<translation id="8089520772729574115">kurang daripada 1 MB</translation>
<translation id="8091372947890762290">Pengaktifan belum selesai pada pelayan</translation>
@@ -769,13 +843,14 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />Alamat DNS<ph name="END_ABBR" /> pelayan <ph name="HOST_NAME" /> tidak ditemui.</translation>
<translation id="8149426793427495338">Komputer anda dalam mod tidur.</translation>
<translation id="8150722005171944719">Fail di <ph name="URL" /> tidak boleh dibaca. Fail mungkin telah dialih keluar, dipindahkan atau kebenaran fail mungkin menghalang akses.</translation>
+<translation id="8184538546369750125">Gunakan lalai global (Benarkan)</translation>
+<translation id="8191494405820426728">ID Ranap Setempat <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Buat Asal Pindahkan</translation>
<translation id="8201077131113104583">URL kemas kini tidak sah untuk sambungan dengan ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Ringkasan pesanan</translation>
<translation id="8218327578424803826">Lokasi yang Ditentukan:</translation>
<translation id="8225771182978767009">Orang yang menyediakan komputer ini telah memilih untuk menyekat tapak ini.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Penyerang yang ada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pada masa ini mungkin cuba memasang program berbahaya pada komputer anda yang boleh mencuri atau memadamkan maklumat anda (contohnya foto, kata laluan, mesej dan kad kredit).</translation>
<translation id="8241707690549784388">Halaman yang anda cari untuk maklumat terpakai yang anda masukkan. Kembali ke halaman tersebut mungkin menyebabkan mana-mana tindakan yang anda ambil akan diulang. Adakah anda mahu teruskan?</translation>
<translation id="8249320324621329438">Diambil kali terakhir:</translation>
<translation id="8253091569723639551">Alamat pengebilan diperlukan</translation>
@@ -783,6 +858,7 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="8289355894181816810">Hubungi pentadbir rangkaian anda jika anda tidak pasti apa yang dimaksudkan ini.</translation>
<translation id="8293206222192510085">Tambah Penanda Halaman</translation>
<translation id="8294431847097064396">Sumber</translation>
+<translation id="8306404619377842860">Sambungan peribadi kepada <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak dapat diwujudkan kerana tarikh dan masa peranti anda (<ph name="DATE_AND_TIME" />) tidak betul. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Gagal terjemahan kerana masalah dengan sambungan rangkaian.</translation>
<translation id="8332188693563227489">Akses ke <ph name="HOST_NAME" /> dinafikan</translation>
<translation id="834457929814110454">Jika anda memahami risiko terhadap keselamatan anda, anda boleh <ph name="BEGIN_LINK" />lawati tapak ini<ph name="END_LINK" /> sebelum atur cara berbahaya dialih keluar.</translation>
@@ -803,11 +879,9 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="8483780878231876732">Log masuk ke Chrome untuk menggunakan kad daripada Akaun Google anda</translation>
<translation id="8488350697529856933">Diguna pakai untuk</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> mengambil masa terlalu lama untuk bertindak balas.</translation>
-<translation id="852346902619691059">Pelayan ini tidak dapat membuktikan bahawa itu <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh sistem pengendalian peranti anda. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintas sambungan anda. <ph name="BEGIN_LEARN_MORE_LINK" />Ketahui lebih lanjut<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Tahun Tamat Tempoh</translation>
<translation id="8543181531796978784">Anda boleh <ph name="BEGIN_ERROR_LINK" />laporkan masalah pengesanan<ph name="END_ERROR_LINK" /> atau jika anda memahami risikonya kepada keselamatan anda, <ph name="BEGIN_LINK" />lawati tapak yang tidak selamat ini<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Gagal terjemahan kerana bahasa halaman tidak dapat ditentukan.</translation>
-<translation id="8559762987265718583">Sambungan peribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak boleh diwujudkan kerana tarikh dan masa peranti anda (<ph name="DATE_AND_TIME" />) tidak betul.</translation>
<translation id="8571890674111243710">Menterjemah halaman ke <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Tambah no. tel.
</translation>
@@ -822,6 +896,7 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="8738058698779197622">Untuk mewujudkan sambungan yang selamat, jam anda perlu ditetapkan dengan betul. Ini kerana sijil yang digunakan oleh tapak web untuk mengenal pastinya hanya sah untuk tempoh masa yang tertentu. Memandangkan jam peranti anda tidak betul, Chromium tidak boleh mengesahkan sijil-sijil ini.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;Alamat DNS&lt;/abbr&gt; <ph name="HOST_NAME" /> tidak ditemui. Masalah sedang didiagnosis.</translation>
<translation id="8759274551635299824">Kad ini telah tamat tempoh</translation>
+<translation id="8761567432415473239">Penyemakan Imbas Selamat Google baru-baru ini <ph name="BEGIN_LINK" />menemui atur cara berbahaya<ph name="END_LINK" /> pada <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Buat semula pemadaman</translation>
<translation id="8800988563907321413">Cadangan berdekatan anda dipaparkan di sini</translation>
<translation id="8820817407110198400">Penanda buku</translation>
@@ -834,29 +909,30 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="8870413625673593573">Ditutup Baru-baru Ini</translation>
<translation id="8874824191258364635">Masukkan nombor kad yang sah</translation>
<translation id="8876793034577346603">Konfigurasi rangkaian gagal dihuraikan.</translation>
-<translation id="8877192140621905067">Setelah anda mengesahkan, butiran kad anda akan dikongsi dengan tapak ini</translation>
<translation id="8889402386540077796">Rona</translation>
<translation id="8891727572606052622">Mod proksi tidak sah.</translation>
<translation id="889901481107108152">Maaf, eksperimen ini tidak tersedia pada platform anda.</translation>
<translation id="8903921497873541725">Zum masuk</translation>
<translation id="8931333241327730545">Adakah anda mahu menyimpan kad ini ke Akaun Google anda?</translation>
<translation id="8932102934695377596">Jam anda di belakang</translation>
-<translation id="8954894007019320973">(Samb.)</translation>
<translation id="8971063699422889582">Sijil pelayan telah tamat tempoh.</translation>
<translation id="8986494364107987395">Hantar statistik penggunaan dan laporan nahas kepada Google secara automatik</translation>
-<translation id="8987927404178983737">Bulan</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Laman web yang akan dilayari mengandungi atur cara berbahaya</translation>
+<translation id="8997023839087525404">Pelayan memberikan sijil yang tidak didedahkan kepada umum menggunakan dasar Ketelusan Sijil. Ini merupakan keperluan bagi sesetengah sijil untuk memastikan sijil itu boleh dipercayai dan untuk melindungi pengguna daripada penyerang.</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> proksi memerlukan nama pengguna dan kata laluan.</translation>
+<translation id="9005998258318286617">Gagal memuatkan dokumen PDF.</translation>
<translation id="901974403500617787">Bendera yang diguna pakai di seluruh sistem hanya boleh ditetapkan oleh pemilik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Alamat pengebilan kad diperlukan</translation>
<translation id="9020542370529661692">Halaman ini telah diterjemahkan kepada <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Ralat keselamatan</translation>
<translation id="9038649477754266430">Gunakan perkhidmatan ramalan untuk memuatkan halaman lebih cepat</translation>
<translation id="9039213469156557790">Selain itu, halaman ini mengandungi sumber lain yang tidak selamat. Sumber ini boleh dilihat oleh orang lain semasa dalam transit dan boleh diubah oleh penyerang untuk menukar kelakuan halaman.</translation>
-<translation id="9040185888511745258">Penyerang pada <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin mencuba untuk menipu anda untuk memasang atur cara yang membahayakan pengalaman penyemak imbas anda (contohnya, dengan menukar halaman utama anda atau menunjukkan iklan tambahan pada laman yang anda lawati).</translation>
+<translation id="9049981332609050619">Anda cuba untuk mencapai <ph name="DOMAIN" />, tetapi pelayan memberikan sijil tidak sah.</translation>
<translation id="9050666287014529139">Frasa laluan</translation>
<translation id="9065203028668620118">Edit</translation>
<translation id="9068849894565669697">Pilih warna</translation>
+<translation id="9069693763241529744">Disekat oleh sambungan</translation>
<translation id="9076283476770535406">Tapak mungkin mengandungi kandungan dewasa</translation>
<translation id="9078964945751709336">Maklumat lanjut diperlukan</translation>
<translation id="9103872766612412690"><ph name="SITE" /> biasanya menggunakan penyulitan untuk melindungi maklumat anda. Apabila Chromium cuba menyambung ke <ph name="SITE" /> pada kali ini, tapak web tersebut mengembalikan bukti kelayakan yang luar biasa dan salah. Hal ini boleh berlaku apabila penyerang sedang cuba menyamar sebagai <ph name="SITE" /> atau skrin log masuk Wi-Fi telah memutuskan sambungan. Maklumat anda masih selamat kerana Chromium menghentikan sambungan sebelum sebarang pertukaran data berlaku.</translation>
@@ -865,16 +941,21 @@ Psst! <ph name="SHORTCUT_KEY" /> mod Inkognito mungkin akan berguna pada masa ak
<translation id="9148507642005240123">&amp;Buat asal edit</translation>
<translation id="9154194610265714752">Dikemas kini</translation>
<translation id="9157595877708044936">Menyediakan...</translation>
+<translation id="9169664750068251925">Sentiasa sekat di tapak ini</translation>
<translation id="9170848237812810038">&amp;Buat asal</translation>
<translation id="917450738466192189">Sijil pelayan tidak sah.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> lagi}other{<ph name="SHIPPING_OPTION_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> lagi}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> menggunakan protokol yang tidak disokong.</translation>
<translation id="9205078245616868884">Data anda disulitkan dengan ungkapan laluan segerak anda. Masukkannya untuk memulakan penyegerakan.</translation>
<translation id="9207861905230894330">Gagal menambahkan artikel.</translation>
+<translation id="9219103736887031265">Imej</translation>
<translation id="933612690413056017">Tiada sambungan Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">KOSONGKAN BORANG</translation>
<translation id="939736085109172342">Folder baharu</translation>
<translation id="941721044073577244">Nampaknya anda tiada kebenaran untuk melawat halaman ini</translation>
<translation id="969892804517981540">Binaan Rasmi</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Tiada}=1{1 item}other{# item}}</translation>
<translation id="988159990683914416">Binaan Pemaju</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_nl.xtb b/chromium/components/strings/components_strings_nl.xtb
index 72e888f266c..40622ea3046 100644
--- a/chromium/components/strings/components_strings_nl.xtb
+++ b/chromium/components/strings/components_strings_nl.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Rechtsom draaien</translation>
<translation id="1038842779957582377">onbekende naam</translation>
<translation id="1050038467049342496">Andere apps sluiten</translation>
-<translation id="1053591932240354961">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat de website gecodeerde inloggegevens heeft verzonden die niet door Google Chrome kunnen worden verwerkt. Aangezien netwerkfouten en aanvallen meestal van tijdelijke aard zijn, zal deze pagina later waarschijnlijk weer correct werken. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Toevoegen ongedaan maken</translation>
<translation id="10614374240317010">Nooit opgeslagen</translation>
<translation id="106701514854093668">Desktopbladwijzers</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cachegeheugen van beleid is OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> meldt het volgende:</translation>
<translation id="1132774398110320017">Instellingen voor automatisch aanvullen in Chrome...</translation>
+<translation id="1150979032973867961">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door het besturingssysteem van je computer. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
+<translation id="1151972924205500581">Wachtwoord vereist</translation>
<translation id="1152921474424827756">Een <ph name="BEGIN_LINK" />gecacht exemplaar<ph name="END_LINK" /> van <ph name="URL" /> openen</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> heeft de verbinding onverwacht verbroken.</translation>
<translation id="1161325031994447685">Maak opnieuw verbinding met wifi</translation>
+<translation id="1165039591588034296">Fout</translation>
<translation id="1175364870820465910">&amp;Afdrukken...</translation>
<translation id="1181037720776840403">Verwijderen</translation>
<translation id="1184214524891303587">Informatie over mogelijke beveiligingsincidenten <ph name="BEGIN_WHITEPAPER_LINK" />automatisch melden<ph name="END_WHITEPAPER_LINK" /> aan Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Meer van deze site</translation>
<translation id="1206967143813997005">Onjuiste eerste handtekening</translation>
<translation id="1209206284964581585">Voorlopig verbergen</translation>
+<translation id="121201262018556460">Je probeert <ph name="DOMAIN" /> te bereiken, maar de server heeft een certificaat geretourneerd met een zwakke sleutel. Een hacker kan de persoonlijke sleutel hebben aangepast en het is mogelijk dat de server zelf een imitatie is (wellicht een server die je schade probeert te berokkenen).</translation>
<translation id="1219129156119358924">Systeembeveiliging</translation>
<translation id="1227224963052638717">Onbekend beleid.</translation>
<translation id="1227633850867390598">Waarde verbergen</translation>
<translation id="1228893227497259893">Onjuiste entiteits-ID</translation>
<translation id="1232569758102978740">Naamloos</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (gesynchroniseerd)</translation>
<translation id="1263231323834454256">Leeslijst</translation>
<translation id="1264126396475825575">Crashrapport vastgelegd op <ph name="CRASH_TIME" /> (nog niet geüpload of genegeerd)</translation>
+<translation id="1281526147609854549">Uitgegeven door <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Gevaarlijke content geblokkeerd</translation>
<translation id="1285320974508926690">Deze site nooit vertalen</translation>
<translation id="129553762522093515">Recent gesloten</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Probeer je cookies te wissen<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Je activiteit is mogelijk <ph name="BEGIN_EMPHASIS" />nog wel zichtbaar<ph name="END_EMPHASIS" /> voor:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Websites die je bezoekt
+ <ph name="LIST_ITEM" />Je werkgever of school
+ <ph name="LIST_ITEM" />Je internetprovider
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Inschrijvingsdomein:</translation>
<translation id="1340482604681802745">Ophaaladres</translation>
<translation id="1344211575059133124">Het lijkt erop dat je toestemming nodig hebt om deze site te bezoeken</translation>
<translation id="1344588688991793829">Instellingen voor automatisch aanvullen in Chromium...</translation>
+<translation id="1348198688976932919">De volgende site bevat gevaarlijke apps</translation>
<translation id="1374468813861204354">suggesties</translation>
<translation id="1375198122581997741">Over deze versie</translation>
<translation id="1377321085342047638">Kaartnummer</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> heeft geen gegevens verzonden.</translation>
<translation id="1407135791313364759">Alles openen</translation>
<translation id="1413809658975081374">Privacyfout</translation>
+<translation id="14171126816530869">De identiteit van <ph name="ORGANIZATION" /> op <ph name="LOCALITY" /> is geverifieerd door <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Afdrukken</translation>
-<translation id="1442912890475371290">Geblokkeerde poging <ph name="BEGIN_LINK" /> om een pagina op <ph name="DOMAIN" /><ph name="END_LINK" /> te bezoeken.</translation>
-<translation id="1491663344921578213">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat de website gebruikmaakt van certificaatpinning. Aangezien netwerkfouten en aanvallen meestal van tijdelijke aard zijn, zal deze pagina later waarschijnlijk weer correct werken. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Een opgeslagen (verouderde) kopie van deze pagina weergeven.</translation>
<translation id="1517433312004943670">Telefoonnummer vereist</translation>
<translation id="1519264250979466059">Datum van build</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript moet zijn ingeschakeld om deze functie te kunnen gebruiken.</translation>
<translation id="1555130319947370107">Blauw</translation>
<translation id="1559528461873125649">Dit bestand of deze directory bestaat niet</translation>
-<translation id="1559572115229829303">&lt;p&gt;Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van je apparaat (<ph name="DATE_AND_TIME" />) onjuist zijn.&lt;/p&gt;
-
- &lt;p&gt;Pas in het gedeelte &lt;strong&gt;Algemeen&lt;/strong&gt; van de app &lt;strong&gt;Instellingen&lt;/strong&gt; de datum en tijd aan.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Er is iets misgegaan met het weergeven van deze webpagina.</translation>
<translation id="1592005682883173041">Lokale gegevenstoegang</translation>
+<translation id="1594030484168838125">Kiezen</translation>
<translation id="161042844686301425">Cyaan</translation>
+<translation id="1620510694547887537">Camera</translation>
<translation id="1629803312968146339">Wil je dat Chrome deze kaart opslaat?</translation>
<translation id="1639239467298939599">Laden</translation>
<translation id="1640180200866533862">Gebruikersbeleid</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">De netwerkconfiguratie is ongeldig en kan niet worden geïmporteerd.</translation>
<translation id="1644574205037202324">Geschiedenis</translation>
<translation id="1645368109819982629">Niet-ondersteund protocol</translation>
+<translation id="1655462015569774233">{1,plural, =1{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is gisteren verlopen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. De klok van je computer is momenteel ingesteld op <ph name="CURRENT_DATE" />. Is dat correct? Zo niet, dan moet je de klok van je systeem aanpassen en vervolgens deze pagina vernieuwen.}other{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is # dagen geleden verlopen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. De klok van je computer is momenteel ingesteld op <ph name="CURRENT_DATE" />. Is dat correct? Zo niet, dan moet je de klok van je systeem aanpassen en vervolgens deze pagina vernieuwen.}}</translation>
<translation id="1656489000284462475">Ophaaltijd</translation>
<translation id="1663943134801823270">Kaarten en adressen zijn afkomstig uit Chrome. Je kunt ze beheren in <ph name="BEGIN_LINK" />Instellingen<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> gebruikt gewoonlijk versleuteling om je gegevens te beschermen. Toen Google Chrome deze keer probeerde verbinding te maken met <ph name="SITE" />, retourneerde de website ongewone en onjuiste inloggegevens. Dit kan gebeuren als een aanvaller probeert zich als <ph name="SITE" /> voor te doen of als een wifi-inlogscherm de verbinding heeft verbroken. Je gegevens zijn nog steeds veilig omdat Google Chrome de verbinding heeft beëindigd voordat er gegevens konden worden uitgewisseld.</translation>
-<translation id="168328519870909584">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen mogelijk gevaarlijke apps op je apparaat te installeren waarmee je gegevens kunnen worden gestolen of verwijderd (bijvoorbeeld foto's, wachtwoorden, berichten en creditcardgegevens).</translation>
<translation id="168841957122794586">Het servercertificaat bevat een zwakke cryptografische sleutel.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is zogenaamd van morgen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.}other{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is zogenaamd van # dagen in de toekomst. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.}}</translation>
<translation id="1710259589646384581">Besturingssysteem</translation>
<translation id="1721312023322545264">Je hebt toestemming van <ph name="NAME" /> nodig om deze site te bezoeken</translation>
<translation id="1721424275792716183">* Verplicht veld</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Pagina later downloaden</translation>
<translation id="17513872634828108">Geopende tabbladen</translation>
<translation id="1753706481035618306">Paginanummer</translation>
+<translation id="1763864636252898013">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door het besturingssysteem van je apparaat. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Voer Windows Netwerkcontrole uit<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Update je wachtwoordzin voor synchronisatie.</translation>
<translation id="1787142507584202372">Je geopende tabbladen worden hier weergegeven</translation>
+<translation id="1789575671122666129">Pop-ups</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Naam kaarthouder</translation>
-<translation id="1803678881841855883">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />malware gedetecteerd<ph name="END_LINK" /> op <ph name="SITE" />. Websites die normaal gesproken veilig zijn, worden soms besmet met malware. De schadelijke content is afkomstig van <ph name="SUBRESOURCE_HOST" />, een bekende distributeur van malware. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Toegevoegd: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Ongeldige aanvraag of aanvraagparameters</translation>
<translation id="1826516787628120939">Controleren</translation>
<translation id="1834321415901700177">Deze site bevat schadelijke programma's</translation>
+<translation id="1840414022444569775">Dit kaartnummer wordt al gebruikt</translation>
<translation id="1842969606798536927">Betalen</translation>
<translation id="1871208020102129563">Proxy is ingesteld op het gebruik van vaste proxyservers, niet op een script-URL van het PAC-type.</translation>
<translation id="1871284979644508959">Verplicht veld</translation>
<translation id="187918866476621466">Startpagina's openen</translation>
<translation id="1883255238294161206">Lijst samenvouwen</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filteren</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Geen}=1{1 site}other{# sites}}</translation>
<translation id="194030505837763158">Ga naar <ph name="LINK" /></translation>
<translation id="1962204205936693436">Bladwijzers voor <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Serialisatiefout</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Genegeerd omdat het werd overschreven door <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Bezig met zoeken naar Fysieke webpagina's in de buurt</translation>
<translation id="213826338245044447">Mobiele bladwijzers</translation>
-<translation id="2148716181193084225">Vandaag</translation>
+<translation id="2147827593068025794">Synchronisatie op de achtergrond</translation>
<translation id="2154054054215849342">De synchronisatieservice is niet beschikbaar voor je domein</translation>
<translation id="2154484045852737596">Kaart bewerken</translation>
<translation id="2166049586286450108">Volledige beheerderstoegang</translation>
<translation id="2166378884831602661">Deze site kan geen beveiligde verbinding leveren</translation>
<translation id="2181821976797666341">Beleid</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adres}other{# adressen}}</translation>
+<translation id="2187317261103489799">Detecteren (standaard)</translation>
<translation id="2202020181578195191">Geef een geldig vervaljaar op</translation>
<translation id="2212735316055980242">Beleid niet gevonden</translation>
<translation id="2213606439339815911">Items ophalen…</translation>
+<translation id="2218879909401188352">Aanvallers die zich momenteel op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> bevinden, kunnen gevaarlijke apps installeren die je apparaat beschadigen, verborgen kosten toevoegen aan je mobiele telefoonrekening of je persoonlijke gegevens stelen. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Los problemen met je verbinding op met de <ph name="BEGIN_LINK" />diagnose-app<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Nu verzenden</translation>
<translation id="225207911366869382">Deze waarde is verouderd voor dit beleid.</translation>
<translation id="2262243747453050782">HTTP-fout</translation>
+<translation id="2270484714375784793">Telefoonnummer</translation>
<translation id="2282872951544483773">Onbeschikbare experimenten</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item}other{<ph name="ITEM_COUNT" /> items}}</translation>
<translation id="2292556288342944218">Je toegang tot internet wordt geblokkeerd</translation>
<translation id="230155334948463882">Nieuwe kaart?</translation>
-<translation id="2305919008529760154">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server is mogelijk frauduleus verstrekt. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">Voor <ph name="DOMAIN" /> zijn een gebruikersnaam en een wachtwoord vereist.</translation>
-<translation id="2318774815570432836">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat de website gebruikmaakt van HSTS. Aangezien netwerkfouten en aanvallen meestal van tijdelijke aard zijn, zal deze pagina later waarschijnlijk weer correct werken. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Instelling beheerd door je beheerder</translation>
<translation id="2354001756790975382">Andere bladwijzers</translation>
+<translation id="2354430244986887761">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />schadelijke apps gevonden<ph name="END_LINK" /> op <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Aanvallers kunnen mogelijk de afbeeldingen zien die je op deze site bekijkt en je misleiden door de afbeeldingen aan te passen.</translation>
+<translation id="2356070529366658676">Vragen</translation>
+<translation id="2359629602545592467">Meerdere</translation>
<translation id="2359808026110333948">Doorgaan</translation>
<translation id="2365563543831475020">Het crashrapport dat is vastgelegd op <ph name="CRASH_TIME" />, is niet geüpload</translation>
<translation id="2367567093518048410">Niveau</translation>
-<translation id="2371153335857947666">{1,plural, =1{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is gisteren verlopen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. De klok van je computer is momenteel ingesteld op <ph name="CURRENT_DATE" />. Is dat correct? Zo niet, dan moet je de klok van je systeem aanpassen en vervolgens deze pagina vernieuwen. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.}other{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is # dagen geleden verlopen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. De klok van je computer is momenteel ingesteld op <ph name="CURRENT_DATE" />. Is dat correct? Zo niet, dan moet je de klok van je systeem aanpassen en vervolgens deze pagina vernieuwen. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Geen UI-alternatieven beschikbaar</translation>
<translation id="2384307209577226199">Standaardinstelling van bedrijf</translation>
<translation id="2386255080630008482">Het servercertificaat is ingetrokken.</translation>
<translation id="2392959068659972793">Beleid weergeven zonder waarde ingesteld</translation>
<translation id="239429038616798445">Deze verzendmethode is niet beschikbaar. Kies een andere methode.</translation>
<translation id="2396249848217231973">&amp;Verwijderen ongedaan maken</translation>
-<translation id="2460160116472764928">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />malware gedetecteerd<ph name="END_LINK" /> op <ph name="SITE" />. Websites die normaal gesproken veilig zijn, worden soms besmet met malware. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server is mogelijk ingetrokken. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
<translation id="2463739503403862330">Invullen</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Netwerkcontrole uitvoeren<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Ongeldige zoek-URL.</translation>
+<translation id="2482878487686419369">Meldingen</translation>
<translation id="2491120439723279231">Het servercertificaat bevat fouten.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2495093607237746763">Als deze optie is aangevinkt, bewaart Chromium een exemplaar van je kaart op dit apparaat om formulieren sneller te kunnen invullen.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Terug</translation>
<translation id="2515629240566999685">Controleer het signaal in je omgeving</translation>
<translation id="2516305470678292029">UI-alternatieven</translation>
+<translation id="2539524384386349900">Detecteren</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> heeft een ongeldige reactie verzonden.</translation>
-<translation id="2552545117464357659">Nieuwer</translation>
<translation id="2556876185419854533">&amp;Bewerken ongedaan maken</translation>
<translation id="2587730715158995865">Van <ph name="ARTICLE_PUBLISHER" />. Lees dit en <ph name="OTHER_ARTICLE_COUNT" /> andere artikelen.</translation>
<translation id="2587841377698384444">Directory API-ID:</translation>
<translation id="2597378329261239068">Dit document is beveiligd met een wachtwoord. Geef een wachtwoord op.</translation>
<translation id="2609632851001447353">Varianten</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Geen}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Je klok loopt voor</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Toegang tot het bestand is geweigerd</translation>
<translation id="2653659639078652383">Verzenden</translation>
<translation id="2666117266261740852">Andere tabbladen of apps sluiten</translation>
+<translation id="2670429602441959756">Deze pagina bevat functies die nog niet worden ondersteund in de VR-modus. Afsluiten...</translation>
<translation id="2674170444375937751">Weet je zeker dat u deze pagina's uit je geschiedenis wilt verwijderen?</translation>
<translation id="2677748264148917807">Verlaten</translation>
-<translation id="269990154133806163">De server heeft een certificaat gepresenteerd dat niet openbaar bekend is gemaakt via het beleid voor Certificaattransparantie. Dit is voor bepaalde certificaten een vereiste om er zeker van te zijn dat ze betrouwbaar zijn en bescherming bieden tegen aanvallers. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Leeslijst</translation>
<translation id="2704283930420550640">Waarde komt niet overeen met notatie.</translation>
<translation id="2704951214193499422">Chromium kan je creditcard momenteel niet bevestigen. Probeer het later opnieuw.</translation>
<translation id="2705137772291741111">De in het cachegeheugen opgeslagen versie van deze site is niet bereikbaar.</translation>
<translation id="2709516037105925701">Automatisch aanvullen</translation>
-<translation id="2712118517637785082">Je probeert <ph name="DOMAIN" /> te bereiken, maar het certificaat dat door de server is geretourneerd, is ingetrokken door de uitgever. Dit betekent dat de beveiligingsreferenties die de server heeft geretourneerd absoluut niet kunnen worden vertrouwd. Het is mogelijk dat je met een hacker communiceert. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Toestemming vragen</translation>
<translation id="2713444072780614174">Wit</translation>
<translation id="2720342946869265578">In de buurt</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Apparaatrecord ontbreekt</translation>
<translation id="2784949926578158345">De verbinding is opnieuw ingesteld.</translation>
<translation id="2794233252405721443">Site geblokkeerd</translation>
+<translation id="2799020568854403057">De volgende site bevat schadelijke apps</translation>
+<translation id="2803306138276472711">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />malware gedetecteerd<ph name="END_LINK" /> op <ph name="SITE" />. Websites die normaal gesproken veilig zijn, worden soms geïnfecteerd met malware.</translation>
<translation id="2824775600643448204">Adres- en zoekbalk</translation>
<translation id="2826760142808435982">De verbinding is gecodeerd en geverifieerd met <ph name="CIPHER" /> en gebruikt <ph name="KX" /> als mechanisme voor sleuteluitwisseling.</translation>
<translation id="2835170189407361413">Formulier leegmaken</translation>
+<translation id="2856444702002559011">Cybercriminelen proberen mogelijk je gegevens van <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> te stelen (bijvoorbeeld wachtwoorden, berichten of creditcardgegevens). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Niet opnieuw laden</translation>
<translation id="2900469785430194048">Google Chrome beschikt over onvoldoende geheugen om deze webpagina weer te geven.</translation>
<translation id="2909946352844186028">Er is een netwerkwijziging gedetecteerd.</translation>
<translation id="2916038427272391327">Andere programma's sluiten</translation>
<translation id="2922350208395188000">Het servercertificaat kan niet worden gecontroleerd.</translation>
<translation id="2928905813689894207">Factuuradres</translation>
+<translation id="2941952326391522266">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server is afkomstig van <ph name="DOMAIN2" />. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
<translation id="2948083400971632585">Via de instellingenpagina kun je proxyservers uitschakelen die voor een verbinding zijn geconfigureerd.</translation>
<translation id="2955913368246107853">Zoekbalk sluiten</translation>
<translation id="2958431318199492670">De netwerkconfiguratie voldoet niet aan de ONC-standaard. Delen van de configuratie worden mogelijk niet geïmporteerd.</translation>
-<translation id="29611076221683977">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen mogelijk gevaarlijke programma's op je Mac te installeren waarmee je gegevens kunnen worden gestolen of verwijderd (bijvoorbeeld foto's, wachtwoorden, berichten en creditcarddetails).</translation>
<translation id="2966678944701946121">Vervaldatum: <ph name="EXPIRATION_DATE_ABBR" />, toegevoegd: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Als je een beveiligde verbinding tot stand wilt brengen, moet je klok correct zijn ingesteld. Dit moet omdat de certificaten die deze websites gebruiken om zichzelf te identificeren, slechts gedurende bepaalde perioden geldig zijn. Aangezien de klok van je apparaat niet goed is ingesteld, kan Chrome deze certificaten niet verifiëren.</translation>
<translation id="2972581237482394796">&amp;Opnieuw</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Geef een geldig adres op</translation>
<translation id="2986368408720340940">Deze ophaalmethode is niet beschikbaar. Kies een andere methode.</translation>
<translation id="2991174974383378012">Delen met websites</translation>
+<translation id="2991571918955627853">Je kunt <ph name="SITE" /> momenteel niet bezoeken, omdat de website HSTS gebruikt. Netwerkfouten en aanvallen zijn doorgaans tijdelijk, dus deze pagina werkt later waarschijnlijk correct.</translation>
<translation id="3005723025932146533">Opgeslagen kopie weergeven</translation>
<translation id="3008447029300691911">Geef de CVC-code voor <ph name="CREDIT_CARD" /> op. Zodra je bevestigt, worden je creditcardgegevens gedeeld met deze site.</translation>
<translation id="3010559122411665027">Lijstitem '<ph name="ENTRY_INDEX" />': <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatisch geblokkeerd</translation>
<translation id="3024663005179499861">Onjuist beleidstype</translation>
<translation id="3032412215588512954">Wil je deze site opnieuw laden?</translation>
<translation id="3037605927509011580">Helaas.</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{ten minste 1 item op gesynchroniseerde apparaten}=1{1 item (en meer op gesynchroniseerde apparaten)}other{# items (en meer op gesynchroniseerde apparaten)}}</translation>
<translation id="3041612393474885105">Certificaatgegevens</translation>
<translation id="3063697135517575841">Chrome kan je creditcard momenteel niet bevestigen. Probeer het later opnieuw.</translation>
<translation id="3064966200440839136">Je verlaat de incognitomodus om te betalen via een externe app. Doorgaan?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Geen}=1{1 wachtwoord}other{# wachtwoorden}}</translation>
<translation id="3093245981617870298">Je bent offline.</translation>
<translation id="3105172416063519923">Item-ID:</translation>
<translation id="3109728660330352905">Je hebt geen toestemming om deze pagina te bekijken.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Voer Verbindingsdiagnose uit<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Kan reactie niet decoderen</translation>
<translation id="3150653042067488994">Tijdelijke serverfout</translation>
@@ -247,13 +277,17 @@
<translation id="3167968892399408617">De pagina's die je op incognitotabbladen weergeeft, worden niet bewaard in je browsergeschiedenis, cookie-opslag of zoekgeschiedenis nadat je al je incognitotabbladen hebt gesloten. Alle bestanden die je hebt gedownload of bladwijzers die je hebt gemaakt, blijven behouden.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Eiland</translation>
+<translation id="317583078218509884">De nieuwe instellingen voor siterechten worden doorgevoerd nadat de pagina opnieuw is geladen.</translation>
<translation id="3176929007561373547">Controleer je proxyinstellingen of neem contact op met je netwerkbeheerder om te controleren of de proxyserver werkt. Als je denkt dat je geen proxyserver zou moeten gebruiken: <ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">De pagina openen in de incognitomodus</translation>
-<translation id="3202578601642193415">Nieuwste</translation>
+<translation id="320323717674993345">Betaling annuleren</translation>
<translation id="3207960819495026254">Toegevoegd aan 'Bladwijzers'</translation>
+<translation id="3225919329040284222">De server heeft een certificaat gepresenteerd dat niet overeenkomt met de ingebouwde verwachtingen. Deze verwachtingen zijn opgenomen voor bepaalde websites om je te beschermen.</translation>
<translation id="3226128629678568754">Klik op de knop 'Opnieuw laden' om de gegevens opnieuw te verzenden die nodig zijn om de pagina te laden.</translation>
+<translation id="3227137524299004712">Microfoon</translation>
<translation id="3228969707346345236">De vertaling is mislukt omdat de pagina al in het <ph name="LANGUAGE" /> is.</translation>
<translation id="323107829343500871">De CVC-code voor <ph name="CREDIT_CARD" /> opgeven</translation>
+<translation id="3234666976984236645">Altijd belangrijke content op deze site detecteren</translation>
<translation id="3254409185687681395">Bladwijzer instellen voor deze pagina</translation>
<translation id="3270847123878663523">&amp;Volgorde wijzigen ongedaan maken</translation>
<translation id="3282497668470633863">Naam op kaart toevoegen</translation>
@@ -267,42 +301,48 @@
<translation id="3340978935015468852">instellingen</translation>
<translation id="3345135638360864351">Je verzoek om toegang tot deze site kan niet worden verzonden naar <ph name="NAME" />. Probeer het opnieuw.</translation>
<translation id="3355823806454867987">Proxyinstellingen wijzigen...</translation>
+<translation id="3361596688432910856">De volgende gegevens worden <ph name="BEGIN_EMPHASIS" />niet opgeslagen<ph name="END_EMPHASIS" /> in Chrome:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Je browsegeschiedenis
+ <ph name="LIST_ITEM" />Cookies en sitegegevens
+ <ph name="LIST_ITEM" />Informatie die is opgegeven in formulieren
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Klokfout</translation>
-<translation id="337311366426640088">Nog <ph name="ITEM_COUNT" /> items...</translation>
<translation id="337363190475750230">Uitgeschreven</translation>
<translation id="3377188786107721145">Fout bij het parseren van beleid</translation>
<translation id="3380365263193509176">Onbekende fout</translation>
<translation id="3380864720620200369">Klant-ID:</translation>
<translation id="3391030046425686457">Afleveradres</translation>
<translation id="3395827396354264108">Ophaalmethode</translation>
-<translation id="340013220407300675">Aanvallers proberen mogelijk je gegevens van <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> te stelen (bijvoorbeeld wachtwoorden, berichten of creditcarddetails).</translation>
<translation id="3422248202833853650">Probeer andere programma's af te sluiten om geheugen vrij te maken.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> is momenteel niet bereikbaar.</translation>
+<translation id="3427092606871434483">Toestaan (standaard)</translation>
<translation id="3427342743765426898">&amp;Opnieuw bewerken</translation>
<translation id="3431636764301398940">Deze creditcard opslaan op dit apparaat</translation>
<translation id="3435896845095436175">Inschakelen</translation>
<translation id="3447661539832366887">De eigenaar van dit apparaat heeft de dinosaurusgame uitgeschakeld.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Ophaalinterval:</translation>
<translation id="3462200631372590220">Gedetailleerde informatie verbergen</translation>
<translation id="3467763166455606212">Naam kaarthouder vereist</translation>
<translation id="3478058380795961209">Vervalmaand</translation>
<translation id="3479539252931486093">Wat dit onverwacht? <ph name="BEGIN_LINK" />Laat het ons weten<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Niet nu</translation>
-<translation id="348000606199325318">Crash-ID <ph name="CRASH_LOCAL_ID" /> (Server-ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">We kunnen je ouder momenteel niet bereiken. Probeer het opnieuw.</translation>
<translation id="3528171143076753409">Het servercertificaat is niet betrouwbaar.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Ten minste één item op gesynchroniseerde apparaten}=1{1 item (en meer op gesynchroniseerde apparaten)}other{# items (en meer op gesynchroniseerde apparaten)}}</translation>
<translation id="3539171420378717834">Een exemplaar van deze kaart op dit apparaat bewaren</translation>
<translation id="3542684924769048008">Wachtwoord gebruiken voor:</translation>
+<translation id="3545341443414427877">Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van je computer (<ph name="DATE_AND_TIME" />) onjuist zijn. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Alle gesynchroniseerde gegevens versleutelen met je eigen wachtwoordzin voor synchronisatie</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> meer...</translation>
-<translation id="3555561725129903880">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server is afkomstig van <ph name="DOMAIN2" />. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Je beheerder kan de blokkering van de site opheffen</translation>
<translation id="3566021033012934673">Je verbinding is niet privé</translation>
+<translation id="3569145463236695319">&lt;p&gt;Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van je apparaat (<ph name="DATE_AND_TIME" />) onjuist zijn.&lt;/p&gt;
+
+ &lt;p&gt;Pas in het gedeelte &lt;strong&gt;Algemeen&lt;/strong&gt; van de app &lt;strong&gt;Instellingen&lt;/strong&gt; de datum en tijd aan.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Voeg naam toe</translation>
<translation id="3583757800736429874">&amp;Opnieuw verplaatsen</translation>
<translation id="3586931643579894722">Details verbergen</translation>
-<translation id="3587482841069643663">Alles</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Geef een geldige vervaldatum op</translation>
<translation id="36224234498066874">Wis browsegegevens...</translation>
@@ -318,7 +358,6 @@
<translation id="3681007416295224113">Certificaatgegevens</translation>
<translation id="3690164694835360974">Inloggen niet veilig</translation>
<translation id="3693415264595406141">Wachtwoord:</translation>
-<translation id="3696411085566228381">geen</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Bezig met laden...</translation>
<translation id="3712624925041724820">Licenties zijn verbruikt</translation>
@@ -326,12 +365,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Controleer de proxy, firewall en DNS-configuratie<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Als je de beveiligingsrisico's begrijpt, kun je <ph name="BEGIN_LINK" />deze onveilige site bezoeken<ph name="END_LINK" /> voordat de gevaarlijke programma's zijn verwijderd.</translation>
<translation id="3739623965217189342">Link die je hebt gekopieerd</translation>
+<translation id="3744899669254331632">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat de website gecodeerde inloggegevens heeft verstuurd die niet door Chromium kunnen worden verwerkt. Aangezien netwerkfouten en aanvallen doorgaans van tijdelijke aard zijn, zal deze pagina later waarschijnlijk wel werken.</translation>
+<translation id="3748148204939282805">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen je mogelijk te misleiden om iets gevaarlijks te doen, zoals software installeren of je persoonlijke gegevens bekendmaken (bijvoorbeeld wachtwoorden, telefoonnummers of creditcardgegevens). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Het vertalen is mislukt wegens een serverfout.</translation>
<translation id="3759461132968374835">Je hebt geen onlangs gemelde crashes. Crashes die zich voordeden toen de crashrapportage was uitgeschakeld, worden hier niet weergegeven.</translation>
+<translation id="3778403066972421603">Wil je deze kaart opslaan in je Google-account en op dit apparaat?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Verloopt: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Als je een proxyserver gebruikt...</translation>
<translation id="3828924085048779000">Een lege wachtwoordzin is niet toegestaan.</translation>
-<translation id="3845539888601087042">Geschiedenis van je ingelogde apparaten wordt weergegeven. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Vorige</translation>
<translation id="3858027520442213535">Datum en tijd updaten</translation>
<translation id="3884278016824448484">Conflicterende apparaat-ID's</translation>
@@ -339,11 +381,13 @@
<translation id="3886446263141354045">Je verzoek voor toegang tot deze website is verzonden naar <ph name="NAME" /></translation>
<translation id="3890664840433101773">E-mailadres toevoegen</translation>
<translation id="3901925938762663762">De kaart is verlopen</translation>
-<translation id="3933571093587347751">{1,plural, =1{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is zogenaamd van morgen. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.}other{Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het bijbehorende beveiligingscertificaat is zogenaamd van # dagen in de toekomst. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF-document kan niet worden geladen</translation>
+<translation id="3945915738023014686">Crashrapport-ID <ph name="CRASH_ID" /> (lokale crash-ID: <ph name="CRASH_LOCAL_ID" />) geüpload</translation>
+<translation id="3949571496842715403">Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. In het bijbehorende beveiligingscertificaat worden geen 'Subject Alternative Names' gespecificeerd. Dit kan worden veroorzaakt door een verkeerde configuratie of door een aanvaller die je verbinding heeft onderschept.</translation>
<translation id="3963721102035795474">Lezermodus</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Geen}=1{Van één site }other{Van # sites }}</translation>
<translation id="397105322502079400">Berekenen...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> wordt geblokkeerd</translation>
+<translation id="3987940399970879459">Minder dan 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 webpagina in de buurt}other{# webpagina's in de buurt}}</translation>
<translation id="4021036232240155012">DNS is de netwerkservice die de naam van een website omzet naar het bijbehorende internetadres.</translation>
<translation id="4030383055268325496">&amp;Toevoegen ongedaan maken</translation>
@@ -354,56 +398,63 @@
<translation id="4079302484614802869">Proxyconfiguratie is ingesteld op het gebruik van een pac-script-URL, niet op het gebruik van vaste proxyservers.</translation>
<translation id="4098354747657067197">Misleidende site gedetecteerd</translation>
<translation id="4103249731201008433">Serienummer van apparaat is ongeldig</translation>
+<translation id="410351446219883937">Automatisch afspelen</translation>
<translation id="4103763322291513355">Ga naar &lt;strong&gt;chrome://policy&lt;/strong&gt; om de lijst met URL's op de zwarte lijst en andere beleidsregels te bekijken die worden afgedwongen door je systeembeheerder.</translation>
-<translation id="4110615724604346410">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server bevat fouten. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Altijd toestaan op deze site</translation>
<translation id="4117700440116928470">Beleidsbereik wordt niet ondersteund.</translation>
-<translation id="4118212371799607889">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door Chromium. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 andere persoon}other{# andere mensen}}</translation>
<translation id="4130226655945681476">Controleer de netwerkkabels, modem en router</translation>
+<translation id="413544239732274901">Meer informatie</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Algemene standaard gebruiken (detecteren)</translation>
+<translation id="4165986682804962316">Site-instellingen</translation>
<translation id="4169947484918424451">Wil je dat Chromium deze kaart opslaat?</translation>
<translation id="4171400957073367226">Onjuiste verificatiehandtekening</translation>
<translation id="4196861286325780578">&amp;Opnieuw verplaatsen</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Controleer firewall- en antivirusconfiguraties<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{geen}=1{1 app ($1)}=2{2 apps ($1, $2)}other{# apps ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Crashes</translation>
+<translation id="422022731706691852">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen je mogelijk te misleiden om programma's te installeren die schadelijk zijn voor de browserfunctionaliteit (door bijvoorbeeld je homepage te wijzigen of extra advertenties weer te geven op sites die je bezoekt). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Voer Netwerkcontrole uit<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Geldig</translation>
<translation id="4250431568374086873">Je verbinding met deze site is niet volledig veilig</translation>
<translation id="4250680216510889253">Nee</translation>
<translation id="425582637250725228">Wijzigingen die je hebt aangebracht, worden mogelijk niet opgeslagen.</translation>
<translation id="4258748452823770588">Onjuiste handtekening</translation>
+<translation id="4265872034478892965">Toegestaan door je beheerder</translation>
<translation id="4269787794583293679">(Geen gebruikersnaam)</translation>
<translation id="4275830172053184480">Je apparaat opnieuw opstarten</translation>
<translation id="4280429058323657511">, vervalt <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />schadelijke programma's gevonden<ph name="END_LINK" /> op <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Bovenliggende suggesties</translation>
<translation id="4304224509867189079">Inloggen</translation>
-<translation id="432290197980158659">De server heeft een certificaat gepresenteerd dat niet overeenkomt met de ingebouwde verwachtingen. Deze verwachtingen zijn opgenomen voor bepaalde zwaar beveiligde websites om je te beschermen. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blokkeren (standaard)</translation>
<translation id="4325863107915753736">Kan artikel niet vinden</translation>
<translation id="4326324639298822553">Controleer de vervaldatum en probeer het opnieuw</translation>
<translation id="4331708818696583467">Niet veilig</translation>
<translation id="4356973930735388585">Cybercriminelen op deze site proberen mogelijk gevaarlijke programma's op je computer te installeren waarmee je gegevens worden gestolen of verwijderd (bijvoorbeeld foto's, wachtwoorden, berichten en creditcards).</translation>
<translation id="4372948949327679948">Verwachte <ph name="VALUE_TYPE" /> waarde.</translation>
+<translation id="4377125064752653719">Je probeert <ph name="DOMAIN" /> te bereiken, maar het certificaat dat de server heeft geretourneerd, is ingetrokken door de uitgever. Dat betekent dat de veiligheidsgaranties die de server heeft geretourneerd, absoluut niet kunnen worden vertrouwd. Het kan zijn dat je met een hacker aan het communiceren bent.</translation>
<translation id="4381091992796011497">Gebruikersnaam:</translation>
<translation id="4394049700291259645">Uitschakelen</translation>
<translation id="4406896451731180161">zoekresultaten</translation>
+<translation id="4424024547088906515">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door Chrome. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> heeft je inlogcertificaat niet geaccepteerd of er is geen inlogcertificaat geleverd.</translation>
<translation id="443673843213245140">Het gebruik van een proxy is uitgeschakeld, maar er is wel een expliciete proxyconfiguratie opgegeven.</translation>
-<translation id="4492190037599258964">Zoekresultaten voor '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Validatiefout: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Neem contact op met de systeembeheerder</translation>
<translation id="450710068430902550">Delen met beheerder</translation>
<translation id="4515275063822566619">Kaarten en adressen zijn afkomstig uit Chrome en je Google-account (<ph name="ACCOUNT_EMAIL" />). Je kunt ze beheren in <ph name="BEGIN_LINK" />Instellingen<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Details</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Probeer je extensies uit te schakelen.</translation>
<translation id="457875822857220463">Bezorging</translation>
<translation id="4587425331216688090">Adres verwijderen uit Chrome?</translation>
-<translation id="4589078953350245614">Je probeert <ph name="DOMAIN" /> te bereiken, maar de server heeft een ongeldig certificaat geretourneerd. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Je verbinding met <ph name="DOMAIN" /> is versleuteld via een moderne Cipher Suite.</translation>
<translation id="4594403342090139922">&amp;Verwijderen ongedaan maken</translation>
<translation id="4619615317237390068">Tabbladen van andere apparaten</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server bevat fouten. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
+<translation id="4690462567478992370">Stoppen met het gebruik van een ongeldig certificaat</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Je verbinding is onderbroken</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows Netwerkcontrole uitvoeren<ph name="END_LINK" /></translation>
@@ -420,21 +471,24 @@
<translation id="4771973620359291008">Er is een onbekende fout opgetreden.</translation>
<translation id="4800132727771399293">Controleer je vervaldatum en CVC-code en probeer het opnieuw</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat de website gecodeerde inloggegevens heeft verzonden die niet door Google Chrome kunnen worden verwerkt. Netwerkfouten en aanvallen zijn meestal tijdelijk, dus deze pagina werkt later waarschijnlijk weer correct.</translation>
<translation id="4813512666221746211">Netwerkfout</translation>
<translation id="4816492930507672669">Aanpassen aan pagina</translation>
<translation id="483020001682031208">Geen Fysieke webpagina's om weer te geven</translation>
<translation id="4850886885716139402">Weergave</translation>
<translation id="4854362297993841467">Deze bezorgingsmethode is niet beschikbaar. Kies een andere methode.</translation>
<translation id="4858792381671956233">Je hebt je ouders gevraagd of je deze site mag bezoeken</translation>
+<translation id="4863764087567530506">Deze content probeert je mogelijk te misleiden zodat je software installeert of persoonlijke gegevens openbaar maakt. <ph name="BEGIN_LINK" />Toch weergeven<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Geschiedenis doorzoeken</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{en nog 1 webpagina}other{en nog # webpagina's}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Deze pagina is vertaald uit een onbekende taal naar het <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Betaling</translation>
<translation id="4926049483395192435">Moet worden opgegeven.</translation>
<translation id="495170559598752135">Acties</translation>
<translation id="4958444002117714549">Lijst uitvouwen</translation>
-<translation id="4962322354953122629">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door Chrome. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Waarschuwingen opnieuw inschakelen</translation>
<translation id="4989809363548539747">Deze plug-in wordt niet ondersteund</translation>
<translation id="5002932099480077015">Indien ingeschakeld, slaat Chrome een kopie van je kaart op dit apparaat op zodat formulieren sneller kunnen worden ingevuld.</translation>
<translation id="5018422839182700155">Kan deze pagina niet openen</translation>
@@ -442,14 +496,15 @@
<translation id="5023310440958281426">Neem het beleid van je beheerder door</translation>
<translation id="5029568752722684782">Kopie wissen</translation>
<translation id="5031870354684148875">Over Google Translate</translation>
+<translation id="5039804452771397117">Toestaan</translation>
<translation id="5040262127954254034">Privacy</translation>
<translation id="5045550434625856497">Onjuist wachtwoord</translation>
<translation id="5056549851600133418">Artikelen voor jou</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Het proxy-adres controleren<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Geen cookies}=1{1 site gebruikt cookies. }other{# sites gebruiken cookies. }}</translation>
<translation id="5087286274860437796">Het servercertificaat is momenteel niet geldig.</translation>
<translation id="5087580092889165836">Kaart toevoegen</translation>
<translation id="5089810972385038852">Staat</translation>
+<translation id="5094747076828555589">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door Chromium. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
<translation id="5095208057601539847">Provincie</translation>
<translation id="5115563688576182185">(64-bits)</translation>
<translation id="5141240743006678641">Gesynchroniseerde wachtwoorden versleutelen met je Google-aanmeldingsgegevens</translation>
@@ -465,24 +520,24 @@
<translation id="5222812217790122047">E-mailadres vereist</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Gebruik je Chrome op het werk? Bedrijven kunnen Chrome-instellingen beheren voor hun werknemers. Meer informatie</translation>
+<translation id="5297526204711817721">Je verbinding met deze site is niet privé. Je kunt de VR-modus op elk gewenst moment afsluiten door de headset af te zetten en op Terug te drukken.</translation>
<translation id="5299298092464848405">Fout bij het parseren van het beleid</translation>
-<translation id="5300589172476337783">Weergeven</translation>
<translation id="5308689395849655368">Crashrapportage is uitgeschakeld.</translation>
<translation id="5317780077021120954">Opslaan</translation>
<translation id="5327248766486351172">Naam</translation>
-<translation id="5337705430875057403">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen je mogelijk te misleiden om iets gevaarlijks te doen, zoals software installeren of je persoonlijke gegevens bekendmaken (bijvoorbeeld wachtwoorden, telefoonnummers of creditcards).</translation>
-<translation id="5359637492792381994">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat is momenteel niet geldig. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Je kunt <ph name="SITE" /> momenteel niet bezoeken, omdat het bijbehorende certificaat is ingetrokken. Netwerkfouten en aanvallen zijn doorgaans tijdelijk, dus deze pagina werkt later waarschijnlijk correct.</translation>
<translation id="536296301121032821">Opslaan van beleidsinstellingen is mislukt</translation>
<translation id="5386426401304769735">De certificaatketen voor deze site bevat een certificaat dat is ondertekend met SHA-1.</translation>
<translation id="5402410679244714488">Vervaldatum: <ph name="EXPIRATION_DATE_ABBR" />, meer dan een jaar geleden voor het laatst gebruikt</translation>
+<translation id="540969355065856584">Deze server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat is momenteel niet geldig. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
<translation id="5421136146218899937">Browsegegevens wissen...</translation>
<translation id="5430298929874300616">Bladwijzer verwijderen</translation>
<translation id="5431657950005405462">Je bestand is niet gevonden</translation>
-<translation id="5435775191620395718">Geschiedenis van dit apparaat wordt weergegeven. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Schemavalidatiefout op '<ph name="ERROR_PATH" />': <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Deze pagina op <ph name="HOST_NAME" /> kan niet worden gevonden</translation>
<translation id="5455374756549232013">Onjuist tijdstempel van beleid</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> van <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Ongeldig</translation>
<translation id="5470861586879999274">&amp;Opnieuw bewerken</translation>
<translation id="54817484435770891">Voeg een geldig adres toe</translation>
<translation id="5492298309214877701">Deze site op het intranet van het bedrijf, de organisatie of de school heeft dezelfde URL als een externe website.
@@ -499,6 +554,8 @@
<translation id="5571083550517324815">Kan niet ophalen van dit adres. Selecteer een ander adres.</translation>
<translation id="5572851009514199876">Start Chrome en log in zodat Chrome kan controleren of je deze site mag openen.</translation>
<translation id="5580958916614886209">Controleer de vervalmaand en probeer het opnieuw</translation>
+<translation id="5586446728396275693">Geen opgeslagen adressen</translation>
+<translation id="5595485650161345191">Adres bewerken</translation>
<translation id="560412284261940334">Beheer wordt niet ondersteund</translation>
<translation id="5610142619324316209">Controleer de verbinding</translation>
<translation id="5610807607761827392">Je kunt kaarten en adressen beheren in <ph name="BEGIN_LINK" />Instellingen<ph name="END_LINK" />.</translation>
@@ -506,15 +563,18 @@
<translation id="5622887735448669177">Wil je deze site verlaten?</translation>
<translation id="5629630648637658800">Laden van beleidsinstellingen is mislukt</translation>
<translation id="5631439013527180824">Ongeldige token voor apparaatbeheer</translation>
+<translation id="5633066919399395251">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen mogelijk gevaarlijke programma's op je computer te installeren waarmee je gegevens kunnen worden gestolen of verwijderd (bijvoorbeeld foto's, wachtwoorden, berichten en creditcardgegevens). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Locatie</translation>
+<translation id="5659593005791499971">E-mailadres</translation>
<translation id="5669703222995421982">Gepersonaliseerde content ontvangen</translation>
<translation id="5675650730144413517">Deze pagina werkt niet</translation>
-<translation id="5677928146339483299">Geblokkeerd</translation>
-<translation id="5694783966845939798">Je hebt geprobeerd <ph name="DOMAIN" /> te bereiken. De server heeft echter een certificaat geretourneerd dat een zwak ondertekeningsalgoritme gebruikt. Dit houdt in dat de betrouwbaarheidsverklaring van de server kan zijn vervalst. Het is mogelijk dat de server zelf een imitatie is (wellicht een server die je schade probeert te berokkenen). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">De identiteit van deze website is niet geverifieerd.</translation>
+<translation id="5713016350996637505">Misleidende content geblokkeerd</translation>
<translation id="5720705177508910913">Huidige gebruiker</translation>
<translation id="5732392974455271431">Je ouders kunnen de blokkering van deze site opheffen</translation>
<translation id="5763042198335101085">Geef een geldig e-mailadres op</translation>
<translation id="5765072501007116331">Selecteer een adres om bezorgingsmethoden en vereisten te bekijken</translation>
+<translation id="5778550464785688721">Volledige controle voor MIDI-apparaten</translation>
<translation id="5784606427469807560">Er is een probleem opgetreden bij het bevestigen van je creditcard. Controleer je internetverbinding en probeer het opnieuw.</translation>
<translation id="5785756445106461925">Bovendien bevat deze pagina bronnen die niet beveiligd zijn. Deze bronnen kunnen tijdens verzending door anderen worden bekeken en kunnen door een aanvaller worden gewijzigd om het uiterlijk van de pagina aan te passen.</translation>
<translation id="5786044859038896871">Wil je de gegevens van je creditcard laten invullen?</translation>
@@ -523,14 +583,14 @@
<translation id="5813119285467412249">&amp;Opnieuw toevoegen</translation>
<translation id="5814352347845180253">Mogelijk heb je geen toegang meer tot premium content van <ph name="SITE" /> en enkele andere sites.</translation>
<translation id="5838278095973806738">Je moet geen gevoelige gegevens (zoals wachtwoorden of creditcards) opgeven op deze site omdat ze kunnen worden gestolen door aanvallers.</translation>
-<translation id="5843436854350372569">Je probeert <ph name="DOMAIN" /> te bereiken, maar de server heeft een certificaat geretourneerd met een zwakke sleutel. Een hacker kan de persoonlijke sleutel hebben aangepast en het is mogelijk dat de server zelf een imitatie is (wellicht een server die je schade probeert te berokkenen). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Deze site is niet bereikbaar</translation>
<translation id="5869522115854928033">Opgeslagen wachtwoorden</translation>
<translation id="5872918882028971132">Bovenliggende suggesties</translation>
<translation id="5901630391730855834">Geel</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (gesynchroniseerd)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 in gebruik}other{# in gebruik}}</translation>
<translation id="5926846154125914413">Mogelijk heb je geen toegang meer tot premium content van bepaalde sites.</translation>
<translation id="5959728338436674663">Bepaalde <ph name="BEGIN_WHITEPAPER_LINK" />systeeminformatie en paginacontent<ph name="END_WHITEPAPER_LINK" /> automatisch verzenden naar Google om te helpen bij de detectie van gevaarlijke apps en sites. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Week</translation>
<translation id="5967867314010545767">Verwijderen uit geschiedenis</translation>
<translation id="5975083100439434680">Uitzoomen</translation>
<translation id="598637245381783098">Kan betaal-app niet openen</translation>
@@ -539,20 +599,28 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Pagina 1}other{Pagina #}}</translation>
<translation id="6017514345406065928">Groen</translation>
+<translation id="6017850046339264347">Aanvallers op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kunnen misleidende apps installeren die zich voordoen als iets anders of gegevens verzamelen die kunnen worden gebruikt om je te volgen. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (gesynchroniseerd)</translation>
<translation id="6027201098523975773">Geef een naam op</translation>
<translation id="6040143037577758943">Sluiten</translation>
<translation id="6042308850641462728">Meer</translation>
+<translation id="6047233362582046994">Als je de beveiligingsrisico's begrijpt, kun je <ph name="BEGIN_LINK" />deze site bezoeken<ph name="END_LINK" /> voordat de schadelijke apps zijn verwijderd.</translation>
+<translation id="6051221802930200923">Je kunt <ph name="SITE" /> momenteel niet bezoeken, omdat de website gebruikmaakt van certificaatpinning. Netwerkfouten en aanvallen zijn doorgaans tijdelijk, dus deze pagina werkt later waarschijnlijk correct.</translation>
<translation id="6060685159320643512">Pas op, dit zijn geen experimenten om zonder handschoenen aan te pakken</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{geen}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Je hebt toegang tot content gekregen met behulp van een certificaat van je beheerder. Gegevens die je verstrekt aan <ph name="DOMAIN" />, kunnen door je beheerder worden onderschept.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Geen}=1{1 wachtwoord (gesynchroniseerd)}other{# wachtwoorden (gesynchroniseerd)}}</translation>
<translation id="6146055958333702838">Controleer alle kabels en start alle routers, modems of andere netwerkapparaten die je gebruikt, opnieuw op.</translation>
<translation id="614940544461990577">Probeer het volgende:</translation>
<translation id="6151417162996330722">Het servercertificaat heeft een te lange geldigheidsperiode.</translation>
<translation id="6157877588268064908">Selecteer een adres om verzendmethoden en vereisten te bekijken</translation>
+<translation id="6158003235852588289">Google Safe Browsing heeft onlangs phishing gedetecteerd op <ph name="SITE" />. Phishingsites doen zich voor als een andere website om je te misleiden.</translation>
<translation id="6165508094623778733">Meer informatie</translation>
+<translation id="6169916984152623906">Je kunt nu privé browsen, zodat andere mensen die dit apparaat gebruiken, jouw activiteit niet kunnen zien. Downloads en bladwijzers worden echter wel opgeslagen.</translation>
<translation id="6177128806592000436">Je verbinding met deze site is niet veilig</translation>
<translation id="6184817833369986695">(cohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Controleer je internetverbinding</translation>
<translation id="6218753634732582820">Adres verwijderen uit Chromium?</translation>
+<translation id="6221345481584921695">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />malware gedetecteerd<ph name="END_LINK" /> op <ph name="SITE" />. Websites die normaal gesproken veilig zijn, worden soms geïnfecteerd met malware. De schadelijke content is afkomstig van <ph name="SUBRESOURCE_HOST" />, een bekende distributeur van malware.</translation>
<translation id="6251924700383757765">Privacybeleid</translation>
<translation id="6254436959401408446">Onvoldoende geheugen om deze pagina te openen</translation>
<translation id="625755898061068298">Je hebt ervoor gekozen beveiligingswaarschuwingen voor deze site uit te schakelen.</translation>
@@ -578,15 +646,14 @@
<translation id="6404511346730675251">Bladwijzer bewerken</translation>
<translation id="6410264514553301377">Geef de vervaldatum en CVC-code op voor <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Je hebt je ouder of voogd gevraagd of je deze site mag bezoeken</translation>
-<translation id="6416403317709441254">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat de website gecodeerde inloggegevens heeft verstuurd die niet door Chromium kunnen worden verwerkt. Aangezien netwerkfouten en aanvallen meestal van tijdelijke aard zijn, zal deze pagina later waarschijnlijk weer correct werken. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Kan niet controleren of het certificaat is ingetrokken.</translation>
<translation id="6433490469411711332">Contactgegevens bewerken</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> heeft de verbinding geweigerd.</translation>
<translation id="6446608382365791566">Meer informatie toevoegen</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Opnieuw indienen bevestigen</translation>
<translation id="6456339708790392414">Je betaling</translation>
<translation id="6458467102616083041">Genegeerd omdat de standaardzoekoptie door het beleid is uitgeschakeld.</translation>
-<translation id="6462969404041126431">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server is mogelijk ingetrokken. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Apparaatbeleid</translation>
<translation id="6477321094435799029">Chrome heeft ongebruikelijke code op deze pagina gedetecteerd en heeft de code geblokkeerd om je persoonlijke gegevens (zoals wachtwoorden, telefoonnummers en creditcards) te beschermen.</translation>
<translation id="6489534406876378309">Uploaden van crashes starten</translation>
@@ -598,20 +665,19 @@
<translation id="6556915248009097796">Vervaldatum: <ph name="EXPIRATION_DATE_ABBR" />, laatst gebruikt: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Je beheerder heeft dit nog niet goedgekeurd</translation>
<translation id="6569060085658103619">Je bekijkt een extensiepagina</translation>
-<translation id="6593753688552673085">minder dan <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Deze content kan proberen gevaarlijke software op je apparaat te installeren die je gegevens steelt of verwijdert. <ph name="BEGIN_LINK" />Toch weergeven<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opties voor encryptie</translation>
<translation id="662080504995468778">Blijven</translation>
<translation id="6626291197371920147">Een geldig kaartnummer toevoegen</translation>
<translation id="6628463337424475685">Zoeken via <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen mogelijk gevaarlijke programma's op je Mac te installeren waarmee je gegevens kunnen worden gestolen of verwijderd (bijvoorbeeld foto's, wachtwoorden, berichten en creditcardgegevens). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Dit beleid is verouderd.</translation>
-<translation id="6652240803263749613">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door het besturingssysteem van je computer. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Formuliersuggestie verwijderen uit Chromium?</translation>
<translation id="6685834062052613830">Uitloggen en configuratie voltooien</translation>
<translation id="6710213216561001401">Vorige</translation>
<translation id="6710594484020273272">&lt;Typ een zoekterm&gt;</translation>
<translation id="6711464428925977395">Er is iets mis met de proxyserver of het adres is onjuist.</translation>
<translation id="6727102863431372879">Instellen</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{geen}=1{1 item}other{# items}}</translation>
<translation id="674375294223700098">Onbekende fout met servercertificaat.</translation>
<translation id="6753269504797312559">Beleidswaarde</translation>
<translation id="6757797048963528358">De slaapstand van je apparaat is geactiveerd.</translation>
@@ -619,6 +685,8 @@
<translation id="6810899417690483278">Aanpassings-ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Kan regiogegevens niet laden</translation>
+<translation id="6825578344716086703">Je probeert <ph name="DOMAIN" /> te bereiken. De server heeft echter een certificaat geretourneerd dat een zwak ondertekeningsalgoritme (zoals SHA-1) gebruikt. Dit houdt in dat de betrouwbaarheidsverklaring van de server kan zijn vervalst. Het is mogelijk dat de server zelf een imitatie is (wellicht een server die je schade probeert te berokkenen).</translation>
+<translation id="6830728435402077660">Niet veilig</translation>
<translation id="6831043979455480757">Vertalen</translation>
<translation id="6839929833149231406">Gebied</translation>
<translation id="6874604403660855544">&amp;Opnieuw toevoegen</translation>
@@ -626,6 +694,7 @@
<translation id="6895330447102777224">Je creditcard is bevestigd</translation>
<translation id="6897140037006041989">User-agent</translation>
<translation id="6915804003454593391">Gebruiker:</translation>
+<translation id="6945221475159498467">Selecteren</translation>
<translation id="6948701128805548767">Selecteer een adres om ophaalmethoden en vereisten te bekijken</translation>
<translation id="6957887021205513506">Het certificaat van de server lijkt vals te zijn.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -634,15 +703,16 @@
<translation id="6973656660372572881">Zowel vaste proxyservers als een pac-script-URL worden gespecificeerd.</translation>
<translation id="6989763994942163495">Geavanceerde instellingen weergeven...</translation>
<translation id="7000990526846637657">Geen geschiedenisitems gevonden</translation>
-<translation id="7009986207543992532">Je probeert <ph name="DOMAIN" /> te bereiken, maar de server heeft een certificaat geretourneerd waarvan de geldigheidsperiode te lang is om betrouwbaar te zijn. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Voor je Google-account kunnen andere vormen van browsegeschiedenis beschikbaar zijn via <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Wachtwoorden</translation>
+<translation id="7050187094878475250">Je hebt geprobeerd <ph name="DOMAIN" /> te bereiken, maar de server heeft een certificaat gepresenteerd waarvan de geldigheidsperiode te lang is om betrouwbaar te zijn.</translation>
+<translation id="7053983685419859001">Blokkeren</translation>
<translation id="7064851114919012435">Contactgegevens</translation>
<translation id="7079718277001814089">Deze site bevat malware</translation>
<translation id="7087282848513945231">County</translation>
-<translation id="7088615885725309056">Ouder</translation>
<translation id="7090678807593890770">Zoek op Google naar <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Toegestaan door een extensie</translation>
<translation id="7119414471315195487">Andere tabbladen of programma's sluiten</translation>
<translation id="7129409597930077180">Kan niet verzenden naar dit adres. Selecteer een ander adres.</translation>
<translation id="7138472120740807366">Bezorgingsmethode</translation>
@@ -660,22 +730,18 @@
<translation id="7220786058474068424">Verwerken</translation>
<translation id="724691107663265825">De volgende website bevat malware</translation>
<translation id="724975217298816891">Geef de vervaldatum en CVC-code voor <ph name="CREDIT_CARD" /> op om je creditcardgegevens te updaten. Zodra je bevestigt, worden je creditcardgegevens gedeeld met deze site.</translation>
-<translation id="725866823122871198">Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van de computer (<ph name="DATE_AND_TIME" />) onjuist zijn.</translation>
+<translation id="7260504762447901703">Toegang intrekken</translation>
<translation id="7275334191706090484">Beheerde bladwijzers</translation>
<translation id="7298195798382681320">Aanbevolen</translation>
<translation id="7309308571273880165">Crashrapport vastgelegd op <ph name="CRASH_TIME" /> (upload aangevraagd door gebruiker, nog niet geüpload)</translation>
<translation id="7334320624316649418">&amp;Opnieuw volgorde wijzigen</translation>
<translation id="733923710415886693">Het certificaat van de server is niet bekendgemaakt via Certificaattransparantie.</translation>
-<translation id="7351800657706554155">Je kunt <ph name="SITE" /> op dit moment niet bezoeken, omdat het bijbehorende certificaat is ingetrokken. Aangezien netwerkfouten en aanvallen meestal van tijdelijke aard zijn, werkt deze pagina later waarschijnlijk weer correct. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Opdrachtregel</translation>
<translation id="7372973238305370288">zoekresultaat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nee</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Creditcard bevestigen</translation>
-<translation id="7394102162464064926">Weet je zeker dat je deze pagina's wilt verwijderen uit je geschiedenis?
-
-De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /> te gebruiken.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Profielpad</translation>
<translation id="7424977062513257142">Een ingesloten pagina op deze webpagina meldt het volgende:</translation>
@@ -683,6 +749,7 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="7444046173054089907">Deze site is geblokkeerd</translation>
<translation id="7445762425076701745">De identiteit van de server waarmee je verbinding maakt, kan niet volledig worden geverifieerd. Je hebt verbinding gemaakt met een server die een naam gebruikt die alleen binnen je netwerk geldig is. Een externe certificeringsinstantie kan hiervoor nooit het eigendom verifiëren. Aangezien sommige certificeringsinstanties toch certificaten voor deze namen verlenen, kun je nooit zeker weten of je verbinding hebt met de bedoelde website en niet met een aanvaller.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /> over dit probleem.</translation>
+<translation id="7455133967321480974">Algemene standaardinstelling gebruiken (Blokkeren)</translation>
<translation id="7460163899615895653">Je recente tabbladen van andere apparaten worden hier weergegeven</translation>
<translation id="7469372306589899959">Creditcard bevestigen</translation>
<translation id="7481312909269577407">Vooruit</translation>
@@ -690,36 +757,43 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="7508255263130623398">Geretourneerde apparaat-ID voor beleid is leeg of komt niet overeen met de huidige apparaat-ID</translation>
<translation id="7514365320538308">Downloaden</translation>
<translation id="7518003948725431193">Er is geen webpagina gevonden voor het webadres: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Waarde</translation>
<translation id="7537536606612762813">Verplicht</translation>
+<translation id="7542403920425041731">Zodra je bevestigt, worden je creditcardgegevens gedeeld met deze site.</translation>
<translation id="7542995811387359312">Het automatisch invullen van creditcardnummers is uitgeschakeld, omdat dit formulier geen beveiligde verbinding gebruikt.</translation>
<translation id="7543525346216957623">Vraag het aan je ouder of voogd</translation>
<translation id="7549584377607005141">Deze webpagina kan alleen correct worden weergegeven op basis van gegevens die je eerder hebt opgegeven. Je kunt deze gegevens opnieuw verzenden, maar hierdoor worden de acties herhaald die eerder op deze pagina zijn uitgevoerd.</translation>
<translation id="7552846755917812628">Probeer de volgende tips:</translation>
<translation id="7554791636758816595">Nieuw tabblad</translation>
+<translation id="7567204685887185387">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server is mogelijk frauduleus verstrekt. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Deze pagina is geschreven in het<ph name="ORIGINAL_LANGUAGE" />Wil je deze laten vertalen?</translation>
<translation id="7569952961197462199">Creditcard verwijderen uit Chrome?</translation>
<translation id="7569983096843329377">Zwart</translation>
<translation id="7578104083680115302">Betaal op verschillende apparaten snel op sites en in apps met kaarten die je hebt opgeslagen via Google.</translation>
<translation id="7588950540487816470">Fysieke web</translation>
<translation id="7592362899630581445">Het certificaat van de server is in strijd met naambeperkingen.</translation>
+<translation id="7598391785903975535">Minder dan <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> kan dit verzoek momenteel niet verwerken.</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> nooit vertalen</translation>
<translation id="7610193165460212391">Waarde <ph name="VALUE" /> is buiten bereik.</translation>
<translation id="7613889955535752492">Vervaldatum: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Je hebt al gegevens die zijn gecodeerd met een andere versie van het wachtwoord voor je Google-account. Geef dit wachtwoord hieronder op.</translation>
-<translation id="7634554953375732414">Je verbinding met deze site is niet privé.</translation>
<translation id="7637571805876720304">Creditcard verwijderen uit Chromium?</translation>
<translation id="765676359832457558">Geavanceerde instellingen verbergen...</translation>
<translation id="7658239707568436148">Annuleren</translation>
+<translation id="7662298039739062396">Instelling beheerd door een extensie</translation>
<translation id="7667346355482952095">Geretourneerde beleidstoken is leeg of komt niet overeen met huidige token</translation>
<translation id="7668654391829183341">Onbekend apparaat</translation>
<translation id="7669271284792375604">Cybercriminelen op deze site proberen je mogelijk over te halen om programma's te installeren die schadelijk zijn voor de browsefunctionaliteit (door bijvoorbeeld je homepage te wijzigen of extra advertenties weer te geven op sites die je bezoekt).</translation>
<translation id="7674629440242451245">Ben je geïnteresseerd in nieuwe, coole Chrome-functies? Probeer ons ontwikkelaarskanaal op chrome.com/dev.</translation>
<translation id="7682287625158474539">Verzendadres</translation>
+<translation id="7701040980221191251">Geen</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Doorgaan naar <ph name="SITE" /> (onveilig)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificaat</translation>
+<translation id="7716147886133743102">Geblokkeerd door je beheerder</translation>
<translation id="7716424297397655342">Deze site kan niet worden geladen vanuit het cachegeheugen</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Niet-beheerd</translation>
<translation id="7755287808199759310">Je ouder of voogd kan de blokkering van deze site opheffen</translation>
<translation id="7758069387465995638">De verbinding is mogelijk geblokkeerd door de firewall of antivirussoftware.</translation>
@@ -746,15 +820,15 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="7951415247503192394">(32-bits)</translation>
<translation id="7956713633345437162">Mobiele bladwijzers</translation>
<translation id="7961015016161918242">Nooit</translation>
-<translation id="7962083544045318153">Crash-ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> altijd vertalen in het <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Niet opgegeven</translation>
<translation id="800218591365569300">Probeer andere tabbladen en programma's te sluiten om geheugen vrij te maken.</translation>
<translation id="8012647001091218357">We kunnen je ouders momenteel niet bereiken. Probeer het opnieuw.</translation>
<translation id="8025119109950072390">Cybercriminelen op deze site proberen je mogelijk te misleiden om iets gevaarlijks te doen, zoals software installeren of je persoonlijke gegevens bekendmaken (bijvoorbeeld wachtwoorden, telefoonnummers of creditcards).</translation>
-<translation id="803030522067524905">Google Safe Browsing heeft onlangs phishing gedetecteerd op <ph name="SITE" />. Phishingsites doen zich voor als een andere website om je te misleiden. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Deze pagina is in het <ph name="SOURCE_LANGUAGE" />. Vertalen naar het <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Vragen (standaard)</translation>
<translation id="8041089156583427627">Feedback verzenden</translation>
+<translation id="8041940743680923270">Algemene standaardinstelling gebruiken (Vragen)</translation>
<translation id="8088680233425245692">Kan artikel niet bekijken.</translation>
<translation id="8089520772729574115">minder dan 1 MB</translation>
<translation id="8091372947890762290">Activering is in behandeling op de server</translation>
@@ -763,13 +837,14 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="8134994873729925007">Het <ph name="BEGIN_ABBR" />DNS-adres<ph name="END_ABBR" /> van de server van <ph name="HOST_NAME" /> kan niet worden gevonden.</translation>
<translation id="8149426793427495338">De slaapstand van je computer is geactiveerd.</translation>
<translation id="8150722005171944719">Het bestand op <ph name="URL" /> is onleesbaar. Het bestand is mogelijk verwijderd of verplaatst of de bestandsrechten zorgen ervoor dat het bestand niet kan worden geopend.</translation>
+<translation id="8184538546369750125">Algemene standaardinstelling gebruiken (Toestaan)</translation>
+<translation id="8191494405820426728">Lokale crash-ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Verplaatsen ongedaan maken</translation>
<translation id="8201077131113104583">Ongeldige update-URL voor de extensie met de ID '<ph name="EXTENSION_ID" />'.</translation>
<translation id="8202097416529803614">Besteloverzicht</translation>
<translation id="8218327578424803826">Toegewezen locatie:</translation>
<translation id="8225771182978767009">De persoon die deze computer heeft geconfigureerd, heeft deze site geblokkeerd.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen mogelijk gevaarlijke programma's op je computer te installeren waarmee je gegevens kunnen worden gestolen of verwijderd (bijvoorbeeld foto's, wachtwoorden, berichten en creditcarddetails).</translation>
<translation id="8241707690549784388">De pagina die je zoekt, heeft informatie gebruikt die je hebt opgegeven Als je terugkeert naar deze pagina, worden acties die je hebt uitgevoerd, mogelijk herhaald. Wil je doorgaan?</translation>
<translation id="8249320324621329438">Laatst opgehaald:</translation>
<translation id="8253091569723639551">Factuuradres vereist</translation>
@@ -777,6 +852,7 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="8289355894181816810">Neem contact op met je netwerkbeheerder als je niet zeker weet wat dit betekent.</translation>
<translation id="8293206222192510085">Bladwijzer toevoegen</translation>
<translation id="8294431847097064396">Bron</translation>
+<translation id="8306404619377842860">Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van je apparaat (<ph name="DATE_AND_TIME" />) onjuist zijn. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">De vertaling is mislukt omdat er een probleem is opgetreden met de netwerkverbinding.</translation>
<translation id="8332188693563227489">Toegang tot <ph name="HOST_NAME" /> is geweigerd</translation>
<translation id="834457929814110454">Als je de beveiligingsrisico's begrijpt, kun je <ph name="BEGIN_LINK" />deze site bezoeken<ph name="END_LINK" /> voordat de schadelijke programma's zijn verwijderd.</translation>
@@ -797,11 +873,9 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="8483780878231876732">Log in bij Chrome om kaarten uit je Google-account te gebruiken</translation>
<translation id="8488350697529856933">Van toepassing op</translation>
<translation id="8498891568109133222">Het duurt te lang voordat <ph name="HOST_NAME" /> reageert.</translation>
-<translation id="852346902619691059">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door het besturingssysteem van je apparaat. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept. <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Vervaljaar</translation>
<translation id="8543181531796978784">Je kunt <ph name="BEGIN_ERROR_LINK" />een detectieprobleem melden<ph name="END_ERROR_LINK" />. Als je de veiligheidsrisico's begrijpt, kun je ook <ph name="BEGIN_LINK" />deze onveilige site bezoeken<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">De vertaling is mislukt omdat de taal van de pagina niet kan worden bepaald.</translation>
-<translation id="8559762987265718583">Er kan geen privéverbinding met <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tot stand worden gebracht, omdat de datum en tijd van je apparaat (<ph name="DATE_AND_TIME" />) onjuist zijn.</translation>
<translation id="8571890674111243710">Pagina wordt vertaald in het <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Telnr. toevoegen</translation>
<translation id="859285277496340001">Er wordt in het certificaat geen methode gespecificeerd waarmee kan worden gecontroleerd of het certificaat is ingetrokken.</translation>
@@ -815,6 +889,7 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="8738058698779197622">Als je een veilige verbinding tot stand wilt brengen, moet je klok goed zijn ingesteld. Dit moet omdat de certificaten die deze websites gebruiken om zichzelf te identificeren, slechts gedurende bepaalde perioden geldig zijn. Aangezien de klok van je apparaat niet goed is ingesteld, kan Chromium deze certificaten niet verifiëren.</translation>
<translation id="8740359287975076522">Het &lt;abbr id="dnsDefinition"&gt;DNS-adres&lt;/abbr&gt; van <ph name="HOST_NAME" /> kan niet worden gevonden. Er wordt een diagnose van het probleem uitgevoerd.</translation>
<translation id="8759274551635299824">Deze kaart is verlopen</translation>
+<translation id="8761567432415473239">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />schadelijke programma's gevonden<ph name="END_LINK" /> op <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Opnieuw verwijderen</translation>
<translation id="8800988563907321413">Je suggesties voor in de buurt worden hier weergegeven</translation>
<translation id="8820817407110198400">Bladwijzers</translation>
@@ -827,29 +902,30 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="8870413625673593573">Recent gesloten</translation>
<translation id="8874824191258364635">Geef een geldig kaartnummer op</translation>
<translation id="8876793034577346603">Netwerkconfiguratie kan niet worden geparseerd.</translation>
-<translation id="8877192140621905067">Zodra je bevestigt, worden je creditcardgegevens gedeeld met deze site</translation>
<translation id="8889402386540077796">Kleurtoon</translation>
<translation id="8891727572606052622">Ongeldige proxymodus.</translation>
<translation id="889901481107108152">Dit experiment is niet beschikbaar op je platform.</translation>
<translation id="8903921497873541725">Inzoomen</translation>
<translation id="8931333241327730545">Wil je deze kaart opslaan in je Google-account?</translation>
<translation id="8932102934695377596">Je klok loopt achter</translation>
-<translation id="8954894007019320973">(Vervolg)</translation>
<translation id="8971063699422889582">Het servercertificaat is verlopen.</translation>
<translation id="8986494364107987395">Automatisch gebruiksstatistieken en crashrapporten naar Google verzenden</translation>
-<translation id="8987927404178983737">Maand</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">De volgende site bevat schadelijke programma's</translation>
+<translation id="8997023839087525404">De server heeft een certificaat gepresenteerd dat niet openbaar bekend is gemaakt via het beleid voor Certificaattransparantie. Dit is voor bepaalde certificaten een vereiste om er zeker van te zijn dat ze betrouwbaar zijn en bescherming bieden tegen aanvallers.</translation>
<translation id="9001074447101275817">Voor de proxy <ph name="DOMAIN" /> zijn een gebruikersnaam en wachtwoord vereist.</translation>
+<translation id="9005998258318286617">Kan pdf-document niet laden</translation>
<translation id="901974403500617787">Markeringen die op het hele systeem van toepassing zijn, kunnen alleen worden ingesteld door de eigenaar: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Factuuradres voor creditcard vereist</translation>
<translation id="9020542370529661692">Deze pagina is vertaald naar het <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Beveiligingsfout</translation>
<translation id="9038649477754266430">Een voorspellingsservice gebruiken om pagina's sneller te laden</translation>
<translation id="9039213469156557790">Bovendien bevat deze pagina bronnen die niet beveiligd zijn. Deze bronnen kunnen tijdens verzending door anderen worden bekeken en kunnen door een aanvaller worden gewijzigd om het gedrag van de pagina aan te passen.</translation>
-<translation id="9040185888511745258">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> proberen je mogelijk over te halen om programma's te installeren die schadelijk zijn voor je surfervaring (door bijvoorbeeld je homepage te wijzigen of extra advertenties weer te geven op sites die je bezoekt).</translation>
+<translation id="9049981332609050619">Je probeert <ph name="DOMAIN" /> te bereiken, maar de server heeft een ongeldig certificaat geretourneerd.</translation>
<translation id="9050666287014529139">Wachtwoordzin</translation>
<translation id="9065203028668620118">Bewerken</translation>
<translation id="9068849894565669697">Kleur selecteren</translation>
+<translation id="9069693763241529744">Geblokkeerd door een extensie</translation>
<translation id="9076283476770535406">De site kan content voor volwassenen bevatten</translation>
<translation id="9078964945751709336">Meer informatie vereist</translation>
<translation id="9103872766612412690"><ph name="SITE" /> gebruikt gewoonlijk versleuteling om je gegevens te beschermen. Toen Chromium deze keer probeerde verbinding te maken met <ph name="SITE" />, retourneerde de website ongewone en onjuiste inloggegevens. Dit gebeurt wanneer een aanvaller probeert zich als <ph name="SITE" /> voor te doen of wanneer een wifi-inlogscherm de verbinding heeft verbroken. Je gegevens zijn nog steeds veilig omdat Chromium de verbinding heeft beëindigd voordat er gegevens konden worden uitgewisseld.</translation>
@@ -858,16 +934,21 @@ De volgende keer kan het handig zijn de incognitomodus <ph name="SHORTCUT_KEY" /
<translation id="9148507642005240123">&amp;Bewerken ongedaan maken</translation>
<translation id="9154194610265714752">Bijgewerkt</translation>
<translation id="9157595877708044936">Bezig met instellen...</translation>
+<translation id="9169664750068251925">Altijd blokkeren op deze site</translation>
<translation id="9170848237812810038">&amp;Ongedaan maken</translation>
<translation id="917450738466192189">Het servercertificaat is ongeldig.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> en nog <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> gebruikt een niet-ondersteund protocol.</translation>
<translation id="9205078245616868884">Je gegevens zijn versleuteld met je wachtwoordzin voor synchronisatie. Geef deze op om de synchronisatie te starten.</translation>
<translation id="9207861905230894330">Kan artikel niet toevoegen.</translation>
+<translation id="9219103736887031265">Afbeeldingen</translation>
<translation id="933612690413056017">Er is geen internetverbinding beschikbaar</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">FORMULIER LEEGMAKEN</translation>
<translation id="939736085109172342">Nieuwe map</translation>
<translation id="941721044073577244">Het lijkt erop dat je geen toestemming hebt om deze site te bezoeken</translation>
<translation id="969892804517981540">Officiële build</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Geen}=1{1 item}other{# items}}</translation>
<translation id="988159990683914416">Ontwikkelaarsbuild</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_no.xtb b/chromium/components/strings/components_strings_no.xtb
index 8b556a7a504..076896040ac 100644
--- a/chromium/components/strings/components_strings_no.xtb
+++ b/chromium/components/strings/components_strings_no.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Rotér med klokken</translation>
<translation id="1038842779957582377">ukjent navn</translation>
<translation id="1050038467049342496">Lukk andre apper</translation>
-<translation id="1053591932240354961">Du kan ikke gå til <ph name="SITE" /> akkurat nå, fordi nettstedet sendte kryptert legitimasjon som Google Chrome ikke kan behandle. Nettverksfeil og -angrep er som regel kortvarige, så denne siden fungerer nok igjen senere. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Angre tilleggingen</translation>
<translation id="10614374240317010">Aldri lagret</translation>
<translation id="106701514854093668">Bokmerker på datamaskinen</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Bufferen for enhetsinnstillinger er OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> sier:</translation>
<translation id="1132774398110320017">Innstillinger for autofyll i Chrome</translation>
+<translation id="1150979032973867961">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren er ikke klarert av datamaskinens operativsystem. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
+<translation id="1151972924205500581">Passord er påkrevd</translation>
<translation id="1152921474424827756">Ã…pne en <ph name="BEGIN_LINK" />bufret kopi<ph name="END_LINK" /> av <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> avsluttet tilkoblingen uventet.</translation>
<translation id="1161325031994447685">Koble til Wi-Fi på nytt</translation>
+<translation id="1165039591588034296">Feil</translation>
<translation id="1175364870820465910">&amp;Skriv ut...</translation>
<translation id="1181037720776840403">Fjern</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Rapportér<ph name="END_WHITEPAPER_LINK" /> automatisk detaljer om mulige sikkerhetsbrudd til Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Mer fra dette nettstedet</translation>
<translation id="1206967143813997005">Ugyldig start på signaturen</translation>
<translation id="1209206284964581585">Skjul for øyeblikket</translation>
+<translation id="121201262018556460">Du forsøkte å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat som inneholder en svak nøkkel. En angriper kan ha løst den private nøkkelen, og tjeneren er kanskje ikke den tjeneren du forventet (det kan hende at du kommuniserer med en angriper).</translation>
<translation id="1219129156119358924">Systemsikkerhet</translation>
<translation id="1227224963052638717">Ukjent innstilling.</translation>
<translation id="1227633850867390598">Skjul verdien</translation>
<translation id="1228893227497259893">Feil enhetsidentifikator</translation>
<translation id="1232569758102978740">Uten tittel</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" /> og <ph name="TYPE_2" /> (synkronisert)</translation>
<translation id="1263231323834454256">Leseliste</translation>
<translation id="1264126396475825575">Programstopprapport fra <ph name="CRASH_TIME" /> (ignorert eller ikke lastet opp ennå)</translation>
+<translation id="1281526147609854549">Utstedt av <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Farlig innhold er blokkert</translation>
<translation id="1285320974508926690">Oversett aldri dette nettstedet</translation>
<translation id="129553762522093515">Nylig lukket</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Prøv å slette informasjonskapslene dine<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Aktiviteten din <ph name="BEGIN_EMPHASIS" />kan fortsatt være synlig<ph name="END_EMPHASIS" /> for
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />nettsteder du besøker
+ <ph name="LIST_ITEM" />arbeidsgiveren eller skolen din
+ <ph name="LIST_ITEM" />Internett-leverandøren din
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Registreringsdomene:</translation>
<translation id="1340482604681802745">Henteadresse</translation>
<translation id="1344211575059133124">Det ser ut til at du trenger tillatelse for å besøke dette nettstedet</translation>
<translation id="1344588688991793829">Innstillinger for autofyll i Chromium</translation>
+<translation id="1348198688976932919">Nettstedet du er på vei til, inneholder farlige apper</translation>
<translation id="1374468813861204354">forslagene</translation>
<translation id="1375198122581997741">Om versjon</translation>
<translation id="1377321085342047638">Kortnummer</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> sendte ingen data.</translation>
<translation id="1407135791313364759">Ã…pne alle</translation>
<translation id="1413809658975081374">Personvernfeil</translation>
+<translation id="14171126816530869">Identiteten til <ph name="ORGANIZATION" /> på <ph name="LOCALITY" /> er verifisert av <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Skriv ut</translation>
-<translation id="1442912890475371290">Blokkerte forsøket <ph name="BEGIN_LINK" /> på å besøke en side på <ph name="DOMAIN" /><ph name="END_LINK" /></translation>
-<translation id="1491663344921578213">Du kan ikke gå til <ph name="SITE" /> akkurat nå, fordi nettstedet bruker sertifikatfesting. Nettverksfeil og -angrep er som regel kortvarige, så denne siden fungerer nok igjen senere. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> til}other{<ph name="PAYMENT_METHOD_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> til}}</translation>
<translation id="1506687042165942984">Vis en lagret kopi av denne siden (dvs. en kopi du vet at er utdatert).</translation>
<translation id="1517433312004943670">Det kreves et telefonnummer</translation>
<translation id="1519264250979466059">Versjonsdato</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Denne funksjonen kan ikke brukes når JavaScript er slått av.</translation>
<translation id="1555130319947370107">Blå</translation>
<translation id="1559528461873125649">Finner ingen slik fil eller katalog</translation>
-<translation id="1559572115229829303">&lt;p&gt;Vi kan ikke opprette noen privat tilkobling til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, fordi datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) på enheten din er feil.&lt;/p&gt;
-
- &lt;p&gt;Juster datoen og klokkeslettet under &lt;strong&gt;Generelt&lt;/strong&gt; i &lt;strong&gt;Innstillinger&lt;/strong&gt;-appen.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Noe gikk galt under åpningen av denne nettsiden.</translation>
<translation id="1592005682883173041">Tilgang til lokale data</translation>
+<translation id="1594030484168838125">Velg</translation>
<translation id="161042844686301425">Cyan</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Vil du at Chrome skal lagre dette kortet?</translation>
<translation id="1639239467298939599">Laster inn</translation>
<translation id="1640180200866533862">Brukerretningslinjer</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Nettverkskonfigurasjonen er ugyldig og kan ikke importeres.</translation>
<translation id="1644574205037202324">Logg</translation>
<translation id="1645368109819982629">Protokollen støttes ikke</translation>
+<translation id="1655462015569774233">{1,plural, =1{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet utløp i går. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen mellom deg og nettstedet. Klokken på datamaskinen din er stilt til <ph name="CURRENT_DATE" />. Er det riktig? Hvis ikke bør du stille klokken på systemet og laste inn denne siden på nytt.}other{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet utløp for # dager siden. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen mellom deg og nettstedet. Klokken på datamaskinen din er stilt til <ph name="CURRENT_DATE" />. Er det riktig? Hvis ikke bør du stille klokken på systemet og laste inn denne siden på nytt.}}</translation>
<translation id="1656489000284462475">Henting</translation>
<translation id="1663943134801823270">Kortene og adressene er fra Chrome. Du kan administrere dem i <ph name="BEGIN_LINK" />Innstillinger<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> bruker vanligvis kryptering for å beskytte informasjonen din. Da Chrome prøvde å koble til <ph name="SITE" /> denne gangen, sendte nettstedet tilbake uvanlig og feil legitimasjon. Dette kan skje hvis en angriper prøver å utgi seg for å være <ph name="SITE" />, eller hvis en Wi-Fi-påloggingsskjerm har avbrutt tilkoblingen. Informasjonen din er likevel sikker fordi Chrome stoppet tilkoblingen før det ble utvekslet noen data.</translation>
-<translation id="168328519870909584">Hackere som for øyeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, prøver kanskje å installere farlige apper på enheten din. Disse appene kan stjele eller slette informasjonen din (for eksempel bilder, passord, meldinger og kredittkortinformasjon).</translation>
<translation id="168841957122794586">Tjenersertifikatet inneholder en svak kryptografisk nøkkel.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ser ut til å være fra i morgen. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen mellom deg og nettstedet.}other{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ser ut til å være fra # dager frem i tid. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen mellom deg og nettstedet.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Du trenger tillatelse fra <ph name="NAME" /> for å besøke dette nettstedet</translation>
<translation id="1721424275792716183">* Feltet er obligatorisk</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Last ned siden senere</translation>
<translation id="17513872634828108">Ã…pne faner</translation>
<translation id="1753706481035618306">Sidenummer</translation>
+<translation id="1763864636252898013">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren er ikke klarert av enhetens operativsystem. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Prøv å kjøre Windows Nettverksdiagnose<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Oppdater passordfrasen for synkronisering.</translation>
<translation id="1787142507584202372">De åpne fanene dine vises her</translation>
+<translation id="1789575671122666129">Forgrunnsvinduer</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Kortinnehaverens navn</translation>
-<translation id="1803678881841855883">Google Safe Browsing oppdaget nylig <ph name="BEGIN_LINK" />skadelig programvare<ph name="END_LINK" /> på <ph name="SITE" />. Nettsteder som vanligvis er pålitelige, kan av og til bli infisert med skadelig programvare. Det skadelige innholdet kommer fra <ph name="SUBRESOURCE_HOST" />, som er en kjent distributør av skadelig programvare. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Lagt til: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Ugyldig forespørsel eller forespørselsparametere</translation>
<translation id="1826516787628120939">Kontrollerer</translation>
<translation id="1834321415901700177">Dette nettstedet inneholder skadelige programmer</translation>
+<translation id="1840414022444569775">Dette kortnummeret er brukt allerede</translation>
<translation id="1842969606798536927">Betal</translation>
<translation id="1871208020102129563">Mellomtjeneren er angitt til å bruke statiske proxytjenere, ikke en nettadresse med .pac-skript.</translation>
<translation id="1871284979644508959">Obligatorisk felt</translation>
<translation id="187918866476621466">Ã…pne oppstartssidene</translation>
<translation id="1883255238294161206">Skjul liste</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> til}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> til}}</translation>
<translation id="1898423065542865115">Filtrering</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ingen}=1{1 nettsted}other{# nettsteder}}</translation>
<translation id="194030505837763158">GÃ¥ til <ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" />-bokmerker</translation>
<translation id="1973335181906896915">Serialiseringsfeil</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorert fordi det ble overstyrt av <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Leter etter Fysisk nett-sider i nærheten</translation>
<translation id="213826338245044447">Bokmerker for mobil</translation>
-<translation id="2148716181193084225">I dag</translation>
+<translation id="2147827593068025794">Bakgrunnssynkronisering</translation>
<translation id="2154054054215849342">Synkronisering er ikke tilgjengelig for domenet ditt</translation>
<translation id="2154484045852737596">Endre kortet</translation>
<translation id="2166049586286450108">Full administratortilgang</translation>
<translation id="2166378884831602661">Dette nettstedet tilbyr ikke sikre tilkoblinger</translation>
<translation id="2181821976797666341">Retningslinjer</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresse}other{# adresser}}</translation>
+<translation id="2187317261103489799">Oppdag (standard)</translation>
<translation id="2202020181578195191">Angi et gyldig utløpsår</translation>
<translation id="2212735316055980242">Innstillingene ble ikke funnet</translation>
<translation id="2213606439339815911">Henter oppføringer …</translation>
+<translation id="2218879909401188352">Angripere som for øyeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, kan installere farlige apper som skader enheten din, legge til skjulte belastninger på mobilregningen din eller stjele personopplysningene dine. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Løs tilkoblingsproblemene med <ph name="BEGIN_LINK" />diagnostikkappen<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Send nå</translation>
<translation id="225207911366869382">Denne verdien er foreldet for denne innstillingen.</translation>
<translation id="2262243747453050782">HTTP-feil</translation>
+<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2282872951544483773">Utilgjengelige eksperimenter</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element}other{<ph name="ITEM_COUNT" /> elementer}}</translation>
<translation id="2292556288342944218">Internett-tilgangen din er blokkert</translation>
<translation id="230155334948463882">Nytt kort?</translation>
-<translation id="2305919008529760154">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet kan ha blitt utstedt på uredelig vis. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> krever brukernavn og passord.</translation>
-<translation id="2318774815570432836">Du kan ikke gå til <ph name="SITE" /> akkurat nå, fordi nettstedet bruker HSTS. Nettverksfeil og -angrep er som regel kortvarige, så denne siden fungerer nok igjen senere. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Innstillingen kontrolleres av administratoren din</translation>
<translation id="2354001756790975382">Andre bokmerker</translation>
+<translation id="2354430244986887761">Google Safe Browsing har nylig <ph name="BEGIN_LINK" />funnet skadelige apper<ph name="END_LINK" /> på <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Angripere kan kanskje se bildene du ser på dette nettstedet, og lure deg ved å endre dem.</translation>
+<translation id="2356070529366658676">Spør</translation>
+<translation id="2359629602545592467">Flere</translation>
<translation id="2359808026110333948">Fortsett</translation>
<translation id="2365563543831475020">Programstopprapporten fra <ph name="CRASH_TIME" /> ble ikke lastet opp</translation>
<translation id="2367567093518048410">Nivå</translation>
-<translation id="2371153335857947666">{1,plural, =1{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet utløp i går. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. Klokken på datamaskinen din er stilt til <ph name="CURRENT_DATE" />. Er det riktig? Hvis ikke bør du stille klokken på systemet og laste inn denne siden på nytt. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.}other{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet utløp for # dager siden. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. Klokken på datamaskinen din er stilt til <ph name="CURRENT_DATE" />. Er det riktig? Hvis ikke bør du stille klokken på systemet og laste inn denne siden på nytt. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Det er ingen tilgjengelige alternativer for brukergrensesnitt</translation>
<translation id="2384307209577226199">Bedriftsstandard</translation>
<translation id="2386255080630008482">Tjenerens sertifikat er tilbakekalt.</translation>
<translation id="2392959068659972793">Vis innstillinger uten verdi</translation>
<translation id="239429038616798445">Denne leveringsmetoden er ikke tilgjengelig. Prøv en annen metode.</translation>
<translation id="2396249848217231973">&amp;Angre slettingen</translation>
-<translation id="2460160116472764928">Google Safe Browsing oppdaget nylig <ph name="BEGIN_LINK" />skadelig programvare<ph name="END_LINK" /> på <ph name="SITE" />. Nettsteder som vanligvis er pålitelige, kan av og til bli infisert med skadelig programvare. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Tjenerens sikkerhetssertifikat kan være trukket tilbake. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
<translation id="2463739503403862330">Fyll ut</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Kjør Nettverksdiagnose<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Ugyldig nettadresse for søk.</translation>
+<translation id="2482878487686419369">Varsler</translation>
<translation id="2491120439723279231">Tjenerens sertifikat inneholder feil.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2495093607237746763">Hvis det er merket av for dette alternativet, lagrer Chromium en kopi av kortet ditt på denne enheten, slik at det går raskere å fylle ut skjemaer.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">GÃ¥ tilbake</translation>
<translation id="2515629240566999685">Sjekk signalet i området ditt</translation>
<translation id="2516305470678292029">Alternativer for brukergrensesnitt</translation>
+<translation id="2539524384386349900">Oppdag</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> sendte et ugyldig svar.</translation>
-<translation id="2552545117464357659">Nyere</translation>
<translation id="2556876185419854533">&amp;Angre endringen</translation>
<translation id="2587730715158995865">Fra <ph name="ARTICLE_PUBLISHER" />. Les denne og <ph name="OTHER_ARTICLE_COUNT" /> andre nyhetssaker.</translation>
<translation id="2587841377698384444">ID for katalog-API:</translation>
<translation id="2597378329261239068">Dette dokumentet er passordbeskyttet. Skriv inn et passord.</translation>
<translation id="2609632851001447353">Varianter</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ingen}=1{1 app ($1)}=2{2 apper ($1, $2)}other{# apper ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Klokken går for fort</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Tilgang til filen ble nektet</translation>
<translation id="2653659639078652383">Send</translation>
<translation id="2666117266261740852">Lukk andre faner eller apper</translation>
+<translation id="2670429602441959756">Denne siden inneholder funksjoner som ikke støttes i VR ennå. Avslutter …</translation>
<translation id="2674170444375937751">Er du sikker på at du vil slette disse sidene fra loggen?</translation>
<translation id="2677748264148917807">GÃ¥ ut</translation>
-<translation id="269990154133806163">Tjeneren presenterte et sertifikat som ikke er offentlig vist i henhold til retningslinjene for sertifikatåpenhet. Dette er et krav for enkelte sertifikater, for å sikre at de er pålitelige, og bidrar til å beskytte mot angrep. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Leseliste</translation>
<translation id="2704283930420550640">Verdien samsvarer ikke med formatet.</translation>
<translation id="2704951214193499422">Chromium kunne ikke bekrefte kortet ditt akkurat nå. Prøv igjen senere.</translation>
<translation id="2705137772291741111">Den lagrede (bufrede) kopien av dette nettstedet kunne ikke leses.</translation>
<translation id="2709516037105925701">Autofyll</translation>
-<translation id="2712118517637785082">Du prøvde å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat som er trukket tilbake av utstederen. Dette innebærer at sikkerhetsinformasjonen tjeneren presenterte, ikke er klarert. Det kan hende at du kommuniserer med en angriper. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Be om tillatelse</translation>
<translation id="2713444072780614174">Hvit</translation>
<translation id="2720342946869265578">Like ved</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Manglende enhetsoppføring</translation>
<translation id="2784949926578158345">Tilkoblingen ble tilbakestilt.</translation>
<translation id="2794233252405721443">Nettstedet er blokkert</translation>
+<translation id="2799020568854403057">Nettstedet du er på vei til, inneholder skadelige apper</translation>
+<translation id="2803306138276472711">Google Safe Browsing oppdaget nylig <ph name="BEGIN_LINK" />skadelig programvare<ph name="END_LINK" /> på <ph name="SITE" />. Nettsteder som vanligvis er sikre, kan noen ganger være infisert av skadelig programvare.</translation>
<translation id="2824775600643448204">Adresse- og søkefelt</translation>
<translation id="2826760142808435982">Tilkoblingen er kryptert ved hjelp av <ph name="CIPHER" />, og bruker <ph name="KX" /> som mekanisme for nøkkelutveksling.</translation>
<translation id="2835170189407361413">Slett skjemaet</translation>
+<translation id="2856444702002559011">Det kan hende at angripere prøver å stjele informasjonen din fra <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (for eksempel passord, meldinger og kredittkortinformasjon). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ikke last inn på nytt</translation>
<translation id="2900469785430194048">Google Chrome gikk tom for minne under forsøket på å vise denne nettsiden.</translation>
<translation id="2909946352844186028">En nettverksendring ble oppdaget.</translation>
<translation id="2916038427272391327">Lukk andre programmer</translation>
<translation id="2922350208395188000">Tjenerens sertifikat kan ikke kontrolleres.</translation>
<translation id="2928905813689894207">Faktureringsadresse</translation>
+<translation id="2941952326391522266">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Tjenerens sikkerhetssertifikat er fra <ph name="DOMAIN2" />. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
<translation id="2948083400971632585">PÃ¥ innstillingssiden kan du deaktivere eventuelle mellomtjenere for tilkoblinger.</translation>
<translation id="2955913368246107853">Lukk søkefelt</translation>
<translation id="2958431318199492670">Nettverkskonfigurasjonen overholder ikke ONC-standarden. Deler av konfigurasjonen kan muligens ikke importeres.</translation>
-<translation id="29611076221683977">Hackere som for øyeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> prøver kanskje å installere farlige programmer på Mac-en din. Disse programmene kan stjele eller slette informasjonen din (for eksempel bilder, passord, e-post og kredittkortinformasjon).</translation>
<translation id="2966678944701946121">Utløper: <ph name="EXPIRATION_DATE_ABBR" />. Lagt til: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Klokken må være riktig stilt før du kan opprette sikre tilkoblinger. Grunnen til dette er at sertifikatene nettsteder identifiserer seg med, bare er gyldige i visse tidsperioder. Ettersom klokken på enheten din er feil, kan ikke Google Chrome bekrefte disse sertifikatene.</translation>
<translation id="2972581237482394796">Gjø&amp;r om</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Angi en gyldig adresse</translation>
<translation id="2986368408720340940">Denne hentemetoden er ikke tilgjengelig. Prøv en annen metode.</translation>
<translation id="2991174974383378012">Deling med nettsteder</translation>
+<translation id="2991571918955627853">Du kan ikke gå til <ph name="SITE" /> akkurat nå, siden nettstedet bruker HSTS. Nettverksfeil og -angrep er vanligvis midlertidige, så denne siden fungerer sannsynligvis senere.</translation>
<translation id="3005723025932146533">Vis lagret kopi</translation>
<translation id="3008447029300691911">Skriv inn verifiseringskoden for <ph name="CREDIT_CARD" />. NÃ¥r du bekrefter, deles kortinformasjonen din med dette nettstedet.</translation>
<translation id="3010559122411665027">Listeoppføring «<ph name="ENTRY_INDEX" />»: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatisk blokkert</translation>
<translation id="3024663005179499861">Feil type enhetsinnstillinger</translation>
<translation id="3032412215588512954">Vil du laste inn dette nettstedet på nytt?</translation>
<translation id="3037605927509011580">Æsj!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{minst 1 element på synkroniserte enheter}=1{1 element (og flere på synkroniserte enheter)}other{# elementer (og flere på synkroniserte enheter)}}</translation>
<translation id="3041612393474885105">Sertifikatinformasjon</translation>
<translation id="3063697135517575841">Chrome kunne ikke bekrefte kortet ditt akkurat nå. Prøv igjen senere.</translation>
<translation id="3064966200440839136">Går ut av inkognitomodus for å betale via en ekstern app. Vil du fortsette?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ingen}=1{1 passord}other{# passord}}</translation>
<translation id="3093245981617870298">Du er ikke tilkoblet Internett.</translation>
<translation id="3105172416063519923">Ressurs-ID:</translation>
<translation id="3109728660330352905">Du har ikke autorisasjon til å se denne siden.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Prøv å kjøre Tilkoblingsdiagnostikk<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Kunne ikke avkode responsen</translation>
<translation id="3150653042067488994">Midlertidig tjenerfeil</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Sider du går til i inkognitofaner, blir ikke værende i nettleserloggen, lageret for informasjonskapsler eller søkeloggen etter at du har lukket alle inkognitofanene. Filer du laster ned eller bokmerker du oppretter, blir lagret.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Øy</translation>
+<translation id="317583078218509884">Nye nettstedinnstillinger trer i kraft etter at siden er lastet inn på nytt.</translation>
<translation id="3176929007561373547">Sjekk innstillingene for proxy-tjeneren eller kontakt nettverksadministratoren
for å forsikre deg om at den fungerer. Følg disse instruksjonene hvis du
ikke tror du trenger å bruke noen proxy-tjener:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Ã…pne siden i inkognitomodus</translation>
-<translation id="3202578601642193415">Nyeste</translation>
+<translation id="320323717674993345">Avbryt betalingen</translation>
<translation id="3207960819495026254">Bokmerket</translation>
+<translation id="3225919329040284222">Tjeneren oppga et sertifikat som ikke samsvarte med innebygde forventninger. Disse forventningene benyttes for visse nettsteder med høy sikkerhet, og brukes for å beskytte deg.</translation>
<translation id="3226128629678568754">Trykk på knappen for å laste inn på nytt, for å sende inn dataene som trengs for å laste inn siden på nytt.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Oversettelsen mislyktes fordi siden allerede er på <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Skriv inn verifiseringskoden for <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Oppdag alltid viktig innhold på dette nettstedet</translation>
<translation id="3254409185687681395">Legg til bokmerke for denne siden</translation>
<translation id="3270847123878663523">&amp;Angre omorganiseringen</translation>
<translation id="3282497668470633863">Legg til navnet på kortet</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">innstillinger</translation>
<translation id="3345135638360864351">Forespørselen om tilgang til dette nettstedet kunne ikke sendes til <ph name="NAME" />. Prøv igjen.</translation>
<translation id="3355823806454867987">Endre innstillinger for mellomtjener</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />lagrer ikke<ph name="END_EMPHASIS" />
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />nettleserloggen din
+ <ph name="LIST_ITEM" />informasjonskapsler og nettstedsdata
+ <ph name="LIST_ITEM" />informasjon du skriver inn i skjemaer
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Klokkefeil</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> varer til …</translation>
<translation id="337363190475750230">Godkjenningen er opphevet</translation>
<translation id="3377188786107721145">Feil under analysen av enhetsinnstillinger</translation>
<translation id="3380365263193509176">Ukjent feil</translation>
<translation id="3380864720620200369">Klient-ID:</translation>
<translation id="3391030046425686457">Leveringsadresse</translation>
<translation id="3395827396354264108">Hentemetode</translation>
-<translation id="340013220407300675">Angripere prøver kanskje å stjele informasjonen din fra <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (for eksempel passord, e-post eller kredittkort).</translation>
<translation id="3422248202833853650">Prøv å lukke andre programmer for å frigjøre minne.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> er ikke tilgjengelig for øyeblikket.</translation>
+<translation id="3427092606871434483">Tillat (standard)</translation>
<translation id="3427342743765426898">&amp;Endre likevel</translation>
<translation id="3431636764301398940">Lagre dette kortet på denne enheten</translation>
<translation id="3435896845095436175">Slå på</translation>
<translation id="3447661539832366887">Eieren av denne enheten har slått av dinosaurspillet.</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">Hentingsintervall:</translation>
<translation id="3462200631372590220">Skjul detaljer</translation>
<translation id="3467763166455606212">Kortinnhaverens navn er obligatorisk</translation>
<translation id="3478058380795961209">Utløpsmåned</translation>
<translation id="3479539252931486093">Var dette uventet? <ph name="BEGIN_LINK" />Si fra til oss<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ikke nå</translation>
-<translation id="348000606199325318">Kræsj-ID <ph name="CRASH_LOCAL_ID" /> (Tjener-ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Vi kunne ikke nå foreldrene dine akkurat nå. Prøv igjen.</translation>
<translation id="3528171143076753409">Tjenerens sertifikat er ikke pålitelig.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Minst 1 element på synkroniserte enheter}=1{1 element (og flere på synkroniserte enheter)}other{# elementer (og flere på synkroniserte enheter)}}</translation>
<translation id="3539171420378717834">Lagre en kopi av dette kortet på denne enheten</translation>
<translation id="3542684924769048008">Bruk passord for:</translation>
+<translation id="3545341443414427877">Det kan ikke opprettes noen privat tilkobling til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, siden datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) på datamaskinen du bruker, er feil. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Kryptér alle synkroniserte data med din egen passordfrase for synkronisering</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> flere</translation>
-<translation id="3555561725129903880">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet tilhører <ph name="DOMAIN2" />. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Administratoren din kan oppheve blokkeringen for deg</translation>
<translation id="3566021033012934673">Tilkoblingen din er ikke privat</translation>
+<translation id="3569145463236695319">&lt;p&gt;Det kan ikke opprettes noen privat tilkobling til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, siden datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) på enheten du bruker, er feil.&lt;/p&gt;
+
+ &lt;p&gt;Endre datoen og klokkeslettet under &lt;strong&gt;Generelt&lt;/strong&gt; i &lt;strong&gt;Innstillinger&lt;/strong&gt;-appen.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" />, <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Legg til navn</translation>
<translation id="3583757800736429874">&amp;Flytt likevel</translation>
<translation id="3586931643579894722">Skjul detaljer</translation>
-<translation id="3587482841069643663">Alle</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Angi en gyldig utløpsdato</translation>
<translation id="36224234498066874">Slett nettlesingsdata...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Sertifikatinformasjon</translation>
<translation id="3690164694835360974">PÃ¥loggingen er ikke trygg</translation>
<translation id="3693415264595406141">Passord:</translation>
-<translation id="3696411085566228381">ingen</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Laster inn ...</translation>
<translation id="3712624925041724820">Lisensene er oppbrukt</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Sjekk proxy-tjener-, brannmur- og DNS-konfigurasjonen<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Hvis du forstår sikkerhetsrisikoen, kan du <ph name="BEGIN_LINK" />gå til det usikre nettstedet<ph name="END_LINK" /> før de farlige programmene er fjernet.</translation>
<translation id="3739623965217189342">En link du kopierte</translation>
+<translation id="3744899669254331632">Du kan ikke gå til <ph name="SITE" /> akkurat nå, fordi nettstedet sendte kryptert legitimasjon som Chromium ikke kan behandle. Nettverksfeil og -angrep er vanligvis forbigående, så siden kommer sikkert til å virke senere.</translation>
+<translation id="3748148204939282805">Angripere på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan lure deg til å gjøre farlige ting, deriblant å installere programvare eller oppgi personopplysninger (for eksempel passord, telefonnumre og kredittkortinformasjon). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Oversettelsen mislyktes på grunn av en tjenerfeil.</translation>
<translation id="3759461132968374835">Du har ingen nylig rapportert programstopp. Programstopp som inntraff når rapportering om programstopp var deaktivert, blir ikke vist her.</translation>
+<translation id="3778403066972421603">Vil du lagre dette kortet i Google-kontoen din og på denne enheten?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Utløper <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Hvis du bruker en mellomtjener...</translation>
<translation id="3828924085048779000">Tom passordfrase er ikke tillatt.</translation>
-<translation id="3845539888601087042">Viser loggen fra enhetene du er logget på. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Tilbake</translation>
<translation id="3858027520442213535">Oppdater dato og klokkeslett</translation>
<translation id="3884278016824448484">Motstridende enhetsidentifikator</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Forespørselen din om å få tilgang til dette nettstedet er sendt til <ph name="NAME" /></translation>
<translation id="3890664840433101773">Legg til e-post</translation>
<translation id="3901925938762663762">Kortet er utløpt</translation>
-<translation id="3933571093587347751">{1,plural, =1{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ser ut til å være fra i morgen. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.}other{Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ser ut til å være fra # dager frem i tid. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Kan ikke laste inn PDF-dokument</translation>
+<translation id="3945915738023014686">ID-en for den opplastede programstopprapporten: <ph name="CRASH_ID" /> (lokal kræsj-ID: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Det er ikke angitt noen alternative emnenavn i tjenerens sikkerhetssertifikat. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
<translation id="3963721102035795474">Lesermodus</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ingen}=1{Fra 1 nettsted }other{Fra # nettsteder }}</translation>
<translation id="397105322502079400">Beregner …</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> er blokkert</translation>
+<translation id="3987940399970879459">Under 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 Like ved-nettside}other{# Like ved-nettsider}}</translation>
<translation id="4021036232240155012">DNS er nettverkstjenesten som oversetter navnene på nettsteder til Internett-adressene deres.</translation>
<translation id="4030383055268325496">&amp;Angre tilleggingen</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Konfigurasjonen av proxytjeneren er angitt til å bruke en nettadresse med .pac-skript, ikke statiske proxytjenere.</translation>
<translation id="4098354747657067197">Villedende nettsted i sikte</translation>
<translation id="4103249731201008433">Enhetens serienummer er ugyldig</translation>
+<translation id="410351446219883937">Autoavspilling</translation>
<translation id="4103763322291513355">Gå til &lt;strong&gt;chrome://policy&lt;/strong&gt; for å se listen over sperrede nettadresser og andre innstillinger aktivert av systemadministratoren din.</translation>
-<translation id="4110615724604346410">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet inneholder feil. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Tillat alltid på dette nettstedet</translation>
<translation id="4117700440116928470">Omfanget for innstillingen støttes ikke.</translation>
-<translation id="4118212371799607889">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ikke er regnet som pålitelig av Chromium. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 til}other{# til}}</translation>
<translation id="4130226655945681476">Sjekk nettverkskablene, modemet og ruteren</translation>
+<translation id="413544239732274901">Finn ut mer</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Bruk global standard (oppdag)</translation>
+<translation id="4165986682804962316">Nettstedsinnstillinger</translation>
<translation id="4169947484918424451">Vil du at Chromium skal lagre dette kortet?</translation>
<translation id="4171400957073367226">Ugyldig bekreftelsessignatur</translation>
<translation id="4196861286325780578">&amp;Flytt likevel</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Sjekk brannmur- og antiviruskonfigurasjonen<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ingen}=1{1 app ($1)}=2{2 apper ($1, $2)}other{# apper ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Kræsj</translation>
+<translation id="422022731706691852">Angripere på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan prøve å lure deg til å installere programmer som påvirker surfeopplevelsen din (for eksempel ved å endre startsiden eller vise ekstra annonser på nettsteder du går til). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Prøv å kjøre Nettverksdiagnose<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Gyldig</translation>
<translation id="4250431568374086873">Tilkoblingen til dette nettstedet er ikke helt sikker</translation>
<translation id="4250680216510889253">Nei</translation>
<translation id="425582637250725228">Det kan hende endringene dine ikke er lagret.</translation>
<translation id="4258748452823770588">DÃ¥rlig signatur</translation>
+<translation id="4265872034478892965">Tillatt av administratoren din</translation>
<translation id="4269787794583293679">(Uten brukernavn)</translation>
<translation id="4275830172053184480">Start enheten din på nytt</translation>
<translation id="4280429058323657511">, utløper <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google Safe Browsing fant nylig <ph name="BEGIN_LINK" />skadelige programmer<ph name="END_LINK" /> på <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Overordnede forslag</translation>
<translation id="4304224509867189079">Logg på</translation>
-<translation id="432290197980158659">Tjeneren presenterte et sertifikat som ikke samsvarer med innebygde forventninger. Disse forventningene benyttes for visse nettsteder med høy sikkerhet og brukes for å beskytte deg. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blokkér (standard)</translation>
<translation id="4325863107915753736">Artikkelen ble ikke funnet</translation>
<translation id="4326324639298822553">Kontrollér utløpsdatoen, og prøv igjen</translation>
<translation id="4331708818696583467">Ikke sikker</translation>
<translation id="4356973930735388585">Angripere på dette nettstedet kan prøve å installere farlige programmer på datamaskinen din. Disse kan stjele eller slette informasjonen din (for eksempel bilder, passord, e-post og kredittkortinformasjon).</translation>
<translation id="4372948949327679948">Forventet <ph name="VALUE_TYPE" />-verdi.</translation>
+<translation id="4377125064752653719">Du forsøkte å gå til <ph name="DOMAIN" />, men sertifikatet tjeneren presenterte har blitt trukket tilbake av utstederen. Dette innebærer at sikkerhetsinformasjonen tjeneren presenterte ikke er klarert. Det kan hende at du kommuniserer med en angriper.</translation>
<translation id="4381091992796011497">Brukernavn:</translation>
<translation id="4394049700291259645">Slå av</translation>
<translation id="4406896451731180161">søkeresultater</translation>
+<translation id="4424024547088906515">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren er ikke klarert av Chrome. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
<translation id="4432688616882109544">Enten godtok ikke <ph name="HOST_NAME" /> påloggingssertifikatet ditt, eller så ble det ikke oppgitt.</translation>
<translation id="443673843213245140">Bruk av mellomtjener er deaktivert, men det er angitt en uttrykkelig mellomtjenerkonfigurasjon.</translation>
-<translation id="4492190037599258964">Søkeresultater for «<ph name="SEARCH_STRING" />»</translation>
<translation id="4506176782989081258">Valideringsfeil: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Kontakt systemadministratoren</translation>
<translation id="450710068430902550">Deling med administratoren</translation>
<translation id="4515275063822566619">Kortene og adressene er fra Chrome og Google-kontoen din (<ph name="ACCOUNT_EMAIL" />). Du kan administrere dem i <ph name="BEGIN_LINK" />Innstillinger<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detaljer</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Prøv å slå av utvidelsene dine.</translation>
<translation id="457875822857220463">Levering</translation>
<translation id="4587425331216688090">Vil du fjerne adressen fra Chrome?</translation>
-<translation id="4589078953350245614">Du prøvde å gå til <ph name="DOMAIN" />, men tjeneren presenterte et ugyldig sertifikat. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Tilkoblingen til <ph name="DOMAIN" /> er kryptert med en moderne chifferserie.</translation>
<translation id="4594403342090139922">&amp;Angre slettingen</translation>
<translation id="4619615317237390068">Faner fra andre enheter</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren inneholder feil. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
+<translation id="4690462567478992370">Slutt å bruke et ugyldig sertifikat</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Tilkoblingen ble avbrutt</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Kjør Windows Nettverksdiagnose<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Det har oppstått en ukjent feil.</translation>
<translation id="4800132727771399293">Kontrollér utløpsdatoen og CVC-koden, og prøv igjen.</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Du kan ikke gå til <ph name="SITE" /> akkurat nå, fordi nettstedet sendte kryptert legitimasjon som Google Chrome ikke kan behandle. Nettverksfeil og -angrep er vanligvis forbigående, så siden kommer sikkert til å virke senere.</translation>
<translation id="4813512666221746211">Nettverksfeil</translation>
<translation id="4816492930507672669">Tilpass til siden</translation>
<translation id="483020001682031208">Det finnes ingen sider på det fysiske nettet å vise</translation>
<translation id="4850886885716139402">Visning</translation>
<translation id="4854362297993841467">Denne leveringsmetoden er ikke tilgjengelig. Prøv en annen metode.</translation>
<translation id="4858792381671956233">Du har spurt foreldrene dine om det er greit å besøke dette nettstedet</translation>
+<translation id="4863764087567530506">Dette innholdet kan prøve å lure deg til å installere programvare eller oppgi personopplysninger. <ph name="BEGIN_LINK" />Vis det likevel<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Søk i loggen</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{og 1 nettside til}other{og # nettsider til}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Denne siden er oversatt til <ph name="LANGUAGE_LANGUAGE" /> fra et ukjent språk</translation>
<translation id="4923459931733593730">Betaling</translation>
<translation id="4926049483395192435">MÃ¥ angis.</translation>
<translation id="495170559598752135">Handlinger</translation>
<translation id="4958444002117714549">Utvid liste</translation>
-<translation id="4962322354953122629">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom skkerhetssertifikatet ikke er regnet som pålitelig av Chrome. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Slå på advarsler på nytt</translation>
<translation id="4989809363548539747">Dette programtillegget støttes ikke</translation>
<translation id="5002932099480077015">Hvis du slår på dette alternativet, lagrer Chrome en kopi av kortet ditt på denne enheten, slik at det blir raskere å fylle ut skjemaer i fremtiden.</translation>
<translation id="5018422839182700155">Kan ikke åpne denne siden</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Kontrollér retningslinjene til administratoren din</translation>
<translation id="5029568752722684782">Slett kopi</translation>
<translation id="5031870354684148875">Om Google Oversett</translation>
+<translation id="5039804452771397117">Tillat</translation>
<translation id="5040262127954254034">Personvern</translation>
<translation id="5045550434625856497">Feil passord</translation>
<translation id="5056549851600133418">Artikler for deg</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Sjekk proxy-tjeneradressen<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Ingen informasjonskapsler}=1{1 nettsted bruker informasjonskapsler }other{# nettsteder bruker informasjonskapsler }}</translation>
<translation id="5087286274860437796">Sertifikatet til tjeneren er ikke gyldig for øyeblikket.</translation>
<translation id="5087580092889165836">Legg til et kort</translation>
<translation id="5089810972385038852">Fylke / delstat</translation>
+<translation id="5094747076828555589">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren er ikke klarert av Chromium. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
<translation id="5095208057601539847">Provins</translation>
<translation id="5115563688576182185">(64-bit)</translation>
<translation id="5141240743006678641">Kryptér synkroniserte passord med Google-legitimasjonen din</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-post er obligatorisk</translation>
<translation id="5251803541071282808">Nettsky</translation>
<translation id="5277279256032773186">Bruker du Chrome på jobben? Bedrifter kan administrere Chrome-innstillingene for de ansatte. Finn ut mer</translation>
+<translation id="5297526204711817721">Tilkoblingen til dette nettstedet er ikke privat. For å gå ut av VR-modus, fjern brillene og trykk på tilbake.</translation>
<translation id="5299298092464848405">Feil under analysen av enhetsinnstillingene</translation>
-<translation id="5300589172476337783">Vis</translation>
<translation id="5308689395849655368">Rapportering av programstopp er deaktivert.</translation>
<translation id="5317780077021120954">Lagre</translation>
<translation id="5327248766486351172">Navn</translation>
-<translation id="5337705430875057403">Angripere på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> prøver kanskje å lure deg til å gjøre farlige ting som å installere programvare eller avsløre personopplysningene dine (for eksempel passord, telefonnumre eller kredittkortinformasjon).</translation>
-<translation id="5359637492792381994">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ikke er gyldig for øyeblikket. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Du kan ikke gå til <ph name="SITE" /> akkurat nå, siden sertifikatet for nettstedet er trukket tilbake. Nettverksfeil- og angrep er vanligvis midlertidige, så denne siden fungerer sannsynligvis senere.</translation>
<translation id="536296301121032821">Kunne ikke lagre angivelsen for enhetsinnstillinger</translation>
<translation id="5386426401304769735">Sertifikatkjeden for dette nettstedet inneholder et sertifikat som er signert med SHA-1.</translation>
<translation id="5402410679244714488">Utløper: <ph name="EXPIRATION_DATE_ABBR" />. Sist brukt for over et år siden</translation>
+<translation id="540969355065856584">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren er ikke gyldig for øyeblikket. Dette kan være forårsaket av en feilkonfigurasjon eller en angriper som lytter på tilkoblingen din.</translation>
<translation id="5421136146218899937">Slett nettlesingsdata...</translation>
<translation id="5430298929874300616">Fjern bokmerke</translation>
<translation id="5431657950005405462">Filen ble ikke funnet</translation>
-<translation id="5435775191620395718">Viser loggen fra denne enheten. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Skjemavalideringsfeil i «<ph name="ERROR_PATH" />»: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Denne siden på <ph name="HOST_NAME" /> ble ikke funnet</translation>
<translation id="5455374756549232013">Feil tidsstempel for enhetsinnstillinger</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> av <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Ugyldig</translation>
<translation id="5470861586879999274">&amp;Endre likevel</translation>
<translation id="54817484435770891">Du må angi en gyldig adresse</translation>
<translation id="5492298309214877701">Dette nettstedet på selskapets, organisasjonens eller skolens intranett har samme nettadresse som et eksternt nettsted.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Kan ikke hente på denne adressen. Velg en annen adresse.</translation>
<translation id="5572851009514199876">Start og logg på Chrome, så Chrome kan sjekke om du har tillatelse til å gå til dette nettstedet.</translation>
<translation id="5580958916614886209">Kontrollér utløpsmåneden, og prøv igjen</translation>
+<translation id="5586446728396275693">Ingen adresser er lagret</translation>
+<translation id="5595485650161345191">Rediger adresse</translation>
<translation id="560412284261940334">Administrering støttes ikke</translation>
<translation id="5610142619324316209">Sjekk tilkoblingen</translation>
<translation id="5610807607761827392">Du kan administrere kort og adresser i <ph name="BEGIN_LINK" />Innstillinger<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Vil du forlate dette nettstedet?</translation>
<translation id="5629630648637658800">Kunne ikke laste in angivelsen for enhetsinnstillinger</translation>
<translation id="5631439013527180824">Ugyldig token for enhetsadministrering</translation>
+<translation id="5633066919399395251">Angripere som for øyeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, kan prøve å installere farlige programmer på datamaskinen du bruker, for å stjele eller slette informasjonen din (for eksempel bilder, passord, meldinger og kredittkortinformasjon). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Posisjon</translation>
+<translation id="5659593005791499971">E-post</translation>
<translation id="5669703222995421982">FÃ¥ innhold med et personlig preg</translation>
<translation id="5675650730144413517">Denne siden fungerer ikke</translation>
-<translation id="5677928146339483299">Blokkert</translation>
-<translation id="5694783966845939798">Du prøvde å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat som er signert med en usikker signaturalgoritme (som SHA-1). Dette betyr at sikkerhetslegitimasjonen tjeneren har presentert, kan være forfalsket. Tjeneren kan med andre ord være en annen tjener enn du tror (og du kommuniserer kanskje med en angriper). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Identiteten til dette nettstedet er ikke verifisert.</translation>
+<translation id="5713016350996637505">Villedende innhold er blokkert</translation>
<translation id="5720705177508910913">Gjeldende bruker</translation>
<translation id="5732392974455271431">Foreldrene dine kan oppheve blokkeringen for deg</translation>
<translation id="5763042198335101085">Angi en gyldig e-postadresse</translation>
<translation id="5765072501007116331">For å se leveringsmetoder og -krav, velg en adresse</translation>
+<translation id="5778550464785688721">Full kontroll av MIDI-enheter</translation>
<translation id="5784606427469807560">Det oppsto et problem under forsøket på å bekrefte kortet ditt. Kontrollér Internett-tilkoblingen din, og prøv igjen.</translation>
<translation id="5785756445106461925">Denne siden inneholder i tillegg andre ressurser som ikke er sikre. Disse ressursene er synlige for andre mens de sendes frem og tilbake, og eventuelle angripere kan modifisere dem for å endre på utseendet til siden.</translation>
<translation id="5786044859038896871">Vil du fylle ut kortinformasjonen?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Legg til likevel</translation>
<translation id="5814352347845180253">Det kan hende du mister tilgang til premium-innhold fra <ph name="SITE" /> og andre nettsteder.</translation>
<translation id="5838278095973806738">Du bør ikke oppgi sensitiv informasjon på dette nettstedet (for eksempel passord eller kredittkort) fordi den kan bli stjålet av angripere.</translation>
-<translation id="5843436854350372569">Du prøvde å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat som inneholder en usikker nøkkel. En angriper kan ha brutt sikkerheten i den private nøkkelen, og tjeneren er kanskje ikke den tjeneren du forventet (det kan hende at du kommuniserer med en angriper). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Dette nettstedet er ikke tilgjengelig</translation>
<translation id="5869522115854928033">Lagrede passord</translation>
<translation id="5872918882028971132">Overordnede forslag</translation>
<translation id="5901630391730855834">Gul</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synkronisert)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 er i bruk}other{# er i bruk}}</translation>
<translation id="5926846154125914413">Det kan hende du mister tilgang til premium-innhold fra enkelte nettsteder.</translation>
<translation id="5959728338436674663">Send automatisk noe <ph name="BEGIN_WHITEPAPER_LINK" />systeminformasjon og sideinnhold<ph name="END_WHITEPAPER_LINK" /> til Google for å bidra til å oppdage farlige apper og nettsteder. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Uke</translation>
<translation id="5967867314010545767">Fjern fra loggen</translation>
<translation id="5975083100439434680">Zoom ut</translation>
<translation id="598637245381783098">Kan ikke åpne betalingsappen</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Side 1}other{Side #}}</translation>
<translation id="6017514345406065928">Grønn</translation>
+<translation id="6017850046339264347">Angripere på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan installere villedende apper som ser ut til å være noe annet, eller samle inn data som kan brukes til å spore deg. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" /> og <ph name="TYPE_3" /> (synkronisert)</translation>
<translation id="6027201098523975773">Skriv inn et navn</translation>
<translation id="6040143037577758943">Lukk</translation>
<translation id="6042308850641462728">Mer</translation>
+<translation id="6047233362582046994">Hvis du forstår sikkerhetsrisikoen, kan du <ph name="BEGIN_LINK" />gå til dette nettstedet<ph name="END_LINK" /> før de skadelige appene er fjernet.</translation>
+<translation id="6051221802930200923">Du kan ikke gå til <ph name="SITE" /> akkurat nå, siden nettstedet bruker sertifikatfesting. Nettverksfeil og -angrep er vanligvis midlertidige, så denne siden fungerer sannsynligvis senere.</translation>
<translation id="6060685159320643512">Vær forsiktig. Disse eksperimentene kan bite</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ingen}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Du har åpnet innhold via et administratorlevert sertifikat. Data du sender til <ph name="DOMAIN" /> kan stoppes av administratoren din.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ingen}=1{1 passord (synkronisert)}other{# passord (synkronisert)}}</translation>
<translation id="6146055958333702838">Sjekk alle kabler, og start rutere, modemer eller andre nettverksenheter
du bruker, på nytt.</translation>
<translation id="614940544461990577">Prøv dette:</translation>
<translation id="6151417162996330722">Tjenersertifikatet har en gyldighetsperiode som er for lang.</translation>
<translation id="6157877588268064908">For å se fraktmetoder og -krav, velg en adresse</translation>
+<translation id="6158003235852588289">Google Safe Browsing oppdaget nylig nettfisking på <ph name="SITE" />. Nettsteder for nettfisking er laget for å ligne på andre nettsteder, for å prøve å lure deg.</translation>
<translation id="6165508094623778733">Les mer</translation>
+<translation id="6169916984152623906">NÃ¥ kan du surfe privat. Andre som bruker denne enheten, ser ikke aktiviteten din, men nedlastinger og bokmerker blir lagret.</translation>
<translation id="6177128806592000436">Tilkoblingen til dette nettstedet er ikke sikker</translation>
<translation id="6184817833369986695">(kohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Kontrollér Internett-tilkoblingen</translation>
<translation id="6218753634732582820">Vil du fjerne adressen fra Chromium?</translation>
+<translation id="6221345481584921695">Google Safe Browsing oppdaget nylig <ph name="BEGIN_LINK" />skadelig programvare<ph name="END_LINK" /> på <ph name="SITE" />. Nettsteder som vanligvis er trygge, kan noen ganger være infisert med skadelig programvare. Det skadelige innholdet kommer fra <ph name="SUBRESOURCE_HOST" />, som er en kjent distributør av skadelig programvare.</translation>
<translation id="6251924700383757765">Personvern</translation>
<translation id="6254436959401408446">Det er ikke nok minne til å åpne denne siden</translation>
<translation id="625755898061068298">Du har valgt å slå av sikkerhetsadvarsler for dette nettstedet.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Rediger bokmerket</translation>
<translation id="6410264514553301377">Skriv inn utløpsdatoen og verifiseringskoden for <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Du har spurt forelderen din om det er greit å besøke dette nettstedet</translation>
-<translation id="6416403317709441254">Du kan ikke gå til <ph name="SITE" /> akkurat nå fordi nettstedet sendte kryptert legitimasjon som Chromium ikke kan behandle. Nettverksfeil og -angrep er som regel kortvarige, så denne siden fungerer nok igjen senere. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Kan ikke kontrollere hvorvidt sertifikatet har blitt tilbakekalt.</translation>
<translation id="6433490469411711332">Endre kontaktinformasjonen</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> avviste tilkoblingsforsøket.</translation>
<translation id="6446608382365791566">Legg til mer informasjon</translation>
+<translation id="6447842834002726250">Informasjonskapsler</translation>
<translation id="6451458296329894277">Bekreft ny innsending av skjema</translation>
<translation id="6456339708790392414">Betalingen din</translation>
<translation id="6458467102616083041">Ignorert fordi standardsøk er deaktivert i henhold til retningslinje.</translation>
-<translation id="6462969404041126431">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet kan ha blitt trukket tilbake. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Enhetsinnstillinger</translation>
<translation id="6477321094435799029">Chrome har oppdaget uvanlig kode på denne siden og blokkert den for å beskytte personopplysningene dine (for eksempel passord, telefonnumre og kredittkortinformasjon).</translation>
<translation id="6489534406876378309">Start opplastingen av krasj</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Utløper: <ph name="EXPIRATION_DATE_ABBR" />. Sist brukt: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Administratoren din har ikke godkjent det ennå</translation>
<translation id="6569060085658103619">Du ser på en utvidelsesside</translation>
-<translation id="6593753688552673085">mindre enn <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Dette innholdet kan prøve å installere farlig programvare som stjeler eller sletter informasjonen din, på enheten du bruker. <ph name="BEGIN_LINK" />Vis det likevel<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Krypteringsalternativer</translation>
<translation id="662080504995468778">Bli her</translation>
<translation id="6626291197371920147">Legg til et gyldig kortnummer</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Søk</translation>
+<translation id="6630809736994426279">Angripere som for øyeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, kan prøve å installere farlige programmer på Macen du bruker, for å stjele eller slette informasjonen din (for eksempel bilder, passord, meldinger og kredittkortinformasjon). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Denne retningslinjen er foreldet.</translation>
-<translation id="6652240803263749613">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ikke er regnet som pålitelig av operativsystemet på datamaskinen din. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Vil du fjerne forslaget fra Chromium?</translation>
<translation id="6685834062052613830">Logg av og fullfør konfigurasjonen</translation>
<translation id="6710213216561001401">Forrige</translation>
<translation id="6710594484020273272">&lt;Skriv inn en søketerm&gt;</translation>
<translation id="6711464428925977395">Det er noe galt med proxy-tjeneren, eller adressen er feil.</translation>
<translation id="6727102863431372879">Angi</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ingen}=1{1 element}other{# elementer}}</translation>
<translation id="674375294223700098">Ukjent feil med tjenersertifikat.</translation>
<translation id="6753269504797312559">Retningslinjeverdi</translation>
<translation id="6757797048963528358">Enheten din gikk inn i hvilemodus.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Tilpasnings-ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Kunne ikke laste inn områdedataene</translation>
+<translation id="6825578344716086703">Du prøvde å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat som er signert med en svak signaturalgoritme (for eksempel SHA-1). Dette betyr at sikkerhetslegitimasjonen tjeneren presenterte, kan være forfalsket. Tjeneren kan med andre ord være en annen tjener enn du tror (og du kommuniserer kanskje med en angriper).</translation>
+<translation id="6830728435402077660">Ikke sikker</translation>
<translation id="6831043979455480757">Oversett</translation>
<translation id="6839929833149231406">Område</translation>
<translation id="6874604403660855544">&amp;Legg til likevel</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Kortet ditt er bekreftet</translation>
<translation id="6897140037006041989">Brukeragent</translation>
<translation id="6915804003454593391">Bruker:</translation>
+<translation id="6945221475159498467">Velg</translation>
<translation id="6948701128805548767">For å se hentemetoder og -krav, velg en adresse</translation>
<translation id="6957887021205513506">Tjenersertifikatet ser ut til å være forfalsket.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">BÃ¥de statiske proxytjenere og en .pac-skriptnettadresse er angitt.</translation>
<translation id="6989763994942163495">Vis avanserte innstillinger</translation>
<translation id="7000990526846637657">Fant ingen loggoppføringer</translation>
-<translation id="7009986207543992532">Du prøvde å gå til <ph name="DOMAIN" />, men tjeneren presenterte et sertifikat hvor gyldighetsperioden er oppgitt som for lang til å være pålitelig. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Google-kontoen din kan ha andre typer nettlesingslogger på <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Passord</translation>
+<translation id="7050187094878475250">Du prøvde å nå <ph name="DOMAIN" />. Tjeneren presenterte et sertifikat som har en gyldighetsperiode som er for lang til å være pålitelig.</translation>
+<translation id="7053983685419859001">Blokkér</translation>
<translation id="7064851114919012435">Kontaktinformasjon</translation>
<translation id="7079718277001814089">Dette nettstedet inneholder skadelig programvare</translation>
<translation id="7087282848513945231">Fylke</translation>
-<translation id="7088615885725309056">Eldre</translation>
<translation id="7090678807593890770">Søk på Google etter <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Tillatt av en utvidelse</translation>
<translation id="7119414471315195487">Lukk andre faner eller programmer</translation>
<translation id="7129409597930077180">Kan ikke sende til denne adressen. Velg en annen adresse.</translation>
<translation id="7138472120740807366">Leveringsmetode</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Behandler</translation>
<translation id="724691107663265825">Nettstedet du er på vei til, inneholder skadelig programvare</translation>
<translation id="724975217298816891">Skriv inn utløpsdatoen og verifiseringskoden for <ph name="CREDIT_CARD" /> for å oppdatere kortinformasjonen din. Når du bekrefter, deles denne informasjonen med dette nettstedet.</translation>
-<translation id="725866823122871198">En privat forbindelse til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> kan ikke opprettes fordi datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) på datamaskinen er feil.</translation>
+<translation id="7260504762447901703">Opphev tilgangen</translation>
<translation id="7275334191706090484">Administrerte bokmerker</translation>
<translation id="7298195798382681320">Anbefalt</translation>
<translation id="7309308571273880165">Programstopprapport opprettet <ph name="CRASH_TIME" /> (opplasting er forespurt av brukeren, men den har ikke blitt utført ennå)</translation>
<translation id="7334320624316649418">&amp;Omorganiser likevel</translation>
<translation id="733923710415886693">Tjenerens sertifikat er ikke vist i henhold til regelen for sertifikatåpenhet.</translation>
-<translation id="7351800657706554155">Du kan ikke gå til <ph name="SITE" /> akkurat nå fordi dette sertifikatet er trukket tilbake. Nettverksfeil og nettangrep er som regel kortvarige, så denne siden fungerer nok igjen senere. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Kommandolinje </translation>
<translation id="7372973238305370288">søkeresultat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> – <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nei takk</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Bekreft kortet</translation>
-<translation id="7394102162464064926">Er du sikker på at du vil slette disse sidene fra loggen din?
-
-Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gang.</translation>
<translation id="7400418766976504921">Nettadresse</translation>
<translation id="7419106976560586862">Profilbane</translation>
<translation id="7424977062513257142">En innebygd side på denne nettsiden sier:</translation>
@@ -688,6 +754,7 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="7444046173054089907">Dette nettstedet er blokkert</translation>
<translation id="7445762425076701745">Identiteten til tjernen du er tilkoblet kan ikke valideres. Du er tilkoblet en tjener som bruker et navn som kun er gyldig i ditt nettverk, som en ekstern sertifiseringsinstans ikke har noen mulighet til å validere eierskap for. Siden enkelte sertifiseringsinstanser likevel utsteder sertifikater for disse navnene, er det umulig å sikre at du er tilkoblet ønsket nettsted og ikke en angriper.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /> om dette problemet.</translation>
+<translation id="7455133967321480974">Bruk global standardinnstilling (Blokkér)</translation>
<translation id="7460163899615895653">De nylige fanene dine fra andre enheter vises her</translation>
<translation id="7469372306589899959">Bekrefter kortet</translation>
<translation id="7481312909269577407">Frem</translation>
@@ -695,36 +762,43 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="7508255263130623398">Den returnerte enhets-ID-en for regelen er tom eller samsvarer ikke med den faktiske enhets-ID-en</translation>
<translation id="7514365320538308">Last ned</translation>
<translation id="7518003948725431193">Finner ingen nettside for denne nettadressen: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Verdi</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
+<translation id="7542403920425041731">NÃ¥r du bekrefter, deles kortinformasjonen din med dette nettstedet.</translation>
<translation id="7542995811387359312">Automatisk utfylling av kredittkort er deaktivert fordi dette skjemaet ikke bruker en sikker tilkobling.</translation>
<translation id="7543525346216957623">Spør forelderen din</translation>
<translation id="7549584377607005141">Denne nettsiden krever data som du har skrevet inn tidligere for å vises korrekt. Du kan sende inn dataene på nytt, men hvis du gjør det, gjentas eventuelle handlinger denne siden utførte.</translation>
<translation id="7552846755917812628">Prøv følgende tips:</translation>
<translation id="7554791636758816595">Ny fane</translation>
+<translation id="7567204685887185387">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Tjenerens sikkerhetssertifikat kan ha blitt utstedt på uredelig vis. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> til}other{<ph name="CONTACT_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> til}}</translation>
<translation id="7568593326407688803">Denne siden er på<ph name="ORIGINAL_LANGUAGE" />Vil du ha den oversatt?</translation>
<translation id="7569952961197462199">Vil du fjerne kredittkortet fra Chrome?</translation>
<translation id="7569983096843329377">Svart</translation>
<translation id="7578104083680115302">Når du lagrer kort med Google, kan du bruke dem til å betale raskt på nettsteder og i apper – uansett hvilken enhet du bruker.</translation>
<translation id="7588950540487816470">Fysisk nett</translation>
<translation id="7592362899630581445">Tjenerens sertifikat bryter navnereglene.</translation>
+<translation id="7598391785903975535">Under <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> kan for øyeblikket ikke behandle denne forespørselen.</translation>
<translation id="7600965453749440009">Oversett aldri <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Verdien er utenfor rekkevidden <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Utløpsdato: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Du har allerede data som er kryptert med en annen versjon av Google-kontopassordet ditt. Skriv det inn nedenfor.</translation>
-<translation id="7634554953375732414">Tilkoblingen til dette nettstedet er ikke privat.</translation>
<translation id="7637571805876720304">Vil du fjerne kredittkortet fra Chromium?</translation>
<translation id="765676359832457558">Skjul avanserte innstillinger</translation>
<translation id="7658239707568436148">Avbryt</translation>
+<translation id="7662298039739062396">Innstillingen kontrolleres av en utvidelse</translation>
<translation id="7667346355482952095">Det returnerte regeltokenet er tomt eller samsvarer ikke med det nåværende tokenet</translation>
<translation id="7668654391829183341">Ukjent enhet</translation>
<translation id="7669271284792375604">Angripere på dette nettstedet kan forsøke å lure deg til å installere programmer som ødelegger surfeopplevelsen din (for eksempel ved å endre startsiden din eller vise ekstra annonser på nettstedene du besøker).</translation>
<translation id="7674629440242451245">Interessert i nye kule Chrome-funksjoner? Prøv utviklerkanalen vår på chrome.com/dev</translation>
<translation id="7682287625158474539">Forsendelse</translation>
+<translation id="7701040980221191251">Ingen</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Fortsett til <ph name="SITE" /> (usikker side)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Sertifikat</translation>
+<translation id="7716147886133743102">Blokkert av administratoren din</translation>
<translation id="7716424297397655342">Dette nettstedet kan ikke lastes inn fra bufferen</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Administreres ikke</translation>
<translation id="7755287808199759310">Forelderen din kan oppheve blokkeringen for deg</translation>
<translation id="7758069387465995638">Brannmur- eller antivirusprogramvare kan ha blokkert tilkoblingen.</translation>
@@ -751,15 +825,15 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Bokmerker for mobil</translation>
<translation id="7961015016161918242">Aldri</translation>
-<translation id="7962083544045318153">Kræsj-ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Oversett alltid <ph name="ORIGINAL_LANGUAGE" /> til <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ikke spesifisert</translation>
<translation id="800218591365569300">Prøv å lukke andre faner eller programmer for å frigjøre minne.</translation>
<translation id="8012647001091218357">Vi kunne ikke nå foreldrene dine akkurat nå. Prøv igjen.</translation>
<translation id="8025119109950072390">Angripere på dette nettstedet prøver kanskje å lure deg til å gjøre farlige ting som å installere programvare eller avsløre personopplysningene dine (for eksempel passord, telefonnumre eller kredittkortinformasjon).</translation>
-<translation id="803030522067524905">Google Safe Browsing oppdaget nylig nettfisking på <ph name="SITE" />. Nettsteder som driver med nettfisking, later som om de er andre nettsteder for å lure deg. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Denne siden er på <ph name="SOURCE_LANGUAGE" />. Vil du oversette den til <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Spør (standard)</translation>
<translation id="8041089156583427627">Send tilbakemelding</translation>
+<translation id="8041940743680923270">Bruk global standardinnstilling (Spør)</translation>
<translation id="8088680233425245692">Kunne ikke åpne artikkelen.</translation>
<translation id="8089520772729574115">under 1 MB</translation>
<translation id="8091372947890762290">Aktivering venter på tjeneren</translation>
@@ -768,13 +842,14 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="8134994873729925007"><ph name="HOST_NAME" />-tjenerens <ph name="BEGIN_ABBR" />DNS-adresse<ph name="END_ABBR" /> ble ikke funnet.</translation>
<translation id="8149426793427495338">Datamaskinen din gikk inn i hvilemodus.</translation>
<translation id="8150722005171944719">Kunne ikke lese filen på <ph name="URL" /> Den kan ha blitt fjernet eller flyttet. Det kan også være filtillatelser som forhindrer tilgang.</translation>
+<translation id="8184538546369750125">Bruk global standardinnstilling (Tillat)</translation>
+<translation id="8191494405820426728">Lokal kræsj-ID: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Angre flyttingen</translation>
<translation id="8201077131113104583">Ugyldig oppdaterings-URL for utvidelse med ID «<ph name="EXTENSION_ID" />».</translation>
<translation id="8202097416529803614">Bestillingssammendrag</translation>
<translation id="8218327578424803826">Tilordnet posisjon:</translation>
<translation id="8225771182978767009">Personen som konfigurerte denne datamaskinen, har valgt å blokkere dette nettstedet.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Hackere som for øyeblikket er på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, prøver kanskje å installere farlige programmer på datamaskinen din. Disse kan stjele eller slette informasjonen din (for eksempel bilder, passord, e-post og kredittkortinformasjon).</translation>
<translation id="8241707690549784388">Siden du ser etter, brukte informasjon som du anga. Hvis du går tilbake til denne siden, kan det føre til at handlinger som er utført, blir gjentatt. Vil du fortsette?</translation>
<translation id="8249320324621329438">Sist hentet:</translation>
<translation id="8253091569723639551">Fakturaadresse er obligatorisk</translation>
@@ -782,6 +857,7 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="8289355894181816810">Kontakt nettverksadministratoren hvis du ikke er sikker på hva dette betyr.</translation>
<translation id="8293206222192510085">Legg til bokmerke</translation>
<translation id="8294431847097064396">Kilde</translation>
+<translation id="8306404619377842860">Det kan ikke opprettes noen privat tilkobling til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, siden datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) på enheten du bruker, er feil. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Oversettelsen mislyktes på grunn av et problem med nettverksforbindelsen.</translation>
<translation id="8332188693563227489">Forsøket på å koble til <ph name="HOST_NAME" /> ble avvist</translation>
<translation id="834457929814110454">Hvis du forstår sikkerhetsrisikoen, kan du <ph name="BEGIN_LINK" />gå til det usikre nettstedet<ph name="END_LINK" /> før de farlige programmene er fjernet.</translation>
@@ -802,11 +878,9 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="8483780878231876732">For å bruke kredittkort du har lagret i Google-kontoen din, logg på Chrome</translation>
<translation id="8488350697529856933">Gjelder for</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> brukte for lang tid på å svare.</translation>
-<translation id="852346902619691059">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />, ettersom sikkerhetssertifikatet ikke er regnet som pålitelig av operativsystemet på enheten din. Dette kan skyldes en feilkonfigurasjon eller at en angriper avskjærer tilkoblingen din. <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Utløpsår</translation>
<translation id="8543181531796978784">Du kan <ph name="BEGIN_ERROR_LINK" />rapportere et påvisningsproblem<ph name="END_ERROR_LINK" /> eller, hvis du forstår sikkerhetsrisikoen, <ph name="BEGIN_LINK" />gå til dette usikre nettstedet<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Oversettelsen mislyktes fordi sidens språk ikke kunne fastslås.</translation>
-<translation id="8559762987265718583">En privat tilkobling til <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> kunne ikke etableres fordi datoen og klokkeslettet (<ph name="DATE_AND_TIME" />) er feil på enheten.</translation>
<translation id="8571890674111243710">Oversett siden til <ph name="LANGUAGE" /></translation>
<translation id="858637041960032120">Legg til telefonnummer</translation>
<translation id="859285277496340001">Sertifikatet spesifiserer ikke en mekanisme for å kontrollere hvorvidt det har blitt tilbakekalt.</translation>
@@ -820,6 +894,7 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="8738058698779197622">Klokken din må være riktig stilt for at du skal kunne opprette en sikker forbindelse. Sertifikatene som nettsteder bruker til å identifisere seg med, er nemlig bare gyldige i en viss tid. Siden enhetens klokke er feil, kan ikke Chromium kontrollere disse sertifikatene.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;DNS-adressen&lt;/abbr&gt; til <ph name="HOST_NAME" /> ble ikke funnet. Problemet diagnostiseres.</translation>
<translation id="8759274551635299824">Dette kortet er utløpt</translation>
+<translation id="8761567432415473239">Google Safe Browsing oppdaget nylig <ph name="BEGIN_LINK" />skadelige programmer<ph name="END_LINK" /> på <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Slett likevel</translation>
<translation id="8800988563907321413">Forslagene dine om ting like ved vises her</translation>
<translation id="8820817407110198400">Bokmerker</translation>
@@ -832,29 +907,30 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="8870413625673593573">Nylig lukket</translation>
<translation id="8874824191258364635">Angi et gyldig kortnummer</translation>
<translation id="8876793034577346603">Nettverkskonfigurasjon kunne ikke analyseres.</translation>
-<translation id="8877192140621905067">NÃ¥r du bekrefter, deles kortinformasjonen din med dette nettstedet</translation>
<translation id="8889402386540077796">Fargetone</translation>
<translation id="8891727572606052622">Ugyldig modus for mellomtjener.</translation>
<translation id="889901481107108152">Beklager, dette eksperimentet er ikke er tilgjengelig på plattformen din.</translation>
<translation id="8903921497873541725">Zoom inn</translation>
<translation id="8931333241327730545">Vil du lagre dette kortet i Google-kontoen din?</translation>
<translation id="8932102934695377596">Klokken går for sent</translation>
-<translation id="8954894007019320973">(Forts.)</translation>
<translation id="8971063699422889582">Tjenerens sertifikat er utløpt.</translation>
<translation id="8986494364107987395">Send bruksstatistikk og programstopprapporter automatisk til Google</translation>
-<translation id="8987927404178983737">MÃ¥ned</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Nettstedet du er i ferd med å åpne, inneholder skadelige programmer</translation>
+<translation id="8997023839087525404">Tjeneren har presentert et sertifikat som ikke er offentlig vist i henhold til regelen om sertifikatåpenhet. Dette er et krav for enkelte sertifikater for å sikre at de er pålitelige, og bidrar til å beskytte mot angrep.</translation>
<translation id="9001074447101275817">Proxy-tjeneren <ph name="DOMAIN" /> krever brukernavn og passord.</translation>
+<translation id="9005998258318286617">Kunne ikke laste inn PDF-dokumentet.</translation>
<translation id="901974403500617787">Rapporteringer som gjelder for hele systemet kan bare angis av eieren: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Faktureringsadressen for kortet er obligatorisk</translation>
<translation id="9020542370529661692">Denne siden har blitt oversatt til <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Sikkerhetsfeil</translation>
<translation id="9038649477754266430">Bruk en prediksjonstjeneste for å laste inn sider raskere</translation>
<translation id="9039213469156557790">Denne siden inneholder i tillegg andre ressurser som ikke er sikre. Disse ressursene er synlige for andre mens de sendes frem og tilbake, og eventuelle angripere kan modifisere dem for å endre på atferden til siden.</translation>
-<translation id="9040185888511745258">Angripere på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan forsøke å lure deg til å installere programmer som ødelegger surfeopplevelsen din (for eksempel ved å endre startsiden din eller vise ekstra annonser på nettstedene du besøker).</translation>
+<translation id="9049981332609050619">Du forsøkte å nå <ph name="DOMAIN" />, men tjeneren oppga et ugyldig sertifikat.</translation>
<translation id="9050666287014529139">Passordfrase</translation>
<translation id="9065203028668620118">Endre</translation>
<translation id="9068849894565669697">Velg farge</translation>
+<translation id="9069693763241529744">Blokkert av en utvidelse</translation>
<translation id="9076283476770535406">Det kan ha voksent innhold</translation>
<translation id="9078964945751709336">Mer informasjon er nødvendig</translation>
<translation id="9103872766612412690"><ph name="SITE" /> bruker vanligvis kryptering for å beskytte informasjonen din. Da Chromium prøvde å koble til <ph name="SITE" /> denne gangen, sendte nettstedet tilbake uvanlig og feil legitimasjon. Dette kan skje hvis en angriper prøver å utgi seg for å være <ph name="SITE" />, eller hvis en Wi-Fi-påloggingsskjerm har avbrutt tilkoblingen. Informasjonen din er likevel sikker fordi Chromium stoppet tilkoblingen før det ble utvekslet noen data.</translation>
@@ -863,16 +939,21 @@ Forresten: Inkognitomodus (<ph name="SHORTCUT_KEY" />) kan være kjekt neste gan
<translation id="9148507642005240123">&amp;Angre endringen</translation>
<translation id="9154194610265714752">Oppdatert</translation>
<translation id="9157595877708044936">Konfigurerer ...</translation>
+<translation id="9169664750068251925">Blokkér alltid på dette nettstedet</translation>
<translation id="9170848237812810038">&amp;Angre</translation>
<translation id="917450738466192189">Tjenerens sertifikat er ugyldig.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> til}other{<ph name="SHIPPING_OPTION_PREVIEW" /> og <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> til}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> bruker en protokoll som ikke støttes.</translation>
<translation id="9205078245616868884">Dataene dine er kryptert med passordfrasen din for synkronisering. Skriv den inn for å starte synkroniseringen.</translation>
<translation id="9207861905230894330">Kunne ikke legge til artikkelen.</translation>
+<translation id="9219103736887031265">Bilder</translation>
<translation id="933612690413056017">Du er ikke koblet til Internett</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">SLETT INNHOLDET I SKJEMAET</translation>
<translation id="939736085109172342">Ny mappe</translation>
<translation id="941721044073577244">Det ser ut til at du ikke har tillatelse til å besøke dette nettstedet</translation>
<translation id="969892804517981540">Offisiell delversjon</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ingen}=1{1 element}other{# elementer}}</translation>
<translation id="988159990683914416">Utviklerversjon</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_pl.xtb b/chromium/components/strings/components_strings_pl.xtb
index 123d96be668..1f78a34bf15 100644
--- a/chromium/components/strings/components_strings_pl.xtb
+++ b/chromium/components/strings/components_strings_pl.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Obróć w prawo</translation>
<translation id="1038842779957582377">nieznana nazwa</translation>
<translation id="1050038467049342496">Zamknij inne aplikacje</translation>
-<translation id="1053591932240354961">Nie możesz teraz wejść na <ph name="SITE" />, bo ta witryna wysłała zaszyfrowane dane logowania, których Google Chrome nie może przetworzyć. Błędy sieci i ataki są zazwyczaj przejściowe, więc prawdopodobnie później strona będzie działać. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Cofnij dodanie</translation>
<translation id="10614374240317010">Nigdy nie zapisane</translation>
<translation id="106701514854093668">Zakładki na komputerze</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Pamięć podręczna zasad: OK</translation>
<translation id="113188000913989374">Komunikat ze strony <ph name="SITE" />:</translation>
<translation id="1132774398110320017">Ustawienia autouzupełniania Chrome...</translation>
+<translation id="1150979032973867961">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest zaufany w systemie operacyjnym tego komputera. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
+<translation id="1151972924205500581">Wymagane hasło</translation>
<translation id="1152921474424827756">Przejdź do <ph name="BEGIN_LINK" />kopii<ph name="END_LINK" /> <ph name="URL" /> w pamięci podręcznej</translation>
<translation id="1158211211994409885">Serwer <ph name="HOST_NAME" /> nieoczekiwanie zakończył połączenie.</translation>
<translation id="1161325031994447685">Ponownie połącz się z Wi-Fi</translation>
+<translation id="1165039591588034296">BÅ‚Ä…d</translation>
<translation id="1175364870820465910">&amp;Drukuj...</translation>
<translation id="1181037720776840403">Usuń</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Automatycznie przesyłaj<ph name="END_WHITEPAPER_LINK" /> do Google szczegółowe informacje o możliwych zagrożeniach. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Więcej z tej witryny</translation>
<translation id="1206967143813997005">Nieprawidłowy podpis wstępny</translation>
<translation id="1209206284964581585">Na razie ukryj</translation>
+<translation id="121201262018556460">Próbujesz wejść na <ph name="DOMAIN" />, ale serwer przedstawił certyfikat ze słabym kluczem. Intruz mógł uzyskać klucz prywatny, a serwer może nie być tym, którego oczekujesz (możliwe, że komunikujesz się z intruzem).</translation>
<translation id="1219129156119358924">Zabezpieczenia systemu</translation>
<translation id="1227224963052638717">Nieznana zasada.</translation>
<translation id="1227633850867390598">Ukryj wartość</translation>
<translation id="1228893227497259893">Błędny identyfikator elementu</translation>
<translation id="1232569758102978740">Bez tytułu</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (zsynchronizowane)</translation>
<translation id="1263231323834454256">Do przeczytania</translation>
<translation id="1264126396475825575">Utworzono raport o awarii w dniu: <ph name="CRASH_TIME" /> (nie został jeszcze przesłany ani zignorowany)</translation>
+<translation id="1281526147609854549">Wystawca: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Zablokowano niebezpieczne treści</translation>
<translation id="1285320974508926690">Nigdy nie tłumacz tej witryny</translation>
<translation id="129553762522093515">Ostatnio zamknięte</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Usuń pliki cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Twoja aktywność <ph name="BEGIN_EMPHASIS" />może być nadal widoczna<ph name="END_EMPHASIS" /> dla:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />stron internetowych, które odwiedzasz;
+ <ph name="LIST_ITEM" />Twojego pracodawcy lub Twojej szkoły;
+ <ph name="LIST_ITEM" />dostawcy usług internetowych.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domena rejestracji:</translation>
<translation id="1340482604681802745">Adres odbioru</translation>
<translation id="1344211575059133124">Wygląda na to, że aby wejść na tę stronę, musisz uzyskać pozwolenie</translation>
<translation id="1344588688991793829">Ustawienia autouzupełniania Chromium...</translation>
+<translation id="1348198688976932919">Strona, którą chcesz otworzyć, zawiera niebezpieczne aplikacje</translation>
<translation id="1374468813861204354">sugestie</translation>
<translation id="1375198122581997741">Informacje o wersji</translation>
<translation id="1377321085342047638">Numer karty</translation>
<translation id="139305205187523129">Serwer <ph name="HOST_NAME" /> nie wysłał żadnych danych.</translation>
<translation id="1407135791313364759">Otwórz wszystkie</translation>
<translation id="1413809658975081374">Błąd dotyczący prywatności</translation>
+<translation id="14171126816530869">Tożsamość organizacji <ph name="ORGANIZATION" /> (<ph name="LOCALITY" />) została zweryfikowana przed wystawcę <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Tak</translation>
<translation id="1430915738399379752">Drukuj</translation>
-<translation id="1442912890475371290">Zablokowano próbę <ph name="BEGIN_LINK" />wejścia na stronę w domenie <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Nie możesz teraz wejść na stronę <ph name="SITE" />, bo stosuje ona przypinanie certyfikatów. Błędy sieci i ataki są zazwyczaj przejściowe, więc prawdopodobnie później strona będzie działać. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> inna}few{<ph name="PAYMENT_METHOD_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> inne}many{<ph name="PAYMENT_METHOD_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> innych}other{<ph name="PAYMENT_METHOD_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> innej}}</translation>
<translation id="1506687042165942984">Pokaż zapisaną (tzn. nieaktualną) kopię tej strony.</translation>
<translation id="1517433312004943670">Numer telefonu jest wymagany</translation>
<translation id="1519264250979466059">Data kompilacji</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Aby można było korzystać z tej funkcji, musi być włączony JavaScript.</translation>
<translation id="1555130319947370107">Niebieski</translation>
<translation id="1559528461873125649">Brak takiego pliku lub katalogu</translation>
-<translation id="1559572115229829303">&lt;p&gt;Nie można nawiązać prywatnego połączenia z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, bo data i godzina (<ph name="DATE_AND_TIME" />) ustawione na urządzeniu są nieprawidłowe.&lt;/p&gt;
-
- &lt;p&gt;Popraw datę i godzinę w sekcji &lt;strong&gt;Ogólne&lt;/strong&gt; w aplikacji &lt;strong&gt;Ustawienia&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Podczas wyświetlania strony wystąpił błąd.</translation>
<translation id="1592005682883173041">Lokalny dostęp do danych</translation>
+<translation id="1594030484168838125">Wybierz</translation>
<translation id="161042844686301425">Cyjan</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Czy Chrome ma zapisać tę kartę?</translation>
<translation id="1639239467298939599">WczytujÄ™</translation>
<translation id="1640180200866533862">Zasady dotyczące użytkowników</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Konfiguracja sieci jest nieprawidłowa i nie można jej zaimportować.</translation>
<translation id="1644574205037202324">Historia</translation>
<translation id="1645368109819982629">Nieobsługiwany protokół</translation>
+<translation id="1655462015569774233">{1,plural, =1{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł wczoraj. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}few{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dni temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}many{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dni temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}other{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dnia temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę.}}</translation>
<translation id="1656489000284462475">Odbiór</translation>
<translation id="1663943134801823270">Karty i adresy pochodzą z Chrome. Możesz nimi zarządzać w <ph name="BEGIN_LINK" />Ustawieniach<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> zazwyczaj używa szyfrowania do ochrony Twoich informacji. Gdy tym razem Google Chrome próbował połączyć się ze stroną <ph name="SITE" />, odesłała ona nietypowe i nieprawidłowe dane logowania. Może się tak zdarzyć, gdy pod stronę <ph name="SITE" /> podszywa się atakująca osoba albo gdy ekran logowania do sieci Wi-Fi przerwie połączenie. Twoje informacje są nadal bezpieczne, bo połączenie w Google Chrome zakończyło się przed wymianą jakichkolwiek danych.</translation>
-<translation id="168328519870909584">Hakerzy mogliby wykorzystać stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, by zainstalować na Twoim urządzeniu niebezpieczne aplikacje, które mogłyby wykraść lub skasować Twoje dane (takie jak zdjęcia, hasła, wiadomości czy numery kart kredytowych).</translation>
<translation id="168841957122794586">Certyfikat serwera ma słaby klucz kryptograficzny.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać od jutra. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia.}few{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać za # dni. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia.}many{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać za # dni. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia.}other{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać za # dnia. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia.}}</translation>
<translation id="1710259589646384581">System operacyjny</translation>
<translation id="1721312023322545264">Aby wejść na tę stronę, musisz uzyskać pozwolenie od użytkownika <ph name="NAME" /></translation>
<translation id="1721424275792716183">* Pole jest wymagane</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Pobierz stronę później</translation>
<translation id="17513872634828108">Otwarte karty</translation>
<translation id="1753706481035618306">Numer strony</translation>
+<translation id="1763864636252898013">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest zaufany w systemie operacyjnym tego urządzenia. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Uruchom DiagnostykÄ™ sieci systemu Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Zaktualizuj swoje hasło synchronizacji.</translation>
<translation id="1787142507584202372">Tutaj pojawiajÄ… siÄ™ otwarte karty</translation>
+<translation id="1789575671122666129">WyskakujÄ…ce okienka</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">ImiÄ™ i nazwisko posiadacza karty</translation>
-<translation id="1803678881841855883">Bezpieczne przeglądanie Google ostatnio <ph name="BEGIN_LINK" />wykryło złośliwe oprogramowanie<ph name="END_LINK" /> na <ph name="SITE" />. Strony, które normalnie są bezpieczne, czasem zostają zainfekowane złośliwym oprogramowaniem. Złośliwa zawartość pochodzi z <ph name="SUBRESOURCE_HOST" /> – znanego dystrybutora złośliwego oprogramowania. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Dodano: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Nieprawidłowe żądanie lub jego parametry</translation>
<translation id="1826516787628120939">Sprawdzam</translation>
<translation id="1834321415901700177">Ta strona zawiera szkodliwe programy</translation>
+<translation id="1840414022444569775">Ten numer karty jest już używany</translation>
<translation id="1842969606798536927">Zapłać</translation>
<translation id="1871208020102129563">Proxy skonfigurowano do używania stałych serwerów proxy, a nie URL-a skryptu PAC.</translation>
<translation id="1871284979644508959">Pole wymagane</translation>
<translation id="187918866476621466">Otwórz strony początkowe</translation>
<translation id="1883255238294161206">Zwiń listę</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> inny}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> inne}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> innych}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> innego}}</translation>
<translation id="1898423065542865115">Filtrowanie</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Brak}=1{1 witryna}few{# witryny}many{# witryn}other{# witryny}}</translation>
<translation id="194030505837763158">Wejdź na <ph name="LINK" /></translation>
<translation id="1962204205936693436">Zakładki z <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Podczas przekształcania do postaci szeregowej wystąpił błąd</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorowana, ponieważ jest zastąpiona przez <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Szukam stron internetu rzeczy w pobliżu</translation>
<translation id="213826338245044447">Zakładki na komórce</translation>
-<translation id="2148716181193084225">Dzisiaj</translation>
+<translation id="2147827593068025794">Synchronizacja w tle</translation>
<translation id="2154054054215849342">Synchronizacja nie jest dostępna w Twojej domenie.</translation>
<translation id="2154484045852737596">Edytowanie karty</translation>
<translation id="2166049586286450108">Pełny dostęp administratora</translation>
<translation id="2166378884831602661">Ta witryna nie umożliwia bezpiecznego połączenia</translation>
<translation id="2181821976797666341">Zasady</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adres}few{# adresy}many{# adresów}other{# adresu}}</translation>
+<translation id="2187317261103489799">Wykrywaj (domyślnie)</translation>
<translation id="2202020181578195191">Wpisz rok w prawidłowym formacie</translation>
<translation id="2212735316055980242">Nie znaleziono zasady</translation>
<translation id="2213606439339815911">Pobieram wpisy...</translation>
+<translation id="2218879909401188352">Osoby obecnie atakujące stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą instalować niebezpieczne aplikacje, które mogą uszkodzić Twoje urządzenie, dodać ukryte opłaty do rachunku za usługi telefoniczne lub wykraść Twoje dane osobowe. <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Napraw połączenie, używając <ph name="BEGIN_LINK" />aplikacji diagnostycznej<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Wyślij teraz</translation>
<translation id="225207911366869382">Ta wartość tej zasady została wycofana.</translation>
<translation id="2262243747453050782">BÅ‚Ä…d HTTP</translation>
+<translation id="2270484714375784793">Numer telefonu</translation>
<translation id="2282872951544483773">Niedostępne eksperymenty</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element}few{<ph name="ITEM_COUNT" /> elementy}many{<ph name="ITEM_COUNT" /> elementów}other{<ph name="ITEM_COUNT" /> elementu}}</translation>
<translation id="2292556288342944218">Masz zablokowany dostęp do internetu</translation>
<translation id="230155334948463882">Nowa karta?</translation>
-<translation id="2305919008529760154">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat mógł zostać wydany w celu dokonania oszustwa. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> wymaga nazwy użytkownika i hasła.</translation>
-<translation id="2318774815570432836">Nie możesz teraz wejść na stronę <ph name="SITE" />, bo używa ona HSTS. Błędy sieci i ataki są zazwyczaj przejściowe, więc prawdopodobnie później strona będzie działać. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Ustawienie kontrolowane przez administratora</translation>
<translation id="2354001756790975382">Inne zakładki</translation>
+<translation id="2354430244986887761">Funkcja Bezpieczne przeglądanie Google niedawno <ph name="BEGIN_LINK" />wykryła szkodliwe aplikacje<ph name="END_LINK" /> na <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Osoby dokonujące ataków mogą widzieć te same obrazy w witrynie co Ty i zmodyfikować je, by Cię oszukać.</translation>
+<translation id="2356070529366658676">Pytaj</translation>
+<translation id="2359629602545592467">Różne</translation>
<translation id="2359808026110333948">Dalej</translation>
<translation id="2365563543831475020">Raport o awarii utworzony w dniu: <ph name="CRASH_TIME" /> nie został przesłany</translation>
<translation id="2367567093518048410">Poziom</translation>
-<translation id="2371153335857947666">{1,plural, =1{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł wczoraj. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}few{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dni temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}many{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dni temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}other{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa wygasł # dnia temu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. Zegar komputera jest obecnie ustawiony na <ph name="CURRENT_DATE" />. Czy to prawidłowa data? Jeśli nie, musisz skorygować zegar systemu, a następnie odświeżyć tę stronę. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Brak dostępnych alternatywnych interfejsów</translation>
<translation id="2384307209577226199">Domyślne zasady przedsiębiorstwa</translation>
<translation id="2386255080630008482">Certyfikat serwera został unieważniony.</translation>
<translation id="2392959068659972793">Pokaż zasady bez ustawionej wartości</translation>
<translation id="239429038616798445">Ta metoda wysyłki jest niedostępna. Wybierz inną.</translation>
<translation id="2396249848217231973">&amp;Cofnij usunięcie</translation>
-<translation id="2460160116472764928">Bezpieczne przeglądanie Google ostatnio <ph name="BEGIN_LINK" />wykryło złośliwe oprogramowanie<ph name="END_LINK" /> na <ph name="SITE" />. Strony, które normalnie są bezpieczne, czasem zostają zainfekowane złośliwym oprogramowaniem. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa mógł zostać odwołany. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="2463739503403862330">Wpisz</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Uruchom diagnostykÄ™ sieci<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Nieprawidłowy URL wyszukiwania</translation>
+<translation id="2482878487686419369">Powiadomienia</translation>
<translation id="2491120439723279231">Certyfikat serwera zawiera błędy.</translation>
<translation id="2495083838625180221">Parser JSON</translation>
<translation id="2495093607237746763">Jeśli zaznaczysz tę opcję, Chromium zapisze kopię Twojej karty na tym urządzeniu, by umożliwić Ci szybsze wypełnianie formularzy.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Wróć</translation>
<translation id="2515629240566999685">Sprawdź sygnał w swojej okolicy</translation>
<translation id="2516305470678292029">Alternatywne interfejsy</translation>
+<translation id="2539524384386349900">Wykrywaj</translation>
<translation id="255002559098805027">Serwer <ph name="HOST_NAME" /> wysłał nieprawidłową odpowiedź.</translation>
-<translation id="2552545117464357659">Nowsze</translation>
<translation id="2556876185419854533">&amp;Cofnij edycjÄ™</translation>
<translation id="2587730715158995865">Wydawca: <ph name="ARTICLE_PUBLISHER" />. Przeczytaj ten artykuł i inne (<ph name="OTHER_ARTICLE_COUNT" />).</translation>
<translation id="2587841377698384444">Identyfikator interfejsu API katalogu:</translation>
<translation id="2597378329261239068">Ten dokument jest chroniony hasłem. Wprowadź hasło.</translation>
<translation id="2609632851001447353">Odmiany</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Brak}=1{1 aplikacja ($1)}=2{2 aplikacje ($1, $2)}few{# aplikacje ($1, $2, $3)}many{# aplikacji ($1, $2, $3)}other{# aplikacji ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Twój zegar się śpieszy</translation>
<translation id="2639739919103226564">Stan:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Odmówiono dostępu do pliku</translation>
<translation id="2653659639078652383">Prześlij</translation>
<translation id="2666117266261740852">Zamknij inne karty lub aplikacje</translation>
+<translation id="2670429602441959756">Strona zawiera funkcje, które nie są jeszcze obsługiwane w rzeczywistości wirtualnej. Zamykam…</translation>
<translation id="2674170444375937751">Czy na pewno chcesz usunąć te strony z historii?</translation>
<translation id="2677748264148917807">Wyjdź</translation>
-<translation id="269990154133806163">Serwer przedstawił certyfikat, który nie został opublikowany za pomocą zasad Certificate Transparency. W przypadku niektórych certyfikatów to wymaganie musi być spełnione, ponieważ gwarantuje, że można im ufać i że chronią one przed atakami. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Do przeczytania</translation>
<translation id="2704283930420550640">Wartość nie pasuje do formatu.</translation>
<translation id="2704951214193499422">Chromium nie może obecnie potwierdzić karty. Spróbuj ponownie później.</translation>
<translation id="2705137772291741111">Zapisana w pamięci podręcznej kopia tej strony jest uszkodzona.</translation>
<translation id="2709516037105925701">Autouzupełnianie</translation>
-<translation id="2712118517637785082">Próbujesz połączyć się z <ph name="DOMAIN" />, ale serwer przedstawił certyfikat unieważniony przez wystawcę. Oznacza to, że dane logowania podane przez serwer są zupełnie niewiarygodne. Możliwe, że komunikujesz się z intruzem. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">PoproÅ› o pozwolenie</translation>
<translation id="2713444072780614174">Biały</translation>
<translation id="2720342946869265578">W pobliżu</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Brak rekordu urzÄ…dzenia</translation>
<translation id="2784949926578158345">Połączenie zostało zresetowane.</translation>
<translation id="2794233252405721443">Strona zablokowana</translation>
+<translation id="2799020568854403057">Strona, którą chcesz otworzyć, zawiera szkodliwe aplikacje</translation>
+<translation id="2803306138276472711">Bezpieczne przeglądanie Google <ph name="BEGIN_LINK" />wykryło ostatnio złośliwe oprogramowanie<ph name="END_LINK" /> na <ph name="SITE" />. Strony, które zazwyczaj są bezpieczne, zostają czasem zainfekowane destrukcyjnym oprogramowaniem.</translation>
<translation id="2824775600643448204">Pasek adresu i wyszukiwania</translation>
<translation id="2826760142808435982">Połączenie jest szyfrowane i uwierzytelniane algorytmem <ph name="CIPHER" />, a mechanizm wymiany kluczy to <ph name="KX" />.</translation>
<translation id="2835170189407361413">Wyczyść formularz</translation>
+<translation id="2856444702002559011">Osoby atakujące mogą próbować wykraść Twoje informacje ze strony <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (na przykład hasła, wiadomości lub dane kart kredytowych). <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Nie Å‚aduj ponownie</translation>
<translation id="2900469785430194048">Podczas próby wyświetlenia tej strony w Google Chrome zabrakło pamięci.</translation>
<translation id="2909946352844186028">Wykryto zmianÄ™ sieci.</translation>
<translation id="2916038427272391327">Zamknij inne programy</translation>
<translation id="2922350208395188000">Nie można sprawdzić certyfikatu serwera.</translation>
<translation id="2928905813689894207">Adres rozliczeniowy</translation>
+<translation id="2941952326391522266">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat pochodzi z <ph name="DOMAIN2" />. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="2948083400971632585">Możesz wyłączyć dowolne serwery proxy skonfigurowane dla połączenia na stronie ustawień.</translation>
<translation id="2955913368246107853">Zamknij pasek wyszukiwania</translation>
<translation id="2958431318199492670">Konfiguracja sieci jest niezgodna ze standardem ONC. Jej fragmenty mogły nie zostać zaimportowane.</translation>
-<translation id="29611076221683977">Osoby atakujące stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą spróbować zainstalować na Twoim Macu niebezpieczne programy, których celem jest wykradzenie lub usunięcie Twoich danych (na przykład zdjęć, haseł, wiadomości czy numerów kart kredytowych).</translation>
<translation id="2966678944701946121">Data ważności: <ph name="EXPIRATION_DATE_ABBR" />, dodano: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Aby urządzenie nawiązało bezpieczne połączenie, jego zegar musi wskazywać prawidłową godzinę. Jest to wymagane, bo certyfikaty używane do identyfikacji stron internetowych są ważne tylko przez określony czas. Zegar urządzenia jest ustawiony nieprawidłowo, więc Google Chrome nie może zweryfikować tych certyfikatów.</translation>
<translation id="2972581237482394796">&amp;Ponów</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Wpisz prawidłowy adres</translation>
<translation id="2986368408720340940">Ta metoda odbioru jest niedostępna. Wybierz inną.</translation>
<translation id="2991174974383378012">Udostępnianie stronom internetowym</translation>
+<translation id="2991571918955627853">Nie możesz teraz wejść na stronę <ph name="SITE" />, ponieważ używa ona HSTS. Błędy sieciowe i ataki są zazwyczaj tymczasowe, więc prawdopodobnie strona będzie dostępna później.</translation>
<translation id="3005723025932146533">Pokaż zapisaną kopię</translation>
<translation id="3008447029300691911">Wpisz kod CVC karty <ph name="CREDIT_CARD" />. Po potwierdzeniu szczegółowe dane karty zostaną udostępnione tej stronie.</translation>
<translation id="3010559122411665027">Pozycja listy „<ph name="ENTRY_INDEX" />â€: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automatycznie zablokowane</translation>
<translation id="3024663005179499861">Nieprawidłowy typ zasady</translation>
<translation id="3032412215588512954">Chcesz ponownie załadować tę stronę?</translation>
<translation id="3037605927509011580">Kurza twarz!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{co najmniej 1 element na synchronizowanych urządzeniach}=1{1 element (i więcej na synchronizowanych urządzeniach)}few{# elementy (i więcej na synchronizowanych urządzeniach)}many{# elementów (i więcej na synchronizowanych urządzeniach)}other{# elementu (i więcej na synchronizowanych urządzeniach)}}</translation>
<translation id="3041612393474885105">Informacje o certyfikacie</translation>
<translation id="3063697135517575841">Chrome nie może obecnie potwierdzić karty. Spróbuj ponownie później.</translation>
<translation id="3064966200440839136">Opuszczasz tryb incognito, by zapłacić w aplikacji zewnętrznej. Kontynuować?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Brak}=1{1 hasło}few{# hasła}many{# haseł}other{# hasła}}</translation>
<translation id="3093245981617870298">JesteÅ› offline.</translation>
<translation id="3105172416063519923">Identyfikator zasobu:</translation>
<translation id="3109728660330352905">Nie masz uprawnień do wyświetlania tej strony.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Uruchom diagnostykę połączeń<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Dekodowanie odpowiedzi nie powiodło się</translation>
<translation id="3150653042067488994">Tymczasowy błąd serwera</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Po zamknięciu wszystkich kart incognito wyświetlane na nich strony nie pozostawią żadnych śladów w historii przeglądarki, magazynie plików cookie ani historii wyszukiwania. Pobrane pliki i utworzone zakładki zostaną jednak zachowane.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Wyspa</translation>
+<translation id="317583078218509884">Nowe ustawienia pozwoleń dla stron zostaną zastosowane po ponownym załadowaniu strony.</translation>
<translation id="3176929007561373547">Sprawdź ustawienia serwera proxy lub skontaktuj się z administratorem sieci,
by upewnić się, że serwer proxy działa. Jeśli uważasz, że
nie powinien być on używany:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Otwórz stronę w trybie incognito</translation>
-<translation id="3202578601642193415">Najnowsze</translation>
+<translation id="320323717674993345">Anuluj płatność</translation>
<translation id="3207960819495026254">Dodano do zakładek</translation>
+<translation id="3225919329040284222">Serwer przedstawił certyfikat, który nie pasuje do zaprogramowanych oczekiwań. Oczekiwania mają chronić Cię w określonych witrynach o wysokim poziomie zabezpieczeń.</translation>
<translation id="3226128629678568754">Naciśnij przycisk ponownego załadowania, by przesłać dane wymagane do wczytania strony.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Tłumaczenie nie powiodło się, ponieważ strona jest już w języku: <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Wpisz kod CVC karty <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Zawsze wykrywaj ważną treść na tej stronie</translation>
<translation id="3254409185687681395">Dodaj stronę do zakładek</translation>
<translation id="3270847123878663523">&amp;Cofnij zmianę kolejności</translation>
<translation id="3282497668470633863">Dodaj imiÄ™ i nazwisko na karcie</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">ustawienia</translation>
<translation id="3345135638360864351">Nie udało się wysłać żądania dostępu do strony do <ph name="NAME" />. Spróbuj ponownie.</translation>
<translation id="3355823806454867987">Zmień ustawienia serwera proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />nie będzie zapisywać<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Twojej historii przeglÄ…dania;
+ <ph name="LIST_ITEM" />plików cookie i danych ze stron internetowych;
+ <ph name="LIST_ITEM" />informacji, które wpisujesz w formularzach.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">BÅ‚Ä…d zegara</translation>
-<translation id="337311366426640088">I jeszcze <ph name="ITEM_COUNT" />…</translation>
<translation id="337363190475750230">Anulowano obsługę</translation>
<translation id="3377188786107721145">Podczas przetwarzania zasady wystąpił błąd</translation>
<translation id="3380365263193509176">Nieznany błąd</translation>
<translation id="3380864720620200369">Identyfikator klienta:</translation>
<translation id="3391030046425686457">Adres dostawy</translation>
<translation id="3395827396354264108">Metoda odbioru</translation>
-<translation id="340013220407300675">Hakerzy mogą próbować wykraść Twoje dane z <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (np. hasła, wiadomości lub informacje o karcie kredytowej).</translation>
<translation id="3422248202833853650">Zamknij inne programy, by zwolnić pamięć.</translation>
<translation id="3422472998109090673">Strona <ph name="HOST_NAME" /> jest obecnie nieosiÄ…galna.</translation>
+<translation id="3427092606871434483">Zezwalaj (domyślnie)</translation>
<translation id="3427342743765426898">&amp;Ponów edycję</translation>
<translation id="3431636764301398940">Zapisz tÄ™ kartÄ™ na tym urzÄ…dzeniu</translation>
<translation id="3435896845095436175">WÅ‚Ä…cz</translation>
<translation id="3447661539832366887">Właściciel tego urządzenia wyłączył grę z dinozaurem.</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">Okres pobierania:</translation>
<translation id="3462200631372590220">Ukryj zaawansowane</translation>
<translation id="3467763166455606212">Wymagane jest imiÄ™ i nazwisko posiadacza karty</translation>
<translation id="3478058380795961209">Miesiąc utraty ważności</translation>
<translation id="3479539252931486093">Zaskoczyło Cię to? <ph name="BEGIN_LINK" />Daj nam znać<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Nie teraz</translation>
-<translation id="348000606199325318">Identyfikator awarii: <ph name="CRASH_LOCAL_ID" /> (identyfikator serwera: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Obecnie nie możemy się skontaktować z Twoim rodzicem. Spróbuj ponownie.</translation>
<translation id="3528171143076753409">Certyfikat serwera nie jest zaufany.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Co najmniej 1 element na synchronizowanych urządzeniach}=1{1 element (i więcej na synchronizowanych urządzeniach)}few{# elementy (i więcej na synchronizowanych urządzeniach)}many{# elementów (i więcej na synchronizowanych urządzeniach)}other{# elementu (i więcej na synchronizowanych urządzeniach)}}</translation>
<translation id="3539171420378717834">Zachowaj kopiÄ™ tej karty na urzÄ…dzeniu</translation>
<translation id="3542684924769048008">Używaj hasła dla:</translation>
+<translation id="3545341443414427877">Nie można nawiązać połączenia prywatnego z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, bo data i godzina ustawione na komputerze (<ph name="DATE_AND_TIME" />) są nieprawidłowe. <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Szyfruj wszystkie synchronizowane dane za pomocą hasła synchronizacji</translation>
-<translation id="3549761410225185768">Jeszcze <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat pochodzi z <ph name="DOMAIN2" />. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Twój menedżer może ją dla Ciebie odblokować</translation>
<translation id="3566021033012934673">Połączenie nie jest prywatne</translation>
+<translation id="3569145463236695319">&lt;p&gt;Nie można nawiązać połączenia prywatnego z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, bo data i godzina ustawione na komputerze (<ph name="DATE_AND_TIME" />) są nieprawidłowe.&lt;/p&gt;
+
+ &lt;p&gt;Popraw datę i godzinę w sekcji &lt;strong&gt;Ogólne&lt;/strong&gt; w aplikacji &lt;strong&gt;Ustawienia&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Dodaj nazwÄ™</translation>
<translation id="3583757800736429874">&amp;Ponów przeniesienie</translation>
<translation id="3586931643579894722">Ukryj szczegóły</translation>
-<translation id="3587482841069643663">Wszystkie</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Wpisz prawidłową datę ważności</translation>
<translation id="36224234498066874">Wyczyść dane przeglądania...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informacje o certyfikacie</translation>
<translation id="3690164694835360974">Logowanie nie jest bezpieczne</translation>
<translation id="3693415264595406141">Hasło:</translation>
-<translation id="3696411085566228381">brak</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ÅadujÄ™...</translation>
<translation id="3712624925041724820">Brak wolnych licencji</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Sprawdź serwer proxy, zaporę sieciową i konfigurację DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Jeśli rozumiesz zagrożenie, możesz <ph name="BEGIN_LINK" />odwiedzić tę niebezpieczną stronę<ph name="END_LINK" />, zanim niebezpieczne programy zostaną usunięte.</translation>
<translation id="3739623965217189342">Skopiowany link</translation>
+<translation id="3744899669254331632">Nie możesz teraz odwiedzić strony <ph name="SITE" />, ponieważ wysłała ona zaszyfrowane dane logowania, których Chromium nie może przetworzyć. Błędy sieciowe i ataki są zazwyczaj tymczasowe, więc prawdopodobnie strona będzie dostępna później.</translation>
+<translation id="3748148204939282805">Osoby atakujące na stronie <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą podstępem nakłonić Cię do wykonania czynności niebezpiecznych takich jak zainstalowanie oprogramowania czy ujawnienie danych osobowych (na przykład haseł, numerów telefonów lub danych kart kredytowych). <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Tłumaczenie nie powiodło się z powodu błędu serwera.</translation>
<translation id="3759461132968374835">Brak ostatnio zgłoszonych awarii. Awarie, które nastąpiły wówczas, gdy funkcja zgłaszania awarii była wyłączona, nie są tutaj wymienione.</translation>
+<translation id="3778403066972421603">Czy chcesz zapisać tę kartę na swoim koncie Google i na tym urządzeniu?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Wygasa: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Jeśli używasz serwera proxy...</translation>
<translation id="3828924085048779000">Puste hasło jest niedozwolone.</translation>
-<translation id="3845539888601087042">Wyświetlam historię z urządzeń, na których jesteś zalogowany. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Wstecz</translation>
<translation id="3858027520442213535">Zaktualizuj datÄ™ i godzinÄ™</translation>
<translation id="3884278016824448484">Konflikt identyfikatorów urządzeń</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Twoja prośba o dostęp to tej strony została wysłana do: <ph name="NAME" /></translation>
<translation id="3890664840433101773">Dodaj adres e-mail</translation>
<translation id="3901925938762663762">Karta straciła ważność</translation>
-<translation id="3933571093587347751">{1,plural, =1{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać od jutra. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}few{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać za # dni. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}many{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać za # ni. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}other{Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa przypuszczalnie zacznie obowiązywać za # dnia. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Nie można wczytać dokumentu PDF</translation>
+<translation id="3945915738023014686">Przesłano raport o awarii – identyfikator: <ph name="CRASH_ID" /> (lokalny identyfikator awarii: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie określa alternatywnych nazw podmiotu. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="3963721102035795474">Tryb czytnika</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Brak}=1{Z 1 witryny }few{Z # witryn }many{Z # witryn }other{Z # witryny }}</translation>
<translation id="397105322502079400">Obliczanie...</translation>
<translation id="3973234410852337861">Strona <ph name="HOST_NAME" /> jest zablokowana</translation>
+<translation id="3987940399970879459">Mniej niż 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 strona w pobliżu}few{# strony w pobliżu}many{# stron w pobliżu}other{# strony w pobliżu}}</translation>
<translation id="4021036232240155012">DNS to usługa sieciowa tłumacząca nazwę serwera na jego adres internetowy.</translation>
<translation id="4030383055268325496">&amp;Cofnij dodanie</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Proxy skonfigurowano do używania URL-a skryptu PAC, a nie ustalonych serwerów proxy.</translation>
<translation id="4098354747657067197">Wchodzisz na stronę wprowadzającą w błąd</translation>
<translation id="4103249731201008433">Numer seryjny urządzenia jest nieprawidłowy</translation>
+<translation id="410351446219883937">Autoodtwarzanie</translation>
<translation id="4103763322291513355">Wejdź na stronę &lt;strong&gt;chrome://policy&lt;/strong&gt;, aby wyświetlić czarną listę URL-i oraz inne zasady egzekwowane przez administratora systemu.</translation>
-<translation id="4110615724604346410">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat zawiera błędy. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Zawsze zezwalaj w tej witrynie</translation>
<translation id="4117700440116928470">Ten zakres zasad nie jest obsługiwany.</translation>
-<translation id="4118212371799607889">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat nie jest zaufany w Chromium. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 inny wpis}few{# inne wpisy}many{# innych wpisów}other{# innego wpisu}}</translation>
<translation id="4130226655945681476">Sprawdź kable sieciowe, modem i router</translation>
+<translation id="413544239732274901">Więcej informacji</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Użyj globalnego ustawienia domyślnego (Wykrywaj)</translation>
+<translation id="4165986682804962316">Ustawienia witryny</translation>
<translation id="4169947484918424451">Czy Chromium ma zapisać tę kartę?</translation>
<translation id="4171400957073367226">Nieprawidłowy podpis weryfikujący</translation>
<translation id="4196861286325780578">&amp;Ponów przeniesienie</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Sprawdź konfigurację zapory sieciowej i oprogramowania antywirusowego<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{brak}=1{1 aplikacja ($1)}=2{2 aplikacje ($1, $2)}few{# aplikacje ($1, $2, $3)}many{# aplikacji ($1, $2, $3)}other{# aplikacji ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Awarie</translation>
+<translation id="422022731706691852">Osoby atakujące na stronie <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą próbować podstępem nakłonić Cię do zainstalowania programów utrudniających korzystanie z internetu (na przykład zmieniających stronę główną lub wyświetlających dodatkowe reklamy na odwiedzanych stronach). <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Uruchom diagnostykÄ™ sieci<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Ważny</translation>
<translation id="4250431568374086873">Twoje połączenie z tą witryną nie jest w pełni bezpieczne</translation>
<translation id="4250680216510889253">Nie</translation>
<translation id="425582637250725228">Wprowadzone zmiany mogą nie zostać zapisane.</translation>
<translation id="4258748452823770588">Nieprawidłowy podpis</translation>
+<translation id="4265872034478892965">Dozwolone przez administratora</translation>
<translation id="4269787794583293679">(Brak nazwy użytkownika)</translation>
<translation id="4275830172053184480">Zrestartuj urzÄ…dzenie</translation>
<translation id="4280429058323657511">, ważna do: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Bezpieczne przeglądanie Google ostatnio <ph name="BEGIN_LINK" />wykryło szkodliwe programy<ph name="END_LINK" /> na <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Propozycje rodziców</translation>
<translation id="4304224509867189079">Zaloguj siÄ™</translation>
-<translation id="432290197980158659">Serwer przedstawił certyfikat, który nie spełnia wbudowanych warunków. Przeglądarka sprawdza je w przypadku określonych witryn wymagających wysokiego poziomu bezpieczeństwa. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blokuj (domyślnie)</translation>
<translation id="4325863107915753736">Nie udało się znaleźć artykułu</translation>
<translation id="4326324639298822553">Sprawdź datę ważności i spróbuj ponownie</translation>
<translation id="4331708818696583467">Niezabezpieczona</translation>
<translation id="4356973930735388585">Osoby atakujące tę stronę mogą próbować zainstalować na Twoim komputerze niebezpieczne programy przeznaczone do kradzieży lub usuwania Twoich danych (na przykład zdjęć, haseł, wiadomości czy numerów kart kredytowych).</translation>
<translation id="4372948949327679948">Oczekiwano wartości typu <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Próbujesz wejść na <ph name="DOMAIN" />, ale serwer przedstawił certyfikat unieważniony przez wystawcę. Oznacza to, że dane uwierzytelniające podane przez serwer są zupełnie niewiarygodne. Możliwe, że komunikujesz się z intruzem.</translation>
<translation id="4381091992796011497">Nazwa użytkownika:</translation>
<translation id="4394049700291259645">Wyłącz</translation>
<translation id="4406896451731180161">wyniki wyszukiwania</translation>
+<translation id="4424024547088906515">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest zaufany w Chrome. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="4432688616882109544">Serwer <ph name="HOST_NAME" /> nie zaakceptował lub nie otrzymał Twojego certyfikatu logowania.</translation>
<translation id="443673843213245140">Korzystanie z serwera proxy jest wyłączone, ale podano konfigurację proxy.</translation>
-<translation id="4492190037599258964">Wyniki wyszukiwania dla „<ph name="SEARCH_STRING" />â€</translation>
<translation id="4506176782989081258">Błąd sprawdzania poprawności: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Skontaktuj siÄ™ z administratorem systemu</translation>
<translation id="450710068430902550">Udostępnianie administratorowi</translation>
<translation id="4515275063822566619">Karty i adresy pochodzą z Chrome i Twojego konta Google (<ph name="ACCOUNT_EMAIL" />). Możesz nimi zarządzać w <ph name="BEGIN_LINK" />Ustawieniach<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Szczegóły</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Spróbuj wyłączyć rozszerzenia.</translation>
<translation id="457875822857220463">Dostawa</translation>
<translation id="4587425331216688090">Usunąć ten adres z Chrome?</translation>
-<translation id="4589078953350245614">Próbujesz wejść na <ph name="DOMAIN" />, ale serwer przedstawił nieprawidłowy certyfikat. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Połączenie z <ph name="DOMAIN" /> jest szyfrowane przy użyciu nowoczesnego zestawu szyfrów.</translation>
<translation id="4594403342090139922">&amp;Cofnij usunięcie</translation>
<translation id="4619615317237390068">Karty z innych urządzeń</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa ma błędy. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
+<translation id="4690462567478992370">Przestań używać nieprawidłowego certyfikatu</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Połączenie zostało przerwane</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Uruchom DiagnostykÄ™ sieci systemu Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Wystąpił nieznany błąd.</translation>
<translation id="4800132727771399293">Sprawdź datę ważności i kod CVC, a potem spróbuj ponownie</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Nie możesz teraz wejść na stronę <ph name="SITE" />, bo wysłała ona zaszyfrowane dane logowania, których Google Chrome nie może przetworzyć. Błędy sieci i ataki są zazwyczaj przejściowe, więc prawdopodobnie strona będzie wkrótce działać.</translation>
<translation id="4813512666221746211">BÅ‚Ä…d sieci</translation>
<translation id="4816492930507672669">Dopasuj do strony</translation>
<translation id="483020001682031208">Brak stron internetu rzeczy do pokazania</translation>
<translation id="4850886885716139402">Widok</translation>
<translation id="4854362297993841467">Ta metoda dostawy jest niedostępna. Wybierz inną.</translation>
<translation id="4858792381671956233">Zapytałeś rodziców, czy możesz wejść na tę stronę</translation>
+<translation id="4863764087567530506">Te treści mogą próbować przez oszustwo nakłonić Cię do zainstalowania oprogramowania lub ujawnienia danych osobowych. <ph name="BEGIN_LINK" />Wyświetl mimo to<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Przeszukaj historiÄ™</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{i jeszcze 1 strona}few{i jeszcze # strony}many{i jeszcze # stron}other{i jeszcze # strony}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Ta strona została przetłumaczona z nieznanego języka na język <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Płatność</translation>
<translation id="4926049483395192435">Musi być określona.</translation>
<translation id="495170559598752135">Czynności</translation>
<translation id="4958444002117714549">Rozwiń listę</translation>
-<translation id="4962322354953122629">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat nie jest zaufany w Chrome. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Ponownie włącz ostrzeżenia</translation>
<translation id="4989809363548539747">Ta wtyczka nie jest obsługiwana</translation>
<translation id="5002932099480077015">Jeśli włączysz tę opcję, Chrome zapisze kopię Twojej karty na tym urządzeniu, by umożliwić Ci szybsze wypełnianie formularzy.</translation>
<translation id="5018422839182700155">Nie można otworzyć tej strony</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Sprawdź zasady administratora</translation>
<translation id="5029568752722684782">Usuń kopię</translation>
<translation id="5031870354684148875">Tłumacz Google – informacje</translation>
+<translation id="5039804452771397117">Zezwalaj</translation>
<translation id="5040262127954254034">Prywatność</translation>
<translation id="5045550434625856497">Nieprawidłowe hasło</translation>
<translation id="5056549851600133418">Artykuły dla Ciebie</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Sprawdź adres serwera proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Bez plików cookie}=1{1 strona używa plików cookie. }few{# strony używają plików cookie. }many{# stron używa plików cookie. }other{# strony używa plików cookie. }}</translation>
<translation id="5087286274860437796">Certyfikat serwera nie jest obecnie ważny.</translation>
<translation id="5087580092889165836">Dodaj kartÄ™</translation>
<translation id="5089810972385038852">Stan</translation>
+<translation id="5094747076828555589">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest zaufany w Chromium. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="5095208057601539847">Prowincja</translation>
<translation id="5115563688576182185">(64-bitowa)</translation>
<translation id="5141240743006678641">Szyfruj synchronizowane hasła za pomocą danych logowania Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-mail jest wymagany</translation>
<translation id="5251803541071282808">Chmura</translation>
<translation id="5277279256032773186">Korzystasz z Chrome w pracy? Firmy mogą zarządzać ustawieniami Chrome swoich pracowników. Więcej informacji</translation>
+<translation id="5297526204711817721">Połączenie z tą stroną nie jest prywatne. Aby w dowolnym momencie zamknąć tryb VR, zdejmij gogle i naciśnij Wstecz.</translation>
<translation id="5299298092464848405">Podczas przetwarzania zasady wystąpił błąd</translation>
-<translation id="5300589172476337783">Pokaż</translation>
<translation id="5308689395849655368">Funkcja zgłaszania awarii jest wyłączona.</translation>
<translation id="5317780077021120954">Zapisz</translation>
<translation id="5327248766486351172">Nazwa</translation>
-<translation id="5337705430875057403">Osoby atakujące stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą podstępem nakłonić Cię do zrobienia czegoś niebezpiecznego, np. zainstalowania oprogramowania lub ujawnienia danych osobowych (takich jak hasła, numery telefonów i dane kart kredytowych).</translation>
-<translation id="5359637492792381994">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest obecnie ważny. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Nie możesz teraz otworzyć strony <ph name="SITE" />, bo jej certyfikat został unieważniony. Błędy sieci i ataki są zazwyczaj przejściowe, więc prawdopodobnie strona będzie wkrótce działać.</translation>
<translation id="536296301121032821">Zapisanie ustawień zasady nie powiodło się</translation>
<translation id="5386426401304769735">ÅaÅ„cuch certyfikatów tej witryny zawiera certyfikat podpisany za pomocÄ… SHA-1.</translation>
<translation id="5402410679244714488">Data ważności: <ph name="EXPIRATION_DATE_ABBR" />, ostatnio używana ponad roku temu</translation>
+<translation id="540969355065856584">Ten serwer nie może udowodnić, że należy do domeny <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest obecnie ważny. Może to być spowodowane nieprawidłową konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
<translation id="5421136146218899937">Wyczyść dane przeglądania...</translation>
<translation id="5430298929874300616">Usuń zakładkę</translation>
<translation id="5431657950005405462">Nie znaleziono pliku</translation>
-<translation id="5435775191620395718">Wyświetlam historię z tego urządzenia. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">BÅ‚Ä…d podczas sprawdzania poprawnoÅ›ci schematu – „<ph name="ERROR_PATH" />â€: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Nie można znaleźć tej strony na <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">Nieprawidłowy czas zasady</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> z <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Nieprawidłowe</translation>
<translation id="5470861586879999274">&amp;Ponów edycję</translation>
<translation id="54817484435770891">Dodaj poprawny adres</translation>
<translation id="5492298309214877701">Ta witryna w intranecie firmy, organizacji czy szkoły ma ten sam URL co zewnętrzna strona internetowa.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Odbiór spod tego adresu jest niemożliwy. Wybierz inny adres.</translation>
<translation id="5572851009514199876">Uruchom Chrome i zaloguj się w nim, by mógł sprawdzić, czy masz uprawnienia dostępu do tej strony.</translation>
<translation id="5580958916614886209">Sprawdź miesiąc ważności i spróbuj ponownie</translation>
+<translation id="5586446728396275693">Brak zapisanych adresów</translation>
+<translation id="5595485650161345191">Edytuj adres</translation>
<translation id="560412284261940334">Zarządzanie jest nieobsługiwane</translation>
<translation id="5610142619324316209">Sprawdź połączenie</translation>
<translation id="5610807607761827392">Możesz zarządzać kartami i adresami w <ph name="BEGIN_LINK" />Ustawieniach<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Chcesz opuścić tę stronę?</translation>
<translation id="5629630648637658800">Åadowanie ustawieÅ„ zasady nie powiodÅ‚o siÄ™</translation>
<translation id="5631439013527180824">Nieprawidłowy token zarządzania urządzeniem</translation>
+<translation id="5633066919399395251">Osoby obecnie atakujące stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą próbować zainstalować na Twoim komputerze niebezpieczne programy, które wykradają lub usuwają informacje (na przykład zdjęcia, hasła, wiadomości lub dane kart kredytowych). <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Lokalizacja</translation>
+<translation id="5659593005791499971">E-mail</translation>
<translation id="5669703222995421982">Otrzymywanie spersonalizowanych treści</translation>
<translation id="5675650730144413517">Ta strona nie działa</translation>
-<translation id="5677928146339483299">Zablokowane</translation>
-<translation id="5694783966845939798">Próbujesz połączyć się z domeną <ph name="DOMAIN" />, ale serwer przedstawił certyfikat podpisany słabym algorytmem (np. SHA-1). Oznacza to, że dane logowania podane przez serwer mogły zostać sfałszowane, a serwer może nie być tym, którego oczekujesz (możliwe, że komunikujesz się z intruzem). <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">Tożsamość witryny nie została zweryfikowana.</translation>
+<translation id="5713016350996637505">Zablokowano treści wprowadzające w błąd</translation>
<translation id="5720705177508910913">Bieżący użytkownik</translation>
<translation id="5732392974455271431">Mogą ją dla Ciebie odblokować Twoi rodzice</translation>
<translation id="5763042198335101085">Wpisz prawidłowy adres e-mail</translation>
<translation id="5765072501007116331">Aby zobaczyć metody dostawy oraz wymagania, wybierz adres</translation>
+<translation id="5778550464785688721">Pełne sterowanie urządzeniami MIDI</translation>
<translation id="5784606427469807560">Podczas potwierdzania karty wystąpił problem. Sprawdź połączenie internetowe i spróbuj ponownie.</translation>
<translation id="5785756445106461925">Ta strona zawiera także niezabezpieczone zasoby. Podczas przesyłania mogą je wyświetlić inni użytkownicy, a osoby atakujące mogą je zmodyfikować, by zmienić wygląd strony.</translation>
<translation id="5786044859038896871">Chcesz wpisać dane swojej karty?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Ponów dodanie</translation>
<translation id="5814352347845180253">Możesz stracić dostęp do płatnych treści w <ph name="SITE" /> i na niektórych innych stronach.</translation>
<translation id="5838278095973806738">Nie podawaj żadnych informacji poufnych (takich jak hasła czy karty kredytowe) w tej witrynie, bo osoby atakujące będą mogły je wykraść.</translation>
-<translation id="5843436854350372569">Próbujesz połączyć się z <ph name="DOMAIN" />, ale serwer przedstawił certyfikat ze słabym kluczem. Intruz mógł złamać klucz prywatny, a serwer może nie być tym, którego oczekujesz (możliwe, że komunikujesz się z intruzem). <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Ta witryna jest nieosiÄ…galna</translation>
<translation id="5869522115854928033">Zapisane hasła</translation>
<translation id="5872918882028971132">Propozycje rodziców</translation>
<translation id="5901630391730855834">Żółty</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (zsynchronizowane)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{W użyciu: 1}few{W użyciu: #}many{W użyciu: #}other{W użyciu: #}}</translation>
<translation id="5926846154125914413">Możesz stracić dostęp do płatnych treści na niektórych stronach.</translation>
<translation id="5959728338436674663">Automatycznie wysyłaj do Google niektóre <ph name="BEGIN_WHITEPAPER_LINK" />informacje o systemie i część zawartości stron<ph name="END_WHITEPAPER_LINK" />, by pomóc w wykrywaniu niebezpiecznych aplikacji i witryn. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Tydzień</translation>
<translation id="5967867314010545767">Usuń z historii</translation>
<translation id="5975083100439434680">Pomniejsz</translation>
<translation id="598637245381783098">Nie można otworzyć aplikacji do płatności</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Strona 1}few{Strona #}many{Strona #}other{Strona #}}</translation>
<translation id="6017514345406065928">Zielony</translation>
+<translation id="6017850046339264347">Osoby atakujące stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą instalować wprowadzające w błąd aplikacje, które udają, że są przeznaczone do czegoś innego niż w rzeczywistości, lub zbierają dane, na podstawie których można Cię śledzić. <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (zsynchronizowane)</translation>
<translation id="6027201098523975773">Wpisz imiÄ™ i nazwisko</translation>
<translation id="6040143037577758943">Zamknij</translation>
<translation id="6042308850641462728">Więcej</translation>
+<translation id="6047233362582046994">Jeśli rozumiesz zagrożenie, możesz <ph name="BEGIN_LINK" />wejść na tę stronę<ph name="END_LINK" />, zanim szkodliwe aplikacje zostaną usunięte.</translation>
+<translation id="6051221802930200923">Nie możesz teraz otworzyć strony <ph name="SITE" />, ponieważ stosuje ona przypinanie certyfikatów. Błędy sieciowe i ataki są zazwyczaj tymczasowe, więc prawdopodobnie strona będzie dostępna później.</translation>
<translation id="6060685159320643512">Ostrożnie, na tych eksperymentach można się sparzyć</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{brak}=1{1}few{#}many{#}other{#}}</translation>
+<translation id="6080696365213338172">Masz dostęp do treści dzięki certyfikatowi dostarczonemu przez administratora. Administrator może odczytać dane, jakie udostępnisz w <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Brak}=1{1 hasło (synchronizowane)}few{# hasła (synchronizowane)}many{# haseł (synchronizowanych)}other{# hasła (synchronizowanego)}}</translation>
<translation id="6146055958333702838">Sprawdź wszystkie kable i uruchom ponownie wszelkie używane routery, modemy
i inne urzÄ…dzenia sieciowe.</translation>
<translation id="614940544461990577">Wypróbuj te rozwiązania:</translation>
<translation id="6151417162996330722">Certyfikat serwera ma za długi okres ważności.</translation>
<translation id="6157877588268064908">Aby zobaczyć metody wysyłki oraz wymagania, wybierz adres</translation>
+<translation id="6158003235852588289">Bezpieczne przeglądanie Google wykryło ostatnio próbę wyłudzenia informacji na stronie <ph name="SITE" />. Strony wyłudzające informacje udają inne strony, aby Cię oszukać.</translation>
<translation id="6165508094623778733">Więcej informacji</translation>
+<translation id="6169916984152623906">Teraz możesz korzystać z internetu w trybie prywatnym. Inne osoby używające tego urządzenia nie zobaczą Twojej aktywności. Pamiętaj tylko, że zakładki i pobrane pliki są zapisywane.</translation>
<translation id="6177128806592000436">Twoje połączenie z tą witryną nie jest bezpieczne</translation>
<translation id="6184817833369986695">(kohorta: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Sprawdź połączenie z internetem</translation>
<translation id="6218753634732582820">Usunąć ten adres z Chromium?</translation>
+<translation id="6221345481584921695">Bezpieczne przeglądanie Google <ph name="BEGIN_LINK" />wykryło ostatnio złośliwe oprogramowanie<ph name="END_LINK" /> na <ph name="SITE" />. Strony, które zazwyczaj są bezpieczne, zostają czasem zainfekowane destrukcyjnym oprogramowaniem. Źródłem złośliwej zawartości jest <ph name="SUBRESOURCE_HOST" /> – znany dystrybutor złośliwego oprogramowania.</translation>
<translation id="6251924700383757765">Polityka prywatności</translation>
<translation id="6254436959401408446">Za mało pamięci, by otworzyć tę stronę</translation>
<translation id="625755898061068298">Wyłączyłeś ostrzeżenia dotyczące bezpieczeństwa tej witryny.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Edytuj zakładkę</translation>
<translation id="6410264514553301377">Wpisz datę ważności i kod CVC karty <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Zapytałeś rodzica, czy możesz odwiedzić tę stronę</translation>
-<translation id="6416403317709441254">Nie możesz teraz wejść na <ph name="SITE" />, bo ta witryna wysłała zaszyfrowane dane logowania, których Chromium nie może przetworzyć. Błędy sieci i ataki są zazwyczaj przejściowe, więc prawdopodobnie później strona będzie działać. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Nie można sprawdzić, czy certyfikat został unieważniony.</translation>
<translation id="6433490469411711332">Edytuj dane kontaktowe</translation>
<translation id="6433595998831338502">Serwer <ph name="HOST_NAME" /> odrzucił połączenie.</translation>
<translation id="6446608382365791566">Dodaj więcej informacji</translation>
+<translation id="6447842834002726250">Pliki cookie</translation>
<translation id="6451458296329894277">Potwierdź ponowne przesłanie formularza</translation>
<translation id="6456339708790392414">Twoja płatność</translation>
<translation id="6458467102616083041">Ignorowana, ponieważ wyszukiwarka domyślna jest wyłączona przez zasadę.</translation>
-<translation id="6462969404041126431">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat mógł zostać unieważniony. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Zasady dotyczące urządzeń</translation>
<translation id="6477321094435799029">Chrome wykrył nietypowy kod na tej stronie i zablokował ją, by chronić Twoje dane osobowe (np. hasła, numery telefonu czy dane kart kredytowych).</translation>
<translation id="6489534406876378309">Rozpocznij przesyłanie informacji o awariach</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Data ważności: <ph name="EXPIRATION_DATE_ABBR" />, ostatnio używana: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Twój menedżer jeszcze na to nie zezwolił</translation>
<translation id="6569060085658103619">PrzeglÄ…dasz stronÄ™ rozszerzenia</translation>
-<translation id="6593753688552673085">mniej niż <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Te treści mogą próbować instalować na Twoim urządzeniu niebezpieczne oprogramowanie, które wykrada lub usuwa Twoje dane. <ph name="BEGIN_LINK" />Wyświetl mimo to<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opcje szyfrowania</translation>
<translation id="662080504995468778">Zostań</translation>
<translation id="6626291197371920147">Dodaj prawidłowy numer karty</translation>
<translation id="6628463337424475685">Wyszukiwarka <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Osoby obecnie atakujące stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą próbować zainstalować na Twoim komputerze Mac niebezpieczne programy wykradające lub usuwające informacje (na przykład zdjęcia, hasła, wiadomości lub dane kart kredytowych). <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Zasada jest przestarzała.</translation>
-<translation id="6652240803263749613">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat nie jest zaufany w systemie operacyjnym Twojego komputera. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Usunąć tę podpowiedź do formularza z Chromium?</translation>
<translation id="6685834062052613830">Wyloguj się i dokończ konfigurację</translation>
<translation id="6710213216561001401">Wstecz</translation>
<translation id="6710594484020273272">&lt;Wpisz wyszukiwane słowa&gt;</translation>
<translation id="6711464428925977395">Serwer proxy działa nieprawidłowo albo adres jest błędny.</translation>
<translation id="6727102863431372879">Ustaw</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{brak}=1{1 element}few{# elementy}many{# elementów}other{# elementu}}</translation>
<translation id="674375294223700098">Nieznany błąd certyfikatu serwera.</translation>
<translation id="6753269504797312559">Wartość zasady</translation>
<translation id="6757797048963528358">Twoje urządzenie przeszło w tryb uśpienia.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Identyfikator dostosowania</translation>
<translation id="6820686453637990663">Kod CVC</translation>
<translation id="6824266427216888781">Nie udało się załadować danych dotyczących regionów</translation>
+<translation id="6825578344716086703">Próbujesz wejść na <ph name="DOMAIN" />, ale serwer przedstawił certyfikat podpisany słabym algorytmem (takim jak SHA-1). Oznacza to, że dane uwierzytelniające podane przez serwer mogły zostać sfałszowane, a serwer może nie być tym, którego oczekujesz (możliwe, że komunikujesz się z intruzem).</translation>
+<translation id="6830728435402077660">Niezabezpieczona</translation>
<translation id="6831043979455480757">TÅ‚umacz</translation>
<translation id="6839929833149231406">Dzielnica</translation>
<translation id="6874604403660855544">&amp;Ponów dodanie</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Karta została potwierdzona</translation>
<translation id="6897140037006041989">Klient</translation>
<translation id="6915804003454593391">Użytkownik:</translation>
+<translation id="6945221475159498467">Wybierz</translation>
<translation id="6948701128805548767">Aby zobaczyć metody odbioru oraz wymagania, wybierz adres</translation>
<translation id="6957887021205513506">Certyfikat serwera wydaje się sfałszowany.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Określono zarówno stałe serwery proxy, jak i URL skryptu PAC.</translation>
<translation id="6989763994942163495">Pokaż ustawienia zaawansowane...</translation>
<translation id="7000990526846637657">Brak wpisów historii</translation>
-<translation id="7009986207543992532">Próbujesz połączyć się z <ph name="DOMAIN" />, ale serwer przedstawił certyfikat, którego okres ważności jest za długi, by był wiarygodny. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Inne rodzaje historii przeglądania mogą być nadal dostępne na Twoim koncie Google na <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Hasła</translation>
+<translation id="7050187094878475250">Próbujesz połączyć się z domeną <ph name="DOMAIN" />, ale serwer przedstawił certyfikat, którego okres ważności jest za długi, by był wiarygodny.</translation>
+<translation id="7053983685419859001">Blokuj</translation>
<translation id="7064851114919012435">Dane kontaktowe</translation>
<translation id="7079718277001814089">Ta strona zawiera złośliwe oprogramowanie</translation>
<translation id="7087282848513945231">Hrabstwo</translation>
-<translation id="7088615885725309056">Starsze</translation>
<translation id="7090678807593890770">Wyszukaj w Google: <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Dozwolone przez rozszerzenie</translation>
<translation id="7119414471315195487">Zamknij inne karty lub programy</translation>
<translation id="7129409597930077180">Nie można wysłać pod ten adres. Wybierz inny.</translation>
<translation id="7138472120740807366">Metoda dostawy</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Przetwarzanie</translation>
<translation id="724691107663265825">Strona, którą chcesz otworzyć, zawiera złośliwe oprogramowanie</translation>
<translation id="724975217298816891">Wpisz datę ważności i kod CVC karty <ph name="CREDIT_CARD" />, by zaktualizować jej szczegółowe dane. Po potwierdzeniu zostaną one udostępnione tej stronie.</translation>
-<translation id="725866823122871198">Nie można nawiązać prywatnego połączenia z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, ponieważ data i godzina (<ph name="DATE_AND_TIME" />) ustawione na komputerze są nieprawidłowe.</translation>
+<translation id="7260504762447901703">Anuluj dostęp</translation>
<translation id="7275334191706090484">Zakładki zarządzane</translation>
<translation id="7298195798382681320">Zalecane</translation>
<translation id="7309308571273880165">Raport o awarii utworzony w dniu: <ph name="CRASH_TIME" /> (użytkownik zażądał przesłania raportu, ale nie został on jeszcze przesłany)</translation>
<translation id="7334320624316649418">&amp;Ponów zmianę kolejności</translation>
<translation id="733923710415886693">Certyfikat serwera nie został ujawniony przez protokół Certificate Transparency.</translation>
-<translation id="7351800657706554155">Nie możesz teraz wejść na stronę <ph name="SITE" />, bo jej certyfikat został unieważniony. Błędy sieci i ataki są zazwyczaj przejściowe, więc prawdopodobnie później strona będzie działać. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Wiersz poleceń</translation>
<translation id="7372973238305370288">wynik wyszukiwania</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> – <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nie</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Potwierdź kartę</translation>
-<translation id="7394102162464064926">Czy na pewno chcesz usunąć te strony ze swojej historii?
-
-Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />.</translation>
<translation id="7400418766976504921">Adres URL</translation>
<translation id="7419106976560586862">Ścieżka profilu</translation>
<translation id="7424977062513257142">Komunikat z elementu umieszczonego na bieżącej stronie internetowej:</translation>
@@ -688,6 +754,7 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="7444046173054089907">Ta strona jest zablokowana</translation>
<translation id="7445762425076701745">Nie można w pełni zweryfikować tożsamości serwera, z którym nawiązano połączenie. Nawiązano połączenie z serwerem przy użyciu nazwy obowiązującej jedynie w Twojej sieci i której własności zewnętrzny urząd certyfikacji nie jest w stanie zweryfikować. Niektóre urzędy certyfikacji wydają certyfikaty dla takich nazw bez względu na to, że nie można upewnić się, iż nawiązano połączenie z witryną, z którą zamierzano, a nie z intruzem.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Dowiedz się więcej<ph name="END_LINK" /> o tym problemie.</translation>
+<translation id="7455133967321480974">Użyj globalnej wartości domyślnej (Blokuj)</translation>
<translation id="7460163899615895653">W tym miejscu pojawią się Twoje ostatnie karty z innych urządzeń</translation>
<translation id="7469372306589899959">Potwierdzam kartÄ™</translation>
<translation id="7481312909269577407">Dalej</translation>
@@ -695,36 +762,43 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="7508255263130623398">Zwrócony identyfikator urządzenia dla zasad jest pusty lub nie pasuje do bieżącego identyfikatora urządzenia</translation>
<translation id="7514365320538308">Pobierz</translation>
<translation id="7518003948725431193">Nie znaleziono strony internetowej pod adresem <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Wartość</translation>
<translation id="7537536606612762813">ObowiÄ…zkowe</translation>
+<translation id="7542403920425041731">Po potwierdzeniu szczegółowe dane karty zostaną udostępnione tej stronie.</translation>
<translation id="7542995811387359312">Automatyczne wypełnianie danych karty kredytowej jest wyłączone, ponieważ ten formularz nie korzysta z bezpiecznego połączenia.</translation>
<translation id="7543525346216957623">PoproÅ› rodzica</translation>
<translation id="7549584377607005141">Do poprawnego wyświetlenia tej strony internetowej wymagane są dane wpisane przez Ciebie wcześniej. Możesz wysłać je ponownie, ale spowoduje to powtórzenie wszystkich działań wykonanych poprzednio przez stronę.</translation>
<translation id="7552846755917812628">Skorzystaj z tych wskazówek:</translation>
<translation id="7554791636758816595">Nowa karta</translation>
+<translation id="7567204685887185387">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa mógł zostać wydany w celu oszustwa. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> inny}few{<ph name="CONTACT_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> inne}many{<ph name="CONTACT_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> innych}other{<ph name="CONTACT_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> innego}}</translation>
<translation id="7568593326407688803">Język strony:<ph name="ORIGINAL_LANGUAGE" />Chcesz ją przetłumaczyć?</translation>
<translation id="7569952961197462199">Usunąć tę kartę kredytową z Chrome?</translation>
<translation id="7569983096843329377">Czarny</translation>
<translation id="7578104083680115302">Używaj swoich kart zapisanych w Google, by łatwiej dokonywać płatności na stronach i w aplikacjach na różnych urządzeniach.</translation>
<translation id="7588950540487816470">Internet rzeczy</translation>
<translation id="7592362899630581445">Certyfikat serwera narusza ograniczenia dotyczÄ…ce nazw.</translation>
+<translation id="7598391785903975535">Mniej niż <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Serwer <ph name="HOST_NAME" /> nie może teraz obsłużyć tego żądania.</translation>
<translation id="7600965453749440009">Nigdy nie tłumacz z języka: <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Wartość spoza zakresu (<ph name="VALUE" />)</translation>
<translation id="7613889955535752492">Wygasa: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Masz już dane zaszyfrowane przy użyciu innej wersji hasła konta Google. Wpisz je poniżej.</translation>
-<translation id="7634554953375732414">Twoje połączenie z tą witryną nie jest prywatne.</translation>
<translation id="7637571805876720304">Usunąć tę kartę kredytową z Chromium?</translation>
<translation id="765676359832457558">Ukryj ustawienia zaawansowane...</translation>
<translation id="7658239707568436148">Anuluj</translation>
+<translation id="7662298039739062396">Ustawienie kontrolowane przez rozszerzenie</translation>
<translation id="7667346355482952095">Zwrócony token zasad jest pusty lub nie pasuje do bieżącego tokena</translation>
<translation id="7668654391829183341">Nieznane urzÄ…dzenie</translation>
<translation id="7669271284792375604">Osoby atakujące tę stronę mogą podstępem próbować nakłonić Cię do zainstalowania programów utrudniających przeglądanie internetu (np. zmieniających stronę główną lub wyświetlających dodatkowe reklamy na stronach, na które wchodzisz).</translation>
<translation id="7674629440242451245">Interesują Cię nowe, przydatne funkcje Chrome? Wypróbuj wersję deweloperską ze strony chrome.com/dev.</translation>
<translation id="7682287625158474539">Adres wysyłkowy</translation>
+<translation id="7701040980221191251">Brak</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Otwórz stronę <ph name="SITE" /> (niebezpieczną)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certyfikat</translation>
+<translation id="7716147886133743102">Zablokowane przez administratora</translation>
<translation id="7716424297397655342">Nie można załadować tej strony z pamięci podręcznej</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">NiezarzÄ…dzany</translation>
<translation id="7755287808199759310">Może ją dla Ciebie odblokować Twój rodzic</translation>
<translation id="7758069387465995638">Połączenie mogło zostać zablokowane przez zaporę sieciową lub program antywirusowy.</translation>
@@ -751,15 +825,15 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="7951415247503192394">(32-bitowa)</translation>
<translation id="7956713633345437162">Zakładki na komórce</translation>
<translation id="7961015016161918242">Nigdy</translation>
-<translation id="7962083544045318153">Identyfikator awarii: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Zawsze tłumacz z języka: <ph name="ORIGINAL_LANGUAGE" /> na <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Nie określono</translation>
<translation id="800218591365569300">Zamknij inne karty lub programy, by zwolnić pamięć.</translation>
<translation id="8012647001091218357">Obecnie nie możemy się skontaktować z Twoimi rodzicami. Spróbuj ponownie.</translation>
<translation id="8025119109950072390">Osoby atakujące tę stronę mogą podstępem nakłonić Cię do zrobienia czegoś niebezpiecznego, np. zainstalowania oprogramowania lub ujawnienia danych osobowych (takich jak hasła, numery telefonów czy dane kart kredytowych).</translation>
-<translation id="803030522067524905">Bezpieczne przeglądanie Google ostatnio wykryło wyłudzanie informacji na <ph name="SITE" />. Strony wyłudzające informacje udają inne strony, by zmylić użytkowników. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Język tej strony to <ph name="SOURCE_LANGUAGE" />. Przetłumaczyć ją na <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Pytaj (domyślnie)</translation>
<translation id="8041089156583427627">Prześlij opinię</translation>
+<translation id="8041940743680923270">Użyj globalnej wartości domyślnej (Pytaj)</translation>
<translation id="8088680233425245692">Nie udało się wyświetlić artykułu.</translation>
<translation id="8089520772729574115">mniej niż 1 MB</translation>
<translation id="8091372947890762290">Aktywacja oczekuje na serwerze</translation>
@@ -768,13 +842,14 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="8134994873729925007">Nie udało się znaleźć <ph name="BEGIN_ABBR" />adresu DNS<ph name="END_ABBR" /> serwera <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Twój komputer przeszedł w tryb uśpienia.</translation>
<translation id="8150722005171944719">Nie można odczytać pliku <ph name="URL" />. Być może został usunięty lub uprawnienia dostępu uniemożliwiają jego odczyt.</translation>
+<translation id="8184538546369750125">Użyj globalnej wartości domyślnej (Zezwalaj)</translation>
+<translation id="8191494405820426728">Lokalny identyfikator awarii: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Cofnij przeniesienie</translation>
<translation id="8201077131113104583">NieprawidÅ‚owy URL aktualizowania dla rozszerzenia o identyfikatorze „<ph name="EXTENSION_ID" />â€.</translation>
<translation id="8202097416529803614">Podsumowanie zamówienia</translation>
<translation id="8218327578424803826">Przypisana lokalizacja:</translation>
<translation id="8225771182978767009">Administrator tego komputera zablokował tę witrynę.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Osoby atakujące stronę <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą spróbować zainstalować na Twoim komputerze niebezpieczne programy, których celem jest wykradzenie lub usunięcie Twoich danych (na przykład zdjęć, haseł, wiadomości czy numerów kart kredytowych).</translation>
<translation id="8241707690549784388">Strona, na której wyszukiwane są wprowadzone przez Ciebie informacje. Powrót do tej strony może spowodować konieczność powtórzenia wykonanych czynności. Czy chcesz kontynuować?</translation>
<translation id="8249320324621329438">Ostatnie pobieranie:</translation>
<translation id="8253091569723639551">Wymagany jest adres rozliczeniowy</translation>
@@ -782,6 +857,7 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="8289355894181816810">Jeśli nie masz pewności, co to oznacza, skontaktuj się z administratorem sieci.</translation>
<translation id="8293206222192510085">Dodaj zakładkę</translation>
<translation id="8294431847097064396">Źródło</translation>
+<translation id="8306404619377842860">Nie można nawiązać prywatnego połączenia z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, ponieważ data i godzina ustawione na urządzeniu (<ph name="DATE_AND_TIME" />) są nieprawidłowe. <ph name="BEGIN_LEARN_MORE_LINK" />Więcej informacji<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Tłumaczenie nie powiodło się z powodu problemu z połączeniem sieciowym.</translation>
<translation id="8332188693563227489">Odmowa dostępu do <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Jeśli rozumiesz zagrożenie, możesz <ph name="BEGIN_LINK" />wejść na tę stronę<ph name="END_LINK" />, zanim szkodliwe programy zostaną usunięte.</translation>
@@ -802,11 +878,9 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="8483780878231876732">Aby użyć kart z konta Google, zaloguj się w Chrome</translation>
<translation id="8488350697529856933">Dotyczy</translation>
<translation id="8498891568109133222">Serwer <ph name="HOST_NAME" /> potrzebował zbyt wiele czasu na odpowiedź.</translation>
-<translation id="852346902619691059">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat nie jest zaufany w systemie operacyjnym Twojego urządzenia. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego. <ph name="BEGIN_LEARN_MORE_LINK" />Dowiedz się więcej<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Rok utraty ważności</translation>
<translation id="8543181531796978784">Możesz <ph name="BEGIN_ERROR_LINK" />zgłosić problem z wykrywaniem<ph name="END_ERROR_LINK" /> lub – jeśli rozumiesz zagrożenie – <ph name="BEGIN_LINK" />wejść na tę niebezpieczną stronę<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Tłumaczenie nie powiodło się, ponieważ nie można określić języka strony.</translation>
-<translation id="8559762987265718583">Nie można nawiązać prywatnego połączenia z <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, ponieważ data i godzina (<ph name="DATE_AND_TIME" />) ustawione na urządzeniu są nieprawidłowe.</translation>
<translation id="8571890674111243710">Trwa tłumaczenie strony na język: <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Dodaj numer telefonu</translation>
<translation id="859285277496340001">Certyfikat nie określa mechanizmu do sprawdzania, czy został on unieważniony.</translation>
@@ -820,6 +894,7 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="8738058698779197622">Aby nawiązać bezpieczne połączenie, Twój zegar musi mieć ustawioną prawidłową godzinę. Jest to wymagane, ponieważ certyfikaty używane do identyfikacji stron internetowych są ważne tylko przez określony czas. Ponieważ zegar Twojego urządzenia nie jest ustawiony prawidłowo, Chromium nie może zweryfikować tych certyfikatów.</translation>
<translation id="8740359287975076522">Nie znaleziono &lt;abbr id="dnsDefinition"&gt;adresu DNS&lt;/abbr&gt; serwera <ph name="HOST_NAME" />. Diagnozujemy problem.</translation>
<translation id="8759274551635299824">Ta karta straciła ważność</translation>
+<translation id="8761567432415473239">Funkcja Bezpieczne przeglądanie Google ostatnio <ph name="BEGIN_LINK" />znalazła szkodliwe<ph name="END_LINK" /> programy na <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Ponów usunięcie</translation>
<translation id="8800988563907321413">Tutaj wyświetlają się sugestie witryn w pobliżu</translation>
<translation id="8820817407110198400">Zakładki</translation>
@@ -832,29 +907,30 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="8870413625673593573">Ostatnio zamknięte</translation>
<translation id="8874824191258364635">Wpisz prawidłowy numer karty</translation>
<translation id="8876793034577346603">Przetwarzanie konfiguracji sieci nie powiodło się.</translation>
-<translation id="8877192140621905067">Po potwierdzeniu szczegółowe dane karty zostaną udostępnione tej stronie</translation>
<translation id="8889402386540077796">Odcień</translation>
<translation id="8891727572606052622">Nieprawidłowy tryb proxy</translation>
<translation id="889901481107108152">Eksperyment jest niedostępny na Twojej platformie.</translation>
<translation id="8903921497873541725">Powiększ</translation>
<translation id="8931333241327730545">Chcesz zapisać tę kartę na swoim koncie Google?</translation>
<translation id="8932102934695377596">Twój zegar się spóźnia</translation>
-<translation id="8954894007019320973">(cd.)</translation>
<translation id="8971063699422889582">Ważność certyfikatu serwera wygasła.</translation>
<translation id="8986494364107987395">Automatycznie przesyłaj do Google statystyki użytkowania i raporty o awariach</translation>
-<translation id="8987927404178983737">MiesiÄ…c</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Na następnej stronie znajdują się szkodliwe programy</translation>
+<translation id="8997023839087525404">Certyfikat przesłany przez serwer nie został publicznie ujawniony przez protokół Certificate Transparency. Jest to wymagane w przypadku niektórych certyfikatów jako potwierdzenie, że są one zaufane i zabezpieczone przed atakami.</translation>
<translation id="9001074447101275817">Serwer proxy <ph name="DOMAIN" /> wymaga nazwy użytkownika i hasła.</translation>
+<translation id="9005998258318286617">Nie udało się wczytać dokumentu PDF.</translation>
<translation id="901974403500617787">Flagi stosowane w całym systemie może ustawić tylko właściciel: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Wymagany jest adres rozliczeniowy karty kredytowej</translation>
<translation id="9020542370529661692">Ta strona została przetłumaczona na <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="9035022520814077154">Błąd zabezpieczeń</translation>
<translation id="9038649477754266430">Użyj usługi podpowiedzi, by strony ładowały się szybciej</translation>
<translation id="9039213469156557790">Ta strona zawiera także niezabezpieczone zasoby. Podczas przesyłania mogą je wyświetlić inni użytkownicy, a osoby atakujące mogą je zmodyfikować, by zmienić sposób działania strony.</translation>
-<translation id="9040185888511745258">Osoby dokonujące ataków na stronie <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mogą podstępem próbować nakłonić Cię do zainstalowania programów obniżających jakość przeglądania internetu (np. zmieniających stronę główną lub powodujących pokazywanie dodatkowych reklam na stronach, na które wchodzisz).</translation>
+<translation id="9049981332609050619">Podjęto próbę nawiązania połączenia z witryną <ph name="DOMAIN" />, jednak serwer przedstawił nieprawidłowy certyfikat.</translation>
<translation id="9050666287014529139">Hasło</translation>
<translation id="9065203028668620118">Edycja</translation>
<translation id="9068849894565669697">Wybierz kolor</translation>
+<translation id="9069693763241529744">Zablokowane przez rozszerzenie</translation>
<translation id="9076283476770535406">Może zawierać treści dla dorosłych</translation>
<translation id="9078964945751709336">Potrzebujemy więcej informacji</translation>
<translation id="9103872766612412690"><ph name="SITE" /> zazwyczaj używa szyfrowania do ochrony Twoich informacji. Gdy tym razem przeglądarka Chromium próbowała połączyć się ze stroną <ph name="SITE" />, odesłała ona nietypowe i nieprawidłowe dane logowania. Może się tak zdarzyć, gdy pod stronę <ph name="SITE" /> podszywa się osoba atakująca albo gdy ekran logowania do sieci Wi-Fi przerwie połączenie. Twoje informacje są nadal bezpieczne, bo połączenie w Chromium zakończyło się przed wymianą jakichkolwiek danych.</translation>
@@ -863,16 +939,21 @@ Psst! Następnym razem możesz użyć trybu incognito <ph name="SHORTCUT_KEY" />
<translation id="9148507642005240123">&amp;Cofnij edycjÄ™</translation>
<translation id="9154194610265714752">Zaktualizowano</translation>
<translation id="9157595877708044936">Konfigurowanie...</translation>
+<translation id="9169664750068251925">Zawsze blokuj w tej witrynie</translation>
<translation id="9170848237812810038">&amp;Cofnij</translation>
<translation id="917450738466192189">Certyfikat serwera jest nieprawidłowy.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> inna}few{<ph name="SHIPPING_OPTION_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> inne}many{<ph name="SHIPPING_OPTION_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> innych}other{<ph name="SHIPPING_OPTION_PREVIEW" /> i <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> innej}}</translation>
<translation id="9183425211371246419">Serwer <ph name="HOST_NAME" /> używa nieobsługiwanego protokołu.</translation>
<translation id="9205078245616868884">Twoje dane są szyfrowane z użyciem hasła synchronizacji. Wpisz je, by rozpocząć synchronizację.</translation>
<translation id="9207861905230894330">Nie udało się dodać artykułu.</translation>
+<translation id="9219103736887031265">Grafika</translation>
<translation id="933612690413056017">Brak połączenia z internetem</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">WYCZYŚĆ FORMULARZ</translation>
<translation id="939736085109172342">Nowy folder</translation>
<translation id="941721044073577244">Wygląda na to, że nie masz uprawnień, by wejść na tę stronę</translation>
<translation id="969892804517981540">Oficjalna wersja</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Brak}=1{1 element}few{# elementy}many{# elementów}other{# elementu}}</translation>
<translation id="988159990683914416">Build</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_pt-BR.xtb b/chromium/components/strings/components_strings_pt-BR.xtb
index 45ae90872d1..4d408a8f5dd 100644
--- a/chromium/components/strings/components_strings_pt-BR.xtb
+++ b/chromium/components/strings/components_strings_pt-BR.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Girar no sentido horário</translation>
<translation id="1038842779957582377">nome desconhecido</translation>
<translation id="1050038467049342496">Fechar outros apps</translation>
-<translation id="1053591932240354961">Não é possível visitar <ph name="SITE" /> no momento, porque o website enviou credenciais codificadas que o Google Chrome não consegue processar. Ataques e erros de rede costumam ser temporários. Portanto, essa página deve voltar a funcionar mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Desfazer adicionar</translation>
<translation id="10614374240317010">Nunca salvam</translation>
<translation id="106701514854093668">Favoritos em computador</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cache da política OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> diz:</translation>
<translation id="1132774398110320017">Configurações de preenchimento automático do Google Chrome...</translation>
+<translation id="1150979032973867961">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança não é confiável para o sistema operacional do seu computador. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
+<translation id="1151972924205500581">Senha obrigatória</translation>
<translation id="1152921474424827756">Acessar uma <ph name="BEGIN_LINK" />cópia em cache<ph name="END_LINK" /> de <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> encerrou a conexão inesperadamente.</translation>
<translation id="1161325031994447685">Conectar-se à rede Wi-Fi novamente</translation>
+<translation id="1165039591588034296">Erro</translation>
<translation id="1175364870820465910">&amp;Imprimir...</translation>
<translation id="1181037720776840403">Remover</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Informar automaticamente<ph name="END_WHITEPAPER_LINK" /> ao Google detalhes de possíveis incidentes de segurança. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Mais deste site</translation>
<translation id="1206967143813997005">Assinatura inicial inválida</translation>
<translation id="1209206284964581585">Ocultar por enquanto</translation>
+<translation id="121201262018556460">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado que contém uma chave fraca. Um invasor pode ter violado a chave privada, e o servidor pode não ser o servidor que você esperava (você pode estar se comunicando com um invasor).</translation>
<translation id="1219129156119358924">Sistema de segurança</translation>
<translation id="1227224963052638717">Política desconhecida.</translation>
<translation id="1227633850867390598">Ocultar valor</translation>
<translation id="1228893227497259893">Identificador de entidade incorreto</translation>
<translation id="1232569758102978740">Sem título</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
<translation id="1263231323834454256">Lista de leitura</translation>
<translation id="1264126396475825575">Relatório de erros registrado em <ph name="CRASH_TIME" /> (ainda não enviado ou ignorado)</translation>
+<translation id="1281526147609854549">Publicado por <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Conteúdo perigoso bloqueado</translation>
<translation id="1285320974508926690">Nunca traduzir este site</translation>
<translation id="129553762522093515">Recentemente fechadas</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Tente limpar os cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">É possível que sua atividade <ph name="BEGIN_EMPHASIS" />ainda esteja visível<ph name="END_EMPHASIS" /> para:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />os websites que você visita
+ <ph name="LIST_ITEM" />seu empregador ou sua escola
+ <ph name="LIST_ITEM" />seu provedor de acesso à Internet
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domínio de inscrição:</translation>
<translation id="1340482604681802745">Endereço de retirada</translation>
<translation id="1344211575059133124">Parece que você precisa de permissão para visitar este site</translation>
<translation id="1344588688991793829">Configurações de preenchimento automático do Chromium...</translation>
+<translation id="1348198688976932919">O site a seguir contém apps perigosos</translation>
<translation id="1374468813861204354">sugestões</translation>
<translation id="1375198122581997741">Sobre a versão</translation>
<translation id="1377321085342047638">Número do cartão</translation>
<translation id="139305205187523129">Nenhum dado foi enviado por <ph name="HOST_NAME" /></translation>
<translation id="1407135791313364759">Abrir todas</translation>
<translation id="1413809658975081374">Erro de privacidade</translation>
+<translation id="14171126816530869">A identidade de <ph name="ORGANIZATION" /> em <ph name="LOCALITY" /> foi confirmada por <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Sim</translation>
<translation id="1430915738399379752">Imprimir</translation>
-<translation id="1442912890475371290">Tentativa bloqueada de <ph name="BEGIN_LINK" />visitar uma página em <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Não é possível visitar <ph name="SITE" /> no momento, porque o website utiliza fixação de certificados. Ataques e erros de rede costumam ser temporários. Portanto, essa página deve voltar a funcionar mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Mostrar uma cópia salva (ou seja, reconhecidamente desatualizada) desta página.</translation>
<translation id="1517433312004943670">Número de telefone necessário</translation>
<translation id="1519264250979466059">Data da versão</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">O JavaScript deve ser ativado para usar este recurso.</translation>
<translation id="1555130319947370107">Azul</translation>
<translation id="1559528461873125649">Arquivo ou diretório não encontrado</translation>
-<translation id="1559572115229829303">&lt;p&gt;Não é possível estabelecer uma conexão particular com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> porque a data e hora do seu dispositivo (<ph name="DATE_AND_TIME" />) estão incorretas.&lt;/p&gt;
-
- &lt;p&gt;Ajuste a data e hora na seção &lt;strong&gt;Geral&lt;/strong&gt; do aplicativo &lt;strong&gt;Config.&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Algo deu errado ao exibir esta página da Web.</translation>
<translation id="1592005682883173041">Acesso a dados locais</translation>
+<translation id="1594030484168838125">Escolher</translation>
<translation id="161042844686301425">Ciano</translation>
+<translation id="1620510694547887537">Câmera</translation>
<translation id="1629803312968146339">Deseja que o Chrome salve este cartão?</translation>
<translation id="1639239467298939599">Carregando</translation>
<translation id="1640180200866533862">Políticas de usuário</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">A configuração de rede é inválida e não pôde ser importada.</translation>
<translation id="1644574205037202324">Histórico</translation>
<translation id="1645368109819982629">Protocolo não compatível</translation>
+<translation id="1655462015569774233">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o certificado de segurança dele expirou ontem. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página.}one{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele expirou há # dias. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele expirou há # dias. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página.}}</translation>
<translation id="1656489000284462475">Retirada</translation>
<translation id="1663943134801823270">Os cartões e os endereços vieram do Chrome. É possível gerenciar essas opções em <ph name="BEGIN_LINK" />Configurações<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">O site <ph name="SITE" /> geralmente usa criptografia para proteger suas informações. Quando o Google Chrome tentou se conectar a <ph name="SITE" /> dessa vez, o website retornou credenciais incomuns e incorretas. Isso pode acontecer quando um invasor está fingindo ser <ph name="SITE" /> ou quando uma tela de login por Wi-Fi interrompeu a conexão. Suas informações ainda estão protegidas, porque o Google Chrome interrompeu a conexão antes que os dados fossem trocados.</translation>
-<translation id="168328519870909584">Os invasores que estão atualmente em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar instalar apps perigosos no seu dispositivo para roubar ou excluir suas informações (por exemplo, fotos, senhas, mensagens e cartões de crédito).</translation>
<translation id="168841957122794586">O certificado do servidor contém uma chave de criptografia fraca.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele está com a data de amanhã. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.}one{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele está com uma data de # dias depois de hoje. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele está com uma data de # dias depois de hoje. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.}}</translation>
<translation id="1710259589646384581">SO</translation>
<translation id="1721312023322545264">É necessário pedir a permissão de <ph name="NAME" /> para visitar este site</translation>
<translation id="1721424275792716183">* Campo obrigatório</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Fazer o download da página mais tarde</translation>
<translation id="17513872634828108">Guias abertas</translation>
<translation id="1753706481035618306">Numero da página</translation>
+<translation id="1763864636252898013">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança não é confiável para o sistema operacional do seu dispositivo. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Tente executar o Diagnóstico de Rede do Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Favor atualizar sua senha de sincronização.</translation>
<translation id="1787142507584202372">Suas guias abertas são exibidas aqui</translation>
+<translation id="1789575671122666129">Pop-ups</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nome do titular do cartão</translation>
-<translation id="1803678881841855883">Recentemente, a Navegação segura do Google <ph name="BEGIN_LINK" />detectou malware<ph name="END_LINK" /> em <ph name="SITE" />. Websites que costumam ser seguros às vezes são infectados por malware. O conteúdo malicioso vem de <ph name="SUBRESOURCE_HOST" />, um conhecido distribuidor de malware. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Adicionado em: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Solicitação ou parâmetros de solicitação inválidos</translation>
<translation id="1826516787628120939">Em verificação</translation>
<translation id="1834321415901700177">Este site contém programas perigosos</translation>
+<translation id="1840414022444569775">Este número de cartão já está sendo usado</translation>
<translation id="1842969606798536927">Pagar</translation>
<translation id="1871208020102129563">O proxy foi configurado para utilizar servidores de proxy fixo e não um URL de script .pac.</translation>
<translation id="1871284979644508959">Campo obrigatório</translation>
<translation id="187918866476621466">Abrir páginas de inicialização</translation>
<translation id="1883255238294161206">Recolher lista</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtragem</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Nenhum}=1{1 site}one{# site}other{# sites}}</translation>
<translation id="194030505837763158">Ir para <ph name="LINK" /></translation>
<translation id="1962204205936693436">Favoritos de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Erro de serialização</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorado porque foi substituído por <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Procurando páginas da Web física nas proximidades</translation>
<translation id="213826338245044447">Favoritos de dispositivos móveis</translation>
-<translation id="2148716181193084225">Hoje</translation>
+<translation id="2147827593068025794">Sincronização em segundo plano</translation>
<translation id="2154054054215849342">O serviço de sincronização não está disponível para seu domínio</translation>
<translation id="2154484045852737596">Editar cartão</translation>
<translation id="2166049586286450108">Acesso completo de administrador</translation>
<translation id="2166378884831602661">Não foi possível estabelecer uma conexão segura com este site</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 endereço}one{# endereço}other{# endereços}}</translation>
+<translation id="2187317261103489799">Detectar (padrão)</translation>
<translation id="2202020181578195191">Informe um ano de validade válido</translation>
<translation id="2212735316055980242">Política não encontrada</translation>
<translation id="2213606439339815911">Buscando entradas...</translation>
+<translation id="2218879909401188352">Os invasores que estão em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> no momento podem instalar apps perigosos que danificam seu dispositivo, acrescentam cobranças ocultas junto à operadora ou roubam suas informações pessoais. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Corrija sua conexão usando o <ph name="BEGIN_LINK" />app de diagnóstico<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Enviar agora</translation>
<translation id="225207911366869382">Este valor está obsoleto para esta política.</translation>
<translation id="2262243747453050782">Erro HTTP</translation>
+<translation id="2270484714375784793">Número do telefone</translation>
<translation id="2282872951544483773">Experiências não disponíveis</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item}one{<ph name="ITEM_COUNT" /> item}other{<ph name="ITEM_COUNT" /> itens}}</translation>
<translation id="2292556288342944218">O seu acesso à Internet está bloqueado</translation>
<translation id="230155334948463882">Novo cartão?</translation>
-<translation id="2305919008529760154">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. É possível que o certificado de segurança dele tenha sido emitido de forma fraudulenta. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> exige um nome de usuário e uma senha.</translation>
-<translation id="2318774815570432836">Não é possível visitar <ph name="SITE" /> no momento, porque o website usa HSTS. Ataques e erros de rede costumam ser temporários. Portanto, essa página deve voltar a funcionar mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Configuração controlada pelo administrador</translation>
<translation id="2354001756790975382">Outros favoritos</translation>
+<translation id="2354430244986887761">Recentemente, o recurso "Navegação segura" do Google <ph name="BEGIN_LINK" />encontrou apps prejudiciais<ph name="END_LINK" /> em <ph name="SITE" />.</translation>
<translation id="2355395290879513365">É possível que invasores consigam ver as imagens que você está olhando nesse site e as modifiquem para enganar você.</translation>
+<translation id="2356070529366658676">Perguntar</translation>
+<translation id="2359629602545592467">Várias</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2365563543831475020">O relatório de erros registrado em <ph name="CRASH_TIME" /> não foi enviado</translation>
<translation id="2367567093518048410">Nível</translation>
-<translation id="2371153335857947666">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele expirou ontem. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}one{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele expirou há # dia. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele expirou há # dias. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. O relógio do seu computador está definido para <ph name="CURRENT_DATE" />. Essa data está correta? Se não estiver, corrija o relógio do sistema e depois atualize esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nenhuma IU alternativa disponível</translation>
<translation id="2384307209577226199">Padrão da empresa</translation>
<translation id="2386255080630008482">O certificado do servidor foi revogado.</translation>
<translation id="2392959068659972793">Mostrar políticas sem valor definido</translation>
<translation id="239429038616798445">Esse método de envio não está disponível. Tente um método diferente.</translation>
<translation id="2396249848217231973">&amp;Desfazer exclusão</translation>
-<translation id="2460160116472764928">Recentemente, a Navegação segura do Google <ph name="BEGIN_LINK" />detectou malware<ph name="END_LINK" /> em <ph name="SITE" />. Websites que costumam ser seguros às vezes são infectados por malware. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança pode ter sido revogado. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="2463739503403862330">Preencher</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Executar o Diagnóstico de Rede<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL de pesquisa inválido.</translation>
+<translation id="2482878487686419369">Notificações</translation>
<translation id="2491120439723279231">O certificado do servidor contém erros.</translation>
<translation id="2495083838625180221">Analisador JSON</translation>
<translation id="2495093607237746763">Se esta opção for selecionada, o Chromium armazenará uma cópia do seu cartão neste dispositivo para preencher de formulários mais rapidamente.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Voltar</translation>
<translation id="2515629240566999685">Verificar o sinal na sua área</translation>
<translation id="2516305470678292029">IUs alternativas</translation>
+<translation id="2539524384386349900">Detectar</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> enviou uma resposta inválida.</translation>
-<translation id="2552545117464357659">Recente</translation>
<translation id="2556876185419854533">&amp;Desfazer editar</translation>
<translation id="2587730715158995865">De <ph name="ARTICLE_PUBLISHER" />. Leia essa matéria e <ph name="OTHER_ARTICLE_COUNT" /> outras.</translation>
<translation id="2587841377698384444">Código da API do diretório:</translation>
<translation id="2597378329261239068">Este documento está protegido por senha. Digite a senha.</translation>
<translation id="2609632851001447353">Variações</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Nenhum}=1{1 app ($1)}=2{2 apps ($1, $2)}one{# app ($1)}other{# apps ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Seu relógio está adiantado</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">O acesso ao arquivo foi negado</translation>
<translation id="2653659639078652383">Enviar</translation>
<translation id="2666117266261740852">Fechar outras guias ou apps</translation>
+<translation id="2670429602441959756">Esta página contém recursos que ainda não são compatíveis com a realidade virtual. Saindo…</translation>
<translation id="2674170444375937751">Tem certeza de que deseja excluir essas páginas do seu histórico?</translation>
<translation id="2677748264148917807">Sair</translation>
-<translation id="269990154133806163">O servidor apresentou um certificado que não foi divulgado publicamente por meio da política de Transparência dos certificados. Essa é uma exigência para alguns certificados, a fim de garantir que eles sejam confiáveis e protejam você contra invasores. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Lista de leitura</translation>
<translation id="2704283930420550640">O valor não corresponde ao formato.</translation>
<translation id="2704951214193499422">Não foi possível confirmar seu cartão com o Chromium no momento. Tente novamente mais tarde.</translation>
<translation id="2705137772291741111">Não foi possível ler a cópia armazenada em cache deste site.</translation>
<translation id="2709516037105925701">Preenchimento automático</translation>
-<translation id="2712118517637785082">Você tentou acessar <ph name="DOMAIN" />, mas o certificado que o servidor apresentou foi revogado pelo emissor. Isso significa que as credenciais de segurança que o servidor apresentou não são nem um pouco seguras. Você pode estar se comunicando com um invasor. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Pedir permissão</translation>
<translation id="2713444072780614174">Branco</translation>
<translation id="2720342946869265578">Por perto</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Registro de dispositivo não encontrado</translation>
<translation id="2784949926578158345">A conexão foi redefinida.</translation>
<translation id="2794233252405721443">Site bloqueado</translation>
+<translation id="2799020568854403057">O site a seguir contém apps prejudiciais</translation>
+<translation id="2803306138276472711">A Navegação segura do Google recentemente <ph name="BEGIN_LINK" />detectou malware<ph name="END_LINK" /> em <ph name="SITE" />. Websites que geralmente são seguros, algumas vezes, são infetados com malware.</translation>
<translation id="2824775600643448204">Barra de endereço e de pesquisa</translation>
<translation id="2826760142808435982">A conexão foi criptografada e autenticada utilizando <ph name="CIPHER" /> e usa <ph name="KX" /> como o mecanismo de troca de chave.</translation>
<translation id="2835170189407361413">Limpar formulário</translation>
+<translation id="2856444702002559011">Invasores podem estar tentando roubar suas informações de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (por exemplo, senhas, mensagens ou cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Não atualizar</translation>
<translation id="2900469785430194048">O Google Chrome ficou sem memória ao tentar exibir essa página da Web.</translation>
<translation id="2909946352844186028">Foi detectada uma alteração na rede.</translation>
<translation id="2916038427272391327">Fechar outros programas</translation>
<translation id="2922350208395188000">O certificado do servidor não pode ser verificado.</translation>
<translation id="2928905813689894207">Endereço de cobrança</translation>
+<translation id="2941952326391522266">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança é de <ph name="DOMAIN2" />. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="2948083400971632585">Na página "Configurações", você pode desativar quaisquer proxies configurados para uma conexão.</translation>
<translation id="2955913368246107853">Fechar barra de localização</translation>
<translation id="2958431318199492670">A configuração de rede não está de acordo com o padrão ONC. Partes da configuração podem não ser importadas.</translation>
-<translation id="29611076221683977">Os invasores que estão atualmente em <ph name="BEGIN_BOLD" /> <ph name="SITE" /> <ph name="END_BOLD" /> podem tentar instalar programas perigosos no seu Mac para roubar ou excluir suas informações (por exemplo, fotos, senhas, mensagens e cartões de crédito).</translation>
<translation id="2966678944701946121">Validade: <ph name="EXPIRATION_DATE_ABBR" />, data de adição: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Para estabelecer uma conexão segura, o relógio precisa estar configurado corretamente. Isso ocorre porque os certificados que os websites usam para se identificar são válidos apenas por períodos específicos. Como o relógio do seu dispositivo está incorreto, o Google Chrome não consegue verificar esses certificados.</translation>
<translation id="2972581237482394796">&amp;Refazer</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Informe um endereço válido</translation>
<translation id="2986368408720340940">Esse método de retirada não está disponível. Tente um método diferente.</translation>
<translation id="2991174974383378012">Compartilhar com websites</translation>
+<translation id="2991571918955627853">Você não pode visitar <ph name="SITE" /> agora, porque o site usa HSTS. Erros de rede e ataques são geralmente temporários. Esta página provavelmente funcionará mais tarde.</translation>
<translation id="3005723025932146533">Mostrar cópia salva</translation>
<translation id="3008447029300691911">Digite o CVC do <ph name="CREDIT_CARD" />. Depois da confirmação, os detalhes do seu cartão serão compartilhados com esse site.</translation>
<translation id="3010559122411665027">Entrada de lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Bloqueada automaticamente</translation>
<translation id="3024663005179499861">Tipo de política incorreto</translation>
<translation id="3032412215588512954">Deseja atualizar este site?</translation>
<translation id="3037605927509011580">Ah, não!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{pelo menos 1 item em dispositivos sincronizados}=1{1 item (e mais em dispositivos sincronizados)}one{# items (and more on synced devices)}other{# itens (e mais em dispositivos sincronizados)}}</translation>
<translation id="3041612393474885105">Informações do certificado</translation>
<translation id="3063697135517575841">Não foi possível confirmar seu cartão com o Chrome no momento. Tente novamente mais tarde.</translation>
-<translation id="3064966200440839136">Saindo do modo de navegação anônima para pagar usando um aplicativo externo. Continuar?</translation>
+<translation id="3064966200440839136">Saindo do modo sem rastros para pagar usando um aplicativo externo. Continuar?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Nenhuma}=1{1 senha}one{# senha}other{# senhas}}</translation>
<translation id="3093245981617870298">Você está off-line.</translation>
<translation id="3105172416063519923">Código do recurso:</translation>
<translation id="3109728660330352905">Você não tem autorização para ver esta página.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Tente executar o Diagnóstico de Conectividade<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Falha ao decodificar resposta</translation>
<translation id="3150653042067488994">Erro temporário do servidor</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Quando você está no modo invisível, as páginas que você visita não aparecem no seu histórico de navegação e de pesquisa, nem armazenam arquivos "cookies". Mas os downloads e os favoritos continuam funcionando normalmente.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ilha</translation>
+<translation id="317583078218509884">As novas configurações de permissões de site entrarão em vigor quando a página for atualizada.</translation>
<translation id="3176929007561373547">Verifique suas configurações de proxy ou entre em contato com o administrador de rede para
verificar se o servidor proxy está funcionando. Se você acredita que não deve
usar um servidor proxy:
<ph name="PLATFORM_TEXT" /></translation>
-<translation id="3200379322500587640">Abrir a página no modo de navegação anônima</translation>
-<translation id="3202578601642193415">Mais recente</translation>
+<translation id="3200379322500587640">Abrir a página no modo sem rastros</translation>
+<translation id="320323717674993345">Cancelar pagamento</translation>
<translation id="3207960819495026254">Adicionada aos favoritos</translation>
+<translation id="3225919329040284222">O servidor apresentou um certificado que não coincide com as expectativas incorporadas. Estas expectativas são incluídas para determinados websites de alta segurança com a finalidade de oferecer proteção a você.</translation>
<translation id="3226128629678568754">Pressione o botão "Atualizar" para reenviar os dados necessários para carregar a página.</translation>
+<translation id="3227137524299004712">Microfone</translation>
<translation id="3228969707346345236">A tradução falhou porque a página já está em <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Digite o CVC do <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Sempre detectar conteúdo importante neste site</translation>
<translation id="3254409185687681395">Adicionar esta página aos favoritos</translation>
<translation id="3270847123878663523">&amp;Desfazer reordenar</translation>
<translation id="3282497668470633863">Adicionar nome (como consta no cartão)</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">configurações</translation>
<translation id="3345135638360864351">Não foi possível enviar sua solicitação a <ph name="NAME" /> para acessar este site. Tente novamente.</translation>
<translation id="3355823806454867987">Alterar configurações de proxy...</translation>
+<translation id="3361596688432910856">O Chrome <ph name="BEGIN_EMPHASIS" />não salvará<ph name="END_EMPHASIS" /> as seguintes informações:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />seu histórico de navegação
+ <ph name="LIST_ITEM" />cookies e dados de sites
+ <ph name="LIST_ITEM" />informações fornecidas em formulários
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Erro do relógio</translation>
-<translation id="337311366426640088">Mais <ph name="ITEM_COUNT" /> itens…</translation>
<translation id="337363190475750230">Desprovisionado</translation>
<translation id="3377188786107721145">Erro de análise da política</translation>
<translation id="3380365263193509176">Erro desconhecido</translation>
<translation id="3380864720620200369">ID do cliente:</translation>
<translation id="3391030046425686457">Endereço de entrega</translation>
<translation id="3395827396354264108">Método de retirada</translation>
-<translation id="340013220407300675">Invasores podem estar tentando roubar suas informações de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (por exemplo, senhas, mensagens ou cartões de crédito).</translation>
<translation id="3422248202833853650">Tente sair de outros programas para liberar memória.</translation>
<translation id="3422472998109090673">No momento, não é possível acessar <ph name="HOST_NAME" />.</translation>
+<translation id="3427092606871434483">Permitir (padrão)</translation>
<translation id="3427342743765426898">&amp;Refazer editar</translation>
<translation id="3431636764301398940">Salvar este cartão neste dispositivo</translation>
<translation id="3435896845095436175">Ativar</translation>
<translation id="3447661539832366887">O proprietário deste dispositivo desativou o jogo do dinossauro.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Buscar intervalo:</translation>
<translation id="3462200631372590220">Ocultar detalhes</translation>
<translation id="3467763166455606212">O nome do titular do cartão é obrigatório</translation>
<translation id="3478058380795961209">Mês de vencimento</translation>
<translation id="3479539252931486093">Isso foi inesperado? <ph name="BEGIN_LINK" />Informe-nos<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Não agora</translation>
-<translation id="348000606199325318">Código de falha <ph name="CRASH_LOCAL_ID" /> (código do servidor: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Não foi possível contatar seu pai/mãe no momento. Tente novamente.</translation>
<translation id="3528171143076753409">O certificado do servidor não é confiável.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Pelo menos 1 item em dispositivos sincronizados}=1{1 item (e mais em dispositivos sincronizados)}one{# item (e mais em dispositivos sincronizados)}other{# itens (e mais em dispositivos sincronizados)}}</translation>
<translation id="3539171420378717834">Manter uma cópia deste cartão neste dispositivo</translation>
<translation id="3542684924769048008">Usar senha para:</translation>
+<translation id="3545341443414427877">Não é possível estabelecer uma conexão particular com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e hora do seu computador (<ph name="DATE_AND_TIME" />) estão incorretas. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Criptografar todos os dados sincronizados com sua senha de sincronização</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> mais...</translation>
-<translation id="3555561725129903880">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele é de <ph name="DOMAIN2" />. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Seu administrador pode desbloqueá-lo para você</translation>
<translation id="3566021033012934673">Sua conexão não é particular</translation>
+<translation id="3569145463236695319">&lt;p&gt;Não é possível estabelecer uma conexão particular com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e hora do dispositivo (<ph name="DATE_AND_TIME" />) estão incorretas.&lt;/p&gt;
+
+ &lt;p&gt;Ajuste a data e hora na seção &lt;strong&gt;Geral&lt;/strong&gt; do app &lt;strong&gt;Ajustes&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Adicionar nome</translation>
<translation id="3583757800736429874">&amp;Refazer mover</translation>
<translation id="3586931643579894722">Ocultar detalhes</translation>
-<translation id="3587482841069643663">Tudo</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Informe uma data de validade válida</translation>
<translation id="36224234498066874">Limpar dados de navegação...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informações do certificado</translation>
<translation id="3690164694835360974">Login não seguro</translation>
<translation id="3693415264595406141">Senha:</translation>
-<translation id="3696411085566228381">nenhum</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Carregando...</translation>
<translation id="3712624925041724820">Licenças esgotadas</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Verificar a configuração de DNS, proxy e firewall<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Se você entende os riscos à sua segurança, pode <ph name="BEGIN_LINK" />acessar este site inseguro<ph name="END_LINK" /> antes de os programas perigosos serem removidos.</translation>
<translation id="3739623965217189342">Link que você copiou</translation>
+<translation id="3744899669254331632">Você não pode visitar <ph name="SITE" /> agora porque o website enviou credenciais embaralhadas que o Chromium não consegue processar. Erros de rede e ataques são geralmente temporários, de modo que esta página provavelmente funcionará mais tarde.</translation>
+<translation id="3748148204939282805">Invasores em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem levar você a fazer algo perigoso, como instalar software ou revelar suas informações pessoais (por exemplo, senhas, números de telefone ou cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">A tradução falhou devido a um erro no servidor.</translation>
<translation id="3759461132968374835">Você não relatou falhas recentemente. As falhas que ocorreram quando o relatório de erros estava desativado não aparecerão aqui.</translation>
+<translation id="3778403066972421603">Deseja salvar este cartão na sua Conta do Google e neste dispositivo?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Validade: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Se você usa um servidor proxy...</translation>
<translation id="3828924085048779000">Uma senha vazia não é permitida.</translation>
-<translation id="3845539888601087042">Exibindo histórico dos seus dispositivos conectados. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Voltar</translation>
<translation id="3858027520442213535">Atualizar data e hora</translation>
<translation id="3884278016824448484">Identificador de dispositivo em conflito</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Sua solicitação para acessar este site foi enviada para <ph name="NAME" /></translation>
<translation id="3890664840433101773">Adicionar e-mail</translation>
<translation id="3901925938762663762">O cartão expirou</translation>
-<translation id="3933571093587347751">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele está com a data de amanhã. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}one{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele está com uma data de # dia depois de hoje. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele está com uma data de # dias depois de hoje. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Falha ao carregar o documento PDF</translation>
+<translation id="3945915738023014686">Código do relatório de falha enviado: <ph name="CRASH_ID" /> (código de falha local: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele não especifica a extensão Nomes alternativos do requerente. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="3963721102035795474">Modo leitor</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Nenhum}=1{1 site }one{# site }other{# sites }}</translation>
<translation id="397105322502079400">Calculando...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> está bloqueado</translation>
+<translation id="3987940399970879459">Menos de 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 página da Web por perto}one{# página da Web por perto}other{# páginas da Web por perto}}</translation>
<translation id="4021036232240155012">O DNS é o serviço de rede que converte o nome de um website para o próprio endereço de Internet.</translation>
<translation id="4030383055268325496">&amp;Desfazer adicionar</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">A configuração do proxy definida utiliza um URL de script .pac, e não servidores proxy fixos.</translation>
<translation id="4098354747657067197">Site enganoso à frente</translation>
<translation id="4103249731201008433">O número de série do dispositivo é inválido</translation>
+<translation id="410351446219883937">Reprodução automática</translation>
<translation id="4103763322291513355">Visite &lt;strong&gt;chrome://policy&lt;/strong&gt; para ver a lista de URLs adicionados à lista negra e outras políticas aplicadas pelo administrador do seu sistema.</translation>
-<translation id="4110615724604346410">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele contém erros. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Sempre permitir neste site</translation>
<translation id="4117700440116928470">O escopo da política não é suportado.</translation>
-<translation id="4118212371799607889">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele não é confiável para o Chromium. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{mais 1}one{mais #}other{mais #}}</translation>
<translation id="4130226655945681476">Verificar os cabos de rede, modem e roteador</translation>
+<translation id="413544239732274901">Saiba mais</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Usar padrão global (Detectar)</translation>
+<translation id="4165986682804962316">Configurações do site</translation>
<translation id="4169947484918424451">Deseja que o Chromium salve este cartão?</translation>
<translation id="4171400957073367226">Assinatura de verificação inválida</translation>
<translation id="4196861286325780578">&amp;Refazer mover</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Verificar as configurações do antivírus e firewall<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{nenhum}=1{1 app ($1)}=2{2 apps ($1, $2)}one{# apps ($1, $2, $3)}other{# apps ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Falhas</translation>
+<translation id="422022731706691852">Invasores em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar levar você a instalar programas que podem prejudicar sua experiência de navegação (por exemplo, alterando sua página inicial ou exibindo anúncios extras em sites que você visitar). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Tente executar o Diagnóstico de Rede<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Válido</translation>
<translation id="4250431568374086873">Sua conexão com esse site não é completamente segura</translation>
<translation id="4250680216510889253">Não</translation>
<translation id="425582637250725228">É possível que as alterações feitas não sejam salvas.</translation>
<translation id="4258748452823770588">Assinatura inválida</translation>
+<translation id="4265872034478892965">Permitido pelo administrador</translation>
<translation id="4269787794583293679">Sem nome de usuário</translation>
<translation id="4275830172053184480">Reiniciar seu dispositivo</translation>
<translation id="4280429058323657511">, validade <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Recentemente, a Navegação segura do Google <ph name="BEGIN_LINK" />encontrou programas prejudiciais<ph name="END_LINK" /> em <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Sugestões para pais</translation>
<translation id="4304224509867189079">Fazer login</translation>
-<translation id="432290197980158659">O servidor apresentou um certificado que não corresponde às expectativas incorporadas. Essas expectativas são incluídas para determinados websites de alta segurança para proteger você. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Bloquear (padrão)</translation>
<translation id="4325863107915753736">Falha ao encontrar artigo</translation>
<translation id="4326324639298822553">Verifique a data de validade e tente novamente</translation>
<translation id="4331708818696583467">Não seguro</translation>
<translation id="4356973930735388585">Invasores nesse site podem tentar instalar programas perigosos no seu computador para roubar ou excluir informações (por exemplo, fotos, senhas, mensagens e cartões de crédito).</translation>
<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE" /> esperado.</translation>
+<translation id="4377125064752653719">Você tentou acessar <ph name="DOMAIN" />, mas o certificado que o servidor apresentou foi revogado pelo seu emissor. Isso significa que as credenciais de segurança que o servidor apresentou não são nem um pouco seguras. Talvez você esteja se comunicando com um invasor.</translation>
<translation id="4381091992796011497">Nome de usuário:</translation>
<translation id="4394049700291259645">Desativar</translation>
<translation id="4406896451731180161">resultados da pesquisa</translation>
+<translation id="4424024547088906515">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança não é confiável para o Chrome. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="4432688616882109544">O certificado de login não foi aceito por <ph name="HOST_NAME" /> ou não foi fornecido.</translation>
<translation id="443673843213245140">O uso de um proxy está desativado, mas uma configuração explícita de proxy é especificada.</translation>
-<translation id="4492190037599258964">Resultados de pesquisa para "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Erro de validação: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Entrar em contato com o administrador do sistema</translation>
<translation id="450710068430902550">Compartilhar com o administrador</translation>
<translation id="4515275063822566619">Os cartões e os endereços vieram do Chrome e da sua Conta do Google (<ph name="ACCOUNT_EMAIL" />). É possível gerenciar essas opções em <ph name="BEGIN_LINK" />Configurações<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detalhes</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Tente desativar suas extensões.</translation>
<translation id="457875822857220463">Entrega</translation>
<translation id="4587425331216688090">Remover endereço do Chrome?</translation>
-<translation id="4589078953350245614">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado inválido. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Sua conexão com <ph name="DOMAIN" /> foi criptografada usando um pacote de criptografia moderno.</translation>
<translation id="4594403342090139922">&amp;Desfazer exclusão</translation>
<translation id="4619615317237390068">Guias de outros dispositivos</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança contém erros. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
+<translation id="4690462567478992370">Suspender o uso de um certificado inválido</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">A conexão foi interrompida</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Executar o Diagnóstico de Rede do Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Ocorreu um erro desconhecido.</translation>
<translation id="4800132727771399293">Verifique sua data de validade e seu CVC e tente novamente</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Não é possível acessar <ph name="SITE" /> no momento, porque o website enviou credenciais codificadas que o Google Chrome não pode processar. Ataques e erros de rede geralmente são temporários. Portanto, essa página provavelmente funcionará mais tarde.</translation>
<translation id="4813512666221746211">Erro na rede</translation>
<translation id="4816492930507672669">Ajustar à página</translation>
<translation id="483020001682031208">Nenhuma página da Web física para exibição</translation>
<translation id="4850886885716139402">Visualizar</translation>
<translation id="4854362297993841467">Esse método de entrega não está disponível. Tente um método diferente.</translation>
<translation id="4858792381671956233">Você perguntou aos seus responsáveis se pode visitar este site</translation>
+<translation id="4863764087567530506">Esse conteúdo pode tentar enganar você para que instale um software ou revele informações pessoais. <ph name="BEGIN_LINK" />Mostrar mesmo assim<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Histórico de pesquisa</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{e mais 1 página da Web}one{e mais # página da Web}other{e mais # páginas da Web}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para o <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pagamento</translation>
<translation id="4926049483395192435">Deve ser especificado.</translation>
<translation id="495170559598752135">Ações</translation>
<translation id="4958444002117714549">Expandir lista</translation>
-<translation id="4962322354953122629">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele não é confiável para o Chrome. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Reativar avisos</translation>
<translation id="4989809363548539747">Este plug-in não é compatível</translation>
<translation id="5002932099480077015">Se ativado, o Chrome armazenará uma cópia do seu cartão neste dispositivo para preencher formulários mais rapidamente.</translation>
<translation id="5018422839182700155">Não é possível abrir essa página</translation>
@@ -446,18 +500,19 @@
<translation id="5023310440958281426">Verifique as políticas do administrador</translation>
<translation id="5029568752722684782">Limpar cópia</translation>
<translation id="5031870354684148875">Sobre o Google Tradutor</translation>
+<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidade</translation>
<translation id="5045550434625856497">Senha incorreta</translation>
<translation id="5056549851600133418">Artigos para você</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Verificar o endereço do proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Sem cookies}=1{1 site usa cookies. }one{# sites use cookies. }other{# sites usam cookies. }}</translation>
<translation id="5087286274860437796">O certificado do servidor não é válido no momento.</translation>
<translation id="5087580092889165836">Adicionar cartão</translation>
<translation id="5089810972385038852">Estado</translation>
+<translation id="5094747076828555589">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança não é confiável para o Chromium. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="5095208057601539847">Província</translation>
<translation id="5115563688576182185">64 bits</translation>
<translation id="5141240743006678641">Criptografar senhas sincronizadas com suas credenciais do Google</translation>
-<translation id="514421653919133810">Abrir a página no modo de navegação anônima (Ctrl-Shift-N)</translation>
+<translation id="514421653919133810">Abrir a página no modo sem rastros (Ctrl-Shift-N)</translation>
<translation id="5145883236150621069">Código de erro presente na resposta da política</translation>
<translation id="5171045022955879922">Pesquisar ou digitar URL</translation>
<translation id="5172758083709347301">Máquina</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-mail obrigatório</translation>
<translation id="5251803541071282808">Nuvem</translation>
<translation id="5277279256032773186">Você usa o Chrome no trabalho? As empresas podem gerenciar as configurações do Chrome para seus funcionários. Saiba mais</translation>
+<translation id="5297526204711817721">Sua conexão com este site não é particular. Para sair do modo de RV a qualquer momento, remova o fone de ouvido e pressione "Voltar".</translation>
<translation id="5299298092464848405">Política de análise de erros</translation>
-<translation id="5300589172476337783">Mostrar</translation>
<translation id="5308689395849655368">O relatório de erros está desativado.</translation>
<translation id="5317780077021120954">Salvar</translation>
<translation id="5327248766486351172">Nome</translation>
-<translation id="5337705430875057403">Os invasores em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem induzir você a fazer algo perigoso, como instalar um software ou revelar suas informações pessoais (por exemplo, senhas, números de telefone ou cartões de crédito).</translation>
-<translation id="5359637492792381994">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele não é válido no momento. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Não é possível acessar <ph name="SITE" /> neste momento, porque o certificado dele foi revogado. Como os ataques e erros de rede são geralmente temporários, esta página provavelmente funcionará mais tarde.</translation>
<translation id="536296301121032821">Falha ao armazenar as configurações da política</translation>
<translation id="5386426401304769735">A cadeia de certificados desse site contém um certificado assinado usando SHA-1.</translation>
<translation id="5402410679244714488">Validade: <ph name="EXPIRATION_DATE_ABBR" />, usado pela última vez há mais de um ano</translation>
+<translation id="540969355065856584">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele não é válido no momento. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
<translation id="5421136146218899937">Limpar dados de navegação...</translation>
<translation id="5430298929874300616">Remover favorito</translation>
<translation id="5431657950005405462">O arquivo não foi encontrado</translation>
-<translation id="5435775191620395718">Exibindo histórico deste dispositivo. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Erro de validação de esquema em "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Não foi possível encontrar a página deste <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">Carimbo de data e hora da política inválido</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> de <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Inválidos</translation>
<translation id="5470861586879999274">&amp;Refazer editar</translation>
<translation id="54817484435770891">Adicionar endereço válido</translation>
<translation id="5492298309214877701">Esse site na intranet da empresa, organização ou escola tem o mesmo URL de um website externo.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Não é possível fazer a retirada nesse endereço. Tente um endereço diferente.</translation>
<translation id="5572851009514199876">Inicie e faça login no Chrome para que ele possa verificar se você tem permissão para acessar este site.</translation>
<translation id="5580958916614886209">Verifique o mês de validade e tente novamente</translation>
+<translation id="5586446728396275693">Nenhum endereço salvo</translation>
+<translation id="5595485650161345191">Editar endereço</translation>
<translation id="560412284261940334">Gerenciamento não suportado</translation>
<translation id="5610142619324316209">Verificar a conexão</translation>
<translation id="5610807607761827392">É possível gerenciar cartões e endereços em <ph name="BEGIN_LINK" />Configurações<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Deseja sair deste site?</translation>
<translation id="5629630648637658800">Falha ao carregar as configurações da política</translation>
<translation id="5631439013527180824">Token de gerenciamento de dispositivo inválido</translation>
+<translation id="5633066919399395251">Invasores que estão em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> no momento podem tentar instalar programas perigosos no seu computador e roubar ou excluir suas informações (por exemplo, fotos, senhas, mensagens e cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Local</translation>
+<translation id="5659593005791499971">E-mail</translation>
<translation id="5669703222995421982">Receber conteúdo personalizado</translation>
<translation id="5675650730144413517">Esta página não está funcionando</translation>
-<translation id="5677928146339483299">Bloqueados</translation>
-<translation id="5694783966845939798">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado assinado por meio de um algoritmo de assinatura fraco (por exemplo, SHA-1). Isso significa que as credenciais de segurança apresentadas pelo servidor podem ter sido forjadas, e talvez o servidor não seja o esperado (você pode estar se comunicando com um invasor). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">A identidade deste site não foi confirmada.</translation>
+<translation id="5713016350996637505">Conteúdo enganoso bloqueado</translation>
<translation id="5720705177508910913">Usuário atual</translation>
<translation id="5732392974455271431">Seus responsáveis podem desbloqueá-lo para você</translation>
<translation id="5763042198335101085">Informe um endereço de e-mail válido.</translation>
<translation id="5765072501007116331">Para ver métodos e requisitos de entrega, selecione um endereço</translation>
+<translation id="5778550464785688721">Controle total de dispositivos MIDI</translation>
<translation id="5784606427469807560">Ocorreu um problema ao confirmar seu cartão. Verifique a conexão com a Internet e tente novamente.</translation>
<translation id="5785756445106461925">Além disso, esta página inclui outros recursos que não são seguros. Esses recursos podem ser visualizados por outros usuários enquanto eles navegam e podem ser modificados por um invasor para alterar o comportamento da página.</translation>
<translation id="5786044859038896871">Deseja preencher as informações do cartão?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Refazer adicionar</translation>
<translation id="5814352347845180253">É possível que você perca o acesso a conteúdos premier de <ph name="SITE" /> e alguns outros sites.</translation>
<translation id="5838278095973806738">Você não deve fornecer nenhuma informação confidencial nesse site (por exemplo, senhas ou cartões de crédito), porque elas podem ser roubadas por invasores.</translation>
-<translation id="5843436854350372569">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado que contém uma chave fraca. É possível que um invasor tenha violado a chave particular, e talvez o servidor não seja o esperado (você pode estar se comunicando com um invasor). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Não é possível acessar esse site</translation>
<translation id="5869522115854928033">Senhas salvas</translation>
<translation id="5872918882028971132">Sugestões para pais</translation>
<translation id="5901630391730855834">Amarelo</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sincronizado)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 em uso}one{# em uso}other{# em uso}}</translation>
<translation id="5926846154125914413">É possível que você perca o acesso a conteúdos premier de alguns sites.</translation>
<translation id="5959728338436674663">Enviar automaticamente <ph name="BEGIN_WHITEPAPER_LINK" />algumas informações do sistema e conteúdos de página<ph name="END_WHITEPAPER_LINK" /> ao Google para ajudar a detectar sites e apps perigosos. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Semana</translation>
<translation id="5967867314010545767">Remover do histórico</translation>
<translation id="5975083100439434680">Diminuir zoom</translation>
<translation id="598637245381783098">Não foi possível abrir app de pagamento</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Página 1}one{Página #}other{Página #}}</translation>
<translation id="6017514345406065928">Verde</translation>
+<translation id="6017850046339264347">Invasores em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem instalar apps enganosos que fingem ser outra pessoa ou coletam dados que podem ser usados para rastrear você. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sincronizados)</translation>
<translation id="6027201098523975773">Insira um nome</translation>
<translation id="6040143037577758943">Fechar</translation>
<translation id="6042308850641462728">Mais</translation>
+<translation id="6047233362582046994">Se você conhece os riscos para sua segurança, pode <ph name="BEGIN_LINK" />visitar este site<ph name="END_LINK" /> antes de os apps prejudiciais serem removidos.</translation>
+<translation id="6051221802930200923">Não é possível acessar <ph name="SITE" /> no momento, porque o site usa bloqueio de certificados. Como os ataques e erros de rede são geralmente temporários, esta pagina provavelmente funcionará mais tarde.</translation>
<translation id="6060685159320643512">Tome cuidado, esses experimentos podem morder</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{nenhum}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">Você acessou conteúdo usando um certificado fornecido pelo administrador. Os dados fornecidos a <ph name="DOMAIN" /> podem ser interceptados por seu administrador.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Nenhuma}=1{1 senha (sincronizada)}one{# senha (sincronizada)}other{# senhas (sincronizadas)}}</translation>
<translation id="6146055958333702838">Verifique todos os cabos e reinicie todos os roteadores, modens ou outros
dispositivos de rede que você estiver usando.</translation>
<translation id="614940544461990577">Tente:</translation>
<translation id="6151417162996330722">O certificado do servidor tem um período de validade excessivamente longo.</translation>
<translation id="6157877588268064908">Para ver métodos e requisitos de envio, selecione um endereço</translation>
+<translation id="6158003235852588289">Recentemente, o recurso "Navegação segura" do Google detectou phishing em <ph name="SITE" />. Sites de phishing fingem ser outros sites para enganar você.</translation>
<translation id="6165508094623778733">Saiba mais</translation>
+<translation id="6169916984152623906">Agora você pode navegar com privacidade. Outras pessoas que usarem este dispositivo não verão sua atividade, mas os downloads e favoritos serão salvos.</translation>
<translation id="6177128806592000436">Sua conexão com esse site não é segura</translation>
<translation id="6184817833369986695">(coorte: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Verifique sua conexão com a Internet</translation>
<translation id="6218753634732582820">Remover endereço do Chromium?</translation>
+<translation id="6221345481584921695">A Navegação segura do Google recentemente <ph name="BEGIN_LINK" />detectou malware<ph name="END_LINK" /> em <ph name="SITE" />. Websites que geralmente são seguros estão, algumas vezes, infectados com malware. O conteúdo malicioso vem de <ph name="SUBRESOURCE_HOST" />, um distribuidor de malware conhecido.</translation>
<translation id="6251924700383757765">Política de Privacidade</translation>
<translation id="6254436959401408446">Não há memória suficiente para abrir essa página</translation>
<translation id="625755898061068298">Você optou por desativar os avisos de segurança para esse site.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Editar favorito</translation>
<translation id="6410264514553301377">Digite a data de validade e o CVC do <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Você perguntou ao seu responsável se pode visitar este site</translation>
-<translation id="6416403317709441254">Não é possível visitar <ph name="SITE" /> no momento porque o website enviou credenciais codificadas que o Chromium não consegue processar. Ataques e erros de rede costumam ser temporários. Portanto, esta página deve voltar a funcionar mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Não foi possível verificar se o certificado foi revogado</translation>
<translation id="6433490469411711332">Editar informações de contato</translation>
<translation id="6433595998831338502">A conexão com <ph name="HOST_NAME" /> foi recusada.</translation>
<translation id="6446608382365791566">Adicionar mais informações</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmar reenvio do formulário</translation>
<translation id="6456339708790392414">Seu pagamento</translation>
<translation id="6458467102616083041">Ignorado porque a pesquisa padrão foi desativada por uma política.</translation>
-<translation id="6462969404041126431">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele pode ter sido revogado. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Políticas de dispositivos</translation>
<translation id="6477321094435799029">O Chrome detectou um código incomum nesta página e a bloqueou para proteger suas informações pessoais (por exemplo, senhas, números de telefone e cartões de crédito).</translation>
<translation id="6489534406876378309">Iniciar upload de falhas</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Validade: <ph name="EXPIRATION_DATE_ABBR" />, usado pela última vez em: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Seu administrador ainda não o aprovou</translation>
<translation id="6569060085658103619">Você está vendo uma página de extensões</translation>
-<translation id="6593753688552673085">menos que <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Esse conteúdo pode tentar instalar softwares perigosos no seu dispositivo que roubam ou excluem suas informações. <ph name="BEGIN_LINK" />Mostrar mesmo assim<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opções de criptografia</translation>
<translation id="662080504995468778">Ficar</translation>
<translation id="6626291197371920147">Adicionar número de cartão de crédito válido</translation>
<translation id="6628463337424475685">Pesquisa do <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Invasores presentes no momento em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar instalar programas perigosos no seu Mac e roubar ou excluir suas informações (por exemplo, fotos, senhas, mensagens e cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Esta política foi encerrada.</translation>
-<translation id="6652240803263749613">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele não é confiável para o sistema operacional do seu computador. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Remover sugestão de formulário do Chromium?</translation>
<translation id="6685834062052613830">Saia e conclua a configuração</translation>
<translation id="6710213216561001401">Anterior</translation>
<translation id="6710594484020273272">&lt;Digitar termo de pesquisa&gt;</translation>
<translation id="6711464428925977395">Há algo errado com o servidor proxy, ou o endereço está incorreto.</translation>
<translation id="6727102863431372879">Definir</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{nenhum}=1{1 item}one{# items}other{# itens}}</translation>
<translation id="674375294223700098">Erro, certificado de servidor desconhecido.</translation>
<translation id="6753269504797312559">Valor da política</translation>
<translation id="6757797048963528358">O dispositivo entrou em modo de suspensão.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Código de personalização</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Falha ao carregar dados de regiões</translation>
+<translation id="6825578344716086703">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado assinado com um algoritmo de assinatura fraco (como SHA-1). Isso significa que as credenciais de segurança apresentadas pelo servidor podem ter sido forjadas, e talvez o servidor não seja o esperado (talvez você esteja se comunicando com um invasor).</translation>
+<translation id="6830728435402077660">Não seguro</translation>
<translation id="6831043979455480757">Traduzir</translation>
<translation id="6839929833149231406">Ãrea</translation>
<translation id="6874604403660855544">&amp;Refazer adicionar</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Seu cartão foi confirmado</translation>
<translation id="6897140037006041989">Agente do usuário</translation>
<translation id="6915804003454593391">Usuário:</translation>
+<translation id="6945221475159498467">Selecionar</translation>
<translation id="6948701128805548767">Para ver métodos e requisitos de retirada, selecione um endereço</translation>
<translation id="6957887021205513506">O certificado do servidor parece ser falsificado.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Ambos os servidores proxy fixo e um URL de script .pac foram especificados.</translation>
<translation id="6989763994942163495">Mostrar configurações avançadas...</translation>
<translation id="7000990526846637657">Nenhum entrada de histórico encontrada</translation>
-<translation id="7009986207543992532">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado cujo período de validade é longo demais para ser confiável. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Sua Conta do Google pode ter outras formas de histórico de navegação em <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Senhas</translation>
+<translation id="7050187094878475250">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado cujo período de validade é extremamente longo, o que não é confiável.</translation>
+<translation id="7053983685419859001">Bloquear</translation>
<translation id="7064851114919012435">Dados de contato</translation>
<translation id="7079718277001814089">Este site contém malware</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7088615885725309056">Mais antigo</translation>
<translation id="7090678807593890770">Pesquise <ph name="LINK" /> no Google</translation>
+<translation id="7108819624672055576">Permitida por uma extensão</translation>
<translation id="7119414471315195487">Fechar outras guias ou programas</translation>
<translation id="7129409597930077180">Não é possível enviar para esse endereço. Selecione um endereço diferente.</translation>
<translation id="7138472120740807366">Método de entrega</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Processando</translation>
<translation id="724691107663265825">O site a seguir contém malware</translation>
<translation id="724975217298816891">Digite a data de validade e o CVC do <ph name="CREDIT_CARD" /> para atualizar os detalhes do cartão. Depois da confirmação, os detalhes do cartão serão compartilhados com esse site.</translation>
-<translation id="725866823122871198">Não é possível estabelecer uma conexão privada com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu computador (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
+<translation id="7260504762447901703">Revogar acesso</translation>
<translation id="7275334191706090484">Favoritos gerenciados</translation>
<translation id="7298195798382681320">Recomendada</translation>
<translation id="7309308571273880165">Relatório de erros capturado em <ph name="CRASH_TIME" /> (upload solicitado pelo usuário, upload ainda não realizado)</translation>
<translation id="7334320624316649418">&amp;Refazer reordenar</translation>
<translation id="733923710415886693">O certificado do servidor não foi divulgado por meio da Transparência dos certificados.</translation>
-<translation id="7351800657706554155">Não é possível visitar <ph name="SITE" /> no momento, porque o certificado desse site foi revogado. Ataques e erros de rede costumam ser temporários. Portanto, esta página deve voltar a funcionar mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Linha de comando</translation>
<translation id="7372973238305370288">resultado da pesquisa</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Não</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Confirmar cartão</translation>
-<translation id="7394102162464064926">Tem certeza de que deseja excluir essas páginas do histórico?
-
-Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil da próxima vez.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Caminho de perfil</translation>
<translation id="7424977062513257142">Uma página incorporada nessa página da Web diz:</translation>
@@ -688,6 +754,7 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="7444046173054089907">Este site está bloqueado</translation>
<translation id="7445762425076701745">A identidade do servidor ao qual você está conectado não pode ser validada completamente. Você está conectado ao servidor com um nome válido somente na sua rede e que, portanto, uma autoridade de certificação externa não consegue validar a propriedade. Como algumas autoridades de certificação emitem certificados para esses nomes mesmo assim, não é possível garantir que você esteja conectado ao site que gostaria e não a um invasor.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Saber mais<ph name="END_LINK" /> sobre esse problema.</translation>
+<translation id="7455133967321480974">Usar padrão global (Bloquear)</translation>
<translation id="7460163899615895653">Suas guias recentes de outros dispositivos são exibidas aqui</translation>
<translation id="7469372306589899959">Confirmando cartão</translation>
<translation id="7481312909269577407">Avançar</translation>
@@ -695,36 +762,43 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="7508255263130623398">O código do dispositivo da política retornado está em branco ou não corresponde ao código do dispositivo atual</translation>
<translation id="7514365320538308">Fazer o download</translation>
<translation id="7518003948725431193">Nenhuma página da web foi encontrada para o endereço da web:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obrigatória</translation>
+<translation id="7542403920425041731">Depois da confirmação, os detalhes do cartão serão compartilhados com esse site.</translation>
<translation id="7542995811387359312">O preenchimento automático do cartão de crédito está desativado porque este formulário não usa uma conexão segura.</translation>
<translation id="7543525346216957623">Peça para seu responsável</translation>
<translation id="7549584377607005141">Esta página da Web requer os dados inseridos anteriormente para ser exibida de modo correto. É possível enviá-los novamente mas, ao fazer isso, você repete qualquer ação realizada anteriormente na página.</translation>
<translation id="7552846755917812628">Tente seguir estas dicas:</translation>
<translation id="7554791636758816595">Nova guia</translation>
+<translation id="7567204685887185387">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança pode ter sido emitido de forma fraudulenta. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Esta página está em<ph name="ORIGINAL_LANGUAGE" />Deseja traduzi-la?</translation>
<translation id="7569952961197462199">Remover cartão de crédito do Chrome?</translation>
<translation id="7569983096843329377">Preto</translation>
<translation id="7578104083680115302">Pague rapidamente em sites e aplicativos em vários dispositivos usando os cards que você salvou com o Google.</translation>
<translation id="7588950540487816470">Web física</translation>
<translation id="7592362899630581445">O certificado do servidor viola as restrições de nome.</translation>
+<translation id="7598391785903975535">Menos de <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> não consegue atender a esta solicitação no momento.</translation>
<translation id="7600965453749440009">Nunca traduzir do <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">O valor não corresponde ao período <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Data de expiração: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Você já possui dados criptografados utilizando uma versão diferente de sua senha para a Conta do Google. Digite-a abaixo.</translation>
-<translation id="7634554953375732414">Sua conexão a este site não é particular.</translation>
<translation id="7637571805876720304">Remover cartão de crédito do Chromium?</translation>
<translation id="765676359832457558">Ocultar configurações avançadas...</translation>
<translation id="7658239707568436148">Cancelar</translation>
+<translation id="7662298039739062396">Configuração controlada por uma extensão</translation>
<translation id="7667346355482952095">O token da política retornado está vazio ou não corresponde ao token atual</translation>
<translation id="7668654391829183341">Dispositivo desconhecido</translation>
<translation id="7669271284792375604">Invasores nesse site podem tentar enganar você para que instale programas que prejudicam sua experiência de navegação (por exemplo, alterando sua página inicial ou mostrando mais anúncios nos sites que você visita).</translation>
<translation id="7674629440242451245">Interessado em novos recursos interessantes do Google Chrome? Veja nosso Canal Dev em chrome.com/dev.</translation>
<translation id="7682287625158474539">Entrega</translation>
+<translation id="7701040980221191251">Nenhum</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Ir para <ph name="SITE" /> (não seguro)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificado</translation>
+<translation id="7716147886133743102">Bloqueada pelo administrador</translation>
<translation id="7716424297397655342">Não é possível carregar este site a partir do cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Não gerenciado</translation>
<translation id="7755287808199759310">Seu responsável pode desbloqueá-lo para você</translation>
<translation id="7758069387465995638">É possível que o software antivírus ou o firewall tenha bloqueado a conexão.</translation>
@@ -751,15 +825,15 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="7951415247503192394">32 bits</translation>
<translation id="7956713633345437162">Favoritos de dispositivos móveis</translation>
<translation id="7961015016161918242">Nunca</translation>
-<translation id="7962083544045318153">Código de falha <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Sempre traduzir <ph name="ORIGINAL_LANGUAGE" /> para <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Não especificado</translation>
<translation id="800218591365569300">Tente fechar outras guias ou programas para liberar memória.</translation>
<translation id="8012647001091218357">Não foi possível contatar seus pais. Tente novamente.</translation>
<translation id="8025119109950072390">Invasores nesse site podem induzir você a fazer algo perigoso, como instalar um software ou revelar suas informações pessoais (por exemplo, senhas, números de telefone ou cartões de crédito).</translation>
-<translation id="803030522067524905">Recentemente, a Navegação segura do Google detectou phishing em <ph name="SITE" />. Os sites de phishing fingem ser outros websites para enganar você. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Esta página está escrita em <ph name="SOURCE_LANGUAGE" />. Traduzi-la para <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Perguntar (padrão)</translation>
<translation id="8041089156583427627">Enviar comentários</translation>
+<translation id="8041940743680923270">Usar padrão global (Perguntar)</translation>
<translation id="8088680233425245692">Falha ao exibir artigo.</translation>
<translation id="8089520772729574115">menos de 1 MB</translation>
<translation id="8091372947890762290">A ativação está pendente no servidor</translation>
@@ -768,13 +842,14 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="8134994873729925007">Não foi possível encontrar o <ph name="BEGIN_ABBR" />endereço DNS<ph name="END_ABBR" /> do servidor de <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Seu computador entrou em modo de suspensão.</translation>
<translation id="8150722005171944719">O arquivo em <ph name="URL" /> não está legível. Ele pode ter sido removido ou movido, ou as permissões do arquivo podem estar impedindo o acesso.</translation>
+<translation id="8184538546369750125">Usar padrão global (Permitir)</translation>
+<translation id="8191494405820426728">Código de falha local: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Desfazer mover</translation>
<translation id="8201077131113104583">URL de atualização inválido para extensão com ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Resumo do pedido</translation>
<translation id="8218327578424803826">Local designado:</translation>
<translation id="8225771182978767009">A pessoa que configurou este computador optou por bloquear esse site.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Os invasores que estão atualmente em <ph name="BEGIN_BOLD" /> <ph name="SITE" /> <ph name="END_BOLD" /> podem tentar instalar programas perigosos no seu computador para roubar ou excluir suas informações (por exemplo, fotos, senhas, mensagens e cartões de crédito).</translation>
<translation id="8241707690549784388">A página que você está procurando usou as informações inseridas. Voltar à essa página poderá fazer com que todas as ações realizadas antes sejam repetidas. Deseja continuar?</translation>
<translation id="8249320324621329438">Última busca:</translation>
<translation id="8253091569723639551">Endereço de faturamento necessário</translation>
@@ -782,10 +857,11 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="8289355894181816810">Entre em contato com seu administrador de rede se não souber o que isso significa.</translation>
<translation id="8293206222192510085">Adicionar favorito</translation>
<translation id="8294431847097064396">Origem</translation>
+<translation id="8306404619377842860">Não é possível estabelecer uma conexão particular com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e hora do dispositivo (<ph name="DATE_AND_TIME" />) estão incorretas. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">A tradução falhou devido a um problema com a conexão de rede.</translation>
<translation id="8332188693563227489">O acesso a <ph name="HOST_NAME" /> foi negado</translation>
<translation id="834457929814110454">Se você entende os riscos para sua segurança, pode <ph name="BEGIN_LINK" />visitar este site<ph name="END_LINK" /> antes de os programas nocivos serem removidos.</translation>
-<translation id="8344669043927012510">Abrir a página no modo de navegação anônima (⇧⌘N)</translation>
+<translation id="8344669043927012510">Abrir a página no modo sem rastros (⇧⌘N)</translation>
<translation id="8349305172487531364">Barra de favoritos</translation>
<translation id="8363502534493474904">Desativar modo avião</translation>
<translation id="8364627913115013041">Não definida.</translation>
@@ -802,11 +878,9 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="8483780878231876732">Para usar os cards da sua Conta do Google, faça login no Google Chrome</translation>
<translation id="8488350697529856933">Aplicável a</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> demorou muito para responder.</translation>
-<translation id="852346902619691059">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança dele não é confiável para o sistema operacional do seu dispositivo. Isso pode ser causado por uma configuração incorreta ou por um invasor que interceptou sua conexão. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Ano de vencimento</translation>
<translation id="8543181531796978784">Você pode <ph name="BEGIN_ERROR_LINK" />denunciar um problema de detecção<ph name="END_ERROR_LINK" /> ou, se entende os riscos à sua segurança, <ph name="BEGIN_LINK" />acessar este site não seguro<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">A tradução falhou porque não foi possível determinar o idioma da página.</translation>
-<translation id="8559762987265718583">Não é possível estabelecer uma conexão privada com <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu dispositivo (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
<translation id="8571890674111243710">Traduzindo página para <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Ad. nº. telefone
</translation>
@@ -821,6 +895,7 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="8738058698779197622">Para estabelecer uma conexão segura, o relógio precisa ser ajustado corretamente. Isso ocorre porque os certificados que os websites usam para se identificar são válidos apenas por períodos específicos. Como o relógio do seu dispositivo está incorreto, o Chromium não pode verificar esses certificados.</translation>
<translation id="8740359287975076522">Não foi possível encontrar o &lt;abbr id="dnsDefinition"&gt;endereço DNS&lt;/abbr&gt; de <ph name="HOST_NAME" />. Diagnosticando o problema.</translation>
<translation id="8759274551635299824">Este cartão expirou</translation>
+<translation id="8761567432415473239">Recentemente, a Navegação Segura do Google <ph name="BEGIN_LINK" />encontrou programas nocivos<ph name="END_LINK" /> no site <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Refazer excluir</translation>
<translation id="8800988563907321413">As sugestões de itens nas proximidades são exibidas aqui</translation>
<translation id="8820817407110198400">Favoritos</translation>
@@ -833,29 +908,30 @@ Dica: o modo de navegação anônimo <ph name="SHORTCUT_KEY" /> pode ser útil d
<translation id="8870413625673593573">Recentemente fechadas</translation>
<translation id="8874824191258364635">Informe um número de cartão válido</translation>
<translation id="8876793034577346603">Falha ao analisar a configuração de rede.</translation>
-<translation id="8877192140621905067">Depois da confirmação, os detalhes do cartão serão compartilhados com esse site</translation>
<translation id="8889402386540077796">Matiz</translation>
<translation id="8891727572606052622">Modo de proxy inválido.</translation>
<translation id="889901481107108152">Esta experiência não está disponível na sua plataforma.</translation>
<translation id="8903921497873541725">Aumentar zoom</translation>
<translation id="8931333241327730545">Deseja salvar este cartão na sua Conta do Google?</translation>
<translation id="8932102934695377596">Seu relógio está atrasado</translation>
-<translation id="8954894007019320973">(Continuação)</translation>
<translation id="8971063699422889582">O certificado do servidor expirou.</translation>
<translation id="8986494364107987395">Enviar estatísticas de uso e relatórios de erros ao Google automaticamente</translation>
-<translation id="8987927404178983737">Mês</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">O site a seguir contém programas prejudiciais</translation>
+<translation id="8997023839087525404">O servidor apresentou um certificado que não foi divulgado publicamente usando a política de Transparência dos certificados. Esse é um requisito para alguns certificados, a fim de garantir que eles sejam confiáveis e protejam você contra invasores.</translation>
<translation id="9001074447101275817">O proxy <ph name="DOMAIN" /> exige um nome de usuário e uma senha.</translation>
+<translation id="9005998258318286617">Falha ao carregar documento PDF.</translation>
<translation id="901974403500617787">Sinalizações aplicáveis a todo o sistema podem ser definidas apenas pelo proprietário: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">O endereço de cobrança do cartão é obrigatório</translation>
<translation id="9020542370529661692">Esta página foi traduzida para <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Erro de segurança</translation>
<translation id="9038649477754266430">Usar um serviço de previsão para carregar páginas mais rapidamente</translation>
<translation id="9039213469156557790">Além disso, esta página inclui outros recursos que não são seguros. Esses recursos podem ser visualizados por outros usuários enquanto eles navegam e podem ser modificados por um invasor para alterar o comportamento da página.</translation>
-<translation id="9040185888511745258">Invasores em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar enganá-lo para que você instale programas que prejudicam sua experiência de navegação (por exemplo, mudando sua página inicial ou mostrando anúncios extras nos sites que você visita).</translation>
+<translation id="9049981332609050619">Você tentou acessar <ph name="DOMAIN" />, mas o servidor apresentou um certificado inválido.</translation>
<translation id="9050666287014529139">Senha</translation>
<translation id="9065203028668620118">Editar</translation>
<translation id="9068849894565669697">Selecionar cor</translation>
+<translation id="9069693763241529744">Bloqueada por uma extensão</translation>
<translation id="9076283476770535406">Pode apresentar conteúdo adulto</translation>
<translation id="9078964945751709336">São necessárias mais informações</translation>
<translation id="9103872766612412690">O site <ph name="SITE" /> geralmente usa criptografia para proteger suas informações. Quando o Chromium tentou se conectar a <ph name="SITE" /> dessa vez, o website retornou credenciais
@@ -865,16 +941,21 @@ incomuns e incorretas. Isso pode acontecer quando um invasor está fingindo ser
<translation id="9148507642005240123">&amp;Desfazer editar</translation>
<translation id="9154194610265714752">Atualizado</translation>
<translation id="9157595877708044936">Configurando...</translation>
+<translation id="9169664750068251925">Sempre bloquear neste site</translation>
<translation id="9170848237812810038">&amp;Desfazer</translation>
<translation id="917450738466192189">O certificado do servidor é inválido.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> usa um protocolo incompatível.</translation>
<translation id="9205078245616868884">Seus dados são criptografados com sua senha longa de sincronização. Informe-a para começar a sincronização.</translation>
<translation id="9207861905230894330">Falha ao adicionar artigo.</translation>
+<translation id="9219103736887031265">Imagens</translation>
<translation id="933612690413056017">Não há conexão com a Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">LIMPAR FORMULÃRIO</translation>
<translation id="939736085109172342">Nova pasta</translation>
<translation id="941721044073577244">Parece que você não tem permissão para visitar este site</translation>
<translation id="969892804517981540">Versão oficial</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Nenhum}=1{1 item}one{# item}other{# itens}}</translation>
<translation id="988159990683914416">Versão do desenvolvedor</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_pt-PT.xtb b/chromium/components/strings/components_strings_pt-PT.xtb
index 0719e2480fa..020ab866ec2 100644
--- a/chromium/components/strings/components_strings_pt-PT.xtb
+++ b/chromium/components/strings/components_strings_pt-PT.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Rodar para a direita</translation>
<translation id="1038842779957582377">nome desconhecido</translation>
<translation id="1050038467049342496">Fechar outras aplicações</translation>
-<translation id="1053591932240354961">De momento, não é possível aceder a <ph name="SITE" /> porque o Website enviou credenciais codificadas que o Google Chrome não consegue processar. Geralmente, os erros de rede e os ataques são temporários, pelo que é provável que esta página funcione mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Anular adição</translation>
<translation id="10614374240317010">Nunca guardadas</translation>
<translation id="106701514854093668">Marcadores do Ambiente de Trabalho</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cache da política OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> diz:</translation>
<translation id="1132774398110320017">Definições de Preenchimento automático do Chrome...</translation>
+<translation id="1150979032973867961">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o sistema operativo do seu computador não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
+<translation id="1151972924205500581">É necessária a palavra-passe</translation>
<translation id="1152921474424827756">Aceda a uma <ph name="BEGIN_LINK" />cópia em cache<ph name="END_LINK" /> de <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> fechou a ligação inesperadamente.</translation>
<translation id="1161325031994447685">Ligar novamente à rede Wi-Fi</translation>
+<translation id="1165039591588034296">Erro</translation>
<translation id="1175364870820465910">Im&amp;primir...</translation>
<translation id="1181037720776840403">Remover</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Comunicar automaticamente<ph name="END_WHITEPAPER_LINK" /> os detalhes de possíveis incidentes de segurança à Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Mais a partir deste Web site</translation>
<translation id="1206967143813997005">Assinatura com inicial incorreta</translation>
<translation id="1209206284964581585">Ocultar para já</translation>
+<translation id="121201262018556460">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado que contém uma chave fraca. Um utilizador mal intencionado poderá ter quebrado a chave privada e o servidor pode não ser o servidor esperado (pode estar a comunicar com um utilizador mal intencionado).</translation>
<translation id="1219129156119358924">Segurança do sistema</translation>
<translation id="1227224963052638717">Política desconhecida.</translation>
<translation id="1227633850867390598">Esconder o valor</translation>
<translation id="1228893227497259893">Identificador de entidade errado</translation>
<translation id="1232569758102978740">Sem nome</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
<translation id="1263231323834454256">Lista de leitura</translation>
<translation id="1264126396475825575">Relatório de falhas capturado <ph name="CRASH_TIME" /> (ainda não carregado ou ignorado)</translation>
+<translation id="1281526147609854549">Emitido por <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Conteúdo perigoso bloqueado</translation>
<translation id="1285320974508926690">Nunca traduzir este site</translation>
<translation id="129553762522093515">Fechados recentemente</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Experimente limpar os cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">A sua atividade <ph name="BEGIN_EMPHASIS" />poderá continuar visível<ph name="END_EMPHASIS" /> para:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Os Sites que visita
+ <ph name="LIST_ITEM" />A sua entidade empregadora ou escola
+ <ph name="LIST_ITEM" />O seu fornecedor de serviços de Internet
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domínio de inscrição:</translation>
<translation id="1340482604681802745">Endereço de recolha</translation>
<translation id="1344211575059133124">Parece que precisas de autorização para visitar este site</translation>
<translation id="1344588688991793829">Definições de preenchimento automático do Chromium…</translation>
+<translation id="1348198688976932919">O site que pretende visitar contém aplicações perigosas</translation>
<translation id="1374468813861204354">sugestões</translation>
<translation id="1375198122581997741">Acerca da versão</translation>
<translation id="1377321085342047638">N.º cartão</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> não enviou quaisquer dados.</translation>
<translation id="1407135791313364759">Abrir tudo</translation>
<translation id="1413809658975081374">Erro de privacidade</translation>
+<translation id="14171126816530869">A identidade de <ph name="ORGANIZATION" /> em <ph name="LOCALITY" /> foi verificada por <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Sim</translation>
<translation id="1430915738399379752">Imprimir</translation>
-<translation id="1442912890475371290">Tentativa bloqueada <ph name="BEGIN_LINK" /> de visitar uma página em <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">De momento, não é possível aceder a <ph name="SITE" /> porque o Website utiliza a afixação de certificados. Geralmente, os erros de rede e os ataques são temporários, pelo que é provável que esta página funcione mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Mostrar uma cópia guardada desta página (isto é, uma cópia desatualizada).</translation>
<translation id="1517433312004943670">Número de telefone obrigatório</translation>
<translation id="1519264250979466059">Data da Compilação</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">É necessário ativar o JavaScript para utilizar esta funcionalidade.</translation>
<translation id="1555130319947370107">Azul</translation>
<translation id="1559528461873125649">Esse ficheiro ou diretório não existe</translation>
-<translation id="1559572115229829303">&lt;p&gt;Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora (<ph name="DATE_AND_TIME" />) do seu dispositivo estão incorretas.&lt;/p&gt;
-
- &lt;p&gt;Ajuste a data e a hora na secção &lt;strong&gt;Geral&lt;/strong&gt; da aplicação &lt;strong&gt;Definições&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Ocorreu um erro ao apresentar esta página Web.</translation>
<translation id="1592005682883173041">Acesso aos dados locais</translation>
+<translation id="1594030484168838125">Escolher</translation>
<translation id="161042844686301425">Turquesa</translation>
+<translation id="1620510694547887537">Câmara</translation>
<translation id="1629803312968146339">Pretende que o Chrome guarde este cartão?</translation>
<translation id="1639239467298939599">A carregar</translation>
<translation id="1640180200866533862">Políticas do utilizador</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">A configuração de rede é inválida e não pode ser importada.</translation>
<translation id="1644574205037202324">Histórico</translation>
<translation id="1645368109819982629">Protocolo não suportado</translation>
+<translation id="1655462015569774233">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o seu certificado de segurança expirou ontem. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação. O relógio do seu computador está atualmente configurado para <ph name="CURRENT_DATE" />. Será que isso está correto? Em caso negativo, deve corrigir o relógio do seu sistema e depois atualizar esta página.}one{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o seu certificado de segurança expirou há # dias. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação. O relógio do seu computador está atualmente configurado para <ph name="CURRENT_DATE" />. Será que isso está correto? Em caso negativo, deve corrigir o relógio do seu sistema e depois atualizar esta página.}}</translation>
<translation id="1656489000284462475">Recolha</translation>
<translation id="1663943134801823270">Os cartões e os endereços são provenientes do Chrome. Pode geri-los nas <ph name="BEGIN_LINK" />Definições<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Normalmente, o site <ph name="SITE" /> utiliza a encriptação para proteger as suas informações. Quando o Google Chrome tentou estabelecer ligação a <ph name="SITE" /> desta vez, o Website devolveu credenciais invulgares e incorretas. Isto pode acontecer quando um utilizador mal intencionado tenta simular ser <ph name="SITE" /> ou quando um ecrã de início de sessão Wi-Fi interrompe a ligação. As suas informações continuam seguras porque o Google Chrome interrompeu a ligação antes de qualquer troca de dados.</translation>
-<translation id="168328519870909584">Os utilizadores mal intencionados que se encontram em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar instalar aplicações perigosas no seu dispositivo que roubem ou eliminem as suas informações (por exemplo, fotos, palavras-passe, mensagens e cartões de crédito).</translation>
<translation id="168841957122794586">O certificado do servidor contém uma chave criptográfica fraca.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o seu certificado de segurança é supostamente de amanhã. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.}one{This server could not prove that it is <ph name="DOMAIN" />; its security certificate is supposedly from # days in the future. This may be caused by a misconfiguration or an attacker intercepting your connection.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; a data do seu certificado de segurança é supostamente daqui a # dias. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.}}</translation>
<translation id="1710259589646384581">SO</translation>
<translation id="1721312023322545264">Precisa da autorização de <ph name="NAME" /> para visitar este site</translation>
<translation id="1721424275792716183">* Campo de preenchimento obrigatório</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Transferir página mais tarde</translation>
<translation id="17513872634828108">Separadores abertos</translation>
<translation id="1753706481035618306">Número de página</translation>
+<translation id="1763864636252898013">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o sistema operativo do seu dispositivo não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Experimente executar o Diagnóstico de rede do Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Atualize a frase de acesso de sincronização.</translation>
<translation id="1787142507584202372">Os separadores abertos aparecem aqui</translation>
+<translation id="1789575671122666129">Pop-ups</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Nome do titular do cartão</translation>
-<translation id="1803678881841855883">Recentemente, a Navegação segura do Google <ph name="BEGIN_LINK" />detetou programas maliciosos<ph name="END_LINK" /> em <ph name="SITE" />. Os Sites que normalmente são seguros estão, por vezes, infetados com programas maliciosos. O conteúdo malicioso é proveniente de <ph name="SUBRESOURCE_HOST" />, um distribuidor de programas maliciosos conhecido. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Adicionado a <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Pedido ou parâmetros do pedido inválidos</translation>
<translation id="1826516787628120939">A verificar</translation>
<translation id="1834321415901700177">Este site contém programas prejudiciais</translation>
+<translation id="1840414022444569775">Este número do cartão já está a ser utilizado.</translation>
<translation id="1842969606798536927">Pagar</translation>
<translation id="1871208020102129563">O proxy está definido para utilizar servidores proxy fixos e não um URL de script .pac.</translation>
<translation id="1871284979644508959">Campo obrigatório</translation>
<translation id="187918866476621466">Abrir páginas iniciais</translation>
<translation id="1883255238294161206">Fechar lista</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtragem</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Nenhum}=1{1 site}one{# sites}other{# sites}}</translation>
<translation id="194030505837763158">Aceder a <ph name="LINK" /></translation>
<translation id="1962204205936693436">Marcadores de <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Erro de serialização</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorada porque foi substituída por <ph name="POLICY_NAME" /> .</translation>
<translation id="2138201775715568214">A procurar páginas da Web física próximas</translation>
<translation id="213826338245044447">Marcadores de Telemóvel</translation>
-<translation id="2148716181193084225">Hoje</translation>
+<translation id="2147827593068025794">Sincronização em segundo plano</translation>
<translation id="2154054054215849342">A sincronização não está disponível para o domínio</translation>
<translation id="2154484045852737596">Editar cartão</translation>
<translation id="2166049586286450108">Acesso de administrador total</translation>
<translation id="2166378884831602661">Este site não consegue fornecer uma ligação segura</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 endereço}one{# addresses}other{# endereços}}</translation>
+<translation id="2187317261103489799">Detetar (predefinição)</translation>
<translation id="2202020181578195191">Introduza um ano de expiração válido</translation>
<translation id="2212735316055980242">Política não encontrada</translation>
<translation id="2213606439339815911">A obter entradas...</translation>
+<translation id="2218879909401188352">Os utilizadores mal-intencionados que se encontram em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem instalar aplicações perigosas que danificam o dispositivo, adicionam cobranças ocultas à fatura de dados móveis ou roubam as suas informações pessoais. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Utilize a <ph name="BEGIN_LINK" />aplicação de diagnóstico<ph name="END_LINK" /> para corrigir a ligação</translation>
<translation id="2239100178324503013">Enviar agora</translation>
<translation id="225207911366869382">Este valor está desatualizado para esta política.</translation>
<translation id="2262243747453050782">Erro HTTP</translation>
+<translation id="2270484714375784793">Número de telefone</translation>
<translation id="2282872951544483773">Experiências Indisponíveis</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item}one{<ph name="ITEM_COUNT" /> itens}other{<ph name="ITEM_COUNT" /> itens}}</translation>
<translation id="2292556288342944218">O acesso à Internet está bloqueado</translation>
<translation id="230155334948463882">Tem um cartão novo?</translation>
-<translation id="2305919008529760154">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança pode ter sido emitido de forma fraudulenta. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">O domínio <ph name="DOMAIN" /> requer um nome de utilizador e uma palavra-passe.</translation>
-<translation id="2318774815570432836">De momento, não é possível aceder a <ph name="SITE" /> porque o Website utiliza HSTS. Geralmente, os erros de rede e os ataques são temporários, pelo que é provável que esta página funcione mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Definição controlada pelo administrador</translation>
<translation id="2354001756790975382">Outros marcadores</translation>
+<translation id="2354430244986887761">A Navegação segura do Google <ph name="BEGIN_LINK" />encontrou aplicações prejudiciais<ph name="END_LINK" /> recentemente em <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Os atacantes podem ver as imagens que está a visualizar neste site e enganá-lo ao modificá-las.</translation>
+<translation id="2356070529366658676">Perguntar</translation>
+<translation id="2359629602545592467">Várias</translation>
<translation id="2359808026110333948">Continuar</translation>
<translation id="2365563543831475020">O relatório de falhas capturado <ph name="CRASH_TIME" /> não foi carregado</translation>
<translation id="2367567093518048410">Nível</translation>
-<translation id="2371153335857947666">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança expirou ontem. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. O relógio do seu computador está atualmente definido para <ph name="CURRENT_DATE" />. Esta definição parece-lhe correta? Caso contrário, deve corrigir o relógio do seu sistema e, em seguida, atualizar esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}one{This server could not prove that it is <ph name="DOMAIN" />; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE" />. Does that look right? If not, you should correct your system's clock and then refresh this page. <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" />.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança expirou há # dias. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. O relógio do seu computador está atualmente definido para <ph name="CURRENT_DATE" />. Esta definição parece-lhe correta? Caso contrário, deve corrigir o relógio do seu sistema e, em seguida, atualizar esta página. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nenhuma alternativa da interface disponível</translation>
<translation id="2384307209577226199">Predefinição empresarial</translation>
<translation id="2386255080630008482">O certificado do servidor foi revogado.</translation>
<translation id="2392959068659972793">Apresentar políticas sem valor definido</translation>
<translation id="239429038616798445">Este método de envio não está disponível. Experimente um método diferente.</translation>
<translation id="2396249848217231973">&amp;Anular eliminação</translation>
-<translation id="2460160116472764928">Recentemente, a Navegação segura do Google <ph name="BEGIN_LINK" />detetou programas maliciosos<ph name="END_LINK" /> em <ph name="SITE" />. Os Sites que normalmente são seguros estão, por vezes, infetados com programas maliciosos. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o respetivo certificado de segurança poderá ser revogado. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
<translation id="2463739503403862330">Preencher</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Executar o Diagnóstico de rede<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL de pesquisa inválido.</translation>
+<translation id="2482878487686419369">Notificações</translation>
<translation id="2491120439723279231">O certificado do servidor contém erros.</translation>
<translation id="2495083838625180221">Analisador JSON</translation>
<translation id="2495093607237746763">Se marcada, o Chromium armazena uma cópia do seu cartão neste dispositivo para preencher formulários mais rapidamente.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Retroceder</translation>
<translation id="2515629240566999685">Verificar o sinal na área</translation>
<translation id="2516305470678292029">Alternativas da interface</translation>
+<translation id="2539524384386349900">Detetar</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> enviou uma resposta inválida.</translation>
-<translation id="2552545117464357659">Mais recente</translation>
<translation id="2556876185419854533">&amp;Anular edição</translation>
<translation id="2587730715158995865">De <ph name="ARTICLE_PUBLISHER" />. Leia esta e mais <ph name="OTHER_ARTICLE_COUNT" /> notícias.</translation>
<translation id="2587841377698384444">ID da API de diretório:</translation>
<translation id="2597378329261239068">Este documento está protegido por palavra-passe. Introduza uma palavra-passe.</translation>
<translation id="2609632851001447353">Variações</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Nenhuma}=1{1 aplicação ($1)}=2{2 aplicações ($1, $2)}one{# aplicações ($1, $2, $3)}other{# aplicações ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">O seu relógio está adiantado</translation>
<translation id="2639739919103226564">Estado:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">O acesso ao ficheiro foi negado</translation>
<translation id="2653659639078652383">Submeter</translation>
<translation id="2666117266261740852">Fechar outros separadores ou aplicações</translation>
+<translation id="2670429602441959756">Esta página contém funcionalidades que ainda não são suportadas no modo de RV e será agora fechada.</translation>
<translation id="2674170444375937751">Tem a certeza de que pretende eliminar estas páginas do seu histórico?</translation>
<translation id="2677748264148917807">Sair</translation>
-<translation id="269990154133806163">O servidor apresentou um certificado que não foi publicamente divulgado através da política de Transparência de certificados. Isto é um requisito para alguns certificados para garantir que são fidedignos e para a proteção contra utilizadores mal-intencionados. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Lista de leitura</translation>
<translation id="2704283930420550640">O valor não corresponde ao formato.</translation>
<translation id="2704951214193499422">O Chromium não conseguiu confirmar o seu cartão neste momento. Tente novamente mais tarde.</translation>
<translation id="2705137772291741111">A cópia guardada (em cache) deste site era ilegível.</translation>
<translation id="2709516037105925701">Preenchimento automático</translation>
-<translation id="2712118517637785082">Tentou aceder a <ph name="DOMAIN" />, mas o certificado que o servidor apresentou foi revogado pelo respetivo emissor. Isto significa que as credenciais de segurança que o servidor apresentou não devem, em circunstância alguma, ser consideradas fidedignas. Pode estar a comunicar com um utilizador mal-intencionado. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Pedir autorização</translation>
<translation id="2713444072780614174">Branco</translation>
<translation id="2720342946869265578">Próximo</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Registo do dispositivo em falta</translation>
<translation id="2784949926578158345">A ligação foi reposta.</translation>
<translation id="2794233252405721443">Site bloqueado</translation>
+<translation id="2799020568854403057">O site que pretende visitar contém aplicações prejudiciais</translation>
+<translation id="2803306138276472711">A Navegação Segura do Google <ph name="BEGIN_LINK" />detetou software malicioso<ph name="END_LINK" /> recentemente em <ph name="SITE" />. Os Sites que normalmente são seguros por vezes são infetados com software malicioso.</translation>
<translation id="2824775600643448204">Barra de pesquisa e endereço</translation>
<translation id="2826760142808435982">A ligação é encriptada e autenticada com <ph name="CIPHER" /> e utiliza <ph name="KX" /> como mecanismo de troca de chaves.</translation>
<translation id="2835170189407361413">Limpar formulário</translation>
+<translation id="2856444702002559011">Os atacantes poderão estar a tentar roubar as suas informações de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (por exemplo, palavras-passe, mensagens ou cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Não atualizar</translation>
<translation id="2900469785430194048">O Google Chrome ficou sem memória ao tentar apresentar esta página Web.</translation>
<translation id="2909946352844186028">Foi detetada uma alteração de rede.</translation>
<translation id="2916038427272391327">Fechar outros programas</translation>
<translation id="2922350208395188000">Não é possível verificar o certificado do servidor.</translation>
<translation id="2928905813689894207">Endereço de faturação</translation>
+<translation id="2941952326391522266">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o respetivo certificado de segurança é do domínio <ph name="DOMAIN2" />. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
<translation id="2948083400971632585">Pode desativar qualquer proxy configurado para uma ligação a partir da página de definições.</translation>
<translation id="2955913368246107853">Fechar barra de localização</translation>
<translation id="2958431318199492670">A configuração de rede não cumpre a norma ONC. Partes da configuração podem não ser importadas.</translation>
-<translation id="29611076221683977">Os hackers que atualmente se encontram em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar instalar programas perigosos no seu Mac que roubam ou eliminam as suas informações (por exemplo, fotografias, palavras-passe, mensagens e cartões de crédito).</translation>
<translation id="2966678944701946121">Exp.: <ph name="EXPIRATION_DATE_ABBR" />, adicionado a <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Para estabelecer uma ligação segura, o relógio tem de ser definido corretamente. Isto deve-se ao facto de os certificados que os Sites utilizam para se identificarem serem apenas válidos para períodos de tempo específicos. Uma vez que o relógio do seu dispositivo está incorreto, o Google Chrome não consegue validar estes certificados.</translation>
<translation id="2972581237482394796">&amp;Repetir</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Introduza um endereço válido</translation>
<translation id="2986368408720340940">Este método de recolha não está disponível. Experimente um método diferente.</translation>
<translation id="2991174974383378012">Partilha com Sites</translation>
+<translation id="2991571918955627853">Não pode visitar <ph name="SITE" /> neste momento, porque o Website utiliza HSTS. Os erros de rede e os ataques são geralmente temporários, pelo que esta página deverá funcionar mais tarde.</translation>
<translation id="3005723025932146533">Mostrar cópia guardada</translation>
<translation id="3008447029300691911">Introduza o Código de Segurança/CVC de <ph name="CREDIT_CARD" />. Ao confirmar, os detalhes do cartão são partilhados com este site.</translation>
<translation id="3010559122411665027">Entrada da lista "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Bloqueada automaticamente</translation>
<translation id="3024663005179499861">Tipo de política incorreto</translation>
<translation id="3032412215588512954">Pretende atualizar este site?</translation>
<translation id="3037605927509011580">Ah, bolas!!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{pelo menos 1 item em dispositivos sincronizados}=1{1 item (e mais em dispositivos sincronizados)}one{# items (and more on synced devices)}other{# itens (e mais em dispositivos sincronizados)}}</translation>
<translation id="3041612393474885105">Informações do certificado</translation>
<translation id="3063697135517575841">O Chrome não conseguiu confirmar o seu cartão neste momento. Tente novamente mais tarde.</translation>
<translation id="3064966200440839136">Está a sair do modo de navegação anónima para pagar através de uma aplicação externa. Pretende continuar?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Nenhuma}=1{1 palavra-passe}one{# palavras-passe}other{# palavras-passe}}</translation>
<translation id="3093245981617870298">O utilizador está em modo offline.</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3109728660330352905">Não tem autorização para ver esta página.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Experimente executar o Diagnóstico de conetividade<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Falha ao descodificar resposta</translation>
<translation id="3150653042067488994">Erro temporário do servidor</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">As páginas que visualizar em separadores de navegação anónima não são memorizadas no histórico do navegador, no armazenamento de cookies ou no histórico de pesquisas depois de fechar todos os separadores de navegação anónima. Todos os ficheiros transferidos ou os marcadores criados são guardados.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ilha</translation>
+<translation id="317583078218509884">As novas definições relativas às permissões do Website terão efeito depois de atualizar a página.</translation>
<translation id="3176929007561373547">Verifique as definições de proxy ou contacte o administrador de rede para
se certificar de que o servidor proxy está a funcionar. Se achar que não deve
utilizar um servidor proxy:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Abrir página no modo de navegação anónima</translation>
-<translation id="3202578601642193415">O mais recente</translation>
+<translation id="320323717674993345">Cancelar pagamento</translation>
<translation id="3207960819495026254">Adicionado aos marcadores</translation>
+<translation id="3225919329040284222">O servidor apresentou um certificado que não corresponde às expectativas existentes. Estas expectativas são incluídas para determinados Web sites de alta segurança para sua proteção.</translation>
<translation id="3226128629678568754">Prima o botão de atualização para enviar novamente os dados necessários para carregar a página.</translation>
+<translation id="3227137524299004712">Microfone</translation>
<translation id="3228969707346345236">Não foi possível traduzir, porque a página já está em <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Introduzir o Código de Segurança/CVC de <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Detetar sempre conteúdo importante neste site</translation>
<translation id="3254409185687681395">Marcar esta página</translation>
<translation id="3270847123878663523">&amp;Anular reordenação</translation>
<translation id="3282497668470633863">Adicionar nome no cartão</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">definições</translation>
<translation id="3345135638360864351">Não é possível enviar o seu pedido de acesso a este site a <ph name="NAME" />. Tente novamente.</translation>
<translation id="3355823806454867987">Alterar definições de proxy...</translation>
+<translation id="3361596688432910856">O Chrome <ph name="BEGIN_EMPHASIS" />não guardará<ph name="END_EMPHASIS" /> as seguintes informações:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />O seu histórico de navegação
+ <ph name="LIST_ITEM" />Os cookies e os dados de sites
+ <ph name="LIST_ITEM" />As informações introduzidas em formulários
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Erro de relógio</translation>
-<translation id="337311366426640088">Mais <ph name="ITEM_COUNT" /> itens...</translation>
<translation id="337363190475750230">Desaprovisionado</translation>
<translation id="3377188786107721145">Erro de análise da política</translation>
<translation id="3380365263193509176">Erro desconhecido</translation>
<translation id="3380864720620200369">ID do Cliente:</translation>
<translation id="3391030046425686457">Endereço de entrega</translation>
<translation id="3395827396354264108">Método de recolha</translation>
-<translation id="340013220407300675">Os atacantes podem estar a tentar roubar as suas informações de <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (por exemplo, palavras-passe, mensagens ou cartões de crédito).</translation>
<translation id="3422248202833853650">Experimente fechar outros programas para libertar memória.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> está inacessível de momento.</translation>
+<translation id="3427092606871434483">Permitir (predefinição)</translation>
<translation id="3427342743765426898">&amp;Refazer edição</translation>
<translation id="3431636764301398940">Guardar este cartão neste dispositivo</translation>
<translation id="3435896845095436175">Ativar</translation>
<translation id="3447661539832366887">O proprietário deste dispositivo desativou o jogo do dinossauro.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Intervalo de obtenção:</translation>
<translation id="3462200631372590220">Ocultar avançadas</translation>
<translation id="3467763166455606212">Nome do titular do cartão obrigatório</translation>
<translation id="3478058380795961209">Mês de validade</translation>
<translation id="3479539252931486093">Esta ação foi inesperada? <ph name="BEGIN_LINK" />Informe-nos<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Agora não</translation>
-<translation id="348000606199325318">ID de falha <ph name="CRASH_LOCAL_ID" /> (ID do servidor: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Não conseguimos falar com o(a) seu (sua) pai/mãe de momento. Tente novamente.</translation>
<translation id="3528171143076753409">O certificado do servidor não é fidedigno.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Pelo menos 1 item em dispositivos sincronizados}=1{1 item (e mais em dispositivos sincronizados)}one{# itens (e mais em dispositivos sincronizados)}other{# itens (e mais em dispositivos sincronizados)}}</translation>
<translation id="3539171420378717834">Guardar uma cópia deste cartão neste dispositivo</translation>
<translation id="3542684924769048008">Utilizar palavra-passe para:</translation>
+<translation id="3545341443414427877">Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu computador (<ph name="DATE_AND_TIME" />) estão erradas. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Encriptar todos os dados sincronizados com a sua própria frase de acesso de sincronização</translation>
-<translation id="3549761410225185768">Mais <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança é de <ph name="DOMAIN2" />. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">O seu administrador pode desbloqueá-lo</translation>
<translation id="3566021033012934673">A sua ligação não é privada</translation>
+<translation id="3569145463236695319">&lt;p&gt;Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu dispositivo (<ph name="DATE_AND_TIME" />) estão erradas.&lt;/p&gt;
+
+ &lt;p&gt;Ajuste a data e a hora na secção &lt;strong&gt;Geral&lt;/strong&gt; da aplicação &lt;strong&gt;Definições&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Adicionar nome</translation>
<translation id="3583757800736429874">&amp;Refazer movimentação</translation>
<translation id="3586931643579894722">Ocultar detalhes</translation>
-<translation id="3587482841069643663">Tudo</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Introduza uma data de expiração válida</translation>
<translation id="36224234498066874">Limpar dados de navegação...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informações do certificado</translation>
<translation id="3690164694835360974">Início de sessão não seguro</translation>
<translation id="3693415264595406141">Palavra-passe:</translation>
-<translation id="3696411085566228381">nenhuns</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">A carregar...</translation>
<translation id="3712624925041724820">Licenças esgotadas</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Verificar a configuração do proxy, da firewall e de DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Se compreende os riscos para a sua segurança, pode <ph name="BEGIN_LINK" />visitar este site não seguro<ph name="END_LINK" /> antes de os programas perigosos terem sido removidos.</translation>
<translation id="3739623965217189342">Link copiado por si</translation>
+<translation id="3744899669254331632">Não pode visitar <ph name="SITE" /> neste momento, porque o Website enviou credenciais baralhadas que o Chromium não consegue processar. Os erros de rede e os ataques são geralmente temporários, pelo que esta página deverá funcionar mais tarde.</translation>
+<translation id="3748148204939282805">Os atacantes em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem levá-lo a tomar medidas perigosas, como instalar software ou revelar as suas informações pessoais (por exemplo, palavras-passe, números de telefone ou cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">A tradução falhou devido a um erro do servidor.</translation>
<translation id="3759461132968374835">Não tem comunicado falhas recentemente. As falhas que tenham ocorrido enquanto a criação de relatórios de falha esteve desativada não surgem aqui.</translation>
+<translation id="3778403066972421603">Pretende guardar este cartão na sua Conta Google e neste dispositivo?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Expira a <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Se utilizar um servidor de proxy...</translation>
<translation id="3828924085048779000">Não é permitida uma frase de acesso vazia.</translation>
-<translation id="3845539888601087042">A mostrar o histórico do seus dispositivos com sessão iniciada. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Anterior</translation>
<translation id="3858027520442213535">Atualizar a data e a hora</translation>
<translation id="3884278016824448484">Identificador do dispositivo em conflito</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">O seu pedido para aceder a este site foi enviado para <ph name="NAME" />.</translation>
<translation id="3890664840433101773">Adicionar email</translation>
<translation id="3901925938762663762">O cartão expirou</translation>
-<translation id="3933571093587347751">{1,plural, =1{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança é supostamente de amanhã. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}one{This server could not prove that it is <ph name="DOMAIN" />; its security certificate is supposedly from # days in the future. This may be caused by a misconfiguration or an attacker intercepting your connection. <ph name="BEGIN_LEARN_MORE_LINK" />Learn more<ph name="END_LEARN_MORE_LINK" />.}other{Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança é supostamente de daqui a # dias. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Falha ao carregar o documento em PDF</translation>
+<translation id="3945915738023014686">ID do relatório de falhas carregado <ph name="CRASH_ID" /> (ID de falha de sistema local: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O respetivo certificado de segurança não especifica Nomes alternativos do requerente. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação.</translation>
<translation id="3963721102035795474">Modo de leitor</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Nenhum}=1{De 1 site }one{De # sites }other{De # sites }}</translation>
<translation id="397105322502079400">A calcular...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> está bloqueado</translation>
+<translation id="3987940399970879459">Menos de 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 página Web próxima}one{# web pages nearby}other{# páginas Web próximas}}</translation>
<translation id="4021036232240155012">O DNS é o serviço de rede que converte o nome de um Website no respetivo endereço de Internet.</translation>
<translation id="4030383055268325496">&amp;Anular adição</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">A configuração do proxy está definida para utilizar um URL de script .pac e não servidores proxy fixos.</translation>
<translation id="4098354747657067197">O site seguinte é fraudulento</translation>
<translation id="4103249731201008433">Número de série do dispositivo é inválido</translation>
+<translation id="410351446219883937">Reprodução automática</translation>
<translation id="4103763322291513355">Visite &lt;strong&gt;chrome://policy&lt;/strong&gt; para ver os URLs que foram colocados na lista negra e outras políticas aplicadas pelo administrador do sistema.</translation>
-<translation id="4110615724604346410">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança contém erros. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Permitir sempre neste Website</translation>
<translation id="4117700440116928470">O âmbito da política não é suportado.</translation>
-<translation id="4118212371799607889">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o Chromium não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 outro}one{# others}other{# outros}}</translation>
<translation id="4130226655945681476">Verificar os cabos de rede, o modem e o router</translation>
+<translation id="413544239732274901">Saiba mais</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Utilizar predefinição global (Detetar)</translation>
+<translation id="4165986682804962316">Definições de sites</translation>
<translation id="4169947484918424451">Pretende que o Chromium guarde este cartão?</translation>
<translation id="4171400957073367226">Assinatura de verificação incorreta</translation>
<translation id="4196861286325780578">&amp;Refazer movimentação</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Verificar as configurações da firewall e de antivírus<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{nenhuma}=1{1 aplicação ($1)}=2{2 aplicações ($1, $2)}one{# apps ($1, $2, $3)}other{# aplicações ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Erros</translation>
+<translation id="422022731706691852">Os atacantes em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar levá-lo a instalar programas que prejudicam a sua experiência de navegação (por exemplo, ao alterar a sua página inicial ou mostrar anúncios adicionais nos sites que visita). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Experimente executar o Diagnóstico de rede<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Válido</translation>
<translation id="4250431568374086873">A ligação a este site não é totalmente segura</translation>
<translation id="4250680216510889253">Não</translation>
<translation id="425582637250725228">É possível que as alterações não tenham sido efetuadas.</translation>
<translation id="4258748452823770588">Assinatura incorreta</translation>
+<translation id="4265872034478892965">Permitida pelo administrador</translation>
<translation id="4269787794583293679">(Sem nome de utilizador)</translation>
<translation id="4275830172053184480">Reiniciar o dispositivo</translation>
<translation id="4280429058323657511">, exp. <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Recentemente, a Navegação segura do Google <ph name="BEGIN_LINK" />encontrou programas prejudiciais<ph name="END_LINK" /> em <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Sugestões superiores</translation>
<translation id="4304224509867189079">Iniciar sessão</translation>
-<translation id="432290197980158659">O servidor apresentou um certificado que não corresponde às expetativas existentes. Estas expetativas estão incluídas em determinados Sites de alta segurança para o proteger. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Bloquear (predefinição)</translation>
<translation id="4325863107915753736">Falha ao encontrar o artigo</translation>
<translation id="4326324639298822553">Verifique a data de validade e tente novamente</translation>
<translation id="4331708818696583467">Inseguro</translation>
<translation id="4356973930735388585">Os utilizadores mal intencionados neste site podem tentar instalar programas perigosos no seu computador que roubam ou eliminam as suas informações (por exemplo, fotos, palavras-passe, mensagens e cartões de crédito).</translation>
<translation id="4372948949327679948">Valor <ph name="VALUE_TYPE" /> esperado.</translation>
+<translation id="4377125064752653719">Tentou aceder a <ph name="DOMAIN" />, mas o certificado que o servidor apresentou foi revogado pelo emissor. Isto significa que as credenciais de segurança apresentadas pelo servidor não deverão, em circunstância alguma, ser consideradas fidedignas. Pode estar a comunicar com um utilizador mal intencionado.</translation>
<translation id="4381091992796011497">Nome do utilizador:</translation>
<translation id="4394049700291259645">Desactivar</translation>
<translation id="4406896451731180161">resultados da pesquisa</translation>
+<translation id="4424024547088906515">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o Chrome não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> não aceitou o seu certificado de início de sessão ou este pode não ter sido fornecido.</translation>
<translation id="443673843213245140">A utilização de um proxy está desativada, mas existe uma configuração de proxy explícita especificada.</translation>
-<translation id="4492190037599258964">Resultados da pesquisa para "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Erro de validação: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Contactar o administrador do sistema</translation>
<translation id="450710068430902550">Partilha com o administrador</translation>
<translation id="4515275063822566619">Os cartões e os endereços são provenientes do Chrome e da sua Conta Google (<ph name="ACCOUNT_EMAIL" />). Pode geri-los nas <ph name="BEGIN_LINK" />Definições<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detalhes</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Experimente desativar as extensões.</translation>
<translation id="457875822857220463">Entrega</translation>
<translation id="4587425331216688090">Pretende remover o endereço do Chrome?</translation>
-<translation id="4589078953350245614">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado inválido. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">A sua ligação a <ph name="DOMAIN" /> está encriptada através de um conjunto de cifras moderno.</translation>
<translation id="4594403342090139922">&amp;Anular eliminação</translation>
<translation id="4619615317237390068">Separadores de outros dispositivos</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o respetivo certificado de segurança contém erros. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
+<translation id="4690462567478992370">Parar de utilizar um certificado inválido</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">A ligação foi interrompida</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Executar o Diagnóstico de rede do Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Ocorreu um erro desconhecido.</translation>
<translation id="4800132727771399293">Verifique a data de validade e o Código de Segurança/CVC e tente novamente</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">De momento, não pode aceder a <ph name="SITE" /> porque o Website enviou credenciais codificadas que o Google Chrome não consegue processar. Geralmente, os erros de rede e os ataques são temporários, pelo que é provável que esta página volte a funcionar mais tarde.</translation>
<translation id="4813512666221746211">Erro de rede</translation>
<translation id="4816492930507672669">Ajustar à página</translation>
<translation id="483020001682031208">Sem páginas da Web física a apresentar</translation>
<translation id="4850886885716139402">Ver</translation>
<translation id="4854362297993841467">Este método de fornecimento não está disponível. Experimente um método diferente.</translation>
<translation id="4858792381671956233">Perguntaste aos teus pais se podes aceder a este site.</translation>
+<translation id="4863764087567530506">Este conteúdo pode tentar enganá-lo de forma a que instale software ou revele informações pessoais. <ph name="BEGIN_LINK" />Mostrar mesmo assim<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Pesquisar histórico</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{e mais 1 página Web}one{and # more web pages}other{e mais # páginas Web}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Pagamento</translation>
<translation id="4926049483395192435">Tem de ser especificado.</translation>
<translation id="495170559598752135">Ações</translation>
<translation id="4958444002117714549">Expandir lista</translation>
-<translation id="4962322354953122629">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o Chrome não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Reativar avisos</translation>
<translation id="4989809363548539747">Este plug-in não é compatível</translation>
<translation id="5002932099480077015">Quando esta opção está ativada, o Chrome armazena uma cópia do seu cartão neste dispositivo para preencher formulários mais rapidamente.</translation>
<translation id="5018422839182700155">Não é possível abrir esta página</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Verificar as políticas do administrador</translation>
<translation id="5029568752722684782">Limpar cópia</translation>
<translation id="5031870354684148875">Acerca do Google Tradutor</translation>
+<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidade</translation>
<translation id="5045550434625856497">Palavra-passe incorrecta</translation>
<translation id="5056549851600133418">Artigos para si</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Verificar o endereço proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Sem cookies}=1{1 site utiliza cookies. }one{# sites use cookies. }other{# sites utilizam cookies. }}</translation>
<translation id="5087286274860437796">De momento, o certificado do servidor não é válido.</translation>
<translation id="5087580092889165836">Adicionar cartão</translation>
<translation id="5089810972385038852">Estado</translation>
+<translation id="5094747076828555589">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o Chromium não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
<translation id="5095208057601539847">Província</translation>
<translation id="5115563688576182185">(64 bits)</translation>
<translation id="5141240743006678641">Encriptar palavras-passe sincronizadas com as credenciais Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Email obrigatório</translation>
<translation id="5251803541071282808">Nuvem</translation>
<translation id="5277279256032773186">Utiliza o Chrome no trabalho? As empresas podem gerir as definições do Chrome para os seus funcionários. Saiba mais</translation>
+<translation id="5297526204711817721">A sua ligação a este site não é privada. Para sair do modo de RV a qualquer momento, remova os auscultadores com microfone integrado e prima Anterior.</translation>
<translation id="5299298092464848405">Erro ao analisar a política</translation>
-<translation id="5300589172476337783">Mostrar</translation>
<translation id="5308689395849655368">O relatório de falha está desativado.</translation>
<translation id="5317780077021120954">Guardar</translation>
<translation id="5327248766486351172">Nome</translation>
-<translation id="5337705430875057403">Utilizadores mal intencionados em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem enganá-lo no sentido de fazer algo perigoso como instalar software ou revelar as suas informações pessoais (por exemplo, palavras-passe, números de telefone ou cartões de crédito).</translation>
-<translation id="5359637492792381994">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança não é válido neste momento. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Não pode visitar <ph name="SITE" /> neste momento, porque o certificado foi revogado. Os erros de rede e os ataques são geralmente temporários, pelo que esta página deverá funcionar mais tarde.</translation>
<translation id="536296301121032821">Falha ao armazenar as definições da política</translation>
<translation id="5386426401304769735">A cadeia de certificados inclui um certificado assinado através de SHA-1.</translation>
<translation id="5402410679244714488">Exp.: <ph name="EXPIRATION_DATE_ABBR" />, última utilização há mais de um ano</translation>
+<translation id="540969355065856584">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; de momento, o respetivo certificado de segurança não é válido. Isto pode ser provocado por uma configuração incorreta ou por um atacante que esteja a intercetar a sua ligação.</translation>
<translation id="5421136146218899937">Limpar dados de navegação...</translation>
<translation id="5430298929874300616">Remover marcador</translation>
<translation id="5431657950005405462">O ficheiro não foi encontrado</translation>
-<translation id="5435775191620395718">A mostrar o histórico deste dispositivo. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Erro de validação de esquema em "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Não é possível encontrar esta página de <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">Carimbo de data/hora da política incorreto</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> de <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Inválido</translation>
<translation id="5470861586879999274">&amp;Refazer edição</translation>
<translation id="54817484435770891">Adicionar endereço válido</translation>
<translation id="5492298309214877701">Este site na intranet da empresa, da entidade ou da escola tem o mesmo URL que um Website externo.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Não é possível recolher a partir deste endereço. Selecione um diferente.</translation>
<translation id="5572851009514199876">Comece e inicie sessão no Chrome para que este possa verificar se tem autorização para aceder a este site.</translation>
<translation id="5580958916614886209">Verifique o mês de validade e tente novamente</translation>
+<translation id="5586446728396275693">Nenhum endereço guardado</translation>
+<translation id="5595485650161345191">Editar morada</translation>
<translation id="560412284261940334">Gestão não suportada</translation>
<translation id="5610142619324316209">Verificar a ligação</translation>
<translation id="5610807607761827392">Pode gerir cartões e endereços nas <ph name="BEGIN_LINK" />Definições<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Pretende sair deste site?</translation>
<translation id="5629630648637658800">Falha ao carregar as definições da política</translation>
<translation id="5631439013527180824">Token de gestão do dispositivo inválido</translation>
+<translation id="5633066919399395251">Os atacantes atualmente em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar instalar programas perigosos no seu computador que roubem ou eliminem as suas informações (por exemplo, fotos, palavras-passe, mensagens e cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Localização</translation>
+<translation id="5659593005791499971">Email</translation>
<translation id="5669703222995421982">Obter conteúdo personalizado</translation>
<translation id="5675650730144413517">Esta página não está a funcionar</translation>
-<translation id="5677928146339483299">Bloqueado</translation>
-<translation id="5694783966845939798">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado assinado com um algoritmo de assinatura fraco (como SHA-1). Isto significa que as credenciais de segurança que o servidor apresentou podem ter sido falsificadas e que o servidor pode não ser o servidor esperado (pode estar a comunicar com um utilizador mal-intencionado). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">A identidade deste Web site não foi verificada.</translation>
+<translation id="5713016350996637505">Conteúdo fraudulento bloqueado</translation>
<translation id="5720705177508910913">Utilizador atual</translation>
<translation id="5732392974455271431">Os teus pais podem desbloquear-te</translation>
<translation id="5763042198335101085">Introduza um endereço de email válido</translation>
<translation id="5765072501007116331">Para ver os métodos de fornecimento e os requisitos, selecione um endereço</translation>
+<translation id="5778550464785688721">Controlo total de dispositivos MIDI</translation>
<translation id="5784606427469807560">Ocorreu um erro ao confirmar o cartão. Verifique a sua ligação à Internet e tente novamente.</translation>
<translation id="5785756445106461925">Além disso, esta página inclui outros recursos que não são seguros. Estes recursos podem ser vistos por outros utilizadores em trânsito e modificados por um utilizador mal intencionado com o intuito de alterar o aspeto da página.</translation>
<translation id="5786044859038896871">Pretende preencher as informações do cartão?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Refazer adição</translation>
<translation id="5814352347845180253">Pode perder o acesso ao conteúdo premium de <ph name="SITE" /> e de outros sites.</translation>
<translation id="5838278095973806738">Não deve introduzir informações confidenciais neste site (por exemplo, palavras-passe ou números de cartões de crédito), porque podem ser roubadas por atacantes.</translation>
-<translation id="5843436854350372569">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado que contém uma chave fraca. Um utilizador mal-intencionado pode ter quebrado a chave privada e o servidor pode não ser o servidor esperado (pode estar a comunicar com um utilizador mal-intencionado). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Não é possível aceder a este site</translation>
<translation id="5869522115854928033">Palavras-passe guardadas</translation>
<translation id="5872918882028971132">Sugestões superiores</translation>
<translation id="5901630391730855834">Amarelo</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sincronizados)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 em utilização}one{# in use}other{# em utilização}}</translation>
<translation id="5926846154125914413">Pode perder o acesso ao conteúdo premium de alguns sites.</translation>
<translation id="5959728338436674663">Enviar automaticamente algumas <ph name="BEGIN_WHITEPAPER_LINK" />informações do sistema e conteúdos de páginas<ph name="END_WHITEPAPER_LINK" /> para a Google de modo a ajudar a detetar aplicações e sites perigosos. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Semana</translation>
<translation id="5967867314010545767">Remover do histórico</translation>
<translation id="5975083100439434680">Reduzir</translation>
<translation id="598637245381783098">Não é possível abrir a aplicação de pagamento</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Página 1}one{Page #}other{Página #}}</translation>
<translation id="6017514345406065928">Verde</translation>
+<translation id="6017850046339264347">Os utilizadores mal-intencionados em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem instalar aplicações fraudulentas que se fazem passar por algo diferente ou recolhem dados que podem ser utilizados para o monitorizar. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sincronizados)</translation>
<translation id="6027201098523975773">Introduza um nome</translation>
<translation id="6040143037577758943">Fechar</translation>
<translation id="6042308850641462728">Mais</translation>
+<translation id="6047233362582046994">Se compreende os riscos para a sua segurança, pode <ph name="BEGIN_LINK" />visitar este site<ph name="END_LINK" /> antes de as aplicações prejudiciais terem sido removidas.</translation>
+<translation id="6051221802930200923">Não pode visitar <ph name="SITE" /> neste momento, porque o Website utiliza a afixação de certificados. Os erros de rede e os ataques são geralmente temporários, pelo que esta página deverá funcionar mais tarde.</translation>
<translation id="6060685159320643512">Tenha cuidado, estas experiências podem morder</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{nenhuma}=1{1}one{#}other{#}}</translation>
+<translation id="6080696365213338172">Acedeu a conteúdos utilizando um certificado fornecido por um administrador. Os dados que fornecer a <ph name="DOMAIN" /> podem ser intercetados pelo seu administrador.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Nenhuma}=1{1 palavra-passe (sincronizada)}one{# palavras-passe (sincronizadas)}other{# palavras-passe (sincronizadas)}}</translation>
<translation id="6146055958333702838">Verifique os cabos e reinicie todos os routers, modems ou outros
dispositivos de rede que possa estar a utilizar.</translation>
<translation id="614940544461990577">Experimente:</translation>
<translation id="6151417162996330722">O certificado do servidor tem um período de validade demasiado longo.</translation>
<translation id="6157877588268064908">Para ver os métodos de envio e os requisitos, selecione um endereço</translation>
+<translation id="6158003235852588289">A Navegação segura do Google detetou recentemente phishing em <ph name="SITE" />. Os sites de phishing simulam ser outros Websites para enganá-lo.</translation>
<translation id="6165508094623778733">Saiba mais</translation>
+<translation id="6169916984152623906">Agora, pode navegar em privado e as outras pessoas que utilizarem este dispositivo não veem a sua atividade. No entanto, as transferências e os marcadores são guardados.</translation>
<translation id="6177128806592000436">A sua ligação a este site não é segura</translation>
<translation id="6184817833369986695">(grupo com caraterísticas em comum: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Verificar a ligação à Internet</translation>
<translation id="6218753634732582820">Pretende remover o endereço do Chromium?</translation>
+<translation id="6221345481584921695">A Navegação Segura do Google <ph name="BEGIN_LINK" />detetou software malicioso<ph name="END_LINK" /> recentemente em <ph name="SITE" />. Os Sites que normalmente são seguros por vezes são infetados com software malicioso. O conteúdo malicioso provém de <ph name="SUBRESOURCE_HOST" />, um distribuidor de software malicioso conhecido.</translation>
<translation id="6251924700383757765">Política de privacidade</translation>
<translation id="6254436959401408446">Não existe memória suficiente para abrir esta página</translation>
<translation id="625755898061068298">Optou por desativar os avisos de segurança para este site.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Editar marcador</translation>
<translation id="6410264514553301377">Introduza a data de validade e o Código de Segurança/CVC de <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Perguntaste ao teu pai/à tua mãe se podes aceder a este site.</translation>
-<translation id="6416403317709441254">De momento, não é possível aceder a <ph name="SITE" /> porque o Website enviou credenciais codificadas que o Chromium não consegue processar. Geralmente, os erros de rede e os ataques são temporários, pelo que é provável que esta página funcione mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Não é possível verificar se o certificado foi revogado.</translation>
<translation id="6433490469411711332">Editar informações de contacto</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> recusou estabelecer ligação.</translation>
<translation id="6446608382365791566">Adicionar mais informações</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmar nova submissão de formulário</translation>
<translation id="6456339708790392414">O seu pagamento</translation>
<translation id="6458467102616083041">Ignorado porque a pesquisa predefinida foi desativada pela política.</translation>
-<translation id="6462969404041126431">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o respetivo certificado de segurança pode ser revogado. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Políticas do dispositivo</translation>
<translation id="6477321094435799029">O Chrome detetou código estranho nesta página e bloqueou-a para proteger as suas informações pessoais (por exemplo, palavras-passe, números de telefone e números de cartões de crédito).</translation>
<translation id="6489534406876378309">Começar a carregar falhas</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Exp.: <ph name="EXPIRATION_DATE_ABBR" />, última utilização a <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">O seu administrador ainda não o aprovou</translation>
<translation id="6569060085658103619">Está a ver a página de uma extensão</translation>
-<translation id="6593753688552673085">menos de <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Este conteúdo pode tentar instalar software perigoso no dispositivo que rouba ou elimina as suas informações. <ph name="BEGIN_LINK" />Mostrar mesmo assim<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opções de encriptação</translation>
<translation id="662080504995468778">Ficar</translation>
<translation id="6626291197371920147">Adicionar número de cartão válido</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Pesquisar</translation>
+<translation id="6630809736994426279">Os atacantes atualmente em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar instalar programas perigosos no seu Mac que roubam ou eliminam as suas informações (por exemplo, fotos, palavras-passe, mensagens e cartões de crédito). <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Esta política está obsoleta.</translation>
-<translation id="6652240803263749613">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o sistema operativo do seu computador não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Pretende remover a sugestão do formulário do Chromium?</translation>
<translation id="6685834062052613830">Termine sessão e conclua a configuração</translation>
<translation id="6710213216561001401">Anterior</translation>
<translation id="6710594484020273272">&lt;Introduzir termo de pesquisa&gt;</translation>
<translation id="6711464428925977395">Existe um problema com o servidor proxy ou o endereço está incorreto.</translation>
<translation id="6727102863431372879">Definir</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{nenhuma}=1{1 item}one{# items}other{# itens}}</translation>
<translation id="674375294223700098">Erro de certificado de servidor desconhecido.</translation>
<translation id="6753269504797312559">Valor da política</translation>
<translation id="6757797048963528358">O dispositivo entrou em suspensão.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ID de personalização</translation>
<translation id="6820686453637990663">Código de segurança</translation>
<translation id="6824266427216888781">Falha ao carregar os dados das regiões</translation>
+<translation id="6825578344716086703">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado assinado utilizando um algoritmo de assinatura fraco (como SHA-1). Isto significa que as credenciais de segurança apresentadas pelo servidor podem ter sido falsificadas e que o servidor pode não ser aquele que pretende (pode estar a comunicar com um utilizador mal intencionado).</translation>
+<translation id="6830728435402077660">Inseguro</translation>
<translation id="6831043979455480757">Traduzir</translation>
<translation id="6839929833149231406">Ãrea</translation>
<translation id="6874604403660855544">&amp;Refazer adição</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">O seu cartão foi confirmado</translation>
<translation id="6897140037006041989">Agente do utilizador</translation>
<translation id="6915804003454593391">Utilizador:</translation>
+<translation id="6945221475159498467">Seleccionar</translation>
<translation id="6948701128805548767">Para ver os métodos de recolha e os requisitos, selecione um endereço</translation>
<translation id="6957887021205513506">O certificado do servidor parece ser uma falsificação.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Foram especificados servidores proxy fixos e um URL de script .pac.</translation>
<translation id="6989763994942163495">Mostrar definições avançadas...</translation>
<translation id="7000990526846637657">Não foram encontradas entradas no histórico</translation>
-<translation id="7009986207543992532">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado cujo período de validade é demasiado longo para ser fidedigno. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">A sua Conta Google pode ter outras formas do histórico de navegação em <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Palavras-passe</translation>
+<translation id="7050187094878475250">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado cujo período de validade é demasiado longo para ser fidedigno.</translation>
+<translation id="7053983685419859001">Bloquear</translation>
<translation id="7064851114919012435">Informações de contacto</translation>
<translation id="7079718277001814089">Este site contém um programa malicioso</translation>
<translation id="7087282848513945231">Condado</translation>
-<translation id="7088615885725309056">Mais antigo</translation>
<translation id="7090678807593890770">Pesquisar <ph name="LINK" /> no Google</translation>
+<translation id="7108819624672055576">Permitida por uma extensão</translation>
<translation id="7119414471315195487">Fechar outros separadores ou programas</translation>
<translation id="7129409597930077180">Não é possível enviar para este endereço. Selecione um diferente.</translation>
<translation id="7138472120740807366">Método de fornecimento</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">A processar</translation>
<translation id="724691107663265825">O site que pretende visitar contém software malicioso</translation>
<translation id="724975217298816891">Introduza a data de validade e o Código de Segurança/CVC de <ph name="CREDIT_CARD" /> para atualizar os detalhes do cartão. Ao confirmar, os detalhes do cartão são partilhados com este site.</translation>
-<translation id="725866823122871198">Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do computador (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
+<translation id="7260504762447901703">Revogar acesso</translation>
<translation id="7275334191706090484">Marcadores Geridos</translation>
<translation id="7298195798382681320">Recomendado</translation>
<translation id="7309308571273880165">Relatório de falhas capturado no(a) <ph name="CRASH_TIME" /> (carregamento pedido pelo utilizador, ainda não carregado)</translation>
<translation id="7334320624316649418">&amp;Refazer reordenação</translation>
<translation id="733923710415886693">O certificado do servidor não foi divulgado através da Transparência de certificados.</translation>
-<translation id="7351800657706554155">De momento, não é possível aceder a <ph name="SITE" /> porque este certificado foi revogado. Geralmente, os erros de rede e os ataques são temporários, pelo que é provável que esta página funcione mais tarde. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Linha de comandos</translation>
<translation id="7372973238305370288">resultado da pesquisa</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Não</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Confirmar cartão</translation>
-<translation id="7394102162464064926">Tem a certeza de que pretende eliminar estas páginas do histórico?
-
-O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da próxima vez.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Caminho do Perfil</translation>
<translation id="7424977062513257142">Uma página incorporada nesta página Web diz:</translation>
@@ -688,6 +754,7 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="7444046173054089907">Este site está bloqueado</translation>
<translation id="7445762425076701745">Não é possível validar totalmente a identidade do servidor ao qual está ligado. Está ligado a um servidor com um nome que apenas é válido na sua rede, que não permite que uma autoridade de certificação externa valide a respectiva propriedade. Ainda assim, algumas autoridades emitem certificados para esses nomes, pelo que não há forma de garantir que está ligado ao Web site que pretende e não a um site pirata.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Saber mais<ph name="END_LINK" /> sobre este problema.</translation>
+<translation id="7455133967321480974">Utilizar predefinição global (Bloquear)</translation>
<translation id="7460163899615895653">Os seus separadores recentes de outros dispositivos aparecem aqui</translation>
<translation id="7469372306589899959">A confirmar o cartão...</translation>
<translation id="7481312909269577407">Avançar</translation>
@@ -695,36 +762,43 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="7508255263130623398">O ID do dispositivo da política devolvido está vazio ou não corresponde ao ID do dispositivo atual</translation>
<translation id="7514365320538308">Transferir</translation>
<translation id="7518003948725431193">Não foi encontrada qualquer página Web para o endereço Web: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obrigatório</translation>
+<translation id="7542403920425041731">Ao confirmar, os detalhes do cartão são partilhados com este site.</translation>
<translation id="7542995811387359312">O preenchimento automático de cartões de crédito está desactivado, porque este formulário não utiliza uma ligação segura.</translation>
<translation id="7543525346216957623">Pede aos teus pais</translation>
<translation id="7549584377607005141">Esta página Web requer os dados introduzidos anteriormente para ser corretamente apresentada. Pode enviar novamente esses dados, mas ao fazê-lo, irá repetir as ações que esta página executou anteriormente.</translation>
<translation id="7552846755917812628">Experimente as sugestões seguintes:</translation>
<translation id="7554791636758816595">Novo separador</translation>
+<translation id="7567204685887185387">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o respetivo certificado de segurança poderá ter sido emitido de forma fraudulenta. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Esta página está em<ph name="ORIGINAL_LANGUAGE" />Pretende traduzi-la?</translation>
<translation id="7569952961197462199">Pretende remover o cartão de crédito do Chrome?</translation>
<translation id="7569983096843329377">Preto</translation>
<translation id="7578104083680115302">Pague rapidamente em sites e aplicações em todos os dispositivos com cartões que tenha guardado com o Google.</translation>
<translation id="7588950540487816470">Web física</translation>
<translation id="7592362899630581445">O certificado do servidor viola as restrições de nome.</translation>
+<translation id="7598391785903975535">Menos de <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> não consegue processar este pedido de momento.</translation>
<translation id="7600965453749440009">Nunca traduzir do <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">O valor está fora do intervalo <ph name="VALUE" /> .</translation>
<translation id="7613889955535752492">Exp.: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Já tem dados encriptados usando uma versão diferente da palavra-passe da sua Conta Google. Introduza-a abaixo.</translation>
-<translation id="7634554953375732414">A sua ligação a este site não é privada.</translation>
<translation id="7637571805876720304">Pretende remover o cartão de crédito do Chromium?</translation>
<translation id="765676359832457558">Ocultar definições avançadas...</translation>
<translation id="7658239707568436148">Cancelar</translation>
+<translation id="7662298039739062396">Definição controlada por uma extensão</translation>
<translation id="7667346355482952095">O símbolo da política devolvido está vazio ou não corresponde ao símbolo atual</translation>
<translation id="7668654391829183341">Dispositivo desconhecido</translation>
<translation id="7669271284792375604">Os utilizadores mal intencionados neste site podem tentar enganá-lo para instalar programas que são prejudiciais para a sua experiência de navegação (por exemplo, ao alterar a sua página inicial ou ao mostrar anúncios adicionais em sites que visita).</translation>
<translation id="7674629440242451245">Está interessado nas novas e fantásticas funcionalidades do Chrome? Experimente o nosso canal para programadores em chrome.com/dev.</translation>
<translation id="7682287625158474539">Envio</translation>
+<translation id="7701040980221191251">Nenhum</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Prosseguir para <ph name="SITE" /> (não seguro)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificado</translation>
+<translation id="7716147886133743102">Bloqueada pelo administrador</translation>
<translation id="7716424297397655342">Não é possível carregar este site a partir da cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Não gerido</translation>
<translation id="7755287808199759310">O teu pai/a tua mãe pode desbloquear-te</translation>
<translation id="7758069387465995638">O software de firewall ou antivírus pode ter bloqueado a ligação.</translation>
@@ -751,15 +825,15 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="7951415247503192394">32 bits</translation>
<translation id="7956713633345437162">Marcadores do telemóvel</translation>
<translation id="7961015016161918242">Nunca</translation>
-<translation id="7962083544045318153">ID de falha <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Traduzir sempre do <ph name="ORIGINAL_LANGUAGE" /> para o <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Não especificado</translation>
<translation id="800218591365569300">Experimente fechar outros separadores ou programas para libertar memória.</translation>
<translation id="8012647001091218357">Não conseguimos falar com os seus pais de momento. Tente novamente.</translation>
<translation id="8025119109950072390">Os utilizadores mal intencionados neste site podem enganá-lo no sentido de fazer algo perigoso como instalar software ou revelar as suas informações pessoais (por exemplo, palavras-passe, números de telefone ou cartões de crédito).</translation>
-<translation id="803030522067524905">Recentemente, a Navegação segura do Google detetou atividade de phishing em <ph name="SITE" />. Os sites de phishing fazem-se passar por outros Sites para o enganar. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Esta página está em <ph name="SOURCE_LANGUAGE" />. Pretende traduzi-la para <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Pedir (predefinição)</translation>
<translation id="8041089156583427627">Enviar comentários</translation>
+<translation id="8041940743680923270">Utilizar predefinição global (Perguntar)</translation>
<translation id="8088680233425245692">Falha ao ver o artigo.</translation>
<translation id="8089520772729574115">menos de 1 MB</translation>
<translation id="8091372947890762290">Ativação pendente no servidor</translation>
@@ -768,13 +842,14 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="8134994873729925007">Não foi possível encontrar o <ph name="BEGIN_ABBR" />endereço DNS<ph name="END_ABBR" /> do servidor de <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">O computador entrou em suspensão.</translation>
<translation id="8150722005171944719">O ficheiro em <ph name="URL" /> não é legível. Pode ter sido removido, movido ou as permissões do ficheiro podem estar a impedir o acesso.</translation>
+<translation id="8184538546369750125">Utilizar predefinição global (Permitir)</translation>
+<translation id="8191494405820426728">ID de falha local <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Anular movimentação</translation>
<translation id="8201077131113104583">Atualizar URL inválido para a extensão com o ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Resumo da encomenda</translation>
<translation id="8218327578424803826">Localização atribuída:</translation>
<translation id="8225771182978767009">A pessoa que configurou este computador optou por bloquear este site.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Os hackers que se encontram em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar instalar programas perigosos no seu computador que roubam ou eliminam as suas informações (por exemplo, fotografias, palavras-passe, mensagens e cartões de crédito).</translation>
<translation id="8241707690549784388">A página que procura utilizou informações introduzidas por si. Regressar a essa página poderá originar a repetição de qualquer acção que tenha efetuado. Pretende continuar?</translation>
<translation id="8249320324621329438">Última obtenção:</translation>
<translation id="8253091569723639551">É necessário um endereço de faturação</translation>
@@ -782,6 +857,7 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="8289355894181816810">Se não tiver a certeza do que isto significa, contacte o administrador de rede.</translation>
<translation id="8293206222192510085">Adicionar marcador</translation>
<translation id="8294431847097064396">Origem</translation>
+<translation id="8306404619377842860">Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu dispositivo (<ph name="DATE_AND_TIME" />) estão erradas. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">A tradução falhou devido a um problema com a ligação de rede.</translation>
<translation id="8332188693563227489">O acesso a <ph name="HOST_NAME" /> foi recusado</translation>
<translation id="834457929814110454">Se compreende os riscos para a sua segurança, pode <ph name="BEGIN_LINK" />visitar este site<ph name="END_LINK" /> antes de os programas prejudiciais terem sido removidos.</translation>
@@ -802,11 +878,9 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="8483780878231876732">Para utilizar cartões da sua Conta Google, inicie sessão no Chrome.</translation>
<translation id="8488350697529856933">Aplica-se a</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> demorou demasiado tempo a responder.</translation>
-<translation id="852346902619691059">Este servidor não conseguiu provar que é <ph name="DOMAIN" />; o sistema operativo do seu dispositivo não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um utilizador mal-intencionado que intercetou a sua ligação. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Ano de validade</translation>
<translation id="8543181531796978784">Pode <ph name="BEGIN_ERROR_LINK" />comunicar um problema de deteção<ph name="END_ERROR_LINK" /> ou, se compreende os riscos para a sua segurança, <ph name="BEGIN_LINK" />aceda a este site não seguro<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">A tradução falhou porque não foi possível determinar o idioma da página.</translation>
-<translation id="8559762987265718583">Não é possível estabelecer uma ligação privada a <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, porque a data e a hora do seu dispositivo (<ph name="DATE_AND_TIME" />) estão incorretas.</translation>
<translation id="8571890674111243710">A traduzir a página para <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Adic. n.º telef.
</translation>
@@ -821,6 +895,7 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="8738058698779197622">Para estabelecer uma ligação segura, o relógio tem de ser definido corretamente. Isto deve-se ao facto de os certificados que os Sites utilizam para se identificarem serem apenas válidos para períodos de tempo específicos. Uma vez que o relógio do seu dispositivo está incorreto, o Chromium não consegue validar estes certificados.</translation>
<translation id="8740359287975076522">Não foi possível encontrar o &lt;abbr id="dnsDefinition"&gt;endereço DNS&lt;/abbr&gt; de <ph name="HOST_NAME" />. Estamos a diagnosticar o problema.</translation>
<translation id="8759274551635299824">Este cartão expirou</translation>
+<translation id="8761567432415473239">A Navegação Segura do Google <ph name="BEGIN_LINK" />encontrou programas prejudiciais<ph name="END_LINK" /> recentemente em <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Refazer eliminação</translation>
<translation id="8800988563907321413">As sugestões próximas aparecem aqui</translation>
<translation id="8820817407110198400">Marcadores</translation>
@@ -833,29 +908,30 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="8870413625673593573">Fechadas recentemente</translation>
<translation id="8874824191258364635">Introduza um número de cartão válido</translation>
<translation id="8876793034577346603">Falha ao analisar a configuração de rede.</translation>
-<translation id="8877192140621905067">Ao confirmar, os detalhes do cartão são partilhados com este site.</translation>
<translation id="8889402386540077796">Tonalidade</translation>
<translation id="8891727572606052622">Modo de proxy inválido.</translation>
<translation id="889901481107108152">Infelizmente, esta experiência não está disponível na sua plataforma.</translation>
<translation id="8903921497873541725">Ampliar</translation>
<translation id="8931333241327730545">Pretende guardar este cartão na sua Conta Google?</translation>
<translation id="8932102934695377596">O seu relógio está atrasado</translation>
-<translation id="8954894007019320973">(Cont.)</translation>
<translation id="8971063699422889582">O certificado do servidor expirou.</translation>
<translation id="8986494364107987395">Enviar automaticamente estatísticas de utilização e relatórios de falhas para a Google</translation>
-<translation id="8987927404178983737">Mês</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">O site que se segue contém programas prejudiciais</translation>
+<translation id="8997023839087525404">O servidor apresentou um certificado que não foi divulgado publicamente através da política de Transparência de certificados. Trata-se de um requisito para alguns certificados de modo a assegurar que são fidedignos e protegem contra utilizadores mal intencionados.</translation>
<translation id="9001074447101275817">O proxy <ph name="DOMAIN" /> necessita de um nome de utilizador e de uma palavra-passe.</translation>
+<translation id="9005998258318286617">Falha ao carregar o documento PDF.</translation>
<translation id="901974403500617787">Os sinalizadores que se aplicam a todo o sistema apenas podem ser definidos pelo proprietário: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Endereço de faturação do cartão necessário</translation>
<translation id="9020542370529661692">Esta página foi traduzida para <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Erro de segurança</translation>
<translation id="9038649477754266430">Utilizar um serviço de previsão para carregar páginas mais rapidamente</translation>
<translation id="9039213469156557790">Além disso, esta página inclui outros recursos que não são seguros. Estes recursos podem ser vistos por outros utilizadores em trânsito e modificados por um utilizador mal intencionado com o intuito de alterar o comportamento da página.</translation>
-<translation id="9040185888511745258">Os atacantes em <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> podem tentar enganá-lo(a) para instalar programas que são prejudiciais para a sua experiência de navegação (por exemplo, ao alterar a sua página inicial ou ao mostrar anúncios adicionais em sites que visita).</translation>
+<translation id="9049981332609050619">Tentou aceder a <ph name="DOMAIN" />, mas o servidor apresentou um certificado inválido.</translation>
<translation id="9050666287014529139">Frase de acesso</translation>
<translation id="9065203028668620118">Editar</translation>
<translation id="9068849894565669697">Selecionar cor</translation>
+<translation id="9069693763241529744">Bloqueada por uma extensão</translation>
<translation id="9076283476770535406">Pode ter conteúdo para adultos</translation>
<translation id="9078964945751709336">São necessárias mais informações</translation>
<translation id="9103872766612412690">Normalmente, o site <ph name="SITE" /> utiliza a encriptação para proteger as suas informações. Quando o Chromium tentou estabelecer ligação a <ph name="SITE" /> desta vez, o Website devolveu credenciais invulgares e incorretas. Isto pode acontecer quando um utilizador mal intencionado tenta simular ser <ph name="SITE" /> ou quando um ecrã de início de sessão Wi-Fi interrompe a ligação. As suas informações continuam seguras porque o Chromium interrompeu a ligação antes de qualquer troca de dados.</translation>
@@ -864,16 +940,21 @@ O modo de navegação anónima <ph name="SHORTCUT_KEY" /> pode ser útil da pró
<translation id="9148507642005240123">&amp;Anular edição</translation>
<translation id="9154194610265714752">Atualizado</translation>
<translation id="9157595877708044936">A configurar...</translation>
+<translation id="9169664750068251925">Bloquear sempre neste Website</translation>
<translation id="9170848237812810038">An&amp;ular</translation>
<translation id="917450738466192189">O certificado do servidor é inválido.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> e mais <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> utiliza um protocolo não suportado.</translation>
<translation id="9205078245616868884">Os dados estão encriptados com a sua frase de acesso de sincronização. Introduza-a para iniciar a sincronização.</translation>
<translation id="9207861905230894330">Falha ao adicionar o artigo.</translation>
+<translation id="9219103736887031265">Imagens</translation>
<translation id="933612690413056017">Não existe ligação à Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">LIMPAR FORMULÃRIO</translation>
<translation id="939736085109172342">Nova pasta</translation>
<translation id="941721044073577244">Parece que não tem autorização para visitar este site</translation>
<translation id="969892804517981540">Compilação oficial</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Nenhum}=1{1 item}one{# itens}other{# itens}}</translation>
<translation id="988159990683914416">Compilação de programador</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ro.xtb b/chromium/components/strings/components_strings_ro.xtb
index f0843816bc1..e7d067ecd8c 100644
--- a/chromium/components/strings/components_strings_ro.xtb
+++ b/chromium/components/strings/components_strings_ro.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Rotește în sensul acelor de ceasornic</translation>
<translation id="1038842779957582377">nume necunoscut</translation>
<translation id="1050038467049342496">închide celelalte aplicații;</translation>
-<translation id="1053591932240354961">Momentan, nu poți accesa site-ul <ph name="SITE" />, deoarece acesta a trimis date de conectare într-un format necunoscut, pe care Google Chrome nu le poate procesa. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Anulați adăugarea</translation>
<translation id="10614374240317010">Nu se salvează niciodată</translation>
<translation id="106701514854093668">Marcaje desktop</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Memoria cache pentru politică este OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> afișează mesajul:</translation>
<translation id="1132774398110320017">Setări de completare automată în Chrome...</translation>
+<translation id="1150979032973867961">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; sistemul de operare al computerului nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
+<translation id="1151972924205500581">Trebuie să introduceți o parolă</translation>
<translation id="1152921474424827756">Accesați o <ph name="BEGIN_LINK" />copie păstrată în memoria cache<ph name="END_LINK" /> a site-ului <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> a închis conexiunea în mod neașteptat.</translation>
<translation id="1161325031994447685">să te reconectezi la Wi-Fi</translation>
+<translation id="1165039591588034296">Eroare</translation>
<translation id="1175364870820465910">&amp;Printează...</translation>
<translation id="1181037720776840403">Elimină</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Raportează automat<ph name="END_WHITEPAPER_LINK" /> la Google detaliile eventualelor incidente privind securitatea. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Mai multe de la acest site</translation>
<translation id="1206967143813997005">Semnătură inițială nevalidă</translation>
<translation id="1209206284964581585">Ascunde momentan</translation>
+<translation id="121201262018556460">Ați încercat să accesați <ph name="DOMAIN" />, dar serverul a furnizat un certificat care conține o cheie slabă. Un atacator ar fi putut sparge cheia privată și este posibil ca serverul să nu fie cel așteptat de dvs. (este posibil să comunicați cu un atacator).</translation>
<translation id="1219129156119358924">Securitatea sistemului</translation>
<translation id="1227224963052638717">Politică necunoscută.</translation>
<translation id="1227633850867390598">Ascundeți valoarea</translation>
<translation id="1228893227497259893">Identificator greșit pentru entitate</translation>
<translation id="1232569758102978740">Fără titlu</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizate)</translation>
<translation id="1263231323834454256">Lista de lectură</translation>
<translation id="1264126396475825575">Raport de blocare creat <ph name="CRASH_TIME" /> (nu a fost încă încărcat sau ignorat)</translation>
+<translation id="1281526147609854549">Emis de <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Conținutul periculos a fost blocat</translation>
<translation id="1285320974508926690">Nu traduce niciodată acest site</translation>
<translation id="129553762522093515">ÃŽnchise recent</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Șterge cookie-urile<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Este posibil ca activitatea ta <ph name="BEGIN_EMPHASIS" />să fie în continuare vizibilă<ph name="END_EMPHASIS" /> pentru:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />site-urile pe care le accesezi;
+ <ph name="LIST_ITEM" />angajatorul sau școala ta;
+ <ph name="LIST_ITEM" />furnizorul de servicii de internet.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domeniu de înregistrare:</translation>
<translation id="1340482604681802745">Adresa de preluare</translation>
<translation id="1344211575059133124">Se pare că ai nevoie de permisiune ca să accesezi acest site</translation>
<translation id="1344588688991793829">Setări de completare automată în Chromium...</translation>
+<translation id="1348198688976932919">Site-ul pe care urmează să îl accesezi conține aplicații periculoase</translation>
<translation id="1374468813861204354">sugestii</translation>
<translation id="1375198122581997741">Despre versiune</translation>
<translation id="1377321085342047638">Număr card</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> nu a trimis date.</translation>
<translation id="1407135791313364759">Deschideți-le pe toate</translation>
<translation id="1413809658975081374">Eroare legată de confidențialitate</translation>
+<translation id="14171126816530869">Identitatea <ph name="ORGANIZATION" /> din <ph name="LOCALITY" /> a fost verificată de către <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Da</translation>
<translation id="1430915738399379752">Printează</translation>
-<translation id="1442912890475371290">Încercarea <ph name="BEGIN_LINK" /> de a accesa o pagină de pe <ph name="DOMAIN" /><ph name="END_LINK" /> a fost blocată.</translation>
-<translation id="1491663344921578213">Momentan, nu poți accesa site-ul <ph name="SITE" />, deoarece acesta folosește fixarea certificatelor. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Afișează o copie salvată (adică despre care se știe că este învechită) a acestei pagini.</translation>
<translation id="1517433312004943670">Numărul de telefon este obligatoriu</translation>
<translation id="1519264250979466059">Dată versiune:</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Trebuie să activezi JavaScript pentru a folosi această funcție.</translation>
<translation id="1555130319947370107">Albastru</translation>
<translation id="1559528461873125649">Nu există un astfel de fișier sau director</translation>
-<translation id="1559572115229829303">&lt;p&gt;O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora dispozitivului (<ph name="DATE_AND_TIME" />) sunt incorecte.&lt;/p&gt;
-
- &lt;p&gt;Corectează data și ora din secțiunea &lt;strong&gt;General&lt;/strong&gt; a aplicației &lt;strong&gt;Setări&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">A apărut o eroare la afișarea paginii web.</translation>
<translation id="1592005682883173041">Accesul la datele locale</translation>
+<translation id="1594030484168838125">Alegeți</translation>
<translation id="161042844686301425">Cyan</translation>
+<translation id="1620510694547887537">Camera</translation>
<translation id="1629803312968146339">Dorești ca acest card să fie salvat în Chrome?</translation>
<translation id="1639239467298939599">Se încarcă</translation>
<translation id="1640180200866533862">Politici privind utilizatorii</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Configurația rețelei este nevalidă și nu a putut fi importată.</translation>
<translation id="1644574205037202324">Istoric</translation>
<translation id="1645368109819982629">Protocol neacceptat</translation>
+<translation id="1655462015569774233">{1,plural, =1{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat ieri. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina.}few{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat acum # zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina.}other{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat acum # de zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina.}}</translation>
<translation id="1656489000284462475">Preluare</translation>
<translation id="1663943134801823270">Cardurile și adresele sunt din Chrome. Le poți gestiona în <ph name="BEGIN_LINK" />Setări<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Site-ul <ph name="SITE" /> folosește în mod obișnuit criptarea pentru a-ți proteja informațiile. Când Google Chrome a încercat să se conecteze la <ph name="SITE" /> de această dată, site-ul a returnat date de conectare neobișnuite și incorecte. Acest lucru s-a întâmplat fie pentru că un atacator încearcă să falsifice site-ul <ph name="SITE" />, fie pentru că un ecran de conectare Wi-Fi a întrerupt conexiunea. Securitatea informațiilor tale nu a fost afectată, deoarece Google Chrome a oprit conexiunea înainte ca datele să fie transferate.</translation>
-<translation id="168328519870909584">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pot încerca să instaleze aplicații periculoase pe dispozitiv, care să îți fure sau să îți șteargă informațiile (de exemplu, fotografii, parole, mesaje și carduri de credit).</translation>
<translation id="168841957122794586">Certificatul de server conține o cheie criptografică slabă.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Data de emitere a certificatului său de securitate este mâine. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator.}few{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Data de emitere a certificatului său de securitate este în viitor, peste # zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator.}other{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Data de emitere a certificatului său de securitate este în viitor, peste # de zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator.}}</translation>
<translation id="1710259589646384581">Sistem de operare</translation>
<translation id="1721312023322545264">Ai nevoie de permisiunea utilizatorului <ph name="NAME" /> ca să accesezi acest site</translation>
<translation id="1721424275792716183">* Câmp obligatoriu</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Descarcă pagina mai târziu</translation>
<translation id="17513872634828108">File deschise</translation>
<translation id="1753706481035618306">Numărul paginii</translation>
+<translation id="1763864636252898013">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; sistemul de operare al dispozitivului nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Rulează Diagnostice rețea Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Actualizează expresia de acces pentru sincronizare.</translation>
<translation id="1787142507584202372">Filele deschise sunt afișate aici</translation>
+<translation id="1789575671122666129">Ferestre de tip pop-up</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Numele titularului cardului</translation>
-<translation id="1803678881841855883">Recent, Navigarea sigură Google <ph name="BEGIN_LINK" />a detectat programe malware<ph name="END_LINK" /> pe <ph name="SITE" />. Site-urile care sunt de obicei sigure sunt uneori infectate cu programe malware. Conținutul rău-intenționat provine de la <ph name="SUBRESOURCE_HOST" />, un distribuitor cunoscut de programe malware. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Adăugat pe <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Solicitarea sau parametrii săi sunt greșiți</translation>
<translation id="1826516787628120939">Se verifică</translation>
<translation id="1834321415901700177">Acest site conține programe dăunătoare</translation>
+<translation id="1840414022444569775">Numărul cardului este folosit deja</translation>
<translation id="1842969606798536927">Plătiți</translation>
<translation id="1871208020102129563">Configurația proxy este setată să utilizeze servere proxy fixe, și nu o adresă URL pentru scripturi .pac.</translation>
<translation id="1871284979644508959">Câmp obligatoriu</translation>
<translation id="187918866476621466">Deschide paginile de pornire</translation>
<translation id="1883255238294161206">Restrângeți lista</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtrarea</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Niciunul}=1{1 site}few{# site-uri}other{# de site-uri}}</translation>
<translation id="194030505837763158">Accesați <ph name="LINK" /></translation>
<translation id="1962204205936693436">Marcaje <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Eroare de serializare</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Politica este ignorată, deoarece a fost înlocuită de <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Se caută pagini din Webul material din apropiere</translation>
<translation id="213826338245044447">Marcaje mobile</translation>
-<translation id="2148716181193084225">Astăzi</translation>
+<translation id="2147827593068025794">Sincronizare în fundal</translation>
<translation id="2154054054215849342">Sincronizarea nu este disponibilă pentru domeniul tău</translation>
<translation id="2154484045852737596">Editează cardul</translation>
<translation id="2166049586286450108">Acces complet de administrare</translation>
<translation id="2166378884831602661">Acest site nu poate oferi o conexiune sigură</translation>
<translation id="2181821976797666341">Politici</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresă}few{# adrese}other{# de adrese}}</translation>
+<translation id="2187317261103489799">Detectează (în mod prestabilit)</translation>
<translation id="2202020181578195191">Introdu un an de expirare valid</translation>
<translation id="2212735316055980242">Politica nu a fost găsită</translation>
<translation id="2213606439339815911">Se preiau intrările...</translation>
+<translation id="2218879909401188352">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ar putea să instaleze aplicații periculoase care deteriorează dispozitivul, adaugă costuri ascunse pe factura de telefonie mobilă sau îți fură informațiile cu caracter personal. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Remediază conexiunea folosind <ph name="BEGIN_LINK" />aplicația de diagnosticare<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Trimite acum</translation>
<translation id="225207911366869382">Valoarea este învechită pentru această politică.</translation>
<translation id="2262243747453050782">Eroare HTTP</translation>
+<translation id="2270484714375784793">Număr telefon</translation>
<translation id="2282872951544483773">Experimente indisponibile</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element}few{<ph name="ITEM_COUNT" /> elemente}other{<ph name="ITEM_COUNT" /> de elemente}}</translation>
<translation id="2292556288342944218">Accesul la internet este blocat</translation>
<translation id="230155334948463882">Card nou?</translation>
-<translation id="2305919008529760154">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Este posibil ca certificatul său de securitate să fi fost emis fraudulos. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> necesită un nume de utilizator și o parolă.</translation>
-<translation id="2318774815570432836">Momentan, nu poți accesa site-ul <ph name="SITE" />, deoarece acesta folosește HSTS. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Setare controlată de administrator</translation>
<translation id="2354001756790975382">Alte marcaje</translation>
+<translation id="2354430244986887761">Navigarea sigură Google <ph name="BEGIN_LINK" />a descoperit recent aplicații dăunătoare<ph name="END_LINK" /> pe <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Este posibil ca atacatorii să poată vedea imaginile la care te uiți pe acest site și să te păcălească prin modificarea lor.</translation>
+<translation id="2356070529366658676">Întreabă-mă</translation>
+<translation id="2359629602545592467">Mai multe</translation>
<translation id="2359808026110333948">Continuă</translation>
<translation id="2365563543831475020">Raportul de blocare creat <ph name="CRASH_TIME" /> nu a fost încărcat</translation>
<translation id="2367567093518048410">Nivel</translation>
-<translation id="2371153335857947666">{1,plural, =1{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat ieri. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.}few{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat acum # zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.}other{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate a expirat acum # de zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. În prezent, ora computerului este setată la <ph name="CURRENT_DATE" />. Este corect? Dacă nu este, corectează ora sistemului și actualizează pagina. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Nu sunt disponibile interfețe de utilizare alternative</translation>
<translation id="2384307209577226199">Setare prestabilită la nivel de companie</translation>
<translation id="2386255080630008482">Certificatul serverului a fost revocat.</translation>
<translation id="2392959068659972793">Afișați politicile care nu au valori setate</translation>
<translation id="239429038616798445">Această metodă de expediere nu este disponibilă. Încearcă altă metodă.</translation>
<translation id="2396249848217231973">&amp;Anulați ștergerea</translation>
-<translation id="2460160116472764928">Recent, Navigarea sigură Google <ph name="BEGIN_LINK" />a detectat programe malware<ph name="END_LINK" /> pe <ph name="SITE" />. Site-urile care sunt de obicei sigure sunt uneori infectate cu programe malware. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; este posibil ca certificatul său de securitate să fie revocat. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
<translation id="2463739503403862330">Completează</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />să rulezi Diagnostice rețea<ph name="END_LINK" />;</translation>
<translation id="2479410451996844060">Adresă URL de căutare nevalidă.</translation>
+<translation id="2482878487686419369">Notificări</translation>
<translation id="2491120439723279231">Certificatul serverului conține erori.</translation>
<translation id="2495083838625180221">Analizor JSON</translation>
<translation id="2495093607237746763">Dacă opțiunea este bifată, Chromium va stoca o copie a cardului pe dispozitiv pentru a completa formularul mai rapid.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">ÃŽnapoi</translation>
<translation id="2515629240566999685">să verifici semnalul din zona ta;</translation>
<translation id="2516305470678292029">Interfețe de utilizare alternative</translation>
+<translation id="2539524384386349900">Detectează</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> a trimis un răspuns nevalid.</translation>
-<translation id="2552545117464357659">Mai noi</translation>
<translation id="2556876185419854533">&amp;Anulați editarea</translation>
<translation id="2587730715158995865">De la <ph name="ARTICLE_PUBLISHER" />. Citește acest articol și încă <ph name="OTHER_ARTICLE_COUNT" />.</translation>
<translation id="2587841377698384444">ID-ul API-ului Directory:</translation>
<translation id="2597378329261239068">Acest document este protejat cu parolă. Introdu o parolă.</translation>
<translation id="2609632851001447353">Modificări</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Niciuna}=1{1 aplicație ($1)}=2{2 aplicații ($1, $2)}few{# aplicații ($1, $2, $3)}other{# de aplicații ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Ora este setată în viitor</translation>
<translation id="2639739919103226564">Stare:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Accesul la fișier a fost refuzat</translation>
<translation id="2653659639078652383">Trimite</translation>
<translation id="2666117266261740852">închide celelalte file sau aplicații;</translation>
+<translation id="2670429602441959756">Această pagină conține funcții care nu sunt încă acceptate în RV. Se iese...</translation>
<translation id="2674170444375937751">Sigur doriți să ștergeți aceste pagini din istoric?</translation>
<translation id="2677748264148917807">Ieși</translation>
-<translation id="269990154133806163">Serverul a prezentat un certificat care nu a fost dezvăluit public folosind politica privind Transparența certificatului. Aceasta este o cerință pentru anumite certificate, pentru a se asigura că sunt de încredere și pentru protecție împotriva atacatorilor. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Listă de lectură</translation>
<translation id="2704283930420550640">Valoarea nu se potrivește cu formatul.</translation>
<translation id="2704951214193499422">Momentan, Chromium nu a putut confirma cardul. Încearcă din nou mai târziu.</translation>
<translation id="2705137772291741111">Copia salvată (în memoria cache) a acestui site nu a putut fi citită.</translation>
<translation id="2709516037105925701">Completare automată</translation>
-<translation id="2712118517637785082">Ai încercat să accesezi <ph name="DOMAIN" />, dar certificatul prezentat de server a fost revocat de emitentul său. Acest lucru înseamnă că datele de conectare de securitate prezentate de server nu sunt deloc de încredere. Este posibil să comunici cu un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Solicită permisiunea</translation>
<translation id="2713444072780614174">Alb</translation>
<translation id="2720342946869265578">ÃŽn apropiere</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Lipsește o înregistrare pentru gadget</translation>
<translation id="2784949926578158345">Conexiunea a fost resetată.</translation>
<translation id="2794233252405721443">Site blocat</translation>
+<translation id="2799020568854403057">Site-ul pe care urmează să îl accesezi conține aplicații dăunătoare</translation>
+<translation id="2803306138276472711">Navigarea sigură Google <ph name="BEGIN_LINK" />a detectat recent programe malware<ph name="END_LINK" /> pe <ph name="SITE" />. Site-urile care sunt de obicei sigure sunt uneori infectate cu programe malware.</translation>
<translation id="2824775600643448204">Bara de adrese și de căutare</translation>
<translation id="2826760142808435982">Conexiunea este criptată și autentificată utilizând <ph name="CIPHER" /> și folosește <ph name="KX" /> ca mecanism de schimb al cheii.</translation>
<translation id="2835170189407361413">Golește formularul</translation>
+<translation id="2856444702002559011">Atacatorii pot încerca să îți fure informațiile de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (de exemplu, parole, mesaje sau date despre cardurile de credit). <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Nu reîncărca</translation>
<translation id="2900469785430194048">Google Chrome nu a avut suficientă memorie la afișarea paginii web.</translation>
<translation id="2909946352844186028">A fost detectată o schimbare a rețelei.</translation>
<translation id="2916038427272391327">închide celelalte programe;</translation>
<translation id="2922350208395188000">Certificatul serverului nu poate fi verificat.</translation>
<translation id="2928905813689894207">Adresă de facturare</translation>
+<translation id="2941952326391522266">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; certificatul său de securitate provine de la <ph name="DOMAIN2" />. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
<translation id="2948083400971632585">Puteți să dezactivați serverele proxy configurate pentru o conexiune din pagina de setări.</translation>
<translation id="2955913368246107853">Închide Bara de căutare</translation>
<translation id="2958431318199492670">Configurația rețelei nu respectă standardul ONC. Este posibil ca anumite părți ale configurației să nu fie importate.</translation>
-<translation id="29611076221683977">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pot încerca să instaleze programe periculoase pe computerul tău Mac, care să îți fure sau să îți șteargă informațiile (de exemplu, fotografiile, parolele, mesajele sau informațiile despre cardurile de credit).</translation>
<translation id="2966678944701946121">Expirat în <ph name="EXPIRATION_DATE_ABBR" />, adăugat pe <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Pentru a stabili o conexiune securizată, ceasul trebuie să fie setat corect, deoarece certificatele pe care site-urile le folosesc pentru a se identifica sunt valabile numai pentru anumite intervale de timp. Din moment ce ora de pe dispozitiv este incorectă, Google Chrome nu poate verifica aceste certificate.</translation>
<translation id="2972581237482394796">&amp;Repetă</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Introdu o adresă validă</translation>
<translation id="2986368408720340940">Această metodă de preluare nu este disponibilă. Încearcă altă metodă.</translation>
<translation id="2991174974383378012">Permiterea accesului pentru site-uri</translation>
+<translation id="2991571918955627853">Nu poți accesa <ph name="SITE" /> acum, deoarece site-ul folosește HSTS. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu.</translation>
<translation id="3005723025932146533">Afișați o copie salvată</translation>
<translation id="3008447029300691911">Introdu codul CVC pentru <ph name="CREDIT_CARD" />. După ce confirmi, acest site va avea acces la detaliile cardului tău.</translation>
<translation id="3010559122411665027">Intrarea din listă „<ph name="ENTRY_INDEX" />â€: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Blocată automat</translation>
<translation id="3024663005179499861">Tip de politică greșit</translation>
<translation id="3032412215588512954">Dorești să reîncarci acest site?</translation>
<translation id="3037605927509011580">Of, nu mai merge!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{cel puțin un element pe dispozitivele sincronizate}=1{un element (și mai multe pe dispozitivele sincronizate)}few{# elemente (și mai multe pe dispozitivele sincronizate)}other{# de elemente (și mai multe pe dispozitivele sincronizate)}}</translation>
<translation id="3041612393474885105">Informații despre certificat</translation>
<translation id="3063697135517575841">Momentan, Chrome nu a putut confirma cardul. Încearcă din nou mai târziu.</translation>
<translation id="3064966200440839136">Vei părăsi modul incognito pentru a plăti folosind o aplicație externă. Continui?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Niciuna}=1{1 parolă}few{# parole}other{# de parole}}</translation>
<translation id="3093245981617870298">Ești offline.</translation>
<translation id="3105172416063519923">ID articol:</translation>
<translation id="3109728660330352905">Nu ești autorizat(ă) să vezi această pagină.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Rulează Diagnostice conectivitate<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Răspunsul nu a putut fi decodificat</translation>
<translation id="3150653042067488994">Eroare temporară de server</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Paginile pe care le accesezi în filele incognito nu vor fi înregistrate în istoricul browserului, nu vor stoca cookie-uri și nu vor rămâne în istoricul de căutare după ce închizi toate filele incognito. Fișierele descărcate și marcajele create vor fi păstrate.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Insulă</translation>
+<translation id="317583078218509884">Setările noi pentru permisiuni legate de site-uri se vor aplica după ce reîncărcați pagina.</translation>
<translation id="3176929007561373547">Verifică setările de proxy sau contactează administratorul de rețea
pentru a te asigura că serverul proxy funcționează. Dacă nu consideri că ar trebui
să folosești un server proxy:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">deschide pagina în modul incognito;</translation>
-<translation id="3202578601642193415">Cele mai noi</translation>
+<translation id="320323717674993345">Anulează plata</translation>
<translation id="3207960819495026254">Marcată</translation>
+<translation id="3225919329040284222">Serverul a prezentat un certificat care nu se potrivește cu așteptările încorporate. Aceste așteptări sunt incluse pentru anumite site-uri web, cu un grad sporit de securitate, pentru a vă proteja.</translation>
<translation id="3226128629678568754">Apăsați butonul de reîncărcare pentru a retrimite datele necesare pentru încărcarea paginii.</translation>
+<translation id="3227137524299004712">Microfon</translation>
<translation id="3228969707346345236">Pagina nu a fost tradusă, deoarece aceasta este deja în <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Introdu codul CVC pentru <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Detectează întotdeauna conținutul important pe acest site</translation>
<translation id="3254409185687681395">Marcați această pagină</translation>
<translation id="3270847123878663523">&amp;Anulați reordonarea</translation>
<translation id="3282497668470633863">Adaugă numele de pe card</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">setări</translation>
<translation id="3345135638360864351">Solicitarea de a accesa acest site nu a putut fi trimisă la <ph name="NAME" />. Încearcă din nou.</translation>
<translation id="3355823806454867987">Modifica setările proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />nu va salva<ph name="END_EMPHASIS" /> următoarele informații:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />istoricul de navigare;
+ <ph name="LIST_ITEM" />cookie-urile și datele privind site-urile;
+ <ph name="LIST_ITEM" />informațiile introduse în formulare.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Eroare de ceas</translation>
-<translation id="337311366426640088">Încă <ph name="ITEM_COUNT" /> articole…</translation>
<translation id="337363190475750230">Scos din uz</translation>
<translation id="3377188786107721145">Eroare la analizarea politicii</translation>
<translation id="3380365263193509176">Eroare necunoscută</translation>
<translation id="3380864720620200369">Cod de client:</translation>
<translation id="3391030046425686457">Adresă de livrare</translation>
<translation id="3395827396354264108">Metodă de preluare</translation>
-<translation id="340013220407300675">Atacatorii pot încerca să vă fure informațiile de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (de exemplu, parolele, mesajele sau informațiile despre cardurile de credit).</translation>
<translation id="3422248202833853650">Încearcă să ieși din celelalte programe pentru a elibera memoria.</translation>
<translation id="3422472998109090673">Momentan, <ph name="HOST_NAME" /> nu poate fi accesat.</translation>
+<translation id="3427092606871434483">Permite (în mod prestabilit)</translation>
<translation id="3427342743765426898">&amp;Repetați editarea</translation>
<translation id="3431636764301398940">Salvează cardul pe acest dispozitiv</translation>
<translation id="3435896845095436175">Activează</translation>
<translation id="3447661539832366887">Proprietarul acestui dispozitiv a dezactivat jocul cu dinozaurul.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval de preluare:</translation>
<translation id="3462200631372590220">Ascundeți detaliile avansate</translation>
<translation id="3467763166455606212">Este necesar numele titularului cardului</translation>
<translation id="3478058380795961209">Lună expirare</translation>
<translation id="3479539252931486093">A fost o situație neașteptată? <ph name="BEGIN_LINK" />Anunță-ne<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Nu acum</translation>
-<translation id="348000606199325318">ID blocare <ph name="CRASH_LOCAL_ID" /> (ID server: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Momentan, nu ți-am putut contacta părintele. Încearcă din nou.</translation>
<translation id="3528171143076753409">Certificatul serverului nu este de încredere.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Cel puțin 1 element pe dispozitivele sincronizate}=1{1 element (și mai multe pe dispozitivele sincronizate)}few{# elemente (și mai multe pe dispozitivele sincronizate)}other{# de elemente (și mai multe pe dispozitivele sincronizate)}}</translation>
<translation id="3539171420378717834">Păstrează o copie a cardului pe dispozitiv</translation>
<translation id="3542684924769048008">Folosește parola pentru:</translation>
+<translation id="3545341443414427877">O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora computerului (<ph name="DATE_AND_TIME" />) sunt incorecte. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Criptați toate datele sincronizate cu parola dvs. de acces pentru sincronizare</translation>
-<translation id="3549761410225185768">Încă <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate provine de la <ph name="DOMAIN2" />. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Administratorul îl poate debloca pentru tine</translation>
<translation id="3566021033012934673">Conexiunea nu este privată</translation>
+<translation id="3569145463236695319">&lt;p&gt;O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora dispozitivului (<ph name="DATE_AND_TIME" />) sunt incorecte.&lt;/p&gt;
+
+ &lt;p&gt;Corectează data și ora din secțiunea &lt;strong&gt;General&lt;/strong&gt; a aplicației &lt;strong&gt;Setări&lt;/strong&gt;. &lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Adăugați un nume</translation>
<translation id="3583757800736429874">&amp;Repetați mutarea</translation>
<translation id="3586931643579894722">Ascunde detaliile</translation>
-<translation id="3587482841069643663">Toate</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Introdu o dată de expirare validă</translation>
<translation id="36224234498066874">Ștergeți datele de navigare...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informații despre certificat</translation>
<translation id="3690164694835360974">Conectarea nu este securizată</translation>
<translation id="3693415264595406141">Parolă:</translation>
-<translation id="3696411085566228381">niciuna</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Se încarcă…</translation>
<translation id="3712624925041724820">Licențe epuizate</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />să verifici configurarea pentru proxy, firewall și DNS;<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Dacă înțelegeți riscurile de securitate, puteți să <ph name="BEGIN_LINK" />accesați acest site nesigur<ph name="END_LINK" /> înainte ca programele periculoase să fie eliminate.</translation>
<translation id="3739623965217189342">Linkul copiat de tine</translation>
+<translation id="3744899669254331632">Nu poți accesa acum <ph name="SITE" />, deoarece site-ul a trimis date de conectare într-un format necunoscut pe care Chromium nu le poate procesa. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu.</translation>
+<translation id="3748148204939282805">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> te pot înșela, determinându-te să faci ceva periculos, cum ar fi să instalezi software sau să îți dezvălui informațiile cu caracter personal (de exemplu, parole, numere de telefon sau date despre cardurile de credit). <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Traducerea nu a reușit din cauza unei erori de server.</translation>
<translation id="3759461132968374835">Nu există blocări raportate recent. Blocările care au avut loc când raportarea blocărilor era dezactivată nu vor apărea aici.</translation>
+<translation id="3778403066972421603">Dorești să salvezi acest card în Contul Google și pe acest dispozitiv?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Expiră în <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Dacă utilizați un server proxy...</translation>
<translation id="3828924085048779000">Trebuie să fie introdusă expresia de acces.</translation>
-<translation id="3845539888601087042">Se afișează istoricul de pe dispozitivele pe care te-ai conectat. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">ÃŽnapoi</translation>
<translation id="3858027520442213535">Actualizează data și ora</translation>
<translation id="3884278016824448484">Identificator de gadget în conflict</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Solicitarea de a accesa acest site a fost trimisă către <ph name="NAME" /></translation>
<translation id="3890664840433101773">Adaugă o adresă de e-mail</translation>
<translation id="3901925938762663762">Cardul este expirat</translation>
-<translation id="3933571093587347751">{1,plural, =1{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Data de emitere a certificatului său de securitate este mâine. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.}few{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Data de emitere a certificatului său de securitate este în viitor, peste # zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.}other{Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Data de emitere a certificatului său de securitate este în viitor, peste # de zile. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Documentul PDF nu a fost încărcat</translation>
+<translation id="3945915738023014686">S-a încărcat Raportul de blocare cu ID-ul <ph name="CRASH_ID" /> (ID blocare locală: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; în certificatul său de securitate nu este specificat câmpul Nume alternative subiect. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator.</translation>
<translation id="3963721102035795474">Modul Cititor</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Niciunul}=1{De la 1 site }few{De la # site-uri }other{De la # de site-uri }}</translation>
<translation id="397105322502079400">Se calculează...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> este blocat</translation>
+<translation id="3987940399970879459">Mai puțin de 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 pagină web în apropiere}few{# pagini web în apropiere}other{# de pagini web în apropiere}}</translation>
<translation id="4021036232240155012">DNS este serviciul de rețea care translatează numele unui site în adresa sa de internet.</translation>
<translation id="4030383055268325496">&amp;Anulați adăugarea</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Configurația pentru proxy este setată să utilizeze o adresă URL pentru scripturi .pac, și nu servere proxy fixe.</translation>
<translation id="4098354747657067197">Urmează un site înșelător</translation>
<translation id="4103249731201008433">Numărul de serie al gadgetului este nevalid</translation>
+<translation id="410351446219883937">Redare automată</translation>
<translation id="4103763322291513355">Accesați &lt;strong&gt;chrome://policy&lt;/strong&gt; pentru a vedea adresele URL introduse pe lista neagră și alte politici impuse de către administratorul de sistem.</translation>
-<translation id="4110615724604346410">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Certificatul său de securitate conține erori. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Permiteți întotdeauna pe acest site</translation>
<translation id="4117700440116928470">Domeniul politicii nu este acceptat.</translation>
-<translation id="4118212371799607889">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Chromium nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{încă 1}few{încă #}other{încă #}}</translation>
<translation id="4130226655945681476">să verifici cablurile de rețea, modemul și routerul;</translation>
+<translation id="413544239732274901">Află mai multe</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Folosește global în mod prestabilit (detectează)</translation>
+<translation id="4165986682804962316">Setări pentru site-uri</translation>
<translation id="4169947484918424451">Dorești ca acest card să fie salvat în Chromium?</translation>
<translation id="4171400957073367226">Semnătură de verificare nevalidă</translation>
<translation id="4196861286325780578">&amp;Repetați mutarea</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />să verifici configurarea pentru firewall și antivirus;<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{niciuna}=1{1 aplicație ($1)}=2{2 aplicații ($1, $2)}few{# aplicații ($1, $2, $3)}other{# de aplicații ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Blocări</translation>
+<translation id="422022731706691852">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pot încerca să te înșele pentru a instala programe care dăunează experienței de navigare (de exemplu, schimbând pagina principală sau afișând anunțuri suplimentare pe site-urile pe care le accesezi).<ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Rulează Diagnostice rețea<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Valid</translation>
<translation id="4250431568374086873">Conexiunea la acest site nu este complet sigură</translation>
<translation id="4250680216510889253">Nu</translation>
<translation id="425582637250725228">Este posibil ca modificările să nu se salveze.</translation>
<translation id="4258748452823770588">Semnătură greșită</translation>
+<translation id="4265872034478892965">Permisă de administrator</translation>
<translation id="4269787794583293679">(Niciun nume de utilizator)</translation>
<translation id="4275830172053184480">Reporniți gadgetul</translation>
<translation id="4280429058323657511">data expirării: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Recent, Navigarea sigură Google <ph name="BEGIN_LINK" />a găsit programe rău-intenționate<ph name="END_LINK" /> pe <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Sugestii parentale</translation>
<translation id="4304224509867189079">Conectează-te</translation>
-<translation id="432290197980158659">Serverul a prezentat un certificat care nu se potrivește cu așteptările încorporate. Aceste așteptări sunt incluse pentru anumite site-uri, cu un grad sporit de securitate, pentru a te proteja. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blochează (în mod prestabilit)</translation>
<translation id="4325863107915753736">Articolul nu a fost găsit</translation>
<translation id="4326324639298822553">Verifică data de expirare și încearcă din nou</translation>
<translation id="4331708818696583467">Nesecurizat</translation>
<translation id="4356973930735388585">Atacatorii de pe acest site pot încerca să instaleze programe periculoase pe computerul tău, care să îți fure sau să îți șteargă informațiile (de exemplu, fotografiile, parolele, mesajele sau informațiile despre cardurile de credit).</translation>
<translation id="4372948949327679948">Se aștepta valoarea <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Ați încercat să accesați <ph name="DOMAIN" />, dar certificatul furnizat de server a fost revocat de emitentul său. Aceasta înseamnă că acreditările de securitate furnizate de server nu sunt deloc de încredere. Este posibil să comunicați cu un atacator.</translation>
<translation id="4381091992796011497">Nume de utilizator:</translation>
<translation id="4394049700291259645">Dezactivează</translation>
<translation id="4406896451731180161">rezultate ale căutării</translation>
+<translation id="4424024547088906515">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; Chrome nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> nu a acceptat certificatul de conectare sau un astfel de certificat nu a fost oferit.</translation>
<translation id="443673843213245140">Utilizarea unui proxy este dezactivată, dar o configurare proxy este specificată în mod explicit.</translation>
-<translation id="4492190037599258964">Rezultatele căutării pentru „<ph name="SEARCH_STRING" />â€</translation>
<translation id="4506176782989081258">Eroare de validare: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">să contactezi administratorul sistemului;</translation>
<translation id="450710068430902550">Permiterea accesului pentru administrator</translation>
<translation id="4515275063822566619">Cardurile și adresele sunt din Chrome și din Contul Google (<ph name="ACCOUNT_EMAIL" />). Poți să le gestionezi în <ph name="BEGIN_LINK" />Setări<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Detalii</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Dezactivează extensiile.</translation>
<translation id="457875822857220463">Livrare</translation>
<translation id="4587425331216688090">Elimini adresa din Chrome?</translation>
-<translation id="4589078953350245614">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat nevalid. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Conexiunea la <ph name="DOMAIN" /> este criptată folosind o suită de codificare modernă.</translation>
<translation id="4594403342090139922">&amp;Anulați ștergerea</translation>
<translation id="4619615317237390068">File de pe alte dispozitive</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; certificatul său de securitate conține erori. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
+<translation id="4690462567478992370">Nu mai folosi un certificat nevalid</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Conexiunea a fost întreruptă</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />să rulezi Diagnostice rețea Windows<ph name="END_LINK" />;</translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">A apărut o eroare necunoscută.</translation>
<translation id="4800132727771399293">Verifică data de expirare și codul CVC și încearcă din nou</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Nu poți accesa acum site-ul <ph name="SITE" />, deoarece acesta a trimis date de conectare într-un format necunoscut, pe care Google Chrome nu le poate procesa. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu.</translation>
<translation id="4813512666221746211">Eroare de rețea</translation>
<translation id="4816492930507672669">Încadrați în pagină</translation>
<translation id="483020001682031208">Nu există pagini din Webul material de afișat</translation>
<translation id="4850886885716139402">Afișează</translation>
<translation id="4854362297993841467">Această metodă de livrare nu este disponibilă. Încearcă altă metodă.</translation>
<translation id="4858792381671956233">Ți-ai întrebat părinții dacă poți accesa acest site</translation>
+<translation id="4863764087567530506">Acest conținut ar putea încerca să te convingă să instalezi software sau să dezvălui informații cu caracter personal, prin înșelătorie. <ph name="BEGIN_LINK" />Afișează oricum<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Caută în istoric</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{și încă 1 pagină web}few{și încă # pagini web}other{și încă # de pagini web}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Această pagină a fost tradusă dintr-o limbă necunoscută în <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Plată</translation>
<translation id="4926049483395192435">Valoarea trebuie specificată.</translation>
<translation id="495170559598752135">Acțiuni</translation>
<translation id="4958444002117714549">Extindeți lista</translation>
-<translation id="4962322354953122629">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Chrome nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Reactivează avertismentele</translation>
<translation id="4989809363548539747">Acest plugin nu este acceptat</translation>
<translation id="5002932099480077015">Dacă este activată, Chrome va stoca o copie a cardului pe acest dispozitiv, pentru completarea mai rapidă a formularelor.</translation>
<translation id="5018422839182700155">Pagina nu poate fi deschisă</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Consultați politicile administratorului</translation>
<translation id="5029568752722684782">Șterge copia</translation>
<translation id="5031870354684148875">Despre Google Traducere</translation>
+<translation id="5039804452771397117">Permite</translation>
<translation id="5040262127954254034">Confidențialitate</translation>
<translation id="5045550434625856497">Parolă incorectă</translation>
<translation id="5056549851600133418">Articole pentru tine</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />să verifici adresa proxy-ului;<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Niciun cookie}=1{1 site folosește cookie-uri. }few{# site-uri folosesc cookie-uri. }other{# de site-uri folosesc cookie-uri. }}</translation>
<translation id="5087286274860437796">Momentan, certificatul serverului este nevalid.</translation>
<translation id="5087580092889165836">Adaugă un card</translation>
<translation id="5089810972385038852">Stat</translation>
+<translation id="5094747076828555589">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; Chromium nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
<translation id="5095208057601539847">Provincie</translation>
<translation id="5115563688576182185">(64 de biți)</translation>
<translation id="5141240743006678641">Criptează parolele sincronizate cu datele de conectare Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Adresa de e-mail este obligatorie</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Folosești Chrome la serviciu? Companiile pot gestiona setările Chrome pentru angajații lor. Află mai multe</translation>
+<translation id="5297526204711817721">Conexiunea la acest site nu este privată. Pentru a ieși oricând din modul RV, scoate vizualizatorul și apasă pe Înapoi.</translation>
<translation id="5299298092464848405">Eroare la analizarea politicii</translation>
-<translation id="5300589172476337783">Afișează</translation>
<translation id="5308689395849655368">Raportarea blocărilor este dezactivată.</translation>
<translation id="5317780077021120954">Salvează</translation>
<translation id="5327248766486351172">Nume</translation>
-<translation id="5337705430875057403">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> te pot înșela, determinându-te să faci ceva periculos, cum ar fi să instalezi software sau să îți dezvălui informațiile personale (de exemplu, parole, numere de telefon sau carduri de credit).</translation>
-<translation id="5359637492792381994">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Momentan, certificatul său de securitate nu este valid. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Nu poți accesa <ph name="SITE" /> acum, deoarece certificatul său a fost revocat. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu.</translation>
<translation id="536296301121032821">Setările pentru politică nu au putut fi stocate</translation>
<translation id="5386426401304769735">Lanțul de certificate pentru acest site conține un certificat semnat folosind SHA-1.</translation>
<translation id="5402410679244714488">Expirat în <ph name="EXPIRATION_DATE_ABBR" />, folosit ultima dată acum peste un an</translation>
+<translation id="540969355065856584">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; momentan, certificatul de securitate nu este valid. Cauza poate fi o configurare greșită sau interceptarea conexiunii de un atacator.</translation>
<translation id="5421136146218899937">Șterge datele de navigare...</translation>
<translation id="5430298929874300616">Elimină marcajul</translation>
<translation id="5431657950005405462">Fișierul nu a fost găsit</translation>
-<translation id="5435775191620395718">Se afișează istoricul de pe acest dispozitiv. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Eroare de validare a schemei la „<ph name="ERROR_PATH" />â€: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Această pagină de pe <ph name="HOST_NAME" /> nu poate fi găsită</translation>
<translation id="5455374756549232013">Marcaj temporal greșit pentru politică</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> din <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Nevalide</translation>
<translation id="5470861586879999274">&amp;Repetați editarea</translation>
<translation id="54817484435770891">Adaugă o adresă validă</translation>
<translation id="5492298309214877701">Acest site din rețeaua intranet a companiei, organizației sau școlii are aceeași adresă URL folosită de un site extern.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Nu se poate prelua de la această adresă. Selectează altă adresă.</translation>
<translation id="5572851009514199876">Pornește și conectează-te la Chrome, ca acesta să verifice dacă ai permisiunea să accesezi site-ul.</translation>
<translation id="5580958916614886209">Verifică luna în care expiră și încearcă din nou</translation>
+<translation id="5586446728396275693">Nu există adrese salvate</translation>
+<translation id="5595485650161345191">Editează adresa</translation>
<translation id="560412284261940334">Gestionarea nu este acceptată</translation>
<translation id="5610142619324316209">să verifici conexiunea;</translation>
<translation id="5610807607761827392">Poți să gestionezi cardurile și adresele în <ph name="BEGIN_LINK" />Setări<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Dorești să părăsești acest site?</translation>
<translation id="5629630648637658800">Setările pentru politică nu au putut fi încărcate</translation>
<translation id="5631439013527180824">Indicativ nevalid pentru gestionarea gadgetului</translation>
+<translation id="5633066919399395251">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pot încerca să instaleze programe periculoase pe computerul tău, care să îți fure sau să îți șteargă informațiile (de exemplu, fotografii, parole, mesaje sau date despre cardurile de credit). <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Locație</translation>
+<translation id="5659593005791499971">Adresă de e-mail</translation>
<translation id="5669703222995421982">Obține conținut personalizat</translation>
<translation id="5675650730144413517">Pagina nu funcționează</translation>
-<translation id="5677928146339483299">Blocat</translation>
-<translation id="5694783966845939798">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat semnat folosind un algoritm de semnare slab (cum ar fi SHA-1). Acest lucru înseamnă că este posibil ca datele de conectare de securitate prezentate de server să fie falsificate sau ca serverul să nu fie cel așteptat (este posibil să comunici cu un atacator). <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Identitatea acestui site nu a fost confirmată.</translation>
+<translation id="5713016350996637505">Conținutul înșelător a fost blocat</translation>
<translation id="5720705177508910913">Utilizator curent</translation>
<translation id="5732392974455271431">Părinții tăi îl pot debloca pentru tine</translation>
<translation id="5763042198335101085">Introdu o adresă de e-mail validă</translation>
<translation id="5765072501007116331">Pentru a vedea metodele de livrare și cerințele, selectează o adresă</translation>
+<translation id="5778550464785688721">Control complet asupra dispozitivelor MIDI</translation>
<translation id="5784606427469807560">A apărut o eroare la confirmarea cardului. Verifică conexiunea la internet și încearcă din nou.</translation>
<translation id="5785756445106461925">În plus, această pagină include alte resurse care nu sunt securizate. Aceste resurse sunt vizibile pentru alți utilizatori în cursul transferului și pot fi modificate de un atacator pentru a schimba aspectul paginii.</translation>
<translation id="5786044859038896871">Dorești să completezi datele cardului de credit?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Repetați adăugarea</translation>
<translation id="5814352347845180253">Este posibil să pierzi accesul la conținutul premium de pe <ph name="SITE" /> și de pe alte site-uri.</translation>
<translation id="5838278095973806738">Nu ar trebui să introduci informații sensibile pe acest site (de exemplu, parole sau carduri de credit), deoarece ar putea fi furate de atacatori.</translation>
-<translation id="5843436854350372569">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat care conține o cheie slabă. Un atacator ar fi putut sparge cheia privată și este posibil ca serverul să nu fie cel care crezi (este posibil să comunici cu un atacator). <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Acest site nu poate fi accesat</translation>
<translation id="5869522115854928033">Parole salvate</translation>
<translation id="5872918882028971132">Sugestii parentale</translation>
<translation id="5901630391730855834">Galben</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sincronizat)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 în uz}few{# în uz}other{# în uz}}</translation>
<translation id="5926846154125914413">Este posibil să pierzi accesul la conținutul premium de pe anumite site-uri.</translation>
<translation id="5959728338436674663">Trimite automat anumite <ph name="BEGIN_WHITEPAPER_LINK" />informații despre sistem și conținutul paginii<ph name="END_WHITEPAPER_LINK" /> la Google pentru a detecta aplicațiile și site-urile periculoase. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Săptămână</translation>
<translation id="5967867314010545767">Eliminați din istoric</translation>
<translation id="5975083100439434680">Micșorează</translation>
<translation id="598637245381783098">Nu se poate deschide aplicația de plată</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Pagina 1}few{Pagina #}other{Pagina #}}</translation>
<translation id="6017514345406065928">Verde</translation>
+<translation id="6017850046339264347">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ar putea instala aplicații înșelătoare care pretind a fi altceva sau culeg date care pot fi folosite pentru a te urmări. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sincronizate)</translation>
<translation id="6027201098523975773">Introdu un nume</translation>
<translation id="6040143037577758943">ÃŽnchide</translation>
<translation id="6042308850641462728">Mai multe</translation>
+<translation id="6047233362582046994">Dacă îți asumi riscurile de securitate, poți să <ph name="BEGIN_LINK" />accesezi acest site<ph name="END_LINK" /> înainte ca aplicațiile dăunătoare să fie eliminate.</translation>
+<translation id="6051221802930200923">Nu poți accesa <ph name="SITE" /> acum, deoarece site-ul folosește fixarea certificatelor. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu.</translation>
<translation id="6060685159320643512">Atenție, aceste experimente pot produce daune</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{niciuna}=1{1}few{#}other{#}}</translation>
+<translation id="6080696365213338172">Ați accesat conținut utilizând un certificat oferit de administrator. Datele pe care le transmiteți către <ph name="DOMAIN" /> pot fi interceptate de administratorul dvs.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Niciuna}=1{1 parolă (sincronizată)}few{# parole (sincronizate)}other{# de parole (sincronizate)}}</translation>
<translation id="6146055958333702838">Verifică toate cablurile și repornește routerele, modemurile sau alte
dispozitive de rețea pe care le folosești.</translation>
<translation id="614940544461990577">Încearcă:</translation>
<translation id="6151417162996330722">Certificatul de server are o perioadă de validitate prea lungă.</translation>
<translation id="6157877588268064908">Pentru a vedea metodele de expediere și cerințele, selectează o adresă</translation>
+<translation id="6158003235852588289">Recent, Navigarea sigură Google a detectat phishing pe <ph name="SITE" />. Site-urile de phishing falsifică alte site-uri, pentru a te înșela.</translation>
<translation id="6165508094623778733">Află mai multe</translation>
+<translation id="6169916984152623906">Acum poți naviga în mod privat, iar celelalte persoane care folosesc acest dispozitiv nu îți vor vedea activitatea. Cu toate acestea, descărcările și marcajele vor fi salvate.</translation>
<translation id="6177128806592000436">Conexiunea la acest site nu este sigură</translation>
<translation id="6184817833369986695">(grup: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Verificați conexiunea la internet</translation>
<translation id="6218753634732582820">Elimini adresa din Chromium?</translation>
+<translation id="6221345481584921695">Navigarea sigură Google <ph name="BEGIN_LINK" />a detectat recent programe malware<ph name="END_LINK" /> pe <ph name="SITE" />. Site-urile care sunt de obicei sigure sunt uneori infectate cu programe malware. Conținutul rău-intenționat provine de la <ph name="SUBRESOURCE_HOST" />, un distribuitor cunoscut de programe malware.</translation>
<translation id="6251924700383757765">Politica de confidențialitate</translation>
<translation id="6254436959401408446">Nu există suficientă memorie pentru a deschide pagina</translation>
<translation id="625755898061068298">Ai ales să dezactivezi avertismentele de securitate pentru acest site.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Modificați marcajul</translation>
<translation id="6410264514553301377">Introdu data de expirare și codul CVC pentru <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Ți-ai întrebat părintele dacă poți accesa acest site</translation>
-<translation id="6416403317709441254">Momentan, nu poți accesa site-ul <ph name="SITE" />, deoarece acesta a trimis date de conectare într-un format necunoscut pe care Chromium nu le poate procesa. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Nu se poate verifica dacă certificatul a fost revocat.</translation>
<translation id="6433490469411711332">Editează informațiile de contact</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> a refuzat conexiunea.</translation>
<translation id="6446608382365791566">Adaugă mai multe informații</translation>
+<translation id="6447842834002726250">Cookie-uri</translation>
<translation id="6451458296329894277">Confirmă retrimiterea formularului</translation>
<translation id="6456339708790392414">Plata</translation>
<translation id="6458467102616083041">Valoare ignorată, deoarece politica a dezactivat căutarea prestabilită.</translation>
-<translation id="6462969404041126431">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Este posibil ca certificatul său de securitate să fi fost revocat. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Politici privind dispozitivele</translation>
<translation id="6477321094435799029">Chrome a detectat un cod neobișnuit pe această pagină și l-a blocat pentru a-ți proteja informațiile cu caracter personal (de exemplu, parole, numere de telefon sau carduri de credit).</translation>
<translation id="6489534406876378309">Începeți încărcarea rapoartelor de blocare</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Expirat în <ph name="EXPIRATION_DATE_ABBR" />, folosit ultima dată pe <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Administratorul nu l-a aprobat încă</translation>
<translation id="6569060085658103619">Se afișează pagina unei extensii</translation>
-<translation id="6593753688552673085">mai puțin de <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Acest conținut ar putea încerca să instaleze software periculos pe dispozitivul tău, care îți fură sau îți șterge informațiile. <ph name="BEGIN_LINK" />Afișează oricum<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Opțiuni de criptare</translation>
<translation id="662080504995468778">Rămâi pe pagină</translation>
<translation id="6626291197371920147">Adaugă un număr de card valid</translation>
<translation id="6628463337424475685">Căutare <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pot încerca să instaleze programe periculoase pe computerul tău Mac, care să îți fure sau să îți șteargă informațiile (de exemplu, fotografii, parole, mesaje sau date despre cardurile de credit). <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Această politică este învechită.</translation>
-<translation id="6652240803263749613">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Sistemul de operare al computerului nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Elimini sugestia pentru formular din Chromium?</translation>
<translation id="6685834062052613830">Deconectează-te și finalizează configurarea</translation>
<translation id="6710213216561001401">ÃŽnapoi</translation>
<translation id="6710594484020273272">&lt;Introdu termenul de căutare&gt;</translation>
<translation id="6711464428925977395">A apărut o problemă la serverul proxy sau adresa nu este corectă.</translation>
<translation id="6727102863431372879">Setează</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{niciuna}=1{1 element}few{# elemente}other{# de elemente}}</translation>
<translation id="674375294223700098">Eroare de certificat de server necunoscută.</translation>
<translation id="6753269504797312559">Valoarea politicii</translation>
<translation id="6757797048963528358">Dispozitivul este inactiv.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ID-ul de personalizare</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Datele regiunii nu au fost încărcate</translation>
+<translation id="6825578344716086703">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat semnat folosind un algoritm de semnare slab (cum ar fi SHA-1). Acest lucru înseamnă că este posibil ca datele de conectare de securitate prezentate de server să fie falsificate sau ca serverul să nu fie cel așteptat (este posibil să comunici cu un atacator).</translation>
+<translation id="6830728435402077660">Nesecurizată</translation>
<translation id="6831043979455480757">Tradu</translation>
<translation id="6839929833149231406">Zonă</translation>
<translation id="6874604403660855544">&amp;Repetați adăugarea</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Cardul tău este confirmat</translation>
<translation id="6897140037006041989">User Agent</translation>
<translation id="6915804003454593391">Utilizator:</translation>
+<translation id="6945221475159498467">Selectează</translation>
<translation id="6948701128805548767">Pentru a vedea metodele de preluare și cerințele, selectează o adresă</translation>
<translation id="6957887021205513506">Certificatul serverului pare a fi un fals.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Sunt specificate atât servere proxy fixe, cât și o adresă URL pentru scripturi .pac.</translation>
<translation id="6989763994942163495">Afișează setările avansate...</translation>
<translation id="7000990526846637657">Nu s-au găsit intrări în istoric</translation>
-<translation id="7009986207543992532">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat a cărui perioadă de valabilitate este prea mare pentru a fi de încredere. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Contul Google poate să ofere alte forme ale istoricului de navigare la <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Parole</translation>
+<translation id="7050187094878475250">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat a cărui perioadă de validitate este prea lungă pentru a fi de încredere.</translation>
+<translation id="7053983685419859001">Blochează</translation>
<translation id="7064851114919012435">Informații de contact</translation>
<translation id="7079718277001814089">Acest site conține programe malware</translation>
<translation id="7087282848513945231">Comitat</translation>
-<translation id="7088615885725309056">Mai vechi</translation>
<translation id="7090678807593890770">Caută <ph name="LINK" /> pe Google</translation>
+<translation id="7108819624672055576">Permisă de o extensie</translation>
<translation id="7119414471315195487">închide celelalte file sau programe;</translation>
<translation id="7129409597930077180">Nu se poate expedia la această adresă. Selectează altă adresă.</translation>
<translation id="7138472120740807366">Metodă de livrare</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Se procesează</translation>
<translation id="724691107663265825">Site-ul pe care urmează să îl accesezi conține programe malware</translation>
<translation id="724975217298816891">Introdu data de expirare și codul CVC pentru <ph name="CREDIT_CARD" />, pentru a actualiza detaliile cardului. După ce confirmi, acest site va avea acces la detaliile cardului tău.</translation>
-<translation id="725866823122871198">O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora computerului (<ph name="DATE_AND_TIME" />) sunt incorecte.</translation>
+<translation id="7260504762447901703">Revocă accesul</translation>
<translation id="7275334191706090484">Marcaje gestionate</translation>
<translation id="7298195798382681320">Recomandate</translation>
<translation id="7309308571273880165">Raportul de blocare creat <ph name="CRASH_TIME" /> (utilizatorul a solicitat încărcarea, dar nu a fost încărcat încă)</translation>
<translation id="7334320624316649418">&amp;Repetați reordonarea</translation>
<translation id="733923710415886693">Certificatul serverului nu a fost dezvăluit folosind Transparența certificatului.</translation>
-<translation id="7351800657706554155">Momentan, nu poți accesa site-ul <ph name="SITE" />, deoarece certificatul acestuia a fost revocat. Erorile de rețea și atacurile sunt de obicei temporare și probabil că această pagină va funcționa mai târziu. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Linie de comandă</translation>
<translation id="7372973238305370288">rezultat al căutării</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nu</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Confirmă cardul</translation>
-<translation id="7394102162464064926">Sigur doriți să ștergeți aceste pagini din istoric?
-
-Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a naviga în modul incognito.</translation>
<translation id="7400418766976504921">Adresă URL</translation>
<translation id="7419106976560586862">Calea profilului</translation>
<translation id="7424977062513257142">O pagină încorporată de pe această pagină web afișează mesajul:</translation>
@@ -688,6 +754,7 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="7444046173054089907">Acest site este blocat</translation>
<translation id="7445762425076701745">Identitatea serverului la care te-ai conectat nu poate fi validată complet. Ești conectat(ă) la un server folosind un nume valid numai în rețeaua ta, pentru care o autoritate de certificare externă nu are nici o modalitate de a-l valida. Deoarece unele autorități de certificare vor emite certificate pentru aceste nume oricum, nu există nicio modalitate de a te asigura că ești conectat(ă) la site-ul corect și nu la un atacator.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />să afli mai multe<ph name="END_LINK" /> despre această problemă.</translation>
+<translation id="7455133967321480974">Utilizați setarea prestabilită la nivel global (Blocați)</translation>
<translation id="7460163899615895653">Filele recente de pe alte dispozitive sunt afișate aici</translation>
<translation id="7469372306589899959">Se confirmă cardul</translation>
<translation id="7481312909269577407">ÃŽnainte</translation>
@@ -695,36 +762,43 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="7508255263130623398">ID-ul de dispozitiv returnat pentru politică este gol sau nu corespunde cu ID-ul de dispozitiv actual</translation>
<translation id="7514365320538308">Descarcă</translation>
<translation id="7518003948725431193">Nu a fost găsită nicio pagină web pentru adresa: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Valoare</translation>
<translation id="7537536606612762813">Obligatorie</translation>
+<translation id="7542403920425041731">După ce confirmi, acest site va avea acces la detaliile cardului tău.</translation>
<translation id="7542995811387359312">Completarea automată a cardului de credit este dezactivată, deoarece acest formular nu utilizează o conexiune sigură.</translation>
<translation id="7543525346216957623">Roagă-ți părintele</translation>
<translation id="7549584377607005141">Pentru a fi afișată corespunzător, această pagină web necesită date pe care le-ați introdus anterior. Puteți trimite aceste date din nou, dar astfel veți repeta orice acțiuni realizate anterior de această pagină.</translation>
<translation id="7552846755917812628">Încearcă următoarele sfaturi:</translation>
<translation id="7554791636758816595">Filă nouă</translation>
+<translation id="7567204685887185387">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; este posibil ca certificatul său de securitate să fi fost emis fraudulos. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Această pagină este în <ph name="ORIGINAL_LANGUAGE" /> Vrei să fie tradusă?</translation>
<translation id="7569952961197462199">Elimini cardul de credit din Chrome?</translation>
<translation id="7569983096843329377">Negru</translation>
<translation id="7578104083680115302">Plătește rapid pe site-uri și în aplicații pe diferite dispozitive folosind cardurile pe care le-ai salvat pe Google.</translation>
<translation id="7588950540487816470">Web material</translation>
<translation id="7592362899630581445">Certificatul serverului încalcă limitările privind numele.</translation>
+<translation id="7598391785903975535">Mai puțin de <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Momentan, <ph name="HOST_NAME" /> nu poate procesa această solicitare.</translation>
<translation id="7600965453749440009">Nu traduce niciodată din <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Valoarea este în afara intervalului <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Expiră pe: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Aveți deja date criptate utilizând o versiune diferită a parolei pentru Contul dvs. Google. Introduceți-o mai jos.</translation>
-<translation id="7634554953375732414">Conexiunea la acest site nu este privată.</translation>
<translation id="7637571805876720304">Elimini cardul de credit din Chromium?</translation>
<translation id="765676359832457558">Ascundeți setările avansate...</translation>
<translation id="7658239707568436148">Anulează</translation>
+<translation id="7662298039739062396">Setare controlată de o extensie</translation>
<translation id="7667346355482952095">Indicativul returnat pentru politică este gol sau nu corespunde cu indicativul actual</translation>
<translation id="7668654391829183341">Dispozitiv necunoscut</translation>
<translation id="7669271284792375604">Atacatorii de pe acest site pot încerca să te înșele pentru a instala programe care dăunează experienței de navigare (de exemplu, schimbând pagina de pornire sau afișând anunțuri suplimentare pe site-urile pe care le accesezi).</translation>
<translation id="7674629440242451245">Doriți să utilizați funcții Chrome noi și interesante? Încercați canalul nostru pentru dezvoltatori, de la chrome.com/dev.</translation>
<translation id="7682287625158474539">Expediere</translation>
+<translation id="7701040980221191251">Niciuna</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Accesați <ph name="SITE" /> (nesigur)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certificat</translation>
+<translation id="7716147886133743102">Blocată de administrator</translation>
<translation id="7716424297397655342">Acest site nu poate fi încărcat din memoria cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Negestionat</translation>
<translation id="7755287808199759310">Părintele tău îl poate debloca pentru tine</translation>
<translation id="7758069387465995638">Este posibil ca firewallul sau software-ul antivirus să fi blocat conexiunea.</translation>
@@ -751,15 +825,15 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="7951415247503192394">(32 de biți)</translation>
<translation id="7956713633345437162">Marcaje mobile</translation>
<translation id="7961015016161918242">Niciodată</translation>
-<translation id="7962083544045318153">ID blocare <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Tradu întotdeauna din <ph name="ORIGINAL_LANGUAGE" /> în <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Nespecificată</translation>
<translation id="800218591365569300">Încearcă să închizi celelalte file sau programe pentru a elibera memoria.</translation>
<translation id="8012647001091218357">Momentan, nu ți-am putut contacta părinții. Încearcă din nou.</translation>
<translation id="8025119109950072390">Atacatorii de pe acest site te pot înșela, determinându-te să faci ceva periculos, cum ar fi să instalezi software sau să îți dezvălui informațiile cu caracter personal (de exemplu, parole, numere de telefon sau carduri de credit).</translation>
-<translation id="803030522067524905">Recent, Navigarea sigură Google a detectat phishing pe <ph name="SITE" />. Site-urile de phishing falsifică alte site-uri, pentru a te înșela. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Această pagină este în <ph name="SOURCE_LANGUAGE" />. Doriți traducere în <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Solicită (în mod prestabilit)</translation>
<translation id="8041089156583427627">Trimiteți feedback</translation>
+<translation id="8041940743680923270">Utilizați setarea prestabilită la nivel global (Întrebați)</translation>
<translation id="8088680233425245692">Articolul nu a fost vizualizat.</translation>
<translation id="8089520772729574115">mai puțin de 1 MB</translation>
<translation id="8091372947890762290">Se așteaptă activarea pe server</translation>
@@ -768,13 +842,14 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />Adresa DNS<ph name="END_ABBR" /> pentru serverul <ph name="HOST_NAME" /> nu a putut fi găsită.</translation>
<translation id="8149426793427495338">Computerul este inactiv.</translation>
<translation id="8150722005171944719">Fișierul de la <ph name="URL" /> nu poate fi citit. Este posibil să fi fost eliminat ori mutat sau ca permisiunile pentru fișiere să împiedice accesarea acestuia.</translation>
+<translation id="8184538546369750125">Utilizați setarea prestabilită la nivel global (Permiteți)</translation>
+<translation id="8191494405820426728">ID blocare locală: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Anulați mutarea</translation>
<translation id="8201077131113104583">Adresa URL pentru actualizarea extensiei cu ID-ul „<ph name="EXTENSION_ID" />†nu este validă.</translation>
<translation id="8202097416529803614">Rezumatul comenzii</translation>
<translation id="8218327578424803826">Locație atribuită:</translation>
<translation id="8225771182978767009">Persoana care a configurat computerul a ales să blocheze acest site.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pot încerca să instaleze programe periculoase pe computerul tău, care să îți fure sau să îți șteargă informațiile (de exemplu, fotografiile, parolele, mesajele sau informațiile despre cardurile de credit).</translation>
<translation id="8241707690549784388">Pagina pe care o cauți a utilizat informațiile pe care le-ai introdus. Întoarcerea la acea pagină ar putea face ca orice acțiune să fie repetată. Vrei să continui?</translation>
<translation id="8249320324621329438">Ultima preluare:</translation>
<translation id="8253091569723639551">Adresa de facturare este obligatorie</translation>
@@ -782,6 +857,7 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="8289355894181816810">Dacă nu știți sigur ce înseamnă aceasta, contactați administratorul de rețea.</translation>
<translation id="8293206222192510085">Adăugați marcaj</translation>
<translation id="8294431847097064396">Sursă</translation>
+<translation id="8306404619377842860">O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora dispozitivului (<ph name="DATE_AND_TIME" />) sunt incorecte. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Traducerea nu a reușit din cauza unei probleme cu conexiunea la rețea.</translation>
<translation id="8332188693563227489">Accesul la <ph name="HOST_NAME" /> nu este permis</translation>
<translation id="834457929814110454">Dacă îți asumi riscurile de securitate, poți să <ph name="BEGIN_LINK" />accesezi acest site<ph name="END_LINK" /> înainte ca programele periculoase să fie eliminate.</translation>
@@ -802,11 +878,9 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="8483780878231876732">Pentru a folosi cardurile din Contul Google, conectează-te la Chrome</translation>
<translation id="8488350697529856933">Se aplică pentru</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> a răspuns prea târziu.</translation>
-<translation id="852346902619691059">Acest server nu a putut dovedi că este <ph name="DOMAIN" />. Sistemul de operare al dispozitivului nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o eroare de configurare sau interceptarea conexiunii de către un atacator. <ph name="BEGIN_LEARN_MORE_LINK" />Află mai multe<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">An expirare</translation>
<translation id="8543181531796978784">Poți să <ph name="BEGIN_ERROR_LINK" />raportezi o problemă privind detectarea<ph name="END_ERROR_LINK" /> sau, dacă îți asumi riscurile de securitate, poți să <ph name="BEGIN_LINK" />accesezi acest site nesigur<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Traducerea nu a reușit, deoarece nu a putut fi stabilită limba paginii.</translation>
-<translation id="8559762987265718583">O conexiune privată la <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> nu poate fi stabilită, deoarece data și ora dispozitivului (<ph name="DATE_AND_TIME" />) sunt incorecte.</translation>
<translation id="8571890674111243710">Se traduce pagina în <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Adăugați telefon
</translation>
@@ -821,6 +895,7 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="8738058698779197622">Pentru a stabili o conexiune securizată, ceasul trebuie să fie setat corect. Aceasta deoarece certificatele pe care site-urile le folosesc pentru a se identifica sunt valabile numai pentru anumite intervale de timp. Din moment ce ora de pe dispozitiv este incorectă, Chromium nu poate verifica aceste certificate.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;Adresa DNS&lt;/abbr&gt; pentru <ph name="HOST_NAME" /> nu a putut fi găsită. Se diagnostichează problema.</translation>
<translation id="8759274551635299824">Acest card este expirat</translation>
+<translation id="8761567432415473239">Recent, Navigarea sigură Google a <ph name="BEGIN_LINK" />descoperit programe dăunătoare<ph name="END_LINK" /> pe <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Repetați ștergerea</translation>
<translation id="8800988563907321413">Sugestiile pentru În apropiere sunt afișate aici</translation>
<translation id="8820817407110198400">Marcaje</translation>
@@ -833,29 +908,30 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="8870413625673593573">ÃŽnchise recent</translation>
<translation id="8874824191258364635">Introdu un număr de card valid</translation>
<translation id="8876793034577346603">Configurația rețelei nu a putut fi analizată.</translation>
-<translation id="8877192140621905067">După ce confirmi, acest site va avea acces la detaliile cardului tău</translation>
<translation id="8889402386540077796">Nuanță</translation>
<translation id="8891727572606052622">Mod proxy nevalid.</translation>
<translation id="889901481107108152">Ne pare rău, acest experiment nu este disponibil pe platforma dvs.</translation>
<translation id="8903921497873541725">Mărește</translation>
<translation id="8931333241327730545">Dorești să salvezi acest card în Contul Google?</translation>
<translation id="8932102934695377596">Ora este setată în trecut</translation>
-<translation id="8954894007019320973">(Continuare)</translation>
<translation id="8971063699422889582">Certificatul serverului a expirat.</translation>
<translation id="8986494364107987395">Trimite automat la Google statistici de utilizare și rapoarte de blocare</translation>
-<translation id="8987927404178983737">Lună</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Site-ul pe care urmează să îl accesezi conține programe dăunătoare</translation>
+<translation id="8997023839087525404">Serverul a prezentat un certificat care nu a fost dezvăluit public folosind politica privind Transparența certificatului. Aceasta este o cerință pentru anumite certificate, pentru a se asigura că sunt de încredere și pentru protecție împotriva atacatorilor.</translation>
<translation id="9001074447101275817">Pentru a accesa proxy-ul <ph name="DOMAIN" />, trebuie să introduci un nume de utilizator și o parolă.</translation>
+<translation id="9005998258318286617">Documentul PDF nu a fost încărcat.</translation>
<translation id="901974403500617787">Marcajele care se aplică la nivel de sistem pot fi create numai de proprietar: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Este necesară adresa de facturare a cardului</translation>
<translation id="9020542370529661692">Această pagină a fost tradusă în <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Eroare de securitate</translation>
<translation id="9038649477754266430">Folosește un serviciu de predicții pentru a încărca paginile mai rapid</translation>
<translation id="9039213469156557790">În plus, această pagină include alte resurse care nu sunt securizate. Aceste resurse sunt vizibile pentru alți utilizatori în cursul transferului și pot fi modificate de un atacator pentru a schimba comportamentul paginii.</translation>
-<translation id="9040185888511745258">Atacatorii de pe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> pot încerca să te înșele pentru a instala programe care dăunează experienței de navigare (de exemplu, schimbând pagina de pornire sau afișând anunțuri suplimentare pe site-urile pe care le accesezi).</translation>
+<translation id="9049981332609050619">Ai încercat să accesezi <ph name="DOMAIN" />, dar serverul a prezentat un certificat nevalid.</translation>
<translation id="9050666287014529139">Expresie de acces</translation>
<translation id="9065203028668620118">Editează</translation>
<translation id="9068849894565669697">Selectați culoarea</translation>
+<translation id="9069693763241529744">Blocată de o extensie</translation>
<translation id="9076283476770535406">Poate include conținut destinat adulților</translation>
<translation id="9078964945751709336">Sunt necesare mai multe informații</translation>
<translation id="9103872766612412690">Site-ul <ph name="SITE" /> folosește în mod obișnuit criptarea pentru a-ți proteja informațiile. Când Chromium a încercat să se conecteze la <ph name="SITE" /> de această dată, site-ul a returnat date de conectare neobișnuite și incorecte. Acest lucru s-a întâmplat fie pentru că un atacator încearcă să falsifice site-ul <ph name="SITE" />, fie pentru că un ecran de conectare Wi-Fi a întrerupt conexiunea. Securitatea informațiilor tale nu a fost afectată, deoarece Chromium a oprit conexiunea înainte ca datele să fie transferate.</translation>
@@ -864,16 +940,21 @@ Data viitoare ați putea utiliza combinația <ph name="SHORTCUT_KEY" /> pentru a
<translation id="9148507642005240123">&amp;Anulați editarea</translation>
<translation id="9154194610265714752">Actualizat</translation>
<translation id="9157595877708044936">Se configurează...</translation>
+<translation id="9169664750068251925">Blocați întotdeauna pe acest site</translation>
<translation id="9170848237812810038">&amp;Anulează</translation>
<translation id="917450738466192189">Certificatul serverului nu este valid.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> și încă <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> folosește un protocol neacceptat.</translation>
<translation id="9205078245616868884">Datele sunt criptate cu expresia de acces pentru sincronizare. Introdu-o pentru a începe sincronizarea.</translation>
<translation id="9207861905230894330">Articolul nu a fost adăugat.</translation>
+<translation id="9219103736887031265">Imagini</translation>
<translation id="933612690413056017">Nu există conexiune la internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">GOLEȘTE FORMULARUL</translation>
<translation id="939736085109172342">Dosar nou</translation>
<translation id="941721044073577244">Se pare că nu ai permisiunea de a accesa acest site</translation>
<translation id="969892804517981540">Versiune oficială</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Niciunul}=1{1 element}few{# elemente}other{# de elemente}}</translation>
<translation id="988159990683914416">Versiune de programare</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ru.xtb b/chromium/components/strings/components_strings_ru.xtb
index 8afc29de8fb..b3d76ceff36 100644
--- a/chromium/components/strings/components_strings_ru.xtb
+++ b/chromium/components/strings/components_strings_ru.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Повернуть по чаÑовой Ñтрелке</translation>
<translation id="1038842779957582377">неизвеÑтное имÑ</translation>
<translation id="1050038467049342496">Закройте другие приложениÑ.</translation>
-<translation id="1053591932240354961">Веб-Ñайт <ph name="SITE" /> отправлÑет Chrome некорректные идентификационные данные, поÑтому открыть его в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ»ÑŒÐ·Ñ. Сбой мог быть вызван Ñетевой ошибкой или дейÑтвиÑми злоумышленников. Скорее вÑего, Ñайт заработает через некоторое времÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;Отменить добавление</translation>
<translation id="10614374240317010">Сайты, пароли Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… не ÑохранÑÑŽÑ‚ÑÑ</translation>
<translation id="106701514854093668">Закладки на компьютере</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">В кеше политики ошибок не найдено</translation>
<translation id="113188000913989374">Подтвердите дейÑтвие на <ph name="SITE" />:</translation>
<translation id="1132774398110320017">ÐаÑтройки Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² Chrome...</translation>
+<translation id="1150979032973867961">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема компьютера не доверÑет его Ñертификату безопаÑноÑти. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
+<translation id="1151972924205500581">Ðеобходимо ввеÑти пароль</translation>
<translation id="1152921474424827756">Открыть <ph name="BEGIN_LINK" />кешированную верÑию<ph name="END_LINK" /> Ñтраницы <ph name="URL" /></translation>
<translation id="1158211211994409885">Сайт <ph name="HOST_NAME" /> неожиданно разорвал Ñоединение.</translation>
<translation id="1161325031994447685">ПодключитеÑÑŒ к Ñети Wi-Fi ещё раз.</translation>
+<translation id="1165039591588034296">Ошибка</translation>
<translation id="1175364870820465910">&amp;Печать...</translation>
<translation id="1181037720776840403">Удалить</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />ÐвтоматичеÑки отправлÑÑ‚ÑŒ в Google<ph name="END_WHITEPAPER_LINK" /> информацию о возможных проблемах безопаÑноÑти. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Другие запиÑи по Ñтому Ñайту</translation>
<translation id="1206967143813997005">ÐÐ°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ недейÑтвительна</translation>
<translation id="1209206284964581585">Скрыть</translation>
+<translation id="121201262018556460">Ð’Ñ‹ попыталиÑÑŒ перейти на Ñайт <ph name="DOMAIN" />, но Ñервер предоÑтавил Ñертификат Ñ Ð½ÐµÐ½Ð°Ð´ÐµÐ¶Ð½Ñ‹Ð¼ ключом. Возможно, чаÑтный ключ был взломан злоумышленником, а Ñервер выдает ÑÐµÐ±Ñ Ð·Ð° другой (вероÑтно, Ñто атака).</translation>
<translation id="1219129156119358924">БезопаÑноÑÑ‚ÑŒ ÑиÑтемы</translation>
<translation id="1227224963052638717">ÐеизвеÑтное правило.</translation>
<translation id="1227633850867390598">Скрыть значение</translation>
<translation id="1228893227497259893">Ðеверный идентификатор объекта</translation>
<translation id="1232569758102978740">Без имени</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (данные ÑинхронизируютÑÑ)</translation>
<translation id="1263231323834454256">СпиÑок Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" />: получен отчет о Ñбое (ещё не загружен или не отклонен)</translation>
+<translation id="1281526147609854549">Выдан <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">ОпаÑный контент заблокирован</translation>
<translation id="1285320974508926690">Ðикогда не переводить Ñтот Ñайт</translation>
<translation id="129553762522093515">Ðедавно закрытые</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Удалите файлы cookie<ph name="END_LINK" />.</translation>
+<translation id="1333989956347591814">Ваши дейÑÑ‚Ð²Ð¸Ñ <ph name="BEGIN_EMPHASIS" />будут видны<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Ñайтам, которые вы поÑещаете;
+ <ph name="LIST_ITEM" />вашему ÑиÑтемному админиÑтратору;
+ <ph name="LIST_ITEM" />интернет-провайдеру.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð´Ð¾Ð¼ÐµÐ½Ð°:</translation>
<translation id="1340482604681802745">ÐÐ´Ñ€ÐµÑ Ð²Ñ‹Ð´Ð°Ñ‡Ð¸</translation>
<translation id="1344211575059133124">Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтой Ñтранице требуетÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ</translation>
<translation id="1344588688991793829">ÐаÑтройки Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² Chromium...</translation>
+<translation id="1348198688976932919">Сайт Ñодержит опаÑные приложениÑ</translation>
<translation id="1374468813861204354">подÑказки</translation>
<translation id="1375198122581997741">Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ верÑии</translation>
<translation id="1377321085342047638">Ðомер карты</translation>
<translation id="139305205187523129">Сайт <ph name="HOST_NAME" /> не отправил данных.</translation>
<translation id="1407135791313364759">Открыть вÑе</translation>
<translation id="1413809658975081374">Ошибка Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð´ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾Ñти</translation>
+<translation id="14171126816530869">Идентификационные данные <ph name="ORGANIZATION" /> в <ph name="LOCALITY" /> проверены <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Да</translation>
<translation id="1430915738399379752">Печать</translation>
-<translation id="1442912890475371290">Заблокирована попытка <ph name="BEGIN_LINK" />перехода на Ñтраницу<ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Веб-Ñайт <ph name="SITE" /> иÑпользует механизм Certificate Pinning, поÑтому на нем могла произойти подмена Ñертификата. Открыть Ñайт в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ»ÑŒÐ·Ñ. Сбой мог быть вызван Ñетевой ошибкой или дейÑтвиÑми злоумышленников. Скорее вÑего, Ñайт заработает через некоторое времÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}many{<ph name="PAYMENT_METHOD_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Показывает предыдущую Ñохраненную копию Ñтой Ñтраницы.</translation>
<translation id="1517433312004943670">Укажите номер телефона</translation>
<translation id="1519264250979466059">Дата Ñборки</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Ð”Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтой функции необходимо включить JavaScript.</translation>
<translation id="1555130319947370107">Синий</translation>
<translation id="1559528461873125649">Данный файл или каталог не ÑущеÑтвует</translation>
-<translation id="1559572115229829303">&lt;p&gt;Ðе удалоÑÑŒ уÑтановить защищенное Ñоединение Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных наÑтроек ÑиÑтемных чаÑов и ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
-
- &lt;p&gt;УÑтановите точную дату и времÑ. Ð”Ð»Ñ Ñтого откройте раздел &lt;strong&gt;Общие&lt;/strong&gt; в приложении &lt;strong&gt;ÐаÑтройки&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">При загрузке Ñтой Ñтраницы возникли неполадки.</translation>
<translation id="1592005682883173041">ДоÑтуп к данным на уÑтройÑтве</translation>
+<translation id="1594030484168838125">Выбрать</translation>
<translation id="161042844686301425">Голубой</translation>
+<translation id="1620510694547887537">Камера</translation>
<translation id="1629803312968146339">Сохранить Ñту карту в Chrome?</translation>
<translation id="1639239467298939599">Загрузка</translation>
<translation id="1640180200866533862">ПользовательÑкие правила</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Импорт невозможен: недопуÑÑ‚Ð¸Ð¼Ð°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñети.</translation>
<translation id="1644574205037202324">ИÑториÑ</translation>
<translation id="1645368109819982629">Ðеподдерживаемый протокол</translation>
+<translation id="1655462015569774233">{1,plural, =1{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек вчера. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные. Обратите внимание, что на компьютере уÑтановлено Ð²Ñ€ÐµÐ¼Ñ <ph name="CURRENT_DATE" />. ЕÑли оно неправильное, измените его и обновите Ñтраницу.}one{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек # день назад. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные. Обратите внимание, что на компьютере уÑтановлено Ð²Ñ€ÐµÐ¼Ñ <ph name="CURRENT_DATE" />. ЕÑли оно неправильное, измените его и обновите Ñтраницу.}few{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек #Â Ð´Ð½Ñ Ð½Ð°Ð·Ð°Ð´. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные. Обратите внимание, что на компьютере уÑтановлено Ð²Ñ€ÐµÐ¼Ñ <ph name="CURRENT_DATE" />. ЕÑли оно неправильное, измените его и обновите Ñтраницу.}many{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек # дней назад. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные. Обратите внимание, что на компьютере уÑтановлено Ð²Ñ€ÐµÐ¼Ñ <ph name="CURRENT_DATE" />. ЕÑли оно неправильное, измените его и обновите Ñтраницу.}other{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек #Â Ð´Ð½Ñ Ð½Ð°Ð·Ð°Ð´. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные. Обратите внимание, что на компьютере уÑтановлено Ð²Ñ€ÐµÐ¼Ñ <ph name="CURRENT_DATE" />. ЕÑли оно неправильное, измените его и обновите Ñтраницу.}}</translation>
<translation id="1656489000284462475">Получение</translation>
<translation id="1663943134801823270">Карты и адреÑа, указанные в Chrome. Ð’Ñ‹ можете изменить их на Ñтранице <ph name="BEGIN_LINK" />ÐаÑтройки<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Ðа Ñайте <ph name="SITE" /> Ð´Ð»Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ ваших данных обычно иÑпользуетÑÑ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ. Однако учетные данные, которые мы получили от Ñайта <ph name="SITE" /> ÑейчаÑ, отличаютÑÑ Ð¾Ñ‚ тех, которые он отправлÑет обычно. ВероÑтно, вредоноÑный Ñайт пытаетÑÑ Ð²Ñ‹Ð´Ð°Ñ‚ÑŒ ÑÐµÐ±Ñ Ð·Ð° <ph name="SITE" />, либо Ñтраница Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñети Wi-Fi прервала Ñоединение. Ваша Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾-прежнему в безопаÑноÑти, так как браузер Google Chrome разорвал Ñоединение до того, как произошел обмен данными.</translation>
-<translation id="168328519870909584">Через Ñайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> на ваш компьютер могут уÑтановить вредоноÑное ПО Ð´Ð»Ñ ÐºÑ€Ð°Ð¶Ð¸ или ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð»Ð¸Ñ‡Ð½Ð¾Ð¹ информации (например, фотографий, паролей, Ñообщений и реквизитов банковÑких карт).</translation>
<translation id="168841957122794586">Сертификат Ñервера Ñодержит ненадежный криптографичеÑкий ключ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу завтра. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.}one{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу через # день. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.}few{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу через # днÑ. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.}many{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу через # дней. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.}other{Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу через # днÑ. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.}}</translation>
<translation id="1710259589646384581">ОС</translation>
<translation id="1721312023322545264">Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтой Ñтранице требуетÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ <ph name="NAME" /></translation>
<translation id="1721424275792716183">*ОбÑзательное поле</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Скачать позже</translation>
<translation id="17513872634828108">Открытые вкладки</translation>
<translation id="1753706481035618306">Ðомер Ñтраницы</translation>
+<translation id="1763864636252898013">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема уÑтройÑтва не доверÑет его Ñертификату безопаÑноÑти. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Выполните диагноÑтику Ñети в Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Обновите кодовую фразу Ð´Ð»Ñ Ñинхронизации.</translation>
<translation id="1787142507584202372">ЗдеÑÑŒ поÑвÑÑ‚ÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ðµ вкладки.</translation>
+<translation id="1789575671122666129">Ð’Ñплывающие окна</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Владелец карты</translation>
-<translation id="1803678881841855883">СиÑтема Google по проверке безопаÑноÑти недавно обнаружила на Ñайте <ph name="SITE" /> <ph name="BEGIN_LINK" />вредоноÑное ПО<ph name="END_LINK" />. Его иÑточник, <ph name="SUBRESOURCE_HOST" />, не раз замечен в раÑпроÑтранении вируÑов. Будьте внимательны: иногда даже на надежных Ñайтах поÑвлÑÑŽÑ‚ÑÑ Ð²Ð¸Ñ€ÑƒÑÑ‹. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Добавлена <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">ÐедопуÑтимый Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð»Ð¸ неверные параметры запроÑа</translation>
<translation id="1826516787628120939">Проверка</translation>
<translation id="1834321415901700177">Сайт Ñодержит вредоноÑное ПО</translation>
+<translation id="1840414022444569775">Карта Ñ Ñ‚Ð°ÐºÐ¸Ð¼ номером уже иÑпользуетÑÑ</translation>
<translation id="1842969606798536927">Оплатить</translation>
<translation id="1871208020102129563">Выбрано иÑпользование фикÑированных прокÑи-Ñерверов, а не URL PAC-Ñкрипта.</translation>
<translation id="1871284979644508959">Поле, обÑзательное Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ</translation>
<translation id="187918866476621466">Открыть Ñтартовые Ñтраницы</translation>
<translation id="1883255238294161206">Свернуть ÑпиÑок</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Фильтры</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ðет}=1{1 Ñайт}one{# Ñайт}few{# Ñайта}many{# Ñайтов}other{# Ñайта}}</translation>
<translation id="194030505837763158">Перейдите по ÑÑылке: <ph name="LINK" /></translation>
<translation id="1962204205936693436">Закладки <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Ðе удалоÑÑŒ выполнить Ñериализацию</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">ИгнорируетÑÑ, так как правило <ph name="POLICY_NAME" /> имеет приоритет.</translation>
<translation id="2138201775715568214">ПоиÑк веб-Ñтраниц…</translation>
<translation id="213826338245044447">Закладки на мобильном</translation>
-<translation id="2148716181193084225">СегоднÑ</translation>
+<translation id="2147827593068025794">Ð¤Ð¾Ð½Ð¾Ð²Ð°Ñ ÑинхронизациÑ</translation>
<translation id="2154054054215849342">Ð’ вашем домене ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½ÐµÐ´Ð¾Ñтупна</translation>
<translation id="2154484045852737596">Изменение данных карты</translation>
<translation id="2166049586286450108">ДоÑтуп админиÑтратора ко вÑем данным</translation>
<translation id="2166378884831602661">Этот Ñайт не может обеÑпечить безопаÑное Ñоединение</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адреÑ}one{# адреÑ}few{# адреÑа}many{# адреÑов}other{# адреÑа}}</translation>
+<translation id="2187317261103489799">ОпределÑÑ‚ÑŒ (по умолчанию)</translation>
<translation id="2202020181578195191">ÐедопуÑтимый формат года.</translation>
<translation id="2212735316055980242">Политика Ð´Ð»Ñ ÑƒÑтройÑтва не найдена</translation>
<translation id="2213606439339815911">Извлечение запиÑей…</translation>
+<translation id="2218879909401188352">Злоумышленники могут иÑпользовать Ñайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, чтобы уÑтановить опаÑные приложениÑ, которые причинÑÑŽÑ‚ вред уÑтройÑтвам, увеличивают раÑходы на мобильную ÑвÑзь и крадут личные данные. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Чтобы уÑтранить неполадки, проведите <ph name="BEGIN_LINK" />диагноÑтику<ph name="END_LINK" /> подключениÑ.</translation>
<translation id="2239100178324503013">Отправить</translation>
<translation id="225207911366869382">Это значение Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ правила больше не иÑпользуетÑÑ.</translation>
<translation id="2262243747453050782">Ошибка HTTP</translation>
+<translation id="2270484714375784793">Ðомер телефона</translation>
<translation id="2282872951544483773">ÐедоÑтупные раÑширениÑ</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> объект}one{<ph name="ITEM_COUNT" /> объект}few{<ph name="ITEM_COUNT" /> объекта}many{<ph name="ITEM_COUNT" /> объектов}other{<ph name="ITEM_COUNT" /> объекта}}</translation>
<translation id="2292556288342944218">ДоÑтуп в Интернет закрыт</translation>
<translation id="230155334948463882">Добавить карту?</translation>
-<translation id="2305919008529760154">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти мог быть выпущен мошенниками. Проблема также может быть ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535">Ð”Ð»Ñ Ð´Ð¾Ñтупа к домену <ph name="DOMAIN" /> необходимо указать Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль.</translation>
-<translation id="2318774815570432836">Соединение Ñ Ð²ÐµÐ±-Ñайтом <ph name="SITE" />, иÑпользующим механизм HSTS, могло быть Ñкомпрометировано, поÑтому его Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ в наÑтоÑщий момент. Проблема также может быть ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников. Скорее вÑего, Ñайт заработает через некоторое времÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Эта наÑтройка управлÑетÑÑ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором</translation>
<translation id="2354001756790975382">Другие закладки</translation>
+<translation id="2354430244986887761">СиÑтема БезопаÑного проÑмотра Google недавно <ph name="BEGIN_LINK" />обнаружила вредоноÑные приложениÑ<ph name="END_LINK" /> на Ñайте <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Злоумышленники могут видеть изображениÑ, которые видны вам, и изменÑÑ‚ÑŒ их в целÑÑ… мошенничеÑтва.</translation>
+<translation id="2356070529366658676">Спрашивать</translation>
+<translation id="2359629602545592467">ÐеÑколько</translation>
<translation id="2359808026110333948">Далее</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" />: получен отчет о Ñбое (не загружен)</translation>
<translation id="2367567093518048410">Уровень</translation>
-<translation id="2371153335857947666">{1,plural, =1{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек вчера. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. ЧаÑÑ‹ на вашем компьютере уÑтановлены на <ph name="CURRENT_DATE" />. ЕÑли Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ðµ, измените его и обновите Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}one{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек # день назад. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. ЧаÑÑ‹ на вашем компьютере уÑтановлены на <ph name="CURRENT_DATE" />. ЕÑли Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ðµ, измените его и обновите Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}few{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек #Â Ð´Ð½Ñ Ð½Ð°Ð·Ð°Ð´. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. ЧаÑÑ‹ на вашем компьютере уÑтановлены на <ph name="CURRENT_DATE" />. ЕÑли Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ðµ, измените его и обновите Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}many{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек # дней назад. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. ЧаÑÑ‹ на вашем компьютере уÑтановлены на <ph name="CURRENT_DATE" />. ЕÑли Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ðµ, измените его и обновите Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}other{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="DOMAIN" />. Срок дейÑÑ‚Ð²Ð¸Ñ ÐµÐ³Ð¾ Ñертификата безопаÑноÑти иÑтек #Â Ð´Ð½Ñ Ð½Ð°Ð·Ð°Ð´. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. ЧаÑÑ‹ на вашем компьютере уÑтановлены на <ph name="CURRENT_DATE" />. ЕÑли Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ðµ, измените его и обновите Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">Ðичего не найдено</translation>
<translation id="2384307209577226199">Ð”Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸Ñтий (по умолчанию)</translation>
<translation id="2386255080630008482">Сертификат Ñервера отозван.</translation>
<translation id="2392959068659972793">Показывать правила, Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… не заданы</translation>
<translation id="239429038616798445">Этот ÑпоÑоб доÑтавки недоÑтупен. Выберите другой.</translation>
<translation id="2396249848217231973">&amp;Отменить удаление</translation>
-<translation id="2460160116472764928">СиÑтема Google по проверке безопаÑноÑти недавно обнаружила на Ñайте <ph name="SITE" /> <ph name="BEGIN_LINK" />вредоноÑное ПО<ph name="END_LINK" />. Будьте внимательны: иногда даже на надежных Ñайтах поÑвлÑÑŽÑ‚ÑÑ Ð²Ð¸Ñ€ÑƒÑÑ‹. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти может быть отозван. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
<translation id="2463739503403862330">Заполнить</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Выполните диагноÑтику Ñети<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">ÐедейÑтвительный URL поиÑковой ÑиÑтемы.</translation>
+<translation id="2482878487686419369">ОповещениÑ</translation>
<translation id="2491120439723279231">Сертификат Ñервера Ñодержит ошибки.</translation>
<translation id="2495083838625180221">СинтакÑичеÑкий анализатор JSON</translation>
<translation id="2495093607237746763">ЕÑли флажок уÑтановлен, Chromium будет хранить на Ñтом уÑтройÑтве данные карты Ð´Ð»Ñ Ð±Ñ‹Ñтрого Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Ðазад</translation>
<translation id="2515629240566999685">Проверьте уровень Ñигнала Ñети.</translation>
<translation id="2516305470678292029">Варианты интерфейÑа</translation>
+<translation id="2539524384386349900">ОпределÑÑ‚ÑŒ</translation>
<translation id="255002559098805027">Сайт <ph name="HOST_NAME" /> отправил недейÑтвительный ответ.</translation>
-<translation id="2552545117464357659">Позже</translation>
<translation id="2556876185419854533">&amp;Отменить изменениÑ</translation>
<translation id="2587730715158995865">ИÑточник: <ph name="ARTICLE_PUBLISHER" />. ДоÑтупно ещё неÑколько Ñтатей (<ph name="OTHER_ARTICLE_COUNT" />).</translation>
<translation id="2587841377698384444">Идентификатор Directory API:</translation>
<translation id="2597378329261239068">Документ защищен паролем. Введите пароль.</translation>
<translation id="2609632851001447353">Варианты</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ðет}=1{1 приложение ($1)}=2{2Â Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1 и $2)}one{# приложение ($1, $2 $3)}few{#Â Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2 $3)}many{# приложений ($1, $2 $3)}other{#Â Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2 $3)}}</translation>
<translation id="2625385379895617796">ЧаÑÑ‹ Ñпешат</translation>
<translation id="2639739919103226564">СоÑтоÑние:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ДоÑтуп к файлу запрещен</translation>
<translation id="2653659639078652383">Отправить</translation>
<translation id="2666117266261740852">Закройте другие вкладки, раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð¸ приложениÑ.</translation>
+<translation id="2670429602441959756">Ðа Ñтой Ñтранице еÑÑ‚ÑŒ Ñлементы, которые пока не поддерживаютÑÑ Ð² VR. Выход из VR-режима…</translation>
<translation id="2674170444375937751">Удалить Ñти Ñтраницы из иÑтории поÑещений?</translation>
<translation id="2677748264148917807">Закрыть</translation>
-<translation id="269990154133806163">ПредоÑтавленный Ñервером Ñертификат не проходил проверку безопаÑноÑти. Ð’ некоторых ÑлучаÑÑ… она необходима, чтобы обеÑпечить надежноÑÑ‚ÑŒ Ñертификата и защиту от злоумышленников. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">СпиÑок Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ</translation>
<translation id="2704283930420550640">Значение не ÑоответÑтвует формату.</translation>
<translation id="2704951214193499422">Ðе удалоÑÑŒ подтвердить данные карты. Повторите попытку позже.</translation>
<translation id="2705137772291741111">Ðевозможно прочитать копию Ñайта, Ñохраненную в кеше.</translation>
<translation id="2709516037105925701">Ðвтозаполнение</translation>
-<translation id="2712118517637785082">Ð’Ñ‹ пытаетеÑÑŒ обратитьÑÑ Ðº Ñерверу в домене <ph name="DOMAIN" />, но его Ñертификат был отозван издателем. Это означает, что доверÑÑ‚ÑŒ информации Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ реÑурÑа нельзÑ. Возможно, вы имеете дело Ñо злоумышленниками. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">ПопроÑить разрешениÑ</translation>
<translation id="2713444072780614174">Белый</translation>
<translation id="2720342946869265578">Мое окружение</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">УÑтройÑтво не зарегиÑтрировано</translation>
<translation id="2784949926578158345">Соединение Ñброшено.</translation>
<translation id="2794233252405721443">Сайт заблокирован</translation>
+<translation id="2799020568854403057">Сайт Ñодержит вредоноÑные приложениÑ</translation>
+<translation id="2803306138276472711">СиÑтема Google по проверке безопаÑноÑти Ñайтов недавно обнаружила на <ph name="SITE" /> <ph name="BEGIN_LINK" />вредоноÑное ПО<ph name="END_LINK" />. Будьте внимательны, иногда даже на безопаÑных Ñайтах поÑвлÑÑŽÑ‚ÑÑ Ð²Ð¸Ñ€ÑƒÑÑ‹.</translation>
<translation id="2824775600643448204">ÐдреÑÐ½Ð°Ñ Ñтрока и Ñтрока поиÑка</translation>
<translation id="2826760142808435982">Соединение зашифровано и проверено Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ <ph name="CIPHER" />. Ð’ качеÑтве механизма обмена ключами иÑпользуетÑÑ <ph name="KX" />.</translation>
<translation id="2835170189407361413">ОчиÑтить форму</translation>
+<translation id="2856444702002559011">Злоумышленники могут пытатьÑÑ Ð¿Ð¾Ñ…Ð¸Ñ‚Ð¸Ñ‚ÑŒ ваши данные Ñ Ñайта <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (например, пароли, ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ номера банковÑких карт). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ðе обновлÑÑ‚ÑŒ</translation>
<translation id="2900469785430194048">Chrome не хватает памÑти Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° Ñтой Ñтраницы.</translation>
<translation id="2909946352844186028">Похоже, вы подключилиÑÑŒ к другой Ñети.</translation>
<translation id="2916038427272391327">Закройте другие программы.</translation>
<translation id="2922350208395188000">Ðе удаетÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚ÑŒ Ñертификат Ñервера.</translation>
<translation id="2928905813689894207">Платежный адреÑ</translation>
+<translation id="2941952326391522266">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти отноÑитÑÑ Ðº <ph name="DOMAIN2" />. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
<translation id="2948083400971632585">ПрокÑи-Ñерверы, иÑпользуемые Ð´Ð»Ñ ÑоединениÑ, можно отключить на Ñтранице наÑтроек.</translation>
<translation id="2955913368246107853">Закрыть панель поиÑка</translation>
<translation id="2958431318199492670">Ðекоторые Ñлементы Ñетевой конфигурации невозможно импортировать, поÑкольку она не ÑоответÑтвует Ñтандарту ONC.</translation>
-<translation id="29611076221683977">Сайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может уÑтановить на ваш компьютер Mac вредоноÑное ПО, которое крадет или удалÑет личную информацию (например, фотографии, пароли, ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ реквизиты банковÑких карт).</translation>
<translation id="2966678944701946121">Срок дейÑтвиÑ: <ph name="EXPIRATION_DATE_ABBR" />, добавлена <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°Ñного Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð¾, чтобы Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ð¸Ñ ÑиÑтемных чаÑов были верны. Причина в том, что Ñертификаты Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ñайтов имеют ограниченный Ñрок дейÑтвиÑ. ЕÑли чаÑÑ‹ на уÑтройÑтве неточны, Chrome не может проверить актуальноÑÑ‚ÑŒ Ñтих Ñертификатов.</translation>
<translation id="2972581237482394796">&amp;Повторить</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Укажите дейÑтвительный адреÑ.</translation>
<translation id="2986368408720340940">Этот ÑпоÑоб выдачи недоÑтупен. Выберите другой.</translation>
<translation id="2991174974383378012">ДоÑтуп веб-Ñайтов</translation>
+<translation id="2991571918955627853">Веб-Ñайт <ph name="SITE" /> иÑпользует механизм HSTS. Открыть Ñайт в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ»ÑŒÐ·Ñ. Сбой мог быть вызван Ñетевой ошибкой или дейÑтвиÑми злоумышленников. Скорее вÑего, Ñайт заработает через некоторое времÑ.</translation>
<translation id="3005723025932146533">Открыть Ñохраненную копию</translation>
<translation id="3008447029300691911">Введите CVC-код карты <ph name="CREDIT_CARD" />. ПоÑле Ñтого ее данные будут переданы Ñайту.</translation>
<translation id="3010559122411665027">Элемент ÑпиÑка "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Заблокировано автоматичеÑки</translation>
<translation id="3024663005179499861">Ðеверный тип политики</translation>
<translation id="3032412215588512954">Обновить Ñту Ñтраницу?</translation>
<translation id="3037605927509011580">Опаньки...</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{по меньшей мере 1 запиÑÑŒ на Ñинхронизируемых уÑтройÑтвах}=1{1 запиÑÑŒ (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}one{# запиÑÑŒ (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}few{# запиÑи (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}many{# запиÑей (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}other{# запиÑей (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}}</translation>
<translation id="3041612393474885105">Данные Ñертификата</translation>
<translation id="3063697135517575841">Ðе удалоÑÑŒ подтвердить данные карты. Повторите попытку позже.</translation>
<translation id="3064966200440839136">Ð’Ñ‹ выйдете из режима инкогнито, чтобы произвеÑти оплату во внешнем приложении. Продолжить?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ðет}=1{1 пароль}one{# пароль}few{# паролÑ}many{# паролей}other{# паролÑ}}</translation>
<translation id="3093245981617870298">Ðет Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñети</translation>
<translation id="3105172416063519923">Идентификатор объекта:</translation>
<translation id="3109728660330352905">У Ð²Ð°Ñ Ð½ÐµÑ‚ прав Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñтой Ñтраницы.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Выполните диагноÑтику подключениÑ<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Ðе удалоÑÑŒ декодировать ответ</translation>
<translation id="3150653042067488994">Временные неполадки на Ñервере</translation>
@@ -247,15 +277,19 @@
<translation id="3167968892399408617">Страницы, открытые в Ñтом окне, не оÑтанутÑÑ Ð² иÑтории браузера или поиÑка. Они не оÑтавÑÑ‚ на компьютере Ñледов, таких как файлы cookie, поÑле того как вы закроете вÑе вкладки инкогнито. Скачанные вами файлы и добавленные закладки будут Ñохранены.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ОÑтров</translation>
+<translation id="317583078218509884">Ðовые наÑтройки разрешений Ð´Ð»Ñ Ñайта вÑтупÑÑ‚ в Ñилу поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñтраницы.</translation>
<translation id="3176929007561373547">Проверьте наÑтройки прокÑи-Ñервера или попроÑите админиÑтратора
задать верные параметры. Ð’ противном Ñлучае^
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Откройте Ñтраницу в режиме инкогнито.</translation>
-<translation id="3202578601642193415">ПоÑледние</translation>
+<translation id="320323717674993345">Отменить оплату</translation>
<translation id="3207960819495026254">Добавлено в закладки</translation>
+<translation id="3225919329040284222">Сертификат не ÑоответÑтвует вÑтроенным параметрам определенных Ñайтов Ñ Ð²Ñ‹Ñоким уровнем безопаÑноÑти.</translation>
<translation id="3226128629678568754">Чтобы повторно ввеÑти данные, необходимые Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ Ñтраницы, нажмите "Обновить".</translation>
+<translation id="3227137524299004712">Микрофон</translation>
<translation id="3228969707346345236">Перевод не удалÑÑ, так как Ñтраница уже напиÑана на Ñледующем Ñзыке: <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Введите CVC-код карты <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Ð’Ñегда находить важный контент на Ñтом Ñайте</translation>
<translation id="3254409185687681395">Добавить Ñтраницу в закладки</translation>
<translation id="3270847123878663523">&amp;Отменить изменение порÑдка</translation>
<translation id="3282497668470633863">Укажите Ð¸Ð¼Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð° карты</translation>
@@ -269,42 +303,48 @@
<translation id="3340978935015468852">наÑтройках</translation>
<translation id="3345135638360864351">Ðе удалоÑÑŒ отправить пользователю <ph name="NAME" /> Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° доÑтуп к Ñтому Ñайту. Повторите попытку.</translation>
<translation id="3355823806454867987">Изменить наÑтройки прокÑи-Ñервера...</translation>
+<translation id="3361596688432910856">Ð’ Chrome <ph name="BEGIN_EMPHASIS" />не будет ÑохранÑÑ‚ÑŒÑÑ<ph name="END_EMPHASIS" /> ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />иÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¿Ñ€Ð¾Ñмотров;
+ <ph name="LIST_ITEM" />файлы cookie и данные Ñайтов;
+ <ph name="LIST_ITEM" />ÑведениÑ, которые вы указываете в формах.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Ошибка чаÑов</translation>
-<translation id="337311366426640088">Ещё <ph name="ITEM_COUNT" /></translation>
<translation id="337363190475750230">Отключен</translation>
<translation id="3377188786107721145">Ðе удалоÑÑŒ выполнить анализ политики</translation>
<translation id="3380365263193509176">ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°</translation>
<translation id="3380864720620200369">Идентификатор клиента:</translation>
<translation id="3391030046425686457">ÐÐ´Ñ€ÐµÑ Ð´Ð¾Ñтавки</translation>
<translation id="3395827396354264108">СпоÑоб выдачи</translation>
-<translation id="340013220407300675">Злоумышленники могут пытатьÑÑ Ð¿Ð¾Ñ…Ð¸Ñ‚Ð¸Ñ‚ÑŒ ваши данные Ñ Ñайта <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (например, пароли, ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ номера банковÑких карт).</translation>
<translation id="3422248202833853650">Закройте другие программы, чтобы оÑвободить памÑÑ‚ÑŒ.</translation>
<translation id="3422472998109090673">Сайт <ph name="HOST_NAME" /> недоÑтупен.</translation>
+<translation id="3427092606871434483">Разрешать (по умолчанию)</translation>
<translation id="3427342743765426898">&amp;Повторить изменениÑ</translation>
<translation id="3431636764301398940">Сохранить карту на Ñтом уÑтройÑтве</translation>
<translation id="3435896845095436175">Включить</translation>
<translation id="3447661539832366887">Владелец Ñтого уÑтройÑтва отключил игру Ñ Ð´Ð¸Ð½Ð¾Ð·Ð°Ð²Ñ€Ð¾Ð¼.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Выберите интервал:</translation>
<translation id="3462200631372590220">Скрыть подробноÑти</translation>
<translation id="3467763166455606212">Укажите Ð¸Ð¼Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð° карты.</translation>
<translation id="3478058380795961209">МеÑÑц</translation>
<translation id="3479539252931486093">Этот Ñайт не должен быть заблокирован? <ph name="BEGIN_LINK" />Сообщите нам об Ñтом<ph name="END_LINK" />.</translation>
<translation id="3479552764303398839">Ðе ÑейчаÑ</translation>
-<translation id="348000606199325318">Идентификатор ÑбоÑ: <ph name="CRASH_LOCAL_ID" /> (идентификатор Ñервера: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Ðе удалоÑÑŒ ÑвÑзатьÑÑ Ñ Ð²Ð°ÑˆÐ¸Ð¼Ð¸ родителÑми. Повторите попытку.</translation>
<translation id="3528171143076753409">Сертификат Ñервера не ÑвлÑетÑÑ Ð´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Как минимум 1 запиÑÑŒ на Ñинхронизируемых уÑтройÑтвах}=1{1 запиÑÑŒ (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}one{# запиÑÑŒ (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}few{# запиÑи (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}many{# запиÑей (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}other{# запиÑей (не ÑÑ‡Ð¸Ñ‚Ð°Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на Ñинхронизируемых уÑтройÑтвах)}}</translation>
<translation id="3539171420378717834">Хранить данные карты на Ñтом уÑтройÑтве</translation>
<translation id="3542684924769048008">ИÑпользовать пароль длÑ:</translation>
+<translation id="3545341443414427877">Ðе удалоÑÑŒ уÑтановить защищенное Ñоединение Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных наÑтроек ÑиÑтемных чаÑов и ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Шифровать вÑе Ñинхронизированные данные Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ кодовой фразы</translation>
-<translation id="3549761410225185768">Ещё <ph name="NUM_TABS_MORE" />…</translation>
-<translation id="3555561725129903880">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти выпущен Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð°Â <ph name="DOMAIN2" />. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Ð”Ð»Ñ Ñ€Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ обратитеÑÑŒ к админиÑтратору.</translation>
<translation id="3566021033012934673">Ваше подключение не защищено</translation>
+<translation id="3569145463236695319">&lt;p&gt;Ðе удалоÑÑŒ уÑтановить защищенное Ñоединение Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных наÑтроек ÑиÑтемных чаÑов и ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
+
+ &lt;p&gt;УÑтановите точную дату и времÑ. Ð”Ð»Ñ Ñтого откройте раздел &lt;strong&gt;ОÑновные&lt;/strong&gt; в приложении &lt;strong&gt;ÐаÑтройки&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Добавьте имÑ</translation>
<translation id="3583757800736429874">&amp;Повторить перемещение</translation>
<translation id="3586931643579894722">Скрыть подробноÑти</translation>
-<translation id="3587482841069643663">Ð’Ñе</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Укажите правильный Ñрок дейÑтвиÑ.</translation>
<translation id="36224234498066874">ОчиÑтить иÑторию...</translation>
@@ -321,7 +361,6 @@
<translation id="3681007416295224113">Данные Ñертификата</translation>
<translation id="3690164694835360974">ÐебезопаÑный вход</translation>
<translation id="3693415264595406141">Пароль:</translation>
-<translation id="3696411085566228381">нет</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Загрузка...</translation>
<translation id="3712624925041724820">ÐедоÑтаточно лицензий</translation>
@@ -329,12 +368,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Проверьте наÑтройки прокÑи-Ñервера, брандмауÑра и DNS<ph name="END_LINK" />.</translation>
<translation id="3736520371357197498">ЕÑли вы готовы подвергнуть риÑку ваши личные данные, вы можете <ph name="BEGIN_LINK" />перейти на зараженный Ñайт<ph name="END_LINK" />, не дожидаÑÑÑŒ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ´Ð¾Ð½Ð¾Ñного ПО.</translation>
<translation id="3739623965217189342">Ð¡ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ ÑÑылка</translation>
+<translation id="3744899669254331632">Перейти на Ñайт <ph name="SITE" /> невозможно, так как его идентификационные данные зашифрованы, и Chrome не может их обработать. Это могло произойти из-за ошибки Ñети или атаки на Ñайт. Скорее вÑего, он заработает через некоторое времÑ.</translation>
+<translation id="3748148204939282805">ПоÑещение Ñайта <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может привеÑти к уÑтановке вредоноÑного ПО или хищению личной информации (например, паролей, телефонных номеров и данных банковÑких карт). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Сбой при переводе вÑледÑтвие ошибки Ñервера.</translation>
<translation id="3759461132968374835">Ðет запиÑей о недавних ÑбоÑÑ…. Сбои, которые произошли при отключенной функции запиÑи Ñбоев, здеÑÑŒ не отображаютÑÑ.</translation>
+<translation id="3778403066972421603">Хотите Ñохранить карту в аккаунте Google и на Ñтом уÑтройÑтве?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Срок дейÑтвиÑ: до <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">ЕÑли вы иÑпользуете прокÑи-Ñервер...</translation>
<translation id="3828924085048779000">ПуÑтые кодовые фразы запрещены.</translation>
-<translation id="3845539888601087042">Показана иÑÑ‚Ð¾Ñ€Ð¸Ñ Ñо вÑех уÑтройÑтв, на которых иÑпользуетÑÑ Ñтот аккаунт. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Ðазад</translation>
<translation id="3858027520442213535">Обновить дату и времÑ</translation>
<translation id="3884278016824448484">Конфликт идентификаторов уÑтройÑтв</translation>
@@ -342,11 +384,13 @@
<translation id="3886446263141354045">Ваш Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° доÑтуп к Ñайту отправлен пользователю <ph name="NAME" /></translation>
<translation id="3890664840433101773">Добавление адреÑа Ñлектронной почты</translation>
<translation id="3901925938762663762">Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ иÑтек</translation>
-<translation id="3933571093587347751">{1,plural, =1{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу только завтра. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}one{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу только через # день. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}few{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу только через # днÑ. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}many{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу только через # дней. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}other{Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти вÑтупит в Ñилу только через # днÑ. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">Ðе удалоÑÑŒ загрузить документ PDF</translation>
+<translation id="3945915738023014686">Идентификатор загруженного отчета о ÑбоÑÑ…: <ph name="CRASH_ID" />. Локальный идентификатор ÑбоÑ: <ph name="CRASH_LOCAL_ID" />.</translation>
+<translation id="3949571496842715403">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="DOMAIN" />. Ð’ его Ñертификате безопаÑноÑти не указаны альтернативные варианты имен. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
<translation id="3963721102035795474">Режим чтениÑ</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ðет}=1{С 1 Ñайта }one{С # Ñайта }few{С # Ñайтов }many{С # Ñайтов }other{С # Ñайта }}</translation>
<translation id="397105322502079400">ВычиÑление…</translation>
<translation id="3973234410852337861">Сайт <ph name="HOST_NAME" /> заблокирован</translation>
+<translation id="3987940399970879459">Менее 1 МБ</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 веб-Ñтраница поблизоÑти}one{# веб-Ñтраница поблизоÑти}few{# веб-Ñтраницы поблизоÑти}many{# веб-Ñтраниц поблизоÑти}other{# веб-Ñтраницы поблизоÑти}}</translation>
<translation id="4021036232240155012">DNS – Ñто ÑÐµÑ‚ÐµÐ²Ð°Ñ Ñлужба, Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·ÑƒÑŽÑ‰Ð°Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ Ñайта в IP-адреÑ.</translation>
<translation id="4030383055268325496">&amp;Отменить добавление</translation>
@@ -357,56 +401,63 @@
<translation id="4079302484614802869">ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¾ÐºÑи-Ñервера предуÑматривает иÑпользование URL PAC-Ñкриптов вмеÑто фикÑированных прокÑи-Ñерверов.</translation>
<translation id="4098354747657067197">ОÑторожно, поддельный Ñайт!</translation>
<translation id="4103249731201008433">Серийный номер уÑтройÑтва недейÑтвителен</translation>
+<translation id="410351446219883937">ÐвтовоÑпроизведение</translation>
<translation id="4103763322291513355">Чтобы проÑмотреть URL, внеÑенные в черный ÑпиÑок, и другие правила, заданные ÑиÑтемным админиÑтратором, перейдите по адреÑу: &lt;strong&gt;chrome://policy&lt;/strong&gt;.</translation>
-<translation id="4110615724604346410">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти Ñодержит ошибки. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Пурпурный</translation>
+<translation id="4116663294526079822">Ð’Ñегда разрешать на Ñтом Ñайте</translation>
<translation id="4117700440116928470">ОблаÑÑ‚ÑŒ дейÑÑ‚Ð²Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» не поддерживаетÑÑ.</translation>
-<translation id="4118212371799607889">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Chromium не Ñчитает его Ñертификат безопаÑноÑти надежным. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{ещё 1 вариант}one{ещё # вариант}few{ещё # варианта}many{ещё # вариантов}other{ещё # варианта}}</translation>
<translation id="4130226655945681476">Проверьте Ñетевые кабели, модем и маршрутизатор.</translation>
+<translation id="413544239732274901">Подробнее...</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">ИÑпользовать глобальный параметр по умолчанию (находить)</translation>
+<translation id="4165986682804962316">ÐаÑтройки Ñайта</translation>
<translation id="4169947484918424451">Сохранить Ñту карту в Chromium?</translation>
<translation id="4171400957073367226">ÐŸÐ¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´Ð°ÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ недейÑтвительна</translation>
<translation id="4196861286325780578">&amp;Повторить перемещение</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Проверьте наÑтройки брандмауÑра и антивируÑного ПО<ph name="END_LINK" />.</translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{нет}=1{1 приложение ($1)}=2{2Â Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1 и $2)}one{# приложение ($1, $2, $3)}few{#Â Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2, $3)}many{# приложений ($1, $2, $3)}other{#Â Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Завершение работы программы</translation>
+<translation id="422022731706691852">ПоÑещение Ñайта <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может привеÑти к уÑтановке вредоноÑного ПО, которое будет мешать вашей работе в браузере (например, менÑÑ‚ÑŒ Ñтартовую Ñтраницу или показывать дополнительную рекламу на Ñайтах). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Выполните диагноÑтику Ñети<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">ДейÑтвительный</translation>
<translation id="4250431568374086873">Подключение к Ñайту защищено не полноÑтью</translation>
<translation id="4250680216510889253">Ðет</translation>
<translation id="425582637250725228">Возможно, внеÑенные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ ÑохранÑÑ‚ÑÑ.</translation>
<translation id="4258748452823770588">ПодпиÑÑŒ недейÑтвительна</translation>
+<translation id="4265872034478892965">Разрешено админиÑтратором</translation>
<translation id="4269787794583293679">(Ðе указано)</translation>
<translation id="4275830172053184480">ПерезапуÑк уÑтройÑтва</translation>
<translation id="4280429058323657511">, дейÑтвует до <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">СиÑтема Google по проверке безопаÑноÑти недавно обнаружила на Ñайте <ph name="SITE" /> <ph name="BEGIN_LINK" />вредоноÑное ПО<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">ПодÑказки Ð´Ð»Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑких Ñлементов</translation>
<translation id="4304224509867189079">Вход</translation>
-<translation id="432290197980158659">Сервер предоÑтавил Ñертификат, который не ÑоответÑтвует требованиÑм браузера. Эти Ñ‚Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ñ‹Ð´Ð²Ð¸Ð³Ð°ÑŽÑ‚ÑÑ Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы обезопаÑить Ð²Ð°Ñ Ð¾Ñ‚ иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ½Ð°Ð´ÐµÐ¶Ð½Ñ‹Ñ… Ñайтов. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Блокировать (по умолчанию)</translation>
<translation id="4325863107915753736">Ðе удалоÑÑŒ найти Ñтатью</translation>
<translation id="4326324639298822553">Проверьте Ñрок дейÑÑ‚Ð²Ð¸Ñ Ð¸ повторите попытку</translation>
<translation id="4331708818696583467">Ðенадежный</translation>
<translation id="4356973930735388585">Злоумышленники могут иÑпользовать Ñтот Ñайт, чтобы уÑтановить на ваш компьютер вредоноÑное ПО, которое крадет или удалÑет личную информацию (например, фотографии, пароли, ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ реквизиты банковÑких карт).</translation>
<translation id="4372948949327679948">Ожидаемое значение: <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Ð’Ñ‹ попыталиÑÑŒ перейти на Ñайт <ph name="DOMAIN" />, однако Ñертификат, предоÑтавленный Ñервером, был отозван издателем. Это означает, что учетные данные безопаÑноÑти, предоÑтавленные Ñервером, не заÑлуживают довериÑ. Возможно, вы имеете дело Ñо злоумышленниками.</translation>
<translation id="4381091992796011497">Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:</translation>
<translation id="4394049700291259645">Отключить</translation>
<translation id="4406896451731180161">Результаты поиÑка</translation>
+<translation id="4424024547088906515">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Chrome не доверÑет его Ñертификату безопаÑноÑти. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
<translation id="4432688616882109544">Ваш Ñертификат отклонен Ñайтом <ph name="HOST_NAME" /> или не был выдан.</translation>
<translation id="443673843213245140">ПрокÑи-Ñервер отключен, но при Ñтом его ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð´Ð°Ð½Ð° Ñвным образом.</translation>
-<translation id="4492190037599258964">Результаты поиÑка по запроÑу "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Ошибка проверки: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">ОбратитеÑÑŒ за помощью к ÑиÑтемному админиÑтратору.</translation>
<translation id="450710068430902550">ДоÑтуп админиÑтратора</translation>
<translation id="4515275063822566619">Карты и адреÑа, указанные в Chrome и в вашем аккаунте Google (<ph name="ACCOUNT_EMAIL" />). Ð’Ñ‹ можете изменить их на Ñтранице <ph name="BEGIN_LINK" />ÐаÑтройки<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Подробнее</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Отключите раÑширениÑ.</translation>
<translation id="457875822857220463">ДоÑтавка</translation>
<translation id="4587425331216688090">Удалить Ð°Ð´Ñ€ÐµÑ Ð¸Ð· Chrome?</translation>
-<translation id="4589078953350245614">Ð’Ñ‹ пытаетеÑÑŒ обратитьÑÑ Ñерверу в домене <ph name="DOMAIN" />, но он предоÑтавил недейÑтвительный Ñертификат. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Соединение Ñ <ph name="DOMAIN" /> зашифровано Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñовременных наборов шифров.</translation>
<translation id="4594403342090139922">&amp;Отменить удаление</translation>
<translation id="4619615317237390068">Вкладки Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… уÑтройÑтв</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти Ñодержит ошибки. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
+<translation id="4690462567478992370">Прекратить иÑпользование недейÑтвительного Ñертификата</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Соединение прервано</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Выполните диагноÑтику Ñети в Windows<ph name="END_LINK" /></translation>
@@ -423,21 +474,24 @@
<translation id="4771973620359291008">Произошла неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.</translation>
<translation id="4800132727771399293">Проверьте Ñрок дейÑÑ‚Ð²Ð¸Ñ Ð¸ CVC-код, а затем повторите попытку</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Перейти на Ñайт <ph name="SITE" /> невозможно, так как его идентификационные данные зашифрованы, и Google Chrome не может их обработать. Это могло произойти из-за ошибки Ñети или атаки на Ñайт. Скорее вÑего, он заработает через некоторое времÑ.</translation>
<translation id="4813512666221746211">Ошибка Ñети</translation>
<translation id="4816492930507672669">По размеру Ñтраницы</translation>
<translation id="483020001682031208">Ðет веб-Ñтраниц Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°</translation>
<translation id="4850886885716139402">ПоÑмотреть</translation>
<translation id="4854362297993841467">Этот ÑпоÑоб доÑтавки недоÑтупен. Выберите другой.</translation>
<translation id="4858792381671956233">Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° проÑмотр Ñайта отправлен вашим родителÑм</translation>
+<translation id="4863764087567530506">ПоÑещение Ñтой Ñтраницы может привеÑти к уÑтановке вредоноÑной программы или хищению вашей личной информации. <ph name="BEGIN_LINK" />Ð’Ñе равно продолжить<ph name="END_LINK" /></translation>
<translation id="4880827082731008257">ИÑкать в иÑтории</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> и <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{и ещё 1 веб-Ñтраница}one{и ещё # веб-Ñтраница}few{и ещё # веб-Ñтраницы}many{и ещё # веб-Ñтраниц}other{и ещё # веб-Ñтраницы}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Эта Ñтраница была автоматичеÑки переведена Ñ Ð½ÐµÐ¸Ð·Ð²ÐµÑтного Ñзыка на <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Платеж</translation>
<translation id="4926049483395192435">Укажите значение.</translation>
<translation id="495170559598752135">ДейÑтвиÑ</translation>
<translation id="4958444002117714549">Развернуть ÑпиÑок</translation>
-<translation id="4962322354953122629">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Chrome не Ñчитает его Ñертификат безопаÑноÑти надежным. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Снова включить предупреждениÑ</translation>
<translation id="4989809363548539747">Плагин не поддерживаетÑÑ</translation>
<translation id="5002932099480077015">Chrome будет хранить на Ñтом уÑтройÑтве данные карты Ð´Ð»Ñ Ð±Ñ‹Ñтрого Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼.</translation>
<translation id="5018422839182700155">Ðе удалоÑÑŒ открыть Ñтраницу</translation>
@@ -445,14 +499,15 @@
<translation id="5023310440958281426">Проверьте правила, уÑтановленные админиÑтратором</translation>
<translation id="5029568752722684782">Удалить данные</translation>
<translation id="5031870354684148875">О Переводчике Google</translation>
+<translation id="5039804452771397117">Разрешить</translation>
<translation id="5040262127954254034">Личные данные</translation>
<translation id="5045550434625856497">Ðеправильный пароль</translation>
<translation id="5056549851600133418">Статьи Ð´Ð»Ñ Ð²Ð°Ñ</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Проверьте Ð°Ð´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи-Ñервера<ph name="END_LINK" />.</translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Ðет файлов cookie.}=1{1 Ñайт иÑпользует файлы cookie. }one{# Ñайт иÑпользует файлы cookie. }few{# Ñайта иÑпользуют файлы cookie. }many{# Ñайтов иÑпользуют файлы cookie. }other{# Ñайта иÑпользуют файлы cookie. }}</translation>
<translation id="5087286274860437796">Сертификат Ñервера не дейÑтвителен в наÑтоÑщее времÑ.</translation>
<translation id="5087580092889165836">Добавить карту</translation>
<translation id="5089810972385038852">Штат</translation>
+<translation id="5094747076828555589">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Chromium не доверÑет его Ñертификату безопаÑноÑти. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
<translation id="5095208057601539847">ПровинциÑ</translation>
<translation id="5115563688576182185">(64 бит)</translation>
<translation id="5141240743006678641">Шифровать Ñинхронизированные пароли Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ учетных данных Google</translation>
@@ -468,24 +523,24 @@
<translation id="5222812217790122047">Введите Ð°Ð´Ñ€ÐµÑ Ñлектронной почты</translation>
<translation id="5251803541071282808">Облако</translation>
<translation id="5277279256032773186">ИÑпользуете Chrome на работе? Узнайте, как компании могут управлÑÑ‚ÑŒ наÑтройками Chrome на корпоративных уÑтройÑтвах.</translation>
+<translation id="5297526204711817721">Подключение к веб-Ñайту не защищено. Чтобы выйти из VR-режима, Ñнимите гарнитуру и нажмите кнопку "Ðазад".</translation>
<translation id="5299298092464848405">Ðе удалоÑÑŒ выполнить анализ политики</translation>
-<translation id="5300589172476337783">Показать</translation>
<translation id="5308689395849655368">Отчеты о ÑбоÑÑ… отключены.</translation>
<translation id="5317780077021120954">Сохранить</translation>
<translation id="5327248766486351172">Ðазвание</translation>
-<translation id="5337705430875057403">ПоÑещение Ñайта <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может привеÑти к уÑтановке вредоноÑного ПО или хищению вашей личной информации (например, паролей, телефонных номеров и данных кредитных карт).</translation>
-<translation id="5359637492792381994">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />, его Ñертификат в наÑтоÑщий момент недейÑтвителен. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">Сертификат веб-Ñайта <ph name="SITE" /> отозван. Открыть Ñайт в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ»ÑŒÐ·Ñ. Сбой мог быть вызван Ñетевой ошибкой или дейÑтвиÑми злоумышленников. Скорее вÑего, Ñайт заработает через некоторое времÑ.</translation>
<translation id="536296301121032821">Ðе удалоÑÑŒ Ñохранить наÑтройки политики</translation>
<translation id="5386426401304769735">Ð’ цепочке Ñертификатов Ñтого Ñайта еÑÑ‚ÑŒ Ñертификат, подпиÑанный Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ алгоритма SHA-1.</translation>
<translation id="5402410679244714488">Срок дейÑтвиÑ: <ph name="EXPIRATION_DATE_ABBR" />, иÑпользовалаÑÑŒ более года назад</translation>
+<translation id="540969355065856584">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти может быть недейÑтвителен в наÑтоÑщее времÑ. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
<translation id="5421136146218899937">ОчиÑтить иÑторию...</translation>
<translation id="5430298929874300616">Удалить закладку</translation>
<translation id="5431657950005405462">Файл не найден</translation>
-<translation id="5435775191620395718">Показана иÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ Ñтого уÑтройÑтва. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Ошибка проверки Ñхемы, <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Страница <ph name="HOST_NAME" /> не найдена</translation>
<translation id="5455374756549232013">ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° политики</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> из <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">ÐедопуÑтимые данные</translation>
<translation id="5470861586879999274">&amp;Повторить изменениÑ</translation>
<translation id="54817484435770891">Введите дейÑтвительный адреÑ</translation>
<translation id="5492298309214877701">Этот Ñайт в интранете организации или учебного Ð·Ð°Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ тот же URL, что и Ñайт в Интернете.
@@ -502,6 +557,8 @@
<translation id="5571083550517324815">Этот Ð°Ð´Ñ€ÐµÑ Ð½Ðµ поддерживаетÑÑ. Выберите другой.</translation>
<translation id="5572851009514199876">Выполните вход, чтобы Chrome определил, разрешен ли вам доÑтуп к Ñтому Ñайту.</translation>
<translation id="5580958916614886209">Проверьте меÑÑц в Ñроке дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ и повторите попытку</translation>
+<translation id="5586446728396275693">Ðет Ñохраненных адреÑов</translation>
+<translation id="5595485650161345191">Изменить адреÑ</translation>
<translation id="560412284261940334">Управление уÑтройÑтвами не поддерживаетÑÑ</translation>
<translation id="5610142619324316209">Проверьте подключение к Интернету.</translation>
<translation id="5610807607761827392">Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ картах и адреÑах можно изменить в <ph name="BEGIN_LINK" />наÑтройках<ph name="END_LINK" />.</translation>
@@ -509,15 +566,18 @@
<translation id="5622887735448669177">Покинуть Ñту Ñтраницу?</translation>
<translation id="5629630648637658800">Ðе удалоÑÑŒ применить наÑтройки политики</translation>
<translation id="5631439013527180824">Токен уÑтройÑтва недейÑтвителен</translation>
+<translation id="5633066919399395251">Сайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может уÑтановить на ваш компьютер вредоноÑное ПО, которое крадет или удалÑет личную информацию (например, фотографии, пароли, ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ реквизиты банковÑких карт). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">МеÑтоположение</translation>
+<translation id="5659593005791499971">Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð°</translation>
<translation id="5669703222995421982">Получение перÑонализированного контента</translation>
<translation id="5675650730144413517">Страница недоÑтупна</translation>
-<translation id="5677928146339483299">Заблокировано</translation>
-<translation id="5694783966845939798">Ð’Ñ‹ пытаетеÑÑŒ обратитьÑÑ Ðº Ñерверу в домене <ph name="DOMAIN" />, но его Ñертификат подпиÑан Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ненадежного алгоритма (например, SHA-1). Это означает, что учетные данные безопаÑноÑти и Ñам Ñервер могут оказатьÑÑ Ð¿Ð¾Ð´Ð´ÐµÐ»ÑŒÐ½Ñ‹Ð¼Ð¸. Возможно, вы имеете дело Ñо злоумышленниками. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">Идентификационные данные Ñтого Ñайта не проверены.</translation>
+<translation id="5713016350996637505">МошенничеÑкий контент заблокирован</translation>
<translation id="5720705177508910913">Текущий пользователь</translation>
<translation id="5732392974455271431">Ð”Ð»Ñ Ñ€Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ обратитеÑÑŒ к родителÑм.</translation>
<translation id="5763042198335101085">Укажите дейÑтвительный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты.</translation>
<translation id="5765072501007116331">Выберите адреÑ, чтобы поÑмотреть ÑпоÑобы и уÑÐ»Ð¾Ð²Ð¸Ñ Ð´Ð¾Ñтавки.</translation>
+<translation id="5778550464785688721">Полный контроль над MIDI-уÑтройÑтвами</translation>
<translation id="5784606427469807560">Ðе удалоÑÑŒ подтвердить данные карты. Проверьте подключение к Интернету и повторите попытку.</translation>
<translation id="5785756445106461925">Обратите внимание, что на Ñтранице обнаружен небезопаÑный контент. Возможно, при передаче реÑурÑÑ‹ проÑматриваютÑÑ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¸Ð¼Ð¸ лицами, а злоумышленники могут получить доÑтуп к Ñтранице и изменить ее поведение или внешний вид.</translation>
<translation id="5786044859038896871">Заполнить данные банковÑкой карты?</translation>
@@ -526,14 +586,14 @@
<translation id="5813119285467412249">&amp;Повторить добавление</translation>
<translation id="5814352347845180253">Ð’Ñ‹ можете потерÑÑ‚ÑŒ доÑтуп к премиум-контенту на <ph name="SITE" /> и других Ñайтах.</translation>
<translation id="5838278095973806738">Ðе Ñообщайте Ñтому Ñайту конфиденциальную информацию (например, пароли и номера банковÑких карт). К ней могут получить доÑтуп злоумышленники.</translation>
-<translation id="5843436854350372569">Ð’Ñ‹ пытаетеÑÑŒ обратитьÑÑ Ðº Ñерверу в домене <ph name="DOMAIN" />, но он предоÑтавил Ñертификат Ñ Ð½ÐµÐ½Ð°Ð´ÐµÐ¶Ð½Ñ‹Ð¼ ключом. Возможно, вы имеете дело Ñо злоумышленником, который взломал закрытый ключ. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">Ðе удаетÑÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ доÑтуп к Ñайту</translation>
<translation id="5869522115854928033">Сайты Ñ Ñохраненными паролÑми</translation>
<translation id="5872918882028971132">ПодÑказки Ð´Ð»Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑких Ñлементов</translation>
<translation id="5901630391730855834">Желтый</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (данные ÑинхронизируютÑÑ)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ИÑпользуетÑÑ 1 файл cookie}one{ИÑпользуетÑÑ # файл cookie}few{ИÑпользуетÑÑ # файла cookie}many{ИÑпользуетÑÑ # файлов cookie}other{ИÑпользуетÑÑ # файла cookie}}</translation>
<translation id="5926846154125914413">Ð’Ñ‹ можете потерÑÑ‚ÑŒ доÑтуп к премиум-контенту на некоторых Ñайтах.</translation>
<translation id="5959728338436674663">ÐвтоматичеÑки отправлÑÑ‚ÑŒ <ph name="BEGIN_WHITEPAPER_LINK" />ÑиÑтемную информацию и контент Ñтраниц<ph name="END_WHITEPAPER_LINK" /> в Google, чтобы улучшить раÑпознавание опаÑных приложений и Ñайтов. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">ÐеделÑ</translation>
<translation id="5967867314010545767">Удалить из иÑтории</translation>
<translation id="5975083100439434680">Уменьшить</translation>
<translation id="598637245381783098">Ðе удалоÑÑŒ открыть Payments</translation>
@@ -542,21 +602,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Страница 1}one{Страница #}few{Страница #}many{Страница #}other{Страница #}}</translation>
<translation id="6017514345406065928">Зеленый</translation>
+<translation id="6017850046339264347">Злоумышленники могут иÑпользовать Ñайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, чтобы уÑтановить вредоноÑные приложениÑ, маÑкирующиеÑÑ Ð¿Ð¾Ð´ безопаÑные программы или Ñобирающие данные, по которым Ð²Ð°Ñ Ð¼Ð¾Ð¶Ð½Ð¾ отÑледить. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (данные ÑинхронизируютÑÑ)</translation>
<translation id="6027201098523975773">Введите имÑ.</translation>
<translation id="6040143037577758943">Закрыть</translation>
<translation id="6042308850641462728">Подробнее...</translation>
+<translation id="6047233362582046994">ЕÑли вы оÑознаете, что можете подвергнуть риÑку Ñвои личные данные, то можете <ph name="BEGIN_LINK" />перейти на зараженный Ñайт<ph name="END_LINK" />, не дожидаÑÑÑŒ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ´Ð¾Ð½Ð¾Ñных приложений.</translation>
+<translation id="6051221802930200923">Веб-Ñайт <ph name="SITE" /> иÑпользует механизм Certificate Pinning, поÑтому на нем могла произойти подмена Ñертификата. Открыть Ñайт в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ»ÑŒÐ·Ñ. Сбой мог быть вызван Ñетевой ошибкой или дейÑтвиÑми злоумышленников. Скорее вÑего, Ñайт заработает через некоторое времÑ.</translation>
<translation id="6060685159320643512">Будьте оÑторожны при работе Ñ ÑкÑпериментальной верÑией</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{нет}=1{1}one{#}few{#}many{#}other{#}}</translation>
+<translation id="6080696365213338172">Ð’Ñ‹ иÑпользуете Ñертификат, предоÑтавленный админиÑтратором, поÑтому он может заблокировать передачу данных на Ñайт <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ðет}=1{1 Ñинхронизированный пароль}one{# Ñинхронизированный пароль}few{# Ñинхронизированных паролÑ}many{# Ñинхронизированных паролей}other{# Ñинхронизированного паролÑ}}</translation>
<translation id="6146055958333702838">Проверьте Ñоединение кабелей, перезагрузите маршрутизаторы, модемы и другие
Ñетевые уÑтройÑтва.</translation>
<translation id="614940544461990577">Попробуйте Ñделать Ñледующее:</translation>
<translation id="6151417162996330722">Слишком долгий Ñрок дейÑÑ‚Ð²Ð¸Ñ Ñертификата, предоÑтавленного Ñервером.</translation>
<translation id="6157877588268064908">Выберите адреÑ, чтобы поÑмотреть ÑпоÑобы и уÑÐ»Ð¾Ð²Ð¸Ñ Ð´Ð¾Ñтавки.</translation>
+<translation id="6158003235852588289">СиÑтема Google по проверке безопаÑноÑти недавно обнаружила попытку фишинга на Ñайте <ph name="SITE" />. Будьте внимательны: мошенники чаÑто Ñоздают веб-Ñтраницы, похожие на знакомые вам Ñайты.</translation>
<translation id="6165508094623778733">Подробнее...</translation>
+<translation id="6169916984152623906">Ваши дейÑÑ‚Ð²Ð¸Ñ Ð² режиме инкогнито будут недоÑтупны другим пользователÑм Ñтого уÑтройÑтва. Однако закладки и Ñкачанные файлы ÑохранÑÑ‚ÑÑ.</translation>
<translation id="6177128806592000436">Подключение к Ñайту не защищено</translation>
<translation id="6184817833369986695">(когорта: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Проверьте подключение к Интернету</translation>
<translation id="6218753634732582820">Удалить Ð°Ð´Ñ€ÐµÑ Ð¸Ð· Chromium?</translation>
+<translation id="6221345481584921695">СиÑтема Google по проверке безопаÑноÑти Ñайтов недавно обнаружила на <ph name="SITE" /> <ph name="BEGIN_LINK" />вредоноÑное ПО<ph name="END_LINK" />. Его иÑточником ÑвлÑетÑÑ <ph name="SUBRESOURCE_HOST" />, не раз замеченным в раÑпроÑтранении вируÑов. Будьте внимательны, иногда даже на безопаÑных Ñайтах поÑвлÑÑŽÑ‚ÑÑ Ð²Ñ€ÐµÐ´Ð¾Ð½Ð¾Ñные программы.</translation>
<translation id="6251924700383757765">Политика конфиденциальноÑти</translation>
<translation id="6254436959401408446">ÐедоÑтаточно памÑти Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ Ñтраницы</translation>
<translation id="625755898061068298">Ð’Ñ‹ отключили Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ ÑиÑтемы безопаÑноÑти Ð´Ð»Ñ Ñтого Ñайта.</translation>
@@ -582,15 +650,14 @@
<translation id="6404511346730675251">Изменить закладку</translation>
<translation id="6410264514553301377">Введите Ñрок дейÑÑ‚Ð²Ð¸Ñ Ð¸ CVC-код карты <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° проÑмотр Ñайта отправлен вашему родителю</translation>
-<translation id="6416403317709441254">Веб-Ñайт <ph name="SITE" /> отправлÑет Chromium некорректные идентификационные данные, поÑтому открыть его в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÐ»ÑŒÐ·Ñ. Сбой мог быть вызван Ñетевой ошибкой или дейÑтвиÑми злоумышленников. Возможно, Ñайт заработает через некоторое времÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">Ðе удаетÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚ÑŒ, был ли отозван Ñертификат.</translation>
<translation id="6433490469411711332">Изменить контактную информацию</translation>
<translation id="6433595998831338502">Сайт <ph name="HOST_NAME" /> не позволÑет уÑтановить Ñоединение.</translation>
<translation id="6446608382365791566">Укажите дополнительную информацию</translation>
+<translation id="6447842834002726250">Файлы Ñookie</translation>
<translation id="6451458296329894277">Подтвердите повторную отправку формы</translation>
<translation id="6456339708790392414">Оплата</translation>
<translation id="6458467102616083041">ИгнорируетÑÑ, так как поиÑк по умолчанию запрещен правилами.</translation>
-<translation id="6462969404041126431">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. ВероÑтно, его Ñертификат был отозван. Проблема также может быть ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Правила уÑтройÑтва</translation>
<translation id="6477321094435799029">Браузер Chrome обнаружил на Ñтой Ñтранице необычный код и заблокировал его, чтобы защитить ваши данные (например, пароли, а также номера телефонов и банковÑких карт).</translation>
<translation id="6489534406876378309">Ðачать загрузку Ñведений об ошибках</translation>
@@ -602,20 +669,19 @@
<translation id="6556915248009097796">Срок дейÑтвиÑ: <ph name="EXPIRATION_DATE_ABBR" />, поÑледний раз иÑпользовалаÑÑŒ <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Ещё не одобрено админиÑтратором</translation>
<translation id="6569060085658103619">Ð’Ñ‹ проÑматриваете Ñтраницу раÑширениÑ</translation>
-<translation id="6593753688552673085">менее <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">ПоÑещение Ñтой Ñтраницы может привеÑти к уÑтановке опаÑной программы, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ñ…Ð¸Ñ‰Ð°ÐµÑ‚ или удалÑет данные. <ph name="BEGIN_LINK" />Ð’Ñе равно продолжить<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">Параметры шифрованиÑ</translation>
<translation id="662080504995468778">ОÑтатьÑÑ</translation>
<translation id="6626291197371920147">Введите номер дейÑтвующей карты</translation>
<translation id="6628463337424475685">ПоиÑк <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Сайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может уÑтановить на ваш компьютер Mac вредоноÑное ПО, которое крадет или удалÑет личную информацию (например, фотографии, пароли, ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ реквизиты банковÑких карт). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Правило уÑтарело.</translation>
-<translation id="6652240803263749613">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти не принимаетÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ ÑиÑтемой вашего компьютера. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Удалить подÑказку из Chromium?</translation>
<translation id="6685834062052613830">Выйдите из аккаунта и завершите наÑтройку</translation>
<translation id="6710213216561001401">Ðазад</translation>
<translation id="6710594484020273272">&lt;Введите поиÑковый запроÑ&gt;</translation>
<translation id="6711464428925977395">Ðа прокÑи-Ñервере возникла проблема или Ð°Ð´Ñ€ÐµÑ ÑƒÐºÐ°Ð·Ð°Ð½ неверно.</translation>
<translation id="6727102863431372879">УÑтановить</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{нет}=1{1 запиÑÑŒ}one{# запиÑÑŒ}few{# запиÑи}many{# запиÑей}other{# запиÑи}}</translation>
<translation id="674375294223700098">ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° Ñертификата Ñервера.</translation>
<translation id="6753269504797312559">Значение правила</translation>
<translation id="6757797048963528358">УÑтройÑтво находитÑÑ Ð² ÑпÑщем режиме.</translation>
@@ -623,6 +689,8 @@
<translation id="6810899417690483278">Идентификатор перÑонализации</translation>
<translation id="6820686453637990663">Код CVC</translation>
<translation id="6824266427216888781">Ðе удалоÑÑŒ загрузить данные регионов</translation>
+<translation id="6825578344716086703">Ð’Ñ‹ пытаетеÑÑŒ обратитьÑÑ Ðº Ñерверу в домене <ph name="DOMAIN" />, но его Ñертификат подпиÑан Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ненадежного алгоритма (например, SHA-1). Это означает, что учетные данные безопаÑноÑти и Ñам Ñервер могут оказатьÑÑ Ð¿Ð¾Ð´Ð´ÐµÐ»ÑŒÐ½Ñ‹Ð¼Ð¸. Возможно, вы имеете дело Ñо злоумышленниками.</translation>
+<translation id="6830728435402077660">Ðе защищено</translation>
<translation id="6831043979455480757">ПеревеÑти</translation>
<translation id="6839929833149231406">ÐдминиÑтративный район</translation>
<translation id="6874604403660855544">&amp;Повторить добавление</translation>
@@ -630,6 +698,7 @@
<translation id="6895330447102777224">Ваша карта подтверждена</translation>
<translation id="6897140037006041989">User Agent</translation>
<translation id="6915804003454593391">Пользователь:</translation>
+<translation id="6945221475159498467">Выбрать</translation>
<translation id="6948701128805548767">Выберите адреÑ, чтобы поÑмотреть ÑпоÑобы и уÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ.</translation>
<translation id="6957887021205513506">Возможно, Ñертификат Ñервера фальÑифицирован.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -638,15 +707,16 @@
<translation id="6973656660372572881">Указаны как фикÑированные прокÑи-Ñерверы, так и URL PAC-Ñкриптов.</translation>
<translation id="6989763994942163495">Показать дополнительные наÑтройки</translation>
<translation id="7000990526846637657">Данные из иÑтории не найдены</translation>
-<translation id="7009986207543992532">Ð’Ñ‹ пытаетеÑÑŒ обратитьÑÑ Ðº Ñерверу в домене <ph name="DOMAIN" />, но он предоÑтавил Ñертификат Ñ Ð¿Ð¾Ð´Ð¾Ð·Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ долгим Ñроком дейÑтвиÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¿Ñ€Ð¾Ñмотра также может хранитьÑÑ Ð² вашем аккаунте Google: <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />.</translation>
<translation id="7029809446516969842">Пароли</translation>
+<translation id="7050187094878475250">Ð’Ñ‹ попыталиÑÑŒ перейти на Ñайт <ph name="DOMAIN" />, но Ñервер предоÑтавил не заÑлуживающий Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ñертификат Ñо Ñлишком долгим Ñроком дейÑтвиÑ.</translation>
+<translation id="7053983685419859001">Блокировать</translation>
<translation id="7064851114919012435">Контактные данные</translation>
<translation id="7079718277001814089">Этот Ñайт Ñодержит вредоноÑное ПО</translation>
<translation id="7087282848513945231">ГрафÑтво</translation>
-<translation id="7088615885725309056">Раньше</translation>
<translation id="7090678807593890770">Выполните поиÑк по запроÑу <ph name="LINK" /> в Google</translation>
+<translation id="7108819624672055576">Разрешено раÑширением</translation>
<translation id="7119414471315195487">Закройте другие вкладки и программы.</translation>
<translation id="7129409597930077180">Ðевозможно отправить заказ по Ñтому адреÑу. Выберите другой вариант.</translation>
<translation id="7138472120740807366">СпоÑоб доÑтавки</translation>
@@ -664,22 +734,18 @@
<translation id="7220786058474068424">Подождите…</translation>
<translation id="724691107663265825">ОÑторожно, вредоноÑное ПО!</translation>
<translation id="724975217298816891">Введите Ñрок дейÑÑ‚Ð²Ð¸Ñ Ð¸ CVC-код карты <ph name="CREDIT_CARD" />. ПоÑле Ñтого ее данные будут переданы Ñайту.</translation>
-<translation id="725866823122871198">Ðе удалоÑÑŒ уÑтановить защищенное Ñоединение Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных наÑтроек ÑиÑтемных чаÑов и ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="7260504762447901703">Запретить доÑтуп</translation>
<translation id="7275334191706090484">УправлÑемые закладки</translation>
<translation id="7298195798382681320">Рекомендованные</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" />: отчет о Ñбое Ñохранен, но ещё не загружен (пользователь запроÑил загрузку)</translation>
<translation id="7334320624316649418">&amp;Повторить изменение порÑдка</translation>
<translation id="733923710415886693">Сертификат Ñервера не проходил проверку.</translation>
-<translation id="7351800657706554155">Открыть Ñайт <ph name="SITE" /> ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ»ÑŒÐ·Ñ, так как его Ñертификат отозван. Возможно, Ñбой вызван Ñетевой ошибкой или дейÑтвиÑми злоумышленников. Сайт может заработать через некоторое времÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">ÐšÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока</translation>
<translation id="7372973238305370288">результат поиÑка</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ðет</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Подтвердите карту</translation>
-<translation id="7394102162464064926">Удалить Ñти Ñтраницы из иÑтории проÑмотров?
-
-КÑтати: в режиме инкогнито <ph name="SHORTCUT_KEY" /> иÑÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ ÑохранÑетÑÑ.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Путь к профилю</translation>
<translation id="7424977062513257142">Подтвердите дейÑтвие:</translation>
@@ -687,6 +753,7 @@
<translation id="7444046173054089907">Сайт заблокирован</translation>
<translation id="7445762425076701745">Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñервера, к которому вы подключилиÑÑŒ, не может быть полноÑтью подтверждена. Ð’Ñ‹ подключилиÑÑŒ к Ñерверу, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ, которое дейÑтвительно только в вашей Ñети; владелец Ñтого Ñервера не может быть проверен или подтвержден внешним центром Ñертификации. Так как некоторые центры Ñертификации могут выдавать Ñертификаты Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ñ‹Ñ… названий, отÑутÑтвуют гарантии в том, что Ñто дейÑтвительно нужный вам Ñайт, а не Ñайт злоумышленника.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Узнайте больше<ph name="END_LINK" /> об Ñтой проблеме.</translation>
+<translation id="7455133967321480974">ИÑпользовать глобальный параметр по умолчанию (блокировать)</translation>
<translation id="7460163899615895653">ЗдеÑÑŒ поÑвÑÑ‚ÑÑ Ð½ÐµÐ´Ð°Ð²Ð½Ð¸Ðµ вкладки Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… уÑтройÑтв</translation>
<translation id="7469372306589899959">Подтверждение карты…</translation>
<translation id="7481312909269577407">Вперед</translation>
@@ -694,36 +761,43 @@
<translation id="7508255263130623398">Возвращенный идентификатор уÑтройÑтва пуÑÑ‚ или не ÑоответÑтвует имеющемуÑÑ</translation>
<translation id="7514365320538308">Скачать</translation>
<translation id="7518003948725431193">Ðе найдена Ñтраница Ð´Ð»Ñ Ð²ÐµÐ±-адреÑа <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Значение</translation>
<translation id="7537536606612762813">ОбÑзательнаÑ</translation>
+<translation id="7542403920425041731">ПоÑле Ñтого данные вашей карты будут переданы Ñайту.</translation>
<translation id="7542995811387359312">Ðвтозаполнение отключено – незащищенное подключение.</translation>
<translation id="7543525346216957623">ОбратитеÑÑŒ за помощью к родителю</translation>
<translation id="7549584377607005141">Ð”Ð»Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð¾Ð³Ð¾ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²ÐµÐ±-Ñтраницы требуютÑÑ Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ‹Ðµ ранее данные. Их можно отправить повторно, но в Ñтом Ñлучае вÑе дейÑÑ‚Ð²Ð¸Ñ Ð½Ð° Ñтранице будут выполнены Ñнова.</translation>
<translation id="7552846755917812628">Попробуйте Ñделать Ñледующее:</translation>
<translation id="7554791636758816595">ÐÐ¾Ð²Ð°Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ°</translation>
+<translation id="7567204685887185387">Ðе удалоÑÑŒ подтвердить, что Ñто Ñервер <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти мог быть выдан обманным путем. Возможно, Ñервер наÑтроен неправильно или кто-то пытаетÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ ваши данные.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}many{<ph name="CONTACT_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Язык Ñтой Ñтраницы<ph name="ORIGINAL_LANGUAGE" />Хотите перевеÑти ее?</translation>
<translation id="7569952961197462199">Удалить кредитную карту из Chrome?</translation>
<translation id="7569983096843329377">Черный</translation>
<translation id="7578104083680115302">БыÑтро оплачивайте покупки на Ñайтах и в приложениÑÑ… Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ карт, Ñохраненных в Google Payments. ÐаÑтройка будет дейÑтвовать на вÑех ваших уÑтройÑтвах.</translation>
<translation id="7588950540487816470">Интернет вокруг наÑ</translation>
<translation id="7592362899630581445">Сертификат Ñервера не ÑоответÑтвует ограничениÑм в отношении имен.</translation>
+<translation id="7598391785903975535">Менее <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Сайт <ph name="HOST_NAME" /> пока не может обработать Ñтот запроÑ.</translation>
<translation id="7600965453749440009">Ðикогда не переводить <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Значение <ph name="VALUE" /> лежит за пределами разрешенного диапазона.</translation>
<translation id="7613889955535752492">Срок дейÑтвиÑ: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">У Ð²Ð°Ñ ÑƒÐ¶Ðµ еÑÑ‚ÑŒ данные, зашифрованные Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ верÑией Ð¿Ð°Ñ€Ð¾Ð»Ñ Ðº аккаунту Google. Введите Ñтот пароль ниже.</translation>
-<translation id="7634554953375732414">Подключение к веб-Ñайту не защищено</translation>
<translation id="7637571805876720304">Удалить кредитную карту из Chromium?</translation>
<translation id="765676359832457558">Скрыть дополнительные наÑтройки</translation>
<translation id="7658239707568436148">Отмена</translation>
+<translation id="7662298039739062396">Эта наÑтройка управлÑетÑÑ Ñ€Ð°Ñширением</translation>
<translation id="7667346355482952095">Возвращенный токен пуÑÑ‚ или не ÑоответÑтвует имеющемуÑÑ</translation>
<translation id="7668654391829183341">ÐеизвеÑтное уÑтройÑтво</translation>
<translation id="7669271284792375604">ПоÑещение Ñтого Ñайта может привеÑти к уÑтановке вредоноÑного ПО, которое будет мешать работе браузера (например, менÑÑ Ñтартовую Ñтраницу или Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½ÑƒÑŽ рекламу на Ñайтах).</translation>
<translation id="7674629440242451245">Хотите быть в курÑе новинок Chrome? Выберите канал Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð² на Ñтранице "chrome.com/dev".</translation>
<translation id="7682287625158474539">ÐÐ´Ñ€ÐµÑ Ð´Ð¾Ñтавки</translation>
+<translation id="7701040980221191251">Ðет</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Перейти на Ñайт <ph name="SITE" /> (небезопаÑно)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Сертификат</translation>
+<translation id="7716147886133743102">Заблокировано админиÑтратором</translation>
<translation id="7716424297397655342">Ðе удалоÑÑŒ загрузить Ñайт из кеша</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Ðе управлÑетÑÑ</translation>
<translation id="7755287808199759310">Ð”Ð»Ñ Ñ€Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ обратитеÑÑŒ к родителю.</translation>
<translation id="7758069387465995638">Возможно, подключение заблокировано брандмауÑром или антивируÑным ПО.</translation>
@@ -750,15 +824,15 @@
<translation id="7951415247503192394">(32 бит)</translation>
<translation id="7956713633345437162">Закладки на мобильном</translation>
<translation id="7961015016161918242">Ðет</translation>
-<translation id="7962083544045318153">Идентификатор ÑбоÑ: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Ð’Ñегда переводить <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ðе указано</translation>
<translation id="800218591365569300">Закройте другие вкладки и программы, чтобы оÑвободить памÑÑ‚ÑŒ.</translation>
<translation id="8012647001091218357">Ðе удалоÑÑŒ ÑвÑзатьÑÑ Ñ Ð²Ð°ÑˆÐ¸Ð¼Ð¸ родителÑми. Повторите попытку.</translation>
<translation id="8025119109950072390">ПоÑещение Ñтого Ñайта может привеÑти к уÑтановке вредоноÑного ПО или хищению личной информации (например, паролей, телефонных номеров и данных банковÑких карт).</translation>
-<translation id="803030522067524905">СиÑтема Google по проверке безопаÑноÑти недавно обнаружила попытку фишинга на Ñайте <ph name="SITE" />. Будьте внимательны: мошенники чаÑто Ñоздают веб-Ñтраницы, похожие на знакомые вам Ñайты. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Язык Ñтой Ñтраницы: <ph name="SOURCE_LANGUAGE" />. ПеревеÑти ее на <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Спрашивать (по умолчанию)</translation>
<translation id="8041089156583427627">Отправить отзыв</translation>
+<translation id="8041940743680923270">ИÑпользовать глобальный параметр по умолчанию (Ñпрашивать)</translation>
<translation id="8088680233425245692">Ðе удалоÑÑŒ показать Ñтатью</translation>
<translation id="8089520772729574115">менее 1 МБ</translation>
<translation id="8091372947890762290">ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑƒÑтройÑтвами не завершена</translation>
@@ -767,13 +841,14 @@
<translation id="8134994873729925007">Ðе удаетÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ <ph name="BEGIN_ABBR" />DNS-адреÑ<ph name="END_ABBR" /> Ñервера <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Ваш компьютер перешел в ÑпÑщий режим.</translation>
<translation id="8150722005171944719">Файл по адреÑу <ph name="URL" /> недоÑтупен. Возможно, он был удален или перемещен либо права доÑтупа к нему ограничены.</translation>
+<translation id="8184538546369750125">ИÑпользовать глобальный параметр по умолчанию (разрешать)</translation>
+<translation id="8191494405820426728">Локальный идентификатор ÑбоÑ: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Отменить перемещение</translation>
<translation id="8201077131113104583">ÐедейÑтвительный URL Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ заказе</translation>
<translation id="8218327578424803826">Ðазначенное меÑтоположение:</translation>
<translation id="8225771182978767009">Тот, кто наÑтраивал компьютер, заблокировал Ñтот Ñайт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" /> и <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Сайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может уÑтановить на ваш компьютер вредоноÑное ПО, которое крадет или удалÑет личную информацию (например, фотографии, пароли, ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ реквизиты банковÑких карт).</translation>
<translation id="8241707690549784388">Ðа Ñтранице, которую вы ищете, иÑпользовалаÑÑŒ Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ð°Ñ Ð²Ð°Ð¼Ð¸ информациÑ. При возврате на Ñту Ñтраницу может потребоватьÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð¸Ñ‚ÑŒ выполненные ранее дейÑтвиÑ. Продолжить?</translation>
<translation id="8249320324621329438">Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледней загрузки:</translation>
<translation id="8253091569723639551">Ðеобходимо указать платежный адреÑ</translation>
@@ -781,6 +856,7 @@
<translation id="8289355894181816810">Уточните информацию у админиÑтратора Ñети.</translation>
<translation id="8293206222192510085">Добавление закладки</translation>
<translation id="8294431847097064396">ИÑточник</translation>
+<translation id="8306404619377842860">Ðе удалоÑÑŒ уÑтановить защищенное Ñоединение Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных наÑтроек ÑиÑтемных чаÑов и ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Перевод не завершен из-за проблем Ñ Ñетевым подключением.</translation>
<translation id="8332188693563227489">ДоÑтуп к <ph name="HOST_NAME" /> запрещен</translation>
<translation id="834457929814110454">ЕÑли вы готовы подвергнуть риÑку ваши личные данные, вы можете <ph name="BEGIN_LINK" />перейти на зараженный Ñайт<ph name="END_LINK" />, не дожидаÑÑÑŒ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ´Ð¾Ð½Ð¾Ñного ПО.</translation>
@@ -801,11 +877,9 @@
<translation id="8483780878231876732">Чтобы иÑпользовать карты, привÑзанные к аккаунту Google Account, войдите в Chrome</translation>
<translation id="8488350697529856933">Объект применениÑ</translation>
<translation id="8498891568109133222">Превышено Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð° от Ñайта <ph name="HOST_NAME" />.</translation>
-<translation id="852346902619691059">Сервер не может подтвердить ÑвÑзь Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼Â <ph name="DOMAIN" />. Его Ñертификат безопаÑноÑти не принимаетÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ ÑиÑтемой вашего уÑтройÑтва. Возможно, проблема ÑвÑзана Ñ Ð½Ð°Ñтройками Ñервера или дейÑтвиÑми злоумышленников, которые пытаютÑÑ Ð¿ÐµÑ€ÐµÑ…Ð²Ð°Ñ‚Ð¸Ñ‚ÑŒ Ñоединение. <ph name="BEGIN_LEARN_MORE_LINK" />Подробнее…<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Год</translation>
<translation id="8543181531796978784"><ph name="BEGIN_ERROR_LINK" />Сообщите о зараженном Ñайте<ph name="END_ERROR_LINK" />. ЕÑли вы готовы подвергнуть риÑку личные данные, то можете <ph name="BEGIN_LINK" />перейти на Ñтраницу<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Перевод не удалÑÑ, так как не удаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ Ñзык Ñтраницы.</translation>
-<translation id="8559762987265718583">Ðе удалоÑÑŒ уÑтановить защищенное Ñоединение Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> из-за неверных наÑтроек ÑиÑтемных чаÑов и ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ (<ph name="DATE_AND_TIME" />).</translation>
<translation id="8571890674111243710">Перевод Ñтраницы на <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Добавьте номер</translation>
<translation id="859285277496340001">Этот Ñертификат не определÑет механизм проверки отзыва.</translation>
@@ -819,6 +893,7 @@
<translation id="8738058698779197622">Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°Ñного Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð¾, чтобы Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ð¸Ñ ÑиÑтемных чаÑов были верны. Причина в том, что Ñертификаты Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ñайтов имеют ограниченный Ñрок дейÑтвиÑ. ЕÑли чаÑÑ‹ на уÑтройÑтве неточны, Chromium не может проверить актуальноÑÑ‚ÑŒ Ñтих Ñертификатов.</translation>
<translation id="8740359287975076522">Ðе удаетÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ &lt;abbr id="dnsDefinition"&gt;DNS-адреÑ&lt;/abbr&gt; Ñайта <ph name="HOST_NAME" />. ВыполнÑетÑÑ Ð´Ð¸Ð°Ð³Ð½Ð¾Ñтика.</translation>
<translation id="8759274551635299824">Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ иÑтек.</translation>
+<translation id="8761567432415473239">СиÑтема Google по проверке безопаÑноÑти Ñайтов недавно обнаружила на <ph name="SITE" /> <ph name="BEGIN_LINK" />вредоноÑное ПО<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;Повторить удаление</translation>
<translation id="8800988563907321413">ЗдеÑÑŒ поÑвÑÑ‚ÑÑ Ñ€ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ð°Ñ†Ð¸Ð¸.</translation>
<translation id="8820817407110198400">Закладки</translation>
@@ -831,29 +906,30 @@
<translation id="8870413625673593573">Ðедавно закрытые</translation>
<translation id="8874824191258364635">Введите дейÑтвительный номер карты.</translation>
<translation id="8876793034577346603">Ðе удалоÑÑŒ выполнить анализ конфигурации Ñети.</translation>
-<translation id="8877192140621905067">ПоÑле Ñтого данные вашей карты будут переданы Ñайту.</translation>
<translation id="8889402386540077796">Тон</translation>
<translation id="8891727572606052622">ÐедопуÑтимый режим работы прокÑи-Ñервера.</translation>
<translation id="889901481107108152">К Ñожалению, данное дейÑтвие невозможно выполнить на Ñтой платформе.</translation>
<translation id="8903921497873541725">Увеличить</translation>
<translation id="8931333241327730545">Сохранить Ñту карту в аккаунте Google?</translation>
<translation id="8932102934695377596">ЧаÑÑ‹ отÑтают</translation>
-<translation id="8954894007019320973">(Продолж.)</translation>
<translation id="8971063699422889582">Сертификат Ñервера уÑтарел.</translation>
<translation id="8986494364107987395">ÐвтоматичеÑки отправлÑÑ‚ÑŒ в Google ÑтатиÑтику иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ отчеты о ÑбоÑÑ…</translation>
-<translation id="8987927404178983737">МеÑÑц</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Сайт Ñодержит нежелательное ПО</translation>
+<translation id="8997023839087525404">ПредоÑтавленный Ñервером Ñертификат не проходил проверку безопаÑноÑти. Она необходима в некоторых ÑлучаÑÑ…, чтобы доказать, что Ñертификат надежен и защищает от злоумышленников.</translation>
<translation id="9001074447101275817">Ð”Ð»Ñ Ð´Ð¾Ñтупа на прокÑи-Ñервер <ph name="DOMAIN" /> требуетÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ пароль.</translation>
+<translation id="9005998258318286617">Ðе удалоÑÑŒ загрузить PDF-документ.</translation>
<translation id="901974403500617787">СиÑтемные флаги может уÑтанавливать только владелец (<ph name="OWNER_EMAIL" />).</translation>
+<translation id="9020200922353704812">Ðеобходимо указать платежный Ð°Ð´Ñ€ÐµÑ ÐºÐ°Ñ€Ñ‚Ñ‹</translation>
<translation id="9020542370529661692">Эта Ñтраница переведена на <ph name="TARGET_LANGUAGE" />.</translation>
<translation id="9035022520814077154">Ошибка безопаÑноÑти</translation>
<translation id="9038649477754266430">ИÑпользовать подÑказки Ð´Ð»Ñ ÑƒÑÐºÐ¾Ñ€ÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ Ñтраниц</translation>
<translation id="9039213469156557790">Обратите внимание, что на Ñтранице обнаружен небезопаÑный контент. Возможно, при передаче реÑурÑÑ‹ проÑматриваютÑÑ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¸Ð¼Ð¸ лицами, а злоумышленники могут получить доÑтуп к Ñтранице и изменить ее поведение.</translation>
-<translation id="9040185888511745258">Сайт <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> может уÑтановить на ваше уÑтройÑтво вредоноÑное ПО, которое будет мешать работе браузера (например, менÑÑ Ñтартовую Ñтраницу или Ð¿Ð¾ÐºÐ°Ð·Ñ‹Ð²Ð°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½ÑƒÑŽ рекламу на Ñайтах).</translation>
+<translation id="9049981332609050619">Ð’Ñ‹ попыталиÑÑŒ открыть <ph name="DOMAIN" />, однако предÑтавленный Ñервером Ñертификат недейÑтвителен.</translation>
<translation id="9050666287014529139">ÐšÐ¾Ð´Ð¾Ð²Ð°Ñ Ñ„Ñ€Ð°Ð·Ð°</translation>
<translation id="9065203028668620118">Изменить</translation>
<translation id="9068849894565669697">Выберите цвет</translation>
+<translation id="9069693763241529744">Заблокировано раÑширением</translation>
<translation id="9076283476770535406">Может Ñодержать контент Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых</translation>
<translation id="9078964945751709336">Информации недоÑтаточно</translation>
<translation id="9103872766612412690">Ðа Ñайте <ph name="SITE" /> Ð´Ð»Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ñ‹ ваших данных обычно иÑпользуетÑÑ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ. Однако учетные данные, которые мы получили от Ñайта <ph name="SITE" /> ÑейчаÑ, отличаютÑÑ Ð¾Ñ‚ тех, которые он отправлÑет обычно. ВероÑтно, вредоноÑный Ñайт пытаетÑÑ Ð²Ñ‹Ð´Ð°Ñ‚ÑŒ ÑÐµÐ±Ñ Ð·Ð° <ph name="SITE" />, либо Ñтраница Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñети Wi-Fi прервала Ñоединение. Ваша Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾-прежнему в безопаÑноÑти, так как браузер Chromium разорвал Ñоединение до того, как произошел обмен данными.</translation>
@@ -862,16 +938,21 @@
<translation id="9148507642005240123">&amp;Отменить изменениÑ</translation>
<translation id="9154194610265714752">Обновлено</translation>
<translation id="9157595877708044936">ÐаÑтройка...</translation>
+<translation id="9169664750068251925">Ð’Ñегда блокировать на Ñтом Ñайте</translation>
<translation id="9170848237812810038">&amp;Отменить</translation>
<translation id="917450738466192189">Сертификат Ñервера недейÑтвителен</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}many{<ph name="SHIPPING_OPTION_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> и ещё <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419">Ðа Ñайте <ph name="HOST_NAME" /> иÑпользуетÑÑ Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ñ‹Ð¹ протокол.</translation>
<translation id="9205078245616868884">Данные зашифрованы Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ кодовой фразы. Введите ее, чтобы начать Ñинхронизацию.</translation>
<translation id="9207861905230894330">Ðе удалоÑÑŒ добавить Ñтатью</translation>
+<translation id="9219103736887031265">Картинки</translation>
<translation id="933612690413056017">Ðет Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Интернету</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ОЧИСТИТЬ ФОРМУ</translation>
<translation id="939736085109172342">ÐÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°</translation>
<translation id="941721044073577244">Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому Ñайту требуетÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ</translation>
<translation id="969892804517981540">ÐžÑ„Ð¸Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ñборка</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ðет}=1{1 запиÑÑŒ}one{# запиÑÑŒ}few{# запиÑи}many{# запиÑей}other{# запиÑи}}</translation>
<translation id="988159990683914416">Сборка Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð²</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sk.xtb b/chromium/components/strings/components_strings_sk.xtb
index f2dc2971e9f..d329c618e89 100644
--- a/chromium/components/strings/components_strings_sk.xtb
+++ b/chromium/components/strings/components_strings_sk.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">OtoÄiÅ¥ v smere hodinových ruÄiÄiek</translation>
<translation id="1038842779957582377">neznámy názov</translation>
<translation id="1050038467049342496">Zavrite ostatné aplikácie</translation>
-<translation id="1053591932240354961">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože vrátil zakódované poverenia, ktoré Google Chrome nedokáže spracovaÅ¥. Chyby siete a útoky sú zvyÄajne doÄasné, takže by táto stránka mala neskôr pravdepodobne fungovaÅ¥. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;Vrátiť späť pridanie</translation>
<translation id="10614374240317010">Neuložené</translation>
<translation id="106701514854093668">Záložky plochy</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Vyrovnávacia pamäť pravidla je v poriadku</translation>
<translation id="113188000913989374">Web <ph name="SITE" /> hovorí:</translation>
<translation id="1132774398110320017">Nastavenia Automatického dopĺňania prehliadaÄa Chrome...</translation>
+<translation id="1150979032973867961">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, operaÄný systém vášho poÄítaÄa nedôveruje jej bezpeÄnostnému certifikátu. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
+<translation id="1151972924205500581">Vyžaduje sa heslo</translation>
<translation id="1152921474424827756">Prístup ku <ph name="BEGIN_LINK" />kópii vo vyrovnávacej pamäti<ph name="END_LINK" /> stránky <ph name="URL" /></translation>
<translation id="1158211211994409885">Hostiteľský web <ph name="HOST_NAME" /> neoÄakávane ukonÄil pripojenie.</translation>
<translation id="1161325031994447685">Znovu sa pripojiť k sieti Wi-Fi</translation>
+<translation id="1165039591588034296">Chyba</translation>
<translation id="1175364870820465910">&amp;TlaÄiÅ¥...</translation>
<translation id="1181037720776840403">Odstrániť</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Automaticky nahlasovaÅ¥<ph name="END_WHITEPAPER_LINK" /> Googlu podrobnosti o možných problémoch so zabezpeÄením. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Viac z týchto stránok</translation>
<translation id="1206967143813997005">Chybný úvodný podpis</translation>
<translation id="1209206284964581585">Skryť</translation>
+<translation id="121201262018556460">Pokúsili ste sa o prístup na stránky <ph name="DOMAIN" />, server vÅ¡ak predložil certifikát obsahujúci slabý kľúÄ. ÚtoÄník mohol tento súkromný kÄ¾ÃºÄ prelomiÅ¥ a môže ísÅ¥ o iný server, než ste oÄakávali (môžete komunikovaÅ¥ s útoÄníkom).</translation>
<translation id="1219129156119358924">ZabezpeÄenie systému</translation>
<translation id="1227224963052638717">Neznáme pravidlo.</translation>
<translation id="1227633850867390598">Skryť hodnotu</translation>
<translation id="1228893227497259893">Nesprávny identifikátor entity</translation>
<translation id="1232569758102978740">Bez názvu</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronizované)</translation>
<translation id="1263231323834454256">Čitateľský zoznam</translation>
<translation id="1264126396475825575">Správa o zlyhaní bola zaznamenaná v Äase <ph name="CRASH_TIME" /> (eÅ¡te nebola nahraná ani ignorovaná)</translation>
+<translation id="1281526147609854549">Vydavateľ: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Zablokovaný nebezpeÄný obsah</translation>
<translation id="1285320974508926690">Nikdy neprekladať tieto webové stránky</translation>
<translation id="129553762522093515">Naposledy zatvorené</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Skúste vymazať súbory cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Vašu aktivitu <ph name="BEGIN_EMPHASIS" />stále môžu vidieť<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />navštívené weby
+ <ph name="LIST_ITEM" />váš zamestnávateľ alebo škola
+ <ph name="LIST_ITEM" />váš poskytovateľ internetu
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Doména registrácie:</translation>
<translation id="1340482604681802745">Adresa vyzdvihnutia</translation>
<translation id="1344211575059133124">Zdá sa, že prístup na tento web si vyžaduje povolenie</translation>
<translation id="1344588688991793829">Nastavenia Automatického dopĺňania prehliadaÄa Chromium...</translation>
+<translation id="1348198688976932919">Web, ktorý chcete otvoriÅ¥, obsahuje nebezpeÄné aplikácie</translation>
<translation id="1374468813861204354">návrhy</translation>
<translation id="1375198122581997741">Informácie o verzii</translation>
<translation id="1377321085342047638">Číslo karty</translation>
<translation id="139305205187523129">Web <ph name="HOST_NAME" /> neodoslal žiadne údaje.</translation>
<translation id="1407135791313364759">Otvoriť všetko</translation>
<translation id="1413809658975081374">Chyba v ochrane osobných údajov</translation>
+<translation id="14171126816530869">Identita spoloÄnosti <ph name="ORGANIZATION" /> so sídlom <ph name="LOCALITY" /> bola overená spoloÄnosÅ¥ou <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ãno</translation>
<translation id="1430915738399379752">TlaÄiÅ¥</translation>
-<translation id="1442912890475371290">Zablokovaný pokus <ph name="BEGIN_LINK" /> o návštevu stránky na doméne <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože používa pripínanie certifikátov. Chyby siete a útoky sú zvyÄajne doÄasné, takže by táto stránka mala neskôr pravdepodobne fungovaÅ¥. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> Äalší}few{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ÄalÅ¡ie}many{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ÄalÅ¡ieho}other{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> Äalších}}</translation>
<translation id="1506687042165942984">Zobrazí sa uložená (t. j. neaktuálna) kópia tejto stránky.</translation>
<translation id="1517433312004943670">Vyžaduje sa telefónne Äíslo</translation>
<translation id="1519264250979466059">Dátum zostavenia</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Ak chcete použiť túto funkciu, musíte povoliť JavaScript.</translation>
<translation id="1555130319947370107">Modrá</translation>
<translation id="1559528461873125649">Neexistuje žiadny takýto súbor ani prieÄinok</translation>
-<translation id="1559572115229829303">&lt;p&gt;Súkromné pripojenie k doméne <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazaÅ¥, pretože dátum a Äas (<ph name="DATE_AND_TIME" />) vášho zariadenia sú nesprávne.&lt;/p&gt;
-
- &lt;p&gt;Dátum a Äas upravte v aplikácii &lt;strong&gt;Nastavenia&lt;/strong&gt; v sekcii &lt;strong&gt;VÅ¡eobecné&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Pri zobrazovaní tejto webovej stránky sa vyskytla chyba.</translation>
<translation id="1592005682883173041">Prístup k miestnym údajom</translation>
+<translation id="1594030484168838125">Zvoliť</translation>
<translation id="161042844686301425">Azúrová</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Chcete, aby Chrome uložil túto kartu?</translation>
<translation id="1639239467298939599">Prebieha naÄítavanie</translation>
<translation id="1640180200866533862">Pravidlá pre používateľa</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Konfigurácia siete je neplatná a nepodarilo sa ju importovať.</translation>
<translation id="1644574205037202324">História</translation>
<translation id="1645368109819982629">Nepodporovaný protokol</translation>
+<translation id="1655462015569774233">{1,plural, =1{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala vÄera. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku.}few{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala pred # dňami. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku.}many{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala pred # dňom. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku.}other{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala pred # dňami. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku.}}</translation>
<translation id="1656489000284462475">Vyzdvihnutie</translation>
<translation id="1663943134801823270">Karty a adresy pochádzajú z Chromu. Môžete ich spravovať v <ph name="BEGIN_LINK" />Nastaveniach<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Web <ph name="SITE" /> zvyÄajne chráni vaÅ¡e informácie pomocou Å¡ifrovania. KeÄ sa Chrome tentokrát pokúsil pripojiÅ¥ k webu <ph name="SITE" />, odoslal späť nezvyÄajné a nesprávne poverenia. Môže sa to staÅ¥ vtedy, keÄ sa za web <ph name="SITE" /> snaží vydávaÅ¥ útoÄník alebo keÄ pripojenie preruší prihlasovacia obrazovka siete Wi-Fi. VaÅ¡e informácie sú stále zabezpeÄené, pretože Chrome zastavil pripojenie eÅ¡te pred výmenou dát.</translation>
-<translation id="168328519870909584">ÚtoÄníci, ktorí sú práve na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, sa možno pokúsia nainÅ¡talovaÅ¥ na vaÅ¡e zariadenie nebezpeÄné programy, ktoré ukradnú alebo odstránia vaÅ¡e informácie, napríklad fotky, heslá, správy alebo kreditné karty.</translation>
<translation id="168841957122794586">Certifikát servera obsahuje slabý kryptografický kľúÄ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ od zajtra. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom.}few{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ o # dni. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom.}many{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ o # dňa. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom.}other{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ o # dní. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Ak chcete navštíviť tento web, potrebujete povolenie od správcu <ph name="NAME" /></translation>
<translation id="1721424275792716183">* Toto pole je povinné</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Stiahnuť stránku neskôr</translation>
<translation id="17513872634828108">Otvorené karty</translation>
<translation id="1753706481035618306">Číslo stránky</translation>
+<translation id="1763864636252898013">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, operaÄný systém vášho zariadenia nedôveruje jej bezpeÄnostnému certifikátu. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Skúste spustiť nástroj Diagnostika siete systému Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Aktualizujte prístupovú frázu na synchronizáciu.</translation>
<translation id="1787142507584202372">Tu sa zobrazia otvorené karty</translation>
+<translation id="1789575671122666129">Kontextové okná</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Meno majiteľa karty</translation>
-<translation id="1803678881841855883">Funkcia BezpeÄné prehliadanie Google nedávno <ph name="BEGIN_LINK" />zistila malvér<ph name="END_LINK" /> na webe <ph name="SITE" />. Weby, ktoré sú zvyÄajne bezpeÄné, môžu byÅ¥ niekedy nakazené malvérom. Å kodlivý obsah pochádza od hostiteľa <ph name="SUBRESOURCE_HOST" />, ktorý je známym distribútorom malvéru. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">Pridané <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Neplatná žiadosť alebo parametre žiadosti</translation>
<translation id="1826516787628120939">Kontroluje sa</translation>
<translation id="1834321415901700177">Tento web obsahuje škodlivé programy</translation>
+<translation id="1840414022444569775">Toto Äíslo karty sa už používa</translation>
<translation id="1842969606798536927">Zaplatiť</translation>
<translation id="1871208020102129563">Proxy je nastavené na použitie pevne daných serverov proxy, nie skriptov PAC webovej adresy.</translation>
<translation id="1871284979644508959">Povinné pole</translation>
<translation id="187918866476621466">Otvoriť stránky pri spustení</translation>
<translation id="1883255238294161206">Zbaliť zoznam</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ÄalÅ¡ia}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ÄalÅ¡ie}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> ÄalÅ¡ej}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> Äalších}}</translation>
<translation id="1898423065542865115">Filtrovanie</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Žiadne}=1{1 web}few{# weby}many{# webu}other{# webov}}</translation>
<translation id="194030505837763158">Prejdite na stránku <ph name="LINK" /></translation>
<translation id="1962204205936693436">Záložky (<ph name="DOMAIN" />)</translation>
<translation id="1973335181906896915">Chyba serializácie</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignorované, pretože bolo prepísané pravidlom <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Vyhľadávajú sa stránky Fyzického webu v okolí</translation>
<translation id="213826338245044447">Záložky v mobile</translation>
-<translation id="2148716181193084225">Dnes</translation>
+<translation id="2147827593068025794">Synchronizácia na pozadí</translation>
<translation id="2154054054215849342">Synchronizácia nie je pre vašu doménu k dispozícii</translation>
<translation id="2154484045852737596">Úprava karty</translation>
<translation id="2166049586286450108">Úplný prístup správcu</translation>
<translation id="2166378884831602661">Tento web nedokáže poskytnúť zabezpeÄené pripojenie</translation>
<translation id="2181821976797666341">Pravidlá</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresa}few{# adresy}many{# adresy}other{# adries}}</translation>
+<translation id="2187317261103489799">Rozpoznávať (predvolené)</translation>
<translation id="2202020181578195191">Zadajte platný rok vypršania platnosti</translation>
<translation id="2212735316055980242">Pravidlo sa nenašlo</translation>
<translation id="2213606439339815911">NaÄítavanie záznamov...</translation>
+<translation id="2218879909401188352">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> by mohli nainÅ¡talovaÅ¥ nebezpeÄné aplikácie, ktoré poÅ¡kodia vaÅ¡e zariadenia, pridaÅ¥ skryté poplatky do vaÅ¡ej faktúry za mobilné služby alebo ukradnúť vaÅ¡e osobné informácie. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Opravte svoje pripojenie pomocou <ph name="BEGIN_LINK" />diagnostickej aplikácie<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Odoslať</translation>
<translation id="225207911366869382">Táto hodnota už pre toto pravidlo nie je podporovaná.</translation>
<translation id="2262243747453050782">Chyba protokolu HTTP</translation>
+<translation id="2270484714375784793">Telefónne Äíslo</translation>
<translation id="2282872951544483773">Nedostupné experimenty</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> položka}few{<ph name="ITEM_COUNT" /> položky}many{<ph name="ITEM_COUNT" /> položky}other{<ph name="ITEM_COUNT" /> položiek}}</translation>
<translation id="2292556288342944218">Váš prístup k internetu je blokovaný</translation>
<translation id="230155334948463882">Nová karta?</translation>
-<translation id="2305919008529760154">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; bezpeÄnostný certifikát mohol byÅ¥ vydaný podvodným spôsobom. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535">Doména <ph name="DOMAIN" /> vyžaduje používateľské meno a heslo.</translation>
-<translation id="2318774815570432836">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože používa pravidlo HSTS. Chyby siete a útoky sú zvyÄajne doÄasné, takže by táto stránka mala neskôr pravdepodobne fungovaÅ¥. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Nastavenie ovládané správcom</translation>
<translation id="2354001756790975382">Iné záložky</translation>
+<translation id="2354430244986887761">Funkcia BezpeÄné prehliadanie Google nedávno <ph name="BEGIN_LINK" />naÅ¡la Å¡kodlivé aplikácie<ph name="END_LINK" /> na webe <ph name="SITE" />.</translation>
<translation id="2355395290879513365">ÚtoÄníci môžu vidieÅ¥ obrázky, ktoré si prehliadate na tomto webe, a môžu vás napadnúť tým, že ich podvodným spôsobom upravia.</translation>
+<translation id="2356070529366658676">Opýtať sa</translation>
+<translation id="2359629602545592467">Viaceré</translation>
<translation id="2359808026110333948">PokraÄovaÅ¥</translation>
<translation id="2365563543831475020">Správa o zlyhaní zaznamenaná v Äase <ph name="CRASH_TIME" /> nebola nahraná</translation>
<translation id="2367567093518048410">Úroveň</translation>
-<translation id="2371153335857947666">{1,plural, =1{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala vÄera. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}few{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala pred # dňami. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}many{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala pred # dňom. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}other{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; platnosÅ¥ jej bezpeÄnostného certifikátu vyprÅ¡ala pred # dňami. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. Hodiny vášho poÄítaÄa sú momentálne nastavené na <ph name="CURRENT_DATE" />. Je tento Äas správny? Ak nie, opravte Äas na hodinách systému a potom obnovte túto stránku. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">Nie sú k dispozícii žiadne alternatívy používateľského rozhrania</translation>
<translation id="2384307209577226199">Predvolené nastavenie na podnikovej úrovni</translation>
<translation id="2386255080630008482">Certifikát servera bol zrušený.</translation>
<translation id="2392959068659972793">Zobraziť pravidlá bez nastavenej hodnoty</translation>
<translation id="239429038616798445">Tento spôsob dodania nie je k dispozícii. Skúste inú možnosť.</translation>
<translation id="2396249848217231973">&amp;Vrátiť späť odstránenie</translation>
-<translation id="2460160116472764928">Funkcia BezpeÄné prehliadanie Google nedávno <ph name="BEGIN_LINK" />zistila malvér<ph name="END_LINK" /> na webe <ph name="SITE" />. Weby, ktoré sú zvyÄajne bezpeÄné, môžu byÅ¥ niekedy nakazené malvérom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, jej bezpeÄnostný certifikát bol zrejme zruÅ¡ený. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
<translation id="2463739503403862330">Vyplniť</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Spustiť nástroj Diagnostika siete<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Neplatná webová adresa vyhľadávania.</translation>
+<translation id="2482878487686419369">Upozornenia</translation>
<translation id="2491120439723279231">Certifikát servera obsahuje chyby.</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2495093607237746763">Ak je toto nastavenie zaÄiarknuté, Chromium uloží na tomto zariadení kópiu karty, aby ste mohli rýchlejÅ¡ie vypĺňaÅ¥ formuláre.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Prejsť späť</translation>
<translation id="2515629240566999685">Skontrolovať signál vo vašej oblasti</translation>
<translation id="2516305470678292029">Alternatívy používateľského rozhrania</translation>
+<translation id="2539524384386349900">Rozpoznávať</translation>
<translation id="255002559098805027">Web <ph name="HOST_NAME" /> odoslal neplatnú odpoveÄ.</translation>
-<translation id="2552545117464357659">Novšie</translation>
<translation id="2556876185419854533">&amp;Vrátiť späť úpravu</translation>
<translation id="2587730715158995865">Od vydavateľa <ph name="ARTICLE_PUBLISHER" />. PreÄítajte si tento príbeh a ÄalÅ¡ie (<ph name="OTHER_ARTICLE_COUNT" />).</translation>
<translation id="2587841377698384444">Identifikátor prieÄinka API:</translation>
<translation id="2597378329261239068">Tento dokument je chránený heslom. Zadajte heslo.</translation>
<translation id="2609632851001447353">Variácie</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Žiadne}=1{1 aplikácia ($1)}=2{2 aplikácie ($1, $2)}few{# aplikácie ($1, $2, $3)}many{# aplikácie ($1, $2, $3)}other{# aplikácií ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Vaše hodiny idú dopredu</translation>
<translation id="2639739919103226564">Stav:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Prístup k súboru bol odmietnutý</translation>
<translation id="2653659639078652383">Odoslať</translation>
<translation id="2666117266261740852">Zavrite ostatné karty alebo aplikácie</translation>
+<translation id="2670429602441959756">Táto stránka obsahuje funkcie, ktoré zatiaľ nie sú podporované v režime VR. Režim sa ukonÄuje…</translation>
<translation id="2674170444375937751">Naozaj chcete odstrániť tieto stránky zo svojej histórie?</translation>
<translation id="2677748264148917807">Opustiť</translation>
-<translation id="269990154133806163">Server predložil certifikát, ktorý nebol zverejnený pomocou pravidla transparentnosti certifikátov. V prípade niektorých certifikátov sa táto podmienka vyžaduje s cieľom zaistiÅ¥ ich dôveryhodnosÅ¥ a ochranu proti útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">Čitateľský zoznam</translation>
<translation id="2704283930420550640">Hodnota nezodpovedá formátu.</translation>
<translation id="2704951214193499422">PrehliadaÄu Chromium sa nepodarilo overiÅ¥ vaÅ¡u kartu. Skúste to znova neskôr.</translation>
<translation id="2705137772291741111">Uložená kópia tohto webu (vo vyrovnávacej pamäti) bola neÄitateľná.</translation>
<translation id="2709516037105925701">Automatické dopĺňanie</translation>
-<translation id="2712118517637785082">Pokúsili ste sa prejsÅ¥ do domény <ph name="DOMAIN" />, ale certifikát predložený serverom bol zruÅ¡ený vydavateľom. Znamená to, že povereniam zabezpeÄenia predloženým serverom sa nedá celkom dôverovaÅ¥. Je možné, že komunikujete s útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Požiadať o povolenie</translation>
<translation id="2713444072780614174">Biela</translation>
<translation id="2720342946869265578">Nablízku</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Chýbajúci záznam zariadenia</translation>
<translation id="2784949926578158345">Spojenie bolo obnovené.</translation>
<translation id="2794233252405721443">Web je blokovaný</translation>
+<translation id="2799020568854403057">Web, ktorý chcete otvoriť, obsahuje škodlivé aplikácie</translation>
+<translation id="2803306138276472711">Funkcia BezpeÄné prehliadanie Google nedávno <ph name="BEGIN_LINK" />zistila malvér<ph name="END_LINK" /> na stránkach <ph name="SITE" />. Webové stránky, ktoré sú zvyÄajne bezpeÄné, môžu byÅ¥ niekedy nakazené malvérom.</translation>
<translation id="2824775600643448204">Panel s adresou a vyhľadávací panel</translation>
<translation id="2826760142808435982">Pripojenie je Å¡ifrované pomocou Å¡tandardu <ph name="CIPHER" /> a používa mechanizmus výmeny kľúÄov <ph name="KX" />.</translation>
<translation id="2835170189407361413">Vymazať formulár</translation>
+<translation id="2856444702002559011">ÚtoÄníci sa môžu pokúsiÅ¥ ukradnúť vaÅ¡e informácie z webu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (napríklad heslá, správy alebo kreditné karty). <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">NenaÄítaÅ¥ znova</translation>
<translation id="2900469785430194048">Pri pokuse o zobrazenie tejto webovej stránky doÅ¡lo miesto v pamäti prehliadaÄa Google Chrome.</translation>
<translation id="2909946352844186028">Zistila sa zmena siete.</translation>
<translation id="2916038427272391327">Zavrite ostatné programy</translation>
<translation id="2922350208395188000">Certifikát servera sa nedá overiť.</translation>
<translation id="2928905813689894207">FakturaÄná adresa</translation>
+<translation id="2941952326391522266">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, jej bezpeÄnostný certifikát pochádza z domény <ph name="DOMAIN2" />. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
<translation id="2948083400971632585">Môžete zakázať ktorékoľvek servery proxy nakonfigurované na pripojenie na stránke nastavení.</translation>
<translation id="2955913368246107853">Zatvoriť panel pre vyhľadávanie</translation>
<translation id="2958431318199492670">Konfigurácia siete nie je v súlade so Å¡tandardom ONC. Niektoré Äasti konfigurácie sa nemusia importovaÅ¥.</translation>
-<translation id="29611076221683977">ÚtoÄníci, ktorí sú práve na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, sa možno pokúsia nainÅ¡talovaÅ¥ na váš poÄítaÄ nebezpeÄné programy, ktoré ukradnú alebo odstránia vaÅ¡e informácie, napríklad fotky, heslá, správy alebo kreditné karty.</translation>
<translation id="2966678944701946121">Platnosť do <ph name="EXPIRATION_DATE_ABBR" />, pridané <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Ak chcete nadviazaÅ¥ zabezpeÄené pripojenie, vaÅ¡e hodiny musia byÅ¥ nastavené správne. Je to preto, že certifikáty, ktoré webové stránky používajú na vlastnú identifikáciu, sú platné iba urÄitý Äas. KeÄže nie sú hodiny vášho zariadenia nastavené správne, Chrome nemôže tieto certifikáty overiÅ¥.</translation>
<translation id="2972581237482394796">&amp;Dopredu</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Zadajte platnú adresu</translation>
<translation id="2986368408720340940">Tento spôsob vyzdvihnutia nie je k dispozícii. Skúste iný spôsob.</translation>
<translation id="2991174974383378012">Zdieľanie s webmi</translation>
+<translation id="2991571918955627853">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože používa certifikát HSTS. Chyby siete a útoky sú zvyÄajne doÄasné, takže by táto stránka mala neskôr pravdepodobne fungovaÅ¥.</translation>
<translation id="3005723025932146533">Zobraziť uloženú kópiu</translation>
<translation id="3008447029300691911">Zadajte kód CVC karty <ph name="CREDIT_CARD" />. Po potvrdení budú podrobnosti o karte zdieľané s týmto webom.</translation>
<translation id="3010559122411665027">Položka zoznamu „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Automaticky blokované</translation>
<translation id="3024663005179499861">Chybný typ pravidla</translation>
<translation id="3032412215588512954">Chcete tento web naÄítaÅ¥ znova?</translation>
<translation id="3037605927509011580">Aj, chyba!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{aspoň jedna položka v synchronizovaných zariadeniach}=1{1 položka (a ÄalÅ¡ie v synchronizovaných zariadeniach)}few{# položky (a ÄalÅ¡ie v synchronizovaných zariadeniach)}many{# položky (a ÄalÅ¡ie v synchronizovaných zariadeniach)}other{# položiek (a ÄalÅ¡ie v synchronizovaných zariadeniach)}}</translation>
<translation id="3041612393474885105">Informácie o certifikáte</translation>
<translation id="3063697135517575841">Chromu sa nepodarilo overiť vašu kartu. Skúste to znova neskôr.</translation>
<translation id="3064966200440839136">Ak zaplatíte pomocou externej aplikácie, opustíte režim inkognito. Chcete pokraÄovaÅ¥?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Žiadne}=1{1 heslo}few{# heslá}many{# hesla}other{# hesiel}}</translation>
<translation id="3093245981617870298">Ste v režime offline.</translation>
<translation id="3105172416063519923">Identifikátor obsahu:</translation>
<translation id="3109728660330352905">Nemáte povolenie na zobrazenie tejto stránky.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Skúste spustiť nástroj Diagnostika konektivity<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">OdpoveÄ sa nepodarilo dekódovaÅ¥</translation>
<translation id="3150653042067488994">DoÄasná chyba servera</translation>
@@ -247,13 +277,17 @@
<translation id="3167968892399408617">KeÄ zavriete vÅ¡etky karty inkognito, po stránkach, ktoré ste na nich zobrazili, nezostane v histórii prehliadania, úložisku súborov cookie a histórii vyhľadávania ani stopa. VÅ¡etky stiahnuté súbory a vytvorené záložky zostanú zachované.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ostrov</translation>
+<translation id="317583078218509884">Nové nastavenia povolení webových stránok sa prejavia po opätovnom naÄítaní stránky.</translation>
<translation id="3176929007561373547">Skontrolujte nastavenia proxy servera alebo kontaktujte správcu siete a požiadajte ho, aby skontroloval, Äi proxy server funguje. Ak sa domnievate, že by ste nemali používaÅ¥ proxy server: <ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Otvorte stránku v režime inkognito</translation>
-<translation id="3202578601642193415">Najnovšie</translation>
+<translation id="320323717674993345">Zrušiť platbu</translation>
<translation id="3207960819495026254">Pridané medzi záložky</translation>
+<translation id="3225919329040284222">Server sa preukázal certifikátom, ktorý nezodpovedá integrovaným oÄakávaniam. Tieto oÄakávania sú kvôli vaÅ¡ej ochrane zahrnuté pri urÄitých webových stránkach s vysokou úrovňou zabezpeÄenia.</translation>
<translation id="3226128629678568754">StlaÄením tlaÄidla opakovaného spustenia znova odoÅ¡lete údaje potrebné na naÄítanie stránky.</translation>
+<translation id="3227137524299004712">Mikrofón</translation>
<translation id="3228969707346345236">Prekladanie zlyhalo, pretože stránka už je v jazyku: <ph name="LANGUAGE" /></translation>
<translation id="323107829343500871">Zadajte kód CVC karty <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Vždy na týchto stránkach zisťovať dôležitý obsah</translation>
<translation id="3254409185687681395">Vytvoriť záložku pre túto stránku</translation>
<translation id="3270847123878663523">&amp;Vrátiť späť zmenu poradia</translation>
<translation id="3282497668470633863">Pridanie mena na karte</translation>
@@ -267,42 +301,48 @@
<translation id="3340978935015468852">nastavenia</translation>
<translation id="3345135638360864351">Vašu žiadosť o prístup k týmto webovým stránkam sa používateľovi <ph name="NAME" /> neporadilo odoslať. Skúste to znova neskôr.</translation>
<translation id="3355823806454867987">Zmeniť nastavenia proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />nebude ukladať<ph name="END_EMPHASIS" /> tieto informácie:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />vašu históriu prehliadania
+ <ph name="LIST_ITEM" />súbory cookie a dáta webov
+ <ph name="LIST_ITEM" />údaje zadané do formulárov
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Chyba hodín</translation>
-<translation id="337311366426640088">Ďalšie položky (<ph name="ITEM_COUNT" />)…</translation>
<translation id="337363190475750230">Odstránené</translation>
<translation id="3377188786107721145">Chyba analýzy pravidla</translation>
<translation id="3380365263193509176">Neznáma chyba</translation>
<translation id="3380864720620200369">ID klienta:</translation>
<translation id="3391030046425686457">DoruÄovacia adresa</translation>
<translation id="3395827396354264108">Spôsob vyzdvihnutia</translation>
-<translation id="340013220407300675">ÚtoÄníci sa možno pokúšajú ukradnúť vaÅ¡e informácie zo stránok <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (napríklad heslá, správy alebo informácie o kreditných kartách).</translation>
<translation id="3422248202833853650">Skúste ukonÄiÅ¥ ostatné programy a uvoľniÅ¥ tak miesto v pamäti.</translation>
<translation id="3422472998109090673">Web <ph name="HOST_NAME" /> nie je momentálne k dispozícii.</translation>
+<translation id="3427092606871434483">Povoliť (predvolené)</translation>
<translation id="3427342743765426898">&amp;Znova upraviť</translation>
<translation id="3431636764301398940">Uložiť túto kartu na zariadení</translation>
<translation id="3435896845095436175">Aktivovať</translation>
<translation id="3447661539832366887">Vlastník tohto zariadenia vypol hru Dinosaur.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Interval naÄítania:</translation>
<translation id="3462200631372590220">Skryť rozšírené podrobnosti</translation>
<translation id="3467763166455606212">Meno majiteľa karty je povinný údaj</translation>
<translation id="3478058380795961209">Mesiac vypršania platnosti</translation>
<translation id="3479539252931486093">NeoÄakávali ste to? <ph name="BEGIN_LINK" />Dajte nám vedieÅ¥<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Teraz nie</translation>
-<translation id="348000606199325318">ID zlyhania <ph name="CRASH_LOCAL_ID" /> (ID servera: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">V tejto chvíli sa nám nepodarilo spojiÅ¥ s vaším rodiÄom. Skúste to znova neskôr.</translation>
<translation id="3528171143076753409">Certifikát servera nie je dôveryhodný.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Aspoň 1 položka v synchronizovaných zariadeniach}=1{1 položka (a ÄalÅ¡ie v synchronizovaných zariadeniach)}few{# položky (a ÄalÅ¡ie v synchronizovaných zariadeniach)}many{# položky (a ÄalÅ¡ie v synchronizovaných zariadeniach)}other{# položiek (a ÄalÅ¡ie v synchronizovaných zariadeniach)}}</translation>
<translation id="3539171420378717834">Ponechať kópiu tejto karty na tomto zariadení</translation>
<translation id="3542684924769048008">Použiť heslo pre:</translation>
+<translation id="3545341443414427877">S doménou <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazaÅ¥ súkromné pripojenie, pretože dátum a Äas (<ph name="DATE_AND_TIME" />) vo vaÅ¡om poÄítaÄi sú nesprávne. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Šifrovať všetky synchronizované údaje pomocou vlastnej prístupovej frázy pre synchronizáciu</translation>
-<translation id="3549761410225185768">Ďalšie: <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej bezpeÄnostný certifikát pochádza z domény <ph name="DOMAIN2" />. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">Váš správca ho môže pre vás odblokovať</translation>
<translation id="3566021033012934673">Vaše pripojenie nie je súkromné</translation>
+<translation id="3569145463236695319">&lt;p&gt;S doménou <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazaÅ¥ súkromné pripojenie, pretože dátum a Äas (<ph name="DATE_AND_TIME" />) vo vaÅ¡om zariadení sú nesprávne.&lt;/p&gt;
+
+ &lt;p&gt;Dátum a Äas upravte v aplikácii &lt;strong&gt;Nastavenia&lt;/strong&gt; v Äasti &lt;strong&gt;VÅ¡eobecné&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Pridajte meno</translation>
<translation id="3583757800736429874">&amp;Znova presunúť</translation>
<translation id="3586931643579894722">Skryť podrobnosti</translation>
-<translation id="3587482841069643663">VÅ¡etko</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Zadajte správny dátum vypršania platnosti</translation>
<translation id="36224234498066874">Vymazať údaje prehliadania...</translation>
@@ -318,7 +358,6 @@
<translation id="3681007416295224113">Informácie o certifikáte</translation>
<translation id="3690164694835360974">Prihlásenie nie je zabezpeÄené</translation>
<translation id="3693415264595406141">Heslo:</translation>
-<translation id="3696411085566228381">žiadne</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">NaÄítava sa...</translation>
<translation id="3712624925041724820">VyÄerpané licencie</translation>
@@ -326,12 +365,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Skontrolovať proxy server, bránu firewall a konfiguráciu DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Ak si uvedomujete bezpeÄnostné riziko, môžete <ph name="BEGIN_LINK" />tieto nebezpeÄné stránky navÅ¡tíviÅ¥<ph name="END_LINK" /> eÅ¡te skôr, ako budú nebezpeÄné programy odstránené.</translation>
<translation id="3739623965217189342">Skopírovaný odkaz</translation>
+<translation id="3744899669254331632">Webové stránky <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože odoslali zakódované poverenia, ktoré Chromium neodkáže spracovaÅ¥. Chyby siete a útoky sú zvyÄajne doÄasné, takže táto stránka by mala pravdepodobne neskôr fungovaÅ¥.</translation>
+<translation id="3748148204939282805">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vás môžu oklamaÅ¥, aby ste urobili nieÄo nebezpeÄné, napríklad nainÅ¡talovali softvér alebo odhalili svoje osobné informácie (napríklad heslá, telefónne Äísla a kreditné karty). <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Preklad zlyhal v dôsledku chyby servera.</translation>
<translation id="3759461132968374835">Nemáte žiadne nedávno nahlásené zlyhania. Na tejto stránke sa nezobrazujú zlyhania, ktoré nastali pri zakázanej možnosti hlásení zlyhaní.</translation>
+<translation id="3778403066972421603">Chcete uložiÅ¥ túto kartu do svojho úÄtu Google a tohto zariadenia?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Platnosť vyprší <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Ak používate server proxy...</translation>
<translation id="3828924085048779000">Prístupová fráza nemôže byť prázdna.</translation>
-<translation id="3845539888601087042">Zobrazuje sa história zo zariadení, na ktorých ste prihlásený/-á. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Naspäť</translation>
<translation id="3858027520442213535">AktualizovaÅ¥ dátum a Äas</translation>
<translation id="3884278016824448484">Kolidujúci identifikátor zariadenia</translation>
@@ -339,11 +381,13 @@
<translation id="3886446263141354045">Vaša žiadosť o prístup na tento web sa odoslala správcovi <ph name="NAME" /></translation>
<translation id="3890664840433101773">Pridanie e-mailu</translation>
<translation id="3901925938762663762">Platnosť karty vypršala</translation>
-<translation id="3933571093587347751">{1,plural, =1{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ od zajtra. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}few{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ o # dni. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}many{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ o # dňa. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}other{Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej certifikát by mal zaÄaÅ¥ platiÅ¥ o # dní. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">NaÄítanie dokumentu PDF zlyhalo</translation>
+<translation id="3945915738023014686">Identifikátor nahranej správy o zlyhaní: <ph name="CRASH_ID" /> (ID miestneho zlyhania: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Tento server nedokázal potvrdiÅ¥, Äi ide o doménu <ph name="DOMAIN" /> – prísluÅ¡ný bezpeÄnostný certifikát neuvádza alternatívne názvy predmetu. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie napadol útoÄník.</translation>
<translation id="3963721102035795474">Režim ÄítaÄky</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Žiadne}=1{Z 1 webu }few{Z # webov }many{Z # webu }other{Z # webov }}</translation>
<translation id="397105322502079400">Prebieha výpoÄet...</translation>
<translation id="3973234410852337861">Web <ph name="HOST_NAME" /> je zablokovaný</translation>
+<translation id="3987940399970879459">Menej ako 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 webová stránka v okolí}few{# webové stránky v okolí}many{# webovej stránky v okolí}other{# webových stránok v okolí}}</translation>
<translation id="4021036232240155012">DNS je sieťová služba, ktorá preloží názov webu do jeho internetovej adresy.</translation>
<translation id="4030383055268325496">&amp;Vrátiť späť pridanie</translation>
@@ -354,56 +398,63 @@
<translation id="4079302484614802869">Konfigurácia proxy je nastavená na použitie skriptu PAC webovej adresy, nie pevne daných serverov proxy.</translation>
<translation id="4098354747657067197">Nasledujúce stránky sú klamlivé</translation>
<translation id="4103249731201008433">Sériové Äíslo zariadenia je neplatné</translation>
+<translation id="410351446219883937">Automatické prehrávanie</translation>
<translation id="4103763322291513355">Na stránke &lt;strong&gt;chrome://policy&lt;/strong&gt; nájdete zoznam zakázaných webových adries a ÄalÅ¡ie pravidlá vynútené vaším správcom systému.</translation>
-<translation id="4110615724604346410">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej bezpeÄnostný certifikát obsahuje chyby. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">Purpurová</translation>
+<translation id="4116663294526079822">Vždy povoliť na týchto stránkach</translation>
<translation id="4117700440116928470">Rozsah pravidla nie je podporovaný.</translation>
-<translation id="4118212371799607889">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; Chromium nedôveruje jej bezpeÄnostnému certifikátu. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 ÄalÅ¡ia}few{# ÄalÅ¡ie}many{# ÄalÅ¡ej}other{# Äalších}}</translation>
<translation id="4130226655945681476">SkontrolovaÅ¥ sieÅ¥ové káble, modem a smerovaÄ</translation>
+<translation id="413544239732274901">Ďalšie informácie</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Použiť globálne predvolené nastavenie (zistiť)</translation>
+<translation id="4165986682804962316">Nastavenia webu</translation>
<translation id="4169947484918424451">Chcete, aby Chromium uložil túto kartu?</translation>
<translation id="4171400957073367226">Nesprávny overovací podpis</translation>
<translation id="4196861286325780578">&amp;Znova presunúť</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Skontrolovať konfiguráciu brány firewall a antivírusového softvéru<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{žiadne}=1{1 aplikácia ($1)}=2{2 aplikácie ($1, $2)}few{# aplikácie ($1, $2, $3)}many{# aplikácie ($1, $2, $3)}other{# aplikácií ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Zlyhania</translation>
+<translation id="422022731706691852">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sa vás môžu pokúsiÅ¥ oklamaÅ¥, aby ste si nainÅ¡talovali programy, ktoré poÅ¡kodia prehliadanie (napríklad zmenia domovskú stránku alebo budú zobrazovaÅ¥ ÄalÅ¡ie reklamy na navÅ¡tívených weboch). <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Skúste spustiť nástroj Diagnostika siete<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Platný</translation>
<translation id="4250431568374086873">VaÅ¡e pripojenie k tomuto webu nie je úplne zabezpeÄené</translation>
<translation id="4250680216510889253">Nie</translation>
<translation id="425582637250725228">Zmeny, ktoré ste vykonali, sa nemusia uložiť.</translation>
<translation id="4258748452823770588">Chybný podpis</translation>
+<translation id="4265872034478892965">Povolené správcom</translation>
<translation id="4269787794583293679">(Žiadne používateľské meno)</translation>
<translation id="4275830172053184480">Reštart zariadenia</translation>
<translation id="4280429058323657511">, dátum vypršania platnosti: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Funkcia BezpeÄné prehliadanie Google nedávno <ph name="BEGIN_LINK" />naÅ¡la Å¡kodlivé programy<ph name="END_LINK" /> na webe <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">Návrhy rodiÄa</translation>
<translation id="4304224509867189079">Prihlásiť</translation>
-<translation id="432290197980158659">Server predložil certifikát, ktorý nezodpovedá vstavaným požiadavkám. Tieto požiadavky sú zahrnuté v prípade konkrétnych webov s vysokým zabezpeÄením, aby sa zaistila vaÅ¡a ochrana. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">Blokovať (predvolené)</translation>
<translation id="4325863107915753736">Článok sa nepodarilo nájsť</translation>
<translation id="4326324639298822553">Skontrolujte dátum vypršania platnosti a skúste to znova</translation>
<translation id="4331708818696583467">NezabezpeÄené</translation>
<translation id="4356973930735388585">ÚtoÄníci na tomto webe sa možno pokúsia nainÅ¡talovaÅ¥ na váš poÄítaÄ nebezpeÄné programy, ktoré ukradnú alebo odstránia vaÅ¡e informácie, napríklad fotky, heslá, správy alebo kreditné karty.</translation>
<translation id="4372948949327679948">OÄakávaná hodnota <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Pokúsili ste sa o prístup na stránky <ph name="DOMAIN" />, avÅ¡ak certifikát poskytnutý serverom bol vydavateľom zruÅ¡ený. Znamená to, že povereniam zabezpeÄenia, ktoré predložil server, sa celkom nedá dôverovaÅ¥. Je možné, že komunikujete s útoÄníkom.</translation>
<translation id="4381091992796011497">Meno používateľa:</translation>
<translation id="4394049700291259645">Zakázať</translation>
<translation id="4406896451731180161">výsledky vyhľadávania</translation>
+<translation id="4424024547088906515">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, Chrome nedôveruje jej bezpeÄnostnému certifikátu. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
<translation id="4432688616882109544">Web <ph name="HOST_NAME" /> neakceptoval váš prihlasovací certifikát alebo nebol žiadny poskytnutý.</translation>
<translation id="443673843213245140">Použitie servera proxy je zakázané, ale je urÄená explicitná konfigurácia servera proxy.</translation>
-<translation id="4492190037599258964">Výsledky vyhľadávania pre dopyt „<ph name="SEARCH_STRING" />“</translation>
<translation id="4506176782989081258">Chyba overenia: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Kontaktovať správcu systému</translation>
<translation id="450710068430902550">Zdieľanie so správcom</translation>
<translation id="4515275063822566619">Karty a adresy pochádzajú z Chromu a úÄtu Google (<ph name="ACCOUNT_EMAIL" />). Môžete ich spravovaÅ¥ v <ph name="BEGIN_LINK" />Nastaveniach<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Podrobnosti</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Skúste deaktivovať rozšírenia.</translation>
<translation id="457875822857220463">DoruÄenie</translation>
<translation id="4587425331216688090">Chcete adresu odstrániÅ¥ z prehliadaÄa Chrome?</translation>
-<translation id="4589078953350245614">Pokúsili ste sa prejsť do domény <ph name="DOMAIN" />, ale server predložil neplatný certifikát. <ph name="BEGIN_LEARN_MORE_LINK" />Ďalšie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">Vaše pripojenie k doméne <ph name="DOMAIN" /> je šifrované pomocou modernej šifrovacej súpravy.</translation>
<translation id="4594403342090139922">&amp;Vrátiť späť odstránenie</translation>
<translation id="4619615317237390068">Karty z iných zariadení</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, jej bezpeÄnostný certifikát obsahuje chyby. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
+<translation id="4690462567478992370">Nepoužívať neplatné certifikáty</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Pripojenie bolo prerušené</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Spustiť nástroj Diagnostika siete systému Windows<ph name="END_LINK" /></translation>
@@ -420,21 +471,24 @@
<translation id="4771973620359291008">Vyskytla sa neznáma chyba.</translation>
<translation id="4800132727771399293">Skontrolujte dátum vypršania platnosti aj kód CVC a skúste to znova</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože vrátil zakódované poverenia, ktoré Google Chrome nedokáže spracovaÅ¥. Chyby siete a útoky sú zvyÄajne doÄasné, takže by táto stránka mala neskôr pravdepodobne fungovaÅ¥.</translation>
<translation id="4813512666221746211">Chyba siete</translation>
<translation id="4816492930507672669">Prispôsobiť stránke</translation>
<translation id="483020001682031208">K dispozícii nie sú žiadne stránky Fyzického webu</translation>
<translation id="4850886885716139402">Zobraziť</translation>
<translation id="4854362297993841467">Tento spôsob doruÄenia nie je k dispozícii. Skúste inú adresu.</translation>
<translation id="4858792381671956233">Požiadali ste rodiÄov o povolenie návÅ¡tevy tohto webu.</translation>
+<translation id="4863764087567530506">Tento obsah sa vás môže podvodom pokúsiÅ¥ presvedÄiÅ¥, aby ste si nainÅ¡talovali softvér alebo poskytli osobné informácie. <ph name="BEGIN_LINK" />Napriek tomu zobraziÅ¥<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Hľadať v histórii</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{a 1 ÄalÅ¡ia webová stránka}few{a # ÄalÅ¡ie webové stránky}many{a # ÄalÅ¡ej webovej stránky}other{a # Äalších webových stránok}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Táto stránka bola preložená z neznámeho jazyka do jazyka <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Platba</translation>
<translation id="4926049483395192435">Musí byÅ¥ urÄená.</translation>
<translation id="495170559598752135">Akcie</translation>
<translation id="4958444002117714549">Rozbaliť zoznam</translation>
-<translation id="4962322354953122629">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; Chrome jej bezpeÄnostnému certifikátu nedôveruje. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">Opätovne aktivovať upozornenia</translation>
<translation id="4989809363548539747">Tento doplnok nie je podporovaný</translation>
<translation id="5002932099480077015">Ak túto možnosÅ¥ povolíte, Chrome bude uchovávaÅ¥ kópiu vaÅ¡ej karty na tomto zariadení na úÄely rýchlejÅ¡ieho dopĺňania formulárov.</translation>
<translation id="5018422839182700155">Táto stránka sa nedá otvoriť</translation>
@@ -442,14 +496,15 @@
<translation id="5023310440958281426">Skontrolujte pravidlá správcu</translation>
<translation id="5029568752722684782">Vymazať kópiu</translation>
<translation id="5031870354684148875">O službe PrekladaÄ Google</translation>
+<translation id="5039804452771397117">Povoliť</translation>
<translation id="5040262127954254034">Ochrana súkromia</translation>
<translation id="5045550434625856497">Nesprávne heslo</translation>
<translation id="5056549851600133418">Články pre vás</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Skontrolovať adresu proxy servera<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Žiadne súbory cookie}=1{1 web používa súbory cookie. }few{# weby používajú súbory cookie. }many{# webu používa súbory cookie. }other{# webov používa súbory cookie. }}</translation>
<translation id="5087286274860437796">Certifikát servera je momentálne neplatný</translation>
<translation id="5087580092889165836">Pridať kartu</translation>
<translation id="5089810972385038852">Štát</translation>
+<translation id="5094747076828555589">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, Chromium nedôveruje jej bezpeÄnostnému certifikátu. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
<translation id="5095208057601539847">Provincia</translation>
<translation id="5115563688576182185">(64-bitová verzia)</translation>
<translation id="5141240743006678641">Šifrovať synchronizované heslá pomocou poverení Google</translation>
@@ -465,24 +520,24 @@
<translation id="5222812217790122047">E-mailová adresa je povinný údaj</translation>
<translation id="5251803541071282808">Cloud</translation>
<translation id="5277279256032773186">Používate Chrome v práci? Firmy môžu spravovaÅ¥ nastavenia prehliadaÄa Chrome pre svojich zamestnancov. ÄŽalÅ¡ie informácie</translation>
+<translation id="5297526204711817721">VaÅ¡e pripojenie k týmto stránkam nie je súkromné. Režim VR môžete kedykoľvek ukonÄiÅ¥, staÄí odpojiÅ¥ náhlavnú súpravu a stlaÄiÅ¥ možnosÅ¥ Späť.</translation>
<translation id="5299298092464848405">Pri analýze pravidla sa vyskytla chyba</translation>
-<translation id="5300589172476337783">Zobraziť</translation>
<translation id="5308689395849655368">Hlásenie zlyhaní je zakázané.</translation>
<translation id="5317780077021120954">Uložiť</translation>
<translation id="5327248766486351172">Názov</translation>
-<translation id="5337705430875057403">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sa vás môžu pokúsiÅ¥ naviesÅ¥ vykonaÅ¥ nieÄo nebezpeÄné, ako je inÅ¡talovanie softvéru alebo odhalenie osobných informácií (napr. heslá, telefónne Äísla alebo kreditné karty).</translation>
-<translation id="5359637492792381994">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej bezpeÄnostný certifikát je momentálne neplatný. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože tento certifikát bol odvolaný. Chyby siete a útoky sú zvyÄajne doÄasné, takže by táto stránka mala neskôr pravdepodobne fungovaÅ¥.</translation>
<translation id="536296301121032821">Nastavenia pravidla sa nepodarilo uložiť</translation>
<translation id="5386426401304769735">Reťazec certifikátu pre tento web obsahuje certifikát podpísaný pomocou funkcie SHA-1.</translation>
<translation id="5402410679244714488">Platnosť do: <ph name="EXPIRATION_DATE_ABBR" />. Naposledy použitá pred viac ako rokom.</translation>
+<translation id="540969355065856584">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" /> – jej bezpeÄnostný certifikát je momentálne neplatný. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie napadol útoÄník.</translation>
<translation id="5421136146218899937">Odstrániť dáta prehliadania…</translation>
<translation id="5430298929874300616">Odstrániť záložku</translation>
<translation id="5431657950005405462">Súbor sa nenašiel</translation>
-<translation id="5435775191620395718">Zobrazuje sa história z tohto zariadenia. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Pri overení schémy sa vyskytla chyba na mieste <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Táto stránka webu <ph name="HOST_NAME" /> sa nenašla</translation>
<translation id="5455374756549232013">Chybná Äasová peÄiatka pravidla</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> z <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Neplatné</translation>
<translation id="5470861586879999274">&amp;Znova upraviť</translation>
<translation id="54817484435770891">Pridanie platnej adresy</translation>
<translation id="5492298309214877701">Tento web v intranete danej spoloÄnosti, organizácie Äi Å¡koly má rovnakú webovú adresu ako externý web.
@@ -499,6 +554,8 @@
<translation id="5571083550517324815">Vyzdvihnutie na tejto adrese nie je možné. Vyberte inú adresu.</translation>
<translation id="5572851009514199876">ZaÄnite a prihláste sa do Chromu, aby skontroloval, Äi môžete navÅ¡tíviÅ¥ tento web.</translation>
<translation id="5580958916614886209">Skontrolujte mesiac vypršania platnosti a skúste to znova</translation>
+<translation id="5586446728396275693">Žiadne uložené adresy</translation>
+<translation id="5595485650161345191">Upraviť adresu</translation>
<translation id="560412284261940334">Správa nie je podporovaná</translation>
<translation id="5610142619324316209">Skontrolovať pripojenie</translation>
<translation id="5610807607761827392">Karty a adresy môžete spravovaÅ¥ v Äasti <ph name="BEGIN_LINK" />Nastavenia<ph name="END_LINK" />.</translation>
@@ -506,15 +563,18 @@
<translation id="5622887735448669177">Chcete tento web opustiť?</translation>
<translation id="5629630648637658800">Nastavenia pravidla sa nepodarilo naÄítaÅ¥</translation>
<translation id="5631439013527180824">Neplatný token správy zariadenia</translation>
+<translation id="5633066919399395251">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sa môžu pokúsiÅ¥ nainÅ¡talovaÅ¥ nebezpeÄné programy vo vaÅ¡om poÄítaÄi, pomocou ktorých ukradnú alebo odstránia informácie (napríklad fotky, heslá, správy a kreditné karty). <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Poloha</translation>
+<translation id="5659593005791499971">E-mail</translation>
<translation id="5669703222995421982">Ako získať prispôsobený obsah</translation>
<translation id="5675650730144413517">Táto stránka nefunguje</translation>
-<translation id="5677928146339483299">Zablokované</translation>
-<translation id="5694783966845939798">Pokúsili ste sa prejsÅ¥ do domény <ph name="DOMAIN" />, ale server predložil certifikát podpísaný slabým algoritmom podpisu (napr. SHA-1). Znamená to, že predložené bezpeÄnostné poverenia mohli byÅ¥ sfalÅ¡ované a môže ísÅ¥ o úplne iný server, ako ste oÄakávali (je možné, že komunikujete s útoÄníkom). <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">Identita tejto webovej stránky nebola overená.</translation>
+<translation id="5713016350996637505">Blokovaný klamlivý obsah</translation>
<translation id="5720705177508910913">Aktuálny používateľ</translation>
<translation id="5732392974455271431">VaÅ¡i rodiÄia ho môžu pre vás odblokovaÅ¥</translation>
<translation id="5763042198335101085">Zadajte platnú e-mailovú adresu</translation>
<translation id="5765072501007116331">Ak chcete zobraziÅ¥ spôsoby a požiadavky doruÄenia, vyberte adresu</translation>
+<translation id="5778550464785688721">Úplné ovládanie zariadení MIDI</translation>
<translation id="5784606427469807560">Pri overovaní karty sa vyskytol problém. Skontrolujte pripojenie k internetu a skúste to znova.</translation>
<translation id="5785756445106461925">Táto stránka obsahuje aj iné zdroje, ktoré nie sú zabezpeÄené. Tieto zdroje môžu pri prenose vidieÅ¥ ostatní používatelia a útoÄník ich môže upraviÅ¥ tak, aby zmenil vzhľad stránky.</translation>
<translation id="5786044859038896871">Chcete vyplniť informácie o karte?</translation>
@@ -523,14 +583,14 @@
<translation id="5813119285467412249">&amp;Znova pridať</translation>
<translation id="5814352347845180253">Môžete stratiÅ¥ prístup k prémiovému obsahu z webu <ph name="SITE" /> a niektorých Äalších webov.</translation>
<translation id="5838278095973806738">Na tomto webe by ste nemali zadávaÅ¥ citlivé informácie (napríklad heslá alebo kreditné karty), pretože by ich mohli ukradnúť útoÄníci.</translation>
-<translation id="5843436854350372569">Pokúsili ste sa prejsÅ¥ do domény <ph name="DOMAIN" />, ale server predložil certifikát obsahujúci slabý kľúÄ. ÚtoÄník mohol tento súkromný kÄ¾ÃºÄ prelomiÅ¥ a môže ísÅ¥ o iný server, než ste oÄakávali (je možné, že komunikujete s útoÄníkom). <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">K tomuto webu sa nedá pripojiť</translation>
<translation id="5869522115854928033">Uložené heslá</translation>
<translation id="5872918882028971132">Návrhy rodiÄa</translation>
<translation id="5901630391730855834">Žltá</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synchronizované)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{Používa sa 1}few{Používajú sa #}many{Používa sa #}other{Používa sa #}}</translation>
<translation id="5926846154125914413">Môžete stratiť prístup k prémiovému obsahu z niektorých webov.</translation>
<translation id="5959728338436674663">Automaticky odosielaÅ¥ <ph name="BEGIN_WHITEPAPER_LINK" />niektoré informácie o systéme a obsah stránok<ph name="END_WHITEPAPER_LINK" /> do Googlu s cieľom pomôcÅ¥ rozpoznávaÅ¥ nebezpeÄné aplikácie a weby. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Týždeň</translation>
<translation id="5967867314010545767">Odstrániť z histórie</translation>
<translation id="5975083100439434680">Oddialiť</translation>
<translation id="598637245381783098">Nie je možné otvoriť platobnú aplikáciu</translation>
@@ -539,20 +599,28 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Strana 1}few{Strana #}many{Strana #}other{Strana #}}</translation>
<translation id="6017514345406065928">Zelená</translation>
+<translation id="6017850046339264347">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> by mohli nainÅ¡talovaÅ¥ klamlivé aplikácie vydávajúce sa za iné aplikácie alebo zhromažÄujúce údaje, ktoré sa dajú použiÅ¥ na sledovanie vaÅ¡ej osoby. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synchronizované)</translation>
<translation id="6027201098523975773">Zadajte meno</translation>
<translation id="6040143037577758943">Zavrieť</translation>
<translation id="6042308850641462728">Viac</translation>
+<translation id="6047233362582046994">Ak si uvedomujete bezpeÄnostné riziko, môžete <ph name="BEGIN_LINK" />tento web navÅ¡tíviÅ¥<ph name="END_LINK" /> eÅ¡te skôr, ako budú Å¡kodlivé aplikácie odstránené.</translation>
+<translation id="6051221802930200923">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože používa pripínanie certifikátov. Chyby siete a útoky sú zvyÄajne doÄasné, takže by táto stránka mala neskôr pravdepodobne fungovaÅ¥.</translation>
<translation id="6060685159320643512">Opatrne, tieto experimenty môžu spôsobiť problémy</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{žiadne}=1{1}few{#}many{#}other{#}}</translation>
+<translation id="6080696365213338172">K obsahu ste pristúpili pomocou certifikátu, ktorý poskytol správca. Údaje, ktoré poskytnete doméne <ph name="DOMAIN" /> môžu byť zachytené správcom.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Žiadne}=1{1 heslo (synchronizované)}few{# heslá (synchronizované)}many{# hesla (synchronizované)}other{# hesiel (synchronizované)}}</translation>
<translation id="6146055958333702838">Skontrolujte vÅ¡etky káble a reÅ¡tartujte vÅ¡etky používané smerovaÄe, modemy alebo iné sieÅ¥ové zariadenia.</translation>
<translation id="614940544461990577">Vyskúšajte:</translation>
<translation id="6151417162996330722">Obdobie platnosti certifikátu servera je príliš dlhé</translation>
<translation id="6157877588268064908">Ak chcete zobraziť spôsoby a požiadavky dodania, vyberte adresu</translation>
+<translation id="6158003235852588289">Funkcia BezpeÄné prehliadanie Google nedávno zistila na webe <ph name="SITE" /> phishing. Phishingové stránky sa vydávajú za iné weby, aby vás oklamali.</translation>
<translation id="6165508094623778733">Viac informácií</translation>
+<translation id="6169916984152623906">Teraz môžete prehliadať internet v súkromí a ostatní používatelia tohto zariadenia vašu aktivitu neuvidia. Stiahnuté súbory a záložky však budú uložené.</translation>
<translation id="6177128806592000436">VaÅ¡e pripojenie k tomuto webu nie je zabezpeÄené</translation>
<translation id="6184817833369986695">(kohorta: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Skontrolujte internetové pripojenie</translation>
<translation id="6218753634732582820">Chcete adresu odstrániÅ¥ z prehliadaÄa Chromium?</translation>
+<translation id="6221345481584921695">Funkcia BezpeÄné prehliadanie Google nedávno <ph name="BEGIN_LINK" />zistila malvér<ph name="END_LINK" /> na stránkach <ph name="SITE" />. Webové stránky, ktoré sú zvyÄajne bezpeÄné, môžu byÅ¥ niekedy nakazené malvérom. Å kodlivý obsah pochádza od hostiteľa <ph name="SUBRESOURCE_HOST" />, ktorý je známym distribútorom malvéru.</translation>
<translation id="6251924700383757765">Pravidlá ochrany súkromia</translation>
<translation id="6254436959401408446">Na otvorenie stránky nie je dostatok pamäte</translation>
<translation id="625755898061068298">Rozhodli ste sa deaktivovaÅ¥ upozornenia týkajúce sa zabezpeÄenia pre tento web.</translation>
@@ -578,15 +646,14 @@
<translation id="6404511346730675251">Upraviť záložku</translation>
<translation id="6410264514553301377">Zadajte dátum vypršania platnosti a kód CVC karty <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Opýtali ste sa svojho rodiÄa, Äi môžete navÅ¡tíviÅ¥ tento web</translation>
-<translation id="6416403317709441254">Web <ph name="SITE" /> momentálne nemôžete navÅ¡tíviÅ¥, pretože odoslal zakódované poverenia, ktoré Chromium neodkáže spracovaÅ¥. Chyby siete a útoky sú zvyÄajne doÄasné, takže táto stránka by mala pravdepodobne neskôr fungovaÅ¥. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">Nie je možné skontrolovaÅ¥, Äi bol certifikát odmietnutý.</translation>
<translation id="6433490469411711332">Úprava kontaktných informácií</translation>
<translation id="6433595998831338502">Web <ph name="HOST_NAME" /> zamietol pripojenie.</translation>
<translation id="6446608382365791566">Pridanie Äalších informácií</translation>
+<translation id="6447842834002726250">Súbory cookie</translation>
<translation id="6451458296329894277">Potvrdiť opakované odoslanie formulára</translation>
<translation id="6456339708790392414">Vaša platba</translation>
<translation id="6458467102616083041">Ignorované, pretože predvolený vyhľadávaÄ je podľa pravidla zakázaný.</translation>
-<translation id="6462969404041126431">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; jej bezpeÄnostný certifikát bol zrejme odvolaný. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">Pravidlá zariadenia</translation>
<translation id="6477321094435799029">Chrome na tejto stránke zaznamenal nezvyÄajný kód a v záujme ochrany vaÅ¡ich osobných informácií (napr. hesiel, telefónnych Äísel a kreditných kariet) ho zablokoval.</translation>
<translation id="6489534406876378309">Spustiť nahrávanie správ o zlyhaní</translation>
@@ -598,20 +665,19 @@
<translation id="6556915248009097796">Platnosť do <ph name="EXPIRATION_DATE_ABBR" />, naposledy použité <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Váš správca to zatiaľ neschválil</translation>
<translation id="6569060085658103619">Prezeráte si stránku s rozšíreniami</translation>
-<translation id="6593753688552673085">menej ako <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Tento obsah sa môže pokúsiÅ¥ na vaÅ¡om zariadení nainÅ¡talovaÅ¥ nebezpeÄný softvér, ktorý ukradne alebo odstráni vaÅ¡e údaje. <ph name="BEGIN_LINK" />Napriek tomu zobraziÅ¥<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">Možnosti šifrovania</translation>
<translation id="662080504995468778">Zostať</translation>
<translation id="6626291197371920147">Pridanie platného Äísla karty</translation>
<translation id="6628463337424475685">Vyhľadávanie <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sa môžu pokúsiÅ¥ vo vaÅ¡om poÄítaÄi Mac nainÅ¡talovaÅ¥ nebezpeÄné programy, pomocou ktorých ukradnú alebo odstránia informácie (napríklad fotky, heslá, správy a kreditné karty). <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Toto pravidlo bolo oznaÄené ako zastarané.</translation>
-<translation id="6652240803263749613">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; operaÄný systém vášho poÄítaÄa nedôveruje jej bezpeÄnostnému certifikátu. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">Chcete návrh položky formulára odstrániÅ¥ z prehliadaÄa Chromium?</translation>
<translation id="6685834062052613830">Odhláste sa a dokonÄite nastavenie</translation>
<translation id="6710213216561001401">Dozadu</translation>
<translation id="6710594484020273272">&lt;Zadajte hľadaný výraz&gt;</translation>
<translation id="6711464428925977395">Vyskytol sa problém s proxy serverom alebo je adresa nesprávna.</translation>
<translation id="6727102863431372879">Nastaviť</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{žiadne}=1{1 položka}few{# položky}many{# položky}other{# položiek}}</translation>
<translation id="674375294223700098">Neznáma chyba spôsobená certifikátom servera.</translation>
<translation id="6753269504797312559">Hodnota pravidla</translation>
<translation id="6757797048963528358">Vaše zariadenie prešlo do režimu spánku.</translation>
@@ -619,6 +685,8 @@
<translation id="6810899417690483278">Identifikátor prispôsobenia</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">NaÄítanie údajov o regiónoch zlyhalo</translation>
+<translation id="6825578344716086703">Pokúsili ste sa o prístup do domény <ph name="DOMAIN" />, server vÅ¡ak predložil certifikát podpísaný slabým algoritmom podpisu. Znamená to, že predložené poverenia zabezpeÄenia mohli byÅ¥ sfalÅ¡ované a môže ísÅ¥ o úplne iný server, než ste oÄakávali (možno komunikujete s útoÄníkom).</translation>
+<translation id="6830728435402077660">NezabezpeÄené</translation>
<translation id="6831043979455480757">Preložiť</translation>
<translation id="6839929833149231406">Oblasť</translation>
<translation id="6874604403660855544">&amp;Znova pridať</translation>
@@ -626,6 +694,7 @@
<translation id="6895330447102777224">Vaša karta je overená</translation>
<translation id="6897140037006041989">Používateľský agent</translation>
<translation id="6915804003454593391">Používateľ:</translation>
+<translation id="6945221475159498467">Vybrať</translation>
<translation id="6948701128805548767">Ak chcete zobraziť spôsoby a požiadavky vyzdvihnutia, vyberte adresu</translation>
<translation id="6957887021205513506">Zdá sa, že certifikát servera je falošný.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -634,15 +703,16 @@
<translation id="6973656660372572881">UrÄené sú pevne dané servery proxy aj skript PAC webovej adresy.</translation>
<translation id="6989763994942163495">Zobraziť rozšírené nastavenia...</translation>
<translation id="7000990526846637657">V histórii sa nenašli žiadne záznamy</translation>
-<translation id="7009986207543992532">Pokúsili ste sa prejsť do domény <ph name="DOMAIN" />, ale server poskytol certifikát, ktorého obdobie platnosti je príliš dlhé a preto nedôveryhodné.<ph name="BEGIN_LEARN_MORE_LINK" />Ďalšie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Váš úÄet Google môže maÅ¥ ÄalÅ¡ie formy histórie prehliadania na adrese <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Heslá</translation>
+<translation id="7050187094878475250">Pokúsili ste sa prejsť do domény <ph name="DOMAIN" />, ale server udelil certifikát, ktorého obdobie platnosti je príliš dlhé, a preto nie je dôveryhodný</translation>
+<translation id="7053983685419859001">Blokovať</translation>
<translation id="7064851114919012435">Kontaktné informácie</translation>
<translation id="7079718277001814089">Tento web obsahuje malvér</translation>
<translation id="7087282848513945231">Grófstvo</translation>
-<translation id="7088615885725309056">Staršie</translation>
<translation id="7090678807593890770">Vyhľadajte na Googli výraz <ph name="LINK" /></translation>
+<translation id="7108819624672055576">Povolené rozšírením</translation>
<translation id="7119414471315195487">Zavrite ostatné karty alebo programy</translation>
<translation id="7129409597930077180">Dodanie na túto adresu nie je možné. Vyberte inú adresu.</translation>
<translation id="7138472120740807366">Spôsob doruÄenia</translation>
@@ -660,22 +730,18 @@
<translation id="7220786058474068424">Spracováva sa</translation>
<translation id="724691107663265825">Webové stránky, ktoré chcete otvoriť, obsahujú malvér</translation>
<translation id="724975217298816891">Ak chcete aktualizovať podrobnosti o karte <ph name="CREDIT_CARD" />, zadajte dátum vypršania platnosti a kód CVC. Po potvrdení budú podrobnosti o karte zdieľané s týmto webom.</translation>
-<translation id="725866823122871198">Súkromné pripojenie k doméne <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazaÅ¥, pretože dátum a Äas (<ph name="DATE_AND_TIME" />) vášho poÄítaÄa sú nesprávne.</translation>
+<translation id="7260504762447901703">Odvolať prístup</translation>
<translation id="7275334191706090484">Spravované záložky</translation>
<translation id="7298195798382681320">OdporúÄané</translation>
<translation id="7309308571273880165">Správa o zlyhaní zaznamenaná v Äase <ph name="CRASH_TIME" /> (nahranie vyžiadané používateľom, zatiaľ nebola nahraná)</translation>
<translation id="7334320624316649418">&amp;Znova zmeniť poradie</translation>
<translation id="733923710415886693">Certifikát servera nebol zverejnený prostredníctvom pravidla transparentnosti certifikátov.</translation>
-<translation id="7351800657706554155">Nemôžete prejsÅ¥ na web <ph name="SITE" />, pretože jeho certifikát bol odvolaný. Chyby siete a útoky sú zvyÄajne doÄasné, takže zrejme bude neskôr opäť fungovaÅ¥. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">Príkazový riadok</translation>
<translation id="7372973238305370288">výsledok vyhľadávania</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> – <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nie</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Overenie karty</translation>
-<translation id="7394102162464064926">Naozaj chcete tieto stránky vymazať z histórie?
-
-Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).</translation>
<translation id="7400418766976504921">Webová adresa</translation>
<translation id="7419106976560586862">Cesta profilu</translation>
<translation id="7424977062513257142">Vložená stránka na tejto webstránke hovorí:</translation>
@@ -683,6 +749,7 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="7444046173054089907">Tento web je blokovaný</translation>
<translation id="7445762425076701745">Identita servera, ku ktorému ste pripojení, sa nedá úplne overiÅ¥. Ste pripojení k serveru, ktorý používa názov platný iba v rámci vaÅ¡ej siete. Externá certifikaÄná autorita nemôže vlastníctvo názvu nijakým spôsobom overiÅ¥. Niektoré certifikaÄné autority vÅ¡ak vydajú certifikát aj pre takéto názvy, a preto sa nedá zaruÄiÅ¥, že ste pripojení k požadovaným webovým stránkam a nie k stránkam útoÄníka.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Ďalšie informácie o tomto probléme<ph name="END_LINK" /></translation>
+<translation id="7455133967321480974">Použiť predvolené všeobecné nastavenie (Blokovať)</translation>
<translation id="7460163899615895653">Vaše nedávne karty z iných zariadení sa zobrazia na tomto mieste</translation>
<translation id="7469372306589899959">Overovanie karty</translation>
<translation id="7481312909269577407">Dopredu</translation>
@@ -690,36 +757,43 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="7508255263130623398">Identifikátor zariadenia vráteného v rámci záruky je prázdny alebo sa nezhoduje s identifikátorom aktuálneho zariadenia</translation>
<translation id="7514365320538308">Stiahnuť</translation>
<translation id="7518003948725431193">Na webovej adrese <ph name="URL" /> sa nepodarilo nájsť žiadne webové stránky</translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Hodnota</translation>
<translation id="7537536606612762813">Povinné</translation>
+<translation id="7542403920425041731">Po potvrdení budú údaje karty zdieľané s týmto webom.</translation>
<translation id="7542995811387359312">Automatické dopĺňanie údajov o kreditnej karte je zakázané, pretože tento formulár nepoužíva zabezpeÄené pripojenie.</translation>
<translation id="7543525346216957623">Opýtajte sa rodiÄa</translation>
<translation id="7549584377607005141">Správne zobrazenie tejto webovej stránky si vyžaduje údaje, ktoré ste zadali v minulosti. Tieto údaje môžete poslať znova, ale v tom prípade zopakujete všetky akcie, ktoré sa na tejto stránke vykonali v minulosti.</translation>
<translation id="7552846755917812628">Vyskúšajte nasledujúce tipy:</translation>
<translation id="7554791636758816595">Nová karta</translation>
+<translation id="7567204685887185387">Server nedokáže overiÅ¥, Äi ide o doménu <ph name="DOMAIN" />, bol zrejme vydaný faloÅ¡ný bezpeÄnostný certifikát. Môže to byÅ¥ spôsobené nesprávnou konfiguráciou alebo tým, že vaÅ¡e pripojenie zachytil útoÄník.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> Äalší}few{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ÄalÅ¡ie}many{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> ÄalÅ¡ieho}other{<ph name="CONTACT_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> Äalších}}</translation>
<translation id="7568593326407688803">Táto stránka je v jazyku<ph name="ORIGINAL_LANGUAGE" />Chceli by ste ju preložiť?</translation>
<translation id="7569952961197462199">Chcete kreditnú kartu odstrániÅ¥ z prehliadaÄa Chrome?</translation>
<translation id="7569983096843329377">ÄŒierna</translation>
<translation id="7578104083680115302">Zaplaťte rýchlejšie na stránkach a v aplikáciách v rôznych službách pomocou kariet, ktoré ste si uložili na Googli.</translation>
<translation id="7588950540487816470">Fyzický web</translation>
<translation id="7592362899630581445">Certifikát servera porušuje obmedzenia názvov.</translation>
+<translation id="7598391785903975535">Menej ako <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Web <ph name="HOST_NAME" /> momentálne nemôže spracovať túto žiadosť.</translation>
<translation id="7600965453749440009">Nikdy neprekladať jazyk <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Hodnota (<ph name="VALUE" />) presahuje povolený rozsah.</translation>
<translation id="7613889955535752492">Dátum vypršania platnosti: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Už máte údaje, ktoré sú Å¡ifrované pomocou inej verzie vášho hesla úÄtu Google. Zadajte ho nižšie.</translation>
-<translation id="7634554953375732414">Vaše pripojenie k týmto stránkam nie je súkromné.</translation>
<translation id="7637571805876720304">Chcete kreditnú kartu odstrániÅ¥ z prehliadaÄa Chromium?</translation>
<translation id="765676359832457558">Skryť rozšírené nastavenia...</translation>
<translation id="7658239707568436148">Zrušiť</translation>
+<translation id="7662298039739062396">Nastavenie ovládané rozšírením</translation>
<translation id="7667346355482952095">Vrátený token pravidla je prázdny alebo sa nezhoduje s aktuálnym tokenom</translation>
<translation id="7668654391829183341">Neznáme zariadenie</translation>
<translation id="7669271284792375604">ÚtoÄníci na tomto webe sa vás môžu pokúsiÅ¥ podvodom presvedÄiÅ¥, aby ste si nainÅ¡talovali programy poÅ¡kodzujúce vaÅ¡e prostredie prehliadania (napríklad zmenou domovskej stránky alebo zobrazovaním Äalších reklám na weboch, ktoré navÅ¡tevujete).</translation>
<translation id="7674629440242451245">Máte záujem o skvelé nové funkcie prehliadaÄa Chrome? Vyskúšajte verziu pre vývojárov na stránke chrome.com/dev.</translation>
<translation id="7682287625158474539">Dodacia</translation>
+<translation id="7701040980221191251">Žiadne</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />PrejsÅ¥ na stránky <ph name="SITE" /> (nebezpeÄné)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certifikát</translation>
+<translation id="7716147886133743102">Blokované správcom</translation>
<translation id="7716424297397655342">Tento web nie je možné naÄítaÅ¥ z vyrovnávacej pamäte</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Nespravované</translation>
<translation id="7755287808199759310">Váš rodiÄ ho môže pre vás odblokovaÅ¥</translation>
<translation id="7758069387465995638">Pripojenie mohla zablokovať brána firewall alebo antivírusový softvér.</translation>
@@ -746,15 +820,15 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="7951415247503192394">(32-bitová verzia)</translation>
<translation id="7956713633345437162">Záložky v mobile</translation>
<translation id="7961015016161918242">Nikdy</translation>
-<translation id="7962083544045318153">ID zlyhania <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Vždy preložiť jazyk <ph name="ORIGINAL_LANGUAGE" /> do jazyka <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Nie je upresnené</translation>
<translation id="800218591365569300">Skúste zavrieť ostatné karty alebo programy a uvoľniť tak miesto v pamäti.</translation>
<translation id="8012647001091218357">V tejto chvíli sa nám nepodarilo spojiÅ¥ s vaÅ¡imi rodiÄmi. Skúste to znova neskôr.</translation>
<translation id="8025119109950072390">ÚtoÄníci na tomto webe sa vás môžu pokúsiÅ¥ naviesÅ¥ vykonaÅ¥ nieÄo nebezpeÄné, ako je inÅ¡talovanie softvéru alebo odhalenie osobných informácií (napr. hesiel, telefónnych Äísel alebo kreditných kariet).</translation>
-<translation id="803030522067524905">Funkcia BezpeÄné prehliadanie Google nedávno zistila phishing na webe <ph name="SITE" />. Phishingové weby sú také, ktoré sa vydávajú za iné weby, aby vás oklamali. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">Táto stránka je v jazyku <ph name="SOURCE_LANGUAGE" />. Chcete ju preložiť do jazyka <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Opýtať sa (predvolené)</translation>
<translation id="8041089156583427627">Odoslať spätnú väzbu</translation>
+<translation id="8041940743680923270">Použiť predvolené všeobecné nastavenie (Opýtať sa)</translation>
<translation id="8088680233425245692">Článok sa nepodarilo zobraziť.</translation>
<translation id="8089520772729574115">menej ako 1 MB</translation>
<translation id="8091372947890762290">Aktivácia Äaká na server</translation>
@@ -763,13 +837,14 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />Adresu DNS<ph name="END_ABBR" /> servera <ph name="HOST_NAME" /> sa nepodarilo nájsť.</translation>
<translation id="8149426793427495338">Váš poÄítaÄ preÅ¡iel do režimu spánku.</translation>
<translation id="8150722005171944719">Súbor na adrese <ph name="URL" /> nie je možné preÄítaÅ¥. Je možné, že bol odstránený, presunutý alebo môžu v prístupe brániÅ¥ povolenia súboru.</translation>
+<translation id="8184538546369750125">Použiť predvolené všeobecné nastavenie (Povoliť)</translation>
+<translation id="8191494405820426728">Identifikátor miestneho zlyhania <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Vrátiť späť presunutie</translation>
<translation id="8201077131113104583">Neplatná webová adresa aktualizácie pre rozšírenie s ID <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Súhrn objednávky</translation>
<translation id="8218327578424803826">Pridelená poloha:</translation>
<translation id="8225771182978767009">Osoba, ktorá nastavila tento poÄítaÄ, sa rozhodla daný web blokovaÅ¥.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">ÚtoÄníci, ktorí sú práve na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, sa možno pokúsia nainÅ¡talovaÅ¥ na váš poÄítaÄ nebezpeÄné programy, ktoré ukradnú alebo odstránia vaÅ¡e informácie, napríklad fotky, heslá, správy alebo kreditné karty.</translation>
<translation id="8241707690549784388">Vami hľadaná stránka použila informácie, ktoré ste zadali. Návrat na túto stránku môže spôsobiÅ¥ zopakovanie akcie, ktorú ste vykonali. Chcete pokraÄovaÅ¥?</translation>
<translation id="8249320324621329438">Naposledy naÄítané:</translation>
<translation id="8253091569723639551">FakturaÄná adresa je povinná</translation>
@@ -777,6 +852,7 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="8289355894181816810">Ak neviete, Äo to znamená, kontaktujte správcu siete.</translation>
<translation id="8293206222192510085">Pridať záložku</translation>
<translation id="8294431847097064396">Zdroj</translation>
+<translation id="8306404619377842860">S doménou <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazaÅ¥ súkromné pripojenie, pretože dátum a Äas (<ph name="DATE_AND_TIME" />) vo vaÅ¡om zariadení sú nesprávne. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Preklad zlyhal v dôsledku problému so sieťovým pripojením.</translation>
<translation id="8332188693563227489">Prístup k webu <ph name="HOST_NAME" /> bol zamietnutý</translation>
<translation id="834457929814110454">Ak si uvedomujete bezpeÄnostné riziko, môžete <ph name="BEGIN_LINK" />tieto stránky navÅ¡tíviÅ¥<ph name="END_LINK" /> eÅ¡te skôr, ako budú Å¡kodlivé programy odstránené.</translation>
@@ -797,11 +873,9 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="8483780878231876732">Ak chcete používaÅ¥ karty z úÄtu Google, prihláste sa do Chromu</translation>
<translation id="8488350697529856933">Platí pre</translation>
<translation id="8498891568109133222">Web <ph name="HOST_NAME" /> príliš dlho neodpovedal.</translation>
-<translation id="852346902619691059">Tomuto serveru sa nepodarilo dokázaÅ¥, že ide o doménu <ph name="DOMAIN" />; operaÄný systém vášho zariadenia nedôveruje jej bezpeÄnostnému certifikátu. Môže to byÅ¥ následok nesprávnej konfigurácie alebo napadnutia vášho pripojenia útoÄníkom. <ph name="BEGIN_LEARN_MORE_LINK" />ÄŽalÅ¡ie informácie<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">Rok vypršania platnosti</translation>
<translation id="8543181531796978784">Môžete buÄ <ph name="BEGIN_ERROR_LINK" />nahlásiÅ¥ problém s zisÅ¥ovaním<ph name="END_ERROR_LINK" />, alebo <ph name="BEGIN_LINK" />tieto nebezpeÄné stránky navÅ¡tíviÅ¥<ph name="END_LINK" /> (ak si uvedomujete bezpeÄnostné riziko).</translation>
<translation id="8553075262323480129">Prekladanie zlyhalo, pretože sa nepodarilo urÄiÅ¥ jazyk stránky.</translation>
-<translation id="8559762987265718583">Súkromné pripojenie k doméne <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> sa nedá nadviazaÅ¥, pretože dátum a Äas (<ph name="DATE_AND_TIME" />) vášho zariadenia sú nesprávne.</translation>
<translation id="8571890674111243710">Prebieha preklad stránky do jazyka: <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Pridať telefón
</translation>
@@ -816,6 +890,7 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="8738058698779197622">Ak chcete nadviazaÅ¥ zabezpeÄené pripojenie, vaÅ¡e hodiny musia byÅ¥ nastavené správne. Je to preto, že certifikáty, ktoré webové stránky používajú na vlastnú identifikáciu, sú platné iba urÄitý Äas. KeÄže nie sú hodiny vášho zariadenia nastavené správne, Chromium nemôže tieto certifikáty overiÅ¥.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;Adresa DNS&lt;/abbr&gt; webu <ph name="HOST_NAME" /> sa nenašla. Problém sa diagnostikuje.</translation>
<translation id="8759274551635299824">Platnosť tejto karty vypršala</translation>
+<translation id="8761567432415473239">BezpeÄné prehliadanie Google nedávno <ph name="BEGIN_LINK" />zistilo Å¡kodlivé programy<ph name="END_LINK" /> na webe <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Znova vymazať</translation>
<translation id="8800988563907321413">Tu sa zobrazia návrhy funkcie Nablízku</translation>
<translation id="8820817407110198400">Záložky</translation>
@@ -828,29 +903,30 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="8870413625673593573">Naposledy zatvorené</translation>
<translation id="8874824191258364635">Zadajte platné Äíslo karty</translation>
<translation id="8876793034577346603">Konfiguráciu siete sa nepodarilo analyzovať.</translation>
-<translation id="8877192140621905067">Po potvrdení budú podrobnosti o karte zdieľané s týmto webom</translation>
<translation id="8889402386540077796">Odtieň</translation>
<translation id="8891727572606052622">Neplatný režim proxy.</translation>
<translation id="889901481107108152">Je nám ľúto, ale tento experiment nie je na vašej platforme k dispozícii.</translation>
<translation id="8903921497873541725">Priblížiť</translation>
<translation id="8931333241327730545">Chcete túto kartu uložiÅ¥ do svojho úÄtu Google?</translation>
<translation id="8932102934695377596">Vaše hodiny idú pozadu</translation>
-<translation id="8954894007019320973">(PokraÄ.)</translation>
<translation id="8971063699422889582">Platnosť certifikátu servera vypršala.</translation>
<translation id="8986494364107987395">Automaticky odosielať Googlu štatistiky používania a správy o zlyhaní</translation>
-<translation id="8987927404178983737">Mesiac</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Webové stránky, ktoré sa chystáte navštíviť, obsahujú škodlivé programy</translation>
+<translation id="8997023839087525404">Server prezentoval certifikát, ktorý nebol zverejnený pomocou pravidla transparentnosti certifikátov. V prípade niektorých certifikátov sa táto podmienka vyžaduje s cieľom zaistiÅ¥ ich dôveryhodnosÅ¥ a ochranu proti útoÄníkom.</translation>
<translation id="9001074447101275817">Proxy server <ph name="DOMAIN" /> vyžaduje používateľské meno a heslo.</translation>
+<translation id="9005998258318286617">Dokument PDF sa nepodarilo naÄítaÅ¥.</translation>
<translation id="901974403500617787">Príznaky, ktoré platia v celom systéme, môže nastaviť iba vlastník: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">FakturaÄná adresa karty je povinná</translation>
<translation id="9020542370529661692">Táto stránka bola preložená do jazyka <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Chyba zabezpeÄenia</translation>
<translation id="9038649477754266430">PoužívaÅ¥ službu predpovedí na rýchlejÅ¡ie naÄítanie stránok</translation>
<translation id="9039213469156557790">Táto stránka obsahuje aj iné zdroje, ktoré nie sú zabezpeÄené. Tieto zdroje môžu pri prenose vidieÅ¥ ostatní používatelia a útoÄník ich môže upraviÅ¥ tak, aby zmenil správanie stránky.</translation>
-<translation id="9040185888511745258">ÚtoÄníci na webe <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sa vás môžu pokúsiÅ¥ podvodom presvedÄiÅ¥, aby ste si nainÅ¡talovali programy poÅ¡kodzujúce vaÅ¡e prostredie prehliadania (napríklad zmenou vaÅ¡ej domovskej stránky alebo zobrazovaním Äalších reklám na stránkach, ktoré navÅ¡tevujete).</translation>
+<translation id="9049981332609050619">Pokúšate sa otvoriť doménu <ph name="DOMAIN" />, ale server predložil neplatný certifikát.</translation>
<translation id="9050666287014529139">Prístupová fráza</translation>
<translation id="9065203028668620118">Upraviť</translation>
<translation id="9068849894565669697">Výber farby</translation>
+<translation id="9069693763241529744">Blokované rozšírením</translation>
<translation id="9076283476770535406">Môže zahŕňať obsah pre dospelých</translation>
<translation id="9078964945751709336">Treba zadaÅ¥ ÄalÅ¡ie informácie</translation>
<translation id="9103872766612412690">Web <ph name="SITE" /> zvyÄajne chráni vaÅ¡e informácie pomocou Å¡ifrovania. KeÄ sa prehliadaÄ Chromium tentokrát pokúsil pripojiÅ¥ k webu <ph name="SITE" />, odoslal späť nezvyÄajné a nesprávne poverenia. Môže sa to staÅ¥ vtedy, keÄ sa za web <ph name="SITE" /> snaží vydávaÅ¥ útoÄník alebo keÄ pripojenie preruší prihlasovacia obrazovka siete Wi-Fi. VaÅ¡e informácie sú stále zabezpeÄené, pretože prehliadaÄ Chromium zastavil pripojenie eÅ¡te pred výmenou dát.</translation>
@@ -859,16 +935,21 @@ Nabudúce by sa vám mohol hodiť režim inkognito (<ph name="SHORTCUT_KEY" />).
<translation id="9148507642005240123">&amp;Vrátiť späť úpravu</translation>
<translation id="9154194610265714752">Aktualizované</translation>
<translation id="9157595877708044936">Prebieha nastavenie...</translation>
+<translation id="9169664750068251925">Vždy blokovať na týchto stránkach</translation>
<translation id="9170848237812810038">&amp;Naspäť</translation>
<translation id="917450738466192189">Certifikát servera je neplatný.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ÄalÅ¡ia}few{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ÄalÅ¡ie}many{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ÄalÅ¡ej}other{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> Äalších}}</translation>
<translation id="9183425211371246419">Web <ph name="HOST_NAME" /> využíva nepodporovaný protokol.</translation>
<translation id="9205078245616868884">Údaje sú Å¡ifrované pomocou vlastnej prístupovej frázy synchronizácie. KeÄ ju zadáte, synchronizácia sa spustí.</translation>
<translation id="9207861905230894330">Článok sa nepodarilo pridať.</translation>
+<translation id="9219103736887031265">Obrázky</translation>
<translation id="933612690413056017">Žiadne internetové pripojenie</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">VYMAZAŤ FORMULÃR</translation>
<translation id="939736085109172342">Nový prieÄinok</translation>
<translation id="941721044073577244">Zdá sa, že nemáte povolenie pristupovať na tento web</translation>
<translation id="969892804517981540">Oficiálne zostavenie</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Žiadne}=1{1 položka}few{# položky}many{# položky}other{# položiek}}</translation>
<translation id="988159990683914416">Zostavenie pre vývojárov</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sl.xtb b/chromium/components/strings/components_strings_sl.xtb
index 25bdb040cef..93cb53f22e9 100644
--- a/chromium/components/strings/components_strings_sl.xtb
+++ b/chromium/components/strings/components_strings_sl.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Sukanje v smeri urnega kazalca</translation>
<translation id="1038842779957582377">neznano ime</translation>
<translation id="1050038467049342496">Zaprite druge aplikacije</translation>
-<translation id="1053591932240354961">Spletnega mesta <ph name="SITE" /> trenutno ni mogoÄe obiskati, saj je poslalo Å¡ifrirane poverilnice, ki jih Google Chrome ne more obdelati. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Razveljavi dodajanje</translation>
<translation id="10614374240317010">Nikoli shranjeno</translation>
<translation id="106701514854093668">Zaznamki namizja</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Predpomnilnik pravilnika ustrezen</translation>
<translation id="113188000913989374"><ph name="SITE" /> sporoÄa:</translation>
<translation id="1132774398110320017">Nastavitve samodejnega izpolnjevanja v Chromu …</translation>
+<translation id="1150979032973867961">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; operacijski sistem vaÅ¡ega raÄunalnika ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
+<translation id="1151972924205500581">Potrebno je geslo</translation>
<translation id="1152921474424827756">Odprite <ph name="BEGIN_LINK" />predpomnjeno kopijo<ph name="END_LINK" /> strani na naslovu <ph name="URL" /></translation>
<translation id="1158211211994409885">Spletno mesto <ph name="HOST_NAME" /> je nepriÄakovano prekinilo povezavo.</translation>
<translation id="1161325031994447685">znova vzpostaviti povezavo z omrežjem Wi-Fi</translation>
+<translation id="1165039591588034296">Napaka</translation>
<translation id="1175364870820465910">&amp;Natisni ...</translation>
<translation id="1181037720776840403">Odstrani</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Samodejno poroÄanje<ph name="END_WHITEPAPER_LINK" /> podrobnosti morebitnih varnostnih dogodkov Googlu. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">VeÄ s tega mesta</translation>
<translation id="1206967143813997005">Neveljaven prvotni podpis</translation>
<translation id="1209206284964581585">Zaenkrat skrij</translation>
+<translation id="121201262018556460">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar ima strežnik potrdilo s Å¡ibkim kljuÄem. Napadalec je morda deÅ¡ifriral zasebni kljuÄ in strežnik morda ni tisti, ki ste ga priÄakovali (morda komunicirate z napadalcem).</translation>
<translation id="1219129156119358924">Varnost sistema</translation>
<translation id="1227224963052638717">Neznan pravilnik</translation>
<translation id="1227633850867390598">Skrij vrednost</translation>
<translation id="1228893227497259893">NapaÄni identifikator subjekta</translation>
<translation id="1232569758102978740">Brez naslova</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sinhronizirano)</translation>
<translation id="1263231323834454256">Bralni seznam</translation>
<translation id="1264126396475825575">PoroÄilo o zruÅ¡itvi je bilo zajeto takrat: <ph name="CRASH_TIME" /> (ni Å¡e naloženo ali je prezrto)</translation>
+<translation id="1281526147609854549">Izdal: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Nevarna vsebina blokirana</translation>
<translation id="1285320974508926690">Nikoli ne prevedi tega spletnega mesta</translation>
<translation id="129553762522093515">Nedavno zaprto</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Poskusite izbrisati piškotke<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Vaša dejavnost <ph name="BEGIN_EMPHASIS" />je morda še vedno vidna<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />spletnim mestom, ki jih obiÅ¡Äete,
+ <ph name="LIST_ITEM" />delodajalcu ali Å¡oli,
+ <ph name="LIST_ITEM" />ponudniku internetnih storitev.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Domena za prijavo:</translation>
<translation id="1340482604681802745">Naslov za prevzem</translation>
<translation id="1344211575059133124">Videti je, da za obisk tega spletnega mesta potrebujete dovoljenje</translation>
<translation id="1344588688991793829">Nastavitve samodejnega izpolnjevanja v Chromiumu …</translation>
+<translation id="1348198688976932919">Spletno mesto vsebuje nevarne aplikacije</translation>
<translation id="1374468813861204354">predlogi</translation>
<translation id="1375198122581997741">O razliÄici</translation>
<translation id="1377321085342047638">Card Number</translation>
<translation id="139305205187523129">Spletno mesto <ph name="HOST_NAME" /> ni poslalo nobenih podatkov.</translation>
<translation id="1407135791313364759">Odpri vse</translation>
<translation id="1413809658975081374">Napaka zasebnosti</translation>
+<translation id="14171126816530869">Identiteto organizacije <ph name="ORGANIZATION" /> v kraju <ph name="LOCALITY" /> je potrdil izdajatelj <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Da</translation>
<translation id="1430915738399379752">Natisni</translation>
-<translation id="1442912890475371290">PrepreÄen poskus <ph name="BEGIN_LINK" />dostopa do strani v domeni <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Spletnega mesta <ph name="SITE" /> trenutno ni mogoÄe obiskati, ker uporablja pripenjanje potrdil. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}two{<ph name="PAYMENT_METHOD_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Prikaži shranjeno (zastarelo) kopijo te strani.</translation>
<translation id="1517433312004943670">Telefonska Å¡tevilka je obvezna</translation>
<translation id="1519264250979466059">Datum gradnje</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">ÄŒe želite uporabljati to funkcijo, mora biti omogoÄen JavaScript.</translation>
<translation id="1555130319947370107">Modra</translation>
<translation id="1559528461873125649">Taka datoteka ali imenik ne obstaja</translation>
-<translation id="1559572115229829303">&lt;p&gt;Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoÄe vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v napravi nepravilna.&lt;/p&gt;
-
- &lt;p&gt;V razdelku &lt;strong&gt;Splošno&lt;/strong&gt; aplikacije &lt;strong&gt;Nastavitve&lt;/strong&gt; prilagodite datum in uro.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Med prikazom spletne strani je prišlo do napake.</translation>
<translation id="1592005682883173041">Dostop do lokalnih podatkov</translation>
+<translation id="1594030484168838125">Izberi</translation>
<translation id="161042844686301425">Cianova</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Ali želite, da Chrome shrani to kartico?</translation>
<translation id="1639239467298939599">Nalaganje</translation>
<translation id="1640180200866533862">Uporabniški pravilniki</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Omrežna konfiguracija ni veljavna in je ni mogoÄe uvoziti.</translation>
<translation id="1644574205037202324">Zgodovina</translation>
<translation id="1645368109819982629">Nepodprt protokol</translation>
+<translation id="1655462015569774233">{1,plural, =1{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo vÄeraj. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran.}one{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevom. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran.}two{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevoma. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran.}few{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevi. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran.}other{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevi. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran.}}</translation>
<translation id="1656489000284462475">Prevzem</translation>
<translation id="1663943134801823270">Kartice in naslovi so iz Chroma. Upravljate jih lahko v <ph name="BEGIN_LINK" />nastavitvah<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Spletno mesto <ph name="SITE" /> za zaÅ¡Äito vaÅ¡ih podatkov obiÄajno uporablja Å¡ifriranje. Ko se je Google Chrome tokrat poskusil povezati s spletnim mestom <ph name="SITE" />, je to vrnilo nenavadne in nepravilne poverilnice. Do tega lahko pride, Äe se napadalec lažno predstavlja za spletno mesto <ph name="SITE" /> ali Äe je povezavo prekinil zaslon za prijavo v omrežje Wi-Fi. VaÅ¡i podatki so Å¡e vedno varni, saj je Google Chrome pred izmenjavo podatkov prekinil povezavo.</translation>
-<translation id="168328519870909584">Napadalci, ki so trenutno na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, lahko poskusijo v vaÅ¡i napravi namestiti nevarne programe, ki kradejo ali briÅ¡ejo podatke (na primer fotografije, gesla, sporoÄila in podatke kreditnih kartic).</translation>
<translation id="168841957122794586">Potrdilo strežnika vsebuje Å¡ibek Å¡ifrirni kljuÄ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo jutriÅ¡nji datum. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.}one{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dan od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.}two{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dneva od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.}few{Strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dni od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.}other{Strežniku ni uspelo dokazati, dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dni od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.}}</translation>
<translation id="1710259589646384581">Operacijski sistem</translation>
<translation id="1721312023322545264"><ph name="NAME" /> vam mora odobriti obisk tega spletnega mesta</translation>
<translation id="1721424275792716183">*Polje je obvezno</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Prenesi stran pozneje</translation>
<translation id="17513872634828108">Odpri zavihke</translation>
<translation id="1753706481035618306">Å tevilka strani</translation>
+<translation id="1763864636252898013">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; operacijski sistem vaÅ¡e naprave ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Poskušajte zagnati orodje Omrežna diagnostika Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Posodobite geslo za sinhronizacijo.</translation>
<translation id="1787142507584202372">Tu so prikazani odprti zavihki</translation>
+<translation id="1789575671122666129">Pojavna okna</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Ime imetnika kartice</translation>
-<translation id="1803678881841855883">Googlova funkcija varnega brskanja je na spletnem mestu <ph name="SITE" /> nedavno <ph name="BEGIN_LINK" />zaznala zlonamerno programsko opremo<ph name="END_LINK" />. Spletna mesta, ki so obiÄajno varna, so vÄasih okužena z zlonamerno programsko opremo. Zlonamerno vsebino razÅ¡irja znani distributer zlonamerne programske opreme, <ph name="SUBRESOURCE_HOST" />. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Dodano: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Neveljavna zahteva ali parametri zahteve</translation>
<translation id="1826516787628120939">Preverjanje</translation>
<translation id="1834321415901700177">Na tem spletnem mestu so Å¡kodljivi programi</translation>
+<translation id="1840414022444569775">Ta številka kartice je že v uporabi</translation>
<translation id="1842969606798536927">PlaÄilo</translation>
<translation id="1871208020102129563">Proxy je nastavljen na uporabo stalnih strežnikov proxy, ne na URL skripta .pac.</translation>
<translation id="1871284979644508959">Obvezno polje</translation>
<translation id="187918866476621466">Odpiranje strani ob zagonu</translation>
<translation id="1883255238294161206">Strni seznam</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}two{<ph name="SHIPPING_ADDRESS_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Filtriranje</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Brez}=1{1 spletno mesto}one{# spletno mesto}two{# spletni mesti}few{# spletna mesta}other{# spletnih mest}}</translation>
<translation id="194030505837763158">Pojdite na <ph name="LINK" /></translation>
<translation id="1962204205936693436">Zaznamki domene <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Napaka pri serializaciji</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Prezrto, ker je to preglasil pravilnik <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Iskanje strani za FiziÄni splet v bližini</translation>
<translation id="213826338245044447">Zaznamki mobilne naprave</translation>
-<translation id="2148716181193084225">Danes</translation>
+<translation id="2147827593068025794">Sinhroniziranje v ozadju</translation>
<translation id="2154054054215849342">Sinhronizacija ni na voljo za vašo domeno</translation>
<translation id="2154484045852737596">Urejanje kartice</translation>
<translation id="2166049586286450108">Polni skrbniški dostop</translation>
<translation id="2166378884831602661">To spletno mesto ne more zagotoviti varne povezave</translation>
<translation id="2181821976797666341">Pravilniki</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 naslov}one{# naslov}two{# naslova}few{# naslovi}other{# naslovov}}</translation>
+<translation id="2187317261103489799">Zaznava (privzeto)</translation>
<translation id="2202020181578195191">Vnesite veljavno leto poteka veljavnosti</translation>
<translation id="2212735316055980242">Pravilnika ni mogoÄe najti</translation>
<translation id="2213606439339815911">Prenos vnosov ...</translation>
+<translation id="2218879909401188352">Napadalci, ki so trenutno na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, bi lahko namestili nevarne aplikacije, ki poÅ¡kodujejo napravo, dodali skrite stroÅ¡ke na raÄun za mobilno napravo ali ukradli osebne podatke. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Odpravite težave s povezavo z <ph name="BEGIN_LINK" />aplikacijo za diagnostiko<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Pošlji</translation>
<translation id="225207911366869382">Vrednost za ta pravilnik je zastarela.</translation>
<translation id="2262243747453050782">Napaka HTTP</translation>
+<translation id="2270484714375784793">Telefonska Å¡tevilka</translation>
<translation id="2282872951544483773">Preizkusi, ki niso na voljo</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element}one{<ph name="ITEM_COUNT" /> element}two{<ph name="ITEM_COUNT" /> elementa}few{<ph name="ITEM_COUNT" /> elementi}other{<ph name="ITEM_COUNT" /> elementov}}</translation>
<translation id="2292556288342944218">Internetni dostop je blokiran</translation>
<translation id="230155334948463882">Nova kartica?</translation>
-<translation id="2305919008529760154">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je bilo morda izdano z goljufijo. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">Domena <ph name="DOMAIN" /> zahteva uporabniško ime in geslo.</translation>
-<translation id="2318774815570432836">Spletnega mesta <ph name="SITE" /> trenutno ni mogoÄe obiskati, saj uporablja protokol HSTS. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">Nastavitev nadzira vaš skrbnik</translation>
<translation id="2354001756790975382">Drugi zaznamki</translation>
+<translation id="2354430244986887761">Google Varno brskanje je nedavno <ph name="BEGIN_LINK" />našlo škodljive aplikacije<ph name="END_LINK" /> na spletnem mestu <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Napadalci morda vidijo slike, ki si jih ogledujete na tem spletnem mestu, in vas ukanijo, tako da jih spremenijo.</translation>
+<translation id="2356070529366658676">Vprašaj</translation>
+<translation id="2359629602545592467">VeÄ valut</translation>
<translation id="2359808026110333948">Nadaljuj</translation>
<translation id="2365563543831475020">PoroÄilo o zruÅ¡itvi, zajeto takrat: <ph name="CRASH_TIME" />, ni bilo naloženo</translation>
<translation id="2367567093518048410">Raven</translation>
-<translation id="2371153335857947666">{1,plural, =1{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo vÄeraj. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}one{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevom. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}two{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevoma. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}few{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevi. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}other{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je poteklo pred # dnevi. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. Ura vaÅ¡ega raÄunalnika je trenutno nastavljena na <ph name="CURRENT_DATE" />. Je to videti v redu? ÄŒe ni, pravilno nastavite sistemsko uro in nato osvežite stran. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Ni nadomestnih uporabniških vmesnikov</translation>
<translation id="2384307209577226199">Privzeto za podjetja</translation>
<translation id="2386255080630008482">Potrdilo strežnika je bilo preklicano.</translation>
<translation id="2392959068659972793">Pokaži pravilnike brez nastavljene vrednosti</translation>
<translation id="239429038616798445">Ta naÄin poÅ¡iljanja ni na voljo. Poskusite uporabiti drugega.</translation>
<translation id="2396249848217231973">&amp;Razveljavi izbris</translation>
-<translation id="2460160116472764928">Googlova funkcija varnega brskanja je na spletnem mestu <ph name="SITE" /> nedavno <ph name="BEGIN_LINK" />zaznala zlonamerno programsko opremo<ph name="END_LINK" />.Spletna mesta, ki so obiÄajno varna, so vÄasih okužena z zlonamerno programsko opremo. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; njegovo varnostno potrdilo je bilo morda preklicano. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
<translation id="2463739503403862330">Izpolni</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Izvajanje orodja za omrežno diagnostiko<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Neveljaven URL iskanja.</translation>
+<translation id="2482878487686419369">Obvestila</translation>
<translation id="2491120439723279231">V potrdilu strežnika so napake.</translation>
<translation id="2495083838625180221">RazÄlenjevalnik za JSON</translation>
<translation id="2495093607237746763">Če je izbrana ta možnost, bo Chromium shranil kopijo kartice v tej napravi za hitrejše izpolnjevanje obrazcev.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Nazaj</translation>
<translation id="2515629240566999685">preveriti signal na svojem obmoÄju</translation>
<translation id="2516305470678292029">Nadomestni uporabniški vmesniki</translation>
+<translation id="2539524384386349900">Zaznava</translation>
<translation id="255002559098805027">Spletno mesto <ph name="HOST_NAME" /> je poslalo neveljaven odgovor.</translation>
-<translation id="2552545117464357659">Novejša</translation>
<translation id="2556876185419854533">&amp;Razveljavi urejanje</translation>
<translation id="2587730715158995865">Izdajatelj: <ph name="ARTICLE_PUBLISHER" />. Preberite to in Å¡e toliko drugih Älankov: <ph name="OTHER_ARTICLE_COUNT" />.</translation>
<translation id="2587841377698384444">ID API-ja imenika:</translation>
<translation id="2597378329261239068">Dokument je zaÅ¡Äiten z geslom. Vnesite geslo.</translation>
<translation id="2609632851001447353">RazliÄice</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Brez}=1{1 aplikacija ($1)}=2{2 aplikaciji ($1, $2)}one{# aplikacija ($1, $2, $3)}two{# aplikaciji ($1, $2, $3)}few{# aplikacije ($1, $2, $3)}other{# aplikacij ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Ura prehiteva</translation>
<translation id="2639739919103226564">Stanje:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Dostop do datoteke je bil zavrnjen</translation>
<translation id="2653659639078652383">Pošlji</translation>
<translation id="2666117266261740852">Zaprite druge zavihke ali aplikacije</translation>
+<translation id="2670429602441959756">Ta stran ima funkcije, ki jih navidezna resniÄnost Å¡e ne podpira. Zapiranje ...</translation>
<translation id="2674170444375937751">Ali ste prepriÄani, da želite te strani izbrisati iz svoje zgodovine?</translation>
<translation id="2677748264148917807">Zapusti</translation>
-<translation id="269990154133806163">Strežnik je posredoval potrdilo, ki ni bilo javno razkrito na podlagi pravilnika o preglednosti potrdila. To je obvezno za nekatera potrdila zaradi zagotavljanja, da so zaupanja vredna in Å¡Äitijo pred napadalci. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Reading List</translation>
<translation id="2704283930420550640">Vrednost se ne ujema z obliko.</translation>
<translation id="2704951214193499422">Chromium trenutno ni mogel potrditi vaše kartice. Poskusite znova pozneje.</translation>
<translation id="2705137772291741111">Shranjena (predpomnjena) kopija tega spletnega mesta je bila neberljiva.</translation>
<translation id="2709516037105925701">Samodejno izpolnjevanje</translation>
-<translation id="2712118517637785082">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar je izdajatelj preklical potrdilo, ki ga je posredoval strežnik. To pomeni, da varnostnim poverilnicam, ki jih je posredoval strežnik, nikakor ne smete zaupati. Morda komunicirate z napadalcem. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">Zahtevaj dovoljenje</translation>
<translation id="2713444072780614174">Bela</translation>
<translation id="2720342946869265578">V bližini</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Manjka zapis o napravi</translation>
<translation id="2784949926578158345">Povezava je bila obnovljena.</translation>
<translation id="2794233252405721443">Spletno mesto blokirano</translation>
+<translation id="2799020568854403057">Spletno mesto vsebuje Å¡kodljive aplikacije</translation>
+<translation id="2803306138276472711">Googlova funkcija varnega brskanja je na spletnem mestu <ph name="SITE" /> nedavno <ph name="BEGIN_LINK" />zaznala zlonamerno programsko opremo<ph name="END_LINK" />. Spletna mesta, ki so obiÄajno varna, so vÄasih okužena z zlonamerno programsko opremo.</translation>
<translation id="2824775600643448204">Naslovna in iskalna vrstica</translation>
<translation id="2826760142808435982">Za Å¡ifriranje in preverjanje pristnosti povezave se uporablja <ph name="CIPHER" />, kot mehanizem za izmenjavo kljuÄev pa <ph name="KX" />.</translation>
<translation id="2835170189407361413">PoÄisti obrazec</translation>
+<translation id="2856444702002559011">Morda poskuÅ¡ajo napadalci ukrasti vaÅ¡e podatke s spletnega mesta <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (na primer gesla, sporoÄila ali podatke kreditnih kartic). <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ne naloži znova</translation>
<translation id="2900469785430194048">Google Chromu je med poskusom prikazovanja te spletne strani zmanjkalo pomnilnika.</translation>
<translation id="2909946352844186028">Zaznana je bila sprememba omrežja.</translation>
<translation id="2916038427272391327">Zaprite druge programe</translation>
<translation id="2922350208395188000">Potrdila strežnika ni mogoÄe preveriti.</translation>
<translation id="2928905813689894207">Naslov za izstavitev raÄuna</translation>
+<translation id="2941952326391522266">Strežniku ni uspelo dokazati, da je res <ph name="DOMAIN" />; njegovo varnostno potrdilo je od <ph name="DOMAIN2" />. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
<translation id="2948083400971632585">NamestniÅ¡ke strežnike, konfigurirane za povezavo, lahko onemogoÄite na strani z nastavitvami.</translation>
<translation id="2955913368246107853">Zapri vrstico za iskanje</translation>
<translation id="2958431318199492670">Omrežna konfiguracija ne ustreza standardu ONC. Deli konfiguracije morda niso bili uvoženi.</translation>
-<translation id="29611076221683977">Napadalci, ki so trenutno na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, lahko poskusijo v vaÅ¡em raÄunalniku Mac namestiti nevarne programe, ki kradejo ali briÅ¡ejo podatke (na primer fotografije, gesla, sporoÄila in podatke kreditnih kartic).</translation>
<translation id="2966678944701946121">Datum poteka: <ph name="EXPIRATION_DATE_ABBR" />, dodano: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">ÄŒe želite vzpostaviti varno povezavo, mora biti ura pravilno nastavljena. Potrdila, ki jih uporabljajo spletna mesta za prepoznavanje, namreÄ veljajo samo doloÄen Äas. Ker je ura naprave nepravilna, Google Chrome teh potrdil ne more preveriti.</translation>
<translation id="2972581237482394796">&amp;Uveljavi</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Vnesite veljaven naslov</translation>
<translation id="2986368408720340940">Ta naÄin prevzema ni na voljo. Poskusite uporabiti drugega.</translation>
<translation id="2991174974383378012">Deljenje s spletnimi mesti</translation>
+<translation id="2991571918955627853">Spletnega mesta <ph name="SITE" /> trenutno ni mogoÄe obiskati, saj uporablja protokol HSTS. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje.</translation>
<translation id="3005723025932146533">Pokaži shranjeno kopijo</translation>
<translation id="3008447029300691911">Vnesite CVC za <ph name="CREDIT_CARD" />. Ko potrdite, bodo temu spletnemu mestu razkriti podatki o vaši kartici.</translation>
<translation id="3010559122411665027">Vnos na sznamu »<ph name="ENTRY_INDEX" />«: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Samodejno blokirano</translation>
<translation id="3024663005179499861">NapaÄna vrsta pravilnika</translation>
<translation id="3032412215588512954">Ali želite znova naložiti to spletno mesto?</translation>
<translation id="3037605927509011580">Ti Å¡ment!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{vsaj en element v sinhroniziranih napravah}=1{1 element (in veÄ v sinhroniziranih napravah)}one{# element (in veÄ v sinhroniziranih napravah)}two{# elementa (in veÄ v sinhroniziranih napravah)}few{# elementi (in veÄ v sinhroniziranih napravah)}other{# elementov (in veÄ v sinhroniziranih napravah)}}</translation>
<translation id="3041612393474885105">Informacije o potrdilu</translation>
<translation id="3063697135517575841">Chrome trenutno ni mogel potrditi vaše kartice. Poskusite znova pozneje.</translation>
<translation id="3064966200440839136">Zaradi plaÄila v zunanji aplikaciji boste zapustili naÄin brez beleženja zgodovine. Želite nadaljevati?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Brez}=1{1 geslo}one{# geslo}two{# gesli}few{# gesla}other{# gesel}}</translation>
<translation id="3093245981617870298">Povezava ni vzpostavljena.</translation>
<translation id="3105172416063519923">ID sredstva:</translation>
<translation id="3109728660330352905">Nimate dovoljenja za ogled te strani.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Poskušajte zagnati orodje Diagnostika povezljivosti<ph name="END_LINK" /></translation>
<translation id="3145945101586104090">Dekodiranje odziva ni uspelo</translation>
<translation id="3150653042067488994">ZaÄasna napaka strežnika</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Strani, ki si jih ogledujete na zavihkih brez beleženja zgodovine, se ne bodo ohranile v zgodovini brskalnika, hrambi piškotkov ali zgodovini iskanja, ko boste zaprli vse zavihke brez beleženja zgodovine. Datoteke, ki jih prenesete, ali zaznamki, ki jih ustvarite, se bodo ohranili.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Otok</translation>
+<translation id="317583078218509884">Nove nastavitve dovoljenj za spletno mesto bodo zaÄele veljati, ko znova naložite stran.</translation>
<translation id="3176929007561373547">Preverite nastavitve strežnika proxy ali se obrnite na skrbnika omrežja in
poskrbite za delovanje strežnika proxy. Če menite, da vam strežnika proxy
ni treba uporabljati:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Odprite stran v naÄinu brez beleženja zgodovine</translation>
-<translation id="3202578601642193415">Najnovejše</translation>
+<translation id="320323717674993345">PrekliÄi plaÄilo</translation>
<translation id="3207960819495026254">Zaznamovano</translation>
+<translation id="3225919329040284222">Strežnik je poslal potrdilo, ki se ne ujema z vgrajenimi priÄakovanji. Ta priÄakovanja so zaradi vaÅ¡e varnosti vkljuÄena za nekatera strogo zavarovana spletna mesta.</translation>
<translation id="3226128629678568754">Pritisnite gumb za vnoviÄno nalaganje, da znova poÅ¡ljete podatke za nalaganje strani.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Prevod ni uspel, ker je stran že v jeziku <ph name="LANGUAGE" /></translation>
<translation id="323107829343500871">Vnesite CVC za <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Vedno zaznaj pomembno vsebino na tem spletnem mestu</translation>
<translation id="3254409185687681395">Zaznamujte to stran</translation>
<translation id="3270847123878663523">&amp;Razveljavi razvrstitev</translation>
<translation id="3282497668470633863">Dodajanje imena na kartico</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">nastavitve</translation>
<translation id="3345135638360864351">Zahteve za dostop do tega spletnega mesta ni bilo mogoÄe poslati osebi <ph name="NAME" />. Poskusite znova.</translation>
<translation id="3355823806454867987">Spremeni nastavitve proxyja ...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />ne shrani<ph name="END_EMPHASIS" /> teh podatkov:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />zgodovine brskanja,
+ <ph name="LIST_ITEM" />piškotkov in podatkov spletnih mest,
+ <ph name="LIST_ITEM" />podatkov, vnesenih v obrazce.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Napaka ure</translation>
-<translation id="337311366426640088">Å e toliko elementov: <ph name="ITEM_COUNT" /> ...</translation>
<translation id="337363190475750230">Nepripravljen</translation>
<translation id="3377188786107721145">Napaka pri razÄlenjevanju pravilnika</translation>
<translation id="3380365263193509176">Neznana napaka</translation>
<translation id="3380864720620200369">ID odjemalca:</translation>
<translation id="3391030046425686457">Naslov za dostavo</translation>
<translation id="3395827396354264108">NaÄin prevzema</translation>
-<translation id="340013220407300675">Napadalci morda poskuÅ¡ajo ukrasti vaÅ¡e podatke s spletnega mesta <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (na primer gesla, sporoÄila ali kreditne kartice).</translation>
<translation id="3422248202833853650">Poskusite zapreti druge programe, da boste tako sprostili pomnilnik.</translation>
<translation id="3422472998109090673">Spletno mesto <ph name="HOST_NAME" /> trenutno ni dosegljivo.</translation>
+<translation id="3427092606871434483">Dovoli (privzeto)</translation>
<translation id="3427342743765426898">&amp;Uveljavi urejanje</translation>
<translation id="3431636764301398940">Shrani to kartico v tej napravi</translation>
<translation id="3435896845095436175">OmogoÄi</translation>
<translation id="3447661539832366887">Lastnik te naprave je izklopil igro z dinozavri</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">Interval prejemanja:</translation>
<translation id="3462200631372590220">Skrij podrobnosti</translation>
<translation id="3467763166455606212">Ime imetnika kartice je obvezno</translation>
<translation id="3478058380795961209">Expiration Month</translation>
<translation id="3479539252931486093">Ali tega niste priÄakovali? <ph name="BEGIN_LINK" />SporoÄite nam<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ne zdaj</translation>
-<translation id="348000606199325318">ID zrušitve <ph name="CRASH_LOCAL_ID" /> (ID strežnika: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Trenutno ni mogoÄe vzpostaviti stika s starÅ¡em. Poskusi znova pozneje.</translation>
<translation id="3528171143076753409">Potrdilo strežnika ni zaupanja vredno.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Vsaj en element v sinhroniziranih napravah}=1{1 element (in veÄ v sinhroniziranih napravah)}one{# element (in veÄ v sinhroniziranih napravah)}two{# elementa (in veÄ v sinhroniziranih napravah)}few{# elementi (in veÄ v sinhroniziranih napravah)}other{# elementov (in veÄ v sinhroniziranih napravah)}}</translation>
<translation id="3539171420378717834">Ohrani kopijo te kartice v tej napravi</translation>
<translation id="3542684924769048008">Uporaba gesla za:</translation>
+<translation id="3545341443414427877">Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoÄe vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v raÄunalniku nepravilna. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Å ifrirajte vse sinhronizirane podatke s svojim geslom</translation>
-<translation id="3549761410225185768">In Å¡e <ph name="NUM_TABS_MORE" /> ...</translation>
-<translation id="3555561725129903880">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je od <ph name="DOMAIN2" />. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Skrbnik ga lahko odblokira</translation>
<translation id="3566021033012934673">Vaša povezava ni zasebna</translation>
+<translation id="3569145463236695319">&lt;p&gt;Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoÄe vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v napravi nepravilna.&lt;/p&gt;
+
+ &lt;p&gt;V razdelku &lt;strong&gt;SploÅ¡no&lt;/strong&gt; aplikacije &lt;strong&gt;Nastavitve&lt;/strong&gt; prilagodite datum in uro.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Dodajte ime</translation>
<translation id="3583757800736429874">&amp;Uveljavi premik</translation>
<translation id="3586931643579894722">Skrij podrobnosti</translation>
-<translation id="3587482841069643663">Vse</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Vnesite veljaven datum poteka veljavnosti</translation>
<translation id="36224234498066874">Izbriši podatke brskanja ...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Informacije o potrdilu</translation>
<translation id="3690164694835360974">Prijava ni varna</translation>
<translation id="3693415264595406141">Geslo:</translation>
-<translation id="3696411085566228381">brez</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Nalaganje ...</translation>
<translation id="3712624925041724820">Ni dovolj licenc</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />preveriti strežnik proxy, požarni zid in konfiguracijo DNS-ja<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">ÄŒe se zavedate varnostnega tveganja, lahko <ph name="BEGIN_LINK" />obiÅ¡Äete to spletno mesto, ki ni varno<ph name="END_LINK" />, preden bodo nevarni programi odstranjeni.</translation>
<translation id="3739623965217189342">Povezava, ki ste jo kopirali</translation>
+<translation id="3744899669254331632">Spletnega mesta <ph name="SITE" /> trenutno ne morete obiskati, ker je poslalo Å¡ifrirane poverilnice, ki jih Chromium ne more obdelati. Napake v omrežju in napadi so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje.</translation>
+<translation id="3748148204939282805">Napadalci na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vas lahko z zavajanjem morda pripravijo do tega, da storite kaj nevarnega – denimo, da namestite programsko opremo ali razkrijete osebne podatke (na primer gesla, telefonske Å¡tevilke ali podatke kreditnih kartic). <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Prevajanje ni uspelo zaradi napake strežnika.</translation>
<translation id="3759461132968374835">Nimate nedavnih poroÄil o zruÅ¡itvah. ZruÅ¡itve, do katerih je priÅ¡lo, ko je bilo poroÄanje onemogoÄeno, ne bodo prikazane zukaj.</translation>
+<translation id="3778403066972421603">Ali želite shraniti to kartico v Google RaÄun in v tej napravi?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">PoteÄe: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Če uporabite namestniški strežnik ...</translation>
<translation id="3828924085048779000">Prazno geslo ni dovoljeno.</translation>
-<translation id="3845539888601087042">Prikazana je zgodovina iz naprav, v katere ste prijavljeni. <ph name="BEGIN_LINK" />VeÄ o tem<ph name="END_LINK" /></translation>
<translation id="385051799172605136">Nazaj</translation>
<translation id="3858027520442213535">Posodobi datum in uro</translation>
<translation id="3884278016824448484">Identifikator naprave je v sporu</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Vaša zahteva za dostop do tega mesta je poslana uporabniku <ph name="NAME" /></translation>
<translation id="3890664840433101773">Dodajanje e-poštnega naslova</translation>
<translation id="3901925938762663762">Kartica je potekla</translation>
-<translation id="3933571093587347751">{1,plural, =1{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo jutriÅ¡nji datum. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}one{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dan od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}two{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dneva od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}few{Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dni od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}other{Temu strežniku ni uspelo dokazati, dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo naj bi imelo datum v prihodnosti – # dni od danes. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Dokumenta PDF ni bilo mogoÄe naložiti</translation>
+<translation id="3945915738023014686">ID naloženega poroÄila o zruÅ¡itvah <ph name="CRASH_ID" /> (ID lokalne zruÅ¡itve: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; njegovo varnostno potrdilo ne doloÄa nadomestnih imen SAN (Subject Alternative Name). Razlog za to je morda napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
<translation id="3963721102035795474">NaÄin bralnika</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Brez}=1{1 spletno mesto }one{# spletno mesto }two{# spletni mesti }few{# spletna mesta }other{# spletnih mest }}</translation>
<translation id="397105322502079400">IzraÄunavanje …</translation>
<translation id="3973234410852337861">Spletno mesto <ph name="HOST_NAME" /> je blokirano</translation>
+<translation id="3987940399970879459">Manj kot 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 spletna stran v bližini}one{# spletna stran v bližini}two{# spletni strani v bližini}few{# spletne strani v bližini}other{# spletnih strani v bližini}}</translation>
<translation id="4021036232240155012">DNS je omrežna storitev, ki ime spletnega mesta prevede v njegov internetni naslov.</translation>
<translation id="4030383055268325496">&amp;Razveljavi dodajanje</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Konfiguracija strežnika proxy je nastavljena na uporabo URL-ja skripta .pac, ne na stalne strežnike proxy.</translation>
<translation id="4098354747657067197">ZavajajoÄe spletno mesto</translation>
<translation id="4103249731201008433">Neveljavna serijska Å¡tevilka naprave</translation>
+<translation id="410351446219883937">Samodejno predvajanje</translation>
<translation id="4103763322291513355">Na &lt;strong&gt;chrome://policy&lt;/strong&gt; si lahko ogledate seznam blokiranih URL-jev in drugih pravilnikov, ki jih uveljavlja skrbnik sistema.</translation>
-<translation id="4110615724604346410">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo vsebuje napake. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Å krlatna</translation>
+<translation id="4116663294526079822">Vedno dovoli na tem spletnem mestu</translation>
<translation id="4117700440116928470">Obseg pravilnika ni podprt.</translation>
-<translation id="4118212371799607889">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; Chromium ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{in Å¡e 1 drug}one{in Å¡e # drug}two{in Å¡e # druga}few{in Å¡e # drugi}other{in Å¡e # drugih}}</translation>
<translation id="4130226655945681476">preveriti omrežne kable, modem in usmerjevalnik</translation>
+<translation id="413544239732274901">VeÄ o tem</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Globalno uporabi privzete nastavitve (zaznavanje)</translation>
+<translation id="4165986682804962316">Nastavitve spletnega mesta</translation>
<translation id="4169947484918424451">Ali želite, da Chromium shrani to kartico?</translation>
<translation id="4171400957073367226">Neveljavni podpis za preverjanje</translation>
<translation id="4196861286325780578">&amp;Uveljavi premik</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />preveriti požarni zid in konfiguracije protivirusnega programa<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{niÄ}=1{1 aplikacija ($1)}=2{2 aplikaciji ($1, $2)}one{# aplikacija ($1, $2, $3)}two{# aplikaciji ($1, $2, $3)}few{# aplikacije ($1, $2, $3)}other{# aplikacij ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Zrušitve</translation>
+<translation id="422022731706691852">Napadalci na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vas bodo morda poskusili zavesti, da bi namestili programe, ki Å¡kodljivo vplivajo na brskanje (na primer tako, da spremenijo vaÅ¡o domaÄo stran ali na spletnih mestih, ki jih obiÅ¡Äete, prikazujejo dodatne oglase). <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Poskušajte zagnati orodje za omrežno diagnostiko<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Veljavno</translation>
<translation id="4250431568374086873">Povezava s tem mestom ni povsem varna.</translation>
<translation id="4250680216510889253">Ne</translation>
<translation id="425582637250725228">Spremembe, ki ste jih naredili, morda niso shranjene.</translation>
<translation id="4258748452823770588">NapaÄen podpis</translation>
+<translation id="4265872034478892965">OmogoÄil skrbnik</translation>
<translation id="4269787794583293679">(Ni uporabniškega imena)</translation>
<translation id="4275830172053184480">Znova zaženite napravo.</translation>
<translation id="4280429058323657511">, datum poteka veljavnosti: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Googlova funkcija varnega brskanja je na spletnem mestu <ph name="SITE" /> nedavno <ph name="BEGIN_LINK" />odkrila Å¡kodljive programe<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Predlogi staršev</translation>
<translation id="4304224509867189079">Prijava</translation>
-<translation id="432290197980158659">Strežnik je poslal potrdilo, ki se ne ujema z vgrajenimi priÄakovanji. Ta priÄakovanja so zaradi vaÅ¡e varnosti vkljuÄena za nekatera strogo zavarovana spletna mesta. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blokira (privzeto)</translation>
<translation id="4325863107915753736">ÄŒlanka ni bilo mogoÄe najti</translation>
<translation id="4326324639298822553">Preverite datum poteka veljavnosti in poskusite znova.</translation>
<translation id="4331708818696583467">Ni varno</translation>
<translation id="4356973930735388585">Napadalci na tem spletnem mestu lahko poskusijo v vaÅ¡em raÄunalniku namestiti nevarne programe, ki kradejo ali briÅ¡ejo podatke (na primer fotografije, gesla, sporoÄila in podatke kreditnih kartic).</translation>
<translation id="4372948949327679948">PriÄakovana vrednost je vrste <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar je izdajatelj preklical potrdilo, ki ga je poslal strežnik. To pomeni, da varnostnim poverilnicam, ki jih je poslal strežnik, nikakor ne smete zaupati. Morda komunicirate z napadalcem.</translation>
<translation id="4381091992796011497">Uporabniško ime:</translation>
<translation id="4394049700291259645">OnemogoÄi</translation>
<translation id="4406896451731180161">rezultati iskanja</translation>
+<translation id="4424024547088906515">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; Chrome ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
<translation id="4432688616882109544">Spletno mesto <ph name="HOST_NAME" /> ni sprejelo potrdila za prijavo ali pa to ni bilo posredovano.</translation>
<translation id="443673843213245140">Uporaba strežnika proxy je onemogoÄena, vendar je njegova konfiguracija izrecno doloÄena.</translation>
-<translation id="4492190037599258964">Rezultati iskanja za »<ph name="SEARCH_STRING" />«</translation>
<translation id="4506176782989081258">Napaka pri preverjanju veljavnosti: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">se obrniti na skrbnika sistema</translation>
<translation id="450710068430902550">Deljenje s skrbnikom</translation>
<translation id="4515275063822566619">Kartice in naslovi so iz Chroma in Google RaÄuna (<ph name="ACCOUNT_EMAIL" />). Upravljate jih lahko v <ph name="BEGIN_LINK" />nastavitvah<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Podrobnosti</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Poskusite onemogoÄiti razÅ¡iritve.</translation>
<translation id="457875822857220463">Dostava</translation>
<translation id="4587425331216688090">Želite odstraniti naslov iz Chroma?</translation>
-<translation id="4589078953350245614">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar je strežnik posredoval neveljavno potrdilo. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Povezava z domeno <ph name="DOMAIN" /> je Å¡ifrirana s sodobno Å¡ifrirno zbirko.</translation>
<translation id="4594403342090139922">&amp;Razveljavi izbris</translation>
<translation id="4619615317237390068">Zavihki iz drugih naprav</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; njegovo varnostno potrdilo vsebuje napake. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
+<translation id="4690462567478992370">Prenehaj uporabljati neveljavno potrdilo</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Povezava je bila prekinjena</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Izvajanje orodja Omrežna diagnostika Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Prišlo je do neznane napake.</translation>
<translation id="4800132727771399293">Preverite datum poteka in Å¡tevilko CVC ter poskusite znova</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Spletnega mesta <ph name="SITE" /> trenutno ne morete obiskati, saj je poslalo Å¡ifrirane poverilnice, ki jih Google Chrome ne more obdelati. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje.</translation>
<translation id="4813512666221746211">Napaka v omrežju</translation>
<translation id="4816492930507672669">Prilagodi strani</translation>
<translation id="483020001682031208">Ni strani za FiziÄni splet za prikaz</translation>
<translation id="4850886885716139402">Pogled</translation>
<translation id="4854362297993841467">Ta naÄin poÅ¡iljanja ni na voljo. Poskusite uporabiti drugega.</translation>
<translation id="4858792381671956233">Starše si vprašal(-a), ali smeš obiskati to spletno mesto</translation>
+<translation id="4863764087567530506">Ta vsebina vas morda poskuša zavesti, da namestite programsko opremo ali razkrijete osebne podatke. <ph name="BEGIN_LINK" />Vseeno prikaži<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Zgodovina iskanja</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{in Å¡e 1 spletna stran}one{in Å¡e # spletna stran}two{in Å¡e # spletni strani}few{in Å¡e # spletne strani}other{in Å¡e # spletnih strani}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Stran je bila iz neznanega jezika prevedena v jezik »<ph name="LANGUAGE_LANGUAGE" />«</translation>
<translation id="4923459931733593730">PlaÄilo</translation>
<translation id="4926049483395192435">Vrednost mora biti doloÄena.</translation>
<translation id="495170559598752135">Dejanja</translation>
<translation id="4958444002117714549">Razširi seznam</translation>
-<translation id="4962322354953122629">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; Chrome ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">VnoviÄno omogoÄanje opozoril</translation>
<translation id="4989809363548539747">Ta vtiÄnik ni podprt</translation>
<translation id="5002932099480077015">ÄŒe je to omogoÄeno, Chrome shrani kopijo kartice v tej napravi zaradi hitrejÅ¡ega izpolnjevanja obrazcev.</translation>
<translation id="5018422839182700155">Te strani ni mogoÄe odpreti</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Preverite skrbnikove pravilnike</translation>
<translation id="5029568752722684782">PoÄisti kopijo</translation>
<translation id="5031870354684148875">Google Prevajalnik – vizitka</translation>
+<translation id="5039804452771397117">Dovoli</translation>
<translation id="5040262127954254034">Zasebnost</translation>
<translation id="5045550434625856497">Nepravilno geslo</translation>
<translation id="5056549851600133418">ÄŒlanki za vas</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />preveriti naslov strežnika proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Brez piškotkov}=1{1 spletno mesto uporablja piškotke. }one{# spletno mesto uporablja piškotke. }two{# spletni mesti uporabljata piškotke. }few{# spletna mesta uporabljajo piškotke. }other{# spletnih mest uporablja piškotke. }}</translation>
<translation id="5087286274860437796">Potrdilo strežnika trenutno ni veljavno.</translation>
<translation id="5087580092889165836">Dodaj kartico</translation>
<translation id="5089810972385038852">Zvezna država</translation>
+<translation id="5094747076828555589">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; Chromium ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
<translation id="5095208057601539847">Provinca</translation>
<translation id="5115563688576182185">(64-bitno)</translation>
<translation id="5141240743006678641">Å ifrirajte sinhronizirana gesla s poverilnicami za Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-poštni naslov je obvezen</translation>
<translation id="5251803541071282808">Oblak</translation>
<translation id="5277279256032773186">Uporabljate Chrome v službi? Podjetja lahko upravljajo nastavitve Chroma za zaposlene. Preberite veÄ o tem.</translation>
+<translation id="5297526204711817721">Povezava s tem spletnim mestom ni zasebna. ÄŒe želite kadar koli zapustiti naÄin navidezne resniÄnosti, snemite naglavni komplet in pritisnite tipko za nazaj.</translation>
<translation id="5299298092464848405">Napaka pri razÄlenjevanju pravilnika</translation>
-<translation id="5300589172476337783">Pokaži</translation>
<translation id="5308689395849655368">PoroÄanje o zruÅ¡itvah je onemogoÄeno.</translation>
<translation id="5317780077021120954">Shrani</translation>
<translation id="5327248766486351172">Ime</translation>
-<translation id="5337705430875057403">Napadalci na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vas lahko z zavajanjem pripravijo do tega, da storite kaj nevarnega – denimo, da namestite programsko opremo ali razkrijete osebne podatke (na primer gesla, telefonske številke ali podatke kreditnih kartic).</translation>
-<translation id="5359637492792381994">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo trenutno ni veljavno. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Spletnega mesta <ph name="SITE" /> trenutno ni mogoÄe obiskati, saj je to potrdilo preklicano. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje.</translation>
<translation id="536296301121032821">Nastavitev pravilnika ni bilo mogoÄe shraniti</translation>
<translation id="5386426401304769735">Veriga potrdil za to spletno mesto vsebuje potrdilo, podpisano z algoritmom SHA-1.</translation>
<translation id="5402410679244714488">Datum poteka: <ph name="EXPIRATION_DATE_ABBR" />, zadnja uporaba pred veÄ kot enim letom</translation>
+<translation id="540969355065856584">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; njegovo varnostno potrdilo trenutno ni veljavno. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
<translation id="5421136146218899937">Izbriši podatke brskanja ...</translation>
<translation id="5430298929874300616">Odstrani zaznamek</translation>
<translation id="5431657950005405462">Datoteke ni bilo mogoÄe najti</translation>
-<translation id="5435775191620395718">Prikazana je zgodovina iz te naprave. <ph name="BEGIN_LINK" />VeÄ o tem<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">Napaka preverjanja sheme pri »<ph name="ERROR_PATH" />«: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Te strani spletnega mesta <ph name="HOST_NAME" /> ni mogoÄe najti</translation>
<translation id="5455374756549232013">NapaÄen Äasovni žig pravilnika</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> od <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Neveljavno</translation>
<translation id="5470861586879999274">&amp;Uveljavi urejanje</translation>
<translation id="54817484435770891">Dodajanje veljavnega naslova</translation>
<translation id="5492298309214877701">To spletno mesto v intranetu podjetja, organizacije ali Å¡ole ima enak URL kot zunanje spletno mesto.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Prevzem na tem naslovu ni mogoÄ. Izberite drugega.</translation>
<translation id="5572851009514199876">ZaÄnite s prijavo v Chrome, da lahko Chrome preveri, ali vam je dovoljeno dostopati do tega spletnega mesta.</translation>
<translation id="5580958916614886209">Preverite mesec poteka veljavnosti in poskusite znova</translation>
+<translation id="5586446728396275693">Ni shranjenih naslovov</translation>
+<translation id="5595485650161345191">Uredi naslov</translation>
<translation id="560412284261940334">Upravljanje ni podprto</translation>
<translation id="5610142619324316209">preveriti povezavo</translation>
<translation id="5610807607761827392">Kartice in naslove je mogoÄe upravljati v <ph name="BEGIN_LINK" />nastavitvah<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Ali želite zapustiti to spletno mesto?</translation>
<translation id="5629630648637658800">Nastavitev pravilnika ni bilo mogoÄe naložiti</translation>
<translation id="5631439013527180824">Neveljaven žeton za upravljanje naprave</translation>
+<translation id="5633066919399395251">Napadalci na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> lahko poskusijo v vaÅ¡em raÄunalniku namestiti nevarne programe, ki kradejo ali briÅ¡ejo podatke (na primer fotografije, gesla, sporoÄila in podatke kreditnih kartic). <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Lokacija</translation>
+<translation id="5659593005791499971">E-pošta</translation>
<translation id="5669703222995421982">Prilagojena vsebina</translation>
<translation id="5675650730144413517">Ta stran ne deluje</translation>
-<translation id="5677928146339483299">Blokirano</translation>
-<translation id="5694783966845939798">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar je strežnik posredoval potrdilo, podpisano s Å¡ibkim podpisnim algoritmom (na primer SHA-1). To pomeni, da so varnostne poverilnice, ki jih je posredoval strežnik, morda ponarejene in strežnik morda ni tisti, ki ga priÄakujete (morda komunicirate z napadalcem). <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Identiteta tega spletnega mesta ni bila potrjena.</translation>
+<translation id="5713016350996637505">ZavajajoÄa vsebina blokirana</translation>
<translation id="5720705177508910913">Trenutni uporabnik</translation>
<translation id="5732392974455271431">Starši ga lahko odblokirajo</translation>
<translation id="5763042198335101085">Vnesite veljaven e-poštni naslov</translation>
<translation id="5765072501007116331">ÄŒe si želite ogledati naÄine dostave in zahteve, izberite naslov</translation>
+<translation id="5778550464785688721">Popolni nadzor naprav MIDI</translation>
<translation id="5784606427469807560">Težava pri potrditvi kartice. Preverite internetno povezavo in poskusite znova.</translation>
<translation id="5785756445106461925">Poleg tega so na tej strani druga sredstva, ki niso varna. Ta sredstva lahko med prenosom pregledujejo drugi, morebitni napadalec pa jih lahko spremeni, tako da se spremeni videz strani.</translation>
<translation id="5786044859038896871">Ali želite izpolniti podatke kreditne kartice?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Uveljavi dodajanje</translation>
<translation id="5814352347845180253">Morda boste izgubili dostop do plaÄljive vsebine na spletnem mestu <ph name="SITE" /> in drugih spletnih mestih.</translation>
<translation id="5838278095973806738">Na tem spletnem mestu ne vnaÅ¡ajte obÄutljivih informacij (npr. gesel ali Å¡tevilk kreditnih kartic), ker jih lahko ukradejo napadalci.</translation>
-<translation id="5843436854350372569">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar ima strežnik potrdilo s Å¡ibkim kljuÄem. Napadalec je morda deÅ¡ifriral zasebni kljuÄ in strežnik morda ni tisti, ki ste ga priÄakovali (morda komunicirate z napadalcem). <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Tega spletnega mesta ni mogoÄe doseÄi</translation>
<translation id="5869522115854928033">Shranjena gesla</translation>
<translation id="5872918882028971132">Predlogi staršev</translation>
<translation id="5901630391730855834">Rumena</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (sinhronizirano)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 v uporabi}one{# v uporabi}two{# v uporabi}few{# v uporabi}other{# v uporabi}}</translation>
<translation id="5926846154125914413">Morda boste izgubili dostop do plaÄljive vsebine na nekaterih spletnih mestih.</translation>
<translation id="5959728338436674663">Samodejno pošlji Googlu nekatere <ph name="BEGIN_WHITEPAPER_LINK" />sistemske podatke in vsebino strani<ph name="END_WHITEPAPER_LINK" /> zaradi zaznavanja nevarnih aplikacij in spletnih mest. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Teden</translation>
<translation id="5967867314010545767">Odstrani iz zgodovine</translation>
<translation id="5975083100439434680">Pomanjšaj</translation>
<translation id="598637245381783098">PlaÄilne aplikacije ni mogoÄe odpreti</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Stran 1}one{Stran #}two{Stran #}few{Stran #}other{Stran #}}</translation>
<translation id="6017514345406065928">Zelena</translation>
+<translation id="6017850046339264347">Napadalci na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> bi lahko namestili zavajajoÄe aplikacije, ki se pretvarjajo, da so nekaj drugega, ali zbirajo podatke, s katerimi vas lahko spremljajo. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (sinhronizirano)</translation>
<translation id="6027201098523975773">Vnesite ime</translation>
<translation id="6040143037577758943">Zapri</translation>
<translation id="6042308850641462728">VeÄ</translation>
+<translation id="6047233362582046994">ÄŒe se zavedate varnostnega tveganja, lahko <ph name="BEGIN_LINK" />obiÅ¡Äete to spletno mesto<ph name="END_LINK" />, preden bodo Å¡kodljive aplikacije odstranjene.</translation>
+<translation id="6051221802930200923">Spletnega mesta <ph name="SITE" /> trenutno ni mogoÄe obiskati, ker uporablja pripenjanje potrdil. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje.</translation>
<translation id="6060685159320643512">Previdno, ti poskusi lahko Å¡kodujejo</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{niÄ}=1{1}one{#}two{#}few{#}other{#}}</translation>
+<translation id="6080696365213338172">Do vsebine ste dostopali z geslom, ki ga je zagotovil skrbnik. Podatke, ki jih pošljete v <ph name="DOMAIN" />, lahko prestreže skrbnik.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Brez}=1{1 geslo (sinhronizirano)}one{# geslo (sinhronizirano)}two{# gesli (sinhronizirani)}few{# gesla (sinhronizirana)}other{# gesel (sinhroniziranih)}}</translation>
<translation id="6146055958333702838">Preverite kable in znova zaženite usmerjevalnike, modeme ali druge omrežne
naprave, ki jih uporabljate.</translation>
<translation id="614940544461990577">Poskusite:</translation>
<translation id="6151417162996330722">Potrdilo strežnika ima predolgo obdobje veljavnosti.</translation>
<translation id="6157877588268064908">ÄŒe si želite ogledati naÄine poÅ¡iljanja in zahteve, izberite naslov</translation>
+<translation id="6158003235852588289">Googlova funkcija varnega brskanja je nedavno zaznala lažno predstavljanje na spletnem mestu <ph name="SITE" />. Spletna mesta z lažnim predstavljanjem zavajajo ljudi, tako da se izdajajo za druga spletna mesta.</translation>
<translation id="6165508094623778733">VeÄ o tem</translation>
+<translation id="6169916984152623906">Zdaj je mogoÄe brskati zasebno in drugi, ki uporabljajo to napravo, ne bodo videli vaÅ¡e dejavnosti. Prenosi in zaznamki bodo vseeno shranjeni.</translation>
<translation id="6177128806592000436">Povezava s tem spletnim mestom ni zasebna</translation>
<translation id="6184817833369986695">(kohorta: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Preverite internetno povezavo</translation>
<translation id="6218753634732582820">Želite naslov odstraniti iz Chromiuma?</translation>
+<translation id="6221345481584921695">Googlova funkcija varnega brskanja je na spletnem mestu <ph name="BEGIN_LINK" /> nedavno <ph name="END_LINK" />zaznala zlonamerno programsko opremo<ph name="SITE" />. Spletna mesta, ki so obiÄajno varna, so vÄasih okužena z zlonamerno programsko opremo. Zlonamerno vsebino razÅ¡irja znani distributer zlonamerne programske opreme, <ph name="SUBRESOURCE_HOST" />.</translation>
<translation id="6251924700383757765">Pravilnik o zasebnosti</translation>
<translation id="6254436959401408446">Ni dovolj pomnilnika za odpiranje te strani</translation>
<translation id="625755898061068298">Izbrali ste onemogoÄanje varnostnih opozoril za to spletno mesto.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Uredi zaznamek</translation>
<translation id="6410264514553301377">Vnesite datum poteka veljavnosti in kodo CVC za kartico <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Starša si vprašal(-a), ali smeš obiskati to spletno mesto</translation>
-<translation id="6416403317709441254">Spletnega mesta <ph name="SITE" /> trenutno ne morete obiskati, saj je poslalo Å¡ifrirane poverilnice, ki jih Chromium ne more obdelati. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Ni mogoÄe preveriti, ali je bilo potrdilo preklicano.</translation>
<translation id="6433490469411711332">Uredi informacije o stiku</translation>
<translation id="6433595998831338502">Spletno mesto <ph name="HOST_NAME" /> ni dovolilo povezave.</translation>
<translation id="6446608382365791566">Dodajanje veÄ podatkov</translation>
+<translation id="6447842834002726250">Piškotki</translation>
<translation id="6451458296329894277">Potrdite ponovno pošiljanje obrazca</translation>
<translation id="6456339708790392414">PlaÄilo</translation>
<translation id="6458467102616083041">Prezrto, ker je pravilnik onemogoÄil privzeto iskanje.</translation>
-<translation id="6462969404041126431">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; njegovo varnostno potrdilo je bilo morda preklicano. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Pravilniki za naprave</translation>
<translation id="6477321094435799029">Chrome je zaznal nenavadno kodo na tej strani in jo zaradi zaÅ¡Äite vaÅ¡ih osebnih podatkov (na primer gesel, telefonskih Å¡tevilk in kreditnih kartic) blokiral.</translation>
<translation id="6489534406876378309">ZaÄetek prenaÅ¡anja zruÅ¡itev v storitev</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Datum poteka: <ph name="EXPIRATION_DATE_ABBR" />, zadnja uporaba: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Skrbnik Å¡e ni odobril</translation>
<translation id="6569060085658103619">Ogledujete si stran razširitve</translation>
-<translation id="6593753688552673085">manj kot <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Ta vsebina morda v napravi poskuša namestiti nevarno programsko opremo, ki ukrade ali izbriše vaše podatke. <ph name="BEGIN_LINK" />Vseeno prikaži<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Možnosti šifriranja</translation>
<translation id="662080504995468778">Ostani</translation>
<translation id="6626291197371920147">Dodajanje veljavne Å¡tevilke kartice</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Iskanje</translation>
+<translation id="6630809736994426279">Napadalci, ki so trenutno na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, lahko poskusijo v vaÅ¡em raÄunalniku Mac namestiti nevarne programe, ki kradejo ali briÅ¡ejo podatke (na primer fotografije, gesla, sporoÄila in podatke kreditnih kartic). <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Ta pravilnik je zastarel.</translation>
-<translation id="6652240803263749613">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; operacijski sistem vaÅ¡ega raÄunalnika ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Želite predlog obrazca odstraniti iz Chromiuma?</translation>
<translation id="6685834062052613830">Odjavite se in dokonÄajte nastavitev</translation>
<translation id="6710213216561001401">Nazaj</translation>
<translation id="6710594484020273272">&lt;Vnesite iskalno poizvedbo&gt;</translation>
<translation id="6711464428925977395">Nekaj je narobe s strežnikom proxy ali pa naslov ni pravilen.</translation>
<translation id="6727102863431372879">Nastavi</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{niÄ}=1{1 element}one{# element}two{# elementa}few{# elementi}other{# elementov}}</translation>
<translation id="674375294223700098">Neznana napaka potrdila strežnika.</translation>
<translation id="6753269504797312559">Vrednost pravilnika</translation>
<translation id="6757797048963528358">Naprava je preklopila v stanje pripravljenosti.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ID za prilagajanje</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Podatkov o obmoÄjih ni bilo mogoÄe naložiti</translation>
+<translation id="6825578344716086703">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar ima strežnik potrdilo, podpisano s Å¡ibkim podpisnim algoritmom (kot je SHA-1). To pomeni, da so varnostne poverilnice, ki jih je poslal strežnik, morda ponarejene in strežnik morda ni tisti, ki ga priÄakujete (morda komunicirate z napadalcem).</translation>
+<translation id="6830728435402077660">Ni varno</translation>
<translation id="6831043979455480757">Prevedi</translation>
<translation id="6839929833149231406">ObmoÄje</translation>
<translation id="6874604403660855544">&amp;Uveljavi dodajanje</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Kartica je potrjena.</translation>
<translation id="6897140037006041989">Uporabnikov posrednik</translation>
<translation id="6915804003454593391">Uporabnik:</translation>
+<translation id="6945221475159498467">Izberi</translation>
<translation id="6948701128805548767">ÄŒe si želite ogledati naÄine prevzema in zahteve, izberite naslov</translation>
<translation id="6957887021205513506">Potrdilo strežnika je oÄitno ponaredek.</translation>
<translation id="6965382102122355670">V redu</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">DoloÄeni so stalni strežniki proxy in URL skripta .pac.</translation>
<translation id="6989763994942163495">Prikaži dodatne nastavitve ...</translation>
<translation id="7000990526846637657">Ni vnosov v zgodovino</translation>
-<translation id="7009986207543992532">Poskusili ste dostopati do domene <ph name="DOMAIN" />, vendar je strežnik uporabil potrdilo, ki ima predolgo obdobje veljavnosti, da bi bilo verodostojno. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">V Google RaÄunu so morda druge vrste zgodovine brskanja na <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Gesla</translation>
+<translation id="7050187094878475250">Poskusili ste odpreti <ph name="DOMAIN" />, vendar je strežnik uporabil potrdilo, ki ima predolgo obdobje veljavnosti, da bi bilo verodostojno.</translation>
+<translation id="7053983685419859001">Blokiraj</translation>
<translation id="7064851114919012435">Podatki o stiku</translation>
<translation id="7079718277001814089">To spletno mesto vsebuje zlonamerno programsko opremo</translation>
<translation id="7087282848513945231">Okraj</translation>
-<translation id="7088615885725309056">Starejše</translation>
<translation id="7090678807593890770">IÅ¡Äite v Googlu s poizvedbo <ph name="LINK" /></translation>
+<translation id="7108819624672055576">OmogoÄa razÅ¡iritev</translation>
<translation id="7119414471315195487">Zaprite druge zavihke ali programe</translation>
<translation id="7129409597930077180">PoÅ¡iljanje na ta naslov ni mogoÄe. Izberite drugega.</translation>
<translation id="7138472120740807366">NaÄin dostave</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Obdelovanje</translation>
<translation id="724691107663265825">Spletno mesto z zlonamerno programsko opremo</translation>
<translation id="724975217298816891">Vnesite datum poteka in CVC za <ph name="CREDIT_CARD" />, da posodobite podatke o kartici. Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kartici.</translation>
-<translation id="725866823122871198">Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoÄe vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v raÄunalniku nepravilna.</translation>
+<translation id="7260504762447901703">Ukinitev dostopa</translation>
<translation id="7275334191706090484">Upravljani zaznamki</translation>
<translation id="7298195798382681320">PriporoÄeni</translation>
<translation id="7309308571273880165">PoroÄilo o zruÅ¡itvi, zajeto takrat: <ph name="CRASH_TIME" /> (uporabnik je zahteval nalaganje; ni Å¡e bilo naloženo)</translation>
<translation id="7334320624316649418">&amp;Uveljavi razvrstitev</translation>
<translation id="733923710415886693">Potrdilo strežnika ni bilo razkrito na podlagi pravilnika o preglednosti potrdila.</translation>
-<translation id="7351800657706554155">Spletnega mesta <ph name="SITE" /> trenutno ni mogoÄe obiskati, saj je to potrdilo preklicano. Napake omrežja in napadi na omrežje so obiÄajno zaÄasni, zato bo ta stran verjetno delovala pozneje. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Ukazna vrstica</translation>
<translation id="7372973238305370288">rezultat iskanja</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> – <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ne</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Potrditev kartice</translation>
-<translation id="7394102162464064926">Ali ste prepriÄani, da želite te strani izbrisati iz zgodovine?
-
-Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za naÄin brez beleženja zgodovine.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Pot profila</translation>
<translation id="7424977062513257142">Vdelana stran na tej spletni strani sporoÄa:</translation>
@@ -688,6 +754,7 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="7444046173054089907">To spletno mesto je blokirano</translation>
<translation id="7445762425076701745">Identitete strežnika, s katerim ste povezani, ni mogoÄe v celoti preveriti. S strežnikom ste povezani z uporabo imena, ki je veljavno samo v vaÅ¡em omrežju, zato zunanji overitelj potrdil ne more preveriti njegovega lastniÅ¡tva. Ker nekateri overitelji potrdil kljub temu izdajajo potrdila za takÅ¡na imena, ni mogoÄe zagotoviti, da ste povezani z želenim spletnim mestom in ne z napadalcem.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Preberite veÄ<ph name="END_LINK" /> o tej težavi.</translation>
+<translation id="7455133967321480974">Uporabi globalno privzeto (Blokiraj)</translation>
<translation id="7460163899615895653">Tu so prikazani nedavni zavihki iz drugih naprav</translation>
<translation id="7469372306589899959">Potrjevanje kartice</translation>
<translation id="7481312909269577407">Naprej</translation>
@@ -695,36 +762,43 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="7508255263130623398">Vrnjen ID naprave pravilnika je prazen ali se ne ujema s trenutnim ID-jem naprave</translation>
<translation id="7514365320538308">Prenos</translation>
<translation id="7518003948725431193">Za ta spletni naslov in bilo mogoÄe najti nobene spletne strani:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Vrednost</translation>
<translation id="7537536606612762813">Obvezen</translation>
+<translation id="7542403920425041731">Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kartici.</translation>
<translation id="7542995811387359312">Samodejno izpolnjevanje podatkov o kreditni kartici je onemogoÄeno, ker ta obrazec ne uporablja varne povezave.</translation>
<translation id="7543525346216957623">Prosi starša</translation>
<translation id="7549584377607005141">Za pravilen prikaz te strani so potrebni podatki, ki ste jih vnesli prej. Podatke lahko pošljete še enkrat, vendar se bodo s tem ponovila vsa prejšnja dejanja strani.</translation>
<translation id="7552846755917812628">Poskusite te nasvete:</translation>
<translation id="7554791636758816595">Nov zavihek</translation>
+<translation id="7567204685887185387">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; njegovo varnostno potrdilo je bilo morda izdano z goljufijo. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}two{<ph name="CONTACT_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Ta stran je v jeziku:<ph name="ORIGINAL_LANGUAGE" />Jo želite prevesti?</translation>
<translation id="7569952961197462199">Želite odstraniti kreditno kartico iz Chroma?</translation>
<translation id="7569983096843329377">ÄŒrna</translation>
<translation id="7578104083680115302">Hitro plaÄevanje na spletnih mestih in v aplikacijah v vseh napravah s karticami, ki ste jih shranili v Googlu.</translation>
<translation id="7588950540487816470">FiziÄni splet</translation>
<translation id="7592362899630581445">Strežnikovo potrdilo krši omejitve imen.</translation>
+<translation id="7598391785903975535">Manj kot <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">Spletno mesto <ph name="HOST_NAME" /> trenutno ne more obdelati te zahteve.</translation>
<translation id="7600965453749440009">Nikoli ne prevedi iz jezika: <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Vrednost je zunaj obsega <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Veljavnost do: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Podatke, ki so Å¡ifrirani z drugo razliÄico gesla za Google RaÄun, že imate. Geslo vnesite spodaj.</translation>
-<translation id="7634554953375732414">Povezava s tem mestom ni zasebna.</translation>
<translation id="7637571805876720304">Želite kreditno kartico odstraniti iz Chromiuma?</translation>
<translation id="765676359832457558">Skrij dodatne nastavitve ...</translation>
<translation id="7658239707568436148">PrekliÄi</translation>
+<translation id="7662298039739062396">Nastavitev nadzira razširitev</translation>
<translation id="7667346355482952095">Vrnjen žeton pravilnika je prazen ali se ne ujema s trenutnim žetonom</translation>
<translation id="7668654391829183341">Neznana naprava</translation>
<translation id="7669271284792375604">Napadalci na tem spletnem mestu vas bodo morda poskusili zavesti, da bi namestili programe, ki Å¡kodljivo vplivajo na brskanje (na primer tako, da spremenijo vaÅ¡o domaÄo stran ali na spletnih mestih, ki jih obiÅ¡Äete, prikazujejo dodatne oglase).</translation>
<translation id="7674629440242451245">Vas zanimajo super nove funkcije Chroma? Preskusite naš kanal za razvijalce na chrome.com/dev.</translation>
<translation id="7682287625158474539">Pošiljanje</translation>
+<translation id="7701040980221191251">Brez</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Nadaljuj na spletno mesto <ph name="SITE" /> (ni varno)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Potrdilo</translation>
+<translation id="7716147886133743102">Blokiral skrbnik</translation>
<translation id="7716424297397655342">Tega spletnega mesta ni mogoÄe naložiti iz predpomnilnika</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Odstranjen iz uporabe</translation>
<translation id="7755287808199759310">Starš ga lahko odblokira</translation>
<translation id="7758069387465995638">Povezavo je morda blokiral požarni zid ali protivirusni program.</translation>
@@ -751,15 +825,15 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="7951415247503192394">(32-bitno)</translation>
<translation id="7956713633345437162">Zaznamki mobilne naprave</translation>
<translation id="7961015016161918242">Nikoli</translation>
-<translation id="7962083544045318153">ID zrušitve <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Vedno prevedi iz jezika <ph name="ORIGINAL_LANGUAGE" /> v jezik <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ni navedeno</translation>
<translation id="800218591365569300">Poskusite zapreti druge zavihke ali programe, da boste tako sprostili pomnilnik.</translation>
<translation id="8012647001091218357">Trenutno ni mogoÄe vzpostaviti stika s starÅ¡i. Poskusi znova pozneje.</translation>
<translation id="8025119109950072390">Napadalci na tem spletnem mestu vas lahko z zavajanjem morda pripravijo do tega, da storite kaj nevarnega – denimo, da namestite programsko opremo ali razkrijete osebne podatke (na primer gesla, telefonske številke ali podatke kreditnih kartic).</translation>
-<translation id="803030522067524905">Googlova funkcija varnega brskanja je nedavno zaznala lažno predstavljanje na spletnem mestu <ph name="SITE" />. Spletna mesta z lažnim predstavljanjem zavajajo ljudi, tako da se izdajajo za druga spletna mesta. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Ta stran je v jeziku <ph name="SOURCE_LANGUAGE" />. Jo želite prevesti v jezik <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Zahteva (privzeto)</translation>
<translation id="8041089156583427627">Pošlji povratne informacije</translation>
+<translation id="8041940743680923270">Uporabi globalno privzeto (Vprašaj)</translation>
<translation id="8088680233425245692">ÄŒlanka si ni bilo mogoÄe ogledati.</translation>
<translation id="8089520772729574115">manj kot 1 MB</translation>
<translation id="8091372947890762290">Čakanje na aktivacijo v strežniku</translation>
@@ -768,13 +842,14 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />Naslova DNS<ph name="END_ABBR" /> strežnika spletnega mesta <ph name="HOST_NAME" /> ni bilo mogoÄe najti.</translation>
<translation id="8149426793427495338">RaÄunalnik je preklopil v stanje pripravljenosti.</translation>
<translation id="8150722005171944719">Datoteke na <ph name="URL" /> ni mogoÄe prebrati. Morda je odstranjena, premaknjena ali pa dostop prepreÄujejo dovoljenja za datoteke.</translation>
+<translation id="8184538546369750125">Uporabi globalno privzeto (Dovoli)</translation>
+<translation id="8191494405820426728">ID lokalne zrušitve <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Razveljavi premik</translation>
<translation id="8201077131113104583">Neveljaven posodobitveni URL za razširitev z ID-jem »<ph name="EXTENSION_ID" />«.</translation>
<translation id="8202097416529803614">Povzetek naroÄila</translation>
<translation id="8218327578424803826">Dodeljena lokacija:</translation>
<translation id="8225771182978767009">Oseba, ki je nastavila ta raÄunalnik, je blokirala to spletno mesto.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Napadalci, ki so trenutno na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, lahko poskusijo v vaÅ¡em raÄunalniku namestiti nevarne programe, ki kradejo ali briÅ¡ejo podatke (na primer fotografije, gesla, sporoÄila in podatke kreditnih kartic).</translation>
<translation id="8241707690549784388">Stran, ki jo iÅ¡Äete, je uporabila informacije, ki ste jih vnesli. Z vrnitvijo na to stran se bodo morda ponovila vsa vaÅ¡a dejanja, ki ste jih opravili. Ali želite nadaljevati?</translation>
<translation id="8249320324621329438">Nazadnje preneseno:</translation>
<translation id="8253091569723639551">Naslov za izstavitev raÄuna je obvezen</translation>
@@ -782,6 +857,7 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="8289355894181816810">ÄŒe niste prepriÄani, kaj to pomeni, se obrnite na skrbnika omrežja.</translation>
<translation id="8293206222192510085">Dodaj zaznamek</translation>
<translation id="8294431847097064396">Vir</translation>
+<translation id="8306404619377842860">Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoÄe vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v napravi nepravilna. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Prevod ni uspel zaradi težave s povezavo omrežja.</translation>
<translation id="8332188693563227489">Dostop do spletnega mesta <ph name="HOST_NAME" /> je bil zavrnjen</translation>
<translation id="834457929814110454">ÄŒe se zavedate varnostnega tveganja, lahko <ph name="BEGIN_LINK" />obiÅ¡Äete to spletno mesto<ph name="END_LINK" />, preden bodo Å¡kodljivi programi odstranjeni.</translation>
@@ -802,11 +878,9 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="8483780878231876732">ÄŒe želite uporabljati kartice iz Google RaÄuna, se prijavite v Chrome</translation>
<translation id="8488350697529856933">Velja za</translation>
<translation id="8498891568109133222">Spletno mesto <ph name="HOST_NAME" /> se ni odzvalo v ustreznem Äasu.</translation>
-<translation id="852346902619691059">Temu strežniku ni uspelo dokazati, da je domena <ph name="DOMAIN" />; operacijski sistem vaÅ¡e naprave ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napaÄna konfiguracija ali napadalÄevo prestrezanje povezave. <ph name="BEGIN_LEARN_MORE_LINK" />VeÄ o tem<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Expiration Year</translation>
<translation id="8543181531796978784"><ph name="BEGIN_ERROR_LINK" />Prijavite lahko težavo z zaznavanjem<ph name="END_ERROR_LINK" />, Äe razumete varnostna tveganja, pa lahko <ph name="BEGIN_LINK" />obiÅ¡Äete to spletno mesto, ki ni varno<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Prevod ni uspel, ker ni mogoÄe doloÄiti jezika strani.</translation>
-<translation id="8559762987265718583">Zasebne povezave z domeno <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ni mogoÄe vzpostaviti, ker sta datum in ura (<ph name="DATE_AND_TIME" />) v napravi nepravilna.</translation>
<translation id="8571890674111243710">Prevajanje strani v jezik <ph name="LANGUAGE" /> ...</translation>
<translation id="858637041960032120">Dodajte tel. Å¡t. </translation>
<translation id="859285277496340001">Potrdilo ne navaja mehanizma za preverjanje tega, ali je bilo preklicano.</translation>
@@ -820,6 +894,7 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="8738058698779197622">ÄŒe želite vzpostaviti varno povezavo, mora biti ura pravilno nastavljena. Potrdila, ki jih uporabljajo spletna mesta za prepoznavanje, namreÄ veljajo samo doloÄen Äas. Ker je ura sistema nepravilna, Chromium teh potrdil ne more preveriti.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;Naslova DNS&lt;/abbr&gt; spletnega mesta <ph name="HOST_NAME" /> ni bilo mogoÄe najti. Poteka diagnosticiranje težave.</translation>
<translation id="8759274551635299824">Ta kartica je potekla</translation>
+<translation id="8761567432415473239">Googlova funkcija varnega brskanja je nedavno <ph name="BEGIN_LINK" />odkrila Å¡kodljive programe<ph name="END_LINK" /> na spletnem mestu <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Uveljavi izbris</translation>
<translation id="8800988563907321413">Tu so prikazani predlogi v bližini</translation>
<translation id="8820817407110198400">Zaznamki</translation>
@@ -832,29 +907,30 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="8870413625673593573">Nedavno zaprto</translation>
<translation id="8874824191258364635">Vnesite veljavno Å¡tevilko kartice</translation>
<translation id="8876793034577346603">Omrežne konfiguracije ni bilo mogoÄe razÄleniti.</translation>
-<translation id="8877192140621905067">Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kartici.</translation>
<translation id="8889402386540077796">Odtenek</translation>
<translation id="8891727572606052622">Neveljaven naÄin strežnika proxy.</translation>
<translation id="889901481107108152">Oprostite, ta poskus ni na voljo za vaše okolje.</translation>
<translation id="8903921497873541725">PoveÄaj</translation>
<translation id="8931333241327730545">Ali želite to kartico shraniti v Google RaÄun?</translation>
<translation id="8932102934695377596">Ura zaostaja</translation>
-<translation id="8954894007019320973">(Nadalj.)</translation>
<translation id="8971063699422889582">Potrdilo strežnika je poteklo.</translation>
<translation id="8986494364107987395">Samodejno poÅ¡lji statistiÄne podatke o uporabi in poroÄila o zruÅ¡itvah Googlu</translation>
-<translation id="8987927404178983737">Mesec</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Pozor: Spletno mesto vsebuje Å¡kodljive programe.</translation>
+<translation id="8997023839087525404">Strežnik je posredoval potrdilo, ki ni bilo javno razkrito na podlagi pravilnika o preglednosti potrdila. To je obvezno za nekatera potrdila zaradi zagotavljanja, da so zaupanja vredna in Å¡Äitijo pred napadalci.</translation>
<translation id="9001074447101275817">Strežnik proxy <ph name="DOMAIN" /> zahteva uporabniško ime in geslo.</translation>
+<translation id="9005998258318286617">Dokumenta PDF ni bilo mogoÄe naložiti.</translation>
<translation id="901974403500617787">Zastavice, ki se uporabijo v celotnem sistemu, lahko nastavi samo lastnik: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Naslov kreditne kartice za raÄune je obvezen</translation>
<translation id="9020542370529661692">Ta stran je prevedena v jezik <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Varnostna napaka</translation>
<translation id="9038649477754266430">Uporaba storitve predvidevanja za hitrejše nalaganje strani</translation>
<translation id="9039213469156557790">Poleg tega so na tej strani druga sredstva, ki niso varna. Ta sredstva lahko med prenosom pregledujejo drugi, morebitni napadalec pa jih lahko spremeni, tako da se spremeni naÄin delovanja strani.</translation>
-<translation id="9040185888511745258">Napadalci na spletnem mestu <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> vas bodo morda poskusili zavesti, da bi namestili programe, ki Å¡kodljivo vplivajo na brskanje (na primer tako, da spremenijo vaÅ¡o domaÄo stran ali na spletnih mestih, ki jih obiÅ¡Äete, prikazujejo dodatne oglase).</translation>
+<translation id="9049981332609050619">Skušali ste dostopati do domene <ph name="DOMAIN" />, vendar je strežnik predložil neveljavno potrdilo.</translation>
<translation id="9050666287014529139">Geslo</translation>
<translation id="9065203028668620118">Uredi</translation>
<translation id="9068849894565669697">Izbira barve</translation>
+<translation id="9069693763241529744">Blokirala razširitev</translation>
<translation id="9076283476770535406">Morda vsebuje vsebino za odrasle</translation>
<translation id="9078964945751709336">Vnesti morate veÄ podatkov</translation>
<translation id="9103872766612412690">Spletno mesto <ph name="SITE" /> za zaÅ¡Äito vaÅ¡ih podatkov obiÄajno uporablja Å¡ifriranje. Ko se je Chromium tokrat poskusil povezati s spletnim mestom <ph name="SITE" />, je to vrnilo nenavadne in nepravilne poverilnice. Do tega lahko pride, Äe se napadalec lažno predstavlja za spletno mesto <ph name="SITE" /> ali Äe je povezavo prekinil zaslon za prijavo v omrežje Wi-Fi. VaÅ¡i podatki so Å¡e vedno varni, saj je Chromium pred izmenjavo podatkov prekinil povezavo.</translation>
@@ -863,16 +939,21 @@ Pst! NaslednjiÄ vam lahko pride prav bližnjica <ph name="SHORTCUT_KEY" /> za n
<translation id="9148507642005240123">&amp;Razveljavi urejanje</translation>
<translation id="9154194610265714752">Posodobljeno</translation>
<translation id="9157595877708044936">Nastavljanje ...</translation>
+<translation id="9169664750068251925">Vedno blokiraj na tem spletnem mestu</translation>
<translation id="9170848237812810038">&amp;Razveljavi</translation>
<translation id="917450738466192189">Potrdilo strežnika ni veljavno.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}two{<ph name="SHIPPING_OPTION_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> in Å¡e <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419">Spletno mesto <ph name="HOST_NAME" /> uporablja nepodprt protokol.</translation>
<translation id="9205078245616868884">Podatki so Å¡ifrirani z vaÅ¡im geslom za sinhronizacijo. Vnesite ga, Äe želite zaÄeti sinhronizacijo.</translation>
<translation id="9207861905230894330">ÄŒlanka ni bilo mogoÄe dodati.</translation>
+<translation id="9219103736887031265">Slike</translation>
<translation id="933612690413056017">Ni internetne povezave</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">POÄŒISTI OBRAZEC</translation>
<translation id="939736085109172342">Nova mapa</translation>
<translation id="941721044073577244">Videti je, da nimate pravice za obisk tega spletnega mesta</translation>
<translation id="969892804517981540">Uradna razliÄica</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Brez}=1{1 element}one{# element}two{# elementa}few{# elementi}other{# elementov}}</translation>
<translation id="988159990683914416">RazliÄica za razvijalce</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sr.xtb b/chromium/components/strings/components_strings_sr.xtb
index 674c02c696a..05ee3f7f3b9 100644
--- a/chromium/components/strings/components_strings_sr.xtb
+++ b/chromium/components/strings/components_strings_sr.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Окрените у Ñмеру казаљке на Ñату</translation>
<translation id="1038842779957582377">непознато име</translation>
<translation id="1050038467049342496">Затворите друге апликације</translation>
-<translation id="1053591932240354961">Тренутно не можете да поÑетите <ph name="SITE" /> зато што је веб-Ñајт поÑлао шифроване акредитиве које Google Chrome не може да обради. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Опозови додавање</translation>
<translation id="10614374240317010">Ðикада Ñе не чува</translation>
<translation id="106701514854093668">Обележивачи на рачунару</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Кеш Ñмерница је у реду</translation>
<translation id="113188000913989374"><ph name="SITE" /> каже:</translation>
<translation id="1132774398110320017">Подешавања Chrome аутоматÑког попуњавања...</translation>
+<translation id="1150979032973867961">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; оперативни ÑиÑтем рачунара нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="1151972924205500581">Лозинка је обавезна</translation>
<translation id="1152921474424827756">ПриÑтупите <ph name="BEGIN_LINK" />кешираној копији<ph name="END_LINK" /> Ñтранице <ph name="URL" /></translation>
<translation id="1158211211994409885">ХоÑÑ‚ <ph name="HOST_NAME" /> је неочекивано прекинуо везу.</translation>
<translation id="1161325031994447685">поново да Ñе повежете Ñа Wi-Fi мрежом</translation>
+<translation id="1165039591588034296">Грешка</translation>
<translation id="1175364870820465910">&amp;Одштампај...</translation>
<translation id="1181037720776840403">Уклони</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />ÐутоматÑки пријави<ph name="END_WHITEPAPER_LINK" /> Google-у детаље о могућим безбедноÑним инцидентима. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Више Ñа овог Ñајта</translation>
<translation id="1206967143813997005">ÐеиÑправан Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ñ˜Ð°Ð»Ð¸Ð¼Ð°</translation>
<translation id="1209206284964581585">Сакриј за Ñада</translation>
+<translation id="121201262018556460">Покушали Ñте да контактирате <ph name="DOMAIN" />, али је Ñервер поÑлао Ñертификат који Ñадржи Ñлаб кључ. Могуће је да је нападач открио приватни кључ и да Ñервер можда није онај који миÑлите да јеÑте (можда комуницирате Ñа нападачем).</translation>
<translation id="1219129156119358924">БезбедноÑÑ‚ ÑиÑтема</translation>
<translation id="1227224963052638717">Ðепознате Ñмернице.</translation>
<translation id="1227633850867390598">Сакриј вредноÑÑ‚</translation>
<translation id="1228893227497259893">Погрешан идентификатор ентитета</translation>
<translation id="1232569758102978740">ÐенаÑловљено</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (Ñинхронизовано)</translation>
<translation id="1263231323834454256">ЛиÑта за читање</translation>
<translation id="1264126396475825575">Извештај о отказивању је Ñнимљен <ph name="CRASH_TIME" /> (још увек није отпремљен или игнориÑан)</translation>
+<translation id="1281526147609854549">Издавач: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">ОпаÑан Ñадржај је блокиран</translation>
<translation id="1285320974508926690">Ðикад не преводи овај Ñајт</translation>
<translation id="129553762522093515">Ðедавно затворено</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Покушајте да обришете колачиће<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">ÐктивноÑти ће <ph name="BEGIN_EMPHASIS" />можда ипак бити видљиве<ph name="END_EMPHASIS" /> за:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />веб-Ñајтове које поÑећујете
+ <ph name="LIST_ITEM" />поÑлодавца или школу
+ <ph name="LIST_ITEM" />интернет провајдера
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Домен упиÑнице:</translation>
<translation id="1340482604681802745">ÐдреÑа преузимања</translation>
<translation id="1344211575059133124">Изгледа да вам је потребна дозвола да биÑте поÑетили овај Ñајт</translation>
<translation id="1344588688991793829">Подешавања Chromium аутоматÑког попуњавања...</translation>
+<translation id="1348198688976932919">Сајт који ћете поÑетити Ñадржи опаÑне апликације</translation>
<translation id="1374468813861204354">предлози</translation>
<translation id="1375198122581997741">О верзији</translation>
<translation id="1377321085342047638">Број картице</translation>
<translation id="139305205187523129">ХоÑÑ‚ <ph name="HOST_NAME" /> није поÑлао никакве податке.</translation>
<translation id="1407135791313364759">Отвори Ñве</translation>
<translation id="1413809658975081374">Грешка у вези Ñа приватношћу</translation>
+<translation id="14171126816530869">Идентитет организације <ph name="ORGANIZATION" /> на локалитету <ph name="LOCALITY" /> је верификовао издавач <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Да</translation>
<translation id="1430915738399379752">Штампај</translation>
-<translation id="1442912890475371290">Блокиран је покушај <ph name="BEGIN_LINK" />поÑећивања Ñтранице на домену <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Тренутно не можете да поÑетите <ph name="SITE" /> зато што веб-Ñајт кориÑти проверу Ñертификата. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Прикажите Ñачувану копију ове Ñтранице (тј. копију за коју Ñе зна да је заÑтарела).</translation>
<translation id="1517433312004943670">Број телефона је обавезан</translation>
<translation id="1519264250979466059">Датум верзије</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript мора да буде омогућен да биÑте кориÑтили ову функцију.</translation>
<translation id="1555130319947370107">Плава</translation>
<translation id="1559528461873125649">Ðема такве датотеке или директоријума</translation>
-<translation id="1559572115229829303">&lt;p&gt;Ðије могуће уÑпоÑтавити приватну везу Ñа доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> јер датум и време на уређају (<ph name="DATE_AND_TIME" />) ниÑу тачни.&lt;/p&gt;
-
- &lt;p&gt;Прилагодите датум и време у одељку &lt;strong&gt;Опште&lt;/strong&gt; у апликацији &lt;strong&gt;Подешавања&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Дошло је до грешке при приказивању ове веб-Ñтранице.</translation>
<translation id="1592005682883173041">ПриÑтуп локалним подацима</translation>
+<translation id="1594030484168838125">Одабери</translation>
<translation id="161042844686301425">Плавозелена</translation>
+<translation id="1620510694547887537">Камера</translation>
<translation id="1629803312968146339">Желите ли да Chrome Ñачува ову картицу?</translation>
<translation id="1639239467298939599">Учитавање</translation>
<translation id="1640180200866533862">Смернице за кориÑнике</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Конфигурација мреже је неважећа и не може да Ñе увезе.</translation>
<translation id="1644574205037202324">ИÑторија</translation>
<translation id="1645368109819982629">Ðеподржани протокол</translation>
+<translation id="1655462015569774233">{1,plural, =1{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао јуче. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу.}one{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу.}few{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу.}other{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу.}}</translation>
<translation id="1656489000284462475">Преузимање</translation>
<translation id="1663943134801823270">Картице и адреÑе Ñу из Chrome-а. Њима можете да управљате у <ph name="BEGIN_LINK" />подешавањима<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> обично кориÑти шифровање да би заштитио информације. Када је Google Chrome овог пута покушао да Ñе повеже Ñа <ph name="SITE" />, веб-Ñајт је вратио необичне и нетачне акредитиве. Или нападач покушава да Ñе предÑтави као <ph name="SITE" /> или је екран за Wi-Fi пријављивање прекинуо везу. Информације Ñу и даље безбедне зато што је Google Chrome прекинуо везу пре него што Ñу размењени било какви подаци.</translation>
-<translation id="168328519870909584">Ðападачи који Ñу тренутно на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ће можда покушати да инÑталирају опаÑне апликације на уређај које краду или бришу податке (на пример, Ñлике, лозинке, поруке и бројеве кредитних картица).</translation>
<translation id="168841957122794586">Сертификат Ñервера Ñадржи Ñлаб криптографÑки кључ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; датум његовог безбедноÑног Ñертификата је наводно Ñутрашњи. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.}one{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је наводно датиран у будућноÑти (за # дан). Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.}few{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је наводно датиран у будућноÑти (за # дана). Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.}other{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је наводно датиран у будућноÑти (за # дана). Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.}}</translation>
<translation id="1710259589646384581">ОС</translation>
<translation id="1721312023322545264">Потребна вам је дозвола кориÑника <ph name="NAME" /> да биÑте поÑетили овај Ñајт</translation>
<translation id="1721424275792716183">* Поље је обавезно</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Преузми Ñтраницу каÑније</translation>
<translation id="17513872634828108">Отворене картице</translation>
<translation id="1753706481035618306">Број Ñтранице</translation>
+<translation id="1763864636252898013">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; оперативни ÑиÑтем уређаја нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Покушајте да покренете Windows дијагноÑтику мреже<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Ðжурирај приÑтупну фразу за Ñинхронизацију</translation>
<translation id="1787142507584202372">Отворене картице Ñе појављују овде</translation>
+<translation id="1789575671122666129">ИÑкачући прозори</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Име влаÑника картице</translation>
-<translation id="1803678881841855883">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило малвер<ph name="END_LINK" /> на <ph name="SITE" />. Веб-Ñајтови који Ñу обично безбедни Ñе понекад заразе малвером. Злонамеран Ñадржај потиче Ñа <ph name="SUBRESOURCE_HOST" />, који је познати диÑтрибутер малвера. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Додато је: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Ðеважећи захтев или параметри захтева</translation>
<translation id="1826516787628120939">Провера</translation>
<translation id="1834321415901700177">Овај Ñајт Ñадржи штетне програме</translation>
+<translation id="1840414022444569775">Овај број картице Ñе већ кориÑти</translation>
<translation id="1842969606798536927">Плаћање</translation>
<translation id="1871208020102129563">ПрокÑи је подешен да кориÑти фикÑне прокÑи Ñервере, а не URL адреÑу .pac Ñкрипте.</translation>
<translation id="1871284979644508959">Обавезно поље</translation>
<translation id="187918866476621466">Отвори почетне Ñтранице</translation>
<translation id="1883255238294161206">Скупи лиÑту</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Филтрирање</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{None}=1{1 Ñајт}one{# Ñајт}few{# Ñајта}other{# Ñајтова}}</translation>
<translation id="194030505837763158">Идите на <ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> – обележивачи</translation>
<translation id="1973335181906896915">Грешка при Ñеријализацији</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Занемарују Ñе јер Ñу замењене Ñмерницама <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Тражимо Ñтранице Интернета око Ð½Ð°Ñ Ñƒ околини</translation>
<translation id="213826338245044447">Обележивачи на мобилном уређају</translation>
-<translation id="2148716181193084225">ДанаÑ</translation>
+<translation id="2147827593068025794">Синхронизација у позадини</translation>
<translation id="2154054054215849342">Синхронизација није доÑтупна за домен</translation>
<translation id="2154484045852737596">Измените картицу</translation>
<translation id="2166049586286450108">Потпуни админиÑтраторÑки приÑтуп</translation>
<translation id="2166378884831602661">Овај Ñајт не може да пружи безбедну везу</translation>
<translation id="2181821976797666341">Смернице</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адреÑа}one{# адреÑа}few{# адреÑе}other{# адреÑа}}</translation>
+<translation id="2187317261103489799">Откриј (подразумевано)</translation>
<translation id="2202020181578195191">УнеÑите важећу годину иÑтека</translation>
<translation id="2212735316055980242">Смернице ниÑу пронађене</translation>
<translation id="2213606439339815911">Преузимање уноÑа...</translation>
+<translation id="2218879909401188352">Ðападачи који Ñу тренутно на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могу да инÑталирају опаÑне апликације које ће вам оштетити уређај, додати нежељене трошкове код мобилног оператера или украÑти личне податке. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Поправите везу помоћу <ph name="BEGIN_LINK" />апликације за дијагноÑтику<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Пошаљи одмах</translation>
<translation id="225207911366869382">Ова вредноÑÑ‚ је заÑтарела за ове Ñмернице.</translation>
<translation id="2262243747453050782">HTTP грешка</translation>
+<translation id="2270484714375784793">Број телефона</translation>
<translation id="2282872951544483773">ÐедоÑтупни екÑперименти</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> Ñтавка}one{<ph name="ITEM_COUNT" /> Ñтавка}few{<ph name="ITEM_COUNT" /> Ñтавке}other{<ph name="ITEM_COUNT" /> Ñтавки}}</translation>
<translation id="2292556288342944218">ПриÑтуп интернету је блокиран</translation>
<translation id="230155334948463882">Ðова картица?</translation>
-<translation id="2305919008529760154">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; могуће је да је његов безбедноÑни Ñертификат лажно издат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> захтева кориÑничко име и лозинку.</translation>
-<translation id="2318774815570432836">Тренутно не можете да поÑетите <ph name="SITE" /> зато што веб-Ñајт кориÑти HSTS. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Подешавање контролише админиÑтратор</translation>
<translation id="2354001756790975382">ОÑтали обележивачи</translation>
+<translation id="2354430244986887761">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило штетне апликације<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Ðападачи ће моћи да виде Ñлике које гледате на овом Ñајту и да их измене како би Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ð¸Ð»Ð¸.</translation>
+<translation id="2356070529366658676">Питај</translation>
+<translation id="2359629602545592467">Више</translation>
<translation id="2359808026110333948">ÐаÑтави</translation>
<translation id="2365563543831475020">Извештај о отказивању Ñнимљен у <ph name="CRASH_TIME" /> није отпремљен</translation>
<translation id="2367567093518048410">Ðиво</translation>
-<translation id="2371153335857947666">{1,plural, =1{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао јуче. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}one{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}few{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}other{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је иÑтекао пре # дана. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. Сат рачунара је тренутно подешен на <ph name="CURRENT_DATE" />. Да ли је то тачно? Ðко није, требало би да иÑправите Ñат ÑиÑтема и да затим оÑвежите ову Ñтраницу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Ðема доÑтупних алтернатива кориÑничког интерфејÑа</translation>
<translation id="2384307209577226199">Подразумеване Ñмернице за предузеће</translation>
<translation id="2386255080630008482">Сертификат Ñервера је опозван.</translation>
<translation id="2392959068659972793">Прикажи Ñмернице без подешених вредноÑти</translation>
<translation id="239429038616798445">Овај начин Ñлања није доÑтупан. ИÑпробајте неки други начин.</translation>
<translation id="2396249848217231973">&amp;Опозови бриÑање</translation>
-<translation id="2460160116472764928">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило малвер<ph name="END_LINK" /> на <ph name="SITE" />. Веб-Ñајтови који Ñу обично безбедни Ñе понекад заразе малвером. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат ће можда бити опозван. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="2463739503403862330">Попуни</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />да покренете дијагноÑтику мреже<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Ðеважећа URL адреÑа претраге.</translation>
+<translation id="2482878487686419369">Обавештења</translation>
<translation id="2491120439723279231">Сертификат Ñервера Ñадржи грешке.</translation>
<translation id="2495083838625180221">Рашчлањивач JSON датотека</translation>
<translation id="2495093607237746763">Ðко означите ову опцију, Chromium ће Ñкладиштити копију картице на овом уређају ради бржег попуњавања образаца.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Иди назад</translation>
<translation id="2515629240566999685">да проверите Ñигнал у Ñвојој облаÑти</translation>
<translation id="2516305470678292029">Ðлтернативе кориÑничког интерфејÑа</translation>
+<translation id="2539524384386349900">Откриј</translation>
<translation id="255002559098805027">ХоÑÑ‚ <ph name="HOST_NAME" /> је поÑлао неважећи одговор.</translation>
-<translation id="2552545117464357659">Ðовије</translation>
<translation id="2556876185419854533">&amp;Опозови измену</translation>
<translation id="2587730715158995865">Од издавача <ph name="ARTICLE_PUBLISHER" />. Прочитајте овај чланак веÑти и још <ph name="OTHER_ARTICLE_COUNT" /> чланака.</translation>
<translation id="2587841377698384444">ИД API-ја за директоријуме:</translation>
<translation id="2597378329261239068">Овај документ је заштићен лозинком. УнеÑите лозинку.</translation>
<translation id="2609632851001447353">Варијације</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{None}=1{1 апликација ($1)}=2{2 апликације ($1, $2)}one{# апликација ($1, $2, $3)}few{# апликације ($1, $2, $3)}other{# апликација ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Сат вам жури</translation>
<translation id="2639739919103226564">СтатуÑ:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ПриÑтуп датотеци је одбијен</translation>
<translation id="2653659639078652383">Пошаљи</translation>
<translation id="2666117266261740852">Затворите друге картице или апликације</translation>
+<translation id="2670429602441959756">Ова Ñтраница Ñадржи функције које још увек ниÑу подржане у режиму виртуелне реалноÑти. Затвара Ñе...</translation>
<translation id="2674170444375937751">Желите ли Ñтварно да избришете ове Ñтранице из иÑторије?</translation>
<translation id="2677748264148917807">Затвори</translation>
-<translation id="269990154133806163">Сервер је поÑлао Ñертификат који није јавно откривен помоћу Ñмерница за транÑпарентноÑÑ‚ Ñертификата. То је обавезно за неке Ñертификате да биÑмо Ñе уверили да Ñу поуздани и да штите од нападача. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">ЛиÑта за читање</translation>
<translation id="2704283930420550640">ВредноÑÑ‚ Ñе не подудара Ñа форматом.</translation>
<translation id="2704951214193499422">Chromium није уÑпео да потврди картицу. Пробајте поново каÑније.</translation>
<translation id="2705137772291741111">Сачувана (кеширана) копија овог Ñајта није могла да Ñе чита.</translation>
<translation id="2709516037105925701">ÐутоматÑко попуњавање</translation>
-<translation id="2712118517637785082">Покушали Ñте да поÑетите <ph name="DOMAIN" />, али је издавач опозвао Ñертификат који је Ñервер поÑлао. То значи да никако не треба да имате поверења у безбедноÑне акредитиве које је Ñервер поÑлао. Могуће је да комуницирате Ñа нападачем. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Затражи дозволу</translation>
<translation id="2713444072780614174">Бела</translation>
<translation id="2720342946869265578">У околини</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ÐедоÑтаје евиденција уређаја</translation>
<translation id="2784949926578158345">Веза је враћена на почетне вредноÑти.</translation>
<translation id="2794233252405721443">Сајт је блокиран</translation>
+<translation id="2799020568854403057">Сајт који ћете поÑетити Ñадржи штетне апликације</translation>
+<translation id="2803306138276472711">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило малвер<ph name="END_LINK" /> на <ph name="SITE" />. Веб-Ñајтови који Ñу обично безбедни Ñе понекад заразе малвером.</translation>
<translation id="2824775600643448204">Трака за адреÑу и претрагу</translation>
<translation id="2826760142808435982">Веза је шифрована и њена аутентичноÑÑ‚ је потврђена помоћу <ph name="CIPHER" /> и кориÑти <ph name="KX" /> као механизам за размену шифара.</translation>
<translation id="2835170189407361413">Обриши образац</translation>
+<translation id="2856444702002559011">Ðападачи можда покушавају да украду информације Ñа <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (на пример, лозинке, поруке или кредитне картице). <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ðе учитавај поново</translation>
<translation id="2900469785430194048">Google Chrome-у је понеÑтало меморије док је покушавао да прикаже ову веб-Ñтраницу.</translation>
<translation id="2909946352844186028">Откривена је промена на мрежи.</translation>
<translation id="2916038427272391327">Затворите друге програме</translation>
<translation id="2922350208395188000">Ðије могуће проверити Ñертификат Ñервера.</translation>
<translation id="2928905813689894207">ÐдреÑа за обрачун</translation>
+<translation id="2941952326391522266">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је Ñа домена <ph name="DOMAIN2" />. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="2948083400971632585">Ðа Ñтраници Подешавања можете да онемогућите Ñве прокÑије конфигуриÑане за везу.</translation>
<translation id="2955913368246107853">Затворите траку за проналажење</translation>
<translation id="2958431318199492670">Конфигурација мреже није у Ñкладу Ñа ONC Ñтандардом. Делови конфигурације не могу да Ñе увезу.</translation>
-<translation id="29611076221683977">Ðападачи који Ñу тренутно на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ће можда покушати да инÑталирају опаÑне програме на Mac-у који краду или бришу податке (на пример, Ñлике, лозинке, поруке и бројеве кредитних картица).</translation>
<translation id="2966678944701946121">ИÑтиче: <ph name="EXPIRATION_DATE_ABBR" />, додато је: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Да биÑте уÑпоÑтавили безбедну везу, Ñат на уређају мора да буде тачан. То је зато што Ñертификати које веб-Ñајтови кориÑте за идентификацију важе Ñамо за одређене временÑке периоде. Пошто Ñат на вашем уређају није тачан, Google Chrome не може да верификује те Ñертификате.</translation>
<translation id="2972581237482394796">&amp;Понови радњу</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">УнеÑите важећу адреÑу</translation>
<translation id="2986368408720340940">Овај начин преузимања није доÑтупан. ИÑпробајте неки други начин.</translation>
<translation id="2991174974383378012">Дељење Ñа веб-Ñајтовима</translation>
+<translation id="2991571918955627853">Тренутно не можете да поÑетите <ph name="SITE" /> јер веб-Ñајт кориÑти HSTS. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније.</translation>
<translation id="3005723025932146533">Прикажи Ñачувану копију</translation>
<translation id="3008447029300691911">УнеÑите CVC за картицу <ph name="CREDIT_CARD" />. Када будете потврдили, подаци о картици ће бити поÑлати овом Ñајту.</translation>
<translation id="3010559122411665027">Ð£Ð½Ð¾Ñ Ð½Ð° лиÑти „<ph name="ENTRY_INDEX" />“: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">ÐутоматÑки је блокирано</translation>
<translation id="3024663005179499861">Погрешан тип Ñмерница</translation>
<translation id="3032412215588512954">Желите ли поново да учитате овај Ñат?</translation>
<translation id="3037605927509011580">О, не!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{најмање 1 Ñтавка на Ñинхронизованим уређајима}=1{1 Ñтавка (и још Ñтавки на Ñинхронизованим уређајима)}one{# Ñтавка (и још Ñтавки на Ñинхронизованим уређајима)}few{# Ñтавке (и још Ñтавки на Ñинхронизованим уређајима)}other{# Ñтавки (и још Ñтавки на Ñинхронизованим уређајима)}}</translation>
<translation id="3041612393474885105">Информације о Ñертификату</translation>
<translation id="3063697135517575841">Chrome није уÑпео да потврди картицу. Пробајте поново каÑније.</translation>
<translation id="3064966200440839136">ÐапуÑтићете режим без архивирања да биÑте платили у Ñпољној апликацији. Желите ли да наÑтавите?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{None}=1{1 лозинка}one{# лозинка}few{# лозинке}other{# лозинки}}</translation>
<translation id="3093245981617870298">Офлајн Ñте.</translation>
<translation id="3105172416063519923">ИД елемента:</translation>
<translation id="3109728660330352905">Ðемате овлашћење да прегледате ову Ñтраницу.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Покушајте да покренете дијагноÑтику везе<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Декодирање одговора није уÑпело</translation>
<translation id="3150653042067488994">Привремена грешка на Ñерверу</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Странице које прегледате на картицама без архивирања Ñе неће задржавати у иÑторији прегледача, Ñкладишту колачића или иÑторији претраге када затворите Ñве картице без архивирања. Сачуваћемо Ñве преузете датотеке или направљене обележиваче.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ОÑтрво</translation>
+<translation id="317583078218509884">Ðова подешавања дозвола Ñајта биће примењена након поновног учитавања Ñтранице.</translation>
<translation id="3176929007561373547">Проверите подешавања прокÑија или контактирајте админиÑтратора мреже да
биÑте Ñе уверили да прокÑи Ñервер функционише. Ðко миÑлите да не
треба да кориÑтите прокÑи Ñервер:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Отворите Ñтраницу у режиму без архивирања</translation>
-<translation id="3202578601642193415">Ðајновије</translation>
+<translation id="320323717674993345">Откажи плаћање</translation>
<translation id="3207960819495026254">Обележено</translation>
+<translation id="3225919329040284222">Сервер је приказао Ñертификат који Ñе не подудара Ñа уграђеним очекивањима. Та очекивања Ñу обухваћена за одређене веб-Ñајтове Ñа јаким безбедноÑним мерама како би Ð²Ð°Ñ Ð·Ð°ÑˆÑ‚Ð¸Ñ‚Ð¸Ð»Ð°.</translation>
<translation id="3226128629678568754">ПритиÑните дугме Поново учитај да биÑте поново поÑлали податке потребне за учитавање Ñтранице.</translation>
+<translation id="3227137524299004712">Микрофон</translation>
<translation id="3228969707346345236">Превод није уÑпео јер је Ñтраница већ на језику <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">УнеÑите CVC за картицу <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Увек откривај важан Ñадржај на овом Ñајту</translation>
<translation id="3254409185687681395">Обележите ову Ñтраницу</translation>
<translation id="3270847123878663523">&amp;Опозови промену редоÑледа</translation>
<translation id="3282497668470633863">Додајте име на картици</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">подешавања</translation>
<translation id="3345135638360864351">Слање захтева за приÑтуп овом Ñајту кориÑнику <ph name="NAME" /> није уÑпело. Пробајте поново.</translation>
<translation id="3355823806454867987">Промени подешавања прокÑија...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />не чува<ph name="END_EMPHASIS" /> Ñледеће информације:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />иÑторију прегледања
+ <ph name="LIST_ITEM" />колачиће и податке о Ñајтовима
+ <ph name="LIST_ITEM" />информације које уноÑите у обраÑцима
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Грешка на Ñату</translation>
-<translation id="337311366426640088">Још Ñтавки (<ph name="ITEM_COUNT" />)...</translation>
<translation id="337363190475750230">Онемогућен је</translation>
<translation id="3377188786107721145">Грешка при рашчлањивању Ñмерница</translation>
<translation id="3380365263193509176">Ðепозната грешка</translation>
<translation id="3380864720620200369">ИД клијента:</translation>
<translation id="3391030046425686457">ÐдреÑа иÑпоруке</translation>
<translation id="3395827396354264108">Ðачин преузимања</translation>
-<translation id="340013220407300675">Хакери можда покушавају да украду ваше информације из <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (на пример, лозинке, поруке или информације о кредитним картицама).</translation>
<translation id="3422248202833853650">Пробајте да изађете из других програма да биÑте оÑлободили меморију.</translation>
<translation id="3422472998109090673">ХоÑÑ‚ <ph name="HOST_NAME" /> тренутно није доÑтупан.</translation>
+<translation id="3427092606871434483">Дозволи (подразумевано)</translation>
<translation id="3427342743765426898">&amp;Понови измену</translation>
<translation id="3431636764301398940">Сачувај ову картицу на овом уређају</translation>
<translation id="3435896845095436175">Омогући</translation>
<translation id="3447661539832366887">ВлаÑник овог уређаја је иÑкључио ову заÑтарелу игру.</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">Интервал учитавања:</translation>
<translation id="3462200631372590220">Сакриј напредно</translation>
<translation id="3467763166455606212">Име влаÑника картице је обавезно</translation>
<translation id="3478058380795961209">МеÑец иÑтека</translation>
<translation id="3479539252931486093">Да ли је ово било неочекивано? <ph name="BEGIN_LINK" />ОбавеÑтите наÑ<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ðе Ñада</translation>
-<translation id="348000606199325318">ИД отказивања <ph name="CRASH_LOCAL_ID" /> (ИД Ñервера: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Тренутно не можемо да контактирамо родитеља. Пробај поново.</translation>
<translation id="3528171143076753409">Сертификат Ñервера није поуздан.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Ðајмање 1 Ñтавка на Ñинхронизованим уређајима}=1{1 Ñтавка (и још Ñтавки на Ñинхронизованим уређајима)}one{# Ñтавка (и још Ñтавки на Ñинхронизованим уређајима)}few{# Ñтавке (и још Ñтавки на Ñинхронизованим уређајима)}other{# Ñтавки (и још Ñтавки на Ñинхронизованим уређајима)}}</translation>
<translation id="3539171420378717834">Задржи копију ове картице на овом уређају</translation>
<translation id="3542684924769048008">КориÑти лозинку за:</translation>
+<translation id="3545341443414427877">УÑпоÑтављање приватне везе Ñа доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> није уÑпело јер Ñу датум и време рачунара (<ph name="DATE_AND_TIME" />) нетачни. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Шифруј Ñве Ñинхронизоване податке помоћу моје приÑтупне фразе за Ñинхронизацију</translation>
-<translation id="3549761410225185768">Још <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је Ñа <ph name="DOMAIN2" />. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Менаџер може да га деблокира за ваÑ</translation>
<translation id="3566021033012934673">Веза није приватна</translation>
+<translation id="3569145463236695319">&lt;p&gt;УÑпоÑтављање приватне везе Ñа доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> није уÑпело јер Ñу датум и време уређаја (<ph name="DATE_AND_TIME" />) нетачни.&lt;/p&gt;
+
+ &lt;p&gt;Прилагодите датум и време у одељку &lt;strong&gt;Опште&lt;/strong&gt; у апликацији &lt;strong&gt;Подешавања&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Додајте име</translation>
<translation id="3583757800736429874">&amp;Понови премештање</translation>
<translation id="3586931643579894722">Сакриј детаље</translation>
-<translation id="3587482841069643663">Све</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">УнеÑите важећи датум иÑтека</translation>
<translation id="36224234498066874">Обриши податке прегледања...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Информације о Ñертификату</translation>
<translation id="3690164694835360974">Пријављивање није безбедно</translation>
<translation id="3693415264595406141">Лозинка:</translation>
-<translation id="3696411085566228381">ништа</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Учитава Ñе...</translation>
<translation id="3712624925041724820">Ðема више лиценци</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />да проверите конфигурацију прокÑија, заштитног зида и DNS-а<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Ðко разумете безбедноÑне ризике, можете да <ph name="BEGIN_LINK" />поÑетите овај небезбедни Ñајт<ph name="END_LINK" /> пре него што уклонимо опаÑне програме.</translation>
<translation id="3739623965217189342">Линк који Ñте копирали</translation>
+<translation id="3744899669254331632">Тренутно не можете да поÑетите <ph name="SITE" /> јер је веб-Ñајт поÑлао кодиране акредитиве које Chromium не може да обради. Грешке на мрежи и напади Ñу углавном привремени, па ће Ñтраница вероватно прорадити каÑније.</translation>
+<translation id="3748148204939282805">Ðападачи на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могу да Ð²Ð°Ñ Ð½Ð°Ð²ÐµÐ´Ñƒ да урадите нешто опаÑно, на пример, да инÑталирате Ñофтвер или откријете личне податке (попут лозинки, бројева телефона или бројева кредитних картица). <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Превођење није уÑпело због грешке Ñервера.</translation>
<translation id="3759461132968374835">Ðемате ниједно недавно пријављено отказивање. Отказивања која Ñу Ñе деÑила док је пријављивање отказивања било онемогућено неће Ñе овде приказати.</translation>
+<translation id="3778403066972421603">Да ли желите да Ñачувате ову картицу на Google налогу и на овом уређају?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">ИÑтиче <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Ðко кориÑтите прокÑи Ñервер...</translation>
<translation id="3828924085048779000">Ðије дозвољено да поље за приÑтупну фразу буде празно.</translation>
-<translation id="3845539888601087042">Приказујемо иÑторију Ñа уређаја на које Ñте пријављени. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Ðазад</translation>
<translation id="3858027520442213535">Ðжурирајте датум и време</translation>
<translation id="3884278016824448484">ÐеуÑаглашени идентификатор уређаја</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Захтев за приÑтуп овом Ñајту је поÑлат кориÑнику <ph name="NAME" /></translation>
<translation id="3890664840433101773">Додајте имејл</translation>
<translation id="3901925938762663762">Картица је иÑтекла</translation>
-<translation id="3933571093587347751">{1,plural, =1{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; датум његовог безбедноÑног Ñертификата је наводно Ñутра. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}one{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је наводно датиран у будућноÑти (за # дан). Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}few{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је наводно датиран у будућноÑти (за # дана). Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}other{Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је наводно датиран у будућноÑти (за # дана). Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Учитавање PDF документа није уÑпело</translation>
+<translation id="3945915738023014686">ИД извештаја о отказивању је отпремљен <ph name="CRASH_ID" /> (ИД локалног отказивања: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат не наводи Ðлтернативне називе Ñубјекта. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="3963721102035795474">Режим читаоца</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{None}=1{Са 1 Ñајта }one{Са # Ñајта }few{Са # Ñајта }other{Са # Ñајтова }}</translation>
<translation id="397105322502079400">Израчунавање...</translation>
<translation id="3973234410852337861">ХоÑÑ‚ <ph name="HOST_NAME" /> је блокиран</translation>
+<translation id="3987940399970879459">Мање од 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 веб-Ñтраница у околини}one{# веб-Ñтраница у околини}few{# веб-Ñтранице у околини}other{# веб-Ñтраница у околини}}</translation>
<translation id="4021036232240155012">DNS је мрежна уÑлуга која преводи назив веб-Ñајта у његову интернет адреÑу.</translation>
<translation id="4030383055268325496">&amp;Опозови додавање</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Конфигурација прокÑија је подешена да кориÑти URL адреÑу .pac Ñкрипте, а не фикÑне прокÑи Ñервере.</translation>
<translation id="4098354747657067197">Пред вама је обмањујући Ñајт</translation>
<translation id="4103249731201008433">СеријÑки број уређаја је неважећи</translation>
+<translation id="410351446219883937">Ðутоплеј</translation>
<translation id="4103763322291513355">ПоÑетите &lt;strong&gt;chrome://policy&lt;/strong&gt; да биÑте видели лиÑту URL-ова Ñтављених на црну лиÑту и друге Ñмернице које је наметнуо админиÑтратор ÑиÑтема.</translation>
-<translation id="4110615724604346410">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат Ñадржи грешке. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Циклама</translation>
+<translation id="4116663294526079822">Увек дозволи на овом Ñајту</translation>
<translation id="4117700440116928470">ОпÑег Ñмерница није подржан.</translation>
-<translation id="4118212371799607889">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; Chromium нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{још 1}one{још #}few{још #}other{још #}}</translation>
<translation id="4130226655945681476">да проверите мрежне каблове, модем и рутер</translation>
+<translation id="413544239732274901">Сазнајте више</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">КориÑти глобалну подразумевану вредноÑÑ‚ (Откривај)</translation>
+<translation id="4165986682804962316">Подешавања Ñајта</translation>
<translation id="4169947484918424451">Желите ли да Chromium Ñачува ову картицу?</translation>
<translation id="4171400957073367226">ÐеиÑправан Ð¿Ð¾Ñ‚Ð¿Ð¸Ñ Ð·Ð° верификацију</translation>
<translation id="4196861286325780578">&amp;Понови премештање</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />да проверите конфигурацију заштитног зида и антивируÑа<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ниједна}=1{1 апликација ($1)}=2{2 апликације ($1, $2)}one{# апликација ($1, $2, $3)}few{# апликације ($1, $2, $3)}other{# апликација ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Отказивања</translation>
+<translation id="422022731706691852">Ðападачи на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могу да покушају да Ð²Ð°Ñ Ð½Ð°Ð²ÐµÐ´Ñƒ да инÑталирате програме који штете доживљају прегледања (на пример, тако што мењају почетну Ñтраницу или приказују додатне оглаÑе на Ñајтовима које поÑећујете). <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Покушајте да покренете дијагноÑтику мреже<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Важећи</translation>
<translation id="4250431568374086873">Веза Ñа овим Ñајтом није потпуно безбедна</translation>
<translation id="4250680216510889253">Ðе</translation>
<translation id="425582637250725228">Промене које Ñте унели можда неће бити Ñачуване.</translation>
<translation id="4258748452823770588">ÐеиÑправан потпиÑ</translation>
+<translation id="4265872034478892965">Дозвољава админиÑтратор</translation>
<translation id="4269787794583293679">(Без кориÑничког имена)</translation>
<translation id="4275830172053184480">Поновно покретање уређаја</translation>
<translation id="4280429058323657511">, иÑтиче <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило штетне програме<ph name="END_LINK" /> на <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Предлози родитеља</translation>
<translation id="4304224509867189079">Пријављивање</translation>
-<translation id="432290197980158659">Сервер је поÑлао Ñертификат који Ñе не подудара Ñа уграђеним очекивањима. Та очекивања Ñу обухваћена због одређених веб-Ñајтова Ñа јаким безбедноÑним мерама како би Ð²Ð°Ñ Ð·Ð°ÑˆÑ‚Ð¸Ñ‚Ð¸Ð»Ð°. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Блокирај (подразумевано)</translation>
<translation id="4325863107915753736">ÐиÑмо уÑпели да пронађемо чланак</translation>
<translation id="4326324639298822553">Проверите датум иÑтека и пробајте поново</translation>
<translation id="4331708818696583467">Ðије безбедан</translation>
<translation id="4356973930735388585">Ðападачи на овом Ñајту ће можда покушати да инÑталирају опаÑне програме на рачунару који краду или бришу информације (на пример, Ñлике, лозинке, поруке и бројеве кредитних картица).</translation>
<translation id="4372948949327679948">Очекивана вредноÑÑ‚ je <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Покушали Ñте да контактирате <ph name="DOMAIN" />, али је издавач опозвао Ñертификат који је Ñервер навео. То значи да никако не треба имати поверења у безбедноÑне акредитиве које је Ñервер навео. Могуће је да комуницирате Ñа нападачем.</translation>
<translation id="4381091992796011497">Име кориÑника:</translation>
<translation id="4394049700291259645">Онемогући</translation>
<translation id="4406896451731180161">резултати претраге</translation>
+<translation id="4424024547088906515">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; Chrome нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> није прихватио Ñертификат за пријављивање или Ñертификат за пријављивање није приложен.</translation>
<translation id="443673843213245140">Коришћење прокÑија је онемогућено, али је наведена екÑплицитна конфигурација прокÑија.</translation>
-<translation id="4492190037599258964">Резултати претраге за „<ph name="SEARCH_STRING" />“</translation>
<translation id="4506176782989081258">Грешка при потврди ваљаноÑти: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">да контактирате админиÑтратора ÑиÑтема</translation>
<translation id="450710068430902550">Дељење Ñа админиÑтратором</translation>
<translation id="4515275063822566619">Картице и адреÑе Ñу из Chrome-а и Ñа вашег Google налога (<ph name="ACCOUNT_EMAIL" />). Њима можете да управљате у <ph name="BEGIN_LINK" />подешавњима<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Детаљи</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Покушајте да онемогућите додатке.</translation>
<translation id="457875822857220463">ИÑпорука</translation>
<translation id="4587425331216688090">Желите ли да уклоните адреÑу из Chrome-а?</translation>
-<translation id="4589078953350245614">Покушали Ñте да поÑетите <ph name="DOMAIN" />, али је Ñервер поÑлао неважећи Ñертификат. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Веза Ñа доменом <ph name="DOMAIN" /> је шифрована помоћу модерног пакета за шифровање.</translation>
<translation id="4594403342090139922">&amp;Опозови бриÑање</translation>
<translation id="4619615317237390068">Картице Ñа других уређаја</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат Ñадржи грешке. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="4690462567478992370">ОбуÑтави коришћење неважећег Ñертификата</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Веза је прекинута</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />да покренете Windows дијагноÑтику мреже<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Дошло је до непознате грешке.</translation>
<translation id="4800132727771399293">Проверите датум иÑтека и CVC и покушајте поново</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Тренутно не можете да поÑетите <ph name="SITE" /> зато што је веб-Ñајт поÑлао шифроване акредитиве које Google Chrome не може да обради. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније.</translation>
<translation id="4813512666221746211">Грешка на мрежи</translation>
<translation id="4816492930507672669">Уклопи у Ñтраницу</translation>
<translation id="483020001682031208">Ðе поÑтоје Ñтранице Интернета око Ð½Ð°Ñ Ð·Ð° приказивање</translation>
<translation id="4850886885716139402">Приказ</translation>
<translation id="4854362297993841467">Овај начин иÑпоруке није доÑтупан. ИÑпробајте неки други начин.</translation>
<translation id="4858792381671956233">Питао/ла Ñи родитеље да ли Ñмеш да поÑетиш овај Ñајт</translation>
+<translation id="4863764087567530506">Овај Ñадржај ће покушати да Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ð¸ да инÑталирате Ñофтвер или откријете личне податке. <ph name="BEGIN_LINK" />Ипак прикажи<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Претражи иÑторију</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{и јој 1 веб-Ñтраница}one{и још # веб-Ñтраница}few{и још # веб-Ñтранице}other{и још # веб-Ñтраница}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Ова Ñтраница је преведена Ñа непознатог језика на <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Плаћање</translation>
<translation id="4926049483395192435">Мора да буде наведено.</translation>
<translation id="495170559598752135">Радње</translation>
<translation id="4958444002117714549">Прошири лиÑту</translation>
-<translation id="4962322354953122629">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; Chrome нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Поново омогући упозорења</translation>
<translation id="4989809363548539747">Ова додатна компонента није подржана</translation>
<translation id="5002932099480077015">Ðко је ова опција омогућена, Chrome ће Ñкладиштити копију картице на овом уређају ради бржег попуњавања образаца.</translation>
<translation id="5018422839182700155">Ðе можемо да отворимо ову Ñтраницу</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Проверите Ñмернице админиÑтратора</translation>
<translation id="5029568752722684782">Обриши копију</translation>
<translation id="5031870354684148875">О Google преводиоцу</translation>
+<translation id="5039804452771397117">Дозволи</translation>
<translation id="5040262127954254034">ПриватноÑÑ‚</translation>
<translation id="5045550434625856497">ÐеиÑправна лозинка</translation>
<translation id="5056549851600133418">Чланци за ваÑ</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />да проверите адреÑу прокÑија<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Ðема колачића}=1{1 Ñајт кориÑти колачиће. }one{# Ñајт кориÑти колачиће. }few{# Ñајта кориÑте колачиће. }other{# Ñајтова кориÑти колачиће. }}</translation>
<translation id="5087286274860437796">Сертификат Ñервера тренутно није важећи.</translation>
<translation id="5087580092889165836">Додај картицу</translation>
<translation id="5089810972385038852">Држава</translation>
+<translation id="5094747076828555589">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; Chromium нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="5095208057601539847">Провинција</translation>
<translation id="5115563688576182185">(64-битни)</translation>
<translation id="5141240743006678641">Шифруј Ñинхронизоване лозинке помоћу Google акредитива</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Имејл је обавезан</translation>
<translation id="5251803541071282808">Клауд</translation>
<translation id="5277279256032773186">Да ли кориÑтите Chrome на поÑлу? Предузеће може да управља подешавањима Chrome-а за запоÑлене. Сазнајте више</translation>
+<translation id="5297526204711817721">Веза Ñа овим Ñајтом није приватна. Да биÑте у било ком тренутку изашли из ВР режима, уклоните хедÑет и притиÑните Ðазад.</translation>
<translation id="5299298092464848405">Грешка при рашчлањивању Ñмерница</translation>
-<translation id="5300589172476337783">Прикажи</translation>
<translation id="5308689395849655368">Извештавање о отказивању је онемогућено.</translation>
<translation id="5317780077021120954">Сачувај</translation>
<translation id="5327248766486351172">Ðазив</translation>
-<translation id="5337705430875057403">Ðападачи на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могу да Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ðµ како биÑте урадили нешто опаÑно, на пример, да инÑталирате Ñофтвер или откријете личне податке (попут лозинки, бројева телефона или бројева кредитних картица).</translation>
-<translation id="5359637492792381994">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат тренутно није важећи. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Тренутно не можете да поÑетите <ph name="SITE" /> јер је његов Ñертификат опозван. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније.</translation>
<translation id="536296301121032821">Складиштење подешавања Ñмерница није уÑпело</translation>
<translation id="5386426401304769735">Ланац Ñертификата за овај Ñајт Ñадржи Ñертификат потпиÑан помоћу алгоритма SHA-1.</translation>
<translation id="5402410679244714488">ИÑтиче: <ph name="EXPIRATION_DATE_ABBR" />, поÑледњи пут коришћено пре више од годину дана</translation>
+<translation id="540969355065856584">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат тренутно није важећи. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="5421136146218899937">Обриши податке прегледања...</translation>
<translation id="5430298929874300616">Уклоните обележивач</translation>
<translation id="5431657950005405462">Датотека није пронађена</translation>
-<translation id="5435775191620395718">Приказујемо иÑторију Ñа овог уређаја. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Грешка у валидацији шеме на „<ph name="ERROR_PATH" />“: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Ðије могуће пронаћи ову Ñтраницу хоÑта <ph name="HOST_NAME" /></translation>
<translation id="5455374756549232013">ÐеиÑправна временÑка ознака Ñмерница</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> од <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Ðеважеће</translation>
<translation id="5470861586879999274">&amp;Понови измену</translation>
<translation id="54817484435770891">Додајте важећу адреÑу</translation>
<translation id="5492298309214877701">Овај Ñајт на интранету компаније, организације или школе има иÑти URL као и један Ñпољни веб-Ñајт.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Преузимање Ñа ове адреÑе није могуће. Изаберите другу адреÑу.</translation>
<translation id="5572851009514199876">Отворите и пријавите Ñе у Chrome да би Chrome могао да провери да ли имате дозволу за приÑтуп овом Ñајту.</translation>
<translation id="5580958916614886209">Проверите меÑец иÑтека и пробајте поново</translation>
+<translation id="5586446728396275693">Ðема Ñачуваних адреÑа</translation>
+<translation id="5595485650161345191">Измена адреÑе</translation>
<translation id="560412284261940334">Управљање није подржано</translation>
<translation id="5610142619324316209">да проверите везу</translation>
<translation id="5610807607761827392">Картицама и адреÑама можете да управљате у <ph name="BEGIN_LINK" />Подешавањима<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Желите ли да напуÑтите овај Ñајт?</translation>
<translation id="5629630648637658800">Учитавање подешавања Ñмерница није уÑпело</translation>
<translation id="5631439013527180824">Ðеважећи токен за управљање уређајима</translation>
+<translation id="5633066919399395251">Ðападачи на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ће можда покушати да инÑталирају опаÑне програме на рачунару који краду или бришу информације (на пример, Ñлике, лозинке, поруке и бројеве кредитних картица). <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Локација</translation>
+<translation id="5659593005791499971">Имејл</translation>
<translation id="5669703222995421982">Добијте перÑонализовани Ñадржај</translation>
<translation id="5675650730144413517">Ова Ñтраница не функционише</translation>
-<translation id="5677928146339483299">Блокирано</translation>
-<translation id="5694783966845939798">Покушали Ñте да поÑетите <ph name="DOMAIN" />, али је Ñервер поÑлао Ñертификат потпиÑан Ñлабим алгоритмом (као што је SHA-1). То значи да Ñу безбедноÑни акредитиви које је Ñервер поÑлао можда кривотворени и Ñервер можда није онај који миÑлите да јеÑте (можда комуницирате Ñа нападачем). <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Идентитет овог веб-Ñајта није верификован.</translation>
+<translation id="5713016350996637505">Обмањујући Ñадржај је блокиран</translation>
<translation id="5720705177508910913">Тренутни кориÑник</translation>
<translation id="5732392974455271431">Родитељи могу да га деблокирају за тебе</translation>
<translation id="5763042198335101085">УнеÑите важећу имејл адреÑу</translation>
<translation id="5765072501007116331">Да биÑте видели начине и захтеве за иÑпоруку, изаберите адреÑу</translation>
+<translation id="5778550464785688721">Потпуна контрола над MIDI уређајима</translation>
<translation id="5784606427469807560">Дошло је до проблема при потврди картице. Проверите интернет везу и покушајте поново.</translation>
<translation id="5785756445106461925">Поред тога, ова Ñтраница Ñадржи и друге реÑурÑе који ниÑу безбедни. Ове реÑурÑе могу да виде и други док Ñу у пролазу и нападач може да их измени како би променио изглед Ñтранице.</translation>
<translation id="5786044859038896871">Желите ли да попуните информације о картици?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Понови додавање</translation>
<translation id="5814352347845180253">Можете да изгубите приÑтуп премијум Ñадржају Ñа Ñајта <ph name="SITE" /> и неких других Ñајтова.</translation>
<translation id="5838278095973806738">Ðемојте да уноÑите оÑетљиве информације на овом Ñајту (на пример, лозинке или кредитне картице) јер нападачи могу да их украду.</translation>
-<translation id="5843436854350372569">Покушали Ñте да поÑетите <ph name="DOMAIN" />, али је Ñервер поÑлао Ñертификат који Ñадржи Ñлаб кључ. Могуће је да је нападач открио приватни кључ и да Ñервер можда није онај који миÑлите да јеÑте (можда комуницирате Ñа нападачем). <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Овај Ñајт није доÑтупан</translation>
<translation id="5869522115854928033">Сачуване лозинке</translation>
<translation id="5872918882028971132">Предлози родитеља</translation>
<translation id="5901630391730855834">Жута</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (Ñинхронизовано)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{КориÑти Ñе 1}one{КориÑти Ñе #}few{КориÑте Ñе #}other{КориÑти Ñе #}}</translation>
<translation id="5926846154125914413">Можете да изгубите приÑтуп премијум Ñадржају Ñа неких Ñајтова.</translation>
<translation id="5959728338436674663">ÐутоматÑки шаљите одређене <ph name="BEGIN_WHITEPAPER_LINK" />информације о ÑиÑтему и Ñадржај Ñтраница<ph name="END_WHITEPAPER_LINK" /> Google-у да биÑте нам помогли да откријемо опаÑне апликације и Ñајтове. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Ðедеља</translation>
<translation id="5967867314010545767">Уклони из иÑторије</translation>
<translation id="5975083100439434680">Умањивање</translation>
<translation id="598637245381783098">Отварање апликације за плаћање није уÑпело</translation>
@@ -543,20 +603,28 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1. Ñтраница}one{#. Ñтраница}few{#. Ñтраница}other{#. Ñтраница}}</translation>
<translation id="6017514345406065928">Зелена</translation>
+<translation id="6017850046339264347">Ðападачи који Ñу на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могу да инÑталирају обмањујуће апликације које Ñе претварају да Ñу нешто друго или да прикупљају податке који могу да Ñе кориÑте за праћење. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (Ñинхронизовано)</translation>
<translation id="6027201098523975773">УнеÑите назив</translation>
<translation id="6040143037577758943">Затвори</translation>
<translation id="6042308850641462728">Више</translation>
+<translation id="6047233362582046994">Ðко разумете безбедноÑне ризике, можете да <ph name="BEGIN_LINK" />поÑетите овај Ñајт<ph name="END_LINK" /> пре него што уклонимо штетне апликације.</translation>
+<translation id="6051221802930200923">Тренутно не можете да поÑетите <ph name="SITE" /> јер веб-Ñајт кориÑти проверу Ñертификата. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније.</translation>
<translation id="6060685159320643512">Пазите, ови екÑперименти могу бити опаÑни</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ниједна}=1{1}one{#}few{#}other{#}}</translation>
+<translation id="6080696365213338172">ПриÑтупали Ñте Ñадржају помоћу Ñертификата који је обезбедио админиÑтратор. ÐдминиÑтратор може да преÑретне податке које обезбедите домену <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{None}=1{1 лозинка (Ñинхронизована)}one{# лозинка (Ñинхронизована)}few{# лозинке (Ñинхронизоване)}other{# лозинки (Ñинхронизованих)}}</translation>
<translation id="6146055958333702838">Проверите Ñве каблове и реÑтартујте Ñве рутере, модеме или друге мрежне уређаје које можда кориÑтите.</translation>
<translation id="614940544461990577">Покушајте:</translation>
<translation id="6151417162996330722">Сертификат Ñервера има предугачак период важења.</translation>
<translation id="6157877588268064908">Да биÑте видели начине и захтеве за Ñлање, изаберите адреÑу</translation>
+<translation id="6158003235852588289">Google безбедно прегледање је недавно открило „пецање“ на <ph name="SITE" />. Сајтови Ñа „пецањем“ Ñе предÑтављају као неки други веб-Ñајтови да би Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ð¸Ð»Ð¸.</translation>
<translation id="6165508094623778733">Сазнајте више</translation>
+<translation id="6169916984152623906">Сада можете да прегледате приватно и други људи који кориÑте овај уређај неће видети ваше активноÑти. Међутим, преузимања и обележивачи ће бити Ñачувани.</translation>
<translation id="6177128806592000436">Веза Ñа овим Ñајтом није безбедна</translation>
<translation id="6184817833369986695">(кохорта: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Проверите интернет везу</translation>
<translation id="6218753634732582820">Желите ли да уклоните адреÑу из Chromium-а?</translation>
+<translation id="6221345481584921695">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило малвер<ph name="END_LINK" /> на <ph name="SITE" />. Веб-Ñајтови који Ñу обично безбедни Ñе понекад заразе малвером. Злонамеран Ñадржај потиче Ñа <ph name="SUBRESOURCE_HOST" />, који је познати диÑтрибутер малвера.</translation>
<translation id="6251924700383757765">Политика приватноÑти</translation>
<translation id="6254436959401408446">Ðема довољно меморије за отварање ове Ñтранице</translation>
<translation id="625755898061068298">Онемогућили Ñте безбедноÑна упозорења за овај Ñајт.</translation>
@@ -582,15 +650,14 @@
<translation id="6404511346730675251">Измена обележивача</translation>
<translation id="6410264514553301377">УнеÑите датум иÑтека и CVC за картицу <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Питао/ла Ñи родитеља да ли Ñмеш да поÑетиш овај Ñајт</translation>
-<translation id="6416403317709441254">Тренутно не можете да поÑетите <ph name="SITE" /> јер је веб-Ñајт поÑлао кодиране акредитиве које Chromium не може да обради. Грешке на мрежи и напади Ñу углавном привремени, па ће Ñтраница вероватно функциониÑати каÑније. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Ðије могуће проверити да ли је Ñертификат опозван.</translation>
<translation id="6433490469411711332">Измените контакт информације</translation>
<translation id="6433595998831338502">ХоÑÑ‚ <ph name="HOST_NAME" /> је одбио повезивање.</translation>
<translation id="6446608382365791566">Додајте још информација</translation>
+<translation id="6447842834002726250">Колачићи</translation>
<translation id="6451458296329894277">Потврђивање поновног Ñлања обраÑца</translation>
<translation id="6456339708790392414">Плаћање</translation>
<translation id="6458467102616083041">Занемарује Ñе зато што ове Ñмернице онемогућавају подразумевану претрагу.</translation>
-<translation id="6462969404041126431">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је можда опозван. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Смернице за уређај</translation>
<translation id="6477321094435799029">Chrome је открио неуобичајени кôд на овој Ñтраници и блокирао је ради заштите ваших личних података (попут лозинки, бројева телефона или бројева кредитних картица).</translation>
<translation id="6489534406876378309">Покрени отпремање отказивања</translation>
@@ -602,20 +669,19 @@
<translation id="6556915248009097796">ИÑтиче: <ph name="EXPIRATION_DATE_ABBR" />, поÑледњи пут коришћено: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Менаџер га још увек није одобрио</translation>
<translation id="6569060085658103619">Прегледате Ñтраницу додатка.</translation>
-<translation id="6593753688552673085">мање од <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Овај Ñадржај ће покушати да инÑталира опаÑан Ñофтвер на уређају који ће украÑти или обриÑати ваше податке. <ph name="BEGIN_LINK" />Ипак прикажи<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Опције шифровања</translation>
<translation id="662080504995468778">Ðе затварај</translation>
<translation id="6626291197371920147">Додајте важећи број картице</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> претрага</translation>
+<translation id="6630809736994426279">Ðападачи који Ñу тренутно на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ће можда покушати да инÑталирају опаÑне програме на Mac-у који краду или бришу податке (на пример, Ñлике, лозинке, поруке и бројеве кредитних картица). <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Ове Ñмернице Ñу заÑтареле.</translation>
-<translation id="6652240803263749613">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; оперативни ÑиÑтем вашег рачунара нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Желите ли да уклоните предлог из Chromium-а?</translation>
<translation id="6685834062052613830">Одјавите Ñе и довршите подешавање</translation>
<translation id="6710213216561001401">Претходно</translation>
<translation id="6710594484020273272">&lt;УнеÑите термин за претрагу&gt;</translation>
<translation id="6711464428925977395">Ðешто није у реду Ñа прокÑи Ñервером или је адреÑа нетачна.</translation>
<translation id="6727102863431372879">ПоÑтави</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ниједна}=1{1 Ñтавка}one{# Ñтавка}few{# Ñтавке}other{# Ñтавки}}</translation>
<translation id="674375294223700098">Ðепозната грешка Ñертификата Ñервера.</translation>
<translation id="6753269504797312559">ВредноÑÑ‚ Ñмерница</translation>
<translation id="6757797048963528358">Уређај је прешао у режим Ñпавања.</translation>
@@ -623,6 +689,8 @@
<translation id="6810899417690483278">ИД за прилагођавање</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Учитавање података према регионима није уÑпело</translation>
+<translation id="6825578344716086703">Покушали Ñте да поÑетите <ph name="DOMAIN" />, али је Ñервер поÑлао Ñертификат потпиÑан Ñлабим алгоритмом (као што је SHA-1). То значи да Ñу безбедноÑни акредитиви које је Ñервер поÑлао можда кривотворени и Ñервер можда није онај који миÑлите да јеÑте (можда комуницирате Ñа нападачем).</translation>
+<translation id="6830728435402077660">Ðије безбедно</translation>
<translation id="6831043979455480757">Преведи</translation>
<translation id="6839929833149231406">ОблаÑÑ‚</translation>
<translation id="6874604403660855544">&amp;Понови додавање</translation>
@@ -630,6 +698,7 @@
<translation id="6895330447102777224">Картица је потврђена</translation>
<translation id="6897140037006041989">КориÑнички агент</translation>
<translation id="6915804003454593391">КориÑник:</translation>
+<translation id="6945221475159498467">Изабери</translation>
<translation id="6948701128805548767">Да биÑте видели начине и захтеве за преузимање, изаберите адреÑу</translation>
<translation id="6957887021205513506">Изгледа да је Ñертификат Ñервера фалÑификован.</translation>
<translation id="6965382102122355670">Потврди</translation>
@@ -638,15 +707,16 @@
<translation id="6973656660372572881">Ðаведени Ñу и фикÑни прокÑи Ñервери и URL адреÑа .pac Ñкрипте.</translation>
<translation id="6989763994942163495">Прикажи напредна подешавања...</translation>
<translation id="7000990526846637657">Ðије пронађен ниједан ÑƒÐ½Ð¾Ñ Ñƒ иÑторији</translation>
-<translation id="7009986207543992532">Покушали Ñте да поÑетите <ph name="DOMAIN" />, али је Ñервер поÑлао Ñертификат Ñа периодом важења који је предугачак да би био поуздан. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Google налог има друге облике иÑторије прегледања на <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Лозинке</translation>
+<translation id="7050187094878475250">Покушали Ñте да поÑетите <ph name="DOMAIN" />, али је Ñервер предÑтавио Ñертификат Ñа периодом важења који је предугачак да би био поуздан.</translation>
+<translation id="7053983685419859001">Блокирај</translation>
<translation id="7064851114919012435">Контакт информације</translation>
<translation id="7079718277001814089">Овај Ñајт Ñадржи малвер</translation>
<translation id="7087282848513945231">Округ</translation>
-<translation id="7088615885725309056">Старије</translation>
<translation id="7090678807593890770">Потражите <ph name="LINK" /> на Google-у</translation>
+<translation id="7108819624672055576">Дозвољава додатак</translation>
<translation id="7119414471315195487">Затворите друге картице или програме</translation>
<translation id="7129409597930077180">Слање на ову адреÑу није могуће. Изаберите другу адреÑу.</translation>
<translation id="7138472120740807366">Ðачин иÑпоруке</translation>
@@ -664,22 +734,18 @@
<translation id="7220786058474068424">Обрада</translation>
<translation id="724691107663265825">Сајт који ћете поÑетити Ñадржи малвер</translation>
<translation id="724975217298816891">УнеÑите рок трајања и CVC за картицу <ph name="CREDIT_CARD" /> да биÑте ажурирали податке о картици. Када будете потврдили, подаци о картици ће бити поÑлати овом Ñајту.</translation>
-<translation id="725866823122871198">Ðије могуће уÑпоÑтавити приватну везу Ñа доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> јер време и датум на рачунару (<ph name="DATE_AND_TIME" />) ниÑу тачни.</translation>
+<translation id="7260504762447901703">Опозовите приÑтуп</translation>
<translation id="7275334191706090484">Обележивачи којим Ñе управља</translation>
<translation id="7298195798382681320">Препоручено</translation>
<translation id="7309308571273880165">Извештај о отказивању је Ñнимљен <ph name="CRASH_TIME" /> (кориÑник треба да га отпреми, још увек није отпремљен)</translation>
<translation id="7334320624316649418">&amp;Понови промену редоÑледа</translation>
<translation id="733923710415886693">Сертификат Ñервера није откривен помоћу ТранÑпарентноÑти Ñертификата.</translation>
-<translation id="7351800657706554155">Тренутно не можете да поÑетите <ph name="SITE" /> јер је његов Ñертификат опозван. Грешке и напади на мрежи Ñу обично привремени, па ће ова Ñтраница вероватно функциониÑати каÑније. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Командна линија</translation>
<translation id="7372973238305370288">резултат претраге</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ðе</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Потврдите картицу</translation>
-<translation id="7394102162464064926">Да ли Ñте Ñигурни да желите да избришете ове Ñтранице из иÑторије?
-
-ПÑÑÑ‚! Следећи пут режим Без архивирања <ph name="SHORTCUT_KEY" /> може да вам буде од кориÑти.</translation>
<translation id="7400418766976504921">URL адреÑа</translation>
<translation id="7419106976560586862">Путања профила</translation>
<translation id="7424977062513257142">Уграђена Ñтраница на овој веб-Ñтраници каже:</translation>
@@ -687,6 +753,7 @@
<translation id="7444046173054089907">Овај Ñајт је блокиран</translation>
<translation id="7445762425076701745">Ðије могуће у потпуноÑти потврдити идентитет Ñервера Ñа којим Ñте повезани. Повезани Ñте Ñа Ñервером који кориÑти назив који је важећи Ñамо у вашој мрежи, а којем Ñпољни ауторитет за издавање Ñертификата не може да провери влаÑништво. Будући да неки ауторитети за издавање Ñертификата ÑƒÐ¿Ñ€ÐºÐ¾Ñ Ñ‚Ð¾Ð¼Ðµ издају Ñертификате за ове називе, ни на који начин не можете да будете Ñигурни да Ñте повезани Ñа жељеним веб-Ñајтом, а не Ñа нападачем.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />да Ñазнате више<ph name="END_LINK" /> о овом проблему.</translation>
+<translation id="7455133967321480974">КориÑти глобалну подразумевану вредноÑÑ‚ (Блокирај)</translation>
<translation id="7460163899615895653">Ðедавне картице Ñа других уређаја Ñе приказују овде</translation>
<translation id="7469372306589899959">Потврђивање картице</translation>
<translation id="7481312909269577407">ПроÑледи</translation>
@@ -694,36 +761,43 @@
<translation id="7508255263130623398">Враћени ИД уређаја за Ñмернице је празан или Ñе не подудара Ñа актуелним ИД-ом уређаја</translation>
<translation id="7514365320538308">Преузми</translation>
<translation id="7518003948725431193">Ðиједна веб-Ñтраница није пронађена за веб адреÑу: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">ВредноÑÑ‚</translation>
<translation id="7537536606612762813">Обавезно</translation>
+<translation id="7542403920425041731">Када будете потврдили, подаци о картици ће бити поÑлати овом Ñајту.</translation>
<translation id="7542995811387359312">Онемогућено је аутоматÑко попуњавање кредитне картице зато што овај образац не кориÑти безбедну везу.</translation>
<translation id="7543525346216957623">Питај родитеља</translation>
<translation id="7549584377607005141">Ова веб-Ñтраница захтева податке које Ñте унели раније да би Ñе правилно приказала. Можете поново да пошаљете те податке, али ако то урадите, поновићете било коју радњу коју је ова Ñтраница претходно обавила.</translation>
<translation id="7552846755917812628">ИÑпробајте Ñледеће Ñавете:</translation>
<translation id="7554791636758816595">Ðова картица</translation>
+<translation id="7567204685887185387">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; његов безбедноÑни Ñертификат је можда лажно издат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Ова Ñтраница је на језику:<ph name="ORIGINAL_LANGUAGE" />Желите ли да је преведете?</translation>
<translation id="7569952961197462199">Желите ли да уклоните кредитну картицу из Chrome-а?</translation>
<translation id="7569983096843329377">Црна</translation>
<translation id="7578104083680115302">Плаћајте брзо на Ñајтовима и у апликацијама на Ñвим уређајима помоћу картица које Ñте Ñачували на Google-у.</translation>
<translation id="7588950540487816470">Интернет око наÑ</translation>
<translation id="7592362899630581445">Сертификат Ñервера крши ограничења за име.</translation>
+<translation id="7598391785903975535">Мање од <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">ХоÑÑ‚ <ph name="HOST_NAME" /> тренутно не може да обради овај захтев.</translation>
<translation id="7600965453749440009">Ðикад не преводи <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">ВредноÑÑ‚ је изван опÑега <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">ИÑтиче: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Већ имате податке који Ñу шифровани помоћу друге верзије лозинке за Google налог. УнеÑите је у наÑтавку.</translation>
-<translation id="7634554953375732414">Веза Ñа овим Ñајтом није приватна.</translation>
<translation id="7637571805876720304">Желите ли да уклоните кредитну картицу из Chromium-а?</translation>
<translation id="765676359832457558">Сакриј напредна подешавања...</translation>
<translation id="7658239707568436148">Откажи</translation>
+<translation id="7662298039739062396">Подешавање контролише додатак</translation>
<translation id="7667346355482952095">Враћени токен Ñмерница је празан или Ñе не подудара Ñа актуелним токеном</translation>
<translation id="7668654391829183341">Ðепознат уређај</translation>
<translation id="7669271284792375604">Ðападачи на овом Ñајту могу да покушају да Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ðµ да биÑте инÑталирали програме који штете доживљају прегледања (на пример, тако што мењају почетну Ñтраницу или приказују додатне оглаÑе на Ñајтовима које поÑећујете).</translation>
<translation id="7674629440242451245">ИнтереÑују Ð²Ð°Ñ Ð½Ð¾Ð²Ðµ занимљиве Chrome функције? ИÑпробајте програмерÑки канал на chrome.com/dev.</translation>
<translation id="7682287625158474539">ИÑпорука</translation>
+<translation id="7701040980221191251">Ðиједна</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />ÐаÑтави на <ph name="SITE" /> (није безбедно)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Сертификат</translation>
+<translation id="7716147886133743102">Блокира админиÑтратор</translation>
<translation id="7716424297397655342">Ðије могуће учитати овај Ñајт из кеша</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Ðе управља</translation>
<translation id="7755287808199759310">Родитељ може да га деблокира за тебе</translation>
<translation id="7758069387465995638">Можда је заштитни зид или антивируÑни Ñофтвер блокирао везу.</translation>
@@ -750,15 +824,15 @@
<translation id="7951415247503192394">(32-битни)</translation>
<translation id="7956713633345437162">Обележивачи на мобилном уређају</translation>
<translation id="7961015016161918242">Ðикад</translation>
-<translation id="7962083544045318153">ИД отказивања <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Увек преводи Ñа језика: <ph name="ORIGINAL_LANGUAGE" /> на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ðије наведено</translation>
<translation id="800218591365569300">Пробајте да затворите друге картице или програме да биÑте оÑлободили меморију.</translation>
<translation id="8012647001091218357">Тренутно не можемо да контактирамо родитеље. Пробај поново.</translation>
<translation id="8025119109950072390">Ðападачи на овом Ñајту могу да Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ðµ да биÑте урадили нешто опаÑно, на пример, да инÑталирате Ñофтвер или откријете личне податке (попут лозинки, бројева телефона или бројева кредитних картица).</translation>
-<translation id="803030522067524905">Google безбедно прегледање је недавно открило „пецање“ на <ph name="SITE" />. Сајтови Ñа „пецањем“ Ñе предÑтављају као неки други веб-Ñајтови да би Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ð¸Ð»Ð¸. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Језик ове Ñтранице је <ph name="SOURCE_LANGUAGE" />. Желите ли да је преведете на <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Питај (подразумевано)</translation>
<translation id="8041089156583427627">Пошаљи повратне информације</translation>
+<translation id="8041940743680923270">КориÑти глобалну подразумевану вредноÑÑ‚ (Питај)</translation>
<translation id="8088680233425245692">Прегледање чланка није уÑпело.</translation>
<translation id="8089520772729574115">мање од 1 MB</translation>
<translation id="8091372947890762290">Ðктивација је на чекању на Ñерверу</translation>
@@ -767,13 +841,14 @@
<translation id="8134994873729925007">ÐиÑмо уÑпели да пронађемо <ph name="BEGIN_ABBR" />DNS адреÑу<ph name="END_ABBR" /> Ñервера хоÑта <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Рачунар је прешао у режим Ñпавања.</translation>
<translation id="8150722005171944719">Датотека на адреÑи <ph name="URL" /> не може да Ñе чита. Можда је уклоњена или премештена или дозволе за датотеке Ñпречавају приÑтуп.</translation>
+<translation id="8184538546369750125">КориÑти глобалну подразумевану вредноÑÑ‚ (Дозволи)</translation>
+<translation id="8191494405820426728">ИД локалног отказивања <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Опозови премештање</translation>
<translation id="8201077131113104583">Ðеважећи URL за ажурирање за додатак Ñа ИД-ом „<ph name="EXTENSION_ID" />“.</translation>
<translation id="8202097416529803614">Резиме поруџбине</translation>
<translation id="8218327578424803826">Додељена локација:</translation>
<translation id="8225771182978767009">ОÑоба која је подеÑила овај рачунар је одлучила да блокира овај Ñајт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Ðападачи који Ñу тренутно на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ће можда покушати да на ваш рачунар инÑталирају опаÑне програме који краду или бришу податке (на пример, Ñлике, лозинке, поруке и бројеве кредитних картица).</translation>
<translation id="8241707690549784388">Страница коју тражите кориÑтила је информације које Ñте унели. Повратак на ту Ñтраницу може да проузрокује потребну понављања радњи које Ñте извршили. Желите ли да наÑтавите?</translation>
<translation id="8249320324621329438">ПоÑледње учитано:</translation>
<translation id="8253091569723639551">ÐдреÑа за обрачун је обавезна</translation>
@@ -781,6 +856,7 @@
<translation id="8289355894181816810">Контактирајте админиÑтратора мреже ако ниÑте Ñигурни шта то значи.</translation>
<translation id="8293206222192510085">Додавање обележивача</translation>
<translation id="8294431847097064396">Извор</translation>
+<translation id="8306404619377842860">УÑпоÑтављање приватне везе Ñа доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> није уÑпело јер Ñу датум и време уређаја (<ph name="DATE_AND_TIME" />) нетачни. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Превођење није уÑпело због проблема Ñа мрежном везом.</translation>
<translation id="8332188693563227489">ПриÑтуп хоÑту <ph name="HOST_NAME" /> је одбијен</translation>
<translation id="834457929814110454">Ðко разумете безбедноÑне ризике, можете да <ph name="BEGIN_LINK" />поÑетите овај Ñајт<ph name="END_LINK" /> пре него што уклонимо штетне програме.</translation>
@@ -801,11 +877,9 @@
<translation id="8483780878231876732">Да биÑте кориÑтили картице Ñа Google налога, пријавите Ñе у Chrome</translation>
<translation id="8488350697529856933">ОдноÑе Ñе на</translation>
<translation id="8498891568109133222">Одговор хоÑта <ph name="HOST_NAME" /> је трајао предуго.</translation>
-<translation id="852346902619691059">Овај Ñервер не може да докаже да је <ph name="DOMAIN" />; оперативни ÑиÑтем вашег уређаја нема поверења у његов безбедноÑни Ñертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу. <ph name="BEGIN_LEARN_MORE_LINK" />Сазнајте више<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Година иÑтека</translation>
<translation id="8543181531796978784">Можете да <ph name="BEGIN_ERROR_LINK" />пријавите проблем Ñа откривањем<ph name="END_ERROR_LINK" /> или, ако Ñхватате безбедноÑне ризике, <ph name="BEGIN_LINK" />поÑетите овај небезбедан Ñајт<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Превод није уÑпео јер језик Ñтранице није могао да буде утврђен.</translation>
-<translation id="8559762987265718583">Ðије могуће уÑпоÑтавити приватну везу Ñа доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> јер датум и време на уређају (<ph name="DATE_AND_TIME" />) ниÑу тачни.</translation>
<translation id="8571890674111243710">Превођење Ñтранице на <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Додај тел. број
</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">Да биÑте уÑпоÑтавили безбедну везу, Ñат на уређају мора да буде тачан. То је зато што Ñертификати које веб-Ñајтови кориÑте за идентификацију важе Ñамо одређени временÑки период. Пошто Ñат на вашем уређају није тачан, Chromium не може да верификује ове Ñертификате.</translation>
<translation id="8740359287975076522">ÐиÑмо уÑпели да пронађемо &lt;abbr id="dnsDefinition"&gt;DNS адреÑу&lt;/abbr&gt; хоÑта <ph name="HOST_NAME" />. Покушавамо да утврдимо у чему је проблем.</translation>
<translation id="8759274551635299824">Ова картица је иÑтекла</translation>
+<translation id="8761567432415473239">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило штетне програме<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Понови бриÑање</translation>
<translation id="8800988563907321413">Предлози у близини ће Ñе приказивати овде</translation>
<translation id="8820817407110198400">Обележивачи</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">Ðедавно затворено</translation>
<translation id="8874824191258364635">УнеÑите важећи број картице</translation>
<translation id="8876793034577346603">Рашчлањивање конфигурације мреже није уÑпело.</translation>
-<translation id="8877192140621905067">Када будете потврдили, подаци о картици ће бити поÑлати овом Ñајту</translation>
<translation id="8889402386540077796">ÐијанÑа</translation>
<translation id="8891727572606052622">Ðеважећи режим прокÑија.</translation>
<translation id="889901481107108152">Жао нам је, овај екÑперимент није доÑтупан на платформи.</translation>
<translation id="8903921497873541725">Увећавање</translation>
<translation id="8931333241327730545">Да ли желите да Ñачувате ову картицу на Google налог?</translation>
<translation id="8932102934695377596">Сат вам каÑни</translation>
-<translation id="8954894007019320973">(наÑтавак)</translation>
<translation id="8971063699422889582">Сертификат Ñервера је иÑтекао.</translation>
<translation id="8986494364107987395">ÐутоматÑки шаљи Google-у ÑтатиÑтичке податке о коришћењу и извештаје о отказивању</translation>
-<translation id="8987927404178983737">МеÑец</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Сајт који ћете поÑетити Ñадржи штетне програме</translation>
+<translation id="8997023839087525404">Сервер је приказао Ñертификат који није јавно откривен помоћу Ñмерница ТранÑпарентноÑÑ‚ Ñертификата. То је обавезно за неке Ñертификате да биÑмо Ñе уверили да Ñу поуздани и да штите од нападача.</translation>
<translation id="9001074447101275817">ПрокÑи <ph name="DOMAIN" /> захтева кориÑничко име и лозинку.</translation>
+<translation id="9005998258318286617">Учитавање PDF документа није уÑпело.</translation>
<translation id="901974403500617787">Ознаке које Ñе примењују у целом ÑиÑтему може да подеÑи Ñамо влаÑник: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">ÐдреÑа за обрачун за картицу је обавезна</translation>
<translation id="9020542370529661692">Ова Ñтраница је преведена на <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">БезбедноÑна грешка</translation>
<translation id="9038649477754266430">КориÑтите уÑлугу предвиђања да биÑте брже учитавали Ñтранице</translation>
<translation id="9039213469156557790">Поред тога, ова Ñтраница Ñадржи и друге реÑурÑе који ниÑу безбедни. Ове реÑурÑе могу да виде и други док Ñу у пролазу и нападач може да их измени како би променио понашање Ñтранице.</translation>
-<translation id="9040185888511745258">Ðападачи на <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> могу да покушају да Ð²Ð°Ñ Ð¿Ñ€ÐµÐ²Ð°Ñ€Ðµ да биÑте инÑталирали програме који штете доживљају прегледања (на пример, тако што мењају почетну Ñтраницу или приказују додатне оглаÑе на Ñајтовима које поÑећујете).</translation>
+<translation id="9049981332609050619">Покушали Ñте да дођете до домена <ph name="DOMAIN" />, али Ñервер је поÑлао неважећи Ñертификат.</translation>
<translation id="9050666287014529139">ПриÑтупна фраза</translation>
<translation id="9065203028668620118">Измени</translation>
<translation id="9068849894565669697">Изаберите боју</translation>
+<translation id="9069693763241529744">Блокира додатак</translation>
<translation id="9076283476770535406">Можда обухвата Ñадржај за одраÑле</translation>
<translation id="9078964945751709336">Потребно је више информација</translation>
<translation id="9103872766612412690"><ph name="SITE" /> обично кориÑти шифровање да би заштитио информације. Када је Chromium овог пута покушао да Ñе повеже Ñа <ph name="SITE" />, веб-Ñајт је вратио необичне и нетачне акредитиве. Или нападач покушава да Ñе предÑтави као <ph name="SITE" /> или је екран за Wi-Fi пријављивање прекинуо везу. Информације Ñу и даље безбедне зато што је Chromium прекинуо везу пре него што Ñу размењени било какви подаци.</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">&amp;Опозови измену</translation>
<translation id="9154194610265714752">Ðжурирано</translation>
<translation id="9157595877708044936">Подешавање...</translation>
+<translation id="9169664750068251925">Увек блокирај на овом Ñајту</translation>
<translation id="9170848237812810038">&amp;Опозови</translation>
<translation id="917450738466192189">Сертификат Ñервера је неважећи.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> и још <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419">ХоÑÑ‚ <ph name="HOST_NAME" /> кориÑти неподржани протокол.</translation>
<translation id="9205078245616868884">Подаци Ñе шифрују помоћу приÑтупне фразе за Ñинхронизацију. УнеÑите је да биÑте започели Ñинхронизацију.</translation>
<translation id="9207861905230894330">Додавање чланка није уÑпело.</translation>
+<translation id="9219103736887031265">Слике</translation>
<translation id="933612690413056017">Ðије уÑпоÑтављена веза Ñа интернетом</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ОБРИШИ ОБРÐЗÐЦ</translation>
<translation id="939736085109172342">Ðови директоријум</translation>
<translation id="941721044073577244">Изгледа да немате дозволу да поÑетите овај Ñајт</translation>
<translation id="969892804517981540">Званична верзија</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{None}=1{1 Ñтавка}one{# Ñтавка}few{# Ñтавке}other{# Ñтавки}}</translation>
<translation id="988159990683914416">Верзија за програмере</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sv.xtb b/chromium/components/strings/components_strings_sv.xtb
index 23cfb64cb04..af51a354898 100644
--- a/chromium/components/strings/components_strings_sv.xtb
+++ b/chromium/components/strings/components_strings_sv.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Rotera medurs</translation>
<translation id="1038842779957582377">okänt namn</translation>
<translation id="1050038467049342496">Stäng andra appar</translation>
-<translation id="1053591932240354961">Det går inte att besöka <ph name="SITE" /> just nu eftersom webbplatsen skickade förvrängda användaruppgifter som Google Chrome inte kan behandla. Nätverksfel och attacker är vanligtvis tillfälliga, så sidan fungerar troligen senare. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Ångra Lägg till</translation>
<translation id="10614374240317010">Aldrig sparad</translation>
<translation id="106701514854093668">Bokmärken på skrivbordet</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Cacheminnet för policyn är OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> säger:</translation>
<translation id="1132774398110320017">Inställningar för Autofyll i Chrome …</translation>
+<translation id="1150979032973867961">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom datorns operativsystem inte litar på dess säkerhetscertifikat. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
+<translation id="1151972924205500581">Lösenord krävs</translation>
<translation id="1152921474424827756">Öppna en <ph name="BEGIN_LINK" />cachad kopia<ph name="END_LINK" /> av <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> stängde oväntat ner anslutningen.</translation>
<translation id="1161325031994447685">Ã¥teransluta till Wi-Fi</translation>
+<translation id="1165039591588034296">Fel</translation>
<translation id="1175364870820465910">Skriv &amp;ut...</translation>
<translation id="1181037720776840403">Ta bort</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Rapportera uppgifter<ph name="END_WHITEPAPER_LINK" /> om möjliga säkerhetsincidenter till Google automatiskt. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Mer från den här webbplatsen</translation>
<translation id="1206967143813997005">Felaktig första signatur</translation>
<translation id="1209206284964581585">Dölj för tillfället</translation>
+<translation id="121201262018556460">Du försökte öppna <ph name="DOMAIN" />, men servern visade ett certifikat som signerats med en svag nyckel. Det innebär att den privata nyckeln som servern visar kan vara en förfalskning och att servern kanske inte är den server du tror (du kanske kommunicerar med en skadlig server).</translation>
<translation id="1219129156119358924">Systemsäkerhet</translation>
-<translation id="1227224963052638717">Okänd policy.</translation>
+<translation id="1227224963052638717">Okänd princip.</translation>
<translation id="1227633850867390598">Dölj värde</translation>
<translation id="1228893227497259893">Fel enhetsidentifierare</translation>
<translation id="1232569758102978740">Namnlös</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synkroniserade)</translation>
<translation id="1263231323834454256">Läslista</translation>
<translation id="1264126396475825575">Felrapport skapades <ph name="CRASH_TIME" /> (har ännu inte laddats upp eller ignorerats)</translation>
+<translation id="1281526147609854549">Utfärdades av <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Farligt innehåll har blockerats</translation>
<translation id="1285320974508926690">Översätt aldrig den här webbplatsen</translation>
<translation id="129553762522093515">Nyligen stängda</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Testa att rensa cookies<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Din aktivitet <ph name="BEGIN_EMPHASIS" />kanske fortfarande är synlig<ph name="END_EMPHASIS" /> för:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />webbplatser som du besöker
+ <ph name="LIST_ITEM" />din arbetsgivare eller skola
+ <ph name="LIST_ITEM" />din internetleverantör.
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Registreringsdomän:</translation>
<translation id="1340482604681802745">Hämtningsadress</translation>
<translation id="1344211575059133124">Du behöver tillstånd att besöka den här webbplatsen</translation>
<translation id="1344588688991793829">Inställningar för Autofyll i Chromium …</translation>
+<translation id="1348198688976932919">Det finns farliga appar på webbplatsen du är på väg till</translation>
<translation id="1374468813861204354">förslag</translation>
<translation id="1375198122581997741">Om version</translation>
<translation id="1377321085342047638">Kortnummer</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> skickade ingen data.</translation>
<translation id="1407135791313364759">Öppna alla</translation>
<translation id="1413809658975081374">Sekretessfel</translation>
+<translation id="14171126816530869">Identiteten hos <ph name="ORGANIZATION" /> på <ph name="LOCALITY" /> har verifierats av <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Skriv ut</translation>
-<translation id="1442912890475371290">Blockerade ett försök <ph name="BEGIN_LINK" />att besöka en sida på <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Det går inte att besöka <ph name="SITE" /> just nu på grund av att fäste av certifikat förekommer på webbplatsen. Nätverksfel och attacker är vanligtvis tillfälliga, så den här sidan fungerar troligen senare. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> till}other{<ph name="PAYMENT_METHOD_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> till}}</translation>
<translation id="1506687042165942984">Visa en sparad kopia av sidan (en som vi vet är inaktuell).</translation>
<translation id="1517433312004943670">Telefonnummer är obligatoriskt</translation>
<translation id="1519264250979466059">Programversionsdatum</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">JavaScript måste aktiveras för att du ska kunna använda den här funktionen.</translation>
<translation id="1555130319947370107">Blå</translation>
<translation id="1559528461873125649">Filen eller katalogen finns inte</translation>
-<translation id="1559572115229829303">&lt;p&gt;Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom enhetens datum och tid (<ph name="DATE_AND_TIME" />) inte stämmer.&lt;/p&gt;
-
- &lt;p&gt;Ändra datumet och tiden under &lt;strong&gt;Allmänt&lt;/strong&gt; i appen &lt;strong&gt;Inställningar&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Ett fel uppstod när webbsidan skulle visas.</translation>
<translation id="1592005682883173041">Lokal dataåtkomst</translation>
+<translation id="1594030484168838125">Välj</translation>
<translation id="161042844686301425">Cyanblå</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Vill du att Chrome sparar det här kortet?</translation>
<translation id="1639239467298939599">Läser in</translation>
<translation id="1640180200866533862">Användarpolicyer</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Nätverkskonfigurationen är ogiltig och kan inte importeras.</translation>
<translation id="1644574205037202324">Historik</translation>
<translation id="1645368109819982629">Det finns inget stöd för protokollet</translation>
+<translation id="1655462015569774233">{1,plural, =1{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat gick ut i går. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. Dagens datum är <ph name="CURRENT_DATE" /> enligt datorklockan. Går den rätt? I annat fall bör du ställa om datorklockan och sedan uppdatera sidan.}other{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat gick ut för # dagar sedan. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. Dagens datum är <ph name="CURRENT_DATE" /> enligt datorklockan. Går den rätt? I annat fall bör du ställa om datorklockan och sedan uppdatera sidan.}}</translation>
<translation id="1656489000284462475">Upphämtning</translation>
<translation id="1663943134801823270">Kort och adresser har hämtats från Chrome. Du hanterar dessa under <ph name="BEGIN_LINK" />Inställningar<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">På <ph name="SITE" /> används vanligtvis kryptering (SSL) för att skydda din information. När Chrome försökte ansluta till <ph name="SITE" /> den här gången skickade webbplatsen tillbaka ovanliga och felaktiga uppgifter. Sådant kan hända när en angripare utger sig för att vara <ph name="SITE" /> eller när anslutningen har avbrutits av en Wi-Fi-inloggningsskärm. Din information är fortfarande säker eftersom Chrome avbröt anslutningen innan någon data utbyttes.</translation>
-<translation id="168328519870909584">Det kan hända att angripare som för närvarande finns på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> försöker installera skadliga appar på enheten som stjäl eller raderar dina uppgifter (t.ex. foton, lösenord, meddelanden och kreditkort).</translation>
<translation id="168841957122794586">Servercertifikatet innehåller en svag kryptografisk nyckel.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat uppges börja gälla i morgon. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad.}other{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat uppges börja gälla om # dagar. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Du behöver tillstånd från <ph name="NAME" /> om du vill besöka den här webbplatsen</translation>
<translation id="1721424275792716183">* Fältet är obligatoriskt</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Ladda ned sidan senare</translation>
<translation id="17513872634828108">Öppna flikar</translation>
<translation id="1753706481035618306">Sidnummer</translation>
+<translation id="1763864636252898013">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom enhetens operativsystem inte litar på dess säkerhetscertifikat. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Testa att köra nätverksdiagnostik för Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Uppdatera lösenfrasen för synkroniseringen.</translation>
<translation id="1787142507584202372">Öppna flikar visas här</translation>
+<translation id="1789575671122666129">Popup-fönster</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Namn på kortinnehavare</translation>
-<translation id="1803678881841855883">Googles tjänst Säker webbsökning <ph name="BEGIN_LINK" />hittade skadliga program<ph name="END_LINK" /> på <ph name="SITE" /> nyligen. Ibland förekommer det skadlig programvara på webbplatser som vanligtvis är säkra. Det skadliga innehållet kommer från <ph name="SUBRESOURCE_HOST" />, som är en känd distributör av skadlig programvara. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Lades till den <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Begäran eller parametrar i begäran var ogiltiga</translation>
<translation id="1826516787628120939">Kontrollerar</translation>
<translation id="1834321415901700177">Den här webbplatsen innehåller skadliga program</translation>
+<translation id="1840414022444569775">Detta kortnummer används redan</translation>
<translation id="1842969606798536927">Betala</translation>
<translation id="1871208020102129563">Proxyn är inställd på att använda fasta proxyservrar, inte en webbadress med PAC-skript.</translation>
<translation id="1871284979644508959">Obligatoriskt fält</translation>
<translation id="187918866476621466">Öppna startsidorna</translation>
<translation id="1883255238294161206">Komprimera lista</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> till}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> till}}</translation>
<translation id="1898423065542865115">Filtrering</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ingen}=1{1 webbplats}other{# webbplatser}}</translation>
<translation id="194030505837763158">Öppna <ph name="LINK" /></translation>
<translation id="1962204205936693436">Bokmärken på <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Serieproduktionsfel</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Ignoreras eftersom den åsidosätts av <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Söker efter Physical Web-sidor i närheten</translation>
<translation id="213826338245044447">Bokmärken i mobilen</translation>
-<translation id="2148716181193084225">Idag</translation>
+<translation id="2147827593068025794">Bakgrundssynkronisering</translation>
<translation id="2154054054215849342">Synkronisering är inte tillgänglig för din domän</translation>
<translation id="2154484045852737596">Redigera kortet</translation>
<translation id="2166049586286450108">Fullständig administrativ åtkomst</translation>
<translation id="2166378884831602661">Webbplatsen kan inte tillhandahålla en säker anslutning</translation>
<translation id="2181821976797666341">Policyer</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adress}other{# adresser}}</translation>
+<translation id="2187317261103489799">Identifiera (standard)</translation>
<translation id="2202020181578195191">Ange ett giltigt utgångsår</translation>
<translation id="2212735316055980242">Policyn hittades inte</translation>
<translation id="2213606439339815911">Hämtar poster …</translation>
+<translation id="2218879909401188352">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> skulle kunna installera farliga appar som skadar enheten, lägger till dolda avgifter på din mobilfaktura eller stjäl personliga uppgifter. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Åtgärda anslutningsproblemet med hjälp av <ph name="BEGIN_LINK" />diagnostiseringsappen<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Skicka nu</translation>
<translation id="225207911366869382">Värdet är inte längre giltigt för policyn.</translation>
<translation id="2262243747453050782">HTTP-fel</translation>
+<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2282872951544483773">Otillgängliga experiment</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> objekt}other{<ph name="ITEM_COUNT" /> objekt}}</translation>
<translation id="2292556288342944218">Internetanslutningen har blockerats</translation>
<translation id="230155334948463882">Har du ett nytt kort?</translation>
-<translation id="2305919008529760154">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat kan ha utfärdats utan behörighet. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> kräver användarnamn och lösenord.</translation>
-<translation id="2318774815570432836">Det går inte att besöka <ph name="SITE" /> just nu på grund av att HSTS används på webbplatsen. Nätverksfel och attacker är vanligtvis tillfälliga, så den här sidan fungerar troligen senare. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Inställningen styrs av administratören</translation>
<translation id="2354001756790975382">Övriga bokmärken</translation>
+<translation id="2354430244986887761">Google Säker webbsökning <ph name="BEGIN_LINK" />hittade skadliga appar<ph name="END_LINK" /> nyligen på <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Det är möjligt att hackare kan se vilka bilder du visar på den här webbplatsen och att de försöker lura dig genom att modifiera dem.</translation>
+<translation id="2356070529366658676">Fråga</translation>
+<translation id="2359629602545592467">Flera</translation>
<translation id="2359808026110333948">Fortsätt</translation>
<translation id="2365563543831475020">Felrapport som skapades <ph name="CRASH_TIME" /> laddades inte upp</translation>
<translation id="2367567093518048410">Nivå</translation>
-<translation id="2371153335857947666">{1,plural, =1{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat gick ut i går. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. Dagens datum är <ph name="CURRENT_DATE" /> enligt datorklockan. Går den rätt? I annat fall bör du ställa om datorklockan och sedan uppdatera sidan. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.}other{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat gick ut för # dagar sedan. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. Dagens datum är <ph name="CURRENT_DATE" /> enligt datorklockan. Går den rätt? I annat fall bör du ställa om datorklockan och sedan uppdatera sidan. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Det finns inga användargränssnittsalternativ</translation>
<translation id="2384307209577226199">Standardinställning i företaget</translation>
<translation id="2386255080630008482">Servercertifikatet har återkallats.</translation>
<translation id="2392959068659972793">Visa policyer utan inställt värde</translation>
<translation id="239429038616798445">Det här fraktalternativet är inte tillgängligt. Testa ett annat alternativ.</translation>
<translation id="2396249848217231973">&amp;Ã…ngra Ta bort</translation>
-<translation id="2460160116472764928">Googles tjänst Säker webbsökning <ph name="BEGIN_LINK" />hittade skadliga program<ph name="END_LINK" /> på <ph name="SITE" /> nyligen. Ibland förekommer det skadlig programvara på webbplatser som vanligtvis är säkra. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat kan ha återkallats. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
<translation id="2463739503403862330">Fyll i</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />att köra nätverksdiagnostik<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Ogiltig sökadress.</translation>
+<translation id="2482878487686419369">Aviseringar</translation>
<translation id="2491120439723279231">Servercertifikatet innehåller fel.</translation>
<translation id="2495083838625180221">JSON-analysator</translation>
<translation id="2495093607237746763">Om alternativet är markerat sparar Chromium en kopia av kortet på enheten så att det går snabbare att fylla i formulär.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Föregående</translation>
<translation id="2515629240566999685">kontrollera mottagningen i området</translation>
<translation id="2516305470678292029">Användargränssnittsalternativ</translation>
+<translation id="2539524384386349900">Identifiera</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> skickade ett ogiltigt svar.</translation>
-<translation id="2552545117464357659">Nyare</translation>
<translation id="2556876185419854533">&amp;Ã…nga Redigera</translation>
<translation id="2587730715158995865">Från <ph name="ARTICLE_PUBLISHER" />. Läs denna och <ph name="OTHER_ARTICLE_COUNT" /> andra artiklar.</translation>
<translation id="2587841377698384444">Id för katalog-API:</translation>
<translation id="2597378329261239068">Dokumentet är lösenordsskyddat. Ange ett lösenord.</translation>
<translation id="2609632851001447353">Varianter</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ingen}=1{1 app ($1)}=2{2 appar ($1, $2)}other{# appar ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Klockan går före</translation>
<translation id="2639739919103226564">Status:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Ã…tkomst till filen nekades</translation>
<translation id="2653659639078652383">Skicka</translation>
<translation id="2666117266261740852">Stäng andra flikar eller appar</translation>
+<translation id="2670429602441959756">Den här sidan har funktioner som inte stöds i VR ännu. VR-läget avslutas …</translation>
<translation id="2674170444375937751">Vill du ta bort de här sidorna från historiken?</translation>
<translation id="2677748264148917807">Lämna</translation>
-<translation id="269990154133806163">Servern angav ett certifikat som inte har lämnats ut enligt policyn Certifikattransparens. Detta krävs för vissa certifikat för att säkerställa att de är tillförlitliga och skyddar mot hackare. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Läslista</translation>
<translation id="2704283930420550640">Värdet matchar inte formatet.</translation>
<translation id="2704951214193499422">Chromium kunde inte bekräfta kortet. Försök igen senare.</translation>
<translation id="2705137772291741111">Det gick inte att läsa den sparade (cachelagrade) kopian av webbplatsen.</translation>
<translation id="2709516037105925701">Autofyll</translation>
-<translation id="2712118517637785082">Du försökte öppna <ph name="DOMAIN" />, men servern angav ett certifikat som har återkallats av utfärdaren. Det innebär att säkerhetsuppgifterna som servern anger inte är tillförlitliga. Du kanske kommunicerar med en angripare. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Begär behörighet</translation>
<translation id="2713444072780614174">Vit</translation>
<translation id="2720342946869265578">I närheten</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Enhetsregister saknas</translation>
<translation id="2784949926578158345">Anslutningen återställdes.</translation>
<translation id="2794233252405721443">Webbplatsen har blockerats</translation>
+<translation id="2799020568854403057">Det finns skadliga appar på webbplatsen du är på väg till</translation>
+<translation id="2803306138276472711">Google Säker webbsökning upptäckte nyligen <ph name="BEGIN_LINK" />skadlig programvara<ph name="END_LINK" /> på <ph name="SITE" />. Ibland förekommer det skadlig programvara på webbplatser som vanligtvis är säkra.</translation>
<translation id="2824775600643448204">Adress- och sökfält</translation>
<translation id="2826760142808435982">Anslutningen är krypterad och verifieras med <ph name="CIPHER" /> och använder <ph name="KX" /> som nyckelutbytesmekanism.</translation>
<translation id="2835170189407361413">Rensa formuläret</translation>
+<translation id="2856444702002559011">En angripare kan försöka stjäla dina uppgifter från <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (t.ex. lösenord, meddelanden eller kreditkortsuppgifter). <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Läs inte in sidan igen</translation>
<translation id="2900469785430194048">Minnet tog slut när den här webbsidan skulle visas i Google Chrome.</translation>
<translation id="2909946352844186028">En nätverksförändring upptäcktes.</translation>
<translation id="2916038427272391327">Stäng andra program</translation>
<translation id="2922350208395188000">Servercertifikatet kan inte kontrolleras.</translation>
<translation id="2928905813689894207">Faktureringsadress</translation>
+<translation id="2941952326391522266">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat kommer från <ph name="DOMAIN2" />. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
<translation id="2948083400971632585">Du kan inaktivera alla proxyservrar som har konfigurerats för en anslutning från sidan Inställningar.</translation>
<translation id="2955913368246107853">Stäng sökfältet</translation>
<translation id="2958431318199492670">Nätverkskonfigurationen uppfyller inte ONC-standarden. Det kan hända att delar av konfigurationen inte kan importeras.</translation>
-<translation id="29611076221683977">Det kan hända att angripare som för närvarande finns på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> försöker installera skadliga program på din Mac som stjäl eller raderar dina uppgifter (t.ex. foton, lösenord, meddelanden och kreditkort).</translation>
<translation id="2966678944701946121">Giltigt till: <ph name="EXPIRATION_DATE_ABBR" />, lades till den <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Om du vill upprätta en säker anslutning måste klockan vara rätt inställd. Det beror på att certifikaten som webbplatserna använder för att identifiera sig har en bestämd giltighetstid. Google Chrome kan inte verifiera certifikaten eftersom klockan på enheten inte går rätt.</translation>
<translation id="2972581237482394796">&amp;Upprepa</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Ange en giltig adress</translation>
<translation id="2986368408720340940">Det här alternativet för utlämning är inte tillgängligt. Testa ett annat alternativ.</translation>
<translation id="2991174974383378012">Dela med webbplatsen</translation>
+<translation id="2991571918955627853">Du kan inte besöka <ph name="SITE" /> just nu eftersom webbplatsen använder HSTS. Nätverksfel och attacker är ofta tillfälliga, så sidan kommer förmodligen att fungera senare.</translation>
<translation id="3005723025932146533">Visa sparad kopia</translation>
<translation id="3008447029300691911">Ange CVC-koden för <ph name="CREDIT_CARD" />. När du bekräftar delas kortinformationen med den här webbplatsen.</translation>
<translation id="3010559122411665027">Listposten <ph name="ENTRY_INDEX" />: <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Blockerades automatiskt</translation>
<translation id="3024663005179499861">Felaktig policytyp</translation>
<translation id="3032412215588512954">Vill du läsa in den här webbplatsen igen?</translation>
<translation id="3037605927509011580">Oj, ett fel har uppstått!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{minst 1 objekt på synkroniserade enheter}=1{1 objekt (och fler på synkroniserade enheter)}other{# objekt (och fler på synkroniserade enheter)}}</translation>
<translation id="3041612393474885105">Certifikatinformation</translation>
<translation id="3063697135517575841">Det gick inte att bekräfta kortet. Försök igen senare.</translation>
<translation id="3064966200440839136">Om du betalar i ett externt program sker inte det i inkognitoläge. Vill du fortsätta?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ingen}=1{1 lösenord}other{# lösenord}}</translation>
<translation id="3093245981617870298">Du är offline.</translation>
<translation id="3105172416063519923">Tillgångs-id:</translation>
<translation id="3109728660330352905">Du är inte behörig att se den här sidan.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Testa att köra anslutningsdiagnostik<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Det gick inte att avkoda svaret</translation>
<translation id="3150653042067488994">Tillfälligt serverfel</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Sidor som visas på flikar i inkognitoläget försvinner från webbhistoriken, från dina cookies och från sökhistoriken när alla inkognitoflikar har stängts. Alla filer som du laddar ned eller bokmärken som du skapar sparas.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">Ö</translation>
+<translation id="317583078218509884">De nya inställningarna för webbplatsbehörighet börjar gälla när sidan uppdateras.</translation>
<translation id="3176929007561373547">Kontrollera dina proxyinställningar eller kontakta nätverksadministratören om du vill
kontrollera att proxyservern fungerar. Om du inte tror att du ska
använda en proxyserver:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Öppna sidan i inkognitoläge</translation>
-<translation id="3202578601642193415">Senaste</translation>
+<translation id="320323717674993345">Avbryt betalningen</translation>
<translation id="3207960819495026254">Bokmärkt</translation>
+<translation id="3225919329040284222">Ett certifikat som inte överensstämmer med inbyggda förväntningar presenterades på servern. Förväntningarna gäller för webbplatser med hög säkerhet för att skydda dig.</translation>
<translation id="3226128629678568754">Om du på nytt vill skicka datan som behövs för att läsa in sidan trycker du på knappen Läs in igen.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Det gick inte att översätta eftersom sidan redan är på <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Ange CVC-koden för <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Upptäck alltid viktigt innehåll på den här webbplatsen</translation>
<translation id="3254409185687681395">Bokmärk sidan</translation>
<translation id="3270847123878663523">&amp;Ångra Ändra ordning</translation>
<translation id="3282497668470633863">Lägg till namnet på kortet</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">inställningar</translation>
<translation id="3345135638360864351">Det gick inte att skicka begäran om åtkomst till den här webbplatsen till <ph name="NAME" />. Försök igen.</translation>
<translation id="3355823806454867987">Ändra proxyinställningar...</translation>
+<translation id="3361596688432910856">Följande information <ph name="BEGIN_EMPHASIS" />sparas inte<ph name="END_EMPHASIS" /> i Chrome:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />webbhistoriken
+ <ph name="LIST_ITEM" />cookies och webbplatsdata
+ <ph name="LIST_ITEM" />uppgifter som angetts i formulär.
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Fel på klockan</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> objekt till …</translation>
<translation id="337363190475750230">Tagen ur bruk</translation>
<translation id="3377188786107721145">Fel vid analys av policyn</translation>
<translation id="3380365263193509176">Okänt fel</translation>
<translation id="3380864720620200369">Klient-ID:</translation>
<translation id="3391030046425686457">Leveransadress</translation>
<translation id="3395827396354264108">Alternativ för utlämning</translation>
-<translation id="340013220407300675">Det är möjligt att hackare försöker stjäla dina uppgifter från <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (till exempel lösenord, meddelanden eller kreditkort).</translation>
<translation id="3422248202833853650">Testa att stänga andra program för att frigöra minne.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> kan inte nås för tillfället.</translation>
+<translation id="3427092606871434483">Tillåt (standard)</translation>
<translation id="3427342743765426898">&amp;Gör om Redigera</translation>
<translation id="3431636764301398940">Spara kortet på enheten</translation>
<translation id="3435896845095436175">Aktivera</translation>
<translation id="3447661539832366887">Enhetens ägare har stängt av dinosauriespelet.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Hämta intervall:</translation>
<translation id="3462200631372590220">Dölja avancerade uppgifter</translation>
<translation id="3467763166455606212">Kortinnehavarens namn måste anges</translation>
<translation id="3478058380795961209">Sista giltighetsmånad</translation>
<translation id="3479539252931486093">Var det här oväntat? <ph name="BEGIN_LINK" />Meddela oss<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Inte nu</translation>
-<translation id="348000606199325318">Krasch-id <ph name="CRASH_LOCAL_ID" /> (server-id: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Vi kunde inte nå din förälder just nu. Försök igen.</translation>
<translation id="3528171143076753409">Servercertifikatet är inte tillförlitligt.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Minst 1 objekt på synkroniserade enheter}=1{1 objekt (och fler på synkroniserade enheter)}other{# objekt (och fler på synkroniserade enheter)}}</translation>
<translation id="3539171420378717834">Spara en kopia av kortet på enheten</translation>
<translation id="3542684924769048008">Använd lösenord för:</translation>
+<translation id="3545341443414427877">Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom datum och tid på datorn (<ph name="DATE_AND_TIME" />) inte stämmer. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Kryptera alla synkroniserade data med en egen lösenfras</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> till ...</translation>
-<translation id="3555561725129903880">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat kommer från <ph name="DOMAIN2" />. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">En ansvarig kan ta bort blockeringen</translation>
<translation id="3566021033012934673">Anslutningen är inte privat</translation>
+<translation id="3569145463236695319">&lt;p&gt;Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom datum och tid på enheten (<ph name="DATE_AND_TIME" />) inte stämmer.&lt;/p&gt;
+
+ &lt;p&gt;Ändra datumet och tiden under &lt;strong&gt;Allmänt&lt;/strong&gt; i appen &lt;strong&gt;Inställningar&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Lägg till namn</translation>
<translation id="3583757800736429874">&amp;Gör om Flytta</translation>
<translation id="3586931643579894722">Dölj detaljerad information</translation>
-<translation id="3587482841069643663">Alla</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Ange ett giltigt utgångsdatum</translation>
<translation id="36224234498066874">Rensa webbinformation...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Certifikatinformation</translation>
<translation id="3690164694835360974">Osäker inloggning</translation>
<translation id="3693415264595406141">Lösenord:</translation>
-<translation id="3696411085566228381">ingen</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Läser in...</translation>
<translation id="3712624925041724820">Licenserna har tagit slut</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />kontrollera proxyn, brandväggen och DNS-konfigureringen<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Om du är medveten om säkerhetsriskerna kan du <ph name="BEGIN_LINK" />besöka den här osäkra webbplatsen<ph name="END_LINK" /> innan de skadliga programmen har tagits bort.</translation>
<translation id="3739623965217189342">Länk som du har kopierat</translation>
+<translation id="3744899669254331632">Du kan inte besöka <ph name="SITE" /> just nu eftersom webbplatsen skickade krypterade användaruppgifter som Chromium inte kan bearbeta. Nätverksfel och attacker är ofta tillfälliga, så sidan kommer förmodligen fungera senare.</translation>
+<translation id="3748148204939282805">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan försöka lura dig att göra något riskfyllt, som att installera programvara eller avslöja personliga uppgifter (t.ex. lösenord, telefonnummer eller kreditkortsuppgifter). <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Det gick inte att översätta på grund av ett serverfel.</translation>
<translation id="3759461132968374835">Inga krascher har rapporterats nyligen. Krascher som uppstod när kraschrapporteringen var inaktiverad visas inte här.</translation>
+<translation id="3778403066972421603">Vill du spara det här kortet i Google-kontot och på den här enheten?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Utgångsdatum: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Om du använder en proxyserver ...</translation>
<translation id="3828924085048779000">Lösenfrasen får inte vara tom.</translation>
-<translation id="3845539888601087042">Historik från enheter som du är inloggad på visas. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Bakåt</translation>
<translation id="3858027520442213535">Uppdatera datum och tid</translation>
<translation id="3884278016824448484">Motstridiga enhetsidentifierare</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Din begäran om att få tillgång till denna webbplats har skickats till <ph name="NAME" /></translation>
<translation id="3890664840433101773">Lägg till e-post</translation>
<translation id="3901925938762663762">Kortet gäller inte längre</translation>
-<translation id="3933571093587347751">{1,plural, =1{Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat uppges börja gälla i morgon. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.}other{Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat uppges börja gälla om # dagar. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Det gick inte att läsa in PDF-dokumentet</translation>
+<translation id="3945915738023014686">Id i den uppladdade felrapporten <ph name="CRASH_ID" /> (Lokalt krasch-id: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom inga alternativa namn på certifikatobjektet anges i säkerhetscertifikatet. Detta kan bero på en felaktig konfigurering eller att en angripare manipulerat anslutningen.</translation>
<translation id="3963721102035795474">Läsarläge</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ingen}=1{Från 1 webbplats }other{Från # webbplatser }}</translation>
<translation id="397105322502079400">Beräknar ...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> har blockerats</translation>
+<translation id="3987940399970879459">Mindre än 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 webbsida i närheten}other{# webbsidor i närheten}}</translation>
<translation id="4021036232240155012">DNS är en webbtjänst som översätter namnet på en webbplats till motsvarande internetadress.</translation>
<translation id="4030383055268325496">&amp;Ångra Lägg till</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Proxykonfigurationen är inställd på att använda en webbadress med PAC-skript, inte fasta proxyservrar.</translation>
<translation id="4098354747657067197">Webbplatsen som öppnas är bedräglig</translation>
<translation id="4103249731201008433">Enhetens serienummer är ogiltigt</translation>
+<translation id="410351446219883937">Automatisk uppspelning</translation>
<translation id="4103763322291513355">Besök &lt;strong&gt;chrome://policy&lt;/strong&gt; om du vill visa listan med webbadresser som inte är godkända och andra policyer som angetts av systemadministratören.</translation>
-<translation id="4110615724604346410">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat innehåller fel. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Magenta</translation>
+<translation id="4116663294526079822">Tillåt alltid på den här webbplatsen</translation>
<translation id="4117700440116928470">Principens omfattning stöds inte.</translation>
-<translation id="4118212371799607889">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom Chromium inte litar på dess säkerhetscertifikat. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 till}other{# till}}</translation>
<translation id="4130226655945681476">Kontrollera nätverkskablar, modem och router</translation>
+<translation id="413544239732274901">Läs mer</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Använd global standardinställning (Upptäck)</translation>
+<translation id="4165986682804962316">Platsinställningar</translation>
<translation id="4169947484918424451">Vill du att Chromium sparar det här kortet?</translation>
<translation id="4171400957073367226">Felaktig verifieringssignatur</translation>
<translation id="4196861286325780578">&amp;Gör om Flytta</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />kontrollera konfigureringarna för brandväggen och antivirusprogram<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{inga}=1{1 app ($1)}=2{2 appar ($1, $2)}other{# appar ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Kraschar</translation>
+<translation id="422022731706691852">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan försöka lura dig att installera program som stör dig när du surfar (t.ex. genom att ändra startsidan eller visa extra annonser på webbplatser du besöker). <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Testa att köra nätverksdiagnostik<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Giltigt</translation>
<translation id="4250431568374086873">Anslutningen till den här webbplatsen är inte helt säker</translation>
<translation id="4250680216510889253">Nej</translation>
<translation id="425582637250725228">Ändringar som du har gjort kanske inte sparas.</translation>
<translation id="4258748452823770588">Felaktig signatur</translation>
+<translation id="4265872034478892965">Beviljades av administratören</translation>
<translation id="4269787794583293679">(Inget användarnamn)</translation>
<translation id="4275830172053184480">Starta om enheten</translation>
<translation id="4280429058323657511">, utgångsdatum <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Googles tjänst Säker webbsökning <ph name="BEGIN_LINK" />hittade skadliga program<ph name="END_LINK" /> på <ph name="SITE" /> nyligen. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Föräldratips</translation>
<translation id="4304224509867189079">Logga in</translation>
-<translation id="432290197980158659">Ett certifikat som inte överensstämmer med inbyggda förväntningar angavs av servern. Förväntningarna gäller för webbplatser med hög säkerhet för att skydda dig. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Blockera (standard)</translation>
<translation id="4325863107915753736">Det gick inte att hitta artikeln</translation>
<translation id="4326324639298822553">Kontrollera utgångsdatum och försök igen</translation>
<translation id="4331708818696583467">Inte säkert</translation>
<translation id="4356973930735388585">Det kan hända att angripare på den här webbplatsen försöker installera skadliga program på datorn som stjäl eller raderar dina uppgifter (t.ex. foton, lösenord, meddelanden och kreditkort).</translation>
<translation id="4372948949327679948">Ett <ph name="VALUE_TYPE" />-värde förväntades.</translation>
+<translation id="4377125064752653719">Du försökte öppna <ph name="DOMAIN" />, men servern visade ett certifikat som har återkallats av utfärdaren. Det innebär att säkerhetsuppgifterna som servern visar inte är absolut tillförlitliga. Du kanske kommunicerar med en skadlig server.</translation>
<translation id="4381091992796011497">Användarnamn:</translation>
<translation id="4394049700291259645">Inaktivera</translation>
<translation id="4406896451731180161">sökresultat</translation>
+<translation id="4424024547088906515">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom Chrome inte litar på dess säkerhetscertifikat. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> godkände inte inloggningscertifikatet eller så har inget inloggningscertifikat angetts.</translation>
<translation id="443673843213245140">Användning av proxy är inaktiverad men en explicit proxykonfiguration har angetts.</translation>
-<translation id="4492190037599258964">Sökresultat för "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Valideringsfel: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">kontakta systemadministratören</translation>
<translation id="450710068430902550">Delad med en administratör</translation>
<translation id="4515275063822566619">Kort och adresser har hämtats från Chrome och ditt Google-konto (<ph name="ACCOUNT_EMAIL" />). Du hanterar dessa under <ph name="BEGIN_LINK" />Inställningar<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Info</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Testa att inaktivera tilläggen.</translation>
<translation id="457875822857220463">Leverans</translation>
<translation id="4587425331216688090">Vill du ta bort adressen från Chrome?</translation>
-<translation id="4589078953350245614">Du försökte öppna <ph name="DOMAIN" />, men servern angav ett ogiltigt certifikat. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Anslutningen till <ph name="DOMAIN" /> är krypterad med en modern krypteringssvit.</translation>
<translation id="4594403342090139922">&amp;Ã…ngra Ta bort</translation>
<translation id="4619615317237390068">Flikar från andra enheter</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat innehåller fel. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
+<translation id="4690462567478992370">Sluta använda ett ogiltigt certifikat</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Anslutningen avbröts</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" /> köra nätverksdiagnostik för Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Ett okänt fel uppstod.</translation>
<translation id="4800132727771399293">Kontrollera utgångsdatum och CVC-kod och försök igen</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Du kan inte besöka <ph name="SITE" /> just nu eftersom webbplatsen skickade krypterade användaruppgifter som Chromium inte kan bearbeta. Nätverksfel och attacker är ofta tillfälliga, så sidan fungerar förmodligen senare.</translation>
<translation id="4813512666221746211">Nätverksfel</translation>
<translation id="4816492930507672669">Anpassa till sida</translation>
<translation id="483020001682031208">Det finns inga Physical Web-sidor att visa</translation>
<translation id="4850886885716139402">Visa</translation>
<translation id="4854362297993841467">Det här leveranssättet är inte tillgängligt. Testa ett annat alternativ.</translation>
<translation id="4858792381671956233">Du har frågat dina föräldrar om lov att besöka den här webbplatsen.</translation>
+<translation id="4863764087567530506">Sidan kan ha till syfte att försöka lura dig att installera programvara eller avslöja personlig information. <ph name="BEGIN_LINK" />Visa ändå<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Sök i historiken</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{och en till webbsida}other{och # till webbsidor}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Sidan har översatts från ett okänt språk till <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Betalning</translation>
<translation id="4926049483395192435">Värdet måste anges.</translation>
<translation id="495170559598752135">Åtgärder</translation>
<translation id="4958444002117714549">Expandera lista</translation>
-<translation id="4962322354953122629">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom Chrome inte litar på dess säkerhetscertifikat. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Aktivera varningar igen</translation>
<translation id="4989809363548539747">Det här pluginprogrammet stöds inte</translation>
<translation id="5002932099480077015">Om alternativet är aktiverat sparar Chrome en kopia av kortet på enheten så att det går snabbare att fylla i formulär.</translation>
<translation id="5018422839182700155">Det går inte att öppna den här sidan</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Kontrollera administratörsprinciperna</translation>
<translation id="5029568752722684782">Ta bort kopia</translation>
<translation id="5031870354684148875">Om Google Översätt</translation>
+<translation id="5039804452771397117">Tillåt</translation>
<translation id="5040262127954254034">Sekretess</translation>
<translation id="5045550434625856497">Felaktigt lösenord</translation>
<translation id="5056549851600133418">Artiklar för dig</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />kontrollera proxyadressen<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Inga cookies}=1{Cookies används på 1 webbplats. }other{Cookies används på # webbplatser. }}</translation>
<translation id="5087286274860437796">Servercertifikatet är inte giltigt för närvarande.</translation>
<translation id="5087580092889165836">Lägg till kort</translation>
<translation id="5089810972385038852">Delstat</translation>
+<translation id="5094747076828555589">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom Chromium inte litar på dess säkerhetscertifikat. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
<translation id="5095208057601539847">Provins</translation>
<translation id="5115563688576182185">(64 bitar)</translation>
<translation id="5141240743006678641">Kryptera synkroniserade lösenord med dina inloggningsuppgifter för Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-postadress måste anges</translation>
<translation id="5251803541071282808">Moln</translation>
<translation id="5277279256032773186">Använder du Chrome på jobbet? Företag kan hantera de anställdas inställningar i Chrome. Läs mer</translation>
+<translation id="5297526204711817721">Din anslutning till webbplatsen är inte privat. Du kan när som helst avsluta VR-läget genom att ta av headsetet och trycka på bakåt.</translation>
<translation id="5299298092464848405">Det uppstod ett fel när policyn analyserades</translation>
-<translation id="5300589172476337783">Visa</translation>
<translation id="5308689395849655368">Krashrapportering har inaktiverats.</translation>
<translation id="5317780077021120954">Spara</translation>
<translation id="5327248766486351172">Namn</translation>
-<translation id="5337705430875057403">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan lura dig att göra något farligt, till exempel installera program eller lämna ut din personliga information (som lösenord, telefonnummer eller kreditkortsuppgifter).</translation>
-<translation id="5359637492792381994">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" />. Dess säkerhetscertifikat är inte giltigt för närvarande. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Det går inte att besöka <ph name="SITE" /> just nu eftersom dess certifikat har återkallats. Nätverksfel och attacker är ofta tillfälliga, så sidan kommer förmodligen att fungera senare.</translation>
<translation id="536296301121032821">Det gick inte att spara policyinställningarna</translation>
<translation id="5386426401304769735">Certifikatkedjan för den här webbplatsen innehåller ett certifikat som signerades med SHA-1.</translation>
<translation id="5402410679244714488">Giltigt till: <ph name="EXPIRATION_DATE_ABBR" />, användes senast för över ett år sedan</translation>
+<translation id="540969355065856584">Servern kunde inte bevisa att det är <ph name="DOMAIN" />. Dess säkerhetscertifikat är inte giltigt för närvarande. Detta kan bero på en felaktig konfiguration eller att någon kapat din anslutning.</translation>
<translation id="5421136146218899937">Ta bort webbinformation...</translation>
<translation id="5430298929874300616">Ta bort bokmärke</translation>
<translation id="5431657950005405462">Filen hittades inte</translation>
-<translation id="5435775191620395718">Historik från den här enheten visas. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Schemavalideringsfel i <ph name="ERROR_PATH" />: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Sidan på <ph name="HOST_NAME" /> kan inte hittas</translation>
<translation id="5455374756549232013">Felaktig tidsstämpel för policy</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> av <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Ogiltigt</translation>
<translation id="5470861586879999274">&amp;Gör om Redigera</translation>
<translation id="54817484435770891">Lägg till giltig adress</translation>
<translation id="5492298309214877701">Webbplatsen på företagets, organisationens eller skolans intranät har samma webbadress som en extern webbplats.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Utlämning erbjuds inte på den här adressen. Välj en annan adress.</translation>
<translation id="5572851009514199876">Logga in på Chrome så att Chrome kan kontrollera om du har tillgång till den här webbplatsen.</translation>
<translation id="5580958916614886209">Kontrollera utgångsmånad och försök igen</translation>
+<translation id="5586446728396275693">Inga sparade adresser</translation>
+<translation id="5595485650161345191">Redigera adress</translation>
<translation id="560412284261940334">Hantering stöds inte</translation>
<translation id="5610142619324316209">kontrollera anslutningen</translation>
<translation id="5610807607761827392">Du hanterar kort och adresser under <ph name="BEGIN_LINK" />Inställningar<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Vill du lämna den här webbplatsen?</translation>
<translation id="5629630648637658800">Det gick inte att läsa in policyinställningarna</translation>
<translation id="5631439013527180824">Ogiltig enhetshanteringstoken</translation>
+<translation id="5633066919399395251">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan försöka installera skadliga program som stjäl eller raderar information (t.ex. foton, lösenord, meddelanden och kreditkortsuppgifter) på datorn. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Plats</translation>
+<translation id="5659593005791499971">E-post</translation>
<translation id="5669703222995421982">Få anpassat innehåll</translation>
<translation id="5675650730144413517">Sidan fungerar inte</translation>
-<translation id="5677928146339483299">Blockerad</translation>
-<translation id="5694783966845939798">Du försökte öppna <ph name="DOMAIN" />, men servern angav ett certifikat som har signerats med en svag signaturalgoritm (till exempel SHA-1). Det innebär att säkerhetsuppgifterna som servern anger kan vara en förfalskning och att servern kanske inte är den server du tror (du kanske kommunicerar med en angripare). <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Webbplatsens identitet har inte verifierats.</translation>
+<translation id="5713016350996637505">Bedrägligt innehåll har blockerats</translation>
<translation id="5720705177508910913">Aktuell användare</translation>
<translation id="5732392974455271431">Dina föräldrar kan ta bort blockeringen</translation>
<translation id="5763042198335101085">Ange en giltig e-postadress</translation>
<translation id="5765072501007116331">Välj en adress för att visa leveranssätt och krav</translation>
+<translation id="5778550464785688721">MIDI-enheter – fullständig kontroll</translation>
<translation id="5784606427469807560">Det gick inte att bekräfta kortet. Kontrollera internetanslutningen och försök igen.</translation>
<translation id="5785756445106461925">Den här sidan innehåller emellertid andra resurser som inte är säkra. Andra kan se resurserna när de överförs och hackare kan ändra resurserna så att sidan får ett annat utseende.</translation>
<translation id="5786044859038896871">Vill du att kortuppgifterna ska fyllas i?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Gör om Lägg till</translation>
<translation id="5814352347845180253">Du kan förlora tillgång till premiuminnehåll från <ph name="SITE" /> och några andra webbplatser.</translation>
<translation id="5838278095973806738">Du bör inte ange några känsliga uppgifter på den här webbplatsen (till exempel lösenord eller kreditkortsuppgifter) eftersom hackare kan stjäla dem.</translation>
-<translation id="5843436854350372569">Du försökte öppna <ph name="DOMAIN" />, men servern angav ett certifikat som signerats med en svag nyckel. Det innebär att den privata nyckeln som servern anger kan vara en förfalskning och att servern kanske inte är den server du tror (du kanske kommunicerar med en angripare). <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Webbplatsen kan inte nås</translation>
<translation id="5869522115854928033">Sparade lösenord</translation>
<translation id="5872918882028971132">Föräldratips</translation>
<translation id="5901630391730855834">Gul</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (synkroniserade)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 används}other{# används}}</translation>
<translation id="5926846154125914413">Du kan förlora tillgång till premiuminnehåll från vissa webbplatser.</translation>
<translation id="5959728338436674663">Skicka automatiskt viss <ph name="BEGIN_WHITEPAPER_LINK" />information om systemet och innehåll på sidan<ph name="END_WHITEPAPER_LINK" /> för att hjälpa Google att identifiera skadliga appar och webbplatser. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Vecka</translation>
<translation id="5967867314010545767">Ta bort från historiken</translation>
<translation id="5975083100439434680">Zooma ut</translation>
<translation id="598637245381783098">Det gick inte att öppna betalningsappen</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Sida 1}other{Sida #}}</translation>
<translation id="6017514345406065928">Grön</translation>
+<translation id="6017850046339264347">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> skulle kunna installera bedrägliga appar som inte gör vad de påstås göra eller samla in data som används för att spåra dig. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (synkroniserade)</translation>
<translation id="6027201098523975773">Ange ett namn</translation>
<translation id="6040143037577758943">Stäng</translation>
<translation id="6042308850641462728">Mer</translation>
+<translation id="6047233362582046994">Om du är medveten om säkerhetsriskerna kan du <ph name="BEGIN_LINK" />besöka webbplatsen<ph name="END_LINK" /> innan de skadliga apparna har tagits bort.</translation>
+<translation id="6051221802930200923">Du kan inte besöka <ph name="SITE" /> just nu eftersom tekniken att fästa certifikat används på webbplatsen. Nätverksfel och attacker är ofta tillfälliga, så sidan kommer förmodligen att fungera senare.</translation>
<translation id="6060685159320643512">Försiktigt, experimenten kan vara skadliga</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{inga}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Du har visat innehåll med hjälp av ett certifikat från en administratör. Det innebär att data som du har angett på <ph name="DOMAIN" /> även kan visas av administratören.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ingen}=1{1 lösenord (synkroniserat)}other{# lösenord (synkroniserade)}}</translation>
<translation id="6146055958333702838">Kontrollera kablar och starta om routrar, modem och andra nätverksenheter
som används.</translation>
<translation id="614940544461990577">Testa att</translation>
<translation id="6151417162996330722">Servercertifikatet har för lång giltighetstid.</translation>
<translation id="6157877588268064908">Välj en adress för att visa fraktalternativ och krav</translation>
+<translation id="6158003235852588289">Google Säker webbsökning upptäckte nyligen nätfiske på <ph name="SITE" />. Webbplatser för nätfiske utger sig för att vara andra webbplatser i syfte att lura dig.</translation>
<translation id="6165508094623778733">Läs mer</translation>
+<translation id="6169916984152623906">Nu kan du surfa privat. Din aktivitet visas inte för andra som använder enheten, men nedladdningar och bokmärken sparas.</translation>
<translation id="6177128806592000436">Anslutningen till webbplatsen är inte säker</translation>
<translation id="6184817833369986695">(kohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Kontrollera internetanslutningen</translation>
<translation id="6218753634732582820">Vill du ta bort adressen från Chromium?</translation>
+<translation id="6221345481584921695">Google Säker webbsökning upptäckte nyligen <ph name="BEGIN_LINK" />skadlig programvara<ph name="END_LINK" /> på <ph name="SITE" />. Webbplatser som vanligtvis är säkra utsätts ibland för skadlig programvara. Det skadliga innehållet kommer från <ph name="SUBRESOURCE_HOST" />, som är en känd distributör av skadlig programvara.</translation>
<translation id="6251924700383757765">Sekretesspolicy</translation>
<translation id="6254436959401408446">Det finns inte tillräckligt med minne för att öppna den här sidan</translation>
<translation id="625755898061068298">Du har valt att inaktivera säkerhetsvarningar för den här webbplatsen.</translation>
@@ -573,7 +641,7 @@
<translation id="6321917430147971392">Kontrollera DNS-inställningarna</translation>
<translation id="6328639280570009161">Prova att inaktivera nätverksförslag</translation>
<translation id="6328786501058569169">Den här webbplatsen är bedräglig</translation>
-<translation id="6337534724793800597">Filtrera policy efter namn</translation>
+<translation id="6337534724793800597">Filtrera princip efter namn</translation>
<translation id="6342069812937806050">Alldeles nyss</translation>
<translation id="6355080345576803305">Åsidosätt offentlig session</translation>
<translation id="6358450015545214790">Vad innebär dessa?</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Redigera bokmärke</translation>
<translation id="6410264514553301377">Ange utgångsdatum och CVC-kod för <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Du har frågat en förälder om lov att besöka den här webbplatsen.</translation>
-<translation id="6416403317709441254">Det går inte att besöka <ph name="SITE" /> just nu eftersom webbplatsen skickade förvrängda användaruppgifter som Chromium inte kan behandla. Nätverksfel och attacker är vanligtvis tillfälliga, så sidan fungerar troligen senare. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Det gick inte att kontrollera om certifikatet har återkallats.</translation>
<translation id="6433490469411711332">Redigera kontaktuppgifter</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> avvisade anslutningen.</translation>
<translation id="6446608382365791566">Lägg till mer information</translation>
+<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Bekräfta återsändning av formulär</translation>
<translation id="6456339708790392414">Din betalning</translation>
-<translation id="6458467102616083041">Ignoreras eftersom standardsökmotorn är inaktiverad av en policy.</translation>
-<translation id="6462969404041126431">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat kan ha återkallats. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen. <ph name="BEGIN_LEARN_MORE_LINK" />Lär mer<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="6458467102616083041">Ignoreras eftersom standardsökmotorn är inaktiverad av en princip.</translation>
<translation id="647261751007945333">Enhetspolicyer</translation>
<translation id="6477321094435799029">Chrome har identifierat ovanlig kod på sidan och blockerat den för att skydda dina personliga uppgifter (som lösenord, telefonnummer och kreditkortsuppgifter).</translation>
<translation id="6489534406876378309">Börja överföra information om krascher</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Giltigt till: <ph name="EXPIRATION_DATE_ABBR" />, användes senast den <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Den ansvarige har inte godkänt den ännu</translation>
<translation id="6569060085658103619">Du visar en tilläggssida</translation>
-<translation id="6593753688552673085">mindre än <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Sidan kan ha till syfte att installera farlig programvara som stjäl eller raderar information på enheten. <ph name="BEGIN_LINK" />Visa ändå<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Krypteringsalternativ</translation>
<translation id="662080504995468778">Stanna kvar</translation>
<translation id="6626291197371920147">Lägg till ett giltigt kortnummer</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Sök</translation>
+<translation id="6630809736994426279">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan försöka installera skadliga program som stjäl eller raderar information (t.ex. foton, lösenord, meddelanden och kreditkortsuppgifter) på din Mac. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Policyn är föråldrad.</translation>
-<translation id="6652240803263749613">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom datorns operativsystem inte litar på dess säkerhetscertifikat. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Vill du ta bort formulärförslaget från Chromium?</translation>
<translation id="6685834062052613830">Logga ut och slutför konfigureringen</translation>
<translation id="6710213216561001401">Föregående</translation>
<translation id="6710594484020273272">&lt;Ange sökterm&gt;</translation>
<translation id="6711464428925977395">Något är fel med proxyservern eller så är adressen felaktig.</translation>
<translation id="6727102863431372879">Ange</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{inga}=1{1 objekt}other{# objekt}}</translation>
<translation id="674375294223700098">Fel - okänt servercertifikat.</translation>
<translation id="6753269504797312559">Policyvärde</translation>
<translation id="6757797048963528358">Enheten gick i viloläge.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Anpassnings-id</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Det gick inte att läsa in regionsuppgifter</translation>
+<translation id="6825578344716086703">Du försökte besöka <ph name="DOMAIN" />, men servern skickade ett certifikat som signerats med en svag signaturalgoritm (t.ex. SHA-1). Det innebär att säkerhetsuppgifterna som servern uppgav kan vara förfalskade och att servern kanske inte är den server du tror (du kanske kommunicerar med en skadlig server).</translation>
+<translation id="6830728435402077660">Inte säkert</translation>
<translation id="6831043979455480757">Översätt</translation>
<translation id="6839929833149231406">Huvudområde</translation>
<translation id="6874604403660855544">&amp;Gör om Lägg till</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Kortet har bekräftats</translation>
<translation id="6897140037006041989">Användaragent</translation>
<translation id="6915804003454593391">Användare:</translation>
+<translation id="6945221475159498467">Välj</translation>
<translation id="6948701128805548767">Välj en adress för att visa alternativ för utlämning och krav</translation>
<translation id="6957887021205513506">Serverns certifikat verkar vara falskt.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Både fasta proxyservrar och en webbadress för PAC-skript anges.</translation>
<translation id="6989763994942163495">Visa avancerade inställningar ...</translation>
<translation id="7000990526846637657">Inga historikposter hittades</translation>
-<translation id="7009986207543992532">Du försökte öppna <ph name="DOMAIN" />, men servern angav ett certifikat vars giltighetstid är för lång för att det ska vara trovärdigt. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Andra former av webbhistorik för Google-kontot kan finnas på <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Lösenord</translation>
+<translation id="7050187094878475250">Du försökte nå <ph name="DOMAIN" />, men servern svarade med ett certifikat vars giltighetstid är för lång för att det ska vara trovärdigt.</translation>
+<translation id="7053983685419859001">Blockera</translation>
<translation id="7064851114919012435">Kontaktuppgifter</translation>
<translation id="7079718277001814089">Webbplatsen innehåller skadlig programvara.</translation>
<translation id="7087282848513945231">Grevskap</translation>
-<translation id="7088615885725309056">Äldre</translation>
<translation id="7090678807593890770">Sök efter <ph name="LINK" /> på Google</translation>
+<translation id="7108819624672055576">Beviljades av ett tillägg</translation>
<translation id="7119414471315195487">Stäng andra flikar eller program</translation>
<translation id="7129409597930077180">Det går inte att skicka till den här adressen. Välj en annan adress.</translation>
<translation id="7138472120740807366">Leveranssätt</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Bearbetning pågår</translation>
<translation id="724691107663265825">Det förekommer skadlig programvara på följande sida</translation>
<translation id="724975217298816891">Ange utgångsdatum och CVC-kod för <ph name="CREDIT_CARD" /> om du vill uppdatera kortinformationen. När du bekräftar delas kortinformationen med den här webbplatsen.</translation>
-<translation id="725866823122871198">Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom datorns datum och tid (<ph name="DATE_AND_TIME" />) inte stämmer.</translation>
+<translation id="7260504762447901703">Återkalla åtkomst</translation>
<translation id="7275334191706090484">Hanterade bokmärken</translation>
<translation id="7298195798382681320">Rekommenderas</translation>
<translation id="7309308571273880165">Felrapport som skapades <ph name="CRASH_TIME" /> (uppladdning begärdes av användaren, har ännu inte laddats upp)</translation>
<translation id="7334320624316649418">&amp;Gör om Ändra ordning</translation>
<translation id="733923710415886693">Servercertifikatet har inte lämnats ut via Certifikattransparens.</translation>
-<translation id="7351800657706554155">Det går inte att besöka <ph name="SITE" /> just nu på grund av att det här certifikatet har återkallats. Nätverksfel och attacker är vanligtvis tillfälliga så sidan fungerar troligen senare. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Kommandorad</translation>
<translation id="7372973238305370288">sökresultat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nej</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Bekräfta kort</translation>
-<translation id="7394102162464064926">Vill du ta bort dessa sidor från historiken?
-
-Psst! Nästa gång kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara något.</translation>
<translation id="7400418766976504921">Webbadress</translation>
<translation id="7419106976560586862">Profilsökväg</translation>
<translation id="7424977062513257142">På en inbäddad sida på den här webbplatsen står det:</translation>
@@ -688,6 +754,7 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="7444046173054089907">Webbplatsen är blockerad</translation>
<translation id="7445762425076701745">Det går inte att fastställa identiteten hos servern som du är ansluten till. Servernamnet som du angav vid anslutningen är bara giltigt inom ditt nätverk och externa certifikatutfärdare kan inte fastställa dess ägarskap. Vissa certifikatutfärdare utfärdar certifikat oavsett namn och därför går det inte att säkerställa att du är ansluten till den avsedda webbplatsen och inte till en skadlig server.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />att läsa mer<ph name="END_LINK" /> om det här problemet.</translation>
+<translation id="7455133967321480974">Använd global standardinställning (Blockera)</translation>
<translation id="7460163899615895653">De senaste flikarna från andra enheter visas här</translation>
<translation id="7469372306589899959">Kortet bekräftas</translation>
<translation id="7481312909269577407">Framåt</translation>
@@ -695,36 +762,43 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="7508255263130623398">Enhets-id för returnerad princip är tomt eller matchar inte nuvarande enhets-id</translation>
<translation id="7514365320538308">Ladda ned</translation>
<translation id="7518003948725431193">Det fanns ingen webbsida på webbadressen: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Värde</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
+<translation id="7542403920425041731">När du bekräftar delas kortuppgifterna med den här webbplatsen.</translation>
<translation id="7542995811387359312">Automatisk ifyllning av kreditkort har inaktiverats eftersom formulärets anslutning inte är säker.</translation>
<translation id="7543525346216957623">Fråga en förälder</translation>
<translation id="7549584377607005141">Den här webbsidan kräver uppgifter som du har angett tidigare för att kunna visas korrekt. Du kan skicka uppgifterna igen, men om du gör det upprepas de åtgärder som har utförts av sidan tidigare.</translation>
<translation id="7552846755917812628">Testa följande tips:</translation>
<translation id="7554791636758816595">Ny flik</translation>
+<translation id="7567204685887185387">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom dess säkerhetscertifikat kan ha utfärdats utan behörighet. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> till}other{<ph name="CONTACT_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> till}}</translation>
<translation id="7568593326407688803">Den här sidan är på<ph name="ORIGINAL_LANGUAGE" />Vill du översätta den?</translation>
<translation id="7569952961197462199">Vill du ta bort kreditkortet från Chrome?</translation>
<translation id="7569983096843329377">Svart</translation>
<translation id="7578104083680115302">Betala snabbt på webbplatser och i appar på olika enheter med kort som du har sparat hos Google.</translation>
<translation id="7588950540487816470">Physical Web</translation>
<translation id="7592362899630581445">Serverns certifikat strider mot namnrestriktionerna.</translation>
+<translation id="7598391785903975535">Mindre än <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> kan för närvarande inte hantera förfrågan.</translation>
<translation id="7600965453749440009">Översätt aldrig från <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Värdet är utanför intervallet <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Upphör: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Du har redan data som krypteras med en annan version av ditt lösenord till Google-kontot. Ange det nedan.</translation>
-<translation id="7634554953375732414">Din anslutning till webbplatsen är inte privat.</translation>
<translation id="7637571805876720304">Vill du ta bort kreditkortet från Chromium?</translation>
<translation id="765676359832457558">Dölj avancerade inställningar ...</translation>
<translation id="7658239707568436148">Avbryt</translation>
+<translation id="7662298039739062396">Inställningen styrs av ett tillägg</translation>
<translation id="7667346355482952095">Policytoken som returnerades är tom eller matchade inte den aktuella token</translation>
<translation id="7668654391829183341">Okänd enhet</translation>
<translation id="7669271284792375604">Angripare på den här webbplatsen kan försöka lura dig att installera program som skadar din webbupplevelse (till exempel genom att byta ut din startsida eller visa extra annonser på webbplatser som du besöker).</translation>
<translation id="7674629440242451245">Är du intresserad av häftiga nya funktioner i Chrome? Pröva vår utvecklarkanal på chrome.com/dev.</translation>
<translation id="7682287625158474539">Frakt</translation>
+<translation id="7701040980221191251">Inget</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Fortsätt till <ph name="SITE" /> (osäkert)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Certifikat</translation>
+<translation id="7716147886133743102">Blockerades av administratören</translation>
<translation id="7716424297397655342">Det går inte att läsa in webbplatsen från cachelagringen</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Hanteras inte</translation>
<translation id="7755287808199759310">En förälder kan ta bort blockeringen</translation>
<translation id="7758069387465995638">Anslutningen kan ha blockerats av en brandvägg eller antivirusprogram.</translation>
@@ -751,15 +825,15 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="7951415247503192394">(32 bitar)</translation>
<translation id="7956713633345437162">Bokmärken i mobilen</translation>
<translation id="7961015016161918242">Aldrig</translation>
-<translation id="7962083544045318153">Krasch-id <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Översätt alltid <ph name="ORIGINAL_LANGUAGE" /> till <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Inte specificerad</translation>
<translation id="800218591365569300">Testa att stänga andra flikar eller program för att frigöra minne.</translation>
<translation id="8012647001091218357">Vi kunde inte nå dina föräldrar just nu. Försök igen.</translation>
<translation id="8025119109950072390">Angripare på den här webbplatsen kan lura dig att göra något farligt, till exempel installera programvara eller lämna ut personliga uppgifter (som lösenord, telefonnummer eller kreditkortsuppgifter).</translation>
-<translation id="803030522067524905">Googles tjänst Säker webbsökning upptäckte nyligen nätfiske på <ph name="SITE" />. Webbplatser för nätfiske utger sig för att vara andra webbplatser i syfte att lura dig. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Den här sidan är skriven på <ph name="SOURCE_LANGUAGE" />. Vill du översätta den till <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Fråga (standard)</translation>
<translation id="8041089156583427627">Skicka feedback</translation>
+<translation id="8041940743680923270">Använd global standardinställning (Fråga)</translation>
<translation id="8088680233425245692">Det gick inte att visa artikeln.</translation>
<translation id="8089520772729574115">mindre än 1 MB</translation>
<translation id="8091372947890762290">Aktiveringen väntar på servern</translation>
@@ -768,13 +842,14 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="8134994873729925007">Det gick inte att hitta <ph name="BEGIN_ABBR" />DNS-adressen<ph name="END_ABBR" /> till servern för <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Datorn gick i viloläge.</translation>
<translation id="8150722005171944719">Det går inte att läsa filen på <ph name="URL" />. Den kan ha tagits bort eller flyttats, eller så krävs behörighet för att få åtkomst till den.</translation>
+<translation id="8184538546369750125">Använd global standardinställning (Tillåt)</translation>
+<translation id="8191494405820426728">Lokalt krasch-id <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Ã…ngra Flytta</translation>
<translation id="8201077131113104583">Ogiltig webbadress för uppdatering för tillägg med id <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Beställningsöversikt</translation>
<translation id="8218327578424803826">Tilldelad plats:</translation>
<translation id="8225771182978767009">Personen som konfigurerade datorn har valt att blockera den här webbplatsen.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Det kan hända att angripare som för närvarande finns på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> försöker installera skadliga program på datorn som stjäl eller raderar dina uppgifter (t.ex. foton, lösenord, meddelanden och kreditkort).</translation>
<translation id="8241707690549784388">Önskad sida använder information som du har angett. Om du återgår till sidan kan eventuella åtgärder på sidan upprepas. Vill du fortsätta?</translation>
<translation id="8249320324621329438">Senast hämtad:</translation>
<translation id="8253091569723639551">En faktureringsadress måste anges</translation>
@@ -782,6 +857,7 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="8289355894181816810">Kontakta din nätverksadministratör om du är osäker på vad det här innebär.</translation>
<translation id="8293206222192510085">Lägg till bokmärke</translation>
<translation id="8294431847097064396">Källa</translation>
+<translation id="8306404619377842860">Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom datum och tid på enheten (<ph name="DATE_AND_TIME" />) inte stämmer. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Det gick inte att översätta på grund av ett nätverksfel.</translation>
<translation id="8332188693563227489">Ã…tkomst nekades till <ph name="HOST_NAME" />.</translation>
<translation id="834457929814110454">Om du är medveten om säkerhetsriskerna kan du <ph name="BEGIN_LINK" />besöka den här osäkra webbplatsen<ph name="END_LINK" /> innan de skadliga programmen har tagits bort.</translation>
@@ -802,11 +878,9 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="8483780878231876732">Logga in i Chrome om du vill använda kort i Google-kontot</translation>
<translation id="8488350697529856933">Gäller för</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> tog för lång tid på sig att svara.</translation>
-<translation id="852346902619691059">Det gick inte att bevisa att serverns identitet är <ph name="DOMAIN" /> eftersom datorns operativsystem inte litar på dess säkerhetscertifikat. Det kan bero på att servern är felkonfigurerad eller att anslutningen har blivit kapad. <ph name="BEGIN_LEARN_MORE_LINK" />Läs mer<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Sista giltighetsår</translation>
<translation id="8543181531796978784">Du kan <ph name="BEGIN_ERROR_LINK" />rapportera ett identifieringsproblem<ph name="END_ERROR_LINK" /> eller <ph name="BEGIN_LINK" />besöka den här osäkra webbplatsen<ph name="END_LINK" /> om du är medveten om säkerhetsriskerna.</translation>
<translation id="8553075262323480129">Det gick inte att översätta eftersom det inte gick att avgöra vilket språk som användes på sidan.</translation>
-<translation id="8559762987265718583">Det gick inte att upprätta en privat anslutning till <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> eftersom enhetens datum och tid (<ph name="DATE_AND_TIME" />) inte stämmer.</translation>
<translation id="8571890674111243710">Översätter sidan till <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Ange telefonnr
</translation>
@@ -821,6 +895,7 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="8738058698779197622">Om du vill upprätta en säker anslutning måste klockan vara rätt inställd. Det beror på att certifikaten som webbplatserna använder för att identifiera sig endast är giltiga under vissa tidsperioder. Chromium kan inte verifiera certifikaten eftersom klockan på enheten inte stämmer.</translation>
<translation id="8740359287975076522">Det gick inte att hitta <ph name="HOST_NAME" />s &lt;abbr id="dnsDefinition"&gt;DNS-adress&lt;/abbr&gt;. Diagnostiserar problemet.</translation>
<translation id="8759274551635299824">Kortets giltighetstid har löpt ut</translation>
+<translation id="8761567432415473239">Googles tjänst Säker webbsökning <ph name="BEGIN_LINK" />hittade skadliga program<ph name="END_LINK" /> på <ph name="SITE" /> nyligen.</translation>
<translation id="8790007591277257123">&amp;Gör om Ta bort</translation>
<translation id="8800988563907321413">Förslag på webbsidor i närheten visas här</translation>
<translation id="8820817407110198400">Bokmärken</translation>
@@ -833,29 +908,30 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="8870413625673593573">Nyligen stängda</translation>
<translation id="8874824191258364635">Ange ett giltigt kortnummer</translation>
<translation id="8876793034577346603">Det gick inte att tolka nätverkskonfigurationen.</translation>
-<translation id="8877192140621905067">När du bekräftar delas kortinformationen med den här webbplatsen</translation>
<translation id="8889402386540077796">Nyans</translation>
<translation id="8891727572606052622">Ogiltigt proxyläge.</translation>
<translation id="889901481107108152">Experimentet finns tyvärr inte på din plattform.</translation>
<translation id="8903921497873541725">Zooma in</translation>
<translation id="8931333241327730545">Vill du spara det här kortet i ditt Google-konto?</translation>
<translation id="8932102934695377596">Klockan går efter</translation>
-<translation id="8954894007019320973">(forts)</translation>
<translation id="8971063699422889582">Servercertifikatet har gått ut.</translation>
<translation id="8986494364107987395">Skicka användningsstatistik och kraschrapporter till Google automatiskt</translation>
-<translation id="8987927404178983737">MÃ¥nad</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Webbplatsen som öppnas innehåller skadliga program</translation>
+<translation id="8997023839087525404">Servern visade ett certifikat som inte lämnats ut via principen Certifikattransparens. Detta är ett krav för vissa certifikat för att säkerställa att de är pålitliga och skyddar mot hackare.</translation>
<translation id="9001074447101275817">Proxyservern <ph name="DOMAIN" /> kräver användarnamn och lösenord.</translation>
+<translation id="9005998258318286617">Det gick inte att läsa in PDF-dokumentet.</translation>
<translation id="901974403500617787">Flaggor som gäller hela systemet kan endast ställas in av ägaren: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Kortets faktureringsadress måste anges</translation>
<translation id="9020542370529661692">Den här sidan har översatts till <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Säkerhetsfel</translation>
<translation id="9038649477754266430">Använd en förslagstjänst om du vill läsa in sidor snabbare</translation>
<translation id="9039213469156557790">Den här sidan innehåller emellertid andra resurser som inte är säkra. Andra kan se resurserna när de överförs och hackare kan ändra resurserna så att sidan får ett annat beteende.</translation>
-<translation id="9040185888511745258">Angripare på <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kan försöka lura dig att installera program som skadar din webbupplevelse (till exempel genom att byta ut din startsida eller visa extra annonser på webbplatser som du besöker).</translation>
+<translation id="9049981332609050619">Du försökte nå <ph name="DOMAIN" /> men servern angav ett ogiltigt certifikat.</translation>
<translation id="9050666287014529139">Lösenfras</translation>
<translation id="9065203028668620118">Redigera</translation>
<translation id="9068849894565669697">Välj färg</translation>
+<translation id="9069693763241529744">Blockerades av ett tillägg</translation>
<translation id="9076283476770535406">Den kan innehålla barnförbjudet innehåll</translation>
<translation id="9078964945751709336">Mer information krävs</translation>
<translation id="9103872766612412690">På <ph name="SITE" /> används normalt kryptering (SSL) för att skydda din information. När Chromium försökte ansluta till <ph name="SITE" /> den här gången skickade webbplatsen tillbaka ovanliga och felaktiga uppgifter. Sådant kan hända när en angripare utger sig för att vara <ph name="SITE" /> eller när anslutningen har avbrutits av en Wi-Fi-inloggningsskärm. Din information är fortfarande säker eftersom Chromium avbröt anslutningen innan någon data utbyttes.</translation>
@@ -864,16 +940,21 @@ Psst! Nästa gÃ¥ng kanske inkognitoläget <ph name="SHORTCUT_KEY" /> kan vara nÃ
<translation id="9148507642005240123">&amp;Ã…ngra Redigera</translation>
<translation id="9154194610265714752">Uppdaterat</translation>
<translation id="9157595877708044936">Konfigurerar...</translation>
+<translation id="9169664750068251925">Blockera alltid den här webbplatsen</translation>
<translation id="9170848237812810038">&amp;Ã…ngra</translation>
<translation id="917450738466192189">Servercertifikatet är ogiltigt.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> till}other{<ph name="SHIPPING_OPTION_PREVIEW" /> och <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> till}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> använder ett protokoll som inte stöds.</translation>
<translation id="9205078245616868884">Din data har krypterats med din lösenfras för synkronisering. Ange den om du vill starta synkroniseringen.</translation>
<translation id="9207861905230894330">Det gick inte att lägga till artikeln.</translation>
+<translation id="9219103736887031265">Bilder</translation>
<translation id="933612690413056017">Det finns ingen internetanslutning</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">RENSA FORMULÄRET</translation>
<translation id="939736085109172342">Ny mapp</translation>
<translation id="941721044073577244">Du har tyvärr inte behörighet att besöka den här webbplatsen.</translation>
<translation id="969892804517981540">Officiell version</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ingen}=1{1 objekt}other{# objekt}}</translation>
<translation id="988159990683914416">Utvecklarversion</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_sw.xtb b/chromium/components/strings/components_strings_sw.xtb
index f0b4fcc16a4..c4ee1c80c08 100644
--- a/chromium/components/strings/components_strings_sw.xtb
+++ b/chromium/components/strings/components_strings_sw.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Zungusha kwenye mwendo wa saa</translation>
<translation id="1038842779957582377">jina lisilojulikana</translation>
<translation id="1050038467049342496">Funga programu nyingine</translation>
-<translation id="1053591932240354961">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti ilituma kitambulisho kilichoharibika ambacho Google Chrome haiwezi kuchakata. Hitilafu na uvamizi wa mtandao kwa kawaida huwa wa muda, kwa hivyo ukurasa huu huenda utafanya kazi baadaye. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">Tendua Kuongeza</translation>
<translation id="10614374240317010">Haijahifadhiwa kamwe</translation>
<translation id="106701514854093668">Alamisho za Eneokazi</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Akiba ya sera ni SAWA</translation>
<translation id="113188000913989374"><ph name="SITE" /> unasema:</translation>
<translation id="1132774398110320017">Mipangilio ya Chrome ya kujaza kiotomatiki...</translation>
+<translation id="1150979032973867961">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na mfumo wa uendeshaji wa kompyuta yako. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
+<translation id="1151972924205500581">Nenosiri linahitajika</translation>
<translation id="1152921474424827756">Fikia <ph name="BEGIN_LINK" />nakala iliyowekwa kwenye akiba<ph name="END_LINK" /> ya <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ilifunga muunganisho bila kutarajia.</translation>
<translation id="1161325031994447685">Kuunganisha tena kwenye Wi-Fi</translation>
+<translation id="1165039591588034296">Hitilafu</translation>
<translation id="1175364870820465910">&amp;Chapisha...</translation>
<translation id="1181037720776840403">Ondoa</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Ripoti kiotomatiki<ph name="END_WHITEPAPER_LINK" /> kwa Google kuhusu maelezo ya uwezekano wa matukio yasiyo salama. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Zaidi kutoka kwenye tovuti hii</translation>
<translation id="1206967143813997005">Sahihi mbaya ya mwanzo</translation>
<translation id="1209206284964581585">Ficha kwa sasa</translation>
+<translation id="121201262018556460">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti kikiwa na ufunguo duni. Huenda mshambulizi alivunja ufunguo wa siri, na huenda seva isiwe seva ulioitarajia (unaweza kuwa unawasiliana na mshambulizi).</translation>
<translation id="1219129156119358924">Usalama wa Mfumo</translation>
<translation id="1227224963052638717">Sera isiyojulikana.</translation>
<translation id="1227633850867390598">Ficha thamani</translation>
<translation id="1228893227497259893">Kitambulisho cha huluki kisicho halali</translation>
<translation id="1232569758102978740">Hakina Jina</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (zimesawazishwa)</translation>
<translation id="1263231323834454256">Orodha ya kusoma</translation>
<translation id="1264126396475825575">Ripoti ya kuacha kufanya kazi iliyochukuliwa <ph name="CRASH_TIME" /> (haijapakiwa au imepuuzwa)</translation>
+<translation id="1281526147609854549">Imetolewa na <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Maudhui hatari yamezuiwa</translation>
<translation id="1285320974508926690">Kamwe usitafsiri tovuti hii</translation>
<translation id="129553762522093515">Vilivyofungwa hivi karibuni</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Jaribu kufuta vidakuzi kwenye kivinjari chako<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Huenda bado shughuli zako <ph name="BEGIN_EMPHASIS" />Zitaonwa<ph name="END_EMPHASIS" /> na:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Tovuti utakazotembelea
+ <ph name="LIST_ITEM" />Mwajiri au shule yako
+ <ph name="LIST_ITEM" />Anayetoa huduma unayotumia ya mtandao
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Kikoa cha kujiandikisha:</translation>
<translation id="1340482604681802745">Anwani ya eneo la kuchukulia</translation>
<translation id="1344211575059133124">Inaonekana unahitaji ruhusa ili uweze kutembelea tovuti hii</translation>
<translation id="1344588688991793829">Mipangilio ya Chromium ya kujaza kiotomatiki...</translation>
+<translation id="1348198688976932919">Kuna programu hasidi kwenye tovuti unayotaka kuifungua</translation>
<translation id="1374468813861204354">mapendekezo</translation>
<translation id="1375198122581997741">Kuhusu Toleo</translation>
<translation id="1377321085342047638">Nambari ya Kadi</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> haikutuma data yoyote.</translation>
<translation id="1407135791313364759">Fungua zote</translation>
<translation id="1413809658975081374">Hitilafu ya faragha</translation>
+<translation id="14171126816530869">Utambulisho wa <ph name="ORGANIZATION" /> iliyo <ph name="LOCALITY" /> umethibitishwa na <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Ndio</translation>
<translation id="1430915738399379752">Chapisha</translation>
-<translation id="1442912890475371290">Imezuia jaribio <ph name="BEGIN_LINK" /> la kutembelea ukurasa kwenye <ph name="DOMAIN" /> <ph name="END_LINK" /> .</translation>
-<translation id="1491663344921578213">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti hutumia ubandikaji vyeti. Hitilafu na uvamizi wa mtandao kwa kawaida huwa wa muda, kwa hivyo ukurasa huu huenda utafanya kazi baadaye.<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Onyesha nakala iliyohifadhiwa (yaani inayojulikana kwisha muda) ya ukurasa huu.</translation>
<translation id="1517433312004943670">Nambari ya simu inahitajika</translation>
<translation id="1519264250979466059">Unda Tarehe</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Lazima JavaScript iwashwe ili utumie kipengele hiki.</translation>
<translation id="1555130319947370107">Samawati</translation>
<translation id="1559528461873125649">Hakuna faili au saraka kama hiyo</translation>
-<translation id="1559572115229829303">&lt;p&gt;Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hauwezi kutambuliwa kwa sababu tarehe na wakati wa kifaa chako <ph name="DATE_AND_TIME" /> si sahihi.&lt;/p&gt;
-
- &lt;p&gt;Tafadhali rekebisha tarehe na wakati kutoka kwenye &lt;strong&gt;sehemu ya Jumla&lt;/strong&gt; ya &lt;strong&gt;programu ya Mipangilio&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Hitilafu ilitokea wakati wa kuonyesha ukurasa huu wa wavuti.</translation>
<translation id="1592005682883173041">Ufikiaji wa Data Iliyo Katika Kifaa Chako</translation>
+<translation id="1594030484168838125">Chagua</translation>
<translation id="161042844686301425">Samawati-Kijani</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Je, unataka Chrome ihifadhi kadi hii?</translation>
<translation id="1639239467298939599">Inapakia</translation>
<translation id="1640180200866533862">Sera za mtumiaji</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Usanidi wa mtandao ni batili na usingeweza kuingizwa.</translation>
<translation id="1644574205037202324">Historia</translation>
<translation id="1645368109819982629">Itifaki haitumiki</translation>
+<translation id="1655462015569774233">{1,plural, =1{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kilikwisha muda jana. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako. Saa ya kompyuta kwa sasa imewekwa kuwa <ph name="CURRENT_DATE" />. Je, hiyo ni sahihi? Ikiwa si sahihi, rekebisha saa ya mfumo wako kisha uonyeshe upya ukurasa huu.}other{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kilikwisha muda siku # zilizopita. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako. Saa ya kompyuta kwa sasa imewekwa kuwa <ph name="CURRENT_DATE" />. Je, hiyo ni sahihi? Ikiwa si sahihi, rekebisha saa ya mfumo wako kisha uonyeshe upya ukurasa huu.}}</translation>
<translation id="1656489000284462475">Muda wa kuabiri gari</translation>
<translation id="1663943134801823270">Kadi na anwani zinatoka Chrome. Unaweza kuzidhibiti kwenye <ph name="BEGIN_LINK" />Mipangilio<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Kwa kawaida <ph name="SITE" /> hutumia usimbaji fiche ili kulinda maelezo yako. Google Chrome ilipojaribu kuunganisha kwenye <ph name="SITE" /> wakati huu, tovuti ilituma kitambulisho kisicho cha kawaida na kisicho sahihi. Hili linaweza kutokea mvamizi anapojaribu kujifanya kuwa <ph name="SITE" />, au uchanganuzi wa kuingia katika Wi-Fi umeingilia muunganisho. Maelezo yako yangali salama kwa sababu Google Chrome ilisimamisha muunganisho kabla data yoyote itumwe.</translation>
-<translation id="168328519870909584">Huenda wavamizi walio kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kwa sasa wakajaribu kusakinisha programu hatari ambazo zinaiba au kufuta maelezo kwenye kifaa chako (kwa mfano, picha, manenosiri, ujumbe na kadi za mkopo).</translation>
<translation id="168841957122794586">Cheti cha seva kina kitufe dhaifu cha kifichua msimbo.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kitakwisha muda kuanzia kesho. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.}other{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kitakwisha muda kuanzia siku # zijazo. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Unahitaji ruhusa kutoka kwa <ph name="NAME" /> ili utembelee tovuti hii</translation>
<translation id="1721424275792716183">* Unahitaji kujaza sehemu hii</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Pakua ukurasa baadaye</translation>
<translation id="17513872634828108">Vichupo vilivyo wazi</translation>
<translation id="1753706481035618306">Nambari ya ukurasa</translation>
+<translation id="1763864636252898013">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na mfumo wa uendeshaji wa kifaa chako. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Jaribu kutumia zana ya Kuchunguza Mtandao wa Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Tafadhali sasisha kaulisiri yako iliyolandanishwa.</translation>
<translation id="1787142507584202372">Vichupo vyako vilivyo wazi huonekana hapa</translation>
+<translation id="1789575671122666129">Ibukizi</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Jina la mwenye kadi</translation>
-<translation id="1803678881841855883">Mfumo wa Google wa Kuvinjari Salama <ph name="BEGIN_LINK" />uligundua programu hasidi<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi majuzi. Tovuti ambazo kwa kawaida huwa salama wakati mwingine huathiriwa na programu hasidi. Maudhui hasidi hutoka kwa <ph name="SUBRESOURCE_HOST" />, msambazaji wa programu hasidi anayejulikana. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Iliongezwa <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Ombi au vigezo vya ombi batili</translation>
<translation id="1826516787628120939">Inakagua</translation>
<translation id="1834321415901700177">Tovuti hii ina programu hatari</translation>
+<translation id="1840414022444569775">Nambari hii ya kadi tayari imetumika</translation>
<translation id="1842969606798536927">Lipa</translation>
<translation id="1871208020102129563">Proksi imewekwa ili kutumia seva za proksi thabiti, siyo URL ya hati .pac.</translation>
<translation id="1871284979644508959">Lazima sehemu hii ijazwe</translation>
<translation id="187918866476621466">Fungua kurasa zinazoanza</translation>
<translation id="1883255238294161206">Kunja orodha</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">Kuchuja</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Hamna}=1{Tovuti 1}other{Tovuti #}}</translation>
<translation id="194030505837763158">Nenda kwenye <ph name="LINK" /></translation>
<translation id="1962204205936693436">Alamisho za <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Hitilafu ya namba tambulishi</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Imepuuzwa kwa sababu ilifutwa na <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Inatafuta kurasa za Wavuti Kila Mahali zilizo karibu</translation>
<translation id="213826338245044447">Alamisho kwenye Simu</translation>
-<translation id="2148716181193084225">Leo</translation>
+<translation id="2147827593068025794">Usawazishaji wa Chini Chini</translation>
<translation id="2154054054215849342">Huduma ya usawazishaji haipatikani kwa ajili ya kikoa chako</translation>
<translation id="2154484045852737596">Badilisha kadi</translation>
<translation id="2166049586286450108">Idhini Kamili ya Kufikia ya Msimamizi</translation>
<translation id="2166378884831602661">Tovuti hii haiwezi kutoa muunganisho salama</translation>
<translation id="2181821976797666341">Sera</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{Anwani 1}other{Anwani #}}</translation>
+<translation id="2187317261103489799">Gundua (chaguo-msingi)</translation>
<translation id="2202020181578195191">Andika mwaka sahihi wa kuisha kwa muda wa matumizi</translation>
<translation id="2212735316055980242">Sera haikupatikana</translation>
<translation id="2213606439339815911">Inachukua viingizo...</translation>
+<translation id="2218879909401188352">Wavamizi walio kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> hivi sasa, wanaweza kusakinisha programu hatari zinazoweza kukiharibu kifaa chako, kuongeza gharama fiche kwenye malipo yako ya simu, au kuiba maelezo yako ya binafsi. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Weka muunganisho wako kwa kutumia <ph name="BEGIN_LINK" />programu ya kuchunguza<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Tuma sasa</translation>
<translation id="225207911366869382">Thamani hii inapingwa kwa sera hii.</translation>
<translation id="2262243747453050782">Hitilfau ya HTTP</translation>
+<translation id="2270484714375784793">Nambari ya simu</translation>
<translation id="2282872951544483773">Majaribio Yasiyopatikana</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{Kipengee <ph name="ITEM_COUNT" />}other{Vipengee <ph name="ITEM_COUNT" />}}</translation>
<translation id="2292556288342944218">Ufikiaji wako wa intaneti umezuiwa</translation>
<translation id="230155334948463882">Je, ni kadi mpya?</translation>
-<translation id="2305919008529760154">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; huenda cheti chake cha usalama kilitolewa kwa ulaghai. Huenda hali hii ilitokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako.<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> inahitaji jina la mtumiaji na nenosiri.</translation>
-<translation id="2318774815570432836">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti hii hutumia HSTS. Hitilafu na uvamizi wa mtandao kwa kawaida huwa wa muda tu, kwa hivyo ukurasa huu huenda utafanya kazi baadaye.<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Mipangilio inadhibitiwa na msimamizi wako</translation>
<translation id="2354001756790975382">Alamisho zingine</translation>
+<translation id="2354430244986887761">Kipengele cha Kuvinjari Salama kwenye Google <ph name="BEGIN_LINK" />kilipata programu hasidi<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi majuzi.</translation>
<translation id="2355395290879513365">Wavamizi wanaweza kuona picha unazoangalia kwenye tovuti hii na wakuhadae kwa kuzibadilisha.</translation>
+<translation id="2356070529366658676">Uliza</translation>
+<translation id="2359629602545592467">Nyingi</translation>
<translation id="2359808026110333948">Endelea</translation>
<translation id="2365563543831475020">Ripoti ya kuacha kufanya kazi iliyochukuliwa <ph name="CRASH_TIME" /> haikupakiwa</translation>
<translation id="2367567093518048410">Kiwango</translation>
-<translation id="2371153335857947666">{1,plural, =1{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kilikwisha muda jana. Huenda hali hii ilitokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. Saa ya kompyuta kwa sasa imewekwa kuwa <ph name="CURRENT_DATE" />. Je, hiyo ni sahihi? Ikiwa si sahihi, rekebisha saa ya mfumo wako kisha uonyeshe upya ukurasa huu. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.}other{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kilikwisha muda siku # zilizopita. Huenda hali hii ilitokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako Saa ya kompyuta kwa sasa imewekwa kuwa <ph name="CURRENT_DATE" />. Je, hiyo ni sahihi? Ikiwa si sahihi, rekebisha saa ya mfumo wako kisha uonyeshe upya ukurasa huu. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Hakuna chaguo mbadala za kiolesura zinazopatikana</translation>
<translation id="2384307209577226199">Biashara chaguo-msingi</translation>
<translation id="2386255080630008482">Cheti cha seva kimebatilishwa.</translation>
<translation id="2392959068659972793">Onyesha sera zisizowekwa thamani</translation>
<translation id="239429038616798445">Mbinu hii ya usafirishaji haipatikani. Jaribu mbinu tofauti.</translation>
<translation id="2396249848217231973">Tendua kufuta</translation>
-<translation id="2460160116472764928">Mfumo wa Google wa Kuvinjari Salama <ph name="BEGIN_LINK" />umegundua programu hasidi<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi majuzi. Tovuti ambazo kwa kawaida huwa salama wakati mwingine huathiriwa na programu hasidi. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; huenda cheti chake cha usalama kimebatilishwa. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
<translation id="2463739503403862330">Jaza</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Inaendesha Zana ya Kuchunguza Mtandao<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL batili ya utafutaji.</translation>
+<translation id="2482878487686419369">Arifa</translation>
<translation id="2491120439723279231">Cheti cha seva kina hitilafu.</translation>
<translation id="2495083838625180221">Kichanganuzi cha JSON</translation>
<translation id="2495093607237746763">Ikitiwa tiki, Chromium itahifadhi nakala ya kadi yako kwenye kifaa hiki kwa ajili ya kujaza fomu haraka zaidi.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Rudi nyuma</translation>
<translation id="2515629240566999685">Kuangalia uthabiti wa mawimbi katika eneo lako</translation>
<translation id="2516305470678292029">Chaguo mbadala za kiolesura</translation>
+<translation id="2539524384386349900">Gundua</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> imetuma jibu ambalo si sahihi.</translation>
-<translation id="2552545117464357659">Mpya zaidi</translation>
<translation id="2556876185419854533">Tendua Kuhariri</translation>
<translation id="2587730715158995865">Kutoka <ph name="ARTICLE_PUBLISHER" />. Soma makala haya na mengine <ph name="OTHER_ARTICLE_COUNT" />.</translation>
<translation id="2587841377698384444">Kitambulisho cha API ya Saraka:</translation>
<translation id="2597378329261239068">Hati hii imelindwa kwa nenosiri. Tafadhali weka nenosiri linalotumika.</translation>
<translation id="2609632851001447353">Vipera</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Hamna}=1{Programu 1 ($1)}=2{Programu 2 ($1, $2)}other{Programu # ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Saa yako iko mbele</translation>
<translation id="2639739919103226564">Hali:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Ufikivu katika faili umekataliwa</translation>
<translation id="2653659639078652383">Wasilisha</translation>
<translation id="2666117266261740852">Funga vichupo au programu nyingine</translation>
+<translation id="2670429602441959756">Ukurasa huu una vipengele visivyotumika katika VR. Unaondoka...</translation>
<translation id="2674170444375937751">Je, una hakika kuwa ungependa kufuta kurasa hizi kutoka historia yako?</translation>
<translation id="2677748264148917807">Ondoka</translation>
-<translation id="269990154133806163">Seva imewasilisha cheti ambacho hakikuonyeshwa hadharani kwa kutumia sera ya Uwazi wa Cheti. Baadhi ya vyeti huwa na masharti haya, ili kuhakikisha kwamba ni vya kuaminika na kulinda dhidi ya wavamizi.<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Orodha ya Kusoma</translation>
<translation id="2704283930420550640">Thamani haioani na umbizo.</translation>
<translation id="2704951214193499422">Chromium haikuweza kuthibitisha kadi yako wakati huu. Tafadhali jaribu tena baadaye.</translation>
<translation id="2705137772291741111">Nakala iliyohifadhiwa (iliyowekwa katika akiba) ya tovuti hii haikusomeka.</translation>
<translation id="2709516037105925701">Kujaza Kiotomatiki</translation>
-<translation id="2712118517637785082">Ulijaribu kufikia <ph name="DOMAIN" />, lakini cheti kilichowasilishwa na seva kimebatilishwa na mtoaji wacho. Inamaanisha kuwa stakabadhi za usalama zilizowasilishwa na seva hii hazifai kuaminiwa kabisa. Huenda unawasiliana na mvamizi.<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Omba ruhusa</translation>
<translation id="2713444072780614174">Nyeupe</translation>
<translation id="2720342946869265578">Uhamishaji wa Karibu</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Rekodi ya kifaa inayokosekana</translation>
<translation id="2784949926578158345">Muunganisho uliwekwa upya.</translation>
<translation id="2794233252405721443">Tovuti imezuiwa</translation>
+<translation id="2799020568854403057">Kuna programu hasidi kwenye tovuti unayotaka kuifungua</translation>
+<translation id="2803306138276472711">Mfumo wa Google wa Kuvinjari kwa Usalama {<ph name="BEGIN_LINK" />uligundua programu hasidi<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi karibuni. Tovuti ambazo kwa kawaida huwa salama wakati mwingine huathiriwa na programu hasidi.</translation>
<translation id="2824775600643448204">Upau wa anwani na utafutaji</translation>
<translation id="2826760142808435982">Muunganisho umesimbwa kwa njia fiche na kuthibitishwa kupitia <ph name="CIPHER" /> na unatumia <ph name="KX" /> kama utaratibu msingi wa ubadilishaji.</translation>
<translation id="2835170189407361413">Futa fomu</translation>
+<translation id="2856444702002559011">Huenda wavamizi wanajaribu kuiba maelezo yako kutoka <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (kwa mfano, manenosiri, ujumbe au kadi za mikopo).<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Usipakie Upya</translation>
<translation id="2900469785430194048">Nafasi ya kuhifadhi kwenye Google Chrome iliisha ilipokuwa ikijaribu kuonyesha ukurasa huu wa wavuti.</translation>
<translation id="2909946352844186028">Mabadiliko ya mtandao yamegunduliwa.</translation>
<translation id="2916038427272391327">Funga programu nyingine</translation>
<translation id="2922350208395188000">Cheti cha seva hakiwezi kukaguliwa.</translation>
<translation id="2928905813689894207">Anwani ya kutuma Bili</translation>
+<translation id="2941952326391522266">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kinatoka <ph name="DOMAIN2" />. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
<translation id="2948083400971632585">Unaweza kuzima proksi zozote zilizosanidiwa kwa muunganisho kutoka kwenye ukurasa wa mipangilio.</translation>
<translation id="2955913368246107853">Funga upau wa kupata</translation>
<translation id="2958431318199492670">Usanidi wa mtandao hautii kiwango cha ONC. Sehemu za usanidi haziwezi kuingizwa.</translation>
-<translation id="29611076221683977">Wavamizi walio kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kwa sasa huenda wakajaribu kusakinisha programu hatari ambazo zinaiba au kufuta maelezo kwenye Mac yako (kwa mfano picha, manenosiri, ujumbe, na kadi za mkopo).</translation>
<translation id="2966678944701946121">Muda wa kutumika utakwisha: <ph name="EXPIRATION_DATE_ABBR" />, iliongezwa <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Ili kutambua muunganisho salama, saa yako inahitaji kusahihishwa. Hii ni kwa sababu vyeti ambavyo tovuti hutumia kujitambua ni sahihi kwa vipindi mahususi pekee. Kwa kuwa saa ya kifaa chako si sahihi, Google Chrome haiwezi kuthibitisha vyeti hivi.</translation>
<translation id="2972581237482394796">&amp;Rudia</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Andika anwani sahihi</translation>
<translation id="2986368408720340940">Mbinu hii ya kuchukua haipatikani. Jaribu mbinu tofauti.</translation>
<translation id="2991174974383378012">Kushiriki kwenye Tovuti</translation>
+<translation id="2991571918955627853">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti inatumia HSTS. Hitilafu na uvamizi wa mtandao kwa kawaida huwa vya muda, kwa hivyo huenda ukurasa huu ukafanya kazi baadaye.</translation>
<translation id="3005723025932146533">Onyesha nakala iliyohifadhiwa</translation>
<translation id="3008447029300691911">Weka CVC ya <ph name="CREDIT_CARD" />. Baada ya kuthibitisha, maelezo ya kadi yako yatashirikiwa na tovuti hii.</translation>
<translation id="3010559122411665027">Ingizo orodha "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Imezuiwa kiotomatiki</translation>
<translation id="3024663005179499861">Aina mbaya ya sera</translation>
<translation id="3032412215588512954">Ungependa kupakia upya tovuti hii?</translation>
<translation id="3037605927509011580">Lo!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{angalau kipengee 1 kwenye vifaa vilivyosawazishwa}=1{Kipengee 1 (na zaidi kwenye vifaa vilivyosawazishwa)}other{Vipengee # (na zaidi kwenye vifaa vilivyosawazishwa)}}</translation>
<translation id="3041612393474885105">Maelezo ya Cheti</translation>
<translation id="3063697135517575841">Chrome haikuweza kuthibitisha kadi yako wakati huu. Tafadhali jaribu tena baadaye.</translation>
<translation id="3064966200440839136">Inaacha hali fiche ili kulipa kupitia programu ya nje. Je, ungependa kuendelea?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Hamna}=1{Nenosiri 1}other{Manenosiri #}}</translation>
<translation id="3093245981617870298">Uko nje ya mtandao.</translation>
<translation id="3105172416063519923">Kitambulisho cha Kipengee:</translation>
<translation id="3109728660330352905">Huna idhini ya kuona ukurasa huu.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Jaribu kutumia zana ya Kuchunguza Muunganisho<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Imeshindwa kusimbua jibu</translation>
<translation id="3150653042067488994">Hitilfau ya muda ya seva</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Kurasa unazoziangalia katika vichupo fiche hazitaendelea kuwepo katika historia ya kivinjari, hifadhi ya vidakuzi, au historia yako ya utafutaji ukishafunga vichupo vyako vyote fiche. Faili zozote unazopakua au alamisho unazounda hazitafutwa.</translation>
<translation id="3169472444629675720">Gundua</translation>
<translation id="3174168572213147020">Kisiwa</translation>
+<translation id="317583078218509884">Mipangilio mipya ya vibali vya tovuti itaanza kufanya kazi baada ya kupakia upya ukurasa huu.</translation>
<translation id="3176929007561373547">Angalia mipangilio yako ya seva mbadala au wasiliana na msimamizi wako wa mtandao ili
kuhakikisha kuwa seva mbadala inafanya kazi. Ikiwa huamini kwamba unapaswa kuwa
ukitumia seva mbadala:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Fungua ukurasa katika hali Fiche</translation>
-<translation id="3202578601642193415">Mpya kuliko zote</translation>
+<translation id="320323717674993345">Ghairi Malipo</translation>
<translation id="3207960819495026254">Imealamishwa</translation>
+<translation id="3225919329040284222">Seva imewasilisha cheti kisicholingana na matarajio ya kijenzi cha ndani. Matarajio haya yanajumlishwa kwa baadhi ya tovuti za usalama wa juu ili kukulinda.</translation>
<translation id="3226128629678568754">Bonyeza kitufe cha kupakia upya ili kuwasilisha upya data inayohitajika kupakia ukurasa.</translation>
+<translation id="3227137524299004712">Maikrofoni</translation>
<translation id="3228969707346345236">Tafsiri ilishindikana kwa sababu ukurasa tayari upo katika <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Weka CVC ya <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Gundua maudhui muhimu kwenye tovuti hii wakati wowote</translation>
<translation id="3254409185687681395">Alamisha ukurasa huu</translation>
<translation id="3270847123878663523">Tendua Kupanga upya</translation>
<translation id="3282497668470633863">Ongeza jina kwenye kadi</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">mipangilio</translation>
<translation id="3345135638360864351">Ombi lako la kufikia tovuti hii halikutumwa kwa <ph name="NAME" />. Tafadhali jaribu tena.</translation>
<translation id="3355823806454867987">Badilisha mipangilio ya seva mbadala...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />haitahifadhi<ph name="END_EMPHASIS" /> maelezo yafuatayo:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Historia yako ya kuvinjari
+ <ph name="LIST_ITEM" />Data ya vidakuzi na tovuti
+ <ph name="LIST_ITEM" />Maelezo unayojaza katika fomu
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Hitilafu ya saa</translation>
-<translation id="337311366426640088">Vipengee <ph name="ITEM_COUNT" /> zaidi...</translation>
<translation id="337363190475750230">Imewekwa katika hali ya kutotumika</translation>
<translation id="3377188786107721145">Hitilafu ya kuchanganua sera</translation>
<translation id="3380365263193509176">Hitilafu isiyojulikana</translation>
<translation id="3380864720620200369">Kitambulisho cha Mteja:</translation>
<translation id="3391030046425686457">Mahali pa kupeleka</translation>
<translation id="3395827396354264108">Mbinu ya kuchukua</translation>
-<translation id="340013220407300675">Huenda wavamizi wanajaribu kuiba maelezo yako kutoka <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (kwa mfano, manenosiri, ujumbe, au kadi za malipo).</translation>
<translation id="3422248202833853650">Jaribu kuondoka kwenye programu nyingine ili upate nafasi zaidi.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> haiwezi kufikiwa kwa sasa.</translation>
+<translation id="3427092606871434483">Ruhusu (chaguo-msingi)</translation>
<translation id="3427342743765426898">Rudia Kuhariri</translation>
<translation id="3431636764301398940">Hifadhi kadi hii kwenye kifaa hiki</translation>
<translation id="3435896845095436175">Washa</translation>
<translation id="3447661539832366887">Mmiliki wa kifaa hiki amezima mchezo wa dinosau.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Muda unaotumika kuleta:</translation>
<translation id="3462200631372590220">Ficha mahiri</translation>
<translation id="3467763166455606212">Jina la mwenye kadi linahitajika</translation>
<translation id="3478058380795961209">Mwezi wa Muda wa Matumizi Kuisha</translation>
<translation id="3479539252931486093">Je, hukutarajia tukio hili? <ph name="BEGIN_LINK" />Tujulishe<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Sio sasa</translation>
-<translation id="348000606199325318">Kitambulisho cha kuacha kufanya kazi <ph name="CRASH_LOCAL_ID" /> (Kitambulisho cha Seva: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Hatukuweza kufikia mzazi wako wakati huu. Tafadhali jaribu tena.</translation>
<translation id="3528171143076753409">Cheti cha seva hakiaminiki.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Angalau kipengee 1 kwenye vifaa vilivyosawazishwa}=1{Kipengee 1 (na zaidi kwenye vifaa vilivyosawazishwa)}other{Vipengee # (na zaidi kwenye vifaa vilivyosawazishwa)}}</translation>
<translation id="3539171420378717834">Weka nakala ya kadi hii kwenye kifaa hiki</translation>
<translation id="3542684924769048008">Tumia nenosiri kwa:</translation>
+<translation id="3545341443414427877">Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hauwezi kutambuliwa kwa sababu tarehe na saa za kompyuta yako <ph name="DATE_AND_TIME" />) si sahihi. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Simba kwa njia fiche data yote iliyosawazishwa kwa kaulisiri yako binafsi ya usawazishaji</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> zaidi...</translation>
-<translation id="3555561725129903880">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama kinatoka katika <ph name="DOMAIN2" />. Hii inatokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Msimamizi wako anaweza kukuondolea kizuizi</translation>
<translation id="3566021033012934673">Muunganisho wako si wa faragha</translation>
+<translation id="3569145463236695319">&lt;p&gt;Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hauwezi kutambuliwa kwa sababu tarehe na wakati wa kifaa chako (<ph name="DATE_AND_TIME" />) si sahihi.&lt;/p&gt;
+
+ &lt;p&gt;Tafadhali rekebisha tarehe na wakati kutoka sehemu ya &lt;strong&gt;Jumla&lt;/strong&gt; ya programu ya &lt;strong&gt;Mipangilio&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Ongeza jina</translation>
<translation id="3583757800736429874">Rudia Hatua</translation>
<translation id="3586931643579894722">Ficha maelezo</translation>
-<translation id="3587482841069643663">Zote</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Andika tarehe sahihi ya kuisha kwa muda wa matumizi</translation>
<translation id="36224234498066874">Futa Data ya Kuvinjari...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Maelezo ya cheti</translation>
<translation id="3690164694835360974">Kuingia katika akaunti si salama</translation>
<translation id="3693415264595406141">Nenosiri:</translation>
-<translation id="3696411085566228381">hamna</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Inapakia...</translation>
<translation id="3712624925041724820">Leseni zimekwisha</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Kuangalia seva mbadala, kinga-mtandao na mipangilio ya DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Ikiwa unaelewa kiwango cha hatari kinachoweza kutokea, unaweza <ph name="BEGIN_LINK" />kutembelea tovuti hii isiyo salama<ph name="END_LINK" /> kabla programu hatari hazijaondolewa.</translation>
<translation id="3739623965217189342">Kiungo ulichonakili</translation>
+<translation id="3744899669254331632">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti ilituma kitambulisho kilichoharibika ambacho Chromium haiwezi kuchakata. Hitilafu na uvamizi wa mtandao kwa kawaida huwa vya muda, kwa hivyo ukurasa huu huenda utafanya kazi baadaye.</translation>
+<translation id="3748148204939282805">Wavamizi kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> huenda wakakuhadaa ufanye kitu hatari kama vile kusakinisha programu au kuonyesha maelezo yako ya binafsi (kwa mfano, manenosiri, nambari za simu au kadi za mikopo). <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Utafsiri haukufanikiwa kwa sababu ya hitilafu ya seva.</translation>
<translation id="3759461132968374835">Huna uharibifu ulioripotiwa hivi karibuni. Uharibifu uliotokea wakati kuripoti kwa uharibifu kulipolemazwa hakutaonekana hapa.</translation>
+<translation id="3778403066972421603">Je, ungependa kuhifadhi kadi hii kwenye Akaunti yako ya Google na kwenye kifaa hiki?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Muda wa matumizi utakwisha <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Ukitumia seva mbadala...</translation>
<translation id="3828924085048779000">Kaulisiri tupu hairuhusiwi.</translation>
-<translation id="3845539888601087042">Inaonyesha historia kutoka vifaa vyako ulivyotumia kuingia katika akaunti. <ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Nyuma</translation>
<translation id="3858027520442213535">Sasisha tarehe na saa</translation>
<translation id="3884278016824448484">Kitambulisho cha kifaa kinachokinzana</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Ombi lako la kufikia tovuti hii limetumwa kwa <ph name="NAME" /></translation>
<translation id="3890664840433101773">Ongeza anwani ya barua pepe</translation>
<translation id="3901925938762663762">Kadi imekwisha muda</translation>
-<translation id="3933571093587347751">{1,plural, =1{Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama kitakwisha muda kuanzia kesho. Huenda hali hii ilitokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.}other{Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kitakwisha muda kuanzia siku # zijazo. Huenda hali hii ilitokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Imeshindwa kupakia hati ya PDF</translation>
+<translation id="3945915738023014686">Kitambulisho cha Ripoti ya Kuacha Kufanya Kazi Kilichopakiwa <ph name="CRASH_ID" /> (Kitambulisho cha Kuacha Kufanya Kazi cha Ndani ya Kifaa: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama hakibainishi Majina Mbadala ya Mada. Hii inaweza kusababishwa na uwekaji mipangilio usiofaa au muunganisho wako kukatwa na mvamizi.</translation>
<translation id="3963721102035795474">Hali ya Usomaji</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Hamna}=1{Kutoka kwenye tovuti 1 }other{Kutoka kwenye tovuti # }}</translation>
<translation id="397105322502079400">Inakokotoa...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> imezuiwa.</translation>
+<translation id="3987940399970879459">Chini ya MB 1</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ukurasa 1 wa wavuti ulio karibu}other{kurasa # za wavuti zilizo karibu}}</translation>
<translation id="4021036232240155012">DNS ni huduma za mtandao ambazo hubadilisha jina la tovuti kuwa anwani yake ya Intaneti.</translation>
<translation id="4030383055268325496">Tendua kuongeza</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Usanidi wa proksi umewekwa kutumia URL hati ya .pac, siyo seva proksi za kudumu.</translation>
<translation id="4098354747657067197">Kuna tovuti danganyifu mbele</translation>
<translation id="4103249731201008433">Namabari tambulishi ya kifaa ni batili</translation>
+<translation id="410351446219883937">Kucheza kiotomatiki</translation>
<translation id="4103763322291513355">Tembelea &lt;strong&gt;chrome://policy&lt;/strong&gt; ili kuona orodha ya URL zilizoondolewa idhini na sera zingine zinazosimamiwa na msimamizi wako wa mfumo.</translation>
-<translation id="4110615724604346410">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama kina hitilafu. Hii inatokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Rangi ya damu ya mzee</translation>
+<translation id="4116663294526079822">Ruhusu mara kwa mara kwenye tovuti hii</translation>
<translation id="4117700440116928470">Upeo wa sera hauwezi kutumika.</translation>
-<translation id="4118212371799607889">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na Chromium. Hii inatokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{Nyingine 1 }other{Nyingine #}}</translation>
<translation id="4130226655945681476">Kukagua kebo za mtandao, modemu au kisambaza data</translation>
+<translation id="413544239732274901">Pata maelezo zaidi</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Tumia chaguo-msingi la kimataifa (Gundua)</translation>
+<translation id="4165986682804962316">Mipangilio ya tovuti</translation>
<translation id="4169947484918424451">Je, unataka Chromium ihifadhi kadi hii?</translation>
<translation id="4171400957073367226">Sahihi mbaya ya uthibitishaji</translation>
<translation id="4196861286325780578">Rudia hatua</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Kuangalia mipangilio ya kinga-mtandao na kinga-virusi<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{hamna}=1{Programu 1 ($1)}=2{Programu 2 ($1, $2)}other{Programu # ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Mivurugo</translation>
+<translation id="422022731706691852">Wavamizi kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> huenda wakajaribu kukuhadaa kusakinisha programu inayoathiri hali yako ya kuvinjari (kwa mfano, kwa kubadilisha ukurasa wako wa kwanza au kuonyesha matangazo ya ziada kwenye tovuti unazotembelea). <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Jaribu kutumia zana ya Kuchunguza Mtandao<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Halali</translation>
<translation id="4250431568374086873">Muunganisho wako kwenye tovuti hii si salama kabisa</translation>
<translation id="4250680216510889253">La</translation>
<translation id="425582637250725228">Huenda mabadiliko uliyofanya yasihifadhiwe.</translation>
<translation id="4258748452823770588">Sahihi mbaya</translation>
+<translation id="4265872034478892965">Imeruhusiwa na msimamizi wako</translation>
<translation id="4269787794583293679">(Hakuna jina la mtumiaji)</translation>
<translation id="4275830172053184480">Washa upya kifaa chako</translation>
<translation id="4280429058323657511">, muda wa kutumika utakwisha <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Mfumo wa Google wa Kuvinjari Salama <ph name="BEGIN_LINK" />uligundua programu zenye virusi<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi majuzi. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Mapendekezo ya wazazi</translation>
<translation id="4304224509867189079">Ingia</translation>
-<translation id="432290197980158659">Seva hii iliwasilisha cheti ambacho hakilingani na vipengele vilivyojengewa ndani. Vipengele hivi vimejumuishwa kwenye baadhi ya tovuti za usalama wa juu ili kukulinda. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Zuia (chaguo-msingi)</translation>
<translation id="4325863107915753736">Haikupata makala</translation>
<translation id="4326324639298822553">Angalia tarehe kuisha kwa muda wa matumizi halafu ujajibu tena</translation>
<translation id="4331708818696583467">Si Salama</translation>
<translation id="4356973930735388585">Huenda wavamizi walio kwenye tovuti hii wakajaribu kusakinisha programu hatari inayoiba au kufuta maelezo yako yaliyo kwenye kompyuta yako (kwa mfano, picha, manenosiri, ujumbe, na kadi za mikopo).</translation>
<translation id="4372948949327679948">Thamani <ph name="VALUE_TYPE" /> inayotarajiwa.</translation>
+<translation id="4377125064752653719">Ulijaribu kufikia <ph name="DOMAIN" />, lakini cheti kilichowasilishwa na seva kimebatilishwa na mtoaji wacho. Huku ni kumaanisha kuwa stakabadhi za usalama zilizowasilishwa na seva hii hazifai kuaminiwa kabisa. Huenda ukawa unawasiliana na mshabulizi.</translation>
<translation id="4381091992796011497">Jina la mtumiaji:</translation>
<translation id="4394049700291259645">Zima</translation>
<translation id="4406896451731180161">matokeo ya utafutaji</translation>
+<translation id="4424024547088906515">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na Chrome. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> haikukubali cheti chako cha kuingia katika akaunti, au huenda hukutoa cheti.</translation>
<translation id="443673843213245140">Matumizi ya proksi yamelemazwa lakini usanidi wa proksi wazi umebainishwa.</translation>
-<translation id="4492190037599258964">Matokeo ya utafutaji wa '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Hitilafu ya uthibitishaji: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Kuwasiliana na msimamizi wa mfumo</translation>
<translation id="450710068430902550">Kushiriki na Msimamizi</translation>
<translation id="4515275063822566619">Kadi na anwani zinatoka Chrome na Akaunti yako ya Google (<ph name="ACCOUNT_EMAIL" />). Unaweza kuzidhibiti katika <ph name="BEGIN_LINK" />Mipangilio<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Maelezo</translation>
+<translation id="4552089082226364758">Mmweko</translation>
<translation id="4558551763791394412">Jaribu kuzima viendelezi vyako.</translation>
<translation id="457875822857220463">Usafirishaji</translation>
<translation id="4587425331216688090">Ungependa kuondoa anwani kutoka kwenye Chrome?</translation>
-<translation id="4589078953350245614">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva imewasilisha cheti kisicho sahihi. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Muunganisho wako kwenye <ph name="DOMAIN" /> umesimbwa kwa njia fiche kwa kutumia mipangilio ya kriptografia ya kisasa.</translation>
<translation id="4594403342090139922">Tendua Kufuta</translation>
<translation id="4619615317237390068">Vichupo kutoka kwenye vifaa vingine</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama kina hitilafu. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
+<translation id="4690462567478992370">Acha kutumia cheti kisicho sahihi</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Muunganisho wako umekatizwa</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Kuendesha Zana ya Windows ya Kuchunguza Mtandao<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Hitilafu isiyojulikana imetokea.</translation>
<translation id="4800132727771399293">Angalia tarehe yako ya kuisha muda na CVC na ujaribu tena</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti ilituma kitambulisho kilichoharibika ambacho Google Chrome haiwezi kushughulikia. Hitilafu na uvamizi wa mtandao kwa kawaida huwa vya muda, kwa hivyo ukurasa huu huenda ukafanya kazi baadaye.</translation>
<translation id="4813512666221746211">Hitilafu ya mtandao</translation>
<translation id="4816492930507672669">Sawazisha kwenye ukurasa</translation>
<translation id="483020001682031208">Hakuna Kurasa za Wavuti kila Mahali za kuonyesha</translation>
<translation id="4850886885716139402">Mwonekano</translation>
<translation id="4854362297993841467">Njia hii ya kusafirisha haitumiki. Jaribu njia tofauti.</translation>
<translation id="4858792381671956233">Umewaomba wazazi wako ruhusa ya kuutembelea ukurasa huu.</translation>
+<translation id="4863764087567530506">Maudhui haya yanaweza kukuhadaa kusakinisha programu au kuonyesha maelezo yako ya binafsi. <ph name="BEGIN_LINK" />Onyesha<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Tafuta katika historia</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{na ukurasa 1 zaidi wa wavuti}other{na kurasa # zaidi za wavuti}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Ukurasa huu umetafsiriwa kutoka katika lugha ambayo haijulikani hadi <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Malipo</translation>
<translation id="4926049483395192435">Sharti ibainishwe.</translation>
<translation id="495170559598752135">Vitendo</translation>
<translation id="4958444002117714549">Panua orodha</translation>
-<translation id="4962322354953122629">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na Chrome. Hii inatokana na uwekaji mipangilio usiofaa, au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Onyesha maonyo tena</translation>
<translation id="4989809363548539747">Programu-jalizi hii haitumiki</translation>
<translation id="5002932099480077015">Ikiwashwa, Chrome itahifadhi nakala ya kadi yako kwenye kifaa hiki kwa ajili ya kujaza fomu haraka zaidi.</translation>
<translation id="5018422839182700155">Ukurasa huu haufunguki</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Angalia sera za msimamizi wako</translation>
<translation id="5029568752722684782">Futa nakala</translation>
<translation id="5031870354684148875">Kuhusu Google Tafsiri</translation>
+<translation id="5039804452771397117">Ruhusu</translation>
<translation id="5040262127954254034">Faragha</translation>
<translation id="5045550434625856497">Nenosiri lisilo sahihi</translation>
<translation id="5056549851600133418">Makala kwa ajili yako</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Kuangalia anwani mbadala<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Hamna vidakuzi}=1{Tovuti 1 inatumia vidakuzi. }other{Tovuti # zinatumia vidakuzi. }}</translation>
<translation id="5087286274860437796">Cheti cha seva si sahihi kwa sasa.</translation>
<translation id="5087580092889165836">Ongeza kadi</translation>
<translation id="5089810972385038852">Jimbo</translation>
+<translation id="5094747076828555589">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na Chromium. Hii inaweza kusababishwa na kusanidi kusikofaa au mvamizi kuingilia muunganisho wako.</translation>
<translation id="5095208057601539847">Mkoa</translation>
<translation id="5115563688576182185">(biti 64)</translation>
<translation id="5141240743006678641">Simba kwa njia fiche manenosiri yaliyosawazishwa ukitumia stakabadhi zako za Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Anwani ya barua pepe inahitajika</translation>
<translation id="5251803541071282808">Wingu</translation>
<translation id="5277279256032773186">Je, unatumia Chrome kazini? Kampuni zinaweza kudhibiti mipangilio ya Chrome ya wafanyikazi wao. Pata maelezo zaidi</translation>
+<translation id="5297526204711817721">Muunganisho wako kwenye tovuti hii si wa faragha. Ili uondoke kwenye hali ya VR wakati wowote, ondoa vifaa vya kutazama uhalisia pepe na ubonyeze tena.</translation>
<translation id="5299298092464848405">Hitilafu wakati wa kuchanganua sera</translation>
-<translation id="5300589172476337783">Onyesha</translation>
<translation id="5308689395849655368">Kuripoti uharibifu kumelemazwa.</translation>
<translation id="5317780077021120954">Hifadhi</translation>
<translation id="5327248766486351172">Jina</translation>
-<translation id="5337705430875057403">Huenda wavamizi kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> wakakulaghai ili ufanye kitu hatari kama vile kusakinisha programu au kuonyesha maelezo yako ya kibinafsi (kwa mfano, manenosiri, nambari za simu, au kadi za mikopo).</translation>
-<translation id="5359637492792381994">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama si sahihi. Hii inatokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu cheti chake kimebatilishwa. Hitilafu na uvamizi wa mtandao kwa kawaida huwa wa muda, kwa hivyo huenda ukurasa huu utafanya kazi baadaye.</translation>
<translation id="536296301121032821">Imeshindwa kuhifadhi mipangilio ya sera</translation>
<translation id="5386426401304769735">Msururu wa cheti wa tovuti hii una cheti kilichotiwa sahihi kwa kutumia SHA-1.</translation>
<translation id="5402410679244714488">Muda wa kutumia utakwisha: <ph name="EXPIRATION_DATE_ABBR" />, ilitumika mwisho zaidi ya mwaka mmoja uliopita</translation>
+<translation id="540969355065856584">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama si sahihi kwa sasa. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
<translation id="5421136146218899937">Futa data ya kuvinjari...</translation>
<translation id="5430298929874300616">Ondoa alamisho</translation>
<translation id="5431657950005405462">Faili yako haikupatikana</translation>
-<translation id="5435775191620395718">Inaonyesha historia kutoka kifaa hiki. <ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Hitilafu katika uhalalishaji wa Skima " <ph name="ERROR_PATH" /> ": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Ukurasa wa <ph name="HOST_NAME" /> hii haukupatikana</translation>
<translation id="5455374756549232013">Muhuri wa muda wa sera mbaya</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> ya <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Haiwezi kutumika</translation>
<translation id="5470861586879999274">Rudia kuhariri</translation>
<translation id="54817484435770891">Ongeza anwani sahihi ya barua pepe</translation>
<translation id="5492298309214877701">Tovuti hii kwenye intraneti ya kampuni, shirika au shule ina URL sawa na tovuti ya nje.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Haiwezi kuchukua kutoka kwenye anwani hii. Chagua anwani tofauti.</translation>
<translation id="5572851009514199876">Tafadhali anza na uingie katika Chrome ili Chrome iangalie ikiwa unaruhusiwa kufikia tovuti hii.</translation>
<translation id="5580958916614886209">Angalia mwezi kuisha kwa muda wa matumizi halafu ujajibu tena</translation>
+<translation id="5586446728396275693">Hakuna anwani zilizohifadhiwa</translation>
+<translation id="5595485650161345191">Badilisha anwani</translation>
<translation id="560412284261940334">Usimamizi hautumiki</translation>
<translation id="5610142619324316209">Kuangalia muunganisho</translation>
<translation id="5610807607761827392">Unaweza kudhibiti maelezo ya kadi na anwani katika <ph name="BEGIN_LINK" />Mipangilio<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Ungependa kuondoka kwenye tovuti hii?</translation>
<translation id="5629630648637658800">Imeshindwa kupakia mipangilio ya sera</translation>
<translation id="5631439013527180824">Ishara ya usimamizi wa kifaa batili</translation>
+<translation id="5633066919399395251">Wavamizi ambao sasa wako kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> huenda wakajaribu kusakinisha programu hatari kwenye kompyuta yako ambazo zinaiba au kufuta maelezo yako (kwa mfano, picha, manenosiri, ujumbe na kadi za mikopo). <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Mahali</translation>
+<translation id="5659593005791499971">Barua pepe</translation>
<translation id="5669703222995421982">Pata maudhui yanayokufaa</translation>
<translation id="5675650730144413517">Ukurasa huu haufanyi kazi</translation>
-<translation id="5677928146339483299">Vilivyozuiwa</translation>
-<translation id="5694783966845939798">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti kilichowekwa sahihi kwa kutumia algoriti dhaifu. Hii inamaanisha kuwa huenda stakabadhi za usalama za seva zilizowasilishwa ni ghushi, na huenda seva siyo uliyoitarajia (huenda unawasiliana na mvamizi).<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Utambulisho wa tovuti hii haujathibitishwa.</translation>
+<translation id="5713016350996637505">Maudhui danganyifu yamezuiwa</translation>
<translation id="5720705177508910913">Mtumiaji wa sasa</translation>
<translation id="5732392974455271431">Wazazi wako wanaweza kukuondolea kizuizi</translation>
<translation id="5763042198335101085">Andika anwani sahihi ya barua pepe</translation>
<translation id="5765072501007116331">Chagua mahali ili uone njia za kusafirisha na mahitaji</translation>
+<translation id="5778550464785688721">Udhibiti kamili wa vifaa vya MIDI</translation>
<translation id="5784606427469807560">Kulikuwa na tatizo wakati wa kuthibitisha kadi yako. Angalia muunganisho wako wa intaneti kisha ujaribu tena.</translation>
<translation id="5785756445106461925">Mbali na hayo, ukurasa huu una rasilimali nyingine zisizo salama. Rasilimali hizi zinaweza kuangaliwa na watu wengine wanaosafiri, na zinaweza kurekebishwa na mvamizi kubadilisha mwonekano wa ukurasa.</translation>
<translation id="5786044859038896871">Ungependa kujaza maelezo ya kadi yako?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">Rudia Kuongeza</translation>
<translation id="5814352347845180253">Utapoteza idhini ya kufikia maudhui ya kulipiwa kutoka kwenye <ph name="SITE" /> na tovuti nyingine.</translation>
<translation id="5838278095973806738">Hupaswi kuweka maelezo nyeti kwenye tovuti hii (kwa mfano, manenosiri au kadi za mikopo), kwa sababu wavamizi wanaweza kuyaiba.</translation>
-<translation id="5843436854350372569">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti chenye ufunguo duni. Huenda mvamizi alivunja ufunguo wa faragha, na huenda seva si ile uliyoitarajia (huenda unawasiliana na mvamizi).<ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Tovuti hii haiwezi kufikiwa</translation>
<translation id="5869522115854928033">Manenosiri yaliyohifadhiwa</translation>
<translation id="5872918882028971132">Mapendekezo ya Wazazi</translation>
<translation id="5901630391730855834">Manjano</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (imesawazishwa)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 kinatumika}other{ # vinatumika}}</translation>
<translation id="5926846154125914413">Utapoteza idhini ya kufikia maudhui ya kulipiwa kutoka kwenye tovuti nyingine.</translation>
<translation id="5959728338436674663">Tuma kiotomatiki <ph name="BEGIN_WHITEPAPER_LINK" />maelezo ya mfumo na maudhui kadha ya ukurasa<ph name="END_WHITEPAPER_LINK" /> kwa Google ili kusaidia kugundua programu na tovuti hatari. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Juma</translation>
<translation id="5967867314010545767">Ondoa kwenye historia</translation>
<translation id="5975083100439434680">Fifiza</translation>
<translation id="598637245381783098">Imeshindwa kufungua programu ya kulipa</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Ukurasa wa 1}other{Ukurasa wa #}}</translation>
<translation id="6017514345406065928">Kijani</translation>
+<translation id="6017850046339264347">Wavamizi walio kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> wanaweza kusakinisha programu za udanganyifu zinazojifanya kuwa kitu kingine au kukusanya data inayoweza kutumika kukufuatilia. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (imesawazishwa)</translation>
<translation id="6027201098523975773">Andika jina</translation>
<translation id="6040143037577758943">Funga</translation>
<translation id="6042308850641462728">Zaidi</translation>
+<translation id="6047233362582046994">Ikiwa unaelewa hatari kwa usalama wako, unaweza <ph name="BEGIN_LINK" />kuitembelea tovuti hii<ph name="END_LINK" /> kabla programu hasidi hazijaondolewa.</translation>
+<translation id="6051221802930200923">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti hii inatumia ubandikaji cheti. Hitilafu na uvamizi wa mtandao kwa kawaida huwa vya muda, kwa hivyo ukurasa huu huenda utafanya kazi baadaye.</translation>
<translation id="6060685159320643512">Tahadhari, majaribio haya yanaweza kusumbua</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{hamna}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Umefikia maudhui kwa kutumia cheti kilichotolewa cha msimamizi. Data unayotoa katika <ph name="DOMAIN" /> inaweza kuzuiliwa na msimamizi wako.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Hamna}=1{Nenosiri 1 (limesawazishwa)}other{Manenosiri # (yamesawazishwa)}}</translation>
<translation id="6146055958333702838">Angalia kebo zozote na uwashe tena kisambaza data, modemu, au vifaa vingine vyovyote vya
mtandao ambavyo huenda unavitumia.</translation>
<translation id="614940544461990577">Jaribu:</translation>
<translation id="6151417162996330722">Cheti cha seva kina muda sahihi ambao ni mrefu sana.</translation>
<translation id="6157877588268064908">Chagua anwani ili uone mbinu za kusafirisha na mahitaji</translation>
+<translation id="6158003235852588289">Mfumo wa Kuvinjari Salama kwenye Google uligundua jaribio la kuhadaa ili kupata maelezo ya kibinafsi kwenye <ph name="SITE" /> hivi majuzi. Tovuti za kuhadaa ili kupata maelezo ya kibinafsi hujifanya kuwa tovuti nyingine ili kukuhadaa.</translation>
<translation id="6165508094623778733">Pata maelezo zaidi</translation>
+<translation id="6169916984152623906">Sasa unaweza kuvinjari kwa faragha na watu wengine wanaotumia kifaa hiki hawataona shughuli zako. Hata hivyo, vipakuliwa na alamisho zitahifadhiwa.</translation>
<translation id="6177128806592000436">Muunganisho wako kwenye tovuti hii si salama</translation>
<translation id="6184817833369986695">(kundi: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Angalia muunganisho wako wa Intaneti</translation>
<translation id="6218753634732582820">Je, ungependa kuondoa anwani kwenye Chromium?</translation>
+<translation id="6221345481584921695">Mfumo wa Google wa Kuvinjari kwa Usalama <ph name="BEGIN_LINK" />uligundua programu hasidi<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi karibuni. Tovuti ambazo kwa kawaida huwa salama wakati mwingine huathiriwa na programu hasidi. Maudhui hasidi hutoka kwa <ph name="SUBRESOURCE_HOST" />, msambazaji wa programu hasidi anayejulikana.</translation>
<translation id="6251924700383757765">Sera ya faragha</translation>
<translation id="6254436959401408446">Hakuna hifadhi ya kutosha kufungua ukurasa huu</translation>
<translation id="625755898061068298">Umechagua kuzima maonyo ya usalama ya tovuti hii.</translation>
@@ -567,7 +635,7 @@
<translation id="6276112860590028508">Kurasa kutoka orodha yako ya usomaji huonekana hapa</translation>
<translation id="6280223929691119688">Haiwezi kuwasilisha kwenye anwani hii. Chagua anwani tofauti.</translation>
<translation id="6282194474023008486">Msimbo wa posta</translation>
-<translation id="6290238015253830360">Makala uliyopendekeza yataonekana hapa</translation>
+<translation id="6290238015253830360">Makala unayopendekezewa yataonekana hapa</translation>
<translation id="6305205051461490394"><ph name="URL" /> haiwezi kufikiwa.</translation>
<translation id="6319915415804115995">Ilitumika mwisho zaidi ya mwaka mmoja uliopita</translation>
<translation id="6321917430147971392">Angalia mipangilio yako ya DNS</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Badilisha alamisho</translation>
<translation id="6410264514553301377">Weka tarehe ya mwisho wa matumizi na CVC ya <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Umewaomba wazazi wako ruhusa ya kuitembelea tovuti hii</translation>
-<translation id="6416403317709441254">Huwezi kutembelea <ph name="SITE" /> hivi sasa kwa sababu tovuti ilituma kitambulisho kilichoharibika ambacho Chromium haiwezi kuchakata. Hitilafu na uvamizi wa mtandao kwa kawaida huwa wa muda, kwa hivyo ukurasa huu huenda utafanya kazi baadaye. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Haiwezi kukagua ikiwa cheti kimebatilishwa.</translation>
<translation id="6433490469411711332">Badilisha maelezo ya mawasiliano</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> imekataa kuunganisha.</translation>
<translation id="6446608382365791566">Ongeza maelezo zaidi</translation>
+<translation id="6447842834002726250">Vidakuzi</translation>
<translation id="6451458296329894277">Thibitisha kuwa Fomu Iwasilishwe Tena</translation>
<translation id="6456339708790392414">Malipo Yako</translation>
<translation id="6458467102616083041">Imepuuzwa kwa sababu utafutaji chaguo-msingi unalemazwa kwa sera.</translation>
-<translation id="6462969404041126431">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama huenda kimebatilishwa. Huenda hali hii inatokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Sera za kifaa</translation>
<translation id="6477321094435799029">Chrome imegundua nambari ya kuthibitisha isiyo ya kawaida kwenye ukurasa huu na ikaizuia ili kulinda maelezo ya binafsi (kwa mfano, manenosiri, nambari za simu na kadi za mikopo).</translation>
<translation id="6489534406876378309">Anza kupakia matukio ya kuacha kufanya kazi</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Muda wa kutumika utakwisha: <ph name="EXPIRATION_DATE_ABBR" />, mara ya mwisho ilitumika <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Msimamizi wako bado hajaiidhinisha</translation>
<translation id="6569060085658103619">Unaangalia ukurasa wa kiendelezi</translation>
-<translation id="6593753688552673085">chini ya <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Huenda maudhui haya yakajaribu kusakinisha programu hatari inayoiba au kufuta maelezo yako kwenye kifaa chako. <ph name="BEGIN_LINK" />Onyesha<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Chaguo za usimbaji fiche</translation>
<translation id="662080504995468778">Usiondoke</translation>
<translation id="6626291197371920147">Ongeza nambari sahihi ya kadi</translation>
<translation id="6628463337424475685">Utafutaji wa <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Wavamizi ambao sasa wako kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> huenda wakajaribu kusakinisha programu hatari kwenye Mac yako ambazo zinaiba au kufuta maelezo yako (kwa mfano, picha, manenosiri, ujumbe na kadi za mikopo). <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Sera hii imepingwa.</translation>
-<translation id="6652240803263749613">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na mfumo wa uendeshaji wa kompyuta yako. Hali hii inatokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Je, ungependa kuondoa pendekezo la fomu kwenye Chromium?</translation>
<translation id="6685834062052613830">Ondoka na ukamilishe kuweka mipangilio</translation>
<translation id="6710213216561001401">Iliyotangulia</translation>
<translation id="6710594484020273272">&lt;Andika neno unalotaka kutafuta&gt;</translation>
<translation id="6711464428925977395">Kuna hitilafu katika seva mbadala, au anwani siyo sahihi.</translation>
<translation id="6727102863431372879">Weka</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{hamna}=1{Kipengee 1}other{Vipengee #}}</translation>
<translation id="674375294223700098">Hitilafu isiyojulikana ya cheti cha seva.</translation>
<translation id="6753269504797312559">Thamani ya sera</translation>
<translation id="6757797048963528358">Kifaa chako kiko katika hali tuli.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Kitambulisho cha kubadilisha ili kukufaa</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Imeshindwa kupakia maeneo ya data</translation>
+<translation id="6825578344716086703">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti kilichotiwa sahihi na kanuni duni. Hii inamaanisha kuwa stakabadhi za usalama zilizowasilishwa na seva hiyo huenda ni bandia na seva hiyo huenda ikawa si ile uliyotarajia (unaweza kuwa unawasiliana na mvamizi).</translation>
+<translation id="6830728435402077660">Si salama</translation>
<translation id="6831043979455480757">Tafsiri</translation>
<translation id="6839929833149231406">Eneo</translation>
<translation id="6874604403660855544">Rudia kuongeza</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Kadi yako imethibitishwa</translation>
<translation id="6897140037006041989">Programu ya Mtumiaji</translation>
<translation id="6915804003454593391">Mtumiaji:</translation>
+<translation id="6945221475159498467">Chagua</translation>
<translation id="6948701128805548767">Chagua anwani ili uone mbinu za kuchukua na mahitaji</translation>
<translation id="6957887021205513506">Cheti cha seva kinaonekana kuwa ghushi.</translation>
<translation id="6965382102122355670">Sawa</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Seva zote za proksi thabiti na URL ya hati ya .pac zimebainishwa.</translation>
<translation id="6989763994942163495">Onyesha mipangilio ya kina...</translation>
<translation id="7000990526846637657">Hakuna historia ya mambo uliyovinjari inayopatikana</translation>
-<translation id="7009986207543992532">Umejaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti ambacho muda wake wa kutumika ni mrefu sana hivi kwamba hauaminiki. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Huenda Akaunti yako ya Google ina aina nyingine za historia ya kuvinjari kwenye <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Manenosiri</translation>
+<translation id="7050187094878475250">Ulijaribu kufikia <ph name="DOMAIN" />, lakini seva ikawasilisha cheti ambacho muda wake sahihi ni mrefu sana wa kuweza kuaminika.</translation>
+<translation id="7053983685419859001">Zuia</translation>
<translation id="7064851114919012435">Maelezo ya mawasiliano</translation>
<translation id="7079718277001814089">Tovuti hii ina programu hasidi</translation>
<translation id="7087282848513945231">Nchi</translation>
-<translation id="7088615885725309056">Za awali</translation>
<translation id="7090678807593890770">Tafuta <ph name="LINK" /> kwenye Google</translation>
+<translation id="7108819624672055576">Imeruhusiwa na kiendelezi</translation>
<translation id="7119414471315195487">Funga vichupo au programu nyingine</translation>
<translation id="7129409597930077180">Haiwezi kusafirisha kwenda kwenye anwani hii. Chagua anwani tofauti.</translation>
<translation id="7138472120740807366">Njia ya kusafirisha</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Malipo yanashughulikiwa</translation>
<translation id="724691107663265825">Tovuti unayoelekea kufungua ina programu hasidi</translation>
<translation id="724975217298816891">Weka tarehe ya kuisha kwa muda wa matumizi na CVC ya <ph name="CREDIT_CARD" /> ili usasishe maelezo ya kadi yako. Baada ya kuthibitisha, maelezo ya kadi yako yatashirikiwa na tovuti hii.</translation>
-<translation id="725866823122871198">Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hauwezi kutambuliwa kwa sababu tarehe na wakati wa kompyuta yako (<ph name="DATE_AND_TIME" />) si sahihi.</translation>
+<translation id="7260504762447901703">Batilisha ufikiaji</translation>
<translation id="7275334191706090484">Alamisho Zinazosimamiwa</translation>
<translation id="7298195798382681320">Zinazopendekezwa</translation>
<translation id="7309308571273880165">Ripoti ya kuacha kufanya kazi iliyochukuliwa <ph name="CRASH_TIME" /> (kipakiwa kilichoombwa na mtumiaji bado hakijapakiwa)</translation>
<translation id="7334320624316649418">Rudia Kupanga Upya</translation>
<translation id="733923710415886693">Cheti cha seva hakikufichuliwa kupitia Uwazi wa Cheti.</translation>
-<translation id="7351800657706554155">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu cheti hiki kimebatilishwa. Hitilafu na uvamizi wa mtandao kwa kawaida huwa wa muda, kwa hivyo ukurasa huu huenda utafanya kazi baadaye. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Mbinu ya Amri</translation>
<translation id="7372973238305370288">matokeo ya utafutaji</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">La</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Thibitisha Kadi</translation>
-<translation id="7394102162464064926">Je, una uhakika unataka kufuta kurasa hizi kutoka kwenye historia yako?
-
-Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Kijia cha Maelezo mafupi</translation>
<translation id="7424977062513257142">Ukurasa uliopachikwa kwenye ukurasa huu wa wavuti unasema:</translation>
@@ -688,6 +754,7 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="7444046173054089907">Tovuti hii imezuiwa</translation>
<translation id="7445762425076701745">Utambulisho wa seva ambayo umejiunga kwayo hauwezi kuhalalishwa kikamilifu. Umeunganishwa kwenye seva kwa kutumia jina ambalo ni halali tu katika mtandao wako, ambalo mamlaka ya cheti cha nje hayana njia ya kuhalalisha umiliki wake. Kama baadhi ya mamlaka ya cheti yatatoa vyeti vya majina haya bila kujali, hakuna njia ya kuhakikisha umeunganishwa kwenye tovuti inayohitajika na sio mshambulizi.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" /> kuhusu hitilafu hii.</translation>
+<translation id="7455133967321480974">Tumia chaguo-msingi la duniani (Zuia)</translation>
<translation id="7460163899615895653">Vichupo vyako vya hivi majuzi kutoka kwenye vifaa vingine vitaonekana hapa</translation>
<translation id="7469372306589899959">Inathibitisha kadi</translation>
<translation id="7481312909269577407">Mbele</translation>
@@ -695,36 +762,43 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="7508255263130623398">Kitambulisho cha sera ya kifaa kilichorejeshwa hakina kitu au hakilingani na kitambulisho cha kifaa kilichopo</translation>
<translation id="7514365320538308">Pakua</translation>
<translation id="7518003948725431193">Hakuna ukurasa wa wavuti uliopatikana kwa anwani hii ya wavuti: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Thamani</translation>
<translation id="7537536606612762813">Lazima</translation>
+<translation id="7542403920425041731">Baada ya kuthibitisha, maelezo ya kadi yako yatashirikiwa na tovuti hii.</translation>
<translation id="7542995811387359312">Mjazo otomatiki wa kadi ya mkopo umelemazwa kwa sababu fomu hii haitumii muunganisho salama.</translation>
<translation id="7543525346216957623">Muulize mzazi wako</translation>
<translation id="7549584377607005141">Ukurasa huu wa wavuti unahitaji data ambayo uliingiza mapema ili ionyeshwe inavyostahili. Unaweza kutuma tena data hii, lakini kwa kufanya hivyo utarudia hatua yoyote ambayo ukurasa huu ulifanya hapo awali.</translation>
<translation id="7552846755917812628">Jaribu vidokezo vinavyofuata:</translation>
<translation id="7554791636758816595">Kichupo Kipya</translation>
+<translation id="7567204685887185387">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; huenda cheti chake cha usalama kimetolewa kwa njia ya ulaghai. Hii inaweza kusababishwa na usanidi usiofaa au mvamizi kuingilia muunganisho wako.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Ukurasa huu umeandikwa kwa<ph name="ORIGINAL_LANGUAGE" />Je, ungependa kuutafsiri?</translation>
<translation id="7569952961197462199">Ungependa kuondoa kadi ya malipo kutoka kwenye Chrome?</translation>
<translation id="7569983096843329377">Nyeusi</translation>
<translation id="7578104083680115302">Lipa haraka kwenye tovuti na programu katika vifaa vyote ukitumia kadi ulizohifadhi kwenye Google.</translation>
<translation id="7588950540487816470">Wavuti Kila Mahali</translation>
<translation id="7592362899630581445">Cheti cha seva kinakiuka vikwazo vya jina.</translation>
+<translation id="7598391785903975535">Chini ya MB <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> haiwezi kushughulikia ombi hili kwa sasa.</translation>
<translation id="7600965453749440009">Kamwe usitafsiri <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Thamani imezidi masafa<ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Muda wa matumizi utakwisha: <ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Tayari una data ambayo imesimbwa kwa fiche kwa kutumia toleo tofauti la nenosiri lako la Akaunti ya Google. Tafadhali liingize hapo chini.</translation>
-<translation id="7634554953375732414">Muunganisho wako kwenye tovuti hii si wa faragha.</translation>
<translation id="7637571805876720304">Je, ungependa kuondoa kadi ya mikopo kwenye Chromium?</translation>
<translation id="765676359832457558">Ficha mipangilio ya kina...</translation>
<translation id="7658239707568436148">Ghairi</translation>
+<translation id="7662298039739062396">Mipangilio inadhibitiwa na kiendelezi</translation>
<translation id="7667346355482952095">Tokeni ya sera iliyoletwa haina chochote au hailingani na tokeni ya sasa</translation>
<translation id="7668654391829183341">Kifaa kisichojulikana</translation>
<translation id="7669271284792375604">Wavamizi kwenye tovuti hii wanaweza kujaribu kukulaghai kusakinisha programu zinazoathiri hali yako ya kuvinjari (kwa mfano, kwa kubadilisha ukurasa wako wa kwanza au kwa kuonyesha matangazo ya ziada kwenye tovuti unazotembelea).</translation>
<translation id="7674629440242451245">Unavutiwa na vipengee vipya vizuri vya Chrome? Jaribu kituo chetu cha dev katika chrome.com/dev.</translation>
<translation id="7682287625158474539">Anwani ya Kufikishia</translation>
+<translation id="7701040980221191251">Hamna</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Nenda kwenye <ph name="SITE" /> (isiyo salama)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Cheti</translation>
+<translation id="7716147886133743102">Imezuiwa na msimamizi</translation>
<translation id="7716424297397655342">Faili hii haiwezi kupakiwa kutoka akiba</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Haidhibitiwi</translation>
<translation id="7755287808199759310">Mzazi wako anaweza kukuondolea kizuizi</translation>
<translation id="7758069387465995638">Huenda programu ya kinga-mtandao au kinga-virusi zimezuia muunganisho huu.</translation>
@@ -735,7 +809,7 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="7791543448312431591">Ongeza</translation>
<translation id="7793809570500803535">Ukurasa wa wavuti ulio kwenye <ph name="SITE" /> unaweza kuwa haupatikani kwa muda au huenda umehamishwa kabisa hadi kwenye anwani mpya ya wavuti.</translation>
<translation id="7800304661137206267">Muunganisho umesimbwa fiche kwa kutumia <ph name="CIPHER" />, kwa <ph name="MAC" /> ya uthibitishaji wa ujumbe na <ph name="KX" /> kama utaratibu muhimu wa ubadilishanaji.</translation>
-<translation id="780301667611848630">Sitaki</translation>
+<translation id="780301667611848630">La, asante</translation>
<translation id="7805768142964895445">Hali</translation>
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Ungependa kuondoa pendekezo la fomu kutoka kwenye Chrome?</translation>
@@ -751,15 +825,15 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="7951415247503192394">(biti 32)</translation>
<translation id="7956713633345437162">Alamisho kwenye simu</translation>
<translation id="7961015016161918242">Katu</translation>
-<translation id="7962083544045318153">Kitambulisho cha kuacha kufanya kazi <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Tafsiri kutoka <ph name="ORIGINAL_LANGUAGE" /> hadi <ph name="TARGET_LANGUAGE" /> kila wakati</translation>
<translation id="7995512525968007366">Hakijabainishwa</translation>
<translation id="800218591365569300">Jaribu kufunga vichupo au programu nyingine upate nafasi zaidi.</translation>
<translation id="8012647001091218357">Hatukuweza kuwafikia wazazi wako wakati huu. Tafadhali jaribu tena.</translation>
<translation id="8025119109950072390">Wavamizi kwenye tovuti hii wanaweza kukulaghai ili ufanye kitu hatari kama vile kusakinisha programu au kuonyesha maelezo yako binafsi (kwa mfano, manenosiri, nambari za simu au kadi za mikopo).</translation>
-<translation id="803030522067524905">Mfumo wa Kuvinjari Salama kwenye Google uligundua jaribio la kuhadaa ili kupata maelezo ya kibinafsi kwenye <ph name="SITE" /> hivi majuzi. Tovuti za kuhadaa ili kupata maelezo ya kibinafsi hujifanya kuwa tovuti nyingine unayoijua ili kukulaghai. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Ukurasa huu ni wa lugha ya <ph name="SOURCE_LANGUAGE" />. Je, ungependa kuutasfiri kuwa <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Uliza (chaguo-msingi)</translation>
<translation id="8041089156583427627">Tuma Maoni</translation>
+<translation id="8041940743680923270">Tumia chaguo-msingi la duniani (Uliza)</translation>
<translation id="8088680233425245692">Haikufaulu kuangalia makala.</translation>
<translation id="8089520772729574115">chini ya MB 1</translation>
<translation id="8091372947890762290">Uwashaji unasubiri kwenye seva</translation>
@@ -768,13 +842,14 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="8134994873729925007"><ph name="BEGIN_ABBR" />Anwani ya DNS <ph name="END_ABBR" /> ya seva ya <ph name="HOST_NAME" /> haikupatikana.</translation>
<translation id="8149426793427495338">Kompyuta yako iko katika hali tuli.</translation>
<translation id="8150722005171944719">Faili katika <ph name="URL" /> haisomeki. Huenda imeondolewa, kusogezwa, au idhini za faili huenda zinazuia ufikiaji.</translation>
+<translation id="8184538546369750125">Tumia chaguo-msingi la duniani (Ruhusu)</translation>
+<translation id="8191494405820426728">Kitambulisho cha Kuacha Kufanya Kazi <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">Tendua hatua</translation>
<translation id="8201077131113104583">URL ya sasisho si sahihi kwa kiendelezi chenye Kitambulisho "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Muhtasari wa agizo</translation>
<translation id="8218327578424803826">Mahali Palipohawilishwa:</translation>
<translation id="8225771182978767009">Mtu ambaye aliweka mipangilio ya kompyuta hii ameamua kuzuia tovuti hii.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Huenda wavamizi walio kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kwa sasa wakajaribu kusakinisha programu hatari ambazo zinaiba au kufuta maelezo kwenye kifaa chako (kwa mfano, picha, manenosiri, ujumbe na kadi za mkopo).</translation>
<translation id="8241707690549784388">Ukurasa unaotafuta ulitumia maelezo uliyoyaingiza. Kurudi kwenye ukurasa huo huenda kukasababisha tendo lolote ulilofanya lirudiwe. Je, ungependa kuendelea?</translation>
<translation id="8249320324621329438">Iliyoletwa mwisho:</translation>
<translation id="8253091569723639551">Anwani ya kutuma bili sharti iandikwe</translation>
@@ -782,6 +857,7 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="8289355894181816810">Wasiliana na msimamizi wako wa mtandao iwapo huna uhakika kile ambacho hiki kinamaanisha.</translation>
<translation id="8293206222192510085">Ongeza Alamisho</translation>
<translation id="8294431847097064396">Chanzo</translation>
+<translation id="8306404619377842860">Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> haujatambuliwa kwa sababu tarehe na saa za kifaa chako (<ph name="DATE_AND_TIME" />) si sahihi. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Utafsiri haukufanikiwa kwa sababu ya hitilafu ya seva.</translation>
<translation id="8332188693563227489">Ufikiaji wa <ph name="HOST_NAME" /> umekataliwa</translation>
<translation id="834457929814110454">Ikiwa unaelewa hatari kwa usalama wako, unaweza <ph name="BEGIN_LINK" />kutembelea tovuti hii<ph name="END_LINK" /> kabla programu hatari hazijaondolewa.</translation>
@@ -802,11 +878,9 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="8483780878231876732">Ili utumie kadi kutoka kwenye Akaunti yako ya Google, ingia katika Chrome</translation>
<translation id="8488350697529856933">Inatumika kwenye</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> imechukua muda mrefu kupakia.</translation>
-<translation id="852346902619691059">Seva hii haikuweza kuthibitisha kwamba ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na mfumo wa uendeshaji wa kifaa chako. Hii inatokana na uwekaji mipangilio usiofaa au mvamizi kuingilia muunganisho wako. <ph name="BEGIN_LEARN_MORE_LINK" />Pata maelezo zaidi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Mwaka wa Muda wa Matumizi Kuisha</translation>
<translation id="8543181531796978784">Unaweza <ph name="BEGIN_ERROR_LINK" />kuripoti tatizo la ugunduzi<ph name="END_ERROR_LINK" /> au, ikiwa unaelewa kiwango cha hatari kinachoweza kutokea, <ph name="BEGIN_LINK" />tembelea tovuti hii isiyo salama<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Tafsiri imeshindwa kwa sababu lugha ya ukurasa isingeweza kuthibitishwa.</translation>
-<translation id="8559762987265718583">Muunganisho wa faragha kwenye <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> hauwezi kupatikana kwa sababu tarehe na wakati wa kifaa chako (<ph name="DATE_AND_TIME" />) si sahihi.</translation>
<translation id="8571890674111243710">Inatafsiri ukurasa katika <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Ongeza simu
</translation>
@@ -821,6 +895,7 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="8738058698779197622">Ili kutambua muunganisho salama, saa yako inahitaji kuwekwa sahihi. Hii ni kwa sababu vyeti ambavyo tovuti hutumia kujitambua ni sahihi kwa vipindi mahususi pekee. Kwa kuwa saa ya kifaa chako si sahihi, Chromium haiwezi kuthibitisha vyeti hivi.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;anwani ya DNS&lt;/abbr&gt; haikupatikana. Tatizo linachunguzwa.</translation>
<translation id="8759274551635299824">Muda wa matumizi wa kadi hii umekwisha</translation>
+<translation id="8761567432415473239">Kuvinjari Salama kwa Google <ph name="BEGIN_LINK" />kulipata programu zinazodhuru<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi karibuni.</translation>
<translation id="8790007591277257123">Rudia kufuta</translation>
<translation id="8800988563907321413">Mapendekezo ya maudhui ya uhamishaji wa karibu yataonekana hapa</translation>
<translation id="8820817407110198400">Alamisho</translation>
@@ -833,29 +908,30 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="8870413625673593573">Zilizofungwa Hivi Karibuni</translation>
<translation id="8874824191258364635">Andika nambari sahihi ya kadi</translation>
<translation id="8876793034577346603">Usanidi wa mtandao umekosa kuchanganuliwa.</translation>
-<translation id="8877192140621905067">Baada ya kuthibitisha, maelezo ya kadi yako yatashirikiwa na tovuti hii</translation>
<translation id="8889402386540077796">Rangi</translation>
<translation id="8891727572606052622">Modi batili ya proksi.</translation>
<translation id="889901481107108152">Samahani, jaribio hili halipatikani kwenye mfumo wako wa uendeshaji.</translation>
<translation id="8903921497873541725">Kuza karibu</translation>
<translation id="8931333241327730545">Je, ungependa kuhifadhi kadi hii katika Akaunti yako ya Google?</translation>
<translation id="8932102934695377596">Saa yako iko nyuma</translation>
-<translation id="8954894007019320973">(Inaendelea)</translation>
<translation id="8971063699422889582">Cheti cha seva kimechina.</translation>
<translation id="8986494364107987395">Tumia Google takwimu za matumizi na ripoti za mara ambazo kivinjari kinaacha kufanya kazi, moja kwa moja</translation>
-<translation id="8987927404178983737">Mwezi</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Tovuti unayoelekea kufungua ina programu zinazodhuru</translation>
+<translation id="8997023839087525404">Seva imewasilisha cheti ambacho hakikufichuliwa hadharani kwa kutumia sera ya Uwazi wa Cheti. Hili ni hitaji kwa baadhi ya vyeti, ili kuhakikisha kwamba ni cha kuaminika na kulinda dhidi ya wavamizi.</translation>
<translation id="9001074447101275817">Seva mbadala ya <ph name="DOMAIN" /> inahitaji jina la mtumiaji na nenosiri.</translation>
+<translation id="9005998258318286617">Imeshindwa kupakia hati ya PDF.</translation>
<translation id="901974403500617787">Alama zinazotumika katika mfumo mzima zinaweza kuwekwa na mmiliki pekee: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Anwani ya kutuma bili ya kadi sharti iandikwe</translation>
<translation id="9020542370529661692">Ukurasa huu umetafsiriwa kwenda <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Hitilafu ya usalama</translation>
<translation id="9038649477754266430">Tumia huduma ya kutabiri ili upakie kurasa kwa haraka zaidi</translation>
<translation id="9039213469156557790">Mbali na hayo, ukurasa huu una rasilimali nyingine zisizo salama. Rasilimali hizi zinaweza kuangaliwa na watu wengine wanaosafiri, na zinaweza kurekebishwa na mvamizi kubadilisha tabia ya ukurasa.</translation>
-<translation id="9040185888511745258">Wavamizi kwenye <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> huenda wakajaribu kukulaghai ili kusakinisha programu zinazodhuru hali yako ya kuvinjari (kwa mfano, kwa kubadilisha ukurasa wako wa mwanzo au kuonyesha matangazo ya ziada kwenye tovuti unazotembelea).</translation>
+<translation id="9049981332609050619">Ulijaribu kufikia <ph name="DOMAIN" />, lakini seva iliwasilisha cheti batili.</translation>
<translation id="9050666287014529139">Kaulisiri</translation>
<translation id="9065203028668620118">Badilisha</translation>
<translation id="9068849894565669697">Chagua rangi</translation>
+<translation id="9069693763241529744">Imezuiwa na kiendelezi</translation>
<translation id="9076283476770535406">Huenda ina maudhui ya ngono</translation>
<translation id="9078964945751709336">Maelezo zaidi yanahitajika</translation>
<translation id="9103872766612412690">Kwa kawaida <ph name="SITE" /> hutumia usimbaji fiche ili kulinda maelezo yako. Chromium ilipojaribu kuunganisha kwenye <ph name="SITE" /> wakati huu, tovuti ilituma kitambulisho kisicho cha kawaida na kisicho sahihi. Hili linaweza kutokea mvamizi anapojaribu kujifanya kuwa <ph name="SITE" />, au uchanganuzi wa kuingia katika Wi-Fi umeingilia muunganisho. Maelezo yako yangali salama kwa sababu Chromium ilisimamisha muunganisho kabla data yoyote itumwe.</translation>
@@ -864,16 +940,21 @@ Hebu! Huenda hali fiche <ph name="SHORTCUT_KEY" /> ikakufaa wakati ujao.</transl
<translation id="9148507642005240123">Tendua kuhariri</translation>
<translation id="9154194610265714752">Imesasishwa</translation>
<translation id="9157595877708044936">Inasanidi...</translation>
+<translation id="9169664750068251925">Zuia kila wakati kwenye tovuti hii</translation>
<translation id="9170848237812810038">&amp;Tendua</translation>
<translation id="917450738466192189">Cheti cha seva ni batili.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> hutumia itifaki isiyokubalika.</translation>
<translation id="9205078245616868884">Data yako imesimbwa kwa njia fiche kwa kauli yako ya siri ya kusawazisha. Iweke ile uanze kusawazisha.</translation>
<translation id="9207861905230894330">Haikufaulu kuongeza makala.</translation>
+<translation id="9219103736887031265">Picha</translation>
<translation id="933612690413056017">Hakuna muunganisho wa Intaneti</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">FUTA FOMU</translation>
<translation id="939736085109172342">Folda mpya</translation>
<translation id="941721044073577244">Inaonekana huna ruhusa ya kutembelea tovuti hii</translation>
<translation id="969892804517981540">Muundo Rasmi</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Hamna}=1{Kipengee 1}other{Vipengee #}}</translation>
<translation id="988159990683914416">Muundo wa Wasanidi Programu</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_ta.xtb b/chromium/components/strings/components_strings_ta.xtb
index ddabd30035c..9a573d501f7 100644
--- a/chromium/components/strings/components_strings_ta.xtb
+++ b/chromium/components/strings/components_strings_ta.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">கடிகாரதà¯à®¤à®¿à®šà¯ˆà®¯à®¿à®²à¯ சà¯à®´à®±à¯à®±à¯</translation>
<translation id="1038842779957582377">அறியபà¯à®ªà®Ÿà®¾à®¤ பெயரà¯</translation>
<translation id="1050038467049342496">பிற பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆ மூடவà¯à®®à¯</translation>
-<translation id="1053591932240354961">Google Chrome ஆல௠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®¾à®¤ சிதைநà¯à®¤ அனà¯à®®à®¤à®¿à®šà¯ சானà¯à®±à¯à®•à®³à¯ˆ இணையதளம௠அனà¯à®ªà¯à®ªà®¿à®¯à¯à®³à¯à®³à®¤à®¾à®²à¯, இபà¯à®ªà¯‹à®¤à¯ <ph name="SITE" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆà®¯à¯‡. இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ சிறித௠நேரம௠கழிதà¯à®¤à¯à®šà¯ செயலà¯à®ªà®Ÿà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;சேரà¯à®¤à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
<translation id="10614374240317010">எபà¯à®ªà¯‹à®¤à¯à®®à¯ சேமிகà¯à®•à®¾à®¤à®µà¯ˆ</translation>
<translation id="106701514854093668">டெஸà¯à®•à¯à®Ÿà®¾à®ªà¯ பà¯à®•à¯à®®à®¾à®°à¯à®•à¯à®•à¯à®•à®³à¯</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">கொளà¯à®•à¯ˆ தறà¯à®•à®¾à®²à®¿à®• சேமிபà¯à®ªà¯ சரியாக உளà¯à®³à®¤à¯</translation>
<translation id="113188000913989374"><ph name="SITE" /> தெரிவிபà¯à®ªà®¤à¯:</translation>
<translation id="1132774398110320017">Chrome தனà¯à®©à®¿à®°à®ªà¯à®ªà®¿ அமைபà¯à®ªà¯à®•à®³à¯...</translation>
+<translation id="1150979032973867961">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ உஙà¯à®•à®³à¯ கணினியின௠இயகà¯à®• à®®à¯à®±à¯ˆà®®à¯ˆ நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
+<translation id="1151972924205500581">கடவà¯à®šà¯à®šà¯Šà®²à¯ தேவை</translation>
<translation id="1152921474424827756"><ph name="URL" /> இன௠<ph name="BEGIN_LINK" />உரà¯à®µà®¾à®•à¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à®¾à®© தறà¯à®•à®¾à®²à®¿à®•à®šà¯ சேமிபà¯à®ªà¯ நகலை<ph name="END_LINK" /> அணà¯à®•à®µà¯à®®à¯</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> எதிரà¯à®ªà®¾à®°à®¾à®¤ விதமாக இணைபà¯à®ªà¯ˆ நிறà¯à®¤à¯à®¤à®¿à®¯à®¤à¯.</translation>
<translation id="1161325031994447685">வைஃபையà¯à®Ÿà®©à¯ மீணà¯à®Ÿà¯à®®à¯ இணைதà¯à®¤à®²à¯</translation>
+<translation id="1165039591588034296">பிழை</translation>
<translation id="1175364870820465910">&amp;அசà¯à®šà®¿à®Ÿà¯...</translation>
<translation id="1181037720776840403">அகறà¯à®±à¯</translation>
<translation id="1184214524891303587">பாதà¯à®•à®¾à®ªà¯à®ªà®¿à®±à¯à®•à¯ இடையூற௠விளைவிகà¯à®•à¯à®®à¯ சாதà¯à®¤à®¿à®¯à®®à¯à®³à¯à®³ செயலà¯à®ªà®¾à®Ÿà¯ கà¯à®±à®¿à®¤à¯à®¤ விவரஙà¯à®•à®³à¯ˆ Googleகà¯à®•à¯à®¤à¯ <ph name="BEGIN_WHITEPAPER_LINK" />தானாகவே அனà¯à®ªà¯à®ªà¯<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">இநà¯à®¤à®¤à¯ தளம௠கூடà¯à®¤à®²à®¾à®• வழஙà¯à®•à¯à®ªà®µà¯ˆ</translation>
<translation id="1206967143813997005">தொடகà¯à®•à®•à¯ கையொபà¯à®ªà®®à¯ சரியானதலà¯à®²</translation>
<translation id="1209206284964581585">இபà¯à®ªà¯‹à®¤à¯ˆà®•à¯à®•à¯ மறை</translation>
+<translation id="121201262018556460">நீஙà¯à®•à®³à¯ <ph name="DOMAIN" /> ஠அடைய à®®à¯à®¯à®±à¯à®šà®¿à®¤à¯à®¤à¯€à®°à¯à®•à®³à¯ ஆனால௠சேவையகம௠ஒர௠வலà¯à®µà®±à¯à®± விசை கொணà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ˆ வழஙà¯à®•à®¿à®¯à®¤à¯. தனிபà¯à®ªà®Ÿà¯à®Ÿ விசையை தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ களவாடி இரà¯à®ªà¯à®ªà®¤à®¾à®²à¯, சேவையகம௠நீஙà¯à®•à®³à¯ எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤ (தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®Ÿà®©à¯ நீஙà¯à®•à®³à¯ தகவல௠பரிமாறà¯à®±à®®à¯ செயà¯à®¤à¯à®•à¯Šà®£à¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯) சேவையகமாக இலà¯à®²à®¾à®®à®²à¯ இரà¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="1219129156119358924">à®®à¯à®±à¯ˆà®®à¯ˆà®ªà¯ பாதà¯à®•à®¾à®ªà¯à®ªà¯</translation>
<translation id="1227224963052638717">அறியாத கொளà¯à®•à¯ˆ.</translation>
<translation id="1227633850867390598">மதிபà¯à®ªà¯ˆ மறை</translation>
<translation id="1228893227497259893">தவறான உடà¯à®ªà¯Šà®°à¯à®³à¯ அடையாளஙà¯à®•à®¾à®Ÿà¯à®Ÿà®¿</translation>
<translation id="1232569758102978740">தலைபà¯à®ªà®¿à®Ÿà®¾à®¤à®¤à¯</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (ஒதà¯à®¤à®¿à®šà¯ˆà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®©)</translation>
<translation id="1263231323834454256">வாசிபà¯à®ªà¯à®ªà¯ படà¯à®Ÿà®¿à®¯à®²à¯</translation>
<translation id="1264126396475825575"><ph name="CRASH_TIME" /> அனà¯à®±à¯ சிதைவ௠அறிகà¯à®•à¯ˆ பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ (இனà¯à®©à¯à®®à¯ பதிவேறà¯à®±à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ அலà¯à®²à®¤à¯ பà¯à®±à®•à¯à®•à®£à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ)</translation>
+<translation id="1281526147609854549">வழஙà¯à®•à®¿à®¯à®¤à¯: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">ஆபதà¯à®¤à®¾à®© உளà¯à®³à®Ÿà®•à¯à®•à®®à¯ தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="1285320974508926690">இநà¯à®¤ தளதà¯à®¤à¯ˆ எபà¯à®ªà¯‹à®¤à¯à®®à¯ மொழிபெயரà¯à®•à¯à®• வேணà¯à®Ÿà®¾à®®à¯</translation>
<translation id="129553762522093515">சமீபதà¯à®¤à®¿à®²à¯ மூடியவை</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />கà¯à®•à¯à®•à¯€à®•à®³à¯ˆ அழிகà¯à®•à®µà¯à®®à¯<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">இரà¯à®ªà¯à®ªà®¿à®©à¯à®®à¯, பினà¯à®µà®°à¯à®®à¯ தரபà¯à®ªà®¿à®©à®°à¯ உஙà¯à®•à®³à¯ செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆà®ªà¯ <ph name="BEGIN_EMPHASIS" />பாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à¯à®®à¯<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />நீஙà¯à®•à®³à¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà¯à®®à¯ இணையதளஙà¯à®•à®³à¯
+ <ph name="LIST_ITEM" />உஙà¯à®•à®³à¯ நிறà¯à®µà®©à®®à¯ அலà¯à®²à®¤à¯ பளà¯à®³à®¿
+ <ph name="LIST_ITEM" />உஙà¯à®•à®³à¯ இணையச௠சேவை வழஙà¯à®•à¯à®¨à®°à¯
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">பதிவà¯à®•à¯ களமà¯:</translation>
<translation id="1340482604681802745">பிகà¯à®•à®ªà¯ à®®à¯à®•à®µà®°à®¿</translation>
<translation id="1344211575059133124">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à¯à®šà¯ செலà¯à®², உஙà¯à®•à®³à¯à®•à¯à®•à¯ அனà¯à®®à®¤à®¿ தேவை</translation>
<translation id="1344588688991793829">Chromium தனà¯à®©à®¿à®°à®ªà¯à®ªà®¿ அமைபà¯à®ªà¯à®•à®³à¯...</translation>
+<translation id="1348198688976932919">தளதà¯à®¤à®¿à®²à¯ ஆபதà¯à®¤à®¾à®© பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ உளà¯à®³à®©</translation>
<translation id="1374468813861204354">பரிநà¯à®¤à¯à®°à¯ˆà®•à®³à¯</translation>
<translation id="1375198122581997741">பதிபà¯à®ªà¯ˆà®ªà¯ பறà¯à®±à®¿</translation>
<translation id="1377321085342047638">காரà¯à®Ÿà¯ எணà¯</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> எநà¯à®¤à®¤à¯ தரவையà¯à®®à¯ அனà¯à®ªà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="1407135791313364759">எலà¯à®²à®¾à®µà®±à¯à®±à¯ˆà®¯à¯à®®à¯ திற</translation>
<translation id="1413809658975081374">தனியà¯à®°à®¿à®®à¯ˆà®ªà¯ பிழை</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" /> இல௠<ph name="ORGANIZATION" /> அடையாளம௠<ph name="ISSUER" /> ஆல௠பரிசோதிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="1426410128494586442">ஆமà¯</translation>
<translation id="1430915738399379752">அசà¯à®šà®¿à®Ÿà¯à®•</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> இல௠பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà¯à®µà®¤à®±à¯à®•à®¾à®©<ph name="END_LINK" /> à®®à¯à®¯à®±à¯à®šà®¿à®¯à¯ˆ தடà¯à®¤à¯à®¤à®¤à¯.</translation>
-<translation id="1491663344921578213">இணையதளமானத௠சரà¯à®Ÿà®¿à®ƒà®ªà®¿à®•à¯‡à®Ÿà¯ பினà¯à®©à®¿à®™à¯à®•à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à®¾à®²à¯, இபà¯à®ªà¯‹à®¤à¯ <ph name="SITE" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆà®¯à¯‡. இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ சிறித௠நேரம௠கழிதà¯à®¤à¯à®šà¯ செயலà¯à®ªà®Ÿà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à®¿à®©à¯ சேமிதà¯à®¤ நகலைக௠காடà¯à®Ÿà¯ (அதாவதà¯, காலாவதியானத௠என அறியபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯).</translation>
<translation id="1517433312004943670">ஃபோன௠எண௠தேவை</translation>
<translation id="1519264250979466059">உரà¯à®µà®¾à®•à¯à®•à®¿à®¯ தேதி</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">இநà¯à®¤ à®…à®®à¯à®šà®¤à¯à®¤à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤ JavaScript இயகà¯à®•à®ªà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯.</translation>
<translation id="1555130319947370107">நீலமà¯</translation>
<translation id="1559528461873125649">இதà¯à®ªà¯‹à®©à¯à®± கோபà¯à®ªà¯ அலà¯à®²à®¤à¯ கோபà¯à®ªà®•à®®à¯ எதà¯à®µà¯à®®à®¿à®²à¯à®²à¯ˆ</translation>
-<translation id="1559572115229829303">&lt;p&gt;உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ தேதி மறà¯à®±à¯à®®à¯ நேரம௠(<ph name="DATE_AND_TIME" />) தவறாக இரà¯à®ªà¯à®ªà®¤à®¾à®²à¯ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> எனà¯à®•à®¿à®± டொமைனிறà¯à®•à¯à®¤à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ இணைபà¯à®ªà¯ˆ à®à®±à¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.&lt;/p&gt;
-
- &lt;p&gt;தேதி மறà¯à®±à¯à®®à¯ நேரதà¯à®¤à¯ˆ &lt;strong&gt;அமைபà¯à®ªà¯à®•à®³à¯&lt;/strong&gt; பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®©à¯ &lt;strong&gt;பொதà¯&lt;/strong&gt; எனà¯à®•à®¿à®± பகà¯à®¤à®¿à®¯à®¿à®²à¯ மாறà¯à®±à®µà¯à®®à¯.&lt;/p&gt;</translation>
<translation id="1583429793053364125">இநà¯à®¤ இணையபà¯à®ªà®•à¯à®•à®¤à¯à®¤à¯ˆà®•à¯ காடà¯à®Ÿà¯à®®à¯à®ªà¯‹à®¤à¯ à®à®¤à¯‹ தவற௠à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="1592005682883173041">அகத௠தரவ௠அணà¯à®•à®²à¯</translation>
+<translation id="1594030484168838125">தேரà¯à®µà¯à®šà¯†à®¯à¯</translation>
<translation id="161042844686301425">சியானà¯</translation>
+<translation id="1620510694547887537">கேமரா</translation>
<translation id="1629803312968146339">இநà¯à®¤à®•à¯ காரà¯à®Ÿà¯ˆ Chrome சேமிகà¯à®• வேணà¯à®Ÿà¯à®®à®¾?</translation>
<translation id="1639239467298939599">à®à®±à¯à®±à¯à®•à®¿à®±à®¤à¯</translation>
<translation id="1640180200866533862">பயனர௠கொளà¯à®•à¯ˆà®•à®³à¯</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">பிணைய உளà¯à®³à®®à¯ˆà®µà¯ தவறானத௠மேலà¯à®®à¯ அதை இறகà¯à®•à¯à®®à®¤à®¿ செயà¯à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="1644574205037202324">வரலாறà¯</translation>
<translation id="1645368109819982629">ஆதரிகà¯à®•à®ªà¯à®ªà®Ÿà®¾à®¤ நெறிமà¯à®±à¯ˆ</translation>
+<translation id="1655462015569774233">{1,plural, =1{இநà¯à®¤à®šà¯ சேவையகம௠தான௠<ph name="DOMAIN" /> எனà¯à®ªà®¤à¯ˆ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ நேறà¯à®±à¯ காலாவதியானதà¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. உஙà¯à®•à®³à¯ கணினியின௠கடிகாரம௠தறà¯à®ªà¯‹à®¤à¯ <ph name="CURRENT_DATE" /> என அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯. அத௠சரியாக இரà¯à®•à¯à®•à®¿à®±à®¤à®¾? இலà¯à®²à¯ˆ எனà¯à®±à®¾à®²à¯, உஙà¯à®•à®³à¯ à®®à¯à®±à¯ˆà®®à¯ˆà®¯à®¿à®©à¯ கடிகாரதà¯à®¤à¯ˆà®šà¯ சரிசெயà¯à®¤à¯, பினà¯à®©à®°à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பà¯à®¤à¯à®ªà¯à®ªà®¿à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯.}other{இநà¯à®¤à®šà¯ சேவையகம௠தான௠<ph name="DOMAIN" /> எனà¯à®ªà®¤à¯ˆ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ # நாடà¯à®•à®³à¯à®•à¯à®•à¯ à®®à¯à®©à¯à®ªà¯ காலாவதியானதà¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. உஙà¯à®•à®³à¯ கணினியின௠கடிகாரம௠தறà¯à®ªà¯‹à®¤à¯ <ph name="CURRENT_DATE" /> என அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯. அத௠சரியாக இரà¯à®•à¯à®•à®¿à®±à®¤à®¾? இலà¯à®²à¯ˆ எனà¯à®±à®¾à®²à¯, உஙà¯à®•à®³à¯ à®®à¯à®±à¯ˆà®®à¯ˆà®¯à®¿à®©à¯ கடிகாரதà¯à®¤à¯ˆà®šà¯ சரிசெயà¯à®¤à¯, பினà¯à®©à®°à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பà¯à®¤à¯à®ªà¯à®ªà®¿à®•à¯à®• வேணà¯à®Ÿà¯à®®à¯.}}</translation>
<translation id="1656489000284462475">பிகà¯à®•à®ªà¯</translation>
<translation id="1663943134801823270">காரà¯à®Ÿà¯à®•à®³à¯à®®à¯ à®®à¯à®•à®µà®°à®¿à®•à®³à¯à®®à¯ Chrome இலிரà¯à®¨à¯à®¤à¯ பெறபà¯à®ªà®Ÿà¯à®Ÿà®µà¯ˆà®¯à®¾à®•à¯à®®à¯. <ph name="BEGIN_LINK" />அமைபà¯à®ªà¯à®•à®³à®¿à®²à¯<ph name="END_LINK" /> அவறà¯à®±à¯ˆ நிரà¯à®µà®•à®¿à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="1676269943528358898">வழகà¯à®•à®®à®¾à®•, <ph name="SITE" /> உஙà¯à®•à®³à¯ தகவலைப௠பாதà¯à®•à®¾à®ªà¯à®ªà®¤à®±à¯à®•à®¾à®• à®®à¯à®±à¯ˆà®®à¯ˆà®¯à®¾à®•à¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯. இநà¯à®¤ à®®à¯à®±à¯ˆ <ph name="SITE" /> உடன௠இணைவதறà¯à®•à¯ Google Chrome à®®à¯à®¯à®±à¯à®šà®¿à®¤à¯à®¤à®ªà¯‹à®¤à¯ வழகà¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ மாறான மறà¯à®±à¯à®®à¯ தவறான நறà¯à®šà®¾à®©à¯à®±à®¿à®¤à®´à¯à®•à®³à¯ˆ இணையதளம௠வழஙà¯à®•à®¿à®¯à®¤à¯. தாகà¯à®•à¯à®ªà®µà®°à¯ தனà¯à®©à¯ˆ <ph name="SITE" /> ஆகக௠காடà¯à®Ÿ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à¯à®®à¯ போத௠அலà¯à®²à®¤à¯ இணைபà¯à®ªà¯ˆ வைஃபை உளà¯à®¨à¯à®´à¯ˆà®µà¯à®¤à¯ திரை கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®®à¯ போத௠இத௠à®à®±à¯à®ªà®Ÿà®²à®¾à®®à¯. இரà¯à®ªà¯à®ªà®¿à®©à¯à®®à¯, தரவ௠எதà¯à®µà¯à®®à¯ பரிமாறà¯à®±à®ªà¯à®ªà®Ÿà¯à®µà®¤à®±à¯à®•à¯ à®®à¯à®©à¯ Google Chrome இணைபà¯à®ªà¯ˆ நிறà¯à®¤à¯à®¤à®¿à®¯à®¤à®¾à®²à¯ உஙà¯à®•à®³à¯ தகவல௠பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®•à®µà¯‡ இரà¯à®•à¯à®•à®¿à®±à®¤à¯.</translation>
-<translation id="168328519870909584"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à®¿à®°à¯à®•à¯à®•à¯à®®à¯ தாகà¯à®•à¯à®ªà®µà®°à¯à®•à®³à¯, உஙà¯à®•à®³à¯ தகவலைத௠(எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, படஙà¯à®•à®³à¯, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯ மறà¯à®±à¯à®®à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) திரà¯à®Ÿà®•à¯à®•à¯‚டிய அலà¯à®²à®¤à¯ நீகà¯à®•à®•à¯à®•à¯‚டிய தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆ உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®²à¯ நிறà¯à®µ à®®à¯à®¯à®±à¯à®šà®¿à®¤à¯à®¤à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="168841957122794586">சேவையக சானà¯à®±à®¿à®¤à®´à®¿à®²à¯ வலà¯à®µà®±à¯à®± கà¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà®¾à®•à¯à®• விசை இரà¯à®•à¯à®•à®¿à®±à®¤à¯.</translation>
+<translation id="1706954506755087368">{1,plural, =1{இநà¯à®¤à®šà¯ சேவையகம௠தான௠<ph name="DOMAIN" /> எனà¯à®ªà®¤à¯ˆ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ நாளை à®®à¯à®¤à®²à¯‡ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à¯à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.}other{இநà¯à®¤à®šà¯ சேவையகம௠தான௠<ph name="DOMAIN" /> எனà¯à®ªà®¤à¯ˆ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ எதிரà¯à®•à®¾à®²à®¤à¯à®¤à®¿à®²à¯ # நாடà¯à®•à®³à®¿à®²à¯ à®à®±à¯à®±à¯à®•à¯à®•à¯Šà®³à¯à®³à®ªà¯à®ªà®Ÿà¯à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à¯à®šà¯ செலà¯à®², <ph name="NAME" /> இன௠அனà¯à®®à®¤à®¿ வேணà¯à®Ÿà¯à®®à¯</translation>
<translation id="1721424275792716183">* அவசியமான பà¯à®²à®®à¯</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பினà¯à®©à®°à¯ பதிவிறகà¯à®•à¯</translation>
<translation id="17513872634828108">தாவலà¯à®•à®³à¯ˆà®¤à¯ திற</translation>
<translation id="1753706481035618306">பகà¯à®• எணà¯</translation>
+<translation id="1763864636252898013">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ இயகà¯à®• à®®à¯à®±à¯ˆà®®à¯ˆ நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows நெடà¯à®µà¯Šà®°à¯à®•à¯ டயகà¯à®©à®¸à¯à®Ÿà®¿à®•à¯à®¸à¯ கரà¯à®µà®¿à®¯à¯ˆ இயகà¯à®•à®µà¯à®®à¯<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">உஙà¯à®•à®³à®¿à®©à¯ ஒதà¯à®¤à®¿à®šà¯ˆ சொறà¯à®±à¯Šà®Ÿà®°à¯ˆà®ªà¯ பà¯à®¤à¯à®ªà¯à®ªà®¿à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="1787142507584202372">உஙà¯à®•à®³à¯ தாவலà¯à®•à®³à¯ இஙà¯à®•à¯‡ தோனà¯à®±à¯à®®à¯</translation>
+<translation id="1789575671122666129">பாப௠அபà¯à®•à®³à¯</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">காரà¯à®Ÿà¯ உரிமையாளரின௠பெயரà¯</translation>
-<translation id="1803678881841855883">சமீபதà¯à®¤à®¿à®²à¯ Google இன௠பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© உலாவலானத௠<ph name="SITE" /> இல௠<ph name="BEGIN_LINK" />தீமà¯à®ªà¯Šà®°à¯à®³à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à¯à®³à¯à®³à®¤à¯<ph name="END_LINK" />. பொதà¯à®µà®¾à®•à®ªà¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®• இரà¯à®•à¯à®•à¯à®®à¯ இணையதளஙà¯à®•à®³à¯ சில நேரஙà¯à®•à®³à®¿à®²à¯ தீமà¯à®ªà¯Šà®°à¯à®³à®¾à®²à¯ பாதிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®µà®¤à¯à®£à¯à®Ÿà¯. தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ உளà¯à®³à®Ÿà®•à¯à®•à®®à®¾à®©à®¤à¯ பிரபலமான <ph name="SUBRESOURCE_HOST" /> எனà¯à®®à¯ தீமà¯à®ªà¯Šà®°à¯à®³à¯ வழஙà¯à®•à¯à®¨à®°à®¿à®Ÿà®®à®¿à®°à¯à®¨à¯à®¤à¯ வரà¯à®•à®¿à®±à®¤à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">சேரà¯à®¤à¯à®¤à®¤à¯: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">தவறான கோரிகà¯à®•à¯ˆ அலà¯à®²à®¤à¯ கோரிகà¯à®•à¯ˆ அளவà¯à®°à¯à®•à¯à®•à®³à¯</translation>
<translation id="1826516787628120939">சரிபாரà¯à®•à¯à®•à®¿à®±à®¤à¯</translation>
<translation id="1834321415901700177">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ நிரலà¯à®•à®³à¯ உளà¯à®³à®©</translation>
+<translation id="1840414022444569775">இநà¯à®¤à®•à¯ காரà¯à®Ÿà¯ எண௠à®à®±à¯à®•à®©à®µà¯‡ சேரà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯</translation>
<translation id="1842969606798536927">பணம௠செலà¯à®¤à¯à®¤à¯à®•</translation>
<translation id="1871208020102129563">நிலையான பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையகஙà¯à®•à®³à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤ பà¯à®°à®¾à®•à¯à®¸à®¿ அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯, .pac ஸà¯à®•à®¿à®°à®¿à®ªà¯à®Ÿà¯ URL அலà¯à®².</translation>
<translation id="1871284979644508959">அவசியமà¯</translation>
<translation id="187918866476621466">தà¯à®µà®•à¯à®•à®ªà¯ பகà¯à®•à®™à¯à®•à®³à¯ˆà®¤à¯ திற</translation>
<translation id="1883255238294161206">படà¯à®Ÿà®¿à®¯à®²à¯ˆà®šà¯ சà¯à®°à¯à®•à¯à®•à¯</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">வடிகடà¯à®Ÿà¯à®¤à®²à¯</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{à®à®¤à¯à®®à®¿à®²à¯à®²à¯ˆ}=1{1 தளமà¯}other{# தளஙà¯à®•à®³à¯}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> கà¯à®•à¯à®šà¯ செலà¯à®•</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> பà¯à®¤à¯à®¤à®•à®•à¯à®•à¯à®±à®¿à®•à®³à¯</translation>
<translation id="1973335181906896915">தொடராகà¯à®• பிழை</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> ஆல௠கொளà¯à®•à¯ˆ மேலெழà¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à®¾à®²à¯ பà¯à®±à®•à¯à®•à®£à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="2138201775715568214">à®…à®°à¯à®•à®¿à®²à¯à®³à¯à®³ இயலà¯à®¨à®¿à®²à¯ˆ இணையப௠பகà¯à®•à®™à¯à®•à®³à¯ˆà®¤à¯ தேடà¯à®•à®¿à®±à®¤à¯</translation>
<translation id="213826338245044447">மொபைல௠பà¯à®•à¯à®®à®¾à®°à¯à®•à¯à®•à¯à®•à®³à¯</translation>
-<translation id="2148716181193084225">இனà¯à®±à¯</translation>
+<translation id="2147827593068025794">பினà¯à®ªà¯à®² ஒதà¯à®¤à®¿à®šà¯ˆà®µà¯</translation>
<translation id="2154054054215849342">உஙà¯à®•à®³à¯ டொமைனà¯à®•à¯à®•à¯ ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤à®²à¯ சேவை à®®à¯à®Ÿà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯</translation>
<translation id="2154484045852737596">காரà¯à®Ÿà¯ˆà®¤à¯ திரà¯à®¤à¯à®¤à®µà¯à®®à¯</translation>
<translation id="2166049586286450108">à®®à¯à®´à¯ நிரà¯à®µà®¾à®•à®¿ அணà¯à®•à®²à¯</translation>
<translation id="2166378884831602661">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¾à®²à¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© இணைபà¯à®ªà¯ˆ வழஙà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="2181821976797666341">கொளà¯à®•à¯ˆà®•à®³à¯</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 à®®à¯à®•à®µà®°à®¿}other{# à®®à¯à®•à®µà®°à®¿à®•à®³à¯}}</translation>
+<translation id="2187317261103489799">கணà¯à®Ÿà®±à®¿ (இயலà¯à®ªà¯)</translation>
<translation id="2202020181578195191">சரியான காலாவதி ஆணà¯à®Ÿà¯ˆ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
<translation id="2212735316055980242">கொளà¯à®•à¯ˆ காணபà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="2213606439339815911">உளà¯à®³à¯€à®Ÿà¯à®•à®³à¯ˆà®ªà¯ பெறà¯à®•à®¿à®±à®¤à¯...</translation>
+<translation id="2218879909401188352">தறà¯à®ªà¯‹à®¤à¯ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> எனà¯à®®à¯ தளதà¯à®¤à®¿à®²à¯ உளà¯à®³ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯ உஙà¯à®•à®³à¯ சாதனதà¯à®¤à¯ˆà®šà¯ சேதபà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯ ஆபதà¯à®¤à®¾à®© பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆ நிறà¯à®µà®²à®¾à®®à¯, மொபைல௠கடà¯à®Ÿà®£à®¤à¯à®¤à®¿à®²à¯ மறைமà¯à®•à®•à¯ கடà¯à®Ÿà®£à®™à¯à®•à®³à¯ˆà®šà¯ சேரà¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலைத௠திரà¯à®Ÿà®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />கணà¯à®Ÿà®±à®¿à®¯à¯à®®à¯ பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆà®ªà¯<ph name="END_LINK" /> பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ இணைபà¯à®ªà¯ˆà®šà¯ சரிசெயà¯à®¯à®µà¯à®®à¯</translation>
<translation id="2239100178324503013">இபà¯à®ªà¯‹à®¤à¯‡ அனà¯à®ªà¯à®ªà¯</translation>
<translation id="225207911366869382">இநà¯à®¤ கொளà¯à®•à¯ˆà®•à¯à®•à®¾à®© மதிபà¯à®ªà¯ தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="2262243747453050782">HTTP பிழை</translation>
+<translation id="2270484714375784793">தொலைபேசி எணà¯</translation>
<translation id="2282872951544483773">கிடைகà¯à®•à®¾à®¤ பரிசோதனைகளà¯</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> உரà¯à®ªà¯à®ªà®Ÿà®¿}other{<ph name="ITEM_COUNT" /> உரà¯à®ªà¯à®ªà®Ÿà®¿à®•à®³à¯}}</translation>
<translation id="2292556288342944218">உஙà¯à®•à®³à¯ இணைய அணà¯à®•à®²à¯ தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="230155334948463882">பà¯à®¤à®¿à®¯ அடà¯à®Ÿà¯ˆà®¯à®¾?</translation>
-<translation id="2305919008529760154"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. அதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ தவறான à®®à¯à®±à¯ˆà®¯à®¿à®²à¯ வழஙà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" />கà¯à®•à¯à®ªà¯ பயனரà¯à®ªà¯†à®¯à®°à¯à®®à¯ கடவà¯à®šà¯à®šà¯Šà®²à¯à®²à¯à®®à¯ தேவை.</translation>
-<translation id="2318774815570432836"><ph name="SITE" /> இணையதளம௠HSTSà®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à®¾à®²à¯, இபà¯à®ªà¯‹à®¤à¯ அதà¯à®¤à®³à®¤à¯à®¤à®¿à®±à¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆà®¯à¯‡. இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ சிறித௠நேரம௠கழிதà¯à®¤à¯à®šà¯ செயலà¯à®ªà®Ÿà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">அமைபà¯à®ªà¯ˆ உஙà¯à®•à®³à¯ நிரà¯à®µà®¾à®•à®¿ கடà¯à®Ÿà¯à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¾à®°à¯</translation>
<translation id="2354001756790975382">பிற பà¯à®•à¯à®®à®¾à®°à¯à®•à¯à®¸à¯</translation>
+<translation id="2354430244986887761">சமீபதà¯à®¤à®¿à®²à¯ Google பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© தேடலானத௠<ph name="SITE" /> இல௠<ph name="BEGIN_LINK" />தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à®¤à¯<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ நீஙà¯à®•à®³à¯ பாரà¯à®¤à¯à®¤à¯à®•à¯ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®•à¯à®®à¯ படஙà¯à®•à®³à¯ˆ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯à®®à¯ பாரà¯à®¤à¯à®¤à¯, அவறà¯à®±à¯ˆ மாறà¯à®±à®¿à®¯à®®à¯ˆà®¤à¯à®¤à¯ உஙà¯à®•à®³à¯ˆ à®à®®à®¾à®±à¯à®±à®•à¯à®•à¯‚டà¯à®®à¯.</translation>
+<translation id="2356070529366658676">கேளà¯</translation>
+<translation id="2359629602545592467">பல</translation>
<translation id="2359808026110333948">தொடரà¯à®•</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> அனà¯à®±à¯ பெறà¯à®± சிதைவ௠அறிகà¯à®•à¯ˆ பதிவேறà¯à®±à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="2367567093518048410">நிலை</translation>
-<translation id="2371153335857947666">{1,plural, =1{<ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ நேறà¯à®±à¯ காலாவதியாகிவிடà¯à®Ÿà®¤à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. உஙà¯à®•à®³à¯ கணினியின௠கடிகாரம௠தறà¯à®ªà¯‹à®¤à¯ <ph name="CURRENT_DATE" /> என அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯. அத௠சரியாக உளà¯à®³à®¤à®¾? இலà¯à®²à¯ˆà®¯à¯†à®©à®¿à®²à¯, கணினியின௠கடிகாரதà¯à®¤à¯ˆà®šà¯ சரிசெயà¯à®¤à¯, இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பà¯à®¤à¯à®ªà¯à®ªà®¿à®•à¯à®•à®µà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.}other{<ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ # நாடà¯à®•à®³à¯à®•à¯à®•à¯ à®®à¯à®©à¯ காலாவதியாகிவிடà¯à®Ÿà®¤à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. உஙà¯à®•à®³à¯ கணினியின௠கடிகாரம௠தறà¯à®ªà¯‹à®¤à¯ <ph name="CURRENT_DATE" /> என அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯. அத௠சரியாக உளà¯à®³à®¤à®¾? இலà¯à®²à¯ˆà®¯à¯†à®©à®¿à®²à¯,கணினியின௠கடிகாரதà¯à®¤à¯ˆà®šà¯ சரிசெயà¯à®¤à¯, இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பà¯à®¤à¯à®ªà¯à®ªà®¿à®•à¯à®•à®µà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">UI மாறà¯à®±à¯à®•à®³à¯ இலà¯à®²à¯ˆ</translation>
<translation id="2384307209577226199">நிறà¯à®µà®© இயலà¯à®ªà¯à®¨à®¿à®²à¯ˆ</translation>
<translation id="2386255080630008482">சேவையகச௠சானà¯à®±à®¿à®¤à®´à¯ திரà¯à®®à¯à®ªà®ªà¯ பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="2392959068659972793">மதிபà¯à®ªà¯à®®à¯ எதà¯à®µà¯à®®à¯ அமைகà¯à®•à®ªà¯à®ªà®Ÿà®¾à®¤ கொளà¯à®•à¯ˆà®•à®³à¯ˆà®•à¯ காடà¯à®Ÿà¯</translation>
<translation id="239429038616798445">இநà¯à®¤ ஷிபà¯à®ªà®¿à®™à¯ à®®à¯à®±à¯ˆ இலà¯à®²à¯ˆ. வேற௠மà¯à®±à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®ªà¯ பாரà¯à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="2396249848217231973">&amp;நீகà¯à®•à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
-<translation id="2460160116472764928">சமீபதà¯à®¤à®¿à®²à¯ Google இன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯ உலாவலானத௠<ph name="SITE" /> இல௠<ph name="BEGIN_LINK" />தீமà¯à®ªà¯Šà®°à¯à®³à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à¯à®³à¯à®³à®¤à¯<ph name="END_LINK" />. பொதà¯à®µà®¾à®•à®ªà¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®• இரà¯à®•à¯à®•à¯à®®à¯ இணையதளஙà¯à®•à®³à¯ சில நேரஙà¯à®•à®³à®¿à®²à¯ தீமà¯à®ªà¯Šà®°à¯à®³à®¾à®²à¯ பாதிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®µà®¤à¯à®£à¯à®Ÿà¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ திரà¯à®®à¯à®ªà®ªà¯à®ªà¯†à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="2463739503403862330">நிரபà¯à®ªà¯</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />நெடà¯à®µà¯Šà®°à¯à®•à¯ டயகà¯à®©à®¸à¯à®Ÿà®¿à®•à¯à®¸à¯ கரà¯à®µà®¿à®¯à¯ˆ இயகà¯à®•à®µà¯à®®à¯<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">தவறான தேடல௠URL.</translation>
+<translation id="2482878487686419369">அறிவிபà¯à®ªà¯à®•à®³à¯</translation>
<translation id="2491120439723279231">சேவையகச௠சானà¯à®±à®¿à®¤à®´à®¿à®²à¯ பிழைகள௠உளà¯à®³à®©.</translation>
<translation id="2495083838625180221">JSON பாரà¯à®šà®°à¯</translation>
<translation id="2495093607237746763">இத௠தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯, விரைவாகப௠படிவதà¯à®¤à¯ˆ நிரபà¯à®ª, உஙà¯à®•à®³à¯ காரà¯à®Ÿà®¿à®©à¯ நகலை Chromium இநà¯à®¤à®šà¯ சாதனதà¯à®¤à®¿à®²à¯ சேமிகà¯à®•à¯à®®à¯.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">திரà¯à®®à¯à®ªà®¿à®šà¯ செலà¯</translation>
<translation id="2515629240566999685">உஙà¯à®•à®³à¯ பகà¯à®¤à®¿à®¯à®¿à®²à¯ உளà¯à®³ சிகà¯à®©à®²à¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à®²à¯</translation>
<translation id="2516305470678292029">UI மாறà¯à®±à¯à®•à®³à¯</translation>
+<translation id="2539524384386349900">கணà¯à®Ÿà®±à®¿</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> தவறான பதிலை அனà¯à®ªà¯à®ªà®¿à®¯à®¤à¯.</translation>
-<translation id="2552545117464357659">பà¯à®¤à®¿à®¯à®¤à¯</translation>
<translation id="2556876185419854533">&amp;திரà¯à®¤à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
<translation id="2587730715158995865">வெளியீடà¯à®Ÿà®¾à®³à®°à¯: <ph name="ARTICLE_PUBLISHER" />. இதையà¯à®®à¯ பிற வெளியீடà¯à®Ÿà®¾à®³à®°à¯à®•à®³à¯ வழஙà¯à®•à¯à®®à¯ <ph name="OTHER_ARTICLE_COUNT" /> கடà¯à®Ÿà¯à®°à¯ˆà®•à®³à¯ˆà®¯à¯à®®à¯ படிகà¯à®•à®µà¯à®®à¯.</translation>
<translation id="2587841377698384444">கோபà¯à®ªà®• API à®à®Ÿà®¿:</translation>
<translation id="2597378329261239068">இநà¯à®¤ ஆவணம௠கடவà¯à®šà¯à®šà¯Šà®²à¯ பாதà¯à®•à®¾à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ ஒனà¯à®±à¯. தயவà¯à®šà¯†à®¯à¯à®¤à¯ ஒர௠கடவà¯à®šà¯à®šà¯Šà®²à¯à®²à¯ˆ உளà¯à®³à®¿à®Ÿà¯à®•.</translation>
<translation id="2609632851001447353">வேறà¯à®ªà®¾à®Ÿà¯à®•à®³à¯</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{à®à®¤à¯à®®à®¿à®²à¯à®²à¯ˆ}=1{1 பயனà¯à®ªà®¾à®Ÿà¯ ($1)}=2{2 பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ ($1, $2)}other{# பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">உஙà¯à®•à®³à¯ கடிகாரம௠மிகவà¯à®®à¯ à®®à¯à®©à¯à®©à¯‹à®•à¯à®•à®¿ இரà¯à®•à¯à®•à®¿à®±à®¤à¯</translation>
<translation id="2639739919103226564">நிலை:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">கோபà¯à®ªà®¿à®±à¯à®•à®¾à®© அணà¯à®•à®²à¯ மறà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="2653659639078652383">சமரà¯à®ªà¯à®ªà®¿</translation>
<translation id="2666117266261740852">பிற தாவலà¯à®•à®³à¯ அலà¯à®²à®¤à¯ பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆ மூடவà¯à®®à¯</translation>
+<translation id="2670429602441959756">VR இல௠இனà¯à®©à¯à®®à¯ ஆதரிகà¯à®•à®ªà¯à®ªà®Ÿà®¾à®¤ à®…à®®à¯à®šà®™à¯à®•à®³à¯, இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à®¿à®²à¯ உளà¯à®³à®©. வெளியேறà¯à®•à®¿à®±à®¤à¯...</translation>
<translation id="2674170444375937751">உஙà¯à®•à®³à¯ வரலாறà¯à®±à®¿à®²à®¿à®°à¯à®•à¯à®•à¯à®®à¯ பகà¯à®•à®™à¯à®•à®³à¯ˆ நிசà¯à®šà®¯à®®à®¾à®• நீகà¯à®• விரà¯à®®à¯à®ªà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾?</translation>
<translation id="2677748264148917807">வெளியேறà¯</translation>
-<translation id="269990154133806163">சானà¯à®±à®¿à®¤à®´à¯ வெளிபà¯à®ªà®Ÿà¯ˆà®¤à¯à®¤à®©à¯à®®à¯ˆ கொளà¯à®•à¯ˆà®¯à®¿à®©à¯à®ªà®Ÿà®¿ பொதà¯à®µà®¿à®²à¯ வெளியிடபà¯à®ªà®Ÿà®¾à®¤ சானà¯à®±à®¿à®¤à®´à¯ˆ சேவையகம௠வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¤à¯. சில சானà¯à®±à®¿à®¤à®´à¯à®•à®³à®¿à®©à¯ நமà¯à®ªà®•à®¤à¯à®¤à®©à¯à®®à¯ˆà®¯à¯ˆà®¯à¯à®®à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯à®•à¯à®•à¯ எதிரான பாதà¯à®•à®¾à®ªà¯à®ªà¯ˆà®¯à¯à®®à¯ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¯, இத௠அவசியமாகà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">வாசிபà¯à®ªà¯à®ªà¯ படà¯à®Ÿà®¿à®¯à®²à¯</translation>
<translation id="2704283930420550640">மதிபà¯à®ªà®¾à®©à®¤à¯ வடிவமைபà¯à®ªà®¿à®±à¯à®•à¯à®ªà¯ பொரà¯à®¨à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="2704951214193499422">இபà¯à®ªà¯‹à®¤à¯ உஙà¯à®•à®³à¯ காரà¯à®Ÿà¯ˆ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. பிறக௠மà¯à®¯à®²à®µà¯à®®à¯.</translation>
<translation id="2705137772291741111">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®©à¯ சேமிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ (தறà¯à®•à®¾à®²à®¿à®•à®šà¯ சேமிபà¯à®ªà¯) நகலைப௠படிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="2709516037105925701">தானாகநிரபà¯à®ªà¯</translation>
-<translation id="2712118517637785082"><ph name="DOMAIN" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®¯à®©à¯à®±à¯€à®°à¯à®•à®³à¯, ஆனால௠சேவையகம௠வழஙà¯à®•à®¿à®¯ சானà¯à®±à®¿à®¤à®´à¯ அதன௠வழஙà¯à®•à¯à®¨à®°à®¾à®²à¯ ரதà¯à®¤à¯à®šà¯†à®¯à¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯. ஆகையாலà¯, சேவையகம௠வழஙà¯à®•à®¿à®¯ அனà¯à®®à®¤à®¿à®šà¯ சானà¯à®±à¯à®•à®³à¯ˆ நமà¯à®ª வேணà¯à®Ÿà®¾à®®à¯. நீஙà¯à®•à®³à¯ தொடரà¯à®ªà¯à®•à¯Šà®£à¯à®Ÿà®¿à®°à¯à®ªà¯à®ªà®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®¾à®³à®°à®¾à®• இரà¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">அனà¯à®®à®¤à®¿ கேளà¯</translation>
<translation id="2713444072780614174">வெளà¯à®³à¯ˆ</translation>
<translation id="2720342946869265578">à®…à®°à¯à®•à®¿à®²à¯à®³à¯à®³à®µà¯ˆ</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">சாதனப௠பதிவ௠இலà¯à®²à¯ˆ</translation>
<translation id="2784949926578158345">இணைபà¯à®ªà¯ மீடà¯à®Ÿà®®à¯ˆà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="2794233252405721443">தளம௠தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
+<translation id="2799020568854403057">தளதà¯à®¤à®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ உளà¯à®³à®©</translation>
+<translation id="2803306138276472711">Google பாதà¯à®•à®¾à®ªà¯à®ªà¯ உலாவலானத௠சமீபதà¯à®¤à®¿à®²à¯ <ph name="SITE" /> இல௠<ph name="BEGIN_LINK" />தீமà¯à®ªà¯Šà®°à¯à®³à¯ உளà¯à®³à®¤à¯ˆà®•à¯ கணà¯à®Ÿà¯à®ªà®¿à®Ÿà®¿à®¤à¯à®¤à®¤à¯<ph name="END_LINK" />. இயலà¯à®ªà®¾à®•à®µà¯‡ பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®• இரà¯à®•à¯à®•à¯à®®à¯ இணையதளஙà¯à®•à®³à¯à®®à¯ சில சமயஙà¯à®•à®³à®¿à®²à¯ தீமà¯à®ªà¯Šà®°à¯à®³à®¿à®©à®¾à®²à¯ பாதிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à¯à®®à¯.</translation>
<translation id="2824775600643448204">à®®à¯à®•à®µà®°à®¿ மறà¯à®±à¯à®®à¯ தேடல௠படà¯à®Ÿà®¿</translation>
<translation id="2826760142808435982">இநà¯à®¤ இணைபà¯à®ªà¯ <ph name="CIPHER" /> à®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ கà¯à®±à®¿à®¯à®¾à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯, à®…à®™à¯à®•à¯€à®•à®°à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯, ஒர௠மà¯à®•à¯à®•à®¿à®¯ பரிமாறà¯à®± செயலà¯à®®à¯à®±à¯ˆà®¯à®¾à®• <ph name="KX" /> à®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯.</translation>
<translation id="2835170189407361413">படிவதà¯à®¤à¯ˆ அழி</translation>
+<translation id="2856444702002559011"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ ஹேகà¯à®•à®°à¯à®•à®³à¯ உஙà¯à®•à®³à¯ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯ அலà¯à®²à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) திரà¯à®Ÿ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">மீணà¯à®Ÿà¯à®®à¯ à®à®±à¯à®± வேணà¯à®Ÿà®¾à®®à¯</translation>
<translation id="2900469785430194048">நினைவகப௠பறà¯à®±à®¾à®•à¯à®•à¯à®±à¯ˆà®¯à®¿à®©à®¾à®²à¯, Google Chrome இநà¯à®¤ இணையபà¯à®ªà®•à¯à®•à®¤à¯à®¤à¯ˆà®•à¯ காடà¯à®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="2909946352844186028">பிணைய மாறà¯à®±à®®à¯ கணà¯à®Ÿà®±à®¿à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="2916038427272391327">பிற நிரலà¯à®•à®³à¯ˆ மூடவà¯à®®à¯</translation>
<translation id="2922350208395188000">சேவையகச௠சானà¯à®±à®¿à®¤à®´à¯ˆ சோதிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="2928905813689894207">பிலà¯à®²à®¿à®™à¯ à®®à¯à®•à®µà®°à®¿</translation>
+<translation id="2941952326391522266">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ <ph name="DOMAIN2" /> இலிரà¯à®¨à¯à®¤à¯ பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="2948083400971632585">இணைபà¯à®ªà®¿à®±à¯à®•à®¾à®• உளà¯à®³à®®à¯ˆà®¤à¯à®¤ எநà¯à®¤ பிராகà¯à®šà®¿à®•à®³à¯ˆà®¯à¯à®®à¯ நீஙà¯à®•à®³à¯ அமைபà¯à®ªà¯à®•à®³à¯ பகà¯à®•à®¤à¯à®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ à®®à¯à®Ÿà®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="2955913368246107853">தேடல௠பெடà¯à®Ÿà®¿à®¯à¯ˆ மூடà¯à®•</translation>
<translation id="2958431318199492670">பிணைய உளà¯à®³à®®à¯ˆà®ªà¯à®ªà®¾à®©à®¤à¯ ONC தரதà¯à®¤à¯à®Ÿà®©à¯ இணஙà¯à®•à®µà®¿à®²à¯à®²à¯ˆ. உளà¯à®³à®®à¯ˆà®µà®¿à®©à¯ பகà¯à®¤à®¿à®•à®³à¯ இறகà¯à®•à¯à®®à®¤à®¿à®¯à®¾à®•à®¾à®®à®²à¯ போககà¯à®•à¯‚டà¯à®®à¯.</translation>
-<translation id="29611076221683977"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à®¿à®°à¯à®•à¯à®•à¯à®®à¯ தாகà¯à®•à¯à®ªà®µà®°à¯à®•à®³à¯, உஙà¯à®•à®³à¯ தகவலைத௠(எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, படஙà¯à®•à®³à¯, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯ மறà¯à®±à¯à®®à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) திரà¯à®Ÿà®•à¯à®•à¯‚டிய அலà¯à®²à®¤à¯ நீகà¯à®•à®•à¯à®•à¯‚டிய தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ நிரலà¯à®•à®³à¯ˆ உஙà¯à®•à®³à¯ Mac இல௠நிறà¯à®µ à®®à¯à®¯à®±à¯à®šà®¿à®¤à¯à®¤à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="2966678944701946121">காலாவதி: <ph name="EXPIRATION_DATE_ABBR" />, சேரà¯à®¤à¯à®¤à®¤à¯: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© இணைபà¯à®ªà¯ˆ à®à®±à¯à®ªà®Ÿà¯à®¤à¯à®¤, கடிகாரம௠சரியாக அமைகà¯à®•à®ªà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯. இணையதளஙà¯à®•à®³à¯ தஙà¯à®•à®³à¯ˆà®¤à¯ தாமே அடையாளபà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®®à¯ சானà¯à®±à®¿à®¤à®´à¯à®•à®³à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà¯à®Ÿ காலதà¯à®¤à®¿à®±à¯à®•à¯ மடà¯à®Ÿà¯à®®à¯ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®µà®¤à®¾à®²à¯, இத௠செயà¯à®¯à®ªà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯. உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ கடிகாரம௠தவறாக இரà¯à®ªà¯à®ªà®¤à®¾à®²à¯, இநà¯à®¤à®šà¯ சானà¯à®±à®¿à®¤à®´à¯à®•à®³à¯ˆ Google Chrome ஆல௠சரிபாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="2972581237482394796">&amp;மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">சரியான à®®à¯à®•à®µà®°à®¿à®¯à¯ˆ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
<translation id="2986368408720340940">இநà¯à®¤à®ªà¯ பிகà¯à®…ப௠மà¯à®±à¯ˆ இலà¯à®²à¯ˆ. வேற௠மà¯à®±à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®ªà¯ பாரà¯à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="2991174974383378012">இணையதளஙà¯à®•à®³à¯à®Ÿà®©à¯ பகிரà¯à®ªà®µà¯ˆ</translation>
+<translation id="2991571918955627853">இணையதளமானத௠HSTSà®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à®¾à®²à¯, தறà¯à®ªà¯‹à®¤à¯ <ph name="SITE" />à®à®ªà¯ பாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆ எனà¯à®ªà®¤à®¾à®²à¯, இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ பினà¯à®©à®°à¯ சரியாகச௠செயலà¯à®ªà®Ÿà®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="3005723025932146533">சேமிதà¯à®¤ நகலைக௠காடà¯à®Ÿà¯</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> இன௠CVC எணà¯à®£à¯ˆ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯. உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¤ பினà¯à®©à®°à¯, உஙà¯à®•à®³à¯ காரà¯à®Ÿà¯ விவரஙà¯à®•à®³à¯ இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à¯à®ªà¯ பகிரபà¯à®ªà®Ÿà¯à®®à¯.</translation>
<translation id="3010559122411665027">படà¯à®Ÿà®¿à®¯à®²à¯ உளà¯à®³à¯€à®Ÿà¯ "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">தானாகத௠தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="3024663005179499861">தவறான கொளà¯à®•à¯ˆ வகை</translation>
<translation id="3032412215588512954">தளதà¯à®¤à¯ˆ மீணà¯à®Ÿà¯à®®à¯ à®à®±à¯à®±à®µà®¾?</translation>
<translation id="3037605927509011580">அசà¯à®šà®šà¯à®šà¯‹!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤ சாதனஙà¯à®•à®³à®¿à®²à¯ கà¯à®±à¯ˆà®¨à¯à®¤à®¤à¯ 1 உரà¯à®ªà¯à®ªà®Ÿà®¿ உளà¯à®³à®¤à¯}=1{1 உரà¯à®ªà¯à®ªà®Ÿà®¿ (ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤ சாதனஙà¯à®•à®³à®¿à®²à¯ இதறà¯à®•à¯ மேல௠உளà¯à®³à®©)}other{# உரà¯à®ªà¯à®ªà®Ÿà®¿à®•à®³à¯ (ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤ சாதனஙà¯à®•à®³à®¿à®²à¯ இதறà¯à®•à¯ மேல௠உளà¯à®³à®©)}}</translation>
<translation id="3041612393474885105">சானà¯à®±à®¿à®¤à®´à¯ தகவலà¯</translation>
<translation id="3063697135517575841">இபà¯à®ªà¯‹à®¤à¯ உஙà¯à®•à®³à¯ காரà¯à®Ÿà¯ˆ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. பிறக௠மà¯à®¯à®²à®µà¯à®®à¯.</translation>
<translation id="3064966200440839136">வெளிபà¯à®ªà¯à®±à®ªà¯ பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®©à¯ மூலம௠பணதà¯à®¤à¯ˆ செலà¯à®¤à¯à®¤, மறைநிலையிலிரà¯à®¨à¯à®¤à¯ வெளியேறà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à¯. தொடரவா?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{à®à®¤à¯à®®à®¿à®²à¯à®²à¯ˆ}=1{1 கடவà¯à®šà¯à®šà¯Šà®²à¯}other{# கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯}}</translation>
<translation id="3093245981617870298">ஆஃபà¯à®²à¯ˆà®©à®¿à®²à¯ உளà¯à®³à¯€à®°à¯à®•à®³à¯.</translation>
<translation id="3105172416063519923">பணà¯à®ªà¯ à®à®Ÿà®¿:</translation>
<translation id="3109728660330352905">இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆà®•à¯ காண உஙà¯à®•à®³à¯à®•à¯à®•à¯ à®…à®™à¯à®•à¯€à®•à®¾à®°à®®à¯ அளிகà¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />கனெகà¯à®Ÿà®¿à®µà®¿à®Ÿà¯à®Ÿà®¿ டயகà¯à®©à®¸à¯à®Ÿà®¿à®•à¯à®¸à¯ கரà¯à®µà®¿à®¯à¯ˆ இயகà¯à®•à®µà¯à®®à¯<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">பதிலைக௠கà¯à®±à®¿à®¨à¯€à®•à¯à®•à®®à¯ செயà¯à®µà®¤à®¿à®²à¯ தோலà¯à®µà®¿</translation>
<translation id="3150653042067488994">தறà¯à®•à®¾à®²à®¿à®• சேவையகப௠பிழை</translation>
@@ -247,13 +277,17 @@
<translation id="3167968892399408617">உஙà¯à®•à®³à¯ மறைநிலை தாவலà¯à®•à®³à¯ அனைதà¯à®¤à¯ˆà®¯à¯à®®à¯ மூடிய பினà¯, அவறà¯à®±à®¿à®²à¯ நீஙà¯à®•à®³à¯ பாரà¯à®¤à¯à®¤ பகà¯à®•à®™à¯à®•à®³à¯ உலாவியின௠வரலாறà¯, கà¯à®•à¯à®•à¯€ சேமிபà¯à®ªà®•à®®à¯ அலà¯à®²à®¤à¯ தேடல௠வரலாறà¯à®±à®¿à®²à¯ இரà¯à®•à¯à®•à®¾à®¤à¯. நீஙà¯à®•à®³à¯ இறகà¯à®•à®¿à®¯ எலà¯à®²à®¾ கோபà¯à®ªà¯à®•à®³à¯ அலà¯à®²à®¤à¯ உரà¯à®µà®¾à®•à¯à®•à®¿à®¯ பà¯à®¤à¯à®¤à®•à®•à¯à®•à¯à®±à®¿à®•à®³à¯ அபà¯à®ªà®Ÿà®¿à®¯à¯‡ இரà¯à®•à¯à®•à¯à®®à¯.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">தீவà¯</translation>
+<translation id="317583078218509884">பகà¯à®•à®¤à¯à®¤à¯ˆ மீணà¯à®Ÿà¯à®®à¯ à®à®±à¯à®±à®¿à®¯à®ªà®¿à®©à¯ பà¯à®¤à®¿à®¯ தள அனà¯à®®à®¤à®¿à®•à®³à¯ செயலாகà¯à®•à®ªà¯à®ªà®Ÿà¯à®®à¯.</translation>
<translation id="3176929007561373547">பிராகà¯à®šà®¿ சரà¯à®µà®°à¯ இயகà¯à®•à®¤à¯à®¤à®¿à®²à¯ உளà¯à®³à®¤à¯ எனà¯à®ªà®¤à¯ˆ உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤ உஙà¯à®•à®³à¯ பிராகà¯à®šà®¿ அமைபà¯à®ªà¯à®•à®³à¯ˆà®šà¯ சரிபாரà¯à®•à¯à®•à®µà¯à®®à¯ அலà¯à®²à®¤à¯ நெடà¯à®µà¯Šà®°à¯à®•à¯ நிரà¯à®µà®¾à®•à®¿à®¯à¯ˆà®¤à¯ தொடரà¯à®ªà¯à®•à¯Šà®³à¯à®³à®µà¯à®®à¯. நீஙà¯à®•à®³à¯ பிராகà¯à®šà®¿ சரà¯à®µà®°à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à¯€à®°à¯à®•à®³à¯ எனà¯à®ªà®¤à¯ˆ நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ எனà¯à®±à®¾à®²à¯, பினà¯à®µà®°à¯à®µà®¤à¯ˆà®šà¯ செயà¯à®¯à®µà¯à®®à¯:<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">பகà¯à®•à®¤à¯à®¤à¯ˆ மறைநிலையில௠திறகà¯à®•à®µà¯à®®à¯</translation>
-<translation id="3202578601642193415">பà¯à®¤à¯à®¤à®®à¯ பà¯à®¤à®¿à®¤à¯</translation>
+<translation id="320323717674993345">கடà¯à®Ÿà®£à®®à¯ செலà¯à®¤à¯à®¤à¯à®µà®¤à¯ˆ ரதà¯à®¤à¯à®šà¯†à®¯à¯</translation>
<translation id="3207960819495026254">பà¯à®•à¯à®®à®¾à®°à¯à®•à¯ செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
+<translation id="3225919329040284222">உளà¯à®³à®®à¯ˆà®¨à¯à®¤ எதிரà¯à®ªà®¾à®°à¯à®ªà¯à®ªà¯à®•à®³à¯à®Ÿà®©à¯ பொரà¯à®¨à¯à®¤à®¾à®¤ சானà¯à®±à®¿à®¤à®´à¯ˆ சேவையகம௠வழஙà¯à®•à®¿à®¯à®¤à¯. சில உயரà¯-பாதà¯à®•à®¾à®ªà¯à®ªà¯ வலைதà¯à®¤à®³à®™à¯à®•à®³à®¿à®²à¯ உஙà¯à®•à®³à¯ˆà®ªà¯ பாதà¯à®•à®¾à®•à¯à®•à®µà¯‡ இநà¯à®¤ எதிரà¯à®ªà®¾à®°à¯à®ªà¯à®ªà¯à®•à®³à¯ சேரà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®•à®¿à®©à¯à®±à®©.</translation>
<translation id="3226128629678568754">பகà¯à®•à®¤à¯à®¤à¯ˆ à®à®±à¯à®± தேவைபà¯à®ªà®Ÿà¯à®®à¯ தரவை மறà¯à®®à¯à®±à¯ˆà®šà¯ சமரà¯à®ªà¯à®ªà®¿à®ªà¯à®ªà®¤à®±à¯à®•à¯ மீணà¯à®Ÿà¯à®®à¯ à®à®±à¯à®±à¯ எனà¯à®± பொதà¯à®¤à®¾à®©à¯ˆ à®…à®´à¯à®¤à¯à®¤à¯à®•.</translation>
+<translation id="3227137524299004712">மைகà¯à®°à¯‡à®¾à®ƒà®ªà¯‡à®¾à®©à¯</translation>
<translation id="3228969707346345236">பகà¯à®•à®®à¯ à®®à¯à®©à¯à®ªà¯‡ <ph name="LANGUAGE" /> இல௠இரà¯à®ªà¯à®ªà®¤à®¾à®²à¯ மொழிபெயரà¯à®ªà¯à®ªà¯ தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> இன௠CVC எணà¯à®£à¯ˆ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
+<translation id="3234666976984236645">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®©à¯ à®®à¯à®•à¯à®•à®¿à®¯ உளà¯à®³à®Ÿà®•à¯à®•à®¤à¯à®¤à¯ˆ எபà¯à®ªà¯‹à®¤à¯à®®à¯ இயகà¯à®•à®µà¯à®®à¯</translation>
<translation id="3254409185687681395">இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆ பà¯à®•à¯à®®à®¾à®°à¯à®•à¯ செயà¯à®•</translation>
<translation id="3270847123878663523">&amp;மறà¯à®µà®°à®¿à®šà¯ˆà®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
<translation id="3282497668470633863">காரà¯à®Ÿà®¿à®²à¯à®³à¯à®³ பெயரைச௠சேரà¯à®•à¯à®•à®µà¯à®®à¯</translation>
@@ -267,42 +301,48 @@
<translation id="3340978935015468852">அமைபà¯à®ªà¯à®•à®³à¯</translation>
<translation id="3345135638360864351">இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆ அணà¯à®•à¯à®µà®¤à®±à¯à®•à®¾à®© கோரிகà¯à®•à¯ˆà®¯à¯ˆ <ph name="NAME" />கà¯à®•à¯ அனà¯à®ªà¯à®ª à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="3355823806454867987">பà¯à®°à®¾à®•à¯à®¸à®¿ அமைபà¯à®ªà¯à®•à®³à¯ˆ மாறà¯à®±à¯à®•...</translation>
+<translation id="3361596688432910856">பினà¯à®µà®°à¯à®®à¯ தகவலை Chrome <ph name="BEGIN_EMPHASIS" />சேமிகà¯à®•à®¾à®¤à¯<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />உலாவல௠வரலாறà¯
+ <ph name="LIST_ITEM" />கà¯à®•à¯à®•à¯€à®•à®³à¯ மறà¯à®±à¯à®®à¯ தளத௠தரவà¯
+ <ph name="LIST_ITEM" />படிவஙà¯à®•à®³à®¿à®²à¯ உளà¯à®³à®¿à®Ÿà¯à®®à¯ தகவலà¯
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">கடிகாரப௠பிழை</translation>
-<translation id="337311366426640088">மேலà¯à®®à¯ <ph name="ITEM_COUNT" /> உரà¯à®ªà¯à®ªà®Ÿà®¿à®•à®³à¯...</translation>
<translation id="337363190475750230">விடà¯à®µà®¿à®¤à¯à®¤à®¤à¯</translation>
<translation id="3377188786107721145">கொளà¯à®•à¯ˆà®¯à¯ˆ அலசà¯à®µà®¤à®¿à®²à¯ பிழை</translation>
<translation id="3380365263193509176">அறியபà¯à®ªà®Ÿà®¾à®¤ பிழை</translation>
<translation id="3380864720620200369">கிளையனà¯à®Ÿà¯ à®à®Ÿà®¿:</translation>
<translation id="3391030046425686457">டெலிவரி à®®à¯à®•à®µà®°à®¿</translation>
<translation id="3395827396354264108">பிகà¯à®…ப௠மà¯à®±à¯ˆ</translation>
-<translation id="340013220407300675">தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> இலிரà¯à®¨à¯à®¤à¯ உஙà¯à®•à®³à¯ தகவலைத௠திரà¯à®Ÿ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®²à®¾à®®à¯ (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯ அலà¯à®²à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯).</translation>
<translation id="3422248202833853650">பிற நிரலà¯à®•à®³à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வெளியேறி, நினைவகதà¯à®¤à¯ˆà®•à¯ காலியாகà¯à®•à®µà¯à®®à¯.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" />à®à®¤à¯ தறà¯à®ªà¯‹à®¤à¯ அணà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
+<translation id="3427092606871434483">அனà¯à®®à®¤à®¿ (இயலà¯à®ªà¯)</translation>
<translation id="3427342743765426898">&amp;திரà¯à®¤à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
<translation id="3431636764301398940">இநà¯à®¤à®šà¯ சாதனதà¯à®¤à®¿à®²à¯ காரà¯à®Ÿà¯ˆà®šà¯ சேமி</translation>
<translation id="3435896845095436175">இயகà¯à®•à¯</translation>
<translation id="3447661539832366887">சாதனதà¯à®¤à®¿à®©à¯ உரிமையாளர௠டைனோசர௠கேமை à®®à¯à®Ÿà®•à¯à®•à®¿à®¯à¯à®³à¯à®³à®¾à®°à¯.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">எடà¯à®ªà¯à®ªà®¤à®±à¯à®•à®¾à®© இடைவேளை:</translation>
<translation id="3462200631372590220">மேமà¯à®ªà®Ÿà¯à®Ÿà®µà¯ˆà®¯à¯ˆ மறை</translation>
<translation id="3467763166455606212">காரà¯à®Ÿà¯ உரிமையாளரின௠பெயர௠தேவை</translation>
<translation id="3478058380795961209">காலாவதியாகà¯à®®à¯ மாதமà¯</translation>
<translation id="3479539252931486093">இதை எதிரà¯à®ªà®¾à®°à¯à®•à¯à®•à®µà®¿à®²à¯à®²à¯ˆà®¯à®¾? <ph name="BEGIN_LINK" />எஙà¯à®•à®³à¯à®•à¯à®•à¯à®¤à¯ தெரியபà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">இபà¯à®ªà¯Šà®´à¯à®¤à¯ இலà¯à®²à¯ˆ</translation>
-<translation id="348000606199325318">சிதைவ௠à®à®Ÿà®¿ <ph name="CRASH_LOCAL_ID" /> (சேவையக à®à®Ÿà®¿: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">தறà¯à®ªà¯‹à®¤à¯ உஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à¯ˆà®¤à¯ தொடரà¯à®ªà¯à®•à¯Šà®³à¯à®³ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="3528171143076753409">சேவையகச௠சானà¯à®±à®¿à®¤à®´à¯ நமà¯à®ªà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤ சாதனஙà¯à®•à®³à®¿à®²à¯ கà¯à®±à¯ˆà®¨à¯à®¤à®¤à¯ 1 உரà¯à®ªà¯à®ªà®Ÿà®¿ உளà¯à®³à®¤à¯}=1{1 உரà¯à®ªà¯à®ªà®Ÿà®¿ (ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤ சாதனஙà¯à®•à®³à®¿à®²à¯ இதறà¯à®•à¯ மேல௠உளà¯à®³à®©)}other{# உரà¯à®ªà¯à®ªà®Ÿà®¿à®•à®³à¯ (ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤ சாதனஙà¯à®•à®³à®¿à®²à¯ இதறà¯à®•à¯ மேல௠உளà¯à®³à®©)}}</translation>
<translation id="3539171420378717834">இநà¯à®¤à®•à¯ காரà¯à®Ÿà®¿à®©à¯ பிரதியை சாதனதà¯à®¤à®¿à®²à¯ சேமி</translation>
<translation id="3542684924769048008">இதறà¯à®•à®¾à®• கடவà¯à®šà¯à®šà¯Šà®²à¯à®²à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯:</translation>
+<translation id="3545341443414427877">உஙà¯à®•à®³à¯ கணினியின௠தேதியà¯à®®à¯ நேரமà¯à®®à¯ (<ph name="DATE_AND_TIME" />) தவறாக இரà¯à®•à¯à®•à¯à®®à¯ காரணதà¯à®¤à®¾à®²à¯, <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />கà¯à®•à®¾à®© தனிபà¯à®ªà®Ÿà¯à®Ÿ இணைபà¯à®ªà¯ˆà®šà¯ செயலாகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">உஙà¯à®•à®³à¯ சொநà¯à®¤ ஒதà¯à®¤à®¿à®šà¯ˆà®µà¯ கடவà¯à®šà¯à®šà¯Šà®±à¯à®±à¯Šà®Ÿà®°à¯ மூலம௠எலà¯à®²à®¾ தரவையà¯à®®à¯ எனà¯à®•à¯à®°à®¿à®ªà¯à®Ÿà¯ செயà¯à®¯à®µà¯à®®à¯</translation>
-<translation id="3549761410225185768">மேலà¯à®®à¯ <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ <ph name="DOMAIN2" /> இலிரà¯à®¨à¯à®¤à¯ பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">உஙà¯à®•à®³à¯à®•à¯à®•à®¾à®•, தளதà¯à®¤à®¿à®©à¯ தடà¯à®ªà¯à®ªà¯ˆ உஙà¯à®•à®³à¯ நிரà¯à®µà®¾à®•à®¿ நீகà¯à®• à®®à¯à®Ÿà®¿à®¯à¯à®®à¯</translation>
<translation id="3566021033012934673">உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯ தனிபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ அலà¯à®²</translation>
+<translation id="3569145463236695319">&lt;p&gt;உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ தேதியà¯à®®à¯ நேரமà¯à®®à¯ (<ph name="DATE_AND_TIME" />) தவறாக இரà¯à®•à¯à®•à¯à®®à¯ காரணதà¯à®¤à®¾à®²à¯, <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />கà¯à®•à®¾à®© தனிபà¯à®ªà®Ÿà¯à®Ÿ இணைபà¯à®ªà¯ˆà®šà¯ செயலாகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.&lt;/p&gt;
+
+ &lt;p&gt;தேதியையà¯à®®à¯ நேரதà¯à®¤à¯ˆà®¯à¯à®®à¯ &lt;strong&gt;அமைபà¯à®ªà¯à®•à®³à¯&lt;/strong&gt; பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà®¿à®©à¯ &lt;strong&gt;பொதà¯&lt;/strong&gt; எனà¯à®®à¯ பிரிவிறà¯à®•à¯à®šà¯ செனà¯à®±à¯ மாறà¯à®±à®µà¯à®®à¯.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">பெயரைச௠சேரà¯</translation>
<translation id="3583757800736429874">&amp;நகரà¯à®¤à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
<translation id="3586931643579894722">விவரஙà¯à®•à®³à¯ˆ மறை</translation>
-<translation id="3587482841069643663">அனைதà¯à®¤à¯à®®à¯</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">சரியான காலாவதித௠தேதியை உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
<translation id="36224234498066874">உலாவல௠தரவை அழி...</translation>
@@ -319,7 +359,6 @@
<translation id="3681007416295224113">சானà¯à®±à®¿à®¤à®´à¯ தகவலà¯</translation>
<translation id="3690164694835360974">உளà¯à®¨à¯à®´à¯ˆà®µà®¤à¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®©à®¤à¯ அலà¯à®²</translation>
<translation id="3693415264595406141">கடவà¯à®šà¯à®šà¯Šà®²à¯:</translation>
-<translation id="3696411085566228381">எதà¯à®µà¯à®®à®¿à®²à¯à®²à¯ˆ</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">à®à®±à¯à®±à¯à®•à®¿à®±à®¤à¯â€¦</translation>
<translation id="3712624925041724820">உரிமம௠மà¯à®Ÿà®¿à®¨à¯à®¤à®¤à¯</translation>
@@ -327,12 +366,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />பà¯à®°à®¾à®•à¯à®¸à®¿, ஃபயரà¯à®µà®¾à®²à¯ மறà¯à®±à¯à®®à¯ DNS உளà¯à®³à®®à¯ˆà®µà¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à®²à¯<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">உஙà¯à®•à®³à¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¿à®±à¯à®•à®¾à®© ஆபதà¯à®¤à¯ˆà®ªà¯ பà¯à®°à®¿à®¨à¯à®¤à¯à®•à¯Šà®£à¯à®Ÿà®¾à®²à¯, தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ நிரலà¯à®•à®³à¯ அகறà¯à®±à®ªà¯à®ªà®Ÿà¯à®µà®¤à®±à¯à®•à¯ à®®à¯à®©à¯ <ph name="BEGIN_LINK" />இநà¯à®¤à®ªà¯ பாதà¯à®•à®¾à®ªà¯à®ªà®±à¯à®± தளதà¯à®¤à¯ˆà®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®²à®¾à®®à¯<ph name="END_LINK" />.</translation>
<translation id="3739623965217189342">நீஙà¯à®•à®³à¯ நகலெடà¯à®¤à¯à®¤ இணைபà¯à®ªà¯</translation>
+<translation id="3744899669254331632">இணையதளம௠Chromium ஆல௠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®¾à®¤ தவறான நறà¯à®šà®¾à®©à¯à®±à¯à®•à®³à¯ˆ அனà¯à®ªà¯à®ªà®¿à®¯à¯à®³à¯à®³à®¤à®¾à®²à¯, இபà¯à®ªà¯‹à®¤à¯ <ph name="SITE" />à®à®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ தாகà¯à®•à¯à®¤à®²à¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®•à®µà¯‡ இரà¯à®•à¯à®•à¯à®®à¯, சிறிதà¯à®¨à¯‡à®°à®®à¯ கழிதà¯à®¤à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ சரியாகச௠செயலà¯à®ªà®Ÿà®²à®¾à®®à¯.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à¯à®³à¯à®³ ஹேகà¯à®•à®°à¯à®•à®³à¯ மெனà¯à®ªà¯Šà®°à¯à®³à¯ˆ நிறà¯à®µà¯à®µà®¤à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, ஃபோன௠எணà¯à®•à®³à¯ அலà¯à®²à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) திரà¯à®Ÿà¯à®µà®¤à¯ போனà¯à®± ஆபதà¯à®¤à®¾à®© காரணஙà¯à®•à®³à®¿à®²à¯ ஈடà¯à®ªà®Ÿà®•à¯à®•à¯‚டà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">ஒர௠சேவையகப௠பிழையின௠காரணமாக மொழிபெயரà¯à®ªà¯à®ªà¯à®¤à¯ தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯.</translation>
<translation id="3759461132968374835">உஙà¯à®•à®³à®¿à®Ÿà®®à¯ சமீபதà¯à®¤à®¿à®²à¯ செயலிழபà¯à®ªà¯à®•à®³à¯ எதà¯à®µà¯à®®à¯ பà¯à®•à®¾à®°à®³à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ. செயலிழபà¯à®ªà¯ பà¯à®•à®¾à®°à®³à®¿à®¤à¯à®¤à®²à¯ à®®à¯à®Ÿà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®¨à¯à®¤à®ªà¯‹à®¤à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿ செயலிழபà¯à®ªà¯à®•à®³à¯ இஙà¯à®•à¯ காணà¯à®ªà®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà®¾à®¤à¯.</translation>
+<translation id="3778403066972421603">காரà¯à®Ÿà¯ˆ உஙà¯à®•à®³à¯ Google கணகà¯à®•à®¿à®²à¯à®®à¯ இநà¯à®¤à®šà¯ சாதனதà¯à®¤à®¿à®²à¯à®®à¯ சேமிகà¯à®• விரà¯à®®à¯à®ªà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">காலாவதி: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">நீஙà¯à®•à®³à¯ பிராகà¯à®šà®¿ சரà¯à®µà®°à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®©à®¾à®²à¯....</translation>
<translation id="3828924085048779000">வெறà¯à®±à¯ கடவà¯à®šà¯à®šà¯Šà®±à¯à®±à¯Šà®Ÿà®°à¯à®•à¯à®•à¯ அனà¯à®®à®¤à®¿à®¯à®¿à®²à¯à®²à¯ˆ.</translation>
-<translation id="3845539888601087042">நீஙà¯à®•à®³à¯ உளà¯à®¨à¯à®´à¯ˆà®¨à¯à®¤à®¿à®°à¯à®•à¯à®•à¯à®®à¯ சாதனஙà¯à®•à®³à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வரலாறà¯à®±à¯ˆà®•à¯ காடà¯à®Ÿà¯à®•à®¿à®±à®¤à¯. <ph name="BEGIN_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">à®®à¯à®¨à¯à®¤à¯ˆà®¯ பகà¯à®•à®®à¯</translation>
<translation id="3858027520442213535">தேதியையà¯à®®à¯ நேரதà¯à®¤à¯ˆà®¯à¯à®®à¯ பà¯à®¤à¯à®ªà¯à®ªà®¿</translation>
<translation id="3884278016824448484">à®®à¯à®°à®£à¯à®ªà®¾à®Ÿà®¾à®© சாதன அடையாளஙà¯à®•à®¾à®Ÿà¯à®Ÿà®¿</translation>
@@ -340,11 +382,13 @@
<translation id="3886446263141354045">இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆ அணà¯à®•à¯à®µà®¤à®±à¯à®•à®¾à®© உஙà¯à®•à®³à¯ கோரிகà¯à®•à¯ˆ <ph name="NAME" />கà¯à®•à¯ அனà¯à®ªà¯à®ªà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="3890664840433101773">மினà¯à®©à®žà¯à®šà®²à¯ˆà®šà¯ சேரà¯</translation>
<translation id="3901925938762663762">காரà¯à®Ÿà¯ காலாவதியானதà¯</translation>
-<translation id="3933571093587347751">{1,plural, =1{<ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ நாளை à®®à¯à®¤à®²à¯ à®à®±à¯à®±à¯à®•à¯à®•à¯Šà®³à¯à®³à®ªà¯à®ªà®Ÿà¯à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.}other{<ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ எதிரà¯à®•à®¾à®²à®¤à¯à®¤à®¿à®²à¯ # நாடà¯à®•à®³à¯ à®®à¯à®¤à®²à¯ à®à®±à¯à®±à¯à®•à¯à®•à¯Šà®³à¯à®³à®ªà¯à®ªà®Ÿà¯à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF ஆவணதà¯à®¤à¯ˆ à®à®±à¯à®±à¯à®µà®¤à¯ தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯</translation>
+<translation id="3945915738023014686">பதிவேறà¯à®±à®¿à®¯ சிதைவ௠அறிகà¯à®•à¯ˆ à®à®Ÿà®¿ <ph name="CRASH_ID" /> (அகச௠சிதைவ௠à®à®Ÿà®¿: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ, இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ; பொரà¯à®³à¯ மாறà¯à®±à¯à®ªà¯ பெயரà¯à®•à®³à¯ˆ அதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¿à®©à®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="3963721102035795474">படிதà¯à®¤à®²à¯ பயனà¯à®®à¯à®±à¯ˆ</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{à®à®¤à¯à®®à®¿à®²à¯à®²à¯ˆ}=1{1 தளதà¯à®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ }other{# தளஙà¯à®•à®³à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ }}</translation>
<translation id="397105322502079400">கணகà¯à®•à®¿à®Ÿà¯à®•à®¿à®±à®¤à¯...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯</translation>
+<translation id="3987940399970879459">1 மெ.பை. அளவை விடக௠கà¯à®±à¯ˆà®µà®¾à®• உளà¯à®³à®¤à¯</translation>
<translation id="40103911065039147">{URL_count,plural, =1{à®…à®°à¯à®•à®¿à®²à¯ ஒர௠இணையப௠பகà¯à®•à®®à¯ உளà¯à®³à®¤à¯}other{à®…à®°à¯à®•à®¿à®²à¯ # இணையப௠பகà¯à®•à®™à¯à®•à®³à¯ உளà¯à®³à®©}}</translation>
<translation id="4021036232240155012">DNS எனà¯à®ªà®¤à¯ இணையதளதà¯à®¤à®¿à®©à¯ பெயரை அதன௠இணைய à®®à¯à®•à®µà®°à®¿à®¯à®¾à®• மாறà¯à®±à¯à®®à¯ நெடà¯à®µà¯Šà®°à¯à®•à¯ சேவையாகà¯à®®à¯.</translation>
<translation id="4030383055268325496">&amp;சேரà¯à®¤à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
@@ -355,56 +399,63 @@
<translation id="4079302484614802869">பà¯à®°à®¾à®•à¯à®¸à®¿ உளà¯à®³à®®à¯ˆà®µà®¾à®©à®¤à¯, .pac ஸà¯à®•à®¿à®°à®¿à®ªà¯à®Ÿà¯ URL à®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯à®ªà®Ÿà®¿ அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®¿à®±à®¤à¯, நிலையான பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையகஙà¯à®•à®³à¯à®•à¯à®•à¯ அலà¯à®².</translation>
<translation id="4098354747657067197">மோசடிசெயà¯à®¯à¯à®®à¯ தளம௠உளà¯à®³à®¤à¯</translation>
<translation id="4103249731201008433">சாதன சீரியல௠எண௠தவறானதà¯</translation>
+<translation id="410351446219883937">தானியஙà¯à®•à®¿</translation>
<translation id="4103763322291513355">à®à®±à¯à®•à®¤à¯à®¤à®•à®¾à®¤ URLகளின௠படà¯à®Ÿà®¿à®¯à®²à¯ˆà®¯à¯à®®à¯ உஙà¯à®•à®³à¯ கணினி நிரà¯à®µà®¾à®•à®¿à®¯à®¾à®²à¯ செயறà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®®à¯ பிற கொளà¯à®•à¯ˆà®•à®³à¯ˆà®¯à¯à®®à¯ காண &lt;strong&gt;chrome://policy&lt;/strong&gt; à®à®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®µà¯à®®à¯.</translation>
-<translation id="4110615724604346410"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à®¿à®²à¯ பிழைகள௠உளà¯à®³à®©. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">மெஜநà¯à®¤à®¾</translation>
+<translation id="4116663294526079822">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ எபà¯à®ªà¯‹à®¤à¯à®®à¯ அனà¯à®®à®¤à®¿</translation>
<translation id="4117700440116928470">கொளà¯à®•à¯ˆà®¯à®¿à®©à¯ நோகà¯à®•à®®à¯ ஆதரிகà¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
-<translation id="4118212371799607889"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ Chromium நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{மேலà¯à®®à¯ ஒனà¯à®±à¯}other{மேலà¯à®®à¯ #}}</translation>
<translation id="4130226655945681476">நெடà¯à®µà¯Šà®°à¯à®•à¯ கேபிளà¯à®•à®³à¯, மோடமà¯, ரூடà¯à®Ÿà®°à¯ ஆகியவறà¯à®±à¯ˆà®šà¯ சரிபாரà¯à®•à¯à®•à®µà¯à®®à¯</translation>
+<translation id="413544239732274901">மேலà¯à®®à¯ அறிக</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">கà¯à®³à¯‹à®ªà®²à¯ இயலà¯à®ªà¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯ (கணà¯à®Ÿà®±à®¿à®¤à®²à¯)</translation>
+<translation id="4165986682804962316">தள அமைபà¯à®ªà¯à®•à®³à¯</translation>
<translation id="4169947484918424451">இநà¯à®¤à®•à¯ காரà¯à®Ÿà¯ˆ Chromium சேமிகà¯à®• வேணà¯à®Ÿà¯à®®à®¾?</translation>
<translation id="4171400957073367226">தவறான சரிபாரà¯à®ªà¯à®ªà¯ கையொபà¯à®ªà®®à¯</translation>
<translation id="4196861286325780578">&amp;நகரà¯à®¤à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ஃபயரà¯à®µà®¾à®²à¯ மறà¯à®±à¯à®®à¯ ஆணà¯à®Ÿà®¿à®µà¯ˆà®°à®¸à¯ உளà¯à®³à®®à¯ˆà®µà¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à®²à¯<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ இலà¯à®²à¯ˆ}=1{1 பயனà¯à®ªà®¾à®Ÿà¯ ($1)}=2{2 பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ ($1, $2)}other{# பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">செயலிழபà¯à®ªà¯à®•à®³à¯</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à¯à®³à¯à®³ ஹேகà¯à®•à®°à¯à®•à®³à¯ உஙà¯à®•à®³à¯ உலாவல௠அனà¯à®ªà®µà®¤à¯à®¤à¯ˆ (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, à®®à¯à®•à®ªà¯à®ªà¯à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆ மாறà¯à®±à¯à®µà®¤à¯, நீஙà¯à®•à®³à¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà¯à®®à¯ தளஙà¯à®•à®³à®¿à®²à¯ கூடà¯à®¤à®²à¯ விளமà¯à®ªà®°à®™à¯à®•à®³à¯ˆà®•à¯ காடà¯à®Ÿà¯à®µà®¤à¯) பாதிகà¯à®•à®•à¯à®•à¯‚டிய வகையில௠நிரலà¯à®•à®³à¯ˆ நிறà¯à®µà¯à®µà®¤à¯ போனà¯à®± காரியஙà¯à®•à®³à¯ˆà®šà¯ செயà¯à®¯ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />நெடà¯à®µà¯Šà®°à¯à®•à¯ டயகà¯à®©à®¸à¯à®Ÿà®¿à®•à¯à®¸à¯ கரà¯à®µà®¿à®¯à¯ˆ இயகà¯à®•à®µà¯à®®à¯<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®©à®¤à¯</translation>
<translation id="4250431568374086873">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à®¾à®© உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯, à®®à¯à®´à¯à®ªà¯ பாதà¯à®•à®¾à®ªà¯à®ªà¯à®Ÿà®©à¯ இலà¯à®²à¯ˆ</translation>
<translation id="4250680216510889253">இலà¯à®²à¯ˆ</translation>
<translation id="425582637250725228">உஙà¯à®•à®³à¯ மாறà¯à®±à®™à¯à®•à®³à¯ சேமிகà¯à®•à®ªà¯à®ªà®Ÿà®¾à®®à®²à¯ இரà¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="4258748452823770588">தவறான கையொபà¯à®ªà®®à¯</translation>
+<translation id="4265872034478892965">உஙà¯à®•à®³à¯ நிரà¯à®µà®¾à®•à®¿ அனà¯à®®à®¤à®¿à®¤à¯à®¤à®¾à®°à¯</translation>
<translation id="4269787794583293679">(பயனரà¯à®ªà¯†à®¯à®°à¯ இலà¯à®²à¯ˆ)</translation>
<translation id="4275830172053184480">உஙà¯à®•à®³à¯ சாதனதà¯à®¤à¯ˆ மீணà¯à®Ÿà¯à®®à¯ தொடஙà¯à®•à®µà¯à®®à¯</translation>
<translation id="4280429058323657511">, காலாவதித௠தேதி: <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">சமீபதà¯à®¤à®¿à®²à¯ Google இன௠பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© உலாவலானத௠<ph name="SITE" /> இல௠<ph name="BEGIN_LINK" />தீஙà¯à®•à¯à®µà®¿à®³à¯ˆà®µà®¿à®•à¯à®•à¯à®®à¯ நிரலà¯à®•à®³à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à¯à®³à¯à®³à®¤à¯<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">மூலப௠பரிநà¯à®¤à¯à®°à¯ˆà®•à®³à¯</translation>
<translation id="4304224509867189079">உளà¯à®¨à¯à®´à¯ˆ</translation>
-<translation id="432290197980158659">உளà¯à®³à®®à¯ˆà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ எதிரà¯à®ªà®¾à®°à¯à®ªà¯à®ªà¯à®•à®³à¯à®Ÿà®©à¯ பொரà¯à®¨à¯à®¤à®¾à®¤à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ சேவையகம௠வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¤à¯. உஙà¯à®•à®³à¯ˆà®ªà¯ பாதà¯à®•à®¾à®•à¯à®•à¯à®®à¯ நோகà¯à®•à®¤à¯à®¤à®¿à®²à¯, கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà¯à®Ÿ அதிக பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© இணையதளஙà¯à®•à®³à®¿à®²à¯ இநà¯à®¤ எதிரà¯à®ªà®¾à®°à¯à®ªà¯à®ªà¯à®•à®³à¯ அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®•à®¿à®©à¯à®±à®©. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">தட௠(இயலà¯à®ªà¯)</translation>
<translation id="4325863107915753736">கடà¯à®Ÿà¯à®°à¯ˆà®¯à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="4326324639298822553">காலாவதித௠தேதியைச௠சரிபாரà¯à®¤à¯à®¤à¯, மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®²à®µà¯à®®à¯</translation>
<translation id="4331708818696583467">பாதà¯à®•à®¾à®ªà¯à®ªà®±à¯à®±à®¤à¯</translation>
<translation id="4356973930735388585">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ உளà¯à®³ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯, உஙà¯à®•à®³à¯ தகவலைத௠(எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà¯: படஙà¯à®•à®³à¯, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯ மறà¯à®±à¯à®®à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) திரà¯à®Ÿà®•à¯à®•à¯‚டிய அலà¯à®²à®¤à¯ நீகà¯à®•à®•à¯à®•à¯‚டிய தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ நிரலà¯à®•à®³à¯ˆ உஙà¯à®•à®³à¯ கணினியில௠நிறà¯à®µ à®®à¯à®¯à®²à®²à®¾à®®à¯.</translation>
<translation id="4372948949327679948">எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤ <ph name="VALUE_TYPE" /> மதிபà¯à®ªà¯.</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" /> ஠அடைய à®®à¯à®¯à®±à¯à®šà®¿ செயà¯à®¤à¯€à®°à¯à®•à®³à¯. ஆனால௠சேவையகம௠வழஙà¯à®•à®¿à®¯ சானà¯à®±à®¿à®¤à®´à®¾à®©à®¤à¯ அதன௠வழஙà¯à®•à¯à®¨à®°à®¾à®²à¯ நிராகரிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯. அதாவதà¯, சேவையகம௠வழஙà¯à®•à®¿à®¯ பாதà¯à®•à®¾à®ªà¯à®ªà¯ நமà¯à®ªà®¿à®•à¯à®•à¯ˆà®šà¯à®šà®¾à®©à¯à®±à¯à®•à®³à¯ˆ நிசà¯à®šà®¯à®®à®¾à®• எகà¯à®•à®¾à®°à®£à®¤à¯à®¤à¯ˆà®•à¯à®•à¯Šà®£à¯à®Ÿà¯à®®à¯ நமà¯à®ªà®•à¯à®•à¯‚டாதà¯. போலியான ஒனà¯à®±à¯à®Ÿà®©à¯ நீஙà¯à®•à®³à¯ தகவல௠பரிமாறà¯à®±à®®à¯ செயà¯à®¤à¯à®•à¯Šà®£à¯à®Ÿà®¿à®°à¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="4381091992796011497">பயனர௠பெயரà¯:</translation>
<translation id="4394049700291259645">à®®à¯à®Ÿà®•à¯à®•à¯</translation>
<translation id="4406896451731180161">தேடல௠மà¯à®Ÿà®¿à®µà¯à®•à®³à¯</translation>
+<translation id="4424024547088906515">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ Chrome நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> உஙà¯à®•à®³à¯ உளà¯à®¨à¯à®´à¯ˆà®µà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ à®à®±à¯à®•à®µà®¿à®²à¯à®²à¯ˆ அலà¯à®²à®¤à¯ சானà¯à®±à®¿à®¤à®´à¯ வழஙà¯à®•à®ªà¯à®ªà®Ÿà®¾à®®à®²à¯ இரà¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="443673843213245140">பà¯à®°à®¾à®•à¯à®¸à®¿ பயனà¯à®ªà®¾à®Ÿà¯ à®®à¯à®Ÿà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯. ஆனால௠வெளிபà¯à®ªà®Ÿà¯ˆà®¯à®¾à®© பà¯à®°à®¾à®•à¯à®¸à®¿ உளà¯à®³à®®à¯ˆà®µà¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯.</translation>
-<translation id="4492190037599258964"><ph name="SEARCH_STRING" />' கà¯à®•à®¾à®©à®¤à¯ தேடல௠மà¯à®Ÿà®¿à®µà¯à®•à®³à¯</translation>
<translation id="4506176782989081258">சரிபாரà¯à®ªà¯à®ªà¯à®ªà¯ பிழை: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">கணினி நிரà¯à®µà®¾à®•à®¿à®¯à¯ˆà®¤à¯ தொடரà¯à®ªà¯à®•à¯Šà®³à¯à®³à¯à®¤à®²à¯</translation>
<translation id="450710068430902550">நிரà¯à®µà®¾à®•à®¿à®¯à¯à®Ÿà®©à¯ பகிரà¯à®ªà®µà¯ˆ</translation>
<translation id="4515275063822566619">காரà¯à®Ÿà¯à®•à®³à¯à®®à¯ à®®à¯à®•à®µà®°à®¿à®•à®³à¯à®®à¯ Chrome இலிரà¯à®¨à¯à®¤à¯à®®à¯ <ph name="ACCOUNT_EMAIL" /> எனà¯à®®à¯ உஙà¯à®•à®³à¯ Google கணகà¯à®•à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯à®®à¯ பெறபà¯à®ªà®Ÿà¯à®Ÿà®µà¯ˆà®¯à®¾à®•à¯à®®à¯. <ph name="BEGIN_LINK" />அமைபà¯à®ªà¯à®•à®³à®¿à®²à¯<ph name="END_LINK" /> அவறà¯à®±à¯ˆ நிரà¯à®µà®•à®¿à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="4522570452068850558">விவரஙà¯à®•à®³à¯</translation>
+<translation id="4552089082226364758">ஃபà¯à®³à®¾à®·à¯</translation>
<translation id="4558551763791394412">நீடà¯à®Ÿà®¿à®ªà¯à®ªà¯à®•à®³à¯ˆ à®®à¯à®Ÿà®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="457875822857220463">டெலிவரி</translation>
<translation id="4587425331216688090">Chrome இலிரà¯à®¨à¯à®¤à¯ à®®à¯à®•à®µà®°à®¿à®¯à¯ˆ அகறà¯à®±à®µà®¾?</translation>
-<translation id="4589078953350245614"><ph name="DOMAIN" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®¯à®©à¯à®±à¯€à®°à¯à®•à®³à¯, ஆனால௠சேவையகம௠தவறான சானà¯à®±à®¿à®¤à®´à¯ˆ வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¤à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">நவீன சைபர௠சூடà¯à®Ÿà¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ <ph name="DOMAIN" /> உடனான உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯ எனà¯à®•à¯à®°à®¿à®ªà¯à®Ÿà¯ செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="4594403342090139922">&amp;நீகà¯à®•à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
<translation id="4619615317237390068">பிற சாதனஙà¯à®•à®³à®¿à®©à¯ தாவலà¯à®•à®³à¯</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à®¿à®²à¯ பிழைகள௠உளà¯à®³à®©. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
+<translation id="4690462567478992370">தவறான சானà¯à®±à®¿à®¤à®´à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à¯ˆ நிறà¯à®¤à¯à®¤à¯</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தடஙà¯à®•à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows நெடà¯à®µà¯Šà®°à¯à®•à¯ டயகà¯à®©à®¸à¯à®Ÿà®¿à®•à¯à®¸à¯ கரà¯à®µà®¿à®¯à¯ˆ இயகà¯à®•à®µà¯à®®à¯<ph name="END_LINK" /></translation>
@@ -421,21 +472,24 @@
<translation id="4771973620359291008">அறியபà¯à®ªà®Ÿà®¾à®¤ பிழை à®à®±à¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯.</translation>
<translation id="4800132727771399293">காலாவதியாகà¯à®®à¯ நேரதà¯à®¤à¯ˆà®¯à¯à®®à¯, CVCà®à®¯à¯à®®à¯ சரிபாரà¯à®¤à¯à®¤à¯, மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">இணையதளமானத௠Google Chrome ஆல௠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®¾à®¤ சிதைநà¯à®¤ நறà¯à®šà®¾à®©à¯à®±à¯à®•à®³à¯ˆ அனà¯à®ªà¯à®ªà®¿à®¯à¯à®³à¯à®³à®¤à®¾à®²à¯, நீஙà¯à®•à®³à¯ இபà¯à®ªà¯‹à®¤à¯ <ph name="SITE" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯, பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ தாகà¯à®•à¯à®¤à®²à¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆà®¯à¯‡, எனவே இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ சிறித௠நேரம௠கழிதà¯à®¤à¯ செயலà¯à®ªà®Ÿà¯à®®à¯.</translation>
<translation id="4813512666221746211">பிணைய பிழை</translation>
<translation id="4816492930507672669">பகà¯à®•à®¤à¯à®¤à®¿à®²à¯ பொரà¯à®¤à¯à®¤à¯</translation>
<translation id="483020001682031208">காடà¯à®Ÿà¯à®µà®¤à®±à¯à®•à¯ இயலà¯à®¨à®¿à®²à¯ˆ இணையப௠பகà¯à®•à®™à¯à®•à®³à¯ எதà¯à®µà¯à®®à®¿à®²à¯à®²à¯ˆ</translation>
<translation id="4850886885716139402">காடà¯à®šà®¿</translation>
<translation id="4854362297993841467">இநà¯à®¤ டெலிவரி à®®à¯à®±à¯ˆ இலà¯à®²à¯ˆ. வேற௠மà¯à®±à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®ªà¯ பாரà¯à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="4858792381671956233">இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆà®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®²à®¾à®®à®¾ என, நீஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à®¿à®Ÿà®®à¯ கேடà¯à®Ÿà¯à®³à¯à®³à¯€à®°à¯à®•à®³à¯</translation>
+<translation id="4863764087567530506">இநà¯à®¤ உளà¯à®³à®Ÿà®•à¯à®•à®®à¯, உஙà¯à®•à®³à¯ˆ à®à®®à®¾à®±à¯à®±à®¿ மெனà¯à®ªà¯Šà®°à¯à®³à¯ˆ நிறà¯à®µ வைகà¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலை வெளிபà¯à®ªà®Ÿà¯à®¤à¯à®¤ வைகà¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LINK" />இரà¯à®ªà¯à®ªà®¿à®©à¯à®®à¯ காடà¯à®Ÿà¯<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">வரலாறà¯à®±à®¿à®²à¯ தேடà¯</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{மேலà¯à®®à¯ ஒர௠இணையப௠பகà¯à®•à®®à¯}other{மேலà¯à®®à¯ # இணையப௠பகà¯à®•à®™à¯à®•à®³à¯}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">ஒர௠அறியபà¯à®ªà®Ÿà®¾à®¤ மொழியிலிரà¯à®¨à¯à®¤à¯ <ph name="LANGUAGE_LANGUAGE" /> -கà¯à®•à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ மொழிபெயரà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯</translation>
<translation id="4923459931733593730">கடà¯à®Ÿà®£ à®®à¯à®±à¯ˆ</translation>
<translation id="4926049483395192435">கடà¯à®Ÿà®¾à®¯à®®à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿ வேணà¯à®Ÿà¯à®®à¯.</translation>
<translation id="495170559598752135">செயலà¯à®•à®³à¯</translation>
<translation id="4958444002117714549">படà¯à®Ÿà®¿à®¯à®²à¯ˆ விரி</translation>
-<translation id="4962322354953122629"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ Chrome நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">எசà¯à®šà®°à®¿à®•à¯à®•à¯ˆà®•à®³à¯ˆ மீணà¯à®Ÿà¯à®®à¯ இயகà¯à®•à¯</translation>
<translation id="4989809363548539747">இநà¯à®¤à®šà¯ செரà¯à®•à¯à®¨à®¿à®°à®²à¯ ஆதரிகà¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="5002932099480077015">இயகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¾à®²à¯, விரைவாகப௠படிவதà¯à®¤à¯ˆ நிரபà¯à®ª உஙà¯à®•à®³à¯ காரà¯à®Ÿà®¿à®©à¯ நகலை இசà¯à®šà®¾à®¤à®©à®¤à¯à®¤à®¿à®²à¯ Chrome சேமிதà¯à®¤à¯ வைகà¯à®•à¯à®®à¯.</translation>
<translation id="5018422839182700155">பகà¯à®•à®¤à¯à®¤à¯ˆà®¤à¯ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
@@ -443,14 +497,15 @@
<translation id="5023310440958281426">உஙà¯à®•à®³à¯ நிரà¯à®µà®¾à®•à®¿à®¯à®¿à®©à¯ கொளà¯à®•à¯ˆà®•à®³à¯ˆà®šà¯ சரிபாரà¯à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="5029568752722684782">நகலை அழி</translation>
<translation id="5031870354684148875">Google மொழியாகà¯à®•à®®à¯ ஓர௠அறிமà¯à®•à®®à¯</translation>
+<translation id="5039804452771397117">அனà¯à®®à®¤à®¿</translation>
<translation id="5040262127954254034">தனியà¯à®°à®¿à®®à¯ˆ</translation>
<translation id="5045550434625856497">தவறான கடவà¯à®šà¯à®šà¯Šà®²à¯</translation>
<translation id="5056549851600133418">உஙà¯à®•à®³à¯à®•à¯à®•à®¾à®© கடà¯à®Ÿà¯à®°à¯ˆà®•à®³à¯</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />பà¯à®°à®¾à®•à¯à®¸à®¿ à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à®²à¯<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{கà¯à®•à¯à®•à¯€à®•à®³à¯ எதà¯à®µà¯à®®à®¿à®²à¯à®²à¯ˆ}=1{கà¯à®•à¯à®•à¯€à®•à®³à¯ˆ ஒர௠தளம௠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯. }other{கà¯à®•à¯à®•à¯€à®•à®³à¯ˆ # தளஙà¯à®•à®³à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®©à¯à®±à®©. }}</translation>
<translation id="5087286274860437796">தறà¯à®ªà¯‹à®¤à¯ சேவையகதà¯à®¤à®¿à®©à¯ சானà¯à®±à®¿à®¤à®´à¯ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à®¾à®¤à¯.</translation>
<translation id="5087580092889165836">காரà¯à®Ÿà¯ˆà®šà¯ சேரà¯</translation>
<translation id="5089810972385038852">மாநிலமà¯</translation>
+<translation id="5094747076828555589">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ Chromium நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="5095208057601539847">பிராநà¯à®¤à®¿à®¯à®®à¯</translation>
<translation id="5115563688576182185">(64-பிடà¯)</translation>
<translation id="5141240743006678641">ஒதà¯à®¤à®¿à®šà¯ˆà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯ˆ உஙà¯à®•à®³à¯ Google நறà¯à®šà®¾à®©à¯à®±à¯à®•à®³à¯ மூலம௠எனà¯à®•à¯à®°à®¿à®ªà¯à®Ÿà¯ செயà¯à®¯à®µà¯à®®à¯</translation>
@@ -466,24 +521,24 @@
<translation id="5222812217790122047">மினà¯à®©à®žà¯à®šà®²à¯ தேவை</translation>
<translation id="5251803541071282808">மேககà¯à®•à®£à®¿</translation>
<translation id="5277279256032773186">பணியில௠Chromeà®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾? வணிக நிறà¯à®µà®©à®™à¯à®•à®³à¯ தஙà¯à®•à®³à®¿à®©à¯ பணியாளரà¯à®•à®³à¯à®•à¯à®•à®¾à®© Chrome அமைபà¯à®ªà¯à®•à®³à¯ˆ நிரà¯à®µà®•à®¿à®•à¯à®•à®²à®¾à®®à¯. மேலà¯à®®à¯ அறிக</translation>
+<translation id="5297526204711817721">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à®¾à®© உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯ தனிபà¯à®ªà®Ÿà¯à®Ÿà®¤à®²à¯à®². VR பயனà¯à®®à¯à®±à¯ˆà®¯à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ எபà¯à®ªà¯‹à®¤à¯ வேணà¯à®Ÿà¯à®®à®¾à®©à®¾à®²à¯à®®à¯ வெளியேற, ஹெடà¯à®šà¯†à®Ÿà¯à®Ÿà¯ˆ அகறà¯à®±à®¿, "à®®à¯à®¨à¯à®¤à¯ˆà®¯à®¤à¯" எனà¯à®ªà®¤à¯ˆà®•à¯ கிளிக௠செயà¯à®¯à®µà¯à®®à¯.</translation>
<translation id="5299298092464848405">கொளà¯à®•à¯ˆà®¯à¯ˆ அலசà¯à®µà®¤à®¿à®²à¯ பிழை</translation>
-<translation id="5300589172476337783">காணà¯à®ªà®¿</translation>
<translation id="5308689395849655368">செயலிழபà¯à®ªà¯ பà¯à®•à®¾à®°à®³à®¿à®¤à¯à®¤à®²à¯ à®®à¯à®Ÿà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯.</translation>
<translation id="5317780077021120954">சேமி</translation>
<translation id="5327248766486351172">பெயரà¯</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> இல௠உளà¯à®³ தாகà¯à®•à¯à®ªà®µà®°à¯à®•à®³à¯, மெனà¯à®ªà¯Šà®°à¯à®³à¯ˆ நிறà¯à®µà¯à®¤à®²à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, ஃபோன௠எணà¯à®•à®³à¯ அலà¯à®²à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) வெளியிடச௠செயà¯à®¤à®²à¯ போனà¯à®± ஆபதà¯à®¤à®¾à®© செயலà¯à®•à®³à¯ˆà®šà¯ செயà¯à®¯à¯à®®à¯à®ªà®Ÿà®¿ à®à®®à®¾à®±à¯à®± à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®²à®¾à®®à¯.</translation>
-<translation id="5359637492792381994"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ இபà¯à®ªà¯‹à®¤à¯ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791"><ph name="SITE" /> தளதà¯à®¤à®¿à®©à¯ சானà¯à®±à®¿à®¤à®´à¯ ரதà¯à®¤à¯à®šà¯†à®¯à¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à®¾à®²à¯, தறà¯à®ªà¯‹à®¤à¯ அதைப௠பாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆ எனà¯à®ªà®¤à®¾à®²à¯, இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ பினà¯à®©à®°à¯ சரியாகச௠செயலà¯à®ªà®Ÿà®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="536296301121032821">கொளà¯à®•à¯ˆ அமைபà¯à®ªà¯à®•à®³à¯ˆà®šà¯ சேமிபà¯à®ªà®¤à®¿à®²à¯ தோலà¯à®µà®¿</translation>
<translation id="5386426401304769735">இநà¯à®¤à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ சஙà¯à®•à®¿à®²à®¿à®¯à®¿à®²à¯, SHA-1à®à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ கையொபà¯à®ªà®®à®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ உளà¯à®³à®¤à¯.</translation>
<translation id="5402410679244714488">காலாவதித௠தேதி: <ph name="EXPIRATION_DATE_ABBR" />, கடைசியாக ஒர௠ஆணà¯à®Ÿà®¿à®±à¯à®•à¯ à®®à¯à®©à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
+<translation id="540969355065856584"><ph name="DOMAIN" /> டொமைனை, சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; அதறà¯à®•à®¾à®© காரணஙà¯à®•à®³à¯: இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ தறà¯à®ªà¯‹à®¤à¯ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®©à®¤à®²à¯à®². இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¿à®©à®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="5421136146218899937">உலாவல௠தரவை அழி...</translation>
<translation id="5430298929874300616">பà¯à®¤à¯à®¤à®•à®•à¯à®•à¯à®±à®¿à®¯à¯ˆ அகறà¯à®±à¯</translation>
<translation id="5431657950005405462">உஙà¯à®•à®³à¯ கோபà¯à®ªà¯ இலà¯à®²à¯ˆ</translation>
-<translation id="5435775191620395718">இநà¯à®¤à®šà¯ சாதனதà¯à®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வரலாறà¯à®±à¯ˆà®•à¯ காடà¯à®Ÿà¯à®•à®¿à®±à®¤à¯. <ph name="BEGIN_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" திடà¯à®Ÿà®®à¯à®±à¯ˆ சரிபாரà¯à®ªà¯à®ªà¯à®ªà¯ பிழை: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">இநà¯à®¤ <ph name="HOST_NAME" /> பகà¯à®•à®¤à¯à®¤à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="5455374756549232013">தவறான கொளà¯à®•à¯ˆ நேரமà¯à®¤à¯à®¤à®¿à®°à¯ˆ</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" /> இல௠<ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">தவறானதà¯</translation>
<translation id="5470861586879999274">&amp;திரà¯à®¤à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
<translation id="54817484435770891">சரியான à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®šà¯ சேரà¯à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="5492298309214877701">நிறà¯à®µà®©à®®à¯, அமைபà¯à®ªà¯ அலà¯à®²à®¤à¯ பளà¯à®³à®¿ அக இணையதà¯à®¤à®¿à®²à¯ உளà¯à®³ இநà¯à®¤à®¤à¯ தளம௠வெளிபà¯à®ªà¯à®± இணையதளம௠ஒனà¯à®±à®¿à®©à¯ அதே URLà®à®•à¯ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®¿à®±à®¤à¯.
@@ -500,6 +555,8 @@
<translation id="5571083550517324815">இநà¯à®¤ à®®à¯à®•à®µà®°à®¿à®¯à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ பிகà¯à®…ப௠செயà¯à®¯ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. வேற௠மà¯à®•à®µà®°à®¿à®¯à¯ˆà®¤à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="5572851009514199876">Chromeà®à®¤à¯ தொடஙà¯à®•à®¿ உளà¯à®¨à¯à®´à¯ˆà®¯à®µà¯à®®à¯. அபà¯à®ªà¯‹à®¤à¯à®¤à®¾à®©à¯ இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆ அணà¯à®•à¯à®µà®¤à®±à¯à®•à¯ உஙà¯à®•à®³à¯à®•à¯à®•à¯ அனà¯à®®à®¤à®¿ உளà¯à®³à®¤à®¾ எனà¯à®ªà®¤à¯ˆ Chrome ஆல௠சரிபாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à¯à®®à¯.</translation>
<translation id="5580958916614886209">காலாவதி மாததà¯à®¤à¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à¯, மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®²à®µà¯à®®à¯</translation>
+<translation id="5586446728396275693">சேமிதà¯à®¤ à®®à¯à®•à®µà®°à®¿à®•à®³à¯ இலà¯à®²à¯ˆ</translation>
+<translation id="5595485650161345191">à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®¤à¯ திரà¯à®¤à¯à®¤à¯</translation>
<translation id="560412284261940334">நிரà¯à®µà®¾à®•à®®à¯ ஆதரிகà¯à®•à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="5610142619324316209">இணைபà¯à®ªà¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à®²à¯</translation>
<translation id="5610807607761827392"><ph name="BEGIN_LINK" />அமைபà¯à®ªà¯à®•à®³à®¿à®²à¯<ph name="END_LINK" /> காரà¯à®Ÿà¯à®•à®³à¯ˆà®¯à¯à®®à¯ à®®à¯à®•à®µà®°à®¿à®•à®³à¯ˆà®¯à¯à®®à¯ நிரà¯à®µà®•à®¿à®•à¯à®•à®²à®¾à®®à¯.</translation>
@@ -507,15 +564,18 @@
<translation id="5622887735448669177">தளதà¯à®¤à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ வெளியேறவா?</translation>
<translation id="5629630648637658800">கொளà¯à®•à¯ˆ அமைபà¯à®ªà¯à®•à®³à¯ˆ à®à®±à¯à®±à¯à®µà®¤à®¿à®²à¯ தோலà¯à®µà®¿</translation>
<translation id="5631439013527180824">தவறான சாதன நிரà¯à®µà®¾à®• டோகà¯à®•à®©à¯</translation>
+<translation id="5633066919399395251"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à¯ தறà¯à®ªà¯‹à®¤à¯à®³à¯à®³ ஹேகà¯à®•à®°à¯à®•à®³à¯ உஙà¯à®•à®³à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, படஙà¯à®•à®³à¯, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯ மறà¯à®±à¯à®®à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) திரà¯à®Ÿà®•à¯à®•à¯‚டிய அலà¯à®²à®¤à¯ நீகà¯à®•à®•à¯à®•à¯‚டிய ஆபதà¯à®¤à®¾à®© நிரலà¯à®•à®³à¯ˆ உஙà¯à®•à®³à¯ கணினியில௠நிறà¯à®µ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">இரà¯à®ªà¯à®ªà®¿à®Ÿà®®à¯</translation>
+<translation id="5659593005791499971">மினà¯à®©à®žà¯à®šà®²à¯</translation>
<translation id="5669703222995421982">தனிபà¯à®ªà®¯à®©à®¾à®•à¯à®•à®¿à®¯ உளà¯à®³à®Ÿà®•à¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பெறà¯à®™à¯à®•à®³à¯</translation>
<translation id="5675650730144413517">இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ செயலà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ</translation>
-<translation id="5677928146339483299">தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
-<translation id="5694783966845939798"><ph name="DOMAIN" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®¯à®±à¯à®šà®¿ செயà¯à®¤à¯€à®°à¯à®•à®³à¯, ஆனால௠சேவையகமானத௠வலிமையறà¯à®± கையொபà¯à®ª அலà¯à®•à®¾à®°à®¿à®¤à®®à¯ˆà®ªà¯ (SHA-1 போனà¯à®±à®µà¯ˆ) பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®•à¯ கையொபà¯à®ªà®®à®¿à®Ÿà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ˆ வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¤à¯. அதாவதà¯, சேவையகம௠வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³ பாதà¯à®•à®¾à®ªà¯à®ªà¯ அனà¯à®®à®¤à®¿à®šà¯ சானà¯à®±à¯à®•à®³à¯ போலியாக உரà¯à®µà®¾à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯, அதà¯à®¤à¯à®Ÿà®©à¯ சேவையகம௠நீஙà¯à®•à®³à¯ எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤ சேவையகமாக இலà¯à®²à®¾à®®à®²à¯ இரà¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯ (நீஙà¯à®•à®³à¯ தொடரà¯à®ªà¯à®•à¯Šà®£à¯à®Ÿà®¿à®°à¯à®ªà¯à®ªà®¤à¯ ஹேகà¯à®•à®°à®¾à®• இரà¯à®•à¯à®•à®²à®¾à®®à¯). <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">இநà¯à®¤ தளதà¯à®¤à®¿à®©à¯ அடையாளம௠சரிபாரà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
+<translation id="5713016350996637505">à®à®®à®¾à®±à¯à®±à®•à¯à®•à¯‚டிய உளà¯à®³à®Ÿà®•à¯à®•à®®à¯ தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="5720705177508910913">நடபà¯à®ªà¯à®ªà¯ பயனரà¯</translation>
<translation id="5732392974455271431">உஙà¯à®•à®³à¯à®•à¯à®•à®¾à®•, தளதà¯à®¤à®¿à®©à¯ தடà¯à®ªà¯à®ªà¯ˆ உஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à¯ நீகà¯à®• à®®à¯à®Ÿà®¿à®¯à¯à®®à¯</translation>
<translation id="5763042198335101085">சரியான மினà¯à®©à®žà¯à®šà®²à¯ à®®à¯à®•à®µà®°à®¿à®¯à¯ˆ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
<translation id="5765072501007116331">டெலிவரி à®®à¯à®±à¯ˆà®•à®³à¯ˆà®¯à¯à®®à¯ தேவைகளையà¯à®®à¯ பாரà¯à®•à¯à®•, à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®¤à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®•à¯à®•à®µà¯à®®à¯</translation>
+<translation id="5778550464785688721">MIDI சாதனஙà¯à®•à®³à¯ à®®à¯à®´à¯à®•à¯à®•à®Ÿà¯à®Ÿà¯à®ªà¯à®ªà®¾à®Ÿà¯</translation>
<translation id="5784606427469807560">காரà¯à®Ÿà¯ˆ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®µà®¤à®¿à®²à¯ சிகà¯à®•à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¤à¯. இணைய இணைபà¯à®ªà¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à¯, மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®²à®µà¯à®®à¯.</translation>
<translation id="5785756445106461925">மேலà¯à®®à¯, பாதà¯à®•à®¾à®ªà¯à®ªà®±à¯à®± பிற ஆதாரஙà¯à®•à®³à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à®¿à®²à¯ உளà¯à®³à®©. இநà¯à®¤ ஆதாரஙà¯à®•à®³à¯ˆ டà¯à®°à®¾à®©à¯à®¸à®¿à®Ÿà¯à®Ÿà®¿à®²à¯ இரà¯à®•à¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯à®®à¯ பிறர௠பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®²à®¾à®®à¯, மேலà¯à®®à¯ பகà¯à®•à®¤à¯à®¤à®¿à®©à¯ தோறà¯à®±à®¤à¯à®¤à¯ˆ மாறà¯à®±, தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ அதை மாறà¯à®±à®¿à®¯à®®à¯ˆà®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="5786044859038896871">காரà¯à®Ÿà¯ தகவலை நிரபà¯à®ª விரà¯à®®à¯à®ªà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾?</translation>
@@ -524,36 +584,44 @@
<translation id="5813119285467412249">&amp;சேரà¯à®¤à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
<translation id="5814352347845180253"><ph name="SITE" /> மறà¯à®±à¯à®®à¯ சில தளஙà¯à®•à®³à®¿à®©à¯ பிரீமிய உளà¯à®³à®Ÿà®•à¯à®• அணà¯à®•à®²à¯ˆ நீஙà¯à®•à®³à¯ இழகà¯à®•à®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="5838278095973806738">தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯ திரà¯à®Ÿà®¿à®µà®¿à®Ÿà®²à®¾à®®à¯ எனà¯à®ªà®¤à®¾à®²à¯, இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ à®®à¯à®•à¯à®•à®¿à®¯à®¤à¯ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà¯: கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯ அலà¯à®²à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) உளà¯à®³à®¿à®Ÿ வேணà¯à®Ÿà®¾à®®à¯.</translation>
-<translation id="5843436854350372569"><ph name="DOMAIN" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®¯à®©à¯à®±à¯€à®°à¯à®•à®³à¯, ஆனால௠சேவையகம௠வலà¯à®µà®±à¯à®± கà¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà¯ˆà®•à¯ கொணà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ˆ வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¤à¯. தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ கà¯à®±à®¿à®¯à¯€à®Ÿà¯à®Ÿà¯ˆà®¤à¯ திரà¯à®Ÿà®¿à®¯à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯, மேலà¯à®®à¯ சேவையகம௠நீஙà¯à®•à®³à¯ எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤ சேவையகமாக இலà¯à®²à®¾à®®à®²à¯ இரà¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯ (நீஙà¯à®•à®³à¯ தொடரà¯à®ªà¯à®•à¯Šà®£à¯à®Ÿà®¿à®°à¯à®ªà¯à®ªà®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®¾à®³à®°à®¾à®• இரà¯à®•à¯à®•à®²à®¾à®®à¯). <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆ அணà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="5869522115854928033">சேமிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯</translation>
<translation id="5872918882028971132">மூலப௠பரிநà¯à®¤à¯à®°à¯ˆà®•à®³à¯</translation>
<translation id="5901630391730855834">மஞà¯à®šà®³à¯</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (ஒதà¯à®¤à®¿à®šà¯ˆà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ஒர௠கà¯à®•à¯à®•à¯€ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®•à®¿à®±à®¤à¯}other{# கà¯à®•à¯à®•à¯€à®•à®³à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®•à®¿à®©à¯à®±à®©}}</translation>
<translation id="5926846154125914413">சில தளஙà¯à®•à®³à®¿à®©à¯ பிரீமிய உளà¯à®³à®Ÿà®•à¯à®• அணà¯à®•à®²à¯ˆ நீஙà¯à®•à®³à¯ இழகà¯à®•à®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="5959728338436674663">ஆபதà¯à®¤à®¾à®© பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆà®¯à¯à®®à¯ தளஙà¯à®•à®³à¯ˆà®¯à¯à®®à¯ கணà¯à®Ÿà®±à®¿à®µà®¤à®±à¯à®•à¯ உதவியாக, சில <ph name="BEGIN_WHITEPAPER_LINK" />சாதனத௠தகவலையà¯à®®à¯ பகà¯à®• உளà¯à®³à®Ÿà®•à¯à®•à®¤à¯à®¤à¯ˆà®¯à¯à®®à¯<ph name="END_WHITEPAPER_LINK" /> Googleகà¯à®•à¯à®¤à¯ தானாக அனà¯à®ªà¯à®ªà¯. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">வாரமà¯</translation>
<translation id="5967867314010545767">வரலாறà¯à®±à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ அகறà¯à®±à¯</translation>
<translation id="5975083100439434680">சிறிதாகà¯à®•à¯</translation>
-<translation id="598637245381783098">பேமணà¯à®Ÿà¯ பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆà®¤à¯ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
+<translation id="598637245381783098">பேமெணà¯à®Ÿà¯ பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆà®¤à¯ திறகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="5989320800837274978">பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையகம௠சரிசெயà¯à®¯à®ªà¯à®ªà®Ÿà®µà¯à®®à¯ இலà¯à®²à¯ˆ .pac ஸà¯à®•à®¿à®°à®¿à®ªà¯à®Ÿà¯ URL கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà¯à®®à®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="5990559369517809815">சேவையகதà¯à®¤à®¿à®±à¯à®•à®¾à®© கோரிகà¯à®•à¯ˆà®•à®³à¯ நீடà¯à®Ÿà®¿à®ªà¯à®ªà®¿à®©à®¾à®²à¯ தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{பகà¯à®•à®®à¯ 1}other{பகà¯à®•à®®à¯ #}}</translation>
<translation id="6017514345406065928">பசà¯à®šà¯ˆ</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> எனà¯à®®à¯ தளதà¯à®¤à®¿à®²à¯ உளà¯à®³ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯, à®à®®à®¾à®±à¯à®±à®•à¯à®•à¯‚டிய பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆ (இவை வேற௠à®à®¤à¯‹à®µà¯Šà®©à¯à®±à¯ˆà®ªà¯ போல போலியாகத௠தோறà¯à®±à®®à®³à®¿à®•à¯à®•à¯à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ˆ டிராக௠செயà¯à®µà®¤à®±à¯à®•à¯à®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®•à¯à®•à¯‚டிய தரவைச௠சேகரிகà¯à®•à¯à®®à¯) நிறà¯à®µà®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (ஒதà¯à®¤à®¿à®šà¯ˆà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®©)</translation>
<translation id="6027201098523975773">பெயரை உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
<translation id="6040143037577758943">மூடà¯</translation>
<translation id="6042308850641462728">மேலà¯à®®à¯</translation>
+<translation id="6047233362582046994">உஙà¯à®•à®³à¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¿à®±à¯à®•à®¾à®© ஆபதà¯à®¤à¯à®•à®³à¯ˆà®ªà¯ பà¯à®°à®¿à®¨à¯à®¤à¯à®•à¯Šà®£à¯à®Ÿà®¾à®²à¯, தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ அகறà¯à®±à®ªà¯à®ªà®Ÿà¯à®µà®¤à®±à¯à®•à¯ à®®à¯à®©à¯ நீஙà¯à®•à®³à¯ <ph name="BEGIN_LINK" />இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆà®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®²à®¾à®®à¯<ph name="END_LINK" />.</translation>
+<translation id="6051221802930200923"><ph name="SITE" /> தளமானத௠சரà¯à®Ÿà®¿à®ƒà®ªà®¿à®•à¯‡à®Ÿà¯ பினà¯à®©à®¿à®™à¯à®•à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à®¾à®²à¯, தறà¯à®ªà¯‹à®¤à¯ அதைப௠பாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆ எனà¯à®ªà®¤à®¾à®²à¯, இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ பினà¯à®©à®°à¯ சரியாகச௠செயலà¯à®ªà®Ÿà®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="6060685159320643512">கவனமà¯, இநà¯à®¤ சோதனைகள௠பாதிபà¯à®ªà¯ˆ à®à®±à¯à®ªà®Ÿà¯à®¤à¯à®¤à®²à®¾à®®à¯</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯ இலà¯à®²à¯ˆ}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">நிரà¯à®µà®¾à®•à®¿ வழஙà¯à®•à®¿à®¯ சானà¯à®±à®¿à®¤à®´à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ உளà¯à®³à®Ÿà®•à¯à®•à®¤à¯à®¤à¯ˆ அணà¯à®•à®¿à®¯à¯à®³à¯à®³à¯€à®°à¯à®•à®³à¯. <ph name="DOMAIN" /> கà¯à®•à¯ நீஙà¯à®•à®³à¯ வழஙà¯à®•à®¿à®¯ தரவானத௠உஙà¯à®•à®³à¯ நிரà¯à®µà®¾à®•à®¿à®¯à®¾à®²à¯ இடைமறிகà¯à®•à®ªà¯à®ªà®Ÿà®²à®¾à®®à¯.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{à®à®¤à¯à®®à®¿à®²à¯à®²à¯ˆ}=1{1 கடவà¯à®šà¯à®šà¯Šà®²à¯ (ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤à®¤à¯)}other{# கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯ (ஒதà¯à®¤à®¿à®šà¯ˆà®¤à¯à®¤à®µà¯ˆ)}}</translation>
<translation id="6146055958333702838">கேபிளà¯à®•à®³à¯ˆà®šà¯ சரிபாரà¯à®¤à¯à®¤à¯, நீஙà¯à®•à®³à¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®•à¯à®•à¯‚டிய ரூடà¯à®Ÿà®°à¯à®•à®³à¯, மோடமà¯à®•à®³à¯ அலà¯à®²à®¤à¯ பிற நெடà¯à®µà¯Šà®°à¯à®•à¯ சாதனஙà¯à®•à®³à¯ˆ மறà¯à®¤à¯Šà®Ÿà®•à¯à®•à®®à¯ செயà¯à®¯à®µà¯à®®à¯.</translation>
<translation id="614940544461990577">இவறà¯à®±à¯ˆà®šà¯ செயà¯à®¤à¯ பாரà¯à®•à¯à®•à®µà¯à®®à¯:</translation>
<translation id="6151417162996330722">சேவை சானà¯à®±à®¿à®¤à®´à¯ நீணà¯à®Ÿ செலà¯à®²à¯à®ªà®Ÿà®¿à®•à¯ காலதà¯à®¤à¯ˆà®•à¯ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯.</translation>
<translation id="6157877588268064908">ஷிபà¯à®ªà®¿à®™à¯ à®®à¯à®±à¯ˆà®•à®³à¯ˆà®¯à¯à®®à¯ தேவைகளையà¯à®®à¯ பாரà¯à®•à¯à®•, à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®¤à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®•à¯à®•à®µà¯à®®à¯</translation>
+<translation id="6158003235852588289">Google பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© உலாவலானத௠<ph name="SITE" /> தளதà¯à®¤à®¿à®²à¯ சமீபதà¯à®¤à®¿à®²à¯ ஃபிஷிஙà¯à®•à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à®¤à¯. ஃபிஷிங௠தளஙà¯à®•à®³à¯ பிற இணையதளஙà¯à®•à®³à¯ˆà®ªà¯ போல௠காணà¯à®ªà®¿à®¤à¯à®¤à¯, உஙà¯à®•à®³à¯ˆ à®à®®à®¾à®±à¯à®± à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯.</translation>
<translation id="6165508094623778733">மேலà¯à®®à¯ அறிக</translation>
+<translation id="6169916984152623906">இபà¯à®ªà¯‹à®¤à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ à®®à¯à®±à¯ˆà®¯à®¿à®²à¯ உலாவலாமà¯. இநà¯à®¤à®šà¯ சாதனதà¯à®¤à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯ பிறரால௠உஙà¯à®•à®³à¯ செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆà®ªà¯ பாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. எனினà¯à®®à¯, பதிவிறகà¯à®•à®™à¯à®•à®³à¯à®®à¯ பà¯à®¤à¯à®¤à®•à®•à¯à®•à¯à®±à®¿à®•à®³à¯à®®à¯ சேமிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®®à¯.</translation>
<translation id="6177128806592000436">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à®¾à®© உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯, பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®• இலà¯à®²à¯ˆ</translation>
<translation id="6184817833369986695">(கà¯à®´à¯: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">உஙà¯à®•à®³à¯ இணைய இணைபà¯à®ªà¯ˆà®šà¯ சரிபாரà¯à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="6218753634732582820">Chromium இலிரà¯à®¨à¯à®¤à¯ à®®à¯à®•à®µà®°à®¿à®¯à¯ˆ அகறà¯à®±à®µà®¾?</translation>
+<translation id="6221345481584921695">Google பாதà¯à®•à®¾à®ªà¯à®ªà¯ உலாவலானதà¯, சமீபதà¯à®¤à®¿à®²à¯ <ph name="SITE" /> இல௠<ph name="BEGIN_LINK" />தீமà¯à®ªà¯Šà®°à¯à®³à¯ உளà¯à®³à®¤à¯ˆà®•à¯ கணà¯à®Ÿà¯à®ªà®¿à®Ÿà®¿à®¤à¯à®¤à®¤à¯<ph name="END_LINK" />. இயலà¯à®ªà®¾à®•à®µà¯‡ பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®• இரà¯à®•à¯à®•à¯à®®à¯ இணையதளஙà¯à®•à®³à¯à®®à¯ சில சமயஙà¯à®•à®³à®¿à®²à¯ தீமà¯à®ªà¯Šà®°à¯à®³à®¿à®©à®¾à®²à¯ பாதிகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à¯à®®à¯. தீஙà¯à®•à¯à®µà®¿à®³à¯ˆà®µà®¿à®•à¯à®•à¯à®®à¯ உளà¯à®³à®Ÿà®•à¯à®•à®®à®¾à®©à®¤à¯ தீமà¯à®ªà¯Šà®°à¯à®³à¯ˆà®ªà¯ பகிரà¯à®ªà®µà®°à¯ என அழைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®®à¯ <ph name="SUBRESOURCE_HOST" /> இலிரà¯à®¨à¯à®¤à¯ வரà¯à®•à®¿à®±à®¤à¯.</translation>
<translation id="6251924700383757765">தனியà¯à®°à®¿à®®à¯ˆà®•à¯ கொளà¯à®•à¯ˆ</translation>
<translation id="6254436959401408446">பகà¯à®•à®¤à¯à®¤à¯ˆà®¤à¯ திறபà¯à®ªà®¤à®±à¯à®•à¯à®ªà¯ போதà¯à®®à®¾à®© நினைவகம௠இலà¯à®²à¯ˆ</translation>
<translation id="625755898061068298">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à®¾à®© பாதà¯à®•à®¾à®ªà¯à®ªà¯ எசà¯à®šà®°à®¿à®•à¯à®•à¯ˆà®•à®³à¯ˆ à®®à¯à®Ÿà®•à¯à®•à®¤à¯ தேரà¯à®µà¯à®šà¯†à®¯à¯à®¤à¯à®³à¯à®³à¯€à®°à¯à®•à®³à¯.</translation>
@@ -579,15 +647,14 @@
<translation id="6404511346730675251">பà¯à®•à¯à®®à®¾à®°à¯à®•à¯à®•à¯à®•à®³à¯ˆà®¤à¯ திரà¯à®¤à¯à®¤à¯</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" />கà¯à®•à®¾à®© காலாவதித௠தேதியையà¯à®®à¯ CVC எணà¯à®£à¯ˆà®¯à¯à®®à¯ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
<translation id="6414888972213066896">இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆà®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®²à®¾à®®à®¾ என, நீஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à®¿à®Ÿà®®à¯ கேடà¯à®Ÿà¯à®³à¯à®³à¯€à®°à¯à®•à®³à¯</translation>
-<translation id="6416403317709441254">Chromium ஆல௠செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®¾à®¤ சிதைநà¯à®¤ அனà¯à®®à®¤à®¿à®šà¯ சானà¯à®±à¯à®•à®³à¯ˆ இணையதளம௠அனà¯à®ªà¯à®ªà®¿à®¯à¯à®³à¯à®³à®¤à®¾à®²à¯, இபà¯à®ªà¯‹à®¤à¯ <ph name="SITE" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆà®¯à¯‡. இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ சிறித௠நேரம௠கழிதà¯à®¤à¯à®šà¯ செயலà¯à®ªà®Ÿà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">சானà¯à®±à®¿à®¤à®´à¯ திரà¯à®®à¯à®ªà®ªà¯à®ªà¯†à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à®¾ எனà¯à®±à¯ சோதிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="6433490469411711332">தொடரà¯à®ªà¯à®¤à¯ தகவலை மாறà¯à®±à¯</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> இணைகà¯à®• மறà¯à®¤à¯à®¤à®¤à¯.</translation>
<translation id="6446608382365791566">மேலà¯à®®à¯ தகவலைச௠சேரà¯à®•à¯à®•à®µà¯à®®à¯</translation>
+<translation id="6447842834002726250">கà¯à®•à¯à®•à¯€à®•à®³à¯</translation>
<translation id="6451458296329894277">படிவ மறà¯à®šà®®à®°à¯à®ªà¯à®ªà®¿à®ªà¯à®ªà¯ˆ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®•</translation>
<translation id="6456339708790392414">உஙà¯à®•à®³à¯ கடà¯à®Ÿà®£à®®à¯</translation>
<translation id="6458467102616083041">கொளà¯à®•à¯ˆ மூலம௠இயலà¯à®ªà¯à®¨à®¿à®²à¯ˆ தேடல௠மà¯à®Ÿà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à®¾à®²à¯, பாலிசியின௠மதிபà¯à®ªà¯ பà¯à®±à®•à¯à®•à®£à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯.</translation>
-<translation id="6462969404041126431"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ ரதà¯à®¤à¯à®šà¯†à®¯à¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">சாதனக௠கொளà¯à®•à¯ˆà®•à®³à¯</translation>
<translation id="6477321094435799029">இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à®¿à®²à¯ வழகà¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ மாறான கà¯à®±à®¿à®¯à¯€à®Ÿà¯ இரà¯à®ªà¯à®ªà®¤à¯ˆ Chrome கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à¯à®³à¯à®³à®¤à¯, மேலà¯à®®à¯ உஙà¯à®•à®³à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà¯: கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, ஃபோன௠எணà¯à®•à®³à¯ மறà¯à®±à¯à®®à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) பாதà¯à®•à®¾à®•à¯à®• அதைத௠தடà¯à®¤à¯à®¤à¯à®³à¯à®³à®¤à¯.</translation>
<translation id="6489534406876378309">சிதைவà¯à®•à®³à¯ˆà®ªà¯ பதிவேறà¯à®±à¯à®µà®¤à¯ˆà®¤à¯ தொடஙà¯à®•à¯</translation>
@@ -599,20 +666,19 @@
<translation id="6556915248009097796">காலாவதி: <ph name="EXPIRATION_DATE_ABBR" />, கடைசியாகப௠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®¯à®¤à¯: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">இனà¯à®©à¯à®®à¯ உஙà¯à®•à®³à¯ நிரà¯à®µà®¾à®•à®¿ அனà¯à®®à®¤à®¿à®•à¯à®•à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="6569060085658103619">நீடà¯à®Ÿà®¿à®ªà¯à®ªà¯à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பாரà¯à®•à¯à®•à®¿à®±à¯€à®°à¯à®•à®³à¯</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" />கà¯à®•à¯à®®à¯ கà¯à®±à¯ˆà®µà®¾à®• உளà¯à®³à®¤à¯</translation>
+<translation id="657639383826808334">உஙà¯à®•à®³à¯ தகவலைத௠திரà¯à®Ÿà¯à®®à¯ அலà¯à®²à®¤à¯ நீகà¯à®•à¯à®®à¯ ஆபதà¯à®¤à®¾à®© மெனà¯à®ªà¯Šà®°à¯à®³à¯ˆ உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®²à¯ இநà¯à®¤ உளà¯à®³à®Ÿà®•à¯à®•à®®à¯ நிறà¯à®µ à®®à¯à®¯à®²à®²à®¾à®®à¯. <ph name="BEGIN_LINK" />பரவாயிலà¯à®²à¯ˆ காடà¯à®Ÿà¯<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">கà¯à®±à®¿à®¯à®¾à®•à¯à®• விரà¯à®ªà¯à®ªà®™à¯à®•à®³à¯</translation>
<translation id="662080504995468778">வேணà¯à®Ÿà®¾à®®à¯</translation>
<translation id="6626291197371920147">சரியான காரà¯à®Ÿà¯ எணà¯à®£à¯ˆà®šà¯ சேரà¯à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> தேடலà¯</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à¯ தறà¯à®ªà¯‹à®¤à¯à®³à¯à®³ ஹேகà¯à®•à®°à¯à®•à®³à¯ உஙà¯à®•à®³à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, படஙà¯à®•à®³à¯, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯ மறà¯à®±à¯à®®à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) திரà¯à®Ÿà®•à¯à®•à¯‚டிய அலà¯à®²à®¤à¯ நீகà¯à®•à®•à¯à®•à¯‚டிய ஆபதà¯à®¤à®¾à®© நிரலà¯à®•à®³à¯ˆ உஙà¯à®•à®³à¯ Mac இல௠நிறà¯à®µ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">இநà¯à®¤à®•à¯ கொளà¯à®•à¯ˆ தவிரà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯.</translation>
-<translation id="6652240803263749613"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ உஙà¯à®•à®³à¯ கணினியின௠இயகà¯à®• à®®à¯à®±à¯ˆà®®à¯ˆ நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Chromium இலிரà¯à®¨à¯à®¤à¯ படிவப௠பரிநà¯à®¤à¯à®°à¯ˆà®¯à¯ˆ அகறà¯à®±à®µà®¾?</translation>
<translation id="6685834062052613830">வெளியேறி, அமைபà¯à®ªà¯ˆ à®®à¯à®Ÿà®¿à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="6710213216561001401">à®®à¯à®¨à¯à®¤à¯ˆà®¯à®¤à¯</translation>
<translation id="6710594484020273272">&lt;தேடல௠வாரà¯à®¤à¯à®¤à¯ˆà®¯à¯ˆ உளà¯à®³à®¿à®Ÿà¯à®•&gt;</translation>
<translation id="6711464428925977395">பà¯à®°à®¾à®•à¯à®¸à®¿ சரà¯à®µà®°à®¿à®²à¯ à®à®¤à¯‹ தவற௠உளà¯à®³à®¤à¯ அலà¯à®²à®¤à¯ à®®à¯à®•à®µà®°à®¿ தவறாக உளà¯à®³à®¤à¯.</translation>
<translation id="6727102863431372879">அமை</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{உரà¯à®ªà¯à®ªà®Ÿà®¿à®•à®³à¯ இலà¯à®²à¯ˆ}=1{1 உரà¯à®ªà¯à®ªà®Ÿà®¿}other{# உரà¯à®ªà¯à®ªà®Ÿà®¿à®•à®³à¯}}</translation>
<translation id="674375294223700098">தெரியாத சேவையகச௠சானà¯à®±à®¿à®¤à®´à¯ பிழை.</translation>
<translation id="6753269504797312559">கொளà¯à®•à¯ˆ மதிபà¯à®ªà¯</translation>
<translation id="6757797048963528358">உஙà¯à®•à®³à¯ சாதனம௠உறகà¯à®•à®¨à®¿à®²à¯ˆà®•à¯à®•à¯à®šà¯ செனà¯à®±à®¤à¯.</translation>
@@ -620,6 +686,8 @@
<translation id="6810899417690483278">தனிபà¯à®ªà®¯à®©à®¾à®•à¯à®•à®²à¯ à®à®Ÿà®¿</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">மணà¯à®Ÿà®²à®™à¯à®•à®³à®¿à®©à¯ தரவை à®à®±à¯à®± à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
+<translation id="6825578344716086703"><ph name="DOMAIN" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®¯à®±à¯à®šà®¿ செயà¯à®¤à¯€à®°à¯à®•à®³à¯. ஆனால௠சேவையகமானத௠வலிமையறà¯à®± கையொபà¯à®ª அலà¯à®•à®¾à®°à®¿à®¤à®®à¯ˆ (SHA-1 போனà¯à®±à®¤à¯) பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿, கையொபà¯à®ªà®®à®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ˆ வழஙà¯à®•à®¿à®¯à®¤à¯. அதாவதà¯, சேவையகம௠வழஙà¯à®•à®¿à®¯ பாதà¯à®•à®¾à®ªà¯à®ªà¯ அனà¯à®®à®¤à®¿à®šà¯ சானà¯à®±à¯à®•à®³à¯ போலியானதாகà¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯, மேலà¯à®®à¯ அநà¯à®¤à®šà¯ சேவையகம௠நீஙà¯à®•à®³à¯ எதிரà¯à®ªà®¾à®°à¯à®¤à¯à®¤ (ஹேகà¯à®•à®°à¯à®Ÿà®©à¯ தகவல௠பரிமாறà¯à®±à®®à¯ செயà¯à®¤à®¿à®°à¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯) சேவையகமாக இலà¯à®²à®¾à®®à®²à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
+<translation id="6830728435402077660">பாதà¯à®•à®¾à®ªà¯à®ªà®±à¯à®±à®¤à¯</translation>
<translation id="6831043979455480757">மொழிபெயரà¯</translation>
<translation id="6839929833149231406">பகà¯à®¤à®¿</translation>
<translation id="6874604403660855544">&amp;சேரà¯à®¤à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
@@ -627,6 +695,7 @@
<translation id="6895330447102777224">காரà¯à®Ÿà¯ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="6897140037006041989">பயனர௠மà¯à®•à®µà®°à¯</translation>
<translation id="6915804003454593391">பயனரà¯:</translation>
+<translation id="6945221475159498467">தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯</translation>
<translation id="6948701128805548767">பிகà¯à®…ப௠மà¯à®±à¯ˆà®•à®³à¯ˆà®¯à¯à®®à¯ தேவைகளையà¯à®®à¯ பாரà¯à®•à¯à®•, à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®¤à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="6957887021205513506">சேவையகதà¯à®¤à®¿à®©à¯ சானà¯à®±à®¿à®¤à®´à¯ போலியானத௠போல௠தெரிகிறதà¯.</translation>
<translation id="6965382102122355670">சரி</translation>
@@ -635,15 +704,16 @@
<translation id="6973656660372572881">நிலையான பà¯à®°à®¾à®•à¯à®¸à®¿ சேவையகஙà¯à®•à®³à¯à®®à¯ .pac ஸà¯à®•à®¿à®°à®¿à®ªà¯à®Ÿà¯ URL ஆகிய இரணà¯à®Ÿà¯à®®à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯.</translation>
<translation id="6989763994942163495">மேமà¯à®ªà®Ÿà¯à®Ÿ அமைபà¯à®ªà¯à®•à®³à¯ˆà®•à¯ காணà¯à®ªà®¿...</translation>
<translation id="7000990526846637657">வரலாற௠உளà¯à®³à¯€à®Ÿà¯à®•à®³à¯ எதà¯à®µà¯à®®à®¿à®²à¯à®²à¯ˆ</translation>
-<translation id="7009986207543992532"><ph name="DOMAIN" />கà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®¯à®©à¯à®±à¯€à®°à¯à®•à®³à¯, ஆனால௠நீணà¯à®Ÿ செலà¯à®²à¯à®ªà®Ÿà®¿à®•à¯ காலதà¯à®¤à¯ˆà®•à¯ கொணà¯à®Ÿ சானà¯à®±à®¿à®¤à®´à¯ˆ சேவையகம௠வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¤à¯, இதà¯à®ªà¯‹à®©à¯à®± சானà¯à®±à®¿à®¤à®´à¯à®•à®³à¯ நமà¯à®ªà®¤à¯à®¤à®•à¯à®•à®µà¯ˆà®¯à®²à¯à®². <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">சீனா UnionPay</translation>
<translation id="7012372675181957985">உஙà¯à®•à®³à¯ Google கணகà¯à®•à¯ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> எனà¯à®± தளதà¯à®¤à®¿à®²à¯ உலாவல௠வரலாற௠தொடரà¯à®ªà®¾à®© பிற தகவலà¯à®•à®³à¯ˆà®•à¯ கொணà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯</translation>
<translation id="7029809446516969842">கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" />஠அடைய à®®à¯à®¯à®±à¯à®šà®¿à®¤à¯à®¤à¯à®³à¯à®³à¯€à®°à¯à®•à®³à¯, சேவையகம௠வழஙà¯à®•à®¿à®¯ சானà¯à®±à®¿à®¤à®´à¯ நமà¯à®ªà¯à®µà®¤à®±à¯à®•à¯ சாதà¯à®¤à®¿à®¯à®®à®±à¯à®± நீணà¯à®Ÿ செலà¯à®²à¯à®ªà®Ÿà®¿à®•à¯à®•à®¾à®²à®¤à¯à®¤à¯ˆà®•à¯ கொணà¯à®Ÿà¯à®³à¯à®³à®¤à¯.</translation>
+<translation id="7053983685419859001">தடà¯</translation>
<translation id="7064851114919012435">தொடரà¯à®ªà¯à®¤à¯ தகவலà¯</translation>
<translation id="7079718277001814089">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ தீபà¯à®ªà¯Šà®°à¯à®³à¯ உளà¯à®³à®¤à¯</translation>
<translation id="7087282848513945231">மாகாணமà¯</translation>
-<translation id="7088615885725309056">பழையவை</translation>
<translation id="7090678807593890770">Google இல௠<ph name="LINK" />à®à®¤à¯ தேடவà¯à®®à¯</translation>
+<translation id="7108819624672055576">நீடà¯à®Ÿà®¿à®ªà¯à®ªà¯ அனà¯à®®à®¤à®¿à®¤à¯à®¤à®¤à¯</translation>
<translation id="7119414471315195487">பிற தாவலà¯à®•à®³à¯ அலà¯à®²à®¤à¯ நிரலà¯à®•à®³à¯ˆ மூடவà¯à®®à¯</translation>
<translation id="7129409597930077180">இநà¯à®¤ à®®à¯à®•à®µà®°à®¿à®•à¯à®•à¯ அனà¯à®ªà¯à®ª à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. வேற௠மà¯à®•à®µà®°à®¿à®¯à¯ˆà®¤à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="7138472120740807366">டெலிவரி à®®à¯à®±à¯ˆ</translation>
@@ -661,22 +731,18 @@
<translation id="7220786058474068424">செயலà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯</translation>
<translation id="724691107663265825">தளதà¯à®¤à®¿à®²à¯ தீபà¯à®ªà¯Šà®°à¯à®³à¯ உளà¯à®³à®¤à¯</translation>
<translation id="724975217298816891">காரà¯à®Ÿà¯ விவரஙà¯à®•à®³à¯ˆà®ªà¯ பà¯à®¤à¯à®ªà¯à®ªà®¿à®•à¯à®•, <ph name="CREDIT_CARD" /> இன௠காலாவதி தேதியையà¯à®®à¯ CVC எணà¯à®£à¯ˆà®¯à¯à®®à¯ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯. உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¤ பினà¯à®©à®°à¯, உஙà¯à®•à®³à¯ காரà¯à®Ÿà¯ விவரஙà¯à®•à®³à¯ இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à¯à®ªà¯ பகிரபà¯à®ªà®Ÿà¯à®®à¯.</translation>
-<translation id="725866823122871198">உஙà¯à®•à®³à¯ கணினியின௠தேதி மறà¯à®±à¯à®®à¯ நேரம௠(<ph name="DATE_AND_TIME" />) தவறாக இரà¯à®ªà¯à®ªà®¤à®¾à®²à¯ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> கà¯à®•à®¾à®© தனிபà¯à®ªà®Ÿà¯à®Ÿ இணைபà¯à®ªà¯ˆ à®à®±à¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
+<translation id="7260504762447901703">அணà¯à®•à®²à¯ˆ ரதà¯à®¤à¯à®šà¯†à®¯à¯</translation>
<translation id="7275334191706090484">நிரà¯à®µà®•à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®®à¯ பà¯à®•à¯à®®à®¾à®°à¯à®•à¯à®•à¯à®•à®³à¯</translation>
<translation id="7298195798382681320">பரிநà¯à®¤à¯à®°à¯ˆà®¤à¯à®¤à®µà¯ˆ</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> அனà¯à®±à¯ சிதைவ௠அறிகà¯à®•à¯ˆ பெறபà¯à®ªà®Ÿà¯à®Ÿà®¤à¯ (பயனர௠பதிவேறà¯à®±à®•à¯ கோரியà¯à®³à¯à®³à®¾à®°à¯, இனà¯à®©à¯à®®à¯ பதிவேறà¯à®±à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ)</translation>
<translation id="7334320624316649418">&amp;மறà¯à®µà®°à®¿à®šà¯ˆà®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
<translation id="733923710415886693">சானà¯à®±à®¿à®¤à®´à¯ வெளிபà¯à®ªà®Ÿà¯ˆà®¤à¯à®¤à®©à¯à®®à¯ˆ மூலம௠சேவையகதà¯à®¤à®¿à®©à¯ சானà¯à®±à®¿à®¤à®´à¯ வெளியிடபà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
-<translation id="7351800657706554155"><ph name="SITE" /> இன௠சானà¯à®±à®¿à®¤à®´à¯ ரதà¯à®¤à¯à®šà¯†à®¯à¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à®¾à®²à¯, அதறà¯à®•à¯à®šà¯ செலà¯à®² à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. பொதà¯à®µà®¾à®• நெடà¯à®µà¯Šà®°à¯à®•à¯ பிழைகளà¯à®®à¯ பாதிபà¯à®ªà¯à®•à®³à¯à®®à¯ தறà¯à®•à®¾à®²à®¿à®•à®®à®¾à®©à®µà¯ˆà®¯à¯‡. இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ சிறித௠நேரம௠கழிதà¯à®¤à¯à®šà¯ செயலà¯à®ªà®Ÿà¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">கடà¯à®Ÿà®³à¯ˆ வரி</translation>
<translation id="7372973238305370288">தேடல௠மà¯à®Ÿà®¿à®µà¯</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">வேணà¯à®Ÿà®¾à®®à¯</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">காரà¯à®Ÿà¯ˆ உறà¯à®¤à®¿à®šà¯†à®¯à¯</translation>
-<translation id="7394102162464064926">உஙà¯à®•à®³à¯ வரலாறà¯à®±à®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®™à¯à®•à®³à¯ˆ நிசà¯à®šà®¯à®®à®¾à®• நீகà¯à®• விரà¯à®®à¯à®ªà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾?
-
-அசà¯à®šà®šà¯à®šà¯‹! மறைநிலைப௠பயனà¯à®®à¯à®±à¯ˆ <ph name="SHORTCUT_KEY" /> அடà¯à®¤à¯à®¤ à®®à¯à®±à¯ˆ பயனà¯à®³à¯à®³à®¤à®¾à®• இரà¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">சà¯à®¯à®µà®¿à®µà®°à®ªà¯ பாதை</translation>
<translation id="7424977062513257142">இநà¯à®¤ இணையபà¯à®ªà®•à¯à®•à®¤à¯à®¤à®¿à®²à¯à®³à¯à®³ உடà¯à®ªà¯Šà®¤à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ பகà¯à®•à®®à¯ தெரிவிபà¯à®ªà®¤à¯:</translation>
@@ -684,6 +750,7 @@
<translation id="7444046173054089907">இநà¯à®¤à®¤à¯ தளம௠தடà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="7445762425076701745">நீஙà¯à®•à®³à¯ இணைநà¯à®¤à¯à®³à¯à®³ சேவையகதà¯à®¤à®¿à®©à¯ அடையாளதà¯à®¤à¯ˆ à®®à¯à®´à¯à®®à¯ˆà®¯à®¾à®• சரிபாரà¯à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. பெயர௠மடà¯à®Ÿà¯à®®à¯‡ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à¯à®®à¯ எனà¯à®± à®®à¯à®±à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ உஙà¯à®•à®³à¯ பிணையதà¯à®¤à®¿à®±à¯à®•à¯à®³à¯ சேவையகதà¯à®¤à¯à®Ÿà®©à¯ இணைநà¯à®¤à¯à®³à¯à®³à¯€à®°à¯à®•à®³à¯, இதன௠உரிமையை ஒர௠வெளிபà¯à®ªà¯à®± சானà¯à®±à®¿à®¤à®´à¯ மையம௠எபà¯à®ªà¯‹à®¤à¯à®®à¯ உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®¾à®¤à¯. சில சானà¯à®±à®¿à®¤à®´à¯ மையஙà¯à®•à®³à¯, இநà¯à®¤à®ªà¯ பெயரà¯à®•à®³à¯à®•à¯à®•à¯à®®à¯ சானà¯à®±à®¿à®¤à®´à¯à®•à®³à¯ˆ வழஙà¯à®•à¯à®µà®¾à®°à¯à®•à®³à¯ எனà¯à®ªà®¤à®¾à®²à¯, நீஙà¯à®•à®³à¯ நினைதà¯à®¤ வலைபà¯à®ªà®•à¯à®•à®¤à¯à®¤à¯à®Ÿà®©à¯‡ இணைநà¯à®¤à¯à®³à¯à®³à¯€à®°à¯à®•à®³à¯, à®à®¤à¯‡à®©à¯à®®à¯ மோசடி தளதà¯à®¤à¯à®Ÿà®©à¯ இணையவிலà¯à®²à¯ˆ எனà¯à®ªà®¤à¯ˆ உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤ எநà¯à®¤ வழியà¯à®®à¯ இலà¯à®²à¯ˆ.</translation>
<translation id="7451311239929941790">இநà¯à®¤à®šà¯ சிகà¯à®•à®²à¯ கà¯à®±à®¿à®¤à¯à®¤à¯ <ph name="BEGIN_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">à®®à¯à®´à¯à®®à¯ˆà®¯à®¾à®© இயலà¯à®ªà¯à®¨à®¿à®²à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯ (தடà¯)</translation>
<translation id="7460163899615895653">பிற சாதனஙà¯à®•à®³à®¿à®²à®¿à®°à¯à®•à¯à®•à¯à®®à¯ உஙà¯à®•à®³à¯ சமீபதà¯à®¤à®¿à®¯ தாவலà¯à®•à®³à¯ இஙà¯à®•à¯‡ தோனà¯à®±à¯à®®à¯</translation>
<translation id="7469372306589899959">காரà¯à®Ÿà¯ˆ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®•à®¿à®±à®¤à¯</translation>
<translation id="7481312909269577407">அடà¯à®¤à¯à®¤ பகà¯à®•à®®à¯</translation>
@@ -691,41 +758,48 @@
<translation id="7508255263130623398">கிடைதà¯à®¤ பாலிசி சாதன à®à®Ÿà®¿ காலியாக உளà¯à®³à®¤à¯ அலà¯à®²à®¤à¯ தறà¯à®ªà¯‹à®¤à¯ˆà®¯ சாதன à®à®Ÿà®¿à®¯à¯à®Ÿà®©à¯ பொரà¯à®¨à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="7514365320538308">பதிவிறகà¯à®•à¯</translation>
<translation id="7518003948725431193">வலை à®®à¯à®•à®µà®°à®¿à®•à¯à®•à®¾à®© வலைபà¯à®ªà®•à¯à®•à®™à¯à®•à®³à¯ à®à®¤à¯à®®à¯ காணபà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">மதிபà¯à®ªà¯</translation>
<translation id="7537536606612762813">கடà¯à®Ÿà®¾à®¯à®®à¯</translation>
+<translation id="7542403920425041731">நீஙà¯à®•à®³à¯ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¤à®¤à¯à®®à¯, உஙà¯à®•à®³à¯ காரà¯à®Ÿà¯ விவரஙà¯à®•à®³à¯ இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯à®Ÿà®©à¯ பகிரபà¯à®ªà®Ÿà¯à®®à¯.</translation>
<translation id="7542995811387359312">இநà¯à®¤à®ªà¯ படிவம௠பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© இணைபà¯à®ªà¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¾à®¤ காரணதà¯à®¤à®¾à®²à¯, தானியஙà¯à®•à¯ கடன௠அடà¯à®Ÿà¯ˆ நிரபà¯à®ªà¯à®¤à®²à¯ à®®à¯à®Ÿà®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®¿à®±à®¤à¯.</translation>
<translation id="7543525346216957623">உஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à®¿à®Ÿà®®à¯ கேடà¯à®•à®µà¯à®®à¯</translation>
<translation id="7549584377607005141">சரியாக காணà¯à®ªà®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®µà®¤à®±à¯à®•à¯ நீஙà¯à®•à®³à¯ à®à®±à¯à®•à®©à®µà¯‡ உளà¯à®³à®¿à®Ÿà¯à®Ÿ தரவ௠இநà¯à®¤ இணையபà¯à®ªà®•à¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ தேவைபà¯à®ªà®Ÿà¯à®•à®¿à®±à®¤à¯. இநà¯à®¤ தரவை நீஙà¯à®•à®³à¯ மீணà¯à®Ÿà¯à®®à¯ அனà¯à®ªà¯à®ªà®²à®¾à®®à¯, ஆனால௠அவà¯à®µà®¾à®±à¯ செயà¯à®µà®¤à®©à®¾à®²à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ à®à®±à¯à®•à®©à®µà¯‡ செயறà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®¯ எலà¯à®²à®¾à®šà¯ செயலையà¯à®®à¯ மீணà¯à®Ÿà¯à®®à¯ செயà¯à®µà¯€à®°à¯à®•à®³à¯.</translation>
<translation id="7552846755917812628">பினà¯à®µà®°à¯à®®à¯ உதவிக௠கà¯à®±à®¿à®ªà¯à®ªà¯à®•à®³à¯ˆà®šà¯ செயà¯à®¤à¯ பாரà¯à®•à¯à®•à®µà¯à®®à¯:</translation>
<translation id="7554791636758816595">பà¯à®¤à®¿à®¯ தாவலà¯</translation>
+<translation id="7567204685887185387">இத௠<ph name="DOMAIN" /> தான௠எனà¯à®ªà®¤à¯ˆ இநà¯à®¤à®šà¯ சேவையகம௠உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ; இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à®¿à®²à¯ மோசடி செயà¯à®¯à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">இநà¯à®¤à®ªà¯ பகà¯à®•à®®à®¾à®©à®¤à¯<ph name="ORIGINAL_LANGUAGE" />இல௠உளà¯à®³à®¤à¯ இதை மொழிபெயரà¯à®•à¯à®• விரà¯à®®à¯à®ªà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾?</translation>
<translation id="7569952961197462199">Chrome இலிரà¯à®¨à¯à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯ˆ அகறà¯à®±à®µà®¾?</translation>
<translation id="7569983096843329377">கரà¯à®ªà¯à®ªà¯</translation>
<translation id="7578104083680115302">Google இல௠நீஙà¯à®•à®³à¯ சேமிதà¯à®¤à¯à®³à¯à®³ காரà¯à®Ÿà¯à®•à®³à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ பல தளஙà¯à®•à®³à®¿à®²à¯à®®à¯ பயனà¯à®ªà®¾à®Ÿà¯à®•à®³à®¿à®²à¯à®®à¯ உஙà¯à®•à®³à¯à®Ÿà¯ˆà®¯ சாதனஙà¯à®•à®³à®¿à®²à¯ அனைதà¯à®¤à®¿à®²à¯à®®à¯ விரைவாகப௠பணம௠செலà¯à®¤à¯à®¤à®²à®¾à®®à¯.</translation>
<translation id="7588950540487816470">இயலà¯à®¨à®¿à®²à¯ˆ இணையமà¯</translation>
<translation id="7592362899630581445">பெயர௠கடà¯à®Ÿà¯à®ªà¯à®ªà®¾à®Ÿà¯à®•à®³à¯ˆà®šà¯ சேவையகதà¯à®¤à®¿à®©à¯ சானà¯à®±à®¿à®¤à®´à¯ மீறà¯à®•à®¿à®±à®¤à¯.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> அளவை விடக௠கà¯à®±à¯ˆà®µà®¾à®• உளà¯à®³à®¤à¯</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ஆல௠தறà¯à®ªà¯‹à®¤à¯ இநà¯à®¤à®•à¯ கோரிகà¯à®•à¯ˆà®¯à¯ˆà®•à¯ கையாள à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> ஠எபà¯à®ªà¯‹à®¤à¯à®®à¯ மொழிபெயரà¯à®•à¯à®• வேணà¯à®Ÿà®¾à®®à¯</translation>
<translation id="7610193165460212391"><ph name="VALUE" /> எனà¯à®± மதிபà¯à®ªà¯ வரமà¯à®ªà¯ˆ மீறியà¯à®³à¯à®³à®¤à¯.</translation>
<translation id="7613889955535752492">காலாவதியாவதà¯: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">உஙà¯à®•à®³à¯ Google கணகà¯à®•à¯ கடவà¯à®šà¯à®šà¯Šà®²à¯à®²à®¿à®©à¯ மறà¯à®±à¯Šà®°à¯ பதிபà¯à®ªà¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿ கà¯à®±à®¿à®¯à®¾à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ தரவ௠உஙà¯à®•à®³à®¿à®Ÿà®®à¯ à®à®±à¯à®•à®©à®µà¯‡ உளà¯à®³à®¤à¯. கீழே அதை உளà¯à®³à®¿à®Ÿà¯à®•.</translation>
-<translation id="7634554953375732414">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à®¾à®© உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯ தனிபà¯à®ªà®Ÿà¯à®Ÿà®¤à®²à¯à®².</translation>
<translation id="7637571805876720304">Chromium இலிரà¯à®¨à¯à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯ˆ அகறà¯à®±à®µà®¾?</translation>
<translation id="765676359832457558">மேமà¯à®ªà®Ÿà¯à®Ÿ அமைபà¯à®ªà¯à®•à®³à¯ˆ மறை...</translation>
<translation id="7658239707568436148">ரதà¯à®¤à¯ செயà¯</translation>
+<translation id="7662298039739062396">அமைபà¯à®ªà¯ˆ நீடà¯à®Ÿà®¿à®ªà¯à®ªà¯ கடà¯à®Ÿà¯à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯</translation>
<translation id="7667346355482952095">கிடைதà¯à®¤ பாலிசி டோகà¯à®•à®©à¯ காலியாக உளà¯à®³à®¤à¯ அலà¯à®²à®¤à¯ தறà¯à®ªà¯‹à®¤à¯ˆà®¯ டோகà¯à®•à®©à¯à®Ÿà®©à¯ பொரà¯à®¨à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="7668654391829183341">அறியபà¯à®ªà®Ÿà®¾à®¤ சாதனமà¯</translation>
<translation id="7669271284792375604">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ உளà¯à®³ ஹேகà¯à®•à®°à¯à®•à®³à¯, உஙà¯à®•à®³à¯ˆ à®à®®à®¾à®±à¯à®±à®¿ (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, உஙà¯à®•à®³à¯ à®®à¯à®•à®ªà¯à®ªà¯à®ªà¯ பகà¯à®•à®¤à¯à®¤à¯ˆ மாறà¯à®±à¯à®µà®¤à¯ அலà¯à®²à®¤à¯ நீஙà¯à®•à®³à¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà¯à®®à¯ தளஙà¯à®•à®³à®¿à®²à¯ கூடà¯à®¤à®²à¯ விளமà¯à®ªà®°à®™à¯à®•à®³à¯ˆà®•à¯ காடà¯à®Ÿà¯à®µà®¤à¯), உஙà¯à®•à®³à¯ உலாவல௠அனà¯à®ªà®µà®¤à¯à®¤à¯ˆà®ªà¯ பாதிகà¯à®•à®•à¯à®•à¯‚டிய நிரலà¯à®•à®³à¯ˆ நிறà¯à®µ வைகà¯à®•à®²à®¾à®®à¯.</translation>
<translation id="7674629440242451245">பà¯à®¤à®¿à®¯ Chrome à®…à®®à¯à®šà®™à¯à®•à®³à®¿à®²à¯ ஆரà¯à®µà®®à®¾à®• உளà¯à®³à¯€à®°à¯à®•à®³à®¾? chrome.com/dev இல௠எஙà¯à®•à®³à¯à®Ÿà¯ˆà®¯ dev சேனலை à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="7682287625158474539">ஷிபà¯à®ªà®¿à®™à¯</translation>
+<translation id="7701040980221191251">எதà¯à®µà¯à®®à®¿à®²à¯à®²à¯ˆ</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" /> (பாதà¯à®•à®¾à®ªà¯à®ªà®±à¯à®± தளமà¯) கà¯à®•à¯à®šà¯ செலà¯à®²à®µà¯à®®à¯<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">சானà¯à®±à®¿à®¤à®´à¯</translation>
+<translation id="7716147886133743102">உஙà¯à®•à®³à¯ நிரà¯à®µà®¾à®•à®¿ தடà¯à®¤à¯à®¤à¯à®³à¯à®³à®¾à®°à¯</translation>
<translation id="7716424297397655342">தறà¯à®•à®¾à®²à®¿à®•à®šà¯ சேமிபà¯à®ªà®¿à®²à®¿à®°à¯à®¨à¯à®¤à¯ இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆ à®à®±à¯à®± à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">நிரà¯à®µà®•à®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà®¾à®¤à®¤à¯</translation>
<translation id="7755287808199759310">உஙà¯à®•à®³à¯à®•à¯à®•à®¾à®•, தளதà¯à®¤à®¿à®©à¯ தடà¯à®ªà¯à®ªà¯ˆ உஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à¯ நீகà¯à®• à®®à¯à®Ÿà®¿à®¯à¯à®®à¯</translation>
<translation id="7758069387465995638">தீசà¯à®šà¯à®µà®°à¯ அலà¯à®²à®¤à¯ வைரஸà¯à®¤à®Ÿà¯à®ªà¯à®ªà¯ மெனà¯à®ªà¯Šà®°à¯à®³à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯ˆà®¤à¯ தடà¯à®¤à¯à®¤à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="7761701407923456692">சேவையகச௠சானà¯à®±à®¿à®¤à®´à¯ URL உடன௠பொரà¯à®¨à¯à®¤à®µà®¿à®²à¯à®²à¯ˆ.</translation>
-<translation id="7763386264682878361">பேமணà¯à®Ÿà¯ மேனிஃபெஸà¯à®Ÿà¯ பாகà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿</translation>
+<translation id="7763386264682878361">பேமெணà¯à®Ÿà¯ மேனிஃபெஸà¯à®Ÿà¯ பாகà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿</translation>
<translation id="7764225426217299476">à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®šà¯ சேரà¯</translation>
<translation id="777702478322588152">பà¯à®°à¯€à®ƒà®ªà¯†à®•à¯à®šà®°à¯</translation>
<translation id="7791543448312431591">சேரà¯</translation>
@@ -747,15 +821,15 @@
<translation id="7951415247503192394">(32-பிடà¯)</translation>
<translation id="7956713633345437162">மொபைல௠பà¯à®•à¯à®®à®¾à®°à¯à®•à¯à®•à¯à®•à®³à¯</translation>
<translation id="7961015016161918242">எபà¯à®ªà¯‹à®¤à¯à®®à¯ இலà¯à®²à¯ˆ</translation>
-<translation id="7962083544045318153">சிதைவ௠à®à®Ÿà®¿ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> à® <ph name="TARGET_LANGUAGE" /> கà¯à®•à¯ எபà¯à®ªà¯‹à®¤à¯à®®à¯ மொழிபெயரà¯à®ªà¯à®ªà¯ செயà¯à®•</translation>
<translation id="7995512525968007366">கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="800218591365569300">பிற தாவலà¯à®•à®³à¯ அலà¯à®²à®¤à¯ நிரலà¯à®•à®³à¯ˆ மூடி, நினைவகதà¯à®¤à¯ˆà®•à¯ காலியாகà¯à®•à®µà¯à®®à¯.</translation>
<translation id="8012647001091218357">தறà¯à®ªà¯‹à®¤à¯ எஙà¯à®•à®³à®¾à®²à¯ உஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à¯à®•à®³à¯ˆà®¤à¯ தொடரà¯à®ªà¯à®•à¯Šà®³à¯à®³ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®µà¯à®®à¯.</translation>
<translation id="8025119109950072390">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ உளà¯à®³ ஹேகà¯à®•à®°à¯à®•à®³à¯, உஙà¯à®•à®³à¯ˆ à®à®®à®¾à®±à¯à®±à®¿, மெனà¯à®ªà¯Šà®°à¯à®³à¯ˆ நிறà¯à®µà¯à®µà®¤à¯ அலà¯à®²à®¤à¯ தனிபà¯à®ªà®Ÿà¯à®Ÿ தகவலை (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, ஃபோன௠எணà¯à®•à®³à¯ அலà¯à®²à®¤à¯ கிரெடிட௠காரà¯à®Ÿà¯à®•à®³à¯) வெளிபà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®µà®¤à¯ போனà¯à®± உஙà¯à®•à®³à¯à®•à¯à®•à¯ ஆபதà¯à®¤à¯ˆ விளைவிகà¯à®•à¯à®®à¯ செயலà¯à®•à®³à¯ˆà®šà¯ செயà¯à®¯ வைகà¯à®•à®²à®¾à®®à¯.</translation>
-<translation id="803030522067524905">சமீபதà¯à®¤à®¿à®²à¯ Google இன௠பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© உலாவலானத௠<ph name="SITE" /> இல௠ஃபிஷிஙà¯à®•à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à¯à®³à¯à®³à®¤à¯. ஃபிஷிங௠தளஙà¯à®•à®³à¯ பிற தளஙà¯à®•à®³à¯ˆà®ªà¯ போலவே தோறà¯à®±à®®à®³à®¿à®¤à¯à®¤à¯ உஙà¯à®•à®³à¯ˆ à®à®®à®¾à®±à¯à®±à¯à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ <ph name="SOURCE_LANGUAGE" /> மொழியில௠உளà¯à®³à®¤à¯. இதை <ph name="TARGET_LANGUAGE" /> கà¯à®•à¯ மொழிபெயரà¯à®•à¯à®•à®µà®¾?</translation>
+<translation id="8037357227543935929">கேள௠(இயலà¯à®ªà¯)</translation>
<translation id="8041089156583427627">கரà¯à®¤à¯à®¤à¯à®¤à¯ தெரிவிகà¯à®•à®µà¯à®®à¯</translation>
+<translation id="8041940743680923270">à®®à¯à®´à¯à®®à¯ˆà®¯à®¾à®© இயலà¯à®ªà¯à®¨à®¿à®²à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯ (கேளà¯)</translation>
<translation id="8088680233425245692">கடà¯à®Ÿà¯à®°à¯ˆà®¯à¯ˆà®•à¯ காடà¯à®Ÿà¯à®µà®¤à®¿à®²à¯ தோலà¯à®µà®¿.</translation>
<translation id="8089520772729574115">1 மெ.பை. கà¯à®•à¯à®®à¯ கà¯à®±à¯ˆà®µà®¾à®• உளà¯à®³à®¤à¯</translation>
<translation id="8091372947890762290">சேவையகதà¯à®¤à®¿à®²à¯ செயலாகà¯à®•à®®à¯ நிலà¯à®µà¯ˆà®¯à®¿à®²à¯à®³à¯à®³à®¤à¯</translation>
@@ -764,13 +838,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> இன௠சேவையக <ph name="BEGIN_ABBR" />DNS à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®•à¯<ph name="END_ABBR" /> கணà¯à®Ÿà¯à®ªà®¿à®Ÿà®¿à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="8149426793427495338">உஙà¯à®•à®³à¯ கணினி உறகà¯à®•à®¨à®¿à®²à¯ˆà®•à¯à®•à¯à®šà¯ செனà¯à®±à®¤à¯.</translation>
<translation id="8150722005171944719"><ph name="URL" /> இல௠உளà¯à®³ கோபà¯à®ªà¯ படிகà¯à®•à®•à¯ கூடியதாக இலà¯à®²à¯ˆ. அத௠அகறà¯à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯, நகரà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ கோபà¯à®ªà¯ அனà¯à®®à®¤à®¿à®•à®³à¯ அணà¯à®•à®²à¯ˆà®¤à¯ தடà¯à®¤à¯à®¤à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯.</translation>
+<translation id="8184538546369750125">à®®à¯à®´à¯à®®à¯ˆà®¯à®¾à®© இயலà¯à®ªà¯à®¨à®¿à®²à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯ (அனà¯à®®à®¤à®¿)</translation>
+<translation id="8191494405820426728">அகச௠சிதைவ௠à®à®Ÿà®¿: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;நகரà¯à®¤à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" à®à®Ÿà®¿à®¯à¯à®Ÿà®©à¯ கூடிய நீடà¯à®Ÿà®¿à®ªà¯à®ªà®¿à®±à¯à®•à®¾à®© தவறான பà¯à®¤à¯à®ªà¯à®ªà®¿à®ªà¯à®ªà¯ URL.</translation>
<translation id="8202097416529803614">ஆரà¯à®Ÿà®°à¯ பறà¯à®±à®¿à®¯ சà¯à®°à¯à®•à¯à®•à®µà®¿à®µà®°à®®à¯</translation>
<translation id="8218327578424803826">ஒதà¯à®•à¯à®•à®¿à®¯ இரà¯à®ªà¯à®ªà®¿à®Ÿà®®à¯:</translation>
<translation id="8225771182978767009">இநà¯à®¤à®•à¯ கணினியை அமைதà¯à®¤ நபர௠இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆà®¤à¯ தடà¯à®•à¯à®•à¯à®®à¯à®ªà®Ÿà®¿ தேரà¯à®µà¯à®šà¯†à®¯à¯à®¤à¯à®³à¯à®³à®¾à®°à¯.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> தளதà¯à®¤à®¿à®²à¯ தறà¯à®ªà¯‹à®¤à¯ இரà¯à®•à¯à®•à¯à®®à¯ தாகà¯à®•à¯à®ªà®µà®°à¯à®•à®³à¯, உஙà¯à®•à®³à¯ படஙà¯à®•à®³à¯, கடவà¯à®šà¯à®šà¯Šà®±à¯à®•à®³à¯, செயà¯à®¤à®¿à®•à®³à¯, கிரெடிக௠காரà¯à®Ÿà¯à®•à®³à¯ போனà¯à®± தகவலà¯à®•à®³à¯ˆà®¤à¯ திரà¯à®Ÿ அலà¯à®²à®¤à¯ அழிகà¯à®•à®•à¯à®•à¯‚டிய ஆபதà¯à®¤à®¾à®© நிரலà¯à®•à®³à¯ˆ உஙà¯à®•à®³à¯ கணினியில௠நிறà¯à®µ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®²à®¾à®®à¯.</translation>
<translation id="8241707690549784388">நீஙà¯à®•à®³à¯ தேடà¯à®®à¯ பகà¯à®•à®®à®¾à®©à®¤à¯ நீஙà¯à®•à®³à¯ உளà¯à®³à®¿à®Ÿà¯à®Ÿ தகவலைப௠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®¿à®¯à®¤à¯. மீணà¯à®Ÿà¯à®®à¯ அநà¯à®¤ பகà¯à®•à®¤à¯à®¤à®¿à®±à¯à®•à¯ திரà¯à®®à¯à®ªà®¿à®©à®¾à®²à¯, நீஙà¯à®•à®³à¯ செயà¯à®¤ à®à®¤à¯‡à®©à¯à®®à¯ செயலை மீணà¯à®Ÿà¯à®®à¯ செயà¯à®¯ வேணà¯à®Ÿà®¿à®¯à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. தொடர விரà¯à®®à¯à®ªà¯à®•à®¿à®±à¯€à®°à¯à®•à®³à®¾?</translation>
<translation id="8249320324621329438">கடைசியாக எடà¯à®¤à¯à®¤à®¤à¯:</translation>
<translation id="8253091569723639551">பிலà¯à®²à®¿à®™à¯ à®®à¯à®•à®µà®°à®¿ தேவை</translation>
@@ -778,6 +853,7 @@
<translation id="8289355894181816810">இதன௠பொரà¯à®³à¯ உஙà¯à®•à®³à¯à®•à¯à®•à¯à®¤à¯ தெரியவிலà¯à®²à¯ˆà®¯à¯†à®©à®¿à®²à¯ உஙà¯à®•à®³à¯ பிணைய நிரà¯à®µà®¾à®•à®¿à®¯à¯ˆà®¤à¯ தொடரà¯à®ªà¯à®•à¯Šà®³à¯à®³à®µà¯à®®à¯.</translation>
<translation id="8293206222192510085">பà¯à®•à¯à®®à®¾à®°à¯à®•à¯à®•à¯ˆà®šà¯ சேரà¯</translation>
<translation id="8294431847097064396">மூலமà¯</translation>
+<translation id="8306404619377842860">உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ தேதியà¯à®®à¯ நேரமà¯à®®à¯ (<ph name="DATE_AND_TIME" />) தவறாக இரà¯à®ªà¯à®ªà®¤à®¾à®²à¯, <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />கà¯à®•à®¾à®© தனிபà¯à®ªà®Ÿà¯à®Ÿ இணைபà¯à®ªà¯ˆà®šà¯ செயலாகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">பிணைய இணைபà¯à®ªà®¿à®²à¯ ஒர௠சிகà¯à®•à®²à¯ இரà¯à®ªà¯à®ªà®¤à®¾à®²à¯ மொழிபà¯à®ªà¯†à®¯à®°à¯à®ªà¯à®ªà¯ தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> கà¯à®•à®¾à®© அணà¯à®•à®²à¯ மறà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="834457929814110454">உஙà¯à®•à®³à¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¿à®±à¯à®•à®¾à®© ஆபதà¯à®¤à¯ˆà®ªà¯ பà¯à®°à®¿à®¨à¯à®¤à¯à®•à¯Šà®£à¯à®Ÿà®¾à®²à¯, தீஙà¯à®•à®¾à®© நிரலà¯à®•à®³à¯ˆ அகறà¯à®±à¯à®®à¯ à®®à¯à®©à¯ <ph name="BEGIN_LINK" />இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆà®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®²à®¾à®®à¯<ph name="END_LINK" />.</translation>
@@ -798,24 +874,23 @@
<translation id="8483780878231876732">Google கணகà¯à®•à®¿à®²à¯ உளà¯à®³ காரà¯à®Ÿà¯à®•à®³à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤, Chrome இல௠உளà¯à®¨à¯à®´à¯ˆà®¯à®µà¯à®®à¯</translation>
<translation id="8488350697529856933">இதறà¯à®•à¯à®ªà¯ பொரà¯à®¨à¯à®¤à¯à®®à¯</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> பதிலளிகà¯à®• நீணà¯à®Ÿ நேரம௠எடà¯à®¤à¯à®¤à¯à®•à¯à®•à¯Šà®£à¯à®Ÿà®¤à¯.</translation>
-<translation id="852346902619691059"><ph name="DOMAIN" /> என இநà¯à®¤à®šà¯ சேவையகதà¯à®¤à®¾à®²à¯ நிரூபிகà¯à®• à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. இதன௠பாதà¯à®•à®¾à®ªà¯à®ªà¯à®šà¯ சானà¯à®±à®¿à®¤à®´à¯ˆ உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ இயகà¯à®• à®®à¯à®±à¯ˆà®®à¯ˆ நமà¯à®ªà®µà®¿à®²à¯à®²à¯ˆ. இத௠தவறான உளà¯à®³à®®à¯ˆà®µà®¾à®²à¯ à®à®±à¯à®ªà®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ இணைபà¯à®ªà®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ கà¯à®±à¯à®•à¯à®•à®¿à®Ÿà¯à®Ÿà®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯. <ph name="BEGIN_LEARN_MORE_LINK" />மேலà¯à®®à¯ அறிக<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">காலாவதியாகà¯à®®à¯ ஆணà¯à®Ÿà¯</translation>
<translation id="8543181531796978784"><ph name="BEGIN_ERROR_LINK" />கணà¯à®Ÿà®±à®¿à®µà®¤à®¿à®²à¯ சிகà¯à®•à®²à¯ இரà¯à®ªà¯à®ªà®¤à¯ˆà®ªà¯ பà¯à®•à®¾à®°à®³à®¿à®•à¯à®•à®²à®¾à®®à¯<ph name="END_ERROR_LINK" /> அலà¯à®²à®¤à¯ உஙà¯à®•à®³à¯ பாதà¯à®•à®¾à®ªà¯à®ªà®¿à®±à¯à®•à¯ à®à®±à¯à®ªà®Ÿà®•à¯à®•à¯‚டிய ஆபதà¯à®¤à¯à®•à®³à¯ˆà®ªà¯ பà¯à®°à®¿à®¨à¯à®¤à¯à®•à¯Šà®£à¯à®Ÿà®¿à®°à¯à®¨à¯à®¤à®¾à®²à¯, <ph name="BEGIN_LINK" />இநà¯à®¤à®ªà¯ பாதà¯à®•à®¾à®ªà¯à®ªà®±à¯à®± தளதà¯à®¤à®¿à®±à¯à®•à¯à®šà¯ செலà¯à®²à®²à®¾à®®à¯<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">பகà¯à®•à®¤à¯à®¤à®¿à®©à¯ மொழியைத௠தீரà¯à®®à®¾à®©à®¿à®•à¯à®• à®®à¯à®Ÿà®¿à®¯à®¾à®¤à®¤à®¾à®²à¯ மொழிபெயரà¯à®ªà¯à®ªà¯ தோலà¯à®µà®¿à®¯à®Ÿà¯ˆà®¨à¯à®¤à®¤à¯.</translation>
-<translation id="8559762987265718583">உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ தேதி மறà¯à®±à¯à®®à¯ நேரம௠(<ph name="DATE_AND_TIME" />) தவறாக உளà¯à®³à®¤à®¾à®²à¯ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> கà¯à®•à®¾à®© தனிபà¯à®ªà®Ÿà¯à®Ÿ இணைபà¯à®ªà¯ˆ à®à®±à¯à®ªà®Ÿà¯à®¤à¯à®¤ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="8571890674111243710"><ph name="LANGUAGE" /> கà¯à®•à¯ பகà¯à®•à®¤à¯à®¤à¯ˆ மொழிபெயரà¯à®•à¯à®•à®¿à®±à®¤à¯...</translation>
<translation id="858637041960032120">தொலைபேசி எணà¯</translation>
<translation id="859285277496340001">இநà¯à®¤ சானà¯à®±à®¿à®¤à®´à¯ திரà¯à®®à¯à®ªà®ªà¯à®ªà¯†à®±à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à®¾ எனà¯à®ªà®¤à¯ˆà®šà¯ சரிபாரà¯à®ªà¯à®ªà®¤à®±à¯à®•à®¾à®© செயலà¯à®®à¯à®±à¯ˆ இதில௠இலà¯à®²à¯ˆ.</translation>
<translation id="8620436878122366504">இனà¯à®©à¯à®®à¯ உஙà¯à®•à®³à¯ பெறà¯à®±à¯‹à®°à¯ அனà¯à®®à®¤à®¿à®•à¯à®•à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="8647750283161643317">எலà¯à®²à®¾à®µà®±à¯à®±à¯ˆà®¯à¯à®®à¯ இயலà¯à®ªà¯à®¨à®¿à®²à¯ˆà®•à¯à®•à¯ மீடà¯à®Ÿà®®à¯ˆ</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> கà¯à®•à®¾à®© உஙà¯à®•à®³à¯ இணைபà¯à®ªà¯ கà¯à®±à®¿à®¯à®¾à®•à¯à®•à®®à¯ செயà¯à®¯à®ªà¯à®ªà®Ÿà®µà®¿à®²à¯à®²à¯ˆ.</translation>
-<translation id="8718314106902482036">பேமணà¯à®Ÿà¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
+<translation id="8718314106902482036">பேமெணà¯à®Ÿà¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ</translation>
<translation id="8725066075913043281">மீணà¯à®Ÿà¯à®®à¯ à®®à¯à®¯à®±à¯à®šà®¿à®•à¯à®•à®µà¯à®®à¯</translation>
<translation id="8728672262656704056">மறைநிலைகà¯à®•à¯à®šà¯ செனà¯à®±à¯à®µà®¿à®Ÿà¯à®Ÿà¯€à®°à¯à®•à®³à¯</translation>
<translation id="8730621377337864115">à®®à¯à®Ÿà®¿à®¨à¯à®¤à®¤à¯</translation>
<translation id="8738058698779197622">பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© இணைபà¯à®ªà¯ˆ அமைகà¯à®•, கடிகாரம௠சரியாக அமைகà¯à®•à®ªà¯à®ªà®Ÿ வேணà¯à®Ÿà¯à®®à¯. இதறà¯à®•à¯à®•à¯ காரணமà¯, இணையதளஙà¯à®•à®³à¯ தஙà¯à®•à®³à¯ˆà®¤à¯ தானே அடையாளபà¯à®ªà®Ÿà¯à®¤à¯à®¤ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®®à¯ சானà¯à®±à®¿à®¤à®´à¯à®•à®³à¯ கà¯à®±à®¿à®ªà¯à®ªà®¿à®Ÿà¯à®Ÿ காலநேரதà¯à®¤à®¿à®±à¯à®•à¯‡ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à¯à®®à¯. உஙà¯à®•à®³à¯ சாதனதà¯à®¤à®¿à®©à¯ கடிகாரம௠தவறாக இரà¯à®¨à¯à®¤à®¾à®²à¯, Chromium இநà¯à®¤à®šà¯ சானà¯à®±à®¿à®¤à®´à¯à®•à®³à¯ˆà®šà¯ சரிபாரà¯à®•à¯à®•à®¾à®¤à¯.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" />’s &lt;abbr id="dnsDefinition"&gt;DNS à®®à¯à®•à®µà®°à®¿à®¯à¯ˆà®•à¯&lt;/abbr&gt; கணà¯à®Ÿà®±à®¿à®¯ à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ. சிகà¯à®•à®²à¯ˆ ஆயà¯à®µà¯ செயà¯à®•à®¿à®±à®¤à¯.</translation>
<translation id="8759274551635299824">காரà¯à®Ÿà¯ காலாவதியாகிவிடà¯à®Ÿà®¤à¯</translation>
+<translation id="8761567432415473239">Google பாதà¯à®•à®¾à®ªà¯à®ªà®¾à®© தேடலà¯, <ph name="SITE" /> இல௠சமீபதà¯à®¤à®¿à®²à¯ <ph name="BEGIN_LINK" />தீஙà¯à®•à®¾à®© நிரலà¯à®•à®³à¯ˆà®•à¯ கணà¯à®Ÿà®±à®¿à®¨à¯à®¤à®¤à¯<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;நீகà¯à®•à¯à®¤à®²à¯ˆ மீணà¯à®Ÿà¯à®®à¯ செயà¯</translation>
<translation id="8800988563907321413">உஙà¯à®•à®³à¯ à®…à®°à¯à®•à®¿à®²à¯à®³à¯à®³à®µà®±à¯à®±à¯à®•à¯à®•à®¾à®© பரிநà¯à®¤à¯à®°à¯ˆà®•à®³à¯ இஙà¯à®•à¯‡ தோனà¯à®±à¯à®®à¯</translation>
<translation id="8820817407110198400">பà¯à®¤à¯à®¤à®•à®•à¯à®•à¯à®±à®¿à®•à®³à¯</translation>
@@ -828,29 +903,30 @@
<translation id="8870413625673593573">சமீபதà¯à®¤à®¿à®²à¯ மூடியவை</translation>
<translation id="8874824191258364635">சரியான காரà¯à®Ÿà¯ எணà¯à®£à¯ˆ உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯</translation>
<translation id="8876793034577346603">அலசà¯à®µà®¤à®¿à®²à¯ பிணைய உளà¯à®³à®®à¯ˆà®µà¯ தோலà¯à®µà®¿.</translation>
-<translation id="8877192140621905067">உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¤ பினà¯à®©à®°à¯, உஙà¯à®•à®³à¯ காரà¯à®Ÿà¯ விவரஙà¯à®•à®³à¯ இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®±à¯à®•à¯à®ªà¯ பகிரபà¯à®ªà®Ÿà¯à®®à¯</translation>
<translation id="8889402386540077796">நிறசà¯à®šà®¾à®¯à®²à¯</translation>
<translation id="8891727572606052622">தவறான பà¯à®°à®¾à®•à¯à®¸à®¿ à®®à¯à®±à¯ˆ.</translation>
<translation id="889901481107108152">மனà¯à®©à®¿à®•à¯à®•à®µà¯à®®à¯, இநà¯à®¤ சோதனை உஙà¯à®•à®³à¯ தளதà¯à®¤à®¿à®²à¯ கிடைகà¯à®•à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="8903921497873541725">பெரிதாகà¯à®•à¯</translation>
<translation id="8931333241327730545">இநà¯à®¤à®•à¯ காரà¯à®Ÿà¯ˆ உஙà¯à®•à®³à¯ Google கணகà¯à®•à®¿à®²à¯ சேமிகà¯à®• வேணà¯à®Ÿà¯à®®à®¾?</translation>
<translation id="8932102934695377596">உஙà¯à®•à®³à¯ கடிகாரம௠மிகவà¯à®®à¯ பினà¯à®¤à®™à¯à®•à®¿ இரà¯à®•à¯à®•à®¿à®±à®¤à¯</translation>
-<translation id="8954894007019320973">(தொடரà¯à®•à®¿à®±à®¤à¯)</translation>
<translation id="8971063699422889582">சேவையகச௠சானà¯à®±à®¿à®¤à®´à¯ காலாவதியானதà¯.</translation>
<translation id="8986494364107987395">பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯à®ªà¯ பà¯à®³à¯à®³à®¿à®µà®¿à®µà®°à®™à¯à®•à®³à¯ˆà®¯à¯à®®à¯ சிதைவ௠அறிகà¯à®•à¯ˆà®•à®³à¯ˆà®¯à¯à®®à¯ தானாகவே Google கà¯à®•à¯ அனà¯à®ªà¯à®ªà¯</translation>
-<translation id="8987927404178983737">மாதமà¯</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">தளதà¯à®¤à®¿à®²à¯ தீஙà¯à®•à®¿à®´à¯ˆà®•à¯à®•à¯à®®à¯ நிரலà¯à®•à®³à¯ அதிகளவில௠உளà¯à®³à®©</translation>
+<translation id="8997023839087525404">சானà¯à®±à®¿à®¤à®´à¯ வெளிபà¯à®ªà®Ÿà¯ˆà®¤à¯à®¤à®©à¯à®®à¯ˆ கொளà¯à®•à¯ˆà®¯à®¿à®©à¯à®ªà®Ÿà®¿ பொதà¯à®µà®¿à®²à¯ வெளியிடபà¯à®ªà®Ÿà®¾à®¤ சானà¯à®±à®¿à®¤à®´à¯ˆà®šà¯ சேவையகம௠வழஙà¯à®•à®¿à®¯à¯à®³à¯à®³à®¤à¯. நமà¯à®ªà®•à®¤à¯à®¤à®©à¯à®®à¯ˆ மறà¯à®±à¯à®®à¯ தாகà¯à®•à¯à®¤à®²à¯à®•à®³à¯à®•à¯à®•à¯ எதிரான பாதà¯à®•à®¾à®ªà¯à®ªà¯ˆ உறà¯à®¤à®¿à®šà¯†à®¯à¯à®¯, சில சானà¯à®±à®¿à®¤à®´à¯à®•à®³à¯à®•à¯à®•à¯ இத௠தேவையான ஒனà¯à®±à®¾à®•à¯à®®à¯.</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> எனà¯à®•à®¿à®± பà¯à®°à®¾à®•à¯à®¸à®¿à®•à¯à®•à¯ பயனரà¯à®ªà¯†à®¯à®°à¯à®®à¯ கடவà¯à®šà¯à®šà¯Šà®²à¯à®²à¯à®®à¯ தேவை.</translation>
+<translation id="9005998258318286617">PDF ஆவணதà¯à®¤à¯ˆ à®à®±à¯à®± à®®à¯à®Ÿà®¿à®¯à®µà®¿à®²à¯à®²à¯ˆ.</translation>
<translation id="901974403500617787">கணினி அளவில௠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®ªà¯à®ªà®Ÿà¯à®®à¯ கொடிகள௠பினà¯à®µà®°à¯à®®à¯ உரிமையாளரால௠மடà¯à®Ÿà¯à®®à¯‡ அமைகà¯à®•à®ªà¯à®ªà®Ÿà¯à®®à¯: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">காரà¯à®Ÿà¯ பிலà¯à®²à®¿à®™à¯ à®®à¯à®•à®µà®°à®¿ தேவை</translation>
<translation id="9020542370529661692">இநà¯à®¤à®ªà¯ பகà¯à®•à®®à¯ <ph name="TARGET_LANGUAGE" /> கà¯à®•à¯ மொழிபெயரà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="9035022520814077154">பாதà¯à®•à®¾à®ªà¯à®ªà¯à®ªà¯ பிழை</translation>
<translation id="9038649477754266430">பகà¯à®•à®™à¯à®•à®³à¯ˆ இனà¯à®©à¯à®®à¯ விரைவாக à®à®±à¯à®±, யூக சேவையைப௠பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à®µà¯à®®à¯</translation>
<translation id="9039213469156557790">மேலà¯à®®à¯, பாதà¯à®•à®¾à®ªà¯à®ªà®±à¯à®± பிற ஆதாரஙà¯à®•à®³à¯ இநà¯à®¤à®ªà¯ பகà¯à®•à®¤à¯à®¤à®¿à®²à¯ உளà¯à®³à®©. இநà¯à®¤ ஆதாரஙà¯à®•à®³à¯ˆ டà¯à®°à®¾à®©à¯à®¸à®¿à®Ÿà¯à®Ÿà®¿à®²à¯ இரà¯à®•à¯à®•à¯à®®à¯à®ªà¯‹à®¤à¯à®®à¯ பிறர௠பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà®²à®¾à®®à¯, மேலà¯à®®à¯ பகà¯à®•à®¤à¯à®¤à®¿à®©à¯ செயலà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ˆ மாறà¯à®±, தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯ அதை மாறà¯à®±à®¿à®¯à®®à¯ˆà®•à¯à®•à®²à®¾à®®à¯.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> இல௠உளà¯à®³ தீஙà¯à®•à®¿à®´à¯ˆà®ªà¯à®ªà®µà®°à¯à®•à®³à¯, உஙà¯à®•à®³à¯ உலாவல௠அனà¯à®ªà®µà®¤à¯à®¤à¯ˆà®ªà¯ பாதிகà¯à®•à¯à®®à¯ நிரலà¯à®•à®³à¯ˆ நிறà¯à®µà¯à®µà®¤à®±à¯à®•à¯ உஙà¯à®•à®³à¯ˆ à®à®®à®¾à®±à¯à®± à®®à¯à®¯à®±à¯à®šà®¿à®¤à¯à®¤à®¿à®°à¯à®•à¯à®•à®²à®¾à®®à¯ (எடà¯à®¤à¯à®¤à¯à®•à¯à®•à®¾à®Ÿà¯à®Ÿà®¾à®•, உஙà¯à®•à®³à¯ à®®à¯à®•à®ªà¯à®ªà¯à®ªà¯à®ªà®•à¯à®•à®¤à¯à®¤à¯ˆ மாறà¯à®±à¯à®µà®¤à¯ அலà¯à®²à®¤à¯ நீஙà¯à®•à®³à¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿà¯à®®à¯ தளஙà¯à®•à®³à®¿à®²à¯ கூடà¯à®¤à®²à¯ விளமà¯à®ªà®°à®™à¯à®•à®³à¯ˆà®•à¯ காடà¯à®Ÿà¯à®µà®¤à¯).</translation>
+<translation id="9049981332609050619">நீஙà¯à®•à®³à¯ <ph name="DOMAIN" /> ஠அடைய à®®à¯à®¯à®±à¯à®šà®¿ செயà¯à®¤à¯€à®°à¯à®•à®³à¯, ஆனால௠சேவையகம௠ஒர௠செலà¯à®²à®¾à®¤ சானà¯à®±à®¿à®¤à®´à¯ˆ வழஙà¯à®•à®¿à®¯à®¤à¯.</translation>
<translation id="9050666287014529139">கடவà¯à®šà¯à®šà¯Šà®±à¯à®±à¯Šà®Ÿà®°à¯</translation>
<translation id="9065203028668620118">திரà¯à®¤à¯à®¤à¯</translation>
<translation id="9068849894565669697">வணà¯à®£à®¤à¯à®¤à¯ˆà®¤à¯ தேரà¯à®¨à¯à®¤à¯†à®Ÿà¯</translation>
+<translation id="9069693763241529744">நீடà¯à®Ÿà®¿à®ªà¯à®ªà¯ தடà¯à®¤à¯à®¤à¯à®³à¯à®³à®¤à¯</translation>
<translation id="9076283476770535406">இதில௠பெரியவரà¯à®•à®³à¯à®•à¯à®•à®¾à®© உளà¯à®³à®Ÿà®•à¯à®•à®®à¯ இரà¯à®•à¯à®•à®•à¯à®•à¯‚டà¯à®®à¯</translation>
<translation id="9078964945751709336">கூடà¯à®¤à®²à¯ தகவல௠தேவை</translation>
<translation id="9103872766612412690">வழகà¯à®•à®®à®¾à®•, <ph name="SITE" /> உஙà¯à®•à®³à¯ தகவலைப௠பாதà¯à®•à®¾à®ªà¯à®ªà®¤à®±à¯à®•à®¾à®• à®®à¯à®±à¯ˆà®®à¯ˆà®¯à®¾à®•à¯à®•à®¤à¯à®¤à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯.
@@ -860,16 +936,21 @@
<translation id="9148507642005240123">&amp;திரà¯à®¤à¯à®¤à®²à¯ˆà®šà¯ செயலà¯à®¤à®µà®¿à®°à¯</translation>
<translation id="9154194610265714752">பà¯à®¤à¯à®ªà¯à®ªà®¿à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯</translation>
<translation id="9157595877708044936">அமைகà¯à®•à®¿à®±à®¤à¯...</translation>
+<translation id="9169664750068251925">இநà¯à®¤à®¤à¯ தளதà¯à®¤à®¿à®²à¯ எபà¯à®ªà¯‹à®¤à¯à®®à¯ தடà¯</translation>
<translation id="9170848237812810038">&amp;செயலà¯à®¤à®µà®¿à®°à¯</translation>
<translation id="917450738466192189">சேவையகச௠சானà¯à®±à®¿à®¤à®´à¯ செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®©à®¤à®²à¯à®².</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" />, மேலà¯à®®à¯ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> ஆதரிகà¯à®•à®ªà¯à®ªà®Ÿà®¾à®¤ நெறிமà¯à®±à¯ˆà®¯à¯ˆà®ªà¯ பயனà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯à®•à®¿à®±à®¤à¯.</translation>
<translation id="9205078245616868884">உஙà¯à®•à®³à¯ தரவ௠உஙà¯à®•à®³à¯ ஒதà¯à®¤à®¿à®šà¯ˆà®µà¯ கடவà¯à®šà¯à®šà¯Šà®±à¯à®±à¯Šà®Ÿà®°à¯ˆà®•à¯ கொணà¯à®Ÿà¯ à®®à¯à®±à¯ˆà®®à¯ˆà®¯à®¾à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®³à¯à®³à®¤à¯. ஒதà¯à®¤à®¿à®šà¯ˆà®µà¯ˆà®¤à¯ தொடஙà¯à®•, அதை உளà¯à®³à®¿à®Ÿà®µà¯à®®à¯.</translation>
<translation id="9207861905230894330">கடà¯à®Ÿà¯à®°à¯ˆà®¯à¯ˆà®šà¯ சேரà¯à®ªà¯à®ªà®¤à®¿à®²à¯ தோலà¯à®µà®¿.</translation>
+<translation id="9219103736887031265">படஙà¯à®•à®³à¯</translation>
<translation id="933612690413056017">இணைய இணைபà¯à®ªà¯ இலà¯à®²à¯ˆ</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">படிவதà¯à®¤à¯ˆ அழி</translation>
<translation id="939736085109172342">பà¯à®¤à®¿à®¯ கோபà¯à®ªà¯à®±à¯ˆ</translation>
<translation id="941721044073577244">உஙà¯à®•à®³à¯à®•à¯à®•à¯ இநà¯à®¤à®¤à¯ தளதà¯à®¤à¯ˆà®ªà¯ பாரà¯à®µà¯ˆà®¯à®¿à®Ÿ அனà¯à®®à®¤à®¿ இலà¯à®²à¯ˆ</translation>
<translation id="969892804517981540">அதிகாரபà¯à®ªà¯‚à®°à¯à®µ கடà¯à®Ÿà®®à¯ˆà®ªà¯à®ªà¯</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{à®à®¤à¯à®®à®¿à®²à¯à®²à¯ˆ}=1{1 உரà¯à®ªà¯à®ªà®Ÿà®¿}other{# உரà¯à®ªà¯à®ªà®Ÿà®¿à®•à®³à¯}}</translation>
<translation id="988159990683914416">டெவலபà¯à®ªà®°à¯ கடà¯à®Ÿà®®à¯ˆà®ªà¯à®ªà¯</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_te.xtb b/chromium/components/strings/components_strings_te.xtb
index fa3023c1407..04744c6548a 100644
--- a/chromium/components/strings/components_strings_te.xtb
+++ b/chromium/components/strings/components_strings_te.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">సవà±à°¯à°¦à°¿à°¶à°²à±‹ తిపà±à°ªà±</translation>
<translation id="1038842779957582377">తెలియని పేరà±</translation>
<translation id="1050038467049342496">ఇతర à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à°¨à± మూసివేయండి</translation>
-<translation id="1053591932240354961"><ph name="SITE" /> Google Chrome à°ªà±à°°à°¾à°¸à±†à°¸à± చేయలేని విధంగా గజిబిజిగా ఉండే ఆధారాలనౠపంపినందà±à°¨ మీరౠపà±à°°à°¸à±à°¤à±à°¤à°‚ à°† వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°¨à°¿ సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°‚గానే ఉంటాయి, à°•à°¨à±à°• à°ˆ పేజీ కాసేపటి తరà±à°µà°¾à°¤ పని చేసే అవకాశం ఉంది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;జోడించడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
<translation id="10614374240317010">à°Žà°ªà±à°ªà°Ÿà°¿à°•à°¿ సేవౠచెయà±à°¯à°¬à°¡à°µà±</translation>
<translation id="106701514854093668">డెసà±à°•à±â€Œà°Ÿà°¾à°ªà±â€Œ à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à±</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">విధాన కాషౠసరిపోయింది</translation>
<translation id="113188000913989374"><ph name="SITE" /> ఇలా చెబà±à°¤à±‹à°‚ది:</translation>
<translation id="1132774398110320017">Chrome à°¸à±à°µà°¯à°‚పూరà±à°¤à°¿ సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±...</translation>
+<translation id="1150979032973867961">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ మీ à°•à°‚à°ªà±à°¯à±‚టరౠఆపరేటింగౠసిసà±à°Ÿà°®à± విశà±à°µà°¸à°¿à°‚చలేదà±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
+<translation id="1151972924205500581">పాసà±â€Œà°µà°°à±à°¡à± అవసరం</translation>
<translation id="1152921474424827756"><ph name="URL" /> యొకà±à°• <ph name="BEGIN_LINK" />కాషౠచేయబడిన కాపీ<ph name="END_LINK" />ని à°ªà±à°°à°¾à°ªà±à°¯à°¤ చేయండి</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ఊహించని విధంగా కనెకà±à°·à°¨à±â€Œà°¨à± మూసివేసింది.</translation>
<translation id="1161325031994447685">Wi-Fià°•à°¿ మళà±à°²à±€ కనెకà±à°Ÿà± చేయడం</translation>
+<translation id="1165039591588034296">లోపం</translation>
<translation id="1175364870820465910">&amp;à°®à±à°¦à±à°°à°¿à°‚à°šà±...</translation>
<translation id="1181037720776840403">తొలగించà±</translation>
<translation id="1184214524891303587">సంభావà±à°¯ à°­à°¦à±à°°à°¤à°¾ సంఘటనల à°—à±à°°à°¿à°‚à°šà°¿à°¨ వివరాలనౠGoogleà°•à°¿ <ph name="BEGIN_WHITEPAPER_LINK" />à°¸à±à°µà°¯à°‚చాలకంగా నివేదిసà±à°¤à±à°‚ది<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">à°ˆ సైటౠనà±à°‚à°¡à°¿ మరింత</translation>
<translation id="1206967143813997005">తపà±à°ªà± à°ªà±à°°à°¾à°°à°‚à°­ సంతకం</translation>
<translation id="1209206284964581585">à°ªà±à°°à°¸à±à°¤à±à°¤à°¾à°¨à°¿à°•à°¿ దాచà±</translation>
+<translation id="121201262018556460">మీరౠ<ph name="DOMAIN" />నౠచేరà±à°•à±‹à°µà°¡à°¾à°¨à°¿à°•à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± బలహీన కీని కలిగి ఉనà±à°¨ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. దాడి చేసేవారౠపà±à°°à±ˆà°µà±‡à°Ÿà± కీని విచà±à°›à°¿à°¨à±à°¨à°‚ చేశారౠమరియౠసరà±à°µà°°à± మీరౠఊహించిన సరà±à°µà°°à± కాకపోవచà±à°šà± (మీరౠదాడి చేసే వారితో à°•à°®à±à°¯à±‚నికేటౠచేసà±à°¤à±à°‚డవచà±à°šà±).</translation>
<translation id="1219129156119358924">సిసà±à°Ÿà°®à± à°­à°¦à±à°°à°¤</translation>
<translation id="1227224963052638717">తెలియని విధానం.</translation>
<translation id="1227633850867390598">విలà±à°µà°¨à± దాచండి</translation>
<translation id="1228893227497259893">à°Žà°‚à°Ÿà°¿à°Ÿà±€ à°à°¡à±†à°‚టిఫైయరౠచెలà±à°²à°¦à±</translation>
<translation id="1232569758102978740">శీరà±à°·à°¿à°•à°²à±‡à°¨à°¿à°¦à°¿</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (సమకాలీకరించబడà±à°¡à°¾à°¯à°¿)</translation>
<translation id="1263231323834454256">పఠన జాబితా</translation>
<translation id="1264126396475825575">à°•à±à°°à°¾à°·à± నివేదిక <ph name="CRASH_TIME" />à°•à°¿ సంగà±à°°à°¹à°¿à°‚చబడింది (ఇంకా à°…à°ªà±â€Œà°²à±‹à°¡à± చేయలేదౠలేదా విసà±à°®à°°à°¿à°‚చబడింది)</translation>
+<translation id="1281526147609854549"><ph name="ISSUER" /> à°¦à±à°µà°¾à°°à°¾ జారీ చేయబడింది</translation>
+<translation id="1283919782143846010">హానికరమైన కంటెంటౠబà±à°²à°¾à°•à± చేయబడింది</translation>
<translation id="1285320974508926690">à°ˆ సైటà±â€Œà°¨à± à°…à°¨à±à°µà°¦à°¿à°‚చవదà±à°¦à±</translation>
<translation id="129553762522093515">ఇటీవల మూసివెయà±à°¯à°¬à°¡à°¿à°¨à°µà°¿</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />మీ à°•à±à°•à±à°•à±€à°²à°¨à± తీసివేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">మీ కారà±à°¯à°¾à°šà°°à°£ వీరికి <ph name="BEGIN_EMPHASIS" />ఇపà±à°ªà°Ÿà°¿à°•à±€ కనిపించవచà±à°šà±<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />మీరౠసందరà±à°¶à°¿à°‚చే వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°²à±
+ <ph name="LIST_ITEM" />మీ యజమాని లేదా పాఠశాల నిరà±à°µà°¾à°¹à°•à±à°²à±
+ <ph name="LIST_ITEM" />మీ ఇంటరà±à°¨à±†à°Ÿà± సేవా à°ªà±à°°à°¦à°¾à°¤
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">నమోదిత డొమైనà±:</translation>
<translation id="1340482604681802745">పికపౠచిరà±à°¨à°¾à°®à°¾</translation>
<translation id="1344211575059133124">à°ˆ సైటà±â€Œà°¨à± సందరà±à°¶à°¿à°‚చడానికి మీకౠఅనà±à°®à°¤à°¿ అవసరమైనటà±à°²à±à°—à°¾ కనిపిసà±à°¤à±‹à°‚ది</translation>
<translation id="1344588688991793829">Chromium à°¸à±à°µà°¯à°‚పూరà±à°¤à°¿ సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±...</translation>
+<translation id="1348198688976932919">రాబోయే సైటà±â€Œà°²à±‹ హానికరమైన యాపà±â€Œà°²à± ఉనà±à°¨à°¾à°¯à°¿</translation>
<translation id="1374468813861204354">సూచనలà±</translation>
<translation id="1375198122581997741">వెరà±à°·à°¨à± à°—à±à°°à°¿à°‚à°šà°¿</translation>
<translation id="1377321085342047638">కారà±à°¡à± సంఖà±à°¯</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> డేటా à°à°¦à±€ పంపలేదà±.</translation>
<translation id="1407135791313364759">à°…à°¨à±à°¨à±€ తెరà±à°µà±</translation>
<translation id="1413809658975081374">గోపà±à°¯à°¤à°¾ లోపం</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" /> వదà±à°¦ <ph name="ORGANIZATION" /> యొకà±à°• à°—à±à°°à±à°¤à°¿à°‚పౠ<ph name="ISSUER" />చే à°§à±à°°à±à°µà±€à°•à°°à°¿à°‚చబడింది.</translation>
<translation id="1426410128494586442">à°…à°µà±à°¨à±</translation>
<translation id="1430915738399379752">à°®à±à°¦à±à°°à°¿à°‚à°šà±</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" />లో పేజీని సందరà±à°¶à°¿à°‚చడానికి<ph name="END_LINK" /> చేసిన à°ªà±à°°à°¯à°¤à±à°¨à°‚ à°¬à±à°²à°¾à°•à± చేయబడింది.</translation>
-<translation id="1491663344921578213">వెబà±â€Œà°¸à±ˆà°Ÿà± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ పినౠచేయబడే పదà±à°§à°¤à°¿à°¨à°¿ ఉపయోగిసà±à°¤à±à°¨à±à°¨à°‚à°¦à±à°¨ మీరౠఇపà±à°ªà±à°¡à± <ph name="SITE" />ని సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°‚గానే ఉంటాయి, కావà±à°¨ à°ˆ పేజీ కాసేపటి తరà±à°µà°¾à°¤ పని చేసే అవకాశం ఉంది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">à°ˆ పేజీ యొకà±à°• సేవౠచేసిన (అంటే పాతది) కాపీని చూపà±à°¤à±à°‚ది.</translation>
<translation id="1517433312004943670">ఫోనౠనంబరౠఅవసరం</translation>
<translation id="1519264250979466059">రూపకలà±à°ªà°¨ తేదీ</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">à°ˆ లకà±à°·à°£à°¾à°¨à±à°¨à°¿ ఉపయోగించడానికి జావాసà±à°•à±à°°à°¿à°ªà±à°Ÿà± తపà±à°ªà°¨à°¿à°¸à°°à°¿à°—à°¾ à°ªà±à°°à°¾à°°à°‚భించాలి.</translation>
<translation id="1555130319947370107">నీలం</translation>
<translation id="1559528461873125649">à°…à°Ÿà±à°µà°‚à°Ÿà°¿ ఫైలౠలేదా డైరెకà±à°Ÿà°°à±€ లేదà±</translation>
-<translation id="1559572115229829303">&lt;p&gt;మీ పరికరం తేదీ మరియౠసమయం (<ph name="DATE_AND_TIME" />) తపà±à°ªà±à°—à°¾ ఉనà±à°¨à°‚à°¦à±à°¨ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />à°•à°¿ à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కనెకà±à°·à°¨à± à°à°°à±à°ªà°¾à°Ÿà± చేయడం సాధà±à°¯à°ªà°¡à°¦à±.&lt;/p&gt;
-
- &lt;p&gt;దయచేసి &lt;strong&gt;సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±&lt;/strong&gt; à°…à°¨à±à°µà°°à±à°¤à°¨à°‚ యొకà±à°• &lt;strong&gt;సాధారణం&lt;/strong&gt; విభాగంలో తేదీ మరియౠసమయానà±à°¨à°¿ సరà±à°¦à±à°¬à°¾à°Ÿà± చేయండి.&lt;/p&gt;</translation>
<translation id="1583429793053364125">à°ˆ వెబౠపేజీని à°ªà±à°°à°¦à°°à±à°¶à°¿à°¸à±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± à°à°¦à±‹ తపà±à°ªà± జరిగింది.</translation>
<translation id="1592005682883173041">à°¸à±à°¥à°¾à°¨à°¿à°• డేటా à°ªà±à°°à°¾à°ªà±à°¯à°¤</translation>
+<translation id="1594030484168838125">à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿</translation>
<translation id="161042844686301425">నీలి ఆకà±à°ªà°šà±à°š</translation>
+<translation id="1620510694547887537">కెమెరా</translation>
<translation id="1629803312968146339">Chrome à°ˆ కారà±à°¡à±â€Œà°¨à± సేవౠచేయాలని మీరౠకోరà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
<translation id="1639239467298939599">లోడౠఅవà±à°¤à±‹à°‚ది</translation>
<translation id="1640180200866533862">వినియోగదారౠవిధానాలà±</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">నెటà±â€Œà°µà°°à±à°•à± కానà±à°«à°¿à°—రేషనౠచెలà±à°²à°¦à± మరియౠదిగà±à°®à°¤à°¿ చేయడం సాధà±à°¯à°‚ కాదà±.</translation>
<translation id="1644574205037202324">à°šà°°à°¿à°¤à±à°°</translation>
<translation id="1645368109819982629">à°ªà±à°°à±‹à°Ÿà±‹à°•à°¾à°²à±â€Œà°•à± మదà±à°¦à°¤à± లేదà±</translation>
+<translation id="1655462015569774233">{1,plural, =1{à°ˆ సరà±à°µà°°à± ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°—à°¡à±à°µà± నినà±à°¨ à°®à±à°—ిసింది. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±. మీ à°•à°‚à°ªà±à°¯à±‚టరౠగడియారం à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="CURRENT_DATE" />à°•à°¿ సెటౠచేయబడింది. అది సరిగà±à°—à°¾ ఉందా? సరిగà±à°—à°¾ లేకà±à°‚టే, మీరౠసిసà±à°Ÿà°®à± గడియారానà±à°¨à°¿ సరిచేసి, ఆపై à°ˆ పేజీని రీఫà±à°°à±†à°·à± చేయాలి.}other{à°ˆ సరà±à°µà°°à± ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°—à°¡à±à°µà± # రోజà±à°² à°•à±à°°à°¿à°¤à°‚ à°®à±à°—ిసింది. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±. మీ à°•à°‚à°ªà±à°¯à±‚టరౠగడియారం à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="CURRENT_DATE" />à°•à°¿ సెటౠచేయబడింది. అది సరిగà±à°—à°¾ ఉందా? సరిగà±à°—à°¾ లేకà±à°‚టే, మీరౠసిసà±à°Ÿà°®à± గడియారానà±à°¨à°¿ సరిచేసి, ఆపై à°ˆ పేజీని రీఫà±à°°à±†à°·à± చేయాలి.}}</translation>
<translation id="1656489000284462475">పికపà±</translation>
<translation id="1663943134801823270">కారà±à°¡à±â€Œà°²à± మరియౠచిరà±à°¨à°¾à°®à°¾à°²à± Chrome à°¨à±à°‚à°¡à°¿ పొందినవి. మీరౠ<ph name="BEGIN_LINK" />సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±<ph name="END_LINK" />లో వాటిని నిరà±à°µà°¹à°¿à°‚చవచà±à°šà±.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> సాధారణంగా మీ సమాచారానà±à°¨à°¿ à°°à°•à±à°·à°¿à°‚చడానికి à°—à±à°ªà±à°¤à±€à°•à°°à°£à°¨à± ఉపయోగిసà±à°¤à±à°‚ది. Google Chrome ఈసారి <ph name="SITE" />à°•à°¿ కనెకà±à°Ÿà± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చినపà±à°ªà±à°¡à±, వెబà±â€Œà°¸à±ˆà°Ÿà± అసాధారణ మరియౠతపà±à°ªà± ఆధారాలౠఅని à°ªà±à°°à°¤à°¿à°¸à±à°ªà°‚దించింది. దాడి చేసే à°µà±à°¯à°•à±à°¤à°¿ <ph name="SITE" />à°—à°¾ à°µà±à°¯à°µà°¹à°°à°¿à°‚à°šà°¿ మోసగించడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°¸à±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± లేదా Wi-Fi సైనà±-ఇనౠసà±à°•à±à°°à±€à°¨à± కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినపà±à°ªà±à°¡à± ఇలా జరగవచà±à°šà±. Google Chrome డేటా వినిమయం సంభవించక à°®à±à°‚దే కనెకà±à°·à°¨à±â€Œà°¨à± ఆపివేసినందà±à°¨ మీ సమాచారం ఇపà±à°ªà°Ÿà°¿à°•à±€ à°¸à±à°°à°•à±à°·à°¿à°¤à°‚గానే ఉంది.</translation>
-<translation id="168328519870909584">à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />పై దాడి చేసేవారౠమీ పరికరంలో మీ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, ఫోటోలà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠమరియౠకà±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) దొంగిలించగలిగే లేదా తొలగించగలిగే à°ªà±à°°à°®à°¾à°¦à°•à°°à°®à±ˆà°¨ à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చవచà±à°šà±.</translation>
<translation id="168841957122794586">సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ బలహీన à°•à±à°°à°¿à°ªà±à°Ÿà±‹à°—à±à°°à°¾à°«à°¿à°•à± కీని కలిగి ఉంది.</translation>
+<translation id="1706954506755087368">{1,plural, =1{à°ˆ సరà±à°µà°°à± ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ రేపటిది కావచà±à°šà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±.}other{à°ˆ సరà±à°µà°°à± ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ భవిషà±à°¯à°¤à±à°¤à±à°²à±‹ # రోజà±à°² తదà±à°ªà°°à°¿à°¦à°¿ కావచà±à°šà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">à°ˆ సైటà±â€Œà°¨à°¿ సందరà±à°¶à°¿à°‚చడానికి మీకౠ<ph name="NAME" /> à°¨à±à°‚à°¡à°¿ à°…à°¨à±à°®à°¤à°¿ అవసరం</translation>
<translation id="1721424275792716183">* అవసరమైన ఫీలà±à°¡à±</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">పేజీని తరà±à°µà°¾à°¤ డౌనà±â€Œà°²à±‹à°¡à± చేయి</translation>
<translation id="17513872634828108">తెరిచిన à°Ÿà±à°¯à°¾à°¬à±â€à°²à±</translation>
<translation id="1753706481035618306">పేజీ సంఖà±à°¯</translation>
+<translation id="1763864636252898013">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ మీ పరికర ఆపరేటింగౠసిసà±à°Ÿà°®à± విశà±à°µà°¸à°¿à°‚చలేదà±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows నెటà±â€Œà°µà°°à±à°•à± సమసà±à°¯ విశà±à°²à±‡à°·à°£à°²à°¨à± అమలౠచేయడం à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">దయచేసి మీ సమకాలీకరణ పాసà±â€Œà°«à±à°°à±‡à°œà±â€Œà°¨à± నవీకరించండి.</translation>
<translation id="1787142507584202372">మీ తెరవబడిన à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à± ఇకà±à°•à°¡ కనిపిసà±à°¤à°¾à°¯à°¿</translation>
+<translation id="1789575671122666129">పాపà±à°…à°ªà±â€Œà°²à±</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">కారà±à°¡à±à°¦à°¾à°°à±à°¨à°¿ పేరà±</translation>
-<translation id="1803678881841855883">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />మాలà±à°µà±‡à°°à±â€Œà°¨à°¿ à°—à±à°°à±à°¤à°¿à°‚చింది<ph name="END_LINK" />. సాధారణంగా à°¸à±à°°à°•à±à°·à°¿à°¤à°®à±ˆà°¨ వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œâ€Œà°²à± కూడా కొనà±à°¨à°¿à°¸à°¾à°°à±à°²à± మాలà±à°µà±‡à°°à± బారినపడతాయి. మాలà±à°µà±‡à°°à±â€Œ పంపిణీదారà±à°—à°¾ పేరà±à°—ాంచిన <ph name="SUBRESOURCE_HOST" /> à°¨à±à°‚à°¡à°¿ ఇతరà±à°²à°•à± హాని తలపటà±à°Ÿà±‡ లాంటి కంటెంటౠసంకà±à°°à°®à°¿à°¸à±à°¤à±à°‚ది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">జోడించినది <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">చెలà±à°²à°¨à°¿ à°…à°­à±à°¯à°°à±à°¥à°¨ లేదా à°…à°­à±à°¯à°°à±à°¥à°¨ పరామితà±à°²à±</translation>
<translation id="1826516787628120939">తనిఖీ చేసà±à°¤à±‹à°‚ది</translation>
<translation id="1834321415901700177">à°ˆ సైటౠహానికరమైన à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± కలిగి ఉంది</translation>
+<translation id="1840414022444569775">à°ˆ కారà±à°¡à± నంబరౠఇపà±à°ªà°Ÿà°¿à°•à±‡ ఉపయోగించబడింది</translation>
<translation id="1842969606798536927">చెలà±à°²à°¿à°‚à°ªà±</translation>
<translation id="1871208020102129563">à°ªà±à°°à°¾à°•à±à°¸à±€ à°¸à±à°¥à°¿à°°à°®à±ˆà°¨ à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à±â€Œà°²à°¨à± ఉపయోగించడానికి సెటౠచేయబడింది, .pac à°¸à±à°•à±à°°à°¿à°ªà±à°Ÿà± URLనౠకాదà±.</translation>
<translation id="1871284979644508959">అవసరమైన ఫీలà±à°¡à±</translation>
<translation id="187918866476621466">à°ªà±à°°à°¾à°°à°‚à°­ పేజీలనౠతెరà±à°µà±</translation>
<translation id="1883255238294161206">జాబితానౠకà±à°¦à°¿à°‚à°šà±</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">à°«à°¿à°²à±à°Ÿà°°à°¿à°‚à°—à±</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{à°à°®à±€ లేవà±}=1{1 సైటà±}other{# సైటà±â€Œà°²à±}}</translation>
<translation id="194030505837763158"><ph name="LINK" />à°•à°¿ వెళà±à°²à°‚à°¡à°¿</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à±</translation>
<translation id="1973335181906896915">à°¶à±à°°à±‡à°£à°¿à°—à°¾ రూపొందించడంలో లోపం</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">ఇది <ph name="POLICY_NAME" /> à°¦à±à°µà°¾à°°à°¾ à°­à°°à±à°¤à±€ చేయబడినందà±à°¨ విసà±à°®à°°à°¿à°‚చబడింది.</translation>
<translation id="2138201775715568214">సమీప భౌతిక వెబౠపేజీల కోసం శోధిసà±à°¤à±‹à°‚ది</translation>
<translation id="213826338245044447">మొబైలౠబà±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à±</translation>
-<translation id="2148716181193084225">à°ˆ రోజà±</translation>
+<translation id="2147827593068025794">నేపథà±à°¯ సమకాలీకరణ</translation>
<translation id="2154054054215849342">సమకాలీకరణ మీ డొమైనà±â€Œà°•à± à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదà±</translation>
<translation id="2154484045852737596">కారà±à°¡à±â€Œà°¨à± సవరించండి</translation>
<translation id="2166049586286450108">పూరà±à°¤à°¿ నిరà±à°µà°¾à°¹à°• à°ªà±à°°à°¾à°ªà±à°¯à°¤</translation>
<translation id="2166378884831602661">à°ˆ సైటౠసà±à°°à°•à±à°·à°¿à°¤à°®à±ˆà°¨ కనెకà±à°·à°¨à±â€Œà°¨à± అందించలేదà±</translation>
<translation id="2181821976797666341">విధానాలà±</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 à°šà°¿à°°à±à°¨à°¾à°®à°¾}other{# à°šà°¿à°°à±à°¨à°¾à°®à°¾à°²à±}}</translation>
+<translation id="2187317261103489799">à°—à±à°°à±à°¤à°¿à°‚à°šà± (డిఫాలà±à°Ÿà±)</translation>
<translation id="2202020181578195191">చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ à°—à°¡à±à°µà± à°®à±à°—ింపౠసంవతà±à°¸à°°à°¾à°¨à±à°¨à°¿ నమోదౠచేయండి</translation>
<translation id="2212735316055980242">విధానం à°•à°¨à±à°—ొనబడలేదà±</translation>
<translation id="2213606439339815911">నమోదà±à°²à°¨à± పొందà±à°¤à±‹à°‚ది...</translation>
+<translation id="2218879909401188352"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />లోని à°¹à±à°¯à°¾à°•à°°à±â€Œà°²à± మీ పరికరంలో హానికరమైన యాపà±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయవచà±à°šà± మరియౠమీ మొబైలౠబిలà±â€Œà°²à±‹ అదృశà±à°¯ ఛారà±à°œà±€à°²à°•à± కారణం కావచà±à°šà± లేదా మీ à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ సమాచారానà±à°¨à°¿ దొంగిలించవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />విశà±à°²à±‡à°·à°£à°² à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°¨à±à°¨à°¿<ph name="END_LINK" /> ఉపయోగించి మీ కనెకà±à°·à°¨à±â€Œà°¨à± సరి చేయండి</translation>
<translation id="2239100178324503013">ఇపà±à°ªà±à°¡à±‡ పంపండి</translation>
<translation id="225207911366869382">à°ˆ విధానం కోసం à°ˆ విలà±à°µ తగà±à°—ించబడింది.</translation>
<translation id="2262243747453050782">HTTP లోపం</translation>
+<translation id="2270484714375784793">ఫోనౠనంబరà±</translation>
<translation id="2282872951544483773">à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేని à°ªà±à°°à°¯à±‹à°—ాలà±</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> అంశం}other{<ph name="ITEM_COUNT" /> అంశాలà±}}</translation>
<translation id="2292556288342944218">మీ ఇంటరà±à°¨à±†à°Ÿà± à°ªà±à°°à°¾à°ªà±à°¯à°¤ à°¬à±à°²à°¾à°•à± చేయబడింది</translation>
<translation id="230155334948463882">కొతà±à°¤ కారà±à°¡à°¾?</translation>
-<translation id="2305919008529760154">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ మోసపూరితంగా జారీ అయి ఉండవచà±à°šà±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడి చేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" />à°•à°¿ వినియోగదారౠపేరౠమరియౠపాసà±â€Œà°µà°°à±à°¡à± అవసరం.</translation>
-<translation id="2318774815570432836">వెబà±â€Œà°¸à±ˆà°Ÿà± HSTSని ఉపయోగిసà±à°¤à±à°¨à±à°¨à°‚à°¦à±à°¨ మీరౠపà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="SITE" />ని సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°‚గానే ఉంటాయి, కావà±à°¨ à°ˆ పేజీ కాసేపటి తరà±à°µà°¾à°¤ పని చేసే అవకాశం ఉంది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°¨à°¿ మీ నిరà±à°µà°¾à°¹à°•à±à°²à± నియంతà±à°°à°¿à°¸à±à°¤à±à°¨à±à°¨à°¾à°°à±</translation>
<translation id="2354001756790975382">ఇతర à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à±</translation>
+<translation id="2354430244986887761">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />హానికర యాపà±â€Œà°²à°¨à± à°•à°¨à±à°—ొంది<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">దాడికి పాలà±à°ªà°¡à±‡à°µà°¾à°°à± à°ˆ సైటà±â€Œà°²à±‹ మీరౠచూసà±à°¤à±à°¨à±à°¨ à°šà°¿à°¤à±à°°à°¾à°²à°¨à± చూడగలగవచà±à°šà± మరియౠవాటిని సవరించడం à°¦à±à°µà°¾à°°à°¾ మిమà±à°®à°²à±à°¨à°¿ మోసగించవచà±à°šà±.</translation>
+<translation id="2356070529366658676">à°…à°¡à±à°—à±</translation>
+<translation id="2359629602545592467">అనేకం</translation>
<translation id="2359808026110333948">కొనసాగà±</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" />à°•à°¿ సంగà±à°°à°¹à°¿à°‚à°šà°¿à°¨ à°•à±à°°à°¾à°·à± నివేదిక à°…à°ªà±â€Œà°²à±‹à°¡à± కాలేదà±</translation>
<translation id="2367567093518048410">à°¸à±à°¥à°¾à°¯à°¿</translation>
-<translation id="2371153335857947666">{1,plural, =1{à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°—à°¡à±à°µà± నినà±à°¨ à°®à±à°—ిసింది. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±. మీ à°•à°‚à°ªà±à°¯à±‚టరౠగడియారం à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="CURRENT_DATE" />à°•à°¿ సెటౠచేయబడింది. అది సరిగà±à°—à°¾ ఉందా? సరిగà±à°—à°¾ లేకà±à°‚టే, మీరౠసిసà±à°Ÿà°®à± గడియారానà±à°¨à°¿ సరిచేసి, ఆపై à°ˆ పేజీని రీఫà±à°°à±†à°·à± చేయాలి. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.}other{à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°—à°¡à±à°µà± # రోజà±à°² à°•à±à°°à°¿à°¤à°‚ à°®à±à°—ిసింది. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±. మీ à°•à°‚à°ªà±à°¯à±‚టరౠగడియారం à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="CURRENT_DATE" />à°•à°¿ సెటౠచేయబడింది. అది సరిగà±à°—à°¾ ఉందా? సరిగà±à°—à°¾ లేకà±à°‚టే, మీరౠసిసà±à°Ÿà°®à± గడియారానà±à°¨à°¿ సరిచేసి, ఆపై à°ˆ పేజీని రీఫà±à°°à±†à°·à± చేయాలి. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">UI à°ªà±à°°à°¤à±à°¯à°¾à°®à±à°¨à°¾à°¯à°¾à°²à± à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేవà±</translation>
<translation id="2384307209577226199">à°Žà°‚à°Ÿà°°à±â€Œà°ªà±à°°à±ˆà°œà± డిఫాలà±à°Ÿà±</translation>
<translation id="2386255080630008482">సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°°à°¦à±à°¦à± చెయà±à°¯à°¬à°¡à°¿à°‚ది.</translation>
<translation id="2392959068659972793">విలà±à°µ సెటౠచేయని విధానాలనౠచూపà±</translation>
<translation id="239429038616798445">à°ˆ రవాణా పదà±à°§à°¤à°¿ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదà±. వేరే పదà±à°§à°¤à°¿à°¨à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="2396249848217231973">&amp;తొలగించడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
-<translation id="2460160116472764928">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />మాలà±à°µà±‡à°°à±â€Œà°¨à°¿ à°—à±à°°à±à°¤à°¿à°‚చింది<ph name="END_LINK" />. సాధారణంగా à°¸à±à°°à°•à±à°·à°¿à°¤à°®à±ˆà°¨ వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œâ€Œà°²à± కూడా కొనà±à°¨à°¿à°¸à°¾à°°à±à°²à± మాలà±à°µà±‡à°°à±â€Œ బారినపడతాయి. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ ఉపసంహరించబడి ఉండవచà±à°šà±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
<translation id="2463739503403862330">పూరించà±</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />నెటà±â€Œà°µà°°à±à°•à± సమసà±à°¯ విశà±à°²à±‡à°·à°£à°²à°¨à± అమలౠచేయడం<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">చెలà±à°²à°¨à°¿ శోధన URL.</translation>
+<translation id="2482878487686419369">à°ªà±à°°à°•à°Ÿà°¨à°²à±</translation>
<translation id="2491120439723279231">సరà±à°µà°°à± యొకà±à°• à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚లో లోపాలౠఉనà±à°¨à°¾à°¯à°¿.</translation>
<translation id="2495083838625180221">JSON పారà±à°¸à°°à±</translation>
<translation id="2495093607237746763">à°Žà°‚à°šà±à°•à±à°‚టే, Chromium వేగవంతమైన ఫారమౠపూరింపౠకోసం à°ˆ పరికరంలో మీ కారà±à°¡à± కాపీని నిలà±à°µ చేసà±à°¤à±à°‚ది.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">వెనà±à°•à°•à± వెళà±à°³à±</translation>
<translation id="2515629240566999685">మీ à°ªà±à°°à°¾à°‚తంలో సిగà±à°¨à°²à±â€Œà°¨à± తనిఖీ చేయడం</translation>
<translation id="2516305470678292029">UI à°ªà±à°°à°¤à±à°¯à°¾à°®à±à°¨à°¾à°¯à°¾à°²à±</translation>
+<translation id="2539524384386349900">à°—à±à°°à±à°¤à°¿à°‚à°šà±</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> చెలà±à°²à°¨à°¿ à°ªà±à°°à°¤à°¿à°¸à±à°ªà°‚దననౠపంపింది.</translation>
-<translation id="2552545117464357659">à°•à±à°°à±Šà°¤à±à°¤à°µà°¿</translation>
<translation id="2556876185419854533">&amp;సవరించడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
<translation id="2587730715158995865">à°ªà±à°°à°šà±à°°à°£à°•à°°à±à°¤ <ph name="ARTICLE_PUBLISHER" />. దీనà±à°¨à°¿ మరియౠమరో <ph name="OTHER_ARTICLE_COUNT" /> ఇతర కథనాలనౠచదవండి.</translation>
<translation id="2587841377698384444">డైరెకà±à°Ÿà°°à±€ API ID:</translation>
<translation id="2597378329261239068">à°ˆ పతà±à°°à°‚ à°…à°¨à±à°®à°¤à°¿ పదంచే à°°à°•à±à°·à°¿à°‚చబడింది. దయచేసి à°…à°¨à±à°®à°¤à°¿ పదానà±à°¨à°¿ నమోదౠచేయండి.</translation>
<translation id="2609632851001447353">à°µà±à°¯à°¤à±à°¯à°¾à°¸à°¾à°²à±</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{à°à°®à±€ లేవà±}=1{1 à°…à°¨à±à°µà°°à±à°¤à°¨à°‚ ($1)}=2{2 à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à± ($1, $2)}other{# à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à± ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">మీ గడియారం సమయం భవిషà±à°¯à°¤à±à°¤à±à°²à±‹ ఉంది</translation>
<translation id="2639739919103226564">à°¸à±à°¥à°¿à°¤à°¿: </translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">ఫైలà±â€Œà°•à± à°ªà±à°°à°¾à°ªà±à°¯à°¤ తిరసà±à°•à°°à°¿à°‚చబడింది</translation>
<translation id="2653659639078652383">సమరà±à°ªà°¿à°‚à°šà±</translation>
<translation id="2666117266261740852">ఇతర à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à± లేదా à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à°¨à± మూసివేయండి</translation>
+<translation id="2670429602441959756">ఇపà±à°ªà°Ÿà°¿à°•à±€ VRలో మదà±à°¦à°¤à± లేని ఫీచరà±â€Œà°²à°¨à± à°ˆ పేజీ కలిగి ఉంది. నిషà±à°•à±à°°à°®à°¿à°¸à±à°¤à±‹à°‚ది...</translation>
<translation id="2674170444375937751">మీ à°šà°°à°¿à°¤à±à°° à°¨à±à°‚à°¡à°¿ à°ˆ పేజీలనౠతొలగించదలిచారా?</translation>
<translation id="2677748264148917807">నిషà±à°•à±à°°à°®à°¿à°‚à°šà±</translation>
-<translation id="269990154133806163">సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°° పారదరà±à°¶à°•à°¤ విధానానà±à°¨à°¿ ఉపయోగించి పబà±à°²à°¿à°•à±â€Œà°—à°¾ బహిరంగపరచబడని à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. కొనà±à°¨à°¿ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°²à°•à±, అవి విశà±à°µà°¸à°¨à±€à°¯à°®à±ˆà°¨à°µà°¨à°¿ మరియౠదాడి చేసేవారి à°¨à±à°‚à°¡à°¿ à°°à°•à±à°·à°£ à°•à°²à±à°ªà°¿à°‚చగలవని నిరà±à°§à°¾à°°à°¿à°‚చడానికి ఇది ఆవశà±à°¯à°•à°‚. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">పఠనా జాబితా</translation>
<translation id="2704283930420550640">విలà±à°µ ఆకృతికి సరిపోలలేదà±.</translation>
<translation id="2704951214193499422">Chromium à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ మీ కారà±à°¡à±â€Œà°¨à± నిరà±à°§à°¾à°°à°¿à°‚చలేకపోయింది. దయచేసి తరà±à°µà°¾à°¤ మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="2705137772291741111">à°ˆ సైటౠయొకà±à°• సేవౠచేయబడిన (కాషౠచేసిన) కాపీ చదవదగినటà±à°²à±à°—à°¾ లేదà±.</translation>
<translation id="2709516037105925701">à°¸à±à°µà°¯à°‚పూరà±à°¤à°¿</translation>
-<translation id="2712118517637785082">మీరౠ<ph name="DOMAIN" />కౠకనెకà±à°Ÿà± కావడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± అందించిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ దానà±à°¨à°¿ జారీ చేసినవారౠరదà±à°¦à± చేసారà±. దీని à°ªà±à°°à°•à°¾à°°à°‚, సరà±à°µà°°à± అందించిన à°­à°¦à±à°°à°¤à°¾ ఆధారాలౠఖచà±à°šà°¿à°¤à°‚à°—à°¾ విశà±à°µà°¸à°¿à°‚చలేనివి. మీరౠదాడి చేసే వారితో à°•à°®à±à°¯à±‚నికేటౠచేసà±à°¤à±à°‚డవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">à°…à°¨à±à°®à°¤à°¿ à°…à°¡à±à°—à±</translation>
<translation id="2713444072780614174">తెలà±à°ªà±</translation>
<translation id="2720342946869265578">సమీపం</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">పరికరం రికారà±à°¡à± లేదà±</translation>
<translation id="2784949926578158345">కనెకà±à°·à°¨à± మళà±à°³à±€ సెటౠచెయà±à°¯à°¬à°¡à°¿à°‚ది.</translation>
<translation id="2794233252405721443">సైటౠబà±à°²à°¾à°•à± చేయబడింది</translation>
+<translation id="2799020568854403057">రాబోయే సైటౠహానికరమైన యాపà±â€Œà°²à°¨à± కలిగి ఉంది</translation>
+<translation id="2803306138276472711">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />మాలà±à°µà±‡à°°à±â€Œà°¨à°¿ à°—à±à°°à±à°¤à°¿à°‚చింది<ph name="END_LINK" />. సాధారణంగా à°¸à±à°°à°•à±à°·à°¿à°¤à°®à±ˆà°¨ వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œâ€Œà°²à°•à± కూడా కొనà±à°¨à°¿à°¸à°¾à°°à±à°²à± మాలà±à°µà±‡à°°à± సోకà±à°¤à±à°‚ది.</translation>
<translation id="2824775600643448204">à°šà°¿à°°à±à°¨à°¾à°®à°¾ మరియౠశోధన బారà±</translation>
<translation id="2826760142808435982"><ph name="CIPHER" />నౠఉపయోగించి కనెకà±à°·à°¨à± à°—à±à°ªà±à°¤à±€à°•à°°à°¿à°‚చబడింది మరియౠపà±à°°à°¾à°®à°¾à°£à±€à°•à°°à°¿à°‚చబడింది మరియౠ<ph name="KX" />నౠకీలకమైన పరివరà±à°¤à°¨ విధానంగా ఉపయోగిసà±à°¤à±à°‚ది.</translation>
<translation id="2835170189407361413">ఫారమà±â€Œà°¨à± à°¤à±à°¡à°¿à°šà°¿à°µà±‡à°¯à°¿</translation>
+<translation id="2856444702002559011">à°¹à±à°¯à°¾à°•à°°à±â€Œà°²à± <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à°¨à±à°‚à°¡à°¿ మీ సమాచారానà±à°¨à°¿ దొంగిలించడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°¸à±à°¤à±‚ ఉండవచà±à°šà± (ఉదాహరణకà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠలేదా à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±). <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">మళà±à°²à±€ లోడౠచేయవదà±à°¦à±</translation>
<translation id="2900469785430194048">Google Chrome à°ˆ వెబà±â€Œà°ªà±‡à°œà±€à°¨à°¿ à°ªà±à°°à°¦à°°à±à°¶à°¿à°‚చడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°¸à±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± మెమరీ అయిపోయింది.</translation>
<translation id="2909946352844186028">నెటà±â€Œà°µà°°à±à°•à± మారà±à°ªà± à°—à±à°°à±à°¤à°¿à°‚చబడింది.</translation>
<translation id="2916038427272391327">ఇతర à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± మూసివేయండి</translation>
<translation id="2922350208395188000">సరà±à°µà°°à± యొకà±à°• à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ తనిఖీ చెయà±à°¯à°¬à°¡à°¦à±.</translation>
<translation id="2928905813689894207">బిలà±à°²à°¿à°‚à°—à± à°šà°¿à°°à±à°¨à°¾à°®à°¾</translation>
+<translation id="2941952326391522266">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ <ph name="DOMAIN2" /> à°¨à±à°‚à°¡à°¿ జారీ చేయబడింది. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
<translation id="2948083400971632585">మీరౠసెటà±à°Ÿà°¿à°‚à°—à±â€Œà°² పేజీ à°¨à±à°‚à°¡à°¿ కనెకà±à°·à°¨à± కోసం కానà±à°«à°¿à°—రౠచేయబడిన à° à°ªà±à°°à°¾à°•à±à°¸à±€à°²à°¨à± అయినా నిలిపివేయవచà±à°šà±.</translation>
<translation id="2955913368246107853">à°•à°¨à±à°—ొనౠపటà±à°Ÿà±€à°¨à°¿ మూసివేయి</translation>
<translation id="2958431318199492670">నెటà±â€Œà°µà°°à±à°•à± కానà±à°«à°¿à°—రేషనౠONC à°ªà±à°°à°®à°¾à°£à°¾à°¨à°¿à°•à°¿ à°…à°¨à±à°•à±‚లంగా లేదà±. కానà±à°«à°¿à°—రేషనà±â€Œà°²à±‹à°¨à°¿ భాగాలౠదిగà±à°®à°¤à°¿ కాకపోయి ఉండకపోవచà±à°šà±.</translation>
-<translation id="29611076221683977">à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />పై దాడి చేసినవారౠమీ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, ఫోటోలà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠమరియౠకà±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) దొంగిలించడం కోసం లేదా తొలగించడం కోసం మీ Macలో à°ªà±à°°à°®à°¾à°¦à°•à°° à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°¿ ఉండవచà±à°šà±.</translation>
<translation id="2966678944701946121">à°—à°¡à±à°µà± à°®à±à°—à°¿à°‚à°ªà±: <ph name="EXPIRATION_DATE_ABBR" />, జోడించినది <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">à°¸à±à°°à°•à±à°·à°¿à°¤ కనెకà±à°·à°¨à±â€Œà°¨à± à°à°°à±à°ªà°¾à°Ÿà± చేయడానికి, మీ గడియారానà±à°¨à°¿ సరైన సమయానికి సెటౠచేయాలి. à°Žà°‚à°¦à±à°•à°‚టే వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°²à± వాటిని à°—à±à°°à±à°¤à°¿à°‚చడానికి ఉపయోగించే à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°²à± నిరà±à°¦à°¿à°·à±à°Ÿ కాలవà±à°¯à°µà°§à±à°²à±à°²à±‹ మాతà±à°°à°®à±‡ చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°µà±à°¤à°¾à°¯à°¿. మీ పరికరం గడియారం సమయం తపà±à°ªà±à°—à°¾ ఉనà±à°¨à°‚à°¦à±à°¨, Google Chrome à°ˆ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°²à°¨à± ధృవీకరించలేదà±.</translation>
<translation id="2972581237482394796">&amp;à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à°¿ నమోదౠచేయండి</translation>
<translation id="2986368408720340940">à°ˆ పికపౠపదà±à°§à°¤à°¿ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదà±. వేరే పదà±à°§à°¤à°¿à°¨à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="2991174974383378012">వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°²à°¤à±‹ భాగసà±à°µà°¾à°®à±à°¯à°‚</translation>
+<translation id="2991571918955627853">వెబà±â€Œà°¸à±ˆà°Ÿà± HSTS ఉపయోగిసà±à°¤à±à°¨à±à°¨à°‚à°¦à±à°¨ మీరౠపà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="SITE" />ని సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°®à±‡, à°•à°¨à±à°• à°ˆ పేజీ తరà±à°µà°¾à°¤ పనిచేయవచà±à°šà±.</translation>
<translation id="3005723025932146533">సేవౠచేయబడిన కాపీని చూపà±</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> కారà±à°¡à± CVCని నమోదౠచేయండి. మీరౠనిరà±à°§à°¾à°°à°¿à°‚à°šà°¿à°¨ తరà±à°µà°¾à°¤, మీ కారà±à°¡à± వివరాలౠఈ సైటà±â€Œà°¤à±‹ భాగసà±à°µà°¾à°®à±à°¯à°‚ చేయబడతాయి.</translation>
<translation id="3010559122411665027">జాబితా నమోదౠ"<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">à°¸à±à°µà°¯à°‚చాలకంగా à°¬à±à°²à°¾à°•à± చేయబడింది</translation>
<translation id="3024663005179499861">చెలà±à°²à°¨à°¿ విధాన à°°à°•à°‚</translation>
<translation id="3032412215588512954">మీరౠఈ సైటà±â€Œà°¨à± మళà±à°²à±€ లోడౠచేయాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
<translation id="3037605927509011580">ఆవà±, à°¸à±à°¨à°¾à°ªà±!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{సమకాలీకరించిన పరికరాలà±à°²à±‹ కనీసం 1 అంశం}=1{1 అంశం (మరియౠసమకాలీకరించిన పరికరాలà±à°²à±‹ మరినà±à°¨à°¿)}other{# అంశాలౠ(మరియౠసమకాలీకరించిన పరికరాలà±à°²à±‹ మరినà±à°¨à°¿)}}</translation>
<translation id="3041612393474885105">సరà±à°Ÿà°¿à°«à°¿à°•à±†à°Ÿà± సమాచారం</translation>
<translation id="3063697135517575841">Chrome à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ మీ కారà±à°¡à±â€Œà°¨à± నిరà±à°§à°¾à°°à°¿à°‚చలేకపోయింది. దయచేసి తరà±à°µà°¾à°¤ మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="3064966200440839136">బాహà±à°¯ à°…à°¨à±à°µà°°à±à°¤à°¨à°‚ à°¦à±à°µà°¾à°°à°¾ చెలà±à°²à°¿à°‚చడానికి à°…à°œà±à°žà°¾à°¤ మోడౠనà±à°‚à°¡à°¿ నిషà±à°•à±à°°à°®à°¿à°¸à±à°¤à±‹à°‚ది. కొనసాగించాలా?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{à°à°®à±€ లేవà±}=1{1 పాసà±â€Œà°µà°°à±à°¡à±}other{# పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±}}</translation>
<translation id="3093245981617870298">మీరౠఆఫà±â€Œà°²à±ˆà°¨à±â€Œà°²à±‹ ఉనà±à°¨à°¾à°°à±.</translation>
<translation id="3105172416063519923">అసెటౠID:</translation>
<translation id="3109728660330352905">మీకౠఈ పేజీని వీకà±à°·à°¿à°‚చడానికి అధికారం లేదà±.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />కనెకà±à°Ÿà°¿à°µà°¿à°Ÿà±€ సమసà±à°¯ విశà±à°²à±‡à°·à°£à°²à°¨à± అమలౠచేయడం à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">à°ªà±à°°à°¤à°¿à°¸à±à°ªà°‚దననౠడీకోడౠచేయడంలో విఫలమైంది</translation>
<translation id="3150653042067488994">తాతà±à°•à°¾à°²à°¿à°• సరà±à°µà°°à± లోపం</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">మీరౠఅజà±à°žà°¾à°¤ à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à±à°²à±‹ వీకà±à°·à°¿à°‚à°šà°¿à°¨ పేజీలౠమీ à°…à°¨à±à°¨à°¿ à°…à°œà±à°žà°¾à°¤ à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à°¨à± మూసివేసిన అనంతరం మీ à°¬à±à°°à±Œà°œà°°à± à°šà°°à°¿à°¤à±à°°, à°•à±à°•à±à°•à±€ à°¸à±à°Ÿà±‹à°°à± లేదా శోధన à°šà°°à°¿à°¤à±à°°à°²à±‹ ఉంచబడవà±. మీరౠడౌనà±â€Œà°²à±‹à°¡à± చేసే à°à°µà±ˆà°¨à°¾ ఫైలà±â€Œà°²à± లేదా మీరౠసృషà±à°Ÿà°¿à°‚చే à°à°µà±ˆà°¨à°¾ à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à± అలాగే ఉంచబడతాయి.</translation>
<translation id="3169472444629675720">à°•à°¨à±à°—ొనà±</translation>
<translation id="3174168572213147020">దీవి</translation>
+<translation id="317583078218509884">à°•à±à°°à±Šà°¤à±à°¤ సైటౠఅనà±à°®à°¤à±à°² సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à± పేజీని మళà±à°²à±€ లోడౠచేసిన తరà±à°µà°¾à°¤ à°ªà±à°°à°­à°¾à°µà°¿à°¤à°®à°µà±à°¤à°¾à°¯à°¿.</translation>
<translation id="3176929007561373547">à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à± పని చేసà±à°¤à±à°¨à±à°¨à°Ÿà±à°²à± నిరà±à°§à°¾à°°à°¿à°‚à°šà±à°•à±‹à°µà°¡à°¾à°¨à°¿à°•à°¿ మీ à°ªà±à°°à°¾à°•à±à°¸à±€ సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à°¨à± తనిఖీ చేయండి లేదా
మీ నెటà±â€Œà°µà°°à±à°•à± నిరà±à°µà°¾à°¹à°•à±à°¡à°¿à°¨à°¿ సంపà±à°°à°¦à°¿à°‚à°šà°‚à°¡à°¿. మీరౠపà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à±â€Œà°¨à±‡ ఉపయోగిసà±à°¤à±à°¨à±à°¨à°Ÿà±à°²à± మీకà±
నమà±à°®à°•à°‚à°—à°¾ లేకà±à°‚టే:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">à°…à°œà±à°žà°¾à°¤ మోడà±â€Œà°²à±‹ పేజీని తెరవండి</translation>
-<translation id="3202578601642193415">సరికà±à°°à±Šà°¤à±à°¤à°¦à°¿</translation>
+<translation id="320323717674993345">చెలà±à°²à°¿à°‚à°ªà±à°¨à± à°°à°¦à±à°¦à± చేయండి</translation>
<translation id="3207960819495026254">à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à± చేయబడింది</translation>
+<translation id="3225919329040284222">అంతరà±à°¨à°¿à°°à±à°®à°¿à°¤ అంచనాలకౠసరిపోలని à°’à°• ధృవీకరణ పతà±à°°à°¾à°¨à±à°¨à°¿ సరà±à°µà°°à± సమరà±à°ªà°¿à°‚చింది. మిమà±à°®à°²à±à°¨à°¿ సంరకà±à°·à°¿à°‚చే దిశగా నిరà±à°¦à°¿à°·à±à°Ÿ, ఉనà±à°¨à°¤ à°¸à±à°§à°¾à°¯à°¿ à°­à°¦à±à°°à°¤à°¾ వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°² కోసం à°ˆ అంచనాలౠచేరà±à°šà°¬à°¡à±à°¡à°¾à°¯à°¿.</translation>
<translation id="3226128629678568754">పేజీని లోడౠచేయడానికి అవసరమైన డేటానౠమళà±à°²à±€ సమరà±à°ªà°¿à°‚à°šà°¡à°‚ కోసం మళà±à°²à±€ లోడౠచేయి బటనౠకà±à°²à°¿à°•à± చేయండి.</translation>
+<translation id="3227137524299004712">మైకà±à°°à±‹à°«à±‹à°¨à±</translation>
<translation id="3228969707346345236">పేజీ ఇపà±à°ªà°Ÿà°¿à°•à±‡ <ph name="LANGUAGE" />లో ఉనà±à°¨à°‚à°¦à±à°¨ à°…à°¨à±à°µà°¾à°¦à°‚ విఫలమైంది.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> కారà±à°¡à± CVCని నమోదౠచేయండి</translation>
+<translation id="3234666976984236645">à°ˆ సైటà±â€Œà°²à±‹ à°Žà°²à±à°²à°ªà±à°ªà±à°¡à±‚ à°®à±à°–à±à°¯à°®à±ˆà°¨ కంటెంటà±â€Œà°¨à± à°—à±à°°à±à°¤à°¿à°‚à°šà±</translation>
<translation id="3254409185687681395">à°ˆ పేజీని à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à± చెయà±à°¯à°¿</translation>
<translation id="3270847123878663523">&amp;మళà±à°²à±€ à°•à±à°°à°®à°‚ చేయడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
<translation id="3282497668470633863">కారà±à°¡à±â€Œà°²à±‹ పేరà±à°¨à°¿ జోడించండి</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±</translation>
<translation id="3345135638360864351">à°ˆ సైటà±â€Œà°¨à°¿ à°ªà±à°°à°¾à°ªà±à°¯à°¤ చేయడానికి మీరౠచేసిన à°…à°­à±à°¯à°°à±à°¥à°¨ <ph name="NAME" />à°•à°¿ పంపబడలేదà±. దయచేసి మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="3355823806454867987">à°ªà±à°°à°¾à°•à±à°¸à±€ సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à°¨à± మారà±à°šà±...</translation>
+<translation id="3361596688432910856">Chrome à°ˆ కింది సమాచారానà±à°¨à°¿ <ph name="BEGIN_EMPHASIS" />సేవౠచేయదà±<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />మీ à°¬à±à°°à±Œà°œà°¿à°‚à°—à± à°šà°°à°¿à°¤à±à°°
+ <ph name="LIST_ITEM" />à°•à±à°•à±à°•à±€à°²à± మరియౠసైటౠడేటా
+ <ph name="LIST_ITEM" />ఫారమà±â€Œà°²à°²à±‹ నమోదౠచేసిన సమాచారం
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">గడియారం లోపం</translation>
-<translation id="337311366426640088">మరో <ph name="ITEM_COUNT" /> వసà±à°¤à±à°µà±à°²à±...</translation>
<translation id="337363190475750230">కేటాయింపౠతీసివేయబడింది</translation>
<translation id="3377188786107721145">విధాన à°…à°¨à±à°µà°¯ లోపం</translation>
<translation id="3380365263193509176">తెలియని లోపం</translation>
<translation id="3380864720620200369">à°•à±à°²à°¯à°¿à°‚à°Ÿà± ID:</translation>
<translation id="3391030046425686457">బటà±à°µà°¾à°¡à°¾ à°šà°¿à°°à±à°¨à°¾à°®à°¾</translation>
<translation id="3395827396354264108">పికపౠపదà±à°§à°¤à°¿</translation>
-<translation id="340013220407300675">దాడి చేసేవారౠ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> à°¨à±à°‚à°¡à°¿ మీ సమాచారానà±à°¨à°¿ దొంగిలించడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°¸à±à°¤à±à°‚డవచà±à°šà± (ఉదాహరణకà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠలేదా à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±).</translation>
<translation id="3422248202833853650">మెమరీని ఖాళీ చేయడానికి ఇతర à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°² à°¨à±à°‚à°¡à°¿ నిషà±à°•à±à°°à°®à°¿à°‚చడానà±à°¨à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" />ని à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ చేరà±à°•à±‹à°µà°¡à°‚ సాధà±à°¯à°ªà°¡à°¦à±.</translation>
+<translation id="3427092606871434483">à°…à°¨à±à°®à°¤à°¿à°‚à°šà± (డిఫాలà±à°Ÿà±)</translation>
<translation id="3427342743765426898">&amp;సవరించడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
<translation id="3431636764301398940">à°ˆ కారà±à°¡à±â€Œà°¨à± à°ˆ పరికరానికి సేవౠచేయి</translation>
<translation id="3435896845095436175">à°ªà±à°°à°¾à°°à°‚à°­à°¿à°‚à°šà°‚à°¡à°¿</translation>
<translation id="3447661539832366887">à°ˆ పరికర యజమాని డైనోసారౠఆటనౠఆఫౠచేసారà±.</translation>
-<translation id="3450660100078934250">మాసà±à°Ÿà°°à±â€Œà°•à°¾à°°à±à°¡à±</translation>
<translation id="3452404311384756672">విరామానà±à°¨à°¿ పొందండి:</translation>
<translation id="3462200631372590220">à°…à°§à±à°¨à°¾à°¤à°¨à°‚ దాచà±</translation>
<translation id="3467763166455606212">కారà±à°¡à±à°¦à°¾à°°à±à°¨à°¿ పేరౠఅవసరం</translation>
<translation id="3478058380795961209">à°—à°¡à±à°µà± à°®à±à°—ింపౠనెల</translation>
<translation id="3479539252931486093">ఊహించని విధంగా ఇది సంభవించిందా? <ph name="BEGIN_LINK" />మాకౠతెలియజేయండి<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">ఇపà±à°ªà±à°¡à± కాదà±</translation>
-<translation id="348000606199325318">à°•à±à°°à°¾à°·à± ID <ph name="CRASH_LOCAL_ID" /> (సరà±à°µà°°à± ID: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">మేమౠపà±à°°à°¸à±à°¤à±à°¤à°‚ మీ తలà±à°²à°¿/తండà±à°°à°¿à°¨à°¿ సంపà±à°°à°¦à°¿à°‚చలేకపోయామà±. దయచేసి మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="3528171143076753409">సరà±à°µà°°à± యొకà±à°• à°ªà±à°°à°®à°¾à°£ పతà±à°°à°‚ నమà±à°®à°¦à°—ినది కాదà±.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{సమకాలీకరించిన పరికరాలà±à°²à±‹ కనీసం 1 అంశం}=1{1 అంశం (మరియౠసమకాలీకరించిన పరికరాలà±à°²à±‹ మరినà±à°¨à°¿)}other{# అంశాలౠ(మరియౠసమకాలీకరించిన పరికరాలà±à°²à±‹ మరినà±à°¨à°¿)}}</translation>
<translation id="3539171420378717834">à°ˆ పరికరంలో à°ˆ కారà±à°¡à± కాపీని ఉంచà±</translation>
<translation id="3542684924769048008">దీని కోసం పాసà±â€Œà°µà°°à±à°¡à±â€Œà°¨à± ఉపయోగించండి:</translation>
+<translation id="3545341443414427877">మీ à°•à°‚à°ªà±à°¯à±‚టరౠతేదీ మరియౠసమయం (<ph name="DATE_AND_TIME" />) తపà±à°ªà±à°—à°¾ ఉనà±à°¨à°‚à°¦à±à°¨ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />à°•à°¿ à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కనెకà±à°·à°¨à± à°à°°à±à°ªà°¾à°Ÿà± కాలేదà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">మీ à°¸à±à°µà°‚à°¤ సమకాలీకరణ రహసà±à°¯ పదబంధంతో సమకాలీకరించబడిన డేటా మొతà±à°¤à°¾à°¨à±à°¨à°¿ à°—à±à°ªà±à°¤à±€à°•à°°à°¿à°‚à°šà°‚à°¡à°¿</translation>
-<translation id="3549761410225185768">మరో <ph name="NUM_TABS_MORE" />...</translation>
-<translation id="3555561725129903880">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ <ph name="DOMAIN2" /> à°¨à±à°‚à°¡à°¿ అందించబడి ఉండవచà±à°šà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగిసà±à°¤à±à°‚à°¡à°Ÿà°‚ వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">మీ నిరà±à°µà°¾à°¹à°•à±à°¡à± మీ కోసం దీనà±à°¨à°¿ à°…à°¨à±â€Œà°¬à±à°²à°¾à°•à± చేయగలరà±</translation>
<translation id="3566021033012934673">మీ కనెకà±à°·à°¨à± à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కాదà±</translation>
+<translation id="3569145463236695319">&lt;p&gt;మీ à°•à°‚à°ªà±à°¯à±‚టరౠతేదీ మరియౠసమయం (<ph name="DATE_AND_TIME" />) తపà±à°ªà±à°—à°¾ ఉనà±à°¨à°‚à°¦à±à°¨ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />à°•à°¿ à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కనెకà±à°·à°¨à± à°à°°à±à°ªà°¾à°Ÿà± కాలేదà±.&lt;/p&gt;
+
+ &lt;p&gt;దయచేసి à°…à°¨à±à°µà°°à±à°¤à°¨ &lt;strong&gt;సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±&lt;/strong&gt; యొకà±à°• &lt;strong&gt;సాధారణ&lt;/strong&gt; వరà±à°—à°‚ à°¨à±à°‚à°¡à°¿ తేదీ మరియౠసమయానà±à°¨à°¿ సరà±à°¦à±à°¬à°¾à°Ÿà± చేయండి.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">పేరౠజోడించండి</translation>
<translation id="3583757800736429874">&amp;తరలించడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
<translation id="3586931643579894722">వివరాలనౠదాచిపెటà±à°Ÿà±</translation>
-<translation id="3587482841069643663">మొతà±à°¤à°‚</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ à°—à°¡à±à°µà± à°®à±à°—ింపౠతేదీని నమోదౠచేయండి</translation>
<translation id="36224234498066874">à°¬à±à°°à±Œà°œà°¿à°‚గౠడేటానౠకà±à°²à°¿à°¯à°°à± చెయà±à°¯à°¿...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">సరà±à°Ÿà°¿à°«à°¿à°•à±†à°Ÿà± సమాచారం</translation>
<translation id="3690164694835360974">లాగినౠసà±à°°à°•à±à°·à°¿à°¤à°‚ కాదà±</translation>
<translation id="3693415264595406141">పాసà±â€Œà°µà°°à±à°¡à±:</translation>
-<translation id="3696411085566228381">à°à°¦à±€ కాదà±</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">లోడౠఅవà±à°¤à±‹à°‚ది...</translation>
<translation id="3712624925041724820">లైసెనà±à°¸à±â€Œà°²à± అయిపోయాయి</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />à°ªà±à°°à°¾à°•à±à°¸à±€, ఫైరà±â€Œà°µà°¾à°²à± మరియౠDNS కానà±à°«à°¿à°—రేషనà±â€Œà°¨à± తనిఖీ చేయడం<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">మీ à°­à°¦à±à°°à°¤à°•à± వాటిలà±à°²à±‡ ఆపదల à°—à±à°°à°¿à°‚à°šà°¿ మీకౠఅరà±à°¥à°‚ à°…à°¯à±à°¯à°¿ ఉంటే, à°ªà±à°°à°®à°¾à°¦à°•à°°à°®à±ˆà°¨ à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à± తీసివేయబడటానికి à°®à±à°‚దే <ph name="BEGIN_LINK" />à°ˆ à°…à°¸à±à°°à°•à±à°·à°¿à°¤à°®à±ˆà°¨ సైటà±â€Œà°¨à± సందరà±à°¶à°¿à°‚చవచà±à°šà±<ph name="END_LINK" />.</translation>
<translation id="3739623965217189342">మీరౠకాపీ చేసిన లింకà±</translation>
+<translation id="3744899669254331632">మీరౠసందరà±à°¶à°¿à°‚చాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨ <ph name="SITE" /> వెబà±â€Œà°¸à±ˆà°Ÿà± Chromium à°ªà±à°°à°¾à°¸à±†à°¸à± చేయలేని చిందరవందరైన ఆధారాలనౠపంపినందà±à°¨ à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ దానà±à°¨à°¿ సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°‚à°—à°¾ మాతà±à°°à°®à±‡ ఉంటాయి, కాబటà±à°Ÿà°¿ à°ˆ పేజీ బహà±à°¶à°¾ తరà±à°µà°¾à°¤ పని చేయవచà±à°šà±.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />లోని à°¹à±à°¯à°¾à°•à°°à±â€Œà°²à± మిమà±à°®à°²à±à°¨à°¿ సాఫà±à°Ÿà±â€Œà°µà±‡à°°à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేసే విధంగా లేదా మీ à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, ఫోనౠనంబరà±â€Œà°²à± లేదా à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) బహిరà±à°—తం చేసే విధంగా మిమà±à°®à°²à±à°¨à°¿ మాయ చేయవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">సరà±à°µà°°à± లోపం వలà±à°² à°…à°¨à±à°µà°¾à°¦à°‚ విఫలమైంది.</translation>
<translation id="3759461132968374835">మీకౠఇటీవల నివేదించిన à°•à±à°°à°¾à°·à±â€Œà°²à± లేవà±. à°•à±à°°à°¾à°·à±â€Œ నివేదన నిలిపివేసినపà±à°¡à± à°à°°à±à°ªà°¡à±‡ à°•à±à°°à°¾à°·à±â€Œà°²à± ఇకà±à°•à°¡ కనిపించవà±.</translation>
+<translation id="3778403066972421603">à°ˆ కారà±à°¡à±â€Œà°¨à°¿ మీ Google ఖాతాకౠమరియౠఈ పరికరంలో సేవౠచేయాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">à°—à°¡à±à°µà± à°®à±à°—ింపౠ<ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">మీరౠపà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à±â€Œà°¨à± ఉపయోగిసà±à°¤à±‡...</translation>
<translation id="3828924085048779000">ఖాళీ పాసà±â€Œà°«à±à°°à±‡à°œà± à°…à°¨à±à°®à°¤à°¿à°‚చబడదà±.</translation>
-<translation id="3845539888601087042">మీరౠసైనà±-ఇనౠచేసిన పరికరాల à°¨à±à°‚à°¡à°¿ à°šà°°à°¿à°¤à±à°°à°¨à± చూపà±à°¤à±‹à°‚ది. <ph name="BEGIN_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">వెనà±à°•à°•à±</translation>
<translation id="3858027520442213535">తేదీ మరియౠసమయానà±à°¨à°¿ నవీకరించà±</translation>
<translation id="3884278016824448484">వైరà±à°§à±à°¯à°®à±ˆà°¨ పరికరం à°à°¡à±†à°‚టిఫైయరà±</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">మీరౠఈ సైటà±â€Œà°¨à± à°ªà±à°°à°¾à°ªà±à°¯à°¤ చేయడానికి చేసిన à°…à°­à±à°¯à°°à±à°¥à°¨ <ph name="NAME" />à°•à°¿ పంపబడింది</translation>
<translation id="3890664840433101773">ఇమెయిలà±â€Œà°¨à± జోడించండి</translation>
<translation id="3901925938762663762">కారà±à°¡à± à°—à°¡à±à°µà± సమయం à°®à±à°—ిసింది</translation>
-<translation id="3933571093587347751">{1,plural, =1{à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ రేపటిది కావచà±à°šà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.}other{à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ భవిషà±à°¯à°¤à±à°¤à±à°²à±‹ # రోజà±à°² తదà±à°ªà°°à°¿à°¦à°¿ కావచà±à°šà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేసినందà±à°¨ లేదా దాడిచేసేవారౠమీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినందà±à°¨ ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF పతà±à°°à°¾à°¨à±à°¨à°¿ లోడౠచెయà±à°¯à°¡à°¾à°¨à°¿à°•à°¿ విఫలమైంది</translation>
+<translation id="3945915738023014686">à°•à±à°°à°¾à°·à± నివేదిక ID <ph name="CRASH_ID" /> (à°¸à±à°¥à°¾à°¨à°¿à°• à°•à±à°°à°¾à°·à± ID: <ph name="CRASH_LOCAL_ID" />) à°…à°ªà±â€Œà°²à±‹à°¡à± చేయబడింది</translation>
+<translation id="3949571496842715403">à°ˆ సరà±à°µà°°à± తనౠ<ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚లో విషయ à°ªà±à°°à°¤à±à°¯à°¾à°®à±à°¨à°¾à°¯ పేరà±à°²à± పేరà±à°•à±Šà°¨à°¬à°¡à°²à±‡à°¦à±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా à°¹à±à°¯à°¾à°•à°°à± మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±.</translation>
<translation id="3963721102035795474">పాఠకà±à°¨à°¿ మోడà±</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{à°à°µà±€ కాదà±}=1{1 సైటౠనà±à°‚à°¡à°¿ }other{# సైటà±â€Œà°² à°¨à±à°‚à°¡à°¿ }}</translation>
<translation id="397105322502079400">గణిసà±à°¤à±‹à°‚ది...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> à°¬à±à°²à°¾à°•à± చేయబడింది</translation>
+<translation id="3987940399970879459">1 MB కంటే తకà±à°•à±à°µ</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 వెబౠపేజీ సమీపంలో ఉంది}other{# వెబౠపేజీలౠసమీపంలో ఉనà±à°¨à°¾à°¯à°¿}}</translation>
<translation id="4021036232240155012">DNS అనేది వెబà±â€Œà°¸à±ˆà°Ÿà± పేరà±à°¨à± దాని ఇంటరà±à°¨à±†à°Ÿà± à°šà°¿à°°à±à°¨à°¾à°®à°¾à°•à°¿ à°…à°¨à±à°µà°¦à°¿à°‚చే నెటà±â€Œà°µà°°à±à°•à± సేవ.</translation>
<translation id="4030383055268325496">&amp;జోడించడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">à°ªà±à°°à°¾à°•à±à°¸à±€ కానà±à°«à°¿à°—రేషనౠసà±à°¥à°¿à°°à°®à±ˆà°¨ à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à±â€Œà°²à°¨à± కాకà±à°‚à°¡à°¾, à°’à°• .pac à°¸à±à°•à±à°°à°¿à°ªà±à°Ÿà± URLనౠఉపయోగించడానికి సెటౠచేయబడింది.</translation>
<translation id="4098354747657067197">à°®à±à°‚దౠవంచనాతà±à°®à°• సైటౠఉంది</translation>
<translation id="4103249731201008433">పరికరం à°•à±à°°à°® సంఖà±à°¯ చెలà±à°²à°¦à±</translation>
+<translation id="410351446219883937">à°¸à±à°µà±€à°¯ à°ªà±à°²à±‡</translation>
<translation id="4103763322291513355">నిరోధిత జాబితాలో ఉనà±à°¨ URLà°² జాబితానౠమరియౠమీ సిసà±à°Ÿà°®à± నిరà±à°µà°¾à°¹à°•à±à°¨à°¿ à°¦à±à°µà°¾à°°à°¾ అమలౠచేయబడిన ఇతర విధానాలనౠచూడటానికి &lt;strong&gt;chrome://policy&lt;/strong&gt;ని సందరà±à°¶à°¿à°‚à°šà°‚à°¡à°¿.</translation>
-<translation id="4110615724604346410">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ లోపాలనౠకలిగి ఉంది. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">మెజెంటా</translation>
+<translation id="4116663294526079822">à°ˆ సైటà±â€Œà°²à±‹ à°Žà°²à±à°²à°ªà±à°ªà±à°¡à±‚ à°…à°¨à±à°®à°¤à°¿à°‚à°šà±</translation>
<translation id="4117700440116928470">విధానం పరిధికి మదà±à°¦à°¤à± లేదà±.</translation>
-<translation id="4118212371799607889">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ Chromium విశà±à°µà°¸à°¿à°‚చలేదà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{మరో 1}other{మరో #}}</translation>
<translation id="4130226655945681476">నెటà±â€Œà°µà°°à±à°•à± కేబà±â€Œà°²à±â€Œà°²à±, మోడమౠమరియౠరూటరà±â€Œà°¨à± తనిఖీ చేయడం</translation>
+<translation id="413544239732274901">మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿</translation>
<translation id="4148925816941278100">అమెరికనౠఎకà±à°¸à±â€Œà°ªà±à°°à±†à°¸à±</translation>
+<translation id="4151403195736952345">భౌగోళిక డిఫాలà±à°Ÿà±â€Œà°¨à± ఉపయోగించౠ(à°—à±à°°à±à°¤à°¿à°‚à°šà±)</translation>
+<translation id="4165986682804962316">సైటౠసెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±</translation>
<translation id="4169947484918424451">Chromium à°ˆ కారà±à°¡à±â€Œà°¨à± సేవౠచేయాలని మీరౠకోరà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
<translation id="4171400957073367226">ధృవీకరణ సంతకం చెలà±à°²à°¦à±</translation>
<translation id="4196861286325780578">&amp;తరలించడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ఫైరà±â€Œà°µà°¾à°²à± మరియౠయాంటీవైరసౠకానà±à°«à°¿à°—రేషనà±â€Œà°²à°¨à± తనిఖీ చేయడం<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{à°à°¦à±€ లేదà±}=1{1 à°…à°¨à±à°µà°°à±à°¤à°¨à°‚ ($1)}=2{2 à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à± ($1, $2)}other{# à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à± ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">à°•à±à°°à°¾à°·à±â€Œà°²à±</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />లోని à°¹à±à°¯à°¾à°•à°°à±â€Œà°²à± మీ à°¬à±à°°à±Œà°œà°¿à°‚à°—à± à°…à°¨à±à°­à°µà°¾à°¨à°¿à°•à°¿ (ఉదాహరణకà±, మీ హోం పేజీని మారà±à°šà°¡à°‚ లేదా మీరౠసందరà±à°¶à°¿à°‚చే సైటà±â€Œà°²à°²à±‹ అదనపౠపà±à°°à°•à°Ÿà°¨à°²à± చూపడం à°¦à±à°µà°¾à°°à°¾) హాని కలిగించే à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేసే విధంగా మిమà±à°®à°²à±à°¨à°¿ మాయచేసే à°ªà±à°°à°¯à°¤à±à°¨à°‚ చేయవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />నెటà±â€Œà°µà°°à±à°•à± సమసà±à°¯ విశà±à°²à±‡à°·à°£à°²à°¨à± అమలౠచేయడం à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">చెలà±à°²à±à°¤à±à°‚ది</translation>
<translation id="4250431568374086873">à°ˆ సైటà±â€Œà°•à°¿ మీ కనెకà±à°·à°¨à± పూరà±à°¤à°¿ à°¸à±à°¥à°¾à°¯à°¿à°²à±‹ à°¸à±à°°à°•à±à°·à°¿à°¤à°‚à°—à°¾ లేదà±</translation>
<translation id="4250680216510889253">కాదà±</translation>
<translation id="425582637250725228">మీరౠచేసిన మారà±à°ªà±à°²à± సేవౠఅయà±à°¯à°¿ ఉండకపోవచà±à°šà±.</translation>
<translation id="4258748452823770588">చెలà±à°²à°¨à°¿ సంతకం</translation>
+<translation id="4265872034478892965">మీ నిరà±à°µà°¾à°¹à°•à±à°²à± à°…à°¨à±à°®à°¤à°¿à°‚చారà±</translation>
<translation id="4269787794583293679">(వినియోగదారౠపేరౠలేదà±)</translation>
<translation id="4275830172053184480">మీ పరికరానà±à°¨à°¿ à°ªà±à°¨à°ƒà°ªà±à°°à°¾à°°à°‚à°­à°¿à°‚à°šà°‚à°¡à°¿</translation>
<translation id="4280429058323657511">, à°—à°¡à±à°µà± à°®à±à°—ింపౠ<ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />హానికరమైన à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± à°—à±à°°à±à°¤à°¿à°‚చింది<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">తలà±à°²à°¿/తండà±à°°à°¿ సూచనలà±</translation>
<translation id="4304224509867189079">లాగినà±</translation>
-<translation id="432290197980158659">సరà±à°µà°°à± అంతరà±à°¨à°¿à°°à±à°®à°¿à°¤ అంచనాలకౠసరిపోలని à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. మిమà±à°®à°²à±à°¨à°¿ సంరకà±à°·à°¿à°‚చే దిశగా నిరà±à°§à°¿à°·à±à°Ÿ, ఉనà±à°¨à°¤ à°¸à±à°¥à°¾à°¯à°¿ à°­à°¦à±à°°à°¤à°¾ వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°² కోసం à°ˆ అంచనాలౠచేరà±à°šà°¬à°¡à±à°¡à°¾à°¯à°¿. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">à°¬à±à°²à°¾à°•à± చేయి (డిఫాలà±à°Ÿà±)</translation>
<translation id="4325863107915753736">కథనానà±à°¨à°¿ à°•à°¨à±à°—ొనడం విఫలమైంది</translation>
<translation id="4326324639298822553">మీ à°—à°¡à±à°µà± à°®à±à°—ింపౠతేదీని తనిఖీ చేసి, ఆపై మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿</translation>
<translation id="4331708818696583467">à°¸à±à°°à°•à±à°·à°¿à°¤à°‚ కాదà±</translation>
<translation id="4356973930735388585">à°ˆ సైటà±â€Œà°²à±‹à°¨à°¿ దాడి చేసేవారౠమీ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, ఫోటోలà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠమరియౠకà±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) దొంగిలించడం కోసం లేదా తొలగించడం కోసం మీ à°•à°‚à°ªà±à°¯à±‚à°Ÿà°°à±â€Œà°²à±‹ à°ªà±à°°à°®à°¾à°¦à°•à°°à°®à±ˆà°¨ à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చవచà±à°šà±.</translation>
<translation id="4372948949327679948">ఆశిసà±à°¤à±à°¨à±à°¨ <ph name="VALUE_TYPE" /> విలà±à°µ.</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" />నౠచేరà±à°•à±‹à°µà°¡à°¾à°¨à°¿à°•à°¿ మీరౠపà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± అందించిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ దానà±à°¨à°¿ జారీ చేసినవారౠరదà±à°¦à± చేసారà±. సరà±à°µà°°à± అందించిన à°­à°¦à±à°°à°¤ ఆధారాలౠఖచà±à°šà°¿à°¤à°‚à°—à°¾ విశà±à°µà°¸à°¿à°‚చబడలేదని దీని à°…à°°à±à°¥à°‚. మీరౠదాడి చేసే వారితో à°•à°®à±à°¯à±‚నికేటౠచేసà±à°¤à±‚ ఉండవచà±à°šà±.</translation>
<translation id="4381091992796011497">యూజరౠపేరà±:</translation>
<translation id="4394049700291259645">ఆపివెయà±à°¯à°¿</translation>
<translation id="4406896451731180161">శోధన ఫలితాలà±</translation>
+<translation id="4424024547088906515">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ Chrome విశà±à°µà°¸à°¿à°‚చలేదà±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> మీ లాగినౠపà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ ఆమోదించలేదౠలేదా à°à°¦à±€ అందించి ఉండకపోవచà±à°šà±.</translation>
<translation id="443673843213245140">à°ªà±à°°à°¾à°•à±à°¸à±€à°¨à°¿ ఉపయోగించడం ఆపివేయబడింది కానీ à°¸à±à°ªà°·à±à°Ÿà°®à±ˆà°¨ à°ªà±à°°à°¾à°•à±à°¸à±€ కానà±à°«à°¿à°—రేషనౠపేరà±à°•à±Šà°¨à°¬à°¡à°¿à°‚ది.</translation>
-<translation id="4492190037599258964"><ph name="SEARCH_STRING" />' కోసం శోధన ఫలితాలà±</translation>
<translation id="4506176782989081258">ధృవీకరణ లోపం: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">సిసà±à°Ÿà°®à± నిరà±à°µà°¾à°¹à°•à±à°¡à°¿à°¨à°¿ సంపà±à°°à°¦à°¿à°‚à°šà°¡à°‚</translation>
<translation id="450710068430902550">నిరà±à°µà°¾à°¹à°•à±à°¡à°¿à°¤à±‹ భాగసà±à°µà°¾à°®à±à°¯à°‚</translation>
<translation id="4515275063822566619">కారà±à°¡à±â€Œà°²à± మరియౠచిరà±à°¨à°¾à°®à°¾à°²à± Chrome మరియౠమీ Google ఖాతా (<ph name="ACCOUNT_EMAIL" />) à°¨à±à°‚à°¡à°¿ పొందినవి. మీరౠ<ph name="BEGIN_LINK" />సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à±<ph name="END_LINK" />లో వాటిని నిరà±à°µà°¹à°¿à°‚చవచà±à°šà±.</translation>
<translation id="4522570452068850558">వివరాలà±</translation>
+<translation id="4552089082226364758">à°«à±à°²à°¾à°·à±</translation>
<translation id="4558551763791394412">మీ పొడిగింపà±à°²à°¨à± నిలిపివేయడం à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="457875822857220463">బటà±à°µà°¾à°¡à°¾</translation>
<translation id="4587425331216688090">Chrome à°¨à±à°‚à°¡à°¿ à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à± తీసివేయాలా?</translation>
-<translation id="4589078953350245614">మీరౠ<ph name="DOMAIN" />à°•à°¿ కనెకà±à°Ÿà± కావడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà± కాని à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" />à°•à°¿ à°—à°² మీ కనెకà±à°·à°¨à± ఆధà±à°¨à°¿à°• సైఫరౠసూటౠఉపయోగించి à°—à±à°ªà±à°¤à±€à°•à°°à°¿à°‚చబడింది.</translation>
<translation id="4594403342090139922">&amp;తొలగించడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
<translation id="4619615317237390068">ఇతర పరికరాలà±à°²à±‹à°¨à°¿ à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à±</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚లో లోపాలౠఉనà±à°¨à°¾à°¯à°¿. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
+<translation id="4690462567478992370">చెలà±à°²à°¨à°¿ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ ఉపయోగించడానà±à°¨à°¿ ఆపివేయి</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">మీ కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం à°à°°à±à°ªà°¡à°¿à°‚ది</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows నెటà±â€Œà°µà°°à±à°•à± సమసà±à°¯ విశà±à°²à±‡à°·à°£à°²à°¨à± అమలౠచేయడం<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">తెలియని లోపం à°’à°•à°Ÿà°¿ à°à°°à±à°ªà°¡à°¿à°‚ది.</translation>
<translation id="4800132727771399293">మీ à°—à°¡à±à°µà± à°®à±à°—ింపౠతేదీ మరియౠCVCని తనిఖీ చేసి, మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">వెబà±â€Œà°¸à±ˆà°Ÿà± Google Chrome à°ªà±à°°à°¾à°¸à±†à°¸à± చేయలేని, గజిబిజిగా ఉండే ఆధారాలనౠపంపినందà±à°¨ మీరౠపà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="SITE" />ని సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°‚గానే ఉంటాయి, à°•à°¨à±à°• à°ˆ పేజీ కాసేపటి తరà±à°µà°¾à°¤ పని చేసే అవకాశం ఉంది.</translation>
<translation id="4813512666221746211">నెటà±â€Œà°µà°°à±à°•à± లోపం</translation>
<translation id="4816492930507672669">పేజీకి తగినటà±à°²à± అమరà±à°šà±</translation>
<translation id="483020001682031208">చూపడానికి సహజసిదà±à°§ వెబౠపేజీలేవీ లేవà±</translation>
<translation id="4850886885716139402">వీకà±à°·à°£</translation>
<translation id="4854362297993841467">à°ˆ బటà±à°µà°¾à°¡à°¾ పదà±à°§à°¤à°¿ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదà±. వేరే పదà±à°§à°¤à°¿à°¨à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="4858792381671956233">à°ˆ సైటà±â€Œà°¨à± సందరà±à°¶à°¿à°‚చడానికి à°…à°¨à±à°®à°¤à°¿à°‚చమని కోరà±à°¤à±‚ మీ తలà±à°²à°¿à°¦à°‚à°¡à±à°°à±à°²à°•à± à°…à°­à±à°¯à°°à±à°¥à°¨ పంపారà±</translation>
+<translation id="4863764087567530506">సాఫà±à°Ÿà±â€Œà°µà±‡à°°à±â€Œà°¨à°¿ ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడం లేదా à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ సమాచారానà±à°¨à°¿ బహిరà±à°—తం చేయడం à°¦à±à°µà°¾à°°à°¾ à°ˆ కంటెంటౠమిమà±à°®à°²à±à°¨à°¿ మోసం చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°¿ ఉండవచà±à°šà±. <ph name="BEGIN_LINK" />à°à°¦à±‡à°®à±ˆà°¨à°¾ చూపà±<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">శోధన à°šà°°à°¿à°¤à±à°°</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{మరియౠమరో 1 వెబౠపేజీ}other{మరియౠమరో # వెబౠపేజీలà±}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">à°ˆ పేజీ తెలియని భాష à°¨à±à°‚à°¡à°¿ <ph name="LANGUAGE_LANGUAGE" />à°•à± à°…à°¨à±à°µà°¦à°¿à°‚చబడింది</translation>
<translation id="4923459931733593730">చెలà±à°²à°¿à°‚à°ªà±</translation>
<translation id="4926049483395192435">à°–à°šà±à°šà°¿à°¤à°‚à°—à°¾ పేరà±à°•à±Šà°¨à°¾à°²à°¿.</translation>
<translation id="495170559598752135">à°šà°°à±à°¯à°²à±</translation>
<translation id="4958444002117714549">జాబితానౠవిసà±à°¤à°°à°¿à°‚à°šà±</translation>
-<translation id="4962322354953122629">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ Chrome విశà±à°µà°¸à°¿à°‚చలేదà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">హెచà±à°šà°°à°¿à°•à°²à°¨à± మళà±à°²à±€ à°ªà±à°°à°¾à°°à°‚à°­à°¿à°‚à°šà±</translation>
<translation id="4989809363548539747">à°ˆ à°ªà±à°²à°—à°¿à°¨à±â€Œà°•à± మదà±à°¦à°¤à± లేదà±</translation>
<translation id="5002932099480077015">à°ªà±à°°à°¾à°°à°‚à°­à°¿à°¸à±à°¤à±‡, వేగవంతమైన ఫారమౠపూరింపౠకోసం Chrome à°ˆ పరికరంలో మీ కారà±à°¡à± కాపీని నిలà±à°µ చేసà±à°¤à±à°‚ది.</translation>
<translation id="5018422839182700155">à°ˆ పేజీని తెరవడం సాధà±à°¯à°ªà°¡à°¦à±</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">మీ నిరà±à°µà°¾à°¹à°•à±à°¨à°¿ విధానాలనౠచూడండి</translation>
<translation id="5029568752722684782">కాపీని తీసివేయి</translation>
<translation id="5031870354684148875">Google à°…à°¨à±à°µà°¾à°¦à°‚ à°—à±à°°à°¿à°‚à°šà°¿</translation>
+<translation id="5039804452771397117">à°…à°¨à±à°®à°¤à°¿à°‚à°šà±</translation>
<translation id="5040262127954254034">గోపà±à°¯à°¤</translation>
<translation id="5045550434625856497">సరికాని పాసà±â€Œà°µà°°à±à°¡à±</translation>
<translation id="5056549851600133418">మీ కోసం కథనాలà±</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />à°ªà±à°°à°¾à°•à±à°¸à±€ à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à± తనిఖీ చేయడం<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{à°•à±à°•à±à°•à±€à°²à± లేవà±}=1{1 సైటౠకà±à°•à±à°•à±€à°²à°¨à± ఉపయోగిసà±à°¤à±‹à°‚ది. }other{# సైటà±â€Œà°²à± à°•à±à°•à±à°•à±€à°²à°¨à± ఉపయోగిసà±à°¤à±à°¨à±à°¨à°¾à°¯à°¿. }}</translation>
<translation id="5087286274860437796">à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ చెలà±à°²à°¦à±.</translation>
<translation id="5087580092889165836">కారà±à°¡à±â€Œà°¨à± జోడించà±</translation>
<translation id="5089810972385038852">రాషà±à°Ÿà±à°°à°‚</translation>
+<translation id="5094747076828555589">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ Chromium విశà±à°µà°¸à°¿à°‚చలేదà±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
<translation id="5095208057601539847">à°ªà±à°°à°¾à°µà°¿à°¨à±à°¸à±</translation>
<translation id="5115563688576182185">(64-బిటà±)</translation>
<translation id="5141240743006678641">మీ Google ఆధారాలతో సమకాలీకరించబడిన పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à°¨à± à°—à±à°ªà±à°¤à±€à°•à°°à°¿à°‚à°šà°‚à°¡à°¿</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">ఇమెయిలౠఆవశà±à°¯à°•à°‚</translation>
<translation id="5251803541071282808">à°•à±à°²à±Œà°¡à±</translation>
<translation id="5277279256032773186">కారà±à°¯à°¾à°²à°¯à°‚లో Chrome ఉపయోగిసà±à°¤à±à°¨à±à°¨à°¾à°°à°¾? à°µà±à°¯à°¾à°ªà°¾à°° సంసà±à°¥à°²à± తమ ఉదà±à°¯à±‹à°—à±à°² కోసం Chrome సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à°¨à± నిరà±à°µà°¹à°¿à°‚చగలవà±. మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿</translation>
+<translation id="5297526204711817721">à°ˆ సైటà±â€Œà°•à± మీ కనెకà±à°·à°¨à± à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కాదà±. à°Žà°ªà±à°ªà±à°¡à±ˆà°¨à°¾ VR మోడౠనà±à°‚à°¡à°¿ నిషà±à°•à±à°°à°®à°¿à°‚చడానికి, హెడà±â€Œà°¸à±†à°Ÿà±â€Œà°¨à± తీసివేసి, వెనà±à°•à°•à± నొకà±à°•à°‚à°¡à°¿.</translation>
<translation id="5299298092464848405">విధానానà±à°¨à°¿ à°…à°¨à±à°µà°¯à°¿à°‚చడంలో లోపం</translation>
-<translation id="5300589172476337783">చూపించà±</translation>
<translation id="5308689395849655368">à°•à±à°°à°¾à°·à± నివేదిక నిలిపివెయà±à°¯à°¬à°¡à°¿à°‚ది.</translation>
<translation id="5317780077021120954">సేవౠచేయి</translation>
<translation id="5327248766486351172">పేరà±</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />పై దాడి చేసే à°µà±à°¯à°•à±à°¤à±à°²à± సాఫà±à°Ÿà±â€Œà°µà±‡à°°à±â€Œà°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేసà±à°•à±‹à°®à°¨à°¡à°‚ లేదా మీ à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, ఫోనౠనంబరà±â€Œà°²à± లేదా à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) వెలà±à°²à°¡à°¿à°‚చమనడం వంటి à°ªà±à°°à°®à°¾à°¦à°•à°°à°®à±ˆà°¨ పనà±à°²à± చేయమని à°ªà±à°°à°¿à°•à±Šà°²à±à°ªà±‡à°²à°¾ మిమà±à°®à°²à±à°¨à°¿ మాయ చేయవచà±à°šà±.</translation>
-<translation id="5359637492792381994">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; à°ˆ సమయంలో దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ చెలà±à°²à°¦à±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791"><ph name="SITE" /> యొకà±à°• à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°°à°¦à±à°¦à± చేయబడినందà±à°¨ మీరౠదీనà±à°¨à°¿ సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°®à±‡, à°•à°¨à±à°• à°ˆ పేజీ తరà±à°µà°¾à°¤ పని చేయవచà±à°šà±.</translation>
<translation id="536296301121032821">విధాన సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à°¨à± నిలà±à°µ చేయడంలో విఫలమైంది</translation>
<translation id="5386426401304769735">à°ˆ సైటౠపà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ గొలà±à°¸à±à°²à±‹ SHA-1 ఉపయోగించి సంతకం చేసిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ ఉంది.</translation>
<translation id="5402410679244714488">à°—à°¡à±à°µà± à°®à±à°—à°¿à°‚à°ªà±: <ph name="EXPIRATION_DATE_ABBR" />, చివరిగా దాదాపౠసంవతà±à°¸à°°à°‚ à°•à±à°°à°¿à°¤à°‚ ఉపయోగించబడింది</translation>
+<translation id="540969355065856584">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ చెలà±à°²à°¦à±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడి చేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
<translation id="5421136146218899937">à°¬à±à°°à±Œà°œà°¿à°‚గౠడేటానౠకà±à°²à°¿à°¯à°°à± చెయà±à°¯à°¿...</translation>
<translation id="5430298929874300616">à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°¨à°¿ తీసివేయి</translation>
<translation id="5431657950005405462">మీ ఫైలౠకనà±à°—ొనబడలేదà±</translation>
-<translation id="5435775191620395718">à°ˆ పరికరం à°¨à±à°‚à°¡à°¿ à°šà°°à°¿à°¤à±à°°à°¨à± చూపà±à°¤à±‹à°‚ది. <ph name="BEGIN_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />"లో à°¸à±à°•à±€à°®à°¾ à°ªà±à°°à°¾à°®à°¾à°£à±€à°•à°°à°£ లోపం: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">à°ˆ <ph name="HOST_NAME" /> పేజీ à°•à°¨à±à°—ొనబడలేదà±</translation>
<translation id="5455374756549232013">చెలà±à°²à°¨à°¿ విధాన సమయమà±à°¦à±à°°</translation>
<translation id="5455790498993699893"><ph name="TOTAL_MATCHCOUNT" />లో <ph name="ACTIVE_MATCH" /></translation>
+<translation id="5457113250005438886">చెలà±à°²à°¦à±</translation>
<translation id="5470861586879999274">&amp;సవరించడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
<translation id="54817484435770891">చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à± జోడించండి</translation>
<translation id="5492298309214877701">కంపెనీ, సంసà±à°¥ లేదా పాఠశాల ఇంటà±à°°à°¾à°¨à±†à°Ÿà±â€Œà°²à±‹à°¨à°¿ à°ˆ సైటౠబాహà±à°¯ వెబà±â€Œà°¸à±ˆà°Ÿà± కలిగి ఉనà±à°¨ అదే URLని కలిగి ఉంది.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">à°ˆ à°šà°¿à°°à±à°¨à°¾à°®à°¾ à°¨à±à°‚à°¡à°¿ పికపౠచేసà±à°•à±‹à°µà°¡à°‚ సాధà±à°¯à°‚ కాదà±. వేరే à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à°¿ à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿.</translation>
<translation id="5572851009514199876">దయచేసి Chromeని à°ªà±à°°à°¾à°°à°‚à°­à°¿à°‚à°šà°¿, దానికి సైనౠఇనౠచేయండి, à°…à°ªà±à°ªà±à°¡à± మీకౠఈ సైటà±â€Œà°¨à± à°ªà±à°°à°¾à°ªà±à°¯à°¤ చేయడానికి à°…à°¨à±à°®à°¤à°¿ ఉందో లేదో Chrome తనిఖీ చేయగలదà±.</translation>
<translation id="5580958916614886209">మీ à°—à°¡à±à°µà± à°®à±à°—ింపౠనెలనౠతనిఖీ చేసి, ఆపై మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿</translation>
+<translation id="5586446728396275693">సేవౠచేయబడిన à°šà°¿à°°à±à°¨à°¾à°®à°¾à°²à± లేవà±</translation>
+<translation id="5595485650161345191">à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à± సవరించà±</translation>
<translation id="560412284261940334">నిరà±à°µà°¹à°£à°•à± మదà±à°¦à°¤à± లేదà±</translation>
<translation id="5610142619324316209">కనెకà±à°·à°¨à±â€Œà°¨à± తనిఖీ చేయడం</translation>
<translation id="5610807607761827392">మీరౠకారà±à°¡à±â€Œà°²à± మరియౠచిరà±à°¨à°¾à°®à°¾à°²à°¨à± <ph name="BEGIN_LINK" />సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²<ph name="END_LINK" />లో నిరà±à°µà°¹à°¿à°‚చగలరà±.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">మీరౠఈ సైటà±â€Œ à°¨à±à°‚à°¡à°¿ నిషà±à°•à±à°°à°®à°¿à°‚చాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
<translation id="5629630648637658800">విధాన సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à°¨à± లోడౠచేయడంలో విఫలమైంది</translation>
<translation id="5631439013527180824">చెలà±à°²à°¨à°¿ పరికర నిరà±à°µà°¹à°£ టోకెనà±</translation>
+<translation id="5633066919399395251"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />లో à°¹à±à°¯à°¾à°•à°°à±â€Œà°²à± మీ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, ఫోటోలà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠమరియౠకà±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) దొంగిలించగల లేదా తొలగించగల హానికరమైన à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± మీ à°•à°‚à°ªà±à°¯à±‚à°Ÿà°°à±â€Œà°²à±‹ ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">à°¸à±à°¥à°¾à°¨à°‚</translation>
+<translation id="5659593005791499971">ఇమెయిలà±</translation>
<translation id="5669703222995421982">à°µà±à°¯à°•à±à°¤à°¿à°—తీకరించిన కంటెంటà±â€Œà°¨à± పొందండి</translation>
<translation id="5675650730144413517">à°ˆ పేజీ పని చేయడం లేదà±</translation>
-<translation id="5677928146339483299">à°¬à±à°²à°¾à°•à± చెయà±à°¯à°¬à°¡à°¿à°‚ది</translation>
-<translation id="5694783966845939798">మీరౠ<ph name="DOMAIN" />à°•à°¿ కనెకà±à°Ÿà± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± బలహీనమైన సంతకం à°…à°²à±à°—ారిథమà±â€Œà°¨à± (SHA-1 వంటిది) ఉపయోగించి సంతకం చేసిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. దీని à°ªà±à°°à°•à°¾à°°à°‚, సరà±à°µà°°à± అందించిన à°­à°¦à±à°°à°¤à°¾ ఆధారాలౠనకిలీవి కావచà±à°šà± మరియౠసరà±à°µà°°à± మీరౠఊహించిన సరà±à°µà°°à± కాకపోవచà±à°šà± (మీరౠదాడి చేసే వారితో à°•à°®à±à°¯à±‚నికేటౠచేసà±à°¤à±à°‚డవచà±à°šà±). <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">à°ˆ వెబà±â€â€Œà°¸à±ˆà°Ÿà± యొకà±à°• à°—à±à°°à±à°¤à°¿à°‚పౠనిరà±à°¥à°¾à°°à°¿à°‚చబడలేదà±.</translation>
+<translation id="5713016350996637505">మోసపూరితమైన కంటెంటౠబà±à°²à°¾à°•à± చేయబడింది</translation>
<translation id="5720705177508910913">à°ªà±à°°à°¸à±à°¤à±à°¤ వినియోగదారà±</translation>
<translation id="5732392974455271431">మీ తలà±à°²à°¿à°¦à°‚à°¡à±à°°à±à°²à± దీనà±à°¨à°¿ మీ కోసం à°…à°¨à±â€Œà°¬à±à°²à°¾à°•à± చేయగలరà±</translation>
<translation id="5763042198335101085">చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ ఇమెయిలౠచిరà±à°¨à°¾à°®à°¾à°¨à°¿ నమోదౠచేయండి</translation>
<translation id="5765072501007116331">బటà±à°µà°¾à°¡à°¾ పదà±à°§à°¤à±à°²à± మరియౠఅవసరాలనౠచూడాలంటే, à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à°¿ à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿</translation>
+<translation id="5778550464785688721">MIDI పరికరాల పూరà±à°¤à°¿ నియంతà±à°°à°£</translation>
<translation id="5784606427469807560">మీ కారà±à°¡à±â€Œà°¨à± నిరà±à°§à°¾à°°à°¿à°‚చడంలో సమసà±à°¯ à°à°°à±à°ªà°¡à°¿à°‚ది. మీ ఇంటరà±à°¨à±†à°Ÿà± కనెకà±à°·à°¨à±â€Œà°¨à°¿ తనిఖీ చేసి, ఆపై మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="5785756445106461925">అలాగే, à°ˆ పేజీలో à°¸à±à°°à°•à±à°·à°¿à°¤à°‚ కాని ఇతర వనరà±à°²à± ఉనà±à°¨à°¾à°¯à°¿. à°ˆ వనరà±à°²à°¨à± బదిలీ చేసà±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± ఇతరà±à°²à± చూడగలరౠమరియౠదాడికి పాలà±à°ªà°¡à±‡à°µà°¾à°°à± పేజీ రూపానà±à°¨à°¿ మారà±à°šà±‡à°²à°¾ వీటిని సవరించగలరà±.</translation>
<translation id="5786044859038896871">మీరౠమీ కారà±à°¡à± సమాచారం పూరించాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;జోడించడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
<translation id="5814352347845180253">మీరౠ<ph name="SITE" /> మరియౠమరికొనà±à°¨à°¿ ఇతర సైటà±â€Œà°² à°¨à±à°‚à°¡à°¿ à°ªà±à°°à±€à°®à°¿à°¯à°‚ కంటెంటà±â€Œà°•à°¿ à°ªà±à°°à°¾à°ªà±à°¯à°¤à°¨à± కోలà±à°ªà±‹à°µà°šà±à°šà±.</translation>
<translation id="5838278095973806738">మీరౠఈ సైటà±â€Œà°²à±‹ ఎలాంటి గోపà±à°¯à°®à±ˆà°¨ సమాచారానà±à°¨à°¿ నమోదౠచేయకూడదౠ(ఉదాహరణకà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à± లేదా à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±), దాడికి పాలà±à°ªà°¡à±‡à°µà°¾à°°à± à°† సమాచారం దొంగిలించే అవకాశం ఉంటà±à°‚ది.</translation>
-<translation id="5843436854350372569">మీరౠ<ph name="DOMAIN" />కౠకనెకà±à°Ÿà± కావడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± బలహీన కీని కలిగి ఉనà±à°¨ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. దాడి చేసేవారౠపà±à°°à±ˆà°µà±‡à°Ÿà± కీని విచà±à°›à°¿à°¨à±à°¨à°‚ చేసారౠమరియౠసరà±à°µà°°à± మీరౠఊహించిన సరà±à°µà°°à± కాకపోవచà±à°šà± (మీరౠదాడి చేసే వారితో à°•à°®à±à°¯à±‚నికేటౠచేసà±à°¤à±à°‚డవచà±à°šà±). <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">à°ˆ సైటà±â€Œà°¨à± చేరà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¾à°®à±</translation>
<translation id="5869522115854928033">సేవౠచేసిన పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±</translation>
<translation id="5872918882028971132">తలà±à°²à°¿/తండà±à°°à°¿ సూచనలà±</translation>
<translation id="5901630391730855834">పసà±à°ªà±</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (సమకాలీకరించబడింది)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 వినియోగంలో ఉంది}other{# వినియోగంలో ఉనà±à°¨à°¾à°¯à°¿}}</translation>
<translation id="5926846154125914413">మీరౠకొనà±à°¨à°¿ సైటà±â€Œà°² à°¨à±à°‚à°¡à°¿ à°ªà±à°°à±€à°®à°¿à°¯à°‚ కంటెంటà±â€Œà°•à°¿ à°ªà±à°°à°¾à°ªà±à°¯à°¤à°¨à± కోలà±à°ªà±‹à°µà°šà±à°šà±.</translation>
<translation id="5959728338436674663">హానికరమైన à°…à°¨à±à°µà°°à±à°¤à°¨à°¾à°²à± మరియౠసైటà±â€Œà°²à°¨à± à°—à±à°°à±à°¤à°¿à°‚చడంలో సహాయపడటానికి కొంత <ph name="BEGIN_WHITEPAPER_LINK" />సిసà±à°Ÿà°®à± సమాచారానà±à°¨à°¿ మరియౠపేజీ కంటెంటà±<ph name="END_WHITEPAPER_LINK" />నౠGoogleà°•à± à°¸à±à°µà°¯à°‚చాలకంగా పంపà±à°¤à±à°‚ది. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">వారం</translation>
<translation id="5967867314010545767">à°šà°°à°¿à°¤à±à°° à°¨à±à°‚à°¡à°¿ తీసివేయి</translation>
<translation id="5975083100439434680">దూరంగా జూమౠచెయà±à°¯à°¿</translation>
<translation id="598637245381783098">చెలà±à°²à°¿à°‚పౠఆపà±â€Œà°¨à°¿ తెరవడం సాధà±à°¯à°‚ కాదà±</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{పేజీ 1}other{పేజీ #}}</translation>
<translation id="6017514345406065928">ఆకà±à°ªà°šà±à°š</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />లోని à°¹à±à°¯à°¾à°•à°°à±â€Œà°²à± మోసపూరిత యాపà±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయవచà±à°šà±, ఇవి వేరే వాటిలా కనిపించవచà±à°šà± లేదా మిమà±à°®à°²à±à°¨à°¿ à°Ÿà±à°°à°¾à°•à± చేయడానికి ఉపయోగించబడే డేటాని సేకరించవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (సమకాలీకరించబడà±à°¡à°¾à°¯à°¿)</translation>
<translation id="6027201098523975773">పేరà±à°¨à°¿ నమోదౠచేయండి</translation>
<translation id="6040143037577758943">మూసివేయి</translation>
<translation id="6042308850641462728">మరింత</translation>
+<translation id="6047233362582046994">మీ à°­à°¦à±à°°à°¤à°•à± వాటిలà±à°²à±‡ ఆపదల à°—à±à°°à°¿à°‚à°šà°¿ మీకౠఅరà±à°¥à°‚ à°…à°¯à±à°¯à°¿ ఉంటే, హానికర యాపà±â€Œà°²à± తీసివేయబడటానికి à°®à±à°‚దే మీరౠ<ph name="BEGIN_LINK" />à°ˆ సైటà±â€Œà°¨à± సందరà±à°¶à°¿à°‚చవచà±à°šà±<ph name="END_LINK" />.</translation>
+<translation id="6051221802930200923">à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ పినౠచేసే పదà±à°§à°¤à°¿à°¨à°¿ వెబà±â€Œà°¸à±ˆà°Ÿà± ఉపయోగిసà±à°¤à±à°‚ది à°•à°¨à±à°• మీరౠపà±à°°à°¸à±à°¤à±à°¤à°¾à°¨à°¿à°•à°¿ <ph name="SITE" />ని సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°®à±‡, à°•à°¨à±à°• à°ˆ పేజీ తరà±à°µà°¾à°¤ పని చేయవచà±à°šà±.</translation>
<translation id="6060685159320643512">జాగà±à°°à°¤à±à°¤, à°ˆ à°ªà±à°°à°¯à±‹à°—ాలౠవిఫలం కావచà±à°šà±</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{à°à°¦à±€ లేదà±}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">మీరౠనిరà±à°µà°¾à°¹à°•à±à°¨à°¿ à°¦à±à°µà°¾à°°à°¾ అందించబడిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ ఉపయోగించి కంటెంటà±â€Œà°¨à± à°ªà±à°°à°¾à°ªà±à°¯à°¤ చేసారà±. మీరౠ<ph name="DOMAIN" />కౠఅందించే డేటాకౠమీ నిరà±à°µà°¾à°¹à°•à±à°¨à°¿ à°¦à±à°µà°¾à°°à°¾ అంతరాయం à°à°°à±à°ªà°¡à°µà°šà±à°šà±.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{à°à°®à±€ లేవà±}=1{1 పాసà±â€Œà°µà°°à±à°¡à± (సమకాలీకరించబడింది)}other{# పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à± (సమకాలీకరించబడà±à°¡à°¾à°¯à°¿)}}</translation>
<translation id="6146055958333702838">à°à°µà±ˆà°¨à°¾ కేబà±à°²à±â€Œà°²à°¨à± తనిఖీ చేయండి మరియౠమీరౠఉపయోగించే à°à°µà±ˆà°¨à°¾ రూటరà±â€Œà°²à±, మోడెమà±â€Œà°²à±
లేదా ఇతర నెటà±â€Œà°µà°°à±à°•à± పరికరాలనౠరీబూటౠచేయండి.</translation>
<translation id="614940544461990577">ఇలా చేసి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿:</translation>
<translation id="6151417162996330722">సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ చెలà±à°²à±à°¬à°¾à°Ÿà± à°µà±à°¯à°µà°§à°¿ చాలా à°Žà°•à±à°•à±à°µ కాలం ఉంది.</translation>
<translation id="6157877588268064908">రవాణా పదà±à°§à°¤à±à°²à± మరియౠఅవసరాలనౠచూడాలంటే, à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à°¿ à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿</translation>
+<translation id="6158003235852588289">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో à°«à°¿à°·à°¿à°‚à°—à±â€Œà°¨à°¿ à°—à±à°°à±à°¤à°¿à°‚చింది. ఫిషింగౠసైటà±â€Œà°²à± వేరే వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°² వలె à°ªà±à°°à°µà°°à±à°¤à°¿à°‚à°šà°¡à°‚ à°¦à±à°µà°¾à°°à°¾ మిమà±à°®à°²à±à°¨à°¿ మాయ చేయవచà±à°šà±.</translation>
<translation id="6165508094623778733">మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿</translation>
+<translation id="6169916984152623906">‌ఇపà±à°ªà±à°¡à± మీరౠవà±à°¯à°•à±à°¤à°¿à°—తంగా à°¬à±à°°à±Œà°œà± చేయవచà±à°šà± మరియౠఈ పరికరానà±à°¨à°¿ ఉపయోగించే ఇతర à°µà±à°¯à°•à±à°¤à±à°²à°•à± మీ కారà±à°¯à°¾à°šà°°à°£ కనిపించదà±. అయినపà±à°ªà°Ÿà°¿à°•à±€, డౌనà±â€Œà°²à±‹à°¡à±â€Œà°²à± మరియౠబà±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à± సేవౠచేయబడతాయి.</translation>
<translation id="6177128806592000436">à°ˆ సైటà±â€Œà°•à°¿ మీ కనెకà±à°·à°¨à± à°¸à±à°°à°•à±à°·à°¿à°¤à°‚à°—à°¾ లేదà±</translation>
<translation id="6184817833369986695">(బృందం: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">మీ ఇంటరà±à°¨à±†à°Ÿà± కనెకà±à°·à°¨à±â€Œà°¨à± తనిఖీ చేయండి</translation>
<translation id="6218753634732582820">Chromium à°¨à±à°‚à°¡à°¿ à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à± తీసివేయాలా?</translation>
+<translation id="6221345481584921695">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="BEGIN_LINK" />లో <ph name="END_LINK" />మాలà±à°µà±‡à°°à± à°—à±à°°à±à°¤à°¿à°‚చింది<ph name="SITE" />. సాధారణంగా à°¸à±à°°à°•à±à°·à°¿à°¤à°®à±ˆà°¨ వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œâ€Œà°²à°•à± కూడా కొనà±à°¨à°¿à°¸à°¾à°°à±à°²à± మాలà±à°µà±‡à°°à± సోకà±à°¤à±à°‚ది. ఇటà±à°µà°‚à°Ÿà°¿ హానికరమైన కంటెంటౠమాలà±à°µà±‡à°°à± పంపిణీదారà±à°—à°¾ à°ªà±à°°à°¸à°¿à°¦à±à°§à°¿à°—ాంచిన <ph name="SUBRESOURCE_HOST" /> à°¨à±à°‚à°¡à°¿ సంకà±à°°à°®à°¿à°¸à±à°¤à±à°‚ది.</translation>
<translation id="6251924700383757765">గోపà±à°¯à°¤à°¾ విధానం</translation>
<translation id="6254436959401408446">à°ˆ పేజీని తెరవడానికి తగినంత మెమరీ లేదà±</translation>
<translation id="625755898061068298">మీరౠఈ సైటà±â€Œà°•à± à°­à°¦à±à°°à°¤à°¾ హెచà±à°šà°°à°¿à°•à°²à°¨à± నిలిపివేయాలని à°Žà°‚à°šà±à°•à±à°¨à±à°¨à°¾à°°à±.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°¨à± సవరించà±</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> à°—à°¡à±à°µà± à°®à±à°—ింపౠతేదీ మరియౠCVCని నమోదౠచేయండి</translation>
<translation id="6414888972213066896">మీరౠఈ సైటà±â€Œà°¨à°¿ సందరà±à°¶à°¿à°‚చడానికి à°…à°¨à±à°®à°¤à°¿à°‚చమని కోరà±à°¤à±‚ మీ తలà±à°²à°¿/తండà±à°°à°¿à°•à°¿ à°…à°­à±à°¯à°°à±à°¥à°¨ పంపారà±</translation>
-<translation id="6416403317709441254"><ph name="SITE" /> Chromium à°ªà±à°°à°¾à°¸à±†à°¸à± చేయలేని రీతిలో గజిబిజిగా ఉండే ఆధారాలనౠపంపినందà±à°¨ మీరౠపà±à°°à°¸à±à°¤à±à°¤à°‚ à°† వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°¨à°¿ సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°‚గానే ఉంటాయి, కావà±à°¨ à°ˆ పేజీ కాసేపటి తరà±à°µà°¾à°¤ పని చేసే అవకాశం ఉంది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°°à°¦à±à°¦à± చెయà±à°¯à°¬à°¡à°¿à°‚దా అని తనిఖీ చెయà±à°¯à°¡à°‚ సాధà±à°¯à°‚ కాలేదà±.</translation>
<translation id="6433490469411711332">సంపà±à°°à°¦à°¿à°‚పౠసమాచారానà±à°¨à°¿ సవరించండి</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> కనెకà±à°Ÿà± కావడానికి నిరాకరించింది.</translation>
<translation id="6446608382365791566">మరింత సమాచారానà±à°¨à°¿ జోడించండి</translation>
+<translation id="6447842834002726250">à°•à±à°•à±à°•à±€à°²à±</translation>
<translation id="6451458296329894277">ఫారమౠపà±à°¨à°ƒà°¸à°®à°°à±à°ªà°£à°¨à± నిరà±à°¥à°¾à°°à°¿à°‚à°šà°‚à°¡à°¿</translation>
<translation id="6456339708790392414">మీ చెలà±à°²à°¿à°‚à°ªà±</translation>
<translation id="6458467102616083041">విధానంచే డిపాలà±à°Ÿà± శోధన ఆపివేయబడినందà±à°¨ విసà±à°®à°°à°¿à°‚చబడింది.</translation>
-<translation id="6462969404041126431">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ ఉపసంహరించబడింది. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">పరికర విధానాలà±</translation>
<translation id="6477321094435799029">Chrome à°ˆ పేజీలో అసాధారణ కోడà±â€Œà°¨à± à°—à±à°°à±à°¤à°¿à°‚చింది మరియౠమీ à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ సమాచారం (ఉదాహరణకà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, ఫోనౠనంబరà±â€Œà°²à± మరియౠకà±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) à°°à°•à±à°·à°¿à°‚చడానికి దానà±à°¨à°¿ à°¬à±à°²à°¾à°•à± చేసింది.</translation>
<translation id="6489534406876378309">à°•à±à°°à°¾à°·à±â€Œà°²à°¨à± à°…à°ªà±â€Œà°²à±‹à°¡à± చేయడానà±à°¨à°¿ à°ªà±à°°à°¾à°°à°‚à°­à°¿à°‚à°šà°‚à°¡à°¿</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">à°—à°¡à±à°µà± à°®à±à°—à°¿à°‚à°ªà±: <ph name="EXPIRATION_DATE_ABBR" />, చివరిగా ఉపయోగించినది <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">మీ నిరà±à°µà°¾à°¹à°•à±à°¡à± దీనà±à°¨à°¿ ఇంకా ఆమోదించలేదà±</translation>
<translation id="6569060085658103619">మీరౠపొడిగింపౠపేజీని వీకà±à°·à°¿à°¸à±à°¤à±à°¨à±à°¨à°¾à°°à±</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" /> కంటే తకà±à°•à±à°µ</translation>
+<translation id="657639383826808334">à°ˆ కంటెంటౠమీ సమాచారానà±à°¨à°¿ దొంగిలించగల లేదా తొలగించగల హానికరమైన సాఫà±à°Ÿà±â€Œà°µà±‡à°°à±â€Œà°¨à°¿ మీ పరికరంలో ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°¿ ఉండవచà±à°šà±. <ph name="BEGIN_LINK" />à°à°¦à±‡à°®à±ˆà°¨à°¾ చూపà±<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">à°—à±à°ªà±à°¤à±€à°•à°°à°£ ఎంపికలà±</translation>
<translation id="662080504995468778">ఇందà±à°²à±‹à°¨à±‡ ఉంచà±</translation>
<translation id="6626291197371920147">చెలà±à°²à±à°¬à°¾à°Ÿà°¯à±à°¯à±‡ కారà±à°¡à± నంబరà±â€Œà°¨à± జోడించండి</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> శోధన</translation>
+<translation id="6630809736994426279"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />లో à°¹à±à°¯à°¾à°•à°°à±â€Œà°²à± మీ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, ఫోటోలà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠమరియౠకà±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) దొంగిలించగల లేదా తొలగించగల హానికరమైన à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± మీ Macలో ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">à°ˆ విధానం విలà±à°µ తగà±à°—ించబడింది.</translation>
-<translation id="6652240803263749613">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ మీ à°•à°‚à°ªà±à°¯à±‚టరౠఆపరేటింగౠసిసà±à°Ÿà°®à± విశà±à°µà°¸à°¿à°‚చలేదà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Chromium à°¨à±à°‚à°¡à°¿ ఫారమౠసూచననౠతీసివేయాలా?</translation>
<translation id="6685834062052613830">సైనౠఅవà±à°Ÿà± చేసి, సెటపà±â€Œà°¨à± పూరà±à°¤à°¿ చేయండి</translation>
<translation id="6710213216561001401">à°®à±à°¨à±à°ªà°Ÿà°¿</translation>
<translation id="6710594484020273272">&lt;శోధన పదానà±à°¨à°¿ టైపౠచేయండి&gt;</translation>
<translation id="6711464428925977395">à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à±â€Œà°²à±‹ à°à°¦à±‹ తపà±à°ªà± ఉంది లేదా à°šà°¿à°°à±à°¨à°¾à°®à°¾ సరైనది కాదà±.</translation>
<translation id="6727102863431372879">సెటౠచెయà±à°¯à°¿</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{à°à°¦à±€ లేదà±}=1{1 అంశం}other{# అంశాలà±}}</translation>
<translation id="674375294223700098">తెలియని సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ లోపం.</translation>
<translation id="6753269504797312559">విధానం విలà±à°µ</translation>
<translation id="6757797048963528358">మీ పరికరం నిదà±à°°à°¾à°µà°¸à±à°¥à°•à°¿ వెళà±à°²à°¿à°‚ది.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">à°…à°¨à±à°•à±‚లీకరణ ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">à°ªà±à°°à°¾à°‚తాల డేటానౠలోడౠచేయడం విఫలమైంది</translation>
+<translation id="6825578344716086703"><ph name="DOMAIN" />నౠచేరà±à°•à±‹à°µà°¡à°¾à°¨à°¿à°•à°¿ మీరౠపà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± (SHA-1 వంటి) బలహీనమైన సంతకం à°…à°²à±à°—ారిథమà±â€Œà°¨à± ఉపయోగించి సంతకం చేసిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. అంటే సరà±à°µà°°à± అందించిన à°­à°¦à±à°°à°¤ ఆధారాలౠనకిలీ కావచà±à°šà± మరియౠసరà±à°µà°°à± మీరౠఊహించిన సరà±à°µà°°à± కాకపోవచà±à°šà± (మీరౠహà±à°¯à°¾à°•à°°à±â€Œà°¤à±‹ పరసà±à°ªà°° à°šà°°à±à°¯ చేసà±à°¤à±à°‚డవచà±à°šà±).</translation>
+<translation id="6830728435402077660">à°¸à±à°°à°•à±à°·à°¿à°¤à°‚ కాదà±</translation>
<translation id="6831043979455480757">à°…à°¨à±à°µà°¦à°¿à°‚à°šà±</translation>
<translation id="6839929833149231406">à°ªà±à°°à°¾à°‚తం</translation>
<translation id="6874604403660855544">&amp;జోడించడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">మీ కారà±à°¡à± నిరà±à°§à°¾à°°à°¿à°‚చబడింది</translation>
<translation id="6897140037006041989">వినియోగదారౠపà±à°°à°¤à°¿à°¨à°¿à°§à°¿</translation>
<translation id="6915804003454593391">వినియోగదారà±:</translation>
+<translation id="6945221475159498467">à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿</translation>
<translation id="6948701128805548767">పికపౠపదà±à°§à°¤à±à°²à± మరియౠఅవసరాలనౠచూడాలంటే, à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à°¿ à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿</translation>
<translation id="6957887021205513506">సరà±à°µà°°à± ధృవీకరణ పతà±à°°à°‚ చెలà±à°²à°¦à±.</translation>
<translation id="6965382102122355670">సరే</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">రెండౠసà±à°¥à°¿à°° à°ªà±à°°à°¾à°•à±à°¸à±€ సరà±à°µà°°à±à°²à± మరియౠఒక .pac à°¸à±à°•à±à°°à°¿à°ªà±à°Ÿà± URL పేరà±à°•à±Šà°¨à°¬à°¡à±à°¡à°¾à°¯à°¿.</translation>
<translation id="6989763994942163495">à°…à°§à±à°¨à°¾à°¤à°¨ సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à°¨à± చూపించà±...</translation>
<translation id="7000990526846637657">à°šà°°à°¿à°¤à±à°° నమోదà±à°²à± à°à°µà±€ à°•à°¨à±à°—ొనబడలేదà±</translation>
-<translation id="7009986207543992532">మీరౠ<ph name="DOMAIN" />à°•à°¿ కనెకà±à°Ÿà± కావడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± అందించిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°—à°¡à±à°µà± కాలం విశà±à°µà°¸à°¿à°‚చలేనంత à°Žà°•à±à°•à±à°µ à°µà±à°¯à°µà°§à°¿ ఉంది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">చైనా యూనియనౠపే</translation>
<translation id="7012372675181957985">మీ Google ఖాతా <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" />లో ఇతర à°¬à±à°°à±Œà°œà°¿à°‚à°—à± à°šà°°à°¿à°¤à±à°° రూపాలౠఉండవచà±à°šà±.</translation>
<translation id="7029809446516969842">పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±</translation>
+<translation id="7050187094878475250">మీరౠ<ph name="DOMAIN" />ని చేరà±à°•à±‹à°µà°¡à°¾à°¨à°¿à°•à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± అందించిన à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ విశà±à°µà°¸à°¿à°‚చలేనంత à°Žà°•à±à°•à±à°µ చెలà±à°²à±à°¬à°¾à°Ÿà± à°µà±à°¯à°µà°§à°¿à°¨à°¿ కలిగి ఉంది.</translation>
+<translation id="7053983685419859001">నిరోధించà±</translation>
<translation id="7064851114919012435">సంపà±à°°à°¦à°¿à°‚పౠసమాచారం</translation>
<translation id="7079718277001814089">à°ˆ సైటౠమాలà±à°µà±‡à°°à±â€Œà°¨à°¿ కలిగి ఉంది</translation>
<translation id="7087282848513945231">కౌంటి</translation>
-<translation id="7088615885725309056">పాతవి</translation>
<translation id="7090678807593890770"><ph name="LINK" /> కోసం Googleలో శోధించండి</translation>
+<translation id="7108819624672055576">పొడిగింపౠదà±à°µà°¾à°°à°¾ à°…à°¨à±à°®à°¤à°¿à°‚చబడింది</translation>
<translation id="7119414471315195487">ఇతర à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à± లేదా à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± మూసివేయండి</translation>
<translation id="7129409597930077180">à°ˆ à°šà°¿à°°à±à°¨à°¾à°®à°¾à°•à± రవాణా చేయడం సాధà±à°¯à°‚ కాదà±. వేరే à°šà°¿à°°à±à°¨à°¾à°®à°¾à°¨à°¿ à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿.</translation>
<translation id="7138472120740807366">బటà±à°µà°¾à°¡à°¾ పదà±à°§à°¤à°¿</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">à°ªà±à°°à°¾à°¸à±†à°¸à± చేసà±à°¤à±‹à°‚ది</translation>
<translation id="724691107663265825">సైటౠమà±à°¨à±à°®à±à°‚దౠమాలà±à°µà±‡à°°à± కలిగి ఉంది</translation>
<translation id="724975217298816891">మీ కారà±à°¡à± వివరాలనౠనవీకరించడానికి <ph name="CREDIT_CARD" /> కారà±à°¡à± à°—à°¡à±à°µà± à°®à±à°—ింపౠతేదీ మరియౠCVCని నమోదౠచేయండి. మీరౠనిరà±à°§à°¾à°°à°¿à°‚à°šà°¿à°¨ తరà±à°µà°¾à°¤, మీ కారà±à°¡à± వివరాలౠఈ సైటà±â€Œà°¤à±‹ భాగసà±à°µà°¾à°®à±à°¯à°‚ చేయబడతాయి.</translation>
-<translation id="725866823122871198">మీ à°•à°‚à°ªà±à°¯à±‚టరౠతేదీ మరియౠసమయం (<ph name="DATE_AND_TIME" />) తపà±à°ªà±à°—à°¾ ఉనà±à°¨à°‚à°¦à±à°¨ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />à°•à°¿ à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కనెకà±à°·à°¨à± à°à°°à±à°ªà°¾à°Ÿà± చేయబడదà±.</translation>
+<translation id="7260504762447901703">à°ªà±à°°à°¾à°ªà±à°¯à°¤à°¨à± ఉపసంహరించà±</translation>
<translation id="7275334191706090484">నిరà±à°µà°¹à°¿à°‚చబడిన à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à±</translation>
<translation id="7298195798382681320">సిఫారà±à°¸à± చేయబడినవి</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> తేదీన సంగà±à°°à°¹à°¿à°‚à°šà°¿à°¨ à°•à±à°°à°¾à°·à± నివేదిక (à°…à°ªà±â€Œà°²à±‹à°¡à± చేయాలà±à°¸à°¿à°‚దిగా వినియోగదారà±à°•à± à°…à°­à±à°¯à°°à±à°¥à°¨, ఇంకా à°…à°ªà±â€Œà°²à±‹à°¡à± చేయలేదà±)</translation>
<translation id="7334320624316649418">&amp;మళà±à°²à±€ à°•à±à°°à°®à°‚ చేయడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
<translation id="733923710415886693">సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ పారదరà±à°¶à°•à°¤ à°¦à±à°µà°¾à°°à°¾ బహిరంగపరచలేదà±.</translation>
-<translation id="7351800657706554155"><ph name="SITE" /> à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ ఉపసంహరించబడినందà±à°¨ మీరౠఆ సైటà±â€Œà°¨à± ఇపà±à°ªà±à°¡à± సందరà±à°¶à°¿à°‚చలేరà±. నెటà±â€Œà°µà°°à±à°•à± లోపాలౠమరియౠదాడà±à°²à± సాధారణంగా తాతà±à°•à°¾à°²à°¿à°•à°‚గానే ఉంటాయి, à°•à°¨à±à°• à°ˆ పేజీ కాసేపటి తరà±à°µà°¾à°¤ పని చేసే అవకాశం ఉంది. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">ఆదేశ పంకà±à°¤à°¿</translation>
<translation id="7372973238305370288">శోధన ఫలితం</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">వదà±à°¦à±</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">కారà±à°¡à±â€Œà°¨à°¿ నిరà±à°§à°¾à°°à°¿à°‚à°šà°‚à°¡à°¿</translation>
-<translation id="7394102162464064926">మీరౠఈ పేజీలనౠఖచà±à°šà°¿à°¤à°‚à°—à°¾ మీ à°šà°°à°¿à°¤à±à°° à°¨à±à°‚à°¡à°¿ తొలగించాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?
-
-à°…à°œà±à°žà°¾à°¤ మోడౠ<ph name="SHORTCUT_KEY" /> తదà±à°ªà°°à°¿à°¸à°¾à°°à°¿ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹à°•à°¿ రావచà±à°šà±.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">à°ªà±à°°à±Šà°«à±ˆà°²à± మారà±à°—à°‚</translation>
<translation id="7424977062513257142">à°ˆ వెబà±â€Œà°ªà±‡à°œà±€à°²à±‹à°¨à°¿ పొందà±à°ªà°°à°¿à°šà°¿à°¨ పేజీ ఇలా చెబà±à°¤à±‹à°‚ది:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">à°ˆ సైటౠబà±à°²à°¾à°•à± చేయబడింది</translation>
<translation id="7445762425076701745">మీరౠకనెకà±à°Ÿà± చేసిన సరà±à°µà°°à± యొకà±à°• à°—à±à°°à±à°¤à°¿à°‚పౠపూరà±à°¤à°¿à°—à°¾ ధృవీకరించబడలేదà±. మీరౠదీని యొకà±à°• యాజమానà±à°¯à°¾à°¨à±à°¨à°¿ ధృవీకరించడానికి అంతరà±à°—à°¤ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ అధికారికి మరొక దాని లేని మీ నెటà±â€Œà°µà°°à±à°•à±â€Œà°²à±‹ మాతà±à°°à°®à±‡ చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ పేరà±à°¨à± ఉపయోగించి సరà±à°µà°°à±â€Œà°•à°¿ కనెకà±à°Ÿà± చేసారà±. కొనà±à°¨à°¿ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ అధికారà±à°²à± సంబంధంలేని à°ˆ పేరà±à°²à°•à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ జారీ చేసà±à°¤à°¾à°°à±, మీరౠసరైన వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°•à°¿ మరియౠఅటాకరà±â€Œà°•à°¿ కనెకà±à°Ÿà± చేసారా అని నిరà±à°§à°¾à°°à°¿à°‚చడానికి వేరే మారà±à°—à°‚ లేదà±.</translation>
<translation id="7451311239929941790">à°ˆ సమసà±à°¯ à°—à±à°°à°¿à°‚à°šà°¿ <ph name="BEGIN_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LINK" />.</translation>
+<translation id="7455133967321480974">సారà±à°µà°œà°¨à±€à°¨ డిఫాలà±à°Ÿà±â€Œà°¨à± ఉపయోగించౠ(à°¬à±à°²à°¾à°•à± చేయి)</translation>
<translation id="7460163899615895653">ఇతర పరికరాలà±à°²à±‹ మీ ఇటీవలి à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à± ఇకà±à°•à°¡ కనిపిసà±à°¤à°¾à°¯à°¿</translation>
<translation id="7469372306589899959">కారà±à°¡à±â€Œà°¨à°¿ నిరà±à°§à°¾à°°à°¿à°¸à±à°¤à±‹à°‚ది</translation>
<translation id="7481312909269577407">ఫారà±à°µà°¾à°°à±à°¡à±</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">అందించబడిన విధాన పరికర id ఖాళీగా ఉంది లేదా à°ªà±à°°à°¸à±à°¤à±à°¤ పరికర idà°•à°¿ సరిపోలలేదà±</translation>
<translation id="7514365320538308">డౌనà±â€Œà°²à±‹à°¡à± చేయి</translation>
<translation id="7518003948725431193">వెబౠచిరà±à°¨à°¾à°®à°¾à°•à± వెబà±â€Œà°ªà±‡à°œà±€ à°•à°¨à±à°—ొనబడలేదà±: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">విలà±à°µ</translation>
<translation id="7537536606612762813">తపà±à°ªà°¨à°¿à°¸à°°à°¿</translation>
+<translation id="7542403920425041731">మీరౠనిరà±à°§à°¾à°°à°¿à°‚à°šà°¿à°¨ తరà±à°µà°¾à°¤, మీ కారà±à°¡à± వివరాలౠఈ సైటà±â€Œà°¤à±‹ షేరౠచేయబడతాయి.</translation>
<translation id="7542995811387359312">à°ˆ ఫారమౠసà±à°°à°•à±à°·à°¿à°¤ కనెకà±à°·à°¨à±â€Œà°¨à°¿ ఉపయోగించనందà±à°¨ à°¸à±à°µà°¯à°‚చాలకంగా à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à± పూరà±à°¤à°¿ చెయà±à°¯à°¡à°‚ ఆపివేయబడింది.</translation>
<translation id="7543525346216957623">మీ తలà±à°²à°¿/తండà±à°°à°¿à°¨à°¿ à°…à°¡à°—à°‚à°¡à°¿</translation>
<translation id="7549584377607005141">à°ˆ వెబà±â€Œà°ªà±‡à°œà±€ సరిగà±à°—à°¾ à°ªà±à°°à°¦à°°à±à°¶à°¿à°‚చబడటానికి మీరౠమà±à°¨à±à°ªà± నమోదౠచేసిన డేటా అవసరం. మీరౠఈ డేటానౠమళà±à°²à±€ పంపవచà±à°šà±, కానీ అలా చేయడం వలన à°ˆ పేజీ à°®à±à°¨à±à°ªà± à°ªà±à°°à°¦à°°à±à°¶à°¿à°‚à°šà°¿à°¨ à°à°¦à±ˆà°¨à°¾ à°šà°°à±à°¯ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ కావచà±à°šà±.</translation>
<translation id="7552846755917812628">à°•à±à°°à°¿à°‚ది à°šà°¿à°Ÿà±à°•à°¾à°²à°¨à± à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿:</translation>
<translation id="7554791636758816595">కొతà±à°¤ à°Ÿà±à°¯à°¾à°¬à±</translation>
+<translation id="7567204685887185387">à°ˆ సరà±à°µà°°à± <ph name="DOMAIN" /> అని నిరూపించà±à°•à±‹à°²à±‡à°•à°ªà±‹à°¯à°¿à°‚ది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ మోసపూరితంగా జారీ à°…à°¯à±à°¯à°¿ ఉండవచà±à°šà±. ఇది తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన జరిగి ఉండవచà±à°šà±.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">à°ˆ పేజీ<ph name="ORIGINAL_LANGUAGE" />లో ఉంది మీరౠదీనà±à°¨à°¿ à°…à°¨à±à°µà°¦à°¿à°‚చాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
<translation id="7569952961197462199">Chrome à°¨à±à°‚à°¡à°¿ à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°¨à± తీసివేయాలా?</translation>
<translation id="7569983096843329377">నలà±à°ªà±</translation>
<translation id="7578104083680115302">మీరౠGoogleతో సేవౠచేసిన కారà±à°¡à±â€Œà°²à°¨à± ఉపయోగించి పరికరాలà±à°²à±‹à°¨à°¿ సైటà±â€Œà°²à± మరియౠఅనà±à°µà°°à±à°¤à°¨à°¾à°²à±à°²à±‹ శీఘà±à°°à°‚à°—à°¾ చెలà±à°²à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="7588950540487816470">భౌతిక వెబà±</translation>
<translation id="7592362899630581445">సరà±à°µà°°à± యొకà±à°• à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ పేరౠపరిమితà±à°²à°¨à± ఉలà±à°²à°‚ఘిసà±à°¤à±‹à°‚ది.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> కంటే తకà±à°•à±à°µ</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ à°ˆ à°…à°­à±à°¯à°°à±à°¥à°¨à°¨à± నిరà±à°µà°¹à°¿à°‚చలేదà±.</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" />నౠఎపà±à°ªà°Ÿà°¿à°•à±€ à°…à°¨à±à°µà°¦à°¿à°‚చవదà±à°¦à±</translation>
<translation id="7610193165460212391">విలà±à°µ <ph name="VALUE" /> పరిధి వెలà±à°ªà°² ఉంది.</translation>
<translation id="7613889955535752492">à°—à°¡à±à°µà± à°®à±à°—à°¿à°‚à°ªà±: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">మీకౠఇపà±à°ªà°Ÿà°¿à°•à±‡ మీ Google ఖాతా పాసà±â€Œà°µà°°à±à°¡à± యొకà±à°• మరొక సంసà±à°•à°°à°£à°¨à± ఉపయోగించి à°Žà°¨à±â€Œà°•à±à°°à°¿à°ªà±à°Ÿà± అయిన డేటా ఉంది. దయచేసి దానà±à°¨à°¿ దిగà±à°µ నమోదౠచేయండి.</translation>
-<translation id="7634554953375732414">à°ˆ సైటà±â€Œà°•à°¿ మీ కనెకà±à°·à°¨à± à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కాదà±.</translation>
<translation id="7637571805876720304">Chromium à°¨à±à°‚à°¡à°¿ à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°¨à± తీసివేయాలా?</translation>
<translation id="765676359832457558">à°…à°§à±à°¨à°¾à°¤à°¨ సెటà±à°Ÿà°¿à°‚à°—à±â€Œà°²à°¨à± దాచà±...</translation>
<translation id="7658239707568436148">à°°à°¦à±à°¦à± చెయà±à°¯à°¿</translation>
+<translation id="7662298039739062396">పొడిగింపౠదà±à°µà°¾à°°à°¾ సెటà±à°Ÿà°¿à°‚గౠనియంతà±à°°à°¿à°‚చబడà±à°¤à±‹à°‚ది</translation>
<translation id="7667346355482952095">అందించిన విధాన టోకెనౠఖాళీగా ఉంది లేదా à°ªà±à°°à°¸à±à°¤à±à°¤ టోకెనà±â€Œà°¤à±‹ సరిపోలలేదà±</translation>
<translation id="7668654391829183341">తెలియని పరికరం</translation>
<translation id="7669271284792375604">à°ˆ సైటà±â€Œà°²à±‹à°¨à°¿ దాడి చేసేవారౠమీ à°¬à±à°°à±Œà°œà°¿à°‚à°—à± à°…à°¨à±à°­à°µà°¾à°¨à°¿à°•à°¿ (ఉదాహరణకà±, మీ హోమౠపేజీని మారà±à°šà°¡à°‚ లేదా మీరౠసందరà±à°¶à°¿à°‚చే సైటà±â€Œà°²à±à°²à±‹ అదనపౠపà±à°°à°•à°Ÿà°¨à°²à°¨à± చూపడం à°¦à±à°µà°¾à°°à°¾) హాని కలిగించే à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేసే విధంగా మిమà±à°®à°²à±à°¨à°¿ మోసగించడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చవచà±à°šà±.</translation>
<translation id="7674629440242451245">à°…à°¦à±à°­à±à°¤à°®à±ˆà°¨ à°•à±à°°à±Šà°¤à±à°¤ Chrome లకà±à°·à°£à°¾à°² పటà±à°² ఆసకà±à°¤à°¿à°—à°¾ ఉనà±à°¨à°¾à°°à°¾? chrome.com/devలో మా డెవలపరౠఛానెలà±â€Œà°¨à± à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="7682287625158474539">ఓడ రవాణా</translation>
+<translation id="7701040980221191251">à°à°¦à±€ కాదà±</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" />à°•à°¿ కొనసాగించండి (à°…à°¸à±à°°à°•à±à°·à°¿à°¤à°‚)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">సరà±à°Ÿà°¿à°«à°¿à°•à±†à°Ÿà±</translation>
+<translation id="7716147886133743102">మీ నిరà±à°µà°¾à°¹à°•à±à°² à°¦à±à°µà°¾à°°à°¾ à°¬à±à°²à°¾à°•à± చేయబడింది</translation>
<translation id="7716424297397655342">కాషౠనà±à°‚à°¡à°¿ à°ˆ సైటà±â€Œà°¨à± లోడౠచేయలేకపోయామà±</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">నిరà±à°µà°¹à°¿à°‚à°šà°¡à°‚ లేదà±</translation>
<translation id="7755287808199759310">మీ తలà±à°²à°¿/తండà±à°°à°¿ దీనà±à°¨à°¿ మీ కోసం à°…à°¨à±â€Œà°¬à±à°²à°¾à°•à± చేయగలరà±</translation>
<translation id="7758069387465995638">ఫైరà±â€Œà°µà°¾à°²à± లేదా యాంటీవైరసౠసాఫà±à°Ÿà±â€Œà°µà±‡à°°à± కనెకà±à°·à°¨à±â€Œà°¨à± à°¬à±à°²à°¾à°•à± చేసి ఉండవచà±à°šà±.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32-బిటà±)</translation>
<translation id="7956713633345437162">మొబైలౠబà±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à±</translation>
<translation id="7961015016161918242">à°Žà°ªà±à°ªà±à°¡à±‚ లేదà±</translation>
-<translation id="7962083544045318153">à°•à±à°°à°¾à°·à± ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">à°Žà°²à±à°²à°ªà±à°ªà±à°¡à±‚ <ph name="ORIGINAL_LANGUAGE" />నౠ<ph name="TARGET_LANGUAGE" />à°•à± à°…à°¨à±à°µà°¦à°¿à°‚à°šà±</translation>
<translation id="7995512525968007366">పేరà±à°•à±Šà°¨à°¬à°¡à°²à±‡à°¦à±</translation>
<translation id="800218591365569300">మెమరీని ఖాళీ చేయడానికి ఇతర à°Ÿà±à°¯à°¾à°¬à±â€Œà°²à± లేదా à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± మూసివేయడానà±à°¨à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="8012647001091218357">మేమౠపà±à°°à°¸à±à°¤à±à°¤à°‚ మీ తలà±à°²à°¿à°¦à°‚à°¡à±à°°à±à°²à°¨à± సంపà±à°°à°¦à°¿à°‚చలేకపోయామà±. దయచేసి మళà±à°²à±€ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="8025119109950072390">à°ˆ సైటà±â€Œà°²à±‹à°¨à°¿ దాడి చేసేవారౠసాఫà±à°Ÿà±â€Œà°µà±‡à°°à±â€Œà°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడం లేదా మీ à°µà±à°¯à°•à±à°¤à°¿à°—à°¤ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, ఫోనౠనంబరà±â€Œà°²à± లేదా à°•à±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) వెలà±à°²à°¡à°¿à°‚à°šà°¡à°‚ వంటి à°ªà±à°°à°®à°¾à°¦à°•à°°à°®à±ˆà°¨ పనà±à°²à± చేసేలా మిమà±à°®à°²à±à°¨à°¿ మాయ చేయవచà±à°šà±.</translation>
-<translation id="803030522067524905">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో à°«à°¿à°·à°¿à°‚à°—à±â€Œà°¨à± à°—à±à°°à±à°¤à°¿à°‚చింది. ఫిషింగౠసైటà±â€Œà°²à± ఇతర వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°² వలె నమà±à°®à°¿à°‚à°šà°¿ మిమà±à°®à°²à±à°¨à°¿ మాయ చేసà±à°¤à°¾à°¯à°¿. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">à°ˆ పేజీ <ph name="SOURCE_LANGUAGE" />లో ఉంది. దీనà±à°¨à°¿ <ph name="TARGET_LANGUAGE" />లోకి à°…à°¨à±à°µà°¦à°¿à°‚చాలా?</translation>
+<translation id="8037357227543935929">అడగాలి (డిఫాలà±à°Ÿà±)</translation>
<translation id="8041089156583427627">à°ªà±à°°à°¤à°¿à°¸à±à°ªà°‚దననౠపంపండి</translation>
+<translation id="8041940743680923270">సారà±à°µà°œà°¨à±€à°¨ డిఫాలà±à°Ÿà±â€Œà°¨à± ఉపయోగించౠ(à°…à°¡à±à°—à±)</translation>
<translation id="8088680233425245692">కథనానà±à°¨à°¿ వీకà±à°·à°¿à°‚చడంలో విఫలమైంది.</translation>
<translation id="8089520772729574115">1 MB కంటే తకà±à°•à±à°µ</translation>
<translation id="8091372947890762290">సకà±à°°à°¿à°¯à°‚ సరà±à°µà°°à±â€Œà°²à±‹ పెండింగà±â€Œà°²à±‹ ఉంది</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007"><ph name="HOST_NAME" /> సరà±à°µà°°à± <ph name="BEGIN_ABBR" />DNS à°šà°¿à°°à±à°¨à°¾à°®à°¾<ph name="END_ABBR" />నౠకనà±à°—ొనడం సాధà±à°¯à°ªà°¡à°²à±‡à°¦à±.</translation>
<translation id="8149426793427495338">మీ à°•à°‚à°ªà±à°¯à±‚టరౠనిదà±à°°à°¾à°µà°¸à±à°¥à°•à°¿ వెళà±à°²à°¿à°‚ది.</translation>
<translation id="8150722005171944719"><ph name="URL" />లో ఫైలౠచదవగలిగేది కాదà±. దీనà±à°¨à°¿ తీసివేసి ఉండవచà±à°šà±, తరలించి ఉండవచà±à°šà± లేదా ఫైలౠఅనà±à°®à°¤à±à°²à± à°ªà±à°°à°¾à°ªà±à°¯à°¤à°¨à± నిరోధిసà±à°¤à±à°‚డవచà±à°šà±.</translation>
+<translation id="8184538546369750125">సారà±à°µà°œà°¨à±€à°¨ డిఫాలà±à°Ÿà±â€Œà°¨à± ఉపయోగించౠ(à°…à°¨à±à°®à°¤à°¿à°‚à°šà±)</translation>
+<translation id="8191494405820426728">à°¸à±à°¥à°¾à°¨à°¿à°• à°•à±à°°à°¾à°·à± ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;తరలించడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
<translation id="8201077131113104583">ID "<ph name="EXTENSION_ID" />" ఉనà±à°¨ పొడిగింపౠకోసం నవీకరణ URL చెలà±à°²à°¦à±.</translation>
<translation id="8202097416529803614">ఆరà±à°¡à°°à± సారాంశం</translation>
<translation id="8218327578424803826">కేటాయించిన à°¸à±à°¥à°¾à°¨à°‚:</translation>
<translation id="8225771182978767009">à°ˆ à°•à°‚à°ªà±à°¯à±‚à°Ÿà°°à±â€Œà°¨à± సెటపౠచేసిన à°µà±à°¯à°•à±à°¤à°¿ à°ˆ సైటà±â€Œà°¨à± à°¬à±à°²à°¾à°•à± చేయడానికి à°Žà°‚à°šà±à°•à±à°¨à±à°¨à°¾à°°à±.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">à°ªà±à°°à°¸à±à°¤à±à°¤à°‚ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />పై దాడి చేసినవారౠమీ సమాచారానà±à°¨à°¿ (ఉదాహరణకà±, ఫోటోలà±, పాసà±â€Œà°µà°°à±à°¡à±â€Œà°²à±, సందేశాలౠమరియౠకà±à°°à±†à°¡à°¿à°Ÿà± కారà±à°¡à±â€Œà°²à±) దొంగిలించడం కోసం లేదా తొలగించడం కోసం మీ à°•à°‚à°ªà±à°¯à±‚à°Ÿà°°à±â€Œà°²à±‹ à°ªà±à°°à°®à°¾à°¦à°•à°°à°®à±ˆà°¨ à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°¿ ఉండవచà±à°šà±.</translation>
<translation id="8241707690549784388">మీరౠవెతికే పేజీ మీరౠఎంటరౠచేసిన సమాచారానà±à°¨à°¿ ఉపయోగించà±à°•à±à°‚ది. à°† పేజీకి తిరిగి వెళà±à°³à°¡à°‚ à°¦à±à°µà°¾à°°à°¾ మీరౠచేసిన à° à°šà°°à±à°¯ అయినా à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చెయà±à°¯à°µà°²à°¸à°¿ వసà±à°¤à±à°‚ది. మీరౠకొనసాగాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
<translation id="8249320324621329438">చివరగా పొందబడినవి:</translation>
<translation id="8253091569723639551">బిలà±à°²à°¿à°‚à°—à± à°šà°¿à°°à±à°¨à°¾à°®à°¾ ఆవశà±à°¯à°•à°‚</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">మీకౠదీని à°—à±à°°à°¿à°‚à°šà°¿ à°–à°šà±à°šà°¿à°¤à°‚à°—à°¾ తెలియకà±à°‚టే మీ నెటà±â€Œà°µà°°à±à°•à± నిరà±à°µà°¾à°¹à°•à±à°¨à°¿ సంపà±à°°à°¦à°¿à°‚à°šà°‚à°¡à°¿.</translation>
<translation id="8293206222192510085">à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à°¨à± జోడించà±</translation>
<translation id="8294431847097064396">మూలం</translation>
+<translation id="8306404619377842860">మీ పరికరం యొకà±à°• తేదీ మరియౠసమయం (<ph name="DATE_AND_TIME" />) తపà±à°ªà±à°—à°¾ ఉనà±à°¨ కారణంగా <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />à°•à± à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కనెకà±à°·à°¨à±â€Œà°¨à°¿ à°à°°à±à°ªà°¾à°Ÿà± చేయడం సాధà±à°¯à°‚ కాదà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">నెటà±â€Œà°µà°°à±à°•à± కనెకà±à°·à°¨à±â€Œà°¤à±‹ సమసà±à°¯ ఉనà±à°¨à°‚à°¦à±à°¨ à°…à°¨à±à°µà°¾à°¦à°‚ విఫలమైంది.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" />à°•à°¿ à°ªà±à°°à°¾à°ªà±à°¯à°¤ నిరాకరించబడింది</translation>
<translation id="834457929814110454">మీ à°­à°¦à±à°°à°¤à°•à± వాటిలà±à°²à±‡ ఆపదల à°—à±à°°à°¿à°‚à°šà°¿ మీకౠఅరà±à°¥à°‚ à°…à°¯à±à°¯à°¿ ఉంటే, హానికర à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à± తీసివేయబడటానికి à°®à±à°‚దే మీరౠ<ph name="BEGIN_LINK" />à°ˆ సైటà±â€Œà°¨à± సందరà±à°¶à°¿à°‚చవచà±à°šà±<ph name="END_LINK" />.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">మీ Google ఖాతా à°¨à±à°‚à°¡à°¿ కారà±à°¡à±â€Œà°²à°¨à± ఉపయోగించేందà±à°•à±, Chromeà°•à°¿ సైనౠఇనౠచేయండి</translation>
<translation id="8488350697529856933">వీటికి వరà±à°¤à°¿à°¸à±à°¤à±à°‚ది</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> à°ªà±à°°à°¤à°¿à°¸à±à°ªà°‚దించడానికి చాలా à°Žà°•à±à°•à±à°µ సమయం పటà±à°Ÿà°¿à°‚ది.</translation>
-<translation id="852346902619691059">à°ˆ సరà±à°µà°°à± ఇది à°’à°• <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని à°­à°¦à±à°°à°¤à°¾ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ మీ పరికరం ఆపరేటింగౠసిసà±à°Ÿà°®à± విశà±à°µà°¸à°¿à°‚చలేదà±. తపà±à°ªà±à°—à°¾ కానà±à°«à°¿à°—రౠచేయడం వలన లేదా దాడిచేసే à°µà±à°¯à°•à±à°¤à°¿ మీ కనెకà±à°·à°¨à±â€Œà°•à°¿ అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచà±à°šà±. <ph name="BEGIN_LEARN_MORE_LINK" />మరింత తెలà±à°¸à±à°•à±‹à°‚à°¡à°¿<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">à°—à°¡à±à°µà± à°®à±à°—ింపౠసంవతà±à°¸à°°à°‚</translation>
<translation id="8543181531796978784">మీరౠ<ph name="BEGIN_ERROR_LINK" />à°—à±à°°à±à°¤à°¿à°‚పౠసమసà±à°¯à°¨à± నివేదించవచà±à°šà±<ph name="END_ERROR_LINK" /> లేదా మీకౠమీ à°­à°¦à±à°°à°¤à°•à± పొంచి ఉనà±à°¨ à°ªà±à°°à°®à°¾à°¦à°¾à°²à± à°…à°°à±à°¥à°‚ à°…à°¯à±à°¯à°¿ ఉంటే, <ph name="BEGIN_LINK" />à°ˆ à°…à°¸à±à°°à°•à±à°·à°¿à°¤ సైటà±â€Œà°¨à± సందరà±à°¶à°¿à°‚à°šà°‚à°¡à°¿<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">పేజీ భాష నిరà±à°¥à°¾à°°à°¿à°‚చలేకపోయినందà±à°¨ à°…à°¨à±à°µà°¾à°¦à°‚ విఫలమైంది.</translation>
-<translation id="8559762987265718583">మీ పరికరం తేదీ మరియౠసమయం (<ph name="DATE_AND_TIME" />) తపà±à°ªà±à°—à°¾ ఉనà±à°¨à°‚à°¦à±à°¨ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />à°•à°¿ à°ªà±à°°à±ˆà°µà±‡à°Ÿà± కనెకà±à°·à°¨à± à°à°°à±à°ªà°¾à°Ÿà± చేయబడదà±.</translation>
<translation id="8571890674111243710">పేజీని <ph name="LANGUAGE" />à°•à± à°…à°¨à±à°µà°¦à°¿à°¸à±à°¤à±‹à°‚ది...</translation>
<translation id="858637041960032120">ఫోనౠనం. జోడిం.
</translation>
@@ -821,6 +895,7 @@
<translation id="8738058698779197622">à°¸à±à°°à°•à±à°·à°¿à°¤ కనెకà±à°·à°¨à±â€Œà°¨à± à°à°°à±à°ªà°¾à°Ÿà± చేయడానికి, మీ గడియారానà±à°¨à°¿ సరైన సమయానికి సెటౠచేయాలి. à°Žà°‚à°¦à±à°•à°‚టే వెబà±â€Œà°¸à±ˆà°Ÿà±â€Œà°²à± వాటిని à°—à±à°°à±à°¤à°¿à°‚చడానికి ఉపయోగించే à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°²à± నిరà±à°¦à°¿à°·à±à°Ÿ కాలవà±à°¯à°µà°§à±à°²à±à°²à±‹ మాతà±à°°à°®à±‡ చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°µà±à°¤à°¾à°¯à°¿. మీ పరికరం యొకà±à°• గడియారం సమయం తపà±à°ªà±à°—à°¾ ఉనà±à°¨à°‚à°¦à±à°¨, Chromium à°ˆ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°²à°¨à± ధృవీకరించడానికి వీలà±à°ªà°¡à°²à±‡à°¦à±.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> &lt;abbr id="dnsDefinition"&gt;DNS à°šà°¿à°°à±à°¨à°¾à°®à°¾&lt;/abbr&gt; à°•à°¨à±à°—ొనబడలేదà±. సమసà±à°¯à°¨à± నిరà±à°§à°¾à°°à°¿à°¸à±à°¤à±‹à°‚ది.</translation>
<translation id="8759274551635299824">à°ˆ కారà±à°¡à± à°—à°¡à±à°µà± à°®à±à°—ిసింది</translation>
+<translation id="8761567432415473239">Google à°¸à±à°°à°•à±à°·à°¿à°¤ à°¬à±à°°à±Œà°œà°¿à°‚గౠఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />హానికర à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€à°²à°¨à± à°•à°¨à±à°—ొనింది<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">&amp;తొలగించడానà±à°¨à°¿ à°ªà±à°¨à°°à°¾à°µà±ƒà°¤à°‚ చేయి</translation>
<translation id="8800988563907321413">మీ సమీపంలోని సూచనలౠఇకà±à°•à°¡ కనిపిసà±à°¤à°¾à°¯à°¿</translation>
<translation id="8820817407110198400">à°¬à±à°•à±â€Œà°®à°¾à°°à±à°•à±â€Œà°²à±</translation>
@@ -833,29 +908,30 @@
<translation id="8870413625673593573">ఇటీవల మూసివేసినవి</translation>
<translation id="8874824191258364635">చెలà±à°²à±à°¬à°¾à°Ÿà± à°…à°¯à±à°¯à±‡ కారà±à°¡à± నంబరà±â€Œà°¨à± నమోదౠచేయండి</translation>
<translation id="8876793034577346603">నెటà±â€Œà°µà°°à±à°•à± కానà±à°«à°¿à°—రేషనౠఅనà±à°µà°¯à°¿à°‚చబడటంలో విఫలమైంది.</translation>
-<translation id="8877192140621905067">మీరౠనిరà±à°§à°¾à°°à°¿à°‚à°šà°¿à°¨ తరà±à°µà°¾à°¤, మీ కారà±à°¡à± వివరాలౠఈ సైటà±â€Œà°¤à±‹ భాగసà±à°µà°¾à°®à±à°¯à°‚ చేయబడతాయి</translation>
<translation id="8889402386540077796">వరà±à°£à°‚</translation>
<translation id="8891727572606052622">చెలà±à°²à°¨à°¿ à°ªà±à°°à°¾à°•à±à°¸à±€ మోడà±.</translation>
<translation id="889901481107108152">à°•à±à°·à°®à°¿à°‚à°šà°‚à°¡à°¿, à°ˆ à°ªà±à°°à°¯à±‹à°—à°‚ మీ à°ªà±à°²à°¾à°Ÿà±â€Œà°«à°¾à°°à°®à±â€Œà°²à±‹ à°…à°‚à°¦à±à°¬à°¾à°Ÿà±à°²à±‹ లేదà±.</translation>
<translation id="8903921497873541725">దగà±à°—à°°à°¿à°•à°¿ జూమౠచెయà±à°¯à°¿</translation>
<translation id="8931333241327730545">మీరౠఈ కారà±à°¡à±â€Œà°¨à± మీ Google ఖాతాకి సేవౠచేయాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?</translation>
<translation id="8932102934695377596">మీ గడియారం సమయం గతంలో ఉంది</translation>
-<translation id="8954894007019320973">(కొనసాగౠ.)</translation>
<translation id="8971063699422889582">సరà±à°µà°°à± యొకà±à°• à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ à°—à°¡à±à°µà± à°®à±à°—ిసింది.</translation>
<translation id="8986494364107987395">Googleà°•à± à°¸à±à°µà°¯à°‚చాలకంగా ఉపయోగ గణాంకాలనౠమరియౠకà±à°°à°¾à°·à± నివేదికలనౠపంపà±</translation>
-<translation id="8987927404178983737">నెల</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">à°ˆ సైటౠహానికర à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± కలిగి ఉంది</translation>
+<translation id="8997023839087525404">సరà±à°µà°°à± à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°° పారదరà±à°¶à°•à°¤ విధానానà±à°¨à°¿ ఉపయోగించి పబà±à°²à°¿à°•à±â€Œà°—à°¾ బహిరంగపరచబడని à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°¨à±à°¨à°¿ అందించింది. కొనà±à°¨à°¿ à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°¾à°²à°•à±, అవి విశà±à°µà°¸à°¨à±€à°¯à°®à±ˆà°¨à°µà°¨à°¿ మరియౠదాడి చేసేవారి à°¨à±à°‚à°¡à°¿ à°°à°•à±à°·à°£ à°•à°²à±à°ªà°¿à°‚చగలవని నిరà±à°§à°¾à°°à°¿à°‚చడానికి, ఇది ఆవశà±à°¯à°•à°‚.</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> à°ªà±à°°à°¾à°•à±à°¸à±€à°•à°¿ వినియోగదారౠపేరౠమరియౠపాసà±â€Œà°µà°°à±à°¡à± అవసరం.</translation>
+<translation id="9005998258318286617">PDF పతà±à°°à°¾à°¨à±à°¨à°¿ లోడౠచేయడం విఫలమైంది.</translation>
<translation id="901974403500617787">సిసà±à°Ÿà°®à± à°µà±à°¯à°¾à°ªà±à°¤à°‚à°—à°¾ వరà±à°¤à°¿à°‚పజేయబడే à°«à±à°²à°¾à°—à±â€Œà°²à± యజమాని à°¦à±à°µà°¾à°°à°¾ మాతà±à°°à°®à±‡ సెటౠచేయబడతాయి: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">కారà±à°¡à± బిలà±à°²à°¿à°‚à°—à± à°šà°¿à°°à±à°¨à°¾à°®à°¾ అవసరం</translation>
<translation id="9020542370529661692">à°ˆ పేజీ <ph name="TARGET_LANGUAGE" />à°•à°¿ à°…à°¨à±à°µà°¦à°¿à°‚చబడింది</translation>
<translation id="9035022520814077154">à°­à°¦à±à°°à°¤à°¾ లోపం</translation>
<translation id="9038649477754266430">పేజీలనౠమరింత శీఘà±à°°à°‚à°—à°¾ లోడౠచేయడానికి సూచన సేవనౠఉపయోగించండి</translation>
<translation id="9039213469156557790">అలాగే, à°ˆ పేజీలో à°¸à±à°°à°•à±à°·à°¿à°¤à°‚ కాని ఇతర వనరà±à°²à± ఉనà±à°¨à°¾à°¯à°¿. à°ˆ వనరà±à°²à°¨à± బదిలీ చేసà±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± ఇతరà±à°²à± చూడగలరౠమరియౠదాడికి పాలà±à°ªà°¡à±‡à°µà°¾à°°à± పేజీ à°ªà±à°°à°µà°°à±à°¤à°¨à°¨à± మారà±à°šà±‡à°²à°¾ వీటిని సవరించగలరà±.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />పై దాడి చేసేవారౠమీ à°¬à±à°°à±Œà°œà°¿à°‚à°—à± à°…à°¨à±à°­à°µà°¾à°¨à°¿à°•à°¿ (ఉదాహరణకà±, మీ హోమౠపేజీని మారà±à°šà°¡à°‚ లేదా మీరౠసందరà±à°¶à°¿à°‚à°šà°¿à°¨ సైటà±â€Œà°²à±à°²à±‹ అదనపౠపà±à°°à°•à°Ÿà°¨à°²à°¨à± చూపడం à°¦à±à°µà°¾à°°à°¾) హాని కలిగించే à°ªà±à°°à±‹à°—à±à°°à°¾à°®à±â€Œà°²à°¨à± ఇనà±â€Œà°¸à±à°Ÿà°¾à°²à± చేసే విధంగా మిమà±à°®à°²à±à°¨à°¿ మోసగించడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚à°šà°¿ ఉండవచà±à°šà±.</translation>
+<translation id="9049981332609050619">మీరౠ<ph name="DOMAIN" />ని చేరà±à°•à±‹à°µà°¡à°¾à°¨à°¿à°•à°¿ à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చారà±, కానీ సరà±à°µà°°à± à°’à°• చెలà±à°²à±à°¬à°¾à°Ÿà±à°²à±‹ లేని à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ని అందించింది.</translation>
<translation id="9050666287014529139">పాసà±â€Œà°«à±à°°à±‡à°œà±</translation>
<translation id="9065203028668620118">సవరించà±</translation>
<translation id="9068849894565669697">à°°à°‚à°—à±à°¨à°¿ à°Žà°‚à°šà±à°•à±‹à°‚à°¡à°¿</translation>
+<translation id="9069693763241529744">పొడిగింపౠదà±à°µà°¾à°°à°¾ à°¬à±à°²à°¾à°•à± చేయబడింది</translation>
<translation id="9076283476770535406">ఇందà±à°²à±‹ పెదà±à°¦à°²à°•à± మాతà±à°°à°®à±‡ à°…à°¨à±à°®à°¤à°¿à°‚à°šà°¿à°¨ కంటెంటౠఉండవచà±à°šà±</translation>
<translation id="9078964945751709336">మరింత సమాచారం ఆవశà±à°¯à°•à°‚</translation>
<translation id="9103872766612412690"><ph name="SITE" /> సాధారణంగా మీ సమాచారానà±à°¨à°¿ à°°à°•à±à°·à°¿à°‚చడానికి à°—à±à°ªà±à°¤à±€à°•à°°à°£à°¨à± ఉపయోగిసà±à°¤à±à°‚ది. Chromium ఈసారి <ph name="SITE" />à°•à°¿ కనెకà±à°Ÿà± చేయడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°‚చినపà±à°ªà±à°¡à±, వెబà±â€Œà°¸à±ˆà°Ÿà± అసాధారణ మరియౠతపà±à°ªà± ఆధారాలౠఅని à°ªà±à°°à°¤à°¿à°¸à±à°ªà°‚దించింది. దాడి చేసే à°µà±à°¯à°•à±à°¤à°¿ <ph name="SITE" />à°—à°¾ à°µà±à°¯à°µà°¹à°°à°¿à°‚à°šà°¿ మోసగించడానికి à°ªà±à°°à°¯à°¤à±à°¨à°¿à°¸à±à°¤à±à°¨à±à°¨à°ªà±à°ªà±à°¡à± లేదా Wi-Fi సైనà±-ఇనౠసà±à°•à±à°°à±€à°¨à± కనెకà±à°·à°¨à±â€Œà°•à± అంతరాయం కలిగించినపà±à°ªà±à°¡à± ఇలా జరగవచà±à°šà±. Chromium ఎలాంటి డేటా వినిమయం సంభవించక à°®à±à°‚దే కనెకà±à°·à°¨à±â€Œà°¨à± ఆపివేసినందà±à°¨ మీ సమాచారం ఇపà±à°ªà°Ÿà°¿à°•à±€ à°¸à±à°°à°•à±à°·à°¿à°¤à°‚గానే ఉంది.</translation>
@@ -864,16 +940,21 @@
<translation id="9148507642005240123">&amp;సవరించడానà±à°¨à°¿ à°°à°¦à±à°¦à± చేయి</translation>
<translation id="9154194610265714752">నవీకరించబడింది</translation>
<translation id="9157595877708044936">అమరà±à°šà±à°¤à±‹à°‚ది...</translation>
+<translation id="9169664750068251925">à°ˆ సైటà±â€Œà°²à±‹ à°Žà°²à±à°²à°ªà±à°ªà±à°¡à±‚ à°¬à±à°²à°¾à°•à± చేయి</translation>
<translation id="9170848237812810038">&amp;à°…à°¨à±à°¡à±</translation>
<translation id="917450738466192189">సరà±à°µà°°à± యొకà±à°• à°ªà±à°°à°®à°¾à°£à°ªà°¤à±à°°à°‚ చెలà±à°²à±à°¬à°¾à°Ÿà± కాదà±.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> మరియౠమరో <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> మదà±à°¦à°¤à± లేని à°ªà±à°°à±‹à°Ÿà±‹à°•à°¾à°²à±â€Œà°¨à± ఉపయోగిసà±à°¤à±‹à°‚ది.</translation>
<translation id="9205078245616868884">మీ సమకాలీకరణ రహసà±à°¯ పదబంధంతో మీ డేటా à°—à±à°ªà±à°¤à±€à°•à°°à°¿à°‚చబడింది. సమకాలీకరణనౠపà±à°°à°¾à°°à°‚భించడానికి దీనà±à°¨à°¿ నమోదౠచేయండి.</translation>
<translation id="9207861905230894330">కథనానà±à°¨à°¿ జోడించడంలో విఫలమైంది.</translation>
+<translation id="9219103736887031265">à°šà°¿à°¤à±à°°à°¾à°²à±</translation>
<translation id="933612690413056017">ఇంటరà±à°¨à±†à°Ÿà± కనెకà±à°·à°¨à± లేదà±</translation>
<translation id="933712198907837967">డైనరà±à°¸à± à°•à±à°²à°¬à±</translation>
<translation id="935608979562296692">ఫారమà±â€Œà°¨à± తీసివేయండి</translation>
<translation id="939736085109172342">à°•à±à°°à±Šà°¤à±à°¤ ఫోలà±à°¡à°°à±</translation>
<translation id="941721044073577244">à°ˆ సైటà±â€Œà°¨à± సందరà±à°¶à°¿à°‚చడానికి మీకౠఅనà±à°®à°¤à°¿ లేనటà±à°²à±à°—à°¾ కనిపిసà±à°¤à±‹à°‚ది</translation>
<translation id="969892804517981540">అధికారిక బిలà±à°¡à±</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{à°à°®à±€ లేవà±}=1{1 అంశం}other{# అంశాలà±}}</translation>
<translation id="988159990683914416">డెవలపరౠబిలà±à°¡à±</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_th.xtb b/chromium/components/strings/components_strings_th.xtb
index d3f6b466d12..ddf56834dec 100644
--- a/chromium/components/strings/components_strings_th.xtb
+++ b/chromium/components/strings/components_strings_th.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">หมุนตามเข็มนาฬิà¸à¸²</translation>
<translation id="1038842779957582377">ไม่ทราบชื่อ</translation>
<translation id="1050038467049342496">ปิดà¹à¸­à¸›à¸­à¸·à¹ˆà¸™à¹†</translation>
-<translation id="1053591932240354961">คุณไม่สามารถเข้าชม <ph name="SITE" /> ได้ในขณะนี้ เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ส่งข้อมูลรับรองที่ถูà¸à¹à¸›à¸¥à¸‡à¸‹à¸¶à¹ˆà¸‡ Google Chrome ไม่สามารถดำเนินà¸à¸²à¸£à¹„ด้ โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจจะใช้งานได้ในภายหลัง <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡</translation>
<translation id="10614374240317010">ไม่เคยบันทึà¸</translation>
<translation id="106701514854093668">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸šà¸™à¹€à¸”สà¸à¹Œà¸—็อป</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">à¹à¸„ชนโยบายใช้ได้</translation>
<translation id="113188000913989374"><ph name="SITE" /> บอà¸à¸§à¹ˆà¸²:</translation>
<translation id="1132774398110320017">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าป้อนข้อความอัตโนมัติของ Chrome...</translation>
+<translation id="1150979032973867961">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปà¸à¸´à¸šà¸±à¸•à¸´à¸à¸²à¸£à¸‚องคอมพิวเตอร์ของคุณไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
+<translation id="1151972924205500581">ต้องมีรหัสผ่าน</translation>
<translation id="1152921474424827756">เข้าถึง<ph name="BEGIN_LINK" />สำเนาà¹à¸„ช<ph name="END_LINK" />ของ <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ปิดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¹‚ดยไม่คาดคิด</translation>
<translation id="1161325031994447685">เชื่อมต่อ Wi-Fi ใหม่</translation>
+<translation id="1165039591588034296">ข้อผิดพลาด</translation>
<translation id="1175364870820465910">&amp;พิมพ์...</translation>
<translation id="1181037720776840403">ลบ</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />รายงาน<ph name="END_WHITEPAPER_LINK" />รายละเอียดของเหตุà¸à¸²à¸£à¸“์ความปลอดภัยที่เป็นไปได้ต่อ Google โดยอัตโนมัติ <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">เพิ่มเติมจาà¸à¹„ซต์นี้</translation>
<translation id="1206967143813997005">ลายเซ็นเริ่มต้นไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="1209206284964581585">ซ่อนไปà¸à¹ˆà¸­à¸™</translation>
+<translation id="121201262018556460">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸ªà¸”งใบรับรองที่มีคีย์ที่ไม่รัดà¸à¸¸à¸¡ ผู้โจมตีอาจทำให้คีย์ส่วนตัวเสียหายไปà¹à¸¥à¹‰à¸§à¹à¸¥à¸°à¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¸™à¸µà¹‰à¸­à¸²à¸ˆà¹„ม่ใช่เซิร์ฟเวอร์ที่คุณคิด (คุณอาจà¸à¸³à¸¥à¸±à¸‡à¸•à¸´à¸”ต่อà¸à¸±à¸šà¸œà¸¹à¹‰à¹‚จมตี)</translation>
<translation id="1219129156119358924">à¸à¸²à¸£à¸£à¸±à¸à¸©à¸²à¸„วามปลอดภัยของระบบ</translation>
<translation id="1227224963052638717">นโยบายที่ไม่รู้จัà¸</translation>
<translation id="1227633850867390598">ซ่อนค่า</translation>
<translation id="1228893227497259893">ตัวระบุเอนทิตีไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="1232569758102978740">ไม่ระบุชื่อ</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" /> <ph name="TYPE_2" /> (ซิงค์à¹à¸¥à¹‰à¸§)</translation>
<translation id="1263231323834454256">เรื่องรออ่าน</translation>
<translation id="1264126396475825575">รายงานข้อขัดข้องเมื่อ <ph name="CRASH_TIME" /> (ยังไม่ได้อัปโหลดหรือละเว้น)</translation>
+<translation id="1281526147609854549">ออà¸à¹‚ดย <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">บล็อà¸à¹€à¸™à¸·à¹‰à¸­à¸«à¸²à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¹à¸¥à¹‰à¸§</translation>
<translation id="1285320974508926690">ไม่ต้องà¹à¸›à¸¥à¹„ซต์นี้</translation>
<translation id="129553762522093515">เพิ่งปิด</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />ลองล้างคุà¸à¸à¸µà¹‰<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">ผู้อื่น<ph name="BEGIN_EMPHASIS" />อาจยังมองเห็น<ph name="END_EMPHASIS" />à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¸‚องคุณ:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />เว็บไซต์ที่คุณเข้าชม
+ <ph name="LIST_ITEM" />นายจ้างหรือโรงเรียน
+ <ph name="LIST_ITEM" />ผู้ให้บริà¸à¸²à¸£à¸­à¸´à¸™à¹€à¸—อร์เน็ต
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">โดเมนà¸à¸²à¸£à¸¥à¸‡à¸—ะเบียน:</translation>
<translation id="1340482604681802745">ที่อยู่ในà¸à¸²à¸£à¸£à¸±à¸š</translation>
<translation id="1344211575059133124">ดูเหมือนว่าคุณต้องได้รับสิทธิ์เพื่อเข้าชมเว็บไซต์นี้</translation>
<translation id="1344588688991793829">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าป้อนข้อความอัตโนมัติของ Chromium...</translation>
+<translation id="1348198688976932919">ไซต์ที่จะเปิดมีà¹à¸­à¸›à¸­à¸±à¸™à¸•à¸£à¸²à¸¢</translation>
<translation id="1374468813861204354">คำà¹à¸™à¸°à¸™à¸³</translation>
<translation id="1375198122581997741">เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸£à¸¸à¹ˆà¸™</translation>
<translation id="1377321085342047638">หมายเลขบัตร</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ไม่ส่งข้อมูลใดๆ</translation>
<translation id="1407135791313364759">เปิดทั้งหมด</translation>
<translation id="1413809658975081374">ข้อผิดพลาดเà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸„วามเป็นส่วนตัว</translation>
+<translation id="14171126816530869">ข้อมูลประจำตัวของ <ph name="ORGANIZATION" /> ใน <ph name="LOCALITY" /> ได้รับà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¹‚ดย <ph name="ISSUER" /></translation>
<translation id="1426410128494586442">ใช่</translation>
<translation id="1430915738399379752">พิมพ์</translation>
-<translation id="1442912890475371290">บล็อà¸à¸„วามพยายาม<ph name="BEGIN_LINK" />ที่จะเข้าชมหน้าเว็บใน <ph name="DOMAIN" /><ph name="END_LINK" /></translation>
-<translation id="1491663344921578213">คุณไม่สามารถเข้าชม <ph name="SITE" /> ได้ในขณะนี้ เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ใช้à¸à¸²à¸£à¸•à¸£à¸¶à¸‡à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡ โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจจะใช้งานได้ในภายหลัง <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> รายà¸à¸²à¸£}other{<ph name="PAYMENT_METHOD_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> รายà¸à¸²à¸£}}</translation>
<translation id="1506687042165942984">à¹à¸ªà¸”งสำเนาที่บันทึà¸à¹„ว้ (หรือที่ล้าสมัย) ของหน้านี้</translation>
<translation id="1517433312004943670">ต้องระบุหมายเลขโทรศัพท์</translation>
<translation id="1519264250979466059">วันที่สร้าง</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">ต้องเปิดใช้ JavaScript เพื่อใช้ฟีเจอร์นี้</translation>
<translation id="1555130319947370107">สีน้ำเงิน</translation>
<translation id="1559528461873125649">ไม่มีไฟล์หรือไดเรà¸à¸—อรีดังà¸à¸¥à¹ˆà¸²à¸§</translation>
-<translation id="1559572115229829303">&lt;p&gt;ไม่สามารถสร้างà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸ªà¹ˆà¸§à¸™à¸•à¸±à¸§à¹„ปที่ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> เนื่องจาà¸à¸§à¸±à¸™à¸—ี่à¹à¸¥à¸°à¹€à¸§à¸¥à¸² (<ph name="DATE_AND_TIME" />) ในอุปà¸à¸£à¸“์ไม่ถูà¸à¸•à¹‰à¸­à¸‡&lt;/p&gt;
-
- &lt;p&gt;โปรดปรับวันที่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²à¸ˆà¸²à¸à¸«à¸±à¸§à¸‚้อ&lt;strong&gt;ทั่วไป&lt;/strong&gt;ในà¹à¸­à¸›&lt;strong&gt;à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า&lt;/strong&gt;&lt;/p&gt;</translation>
<translation id="1583429793053364125">มีสิ่งผิดปà¸à¸•à¸´à¹€à¸à¸´à¸”ขึ้นในขณะที่à¹à¸ªà¸”งหน้าเว็บนี้</translation>
<translation id="1592005682883173041">à¸à¸²à¸£à¹€à¸‚้าถึงข้อมูลในเครื่อง</translation>
+<translation id="1594030484168838125">เลือà¸</translation>
<translation id="161042844686301425">สีฟ้า</translation>
+<translation id="1620510694547887537">à¸à¸¥à¹‰à¸­à¸‡à¸–่ายรูป</translation>
<translation id="1629803312968146339">คุณต้องà¸à¸²à¸£à¹ƒà¸«à¹‰ Chrome บันทึà¸à¸šà¸±à¸•à¸£à¸™à¸µà¹‰à¹„หม</translation>
<translation id="1639239467298939599">à¸à¸³à¸¥à¸±à¸‡à¹‚หลด</translation>
<translation id="1640180200866533862">นโยบายผู้ใช้</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าเครือข่ายไม่ถูà¸à¸•à¹‰à¸­à¸‡à¹à¸¥à¸°à¹„ม่สามารถนำเข้า</translation>
<translation id="1644574205037202324">ประวัติà¸à¸²à¸£à¹€à¸‚้าชม</translation>
<translation id="1645368109819982629">ไม่รองรับโปรโตคอล</translation>
+<translation id="1655462015569774233">{1,plural, =1{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยหมดอายุไปเมื่อวานนี้ โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ ขณะนี้นาฬิà¸à¸²à¸‚องคุณตั้งค่าไว้ที่วันที่ <ph name="CURRENT_DATE" /> à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่านี้ถูà¸à¸•à¹‰à¸­à¸‡à¹„หม หาà¸à¹„ม่ถูà¸à¸•à¹‰à¸­à¸‡ คุณควรà¹à¸à¹‰à¹„ขนาฬิà¸à¸²à¸‚องระบบà¹à¸¥à¸°à¸£à¸µà¹€à¸Ÿà¸£à¸Šà¸«à¸™à¹‰à¸²à¸™à¸µà¹‰}other{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยหมดอายุไปเมื่อ # วันที่ผ่านมา โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ ขณะนี้นาฬิà¸à¸²à¸‚องคุณตั้งค่าไว้ที่วันที่ <ph name="CURRENT_DATE" /> à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่านี้ถูà¸à¸•à¹‰à¸­à¸‡à¹„หม หาà¸à¹„ม่ถูà¸à¸•à¹‰à¸­à¸‡ คุณควรà¹à¸à¹‰à¹„ขนาฬิà¸à¸²à¸‚องระบบà¹à¸¥à¸°à¸£à¸µà¹€à¸Ÿà¸£à¸Šà¸«à¸™à¹‰à¸²à¸™à¸µà¹‰}}</translation>
<translation id="1656489000284462475">à¸à¸²à¸£à¸£à¸±à¸š</translation>
<translation id="1663943134801823270">ข้อมูลบัตรà¹à¸¥à¸°à¸—ี่อยู่มาจาภChrome คุณสามารถจัดà¸à¸²à¸£à¸‚้อมูลเหล่านี้ใน<ph name="BEGIN_LINK" />à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า<ph name="END_LINK" /></translation>
<translation id="1676269943528358898">โดยทั่วไป <ph name="SITE" /> จะใช้à¸à¸²à¸£à¹€à¸‚้ารหัสเพื่อปà¸à¸›à¹‰à¸­à¸‡à¸‚้อมูลของคุณ เมื่อ Google Chrome พยายามเชื่อมต่อà¸à¸±à¸š <ph name="SITE" /> ในครั้งนี้ เว็บไซต์ดังà¸à¸¥à¹ˆà¸²à¸§à¸ªà¹ˆà¸‡à¸‚้อมูลรับรองที่ผิดปà¸à¸•à¸´à¹à¸¥à¸°à¹„ม่ถูà¸à¸•à¹‰à¸­à¸‡à¸à¸¥à¸±à¸šà¸¡à¸² เหตุà¸à¸²à¸£à¸“์นี้อาจเà¸à¸´à¸”ขึ้นเมื่อผู้บุà¸à¸£à¸¸à¸à¸žà¸¢à¸²à¸¢à¸²à¸¡à¸›à¸¥à¸­à¸¡à¹€à¸›à¹‡à¸™ <ph name="SITE" /> หรือหน้าจอà¸à¸²à¸£à¸¥à¸‡à¸Šà¸·à¹ˆà¸­à¹€à¸‚้าใช้ Wi-Fi รบà¸à¸§à¸™à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­ ข้อมูลของคุณยังปลอดภัยอยู่เนื่องจาภGoogle Chrome หยุดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¹ˆà¸­à¸™à¸¡à¸µà¸à¸²à¸£à¹à¸¥à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸‚้อมูล</translation>
-<translation id="168328519870909584">ผู้บุà¸à¸£à¸¸à¸à¸—ี่à¸à¸³à¸¥à¸±à¸‡à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจพยายามติดตั้งโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸šà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ของคุณ ซึ่งจะขโมยหรือลบข้อมูล (ตัวอย่างเช่น รูปภาพ รหัสผ่าน ข้อความ à¹à¸¥à¸°à¸šà¸±à¸•à¸£à¹€à¸„รดิต)</translation>
<translation id="168841957122794586">ใบรับรองของเซิร์ฟเวอร์มีคีย์à¸à¸²à¸£à¹€à¸‚้ารหัสที่ไม่รัดà¸à¸¸à¸¡</translation>
+<translation id="1706954506755087368">{1,plural, =1{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ตั้งà¹à¸•à¹ˆà¸§à¸±à¸™à¸žà¸£à¸¸à¹ˆà¸‡à¸™à¸µà¹‰ โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ}other{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ในอีภ# วันข้างหน้า โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ}}</translation>
<translation id="1710259589646384581">ระบบปà¸à¸´à¸šà¸±à¸•à¸´à¸à¸²à¸£</translation>
<translation id="1721312023322545264">คุณต้องได้รับสิทธิ์จาภ<ph name="NAME" /> เพื่อเข้าชมเว็บไซต์นี้</translation>
<translation id="1721424275792716183">* ช่องที่ต้องà¸à¸£à¸­à¸</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">ดาวน์โหลดหน้าเว็บในภายหลัง</translation>
<translation id="17513872634828108">à¹à¸—็บที่เปิดอยู่</translation>
<translation id="1753706481035618306">เลขหน้า</translation>
+<translation id="1763864636252898013">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปà¸à¸´à¸šà¸±à¸•à¸´à¸à¸²à¸£à¸‚องอุปà¸à¸£à¸“์ของคุณไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />ลองเรียà¸à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸§à¸´à¸™à¸´à¸ˆà¸‰à¸±à¸¢à¹€à¸„รือข่ายของ Windows<ph name="END_LINK" /></translation>
<translation id="1783075131180517613">โปรดอัปเดตข้อความรหัสผ่านที่ซิงค์ของคุณ</translation>
<translation id="1787142507584202372">à¹à¸—็บที่คุณเปิดไว้จะปราà¸à¸à¸—ี่นี่</translation>
+<translation id="1789575671122666129">ป๊อปอัป</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">ชื่อผู้ถือบัตร</translation>
-<translation id="1803678881841855883">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />ตรวจพบมัลà¹à¸§à¸£à¹Œ<ph name="END_LINK" />บน <ph name="SITE" /> บางครั้งเว็บไซต์ที่โดยปà¸à¸•à¸´à¹à¸¥à¹‰à¸§à¸ˆà¸°à¸›à¸¥à¸­à¸”ภัยอาจติดมัลà¹à¸§à¸£à¹Œà¹„ด้ เนื้อหาที่เป็นอันตรายมาจาภ<ph name="SUBRESOURCE_HOST" /> ซึ่งเป็นผู้เผยà¹à¸žà¸£à¹ˆà¸¡à¸±à¸¥à¹à¸§à¸£à¹Œà¸—ี่เป็นที่รู้จัภ<ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">วันที่เพิ่ม <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">คำขอหรือพารามิเตอร์คำขอไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="1826516787628120939">à¸à¸³à¸¥à¸±à¸‡à¸•à¸£à¸§à¸ˆà¸ªà¸­à¸š</translation>
<translation id="1834321415901700177">เว็บไซต์นี้มีโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢</translation>
+<translation id="1840414022444569775">มีà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸«à¸¡à¸²à¸¢à¹€à¸¥à¸‚บัตรนี้à¹à¸¥à¹‰à¸§</translation>
<translation id="1842969606798536927">จ่าย</translation>
<translation id="1871208020102129563">พร็อà¸à¸‹à¸µà¸–ูà¸à¸•à¸±à¹‰à¸‡à¸„่าให้ใช้พร็อà¸à¸‹à¸µà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸šà¸šà¸„งที่ ไม่ใช่ URL สคริปต์ .pac</translation>
<translation id="1871284979644508959">ช่องที่ต้องà¸à¸£à¸­à¸</translation>
<translation id="187918866476621466">เปิดหน้าเริ่มต้นใช้งาน</translation>
<translation id="1883255238294161206">ยุบรายà¸à¸²à¸£</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> รายà¸à¸²à¸£}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> รายà¸à¸²à¸£}}</translation>
<translation id="1898423065542865115">à¸à¸²à¸£à¸à¸£à¸­à¸‡</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{ไม่มี}=1{เว็บไซต์ 1 à¹à¸«à¹ˆà¸‡}other{เว็บไซต์ # à¹à¸«à¹ˆà¸‡}}</translation>
<translation id="194030505837763158">ไปที่ <ph name="LINK" /></translation>
<translation id="1962204205936693436">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸‚อง <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">ข้อผิดพลาดในà¸à¸²à¸£à¸ˆà¸±à¸”เรียง</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">ไม่สนใจเพราะถูà¸à¹à¸—นที่โดย <ph name="POLICY_NAME" /></translation>
<translation id="2138201775715568214">à¸à¸³à¸¥à¸±à¸‡à¸¡à¸­à¸‡à¸«à¸²à¸«à¸™à¹‰à¸² Physical Web ที่อยู่ใà¸à¸¥à¹‰à¹€à¸„ียง</translation>
<translation id="213826338245044447">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸šà¸™à¸¡à¸·à¸­à¸–ือ</translation>
-<translation id="2148716181193084225">วันนี้</translation>
+<translation id="2147827593068025794">à¸à¸²à¸£à¸‹à¸´à¸‡à¸„์ในà¹à¸šà¹‡à¸à¸à¸£à¸²à¸§à¸”์</translation>
<translation id="2154054054215849342">ไม่มีà¸à¸²à¸£à¸‹à¸´à¸‡à¸„์สำหรับโดเมนของคุณ</translation>
<translation id="2154484045852737596">à¹à¸à¹‰à¹„ขบัตร</translation>
<translation id="2166049586286450108">à¸à¸²à¸£à¹€à¸‚้าถึงระดับผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¹‚ดยสมบูรณ์</translation>
<translation id="2166378884831602661">เว็บไซต์นี้ไม่สามารถให้à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸—ี่ปลอดภัย</translation>
<translation id="2181821976797666341">นโยบาย</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{ที่อยู่ 1 รายà¸à¸²à¸£}other{ที่อยู่ # รายà¸à¸²à¸£}}</translation>
+<translation id="2187317261103489799">ตรวจหา (ค่าเริ่มต้น)</translation>
<translation id="2202020181578195191">ป้อนปีที่หมดอายุที่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="2212735316055980242">ไม่พบนโยบาย</translation>
<translation id="2213606439339815911">à¸à¸³à¸¥à¸±à¸‡à¸”ึงรายà¸à¸²à¸£...</translation>
+<translation id="2218879909401188352">ผู้โจมตีที่à¸à¸³à¸¥à¸±à¸‡à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> สามารถติดตั้งà¹à¸­à¸›à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸—ี่ทำลายอุปà¸à¸£à¸“์ของคุณ เพิ่มค่าใช้จ่ายà¹à¸à¸‡à¹ƒà¸™à¹ƒà¸šà¹à¸ˆà¹‰à¸‡à¸¢à¸­à¸”มือถือ หรือขโมยข้อมูลส่วนบุคคล <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณด้วย<ph name="BEGIN_LINK" />à¹à¸­à¸›à¸à¸²à¸£à¸§à¸´à¸™à¸´à¸ˆà¸‰à¸±à¸¢<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">ส่งเลย</translation>
<translation id="225207911366869382">เลิà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸„่านี้à¸à¸±à¸šà¸™à¹‚ยบายนี้</translation>
<translation id="2262243747453050782">ข้อผิดพลาดของ HTTP</translation>
+<translation id="2270484714375784793">หมายเลขโทรศัพท์</translation>
<translation id="2282872951544483773">à¸à¸²à¸£à¸—ดลองที่ไม่พร้อมใช้งาน</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> รายà¸à¸²à¸£}other{<ph name="ITEM_COUNT" /> รายà¸à¸²à¸£}}</translation>
<translation id="2292556288342944218">à¸à¸²à¸£à¹€à¸‚้าถึงอินเทอร์เน็ตของคุณถูà¸à¸šà¸¥à¹‡à¸­à¸</translation>
<translation id="230155334948463882">บัตรใหม่ใช่ไหม</translation>
-<translation id="2305919008529760154">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะอาจมีà¸à¸²à¸£à¸­à¸­à¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸„วามปลอดภัยปลอม สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> ต้องใช้ชื่อผู้ใช้à¹à¸¥à¸°à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™</translation>
-<translation id="2318774815570432836">คุณไม่สามารถเข้าชม <ph name="SITE" /> ได้ในขณะนี้ เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ดังà¸à¸¥à¹ˆà¸²à¸§à¹ƒà¸Šà¹‰ HSTS โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจจะใช้งานได้ในภายหลัง <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">ผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¹€à¸›à¹‡à¸™à¸œà¸¹à¹‰à¸„วบคุมà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า</translation>
<translation id="2354001756790975382">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸­à¸·à¹ˆà¸™à¹†</translation>
+<translation id="2354430244986887761">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />พบà¹à¸­à¸›à¸­à¸±à¸™à¸•à¸£à¸²à¸¢<ph name="END_LINK" />ใน <ph name="SITE" /></translation>
<translation id="2355395290879513365">ผู้โจมตีอาจเห็นรูปภาพที่คุณà¸à¸³à¸¥à¸±à¸‡à¸”ูอยู่บนเว็บไซต์นี้à¹à¸¥à¸°à¸«à¸¥à¸­à¸à¸¥à¸§à¸‡à¸„ุณโดยà¸à¸²à¸£à¹à¸à¹‰à¹„ขรูปภาพ</translation>
+<translation id="2356070529366658676">ถาม</translation>
+<translation id="2359629602545592467">หลายรายà¸à¸²à¸£</translation>
<translation id="2359808026110333948">ดำเนินà¸à¸²à¸£à¸•à¹ˆà¸­</translation>
<translation id="2365563543831475020">รายงานข้อขัดข้องเมื่อ <ph name="CRASH_TIME" /> ยังไม่ได้อัปโหลด</translation>
<translation id="2367567093518048410">ระดับ</translation>
-<translation id="2371153335857947666">{1,plural, =1{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยหมดอายุไปเมื่อวานนี้ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ ขณะนี้นาฬิà¸à¸²à¸‚องคุณตั้งค่าไว้ที่วันที่ <ph name="CURRENT_DATE" /> à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่านี้ถูà¸à¸•à¹‰à¸­à¸‡à¹„หม หาà¸à¹„ม่ถูà¸à¸•à¹‰à¸­à¸‡ คุณควรà¹à¸à¹‰à¹„ขนาฬิà¸à¸²à¸‚องระบบà¹à¸¥à¸°à¸£à¸µà¹€à¸Ÿà¸£à¸Šà¸«à¸™à¹‰à¸²à¸™à¸µà¹‰ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" />}other{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยหมดอายุไปเมื่อ # วันที่ผ่านมา สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ ขณะนี้นาฬิà¸à¸²à¸‚องคุณตั้งค่าไว้ที่วันที่ <ph name="CURRENT_DATE" /> à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่านี้ถูà¸à¸•à¹‰à¸­à¸‡à¹„หม หาà¸à¹„ม่ถูà¸à¸•à¹‰à¸­à¸‡ คุณควรà¹à¸à¹‰à¹„ขนาฬิà¸à¸²à¸‚องระบบà¹à¸¥à¸°à¸£à¸µà¹€à¸Ÿà¸£à¸Šà¸«à¸™à¹‰à¸²à¸™à¸µà¹‰ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">ไม่มีทางเลือภUI ที่พร้อมใช้งาน</translation>
<translation id="2384307209577226199">ค่าเริ่มต้นขององค์à¸à¸£</translation>
<translation id="2386255080630008482">ใบรับรองของเซิร์ฟเวอร์ถูà¸à¹€à¸žà¸´à¸à¸–อนà¹à¸¥à¹‰à¸§</translation>
<translation id="2392959068659972793">à¹à¸ªà¸”งนโยบายโดยที่ไม่ได้ตั้งค่า</translation>
<translation id="239429038616798445">วิธีà¸à¸²à¸£à¸ˆà¸±à¸”ส่งสินค้านี้ไม่พร้อมให้บริà¸à¸²à¸£ โปรดลองใช้วิธีà¸à¸²à¸£à¸­à¸·à¹ˆà¸™</translation>
<translation id="2396249848217231973">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¸™à¸³à¸­à¸­à¸</translation>
-<translation id="2460160116472764928">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />ตรวจพบมัลà¹à¸§à¸£à¹Œ<ph name="END_LINK" />บน <ph name="SITE" /> บางครั้งเว็บไซต์ที่โดยปà¸à¸•à¸´à¹à¸¥à¹‰à¸§à¸ˆà¸°à¸›à¸¥à¸­à¸”ภัยอาจติดมัลà¹à¸§à¸£à¹Œà¹„ด้ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะอาจมีà¸à¸²à¸£à¹€à¸žà¸´à¸à¸–อนใบรับรองความปลอดภัย โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
<translation id="2463739503403862330">à¸à¸£à¸­à¸à¸‚้อมูล</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />เรียà¸à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸§à¸´à¸™à¸´à¸ˆà¸‰à¸±à¸¢à¹€à¸„รือข่าย<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL ค้นหาไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
+<translation id="2482878487686419369">à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•à¸·à¸­à¸™</translation>
<translation id="2491120439723279231">ใบรับรองของเซิร์ฟเวอร์มีข้อผิดพลาด</translation>
<translation id="2495083838625180221">โปรà¹à¸à¸£à¸¡à¹à¸¢à¸à¸§à¸´à¹€à¸„ราะห์ JSON</translation>
<translation id="2495093607237746763">หาà¸à¹€à¸¥à¸·à¸­à¸à¹„ว้ Chromium จะจัดเà¸à¹‡à¸šà¸ªà¸³à¹€à¸™à¸²à¸šà¸±à¸•à¸£à¸‚องคุณบนอุปà¸à¸£à¸“์นี้เพื่อà¸à¸²à¸£à¸à¸£à¸­à¸à¹à¸šà¸šà¸Ÿà¸­à¸£à¹Œà¸¡à¸—ี่รวดเร็วขึ้น</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">ย้อนà¸à¸¥à¸±à¸š</translation>
<translation id="2515629240566999685">ตรวจสอบสัà¸à¸à¸²à¸“ในพื้นที่ของคุณ</translation>
<translation id="2516305470678292029">ทางเลือภUI</translation>
+<translation id="2539524384386349900">ตรวจหา</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> ส่งà¸à¸²à¸£à¸•à¸­à¸šà¸à¸¥à¸±à¸šà¸—ี่ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
-<translation id="2552545117464357659">ใหม่à¸à¸§à¹ˆà¸²</translation>
<translation id="2556876185419854533">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¹à¸à¹‰à¹„ข</translation>
<translation id="2587730715158995865">จาภ<ph name="ARTICLE_PUBLISHER" /> อ่านเรื่องราวนี้à¹à¸¥à¸°à¸­à¸·à¹ˆà¸™à¹† อีภ<ph name="OTHER_ARTICLE_COUNT" /> เรื่อง</translation>
<translation id="2587841377698384444">รหัส API ไดเรà¸à¸—อรี:</translation>
<translation id="2597378329261239068">เอà¸à¸ªà¸²à¸£à¸™à¸µà¹‰à¹„ด้รับà¸à¸²à¸£à¸›à¹‰à¸­à¸‡à¸à¸±à¸™à¸”้วยรหัสผ่าน โปรดป้อนรหัสผ่าน</translation>
<translation id="2609632851001447353">รูปà¹à¸šà¸šà¸•à¹ˆà¸²à¸‡à¹†</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{ไม่มี}=1{1 à¹à¸­à¸› ($1)}=2{2 à¹à¸­à¸› ($1, $2)}other{# à¹à¸­à¸› ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">นาฬิà¸à¸²à¹€à¸£à¹‡à¸§à¹€à¸à¸´à¸™à¹„ป</translation>
<translation id="2639739919103226564">สถานะ:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">à¸à¸²à¸£à¹€à¸‚้าถึงไฟล์ถูà¸à¸›à¸à¸´à¹€à¸ªà¸˜</translation>
<translation id="2653659639078652383">ส่ง</translation>
<translation id="2666117266261740852">ปิดà¹à¸—็บหรือà¹à¸­à¸›à¸­à¸·à¹ˆà¸™à¹†</translation>
+<translation id="2670429602441959756">หน้านี้มีฟีเจอร์ที่ยังไม่รองรับใน VR à¸à¸³à¸¥à¸±à¸‡à¸­à¸­à¸à¸ˆà¸²à¸à¹‚หมดนี้...</translation>
<translation id="2674170444375937751">คุณà¹à¸™à¹ˆà¹ƒà¸ˆà¸«à¸£à¸·à¸­à¹„ม่ว่าต้องà¸à¸²à¸£à¸™à¸³à¸­à¸­à¸à¸«à¸™à¹‰à¸²à¹€à¸«à¸¥à¹ˆà¸²à¸™à¸µà¹‰à¸­à¸­à¸à¸ˆà¸²à¸à¸›à¸£à¸°à¸§à¸±à¸•à¸´à¸à¸²à¸£à¹€à¸‚้าชมของคุณ</translation>
<translation id="2677748264148917807">ออà¸</translation>
-<translation id="269990154133806163">เซิร์ฟเวอร์à¹à¸ªà¸”งใบรับรองที่ไม่เปิดเผยต่อสาธารณะโดยใช้นโยบายความโปร่งใสของใบรับรอง นี่เป็นข้อà¸à¸³à¸«à¸™à¸”สำหรับใบรับรองบางรายà¸à¸²à¸£ เพื่อให้à¹à¸™à¹ˆà¹ƒà¸ˆà¹„ด้ว่าใบรับรองมีความน่าเชื่อถือà¹à¸¥à¸°à¸›à¹‰à¸­à¸‡à¸à¸±à¸™à¸œà¸¹à¹‰à¹‚จมตีได้ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">รายà¸à¸²à¸£à¸—ี่จะอ่าน</translation>
<translation id="2704283930420550640">ค่าไม่ตรงà¸à¸±à¸šà¸£à¸¹à¸›à¹à¸šà¸š</translation>
<translation id="2704951214193499422">Chromium ไม่สามารถยืนยันบัตรของคุณได้ในขณะนี้ โปรดลองอีà¸à¸„รั้งในภายหลัง</translation>
<translation id="2705137772291741111">อ่านสำเนาที่บันทึà¸à¹„ว้ (à¹à¸„ช) ของเว็บไซต์นี้ไม่ได้</translation>
<translation id="2709516037105925701">ป้อนอัตโนมัติ</translation>
-<translation id="2712118517637785082">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸—ี่เซิร์ฟเวอร์à¹à¸ªà¸”งถูà¸à¹€à¸žà¸´à¸à¸–อนโดยผู้ออà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡ ซึ่งหมายความว่าข้อมูลรับรองด้านความปลอดภัยที่เซิร์ฟเวอร์à¹à¸ªà¸”งมานั้นไม่สามารถเชื่อถือได้ คุณอาจà¸à¸³à¸¥à¸±à¸‡à¸ªà¸·à¹ˆà¸­à¸ªà¸²à¸£à¸­à¸¢à¸¹à¹ˆà¸à¸±à¸šà¸œà¸¹à¹‰à¹‚จมตี <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">ขออนุà¸à¸²à¸•</translation>
<translation id="2713444072780614174">สีขาว</translation>
<translation id="2720342946869265578">ใà¸à¸¥à¹‰à¹€à¸„ียง</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ไม่มีอุปà¸à¸£à¸“์บันทึà¸</translation>
<translation id="2784949926578158345">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¹„ด้รับà¸à¸²à¸£à¸£à¸µà¹€à¸‹à¹‡à¸•à¹à¸¥à¹‰à¸§</translation>
<translation id="2794233252405721443">เว็บไซต์ที่ถูà¸à¸šà¸¥à¹‡à¸­à¸</translation>
+<translation id="2799020568854403057">ไซต์ที่จะเปิดมีà¹à¸­à¸›à¸­à¸±à¸™à¸•à¸£à¸²à¸¢</translation>
+<translation id="2803306138276472711">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />ตรวจพบมัลà¹à¸§à¸£à¹Œ<ph name="END_LINK" />ใน <ph name="SITE" /> เว็บไซต์ที่โดยปà¸à¸•à¸´à¸ˆà¸°à¸›à¸¥à¸­à¸”ภัยบางครั้งอาจติดมัลà¹à¸§à¸£à¹Œ</translation>
<translation id="2824775600643448204">ที่อยู่à¹à¸¥à¸°à¹à¸–บค้นหา</translation>
<translation id="2826760142808435982">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸–ูà¸à¹€à¸‚้ารหัสà¹à¸¥à¸°à¸£à¸±à¸šà¸£à¸­à¸‡à¸„วามถูà¸à¸•à¹‰à¸­à¸‡à¹‚ดยใช้ <ph name="CIPHER" /> à¹à¸¥à¸°à¹ƒà¸Šà¹‰ <ph name="KX" /> เป็นà¸à¸¥à¹„à¸à¸à¸²à¸£à¹à¸¥à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸„ีย์</translation>
<translation id="2835170189407361413">ล้างฟอร์ม</translation>
+<translation id="2856444702002559011">ผู้โจมตีอาจพยายามขโมยข้อมูลจาภ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (ตัวอย่างเช่น รหัสผ่าน ข้อความ หรือบัตรเครดิต) <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">อย่าโหลดซ้ำ</translation>
<translation id="2900469785430194048">Google Chrome หน่วยความจำเต็มเมื่อพยายามà¹à¸ªà¸”งหน้าเว็บนี้</translation>
<translation id="2909946352844186028">ตรวจพบà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹€à¸„รือข่าย</translation>
<translation id="2916038427272391327">ปิดโปรà¹à¸à¸£à¸¡à¸­à¸·à¹ˆà¸™à¹†</translation>
<translation id="2922350208395188000">ไม่สามารถตรวจสอบใบรับรองของเซิร์ฟเวอร์</translation>
<translation id="2928905813689894207">ที่อยู่สำหรับà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¹€à¸à¹‡à¸šà¹€à¸‡à¸´à¸™</translation>
+<translation id="2941952326391522266">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยมาจาภ<ph name="DOMAIN2" /> โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
<translation id="2948083400971632585">คุณสามารถปิดใช้งานพร็อà¸à¸‹à¸µà¸—ี่à¸à¸³à¸«à¸™à¸”ค่าสำหรับà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸ˆà¸²à¸à¸«à¸™à¹‰à¸²à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าได้</translation>
<translation id="2955913368246107853">ปิดà¹à¸–บค้นหา</translation>
<translation id="2958431318199492670">à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าเครือข่ายไม่เป็นไปตามมาตรà¸à¸²à¸™ ONC à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าบางส่วนอาจไม่ได้รับà¸à¸²à¸£à¸™à¸³à¹€à¸‚้า</translation>
-<translation id="29611076221683977">ผู้บุà¸à¸£à¸¸à¸à¸—ี่à¸à¸³à¸¥à¸±à¸‡à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจพยายามติดตั้งโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸‹à¸¶à¹ˆà¸‡à¸‚โมยหรือลบข้อมูล (ตัวอย่างเช่น รูปภาพ รหัสผ่าน ข้อความ à¹à¸¥à¸°à¸šà¸±à¸•à¸£à¹€à¸„รดิต) ลงในเครื่อง Mac ของคุณ</translation>
<translation id="2966678944701946121">วันที่หมดอายุ: <ph name="EXPIRATION_DATE_ABBR" /> วันที่เพิ่ม <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">หาà¸à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸—ี่ปลอดภัย คุณต้องตั้งค่านาฬิà¸à¸²à¹ƒà¸«à¹‰à¸–ูà¸à¸•à¹‰à¸­à¸‡à¹€à¸™à¸·à¹ˆà¸­à¸‡à¸ˆà¸²à¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸—ี่เว็บไซต์ใช้เพื่อระบุตัวตนจะใช้ได้ในช่วงเวลาที่เจาะจงเท่านั้น à¹à¸•à¹ˆà¹€à¸™à¸·à¹ˆà¸­à¸‡à¸ˆà¸²à¸à¸™à¸²à¸¬à¸´à¸à¸²à¸‚องอุปà¸à¸£à¸“์ไม่ถูà¸à¸•à¹‰à¸­à¸‡ Google Chrome จึงไม่สามารถยืนยันใบรับรองเหล่านี้</translation>
<translation id="2972581237482394796">&amp;ทำซ้ำ</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">ป้อนที่อยู่ที่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="2986368408720340940">วิธีà¸à¸²à¸£à¸£à¸±à¸šà¸ªà¸´à¸™à¸„้านี้ไม่พร้อมให้บริà¸à¸²à¸£ โปรดลองใช้วิธีà¸à¸²à¸£à¸­à¸·à¹ˆà¸™</translation>
<translation id="2991174974383378012">à¸à¸²à¸£à¹à¸Šà¸£à¹Œà¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์</translation>
+<translation id="2991571918955627853">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ใช้ HSTS โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจใช้งานได้ในภายหลัง</translation>
<translation id="3005723025932146533">à¹à¸ªà¸”งสำเนาที่บันทึà¸à¹„ว้</translation>
<translation id="3008447029300691911">ป้อน CVC สำหรับ <ph name="CREDIT_CARD" /> เมื่อยืนยันà¹à¸¥à¹‰à¸§ รายละเอียดบัตรของคุณจะà¹à¸Šà¸£à¹Œà¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์นี้</translation>
<translation id="3010559122411665027">รายà¸à¸²à¸£à¸—ี่เข้ามา "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">ถูà¸à¸šà¸¥à¹‡à¸­à¸à¹‚ดยอัตโนมัติ</translation>
<translation id="3024663005179499861">ประเภทนโยบายไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="3032412215588512954">คุณต้องà¸à¸²à¸£à¹‚หลดเว็บไซต์นี้ซ้ำใช่ไหม</translation>
<translation id="3037605927509011580">à¹à¸¢à¹ˆà¸ˆà¸±à¸‡!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{อย่างน้อย 1 รายà¸à¸²à¸£à¸šà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ที่ซิงค์}=1{1 รายà¸à¸²à¸£ (à¹à¸¥à¸°à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸šà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ที่ซิงค์)}other{# รายà¸à¸²à¸£ (à¹à¸¥à¸°à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸šà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ที่ซิงค์)}}</translation>
<translation id="3041612393474885105">ข้อมูลในใบรับรอง</translation>
<translation id="3063697135517575841">Chrome ไม่สามารถยืนยันบัตรของคุณได้ในขณะนี้ โปรดลองอีà¸à¸„รั้งในภายหลัง</translation>
<translation id="3064966200440839136">ออà¸à¸ˆà¸²à¸à¹‚หมดไม่ระบุตัวตนเพื่อชำระเงินผ่านà¹à¸­à¸›à¸žà¸¥à¸´à¹€à¸„ชันภายนอภดำเนินà¸à¸²à¸£à¸•à¹ˆà¸­à¹„หม</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{ไม่มี}=1{รหัสผ่าน 1 รายà¸à¸²à¸£}other{รหัสผ่าน # รายà¸à¸²à¸£}}</translation>
<translation id="3093245981617870298">คุณออฟไลน์อยู่</translation>
<translation id="3105172416063519923">รหัสสินทรัพย์:</translation>
<translation id="3109728660330352905">คุณไม่มีสิทธิ์ดูหน้านี้</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />ลองเรียà¸à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸§à¸´à¸™à¸´à¸ˆà¸‰à¸±à¸¢à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­<ph name="END_LINK" /></translation>
<translation id="3145945101586104090">à¸à¸²à¸£à¸–อดรหัสà¸à¸²à¸£à¸•à¸­à¸šà¸à¸¥à¸±à¸šà¸¥à¹‰à¸¡à¹€à¸«à¸¥à¸§</translation>
<translation id="3150653042067488994">ข้อผิดพลาดชั่วคราวของเซิร์ฟเวอร์</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">หน้าที่คุณดูในà¹à¸—็บไม่ระบุตัวตนจะไม่เà¸à¹‡à¸šà¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸›à¸£à¸°à¸§à¸±à¸•à¸´à¸à¸²à¸£à¹€à¸‚้าชมของเบราว์เซอร์ à¸à¸²à¸£à¸ˆà¸±à¸”เà¸à¹‡à¸šà¸„ุà¸à¸à¸µà¹‰ หรือประวัติà¸à¸²à¸£à¸„้นหาหลังจาà¸à¸—ี่คุณปิดà¹à¸—็บไม่ระบุตัวตนทั้งหมด à¹à¸•à¹ˆà¸ˆà¸°à¸¡à¸µà¸à¸²à¸£à¹€à¸à¹‡à¸šà¹„ฟล์ที่คุณดาวน์โหลดหรือบุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸—ี่คุณสร้างขึ้น</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">เà¸à¸²à¸°</translation>
+<translation id="317583078218509884">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าà¸à¸²à¸£à¸­à¸™à¸¸à¸à¸²à¸•à¹„ซต์ใหม่จะมีผลหลังจาà¸à¹‚หลดซ้ำหน้าเว็บนี้</translation>
<translation id="3176929007561373547">ตรวจสอบà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าพร็อà¸à¸‹à¸µà¸«à¸£à¸·à¸­à¸•à¸´à¸”ต่อผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¹€à¸„รือข่ายของคุณเพื่อ
ตรวจสอบว่าพร็อà¸à¸‹à¸µà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¸—ำงานอยู่ หาà¸à¸„ุณคิดว่าไม่ควร
ใช้พร็อà¸à¸‹à¸µà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œ ให้ดำเนินà¸à¸²à¸£à¸”ังนี้:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">เปิดหน้าในโหมดไม่ระบุตัวตน</translation>
-<translation id="3202578601642193415">ใหม่ที่สุด</translation>
+<translation id="320323717674993345">ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸Šà¸³à¸£à¸°à¹€à¸‡à¸´à¸™</translation>
<translation id="3207960819495026254">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¹à¸¥à¹‰à¸§</translation>
+<translation id="3225919329040284222">เซิร์ฟเวอร์à¹à¸ªà¸”งใบรับรองที่ไม่ตรงà¸à¸±à¸šà¸à¸²à¸£à¸„าดà¸à¸²à¸£à¸“์ที่มีอยู่ à¸à¸²à¸£à¸„าดà¸à¸²à¸£à¸“์เหล่านี้มีอยู่ในบางเว็บไซต์ที่มีà¸à¸²à¸£à¸£à¸±à¸à¸©à¸²à¸„วามปลอดภัยสูงเพื่อปà¸à¸›à¹‰à¸­à¸‡à¸„ุณ</translation>
<translation id="3226128629678568754">à¸à¸”ปุ่มโหลดซ้ำเพื่อส่งซ้ำข้อมูลที่จำเป็นในà¸à¸²à¸£à¹‚หลดหน้าเว็บ</translation>
+<translation id="3227137524299004712">ไมโครโฟน</translation>
<translation id="3228969707346345236">à¸à¸²à¸£à¹à¸›à¸¥à¸¥à¹‰à¸¡à¹€à¸«à¸¥à¸§à¹€à¸™à¸·à¹ˆà¸­à¸‡à¸ˆà¸²à¸à¸«à¸™à¹‰à¸²à¹€à¸§à¹‡à¸šà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸ à¸²à¸©à¸²<ph name="LANGUAGE" />อยู่à¹à¸¥à¹‰à¸§</translation>
<translation id="323107829343500871">ป้อน CVC สำหรับ <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">ตรวจหาเนื้อหาที่สำคัà¸à¸šà¸™à¹„ซต์นี้เสมอ</translation>
<translation id="3254409185687681395">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰</translation>
<translation id="3270847123878663523">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¸ˆà¸±à¸”ลำดับใหม่</translation>
<translation id="3282497668470633863">เพิ่มชื่อบนบัตร</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า</translation>
<translation id="3345135638360864351">ไม่สามารถส่งคำขอเข้าถึงไซต์นี้ไปยัง <ph name="NAME" /> ได้ โปรดลองอีà¸à¸„รั้ง</translation>
<translation id="3355823806454867987">เปลี่ยนà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าพร็อà¸à¸‹à¸µ...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />จะไม่บันทึà¸<ph name="END_EMPHASIS" />ข้อมูลต่อไปนี้:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />ประวัติà¸à¸²à¸£à¸—่องเว็บของคุณ
+ <ph name="LIST_ITEM" />คุà¸à¸à¸µà¹‰à¹à¸¥à¸°à¸‚้อมูลไซต์
+ <ph name="LIST_ITEM" />ข้อมูลที่à¸à¸£à¸­à¸à¹ƒà¸™à¸Ÿà¸­à¸£à¹Œà¸¡
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">ข้อผิดพลาดของนาฬิà¸à¸²</translation>
-<translation id="337311366426640088">à¹à¸¥à¸°à¸­à¸µà¸ <ph name="ITEM_COUNT" /> รายà¸à¸²à¸£...</translation>
<translation id="337363190475750230">ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸ˆà¸±à¸”เตรียมà¹à¸¥à¹‰à¸§</translation>
<translation id="3377188786107721145">ข้อผิดพลาดในà¸à¸²à¸£à¹à¸¢à¸à¸§à¸´à¹€à¸„ราะห์นโยบาย</translation>
<translation id="3380365263193509176">ข้อผิดพลาดที่ไม่รู้จัà¸</translation>
<translation id="3380864720620200369">รหัสลูà¸à¸„้า:</translation>
<translation id="3391030046425686457">ที่อยู่สำหรับจัดส่ง</translation>
<translation id="3395827396354264108">วิธีà¸à¸²à¸£à¸£à¸±à¸šà¸ªà¸´à¸™à¸„้า</translation>
-<translation id="340013220407300675">ผู้บุà¸à¸£à¸¸à¸à¸­à¸²à¸ˆà¸žà¸¢à¸²à¸¢à¸²à¸¡à¸‚โมยข้อมูลของคุณจาภ<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (ตัวอย่างเช่น รหัสผ่าน ข้อความ หรือบัตรเครดิต)</translation>
<translation id="3422248202833853650">ลองออà¸à¸ˆà¸²à¸à¹‚ปรà¹à¸à¸£à¸¡à¸­à¸·à¹ˆà¸™à¹† เพื่อเพิ่มหน่วยความจำ</translation>
<translation id="3422472998109090673">ไม่สามารถเข้าถึง <ph name="HOST_NAME" /> ได้ในขณะนี้</translation>
+<translation id="3427092606871434483">อนุà¸à¸²à¸• (ค่าเริ่มต้น)</translation>
<translation id="3427342743765426898">&amp;ทำซ้ำà¸à¸²à¸£à¹à¸à¹‰à¹„ข</translation>
<translation id="3431636764301398940">บันทึà¸à¸šà¸±à¸•à¸£à¸™à¸µà¹‰à¸¥à¸‡à¹ƒà¸™à¸­à¸¸à¸›à¸à¸£à¸“์นี้</translation>
<translation id="3435896845095436175">เปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™</translation>
<translation id="3447661539832366887">เจ้าของอุปà¸à¸£à¸“์นี้ปิดเà¸à¸¡à¹„ดโนเสาร์</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">ช่วงà¸à¸²à¸£à¸”ึงข้อมูล:</translation>
<translation id="3462200631372590220">ซ่อนข้อมูลขั้นสูง</translation>
<translation id="3467763166455606212">ต้องระบุชื่อผู้ถือบัตร</translation>
<translation id="3478058380795961209">เดือนที่หมดอายุ</translation>
<translation id="3479539252931486093">หาà¸à¹€à¸«à¸•à¸¸à¸à¸²à¸£à¸“์นี้ผิดปà¸à¸•à¸´ <ph name="BEGIN_LINK" />โปรดà¹à¸ˆà¹‰à¸‡à¹ƒà¸«à¹‰à¹€à¸£à¸²à¸—ราบ<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">ไม่ใช่ตอนนี้</translation>
-<translation id="348000606199325318">รหัสข้อขัดข้อง <ph name="CRASH_LOCAL_ID" /> (รหัสเซิร์ฟเวอร์: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">เราไม่สามารถติดต่อผู้ปà¸à¸„รองของคุณได้ในขณะนี้ โปรดลองอีà¸à¸„รั้ง</translation>
<translation id="3528171143076753409">ใบรับรองของเซิร์ฟเวอร์ไม่น่าเชื่อถือ</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{อย่างน้อย 1 รายà¸à¸²à¸£à¸šà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ที่ซิงค์}=1{1 รายà¸à¸²à¸£ (à¹à¸¥à¸°à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸šà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ที่ซิงค์)}other{# รายà¸à¸²à¸£ (à¹à¸¥à¸°à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸šà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ที่ซิงค์)}}</translation>
<translation id="3539171420378717834">เà¸à¹‡à¸šà¸ªà¸³à¹€à¸™à¸²à¸šà¸±à¸•à¸£à¸™à¸µà¹‰à¹„ว้บนอุปà¸à¸£à¸“์นี้</translation>
<translation id="3542684924769048008">ใช้รหัสผ่านสำหรับ:</translation>
+<translation id="3545341443414427877">ไม่สามารถสร้างà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸ªà¹ˆà¸§à¸™à¸•à¸±à¸§à¸à¸±à¸š <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> เนื่องจาà¸à¸§à¸±à¸™à¸—ี่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²à¸‚องคอมพิวเตอร์ (<ph name="DATE_AND_TIME" />) ไม่ถูà¸à¸•à¹‰à¸­à¸‡ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">เข้ารหัสข้อมูลที่ซิงค์ทั้งหมดด้วยข้อความรหัสผ่านà¸à¸²à¸£à¸‹à¸´à¸‡à¸„์ของคุณเอง</translation>
-<translation id="3549761410225185768">พร้อมใช้งานอีภ<ph name="NUM_TABS_MORE" /> à¹à¸—็บ</translation>
-<translation id="3555561725129903880">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยของเซิร์ฟเวอร์มาจาภ<ph name="DOMAIN2" /> สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">ผู้จัดà¸à¸²à¸£à¸ªà¸²à¸¡à¸²à¸£à¸–เลิà¸à¸šà¸¥à¹‡à¸­à¸à¹€à¸§à¹‡à¸šà¹„ซต์ให้คุณ</translation>
<translation id="3566021033012934673">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณไม่เป็นส่วนตัว</translation>
+<translation id="3569145463236695319">&lt;p&gt;ไม่สามารถสร้างà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸ªà¹ˆà¸§à¸™à¸•à¸±à¸§à¸à¸±à¸š <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> เนื่องจาà¸à¸§à¸±à¸™à¸—ี่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²à¸‚องอุปà¸à¸£à¸“์ (<ph name="DATE_AND_TIME" />) ไม่ถูà¸à¸•à¹‰à¸­à¸‡&lt;/p&gt;
+
+ &lt;p&gt;โปรดปรับวันที่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²à¸ˆà¸²à¸à¸ªà¹ˆà¸§à¸™&lt;strong&gt;ทั่วไป&lt;/strong&gt;ในà¹à¸­à¸›&lt;strong&gt;à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า&lt;/strong&gt;&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">เพิ่มชื่อ</translation>
<translation id="3583757800736429874">&amp;ทำซ้ำà¸à¸²à¸£à¸¢à¹‰à¸²à¸¢</translation>
<translation id="3586931643579894722">ซ่อนรายละเอียด</translation>
-<translation id="3587482841069643663">ทั้งหมด</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">ป้อนวันที่หมดอายุที่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="36224234498066874">ล้างข้อมูลà¸à¸²à¸£à¸—่องเว็บ</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">ข้อมูลในใบรับรอง</translation>
<translation id="3690164694835360974">à¸à¸²à¸£à¹€à¸‚้าสู่ระบบไม่ปลอดภัย</translation>
<translation id="3693415264595406141">รหัสผ่าน:</translation>
-<translation id="3696411085566228381">ไม่มี</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">à¸à¸³à¸¥à¸±à¸‡à¹‚หลด ...</translation>
<translation id="3712624925041724820">ใบอนุà¸à¸²à¸•à¸«à¸¡à¸”</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ตรวจสอบพร็อà¸à¸‹à¸µ ไฟร์วอลล์ à¹à¸¥à¸°à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่า DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">หาà¸à¸„ุณเข้าใจความเสี่ยงต่อความปลอดภัย คุณสามารถ<ph name="BEGIN_LINK" />ไปยังไซต์ที่ไม่ปลอดภัยนี้<ph name="END_LINK" /> à¸à¹ˆà¸­à¸™à¸ˆà¸°à¸¡à¸µà¸à¸²à¸£à¸™à¸³à¹‚ปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸­à¸­à¸</translation>
<translation id="3739623965217189342">ลิงà¸à¹Œà¸—ี่คุณคัดลอà¸à¸¡à¸²</translation>
+<translation id="3744899669254331632">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ได้ส่งข้อมูลรับรองที่มีà¸à¸²à¸£à¹à¸›à¸¥à¸‡à¸‚้อมูลซึ่ง Chromium ไม่สามารถดำเนินà¸à¸²à¸£à¹„ด้ ข้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีมัà¸à¸ˆà¸°à¹€à¸à¸´à¸”ขึ้นชั่วคราว ดังนั้นหน้านี้อาจจะใช้งานได้ในภายหลัง</translation>
+<translation id="3748148204939282805">ผู้โจมตีที่อยู่ใน <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจหลอà¸à¸¥à¹ˆà¸­à¹ƒà¸«à¹‰à¸„ุณทำบางสิ่งที่อันตราย เช่น à¸à¸²à¸£à¸•à¸´à¸”ตั้งซอฟต์à¹à¸§à¸£à¹Œà¸«à¸£à¸·à¸­à¹€à¸›à¸´à¸”เผยข้อมูลส่วนบุคคล (ตัวอย่างเช่น รหัสผ่าน หมายเลขโทรศัพท์ หรือบัตรเครดิต) <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">à¸à¸²à¸£à¹à¸›à¸¥à¸¥à¹‰à¸¡à¹€à¸«à¸¥à¸§à¹€à¸™à¸·à¹ˆà¸­à¸‡à¸ˆà¸²à¸à¸‚้อผิดพลาดของเซิร์ฟเวอร์</translation>
<translation id="3759461132968374835">คุณไม่ได้รายงานข้อขัดข้องเมื่อเร็วๆ นี้ ข้อขัดข้องที่เà¸à¸´à¸”ขึ้นเมื่อปิดใช้งานà¸à¸²à¸£à¸£à¸²à¸¢à¸‡à¸²à¸™à¸‚้อขัดข้อง จะไม่ปราà¸à¸à¸—ี่นี่</translation>
+<translation id="3778403066972421603">คุณต้องà¸à¸²à¸£à¸šà¸±à¸™à¸—ึà¸à¸šà¸±à¸•à¸£à¸™à¸µà¹‰à¸¥à¸‡à¹ƒà¸™à¸šà¸±à¸à¸Šà¸µ Google à¹à¸¥à¸°à¹ƒà¸™à¸­à¸¸à¸›à¸à¸£à¸“์นี้ไหม</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">หมดอายุ <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">หาà¸à¸„ุณใช้พร็อà¸à¸‹à¸µà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œ...</translation>
<translation id="3828924085048779000">ข้อความรหัสผ่านต้องไม่เว้นว่างไว้</translation>
-<translation id="3845539888601087042">à¸à¸³à¸¥à¸±à¸‡à¹à¸ªà¸”งประวัติà¸à¸²à¸£à¹€à¸‚้าชมจาà¸à¸­à¸¸à¸›à¸à¸£à¸“์ที่คุณลงชื่อเข้าใช้ <ph name="BEGIN_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LINK" /></translation>
<translation id="385051799172605136">à¸à¸¥à¸±à¸š</translation>
<translation id="3858027520442213535">อัปเดตวันที่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²</translation>
<translation id="3884278016824448484">ตัวชี้อุปà¸à¸£à¸“์ขัดà¹à¸¢à¹‰à¸‡à¸à¸±à¸™</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">ระบบส่งคำขอเข้าถึงเว็บไซต์นี้ของคุณให้ <ph name="NAME" /> à¹à¸¥à¹‰à¸§</translation>
<translation id="3890664840433101773">เพิ่มอีเมล</translation>
<translation id="3901925938762663762">บัตรหมดอายุ</translation>
-<translation id="3933571093587347751">{1,plural, =1{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ตั้งà¹à¸•à¹ˆà¸§à¸±à¸™à¸žà¸£à¸¸à¹ˆà¸‡à¸™à¸µà¹‰ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" />}other{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ในอีภ# วันข้างหน้า สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">โหลดเอà¸à¸ªà¸²à¸£ PDF ล้มเหลว</translation>
+<translation id="3945915738023014686">อัปโหลดรหัสรายงานข้อขัดข้อง <ph name="CRASH_ID" /> à¹à¸¥à¹‰à¸§ (รหัสข้อขัดข้องในเครื่อง: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยไม่ได้ระบุชื่อสำรองของหัวเรื่อง โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีที่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
<translation id="3963721102035795474">โหมดนัà¸à¸­à¹ˆà¸²à¸™</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{ไม่มี}=1{จาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ 1 à¹à¸«à¹ˆà¸‡ }other{จาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ # à¹à¸«à¹ˆà¸‡ }}</translation>
<translation id="397105322502079400">à¸à¸³à¸¥à¸±à¸‡à¸„ำนวณ...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> ถูà¸à¸šà¸¥à¹‡à¸­à¸</translation>
+<translation id="3987940399970879459">ไม่ถึง 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{มีหน้าเว็บ 1 หน้าใà¸à¸¥à¹‰à¹†}other{มีหน้าเว็บ # หน้าใà¸à¸¥à¹‰à¹†}}</translation>
<translation id="4021036232240155012">DNS คือบริà¸à¸²à¸£à¹€à¸„รือข่ายที่à¹à¸›à¸¥à¸Šà¸·à¹ˆà¸­à¸‚องเว็บไซต์เป็นที่อยู่อินเทอร์เน็ต</translation>
<translation id="4030383055268325496">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าพร็อà¸à¸‹à¸µà¸¡à¸µà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าให้ใช้ URL สคริปต์ .pac ไม่ใช่พร็อà¸à¸‹à¸µà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸šà¸šà¸„งที่</translation>
<translation id="4098354747657067197">เว็บไซต์ข้างหน้ามีà¸à¸²à¸£à¸«à¸¥à¸­à¸à¸¥à¸§à¸‡</translation>
<translation id="4103249731201008433">หมายเลขซีเรียลของอุปà¸à¸£à¸“์ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
+<translation id="410351446219883937">เล่นอัตโนมัติ</translation>
<translation id="4103763322291513355">ไปที่ &lt;strong&gt;chrome://policy&lt;/strong&gt; เพื่อดูรายà¸à¸²à¸£à¸‚อง URL ที่ไม่ได้รับอนุà¸à¸²à¸• à¹à¸¥à¸°à¸™à¹‚ยบายอื่นๆ ที่ผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¸‚องคุณบังคับใช้</translation>
-<translation id="4110615724604346410">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยของเซิร์ฟเวอร์มีข้อผิดพลาด สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">สีม่วงà¹à¸”ง</translation>
+<translation id="4116663294526079822">อนุà¸à¸²à¸•à¸šà¸™à¹„ซต์นี้เสมอ</translation>
<translation id="4117700440116928470">ขอบข่ายนโยบายไม่ได้รับà¸à¸²à¸£à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™</translation>
-<translation id="4118212371799607889">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chromium ไม่เชื่อถือใบรับรองความปลอดภัยของเซิร์ฟเวอร์นี้ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{อีภ1 รายà¸à¸²à¸£}other{อีภ# รายà¸à¸²à¸£}}</translation>
<translation id="4130226655945681476">ตรวจสอบสายเครือข่าย โมเด็ม à¹à¸¥à¸°à¹€à¸£à¸²à¹€à¸•à¸­à¸£à¹Œ</translation>
+<translation id="413544239732274901">เรียนรู้เพิ่มเติม</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">ใช้ค่าเริ่มต้นส่วนà¸à¸¥à¸²à¸‡ (ตรวจหา)</translation>
+<translation id="4165986682804962316">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าไซต์</translation>
<translation id="4169947484918424451">คุณต้องà¸à¸²à¸£à¹ƒà¸«à¹‰ Chromium บันทึà¸à¸šà¸±à¸•à¸£à¸™à¸µà¹‰à¹„หม</translation>
<translation id="4171400957073367226">ลายเซ็นยืนยันไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="4196861286325780578">&amp;ทำซ้ำà¸à¸²à¸£à¸¢à¹‰à¸²à¸¢</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ตรวจสอบไฟร์วอลล์à¹à¸¥à¸°à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าà¸à¸²à¸£à¸›à¹‰à¸­à¸‡à¸à¸±à¸™à¹„วรัส<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ไม่มี}=1{1 à¹à¸­à¸› ($1)}=2{2 à¹à¸­à¸› ($1, $2)}other{# à¹à¸­à¸› ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">à¸à¸²à¸£à¸‚ัดข้อง</translation>
+<translation id="422022731706691852">ผู้โจมตีที่อยู่ใน <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจพยายามหลอà¸à¸¥à¹ˆà¸­à¹ƒà¸«à¹‰à¸„ุณติดตั้งโปรà¹à¸à¸£à¸¡à¸—ี่ทำให้à¸à¸²à¸£à¸—่องเว็บเป็นเรื่องอันตราย (ตัวอย่างเช่น à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸«à¸™à¹‰à¸²à¹à¸£à¸à¸«à¸£à¸·à¸­à¸à¸²à¸£à¹à¸ªà¸”งโฆษณาเพิ่มเติมในไซต์ที่คุณเข้าชม) <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />ลองเรียà¸à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸§à¸´à¸™à¸´à¸ˆà¸‰à¸±à¸¢à¹€à¸„รือข่าย<ph name="END_LINK" /></translation>
+<translation id="4235360514405112390">ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="4250431568374086873">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์นี้ไม่ปลอดภัยโดยสมบูรณ์</translation>
<translation id="4250680216510889253">ไม่มี</translation>
<translation id="425582637250725228">ระบบอาจไม่ได้บันทึà¸à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸‚องคุณ</translation>
<translation id="4258748452823770588">ลายเซ็นไม่เหมาะสม</translation>
+<translation id="4265872034478892965">อนุà¸à¸²à¸•à¹‚ดยผู้ดูà¹à¸¥à¸£à¸°à¸šà¸š</translation>
<translation id="4269787794583293679">(ไม่มีชื่อผู้ใช้)</translation>
<translation id="4275830172053184480">รีสตาร์ทอุปà¸à¸£à¸“์ของคุณ</translation>
<translation id="4280429058323657511">หมดอายุ <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />พบโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢<ph name="END_LINK" />บน <ph name="SITE" /> <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">คำà¹à¸™à¸°à¸™à¸³à¸£à¸°à¸”ับบนสุด</translation>
<translation id="4304224509867189079">เข้าสู่ระบบ</translation>
-<translation id="432290197980158659">เซิร์ฟเวอร์à¹à¸ªà¸”งใบรับรองที่ไม่ตรงà¸à¸±à¸šà¸à¸²à¸£à¸„าดà¸à¸²à¸£à¸“์ที่มีอยู่ à¸à¸²à¸£à¸„าดà¸à¸²à¸£à¸“์เหล่านี้มีอยู่ในบางเว็บไซต์ที่มีà¸à¸²à¸£à¸£à¸±à¸à¸©à¸²à¸„วามปลอดภัยสูงเพื่อปà¸à¸›à¹‰à¸­à¸‡à¸„ุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">บล็อภ(ค่าเริ่มต้น)</translation>
<translation id="4325863107915753736">à¸à¸²à¸£à¸„้นหาบทความล้มเหลว</translation>
<translation id="4326324639298822553">ตรวจสอบวันหมดอายุà¹à¸¥à¹‰à¸§à¸¥à¸­à¸‡à¸­à¸µà¸à¸„รั้ง</translation>
<translation id="4331708818696583467">ไม่ปลอดภัย</translation>
<translation id="4356973930735388585">ผู้โจมตีในเว็บไซต์นี้อาจพยายามติดตั้งโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸‹à¸¶à¹ˆà¸‡à¸ˆà¸°à¸‚โมยหรือลบข้อมูล (ตัวอย่างเช่น รูปภาพ รหัสผ่าน ข้อความ à¹à¸¥à¸°à¸šà¸±à¸•à¸£à¹€à¸„รดิต) ลงในคอมพิวเตอร์ของคุณ</translation>
<translation id="4372948949327679948">ค่า <ph name="VALUE_TYPE" /> ที่คาดไว้</translation>
+<translation id="4377125064752653719">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸—ี่เซิร์ฟเวอร์à¹à¸ˆà¹‰à¸‡à¸¡à¸²à¸–ูà¸à¹€à¸žà¸´à¸à¸–อนโดยผู้ออà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡ ซึ่งหมายความว่าข้อมูลรับรองด้านความปลอดภัยที่เซิร์ฟเวอร์à¹à¸ˆà¹‰à¸‡à¸¡à¸²à¸™à¸±à¹‰à¸™à¹„ม่สามารถเชื่อถือได้ คุณอาจà¸à¸³à¸¥à¸±à¸‡à¸•à¸´à¸”ต่อà¸à¸±à¸šà¸„นที่คิดจะโจมตีคุณ</translation>
<translation id="4381091992796011497">ชื่อผู้ใช้:</translation>
<translation id="4394049700291259645">ปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™</translation>
<translation id="4406896451731180161">ผลà¸à¸²à¸£à¸„้นหา</translation>
+<translation id="4424024547088906515">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chrome ไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ไม่ยอมรับใบรับรองà¸à¸²à¸£à¹€à¸‚้าสู่ระบบหรือไม่ได้ให้ใบรับรองไว้</translation>
<translation id="443673843213245140">à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸žà¸£à¹‡à¸­à¸à¸‹à¸µà¸–ูà¸à¸›à¸´à¸”ใช้งาน à¹à¸•à¹ˆà¸¡à¸µà¸à¸²à¸£à¸£à¸°à¸šà¸¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าพร็อà¸à¸‹à¸µà¸­à¸¢à¹ˆà¸²à¸‡à¸Šà¸±à¸”เจน</translation>
-<translation id="4492190037599258964">ผลà¸à¸²à¸£à¸„้นหาคำว่า "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">ข้อผิดพลาดในà¸à¸²à¸£à¸•à¸£à¸§à¸ˆà¸ªà¸­à¸š: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">ติดต่อผู้ดูà¹à¸¥à¸£à¸°à¸šà¸š</translation>
<translation id="450710068430902550">à¸à¸²à¸£à¹à¸Šà¸£à¹Œà¸à¸±à¸šà¸œà¸¹à¹‰à¸”ูà¹à¸¥à¸£à¸°à¸šà¸š</translation>
<translation id="4515275063822566619">ข้อมูลบัตรà¹à¸¥à¸°à¸—ี่อยู่มาจาภChrome à¹à¸¥à¸°à¸šà¸±à¸à¸Šà¸µ Google (<ph name="ACCOUNT_EMAIL" />) คุณสามารถจัดà¸à¸²à¸£à¸‚้อมูลเหล่านี้ใน<ph name="BEGIN_LINK" />à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า<ph name="END_LINK" /></translation>
<translation id="4522570452068850558">รายละเอียด</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">ลองปิดใช้ส่วนขยาย</translation>
<translation id="457875822857220463">à¸à¸²à¸£à¸ˆà¸±à¸”ส่ง</translation>
<translation id="4587425331216688090">นำที่อยู่ออà¸à¸ˆà¸²à¸ Chrome ไหม</translation>
-<translation id="4589078953350245614">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸ªà¸”งใบรับรองที่ไม่ถูà¸à¸•à¹‰à¸­à¸‡ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">มีà¸à¸²à¸£à¹€à¸‚้ารหัสà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณà¸à¸±à¸š <ph name="DOMAIN" /> ด้วยชุดà¸à¸²à¸£à¹€à¸‚้ารหัสที่ทันสมัย</translation>
<translation id="4594403342090139922">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¸™à¸³à¸­à¸­à¸</translation>
<translation id="4619615317237390068">à¹à¸—็บจาà¸à¸­à¸¸à¸›à¸à¸£à¸“์อื่นๆ</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยมีข้อผิดพลาด โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
+<translation id="4690462567478992370">หยุดใช้ใบรับรองที่ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณขัดข้อง</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />เรียà¸à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸§à¸´à¸™à¸´à¸ˆà¸‰à¸±à¸¢à¹€à¸„รือข่ายของ Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">มีข้อผิดพลาดที่ไม่ทราบเà¸à¸´à¸”ขึ้น</translation>
<translation id="4800132727771399293">ตรวจสอบวันหมดอายุà¹à¸¥à¸° CVC à¹à¸¥à¹‰à¸§à¸¥à¸­à¸‡à¸­à¸µà¸à¸„รั้ง</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้ เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ดังà¸à¸¥à¹ˆà¸²à¸§à¸ªà¹ˆà¸‡à¸‚้อมูลรับรองที่เข้ารหัส ซึ่ง Google Chrome ไม่สามารถประมวลผลได้ โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¸šà¸¸à¸à¸£à¸¸à¸à¸ˆà¸°à¹€à¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจใช้งานได้ในภายหลัง</translation>
<translation id="4813512666221746211">ข้อผิดพลาดของเครือข่าย</translation>
<translation id="4816492930507672669">พอดีà¸à¸±à¸šà¸«à¸™à¹‰à¸²</translation>
<translation id="483020001682031208">ไม่มีหน้า Physical Web ที่จะà¹à¸ªà¸”ง</translation>
<translation id="4850886885716139402">มุมมอง</translation>
<translation id="4854362297993841467">วิธีà¸à¸²à¸£à¸™à¸³à¸ªà¹ˆà¸‡à¸ªà¸´à¸™à¸„้านี้ไม่พร้อมให้บริà¸à¸²à¸£ โปรดลองใช้วิธีà¸à¸²à¸£à¸­à¸·à¹ˆà¸™</translation>
<translation id="4858792381671956233">คุณถามผู้ปà¸à¸„รองà¹à¸¥à¹‰à¸§à¸§à¹ˆà¸²à¸ªà¸²à¸¡à¸²à¸£à¸–เข้าชมเว็บไซต์นี้ได้ไหม</translation>
+<translation id="4863764087567530506">เนื้อหานี้อาจลองล่อลวงให้คุณติดตั้งซอฟต์à¹à¸§à¸£à¹Œà¸«à¸£à¸·à¸­à¹€à¸›à¸´à¸”เผยข้อมูลส่วนบุคคล <ph name="BEGIN_LINK" />à¹à¸ªà¸”งเนื้อหา<ph name="END_LINK" /></translation>
<translation id="4880827082731008257">ค้นประวัติà¸à¸²à¸£à¹€à¸‚้าชม</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> à¹à¸¥à¸° <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{à¹à¸¥à¸°à¸«à¸™à¹‰à¸²à¹€à¸§à¹‡à¸šà¸­à¸µà¸ 1 หน้า}other{à¹à¸¥à¸°à¸«à¸™à¹‰à¸²à¹€à¸§à¹‡à¸šà¸­à¸µà¸ # หน้า}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">หน้านี้à¹à¸›à¸¥à¸ˆà¸²à¸à¸ à¸²à¸©à¸²à¸—ี่ไม่รู้จัà¸à¹€à¸›à¹‡à¸™à¸ à¸²à¸©à¸² <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">à¸à¸²à¸£à¸Šà¸³à¸£à¸°à¹€à¸‡à¸´à¸™</translation>
<translation id="4926049483395192435">ต้องระบุ</translation>
<translation id="495170559598752135">à¸à¸²à¸£à¸—ำงาน</translation>
<translation id="4958444002117714549">ขยายรายà¸à¸²à¸£</translation>
-<translation id="4962322354953122629">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chrome ไม่เชื่อถือใบรับรองความปลอดภัยของเซิร์ฟเวอร์นี้ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">เปิดใช้คำเตือนอีà¸à¸„รั้ง</translation>
<translation id="4989809363548539747">ไม่รองรับปลั๊à¸à¸­à¸´à¸™à¸™à¸µà¹‰</translation>
<translation id="5002932099480077015">หาà¸à¹€à¸›à¸´à¸”ใช้ Chrome จะเà¸à¹‡à¸šà¸ªà¸³à¹€à¸™à¸²à¸à¸²à¸£à¹Œà¸”ของคุณในอุปà¸à¸£à¸“์นี้เพื่อให้à¸à¸²à¸£à¸à¸£à¸­à¸à¸Ÿà¸­à¸£à¹Œà¸¡à¸—ำได้เร็วขึ้น</translation>
<translation id="5018422839182700155">ไม่สามารถเปิดหน้านี้</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">ตรวจสอบนโยบายของผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¸‚องคุณ</translation>
<translation id="5029568752722684782">ล้างสำเนา</translation>
<translation id="5031870354684148875">เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸š Google à¹à¸›à¸¥à¸ à¸²à¸©à¸²</translation>
+<translation id="5039804452771397117">อนุà¸à¸²à¸•</translation>
<translation id="5040262127954254034">ความเป็นส่วนตัว</translation>
<translation id="5045550434625856497">รหัสผ่านไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="5056549851600133418">บทความสำหรับคุณ</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />ตรวจสอบที่อยู่พร็อà¸à¸‹à¸µ<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{ไม่มีคุà¸à¸à¸µà¹‰}=1{1 เว็บไซต์ใช้คุà¸à¸à¸µà¹‰ }other{# เว็บไซต์ใช้คุà¸à¸à¸µà¹‰ }}</translation>
<translation id="5087286274860437796">ใบรับรองของเซิร์ฟเวอร์ไม่สามารถใช้ได้ในขณะนี้</translation>
<translation id="5087580092889165836">เพิ่มบัตร</translation>
<translation id="5089810972385038852">รัà¸</translation>
+<translation id="5094747076828555589">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chromium ไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
<translation id="5095208057601539847">จังหวัด</translation>
<translation id="5115563688576182185">(64 บิต)</translation>
<translation id="5141240743006678641">เข้ารหัสผ่านที่ซิงค์ด้วยข้อมูลรับรอง Google ของคุณ</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">ต้องระบุอีเมล</translation>
<translation id="5251803541071282808">ระบบคลาวด์</translation>
<translation id="5277279256032773186">หาà¸à¹ƒà¸Šà¹‰ Chrome ที่ทำงาน ธุรà¸à¸´à¸ˆà¸ªà¸²à¸¡à¸²à¸£à¸–จัดà¸à¸²à¸£à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า Chrome ให้พนัà¸à¸‡à¸²à¸™à¸‚องตนได้ เรียนรู้เพิ่มเติม</translation>
+<translation id="5297526204711817721">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์นี้ไม่เป็นส่วนตัว หาà¸à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸­à¸­à¸à¸ˆà¸²à¸à¹‚หมด VR ในเวลาใดà¸à¹‡à¸•à¸²à¸¡ ให้นำอุปà¸à¸£à¸“์สวมศีรษะออภà¹à¸¥à¹‰à¸§à¸à¸” "à¸à¸¥à¸±à¸š"</translation>
<translation id="5299298092464848405">ข้อผิดพลาดในà¸à¸²à¸£à¹à¸¢à¸à¸§à¸´à¹€à¸„ราะห์นโยบาย</translation>
-<translation id="5300589172476337783">à¹à¸ªà¸”ง</translation>
<translation id="5308689395849655368">à¸à¸²à¸£à¸£à¸²à¸¢à¸‡à¸²à¸™à¸‚้อขัดข้องถูà¸à¸›à¸´à¸”ใช้งาน</translation>
<translation id="5317780077021120954">บันทึà¸</translation>
<translation id="5327248766486351172">ชื่อ</translation>
-<translation id="5337705430875057403">ผู้บุà¸à¸£à¸¸à¸à¸—ี่อยู่ใน <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจหลอà¸à¸¥à¹ˆà¸­à¸„ุณเพื่อทำบางสิ่งที่อันตราย เช่น à¸à¸²à¸£à¸•à¸´à¸”ตั้งซอฟต์à¹à¸§à¸£à¹Œà¸«à¸£à¸·à¸­à¹€à¸›à¸´à¸”เผยข้อมูลส่วนบุคคล (ตัวอย่างเช่น รหัสผ่าน หมายเลขโทรศัพท์ หรือบัตรเครดิต)</translation>
-<translation id="5359637492792381994">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยของเซิร์ฟเวอร์ใช้ไม่ได้ในขณะนี้ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้เนื่องจาà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸–ูà¸à¹€à¸žà¸´à¸à¸–อนà¹à¸¥à¹‰à¸§ โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจจะใช้งานได้ในภายหลัง</translation>
<translation id="536296301121032821">ไม่สามารถจัดเà¸à¹‡à¸šà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่านโยบาย</translation>
<translation id="5386426401304769735">à¸à¸¥à¸¸à¹ˆà¸¡à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์นี้มีใบรับรองที่ลงนามโดยใช้ SHA-1</translation>
<translation id="5402410679244714488">วันที่หมดอายุ: <ph name="EXPIRATION_DATE_ABBR" /> ใช้ล่าสุดà¸à¸§à¹ˆà¸² 1 ปีที่ผ่านมา</translation>
+<translation id="540969355065856584">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เนื่องจาà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸„วามปลอดภัยไม่สามารถใช้ได้ในขณะนี้ ซึ่งอาจเป็นเพราะà¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าที่ไม่ถูà¸à¸•à¹‰à¸­à¸‡à¸«à¸£à¸·à¸­à¸¡à¸µà¸œà¸¹à¹‰à¹‚จมตีที่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
<translation id="5421136146218899937">ล้างข้อมูลà¸à¸²à¸£à¸—่องเว็บ...</translation>
<translation id="5430298929874300616">นำบุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸­à¸­à¸</translation>
<translation id="5431657950005405462">ไม่พบไฟล์ของคุณ</translation>
-<translation id="5435775191620395718">à¸à¸³à¸¥à¸±à¸‡à¹à¸ªà¸”งประวัติà¸à¸²à¸£à¹€à¸‚้าชมจาà¸à¸­à¸¸à¸›à¸à¸£à¸“์นี้ <ph name="BEGIN_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">ข้อผิดพลาดในà¸à¸²à¸£à¸•à¸£à¸§à¸ˆà¸ªà¸­à¸šà¸£à¸¹à¸›à¹à¸šà¸šà¸—ี่ "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">ไม่พบหน้า <ph name="HOST_NAME" /> นี้</translation>
<translation id="5455374756549232013">เวลาบันทึà¸à¸‚องนโยบายไม่เหมาะสม</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> ของ <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="5470861586879999274">&amp;ทำซ้ำà¸à¸²à¸£à¹à¸à¹‰à¹„ข</translation>
<translation id="54817484435770891">เพิ่มที่อยู่ที่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="5492298309214877701">เว็บไซต์นี้บนอินทราเน็ตของบริษัท องค์à¸à¸£ หรือโรงเรียนมี URL เหมือนà¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์ภายนอà¸
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">ไม่สามารถรับสินค้าจาà¸à¸—ี่อยู่นี้ โปรดเลือà¸à¸—ี่อยู่อื่น</translation>
<translation id="5572851009514199876">โปรดเปิดà¹à¸¥à¸°à¸¥à¸‡à¸Šà¸·à¹ˆà¸­à¹€à¸‚้าใช้ Chrome เพื่อให้ Chrome ตรวจสอบได้ว่าคุณได้รับอนุà¸à¸²à¸•à¹ƒà¸«à¹‰à¹€à¸‚้าถึงไซต์นี้หรือไม่</translation>
<translation id="5580958916614886209">ตรวจสอบเดือนหมดอายุà¹à¸¥à¹‰à¸§à¸¥à¸­à¸‡à¸­à¸µà¸à¸„รั้ง</translation>
+<translation id="5586446728396275693">ไม่มีที่อยู่ที่บันทึà¸à¹„ว้</translation>
+<translation id="5595485650161345191">à¹à¸à¹‰à¹„ขที่อยู่</translation>
<translation id="560412284261940334">ไม่สนับสนุนà¸à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£</translation>
<translation id="5610142619324316209">ตรวจสอบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­</translation>
<translation id="5610807607761827392">คุณสามารถจัดà¸à¸²à¸£à¸šà¸±à¸•à¸£à¹à¸¥à¸°à¸—ี่อยู่ใน<ph name="BEGIN_LINK" />à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า<ph name="END_LINK" /></translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">คุณต้องà¸à¸²à¸£à¸­à¸­à¸à¸ˆà¸²à¸à¹€à¸§à¹‡à¸šà¹„ซต์นี้ใช่ไหม</translation>
<translation id="5629630648637658800">ไม่สามารถโหลดà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่านโยบาย</translation>
<translation id="5631439013527180824">โทเค็นà¸à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£à¸­à¸¸à¸›à¸à¸£à¸“์ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
+<translation id="5633066919399395251">ผู้โจมตีที่à¸à¸³à¸¥à¸±à¸‡à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจพยายามติดตั้งโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸‹à¸¶à¹ˆà¸‡à¸ˆà¸°à¸‚โมยหรือลบข้อมูล (ตัวอย่างเช่น รูปภาพ รหัสผ่าน ข้อความ à¹à¸¥à¸°à¸šà¸±à¸•à¸£à¹€à¸„รดิต) ลงในคอมพิวเตอร์ของคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">ตำà¹à¸«à¸™à¹ˆà¸‡</translation>
+<translation id="5659593005791499971">อีเมล</translation>
<translation id="5669703222995421982">รับเนื้อหาที่ปรับเปลี่ยนในà¹à¸šà¸šà¸‚องคุณ</translation>
<translation id="5675650730144413517">หน้านี้ใช้ไม่ได้</translation>
-<translation id="5677928146339483299">ถูà¸à¸šà¸¥à¹‡à¸­à¸</translation>
-<translation id="5694783966845939798">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸ªà¸”งใบรับรองที่ลงนามด้วยอัลà¸à¸­à¸£à¸´à¸—ึมลายเซ็นที่ไม่รัดà¸à¸¸à¸¡ (เช่น SHA-1) ซึ่งหมายความว่าข้อมูลรับรองด้านความปลอดภัยที่เซิร์ฟเวอร์à¹à¸ªà¸”งอาจถูà¸à¸›à¸¥à¸­à¸¡à¹à¸›à¸¥à¸‡à¸‚ึ้น à¹à¸¥à¸°à¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¸”ังà¸à¸¥à¹ˆà¸²à¸§à¸­à¸²à¸ˆà¹„ม่ใช่เซิร์ฟเวอร์ที่คุณคิด (คุณอาจà¸à¸³à¸¥à¸±à¸‡à¸•à¸´à¸”ต่อà¸à¸±à¸šà¸œà¸¹à¹‰à¹‚จมตี) <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5710435578057952990">ข้อมูลประจำตัวของเว็บไซต์นี้ยังไม่ได้รับà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™</translation>
+<translation id="5713016350996637505">บล็อà¸à¹€à¸™à¸·à¹‰à¸­à¸«à¸²à¸—ี่หลอà¸à¸¥à¸§à¸‡à¹à¸¥à¹‰à¸§</translation>
<translation id="5720705177508910913">ผู้ใช้ปัจจุบัน</translation>
<translation id="5732392974455271431">ผู้ปà¸à¸„รองสามารถเลิà¸à¸šà¸¥à¹‡à¸­à¸à¹€à¸§à¹‡à¸šà¹„ซต์ให้คุณ</translation>
<translation id="5763042198335101085">ป้อนที่อยู่อีเมลที่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="5765072501007116331">หาà¸à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸”ูวิธีà¸à¸²à¸£à¸™à¸³à¸ªà¹ˆà¸‡à¸ªà¸´à¸™à¸„้าà¹à¸¥à¸°à¸‚้อà¸à¸³à¸«à¸™à¸” โปรดเลือà¸à¸—ี่อยู่</translation>
+<translation id="5778550464785688721">à¸à¸²à¸£à¸„วบคุมอุปà¸à¸£à¸“์ MIDI เต็มรูปà¹à¸šà¸š</translation>
<translation id="5784606427469807560">เà¸à¸´à¸”ปัà¸à¸«à¸²à¹ƒà¸™à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸šà¸±à¸•à¸£à¸‚องคุณ โปรดตรวจสอบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸­à¸´à¸™à¹€à¸—อร์เน็ตà¹à¸¥à¸°à¸¥à¸­à¸‡à¸­à¸µà¸à¸„รั้ง</translation>
<translation id="5785756445106461925">นอà¸à¸ˆà¸²à¸à¸™à¸µà¹‰ หน้านี้ประà¸à¸­à¸šà¸”้วยทรัพยาà¸à¸£à¸­à¸·à¹ˆà¸™à¹† ซึ่งไม่ปลอดภัย ผู้อื่นสามารถดูทรัพยาà¸à¸£à¹€à¸«à¸¥à¹ˆà¸²à¸™à¸µà¹‰à¸‚ณะถ่ายโอน à¹à¸¥à¸°à¸œà¸¹à¹‰à¸šà¸¸à¸à¸£à¸¸à¸à¸ªà¸²à¸¡à¸²à¸£à¸–à¹à¸à¹‰à¹„ขเพื่อเปลี่ยนรูปลัà¸à¸©à¸“์ของหน้าได้</translation>
<translation id="5786044859038896871">คุณต้องà¸à¸²à¸£à¸à¸£à¸­à¸à¸‚้อมูลบัตรไหม</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;ทำซ้ำà¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡</translation>
<translation id="5814352347845180253">คุณอาจสูà¸à¹€à¸ªà¸µà¸¢à¸ªà¸´à¸—ธิ์à¸à¸²à¸£à¹€à¸‚้าถึงเนื้อหาระดับพรีเมียมจาภ<ph name="SITE" /> à¹à¸¥à¸°à¹€à¸§à¹‡à¸šà¹„ซต์อื่นๆ บางà¹à¸«à¹ˆà¸‡</translation>
<translation id="5838278095973806738">คุณไม่ควรป้อนข้อมูลที่ละเอียดอ่อนบนเว็บไซต์นี้ (ตัวอย่างเช่น รหัสผ่านหรือบัตรเครดิต) เนื่องจาà¸à¸œà¸¹à¹‰à¹‚จมตีอาจขโมยข้อมูลดังà¸à¸¥à¹ˆà¸²à¸§à¹„ปได้</translation>
-<translation id="5843436854350372569">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸ªà¸”งใบรับรองที่มีคีย์ที่ไม่รัดà¸à¸¸à¸¡ ผู้โจมตีอาจทำให้คีย์ส่วนตัวเสียหายไปà¹à¸¥à¹‰à¸§à¹à¸¥à¸°à¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¸™à¸µà¹‰à¸­à¸²à¸ˆà¹„ม่ใช่เซิร์ฟเวอร์ที่คุณคิด (คุณอาจà¸à¸³à¸¥à¸±à¸‡à¸•à¸´à¸”ต่อà¸à¸±à¸šà¸œà¸¹à¹‰à¹‚จมตี) <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">ไม่สามารถเข้าถึงเว็บไซต์นี้</translation>
<translation id="5869522115854928033">รหัสผ่านที่บันทึà¸à¹„ว้</translation>
<translation id="5872918882028971132">คำà¹à¸™à¸°à¸™à¸³à¸£à¸°à¸”ับบนสุด</translation>
<translation id="5901630391730855834">สีเหลือง</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (ซิงค์à¹à¸¥à¹‰à¸§)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ใช้งานอยู่ 1 รายà¸à¸²à¸£}other{ใช้งานอยู่ # รายà¸à¸²à¸£}}</translation>
<translation id="5926846154125914413">คุณอาจสูà¸à¹€à¸ªà¸µà¸¢à¸ªà¸´à¸—ธิ์à¸à¸²à¸£à¹€à¸‚้าถึงเนื้อหาระดับพรีเมียมจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์บางà¹à¸«à¹ˆà¸‡</translation>
<translation id="5959728338436674663">ส่ง<ph name="BEGIN_WHITEPAPER_LINK" />ข้อมูลบางอย่างของระบบà¹à¸¥à¸°à¹€à¸™à¸·à¹‰à¸­à¸«à¸²à¸‚องหน้าเว็บ<ph name="END_WHITEPAPER_LINK" />ไปยัง Google เพื่อช่วยตรวจหาà¹à¸­à¸›à¹à¸¥à¸°à¹€à¸§à¹‡à¸šà¹„ซต์ที่เป็นอันตรายโดยอัตโนมัติ<ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">สัปดาห์</translation>
<translation id="5967867314010545767">ลบจาà¸à¸›à¸£à¸°à¸§à¸±à¸•à¸´à¸à¸²à¸£à¹€à¸‚้าชม</translation>
<translation id="5975083100439434680">ย่อ</translation>
<translation id="598637245381783098">ไม่สามารถเปิดà¹à¸­à¸›à¸à¸²à¸£à¸Šà¸³à¸£à¸°à¹€à¸‡à¸´à¸™</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{หน้า 1}other{หน้า #}}</translation>
<translation id="6017514345406065928">สีเขียว</translation>
+<translation id="6017850046339264347">ผู้โจมตี <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> สามารถติดตั้งà¹à¸­à¸›à¸—ี่หลอà¸à¸¥à¸§à¸‡à¸‹à¸¶à¹ˆà¸‡à¸›à¸¥à¸­à¸¡à¹€à¸›à¹‡à¸™à¹€à¸™à¸·à¹‰à¸­à¸«à¸²à¸­à¸¢à¹ˆà¸²à¸‡à¸­à¸·à¹ˆà¸™à¸«à¸£à¸·à¸­à¸£à¸§à¸šà¸£à¸§à¸¡à¸‚้อมูลที่อาจนำไปใช้ติดตามคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" /> <ph name="TYPE_2" /> <ph name="TYPE_3" /> (ซิงค์à¹à¸¥à¹‰à¸§)</translation>
<translation id="6027201098523975773">ป้อนชื่อ</translation>
<translation id="6040143037577758943">ปิด</translation>
<translation id="6042308850641462728">เพิ่มเติม</translation>
+<translation id="6047233362582046994">หาà¸à¸„ุณเข้าใจความเสี่ยงต่อความปลอดภัย คุณสามารถ<ph name="BEGIN_LINK" />ไปยังไซต์นี้<ph name="END_LINK" />à¸à¹ˆà¸­à¸™à¸—ี่จะมีà¸à¸²à¸£à¸™à¸³à¹à¸­à¸›à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸­à¸­à¸</translation>
+<translation id="6051221802930200923">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ใช้à¸à¸²à¸£à¸•à¸£à¸¶à¸‡à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡ โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจใช้งานได้ในภายหลัง</translation>
<translation id="6060685159320643512">ระวัง à¸à¸²à¸£à¸—ดลองนี้อาจเป็นอันตราย</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ไม่มี}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">คุณเข้าถึงเนื้อหาโดยใช้ใบรับรองที่ผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¸­à¸­à¸à¹ƒà¸«à¹‰ ข้อมูลที่คุณให้à¸à¸±à¸š <ph name="DOMAIN" /> อาจถูà¸à¸ªà¸à¸±à¸”à¸à¸±à¹‰à¸™à¹‚ดยผู้ดูà¹à¸¥à¸£à¸°à¸šà¸š</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{ไม่มี}=1{รหัสผ่าน (ที่ซิงค์) 1 รายà¸à¸²à¸£}other{รหัสผ่าน (ที่ซิงค์) # รายà¸à¸²à¸£}}</translation>
<translation id="6146055958333702838">ตรวจสายเคเบิลà¹à¸¥à¸°à¸£à¸µà¸šà¸¹à¸•à¹€à¸£à¸²à¹€à¸•à¸­à¸£à¹Œ โมเด็ม หรืออุปà¸à¸£à¸“์เครือข่ายอื่น
ที่คุณอาจใช้งานอยู่</translation>
<translation id="614940544461990577">ลอง:</translation>
<translation id="6151417162996330722">ใบรับรองเซิร์ฟเวอร์มีระยะเวลาที่สามารถใช้ได้นานเà¸à¸´à¸™à¹„ป</translation>
<translation id="6157877588268064908">หาà¸à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸”ูวิธีà¸à¸²à¸£à¸ˆà¸±à¸”ส่งสินค้าà¹à¸¥à¸°à¸‚้อà¸à¸³à¸«à¸™à¸” โปรดเลือà¸à¸—ี่อยู่</translation>
+<translation id="6158003235852588289">เมื่อเร็วๆ นี้ Google Safe Browsing ตรวจพบฟิชชิงใน <ph name="SITE" /> ไซต์ฟิชชิงปลอมเป็นเว็บไซต์อื่นๆ เพื่อหลอà¸à¸„ุณ</translation>
<translation id="6165508094623778733">เรียนรู้เพิ่มเติม</translation>
+<translation id="6169916984152623906">ขณะนี้คุณสามารถท่องเว็บà¹à¸šà¸šà¹€à¸›à¹‡à¸™à¸ªà¹ˆà¸§à¸™à¸•à¸±à¸§ à¹à¸¥à¸°à¸œà¸¹à¹‰à¸­à¸·à¹ˆà¸™à¸—ี่ใช้อุปà¸à¸£à¸“์เครื่องนี้จะไม่เห็นà¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¸‚องคุณ à¹à¸•à¹ˆà¸ˆà¸°à¸¡à¸µà¸à¸²à¸£à¸šà¸±à¸™à¸—ึà¸à¸à¸²à¸£à¸”าวน์โหลดà¹à¸¥à¸°à¸šà¸¸à¹Šà¸à¸¡à¸²à¸£à¹Œà¸à¹„ว้</translation>
<translation id="6177128806592000436">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์นี้ไม่ปลอดภัย</translation>
<translation id="6184817833369986695">(รุ่น: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">ตรวจสอบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸­à¸´à¸™à¹€à¸—อร์เน็ต</translation>
<translation id="6218753634732582820">ต้องà¸à¸²à¸£à¸™à¸³à¸—ี่อยู่ออà¸à¸ˆà¸²à¸ Chromium ใช่ไหม</translation>
+<translation id="6221345481584921695">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />ตรวจพบมัลà¹à¸§à¸£à¹Œ<ph name="END_LINK" />ใน <ph name="SITE" /> เว็บไซต์ที่โดยปà¸à¸•à¸´à¸ˆà¸°à¸›à¸¥à¸­à¸”ภัยบางครั้งอาจติดมัลà¹à¸§à¸£à¹Œ เนื้อหาที่เป็นอันตรายมาจาภ<ph name="SUBRESOURCE_HOST" /> ซึ่งเป็นผู้เผยà¹à¸žà¸£à¹ˆà¸¡à¸±à¸¥à¹à¸§à¸£à¹Œà¸—ี่เป็นที่รู้จัà¸</translation>
<translation id="6251924700383757765">นโยบายความเป็นส่วนตัว</translation>
<translation id="6254436959401408446">หน่วยความจำไม่เพียงพอที่จะเปิดหน้านี้</translation>
<translation id="625755898061068298">คุณเลือà¸à¸›à¸´à¸”ใช้คำเตือนด้านความปลอดภัยของเว็บไซต์นี้</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">à¹à¸à¹‰à¹„ขบุ๊à¸à¸¡à¸²à¸£à¹Œà¸</translation>
<translation id="6410264514553301377">ป้อนวันหมดอายุà¹à¸¥à¸° CVC ของ <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">คุณถามผู้ปà¸à¸„รองà¹à¸¥à¹‰à¸§à¸§à¹ˆà¸²à¸ªà¸²à¸¡à¸²à¸£à¸–เข้าชมเว็บไซต์นี้ได้ไหม</translation>
-<translation id="6416403317709441254">คุณไม่สามารถเข้าชม <ph name="SITE" /> ได้ในขณะนี้ เนื่องจาà¸à¹€à¸§à¹‡à¸šà¹„ซต์ส่งข้อมูลรับรองที่ถูà¸à¹à¸›à¸¥à¸‡à¸‹à¸¶à¹ˆà¸‡ Chromium ไม่สามารถดำเนินà¸à¸²à¸£à¹„ด้ โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจจะใช้งานได้ในภายหลัง <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">ไม่สามารถตรวจสอบว่าใบรับรองถูà¸à¹€à¸žà¸´à¸à¸–อนหรือไม่</translation>
<translation id="6433490469411711332">à¹à¸à¹‰à¹„ขข้อมูลติดต่อ</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ปà¸à¸´à¹€à¸ªà¸˜à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­</translation>
<translation id="6446608382365791566">เพิ่มข้อมูลเพิ่มเติม</translation>
+<translation id="6447842834002726250">คุà¸à¸à¸µà¹‰</translation>
<translation id="6451458296329894277">ยืนยันà¸à¸²à¸£à¸ªà¹ˆà¸‡à¹à¸šà¸šà¸Ÿà¸­à¸£à¹Œà¸¡à¸­à¸µà¸à¸„รั้ง</translation>
<translation id="6456339708790392414">à¸à¸²à¸£à¸Šà¸³à¸£à¸°à¹€à¸‡à¸´à¸™à¸‚องคุณ</translation>
<translation id="6458467102616083041">ไม่ใช้งานเนื่องจาà¸à¸à¸²à¸£à¸„้นหาเริ่มต้นถูà¸à¸›à¸´à¸”ใช้งานตามนโยบาย</translation>
-<translation id="6462969404041126431">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยของเซิร์ฟเวอร์อาจถูà¸à¹€à¸žà¸´à¸à¸–อนไปà¹à¸¥à¹‰à¸§ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">นโยบายอุปà¸à¸£à¸“์</translation>
<translation id="6477321094435799029">Chrome ได้ตรวจพบรหัสที่ผิดปà¸à¸•à¸´à¸šà¸™à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰à¹à¸¥à¸°à¹„ด้บล็อà¸à¸£à¸«à¸±à¸ªà¸”ังà¸à¸¥à¹ˆà¸²à¸§à¹€à¸žà¸·à¹ˆà¸­à¸›à¸à¸›à¹‰à¸­à¸‡à¸‚้อมูลส่วนบุคคลของคุณ (เช่น รหัสผ่าน หมายเลขโทรศัพท์ à¹à¸¥à¸°à¸šà¸±à¸•à¸£à¹€à¸„รดิต)</translation>
<translation id="6489534406876378309">เริ่มอัปโหลดข้อขัดข้อง</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">วันที่หมดอายุ: <ph name="EXPIRATION_DATE_ABBR" /> ใช้ล่าสุดเมื่อ <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">ผู้จัดà¸à¸²à¸£à¸¢à¸±à¸‡à¹„ม่ได้อนุมัติเว็บไซต์นี้</translation>
<translation id="6569060085658103619">คุณà¸à¸³à¸¥à¸±à¸‡à¸”ูหน้าส่วนขยาย</translation>
-<translation id="6593753688552673085">น้อยà¸à¸§à¹ˆà¸² <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">เนื้อหานี้อาจพยายามติดตั้งซอฟต์à¹à¸§à¸£à¹Œà¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸—ี่จะขโมยหรือลบข้อมูลในอุปà¸à¸£à¸“์ของคุณ <ph name="BEGIN_LINK" />à¹à¸ªà¸”งเนื้อหา<ph name="END_LINK" /></translation>
<translation id="6596325263575161958">ตัวเลือà¸à¸à¸²à¸£à¹€à¸‚้ารหัส</translation>
<translation id="662080504995468778">อยู่ต่อ</translation>
<translation id="6626291197371920147">เพิ่มหมายเลขบัตรที่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> ค้นหา</translation>
+<translation id="6630809736994426279">ผู้โจมตีที่à¸à¸³à¸¥à¸±à¸‡à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจพยายามติดตั้งโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸¥à¸‡à¹ƒà¸™à¹€à¸„รื่อง Mac ของคุณ เพื่อขโมยหรือลบข้อมูล (ตัวอย่างเช่น รูปภาพ รหัสผ่าน ข้อความ à¹à¸¥à¸°à¸šà¸±à¸•à¸£à¹€à¸„รดิต) <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">นโยบายนี้ถูà¸à¸¢à¸à¹€à¸¥à¸´à¸à¹à¸¥à¹‰à¸§</translation>
-<translation id="6652240803263749613">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปà¸à¸´à¸šà¸±à¸•à¸´à¸à¸²à¸£à¸‚องคอมพิวเตอร์ไม่เชื่อถือใบรับรองความปลอดภัยของเซิร์ฟเวอร์นี้ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">ต้องà¸à¸²à¸£à¸™à¸³à¸„ำà¹à¸™à¸°à¸™à¸³à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸šà¸šà¸Ÿà¸­à¸£à¹Œà¸¡à¸­à¸­à¸à¸ˆà¸²à¸ Chromium ใช่ไหม</translation>
<translation id="6685834062052613830">ออà¸à¸ˆà¸²à¸à¸£à¸°à¸šà¸šà¹à¸¥à¸°à¸•à¸±à¹‰à¸‡à¸„่าให้เสร็จสมบูรณ์</translation>
<translation id="6710213216561001401">à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²</translation>
<translation id="6710594484020273272">&lt;พิมพ์ข้อความค้นหา&gt;</translation>
<translation id="6711464428925977395">พร็อà¸à¸‹à¸µà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¸œà¸´à¸”ปà¸à¸•à¸´à¸«à¸£à¸·à¸­à¸—ี่อยู่ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="6727102863431372879">ตั้งค่า</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{ไม่มี}=1{1 รายà¸à¸²à¸£}other{# รายà¸à¸²à¸£}}</translation>
<translation id="674375294223700098">ข้อผิดพลาดใบรับรองของเซิร์ฟเวอร์ที่ไม่รู้จัà¸</translation>
<translation id="6753269504797312559">ค่านโยบาย</translation>
<translation id="6757797048963528358">อุปà¸à¸£à¸“์ของคุณเข้าสู่โหมดสลีปà¹à¸¥à¹‰à¸§</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">รหัสà¸à¸²à¸£à¸›à¸£à¸±à¸šà¹à¸•à¹ˆà¸‡</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">ไม่สามารถโหลดข้อมูลภูมิภาค</translation>
+<translation id="6825578344716086703">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸ªà¸”งใบรับรองที่ลงนามด้วยอัลà¸à¸­à¸£à¸´à¸—ึมลายเซ็นที่ไม่รัดà¸à¸¸à¸¡ (เช่น SHA-1) ซึ่งหมายความว่าข้อมูลรับรองด้านความปลอดภัยที่เซิร์ฟเวอร์à¹à¸ªà¸”งอาจถูà¸à¸›à¸¥à¸­à¸¡à¹à¸›à¸¥à¸‡à¸‚ึ้น à¹à¸¥à¸°à¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¸”ังà¸à¸¥à¹ˆà¸²à¸§à¸­à¸²à¸ˆà¹„ม่ใช่เซิร์ฟเวอร์ที่คุณคิด (คุณอาจà¸à¸³à¸¥à¸±à¸‡à¸•à¸´à¸”ต่อà¸à¸±à¸šà¸œà¸¹à¹‰à¹‚จมตี)</translation>
+<translation id="6830728435402077660">ไม่ปลอดภัย</translation>
<translation id="6831043979455480757">à¹à¸›à¸¥à¸ à¸²à¸©à¸²</translation>
<translation id="6839929833149231406">พื้นที่</translation>
<translation id="6874604403660855544">&amp;ทำซ้ำà¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">บัตรของคุณได้รับà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¹à¸¥à¹‰à¸§</translation>
<translation id="6897140037006041989">User agent</translation>
<translation id="6915804003454593391">ผู้ใช้:</translation>
+<translation id="6945221475159498467">เลือà¸</translation>
<translation id="6948701128805548767">หาà¸à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸”ูวิธีà¸à¸²à¸£à¸£à¸±à¸šà¸ªà¸´à¸™à¸„้าà¹à¸¥à¸°à¸‚้อà¸à¸³à¸«à¸™à¸” โปรดเลือà¸à¸—ี่อยู่</translation>
<translation id="6957887021205513506">ใบรับรองของเซิร์ฟเวอร์น่าจะเป็นของปลอม</translation>
<translation id="6965382102122355670">ตà¸à¸¥à¸‡</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">มีà¸à¸²à¸£à¸£à¸°à¸šà¸¸à¸—ั้งพร็อà¸à¸‹à¸µà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸šà¸šà¸„งที่à¹à¸¥à¸° URL สคริปต์ .pac ไว้</translation>
<translation id="6989763994942163495">à¹à¸ªà¸”งà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าขั้นสูง...</translation>
<translation id="7000990526846637657">ไม่พบข้อมูลประวัติà¸à¸²à¸£à¹€à¸‚้าชม</translation>
-<translation id="7009986207543992532">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸ªà¸”งใบรับรองที่มีระยะเวลาà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹„ด้นานเà¸à¸´à¸™à¸à¸§à¹ˆà¸²à¸ˆà¸°à¹€à¸Šà¸·à¹ˆà¸­à¸–ือได้ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">บัà¸à¸Šà¸µ Google ของคุณอาจมีประวัติà¸à¸²à¸£à¸—่องเว็บในรูปà¹à¸šà¸šà¸­à¸·à¹ˆà¸™à¹† ที่ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">รหัสผ่าน</translation>
+<translation id="7050187094878475250">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹„ด้à¹à¸ªà¸”งใบรับรองที่มีระยะเวลาที่สามารถใช้ได้นานเà¸à¸´à¸™à¸à¸§à¹ˆà¸²à¸—ี่จะเชื่อถือได้</translation>
+<translation id="7053983685419859001">บล็อà¸</translation>
<translation id="7064851114919012435">ข้อมูลติดต่อ</translation>
<translation id="7079718277001814089">เว็บไซต์นี้มีมัลà¹à¸§à¸£à¹Œ</translation>
<translation id="7087282848513945231">อำเภอ</translation>
-<translation id="7088615885725309056">เà¸à¹ˆà¸²à¸à¸§à¹ˆà¸²</translation>
<translation id="7090678807593890770">ค้นหา <ph name="LINK" /> จาภGoogle</translation>
+<translation id="7108819624672055576">อนุà¸à¸²à¸•à¹‚ดยส่วนขยาย</translation>
<translation id="7119414471315195487">ปิดà¹à¸—็บหรือโปรà¹à¸à¸£à¸¡à¸­à¸·à¹ˆà¸™à¹†</translation>
<translation id="7129409597930077180">ไม่สามารถจัดส่งสินค้าไปยังที่อยู่นี้ โปรดเลือà¸à¸—ี่อยู่อื่น</translation>
<translation id="7138472120740807366">วิธีà¸à¸²à¸£à¸™à¸³à¸ªà¹ˆà¸‡à¸ªà¸´à¸™à¸„้า</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">à¸à¸³à¸¥à¸±à¸‡à¸”ำเนินà¸à¸²à¸£</translation>
<translation id="724691107663265825">ไซต์ที่จะเปิดมีมัลà¹à¸§à¸£à¹Œ</translation>
<translation id="724975217298816891">ป้อนวันหมดอายุà¹à¸¥à¸° CVC สำหรับ <ph name="CREDIT_CARD" /> เพื่ออัปเดตรายละเอียดของบัตร เมื่อคุณยืนยันà¹à¸¥à¹‰à¸§ รายละเอียดบัตรของคุณจะà¹à¸Šà¸£à¹Œà¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์นี้</translation>
-<translation id="725866823122871198">ไม่สามารถเริ่มà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸ªà¹ˆà¸§à¸™à¸•à¸±à¸§à¸à¸±à¸š <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ได้เนื่องจาà¸à¸§à¸±à¸™à¸—ี่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²à¸‚องคอมพิวเตอร์ (<ph name="DATE_AND_TIME" />) ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
+<translation id="7260504762447901703">เพิà¸à¸–อนสิทธิ์à¸à¸²à¸£à¹€à¸‚้าถึง</translation>
<translation id="7275334191706090484">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸—ี่มีà¸à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£</translation>
<translation id="7298195798382681320">à¹à¸™à¸°à¸™à¸³</translation>
<translation id="7309308571273880165">รายงานข้อขัดข้องเมื่อ <ph name="CRASH_TIME" /> (ผู้ใช้ขอà¸à¸²à¸£à¸­à¸±à¸›à¹‚หลด ยังไม่ได้อัปโหลด)</translation>
<translation id="7334320624316649418">&amp;ทำซ้ำà¸à¸²à¸£à¸ˆà¸±à¸”ลำดับใหม่</translation>
<translation id="733923710415886693">ไม่มีà¸à¸²à¸£à¹€à¸›à¸´à¸”เผยใบรับรองของเซิร์ฟเวอร์ผ่านความโปร่งใสของใบรับรอง</translation>
-<translation id="7351800657706554155">คุณไม่สามารถเข้าชม <ph name="SITE" /> ได้ในขณะนี้ เนื่องจาà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸‚องเว็บไซต์ถูà¸à¹€à¸žà¸´à¸à¸–อนà¹à¸¥à¹‰à¸§ โดยปà¸à¸•à¸´à¸‚้อผิดพลาดของเครือข่ายà¹à¸¥à¸°à¸à¸²à¸£à¹‚จมตีจะเà¸à¸´à¸”ขึ้นเพียงชั่วคราว หน้านี้จึงอาจจะใช้งานได้ในภายหลัง <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">บรรทัดคำสั่ง </translation>
<translation id="7372973238305370288">ผลà¸à¸²à¸£à¸„้นหา</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ไม่</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">ยืนยันบัตร</translation>
-<translation id="7394102162464064926">คุณà¹à¸™à¹ˆà¹ƒà¸ˆà¸«à¸£à¸·à¸­à¹„ม่ว่าต้องà¸à¸²à¸£à¸¥à¸šà¸«à¸™à¹‰à¸²à¹€à¸§à¹‡à¸šà¹€à¸«à¸¥à¹ˆà¸²à¸™à¸µà¹‰à¸ˆà¸²à¸à¸›à¸£à¸°à¸§à¸±à¸•à¸´à¸à¸²à¸£à¹€à¸‚้าชมของคุณ
-
-รู้หรือไม่! <ph name="SHORTCUT_KEY" /> ของโหมดไม่ระบุตัวตนอาจมีประโยชน์ต่อà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹ƒà¸™à¸„รั้งถัดไป</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">เส้นทางโปรไฟล์</translation>
<translation id="7424977062513257142">หน้าที่à¸à¸±à¸‡à¹„ว้ในหน้าเว็บนี้บอà¸à¸§à¹ˆà¸²:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">เว็บไซต์นี้ถูà¸à¸šà¸¥à¹‡à¸­à¸</translation>
<translation id="7445762425076701745">ไม่สามารถตรวจสอบความถูà¸à¸•à¹‰à¸­à¸‡à¸‚องข้อมูลประจำตัวของเซิร์ฟเวอร์ที่คุณเชื่อมต่ออยู่ได้ทั้งหมด คุณà¸à¸³à¸¥à¸±à¸‡à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¸±à¸šà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¸—ี่ใช้ชื่อที่ใช้ได้เฉพาะในเครือข่ายของคุณ ซึ่งผู้ออà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸ à¸²à¸¢à¸™à¸­à¸à¹„ม่สามารถตรวจสอบà¸à¸²à¸£à¹€à¸›à¹‡à¸™à¹€à¸ˆà¹‰à¸²à¸‚องได้ เนื่องจาà¸à¸œà¸¹à¹‰à¸­à¸­à¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸šà¸²à¸‡à¸£à¸²à¸¢à¸ˆà¸°à¸¢à¸±à¸‡à¸„งออà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¹ƒà¸«à¹‰à¸à¸±à¸šà¸Šà¸·à¹ˆà¸­à¹€à¸«à¸¥à¹ˆà¸²à¸™à¸µà¹‰à¸­à¸¢à¸¹à¹ˆ คุณจึงไม่มีทางมั่นใจได้ว่าà¸à¸³à¸¥à¸±à¸‡à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์ที่คุณต้องà¸à¸²à¸£à¸”ูโดยไม่ใช่ผู้โจมตี</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LINK" />เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸›à¸±à¸à¸«à¸²à¸™à¸µà¹‰</translation>
+<translation id="7455133967321480974">ใช้ค่าเริ่มต้นสาà¸à¸¥ (บล็อà¸)</translation>
<translation id="7460163899615895653">à¹à¸—็บล่าสุดจาà¸à¸­à¸¸à¸›à¸à¸£à¸“์อื่นๆ จะปราà¸à¸à¸—ี่นี่</translation>
<translation id="7469372306589899959">à¸à¸³à¸¥à¸±à¸‡à¸¢à¸·à¸™à¸¢à¸±à¸™à¸šà¸±à¸•à¸£</translation>
<translation id="7481312909269577407">ส่งต่อ</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">รหัสอุปà¸à¸£à¸“์นโยบายที่ส่งà¸à¸¥à¸±à¸šà¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²à¸«à¸£à¸·à¸­à¹„ม่ตรงà¸à¸±à¸šà¸£à¸«à¸±à¸ªà¸­à¸¸à¸›à¸à¸£à¸“์ปัจจุบัน</translation>
<translation id="7514365320538308">ดาวน์โหลด</translation>
<translation id="7518003948725431193">ไม่พบหน้าเว็บสำหรับที่อยู่เว็บ: <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">ราคา</translation>
<translation id="7537536606612762813">จำเป็น</translation>
+<translation id="7542403920425041731">เมื่อคุณยืนยันà¹à¸¥à¹‰à¸§ จะมีà¸à¸²à¸£à¹à¸Šà¸£à¹Œà¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”บัตรของคุณà¸à¸±à¸šà¹„ซต์นี้</translation>
<translation id="7542995811387359312">à¸à¸²à¸£à¸›à¹‰à¸­à¸™à¸«à¸¡à¸²à¸¢à¹€à¸¥à¸‚บัตรเครดิตอัตโนมัติถูà¸à¸›à¸´à¸”ใช้งานเนื่องจาà¸à¸Ÿà¸­à¸£à¹Œà¸¡à¸™à¸µà¹‰à¹„ม่ได้ใช้à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸—ี่ปลอดภัย</translation>
<translation id="7543525346216957623">ถามผู้ปà¸à¸„รอง</translation>
<translation id="7549584377607005141">หน้าเว็บนี้ต้องใช้ข้อมูลที่คุณป้อนà¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰à¹€à¸žà¸·à¹ˆà¸­à¹ƒà¸«à¹‰à¹à¸ªà¸”งได้อย่างถูà¸à¸•à¹‰à¸­à¸‡ คุณสามารถส่งข้อมูลนี้ได้อีà¸à¸„รั้ง à¹à¸•à¹ˆà¸à¸²à¸£à¸—ำเช่นนั้นจะเป็นà¸à¸²à¸£à¸—ำสิ่งที่หน้าเว็บนี้เคยดำเนินà¸à¸²à¸£à¸‹à¹‰à¸³à¸­à¸µà¸à¸„รั้ง</translation>
<translation id="7552846755917812628">ลองทำตามเคล็ดลับต่อไปนี้:</translation>
<translation id="7554791636758816595">à¹à¸—็บใหม่</translation>
+<translation id="7567204685887185387">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะอาจมีà¸à¸²à¸£à¸­à¸­à¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸„วามปลอดภัยปลอม โดยอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้บุà¸à¸£à¸¸à¸à¸—ี่ขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> รายà¸à¸²à¸£}other{<ph name="CONTACT_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> รายà¸à¸²à¸£}}</translation>
<translation id="7568593326407688803">หน้าเว็บนี้เป็น<ph name="ORIGINAL_LANGUAGE" />คุณต้องà¸à¸²à¸£à¹à¸›à¸¥à¸«à¸£à¸·à¸­à¹„ม่</translation>
<translation id="7569952961197462199">นำบัตรเครดิตออà¸à¸ˆà¸²à¸ Chrome ไหม</translation>
<translation id="7569983096843329377">สีดำ</translation>
<translation id="7578104083680115302">ชำระเงินบนเว็บไซต์à¹à¸¥à¸°à¹à¸­à¸›à¹ƒà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ต่างๆ ได้อย่างรวดเร็วด้วยบัตรที่คุณได้บันทึà¸à¹„ว้à¸à¸±à¸š Google</translation>
<translation id="7588950540487816470">Physical Web</translation>
<translation id="7592362899630581445">ใบรับรองของเซิร์ฟเวอร์ละเมิดข้อà¸à¸³à¸«à¸™à¸”ชื่อ</translation>
+<translation id="7598391785903975535">ไม่ถึง <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ไม่สามารถดำเนินà¸à¸²à¸£à¸à¸±à¸šà¸„ำขอนี้ในขณะนี้</translation>
<translation id="7600965453749440009">ไม่ต้องà¹à¸›à¸¥à¸ à¸²à¸©à¸²<ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">ค่าอยู่นอà¸à¸Šà¹ˆà¸§à¸‡ <ph name="VALUE" /></translation>
<translation id="7613889955535752492">หมดอายุ: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">คุณมีข้อมูลที่ถูà¸à¹€à¸‚้ารหัสโดยใช้รหัสผ่านบัà¸à¸Šà¸µ Google รูปà¹à¸šà¸šà¸­à¸·à¹ˆà¸™à¸­à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§ โปรดป้อนรหัสผ่านด้านล่าง</translation>
-<translation id="7634554953375732414">à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¸±à¸šà¹„ซต์นี้ไม่ได้เป็นส่วนตัว</translation>
<translation id="7637571805876720304">ต้องà¸à¸²à¸£à¸™à¸³à¸šà¸±à¸•à¸£à¹€à¸„รดิตออà¸à¸ˆà¸²à¸ Chromium ใช่ไหม</translation>
<translation id="765676359832457558">ซ่อนà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าขั้นสูง...</translation>
<translation id="7658239707568436148">ยà¸à¹€à¸¥à¸´à¸</translation>
+<translation id="7662298039739062396">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าควบคุมโดยส่วนขยาย</translation>
<translation id="7667346355482952095">โทเค็นนโยบายที่ส่งà¸à¸¥à¸±à¸šà¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²à¸«à¸£à¸·à¸­à¹„ม่ตรงà¸à¸±à¸šà¹‚ทเค็นปัจจุบัน</translation>
<translation id="7668654391829183341">อุปà¸à¸£à¸“์ที่ไม่รู้จัà¸</translation>
<translation id="7669271284792375604">ผู้โจมตีเว็บไซต์นี้อาจพยายามหลอà¸à¸¥à¹ˆà¸­à¹ƒà¸«à¹‰à¸„ุณติดตั้งโปรà¹à¸à¸£à¸¡à¸—ี่เป็นอันตรายต่อประสบà¸à¸²à¸£à¸“์à¸à¸²à¸£à¸—่องเว็บของคุณ (ตัวอย่างเช่น โดยà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸«à¸™à¹‰à¸²à¹à¸£à¸à¸«à¸£à¸·à¸­à¹à¸ªà¸”งโฆษณาเพิ่มเติมในเว็บไซต์ที่คุณเข้าชม)</translation>
<translation id="7674629440242451245">หาà¸à¸ªà¸™à¹ƒà¸ˆà¹ƒà¸™à¸Ÿà¸µà¹€à¸ˆà¸­à¸£à¹Œà¹ƒà¸«à¸¡à¹ˆà¹† สุดเจ๋งของ Chrome ลองใช้เวอร์ชันที่à¸à¸³à¸¥à¸±à¸‡à¸žà¸±à¸’นาของเราที่ chrome.com/dev</translation>
<translation id="7682287625158474539">จัดส่ง</translation>
+<translation id="7701040980221191251">ไม่มี</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />ไปยัง <ph name="SITE" /> (ไม่ปลอดภัย)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">ใบรับรอง</translation>
+<translation id="7716147886133743102">ถูà¸à¸šà¸¥à¹‡à¸­à¸à¹‚ดยผู้ดูà¹à¸¥à¸£à¸°à¸šà¸š</translation>
<translation id="7716424297397655342">ไม่สามารถโหลดเว็บไซต์นี้จาà¸à¹à¸„ช</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">ไม่ได้จัดà¸à¸²à¸£</translation>
<translation id="7755287808199759310">ผู้ปà¸à¸„รองสามารถเลิà¸à¸šà¸¥à¹‡à¸­à¸à¹€à¸§à¹‡à¸šà¹„ซต์ให้คุณ</translation>
<translation id="7758069387465995638">ไฟร์วอลล์หรือซอฟต์à¹à¸§à¸£à¹Œà¸›à¹‰à¸­à¸‡à¸à¸±à¸™à¹„วรัสอาจบล็อà¸à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸™à¸µà¹‰</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32 บิต)</translation>
<translation id="7956713633345437162">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸à¸šà¸™à¸¡à¸·à¸­à¸–ือ</translation>
<translation id="7961015016161918242">ไม่ต้องเลย</translation>
-<translation id="7962083544045318153">รหัสข้อขัดข้อง <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">à¹à¸›à¸¥ <ph name="ORIGINAL_LANGUAGE" /> เป็น <ph name="TARGET_LANGUAGE" /> เสมอ</translation>
<translation id="7995512525968007366">ไม่ได้ระบุ</translation>
<translation id="800218591365569300">ลองปิดà¹à¸—็บหรือโปรà¹à¸à¸£à¸¡à¸­à¸·à¹ˆà¸™à¹† เพื่อเพิ่มหน่วยความจำ</translation>
<translation id="8012647001091218357">เราไม่สามารถติดต่อผู้ปà¸à¸„รองของคุณได้ในขณะนี้ โปรดลองอีà¸à¸„รั้ง</translation>
<translation id="8025119109950072390">ผู้โจมตีในเว็บไซต์นี้อาจหลอà¸à¸¥à¹ˆà¸­à¹ƒà¸«à¹‰à¸„ุณทำบางสิ่งที่อันตราย เช่น à¸à¸²à¸£à¸•à¸´à¸”ตั้งซอฟต์à¹à¸§à¸£à¹Œà¸«à¸£à¸·à¸­à¹€à¸›à¸´à¸”เผยข้อมูลส่วนบุคคล (ตัวอย่างเช่น รหัสผ่าน หมายเลขโทรศัพท์ หรือบัตรเครดิต)</translation>
-<translation id="803030522067524905">เมื่อเร็วๆ นี้ Google Safe Browsing ตรวจพบฟิชชิงบน <ph name="SITE" /> เว็บไซต์ฟิชชิงปลอมเป็นเว็บไซต์อื่นๆ เพื่อหลอà¸à¸„ุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">หน้าเว็บนี้อยู่ในภาษา<ph name="SOURCE_LANGUAGE" /> ต้องà¸à¸²à¸£à¹à¸›à¸¥à¹€à¸›à¹‡à¸™à¸ à¸²à¸©à¸²<ph name="TARGET_LANGUAGE" />ไหม</translation>
+<translation id="8037357227543935929">ขอ (ค่าเริ่มต้น)</translation>
<translation id="8041089156583427627">ส่งความคิดเห็น</translation>
+<translation id="8041940743680923270">ใช้ค่าเริ่มต้นสาà¸à¸¥ (ถาม)</translation>
<translation id="8088680233425245692">à¸à¸²à¸£à¸”ูบทความล้มเหลว</translation>
<translation id="8089520772729574115">ไม่ถึง 1 MB</translation>
<translation id="8091372947890762290">à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¸à¸²à¸£à¹€à¸›à¸´à¸”ใช้งานบนเซิร์ฟเวอร์</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007">ไม่พบ<ph name="BEGIN_ABBR" />ที่อยู่ DNS<ph name="END_ABBR" /> ของเซิร์ฟเวอร์ของ <ph name="HOST_NAME" /></translation>
<translation id="8149426793427495338">คอมพิวเตอร์ของคุณเข้าสู่โหมดสลีปà¹à¸¥à¹‰à¸§</translation>
<translation id="8150722005171944719">ไฟล์ที่ <ph name="URL" /> ไม่สามารถอ่านได้ เนื่องจาà¸à¸­à¸²à¸ˆà¸–ูà¸à¸¥à¸š ย้ายไปà¹à¸¥à¹‰à¸§ หรือà¸à¸²à¸£à¸­à¸™à¸¸à¸à¸²à¸•à¸‚องไฟล์อาจป้องà¸à¸±à¸™à¸à¸²à¸£à¹€à¸‚้าถึง</translation>
+<translation id="8184538546369750125">ใช้ค่าเริ่มต้นสาà¸à¸¥ (อนุà¸à¸²à¸•)</translation>
+<translation id="8191494405820426728">รหัสข้อขัดข้องในเครื่อง <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¸¢à¹‰à¸²à¸¢</translation>
<translation id="8201077131113104583">à¸à¸²à¸£à¸­à¸±à¸›à¹€à¸”ต URL ไม่ถูà¸à¸•à¹‰à¸­à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¸ªà¹ˆà¸§à¸™à¸‚ยายรหัส "<ph name="EXTENSION_ID" />"</translation>
<translation id="8202097416529803614">ข้อมูลสรุปคำสั่งซื้อ</translation>
<translation id="8218327578424803826">ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่มอบหมาย:</translation>
<translation id="8225771182978767009">ผู้ที่ตั้งค่าคอมพิวเตอร์เครื่องนี้เลือà¸à¸šà¸¥à¹‡à¸­à¸à¹€à¸§à¹‡à¸šà¹„ซต์นี้</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">ผู้บุà¸à¸£à¸¸à¸à¸—ี่à¸à¸³à¸¥à¸±à¸‡à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจพยายามติดตั้งโปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸‹à¸¶à¹ˆà¸‡à¸ˆà¸°à¸‚โมยหรือลบข้อมูล (ตัวอย่างเช่น รูปภาพ รหัสผ่าน ข้อความ à¹à¸¥à¸°à¸šà¸±à¸•à¸£à¹€à¸„รดิต) ลงในคอมพิวเตอร์ของคุณ</translation>
<translation id="8241707690549784388">หน้าที่คุณà¸à¸³à¸¥à¸±à¸‡à¸¡à¸­à¸‡à¸«à¸²à¹ƒà¸Šà¹‰à¸‚้อมูลที่คุณได้ป้อนไว้à¹à¸¥à¹‰à¸§ à¸à¸²à¸£à¸à¸¥à¸±à¸šà¹„ปสู่หน้านั้นอาจทำให้คุณต้องทำซ้ำà¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¹ƒà¸”ๆ ที่คุณทำà¹à¸¥à¹‰à¸§ คุณต้องà¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸•à¹ˆà¸­à¸«à¸£à¸·à¸­à¹„ม่</translation>
<translation id="8249320324621329438">เรียà¸à¸”ูครั้งสุดท้ายเมื่อ:</translation>
<translation id="8253091569723639551">ต้องใส่ที่อยู่สำหรับà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¹€à¸à¹‡à¸šà¹€à¸‡à¸´à¸™</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">ติดต่อผู้ดูà¹à¸¥à¸£à¸°à¸šà¸šà¹€à¸„รือข่ายของคุณหาà¸à¹„ม่à¹à¸™à¹ˆà¹ƒà¸ˆà¸§à¹ˆà¸²à¸‚้อความนี้หมายถึงอะไร</translation>
<translation id="8293206222192510085">เพิ่มบุ๊à¸à¸¡à¸²à¸£à¹Œà¸</translation>
<translation id="8294431847097064396">à¹à¸«à¸¥à¹ˆà¸‡à¸—ี่มา</translation>
+<translation id="8306404619377842860">ไม่สามารถสร้างà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸ªà¹ˆà¸§à¸™à¸•à¸±à¸§à¸à¸±à¸š <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> เนื่องจาà¸à¸§à¸±à¸™à¸—ี่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²à¸‚องอุปà¸à¸£à¸“์ (<ph name="DATE_AND_TIME" />) ไม่ถูà¸à¸•à¹‰à¸­à¸‡ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">à¸à¸²à¸£à¹à¸›à¸¥à¸¥à¹‰à¸¡à¹€à¸«à¸¥à¸§à¹€à¸™à¸·à¹ˆà¸­à¸‡à¸ˆà¸²à¸à¹€à¸à¸´à¸”ปัà¸à¸«à¸²à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¸±à¸šà¹€à¸„รือข่าย </translation>
<translation id="8332188693563227489">à¸à¸²à¸£à¹€à¸‚้าถึง <ph name="HOST_NAME" /> ถูà¸à¸›à¸à¸´à¹€à¸ªà¸˜</translation>
<translation id="834457929814110454">หาà¸à¸„ุณเข้าใจความเสี่ยงต่อความปลอดภัย คุณสามารถ<ph name="BEGIN_LINK" />ไปยังไซต์นี้<ph name="END_LINK" />à¸à¹ˆà¸­à¸™à¸—ี่จะมีà¸à¸²à¸£à¸™à¸³à¹‚ปรà¹à¸à¸£à¸¡à¸­à¸±à¸™à¸•à¸£à¸²à¸¢à¸­à¸­à¸</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">หาà¸à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸à¸²à¸£à¹Œà¸”จาà¸à¸šà¸±à¸à¸Šà¸µ Google ให้ลงชื่อเข้าใช้ Chrome</translation>
<translation id="8488350697529856933">ใช้à¸à¸±à¸š</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ใช้เวลาตอบà¸à¸¥à¸±à¸šà¸™à¸²à¸™à¹€à¸à¸´à¸™à¹„ป</translation>
-<translation id="852346902619691059">เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปà¸à¸´à¸šà¸±à¸•à¸´à¸à¸²à¸£à¸‚องอุปà¸à¸£à¸“์ไม่เชื่อถือใบรับรองความปลอดภัยของเซิร์ฟเวอร์นี้ สาเหตุอาจเà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าผิดหรือผู้โจมตีขัดขวางà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸‚องคุณ <ph name="BEGIN_LEARN_MORE_LINK" />เรียนรู้เพิ่มเติม<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">ปีที่หมดอายุ</translation>
<translation id="8543181531796978784">คุณสามารถ<ph name="BEGIN_ERROR_LINK" />รายงานปัà¸à¸«à¸²à¹ƒà¸™à¸à¸²à¸£à¸•à¸£à¸§à¸ˆà¸«à¸²<ph name="END_ERROR_LINK" />ได้ หรือหาà¸à¸„ุณเข้าใจถึงความเสี่ยงต่อความปลอดภัยของคุณ คุณสามารถ<ph name="BEGIN_LINK" />เข้าชมเว็บไซต์ที่ไม่ปลอดภัย<ph name="END_LINK" />ได้</translation>
<translation id="8553075262323480129">à¸à¸²à¸£à¹à¸›à¸¥à¸¥à¹‰à¸¡à¹€à¸«à¸¥à¸§à¹€à¸™à¸·à¹ˆà¸­à¸‡à¸ˆà¸²à¸à¹„ม่สามารถระบุภาษาของหน้าเว็บนี้ได้</translation>
-<translation id="8559762987265718583">ไม่สามารถเริ่มà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸ªà¹ˆà¸§à¸™à¸•à¸±à¸§à¸à¸±à¸š <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ได้เนื่องจาà¸à¸§à¸±à¸™à¸—ี่à¹à¸¥à¸°à¹€à¸§à¸¥à¸²à¸‚องอุปà¸à¸£à¸“์ (<ph name="DATE_AND_TIME" />) ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="8571890674111243710">à¸à¸³à¸¥à¸±à¸‡à¹à¸›à¸¥à¸«à¸™à¹‰à¸²à¹€à¸§à¹‡à¸šà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸ à¸²à¸©à¸²<ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">เพิ่มเบอร์โทร
</translation>
@@ -821,6 +895,7 @@
<translation id="8738058698779197622">หาà¸à¸•à¹‰à¸­à¸‡à¹€à¸£à¸´à¹ˆà¸¡à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸—ี่ปลอดภัย นาฬิà¸à¸²à¸ˆà¸°à¸•à¹‰à¸­à¸‡à¸•à¸±à¹‰à¸‡à¸„่าไว้อย่างถูà¸à¸•à¹‰à¸­à¸‡ เนื่องจาà¸à¹ƒà¸šà¸£à¸±à¸šà¸£à¸­à¸‡à¸—ี่เว็บไซต์ใช้เพื่อระบุตนเองจะใช้ได้เฉพาะช่วงเวลาหนึ่งเท่านั้น นาฬิà¸à¸²à¸‚องอุปà¸à¸£à¸“์ไม่ถูà¸à¸•à¹‰à¸­à¸‡ Chromium จึงไม่สามารถยืนยันใบรับรองเหล่านี้ได้</translation>
<translation id="8740359287975076522">ไม่พบ&lt;abbr id="dnsDefinition"&gt;ที่อยู่ DNS&lt;/abbr&gt; ของ <ph name="HOST_NAME" /> à¸à¸³à¸¥à¸±à¸‡à¸§à¸´à¸™à¸´à¸ˆà¸‰à¸±à¸¢à¸›à¸±à¸à¸«à¸²</translation>
<translation id="8759274551635299824">บัตรนี้หมดอายุà¹à¸¥à¹‰à¸§</translation>
+<translation id="8761567432415473239">Google Safe Browsing <ph name="BEGIN_LINK" />พบโปรà¹à¸à¸£à¸¡à¸—ี่เป็นอันตราย<ph name="END_LINK" />บน <ph name="SITE" /> เมื่อเร็วๆ นี้</translation>
<translation id="8790007591277257123">&amp;ทำซ้ำà¸à¸²à¸£à¸™à¸³à¸­à¸­à¸</translation>
<translation id="8800988563907321413">คำà¹à¸™à¸°à¸™à¸³à¹ƒà¸™à¸šà¸£à¸´à¹€à¸§à¸“ใà¸à¸¥à¹‰à¹€à¸„ียงจะปราà¸à¸à¸—ี่นี่</translation>
<translation id="8820817407110198400">บุ๊à¸à¸¡à¸²à¸£à¹Œà¸</translation>
@@ -833,29 +908,30 @@
<translation id="8870413625673593573">เพิ่งปิด</translation>
<translation id="8874824191258364635">ป้อนหมายเลขบัตรที่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="8876793034577346603">ไม่สามารถà¹à¸¢à¸à¸§à¸´à¹€à¸„ราะห์à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ค่าเครือข่าย</translation>
-<translation id="8877192140621905067">เมื่อคุณยืนยันà¹à¸¥à¹‰à¸§ รายละเอียดบัตรของคุณจะà¹à¸Šà¸£à¹Œà¸à¸±à¸šà¹€à¸§à¹‡à¸šà¹„ซต์นี้</translation>
<translation id="8889402386540077796">โทนสี</translation>
<translation id="8891727572606052622">โหมดพร็อà¸à¸‹à¸µà¹„ม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="889901481107108152">ขออภัย à¸à¸²à¸£à¸—ดลองนี้ไม่สามารถใช้ได้à¸à¸±à¸šà¹à¸žà¸¥à¸•à¸Ÿà¸­à¸£à¹Œà¸¡à¸‚องคุณ</translation>
<translation id="8903921497873541725">ขยาย</translation>
<translation id="8931333241327730545">คุณต้องà¸à¸²à¸£à¸šà¸±à¸™à¸—ึà¸à¸šà¸±à¸•à¸£à¸™à¸µà¹‰à¹ƒà¸™à¸šà¸±à¸à¸Šà¸µ Google ไหม</translation>
<translation id="8932102934695377596">นาฬิà¸à¸²à¸Šà¹‰à¸²à¹€à¸à¸´à¸™à¹„ป</translation>
-<translation id="8954894007019320973">(ต่อ)</translation>
<translation id="8971063699422889582">ใบรับรองของเซิร์ฟเวอร์หมดอายุà¹à¸¥à¹‰à¸§</translation>
<translation id="8986494364107987395">ส่งสถิติà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸¥à¸°à¸£à¸²à¸¢à¸‡à¸²à¸™à¸‚้อขัดข้องไปยัง Google โดยอัตโนมัติ</translation>
-<translation id="8987927404178983737">เดือน</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ไซต์ที่จะเปิดมีโปรà¹à¸à¸£à¸¡à¸—ี่เป็นอันตราย</translation>
+<translation id="8997023839087525404">เซิร์ฟเวอร์à¹à¸ªà¸”งใบรับรองที่ไม่มีà¸à¸²à¸£à¹€à¸›à¸´à¸”เผยต่อสาธารณะโดยใช้นโยบายความโปร่งใสของใบรับรอง ซึ่งเป็นข้อà¸à¸³à¸«à¸™à¸”สำหรับใบรับรองบางรายà¸à¸²à¸£ เพื่อยืนยันว่าเชื่อถือได้à¹à¸¥à¸°à¸›à¹‰à¸­à¸‡à¸à¸±à¸™à¸à¸²à¸£à¸ˆà¸¹à¹ˆà¹‚จม</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> ของพร็อà¸à¸‹à¸µà¸•à¹‰à¸­à¸‡à¹ƒà¸Šà¹‰à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹à¸¥à¸°à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™</translation>
+<translation id="9005998258318286617">ไม่สามารถโหลดเอà¸à¸ªà¸²à¸£ PDF</translation>
<translation id="901974403500617787">à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าสถานะที่ใช้ทั้งระบบสามารถตั้งค่าได้โดยเจ้าของเท่านั้น: <ph name="OWNER_EMAIL" /></translation>
+<translation id="9020200922353704812">ต้องใส่ที่อยู่สำหรับà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¹€à¸à¹‡à¸šà¹€à¸‡à¸´à¸™à¸‚องบัตร</translation>
<translation id="9020542370529661692">หน้านี้ได้รับà¸à¸²à¸£à¹à¸›à¸¥à¹€à¸›à¹‡à¸™ <ph name="TARGET_LANGUAGE" /> à¹à¸¥à¹‰à¸§</translation>
<translation id="9035022520814077154">ข้อผิดพลาดของà¸à¸²à¸£à¸£à¸±à¸à¸©à¸²à¸„วามปลอดภัย</translation>
<translation id="9038649477754266430">ใช้บริà¸à¸²à¸£à¸à¸²à¸£à¸„าดคะเนเพื่อโหลดหน้าได้เร็วขึ้น</translation>
<translation id="9039213469156557790">นอà¸à¸ˆà¸²à¸à¸™à¸µà¹‰ หน้านี้ประà¸à¸­à¸šà¸”้วยทรัพยาà¸à¸£à¸­à¸·à¹ˆà¸™à¹† ซึ่งไม่ปลอดภัย ผู้อื่นสามารถดูทรัพยาà¸à¸£à¹€à¸«à¸¥à¹ˆà¸²à¸™à¸µà¹‰à¸‚ณะถ่ายโอน à¹à¸¥à¸°à¸œà¸¹à¹‰à¸šà¸¸à¸à¸£à¸¸à¸à¸ªà¸²à¸¡à¸²à¸£à¸–à¹à¸à¹‰à¹„ขเพื่อเปลี่ยนà¸à¸²à¸£à¸—ำงานของหน้าได้</translation>
-<translation id="9040185888511745258">ผู้บุà¸à¸£à¸¸à¸à¹€à¸¡à¸·à¹ˆà¸­à¸§à¸±à¸™à¸—ี่ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> อาจพยายามหลอà¸à¸¥à¸§à¸‡à¹ƒà¸«à¹‰à¸„ุณติดตั้งโปรà¹à¸à¸£à¸¡à¸—ี่เป็นอันตรายต่อประสบà¸à¸²à¸£à¸“์ในà¸à¸²à¸£à¸—่องเว็บของคุณ (ตัวอย่างเช่น โดยà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸«à¸™à¹‰à¸²à¹à¸£à¸à¸«à¸£à¸·à¸­à¹à¸ªà¸”งโฆษณาเพิ่มเติมบนเว็บไซต์ที่คุณเข้าชม)</translation>
+<translation id="9049981332609050619">คุณพยายามเข้าถึง <ph name="DOMAIN" /> à¹à¸•à¹ˆà¹€à¸‹à¸´à¸£à¹Œà¸Ÿà¹€à¸§à¸­à¸£à¹Œà¹à¸ªà¸”งใบรับรองที่ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
<translation id="9050666287014529139">ข้อความรหัสผ่าน</translation>
<translation id="9065203028668620118">à¹à¸à¹‰à¹„ข</translation>
<translation id="9068849894565669697">เลือà¸à¸ªà¸µ</translation>
+<translation id="9069693763241529744">ถูà¸à¸šà¸¥à¹‡à¸­à¸à¹‚ดยส่วนขยาย</translation>
<translation id="9076283476770535406">เว็บไซต์นี้อาจมีเนื้อหาสำหรับผู้ใหà¸à¹ˆ</translation>
<translation id="9078964945751709336">ต้องระบุข้อมูลเพิ่มเติม</translation>
<translation id="9103872766612412690">โดยทั่วไป <ph name="SITE" /> จะใช้à¸à¸²à¸£à¹€à¸‚้ารหัสเพื่อปà¸à¸›à¹‰à¸­à¸‡à¸‚้อมูลของคุณ เมื่อ Chromium พยายามเชื่อมต่อà¸à¸±à¸š <ph name="SITE" /> ในครั้งนี้ เว็บไซต์ดังà¸à¸¥à¹ˆà¸²à¸§à¸ªà¹ˆà¸‡à¸‚้อมูลรับรองที่ผิดปà¸à¸•à¸´à¹à¸¥à¸°à¹„ม่ถูà¸à¸•à¹‰à¸­à¸‡à¸à¸¥à¸±à¸šà¸¡à¸² เหตุà¸à¸²à¸£à¸“์นี้อาจเà¸à¸´à¸”ขึ้นเมื่อผู้บุà¸à¸£à¸¸à¸à¸žà¸¢à¸²à¸¢à¸²à¸¡à¸›à¸¥à¸­à¸¡à¹€à¸›à¹‡à¸™ <ph name="SITE" /> หรือหน้าจอà¸à¸²à¸£à¸¥à¸‡à¸Šà¸·à¹ˆà¸­à¹€à¸‚้าใช้ Wi-Fi รบà¸à¸§à¸™à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­ ข้อมูลของคุณยังปลอดภัยอยู่เนื่องจาภChromium หยุดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸à¹ˆà¸­à¸™à¸¡à¸µà¸à¸²à¸£à¹à¸¥à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸‚้อมูล</translation>
@@ -864,16 +940,21 @@
<translation id="9148507642005240123">&amp;เลิà¸à¸—ำà¸à¸²à¸£à¹à¸à¹‰à¹„ข</translation>
<translation id="9154194610265714752">อัปเดตà¹à¸¥à¹‰à¸§</translation>
<translation id="9157595877708044936">à¸à¸³à¸¥à¸±à¸‡à¸•à¸±à¹‰à¸‡à¸„่า...</translation>
+<translation id="9169664750068251925">บล็อà¸à¸šà¸™à¹„ซต์นี้เสมอ</translation>
<translation id="9170848237812810038">เ&amp;ลิà¸à¸—ำ</translation>
<translation id="917450738466192189">ใบรับรองของเซิร์ฟเวอร์ไม่ถูà¸à¸•à¹‰à¸­à¸‡</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> วิธี}other{<ph name="SHIPPING_OPTION_PREVIEW" /> à¹à¸¥à¸°à¸­à¸µà¸ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> วิธี}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> ใช้โปรโตคอลที่ไม่รองรับ</translation>
<translation id="9205078245616868884">ข้อมูลของคุณมีà¸à¸²à¸£à¹€à¸‚้ารหัสด้วยรหัสผ่านà¸à¸²à¸£à¸‹à¸´à¸‡à¸„์ โปรดป้อนรหัสผ่านเพื่อเริ่มซิงค์</translation>
<translation id="9207861905230894330">à¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡à¸šà¸—ความล้มเหลว</translation>
+<translation id="9219103736887031265">ภาพ</translation>
<translation id="933612690413056017">ไม่มีà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¸•à¹ˆà¸­à¸­à¸´à¸™à¹€à¸—อร์เน็ต</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ล้างฟอร์ม</translation>
<translation id="939736085109172342">โฟลเดอร์ใหม่</translation>
<translation id="941721044073577244">ดูเหมือนว่าคุณจะไม่มีสิทธิ์เข้าชมเว็บไซต์นี้</translation>
<translation id="969892804517981540">รุ่นที่เป็นทางà¸à¸²à¸£</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{ไม่มี}=1{1 รายà¸à¸²à¸£}other{# รายà¸à¸²à¸£}}</translation>
<translation id="988159990683914416">รุ่นนัà¸à¸žà¸±à¸’นา</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_tr.xtb b/chromium/components/strings/components_strings_tr.xtb
index 75426a1332a..91c76aa1a18 100644
--- a/chromium/components/strings/components_strings_tr.xtb
+++ b/chromium/components/strings/components_strings_tr.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Saat yönünde döndür</translation>
<translation id="1038842779957582377">bilinmeyen ad</translation>
<translation id="1050038467049342496">Diğer uygulamaları kapatın</translation>
-<translation id="1053591932240354961"><ph name="SITE" /> web sitesi Google Chrome'un işleyemediği karışık kimlik bilgileri gönderdiği için bu web sitesini şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan, bu sayfa muhtemelen daha sonra çalışacaktır. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">Eklemeyi &amp;Geri Al</translation>
<translation id="10614374240317010">Hiç kaydedilmeyecekler</translation>
<translation id="106701514854093668">Masaüstü Yer İşaretleri</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Politika önbelleği uygun</translation>
<translation id="113188000913989374"><ph name="SITE" /> web sitesinin mesajı:</translation>
<translation id="1132774398110320017">Chrome Otomatik Doldurma ayarları...</translation>
+<translation id="1150979032973867961">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Bilgisayarınızın işletim sistemi, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
+<translation id="1151972924205500581">Åžifre gerekiyor</translation>
<translation id="1152921474424827756"><ph name="URL" /> sitesinin <ph name="BEGIN_LINK" />önbelleğe alınmış bir kopyasına<ph name="END_LINK" /> erişin</translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> bağlantıyı beklenmedik şekilde kapattı.</translation>
<translation id="1161325031994447685">Kablosuz aÄŸa yeniden baÄŸlanma</translation>
+<translation id="1165039591588034296">Hata</translation>
<translation id="1175364870820465910">Ya&amp;zdır...</translation>
<translation id="1181037720776840403">Kaldır</translation>
<translation id="1184214524891303587">Olası güvenlik olaylarının ayrıntılarını Google'a <ph name="BEGIN_WHITEPAPER_LINK" />otomatik olarak bildir<ph name="END_WHITEPAPER_LINK" />. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Bu siteden daha çok</translation>
<translation id="1206967143813997005">Başlangıç anahtarlı imza hatalı</translation>
<translation id="1209206284964581585">Åžimdilik gizle</translation>
+<translation id="121201262018556460"><ph name="DOMAIN" /> alanına ulaşmayı denediniz, ancak sunucu zayıf anahtar içeren bir sertifika sundu. Bir saldırgan özel anahtarı ele geçirmiş olabilir ve sunucu beklediğiniz sunucu olmayabilir (bir saldırganla irtibat kuruyor olabilirsiniz).</translation>
<translation id="1219129156119358924">Sistem Güvenliği</translation>
<translation id="1227224963052638717">Bilinmeyen politika.</translation>
<translation id="1227633850867390598">DeÄŸeri gizle</translation>
<translation id="1228893227497259893">Yanlış varlık tanımlayıcı</translation>
<translation id="1232569758102978740">Adsız</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (senkronize edildi)</translation>
<translation id="1263231323834454256">Okuma listesi</translation>
<translation id="1264126396475825575">Kilitlenme raporu yakalanma zamanı: <ph name="CRASH_TIME" /> (henüz yüklenmedi veya yoksayıldı)</translation>
+<translation id="1281526147609854549">Yayınlayan: <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Tehlikeli içerik engellendi</translation>
<translation id="1285320974508926690">Bu siteyi hiçbir zaman çevirme</translation>
<translation id="129553762522093515">Son kapatılan</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Çerezlerinizi temizlemeyi deneyin<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Etkinliğiniz şunlar tarafından <ph name="BEGIN_EMPHASIS" />yine de görülebilir<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Ziyaret ettiÄŸiniz web siteleri
+ <ph name="LIST_ITEM" />Ä°ÅŸvereniniz veya okulunuz
+ <ph name="LIST_ITEM" />İnternet servis sağlayıcınız
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Kayıt alan adı:</translation>
<translation id="1340482604681802745">Alınacağı adres</translation>
<translation id="1344211575059133124">Bu siteyi ziyaret etmek için izne ihtiyacınız var</translation>
<translation id="1344588688991793829">Chromium Otomatik Doldurma ayarları...</translation>
+<translation id="1348198688976932919">Girmekte olduğunuz site tehlikeli uygulamalar içeriyor</translation>
<translation id="1374468813861204354">öneriler</translation>
<translation id="1375198122581997741">Sürüm Hakkında</translation>
<translation id="1377321085342047638">Kart Numarası</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> hiç veri göndermedi.</translation>
<translation id="1407135791313364759">Tümünü aç</translation>
<translation id="1413809658975081374">Gizlilik hatası</translation>
+<translation id="14171126816530869"><ph name="LOCALITY" /> konumundaki <ph name="ORGANIZATION" /> kuruluşunun kimliği <ph name="ISSUER" /> tarafından doğrulandı.</translation>
<translation id="1426410128494586442">Evet</translation>
<translation id="1430915738399379752">Yazdır</translation>
-<translation id="1442912890475371290"><ph name="BEGIN_LINK" /><ph name="DOMAIN" /> alan adındaki bir sayfayı ziyaret etme<ph name="END_LINK" /> girişimi engellendi.</translation>
-<translation id="1491663344921578213"><ph name="SITE" /> web sitesi, sertifika sabitleme yöntemini kullandığı için web sitesini şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan, bu sayfa muhtemelen daha sonra çalışacaktır. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> tane daha}other{<ph name="PAYMENT_METHOD_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> tane daha}}</translation>
<translation id="1506687042165942984">Bu sayfanın kaydedilmiş (eski olduğu bilinen) bir kopyasını gösterin.</translation>
<translation id="1517433312004943670">Telefon numarası gerekli</translation>
<translation id="1519264250979466059">OluÅŸturma Tarihi</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Bu özelliğin kullanılabilmesi için JavaScript etkinleştirilmelidir.</translation>
<translation id="1555130319947370107">Mavi</translation>
<translation id="1559528461873125649">Belirtilen dosya veya dizin yok</translation>
-<translation id="1559572115229829303">&lt;p&gt;Cihazınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> alan adına gizli bir bağlantı kurulamadı.&lt;/p&gt;
-
- &lt;p&gt;Lütfen &lt;strong&gt;Ayarlar&lt;/strong&gt; uygulamasının &lt;strong&gt;Genel&lt;/strong&gt; bölümünden tarih ve saati ayarlayın.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Bu web sayfasını görüntülerken bir hata oluştu.</translation>
<translation id="1592005682883173041">Yerel Veri EriÅŸimi</translation>
+<translation id="1594030484168838125">Seç</translation>
<translation id="161042844686301425">Camgöbeği</translation>
+<translation id="1620510694547887537">Kamera</translation>
<translation id="1629803312968146339">Chrome'un bu kartı kaydetmesini istiyor musunuz?</translation>
<translation id="1639239467298939599">Yükleniyor</translation>
<translation id="1640180200866533862">Kullanıcı politikaları</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Ağ yapılandırması geçersiz, dolayısıyla içe aktarılamadı.</translation>
<translation id="1644574205037202324">Geçmiş</translation>
<translation id="1645368109819982629">Desteklenmeyen protokol</translation>
+<translation id="1655462015569774233">{1,plural, =1{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının süresi dün sona erdi. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. Bilgisayarınızın saati geçerli olarak <ph name="CURRENT_DATE" /> tarihine ayarlı. Bu ayar doğru görünüyor mu? Değilse, sisteminizin saatini düzeltmeli ve sonra bu sayfayı yenilemelisiniz.}other{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası # gün önce sona erdi. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. Bilgisayarınızın saati geçerli olarak <ph name="CURRENT_DATE" /> tarihine ayarlı. Bu ayar doğru görünüyor mu? Değilse, sisteminizin saatini düzeltmeli ve sonra bu sayfayı yenilemelisiniz.}}</translation>
<translation id="1656489000284462475">Alma</translation>
<translation id="1663943134801823270">Kartlar ve adresler Chrome'dan alınmaktadır. Bu bilgileri <ph name="BEGIN_LINK" />Ayarlar<ph name="END_LINK" />'dan yönetebilirsiniz.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> normalde bilgilerinizi korumak için şifreleme kullanmaktadır. Google Chrome bu sefer <ph name="SITE" /> sitesine bağlanmayı denediğinde, web sitesi sıra dışı ve yanlış kimlik bilgileri döndürdü. Bir saldırgan <ph name="SITE" /> gibi davranmaya çalışıyor olabilir ya da bir Kablosuz oturum açma ekranı bağlantıyı kesmiştir. Google Chrome herhangi bir veri alışverişinden önce bağlantıyı durdurduğu için bilgileriniz hâlâ güvendedir.</translation>
-<translation id="168328519870909584">Şu anda <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesinde bulunan saldırganlar, cihazınıza bilgilerinizi (örneğin fotoğraflar, şifreler, mesajlar ve kredi kartları) çalacak veya silecek tehlikeli uygulamalar yüklemeyi deneyebilir.</translation>
<translation id="168841957122794586">Sunucu sertifikasında zayıf bir şifreleme anahtarı var.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının alınma tarihinin yarın olduğu iddia ediliyor. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir.}other{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının alınma tarihinin # gün sonra olduğu iddia ediliyor. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Bu siteyi ziyaret etmek için <ph name="NAME" /> size izin vermelidir</translation>
<translation id="1721424275792716183">* Zorunlu alan</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Sayfayı daha sonra indir</translation>
<translation id="17513872634828108">Açık sekmeler</translation>
<translation id="1753706481035618306">Sayfa numarası</translation>
+<translation id="1763864636252898013">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. cihazınızın işletim sistemi, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Windows Ağ Teşhislerini çalıştırmayı deneyin<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Lütfen senkronizasyon parolanızı güncelleyin.</translation>
<translation id="1787142507584202372">Açık sekmeleriniz burada görünür</translation>
+<translation id="1789575671122666129">Pop-up'lar</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Kart Sahibinin Adı</translation>
-<translation id="1803678881841855883">Google Güvenli Tarama, yakın bir zamanda <ph name="SITE" /> web sitesinde <ph name="BEGIN_LINK" />kötü amaçlı yazılım tespit etti<ph name="END_LINK" />. Normalde güvenli olan web sitelerine bazen kötü amaçlı yazılımlar bulaşır. Kötü amaçlı içerik, kötü amaçlı yazılım dağıtımcısı olduğu bilinen <ph name="SUBRESOURCE_HOST" /> kaynağından gelmektedir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Eklenme tarihi: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Geçersiz istek veya istek parametreleri</translation>
<translation id="1826516787628120939">Kontrol ediliyor</translation>
<translation id="1834321415901700177">Bu site zararlı programlar içeriyor</translation>
+<translation id="1840414022444569775">Bu kart numarası zaten kullanılıyor</translation>
<translation id="1842969606798536927">Ödeme</translation>
<translation id="1871208020102129563">Proxy, bir .pac komut dosyası URL'sini değil, sabit proxy sunucuları kullanacak şekilde ayarlanır.</translation>
<translation id="1871284979644508959">Zorunlu alan</translation>
<translation id="187918866476621466">Başlangıç sayfalarını aç</translation>
<translation id="1883255238294161206">Listeyi daralt</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> tane daha}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> tane daha}}</translation>
<translation id="1898423065542865115">Filtreleme</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Yok}=1{1 site}other{# site}}</translation>
<translation id="194030505837763158"><ph name="LINK" /> adresine git</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> Yer Ä°ÅŸaretleri</translation>
<translation id="1973335181906896915">Serileştirme hatası</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> tarafından geçersiz kılındığı için yoksayıldı.</translation>
<translation id="2138201775715568214">Yakınlardaki Fiziksel Web sayfaları aranıyor</translation>
<translation id="213826338245044447">Mobil Yer Ä°ÅŸaretleri</translation>
-<translation id="2148716181193084225">Bugün</translation>
+<translation id="2147827593068025794">Arka Plan Senkronizasyonu</translation>
<translation id="2154054054215849342">Senkronizasyon alan adınızda kullanılamıyor</translation>
<translation id="2154484045852737596">Kartı düzenle</translation>
<translation id="2166049586286450108">Tam Yönetici Erişimi</translation>
<translation id="2166378884831602661">Bu site güvenli bağlantı sağlayamıyor</translation>
<translation id="2181821976797666341">Politikalar</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adres}other{# adres}}</translation>
+<translation id="2187317261103489799">Algıla (varsayılan)</translation>
<translation id="2202020181578195191">Geçerli bir son kullanma yılı girin</translation>
<translation id="2212735316055980242">Politika bulunamadı</translation>
<translation id="2213606439339815911">GiriÅŸler getiriliyor...</translation>
+<translation id="2218879909401188352">Şu anda <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> öğesini kullanan saldırganlar cihazınıza zarar verebilecek uygulamalar yükleyebilir, sizden habersiz mobil faturanıza ücretler ekleyebilir veya kişisel bilgilerinizi çalabilirler. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />Tanılama uygulamasını<ph name="END_LINK" /> kullanarak bağlantınızı düzeltin</translation>
<translation id="2239100178324503013">Şimdi gönder</translation>
<translation id="225207911366869382">Bu değer bu politika için kullanımdan kaldırıldı.</translation>
<translation id="2262243747453050782">HTTP hatası</translation>
+<translation id="2270484714375784793">Telefon numarası</translation>
<translation id="2282872951544483773">Kullanılamayan Deneyler</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> öğe}other{<ph name="ITEM_COUNT" /> öğe}}</translation>
<translation id="2292556288342944218">Ä°nternet eriÅŸiminiz engellendi</translation>
<translation id="230155334948463882">Yeni bir kart mı?</translation>
-<translation id="2305919008529760154">Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası hileli bir şekilde yayınlanmış olabilir. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> için kullanıcı adı ve şifre gerekiyor.</translation>
-<translation id="2318774815570432836"><ph name="SITE" /> web sitesi HSTS kullandığı için bu web sitesini şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan, bu sayfa muhtemelen daha sonra çalışacaktır. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Ayar yöneticinizin kontrolü altındadır</translation>
<translation id="2354001756790975382">DiÄŸer yer iÅŸaretleri</translation>
+<translation id="2354430244986887761">Google Güvenli Tarama son zamanlarda <ph name="SITE" /> sitesinde <ph name="BEGIN_LINK" />zararlı uygulamalar buldu<ph name="END_LINK" />.</translation>
<translation id="2355395290879513365">Saldırganlar bu sitede baktığınız resimleri görebilir ve bu resimler üzerinde değişiklik yaparak sizi kandırabilirler.</translation>
+<translation id="2356070529366658676">Sor</translation>
+<translation id="2359629602545592467">Birden fazla</translation>
<translation id="2359808026110333948">Devam Et</translation>
<translation id="2365563543831475020">Yakalanan kilitlenme raporu (<ph name="CRASH_TIME" />) yüklenmedi</translation>
<translation id="2367567093518048410">Düzey</translation>
-<translation id="2371153335857947666">{1,plural, =1{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının süresi dün sona erdi. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. Bilgisayarınızın saati şu anda <ph name="CURRENT_DATE" /> olarak ayarlanmış. Bu tarih doğru mu? Değilse, sisteminizin saatini düzeltmeli ve sonra bu sayfayı yenilemelisiniz. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.}other{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası # gün önce sona erdi. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. Bilgisayarınızın saati şu anda <ph name="CURRENT_DATE" /> olarak ayarlanmış. Bu tarih doğru mu? Değilse, sisteminizin saatini düzeltmeli ve sonra bu sayfayı yenilemelisiniz. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Mevcut kullanıcı arayüzü alternatifi yok</translation>
<translation id="2384307209577226199">Kuruluşun varsayılan ayarı</translation>
<translation id="2386255080630008482">Sunucunun sertifikası iptal edildi.</translation>
<translation id="2392959068659972793">Hiçbir değer ayarlanmamış politikaları göster</translation>
<translation id="239429038616798445">Bu gönderim yöntemi kullanılamıyor. Farklı bir yöntem deneyin.</translation>
<translation id="2396249848217231973">Silmeyi &amp;geri al</translation>
-<translation id="2460160116472764928">Google Güvenli Tarama, yakın bir zamanda <ph name="SITE" /> web sitesinde <ph name="BEGIN_LINK" />kötü amaçlı yazılım tespit etti<ph name="END_LINK" />. Normalde güvenli olan web sitelerine bazen kötü amaçlı yazılımlar bulaşır. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası iptal edilmiş olabilir. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="2463739503403862330">Doldur</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Ağ Teşhislerini Çalıştırma<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">Geçersiz arama URL'si.</translation>
+<translation id="2482878487686419369">Bildirimler</translation>
<translation id="2491120439723279231">Sunucu sertifikası hatalar içeriyor.</translation>
<translation id="2495083838625180221">JSON Ayrıştırıcı</translation>
<translation id="2495093607237746763">İşaretlenirse Chromium, formları daha hızlı doldurma amacıyla kartınızın bir kopyasını bu cihazda depolar.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Geri dön</translation>
<translation id="2515629240566999685">Bulunduğunuz bölgedeki sinyali kontrol etme</translation>
<translation id="2516305470678292029">Kullanıcı Arayüzü Alternatifleri</translation>
+<translation id="2539524384386349900">Algıla</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> geçersiz bir yanıt gönderdi.</translation>
-<translation id="2552545117464357659">Daha yeni</translation>
<translation id="2556876185419854533">Düzenlemeyi &amp;Geri Al</translation>
<translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> adlı yayıncıdan. Bunu ve diğer <ph name="OTHER_ARTICLE_COUNT" /> haberi okuyun.</translation>
<translation id="2587841377698384444">Dizin API'sı Kimliği:</translation>
<translation id="2597378329261239068">Doküman şifre korumalı. Lütfen şifreyi girin.</translation>
<translation id="2609632851001447353">Varyasyonlar</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Yok}=1{1 uygulama ($1)}=2{2 uygulama ($1, $2)}other{# uygulama ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Saatiniz ileri</translation>
<translation id="2639739919103226564">Durum:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Dosyaya eriÅŸim reddedildi</translation>
<translation id="2653659639078652383">Gönder</translation>
<translation id="2666117266261740852">Diğer sekmeleri veya uygulamaları kapatın</translation>
+<translation id="2670429602441959756">Bu sayfa henüz Sanal Gerçeklik'te desteklenmeyen özellikler içeriyor. Sayfadan çıkılıyor...</translation>
<translation id="2674170444375937751">Bu sayfaları geçmişinizden silmek istediğinizden emin misiniz?</translation>
<translation id="2677748264148917807">Çık</translation>
-<translation id="269990154133806163">Sunucu, Sertifika Şeffaflığı politikası kullanılarak herkese açık bir şekilde sağlanmayan bir sertifika sundu. Güvenilir olduklarından emin olmak ve saldırganlara karşı korunmak için bazı sertifikalarda bu zorunludur. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Okuma Listesi</translation>
<translation id="2704283930420550640">Değer, biçimle eşleşmiyor.</translation>
<translation id="2704951214193499422">Chromium, şu anda kartınızı onaylayamıyor. Lütfen daha sonra tekrar deneyin.</translation>
<translation id="2705137772291741111">Bu sitenin kaydedilen (önbelleğe alınan) kopyası okunamadı.</translation>
<translation id="2709516037105925701">Otomatik doldurma</translation>
-<translation id="2712118517637785082"><ph name="DOMAIN" /> alan adına ulaşmayı denediniz, ancak sunucunun sağladığı sertifika, sertifikayı veren tarafından iptal edildi. Bu durum, sunucunun sağladığı güvenlik kimlik bilgilerine kesinlikle güvenilmemesi gerektiği anlamına gelir. Bir saldırganla irtibat kuruyor olabilirsiniz. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Ä°zin iste</translation>
<translation id="2713444072780614174">Beyaz</translation>
<translation id="2720342946869265578">Etrafımda</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Eksik cihaz kaydı</translation>
<translation id="2784949926578158345">Bağlantı sıfırlandı.</translation>
<translation id="2794233252405721443">Site engellenmiÅŸ</translation>
+<translation id="2799020568854403057">Girmekte olduğunuz site zararlı uygulamalar içeriyor</translation>
+<translation id="2803306138276472711">Google Güvenli Tarama yakın bir zamanda <ph name="SITE" /> sitesinde <ph name="BEGIN_LINK" />kötü amaçlı yazılım<ph name="END_LINK" /> tespit etti. Normalde güvenli olan web sitelerine bazen kötü amaçlı yazılımlar bulaşır.</translation>
<translation id="2824775600643448204">Adres ve arama çubuğu</translation>
<translation id="2826760142808435982">Bağlantı <ph name="CIPHER" /> kullanılarak şifrelenmiş ve kimliği doğrulanmıştır. Anahtar değişim mekanizması olarak <ph name="KX" /> kullanılır.</translation>
<translation id="2835170189407361413">Formu temizle</translation>
+<translation id="2856444702002559011">Saldırganlar <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> üzerinden bilgilerinizi çalmaya çalışıyor olabilir (örneğin, şifreler, mesajlar veya kredi kartları). <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Yeniden Yükleme</translation>
<translation id="2900469785430194048">Bu web sayfası görüntülenmeye çalışılırken Google Chrome'da bellek kalmadı.</translation>
<translation id="2909946352844186028">Bir ağ değişikliği algılandı.</translation>
<translation id="2916038427272391327">Diğer programları kapatın</translation>
<translation id="2922350208395188000">Sunucunun sertifikası kontrol edilemiyor.</translation>
<translation id="2928905813689894207">Fatura Adresi</translation>
+<translation id="2941952326391522266">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası <ph name="DOMAIN2" /> alan adından geliyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="2948083400971632585">Ayarlar sayfasından, bir bağlantı için yapılandırılmış proxy'leri devre dışı bırakabilirsiniz.</translation>
<translation id="2955913368246107853">Bulma çubuğunu kapat</translation>
<translation id="2958431318199492670">Ağ yapılandırması ONC standardıyla uyumlu değil. Yapılandırmanın bazı bölümleri içe aktarılamaz.</translation>
-<translation id="29611076221683977">Şu anda <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesinde bulunan saldırganlar, Mac makinenize bilgilerinizi (örneğin fotoğraflar, şifreler, mesajlar ve kredi kartları) çalacak veya silecek tehlikeli programlar yüklemeyi deneyebilir.</translation>
<translation id="2966678944701946121">Son kullanım tarihi: <ph name="EXPIRATION_DATE_ABBR" />, eklenme tarihi: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Güvenli bir bağlantı kurmak için saatinizin doğru ayarlanmış olması gerekir. Bunun sebebi, web sitelerinin kendilerini tanımlamak için kullandıkları sertifikaların sadece belli süreler için geçerli olmasıdır. Cihazınızın saati yanlış olduğundan, Google Chrome bu sertifikaları doğrulayamıyor.</translation>
<translation id="2972581237482394796">&amp;Yinele</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Geçerli bir adres girin</translation>
<translation id="2986368408720340940">Bu alım yöntemi kullanılamıyor. Farklı bir yöntem deneyin.</translation>
<translation id="2991174974383378012">Web Siteleriyle PaylaÅŸma</translation>
+<translation id="2991571918955627853"><ph name="SITE" /> web sitesi HSTS kullandığından şu anda siteyi ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan bu sayfa muhtemelen daha sonra çalışacaktır.</translation>
<translation id="3005723025932146533">Kaydedilen kopyayı göster</translation>
<translation id="3008447029300691911"><ph name="CREDIT_CARD" /> numaralı kartın CVC kodunu girin. Onayladığınızda kart ayrıntılarınız bu siteyle paylaşılacaktır.</translation>
<translation id="3010559122411665027">Liste giriÅŸi "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Otomatik olarak engellendi</translation>
<translation id="3024663005179499861">Yanlış politika türü</translation>
<translation id="3032412215588512954">Bu siteyi yeniden yüklemek istiyor musunuz?</translation>
<translation id="3037605927509011580">Hay aksi!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{senkronize edilmiş cihazlarda en az 1 öğe}=1{1 öğe (ve senkronize edilmiş cihazlarda daha fazlası)}other{# öğe (ve senkronize edilmiş cihazlarda daha fazlası)}}</translation>
<translation id="3041612393474885105">Sertifika Bilgileri</translation>
<translation id="3063697135517575841">Chrome şu anda kartınızı onaylayamıyor. Lütfen daha sonra tekrar deneyin.</translation>
<translation id="3064966200440839136">Harici bir uygulama üzerinden ödeme gerçekleştirmek için gizli moddan çıkılacak. Devam edilsin mi?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Yok}=1{1 ÅŸifre}other{# ÅŸifre}}</translation>
<translation id="3093245981617870298">Çevrimdışısınız.</translation>
<translation id="3105172416063519923">Öğe Kimliği:</translation>
<translation id="3109728660330352905">Bu sayfayı görüntüleme yetkiniz yok.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Bağlantı Teşhislerini çalıştırmayı deneyin<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Yanıtın kodu çözülemedi</translation>
<translation id="3150653042067488994">Geçici sunucu hatası</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Gizli sekmelerde görüntülediğiniz sayfalar, açık olan tüm gizli sekmeler kapatıldıktan sonra tarayıcınızın geçmişinden, çerez deposundan veya arama geçmişinden silinecektir. İndirdiğiniz dosyalar veya oluşturduğunuz yer işaretleri kalacaktır.</translation>
<translation id="3169472444629675720">Bul</translation>
<translation id="3174168572213147020">Ada</translation>
+<translation id="317583078218509884">Yeni site izinleri için ayarlar sayfa yeniden yüklendikten sonra geçerli olacaktır.</translation>
<translation id="3176929007561373547">Proxy sunucunun çalışıyor olduğundan emin olmak için
proxy ayarlarınızı kontrol edin veya ağ yöneticinize danışın. Proxy sunucu
kullanmamanız gerektiğini düşünüyorsanız:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Sayfayı Gizli modda açın</translation>
-<translation id="3202578601642193415">En yeni</translation>
+<translation id="320323717674993345">Ödemeyi iptal et</translation>
<translation id="3207960819495026254">Yer iÅŸareti koyuldu</translation>
+<translation id="3225919329040284222">Sunucu, yerleşik beklentilerle eşleşmeyen bir sertifika sundu. Bu beklentiler sizi korumak amacıyla bazı yüksek güvenlikli web sitelerinde bulunur.</translation>
<translation id="3226128629678568754">Sayfayı yüklemek üzere gereken verileri tekrar göndermek için yeniden yükle düğmesine basın.</translation>
+<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Sayfa zaten <ph name="LANGUAGE" /> dilinde olduğundan çeviri işlemi başarısız oldu.</translation>
<translation id="323107829343500871"><ph name="CREDIT_CARD" /> numaralı kartın CVC kodunu girin</translation>
+<translation id="3234666976984236645">Her zaman bu sitedeki önemli içeriği algıla</translation>
<translation id="3254409185687681395">Bu sayfaya yer iÅŸareti koy</translation>
<translation id="3270847123878663523">Sıralama Değişikliğini &amp;Geri Al</translation>
<translation id="3282497668470633863">Kart üzerindeki ismi ekle</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">ayarlar</translation>
<translation id="3345135638360864351">Bu siteye erişim isteğiniz <ph name="NAME" /> adlı kullanıcıya gönderilemedi. Lütfen tekrar deneyin.</translation>
<translation id="3355823806454867987">Proxy ayarlarını değiştir...</translation>
+<translation id="3361596688432910856">Chrome aşağıdaki bilgileri <ph name="BEGIN_EMPHASIS" />kaydetmez<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Tarama geçmişiniz
+ <ph name="LIST_ITEM" />Çerezler ve site verileri
+ <ph name="LIST_ITEM" />Formlara girilen bilgiler
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Saat hatası</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> öğe daha...</translation>
<translation id="337363190475750230">Temel hazırlık iptal edildi</translation>
<translation id="3377188786107721145">Politika ayrıştırma hatası</translation>
<translation id="3380365263193509176">Bilinmeyen hata</translation>
<translation id="3380864720620200369">Ä°stemci KimliÄŸi:</translation>
<translation id="3391030046425686457">Teslimat adresi</translation>
<translation id="3395827396354264108">Alım yöntemi</translation>
-<translation id="340013220407300675">Saldırganlar <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesinden bilgilerinizi çalmaya çalışıyor olabilir (örneğin, şifreler, mesajlar veya kredi kartı bilgileri).</translation>
<translation id="3422248202833853650">Bellekte yer açmak için diğer programlardan çıkmayı deneyin.</translation>
<translation id="3422472998109090673"><ph name="HOST_NAME" /> ana makinesine şu anda ulaşılamıyor.</translation>
+<translation id="3427092606871434483">İzin ver (varsayılan)</translation>
<translation id="3427342743765426898">&amp;Düzenlemeyi Yeniden Yap</translation>
<translation id="3431636764301398940">Bu kartı bu cihaza kaydet</translation>
<translation id="3435896845095436175">EtkinleÅŸtir</translation>
<translation id="3447661539832366887">Bu cihazın sahibi dinozor oyununu kapattı.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Getirme aralığı:</translation>
<translation id="3462200631372590220">GeliÅŸmiÅŸ bilgileri gizle</translation>
<translation id="3467763166455606212">Kart sahibinin adı zorunludur</translation>
<translation id="3478058380795961209">Son Kullanım Ayı</translation>
<translation id="3479539252931486093">Bu beklenmedik bir durum mu? <ph name="BEGIN_LINK" />Bize bildirin<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Åžimdi deÄŸil</translation>
-<translation id="348000606199325318">Kilitlenme KimliÄŸi: <ph name="CRASH_LOCAL_ID" /> (Sunucu KimliÄŸi: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Şu anda ebeveyninize erişemedik. Lütfen tekrar deneyin.</translation>
<translation id="3528171143076753409">Sunucunun sertifikasına güvenilmiyor.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Senkronize edilmiş cihazlarda en az 1 öğe}=1{1 öğe (ve senkronize edilmiş cihazlarda daha fazlası)}other{# öğe (ve senkronize edilmiş cihazlarda daha fazlası)}}</translation>
<translation id="3539171420378717834">Bu kartın bir kopyasını bu cihazda tut</translation>
<translation id="3542684924769048008">Şunun için şifre kullan:</translation>
+<translation id="3545341443414427877">Bilgisayarınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ile gizli bağlantı kurulamıyor. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Senkronize edilen tüm verileri kendi senkronizasyon parolanızla şifreleyin</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> tane daha...</translation>
-<translation id="3555561725129903880">Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası <ph name="DOMAIN2" /> alan adından geliyor. Bu durum yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">Yöneticiniz engellemeyi kaldırabilir</translation>
<translation id="3566021033012934673">Bağlantınız gizli değil</translation>
+<translation id="3569145463236695319">&lt;p&gt;Cihazınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ile gizli bir bağlantı kurulamıyor.&lt;/p&gt;
+
+ &lt;p&gt;Lütfen &lt;strong&gt;Ayarlar&lt;/strong&gt; uygulamasının &lt;strong&gt;Genel&lt;/strong&gt; bölümünden tarih ve saati ayarlayın.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Ad ekleyin</translation>
<translation id="3583757800736429874">Taşımayı &amp;Yeniden Yap</translation>
<translation id="3586931643579894722">Ayrıntıları gizle</translation>
-<translation id="3587482841069643663">Tümü</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Geçerli bir son kullanma tarihi girin</translation>
<translation id="36224234498066874">Göz Atma Verilerini Temizle...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Sertifika bilgileri</translation>
<translation id="3690164694835360974">Giriş yapma işlemi güvenli değil</translation>
<translation id="3693415264595406141">Åžifre:</translation>
-<translation id="3696411085566228381">yok</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Yükleniyor...</translation>
<translation id="3712624925041724820">Lisanslar bitti</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Proxy, güvenlik duvarı ve DNS yapılandırmasını kontrol etme<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Güvenliğinizle ilgili riskleri anlıyorsanız tehlikeli programlar kaldırılmadan önce <ph name="BEGIN_LINK" />güvenli olmayan bu siteyi ziyaret edebilirsiniz<ph name="END_LINK" />.</translation>
<translation id="3739623965217189342">Kopyaladığınız bağlantı</translation>
+<translation id="3744899669254331632">Web sitesi Chromium'un işleyemediği karışık kimlik bilgileri gönderdiğinden <ph name="SITE" /> sitesini şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici türdendir, dolayısıyla bu sayfa muhtemelen daha sonra çalışacaktır.</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesine saldıranlar sizi yanıltarak yazılım yüklemek veya kişisel bilgilerinizi (örneğin, şifreler, telefon numaraları veya kredi kartları) ifşa etmek gibi tehlikeli bir şey yapmanızı sağlayabilirler. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Çeviri, bir sunucu hatası nedeniyle başarısız oldu.</translation>
<translation id="3759461132968374835">Son zamanda herhangi bir kilitlenme bildirmediniz. Kilitlenme bildirme özelliği devre dışıyken oluşan kilitlenmeler burada görünmez.</translation>
+<translation id="3778403066972421603">Bu kartı Google Hesabınıza ve bu cihaza kaydetmek istiyor musunuz?</translation>
+<translation id="3783418713923659662">MasterCard</translation>
<translation id="3787705759683870569">Son kullanma tarihi: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Proxy sunucu kullanıyorsanız...</translation>
<translation id="3828924085048779000">BoÅŸ parolaya izin verilmez.</translation>
-<translation id="3845539888601087042">Oturum açtığınız cihazlardan geçmiş bilgileri gösteriliyor. <ph name="BEGIN_LINK" />Daha fazla bilgi edinin<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Geri</translation>
<translation id="3858027520442213535">Tarih ve saati güncelle</translation>
<translation id="3884278016824448484">Çakışan cihaz tanımlayıcısı</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Bu siteye erişim isteğiniz şu kişiye gönderildi: <ph name="NAME" /></translation>
<translation id="3890664840433101773">E-posta adresi ekle</translation>
<translation id="3901925938762663762">Kartın kullanım süresi doldu</translation>
-<translation id="3933571093587347751">{1,plural, =1{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının alınma tarihinin yarın olduğu iddia ediliyor. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.}other{Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasının alınma tarihinin # gün sonra olduğu iddia ediliyor. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">PDF dokümanı yüklenemedi</translation>
+<translation id="3945915738023014686">Kilitlenme Raporu Kimliği <ph name="CRASH_ID" /> Yüklendi (Yerel Kilitlenme Kimliği: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasında Konu Diğer Adları belirtilmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="3963721102035795474">Okuyucu Modu</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Yok}=1{1 siteden }other{# siteden }}</translation>
<translation id="397105322502079400">Hesaplanııyor...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> engellendi</translation>
+<translation id="3987940399970879459">1 MB'tan az</translation>
<translation id="40103911065039147">{URL_count,plural, =1{Yakındaki 1 web sayfası}other{Yakındaki # web sayfası}}</translation>
<translation id="4021036232240155012">DNS, bir web sitesinin adını o siteye özgü İnternet adresine dönüştüren ağ hizmetidir.</translation>
<translation id="4030383055268325496">Eklemeyi &amp;geri al</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Proxy yapılandırması sabit proxy sunucuları değil, bir .pac komut dosyası URL'sini kullanmak üzere ayarlandı.</translation>
<translation id="4098354747657067197">Yanıltıcı bir siteye girmek üzeresiniz</translation>
<translation id="4103249731201008433">Cihazın seri numarası geçersiz</translation>
+<translation id="410351446219883937">Otomatik oynatma</translation>
<translation id="4103763322291513355">Kara listeye alınmış URL'lerin ve sistem yöneticinizin zorunlu tuttuğu diğer politikaların listesini görmek için &lt;strong&gt;chrome://policy&lt;/strong&gt; adresini ziyaret edin.</translation>
-<translation id="4110615724604346410">Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası hatalar içeriyor. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Macenta</translation>
+<translation id="4116663294526079822">Bu sitede her zaman izin ver</translation>
<translation id="4117700440116928470">Politika kapsamı desteklenmiyor.</translation>
-<translation id="4118212371799607889">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Chromium, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 öğe daha}other{# öğe daha}}</translation>
<translation id="4130226655945681476">Ağ kabloları, modem ve yönlendirici kontrol ediliyor</translation>
+<translation id="413544239732274901">Daha fazla bilgi</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Genel varsayılanı kullan (Algıla)</translation>
+<translation id="4165986682804962316">Site ayarları</translation>
<translation id="4169947484918424451">Chromium'un bu kartı kaydetmesini istiyor musunuz?</translation>
<translation id="4171400957073367226">Geçersiz doğrulama imzası</translation>
<translation id="4196861286325780578">Taşımayı &amp;yeniden yap</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Güvenlik duvarı ve virüsten korunma yapılandırmalarını kontrol etme<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{yok}=1{1 uygulama ($1)}=2{2 uygulama ($1, $2)}other{# uygulama ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Kilitlenmeler</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesine saldıranlar sizi yanıltarak göz atma deneyiminize zarar verecek (örneğin, ana sayfanızı değiştirecek veya ziyaret ettiğiniz sitelerde ek reklamlar gösterecek) programlar yüklemenizi sağlayabilirler. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Ağ Teşhislerini çalıştırmayı deneyin<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Geçerli</translation>
<translation id="4250431568374086873">Bu siteye bağlantınız tam olarak güvenli değil</translation>
<translation id="4250680216510889253">Hayır</translation>
<translation id="425582637250725228">Yaptığınız değişiklikler kaydedilmemiş olabilir.</translation>
<translation id="4258748452823770588">İmza yanlış</translation>
+<translation id="4265872034478892965">Yöneticiniz tarafından izin verildi</translation>
<translation id="4269787794583293679">(Kullanıcı adı yok)</translation>
<translation id="4275830172053184480">Cihazınızı yeniden başlatın</translation>
<translation id="4280429058323657511">, son kullanma tarihi <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google Güvenli Tarama, yakın bir zamanda <ph name="SITE" /> web sitesinde <ph name="BEGIN_LINK" />zararlı programlar buldu<ph name="END_LINK" />. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Ebeveyn önerileri</translation>
<translation id="4304224509867189079">GiriÅŸ Yap</translation>
-<translation id="432290197980158659">Sunucu, yerleşik beklentilerle eşleşmeyen bir sertifika sundu. Bu beklentiler sizi korumak amacıyla bazı yüksek güvenlikli web sitelerinde bulunur. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Engelle (varsayılan)</translation>
<translation id="4325863107915753736">Makale bulunamadı</translation>
<translation id="4326324639298822553">Son kullanma tarihini kontrol edip tekrar deneyin</translation>
<translation id="4331708818696583467">Güvenli Değil</translation>
<translation id="4356973930735388585">Bu sitedeki saldırganlar, bilgilerinizi (örneğin fotoğraflar, şifreler, mesajlar ve kredi kartları) çalacak veya silecek tehlikeli programları bilgisayarınıza yüklemeyi deneyebilir.</translation>
<translation id="4372948949327679948">Beklenen <ph name="VALUE_TYPE" /> deÄŸeri.</translation>
+<translation id="4377125064752653719"><ph name="DOMAIN" /> adresine ulaşmayı denediniz, ancak sunucunun sağladığı sertifika, sertifikayı veren tarafından iptal edildi. Bu, sunucunun sağladığı güvenlik kimlik bilgilerine kesinlikle güvenilmemesi gerektiği anlamına gelir. Bir saldırganla irtibat kuruyor olabilirsiniz.</translation>
<translation id="4381091992796011497">Kullanıcı Adı:</translation>
<translation id="4394049700291259645">Devre dışı bırak</translation>
<translation id="4406896451731180161">arama sonuçları</translation>
+<translation id="4424024547088906515">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Chrome, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> giriş sertifikanızı kabul etmedi veya giriş sertifikası sağlanmamış olabilir.</translation>
<translation id="443673843213245140">Proxy kullanımı devre dışı, ancak açık bir proxy yapılandırması belirtildi.</translation>
-<translation id="4492190037599258964">'<ph name="SEARCH_STRING" />' için arama sonuçları</translation>
<translation id="4506176782989081258">Doğrulama hatası: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Sistem yöneticisiyle iletişime geçme</translation>
<translation id="450710068430902550">Yöneticiyle Paylaşma</translation>
<translation id="4515275063822566619">Kart ve adres bilgileri Chrome'dan ve Google Hesabınızdan (<ph name="ACCOUNT_EMAIL" />) alınmaktadır. Bunları <ph name="BEGIN_LINK" />Ayarlar<ph name="END_LINK" />'dan yönetebilirsiniz.</translation>
<translation id="4522570452068850558">Ayrıntılar</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Uzantılarınızı devre dışı bırakmayı deneyin</translation>
<translation id="457875822857220463">Teslimat</translation>
<translation id="4587425331216688090">Adres Chrome'dan kaldırılsın mı?</translation>
-<translation id="4589078953350245614"><ph name="DOMAIN" /> alan adına erişmeyi denediniz, ancak sunucu geçersiz bir sertifika sundu. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" /> ile olan bağlantınız modern bir şifre seti kullanılarak şifrelendi.</translation>
<translation id="4594403342090139922">Silmeyi &amp;Geri Al</translation>
<translation id="4619615317237390068">DiÄŸer cihazlardan sekmeler</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikasında hatalar var. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
+<translation id="4690462567478992370">Geçersiz sertifika kullanımını durdur</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Bağlantınız kesildi</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows Ağ Teşhislerini Çalıştırma<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Bilinmeyen bir hata oluÅŸtu.</translation>
<translation id="4800132727771399293">Son kullanma tarihinizi ve CVC'nizi kontrol edip tekrar deneyin</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102"><ph name="SITE" /> web sitesi Google Chrome'un işleyemediği karışık kimlik bilgileri gönderdiği için bu siteyi şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan bu sayfa muhtemelen daha sonra çalışacaktır.</translation>
<translation id="4813512666221746211">Ağ hatası</translation>
<translation id="4816492930507672669">Sayfaya sığdır</translation>
<translation id="483020001682031208">Gösterilecek Fiziksel Web sayfası yok</translation>
<translation id="4850886885716139402">Görüntüle</translation>
<translation id="4854362297993841467">Bu teslimat yöntemi kullanılamıyor. Farklı bir yöntem deneyin.</translation>
<translation id="4858792381671956233">Ebeveynlerinize bu siteyi ziyaret etmenizin uygun olup olmadığını sordunuz</translation>
+<translation id="4863764087567530506">Bu içerik sizi kandırarak yazılım yüklemenizi veya kişisel bilgilerinizi ifşa etmenizi sağlamaya çalışabilir. <ph name="BEGIN_LINK" />Yine de göster<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Geçmişte ara</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{ve 1 web sayfası daha}other{ve # web sayfası daha}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Bu sayfa, bilinmeyen bir dilden <ph name="LANGUAGE_LANGUAGE" /> diline çevrildi</translation>
<translation id="4923459931733593730">Ödeme</translation>
<translation id="4926049483395192435">Belirtilmelidir.</translation>
<translation id="495170559598752135">Ä°ÅŸlemler</translation>
<translation id="4958444002117714549">Listeyi geniÅŸlet</translation>
-<translation id="4962322354953122629">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Chrome, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Uyarıları yeniden etkinleştir</translation>
<translation id="4989809363548539747">Bu eklenti desteklenmiyor</translation>
<translation id="5002932099480077015">Bu seçenek etkinleştirildiğinde Chrome, formları daha hızlı doldurmak için kartınızın bir kopyasını bu cihazda saklar.</translation>
<translation id="5018422839182700155">Bu sayfa açılamıyor</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Yöneticinizin politikalarını inceleyin.</translation>
<translation id="5029568752722684782">Kopyayı temizle</translation>
<translation id="5031870354684148875">Google Çeviri Hakkında</translation>
+<translation id="5039804452771397117">Ä°zin ver</translation>
<translation id="5040262127954254034">Gizlilik</translation>
<translation id="5045550434625856497">Hatalı parola</translation>
<translation id="5056549851600133418">Size uygun makaleler</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Proxy adresini kontrol etme<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Çerez yok}=1{1 site çerez kullanıyor. }other{# site çerez kullanıyor. }}</translation>
<translation id="5087286274860437796">Sunucu sertifikası şu anda geçerli değil.</translation>
<translation id="5087580092889165836">Kart ekle</translation>
<translation id="5089810972385038852">Eyalet</translation>
+<translation id="5094747076828555589">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı; Chromium, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="5095208057601539847">Bölge</translation>
<translation id="5115563688576182185">(64 bit)</translation>
<translation id="5141240743006678641">Senkronize edilen ÅŸifreleri Google kimlik bilgilerinizle ÅŸifreleyin</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">E-posta gerekli</translation>
<translation id="5251803541071282808">Bulut</translation>
<translation id="5277279256032773186">Chrome'u işte mi kullanıyorsunuz? İşletmeler, çalışanları için Chrome ayarlarını yönetebilir. Daha fazla bilgi edinin</translation>
+<translation id="5297526204711817721">Bu siteyle bağlantınız gizli değil. VR modundan istediğiniz zaman çıkmak için başlığı çıkarıp Geri düğmesine basın.</translation>
<translation id="5299298092464848405">Politika ayrıştırma hatası</translation>
-<translation id="5300589172476337783">Göster</translation>
<translation id="5308689395849655368">Kilitlenme bildirme devre dışı.</translation>
<translation id="5317780077021120954">Kaydet</translation>
<translation id="5327248766486351172">Ad</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesindeki saldırganlar, yazılım yükleme veya kişisel bilgilerinizi (örneğin, şifreler, telefon numaraları veya kredi kartları) ortaya çıkarma gibi tehlikeli şeyler yapmak için sizi kandırabilir.</translation>
-<translation id="5359637492792381994">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası şu anda geçerli değil. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Sertifikası iptal edildiği için <ph name="SITE" /> sitesini şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan, bu sayfa muhtemelen daha sonra çalışacaktır.</translation>
<translation id="536296301121032821">Politika ayarları saklanamadı</translation>
<translation id="5386426401304769735">Bu sitenin sertifika zinciri, SHA-1 kullanılarak imzalanmış bir sertifika içeriyor.</translation>
<translation id="5402410679244714488">Son kullanım tarihi: <ph name="EXPIRATION_DATE_ABBR" />, en son bir yıldan uzun bir süre önce kullanıldı</translation>
+<translation id="540969355065856584">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası şu anda geçerli değil. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
<translation id="5421136146218899937">Tarama verilerini temizle...</translation>
<translation id="5430298929874300616">Yer işaretini kaldır</translation>
<translation id="5431657950005405462">Dosyanız bulunamadı</translation>
-<translation id="5435775191620395718">Bu cihazdan geçmiş bilgileri gösteriliyor. <ph name="BEGIN_LINK" />Daha fazla bilgi edinin<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">"<ph name="ERROR_PATH" />" üzerinde şema doğrulama hatası: <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Bu <ph name="HOST_NAME" /> sayfası bulunamıyor</translation>
<translation id="5455374756549232013">Politika zaman damgası yanlış</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> / <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Geçersiz</translation>
<translation id="5470861586879999274">Düzenlemeyi &amp;yeniden yap</translation>
<translation id="54817484435770891">Geçerli adres ekleyin</translation>
<translation id="5492298309214877701">Şirket, kuruluş veya okul intranet'indeki bu site harici bir web sitesiyle aynı URL'ye sahip.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Bu adresten alım yapılamıyor. Farklı bir adres seçin.</translation>
<translation id="5572851009514199876">Chrome'un bu siteye erişmenize izin verilip verilmediğini kontrol edebilmesi için lütfen Chrome'u başlatıp oturum açın.</translation>
<translation id="5580958916614886209">Son kullanma tarihinin ayını kontrol edip tekrar deneyin</translation>
+<translation id="5586446728396275693">KaydedilmiÅŸ adres yok</translation>
+<translation id="5595485650161345191">Adresi düzenle</translation>
<translation id="560412284261940334">Yönetim desteklenmiyor</translation>
<translation id="5610142619324316209">Bağlantınızı kontrol etme</translation>
<translation id="5610807607761827392">Kartları ve adresleri <ph name="BEGIN_LINK" />Ayarlar<ph name="END_LINK" />'da yönetebilirsiniz.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Bu siteden ayrılmak istiyor musunuz?</translation>
<translation id="5629630648637658800">Politika ayarları yüklenemedi</translation>
<translation id="5631439013527180824">Geçersiz cihaz yönetimi jetonu</translation>
+<translation id="5633066919399395251">Şu anda <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesindeki saldırganlar, bilgilerinizi (örneğin, fotoğraflar, şifreler, mesajlar ve kredi kartları) çalabilecek veya silebilecek tehlikeli programları bilgisayarınıza yüklemeye çalışabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Konum</translation>
+<translation id="5659593005791499971">E-posta</translation>
<translation id="5669703222995421982">Kişiselleştirilmiş içerikler alma</translation>
<translation id="5675650730144413517">Bu sayfa çalışmıyor</translation>
-<translation id="5677928146339483299">Engellenenler</translation>
-<translation id="5694783966845939798"><ph name="DOMAIN" /> alan adına erişme girişiminde bulundunuz, ancak sunucu zayıf bir imza algoritması kullanılarak imzalanmış bir sertifika sağladı. Bu durum, sunucunun sağladığı güvenlik bilgilerinin sahte olabileceği anlamına gelir ve sunucu sizin beklediğiniz sunucu olmayabilir (bir saldırgan ile irtibat kuruyor olabilirsiniz). <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Bu web sitesinin kimliği doğrulanmadı.</translation>
+<translation id="5713016350996637505">Yanıltıcı içerik engellendi</translation>
<translation id="5720705177508910913">Geçerli kullanıcı</translation>
<translation id="5732392974455271431">Ebeveynleriniz engellemeyi kaldırabilir</translation>
<translation id="5763042198335101085">Geçerli bir e-posta adresi girin</translation>
<translation id="5765072501007116331">Teslimat yöntemlerini ve gereksinimleri görmek için bir adres seçin</translation>
+<translation id="5778550464785688721">MIDI cihazları tam denetimi</translation>
<translation id="5784606427469807560">Kartınız onaylanırken bir sorun oluştu. İnternet bağlantınızı kontrol edip tekrar deneyin.</translation>
<translation id="5785756445106461925">Ayrıca, bu sayfa güvenli olmayan başka kaynaklar içeriyor. Bu kaynaklar, aktarım sırasında başkaları tarafından görülebilir ve bir saldırgan tarafından sayfanın görünüşünü değiştirmek üzere kullanılabilir.</translation>
<translation id="5786044859038896871">Kart bilgilerinizin doldurulmasını istiyor musunuz?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">Eklemeyi &amp;Yeniden Yap</translation>
<translation id="5814352347845180253"><ph name="SITE" /> ve diğer sitelerden alınan premium içeriğe erişiminizi kaybedebilirsiniz.</translation>
<translation id="5838278095973806738">Bu sitede hiçbir hassas bilginizi (örneğin şifrelerinizi veya kredi kartı bilgilerinizi) girmemelisiniz. Aksi takdirde bu bilgiler saldırganlar tarafından çalınabilir.</translation>
-<translation id="5843436854350372569"><ph name="DOMAIN" /> alan adına ulaşmayı denediniz, ancak sunucu zayıf anahtar içeren bir sertifika sundu. Bir saldırgan özel anahtarı ele geçirmiş olabilir ve sunucu beklediğiniz sunucu olmayabilir (bir saldırganla irtibat kuruyor olabilirsiniz). <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Bu siteye ulaşılamıyor</translation>
<translation id="5869522115854928033">Kayıtlı şifreler</translation>
<translation id="5872918882028971132">Ebeveyn Önerileri</translation>
<translation id="5901630391730855834">Sarı</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (senkronize edildi)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{1 çerez kullanımda}other{# çerez kullanımda}}</translation>
<translation id="5926846154125914413">Bazı sitelerden alınan premium içeriğe erişiminizi kaybedebilirsiniz.</translation>
<translation id="5959728338436674663">Tehlikeli uygulamaların ve sitelerin tespit edilmesine yardımcı olmak için Google'a bazı <ph name="BEGIN_WHITEPAPER_LINK" />sistem bilgilerini ve sayfa içeriklerini<ph name="END_WHITEPAPER_LINK" /> otomatik olarak gönder.<ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Hafta</translation>
<translation id="5967867314010545767">Geçmişten kaldır.</translation>
<translation id="5975083100439434680">Uzaklaştır</translation>
<translation id="598637245381783098">Ödeme uygulaması açılamıyor</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{1. sayfa}other{#. sayfa}}</translation>
<translation id="6017514345406065928">YeÅŸil</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> öğesini kullanan saldırganlar başka bir şeyi taklit eden aldatıcı uygulamalar yükleyebilir veya sizi izlemek için kullanılabilecek veriler toplayabilirler. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (senkronize edildi)</translation>
<translation id="6027201098523975773">Bir ad girin</translation>
<translation id="6040143037577758943">Kapat</translation>
<translation id="6042308850641462728">Daha fazla</translation>
+<translation id="6047233362582046994">Güvenliğinize ilişkin riskleri anladıysanız zararlı programlar kaldırılmadan önce <ph name="BEGIN_LINK" />bu siteyi ziyaret edebilirsiniz<ph name="END_LINK" />.</translation>
+<translation id="6051221802930200923"><ph name="SITE" /> sitesi sertifika sabitleme yöntemi kullandığından siteyi şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan bu sayfa muhtemelen daha sonra çalışacaktır.</translation>
<translation id="6060685159320643512">Dikkatli olun, bu deneyler canınızı yakabilir</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{yok}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Yönetici tarafından sağlanmış bir sertifika kullanan içeriğe eriştiniz. <ph name="DOMAIN" /> alan adına sağladığınız verileri yöneticiniz görebilir ve bunlara müdahale edebilir.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Yok}=1{1 ÅŸifre (senkronize edildi)}other{# ÅŸifre (senkronize edildi)}}</translation>
<translation id="6146055958333702838">Kabloları kontrol edin ve kullandığınız yönlendiricileri, modemleri
veya diğer ağ cihazlarını yeniden başlatın.</translation>
<translation id="614940544461990577">Aşağıdakileri deneyin:</translation>
<translation id="6151417162996330722">Sunucu sertifikasının geçerlilik dönemi çok uzun.</translation>
<translation id="6157877588268064908">Gönderim yöntemlerini ve gereksinimlerini görmek için bir adres seçin</translation>
+<translation id="6158003235852588289">Google Güvenli Tarama yakın bir zamanda <ph name="SITE" /> sitesinde kimlik avı yapıldığını tespit etti. Kimlik avı siteleri sizi aldatmak için başka web siteleri gibi görünür.</translation>
<translation id="6165508094623778733">Daha fazla bilgi edinin</translation>
+<translation id="6169916984152623906">Artık gizli olarak göz atabilirsiniz ve bu cihazı kullanan diğer kişiler etkinliğinizi görmez. Yine de indirdikleriniz ve yer işaretleri kaydedilir.</translation>
<translation id="6177128806592000436">Bu siteye bağlantınız güvenli değil</translation>
<translation id="6184817833369986695">(kohort: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">İnternet bağlantınızı kontrol edin</translation>
<translation id="6218753634732582820">Adres Chromium'dan kaldırılsın mı?</translation>
+<translation id="6221345481584921695">Google Güvenli Tarama yakın bir zamanda <ph name="SITE" /> sitesinde <ph name="BEGIN_LINK" />kötü amaçlı yazılım tespit etti<ph name="END_LINK" />. Normalde güvenli olan web sitelerine bazen kötü amaçlı yazılımlar bulaşır. Kötü amaçlı içerik, kötü amaçlı yazılım dağıtımcısı olduğu bilinen <ph name="SUBRESOURCE_HOST" /> kaynağından gelmektedir.</translation>
<translation id="6251924700383757765">Gizlilik politikası</translation>
<translation id="6254436959401408446">Bu sayfayı açmaya yetecek kadar bellek yok</translation>
<translation id="625755898061068298">Bu site için güvenlik uyarılarını devre dışı bırakmayı seçtiniz.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Yer işaretini düzenle</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> numaralı kartın son kullanma tarihini ve CVC kodunu girin</translation>
<translation id="6414888972213066896">Ebeveyninize bu siteyi ziyaret etmenizin uygun olup olmadığını sordunuz</translation>
-<translation id="6416403317709441254"><ph name="SITE" /> web sitesi Chromium'un işleyemediği karışık kimlik bilgileri gönderdiğinden bu web sitesini şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici türdendir, dolayısıyla bu sayfa muhtemelen daha sonra çalışacaktır. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Sertifikanın iptal edilip edilmediği kontrol edilemiyor.</translation>
<translation id="6433490469411711332">İletişim bilgilerini düzenle</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> bağlanmayı reddetti.</translation>
<translation id="6446608382365791566">Daha fazla bilgi ekleyin</translation>
+<translation id="6447842834002726250">Çerezler</translation>
<translation id="6451458296329894277">Yeniden Form Gönderme İşlemini Onayla</translation>
<translation id="6456339708790392414">Ödemeniz</translation>
<translation id="6458467102616083041">Varsayılan arama politika tarafından devre dışı bırakıldığı için yoksayıldı.</translation>
-<translation id="6462969404041126431">Bu sunucu, <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası iptal edilmiş olabilir. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Cihaz politikaları</translation>
<translation id="6477321094435799029">Chrome, bu sayfada olağan dışı kod tespit etti ve kişisel bilgilerinizi (örneğin, şifreler, telefon numaraları ve kredi kartları) korumak için sayfayı engelledi.</translation>
<translation id="6489534406876378309">Kilitlenmeleri yüklemeye başla</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Son kullanım tarihi: <ph name="EXPIRATION_DATE_ABBR" />, son kullanıldığı tarih: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">Yöneticiniz henüz onaylamadı</translation>
<translation id="6569060085658103619">Bir uzantı sayfası görüntülüyorsunuz</translation>
-<translation id="6593753688552673085"><ph name="UPPER_ESTIMATE" />'tan az</translation>
+<translation id="657639383826808334">Bu içerik, cihazınıza bilgilerinizi çalabilecek veya silebilecek tehlikeli yazılımlar yüklemeye çalışabilir. <ph name="BEGIN_LINK" />Yine de göster<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Şifreleme seçenekleri</translation>
<translation id="662080504995468778">Kal</translation>
<translation id="6626291197371920147">Geçerli kart numarası ekle</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Arama</translation>
+<translation id="6630809736994426279">Şu anda <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesindeki saldırganlar bilgilerinizi (örneğin, fotoğraflar, şifreler, mesajlar ve kredi kartları) çalabilecek veya silebilecek tehlikeli programları Mac'inize yüklemeye çalışabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Bu politika uygun bulunmadı.</translation>
-<translation id="6652240803263749613">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Bilgisayarınızın işletim sistemi, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Form önerisi Chromium'dan kaldırılsın mı?</translation>
<translation id="6685834062052613830">Çıkış yapın ve kurulumu tamamlayın</translation>
<translation id="6710213216561001401">Önceki</translation>
<translation id="6710594484020273272">&lt;Arama terimini yazın&gt;</translation>
<translation id="6711464428925977395">Proxy sunucusunda bir sorun var veya adres yanlış.</translation>
<translation id="6727102863431372879">Ayarla</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{yok}=1{1 öğe}other{# öğe}}</translation>
<translation id="674375294223700098">Bilinmeyen sunucu sertifikası hatası.</translation>
<translation id="6753269504797312559">Politika deÄŸeri</translation>
<translation id="6757797048963528358">Cihazınız uyku moduna geçti.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Özelleştirme Kimliği</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Bölge verileri yüklenemedi</translation>
+<translation id="6825578344716086703"><ph name="DOMAIN" /> alanına erişme girişiminde bulundunuz ancak sunucu SHA-1 gibi zayıf bir imza algoritması kullanılarak imzalanmış bir sertifika sağladı. Bu, sunucunun sağladığı güvenlik bilgilerinin sahte olabileceği anlamına gelir ve sunucu sizin beklediğiniz sunucu olmayabilir (bir saldırgan ile irtibat kuruyor olabilirsiniz).</translation>
+<translation id="6830728435402077660">Güvenli değil</translation>
<translation id="6831043979455480757">Çevir</translation>
<translation id="6839929833149231406">Bölge</translation>
<translation id="6874604403660855544">Eklemeyi &amp;yeniden yap</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Kartınız onaylandı</translation>
<translation id="6897140037006041989">Kullanıcı Aracısı</translation>
<translation id="6915804003454593391">Kullanıcı:</translation>
+<translation id="6945221475159498467">Seç</translation>
<translation id="6948701128805548767">Alım yöntemlerini ve gereksinimlerini görmek için bir adres seçin</translation>
<translation id="6957887021205513506">Sunucunun sertifikası sahte görünüyor.</translation>
<translation id="6965382102122355670">Tamam</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Hem sabit proxy sunucular hem de bir .pac komut dosyası URL'si belirtildi.</translation>
<translation id="6989763994942163495">Gelişmiş ayarları göster...</translation>
<translation id="7000990526846637657">Geçmiş girişi bulunamadı</translation>
-<translation id="7009986207543992532"><ph name="DOMAIN" /> alan adına erişmeyi denediniz ancak sunucu, geçerlilik dönemi güvenilir olmayacak kadar uzun olan bir sertifika sundu. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985"><ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> adresinde Google Hesabınıza ilişkin başka biçimlerde tarama geçmişi olabilir.</translation>
<translation id="7029809446516969842">Åžifreler</translation>
+<translation id="7050187094878475250"><ph name="DOMAIN" /> alan adına erişmeyi denediniz, ancak sunucu, geçerlilik dönemi güvenilir olmayacak kadar uzun olan bir sertifika sundu.</translation>
+<translation id="7053983685419859001">Engelle</translation>
<translation id="7064851114919012435">Ä°letiÅŸim bilgileri</translation>
<translation id="7079718277001814089">Bu site kötü amaçlı yazılım içeriyor</translation>
<translation id="7087282848513945231">İlçe</translation>
-<translation id="7088615885725309056">Daha eski</translation>
<translation id="7090678807593890770">Google'da <ph name="LINK" /> araması yapın</translation>
+<translation id="7108819624672055576">Bir uzantı tarafından izin verildi</translation>
<translation id="7119414471315195487">Diğer sekmeleri veya programları kapatın</translation>
<translation id="7129409597930077180">Bu adrese gönderim yapılamıyor. Farklı bir adres seçin.</translation>
<translation id="7138472120740807366">Teslimat yöntemi</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Ä°ÅŸleme koyuluyor</translation>
<translation id="724691107663265825">Gideceğiniz site kötü amaçlı yazılım içeriyor</translation>
<translation id="724975217298816891">Kart ayrıntılarınızı güncellemek için <ph name="CREDIT_CARD" /> numaralı karta ilişkin son kullanma tarihini ve CVC kodunu girin. Onayladığınızda kart ayrıntılarınız bu siteyle paylaşılacaktır.</translation>
-<translation id="725866823122871198">Bilgisayarınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> alan adına gizli bir bağlantı kurulamıyor.</translation>
+<translation id="7260504762447901703">EriÅŸimi iptal et</translation>
<translation id="7275334191706090484">Yönetilen Yer İşaretleri</translation>
<translation id="7298195798382681320">Önerilenler</translation>
<translation id="7309308571273880165">Kilitlenme raporu yakalandı (<ph name="CRASH_TIME" />) (yükleme kullanıcı tarafından istendi, ancak henüz yüklenmedi)</translation>
<translation id="7334320624316649418">Sıralama değişikliğini &amp;yeniden yap</translation>
<translation id="733923710415886693">Sunucunun sertifikası, Sertifika Şeffaflığı aracılığıyla açıklanmadı.</translation>
-<translation id="7351800657706554155">Sertifikası iptal edildiği için <ph name="SITE" /> web sitesini şu anda ziyaret edemezsiniz. Ağ hataları ve saldırılar genellikle geçici olduğundan, bu sayfa muhtemelen daha sonra çalışacaktır. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Komut Satırı</translation>
<translation id="7372973238305370288">arama sonucu</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Hayır</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Kartı Onayla</translation>
-<translation id="7394102162464064926">Bu sayfaları geçmişinizden silmek istediğinizden emin misiniz?
-
-Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlı olabilir.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">Profil Yolu</translation>
<translation id="7424977062513257142">Bu web sayfasındaki yerleşik bir sayfanın mesajı:</translation>
@@ -688,6 +754,7 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="7444046173054089907">Bu site engellenmiÅŸ</translation>
<translation id="7445762425076701745">Bağlı olduğunuz sunucunun kimliği tam olarak doğrulanamıyor. Sunucuya yalnızca ağınızın içinde geçerli olan ve dış sertifika yetkilisi tarafından hiçbir şekilde sahipliği doğrulanamayacak bir ad kullanarak bağlandınız. Bazı sertifika yetkilileri bu adlar için sertifikalar yayınlasa da, bir saldırgana değil, hedeflenen web sitesine bağlandığınızdan emin olmanın herhangi bir yolu yoktur.</translation>
<translation id="7451311239929941790">Bu sorun hakkında <ph name="BEGIN_LINK" />daha fazla<ph name="END_LINK" /> bilgi edinme.</translation>
+<translation id="7455133967321480974">Genel varsayılanı kullan (Engelle)</translation>
<translation id="7460163899615895653">Diğer cihazlardan yeni tarihli sekmeleriniz burada görünür</translation>
<translation id="7469372306589899959">Kart onaylanıyor</translation>
<translation id="7481312909269577407">Ä°leri</translation>
@@ -695,36 +762,43 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="7508255263130623398">Döndürülen politika cihaz kimliği boş veya mevcut cihaz kimliğiyle eşleşmiyor</translation>
<translation id="7514365320538308">Ä°ndir</translation>
<translation id="7518003948725431193">Şu web adresi için web sayfası bulunamadı:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">DeÄŸer</translation>
<translation id="7537536606612762813">Zorunlu</translation>
+<translation id="7542403920425041731">Onayladığınızda kart ayrıntılarınız bu siteyle paylaşılacaktır.</translation>
<translation id="7542995811387359312">Bu form güvenli bağlantı kullanmadığından kredi kartı bilgilerini otomatik doldurma özelliği devre dışı bırakıldı.</translation>
<translation id="7543525346216957623">Ebeveyninize sorun</translation>
<translation id="7549584377607005141">Bu Web sayfasının düzgün şekilde görüntülenmesi için, önceden girdiğiniz veriler gerekiyor. Bu verileri tekrar gönderebilirsiniz, ancak bunu yaptığınızda bu sayfanın daha önce gerçekleştirdiği işlemler de tekrar edilir.</translation>
<translation id="7552846755917812628">Aşağıdaki ipuçlarını deneyin:</translation>
<translation id="7554791636758816595">Yeni Sekme</translation>
+<translation id="7567204685887185387">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Güvenlik sertifikası hileli bir şekilde yayınlanmış olabilir. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> tane daha}other{<ph name="CONTACT_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> tane daha}}</translation>
<translation id="7568593326407688803">Bu sayfanın dili<ph name="ORIGINAL_LANGUAGE" />Çevrilmesini istiyor musunuz?</translation>
<translation id="7569952961197462199">Kredi kartı Chrome'dan kaldırılsın mı?</translation>
<translation id="7569983096843329377">Siyah</translation>
<translation id="7578104083680115302">Google'a kaydettiğiniz kartları kullanarak farklı cihazlardan sitelerde ve uygulamalarda ödemelerinizi hızla yapabilirsiniz.</translation>
<translation id="7588950540487816470">Fiziksel Web</translation>
<translation id="7592362899630581445">Sunucunun sertifikası ad sınırlamasını ihlal ediyor.</translation>
+<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" />'tan az</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> şu anda bu isteği işleme alamıyor.</translation>
<translation id="7600965453749440009"><ph name="LANGUAGE" /> dilini asla çevirme</translation>
<translation id="7610193165460212391">Değer aralık dışında: <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Son kullanım tarihi: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Google Hesabı şifrenizin farklı bir sürümü kullanılarak şifrelenmiş verileriniz zaten var. Lütfen bu şifreyi aşağıya girin.</translation>
-<translation id="7634554953375732414">Bu siteye bağlantınız gizli değil.</translation>
<translation id="7637571805876720304">Kredi kartı Chromium'dan kaldırılsın mı?</translation>
<translation id="765676359832457558">Gelişmiş ayarları gizle...</translation>
<translation id="7658239707568436148">Ä°ptal</translation>
+<translation id="7662298039739062396">Ayar bir uzantının kontrolü altında</translation>
<translation id="7667346355482952095">Döndürülen politika jetonu boş veya mevcut jetonla eşleşmiyor</translation>
<translation id="7668654391829183341">Bilinmeyen cihaz</translation>
<translation id="7669271284792375604">Bu sitedeki saldırganlar web'e göz atma deneyiminize zarar veren programlar yüklemeniz için sizi kandırmayı (örneğin ana sayfanızı değiştirerek ya da ziyaret ettiğiniz sitelerde ek reklamlar görüntüleyerek) deneyebilir.</translation>
<translation id="7674629440242451245">Chrome'daki etkileyici, yeni özellikler ilginizi çekiyor mu? chrome.com/dev adresinden geliştirici kanalımızı deneyin.</translation>
<translation id="7682287625158474539">Sevkiyat</translation>
+<translation id="7701040980221191251">Yok</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" /><ph name="SITE" /> sitesine ilerle (güvenli değil)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Sertifika</translation>
+<translation id="7716147886133743102">Yöneticiniz tarafından engellendi</translation>
<translation id="7716424297397655342">Bu site önbellekten yüklenemiyor</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Yönetimden kaldırıldı</translation>
<translation id="7755287808199759310">Ebeveyniniz engellemeyi sizin için kaldırabilir</translation>
<translation id="7758069387465995638">Bağlantıyı güvenlik duvarı veya virüsten korunma yazılımı engellemiş olabilir.</translation>
@@ -751,15 +825,15 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="7951415247503192394">(32 bit)</translation>
<translation id="7956713633345437162">Mobil yer iÅŸaretleri</translation>
<translation id="7961015016161918242">Hiçbir Zaman</translation>
-<translation id="7962083544045318153">Kilitlenme KimliÄŸi: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893"><ph name="ORIGINAL_LANGUAGE" /> dilini her zaman <ph name="TARGET_LANGUAGE" /> diline çevir</translation>
<translation id="7995512525968007366">Belirtilmedi</translation>
<translation id="800218591365569300">Bellekte yer açmak için diğer sekmeleri veya programları kapatmayı deneyin.</translation>
<translation id="8012647001091218357">Şu anda ebeveynlerinize erişemedik. Lütfen tekrar deneyin.</translation>
<translation id="8025119109950072390">Bu sitedeki saldırganlar sizi kandırarak yazılım yükleme veya kişisel bilgilerinizi (örneğin şifreler, telefon numaraları veya kredi kartları) ifşa etme gibi tehlikeli şeyler yaptırabilir.</translation>
-<translation id="803030522067524905">Google Güvenli Tarama yakın bir zamanda <ph name="SITE" /> web sitesinde kimlik avı yapıldığını tespit etti. Kimlik avı siteleri, sizi aldatmak için başka web siteleri gibi görünür. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Bu sayfa <ph name="SOURCE_LANGUAGE" /> dilinde. <ph name="TARGET_LANGUAGE" /> diline çevrilsin mi?</translation>
+<translation id="8037357227543935929">Sor (varsayılan)</translation>
<translation id="8041089156583427627">Görüş bildirin</translation>
+<translation id="8041940743680923270">Genel varsayılanı kullan (Sor)</translation>
<translation id="8088680233425245692">Makale görüntülenemedi.</translation>
<translation id="8089520772729574115">1 MB'tan az</translation>
<translation id="8091372947890762290">EtkinleÅŸtirme sunucuda bekliyor</translation>
@@ -768,13 +842,14 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="8134994873729925007"><ph name="HOST_NAME" /> ana makinesinin sunucu <ph name="BEGIN_ABBR" />DNS adresi<ph name="END_ABBR" /> bulunamadı.</translation>
<translation id="8149426793427495338">Bilgisayarınız uyku moduna geçti.</translation>
<translation id="8150722005171944719"><ph name="URL" /> konumundaki dosya okunamıyor. Kaldırılmış ya da taşınmış olabilir veya dosya izinleri erişimi önlüyordur.</translation>
+<translation id="8184538546369750125">Genel varsayılanı kullan (İzin ver)</translation>
+<translation id="8191494405820426728">Yerel Kilitlenme KimliÄŸi: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">Taşımayı &amp;Geri Al</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" kodlu uzantı için geçersiz güncelleme URL'si.</translation>
<translation id="8202097416529803614">Sipariş özeti</translation>
<translation id="8218327578424803826">Atanan Konum:</translation>
<translation id="8225771182978767009">Bu bilgisayarı kuran kişi bu siteyi engellemeyi seçmiş.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Şu anda <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesinde bulunan saldırganlar, bilgilerinizi (örneğin fotoğraflar, şifreler, mesajlar ve kredi kartları) çalacak veya silecek tehlikeli programları bilgisayarınıza yüklemeyi deneyebilirler.</translation>
<translation id="8241707690549784388">Aradığınız sayfa, girdiğiniz bilgileri kullandı. O sayfaya dönmeniz, gerçekleştirdiğiniz işlemlerin tekrarlanmasına yol açabilir. Devam etmek istiyor musunuz?</translation>
<translation id="8249320324621329438">Son getirilen:</translation>
<translation id="8253091569723639551">Fatura adresi gerekli</translation>
@@ -782,6 +857,7 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="8289355894181816810">Bunun ne anlama geldiğini bilmiyorsanız ağ yöneticinizle bağlantı kurun.</translation>
<translation id="8293206222192510085">Yer Ä°ÅŸareti Ekle</translation>
<translation id="8294431847097064396">Kaynak</translation>
+<translation id="8306404619377842860">Cihazınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ile gizli bağlantı kurulamıyor. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Ağ bağlantısıyla ilgili bir sorun nedeniyle çeviri başarısız oldu.</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ana makinesine eriÅŸim reddedildi</translation>
<translation id="834457929814110454">Güvenliğinize ilişkin riskleri anladıysanız <ph name="BEGIN_LINK" />bu siteyi<ph name="END_LINK" /> zararlı programlar kaldırılmadan önce ziyaret edebilirsiniz.</translation>
@@ -802,11 +878,9 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="8483780878231876732">Google Hesabınızda kayıtlı kartları kullanmak için Chrome'da oturum açın</translation>
<translation id="8488350697529856933">Uygulandığı yer</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> ana makinesinin yanıt vermesi çok uzun sürdü.</translation>
-<translation id="852346902619691059">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı. Cihazınızın işletim sistemi, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, yanlış yapılandırmadan veya bağlantınıza müdahale eden bir saldırgandan kaynaklanıyor olabilir. <ph name="BEGIN_LEARN_MORE_LINK" />Daha fazla bilgi edinin<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Son Kullanım Yılı</translation>
<translation id="8543181531796978784"><ph name="BEGIN_ERROR_LINK" />Bir tespit sorununu bildirebilir<ph name="END_ERROR_LINK" /> veya güvenliğiniz açısından riskleri anlıyorsanız <ph name="BEGIN_LINK" />güvenli olmayan bu siteyi ziyaret edebilirsiniz<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Sayfanın dili belirlenemediğinden çeviri başarısız oldu.</translation>
-<translation id="8559762987265718583">Cihazınızın tarih ve saati (<ph name="DATE_AND_TIME" />) yanlış olduğundan <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> alan adına gizli bir bağlantı kurulamıyor.</translation>
<translation id="8571890674111243710">Sayfa <ph name="LANGUAGE" /> diline çevriliyor...</translation>
<translation id="858637041960032120">Telefon no ekle
</translation>
@@ -821,6 +895,7 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="8738058698779197622">Güvenli bir bağlantı kurmak için saatinizin doğru ayarlanmış olması gerekir. Bunun sebebi, web sitelerinin kendilerini tanımlamak için kullandıkları sertifikaların sadece belli süreler için geçerli olmasıdır. Cihazınızın saati yanlış olduğundan, Chromium bu sertifikaları doğrulayamaz.</translation>
<translation id="8740359287975076522"><ph name="HOST_NAME" /> ana makinesinin &lt;abbr id="dnsDefinition"&gt;DNS adresi&lt;/abbr&gt; bulunamadı. Sorun teşhis ediliyor.</translation>
<translation id="8759274551635299824">Bu kartın kullanım süresi doldu</translation>
+<translation id="8761567432415473239">Google Güvenli Tarama, yakın zamanda <ph name="SITE" /> sitesinde <ph name="BEGIN_LINK" />zararlı programlar buldu<ph name="END_LINK" />.</translation>
<translation id="8790007591277257123">Silmeyi &amp;yeniden yap</translation>
<translation id="8800988563907321413">Yakın çevrenizle ilgili öneriler burada görünür</translation>
<translation id="8820817407110198400">Favoriler</translation>
@@ -833,29 +908,30 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="8870413625673593573">Son Kapatılan</translation>
<translation id="8874824191258364635">Geçerli bir kart numarası girin</translation>
<translation id="8876793034577346603">Ağ yapılandırması ayrıştırılamadı.</translation>
-<translation id="8877192140621905067">Onayladığınızda kart ayrıntılarınız bu siteyle paylaşılacaktır</translation>
<translation id="8889402386540077796">Ton</translation>
<translation id="8891727572606052622">Geçersiz proxy modu.</translation>
<translation id="889901481107108152">Maalesef bu deney platformunuzda kullanılamıyor.</translation>
<translation id="8903921497873541725">Yakınlaştır</translation>
<translation id="8931333241327730545">Bu kartı Google Hesabınıza kaydetmek istiyor musunuz?</translation>
<translation id="8932102934695377596">Saatiniz geri</translation>
-<translation id="8954894007019320973">(Dev.)</translation>
<translation id="8971063699422889582">Sunucu sertifikasının süresi doldu.</translation>
<translation id="8986494364107987395">Kullanım istatistiklerini ve çökme raporlarını otomatik olarak Google'a gönder</translation>
-<translation id="8987927404178983737">Ay</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Girmekte olduğunuz site zararlı programlar içermektedir</translation>
+<translation id="8997023839087525404">Sunucu, Sertifika Şeffaflığı politikası kullanılarak herkese açık bir şekilde açıklanmayan bir sertifika sundu. Güvenilir olduklarından emin olmak ve saldırganlara karşı koruma sağlamak için bazı sertifikalarda bu zorunludur.</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> proxy'si için kullanıcı adı ve şifre gerekiyor.</translation>
+<translation id="9005998258318286617">PDF dokümanı yüklenemedi.</translation>
<translation id="901974403500617787">Tüm sistem için geçerli olan işaretler sadece sahibi <ph name="OWNER_EMAIL" /> tarafından ayarlanabilir.</translation>
+<translation id="9020200922353704812">Kartın fatura adresi gerekli</translation>
<translation id="9020542370529661692">Bu sayfa <ph name="TARGET_LANGUAGE" /> diline çevrildi</translation>
<translation id="9035022520814077154">Güvenlik hatası</translation>
<translation id="9038649477754266430">Sayfaları daha hızlı yüklemek için bir tahmin hizmeti kullan</translation>
<translation id="9039213469156557790">Ayrıca, bu sayfa güvenli olmayan başka kaynaklar içeriyor. Bu kaynaklar, aktarım sırasında başkaları tarafından görülebilir ve bir saldırgan tarafından sayfanın davranışını değiştirmek üzere kullanılabilir.</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> sitesindeki saldırganlar web'e göz atma deneyiminize zarar veren programları yüklemeniz için sizi kandırmayı (örneğin ana sayfanızı değiştirerek ya da ziyaret ettiğiniz sitelerde ek reklamlar görüntüleyerek) deneyebilirler.</translation>
+<translation id="9049981332609050619"><ph name="DOMAIN" /> alan adına erişmeye çalıştınız, ancak sunucu geçersiz bir sertifika sağladı.</translation>
<translation id="9050666287014529139">Parola</translation>
<translation id="9065203028668620118">Düzenle</translation>
<translation id="9068849894565669697">Renk seçin</translation>
+<translation id="9069693763241529744">Bir uzantı tarafından engellendi</translation>
<translation id="9076283476770535406">Yetişkin içeriği bulunabilir</translation>
<translation id="9078964945751709336">Daha fazla bilgi gerekli</translation>
<translation id="9103872766612412690"><ph name="SITE" /> normalde bilgilerinizi korumak için şifreleme kullanmaktadır. Chromium bu sefer <ph name="SITE" /> sitesine bağlanmayı denediğinde, web sitesi sıra dışı ve yanlış kimlik bilgileri döndürdü. Bir saldırgan <ph name="SITE" /> gibi davranmaya çalışıyor olabilir ya da bir Kablosuz oturum açma ekranı bağlantıyı kesmiştir. Chromium herhangi bir veri alışverişinden önce bağlantıyı durdurduğu için bilgileriniz hâlâ güvendedir.</translation>
@@ -864,16 +940,21 @@ Hatırlatma! Bir dahaki sefere Gizli mod <ph name="SHORTCUT_KEY" /> kullanışlÄ
<translation id="9148507642005240123">Düzenlemeyi &amp;geri al</translation>
<translation id="9154194610265714752">Güncellendi</translation>
<translation id="9157595877708044936">Ayarlanıyor...</translation>
+<translation id="9169664750068251925">Bu sitede her zaman engelle</translation>
<translation id="9170848237812810038">&amp;Geri al</translation>
<translation id="917450738466192189">Sunucunun sertifikası geçersiz.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> tane daha}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> tane daha}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> desteklenmeyen bir protokol kullanıyor.</translation>
<translation id="9205078245616868884">Verileriniz senkronizasyon parolanızla şifrelendi. Senkronizasyonu başlatmak için senkronizasyon parolanızı girin.</translation>
<translation id="9207861905230894330">Makale eklenemedi.</translation>
+<translation id="9219103736887031265">Resimler</translation>
<translation id="933612690413056017">İnternet bağlantısı yok</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">FORMU TEMÄ°ZLE</translation>
<translation id="939736085109172342">Yeni klasör</translation>
<translation id="941721044073577244">Bu siteyi ziyaret etme izniniz yok</translation>
<translation id="969892804517981540">Resmi Derleme</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Yok}=1{1 öğe}other{# öğe}}</translation>
<translation id="988159990683914416">GeliÅŸtirici Derlemesi</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_uk.xtb b/chromium/components/strings/components_strings_uk.xtb
index 8f2b5a497e4..0ecb8fc0b57 100644
--- a/chromium/components/strings/components_strings_uk.xtb
+++ b/chromium/components/strings/components_strings_uk.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Обернути за годинниковою Ñтрілкою</translation>
<translation id="1038842779957582377">Ðевідоме ім’Ñ</translation>
<translation id="1050038467049342496">Закрийте інші додатки</translation>
-<translation id="1053591932240354961">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки веб-Ñайт надіÑлав зашифровані облікові дані, Ñкі Google Chrome не може обробити. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Відмінити додаваннÑ</translation>
<translation id="10614374240317010">Ðіколи не зберігалоÑÑ</translation>
<translation id="106701514854093668">Закладки Ð´Ð»Ñ Ð½Ð°Ñтільного комп’ютера</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Кеш-пам’ÑÑ‚ÑŒ правила не пошкоджено</translation>
<translation id="113188000913989374">ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ–Ð· Ñайту <ph name="SITE" />:</translation>
<translation id="1132774398110320017">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Chrome…</translation>
+<translation id="1150979032973867961">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Операційна ÑиÑтема вашого комп’ютера не вважає його Ñертифікат безпеки надійним. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
+<translation id="1151972924205500581">Потрібен пароль</translation>
<translation id="1152921474424827756">Відкрийте <ph name="BEGIN_LINK" />кешовану копію<ph name="END_LINK" /> <ph name="URL" /></translation>
<translation id="1158211211994409885">ХоÑÑ‚ <ph name="HOST_NAME" /> неочікувано розірвав з’єднаннÑ.</translation>
<translation id="1161325031994447685">знову під’єднати приÑтрій до мережі Wi-Fi</translation>
+<translation id="1165039591588034296">Помилка</translation>
<translation id="1175364870820465910">&amp;Друк...</translation>
<translation id="1181037720776840403">Видалити</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Ðвтоматично надÑилати<ph name="END_WHITEPAPER_LINK" /> в Google інформацію про можливі Ð¿Ð¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Більше з цього Ñайту</translation>
<translation id="1206967143813997005">ÐедійÑний підпиÑ</translation>
<translation id="1209206284964581585">Приховати</translation>
+<translation id="121201262018556460">Ви пробували зв’ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, проте Ñервер надав Ñертифікат, Ñкий міÑтить Ñлабкий ключ. Можливо, зловмиÑник зламав Ñекретний ключ, а Ñервер не Ñ” тим, Ñкий вам потрібен (ви можете обмінюватиÑÑ Ð´Ð°Ð½Ð¸Ð¼Ð¸ зі зловмиÑником).</translation>
<translation id="1219129156119358924">Безпека ÑиÑтеми</translation>
<translation id="1227224963052638717">Ðевідоме правило</translation>
<translation id="1227633850867390598">Сховати значеннÑ</translation>
<translation id="1228893227497259893">Ðеправильний ідентифікатор організації</translation>
<translation id="1232569758102978740">Без імені</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (Ñинхронізовано)</translation>
<translation id="1263231323834454256">СпиÑок читаннÑ</translation>
<translation id="1264126396475825575">Звіт про аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ о <ph name="CRASH_TIME" /> (ще не завантажено або пропущено)</translation>
+<translation id="1281526147609854549">Видано <ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">Заблоковано небезпечний вміÑÑ‚</translation>
<translation id="1285320974508926690">Ðіколи не перекладати цей Ñайт</translation>
<translation id="129553762522093515">Ðещодавно закриті</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Спробуйте видалити файли cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Дані про вашу активніÑÑ‚ÑŒ <ph name="BEGIN_EMPHASIS" />уÑе ще можуть бачити<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />адмініÑтратори веб-Ñайтів, Ñкі ви відвідуєте
+ <ph name="LIST_ITEM" />роботодавець або керівник навчального закладу
+ <ph name="LIST_ITEM" />поÑтачальник поÑлуг Інтернету
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Домен реєÑтрації:</translation>
<translation id="1340482604681802745">ÐдреÑа отриманнÑ</translation>
<translation id="1344211575059133124">Схоже, вам потрібен дозвіл, щоб перейти на цей Ñайт</translation>
<translation id="1344588688991793829">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Chromium…</translation>
+<translation id="1348198688976932919">Сайт міÑтить небезпечні додатки</translation>
<translation id="1374468813861204354">пропозиції</translation>
<translation id="1375198122581997741">Про верÑÑ–ÑŽ</translation>
<translation id="1377321085342047638">Ðомер картки</translation>
<translation id="139305205187523129">ХоÑÑ‚ <ph name="HOST_NAME" /> не надіÑлав дані.</translation>
<translation id="1407135791313364759">Відкрити вÑе</translation>
<translation id="1413809658975081374">Помилка через Ð¿Ð¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð´ÐµÐ½Ñ†Ñ–Ð¹Ð½Ð¾ÑÑ‚Ñ–</translation>
+<translation id="14171126816530869">Ідентифікаційну інформацію <ph name="ORGANIZATION" /> із <ph name="LOCALITY" /> було перевірено <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">так</translation>
<translation id="1430915738399379752">Друк</translation>
-<translation id="1442912890475371290">Заблоковано Ñпробу <ph name="BEGIN_LINK" />перейти на Ñторінку в домені <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки веб-Ñайт викориÑтовує Ð·Ð°ÐºÑ€Ñ–Ð¿Ð»ÐµÐ½Ð½Ñ Ñертифікатів. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}one{<ph name="PAYMENT_METHOD_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}many{<ph name="PAYMENT_METHOD_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="1506687042165942984">Показати Ñтару збережену копію цієї Ñторінки.</translation>
<translation id="1517433312004943670">Введіть номер телефону</translation>
<translation id="1519264250979466059">Дата ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñ—</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Щоб кориÑтуватиÑÑ Ñ†Ñ–Ñ”ÑŽ функцією, потрібно ввімкнути JavaScript.</translation>
<translation id="1555130319947370107">Синій</translation>
<translation id="1559528461873125649">Такого файла або каталогу немає</translation>
-<translation id="1559572115229829303">&lt;p&gt;Ðе вдаєтьÑÑ Ð²Ñтановити конфіденційне Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ–Ð· Ñайтом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оÑкільки на вашому приÑтрої неправильно налаштовано дату й Ñ‡Ð°Ñ (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
-
- &lt;p&gt;Ðалаштуйте дату й Ñ‡Ð°Ñ Ñƒ розділі &lt;strong&gt;Загальні&lt;/strong&gt; додатка &lt;strong&gt;ÐалаштуваннÑ&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Під Ñ‡Ð°Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ цієї Ñторінки ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°.</translation>
<translation id="1592005682883173041">ДоÑтуп до локальних даних</translation>
+<translation id="1594030484168838125">Вибрати</translation>
<translation id="161042844686301425">Бірюзовий</translation>
+<translation id="1620510694547887537">Камера</translation>
<translation id="1629803312968146339">Зберегти цю картку в Chrome?</translation>
<translation id="1639239467298939599">ЗавантаженнÑ</translation>
<translation id="1640180200866533862">Правила кориÑтувача</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð¼ÐµÑ€ÐµÐ¶Ñ– недійÑна та не може імпортуватиÑÑ.</translation>
<translation id="1644574205037202324">ІÑторіÑ</translation>
<translation id="1645368109819982629">Протокол не підтримуєтьÑÑ</translation>
+<translation id="1655462015569774233">{1,plural, =1{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти учора. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку.}one{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # день тому. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку.}few{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # дні тому. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку.}many{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # днів тому. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку.}other{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # Ð´Ð½Ñ Ñ‚Ð¾Ð¼Ñƒ. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку.}}</translation>
<translation id="1656489000284462475">ОтриманнÑ</translation>
<translation id="1663943134801823270">Дані картки та ÑпиÑок Ð°Ð´Ñ€ÐµÑ Ð¼Ñ–ÑÑ‚ÑÑ‚ÑŒÑÑ Ð² Chrome. Ðими можна керувати в <ph name="BEGIN_LINK" />ÐалаштуваннÑÑ…<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898">Веб-Ñайт <ph name="SITE" /> зазвичай викориÑтовує ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð·Ð°Ñ…Ð¸Ñту вашої інформації. Під Ñ‡Ð°Ñ Ñ†Ñ–Ñ”Ñ— Ñпроби Chrome під’єднатиÑÑ Ð´Ð¾ Ñторінки <ph name="SITE" /> з неї отримано незвичні й неправильні облікові дані. Це може ÑтатиÑÑ, коли зловмиÑник намагаєтьÑÑ Ð²Ð¸Ð´Ð°Ð²Ð°Ñ‚Ð¸ Ñебе за веб-Ñайт <ph name="SITE" /> або Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾ екраном входу Wi-Fi. Ваша Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð·Ð°Ð»Ð¸ÑˆÐ°Ñ”Ñ‚ÑŒÑÑ Ð·Ð°Ñ…Ð¸Ñ‰ÐµÐ½Ð¾ÑŽ, оÑкільки Chrome припинив Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ того, Ñк почавÑÑ Ð¾Ð±Ð¼Ñ–Ð½ будь-Ñкими даними.</translation>
-<translation id="168328519870909584">ЗловмиÑники, Ñкі зараз перебувають на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, можуть намагатиÑÑ Ð²Ñтановити на ваш приÑтрій небезпечні додатки, що викрадають або видалÑÑŽÑ‚ÑŒ інформацію (Ñк-от фотографії, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð¸ дані кредитних карток).</translation>
<translation id="168841957122794586">Сертифікат Ñервера міÑтить Ñлабкий криптографічний ключ.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти завтра. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані.}one{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # день. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані.}few{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # дні. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані.}many{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # днів. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані.}other{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # днÑ. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваші дані.}}</translation>
<translation id="1710259589646384581">ОС</translation>
<translation id="1721312023322545264">Вам потрібен дозвіл адмініÑтратора <ph name="NAME" />, щоб перейти на цей Ñайт</translation>
<translation id="1721424275792716183">* Обов’Ñзкове поле</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Завантажити Ñторінку пізніше</translation>
<translation id="17513872634828108">Відкриті вкладки</translation>
<translation id="1753706481035618306">Ðомер Ñторінки</translation>
+<translation id="1763864636252898013">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Операційна ÑиÑтема вашого приÑтрою не вважає його Ñертифікат безпеки надійним. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Проведіть діагноÑтику мережі Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Оновіть парольну фразу Ð´Ð»Ñ Ñинхронізації.</translation>
<translation id="1787142507584202372">Тут відображатимутьÑÑ Ð²Ð°ÑˆÑ– відкриті вкладки</translation>
+<translation id="1789575671122666129">Спливаючі вікна</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Ð†Ð¼â€™Ñ Ñ‚Ð° прізвище влаÑника картки</translation>
-<translation id="1803678881841855883">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно <ph name="BEGIN_LINK" />виÑвила зловмиÑне програмне забезпеченнÑ<ph name="END_LINK" /> на Ñайті <ph name="SITE" />. Іноді зловмиÑне програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñ€Ð°Ð¶Ð°Ñ” зазвичай безпечні веб-Ñайти. Шкідливий вміÑÑ‚ походить із хоÑту <ph name="SUBRESOURCE_HOST" /> – відомого розповÑюджувача зловмиÑного програмного забезпеченнÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Додано <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">ÐедійÑний запит або параметри запиту</translation>
<translation id="1826516787628120939">Перевірка</translation>
<translation id="1834321415901700177">Цей Ñайт міÑтить шкідливі програми</translation>
+<translation id="1840414022444569775">Цей номер картки вже викориÑтовуєтьÑÑ</translation>
<translation id="1842969606798536927">Оплатити</translation>
<translation id="1871208020102129563">ПрокÑÑ–-Ñервер налаштовано на викориÑÑ‚Ð°Ð½Ð½Ñ Ñ„Ñ–ÐºÑованих прокÑÑ–-Ñерверів, а не URL-адреÑи Ñценарію .pac.</translation>
<translation id="1871284979644508959">Обов’Ñзкове поле</translation>
<translation id="187918866476621466">Відкрити Ñтартові Ñторінки</translation>
<translation id="1883255238294161206">Згорнути ÑпиÑок</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}one{<ph name="SHIPPING_ADDRESS_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
<translation id="1898423065542865115">ФільтруваннÑ</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Ðемає}=1{1 Ñайт}one{# Ñайт}few{# Ñайти}many{# Ñайтів}other{# Ñайту}}</translation>
<translation id="194030505837763158">Перейдіть за адреÑою <ph name="LINK" /></translation>
<translation id="1962204205936693436">Закладки <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Помилка Ñеріалізації</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">Правило ігноруєтьÑÑ, оÑкільки його замінено правилом <ph name="POLICY_NAME" />.</translation>
<translation id="2138201775715568214">Пошук веб-Ñторінок у ÑервіÑÑ– "Інтернет навколо наÑ"</translation>
<translation id="213826338245044447">Закладки Ð´Ð»Ñ Ð¼Ð¾Ð±Ñ–Ð»ÑŒÐ½Ð¸Ñ… приÑтроїв</translation>
-<translation id="2148716181193084225">Сьогодні</translation>
+<translation id="2147827593068025794">Фонова ÑинхронізаціÑ</translation>
<translation id="2154054054215849342">Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð½ÐµÐ´Ð¾Ñтупна Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ домену</translation>
<translation id="2154484045852737596">Редагувати картку</translation>
<translation id="2166049586286450108">Повний адмініÑтративний доÑтуп</translation>
<translation id="2166378884831602661">Цей Ñайт не може забезпечити захищене з’єднаннÑ</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адреÑа}one{# адреÑа}few{# адреÑи}many{# адреÑ}other{# адреÑи}}</translation>
+<translation id="2187317261103489799">Визначати (за умовчаннÑм)</translation>
<translation id="2202020181578195191">Введіть дійÑний рік Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії</translation>
<translation id="2212735316055980242">Правило не знайдено</translation>
<translation id="2213606439339815911">ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñів…</translation>
+<translation id="2218879909401188352">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть уÑтановити небезпечні додатки, Ñкі шкодÑÑ‚ÑŒ вашому приÑтрою, додають приховані платежі за мобільний зв’Ñзок або викрадають оÑобиÑту інформацію. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Відновіть Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð·Ð° допомогою <ph name="BEGIN_LINK" />додатка Ð´Ð»Ñ Ð´Ñ–Ð°Ð³Ð½Ð¾Ñтики<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">ÐадіÑлати</translation>
<translation id="225207911366869382">Дію цього Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð¿Ð¸Ð½ÐµÐ½Ð¾ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ правила</translation>
<translation id="2262243747453050782">Помилка HTTP</translation>
+<translation id="2270484714375784793">Ðомер телефону</translation>
<translation id="2282872951544483773">ÐедоÑтупні екÑпериментальні функції</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> елемент}one{<ph name="ITEM_COUNT" /> елемент}few{<ph name="ITEM_COUNT" /> елементи}many{<ph name="ITEM_COUNT" /> елементів}other{<ph name="ITEM_COUNT" /> елемента}}</translation>
<translation id="2292556288342944218">Ваш доÑтуп до Інтернету заблоковано</translation>
<translation id="230155334948463882">Ðова картка?</translation>
-<translation id="2305919008529760154">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Можливо, його Ñертифікат безпеки видали шахраї. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535">Ð”Ð»Ñ Ñайту <ph name="DOMAIN" /> потрібно ввеÑти Ñ–Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача та пароль.</translation>
-<translation id="2318774815570432836">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки веб-Ñайт викориÑтовує протокол HSTS. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">ÐалаштуваннÑм керує ваш адмініÑтратор</translation>
<translation id="2354001756790975382">Інші закладки</translation>
+<translation id="2354430244986887761">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно <ph name="BEGIN_LINK" />виÑвила шкідливі додатки<ph name="END_LINK" /> на Ñайті <ph name="SITE" />.</translation>
<translation id="2355395290879513365">ЗловмиÑники можуть бачити зображеннÑ, Ñкі ви переглÑдаєте на цьому Ñайті, Ñ– змінювати Ñ—Ñ… із метою ошукати ваÑ.</translation>
+<translation id="2356070529366658676">Запитати</translation>
+<translation id="2359629602545592467">Декілька</translation>
<translation id="2359808026110333948">Продовжити</translation>
<translation id="2365563543831475020">Звіт про аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ о <ph name="CRASH_TIME" /> не завантажено</translation>
<translation id="2367567093518048410">Рівень</translation>
-<translation id="2371153335857947666">{1,plural, =1{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти вчора. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}one{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # день тому. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}few{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # дні тому. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}many{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # днів тому. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}other{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат переÑтав діÑти # Ð´Ð½Ñ Ñ‚Ð¾Ð¼Ñƒ. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. Ðа годиннику вашого комп’ютера зараз <ph name="CURRENT_DATE" />. Якщо дата неправильна, налаштуйте ÑиÑтемний годинник Ñ– оновіть цю Ñторінку. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Ðемає варіантів інтерфейÑу кориÑтувача</translation>
<translation id="2384307209577226199">Стандартне корпоративне правило</translation>
<translation id="2386255080630008482">Сертифікат Ñервера відкликано.</translation>
<translation id="2392959068659972793">Показувати правила, Ð´Ð»Ñ Ñких не вÑтановлено значеннÑ</translation>
<translation id="239429038616798445">Цей ÑпоÑіб Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð½ÐµÐ´Ð¾Ñтупний. Виберіть інший ÑпоÑіб.</translation>
<translation id="2396249848217231973">&amp;Відмінити видаленнÑ</translation>
-<translation id="2460160116472764928">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно <ph name="BEGIN_LINK" />виÑвила зловмиÑне програмне забезпеченнÑ<ph name="END_LINK" /> на Ñайті <ph name="SITE" />. Іноді зловмиÑне програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñ€Ð°Ð¶Ð°Ñ” зазвичай безпечні веб-Ñайти. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Можливо, його Ñертифікат безпеки відкликано. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
<translation id="2463739503403862330">Заповнити</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />провеÑти діагноÑтику мережі<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">ÐедійÑна URL-адреÑа Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ.</translation>
+<translation id="2482878487686419369">СповіщеннÑ</translation>
<translation id="2491120439723279231">Сертифікат Ñервера міÑтить помилки.</translation>
<translation id="2495083838625180221">СинтакÑичний аналізатор файлів JSON</translation>
<translation id="2495093607237746763">Якщо вибрати цю опцію, Chromium зберігатиме копію даних вашої картки на цьому приÑтрої, щоб ви могли швидше заповнювати форми.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Ðазад</translation>
<translation id="2515629240566999685">перевірити Ñигнал у Ñвоїй міÑцевоÑÑ‚Ñ–</translation>
<translation id="2516305470678292029">Варіанти інтерфейÑу кориÑтувача</translation>
+<translation id="2539524384386349900">Визначити</translation>
<translation id="255002559098805027">ХоÑÑ‚ <ph name="HOST_NAME" /> надіÑлав недійÑну відповідь.</translation>
-<translation id="2552545117464357659">Ðовіша</translation>
<translation id="2556876185419854533">&amp;Відмінити редагуваннÑ</translation>
<translation id="2587730715158995865">Видавець: <ph name="ARTICLE_PUBLISHER" />. Читайте цю та ще <ph name="OTHER_ARTICLE_COUNT" /> Ñтатей.</translation>
<translation id="2587841377698384444">Ідентифікатор API каталогу:</translation>
<translation id="2597378329261239068">Цей документ захищено паролем. Введіть пароль.</translation>
<translation id="2609632851001447353">Різновиди</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Ðемає}=1{1 додаток ($1)}=2{2 додатки ($1, $2)}one{# додаток ($1, $2, $3)}few{# додатки ($1, $2, $3)}many{# додатків ($1, $2, $3)}other{# додатка ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Ваш годинник Ñпішить</translation>
<translation id="2639739919103226564">СтатуÑ:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">У доÑтупі до файлу відмовлено</translation>
<translation id="2653659639078652383">ÐадіÑлати</translation>
<translation id="2666117266261740852">Закрийте інші вкладки та додатки</translation>
+<translation id="2670429602441959756">Ð¦Ñ Ñторінка міÑтить функції, Ñкі не підтримуютьÑÑ Ð² режимі віртуальної реальноÑÑ‚Ñ–. Вихід…</translation>
<translation id="2674170444375937751">Ви дійÑно бажаєте видалити ці Ñторінки зі Ñвоєї Ñ–Ñторії?</translation>
<translation id="2677748264148917807">Вийти</translation>
-<translation id="269990154133806163">Сервер надав Ñертифікат без інформації про перевірку. Це обов’Ñзкові дані Ð´Ð»Ñ Ð´ÐµÑких Ñертифікатів. Вони підтверджують надійніÑÑ‚ÑŒ Ñертифіката й захищають від атак зловмиÑників. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">СпиÑок читаннÑ</translation>
<translation id="2704283930420550640">Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ відповідає формату.</translation>
<translation id="2704951214193499422">Chromium не вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸ дані вашої картки. Спробуйте пізніше.</translation>
<translation id="2705137772291741111">Ðе вдаєтьÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ збережену (кешовану) копію цього Ñайту.</translation>
<translation id="2709516037105925701">ÐвтозаповненнÑ</translation>
-<translation id="2712118517637785082">Ви намагалиÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, але Ñервер надав Ñертифікат, відкликаний його видавцем. Це означає, що обліковим даним безпеки, наданим Ñервером, не можна довірÑти. Ви можете передавати Ñвої дані зловмиÑнику. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Запитувати дозвіл</translation>
<translation id="2713444072780614174">Білий</translation>
<translation id="2720342946869265578">Поблизу</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">ВідÑутній Ð·Ð°Ð¿Ð¸Ñ Ð¿Ñ€Ð¸Ñтрою</translation>
<translation id="2784949926578158345">Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ Ñкинуто.</translation>
<translation id="2794233252405721443">Сайт заблоковано</translation>
+<translation id="2799020568854403057">Сайт міÑтить шкідливі додатки</translation>
+<translation id="2803306138276472711">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно <ph name="BEGIN_LINK" />виÑвила зловмиÑне програмне забезпеченнÑ<ph name="END_LINK" /> на Ñайті <ph name="SITE" />. Іноді зловмиÑне програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñ€Ð°Ð¶Ð°Ñ” зазвичай безпечні веб-Ñайти.</translation>
<translation id="2824775600643448204">ÐдреÑний Ñ– пошуковий Ñ€Ñдок</translation>
<translation id="2826760142808435982">Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð·Ð°ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¾ й автентифіковано з викориÑтаннÑм шифру <ph name="CIPHER" /> Ñ– викориÑтовує механізм обміну ключами <ph name="KX" />.</translation>
<translation id="2835170189407361413">ОчиÑтити форму</translation>
+<translation id="2856444702002559011">ЗловмиÑники можуть намагатиÑÑ Ð²Ð¸ÐºÑ€Ð°Ñти вашу інформацію із Ñайту <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (наприклад, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð¸ дані кредитних карток). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Ðе оновлювати</translation>
<translation id="2900469785430194048">ÐедоÑтатньо пам’ÑÑ‚Ñ– Google Chrome, щоб показати цю веб-Ñторінку.</translation>
<translation id="2909946352844186028">ВиÑвлено зміну в мережі.</translation>
<translation id="2916038427272391327">Закрийте інші програми</translation>
<translation id="2922350208395188000">Сертифікат Ñервера неможливо перевірити.</translation>
<translation id="2928905813689894207">Платіжна адреÑа</translation>
+<translation id="2941952326391522266">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Його Ñертифікат безпеки походить із домену <ph name="DOMAIN2" />. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
<translation id="2948083400971632585">УÑÑ– прокÑÑ–-Ñервери, налаштовані Ð´Ð»Ñ Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ, можна вимкнути на Ñторінці налаштувань.</translation>
<translation id="2955913368246107853">Закрити панель пошуку</translation>
<translation id="2958431318199492670">ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð¼ÐµÑ€ÐµÐ¶Ñ– не відповідає Ñтандарту ONC. Вона може імпортуватиÑÑ Ñ‡Ð°Ñтково.</translation>
-<translation id="29611076221683977">ЗловмиÑники, Ñкі зараз перебувають на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, можуть намагатиÑÑ Ð²Ñтановити на ваш приÑтрій з ОС Mac небезпечні програми, що викрадають або видалÑÑŽÑ‚ÑŒ інформацію (Ñк-от фотографії, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð¸ кредитні картки).</translation>
<translation id="2966678944701946121">Додано <ph name="ADDED_TO_AUTOFILL_MONTH" />, діє до <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2969319727213777354">Щоб уÑтановити безпечне з’єднаннÑ, потрібно правильно налаштувати чаÑ, оÑкільки Ñертифікати, Ñкі підтверджують ÑправжніÑÑ‚ÑŒ веб-Ñайтів, дійÑні лише протÑгом певного періоду. Ðа вашому приÑтрої неправильно налаштовано чаÑ, тому Chrome не може перевірити Ñертифікати.</translation>
<translation id="2972581237482394796">&amp;Повторити</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Введіть дійÑну адреÑу</translation>
<translation id="2986368408720340940">Цей ÑпоÑіб Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð½ÐµÐ´Ð¾Ñтупний. Виберіть інший ÑпоÑіб.</translation>
<translation id="2991174974383378012">ÐÐ°Ð´Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— веб-Ñайтам</translation>
+<translation id="2991571918955627853">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки веб-Ñайт викориÑтовує протокол HSTS. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше.</translation>
<translation id="3005723025932146533">Показати збережену копію</translation>
<translation id="3008447029300691911">Введіть код CVC картки <ph name="CREDIT_CARD" />. Щойно ви підтвердите дані картки, цей Ñайт отримає доÑтуп до них.</translation>
<translation id="3010559122411665027">Елемент ÑпиÑку "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">БлокуєтьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾</translation>
<translation id="3024663005179499861">Ðеправильний тип правила</translation>
<translation id="3032412215588512954">Оновити цей Ñайт?</translation>
<translation id="3037605927509011580">От халепа!</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{щонайменше 1 Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° Ñинхронізованих приÑтроÑÑ…}=1{1 Ð·Ð°Ð¿Ð¸Ñ (Ñ– більше на Ñинхронізованих приÑтроÑÑ…)}one{# Ð·Ð°Ð¿Ð¸Ñ (Ñ– більше на Ñинхронізованих приÑтроÑÑ…)}few{# запиÑи (Ñ– більше на Ñинхронізованих приÑтроÑÑ…)}many{# запиÑів (Ñ– більше на Ñинхронізованих приÑтроÑÑ…)}other{# запиÑу (Ñ– більше на Ñинхронізованих приÑтроÑÑ…)}}</translation>
<translation id="3041612393474885105">Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ Ñертифікат</translation>
<translation id="3063697135517575841">Chrome не вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸ дані вашої картки. Спробуйте пізніше.</translation>
<translation id="3064966200440839136">Щоб оплатити в зовнішньому додатку, ви вийдете з режиму анонімного переглÑду. Продовжити?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Ðемає}=1{1 пароль}one{# пароль}few{# паролі}many{# паролів}other{# паролÑ}}</translation>
<translation id="3093245981617870298">Ви в режимі офлайн</translation>
<translation id="3105172416063519923">Ідентифікатор об’єкта:</translation>
<translation id="3109728660330352905">У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” дозволу переглÑдати цю Ñторінку.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Проведіть діагноÑтику з’єднаннÑ<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Помилка Ð´ÐµÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ñ–</translation>
<translation id="3150653042067488994">ТимчаÑова помилка Ñервера</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Сторінки, Ñкі ви переглÑдаєте на анонімних вкладках, не реєÑтруютьÑÑ Ð² Ñ–Ñторії веб-переглÑдача чи Ñ–Ñторії пошуку та не залишають файлів cookie, коли ви закриваєте вÑÑ– анонімні вкладки. УÑÑ– завантажені файли чи Ñтворені закладки зберігаютьÑÑ.</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">ОÑтрів</translation>
+<translation id="317583078218509884">Ðові Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»Ñ–Ð² Ñайту почнуть діÑти піÑÐ»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñторінки.</translation>
<translation id="3176929007561373547">Перевірте Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñвого прокÑÑ–-Ñервера чи звернітьÑÑ Ð´Ð¾ адмініÑтратора мережі,
щоб переконатиÑÑ, що прокÑÑ–-Ñервер працює. Якщо ви вважаєте, що не потрібно
викориÑтовувати прокÑÑ–-Ñервер, виконайте вказані нижче дії.
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Відкрийте Ñторінку в режимі анонімного переглÑду</translation>
-<translation id="3202578601642193415">Ðайновіше</translation>
+<translation id="320323717674993345">СкаÑувати оплату</translation>
<translation id="3207960819495026254">Створено закладку</translation>
+<translation id="3225919329040284222">Сервер надав Ñертифікат, Ñкий не відповідає очікуваним вбудованим параметрам. Ці очікувані параметри вÑтановлено Ð´Ð»Ñ Ð¿ÐµÐ²Ð½Ð¸Ñ… веб-Ñайтів із виÑоким рівнем безпеки, щоб захиÑтити ваÑ.</translation>
<translation id="3226128629678568754">ÐатиÑніть кнопку перезавантаженнÑ, щоб повторно надіÑлати дані, потрібні Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñторінки.</translation>
+<translation id="3227137524299004712">Мікрофон</translation>
<translation id="3228969707346345236">Помилка перекладу. Сторінку вже перекладено такою мовою: <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">ВвеÑти код CVC картки <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Завжди виÑвлÑти важливий вміÑÑ‚ на цьому Ñайті</translation>
<translation id="3254409185687681395">Додати цю Ñторінку до закладок</translation>
<translation id="3270847123878663523">&amp;Відмінити перевпорÑдкуваннÑ</translation>
<translation id="3282497668470633863">Додати Ñ–Ð¼â€™Ñ Ð½Ð° кредитній картці</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">налаштуваннÑ</translation>
<translation id="3345135638360864351">Ðе вдалоÑÑ Ð½Ð°Ð´Ñ–Ñлати запит на доÑтуп до цього Ñайту кориÑтувачеві <ph name="NAME" />. Повторіть Ñпробу.</translation>
<translation id="3355823806454867987">Змінити Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ–...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />не зберігатиме<ph name="END_EMPHASIS" />:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Ñ–Ñторію веб-переглÑду
+ <ph name="LIST_ITEM" />файли cookie та дані із Ñайтів
+ <ph name="LIST_ITEM" />дані, Ñкі ви заповнюєте у формах
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Помилка годинника</translation>
-<translation id="337311366426640088">Ще <ph name="ITEM_COUNT" />…</translation>
<translation id="337363190475750230">Деініціалізовано</translation>
<translation id="3377188786107721145">Помилка аналізу правила</translation>
<translation id="3380365263193509176">Ðевідома помилка</translation>
<translation id="3380864720620200369">Ідентифікатор клієнта:</translation>
<translation id="3391030046425686457">ÐдреÑа доÑтавки</translation>
<translation id="3395827396354264108">СпоÑіб отриманнÑ</translation>
-<translation id="340013220407300675">ЗловмиÑники можуть намагатиÑÑ Ð²Ð¸ÐºÑ€Ð°Ñти вашу інформацію з <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (наприклад, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð¸ кредитні картки).</translation>
<translation id="3422248202833853650">Щоб звільнити пам’ÑÑ‚ÑŒ, закрийте інші програми.</translation>
<translation id="3422472998109090673">ХоÑÑ‚ <ph name="HOST_NAME" /> зараз недоÑтупний.</translation>
+<translation id="3427092606871434483">ДозволÑти (за умовчаннÑм)</translation>
<translation id="3427342743765426898">&amp;Повторити редагуваннÑ</translation>
<translation id="3431636764301398940">Зберегти цю картку на приÑтрої</translation>
<translation id="3435896845095436175">Увімкнути</translation>
<translation id="3447661539832366887">ВлаÑник цього приÑтрою вимкнув гру з динозавром.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Інтервал отриманнÑ:</translation>
<translation id="3462200631372590220">Сховати додаткову інформацію</translation>
<translation id="3467763166455606212">Потрібно вказати Ñ–Ð¼â€™Ñ Ð²Ð»Ð°Ñника картки</translation>
<translation id="3478058380795961209">МіÑÑць Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії</translation>
<translation id="3479539252931486093">Ðе очікували? <ph name="BEGIN_LINK" />Повідомте наÑ<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Ðе зараз</translation>
-<translation id="348000606199325318">Ідентифікатор аварійного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ <ph name="CRASH_LOCAL_ID" /> (ідентифікатор Ñервера: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Ðе вдалоÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· одним із ваших батьків. Повторіть Ñпробу.</translation>
<translation id="3528171143076753409">Сертифікат Ñервера ненадійний.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Принаймні 1 Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° Ñинхронізованих приÑтроÑÑ…}=1{1 Ð·Ð°Ð¿Ð¸Ñ (Ñ– ще на Ñинхронізованих приÑтроÑÑ…)}one{# Ð·Ð°Ð¿Ð¸Ñ (Ñ– ще на Ñинхронізованих приÑтроÑÑ…)}few{# запиÑи (Ñ– ще на Ñинхронізованих приÑтроÑÑ…)}many{# запиÑів (Ñ– ще на Ñинхронізованих приÑтроÑÑ…)}other{# запиÑу (Ñ– ще на Ñинхронізованих приÑтроÑÑ…)}}</translation>
<translation id="3539171420378717834">Зберігати копію даних цієї картки на цьому приÑтрої</translation>
<translation id="3542684924769048008">ВикориÑтовувати пароль длÑ:</translation>
+<translation id="3545341443414427877">Ðе вдаєтьÑÑ Ð²Ñтановити конфіденційне Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оÑкільки на комп’ютері налаштовано неправильні дату й Ñ‡Ð°Ñ (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Шифрувати вÑÑ– Ñинхронізовані дані за допомогою влаÑної парольної фрази Ð´Ð»Ñ Ñинхронізації</translation>
-<translation id="3549761410225185768">ще <ph name="NUM_TABS_MORE" />…</translation>
-<translation id="3555561725129903880">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки походить із домену <ph name="DOMAIN2" />. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">ÐдмініÑтратор може розблокувати його</translation>
<translation id="3566021033012934673">Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ конфіденційне</translation>
+<translation id="3569145463236695319">&lt;p&gt;Ðе вдаєтьÑÑ Ð²Ñтановити конфіденційне Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оÑкільки на вашому приÑтрої налаштовано неправильні дату й Ñ‡Ð°Ñ (<ph name="DATE_AND_TIME" />).&lt;/p&gt;
+
+ &lt;p&gt;Ðалаштуйте дату й Ñ‡Ð°Ñ Ñƒ розділі &lt;strong&gt;Загальні&lt;/strong&gt; додатка &lt;strong&gt;ÐалаштуваннÑ&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Додати ім’Ñ</translation>
<translation id="3583757800736429874">&amp;Повторити переміщеннÑ</translation>
<translation id="3586931643579894722">Сховати докладні дані</translation>
-<translation id="3587482841069643663">Ð’Ñе</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Введіть дійÑний термін дії</translation>
<translation id="36224234498066874">ОчиÑтити дані веб-переглÑду...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ Ñертифікат</translation>
<translation id="3690164694835360974">Вхід не захищено</translation>
<translation id="3693415264595406141">Пароль:</translation>
-<translation id="3696411085566228381">немає</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ЗавантаженнÑ...</translation>
<translation id="3712624925041724820">Ліцензії вичерпано</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />перевірити конфігурацію прокÑÑ–-Ñервера, брандмауера та DNS-Ñервера<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Якщо ви розумієте ризики, пов’Ñзані з безпекою, <ph name="BEGIN_LINK" />перейдіть на цей ненадійний Ñайт<ph name="END_LINK" /> до того, Ñк небезпечні програми буде видалено.</translation>
<translation id="3739623965217189342">Скопійоване поÑиланнÑ</translation>
+<translation id="3744899669254331632">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки веб-Ñайт надіÑлав зашифровані облікові дані, Ñкі Chromium не може обробити. Помилки мережі й атаки зазвичай Ñ” тимчаÑовими, тому Ñ†Ñ Ñторінка може працювати пізніше.</translation>
+<translation id="3748148204939282805">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть обманом змуÑити Ð²Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ небезпечну дію, Ñк-от уÑтановити шкідливе програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ повідомити оÑобиÑту інформацію (наприклад, паролі, номери телефону або дані кредитних карток). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ переклад через помилку Ñервера.</translation>
<translation id="3759461132968374835">У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” оÑтанніх повідомлень про аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸. Тут не відображатимутьÑÑ Ð²Ð¸Ð¿Ð°Ð´ÐºÐ¸ аварійного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸, Ñкі ÑталиÑÑ, коли Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ було вимкнено.</translation>
+<translation id="3778403066972421603">Зберегти дані картки у вашому обліковому запиÑÑ– Google Ñ– на цьому приÑтрої?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Діє до <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Якщо ви викориÑтовуєте прокÑÑ–-Ñервер…</translation>
<translation id="3828924085048779000">ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»ÑŒÐ½Ð° фраза заборонена.</translation>
-<translation id="3845539888601087042">Показано Ñ–Ñторію з приÑтроїв, на Ñких ви ввійшли в обліковий запиÑ. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Ðазад</translation>
<translation id="3858027520442213535">Оновити дату й чаÑ</translation>
<translation id="3884278016824448484">Конфліктуючий ідентифікатор приÑтрою</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Запит на доÑтуп до цього Ñайту надіÑлано кориÑтувачу <ph name="NAME" /></translation>
<translation id="3890664840433101773">Додати електронну адреÑу</translation>
<translation id="3901925938762663762">Термін дії картки минув</translation>
-<translation id="3933571093587347751">{1,plural, =1{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти завтра. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}one{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # день. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}few{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # дні. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}many{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # днів. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}other{Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки почне діÑти через # днÑ. Можливо, Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ документ PDF</translation>
+<translation id="3945915738023014686">Ідентифікатор завантаженого звіту про аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸: <ph name="CRASH_ID" /> (локальний ідентифікатор аварійного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. У його Ñертифікаті безпеки не вказано альтернативні імена. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
<translation id="3963721102035795474">Режим переглÑду</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Ðемає}=1{З 1 Ñайту }one{З # Ñайту }few{З # Ñайтів }many{З # Ñайтів }other{З # Ñайту }}</translation>
<translation id="397105322502079400">ОбчиÑленнÑ...</translation>
<translation id="3973234410852337861">ХоÑÑ‚ <ph name="HOST_NAME" /> заблокований</translation>
+<translation id="3987940399970879459">Менше 1 Мб</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 веб-Ñторінка поруч}one{# веб-Ñторінка поруч}few{# веб-Ñторінки поруч}many{# веб-Ñторінок поруч}other{# веб-Ñторінки поруч}}</translation>
<translation id="4021036232240155012">DNS – це мережева Ñлужба, Ñка перетворює назву веб-Ñайту на його інтернет-адреÑу.</translation>
<translation id="4030383055268325496">&amp;Відмінити додаваннÑ</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Конфігурацію прокÑÑ–-Ñервера налаштовано на викориÑÑ‚Ð°Ð½Ð½Ñ URL-адреÑи Ñценарію .pac, а не фікÑованих прокÑÑ–-Ñерверів.</translation>
<translation id="4098354747657067197">Оманливий Ñайт</translation>
<translation id="4103249731201008433">ÐедійÑний Ñерійний номер приÑтрою</translation>
+<translation id="410351446219883937">ÐвтовідтвореннÑ</translation>
<translation id="4103763322291513355">Перейдіть на Ñторінку &lt;strong&gt;chrome://policy&lt;/strong&gt;, щоб переглÑнути ÑпиÑок URL-Ð°Ð´Ñ€ÐµÑ Ñ–Ð· "чорного" ÑпиÑку й інші правила, що примуÑово заÑтоÑовуєтьÑÑ ÑиÑтемним адмініÑтратором.</translation>
-<translation id="4110615724604346410">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки міÑтить помилки. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Пурпурний</translation>
+<translation id="4116663294526079822">Завжди дозволÑти на цьому Ñайті</translation>
<translation id="4117700440116928470">Правило не підтримуєтьÑÑ.</translation>
-<translation id="4118212371799607889">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Chromium вважає його Ñертифікат безпеки ненадійним. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{і ще 1 елемент даних}one{і ще # елемент даних}few{і ще # елементи даних}many{і ще # елементів даних}other{і ще # елемента даних}}</translation>
<translation id="4130226655945681476">перевірити мережевий кабель, модем і маршрутизатор</translation>
+<translation id="413544239732274901">Докладніше</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">ВикориÑтовувати загальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° умовчаннÑм (визначати)</translation>
+<translation id="4165986682804962316">ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñайту</translation>
<translation id="4169947484918424451">Зберегти цю картку в Chromium?</translation>
<translation id="4171400957073367226">ÐедійÑний Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ</translation>
<translation id="4196861286325780578">&amp;Повторити переміщеннÑ</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />перевірити конфігурацію брандмауера й антивіруÑної програми<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{немає}=1{1 додаток ($1)}=2{2 додатки ($1, $2)}one{# додаток ($1, $2, $3)}few{# додатки ($1, $2, $3)}many{# додатків ($1, $2, $3)}other{# додатка ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Збої в роботі</translation>
+<translation id="422022731706691852">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть обманом змуÑити Ð²Ð°Ñ ÑƒÑтановити програми, що погіршують переглÑд веб-Ñторінок (наприклад, змінюють вашу домашню Ñторінку або показують додаткову рекламу на Ñайтах, Ñкі ви відвідуєте). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Проведіть діагноÑтику мережі<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">ДійÑний</translation>
<translation id="4250431568374086873">Ваше Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· цим Ñайтом не повніÑÑ‚ÑŽ захищене</translation>
<translation id="4250680216510889253">ні</translation>
<translation id="425582637250725228">ВнеÑені зміни, можливо, не буде збережено.</translation>
<translation id="4258748452823770588">ÐедійÑний підпиÑ</translation>
+<translation id="4265872034478892965">Дозволено адмініÑтратором</translation>
<translation id="4269787794583293679">(Ðемає імені кориÑтувача)</translation>
<translation id="4275830172053184480">ПерезапуÑÑ‚Ñ–Ñ‚ÑŒ приÑтрій</translation>
<translation id="4280429058323657511">, дійÑна до <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно <ph name="BEGIN_LINK" />виÑвила шкідливі програми<ph name="END_LINK" /> на Ñайті <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Поради Ð´Ð»Ñ Ð±Ð°Ñ‚ÑŒÐºÑ–Ð²</translation>
<translation id="4304224509867189079">Вхід</translation>
-<translation id="432290197980158659">Сервер надав Ñертифікат, Ñкий не відповідає очікуваним вбудованим параметрам. Ці очікувані параметри включено Ð´Ð»Ñ Ð¿ÐµÐ²Ð½Ð¸Ñ… веб-Ñайтів із виÑоким рівнем безпеки, щоб захиÑтити ваÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Блокувати (за умовчаннÑм)</translation>
<translation id="4325863107915753736">Статтю не знайдено</translation>
<translation id="4326324639298822553">Перевірте дату Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії та повторіть Ñпробу</translation>
<translation id="4331708818696583467">Ðенадійне</translation>
<translation id="4356973930735388585">ЗловмиÑники на цьому Ñайті можуть намагатиÑÑ Ð²Ñтановити на ваш комп’ютер небезпечні програми, що викрадають або видалÑÑŽÑ‚ÑŒ інформацію (наприклад, фотографії, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¹ дані кредитних карток).</translation>
<translation id="4372948949327679948">Очікуване значеннÑ: <ph name="VALUE_TYPE" />.</translation>
+<translation id="4377125064752653719">Ви пробували зв’ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, проте Ñервер надав Ñертифікат, відкликаний його видавцем. Це означає, що не варто довірÑти обліковим даним ÑиÑтеми захиÑту, наданим Ñервером. Можливо, ви обмінюєтеÑÑ Ð´Ð°Ð½Ð¸Ð¼Ð¸ зі зловмиÑником.</translation>
<translation id="4381091992796011497">Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача:</translation>
<translation id="4394049700291259645">Вимкнути</translation>
<translation id="4406896451731180161">результати пошуку</translation>
+<translation id="4424024547088906515">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Chrome не вважає його Ñертифікат безпеки надійним. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
<translation id="4432688616882109544">ХоÑÑ‚ <ph name="HOST_NAME" /> не прийнÑв ваш Ñертифікат входу або ви не надали цей Ñертифікат.</translation>
<translation id="443673843213245140">ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ–-Ñервера вимкнено, але чітко вказано Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐºÑÑ–-Ñервера.</translation>
-<translation id="4492190037599258964">Результати пошуку Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ "<ph name="SEARCH_STRING" />"</translation>
<translation id="4506176782989081258">Помилка перевірки: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">зв’ÑзатиÑÑ Ñ–Ð· ÑиÑтемним адмініÑтратором</translation>
<translation id="450710068430902550">ÐÐ°Ð´Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— адмініÑтратору</translation>
<translation id="4515275063822566619">Дані картки та ÑпиÑок Ð°Ð´Ñ€ÐµÑ Ð¼Ñ–ÑÑ‚ÑÑ‚ÑŒÑÑ Ð² Chrome Ñ– вашому обліковому запиÑÑ– Google (<ph name="ACCOUNT_EMAIL" />). Ðими можна керувати в <ph name="BEGIN_LINK" />ÐалаштуваннÑÑ…<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Деталі</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Спробуйте вимкнути розширеннÑ.</translation>
<translation id="457875822857220463">ДоÑтавка</translation>
<translation id="4587425331216688090">Видалити адреÑу з Chrome?</translation>
-<translation id="4589078953350245614">Ви намагалиÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, але Ñервер надав недійÑний Ñертифікат. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· доменом <ph name="DOMAIN" /> шифруєтьÑÑ Ð·Ð° допомогою ÑучаÑного набору шифрів.</translation>
<translation id="4594403342090139922">&amp;Відмінити видаленнÑ</translation>
<translation id="4619615317237390068">Вкладки з інших приÑтроїв</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Його Ñертифікат безпеки міÑтить помилки. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
+<translation id="4690462567478992370">Припинити викориÑÑ‚Ð°Ð½Ð½Ñ Ð½ÐµÐ´Ñ–Ð¹Ñного Ñертифіката</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Ð—â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ–Ñ€Ð²Ð°Ð½Ð¾</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />провеÑти діагноÑтику мережі Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Виникла невідома помилка.</translation>
<translation id="4800132727771399293">Перевірте дату Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії та код CVC та повторіть Ñпробу</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
+<translation id="4807049035289105102">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки веб-Ñайт надіÑлав зашифровані облікові дані, Ñкі Google Chrome не може обробити. Помилки мережі й атаки зазвичай Ñ” тимчаÑовими, тому Ñ†Ñ Ñторінка може працювати пізніше.</translation>
<translation id="4813512666221746211">Помилка мережі</translation>
<translation id="4816492930507672669">За розміром Ñторінки</translation>
<translation id="483020001682031208">Ðемає Ñторінок ÑервіÑу "Інтернет навколо наÑ" Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ</translation>
<translation id="4850886885716139402">ПереглÑд</translation>
<translation id="4854362297993841467">Цей ÑпоÑіб доÑтавки недоÑтупний. Виберіть інший ÑпоÑіб.</translation>
<translation id="4858792381671956233">Ви надіÑлали батькам запит на переглÑд цього Ñайту</translation>
+<translation id="4863764087567530506">Цей вміÑÑ‚ може оманливим шлÑхом змуÑити Ð²Ð°Ñ ÑƒÑтановити програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ надати оÑобиÑту інформацію. <ph name="BEGIN_LINK" />УÑе одно показати<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Пошук в Ñ–Ñторії</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{Ñ– ще 1 веб-Ñторінка}one{Ñ– ще # веб-Ñторінка}few{Ñ– ще # веб-Ñторінки}many{Ñ– ще # веб-Ñторінок}other{Ñ– ще # веб-Ñторінки}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Цю Ñторінку перекладено з невідомої мови оригіналу такою мовою: <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Оплата</translation>
<translation id="4926049483395192435">Потрібно вказати.</translation>
<translation id="495170559598752135">Дії</translation>
<translation id="4958444002117714549">Розгорнути ÑпиÑок</translation>
-<translation id="4962322354953122629">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Chrome вважає його Ñертифікат безпеки ненадійним. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Показувати заÑтереженнÑ</translation>
<translation id="4989809363548539747">Цей плагін не підтримуєтьÑÑ</translation>
<translation id="5002932099480077015">Коли цю функцію ввімкнено, Chrome зберігає копію даних вашої картки на приÑтрої, щоб ви могли швидше заповнювати форми.</translation>
<translation id="5018422839182700155">Ðе вдаєтьÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ цю Ñторінку</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">ПереглÑньте правила Ñвого адмініÑтратора</translation>
<translation id="5029568752722684782">Видалити копію</translation>
<translation id="5031870354684148875">Про Перекладач Google</translation>
+<translation id="5039804452771397117">Дозволити</translation>
<translation id="5040262127954254034">КонфіденційніÑÑ‚ÑŒ</translation>
<translation id="5045550434625856497">Ðеправильний пароль</translation>
<translation id="5056549851600133418">Статті Ð´Ð»Ñ Ð²Ð°Ñ</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />перевірити адреÑу прокÑÑ–-Ñервера<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Ðемає файлів cookie}=1{1 Ñайт викориÑтовує файли cookie. }one{# Ñайт викориÑтовує файли cookie. }few{# Ñайти викориÑтовують файли cookie. }many{# Ñайтів викориÑтовують файли cookie. }other{# Ñайту викориÑтовує файли cookie. }}</translation>
<translation id="5087286274860437796">Сертифікат Ñервера зараз недійÑний.</translation>
<translation id="5087580092889165836">Додати картку</translation>
<translation id="5089810972385038852">Штат</translation>
+<translation id="5094747076828555589">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Chromium не вважає його Ñертифікат безпеки надійним. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
<translation id="5095208057601539847">ÐŸÑ€Ð¾Ð²Ñ–Ð½Ñ†Ñ–Ñ Ñ‡Ð¸ облаÑÑ‚ÑŒ</translation>
<translation id="5115563688576182185">(64-розрÑдна верÑÑ–Ñ)</translation>
<translation id="5141240743006678641">Шифрувати Ñинхронізовані паролі за допомогою облікових даних Google</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Укажіть електронну адреÑу</translation>
<translation id="5251803541071282808">Хмара</translation>
<translation id="5277279256032773186">КориÑтуєтеÑÑ Chrome на роботі? Компанії можуть налаштовувати Chrome Ð´Ð»Ñ Ñвоїх працівників. Докладніше</translation>
+<translation id="5297526204711817721">Ваше Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· цим Ñайтом не конфіденційне. Щоб будь-коли вийти з режиму віртуальної реальноÑÑ‚Ñ–, від’єднайте гарнітуру та натиÑніть кнопку "Ðазад".</translation>
<translation id="5299298092464848405">Помилка аналізу правила</translation>
-<translation id="5300589172476337783">Показати</translation>
<translation id="5308689395849655368">ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ вимкнено.</translation>
<translation id="5317780077021120954">Зберегти</translation>
<translation id="5327248766486351172">Ðазва</translation>
-<translation id="5337705430875057403">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть обманом змуÑити Ð²Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ небезпечну дію, Ñк-от уÑтановити шкідливе програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ повідомити оÑобиÑту інформацію (наприклад, паролі, номери телефонів або кредитних карток).</translation>
-<translation id="5359637492792381994">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Його Ñертифікат безпеки зараз недійÑний. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки цей Ñертифікат відкликано. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше.</translation>
<translation id="536296301121032821">Помилка Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ правила</translation>
<translation id="5386426401304769735">Ланцюжок Ñертифіката цього Ñайту міÑтить Ñертифікат, підпиÑаний за допомогою SHA-1.</translation>
<translation id="5402410679244714488">Діє до <ph name="EXPIRATION_DATE_ABBR" />. ВоÑтаннє викориÑтано понад рік тому</translation>
+<translation id="540969355065856584">Серверу не вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це <ph name="DOMAIN" />. Його Ñертифікат безпеки зараз недійÑний. Можливі причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ перехопив ваше з’єднаннÑ.</translation>
<translation id="5421136146218899937">ОчиÑтити дані веб-переглÑду...</translation>
<translation id="5430298929874300616">Видалити закладку</translation>
<translation id="5431657950005405462">Файл не знайдено</translation>
-<translation id="5435775191620395718">Показано Ñ–Ñторію з цього приÑтрою. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Помилка перевірки Ñхеми за адреÑою "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Сторінку хоÑту <ph name="HOST_NAME" /> не знайдено</translation>
<translation id="5455374756549232013">ÐедійÑна мітка чаÑу правила</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> із <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">ÐедійÑні дані</translation>
<translation id="5470861586879999274">&amp;Повторити редагуваннÑ</translation>
<translation id="54817484435770891">Додати дійÑну адреÑу</translation>
<translation id="5492298309214877701">URL-адреÑа цього Ñайту в інтранеті компанії, організації чи навчального закладу збігаєтьÑÑ Ð· адреÑою зовнішнього веб-Ñайту.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">ÐдреÑа Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ. Укажіть іншу адреÑу.</translation>
<translation id="5572851009514199876">Увійдіть в обліковий Ð·Ð°Ð¿Ð¸Ñ Chrome, щоб веб-переглÑдач міг перевірити, чи ви маєте дозвіл відвідувати цей Ñайт.</translation>
<translation id="5580958916614886209">Перевірте міÑÑць Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії та повторіть Ñпробу</translation>
+<translation id="5586446728396275693">Ðемає збережених адреÑ</translation>
+<translation id="5595485650161345191">Редагувати адреÑу</translation>
<translation id="560412284261940334">ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ підтримуєтьÑÑ</translation>
<translation id="5610142619324316209">перевірити наÑвніÑÑ‚ÑŒ з’єднаннÑ</translation>
<translation id="5610807607761827392">Ви можете керувати картками й адреÑами в <ph name="BEGIN_LINK" />ÐалаштуваннÑÑ…<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Покинути цей Ñайт?</translation>
<translation id="5629630648637658800">Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ правила</translation>
<translation id="5631439013527180824">ÐедійÑний маркер ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ñтрою</translation>
+<translation id="5633066919399395251">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть уÑтановити на ваш комп’ютер небезпечні програми, що викрадають або видалÑÑŽÑ‚ÑŒ інформацію (Ñк-от фотографії, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° дані кредитних карток). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">МіÑцезнаходженнÑ</translation>
+<translation id="5659593005791499971">Електронна пошта</translation>
<translation id="5669703222995421982">Отримувати перÑоналізовані пропозиції</translation>
<translation id="5675650730144413517">Сторінка не працює</translation>
-<translation id="5677928146339483299">Заблоковано</translation>
-<translation id="5694783966845939798">Ви намагалиÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, але Ñервер надав Ñертифікат, підпиÑаний із викориÑтаннÑм Ñлабкого алгоритму підпиÑу (Ñк-от SHA-1). Це означає, що облікові дані безпеки, надані Ñервером, можуть бути ÑфальÑифікованими, а Ñервер – не тим, Ñкий вам потрібен (ви можете передавати Ñвої дані зловмиÑнику). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Ідентифікаційну інформацію цього веб-Ñайта не було перевірено.</translation>
+<translation id="5713016350996637505">Заблоковано оманливий вміÑÑ‚</translation>
<translation id="5720705177508910913">Поточний кориÑтувач</translation>
<translation id="5732392974455271431">Батьки можуть розблокувати його</translation>
<translation id="5763042198335101085">Введіть дійÑну електронну адреÑу</translation>
<translation id="5765072501007116331">Укажіть адреÑу, щоб переглÑнути ÑпоÑоби доÑтавки та вимоги.</translation>
+<translation id="5778550464785688721">Повний контроль приÑтроїв MIDI</translation>
<translation id="5784606427469807560">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸ дані картки. Перевірте Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Інтернетом Ñ– повторіть Ñпробу.</translation>
<translation id="5785756445106461925">Окрім цього, Ñторінка міÑтить незахищені реÑурÑи. Інші оÑоби можуть переглÑдати Ñ—Ñ… під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…, а зловмиÑники можуть змінювати виглÑд Ñторінки.</translation>
<translation id="5786044859038896871">ВвеÑти дані кредитної картки?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Повторити додаваннÑ</translation>
<translation id="5814352347845180253">Ви можете втратити доÑтуп до платного вміÑту на Ñайті <ph name="SITE" /> Ñ– деÑких інших Ñайтах.</translation>
<translation id="5838278095973806738">Ðе вводьте конфіденційну інформацію на цьому Ñайті (Ñк-от паролі й дані кредитних карток). ЗловмиÑники можуть викраÑти Ñ—Ñ—.</translation>
-<translation id="5843436854350372569">Ви намагалиÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, але Ñервер надав Ñертифікат, Ñкий міÑтить Ñлабкий ключ. Можливо, зловмиÑник зламав Ñекретний ключ, а Ñервер не Ñ” тим, Ñкий вам потрібен (ви можете передавати Ñвої дані зловмиÑнику). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Ðемає зв’Ñзку із Ñайтом</translation>
<translation id="5869522115854928033">Збережені паролі</translation>
<translation id="5872918882028971132">Поради Ð´Ð»Ñ Ð±Ð°Ñ‚ÑŒÐºÑ–Ð²</translation>
<translation id="5901630391730855834">Жовтий</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (Ñинхронізовано)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ВикориÑтовуєтьÑÑ 1 файл}one{ВикориÑтовуєтьÑÑ # файл}few{ВикориÑтовуютьÑÑ # файли}many{ВикориÑтовуютьÑÑ # файлів}other{ВикориÑтовуютьÑÑ # файлу}}</translation>
<translation id="5926846154125914413">Ви можете втратити доÑтуп до платного вміÑту на деÑких Ñайтах.</translation>
<translation id="5959728338436674663">Ðвтоматично надÑилати в Google деÑку <ph name="BEGIN_WHITEPAPER_LINK" />інформацію про ÑиÑтему та вміÑÑ‚ Ñторінок<ph name="END_WHITEPAPER_LINK" />, щоб допомогти виÑвлÑти небезпечні додатки й Ñайти<ph name="PRIVACY_PAGE_LINK" />.</translation>
-<translation id="5966707198760109579">Тиждень</translation>
<translation id="5967867314010545767">Видалити з Ñ–Ñторії</translation>
<translation id="5975083100439434680">Зменшити маÑштаб</translation>
<translation id="598637245381783098">Ðеможливо відкрити додаток Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶Ñ–Ð²</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Сторінка 1}one{Сторінка #}few{Сторінка #}many{Сторінка #}other{Сторінка #}}</translation>
<translation id="6017514345406065928">Зелений</translation>
+<translation id="6017850046339264347">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть уÑтановити на ваш приÑтрій оманливі додатки, Ñкі видають Ñебе за інший вміÑÑ‚ або збирають дані Ð´Ð»Ñ Ð²Ñ–Ð´ÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¾Ñ— активноÑÑ‚Ñ–. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (Ñинхронізовано)</translation>
<translation id="6027201098523975773">Введіть ім’Ñ</translation>
<translation id="6040143037577758943">Закрити</translation>
<translation id="6042308850641462728">Більше</translation>
+<translation id="6047233362582046994">Якщо ви розумієте ризики, пов’Ñзані з безпекою, можете <ph name="BEGIN_LINK" />перейти на цей Ñайт<ph name="END_LINK" />, перш ніж небезпечні додатки буде видалено.</translation>
+<translation id="6051221802930200923">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки цей веб-Ñайт викориÑтовує Ð·Ð°ÐºÑ€Ñ–Ð¿Ð»ÐµÐ½Ð½Ñ Ñертифікатів. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше.</translation>
<translation id="6060685159320643512">Обережно, ці екÑперименти ненадійні</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{немає}=1{1}one{#}few{#}many{#}other{#}}</translation>
+<translation id="6080696365213338172">Ви отримали доÑтуп до вміÑту, викориÑтовуючи наданий адмініÑтратором Ñертифікат. ÐдмініÑтратор може перехоплювати дані, Ñкі ви надаÑте домену <ph name="DOMAIN" />.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Ðемає}=1{1 пароль (Ñинхронізовано)}one{# пароль (Ñинхронізовано)}few{# паролі (Ñинхронізовано)}many{# паролів (Ñинхронізовано)}other{# Ð¿Ð°Ñ€Ð¾Ð»Ñ (Ñинхронізовано)}}</translation>
<translation id="6146055958333702838">Перевірте вÑÑ– кабелі та перезавантажте вÑÑ– маршрутизатори, модеми чи інші мережеві
приÑтрої, Ñкі ви викориÑтовуєте.</translation>
<translation id="614940544461990577">Спробуйте:</translation>
<translation id="6151417162996330722">Сертифікат Ñервера має задовгий термін дії.</translation>
<translation id="6157877588268064908">Укажіть адреÑу, щоб переглÑнути ÑпоÑоби Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° вимоги.</translation>
+<translation id="6158003235852588289">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно виÑвила фішинг на Ñайті <ph name="SITE" />. Фішингові Ñайти видають Ñебе за інші Ñайти, щоб ошукати ваÑ.</translation>
<translation id="6165508094623778733">Докладніше</translation>
+<translation id="6169916984152623906">Тепер ви можете переглÑдати вміÑÑ‚ анонімно. Інші кориÑтувачі вашого приÑтрою не бачитимуть дані про вашу активніÑÑ‚ÑŒ. Однак Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° закладки зберігатимутьÑÑ.</translation>
<translation id="6177128806592000436">Ваше Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· цим Ñайтом не захищене</translation>
<translation id="6184817833369986695">(когорта: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Перевірте Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Інтернетом</translation>
<translation id="6218753634732582820">Видалити адреÑу з Chromium?</translation>
+<translation id="6221345481584921695">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google <ph name="BEGIN_LINK" />виÑвила зловмиÑне програмне забезпеченнÑ<ph name="END_LINK" /> на Ñайті <ph name="SITE" />. Іноді зловмиÑне програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñ€Ð°Ð¶Ð°Ñ” зазвичай безпечні веб-Ñайти. Шкідливий вміÑÑ‚ походить із хоÑту <ph name="SUBRESOURCE_HOST" /> – відомого розповÑюджувача зловмиÑного програмного забезпеченнÑ.</translation>
<translation id="6251924700383757765">Політика конфіденційноÑÑ‚Ñ–</translation>
<translation id="6254436959401408446">ÐедоÑтатньо пам’ÑÑ‚Ñ–, щоб відкрити цю Ñторінку</translation>
<translation id="625755898061068298">Ви вимкнули показ заÑтережень про небезпеку Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñайту.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Редагувати закладку</translation>
<translation id="6410264514553301377">Введіть дату Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії та код CVC картки <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Ви надіÑлали одному з батьків запит на переглÑд цього Ñайту</translation>
-<translation id="6416403317709441254">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки веб-Ñайт надіÑлав зашифровані облікові дані, Ñкі Chromium не може обробити. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Ðеможливо перевірити, чи цей Ñертифікат було відкликано.</translation>
<translation id="6433490469411711332">Змінити контактні дані</translation>
<translation id="6433595998831338502">ХоÑÑ‚ <ph name="HOST_NAME" /> відхилив запит на з’єднаннÑ.</translation>
<translation id="6446608382365791566">Додати більше інформації</translation>
+<translation id="6447842834002726250">Cookie-файли</translation>
<translation id="6451458296329894277">Підтвердити повторне надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð¸</translation>
<translation id="6456339708790392414">Ваш платіж</translation>
<translation id="6458467102616083041">ІгноруєтьÑÑ, оÑкільки пошук за умовчаннÑм вимкнено правилом.</translation>
-<translation id="6462969404041126431">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Можливо, його Ñертифікат безпеки відкликано. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Правила приÑтрою</translation>
<translation id="6477321094435799029">Chrome виÑвив на цій Ñторінці незвичний код Ñ– заблокував його, щоб захиÑтити вашу оÑобиÑту інформацію (наприклад, паролі, номери телефонів або кредитних карток).</translation>
<translation id="6489534406876378309">Почати Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… про аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">ВоÑтаннє викориÑтано <ph name="LAST_USED_DATE_NO_DETAIL" />, діє до <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="6563469144985748109">ÐдмініÑтратор ще не Ñхвалив його</translation>
<translation id="6569060085658103619">Ви переглÑдаєте Ñторінку розширень</translation>
-<translation id="6593753688552673085">менше <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Цей вміÑÑ‚ може вÑтановити небезпечне програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð½Ð° ваш приÑтрій, щоб викраÑти або видалити інформацію. <ph name="BEGIN_LINK" />УÑе одно показати<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Параметри шифруваннÑ</translation>
<translation id="662080504995468778">ЗалишитиÑÑ</translation>
<translation id="6626291197371920147">Додати дійÑний номер картки</translation>
<translation id="6628463337424475685">Пошук <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть уÑтановити на ваш комп’ютер Mac небезпечні програми, що викрадають або видалÑÑŽÑ‚ÑŒ інформацію (Ñк-от фотографії, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚Ð° дані кредитних карток). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Це правило більше не викориÑтовуєтьÑÑ.</translation>
-<translation id="6652240803263749613">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Операційна ÑиÑтема вашого комп’ютера вважає його Ñертифікат безпеки ненадійним. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Видалити пропозицію Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ñ„Ð¾Ñ€Ð¼ із Chromium?</translation>
<translation id="6685834062052613830">Вийдіть з облікового запиÑу та завершіть процедуру налаштуваннÑ</translation>
<translation id="6710213216561001401">Попереднє</translation>
<translation id="6710594484020273272">&lt;Введіть пошуковий термін&gt;</translation>
<translation id="6711464428925977395">Помилка прокÑÑ–-Ñервера або неправильна адреÑа.</translation>
<translation id="6727102863431372879">Ð’Ñтановити</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{немає}=1{1 запиÑ}one{# запиÑ}few{# запиÑи}many{# запиÑів}other{# запиÑу}}</translation>
<translation id="674375294223700098">Помилка "Ðевідомий Ñертифікат Ñервера".</translation>
<translation id="6753269504797312559">Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð°</translation>
<translation id="6757797048963528358">Ваш приÑтрій перейшов у режим Ñну.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">Ідентифікатор налаштуваннÑ</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ дані регіонів</translation>
+<translation id="6825578344716086703">Ви Ñпробували зв’ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, проте Ñервер надав Ñертифікат, підпиÑаний із викориÑтаннÑм Ñлабкого алгоритму підпиÑу (Ñк-от SHA-1). Це означає, що облікові дані безпеки, надані Ñервером, можуть бути ÑфальÑифікованими, а Ñервер – не тим, Ñкий вам потрібен (ви можете передавати Ñвої дані зловмиÑнику).</translation>
+<translation id="6830728435402077660">Ðебезпечно</translation>
<translation id="6831043979455480757">ПереклаÑти</translation>
<translation id="6839929833149231406">Регіон або територіÑ</translation>
<translation id="6874604403660855544">&amp;Повторити додаваннÑ</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Дані картки підтверджено</translation>
<translation id="6897140037006041989">Ðгент кориÑтувача</translation>
<translation id="6915804003454593391">КориÑтувач:</translation>
+<translation id="6945221475159498467">Вибрати</translation>
<translation id="6948701128805548767">Укажіть адреÑу, щоб переглÑнути ÑпоÑоби Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ‚Ð° вимоги.</translation>
<translation id="6957887021205513506">Схоже, що Ñертифікат Ñервера підроблено.</translation>
<translation id="6965382102122355670">ТÐК</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Указано фікÑовані прокÑÑ–-Ñервери та URL-адреÑа Ñценарію .pac.</translation>
<translation id="6989763994942163495">Показати розширені налаштуваннÑ...</translation>
<translation id="7000990526846637657">Ðемає запиÑів в Ñ–Ñторії</translation>
-<translation id="7009986207543992532">Ви намагалиÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, але Ñервер надав Ñертифікат із задовгим терміном дії. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð²ÐµÐ±-переглÑду також може зберігатиÑÑ Ñƒ вашому обліковому запиÑÑ– Google на Ñторінці <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Паролі</translation>
+<translation id="7050187094878475250">Ви намагалиÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, але Ñервер надав Ñертифікат із задовгим терміном дії.</translation>
+<translation id="7053983685419859001">Блокувати</translation>
<translation id="7064851114919012435">Контактна інформаціÑ</translation>
<translation id="7079718277001814089">Цей Ñайт міÑтить зловмиÑне програмне забезпеченнÑ</translation>
<translation id="7087282848513945231">Округ або графÑтво</translation>
-<translation id="7088615885725309056">Давніше</translation>
<translation id="7090678807593890770">Пошукайте за запитом "<ph name="LINK" />" у Google</translation>
+<translation id="7108819624672055576">Дозволено розширеннÑм</translation>
<translation id="7119414471315195487">Закрийте інші вкладки та програми</translation>
<translation id="7129409597930077180">Ðеможливо відправити Ð·Ð°Ð¼Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð° цю адреÑу. Укажіть іншу адреÑу.</translation>
<translation id="7138472120740807366">СпоÑіб доÑтавки</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Обробка</translation>
<translation id="724691107663265825">Сайт міÑтить зловмиÑне програмне забезпеченнÑ</translation>
<translation id="724975217298816891">Введіть термін дії та код CVC картки <ph name="CREDIT_CARD" />, щоб оновити Ñ—Ñ— дані. Щойно ви підтвердите дані картки, цей Ñайт отримає доÑтуп до них.</translation>
-<translation id="725866823122871198">Ðе вдаєтьÑÑ Ð²Ñтановити конфіденційне Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оÑкільки на комп’ютері вÑтановлено неправильні дату й Ñ‡Ð°Ñ (<ph name="DATE_AND_TIME" />).</translation>
+<translation id="7260504762447901703">СкаÑувати доÑтуп</translation>
<translation id="7275334191706090484">Закладки, Ñкими керує адмініÑтратор</translation>
<translation id="7298195798382681320">Рекомендоване</translation>
<translation id="7309308571273880165">Звіт про аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ Ñтворено <ph name="CRASH_TIME" /> (ще не завантажено)</translation>
<translation id="7334320624316649418">&amp;Повторити перевпорÑдкуваннÑ</translation>
<translation id="733923710415886693">Сертифікат Ñервера не надав інформацію про перевірку.</translation>
-<translation id="7351800657706554155">Зараз не можна перейти на Ñторінку <ph name="SITE" />, оÑкільки Ñ—Ñ— Ñертифікат відкликано. Помилки мережі й атаки зазвичай тимчаÑові, тому Ñ†Ñ Ñторінка, Ñкоріш за вÑе, запрацює пізніше. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Командний Ñ€Ñдок</translation>
<translation id="7372973238305370288">результат пошуку</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ÐÑ–</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Підтвердити дані картки</translation>
-<translation id="7394102162464064926">Справді видалити ці Ñторінки з Ñ–Ñторії?
-
-ÐаÑтупного разу ÑкориÑтайтеÑÑ Ñ€ÐµÐ¶Ð¸Ð¼Ð¾Ð¼ анонімного переглÑду (<ph name="SHORTCUT_KEY" />).</translation>
<translation id="7400418766976504921">URL-адреÑа</translation>
<translation id="7419106976560586862">ШлÑÑ… до профілю</translation>
<translation id="7424977062513257142">ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· вбудованої Ñторінки на цій веб-Ñторінці:</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">Цей Ñайт заблоковано</translation>
<translation id="7445762425076701745">Ідентифікацію Ñервера, з Ñким ви з'єднані, не можна повніÑÑ‚ÑŽ підтвердити. Ви з'єднані із Ñервером за допомогою імені, дійÑного лише у вашій мережі, Ñ– зовнішній центр Ñертифікації не має ÑпоÑобів підтвердити право влаÑноÑÑ‚Ñ– на це ім'Ñ. Хоча деÑкі центри Ñертифікації, попри вÑе, видають Ñертифікати на такі імена, неможливо цілком упевнитиÑÑ, що ви з'єднані з безпечним Ñайтом, а не зі зловмиÑником.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />дізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ<ph name="END_LINK" /> про цю проблему.</translation>
+<translation id="7455133967321480974">ВикориÑтовувати глобальне Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° умовчаннÑм (Блокувати)</translation>
<translation id="7460163899615895653">Тут відображатимутьÑÑ Ð²Ð°ÑˆÑ– оÑтанні вкладки з інших приÑтроїв</translation>
<translation id="7469372306589899959">ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… картки</translation>
<translation id="7481312909269577407">ПереÑлати</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">Отриманий ідентифікатор правил приÑтрою порожній або не збігаєтьÑÑ Ð· поточним ідентифікатором приÑтрою</translation>
<translation id="7514365320538308">Завантажити</translation>
<translation id="7518003948725431193">Ðе знайдено веб-Ñторінок Ð´Ð»Ñ Ð²ÐµÐ±-адреÑи <ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">ЯÑкравіÑÑ‚ÑŒ</translation>
<translation id="7537536606612762813">Обов’Ñзкове</translation>
+<translation id="7542403920425041731">Щойно ви підтвердите, цей Ñайт отримає доÑтуп до даних вашої картки.</translation>
<translation id="7542995811387359312">Ðвтоматичне Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÐºÑ€ÐµÐ´Ð¸Ñ‚Ð½Ð¾Ñ— картки вимкнено, оÑкільки Ñ†Ñ Ñ„Ð¾Ñ€Ð¼Ð° не викориÑтовує безпечне з'єднаннÑ.</translation>
<translation id="7543525346216957623">ПопроÑÑ–Ñ‚ÑŒ когоÑÑŒ із батьків</translation>
<translation id="7549584377607005141">Ð”Ð»Ñ Ð½Ð°Ð»ÐµÐ¶Ð½Ð¾Ð³Ð¾ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñ†Ñ–Ð¹ веб-Ñторінці потрібні введені вами раніше дані. Можна ще раз надіÑлати дані, однак зробивши це, ви повторите вÑÑ– дії, Ñкі Ñ†Ñ Ñторінка виконувала раніше.</translation>
<translation id="7552846755917812628">Виконайте вказівки нижче.</translation>
<translation id="7554791636758816595">Ðова вкладка</translation>
+<translation id="7567204685887185387">Цей Ñервер не зміг довеÑти, що він – домен <ph name="DOMAIN" />. Можливо, його Ñертифікат безпеки видали шахраї. Імовірні причини: неправильна ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð°Ð±Ð¾ хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}one{<ph name="CONTACT_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}many{<ph name="CONTACT_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="7568593326407688803">Мова цієї Ñторінки:<ph name="ORIGINAL_LANGUAGE" />ПереклаÑти Ñ—Ñ—?</translation>
<translation id="7569952961197462199">Видалити дані кредитної картки з Chrome?</translation>
<translation id="7569983096843329377">Чорний</translation>
<translation id="7578104083680115302">Зберігайте картки в Google, щоб швидко платити на Ñайтах Ñ– в додатках на вÑÑ–Ñ… Ñвоїх приÑтроÑÑ….</translation>
<translation id="7588950540487816470">Інтернет навколо наÑ</translation>
<translation id="7592362899630581445">Сертифікат Ñервера порушує обмежувальні умови щодо імен.</translation>
+<translation id="7598391785903975535">Менше <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187">ХоÑÑ‚ <ph name="HOST_NAME" /> зараз не може обробити цей запит.</translation>
<translation id="7600965453749440009">Ðіколи не перекладати з такої мови: <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° межами діапазону <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Діє до: <ph name="EXPIRATION_MONTH" />.<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Ви вже зашифрували дані, викориÑтовуючи іншу верÑÑ–ÑŽ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу Google. Введіть його нижче.</translation>
-<translation id="7634554953375732414">Ваше Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· цим Ñайтом не конфіденційне.</translation>
<translation id="7637571805876720304">Видалити дані кредитної картки з Chromium?</translation>
<translation id="765676359832457558">Сховати розширені налаштуваннÑ...</translation>
<translation id="7658239707568436148">СкаÑувати</translation>
+<translation id="7662298039739062396">ÐалаштуваннÑм керує розширеннÑ</translation>
<translation id="7667346355482952095">Отриманий маркер правила порожній або не збігаєтьÑÑ Ð· поточним маркером</translation>
<translation id="7668654391829183341">Ðевідомий приÑтрій</translation>
<translation id="7669271284792375604">ЗловмиÑники на цьому Ñайті можуть обманом змуÑити Ð²Ð°Ñ ÑƒÑтановити програми, Ñкі погіршують роботу в Інтернеті (наприклад, змінюють вашу домашню Ñторінку або показують додаткову рекламу на Ñайтах, Ñкі ви відвідуєте).</translation>
<translation id="7674629440242451245">Хочете Ñпробувати нові цікаві функції Chrome? Завантажте верÑÑ–ÑŽ Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÑ–Ð² зі Ñторінки chrome.com/dev.</translation>
<translation id="7682287625158474539">ÐдреÑа Ð´Ð»Ñ Ð½Ð°Ð´ÑиланнÑ</translation>
+<translation id="7701040980221191251">Ðемає</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Перейти на Ñайт <ph name="SITE" /> (небезпечно)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Сертифікат</translation>
+<translation id="7716147886133743102">Заблоковано адмініÑтратором</translation>
<translation id="7716424297397655342">Ðе вдаєтьÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ цей Ñайт із кешу</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Ðекерований клієнт</translation>
<translation id="7755287808199759310">ХтоÑÑŒ із батьків може розблокувати його</translation>
<translation id="7758069387465995638">Можливо, брандмауер або антивіруÑна програма заблокували з’єднаннÑ.</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32-розрÑдна верÑÑ–Ñ)</translation>
<translation id="7956713633345437162">Закладки Ð´Ð»Ñ Ð¼Ð¾Ð±Ñ–Ð»ÑŒÐ½Ð¸Ñ… приÑтроїв</translation>
<translation id="7961015016161918242">Ðіколи</translation>
-<translation id="7962083544045318153">Ідентифікатор аварійного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Завжди перекладати цю мовну пару: <ph name="ORIGINAL_LANGUAGE" /> – <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Ðе вказано</translation>
<translation id="800218591365569300">Щоб звільнити пам’ÑÑ‚ÑŒ, закрийте інші вкладки та програми.</translation>
<translation id="8012647001091218357">Ðе вдалоÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· вашими батьками. Повторіть Ñпробу.</translation>
<translation id="8025119109950072390">ЗловмиÑники на цьому Ñайті можуть обманом змуÑити Ð²Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ небезпечну дію, Ñк-от уÑтановити програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ повідомити оÑобиÑту інформацію (наприклад, паролі, номери телефонів або кредитних карток).</translation>
-<translation id="803030522067524905">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно виÑвила фішинг на Ñайті <ph name="SITE" />. Фішингові Ñайти видають Ñебе за інші Ñайти, щоб ошукати ваÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Мова цієї Ñторінки: <ph name="SOURCE_LANGUAGE" />. ПереклаÑти Ñ—Ñ— такою мовою: <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Запитувати (за умовчаннÑм)</translation>
<translation id="8041089156583427627">ÐадіÑлати відгук</translation>
+<translation id="8041940743680923270">ВикориÑтовувати глобальне Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° умовчаннÑм (Запитувати)</translation>
<translation id="8088680233425245692">Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ³Ð»Ñнути Ñтаттю.</translation>
<translation id="8089520772729574115">менше 1 Мб</translation>
<translation id="8091372947890762290">ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ñ‡Ñ–ÐºÑƒÑ” на Ñервері</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007">Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ <ph name="BEGIN_ABBR" />адреÑу DNS-Ñервера<ph name="END_ABBR" /> хоÑту <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Ваш комп’ютер перейшов у режим Ñну.</translation>
<translation id="8150722005171944719">Файл за адреÑою <ph name="URL" /> не читаєтьÑÑ. Можливо, його видалено, переміщено або доÑтуп заборонено дозволами файлу.</translation>
+<translation id="8184538546369750125">ВикориÑтовувати глобальне Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° умовчаннÑм (ДозволÑти)</translation>
+<translation id="8191494405820426728">Локальний ідентифікатор аварійного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Відмінити переміщеннÑ</translation>
<translation id="8201077131113104583">ÐедійÑна URL-адреÑа Ð´Ð»Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ð· ідентифікатором "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">ПідÑумок замовленнÑ</translation>
<translation id="8218327578424803826">Указане міÑцезнаходженнÑ:</translation>
<translation id="8225771182978767009">КориÑтувач, Ñкий налаштував комп’ютер, заблокував цей Ñайт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">ЗловмиÑники, Ñкі зараз перебувають на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />, можуть намагатиÑÑ Ð²Ñтановити на ваш комп’ютер небезпечні програми, що викрадають або видалÑÑŽÑ‚ÑŒ інформацію (Ñк-от фотографії, паролі, Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð¸ кредитні картки).</translation>
<translation id="8241707690549784388">Сторінка, Ñку ви шукаєте, викориÑтовувала інформацію, введену вами. ÐŸÐ¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð´Ð¾ такої Ñторінки може призвеÑти до Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¸Ñ… попередніх дій. Ви дійÑно бажаєте продовжити?</translation>
<translation id="8249320324621329438">ВоÑтаннє отримано:</translation>
<translation id="8253091569723639551">Потрібно вказати платіжну адреÑу</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">ЗвернітьÑÑ Ð´Ð¾ адмініÑтратора Ñвоєї мережі, Ñкщо ви не знаєте, що це означає.</translation>
<translation id="8293206222192510085">Додати закладку</translation>
<translation id="8294431847097064396">Джерело</translation>
+<translation id="8306404619377842860">Ðе вдаєтьÑÑ Ð²Ñтановити конфіденційне Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· доменом <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оÑкільки на приÑтрої налаштовано неправильні дату й Ñ‡Ð°Ñ (<ph name="DATE_AND_TIME" />). <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Переклад не виконано через проблему Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ мережі.</translation>
<translation id="8332188693563227489">Відмовлено в доÑтупі до хоÑту <ph name="HOST_NAME" /></translation>
<translation id="834457929814110454">Якщо ви розумієте ризики, пов’Ñзані з безпекою, можете <ph name="BEGIN_LINK" />перейти на цей Ñайт<ph name="END_LINK" /> до того, Ñк небезпечні програми буде видалено.</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">Щоб кориÑтуватиÑÑ ÐºÐ°Ñ€Ñ‚ÐºÐ°Ð¼Ð¸ у Ñвоєму обліковому запиÑÑ– Google, увійдіть у Chrome</translation>
<translation id="8488350697529856933">ЗаÑтоÑовуєтьÑÑ Ð´Ð¾:</translation>
<translation id="8498891568109133222">ХоÑÑ‚ <ph name="HOST_NAME" /> довго не відповідає.</translation>
-<translation id="852346902619691059">Ðе вдалоÑÑ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚Ð¸, що це Ñервер <ph name="DOMAIN" />. Операційна ÑиÑтема вашого приÑтрою вважає його Ñертифікат безпеки ненадійним. Імовірні причини: Ñервер налаштовано неправильно або хтоÑÑŒ намагаєтьÑÑ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð¸Ñ‚Ð¸ ваше з’єднаннÑ. <ph name="BEGIN_LEARN_MORE_LINK" />Докладніше<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Рік Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії</translation>
<translation id="8543181531796978784">Ви можете <ph name="BEGIN_ERROR_LINK" />повідомити про проблему з пошуком<ph name="END_ERROR_LINK" /> або <ph name="BEGIN_LINK" />перейти на цей незахищений Ñайт<ph name="END_LINK" /> (Ñкщо розумієте, наÑкільки це небезпечно).</translation>
<translation id="8553075262323480129">Помилка перекладу. Ðеможливо визначити мову Ñторінки.</translation>
-<translation id="8559762987265718583">Ðе вдаєтьÑÑ Ð²Ñтановити конфіденційне Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" />, оÑкільки на приÑтрої вÑтановлено неправильні дату й Ñ‡Ð°Ñ (<ph name="DATE_AND_TIME" />).</translation>
<translation id="8571890674111243710">ВиконуєтьÑÑ Ð¿ÐµÑ€ÐµÐºÐ»Ð°Ð´ Ñторінки такою мовою: <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Додати тел.номер
</translation>
@@ -821,6 +895,7 @@
<translation id="8738058698779197622">Щоб уÑтановити безпечне з’єднаннÑ, потрібно правильно вказати чаÑ, оÑкільки Ñертифікати, Ñкі веб-Ñайти викориÑтовують Ð´Ð»Ñ Ñамоідентифікації дійÑні лише протÑгом певного періоду чаÑу. Ð§Ð°Ñ Ð½Ð° вашому приÑтрої неправильний, тому Chromium не може перевірити Ñертифікати.</translation>
<translation id="8740359287975076522">&lt;abbr id="dnsDefinition"&gt;ÐдреÑу DNS&lt;/abbr&gt; хоÑту <ph name="HOST_NAME" /> не знайдено. ДіагноÑтика проблеми.</translation>
<translation id="8759274551635299824">Термін дії цієї картки минув</translation>
+<translation id="8761567432415473239">Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ переглÑду від Google нещодавно <ph name="BEGIN_LINK" />виÑвила шкідливі програми<ph name="END_LINK" /> на Ñайті <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Повторити видаленнÑ</translation>
<translation id="8800988563907321413">Тут відображатимутьÑÑ Ð¿Ñ€Ð¾Ð¿Ð¾Ð·Ð¸Ñ†Ñ–Ñ—</translation>
<translation id="8820817407110198400">Закладки</translation>
@@ -833,29 +908,30 @@
<translation id="8870413625673593573">Ðещодавно закриті</translation>
<translation id="8874824191258364635">Введіть дійÑний номер картки</translation>
<translation id="8876793034577346603">Помилка аналізу конфігурації мережі.</translation>
-<translation id="8877192140621905067">Щойно ви підтвердите дані картки, цей Ñайт отримає доÑтуп до них</translation>
<translation id="8889402386540077796">Тон</translation>
<translation id="8891727572606052622">ÐедійÑний режим прокÑÑ–-Ñервера.</translation>
<translation id="889901481107108152">Ðа жаль, цей екÑперимент не доÑтупний на вашій платформі.</translation>
<translation id="8903921497873541725">Збільшити маÑштаб</translation>
<translation id="8931333241327730545">Зберегти цю картку у вашому обліковому запиÑÑ– Google?</translation>
<translation id="8932102934695377596">Ваш годинник запізнюєтьÑÑ</translation>
-<translation id="8954894007019320973">(Продовж.)</translation>
<translation id="8971063699422889582">Термін дії Ñертифіката Ñервера завершивÑÑ.</translation>
<translation id="8986494364107987395">Ðвтоматично надÑилати ÑтатиÑтику викориÑÑ‚Ð°Ð½Ð½Ñ Ñ‚Ð° звіти про аварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ в Google</translation>
-<translation id="8987927404178983737">МіÑÑць</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Сайт міÑтить шкідливі програми</translation>
+<translation id="8997023839087525404">Сервер надав Ñертифікат без інформації про перевірку. Це обов’Ñзкові дані Ð´Ð»Ñ Ð´ÐµÑких Ñертифікатів. Вони підтверджують надійніÑÑ‚ÑŒ Ñертифіката й захищають від атак зловмиÑників.</translation>
<translation id="9001074447101275817">Ð”Ð»Ñ Ð¿Ñ€Ð¾ÐºÑÑ– <ph name="DOMAIN" /> потрібно ввеÑти Ñ–Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача та пароль.</translation>
+<translation id="9005998258318286617">Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ документ PDF.</translation>
<translation id="901974403500617787">Позначки, Ñкі заÑтоÑовуютьÑÑ Ð´Ð¾ вÑієї ÑиÑтеми, може вÑтановлювати лише влаÑник: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Потрібно вказати платіжну адреÑу картки</translation>
<translation id="9020542370529661692">Цю Ñторінку перекладено такою мовою: <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Помилка ÑиÑтеми безпеки</translation>
<translation id="9038649477754266430">КориÑтуйтеÑÑ Ñлужбою передбаченнÑ, щоб Ñторінки завантажувалиÑÑ ÑˆÐ²Ð¸Ð´ÑˆÐµ</translation>
<translation id="9039213469156557790">Окрім цього, Ñторінка міÑтить незахищені реÑурÑи. Інші оÑоби можуть переглÑдати Ñ—Ñ… під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…, а зловмиÑники можуть змінювати роботу Ñторінки.</translation>
-<translation id="9040185888511745258">ЗловмиÑники на Ñайті <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> можуть оманливим шлÑхом змуÑити Ð²Ð°Ñ ÑƒÑтановити на Ñвій приÑтрій програми, Ñкі погіршують переглÑд веб-Ñторінок (наприклад, змінюють вашу домашню Ñторінку або показують додаткову рекламу на Ñайтах, Ñкі ви відвідуєте).</translation>
+<translation id="9049981332609050619">Ви пробували зв’ÑзатиÑÑ Ð· доменом <ph name="DOMAIN" />, але Ñервер надав недійÑний Ñертифікат.</translation>
<translation id="9050666287014529139">Парольна фраза</translation>
<translation id="9065203028668620118">Редагувати</translation>
<translation id="9068849894565669697">Вибрати колір</translation>
+<translation id="9069693763241529744">Заблоковано розширеннÑм</translation>
<translation id="9076283476770535406">Ðа ньому може бути вміÑÑ‚ Ð´Ð»Ñ Ð´Ð¾Ñ€Ð¾Ñлих</translation>
<translation id="9078964945751709336">Потрібно більше інформації</translation>
<translation id="9103872766612412690">Веб-Ñайт <ph name="SITE" /> зазвичай викориÑтовує ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð·Ð°Ñ…Ð¸Ñту вашої інформації. Під Ñ‡Ð°Ñ Ñ†Ñ–Ñ”Ñ— Ñпроби Chromium під’єднатиÑÑ Ð´Ð¾ Ñторінки <ph name="SITE" /> з неї отримано незвичні й неправильні облікові дані. Це може ÑтатиÑÑ, коли зловмиÑник намагаєтьÑÑ Ð²Ð¸Ð´Ð°Ð²Ð°Ñ‚Ð¸ Ñебе за веб-Ñайт <ph name="SITE" /> або Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾ екраном входу Wi-Fi. Ваша Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð·Ð°Ð»Ð¸ÑˆÐ°Ñ”Ñ‚ÑŒÑÑ Ð·Ð°Ñ…Ð¸Ñ‰ÐµÐ½Ð¾ÑŽ, оÑкільки Chromium припинив Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ того, Ñк почавÑÑ Ð¾Ð±Ð¼Ñ–Ð½ будь-Ñкими даними.</translation>
@@ -864,16 +940,21 @@
<translation id="9148507642005240123">&amp;Відмінити редагуваннÑ</translation>
<translation id="9154194610265714752">Оновлено</translation>
<translation id="9157595877708044936">ÐалаштуваннÑ...</translation>
+<translation id="9169664750068251925">Завжди блокувати на цьому Ñайті</translation>
<translation id="9170848237812810038">&amp;СкаÑувати</translation>
<translation id="917450738466192189">Сертифікат Ñервера недійÑний.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}one{<ph name="SHIPPING_OPTION_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}many{<ph name="SHIPPING_OPTION_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> і ще <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
<translation id="9183425211371246419">Протокол, Ñкий викориÑтовує хоÑÑ‚ <ph name="HOST_NAME" />, не підтримуєтьÑÑ.</translation>
<translation id="9205078245616868884">Ваші дані зашифровано за допомогою парольної фрази. Введіть Ñ—Ñ—, щоб почати Ñинхронізацію.</translation>
<translation id="9207861905230894330">Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ Ñтаттю.</translation>
+<translation id="9219103736887031265">ЗображеннÑ</translation>
<translation id="933612690413056017">Ðемає Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Інтернетом</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ОЧИСТИТИ ФОРМУ</translation>
<translation id="939736085109172342">Ðова папка</translation>
<translation id="941721044073577244">Схоже, у Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” дозволу, щоб перейти на цей Ñайт</translation>
<translation id="969892804517981540">Розробка</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Ðемає}=1{1 запиÑ}one{# запиÑ}few{# запиÑи}many{# запиÑів}other{# запиÑу}}</translation>
<translation id="988159990683914416">КонÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_vi.xtb b/chromium/components/strings/components_strings_vi.xtb
index 81c4bed838f..2220e4fe80a 100644
--- a/chromium/components/strings/components_strings_vi.xtb
+++ b/chromium/components/strings/components_strings_vi.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">Xoay theo chiá»u kim đồng hồ</translation>
<translation id="1038842779957582377">tên không biết</translation>
<translation id="1050038467049342496">Äóng các ứng dụng khác</translation>
-<translation id="1053591932240354961">Bạn không thể truy cập <ph name="SITE" /> ngay bây giá» do trang web gá»­i thông tin đăng nhập đã mã hóa mà Google Chrome không thể xá»­ lý. Lá»—i mạng và các cuá»™c tấn công mạng thÆ°á»ng chỉ là tạm thá»i, do đó, trang này có thể sẽ hoạt Ä‘á»™ng lại sau. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1055184225775184556">&amp;Hoàn tác thêm</translation>
<translation id="10614374240317010">Không bao giỠđược lưu</translation>
<translation id="106701514854093668">Dấu trang máy tính</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">Bộ nhớ cache chính sách OK</translation>
<translation id="113188000913989374"><ph name="SITE" /> cho biết:</translation>
<translation id="1132774398110320017">Cài đặt tá»± Ä‘á»™ng Ä‘iá»n trên Chrome...</translation>
+<translation id="1150979032973867961">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được hệ Ä‘iá»u hành máy tính của bạn tin cậy. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
+<translation id="1151972924205500581">Mật khẩu bắt buộc</translation>
<translation id="1152921474424827756">Truy cập <ph name="BEGIN_LINK" />bản sao được lưu trong bộ nhớ cache<ph name="END_LINK" /> của <ph name="URL" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> đã bất ngỠđóng kết nối.</translation>
<translation id="1161325031994447685">Kết nối lại với Wi-Fi</translation>
+<translation id="1165039591588034296">Lá»—i</translation>
<translation id="1175364870820465910">&amp;In...</translation>
<translation id="1181037720776840403">Xóa</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />Tự động báo cáo<ph name="END_WHITEPAPER_LINK" /> chi tiết các sự cố bảo mật có thể xảy ra với Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">Thêm từ trang web này</translation>
<translation id="1206967143813997005">Chữ ký ban đầu không hợp lệ</translation>
<translation id="1209206284964581585">Ẩn ngay bây giá»</translation>
+<translation id="121201262018556460">Bạn đã cố truy cập vào <ph name="DOMAIN" /> nhưng máy chủ xuất trình chứng chỉ chứa khóa yếu. Kẻ tấn công có thể đã phá khóa cá nhân và máy chủ đó có thể không phải là máy chủ bạn mong đợi (bạn có thể đang giao tiếp với một kẻ tấn công).</translation>
<translation id="1219129156119358924">Bảo mật hệ thống</translation>
<translation id="1227224963052638717">Chính sách không xác định.</translation>
<translation id="1227633850867390598">Ẩn giá trị</translation>
<translation id="1228893227497259893">Số nhận dạng tổ chức không đúng</translation>
<translation id="1232569758102978740">Không tên</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (được đồng bộ hóa)</translation>
<translation id="1263231323834454256">Danh sách Ä‘á»c</translation>
<translation id="1264126396475825575">Báo cáo sự cố được ghi lại vào <ph name="CRASH_TIME" /> (nhưng chưa tải lên hoặc đã bị bỠqua)</translation>
+<translation id="1281526147609854549">Do <ph name="ISSUER" /> phát hành</translation>
+<translation id="1283919782143846010">Äã chặn ná»™i dung nguy hiểm</translation>
<translation id="1285320974508926690">Không bao giỠdịch trang web này</translation>
<translation id="129553762522093515">Các tab đã đóng gần đây</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Thử xóa các cookie của bạn<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">Hoạt động của bạn <ph name="BEGIN_EMPHASIS" />có thể vẫn hiển thị<ph name="END_EMPHASIS" /> với:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Trang web bạn truy cập
+ <ph name="LIST_ITEM" />Chủ lao Ä‘á»™ng hoặc trÆ°á»ng há»c của bạn
+ <ph name="LIST_ITEM" />Nhà cung cấp dịch vụ Internet của bạn
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">Tên miá»n đăng ký:</translation>
<translation id="1340482604681802745">Äịa chỉ nhận hàng</translation>
<translation id="1344211575059133124">Có vẻ nhÆ° bạn cần có quyá»n truy cập trang web này</translation>
<translation id="1344588688991793829">Cài đặt tá»± Ä‘á»™ng Ä‘iá»n trong Chromium...</translation>
+<translation id="1348198688976932919">Trang web bạn sắp truy cập chứa ứng dụng nguy hiểm</translation>
<translation id="1374468813861204354">đỠxuất</translation>
<translation id="1375198122581997741">Giới thiệu Phiên bản</translation>
<translation id="1377321085342047638">Số thẻ</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> không gửi bất kỳ dữ liệu nào.</translation>
<translation id="1407135791313364759">Mở tất cả</translation>
<translation id="1413809658975081374">Lỗi bảo mật</translation>
+<translation id="14171126816530869">Nhận dạng <ph name="ORGANIZATION" /> tại <ph name="LOCALITY" /> đã được xác minh bởi <ph name="ISSUER" />.</translation>
<translation id="1426410128494586442">Có</translation>
<translation id="1430915738399379752">In</translation>
-<translation id="1442912890475371290">Äã chặn ná»— lá»±c <ph name="BEGIN_LINK" /> truy cập trang trên <ph name="DOMAIN" /><ph name="END_LINK" />.</translation>
-<translation id="1491663344921578213">Bạn không thể truy cập <ph name="SITE" /> ngay bây giá» do trang web sá»­ dụng tính năng ghim chứng chỉ. Lá»—i mạng và các cuá»™c tấn công mạng thÆ°á»ng chỉ là tạm thá»i, do đó, trang này có thể sẽ hoạt Ä‘á»™ng lại sau. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> phương thức thanh toán khác}other{<ph name="PAYMENT_METHOD_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> phương thức thanh toán khác}}</translation>
<translation id="1506687042165942984">Hiển thị bản sao đã lÆ°u (nghÄ©a là đã lá»—i thá»i) của trang này.</translation>
<translation id="1517433312004943670">Phải có số điện thoại</translation>
<translation id="1519264250979466059">Ngày tạo</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">Bạn phải bật JavaScript để sử dụng tính năng này.</translation>
<translation id="1555130319947370107">Xanh lam</translation>
<translation id="1559528461873125649">Không có tệp hoặc thư mục nào như vậy</translation>
-<translation id="1559572115229829303">&lt;p&gt;Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giỠ(<ph name="DATE_AND_TIME" />) trên thiết bị của bạn không chính xác.&lt;/p&gt;
-
- &lt;p&gt;Hãy Ä‘iá»u chỉnh ngày và giá» từ phần &lt;strong&gt;Chung&lt;/strong&gt; của ứng dụng &lt;strong&gt;Cài đặt&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1583429793053364125">Äã xảy ra lá»—i khi hiển thị trang web này.</translation>
<translation id="1592005682883173041">Quyá»n truy cập dữ liệu cục bá»™</translation>
+<translation id="1594030484168838125">Chá»n</translation>
<translation id="161042844686301425">Lục lam</translation>
+<translation id="1620510694547887537">Máy ảnh</translation>
<translation id="1629803312968146339">Bạn có muốn Chrome lưu thẻ này không?</translation>
<translation id="1639239467298939599">Äang tải</translation>
<translation id="1640180200866533862">Chính sách ngÆ°á»i dùng</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">Cấu hình mạng không hợp lệ và không thể nhập được.</translation>
<translation id="1644574205037202324">Lịch sử</translation>
<translation id="1645368109819982629">Giao thức không được hỗ trợ</translation>
+<translation id="1655462015569774233">{1,plural, =1{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này đã hết hạn hôm qua. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. Äồng hồ máy tính của bạn hiện được đặt là <ph name="CURRENT_DATE" />. Ngày này có đúng không? Nếu không đúng, bạn phải sá»­a lại đồng hồ của hệ thống rồi làm má»›i trang này.}other{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này đã hết hạn cách đây # ngày. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. Äồng hồ máy tính của bạn hiện được đặt là <ph name="CURRENT_DATE" />. Ngày này có đúng không? Nếu không đúng, bạn phải sá»­a lại đồng hồ của hệ thống rồi làm má»›i trang này.}}</translation>
<translation id="1656489000284462475">Nhận hàng</translation>
<translation id="1663943134801823270">Thẻ và địa chỉ từ Chrome. Bạn có thể quản lý thẻ và địa chỉ trong <ph name="BEGIN_LINK" />Cài đặt<ph name="END_LINK" />.</translation>
<translation id="1676269943528358898"><ph name="SITE" /> thÆ°á»ng sá»­ dụng mã hóa để bảo vệ thông tin của bạn. Khi Google Chrome tìm cách kết nối vá»›i <ph name="SITE" /> tại thá»i Ä‘iểm này, trang web đã gá»­i lại thông tin đăng nhập không chính xác và bất thÆ°á»ng. Äiá»u này có thể xảy ra khi kẻ tấn công Ä‘ang cố gắng giả mạo là <ph name="SITE" /> hoặc màn hình đăng nhập Wi-Fi đã làm gián Ä‘oạn kết nối. Thông tin của bạn vẫn an toàn do Google Chrome đã ngừng kết nối trÆ°á»›c khi bất kỳ dữ liệu nào được trao đổi.</translation>
-<translation id="168328519870909584">Những kẻ tấn công hiện đang truy cập <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cố cài đặt các ứng dụng nguy hiểm trên thiết bị của bạn để lấy cắp hoặc xóa thông tin của bạn (ví dụ: ảnh, mật khẩu, thư và thẻ tín dụng).</translation>
<translation id="168841957122794586">Chứng chỉ máy chủ chứa khóa mật mã yếu.</translation>
+<translation id="1706954506755087368">{1,plural, =1{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này được Ä‘á» từ ngày mai. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.}other{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này được Ä‘á» # ngày trong tÆ°Æ¡ng lai. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.}}</translation>
<translation id="1710259589646384581">OS</translation>
<translation id="1721312023322545264">Bạn cần được <ph name="NAME" /> cấp quyá»n để truy cập vào trang web này</translation>
<translation id="1721424275792716183">TrÆ°á»ng * là bắt buá»™c</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">Tải trang xuống sau</translation>
<translation id="17513872634828108">Tab đang mở</translation>
<translation id="1753706481035618306">Số trang</translation>
+<translation id="1763864636252898013">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được hệ Ä‘iá»u hành thiết bị của bạn tin cậy. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />Thử chạy Chẩn đoán mạng của Windows<ph name="END_LINK" />.</translation>
<translation id="1783075131180517613">Vui lòng cập nhật cụm mật khẩu đồng bộ hóa của bạn.</translation>
<translation id="1787142507584202372">Tab đang mở của bạn xuất hiện ở đây</translation>
+<translation id="1789575671122666129">Cửa sổ bật lên</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">Tên chủ thẻ</translation>
-<translation id="1803678881841855883">Gần đây, tính năng Duyệt web an toàn của Google <ph name="BEGIN_LINK" />đã phát hiện thấy phần má»m Ä‘á»™c hại<ph name="END_LINK" /> trên <ph name="SITE" />. Các trang web bình thÆ°á»ng vẫn an toàn đôi khi bị lây nhiá»…m phần má»m Ä‘á»™c hại. Ná»™i dung Ä‘á»™c hại đến từ <ph name="SUBRESOURCE_HOST" />, má»™t đối tượng phân phối phần má»m Ä‘á»™c hại đã biết. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="1806541873155184440">Ngày thêm: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">Yêu cầu hoặc tham số yêu cầu không hợp lệ</translation>
<translation id="1826516787628120939">Äang kiểm tra</translation>
<translation id="1834321415901700177">Trang web này có chứa các chương trình độc hại</translation>
+<translation id="1840414022444569775">Số thẻ này đã được sử dụng</translation>
<translation id="1842969606798536927">Thanh toán</translation>
<translation id="1871208020102129563">Proxy được đặt để sử dụng máy chủ proxy cố định chứ không phải URL tập lệnh .pac.</translation>
<translation id="1871284979644508959">TrÆ°á»ng bắt buá»™c</translation>
<translation id="187918866476621466">Mở trang khởi động</translation>
<translation id="1883255238294161206">Thu gá»n danh sách</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> địa chỉ giao hàng khác}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> địa chỉ giao hàng khác}}</translation>
<translation id="1898423065542865115">Lá»c</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{Không có}=1{1 trang web}other{# trang web}}</translation>
<translation id="194030505837763158">Truy cập <ph name="LINK" /></translation>
<translation id="1962204205936693436">Dấu trang của <ph name="DOMAIN" /></translation>
<translation id="1973335181906896915">Lỗi nối tiếp hóa</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">BỠqua vì đã bị <ph name="POLICY_NAME" /> ghi đè.</translation>
<translation id="2138201775715568214">Äang tìm kiếm các trang Web trong cuá»™c sống lân cận</translation>
<translation id="213826338245044447">Dấu trang di động</translation>
-<translation id="2148716181193084225">Hôm nay</translation>
+<translation id="2147827593068025794">Äồng bá»™ hóa dÆ°á»›i ná»n</translation>
<translation id="2154054054215849342">Tính năng đồng bá»™ hóa không khả dụng cho miá»n của bạn</translation>
<translation id="2154484045852737596">Chỉnh sửa thẻ</translation>
<translation id="2166049586286450108">Quyá»n truy cập quản trị đầy đủ</translation>
<translation id="2166378884831602661">Trang web này không thể cung cấp kết nối an toàn</translation>
<translation id="2181821976797666341">Chính sách</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 địa chỉ}other{# địa chỉ}}</translation>
+<translation id="2187317261103489799">Phát hiện (mặc định)</translation>
<translation id="2202020181578195191">Nhập năm hết hạn hợp lệ</translation>
<translation id="2212735316055980242">Không tìm thấy chính sách</translation>
<translation id="2213606439339815911">Äang tìm nạp các mục nhập...</translation>
+<translation id="2218879909401188352">Những kẻ tấn công hiện ở trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cài đặt ứng dụng nguy hiểm làm há»ng thiết bị của bạn, thêm các khoản phí ẩn vào hóa Ä‘Æ¡n di Ä‘á»™ng hoặc lấy cắp thông tin cá nhân của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">Sửa kết nối bằng <ph name="BEGIN_LINK" />ứng dụng chẩn đoán<ph name="END_LINK" /></translation>
<translation id="2239100178324503013">Gá»­i bây giá»</translation>
<translation id="225207911366869382">Giá trị này không được dùng cho chính sách này nữa.</translation>
<translation id="2262243747453050782">Lá»—i HTTP</translation>
+<translation id="2270484714375784793">Số điện thoại</translation>
<translation id="2282872951544483773">Thử nghiệm không khả dụng</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> mục}other{<ph name="ITEM_COUNT" /> mục}}</translation>
<translation id="2292556288342944218">Quyá»n truy cập Internet của bạn bị chặn</translation>
<translation id="230155334948463882">Thẻ mới?</translation>
-<translation id="2305919008529760154">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này có thể đã được cấp má»™t cách gian lận. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> yêu cầu tên ngÆ°á»i dùng và mật khẩu.</translation>
-<translation id="2318774815570432836">Bạn không thể truy cập <ph name="SITE" /> ngay bây giá» vì trang web sá»­ dụng HSTS. Lá»—i mạng và các cuá»™c tấn công mạng thÆ°á»ng chỉ là tạm thá»i, do đó, trang này có thể sẽ hoạt Ä‘á»™ng lại sau. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2337852623177822836">Cài đặt do quản trị viên kiểm soát</translation>
<translation id="2354001756790975382">Dấu trang khác</translation>
+<translation id="2354430244986887761">Gần đây, Duyệt web an toàn của Google <ph name="BEGIN_LINK" />đã tìm thấy các ứng dụng có hại<ph name="END_LINK" /> trên <ph name="SITE" />.</translation>
<translation id="2355395290879513365">Kẻ tấn công có thể thấy những hình ảnh mà bạn đang xem trên trang web này và lừa bạn bằng cách sửa đổi những hình ảnh đó.</translation>
+<translation id="2356070529366658676">Yêu cầu</translation>
+<translation id="2359629602545592467">Nhiá»u</translation>
<translation id="2359808026110333948">Tiếp tục</translation>
<translation id="2365563543831475020">Báo cáo sự cố được ghi lại vào <ph name="CRASH_TIME" /> chưa được tải lên</translation>
<translation id="2367567093518048410">Mức độ</translation>
-<translation id="2371153335857947666">{1,plural, =1{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này đã hết hạn hôm qua. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. Äồng hồ của máy tính hiện được đặt là <ph name="CURRENT_DATE" />. Ngày này có đúng không? Nếu không đúng, bạn phải sá»­a lại đồng hồ của hệ thống rồi làm má»›i trang này. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.}other{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này đã hết hạn cách đây # ngày. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. Äồng hồ của máy tính hiện được đặt là <ph name="CURRENT_DATE" />. Ngày này có đúng không? Nếu không đúng, bạn phải sá»­a lại đồng hồ của hệ thống rồi làm má»›i trang này. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.}}</translation>
<translation id="237718015863234333">Không có giao diện ngÆ°á»i dùng thay thế nào</translation>
<translation id="2384307209577226199">Äặt mặc định trong môi trÆ°á»ng doanh nghiệp</translation>
<translation id="2386255080630008482">Chứng chỉ của máy chủ đã bị thu hồi.</translation>
<translation id="2392959068659972793">Hiển thị chính sách không có giá trị được đặt</translation>
<translation id="239429038616798445">Phương thức giao hàng này không có sẵn. Hãy thử một phương thức khác.</translation>
<translation id="2396249848217231973">&amp;Hoàn tác xóa</translation>
-<translation id="2460160116472764928">Gần đây, tính năng Duyệt web an toàn của Google <ph name="BEGIN_LINK" />đã phát hiện thấy phần má»m Ä‘á»™c hại<ph name="END_LINK" /> trên <ph name="SITE" />. Các trang web bình thÆ°á»ng vẫn an toàn đôi khi bị lây nhiá»…m phần má»m Ä‘á»™c hại. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="2413528052993050574">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này có thể đã bị thu hồi. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="2463739503403862330">Äiá»n</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Chạy Chẩn đoán mạng<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">URL tìm kiếm hợp lệ.</translation>
+<translation id="2482878487686419369">Thông báo</translation>
<translation id="2491120439723279231">Chứng chỉ của máy chủ có lỗi.</translation>
<translation id="2495083838625180221">Trình phân tích cú pháp JSON</translation>
<translation id="2495093607237746763">Nếu được chá»n, Chromium sẽ lÆ°u trữ bản sao thẻ của bạn trên thiết bị này để Ä‘iá»n biểu mẫu nhanh hÆ¡n.</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">Quay lại</translation>
<translation id="2515629240566999685">Kiểm tra tín hiệu trong khu vực của bạn</translation>
<translation id="2516305470678292029">Giao diện ngÆ°á»i dùng thay thế</translation>
+<translation id="2539524384386349900">Phát hiện</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> đã gửi phản hồi không hợp lệ.</translation>
-<translation id="2552545117464357659">Mới hơn</translation>
<translation id="2556876185419854533">&amp;Hoàn tác chỉnh sửa</translation>
<translation id="2587730715158995865">Từ <ph name="ARTICLE_PUBLISHER" />. Äá»c tin bài này và <ph name="OTHER_ARTICLE_COUNT" /> tin bài khác.</translation>
<translation id="2587841377698384444">ID API thư mục:</translation>
<translation id="2597378329261239068">Tài liệu này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu.</translation>
<translation id="2609632851001447353">Các biến thể</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{Không có}=1{1 ứng dụng ($1)}=2{2 ứng dụng ($1, $2)}other{# ứng dụng ($1, $2, $3)}}</translation>
<translation id="2625385379895617796">Äồng hồ của bạn chạy nhanh</translation>
<translation id="2639739919103226564">Trạng thái:</translation>
+<translation id="2649204054376361687"><ph name="CITY" />, <ph name="COUNTRY" /></translation>
<translation id="2650446666397867134">Truy cập vào tệp bị từ chối</translation>
<translation id="2653659639078652383">Gá»­i</translation>
<translation id="2666117266261740852">Äóng các tab hoặc ứng dụng khác</translation>
+<translation id="2670429602441959756">Trang này có các tính năng chÆ°a được há»— trợ ở chế Ä‘á»™ VR. Äang thoát...</translation>
<translation id="2674170444375937751">Bạn có chắc chắn muốn xóa những trang này khá»i lịch sá»­ duyệt web của mình không?</translation>
<translation id="2677748264148917807">Rá»i khá»i</translation>
-<translation id="269990154133806163">Máy chủ đã xuất trình chứng chỉ không được tiết lá»™ công khai theo chính sách Tính minh bạch của chứng chỉ. Äây là yêu cầu đối vá»›i má»™t số chứng chỉ, để đảm bảo chúng đáng tin cậy và giúp chống lại những kẻ tấn công. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2702801445560668637">Danh sách Ä‘á»c</translation>
<translation id="2704283930420550640">Giá trị không khớp với định dạng.</translation>
<translation id="2704951214193499422">Chromium không thể xác nhận thẻ của bạn tại thá»i Ä‘iểm này. Vui lòng thá»­ lại sau.</translation>
<translation id="2705137772291741111">Không thể Ä‘á»c được bản sao đã lÆ°u (đã lÆ°u vào bá»™ nhá»› cache) của trang web này.</translation>
<translation id="2709516037105925701">TÆ°Ì£ động Ä‘iá»n</translation>
-<translation id="2712118517637785082">Bạn đã cố gắng truy cập <ph name="DOMAIN" /> nhÆ°ng chứng chỉ mà máy chủ xuất trình đã bị nhà phát hành thu hồi. Äiá»u này có nghÄ©a là thông tin đăng nhập bảo mật mà máy chủ xuất trình hoàn toàn không đáng tin cậy. Bạn có thể Ä‘ang kết nối vá»›i kẻ tấn công. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="2712173769900027643">Xin phép</translation>
<translation id="2713444072780614174">Trắng</translation>
<translation id="2720342946869265578">Lân cận</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">Thiếu hồ sơ thiết bị</translation>
<translation id="2784949926578158345">Kết nối đã được đặt lại.</translation>
<translation id="2794233252405721443">Trang web đã bị chặn</translation>
+<translation id="2799020568854403057">Trang web bạn sắp truy cập chứa ứng dụng có hại</translation>
+<translation id="2803306138276472711">Duyệt web an toàn của Google gần đây <ph name="BEGIN_LINK" />đã phát hiện phần má»m Ä‘á»™c hại<ph name="END_LINK" /> trên <ph name="SITE" />. Các trang web thÆ°á»ng được coi là an toàn đôi khi vẫn bị nhiá»…m phần má»m Ä‘á»™c hại.</translation>
<translation id="2824775600643448204">Thanh địa chỉ và tìm kiếm</translation>
<translation id="2826760142808435982">Kết nối được mã hóa và xác thá»±c bằng <ph name="CIPHER" /> đồng thá»i sá»­ dụng <ph name="KX" /> làm cÆ¡ chế trao đổi chính.</translation>
<translation id="2835170189407361413">Xóa biểu mẫu</translation>
+<translation id="2856444702002559011">Những kẻ tấn công có thể đang cố gắng đánh cắp thông tin của bạn từ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (ví dụ: mật khẩu, thư hoặc thẻ tín dụng). <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">Không tải lại</translation>
<translation id="2900469785430194048">Google Chrome đã hết bộ nhớ khi cố gắng hiển thị trang web này.</translation>
<translation id="2909946352844186028">Äã phát hiện thấy thay đổi mạng.</translation>
<translation id="2916038427272391327">Äóng các chÆ°Æ¡ng trình khác</translation>
<translation id="2922350208395188000">Không thể kiểm tra chứng chỉ của máy chủ.</translation>
<translation id="2928905813689894207">Ãịa chỉ thanh toán</translation>
+<translation id="2941952326391522266">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này là từ <ph name="DOMAIN2" />. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="2948083400971632585">Bạn có thể tắt má»i proxy được định cấu hình cho kết nối từ trang cài đặt.</translation>
<translation id="2955913368246107853">Äóng thanh tìm</translation>
<translation id="2958431318199492670">Cấu hình mạng không tuân thủ tiêu chuẩn ONC. Các bộ phận của cấu hình có thể không được nhập.</translation>
-<translation id="29611076221683977">Những kẻ tấn công hiện đang truy cập <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cố gắng cài đặt các chương trình nguy hiểm trên máy Mac. Các chương trình này sẽ đánh cắp hoặc xóa thông tin của bạn (ví dụ: ảnh, mật khẩu, thư và thẻ tín dụng).</translation>
<translation id="2966678944701946121">Hết hạn: <ph name="EXPIRATION_DATE_ABBR" />, ngày thêm: <ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">Äể thiết lập kết nối an toàn, bạn cần đặt thá»i gian đúng cho đồng hồ. Nguyên nhân là do chứng chỉ mà các trang web dùng để tá»± nhận dạng chỉ có hiệu lá»±c trong khoảng thá»i gian cụ thể. Vì đồng hồ trên thiết bị của bạn không đúng nên Chrome không thể xác minh các chứng chỉ này.</translation>
<translation id="2972581237482394796">&amp;Làm lại</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">Nhập địa chỉ hợp lệ</translation>
<translation id="2986368408720340940">Phương thức nhận hàng này không có sẵn. Hãy thử một phương thức khác.</translation>
<translation id="2991174974383378012">Chia sẻ với trang web</translation>
+<translation id="2991571918955627853">Bạn không thể truy cập vào <ph name="SITE" /> ngay bây giá» vì trang web sá»­ dụng HSTS. Lá»—i mạng và các cuá»™c tấn công mạng thÆ°á»ng chỉ là tạm thá»i nên trang này có thể sẽ hoạt Ä‘á»™ng lại sau.</translation>
<translation id="3005723025932146533">Hiển thị bản sao đã lưu</translation>
<translation id="3008447029300691911">Nhập CVC cho <ph name="CREDIT_CARD" />. Sau khi bạn xác nhận, chi tiết thẻ của bạn sẽ được chia sẻ với trang web này.</translation>
<translation id="3010559122411665027">Mục nhập danh sách "<ph name="ENTRY_INDEX" />": <ph name="ERROR" /></translation>
+<translation id="301521992641321250">Tự động bị chặn</translation>
<translation id="3024663005179499861">Loại chính sách sai</translation>
<translation id="3032412215588512954">Bạn có muốn tải lại trang web này không?</translation>
<translation id="3037605927509011580">Ôi, há»ng! </translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{ít nhất 1 mục trên các thiết bị đã đồng bá»™ hóa}=1{1 mục (và nhiá»u mục khác trên các thiết bị đã đồng bá»™ hóa)}other{# mục (và nhiá»u mục khác trên các thiết bị đã đồng bá»™ hóa)}}</translation>
<translation id="3041612393474885105">Thông tin Chứng chỉ</translation>
<translation id="3063697135517575841">Chrome không thể xác nhận thẻ của bạn tại thá»i Ä‘iểm này. Vui lòng thá»­ lại sau.</translation>
<translation id="3064966200440839136">Rá»i khá»i chế Ä‘á»™ ẩn danh để thanh toán qua má»™t ứng dụng bên ngoài. Tiếp tục?</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{Không có}=1{1 mật khẩu}other{# mật khẩu}}</translation>
<translation id="3093245981617870298">Bạn đang ngoại tuyến.</translation>
<translation id="3105172416063519923">ID phần tử:</translation>
<translation id="3109728660330352905">Bạn không có quyá»n xem trang này.</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />Thử chạy Chẩn đoán kết nối<ph name="END_LINK" />.</translation>
<translation id="3145945101586104090">Không thể giải mã phản hồi</translation>
<translation id="3150653042067488994">Lá»—i máy chủ tạm thá»i</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">Các trang bạn xem trong tab ẩn danh sẽ không bị lÆ°u lại trong lịch sá»­ của trình duyệt, kho cookie hoặc lịch sá»­ tìm kiếm sau khi bạn đóng tất cả các tab ẩn danh của mình. Má»i tệp bạn tải xuống hoặc dấu trang mà bạn tạo sẽ được giữ nguyên.</translation>
<translation id="3169472444629675720">Khám phá</translation>
<translation id="3174168572213147020">Äảo</translation>
+<translation id="317583078218509884">Cài đặt giấy phép trang web mới sẽ có hiệu lực sau khi tải lại trang.</translation>
<translation id="3176929007561373547">Kiểm tra cài đặt proxy của bạn hoặc liên hệ với quản trị viên mạng để
đảm bảo rằng máy chủ proxy đang hoạt động. Nếu bạn cho rằng mình không cần
sử dụng máy chủ proxy:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">Mở trang ở chế độ ẩn danh</translation>
-<translation id="3202578601642193415">Mới nhất</translation>
+<translation id="320323717674993345">Hủy thanh toán</translation>
<translation id="3207960819495026254">Äã được đánh dấu trang</translation>
+<translation id="3225919329040284222">Máy chủ Ä‘Æ°a ra chứng chỉ không khá»›p vá»›i kỳ vá»ng được tích hợp sẵn. Các kỳ vá»ng này có trong má»™t số trang web nhất định, có tính bảo mật cao vá»›i mục đích bảo vệ bạn.</translation>
<translation id="3226128629678568754">Nhấn nút tải lại để gửi lại các dữ liệu cần thiết để tải trang.</translation>
+<translation id="3227137524299004712">Micrô</translation>
<translation id="3228969707346345236">Dịch thất bại vì trang đã bằng <ph name="LANGUAGE" />.</translation>
<translation id="323107829343500871">Nhập CVC cho <ph name="CREDIT_CARD" /></translation>
+<translation id="3234666976984236645">Luôn luôn phát hiện ná»™i dung quan trá»ng trên trang web này</translation>
<translation id="3254409185687681395">Äánh dấu trang này</translation>
<translation id="3270847123878663523">&amp;Hoàn tác sắp xếp lại</translation>
<translation id="3282497668470633863">Thêm tên trên thẻ</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">cài đặt</translation>
<translation id="3345135638360864351">Không thể gửi yêu cầu truy cập trang web này của bạn tới <ph name="NAME" />. Vui lòng thử lại.</translation>
<translation id="3355823806454867987">Thay đổi cài đặt proxy...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />sẽ không lưu<ph name="END_EMPHASIS" /> thông tin sau đây:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />Lịch sử duyệt web của bạn
+ <ph name="LIST_ITEM" />Cookie và dữ liệu trang web
+ <ph name="LIST_ITEM" />Thông tin đã nhập trong biểu mẫu
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">Lỗi đồng hồ</translation>
-<translation id="337311366426640088"><ph name="ITEM_COUNT" /> mục khác...</translation>
<translation id="337363190475750230">Äã hủy cấp phép</translation>
<translation id="3377188786107721145">Lỗi phân tích cú pháp chính sách</translation>
<translation id="3380365263193509176">Lỗi không xác định</translation>
<translation id="3380864720620200369">ID ứng dụng khách:</translation>
<translation id="3391030046425686457">Äịa chỉ giao hàng</translation>
<translation id="3395827396354264108">Phương thức nhận hàng</translation>
-<translation id="340013220407300675">Có thể những kẻ tấn công đang cố đánh cắp thông tin của bạn từ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (ví dụ: mật khẩu, tin nhắn hoặc thẻ tín dụng).</translation>
<translation id="3422248202833853650">Thử thoát các chương trình khác để giải phóng bộ nhớ.</translation>
<translation id="3422472998109090673">Hiện không thể truy cập <ph name="HOST_NAME" />.</translation>
+<translation id="3427092606871434483">Cho phép (mặc định)</translation>
<translation id="3427342743765426898">&amp;Làm lại chỉnh sửa</translation>
<translation id="3431636764301398940">Lưu thẻ này vào thiết bị này</translation>
<translation id="3435896845095436175">Bật</translation>
<translation id="3447661539832366887">Chủ sở hữu của thiết bị này đã tắt trò chơi khủng long.</translation>
-<translation id="3450660100078934250">MasterCard</translation>
<translation id="3452404311384756672">Khoảng thá»i gian tìm nạp:</translation>
<translation id="3462200631372590220">Ẩn chi tiêÌt</translation>
<translation id="3467763166455606212">Yêu cầu tên chủ thẻ</translation>
<translation id="3478058380795961209">Tháng hết hạn</translation>
<translation id="3479539252931486093">Trang web này có như bạn mong đợi không? Hãy <ph name="BEGIN_LINK" />cho chúng tôi biết<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">Không phải bây giá»</translation>
-<translation id="348000606199325318">ID sự cố <ph name="CRASH_LOCAL_ID" /> (ID máy chủ: <ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">Chúng tôi không thể liên lạc vá»›i cha mẹ của bạn vào thá»i Ä‘iểm này. Vui lòng thá»­ lại.</translation>
<translation id="3528171143076753409">Chứng chỉ của máy chủ không đáng tin cậy.</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{Ãt nhất 1 mục trên các thiết bị đã đồng bá»™ hóa}=1{1 mục (và nhiá»u mục khác trên các thiết bị đã đồng bá»™ hóa)}other{# mục (và nhiá»u mục khác trên các thiết bị đã đồng bá»™ hóa)}}</translation>
<translation id="3539171420378717834">Giữ bản sao thẻ này trên thiết bị này</translation>
<translation id="3542684924769048008">Sử dụng mật khẩu cho:</translation>
+<translation id="3545341443414427877">Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giỠ(<ph name="DATE_AND_TIME" />) trên máy tính của bạn không đúng. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">Mã hóa tất cả dữ liệu đã đồng bộ hóa bằng cụm mật khẩu đồng bộ hóa của riêng bạn</translation>
-<translation id="3549761410225185768"><ph name="NUM_TABS_MORE" /> tab nữa...</translation>
-<translation id="3555561725129903880">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này là từ <ph name="DOMAIN2" />. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="3556433843310711081">NgÆ°á»i quản lý của bạn có thể bá» chặn trang web cho bạn</translation>
<translation id="3566021033012934673">Kết nối của bạn không phải là kết nối riêng tư</translation>
+<translation id="3569145463236695319">&lt;p&gt;Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giỠ(<ph name="DATE_AND_TIME" />) trên thiết bị của bạn không đúng.&lt;/p&gt;
+
+ &lt;p&gt;Hãy Ä‘iá»u chỉnh ngày và giá» từ phần &lt;strong&gt;Chung&lt;/strong&gt; của ứng dụng &lt;strong&gt;Cài đặt&lt;/strong&gt;.&lt;/p&gt; <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="CITY" />, <ph name="STATE" /> <ph name="COUNTRY" /></translation>
<translation id="3582930987043644930">Thêm tên</translation>
<translation id="3583757800736429874">&amp;Làm lại di chuyển</translation>
<translation id="3586931643579894722">Ẩn chi tiết</translation>
-<translation id="3587482841069643663">Tất cả</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3615877443314183785">Nhập ngày hết hạn hợp lệ</translation>
<translation id="36224234498066874">Xóa Dữ liệu Duyệt web...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">Thông tin chứng chỉ</translation>
<translation id="3690164694835360974">Äăng nhập không an toàn</translation>
<translation id="3693415264595406141">Mật khẩu:</translation>
-<translation id="3696411085566228381">không có</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Äang tải...</translation>
<translation id="3712624925041724820">Giấy phép không đủ</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Kiểm tra proxy, tÆ°á»ng lá»­a và cấu hình DNS<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">Nếu bạn hiểu các rủi ro bảo mật, bạn có thể <ph name="BEGIN_LINK" />truy cập trang web không an toàn này<ph name="END_LINK" /> trước khi các chương trình nguy hiểm bị xóa.</translation>
<translation id="3739623965217189342">Liên kết đã sao chép</translation>
+<translation id="3744899669254331632">Bạn không thể truy cập <ph name="SITE" /> ngay bây giá» vì trang web này đã gá»­i thông tin đăng nhập há»—n Ä‘á»™n mà Chromium không thể xá»­ lý. Lá»—i mạng và các cuá»™c tấn công thÆ°á»ng chỉ diá»…n ra tạm thá»i nên trang này có thể sẽ hoạt Ä‘á»™ng sau.</translation>
+<translation id="3748148204939282805">Những kẻ tấn công trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể đánh lừa bạn làm việc gì đó nguy hiểm nhÆ° cài đặt phần má»m hoặc tiết lá»™ thông tin cá nhân (ví dụ: mật khẩu, số Ä‘iện thoại hoặc thẻ tín dụng). <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">Không thể dịch do lỗi máy chủ.</translation>
<translation id="3759461132968374835">Bạn không nhận được báo cáo sự cố nào gần đây. Sự cố xảy ra khi báo cáo sự cố đã bị tắt sẽ không xuất hiện ở đây.</translation>
+<translation id="3778403066972421603">Bạn có muốn lưu thẻ này vào Tài khoản Google của bạn và trên thiết bị này không?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Ngày hết hạn <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">Nếu bạn sử dụng máy chủ proxy...</translation>
<translation id="3828924085048779000">Không cho phép cụm mật khẩu trống.</translation>
-<translation id="3845539888601087042">Hiển thị lịch sử từ các thiết bị bạn đã đăng nhập. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" />.</translation>
<translation id="385051799172605136">Quay lại</translation>
<translation id="3858027520442213535">Cập nhật ngày và giá»</translation>
<translation id="3884278016824448484">Số nhận dạng thiết bị xung đột</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">Yêu cầu truy cập trang web này của bạn đã được gửi tới <ph name="NAME" /></translation>
<translation id="3890664840433101773">Thêm email</translation>
<translation id="3901925938762663762">Thẻ đã hết hạn</translation>
-<translation id="3933571093587347751">{1,plural, =1{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này được Ä‘á» là ngày mai. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.}other{Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này được Ä‘á» là # ngày nữa trong tÆ°Æ¡ng lai. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.}}</translation>
-<translation id="3934680773876859118">Không thể tải tài liệu PDF</translation>
+<translation id="3945915738023014686">ID báo cáo sự cố đã tải lên <ph name="CRASH_ID" /> (ID sự cố cục bộ: <ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">Máy chủ này không thể chứng minh được đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ không chỉ định Tên thay thế đối tượng. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="3963721102035795474">Chế Ä‘á»™ Ä‘á»c</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{Không có}=1{Từ 1 trang web }other{Từ # trang web }}</translation>
<translation id="397105322502079400">Äang tính...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> bị chặn</translation>
+<translation id="3987940399970879459">DÆ°á»›i 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 trang web lân cận}other{# trang web lân cận}}</translation>
<translation id="4021036232240155012">DNS là dịch vụ mạng dịch tên trang web sang địa chỉ Internet.</translation>
<translation id="4030383055268325496">&amp;Hoàn tác thêm</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Cấu hình proxy được đặt để sử dụng URL tập lệnh .pac chứ không phải máy chủ proxy cố định.</translation>
<translation id="4098354747657067197">Trang web lừa đảo phía trước</translation>
<translation id="4103249731201008433">Số sê-ri thiết bị không hợp lệ</translation>
+<translation id="410351446219883937">Tự động phát</translation>
<translation id="4103763322291513355">Truy cập &lt;strong&gt;chrome://policy&lt;/strong&gt; để xem danh sách các URL bị chặn quyá»n truy cập và các chính sách khác bị quản trị viên hệ thống buá»™c phải thá»±c thi.</translation>
-<translation id="4110615724604346410">Máy chủ này không chứng minh được rằng đó là là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này có lá»—i. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4115378294792113321">Äá» thẫm</translation>
+<translation id="4116663294526079822">Luôn cho phép trên trang web này</translation>
<translation id="4117700440116928470">Phạm vi chính sách không được hỗ trợ.</translation>
-<translation id="4118212371799607889">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được Chromium tin tưởng. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 mục khaÌc}other{# mục khác}}</translation>
<translation id="4130226655945681476">Kiểm tra cáp mạng, modem và bộ định tuyến</translation>
+<translation id="413544239732274901">Tìm hiểu thêm</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">Sử dụng cài đặt mặc định chung (Phát hiện)</translation>
+<translation id="4165986682804962316">Cài đặt trang web</translation>
<translation id="4169947484918424451">Bạn có muốn Chromium lưu thẻ này không?</translation>
<translation id="4171400957073367226">Chữ ký xác minh không hợp lệ</translation>
<translation id="4196861286325780578">&amp;Làm lại di chuyển</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Kiểm tra tÆ°á»ng lá»­a và cấu hình diệt vi-rút<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{không có gì}=1{1 ứng dụng ($1)}=2{2 ứng dụng ($1, $2)}other{# ứng dụng ($1, $2, $3)}}</translation>
<translation id="4220128509585149162">Sự cố</translation>
+<translation id="422022731706691852">Những kẻ tấn công trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cố gắng đánh lừa bạn cài đặt các chương trình ảnh hưởng đến trải nghiệm duyệt web của bạn (ví dụ: bằng cách thay đổi trang chủ hoặc hiển thị thêm quảng cáo trên các trang web bạn truy cập). <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />Thử chạy Chẩn đoán mạng<ph name="END_LINK" />.</translation>
+<translation id="4235360514405112390">Hợp lệ</translation>
<translation id="4250431568374086873">Kết nối của bạn tới trang web này không đủ an toàn</translation>
<translation id="4250680216510889253">Không</translation>
<translation id="425582637250725228">Các thay đổi bạn đã thực hiện có thể không được lưu.</translation>
<translation id="4258748452823770588">Chữ ký không hợp lệ</translation>
+<translation id="4265872034478892965">Äược quản trị viên cho phép</translation>
<translation id="4269787794583293679">(Không có tên ngÆ°á»i dùng)</translation>
<translation id="4275830172053184480">Khởi động lại thiết bị của bạn</translation>
<translation id="4280429058323657511">, hết hạn <ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Gần đây, tính năng Duyệt web an toàn của Google <ph name="BEGIN_LINK" />đã phát hiện thấy chương trình độc hại<ph name="END_LINK" /> trên <ph name="SITE" />. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4300246636397505754">Äá» xuất chính</translation>
<translation id="4304224509867189079">Äăng nhập</translation>
-<translation id="432290197980158659">Máy chủ đã xuất trình chứng chỉ không khá»›p vá»›i các kỳ vá»ng được tích hợp sẵn. Các kỳ vá»ng này có trong má»™t số trang web nhất định, có tính bảo mật cao vá»›i mục đích bảo vệ bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4312866146174492540">Chặn (mặc định)</translation>
<translation id="4325863107915753736">Không tìm được bài viết</translation>
<translation id="4326324639298822553">Kiểm tra ngày hết hạn của bạn và thử lại</translation>
<translation id="4331708818696583467">Không bảo mật</translation>
<translation id="4356973930735388585">Những kẻ tấn công trên trang web này có thể tìm cách cài đặt các chương trình nguy hiểm vào máy tính của bạn. Các chương trình này sẽ đánh cắp hoặc xóa thông tin của bạn (ví dụ: ảnh, mật khẩu, thư và thẻ tín dụng).</translation>
<translation id="4372948949327679948">Giá trị <ph name="VALUE_TYPE" /> mong đợi.</translation>
+<translation id="4377125064752653719">Bạn đã cố truy cập vào <ph name="DOMAIN" /> nhÆ°ng chứng chỉ mà máy chủ xuất trình đã bị nhà phát hành thu hồi. Äiá»u này có nghÄ©a là giấy ủy nhiệm bảo mật mà máy chủ xuất trình hoàn toàn không đáng tin cậy. Bạn có thể Ä‘ang giao tiếp vá»›i kẻ tấn công.</translation>
<translation id="4381091992796011497">Tên NgÆ°á»i dùng:</translation>
<translation id="4394049700291259645">Vô hiệu hóa</translation>
<translation id="4406896451731180161">kết quả tìm kiếm</translation>
+<translation id="4424024547088906515">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được Chrome tin cậy. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> không chấp nhận chứng chỉ đăng nhập của bạn hoặc có thể bạn chưa cung cấp chứng chỉ đăng nhập.</translation>
<translation id="443673843213245140">Äã tắt sá»­ dụng proxy nhÆ°ng cấu hình proxy rõ ràng được chỉ định.</translation>
-<translation id="4492190037599258964">Kết quả tìm kiếm cho '<ph name="SEARCH_STRING" />'</translation>
<translation id="4506176782989081258">Lỗi xác thực: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4506599922270137252">Liên hệ với quản trị viên hệ thống</translation>
<translation id="450710068430902550">Chia sẻ với quản trị viên</translation>
<translation id="4515275063822566619">Thẻ và địa chỉ từ Chrome và Tài khoản Google của bạn (<ph name="ACCOUNT_EMAIL" />). Bạn có thể quản lý thẻ và địa chỉ trong <ph name="BEGIN_LINK" />Cài đặt<ph name="END_LINK" />.</translation>
<translation id="4522570452068850558">Chi tiết</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Thử tắt tiện ích.</translation>
<translation id="457875822857220463">Giao hàng</translation>
<translation id="4587425331216688090">Xóa địa chỉ khá»i Chrome?</translation>
-<translation id="4589078953350245614">Bạn đã cố gắng truy cập <ph name="DOMAIN" /> nhưng máy chủ đã xuất trình chứng chỉ không hợp lệ. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="4592951414987517459">Kết nối của bạn tới <ph name="DOMAIN" /> được mã hóa bằng bộ số 0 hiện đại.</translation>
<translation id="4594403342090139922">&amp;Hoàn tác xóa</translation>
<translation id="4619615317237390068">Tab từ các thiết bị khác</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này có lá»—i. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
+<translation id="4690462567478992370">Dừng sử dụng chứng chỉ không hợp lệ</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Kết nối của bạn bị gián đoạn</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Chạy Chẩn đoán mạng của Windows<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">Xảy ra lỗi chưa biết.</translation>
<translation id="4800132727771399293">Kiểm tra ngày hết hạn và CVC của bạn rồi thử lại</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">Bạn không thể truy cập <ph name="SITE" /> ngay bây giá» do trang web gá»­i thông tin đăng nhập đã mã hóa mà Google Chrome không thể xá»­ lý. Lỗi maÌ£ng vaÌ€ caÌc cuộc tâÌn công maÌ£ng thÆ°Æ¡Ì€ng chỉ laÌ€ taÌ£m thÆ¡Ì€i, do Ä‘oÌ trang naÌ€y coÌ thể sẽ hoaÌ£t động laÌ£i sau.</translation>
<translation id="4813512666221746211">Lỗi mạng</translation>
<translation id="4816492930507672669">Vừa với trang</translation>
<translation id="483020001682031208">Không có trang Web trong cuộc sống nào để hiển thị</translation>
<translation id="4850886885716139402">Xem</translation>
<translation id="4854362297993841467">Phương thức phân phối này không có sẵn. Hãy thử một phương thức khác.</translation>
<translation id="4858792381671956233">Bạn đã há»i cha mẹ mình xem có thể truy cập vào trang này hay không</translation>
+<translation id="4863764087567530506">Ná»™i dung này có thể tìm cách đánh lừa bạn cài đặt phần má»m hoặc tiết lá»™ thông tin cá nhân. <ph name="BEGIN_LINK" />Vẫn hiển thị<ph name="END_LINK" />.</translation>
<translation id="4880827082731008257">Lịch sử tìm kiếm</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{và thêm 1 trang web}other{và thêm # trang web}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Trang này đã được dịch từ một ngôn ngữ không xác định sang <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">Thanh toán</translation>
<translation id="4926049483395192435">Phải được chỉ định.</translation>
<translation id="495170559598752135">Tác vụ</translation>
<translation id="4958444002117714549">Mở rộng danh sách</translation>
-<translation id="4962322354953122629">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được Chrome tin tưởng. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="4974590756084640048">Bật lại cảnh báo</translation>
<translation id="4989809363548539747">Plugin này không được hỗ trợ</translation>
<translation id="5002932099480077015">Nếu được bật, Chrome sẽ lÆ°u trữ bản sao thẻ của bạn trên thiết bị này để Ä‘iá»n vào biểu mẫu nhanh hÆ¡n.</translation>
<translation id="5018422839182700155">Không thể mở trang này</translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">Kiểm tra chính sách của quản trị viên của bạn</translation>
<translation id="5029568752722684782">Xóa bản sao</translation>
<translation id="5031870354684148875">Giới thiệu vỠGoogle Dịch</translation>
+<translation id="5039804452771397117">Cho phép</translation>
<translation id="5040262127954254034">Bảo mật</translation>
<translation id="5045550434625856497">Mật khẩu sai</translation>
<translation id="5056549851600133418">Bài viết dành cho bạn</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Kiểm tra địa chỉ proxy<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{Không có cookie}=1{1 trang web sử dụng cookie. }other{# trang web sử dụng cookie. }}</translation>
<translation id="5087286274860437796">Chứng chỉ của máy chủ không hợp lệ tại thá»i Ä‘iểm này.</translation>
<translation id="5087580092889165836">Thêm thẻ</translation>
<translation id="5089810972385038852">Tiểu bang</translation>
+<translation id="5094747076828555589">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được Chromium tin cậy. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="5095208057601539847">Tỉnh/thành phố</translation>
<translation id="5115563688576182185">(64 bit)</translation>
<translation id="5141240743006678641">Mã hóa mật khẩu đã đồng bộ hóa với thông tin đăng nhập Google của bạn</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">Cần có email</translation>
<translation id="5251803541071282808">Äám mây</translation>
<translation id="5277279256032773186">Sá»­ dụng Chrome ở cÆ¡ quan? Các doanh nghiệp có thể quản lý cài đặt Chrome cho nhân viên của há». Tìm hiểu thêm</translation>
+<translation id="5297526204711817721">Kết nối của bạn tá»›i trang web này không ở chế Ä‘á»™ riêng tÆ°. Äể thoát chế Ä‘á»™ VR bất cứ lúc nào, hãy tháo tai nghe và nhấn quay lại.</translation>
<translation id="5299298092464848405">Lỗi phân tích cú pháp chính sách</translation>
-<translation id="5300589172476337783">Hiển thị</translation>
<translation id="5308689395849655368">Báo cáo sự cố bị tắt.</translation>
<translation id="5317780077021120954">LÆ°u</translation>
<translation id="5327248766486351172">Tên</translation>
-<translation id="5337705430875057403">Kẻ tấn công trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể đánh lừa bạn làm má»™t việc gì đó nguy hiểm nhÆ° cài đặt phần má»m hoặc tiết lá»™ thông tin cá nhân của bạn (ví dụ: mật khẩu, số Ä‘iện thoại hoặc thẻ tín dụng).</translation>
-<translation id="5359637492792381994">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; hiện tại, chứng chỉ bảo mật của máy chủ này không hợp lệ. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
+<translation id="5355557959165512791">Bạn không thể truy cập vào <ph name="SITE" /> ngay bây giá» vì chứng chỉ của trang này đã bị thu hồi. Lá»—i mạng và các cuá»™c tấn công mạng thÆ°á»ng chỉ là tạm thá»i nên trang này có thể sẽ hoạt Ä‘á»™ng lại sau.</translation>
<translation id="536296301121032821">Không thể lưu trữ cài đặt chính sách</translation>
<translation id="5386426401304769735">Chuỗi chứng chỉ cho trang web này có chứa một chứng chỉ đã ký bằng SHA-1.</translation>
<translation id="5402410679244714488">Hết hạn: <ph name="EXPIRATION_DATE_ABBR" />, sử dụng lần cuối hơn một năm trước</translation>
+<translation id="540969355065856584">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không hợp lệ tại thá»i Ä‘iểm này. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
<translation id="5421136146218899937">Xóa dữ liệu duyệt web...</translation>
<translation id="5430298929874300616">Xóa dấu trang</translation>
<translation id="5431657950005405462">Không tìm thấy tệp của bạn</translation>
-<translation id="5435775191620395718">Hiển thị lịch sử từ thiết bị này. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" />.</translation>
<translation id="5439770059721715174">Lỗi xác thực lược đồ tại "<ph name="ERROR_PATH" />": <ph name="ERROR" /></translation>
<translation id="5452270690849572955">Không thể tìm thấy trang <ph name="HOST_NAME" /> này</translation>
<translation id="5455374756549232013">Dấu thá»i gian chính sách không hợp lệ</translation>
<translation id="5455790498993699893"><ph name="ACTIVE_MATCH" /> của <ph name="TOTAL_MATCHCOUNT" /></translation>
+<translation id="5457113250005438886">Không hợp lệ</translation>
<translation id="5470861586879999274">&amp;Làm lại chỉnh sửa</translation>
<translation id="54817484435770891">Thêm địa chỉ hợp lệ</translation>
<translation id="5492298309214877701">Trang web trên mạng ná»™i bá»™ của công ty, tổ chức hoặc trÆ°á»ng há»c này có URL tÆ°Æ¡ng tá»± nhÆ° trang web bên ngoài.
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">Không thể nhận hàng từ địa chỉ này. Chá»n má»™t địa chỉ khác.</translation>
<translation id="5572851009514199876">Vui lòng khởi động và đăng nhập vào Chrome để Chrome có thể kiểm tra xem bạn có được phép truy cập trang web này không.</translation>
<translation id="5580958916614886209">Kiểm tra tháng hết hạn của bạn và thử lại</translation>
+<translation id="5586446728396275693">Không có địa chỉ nào được lưu</translation>
+<translation id="5595485650161345191">Chỉnh sửa địa chỉ</translation>
<translation id="560412284261940334">Không hỗ trợ quản lý</translation>
<translation id="5610142619324316209">Kiểm tra kết nối</translation>
<translation id="5610807607761827392">Bạn có thể quản lý thẻ và địa chỉ trong <ph name="BEGIN_LINK" />Cài đặt<ph name="END_LINK" />.</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">Bạn có muốn rá»i khá»i trang web này không?</translation>
<translation id="5629630648637658800">Không thể tải cài đặt chính sách</translation>
<translation id="5631439013527180824">Mã thông báo quản lý thiết bị không hợp lệ</translation>
+<translation id="5633066919399395251">Những kẻ tấn công hiện ở trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cố gắng cài đặt các chương trình nguy hiểm vào máy tính của bạn. Các chương trình này sẽ đánh cắp hoặc xóa thông tin của bạn (ví dụ: ảnh, mật khẩu, thư và thẻ tín dụng). <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">Vị trí</translation>
+<translation id="5659593005791499971">Email</translation>
<translation id="5669703222995421982">Nhận nội dung được cá nhân hóa</translation>
<translation id="5675650730144413517">Trang này hiện không hoạt động</translation>
-<translation id="5677928146339483299">Bị chặn</translation>
-<translation id="5694783966845939798">Bạn đã cố gắng truy cập <ph name="DOMAIN" /> nhÆ°ng máy chủ xuất trình má»™t chứng chỉ được ký bằng má»™t thuật toán chữ ký yếu (chẳng hạn nhÆ° SHA-1). Äiá»u này có nghÄ©a là thông tin đăng nhập bảo mật mà máy chủ xuất trình có thể đã bị giả mạo và máy chủ đó có thể không phải là máy chủ mà bạn mong đợi (bạn có thể Ä‘ang kết nối vá»›i kẻ tấn công). <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5710435578057952990">Nhận dạng trang web này chưa được xác minh.</translation>
+<translation id="5713016350996637505">Äã chặn ná»™i dung lừa đảo</translation>
<translation id="5720705177508910913">NgÆ°á»i dùng hiện tại</translation>
<translation id="5732392974455271431">Cha mẹ của bạn có thể bỠchặn trang web cho bạn</translation>
<translation id="5763042198335101085">Nhập địa chỉ email hợp lệ</translation>
<translation id="5765072501007116331">Äể xem các yêu cầu và phÆ°Æ¡ng thức phân phối, hãy chá»n má»™t địa chỉ</translation>
+<translation id="5778550464785688721">Äiá»u khiển toàn bá»™ thiết bị MIDI</translation>
<translation id="5784606427469807560">Äã xảy ra sá»± cố khi xác nhận thẻ của bạn. Hãy kiểm tra kết nối Internet của bạn và thá»­ lại.</translation>
<translation id="5785756445106461925">Ngoài ra, trang này bao gồm các tài nguyên khác không an toàn. Những tài nguyên này có thể bị ngÆ°á»i khác xem khi Ä‘ang gá»­i và có thể bị kẻ tấn công sá»­a đổi nhằm thay đổi giao diện của trang.</translation>
<translation id="5786044859038896871">Bạn có muốn Ä‘iá»n thông tin thẻ của mình không?</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">&amp;Làm lại thêm</translation>
<translation id="5814352347845180253">Bạn có thể mất quyá»n truy cập vào ná»™i dung cao cấp từ <ph name="SITE" /> và má»™t số trang web khác.</translation>
<translation id="5838278095973806738">Bạn không nên nhập bất kỳ thông tin nhạy cảm nào trên trang web này (ví dụ: mật khẩu hoặc thẻ tín dụng), vì những kẻ tấn công có thể đánh cắp thông tin đó.</translation>
-<translation id="5843436854350372569">Bạn đã cố gắng truy cập <ph name="DOMAIN" /> nhưng máy chủ xuất trình chứng chỉ chứa khóa yếu. Kẻ tấn công có thể đã phá khóa cá nhân và máy chủ đó có thể không phải là máy chủ bạn mong đợi (bạn có thể đang kết nối với kẻ tấn công). <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="5869405914158311789">Không thể truy cập trang web này</translation>
<translation id="5869522115854928033">Mật khẩu đã lưu</translation>
<translation id="5872918882028971132">Äá» xuất chính</translation>
<translation id="5901630391730855834">Vàng</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (được đồng bộ hóa)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{Äang sá»­ dụng 1 cookie}other{Äang sá»­ dụng # cookie}}</translation>
<translation id="5926846154125914413">Bạn có thể mất quyá»n truy cập vào ná»™i dung cao cấp từ má»™t số trang web.</translation>
<translation id="5959728338436674663">Tự động gửi một số <ph name="BEGIN_WHITEPAPER_LINK" />thông tin hệ thống và nội dung trang<ph name="END_WHITEPAPER_LINK" /> tới Google để giúp phát hiện các ứng dụng và trang web nguy hiểm. <ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">Tuần</translation>
<translation id="5967867314010545767">Xóa khá»i lịch sá»­</translation>
<translation id="5975083100439434680">Thu nhá»</translation>
<translation id="598637245381783098">Không thể mở ứng dụng thanh toán</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{Trang 1}other{Trang #}}</translation>
<translation id="6017514345406065928">Xanh lục</translation>
+<translation id="6017850046339264347">Những kẻ tấn công trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cài đặt ứng dụng lừa đảo giả vỠlà nội dung khác hoặc thu thập dữ liệu có thể dùng để theo dõi bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (được đồng bộ hóa)</translation>
<translation id="6027201098523975773">Nhập tên</translation>
<translation id="6040143037577758943">Äóng</translation>
<translation id="6042308850641462728">Thêm</translation>
+<translation id="6047233362582046994">Nếu bạn hiểu các rủi ro vỠbảo mật, bạn có thể <ph name="BEGIN_LINK" />truy cập trang này<ph name="END_LINK" /> trước khi các ứng dụng có hại bị xóa.</translation>
+<translation id="6051221802930200923">Bạn không thể truy cập vào <ph name="SITE" /> ngay bây giá» do trang web sá»­ dụng tính năng ghim chứng chỉ. Lá»—i mạng và các cuá»™c tấn công mạng thÆ°á»ng chỉ là tạm thá»i nên trang này có thể sẽ hoạt Ä‘á»™ng lại sau.</translation>
<translation id="6060685159320643512">Hãy cẩn thận, thử nghiệm này có thể gây lỗi</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{không có gì}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">Bạn đã truy cập nội dung bằng chứng chỉ do quản trị viên cấp. Dữ liệu mà bạn cung cấp cho <ph name="DOMAIN" /> có thể bị quản trị viên của bạn chặn.</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{Không có}=1{1 mật khẩu (đã đồng bộ hóa)}other{# mật khẩu (đã đồng bộ hóa)}}</translation>
<translation id="6146055958333702838">Kiểm tra má»i dây cáp rồi khởi Ä‘á»™ng lại bá»™ định tuyến, modem hoặc các thiết bị
mạng khác mà bạn có thể đang sử dụng.</translation>
<translation id="614940544461990577">Hãy thử:</translation>
<translation id="6151417162996330722">Chứng chỉ máy chủ có thá»i gian hiệu lá»±c quá dài.</translation>
<translation id="6157877588268064908">Äể xem các yêu cầu và phÆ°Æ¡ng thức giao hàng, hãy chá»n má»™t địa chỉ</translation>
+<translation id="6158003235852588289">Gần đây, tính năng Duyệt web an toàn của Google đã phát hiện thấy hành vi lừa đảo trên <ph name="SITE" />. Các trang web lừa đảo giả mạo các trang web khác để lừa bạn.</translation>
<translation id="6165508094623778733">Tìm hiểu thêm</translation>
+<translation id="6169916984152623906">GiỠđây, bạn có thể duyệt web riêng tÆ° và ngÆ°á»i khác sá»­ dụng thiết bị này sẽ không thấy hoạt Ä‘á»™ng của bạn. Tuy nhiên, tài nguyên đã tải xuống và dấu trang sẽ được lÆ°u.</translation>
<translation id="6177128806592000436">Kết nối của bạn tới trang web này không an toàn</translation>
<translation id="6184817833369986695">(nhóm thuần tập: <ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">Kiểm tra kết nối Internet của bạn</translation>
<translation id="6218753634732582820">Bạn muốn xóa địa chỉ khá»i Chromium?</translation>
+<translation id="6221345481584921695">Duyệt web an toàn của Google gần đây <ph name="BEGIN_LINK" />đã phát hiện phần má»m Ä‘á»™c hại<ph name="END_LINK" /> trên <ph name="SITE" />. Các trang web thÆ°á»ng được coi là an toàn đôi khi vẫn bị nhiá»…m phần má»m Ä‘á»™c hại. Ná»™i dung Ä‘á»™c hại xuất phát từ <ph name="SUBRESOURCE_HOST" />, má»™t nguồn phát tán phần má»m Ä‘á»™c hại đã xác định.</translation>
<translation id="6251924700383757765">ChiÌnh saÌch bảo mật</translation>
<translation id="6254436959401408446">Không đủ bộ nhớ để mở trang này</translation>
<translation id="625755898061068298">Bạn đã chá»n tắt cảnh báo bảo mật cho trang web này.</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">Chỉnh sửa dấu trang</translation>
<translation id="6410264514553301377">Nhập ngày hết hạn và CVC cho <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Bạn đã há»i cha mẹ mình xem có thể truy cập vào trang này hay không</translation>
-<translation id="6416403317709441254">Bạn không thể truy cập <ph name="SITE" /> ngay bây giá» do trang web gá»­i thông tin đăng nhập đã mã hóa mà Chromium không thể xá»­ lý. Lá»—i mạng và các cuá»™c tấn công mạng thÆ°á»ng chỉ là tạm thá»i, do đó, trang này có thể sẽ hoạt Ä‘á»™ng lại sau. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6417515091412812850">Không thể kiểm tra liệu chứng chỉ đã bị thu hồi hay chưa.</translation>
<translation id="6433490469411711332">Chỉnh sửa thông tin liên hệ</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> đã từ chối kết nối.</translation>
<translation id="6446608382365791566">Thêm thông tin khác</translation>
+<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">Xác nhận việc Gửi lại Biểu mẫu</translation>
<translation id="6456339708790392414">Thanh toán của bạn</translation>
<translation id="6458467102616083041">Bị bỠqua vì chính sách đã tắt tìm kiếm mặc định.</translation>
-<translation id="6462969404041126431">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này có thể bị thu hồi. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="647261751007945333">Chính sách thiết bị</translation>
<translation id="6477321094435799029">Chrome đã phát hiện mã bất thÆ°á»ng trên trang này và đã chặn mã này để bảo vệ thông tin cá nhân của bạn (ví dụ nhÆ° mật khẩu, số Ä‘iện thoại và thẻ tín dụng).</translation>
<translation id="6489534406876378309">Bắt đầu tải lên sự cố</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">Hết hạn: <ph name="EXPIRATION_DATE_ABBR" />, sử dụng lần cuối: <ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">NgÆ°á»i quản lý của bạn chÆ°a phê duyệt trang web</translation>
<translation id="6569060085658103619">Bạn đang xem trang tiện ích</translation>
-<translation id="6593753688552673085">dÆ°á»›i <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">Ná»™i dung này có thể tìm cách cài đặt phần má»m nguy hiểm trên thiết bị của bạn để lấy cắp hoặc xóa thông tin. <ph name="BEGIN_LINK" />Vẫn hiển thị<ph name="END_LINK" />.</translation>
<translation id="6596325263575161958">Tùy chá»n mã hóa</translation>
<translation id="662080504995468778">Ở lại</translation>
<translation id="6626291197371920147">Thêm số thẻ hợp lệ</translation>
<translation id="6628463337424475685">Tìm kiếm trên <ph name="ENGINE" /></translation>
+<translation id="6630809736994426279">Những kẻ tấn công hiện ở trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cố gắng cài đặt các chương trình nguy hiểm vào máy Mac của bạn. Các chương trình này sẽ đánh cắp hoặc xóa thông tin của bạn (ví dụ: ảnh, mật khẩu, thư và thẻ tín dụng). <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">Chính sách này không được chấp thuận.</translation>
-<translation id="6652240803263749613">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được hệ Ä‘iá»u hành của máy tính tin tưởng. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="6671697161687535275">Bạn muốn xóa Ä‘á» xuất biểu mẫu khá»i Chromium?</translation>
<translation id="6685834062052613830">Äăng xuất và hoàn thành quá trình thiết lập</translation>
<translation id="6710213216561001401">Trước đó</translation>
<translation id="6710594484020273272">&lt;Nhập cụm từ tìm kiếm&gt;</translation>
<translation id="6711464428925977395">Äã xảy ra sá»± cố vá»›i máy chủ proxy hoặc địa chỉ không chính xác.</translation>
<translation id="6727102863431372879">Äặt</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{không có gì}=1{1 mục}other{# mục}}</translation>
<translation id="674375294223700098">Lỗi chứng chỉ máy chủ không xác định.</translation>
<translation id="6753269504797312559">Giá trị chính sách</translation>
<translation id="6757797048963528358">Thiết bị của bạn đã chuyển sang chế độ ngủ.</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">ID tùy chỉnh</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">Không tải được dữ liệu khu vực</translation>
+<translation id="6825578344716086703">Bạn đã cố gắng truy cập vào <ph name="DOMAIN" /> nhÆ°ng máy chủ xuất trình má»™t chứng chỉ được ký bằng má»™t thuật toán chữ ký yếu (chẳng hạn nhÆ° SHA-1). Äiá»u này có nghÄ©a là thông tin đăng nhập bảo mật mà máy chủ xuất trình có thể đã bị giả mạo và máy chủ đó có thể không phải là máy chủ mà bạn mong đợi (bạn có thể Ä‘ang kết nối vá»›i kẻ tấn công).</translation>
+<translation id="6830728435402077660">Không bảo mật</translation>
<translation id="6831043979455480757">Dịch</translation>
<translation id="6839929833149231406">Khu vá»±c</translation>
<translation id="6874604403660855544">&amp;Làm lại thêm</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">Thẻ của bạn đã được xác nhận</translation>
<translation id="6897140037006041989">Tác nhân NgÆ°á»i dùng</translation>
<translation id="6915804003454593391">NgÆ°á»i dùng:</translation>
+<translation id="6945221475159498467">Chá»n</translation>
<translation id="6948701128805548767">Äể xem các yêu cầu và phÆ°Æ¡ng thức nhận hàng, hãy chá»n má»™t địa chỉ</translation>
<translation id="6957887021205513506">Chứng chỉ của máy chủ dÆ°á»ng nhÆ° giả mạo.</translation>
<translation id="6965382102122355670">OK</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">Cả hai máy chủ proxy cố định và URL tập lệnh .pac Ä‘á»u được chỉ định.</translation>
<translation id="6989763994942163495">Hiển thị cài đặt nâng cao...</translation>
<translation id="7000990526846637657">Không tìm thấy mục nhập lịch sử nào</translation>
-<translation id="7009986207543992532">Bạn đã cố gắng truy cập <ph name="DOMAIN" /> nhÆ°ng máy chủ đã xuất trình chứng chỉ có thá»i gian có hiệu lá»±c quá dài để có thể tin cậy. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7012372675181957985">Tài khoản Google của bạn có thể có các biểu mẫu lịch sử duyệt web khác tại <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation>
<translation id="7029809446516969842">Mật khẩu</translation>
+<translation id="7050187094878475250">Bạn đã cố gắng truy cập <ph name="DOMAIN" /> nhÆ°ng máy chủ đã hiển thị chứng chỉ có thá»i gian hiệu lá»±c quá dài để có thể tin cậy.</translation>
+<translation id="7053983685419859001">Chặn</translation>
<translation id="7064851114919012435">Thông tin liên hệ</translation>
<translation id="7079718277001814089">Trang web này có chứa phần má»m Ä‘á»™c hại</translation>
<translation id="7087282848513945231">Hạt</translation>
-<translation id="7088615885725309056">Cũ hơn</translation>
<translation id="7090678807593890770">Tìm kiếm <ph name="LINK" /> trên Google</translation>
+<translation id="7108819624672055576">Äược má»™t tiện ích cho phép</translation>
<translation id="7119414471315195487">Äóng các tab hoặc chÆ°Æ¡ng trình khác</translation>
<translation id="7129409597930077180">Không thể giao hàng đến địa chỉ này. Chá»n má»™t địa chỉ khác.</translation>
<translation id="7138472120740807366">Phương thức phân phối</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">Äang xá»­ lý</translation>
<translation id="724691107663265825">Trang web bạn sắp truy cập chứa phần má»m Ä‘á»™c hại</translation>
<translation id="724975217298816891">Nhập ngày hết hạn và CVC cho <ph name="CREDIT_CARD" /> để cập nhật chi tiết thẻ của bạn. Sau khi bạn xác nhận, chi tiết thẻ của bạn sẽ được chia sẻ với trang web này.</translation>
-<translation id="725866823122871198">Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giỠ(<ph name="DATE_AND_TIME" />) trên máy tính của bạn không đúng.</translation>
+<translation id="7260504762447901703">Thu hồi quyá»n truy cập</translation>
<translation id="7275334191706090484">Dấu trang được quản lý</translation>
<translation id="7298195798382681320">Äược Ä‘á» xuất</translation>
<translation id="7309308571273880165">Báo cáo sá»± cố được ghi lại vào <ph name="CRASH_TIME" /> (ngÆ°á»i dùng yêu cầu tải lên, nhÆ°ng chÆ°a được tải lên)</translation>
<translation id="7334320624316649418">&amp;Làm lại sắp xếp lại</translation>
<translation id="733923710415886693">Chứng chỉ của máy chủ đã không được tiết lộ qua Tính minh bạch của chứng chỉ.</translation>
-<translation id="7351800657706554155">Bạn không thể truy cập <ph name="SITE" /> ngay bây giá» do chứng chỉ của trang web đã bị thu hồi. Các cuá»™c tấn công và lá»—i mạng thÆ°á»ng chỉ là tạm thá»i, do đó trang này có thể sẽ hoạt Ä‘á»™ng lại sau. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="7353601530677266744">Dòng Lệnh</translation>
<translation id="7372973238305370288">kết quả tìm kiếm</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Không</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">Xác nhận thẻ</translation>
-<translation id="7394102162464064926">Bạn có chắc chắn muốn xóa những trang này khá»i lịch sá»­ của mình không?
-
-Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích vào lần sau.</translation>
<translation id="7400418766976504921">URL</translation>
<translation id="7419106976560586862">ÄÆ°á»ng dẫn cấu hình</translation>
<translation id="7424977062513257142">Trang được nhúng trên trang web này cho biết:</translation>
@@ -688,6 +754,7 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="7444046173054089907">Trang web này bị chặn</translation>
<translation id="7445762425076701745">Không thể xác thực đầy đủ nhận dạng của máy chủ bạn đã kết nối. Bạn đã kết nối vào máy chủ bằng một tên chỉ hợp lệ trong mạng của bạn và đó là tên mà các tổ chức phát hành chứng chỉ bên ngoài không thể xác thực được. Vì một số tổ chức phát hành chứng chỉ sẽ cấp chứng chỉ cho các tên này thay thế, nên không có cách nào đảm bảo bạn được kết nối tới trang web đã chỉ định và không phải là kẻ tấn công.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /> vỠsự cố này.</translation>
+<translation id="7455133967321480974">Sử dụng cài đặt mặc định chung (Chặn)</translation>
<translation id="7460163899615895653">Các tab gần đây của bạn từ các thiết bị khác xuất hiện ở đây</translation>
<translation id="7469372306589899959">Äang xác nhận thẻ</translation>
<translation id="7481312909269577407">Chuyển tiếp</translation>
@@ -695,36 +762,43 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="7508255263130623398">ID thiết bị thuộc chính sách trả lại trống hoặc không khớp với ID của thiết bị hiện tại</translation>
<translation id="7514365320538308">Tải xuống</translation>
<translation id="7518003948725431193">Không tìm thấy trang web nào ứng với địa chỉ web:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">Giá trị</translation>
<translation id="7537536606612762813">Bắt buộc</translation>
+<translation id="7542403920425041731">Sau khi bạn xác nhận, chi tiết thẻ của bạn sẽ được chia sẻ với trang web này.</translation>
<translation id="7542995811387359312">Tính năng tá»± Ä‘á»™ng Ä‘iá»n thẻ tín dụng đã bị vô hiệu hóa vì biểu mẫu này không sá»­ dụng kết nối an toàn.</translation>
<translation id="7543525346216957623">Hãy há»i ý kiến cha mẹ của bạn</translation>
<translation id="7549584377607005141">Trang web này yêu cầu dữ liệu mà bạn đã nhập trÆ°á»›c đó để được hiển thị đúng cách. Bạn có thể gá»­i lại dữ liệu này nhÆ°ng làm nhÆ° vậy bạn sẽ lặp lại má»i hoạt Ä‘á»™ng mà trang này đã thá»±c hiện trÆ°á»›c đó.</translation>
<translation id="7552846755917812628">Thử các mẹo sau:</translation>
<translation id="7554791636758816595">Tab má»›i</translation>
+<translation id="7567204685887185387">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này có thể đã bị gian lận khi phát hành. Äiá»u này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> liên hệ khác}other{<ph name="CONTACT_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> liên hệ khác}}</translation>
<translation id="7568593326407688803">Trang này bằng<ph name="ORIGINAL_LANGUAGE" />Bạn có muốn dịch trang này không?</translation>
<translation id="7569952961197462199">Xóa thẻ tín dụng khá»i Chrome?</translation>
<translation id="7569983096843329377">Äen</translation>
<translation id="7578104083680115302">Thanh toán nhanh trên các trang web và ứng dụng trong má»i thiết bị nhá» sá»­ dụng thẻ bạn đã lÆ°u vá»›i Google.</translation>
<translation id="7588950540487816470">Web trong cuộc sống</translation>
<translation id="7592362899630581445">Chứng chỉ của máy chủ vi phạm hạn chế tên.</translation>
+<translation id="7598391785903975535">DÆ°á»›i <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> hiện không thể xử lý yêu cầu này.</translation>
<translation id="7600965453749440009">Không bao giỠdịch <ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">Giá trị nằm ngoài phạm vi <ph name="VALUE" />.</translation>
<translation id="7613889955535752492">Hết hạn: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">Bạn đã có dữ liệu được mã hóa bằng mật khẩu khác của Tài khoản Google. Vui lòng nhập mật khẩu đó bên dưới.</translation>
-<translation id="7634554953375732414">Kết nối của bạn tới trang web này không ở chế độ riêng tư.</translation>
<translation id="7637571805876720304">Bạn muốn xóa thẻ tín dụng khá»i Chromium?</translation>
<translation id="765676359832457558">Ẩn cài đặt nâng cao...</translation>
<translation id="7658239707568436148">Hủy</translation>
+<translation id="7662298039739062396">Cài đặt được một tiện ích kiểm soát</translation>
<translation id="7667346355482952095">Mã thông báo chính sách trả vỠtrống hoặc không khớp với mã thông báo hiện tại</translation>
<translation id="7668654391829183341">Thiết bị không xác định</translation>
<translation id="7669271284792375604">Những kẻ tấn công trên trang web này có thể đánh lừa bạn cài đặt các chương trình ảnh hưởng đến trải nghiệm duyệt web của bạn (ví dụ: bằng cách thay đổi trang chủ của bạn hoặc hiển thị thêm quảng cáo trên các trang web bạn truy cập).</translation>
<translation id="7674629440242451245">Bạn quan tâm đến các tính năng mới thú vị của Chrome? Hãy dùng thử kênh nhà phát triển của chúng tôi tại chrome.com/dev.</translation>
<translation id="7682287625158474539">Äịa chỉ gá»­i hàng</translation>
+<translation id="7701040980221191251">Không</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />Tiếp tục truy cập <ph name="SITE" /> (không an toàn)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">Chứng chỉ</translation>
+<translation id="7716147886133743102">Bị quản trị viên của bạn chặn</translation>
<translation id="7716424297397655342">Không thể tải trang web này từ bộ nhớ cache</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">Không được quản lý</translation>
<translation id="7755287808199759310">Cha mẹ của bạn có thể bỠchặn trang web cho bạn</translation>
<translation id="7758069387465995638">TÆ°á»ng lá»­a hoặc phần má»m diệt vi-rút có thể đã chặn kết nối.</translation>
@@ -751,15 +825,15 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="7951415247503192394">(32 bit)</translation>
<translation id="7956713633345437162">Dấu trang di động</translation>
<translation id="7961015016161918242">ChÆ°a bao giá»</translation>
-<translation id="7962083544045318153">ID sự cố <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">Luôn dịch <ph name="ORIGINAL_LANGUAGE" /> sang <ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">Không chỉ định</translation>
<translation id="800218591365569300">Thử đóng các tab hoặc chương trình khác để giải phóng bộ nhớ.</translation>
<translation id="8012647001091218357">Chúng tôi không thể liên lạc vá»›i cha mẹ của bạn vào thá»i Ä‘iểm này. Vui lòng thá»­ lại.</translation>
<translation id="8025119109950072390">Những kẻ tấn công trên trang web này có thể đánh lừa bạn làm má»™t việc gì đó nguy hiểm nhÆ° cài đặt phần má»m hoặc tiết lá»™ thông tin cá nhân của bạn (ví dụ: mật khẩu, số Ä‘iện thoại hoặc thẻ tín dụng).</translation>
-<translation id="803030522067524905">Gần đây, tính năng Duyệt web an toàn của Google đã phát hiện thấy lừa đảo trên <ph name="SITE" />. Các trang web lừa đảo giả mạo các trang web khác để lừa bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8034522405403831421">Trang này có ngôn ngữ là <ph name="SOURCE_LANGUAGE" />. Dịch trang này sang <ph name="TARGET_LANGUAGE" />?</translation>
+<translation id="8037357227543935929">Yêu cầu (mặc định)</translation>
<translation id="8041089156583427627">Gửi phản hồi</translation>
+<translation id="8041940743680923270">Sá»­ dụng cài đặt mặc định chung (Há»i)</translation>
<translation id="8088680233425245692">Không xem được bài viết.</translation>
<translation id="8089520772729574115">dÆ°á»›i 1 MB</translation>
<translation id="8091372947890762290">Kích hoạt đang chỠxử lý trên máy chủ</translation>
@@ -768,13 +842,14 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="8134994873729925007">Không thể tìm thấy <ph name="BEGIN_ABBR" />địa chỉ DNS<ph name="END_ABBR" /> của máy chủ của <ph name="HOST_NAME" />.</translation>
<translation id="8149426793427495338">Máy tính của bạn đã chuyển sang chế độ ngủ.</translation>
<translation id="8150722005171944719">Không thể Ä‘á»c được tệp tại <ph name="URL" />. Tệp này có thể đã bị xóa, di chuyển hoặc quyá»n tệp có thể Ä‘ang chặn truy cập.</translation>
+<translation id="8184538546369750125">Sử dụng cài đặt mặc định chung (Cho phép)</translation>
+<translation id="8191494405820426728">ID sự cố cục bộ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">&amp;Hoàn tác di chuyển</translation>
<translation id="8201077131113104583">URL cập nhật không hợp lệ cho tiện ích có ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Tóm tắt đơn đặt hàng</translation>
<translation id="8218327578424803826">Vị trí được gán:</translation>
<translation id="8225771182978767009">NgÆ°á»i thiết lập máy tính này đã chá»n chặn trang web này.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">Những kẻ tấn công đang ở trên <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể cố gắng cài đặt các chương trình nguy hiểm vào máy tính của bạn. Các chương trình này sẽ đánh cắp hoặc xóa thông tin của bạn (ví dụ: ảnh, mật khẩu, thư và thẻ tín dụng).</translation>
<translation id="8241707690549784388">Trang mà bạn đang tìm sử dụng thông tin bạn đã nhập vào. Việc quay lại trang đó có thể lặp lại bất kỳ tác vụ nào bạn đã thực hiện. Bạn có muốn tiếp tục không?</translation>
<translation id="8249320324621329438">Tìm nạp lần cuối:</translation>
<translation id="8253091569723639551">Yêu cầu địa chỉ thanh toán</translation>
@@ -782,6 +857,7 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="8289355894181816810">Hãy liên hệ vá»›i quản trị viên mạng của bạn nếu bạn không chắc chắn vá» Ä‘iá»u này có ý nghÄ©a gì.</translation>
<translation id="8293206222192510085">Thêm Dấu trang</translation>
<translation id="8294431847097064396">Nguồn</translation>
+<translation id="8306404619377842860">Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giỠ(<ph name="DATE_AND_TIME" />) trên thiết bị của bạn không đúng. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">Không thể dịch do kết nối mạng có sự cố.</translation>
<translation id="8332188693563227489">Quyá»n truy cập <ph name="HOST_NAME" /> bị từ chối</translation>
<translation id="834457929814110454">Nếu bạn hiểu các rủi ro vỠbảo mật, bạn có thể <ph name="BEGIN_LINK" />truy cập trang này<ph name="END_LINK" /> trước khi các chương trình độc hại bị xóa.</translation>
@@ -802,11 +878,9 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="8483780878231876732">Äể sá»­ dụng thẻ từ Tài khoản Google, hãy đăng nhập vào Chrome</translation>
<translation id="8488350697529856933">Ãp dụng cho</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> mất quá nhiá»u thá»i gian để phản hồi.</translation>
-<translation id="852346902619691059">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được hệ Ä‘iá»u hành của thiết bị tin tưởng. Äiá»u này có thể do cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn. <ph name="BEGIN_LEARN_MORE_LINK" />Tìm hiểu thêm<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="8532105204136943229">Năm hết hạn</translation>
<translation id="8543181531796978784">Bạn có thể <ph name="BEGIN_ERROR_LINK" />báo cáo sự cố đã phát hiện<ph name="END_ERROR_LINK" /> hoặc nếu bạn hiểu rủi ro với bảo mật của mình, hãy <ph name="BEGIN_LINK" />truy cập trang web không an toàn này<ph name="END_LINK" />.</translation>
<translation id="8553075262323480129">Dịch thất bại do ngôn ngữ của trang không được xác định.</translation>
-<translation id="8559762987265718583">Không thể thiết lập kết nối riêng tư với <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> vì ngày và giỠ(<ph name="DATE_AND_TIME" />) trên thiết bị của bạn không đúng.</translation>
<translation id="8571890674111243710">Äang dịch trang sang <ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">Thêm số đ.thoại
</translation>
@@ -821,6 +895,7 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="8738058698779197622">Äể thiết lập kết nối an toàn, bạn cần đặt thá»i gian đúng cho đồng hồ. Nguyên nhân là do chứng chỉ mà các trang web dùng để tá»± nhận dạng chỉ có hiệu lá»±c trong khoảng thá»i gian cụ thể. Vì đồng hồ trên thiết bị của bạn không đúng nên Chromium không thể xác minh các chứng chỉ này.</translation>
<translation id="8740359287975076522">Không thể tìm thấy &lt;abbr id="dnsDefinition"&gt;địa chỉ DNS&lt;/abbr&gt; của <ph name="HOST_NAME" />. Äang chẩn Ä‘oán sá»± cố.</translation>
<translation id="8759274551635299824">Thẻ này đã hết hạn</translation>
+<translation id="8761567432415473239">Gần đây, Duyệt web an toàn của Google <ph name="BEGIN_LINK" />tìm thấy chương trình độc hại<ph name="END_LINK" /> trên trang <ph name="SITE" />.</translation>
<translation id="8790007591277257123">&amp;Làm lại xóa</translation>
<translation id="8800988563907321413">Äá» xuất ở gần bạn xuất hiện ở đây</translation>
<translation id="8820817407110198400">Dấu trang</translation>
@@ -833,29 +908,30 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="8870413625673593573">Các tab đã Äóng gần đây</translation>
<translation id="8874824191258364635">Nhập số thẻ hợp lệ</translation>
<translation id="8876793034577346603">Không thể phân tích cú pháp cấu hình mạng.</translation>
-<translation id="8877192140621905067">Sau khi bạn xác nhận, chi tiết thẻ của bạn sẽ được chia sẻ với trang web này</translation>
<translation id="8889402386540077796">Màu sắc</translation>
<translation id="8891727572606052622">Chế độ proxy không hợp lệ.</translation>
<translation id="889901481107108152">Rất tiếc, thá»­ nghiệm này không sẵn có trên ná»n tảng của bạn.</translation>
<translation id="8903921497873541725">Phóng to</translation>
<translation id="8931333241327730545">Bạn có muốn lưu thẻ này vào Tài khoản Google của mình không?</translation>
<translation id="8932102934695377596">Äồng hồ của bạn chạy chậm</translation>
-<translation id="8954894007019320973">(Tiếp tục)</translation>
<translation id="8971063699422889582">Chứng chỉ của máy chủ đã hết hạn.</translation>
<translation id="8986494364107987395">Tự động gửi số liệu thống kê vỠviệc sử dụng và báo cáo sự cố cho Google</translation>
-<translation id="8987927404178983737">Tháng</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Trang web sắp truy cập chứa chương trình độc hại</translation>
+<translation id="8997023839087525404">Máy chủ đã Ä‘Æ°a ra chứng chỉ không được tiết lá»™ công khai theo chính sách Tính minh bạch của chứng chỉ. Äây là yêu cầu đối vá»›i má»™t số chứng chỉ, để đảm bảo chúng đáng tin cậy và giúp chống lại những kẻ tấn công.</translation>
<translation id="9001074447101275817">Proxy <ph name="DOMAIN" /> yêu cầu tên ngÆ°á»i dùng và mật khẩu.</translation>
+<translation id="9005998258318286617">Không tải được tài liệu PDF.</translation>
<translation id="901974403500617787">Chỉ chủ sở hữu mới có thể đặt cỠáp dụng cho toàn hệ thống: <ph name="OWNER_EMAIL" />.</translation>
+<translation id="9020200922353704812">Yêu cầu địa chỉ thanh toán của thẻ</translation>
<translation id="9020542370529661692">Trang này đã được dịch sang <ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">Lỗi bảo mật</translation>
<translation id="9038649477754266430">Sử dụng dịch vụ gợi ý để tải trang nhanh hơn</translation>
<translation id="9039213469156557790">Ngoài ra, trang này bao gồm các tài nguyên khác không an toàn. Những tài nguyên này có thể bị ngÆ°á»i khác xem khi Ä‘ang gá»­i và có thể bị kẻ tấn công sá»­a đổi nhằm thay đổi hành vi của trang.</translation>
-<translation id="9040185888511745258">Những kẻ tấn công trên trang <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> có thể đánh lừa bạn cài đặt các chương trình ảnh hưởng đến trải nghiệm duyệt web của bạn (ví dụ: bằng cách thay đổi trang chủ của bạn hoặc hiển thị thêm quảng cáo trên các trang bạn truy cập).</translation>
+<translation id="9049981332609050619">Bạn đã cố truy cập vào <ph name="DOMAIN" />, nhưng máy chủ cho biết chứng chỉ không hợp lệ.</translation>
<translation id="9050666287014529139">Cụm mật khẩu</translation>
<translation id="9065203028668620118">Chỉnh sửa</translation>
<translation id="9068849894565669697">Chá»n màu</translation>
+<translation id="9069693763241529744">Bị một tiện ích chặn</translation>
<translation id="9076283476770535406">Trang web có thể có ná»™i dung ngÆ°á»i lá»›n</translation>
<translation id="9078964945751709336">Yêu cầu thêm thông tin</translation>
<translation id="9103872766612412690"><ph name="SITE" /> thÆ°á»ng sá»­ dụng mã hóa để bảo vệ thông tin của bạn. Khi Chromium cố gắng kết nối vá»›i <ph name="SITE" /> tại thá»i Ä‘iểm này, trang web đã gá»­i lại thông tin đăng nhập không chính xác và bất thÆ°á»ng. Äiá»u này có thể xảy ra khi kẻ tấn công Ä‘ang cố gắng giả mạo là <ph name="SITE" /> hoặc màn hình đăng nhập Wi-Fi đã làm gián Ä‘oạn kết nối. Thông tin của bạn vẫn an toàn do Chromium đã ngừng kết nối trÆ°á»›c khi bất kỳ dữ liệu nào được trao đổi.</translation>
@@ -864,16 +940,21 @@ Lưu ý! Chế độ ẩn danh <ph name="SHORTCUT_KEY" /> có thể hữu ích v
<translation id="9148507642005240123">&amp;Hoàn tác chỉnh sửa</translation>
<translation id="9154194610265714752">Äã cập nhật</translation>
<translation id="9157595877708044936">Äang thiết lập...</translation>
+<translation id="9169664750068251925">Luôn chặn trên trang web này</translation>
<translation id="9170848237812810038">H&amp;oàn tác</translation>
<translation id="917450738466192189">Chứng chỉ của máy chủ không hợp lệ.</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> tùy chá»n giao hàng khác}other{<ph name="SHIPPING_OPTION_PREVIEW" /> và <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> tùy chá»n giao hàng khác}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> sử dụng giao thức không được hỗ trợ.</translation>
<translation id="9205078245616868884">Dữ liệu của bạn đã được mã hóa bằng cụm mật khẩu đồng bộ hóa. Nhập cụm mật khẩu đó để bắt đầu đồng bộ hóa.</translation>
<translation id="9207861905230894330">Không thêm được bài viết.</translation>
+<translation id="9219103736887031265">Hình ảnh</translation>
<translation id="933612690413056017">Không có kết nối Internet</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">XÓA BIỂU MẪU</translation>
<translation id="939736085109172342">Thư mục mới</translation>
<translation id="941721044073577244">Có vẻ nhÆ° bạn không có quyá»n truy cập trang web này</translation>
<translation id="969892804517981540">Phiên bản Chính thức</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{Không có}=1{1 mục}other{# mục}}</translation>
<translation id="988159990683914416">Phiên bản dành cho Nhà phát triển</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_zh-CN.xtb b/chromium/components/strings/components_strings_zh-CN.xtb
index 89647697416..e5280d6b7d9 100644
--- a/chromium/components/strings/components_strings_zh-CN.xtb
+++ b/chromium/components/strings/components_strings_zh-CN.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">顺时针旋转</translation>
<translation id="1038842779957582377">未知å称</translation>
<translation id="1050038467049342496">关闭其他应用</translation>
-<translation id="1053591932240354961">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站å‘é€çš„凭æ®æ˜¯ä¹±ç ï¼ŒGoogle Chrome 无法处ç†ã€‚网络错误和攻击行为通常是暂时的,因此,此网页ç¨åŽå¯èƒ½å°±ä¼šæ¢å¤æ­£å¸¸ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="1055184225775184556">撤消添加(&amp;U)</translation>
<translation id="10614374240317010">一律ä¸ä¿å­˜</translation>
<translation id="106701514854093668">æ¡Œé¢ä¹¦ç­¾</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">策略缓存良好</translation>
<translation id="113188000913989374"><ph name="SITE" /> 显示:</translation>
<translation id="1132774398110320017">Chrome自动填充设置…</translation>
+<translation id="1150979032973867961">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />;您计算机的æ“作系统ä¸ä¿¡ä»»å…¶å®‰å…¨è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
+<translation id="1151972924205500581">需è¦å¯†ç </translation>
<translation id="1152921474424827756">访问<ph name="URL" />的<ph name="BEGIN_LINK" />缓存副本<ph name="END_LINK" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> æ„外终止了连接。</translation>
<translation id="1161325031994447685">é‡æ–°è¿žæŽ¥åˆ° Wi-Fi 网络</translation>
+<translation id="1165039591588034296">错误</translation>
<translation id="1175364870820465910">打å°(&amp;P)...</translation>
<translation id="1181037720776840403">删除</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />è‡ªåŠ¨å‘ Google 报告<ph name="END_WHITEPAPER_LINK" />å¯èƒ½å‡ºçŽ°çš„安全事件的详细信æ¯ã€‚<ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">æ¥è‡ªè¯¥ç½‘站的更多内容</translation>
<translation id="1206967143813997005">åˆå§‹ç­¾åä¸æ­£ç¡®</translation>
<translation id="1209206284964581585">æš‚æ—¶éšè—</translation>
+<translation id="121201262018556460">您å°è¯•è®¿é—®çš„是 <ph name="DOMAIN" />,但是æœåŠ¡å™¨å‡ºç¤ºçš„è¯ä¹¦åŒ…å«å¼±å¯†é’¥ã€‚攻击者å¯èƒ½å·²ç»ç ´è§£äº†ç§é’¥ï¼Œå› æ­¤è¿™å¯èƒ½å¹¶ä¸æ˜¯æ‚¨æƒ³è¦è®¿é—®çš„æœåŠ¡å™¨ï¼ˆæ‚¨å¯èƒ½æ­£åœ¨ä¸Žæ”»å‡»è€…进行通信)。</translation>
<translation id="1219129156119358924">系统安全</translation>
<translation id="1227224963052638717">未知政策。</translation>
<translation id="1227633850867390598">éšè—值</translation>
<translation id="1228893227497259893">实体标识符有误</translation>
<translation id="1232569758102978740">无标题</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />(已åŒæ­¥ï¼‰</translation>
<translation id="1263231323834454256">阅读清å•</translation>
<translation id="1264126396475825575">崩溃报告获å–时间:<ph name="CRASH_TIME" />(该报告尚未上传或已被忽略)</translation>
+<translation id="1281526147609854549">é¢å‘者:<ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">å±é™©å†…容已被拦截</translation>
<translation id="1285320974508926690">一律ä¸ç¿»è¯‘此网站</translation>
<translation id="129553762522093515">最近关闭的标签页</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />å°è¯•æ¸…除 Cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">以下å„æ–¹<ph name="BEGIN_EMPHASIS" />å¯èƒ½ä»ä¼šçœ‹åˆ°<ph name="END_EMPHASIS" />您的活动:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />您访问的网站
+ <ph name="LIST_ITEM" />您的雇主或您所在的学校
+ <ph name="LIST_ITEM" />您的互è”网æœåŠ¡æ供商
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">注册域:</translation>
<translation id="1340482604681802745">å–货地å€</translation>
<translation id="1344211575059133124">您似乎需è¦èŽ·å¾—许å¯ï¼Œç„¶åŽæ‰èƒ½è®¿é—®æ­¤ç½‘ç«™</translation>
<translation id="1344588688991793829">Chromium自动填充设置…</translation>
+<translation id="1348198688976932919">您è¦è®¿é—®çš„网站包å«å±é™©åº”用</translation>
<translation id="1374468813861204354">建议</translation>
<translation id="1375198122581997741">关于版本</translation>
<translation id="1377321085342047638">å¡å·</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> 未å‘é€ä»»ä½•æ•°æ®ã€‚</translation>
<translation id="1407135791313364759">全部打开</translation>
<translation id="1413809658975081374">éšç§è®¾ç½®é”™è¯¯</translation>
+<translation id="14171126816530869">ä½äºŽ<ph name="LOCALITY" />çš„<ph name="ORGANIZATION" />的身份已通过了<ph name="ISSUER" />的验è¯ã€‚</translation>
<translation id="1426410128494586442">是</translation>
<translation id="1430915738399379752">打å°</translation>
-<translation id="1442912890475371290">å°è¯•<ph name="BEGIN_LINK" />访问 <ph name="DOMAIN" /> 中的网页<ph name="END_LINK" />的行为已é­é˜»æ­¢ã€‚</translation>
-<translation id="1491663344921578213">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站使用了è¯ä¹¦é”定功能。网络错误和攻击行为通常是暂时的,因此,此网页ç¨åŽå¯èƒ½å°±ä¼šæ¢å¤æ­£å¸¸ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ç§ä»˜æ¬¾æ–¹å¼}other{<ph name="PAYMENT_METHOD_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> ç§ä»˜æ¬¾æ–¹å¼}}</translation>
<translation id="1506687042165942984">显示为此页é¢ä¿å­˜çš„已知过时副本。</translation>
<translation id="1517433312004943670">å¿…é¡»æ供电è¯å·ç </translation>
<translation id="1519264250979466059">构建日期</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">å¿…é¡»å¯ç”¨ JavaScript æ‰èƒ½ä½¿ç”¨æ­¤åŠŸèƒ½ã€‚</translation>
<translation id="1555130319947370107">è“色</translation>
<translation id="1559528461873125649">ä¸å­˜åœ¨æ­¤ç±»æ–‡ä»¶æˆ–目录</translation>
-<translation id="1559572115229829303">&lt;p&gt;您设备的日期和时间(<ph name="DATE_AND_TIME" />)ä¸æ­£ç¡®ï¼Œå› æ­¤æ— æ³•ä¸Ž <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§å¯†è¿žæŽ¥ã€‚&lt;/p&gt;
-
- &lt;p&gt;请在&lt;strong&gt;设置&lt;/strong&gt;应用的&lt;strong&gt;通用&lt;/strong&gt;部分调整日期和时间。&lt;/p&gt;</translation>
<translation id="1583429793053364125">显示此网页时出了点问题。</translation>
<translation id="1592005682883173041">本地数æ®è®¿é—®æƒé™</translation>
+<translation id="1594030484168838125">选择</translation>
<translation id="161042844686301425">é’色</translation>
+<translation id="1620510694547887537">æ‘„åƒå¤´</translation>
<translation id="1629803312968146339">您希望 Chrome ä¿å­˜æ­¤ä¿¡ç”¨å¡å—?</translation>
<translation id="1639239467298939599">正在加载</translation>
<translation id="1640180200866533862">用户政策</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">网络é…置无效,无法导入。</translation>
<translation id="1644574205037202324">历å²è®°å½•</translation>
<translation id="1645368109819982629">åè®®ä¸å—支æŒ</translation>
+<translation id="1655462015569774233">{1,plural, =1{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯ <ph name="DOMAIN" />;其安全è¯ä¹¦å·²åœ¨æ˜¨å¤©è¿‡æœŸã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或有攻击者拦截了您的连接。计算机的时钟目å‰å·²è®¾ä¸º <ph name="CURRENT_DATE" />,该设置是å¦æ­£ç¡®ï¼Ÿå¦‚æžœä¸æ­£ç¡®ï¼Œè¯·æ›´æ­£ç³»ç»Ÿçš„时钟,然åŽåˆ·æ–°æ­¤é¡µé¢ã€‚}other{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯ <ph name="DOMAIN" />;其安全è¯ä¹¦å·²åœ¨ # 天å‰è¿‡æœŸã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或有攻击者拦截了您的连接。计算机的时钟目å‰å·²è®¾ä¸º <ph name="CURRENT_DATE" />,该设置是å¦æ­£ç¡®ï¼Ÿå¦‚æžœä¸æ­£ç¡®ï¼Œè¯·æ›´æ­£ç³»ç»Ÿçš„时钟,然åŽåˆ·æ–°æ­¤é¡µé¢ã€‚}}</translation>
<translation id="1656489000284462475">å–è´§</translation>
<translation id="1663943134801823270">信用å¡é€‰é¡¹å’Œåœ°å€é€‰é¡¹å‡æ¥è‡ª Chrome。您å¯åœ¨<ph name="BEGIN_LINK" />设置<ph name="END_LINK" />中管ç†è¿™äº›é€‰é¡¹ã€‚</translation>
<translation id="1676269943528358898"><ph name="SITE" /> 通常会使用加密技术æ¥ä¿æŠ¤æ‚¨çš„ä¿¡æ¯ã€‚Google Chrome 此次å°è¯•è¿žæŽ¥åˆ° <ph name="SITE" /> 时,此网站å‘回了异常的错误凭æ®ã€‚è¿™å¯èƒ½æ˜¯å› ä¸ºæœ‰æ”»å‡»è€…在试图冒充 <ph name="SITE" />,或 Wi-Fi 登录å±å¹•ä¸­æ–­äº†æ­¤æ¬¡è¿žæŽ¥ã€‚请放心,您的信æ¯ä»ç„¶æ˜¯å®‰å…¨çš„,因为 Google Chrome 尚未进行任何数æ®äº¤æ¢ä¾¿åœæ­¢äº†è¿žæŽ¥ã€‚</translation>
-<translation id="168328519870909584"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的现有攻击者å¯èƒ½ä¼šè¯•å›¾é€šè¿‡åœ¨æ‚¨çš„设备上安装å±é™©åº”用æ¥çªƒå–或删除您的信æ¯ï¼ˆå¦‚照片ã€å¯†ç ã€é€šè®¯å†…容和信用å¡ä¿¡æ¯ï¼‰ã€‚</translation>
<translation id="168841957122794586">æœåŠ¡å™¨è¯ä¹¦åŒ…å«å¼±åŠ å¯†å¯†é’¥ã€‚</translation>
+<translation id="1706954506755087368">{1,plural, =1{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯ <ph name="DOMAIN" />;其安全è¯ä¹¦æ˜Žå¤©æ‰ä¼šç”Ÿæ•ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或有攻击者拦截了您的连接。}other{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯ <ph name="DOMAIN" />;其安全è¯ä¹¦ # 天åŽæ‰ä¼šç”Ÿæ•ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或有攻击者拦截了您的连接。}}</translation>
<translation id="1710259589646384581">æ“作系统</translation>
<translation id="1721312023322545264">您需è¦èŽ·å¾—<ph name="NAME" />的许å¯ï¼Œç„¶åŽæ‰èƒ½è®¿é—®æ­¤ç½‘ç«™</translation>
<translation id="1721424275792716183">标有“*â€çš„字段å‡æ˜¯å¿…填字段</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">ç¨åŽä¸‹è½½ç½‘页</translation>
<translation id="17513872634828108">ç›®å‰æ‰“开的标签页</translation>
<translation id="1753706481035618306">页ç </translation>
+<translation id="1763864636252898013">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />;您设备的æ“作系统ä¸ä¿¡ä»»å…¶å®‰å…¨è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />å°è¯•è¿è¡Œ Windows 网络诊断<ph name="END_LINK" />。</translation>
<translation id="1783075131180517613">请更新您的åŒæ­¥å¯†ç ã€‚</translation>
<translation id="1787142507584202372">您打开的标签页会显示在此处</translation>
+<translation id="1789575671122666129">弹出å¼çª—å£</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">æŒå¡äººå§“å</translation>
-<translation id="1803678881841855883">Google 安全æµè§ˆåŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />检测到æ¶æ„软件<ph name="END_LINK" />。平常éžå¸¸å®‰å…¨çš„网站有时也会感染æ¶æ„软件。这些æ¶æ„内容æ¥è‡ªå·²çŸ¥çš„æ¶æ„软件散布网站 <ph name="SUBRESOURCE_HOST" />。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="1806541873155184440">添加日期:<ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">请求或请求å‚数无效</translation>
<translation id="1826516787628120939">正在检查</translation>
<translation id="1834321415901700177">此网站包å«æœ‰å®³ç¨‹åº</translation>
+<translation id="1840414022444569775">æ­¤å¡å·å·²å­˜åœ¨</translation>
<translation id="1842969606798536927">付款</translation>
<translation id="1871208020102129563">代ç†å·²è®¾ç½®ä¸ºä½¿ç”¨å›ºå®šçš„代ç†æœåŠ¡å™¨ï¼Œè€Œä¸æ˜¯ .pac 脚本网å€ã€‚</translation>
<translation id="1871284979644508959">必填字段</translation>
<translation id="187918866476621466">打开å¯åŠ¨é¡µ</translation>
<translation id="1883255238294161206">收起列表</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 个地å€}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 个地å€}}</translation>
<translation id="1898423065542865115">过滤</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{无}=1{1 个网站}other{# 个网站}}</translation>
<translation id="194030505837763158">请访问<ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" />书签</translation>
<translation id="1973335181906896915">åºåˆ—化错误</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">由于已被 <ph name="POLICY_NAME" /> 替æ¢ï¼Œè¯¥æ”¿ç­–已忽略。</translation>
<translation id="2138201775715568214">正在查找附近的“实物网â€ç½‘页</translation>
<translation id="213826338245044447">移动设备书签</translation>
-<translation id="2148716181193084225">今天</translation>
+<translation id="2147827593068025794">åŽå°åŒæ­¥</translation>
<translation id="2154054054215849342">您的网域ä¸æ”¯æŒåŒæ­¥</translation>
<translation id="2154484045852737596">修改支付å¡</translation>
<translation id="2166049586286450108">完全的管ç†å‘˜è®¿é—®æƒé™</translation>
<translation id="2166378884831602661">此网站无法æ供安全连接</translation>
<translation id="2181821976797666341">政策</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 个地å€}other{# 个地å€}}</translation>
+<translation id="2187317261103489799">检测(默认)</translation>
<translation id="2202020181578195191">请输入有效的失效年份</translation>
<translation id="2212735316055980242">找ä¸åˆ°ç­–ç•¥</translation>
<translation id="2213606439339815911">正在获å–æ¡ç›®â€¦</translation>
+<translation id="2218879909401188352"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的现有攻击者å¯èƒ½ä¼šå®‰è£…å±é™©åº”用æ¥æŸå®³æ‚¨çš„设备ã€ç»™æ‚¨çš„手机å¸å•å¢žæ·»éšå«è´¹ç”¨æˆ–窃å–您的个人信æ¯ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">请使用<ph name="BEGIN_LINK" />诊断应用<ph name="END_LINK" />ä¿®å¤ç½‘络连接</translation>
<translation id="2239100178324503013">ç«‹å³å‘é€</translation>
<translation id="225207911366869382">适用于该政策的此值已弃用。</translation>
<translation id="2262243747453050782">HTTP 错误</translation>
+<translation id="2270484714375784793">电è¯å·ç </translation>
<translation id="2282872951544483773">无法使用的实验功能</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> 项内容}other{<ph name="ITEM_COUNT" /> 项内容}}</translation>
<translation id="2292556288342944218">您被ç¦æ­¢è®¿é—®äº’è”网</translation>
<translation id="230155334948463882">è¦ä½¿ç”¨æ–°ä¿¡ç”¨å¡å—?</translation>
-<translation id="2305919008529760154">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦é¢å‘æ¥æºæœ‰æ¬ºè¯ˆå«Œç–‘。出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> è¦æ±‚æ供用户å和密ç ã€‚</translation>
-<translation id="2318774815570432836">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站使用了 HSTS。网络错误和攻击行为通常是暂时的,因此,此网页ç¨åŽå¯èƒ½å°±ä¼šæ¢å¤æ­£å¸¸ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
+<translation id="2337852623177822836">设置由管ç†å‘˜æŽ§åˆ¶</translation>
<translation id="2354001756790975382">其他书签</translation>
+<translation id="2354430244986887761">Google 安全æµè§ˆåŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />å‘现了有害应用<ph name="END_LINK" />。</translation>
<translation id="2355395290879513365">攻击者å¯èƒ½èƒ½å¤Ÿçœ‹åˆ°æ‚¨æ­£åœ¨æ­¤ç½‘站上æµè§ˆçš„图片,并通过编辑这些图片让您å—骗。</translation>
+<translation id="2356070529366658676">询问</translation>
+<translation id="2359629602545592467">多ç§è´§å¸</translation>
<translation id="2359808026110333948">继续</translation>
<translation id="2365563543831475020">于 <ph name="CRASH_TIME" /> 获å–的崩溃报告未上传</translation>
<translation id="2367567093518048410">级别</translation>
-<translation id="2371153335857947666">{1,plural, =1{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦å·²åœ¨æ˜¨å¤©è¿‡æœŸã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。计算机的时钟目å‰å·²è®¾ä¸º <ph name="CURRENT_DATE" />,该设置是å¦æ­£ç¡®ï¼Ÿå¦‚æžœä¸æ­£ç¡®ï¼Œè¯·æ›´æ­£ç³»ç»Ÿçš„时钟,然åŽåˆ·æ–°æ­¤ç½‘é¢ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。}other{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦å·²åœ¨ # 天å‰è¿‡æœŸã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。计算机的时钟目å‰å·²è®¾ä¸º <ph name="CURRENT_DATE" />,该设置是å¦æ­£ç¡®ï¼Ÿå¦‚æžœä¸æ­£ç¡®ï¼Œè¯·æ›´æ­£ç³»ç»Ÿçš„时钟,然åŽåˆ·æ–°æ­¤ç½‘é¢ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。}}</translation>
<translation id="237718015863234333">没有å¯ç”¨çš„ç•Œé¢å¤‡é€‰é¡¹</translation>
<translation id="2384307209577226199">在ä¼ä¸šçŽ¯å¢ƒä¸­é»˜è®¤å®žæ–½</translation>
<translation id="2386255080630008482">æœåŠ¡å™¨çš„è¯ä¹¦å·²æ’¤æ¶ˆã€‚</translation>
<translation id="2392959068659972793">显示未设定值的政策</translation>
<translation id="239429038616798445">该é€è´§æ–¹å¼ä¸å¯ç”¨ã€‚请å¦é€‰ä¸€ç§æ–¹å¼ã€‚</translation>
<translation id="2396249848217231973">撤消删除(&amp;U)</translation>
-<translation id="2460160116472764928">Google 安全æµè§ˆåŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />检测到æ¶æ„软件<ph name="END_LINK" />。平常éžå¸¸å®‰å…¨çš„网站有时也会感染æ¶æ„软件。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
+<translation id="2413528052993050574">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />;其安全è¯ä¹¦å¯èƒ½å·²è¢«æ’¤æ¶ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
<translation id="2463739503403862330">å¡«å……</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />è¿è¡Œç½‘络诊断<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">æœç´¢ç½‘å€æ— æ•ˆã€‚</translation>
+<translation id="2482878487686419369">通知</translation>
<translation id="2491120439723279231">æœåŠ¡å™¨è¯ä¹¦ä¸­åŒ…å«é”™è¯¯ã€‚</translation>
<translation id="2495083838625180221">JSON 解æžå™¨</translation>
<translation id="2495093607237746763">选中åŽï¼ŒChromium 会将您的信用å¡å‰¯æœ¬å­˜å‚¨åœ¨æ­¤è®¾å¤‡ä¸Šï¼Œä»¥åŠ å¿«è¡¨å•å¡«å†™é€Ÿåº¦ã€‚</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">返回</translation>
<translation id="2515629240566999685">检查您所在区域的网络信å·</translation>
<translation id="2516305470678292029">ç•Œé¢å¤‡é€‰é¡¹</translation>
+<translation id="2539524384386349900">检测</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> å‘é€çš„å“应无效。</translation>
-<translation id="2552545117464357659">å¾€åŽ</translation>
<translation id="2556876185419854533">撤消修改(&amp;U)</translation>
<translation id="2587730715158995865">æ¥è‡ª<ph name="ARTICLE_PUBLISHER" />。阅读这篇报é“以åŠå…¶ä»– <ph name="OTHER_ARTICLE_COUNT" /> 篇报é“。</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">本文档设置了密ç ä¿æŠ¤ï¼Œè¯·è¾“入密ç ã€‚</translation>
<translation id="2609632851001447353">其他å˜ä½“</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{æ— }=1{1 个应用($1)}=2{2 个应用($1ã€$2)}other{# 个应用($1ã€$2,$3)}}</translation>
<translation id="2625385379895617796">您的时钟快了</translation>
<translation id="2639739919103226564">状æ€ï¼š</translation>
+<translation id="2649204054376361687"><ph name="COUNTRY" /><ph name="CITY" /></translation>
<translation id="2650446666397867134">访问文件é­æ‹’</translation>
<translation id="2653659639078652383">æ交</translation>
<translation id="2666117266261740852">关闭其他标签页或应用</translation>
+<translation id="2670429602441959756">此网页包å«å°šä¸å—虚拟现实模å¼æ”¯æŒçš„功能。å³å°†é€€å‡ºâ€¦</translation>
<translation id="2674170444375937751">确定è¦ä»ŽåŽ†å²è®°å½•ä¸­åˆ é™¤è¿™äº›é¡µå—?</translation>
<translation id="2677748264148917807">离开</translation>
-<translation id="269990154133806163">该æœåŠ¡å™¨æ供的è¯ä¹¦æœªæ ¹æ®è¯ä¹¦é€æ˜Žåº¦æ”¿ç­–公开披露。部分è¯ä¹¦å¿…须符åˆè¿™é¡¹è§„定,以确ä¿è¯ä¹¦å€¼å¾—信任,并ä¿æŠ¤ç”¨æˆ·ä¸ä¼šé­åˆ°æ”»å‡»ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="2702801445560668637">读å–列表</translation>
<translation id="2704283930420550640">值ä¸ç¬¦åˆæ ¼å¼è¦æ±‚。</translation>
<translation id="2704951214193499422">Chromium ç›®å‰æ— æ³•ç¡®è®¤æ‚¨çš„信用å¡ï¼Œè¯·ç¨åŽé‡è¯•ã€‚</translation>
<translation id="2705137772291741111">无法读å–此网站的已ä¿å­˜ï¼ˆç¼“存)副本。</translation>
<translation id="2709516037105925701">自动填充</translation>
-<translation id="2712118517637785082">您å°è¯•è¿žæŽ¥åˆ° <ph name="DOMAIN" />,但æœåŠ¡å™¨æ供的è¯ä¹¦å·²è¢«å…¶é¢å‘者撤消。在这ç§æƒ…况下,请勿信任æœåŠ¡å™¨æ供的安全凭æ®ã€‚您å¯èƒ½æ­£åœ¨ä¸Žæ”»å‡»è€…进行通信。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="2712173769900027643">请求批准</translation>
<translation id="2713444072780614174">白色</translation>
<translation id="2720342946869265578">附近</translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">缺少设备记录</translation>
<translation id="2784949926578158345">连接已é‡ç½®ã€‚</translation>
<translation id="2794233252405721443">网站已被å±è”½</translation>
+<translation id="2799020568854403057">您è¦è®¿é—®çš„网站包å«æœ‰å®³åº”用</translation>
+<translation id="2803306138276472711">Google安全æµè§ˆåŠŸèƒ½æœ€è¿‘在<ph name="SITE" />上<ph name="BEGIN_LINK" />检测到了æ¶æ„软件<ph name="END_LINK" />。平常éžå¸¸å®‰å…¨çš„网站有时也会感染æ¶æ„软件。</translation>
<translation id="2824775600643448204">地å€å’Œæœç´¢æ </translation>
<translation id="2826760142808435982">该连接使用 <ph name="CIPHER" /> 进行加密和身份验è¯ï¼Œå¹¶ä½¿ç”¨ <ph name="KX" /> 作为密钥交æ¢æœºåˆ¶ã€‚</translation>
<translation id="2835170189407361413">清除表å•</translation>
+<translation id="2856444702002559011">攻击者å¯èƒ½ä¼šè¯•å›¾ä»Ž <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 窃å–您的信æ¯ï¼ˆä¾‹å¦‚:密ç ã€é€šè®¯å†…容或信用å¡ä¿¡æ¯ï¼‰ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">ä¸é‡æ–°åŠ è½½</translation>
<translation id="2900469785430194048">Google Chrome 在å°è¯•æ˜¾ç¤ºæ­¤ç½‘页时内存ä¸è¶³ã€‚</translation>
<translation id="2909946352844186028">检测到了网络å˜åŒ–。</translation>
<translation id="2916038427272391327">关闭其他程åº</translation>
<translation id="2922350208395188000">无法核实æœåŠ¡å™¨è¯ä¹¦ã€‚</translation>
<translation id="2928905813689894207">å¸å•é‚®å¯„地å€</translation>
+<translation id="2941952326391522266">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />;其安全è¯ä¹¦æ¥è‡ª<ph name="DOMAIN2" />。出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
<translation id="2948083400971632585">您å¯ä»¥åœ¨è®¾ç½®é¡µé¢ä¸­åœç”¨ä»»ä½•é’ˆå¯¹æŸä¸ªè¿žæŽ¥é…置的代ç†ã€‚</translation>
<translation id="2955913368246107853">关闭查找æ </translation>
<translation id="2958431318199492670">网络é…ç½®ä¸ç¬¦åˆ ONC 标准。无法导入é…置的æŸäº›éƒ¨åˆ†ã€‚</translation>
-<translation id="29611076221683977">攻击者å¯èƒ½ä¼šè¯•å›¾é€šè¿‡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在您的 Mac 上安装å±é™©ç¨‹åºï¼Œä»¥çªƒå–或删除您的信æ¯ï¼ˆå¦‚照片ã€å¯†ç ã€é€šè®¯å†…容和信用å¡ä¿¡æ¯ï¼‰ã€‚</translation>
<translation id="2966678944701946121">到期日期:<ph name="EXPIRATION_DATE_ABBR" />;添加日期:<ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">è¦å»ºç«‹å®‰å…¨è¿žæŽ¥ï¼Œæ‚¨çš„时钟设置必须正确。这是因为,网站用于è¯æ˜Žèº«ä»½çš„è¯ä¹¦ä»…在特定时间段有效。由于您设备的时钟ä¸æ­£ç¡®ï¼Œå› æ­¤ Google Chrome 无法验è¯è¿™äº›è¯ä¹¦ã€‚</translation>
<translation id="2972581237482394796">é‡åš(&amp;R)</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">请输入有效的é€è´§åœ°å€</translation>
<translation id="2986368408720340940">该å–货方å¼ä¸å¯ç”¨ã€‚请å¦é€‰ä¸€ç§æ–¹å¼ã€‚</translation>
<translation id="2991174974383378012">与网站分享</translation>
+<translation id="2991571918955627853">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站使用了 HSTS。网络错误和攻击通常是暂时的,因此,此网页ç¨åŽå¯èƒ½ä¼šæ¢å¤æ­£å¸¸ã€‚</translation>
<translation id="3005723025932146533">显示已ä¿å­˜çš„版本</translation>
<translation id="3008447029300691911">输入“<ph name="CREDIT_CARD" />â€çš„银行å¡éªŒè¯ç  (CVC)。在您确认åŽï¼Œæ‚¨çš„信用å¡è¯¦æƒ…将与此网站共享。</translation>
<translation id="3010559122411665027">列表æ¡ç›®â€œ<ph name="ENTRY_INDEX" />â€ï¼š<ph name="ERROR" /></translation>
+<translation id="301521992641321250">已被自动ç¦æ­¢</translation>
<translation id="3024663005179499861">策略类型有误</translation>
<translation id="3032412215588512954">è¦é‡æ–°åŠ è½½è¯¥ç½‘ç«™å—?</translation>
<translation id="3037605927509011580">喔唷,崩溃啦ï¼</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{在已åŒæ­¥çš„设备上至少有 1 项内容}=1{1 项内容(在已åŒæ­¥çš„设备上还有更多内容)}other{# 项内容(在已åŒæ­¥çš„设备上还有更多内容)}}</translation>
<translation id="3041612393474885105">è¯ä¹¦ä¿¡æ¯</translation>
<translation id="3063697135517575841">Chrome ç›®å‰æ— æ³•ç¡®è®¤æ‚¨çš„信用å¡ï¼Œè¯·ç¨åŽé‡è¯•ã€‚</translation>
<translation id="3064966200440839136">å°†è¦é€€å‡ºéšèº«æ¨¡å¼ï¼Œä»¥ä¾¿é€šè¿‡å¤–部应用付款。是å¦ç»§ç»­ï¼Ÿ</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{æ— }=1{1 个密ç }other{# 个密ç }}</translation>
<translation id="3093245981617870298">您处于离线状æ€ã€‚</translation>
<translation id="3105172416063519923">资产 ID:</translation>
<translation id="3109728660330352905">您未获授æƒï¼Œæ— æ³•æŸ¥çœ‹æ­¤ç½‘页。</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />å°è¯•è¿è¡Œç½‘络连接诊断<ph name="END_LINK" />。</translation>
<translation id="3145945101586104090">无法对å“应解ç </translation>
<translation id="3150653042067488994">æœåŠ¡å™¨ä¸´æ—¶é”™è¯¯</translation>
@@ -247,14 +277,18 @@
<translation id="3167968892399408617">在您关闭所有éšèº«æ ‡ç­¾é¡µåŽï¼Œæ‚¨åœ¨è¿™äº›æ ‡ç­¾é¡µä¸­æŸ¥çœ‹çš„网页ä¸ä¼šåœ¨æµè§ˆå™¨åŽ†å²è®°å½•ã€Cookie 存储区或æœç´¢è®°å½•ä¸­ç•™ä¸‹ä»»ä½•ç—•è¿¹ã€‚ä¸è¿‡ï¼Œæ‚¨ä¸‹è½½çš„所有文件或创建的书签å‡ä¼šä¿ç•™ä¸‹æ¥ã€‚</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">å²›</translation>
+<translation id="317583078218509884">新的网站æƒé™è®¾ç½®ä¼šåœ¨é‡æ–°åŠ è½½é¡µé¢åŽç”Ÿæ•ˆã€‚</translation>
<translation id="3176929007561373547">请检查您的代ç†æœåŠ¡å™¨è®¾ç½®æˆ–与网络管ç†å‘˜è”系,以确ä¿ä»£ç†æœåŠ¡å™¨æ­£å¸¸è¿è¡Œã€‚如果您认为自己ä¸éœ€è¦ä½¿ç”¨ä»£ç†æœåŠ¡å™¨ï¼Œè¯·æ‰§è¡Œä»¥ä¸‹æ“作:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">以éšèº«æ¨¡å¼æ‰“开网页</translation>
-<translation id="3202578601642193415">最åŽ</translation>
+<translation id="320323717674993345">å–消付款</translation>
<translation id="3207960819495026254">已加书签</translation>
+<translation id="3225919329040284222">æœåŠ¡å™¨æ供的è¯ä¹¦ä¸Žå†…置预期è¯ä¹¦ä¸åŒ¹é…。这些预期è¯ä¹¦æ˜¯é’ˆå¯¹æŸäº›é«˜å®‰å…¨æ€§ç½‘ç«™æ供的,以便为您æä¾›ä¿æŠ¤ã€‚</translation>
<translation id="3226128629678568754">按“é‡æ–°åŠ è½½â€æŒ‰é’®ï¼Œé‡æ–°æ交加载该网页所需的数æ®ã€‚</translation>
+<translation id="3227137524299004712">麦克风</translation>
<translation id="3228969707346345236">此网页已ç»æ˜¯<ph name="LANGUAGE" />网页,因此无法翻译。</translation>
<translation id="323107829343500871">输入“<ph name="CREDIT_CARD" />â€çš„银行å¡éªŒè¯ç  (CVC)</translation>
+<translation id="3234666976984236645">始终检测此网站上的é‡è¦å†…容</translation>
<translation id="3254409185687681395">为此页添加书签</translation>
<translation id="3270847123878663523">撤消顺åºè°ƒæ•´(&amp;U)</translation>
<translation id="3282497668470633863">添加æŒå¡äººå§“å</translation>
@@ -268,42 +302,48 @@
<translation id="3340978935015468852">设置</translation>
<translation id="3345135638360864351">无法将您访问此网站的请求å‘é€ç»™<ph name="NAME" />,请é‡è¯•ã€‚</translation>
<translation id="3355823806454867987">更改代ç†æœåŠ¡å™¨è®¾ç½®...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />ä¸ä¼šä¿å­˜<ph name="END_EMPHASIS" />以下信æ¯ï¼š
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />您的æµè§ˆè®°å½•
+ <ph name="LIST_ITEM" />Cookie 和网站数æ®
+ <ph name="LIST_ITEM" />在表å•ä¸­å¡«å†™çš„ä¿¡æ¯
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">时钟错误</translation>
-<translation id="337311366426640088">å¦å¤–还有 <ph name="ITEM_COUNT" /> 项…</translation>
<translation id="337363190475750230">å·²å–消é…ç½®</translation>
<translation id="3377188786107721145">策略解æžé”™è¯¯</translation>
<translation id="3380365263193509176">未知错误</translation>
<translation id="3380864720620200369">客户端 ID:</translation>
<translation id="3391030046425686457">递é€åœ°å€</translation>
<translation id="3395827396354264108">å–货方å¼</translation>
-<translation id="340013220407300675">攻击者å¯èƒ½ä¼šè¯•å›¾ä»Ž<ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />窃å–您的信æ¯ï¼ˆä¾‹å¦‚:密ç ã€é€šè®¯å†…容或信用å¡ä¿¡æ¯ï¼‰ã€‚</translation>
<translation id="3422248202833853650">请å°è¯•é€€å‡ºå…¶ä»–程åºä»¥é‡Šæ”¾å†…存。</translation>
<translation id="3422472998109090673">ç›®å‰æ— æ³•è®¿é—® <ph name="HOST_NAME" />。</translation>
+<translation id="3427092606871434483">å…许(默认)</translation>
<translation id="3427342743765426898">æ¢å¤ä¿®æ”¹(&amp;R)</translation>
<translation id="3431636764301398940">将此å¡çš„ä¿¡æ¯ä¿å­˜åˆ°è¯¥è®¾å¤‡</translation>
<translation id="3435896845095436175">å¯ç”¨</translation>
<translation id="3447661539832366887">此设备的所有者已关闭æ龙游æˆã€‚</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">抓å–时间间隔:</translation>
<translation id="3462200631372590220">éšè—详情</translation>
<translation id="3467763166455606212">必须输入æŒå¡äººå§“å</translation>
<translation id="3478058380795961209">到期月份</translation>
<translation id="3479539252931486093">ä¸åº”该出现这ç§æƒ…况?请<ph name="BEGIN_LINK" />告诉我们<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">以åŽå†è¯´</translation>
-<translation id="348000606199325318">崩溃 ID:<ph name="CRASH_LOCAL_ID" />(æœåŠ¡å™¨ ID:<ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">我们暂时无法与您父æ¯å–å¾—è”系,请é‡è¯•ã€‚</translation>
<translation id="3528171143076753409">æœåŠ¡å™¨çš„è¯ä¹¦ä¸å—信任。</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{在已åŒæ­¥çš„设备上至少有 1 项内容}=1{1 项内容(在已åŒæ­¥çš„设备上还有更多内容)}other{# 项内容(在已åŒæ­¥çš„设备上还有更多内容)}}</translation>
<translation id="3539171420378717834">在此设备上ä¿å­˜æ­¤ä¿¡ç”¨å¡çš„副本</translation>
<translation id="3542684924769048008">使用以下项的密ç ï¼š</translation>
+<translation id="3545341443414427877">您设备的日期和时间(<ph name="DATE_AND_TIME" />)ä¸æ­£ç¡®ï¼Œå› æ­¤æ— æ³•ä¸Ž <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§å¯†è¿žæŽ¥ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">使用您自己的åŒæ­¥å¯†ç åŠ å¯†æ‰€æœ‰å·²åŒæ­¥æ•°æ®</translation>
-<translation id="3549761410225185768">还有 <ph name="NUM_TABS_MORE" /> 个…</translation>
-<translation id="3555561725129903880">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦æ¥è‡ª <ph name="DOMAIN2" />。出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="3556433843310711081">您的管ç†å‘˜å¯ä¸ºæ‚¨å–消å±è”½æ­¤ç½‘ç«™</translation>
<translation id="3566021033012934673">您的连接ä¸æ˜¯ç§å¯†è¿žæŽ¥</translation>
+<translation id="3569145463236695319">&lt;p&gt;您设备的日期和时间(<ph name="DATE_AND_TIME" />)ä¸æ­£ç¡®ï¼Œå› æ­¤æ— æ³•ä¸Ž <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§å¯†è¿žæŽ¥ã€‚&lt;/p&gt;
+
+ &lt;p&gt;请在&lt;strong&gt;设置&lt;/strong&gt;应用的&lt;strong&gt;常规&lt;/strong&gt;部分调整日期和时间。&lt;/p&gt;<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="COUNTRY" /><ph name="STATE" /><ph name="CITY" /></translation>
<translation id="3582930987043644930">添加å称</translation>
<translation id="3583757800736429874">æ¢å¤ç§»åŠ¨(&amp;R)</translation>
<translation id="3586931643579894722">éšè—详细信æ¯</translation>
-<translation id="3587482841069643663">全部</translation>
<translation id="3600246354004376029"><ph name="TITLE" />,<ph name="DOMAIN" />,<ph name="TIME" /></translation>
<translation id="3615877443314183785">请输入有效的失效日期</translation>
<translation id="36224234498066874">清除æµè§ˆæ•°æ®...</translation>
@@ -319,7 +359,6 @@
<translation id="3681007416295224113">è¯ä¹¦ä¿¡æ¯</translation>
<translation id="3690164694835360974">登录方å¼ä¸å®‰å…¨</translation>
<translation id="3693415264595406141">密ç ï¼š</translation>
-<translation id="3696411085566228381">æ— </translation>
<translation id="3704609568417268905"><ph name="TIME" /> - <ph name="BOOKMARKED" /> - <ph name="TITLE" /> - <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">正在加载...</translation>
<translation id="3712624925041724820">许å¯å·²ç”¨å°½</translation>
@@ -327,12 +366,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />检查代ç†æœåŠ¡å™¨ã€é˜²ç«å¢™å’Œ DNS é…ç½®<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">如果您了解自己将é¢ä¸´çš„安全风险,则å¯ä»¥åœ¨å±é™©ç¨‹åºè¢«æ¸…除å‰<ph name="BEGIN_LINK" />访问这个ä¸å®‰å…¨çš„网站<ph name="END_LINK" />。</translation>
<translation id="3739623965217189342">您å¤åˆ¶çš„链接</translation>
+<translation id="3744899669254331632">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站å‘é€äº† Chromium 无法处ç†çš„æ‚乱凭æ®ã€‚网络错误和攻击通常是暂时的,因此,此网页ç¨åŽå¯èƒ½ä¼šæ¢å¤æ­£å¸¸ã€‚</translation>
+<translation id="3748148204939282805"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻击者å¯èƒ½ä¼šè¯±éª—您åšä¸€äº›å±é™©çš„事情,例如安装软件或泄露您的个人信æ¯ï¼ˆå¦‚密ç ã€ç”µè¯å·ç æˆ–信用å¡ä¿¡æ¯ï¼‰ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">由于æœåŠ¡å™¨å‡ºé”™ï¼Œç¿»è¯‘失败。</translation>
<translation id="3759461132968374835">您最近未收到崩溃报告。崩溃报告åœç”¨æ—¶å‘生的崩溃ä¸ä¼šåœ¨æ­¤å¤„显示。</translation>
+<translation id="3778403066972421603">è¦å°†æ­¤å¡çš„ä¿¡æ¯ä¿å­˜åˆ°æ‚¨çš„ Google å¸å·ä¸­å’Œæ­¤è®¾å¤‡ä¸Šå—?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">失效日期:<ph name="EXPIRATION_YEAR" /> 年 <ph name="EXPIRATION_MONTH" /> 月</translation>
<translation id="382518646247711829">如果您使用代ç†æœåŠ¡å™¨â€¦</translation>
<translation id="3828924085048779000">密ç è¾“入字段ä¸èƒ½ç•™ç©ºã€‚</translation>
-<translation id="3845539888601087042">ç›®å‰æ˜¾ç¤ºçš„是您登录过的设备中的历å²è®°å½•ã€‚<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" />。</translation>
<translation id="385051799172605136">åŽé€€</translation>
<translation id="3858027520442213535">更新日期和时间</translation>
<translation id="3884278016824448484">设备标识符存在冲çª</translation>
@@ -340,11 +382,13 @@
<translation id="3886446263141354045">系统已将您想访问此网站的请求å‘é€ç»™<ph name="NAME" /></translation>
<translation id="3890664840433101773">添加电å­é‚®ä»¶åœ°å€</translation>
<translation id="3901925938762663762">此信用å¡å·²è¿‡æœŸ</translation>
-<translation id="3933571093587347751">{1,plural, =1{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦å¤§æ¦‚明天æ‰ä¼šç”Ÿæ•ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。}other{æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦å¤§æ¦‚ # 天åŽæ‰ä¼šç”Ÿæ•ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。}}</translation>
-<translation id="3934680773876859118">无法加载 PDF 文档</translation>
+<translation id="3945915738023014686">已上传的崩溃报告的 ID:<ph name="CRASH_ID" />(本地崩溃 ID:<ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">æ­¤æœåŠ¡å™¨æ— æ³•è¯å®žå®ƒå°±æ˜¯ <ph name="DOMAIN" /> - 它的安全è¯ä¹¦æ²¡æœ‰æŒ‡å®šä¸»é¢˜å¤‡ç”¨å称。这å¯èƒ½æ˜¯å› ä¸ºæŸé¡¹é…置有误或æŸä¸ªæ”»å‡»è€…拦截了您的连接。</translation>
<translation id="3963721102035795474">阅读器模å¼</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{æ— }=1{æ¥è‡ª 1 个网站}other{æ¥è‡ª # 个网站}}</translation>
<translation id="397105322502079400">正在计算...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> 已被å±è”½</translation>
+<translation id="3987940399970879459">å°äºŽ 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{附近有 1 个网页}other{附近有 # 个网页}}</translation>
<translation id="4021036232240155012">DNS 是一项网络æœåŠ¡ï¼Œå¯å°†ç½‘站的å称转译为其对应的互è”网地å€ã€‚</translation>
<translation id="4030383055268325496">撤消添加(&amp;U)</translation>
@@ -355,56 +399,63 @@
<translation id="4079302484614802869">代ç†é…置已设置为使用 .pac 脚本网å€ï¼Œè€Œä¸æ˜¯å›ºå®šçš„代ç†æœåŠ¡å™¨ã€‚</translation>
<translation id="4098354747657067197">您è¦è®¿é—®çš„网站是欺骗性网站</translation>
<translation id="4103249731201008433">设备åºåˆ—å·æ— æ•ˆ</translation>
+<translation id="410351446219883937">自动播放</translation>
<translation id="4103763322291513355">请访问 &lt;strong&gt;chrome:// 政策&lt;/strong&gt;,查看列入黑åå•çš„网å€åˆ—表以åŠæ‚¨çš„系统管ç†å‘˜å¼ºåˆ¶è¦æ±‚执行的其他政策。</translation>
-<translation id="4110615724604346410">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦æœ‰è¯¯ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="4115378294792113321">洋红色</translation>
+<translation id="4116663294526079822">在此网站上始终å…许</translation>
<translation id="4117700440116928470">政策范围ä¸å—支æŒã€‚</translation>
-<translation id="4118212371799607889">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›Chromium ä¸ä¿¡ä»»æœåŠ¡å™¨çš„安全è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="4129401438321186435">{COUNT,plural, =1{1 项其他内容}other{# 项其他内容}}</translation>
<translation id="4130226655945681476">检查网线ã€è°ƒåˆ¶è§£è°ƒå™¨å’Œè·¯ç”±å™¨</translation>
+<translation id="413544239732274901">了解详情</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">使用全局默认设置(检测)</translation>
+<translation id="4165986682804962316">网站设置</translation>
<translation id="4169947484918424451">您希望 Chromium ä¿å­˜æ­¤ä¿¡ç”¨å¡å—?</translation>
<translation id="4171400957073367226">验è¯ç­¾å无效</translation>
<translation id="4196861286325780578">æ¢å¤ç§»åŠ¨(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />检查防ç«å¢™å’Œé˜²ç—…毒é…ç½®<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{æ— }=1{1 个应用 ($1)}=2{2 个应用($1ã€$2)}other{# 个应用($1ã€$2,$3)}}</translation>
<translation id="4220128509585149162">崩溃</translation>
+<translation id="422022731706691852"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻击者å¯èƒ½ä¼šè¯•å›¾éª—您安装有æŸæµè§ˆä½“验的程åºï¼ˆä¾‹å¦‚更改您的主页或在您访问的网站上显示é¢å¤–的广告)。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />å°è¯•è¿è¡Œç½‘络诊断<ph name="END_LINK" />。</translation>
+<translation id="4235360514405112390">有效</translation>
<translation id="4250431568374086873">您与此网站之间建立的连接并éžå®Œå…¨å®‰å…¨</translation>
<translation id="4250680216510889253">å¦</translation>
<translation id="425582637250725228">系统å¯èƒ½ä¸ä¼šä¿å­˜æ‚¨æ‰€åšçš„更改。</translation>
<translation id="4258748452823770588">ç­¾å无效</translation>
+<translation id="4265872034478892965">您的管ç†å‘˜å…许</translation>
<translation id="4269787794583293679">(无用户å)</translation>
<translation id="4275830172053184480">é‡å¯æ‚¨çš„设备</translation>
<translation id="4280429058323657511">,到期日期:<ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google 安全æµè§ˆåŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />å‘现有害程åº<ph name="END_LINK" />。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="4300246636397505754">家长建议</translation>
<translation id="4304224509867189079">登录</translation>
-<translation id="432290197980158659">该æœåŠ¡å™¨æ供的è¯ä¹¦ä¸ç¬¦åˆå†…置的预期æ¡ä»¶ã€‚我们针对特定的高安全性网站内置了这些预期æ¡ä»¶ï¼Œä»¥ç¡®ä¿æ‚¨çš„æ•°æ®å®‰å…¨æ— è™žã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
+<translation id="4312866146174492540">å±è”½ï¼ˆé»˜è®¤ï¼‰</translation>
<translation id="4325863107915753736">找ä¸åˆ°æ–‡ç« </translation>
<translation id="4326324639298822553">请检查您的信用å¡åˆ°æœŸæ—¥æœŸï¼Œç„¶åŽé‡è¯•</translation>
<translation id="4331708818696583467">ä¸å®‰å…¨</translation>
<translation id="4356973930735388585">此网站上的攻击者å¯èƒ½ä¼šè¯•å›¾åœ¨æ‚¨çš„计算机上安装å±é™©ç¨‹åºï¼Œä»¥çªƒå–或删除您的信æ¯ï¼ˆä¾‹å¦‚:照片ã€å¯†ç ã€é€šè®¯å†…容和信用å¡ä¿¡æ¯ï¼‰ã€‚</translation>
<translation id="4372948949327679948">应使用<ph name="VALUE_TYPE" />值。</translation>
+<translation id="4377125064752653719">您å°è¯•è®¿é—®çš„是 <ph name="DOMAIN" />,但æœåŠ¡å™¨å‡ºç¤ºçš„è¯ä¹¦å·²è¢«å…¶é¢å‘者åŠé”€ã€‚这表明ç»å¯¹ä¸åº”该信任此æœåŠ¡å™¨å‡ºç¤ºçš„安全凭æ®ã€‚您å¯èƒ½æ­£åœ¨ä¸Žæ”»å‡»è€…进行通信。</translation>
<translation id="4381091992796011497">用户å:</translation>
<translation id="4394049700291259645">åœç”¨</translation>
<translation id="4406896451731180161">æœç´¢ç»“æžœ</translation>
+<translation id="4424024547088906515">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />ï¼›Chromeä¸ä¿¡ä»»å…¶å®‰å…¨è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ä¸æŽ¥å—您的登录è¯ä¹¦ï¼Œæˆ–者您å¯èƒ½æ²¡æœ‰æ供登录è¯ä¹¦ã€‚</translation>
<translation id="443673843213245140">å·²åœç”¨ä»£ç†ï¼Œä½†æ˜¯æŒ‡å®šäº†æ˜Žç¡®çš„代ç†é…置。</translation>
-<translation id="4492190037599258964">“<ph name="SEARCH_STRING" />â€çš„æœç´¢ç»“æžœ</translation>
<translation id="4506176782989081258">验è¯é”™è¯¯ï¼š<ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">è”系系统管ç†å‘˜</translation>
<translation id="450710068430902550">与管ç†å‘˜åˆ†äº«</translation>
<translation id="4515275063822566619">信用å¡é€‰é¡¹å’Œåœ°å€é€‰é¡¹å‡æ¥è‡ª Chrome 和您的 Google å¸å· (<ph name="ACCOUNT_EMAIL" />)。您å¯åœ¨<ph name="BEGIN_LINK" />设置<ph name="END_LINK" />中管ç†è¿™äº›é€‰é¡¹ã€‚</translation>
<translation id="4522570452068850558">详细信æ¯</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">å°è¯•åœç”¨æ‰©å±•ç¨‹åºã€‚</translation>
<translation id="457875822857220463">递é€</translation>
<translation id="4587425331216688090">从 Chrome 中移除地å€ï¼Ÿ</translation>
-<translation id="4589078953350245614">您å°è¯•è¿žæŽ¥åˆ° <ph name="DOMAIN" />,但æœåŠ¡å™¨æ供的è¯ä¹¦æ— æ•ˆã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="4592951414987517459">您与 <ph name="DOMAIN" /> 之间的连接采用新型加密套件进行了加密。</translation>
<translation id="4594403342090139922">撤消删除(&amp;U)</translation>
<translation id="4619615317237390068">从其他设备打开的标签页</translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />;其安全è¯ä¹¦æœ‰è¯¯ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
+<translation id="4690462567478992370">åœæ­¢ä½¿ç”¨æ— æ•ˆçš„è¯ä¹¦</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /><ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">您的连接已中断</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />è¿è¡Œ Windows 网络诊断<ph name="END_LINK" /></translation>
@@ -421,21 +472,24 @@
<translation id="4771973620359291008">å‘生未知错误。</translation>
<translation id="4800132727771399293">请检查您的到期日期和银行å¡éªŒè¯ç  (CVC),然åŽé‡è¯•</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站å‘é€äº† Google Chrome 无法处ç†çš„æ‚乱凭æ®ã€‚网络错误和攻击通常是暂时的,因此,此网页ç¨åŽå¯èƒ½ä¼šæ¢å¤æ­£å¸¸ã€‚</translation>
<translation id="4813512666221746211">网络错误</translation>
<translation id="4816492930507672669">适åˆé¡µé¢å¤§å°</translation>
<translation id="483020001682031208">没有å¯æ˜¾ç¤ºçš„实物网网页</translation>
<translation id="4850886885716139402">视图</translation>
<translation id="4854362297993841467">该递é€æ–¹å¼ä¸å¯ç”¨ã€‚请å¦é€‰ä¸€ç§æ–¹å¼ã€‚</translation>
<translation id="4858792381671956233">您已å‘父æ¯å‘é€è¯·æ±‚,询问他们是å¦å…许您访问此网站</translation>
+<translation id="4863764087567530506">此内容å¯èƒ½ä¼šè¯•å›¾è¯±éª—您安装软件或é€éœ²ä¸ªäººä¿¡æ¯ã€‚<ph name="BEGIN_LINK" />ä»ç„¶æ˜¾ç¤º<ph name="END_LINK" />。</translation>
<translation id="4880827082731008257">æœç´¢åŽ†å²è®°å½•</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />ã€<ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{å’Œå¦å¤– 1 个网页}other{å’Œå¦å¤– # 个网页}}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">翻译æœåŠ¡å™¨å·²å°†æ­¤ç½‘页从æŸç§æœªçŸ¥è¯­è¨€ç¿»è¯‘æˆäº†<ph name="LANGUAGE_LANGUAGE" />。</translation>
<translation id="4923459931733593730">付款</translation>
<translation id="4926049483395192435">必须指定。</translation>
<translation id="495170559598752135">æ“作</translation>
<translation id="4958444002117714549">展开列表</translation>
-<translation id="4962322354953122629">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›Chrome ä¸ä¿¡ä»»æœåŠ¡å™¨çš„安全è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
+<translation id="4974590756084640048">é‡æ–°å¯ç”¨è­¦å‘ŠåŠŸèƒ½</translation>
<translation id="4989809363548539747">该æ’件ä¸å—支æŒ</translation>
<translation id="5002932099480077015">如果您选中此项,Chrome 会将您的å¡çš„副本存储在此设备上,以加快表å•å¡«å†™é€Ÿåº¦ã€‚</translation>
<translation id="5018422839182700155">无法打开此网页</translation>
@@ -443,14 +497,15 @@
<translation id="5023310440958281426">请查看管ç†å‘˜åˆ¶å®šçš„政策</translation>
<translation id="5029568752722684782">清除副本</translation>
<translation id="5031870354684148875">关于 Google 翻译</translation>
+<translation id="5039804452771397117">å…许</translation>
<translation id="5040262127954254034">éšç§è®¾ç½®</translation>
<translation id="5045550434625856497">密ç ä¸æ­£ç¡®</translation>
<translation id="5056549851600133418">为您推è的文章</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />检查代ç†æœåŠ¡å™¨åœ°å€<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{没有 Cookie}=1{1 个网站使用 Cookie。}other{# 个网站使用 Cookie。}}</translation>
<translation id="5087286274860437796">æœåŠ¡å™¨çš„è¯ä¹¦ç›®å‰æ— æ•ˆã€‚</translation>
<translation id="5087580092889165836">添加新å¡</translation>
<translation id="5089810972385038852">å·ž</translation>
+<translation id="5094747076828555589">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />ï¼›Chromiumä¸ä¿¡ä»»å…¶å®‰å…¨è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
<translation id="5095208057601539847">çœ</translation>
<translation id="5115563688576182185">(64 ä½ï¼‰</translation>
<translation id="5141240743006678641">使用您的 Google 凭æ®åŠ å¯†å·²åŒæ­¥çš„密ç </translation>
@@ -466,24 +521,24 @@
<translation id="5222812217790122047">需è¦æ供电å­é‚®ä»¶åœ°å€</translation>
<translation id="5251803541071282808">云端</translation>
<translation id="5277279256032773186">使用 Chrome 办公?ä¼ä¸šå¯ä»¥ä¸ºå…¶å‘˜å·¥ç®¡ç† Chrome 设置。了解详情</translation>
+<translation id="5297526204711817721">您与此网站建立的ä¸æ˜¯ç§å¯†è¿žæŽ¥ã€‚您å¯ä»¥éšæ—¶å–下头戴å¼è®¾å¤‡ï¼Œç„¶åŽæŒ‰â€œè¿”回â€ï¼Œä»¥é€€å‡º VR 模å¼ã€‚</translation>
<translation id="5299298092464848405">解æžç­–略时出错</translation>
-<translation id="5300589172476337783">显示</translation>
<translation id="5308689395849655368">å·²åœç”¨å´©æºƒæŠ¥å‘Šã€‚</translation>
<translation id="5317780077021120954">ä¿å­˜</translation>
<translation id="5327248766486351172">å称</translation>
-<translation id="5337705430875057403"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻击者å¯èƒ½ä¼šè¯±éª—您åšä¸€äº›å±é™©çš„事情,如安装软件或泄露您的个人信æ¯ï¼ˆå¦‚密ç ã€ç”µè¯å·ç æˆ–信用å¡ä¿¡æ¯ï¼‰ã€‚</translation>
-<translation id="5359637492792381994">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦ç›®å‰æ— æ•ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
+<translation id="5355557959165512791">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此è¯ä¹¦å·²è¢«æ’¤æ¶ˆã€‚网络错误和攻击行为通常是暂时的,因此,此网页ç¨åŽå¯èƒ½ä¼šæ¢å¤æ­£å¸¸ã€‚</translation>
<translation id="536296301121032821">无法存储策略设置</translation>
<translation id="5386426401304769735">此网站的è¯ä¹¦é“¾åŒ…å«ä½¿ç”¨ SHA-1 签署的è¯ä¹¦ã€‚</translation>
<translation id="5402410679244714488">到期日期:<ph name="EXPIRATION_DATE_ABBR" />ï¼›è·ç¦»ä¸Šæ¬¡ä½¿ç”¨å·²è¶…过 1 å¹´</translation>
+<translation id="540969355065856584">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯ <ph name="DOMAIN" />;其安全è¯ä¹¦ç›®å‰æ— æ•ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
<translation id="5421136146218899937">清除æµè§ˆæ•°æ®...</translation>
<translation id="5430298929874300616">移除书签</translation>
<translation id="5431657950005405462">找ä¸åˆ°æ‚¨çš„文件</translation>
-<translation id="5435775191620395718">ç›®å‰æ˜¾ç¤ºçš„是此设备中的历å²è®°å½•ã€‚<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" />。</translation>
<translation id="5439770059721715174">“<ph name="ERROR_PATH" />â€ä¸­å­˜åœ¨æ¨¡å¼éªŒè¯é”™è¯¯ï¼š<ph name="ERROR" /></translation>
<translation id="5452270690849572955">找ä¸åˆ° <ph name="HOST_NAME" /> 的网页</translation>
<translation id="5455374756549232013">策略时间戳无效</translation>
<translation id="5455790498993699893">第 <ph name="ACTIVE_MATCH" /> æ¡ï¼Œå…± <ph name="TOTAL_MATCHCOUNT" /> æ¡</translation>
+<translation id="5457113250005438886">无效</translation>
<translation id="5470861586879999274">æ¢å¤ä¿®æ”¹(&amp;R)</translation>
<translation id="54817484435770891">添加有效地å€</translation>
<translation id="5492298309214877701">这个ä½äºŽå…¬å¸ã€ç»„织或学校内网中的网站使用的网å€ä¸ŽæŸä¸ªå¤–部网站的网å€ç›¸åŒã€‚
@@ -500,6 +555,8 @@
<translation id="5571083550517324815">无法从此地å€å–货。请å¦é€‰ä¸€ä¸ªåœ°å€ã€‚</translation>
<translation id="5572851009514199876">请å¯åŠ¨å¹¶ç™»å½• Chrome,以便 Chrome 能够检查您是å¦å¯ä»¥è®¿é—®æ­¤ç½‘站。</translation>
<translation id="5580958916614886209">请检查您的信用å¡åˆ°æœŸæœˆä»½ï¼Œç„¶åŽé‡è¯•</translation>
+<translation id="5586446728396275693">没有已ä¿å­˜çš„地å€</translation>
+<translation id="5595485650161345191">修改地å€</translation>
<translation id="560412284261940334">ä¸æ”¯æŒç®¡ç†</translation>
<translation id="5610142619324316209">检查网络连接</translation>
<translation id="5610807607761827392">您å¯ä»¥åœ¨<ph name="BEGIN_LINK" />设置<ph name="END_LINK" />中管ç†ä¿¡ç”¨å¡å’Œåœ°å€ä¿¡æ¯ã€‚</translation>
@@ -507,15 +564,18 @@
<translation id="5622887735448669177">è¦ç¦»å¼€æ­¤ç½‘ç«™å—?</translation>
<translation id="5629630648637658800">无法加载策略设置</translation>
<translation id="5631439013527180824">设备管ç†ä»¤ç‰Œæ— æ•ˆ</translation>
+<translation id="5633066919399395251">攻击者å¯èƒ½ä¼šè¯•å›¾é€šè¿‡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在您的计算机上安装å±é™©ç¨‹åºï¼Œä»¥çªƒå–或删除您的信æ¯ï¼ˆå¦‚照片ã€å¯†ç ã€é€šè®¯å†…容和信用å¡ä¿¡æ¯ï¼‰ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">ä½ç½®</translation>
+<translation id="5659593005791499971">电å­é‚®ä»¶</translation>
<translation id="5669703222995421982">获å–个性化内容</translation>
<translation id="5675650730144413517">该网页无法正常è¿ä½œ</translation>
-<translation id="5677928146339483299">å·²å±è”½</translation>
-<translation id="5694783966845939798">您å°è¯•è¿žæŽ¥åˆ° <ph name="DOMAIN" />,但相应æœåŠ¡å™¨æ供的è¯ä¹¦æ˜¯ä½¿ç”¨é˜²æŠ¤åŠ›è–„弱的签å算法(如 SHA-1)签署的。这æ„味ç€è¯¥æœåŠ¡å™¨æ供的安全凭æ®å¯èƒ½æ˜¯ä¼ªé€ çš„,而且该æœåŠ¡å™¨å¯èƒ½å¹¶ä¸æ˜¯æ‚¨æƒ³è®¿é—®çš„æœåŠ¡å™¨ï¼ˆæ‚¨å¯èƒ½æ­£åœ¨ä¸Žæ”»å‡»è€…通信)。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="5710435578057952990">此网站尚未ç»è¿‡èº«ä»½éªŒè¯ã€‚</translation>
+<translation id="5713016350996637505">欺骗性内容已被拦截</translation>
<translation id="5720705177508910913">当å‰ç”¨æˆ·</translation>
<translation id="5732392974455271431">您的父æ¯å¯ä¸ºæ‚¨å–消å±è”½æ­¤ç½‘ç«™</translation>
<translation id="5763042198335101085">请输入有效的电å­é‚®ä»¶åœ°å€</translation>
<translation id="5765072501007116331">è¦æŸ¥çœ‹é€’é€æ–¹å¼å’Œè¦æ±‚,请选择相应地å€</translation>
+<translation id="5778550464785688721">完全控制 MIDI 设备</translation>
<translation id="5784606427469807560">确认您的信用å¡æ—¶å‡ºçŽ°é—®é¢˜ã€‚请检查您的互è”网连接,然åŽé‡è¯•ã€‚</translation>
<translation id="5785756445106461925">而且,此页中包å«å…¶ä»–ä¸å®‰å…¨çš„资æºã€‚他人能在这些资æºä¼ è¾“过程中进行查看,攻击者也å¯ä»¥ä¿®æ”¹è¿™äº›èµ„æºï¼Œä»Žè€Œæ”¹å˜æ­¤é¡µçš„外观。</translation>
<translation id="5786044859038896871">è¦å¡«å……您的信用å¡ä¿¡æ¯å—?</translation>
@@ -524,14 +584,14 @@
<translation id="5813119285467412249">æ¢å¤æ·»åŠ (&amp;R)</translation>
<translation id="5814352347845180253">您å¯èƒ½æ— æ³•å†è®¿é—® <ph name="SITE" /> 以åŠå…¶ä»–一些网站上的付费内容。</translation>
<translation id="5838278095973806738">请勿在此网站上输入任何æ•æ„Ÿä¿¡æ¯ï¼ˆä¾‹å¦‚密ç æˆ–信用å¡ä¿¡æ¯ï¼‰ï¼Œå› ä¸ºæ”»å‡»è€…å¯èƒ½ä¼šç›—å–这些信æ¯ã€‚</translation>
-<translation id="5843436854350372569">您å°è¯•è®¿é—® <ph name="DOMAIN" />,但æœåŠ¡å™¨æ供的è¯ä¹¦åŒ…å«é˜²æŠ¤åŠ›è–„弱的密钥。攻击者å¯èƒ½å·²ç ´è§£ç§é’¥ï¼Œè€Œä¸”这个æœåŠ¡å™¨å¯èƒ½å¹¶ä¸æ˜¯æ‚¨æƒ³è¦è®¿é—®çš„æœåŠ¡å™¨ï¼ˆæ‚¨å¯èƒ½æ­£åœ¨ä¸Žæ”»å‡»è€…进行通信)。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="5869405914158311789">无法访问此网站</translation>
<translation id="5869522115854928033">å·²ä¿å­˜çš„密ç </translation>
<translation id="5872918882028971132">家长建议</translation>
<translation id="5901630391730855834">黄色</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" />(已åŒæ­¥ï¼‰</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{正在使用 1 个}other{正在使用 # 个}}</translation>
<translation id="5926846154125914413">您å¯èƒ½æ— æ³•å†è®¿é—®æŸäº›ç½‘站上的付费内容。</translation>
<translation id="5959728338436674663">è‡ªåŠ¨å‘ Google å‘é€ä¸€äº›<ph name="BEGIN_WHITEPAPER_LINK" />系统信æ¯å’Œç½‘页内容<ph name="END_WHITEPAPER_LINK" />,以帮助检测å±é™©åº”用和网站。<ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">周</translation>
<translation id="5967867314010545767">从历å²è®°å½•ä¸­ç§»é™¤</translation>
<translation id="5975083100439434680">缩å°</translation>
<translation id="598637245381783098">无法打开付款应用</translation>
@@ -540,20 +600,28 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{第 1 页}other{第 # 页}}</translation>
<translation id="6017514345406065928">绿色</translation>
+<translation id="6017850046339264347"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻击者å¯èƒ½ä¼šå®‰è£…欺骗性应用æ¥å†’充其他内容或收集å¯ç”¨äºŽå¯¹æ‚¨è¿›è¡Œè·Ÿè¸ªçš„æ•°æ®ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />ã€<ph name="TYPE_3" />(已åŒæ­¥ï¼‰</translation>
<translation id="6027201098523975773">请输入å称</translation>
<translation id="6040143037577758943">关闭</translation>
<translation id="6042308850641462728">更多</translation>
+<translation id="6047233362582046994">如果您了解自己将é¢ä¸´çš„安全风险,则å¯åœ¨æœ‰å®³åº”用被移除之å‰<ph name="BEGIN_LINK" />访问此网站<ph name="END_LINK" />。</translation>
+<translation id="6051221802930200923">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站使用了è¯ä¹¦é”定。网络错误和攻击通常是暂时的,因此,此网页ç¨åŽå¯èƒ½ä¼šæ¢å¤æ­£å¸¸ã€‚</translation>
<translation id="6060685159320643512">请å°å¿ƒï¼Œè¿™äº›å®žéªŒæ€§åŠŸèƒ½å¯èƒ½æœ‰é£Žé™©</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{无}=1{1 个}other{# 个}}</translation>
+<translation id="6080696365213338172">您已使用管ç†å‘˜æ供的è¯ä¹¦è®¿é—®äº†å†…容,因此管ç†å‘˜å¯ä»¥æ‹¦æˆªæ‚¨æ供给 <ph name="DOMAIN" /> çš„æ•°æ®ã€‚</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{æ— }=1{1 个密ç ï¼ˆå·²åŒæ­¥ï¼‰}other{# 个密ç ï¼ˆå·²åŒæ­¥ï¼‰}}</translation>
<translation id="6146055958333702838">请检查所有网线是å¦éƒ½å·²è¿žå¥½ï¼Œç„¶åŽé‡æ–°å¯åŠ¨æ‚¨å¯èƒ½æ­£åœ¨ä½¿ç”¨çš„任何路由器ã€è°ƒåˆ¶è§£è°ƒå™¨æˆ–其他网络设备。</translation>
<translation id="614940544461990577">请试试以下办法:</translation>
<translation id="6151417162996330722">该æœåŠ¡å™¨è¯ä¹¦çš„有效期过长。</translation>
<translation id="6157877588268064908">è¦æŸ¥çœ‹é€è´§æ–¹å¼å’Œè¦æ±‚,请选择相应地å€</translation>
+<translation id="6158003235852588289">Google 安全æµè§ˆåŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上检测到网上诱骗行为。网上诱骗网站会å‡å†’其他网站æ¥æ¬ºéª—您。</translation>
<translation id="6165508094623778733">了解详情</translation>
+<translation id="6169916984152623906">现在,您便å¯è¿›è¡Œç§å¯†æµè§ˆäº†ã€‚共用此设备的其他用户将ä¸ä¼šçœ‹åˆ°æ‚¨çš„活动,但您下载的内容和添加的书签ä»ä¼šä¿å­˜åœ¨è®¾å¤‡ä¸Šã€‚</translation>
<translation id="6177128806592000436">您与此网站之间建立的连接ä¸å®‰å…¨</translation>
<translation id="6184817833369986695">(åŒç±»ç¾¤ç»„:<ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">请检查您的互è”网连接是å¦æ­£å¸¸</translation>
<translation id="6218753634732582820">è¦ä»Ž Chromium 中移除地å€å—?</translation>
+<translation id="6221345481584921695">Google安全æµè§ˆåŠŸèƒ½æœ€è¿‘在<ph name="SITE" />上<ph name="BEGIN_LINK" />检测到了æ¶æ„软件<ph name="END_LINK" />。平常éžå¸¸å®‰å…¨çš„网站有时也会感染æ¶æ„软件。检测到的æ¶æ„内容æ¥è‡ªäºŽ<ph name="SUBRESOURCE_HOST" />,这是个出了åçš„æ¶æ„软件散布方。</translation>
<translation id="6251924700383757765">éšç§æƒæ”¿ç­–</translation>
<translation id="6254436959401408446">内存ä¸è¶³ï¼Œæ— æ³•æ‰“开此网页</translation>
<translation id="625755898061068298">您已选择针对此网站åœç”¨å®‰å…¨è­¦å‘ŠåŠŸèƒ½ã€‚</translation>
@@ -579,15 +647,14 @@
<translation id="6404511346730675251">修改书签</translation>
<translation id="6410264514553301377">请输入“<ph name="CREDIT_CARD" />â€çš„到期日期和银行å¡éªŒè¯ç  (CVC)</translation>
<translation id="6414888972213066896">您已å‘父亲/æ¯äº²å‘é€è¯·æ±‚,询问其是å¦å…许您访问此网站</translation>
-<translation id="6416403317709441254">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为此网站å‘é€çš„凭æ®æ˜¯ä¹±ç ï¼ŒChromium 无法处ç†ã€‚网络错误和攻击行为通常是暂时的,因此,此网页ç¨åŽå¯èƒ½å°±ä¼šæ¢å¤æ­£å¸¸ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="6417515091412812850">无法检查è¯ä¹¦æ˜¯å¦å·²åŠé”€ã€‚</translation>
<translation id="6433490469411711332">修改è”系信æ¯</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> æ‹’ç»äº†æˆ‘们的连接请求。</translation>
<translation id="6446608382365791566">添加更多信æ¯</translation>
+<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">确认é‡æ–°æ交表å•</translation>
<translation id="6456339708790392414">您的付款</translation>
<translation id="6458467102616083041">由于默认æœç´¢è¢«æ”¿ç­–åœç”¨ï¼Œæ”¿ç­–值已被忽略。</translation>
-<translation id="6462969404041126431">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />ï¼›æœåŠ¡å™¨çš„安全è¯ä¹¦å¯èƒ½é­åˆ°æ’¤æ¶ˆã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="647261751007945333">设备政策</translation>
<translation id="6477321094435799029">Chrome 在此网页上检测到了异常代ç ã€‚为ä¿æŠ¤æ‚¨çš„个人信æ¯ï¼ˆä¾‹å¦‚密ç ã€ç”µè¯å·ç å’Œä¿¡ç”¨å¡ä¿¡æ¯ï¼‰ï¼ŒChrome 已将该网页拦截。</translation>
<translation id="6489534406876378309">开始上传崩溃数æ®</translation>
@@ -599,20 +666,19 @@
<translation id="6556915248009097796">到期日期:<ph name="EXPIRATION_DATE_ABBR" />;上次使用日期:<ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">您的管ç†å‘˜å°šæœªæ‰¹å‡†æ­¤ç½‘ç«™</translation>
<translation id="6569060085658103619">您正在查看扩展程åºé¡µé¢</translation>
-<translation id="6593753688552673085">ä¸åˆ° <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">此内容å¯èƒ½ä¼šè¯•å›¾åœ¨æ‚¨çš„设备上安装å±é™©è½¯ä»¶æ¥çªƒå–或删除您的信æ¯ã€‚<ph name="BEGIN_LINK" />ä»ç„¶æ˜¾ç¤º<ph name="END_LINK" />。</translation>
<translation id="6596325263575161958">加密选项</translation>
<translation id="662080504995468778">留下</translation>
<translation id="6626291197371920147">添加有效的å¡å·</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> æœç´¢</translation>
+<translation id="6630809736994426279">攻击者å¯èƒ½ä¼šè¯•å›¾é€šè¿‡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在您的 Mac 上安装å±é™©ç¨‹åºï¼Œä»¥çªƒå–或删除您的信æ¯ï¼ˆå¦‚照片ã€å¯†ç ã€é€šè®¯å†…容和信用å¡ä¿¡æ¯ï¼‰ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">此政策已弃用。</translation>
-<translation id="6652240803263749613">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />;您计算机的æ“作系统ä¸ä¿¡ä»»æœåŠ¡å™¨çš„安全è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="6671697161687535275">è¦ä»Ž Chromium 中移除表å•å¡«å†™å»ºè®®å—?</translation>
<translation id="6685834062052613830">请退出并完æˆè®¾ç½®</translation>
<translation id="6710213216561001401">上一个</translation>
<translation id="6710594484020273272">&lt;输入æœç´¢å­—è¯&gt;</translation>
<translation id="6711464428925977395">代ç†æœåŠ¡å™¨å‡ºçŽ°é—®é¢˜ï¼Œæˆ–者地å€æœ‰è¯¯ã€‚</translation>
<translation id="6727102863431372879">设置</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{无}=1{1 项内容}other{# 项内容}}</translation>
<translation id="674375294223700098">未知的æœåŠ¡å™¨è¯ä¹¦é”™è¯¯ã€‚</translation>
<translation id="6753269504797312559">政策值</translation>
<translation id="6757797048963528358">您的设备已进入休眠模å¼ã€‚</translation>
@@ -620,6 +686,8 @@
<translation id="6810899417690483278">自定义 ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">未能加载区域数æ®</translation>
+<translation id="6825578344716086703">您å°è¯•è®¿é—®çš„是 <ph name="DOMAIN" />,但是æœåŠ¡å™¨å‡ºç¤ºçš„è¯ä¹¦æ˜¯ä½¿ç”¨å¼±ç­¾å算法(例如 SHA-1)签署的。这æ„味ç€æœåŠ¡å™¨å‡ºç¤ºçš„安全凭æ®å¯èƒ½æ˜¯ä¼ªé€ çš„,因此这å¯èƒ½å¹¶ä¸æ˜¯æ‚¨æƒ³è¦è®¿é—®çš„æœåŠ¡å™¨ï¼ˆæ‚¨å¯èƒ½æ­£åœ¨ä¸Žæ”»å‡»è€…进行通信)。</translation>
+<translation id="6830728435402077660">ä¸å®‰å…¨</translation>
<translation id="6831043979455480757">翻译</translation>
<translation id="6839929833149231406">地域</translation>
<translation id="6874604403660855544">æ¢å¤æ·»åŠ (&amp;R)</translation>
@@ -627,6 +695,7 @@
<translation id="6895330447102777224">已确认您的信用å¡</translation>
<translation id="6897140037006041989">用户代ç†</translation>
<translation id="6915804003454593391">用户:</translation>
+<translation id="6945221475159498467">选择</translation>
<translation id="6948701128805548767">è¦æŸ¥çœ‹å–货方å¼å’Œè¦æ±‚,请选择相应地å€</translation>
<translation id="6957887021205513506">该æœåŠ¡å™¨çš„è¯ä¹¦ä¼¼ä¹Žæ˜¯ä¼ªé€ çš„。</translation>
<translation id="6965382102122355670">确定</translation>
@@ -635,15 +704,16 @@
<translation id="6973656660372572881">固定代ç†æœåŠ¡å™¨å’Œ .pac 脚本网å€å‡å·²æŒ‡å®šã€‚</translation>
<translation id="6989763994942163495">显示高级设置...</translation>
<translation id="7000990526846637657">未找到任何记录æ¡ç›®</translation>
-<translation id="7009986207543992532">您å°è¯•è¿žæŽ¥åˆ° <ph name="DOMAIN" />,但æœåŠ¡å™¨æ供的è¯ä¹¦æœ‰æ•ˆæœŸè¿‡é•¿ï¼Œå› æ­¤éš¾ä»¥ä¿¡ä»»ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="7012363358306927923">中国银è”</translation>
<translation id="7012372675181957985">您的 Google å¸å·åœ¨ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> 上å¯èƒ½æœ‰å…¶ä»–å½¢å¼çš„æµè§ˆè®°å½•</translation>
<translation id="7029809446516969842">密ç </translation>
+<translation id="7050187094878475250">您å°è¯•è®¿é—® <ph name="DOMAIN" />,但æœåŠ¡å™¨æ供的è¯ä¹¦ä¸å¯ä¿¡ï¼ˆæœ‰æ•ˆæœŸè¿‡é•¿ï¼‰ã€‚</translation>
+<translation id="7053983685419859001">ç¦æ­¢</translation>
<translation id="7064851114919012435">è”系信æ¯</translation>
<translation id="7079718277001814089">此网站包å«æ¶æ„软件</translation>
<translation id="7087282848513945231">县/郡</translation>
-<translation id="7088615885725309056">å¾€å‰</translation>
<translation id="7090678807593890770">请在 Google 中æœç´¢â€œ<ph name="LINK" />â€</translation>
+<translation id="7108819624672055576">æŸæ¬¾æ‰©å±•ç¨‹åºå…许</translation>
<translation id="7119414471315195487">关闭其他标签页或程åº</translation>
<translation id="7129409597930077180">无法å‘此地å€é€è´§ã€‚请å¦é€‰ä¸€ä¸ªåœ°å€ã€‚</translation>
<translation id="7138472120740807366">递é€æ–¹å¼</translation>
@@ -661,22 +731,18 @@
<translation id="7220786058474068424">正在处ç†</translation>
<translation id="724691107663265825">您è¦è®¿é—®çš„网站包å«æ¶æ„软件</translation>
<translation id="724975217298816891">输入“<ph name="CREDIT_CARD" />â€çš„过期日期和银行å¡éªŒè¯ç  (CVC) 以更新您的信用å¡è¯¦æƒ…。在您确认åŽï¼Œæ‚¨çš„信用å¡è¯¦æƒ…将与此网站共享。</translation>
-<translation id="725866823122871198">您计算机的日期和时间(<ph name="DATE_AND_TIME" />)ä¸æ­£ç¡®ï¼Œå› æ­¤æ— æ³•ä¸Ž <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§å¯†è¿žæŽ¥ã€‚</translation>
+<translation id="7260504762447901703">撤消访问æƒé™</translation>
<translation id="7275334191706090484">å—管ç†çš„书签</translation>
<translation id="7298195798382681320">推è</translation>
<translation id="7309308571273880165">崩溃报告获å–时间:<ph name="CRASH_TIME" />(用户已请求上传,但尚未上传)</translation>
<translation id="7334320624316649418">æ¢å¤é¡ºåºè°ƒæ•´(&amp;R)</translation>
<translation id="733923710415886693">该æœåŠ¡å™¨çš„è¯ä¹¦æœªé€šè¿‡è¯ä¹¦é€æ˜Žåº¦æ”¿ç­–进行披露。</translation>
-<translation id="7351800657706554155">您目å‰æ— æ³•è®¿é—® <ph name="SITE" />,因为其è¯ä¹¦å·²è¢«æ’¤æ¶ˆã€‚网络错误和攻击行为通常是暂时的,因此,此网页ç¨åŽå¯èƒ½å°±ä¼šæ¢å¤æ­£å¸¸ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="7353601530677266744">命令行</translation>
<translation id="7372973238305370288">æœç´¢ç»“æžœ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">å¦</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">确认信用å¡</translation>
-<translation id="7394102162464064926">您确定è¦ä»ŽåŽ†å²è®°å½•ä¸­åˆ é™¤è¿™äº›ç½‘页å—?
-
-嘘ï¼ä¸‹æ¬¡æ‚¨å¯ä»¥ä½¿ç”¨éšèº«æ¨¡å¼ï¼ˆå¿«æ·é”®ä¸º <ph name="SHORTCUT_KEY" />)。</translation>
<translation id="7400418766976504921">网å€</translation>
<translation id="7419106976560586862">个人资料路径</translation>
<translation id="7424977062513257142">此网页上的嵌入å¼é¡µé¢æ˜¾ç¤ºï¼š</translation>
@@ -684,6 +750,7 @@
<translation id="7444046173054089907">此网站已被å±è”½</translation>
<translation id="7445762425076701745">无法完全验è¯æ‚¨æ‰€è¿žæŽ¥åˆ°çš„æœåŠ¡å™¨çš„身份。您在连接æœåŠ¡å™¨æ—¶ä½¿ç”¨çš„æœåŠ¡å™¨å称仅在您的网络中有效,而外部è¯ä¹¦æŽˆæƒä¸­å¿ƒæ— æ³•éªŒè¯è¯¥å称的所有æƒã€‚由于一些è¯ä¹¦æŽˆæƒä¸­å¿ƒä»ç„¶ä¼šä¸ºè¿™äº›å称é¢å‘è¯ä¹¦ï¼Œå› æ­¤æ— æ³•ç¡®ä¿æ‚¨è¿žæŽ¥åˆ°æƒ³è¦è®¿é—®çš„网站而ä¸æ˜¯æ”»å‡»ç½‘站。</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />详细了解<ph name="END_LINK" />此问题。</translation>
+<translation id="7455133967321480974">使用全局默认设置(阻止)</translation>
<translation id="7460163899615895653">此处将会显示您最近从其他设备打开的标签页</translation>
<translation id="7469372306589899959">确认信用å¡</translation>
<translation id="7481312909269577407">å‰è¿›</translation>
@@ -691,36 +758,43 @@
<translation id="7508255263130623398">返回的政策设备 ID 为空,或与当å‰çš„设备 ID ä¸ä¸€è‡´</translation>
<translation id="7514365320538308">下载</translation>
<translation id="7518003948725431193">找ä¸åˆ°ä¸Žä»¥ä¸‹ç½‘å€å¯¹åº”的网页:<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">值</translation>
<translation id="7537536606612762813">强制</translation>
+<translation id="7542403920425041731">一旦您予以确认,系统便会将您的信用å¡è¯¦æƒ…共享给此网站。</translation>
<translation id="7542995811387359312">由于该表å•ä¸ä½¿ç”¨å®‰å…¨è¿žæŽ¥ï¼Œå› æ­¤è‡ªåŠ¨å¡«å†™ä¿¡ç”¨å¡ä¿¡æ¯çš„功能已åœç”¨ã€‚</translation>
<translation id="7543525346216957623">请先å¾å¾—您父亲/æ¯äº²çš„许å¯</translation>
<translation id="7549584377607005141">此网页需è¦ä½¿ç”¨æ‚¨ä¹‹å‰è¾“入的数æ®æ‰èƒ½æ­£å¸¸æ˜¾ç¤ºã€‚您å¯ä»¥é‡æ–°å‘é€è¿™äº›æ•°æ®ï¼Œä¸è¿‡ï¼Œè¿™ä¹ˆåšä¼šé‡å¤æ‰§è¡Œæ­¤ç½‘页之å‰æ‰§è¡Œè¿‡çš„所有æ“作。</translation>
<translation id="7552846755917812628">请å°è¯•æŒ‰ä»¥ä¸‹æ示æ“作:</translation>
<translation id="7554791636758816595">新标签页</translation>
+<translation id="7567204685887185387">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå®ƒæ˜¯<ph name="DOMAIN" />;其安全è¯ä¹¦å¯èƒ½æ˜¯ç”±éª—å­å‘出的。出现此问题的原因å¯èƒ½æ˜¯é…置有误或您的连接被拦截了。</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> åè”系人}other{<ph name="CONTACT_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> åè”系人}}</translation>
<translation id="7568593326407688803">此网页为<ph name="ORIGINAL_LANGUAGE" />网页,是å¦éœ€è¦ç¿»è¯‘?</translation>
<translation id="7569952961197462199">从 Chrome 中移除信用å¡ä¿¡æ¯ï¼Ÿ</translation>
<translation id="7569983096843329377">黑色</translation>
<translation id="7578104083680115302">通过å„ç§è®¾å¤‡åœ¨ç½‘站和应用中购物时,您都å¯ä»¥ä½¿ç”¨ Google 为您ä¿å­˜çš„银行å¡ä¿¡æ¯å¿«é€Ÿä»˜æ¬¾ã€‚</translation>
<translation id="7588950540487816470">实物网</translation>
<translation id="7592362899630581445">æœåŠ¡å™¨çš„è¯ä¹¦è¿å了域åé™åˆ¶ã€‚</translation>
+<translation id="7598391785903975535">少于 <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ç›®å‰æ— æ³•å¤„ç†æ­¤è¯·æ±‚。</translation>
<translation id="7600965453749440009">一律ä¸ç¿»è¯‘<ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">值超出了范围 (<ph name="VALUE" />)。</translation>
<translation id="7613889955535752492">过期时间:<ph name="EXPIRATION_YEAR" /> 年 <ph name="EXPIRATION_MONTH" /> 月</translation>
<translation id="7615602087246926389">您已ç»ä½¿ç”¨ä¸åŒç‰ˆæœ¬çš„ Google å¸å·å¯†ç åŠ å¯†äº†æ•°æ®ã€‚请在下方输入。</translation>
-<translation id="7634554953375732414">您与此网站建立的ä¸æ˜¯ç§å¯†è¿žæŽ¥ã€‚</translation>
<translation id="7637571805876720304">è¦ä»Ž Chromium 中移除信用å¡å—?</translation>
<translation id="765676359832457558">éšè—高级设置...</translation>
<translation id="7658239707568436148">å–消</translation>
+<translation id="7662298039739062396">设置由æŸæ¬¾æ‰©å±•ç¨‹åºæŽ§åˆ¶</translation>
<translation id="7667346355482952095">返回的政策令牌为空或与当å‰ä»¤ç‰Œä¸åŒ¹é…</translation>
<translation id="7668654391829183341">未知设备</translation>
<translation id="7669271284792375604">此网站上的攻击者å¯èƒ½ä¼šè¯•å›¾è¯±éª—您安装有æŸæµè§ˆä½“验的程åºï¼ˆä¾‹å¦‚:通过更改您的主页或在您访问的网站上显示é¢å¤–的广告)。</translation>
<translation id="7674629440242451245">想试试超酷的 Chrome 新功能?欢迎访问 chrome.com/dev,试用我们的测试版ï¼</translation>
<translation id="7682287625158474539">é€è´§åœ°å€</translation>
+<translation id="7701040980221191251">æ— </translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />继续å‰å¾€<ph name="SITE" />(ä¸å®‰å…¨ï¼‰<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">è¯ä¹¦</translation>
+<translation id="7716147886133743102">已被您的管ç†å‘˜é˜»æ­¢</translation>
<translation id="7716424297397655342">无法从缓存中加载此网站</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" /> 次)</translation>
<translation id="7752995774971033316">éžæ‰˜ç®¡</translation>
<translation id="7755287808199759310">您的父亲/æ¯äº²å¯ä¸ºæ‚¨å–消å±è”½æ­¤ç½‘ç«™</translation>
<translation id="7758069387465995638">防ç«å¢™æˆ–防病毒软件å¯èƒ½å·²é˜»æ­¢æ‚¨è¿žæŽ¥åˆ°ç½‘络。</translation>
@@ -747,15 +821,15 @@
<translation id="7951415247503192394">(32 ä½ï¼‰</translation>
<translation id="7956713633345437162">移动设备书签</translation>
<translation id="7961015016161918242">一律ä¸</translation>
-<translation id="7962083544045318153">崩溃 ID:<ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">一律将<ph name="ORIGINAL_LANGUAGE" />翻译æˆ<ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">未指定</translation>
<translation id="800218591365569300">请å°è¯•å…³é—­å…¶ä»–标签页或程åºä»¥é‡Šæ”¾å†…存。</translation>
<translation id="8012647001091218357">我们暂时无法与您父æ¯å–å¾—è”系,请é‡è¯•ã€‚</translation>
<translation id="8025119109950072390">此网站上的攻击者å¯èƒ½ä¼šè¯±éª—您åšå‡ºä¸€äº›è¯¸å¦‚安装软件或泄露个人信æ¯ï¼ˆä¾‹å¦‚:密ç ã€ç”µè¯å·ç æˆ–信用å¡ä¿¡æ¯ï¼‰ä¹‹ç±»çš„å±é™©äº‹æƒ…。</translation>
-<translation id="803030522067524905">Google 安全æµè§ˆåŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上检测到网上诱骗行为。网上诱骗网站会å‡å†’其他网站æ¥æ¬ºéª—您。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="8034522405403831421">此网页的æºè¯­è¨€ä¸º<ph name="SOURCE_LANGUAGE" />,è¦å°†å…¶ç¿»è¯‘æˆ<ph name="TARGET_LANGUAGE" />å—?</translation>
+<translation id="8037357227543935929">询问(默认)</translation>
<translation id="8041089156583427627">å‘é€å馈</translation>
+<translation id="8041940743680923270">使用全局默认设置(询问)</translation>
<translation id="8088680233425245692">无法查看文章。</translation>
<translation id="8089520772729574115">å°äºŽ 1 MB</translation>
<translation id="8091372947890762290">正等待在æœåŠ¡å™¨ä¸Šæ¿€æ´»</translation>
@@ -764,13 +838,14 @@
<translation id="8134994873729925007">找ä¸åˆ° <ph name="HOST_NAME" /> çš„æœåŠ¡å™¨ <ph name="BEGIN_ABBR" />DNS 地å€<ph name="END_ABBR" />。</translation>
<translation id="8149426793427495338">您的计算机已进入休眠模å¼ã€‚</translation>
<translation id="8150722005171944719">æ— æ³•è¯»å– <ph name="URL" /> 上的文件。该文件å¯èƒ½å·²é­åˆ°åˆ é™¤ã€ç§»åŠ¨ï¼Œæˆ–者文件æƒé™ä¸å…许进行访问。</translation>
+<translation id="8184538546369750125">使用全局默认设置(å…许)</translation>
+<translation id="8191494405820426728">本地崩溃 ID:<ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">撤消移动(&amp;U)</translation>
<translation id="8201077131113104583">ID 为“<ph name="EXTENSION_ID" />â€çš„扩展程åºçš„更新网å€æ— æ•ˆã€‚</translation>
<translation id="8202097416529803614">订å•æ‘˜è¦</translation>
<translation id="8218327578424803826">分é…çš„ä½ç½®ï¼š</translation>
<translation id="8225771182978767009">设置此计算机的用户已选择å±è”½æ­¤ç½‘站。</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />ã€<ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">攻击者å¯èƒ½ä¼šè¯•å›¾é€šè¿‡ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在您的计算机上安装å±é™©ç¨‹åºï¼Œä»¥çªƒå–或删除您的信æ¯ï¼ˆå¦‚照片ã€å¯†ç ã€é€šè®¯å†…容和信用å¡ä¿¡æ¯ï¼‰ã€‚</translation>
<translation id="8241707690549784388">您所查找的网页è¦ä½¿ç”¨å·²è¾“入的信æ¯ã€‚返回此页å¯èƒ½éœ€è¦é‡å¤å·²è¿›è¡Œçš„所有æ“作。是å¦è¦ç»§ç»­æ“作?</translation>
<translation id="8249320324621329438">最åŽä¸€æ¬¡æŠ“å–时间:</translation>
<translation id="8253091569723639551">è´¦å•é‚®å¯„地å€æ˜¯å¿…填项</translation>
@@ -778,6 +853,7 @@
<translation id="8289355894181816810">如果您ä¸ç¡®å®šè¿™æ˜¯ä»€ä¹ˆæ„æ€ï¼Œè¯·ä¸Žæ‚¨çš„网络管ç†å‘˜è”系。</translation>
<translation id="8293206222192510085">添加书签</translation>
<translation id="8294431847097064396">æ¥æº</translation>
+<translation id="8306404619377842860">您设备的日期和时间(<ph name="DATE_AND_TIME" />)ä¸æ­£ç¡®ï¼Œå› æ­¤æ— æ³•ä¸Ž <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§å¯†è¿žæŽ¥ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">由于网络连接问题,翻译失败。</translation>
<translation id="8332188693563227489">访问 <ph name="HOST_NAME" /> 的请求é­åˆ°æ‹’ç»</translation>
<translation id="834457929814110454">如果您了解自己将é¢ä¸´çš„安全风险,则å¯ä»¥åœ¨æœ‰å®³ç¨‹åºè¢«æ¸…除之å‰<ph name="BEGIN_LINK" />访问此网站<ph name="END_LINK" />。</translation>
@@ -798,11 +874,9 @@
<translation id="8483780878231876732">è¦ä½¿ç”¨æ‚¨ Google å¸å·ä¸­çš„信用å¡ï¼Œè¯·ç™»å½• Chrome</translation>
<translation id="8488350697529856933">适用对象</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> çš„å“应时间过长。</translation>
-<translation id="852346902619691059">æ­¤æœåŠ¡å™¨æ— æ³•è¯æ˜Žå…¶æ‰€åœ¨ç½‘域是 <ph name="DOMAIN" />;您设备的æ“作系统ä¸ä¿¡ä»»æœåŠ¡å™¨çš„安全è¯ä¹¦ã€‚出现此问题的原因å¯èƒ½æ˜¯é…置有误,或是有攻击者拦截您的连接。<ph name="BEGIN_LEARN_MORE_LINK" />了解详情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="8532105204136943229">到期年份</translation>
<translation id="8543181531796978784">您å¯ä»¥<ph name="BEGIN_ERROR_LINK" />报告检测问题<ph name="END_ERROR_LINK" />;或者,如果您了解自己将é¢ä¸´çš„安全风险,则å¯ä»¥<ph name="BEGIN_LINK" />访问这个ä¸å®‰å…¨çš„网站<ph name="END_LINK" />。</translation>
<translation id="8553075262323480129">系统无法确定该网页的语言,因此无法进行翻译。</translation>
-<translation id="8559762987265718583">您设备的日期和时间(<ph name="DATE_AND_TIME" />)ä¸æ­£ç¡®ï¼Œå› æ­¤æ— æ³•ä¸Ž <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§å¯†è¿žæŽ¥ã€‚</translation>
<translation id="8571890674111243710">正在将网页翻译æˆ<ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">添加电è¯å·ç 
</translation>
@@ -817,6 +891,7 @@
<translation id="8738058698779197622">è¦å»ºç«‹å®‰å…¨è¿žæŽ¥ï¼Œæ‚¨çš„时钟设置必须正确。这是因为,网站用于è¯æ˜Žèº«ä»½çš„è¯ä¹¦ä»…在特定时间段有效。由于您设备的时钟ä¸æ­£ç¡®ï¼Œå› æ­¤ Chromium 无法验è¯è¿™äº›è¯ä¹¦ã€‚</translation>
<translation id="8740359287975076522">无法找到 <ph name="HOST_NAME" /> çš„ &lt;abbr id="dnsDefinition"&gt;DNS 地å€&lt;/abbr&gt;。正在诊断该问题。</translation>
<translation id="8759274551635299824">此信用å¡å·²å¤±æ•ˆ</translation>
+<translation id="8761567432415473239">Google安全æµè§ˆåŠŸèƒ½æœ€è¿‘在<ph name="SITE" />上<ph name="BEGIN_LINK" />å‘现了有害程åº<ph name="END_LINK" />。</translation>
<translation id="8790007591277257123">æ¢å¤åˆ é™¤(&amp;R)</translation>
<translation id="8800988563907321413">此处将显示系统建议您æµè§ˆçš„附近网页</translation>
<translation id="8820817407110198400">书签</translation>
@@ -829,29 +904,30 @@
<translation id="8870413625673593573">最近关闭的标签页</translation>
<translation id="8874824191258364635">请输入有效的信用å¡å·</translation>
<translation id="8876793034577346603">无法解æžç½‘络é…置。</translation>
-<translation id="8877192140621905067">在您确认åŽï¼Œæ‚¨çš„信用å¡è¯¦æƒ…将与此网站共享</translation>
<translation id="8889402386540077796">色调</translation>
<translation id="8891727572606052622">代ç†æ¨¡å¼æ— æ•ˆã€‚</translation>
<translation id="889901481107108152">抱歉,此项实验性功能ä¸èƒ½ç”¨äºŽæ‚¨çš„å¹³å°ã€‚</translation>
<translation id="8903921497873541725">放大</translation>
<translation id="8931333241327730545">è¦å°†æ­¤å¡çš„ä¿¡æ¯ä¿å­˜åˆ°æ‚¨çš„ Google å¸å·å—?</translation>
<translation id="8932102934695377596">您的时钟慢了</translation>
-<translation id="8954894007019320973">(续)</translation>
<translation id="8971063699422889582">æœåŠ¡å™¨çš„è¯ä¹¦å·²è¿‡æœŸã€‚</translation>
<translation id="8986494364107987395">将使用情况统计信æ¯å’Œå´©æºƒæŠ¥å‘Šè‡ªåŠ¨å‘é€ç»™ Google</translation>
-<translation id="8987927404178983737">月</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">您è¦è®¿é—®çš„网站包å«æœ‰å®³ç¨‹åº</translation>
+<translation id="8997023839087525404">该æœåŠ¡å™¨æ供了一个未通过è¯ä¹¦é€æ˜Žåº¦æ”¿ç­–公开披露的è¯ä¹¦ã€‚æŸäº›è¯ä¹¦å¿…须通过è¯ä¹¦é€æ˜Žåº¦æ”¿ç­–进行公开披露,以确ä¿å®ƒä»¬å€¼å¾—信任且能ä¿æŠ¤ç”¨æˆ·å…é­æ”»å‡»ã€‚</translation>
<translation id="9001074447101275817">ä»£ç† (<ph name="DOMAIN" />) è¦æ±‚æ供用户å和密ç ã€‚</translation>
+<translation id="9005998258318286617">未能加载 PDF 文档。</translation>
<translation id="901974403500617787">应用于整个系统的设置åªèƒ½ç”±ä»¥ä¸‹æ‰€æœ‰è€…设定:<ph name="OWNER_EMAIL" />。</translation>
+<translation id="9020200922353704812">必须输入信用å¡å¸å•é‚®å¯„地å€</translation>
<translation id="9020542370529661692">已将此网页内容翻译æˆ<ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">安全错误</translation>
<translation id="9038649477754266430">使用è”想查询æœåŠ¡æ›´å¿«é€Ÿåœ°åŠ è½½ç½‘页</translation>
<translation id="9039213469156557790">而且,此页中包å«å…¶ä»–ä¸å®‰å…¨çš„资æºã€‚他人能在这些资æºä¼ è¾“过程中进行查看,而攻击者å¯ä»¥ä¿®æ”¹è¿™äº›èµ„æºï¼Œä»Žè€Œæ”¹å˜æ­¤é¡µçš„行为。</translation>
-<translation id="9040185888511745258"><ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻击者å¯èƒ½ä¼šè¯•å›¾éª—您安装有æŸæµè§ˆä½“验的程åºï¼ˆä¾‹å¦‚更改您的主页或在您访问的网站上显示é¢å¤–的广告)。</translation>
+<translation id="9049981332609050619">您试图访问 <ph name="DOMAIN" />,但æœåŠ¡å™¨æ供的è¯ä¹¦æ— æ•ˆã€‚</translation>
<translation id="9050666287014529139">密ç </translation>
<translation id="9065203028668620118">修改</translation>
<translation id="9068849894565669697">选择颜色</translation>
+<translation id="9069693763241529744">已被æŸæ¬¾æ‰©å±•ç¨‹åºé˜»æ­¢</translation>
<translation id="9076283476770535406">此网站å¯èƒ½åŒ…å«æˆäººå†…容</translation>
<translation id="9078964945751709336">å¿…é¡»æ供更多信æ¯</translation>
<translation id="9103872766612412690"><ph name="SITE" /> 通常会使用加密技术æ¥ä¿æŠ¤æ‚¨çš„ä¿¡æ¯ã€‚Chromium 此次å°è¯•è¿žæŽ¥åˆ° <ph name="SITE" /> 时,此网站å‘回了异常的错误凭æ®ã€‚è¿™å¯èƒ½æ˜¯å› ä¸ºæœ‰æ”»å‡»è€…在试图冒充 <ph name="SITE" />,或 Wi-Fi 登录å±å¹•ä¸­æ–­äº†æ­¤æ¬¡è¿žæŽ¥ã€‚请放心,您的信æ¯ä»ç„¶æ˜¯å®‰å…¨çš„,因为 Chromium 尚未进行任何数æ®äº¤æ¢ä¾¿åœæ­¢äº†è¿žæŽ¥ã€‚</translation>
@@ -860,16 +936,21 @@
<translation id="9148507642005240123">撤消修改(&amp;U)</translation>
<translation id="9154194610265714752">已更新</translation>
<translation id="9157595877708044936">正在设置...</translation>
+<translation id="9169664750068251925">在此网站上始终阻止</translation>
<translation id="9170848237812810038">撤消(&amp;U)</translation>
<translation id="917450738466192189">æœåŠ¡å™¨è¯ä¹¦æ— æ•ˆã€‚</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ç§é€è´§æ–¹å¼}other{<ph name="SHIPPING_OPTION_PREVIEW" />以åŠå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ç§é€è´§æ–¹å¼}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> 使用了ä¸å—支æŒçš„å议。</translation>
<translation id="9205078245616868884">您的数æ®å·²ä½¿ç”¨æ‚¨çš„åŒæ­¥å¯†ç åŠ å¯†ã€‚输入该密ç å³å¯å¼€å§‹åŒæ­¥ã€‚</translation>
<translation id="9207861905230894330">无法添加文章。</translation>
+<translation id="9219103736887031265">图片</translation>
<translation id="933612690413056017">未连接到互è”网</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">清除表å•å†…容</translation>
<translation id="939736085109172342">新建文件夹</translation>
<translation id="941721044073577244">您似乎无æƒè®¿é—®æ­¤ç½‘ç«™</translation>
<translation id="969892804517981540">æ­£å¼ç‰ˆæœ¬</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{无}=1{1 项内容}other{# 项内容}}</translation>
<translation id="988159990683914416">å¼€å‘者内部版本</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_strings_zh-TW.xtb b/chromium/components/strings/components_strings_zh-TW.xtb
index cf06d29a33c..659321a7742 100644
--- a/chromium/components/strings/components_strings_zh-TW.xtb
+++ b/chromium/components/strings/components_strings_zh-TW.xtb
@@ -7,7 +7,6 @@
<translation id="1032854598605920125">順時é‡æ—‹è½‰</translation>
<translation id="1038842779957582377">ä¸æ˜Žå稱</translation>
<translation id="1050038467049342496">關閉其他應用程å¼</translation>
-<translation id="1053591932240354961">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站傳é€çš„憑證å«æœ‰äº‚碼,Google Chrome 無法處ç†ã€‚網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1055184225775184556">復原新增(&amp;U)</translation>
<translation id="10614374240317010">一律ä¸å„²å­˜</translation>
<translation id="106701514854093668">電腦版書籤</translation>
@@ -21,9 +20,12 @@
<translation id="112840717907525620">政策快å–正確</translation>
<translation id="113188000913989374"><ph name="SITE" /> 顯示:</translation>
<translation id="1132774398110320017">Chrome 自動填入設定...</translation>
+<translation id="1150979032973867961">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證未å–得你電腦作業系統的信任。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
+<translation id="1151972924205500581">請輸入密碼</translation>
<translation id="1152921474424827756">å­˜å– <ph name="URL" /> çš„<ph name="BEGIN_LINK" />é åº«å­˜æª”副本<ph name="END_LINK" /></translation>
<translation id="1158211211994409885"><ph name="HOST_NAME" /> æ„外中斷連線。</translation>
<translation id="1161325031994447685">é‡æ–°é€£ç·šè‡³ Wi-Fi 網路</translation>
+<translation id="1165039591588034296">錯誤</translation>
<translation id="1175364870820465910">列å°(&amp;P)...</translation>
<translation id="1181037720776840403">移除</translation>
<translation id="1184214524891303587"><ph name="BEGIN_WHITEPAPER_LINK" />è‡ªå‹•å‘ Google 回報<ph name="END_WHITEPAPER_LINK" />疑似安全性事件的詳細資料。<ph name="PRIVACY_PAGE_LINK" /></translation>
@@ -31,30 +33,41 @@
<translation id="1201895884277373915">這個網站的更多內容</translation>
<translation id="1206967143813997005">縮寫簽å無效</translation>
<translation id="1209206284964581585">暫時隱è—</translation>
+<translation id="121201262018556460">你嘗試å‰å¾€ <ph name="DOMAIN" />,但伺æœå™¨æ‰€æ供的憑證å«æœ‰é˜²è­·åŠ›è–„弱的金鑰。攻擊者å¯èƒ½å·²ç ´å£žç§å¯†é‡‘鑰,而該伺æœå™¨å¯èƒ½ä¸¦éžä½ çš„目標伺æœå™¨ (你的連線å°è±¡å¯èƒ½æ˜¯æ”»æ“Šè€…的電腦)。</translation>
<translation id="1219129156119358924">系統安全性</translation>
<translation id="1227224963052638717">ä¸æ˜Žæ”¿ç­–。</translation>
<translation id="1227633850867390598">éš±è—政策值</translation>
<translation id="1228893227497259893">實體識別碼錯誤</translation>
<translation id="1232569758102978740">未命å</translation>
+<translation id="1253921432148366685"><ph name="TYPE_1" />ã€<ph name="TYPE_2" /> (å·²åŒæ­¥)</translation>
<translation id="1263231323834454256">閱讀清單</translation>
<translation id="1264126396475825575">當機報告擷å–時間:<ph name="CRASH_TIME" /> (尚未上傳或略éŽ)</translation>
+<translation id="1281526147609854549">核發者:<ph name="ISSUER" /></translation>
+<translation id="1283919782143846010">å·²å°éŽ–ä¸å®‰å…¨çš„內容</translation>
<translation id="1285320974508926690">一律ä¸ç¿»è­¯æ­¤ç¶²ç«™</translation>
<translation id="129553762522093515">最近關閉的分é </translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />試試看清除 Cookie<ph name="END_LINK" /></translation>
+<translation id="1333989956347591814">以下å„æ–¹<ph name="BEGIN_EMPHASIS" />å¯èƒ½ä»æœƒçœ‹åˆ°<ph name="END_EMPHASIS" />你的活動:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />你造訪的網站
+ <ph name="LIST_ITEM" />你的雇主或學校
+ <ph name="LIST_ITEM" />你的網際網路æœå‹™ä¾›æ‡‰å•†
+ <ph name="END_LIST" /></translation>
<translation id="1339601241726513588">註冊網域:</translation>
<translation id="1340482604681802745">å–件地å€</translation>
<translation id="1344211575059133124">ä½ å¿…é ˆç²å¾—授權,æ‰èƒ½é€ è¨ªé€™å€‹ç¶²ç«™</translation>
<translation id="1344588688991793829">Chromium 自動填入設定...</translation>
+<translation id="1348198688976932919">ä½ è¦é€ è¨ªçš„網站å«æœ‰ä¸å®‰å…¨çš„應用程å¼</translation>
<translation id="1374468813861204354">建議</translation>
<translation id="1375198122581997741">關於版本</translation>
<translation id="1377321085342047638">å¡è™Ÿ</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> 未傳é€ä»»ä½•è³‡æ–™ã€‚</translation>
<translation id="1407135791313364759">全部開啟</translation>
<translation id="1413809658975081374">éš±ç§æ¬Šè¨­å®šç™¼ç”ŸéŒ¯èª¤</translation>
+<translation id="14171126816530869">ä½æ–¼ <ph name="LOCALITY" /> çš„ <ph name="ORGANIZATION" />ï¼Œå·²ç¶“éŽ <ph name="ISSUER" /> 驗證身分。</translation>
<translation id="1426410128494586442">是</translation>
<translation id="1430915738399379752">列å°</translation>
-<translation id="1442912890475371290">å·²å°éŽ–<ph name="BEGIN_LINK" />造訪ä½æ–¼ <ph name="DOMAIN" /> 的網é <ph name="END_LINK" />çš„è¦æ±‚。</translation>
-<translation id="1491663344921578213">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站使用憑證鎖定功能。網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="1495172241291051507">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" /> å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> 種付款方å¼}other{<ph name="PAYMENT_METHOD_PREVIEW" /> å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> 種付款方å¼}}</translation>
<translation id="1506687042165942984">顯示這個網é çš„儲存複本 (亦å³ç¾å·²ä¸å†ä½¿ç”¨çš„版本)。</translation>
<translation id="1517433312004943670">必須輸入電話號碼</translation>
<translation id="1519264250979466059">建立日期</translation>
@@ -62,12 +75,11 @@
<translation id="1549470594296187301">您必須啟用 JavaScript æ‰èƒ½ä½¿ç”¨é€™é …功能。</translation>
<translation id="1555130319947370107">è—色</translation>
<translation id="1559528461873125649">找ä¸åˆ°ä½ æ‰€æŒ‡å®šçš„檔案或目錄</translation>
-<translation id="1559572115229829303">&lt;p&gt;您è£ç½®çš„日期和時間 (<ph name="DATE_AND_TIME" />) ä¸æ­£ç¢ºï¼Œå› æ­¤ç„¡æ³•èˆ‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§äººé€£ç·šã€‚&lt;/p&gt;
-
- &lt;p&gt;è«‹å‰å¾€ã€Œè¨­å®šã€æ‡‰ç”¨ç¨‹å¼çš„「一般設定ã€å°ˆå€èª¿æ•´æ—¥æœŸå’Œæ™‚間。&lt;strong&gt;&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;</translation>
<translation id="1583429793053364125">顯示這個網é æ™‚發生錯誤。</translation>
<translation id="1592005682883173041">本機資料存å–權</translation>
+<translation id="1594030484168838125">é¸æ“‡</translation>
<translation id="161042844686301425">é’色</translation>
+<translation id="1620510694547887537">æ”影機</translation>
<translation id="1629803312968146339">您希望 Chrome 儲存這張信用å¡å—Žï¼Ÿ</translation>
<translation id="1639239467298939599">載入中</translation>
<translation id="1640180200866533862">使用者政策</translation>
@@ -75,11 +87,12 @@
<translation id="1644184664548287040">網路設定無效,無法匯入。</translation>
<translation id="1644574205037202324">æ­·å²ç´€éŒ„</translation>
<translation id="1645368109819982629">ä¸æ”¯æ´çš„通訊å”定</translation>
+<translation id="1655462015569774233">{1,plural, =1{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證已在昨天éŽæœŸã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截您的連線。您電腦的時é˜ç›®å‰è¨­ç‚º <ph name="CURRENT_DATE" />,這是正確的時間嗎?如果ä¸æ˜¯çš„話,請更新系統時é˜ï¼Œç„¶å¾Œé‡æ–°æ•´ç†é€™å€‹ç¶²é ã€‚}other{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證已在 # 天å‰éŽæœŸã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截您的連線。您電腦的時é˜ç›®å‰è¨­ç‚º <ph name="CURRENT_DATE" />,這是正確的時間嗎?如果ä¸æ˜¯çš„話,請更新系統時é˜ï¼Œç„¶å¾Œé‡æ–°æ•´ç†é€™å€‹ç¶²é ã€‚}}</translation>
<translation id="1656489000284462475">å–件</translation>
<translation id="1663943134801823270">信用å¡å’Œåœ°å€è³‡è¨Šçš†ä¾†è‡ª Chrome。你å¯ä»¥åœ¨<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />é é¢ç®¡ç†é€™äº›è³‡è¨Šã€‚</translation>
<translation id="1676269943528358898"><ph name="SITE" /> 通常使用加密方å¼ä¿è­·æ‚¨çš„資訊。但 Google Chrome 這次嘗試連線到 <ph name="SITE" /> 時,該網站傳回了異常且錯誤的憑證。這å¯èƒ½æ˜¯å› ç‚ºæœ‰æ”»æ“Šè€…ä¼åœ–å½è£æˆ <ph name="SITE" />,或是å—到 Wi-Fi 登入畫é¢å½±éŸ¿è€Œé€ æˆé€£ç·šä¸­æ–·ã€‚ä¸éŽè«‹æ”¾å¿ƒï¼ŒGoogle Chrome å·²åŠæ™‚åœæ­¢é€£ç·šï¼Œä¸¦æœªå‚³è¼¸ä»»ä½•è³‡æ–™ï¼Œå› æ­¤æ‚¨çš„資訊ä»ç„¶å®‰å…¨ç„¡è™žã€‚</translation>
-<translation id="168328519870909584">攻擊者目å‰å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在您的è£ç½®ä¸Šå®‰è£å±éšªçš„應用程å¼ï¼Œè—‰æ­¤ç«Šå–或刪除您的資訊 (例如相片ã€å¯†ç¢¼ã€éƒµä»¶æˆ–信用å¡è³‡æ–™)。</translation>
<translation id="168841957122794586">伺æœå™¨æ†‘è­‰å«æœ‰é˜²è­·åŠ›è–„弱的加密編譯金鑰。</translation>
+<translation id="1706954506755087368">{1,plural, =1{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證é å®šæ˜Žå¤©æ‰ç”Ÿæ•ˆã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截您的連線。}other{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證é å®š # 天後æ‰ç”Ÿæ•ˆã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截您的連線。}}</translation>
<translation id="1710259589646384581">作業系統</translation>
<translation id="1721312023322545264">ä½ å¿…é ˆç²å¾—<ph name="NAME" />授權,æ‰èƒ½é€ è¨ªé€™å€‹ç¶²ç«™</translation>
<translation id="1721424275792716183">* 這是必填欄ä½</translation>
@@ -91,22 +104,26 @@
<translation id="1745358365027406341">ç¨å¾Œä¸‹è¼‰ç¶²é </translation>
<translation id="17513872634828108">開啟分é </translation>
<translation id="1753706481035618306">é ç¢¼</translation>
+<translation id="1763864636252898013">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證未å–å¾—ä½ è£ç½®ä½œæ¥­ç³»çµ±çš„信任。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
<translation id="1768211456781949159"><ph name="BEGIN_LINK" />嘗試執行 Windows 網路診斷<ph name="END_LINK" />。</translation>
<translation id="1783075131180517613">è«‹æ›´æ–°ä½ çš„åŒæ­¥é€šé—œå¯†èªžã€‚</translation>
<translation id="1787142507584202372">這裡會顯示你最近開啟的分é </translation>
+<translation id="1789575671122666129">彈出å¼è¦–窗</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
<translation id="1803264062614276815">æŒå¡äººå§“å</translation>
-<translation id="1803678881841855883">Google 安全ç€è¦½åŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />åµæ¸¬åˆ°æƒ¡æ„軟體<ph name="END_LINK" />。å³ä½¿æ˜¯å¹³å¸¸å¯ä»¥å®‰å…¨ä½¿ç”¨çš„網站,有時也會é­åˆ°æƒ¡æ„軟體感染。這些惡æ„內容來自已知的惡æ„軟體散佈網站 <ph name="SUBRESOURCE_HOST" />。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="1806541873155184440">新增日期:<ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="1821930232296380041">è¦æ±‚或è¦æ±‚åƒæ•¸ç„¡æ•ˆ</translation>
<translation id="1826516787628120939">檢查中</translation>
<translation id="1834321415901700177">這個網站å«æœ‰æœ‰å®³ç¨‹å¼</translation>
+<translation id="1840414022444569775">這組信用å¡è™Ÿç¢¼å·²ç¶“使用éŽäº†</translation>
<translation id="1842969606798536927">支付</translation>
<translation id="1871208020102129563">Proxy 設定為使用固定的 Proxy 伺æœå™¨ï¼Œè€Œéž .pac 指令碼網å€ã€‚</translation>
<translation id="1871284979644508959">必填欄ä½</translation>
<translation id="187918866476621466">開啟起始網é </translation>
<translation id="1883255238294161206">收åˆæ¸…å–®</translation>
+<translation id="1894246157993903018">{SHIPPING_ADDRESS,plural, =1{「<ph name="SHIPPING_ADDRESS_PREVIEW" />ã€å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 個地å€}other{「<ph name="SHIPPING_ADDRESS_PREVIEW" />ã€å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> 個地å€}}</translation>
<translation id="1898423065542865115">篩é¸</translation>
+<translation id="192020519938775529">{COUNT,plural, =0{無}=1{1 個網站}other{# 個網站}}</translation>
<translation id="194030505837763158">å‰å¾€ <ph name="LINK" /></translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> 書籤</translation>
<translation id="1973335181906896915">åºåˆ—化錯誤</translation>
@@ -130,42 +147,48 @@
<translation id="2114841414352855701">由於政策被「<ph name="POLICY_NAME" />ã€è¦†å¯«äº†ï¼Œå› æ­¤é­åˆ°ç•¥éŽã€‚</translation>
<translation id="2138201775715568214">正在尋找附近的實體化網路網é </translation>
<translation id="213826338245044447">行動版書籤</translation>
-<translation id="2148716181193084225">今天</translation>
+<translation id="2147827593068025794">背景åŒæ­¥è™•ç†</translation>
<translation id="2154054054215849342">你的網域無法使用åŒæ­¥åŠŸèƒ½</translation>
<translation id="2154484045852737596">編輯å¡ç‰‡è³‡è¨Š</translation>
<translation id="2166049586286450108">完整管ç†å“¡å­˜å–權</translation>
<translation id="2166378884831602661">這個網站無法æ供安全連線</translation>
<translation id="2181821976797666341">政策</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 個地å€}other{# 個地å€}}</translation>
+<translation id="2187317261103489799">åµæ¸¬ (é è¨­)</translation>
<translation id="2202020181578195191">請輸入有效的到期年份</translation>
<translation id="2212735316055980242">找ä¸åˆ°æ”¿ç­–</translation>
<translation id="2213606439339815911">正在擷å–é …ç›®...</translation>
+<translation id="2218879909401188352">ç›®å‰åœ¨ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻擊者å¯èƒ½æœƒè®“你安è£ä¸å®‰å…¨çš„應用程å¼ï¼Œå°Žè‡´è£ç½®å—æã€æ‰‹æ©Ÿå¸³å–®ä¸­å¤šå‡ºéš±è—費用,或是個人資訊é­ç«Šã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2230458221926704099">請使用<ph name="BEGIN_LINK" />診斷應用程å¼<ph name="END_LINK" />修正連線å•é¡Œ</translation>
<translation id="2239100178324503013">ç«‹å³å‚³é€</translation>
<translation id="225207911366869382">這個政策值已é­æ±°æ›ã€‚</translation>
<translation id="2262243747453050782">HTTP 錯誤</translation>
+<translation id="2270484714375784793">電話號碼</translation>
<translation id="2282872951544483773">無法使用的實驗性功能</translation>
+<translation id="2283595600756901917">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> 個項目}other{<ph name="ITEM_COUNT" /> 個項目}}</translation>
<translation id="2292556288342944218">您的網際網路存å–權é­åˆ°å°éŽ–</translation>
<translation id="230155334948463882">新信用å¡ï¼Ÿ</translation>
-<translation id="2305919008529760154">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證核發來æºæœ‰è©æ¬ºå«Œç–‘。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> è¦æ±‚æ供使用者å稱和密碼。</translation>
-<translation id="2318774815570432836">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站使用 HSTS。網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2337852623177822836">管ç†å“¡æ‰€æŽ§åˆ¶çš„設定</translation>
<translation id="2354001756790975382">其他書籤</translation>
+<translation id="2354430244986887761">Google 安全ç€è¦½æœå‹™æœ€è¿‘在 <ph name="SITE" /> <ph name="BEGIN_LINK" />發ç¾æœ‰å®³çš„應用程å¼<ph name="END_LINK" />。</translation>
<translation id="2355395290879513365">攻擊者å¯èƒ½æœƒçœ‹åˆ°ä½ æ­£åœ¨é€™å€‹ç¶²ç«™ä¸Šç€è¦½çš„圖片,並以修改圖片內容的方å¼è®“ä½ å—騙。</translation>
+<translation id="2356070529366658676">è©¢å•</translation>
+<translation id="2359629602545592467">多種</translation>
<translation id="2359808026110333948">繼續</translation>
<translation id="2365563543831475020">當機報告擷å–時間:<ph name="CRASH_TIME" /> (尚未上傳)</translation>
<translation id="2367567093518048410">等級</translation>
-<translation id="2371153335857947666">{1,plural, =1{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證已在昨天éŽæœŸã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。電腦的時é˜ç›®å‰è¨­ç‚º <ph name="CURRENT_DATE" />,這是正確的時間嗎?如果ä¸æ˜¯çš„話,請更新系統時é˜ï¼Œç„¶å¾Œé‡æ–°æ•´ç†é€™å€‹ç¶²é ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" />}other{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證已在 # 天å‰éŽæœŸã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。電腦的時é˜ç›®å‰è¨­ç‚º <ph name="CURRENT_DATE" />,這是正確的時間嗎?如果ä¸æ˜¯çš„話,請更新系統時é˜ï¼Œç„¶å¾Œé‡æ–°æ•´ç†é€™å€‹ç¶²é ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" />}}</translation>
<translation id="237718015863234333">沒有å¯ç”¨çš„替代使用者介é¢</translation>
<translation id="2384307209577226199">ä¼æ¥­é è¨­</translation>
<translation id="2386255080630008482">伺æœå™¨æ†‘證已é­æ’¤éŠ·ã€‚</translation>
<translation id="2392959068659972793">顯示尚未設定任何值的政策</translation>
<translation id="239429038616798445">ä¸æ”¯æ´æ‰€é¸çš„é‹é€æ–¹å¼ï¼Œè«‹æ”¹é¸å…¶ä»–æ–¹å¼ã€‚</translation>
<translation id="2396249848217231973">復原刪除(&amp;U)</translation>
-<translation id="2460160116472764928">Google 安全ç€è¦½åŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />åµæ¸¬åˆ°æƒ¡æ„軟體<ph name="END_LINK" />。å³ä½¿æ˜¯å¹³å¸¸å¯ä»¥å®‰å…¨ä½¿ç”¨çš„網站,有時也會é­åˆ°æƒ¡æ„軟體感染。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2413528052993050574">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證已é­æ’¤éŠ·ã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
<translation id="2463739503403862330">å¡«å…¥</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />執行網路診斷<ph name="END_LINK" /></translation>
<translation id="2479410451996844060">無效的æœå°‹ç¶²å€ã€‚</translation>
+<translation id="2482878487686419369">通知</translation>
<translation id="2491120439723279231">伺æœå™¨æ†‘è­‰å«æœ‰éŒ¯èª¤ã€‚</translation>
<translation id="2495083838625180221">JSON 剖æžå™¨</translation>
<translation id="2495093607237746763">勾é¸å¾Œï¼ŒChromium 會將您的信用å¡è³‡æ–™å„²å­˜åœ¨é€™å€‹è£ç½®ä¸Šï¼Œä»¥åŠ å¿«è¡¨å–®å¡«å¯«é€Ÿåº¦ã€‚</translation>
@@ -173,27 +196,28 @@
<translation id="2501278716633472235">返回</translation>
<translation id="2515629240566999685">檢查所在ä½ç½®çš„網路訊號</translation>
<translation id="2516305470678292029">替代使用者介é¢</translation>
+<translation id="2539524384386349900">åµæ¸¬</translation>
<translation id="255002559098805027"><ph name="HOST_NAME" /> 傳é€çš„回應無效。</translation>
-<translation id="2552545117464357659">較新紀錄</translation>
<translation id="2556876185419854533">復原編輯(&amp;U)</translation>
<translation id="2587730715158995865">出自「<ph name="ARTICLE_PUBLISHER" />ã€ã€‚閱讀這篇報導和å¦å¤– <ph name="OTHER_ARTICLE_COUNT" /> 篇報導。</translation>
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">此文件å—到密碼ä¿è­·ï¼Œè«‹è¼¸å…¥å¯†ç¢¼ã€‚</translation>
<translation id="2609632851001447353">變化版本</translation>
+<translation id="262424810616849754">{COUNT,plural, =0{ç„¡}=1{1 å€‹æ‡‰ç”¨ç¨‹å¼ ($1)}=2{2 å€‹æ‡‰ç”¨ç¨‹å¼ ($1ã€$2)}other{# å€‹æ‡‰ç”¨ç¨‹å¼ ($1ã€$2 $3)}}</translation>
<translation id="2625385379895617796">你的時é˜æ™‚é–“éŽå¿«</translation>
<translation id="2639739919103226564">狀態:</translation>
+<translation id="2649204054376361687"><ph name="COUNTRY" />,<ph name="CITY" /></translation>
<translation id="2650446666397867134">å­˜å–檔案é­æ‹’</translation>
<translation id="2653659639078652383">æ交</translation>
<translation id="2666117266261740852">關閉其他分é æˆ–應用程å¼</translation>
+<translation id="2670429602441959756">這個網é æ‰€å«çš„功能目å‰èˆ‡ VR ä¸ç›¸å®¹ã€‚正在çµæŸ VR 模å¼...</translation>
<translation id="2674170444375937751">確定è¦å¾žä½ çš„紀錄中刪除這些網é å—Žï¼Ÿ</translation>
<translation id="2677748264148917807">離開</translation>
-<translation id="269990154133806163">這個伺æœå™¨çš„憑證並未根據憑證é€æ˜ŽåŒ–政策å°å¤–公開。部分憑證必須符åˆé€™é …è¦å®šï¼Œä»¥ç¢ºä¿æ†‘證值得信任,ä¸æœƒè®“使用者é­åˆ°æ”»æ“Šã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2702801445560668637">閱讀清單</translation>
<translation id="2704283930420550640">政策值格å¼ä¸ç¬¦ã€‚</translation>
<translation id="2704951214193499422">Chromium ç›®å‰ç„¡æ³•é©—證您的信用å¡ï¼Œè«‹ç¨å¾Œå†è©¦ã€‚</translation>
<translation id="2705137772291741111">已儲存 (å¿«å–) 這個網站的複本,但無法讀å–。</translation>
<translation id="2709516037105925701">自動填入</translation>
-<translation id="2712118517637785082">你嘗試連上 <ph name="DOMAIN" />,但伺æœå™¨çš„憑證已é­åˆ°æ ¸ç™¼å–®ä½æ’¤éŠ·ã€‚在這種情æ³ä¸‹ï¼Œè«‹å‹¿ä¿¡ä»»ä¼ºæœå™¨æ供的安全性憑證。你的連線å°è±¡å¯èƒ½æ˜¯æ”»æ“Šè€…的電腦。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2712173769900027643">è¦æ±‚權é™</translation>
<translation id="2713444072780614174">白色</translation>
<translation id="2720342946869265578">鄰近網é </translation>
@@ -206,19 +230,22 @@
<translation id="277499241957683684">沒有è£ç½®ç´€éŒ„</translation>
<translation id="2784949926578158345">連線已é‡è¨­ã€‚</translation>
<translation id="2794233252405721443">網站é­åˆ°å°éŽ–</translation>
+<translation id="2799020568854403057">ä½ è¦é€ è¨ªçš„網站å«æœ‰æœ‰å®³çš„應用程å¼</translation>
+<translation id="2803306138276472711">Google 安全ç€è¦½åŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />åµæ¸¬åˆ°æƒ¡æ„軟體<ph name="END_LINK" />。å³ä½¿æ˜¯å¹³å¸¸å¯ä»¥å®‰å…¨ä½¿ç”¨çš„網站,有時也會é­åˆ°æƒ¡æ„軟體感染。</translation>
<translation id="2824775600643448204">網å€èˆ‡æœå°‹åˆ—</translation>
<translation id="2826760142808435982">連線採用 <ph name="CIPHER" /> 加密,並設有 <ph name="KX" /> 金鑰交æ›æ©Ÿåˆ¶ã€‚</translation>
<translation id="2835170189407361413">清除表單</translation>
+<translation id="2856444702002559011">攻擊者å¯èƒ½æœƒè©¦åœ–從 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ç«Šå–你的資訊 (例如密碼ã€éƒµä»¶æˆ–信用å¡è³‡æ–™)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="2889159643044928134">ä¸è¦é‡æ–°è¼‰å…¥</translation>
<translation id="2900469785430194048">Google Chrome 嘗試顯示這個網é æ™‚用盡了記憶體。</translation>
<translation id="2909946352844186028">系統åµæ¸¬åˆ°ç¶²è·¯è®Šæ›´ã€‚</translation>
<translation id="2916038427272391327">關閉其他程å¼</translation>
<translation id="2922350208395188000">無法檢查伺æœå™¨æ†‘證。</translation>
<translation id="2928905813689894207">帳單地å€</translation>
+<translation id="2941952326391522266">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證來自 <ph name="DOMAIN2" /> 網域。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
<translation id="2948083400971632585">ä½ å¯ä»¥åœ¨è¨­å®šé é¢åœç”¨ä»»ä½•ç‚ºé€£ç·šè¨­ç½®çš„ Proxy。</translation>
<translation id="2955913368246107853">關閉æœå°‹åˆ—</translation>
<translation id="2958431318199492670">網路設定未éµå¾ª ONC 標準,系統å¯èƒ½ç„¡æ³•åŒ¯å…¥éƒ¨åˆ†è¨­å®šã€‚</translation>
-<translation id="29611076221683977">攻擊者目å‰å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在你的 Mac 上安è£å±éšªç¨‹å¼ï¼Œè—‰æ­¤ç«Šå–或刪除你的資訊 (例如相片ã€å¯†ç¢¼ã€éƒµä»¶æˆ–信用å¡è³‡æ–™)。</translation>
<translation id="2966678944701946121">到期日:<ph name="EXPIRATION_DATE_ABBR" />,新增日期:<ph name="ADDED_TO_AUTOFILL_MONTH" /></translation>
<translation id="2969319727213777354">您必須正確設定時é˜ï¼Œæ‰èƒ½å»ºç«‹å®‰å…¨é€£ç·šã€‚這是因為網站驗證身分時所使用的憑證僅於特定一段時間內有效。由於您è£ç½®çš„時é˜ä¸æ­£ç¢ºï¼Œå› æ­¤ Google Chrome 無法驗證這些憑證。</translation>
<translation id="2972581237482394796">é‡åš(&amp;R)</translation>
@@ -226,19 +253,22 @@
<translation id="2985398929374701810">請輸入有效的地å€</translation>
<translation id="2986368408720340940">ä¸æ”¯æ´æ‰€é¸çš„å–件方å¼ï¼Œè«‹æ”¹é¸å…¶ä»–æ–¹å¼ã€‚</translation>
<translation id="2991174974383378012">與網站分享</translation>
+<translation id="2991571918955627853">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站使用 HSTS。網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚</translation>
<translation id="3005723025932146533">顯示儲存的複本</translation>
<translation id="3008447029300691911">請輸入 <ph name="CREDIT_CARD" /> 的信用å¡å®‰å…¨ç¢¼ã€‚完æˆé©—證後,這個網站就會å–得您的信用å¡è©³ç´°è³‡è¨Šã€‚</translation>
<translation id="3010559122411665027">清單項目「<ph name="ENTRY_INDEX" />ã€ï¼š<ph name="ERROR" /></translation>
+<translation id="301521992641321250">已自動å°éŽ–</translation>
<translation id="3024663005179499861">政策類型有誤</translation>
<translation id="3032412215588512954">您è¦é‡æ–°è¼‰å…¥é€™å€‹ç¶²ç«™å—Žï¼Ÿ</translation>
<translation id="3037605927509011580">糟糕ï¼</translation>
-<translation id="3040955737384246924">{COUNT,plural, =0{在已åŒæ­¥çš„è£ç½®ä¸Šè‡³å°‘有 1 個項目}=1{1 個項目 (在已åŒæ­¥çš„è£ç½®ä¸Šé‚„有更多項目)}other{# 個項目 (在已åŒæ­¥çš„è£ç½®ä¸Šé‚„有更多項目)}}</translation>
<translation id="3041612393474885105">憑證資訊</translation>
<translation id="3063697135517575841">Chrome ç›®å‰ç„¡æ³•é©—證您的信用å¡ï¼Œè«‹ç¨å¾Œå†è©¦ã€‚</translation>
<translation id="3064966200440839136">å³å°‡é›¢é–‹ç„¡ç—•æ¨¡å¼ï¼Œæ”¹ç‚ºä½¿ç”¨å¤–部應用程å¼ä»˜æ¬¾ï¼Œè¦ç¹¼çºŒå—Žï¼Ÿ</translation>
+<translation id="3083099961703215236">{COUNT,plural, =0{無}=1{1 組密碼}other{# 組密碼}}</translation>
<translation id="3093245981617870298">你處於離線狀態。</translation>
<translation id="3105172416063519923">資產 ID:</translation>
<translation id="3109728660330352905">您未ç²å¾—授權,無法ç€è¦½é€™å€‹ç¶²é ã€‚</translation>
+<translation id="3120730422813725195">Elo</translation>
<translation id="31207688938192855"><ph name="BEGIN_LINK" />嘗試執行連線診斷<ph name="END_LINK" />。</translation>
<translation id="3145945101586104090">無法將回應解碼</translation>
<translation id="3150653042067488994">伺æœå™¨æš«æ™‚發生錯誤</translation>
@@ -247,16 +277,20 @@
<translation id="3167968892399408617">當您關閉所有無痕å¼åˆ†é å¾Œï¼Œæ‚¨åœ¨å…¶ä¸­ç€è¦½çš„網é éƒ½ä¸æœƒä¿ç•™åœ¨ç€è¦½å™¨ç´€éŒ„ã€Cookie 儲存庫或æœå°‹ç´€éŒ„中。ä¸éŽï¼Œæ‚¨ä¸‹è¼‰çš„檔案或建立的書籤全部都會ä¿ç•™ä¸‹ä¾†ã€‚</translation>
<translation id="3169472444629675720">Discover</translation>
<translation id="3174168572213147020">島</translation>
+<translation id="317583078218509884">新的網站權é™è¨­å®šæœƒåœ¨é‡æ–°è¼‰å…¥ç¶²é å¾Œç”Ÿæ•ˆã€‚</translation>
<translation id="3176929007561373547">檢查您的 Proxy 設定,或是與您的網路管ç†å“¡è¯çµ¡
確èªæ‚¨çš„ Proxy 伺æœå™¨é‹ä½œæ­£å¸¸ã€‚如果您èªç‚ºè‡ªå·±ä¸éœ€è¦ä½¿ç”¨
Proxy 伺æœå™¨ï¼š
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3200379322500587640">以無痕模å¼é–‹å•Ÿç¶²é </translation>
-<translation id="3202578601642193415">最新記錄</translation>
+<translation id="320323717674993345">å–消付款</translation>
<translation id="3207960819495026254">已加入書籤</translation>
+<translation id="3225919329040284222">伺æœå™¨å‘ˆç¾çš„憑證與內建的é æœŸæ¢ä»¶ä¸ç¬¦ã€‚我們在系統中é‡å°ç‰¹å®šé«˜å®‰å…¨æ€§çš„網站內建了這些é æœŸæ¢ä»¶ï¼Œç›®çš„在於ä¿è­·ä½ çš„資料安全無虞。</translation>
<translation id="3226128629678568754">按下é‡æ–°è¼‰å…¥æŒ‰éˆ•ï¼Œé‡æ–°æ交載入網é æ‰€éœ€çš„資料。</translation>
+<translation id="3227137524299004712">麥克風</translation>
<translation id="3228969707346345236">網é å·²ç¶“是<ph name="LANGUAGE" />,翻譯作業失敗。</translation>
<translation id="323107829343500871">輸入 <ph name="CREDIT_CARD" /> 的信用å¡å®‰å…¨ç¢¼</translation>
+<translation id="3234666976984236645">一律åµæ¸¬é€™å€‹ç¶²ç«™çš„é‡è¦å…§å®¹</translation>
<translation id="3254409185687681395">把此é åŠ å…¥æ›¸ç±¤</translation>
<translation id="3270847123878663523">復原é‡æ–°æŽ’åº(&amp;U)</translation>
<translation id="3282497668470633863">新增æŒå¡äººå§“å</translation>
@@ -270,42 +304,48 @@
<translation id="3340978935015468852">設定</translation>
<translation id="3345135638360864351">無法將您的網站存å–è¦æ±‚傳é€çµ¦<ph name="NAME" />,請å†è©¦ä¸€æ¬¡ã€‚</translation>
<translation id="3355823806454867987">變更 Proxy 設定...</translation>
+<translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />ä¸æœƒå„²å­˜<ph name="END_EMPHASIS" />下列資訊:
+ <ph name="BEGIN_LIST" />
+ <ph name="LIST_ITEM" />ä½ çš„ç€è¦½ç´€éŒ„
+ <ph name="LIST_ITEM" />Cookie 和網站資料
+ <ph name="LIST_ITEM" />你在表單中輸入的資訊
+ <ph name="END_LIST" /></translation>
<translation id="3369192424181595722">時é˜éŒ¯èª¤</translation>
-<translation id="337311366426640088">還有 <ph name="ITEM_COUNT" /> 個項目...</translation>
<translation id="337363190475750230">å·²å–消佈建</translation>
<translation id="3377188786107721145">政策解æžéŒ¯èª¤</translation>
<translation id="3380365263193509176">未知的錯誤</translation>
<translation id="3380864720620200369">用戶端 ID:</translation>
<translation id="3391030046425686457">å¿«éžåœ°å€</translation>
<translation id="3395827396354264108">å–件方å¼</translation>
-<translation id="340013220407300675">攻擊者å¯èƒ½æœƒå˜—試從 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> ç«Šå–你的資訊 (例如密碼ã€éƒµä»¶æˆ–信用å¡è³‡è¨Š)。</translation>
<translation id="3422248202833853650">嘗試關閉其他程å¼ä»¥é‡‹å‡ºè¨˜æ†¶é«”。</translation>
<translation id="3422472998109090673">ç›®å‰ç„¡æ³•é€£ä¸Š <ph name="HOST_NAME" />。</translation>
+<translation id="3427092606871434483">å…許 (é è¨­)</translation>
<translation id="3427342743765426898">é‡åšç·¨è¼¯(&amp;R)</translation>
<translation id="3431636764301398940">將這張信用å¡å„²å­˜åˆ°é€™å€‹è£ç½®</translation>
<translation id="3435896845095436175">啟用</translation>
<translation id="3447661539832366887">這個è£ç½®çš„æ“有者已關閉æé¾éŠæˆ²ã€‚</translation>
-<translation id="3450660100078934250">Mastercard</translation>
<translation id="3452404311384756672">æ“·å–間隔:</translation>
<translation id="3462200631372590220">éš±è—詳細資料</translation>
<translation id="3467763166455606212">æŒå¡äººå§“å為必填項目</translation>
<translation id="3478058380795961209">到期月份</translation>
<translation id="3479539252931486093">這是未é æœŸçš„情æ³å—Žï¼Ÿ<ph name="BEGIN_LINK" />通知我們<ph name="END_LINK" /></translation>
<translation id="3479552764303398839">ç¾åœ¨ä¸è¦</translation>
-<translation id="348000606199325318">當機 ID:<ph name="CRASH_LOCAL_ID" /> (伺æœå™¨ ID:<ph name="CRASH_ID" />)</translation>
<translation id="3498215018399854026">我們暫時無法與您的家長è¯çµ¡ï¼Œè«‹å†è©¦ä¸€æ¬¡ã€‚</translation>
<translation id="3528171143076753409">伺æœå™¨æ†‘證授權ä¸å¯é ã€‚</translation>
+<translation id="3530944546672790857">{COUNT,plural, =0{在已åŒæ­¥çš„è£ç½®ä¸Šè‡³å°‘有 1 個項目}=1{1 個項目 (在已åŒæ­¥çš„è£ç½®ä¸Šé‚„有更多項目)}other{# 個項目 (在已åŒæ­¥çš„è£ç½®ä¸Šé‚„有更多項目)}}</translation>
<translation id="3539171420378717834">在這個è£ç½®ä¸Šä¿ç•™é€™å¼µä¿¡ç”¨å¡çš„複本</translation>
<translation id="3542684924769048008">é¸æ“‡å¯†ç¢¼ï¼š</translation>
+<translation id="3545341443414427877">電腦的日期和時間 (<ph name="DATE_AND_TIME" />) ä¸æ­£ç¢ºï¼Œå› æ­¤ç„¡æ³•èˆ‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§äººé€£ç·šã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3549644494707163724">使用你的通關密語å°æ‰€æœ‰å·²åŒæ­¥è™•ç†çš„資料進行加密</translation>
-<translation id="3549761410225185768">還有 <ph name="NUM_TABS_MORE" /> 個分é ...</translation>
-<translation id="3555561725129903880">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證來自 <ph name="DOMAIN2" />。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="3556433843310711081">你的管ç†å“¡å¯ä»¥ç‚ºä½ è§£é™¤å°éŽ–這個網站</translation>
<translation id="3566021033012934673">你的連線ä¸æ˜¯ç§äººé€£ç·š</translation>
+<translation id="3569145463236695319">&lt;p&gt;è£ç½®çš„日期和時間 (<ph name="DATE_AND_TIME" />) ä¸æ­£ç¢ºï¼Œå› æ­¤ç„¡æ³•èˆ‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§äººé€£ç·šã€‚&lt;/p&gt;
+
+ &lt;p&gt;è«‹å‰å¾€ã€Œè¨­å®šã€æ‡‰ç”¨ç¨‹å¼çš„「一般設定ã€å°ˆå€èª¿æ•´æ—¥æœŸå’Œæ™‚間。&lt;strong&gt;&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="3574305903863751447"><ph name="COUNTRY" />,<ph name="STATE" />,<ph name="CITY" /></translation>
<translation id="3582930987043644930">新增å稱</translation>
<translation id="3583757800736429874">é‡åšç§»å‹•(&amp;R)</translation>
<translation id="3586931643579894722">éš±è—詳細資訊</translation>
-<translation id="3587482841069643663">全部</translation>
<translation id="3600246354004376029"><ph name="TITLE" />,<ph name="DOMAIN" />,<ph name="TIME" /></translation>
<translation id="3615877443314183785">請輸入有效的到期日</translation>
<translation id="36224234498066874">清除ç€è¦½è³‡æ–™...</translation>
@@ -322,7 +362,6 @@
<translation id="3681007416295224113">憑證資訊</translation>
<translation id="3690164694835360974">登入行為ä¸å®‰å…¨</translation>
<translation id="3693415264595406141">密碼:</translation>
-<translation id="3696411085566228381">ç„¡</translation>
<translation id="3704609568417268905"><ph name="TIME" />,<ph name="BOOKMARKED" />,<ph name="TITLE" />,<ph name="DOMAIN" /></translation>
<translation id="370665806235115550">載入中…</translation>
<translation id="3712624925041724820">授權已用盡</translation>
@@ -330,12 +369,15 @@
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />檢查 Proxyã€é˜²ç«ç‰†å’Œ DNS 設定<ph name="END_LINK" /></translation>
<translation id="3736520371357197498">如果你瞭解安全性風險,也å¯ä»¥é¸æ“‡åœ¨å±éšªç¨‹å¼å°šæœªé­åˆ°ç§»é™¤çš„狀態下<ph name="BEGIN_LINK" />造訪這個ä¸å®‰å…¨çš„網站<ph name="END_LINK" />。</translation>
<translation id="3739623965217189342">您複製的連çµ</translation>
+<translation id="3744899669254331632"><ph name="SITE" /> 傳é€çš„憑證å—åˆ°å¹²æ“¾ï¼Œé€ æˆ Chromium 無法處ç†ï¼Œå› æ­¤ä½ ç›®å‰ç„¡æ³•é€ è¨ªè©²ç¶²ç«™ã€‚網路錯誤和攻擊通常是暫時性狀態,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸é‹ä½œã€‚</translation>
+<translation id="3748148204939282805">攻擊者å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 誘使你åšä¸€äº›å±éšªè¡Œç‚ºï¼Œä¾‹å¦‚安è£è»Ÿé«”或æ供個人資訊 (包括密碼ã€é›»è©±è™Ÿç¢¼æˆ–信用å¡è³‡æ–™)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="375403751935624634">伺æœå™¨éŒ¯èª¤ï¼Œç¿»è­¯ä½œæ¥­å¤±æ•—。</translation>
<translation id="3759461132968374835">最近沒有收到當機資訊。當機回報功能åœç”¨æ™‚發生的當機ä¸æœƒåˆ—在這裡。</translation>
+<translation id="3778403066972421603">ä½ è¦å°‡é€™å¼µä¿¡ç”¨å¡çš„資訊儲存到你在這個è£ç½®ä¸Šçš„ Google 帳戶嗎?</translation>
+<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">到期日:<ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="382518646247711829">如果你使用 Proxy 伺æœå™¨...</translation>
<translation id="3828924085048779000">通關密語欄ä½ä¸å¾—留空。</translation>
-<translation id="3845539888601087042">ç›®å‰é¡¯ç¤ºçš„æ­·å²ç´€éŒ„來æºåŒ…括您已登入帳戶的所有è£ç½®ã€‚<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation>
<translation id="385051799172605136">返回</translation>
<translation id="3858027520442213535">更新日期和時間</translation>
<translation id="3884278016824448484">è£ç½®è­˜åˆ¥ç¢¼ç™¼ç”Ÿè¡çª</translation>
@@ -343,11 +385,13 @@
<translation id="3886446263141354045">你想存å–這個網站的è¦æ±‚已傳é€çµ¦<ph name="NAME" /></translation>
<translation id="3890664840433101773">新增電å­éƒµä»¶åœ°å€</translation>
<translation id="3901925938762663762">這張信用å¡å·²éŽæœŸ</translation>
-<translation id="3933571093587347751">{1,plural, =1{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證é å®šæ˜Žå¤©æ‰ç”Ÿæ•ˆã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" />}other{這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證é å®š # 天後æ‰ç”Ÿæ•ˆã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" />}}</translation>
-<translation id="3934680773876859118">無法載入 PDF 文件</translation>
+<translation id="3945915738023014686">已上傳的當機報告 ID:<ph name="CRASH_ID" /> (本機當機 ID:<ph name="CRASH_LOCAL_ID" />)</translation>
+<translation id="3949571496842715403">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€å±¬ç¶²åŸŸç‚º <ph name="DOMAIN" />;其安全性憑證未指定主體別å。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線所致。</translation>
<translation id="3963721102035795474">閱讀器模å¼</translation>
+<translation id="3964661563329879394">{COUNT,plural, =0{無}=1{來自 1 個網站 }other{來自 # 個網站 }}</translation>
<translation id="397105322502079400">計算中…</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> é­åˆ°å°éŽ–</translation>
+<translation id="3987940399970879459">ä¸åˆ° 1 MB</translation>
<translation id="40103911065039147">{URL_count,plural, =1{附近有 1 個網é }other{附近有 # 個網é }}</translation>
<translation id="4021036232240155012">DNS 這項網路æœå‹™æœƒå°‡ç¶²ç«™çš„å稱轉譯æˆç¶²éš›ç¶²è·¯ä½å€ã€‚</translation>
<translation id="4030383055268325496">復原新增(&amp;U)</translation>
@@ -358,56 +402,63 @@
<translation id="4079302484614802869">Proxy 設定已設為使用 .pac 指令碼網å€ï¼Œè€Œéžå›ºå®šçš„ Proxy 伺æœå™¨ã€‚</translation>
<translation id="4098354747657067197">您å³å°‡å‰å¾€è©é¨™ç¶²ç«™</translation>
<translation id="4103249731201008433">è£ç½®åºè™Ÿç„¡æ•ˆ</translation>
+<translation id="410351446219883937">自動播放</translation>
<translation id="4103763322291513355">è«‹å‰å¾€ &lt;strong&gt;chrome://policy&lt;/strong&gt; 查看列入黑å單的網å€æ¸…單,以åŠå…¶ä»–系統管ç†å“¡å¼·åˆ¶åŸ·è¡Œçš„政策。</translation>
-<translation id="4110615724604346410">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證å«æœ‰éŒ¯èª¤ã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4115378294792113321">洋紅色</translation>
+<translation id="4116663294526079822">æ°¸é å…許在這個網站執行</translation>
<translation id="4117700440116928470">系統ä¸æ”¯æ´é€™é …政策的範åœã€‚</translation>
-<translation id="4118212371799607889">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />ï¼›Chromium ä¸ä¿¡ä»»ä¼ºæœå™¨çš„安全性憑證。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4129401438321186435">{COUNT,plural, =1{以åŠå¦å¤– 1 項表單資料}other{以åŠå¦å¤– # 項表單資料}}</translation>
<translation id="4130226655945681476">檢查網路線ã€æ•¸æ“šæ©Ÿå’Œè·¯ç”±å™¨</translation>
+<translation id="413544239732274901">瞭解詳情</translation>
<translation id="4148925816941278100">American Express</translation>
+<translation id="4151403195736952345">使用全域é è¨­è¨­å®š (åµæ¸¬)</translation>
+<translation id="4165986682804962316">網站設定</translation>
<translation id="4169947484918424451">您希望 Chromium 儲存這張信用å¡å—Žï¼Ÿ</translation>
<translation id="4171400957073367226">驗證簽å無效</translation>
<translation id="4196861286325780578">é‡åšç§»å‹•(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />檢查防ç«ç‰†å’Œé˜²æ¯’軟體設定<ph name="END_LINK" /></translation>
-<translation id="4206349416402437184">{COUNT,plural, =0{ç„¡}=1{1 å€‹æ‡‰ç”¨ç¨‹å¼ ($1)}=2{2 å€‹æ‡‰ç”¨ç¨‹å¼ ($1ã€$2)}other{# å€‹æ‡‰ç”¨ç¨‹å¼ ($1ã€$2ã€$3)}}</translation>
<translation id="4220128509585149162">當機</translation>
+<translation id="422022731706691852">攻擊者å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 誘使你安è£å°ç€è¦½é«”驗有害 (例如變更你的首é ï¼Œæˆ–是在你造訪的網站上顯示多餘的廣告) 的程å¼ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />嘗試執行網路診斷<ph name="END_LINK" />。</translation>
+<translation id="4235360514405112390">有效</translation>
<translation id="4250431568374086873">你與這個網站的連線å¯èƒ½æœ‰å®‰å…¨æ¼æ´ž</translation>
<translation id="4250680216510889253">å¦</translation>
<translation id="425582637250725228">系統å¯èƒ½ä¸æœƒå„²å­˜æ‚¨æ‰€åšçš„變更。</translation>
<translation id="4258748452823770588">ç°½å有誤</translation>
+<translation id="4265872034478892965">ä¾æ“šç®¡ç†å“¡çš„設定å…許</translation>
<translation id="4269787794583293679">(沒有使用者å稱)</translation>
<translation id="4275830172053184480">é‡æ–°å•Ÿå‹•è£ç½®</translation>
<translation id="4280429058323657511">,到期日:<ph name="EXPIRATION_DATE_ABBR" /></translation>
-<translation id="4295944351946828969">Google 安全ç€è¦½åŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />找到有害的應用程å¼<ph name="END_LINK" />。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4300246636397505754">家長建議</translation>
<translation id="4304224509867189079">登入</translation>
-<translation id="432290197980158659">這個伺æœå™¨çš„憑證ä¸ç¬¦åˆå…§å»ºçš„é æœŸæ¢ä»¶ã€‚我們é‡å°ç‰¹å®šçš„高安全性網站內建了這些é æœŸæ¢ä»¶ï¼Œä»¥ç¢ºä¿ä½ çš„資料安全無虞。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4312866146174492540">å°éŽ– (é è¨­)</translation>
<translation id="4325863107915753736">找ä¸åˆ°æ–‡ç« </translation>
<translation id="4326324639298822553">請檢查信用å¡åˆ°æœŸæ—¥ï¼Œç„¶å¾Œå†è©¦ä¸€æ¬¡</translation>
<translation id="4331708818696583467">ä¸å®‰å…¨</translation>
<translation id="4356973930735388585">攻擊者å¯èƒ½æœƒè©¦åœ–é€éŽé€™å€‹ç¶²ç«™åœ¨ä½ çš„電腦上安è£å±éšªç¨‹å¼ï¼Œè—‰æ­¤ç«Šå–或刪除你的資訊 (例如相片ã€å¯†ç¢¼ã€éƒµä»¶å’Œä¿¡ç”¨å¡è³‡æ–™)。</translation>
<translation id="4372948949327679948">é æœŸçš„「<ph name="VALUE_TYPE" />ã€å€¼ã€‚</translation>
+<translation id="4377125064752653719">你嘗試å‰å¾€ <ph name="DOMAIN" />,但是發行者已撤銷伺æœå™¨æ供的憑證。在這種情æ³ä¸‹ï¼Œè«‹å‹¿ä¿¡ä»»ä¼ºæœå™¨æ供的安全性憑證,因為你的連線å°è±¡å¯èƒ½æ˜¯æ”»æ“Šè€…的電腦。</translation>
<translation id="4381091992796011497">使用者å稱:</translation>
<translation id="4394049700291259645">åœç”¨</translation>
<translation id="4406896451731180161">æœå°‹çµæžœ</translation>
+<translation id="4424024547088906515">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證未å–å¾— Chrome 的信任。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ä¸æŽ¥å—你的登入憑證,或是你å¯èƒ½æœªæ供登入憑證。</translation>
<translation id="443673843213245140">雖然已åœç”¨ Proxy,ä¸éŽå·²æŒ‡å®šæ˜Žç¢º Proxy 設定。</translation>
-<translation id="4492190037599258964">「<ph name="SEARCH_STRING" />ã€çš„æœå°‹çµæžœ</translation>
<translation id="4506176782989081258">驗證錯誤:<ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">與系統管ç†å“¡è¯çµ¡</translation>
<translation id="450710068430902550">與管ç†å“¡åˆ†äº«</translation>
<translation id="4515275063822566619">信用å¡å’Œåœ°å€è³‡è¨Šçš†ä¾†è‡ª Chrome 和你的 Google 帳戶 (<ph name="ACCOUNT_EMAIL" />)。你å¯ä»¥åœ¨<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />é é¢ç®¡ç†é€™äº›è³‡è¨Šã€‚</translation>
<translation id="4522570452068850558">詳細資訊</translation>
+<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">試試看åœç”¨æ“´å……功能。</translation>
<translation id="457875822857220463">å¿«éž</translation>
<translation id="4587425331216688090">è¦å¾ž Chrome 中移除地å€å—Žï¼Ÿ</translation>
-<translation id="4589078953350245614">你嘗試連上 <ph name="DOMAIN" />,但伺æœå™¨æ供的憑證無效。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="4592951414987517459">您的 <ph name="DOMAIN" /> 連線使用新型加密套件進行加密。</translation>
<translation id="4594403342090139922">復原刪除(&amp;U)</translation>
<translation id="4619615317237390068">在其他è£ç½®ä¸Šé–‹å•Ÿçš„分é </translation>
<translation id="4668929960204016307">,</translation>
+<translation id="467662567472608290">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證å«æœ‰éŒ¯èª¤ã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
+<translation id="4690462567478992370">åœæ­¢ä½¿ç”¨ç„¡æ•ˆçš„憑證</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">您的連線已中斷</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />執行 Windows 網路診斷<ph name="END_LINK" /></translation>
@@ -424,21 +475,24 @@
<translation id="4771973620359291008">發生ä¸æ˜Žçš„錯誤。</translation>
<translation id="4800132727771399293">請檢查您的有效期é™å’Œä¿¡ç”¨å¡å®‰å…¨ç¢¼ï¼Œç„¶å¾Œå†è©¦ä¸€æ¬¡</translation>
<translation id="4803924862070940586"><ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
+<translation id="4807049035289105102">您目å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站傳é€çš„憑證是亂碼,Google Chrome 無法處ç†ã€‚網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ­£å¸¸é‹ä½œã€‚</translation>
<translation id="4813512666221746211">網路錯誤</translation>
<translation id="4816492930507672669">ä¾é é¢å¤§å°è‡ªå‹•èª¿æ•´</translation>
<translation id="483020001682031208">沒有å¯é¡¯ç¤ºçš„實體化網路é é¢</translation>
<translation id="4850886885716139402">檢視</translation>
<translation id="4854362297993841467">ä¸æ”¯æ´æ‰€é¸çš„å¿«éžæ–¹å¼ï¼Œè«‹æ”¹é¸å…¶ä»–æ–¹å¼ã€‚</translation>
<translation id="4858792381671956233">你已詢å•å®¶é•·æ˜¯å¦åŒæ„你造訪這個網站</translation>
+<translation id="4863764087567530506">這項內容å¯èƒ½æœƒè©¦åœ–誘使你安è£è»Ÿé«”或æ供個人資訊。<ph name="BEGIN_LINK" />ä»è¦é¡¯ç¤º<ph name="END_LINK" />。</translation>
<translation id="4880827082731008257">æœå°‹ç´€éŒ„</translation>
<translation id="4895877746940133817"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />,<ph name="TYPE_3" /></translation>
<translation id="4914479371620770914">{URL_count,plural, =1{還有å¦å¤– 1 個網é }other{還有å¦å¤– # 個網é }}</translation>
+<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">系統已將此網é å¾žä¸æ˜Žèªžè¨€ç¿»è­¯æˆ<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="4923459931733593730">付款</translation>
<translation id="4926049483395192435">必須指定。</translation>
<translation id="495170559598752135">動作</translation>
<translation id="4958444002117714549">展開清單</translation>
-<translation id="4962322354953122629">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />ï¼›Chrome ä¸ä¿¡ä»»ä¼ºæœå™¨çš„安全性憑證。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="4974590756084640048">é‡æ–°å•Ÿç”¨è­¦å‘ŠåŠŸèƒ½</translation>
<translation id="4989809363548539747">這是ä¸æ”¯æ´çš„外掛程å¼</translation>
<translation id="5002932099480077015">啟用後,Chrome 會將您的信用å¡è¤‡æœ¬å„²å­˜åœ¨é€™å€‹è£ç½®ä¸Šï¼Œä»¥åŠ å¿«è¡¨å–®å¡«å¯«é€Ÿåº¦ã€‚</translation>
<translation id="5018422839182700155">無法開啟這個網é </translation>
@@ -446,14 +500,15 @@
<translation id="5023310440958281426">請查看你的管ç†å“¡æ”¿ç­–</translation>
<translation id="5029568752722684782">清除複本</translation>
<translation id="5031870354684148875">關於「Google 翻譯ã€</translation>
+<translation id="5039804452771397117">å…許</translation>
<translation id="5040262127954254034">éš±ç§æ¬Š</translation>
<translation id="5045550434625856497">密碼ä¸æ­£ç¢º</translation>
<translation id="5056549851600133418">為您推薦的文章</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />檢查 Proxy ä½å€<ph name="END_LINK" /></translation>
-<translation id="5076731569460970710">{COUNT,plural, =0{沒有任何 Cookie}=1{1 個網站會使用 Cookie。}other{# 個網站會使用 Cookie。}}</translation>
<translation id="5087286274860437796">伺æœå™¨æ†‘證目å‰ç„¡æ•ˆã€‚</translation>
<translation id="5087580092889165836">新增信用å¡</translation>
<translation id="5089810972385038852">å·ž</translation>
+<translation id="5094747076828555589">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證未å–å¾— Chromium 的信任。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
<translation id="5095208057601539847">çœ</translation>
<translation id="5115563688576182185">(64 ä½å…ƒ)</translation>
<translation id="5141240743006678641">使用你的 Google 憑證å°å·²åŒæ­¥è™•ç†çš„密碼進行加密</translation>
@@ -469,24 +524,24 @@
<translation id="5222812217790122047">請輸入電å­éƒµä»¶åœ°å€</translation>
<translation id="5251803541071282808">雲端</translation>
<translation id="5277279256032773186">在工作環境使用 Chrome 嗎?ä¼æ¥­å¯ä»¥ç®¡ç†å“¡å·¥çš„ Chrome 設定。瞭解詳情</translation>
+<translation id="5297526204711817721">你與這個網站之間的連線ä¸æ˜¯ç§äººé€£ç·šã€‚你隨時å¯ä»¥æ‘˜ä¸‹é ­æˆ´å¼è£ç½®ï¼Œç„¶å¾ŒæŒ‰ä¸‹è¿”回éµé€€å‡º VR 模å¼ã€‚</translation>
<translation id="5299298092464848405">解æžæ”¿ç­–時發生錯誤</translation>
-<translation id="5300589172476337783">顯示</translation>
<translation id="5308689395849655368">當機報告功能已åœç”¨ã€‚</translation>
<translation id="5317780077021120954">儲存</translation>
<translation id="5327248766486351172">å稱</translation>
-<translation id="5337705430875057403">攻擊者å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 誘使您åšä¸€äº›å±éšªçš„事,例如安è£è»Ÿé«”或æ供個人資訊 (包括密碼ã€é›»è©±è™Ÿç¢¼æˆ–信用å¡è³‡æ–™)。</translation>
-<translation id="5359637492792381994">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證目å‰ç„¡æ•ˆã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5355557959165512791">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站的憑證已é­æ’¤éŠ·ã€‚網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚</translation>
<translation id="536296301121032821">無法儲存政策設定</translation>
<translation id="5386426401304769735">這個網站的憑證éˆçµåŒ…å«ä½¿ç”¨ SHA-1 進行簽署的憑證。</translation>
<translation id="5402410679244714488">到期日:<ph name="EXPIRATION_DATE_ABBR" />,è·é›¢ä¸Šæ¬¡ä½¿ç”¨å·²è¶…éŽ 1 å¹´</translation>
+<translation id="540969355065856584">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€å±¬ç¶²åŸŸç‚º <ph name="DOMAIN" />;其安全性憑證目å‰ç„¡æ•ˆã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截您的連線所致。</translation>
<translation id="5421136146218899937">清除ç€è¦½è³‡æ–™...</translation>
<translation id="5430298929874300616">移除書籤</translation>
<translation id="5431657950005405462">找ä¸åˆ°æ‚¨çš„檔案</translation>
-<translation id="5435775191620395718">ç›®å‰é¡¯ç¤ºé€™å€‹è£ç½®çš„æ­·å²ç´€éŒ„。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation>
<translation id="5439770059721715174">「<ph name="ERROR_PATH" />ã€ç™¼ç”Ÿæž¶æ§‹é©—證錯誤:<ph name="ERROR" /></translation>
<translation id="5452270690849572955">找ä¸åˆ° <ph name="HOST_NAME" /> 網é </translation>
<translation id="5455374756549232013">政策時間戳記有誤</translation>
<translation id="5455790498993699893">第 <ph name="ACTIVE_MATCH" /> 個,共 <ph name="TOTAL_MATCHCOUNT" /> 個</translation>
+<translation id="5457113250005438886">無效</translation>
<translation id="5470861586879999274">é‡åšç·¨è¼¯(&amp;R)</translation>
<translation id="54817484435770891">新增有效的地å€</translation>
<translation id="5492298309214877701">這個ä½æ–¼å…¬å¸ã€æ©Ÿæ§‹æˆ–學校內部網路的網站使用的網å€èˆ‡æŸå€‹å¤–部網站相åŒã€‚
@@ -503,6 +558,8 @@
<translation id="5571083550517324815">無法在這個地å€å–件,請改用其他地å€ã€‚</translation>
<translation id="5572851009514199876">è«‹å•Ÿå‹• Chrome 並登入帳戶,Chrome 將確èªä½ æ˜¯å¦å¯å­˜å–這個網站。</translation>
<translation id="5580958916614886209">請檢查信用å¡åˆ°æœŸæœˆä»½ï¼Œç„¶å¾Œå†è©¦ä¸€æ¬¡</translation>
+<translation id="5586446728396275693">沒有已儲存的地å€</translation>
+<translation id="5595485650161345191">編輯地å€</translation>
<translation id="560412284261940334">系統ä¸æ”¯æ´ç®¡ç†</translation>
<translation id="5610142619324316209">檢查連線狀態</translation>
<translation id="5610807607761827392">ä½ å¯ä»¥åœ¨<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />中管ç†ä¿¡ç”¨å¡å’Œåœ°å€è³‡è¨Šã€‚</translation>
@@ -510,15 +567,18 @@
<translation id="5622887735448669177">您è¦é›¢é–‹é€™å€‹ç¶²ç«™å—Žï¼Ÿ</translation>
<translation id="5629630648637658800">無法載入政策設定</translation>
<translation id="5631439013527180824">è£ç½®ç®¡ç†ç¬¦è¨˜ç„¡æ•ˆ</translation>
+<translation id="5633066919399395251">攻擊者目å‰å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在你的電腦上安è£å±éšªç¨‹å¼ï¼Œè—‰æ­¤ç«Šå–或刪除你的資訊 (例如相片ã€å¯†ç¢¼ã€éƒµä»¶å’Œä¿¡ç”¨å¡è³‡æ–™)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="5646376287012673985">ä½ç½®</translation>
+<translation id="5659593005791499971">é›»å­éƒµä»¶</translation>
<translation id="5669703222995421982">å–得個人化內容</translation>
<translation id="5675650730144413517">這個網é ç„¡æ³•æ­£å¸¸é‹ä½œ</translation>
-<translation id="5677928146339483299">å·²å°éŽ–</translation>
-<translation id="5694783966845939798">你嘗試連上 <ph name="DOMAIN" />,但伺æœå™¨çš„憑證是以防護力薄弱的簽章演算法 (例如 SHA-1) 進行簽署。這代表伺æœå™¨æ供的安全性憑證å¯èƒ½é­åˆ°å½é€ ï¼Œè€Œä¸”這個伺æœå™¨å¯èƒ½ä¸¦ä¸æ˜¯ä½ çš„目標伺æœå™¨ (你的連線å°è±¡å¯èƒ½æ˜¯æ”»æ“Šè€…的電腦)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" />。</translation>
<translation id="5710435578057952990">此網é çš„身分未經驗證。</translation>
+<translation id="5713016350996637505">å·²å°éŽ–欺騙性內容</translation>
<translation id="5720705177508910913">ç›®å‰ä½¿ç”¨è€…</translation>
<translation id="5732392974455271431">你的家長å¯ä»¥ç‚ºä½ è§£é™¤å°éŽ–這個網站</translation>
<translation id="5763042198335101085">請輸入有效的電å­éƒµä»¶åœ°å€</translation>
<translation id="5765072501007116331">如è¦æŸ¥çœ‹å¿«éžæ–¹å¼å’Œç›¸é—œè¦å®šï¼Œè«‹é¸å–一個地å€</translation>
+<translation id="5778550464785688721">MIDI è£ç½®å®Œæ•´æŽ§åˆ¶</translation>
<translation id="5784606427469807560">驗證您的信用å¡æ™‚發生å•é¡Œã€‚請檢查網際網路連線,然後å†è©¦ä¸€æ¬¡ã€‚</translation>
<translation id="5785756445106461925">此外,這個網é å«æœ‰å…¶ä»–ä¸å®‰å…¨çš„資æºã€‚其他人å¯èƒ½æœƒåœ¨è³‡æºå‚³è¼¸æœŸé–“檢視這些資æºï¼Œæ”»æ“Šè€…也å¯èƒ½æœƒä¿®æ”¹é€™äº›è³‡æºï¼Œé€²è€Œè®Šæ›´ç¶²é å¤–觀。</translation>
<translation id="5786044859038896871">è¦å¡«å…¥ä½ çš„信用å¡è³‡è¨Šå—Žï¼Ÿ</translation>
@@ -527,14 +587,14 @@
<translation id="5813119285467412249">é‡åšæ–°å¢ž(&amp;R)</translation>
<translation id="5814352347845180253">您å¯èƒ½ç„¡æ³•å†å­˜å– <ph name="SITE" /> å’Œå¦ä¸€äº›ç¶²ç«™çš„付費內容。</translation>
<translation id="5838278095973806738">請勿在這個網站上輸入任何機密資訊 (例如密碼或信用å¡è™Ÿç¢¼),以å…é­åˆ°æ”»æ“Šè€…ç«Šå–。</translation>
-<translation id="5843436854350372569">你嘗試連上 <ph name="DOMAIN" />,但伺æœå™¨çš„憑證å«æœ‰é˜²è­·åŠ›è–„弱的金鑰。攻擊者å¯èƒ½å·²ç ´è§£ç§å¯†é‡‘鑰,而且這個伺æœå™¨å¯èƒ½ä¸¦ä¸æ˜¯ä½ çš„目標伺æœå™¨ (你的連線å°è±¡å¯èƒ½æ˜¯æ”»æ“Šè€…的電腦)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="5869405914158311789">無法連上這個網站</translation>
<translation id="5869522115854928033">已儲存的密碼</translation>
<translation id="5872918882028971132">家長建議</translation>
<translation id="5901630391730855834">黃色</translation>
+<translation id="5908541034548427511"><ph name="TYPE_1" /> (å·²åŒæ­¥)</translation>
+<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ç›®å‰ä½¿ç”¨ 1 個 Cookie}other{ç›®å‰ä½¿ç”¨ # 個 Cookie}}</translation>
<translation id="5926846154125914413">您å¯èƒ½ç„¡æ³•å†å­˜å–部分網站的付費內容。</translation>
<translation id="5959728338436674663">自動傳é€éƒ¨åˆ†<ph name="BEGIN_WHITEPAPER_LINK" />系統資訊和網é å…§å®¹<ph name="END_WHITEPAPER_LINK" />給 Google,å”助åµæ¸¬å±éšªçš„應用程å¼å’Œç¶²ç«™ã€‚<ph name="PRIVACY_PAGE_LINK" /></translation>
-<translation id="5966707198760109579">週</translation>
<translation id="5967867314010545767">從紀錄中移除</translation>
<translation id="5975083100439434680">縮å°</translation>
<translation id="598637245381783098">無法開啟付款應用程å¼</translation>
@@ -543,21 +603,29 @@
<translation id="6008256403891681546">JCB</translation>
<translation id="6016158022840135739">{COUNT,plural, =1{第 1 é }other{第 # é }}</translation>
<translation id="6017514345406065928">綠色</translation>
+<translation id="6017850046339264347">ç›®å‰åœ¨ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 上的攻擊者å¯èƒ½æœƒè®“你安è£èº«åˆ†ä¸å¯¦çš„欺騙性應用程å¼ï¼Œæˆ–是收集å¯ç”¨æ–¼è¿½è¹¤ä½ çš„資料。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="6025416945513303461"><ph name="TYPE_1" />ã€<ph name="TYPE_2" />ã€<ph name="TYPE_3" /> (å·²åŒæ­¥)</translation>
<translation id="6027201098523975773">輸入å稱</translation>
<translation id="6040143037577758943">關閉</translation>
<translation id="6042308850641462728">更多</translation>
+<translation id="6047233362582046994">如果你瞭解安全性風險,也å¯ä»¥é¸æ“‡åœ¨æœ‰å®³æ‡‰ç”¨ç¨‹å¼å°šæœªé­åˆ°ç§»é™¤çš„狀態下<ph name="BEGIN_LINK" />造訪這個網站<ph name="END_LINK" />。</translation>
+<translation id="6051221802930200923">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站使用憑證鎖定功能。網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚</translation>
<translation id="6060685159320643512">請注æ„,這些實驗性功能å¯èƒ½å°é›»è…¦æœ‰å®³</translation>
-<translation id="6108835911243775197">{COUNT,plural, =0{ç„¡}=1{1}other{#}}</translation>
+<translation id="6080696365213338172">你使用了管ç†å“¡æ供的憑證存å–內容,因此管ç†å“¡å¯æ””截你傳é€è‡³ã€Œ<ph name="DOMAIN" />ã€çš„資料。</translation>
+<translation id="6144381551823904650">{COUNT,plural, =0{ç„¡}=1{1 組密碼 (ä¿æŒåŒæ­¥)}other{# 組密碼 (ä¿æŒåŒæ­¥)}}</translation>
<translation id="6146055958333702838">檢查您的網路線是å¦ç©©å›ºé€£æŽ¥ã€‚é‡æ–°å•Ÿå‹•æ‚¨å¯èƒ½æ­£åœ¨ä½¿ç”¨çš„任何路由器ã€
數據機或其他網路è£ç½®ã€‚</translation>
<translation id="614940544461990577">建議åšæ³•ï¼š</translation>
<translation id="6151417162996330722">伺æœå™¨æ†‘證的有效期é™å¤ªé•·ã€‚</translation>
<translation id="6157877588268064908">如è¦æŸ¥çœ‹é‹é€æ–¹å¼å’Œç›¸é—œè¦å®šï¼Œè«‹é¸å–一個地å€</translation>
+<translation id="6158003235852588289">Google 安全ç€è¦½åŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上åµæ¸¬åˆ°ç¶²è·¯è©é¨™è¡Œç‚ºã€‚è©é¨™ç¶²ç«™æœƒå½è£æˆå…¶ä»–網站,藉此騙å–你的資訊。</translation>
<translation id="6165508094623778733">瞭解詳情</translation>
+<translation id="6169916984152623906">ç¾åœ¨ï¼Œä½ å¯ä»¥é€²è¡Œç§å¯†ç€è¦½äº†ã€‚共用這部è£ç½®çš„其他使用者ä¸æœƒçœ‹åˆ°ä½ çš„活動,ä¸éŽï¼Œä½ ä¸‹è¼‰çš„內容和新增的書籤ä»æœƒä¿ç•™åœ¨è£ç½®ä¸Šã€‚</translation>
<translation id="6177128806592000436">你與這個網站的連線ä¸å®‰å…¨</translation>
<translation id="6184817833369986695">(發佈版本:<ph name="UPDATE_COHORT_NAME" />)</translation>
<translation id="6203231073485539293">檢查網際網路連線</translation>
<translation id="6218753634732582820">è¦å¾ž Chromium 中移除地å€å—Žï¼Ÿ</translation>
+<translation id="6221345481584921695">Google 安全ç€è¦½åŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />åµæ¸¬åˆ°æƒ¡æ„軟體<ph name="END_LINK" />。å³ä½¿æ˜¯å¹³å¸¸å¯ä»¥å®‰å…¨ä½¿ç”¨çš„網站,有時也會é­åˆ°æƒ¡æ„軟體感染。這些惡æ„內容來自已知的惡æ„軟體散佈網站 <ph name="SUBRESOURCE_HOST" />。</translation>
<translation id="6251924700383757765">éš±ç§æ¬Šæ”¿ç­–</translation>
<translation id="6254436959401408446">記憶體ä¸è¶³ï¼Œç„¡æ³•é–‹å•Ÿé€™å€‹ç¶²é </translation>
<translation id="625755898061068298">ä½ å·²é¸æ“‡é‡å°é€™å€‹ç¶²ç«™åœç”¨å®‰å…¨æ€§è­¦å‘ŠåŠŸèƒ½ã€‚</translation>
@@ -583,15 +651,14 @@
<translation id="6404511346730675251">編輯書籤</translation>
<translation id="6410264514553301377">輸入 <ph name="CREDIT_CARD" /> 的到期日和信用å¡å®‰å…¨ç¢¼</translation>
<translation id="6414888972213066896">你已詢å•å®¶é•·æ˜¯å¦åŒæ„你造訪這個網站</translation>
-<translation id="6416403317709441254">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站傳é€çš„憑證å«æœ‰äº‚碼,Chromium 無法處ç†ã€‚網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6417515091412812850">無法檢查憑證是å¦å·²é­æ’¤éŠ·ã€‚</translation>
<translation id="6433490469411711332">編輯è¯çµ¡è³‡è¨Š</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> 拒絕連線。</translation>
<translation id="6446608382365791566">新增詳細資訊</translation>
+<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">確èªé‡æ–°æ交表單</translation>
<translation id="6456339708790392414">你的付款</translation>
<translation id="6458467102616083041">由於政策åœç”¨äº†é è¨­æœå°‹ï¼Œå› æ­¤é­åˆ°ç•¥éŽã€‚</translation>
-<translation id="6462969404041126431">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;伺æœå™¨çš„安全性憑證å¯èƒ½é­åˆ°æ’¤éŠ·ã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="647261751007945333">è£ç½®æ”¿ç­–</translation>
<translation id="6477321094435799029">Chrome 在這個網é ä¸Šåµæ¸¬åˆ°ç•°å¸¸ä»£ç¢¼ã€‚為了ä¿è­·ä½ çš„個人資訊 (包括密碼ã€é›»è©±è™Ÿç¢¼æˆ–信用å¡è³‡æ–™),Chrome å·²å°éŽ–這個網é ã€‚</translation>
<translation id="6489534406876378309">開始上傳當機報告</translation>
@@ -603,20 +670,19 @@
<translation id="6556915248009097796">到期日:<ph name="EXPIRATION_DATE_ABBR" />,上次使用日期:<ph name="LAST_USED_DATE_NO_DETAIL" /></translation>
<translation id="6563469144985748109">你的管ç†å“¡å°šæœªæ ¸å‡†é€™å€‹ç¶²ç«™</translation>
<translation id="6569060085658103619">ç›®å‰é¡¯ç¤ºçš„是擴充功能é é¢</translation>
-<translation id="6593753688552673085">ä¸åˆ° <ph name="UPPER_ESTIMATE" /></translation>
+<translation id="657639383826808334">這項內容å¯èƒ½æœƒè©¦åœ–在你的è£ç½®ä¸Šå®‰è£ä¸å®‰å…¨çš„軟體,藉此竊å–或刪除你的資訊。<ph name="BEGIN_LINK" />ä»è¦é¡¯ç¤º<ph name="END_LINK" />。</translation>
<translation id="6596325263575161958">加密é¸é …</translation>
<translation id="662080504995468778">ä¸é›¢é–‹</translation>
<translation id="6626291197371920147">新增有效的信用å¡è™Ÿç¢¼</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> æœå°‹</translation>
+<translation id="6630809736994426279">攻擊者目å‰å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在你的 Mac 上安è£å±éšªç¨‹å¼ï¼Œè—‰æ­¤ç«Šå–或刪除你的資訊 (例如相片ã€å¯†ç¢¼ã€éƒµä»¶å’Œä¿¡ç”¨å¡è³‡æ–™)。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6644283850729428850">這項政策已é­å–代。</translation>
-<translation id="6652240803263749613">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />;電腦的作業系統ä¸ä¿¡ä»»ä¼ºæœå™¨çš„安全性憑證。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="6671697161687535275">è¦å¾ž Chromium 中移除表單填寫建議嗎?</translation>
<translation id="6685834062052613830">請登出並完æˆè¨­å®šç¨‹åº</translation>
<translation id="6710213216561001401">返回</translation>
<translation id="6710594484020273272">&lt;輸入æœå°‹å­—è©ž&gt;</translation>
<translation id="6711464428925977395">Proxy 伺æœå™¨ç™¼ç”ŸéŒ¯èª¤ï¼Œæˆ–是ä½å€ä¸æ­£ç¢ºã€‚</translation>
<translation id="6727102863431372879">設定</translation>
-<translation id="6731320287533051140">{COUNT,plural, =0{無}=1{1 個項目}other{# 個項目}}</translation>
<translation id="674375294223700098">ä¸æ˜Žçš„伺æœå™¨æ†‘證錯誤。</translation>
<translation id="6753269504797312559">政策值</translation>
<translation id="6757797048963528358">您的è£ç½®å·²é€²å…¥ç¡çœ æ¨¡å¼ã€‚</translation>
@@ -624,6 +690,8 @@
<translation id="6810899417690483278">自訂 ID</translation>
<translation id="6820686453637990663">CVC</translation>
<translation id="6824266427216888781">無法載入地å€è³‡æ–™</translation>
+<translation id="6825578344716086703">你嘗試連上 <ph name="DOMAIN" />,但伺æœå™¨çš„憑證是以防護力薄弱的簽章演算法 (例如 SHA-1) 進行簽署。這代表伺æœå™¨æ供的安全性憑證å¯èƒ½é­åˆ°å½é€ ï¼Œè€Œä¸”這個伺æœå™¨å¯èƒ½ä¸¦ä¸æ˜¯ä½ çš„目標伺æœå™¨ (你的連線å°è±¡å¯èƒ½æ˜¯æ”»æ“Šè€…的電腦)。</translation>
+<translation id="6830728435402077660">ä¸å®‰å…¨</translation>
<translation id="6831043979455480757">翻譯</translation>
<translation id="6839929833149231406">å€</translation>
<translation id="6874604403660855544">é‡åšæ–°å¢ž(&amp;R)</translation>
@@ -631,6 +699,7 @@
<translation id="6895330447102777224">您的信用å¡å·²é€šéŽé©—è­‰</translation>
<translation id="6897140037006041989">使用者代ç†ç¨‹å¼</translation>
<translation id="6915804003454593391">使用者:</translation>
+<translation id="6945221475159498467">é¸å–</translation>
<translation id="6948701128805548767">如è¦æŸ¥çœ‹å–件方å¼å’Œç›¸é—œè¦å®šï¼Œè«‹é¸å–一個地å€</translation>
<translation id="6957887021205513506">伺æœå™¨æ†‘證疑似å½é€ ã€‚</translation>
<translation id="6965382102122355670">確定</translation>
@@ -639,15 +708,16 @@
<translation id="6973656660372572881">已指定固定的 Proxy 伺æœå™¨å’Œ .pac 指令碼網å€ã€‚</translation>
<translation id="6989763994942163495">顯示進階設定...</translation>
<translation id="7000990526846637657">找ä¸åˆ°ä»»ä½•ç´€éŒ„é …ç›®</translation>
-<translation id="7009986207543992532">你嘗試連上 <ph name="DOMAIN" />,但伺æœå™¨æ供的憑證有效期é™å¤ªé•·ï¼Œå› æ­¤é›£ä»¥ä¿¡ä»»ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7012363358306927923">中國銀è¯</translation>
<translation id="7012372675181957985">ä½ ä»å¯å‰å¾€ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> å­˜å– Google 帳戶中ä¿å­˜çš„å„種ç€è¦½ç´€éŒ„</translation>
<translation id="7029809446516969842">密碼</translation>
+<translation id="7050187094878475250">您嘗試連線至 <ph name="DOMAIN" />,但伺æœå™¨æ供的憑證有效期é™å¤ªé•·ï¼Œå› æ­¤é›£ä»¥ä¿¡ä»»ã€‚</translation>
+<translation id="7053983685419859001">å°éŽ–</translation>
<translation id="7064851114919012435">è¯çµ¡è³‡è¨Š</translation>
<translation id="7079718277001814089">這個網站å«æœ‰æƒ¡æ„軟體</translation>
<translation id="7087282848513945231">郡</translation>
-<translation id="7088615885725309056">較舊記錄</translation>
<translation id="7090678807593890770">è«‹é€éŽ Google æœå°‹ã€Œ<ph name="LINK" />ã€</translation>
+<translation id="7108819624672055576">ä¾æ“šæ“´å……功能設定å…許</translation>
<translation id="7119414471315195487">關閉其他分é æˆ–程å¼</translation>
<translation id="7129409597930077180">無法é‹é€åˆ°é€™å€‹åœ°å€ï¼Œè«‹æ”¹ç”¨å…¶ä»–地å€ã€‚</translation>
<translation id="7138472120740807366">å¿«éžæ–¹å¼</translation>
@@ -665,22 +735,18 @@
<translation id="7220786058474068424">處ç†ä¸­</translation>
<translation id="724691107663265825">ä½ è¦é€ è¨ªçš„網站å«æœ‰æƒ¡æ„軟體</translation>
<translation id="724975217298816891">請輸入 <ph name="CREDIT_CARD" /> 的有效日期和信用å¡å®‰å…¨ç¢¼ï¼Œæ›´æ–°æ‚¨çš„信用å¡è©³ç´°è³‡è¨Šã€‚完æˆé©—證後,這個網站就會å–得您的信用å¡è©³ç´°è³‡è¨Šã€‚</translation>
-<translation id="725866823122871198">你電腦的日期和時間 (<ph name="DATE_AND_TIME" />) ä¸æ­£ç¢ºï¼Œå› æ­¤ç„¡æ³•èˆ‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§äººé€£ç·šã€‚</translation>
+<translation id="7260504762447901703">撤銷存å–權</translation>
<translation id="7275334191706090484">å—管ç†æ›¸ç±¤</translation>
<translation id="7298195798382681320">建議採用</translation>
<translation id="7309308571273880165">當機報告擷å–時間:<ph name="CRASH_TIME" /> (使用者è¦æ±‚上傳,但尚未上傳)</translation>
<translation id="7334320624316649418">é‡åšé‡æ–°æŽ’åº(&amp;R)</translation>
<translation id="733923710415886693">伺æœå™¨æ†‘證未ä¾æ†‘è­‰é€æ˜ŽåŒ–政策公開。</translation>
-<translation id="7351800657706554155">ç›®å‰ç„¡æ³•é€ è¨ª <ph name="SITE" />,因為這個網站的憑證已é­æ’¤éŠ·ã€‚網路錯誤和攻擊行為通常是暫時性的,因此這個網é å¯èƒ½ç¨å¾Œå°±æœƒæ¢å¾©æ­£å¸¸ç‹€æ…‹ã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="7353601530677266744">命令列</translation>
<translation id="7372973238305370288">æœå°‹çµæžœ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ä¸éœ€è¦</translation>
<translation id="7378810950367401542">/</translation>
<translation id="7390545607259442187">驗證信用å¡</translation>
-<translation id="7394102162464064926">你確定è¦å¾žç´€éŒ„中刪除這些網é å—Žï¼Ÿ
-
-æ醒你ï¼ä¸‹æ¬¡å¯ä»¥è©¦è©¦å¥½ç”¨çš„ç„¡ç—•æ¨¡å¼ (<ph name="SHORTCUT_KEY" />)。</translation>
<translation id="7400418766976504921">網å€</translation>
<translation id="7419106976560586862">設定檔路徑</translation>
<translation id="7424977062513257142">這個網é ä¸Šçš„嵌入å¼ç¶²é é¡¯ç¤ºï¼š</translation>
@@ -688,6 +754,7 @@
<translation id="7444046173054089907">這個網站é­åˆ°å°éŽ–</translation>
<translation id="7445762425076701745">你所連線的伺æœå™¨èº«åˆ†ç„¡æ³•å®Œå…¨é©—證,該伺æœå™¨æ‰€ä½¿ç”¨çš„å稱僅在你的網路中有效,無法驗證外部憑證授權單ä½çš„æ“有權。å³ä½¿æŸäº›æ†‘證授權單ä½æœƒæ ¸ç™¼é€™äº›æ†‘證,ä¸éŽç„¡æ³•å°±æ­¤ç¢ºä¿ä½ æ‰€é€£ä¸Šçš„網站是正確的,而ä¸æœƒé­åˆ°ç¶²è·¯æ”»æ“Šã€‚</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />進一步瞭解<ph name="END_LINK" />這個å•é¡Œã€‚</translation>
+<translation id="7455133967321480974">使用全域é è¨­å€¼ (å°éŽ–)</translation>
<translation id="7460163899615895653">你最近在其他è£ç½®ä¸Šé–‹å•Ÿçš„分é æœƒé¡¯ç¤ºåœ¨é€™è£¡</translation>
<translation id="7469372306589899959">正在驗證信用å¡</translation>
<translation id="7481312909269577407">å¾€å‰</translation>
@@ -695,36 +762,43 @@
<translation id="7508255263130623398">傳回的政策è£ç½® ID 沒有任何內容,或是與目å‰çš„è£ç½® ID ä¸ç¬¦</translation>
<translation id="7514365320538308">下載</translation>
<translation id="7518003948725431193">找ä¸åˆ°æ­¤ç¶²å€çš„網é ï¼š<ph name="URL" /></translation>
+<translation id="7521387064766892559">JavaScript</translation>
<translation id="7535087603100972091">值</translation>
<translation id="7537536606612762813">強制</translation>
+<translation id="7542403920425041731">經éŽä½ ç¢ºèªå¾Œï¼Œé€™å€‹ç¶²ç«™å°±æœƒå–得你的信用å¡è©³ç´°è³‡æ–™ã€‚</translation>
<translation id="7542995811387359312">由於這個表單並未採用加密連線方å¼ï¼Œæ‰€ä»¥ä¿¡ç”¨å¡è‡ªå‹•å¡«å…¥åŠŸèƒ½å·²åœç”¨ã€‚</translation>
<translation id="7543525346216957623">請徵求家長åŒæ„</translation>
<translation id="7549584377607005141">這個網é éœ€è¦ä½¿ç”¨ä½ å…ˆå‰è¼¸å…¥çš„資料æ‰èƒ½æ­£ç¢ºé¡¯ç¤ºã€‚ä½ å¯ä»¥é‡æ–°å‚³é€é€™äº›è³‡æ–™ï¼Œä¸éŽé€™éº¼åšæœƒé‡è¤‡åŸ·è¡Œé€™å€‹ç¶²é å…ˆå‰åŸ·è¡ŒéŽçš„任何動作。</translation>
<translation id="7552846755917812628">嘗試按照下列æ示æ“作:</translation>
<translation id="7554791636758816595">新增分é </translation>
+<translation id="7567204685887185387">伺æœå™¨ç„¡æ³•è­‰æ˜Žå…¶å±¬æ–¼ <ph name="DOMAIN" /> 網域;其安全性憑證是以欺è©æ–¹å¼ç™¼è¡Œã€‚這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–有攻擊者攔截你的連線所致。</translation>
+<translation id="7567794288553138946">{CONTACT,plural, =1{「<ph name="CONTACT_PREVIEW" />ã€å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> é …è¯çµ¡è³‡è¨Š}other{「<ph name="CONTACT_PREVIEW" />ã€å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> é …è¯çµ¡è³‡è¨Š}}</translation>
<translation id="7568593326407688803">此網é ç‚º<ph name="ORIGINAL_LANGUAGE" />ä½ è¦ç¿»è­¯ç¶²é å…§å®¹å—Žï¼Ÿ</translation>
<translation id="7569952961197462199">è¦å¾ž Chrome 中移除信用å¡å—Žï¼Ÿ</translation>
<translation id="7569983096843329377">黑色</translation>
<translation id="7578104083680115302">在ä¸åŒçš„è£ç½®ä¸Šé€éŽå„個網站和應用程å¼æ¶ˆè²»æ™‚,使用您讓 Google 儲存的信用å¡è³‡æ–™å³å¯å¿«é€Ÿä»˜æ¬¾ã€‚</translation>
<translation id="7588950540487816470">實體化網路</translation>
<translation id="7592362899630581445">伺æœå™¨æ†‘證的å稱ä¸ç¬¦åˆé™åˆ¶ã€‚</translation>
+<translation id="7598391785903975535">ä¸åˆ° <ph name="UPPER_ESTIMATE" /></translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> ç›®å‰ç„¡æ³•è™•ç†é€™é …è¦æ±‚。</translation>
<translation id="7600965453749440009">一律ä¸ç¿»è­¯<ph name="LANGUAGE" /></translation>
<translation id="7610193165460212391">值超出 <ph name="VALUE" /> 的範åœã€‚</translation>
<translation id="7613889955535752492">有效期é™ï¼š<ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">你已經使用其他版本的「Google 帳戶ã€å¯†ç¢¼å°è³‡æ–™é€²è¡ŒåŠ å¯†ï¼Œè«‹åœ¨ä¸‹æ–¹è¼¸å…¥å¯†ç¢¼ã€‚</translation>
-<translation id="7634554953375732414">你與這個網站建立了éžç§äººé€£ç·šã€‚</translation>
<translation id="7637571805876720304">è¦å¾ž Chromium 中移除信用å¡å—Žï¼Ÿ</translation>
<translation id="765676359832457558">éš±è—進階設定...</translation>
<translation id="7658239707568436148">å–消</translation>
+<translation id="7662298039739062396">由擴充功能控制的設定</translation>
<translation id="7667346355482952095">傳回的政策憑證沒有任何內容,或是與目å‰çš„憑證ä¸ç¬¦</translation>
<translation id="7668654391829183341">ä¸æ˜Žçš„è£ç½®</translation>
<translation id="7669271284792375604">攻擊者å¯èƒ½æœƒè©¦åœ–é€éŽé€™å€‹ç¶²ç«™èª˜ä½¿ä½ å®‰è£å°ç€è¦½é«”驗有害 (例如變更你的首é ï¼Œæˆ–是在你造訪的網站上顯示多餘的廣告) 的程å¼ã€‚</translation>
<translation id="7674629440242451245">想æ¶å…ˆè©¦ç”¨é…·ç‚«çš„ Chrome 新功能嗎?請å‰å¾€ chrome.com/dev 安è£é–‹ç™¼äººå“¡ç‰ˆã€‚</translation>
<translation id="7682287625158474539">寄é€åœ°å€</translation>
+<translation id="7701040980221191251">ç„¡</translation>
<translation id="7704050614460855821"><ph name="BEGIN_LINK" />繼續å‰å¾€ <ph name="SITE" /> 網站 (ä¸å®‰å…¨)<ph name="END_LINK" /></translation>
+<translation id="7714464543167945231">憑證</translation>
+<translation id="7716147886133743102">ä¾æ“šç®¡ç†å“¡çš„設定å°éŽ–</translation>
<translation id="7716424297397655342">無法從快å–載入這個網站</translation>
-<translation id="7733391738235763478">(<ph name="NUMBER_VISITS" />)</translation>
<translation id="7752995774971033316">未管ç†</translation>
<translation id="7755287808199759310">你的家長å¯ä»¥ç‚ºä½ è§£é™¤å°éŽ–這個網站</translation>
<translation id="7758069387465995638">防ç«ç‰†æˆ–防毒軟體å¯èƒ½å°éŽ–了連線。</translation>
@@ -751,15 +825,15 @@
<translation id="7951415247503192394">(32 ä½å…ƒ)</translation>
<translation id="7956713633345437162">行動版書籤</translation>
<translation id="7961015016161918242">一律ä¸è¦</translation>
-<translation id="7962083544045318153">當機 ID:<ph name="CRASH_LOCAL_ID" /></translation>
<translation id="7983301409776629893">一律將網é å…§å®¹ç”±<ph name="ORIGINAL_LANGUAGE" />翻譯æˆ<ph name="TARGET_LANGUAGE" /></translation>
<translation id="7995512525968007366">未指定</translation>
<translation id="800218591365569300">嘗試關閉其他分é æˆ–程å¼ï¼Œä»¥é‡‹å‡ºè¨˜æ†¶é«”。</translation>
<translation id="8012647001091218357">我們暫時無法與您的家長è¯çµ¡ï¼Œè«‹å†è©¦ä¸€æ¬¡ã€‚</translation>
<translation id="8025119109950072390">攻擊者å¯èƒ½æœƒè©¦åœ–é€éŽé€™å€‹ç¶²ç«™èª˜ä½¿ä½ åšä¸€äº›å±éšªçš„行為,例如安è£è»Ÿé«”或æ供個人資訊 (包括密碼ã€é›»è©±è™Ÿç¢¼æˆ–信用å¡è³‡æ–™)。</translation>
-<translation id="803030522067524905">Google 安全ç€è¦½åŠŸèƒ½æœ€è¿‘在 <ph name="SITE" /> 上åµæ¸¬åˆ°ç¶²è·¯è©é¨™è¡Œç‚ºã€‚è©é¨™ç¶²ç«™æœƒå½è£æˆå…¶ä»–網站,藉此騙å–你的資訊。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8034522405403831421">這是<ph name="SOURCE_LANGUAGE" />網é ï¼Œéœ€è¦ç¿»è­¯æˆ<ph name="TARGET_LANGUAGE" />嗎?</translation>
+<translation id="8037357227543935929">è©¢å• (é è¨­)</translation>
<translation id="8041089156583427627">æä¾›æ„見</translation>
+<translation id="8041940743680923270">使用全域é è¨­å€¼ (è¦æ±‚確èª)</translation>
<translation id="8088680233425245692">無法查看文章。</translation>
<translation id="8089520772729574115">ä¸åˆ° 1 MB</translation>
<translation id="8091372947890762290">尚未在伺æœå™¨ä¸Šå•Ÿå‹•</translation>
@@ -768,13 +842,14 @@
<translation id="8134994873729925007">找ä¸åˆ° <ph name="HOST_NAME" /> 的伺æœå™¨ <ph name="BEGIN_ABBR" />DNS ä½å€<ph name="END_ABBR" />。</translation>
<translation id="8149426793427495338">您的電腦已進入ç¡çœ æ¨¡å¼ã€‚</translation>
<translation id="8150722005171944719">無法讀å–ä½æ–¼ <ph name="URL" /> 的檔案。這個檔案å¯èƒ½å·²é­ç§»é™¤æˆ–移動ä½ç½®ï¼Œæˆ–者檔案權é™ç‚ºç¦æ­¢å­˜å–。</translation>
+<translation id="8184538546369750125">使用全域é è¨­å€¼ (å…許)</translation>
+<translation id="8191494405820426728">本機當機 ID:<ph name="CRASH_LOCAL_ID" /></translation>
<translation id="8194797478851900357">復原移動(&amp;U)</translation>
<translation id="8201077131113104583">擴充功能 (ID:「<ph name="EXTENSION_ID" />ã€) 的更新網å€ç„¡æ•ˆã€‚</translation>
<translation id="8202097416529803614">訂單摘è¦</translation>
<translation id="8218327578424803826">指派的ä½ç½®ï¼š</translation>
<translation id="8225771182978767009">設定這部電腦的使用者é¸æ“‡å°éŽ–這個網站。</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />ã€<ph name="TYPE_2" /></translation>
-<translation id="8230421197304563332">攻擊者目å‰å¯èƒ½æœƒè©¦åœ–é€éŽ <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 在你的電腦上安è£å±éšªç¨‹å¼ï¼Œè—‰æ­¤ç«Šå–或刪除你的資訊 (例如相片ã€å¯†ç¢¼ã€éƒµä»¶æˆ–信用å¡è³‡æ–™)。</translation>
<translation id="8241707690549784388">你尋找的網é ä½¿ç”¨äº†ä½ è¼¸å…¥çš„資料。返回該é æœƒé‡è¤‡ä½ å‰›æ‰çš„行動。你確定è¦ç¹¼çºŒå—Žï¼Ÿ</translation>
<translation id="8249320324621329438">上次擷å–時間:</translation>
<translation id="8253091569723639551">è«‹æ供帳單地å€</translation>
@@ -782,6 +857,7 @@
<translation id="8289355894181816810">如果你ä¸ç¢ºå®šé€™ä»£è¡¨ä»€éº¼æ„æ€ï¼Œè«‹èˆ‡ç¶²è·¯ç®¡ç†å“¡è¯çµ¡ã€‚</translation>
<translation id="8293206222192510085">新增書籤</translation>
<translation id="8294431847097064396">來æº</translation>
+<translation id="8306404619377842860">è£ç½®çš„日期和時間 (<ph name="DATE_AND_TIME" />) ä¸æ­£ç¢ºï¼Œå› æ­¤ç„¡æ³•èˆ‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§äººé€£ç·šã€‚<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8308427013383895095">網路連線發生å•é¡Œï¼Œç¿»è­¯ä½œæ¥­å¤±æ•—。</translation>
<translation id="8332188693563227489">å­˜å– <ph name="HOST_NAME" /> çš„è¦æ±‚é­åˆ°æ‹’絕</translation>
<translation id="834457929814110454">如果你瞭解安全性風險,也å¯ä»¥é¸æ“‡åœ¨æœ‰å®³ç¨‹å¼å°šæœªé­åˆ°ç§»é™¤çš„狀態下<ph name="BEGIN_LINK" />造訪這個網站<ph name="END_LINK" />。</translation>
@@ -802,11 +878,9 @@
<translation id="8483780878231876732">如è¦ä½¿ç”¨æ‚¨çš„ Google 帳戶中的信用å¡ï¼Œè«‹ç™»å…¥ Chrome</translation>
<translation id="8488350697529856933">é©ç”¨å°è±¡</translation>
<translation id="8498891568109133222"><ph name="HOST_NAME" /> 的回應時間éŽé•·ã€‚</translation>
-<translation id="852346902619691059">這個伺æœå™¨ç„¡æ³•è­‰æ˜Žæ‰€åœ¨ç¶²åŸŸæ˜¯ <ph name="DOMAIN" />ï¼›è£ç½®çš„作業系統ä¸ä¿¡ä»»ä¼ºæœå™¨çš„安全性憑證。這å¯èƒ½æ˜¯å› ç‚ºè¨­å®šéŒ¯èª¤ï¼Œæˆ–是有攻擊者攔截你的連線。<ph name="BEGIN_LEARN_MORE_LINK" />瞭解詳情<ph name="END_LEARN_MORE_LINK" /></translation>
<translation id="8532105204136943229">到期年份</translation>
<translation id="8543181531796978784">您å¯ä»¥<ph name="BEGIN_ERROR_LINK" />回報åµæ¸¬å•é¡Œ<ph name="END_ERROR_LINK" />。或者在您瞭解安全性風險後,ä»ç„¶å¯ä»¥<ph name="BEGIN_LINK" />å‰å¾€é€™å€‹ä¸å®‰å…¨çš„網站<ph name="END_LINK" />。</translation>
<translation id="8553075262323480129">無法判定網é çš„語言,翻譯作業失敗。</translation>
-<translation id="8559762987265718583">ä½ è£ç½®çš„日期和時間 (<ph name="DATE_AND_TIME" />) ä¸æ­£ç¢ºï¼Œå› æ­¤ç„¡æ³•èˆ‡ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> 建立ç§äººé€£ç·šã€‚</translation>
<translation id="8571890674111243710">正在將網é ç¿»è­¯æˆ<ph name="LANGUAGE" />...</translation>
<translation id="858637041960032120">新增電話號碼</translation>
<translation id="859285277496340001">憑證未指定負責檢查其本身是å¦å·²é­åˆ°æ’¤éŠ·çš„機制。</translation>
@@ -820,6 +894,7 @@
<translation id="8738058698779197622">你必須正確設定時é˜ï¼Œæ‰èƒ½å»ºç«‹å®‰å…¨é€£ç·šã€‚這是因為網站驗證身分時所使用的憑證僅於特定一段時間內有效。由於你è£ç½®çš„時é˜ä¸æ­£ç¢ºï¼Œå› æ­¤ Chromium 無法驗證這些憑證。</translation>
<translation id="8740359287975076522">找ä¸åˆ° <ph name="HOST_NAME" /> çš„ &lt;abbr id="dnsDefinition"&gt;DNS ä½å€&lt;/abbr&gt;,正在診斷å•é¡Œã€‚</translation>
<translation id="8759274551635299824">這張信用å¡å·²éŽæœŸ</translation>
+<translation id="8761567432415473239">Google 安全ç€è¦½æœ€è¿‘在「<ph name="SITE" />ã€<ph name="BEGIN_LINK" />發ç¾äº†æœ‰å®³ç¨‹å¼<ph name="END_LINK" />。</translation>
<translation id="8790007591277257123">é‡åšåˆªé™¤(&amp;R)</translation>
<translation id="8800988563907321413">這裡會顯示系統建議你ç€è¦½çš„鄰近網é </translation>
<translation id="8820817407110198400">書籤</translation>
@@ -832,29 +907,30 @@
<translation id="8870413625673593573">最近關閉的分é </translation>
<translation id="8874824191258364635">請輸入有效的信用å¡è™Ÿç¢¼</translation>
<translation id="8876793034577346603">無法解æžç¶²è·¯è¨­å®šã€‚</translation>
-<translation id="8877192140621905067">完æˆé©—證後,這個網站就會å–得您的信用å¡è©³ç´°è³‡è¨Š</translation>
<translation id="8889402386540077796">色調</translation>
<translation id="8891727572606052622">Proxy 模å¼ç„¡æ•ˆã€‚</translation>
<translation id="889901481107108152">很抱歉,這項實驗功能無法支æ´ä½ çš„å¹³å°ã€‚</translation>
<translation id="8903921497873541725">放大</translation>
<translation id="8931333241327730545">您è¦å°‡é€™å¼µå¡ç‰‡çš„資訊儲存到您的 Google 帳戶嗎?</translation>
<translation id="8932102934695377596">你的時é˜æ™‚é–“éŽæ…¢</translation>
-<translation id="8954894007019320973">(續)</translation>
<translation id="8971063699422889582">伺æœå™¨æ†‘證已éŽæœŸã€‚</translation>
<translation id="8986494364107987395">自動傳é€ä½¿ç”¨çµ±è¨ˆè³‡æ–™åŠç•¶æ©Ÿå ±å‘Šçµ¦ Google</translation>
-<translation id="8987927404178983737">月</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ä½ è¦ç€è¦½çš„網站å«æœ‰æœ‰å®³ç¨‹å¼</translation>
+<translation id="8997023839087525404">該伺æœå™¨çš„憑證並未根據憑證é€æ˜ŽåŒ–政策å°å¤–公開。部分憑證必須符åˆé€™é …è¦å®šï¼Œä»¥ç¢ºä¿æ†‘證值得信任,ä¸æœƒè®“使用者é­åˆ°æ”»æ“Šã€‚</translation>
<translation id="9001074447101275817"><ph name="DOMAIN" /> Proxy è¦æ±‚æ供使用者å稱和密碼。</translation>
+<translation id="9005998258318286617">無法載入 PDF 文件。</translation>
<translation id="901974403500617787">這些設定會套用至整個系統,åªæœ‰ä»¥ä¸‹ä½¿ç”¨è€…å¯è¨­å®šï¼š<ph name="OWNER_EMAIL" />。</translation>
+<translation id="9020200922353704812">請輸入信用å¡å¸³å–®åœ°å€</translation>
<translation id="9020542370529661692">此網é å…§å®¹å·²ç¿»è­¯æˆ<ph name="TARGET_LANGUAGE" /></translation>
<translation id="9035022520814077154">安全性錯誤</translation>
<translation id="9038649477754266430">使用é æ¸¬æŸ¥è©¢å­—串æœå‹™ï¼Œè®“系統更快載入網é </translation>
<translation id="9039213469156557790">此外,這個網é å«æœ‰å…¶ä»–ä¸å®‰å…¨çš„資æºã€‚其他人å¯èƒ½æœƒåœ¨è³‡æºå‚³è¼¸æœŸé–“檢視這些資æºï¼Œæ”»æ“Šè€…也å¯èƒ½æœƒä¿®æ”¹é€™äº›è³‡æºï¼Œé€²è€Œè®Šæ›´ç¶²é è¡Œç‚ºã€‚</translation>
-<translation id="9040185888511745258">攻擊者ä¼åœ–在 <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> 誘使你安è£æœ‰å®³ç€è¦½é«”é©—çš„ç¨‹å¼ (比如竄改你的首é ï¼Œæˆ–在你造訪的網站上å¦å¤–顯示廣告)。</translation>
+<translation id="9049981332609050619">你嘗試連線至 <ph name="DOMAIN" />,但伺æœå™¨æ供的憑證無效。</translation>
<translation id="9050666287014529139">通關密語</translation>
<translation id="9065203028668620118">編輯</translation>
<translation id="9068849894565669697">é¸å–é¡è‰²</translation>
+<translation id="9069693763241529744">ä¾æ“šæ“´å……功能設定å°éŽ–</translation>
<translation id="9076283476770535406">這個網站å¯èƒ½å«æœ‰æˆäººå…§å®¹</translation>
<translation id="9078964945751709336">è«‹æ供詳細資訊</translation>
<translation id="9103872766612412690"><ph name="SITE" /> 通常使用加密方å¼ä¿è­·æ‚¨çš„資訊。但 Chromium 這次嘗試連線到 <ph name="SITE" /> 時,該網站傳回了異常且錯誤的憑證。這å¯èƒ½æ˜¯å› ç‚ºæœ‰æ”»æ“Šè€…ä¼åœ–å½è£æˆ <ph name="SITE" />,或是å—到 Wi-Fi 登入畫é¢å½±éŸ¿è€Œé€ æˆé€£ç·šä¸­æ–·ã€‚ä¸éŽè«‹æ”¾å¿ƒï¼ŒChromium å·²åŠæ™‚åœæ­¢é€£ç·šï¼Œä¸¦æœªå‚³è¼¸ä»»ä½•è³‡æ–™ï¼Œå› æ­¤æ‚¨çš„資訊ä»ç„¶å®‰å…¨ç„¡è™žã€‚</translation>
@@ -863,16 +939,21 @@
<translation id="9148507642005240123">復原編輯(&amp;U)</translation>
<translation id="9154194610265714752">已更新</translation>
<translation id="9157595877708044936">設定中...</translation>
+<translation id="9169664750068251925">æ°¸é ç¦æ­¢åœ¨é€™å€‹ç¶²ç«™åŸ·è¡Œ</translation>
<translation id="9170848237812810038">å–消(&amp;U)</translation>
<translation id="917450738466192189">伺æœå™¨æ†‘證無效。</translation>
+<translation id="9180730219696997905">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> 種é¸é …}other{<ph name="SHIPPING_OPTION_PREVIEW" />å’Œå¦å¤– <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> 種é¸é …}}</translation>
<translation id="9183425211371246419"><ph name="HOST_NAME" /> 使用了ä¸æ”¯æ´çš„通訊å”定。</translation>
<translation id="9205078245616868884">您已使用åŒæ­¥é€šé—œå¯†èªžå°è³‡æ–™é€²è¡ŒåŠ å¯†ï¼Œè«‹è¼¸å…¥é€šé—œå¯†èªžé–‹å§‹é€²è¡ŒåŒæ­¥ã€‚</translation>
<translation id="9207861905230894330">無法新增文章。</translation>
+<translation id="9219103736887031265">圖片</translation>
<translation id="933612690413056017">無法連上網際網路</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">清除表單</translation>
<translation id="939736085109172342">新增資料夾</translation>
<translation id="941721044073577244">你沒有這個網站的ç€è¦½æ¬Šé™</translation>
<translation id="969892804517981540">æ­£å¼ç‰ˆæœ¬</translation>
+<translation id="975560348586398090">{COUNT,plural, =0{無}=1{1 個項目}other{# 個項目}}</translation>
<translation id="988159990683914416">開發人員版本</translation>
+<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/subresource_filter/OWNERS b/chromium/components/subresource_filter/OWNERS
index c21f3df9824..2fadb14a6ee 100644
--- a/chromium/components/subresource_filter/OWNERS
+++ b/chromium/components/subresource_filter/OWNERS
@@ -1,4 +1,5 @@
battre@chromium.org
+csharrison@chromium.org
engedy@chromium.org
melandory@chromium.org
pkalinnikov@chromium.org
diff --git a/chromium/components/subresource_filter/content/browser/BUILD.gn b/chromium/components/subresource_filter/content/browser/BUILD.gn
index bda66f04529..dd59a011c22 100644
--- a/chromium/components/subresource_filter/content/browser/BUILD.gn
+++ b/chromium/components/subresource_filter/content/browser/BUILD.gn
@@ -16,11 +16,20 @@ static_library("browser") {
"content_subresource_filter_driver_factory.h",
"content_subresource_filter_throttle_manager.cc",
"content_subresource_filter_throttle_manager.h",
+ "page_load_statistics.cc",
+ "page_load_statistics.h",
"subframe_navigation_filtering_throttle.cc",
"subframe_navigation_filtering_throttle.h",
"subresource_filter_client.h",
+ "subresource_filter_observer.h",
+ "subresource_filter_observer_manager.cc",
+ "subresource_filter_observer_manager.h",
"subresource_filter_safe_browsing_activation_throttle.cc",
"subresource_filter_safe_browsing_activation_throttle.h",
+ "subresource_filter_safe_browsing_client.cc",
+ "subresource_filter_safe_browsing_client.h",
+ "subresource_filter_safe_browsing_client_request.cc",
+ "subresource_filter_safe_browsing_client_request.h",
"verified_ruleset_dealer.cc",
"verified_ruleset_dealer.h",
]
@@ -48,12 +57,19 @@ static_library("test_support") {
sources = [
"async_document_subresource_filter_test_utils.cc",
"async_document_subresource_filter_test_utils.h",
+ "fake_safe_browsing_database_manager.cc",
+ "fake_safe_browsing_database_manager.h",
]
deps = [
":browser",
"//base/test:test_support",
"//components/subresource_filter/core/common",
+ "//content/public/browser",
"//testing/gtest:gtest",
+ "//url",
+ ]
+ public_deps = [
+ "//components/safe_browsing_db:test_database_manager",
]
}
@@ -63,7 +79,6 @@ source_set("unit_tests") {
"activation_state_computing_navigation_throttle_unittest.cc",
"async_document_subresource_filter_unittest.cc",
"content_ruleset_service_unittest.cc",
- "content_subresource_filter_driver_factory_unittest.cc",
"content_subresource_filter_throttle_manager_unittest.cc",
"subframe_navigation_filtering_throttle_unittest.cc",
"subresource_filter_safe_browsing_activation_throttle_unittest.cc",
@@ -73,7 +88,6 @@ source_set("unit_tests") {
":browser",
":test_support",
"//base/test:test_support",
- "//components/safe_browsing_db:test_database_manager",
"//components/safe_browsing_db:util",
"//components/subresource_filter/content/common",
"//components/subresource_filter/core/browser",
diff --git a/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc b/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc
index fddc75bd4d2..01c8cb75e45 100644
--- a/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc
+++ b/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc
@@ -9,7 +9,9 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter.h"
+#include "components/subresource_filter/core/common/time_measurements.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -82,9 +84,7 @@ ActivationStateComputingNavigationThrottle::WillProcessResponse() {
params.document_url = navigation_handle()->GetURL();
params.parent_activation_state = parent_activation_state_.value();
if (!navigation_handle()->IsInMainFrame()) {
- content::RenderFrameHost* parent =
- navigation_handle()->GetWebContents()->FindFrameByFrameTreeNodeId(
- navigation_handle()->GetParentFrameTreeNodeId());
+ content::RenderFrameHost* parent = navigation_handle()->GetParentFrame();
DCHECK(parent);
params.parent_document_origin = parent->GetLastCommittedOrigin();
}
@@ -94,11 +94,29 @@ ActivationStateComputingNavigationThrottle::WillProcessResponse() {
base::Bind(&ActivationStateComputingNavigationThrottle::
OnActivationStateComputed,
weak_ptr_factory_.GetWeakPtr()));
+
+ defer_timestamp_ = base::TimeTicks::Now();
return content::NavigationThrottle::ThrottleCheckResult::DEFER;
}
+const char* ActivationStateComputingNavigationThrottle::GetNameForLogging() {
+ return "ActivationStateComputingNavigationThrottle";
+}
+
void ActivationStateComputingNavigationThrottle::OnActivationStateComputed(
ActivationState state) {
+ DCHECK(!defer_timestamp_.is_null());
+ base::TimeDelta delay = base::TimeTicks::Now() - defer_timestamp_;
+ UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
+ "SubresourceFilter.DocumentLoad.ActivationComputingDelay", delay,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
+ 50);
+ if (navigation_handle()->IsInMainFrame()) {
+ UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
+ "SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame",
+ delay, base::TimeDelta::FromMicroseconds(1),
+ base::TimeDelta::FromSeconds(10), 50);
+ }
navigation_handle()->Resume();
}
diff --git a/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h b/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h
index c3415734a27..2ca8b3ef33e 100644
--- a/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h
+++ b/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
+#include "base/time/time.h"
#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
#include "components/subresource_filter/core/common/activation_state.h"
#include "content/public/browser/navigation_throttle.h"
@@ -55,6 +56,7 @@ class ActivationStateComputingNavigationThrottle
// content::NavigationThrottle:
content::NavigationThrottle::ThrottleCheckResult WillProcessResponse()
override;
+ const char* GetNameForLogging() override;
// After the navigation is finished, the client may optionally choose to
// continue using the DocumentSubresourceFilter that was used to compute the
@@ -88,6 +90,8 @@ class ActivationStateComputingNavigationThrottle
// nullptr until NotifyPageActivationWithRuleset is called.
VerifiedRuleset::Handle* ruleset_handle_;
+ base::TimeTicks defer_timestamp_;
+
// Becomes true when the throttle manager reaches ReadyToCommitNavigation and
// sends an activation IPC to the render process. Makes sure a caller cannot
// take ownership of the subresource filter unless an activation IPC is sent
diff --git a/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc b/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc
index 4be0506e0e0..9b06df81a45 100644
--- a/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc
+++ b/chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc
@@ -6,12 +6,15 @@
#include <memory>
#include <utility>
+#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
+#include "base/test/histogram_tester.h"
#include "base/test/test_simple_task_runner.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h"
@@ -363,6 +366,28 @@ TEST_F(ActivationStateComputingThrottleSubFrameTest, DryRunIsPropagated) {
EXPECT_FALSE(state.generic_blocking_rules_disabled);
}
+TEST_F(ActivationStateComputingThrottleSubFrameTest,
+ DryRunWithLoggingIsPropagated) {
+ ActivationState page_state(ActivationLevel::DRYRUN);
+ page_state.enable_logging = true;
+ NavigateAndCommitMainFrameWithPageActivationState(
+ GURL("http://example.test/"), page_state);
+ EXPECT_EQ(ActivationLevel::DRYRUN, last_activation_state().activation_level);
+
+ CreateSubframeAndInitTestNavigation(GURL("http://example.child/"),
+ last_committed_frame_host(),
+ last_activation_state());
+ SimulateStartAndExpectToProceed();
+ SimulateRedirectAndExpectToProceed(GURL("http://example.child/?v=1"));
+ SimulateCommitAndExpectToProceed();
+
+ ActivationState state = last_activation_state();
+ EXPECT_EQ(ActivationLevel::DRYRUN, state.activation_level);
+ EXPECT_TRUE(state.enable_logging);
+ EXPECT_FALSE(state.filtering_disabled_for_document);
+ EXPECT_FALSE(state.generic_blocking_rules_disabled);
+}
+
TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated) {
NavigateAndCommitMainFrameWithPageActivationState(
GURL("http://allow-child-to-be-whitelisted.com/"),
@@ -413,4 +438,39 @@ TEST_F(ActivationStateComputingThrottleSubFrameTest, DisabledStatePropagated2) {
EXPECT_TRUE(state.generic_blocking_rules_disabled);
}
+TEST_F(ActivationStateComputingThrottleSubFrameTest, DelayMetrics) {
+ base::HistogramTester histogram_tester;
+ NavigateAndCommitMainFrameWithPageActivationState(
+ GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED));
+ ActivationState state = last_activation_state();
+ EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level);
+ EXPECT_FALSE(state.filtering_disabled_for_document);
+
+ const char kActivationDelay[] =
+ "SubresourceFilter.DocumentLoad.ActivationComputingDelay";
+ const char kActivationDelayMainFrame[] =
+ "SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame";
+ histogram_tester.ExpectTotalCount(kActivationDelay, 1);
+ histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1);
+
+ // Subframe activation should not log main frame metrics.
+ CreateSubframeAndInitTestNavigation(GURL("http://example.test/"),
+ last_committed_frame_host(),
+ last_activation_state());
+ SimulateStartAndExpectToProceed();
+ SimulateCommitAndExpectToProceed();
+ histogram_tester.ExpectTotalCount(kActivationDelay, 2);
+ histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1);
+
+ // No page activation should imply no delay.
+ CreateTestNavigationForMainFrame(GURL("http://example.test2/"));
+ SimulateStartAndExpectToProceed();
+ SimulateCommitAndExpectToProceed();
+
+ state = last_activation_state();
+ EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level);
+ histogram_tester.ExpectTotalCount(kActivationDelay, 2);
+ histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1);
+}
+
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/content_ruleset_service.cc b/chromium/components/subresource_filter/content/browser/content_ruleset_service.cc
index 72a5734ac46..67dbd914b23 100644
--- a/chromium/components/subresource_filter/content/browser/content_ruleset_service.cc
+++ b/chromium/components/subresource_filter/content/browser/content_ruleset_service.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/sequenced_task_runner.h"
#include "components/subresource_filter/content/common/subresource_filter_messages.h"
#include "components/subresource_filter/core/browser/ruleset_service.h"
#include "content/public/browser/browser_thread.h"
diff --git a/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc b/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
index 7ba5c822365..cff5203f629 100644
--- a/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
+++ b/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
@@ -4,36 +4,25 @@
#include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h"
-#include "base/feature_list.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/memory/ptr_util.h"
#include "base/rand_util.h"
#include "base/time/time.h"
-#include "components/subresource_filter/content/browser/content_activation_list_utils.h"
#include "components/subresource_filter/content/browser/subresource_filter_client.h"
-#include "components/subresource_filter/content/common/subresource_filter_messages.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
+#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
#include "components/subresource_filter/core/common/activation_list.h"
#include "components/subresource_filter/core/common/activation_state.h"
-#include "components/subresource_filter/core/common/time_measurements.h"
#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/navigation_throttle.h"
-#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
-#include "ipc/ipc_message_macros.h"
#include "net/base/net_errors.h"
#include "url/gurl.h"
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(
+ subresource_filter::ContentSubresourceFilterDriverFactory);
+
namespace subresource_filter {
namespace {
-const char kWebContentsUserDataKey[] =
- "web_contents_subresource_filter_driver_factory";
-
-std::string DistillURLToHostAndPath(const GURL& url) {
- return url.host() + url.path();
-}
-
// Returns true with a probability given by |performance_measurement_rate| if
// ThreadTicks is supported, otherwise returns false.
bool ShouldMeasurePerformanceForPageLoad(double performance_measurement_rate) {
@@ -44,369 +33,93 @@ bool ShouldMeasurePerformanceForPageLoad(double performance_measurement_rate) {
base::RandDouble() < performance_measurement_rate);
}
-// Records histograms about the length of redirect chains, and about the pattern
-// of whether each URL in the chain matched the activation list.
-#define REPORT_REDIRECT_PATTERN_FOR_SUFFIX(suffix, hits_pattern, chain_size) \
- do { \
- UMA_HISTOGRAM_ENUMERATION( \
- "SubresourceFilter.PageLoad.RedirectChainMatchPattern." suffix, \
- hits_pattern, 0x10); \
- UMA_HISTOGRAM_COUNTS( \
- "SubresourceFilter.PageLoad.RedirectChainLength." suffix, chain_size); \
- } while (0)
-
} // namespace
// static
void ContentSubresourceFilterDriverFactory::CreateForWebContents(
content::WebContents* web_contents,
- std::unique_ptr<SubresourceFilterClient> client) {
+ SubresourceFilterClient* client) {
if (FromWebContents(web_contents))
return;
- web_contents->SetUserData(kWebContentsUserDataKey,
- new ContentSubresourceFilterDriverFactory(
- web_contents, std::move(client)));
+ web_contents->SetUserData(
+ UserDataKey(), base::MakeUnique<ContentSubresourceFilterDriverFactory>(
+ web_contents, client));
}
// static
-ContentSubresourceFilterDriverFactory*
-ContentSubresourceFilterDriverFactory::FromWebContents(
- content::WebContents* web_contents) {
- return static_cast<ContentSubresourceFilterDriverFactory*>(
- web_contents->GetUserData(kWebContentsUserDataKey));
-}
-
-// static
-bool ContentSubresourceFilterDriverFactory::NavigationIsPageReload(
- const GURL& url,
- const content::Referrer& referrer,
- ui::PageTransition transition) {
- return ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD) ||
- // Some pages 'reload' from JavaScript by navigating to themselves.
- url == referrer.url;
-}
-
ContentSubresourceFilterDriverFactory::ContentSubresourceFilterDriverFactory(
content::WebContents* web_contents,
- std::unique_ptr<SubresourceFilterClient> client)
+ SubresourceFilterClient* client)
: content::WebContentsObserver(web_contents),
- configuration_(GetActiveConfiguration()),
- client_(std::move(client)),
+ client_(client),
throttle_manager_(
base::MakeUnique<ContentSubresourceFilterThrottleManager>(
this,
client_->GetRulesetDealer(),
- web_contents)),
- activation_level_(ActivationLevel::DISABLED),
- activation_decision_(ActivationDecision::UNKNOWN),
- measure_performance_(false) {}
+ web_contents)) {}
ContentSubresourceFilterDriverFactory::
~ContentSubresourceFilterDriverFactory() {}
-void ContentSubresourceFilterDriverFactory::OnDocumentLoadStatistics(
- const DocumentLoadStatistics& statistics) {
- // Note: Chances of overflow are negligible.
- aggregated_document_statistics_.num_loads_total += statistics.num_loads_total;
- aggregated_document_statistics_.num_loads_evaluated +=
- statistics.num_loads_evaluated;
- aggregated_document_statistics_.num_loads_matching_rules +=
- statistics.num_loads_matching_rules;
- aggregated_document_statistics_.num_loads_disallowed +=
- statistics.num_loads_disallowed;
-
- aggregated_document_statistics_.evaluation_total_wall_duration +=
- statistics.evaluation_total_wall_duration;
- aggregated_document_statistics_.evaluation_total_cpu_duration +=
- statistics.evaluation_total_cpu_duration;
-}
-
-bool ContentSubresourceFilterDriverFactory::IsWhitelisted(
- const GURL& url) const {
- return whitelisted_hosts_.find(url.host()) != whitelisted_hosts_.end() ||
- client_->IsWhitelistedByContentSettings(url);
-}
-
-void ContentSubresourceFilterDriverFactory::
- OnMainResourceMatchedSafeBrowsingBlacklist(
- const GURL& url,
- const std::vector<GURL>& redirect_urls,
- safe_browsing::SBThreatType threat_type,
- safe_browsing::ThreatPatternType threat_type_metadata) {
- AddActivationListMatch(
- url, GetListForThreatTypeAndMetadata(threat_type, threat_type_metadata));
-}
-
-void ContentSubresourceFilterDriverFactory::AddHostOfURLToWhitelistSet(
- const GURL& url) {
- if (url.has_host() && url.SchemeIsHTTPOrHTTPS())
- whitelisted_hosts_.insert(url.host());
-}
-
-ContentSubresourceFilterDriverFactory::ActivationDecision
-ContentSubresourceFilterDriverFactory::ComputeActivationDecisionForMainFrameURL(
- const GURL& url) const {
- if (configuration_.activation_level == ActivationLevel::DISABLED)
- return ActivationDecision::ACTIVATION_DISABLED;
-
- if (configuration_.activation_scope == ActivationScope::NO_SITES)
- return ActivationDecision::ACTIVATION_DISABLED;
-
- if (!url.SchemeIsHTTPOrHTTPS())
- return ActivationDecision::UNSUPPORTED_SCHEME;
- if (IsWhitelisted(url))
- return ActivationDecision::URL_WHITELISTED;
-
- switch (configuration_.activation_scope) {
- case ActivationScope::ALL_SITES:
- return ActivationDecision::ACTIVATED;
- case ActivationScope::ACTIVATION_LIST: {
- // The logic to ensure only http/https URLs are activated lives in
- // AddActivationListMatch to ensure the activation list only has relevant
- // entries.
- DCHECK(url.SchemeIsHTTPOrHTTPS() ||
- !DidURLMatchActivationList(url, configuration_.activation_list));
- bool should_activate =
- DidURLMatchActivationList(url, configuration_.activation_list);
- if (configuration_.activation_list ==
- ActivationList::PHISHING_INTERSTITIAL) {
- // Handling special case, where activation on the phishing sites also
- // mean the activation on the sites with social engineering metadata.
- should_activate |= DidURLMatchActivationList(
- url, ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL);
- }
- return should_activate ? ActivationDecision::ACTIVATED
- : ActivationDecision::ACTIVATION_LIST_NOT_MATCHED;
- }
- default:
- return ActivationDecision::ACTIVATION_DISABLED;
- }
-}
-
-void ContentSubresourceFilterDriverFactory::OnReloadRequested() {
- UMA_HISTOGRAM_BOOLEAN("SubresourceFilter.Prompt.NumReloads", true);
- const GURL& whitelist_url = web_contents()->GetLastCommittedURL();
-
- // Only whitelist via content settings when using the experimental UI,
- // otherwise could get into a situation where content settings cannot be
- // adjusted.
- if (base::FeatureList::IsEnabled(
- subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI)) {
- client_->WhitelistByContentSettings(whitelist_url);
- } else {
- AddHostOfURLToWhitelistSet(whitelist_url);
- }
- web_contents()->GetController().Reload(content::ReloadType::NORMAL, true);
-}
-
-void ContentSubresourceFilterDriverFactory::WillProcessResponse(
- content::NavigationHandle* navigation_handle) {
+void ContentSubresourceFilterDriverFactory::NotifyPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ ActivationDecision activation_decision,
+ Configuration::ActivationOptions matched_options) {
+ DCHECK(navigation_handle->IsInMainFrame());
DCHECK(!navigation_handle->IsSameDocument());
- if (!navigation_handle->IsInMainFrame() ||
- navigation_handle->GetNetErrorCode() != net::OK) {
+ if (navigation_handle->GetNetErrorCode() != net::OK)
return;
- }
-
- const GURL& url = navigation_handle->GetURL();
- const content::Referrer& referrer = navigation_handle->GetReferrer();
- ui::PageTransition transition = navigation_handle->GetPageTransition();
-
- RecordRedirectChainMatchPattern();
-
- if (configuration_.should_whitelist_site_on_reload &&
- NavigationIsPageReload(url, referrer, transition)) {
- // Whitelist this host for the current as well as subsequent navigations.
- AddHostOfURLToWhitelistSet(url);
- }
- activation_decision_ = ComputeActivationDecisionForMainFrameURL(url);
- DCHECK(activation_decision_ != ActivationDecision::UNKNOWN);
+ activation_decision_ = activation_decision;
+ activation_options_ = matched_options;
+ DCHECK_NE(activation_decision_, ActivationDecision::UNKNOWN);
if (activation_decision_ != ActivationDecision::ACTIVATED) {
- ResetActivationState();
+ DCHECK_EQ(activation_options_.activation_level, ActivationLevel::DISABLED);
return;
}
- activation_level_ = configuration_.activation_level;
- measure_performance_ = activation_level_ != ActivationLevel::DISABLED &&
- ShouldMeasurePerformanceForPageLoad(
- configuration_.performance_measurement_rate);
- ActivationState state = ActivationState(activation_level_);
- state.measure_performance = measure_performance_;
- throttle_manager_->NotifyPageActivationComputed(navigation_handle, state);
+ DCHECK_NE(activation_options_.activation_level, ActivationLevel::DISABLED);
+ ActivationState state = ActivationState(activation_options_.activation_level);
+ state.measure_performance = ShouldMeasurePerformanceForPageLoad(
+ activation_options_.performance_measurement_rate);
+
+ // TODO(csharrison): Also use metadata returned from the safe browsing filter,
+ // when it is available to set enable_logging. Add tests for this behavior.
+ state.enable_logging =
+ activation_options_.activation_level == ActivationLevel::ENABLED &&
+ !activation_options_.should_suppress_notifications &&
+ base::FeatureList::IsEnabled(
+ kSafeBrowsingSubresourceFilterExperimentalUI);
+
+ SubresourceFilterObserverManager::FromWebContents(web_contents())
+ ->NotifyPageActivationComputed(navigation_handle, activation_decision_,
+ state);
}
void ContentSubresourceFilterDriverFactory::OnFirstSubresourceLoadDisallowed() {
- if (configuration_.should_suppress_notifications)
+ if (activation_options_.should_suppress_notifications)
return;
-
- client_->ToggleNotificationVisibility(activation_level_ ==
+ client_->ToggleNotificationVisibility(activation_options_.activation_level ==
ActivationLevel::ENABLED);
}
-bool ContentSubresourceFilterDriverFactory::ShouldSuppressActivation(
- content::NavigationHandle* navigation_handle) {
- // Never suppress subframe navigations.
- return navigation_handle->IsInMainFrame() &&
- IsWhitelisted(navigation_handle->GetURL());
-}
-
-void ContentSubresourceFilterDriverFactory::ResetActivationState() {
- navigation_chain_.clear();
- activation_list_matches_.clear();
- activation_level_ = ActivationLevel::DISABLED;
- measure_performance_ = false;
- aggregated_document_statistics_ = DocumentLoadStatistics();
-}
-
void ContentSubresourceFilterDriverFactory::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
if (navigation_handle->IsInMainFrame() &&
!navigation_handle->IsSameDocument()) {
activation_decision_ = ActivationDecision::UNKNOWN;
- ResetActivationState();
- navigation_chain_.push_back(navigation_handle->GetURL());
client_->ToggleNotificationVisibility(false);
}
}
-void ContentSubresourceFilterDriverFactory::DidRedirectNavigation(
+void ContentSubresourceFilterDriverFactory::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
- DCHECK(!navigation_handle->IsSameDocument());
- if (navigation_handle->IsInMainFrame())
- navigation_chain_.push_back(navigation_handle->GetURL());
-}
-
-void ContentSubresourceFilterDriverFactory::DidFinishLoad(
- content::RenderFrameHost* render_frame_host,
- const GURL& validated_url) {
- if (render_frame_host->GetParent())
- return;
-
- if (activation_level_ != ActivationLevel::DISABLED) {
- UMA_HISTOGRAM_COUNTS_1000(
- "SubresourceFilter.PageLoad.NumSubresourceLoads.Total",
- aggregated_document_statistics_.num_loads_total);
- UMA_HISTOGRAM_COUNTS_1000(
- "SubresourceFilter.PageLoad.NumSubresourceLoads.Evaluated",
- aggregated_document_statistics_.num_loads_evaluated);
- UMA_HISTOGRAM_COUNTS_1000(
- "SubresourceFilter.PageLoad.NumSubresourceLoads.MatchedRules",
- aggregated_document_statistics_.num_loads_matching_rules);
- UMA_HISTOGRAM_COUNTS_1000(
- "SubresourceFilter.PageLoad.NumSubresourceLoads.Disallowed",
- aggregated_document_statistics_.num_loads_disallowed);
- }
-
- if (measure_performance_) {
- DCHECK(activation_level_ != ActivationLevel::DISABLED);
- UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
- "SubresourceFilter.PageLoad.SubresourceEvaluation.TotalWallDuration",
- aggregated_document_statistics_.evaluation_total_wall_duration,
- base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
- 50);
- UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
- "SubresourceFilter.PageLoad.SubresourceEvaluation.TotalCPUDuration",
- aggregated_document_statistics_.evaluation_total_cpu_duration,
- base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
- 50);
- } else {
- DCHECK(aggregated_document_statistics_.evaluation_total_wall_duration
- .is_zero());
- DCHECK(aggregated_document_statistics_.evaluation_total_cpu_duration
- .is_zero());
- }
-}
-
-bool ContentSubresourceFilterDriverFactory::OnMessageReceived(
- const IPC::Message& message,
- content::RenderFrameHost* render_frame_host) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(ContentSubresourceFilterDriverFactory, message)
- IPC_MESSAGE_HANDLER(SubresourceFilterHostMsg_DocumentLoadStatistics,
- OnDocumentLoadStatistics)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-bool ContentSubresourceFilterDriverFactory::DidURLMatchActivationList(
- const GURL& url,
- ActivationList activation_list) const {
- auto match_types =
- activation_list_matches_.find(DistillURLToHostAndPath(url));
- return match_types != activation_list_matches_.end() &&
- match_types->second.find(activation_list) != match_types->second.end();
-}
-
-void ContentSubresourceFilterDriverFactory::AddActivationListMatch(
- const GURL& url,
- ActivationList match_type) {
- if (match_type == ActivationList::NONE)
- return;
- if (url.has_host() && url.SchemeIsHTTPOrHTTPS())
- activation_list_matches_[DistillURLToHostAndPath(url)].insert(match_type);
-}
-
-int ContentSubresourceFilterDriverFactory::CalculateHitPatternForActivationList(
- ActivationList activation_list) const {
- int hits_pattern = 0;
- const int kInitialURLHitMask = 0x4;
- const int kRedirectURLHitMask = 0x2;
- const int kFinalURLHitMask = 0x1;
-
- if (navigation_chain_.size() > 1) {
- if (DidURLMatchActivationList(navigation_chain_.back(), activation_list))
- hits_pattern |= kFinalURLHitMask;
- if (DidURLMatchActivationList(navigation_chain_.front(), activation_list))
- hits_pattern |= kInitialURLHitMask;
-
- // Examine redirects.
- for (size_t i = 1; i < navigation_chain_.size() - 1; ++i) {
- if (DidURLMatchActivationList(navigation_chain_[i], activation_list)) {
- hits_pattern |= kRedirectURLHitMask;
- break;
- }
- }
- } else {
- if (navigation_chain_.size() &&
- DidURLMatchActivationList(navigation_chain_.front(), activation_list)) {
- hits_pattern = 0x8; // One url hit.
- }
- }
- return hits_pattern;
-}
-
-void ContentSubresourceFilterDriverFactory::RecordRedirectChainMatchPattern()
- const {
- RecordRedirectChainMatchPatternForList(
- ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL);
- RecordRedirectChainMatchPatternForList(ActivationList::PHISHING_INTERSTITIAL);
- RecordRedirectChainMatchPatternForList(ActivationList::SUBRESOURCE_FILTER);
-}
-
-void ContentSubresourceFilterDriverFactory::
- RecordRedirectChainMatchPatternForList(
- ActivationList activation_list) const {
- int hits_pattern = CalculateHitPatternForActivationList(activation_list);
- if (!hits_pattern)
- return;
- size_t chain_size = navigation_chain_.size();
- switch (activation_list) {
- case ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL:
- REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SocialEngineeringAdsInterstitial",
- hits_pattern, chain_size);
- break;
- case ActivationList::PHISHING_INTERSTITIAL:
- REPORT_REDIRECT_PATTERN_FOR_SUFFIX("PhishingInterstital", hits_pattern,
- chain_size);
- break;
- case ActivationList::SUBRESOURCE_FILTER:
- REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SubresourceFilterOnly", hits_pattern,
- chain_size);
- break;
- default:
- NOTREACHED();
- break;
+ if (navigation_handle->IsInMainFrame() &&
+ !navigation_handle->IsSameDocument() &&
+ activation_decision_ == ActivationDecision::UNKNOWN &&
+ navigation_handle->HasCommitted()) {
+ activation_decision_ = ActivationDecision::ACTIVATION_DISABLED;
+ activation_options_ = Configuration::ActivationOptions();
}
}
diff --git a/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h b/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h
index 7577274e45f..bbb2d6b2b53 100644
--- a/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h
+++ b/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h
@@ -5,27 +5,17 @@
#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_SUBRESOURCE_FILTER_DRIVER_FACTORY_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_SUBRESOURCE_FILTER_DRIVER_FACTORY_H_
-#include <map>
#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
#include "base/macros.h"
-#include "base/supports_user_data.h"
-#include "base/time/time.h"
-#include "components/safe_browsing_db/util.h"
#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
-#include "components/subresource_filter/core/common/document_load_statistics.h"
+#include "components/subresource_filter/core/common/activation_decision.h"
#include "content/public/browser/web_contents_observer.h"
-#include "ui/base/page_transition_types.h"
-#include "url/gurl.h"
+#include "content/public/browser/web_contents_user_data.h"
namespace content {
class WebContents;
-class RenderFrameHost;
} // namespace content
namespace safe_browsing {
@@ -38,162 +28,88 @@ class SubresourceFilterClient;
enum class ActivationLevel;
enum class ActivationList;
-using HostPathSet = std::set<std::string>;
-using URLToActivationListsMap =
- std::unordered_map<std::string, std::set<ActivationList>>;
-
// Controls the activation of subresource filtering for each page load in a
// WebContents and is responsible for sending the activation signal to all the
// per-frame SubresourceFilterAgents on the renderer side.
class ContentSubresourceFilterDriverFactory
- : public base::SupportsUserData::Data,
+ : public content::WebContentsUserData<
+ ContentSubresourceFilterDriverFactory>,
public content::WebContentsObserver,
public ContentSubresourceFilterThrottleManager::Delegate {
public:
- // NOTE: ActivationDecision backs a UMA histogram, so it is append-only.
- enum class ActivationDecision {
- // The activation decision is unknown, or not known yet.
- UNKNOWN,
-
- // Subresource filtering was activated.
- ACTIVATED,
-
- // Did not activate because subresource filtering was disabled.
- ACTIVATION_DISABLED,
-
- // Did not activate because the main frame document URL had an unsupported
- // scheme.
- UNSUPPORTED_SCHEME,
-
- // Did not activate because the main frame document URL was whitelisted.
- URL_WHITELISTED,
-
- // Did not activate because the main frame document URL did not match the
- // activation list.
- ACTIVATION_LIST_NOT_MATCHED,
-
- // Max value for enum.
- ACTIVATION_DECISION_MAX
- };
-
- static void CreateForWebContents(
- content::WebContents* web_contents,
- std::unique_ptr<SubresourceFilterClient> client);
- static ContentSubresourceFilterDriverFactory* FromWebContents(
- content::WebContents* web_contents);
-
- // Whether the |url|, |referrer|, and |transition| are considered to be
- // associated with a page reload.
- static bool NavigationIsPageReload(const GURL& url,
- const content::Referrer& referrer,
- ui::PageTransition transition);
+ static void CreateForWebContents(content::WebContents* web_contents,
+ SubresourceFilterClient* client);
explicit ContentSubresourceFilterDriverFactory(
content::WebContents* web_contents,
- std::unique_ptr<SubresourceFilterClient> client);
+ SubresourceFilterClient* client);
~ContentSubresourceFilterDriverFactory() override;
- // Whitelists the host of |url|, so that page loads with the main-frame
- // document being loaded from this host will be exempted from subresource
- // filtering for the lifetime of this WebContents.
- void AddHostOfURLToWhitelistSet(const GURL& url);
-
- // Called when Safe Browsing detects that the |url| corresponding to the load
- // of the main frame belongs to the blacklist with |threat_type|. If the
- // blacklist is the Safe Browsing Social Engineering ads landing, then |url|
- // and |redirects| are saved.
- void OnMainResourceMatchedSafeBrowsingBlacklist(
- const GURL& url,
- const std::vector<GURL>& redirect_urls,
- safe_browsing::SBThreatType threat_type,
- safe_browsing::ThreatPatternType threat_type_metadata);
-
- // Reloads the page and inserts the host of its URL to the whitelist.
- void OnReloadRequested();
-
- // Returns the |ActivationDecision| for the current main frame
- // document.
+ void NotifyPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ ActivationDecision activation_decision,
+ Configuration::ActivationOptions matched_options);
+
+ // Returns the |ActivationDecision| for the current main frame document. Do
+ // not rely on this API, it is only temporary.
+ // TODO(csharrison): Remove this and |activation_decision_| once consumers
+ // move to become SubresourceFilterObservers.
ActivationDecision GetActivationDecisionForLastCommittedPageLoad() const {
return activation_decision_;
}
+ // Returns the |ActivationOptions| for the current main frame
+ // document. Do not rely on this API, it is only temporary.
+ // TODO(csharrison): Remove this and |activation_options_| in place of adding
+ // |should_suppress_notifications| on ActivationState.
+ const Configuration::ActivationOptions&
+ GetActivationOptionsForLastCommittedPageLoad() const {
+ return activation_options_;
+ }
+
// ContentSubresourceFilterThrottleManager::Delegate:
void OnFirstSubresourceLoadDisallowed() override;
- bool ShouldSuppressActivation(
- content::NavigationHandle* navigation_handle) override;
- void WillProcessResponse(
- content::NavigationHandle* navigation_handle) override;
ContentSubresourceFilterThrottleManager* throttle_manager() {
return throttle_manager_.get();
}
- // TODO(https://crbug.com/708181): Allow tests to change the configuration
- // after construction (which happens at WebContents creation) but before a
- // navigation start. Can be removed once the Safe Browsing navigation throttle
- // handles all activation decisions.
- void set_configuration_for_testing(Configuration configuration) {
- configuration_ = std::move(configuration);
- }
+ SubresourceFilterClient* client() { return client_; }
private:
friend class ContentSubresourceFilterDriverFactoryTest;
friend class safe_browsing::SafeBrowsingServiceTest;
- void ResetActivationState();
-
- void OnDocumentLoadStatistics(const DocumentLoadStatistics& statistics);
-
- bool IsWhitelisted(const GURL& url) const;
-
// content::WebContentsObserver:
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override;
- void DidRedirectNavigation(
+ void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
- void DidFinishLoad(content::RenderFrameHost* render_frame_host,
- const GURL& validated_url) override;
- bool OnMessageReceived(const IPC::Message& message,
- content::RenderFrameHost* render_frame_host) override;
-
- // Checks base on the value of |url| and current activation scope if
- // activation signal should be sent.
- ActivationDecision ComputeActivationDecisionForMainFrameURL(
- const GURL& url) const;
-
- bool DidURLMatchActivationList(const GURL& url,
- ActivationList activation_list) const;
- void AddActivationListMatch(const GURL& url, ActivationList match_type);
- int CalculateHitPatternForActivationList(
- ActivationList activation_list) const;
- void RecordRedirectChainMatchPattern() const;
-
- void RecordRedirectChainMatchPatternForList(
- ActivationList activation_list) const;
-
- Configuration configuration_;
-
- std::unique_ptr<SubresourceFilterClient> client_;
+ // Must outlive this class.
+ SubresourceFilterClient* client_;
std::unique_ptr<ContentSubresourceFilterThrottleManager> throttle_manager_;
- // Hosts to whitelist. This is only used for per-WebContents whitelisting and
- // is distinct from content settings whitelisting.
- HostPathSet whitelisted_hosts_;
-
- ActivationLevel activation_level_;
- ActivationDecision activation_decision_;
- bool measure_performance_;
-
- // The URLs in the navigation chain.
- std::vector<GURL> navigation_chain_;
-
- URLToActivationListsMap activation_list_matches_;
-
- // Statistics about subresource loads, aggregated across all frames of the
- // current page.
- DocumentLoadStatistics aggregated_document_statistics_;
+ // The activation decision corresponding to the most recently _started_
+ // non-same-document navigation in the main frame.
+ //
+ // The value is reset to ActivationDecision::UNKNOWN at the start of each such
+ // navigation, and will not be assigned until the navigation successfully
+ // reaches the WillProcessResponse stage (or successfully finishes if
+ // throttles are not invoked). This means that after a cancelled or otherwise
+ // unsuccessful navigation, the value will be left at UNKNOWN indefinitely.
+ ActivationDecision activation_decision_ =
+ ActivationDecision::ACTIVATION_DISABLED;
+
+ // The activation options corresponding to the most recently _committed_
+ // non-same-document navigation in the main frame.
+ //
+ // The value corresponding to the previous such navigation will be retained,
+ // and the new value not assigned until a subsequent navigation successfully
+ // reaches the WillProcessResponse stage (or successfully finishes if
+ // throttles are not invoked).
+ Configuration::ActivationOptions activation_options_;
DISALLOW_COPY_AND_ASSIGN(ContentSubresourceFilterDriverFactory);
};
diff --git a/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc b/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
deleted file mode 100644
index b230b216a93..00000000000
--- a/chromium/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
+++ /dev/null
@@ -1,895 +0,0 @@
-// Copyright 2016 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/subresource_filter/content/browser/content_subresource_filter_driver_factory.h"
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/field_trial.h"
-#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
-#include "components/safe_browsing_db/util.h"
-#include "components/subresource_filter/content/browser/content_activation_list_utils.h"
-#include "components/subresource_filter/content/browser/subresource_filter_client.h"
-#include "components/subresource_filter/content/common/subresource_filter_messages.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
-#include "components/subresource_filter/core/common/activation_list.h"
-#include "components/subresource_filter/core/common/test_ruleset_creator.h"
-#include "components/subresource_filter/core/common/test_ruleset_utils.h"
-#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/navigation_throttle.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/test/mock_render_process_host.h"
-#include "content/public/test/navigation_simulator.h"
-#include "content/public/test/test_renderer_host.h"
-#include "content/public/test/web_contents_tester.h"
-#include "net/base/net_errors.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace subresource_filter {
-
-using ActivationDecision =
- ContentSubresourceFilterDriverFactory::ActivationDecision;
-
-namespace {
-
-const char kExampleUrlWithParams[] = "https://example.com/soceng?q=engsoc";
-const char kExampleUrl[] = "https://example.com";
-const char kExampleLoginUrl[] = "https://example.com/login";
-const char kUrlA[] = "https://example_a.com";
-const char kUrlB[] = "https://example_b.com";
-const char kUrlC[] = "https://example_c.com";
-const char kUrlD[] = "https://example_d.com";
-const char kSubframeName[] = "Child";
-const char kDisallowedUrl[] = "https://example.com/disallowed.html";
-
-const char kMatchesPatternHistogramName[] =
- "SubresourceFilter.PageLoad.RedirectChainMatchPattern.";
-const char kNavigationChainSize[] =
- "SubresourceFilter.PageLoad.RedirectChainLength.";
-
-// Human readable representation of expected redirect chain match patterns.
-// The explanations for the buckets given for the following redirect chain:
-// A->B->C->D, where A is initial URL and D is a final URL.
-enum RedirectChainMatchPattern {
- EMPTY, // No histograms were recorded.
- F0M0L1, // D is a Safe Browsing match.
- F0M1L0, // B or C, or both are Safe Browsing matches.
- F0M1L1, // B or C, or both and D are Safe Browsing matches.
- F1M0L0, // A is Safe Browsing match
- F1M0L1, // A and D are Safe Browsing matches.
- F1M1L0, // B and/or C and A are Safe Browsing matches.
- F1M1L1, // B and/or C and A and D are Safe Browsing matches.
- NO_REDIRECTS_HIT, // Redirect chain consists of single URL, aka no redirects
- // has happened, and this URL was a Safe Browsing hit.
- NUM_HIT_PATTERNS,
-};
-
-std::string GetSuffixForList(const ActivationList& type) {
- switch (type) {
- case ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL:
- return "SocialEngineeringAdsInterstitial";
- case ActivationList::PHISHING_INTERSTITIAL:
- return "PhishingInterstital";
- case ActivationList::SUBRESOURCE_FILTER:
- return "SubresourceFilterOnly";
- case ActivationList::NONE:
- return std::string();
- }
- return std::string();
-}
-
-struct ActivationListTestData {
- ActivationDecision expected_activation_decision;
- const char* const activation_list;
- safe_browsing::SBThreatType threat_type;
- safe_browsing::ThreatPatternType threat_type_metadata;
-};
-
-const ActivationListTestData kActivationListTestData[] = {
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED, "",
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListSocialEngineeringAdsInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::NONE},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListSocialEngineeringAdsInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::MALWARE_LANDING},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListSocialEngineeringAdsInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::MALWARE_DISTRIBUTION},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_API_ABUSE,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_BLACKLISTED_RESOURCE,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_BINARY_MALWARE_URL,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_UNWANTED,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_SAFE,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::NONE},
- {ActivationDecision::ACTIVATED,
- subresource_filter::kActivationListSocialEngineeringAdsInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
- {ActivationDecision::ACTIVATED,
- subresource_filter::kActivationListPhishingInterstitial,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
-};
-
-struct ActivationScopeTestData {
- ActivationDecision expected_activation_decision;
- bool url_matches_activation_list;
- const char* const activation_scope;
-};
-
-const ActivationScopeTestData kActivationScopeTestData[] = {
- {ActivationDecision::ACTIVATED, false /* url_matches_activation_list */,
- kActivationScopeAllSites},
- {ActivationDecision::ACTIVATED, true /* url_matches_activation_list */,
- kActivationScopeAllSites},
- {ActivationDecision::ACTIVATION_DISABLED,
- true /* url_matches_activation_list */, kActivationScopeNoSites},
- {ActivationDecision::ACTIVATED, true /* url_matches_activation_list */,
- kActivationScopeActivationList},
- {ActivationDecision::ACTIVATION_LIST_NOT_MATCHED,
- false /* url_matches_activation_list */, kActivationScopeActivationList},
-};
-
-struct ActivationLevelTestData {
- ActivationDecision expected_activation_decision;
- const char* const activation_level;
-};
-
-const ActivationLevelTestData kActivationLevelTestData[] = {
- {ActivationDecision::ACTIVATED, kActivationLevelDryRun},
- {ActivationDecision::ACTIVATED, kActivationLevelEnabled},
- {ActivationDecision::ACTIVATION_DISABLED, kActivationLevelDisabled},
-};
-
-class MockSubresourceFilterClient : public SubresourceFilterClient {
- public:
- MockSubresourceFilterClient(VerifiedRulesetDealer::Handle* ruleset_dealer)
- : ruleset_dealer_(ruleset_dealer) {}
-
- ~MockSubresourceFilterClient() override = default;
-
- bool IsWhitelistedByContentSettings(const GURL& url) override {
- return false;
- }
-
- void WhitelistByContentSettings(const GURL& url) override {}
-
- VerifiedRulesetDealer::Handle* GetRulesetDealer() override {
- return ruleset_dealer_;
- }
-
- MOCK_METHOD1(ToggleNotificationVisibility, void(bool));
-
- private:
- // Owned by the test harness.
- VerifiedRulesetDealer::Handle* ruleset_dealer_;
-
- DISALLOW_COPY_AND_ASSIGN(MockSubresourceFilterClient);
-};
-
-} // namespace
-
-class ContentSubresourceFilterDriverFactoryTest
- : public content::RenderViewHostTestHarness,
- public content::WebContentsObserver {
- public:
- ContentSubresourceFilterDriverFactoryTest() {}
- ~ContentSubresourceFilterDriverFactoryTest() override {}
-
- // content::RenderViewHostImplTestHarness:
- void SetUp() override {
- RenderViewHostTestHarness::SetUp();
-
- std::vector<proto::UrlRule> rules;
- rules.push_back(testing::CreateSuffixRule("disallowed.html"));
- ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules(
- rules, &test_ruleset_pair_));
- ruleset_dealer_ = base::MakeUnique<VerifiedRulesetDealer::Handle>(
- base::MessageLoop::current()->task_runner());
- ruleset_dealer_->SetRulesetFile(
- testing::TestRuleset::Open(test_ruleset_pair_.indexed));
- client_ = new MockSubresourceFilterClient(ruleset_dealer_.get());
- ContentSubresourceFilterDriverFactory::CreateForWebContents(
- RenderViewHostTestHarness::web_contents(), base::WrapUnique(client()));
-
- // Add a subframe.
- content::RenderFrameHostTester* rfh_tester =
- content::RenderFrameHostTester::For(main_rfh());
- rfh_tester->InitializeRenderFrameIfNeeded();
- rfh_tester->AppendChild(kSubframeName);
-
- Observe(content::RenderViewHostTestHarness::web_contents());
- }
-
- void TearDown() override {
- ruleset_dealer_.reset();
- base::RunLoop().RunUntilIdle();
- RenderViewHostTestHarness::TearDown();
- }
-
- ContentSubresourceFilterDriverFactory* factory() {
- return ContentSubresourceFilterDriverFactory::FromWebContents(
- RenderViewHostTestHarness::web_contents());
- }
-
- MockSubresourceFilterClient* client() { return client_; }
-
- content::RenderFrameHost* GetSubframeRFH() {
- for (content::RenderFrameHost* rfh :
- RenderViewHostTestHarness::web_contents()->GetAllFrames()) {
- if (rfh->GetFrameName() == kSubframeName)
- return rfh;
- }
- return nullptr;
- }
-
- void ExpectActivationSignalForFrame(content::RenderFrameHost* rfh,
- bool expect_activation) {
- content::MockRenderProcessHost* render_process_host =
- static_cast<content::MockRenderProcessHost*>(rfh->GetProcess());
- const IPC::Message* message =
- render_process_host->sink().GetFirstMessageMatching(
- SubresourceFilterMsg_ActivateForNextCommittedLoad::ID);
- ASSERT_EQ(expect_activation, !!message);
- if (expect_activation) {
- std::tuple<ActivationState> args;
- SubresourceFilterMsg_ActivateForNextCommittedLoad::Read(message, &args);
- ActivationLevel level = std::get<0>(args).activation_level;
- EXPECT_NE(ActivationLevel::DISABLED, level);
- }
- render_process_host->sink().ClearMessages();
- }
-
- void BlacklistURLWithRedirectsNavigateAndCommit(
- const std::vector<bool>& blacklisted_urls,
- const std::vector<GURL>& navigation_chain,
- safe_browsing::SBThreatType threat_type,
- safe_browsing::ThreatPatternType threat_type_metadata,
- const content::Referrer& referrer,
- ui::PageTransition transition,
- RedirectChainMatchPattern expected_pattern,
- ActivationDecision expected_activation_decision) {
- const bool expected_activation =
- expected_activation_decision == ActivationDecision::ACTIVATED;
- base::HistogramTester tester;
- EXPECT_CALL(*client(), ToggleNotificationVisibility(false)).Times(1);
-
- std::unique_ptr<content::NavigationSimulator> navigation_simulator =
- content::NavigationSimulator::CreateRendererInitiated(
- navigation_chain.front(), main_rfh());
- navigation_simulator->SetReferrer(referrer);
- navigation_simulator->SetTransition(transition);
- navigation_simulator->Start();
-
- if (blacklisted_urls.front()) {
- factory()->OnMainResourceMatchedSafeBrowsingBlacklist(
- navigation_chain.front(), navigation_chain, threat_type,
- threat_type_metadata);
- }
- ::testing::Mock::VerifyAndClearExpectations(client());
-
- for (size_t i = 1; i < navigation_chain.size(); ++i) {
- const GURL url = navigation_chain[i];
- if (i < blacklisted_urls.size() && blacklisted_urls[i]) {
- factory()->OnMainResourceMatchedSafeBrowsingBlacklist(
- url, navigation_chain, threat_type, threat_type_metadata);
- }
- navigation_simulator->Redirect(url);
- }
-
- navigation_simulator->Commit();
- ExpectActivationSignalForFrame(main_rfh(), expected_activation);
- EXPECT_EQ(expected_activation_decision,
- factory()->GetActivationDecisionForLastCommittedPageLoad());
-
- // Re-create a subframe now that the frame has navigated.
- content::RenderFrameHostTester* rfh_tester =
- content::RenderFrameHostTester::For(main_rfh());
- rfh_tester->AppendChild(kSubframeName);
- ActivationList activation_list =
- GetListForThreatTypeAndMetadata(threat_type, threat_type_metadata);
-
- const std::string suffix(GetSuffixForList(activation_list));
- size_t all_pattern =
- tester.GetTotalCountsForPrefix(kMatchesPatternHistogramName).size();
- size_t all_chain_size =
- tester.GetTotalCountsForPrefix(kNavigationChainSize).size();
- if (expected_pattern != EMPTY) {
- EXPECT_THAT(tester.GetAllSamples(kMatchesPatternHistogramName + suffix),
- ::testing::ElementsAre(base::Bucket(expected_pattern, 1)));
- EXPECT_THAT(
- tester.GetAllSamples(kNavigationChainSize + suffix),
- ::testing::ElementsAre(base::Bucket(navigation_chain.size(), 1)));
- // Check that we recorded only what is needed.
- EXPECT_EQ(1u, all_pattern);
- EXPECT_EQ(1u, all_chain_size);
- } else {
- EXPECT_EQ(0u, all_pattern);
- EXPECT_EQ(0u, all_chain_size);
- }
- }
-
- void NavigateSubframeAndExpectCheckResult(const GURL& url,
- bool expect_cancelled) {
- std::unique_ptr<content::NavigationSimulator> simulator =
- content::NavigationSimulator::CreateRendererInitiated(url,
- GetSubframeRFH());
- simulator->Start();
- content::NavigationThrottle::ThrottleCheckResult result =
- simulator->GetLastThrottleCheckResult();
- if (expect_cancelled) {
- EXPECT_EQ(content::NavigationThrottle::CANCEL, result);
- } else {
- EXPECT_EQ(content::NavigationThrottle::PROCEED, result);
- simulator->Commit();
- }
- }
-
- void NavigateAndCommitSubframe(const GURL& url, bool expected_activation) {
- EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0);
-
- content::NavigationSimulator::NavigateAndCommitFromDocument(
- url, GetSubframeRFH());
- ExpectActivationSignalForFrame(GetSubframeRFH(), expected_activation);
- ::testing::Mock::VerifyAndClearExpectations(client());
- }
-
- void NavigateAndExpectActivation(
- const std::vector<bool>& blacklisted_urls,
- const std::vector<GURL>& navigation_chain,
- safe_browsing::SBThreatType threat_type,
- safe_browsing::ThreatPatternType threat_type_metadata,
- const content::Referrer& referrer,
- ui::PageTransition transition,
- RedirectChainMatchPattern expected_pattern,
- ActivationDecision expected_activation_decision) {
- const bool expected_activation =
- expected_activation_decision == ActivationDecision::ACTIVATED;
- BlacklistURLWithRedirectsNavigateAndCommit(
- blacklisted_urls, navigation_chain, threat_type, threat_type_metadata,
- referrer, transition, expected_pattern, expected_activation_decision);
-
- NavigateAndCommitSubframe(GURL(kExampleLoginUrl), expected_activation);
- }
-
- void NavigateAndExpectActivation(
- const std::vector<bool>& blacklisted_urls,
- const std::vector<GURL>& navigation_chain,
- RedirectChainMatchPattern expected_pattern,
- ActivationDecision expected_activation_decision) {
- NavigateAndExpectActivation(
- blacklisted_urls, navigation_chain,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS,
- content::Referrer(), ui::PAGE_TRANSITION_LINK, expected_pattern,
- expected_activation_decision);
- }
-
- void EmulateFailedNavigationAndExpectNoActivation(const GURL& url) {
- EXPECT_CALL(*client(), ToggleNotificationVisibility(false)).Times(1);
-
- // With browser-side navigation enabled, ReadyToCommitNavigation is invoked
- // even for failed navigations. This is correctly simulated by
- // NavigationSimulator. Make sure no activation message is sent in this
- // case.
- content::NavigationSimulator::NavigateAndFailFromDocument(
- url, net::ERR_TIMED_OUT, main_rfh());
- ExpectActivationSignalForFrame(main_rfh(), false);
- ::testing::Mock::VerifyAndClearExpectations(client());
- }
-
- void EmulateInPageNavigation(
- const std::vector<bool>& blacklisted_urls,
- RedirectChainMatchPattern expected_pattern,
- ActivationDecision expected_activation_decision) {
- // This test examines the navigation with the following sequence of events:
- // DidStartProvisional(main, "example.com")
- // ReadyToCommitNavigation(“example.comâ€)
- // DidCommitProvisional(main, "example.com")
- // DidStartProvisional(sub, "example.com/login")
- // DidCommitProvisional(sub, "example.com/login")
- // DidCommitProvisional(main, "example.com#ref")
-
- NavigateAndExpectActivation(blacklisted_urls, {GURL(kExampleUrl)},
- expected_pattern, expected_activation_decision);
- EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0);
- std::unique_ptr<content::NavigationSimulator> navigation_simulator =
- content::NavigationSimulator::CreateRendererInitiated(GURL(kExampleUrl),
- main_rfh());
- navigation_simulator->CommitSameDocument();
- ExpectActivationSignalForFrame(main_rfh(), false);
- ::testing::Mock::VerifyAndClearExpectations(client());
- }
-
- protected:
- // content::WebContentsObserver
- void DidStartNavigation(
- content::NavigationHandle* navigation_handle) override {
- if (navigation_handle->IsSameDocument())
- return;
-
- std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
- factory()->throttle_manager()->MaybeAppendNavigationThrottles(
- navigation_handle, &throttles);
- for (auto& it : throttles)
- navigation_handle->RegisterThrottleForTesting(std::move(it));
- }
-
- private:
- static bool expected_measure_performance() {
- const double rate = GetActiveConfiguration().performance_measurement_rate;
- // Note: The case when 0 < rate < 1 is not deterministic, don't test it.
- EXPECT_TRUE(rate == 0 || rate == 1);
- return rate == 1;
- }
-
- testing::TestRulesetCreator test_ruleset_creator_;
- testing::TestRulesetPair test_ruleset_pair_;
-
- // Owned by the factory.
- MockSubresourceFilterClient* client_;
-
- std::unique_ptr<VerifiedRulesetDealer::Handle> ruleset_dealer_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentSubresourceFilterDriverFactoryTest);
-};
-
-class ContentSubresourceFilterDriverFactoryThreatTypeTest
- : public ContentSubresourceFilterDriverFactoryTest,
- public ::testing::WithParamInterface<ActivationListTestData> {
- public:
- ContentSubresourceFilterDriverFactoryThreatTypeTest() {}
- ~ContentSubresourceFilterDriverFactoryThreatTypeTest() override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ContentSubresourceFilterDriverFactoryThreatTypeTest);
-};
-
-class ContentSubresourceFilterDriverFactoryActivationScopeTest
- : public ContentSubresourceFilterDriverFactoryTest,
- public ::testing::WithParamInterface<ActivationScopeTestData> {
- public:
- ContentSubresourceFilterDriverFactoryActivationScopeTest() {}
- ~ContentSubresourceFilterDriverFactoryActivationScopeTest() override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(
- ContentSubresourceFilterDriverFactoryActivationScopeTest);
-};
-
-class ContentSubresourceFilterDriverFactoryActivationLevelTest
- : public ContentSubresourceFilterDriverFactoryTest,
- public ::testing::WithParamInterface<ActivationLevelTestData> {
- public:
- ContentSubresourceFilterDriverFactoryActivationLevelTest() {}
- ~ContentSubresourceFilterDriverFactoryActivationLevelTest() override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(
- ContentSubresourceFilterDriverFactoryActivationLevelTest);
-};
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest,
- ActivateForFrameHostDisabledFeature) {
- // Activation scope is set to NONE => no activation should happen even if URL
- // which is visited was a SB hit.
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_DISABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeAllSites,
- kActivationListSocialEngineeringAdsInterstitial);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
- const GURL url(kExampleUrlWithParams);
- NavigateAndExpectActivation({true}, {url}, NO_REDIRECTS_HIT,
- ActivationDecision::ACTIVATION_DISABLED);
- factory()->AddHostOfURLToWhitelistSet(url);
- NavigateAndExpectActivation({true}, {url}, NO_REDIRECTS_HIT,
- ActivationDecision::ACTIVATION_DISABLED);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest, NoActivationWhenNoMatch) {
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeActivationList,
- kActivationListSocialEngineeringAdsInterstitial);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
- NavigateAndExpectActivation({false}, {GURL(kExampleUrl)}, EMPTY,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest,
- SpecialCaseNavigationAllSitesEnabled) {
- // Check that when the experiment is enabled for all site, the activation
- // signal is always sent.
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeAllSites);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
- EmulateInPageNavigation({false}, EMPTY, ActivationDecision::ACTIVATED);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest,
- SpecialCaseNavigationActivationListEnabled) {
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeActivationList,
- kActivationListSocialEngineeringAdsInterstitial);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
- EmulateInPageNavigation({true}, NO_REDIRECTS_HIT,
- ActivationDecision::ACTIVATED);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest,
- SpecialCaseNavigationActivationListEnabledWithPerformanceMeasurement) {
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeActivationList,
- kActivationListSocialEngineeringAdsInterstitial,
- "1" /* performance_measurement_rate */);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
- EmulateInPageNavigation({true}, NO_REDIRECTS_HIT,
- ActivationDecision::ACTIVATED);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest, FailedNavigation) {
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeAllSites);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
- const GURL url(kExampleUrl);
- NavigateAndExpectActivation({false}, {url}, EMPTY,
- ActivationDecision::ACTIVATED);
- EmulateFailedNavigationAndExpectNoActivation(url);
-}
-
-// TODO(melandory): refactor the test so it no longer require the current
-// activation list to be matching.
-TEST_F(ContentSubresourceFilterDriverFactoryTest, RedirectPatternTest) {
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeActivationList,
- kActivationListSocialEngineeringAdsInterstitial);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
- struct RedirectRedirectChainMatchPatternTestData {
- std::vector<bool> blacklisted_urls;
- std::vector<GURL> navigation_chain;
- RedirectChainMatchPattern hit_expected_pattern;
- ActivationDecision expected_activation_decision;
- } kRedirectRedirectChainMatchPatternTestData[] = {
- {{false},
- {GURL(kUrlA)},
- EMPTY,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- {{true}, {GURL(kUrlA)}, NO_REDIRECTS_HIT, ActivationDecision::ACTIVATED},
- {{false, false},
- {GURL(kUrlA), GURL(kUrlB)},
- EMPTY,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- {{false, true},
- {GURL(kUrlA), GURL(kUrlB)},
- F0M0L1,
- ActivationDecision::ACTIVATED},
- {{true, false},
- {GURL(kUrlA), GURL(kUrlB)},
- F1M0L0,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- {{true, true},
- {GURL(kUrlA), GURL(kUrlB)},
- F1M0L1,
- ActivationDecision::ACTIVATED},
- {{false, false, false},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- EMPTY,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- {{false, false, true},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- F0M0L1,
- ActivationDecision::ACTIVATED},
- {{false, true, false},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- F0M1L0,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- {{false, true, true},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- F0M1L1,
- ActivationDecision::ACTIVATED},
- {{true, false, false},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- F1M0L0,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- {{true, false, true},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- F1M0L1,
- ActivationDecision::ACTIVATED},
- {{true, true, false},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- F1M1L0,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- {{true, true, true},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)},
- F1M1L1,
- ActivationDecision::ACTIVATED},
- {{false, true, false, false},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC), GURL(kUrlD)},
- F0M1L0,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED},
- };
-
- for (size_t i = 0U; i < arraysize(kRedirectRedirectChainMatchPatternTestData);
- ++i) {
- auto test_data = kRedirectRedirectChainMatchPatternTestData[i];
- NavigateAndExpectActivation(
- test_data.blacklisted_urls, test_data.navigation_chain,
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS,
- content::Referrer(), ui::PAGE_TRANSITION_LINK,
- test_data.hit_expected_pattern, test_data.expected_activation_decision);
- NavigateAndExpectActivation(
- {false}, {GURL("https://dummy.com")}, EMPTY,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED);
-#if defined(GOOGLE_CHROME_BUILD)
- NavigateAndExpectActivation(
- test_data.blacklisted_urls, test_data.navigation_chain,
- safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
- safe_browsing::ThreatPatternType::NONE, content::Referrer(),
- ui::PAGE_TRANSITION_LINK, test_data.hit_expected_pattern,
- ActivationDecision::ACTIVATION_LIST_NOT_MATCHED);
-#endif
- }
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest, NotificationVisibility) {
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeAllSites);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
-
- NavigateAndExpectActivation({false}, {GURL(kExampleUrl)}, EMPTY,
- ActivationDecision::ACTIVATED);
- EXPECT_CALL(*client(), ToggleNotificationVisibility(true)).Times(1);
- NavigateSubframeAndExpectCheckResult(GURL(kDisallowedUrl),
- true /* expect_cancelled */);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest,
- SuppressNotificationVisibility) {
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeAllSites, "" /* activation_lists */,
- "" /* performance_measurement_rate */,
- "true" /* suppress_notifications */);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
-
- NavigateAndExpectActivation({false}, {GURL(kExampleUrl)}, EMPTY,
- ActivationDecision::ACTIVATED);
- EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0);
- NavigateSubframeAndExpectCheckResult(GURL(kDisallowedUrl),
- true /* expect_cancelled */);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest,
- InactiveMainFrame_SubframeNotFiltered) {
- GURL url(kExampleUrl);
- NavigateAndExpectActivation({false}, {url}, EMPTY,
- ActivationDecision::ACTIVATION_DISABLED);
- NavigateSubframeAndExpectCheckResult(url, false /* expect_cancelled */);
-}
-
-TEST_F(ContentSubresourceFilterDriverFactoryTest, WhitelistSiteOnReload) {
- const struct {
- content::Referrer referrer;
- ui::PageTransition transition;
- ActivationDecision expected_activation_decision;
- } kTestCases[] = {
- {content::Referrer(), ui::PAGE_TRANSITION_LINK,
- ActivationDecision::ACTIVATED},
- {content::Referrer(GURL(kUrlA), blink::kWebReferrerPolicyDefault),
- ui::PAGE_TRANSITION_LINK, ActivationDecision::ACTIVATED},
- {content::Referrer(GURL(kExampleUrl), blink::kWebReferrerPolicyDefault),
- ui::PAGE_TRANSITION_LINK, ActivationDecision::URL_WHITELISTED},
- {content::Referrer(), ui::PAGE_TRANSITION_RELOAD,
- ActivationDecision::URL_WHITELISTED}};
-
- for (const auto& test_case : kTestCases) {
- SCOPED_TRACE(::testing::Message("referrer = \"")
- << test_case.referrer.url << "\""
- << " transition = \"" << test_case.transition << "\"");
-
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeAllSites, "" /* activation_lists */,
- "" /* performance_measurement_rate */, "" /* suppress_notifications */,
- "true" /* whitelist_site_on_reload */);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
-
- NavigateAndExpectActivation(
- {false}, {GURL(kExampleUrl)},
- safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
- safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS,
- test_case.referrer, test_case.transition, EMPTY,
- test_case.expected_activation_decision);
- // Verify that if the first URL failed to activate, subsequent same-origin
- // navigations also fail to activate.
- NavigateAndExpectActivation({false}, {GURL(kExampleUrlWithParams)}, EMPTY,
- test_case.expected_activation_decision);
- }
-}
-
-TEST_P(ContentSubresourceFilterDriverFactoryActivationLevelTest,
- ActivateForFrameState) {
- const ActivationLevelTestData& test_data = GetParam();
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, test_data.activation_level,
- kActivationScopeActivationList,
- kActivationListSocialEngineeringAdsInterstitial);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
-
- const GURL url(kExampleUrlWithParams);
- NavigateAndExpectActivation({true}, {url}, NO_REDIRECTS_HIT,
- test_data.expected_activation_decision);
- factory()->AddHostOfURLToWhitelistSet(url);
- NavigateAndExpectActivation(
- {true}, {GURL(kExampleUrlWithParams)}, NO_REDIRECTS_HIT,
- GetActiveConfiguration().activation_level == ActivationLevel::DISABLED
- ? ActivationDecision::ACTIVATION_DISABLED
- : ActivationDecision::URL_WHITELISTED);
-}
-
-TEST_P(ContentSubresourceFilterDriverFactoryThreatTypeTest,
- ActivateForTheListType) {
- // Sets up the experiment in a way that the activation decision depends on the
- // list for which the Safe Browsing hit has happened.
- const ActivationListTestData& test_data = GetParam();
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeActivationList, test_data.activation_list);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
-
- const GURL test_url("https://example.com/nonsoceng?q=engsocnon");
- std::vector<GURL> navigation_chain;
-
- ActivationList effective_list = GetListForThreatTypeAndMetadata(
- test_data.threat_type, test_data.threat_type_metadata);
- NavigateAndExpectActivation(
- {false, false, false, true},
- {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC), test_url}, test_data.threat_type,
- test_data.threat_type_metadata, content::Referrer(),
- ui::PAGE_TRANSITION_LINK,
- effective_list != ActivationList::NONE ? F0M0L1 : EMPTY,
- test_data.expected_activation_decision);
-};
-
-TEST_P(ContentSubresourceFilterDriverFactoryActivationScopeTest,
- ActivateForScopeType) {
- const ActivationScopeTestData& test_data = GetParam();
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- test_data.activation_scope,
- kActivationListSocialEngineeringAdsInterstitial);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
-
- const GURL test_url(kExampleUrlWithParams);
-
- RedirectChainMatchPattern expected_pattern =
- test_data.url_matches_activation_list ? NO_REDIRECTS_HIT : EMPTY;
- NavigateAndExpectActivation({test_data.url_matches_activation_list},
- {test_url}, expected_pattern,
- test_data.expected_activation_decision);
- if (test_data.url_matches_activation_list) {
- factory()->AddHostOfURLToWhitelistSet(test_url);
- NavigateAndExpectActivation(
- {test_data.url_matches_activation_list}, {GURL(kExampleUrlWithParams)},
- expected_pattern,
- GetActiveConfiguration().activation_scope == ActivationScope::NO_SITES
- ? ActivationDecision::ACTIVATION_DISABLED
- : ActivationDecision::URL_WHITELISTED);
- }
-};
-
-// Only main frames with http/https schemes should activate, unless the
-// activation scope is for all sites.
-TEST_P(ContentSubresourceFilterDriverFactoryActivationScopeTest,
- ActivateForSupportedUrlScheme) {
- const ActivationScopeTestData& test_data = GetParam();
- base::FieldTrialList field_trial_list(nullptr);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- test_data.activation_scope,
- kActivationListSocialEngineeringAdsInterstitial);
- factory()->set_configuration_for_testing(GetActiveConfiguration());
-
- // data URLs are also not supported, but not listed here, as it's not possible
- // for a page to redirect to them after https://crbug.com/594215 is fixed.
- const char* unsupported_urls[] = {"ftp://example.com/", "chrome://settings",
- "chrome-extension://some-extension",
- "file:///var/www/index.html"};
- const char* supported_urls[] = {"http://example.test",
- "https://example.test"};
- for (auto* url : unsupported_urls) {
- SCOPED_TRACE(url);
- RedirectChainMatchPattern expected_pattern = EMPTY;
- NavigateAndExpectActivation(
- {test_data.url_matches_activation_list}, {GURL(url)}, expected_pattern,
- GetActiveConfiguration().activation_scope == ActivationScope::NO_SITES
- ? ActivationDecision::ACTIVATION_DISABLED
- : ActivationDecision::UNSUPPORTED_SCHEME);
- }
- for (auto* url : supported_urls) {
- SCOPED_TRACE(url);
- RedirectChainMatchPattern expected_pattern =
- test_data.url_matches_activation_list ? NO_REDIRECTS_HIT : EMPTY;
- NavigateAndExpectActivation({test_data.url_matches_activation_list},
- {GURL(url)}, expected_pattern,
- test_data.expected_activation_decision);
- }
-};
-
-INSTANTIATE_TEST_CASE_P(NoSocEngHit,
- ContentSubresourceFilterDriverFactoryThreatTypeTest,
- ::testing::ValuesIn(kActivationListTestData));
-
-INSTANTIATE_TEST_CASE_P(
- ActivationScopeTest,
- ContentSubresourceFilterDriverFactoryActivationScopeTest,
- ::testing::ValuesIn(kActivationScopeTestData));
-
-INSTANTIATE_TEST_CASE_P(
- ActivationLevelTest,
- ContentSubresourceFilterDriverFactoryActivationLevelTest,
- ::testing::ValuesIn(kActivationLevelTestData));
-
-} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
index eed2e727071..bf71456cf28 100644
--- a/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
+++ b/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -4,77 +4,51 @@
#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
#include "components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter.h"
+#include "components/subresource_filter/content/browser/page_load_statistics.h"
#include "components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h"
+#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
#include "components/subresource_filter/content/common/subresource_filter_messages.h"
+#include "components/subresource_filter/core/browser/subresource_filter_constants.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/console_message_level.h"
#include "net/base/net_errors.h"
namespace subresource_filter {
-namespace {
-
-// Used to forward calls to WillProcessResonse to the driver.
-// TODO(https://crbug.com/708181): Remove this once the safe browsing navigation
-// throttle is responsible for all activation decisions.
-class ForwardingNavigationThrottle : public content::NavigationThrottle {
- public:
- ForwardingNavigationThrottle(
- content::NavigationHandle* handle,
- ContentSubresourceFilterThrottleManager::Delegate* delegate)
- : content::NavigationThrottle(handle), delegate_(delegate) {}
- ~ForwardingNavigationThrottle() override {}
-
- // content::NavigationThrottle:
- content::NavigationThrottle::ThrottleCheckResult WillProcessResponse()
- override {
- delegate_->WillProcessResponse(navigation_handle());
- return content::NavigationThrottle::PROCEED;
- }
-
- private:
- ContentSubresourceFilterThrottleManager::Delegate* delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(ForwardingNavigationThrottle);
-};
-
-} // namespace
-
-bool ContentSubresourceFilterThrottleManager::Delegate::
- ShouldSuppressActivation(content::NavigationHandle* navigation_handle) {
- return false;
-}
-
ContentSubresourceFilterThrottleManager::
ContentSubresourceFilterThrottleManager(
Delegate* delegate,
VerifiedRulesetDealer::Handle* dealer_handle,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
+ scoped_observer_(this),
dealer_handle_(dealer_handle),
delegate_(delegate),
- weak_ptr_factory_(this) {}
+ weak_ptr_factory_(this) {
+ SubresourceFilterObserverManager::CreateForWebContents(web_contents);
+ scoped_observer_.Add(
+ SubresourceFilterObserverManager::FromWebContents(web_contents));
+}
ContentSubresourceFilterThrottleManager::
~ContentSubresourceFilterThrottleManager() {}
-void ContentSubresourceFilterThrottleManager::NotifyPageActivationComputed(
- content::NavigationHandle* navigation_handle,
- const ActivationState& activation_state) {
- DCHECK(navigation_handle->IsInMainFrame());
- DCHECK(!navigation_handle->HasCommitted());
- auto it = ongoing_activation_throttles_.find(navigation_handle);
- if (it != ongoing_activation_throttles_.end()) {
- it->second->NotifyPageActivationWithRuleset(EnsureRulesetHandle(),
- activation_state);
- }
+void ContentSubresourceFilterThrottleManager::OnSubresourceFilterGoingAway() {
+ // Stop observing here because the observer manager could be destroyed by the
+ // time this class is destroyed.
+ scoped_observer_.RemoveAll();
}
void ContentSubresourceFilterThrottleManager::RenderFrameDeleted(
@@ -96,11 +70,15 @@ void ContentSubresourceFilterThrottleManager::ReadyToCommitNavigation(
AsyncDocumentSubresourceFilter* filter = throttle->second->filter();
if (!filter || navigation_handle->GetNetErrorCode() != net::OK ||
filter->activation_state().activation_level ==
- ActivationLevel::DISABLED ||
- delegate_->ShouldSuppressActivation(navigation_handle)) {
+ ActivationLevel::DISABLED) {
return;
}
+ TRACE_EVENT1(
+ TRACE_DISABLED_BY_DEFAULT("loading"),
+ "ContentSubresourceFilterThrottleManager::ReadyToCommitNavigation",
+ "activation_state", filter->activation_state().ToTracedValue());
+
throttle->second->WillSendActivationToRenderer();
content::RenderFrameHost* frame_host =
@@ -126,10 +104,25 @@ void ContentSubresourceFilterThrottleManager::DidFinishNavigation(
ongoing_activation_throttles_.erase(throttle);
}
- // Make sure |activated_frame_hosts_| is updated or cleaned up depending on
- // this navigation's activation state.
content::RenderFrameHost* frame_host =
navigation_handle->GetRenderFrameHost();
+ if (navigation_handle->IsInMainFrame()) {
+ current_committed_load_has_notified_disallowed_load_ = false;
+ statistics_.reset();
+ if (filter) {
+ statistics_ =
+ base::MakeUnique<PageLoadStatistics>(filter->activation_state());
+ if (filter->activation_state().enable_logging) {
+ DCHECK(filter->activation_state().activation_level !=
+ ActivationLevel::DISABLED);
+ frame_host->AddMessageToConsole(content::CONSOLE_MESSAGE_LEVEL_WARNING,
+ kActivationConsoleMessage);
+ }
+ }
+ }
+
+ // Make sure |activated_frame_hosts_| is updated or cleaned up depending on
+ // this navigation's activation state.
if (filter) {
filter->set_first_disallowed_load_callback(base::Bind(
&ContentSubresourceFilterThrottleManager::MaybeCallFirstDisallowedLoad,
@@ -138,12 +131,17 @@ void ContentSubresourceFilterThrottleManager::DidFinishNavigation(
} else {
activated_frame_hosts_.erase(frame_host);
}
-
- if (navigation_handle->IsInMainFrame())
- current_committed_load_has_notified_disallowed_load_ = false;
DestroyRulesetHandleIfNoLongerUsed();
}
+void ContentSubresourceFilterThrottleManager::DidFinishLoad(
+ content::RenderFrameHost* render_frame_host,
+ const GURL& validated_url) {
+ if (!statistics_ || render_frame_host->GetParent())
+ return;
+ statistics_->OnDidFinishLoad();
+}
+
bool ContentSubresourceFilterThrottleManager::OnMessageReceived(
const IPC::Message& message,
content::RenderFrameHost* render_frame_host) {
@@ -151,19 +149,37 @@ bool ContentSubresourceFilterThrottleManager::OnMessageReceived(
IPC_BEGIN_MESSAGE_MAP(ContentSubresourceFilterThrottleManager, message)
IPC_MESSAGE_HANDLER(SubresourceFilterHostMsg_DidDisallowFirstSubresource,
MaybeCallFirstDisallowedLoad)
+ IPC_MESSAGE_HANDLER(SubresourceFilterHostMsg_DocumentLoadStatistics,
+ OnDocumentLoadStatistics)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
+// Sets the desired page-level |activation_state| for the currently ongoing
+// page load, identified by its main-frame |navigation_handle|. If this method
+// is not called for a main-frame navigation, the default behavior is no
+// activation for that page load.
+void ContentSubresourceFilterThrottleManager::OnPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ ActivationDecision activation_decision,
+ const ActivationState& activation_state) {
+ DCHECK(navigation_handle->IsInMainFrame());
+ DCHECK(!navigation_handle->HasCommitted());
+ // Do not notify the throttle if activation is disabled.
+ if (activation_state.activation_level == ActivationLevel::DISABLED)
+ return;
+ auto it = ongoing_activation_throttles_.find(navigation_handle);
+ if (it != ongoing_activation_throttles_.end()) {
+ it->second->NotifyPageActivationWithRuleset(EnsureRulesetHandle(),
+ activation_state);
+ }
+}
+
void ContentSubresourceFilterThrottleManager::MaybeAppendNavigationThrottles(
content::NavigationHandle* navigation_handle,
std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) {
DCHECK(!navigation_handle->IsSameDocument());
- if (navigation_handle->IsInMainFrame()) {
- throttles->push_back(base::MakeUnique<ForwardingNavigationThrottle>(
- navigation_handle, delegate_));
- }
if (!dealer_handle_)
return;
if (auto filtering_throttle =
@@ -178,6 +194,18 @@ void ContentSubresourceFilterThrottleManager::MaybeAppendNavigationThrottles(
}
}
+bool ContentSubresourceFilterThrottleManager::ShouldDisallowNewWindow() {
+ auto it = activated_frame_hosts_.find(web_contents()->GetMainFrame());
+ if (it == activated_frame_hosts_.end())
+ return false;
+ const ActivationState state = it->second->activation_state();
+ // This should trigger the standard popup blocking UI, so don't force the
+ // subresource filter specific UI here.
+ return state.activation_level == ActivationLevel::ENABLED &&
+ !state.filtering_disabled_for_document &&
+ !state.generic_blocking_rules_disabled;
+}
+
std::unique_ptr<SubframeNavigationFilteringThrottle>
ContentSubresourceFilterThrottleManager::
MaybeCreateSubframeNavigationFilteringThrottle(
@@ -216,8 +244,7 @@ AsyncDocumentSubresourceFilter*
ContentSubresourceFilterThrottleManager::GetParentFrameFilter(
content::NavigationHandle* child_frame_navigation) {
DCHECK(!child_frame_navigation->IsInMainFrame());
- content::RenderFrameHost* parent = web_contents()->FindFrameByFrameTreeNodeId(
- child_frame_navigation->GetParentFrameTreeNodeId());
+ content::RenderFrameHost* parent = child_frame_navigation->GetParentFrame();
DCHECK(parent);
auto it = activated_frame_hosts_.find(parent);
return it == activated_frame_hosts_.end() ? nullptr : it->second.get();
@@ -245,4 +272,10 @@ void ContentSubresourceFilterThrottleManager::
}
}
+void ContentSubresourceFilterThrottleManager::OnDocumentLoadStatistics(
+ const DocumentLoadStatistics& statistics) {
+ if (statistics_)
+ statistics_->OnDocumentLoadStatistics(statistics);
+}
+
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h b/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
index e113c3cc890..4240c57946b 100644
--- a/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
+++ b/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h
@@ -11,7 +11,10 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
+#include "components/subresource_filter/content/browser/subresource_filter_observer.h"
#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
+#include "components/subresource_filter/core/common/activation_decision.h"
#include "components/subresource_filter/core/common/activation_state.h"
#include "content/public/browser/web_contents_observer.h"
@@ -30,6 +33,9 @@ namespace subresource_filter {
class AsyncDocumentSubresourceFilter;
class ActivationStateComputingNavigationThrottle;
class SubframeNavigationFilteringThrottle;
+class SubresourceFilterObserverManager;
+class PageLoadStatistics;
+struct DocumentLoadStatistics;
// The ContentSubresourceFilterThrottleManager manages NavigationThrottles in
// order to calculate frame activation states and subframe navigation filtering,
@@ -41,7 +47,8 @@ class SubframeNavigationFilteringThrottle;
// will be notified of the first disallowed subresource load for a top level
// navgation, and has veto power for frame activation.
class ContentSubresourceFilterThrottleManager
- : public content::WebContentsObserver {
+ : public content::WebContentsObserver,
+ public SubresourceFilterObserver {
public:
// It is expected that the Delegate outlives |this|, and manages the lifetime
// of this class.
@@ -50,15 +57,6 @@ class ContentSubresourceFilterThrottleManager
// The embedder may be interested in displaying UI to the user when the
// first load is disallowed for a given page load.
virtual void OnFirstSubresourceLoadDisallowed() {}
-
- // Let the delegate have the last word when it comes to activation. It might
- // have a specific whitelist.
- virtual bool ShouldSuppressActivation(
- content::NavigationHandle* navigation_handle);
-
- // Temporary method to help the delegate compute the activation decision.
- virtual void WillProcessResponse(
- content::NavigationHandle* navigation_handle) {}
};
ContentSubresourceFilterThrottleManager(
@@ -67,17 +65,6 @@ class ContentSubresourceFilterThrottleManager
content::WebContents* web_contents);
~ContentSubresourceFilterThrottleManager() override;
- // Sets the desired page-level |activation_state| for the currently ongoing
- // page load, identified by its main-frame |navigation_handle|. To be called
- // by the embedder at the latest in the WillProcessResponse stage from a
- // NavigationThrottle that was registered before the throttles created by this
- // manager in MaybeAppendNavigationThrottles(). If this method is not called
- // for a main-frame navigation, the default behavior is no activation for that
- // page load.
- void NotifyPageActivationComputed(
- content::NavigationHandle* navigation_handle,
- const ActivationState& activation_state);
-
// This method inspects |navigation_handle| and attaches navigation throttles
// appropriately, based on the current state of frame activation.
//
@@ -91,6 +78,10 @@ class ContentSubresourceFilterThrottleManager
content::NavigationHandle* navigation_handle,
std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles);
+ // Returns whether or not the current WebContents is allowed to create a new
+ // window.
+ bool ShouldDisallowNewWindow();
+
VerifiedRuleset::Handle* ruleset_handle_for_testing() {
return ruleset_handle_.get();
}
@@ -102,9 +93,18 @@ class ContentSubresourceFilterThrottleManager
content::NavigationHandle* navigation_handle) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
+ void DidFinishLoad(content::RenderFrameHost* render_frame_host,
+ const GURL& validated_url) override;
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* render_frame_host) override;
+ // SubresourceFilterObserver:
+ void OnSubresourceFilterGoingAway() override;
+ void OnPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ ActivationDecision activation_decision,
+ const ActivationState& activation_state) override;
+
private:
std::unique_ptr<SubframeNavigationFilteringThrottle>
MaybeCreateSubframeNavigationFilteringThrottle(
@@ -120,13 +120,13 @@ class ContentSubresourceFilterThrottleManager
// Calls OnFirstSubresourceLoadDisallowed on the Delegate at most once per
// committed, non-same-page navigation in the main frame.
- // TODO(csharrison): Ensure IPCs from the renderer go through this path when
- // they disallow subresource loads.
void MaybeCallFirstDisallowedLoad();
VerifiedRuleset::Handle* EnsureRulesetHandle();
void DestroyRulesetHandleIfNoLongerUsed();
+ void OnDocumentLoadStatistics(const DocumentLoadStatistics& statistics);
+
// For each RenderFrameHost where the last committed load has subresource
// filtering activated, owns the corresponding AsyncDocumentSubresourceFilter.
std::unordered_map<content::RenderFrameHost*,
@@ -140,11 +140,16 @@ class ContentSubresourceFilterThrottleManager
ActivationStateComputingNavigationThrottle*>
ongoing_activation_throttles_;
+ ScopedObserver<SubresourceFilterObserverManager, SubresourceFilterObserver>
+ scoped_observer_;
+
// Lazily instantiated in EnsureRulesetHandle when the first page level
// activation is triggered. Will go away when there are no more activated
// RenderFrameHosts (i.e. activated_frame_hosts_ is empty).
std::unique_ptr<VerifiedRuleset::Handle> ruleset_handle_;
+ std::unique_ptr<PageLoadStatistics> statistics_;
+
// True if the current committed main frame load in this WebContents has
// notified the delegate that a subresource was disallowed. The callback
// should only be called at most once per main frame load.
diff --git a/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc b/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
index 6c988fb4e82..fbd140e28ba 100644
--- a/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
+++ b/chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
@@ -4,15 +4,19 @@
#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
+#include <map>
#include <memory>
+#include <tuple>
#include <utility>
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/test_simple_task_runner.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter.h"
+#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
#include "components/subresource_filter/content/common/subresource_filter_messages.h"
#include "components/subresource_filter/core/common/activation_level.h"
#include "components/subresource_filter/core/common/activation_state.h"
@@ -22,6 +26,7 @@
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
@@ -35,6 +40,8 @@ const char kTestURLWithActivation[] = "https://www.page-with-activation.com/";
const char kTestURLWithActivation2[] =
"https://www.page-with-activation-2.com/";
const char kTestURLWithDryRun[] = "https://www.page-with-dryrun.com/";
+const char kTestURLWithNoActivation[] =
+ "https://www.page-without-activation.com/";
// Enum determining when the mock page state throttle notifies the throttle
// manager of page level activation state.
@@ -49,11 +56,9 @@ class MockPageStateActivationThrottle : public content::NavigationThrottle {
public:
MockPageStateActivationThrottle(
content::NavigationHandle* navigation_handle,
- PageActivationNotificationTiming activation_throttle_state,
- ContentSubresourceFilterThrottleManager* throttle_manager)
+ PageActivationNotificationTiming activation_throttle_state)
: content::NavigationThrottle(navigation_handle),
- activation_throttle_state_(activation_throttle_state),
- throttle_manager_(throttle_manager) {
+ activation_throttle_state_(activation_throttle_state) {
// Add some default activations.
mock_page_activations_[GURL(kTestURLWithActivation)] =
ActivationState(ActivationLevel::ENABLED);
@@ -61,6 +66,8 @@ class MockPageStateActivationThrottle : public content::NavigationThrottle {
ActivationState(ActivationLevel::ENABLED);
mock_page_activations_[GURL(kTestURLWithDryRun)] =
ActivationState(ActivationLevel::DRYRUN);
+ mock_page_activations_[GURL(kTestURLWithNoActivation)] =
+ ActivationState(ActivationLevel::DISABLED);
}
~MockPageStateActivationThrottle() override {}
@@ -73,6 +80,9 @@ class MockPageStateActivationThrottle : public content::NavigationThrottle {
override {
return MaybeNotifyActivation(WILL_PROCESS_RESPONSE);
}
+ const char* GetNameForLogging() override {
+ return "MockPageStateActivationThrottle";
+ }
private:
content::NavigationThrottle::ThrottleCheckResult MaybeNotifyActivation(
@@ -80,8 +90,11 @@ class MockPageStateActivationThrottle : public content::NavigationThrottle {
if (throttle_state == activation_throttle_state_) {
auto it = mock_page_activations_.find(navigation_handle()->GetURL());
if (it != mock_page_activations_.end()) {
- throttle_manager_->NotifyPageActivationComputed(navigation_handle(),
- it->second);
+ // The throttle manager does not use the activation decision.
+ SubresourceFilterObserverManager::FromWebContents(
+ navigation_handle()->GetWebContents())
+ ->NotifyPageActivationComputed(
+ navigation_handle(), ActivationDecision::UNKNOWN, it->second);
}
}
return content::NavigationThrottle::PROCEED;
@@ -89,7 +102,6 @@ class MockPageStateActivationThrottle : public content::NavigationThrottle {
std::map<GURL, ActivationState> mock_page_activations_;
PageActivationNotificationTiming activation_throttle_state_;
- ContentSubresourceFilterThrottleManager* throttle_manager_;
DISALLOW_COPY_AND_ASSIGN(MockPageStateActivationThrottle);
};
@@ -232,18 +244,12 @@ class ContentSubresourceFilterThrottleManagerTest
SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED);
}
- void SuppressActivationForUrl(const GURL& url) {
- urls_to_suppress_activation_.insert(url);
- }
-
bool ManagerHasRulesetHandle() {
return throttle_manager_->ruleset_handle_for_testing();
}
int disallowed_notification_count() { return disallowed_notification_count_; }
- int attempted_frame_activations() { return attempted_frame_activations_; }
-
protected:
// content::WebContentsObserver
void DidStartNavigation(
@@ -258,7 +264,7 @@ class ContentSubresourceFilterThrottleManagerTest
? GetParam()
: WILL_PROCESS_RESPONSE;
throttles.push_back(base::MakeUnique<MockPageStateActivationThrottle>(
- navigation_handle, state, throttle_manager_.get()));
+ navigation_handle, state));
throttle_manager_->MaybeAppendNavigationThrottles(navigation_handle,
&throttles);
for (auto& it : throttles) {
@@ -271,19 +277,10 @@ class ContentSubresourceFilterThrottleManagerTest
++disallowed_notification_count_;
}
- bool ShouldSuppressActivation(
- content::NavigationHandle* navigation_handle) override {
- ++attempted_frame_activations_;
- return urls_to_suppress_activation_.find(navigation_handle->GetURL()) !=
- urls_to_suppress_activation_.end();
- }
-
private:
testing::TestRulesetCreator test_ruleset_creator_;
testing::TestRulesetPair test_ruleset_pair_;
- std::set<GURL> urls_to_suppress_activation_;
-
std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_;
std::unique_ptr<ContentSubresourceFilterThrottleManager> throttle_manager_;
@@ -293,10 +290,6 @@ class ContentSubresourceFilterThrottleManagerTest
// Incremented on every OnFirstSubresourceLoadDisallowed call.
int disallowed_notification_count_ = 0;
- // Incremented every time the manager queries the harness for activation
- // suppression.
- int attempted_frame_activations_ = 0;
-
DISALLOW_COPY_AND_ASSIGN(ContentSubresourceFilterThrottleManagerTest);
};
@@ -314,10 +307,24 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
// A disallowed subframe navigation should be successfully filtered.
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
+}
+
+TEST_P(ContentSubresourceFilterThrottleManagerTest, NoPageActivation) {
+ // Commit a navigation that triggers page level activation.
+ NavigateAndCommitMainFrame(GURL(kTestURLWithNoActivation));
+ ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
+ EXPECT_FALSE(ManagerHasRulesetHandle());
+
+ // A disallowed subframe navigation should not be filtered.
+ CreateSubframeWithTestNavigation(
+ GURL("https://www.example.com/disallowed.html"), main_rfh());
+ SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED);
+
+ EXPECT_EQ(0, disallowed_notification_count());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
@@ -336,7 +343,6 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
ExpectActivationSignalForFrame(child, true /* expect_activation */);
EXPECT_EQ(0, disallowed_notification_count());
- EXPECT_EQ(2, attempted_frame_activations());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
@@ -350,12 +356,14 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/before-redirect.html"), main_rfh());
SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
+ content::NavigationThrottle::ThrottleCheckResult expected_result =
+ content::IsBrowserSideNavigationEnabled()
+ ? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
+ : content::NavigationThrottle::CANCEL;
SimulateRedirectAndExpectResult(
- GURL("https://www.example.com/disallowed.html"),
- content::NavigationThrottle::CANCEL);
+ GURL("https://www.example.com/disallowed.html"), expected_result);
EXPECT_EQ(1, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
@@ -375,7 +383,6 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
ExpectActivationSignalForFrame(child, true /* expect_activation */);
EXPECT_EQ(0, disallowed_notification_count());
- EXPECT_EQ(2, attempted_frame_activations());
}
// This should fail if the throttle manager notifies the delegate twice of a
@@ -389,16 +396,17 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
// A disallowed subframe navigation should be successfully filtered.
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/1/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/2/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
@@ -410,7 +418,8 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
// A disallowed subframe navigation should be successfully filtered.
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/1/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
@@ -420,10 +429,10 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/2/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(2, disallowed_notification_count());
- EXPECT_EQ(2, attempted_frame_activations());
}
// Test that the disallow load notification will not be repeated for the first
@@ -437,7 +446,8 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
// A disallowed subframe navigation should be successfully filtered.
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/1/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
@@ -449,10 +459,10 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/2/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
@@ -469,24 +479,6 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
ExpectActivationSignalForFrame(child, false /* expect_activation */);
EXPECT_EQ(0, disallowed_notification_count());
- EXPECT_EQ(0, attempted_frame_activations());
-}
-
-TEST_P(ContentSubresourceFilterThrottleManagerTest, SuppressActivation) {
- SuppressActivationForUrl(GURL(kTestURLWithActivation));
- NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
- ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
-
- // A subframe navigation should complete successfully.
- CreateSubframeWithTestNavigation(GURL("https://www.example.com/allowed.html"),
- main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
- content::RenderFrameHost* child =
- SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED);
- ExpectActivationSignalForFrame(child, false /* expect_activation */);
-
- EXPECT_EQ(0, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
// Once there are no activated frames, the manager drops its ruleset handle. If
@@ -497,7 +489,8 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest, RulesetHandleRegeneration) {
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
@@ -512,17 +505,16 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest, RulesetHandleRegeneration) {
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(2, disallowed_notification_count());
- EXPECT_EQ(2, attempted_frame_activations());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
SameSiteNavigation_RulesetGoesAway) {
GURL same_site_inactive_url =
- GURL(base::StringPrintf("%ssuppressed.html", kTestURLWithActivation));
- SuppressActivationForUrl(same_site_inactive_url);
+ GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation));
NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
@@ -541,7 +533,6 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
ExpectActivationSignalForFrame(child, false /* expect_activation */);
EXPECT_EQ(0, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
@@ -551,8 +542,7 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
EXPECT_TRUE(ManagerHasRulesetHandle());
GURL same_site_inactive_url =
- GURL(base::StringPrintf("%ssuppressed.html", kTestURLWithActivation));
- SuppressActivationForUrl(same_site_inactive_url);
+ GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation));
CreateTestNavigation(same_site_inactive_url, main_rfh());
SimulateFailedNavigation(net::ERR_ABORTED);
@@ -562,10 +552,10 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
// A subframe navigation fail.
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
TEST_P(ContentSubresourceFilterThrottleManagerTest,
@@ -575,8 +565,7 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
EXPECT_TRUE(ManagerHasRulesetHandle());
GURL same_site_inactive_url =
- GURL(base::StringPrintf("%ssuppressed.html", kTestURLWithActivation));
- SuppressActivationForUrl(same_site_inactive_url);
+ GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation));
CreateTestNavigation(same_site_inactive_url, main_rfh());
SimulateFailedNavigation(net::ERR_FAILED);
@@ -591,7 +580,6 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
ExpectActivationSignalForFrame(child, false /* expect_activation */);
EXPECT_EQ(0, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
// Ensure activation propagates into great-grandchild frames, including cross
@@ -621,10 +609,10 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest, ActivationPropagation) {
// A final, nested subframe navigation is filtered.
CreateSubframeWithTestNavigation(GURL("https://www.c.com/disallowed.html"),
subframe2);
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
EXPECT_EQ(1, disallowed_notification_count());
- EXPECT_EQ(3, attempted_frame_activations());
}
// Ensure activation propagates through whitelisted documents.
@@ -647,7 +635,6 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest, ActivationPropagation2) {
SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED);
ExpectActivationSignalForFrame(subframe2, true /* expect_activation */);
- EXPECT_EQ(3, attempted_frame_activations());
EXPECT_EQ(0, disallowed_notification_count());
// An identical series of events that don't match whitelist rules cause
@@ -661,9 +648,9 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest, ActivationPropagation2) {
// Navigate a sub-subframe that is not filtered due to the whitelist.
CreateSubframeWithTestNavigation(
GURL("https://www.example.com/disallowed.html"), subframe3);
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
- EXPECT_EQ(4, attempted_frame_activations());
EXPECT_EQ(1, disallowed_notification_count());
}
@@ -672,13 +659,11 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
SameSiteNavigationStopsActivation) {
NavigateAndCommitMainFrame(GURL(kTestURLWithActivation));
ExpectActivationSignalForFrame(main_rfh(), true /* expect_activation */);
- EXPECT_EQ(1, attempted_frame_activations());
// Mock a same-site navigation, in the same RFH, this URL does not trigger
// page level activation.
NavigateAndCommitMainFrame(
GURL(base::StringPrintf("%s/some_path/", kTestURLWithActivation)));
- EXPECT_EQ(1, attempted_frame_activations());
ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */);
CreateSubframeWithTestNavigation(
@@ -689,7 +674,6 @@ TEST_P(ContentSubresourceFilterThrottleManagerTest,
ExpectActivationSignalForFrame(child, false /* expect_activation */);
EXPECT_EQ(0, disallowed_notification_count());
- EXPECT_EQ(1, attempted_frame_activations());
}
// TODO(csharrison): Make sure the following conditions are exercised in tests:
diff --git a/chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc b/chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc
new file mode 100644
index 00000000000..6ac5a136c8c
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.cc
@@ -0,0 +1,102 @@
+// Copyright 2017 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/subresource_filter/content/browser/fake_safe_browsing_database_manager.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "content/public/browser/browser_thread.h"
+#include "url/gurl.h"
+
+FakeSafeBrowsingDatabaseManager::FakeSafeBrowsingDatabaseManager()
+ : simulate_timeout_(false) {}
+
+void FakeSafeBrowsingDatabaseManager::AddBlacklistedUrl(
+ const GURL& url,
+ safe_browsing::SBThreatType threat_type,
+ safe_browsing::ThreatPatternType pattern_type) {
+ url_to_threat_type_[url] = std::make_pair(threat_type, pattern_type);
+}
+
+void FakeSafeBrowsingDatabaseManager::RemoveBlacklistedUrl(const GURL& url) {
+ url_to_threat_type_.erase(url);
+}
+
+void FakeSafeBrowsingDatabaseManager::RemoveAllBlacklistedUrls() {
+ DCHECK(checks_.empty());
+ url_to_threat_type_.clear();
+}
+
+void FakeSafeBrowsingDatabaseManager::SimulateTimeout() {
+ simulate_timeout_ = true;
+}
+
+FakeSafeBrowsingDatabaseManager::~FakeSafeBrowsingDatabaseManager() {}
+
+bool FakeSafeBrowsingDatabaseManager::CheckUrlForSubresourceFilter(
+ const GURL& url,
+ Client* client) {
+ if (simulate_timeout_)
+ return false;
+ if (!url_to_threat_type_.count(url))
+ return true;
+
+ // Enforce the invariant that a client will not send multiple requests, with
+ // the subresource filter client implementation.
+ DCHECK(checks_.find(client) == checks_.end());
+ checks_.insert(client);
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&FakeSafeBrowsingDatabaseManager::
+ OnCheckUrlForSubresourceFilterComplete,
+ base::Unretained(this), base::Unretained(client), url));
+ return false;
+}
+
+void FakeSafeBrowsingDatabaseManager::OnCheckUrlForSubresourceFilterComplete(
+ Client* client,
+ const GURL& url) {
+ // Check to see if the request was cancelled to avoid use-after-free.
+ if (checks_.find(client) == checks_.end())
+ return;
+ safe_browsing::ThreatMetadata metadata;
+ metadata.threat_pattern_type = url_to_threat_type_[url].second;
+
+ client->OnCheckBrowseUrlResult(url, url_to_threat_type_[url].first, metadata);
+ // Erase the client when a check is complete. Otherwise, it's possible
+ // subsequent clients that share an address with this one will DCHECK in
+ // CheckUrlForSubresourceFilter.
+ checks_.erase(client);
+}
+
+bool FakeSafeBrowsingDatabaseManager::CheckResourceUrl(const GURL& url,
+ Client* client) {
+ return true;
+}
+
+bool FakeSafeBrowsingDatabaseManager::IsSupported() const {
+ return true;
+}
+bool FakeSafeBrowsingDatabaseManager::ChecksAreAlwaysAsync() const {
+ return false;
+}
+void FakeSafeBrowsingDatabaseManager::CancelCheck(Client* client) {
+ checks_.erase(client);
+}
+bool FakeSafeBrowsingDatabaseManager::CanCheckResourceType(
+ content::ResourceType /* resource_type */) const {
+ return true;
+}
+
+safe_browsing::ThreatSource FakeSafeBrowsingDatabaseManager::GetThreatSource()
+ const {
+ return safe_browsing::ThreatSource::LOCAL_PVER4;
+}
+
+bool FakeSafeBrowsingDatabaseManager::CheckExtensionIDs(
+ const std::set<std::string>& extension_ids,
+ Client* client) {
+ return true;
+}
diff --git a/chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h b/chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h
new file mode 100644
index 00000000000..ba2f9c7e348
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h
@@ -0,0 +1,61 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CONTENT_BROWSER_FAKE_SAFE_BROWSING_DATABASE_MANAGER_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_FAKE_SAFE_BROWSING_DATABASE_MANAGER_H_
+
+#include <map>
+#include <set>
+
+#include "base/macros.h"
+#include "components/safe_browsing_db/test_database_manager.h"
+#include "content/public/common/resource_type.h"
+
+class GURL;
+
+// Database manager that allows any URL to be configured as blacklisted for
+// testing.
+class FakeSafeBrowsingDatabaseManager
+ : public safe_browsing::TestSafeBrowsingDatabaseManager {
+ public:
+ FakeSafeBrowsingDatabaseManager();
+
+ void AddBlacklistedUrl(const GURL& url,
+ safe_browsing::SBThreatType threat_type,
+ safe_browsing::ThreatPatternType pattern_type =
+ safe_browsing::ThreatPatternType::NONE);
+ void RemoveBlacklistedUrl(const GURL& url);
+ void RemoveAllBlacklistedUrls();
+
+ void SimulateTimeout();
+
+ protected:
+ ~FakeSafeBrowsingDatabaseManager() override;
+
+ // safe_browsing::TestSafeBrowsingDatabaseManager:
+ bool CheckUrlForSubresourceFilter(const GURL& url, Client* client) override;
+ bool CheckResourceUrl(const GURL& url, Client* client) override;
+ bool IsSupported() const override;
+ void CancelCheck(Client* client) override;
+ bool ChecksAreAlwaysAsync() const override;
+ bool CanCheckResourceType(
+ content::ResourceType /* resource_type */) const override;
+ safe_browsing::ThreatSource GetThreatSource() const override;
+ bool CheckExtensionIDs(const std::set<std::string>& extension_ids,
+ Client* client) override;
+
+ private:
+ void OnCheckUrlForSubresourceFilterComplete(Client* client, const GURL& url);
+
+ std::set<Client*> checks_;
+ std::map<
+ GURL,
+ std::pair<safe_browsing::SBThreatType, safe_browsing::ThreatPatternType>>
+ url_to_threat_type_;
+ bool simulate_timeout_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
+};
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_FAKE_SAFE_BROWSING_DATABASE_MANAGER_H_
diff --git a/chromium/components/subresource_filter/content/browser/page_load_statistics.cc b/chromium/components/subresource_filter/content/browser/page_load_statistics.cc
new file mode 100644
index 00000000000..6d9f749585d
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/page_load_statistics.cc
@@ -0,0 +1,71 @@
+// Copyright 2017 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/subresource_filter/content/browser/page_load_statistics.h"
+
+#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
+#include "components/subresource_filter/core/common/time_measurements.h"
+
+namespace subresource_filter {
+
+PageLoadStatistics::PageLoadStatistics(const ActivationState& state)
+ : activation_state_(state) {}
+
+PageLoadStatistics::~PageLoadStatistics() = default;
+
+void PageLoadStatistics::OnDocumentLoadStatistics(
+ const DocumentLoadStatistics& statistics) {
+ // Note: Chances of overflow are negligible.
+ aggregated_document_statistics_.num_loads_total += statistics.num_loads_total;
+ aggregated_document_statistics_.num_loads_evaluated +=
+ statistics.num_loads_evaluated;
+ aggregated_document_statistics_.num_loads_matching_rules +=
+ statistics.num_loads_matching_rules;
+ aggregated_document_statistics_.num_loads_disallowed +=
+ statistics.num_loads_disallowed;
+
+ aggregated_document_statistics_.evaluation_total_wall_duration +=
+ statistics.evaluation_total_wall_duration;
+ aggregated_document_statistics_.evaluation_total_cpu_duration +=
+ statistics.evaluation_total_cpu_duration;
+}
+
+void PageLoadStatistics::OnDidFinishLoad() {
+ if (activation_state_.activation_level != ActivationLevel::DISABLED) {
+ UMA_HISTOGRAM_COUNTS_1000(
+ "SubresourceFilter.PageLoad.NumSubresourceLoads.Total",
+ aggregated_document_statistics_.num_loads_total);
+ UMA_HISTOGRAM_COUNTS_1000(
+ "SubresourceFilter.PageLoad.NumSubresourceLoads.Evaluated",
+ aggregated_document_statistics_.num_loads_evaluated);
+ UMA_HISTOGRAM_COUNTS_1000(
+ "SubresourceFilter.PageLoad.NumSubresourceLoads.MatchedRules",
+ aggregated_document_statistics_.num_loads_matching_rules);
+ UMA_HISTOGRAM_COUNTS_1000(
+ "SubresourceFilter.PageLoad.NumSubresourceLoads.Disallowed",
+ aggregated_document_statistics_.num_loads_disallowed);
+ }
+
+ if (activation_state_.measure_performance) {
+ DCHECK(activation_state_.activation_level != ActivationLevel::DISABLED);
+ UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
+ "SubresourceFilter.PageLoad.SubresourceEvaluation.TotalWallDuration",
+ aggregated_document_statistics_.evaluation_total_wall_duration,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
+ 50);
+ UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
+ "SubresourceFilter.PageLoad.SubresourceEvaluation.TotalCPUDuration",
+ aggregated_document_statistics_.evaluation_total_cpu_duration,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
+ 50);
+ } else {
+ DCHECK(aggregated_document_statistics_.evaluation_total_wall_duration
+ .is_zero());
+ DCHECK(aggregated_document_statistics_.evaluation_total_cpu_duration
+ .is_zero());
+ }
+}
+
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/page_load_statistics.h b/chromium/components/subresource_filter/content/browser/page_load_statistics.h
new file mode 100644
index 00000000000..9666e240916
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/page_load_statistics.h
@@ -0,0 +1,37 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CONTENT_BROWSER_PAGE_LOAD_STATISTICS_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_PAGE_LOAD_STATISTICS_H_
+
+#include "base/macros.h"
+#include "components/subresource_filter/core/common/activation_state.h"
+#include "components/subresource_filter/core/common/document_load_statistics.h"
+
+namespace subresource_filter {
+
+// This class is notified of performance metrics recorded for individual
+// (sub-)documents of a page, aggregates them, and logs the aggregated metrics
+// to UMA histograms when the page load is complete (at the load event).
+class PageLoadStatistics {
+ public:
+ PageLoadStatistics(const ActivationState& state);
+ ~PageLoadStatistics();
+
+ void OnDocumentLoadStatistics(const DocumentLoadStatistics& statistics);
+ void OnDidFinishLoad();
+
+ private:
+ ActivationState activation_state_;
+
+ // Statistics about subresource loads, aggregated across all frames of the
+ // current page.
+ DocumentLoadStatistics aggregated_document_statistics_;
+
+ DISALLOW_COPY_AND_ASSIGN(PageLoadStatistics);
+};
+
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_PAGE_LOAD_STATISTICS_H_
diff --git a/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc b/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc
index 4fa61169d4b..8254f538d79 100644
--- a/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc
+++ b/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc
@@ -6,7 +6,10 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
+#include "components/subresource_filter/core/common/time_measurements.h"
#include "content/public/browser/navigation_handle.h"
+#include "content/public/common/browser_side_navigation_policy.h"
namespace subresource_filter {
@@ -20,35 +23,63 @@ SubframeNavigationFilteringThrottle::SubframeNavigationFilteringThrottle(
DCHECK(parent_frame_filter_);
}
-SubframeNavigationFilteringThrottle::~SubframeNavigationFilteringThrottle() {}
+SubframeNavigationFilteringThrottle::~SubframeNavigationFilteringThrottle() {
+ if (disallowed_) {
+ UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
+ "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Disallowed",
+ total_defer_time_, base::TimeDelta::FromMicroseconds(1),
+ base::TimeDelta::FromSeconds(10), 50);
+ } else {
+ UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(
+ "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Allowed",
+ total_defer_time_, base::TimeDelta::FromMicroseconds(1),
+ base::TimeDelta::FromSeconds(10), 50);
+ }
+}
content::NavigationThrottle::ThrottleCheckResult
SubframeNavigationFilteringThrottle::WillStartRequest() {
- return DeferToCalculateLoadPolicy();
+ return DeferToCalculateLoadPolicy(ThrottlingStage::WillStartRequest);
}
content::NavigationThrottle::ThrottleCheckResult
SubframeNavigationFilteringThrottle::WillRedirectRequest() {
- return DeferToCalculateLoadPolicy();
+ return DeferToCalculateLoadPolicy(ThrottlingStage::WillRedirectRequest);
+}
+
+const char* SubframeNavigationFilteringThrottle::GetNameForLogging() {
+ return "SubframeNavigationFilteringThrottle";
}
content::NavigationThrottle::ThrottleCheckResult
-SubframeNavigationFilteringThrottle::DeferToCalculateLoadPolicy() {
+SubframeNavigationFilteringThrottle::DeferToCalculateLoadPolicy(
+ ThrottlingStage stage) {
parent_frame_filter_->GetLoadPolicyForSubdocument(
navigation_handle()->GetURL(),
base::Bind(&SubframeNavigationFilteringThrottle::OnCalculatedLoadPolicy,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_ptr_factory_.GetWeakPtr(), stage));
+ last_defer_timestamp_ = base::TimeTicks::Now();
return content::NavigationThrottle::ThrottleCheckResult::DEFER;
}
void SubframeNavigationFilteringThrottle::OnCalculatedLoadPolicy(
+ ThrottlingStage stage,
LoadPolicy policy) {
+ DCHECK(!last_defer_timestamp_.is_null());
+ total_defer_time_ += base::TimeTicks::Now() - last_defer_timestamp_;
// TODO(csharrison): Support WouldDisallow pattern and expose the policy for
- // metrics. Also, cancel with BLOCK_AND_COLLAPSE when it is implemented.
+ // metrics.
if (policy == LoadPolicy::DISALLOW) {
+ disallowed_ = true;
parent_frame_filter_->ReportDisallowedLoad();
+
+ const bool block_and_collapse_is_supported =
+ content::IsBrowserSideNavigationEnabled() ||
+ stage == ThrottlingStage::WillStartRequest;
navigation_handle()->CancelDeferredNavigation(
- content::NavigationThrottle::CANCEL);
+ block_and_collapse_is_supported
+ ? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
+ : content::NavigationThrottle::CANCEL);
} else {
navigation_handle()->Resume();
}
diff --git a/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h b/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h
index c9ba823943d..e4dbfe12c84 100644
--- a/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h
+++ b/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter.h"
#include "content/public/browser/navigation_throttle.h"
@@ -37,14 +38,22 @@ class SubframeNavigationFilteringThrottle : public content::NavigationThrottle {
content::NavigationThrottle::ThrottleCheckResult WillStartRequest() override;
content::NavigationThrottle::ThrottleCheckResult WillRedirectRequest()
override;
+ const char* GetNameForLogging() override;
private:
- content::NavigationThrottle::ThrottleCheckResult DeferToCalculateLoadPolicy();
- void OnCalculatedLoadPolicy(LoadPolicy policy);
+ enum class ThrottlingStage { WillStartRequest, WillRedirectRequest };
+
+ content::NavigationThrottle::ThrottleCheckResult DeferToCalculateLoadPolicy(
+ ThrottlingStage stage);
+ void OnCalculatedLoadPolicy(ThrottlingStage stage, LoadPolicy policy);
// Must outlive this class.
AsyncDocumentSubresourceFilter* parent_frame_filter_;
+ base::TimeTicks last_defer_timestamp_;
+ base::TimeDelta total_defer_time_;
+ bool disallowed_ = false;
+
base::WeakPtrFactory<SubframeNavigationFilteringThrottle> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(SubframeNavigationFilteringThrottle);
diff --git a/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc b/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc
index 71a590963ee..9971215160c 100644
--- a/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc
+++ b/chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc
@@ -11,6 +11,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
+#include "base/test/histogram_tester.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter.h"
#include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h"
#include "components/subresource_filter/core/common/activation_level.h"
@@ -18,6 +19,7 @@
#include "components/subresource_filter/core/common/test_ruleset_creator.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -45,6 +47,10 @@ class SubframeNavigationFilteringThrottleTest
content::RenderViewHostTestHarness::TearDown();
}
+ content::NavigationSimulator* navigation_simulator() {
+ return navigation_simulator_.get();
+ }
+
// content::WebContentsObserver:
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override {
@@ -119,6 +125,11 @@ class SubframeNavigationFilteringThrottleTest
navigation_simulator_->GetLastThrottleCheckResult());
}
+ void SimulateCommitErrorPage() {
+ DCHECK(content::IsBrowserSideNavigationEnabled());
+ navigation_simulator_->CommitErrorPage();
+ }
+
private:
testing::TestRulesetCreator test_ruleset_creator_;
testing::TestRulesetPair test_ruleset_pair_;
@@ -137,7 +148,8 @@ TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnStart) {
InitializeDocumentSubresourceFilter(GURL("https://example.test"));
CreateTestSubframeAndInitNavigation(
GURL("https://example.test/disallowed.html"), main_rfh());
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
}
TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnRedirect) {
@@ -146,8 +158,12 @@ TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnRedirect) {
main_rfh());
SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
+ content::NavigationThrottle::ThrottleCheckResult expected_result =
+ content::IsBrowserSideNavigationEnabled()
+ ? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
+ : content::NavigationThrottle::CANCEL;
SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"),
- content::NavigationThrottle::CANCEL);
+ expected_result);
}
TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnSecondRedirect) {
@@ -158,8 +174,12 @@ TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnSecondRedirect) {
SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
SimulateRedirectAndExpectResult(GURL("https://example.test/allowed2.html"),
content::NavigationThrottle::PROCEED);
+ content::NavigationThrottle::ThrottleCheckResult expected_result =
+ content::IsBrowserSideNavigationEnabled()
+ ? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
+ : content::NavigationThrottle::CANCEL;
SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"),
- content::NavigationThrottle::CANCEL);
+ expected_result);
}
TEST_F(SubframeNavigationFilteringThrottleTest, NeverFilterNonMatchingRule) {
@@ -187,7 +207,40 @@ TEST_F(SubframeNavigationFilteringThrottleTest, FilterSubsubframe) {
CreateTestSubframeAndInitNavigation(
GURL("https://example.test/disallowed.html"), parent_subframe);
- SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL);
+ SimulateStartAndExpectResult(
+ content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE);
+}
+
+TEST_F(SubframeNavigationFilteringThrottleTest, DelayMetrics) {
+ base::HistogramTester histogram_tester;
+ InitializeDocumentSubresourceFilter(GURL("https://example.test"));
+ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"),
+ main_rfh());
+ if (content::IsBrowserSideNavigationEnabled())
+ navigation_simulator()->SetTransition(ui::PAGE_TRANSITION_MANUAL_SUBFRAME);
+ SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
+ content::NavigationThrottle::ThrottleCheckResult expected_result =
+ content::IsBrowserSideNavigationEnabled()
+ ? content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE
+ : content::NavigationThrottle::CANCEL;
+ SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"),
+ expected_result);
+ if (content::IsBrowserSideNavigationEnabled())
+ SimulateCommitErrorPage();
+
+ const char kFilterDelayDisallowed[] =
+ "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Disallowed";
+ const char kFilterDelayAllowed[] =
+ "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Allowed";
+ histogram_tester.ExpectTotalCount(kFilterDelayDisallowed, 1);
+ histogram_tester.ExpectTotalCount(kFilterDelayAllowed, 0);
+
+ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"),
+ main_rfh());
+ SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED);
+ SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED);
+ histogram_tester.ExpectTotalCount(kFilterDelayDisallowed, 1);
+ histogram_tester.ExpectTotalCount(kFilterDelayAllowed, 1);
}
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_client.h b/chromium/components/subresource_filter/content/browser/subresource_filter_client.h
index b9be5a5c831..c46a0a24576 100644
--- a/chromium/components/subresource_filter/content/browser/subresource_filter_client.h
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_client.h
@@ -6,9 +6,14 @@
#define COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_CLIENT_H_
#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
+#include "content/public/browser/web_contents.h"
class GURL;
+namespace content {
+class NavigationHandle;
+} // namespace content
+
namespace subresource_filter {
class SubresourceFilterClient {
@@ -23,13 +28,18 @@ class SubresourceFilterClient {
// off.
virtual void ToggleNotificationVisibility(bool visibility) = 0;
- // Returns true if the given URL is whitelisted from activation via content
- // settings. This should only be called for main frame URLs.
- virtual bool IsWhitelistedByContentSettings(const GURL& url) = 0;
-
- // Adds |url| to the BLOCKED state via content settings for the current
- // profile.
- virtual void WhitelistByContentSettings(const GURL& url) = 0;
+ // Called when the activation decision is otherwise completely computed by the
+ // subresource filter. At this point, the embedder still has a chance to
+ // return false to suppress the activation. Returns whether the activation
+ // should be whitelisted for this navigation.
+ //
+ // Precondition: The navigation must be a main frame navigation.
+ virtual bool OnPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ bool activated) = 0;
+
+ // Adds |url| to a per-WebContents whitelist.
+ virtual void WhitelistInCurrentWebContents(const GURL& url) = 0;
virtual VerifiedRulesetDealer::Handle* GetRulesetDealer() = 0;
};
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_observer.h b/chromium/components/subresource_filter/content/browser/subresource_filter_observer.h
new file mode 100644
index 00000000000..7daa78a65f7
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_observer.h
@@ -0,0 +1,34 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_OBSERVER_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_OBSERVER_H_
+
+#include "components/subresource_filter/core/common/activation_decision.h"
+
+namespace content {
+class NavigationHandle;
+} // namespace content
+
+namespace subresource_filter {
+
+struct ActivationState;
+
+// Class to receive notifications of subresource filter events for a given
+// WebContents. Registered with a SubresourceFilterObserverManager.
+class SubresourceFilterObserver {
+ public:
+ virtual ~SubresourceFilterObserver() = default;
+
+ virtual void OnSubresourceFilterGoingAway() {}
+
+ virtual void OnPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ ActivationDecision activation_decision,
+ const ActivationState& activation_state) {}
+};
+
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_OBSERVER_H_
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.cc b/chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.cc
new file mode 100644
index 00000000000..f3b891c7aee
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.cc
@@ -0,0 +1,42 @@
+// Copyright 2017 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/subresource_filter/content/browser/subresource_filter_observer_manager.h"
+
+#include "components/subresource_filter/core/common/activation_state.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(
+ subresource_filter::SubresourceFilterObserverManager);
+
+namespace subresource_filter {
+
+SubresourceFilterObserverManager::SubresourceFilterObserverManager(
+ content::WebContents* web_contents) {}
+
+SubresourceFilterObserverManager::~SubresourceFilterObserverManager() {
+ for (auto& observer : observers_)
+ observer.OnSubresourceFilterGoingAway();
+}
+
+void SubresourceFilterObserverManager::AddObserver(
+ SubresourceFilterObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void SubresourceFilterObserverManager::RemoveObserver(
+ SubresourceFilterObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void SubresourceFilterObserverManager::NotifyPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ ActivationDecision activation_decision,
+ const ActivationState& activation_state) {
+ for (auto& observer : observers_) {
+ observer.OnPageActivationComputed(navigation_handle, activation_decision,
+ activation_state);
+ }
+}
+
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.h b/chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.h
new file mode 100644
index 00000000000..489fb214306
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_observer_manager.h
@@ -0,0 +1,49 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_OBSERVER_MANAGER_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_OBSERVER_MANAGER_H_
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "components/subresource_filter/content/browser/subresource_filter_observer.h"
+#include "components/subresource_filter/core/common/activation_decision.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace content {
+class NavigationHandle;
+class WebContents;
+} // namespace content
+
+namespace subresource_filter {
+
+struct ActivationState;
+
+// Manages retaining the list of SubresourceFilterObservers and notifying them
+// of various filtering events. Scoped to the lifetime of a WebContents.
+class SubresourceFilterObserverManager
+ : public content::WebContentsUserData<SubresourceFilterObserverManager> {
+ public:
+ explicit SubresourceFilterObserverManager(content::WebContents* web_contents);
+ ~SubresourceFilterObserverManager() override;
+
+ void AddObserver(SubresourceFilterObserver* observer);
+ void RemoveObserver(SubresourceFilterObserver* observer);
+
+ // Will be called at the latest in the WillProcessResponse stage from a
+ // NavigationThrottle that was registered before the throttle manager's
+ // throttles created in MaybeAppendNavigationThrottles().
+ void NotifyPageActivationComputed(
+ content::NavigationHandle* navigation_handle,
+ ActivationDecision activation_decision,
+ const ActivationState& activation_state);
+
+ private:
+ base::ObserverList<SubresourceFilterObserver> observers_;
+ DISALLOW_COPY_AND_ASSIGN(SubresourceFilterObserverManager);
+};
+
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_OBSERVER_MANAGER_H_
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc
index d75a56a3488..dfa868bdc33 100644
--- a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc
@@ -1,144 +1,291 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Copyright 2017 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/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h"
+#include <utility>
#include <vector>
+#include "base/metrics/histogram_macros.h"
#include "base/timer/timer.h"
-#include "components/safe_browsing_db/v4_local_database_manager.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "components/subresource_filter/content/browser/content_activation_list_utils.h"
#include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h"
+#include "components/subresource_filter/content/browser/subresource_filter_client.h"
+#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
+#include "ui/base/page_transition_types.h"
+#include "url/gurl.h"
+
+namespace subresource_filter {
namespace {
-// Maximum time in milliseconds to wait for the Safe Browsing service to
-// verify a URL. After this amount of time the outstanding check will be
-// aborted, and the URL will be treated as if it didn't belong to the
-// Subresource Filter only list.
-constexpr base::TimeDelta kCheckURLTimeout = base::TimeDelta::FromSeconds(5);
+// Records histograms about the pattern of redirect chains, and about the
+// pattern of whether the last URL in the chain matched the activation list.
+#define REPORT_REDIRECT_PATTERN_FOR_SUFFIX(suffix, is_matched, chain_size) \
+ do { \
+ UMA_HISTOGRAM_BOOLEAN("SubresourceFilter.PageLoad.FinalURLMatch." suffix, \
+ is_matched); \
+ if (is_matched) { \
+ UMA_HISTOGRAM_COUNTS( \
+ "SubresourceFilter.PageLoad.RedirectChainLength." suffix, \
+ chain_size); \
+ }; \
+ } while (0)
} // namespace
-namespace subresource_filter {
+SubresourceFilterSafeBrowsingActivationThrottle::
+ SubresourceFilterSafeBrowsingActivationThrottle(
+ content::NavigationHandle* handle,
+ SubresourceFilterClient* client,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+ database_manager)
+ : NavigationThrottle(handle),
+ io_task_runner_(std::move(io_task_runner)),
+ // The throttle can be created without a valid database manager. If so, it
+ // becomes a pass-through throttle and should never defer.
+ database_client_(database_manager
+ ? new SubresourceFilterSafeBrowsingClient(
+ std::move(database_manager),
+ AsWeakPtr(),
+ io_task_runner_,
+ base::ThreadTaskRunnerHandle::Get())
+ : nullptr,
+ base::OnTaskRunnerDeleter(io_task_runner_)),
+ client_(client) {
+ DCHECK(handle->IsInMainFrame());
+}
+
+SubresourceFilterSafeBrowsingActivationThrottle::
+ ~SubresourceFilterSafeBrowsingActivationThrottle() {
+ // The last check could be ongoing when the navigation is cancelled.
+ if (check_results_.empty() || !check_results_.back().finished)
+ return;
+ // TODO(csharrison): Log more metrics based on check_results_.
+ RecordRedirectChainMatchPatternForList(
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL);
+ RecordRedirectChainMatchPatternForList(ActivationList::PHISHING_INTERSTITIAL);
+ RecordRedirectChainMatchPatternForList(ActivationList::SUBRESOURCE_FILTER);
+}
+
+bool SubresourceFilterSafeBrowsingActivationThrottle::NavigationIsPageReload(
+ content::NavigationHandle* handle) {
+ return ui::PageTransitionCoreTypeIs(handle->GetPageTransition(),
+ ui::PAGE_TRANSITION_RELOAD) ||
+ // Some pages 'reload' from JavaScript by navigating to themselves.
+ handle->GetURL() == handle->GetReferrer().url;
+}
+
+content::NavigationThrottle::ThrottleCheckResult
+SubresourceFilterSafeBrowsingActivationThrottle::WillStartRequest() {
+ CheckCurrentUrl();
+ return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
+}
+
+content::NavigationThrottle::ThrottleCheckResult
+SubresourceFilterSafeBrowsingActivationThrottle::WillRedirectRequest() {
+ CheckCurrentUrl();
+ return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
+}
-class SubresourceFilterSafeBrowsingActivationThrottle::SBDatabaseClient
- : public safe_browsing::SafeBrowsingDatabaseManager::Client {
- public:
- SBDatabaseClient(
- scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
- database_manager,
- base::WeakPtr<SubresourceFilterSafeBrowsingActivationThrottle> throttle,
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
- : database_manager_(std::move(database_manager)),
- throttle_(throttle),
- io_task_runner_(io_task_runner) {}
-
- ~SBDatabaseClient() override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- database_manager_->CancelCheck(this);
+content::NavigationThrottle::ThrottleCheckResult
+SubresourceFilterSafeBrowsingActivationThrottle::WillProcessResponse() {
+ // No need to defer the navigation if the check already happened.
+ if (!database_client_ || check_results_.back().finished) {
+ NotifyResult();
+ return content::NavigationThrottle::ThrottleCheckResult::PROCEED;
}
+ defer_time_ = base::TimeTicks::Now();
+ return content::NavigationThrottle::ThrottleCheckResult::DEFER;
+}
+
+const char*
+SubresourceFilterSafeBrowsingActivationThrottle::GetNameForLogging() {
+ return "SubresourceFilterSafeBrowsingActivationThrottle";
+}
+
+void SubresourceFilterSafeBrowsingActivationThrottle::OnCheckUrlResultOnUI(
+ const SubresourceFilterSafeBrowsingClient::CheckResult& result) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ size_t request_id = result.request_id;
+ DCHECK_LT(request_id, check_results_.size());
- void CheckUrlOnIO(const GURL& url) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK(!url.is_empty());
- url_being_checked_ = url;
- if (database_manager_->CheckUrlForSubresourceFilter(url, this)) {
- OnCheckBrowseUrlResult(url, safe_browsing::SB_THREAT_TYPE_SAFE,
- safe_browsing::ThreatMetadata());
- return;
- }
- timer_.Start(FROM_HERE, kCheckURLTimeout, this,
- &SubresourceFilterSafeBrowsingActivationThrottle::
- SBDatabaseClient::OnCheckUrlTimeout);
+ auto& stored_result = check_results_.at(request_id);
+ DCHECK(!stored_result.finished);
+ stored_result = result;
+ if (!defer_time_.is_null() && request_id == check_results_.size() - 1) {
+ NotifyResult();
+ navigation_handle()->Resume();
}
+}
- void OnCheckBrowseUrlResult(
- const GURL& url,
- safe_browsing::SBThreatType threat_type,
- const safe_browsing::ThreatMetadata& metadata) override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- DCHECK_EQ(url_being_checked_, url);
- timer_.Stop(); // Cancel the timeout timer.
- io_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&SubresourceFilterSafeBrowsingActivationThrottle::
- OnCheckUrlResultOnUI,
- throttle_, url, threat_type, metadata.threat_pattern_type));
+void SubresourceFilterSafeBrowsingActivationThrottle::CheckCurrentUrl() {
+ if (!database_client_)
+ return;
+ check_results_.emplace_back();
+ size_t id = check_results_.size() - 1;
+ io_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&SubresourceFilterSafeBrowsingClient::CheckUrlOnIO,
+ base::Unretained(database_client_.get()),
+ navigation_handle()->GetURL(), id));
+}
+
+void SubresourceFilterSafeBrowsingActivationThrottle::NotifyResult() {
+ auto* driver_factory = ContentSubresourceFilterDriverFactory::FromWebContents(
+ navigation_handle()->GetWebContents());
+ DCHECK(driver_factory);
+ if (driver_factory->GetActivationOptionsForLastCommittedPageLoad()
+ .should_whitelist_site_on_reload &&
+ NavigationIsPageReload(navigation_handle())) {
+ // Whitelist this host for the current as well as subsequent navigations.
+ client_->WhitelistInCurrentWebContents(navigation_handle()->GetURL());
}
- // Callback for when the safe browsing check has taken longer than
- // kCheckURLTimeout.
- void OnCheckUrlTimeout() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- database_manager_->CancelCheck(this);
+ Configuration::ActivationOptions matched_options;
+ ActivationDecision activation_decision = ComputeActivation(&matched_options);
+
+ // Check for whitelisted status last, so that the client gets an accurate
+ // indication of whether there would be activation otherwise.
+ bool whitelisted = client_->OnPageActivationComputed(
+ navigation_handle(),
+ matched_options.activation_level == ActivationLevel::ENABLED);
- OnCheckBrowseUrlResult(url_being_checked_,
- safe_browsing::SB_THREAT_TYPE_SAFE,
- safe_browsing::ThreatMetadata());
+ // Only reset the activation decision reason if we would have activated.
+ if (whitelisted && activation_decision == ActivationDecision::ACTIVATED) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "ActivationWhitelisted");
+ activation_decision = ActivationDecision::URL_WHITELISTED;
+ matched_options = Configuration::ActivationOptions();
}
- private:
- scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
+ driver_factory->NotifyPageActivationComputed(
+ navigation_handle(), activation_decision, matched_options);
- // Timer to abort the safe browsing check if it takes too long.
- base::OneShotTimer timer_;
- GURL url_being_checked_;
+ base::TimeDelta delay = defer_time_.is_null()
+ ? base::TimeDelta::FromMilliseconds(0)
+ : base::TimeTicks::Now() - defer_time_;
+ UMA_HISTOGRAM_TIMES("SubresourceFilter.PageLoad.SafeBrowsingDelay", delay);
- base::WeakPtr<SubresourceFilterSafeBrowsingActivationThrottle> throttle_;
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ // Log a histogram for the delay we would have introduced if the throttle only
+ // speculatively checks URLs on WillStartRequest. This is only different from
+ // the actual delay if there was at least one redirect.
+ base::TimeDelta no_redirect_speculation_delay =
+ check_results_.size() > 1 ? check_results_.back().check_time : delay;
+ UMA_HISTOGRAM_TIMES(
+ "SubresourceFilter.PageLoad.SafeBrowsingDelay.NoRedirectSpeculation",
+ no_redirect_speculation_delay);
+}
- DISALLOW_COPY_AND_ASSIGN(SBDatabaseClient);
-};
+ActivationDecision
+SubresourceFilterSafeBrowsingActivationThrottle::ComputeActivation(
+ Configuration::ActivationOptions* options) {
+ const GURL& url(navigation_handle()->GetURL());
+ ActivationList matched_list = ActivationList::NONE;
+ DCHECK(!database_client_ || !check_results_.empty());
+ if (!check_results_.empty()) {
+ DCHECK(check_results_.back().finished);
+ matched_list = GetListForThreatTypeAndMetadata(
+ check_results_.back().threat_type, check_results_.back().pattern_type);
+ }
-SubresourceFilterSafeBrowsingActivationThrottle::
- SubresourceFilterSafeBrowsingActivationThrottle(
- content::NavigationHandle* handle,
- scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
- database_manager)
- : NavigationThrottle(handle),
- io_task_runner_(content::BrowserThread::GetTaskRunnerForThread(
- content::BrowserThread::IO)),
- database_client_(
- new SubresourceFilterSafeBrowsingActivationThrottle::SBDatabaseClient(
- std::move(database_manager),
- AsWeakPtr(),
- base::ThreadTaskRunnerHandle::Get()),
- base::OnTaskRunnerDeleter(io_task_runner_)) {}
+ const auto config_list = GetEnabledConfigurations();
+ bool scheme_is_http_or_https = url.SchemeIsHTTPOrHTTPS();
+ const auto highest_priority_activated_config =
+ std::find_if(config_list->configs_by_decreasing_priority().begin(),
+ config_list->configs_by_decreasing_priority().end(),
+ [&url, scheme_is_http_or_https, matched_list,
+ this](const Configuration& config) {
+ return DoesMainFrameURLSatisfyActivationConditions(
+ url, scheme_is_http_or_https,
+ config.activation_conditions, matched_list);
+ });
-SubresourceFilterSafeBrowsingActivationThrottle::
- ~SubresourceFilterSafeBrowsingActivationThrottle() {}
+ bool has_activated_config =
+ highest_priority_activated_config !=
+ config_list->configs_by_decreasing_priority().end();
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "ContentSubresourceFilterDriverFactory::"
+ "ComputeActivationForMainFrameNavigation",
+ "highest_priority_activated_config",
+ has_activated_config
+ ? highest_priority_activated_config->ToTracedValue()
+ : base::MakeUnique<base::trace_event::TracedValue>());
-content::NavigationThrottle::ThrottleCheckResult
-SubresourceFilterSafeBrowsingActivationThrottle::WillProcessResponse() {
- io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&SubresourceFilterSafeBrowsingActivationThrottle::
- SBDatabaseClient::CheckUrlOnIO,
- base::Unretained(database_client_.get()),
- navigation_handle()->GetURL()));
- return content::NavigationThrottle::ThrottleCheckResult::DEFER;
+ if (!has_activated_config)
+ return ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET;
+
+ const Configuration::ActivationOptions activation_options =
+ highest_priority_activated_config->activation_options;
+ if (!scheme_is_http_or_https &&
+ activation_options.activation_level != ActivationLevel::DISABLED) {
+ return ActivationDecision::UNSUPPORTED_SCHEME;
+ }
+
+ *options = activation_options;
+ return activation_options.activation_level == ActivationLevel::DISABLED
+ ? ActivationDecision::ACTIVATION_DISABLED
+ : ActivationDecision::ACTIVATED;
}
-void SubresourceFilterSafeBrowsingActivationThrottle::OnCheckUrlResultOnUI(
- const GURL& url,
- safe_browsing::SBThreatType threat_type,
- safe_browsing::ThreatPatternType pattern_type) {
- content::WebContents* web_contents = navigation_handle()->GetWebContents();
- if (web_contents) {
- using subresource_filter::ContentSubresourceFilterDriverFactory;
- ContentSubresourceFilterDriverFactory* driver_factory =
- ContentSubresourceFilterDriverFactory::FromWebContents(web_contents);
- DCHECK(driver_factory);
-
- driver_factory->OnMainResourceMatchedSafeBrowsingBlacklist(
- url, std::vector<GURL>(), threat_type, pattern_type);
+bool SubresourceFilterSafeBrowsingActivationThrottle::
+ DoesMainFrameURLSatisfyActivationConditions(
+ const GURL& url,
+ bool scheme_is_http_or_https,
+ const Configuration::ActivationConditions& conditions,
+ ActivationList matched_list) const {
+ switch (conditions.activation_scope) {
+ case ActivationScope::ALL_SITES:
+ return true;
+ case ActivationScope::ACTIVATION_LIST:
+ // ACTIVATION_LIST does not support non http/s URLs.
+ if (!scheme_is_http_or_https)
+ return false;
+ if (conditions.activation_list == matched_list)
+ return true;
+ if (conditions.activation_list == ActivationList::PHISHING_INTERSTITIAL &&
+ matched_list == ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL) {
+ // Handling special case, where activation on the phishing sites also
+ // mean the activation on the sites with social engineering metadata.
+ return true;
+ }
+ return false;
+ case ActivationScope::NO_SITES:
+ return false;
+ }
+ NOTREACHED();
+ return false;
+}
+
+void SubresourceFilterSafeBrowsingActivationThrottle::
+ RecordRedirectChainMatchPatternForList(ActivationList activation_list) {
+ DCHECK(check_results_.back().finished);
+ ActivationList matched_list = GetListForThreatTypeAndMetadata(
+ check_results_.back().threat_type, check_results_.back().pattern_type);
+ bool is_matched = matched_list == activation_list;
+ size_t chain_size = check_results_.size();
+ switch (activation_list) {
+ case ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL:
+ REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SocialEngineeringAdsInterstitial",
+ is_matched, chain_size);
+ break;
+ case ActivationList::PHISHING_INTERSTITIAL:
+ REPORT_REDIRECT_PATTERN_FOR_SUFFIX("PhishingInterstitial", is_matched,
+ chain_size);
+ break;
+ case ActivationList::SUBRESOURCE_FILTER:
+ REPORT_REDIRECT_PATTERN_FOR_SUFFIX("SubresourceFilterOnly", is_matched,
+ chain_size);
+ break;
+ default:
+ NOTREACHED();
+ break;
}
- // TODO(https://crbug.com/704508): We should measure the delay introduces by
- // this check. Similarly, as it's done the Safe Browsing Resource throttle.
- navigation_handle()->Resume();
}
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h
index 082076bada7..885e4e3e953 100644
--- a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h
@@ -1,20 +1,35 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Copyright 2017 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_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_ACTIVATION_THROTTLE_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_ACTIVATION_THROTTLE_H_
+#include <stddef.h>
+
+#include <memory>
+#include <vector>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
+#include "base/time/time.h"
#include "components/safe_browsing_db/database_manager.h"
+#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h"
+#include "components/subresource_filter/core/browser/subresource_filter_features.h"
+#include "components/subresource_filter/core/common/activation_decision.h"
+#include "components/subresource_filter/core/common/activation_list.h"
#include "content/public/browser/navigation_throttle.h"
-#include "url/gurl.h"
+
+namespace base {
+class GURL;
+} // namespace base
namespace subresource_filter {
+class SubresourceFilterClient;
+
// Navigation throttle responsible for activating subresource filtering on page
// loads that match the SUBRESOURCE_FILTER Safe Browsing list.
class SubresourceFilterSafeBrowsingActivationThrottle
@@ -24,24 +39,60 @@ class SubresourceFilterSafeBrowsingActivationThrottle
public:
SubresourceFilterSafeBrowsingActivationThrottle(
content::NavigationHandle* handle,
+ SubresourceFilterClient* client,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
database_manager);
~SubresourceFilterSafeBrowsingActivationThrottle() override;
+ // Returns whether the navigation handle is a page reload, based on the
+ // transition type and referrer.
+ static bool NavigationIsPageReload(content::NavigationHandle* handle);
+
// content::NavigationThrottle:
+ content::NavigationThrottle::ThrottleCheckResult WillStartRequest() override;
+ content::NavigationThrottle::ThrottleCheckResult WillRedirectRequest()
+ override;
content::NavigationThrottle::ThrottleCheckResult WillProcessResponse()
override;
+ const char* GetNameForLogging() override;
- void OnCheckUrlResultOnUI(const GURL& url,
- safe_browsing::SBThreatType threat_type,
- safe_browsing::ThreatPatternType pattern_type);
+ void OnCheckUrlResultOnUI(
+ const SubresourceFilterSafeBrowsingClient::CheckResult& result);
private:
- class SBDatabaseClient;
+ void CheckCurrentUrl();
+ void NotifyResult();
+
+ ActivationDecision ComputeActivation(
+ Configuration::ActivationOptions* options);
+ // Returns whether a main-frame navigation to the given |url| satisfies the
+ // activation |conditions| of a given configuration, except for |priority|.
+ bool DoesMainFrameURLSatisfyActivationConditions(
+ const GURL& url,
+ bool scheme_is_http_or_https,
+ const Configuration::ActivationConditions& conditions,
+ ActivationList matched_list) const;
+
+ void RecordRedirectChainMatchPatternForList(ActivationList activation_list);
+
+ std::vector<SubresourceFilterSafeBrowsingClient::CheckResult> check_results_;
+
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
- std::unique_ptr<SBDatabaseClient, base::OnTaskRunnerDeleter> database_client_;
+
+ std::unique_ptr<SubresourceFilterSafeBrowsingClient,
+ base::OnTaskRunnerDeleter>
+ database_client_;
+
+ // Must outlive this class.
+ SubresourceFilterClient* client_;
+
+ // Set to TimeTicks::Now() when the navigation is deferred in
+ // WillProcessResponse. If deferral was not necessary, will remain null.
+ base::TimeTicks defer_time_;
DISALLOW_COPY_AND_ASSIGN(SubresourceFilterSafeBrowsingActivationThrottle);
};
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
index 0a49f61053c..9939a319584 100644
--- a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
@@ -5,19 +5,36 @@
#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h"
#include <memory>
+#include <set>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
+#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
+#include "base/test/test_mock_time_task_runner.h"
#include "components/safe_browsing_db/test_database_manager.h"
#include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h"
+#include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h"
#include "components/subresource_filter/content/browser/subresource_filter_client.h"
+#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h"
+#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h"
+#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
#include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
+#include "components/subresource_filter/core/common/activation_decision.h"
+#include "components/subresource_filter/core/common/activation_level.h"
+#include "components/subresource_filter/core/common/activation_list.h"
+#include "components/subresource_filter/core/common/activation_state.h"
#include "components/subresource_filter/core/common/test_ruleset_creator.h"
+#include "components/subresource_filter/core/common/test_ruleset_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents_observer.h"
+#include "content/public/test/cancelling_navigation_throttle.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -27,8 +44,14 @@ namespace subresource_filter {
namespace {
+const char kUrlA[] = "https://example_a.com";
+const char kUrlB[] = "https://example_b.com";
+const char kUrlC[] = "https://example_c.com";
+const char kUrlD[] = "https://example_d.com";
+
char kURL[] = "http://example.test/";
-char kRedirectURL[] = "http://foo.test/";
+char kURLWithParams[] = "http://example.test/?v=10";
+char kRedirectURL[] = "http://redirect.test/";
// Names of navigation chain patterns histogram.
const char kMatchesPatternHistogramNameSubresourceFilterSuffix[] =
@@ -36,120 +59,98 @@ const char kMatchesPatternHistogramNameSubresourceFilterSuffix[] =
"SubresourceFilterOnly";
const char kNavigationChainSizeSubresourceFilterSuffix[] =
"SubresourceFilter.PageLoad.RedirectChainLength.SubresourceFilterOnly";
+const char kSafeBrowsingNavigationDelay[] =
+ "SubresourceFilter.PageLoad.SafeBrowsingDelay";
+const char kSafeBrowsingNavigationDelayNoSpeculation[] =
+ "SubresourceFilter.PageLoad.SafeBrowsingDelay.NoRedirectSpeculation";
+const char kSafeBrowsingCheckTime[] =
+ "SubresourceFilter.SafeBrowsing.CheckTime";
+const char kMatchesPatternHistogramName[] =
+ "SubresourceFilter.PageLoad.FinalURLMatch.";
+const char kNavigationChainSize[] =
+ "SubresourceFilter.PageLoad.RedirectChainLength.";
-// Human readable representation of expected redirect chain match patterns.
-// The explanations for the buckets given for the following redirect chain:
-// A->B->C->D, where A is initial URL and D is a final URL.
-enum RedirectChainMatchPattern {
- EMPTY, // No histograms were recorded.
- F0M0L1, // D is a Safe Browsing match.
- F0M1L0, // B or C, or both are Safe Browsing matches.
- F0M1L1, // B or C, or both and D are Safe Browsing matches.
- F1M0L0, // A is Safe Browsing match
- F1M0L1, // A and D are Safe Browsing matches.
- F1M1L0, // B and/or C and A are Safe Browsing matches.
- F1M1L1, // B and/or C and A and D are Safe Browsing matches.
- NO_REDIRECTS_HIT, // Redirect chain consists of single URL, aka no redirects
- // has happened, and this URL was a Safe Browsing hit.
- NUM_HIT_PATTERNS,
-};
-
-// Database manager that allows any URL to be configured as blacklisted for
-// testing.
-class FakeSafeBrowsingDatabaseManager
- : public safe_browsing::TestSafeBrowsingDatabaseManager {
+class MockSubresourceFilterClient : public SubresourceFilterClient {
public:
- FakeSafeBrowsingDatabaseManager() : simulate_timeout_(false) {}
+ MockSubresourceFilterClient() = default;
+ ~MockSubresourceFilterClient() override = default;
- void AddBlacklistedUrl(const GURL& url,
- safe_browsing::SBThreatType threat_type) {
- url_to_threat_type_[url] = threat_type;
+ // Mocks have trouble with move-only types passed in the constructor.
+ void set_ruleset_dealer(
+ std::unique_ptr<VerifiedRulesetDealer::Handle> ruleset_dealer) {
+ ruleset_dealer_ = std::move(ruleset_dealer);
}
- void SimulateTimeout() { simulate_timeout_ = true; }
-
- protected:
- ~FakeSafeBrowsingDatabaseManager() override {}
-
- bool CheckUrlForSubresourceFilter(const GURL& url, Client* client) override {
- if (simulate_timeout_)
- return false;
- if (!url_to_threat_type_.count(url))
- return true;
-
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&Client::OnCheckBrowseUrlResult, base::Unretained(client),
- url, url_to_threat_type_[url],
- safe_browsing::ThreatMetadata()));
- return false;
+ bool OnPageActivationComputed(content::NavigationHandle* handle,
+ bool activated) override {
+ DCHECK(handle->IsInMainFrame());
+ return whitelisted_hosts_.count(handle->GetURL().host());
}
- bool CheckResourceUrl(const GURL& url, Client* client) override {
- return true;
+ void WhitelistInCurrentWebContents(const GURL& url) override {
+ ASSERT_TRUE(url.SchemeIsHTTPOrHTTPS());
+ whitelisted_hosts_.insert(url.host());
}
- bool IsSupported() const override { return true; }
- bool ChecksAreAlwaysAsync() const override { return false; }
- bool CanCheckResourceType(
- content::ResourceType /* resource_type */) const override {
- return true;
+ VerifiedRulesetDealer::Handle* GetRulesetDealer() override {
+ return ruleset_dealer_.get();
}
- safe_browsing::ThreatSource GetThreatSource() const override {
- return safe_browsing::ThreatSource::LOCAL_PVER4;
- }
+ MOCK_METHOD1(ToggleNotificationVisibility, void(bool));
- bool CheckExtensionIDs(const std::set<std::string>& extension_ids,
- Client* client) override {
- return true;
- }
+ void ClearWhitelist() { whitelisted_hosts_.clear(); }
private:
- std::map<GURL, safe_browsing::SBThreatType> url_to_threat_type_;
- bool simulate_timeout_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
-};
+ std::set<std::string> whitelisted_hosts_;
-class MockSubresourceFilterClient
- : public subresource_filter::SubresourceFilterClient {
- public:
- MockSubresourceFilterClient() {}
-
- ~MockSubresourceFilterClient() override = default;
+ std::unique_ptr<VerifiedRulesetDealer::Handle> ruleset_dealer_;
- MOCK_METHOD1(ToggleNotificationVisibility, void(bool));
- MOCK_METHOD1(IsWhitelistedByContentSettings, bool(const GURL&));
- MOCK_METHOD1(WhitelistByContentSettings, void(const GURL&));
- MOCK_METHOD0(GetRulesetDealer, VerifiedRulesetDealer::Handle*());
-
- private:
DISALLOW_COPY_AND_ASSIGN(MockSubresourceFilterClient);
};
-// Throttle to call WillProcessResponse on the factory, which is otherwise
-// called by the ThrottleManager.
-class TestForwardingNavigationThrottle : public content::NavigationThrottle {
- public:
- TestForwardingNavigationThrottle(content::NavigationHandle* handle)
- : content::NavigationThrottle(handle) {}
- ~TestForwardingNavigationThrottle() override {}
-
- // content::NavigationThrottle:
- content::NavigationThrottle::ThrottleCheckResult WillProcessResponse()
- override {
- content::WebContents* web_contents = navigation_handle()->GetWebContents();
- ContentSubresourceFilterDriverFactory* factory =
- ContentSubresourceFilterDriverFactory::FromWebContents(web_contents);
- factory->WillProcessResponse(navigation_handle());
- return content::NavigationThrottle::PROCEED;
+std::string GetSuffixForList(const ActivationList& type) {
+ switch (type) {
+ case ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL:
+ return "SocialEngineeringAdsInterstitial";
+ case ActivationList::PHISHING_INTERSTITIAL:
+ return "PhishingInterstitial";
+ case ActivationList::SUBRESOURCE_FILTER:
+ return "SubresourceFilterOnly";
+ case ActivationList::NONE:
+ return std::string();
}
+ return std::string();
+}
- private:
- DISALLOW_COPY_AND_ASSIGN(TestForwardingNavigationThrottle);
+struct ActivationListTestData {
+ const char* const activation_list;
+ ActivationList activation_list_type;
+ safe_browsing::SBThreatType threat_type;
+ safe_browsing::ThreatPatternType threat_type_metadata;
};
+const ActivationListTestData kActivationListTestData[] = {
+ {subresource_filter::kActivationListSocialEngineeringAdsInterstitial,
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {subresource_filter::kActivationListPhishingInterstitial,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::NONE},
+ {subresource_filter::kActivationListSubresourceFilter,
+ ActivationList::SUBRESOURCE_FILTER,
+ safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
+ safe_browsing::ThreatPatternType::NONE},
+};
+
+void ExpectSampleForSuffix(const std::string& suffix,
+ const std::string& match_suffix,
+ const base::HistogramTester& tester) {
+ tester.ExpectUniqueSample(kMatchesPatternHistogramName + suffix,
+ (suffix == match_suffix), 1);
+}
+
} // namespace
class SubresourceFilterSafeBrowsingActivationThrottleTest
@@ -162,18 +163,39 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
void SetUp() override {
content::RenderViewHostTestHarness::SetUp();
- scoped_feature_toggle_.reset(
- new testing::ScopedSubresourceFilterFeatureToggle(
- base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled,
- kActivationScopeActivationList, kActivationListSubresourceFilter));
- auto client = base::MakeUnique<MockSubresourceFilterClient>();
+ Configure();
+ test_io_task_runner_ = new base::TestMockTimeTaskRunner();
+ // Note: Using NiceMock to allow uninteresting calls and suppress warnings.
+ std::vector<proto::UrlRule> rules;
+ rules.push_back(testing::CreateSuffixRule("disallowed.html"));
+ ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules(
+ rules, &test_ruleset_pair_));
+ auto ruleset_dealer = base::MakeUnique<VerifiedRulesetDealer::Handle>(
+ base::MessageLoop::current()->task_runner());
+ ruleset_dealer->SetRulesetFile(
+ testing::TestRuleset::Open(test_ruleset_pair_.indexed));
+ client_ =
+ base::MakeUnique<::testing::NiceMock<MockSubresourceFilterClient>>();
+ client_->set_ruleset_dealer(std::move(ruleset_dealer));
ContentSubresourceFilterDriverFactory::CreateForWebContents(
- RenderViewHostTestHarness::web_contents(), std::move(client));
+ RenderViewHostTestHarness::web_contents(), client_.get());
fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager();
NavigateAndCommit(GURL("https://test.com"));
Observe(RenderViewHostTestHarness::web_contents());
}
+ virtual void Configure() {
+ scoped_configuration_.ResetConfiguration(Configuration(
+ ActivationLevel::ENABLED, ActivationScope::ACTIVATION_LIST,
+ ActivationList::SUBRESOURCE_FILTER));
+ }
+
+ void TearDown() override {
+ client_.reset();
+ RunUntilIdle();
+ content::RenderViewHostTestHarness::TearDown();
+ }
+
ContentSubresourceFilterDriverFactory* factory() {
return ContentSubresourceFilterDriverFactory::FromWebContents(
RenderViewHostTestHarness::web_contents());
@@ -182,140 +204,913 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
// content::WebContentsObserver:
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override {
- ASSERT_TRUE(navigation_handle->IsInMainFrame());
- navigation_handle_ = navigation_handle;
- navigation_handle->RegisterThrottleForTesting(
- base::MakeUnique<SubresourceFilterSafeBrowsingActivationThrottle>(
- navigation_handle, fake_safe_browsing_database_));
- navigation_handle->RegisterThrottleForTesting(
- base::MakeUnique<TestForwardingNavigationThrottle>(navigation_handle));
+ if (navigation_handle->IsInMainFrame()) {
+ navigation_handle->RegisterThrottleForTesting(
+ base::MakeUnique<SubresourceFilterSafeBrowsingActivationThrottle>(
+ navigation_handle, client(), test_io_task_runner_,
+ fake_safe_browsing_database_));
+ }
+ std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
+ factory()->throttle_manager()->MaybeAppendNavigationThrottles(
+ navigation_handle, &throttles);
+ for (auto& it : throttles) {
+ navigation_handle->RegisterThrottleForTesting(std::move(it));
+ }
+ }
+
+ // Returns the frame host the navigation committed in, or nullptr if it did
+ // not succeed.
+ content::RenderFrameHost* CreateAndNavigateDisallowedSubframe(
+ content::RenderFrameHost* parent) {
+ auto* subframe =
+ content::RenderFrameHostTester::For(parent)->AppendChild("subframe");
+ auto simulator = content::NavigationSimulator::CreateRendererInitiated(
+ GURL("https://example.test/disallowed.html"), subframe);
+ simulator->Commit();
+ return simulator->GetLastThrottleCheckResult() ==
+ content::NavigationThrottle::PROCEED
+ ? simulator->GetFinalRenderFrameHost()
+ : nullptr;
}
- void SimulateStartAndExpectProceed() {
+ content::RenderFrameHost* SimulateNavigateAndCommit(
+ std::vector<GURL> navigation_chain,
+ content::RenderFrameHost* rfh) {
+ SimulateStart(navigation_chain.front(), rfh);
+ for (auto it = navigation_chain.begin() + 1; it != navigation_chain.end();
+ ++it) {
+ SimulateRedirectAndExpectProceed(*it);
+ }
+ SimulateCommitAndExpectProceed();
+ return navigation_simulator_->GetFinalRenderFrameHost();
+ }
+
+ content::NavigationThrottle::ThrottleCheckResult SimulateStart(
+ const GURL& first_url,
+ content::RenderFrameHost* rfh) {
+ navigation_simulator_ =
+ content::NavigationSimulator::CreateRendererInitiated(first_url, rfh);
navigation_simulator_->Start();
- EXPECT_EQ(content::NavigationThrottle::PROCEED,
- navigation_simulator_->GetLastThrottleCheckResult());
+ auto result = navigation_simulator_->GetLastThrottleCheckResult();
+ if (result == content::NavigationThrottle::CANCEL)
+ navigation_simulator_.reset();
+ return result;
}
- void SimulateRedirectAndExpectProceed(const GURL& new_url) {
+ content::NavigationThrottle::ThrottleCheckResult SimulateRedirect(
+ const GURL& new_url) {
navigation_simulator_->Redirect(new_url);
+ auto result = navigation_simulator_->GetLastThrottleCheckResult();
+ if (result == content::NavigationThrottle::CANCEL)
+ navigation_simulator_.reset();
+ return result;
+ }
+
+ content::NavigationThrottle::ThrottleCheckResult SimulateCommit(
+ content::NavigationSimulator* simulator) {
+ // Need to post a task to flush the IO thread because calling Commit()
+ // blocks until the throttle checks are complete.
+ // TODO(csharrison): Consider adding finer grained control to the
+ // NavigationSimulator by giving it an option to be driven by a
+ // TestMockTimeTaskRunner. Also see https://crbug.com/703346.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&base::TestMockTimeTaskRunner::RunUntilIdle,
+ base::Unretained(test_io_task_runner_.get())));
+ simulator->Commit();
+ return simulator->GetLastThrottleCheckResult();
+ }
+
+ void SimulateStartAndExpectProceed(const GURL& first_url) {
EXPECT_EQ(content::NavigationThrottle::PROCEED,
- navigation_simulator_->GetLastThrottleCheckResult());
+ SimulateStart(first_url, main_rfh()));
+ }
+
+ void SimulateRedirectAndExpectProceed(const GURL& new_url) {
+ EXPECT_EQ(content::NavigationThrottle::PROCEED, SimulateRedirect(new_url));
}
void SimulateCommitAndExpectProceed() {
- navigation_simulator_->Commit();
EXPECT_EQ(content::NavigationThrottle::PROCEED,
- navigation_simulator_->GetLastThrottleCheckResult());
+ SimulateCommit(navigation_simulator()));
}
- void CreateTestNavigationForMainFrame(const GURL& first_url) {
- navigation_simulator_ =
- content::NavigationSimulator::CreateRendererInitiated(first_url,
- main_rfh());
+ void ConfigureForMatch(const GURL& url,
+ safe_browsing::SBThreatType pattern_type =
+ safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
+ safe_browsing::ThreatPatternType metadata =
+ safe_browsing::ThreatPatternType::NONE) {
+ fake_safe_browsing_database_->AddBlacklistedUrl(url, pattern_type,
+ metadata);
}
- void ConfigureAsSubresourceFilterOnlyURL(const GURL& url) {
- fake_safe_browsing_database_->AddBlacklistedUrl(
- url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER);
+ void SimulateTimeout() { fake_safe_browsing_database_->SimulateTimeout(); }
+
+ void ClearAllBlacklistedUrls() {
+ fake_safe_browsing_database_->RemoveAllBlacklistedUrls();
}
- void SimulateTimeout() { fake_safe_browsing_database_->SimulateTimeout(); }
+ // With a null database the throttle becomes pass-through.
+ void UsePassThroughThrottle() { fake_safe_browsing_database_ = nullptr; }
+
+ void RunUntilIdle() {
+ test_io_task_runner_->RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ content::NavigationSimulator* navigation_simulator() {
+ return navigation_simulator_.get();
+ }
const base::HistogramTester& tester() const { return tester_; }
+ MockSubresourceFilterClient* client() { return client_.get(); }
+
+ base::TestMockTimeTaskRunner* test_io_task_runner() const {
+ return test_io_task_runner_.get();
+ }
+
+ testing::ScopedSubresourceFilterConfigurator* scoped_configuration() {
+ return &scoped_configuration_;
+ }
+
private:
base::FieldTrialList field_trial_list_;
- std::unique_ptr<testing::ScopedSubresourceFilterFeatureToggle>
- scoped_feature_toggle_;
+ testing::ScopedSubresourceFilterConfigurator scoped_configuration_;
+ scoped_refptr<base::TestMockTimeTaskRunner> test_io_task_runner_;
+
+ testing::TestRulesetCreator test_ruleset_creator_;
+ testing::TestRulesetPair test_ruleset_pair_;
+
std::unique_ptr<content::NavigationSimulator> navigation_simulator_;
+ std::unique_ptr<MockSubresourceFilterClient> client_;
scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_;
base::HistogramTester tester_;
- content::NavigationHandle* navigation_handle_;
DISALLOW_COPY_AND_ASSIGN(SubresourceFilterSafeBrowsingActivationThrottleTest);
};
+class SubresourceFilterSafeBrowsingActivationThrottleParamTest
+ : public SubresourceFilterSafeBrowsingActivationThrottleTest,
+ public ::testing::WithParamInterface<ActivationListTestData> {
+ public:
+ SubresourceFilterSafeBrowsingActivationThrottleParamTest() {}
+ ~SubresourceFilterSafeBrowsingActivationThrottleParamTest() override {}
+
+ void Configure() override {
+ const ActivationListTestData& test_data = GetParam();
+ scoped_configuration()->ResetConfiguration(Configuration(
+ ActivationLevel::ENABLED, ActivationScope::ACTIVATION_LIST,
+ test_data.activation_list_type));
+ }
+
+ void ConfigureForMatchParam(const GURL& url) {
+ const ActivationListTestData& test_data = GetParam();
+ ConfigureForMatch(url, test_data.threat_type,
+ test_data.threat_type_metadata);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(
+ SubresourceFilterSafeBrowsingActivationThrottleParamTest);
+};
+
+class SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling
+ : public SubresourceFilterSafeBrowsingActivationThrottleTest,
+ public ::testing::WithParamInterface<
+ std::tuple<content::CancellingNavigationThrottle::CancelTime,
+ content::CancellingNavigationThrottle::ResultSynchrony>> {
+ public:
+ SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling() {
+ std::tie(cancel_time_, result_sync_) = GetParam();
+ }
+ ~SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling()
+ override {}
+
+ void DidStartNavigation(content::NavigationHandle* handle) override {
+ handle->RegisterThrottleForTesting(
+ base::MakeUnique<content::CancellingNavigationThrottle>(
+ handle, cancel_time_, result_sync_));
+ SubresourceFilterSafeBrowsingActivationThrottleTest::DidStartNavigation(
+ handle);
+ }
+
+ content::CancellingNavigationThrottle::CancelTime cancel_time() {
+ return cancel_time_;
+ }
+
+ content::CancellingNavigationThrottle::ResultSynchrony result_sync() {
+ return result_sync_;
+ }
+
+ private:
+ content::CancellingNavigationThrottle::CancelTime cancel_time_;
+ content::CancellingNavigationThrottle::ResultSynchrony result_sync_;
+
+ DISALLOW_COPY_AND_ASSIGN(
+ SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling);
+};
+
+struct ActivationScopeTestData {
+ ActivationDecision expected_activation_decision;
+ bool url_matches_activation_list;
+ ActivationScope activation_scope;
+};
+
+const ActivationScopeTestData kActivationScopeTestData[] = {
+ {ActivationDecision::ACTIVATED, false /* url_matches_activation_list */,
+ ActivationScope::ALL_SITES},
+ {ActivationDecision::ACTIVATED, true /* url_matches_activation_list */,
+ ActivationScope::ALL_SITES},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ true /* url_matches_activation_list */, ActivationScope::NO_SITES},
+ {ActivationDecision::ACTIVATED, true /* url_matches_activation_list */,
+ ActivationScope::ACTIVATION_LIST},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ false /* url_matches_activation_list */, ActivationScope::ACTIVATION_LIST},
+};
+
+class SubresourceFilterSafeBrowsingActivationThrottleScopeTest
+ : public SubresourceFilterSafeBrowsingActivationThrottleTest,
+ public ::testing::WithParamInterface<ActivationScopeTestData> {
+ public:
+ SubresourceFilterSafeBrowsingActivationThrottleScopeTest() {}
+ ~SubresourceFilterSafeBrowsingActivationThrottleScopeTest() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(
+ SubresourceFilterSafeBrowsingActivationThrottleScopeTest);
+};
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ PassThroughThrottle) {
+ UsePassThroughThrottle();
+ SimulateNavigateAndCommit({GURL(kURL), GURL(kRedirectURL)}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ scoped_configuration()->ResetConfiguration(
+ Configuration(ActivationLevel::ENABLED, ActivationScope::ALL_SITES));
+ SimulateNavigateAndCommit({GURL(kURL), GURL(kRedirectURL)}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ scoped_configuration()->ResetConfiguration(
+ Configuration(ActivationLevel::ENABLED, ActivationScope::NO_SITES));
+ SimulateNavigateAndCommit({GURL(kURL), GURL(kRedirectURL)}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, NoConfigs) {
+ scoped_configuration()->ResetConfiguration(std::vector<Configuration>());
+ SimulateNavigateAndCommit({GURL(kURL)}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ MultipleSimultaneousConfigs) {
+ Configuration config1(ActivationLevel::DRYRUN, ActivationScope::NO_SITES);
+ config1.activation_conditions.priority = 2;
+
+ Configuration config2(ActivationLevel::DISABLED,
+ ActivationScope::ACTIVATION_LIST,
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL);
+ config2.activation_conditions.priority = 1;
+
+ Configuration config3(ActivationLevel::ENABLED, ActivationScope::ALL_SITES);
+ config3.activation_options.should_whitelist_site_on_reload = true;
+ config3.activation_conditions.priority = 0;
+
+ scoped_configuration()->ResetConfiguration({config1, config2, config3});
+
+ // Should match |config2| and |config3|, the former with the higher priority.
+ GURL match_url(kUrlA);
+ GURL non_match_url(kUrlB);
+ ConfigureForMatch(match_url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS);
+ SimulateNavigateAndCommit({match_url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ // Should match |config3|.
+ SimulateNavigateAndCommit({non_match_url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ // Should match |config3|, but a reload, so this should get whitelisted.
+ auto reload_simulator = content::NavigationSimulator::CreateRendererInitiated(
+ non_match_url, main_rfh());
+ reload_simulator->SetTransition(ui::PAGE_TRANSITION_RELOAD);
+ reload_simulator->Start();
+ SimulateCommit(reload_simulator.get());
+ EXPECT_EQ(ActivationDecision::URL_WHITELISTED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ ActivationLevelDisabled_NoActivation) {
+ scoped_configuration()->ResetConfiguration(
+ Configuration(ActivationLevel::DISABLED, ActivationScope::ACTIVATION_LIST,
+ ActivationList::SUBRESOURCE_FILTER));
+ GURL url(kURL);
+
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ ConfigureForMatch(url);
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ // Whitelisting occurs last, so the decision should still be DISABLED.
+ factory()->client()->WhitelistInCurrentWebContents(url);
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ AllSiteEnabled_Activates) {
+ scoped_configuration()->ResetConfiguration(
+ Configuration(ActivationLevel::ENABLED, ActivationScope::ALL_SITES));
+ GURL url(kURL);
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ ConfigureForMatch(url);
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ // Adding performance measurement should keep activation.
+ Configuration config_with_perf(
+ Configuration(ActivationLevel::ENABLED, ActivationScope::ALL_SITES));
+ config_with_perf.activation_options.performance_measurement_rate = 1.0;
+ scoped_configuration()->ResetConfiguration(std::move(config_with_perf));
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ NavigationFails_NoActivation) {
+ EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ content::NavigationSimulator::NavigateAndFailFromDocument(
+ GURL(kURL), net::ERR_TIMED_OUT, main_rfh());
+ EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ NotificationVisibility) {
+ GURL url(kURL);
+ ConfigureForMatch(url);
+ EXPECT_CALL(*client(), ToggleNotificationVisibility(false)).Times(1);
+ content::RenderFrameHost* rfh = SimulateNavigateAndCommit({url}, main_rfh());
+
+ EXPECT_CALL(*client(), ToggleNotificationVisibility(true)).Times(1);
+ EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(rfh));
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ SuppressNotificationVisibility) {
+ Configuration config(ActivationLevel::ENABLED, ActivationScope::ALL_SITES);
+ config.activation_options.should_suppress_notifications = true;
+ scoped_configuration()->ResetConfiguration(std::move(config));
+
+ GURL url(kURL);
+ content::RenderFrameHost* rfh = SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0);
+ EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(rfh));
+}
+
TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ WhitelistSiteOnReload) {
+ const struct {
+ content::Referrer referrer;
+ ui::PageTransition transition;
+ ActivationDecision expected_activation_decision;
+ } kTestCases[] = {
+ {content::Referrer(), ui::PAGE_TRANSITION_LINK,
+ ActivationDecision::ACTIVATED},
+ {content::Referrer(GURL(kUrlA), blink::kWebReferrerPolicyDefault),
+ ui::PAGE_TRANSITION_LINK, ActivationDecision::ACTIVATED},
+ {content::Referrer(GURL(kURL), blink::kWebReferrerPolicyDefault),
+ ui::PAGE_TRANSITION_LINK, ActivationDecision::URL_WHITELISTED},
+ {content::Referrer(), ui::PAGE_TRANSITION_RELOAD,
+ ActivationDecision::URL_WHITELISTED}};
+
+ Configuration config(ActivationLevel::ENABLED, ActivationScope::ALL_SITES);
+ config.activation_options.should_whitelist_site_on_reload = true;
+ scoped_configuration()->ResetConfiguration(std::move(config));
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message("referrer = \"")
+ << test_case.referrer.url << "\""
+ << " transition = \"" << test_case.transition << "\"");
+
+ auto simulator = content::NavigationSimulator::CreateRendererInitiated(
+ GURL(kURL), main_rfh());
+ simulator->SetTransition(test_case.transition);
+ simulator->SetReferrer(test_case.referrer);
+ SimulateCommit(simulator.get());
+ EXPECT_EQ(test_case.expected_activation_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ // Verify that if the first URL failed to activate, subsequent same-origin
+ // navigations also fail to activate.
+ simulator = content::NavigationSimulator::CreateRendererInitiated(
+ GURL(kURLWithParams), main_rfh());
+ SimulateCommit(simulator.get());
+ EXPECT_EQ(test_case.expected_activation_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ }
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+ ActivateForFrameState) {
+ const struct {
+ ActivationDecision activation_decision;
+ ActivationLevel activation_level;
+ } kTestCases[] = {
+ {ActivationDecision::ACTIVATED, ActivationLevel::DRYRUN},
+ {ActivationDecision::ACTIVATED, ActivationLevel::ENABLED},
+ {ActivationDecision::ACTIVATION_DISABLED, ActivationLevel::DISABLED},
+ };
+ for (const auto& test_data : kTestCases) {
+ SCOPED_TRACE(::testing::Message()
+ << "activation_decision "
+ << static_cast<int>(test_data.activation_decision)
+ << " activation_level " << test_data.activation_level);
+ client()->ClearWhitelist();
+ scoped_configuration()->ResetConfiguration(Configuration(
+ test_data.activation_level, ActivationScope::ACTIVATION_LIST,
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL));
+ const GURL url(kURLWithParams);
+ ConfigureForMatch(url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS);
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(test_data.activation_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+
+ // Whitelisting is only applied when the page will otherwise activate.
+ client()->WhitelistInCurrentWebContents(url);
+ ActivationDecision decision =
+ test_data.activation_level == ActivationLevel::DISABLED
+ ? test_data.activation_decision
+ : ActivationDecision::URL_WHITELISTED;
+ SimulateNavigateAndCommit({url}, main_rfh());
+ EXPECT_EQ(decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ }
+}
+
+TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, ActivationList) {
+ const struct {
+ ActivationDecision expected_activation_decision;
+ ActivationList activation_list;
+ safe_browsing::SBThreatType threat_type;
+ safe_browsing::ThreatPatternType threat_type_metadata;
+ } kTestCases[] = {
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET, ActivationList::NONE,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::NONE},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::MALWARE_LANDING},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::MALWARE_DISTRIBUTION},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_API_ABUSE,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_BLACKLISTED_RESOURCE,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_BINARY_MALWARE_URL,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_UNWANTED,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_SAFE,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATED, ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::NONE},
+ {ActivationDecision::ACTIVATED,
+ ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATED, ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
+ {ActivationDecision::ACTIVATED, ActivationList::SUBRESOURCE_FILTER,
+ safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
+ safe_browsing::ThreatPatternType::NONE},
+ {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ ActivationList::PHISHING_INTERSTITIAL,
+ safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
+ safe_browsing::ThreatPatternType::NONE},
+ };
+ const GURL test_url("https://matched_url.com/");
+ for (const auto& test_case : kTestCases) {
+ scoped_configuration()->ResetConfiguration(Configuration(
+ ActivationLevel::ENABLED, ActivationScope::ACTIVATION_LIST,
+ test_case.activation_list));
+ ClearAllBlacklistedUrls();
+ ConfigureForMatch(test_url, test_case.threat_type,
+ test_case.threat_type_metadata);
+ SimulateNavigateAndCommit({GURL(kUrlA), GURL(kUrlB), GURL(kUrlC), test_url},
+ main_rfh());
+ EXPECT_EQ(test_case.expected_activation_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ }
+}
+
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
+ ActivateForScopeType) {
+ const ActivationScopeTestData& test_data = GetParam();
+ scoped_configuration()->ResetConfiguration(
+ Configuration(ActivationLevel::ENABLED, test_data.activation_scope,
+ ActivationList::SUBRESOURCE_FILTER));
+
+ const GURL test_url(kURLWithParams);
+ if (test_data.url_matches_activation_list)
+ ConfigureForMatch(test_url);
+ SimulateNavigateAndCommit({test_url}, main_rfh());
+ EXPECT_EQ(test_data.expected_activation_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ if (test_data.url_matches_activation_list) {
+ factory()->client()->WhitelistInCurrentWebContents(test_url);
+ ActivationDecision expected_decision =
+ test_data.expected_activation_decision;
+ if (expected_decision == ActivationDecision::ACTIVATED)
+ expected_decision = ActivationDecision::URL_WHITELISTED;
+ SimulateNavigateAndCommit({test_url}, main_rfh());
+ EXPECT_EQ(expected_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ }
+};
+
+// Only main frames with http/https schemes should activate.
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
+ ActivateForSupportedUrlScheme) {
+ const ActivationScopeTestData& test_data = GetParam();
+ scoped_configuration()->ResetConfiguration(
+ Configuration(ActivationLevel::ENABLED, test_data.activation_scope,
+ ActivationList::SUBRESOURCE_FILTER));
+
+ // data URLs are also not supported, but not listed here, as it's not possible
+ // for a page to redirect to them after https://crbug.com/594215 is fixed.
+ const char* unsupported_urls[] = {"ftp://example.com/", "chrome://settings",
+ "chrome-extension://some-extension",
+ "file:///var/www/index.html"};
+ const char* supported_urls[] = {"http://example.test",
+ "https://example.test"};
+ for (auto* url : unsupported_urls) {
+ SCOPED_TRACE(url);
+ if (test_data.url_matches_activation_list)
+ ConfigureForMatch(GURL(url));
+ SimulateNavigateAndCommit({GURL(url)}, main_rfh());
+ ActivationDecision expected_decision =
+ ActivationDecision::UNSUPPORTED_SCHEME;
+ // We only log UNSUPPORTED_SCHEME if the navigation would have otherwise
+ // activated. Note that non http/s URLs will never match an activation list.
+ if (test_data.expected_activation_decision ==
+ ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET ||
+ test_data.activation_scope == ActivationScope::ACTIVATION_LIST) {
+ expected_decision = ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET;
+ }
+ EXPECT_EQ(expected_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ }
+
+ for (auto* url : supported_urls) {
+ SCOPED_TRACE(url);
+ if (test_data.url_matches_activation_list)
+ ConfigureForMatch(GURL(url));
+ SimulateNavigateAndCommit({GURL(url)}, main_rfh());
+ EXPECT_EQ(test_data.expected_activation_decision,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ }
+};
+
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
ListNotMatched_NoActivation) {
+ const ActivationListTestData& test_data = GetParam();
const GURL url(kURL);
- CreateTestNavigationForMainFrame(url);
- SimulateStartAndExpectProceed();
+ const std::string suffix(GetSuffixForList(test_data.activation_list_type));
+ SimulateStartAndExpectProceed(url);
SimulateCommitAndExpectProceed();
- EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision::
- ACTIVATION_LIST_NOT_MATCHED,
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
factory()->GetActivationDecisionForLastCommittedPageLoad());
- tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix,
- 0);
- tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0);
+ ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", std::string(),
+ tester());
+ ExpectSampleForSuffix("PhishingInterstitial", std::string(), tester());
+ ExpectSampleForSuffix("SubresourceFilterOnly", std::string(), tester());
+
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelay, 1);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelayNoSpeculation, 1);
+ tester().ExpectTotalCount(kSafeBrowsingCheckTime, 1);
+ tester().ExpectTotalCount(kNavigationChainSize + suffix, 0);
}
-TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
ListMatched_Activation) {
+ const ActivationListTestData& test_data = GetParam();
const GURL url(kURL);
- ConfigureAsSubresourceFilterOnlyURL(url);
- CreateTestNavigationForMainFrame(url);
- SimulateStartAndExpectProceed();
+ ConfigureForMatchParam(url);
+ SimulateStartAndExpectProceed(url);
SimulateCommitAndExpectProceed();
- EXPECT_EQ(
- ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED,
- factory()->GetActivationDecisionForLastCommittedPageLoad());
- tester().ExpectUniqueSample(
- kMatchesPatternHistogramNameSubresourceFilterSuffix, NO_REDIRECTS_HIT, 1);
- tester().ExpectUniqueSample(kNavigationChainSizeSubresourceFilterSuffix, 1,
- 1);
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ const std::string suffix(GetSuffixForList(test_data.activation_list_type));
+ ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", suffix, tester());
+ ExpectSampleForSuffix("PhishingInterstitial", suffix, tester());
+ ExpectSampleForSuffix("SubresourceFilterOnly", suffix, tester());
+ tester().ExpectUniqueSample(kNavigationChainSize + suffix, 1, 1);
}
-TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
ListNotMatchedAfterRedirect_NoActivation) {
+ const ActivationListTestData& test_data = GetParam();
const GURL url(kURL);
- CreateTestNavigationForMainFrame(url);
- SimulateStartAndExpectProceed();
+ const std::string suffix(GetSuffixForList(test_data.activation_list_type));
+ SimulateStartAndExpectProceed(url);
SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
SimulateCommitAndExpectProceed();
- EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision::
- ACTIVATION_LIST_NOT_MATCHED,
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
factory()->GetActivationDecisionForLastCommittedPageLoad());
- tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix,
- 0);
- tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0);
+ ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", std::string(),
+ tester());
+ ExpectSampleForSuffix("PhishingInterstitial", std::string(), tester());
+ ExpectSampleForSuffix("SubresourceFilterOnly", std::string(), tester());
+ tester().ExpectTotalCount(kNavigationChainSize + suffix, 0);
}
-TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
ListMatchedAfterRedirect_Activation) {
+ const ActivationListTestData& test_data = GetParam();
const GURL url(kURL);
- ConfigureAsSubresourceFilterOnlyURL(GURL(kRedirectURL));
- CreateTestNavigationForMainFrame(url);
- SimulateStartAndExpectProceed();
+ const std::string suffix(GetSuffixForList(test_data.activation_list_type));
+ ConfigureForMatchParam(GURL(kRedirectURL));
+ SimulateStartAndExpectProceed(url);
SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
SimulateCommitAndExpectProceed();
- EXPECT_EQ(
- ContentSubresourceFilterDriverFactory::ActivationDecision::ACTIVATED,
- factory()->GetActivationDecisionForLastCommittedPageLoad());
- tester().ExpectUniqueSample(
- kMatchesPatternHistogramNameSubresourceFilterSuffix, F0M0L1, 1);
- tester().ExpectUniqueSample(kNavigationChainSizeSubresourceFilterSuffix, 2,
- 1);
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ tester().ExpectUniqueSample(kNavigationChainSize + suffix, 2, 1);
+ ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", suffix, tester());
+ ExpectSampleForSuffix("PhishingInterstitial", suffix, tester());
+ ExpectSampleForSuffix("SubresourceFilterOnly", suffix, tester());
}
-TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
ListNotMatchedAndTimeout_NoActivation) {
+ const ActivationListTestData& test_data = GetParam();
const GURL url(kURL);
+ const std::string suffix(GetSuffixForList(test_data.activation_list_type));
SimulateTimeout();
- CreateTestNavigationForMainFrame(url);
- SimulateStartAndExpectProceed();
+ SimulateStartAndExpectProceed(url);
+
+ // Flush the pending tasks on the IO thread, so the delayed task surely gets
+ // posted.
+ test_io_task_runner()->RunUntilIdle();
+
+ // Expect one delayed task, and fast forward time.
+ base::TimeDelta expected_delay =
+ SubresourceFilterSafeBrowsingClientRequest::kCheckURLTimeout;
+ EXPECT_EQ(expected_delay, test_io_task_runner()->NextPendingTaskDelay());
+ test_io_task_runner()->FastForwardBy(expected_delay);
SimulateCommitAndExpectProceed();
- EXPECT_EQ(ContentSubresourceFilterDriverFactory::ActivationDecision::
- ACTIVATION_LIST_NOT_MATCHED,
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
factory()->GetActivationDecisionForLastCommittedPageLoad());
tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix,
0);
tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelay, 1);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelayNoSpeculation, 1);
+ tester().ExpectTotalCount(kSafeBrowsingCheckTime, 1);
+}
+
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
+ ListMatchedOnStart_NoDelay) {
+ const ActivationListTestData& test_data = GetParam();
+ const GURL url(kURL);
+ ConfigureForMatchParam(url);
+ SimulateStartAndExpectProceed(url);
+
+ // Get the database result back before commit.
+ RunUntilIdle();
+
+ SimulateCommitAndExpectProceed();
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ const std::string suffix(GetSuffixForList(test_data.activation_list_type));
+ ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", suffix, tester());
+ ExpectSampleForSuffix("PhishingInterstitial", suffix, tester());
+ ExpectSampleForSuffix("SubresourceFilterOnly", suffix, tester());
+ tester().ExpectUniqueSample(kNavigationChainSize + suffix, 1, 1);
+
+ tester().ExpectTimeBucketCount(kSafeBrowsingNavigationDelay,
+ base::TimeDelta::FromMilliseconds(0), 1);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelayNoSpeculation, 1);
+}
+
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
+ ListMatchedOnRedirect_NoDelay) {
+ const ActivationListTestData& test_data = GetParam();
+ const GURL url(kURL);
+ const GURL redirect_url(kRedirectURL);
+ ConfigureForMatchParam(redirect_url);
+
+ SimulateStartAndExpectProceed(url);
+ SimulateRedirectAndExpectProceed(redirect_url);
+
+ // Get the database result back before commit.
+ RunUntilIdle();
+
+ SimulateCommitAndExpectProceed();
+ EXPECT_EQ(ActivationDecision::ACTIVATED,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ const std::string suffix(GetSuffixForList(test_data.activation_list_type));
+ ExpectSampleForSuffix("SocialEngineeringAdsInterstitial", suffix, tester());
+ ExpectSampleForSuffix("PhishingInterstitial", suffix, tester());
+ ExpectSampleForSuffix("SubresourceFilterOnly", suffix, tester());
+ tester().ExpectUniqueSample(kNavigationChainSize + suffix, 2, 1);
+
+ tester().ExpectTimeBucketCount(kSafeBrowsingNavigationDelay,
+ base::TimeDelta::FromMilliseconds(0), 1);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelayNoSpeculation, 1);
+ tester().ExpectTotalCount(kSafeBrowsingCheckTime, 2);
}
-// TODO(melandory): Once non-defering check in WillStart is implemented add one
-// more test that destroys the Navigation along with corresponding throttles
-// while the SB check is pending? (To be run by ASAN bots to ensure
-// no use-after-free.)
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
+ ListMatchedOnStartWithRedirect_NoActivation) {
+ const GURL url(kURL);
+ const GURL redirect_url(kRedirectURL);
+ ConfigureForMatchParam(url);
+
+ // These two lines also test how the database client reacts to two requests
+ // happening one after another.
+ SimulateStartAndExpectProceed(url);
+ SimulateRedirectAndExpectProceed(redirect_url);
+
+ // Get the database result back before commit.
+ RunUntilIdle();
+
+ SimulateCommitAndExpectProceed();
+ EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
+ factory()->GetActivationDecisionForLastCommittedPageLoad());
+ tester().ExpectTotalCount(kMatchesPatternHistogramNameSubresourceFilterSuffix,
+ 0);
+ tester().ExpectTotalCount(kNavigationChainSizeSubresourceFilterSuffix, 0);
+ tester().ExpectTimeBucketCount(kSafeBrowsingNavigationDelay,
+ base::TimeDelta::FromMilliseconds(0), 1);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelayNoSpeculation, 1);
+}
+
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
+ RedirectPatternTest) {
+ struct RedirectRedirectChainMatchPatternTestData {
+ std::vector<bool> blacklisted_urls;
+ std::vector<GURL> navigation_chain;
+ } kRedirectRecordedHistogramsTestData[] = {
+ {{false}, {GURL(kUrlA)}},
+ {{true}, {GURL(kUrlA)}},
+ {{false, false}, {GURL(kUrlA), GURL(kUrlB)}},
+ {{false, true}, {GURL(kUrlA), GURL(kUrlB)}},
+ {{true, false}, {GURL(kUrlA), GURL(kUrlB)}},
+ {{true, true}, {GURL(kUrlA), GURL(kUrlB)}},
+ {{false, false, false}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{false, false, true}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{false, true, false}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{false, true, true}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{true, false, false}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{true, false, true}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{true, true, false}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{true, true, true}, {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC)}},
+ {{false, true, false, false},
+ {GURL(kUrlA), GURL(kUrlB), GURL(kUrlC), GURL(kUrlD)}},
+ };
+
+ for (const auto& test_data : kRedirectRecordedHistogramsTestData) {
+ base::HistogramTester histogram_tester;
+ ClearAllBlacklistedUrls();
+ auto it = test_data.navigation_chain.begin();
+ for (size_t i = 0u; i < test_data.blacklisted_urls.size(); ++i) {
+ if (test_data.blacklisted_urls[i])
+ ConfigureForMatchParam(test_data.navigation_chain[i]);
+ }
+ SimulateStartAndExpectProceed(*it);
+ for (++it; it != test_data.navigation_chain.end(); ++it)
+ SimulateRedirectAndExpectProceed(*it);
+ SimulateCommitAndExpectProceed();
+
+ // Verify histograms
+ const std::string suffix_param(
+ GetSuffixForList(GetParam().activation_list_type));
+ auto check_histogram = [&](std::string suffix) {
+ bool matches =
+ suffix == suffix_param && test_data.blacklisted_urls.back();
+ histogram_tester.ExpectBucketCount(kMatchesPatternHistogramName + suffix,
+ matches, 1);
+
+ if (matches) {
+ histogram_tester.ExpectBucketCount(kNavigationChainSize + suffix,
+ test_data.navigation_chain.size(),
+ 1);
+ } else {
+ histogram_tester.ExpectTotalCount(kNavigationChainSize + suffix, 0);
+ }
+ };
+
+ check_histogram("SocialEngineeringAdsInterstitial");
+ check_histogram("PhishingInterstitial");
+ check_histogram("SubresourceFilterOnly");
+ }
+}
+
+TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling,
+ Cancel) {
+ const GURL url(kURL);
+ SCOPED_TRACE(::testing::Message() << "CancelTime: " << cancel_time()
+ << " ResultSynchrony: " << result_sync());
+ ConfigureForMatch(url);
+ content::NavigationThrottle::ThrottleCheckResult result =
+ SimulateStart(url, main_rfh());
+ if (cancel_time() ==
+ content::CancellingNavigationThrottle::WILL_START_REQUEST) {
+ EXPECT_EQ(content::NavigationThrottle::CANCEL, result);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelay, 0);
+ return;
+ }
+ EXPECT_EQ(content::NavigationThrottle::PROCEED, result);
+
+ result = SimulateRedirect(GURL(kRedirectURL));
+ if (cancel_time() ==
+ content::CancellingNavigationThrottle::WILL_REDIRECT_REQUEST) {
+ EXPECT_EQ(content::NavigationThrottle::CANCEL, result);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelay, 0);
+ return;
+ }
+ EXPECT_EQ(content::NavigationThrottle::PROCEED, result);
+
+ base::RunLoop().RunUntilIdle();
+
+ result = SimulateCommit(navigation_simulator());
+ EXPECT_EQ(content::NavigationThrottle::CANCEL, result);
+ tester().ExpectTotalCount(kSafeBrowsingNavigationDelay, 0);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ CancelMethod,
+ SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling,
+ ::testing::Combine(
+ ::testing::Values(
+ content::CancellingNavigationThrottle::WILL_START_REQUEST,
+ content::CancellingNavigationThrottle::WILL_REDIRECT_REQUEST,
+ content::CancellingNavigationThrottle::WILL_PROCESS_RESPONSE),
+ ::testing::Values(
+ content::CancellingNavigationThrottle::SYNCHRONOUS,
+ content::CancellingNavigationThrottle::ASYNCHRONOUS)));
+
+INSTANTIATE_TEST_CASE_P(
+ ActivationLevelTest,
+ SubresourceFilterSafeBrowsingActivationThrottleParamTest,
+ ::testing::ValuesIn(kActivationListTestData));
+
+INSTANTIATE_TEST_CASE_P(
+ ActivationScopeTest,
+ SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
+ ::testing::ValuesIn(kActivationScopeTestData));
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc
new file mode 100644
index 00000000000..d5bc6a7cc97
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.cc
@@ -0,0 +1,59 @@
+// Copyright 2017 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/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
+#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h"
+#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace subresource_filter {
+
+SubresourceFilterSafeBrowsingClient::SubresourceFilterSafeBrowsingClient(
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
+ base::WeakPtr<SubresourceFilterSafeBrowsingActivationThrottle> throttle,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> throttle_task_runner)
+ : database_manager_(std::move(database_manager)),
+ throttle_(std::move(throttle)),
+ io_task_runner_(std::move(io_task_runner)),
+ throttle_task_runner_(std::move(throttle_task_runner)) {}
+
+SubresourceFilterSafeBrowsingClient::~SubresourceFilterSafeBrowsingClient() {}
+
+void SubresourceFilterSafeBrowsingClient::CheckUrlOnIO(const GURL& url,
+ size_t request_id) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK(!url.is_empty());
+
+ auto request = base::MakeUnique<SubresourceFilterSafeBrowsingClientRequest>(
+ url, request_id, database_manager_, io_task_runner_, this);
+ auto* raw_request = request.get();
+ DCHECK(requests_.find(raw_request) == requests_.end());
+ requests_[raw_request] = std::move(request);
+ raw_request->Start();
+ // Careful, |raw_request| can be destroyed after this line.
+}
+
+void SubresourceFilterSafeBrowsingClient::OnCheckBrowseUrlResult(
+ SubresourceFilterSafeBrowsingClientRequest* request,
+ const CheckResult& check_result) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ throttle_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&SubresourceFilterSafeBrowsingActivationThrottle::
+ OnCheckUrlResultOnUI,
+ throttle_, check_result));
+
+ DCHECK(requests_.find(request) != requests_.end());
+ requests_.erase(request);
+}
+
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h
new file mode 100644
index 00000000000..96929ac751a
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h
@@ -0,0 +1,80 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_CLIENT_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_CLIENT_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "components/safe_browsing_db/util.h"
+#include "components/safe_browsing_db/v4_local_database_manager.h"
+
+class GURL;
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace subresource_filter {
+
+class SubresourceFilterSafeBrowsingActivationThrottle;
+class SubresourceFilterSafeBrowsingClientRequest;
+
+// Created on the UI thread but used on the IO thread to communicate with the
+// safe browsing service.
+//
+// The class is expected to accompany a single navigation, and can maintain many
+// database requests. It will cancel any outgoing requests when it is destroyed.
+class SubresourceFilterSafeBrowsingClient {
+ public:
+ struct CheckResult {
+ size_t request_id = 0;
+ safe_browsing::SBThreatType threat_type =
+ safe_browsing::SBThreatType::SB_THREAT_TYPE_SAFE;
+ safe_browsing::ThreatPatternType pattern_type =
+ safe_browsing::ThreatPatternType::NONE;
+ base::TimeDelta check_time;
+ bool finished = false;
+ };
+
+ SubresourceFilterSafeBrowsingClient(
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+ database_manager,
+ base::WeakPtr<SubresourceFilterSafeBrowsingActivationThrottle> throttle,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> throttle_task_runner);
+
+ ~SubresourceFilterSafeBrowsingClient();
+
+ void CheckUrlOnIO(const GURL& url, size_t request_id);
+
+ void OnCheckBrowseUrlResult(
+ SubresourceFilterSafeBrowsingClientRequest* request,
+ const CheckResult& check_result);
+
+ private:
+ // This is stored as a map to allow for ergonomic deletion.
+ base::flat_map<SubresourceFilterSafeBrowsingClientRequest*,
+ std::unique_ptr<SubresourceFilterSafeBrowsingClientRequest>>
+ requests_;
+
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
+
+ base::WeakPtr<SubresourceFilterSafeBrowsingActivationThrottle> throttle_;
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> throttle_task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(SubresourceFilterSafeBrowsingClient);
+};
+
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_CLIENT_H_
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc
new file mode 100644
index 00000000000..a7b477838eb
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.cc
@@ -0,0 +1,101 @@
+// Copyright 2017 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/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/single_thread_task_runner.h"
+#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace subresource_filter {
+
+constexpr base::TimeDelta
+ SubresourceFilterSafeBrowsingClientRequest::kCheckURLTimeout;
+
+SubresourceFilterSafeBrowsingClientRequest::
+ SubresourceFilterSafeBrowsingClientRequest(
+ const GURL& url,
+ size_t request_id,
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+ database_manager,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ SubresourceFilterSafeBrowsingClient* client)
+ : url_(url),
+ request_id_(request_id),
+ database_manager_(std::move(database_manager)),
+ client_(client) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ timer_.SetTaskRunner(std::move(io_task_runner));
+}
+
+SubresourceFilterSafeBrowsingClientRequest::
+ ~SubresourceFilterSafeBrowsingClientRequest() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ if (!request_completed_)
+ database_manager_->CancelCheck(this);
+ timer_.Stop();
+}
+
+void SubresourceFilterSafeBrowsingClientRequest::Start() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ start_time_ = base::TimeTicks::Now();
+ if (database_manager_->CheckUrlForSubresourceFilter(url_, this)) {
+ SendCheckResultToClient(false /* served_from_network */,
+ safe_browsing::SB_THREAT_TYPE_SAFE,
+ safe_browsing::ThreatMetadata());
+ return;
+ }
+ timer_.Start(
+ FROM_HERE, kCheckURLTimeout,
+ base::Bind(&SubresourceFilterSafeBrowsingClientRequest::OnCheckUrlTimeout,
+ base::Unretained(this)));
+}
+
+void SubresourceFilterSafeBrowsingClientRequest::OnCheckBrowseUrlResult(
+ const GURL& url,
+ safe_browsing::SBThreatType threat_type,
+ const safe_browsing::ThreatMetadata& metadata) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK_EQ(url_, url);
+ request_completed_ = true;
+ SendCheckResultToClient(true /* served_from_network */, threat_type,
+ metadata);
+}
+
+void SubresourceFilterSafeBrowsingClientRequest::OnCheckUrlTimeout() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ SendCheckResultToClient(true /* served_from_network */,
+ safe_browsing::SB_THREAT_TYPE_SAFE,
+ safe_browsing::ThreatMetadata());
+}
+
+void SubresourceFilterSafeBrowsingClientRequest::SendCheckResultToClient(
+ bool served_from_network,
+ safe_browsing::SBThreatType threat_type,
+ const safe_browsing::ThreatMetadata& metadata) {
+ SubresourceFilterSafeBrowsingClient::CheckResult result;
+ result.request_id = request_id_;
+ result.threat_type = threat_type;
+ result.pattern_type = metadata.threat_pattern_type;
+ result.check_time = base::TimeTicks::Now() - start_time_;
+
+ // This memeber is separate from |request_completed_|, in that it just
+ // indicates that this request is done processing (due to completion or
+ // timeout).
+ result.finished = true;
+
+ UMA_HISTOGRAM_TIMES("SubresourceFilter.SafeBrowsing.CheckTime",
+ result.check_time);
+ // Will delete |this|.
+ client_->OnCheckBrowseUrlResult(this, result);
+}
+
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h
new file mode 100644
index 00000000000..ef8bf14b5c1
--- /dev/null
+++ b/chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h
@@ -0,0 +1,95 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_CLIENT_REQUEST_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_CLIENT_REQUEST_H_
+
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "components/safe_browsing_db/database_manager.h"
+#include "components/safe_browsing_db/util.h"
+#include "components/safe_browsing_db/v4_local_database_manager.h"
+#include "url/gurl.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace safe_browsing {
+struct ThreatMetadata;
+} // namespace safe_browsing
+
+namespace subresource_filter {
+
+class SubresourceFilterSafeBrowsingClient;
+
+// This class is scoped to a single database check, and it lives on the IO
+// thread exclusively.
+class SubresourceFilterSafeBrowsingClientRequest
+ : public safe_browsing::SafeBrowsingDatabaseManager::Client {
+ public:
+ SubresourceFilterSafeBrowsingClientRequest(
+ const GURL& url,
+ size_t request_id,
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+ database_manager,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ SubresourceFilterSafeBrowsingClient* client);
+ ~SubresourceFilterSafeBrowsingClientRequest() override;
+
+ void Start();
+
+ // safe_browsing::SafeBrowsingDatabaseManager::Client:
+ void OnCheckBrowseUrlResult(
+ const GURL& url,
+ safe_browsing::SBThreatType threat_type,
+ const safe_browsing::ThreatMetadata& metadata) override;
+
+ const GURL& url() const { return url_; }
+ size_t request_id() const { return request_id_; }
+
+ // Maximum time in milliseconds to wait for the Safe Browsing service to
+ // verify a URL. After this amount of time the outstanding check will be
+ // aborted, and the URL will be treated as if it didn't belong to the
+ // Subresource Filter only list.
+ static constexpr base::TimeDelta kCheckURLTimeout =
+ base::TimeDelta::FromSeconds(5);
+
+ private:
+ // Callback for when the safe browsing check has taken longer than
+ // kCheckURLTimeout.
+ void OnCheckUrlTimeout();
+
+ void SendCheckResultToClient(bool served_from_network,
+ safe_browsing::SBThreatType threat_type,
+ const safe_browsing::ThreatMetadata& metadata);
+
+ const GURL url_;
+
+ // The |request_id_| identifies a particular request, as issued from the
+ // SubresourceFilterSafeBrowsingClient. It will be unique in the scope of a
+ // single navigation (i.e. the scope of the
+ // SubresourceFilterSafeBrowsingClient).
+ const size_t request_id_;
+
+ scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
+ SubresourceFilterSafeBrowsingClient* client_ = nullptr;
+
+ // Timer to abort the safe browsing check if it takes too long.
+ base::OneShotTimer timer_;
+
+ base::TimeTicks start_time_;
+
+ bool request_completed_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(SubresourceFilterSafeBrowsingClientRequest);
+};
+
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_SAFE_BROWSING_CLIENT_REQUEST_H_
diff --git a/chromium/components/subresource_filter/content/common/subresource_filter_messages.h b/chromium/components/subresource_filter/content/common/subresource_filter_messages.h
index bef8fc95b23..c8333c09a8e 100644
--- a/chromium/components/subresource_filter/content/common/subresource_filter_messages.h
+++ b/chromium/components/subresource_filter/content/common/subresource_filter_messages.h
@@ -24,6 +24,7 @@ IPC_STRUCT_TRAITS_BEGIN(subresource_filter::ActivationState)
IPC_STRUCT_TRAITS_MEMBER(filtering_disabled_for_document)
IPC_STRUCT_TRAITS_MEMBER(generic_blocking_rules_disabled)
IPC_STRUCT_TRAITS_MEMBER(measure_performance)
+ IPC_STRUCT_TRAITS_MEMBER(enable_logging)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(subresource_filter::DocumentLoadStatistics)
diff --git a/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.cc b/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.cc
index 80a57c64b6b..de17ed654bc 100644
--- a/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.cc
+++ b/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.cc
@@ -118,6 +118,10 @@ void WebDocumentSubresourceFilterImpl::ReportDisallowedLoad() {
std::move(first_disallowed_load_callback_).Run();
}
+bool WebDocumentSubresourceFilterImpl::ShouldLogToConsole() {
+ return filter_.activation_state().enable_logging;
+}
+
WebLoadPolicy WebDocumentSubresourceFilterImpl::getLoadPolicyImpl(
const blink::WebURL& url,
proto::ElementType element_type) {
diff --git a/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.h b/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.h
index 686a81e0752..9722aa46814 100644
--- a/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.h
+++ b/chromium/components/subresource_filter/content/renderer/web_document_subresource_filter_impl.h
@@ -41,6 +41,7 @@ class WebDocumentSubresourceFilterImpl
LoadPolicy GetLoadPolicyForWebSocketConnect(
const blink::WebURL& url) override;
void ReportDisallowedLoad() override;
+ bool ShouldLogToConsole() override;
private:
LoadPolicy getLoadPolicyImpl(const blink::WebURL& url,
diff --git a/chromium/components/subresource_filter/core/browser/BUILD.gn b/chromium/components/subresource_filter/core/browser/BUILD.gn
index d61c1c048b9..2e3e756b118 100644
--- a/chromium/components/subresource_filter/core/browser/BUILD.gn
+++ b/chromium/components/subresource_filter/core/browser/BUILD.gn
@@ -51,6 +51,7 @@ source_set("unit_tests") {
"//components/prefs:test_support",
"//components/subresource_filter/core/common:test_support",
"//components/subresource_filter/core/common/proto",
+ "//components/variations",
"//testing/gmock",
"//testing/gtest",
"//third_party/protobuf:protobuf_lite",
diff --git a/chromium/components/subresource_filter/core/browser/subresource_filter_constants.cc b/chromium/components/subresource_filter/core/browser/subresource_filter_constants.cc
index dbc9e0999c0..a1bee67ca17 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_constants.cc
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_constants.cc
@@ -30,4 +30,8 @@ const base::FilePath::CharType kUnindexedRulesetLicenseFileName[] =
const base::FilePath::CharType kUnindexedRulesetDataFileName[] =
FILE_PATH_LITERAL("Filtering Rules");
+// TODO(shivanisha): Update the string when finalized.
+const std::string kActivationConsoleMessage =
+ "Subresource filter is activated on this site";
+
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/browser/subresource_filter_constants.h b/chromium/components/subresource_filter/core/browser/subresource_filter_constants.h
index d78b18fdda4..ce2ba436d36 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_constants.h
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_constants.h
@@ -47,6 +47,9 @@ extern const base::FilePath::CharType kUnindexedRulesetLicenseFileName[];
// The name of the file that stores the unindexed filtering rules.
extern const base::FilePath::CharType kUnindexedRulesetDataFileName[];
+// Console message to be displayed on activation.
+extern const std::string kActivationConsoleMessage;
+
} // namespace subresource_filter
#endif // COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_CONSTANTS_H_
diff --git a/chromium/components/subresource_filter/core/browser/subresource_filter_features.cc b/chromium/components/subresource_filter/core/browser/subresource_filter_features.cc
index 2ad875eaf25..6621c922404 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_features.cc
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_features.cc
@@ -4,19 +4,53 @@
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
+#include <map>
+#include <ostream>
+#include <sstream>
#include <string>
+#include <tuple>
+#include <utility>
+#include "base/lazy_instance.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/synchronization/lock.h"
+#include "base/trace_event/trace_event_argument.h"
#include "components/variations/variations_associated_data.h"
namespace subresource_filter {
namespace {
+// Helpers --------------------------------------------------------------------
+
+class CommaSeparatedStrings {
+ public:
+ CommaSeparatedStrings(std::string comma_separated_strings)
+ : backing_string_(comma_separated_strings),
+ pieces_(base::SplitStringPiece(backing_string_,
+ ",",
+ base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY)) {}
+
+ bool CaseInsensitiveContains(base::StringPiece lowercase_key) const {
+ const auto predicate = [lowercase_key](base::StringPiece element) {
+ return base::LowerCaseEqualsASCII(element, lowercase_key);
+ };
+ return std::find_if(pieces_.begin(), pieces_.end(), predicate) !=
+ pieces_.end();
+ }
+
+ private:
+ const std::string backing_string_;
+ const std::vector<base::StringPiece> pieces_;
+
+ DISALLOW_COPY_AND_ASSIGN(CommaSeparatedStrings);
+};
+
std::string TakeVariationParamOrReturnEmpty(
std::map<std::string, std::string>* params,
const std::string& key) {
@@ -45,30 +79,26 @@ ActivationScope ParseActivationScope(const base::StringPiece activation_scope) {
return ActivationScope::NO_SITES;
}
-ActivationList ParseActivationList(const base::StringPiece activation_lists) {
+ActivationList ParseActivationList(std::string activation_lists_string) {
ActivationList activation_list_type = ActivationList::NONE;
- for (const base::StringPiece& activation_list :
- base::SplitStringPiece(activation_lists, ",", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY)) {
- if (base::LowerCaseEqualsASCII(activation_list,
- kActivationListPhishingInterstitial)) {
- return ActivationList::PHISHING_INTERSTITIAL;
- } else if (base::LowerCaseEqualsASCII(
- activation_list,
- kActivationListSocialEngineeringAdsInterstitial)) {
- activation_list_type = ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL;
- } else if (base::LowerCaseEqualsASCII(activation_list,
- kActivationListSubresourceFilter)) {
- activation_list_type = ActivationList::SUBRESOURCE_FILTER;
- }
+ CommaSeparatedStrings activation_lists(std::move(activation_lists_string));
+ if (activation_lists.CaseInsensitiveContains(
+ kActivationListPhishingInterstitial)) {
+ return ActivationList::PHISHING_INTERSTITIAL;
+ } else if (activation_lists.CaseInsensitiveContains(
+ kActivationListSocialEngineeringAdsInterstitial)) {
+ activation_list_type = ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL;
+ } else if (activation_lists.CaseInsensitiveContains(
+ kActivationListSubresourceFilter)) {
+ activation_list_type = ActivationList::SUBRESOURCE_FILTER;
}
return activation_list_type;
}
double ParsePerformanceMeasurementRate(const std::string& rate) {
- double value = 0;
+ double value = 0.0;
if (!base::StringToDouble(rate, &value) || value < 0)
- return 0;
+ return 0.0;
return value < 1 ? value : 1;
}
@@ -76,8 +106,130 @@ bool ParseBool(const base::StringPiece value) {
return base::LowerCaseEqualsASCII(value, "true");
}
+int ParseInt(const base::StringPiece value) {
+ int result = 0;
+ base::StringToInt(value, &result);
+ return result;
+}
+
+std::vector<Configuration> FillEnabledPresetConfigurations(
+ std::map<std::string, std::string>* params) {
+ const struct {
+ const char* name;
+ bool enabled_by_default;
+ Configuration (*factory_method)();
+ } kAvailablePresetConfigurations[] = {
+ {kPresetLiveRunOnPhishingSites, false,
+ &Configuration::MakePresetForLiveRunOnPhishingSites},
+ {kPresetPerformanceTestingDryRunOnAllSites, false,
+ &Configuration::MakePresetForPerformanceTestingDryRunOnAllSites}};
+
+ CommaSeparatedStrings enabled_presets(
+ TakeVariationParamOrReturnEmpty(params, kEnablePresetsParameterName));
+ CommaSeparatedStrings disabled_presets(
+ TakeVariationParamOrReturnEmpty(params, kDisablePresetsParameterName));
+
+ std::vector<Configuration> enabled_configurations;
+ for (const auto& available_preset : kAvailablePresetConfigurations) {
+ if ((enabled_presets.CaseInsensitiveContains(available_preset.name) ||
+ available_preset.enabled_by_default) &&
+ !disabled_presets.CaseInsensitiveContains(available_preset.name)) {
+ enabled_configurations.push_back(available_preset.factory_method());
+ }
+ }
+
+ return enabled_configurations;
+}
+
+Configuration ParseExperimentalConfiguration(
+ std::map<std::string, std::string>* params) {
+ Configuration configuration;
+
+ // ActivationConditions:
+ configuration.activation_conditions.activation_scope = ParseActivationScope(
+ TakeVariationParamOrReturnEmpty(params, kActivationScopeParameterName));
+
+ configuration.activation_conditions.activation_list = ParseActivationList(
+ TakeVariationParamOrReturnEmpty(params, kActivationListsParameterName));
+
+ configuration.activation_conditions.priority =
+ ParseInt(TakeVariationParamOrReturnEmpty(
+ params, kActivationPriorityParameterName));
+
+ // ActivationOptions:
+ configuration.activation_options.activation_level = ParseActivationLevel(
+ TakeVariationParamOrReturnEmpty(params, kActivationLevelParameterName));
+
+ configuration.activation_options.performance_measurement_rate =
+ ParsePerformanceMeasurementRate(TakeVariationParamOrReturnEmpty(
+ params, kPerformanceMeasurementRateParameterName));
+
+ configuration.activation_options.should_suppress_notifications =
+ ParseBool(TakeVariationParamOrReturnEmpty(
+ params, kSuppressNotificationsParameterName));
+
+ configuration.activation_options.should_whitelist_site_on_reload =
+ ParseBool(TakeVariationParamOrReturnEmpty(
+ params, kWhitelistSiteOnReloadParameterName));
+
+ // GeneralSettings:
+ configuration.general_settings.ruleset_flavor =
+ TakeVariationParamOrReturnEmpty(params, kRulesetFlavorParameterName);
+
+ return configuration;
+}
+
+std::vector<Configuration> ParseEnabledConfigurations() {
+ std::map<std::string, std::string> params;
+ base::GetFieldTrialParamsByFeature(kSafeBrowsingSubresourceFilter, &params);
+
+ std::vector<Configuration> configs = FillEnabledPresetConfigurations(&params);
+
+ Configuration experimental_config = ParseExperimentalConfiguration(&params);
+ configs.push_back(std::move(experimental_config));
+
+ return configs;
+}
+
+template <class T>
+std::string StreamToString(const T& value) {
+ std::ostringstream oss;
+ oss << value;
+ return oss.str();
+}
+
+std::vector<Configuration> SortConfigsByDecreasingPriority(
+ std::vector<Configuration> configs) {
+ auto comp = [](const Configuration& a, const Configuration& b) {
+ return a.activation_conditions.priority > b.activation_conditions.priority;
+ };
+ std::sort(configs.begin(), configs.end(), comp);
+ return configs;
+}
+
+base::StringPiece GetLexicographicallyGreatestRulesetFlavor(
+ const std::vector<Configuration>& configs) {
+ base::StringPiece greatest_flavor;
+ for (const auto& config : configs) {
+ base::StringPiece flavor = config.general_settings.ruleset_flavor;
+ if (flavor > greatest_flavor)
+ greatest_flavor = flavor;
+ }
+ return greatest_flavor;
+}
+
+// Globals --------------------------------------------------------------------
+
+base::LazyInstance<base::Lock>::Leaky g_active_configurations_lock =
+ LAZY_INSTANCE_INITIALIZER;
+
+base::LazyInstance<scoped_refptr<ConfigurationList>>::Leaky
+ g_active_configurations = LAZY_INSTANCE_INITIALIZER;
+
} // namespace
+// Constant definitions -------------------------------------------------------
+
const base::Feature kSafeBrowsingSubresourceFilter{
"SubresourceFilter", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -101,51 +253,122 @@ const char kActivationListSocialEngineeringAdsInterstitial[] =
const char kActivationListPhishingInterstitial[] = "phishing_interstitial";
const char kActivationListSubresourceFilter[] = "subresource_filter";
-const char kRulesetFlavorParameterName[] = "ruleset_flavor";
+const char kActivationPriorityParameterName[] = "activation_priority";
const char kPerformanceMeasurementRateParameterName[] =
"performance_measurement_rate";
-
const char kSuppressNotificationsParameterName[] = "suppress_notifications";
-
const char kWhitelistSiteOnReloadParameterName[] = "whitelist_site_on_reload";
-Configuration::Configuration() = default;
-Configuration::~Configuration() = default;
-Configuration::Configuration(Configuration&&) = default;
-Configuration& Configuration::operator=(Configuration&&) = default;
-
-Configuration GetActiveConfiguration() {
- Configuration active_configuration;
+const char kRulesetFlavorParameterName[] = "ruleset_flavor";
- std::map<std::string, std::string> params;
- base::GetFieldTrialParamsByFeature(kSafeBrowsingSubresourceFilter, &params);
+const char kEnablePresetsParameterName[] = "enable_presets";
+const char kDisablePresetsParameterName[] = "disable_presets";
+const char kPresetLiveRunOnPhishingSites[] = "liverun_on_phishing_sites";
+const char kPresetPerformanceTestingDryRunOnAllSites[] =
+ "performance_testing_dryrun_on_all_sites";
+
+// Configuration --------------------------------------------------------------
+
+// static
+Configuration Configuration::MakePresetForLiveRunOnPhishingSites() {
+ Configuration config(ActivationLevel::ENABLED,
+ ActivationScope::ACTIVATION_LIST,
+ ActivationList::PHISHING_INTERSTITIAL);
+ config.activation_conditions.priority = 1000;
+ return config;
+}
- active_configuration.activation_level = ParseActivationLevel(
- TakeVariationParamOrReturnEmpty(&params, kActivationLevelParameterName));
+// static
+Configuration Configuration::MakePresetForPerformanceTestingDryRunOnAllSites() {
+ Configuration config(ActivationLevel::DRYRUN, ActivationScope::ALL_SITES);
+ config.activation_options.performance_measurement_rate = 1.0;
+ config.activation_conditions.priority = 500;
+ return config;
+}
- active_configuration.activation_scope = ParseActivationScope(
- TakeVariationParamOrReturnEmpty(&params, kActivationScopeParameterName));
+Configuration::Configuration() = default;
+Configuration::Configuration(ActivationLevel activation_level,
+ ActivationScope activation_scope,
+ ActivationList activation_list) {
+ activation_options.activation_level = activation_level;
+ activation_conditions.activation_scope = activation_scope;
+ activation_conditions.activation_list = activation_list;
+}
+Configuration::Configuration(const Configuration&) = default;
+Configuration::Configuration(Configuration&&) = default;
+Configuration::~Configuration() = default;
+Configuration& Configuration::operator=(const Configuration&) = default;
+Configuration& Configuration::operator=(Configuration&&) = default;
- active_configuration.activation_list = ParseActivationList(
- TakeVariationParamOrReturnEmpty(&params, kActivationListsParameterName));
+bool Configuration::operator==(const Configuration& rhs) const {
+ const auto tie = [](const Configuration& config) {
+ return std::tie(config.activation_conditions.activation_scope,
+ config.activation_conditions.activation_list,
+ config.activation_conditions.priority,
+ config.activation_options.activation_level,
+ config.activation_options.performance_measurement_rate,
+ config.activation_options.should_whitelist_site_on_reload,
+ config.activation_options.should_suppress_notifications,
+ config.general_settings.ruleset_flavor);
+ };
+ return tie(*this) == tie(rhs);
+}
- active_configuration.performance_measurement_rate =
- ParsePerformanceMeasurementRate(TakeVariationParamOrReturnEmpty(
- &params, kPerformanceMeasurementRateParameterName));
+bool Configuration::operator!=(const Configuration& rhs) const {
+ return !(*this == rhs);
+}
- active_configuration.should_suppress_notifications =
- ParseBool(TakeVariationParamOrReturnEmpty(
- &params, kSuppressNotificationsParameterName));
+std::unique_ptr<base::trace_event::TracedValue> Configuration::ToTracedValue()
+ const {
+ auto value = base::MakeUnique<base::trace_event::TracedValue>();
+ value->SetString("activation_scope",
+ StreamToString(activation_conditions.activation_scope));
+ value->SetString("activation_list",
+ StreamToString(activation_conditions.activation_list));
+ value->SetInteger("priority", activation_conditions.priority);
+ value->SetString("activation_level",
+ StreamToString(activation_options.activation_level));
+ value->SetDouble("performance_measurement_rate",
+ activation_options.performance_measurement_rate);
+ value->SetBoolean("should_suppress_notifications",
+ activation_options.should_suppress_notifications);
+ value->SetBoolean("should_whitelist_site_on_reload",
+ activation_options.should_whitelist_site_on_reload);
+ value->SetString("ruleset_flavor",
+ StreamToString(general_settings.ruleset_flavor));
+ return value;
+}
- active_configuration.ruleset_flavor =
- TakeVariationParamOrReturnEmpty(&params, kRulesetFlavorParameterName);
+// ConfigurationList ----------------------------------------------------------
+
+ConfigurationList::ConfigurationList(std::vector<Configuration> configs)
+ : configs_by_decreasing_priority_(
+ SortConfigsByDecreasingPriority(std::move(configs))),
+ lexicographically_greatest_ruleset_flavor_(
+ GetLexicographicallyGreatestRulesetFlavor(
+ configs_by_decreasing_priority_)) {}
+ConfigurationList::~ConfigurationList() = default;
+
+scoped_refptr<ConfigurationList> GetEnabledConfigurations() {
+ base::AutoLock lock(g_active_configurations_lock.Get());
+ if (!g_active_configurations.Get()) {
+ g_active_configurations.Get() =
+ base::MakeRefCounted<ConfigurationList>(ParseEnabledConfigurations());
+ }
+ return g_active_configurations.Get();
+}
- active_configuration.should_whitelist_site_on_reload =
- ParseBool(TakeVariationParamOrReturnEmpty(
- &params, kWhitelistSiteOnReloadParameterName));
+namespace testing {
- return active_configuration;
+scoped_refptr<ConfigurationList> GetAndSetActivateConfigurations(
+ scoped_refptr<ConfigurationList> new_configs) {
+ base::AutoLock lock(g_active_configurations_lock.Get());
+ auto old_configs = std::move(g_active_configurations.Get());
+ g_active_configurations.Get() = std::move(new_configs);
+ return old_configs;
}
+} // namespace testing
+
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/browser/subresource_filter_features.h b/chromium/components/subresource_filter/core/browser/subresource_filter_features.h
index 9ac8d317cb6..a828a4ef778 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_features.h
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_features.h
@@ -5,56 +5,169 @@
#ifndef COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_FEATURES_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_FEATURES_H_
+#include <memory>
+#include <vector>
+
#include "base/feature_list.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_piece.h"
#include "components/subresource_filter/core/common/activation_level.h"
#include "components/subresource_filter/core/common/activation_list.h"
#include "components/subresource_filter/core/common/activation_scope.h"
+namespace base {
+namespace trace_event {
+class TracedValue;
+} // namespace trace_event
+} // namespace base
+
namespace subresource_filter {
-// Encapsulates all parameters that define how the subresource filter feature
-// should operate.
+// Encapsulates a set of parameters that define how the subresource filter
+// feature should operate. Each configuration consists of three parts as
+// described in detail below.
+//
+// There can be multiple configuration enabled at the same time. For each
+// navigation, however, subresource filtering will be activated according to
+// exactly one of these enabled configuration, if any. Namely, the configuration
+// with the highest |priority| among those whose |activation_conditions| are
+// otherwise satisfied for the navigation.
+//
+// Even when there are multiple enabled configurations, the RulesetService is
+// currently only capable of fetching and indexing a single |ruleset_flavor|,
+// which will be used for all navigations with subresource filtering activated,
+// regardless of which configuration prescribed filtering for that navigation.
+// This shared ruleset flavor will be the one lexicographically greatest.
+//
+// Experimenters wishing to use customized rulesets therefore must ensure that
+// they set up the experimental state so that the ruleset chosen through this
+// mechanism is compatible with all the enabled configurations (or disable some
+// as needed).
struct Configuration {
+ // The conditions that determine whether subresource filtering should be
+ // activated for a given main frame navigation using this configuration.
+ struct ActivationConditions {
+ // The activation scope. That is, the subset of page loads where subresource
+ // filtering should be activated according to this configuration. When set
+ // to NO_SITES, this configuration will never be active.
+ ActivationScope activation_scope = ActivationScope::NO_SITES;
+
+ // The activation list to use when the |activation_scope| is
+ // ACTIVATION_LIST, ignored otherwise.
+ ActivationList activation_list = ActivationList::NONE;
+
+ // The activation priority of this configuration. Used to break ties when
+ // there are multiple configurations whose activation conditions are
+ // otherwise satisfied. A greater value indicates higher priority.
+ int priority = 0;
+ };
+
+ // The details of how subresource filtering should operate for a given main
+ // frame navigation when it is activated using this configuration.
+ struct ActivationOptions {
+ // The maximum degree to which subresource filtering should be activated on
+ // any RenderFrame. When set to DISABLED, this configuration will cause
+ // subresource filtering to be de-activated for a navigation if this is the
+ // highest priority configuration with its activation conditions met.
+ ActivationLevel activation_level = ActivationLevel::DISABLED;
+
+ // A number in the range [0, 1], indicating the fraction of page loads that
+ // should have extended performance measurements enabled.
+ double performance_measurement_rate = 0.0;
+
+ // Whether notifications indicating that a subresource was disallowed should
+ // be suppressed in the UI.
+ bool should_suppress_notifications = false;
+
+ // Whether to whitelist a site when a page loaded from that site is
+ // reloaded.
+ bool should_whitelist_site_on_reload = false;
+ };
+
+ // General settings that apply outside of the scope of a navigation.
+ struct GeneralSettings {
+ // The ruleset flavor to download through the component updater. The empty
+ // string indicates that the default ruleset should be used.
+ std::string ruleset_flavor;
+ };
+
+ // Do not forget updating operator==, operator<<, and any other necessary
+ // methods when adding new fields here!
+
Configuration();
- ~Configuration();
+ Configuration(ActivationLevel activation_level,
+ ActivationScope activation_scope,
+ ActivationList activation_list = ActivationList::NONE);
+ Configuration(const Configuration&);
Configuration(Configuration&&);
+ ~Configuration();
+ Configuration& operator=(const Configuration&);
Configuration& operator=(Configuration&&);
- // The maximum degree to which subresource filtering should be activated on
- // any RenderFrame. This will be ActivationLevel::DISABLED unless the feature
- // is enabled and variation parameters prescribe a higher activation level.
- ActivationLevel activation_level = ActivationLevel::DISABLED;
-
- // The activation scope. That is, the subset of page loads where subresource
- // filtering should be activated. This will be ActivationScope::NO_SITES
- // unless the feature is =enabled and variation parameters prescribe a wider
- // activation scope.
- ActivationScope activation_scope = ActivationScope::NO_SITES;
-
- // The activation list to use when the |activation_scope| is ACTIVATION_LIST.
- // This will be ActivationList::NONE unless variation parameters prescribe a
- // recognized list.
- ActivationList activation_list = ActivationList::NONE;
-
- // A number in the range [0, 1], indicating the fraction of page loads that
- // should have extended performance measurements enabled. The rate will
- // be 0 unless a greater frequency is specified by variation parameters.
- double performance_measurement_rate = 0.0;
-
- // Whether notifications indicating that a subresource was disallowed should
- // be suppressed in the UI.
- bool should_suppress_notifications = false;
-
- // The ruleset flavor to download through the component updater, or the empty
- // string if the default ruleset should be used.
- std::string ruleset_flavor;
-
- // Whether to whitelist a site when a page loaded from that site is reloaded.
- bool should_whitelist_site_on_reload = false;
+ bool operator==(const Configuration& rhs) const;
+ bool operator!=(const Configuration& rhs) const;
+
+ std::unique_ptr<base::trace_event::TracedValue> ToTracedValue() const;
+
+ // Factory methods for preset configurations.
+ //
+ // To add a new preset:
+ // 1.) Define a named factory method here.
+ // 2.) Define a name for the configuration to be used in variation params.
+ // 3.) Register it into |kAvailablePresetConfigurations| in the .cc file.
+ // 4.) Update unittests to cover the new preset.
+ static Configuration MakePresetForLiveRunOnPhishingSites();
+ static Configuration MakePresetForPerformanceTestingDryRunOnAllSites();
+
+ ActivationConditions activation_conditions;
+ ActivationOptions activation_options;
+ GeneralSettings general_settings;
+};
+
+// Thread-safe, ref-counted wrapper around an immutable list of configurations.
+class ConfigurationList : public base::RefCountedThreadSafe<ConfigurationList> {
+ public:
+ explicit ConfigurationList(std::vector<Configuration> configs);
+
+ // Returns the lexicographically greatest flavor string that is prescribed by
+ // any of the configurations. The caller must hold a reference to this
+ // instance while using the returned string piece.
+ base::StringPiece lexicographically_greatest_ruleset_flavor() const {
+ return lexicographically_greatest_ruleset_flavor_;
+ }
+
+ // Retrieves the configurations pre-sorted in decreasing order of their
+ // |activation_condition.priority|.
+ const std::vector<Configuration>& configs_by_decreasing_priority() const {
+ return configs_by_decreasing_priority_;
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<ConfigurationList>;
+ ~ConfigurationList();
+
+ const std::vector<Configuration> configs_by_decreasing_priority_;
+ const base::StringPiece lexicographically_greatest_ruleset_flavor_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConfigurationList);
};
-// Retrieves the subresource filtering configuration to use. Expensive to call.
-Configuration GetActiveConfiguration();
+// Retrieves all currently enabled subresource filtering configurations. The
+// configurations are parsed on first access and then the result is cached.
+//
+// In tests, however, the config may be changed in-between navigations, so
+// callers should not hold on to the result for long.
+scoped_refptr<ConfigurationList> GetEnabledConfigurations();
+
+namespace testing {
+
+// Returns the currently cached enabled ConfigurationList, if any, and replaces
+// it with |new_configs|, which may be nullptr to clear the cache.
+scoped_refptr<ConfigurationList> GetAndSetActivateConfigurations(
+ scoped_refptr<ConfigurationList> new_configs);
+
+} // namespace testing
// Feature and variation parameter definitions -------------------------------
@@ -80,7 +193,7 @@ extern const char kActivationListSocialEngineeringAdsInterstitial[];
extern const char kActivationListPhishingInterstitial[];
extern const char kActivationListSubresourceFilter[];
-extern const char kRulesetFlavorParameterName[];
+extern const char kActivationPriorityParameterName[];
extern const char kPerformanceMeasurementRateParameterName[];
@@ -88,6 +201,13 @@ extern const char kSuppressNotificationsParameterName[];
extern const char kWhitelistSiteOnReloadParameterName[];
+extern const char kRulesetFlavorParameterName[];
+
+extern const char kEnablePresetsParameterName[];
+extern const char kDisablePresetsParameterName[];
+extern const char kPresetLiveRunOnPhishingSites[];
+extern const char kPresetPerformanceTestingDryRunOnAllSites[];
+
} // namespace subresource_filter
#endif // COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_FEATURES_H_
diff --git a/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc b/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc
index 16b8354e0e7..f14bc212dad 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc
@@ -4,71 +4,98 @@
#include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
-#include <map>
-#include <memory>
+#include <ostream>
+#include <utility>
-#include "base/metrics/field_trial.h"
-#include "base/metrics/field_trial_params.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
-#include "components/variations/variations_associated_data.h"
-#include "testing/gtest/include/gtest/gtest.h"
+#include "base/json/json_writer.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_util.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "base/values.h"
namespace subresource_filter {
namespace testing {
-namespace {
-constexpr const char kTestFieldTrialName[] = "FieldTrialNameShouldNotMatter";
-constexpr const char kTestExperimentGroupName[] = "GroupNameShouldNotMatter";
-} // namespace
+// ScopedSubresourceFilterConfigurator ----------------------------------------
+ScopedSubresourceFilterConfigurator::ScopedSubresourceFilterConfigurator(
+ scoped_refptr<ConfigurationList> configs_list)
+ : original_config_(GetAndSetActivateConfigurations(configs_list)) {}
+
+ScopedSubresourceFilterConfigurator::ScopedSubresourceFilterConfigurator(
+ Configuration config)
+ : ScopedSubresourceFilterConfigurator(
+ std::vector<Configuration>(1, std::move(config))) {}
+
+ScopedSubresourceFilterConfigurator::ScopedSubresourceFilterConfigurator(
+ std::vector<Configuration> configs)
+ : ScopedSubresourceFilterConfigurator(
+ base::MakeRefCounted<ConfigurationList>(std::move(configs))) {}
+
+ScopedSubresourceFilterConfigurator::~ScopedSubresourceFilterConfigurator() {
+ GetAndSetActivateConfigurations(std::move(original_config_));
+}
+
+void ScopedSubresourceFilterConfigurator::ResetConfiguration(
+ scoped_refptr<ConfigurationList> configs_list) {
+ GetAndSetActivateConfigurations(configs_list);
+}
+
+void ScopedSubresourceFilterConfigurator::ResetConfiguration(
+ Configuration config) {
+ ResetConfiguration(std::vector<Configuration>(1, std::move(config)));
+}
+
+void ScopedSubresourceFilterConfigurator::ResetConfiguration(
+ std::vector<Configuration> config) {
+ ResetConfiguration(
+ base::MakeRefCounted<ConfigurationList>(std::move(config)));
+}
+
+// ScopedSubresourceFilterFeatureToggle ---------------------------------------
+
+ScopedSubresourceFilterFeatureToggle::ScopedSubresourceFilterFeatureToggle() {}
ScopedSubresourceFilterFeatureToggle::ScopedSubresourceFilterFeatureToggle(
base::FeatureList::OverrideState feature_state,
- const std::string& maximum_activation_level,
- const std::string& activation_scope,
- const std::string& activation_lists,
- const std::string& performance_measurement_rate,
- const std::string& suppress_notifications,
- const std::string& whitelist_site_on_reload)
- : ScopedSubresourceFilterFeatureToggle(
- feature_state,
- {{kActivationLevelParameterName, maximum_activation_level},
- {kActivationScopeParameterName, activation_scope},
- {kActivationListsParameterName, activation_lists},
- {kPerformanceMeasurementRateParameterName,
- performance_measurement_rate},
- {kSuppressNotificationsParameterName, suppress_notifications},
- {kWhitelistSiteOnReloadParameterName, whitelist_site_on_reload}}) {}
+ const std::string& additional_features_to_enable) {
+ ResetSubresourceFilterState(feature_state, additional_features_to_enable);
+}
-ScopedSubresourceFilterFeatureToggle::ScopedSubresourceFilterFeatureToggle(
+void ScopedSubresourceFilterFeatureToggle::ResetSubresourceFilterState(
base::FeatureList::OverrideState feature_state,
- std::map<std::string, std::string> variation_params) {
- EXPECT_TRUE(base::AssociateFieldTrialParams(
- kTestFieldTrialName, kTestExperimentGroupName, variation_params));
-
- base::FieldTrial* field_trial = base::FieldTrialList::CreateFieldTrial(
- kTestFieldTrialName, kTestExperimentGroupName);
-
- std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
- feature_list->RegisterFieldTrialOverride(kSafeBrowsingSubresourceFilter.name,
- feature_state, field_trial);
-
- // Since we are adding a scoped feature list after browser start, copy over
- // the existing feature list to prevent inconsistency.
- base::FeatureList* existing_feature_list = base::FeatureList::GetInstance();
- if (existing_feature_list) {
- std::string enabled_features;
- std::string disabled_features;
- base::FeatureList::GetInstance()->GetFeatureOverrides(&enabled_features,
- &disabled_features);
- feature_list->InitializeFromCommandLine(enabled_features,
- disabled_features);
+ const std::string& additional_features_to_enable) {
+ std::string enabled_features;
+ std::string disabled_features;
+
+ if (feature_state == base::FeatureList::OVERRIDE_ENABLE_FEATURE) {
+ enabled_features = kSafeBrowsingSubresourceFilter.name;
+ } else if (feature_state == base::FeatureList::OVERRIDE_DISABLE_FEATURE) {
+ disabled_features = kSafeBrowsingSubresourceFilter.name;
+ }
+
+ if (!additional_features_to_enable.empty()) {
+ if (!enabled_features.empty())
+ enabled_features += ',';
+ enabled_features += additional_features_to_enable;
}
- scoped_feature_list_.InitWithFeatureList(std::move(feature_list));
+ scoped_configuration_.ResetConfiguration();
+ scoped_feature_list_ = base::MakeUnique<base::test::ScopedFeatureList>();
+ scoped_feature_list_->InitFromCommandLine(enabled_features,
+ disabled_features);
}
-ScopedSubresourceFilterFeatureToggle::~ScopedSubresourceFilterFeatureToggle() {
- variations::testing::ClearAllVariationParams();
+ScopedSubresourceFilterFeatureToggle::~ScopedSubresourceFilterFeatureToggle() {}
+
+std::ostream& operator<<(std::ostream& os, const Configuration& config) {
+ std::unique_ptr<base::Value> value = config.ToTracedValue()->ToBaseValue();
+ base::DictionaryValue* dict;
+ value->GetAsDictionary(&dict);
+ std::string json;
+ base::JSONWriter::WriteWithOptions(
+ *dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
+ return os << json;
}
} // namespace testing
diff --git a/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.h b/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.h
index 080bf615931..91ad51698fe 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.h
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_features_test_support.h
@@ -5,42 +5,74 @@
#ifndef COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_FEATURES_TEST_SUPPORT_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_FEATURES_TEST_SUPPORT_H_
-#include <map>
+#include <iosfwd>
+#include <memory>
#include <string>
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/test/scoped_feature_list.h"
+#include "components/subresource_filter/core/browser/subresource_filter_features.h"
namespace subresource_filter {
namespace testing {
-// Helper to override the state of the |kSafeBrowsingSubresourceFilter| feature,
-// and its variation parameters, e.g., maximum activation level and activation
-// scope. Expects a pre-existing global base::FieldTrialList singleton.
+// Helper class to override the active subresource filtering configuration to be
+// used in tests while the instance is in scope.
+//
+// Configuration overrides can be nested, and will take effect regardless of
+// field trial, feature, and/or variation parameter states.
+class ScopedSubresourceFilterConfigurator {
+ public:
+ explicit ScopedSubresourceFilterConfigurator(
+ scoped_refptr<ConfigurationList> config_list = nullptr);
+ explicit ScopedSubresourceFilterConfigurator(Configuration config);
+ explicit ScopedSubresourceFilterConfigurator(
+ std::vector<Configuration> configs);
+ ~ScopedSubresourceFilterConfigurator();
+
+ void ResetConfiguration(
+ scoped_refptr<ConfigurationList> config_list = nullptr);
+ void ResetConfiguration(Configuration config);
+ void ResetConfiguration(std::vector<Configuration> config);
+
+ private:
+ scoped_refptr<ConfigurationList> original_config_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSubresourceFilterConfigurator);
+};
+
+// Helper class to override the state of the |kSafeBrowsingSubresourceFilter|
+// feature.
+//
+// Clears the active subresource filtering configuration override upon
+// construction, if any, and restores it on destruction. So while the instance
+// is in scope, calls to GetEnabledConfigurations() will default to returning
+// the hard-coded configuration corresponding to the forced feature state. Tests
+// that need to toggle both the feature and override the active configuration
+// should therefore do so in that order.
class ScopedSubresourceFilterFeatureToggle {
public:
- ScopedSubresourceFilterFeatureToggle(
- base::FeatureList::OverrideState feature_state,
- const std::string& maximum_activation_level,
- const std::string& activation_scope,
- const std::string& activation_lists = std::string(),
- const std::string& performance_measurement_rate = std::string(),
- const std::string& suppress_notifications = std::string(),
- const std::string& whitelist_site_on_reload = std::string());
-
- ScopedSubresourceFilterFeatureToggle(
+ ScopedSubresourceFilterFeatureToggle();
+ explicit ScopedSubresourceFilterFeatureToggle(
base::FeatureList::OverrideState feature_state,
- std::map<std::string, std::string> variation_params);
-
+ const std::string& additional_features_to_enable = std::string());
~ScopedSubresourceFilterFeatureToggle();
+ void ResetSubresourceFilterState(
+ base::FeatureList::OverrideState feature_state,
+ const std::string& additional_features_to_enable = std::string());
+
private:
- base::test::ScopedFeatureList scoped_feature_list_;
+ ScopedSubresourceFilterConfigurator scoped_configuration_;
+ std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
DISALLOW_COPY_AND_ASSIGN(ScopedSubresourceFilterFeatureToggle);
};
+// For logging in tests.
+std::ostream& operator<<(std::ostream& os, const Configuration& config);
+
} // namespace testing
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc b/chromium/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc
index 204186832d2..6b7263dcd94 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc
@@ -4,14 +4,91 @@
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
+#include <map>
+#include <memory>
#include <string>
+#include <utility>
+#include <vector>
+#include "base/feature_list.h"
+#include "base/macros.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_util.h"
#include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
+#include "components/variations/variations_associated_data.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace subresource_filter {
+namespace {
+
+constexpr const char kTestFieldTrialName[] = "FieldTrialNameShouldNotMatter";
+constexpr const char kTestExperimentGroupName[] = "GroupNameShouldNotMatter";
+
+class ScopedExperimentalStateToggle {
+ public:
+ ScopedExperimentalStateToggle(
+ base::FeatureList::OverrideState feature_state,
+ std::map<std::string, std::string> variation_params)
+ : field_trial_list_(nullptr /* entropy_provider */),
+ scoped_configurator_(nullptr) {
+ EXPECT_TRUE(base::AssociateFieldTrialParams(
+ kTestFieldTrialName, kTestExperimentGroupName, variation_params));
+ base::FieldTrial* field_trial = base::FieldTrialList::CreateFieldTrial(
+ kTestFieldTrialName, kTestExperimentGroupName);
+
+ std::unique_ptr<base::FeatureList> feature_list =
+ base::MakeUnique<base::FeatureList>();
+ feature_list->RegisterFieldTrialOverride(
+ kSafeBrowsingSubresourceFilter.name, feature_state, field_trial);
+ scoped_feature_list_.InitWithFeatureList(std::move(feature_list));
+ }
+
+ ~ScopedExperimentalStateToggle() {
+ variations::testing::ClearAllVariationParams();
+ }
+
+ private:
+ base::FieldTrialList field_trial_list_;
+
+ testing::ScopedSubresourceFilterConfigurator scoped_configurator_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedExperimentalStateToggle);
+};
+
+void ExpectAndRetrieveExactlyOneEnabledConfig(Configuration* actual_config) {
+ DCHECK(actual_config);
+ const auto config_list = GetEnabledConfigurations();
+ ASSERT_EQ(1u, config_list->configs_by_decreasing_priority().size());
+ *actual_config = config_list->configs_by_decreasing_priority().front();
+}
+
+void ExpectPresetCanBeEnabledByName(Configuration preset, const char* name) {
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+ {{kEnablePresetsParameterName, name}});
+
+ const auto config_list = GetEnabledConfigurations();
+ EXPECT_THAT(config_list->configs_by_decreasing_priority(),
+ ::testing::ElementsAre(preset, Configuration()));
+}
+
+void ExpectPresetIsEquivalentToVariationParams(
+ Configuration preset,
+ std::map<std::string, std::string> variation_params) {
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ base::FeatureList::OVERRIDE_ENABLE_FEATURE, variation_params);
+
+ Configuration experimental_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&experimental_configuration);
+ EXPECT_EQ(preset, experimental_configuration);
+}
+
+} // namespace
+
TEST(SubresourceFilterFeaturesTest, ActivationLevel) {
const struct {
bool feature_enabled;
@@ -36,16 +113,18 @@ TEST(SubresourceFilterFeaturesTest, ActivationLevel) {
SCOPED_TRACE(::testing::Message("ActivationLevelParam = \"")
<< test_case.activation_level_param << "\"");
- base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
+ ScopedExperimentalStateToggle scoped_experimental_state(
test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
: base::FeatureList::OVERRIDE_USE_DEFAULT,
- test_case.activation_level_param, kActivationScopeNoSites);
+ {{kActivationLevelParameterName, test_case.activation_level_param},
+ {kActivationScopeParameterName, kActivationScopeNoSites}});
- Configuration actual_configuration = GetActiveConfiguration();
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
EXPECT_EQ(test_case.expected_activation_level,
- actual_configuration.activation_level);
- EXPECT_EQ(ActivationScope::NO_SITES, actual_configuration.activation_scope);
+ actual_configuration.activation_options.activation_level);
+ EXPECT_EQ(ActivationScope::NO_SITES,
+ actual_configuration.activation_conditions.activation_scope);
}
}
@@ -73,16 +152,18 @@ TEST(SubresourceFilterFeaturesTest, ActivationScope) {
SCOPED_TRACE(::testing::Message("ActivationScopeParam = \"")
<< test_case.activation_scope_param << "\"");
- base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
+ ScopedExperimentalStateToggle scoped_experimental_state(
test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
: base::FeatureList::OVERRIDE_USE_DEFAULT,
- kActivationLevelDisabled, test_case.activation_scope_param);
+ {{kActivationLevelParameterName, kActivationLevelDisabled},
+ {kActivationScopeParameterName, test_case.activation_scope_param}});
- Configuration actual_configuration = GetActiveConfiguration();
- EXPECT_EQ(ActivationLevel::DISABLED, actual_configuration.activation_level);
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
+ EXPECT_EQ(ActivationLevel::DISABLED,
+ actual_configuration.activation_options.activation_level);
EXPECT_EQ(test_case.expected_activation_scope,
- actual_configuration.activation_scope);
+ actual_configuration.activation_conditions.activation_scope);
}
}
@@ -124,17 +205,24 @@ TEST(SubresourceFilterFeaturesTest, ActivationLevelAndScope) {
kActivationScopeAllSites, ActivationScope::NO_SITES}};
for (const auto& test_case : kTestCases) {
- base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
+ SCOPED_TRACE(::testing::Message("Enabled = ") << test_case.feature_enabled);
+ SCOPED_TRACE(::testing::Message("ActivationLevelParam = \"")
+ << test_case.activation_level_param << "\"");
+ SCOPED_TRACE(::testing::Message("ActivationScopeParam = \"")
+ << test_case.activation_scope_param << "\"");
+
+ ScopedExperimentalStateToggle scoped_experimental_state(
test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
: base::FeatureList::OVERRIDE_USE_DEFAULT,
- test_case.activation_level_param, test_case.activation_scope_param);
+ {{kActivationLevelParameterName, test_case.activation_level_param},
+ {kActivationScopeParameterName, test_case.activation_scope_param}});
- Configuration actual_configuration = GetActiveConfiguration();
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
EXPECT_EQ(test_case.expected_activation_level,
- actual_configuration.activation_level);
+ actual_configuration.activation_options.activation_level);
EXPECT_EQ(test_case.expected_activation_scope,
- actual_configuration.activation_scope);
+ actual_configuration.activation_conditions.activation_scope);
}
}
@@ -156,11 +244,11 @@ TEST(SubresourceFilterFeaturesTest, ActivationList) {
} kTestCases[] = {
{false, "", ActivationList::NONE},
{false, "social eng ads intertitial", ActivationList::NONE},
- {false, "phishing,interstital", ActivationList::NONE},
+ {false, "phishing,interstitial", ActivationList::NONE},
{false, "%$ garbage !%", ActivationList::NONE},
{true, "", ActivationList::NONE},
{true, "social eng ads intertitial", ActivationList::NONE},
- {true, "phishing interstital", ActivationList::NONE},
+ {true, "phishing interstitial", ActivationList::NONE},
{true, "%$ garbage !%", ActivationList::NONE},
{true, kActivationListSocialEngineeringAdsInterstitial,
ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL},
@@ -179,16 +267,56 @@ TEST(SubresourceFilterFeaturesTest, ActivationList) {
SCOPED_TRACE(::testing::Message("ActivationListParam = \"")
<< test_case.activation_list_param << "\"");
- base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
+ ScopedExperimentalStateToggle scoped_experimental_state(
test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
: base::FeatureList::OVERRIDE_USE_DEFAULT,
- kActivationLevelDisabled, kActivationScopeNoSites,
- test_case.activation_list_param);
+ {{kActivationLevelParameterName, kActivationLevelDisabled},
+ {kActivationScopeParameterName, kActivationScopeNoSites},
+ {kActivationListsParameterName, test_case.activation_list_param}});
- Configuration actual_configuration = GetActiveConfiguration();
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
EXPECT_EQ(test_case.expected_activation_list,
- actual_configuration.activation_list);
+ actual_configuration.activation_conditions.activation_list);
+ }
+}
+
+TEST(SubresourceFilterFeaturesTest, ActivationPriority) {
+ const struct {
+ bool feature_enabled;
+ const char* activation_priority_param;
+ int expected_priority;
+ } kTestCases[] = {{false, "", 0},
+ {false, "not_an_integer", 0},
+ {false, "100", 0},
+ {true, "", 0},
+ {true, "not_an_integer", 0},
+ {true, "0.5not_an_integer", 0},
+ {true, "garbage42", 0},
+ {true, "42garbage", 42},
+ {true, "0", 0},
+ {true, "1", 1},
+ {true, "-1", -1},
+ {true, "2.9", 2},
+ {true, "-2.9", -2},
+ {true, "2e0", 2},
+ {true, "100", 100}};
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message("Enabled = ") << test_case.feature_enabled);
+ SCOPED_TRACE(::testing::Message("Priority = \"")
+ << test_case.activation_priority_param << "\"");
+
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
+ : base::FeatureList::OVERRIDE_USE_DEFAULT,
+ {{kActivationPriorityParameterName,
+ test_case.activation_priority_param}});
+
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
+ EXPECT_EQ(test_case.expected_priority,
+ actual_configuration.activation_conditions.priority);
}
}
@@ -216,16 +344,17 @@ TEST(SubresourceFilterFeaturesTest, PerfMeasurementRate) {
SCOPED_TRACE(::testing::Message("PerfMeasurementParam = \"")
<< test_case.perf_measurement_param << "\"");
- base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
+ ScopedExperimentalStateToggle scoped_experimental_state(
test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
: base::FeatureList::OVERRIDE_USE_DEFAULT,
{{kPerformanceMeasurementRateParameterName,
test_case.perf_measurement_param}});
- Configuration actual_configuration = GetActiveConfiguration();
- EXPECT_EQ(test_case.expected_perf_measurement_rate,
- actual_configuration.performance_measurement_rate);
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
+ EXPECT_EQ(
+ test_case.expected_perf_measurement_rate,
+ actual_configuration.activation_options.performance_measurement_rate);
}
}
@@ -250,16 +379,17 @@ TEST(SubresourceFilterFeaturesTest, SuppressNotifications) {
SCOPED_TRACE(::testing::Message("SuppressNotificationsParam = \"")
<< test_case.suppress_notifications_param << "\"");
- base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
+ ScopedExperimentalStateToggle scoped_experimental_state(
test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
: base::FeatureList::OVERRIDE_USE_DEFAULT,
{{kSuppressNotificationsParameterName,
test_case.suppress_notifications_param}});
- Configuration actual_configuration = GetActiveConfiguration();
- EXPECT_EQ(test_case.expected_suppress_notifications_value,
- actual_configuration.should_suppress_notifications);
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
+ EXPECT_EQ(
+ test_case.expected_suppress_notifications_value,
+ actual_configuration.activation_options.should_suppress_notifications);
}
}
@@ -284,17 +414,236 @@ TEST(SubresourceFilterFeaturesTest, WhitelistSiteOnReload) {
SCOPED_TRACE(::testing::Message("WhitelistSiteOnReloadParam = \"")
<< test_case.whitelist_site_on_reload_param << "\"");
- base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
- testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
+ ScopedExperimentalStateToggle scoped_experimental_state(
test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
: base::FeatureList::OVERRIDE_USE_DEFAULT,
{{kWhitelistSiteOnReloadParameterName,
test_case.whitelist_site_on_reload_param}});
- Configuration actual_configuration = GetActiveConfiguration();
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
EXPECT_EQ(test_case.expected_whitelist_site_on_reload_value,
- actual_configuration.should_whitelist_site_on_reload);
+ actual_configuration.activation_options
+ .should_whitelist_site_on_reload);
}
}
+TEST(SubresourceFilterFeaturesTest, RulesetFlavor) {
+ const struct {
+ bool feature_enabled;
+ const char* ruleset_flavor_param;
+ const char* expected_ruleset_flavor_value;
+ } kTestCases[] = {
+ {false, "", ""}, {false, "a", ""}, {false, "test value", ""},
+ {true, "", ""}, {true, "a", "a"}, {true, "test value", "test value"}};
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message("Enabled = ") << test_case.feature_enabled);
+ SCOPED_TRACE(::testing::Message("Flavor = \"")
+ << test_case.ruleset_flavor_param << "\"");
+
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
+ : base::FeatureList::OVERRIDE_USE_DEFAULT,
+ {{kRulesetFlavorParameterName, test_case.ruleset_flavor_param}});
+
+ Configuration actual_configuration;
+ ExpectAndRetrieveExactlyOneEnabledConfig(&actual_configuration);
+ EXPECT_EQ(std::string(test_case.expected_ruleset_flavor_value),
+ actual_configuration.general_settings.ruleset_flavor);
+ }
+}
+
+TEST(SubresourceFilterFeaturesTest, LexicographicallyGreatestRulesetFlavor) {
+ const struct {
+ const char* expected_ruleset_flavor_selected;
+ std::vector<std::string> ruleset_flavors;
+ } kTestCases[] = {{"", std::vector<std::string>()},
+ {"", {""}},
+ {"a", {"a"}},
+ {"e", {"e"}},
+ {"foo", {"foo"}},
+ {"", {"", ""}},
+ {"a", {"a", ""}},
+ {"a", {"", "a"}},
+ {"a", {"a", "a"}},
+ {"c", {"b", "", "c"}},
+ {"b", {"", "b", "a"}},
+ {"aa", {"", "a", "aa"}},
+ {"b", {"", "a", "aa", "b"}},
+ {"foo", {"foo", "bar", "b", ""}},
+ {"2.1", {"2", "2.1", "1.3", ""}},
+ {"3", {"2", "2.1", "1.3", "3"}}};
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message()
+ << "ruleset_flavors: "
+ << ::testing::PrintToString(test_case.ruleset_flavors));
+
+ std::vector<Configuration> configs;
+ for (const auto& ruleset_flavor : test_case.ruleset_flavors) {
+ Configuration config;
+ config.general_settings.ruleset_flavor = ruleset_flavor;
+ configs.push_back(std::move(config));
+ }
+
+ subresource_filter::testing::ScopedSubresourceFilterConfigurator
+ scoped_configuration(std::move(configs));
+ EXPECT_EQ(test_case.expected_ruleset_flavor_selected,
+ GetEnabledConfigurations()
+ ->lexicographically_greatest_ruleset_flavor());
+ }
+}
+
+TEST(SubresourceFilterFeaturesTest, EnabledConfigurations_FeatureDisabled) {
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ base::FeatureList::OVERRIDE_DISABLE_FEATURE,
+ std::map<std::string, std::string>());
+
+ const auto config_list = GetEnabledConfigurations();
+ EXPECT_THAT(config_list->configs_by_decreasing_priority(),
+ ::testing::ElementsAre(Configuration()));
+ EXPECT_EQ(std::string(),
+ config_list->lexicographically_greatest_ruleset_flavor());
+}
+
+TEST(SubresourceFilterFeaturesTest,
+ EnabledConfigurations_FeatureEnabledWithNoParameters) {
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+ std::map<std::string, std::string>());
+
+ const auto config_list = GetEnabledConfigurations();
+ EXPECT_THAT(config_list->configs_by_decreasing_priority(),
+ ::testing::ElementsAre(Configuration()));
+ EXPECT_EQ(std::string(),
+ config_list->lexicographically_greatest_ruleset_flavor());
+}
+
+TEST(SubresourceFilterFeaturesTest, PresetForLiveRunOnPhishingSites) {
+ ExpectPresetCanBeEnabledByName(
+ Configuration::MakePresetForLiveRunOnPhishingSites(),
+ kPresetLiveRunOnPhishingSites);
+ ExpectPresetIsEquivalentToVariationParams(
+ Configuration::MakePresetForLiveRunOnPhishingSites(),
+ {{kActivationLevelParameterName, kActivationLevelEnabled},
+ {kActivationScopeParameterName, kActivationScopeActivationList},
+ {kActivationListsParameterName, kActivationListPhishingInterstitial},
+ {kActivationPriorityParameterName, "1000"}});
+}
+
+TEST(SubresourceFilterFeaturesTest,
+ PresetForPerformanceTestingDryRunOnAllSites) {
+ ExpectPresetCanBeEnabledByName(
+ Configuration::MakePresetForPerformanceTestingDryRunOnAllSites(),
+ kPresetPerformanceTestingDryRunOnAllSites);
+ ExpectPresetIsEquivalentToVariationParams(
+ Configuration::MakePresetForPerformanceTestingDryRunOnAllSites(),
+ {{kActivationLevelParameterName, kActivationLevelDryRun},
+ {kActivationScopeParameterName, kActivationScopeAllSites},
+ {kActivationPriorityParameterName, "500"},
+ {kPerformanceMeasurementRateParameterName, "1.0"}});
+}
+
+TEST(SubresourceFilterFeaturesTest, ConfigurationPriorities) {
+ const std::vector<Configuration> expected_order_by_decreasing_priority = {
+ Configuration::MakePresetForLiveRunOnPhishingSites(),
+ Configuration::MakePresetForPerformanceTestingDryRunOnAllSites(),
+ Configuration() /* default constructor */
+ };
+
+ std::vector<Configuration> shuffled_order = {
+ expected_order_by_decreasing_priority[2],
+ expected_order_by_decreasing_priority[0],
+ expected_order_by_decreasing_priority[1]};
+ subresource_filter::testing::ScopedSubresourceFilterConfigurator
+ scoped_configuration(std::move(shuffled_order));
+ EXPECT_THAT(
+ GetEnabledConfigurations()->configs_by_decreasing_priority(),
+ ::testing::ElementsAreArray(expected_order_by_decreasing_priority));
+}
+
+TEST(SubresourceFilterFeaturesTest, EnableDisableMultiplePresets) {
+ const std::string kPhishing(kPresetLiveRunOnPhishingSites);
+ const std::string kPerfTest(kPresetPerformanceTestingDryRunOnAllSites);
+
+ // The default config comes from the empty experimental configuration.
+ const std::vector<Configuration> kDefaultConfig = {Configuration()};
+ const std::vector<Configuration> kPhishingAndDefaultConfigs = {
+ Configuration::MakePresetForLiveRunOnPhishingSites(), Configuration()};
+ const std::vector<Configuration> kAllConfigs = {
+ Configuration::MakePresetForLiveRunOnPhishingSites(),
+ Configuration::MakePresetForPerformanceTestingDryRunOnAllSites(),
+ Configuration()};
+
+ const struct {
+ std::string enable_preset_name_list;
+ std::string disable_preset_name_list;
+ const std::vector<Configuration> expected_configs;
+ } kTestCases[] = {
+ {"", "", kDefaultConfig},
+ {"garbage1", "garbage2", kDefaultConfig},
+ {"", kPhishing + "," + kPerfTest, kDefaultConfig},
+ {kPhishing, kPerfTest, kPhishingAndDefaultConfigs},
+ {kPhishing + "," + kPerfTest, "garbage", kAllConfigs},
+ {kPerfTest + "," + kPhishing, base::ToUpperASCII(kPerfTest),
+ kPhishingAndDefaultConfigs},
+ {kPerfTest + "," + kPhishing,
+ ",,garbage, ," + kPerfTest + "," + kPhishing, kDefaultConfig},
+ {base::ToUpperASCII(kPhishing) + "," + base::ToUpperASCII(kPerfTest), "",
+ kAllConfigs},
+ {",, ," + kPerfTest + ",," + kPhishing, "", kAllConfigs},
+ {"garbage,garbage2," + kPerfTest + "," + kPhishing, "", kAllConfigs}};
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(
+ ::testing::Message()
+ << "enable_preset_name_list: " << test_case.enable_preset_name_list
+ << " disable_preset_name_list: " << test_case.disable_preset_name_list);
+
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+ {{kEnablePresetsParameterName, test_case.enable_preset_name_list},
+ {kDisablePresetsParameterName, test_case.disable_preset_name_list}});
+
+ const auto config_list = GetEnabledConfigurations();
+ EXPECT_THAT(config_list->configs_by_decreasing_priority(),
+ ::testing::ElementsAreArray(test_case.expected_configs));
+ EXPECT_EQ(std::string(),
+ config_list->lexicographically_greatest_ruleset_flavor());
+ }
+}
+
+TEST(SubresourceFilterFeaturesTest,
+ EnableMultiplePresetsAndExperimentalConfig) {
+ const std::string kPhishing(kPresetLiveRunOnPhishingSites);
+ const std::string kPerfTest(kPresetPerformanceTestingDryRunOnAllSites);
+ const std::string kTestRulesetFlavor("foobar");
+
+ ScopedExperimentalStateToggle scoped_experimental_state(
+ base::FeatureList::OVERRIDE_ENABLE_FEATURE,
+ {{kEnablePresetsParameterName, kPhishing + "," + kPerfTest},
+ {kActivationLevelParameterName, kActivationLevelDryRun},
+ {kActivationScopeParameterName, kActivationScopeActivationList},
+ {kActivationListsParameterName, kActivationListSubresourceFilter},
+ {kActivationPriorityParameterName, "750"},
+ {kRulesetFlavorParameterName, kTestRulesetFlavor}});
+
+ Configuration experimental_config(ActivationLevel::DRYRUN,
+ ActivationScope::ACTIVATION_LIST,
+ ActivationList::SUBRESOURCE_FILTER);
+ experimental_config.activation_conditions.priority = 750;
+ experimental_config.general_settings.ruleset_flavor = kTestRulesetFlavor;
+
+ const auto config_list = GetEnabledConfigurations();
+ EXPECT_THAT(
+ config_list->configs_by_decreasing_priority(),
+ ::testing::ElementsAre(
+ Configuration::MakePresetForLiveRunOnPhishingSites(),
+ experimental_config,
+ Configuration::MakePresetForPerformanceTestingDryRunOnAllSites()));
+ EXPECT_EQ(kTestRulesetFlavor,
+ config_list->lexicographically_greatest_ruleset_flavor());
+}
+
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/BUILD.gn b/chromium/components/subresource_filter/core/common/BUILD.gn
index eed0e8a63fd..61964f8d5e9 100644
--- a/chromium/components/subresource_filter/core/common/BUILD.gn
+++ b/chromium/components/subresource_filter/core/common/BUILD.gn
@@ -4,12 +4,14 @@
static_library("common") {
sources = [
+ "activation_decision.h",
"activation_level.cc",
"activation_level.h",
"activation_list.cc",
"activation_list.h",
"activation_scope.cc",
"activation_scope.h",
+ "activation_state.cc",
"activation_state.h",
"closed_hash_map.h",
"copying_file_stream.cc",
@@ -34,6 +36,8 @@ static_library("common") {
"unindexed_ruleset.h",
"url_pattern.cc",
"url_pattern.h",
+ "url_pattern_index.cc",
+ "url_pattern_index.h",
]
public_deps = [
@@ -57,10 +61,13 @@ static_library("test_support") {
"test_ruleset_creator.h",
"test_ruleset_utils.cc",
"test_ruleset_utils.h",
+ "url_rule_test_support.cc",
+ "url_rule_test_support.h",
]
deps = [
":common",
"//base",
+ "//net",
"//testing/gtest",
"//third_party/protobuf:protobuf_lite",
]
@@ -78,6 +85,7 @@ source_set("unit_tests") {
"scoped_timers_unittest.cc",
"string_splitter_unittest.cc",
"unindexed_ruleset_unittest.cc",
+ "url_pattern_index_unittest.cc",
"url_pattern_unittest.cc",
]
deps = [
diff --git a/chromium/components/subresource_filter/core/common/PRESUBMIT.py b/chromium/components/subresource_filter/core/common/PRESUBMIT.py
new file mode 100644
index 00000000000..7e054081adb
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/PRESUBMIT.py
@@ -0,0 +1,46 @@
+# Copyright 2017 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.
+
+"""Presubmit script for subresource_filter component's core/common directory.
+
+See https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+def CheckIndexedRulesetVersion(input_api, output_api):
+ """ Checks that IndexedRuleset format version is modified when necessary.
+
+ Whenever a *.fbs or indexed_ruleset.cc file is touched in
+ components/subresource_filter/core/common and kIndexedFormatVersion constant
+ is not changed, this check returns a presubmit warning to make sure the value
+ should not be updated.
+ """
+
+ indexed_ruleset_changed = False
+ indexed_ruleset_version_changed = False
+
+ for affected_file in input_api.AffectedFiles():
+ path = affected_file.LocalPath()
+ if not 'components/subresource_filter/core/common' in path:
+ continue
+ basename = input_api.basename(path)
+
+ if (basename == 'indexed_ruleset.cc' or basename == 'url_pattern_index.cc'
+ or basename.endswith('.fbs')):
+ indexed_ruleset_changed = True
+ if basename == 'indexed_ruleset.cc':
+ for (_, line) in affected_file.ChangedContents():
+ if 'kIndexedFormatVersion =' in line:
+ indexed_ruleset_version_changed = True
+ break
+
+ if indexed_ruleset_changed and not indexed_ruleset_version_changed:
+ return [output_api.PresubmitPromptWarning(
+ 'Please make sure that IndexedRuleset modifications in *.fbs and '
+ 'indexed_ruleset.cc do not require updating '
+ 'RulesetIndexer::kIndexedFormatVersion.')]
+ return []
+
+def CheckChangeOnUpload(input_api, output_api):
+ return CheckIndexedRulesetVersion(input_api, output_api)
diff --git a/chromium/components/subresource_filter/core/common/activation_decision.h b/chromium/components/subresource_filter/core/common/activation_decision.h
new file mode 100644
index 00000000000..a232a3fc72d
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/activation_decision.h
@@ -0,0 +1,40 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CORE_COMMON_ACTIVATION_DECISION_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_ACTIVATION_DECISION_H_
+
+namespace subresource_filter {
+
+// NOTE: ActivationDecision backs a UMA histogram, so it is append-only.
+enum class ActivationDecision : int {
+ // The activation decision is unknown, or not known yet.
+ UNKNOWN,
+
+ // Subresource filtering was activated.
+ ACTIVATED,
+
+ // Did not activate because subresource filtering was disabled by the
+ // highest priority configuration whose activation conditions were met.
+ ACTIVATION_DISABLED,
+
+ // Did not activate because the main frame document URL had an unsupported
+ // scheme.
+ UNSUPPORTED_SCHEME,
+
+ // Did not activate because although there was a configuration whose
+ // activation conditions were met, the main frame URL was whitelisted.
+ URL_WHITELISTED,
+
+ // Did not activate because the main frame document URL did not match the
+ // activation conditions of any of enabled configurations.
+ ACTIVATION_CONDITIONS_NOT_MET,
+
+ // Max value for enum.
+ ACTIVATION_DECISION_MAX
+};
+
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_ACTIVATION_DECISION_H_
diff --git a/chromium/components/subresource_filter/core/common/activation_scope.h b/chromium/components/subresource_filter/core/common/activation_scope.h
index aa65d368b8a..37c594af709 100644
--- a/chromium/components/subresource_filter/core/common/activation_scope.h
+++ b/chromium/components/subresource_filter/core/common/activation_scope.h
@@ -18,7 +18,7 @@ enum class ActivationScope {
// Testing only. Allows to send activation signal to the RenderFrame for each
// load.
ALL_SITES,
- LAST = ACTIVATION_LIST,
+ LAST = ALL_SITES,
};
// For logging use only.
diff --git a/chromium/components/subresource_filter/core/common/activation_state.cc b/chromium/components/subresource_filter/core/common/activation_state.cc
new file mode 100644
index 00000000000..43e75137a7d
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/activation_state.cc
@@ -0,0 +1,31 @@
+// Copyright 2017 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/subresource_filter/core/common/activation_state.h"
+
+#include <ostream>
+#include <sstream>
+#include <string>
+
+#include "base/memory/ptr_util.h"
+#include "base/trace_event/trace_event_argument.h"
+
+namespace subresource_filter {
+
+std::unique_ptr<base::trace_event::TracedValue> ActivationState::ToTracedValue()
+ const {
+ auto value = base::MakeUnique<base::trace_event::TracedValue>();
+ std::ostringstream level;
+ level << this;
+ value->SetString("activation_level", level.str());
+ value->SetBoolean("filtering_disabled_for_document",
+ filtering_disabled_for_document);
+ value->SetBoolean("generic_blocking_rules_disabled",
+ generic_blocking_rules_disabled);
+ value->SetBoolean("measure_performance", measure_performance);
+ value->SetBoolean("enable_logging", enable_logging);
+ return value;
+}
+
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/activation_state.h b/chromium/components/subresource_filter/core/common/activation_state.h
index a591ed692ad..e8c03058429 100644
--- a/chromium/components/subresource_filter/core/common/activation_state.h
+++ b/chromium/components/subresource_filter/core/common/activation_state.h
@@ -5,8 +5,16 @@
#ifndef COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_ACTIVATION_STATE_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_ACTIVATION_STATE_H_
+#include <memory>
+
#include "components/subresource_filter/core/common/activation_level.h"
+namespace base {
+namespace trace_event {
+class TracedValue;
+} // namespace trace_event
+} // namespace base
+
namespace subresource_filter {
// Encompasses all details of whether/how subresource filtering should be
@@ -24,11 +32,14 @@ struct ActivationState {
(filtering_disabled_for_document ||
generic_blocking_rules_disabled ==
rhs.generic_blocking_rules_disabled) &&
- measure_performance == rhs.measure_performance;
+ measure_performance == rhs.measure_performance &&
+ enable_logging == rhs.enable_logging;
}
bool operator!=(const ActivationState& rhs) const { return !operator==(rhs); }
+ std::unique_ptr<base::trace_event::TracedValue> ToTracedValue() const;
+
// The degree to which subresource filtering is activated for the page load.
ActivationLevel activation_level = ActivationLevel::DISABLED;
@@ -50,6 +61,9 @@ struct ActivationState {
// Whether or not extended performance measurements are enabled for the
// current page load (across all frames).
bool measure_performance = false;
+
+ // Whether or not to log messages in the devtools console.
+ bool enable_logging = false;
};
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/document_subresource_filter_unittest.cc b/chromium/components/subresource_filter/core/common/document_subresource_filter_unittest.cc
index 71562368cc6..f447177ab8d 100644
--- a/chromium/components/subresource_filter/core/common/document_subresource_filter_unittest.cc
+++ b/chromium/components/subresource_filter/core/common/document_subresource_filter_unittest.cc
@@ -11,6 +11,8 @@
#include "components/subresource_filter/core/common/test_ruleset_creator.h"
#include "components/subresource_filter/core/common/test_ruleset_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
namespace subresource_filter {
@@ -163,7 +165,7 @@ class SubresourceFilterComputeActivationStateTest : public ::testing::Test {
activation_state.generic_blocking_rules_disabled =
generic_blocking_rules_disabled;
return activation_state;
- };
+ }
const MemoryMappedRuleset* ruleset() { return ruleset_.get(); }
diff --git a/chromium/components/subresource_filter/core/common/flat/BUILD.gn b/chromium/components/subresource_filter/core/common/flat/BUILD.gn
index 195c0cd11e0..d554b35a338 100644
--- a/chromium/components/subresource_filter/core/common/flat/BUILD.gn
+++ b/chromium/components/subresource_filter/core/common/flat/BUILD.gn
@@ -6,6 +6,7 @@ import("//third_party/flatbuffers/flatbuffer.gni")
flatbuffer("flatbuffer") {
sources = [
- "rules.fbs",
+ "indexed_ruleset.fbs",
+ "url_pattern_index.fbs",
]
}
diff --git a/chromium/components/subresource_filter/core/common/flat/indexed_ruleset.fbs b/chromium/components/subresource_filter/core/common/flat/indexed_ruleset.fbs
new file mode 100644
index 00000000000..91262283f09
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/flat/indexed_ruleset.fbs
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+// TODO(pkalinnikov): Make including by absolute path work.
+include "url_pattern_index.fbs";
+
+namespace subresource_filter.flat;
+
+// The top-level data structure used to store URL rules.
+table IndexedRuleset {
+ // The index of all blacklist URL rules.
+ blacklist_index : UrlPatternIndex;
+
+ // The index of all whitelist URL rules, except pure deactivation rules.
+ whitelist_index : UrlPatternIndex;
+
+ // The index of all whitelist URL rules with activation options.
+ deactivation_index : UrlPatternIndex;
+}
+
+root_type IndexedRuleset;
diff --git a/chromium/components/subresource_filter/core/common/flat/rules.fbs b/chromium/components/subresource_filter/core/common/flat/url_pattern_index.fbs
index fdeaea972ee..ace4a0566dc 100644
--- a/chromium/components/subresource_filter/core/common/flat/rules.fbs
+++ b/chromium/components/subresource_filter/core/common/flat/url_pattern_index.fbs
@@ -1,3 +1,7 @@
+// Copyright 2017 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.
+
namespace subresource_filter.flat;
// Corresponds to subresource_filter::proto::UrlPatternType.
@@ -89,16 +93,4 @@ table UrlPatternIndex {
fallback_rules : [UrlRule];
}
-// The top-level data structure used to store URL rules.
-table IndexedRuleset {
- // The index of all blacklist URL rules.
- blacklist_index : UrlPatternIndex;
-
- // The index of all whitelist URL rules, except pure activation rules.
- whitelist_index : UrlPatternIndex;
-
- // The index of all whitelist URL rules with activation options.
- activation_index : UrlPatternIndex;
-}
-
-root_type IndexedRuleset;
+root_type UrlPatternIndex;
diff --git a/chromium/components/subresource_filter/core/common/indexed_ruleset.cc b/chromium/components/subresource_filter/core/common/indexed_ruleset.cc
index 66d08f4c4a4..edbbee88c9d 100644
--- a/chromium/components/subresource_filter/core/common/indexed_ruleset.cc
+++ b/chromium/components/subresource_filter/core/common/indexed_ruleset.cc
@@ -4,558 +4,56 @@
#include "components/subresource_filter/core/common/indexed_ruleset.h"
-#include <algorithm>
-#include <limits>
-#include <string>
-
#include "base/logging.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/strings/string_util.h"
#include "components/subresource_filter/core/common/first_party_origin.h"
-#include "components/subresource_filter/core/common/ngram_extractor.h"
-#include "components/subresource_filter/core/common/url_pattern.h"
-#include "third_party/flatbuffers/src/include/flatbuffers/flatbuffers.h"
+#include "url/gurl.h"
+#include "url/origin.h"
namespace subresource_filter {
-namespace {
-
-using FlatStringOffset = flatbuffers::Offset<flatbuffers::String>;
-using FlatDomains = flatbuffers::Vector<FlatStringOffset>;
-using FlatDomainsOffset = flatbuffers::Offset<FlatDomains>;
-
-base::StringPiece ToStringPiece(const flatbuffers::String* string) {
- DCHECK(string);
- return base::StringPiece(string->c_str(), string->size());
-}
-
-// Performs three-way comparison between two domains. In the total order defined
-// by this predicate, the lengths of domains will be monotonically decreasing.
-int CompareDomains(base::StringPiece lhs_domain, base::StringPiece rhs_domain) {
- if (lhs_domain.size() != rhs_domain.size())
- return lhs_domain.size() > rhs_domain.size() ? -1 : 1;
- return lhs_domain.compare(rhs_domain);
-}
-
-bool HasNoUpperAscii(base::StringPiece string) {
- return std::none_of(string.begin(), string.end(),
- [](char c) { return base::IsAsciiUpper(c); });
-}
-
-// Checks whether a URL |rule| can be converted to its FlatBuffers equivalent,
-// and performs the actual conversion.
-class UrlRuleFlatBufferConverter {
- public:
- // Creates the converter, and initializes |is_convertible| bit. If
- // |is_convertible| == true, then all the fields, needed for serializing the
- // |rule| to FlatBuffer, are initialized (|options|, |anchor_right|, etc.).
- UrlRuleFlatBufferConverter(const proto::UrlRule& rule) : rule_(rule) {
- is_convertible_ = InitializeOptions() && InitializeElementTypes() &&
- InitializeActivationTypes() && InitializeUrlPattern() &&
- IsMeaningful();
- }
-
- // Returns whether the |rule| can be converted to its FlatBuffers equivalent.
- // The conversion is not possible if the rule has attributes not supported by
- // this client version.
- bool is_convertible() const { return is_convertible_; }
-
- bool has_element_types() const { return !!element_types_; }
- bool has_activation_types() const { return !!activation_types_; }
-
- // Writes the URL |rule| to the FlatBuffer using the |builder|, and returns
- // the offset to the serialized rule.
- flatbuffers::Offset<flat::UrlRule> SerializeConvertedRule(
- flatbuffers::FlatBufferBuilder* builder) const {
- DCHECK(is_convertible());
-
- FlatDomainsOffset domains_included_offset;
- FlatDomainsOffset domains_excluded_offset;
- if (rule_.domains_size()) {
- // TODO(pkalinnikov): Consider sharing the vectors between rules.
- std::vector<FlatStringOffset> domains_included;
- std::vector<FlatStringOffset> domains_excluded;
- // Reserve only for |domains_included| because it is expected to be the
- // one used more frequently.
- domains_included.reserve(rule_.domains_size());
-
- for (const auto& domain_list_item : rule_.domains()) {
- // Note: The |domain| can have non-ASCII UTF-8 characters, but
- // ToLowerASCII leaves these intact.
- // TODO(pkalinnikov): Convert non-ASCII characters to lower case too.
- // TODO(pkalinnikov): Possibly convert Punycode to IDN here or directly
- // assume this is done in the proto::UrlRule.
- const std::string& domain = domain_list_item.domain();
- auto offset = builder->CreateSharedString(
- HasNoUpperAscii(domain) ? domain : base::ToLowerASCII(domain));
-
- if (domain_list_item.exclude())
- domains_excluded.push_back(offset);
- else
- domains_included.push_back(offset);
- }
-
- // The comparator ensuring the domains order necessary for fast matching.
- auto precedes = [&builder](FlatStringOffset lhs, FlatStringOffset rhs) {
- return CompareDomains(ToStringPiece(flatbuffers::GetTemporaryPointer(
- *builder, lhs)),
- ToStringPiece(flatbuffers::GetTemporaryPointer(
- *builder, rhs))) < 0;
- };
-
- // The domains are stored in sorted order to support fast matching.
- if (!domains_included.empty()) {
- // TODO(pkalinnikov): Don't sort if it is already sorted offline.
- std::sort(domains_included.begin(), domains_included.end(), precedes);
- domains_included_offset = builder->CreateVector(domains_included);
- }
- if (!domains_excluded.empty()) {
- std::sort(domains_excluded.begin(), domains_excluded.end(), precedes);
- domains_excluded_offset = builder->CreateVector(domains_excluded);
- }
- }
-
- auto url_pattern_offset = builder->CreateString(rule_.url_pattern());
-
- return flat::CreateUrlRule(
- *builder, options_, element_types_, activation_types_,
- url_pattern_type_, anchor_left_, anchor_right_, domains_included_offset,
- domains_excluded_offset, url_pattern_offset);
- }
-
- private:
- static bool ConvertAnchorType(proto::AnchorType anchor_type,
- flat::AnchorType* result) {
- switch (anchor_type) {
- case proto::ANCHOR_TYPE_NONE:
- *result = flat::AnchorType_NONE;
- break;
- case proto::ANCHOR_TYPE_BOUNDARY:
- *result = flat::AnchorType_BOUNDARY;
- break;
- case proto::ANCHOR_TYPE_SUBDOMAIN:
- *result = flat::AnchorType_SUBDOMAIN;
- break;
- default:
- return false; // Unsupported anchor type.
- }
- return true;
- }
-
- bool InitializeOptions() {
- if (rule_.semantics() == proto::RULE_SEMANTICS_WHITELIST) {
- options_ |= flat::OptionFlag_IS_WHITELIST;
- } else if (rule_.semantics() != proto::RULE_SEMANTICS_BLACKLIST) {
- return false; // Unsupported semantics.
- }
-
- switch (rule_.source_type()) {
- case proto::SOURCE_TYPE_ANY:
- options_ |= flat::OptionFlag_APPLIES_TO_THIRD_PARTY;
- // Note: fall through here intentionally.
- case proto::SOURCE_TYPE_FIRST_PARTY:
- options_ |= flat::OptionFlag_APPLIES_TO_FIRST_PARTY;
- break;
- case proto::SOURCE_TYPE_THIRD_PARTY:
- options_ |= flat::OptionFlag_APPLIES_TO_THIRD_PARTY;
- break;
-
- default:
- return false; // Unsupported source type.
- }
-
- if (rule_.match_case())
- options_ |= flat::OptionFlag_IS_MATCH_CASE;
-
- return true;
- }
-
- bool InitializeElementTypes() {
- static_assert(
- proto::ELEMENT_TYPE_ALL <= std::numeric_limits<uint16_t>::max(),
- "Element types can not be stored in uint16_t.");
- element_types_ = static_cast<uint16_t>(rule_.element_types());
-
- // Note: Normally we can not distinguish between the main plugin resource
- // and any other loads it makes. We treat them both as OBJECT requests.
- if (element_types_ & proto::ELEMENT_TYPE_OBJECT_SUBREQUEST)
- element_types_ |= proto::ELEMENT_TYPE_OBJECT;
-
- // Ignore unknown element types.
- element_types_ &= proto::ELEMENT_TYPE_ALL;
- // Filtering popups is not supported.
- element_types_ &= ~proto::ELEMENT_TYPE_POPUP;
-
- return true;
- }
-
- bool InitializeActivationTypes() {
- static_assert(
- proto::ACTIVATION_TYPE_ALL <= std::numeric_limits<uint8_t>::max(),
- "Activation types can not be stored in uint8_t.");
- activation_types_ = static_cast<uint8_t>(rule_.activation_types());
-
- // Ignore unknown activation types.
- activation_types_ &= proto::ACTIVATION_TYPE_ALL;
- // No need in CSS activation, because the CSS rules are not supported.
- activation_types_ &=
- ~(proto::ACTIVATION_TYPE_ELEMHIDE | proto::ACTIVATION_TYPE_GENERICHIDE);
-
- return true;
- }
-
- bool InitializeUrlPattern() {
- switch (rule_.url_pattern_type()) {
- case proto::URL_PATTERN_TYPE_SUBSTRING:
- url_pattern_type_ = flat::UrlPatternType_SUBSTRING;
- break;
- case proto::URL_PATTERN_TYPE_WILDCARDED:
- url_pattern_type_ = flat::UrlPatternType_WILDCARDED;
- break;
-
- // TODO(pkalinnikov): Implement REGEXP rules matching.
- case proto::URL_PATTERN_TYPE_REGEXP:
- default:
- return false; // Unsupported URL pattern type.
- }
-
- if (!ConvertAnchorType(rule_.anchor_left(), &anchor_left_) ||
- !ConvertAnchorType(rule_.anchor_right(), &anchor_right_)) {
- return false;
- }
- if (anchor_right_ == flat::AnchorType_SUBDOMAIN)
- return false; // Unsupported right anchor.
-
- return true;
- }
-
- // Returns whether the rule is not a no-op after all the modifications above.
- bool IsMeaningful() const { return element_types_ || activation_types_; }
-
- const proto::UrlRule& rule_;
-
- uint8_t options_ = 0;
- uint16_t element_types_ = 0;
- uint8_t activation_types_ = 0;
- flat::UrlPatternType url_pattern_type_ = flat::UrlPatternType_WILDCARDED;
- flat::AnchorType anchor_left_ = flat::AnchorType_NONE;
- flat::AnchorType anchor_right_ = flat::AnchorType_NONE;
-
- bool is_convertible_ = true;
-};
-
-} // namespace
-
// RulesetIndexer --------------------------------------------------------------
// static
const int RulesetIndexer::kIndexedFormatVersion = 17;
-RulesetIndexer::MutableUrlPatternIndex::MutableUrlPatternIndex() = default;
-RulesetIndexer::MutableUrlPatternIndex::~MutableUrlPatternIndex() = default;
+RulesetIndexer::RulesetIndexer()
+ : blacklist_(&builder_), whitelist_(&builder_), deactivation_(&builder_) {}
-RulesetIndexer::RulesetIndexer() = default;
RulesetIndexer::~RulesetIndexer() = default;
bool RulesetIndexer::AddUrlRule(const proto::UrlRule& rule) {
- UrlRuleFlatBufferConverter converter(rule);
- if (!converter.is_convertible())
+ const UrlRuleOffset offset = SerializeUrlRule(rule, &builder_);
+ // Note: A zero offset.o means a "nullptr" offset. It is returned when the
+ // rule has not been serialized.
+ if (!offset.o)
return false;
- DCHECK_NE(rule.url_pattern_type(), proto::URL_PATTERN_TYPE_REGEXP);
- auto rule_offset = converter.SerializeConvertedRule(&builder_);
-
- auto add_rule_to_index = [&rule, rule_offset](MutableUrlPatternIndex* index) {
- NGram ngram =
- GetMostDistinctiveNGram(index->ngram_index, rule.url_pattern());
- if (ngram) {
- index->ngram_index[ngram].push_back(rule_offset);
- } else {
- // TODO(pkalinnikov): Index fallback rules as well.
- index->fallback_rules.push_back(rule_offset);
- }
- };
if (rule.semantics() == proto::RULE_SEMANTICS_BLACKLIST) {
- add_rule_to_index(&blacklist_);
+ blacklist_.IndexUrlRule(offset);
} else {
- if (converter.has_element_types())
- add_rule_to_index(&whitelist_);
- if (converter.has_activation_types())
- add_rule_to_index(&activation_);
+ const auto* flat_rule = flatbuffers::GetTemporaryPointer(builder_, offset);
+ DCHECK(flat_rule);
+ if (flat_rule->element_types())
+ whitelist_.IndexUrlRule(offset);
+ if (flat_rule->activation_types())
+ deactivation_.IndexUrlRule(offset);
}
return true;
}
void RulesetIndexer::Finish() {
- auto blacklist_offset = SerializeUrlPatternIndex(blacklist_);
- auto whitelist_offset = SerializeUrlPatternIndex(whitelist_);
- auto activation_offset = SerializeUrlPatternIndex(activation_);
+ auto blacklist_offset = blacklist_.Finish();
+ auto whitelist_offset = whitelist_.Finish();
+ auto deactivation_offset = deactivation_.Finish();
auto url_rules_index_offset = flat::CreateIndexedRuleset(
- builder_, blacklist_offset, whitelist_offset, activation_offset);
+ builder_, blacklist_offset, whitelist_offset, deactivation_offset);
builder_.Finish(url_rules_index_offset);
}
-// static
-NGram RulesetIndexer::GetMostDistinctiveNGram(
- const MutableNGramIndex& ngram_index,
- base::StringPiece pattern) {
- size_t min_list_size = std::numeric_limits<size_t>::max();
- NGram best_ngram = 0;
-
- auto ngrams = CreateNGramExtractor<kNGramSize, NGram>(
- pattern, [](char c) { return c == '*' || c == '^'; });
-
- for (uint64_t ngram : ngrams) {
- const MutableUrlRuleList* rules = ngram_index.Get(ngram);
- const size_t list_size = rules ? rules->size() : 0;
- if (list_size < min_list_size) {
- // TODO(pkalinnikov): Pick random of the same-sized lists.
- min_list_size = list_size;
- best_ngram = ngram;
- if (list_size == 0)
- break;
- }
- }
-
- return best_ngram;
-}
-
-flatbuffers::Offset<flat::UrlPatternIndex>
-RulesetIndexer::SerializeUrlPatternIndex(const MutableUrlPatternIndex& index) {
- const MutableNGramIndex& ngram_index = index.ngram_index;
-
- std::vector<flatbuffers::Offset<flat::NGramToRules>> flat_hash_table(
- ngram_index.table_size());
-
- flatbuffers::Offset<flat::NGramToRules> empty_slot_offset =
- flat::CreateNGramToRules(builder_);
- for (size_t i = 0, size = ngram_index.table_size(); i != size; ++i) {
- const uint32_t entry_index = ngram_index.hash_table()[i];
- if (entry_index >= ngram_index.size()) {
- flat_hash_table[i] = empty_slot_offset;
- continue;
- }
- const MutableNGramIndex::EntryType& entry =
- ngram_index.entries()[entry_index];
- auto rules_offset = builder_.CreateVector(entry.second);
- flat_hash_table[i] =
- flat::CreateNGramToRules(builder_, entry.first, rules_offset);
- }
- auto ngram_index_offset = builder_.CreateVector(flat_hash_table);
-
- auto fallback_rules_offset = builder_.CreateVector(index.fallback_rules);
-
- return flat::CreateUrlPatternIndex(builder_, kNGramSize, ngram_index_offset,
- empty_slot_offset, fallback_rules_offset);
-}
-
// IndexedRulesetMatcher -------------------------------------------------------
-namespace {
-
-using FlatUrlRuleList = flatbuffers::Vector<flatbuffers::Offset<flat::UrlRule>>;
-using FlatNGramIndex =
- flatbuffers::Vector<flatbuffers::Offset<flat::NGramToRules>>;
-
-// Returns the size of the longest (sub-)domain of |origin| matching one of the
-// |domains| in the list.
-//
-// The |domains| should be sorted in descending order of their length, and
-// ascending alphabetical order within the groups of same-length domains.
-size_t GetLongestMatchingSubdomain(const url::Origin& origin,
- const FlatDomains& domains) {
- // If the |domains| list is short, then the simple strategy is usually faster.
- if (domains.size() <= 5) {
- for (auto* domain : domains) {
- const base::StringPiece domain_piece = ToStringPiece(domain);
- if (origin.DomainIs(domain_piece))
- return domain_piece.size();
- }
- return 0;
- }
- // Otherwise look for each subdomain of the |origin| using binary search.
-
- DCHECK(!origin.unique());
- base::StringPiece canonicalized_host(origin.host());
- if (canonicalized_host.empty())
- return 0;
-
- // If the host name ends with a dot, then ignore it.
- if (canonicalized_host.back() == '.')
- canonicalized_host.remove_suffix(1);
-
- // The |left| bound of the search is shared between iterations, because
- // subdomains are considered in decreasing order of their lengths, therefore
- // each consecutive lower_bound will be at least as far as the previous.
- flatbuffers::uoffset_t left = 0;
- for (size_t position = 0;; ++position) {
- const base::StringPiece subdomain = canonicalized_host.substr(position);
-
- flatbuffers::uoffset_t right = domains.size();
- while (left + 1 < right) {
- auto middle = left + (right - left) / 2;
- DCHECK_LT(middle, domains.size());
- if (CompareDomains(ToStringPiece(domains[middle]), subdomain) <= 0)
- left = middle;
- else
- right = middle;
- }
-
- DCHECK_LT(left, domains.size());
- if (ToStringPiece(domains[left]) == subdomain)
- return subdomain.size();
-
- position = canonicalized_host.find('.', position);
- if (position == base::StringPiece::npos)
- break;
- }
-
- return 0;
-}
-
-// Returns whether the |origin| matches the domain list of the |rule|. A match
-// means that the longest domain in |domains| that |origin| is a sub-domain of
-// is not an exception OR all the |domains| are exceptions and neither matches
-// the |origin|. Thus, domain filters with more domain components trump filters
-// with fewer domain components, i.e. the more specific a filter is, the higher
-// the priority.
-//
-// A rule whose domain list is empty or contains only negative domains is still
-// considered a "generic" rule. Therefore, if |disable_generic_rules| is set,
-// this function will always return false for such rules.
-bool DoesOriginMatchDomainList(const url::Origin& origin,
- const flat::UrlRule& rule,
- bool disable_generic_rules) {
- const bool is_generic = !rule.domains_included();
- DCHECK(is_generic || rule.domains_included()->size());
- if (disable_generic_rules && is_generic)
- return false;
-
- // Unique |origin| matches lists of exception domains only.
- if (origin.unique())
- return is_generic;
-
- size_t longest_matching_included_domain_length = 1;
- if (!is_generic) {
- longest_matching_included_domain_length =
- GetLongestMatchingSubdomain(origin, *rule.domains_included());
- }
- if (longest_matching_included_domain_length && rule.domains_excluded()) {
- return GetLongestMatchingSubdomain(origin, *rule.domains_excluded()) <
- longest_matching_included_domain_length;
- }
- return !!longest_matching_included_domain_length;
-}
-
-// Returns whether the request matches flags of the specified URL |rule|. Takes
-// into account:
-// - |element_type| of the requested resource, if not *_UNSPECIFIED.
-// - |activation_type| for a subdocument request, if not *_UNSPECIFIED.
-// - Whether the resource |is_third_party| w.r.t. its embedding document.
-bool DoesRuleFlagsMatch(const flat::UrlRule& rule,
- proto::ElementType element_type,
- proto::ActivationType activation_type,
- bool is_third_party) {
- DCHECK(element_type == proto::ELEMENT_TYPE_UNSPECIFIED ||
- activation_type == proto::ACTIVATION_TYPE_UNSPECIFIED);
-
- if (element_type != proto::ELEMENT_TYPE_UNSPECIFIED &&
- !(rule.element_types() & element_type)) {
- return false;
- }
- if (activation_type != proto::ACTIVATION_TYPE_UNSPECIFIED &&
- !(rule.activation_types() & activation_type)) {
- return false;
- }
-
- if (is_third_party &&
- !(rule.options() & flat::OptionFlag_APPLIES_TO_THIRD_PARTY)) {
- return false;
- }
- if (!is_third_party &&
- !(rule.options() & flat::OptionFlag_APPLIES_TO_FIRST_PARTY)) {
- return false;
- }
-
- return true;
-}
-
-bool MatchesAny(const FlatUrlRuleList* rules,
- const GURL& url,
- const url::Origin& document_origin,
- proto::ElementType element_type,
- proto::ActivationType activation_type,
- bool is_third_party,
- bool disable_generic_rules) {
- if (!rules)
- return false;
- for (const flat::UrlRule* rule : *rules) {
- DCHECK_NE(rule, nullptr);
- DCHECK_NE(rule->url_pattern_type(), flat::UrlPatternType_REGEXP);
- if (!DoesRuleFlagsMatch(*rule, element_type, activation_type,
- is_third_party)) {
- continue;
- }
- if (!UrlPattern(*rule).MatchesUrl(url))
- continue;
-
- if (DoesOriginMatchDomainList(document_origin, *rule,
- disable_generic_rules)) {
- return true;
- }
- }
-
- return false;
-}
-
-// Returns whether the network request matches a particular part of the index.
-// |is_third_party| should reflect the relation between |url| and
-// |document_origin|.
-bool IsMatch(const flat::UrlPatternIndex* index,
- const GURL& url,
- const url::Origin& document_origin,
- proto::ElementType element_type,
- proto::ActivationType activation_type,
- bool is_third_party,
- bool disable_generic_rules) {
- if (!index)
- return false;
- const FlatNGramIndex* hash_table = index->ngram_index();
- const flat::NGramToRules* empty_slot = index->ngram_index_empty_slot();
- DCHECK_NE(hash_table, nullptr);
-
- NGramHashTableProber prober;
-
- auto ngrams = CreateNGramExtractor<kNGramSize, uint64_t>(
- url.spec(), [](char) { return false; });
- for (uint64_t ngram : ngrams) {
- const size_t slot_index = prober.FindSlot(
- ngram, base::strict_cast<size_t>(hash_table->size()),
- [hash_table, empty_slot](NGram ngram, size_t slot_index) {
- const flat::NGramToRules* entry = hash_table->Get(slot_index);
- DCHECK_NE(entry, nullptr);
- return entry == empty_slot || entry->ngram() == ngram;
- });
- DCHECK_LT(slot_index, hash_table->size());
-
- const flat::NGramToRules* entry = hash_table->Get(slot_index);
- if (entry == empty_slot)
- continue;
- if (MatchesAny(entry->rule_list(), url, document_origin, element_type,
- activation_type, is_third_party, disable_generic_rules)) {
- return true;
- }
- }
-
- const FlatUrlRuleList* rules = index->fallback_rules();
- return MatchesAny(rules, url, document_origin, element_type, activation_type,
- is_third_party, disable_generic_rules);
-}
-
-} // namespace
-
// static
bool IndexedRulesetMatcher::Verify(const uint8_t* buffer, size_t size) {
flatbuffers::Verifier verifier(buffer, size);
@@ -563,24 +61,18 @@ bool IndexedRulesetMatcher::Verify(const uint8_t* buffer, size_t size) {
}
IndexedRulesetMatcher::IndexedRulesetMatcher(const uint8_t* buffer, size_t size)
- : root_(flat::GetIndexedRuleset(buffer)) {
- const flat::UrlPatternIndex* index = root_->blacklist_index();
- DCHECK(!index || index->n() == kNGramSize);
- index = root_->whitelist_index();
- DCHECK(!index || index->n() == kNGramSize);
-}
+ : root_(flat::GetIndexedRuleset(buffer)),
+ blacklist_(root_->blacklist_index()),
+ whitelist_(root_->whitelist_index()),
+ deactivation_(root_->deactivation_index()) {}
bool IndexedRulesetMatcher::ShouldDisableFilteringForDocument(
const GURL& document_url,
const url::Origin& parent_document_origin,
proto::ActivationType activation_type) const {
- if (!document_url.is_valid() ||
- activation_type == proto::ACTIVATION_TYPE_UNSPECIFIED) {
- return false;
- }
- return IsMatch(
- root_->activation_index(), document_url, parent_document_origin,
- proto::ELEMENT_TYPE_UNSPECIFIED, activation_type,
+ return !!deactivation_.FindMatch(
+ document_url, parent_document_origin, proto::ELEMENT_TYPE_UNSPECIFIED,
+ activation_type,
FirstPartyOrigin::IsThirdParty(document_url, parent_document_origin),
false);
}
@@ -590,15 +82,13 @@ bool IndexedRulesetMatcher::ShouldDisallowResourceLoad(
const FirstPartyOrigin& first_party,
proto::ElementType element_type,
bool disable_generic_rules) const {
- if (!url.is_valid() || element_type == proto::ELEMENT_TYPE_UNSPECIFIED)
- return false;
const bool is_third_party = first_party.IsThirdParty(url);
- return IsMatch(root_->blacklist_index(), url, first_party.origin(),
- element_type, proto::ACTIVATION_TYPE_UNSPECIFIED,
- is_third_party, disable_generic_rules) &&
- !IsMatch(root_->whitelist_index(), url, first_party.origin(),
- element_type, proto::ACTIVATION_TYPE_UNSPECIFIED,
- is_third_party, disable_generic_rules);
+ return !!blacklist_.FindMatch(url, first_party.origin(), element_type,
+ proto::ACTIVATION_TYPE_UNSPECIFIED,
+ is_third_party, disable_generic_rules) &&
+ !whitelist_.FindMatch(url, first_party.origin(), element_type,
+ proto::ACTIVATION_TYPE_UNSPECIFIED,
+ is_third_party, disable_generic_rules);
}
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/indexed_ruleset.h b/chromium/components/subresource_filter/core/common/indexed_ruleset.h
index a9fbd941e02..00588f8a0a7 100644
--- a/chromium/components/subresource_filter/core/common/indexed_ruleset.h
+++ b/chromium/components/subresource_filter/core/common/indexed_ruleset.h
@@ -5,33 +5,28 @@
#ifndef COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_INDEXED_RULESET_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_INDEXED_RULESET_H_
+#include <stddef.h>
#include <stdint.h>
-#include <vector>
-
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
-#include "base/strings/string_piece.h"
-#include "components/subresource_filter/core/common/closed_hash_map.h"
-#include "components/subresource_filter/core/common/flat/rules_generated.h"
-#include "components/subresource_filter/core/common/proto/rules.pb.h"
-#include "components/subresource_filter/core/common/uint64_hasher.h"
-#include "url/gurl.h"
-#include "url/origin.h"
+#include "components/subresource_filter/core/common/flat/indexed_ruleset_generated.h"
+#include "components/subresource_filter/core/common/url_pattern_index.h"
+#include "third_party/flatbuffers/src/include/flatbuffers/flatbuffers.h"
+
+class GURL;
+
+namespace url {
+class Origin;
+}
namespace subresource_filter {
class FirstPartyOrigin;
-// The integer type used to represent N-grams.
-using NGram = uint64_t;
-// The hasher used for hashing N-grams.
-using NGramHasher = Uint64Hasher;
-// The hash table probe sequence used both by the ruleset builder and matcher.
-using NGramHashTableProber = DefaultProber<NGram, NGramHasher>;
-
-constexpr size_t kNGramSize = 5;
-static_assert(kNGramSize <= sizeof(NGram), "NGram type is too narrow.");
+namespace proto {
+class UrlRule;
+}
// The class used to construct flat data structures representing the set of URL
// filtering rules, as well as the index of those. Internally owns a
@@ -39,6 +34,12 @@ static_assert(kNGramSize <= sizeof(NGram), "NGram type is too narrow.");
class RulesetIndexer {
public:
// The current binary format version of the indexed ruleset.
+ //
+ // Increase this value when introducing an incompatible change in
+ // IndexedRuleset format, or otherwise willing to nudge clients to rebuild
+ // their ruleset (e.g., a change is compatible, but significantly reduces the
+ // size of the buffer). Note: The PRESUBMIT.py script tries to keep
+ // contributors aware of that.
static const int kIndexedFormatVersion;
RulesetIndexer();
@@ -60,45 +61,12 @@ class RulesetIndexer {
size_t size() const { return base::strict_cast<size_t>(builder_.GetSize()); }
private:
- using MutableUrlRuleList = std::vector<flatbuffers::Offset<flat::UrlRule>>;
- using MutableNGramIndex =
- ClosedHashMap<NGram, MutableUrlRuleList, NGramHashTableProber>;
-
- // Encapsulates a subset of the rules, and an index built on the URL patterns
- // in these rules. The ruleset is divided into parts according to metadata of
- // the rules. Currently there are two parts: blacklist and whitelist.
- struct MutableUrlPatternIndex {
- // This index contains all non-REGEXP rules that have at least one
- // acceptable N-gram. For a single rule the N-gram used as an index key is
- // picked greedily (see GetMostDistinctiveNGram).
- MutableNGramIndex ngram_index;
-
- // A fallback list that contains all the rules with no acceptable N-gram,
- // and all the REGEXP rules.
- MutableUrlRuleList fallback_rules;
-
- MutableUrlPatternIndex();
- ~MutableUrlPatternIndex();
- };
-
- // Returns an N-gram of the |pattern| encoded into the NGram integer type. The
- // N-gram is picked using a greedy heuristic, i.e. the one is chosen which
- // corresponds to the shortest list of rules within the |index|. If there are
- // no valid N-grams in the |pattern|, the return value is 0.
- static NGram GetMostDistinctiveNGram(const MutableNGramIndex& index,
- base::StringPiece pattern);
-
- // Serialized an |index| built over a part of the ruleset, and returns its
- // offset in the FlatBuffer.
- flatbuffers::Offset<flat::UrlPatternIndex> SerializeUrlPatternIndex(
- const MutableUrlPatternIndex& index);
-
- MutableUrlPatternIndex blacklist_;
- MutableUrlPatternIndex whitelist_;
- MutableUrlPatternIndex activation_;
-
flatbuffers::FlatBufferBuilder builder_;
+ UrlPatternIndexBuilder blacklist_;
+ UrlPatternIndexBuilder whitelist_;
+ UrlPatternIndexBuilder deactivation_;
+
DISALLOW_COPY_AND_ASSIGN(RulesetIndexer);
};
@@ -136,6 +104,10 @@ class IndexedRulesetMatcher {
private:
const flat::IndexedRuleset* root_;
+ UrlPatternIndexMatcher blacklist_;
+ UrlPatternIndexMatcher whitelist_;
+ UrlPatternIndexMatcher deactivation_;
+
DISALLOW_COPY_AND_ASSIGN(IndexedRulesetMatcher);
};
diff --git a/chromium/components/subresource_filter/core/common/indexed_ruleset_unittest.cc b/chromium/components/subresource_filter/core/common/indexed_ruleset_unittest.cc
index 998fd747322..bf94498f8e2 100644
--- a/chromium/components/subresource_filter/core/common/indexed_ruleset_unittest.cc
+++ b/chromium/components/subresource_filter/core/common/indexed_ruleset_unittest.cc
@@ -5,729 +5,105 @@
#include "components/subresource_filter/core/common/indexed_ruleset.h"
#include <memory>
-#include <string>
-#include <vector>
#include "base/logging.h"
#include "base/macros.h"
-#include "base/strings/string_util.h"
+#include "base/strings/string_piece.h"
#include "components/subresource_filter/core/common/first_party_origin.h"
#include "components/subresource_filter/core/common/proto/rules.pb.h"
#include "components/subresource_filter/core/common/url_pattern.h"
+#include "components/subresource_filter/core/common/url_rule_test_support.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
namespace subresource_filter {
-namespace {
+using namespace testing;
-constexpr proto::AnchorType kAnchorNone = proto::ANCHOR_TYPE_NONE;
-constexpr proto::AnchorType kBoundary = proto::ANCHOR_TYPE_BOUNDARY;
-constexpr proto::AnchorType kSubdomain = proto::ANCHOR_TYPE_SUBDOMAIN;
-constexpr proto::UrlPatternType kSubstring = proto::URL_PATTERN_TYPE_SUBSTRING;
-
-constexpr proto::SourceType kAnyParty = proto::SOURCE_TYPE_ANY;
-constexpr proto::SourceType kFirstParty = proto::SOURCE_TYPE_FIRST_PARTY;
-constexpr proto::SourceType kThirdParty = proto::SOURCE_TYPE_THIRD_PARTY;
-
-constexpr proto::ElementType kAllElementTypes = proto::ELEMENT_TYPE_ALL;
-constexpr proto::ElementType kOther = proto::ELEMENT_TYPE_OTHER;
-constexpr proto::ElementType kImage = proto::ELEMENT_TYPE_IMAGE;
-constexpr proto::ElementType kFont = proto::ELEMENT_TYPE_FONT;
-constexpr proto::ElementType kScript = proto::ELEMENT_TYPE_SCRIPT;
-constexpr proto::ElementType kPopup = proto::ELEMENT_TYPE_POPUP;
-constexpr proto::ElementType kWebSocket = proto::ELEMENT_TYPE_WEBSOCKET;
-
-constexpr proto::ActivationType kDocument = proto::ACTIVATION_TYPE_DOCUMENT;
-constexpr proto::ActivationType kGenericBlock =
- proto::ACTIVATION_TYPE_GENERICBLOCK;
-
-// Note: Returns unique origin on origin_string == nullptr.
-url::Origin GetOrigin(const char* origin_string) {
- return origin_string ? url::Origin(GURL(origin_string)) : url::Origin();
-}
-
-class UrlRuleBuilder {
+class SubresourceFilterIndexedRulesetTest : public ::testing::Test {
public:
- explicit UrlRuleBuilder(const UrlPattern& url_pattern,
- bool is_whitelist = false)
- : UrlRuleBuilder(url_pattern, kAnyParty, is_whitelist) {}
-
- UrlRuleBuilder(const UrlPattern& url_pattern,
- proto::SourceType source_type,
- bool is_whitelist) {
- rule_.set_semantics(is_whitelist ? proto::RULE_SEMANTICS_WHITELIST
- : proto::RULE_SEMANTICS_BLACKLIST);
-
- rule_.set_source_type(source_type);
- rule_.set_element_types(kAllElementTypes);
-
- rule_.set_url_pattern_type(url_pattern.type());
- rule_.set_anchor_left(url_pattern.anchor_left());
- rule_.set_anchor_right(url_pattern.anchor_right());
- rule_.set_match_case(url_pattern.match_case());
- rule_.set_url_pattern(url_pattern.url_pattern().as_string());
- }
-
- UrlRuleBuilder& AddDomain(std::string domain_pattern) {
- DCHECK(!domain_pattern.empty());
- auto* domain = rule_.add_domains();
- if (domain_pattern[0] == '~') {
- domain_pattern.erase(0, 1);
- domain->set_exclude(true);
- }
- domain->set_domain(domain_pattern);
- return *this;
- }
-
- UrlRuleBuilder& AddDomains(const std::vector<std::string>& domains) {
- for (const std::string domain : domains)
- AddDomain(domain);
- return *this;
- }
-
- const proto::UrlRule& rule() const { return rule_; }
- proto::UrlRule& rule() { return rule_; }
-
- private:
- proto::UrlRule rule_;
-
- DISALLOW_COPY_AND_ASSIGN(UrlRuleBuilder);
-};
-
-} // namespace
-
-class SubresourceFilterIndexedRulesetTest : public testing::Test {
- public:
- SubresourceFilterIndexedRulesetTest() = default;
+ SubresourceFilterIndexedRulesetTest() { Reset(); }
protected:
- bool ShouldAllow(const char* url,
- const char* document_origin = nullptr,
+ bool ShouldAllow(base::StringPiece url,
+ base::StringPiece document_origin = nullptr,
proto::ElementType element_type = kOther,
bool disable_generic_rules = false) const {
- DCHECK_NE(matcher_.get(), nullptr);
- url::Origin origin = GetOrigin(document_origin);
- FirstPartyOrigin first_party(origin);
+ DCHECK(matcher_);
return !matcher_->ShouldDisallowResourceLoad(
- GURL(url), first_party, element_type, disable_generic_rules);
- }
-
- bool ShouldAllow(const char* url,
- const char* document_origin,
- bool disable_generic_rules) const {
- return ShouldAllow(url, document_origin, kOther, disable_generic_rules);
+ GURL(url), FirstPartyOrigin(GetOrigin(document_origin)), element_type,
+ disable_generic_rules);
}
- bool ShouldDeactivate(const char* document_url,
- const char* parent_document_origin = nullptr,
- proto::ActivationType activation_type =
- proto::ACTIVATION_TYPE_UNSPECIFIED) const {
+ bool ShouldDeactivate(
+ base::StringPiece document_url,
+ base::StringPiece parent_document_origin = nullptr,
+ proto::ActivationType activation_type = kNoActivation) const {
DCHECK(matcher_);
- url::Origin origin = GetOrigin(parent_document_origin);
- return matcher_->ShouldDisableFilteringForDocument(GURL(document_url),
- origin, activation_type);
+ return matcher_->ShouldDisableFilteringForDocument(
+ GURL(document_url), GetOrigin(parent_document_origin), activation_type);
}
- void AddUrlRule(const proto::UrlRule& rule) {
- ASSERT_TRUE(indexer_.AddUrlRule(rule)) << "URL pattern: "
- << rule.url_pattern();
+ bool AddUrlRule(const proto::UrlRule& rule) {
+ return indexer_->AddUrlRule(rule);
}
- void AddSimpleRule(const UrlPattern& url_pattern, bool is_whitelist) {
- AddUrlRule(UrlRuleBuilder(url_pattern, is_whitelist).rule());
+ bool AddSimpleRule(base::StringPiece url_pattern) {
+ return AddUrlRule(MakeUrlRule(UrlPattern(url_pattern, kSubstring)));
}
- void AddBlacklistRule(const UrlPattern& url_pattern,
- proto::SourceType source_type = kAnyParty) {
- AddUrlRule(UrlRuleBuilder(url_pattern, source_type, false).rule());
+ bool AddSimpleWhitelistRule(base::StringPiece url_pattern) {
+ auto rule = MakeUrlRule(UrlPattern(url_pattern, kSubstring));
+ rule.set_semantics(proto::RULE_SEMANTICS_WHITELIST);
+ return AddUrlRule(rule);
}
- void AddWhitelistRuleWithActivationTypes(const UrlPattern& url_pattern,
- int32_t activation_types) {
- UrlRuleBuilder builder(url_pattern, kAnyParty, true);
- builder.rule().set_element_types(proto::ELEMENT_TYPE_UNSPECIFIED);
- builder.rule().set_activation_types(activation_types);
- AddUrlRule(builder.rule());
+ bool AddSimpleWhitelistRule(base::StringPiece url_pattern,
+ int32_t activation_types) {
+ auto rule = MakeUrlRule(UrlPattern(url_pattern, kSubstring));
+ rule.set_semantics(proto::RULE_SEMANTICS_WHITELIST);
+ rule.clear_element_types();
+ rule.set_activation_types(activation_types);
+ return AddUrlRule(rule);
}
void Finish() {
- indexer_.Finish();
- matcher_.reset(new IndexedRulesetMatcher(indexer_.data(), indexer_.size()));
+ indexer_->Finish();
+ matcher_.reset(
+ new IndexedRulesetMatcher(indexer_->data(), indexer_->size()));
}
void Reset() {
matcher_.reset(nullptr);
- indexer_.~RulesetIndexer();
- new (&indexer_) RulesetIndexer();
+ indexer_.reset(new RulesetIndexer);
}
- RulesetIndexer indexer_;
+ std::unique_ptr<RulesetIndexer> indexer_;
std::unique_ptr<IndexedRulesetMatcher> matcher_;
private:
DISALLOW_COPY_AND_ASSIGN(SubresourceFilterIndexedRulesetTest);
};
-TEST_F(SubresourceFilterIndexedRulesetTest, OneRuleWithoutMetaInfo) {
- const struct {
- UrlPattern url_pattern;
- const char* url;
- bool expect_allowed;
- } kTestCases[] = {
- // SUBSTRING
- {{"abcd", kSubstring}, "http://example.com/abcd", false},
- {{"abcd", kSubstring}, "http://example.com/dcab", true},
- {{"42", kSubstring}, "http://example.com/adcd/picture42.png", false},
- {{"&test", kSubstring},
- "http://example.com/params?para1=false&test=true",
- false},
- {{"-test-42.", kSubstring}, "http://example.com/unit-test-42.1", false},
- {{"/abcdtest160x600.", kSubstring},
- "http://example.com/abcdtest160x600.png",
- false},
-
- // WILDCARDED
- {{"http://example.com/abcd/picture*.png"},
- "http://example.com/abcd/picture42.png",
- false},
- {{"example.com", kSubdomain, kAnchorNone}, "http://example.com", false},
- {{"example.com", kSubdomain, kAnchorNone},
- "http://test.example.com",
- false},
- {{"example.com", kSubdomain, kAnchorNone},
- "https://test.example.com.com",
- false},
- {{"example.com", kSubdomain, kAnchorNone},
- "https://test.rest.example.com",
- false},
- {{"example.com", kSubdomain, kAnchorNone},
- "https://test_example.com",
- true},
-
- {{"http://example.com", kBoundary, kAnchorNone},
- "http://example.com/",
- false},
- {{"http://example.com", kBoundary, kAnchorNone},
- "http://example.com/42",
- false},
- {{"http://example.com", kBoundary, kAnchorNone},
- "http://example.com/42/http://example.com/",
- false},
- {{"http://example.com", kBoundary, kAnchorNone},
- "http://example.com/42/http://example.info/",
- false},
- {{"http://example.com/", kBoundary, kBoundary},
- "http://example.com",
- false},
- {{"http://example.com/", kBoundary, kBoundary},
- "http://example.com/42",
- true},
- {{"http://example.com/", kBoundary, kBoundary},
- "http://example.info/42/http://example.com/",
- true},
- {{"http://example.com/", kBoundary, kBoundary},
- "http://example.info/42/http://example.com/",
- true},
- {{"http://example.com/", kBoundary, kBoundary},
- "http://example.com/",
- false},
- {{"http://example.com/", kBoundary, kBoundary},
- "http://example.com/42.swf",
- true},
- {{"http://example.com/", kBoundary, kBoundary},
- "http://example.info/redirect/http://example.com/",
- true},
- {{"pdf", kAnchorNone, kBoundary}, "http://example.com/abcd.pdf", false},
- {{"pdf", kAnchorNone, kBoundary}, "http://example.com/pdfium", true},
- {{"http://example.com^"}, "http://example.com/", false},
- {{"http://example.com^"}, "http://example.com:8000/", false},
- {{"http://example.com^"}, "http://example.com.ru", true},
- {{"^example.com^"},
- "http://example.com:8000/42.loss?a=12&b=%D1%82%D0%B5%D1%81%D1%82",
- false},
- {{"^42.loss^"},
- "http://example.com:8000/42.loss?a=12&b=%D1%82%D0%B5%D1%81%D1%82",
- false},
-
- // FIXME(pkalinnikov): The '^' at the end should match end-of-string.
- // {"^%D1%82%D0%B5%D1%81%D1%82^",
- // "http://example.com:8000/42.loss?a=12&b=%D1%82%D0%B5%D1%81%D1%82",
- // false},
- // {"/abcd/*/picture^", "http://example.com/abcd/42/picture", false},
-
- {{"/abcd/*/picture^"},
- "http://example.com/abcd/42/loss/picture?param",
- false},
- {{"/abcd/*/picture^"}, "http://example.com/abcd//picture/42", false},
- {{"/abcd/*/picture^"}, "http://example.com/abcd/picture", true},
- {{"/abcd/*/picture^"}, "http://example.com/abcd/42/pictureraph", true},
- {{"/abcd/*/picture^"}, "http://example.com/abcd/42/picture.swf", true},
- {{"test.example.com^", kSubdomain, kAnchorNone},
- "http://test.example.com/42.swf",
- false},
- {{"test.example.com^", kSubdomain, kAnchorNone},
- "http://server1.test.example.com/42.swf",
- false},
- {{"test.example.com^", kSubdomain, kAnchorNone},
- "https://test.example.com:8000/",
- false},
- {{"test.example.com^", kSubdomain, kAnchorNone},
- "http://test.example.com.ua/42.swf",
- true},
- {{"test.example.com^", kSubdomain, kAnchorNone},
- "http://example.com/redirect/http://test.example.com/",
- true},
-
- {{"/abcd/*"}, "https://example.com/abcd/", false},
- {{"/abcd/*"}, "http://example.com/abcd/picture.jpeg", false},
- {{"/abcd/*"}, "https://example.com/abcd", true},
- {{"/abcd/*"}, "http://abcd.example.com", true},
- {{"*/abcd/"}, "https://example.com/abcd/", false},
- {{"*/abcd/"}, "http://example.com/abcd/picture.jpeg", false},
- {{"*/abcd/"}, "https://example.com/test-abcd/", true},
- {{"*/abcd/"}, "http://abcd.example.com", true},
-
- // FIXME(pkalinnikov): Implement REGEXP matching.
- // REGEXP
- // {"/test|rest\\d+/", "http://example.com/test42", false},
- // {"/test|rest\\d+/", "http://example.com/test", false},
- // {"/test|rest\\d+/", "http://example.com/rest42", false},
- // {"/test|rest\\d+/", "http://example.com/rest", true},
- // {"/example\\.com/.*\\/[a-zA-Z0-9]{3}/", "http://example.com/abcd/42y",
- // false},
- // {"/example\\.com/.*\\/[a-zA-Z0-9]{3}/", "http://example.com/abcd/%42y",
- // true},
- // {"||example.com^*/test.htm", "http://example.com/unit/test.html",
- // false},
- // {"||example.com^*/test.htm", "http://examole.com/test.htm", true},
- };
-
- for (const auto& test_case : kTestCases) {
- SCOPED_TRACE(testing::Message() << "Rule: " << test_case.url_pattern
- << "; URL: " << test_case.url);
-
- AddBlacklistRule(test_case.url_pattern);
- Finish();
-
- EXPECT_EQ(test_case.expect_allowed, ShouldAllow(test_case.url));
- Reset();
- }
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest, OneRuleWithThirdParty) {
- const struct {
- const char* url_pattern;
- proto::SourceType source_type;
-
- const char* url;
- const char* document_origin;
- bool expect_allowed;
- } kTestCases[] = {
- {"example.com", kThirdParty, "http://example.com", "http://exmpl.org",
- false},
- {"example.com", kThirdParty, "http://example.com", "http://example.com",
- true},
- {"example.com", kThirdParty, "http://example.com/path?k=v",
- "http://exmpl.org", false},
- {"example.com", kThirdParty, "http://example.com/path?k=v",
- "http://example.com", true},
- {"example.com", kFirstParty, "http://example.com/path?k=v",
- "http://example.com", false},
- {"example.com", kFirstParty, "http://example.com/path?k=v",
- "http://exmpl.com", true},
- {"example.com", kAnyParty, "http://example.com/path?k=v",
- "http://example.com", false},
- {"example.com", kAnyParty, "http://example.com/path?k=v",
- "http://exmpl.com", false},
- {"example.com", kThirdParty, "http://subdomain.example.com",
- "http://example.com", true},
- {"example.com", kThirdParty, "http://example.com", nullptr, false},
-
- // Public Suffix List tests.
- {"example.com", kThirdParty, "http://two.example.com",
- "http://one.example.com", true},
- {"example.com", kThirdParty, "http://example.com",
- "http://one.example.com", true},
- {"example.com", kThirdParty, "http://two.example.com",
- "http://example.com", true},
- {"example.com", kThirdParty, "http://example.com", "http://example.org",
- false},
- {"appspot.com", kThirdParty, "http://two.appspot.org",
- "http://one.appspot.com", true},
- };
-
- for (auto test_case : kTestCases) {
- SCOPED_TRACE(testing::Message()
- << "Rule: " << test_case.url_pattern << "; source: "
- << (int)test_case.source_type << "; URL: " << test_case.url
- << "; document: " << test_case.document_origin);
-
- AddBlacklistRule(UrlPattern(test_case.url_pattern, kSubstring),
- test_case.source_type);
- Finish();
-
- EXPECT_EQ(test_case.expect_allowed,
- ShouldAllow(test_case.url, test_case.document_origin));
- Reset();
- }
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest, OneRuleWithDomainList) {
- constexpr const char* kUrl = "http://example.com";
-
- const struct {
- std::vector<std::string> domains;
- const char* document_origin;
-
- bool expect_allowed;
- } kTestCases[] = {
- {std::vector<std::string>(), nullptr, false},
- {std::vector<std::string>(), "http://domain.com", false},
-
- {{"domain.com"}, nullptr, true},
- {{"domain.com"}, "http://domain.com", false},
- {{"ddomain.com"}, "http://domain.com", true},
- {{"domain.com"}, "http://ddomain.com", true},
- {{"domain.com"}, "http://sub.domain.com", false},
- {{"sub.domain.com"}, "http://domain.com", true},
- {{"sub.domain.com"}, "http://sub.domain.com", false},
- {{"sub.domain.com"}, "http://a.b.c.sub.domain.com", false},
- {{"sub.domain.com"}, "http://sub.domain.com.com", true},
-
- // TODO(pkalinnikov): Probably need to canonicalize domain patterns to
- // avoid subtleties like below.
- {{"domain.com"}, "http://domain.com.", false},
- {{"domain.com"}, "http://.domain.com", false},
- {{"domain.com"}, "http://.domain.com.", false},
- {{".domain.com"}, "http://.domain.com", false},
- {{"domain.com."}, "http://domain.com", true},
- {{"domain.com."}, "http://domain.com.", false},
-
- {{"domain..com"}, "http://domain.com", true},
- {{"domain.com"}, "http://domain..com", true},
- {{"domain..com"}, "http://domain..com", false},
-
- {{"~domain.com"}, nullptr, false},
- {{"~domain.com"}, "http://domain.com", true},
- {{"~ddomain.com"}, "http://domain.com", false},
- {{"~domain.com"}, "http://ddomain.com", false},
- {{"~domain.com"}, "http://sub.domain.com", true},
- {{"~sub.domain.com"}, "http://domain.com", false},
- {{"~sub.domain.com"}, "http://sub.domain.com", true},
- {{"~sub.domain.com"}, "http://a.b.c.sub.domain.com", true},
- {{"~sub.domain.com"}, "http://sub.domain.com.com", false},
-
- {{"domain1.com", "domain2.com"}, nullptr, true},
- {{"domain1.com", "domain2.com"}, "http://domain1.com", false},
- {{"domain1.com", "domain2.com"}, "http://domain2.com", false},
- {{"domain1.com", "domain2.com"}, "http://domain3.com", true},
- {{"domain1.com", "domain2.com"}, "http://not_domain1.com", true},
- {{"domain1.com", "domain2.com"}, "http://sub.domain1.com", false},
- {{"domain1.com", "domain2.com"}, "http://a.b.c.sub.domain2.com", false},
-
- {{"~domain1.com", "~domain2.com"}, "http://domain1.com", true},
- {{"~domain1.com", "~domain2.com"}, "http://domain2.com", true},
- {{"~domain1.com", "~domain2.com"}, "http://domain3.com", false},
-
- {{"domain.com", "~sub.domain.com"}, "http://domain.com", false},
- {{"domain.com", "~sub.domain.com"}, "http://sub.domain.com", true},
- {{"domain.com", "~sub.domain.com"}, "http://a.b.sub.domain.com", true},
- {{"domain.com", "~sub.domain.com"}, "http://ssub.domain.com", false},
-
- {{"domain.com", "~a.domain.com", "~b.domain.com"},
- "http://domain.com",
- false},
- {{"domain.com", "~a.domain.com", "~b.domain.com"},
- "http://a.domain.com",
- true},
- {{"domain.com", "~a.domain.com", "~b.domain.com"},
- "http://b.domain.com",
- true},
-
- {{"domain.com", "~a.domain.com", "b.a.domain.com"},
- "http://domain.com",
- false},
- {{"domain.com", "~a.domain.com", "b.a.domain.com"},
- "http://a.domain.com",
- true},
- {{"domain.com", "~a.domain.com", "b.a.domain.com"},
- "http://b.a.domain.com",
- false},
- {{"domain.com", "~a.domain.com", "b.a.domain.com"},
- "http://c.b.a.domain.com",
- false},
-
- // The following test addresses a former bug in domain list matcher. When
- // "domain.com" was matched, the positive filters lookup stopped, and the
- // next domain was considered as a negative. The initial character was
- // skipped (supposing it's a '~') and the remainder was considered a
- // domain. So "ddomain.com" would be matched and thus the whole rule would
- // be classified as non-matching, which is not correct.
- {{"domain.com", "ddomain.com", "~sub.domain.com"},
- "http://domain.com",
- false},
- };
-
- for (const auto& test_case : kTestCases) {
- SCOPED_TRACE(testing::Message()
- << "Domains: " << base::JoinString(test_case.domains, "|")
- << "; document: " << test_case.document_origin);
-
- UrlRuleBuilder builder(UrlPattern(kUrl, kSubstring));
- builder.AddDomains(test_case.domains);
- AddUrlRule(builder.rule());
- Finish();
-
- EXPECT_EQ(test_case.expect_allowed,
- ShouldAllow(kUrl, test_case.document_origin));
- Reset();
- }
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest, OneRuleWithLongDomainList) {
- constexpr const char* kUrl = "http://example.com";
- constexpr size_t kDomains = 200;
-
- std::vector<std::string> domains;
- for (size_t i = 0; i < kDomains; ++i) {
- const std::string domain = "domain" + std::to_string(i) + ".com";
- domains.push_back(domain);
- domains.push_back("~sub." + domain);
- domains.push_back("a.sub." + domain);
- domains.push_back("b.sub." + domain);
- domains.push_back("c.sub." + domain);
- domains.push_back("~aa.sub." + domain);
- domains.push_back("~ab.sub." + domain);
- domains.push_back("~ba.sub." + domain);
- domains.push_back("~bb.sub." + domain);
- domains.push_back("~sub.sub.c.sub." + domain);
- }
-
- UrlRuleBuilder builder(UrlPattern(kUrl, kSubstring));
- builder.AddDomains(domains);
- AddUrlRule(builder.rule());
- Finish();
-
- for (size_t i = 0; i < kDomains; ++i) {
- SCOPED_TRACE(testing::Message() << "Iteration: " << i);
- const std::string domain = "domain" + std::to_string(i) + ".com";
-
- EXPECT_FALSE(ShouldAllow(kUrl, ("http://" + domain).c_str()));
- EXPECT_TRUE(ShouldAllow(kUrl, ("http://sub." + domain).c_str()));
- EXPECT_FALSE(ShouldAllow(kUrl, ("http://a.sub." + domain).c_str()));
- EXPECT_FALSE(ShouldAllow(kUrl, ("http://b.sub." + domain).c_str()));
- EXPECT_FALSE(ShouldAllow(kUrl, ("http://c.sub." + domain).c_str()));
- EXPECT_TRUE(ShouldAllow(kUrl, ("http://aa.sub." + domain).c_str()));
- EXPECT_TRUE(ShouldAllow(kUrl, ("http://ab.sub." + domain).c_str()));
- EXPECT_TRUE(ShouldAllow(kUrl, ("http://ba.sub." + domain).c_str()));
- EXPECT_TRUE(ShouldAllow(kUrl, ("http://bb.sub." + domain).c_str()));
- EXPECT_FALSE(ShouldAllow(kUrl, ("http://sub.c.sub." + domain).c_str()));
- EXPECT_TRUE(ShouldAllow(kUrl, ("http://sub.sub.c.sub." + domain).c_str()));
- }
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest, OneRuleWithElementTypes) {
- constexpr auto kAll = kAllElementTypes;
- const struct {
- const char* url_pattern;
- int32_t element_types;
-
- const char* url;
- proto::ElementType element_type;
- bool expect_allowed;
- } kTestCases[] = {
- {"ex.com", kAll, "http://ex.com/img.jpg", kImage, false},
- {"ex.com", kAll & ~kPopup, "http://ex.com/img", kPopup, true},
-
- {"ex.com", kImage, "http://ex.com/img.jpg", kImage, false},
- {"ex.com", kAll & ~kImage, "http://ex.com/img.jpg", kImage, true},
- {"ex.com", kScript, "http://ex.com/img.jpg", kImage, true},
- {"ex.com", kAll & ~kScript, "http://ex.com/img.jpg", kImage, false},
-
- {"ex.com", kImage | kFont, "http://ex.com/font", kFont, false},
- {"ex.com", kImage | kFont, "http://ex.com/image", kImage, false},
- {"ex.com", kImage | kFont, "http://ex.com/video",
- proto::ELEMENT_TYPE_MEDIA, true},
- {"ex.com", kAll & ~kFont & ~kScript, "http://ex.com/font", kFont, true},
- {"ex.com", kAll & ~kFont & ~kScript, "http://ex.com/scr", kScript, true},
- {"ex.com", kAll & ~kFont & ~kScript, "http://ex.com/img", kImage, false},
-
- {"ex.com", kAll, "http://ex.com", proto::ELEMENT_TYPE_OTHER, false},
- {"ex.com", kAll, "http://ex.com", proto::ELEMENT_TYPE_UNSPECIFIED, true},
- {"ex.com", kWebSocket, "ws://ex.com", proto::ELEMENT_TYPE_WEBSOCKET,
- false},
- };
-
- for (const auto& test_case : kTestCases) {
- SCOPED_TRACE(testing::Message()
- << "Rule: " << test_case.url_pattern << "; ElementTypes: "
- << (int)test_case.element_types << "; URL: " << test_case.url
- << "; ElementType: " << (int)test_case.element_type);
-
- UrlRuleBuilder builder(UrlPattern(test_case.url_pattern, kSubstring));
- builder.rule().set_element_types(test_case.element_types);
- AddUrlRule(builder.rule());
- Finish();
-
- EXPECT_EQ(test_case.expect_allowed,
- ShouldAllow(test_case.url, nullptr /* document_origin */,
- test_case.element_type));
- Reset();
- }
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest, OneRuleWithActivationTypes) {
- constexpr proto::ActivationType kNone = proto::ACTIVATION_TYPE_UNSPECIFIED;
-
- const struct {
- const char* url_pattern;
- int32_t activation_types;
-
- const char* document_url;
- proto::ActivationType activation_type;
- bool expect_disabled;
- } kTestCases[] = {
- {"example.com", kDocument, "http://example.com", kDocument, true},
- {"xample.com", kDocument, "http://example.com", kDocument, true},
- {"exampl.com", kDocument, "http://example.com", kDocument, false},
-
- {"example.com", kGenericBlock, "http://example.com", kDocument, false},
- {"example.com", kDocument, "http://example.com", kNone, false},
- {"example.com", kGenericBlock, "http://example.com", kNone, false},
-
- // Invalid GURL.
- {"example.com", kDocument, "http;//example.com", kDocument, false},
- };
-
- for (const auto& test_case : kTestCases) {
- SCOPED_TRACE(testing::Message()
- << "Rule: " << test_case.url_pattern
- << "; ActivationTypes: " << (int)test_case.activation_types
- << "; DocURL: " << test_case.document_url
- << "; ActivationType: " << (int)test_case.activation_type);
-
- AddWhitelistRuleWithActivationTypes(
- UrlPattern(test_case.url_pattern, kSubstring),
- test_case.activation_types);
- Finish();
-
- EXPECT_EQ(test_case.expect_disabled,
- ShouldDeactivate(test_case.document_url,
- nullptr /* parent_document_origin */,
- test_case.activation_type));
- EXPECT_EQ(test_case.expect_disabled,
- ShouldDeactivate(test_case.document_url, "http://example.com/",
- test_case.activation_type));
- EXPECT_EQ(test_case.expect_disabled,
- ShouldDeactivate(test_case.document_url, "http://xmpl.com/",
- test_case.activation_type));
- Reset();
- }
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest, RuleWithElementAndActivationTypes) {
- UrlRuleBuilder builder(UrlPattern("allow.ex.com"), true /* is_whitelist */);
- builder.rule().set_activation_types(kDocument);
-
- AddUrlRule(builder.rule());
- AddBlacklistRule(UrlPattern("ex.com"));
- Finish();
-
- EXPECT_FALSE(ShouldAllow("http://ex.com"));
- EXPECT_TRUE(ShouldAllow("http://allow.ex.com"));
- EXPECT_FALSE(ShouldDeactivate("http://allow.ex.com",
- nullptr /* parent_document_origin */,
- kGenericBlock));
- EXPECT_TRUE(ShouldDeactivate(
- "http://allow.ex.com", nullptr /* parent_document_origin */, kDocument));
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest, MatchWithDisableGenericRules) {
- // Generic rules.
- ASSERT_NO_FATAL_FAILURE(
- AddUrlRule(UrlRuleBuilder(UrlPattern("some_text", kSubstring)).rule()));
- ASSERT_NO_FATAL_FAILURE(
- AddUrlRule(UrlRuleBuilder(UrlPattern("another_text", kSubstring))
- .AddDomain("~example.com")
- .rule()));
-
- // Domain specific rules.
- ASSERT_NO_FATAL_FAILURE(
- AddUrlRule(UrlRuleBuilder(UrlPattern("some_text", kSubstring))
- .AddDomain("example1.com")
- .rule()));
- ASSERT_NO_FATAL_FAILURE(
- AddUrlRule(UrlRuleBuilder(UrlPattern("more_text", kSubstring))
- .AddDomain("example.com")
- .AddDomain("~exclude.example.com")
- .rule()));
- ASSERT_NO_FATAL_FAILURE(
- AddUrlRule(UrlRuleBuilder(UrlPattern("last_text", kSubstring))
- .AddDomain("example1.com")
- .AddDomain("sub.example2.com")
- .rule()));
- // Note: Some of the rules have common domains (e.g., example1.com), which are
- // ultimately shared by FlatBuffers' CreateSharedString. The test also makes
- // sure that the data structure works properly with such optimization.
-
- Finish();
-
- const struct {
- const char* url_pattern;
- const char* document_origin;
- bool should_allow_with_disable_generic_rules;
- bool should_allow_with_enable_all_rules;
- } kTestCases[] = {
- {"http://ex.com/some_text", "http://example.com", true, false},
- {"http://ex.com/some_text", "http://example1.com", false, false},
-
- {"http://ex.com/another_text", "http://example.com", true, true},
- {"http://ex.com/another_text", "http://example1.com", true, false},
-
- {"http://ex.com/more_text", "http://example.com", false, false},
- {"http://ex.com/more_text", "http://exclude.example.com", true, true},
- {"http://ex.com/more_text", "http://example1.com", true, true},
-
- {"http://ex.com/last_text", "http://example.com", true, true},
- {"http://ex.com/last_text", "http://example1.com", false, false},
- {"http://ex.com/last_text", "http://example2.com", true, true},
- {"http://ex.com/last_text", "http://sub.example2.com", false, false},
- };
-
- constexpr bool kDisableGenericRules = true;
- constexpr bool kEnableAllRules = false;
- for (const auto& test_case : kTestCases) {
- SCOPED_TRACE(testing::Message()
- << "Url: " << test_case.url_pattern
- << "; document: " << test_case.document_origin);
-
- EXPECT_EQ(test_case.should_allow_with_disable_generic_rules,
- ShouldAllow(test_case.url_pattern, test_case.document_origin,
- kDisableGenericRules));
- EXPECT_EQ(test_case.should_allow_with_enable_all_rules,
- ShouldAllow(test_case.url_pattern, test_case.document_origin,
- kEnableAllRules));
- }
-}
-
TEST_F(SubresourceFilterIndexedRulesetTest, EmptyRuleset) {
Finish();
+ EXPECT_TRUE(ShouldAllow(nullptr));
EXPECT_TRUE(ShouldAllow("http://example.com"));
EXPECT_TRUE(ShouldAllow("http://another.example.com?param=val"));
- EXPECT_TRUE(ShouldAllow(nullptr));
}
TEST_F(SubresourceFilterIndexedRulesetTest, NoRuleApplies) {
- AddSimpleRule(UrlPattern("?filtered_content=", kSubstring), false);
- AddSimpleRule(UrlPattern("&filtered_content=", kSubstring), false);
+ ASSERT_TRUE(AddSimpleRule("?filter_out="));
+ ASSERT_TRUE(AddSimpleRule("&filter_out="));
Finish();
EXPECT_TRUE(ShouldAllow("http://example.com"));
- EXPECT_TRUE(ShouldAllow("http://example.com?filtered_not"));
+ EXPECT_TRUE(ShouldAllow("http://example.com?filter_not"));
}
TEST_F(SubresourceFilterIndexedRulesetTest, SimpleBlacklist) {
- AddSimpleRule(UrlPattern("?param=", kSubstring), false);
+ ASSERT_TRUE(AddSimpleRule("?param="));
Finish();
EXPECT_TRUE(ShouldAllow("https://example.com"));
@@ -735,26 +111,26 @@ TEST_F(SubresourceFilterIndexedRulesetTest, SimpleBlacklist) {
}
TEST_F(SubresourceFilterIndexedRulesetTest, SimpleWhitelist) {
- AddSimpleRule(UrlPattern("example.com/?filtered_content=", kSubstring), true);
+ ASSERT_TRUE(AddSimpleWhitelistRule("example.com/?filter_out="));
Finish();
- EXPECT_TRUE(ShouldAllow("https://example.com?filtered_content=image1"));
+ EXPECT_TRUE(ShouldAllow("https://example.com?filter_out=true"));
}
-TEST_F(SubresourceFilterIndexedRulesetTest, BlacklistWhitelist) {
- AddSimpleRule(UrlPattern("?filter=", kSubstring), false);
- AddSimpleRule(UrlPattern("whitelisted.com/?filter=", kSubstring), true);
+TEST_F(SubresourceFilterIndexedRulesetTest, SimpleBlacklistAndWhitelist) {
+ ASSERT_TRUE(AddSimpleRule("?filter="));
+ ASSERT_TRUE(AddSimpleWhitelistRule("whitelisted.com/?filter="));
Finish();
- EXPECT_TRUE(ShouldAllow("https://whitelisted.com?filter=off"));
- EXPECT_TRUE(ShouldAllow("https://notblacklisted.com"));
EXPECT_FALSE(ShouldAllow("http://blacklisted.com?filter=on"));
+ EXPECT_TRUE(ShouldAllow("https://whitelisted.com?filter=on"));
+ EXPECT_TRUE(ShouldAllow("https://notblacklisted.com"));
}
-TEST_F(SubresourceFilterIndexedRulesetTest, BlacklistAndActivationType) {
- AddSimpleRule(UrlPattern("example.com", kSubstring), false);
- AddWhitelistRuleWithActivationTypes(UrlPattern("example.com", kSubstring),
- kDocument);
+TEST_F(SubresourceFilterIndexedRulesetTest,
+ OneBlacklistAndOneDeactivationRule) {
+ ASSERT_TRUE(AddSimpleRule("example.com"));
+ ASSERT_TRUE(AddSimpleWhitelistRule("example.com", kDocument));
Finish();
EXPECT_TRUE(ShouldDeactivate("https://example.com", nullptr, kDocument));
@@ -763,62 +139,4 @@ TEST_F(SubresourceFilterIndexedRulesetTest, BlacklistAndActivationType) {
EXPECT_TRUE(ShouldAllow("https://xample.com"));
}
-TEST_F(SubresourceFilterIndexedRulesetTest, RuleWithUnsupportedTypes) {
- const struct {
- int element_types;
- int activation_types;
- } kRules[] = {
- {proto::ELEMENT_TYPE_MAX << 1, 0},
- {0, proto::ACTIVATION_TYPE_MAX << 1},
- {proto::ELEMENT_TYPE_MAX << 1, proto::ACTIVATION_TYPE_MAX << 1},
-
- {kPopup, 0},
- {0, proto::ACTIVATION_TYPE_ELEMHIDE},
- {0, proto::ACTIVATION_TYPE_GENERICHIDE},
- {0, proto::ACTIVATION_TYPE_ELEMHIDE | proto::ACTIVATION_TYPE_GENERICHIDE},
- {proto::ELEMENT_TYPE_POPUP, proto::ACTIVATION_TYPE_ELEMHIDE},
- };
-
- for (const auto& rule : kRules) {
- UrlRuleBuilder builder(UrlPattern("example.com"));
- builder.rule().set_element_types(rule.element_types);
- builder.rule().set_activation_types(rule.activation_types);
- EXPECT_FALSE(indexer_.AddUrlRule(builder.rule()));
- }
- AddSimpleRule(UrlPattern("exmpl.com", kSubstring), false);
-
- Finish();
- EXPECT_TRUE(ShouldAllow("http://example.com/"));
- EXPECT_FALSE(ShouldAllow("https://exmpl.com/"));
-}
-
-TEST_F(SubresourceFilterIndexedRulesetTest,
- RuleWithSupportedAndUnsupportedTypes) {
- const struct {
- int element_types;
- int activation_types;
- } kRules[] = {
- {kImage | (proto::ELEMENT_TYPE_MAX << 1), 0},
- {kScript | kPopup, 0},
- {0, kDocument | (proto::ACTIVATION_TYPE_MAX << 1)},
- };
-
- for (const auto& rule : kRules) {
- UrlRuleBuilder builder(UrlPattern("example.com"));
- builder.rule().set_element_types(rule.element_types);
- builder.rule().set_activation_types(rule.activation_types);
- if (rule.activation_types)
- builder.rule().set_semantics(proto::RULE_SEMANTICS_WHITELIST);
- EXPECT_TRUE(indexer_.AddUrlRule(builder.rule()));
- }
- Finish();
-
- EXPECT_FALSE(ShouldAllow("http://example.com/", nullptr, kImage));
- EXPECT_FALSE(ShouldAllow("http://example.com/", nullptr, kScript));
- EXPECT_TRUE(ShouldAllow("http://example.com/"));
-
- EXPECT_TRUE(ShouldDeactivate("http://example.com", nullptr, kDocument));
- EXPECT_FALSE(ShouldDeactivate("http://example.com", nullptr, kGenericBlock));
-}
-
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/test_ruleset_creator.cc b/chromium/components/subresource_filter/core/common/test_ruleset_creator.cc
index 408a9845353..939dff3085e 100644
--- a/chromium/components/subresource_filter/core/common/test_ruleset_creator.cc
+++ b/chromium/components/subresource_filter/core/common/test_ruleset_creator.cc
@@ -8,7 +8,9 @@
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
+#include "base/threading/thread_restrictions.h"
#include "components/subresource_filter/core/common/indexed_ruleset.h"
#include "components/subresource_filter/core/common/proto/rules.pb.h"
#include "components/subresource_filter/core/common/test_ruleset_utils.h"
@@ -25,6 +27,7 @@ static_assert(CHAR_BIT == 8, "Assumed char was 8 bits.");
void WriteRulesetContents(const std::vector<uint8_t>& contents,
base::FilePath path) {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
int ruleset_size_as_int = base::checked_cast<int>(contents.size());
int num_bytes_written =
base::WriteFile(path, reinterpret_cast<const char*>(contents.data()),
@@ -65,6 +68,7 @@ TestRuleset::~TestRuleset() = default;
// static
base::File TestRuleset::Open(const TestRuleset& ruleset) {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
base::File file;
file.Initialize(ruleset.path, base::File::FLAG_OPEN | base::File::FLAG_READ |
base::File::FLAG_SHARE_DELETE);
@@ -105,8 +109,13 @@ TestRulesetPair::~TestRulesetPair() = default;
// TestRulesetCreator ----------------------------------------------------------
-TestRulesetCreator::TestRulesetCreator() = default;
-TestRulesetCreator::~TestRulesetCreator() = default;
+TestRulesetCreator::TestRulesetCreator()
+ : scoped_temp_dir_(base::MakeUnique<base::ScopedTempDir>()) {}
+
+TestRulesetCreator::~TestRulesetCreator() {
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ scoped_temp_dir_.reset();
+}
void TestRulesetCreator::CreateRulesetToDisallowURLsWithPathSuffix(
base::StringPiece suffix,
@@ -161,9 +170,10 @@ void TestRulesetCreator::CreateUnindexedRulesetWithRules(
void TestRulesetCreator::GetUniqueTemporaryPath(base::FilePath* path) {
DCHECK(path);
- ASSERT_TRUE(scoped_temp_dir_.IsValid() ||
- scoped_temp_dir_.CreateUniqueTempDir());
- *path = scoped_temp_dir_.GetPath().AppendASCII(
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ ASSERT_TRUE(scoped_temp_dir_->IsValid() ||
+ scoped_temp_dir_->CreateUniqueTempDir());
+ *path = scoped_temp_dir_->GetPath().AppendASCII(
base::IntToString(next_unique_file_suffix++));
}
diff --git a/chromium/components/subresource_filter/core/common/test_ruleset_creator.h b/chromium/components/subresource_filter/core/common/test_ruleset_creator.h
index 88338f60922..cb07526e787 100644
--- a/chromium/components/subresource_filter/core/common/test_ruleset_creator.h
+++ b/chromium/components/subresource_filter/core/common/test_ruleset_creator.h
@@ -98,7 +98,7 @@ class TestRulesetCreator {
void CreateTestRulesetFromContents(std::vector<uint8_t> ruleset_contents,
TestRuleset* ruleset);
- base::ScopedTempDir scoped_temp_dir_;
+ std::unique_ptr<base::ScopedTempDir> scoped_temp_dir_;
int next_unique_file_suffix = 1;
DISALLOW_COPY_AND_ASSIGN(TestRulesetCreator);
diff --git a/chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc b/chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
index bc66bbe13a4..f193b5ed46e 100644
--- a/chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
+++ b/chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
@@ -11,8 +11,8 @@
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
-#include "components/subresource_filter/core/common/proto/rules.pb.h"
#include "components/subresource_filter/core/common/url_pattern.h"
+#include "components/subresource_filter/core/common/url_rule_test_support.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h"
#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
@@ -21,35 +21,10 @@ namespace subresource_filter {
namespace {
-bool IsEqual(const proto::UrlRule& first, const proto::UrlRule& second) {
- // Note: The domain list is omitted for simplicity.
- return first.semantics() == second.semantics() &&
- first.source_type() == second.source_type() &&
- first.element_types() == second.element_types() &&
- first.activation_types() == second.activation_types() &&
- first.url_pattern_type() == second.url_pattern_type() &&
- first.anchor_left() == second.anchor_left() &&
- first.anchor_right() == second.anchor_right() &&
- first.match_case() == second.match_case() &&
- first.url_pattern() == second.url_pattern();
-}
+using namespace testing;
-proto::UrlRule CreateRule(const UrlPattern& url_pattern,
- proto::SourceType source_type,
- bool is_whitelist) {
- proto::UrlRule rule;
- rule.set_semantics(is_whitelist ? proto::RULE_SEMANTICS_WHITELIST
- : proto::RULE_SEMANTICS_BLACKLIST);
-
- rule.set_source_type(source_type);
- rule.set_element_types(proto::ELEMENT_TYPE_ALL);
-
- rule.set_url_pattern_type(url_pattern.type());
- rule.set_anchor_left(url_pattern.anchor_left());
- rule.set_anchor_right(url_pattern.anchor_right());
- rule.set_match_case(url_pattern.match_case());
- rule.set_url_pattern(url_pattern.url_pattern().as_string());
- return rule;
+bool IsEqual(const proto::UrlRule& lhs, const proto::UrlRule& rhs) {
+ return lhs.SerializeAsString() == rhs.SerializeAsString();
}
// The helper class used for building UnindexedRulesets.
@@ -76,8 +51,13 @@ class UnindexedRulesetTestBuilder {
bool AddUrlRule(const UrlPattern& url_pattern,
proto::SourceType source_type,
- bool is_whitelist) {
- url_rules_.push_back(CreateRule(url_pattern, source_type, is_whitelist));
+ bool is_whitelist = false) {
+ auto rule = MakeUrlRule(url_pattern);
+ if (is_whitelist)
+ rule.set_semantics(proto::RULE_SEMANTICS_WHITELIST);
+ rule.set_source_type(source_type);
+
+ url_rules_.push_back(rule);
return !ruleset_writer_.had_error() &&
ruleset_writer_.AddUrlRule(url_rules_.back());
}
@@ -85,7 +65,7 @@ class UnindexedRulesetTestBuilder {
bool AddUrlRules(int number_of_rules) {
for (int i = 0; i < number_of_rules; ++i) {
std::string url_pattern = "example" + base::IntToString(i) + ".com";
- if (!AddUrlRule(UrlPattern(url_pattern), proto::SOURCE_TYPE_ANY, i & 1))
+ if (!AddUrlRule(UrlPattern(url_pattern), kAnyParty, i & 1))
return false;
}
return true;
@@ -147,8 +127,7 @@ TEST(UnindexedRulesetTest, EmptyRuleset) {
TEST(UnindexedRulesetTest, OneUrlRule) {
UnindexedRulesetTestBuilder builder;
- EXPECT_TRUE(builder.AddUrlRule(UrlPattern("example.com"),
- proto::SOURCE_TYPE_THIRD_PARTY, false));
+ EXPECT_TRUE(builder.AddUrlRule(UrlPattern("example.com"), kThirdParty));
EXPECT_TRUE(builder.Finish());
EXPECT_TRUE(IsRulesetValid(builder.ruleset_contents(), builder.url_rules()));
}
diff --git a/chromium/components/subresource_filter/core/common/url_pattern.cc b/chromium/components/subresource_filter/core/common/url_pattern.cc
index d601f41e6d5..381def4b45e 100644
--- a/chromium/components/subresource_filter/core/common/url_pattern.cc
+++ b/chromium/components/subresource_filter/core/common/url_pattern.cc
@@ -20,7 +20,7 @@
#include <ostream>
#include "base/logging.h"
-#include "components/subresource_filter/core/common/flat/rules_generated.h"
+#include "components/subresource_filter/core/common/flat/url_pattern_index_generated.h"
#include "components/subresource_filter/core/common/fuzzy_pattern_matching.h"
#include "components/subresource_filter/core/common/string_splitter.h"
#include "url/gurl.h"
diff --git a/chromium/components/subresource_filter/core/common/url_pattern_index.cc b/chromium/components/subresource_filter/core/common/url_pattern_index.cc
new file mode 100644
index 00000000000..574f577a325
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/url_pattern_index.cc
@@ -0,0 +1,567 @@
+// Copyright 2017 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/subresource_filter/core/common/url_pattern_index.h"
+
+#include <algorithm>
+#include <limits>
+#include <string>
+
+#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "components/subresource_filter/core/common/ngram_extractor.h"
+#include "components/subresource_filter/core/common/url_pattern.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace subresource_filter {
+
+namespace {
+
+using FlatStringOffset = flatbuffers::Offset<flatbuffers::String>;
+using FlatDomains = flatbuffers::Vector<FlatStringOffset>;
+using FlatDomainsOffset = flatbuffers::Offset<FlatDomains>;
+
+base::StringPiece ToStringPiece(const flatbuffers::String* string) {
+ DCHECK(string);
+ return base::StringPiece(string->c_str(), string->size());
+}
+
+// Performs three-way comparison between two domains. In the total order defined
+// by this predicate, the lengths of domains will be monotonically decreasing.
+int CompareDomains(base::StringPiece lhs_domain, base::StringPiece rhs_domain) {
+ if (lhs_domain.size() != rhs_domain.size())
+ return lhs_domain.size() > rhs_domain.size() ? -1 : 1;
+ return lhs_domain.compare(rhs_domain);
+}
+
+bool HasNoUpperAscii(base::StringPiece string) {
+ return std::none_of(string.begin(), string.end(),
+ [](char c) { return base::IsAsciiUpper(c); });
+}
+
+// Checks whether a URL |rule| can be converted to its FlatBuffers equivalent,
+// and performs the actual conversion.
+class UrlRuleFlatBufferConverter {
+ public:
+ // Creates the converter, and initializes |is_convertible| bit. If
+ // |is_convertible| == true, then all the fields, needed for serializing the
+ // |rule| to FlatBuffer, are initialized (|options|, |anchor_right|, etc.).
+ explicit UrlRuleFlatBufferConverter(const proto::UrlRule& rule)
+ : rule_(rule) {
+ is_convertible_ = InitializeOptions() && InitializeElementTypes() &&
+ InitializeActivationTypes() && InitializeUrlPattern() &&
+ IsMeaningful();
+ }
+
+ // Returns whether the |rule| can be converted to its FlatBuffers equivalent.
+ // The conversion is not possible if the rule has attributes not supported by
+ // this client version.
+ bool is_convertible() const { return is_convertible_; }
+
+ // Writes the URL |rule| to the FlatBuffer using the |builder|, and returns
+ // the offset to the serialized rule.
+ UrlRuleOffset SerializeConvertedRule(
+ flatbuffers::FlatBufferBuilder* builder) const {
+ DCHECK(is_convertible());
+
+ FlatDomainsOffset domains_included_offset;
+ FlatDomainsOffset domains_excluded_offset;
+ if (rule_.domains_size()) {
+ // TODO(pkalinnikov): Consider sharing the vectors between rules.
+ std::vector<FlatStringOffset> domains_included;
+ std::vector<FlatStringOffset> domains_excluded;
+ // Reserve only for |domains_included| because it is expected to be the
+ // one used more frequently.
+ domains_included.reserve(rule_.domains_size());
+
+ for (const auto& domain_list_item : rule_.domains()) {
+ // Note: The |domain| can have non-ASCII UTF-8 characters, but
+ // ToLowerASCII leaves these intact.
+ // TODO(pkalinnikov): Convert non-ASCII characters to lower case too.
+ // TODO(pkalinnikov): Possibly convert Punycode to IDN here or directly
+ // assume this is done in the proto::UrlRule.
+ const std::string& domain = domain_list_item.domain();
+ auto offset = builder->CreateSharedString(
+ HasNoUpperAscii(domain) ? domain : base::ToLowerASCII(domain));
+
+ if (domain_list_item.exclude())
+ domains_excluded.push_back(offset);
+ else
+ domains_included.push_back(offset);
+ }
+
+ // The comparator ensuring the domains order necessary for fast matching.
+ auto precedes = [&builder](FlatStringOffset lhs, FlatStringOffset rhs) {
+ return CompareDomains(ToStringPiece(flatbuffers::GetTemporaryPointer(
+ *builder, lhs)),
+ ToStringPiece(flatbuffers::GetTemporaryPointer(
+ *builder, rhs))) < 0;
+ };
+
+ // The domains are stored in sorted order to support fast matching.
+ if (!domains_included.empty()) {
+ // TODO(pkalinnikov): Don't sort if it is already sorted offline.
+ std::sort(domains_included.begin(), domains_included.end(), precedes);
+ domains_included_offset = builder->CreateVector(domains_included);
+ }
+ if (!domains_excluded.empty()) {
+ std::sort(domains_excluded.begin(), domains_excluded.end(), precedes);
+ domains_excluded_offset = builder->CreateVector(domains_excluded);
+ }
+ }
+
+ auto url_pattern_offset = builder->CreateString(rule_.url_pattern());
+
+ return flat::CreateUrlRule(
+ *builder, options_, element_types_, activation_types_,
+ url_pattern_type_, anchor_left_, anchor_right_, domains_included_offset,
+ domains_excluded_offset, url_pattern_offset);
+ }
+
+ private:
+ static bool ConvertAnchorType(proto::AnchorType anchor_type,
+ flat::AnchorType* result) {
+ switch (anchor_type) {
+ case proto::ANCHOR_TYPE_NONE:
+ *result = flat::AnchorType_NONE;
+ break;
+ case proto::ANCHOR_TYPE_BOUNDARY:
+ *result = flat::AnchorType_BOUNDARY;
+ break;
+ case proto::ANCHOR_TYPE_SUBDOMAIN:
+ *result = flat::AnchorType_SUBDOMAIN;
+ break;
+ default:
+ return false; // Unsupported anchor type.
+ }
+ return true;
+ }
+
+ bool InitializeOptions() {
+ if (rule_.semantics() == proto::RULE_SEMANTICS_WHITELIST) {
+ options_ |= flat::OptionFlag_IS_WHITELIST;
+ } else if (rule_.semantics() != proto::RULE_SEMANTICS_BLACKLIST) {
+ return false; // Unsupported semantics.
+ }
+
+ switch (rule_.source_type()) {
+ case proto::SOURCE_TYPE_ANY:
+ options_ |= flat::OptionFlag_APPLIES_TO_THIRD_PARTY;
+ // Note: fall through here intentionally.
+ case proto::SOURCE_TYPE_FIRST_PARTY:
+ options_ |= flat::OptionFlag_APPLIES_TO_FIRST_PARTY;
+ break;
+ case proto::SOURCE_TYPE_THIRD_PARTY:
+ options_ |= flat::OptionFlag_APPLIES_TO_THIRD_PARTY;
+ break;
+
+ default:
+ return false; // Unsupported source type.
+ }
+
+ if (rule_.match_case())
+ options_ |= flat::OptionFlag_IS_MATCH_CASE;
+
+ return true;
+ }
+
+ bool InitializeElementTypes() {
+ static_assert(
+ proto::ELEMENT_TYPE_ALL <= std::numeric_limits<uint16_t>::max(),
+ "Element types can not be stored in uint16_t.");
+ element_types_ = static_cast<uint16_t>(rule_.element_types());
+
+ // Note: Normally we can not distinguish between the main plugin resource
+ // and any other loads it makes. We treat them both as OBJECT requests.
+ if (element_types_ & proto::ELEMENT_TYPE_OBJECT_SUBREQUEST)
+ element_types_ |= proto::ELEMENT_TYPE_OBJECT;
+
+ // Ignore unknown element types.
+ element_types_ &= proto::ELEMENT_TYPE_ALL;
+ // Filtering popups is not supported.
+ element_types_ &= ~proto::ELEMENT_TYPE_POPUP;
+
+ return true;
+ }
+
+ bool InitializeActivationTypes() {
+ static_assert(
+ proto::ACTIVATION_TYPE_ALL <= std::numeric_limits<uint8_t>::max(),
+ "Activation types can not be stored in uint8_t.");
+ activation_types_ = static_cast<uint8_t>(rule_.activation_types());
+
+ // Only the following activation types are supported, ignore the others.
+ activation_types_ &=
+ proto::ACTIVATION_TYPE_DOCUMENT | proto::ACTIVATION_TYPE_GENERICBLOCK;
+
+ return true;
+ }
+
+ bool InitializeUrlPattern() {
+ switch (rule_.url_pattern_type()) {
+ case proto::URL_PATTERN_TYPE_SUBSTRING:
+ url_pattern_type_ = flat::UrlPatternType_SUBSTRING;
+ break;
+ case proto::URL_PATTERN_TYPE_WILDCARDED:
+ url_pattern_type_ = flat::UrlPatternType_WILDCARDED;
+ break;
+
+ // TODO(pkalinnikov): Implement REGEXP rules matching.
+ case proto::URL_PATTERN_TYPE_REGEXP:
+ default:
+ return false; // Unsupported URL pattern type.
+ }
+
+ if (!ConvertAnchorType(rule_.anchor_left(), &anchor_left_) ||
+ !ConvertAnchorType(rule_.anchor_right(), &anchor_right_)) {
+ return false;
+ }
+ if (anchor_right_ == flat::AnchorType_SUBDOMAIN)
+ return false; // Unsupported right anchor.
+
+ return true;
+ }
+
+ // Returns whether the rule is not a no-op after all the modifications above.
+ bool IsMeaningful() const { return element_types_ || activation_types_; }
+
+ const proto::UrlRule& rule_;
+
+ uint8_t options_ = 0;
+ uint16_t element_types_ = 0;
+ uint8_t activation_types_ = 0;
+ flat::UrlPatternType url_pattern_type_ = flat::UrlPatternType_WILDCARDED;
+ flat::AnchorType anchor_left_ = flat::AnchorType_NONE;
+ flat::AnchorType anchor_right_ = flat::AnchorType_NONE;
+
+ bool is_convertible_ = true;
+};
+
+} // namespace
+
+// Helpers. --------------------------------------------------------------------
+
+UrlRuleOffset SerializeUrlRule(const proto::UrlRule& rule,
+ flatbuffers::FlatBufferBuilder* builder) {
+ DCHECK(builder);
+ UrlRuleFlatBufferConverter converter(rule);
+ if (!converter.is_convertible())
+ return UrlRuleOffset();
+ DCHECK_NE(rule.url_pattern_type(), proto::URL_PATTERN_TYPE_REGEXP);
+ return converter.SerializeConvertedRule(builder);
+}
+
+// UrlPatternIndexBuilder ------------------------------------------------------
+
+UrlPatternIndexBuilder::UrlPatternIndexBuilder(
+ flatbuffers::FlatBufferBuilder* flat_builder)
+ : flat_builder_(flat_builder) {
+ DCHECK(flat_builder_);
+}
+
+UrlPatternIndexBuilder::~UrlPatternIndexBuilder() = default;
+
+void UrlPatternIndexBuilder::IndexUrlRule(UrlRuleOffset offset) {
+ DCHECK(offset.o);
+
+ const auto* rule = flatbuffers::GetTemporaryPointer(*flat_builder_, offset);
+ DCHECK(rule);
+ NGram ngram = GetMostDistinctiveNGram(ToStringPiece(rule->url_pattern()));
+
+ if (ngram) {
+ ngram_index_[ngram].push_back(offset);
+ } else {
+ // TODO(pkalinnikov): Index fallback rules as well.
+ fallback_rules_.push_back(offset);
+ }
+}
+
+UrlPatternIndexOffset UrlPatternIndexBuilder::Finish() {
+ std::vector<flatbuffers::Offset<flat::NGramToRules>> flat_hash_table(
+ ngram_index_.table_size());
+
+ flatbuffers::Offset<flat::NGramToRules> empty_slot_offset =
+ flat::CreateNGramToRules(*flat_builder_);
+ for (size_t i = 0, size = ngram_index_.table_size(); i != size; ++i) {
+ const uint32_t entry_index = ngram_index_.hash_table()[i];
+ if (entry_index >= ngram_index_.size()) {
+ flat_hash_table[i] = empty_slot_offset;
+ continue;
+ }
+ const MutableNGramIndex::EntryType& entry =
+ ngram_index_.entries()[entry_index];
+ auto rules_offset = flat_builder_->CreateVector(entry.second);
+ flat_hash_table[i] =
+ flat::CreateNGramToRules(*flat_builder_, entry.first, rules_offset);
+ }
+ auto ngram_index_offset = flat_builder_->CreateVector(flat_hash_table);
+
+ auto fallback_rules_offset = flat_builder_->CreateVector(fallback_rules_);
+
+ return flat::CreateUrlPatternIndex(*flat_builder_, kNGramSize,
+ ngram_index_offset, empty_slot_offset,
+ fallback_rules_offset);
+}
+
+NGram UrlPatternIndexBuilder::GetMostDistinctiveNGram(
+ base::StringPiece pattern) {
+ size_t min_list_size = std::numeric_limits<size_t>::max();
+ NGram best_ngram = 0;
+
+ auto ngrams = CreateNGramExtractor<kNGramSize, NGram>(
+ pattern, [](char c) { return c == '*' || c == '^'; });
+
+ for (uint64_t ngram : ngrams) {
+ const MutableUrlRuleList* rules = ngram_index_.Get(ngram);
+ const size_t list_size = rules ? rules->size() : 0;
+ if (list_size < min_list_size) {
+ // TODO(pkalinnikov): Pick random of the same-sized lists.
+ min_list_size = list_size;
+ best_ngram = ngram;
+ if (list_size == 0)
+ break;
+ }
+ }
+
+ return best_ngram;
+}
+
+// UrlPatternIndex -------------------------------------------------------------
+
+namespace {
+
+using FlatUrlRuleList = flatbuffers::Vector<flatbuffers::Offset<flat::UrlRule>>;
+using FlatNGramIndex =
+ flatbuffers::Vector<flatbuffers::Offset<flat::NGramToRules>>;
+
+// Returns the size of the longest (sub-)domain of |origin| matching one of the
+// |domains| in the list.
+//
+// The |domains| should be sorted in descending order of their length, and
+// ascending alphabetical order within the groups of same-length domains.
+size_t GetLongestMatchingSubdomain(const url::Origin& origin,
+ const FlatDomains& domains) {
+ // If the |domains| list is short, then the simple strategy is usually faster.
+ if (domains.size() <= 5) {
+ for (auto* domain : domains) {
+ const base::StringPiece domain_piece = ToStringPiece(domain);
+ if (origin.DomainIs(domain_piece))
+ return domain_piece.size();
+ }
+ return 0;
+ }
+ // Otherwise look for each subdomain of the |origin| using binary search.
+
+ DCHECK(!origin.unique());
+ base::StringPiece canonicalized_host(origin.host());
+ if (canonicalized_host.empty())
+ return 0;
+
+ // If the host name ends with a dot, then ignore it.
+ if (canonicalized_host.back() == '.')
+ canonicalized_host.remove_suffix(1);
+
+ // The |left| bound of the search is shared between iterations, because
+ // subdomains are considered in decreasing order of their lengths, therefore
+ // each consecutive lower_bound will be at least as far as the previous.
+ flatbuffers::uoffset_t left = 0;
+ for (size_t position = 0;; ++position) {
+ const base::StringPiece subdomain = canonicalized_host.substr(position);
+
+ flatbuffers::uoffset_t right = domains.size();
+ while (left + 1 < right) {
+ auto middle = left + (right - left) / 2;
+ DCHECK_LT(middle, domains.size());
+ if (CompareDomains(ToStringPiece(domains[middle]), subdomain) <= 0)
+ left = middle;
+ else
+ right = middle;
+ }
+
+ DCHECK_LT(left, domains.size());
+ if (ToStringPiece(domains[left]) == subdomain)
+ return subdomain.size();
+
+ position = canonicalized_host.find('.', position);
+ if (position == base::StringPiece::npos)
+ break;
+ }
+
+ return 0;
+}
+
+// Returns whether the |origin| matches the domain list of the |rule|. A match
+// means that the longest domain in |domains| that |origin| is a sub-domain of
+// is not an exception OR all the |domains| are exceptions and neither matches
+// the |origin|. Thus, domain filters with more domain components trump filters
+// with fewer domain components, i.e. the more specific a filter is, the higher
+// the priority.
+//
+// A rule whose domain list is empty or contains only negative domains is still
+// considered a "generic" rule. Therefore, if |disable_generic_rules| is set,
+// this function will always return false for such rules.
+bool DoesOriginMatchDomainList(const url::Origin& origin,
+ const flat::UrlRule& rule,
+ bool disable_generic_rules) {
+ const bool is_generic = !rule.domains_included();
+ DCHECK(is_generic || rule.domains_included()->size());
+ if (disable_generic_rules && is_generic)
+ return false;
+
+ // Unique |origin| matches lists of exception domains only.
+ if (origin.unique())
+ return is_generic;
+
+ size_t longest_matching_included_domain_length = 1;
+ if (!is_generic) {
+ longest_matching_included_domain_length =
+ GetLongestMatchingSubdomain(origin, *rule.domains_included());
+ }
+ if (longest_matching_included_domain_length && rule.domains_excluded()) {
+ return GetLongestMatchingSubdomain(origin, *rule.domains_excluded()) <
+ longest_matching_included_domain_length;
+ }
+ return !!longest_matching_included_domain_length;
+}
+
+// Returns whether the request matches flags of the specified URL |rule|. Takes
+// into account:
+// - |element_type| of the requested resource, if not *_UNSPECIFIED.
+// - |activation_type| for a subdocument request, if not *_UNSPECIFIED.
+// - Whether the resource |is_third_party| w.r.t. its embedding document.
+bool DoesRuleFlagsMatch(const flat::UrlRule& rule,
+ proto::ElementType element_type,
+ proto::ActivationType activation_type,
+ bool is_third_party) {
+ DCHECK((element_type == proto::ELEMENT_TYPE_UNSPECIFIED) !=
+ (activation_type == proto::ACTIVATION_TYPE_UNSPECIFIED));
+
+ if (element_type != proto::ELEMENT_TYPE_UNSPECIFIED &&
+ !(rule.element_types() & element_type)) {
+ return false;
+ }
+ if (activation_type != proto::ACTIVATION_TYPE_UNSPECIFIED &&
+ !(rule.activation_types() & activation_type)) {
+ return false;
+ }
+
+ if (is_third_party &&
+ !(rule.options() & flat::OptionFlag_APPLIES_TO_THIRD_PARTY)) {
+ return false;
+ }
+ if (!is_third_party &&
+ !(rule.options() & flat::OptionFlag_APPLIES_TO_FIRST_PARTY)) {
+ return false;
+ }
+
+ return true;
+}
+
+const flat::UrlRule* FindMatchAmongCandidates(
+ const FlatUrlRuleList* candidates,
+ const GURL& url,
+ const url::Origin& document_origin,
+ proto::ElementType element_type,
+ proto::ActivationType activation_type,
+ bool is_third_party,
+ bool disable_generic_rules) {
+ if (!candidates)
+ return nullptr;
+ for (const flat::UrlRule* rule : *candidates) {
+ DCHECK_NE(rule, nullptr);
+ DCHECK_NE(rule->url_pattern_type(), flat::UrlPatternType_REGEXP);
+ if (!DoesRuleFlagsMatch(*rule, element_type, activation_type,
+ is_third_party)) {
+ continue;
+ }
+ if (!UrlPattern(*rule).MatchesUrl(url))
+ continue;
+
+ if (DoesOriginMatchDomainList(document_origin, *rule,
+ disable_generic_rules)) {
+ return rule;
+ }
+ }
+
+ return nullptr;
+}
+
+// Returns whether the network request matches a UrlPattern |index| represented
+// in its FlatBuffers format. |is_third_party| should reflect the relation
+// between |url| and |document_origin|.
+const flat::UrlRule* FindMatchInFlatUrlPatternIndex(
+ const flat::UrlPatternIndex& index,
+ const GURL& url,
+ const url::Origin& document_origin,
+ proto::ElementType element_type,
+ proto::ActivationType activation_type,
+ bool is_third_party,
+ bool disable_generic_rules) {
+ const FlatNGramIndex* hash_table = index.ngram_index();
+ const flat::NGramToRules* empty_slot = index.ngram_index_empty_slot();
+ DCHECK_NE(hash_table, nullptr);
+
+ NGramHashTableProber prober;
+
+ auto ngrams = CreateNGramExtractor<kNGramSize, uint64_t>(
+ url.spec(), [](char) { return false; });
+ for (uint64_t ngram : ngrams) {
+ const size_t slot_index = prober.FindSlot(
+ ngram, base::strict_cast<size_t>(hash_table->size()),
+ [hash_table, empty_slot](NGram ngram, size_t slot_index) {
+ const flat::NGramToRules* entry = hash_table->Get(slot_index);
+ DCHECK_NE(entry, nullptr);
+ return entry == empty_slot || entry->ngram() == ngram;
+ });
+ DCHECK_LT(slot_index, hash_table->size());
+
+ const flat::NGramToRules* entry = hash_table->Get(slot_index);
+ if (entry == empty_slot)
+ continue;
+ const flat::UrlRule* rule = FindMatchAmongCandidates(
+ entry->rule_list(), url, document_origin, element_type, activation_type,
+ is_third_party, disable_generic_rules);
+ if (rule)
+ return rule;
+ }
+
+ const FlatUrlRuleList* rules = index.fallback_rules();
+ return FindMatchAmongCandidates(rules, url, document_origin, element_type,
+ activation_type, is_third_party,
+ disable_generic_rules);
+}
+
+} // namespace
+
+UrlPatternIndexMatcher::UrlPatternIndexMatcher(
+ const flat::UrlPatternIndex* flat_index)
+ : flat_index_(flat_index) {
+ DCHECK(!flat_index || flat_index->n() == kNGramSize);
+}
+
+UrlPatternIndexMatcher::~UrlPatternIndexMatcher() = default;
+
+const flat::UrlRule* UrlPatternIndexMatcher::FindMatch(
+ const GURL& url,
+ const url::Origin& first_party_origin,
+ proto::ElementType element_type,
+ proto::ActivationType activation_type,
+ bool is_third_party,
+ bool disable_generic_rules) const {
+ if (!flat_index_ || !url.is_valid())
+ return nullptr;
+ if ((element_type == proto::ELEMENT_TYPE_UNSPECIFIED) ==
+ (activation_type == proto::ACTIVATION_TYPE_UNSPECIFIED)) {
+ return nullptr;
+ }
+
+ return FindMatchInFlatUrlPatternIndex(*flat_index_, url, first_party_origin,
+ element_type, activation_type,
+ is_third_party, disable_generic_rules);
+}
+
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/url_pattern_index.h b/chromium/components/subresource_filter/core/common/url_pattern_index.h
new file mode 100644
index 00000000000..30224dce768
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/url_pattern_index.h
@@ -0,0 +1,135 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CORE_COMMON_URL_PATTERN_INDEX_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_URL_PATTERN_INDEX_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/strings/string_piece_forward.h"
+#include "components/subresource_filter/core/common/closed_hash_map.h"
+#include "components/subresource_filter/core/common/flat/url_pattern_index_generated.h"
+#include "components/subresource_filter/core/common/proto/rules.pb.h"
+#include "components/subresource_filter/core/common/uint64_hasher.h"
+#include "third_party/flatbuffers/src/include/flatbuffers/flatbuffers.h"
+
+class GURL;
+
+namespace url {
+class Origin;
+}
+
+namespace subresource_filter {
+
+// The integer type used to represent N-grams.
+using NGram = uint64_t;
+// The hasher used for hashing N-grams.
+using NGramHasher = Uint64Hasher;
+// The hash table probe sequence used both by UrlPatternIndex and its builder.
+using NGramHashTableProber = DefaultProber<NGram, NGramHasher>;
+
+// FlatBuffer offset aliases.
+using UrlRuleOffset = flatbuffers::Offset<flat::UrlRule>;
+using UrlPatternIndexOffset = flatbuffers::Offset<flat::UrlPatternIndex>;
+
+constexpr size_t kNGramSize = 5;
+static_assert(kNGramSize <= sizeof(NGram), "NGram type is too narrow.");
+
+// Serializes the |rule| to the FlatBuffer |builder|, and returns an offset to
+// it in the resulting buffer. Returns null offset iff the |rule| could not be
+// serialized because of unsupported options or it is otherwise invalid.
+UrlRuleOffset SerializeUrlRule(const proto::UrlRule& rule,
+ flatbuffers::FlatBufferBuilder* builder);
+
+// The class used to construct an index over the URL patterns of a set of URL
+// rules. The rules themselves need to be converted to FlatBuffers format by the
+// client of this class, as well as persisted into the |flat_builder| that is
+// supplied in the constructor.
+class UrlPatternIndexBuilder {
+ public:
+ explicit UrlPatternIndexBuilder(flatbuffers::FlatBufferBuilder* flat_builder);
+ ~UrlPatternIndexBuilder();
+
+ // Adds a UrlRule to the index. The caller should have already persisted the
+ // rule into the same |flat_builder| by a call to SerializeUrlRule returning a
+ // non-null |offset|, and should pass in the resulting |offset| here.
+ void IndexUrlRule(UrlRuleOffset offset);
+
+ // Finalizes construction of the index, serializes it using |flat_builder|,
+ // and returns an offset to it in the resulting FlatBuffer.
+ UrlPatternIndexOffset Finish();
+
+ private:
+ using MutableUrlRuleList = std::vector<UrlRuleOffset>;
+ using MutableNGramIndex =
+ ClosedHashMap<NGram, MutableUrlRuleList, NGramHashTableProber>;
+
+ // Returns an N-gram of the |pattern| encoded into the NGram integer type. The
+ // N-gram is picked using a greedy heuristic, i.e. the one is chosen which
+ // corresponds to the shortest list of rules within the index. If there are no
+ // valid N-grams in the |pattern|, the return value is 0.
+ NGram GetMostDistinctiveNGram(base::StringPiece pattern);
+
+ // This index contains all non-REGEXP rules that have at least one acceptable
+ // N-gram. For each given rule, the N-gram used as an index key is picked
+ // greedily (see GetMostDistinctiveNGram).
+ MutableNGramIndex ngram_index_;
+
+ // A fallback list that contains all the rules with no acceptable N-gram.
+ MutableUrlRuleList fallback_rules_;
+
+ // Must outlive this instance.
+ flatbuffers::FlatBufferBuilder* flat_builder_;
+
+ DISALLOW_COPY_AND_ASSIGN(UrlPatternIndexBuilder);
+};
+
+// Encapsulates a read-only index built over the URL patterns of a set of URL
+// rules, and provides fast matching of network requests against these rules.
+class UrlPatternIndexMatcher {
+ public:
+ // Creates an instance to access the given |flat_index|. If |flat_index| is
+ // nullptr, then all requests return no match.
+ explicit UrlPatternIndexMatcher(const flat::UrlPatternIndex* flat_index);
+ ~UrlPatternIndexMatcher();
+
+ // If the index contains one or more UrlRules that match the request, returns
+ // one of them (it is undefined which one). Otherwise, returns nullptr.
+ //
+ // Notes on parameters:
+ // - |url| should be valid, otherwise the return value is nullptr.
+ // - Exactly one of |element_type| and |activation_type| should be specified,
+ // i.e., not equal to *_UNSPECIFIED, otherwise the return value is nullptr.
+ // - |is_third_party| should be pre-computed by the caller, e.g. using the
+ // registry_controlled_domains library, to reflect the relation between
+ // |url| and |first_party_origin|.
+ //
+ // A rule is deemed to match the request iff all of the following applies:
+ // - The |url| matches the rule's UrlPattern (see url_pattern.h).
+ // - The |first_party_origin| matches the rule's targeted domains list.
+ // - |element_type| or |activation_type| is among the rule's targeted types.
+ // - The |is_third_party| bit matches the rule's requirement on the requested
+ // |url| being first-/third-party w.r.t. its |first_party_origin|.
+ // - The rule is not generic if |disable_generic_rules| is true.
+ const flat::UrlRule* FindMatch(const GURL& url,
+ const url::Origin& first_party_origin,
+ proto::ElementType element_type,
+ proto::ActivationType activation_type,
+ bool is_third_party,
+ bool disable_generic_rules) const;
+
+ private:
+ // Must outlive this instance.
+ const flat::UrlPatternIndex* flat_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(UrlPatternIndexMatcher);
+};
+
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_URL_PATTERN_INDEX_H_
diff --git a/chromium/components/subresource_filter/core/common/url_pattern_index_unittest.cc b/chromium/components/subresource_filter/core/common/url_pattern_index_unittest.cc
new file mode 100644
index 00000000000..fcdb9da54c4
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/url_pattern_index_unittest.cc
@@ -0,0 +1,707 @@
+// Copyright 2017 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/subresource_filter/core/common/url_pattern_index.h"
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/strings/string_piece.h"
+#include "components/subresource_filter/core/common/url_pattern.h"
+#include "components/subresource_filter/core/common/url_rule_test_support.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace subresource_filter {
+
+using namespace testing;
+
+class UrlPatternIndexTest : public ::testing::Test {
+ public:
+ UrlPatternIndexTest() { Reset(); }
+
+ protected:
+ bool AddUrlRule(const proto::UrlRule& rule) {
+ auto offset = SerializeUrlRule(rule, flat_builder_.get());
+ if (offset.o)
+ index_builder_->IndexUrlRule(offset);
+ return !!offset.o;
+ }
+
+ void Finish() {
+ const auto index_offset = index_builder_->Finish();
+ flat_builder_->Finish(index_offset);
+
+ const flat::UrlPatternIndex* flat_index =
+ flat::GetUrlPatternIndex(flat_builder_->GetBufferPointer());
+ index_matcher_.reset(new UrlPatternIndexMatcher(flat_index));
+ }
+
+ const flat::UrlRule* FindMatch(
+ base::StringPiece url_string,
+ base::StringPiece document_origin_string = base::StringPiece(),
+ proto::ElementType element_type = kOther,
+ proto::ActivationType activation_type = kNoActivation,
+ bool disable_generic_rules = false) {
+ const GURL url(url_string);
+ const url::Origin document_origin = GetOrigin(document_origin_string);
+ return index_matcher_->FindMatch(
+ url, document_origin, element_type, activation_type,
+ IsThirdParty(url, document_origin), disable_generic_rules);
+ }
+
+ bool IsOutOfRange(const flat::UrlRule* rule) const {
+ if (!rule)
+ return false;
+ const auto* data = reinterpret_cast<const uint8_t*>(rule);
+ return data < flat_builder_->GetBufferPointer() ||
+ data >= flat_builder_->GetBufferPointer() + flat_builder_->GetSize();
+ }
+
+ void Reset() {
+ index_matcher_.reset();
+ index_builder_.reset();
+ flat_builder_.reset(new flatbuffers::FlatBufferBuilder());
+ index_builder_.reset(new UrlPatternIndexBuilder(flat_builder_.get()));
+ }
+
+ private:
+ std::unique_ptr<flatbuffers::FlatBufferBuilder> flat_builder_;
+ std::unique_ptr<UrlPatternIndexBuilder> index_builder_;
+ std::unique_ptr<UrlPatternIndexMatcher> index_matcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(UrlPatternIndexTest);
+};
+
+TEST_F(UrlPatternIndexTest, EmptyIndex) {
+ Finish();
+ EXPECT_FALSE(FindMatch(base::StringPiece() /* url */));
+ EXPECT_FALSE(FindMatch("http://example.com"));
+ EXPECT_FALSE(FindMatch("http://another.example.com?param=val"));
+}
+
+TEST_F(UrlPatternIndexTest, OneSimpleRule) {
+ ASSERT_TRUE(AddUrlRule(MakeUrlRule(UrlPattern("?param=", kSubstring))));
+ Finish();
+
+ EXPECT_FALSE(FindMatch("https://example.com"));
+ EXPECT_TRUE(FindMatch("http://example.org?param=image1"));
+}
+
+TEST_F(UrlPatternIndexTest, NoRuleApplies) {
+ ASSERT_TRUE(AddUrlRule(MakeUrlRule(UrlPattern("?filter_out=", kSubstring))));
+ ASSERT_TRUE(AddUrlRule(MakeUrlRule(UrlPattern("&filter_out=", kSubstring))));
+ Finish();
+
+ EXPECT_FALSE(FindMatch("http://example.com"));
+ EXPECT_FALSE(FindMatch("http://example.com?filter_not"));
+ EXPECT_FALSE(FindMatch("http://example.com?k=v&filter_not"));
+}
+
+TEST_F(UrlPatternIndexTest, OneRuleWithoutMetaInfo) {
+ const struct {
+ UrlPattern url_pattern;
+ const char* url;
+ bool expect_match;
+ } kTestCases[] = {
+ // SUBSTRING
+ {{"abcd", kSubstring}, "http://ex.com/abcd", true},
+ {{"abcd", kSubstring}, "http://ex.com/dcab", false},
+ {{"42", kSubstring}, "http://ex.com/adcd/picture42.png", true},
+ {{"&test", kSubstring},
+ "http://ex.com/params?param1=false&test=true",
+ true},
+ {{"-test-42.", kSubstring}, "http://ex.com/unit-test-42.1", true},
+ {{"/abcdtest160x600.", kSubstring},
+ "http://ex.com/abcdtest160x600.png",
+ true},
+
+ // WILDCARDED
+ {{"http://ex.com/abcd/picture*.png"},
+ "http://ex.com/abcd/picture42.png",
+ true},
+ {{"ex.com", kSubdomain, kAnchorNone}, "http://ex.com", true},
+ {{"ex.com", kSubdomain, kAnchorNone}, "http://test.ex.com", true},
+ {{"ex.com", kSubdomain, kAnchorNone}, "https://test.ex.com.com", true},
+ {{"ex.com", kSubdomain, kAnchorNone}, "https://test.rest.ex.com", true},
+ {{"ex.com", kSubdomain, kAnchorNone}, "https://test_ex.com", false},
+
+ {{"http://ex.com", kBoundary, kAnchorNone}, "http://ex.com/", true},
+ {{"http://ex.com", kBoundary, kAnchorNone}, "http://ex.com/42", true},
+ {{"http://ex.com", kBoundary, kAnchorNone},
+ "http://ex.com/42/http://ex.com/",
+ true},
+ {{"http://ex.com", kBoundary, kAnchorNone},
+ "http://ex.com/42/http://ex.info/",
+ true},
+ {{"http://ex.com/", kBoundary, kBoundary}, "http://ex.com", true},
+ {{"http://ex.com/", kBoundary, kBoundary}, "http://ex.com/42", false},
+ {{"http://ex.com/", kBoundary, kBoundary},
+ "http://ex.info/42/http://ex.com/",
+ false},
+ {{"http://ex.com/", kBoundary, kBoundary},
+ "http://ex.info/42/http://ex.com/",
+ false},
+ {{"http://ex.com/", kBoundary, kBoundary}, "http://ex.com/", true},
+ {{"http://ex.com/", kBoundary, kBoundary}, "http://ex.com/42.swf", false},
+ {{"http://ex.com/", kBoundary, kBoundary},
+ "http://ex.info/redirect/http://ex.com/",
+ false},
+ {{"pdf", kAnchorNone, kBoundary}, "http://ex.com/abcd.pdf", true},
+ {{"pdf", kAnchorNone, kBoundary}, "http://ex.com/pdfium", false},
+ {{"http://ex.com^"}, "http://ex.com/", true},
+ {{"http://ex.com^"}, "http://ex.com:8000/", true},
+ {{"http://ex.com^"}, "http://ex.com.ru", false},
+ {{"^ex.com^"},
+ "http://ex.com:8000/42.loss?a=12&b=%D1%82%D0%B5%D1%81%D1%82",
+ true},
+ {{"^42.loss^"},
+ "http://ex.com:8000/42.loss?a=12&b=%D1%82%D0%B5%D1%81%D1%82",
+ true},
+
+ // TODO(pkalinnikov): The '^' at the end should match end-of-string.
+ //
+ // {"^%D1%82%D0%B5%D1%81%D1%82^",
+ // "http://ex.com:8000/42.loss?a=12&b=%D1%82%D0%B5%D1%81%D1%82",
+ // true},
+ // {"/abcd/*/picture^", "http://ex.com/abcd/42/picture", true},
+
+ {{"/abcd/*/picture^"}, "http://ex.com/abcd/42/loss/picture?param", true},
+ {{"/abcd/*/picture^"}, "http://ex.com/abcd//picture/42", true},
+ {{"/abcd/*/picture^"}, "http://ex.com/abcd/picture", false},
+ {{"/abcd/*/picture^"}, "http://ex.com/abcd/42/pictureraph", false},
+ {{"/abcd/*/picture^"}, "http://ex.com/abcd/42/picture.swf", false},
+ {{"test.ex.com^", kSubdomain, kAnchorNone},
+ "http://test.ex.com/42.swf",
+ true},
+ {{"test.ex.com^", kSubdomain, kAnchorNone},
+ "http://server1.test.ex.com/42.swf",
+ true},
+ {{"test.ex.com^", kSubdomain, kAnchorNone},
+ "https://test.ex.com:8000/",
+ true},
+ {{"test.ex.com^", kSubdomain, kAnchorNone},
+ "http://test.ex.com.ua/42.swf",
+ false},
+ {{"test.ex.com^", kSubdomain, kAnchorNone},
+ "http://ex.com/redirect/http://test.ex.com/",
+ false},
+
+ {{"/abcd/*"}, "https://ex.com/abcd/", true},
+ {{"/abcd/*"}, "http://ex.com/abcd/picture.jpeg", true},
+ {{"/abcd/*"}, "https://ex.com/abcd", false},
+ {{"/abcd/*"}, "http://abcd.ex.com", false},
+ {{"*/abcd/"}, "https://ex.com/abcd/", true},
+ {{"*/abcd/"}, "http://ex.com/abcd/picture.jpeg", true},
+ {{"*/abcd/"}, "https://ex.com/test-abcd/", false},
+ {{"*/abcd/"}, "http://abcd.ex.com", false},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message() << "UrlPattern: " << test_case.url_pattern
+ << "; URL: " << test_case.url);
+
+ ASSERT_TRUE(AddUrlRule(MakeUrlRule(test_case.url_pattern)));
+ Finish();
+
+ EXPECT_EQ(test_case.expect_match, !!FindMatch(test_case.url));
+ Reset();
+ }
+}
+
+TEST_F(UrlPatternIndexTest, OneRuleWithThirdParty) {
+ const struct {
+ const char* url_pattern;
+ proto::SourceType source_type;
+
+ const char* url;
+ const char* document_origin;
+ bool expect_match;
+ } kTestCases[] = {
+ {"ex.com", kThirdParty, "http://ex.com", "http://exmpl.org", true},
+ {"ex.com", kThirdParty, "http://ex.com", "http://ex.com", false},
+ {"ex.com", kThirdParty, "http://ex.com/path?k=v", "http://exmpl.org",
+ true},
+ {"ex.com", kThirdParty, "http://ex.com/path?k=v", "http://ex.com", false},
+ {"ex.com", kFirstParty, "http://ex.com/path?k=v", "http://ex.com", true},
+ {"ex.com", kFirstParty, "http://ex.com/path?k=v", "http://exmpl.com",
+ false},
+ {"ex.com", kAnyParty, "http://ex.com/path?k=v", "http://ex.com", true},
+ {"ex.com", kAnyParty, "http://ex.com/path?k=v", "http://exmpl.com", true},
+ {"ex.com", kThirdParty, "http://subdomain.ex.com", "http://ex.com",
+ false},
+ {"ex.com", kThirdParty, "http://ex.com", nullptr, true},
+
+ // Public Suffix List tests.
+ {"ex.com", kThirdParty, "http://two.ex.com", "http://one.ex.com", false},
+ {"ex.com", kThirdParty, "http://ex.com", "http://one.ex.com", false},
+ {"ex.com", kThirdParty, "http://two.ex.com", "http://ex.com", false},
+ {"ex.com", kThirdParty, "http://ex.com", "http://example.org", true},
+ {"appspot.com", kThirdParty, "http://two.appspot.org",
+ "http://one.appspot.com", false},
+ };
+
+ for (auto test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message()
+ << "UrlPattern: " << test_case.url_pattern
+ << "; SourceType: " << static_cast<int>(test_case.source_type)
+ << "; URL: " << test_case.url
+ << "; DocumentOrigin: " << test_case.document_origin);
+
+ auto rule = MakeUrlRule(UrlPattern(test_case.url_pattern, kSubstring));
+ rule.set_source_type(test_case.source_type);
+ ASSERT_TRUE(AddUrlRule(rule));
+ Finish();
+
+ EXPECT_EQ(test_case.expect_match,
+ !!FindMatch(test_case.url, test_case.document_origin));
+ Reset();
+ }
+}
+
+TEST_F(UrlPatternIndexTest, OneRuleWithDomainList) {
+ constexpr const char* kUrl = "http://example.com";
+
+ const struct {
+ std::vector<std::string> domains;
+ const char* document_origin;
+ bool expect_match;
+ } kTestCases[] = {
+ {std::vector<std::string>(), nullptr, true},
+ {std::vector<std::string>(), "http://domain.com", true},
+
+ {{"domain.com"}, nullptr, false},
+ {{"domain.com"}, "http://domain.com", true},
+ {{"ddomain.com"}, "http://domain.com", false},
+ {{"domain.com"}, "http://ddomain.com", false},
+ {{"domain.com"}, "http://sub.domain.com", true},
+ {{"sub.domain.com"}, "http://domain.com", false},
+ {{"sub.domain.com"}, "http://sub.domain.com", true},
+ {{"sub.domain.com"}, "http://a.b.c.sub.domain.com", true},
+ {{"sub.domain.com"}, "http://sub.domain.com.com", false},
+
+ // TODO(pkalinnikov): Probably need to canonicalize domain patterns to
+ // avoid subtleties like below.
+ {{"domain.com"}, "http://domain.com.", true},
+ {{"domain.com"}, "http://.domain.com", true},
+ {{"domain.com"}, "http://.domain.com.", true},
+ {{".domain.com"}, "http://.domain.com", true},
+ {{"domain.com."}, "http://domain.com", false},
+ {{"domain.com."}, "http://domain.com.", true},
+
+ {{"domain..com"}, "http://domain.com", false},
+ {{"domain.com"}, "http://domain..com", false},
+ {{"domain..com"}, "http://domain..com", true},
+
+ {{"~domain.com"}, nullptr, true},
+ {{"~domain.com"}, "http://domain.com", false},
+ {{"~ddomain.com"}, "http://domain.com", true},
+ {{"~domain.com"}, "http://ddomain.com", true},
+ {{"~domain.com"}, "http://sub.domain.com", false},
+ {{"~sub.domain.com"}, "http://domain.com", true},
+ {{"~sub.domain.com"}, "http://sub.domain.com", false},
+ {{"~sub.domain.com"}, "http://a.b.c.sub.domain.com", false},
+ {{"~sub.domain.com"}, "http://sub.domain.com.com", true},
+
+ {{"domain1.com", "domain2.com"}, nullptr, false},
+ {{"domain1.com", "domain2.com"}, "http://domain1.com", true},
+ {{"domain1.com", "domain2.com"}, "http://domain2.com", true},
+ {{"domain1.com", "domain2.com"}, "http://domain3.com", false},
+ {{"domain1.com", "domain2.com"}, "http://not_domain1.com", false},
+ {{"domain1.com", "domain2.com"}, "http://sub.domain1.com", true},
+ {{"domain1.com", "domain2.com"}, "http://a.b.c.sub.domain2.com", true},
+
+ {{"~domain1.com", "~domain2.com"}, "http://domain1.com", false},
+ {{"~domain1.com", "~domain2.com"}, "http://domain2.com", false},
+ {{"~domain1.com", "~domain2.com"}, "http://domain3.com", true},
+
+ {{"domain.com", "~sub.domain.com"}, "http://domain.com", true},
+ {{"domain.com", "~sub.domain.com"}, "http://sub.domain.com", false},
+ {{"domain.com", "~sub.domain.com"}, "http://a.b.sub.domain.com", false},
+ {{"domain.com", "~sub.domain.com"}, "http://ssub.domain.com", true},
+
+ {{"domain.com", "~a.domain.com", "~b.domain.com"},
+ "http://domain.com",
+ true},
+ {{"domain.com", "~a.domain.com", "~b.domain.com"},
+ "http://a.domain.com",
+ false},
+ {{"domain.com", "~a.domain.com", "~b.domain.com"},
+ "http://b.domain.com",
+ false},
+
+ {{"domain.com", "~a.domain.com", "b.a.domain.com"},
+ "http://domain.com",
+ true},
+ {{"domain.com", "~a.domain.com", "b.a.domain.com"},
+ "http://a.domain.com",
+ false},
+ {{"domain.com", "~a.domain.com", "b.a.domain.com"},
+ "http://b.a.domain.com",
+ true},
+ {{"domain.com", "~a.domain.com", "b.a.domain.com"},
+ "http://c.b.a.domain.com",
+ true},
+
+ // The following test addresses a former bug in domain list matcher. When
+ // "domain.com" was matched, the positive filters lookup stopped, and the
+ // next domain was considered as a negative. The initial character was
+ // skipped (supposing it's a '~') and the remainder was considered a
+ // domain. So "ddomain.com" would be matched and thus the whole rule would
+ // be classified as non-matching, which is not correct.
+ {{"domain.com", "ddomain.com", "~sub.domain.com"},
+ "http://domain.com",
+ true},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message()
+ << "Domains: " << ::testing::PrintToString(test_case.domains)
+ << "; DocumentOrigin: " << test_case.document_origin);
+
+ auto rule = MakeUrlRule(UrlPattern(kUrl, kSubstring));
+ AddDomains(test_case.domains, &rule);
+ ASSERT_TRUE(AddUrlRule(rule));
+ Finish();
+
+ EXPECT_EQ(test_case.expect_match,
+ !!FindMatch(kUrl, test_case.document_origin));
+ Reset();
+ }
+}
+
+TEST_F(UrlPatternIndexTest, OneRuleWithLongDomainList) {
+ constexpr const char* kUrl = "http://example.com";
+ constexpr size_t kDomains = 200;
+
+ std::vector<std::string> domains;
+ for (size_t i = 0; i < kDomains; ++i) {
+ const std::string domain = "domain" + std::to_string(i) + ".com";
+ domains.push_back(domain);
+ domains.push_back("~sub." + domain);
+ domains.push_back("a.sub." + domain);
+ domains.push_back("b.sub." + domain);
+ domains.push_back("c.sub." + domain);
+ domains.push_back("~aa.sub." + domain);
+ domains.push_back("~ab.sub." + domain);
+ domains.push_back("~ba.sub." + domain);
+ domains.push_back("~bb.sub." + domain);
+ domains.push_back("~sub.sub.c.sub." + domain);
+ }
+
+ auto rule = MakeUrlRule(UrlPattern(kUrl, kSubstring));
+ AddDomains(domains, &rule);
+ ASSERT_TRUE(AddUrlRule(rule));
+ Finish();
+
+ for (size_t i = 0; i < kDomains; ++i) {
+ SCOPED_TRACE(::testing::Message() << "Iteration: " << i);
+ const std::string domain = "domain" + std::to_string(i) + ".com";
+
+ EXPECT_TRUE(FindMatch(kUrl, "http://" + domain));
+ EXPECT_FALSE(FindMatch(kUrl, "http://sub." + domain));
+ EXPECT_TRUE(FindMatch(kUrl, "http://a.sub." + domain));
+ EXPECT_TRUE(FindMatch(kUrl, "http://b.sub." + domain));
+ EXPECT_TRUE(FindMatch(kUrl, "http://c.sub." + domain));
+ EXPECT_FALSE(FindMatch(kUrl, "http://aa.sub." + domain));
+ EXPECT_FALSE(FindMatch(kUrl, "http://ab.sub." + domain));
+ EXPECT_FALSE(FindMatch(kUrl, "http://ba.sub." + domain));
+ EXPECT_FALSE(FindMatch(kUrl, "http://bb.sub." + domain));
+ EXPECT_TRUE(FindMatch(kUrl, "http://sub.c.sub." + domain));
+ EXPECT_FALSE(FindMatch(kUrl, "http://sub.sub.c.sub." + domain));
+ }
+}
+
+TEST_F(UrlPatternIndexTest, OneRuleWithElementTypes) {
+ constexpr auto kAll = kAllElementTypes;
+ const struct {
+ const char* url_pattern;
+ int32_t element_types;
+
+ const char* url;
+ proto::ElementType element_type;
+ bool expect_match;
+ } kTestCases[] = {
+ {"ex.com", kAll, "http://ex.com/img.jpg", kImage, true},
+ {"ex.com", kAll & ~kPopup, "http://ex.com/img", kPopup, false},
+
+ {"ex.com", kImage, "http://ex.com/img.jpg", kImage, true},
+ {"ex.com", kAll & ~kImage, "http://ex.com/img.jpg", kImage, false},
+ {"ex.com", kScript, "http://ex.com/img.jpg", kImage, false},
+ {"ex.com", kAll & ~kScript, "http://ex.com/img.jpg", kImage, true},
+
+ {"ex.com", kImage | kFont, "http://ex.com/font", kFont, true},
+ {"ex.com", kImage | kFont, "http://ex.com/image", kImage, true},
+ {"ex.com", kImage | kFont, "http://ex.com/video",
+ proto::ELEMENT_TYPE_MEDIA, false},
+ {"ex.com", kAll & ~kFont & ~kScript, "http://ex.com/font", kFont, false},
+ {"ex.com", kAll & ~kFont & ~kScript, "http://ex.com/scr", kScript, false},
+ {"ex.com", kAll & ~kFont & ~kScript, "http://ex.com/img", kImage, true},
+
+ {"ex.com", kAll, "http://ex.com", proto::ELEMENT_TYPE_OTHER, true},
+ {"ex.com", kAll, "http://ex.com", proto::ELEMENT_TYPE_UNSPECIFIED, false},
+ {"ex.com", kWebSocket, "ws://ex.com", proto::ELEMENT_TYPE_WEBSOCKET,
+ true},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(
+ ::testing::Message()
+ << "UrlPattern: " << test_case.url_pattern
+ << "; ElementTypes: " << static_cast<int>(test_case.element_types)
+ << "; URL: " << test_case.url
+ << "; ElementType: " << static_cast<int>(test_case.element_type));
+
+ auto rule = MakeUrlRule(UrlPattern(test_case.url_pattern, kSubstring));
+ rule.set_element_types(test_case.element_types);
+ ASSERT_TRUE(AddUrlRule(rule));
+ Finish();
+
+ EXPECT_EQ(test_case.expect_match,
+ !!FindMatch(test_case.url, nullptr /* document_origin_string */,
+ test_case.element_type));
+ Reset();
+ }
+}
+
+TEST_F(UrlPatternIndexTest, OneRuleWithActivationTypes) {
+ const struct {
+ const char* url_pattern;
+ int32_t activation_types;
+
+ const char* document_url;
+ proto::ActivationType activation_type;
+ bool expect_match;
+ } kTestCases[] = {
+ {"example.com", kDocument, "http://example.com", kDocument, true},
+ {"xample.com", kDocument, "http://example.com", kDocument, true},
+ {"exampl.com", kDocument, "http://example.com", kDocument, false},
+
+ {"example.com", kGenericBlock, "http://example.com", kDocument, false},
+ {"example.com", kDocument, "http://example.com", kNoActivation, false},
+ {"example.com", kGenericBlock, "http://example.com", kNoActivation,
+ false},
+
+ // Invalid GURL.
+ {"example.com", kDocument, "http;//example.com", kDocument, false},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(
+ ::testing::Message()
+ << "UrlPattern: " << test_case.url_pattern
+ << "; ActivationTypes: " << static_cast<int>(test_case.activation_types)
+ << "; DocumentURL: " << test_case.document_url
+ << "; ActivationType: " << static_cast<int>(test_case.activation_type));
+
+ auto rule = MakeUrlRule(UrlPattern(test_case.url_pattern, kSubstring));
+ rule.set_semantics(proto::RULE_SEMANTICS_WHITELIST);
+ rule.clear_element_types();
+ rule.set_activation_types(test_case.activation_types);
+ ASSERT_TRUE(AddUrlRule(rule));
+ Finish();
+
+ EXPECT_EQ(test_case.expect_match,
+ !!FindMatch(test_case.document_url,
+ nullptr /* parent_document_origin */, kNoElement,
+ test_case.activation_type));
+ EXPECT_EQ(test_case.expect_match,
+ !!FindMatch(test_case.document_url, "http://example.com/",
+ kNoElement, test_case.activation_type));
+ EXPECT_EQ(test_case.expect_match,
+ !!FindMatch(test_case.document_url, "http://xmpl.com/",
+ kNoElement, test_case.activation_type));
+ Reset();
+ }
+}
+
+TEST_F(UrlPatternIndexTest, OneRuleWithElementAndActivationTypes) {
+ auto rule = MakeUrlRule(UrlPattern("allow.ex.com", kSubstring));
+ rule.set_semantics(proto::RULE_SEMANTICS_WHITELIST);
+ rule.set_element_types(kSubdocument);
+ rule.set_activation_types(kDocument);
+ ASSERT_TRUE(AddUrlRule(rule));
+ Finish();
+
+ EXPECT_FALSE(FindMatch("http://allow.ex.com"));
+ EXPECT_TRUE(FindMatch("http://allow.ex.com",
+ nullptr /*document_origin_string */, kSubdocument));
+
+ EXPECT_FALSE(FindMatch("http://allow.ex.com",
+ nullptr /* document_origin_string */, kNoElement,
+ kGenericBlock));
+ EXPECT_TRUE(FindMatch("http://allow.ex.com",
+ nullptr /* document_origin_string */, kNoElement,
+ kDocument));
+}
+
+TEST_F(UrlPatternIndexTest, MatchWithDisableGenericRules) {
+ const struct {
+ const char* url_pattern;
+ std::vector<std::string> domains;
+ } kRules[] = {
+ // Generic rules.
+ {"some_text", std::vector<std::string>()},
+ {"another_text", {"~example.com"}},
+ {"final_text", {"~example1.com", "~example2.com"}},
+ // Domain specific rules.
+ {"some_text", {"example1.com"}},
+ {"more_text", {"example.com", "~exclude.example.com"}},
+ {"last_text", {"example1.com", "sub.example2.com"}},
+ };
+
+ for (const auto& rule_data : kRules) {
+ auto rule = MakeUrlRule(UrlPattern(rule_data.url_pattern, kSubstring));
+ AddDomains(rule_data.domains, &rule);
+ ASSERT_TRUE(AddUrlRule(rule))
+ << "UrlPattern: " << rule_data.url_pattern
+ << "; Domains: " << ::testing::PrintToString(rule_data.domains);
+ }
+
+ // Note: Some of the rules have common domains (e.g., example1.com), which are
+ // ultimately shared by FlatBuffers' CreateSharedString. The test also makes
+ // sure that the data structure works properly with such optimization.
+ Finish();
+
+ const struct {
+ const char* url;
+ const char* document_origin;
+ bool expect_match_with_enable_all_rules;
+ bool expect_match_with_disable_generic_rules;
+ } kTestCases[] = {
+ {"http://ex.com/some_text", "http://example.com", true, false},
+ {"http://ex.com/some_text", "http://example1.com", true, true},
+
+ {"http://ex.com/another_text", "http://example.com", false, false},
+ {"http://ex.com/another_text", "http://example1.com", true, false},
+
+ {"http://ex.com/final_text", "http://example.com", true, false},
+ {"http://ex.com/final_text", "http://example1.com", false, false},
+ {"http://ex.com/final_text", "http://example2.com", false, false},
+
+ {"http://ex.com/more_text", "http://example.com", true, true},
+ {"http://ex.com/more_text", "http://exclude.example.com", false, false},
+ {"http://ex.com/more_text", "http://example1.com", false, false},
+
+ {"http://ex.com/last_text", "http://example.com", false, false},
+ {"http://ex.com/last_text", "http://example1.com", true, true},
+ {"http://ex.com/last_text", "http://example2.com", false, false},
+ {"http://ex.com/last_text", "http://sub.example2.com", true, true},
+ };
+
+ constexpr bool kDisableGenericRules = true;
+ constexpr bool kEnableAllRules = false;
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(::testing::Message()
+ << "UrlPattern: " << test_case.url
+ << "; DocumentOrigin: " << test_case.document_origin);
+
+ EXPECT_EQ(test_case.expect_match_with_disable_generic_rules,
+ !!FindMatch(test_case.url, test_case.document_origin, kOther,
+ kNoActivation, kDisableGenericRules));
+ EXPECT_EQ(test_case.expect_match_with_enable_all_rules,
+ !!FindMatch(test_case.url, test_case.document_origin, kOther,
+ kNoActivation, kEnableAllRules));
+ }
+}
+
+TEST_F(UrlPatternIndexTest, RulesWithUnsupportedTypes) {
+ const struct {
+ int element_types;
+ int activation_types;
+ } kRules[] = {
+ {proto::ELEMENT_TYPE_MAX << 1, 0},
+ {0, proto::ACTIVATION_TYPE_MAX << 1},
+ {proto::ELEMENT_TYPE_MAX << 1, proto::ACTIVATION_TYPE_MAX << 1},
+
+ {kPopup, 0},
+ {0, proto::ACTIVATION_TYPE_ELEMHIDE},
+ {0, proto::ACTIVATION_TYPE_GENERICHIDE},
+ {0, proto::ACTIVATION_TYPE_ELEMHIDE | proto::ACTIVATION_TYPE_GENERICHIDE},
+ {proto::ELEMENT_TYPE_POPUP, proto::ACTIVATION_TYPE_ELEMHIDE},
+ };
+
+ for (const auto& rule_data : kRules) {
+ auto rule = MakeUrlRule(UrlPattern("example.com", kSubstring));
+ rule.set_element_types(rule_data.element_types);
+ rule.set_activation_types(rule_data.activation_types);
+ EXPECT_FALSE(AddUrlRule(rule))
+ << "ElementTypes: " << static_cast<int>(rule_data.element_types)
+ << "; ActivationTypes: "
+ << static_cast<int>(rule_data.activation_types);
+ }
+ ASSERT_TRUE(AddUrlRule(MakeUrlRule(UrlPattern("exmpl.com", kSubstring))));
+ Finish();
+
+ EXPECT_FALSE(FindMatch("http://example.com/"));
+ EXPECT_TRUE(FindMatch("https://exmpl.com/"));
+}
+
+TEST_F(UrlPatternIndexTest, RulesWithSupportedAndUnsupportedTypes) {
+ const struct {
+ int element_types;
+ int activation_types;
+ } kRules[] = {
+ {kImage | (proto::ELEMENT_TYPE_MAX << 1), 0},
+ {kScript | kPopup, 0},
+ {0, kDocument | (proto::ACTIVATION_TYPE_MAX << 1)},
+ };
+
+ for (const auto& rule_data : kRules) {
+ auto rule = MakeUrlRule(UrlPattern("example.com", kSubstring));
+ rule.set_semantics(proto::RULE_SEMANTICS_WHITELIST);
+ rule.set_element_types(rule_data.element_types);
+ rule.set_activation_types(rule_data.activation_types);
+ EXPECT_TRUE(AddUrlRule(rule))
+ << "ElementTypes: " << static_cast<int>(rule_data.element_types)
+ << "; ActivationTypes: "
+ << static_cast<int>(rule_data.activation_types);
+ }
+ Finish();
+
+ EXPECT_TRUE(FindMatch("http://example.com/", nullptr, kImage));
+ EXPECT_TRUE(FindMatch("http://example.com/", nullptr, kScript));
+ EXPECT_FALSE(FindMatch("http://example.com/", nullptr, kPopup));
+ EXPECT_FALSE(FindMatch("http://example.com/"));
+
+ EXPECT_TRUE(FindMatch("http://example.com", nullptr, kNoElement, kDocument));
+ EXPECT_FALSE(
+ FindMatch("http://example.com", nullptr, kNoElement, kGenericBlock));
+}
+
+TEST_F(UrlPatternIndexTest, FindMatchReturnsCorrectRules) {
+ constexpr size_t kNumOfPatterns = 1024;
+
+ std::vector<std::string> url_patterns(kNumOfPatterns);
+ for (size_t i = 0; i < kNumOfPatterns; ++i) {
+ url_patterns[i] = "http://example." + std::to_string(i) + ".com";
+ ASSERT_TRUE(
+ AddUrlRule(MakeUrlRule(UrlPattern(url_patterns[i], kSubstring))))
+ << "Rule #" << i;
+ }
+ Finish();
+
+ std::reverse(url_patterns.begin() + kNumOfPatterns / 2, url_patterns.end());
+ for (const std::string& url_pattern : url_patterns) {
+ SCOPED_TRACE(::testing::Message() << "UrlPattern: " << url_pattern);
+
+ const flat::UrlRule* rule = FindMatch(url_pattern);
+ ASSERT_TRUE(rule);
+ ASSERT_FALSE(IsOutOfRange(rule));
+
+ const flatbuffers::String* rule_pattern = rule->url_pattern();
+ ASSERT_TRUE(rule_pattern);
+ EXPECT_EQ(url_pattern,
+ base::StringPiece(rule_pattern->data(), rule_pattern->size()));
+ }
+
+ EXPECT_FALSE(
+ FindMatch("http://example." + std::to_string(kNumOfPatterns) + ".com"));
+}
+
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/url_rule_test_support.cc b/chromium/components/subresource_filter/core/common/url_rule_test_support.cc
new file mode 100644
index 00000000000..ab6f7f1bfe7
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/url_rule_test_support.cc
@@ -0,0 +1,56 @@
+// Copyright 2017 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/subresource_filter/core/common/url_rule_test_support.h"
+
+#include "base/logging.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace subresource_filter {
+namespace testing {
+
+proto::UrlRule MakeUrlRule(const UrlPattern& url_pattern) {
+ proto::UrlRule rule;
+
+ rule.set_semantics(proto::RULE_SEMANTICS_BLACKLIST);
+ rule.set_source_type(proto::SOURCE_TYPE_ANY);
+ rule.set_element_types(kAllElementTypes);
+
+ rule.set_url_pattern_type(url_pattern.type());
+ rule.set_anchor_left(url_pattern.anchor_left());
+ rule.set_anchor_right(url_pattern.anchor_right());
+ rule.set_match_case(url_pattern.match_case());
+ rule.set_url_pattern(url_pattern.url_pattern().as_string());
+
+ return rule;
+}
+
+void AddDomains(const std::vector<std::string>& domains, proto::UrlRule* rule) {
+ for (std::string domain_pattern : domains) {
+ DCHECK(!domain_pattern.empty());
+ auto* domain = rule->add_domains();
+ if (domain_pattern[0] == '~') {
+ domain_pattern.erase(0, 1);
+ domain->set_exclude(true);
+ }
+ domain->set_domain(std::move(domain_pattern));
+ }
+}
+
+url::Origin GetOrigin(base::StringPiece origin_string) {
+ return !origin_string.empty() ? url::Origin(GURL(origin_string))
+ : url::Origin();
+}
+
+bool IsThirdParty(const GURL& url, const url::Origin& first_party_origin) {
+ return first_party_origin.unique() ||
+ !net::registry_controlled_domains::SameDomainOrHost(
+ url, first_party_origin,
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+}
+
+} // namespace testing
+} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/core/common/url_rule_test_support.h b/chromium/components/subresource_filter/core/common/url_rule_test_support.h
new file mode 100644
index 00000000000..fef73b9456e
--- /dev/null
+++ b/chromium/components/subresource_filter/core/common/url_rule_test_support.h
@@ -0,0 +1,74 @@
+// Copyright 2017 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_SUBRESOURCE_FILTER_CORE_COMMON_URL_RULE_TEST_SUPPORT_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_URL_RULE_TEST_SUPPORT_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string_piece.h"
+#include "components/subresource_filter/core/common/proto/rules.pb.h"
+#include "components/subresource_filter/core/common/url_pattern.h"
+
+class GURL;
+
+namespace url {
+class Origin;
+}
+
+namespace subresource_filter {
+namespace testing {
+
+// Constants -------------------------------------------------------------------
+
+constexpr proto::UrlPatternType kSubstring = proto::URL_PATTERN_TYPE_SUBSTRING;
+
+constexpr proto::AnchorType kAnchorNone = proto::ANCHOR_TYPE_NONE;
+constexpr proto::AnchorType kBoundary = proto::ANCHOR_TYPE_BOUNDARY;
+constexpr proto::AnchorType kSubdomain = proto::ANCHOR_TYPE_SUBDOMAIN;
+
+constexpr proto::ElementType kNoElement = proto::ELEMENT_TYPE_UNSPECIFIED;
+constexpr proto::ElementType kOther = proto::ELEMENT_TYPE_OTHER;
+constexpr proto::ElementType kScript = proto::ELEMENT_TYPE_SCRIPT;
+constexpr proto::ElementType kImage = proto::ELEMENT_TYPE_IMAGE;
+constexpr proto::ElementType kSubdocument = proto::ELEMENT_TYPE_SUBDOCUMENT;
+constexpr proto::ElementType kFont = proto::ELEMENT_TYPE_FONT;
+constexpr proto::ElementType kPopup = proto::ELEMENT_TYPE_POPUP;
+constexpr proto::ElementType kWebSocket = proto::ELEMENT_TYPE_WEBSOCKET;
+constexpr proto::ElementType kAllElementTypes = proto::ELEMENT_TYPE_ALL;
+
+constexpr proto::ActivationType kNoActivation =
+ proto::ACTIVATION_TYPE_UNSPECIFIED;
+constexpr proto::ActivationType kDocument = proto::ACTIVATION_TYPE_DOCUMENT;
+constexpr proto::ActivationType kGenericBlock =
+ proto::ACTIVATION_TYPE_GENERICBLOCK;
+
+constexpr proto::SourceType kAnyParty = proto::SOURCE_TYPE_ANY;
+constexpr proto::SourceType kThirdParty = proto::SOURCE_TYPE_THIRD_PARTY;
+constexpr proto::SourceType kFirstParty = proto::SOURCE_TYPE_FIRST_PARTY;
+
+// Helpers ---------------------------------------------------------------------
+
+// Creates a UrlRule with the given |url_pattern|, and all necessary fields
+// initialized to defaults.
+proto::UrlRule MakeUrlRule(const UrlPattern& url_pattern = UrlPattern());
+
+// Parses |domains| and adds them to the domain list of the |rule|.
+//
+// The |domains| vector should contain non-empty strings. If a string starts
+// with '~' then the following part of the string is an exception domain.
+void AddDomains(const std::vector<std::string>& domains, proto::UrlRule* rule);
+
+// Returns the url::Origin parsed from |origin_string|, or the unique origin if
+// the string is empty.
+url::Origin GetOrigin(base::StringPiece origin_string);
+
+// Returns whether |url| is third-party resource w.r.t. |first_party_origin|.
+bool IsThirdParty(const GURL& url, const url::Origin& first_party_origin);
+
+} // namespace testing
+} // namespace subresource_filter
+
+#endif // COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_URL_RULE_TEST_SUPPORT_H_
diff --git a/chromium/components/suggestions/BUILD.gn b/chromium/components/suggestions/BUILD.gn
index 9d4a692b276..6d93d045bc4 100644
--- a/chromium/components/suggestions/BUILD.gn
+++ b/chromium/components/suggestions/BUILD.gn
@@ -6,6 +6,8 @@ static_library("suggestions") {
sources = [
"blacklist_store.cc",
"blacklist_store.h",
+ "features.cc",
+ "features.h",
"image_encoder.h",
"image_manager.cc",
"image_manager.h",
diff --git a/chromium/components/suggestions/features.cc b/chromium/components/suggestions/features.cc
new file mode 100644
index 00000000000..2cac42d4bbd
--- /dev/null
+++ b/chromium/components/suggestions/features.cc
@@ -0,0 +1,12 @@
+// Copyright 2017 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/suggestions/features.h"
+
+namespace suggestions {
+
+const base::Feature kUseSuggestionsEvenIfFewFeature{
+ "UseSuggestionsEvenIfFew", base::FEATURE_DISABLED_BY_DEFAULT};
+
+} // namespace suggestions
diff --git a/chromium/components/suggestions/features.h b/chromium/components/suggestions/features.h
new file mode 100644
index 00000000000..8a7945946c2
--- /dev/null
+++ b/chromium/components/suggestions/features.h
@@ -0,0 +1,18 @@
+// Copyright 2017 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_SUGGESTIONS_FEATURES_H_
+#define COMPONENTS_SUGGESTIONS_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace suggestions {
+
+// If this feature is enabled, we request and use suggestions even if there are
+// only very few of them.
+extern const base::Feature kUseSuggestionsEvenIfFewFeature;
+
+} // namespace suggestions
+
+#endif // COMPONENTS_SUGGESTIONS_FEATURES_H_
diff --git a/chromium/components/suggestions/image_encoder.cc b/chromium/components/suggestions/image_encoder.cc
index 73283cf5bbb..8b0fa09fc26 100644
--- a/chromium/components/suggestions/image_encoder.cc
+++ b/chromium/components/suggestions/image_encoder.cc
@@ -17,7 +17,6 @@ std::unique_ptr<SkBitmap> DecodeJPEGToSkBitmap(const void* encoded_data,
bool EncodeSkBitmapToJPEG(const SkBitmap& bitmap,
std::vector<unsigned char>* dest) {
- SkAutoLockPixels bitmap_lock(bitmap);
if (!bitmap.readyToDraw() || bitmap.isNull()) {
return false;
}
diff --git a/chromium/components/suggestions/image_manager.cc b/chromium/components/suggestions/image_manager.cc
index 366a6a2018c..d2fb227f9ac 100644
--- a/chromium/components/suggestions/image_manager.cc
+++ b/chromium/components/suggestions/image_manager.cc
@@ -12,6 +12,7 @@
#include "base/task_runner_util.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/suggestions/image_encoder.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ui/gfx/image/image.h"
using leveldb_proto::ProtoDatabase;
@@ -39,6 +40,39 @@ void WrapCallback(
wrapped_callback.Run(GURL(url), image);
}
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("suggestions_image_manager", R"(
+ semantics {
+ sender: "Suggestions Service Thumbnail Fetch"
+ description:
+ "Retrieves thumbnails for site suggestions based on the user's "
+ "synced browsing history, for use e.g. on the New Tab page."
+ trigger:
+ "Triggered when a thumbnail for a suggestion is required, and no "
+ "local thumbnail is available."
+ data: "The URL for which to retrieve a thumbnail."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can disable this feature by signing out of Chrome, or "
+ "disabling Sync or History Sync in Chrome settings under 'Advanced "
+ "sync settings...'. The feature is enabled by default."
+ chrome_policy {
+ SyncDisabled {
+ policy_options {mode: MANDATORY}
+ SyncDisabled: true
+ }
+ }
+ chrome_policy {
+ SigninAllowed {
+ policy_options {mode: MANDATORY}
+ SigninAllowed: false
+ }
+ }
+ })");
+
} // namespace
namespace suggestions {
@@ -146,7 +180,8 @@ void ImageManager::OnCacheImageDecoded(
callback.Run(url, gfx::Image::CreateFrom1xBitmap(*bitmap));
} else {
image_fetcher_->StartOrQueueNetworkRequest(
- url.spec(), image_url, base::Bind(&WrapCallback, callback));
+ url.spec(), image_url, base::Bind(&WrapCallback, callback),
+ kTrafficAnnotation);
}
}
@@ -173,7 +208,8 @@ void ImageManager::ServeFromCacheOrNetwork(
weak_ptr_factory_.GetWeakPtr(), url, image_url, callback));
} else {
image_fetcher_->StartOrQueueNetworkRequest(
- url.spec(), image_url, base::Bind(&WrapCallback, callback));
+ url.spec(), image_url, base::Bind(&WrapCallback, callback),
+ kTrafficAnnotation);
}
}
diff --git a/chromium/components/suggestions/image_manager_unittest.cc b/chromium/components/suggestions/image_manager_unittest.cc
index 0966a21a7f1..86717dd169b 100644
--- a/chromium/components/suggestions/image_manager_unittest.cc
+++ b/chromium/components/suggestions/image_manager_unittest.cc
@@ -18,6 +18,7 @@
#include "components/leveldb_proto/testing/fake_db.h"
#include "components/suggestions/image_encoder.h"
#include "components/suggestions/proto/suggestions.pb.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size.h"
@@ -41,7 +42,7 @@ const char kInvalidImagePath[] = "files/DOESNOTEXIST";
using leveldb_proto::test::FakeDB;
-typedef base::hash_map<std::string, ImageData> EntryMap;
+typedef std::map<std::string, ImageData> EntryMap;
void AddEntry(const ImageData& d, EntryMap* map) { (*map)[d.url()] = d; }
@@ -49,10 +50,11 @@ class MockImageFetcher : public ImageFetcher {
public:
MockImageFetcher() {}
virtual ~MockImageFetcher() {}
- MOCK_METHOD3(StartOrQueueNetworkRequest,
+ MOCK_METHOD4(StartOrQueueNetworkRequest,
void(const std::string&,
const GURL&,
- const ImageFetcherCallback&));
+ const ImageFetcherCallback&,
+ const net::NetworkTrafficAnnotationTag&));
MOCK_METHOD1(SetImageFetcherDelegate, void(ImageFetcherDelegate*));
MOCK_METHOD1(SetDataUseServiceName, void(DataUseServiceName));
MOCK_METHOD1(SetImageDownloadLimit,
@@ -178,7 +180,7 @@ TEST_F(ImageManagerTest, GetImageForURLNetwork) {
InitializeDefaultImageMapAndDatabase(image_manager_.get(), fake_db_);
// We expect the fetcher to go to network and call the callback.
- EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _));
+ EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _, _));
// Fetch existing URL.
base::RunLoop run_loop;
diff --git a/chromium/components/suggestions/suggestions_service.h b/chromium/components/suggestions/suggestions_service.h
index 9773ee07418..76a118290f6 100644
--- a/chromium/components/suggestions/suggestions_service.h
+++ b/chromium/components/suggestions/suggestions_service.h
@@ -17,7 +17,7 @@
namespace gfx {
class Image;
-} // namespce gfx
+} // namespace gfx
namespace suggestions {
diff --git a/chromium/components/suggestions/suggestions_service_impl.cc b/chromium/components/suggestions/suggestions_service_impl.cc
index 6e41445d9a6..aacd400d7b5 100644
--- a/chromium/components/suggestions/suggestions_service_impl.cc
+++ b/chromium/components/suggestions/suggestions_service_impl.cc
@@ -10,6 +10,7 @@
#include "base/feature_list.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_number_conversions.h"
@@ -22,6 +23,7 @@
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/suggestions/blacklist_store.h"
+#include "components/suggestions/features.h"
#include "components/suggestions/image_manager.h"
#include "components/suggestions/suggestions_store.h"
#include "components/sync/driver/sync_service.h"
@@ -46,37 +48,6 @@ namespace suggestions {
namespace {
-// Establishes the different sync states that matter to SuggestionsService.
-// There are three different concepts in the sync service: initialized, sync
-// enabled and history sync enabled.
-enum SyncState {
- // State: Sync service is not initialized, yet not disabled. History sync
- // state is unknown (since not initialized).
- // Behavior: Does not issue a server request, but serves from cache if
- // available.
- NOT_INITIALIZED_ENABLED,
-
- // State: Sync service is initialized, sync is enabled and history sync is
- // enabled.
- // Behavior: Update suggestions from the server. Serve from cache on timeout.
- INITIALIZED_ENABLED_HISTORY,
-
- // State: Sync service is disabled or history sync is disabled.
- // Behavior: Do not issue a server request. Clear the cache. Serve empty
- // suggestions.
- SYNC_OR_HISTORY_SYNC_DISABLED,
-};
-
-SyncState GetSyncState(syncer::SyncService* sync) {
- if (!sync || !sync->CanSyncStart() || sync->IsLocalSyncEnabled())
- return SYNC_OR_HISTORY_SYNC_DISABLED;
- if (!sync->IsSyncActive() || !sync->ConfigurationDone())
- return NOT_INITIALIZED_ENABLED;
- return sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES)
- ? INITIALIZED_ENABLED_HISTORY
- : SYNC_OR_HISTORY_SYNC_DISABLED;
-}
-
// Used to UMA log the state of the last response from the server.
enum SuggestionsResponseState {
RESPONSE_EMPTY,
@@ -113,13 +84,18 @@ GURL GetGoogleBaseURL() {
// Format strings for the various suggestions URLs. They all have two string
// params: The Google base URL and the device type.
// TODO(mathp): Put this in TemplateURL.
-const char kSuggestionsURLFormat[] = "%schromesuggestions?t=%s";
+const char kSuggestionsURLFormat[] = "%schromesuggestions?%s";
const char kSuggestionsBlacklistURLPrefixFormat[] =
"%schromesuggestions/blacklist?t=%s&url=";
const char kSuggestionsBlacklistClearURLFormat[] =
"%schromesuggestions/blacklist/clear?t=%s";
const char kSuggestionsBlacklistURLParam[] = "url";
+const char kSuggestionsDeviceParam[] = "t=%s";
+const char kSuggestionsMinParam[] = "min=%i";
+
+const char kSuggestionsMinVariationName[] = "min_suggestions";
+const int kSuggestionsMinVariationDefault = 0;
#if defined(OS_ANDROID) || defined(OS_IOS)
const char kDeviceType[] = "2";
@@ -136,6 +112,12 @@ const char kFaviconURL[] =
// The default expiry timeout is 168 hours.
const int64_t kDefaultExpiryUsec = 168 * base::Time::kMicrosecondsPerHour;
+int GetMinimumSuggestionsCount() {
+ return base::GetFieldTrialParamByFeatureAsInt(
+ kUseSuggestionsEvenIfFewFeature, kSuggestionsMinVariationName,
+ kSuggestionsMinVariationDefault);
+}
+
} // namespace
SuggestionsServiceImpl::SuggestionsServiceImpl(
@@ -150,6 +132,7 @@ SuggestionsServiceImpl::SuggestionsServiceImpl(
token_service_(token_service),
sync_service_(sync_service),
sync_service_observer_(this),
+ sync_state_(INITIALIZED_ENABLED_HISTORY),
url_request_context_(url_request_context),
suggestions_store_(std::move(suggestions_store)),
thumbnail_manager_(std::move(thumbnail_manager)),
@@ -157,8 +140,9 @@ SuggestionsServiceImpl::SuggestionsServiceImpl(
scheduling_delay_(TimeDelta::FromSeconds(kDefaultSchedulingDelaySec)),
weak_ptr_factory_(this) {
// |sync_service_| is null if switches::kDisableSync is set (tests use that).
- if (sync_service_)
+ if (sync_service_) {
sync_service_observer_.Add(sync_service_);
+ }
// Immediately get the current sync state, so we'll flush the cache if
// necessary.
OnStateChanged(sync_service_);
@@ -169,8 +153,9 @@ SuggestionsServiceImpl::~SuggestionsServiceImpl() {}
bool SuggestionsServiceImpl::FetchSuggestionsData() {
DCHECK(thread_checker_.CalledOnValidThread());
// If sync state allows, issue a network request to refresh the suggestions.
- if (GetSyncState(sync_service_) != INITIALIZED_ENABLED_HISTORY)
+ if (sync_state_ != INITIALIZED_ENABLED_HISTORY) {
return false;
+ }
IssueRequestIfNoneOngoing(BuildSuggestionsURL());
return true;
}
@@ -208,6 +193,8 @@ void SuggestionsServiceImpl::GetPageThumbnailWithURL(
bool SuggestionsServiceImpl::BlacklistURL(const GURL& candidate_url) {
DCHECK(thread_checker_.CalledOnValidThread());
+ // TODO(treib): Do we need to check |sync_state_| here?
+
if (!blacklist_store_->BlacklistUrl(candidate_url))
return false;
@@ -224,6 +211,9 @@ bool SuggestionsServiceImpl::BlacklistURL(const GURL& candidate_url) {
bool SuggestionsServiceImpl::UndoBlacklistURL(const GURL& url) {
DCHECK(thread_checker_.CalledOnValidThread());
+
+ // TODO(treib): Do we need to check |sync_state_| here?
+
TimeDelta time_delta;
if (blacklist_store_->GetTimeUntilURLReadyForUpload(url, &time_delta) &&
time_delta > TimeDelta::FromSeconds(0) &&
@@ -239,6 +229,9 @@ bool SuggestionsServiceImpl::UndoBlacklistURL(const GURL& url) {
void SuggestionsServiceImpl::ClearBlacklist() {
DCHECK(thread_checker_.CalledOnValidThread());
+
+ // TODO(treib): Do we need to check |sync_state_| here?
+
blacklist_store_->ClearBlacklist();
callback_list_.Notify(
GetSuggestionsDataFromCache().value_or(SuggestionsProfile()));
@@ -276,8 +269,16 @@ void SuggestionsServiceImpl::RegisterProfilePrefs(
// static
GURL SuggestionsServiceImpl::BuildSuggestionsURL() {
+ std::string device = base::StringPrintf(kSuggestionsDeviceParam, kDeviceType);
+ std::string query = device;
+ if (base::FeatureList::IsEnabled(kUseSuggestionsEvenIfFewFeature)) {
+ std::string min_suggestions =
+ base::StringPrintf(kSuggestionsMinParam, GetMinimumSuggestionsCount());
+ query =
+ base::StringPrintf("%s&%s", device.c_str(), min_suggestions.c_str());
+ }
return GURL(base::StringPrintf(
- kSuggestionsURLFormat, GetGoogleBaseURL().spec().c_str(), kDeviceType));
+ kSuggestionsURLFormat, GetGoogleBaseURL().spec().c_str(), query.c_str()));
}
// static
@@ -300,22 +301,64 @@ GURL SuggestionsServiceImpl::BuildSuggestionsBlacklistClearURL() {
kDeviceType));
}
-void SuggestionsServiceImpl::OnStateChanged(syncer::SyncService* sync) {
- switch (GetSyncState(sync_service_)) {
+SuggestionsServiceImpl::SyncState SuggestionsServiceImpl::ComputeSyncState()
+ const {
+ if (!sync_service_ || !sync_service_->CanSyncStart() ||
+ sync_service_->IsLocalSyncEnabled()) {
+ return SYNC_OR_HISTORY_SYNC_DISABLED;
+ }
+ if (!sync_service_->IsSyncActive() || !sync_service_->ConfigurationDone()) {
+ return NOT_INITIALIZED_ENABLED;
+ }
+ return sync_service_->GetActiveDataTypes().Has(
+ syncer::HISTORY_DELETE_DIRECTIVES)
+ ? INITIALIZED_ENABLED_HISTORY
+ : SYNC_OR_HISTORY_SYNC_DISABLED;
+}
+
+SuggestionsServiceImpl::RefreshAction
+SuggestionsServiceImpl::RefreshSyncState() {
+ SyncState new_sync_state = ComputeSyncState();
+ if (sync_state_ == new_sync_state) {
+ return NO_ACTION;
+ }
+
+ SyncState old_sync_state = sync_state_;
+ sync_state_ = new_sync_state;
+
+ switch (new_sync_state) {
+ case NOT_INITIALIZED_ENABLED:
+ break;
+ case INITIALIZED_ENABLED_HISTORY:
+ // If the user just signed in, we fetch suggestions, so that hopefully the
+ // next NTP will already get them.
+ if (old_sync_state == SYNC_OR_HISTORY_SYNC_DISABLED) {
+ return FETCH_SUGGESTIONS;
+ }
+ break;
case SYNC_OR_HISTORY_SYNC_DISABLED:
+ // If the user signed out (or disabled history sync), we have to clear
+ // everything.
+ return CLEAR_SUGGESTIONS;
+ }
+ // Otherwise, there's nothing to do.
+ return NO_ACTION;
+}
+
+void SuggestionsServiceImpl::OnStateChanged(syncer::SyncService* sync) {
+ DCHECK(sync_service_ == sync);
+
+ switch (RefreshSyncState()) {
+ case NO_ACTION:
+ break;
+ case CLEAR_SUGGESTIONS:
// Cancel any ongoing request, to stop interacting with the server.
pending_request_.reset(nullptr);
suggestions_store_->ClearSuggestions();
callback_list_.Notify(SuggestionsProfile());
break;
- case NOT_INITIALIZED_ENABLED:
- // Keep the cache (if any), but don't refresh.
- break;
- case INITIALIZED_ENABLED_HISTORY:
- // If we have any observers, issue a network request to refresh the
- // suggestions in the cache.
- if (!callback_list_.empty())
- IssueRequestIfNoneOngoing(BuildSuggestionsURL());
+ case FETCH_SUGGESTIONS:
+ IssueRequestIfNoneOngoing(BuildSuggestionsURL());
break;
}
}
@@ -335,6 +378,10 @@ void SuggestionsServiceImpl::SetDefaultExpiryTimestamp(
void SuggestionsServiceImpl::IssueRequestIfNoneOngoing(const GURL& url) {
// If there is an ongoing request, let it complete.
+ // This will silently swallow blacklist and clearblacklist requests if a
+ // request happens to be ongoing.
+ // TODO(treib): Queue such requests and send them after the current one
+ // completes.
if (pending_request_.get()) {
return;
}
diff --git a/chromium/components/suggestions/suggestions_service_impl.h b/chromium/components/suggestions/suggestions_service_impl.h
index ff31fc84ce4..f01cb854745 100644
--- a/chromium/components/suggestions/suggestions_service_impl.h
+++ b/chromium/components/suggestions/suggestions_service_impl.h
@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/callback_list.h"
+#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
@@ -77,6 +78,16 @@ class SuggestionsServiceImpl : public SuggestionsService,
bool UndoBlacklistURL(const GURL& url) override;
void ClearBlacklist() override;
+ base::TimeDelta blacklist_delay_for_testing() const {
+ return scheduling_delay_;
+ }
+ void set_blacklist_delay_for_testing(base::TimeDelta delay) {
+ scheduling_delay_ = delay;
+ }
+ bool has_pending_request_for_testing() const {
+ return !!pending_request_.get();
+ }
+
// Determines which URL a blacklist request was for, irrespective of the
// request's status. Returns false if |request| is not a blacklist request.
static bool GetBlacklistedUrl(const net::URLFetcher& request, GURL* url);
@@ -85,23 +96,27 @@ class SuggestionsServiceImpl : public SuggestionsService,
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
private:
- friend class SuggestionsServiceTest;
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, FetchSuggestionsData);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest,
- FetchSuggestionsDataSyncDisabled);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest,
- FetchSuggestionsDataNoAccessToken);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest,
- IssueRequestIfNoneOngoingError);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest,
- IssueRequestIfNoneOngoingResponseNotOK);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURL);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURLRequestFails);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, ClearBlacklist);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UndoBlacklistURL);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, GetBlacklistedUrl);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UpdateBlacklistDelay);
- FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, CheckDefaultTimeStamps);
+ // Establishes the different sync states that matter to SuggestionsService.
+ enum SyncState {
+ // State: Sync service is not initialized, yet not disabled. History sync
+ // state is unknown (since not initialized).
+ // Behavior: Do not issue server requests, but serve from cache if
+ // available.
+ NOT_INITIALIZED_ENABLED,
+
+ // State: Sync service is initialized, sync is enabled and history sync is
+ // enabled.
+ // Behavior: Update suggestions from the server on FetchSuggestionsData().
+ INITIALIZED_ENABLED_HISTORY,
+
+ // State: Sync service is disabled or history sync is disabled.
+ // Behavior: Do not issue server requests. Clear the cache. Serve empty
+ // suggestions.
+ SYNC_OR_HISTORY_SYNC_DISABLED,
+ };
+
+ // The action that should be taken as the result of a RefreshSyncState call.
+ enum RefreshAction { NO_ACTION, FETCH_SUGGESTIONS, CLEAR_SUGGESTIONS };
// Helpers to build the various suggestions URLs. These are static members
// rather than local functions in the .cc file to make them accessible to
@@ -111,6 +126,13 @@ class SuggestionsServiceImpl : public SuggestionsService,
static GURL BuildSuggestionsBlacklistURL(const GURL& candidate_url);
static GURL BuildSuggestionsBlacklistClearURL();
+ // Computes the appropriate SyncState from |sync_service_|.
+ SyncState ComputeSyncState() const;
+
+ // Re-computes |sync_state_| from the sync service. Returns the action that
+ // should be taken in response.
+ RefreshAction RefreshSyncState() WARN_UNUSED_RESULT;
+
// syncer::SyncServiceObserver implementation.
void OnStateChanged(syncer::SyncService* sync) override;
@@ -159,10 +181,6 @@ class SuggestionsServiceImpl : public SuggestionsService,
// Adds extra data to suggestions profile.
void PopulateExtraData(SuggestionsProfile* suggestions);
- // Test seams.
- base::TimeDelta blacklist_delay() const { return scheduling_delay_; }
- void set_blacklist_delay(base::TimeDelta delay) { scheduling_delay_ = delay; }
-
base::ThreadChecker thread_checker_;
SigninManagerBase* signin_manager_;
@@ -172,6 +190,8 @@ class SuggestionsServiceImpl : public SuggestionsService,
ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver>
sync_service_observer_;
+ SyncState sync_state_;
+
net::URLRequestContextGetter* url_request_context_;
// The cache for the suggestions.
diff --git a/chromium/components/suggestions/suggestions_service_impl_unittest.cc b/chromium/components/suggestions/suggestions_service_impl_unittest.cc
index 829c0536912..7aa45beb51e 100644
--- a/chromium/components/suggestions/suggestions_service_impl_unittest.cc
+++ b/chromium/components/suggestions/suggestions_service_impl_unittest.cc
@@ -10,22 +10,25 @@
#include <utility>
#include "base/bind.h"
-#include "base/feature_list.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/suggestions/blacklist_store.h"
+#include "components/suggestions/features.h"
#include "components/suggestions/image_manager.h"
#include "components/suggestions/proto/suggestions.pb.h"
#include "components/suggestions/suggestions_store.h"
#include "components/sync/driver/fake_sync_service.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
-#include "net/base/escape.h"
+#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
@@ -36,11 +39,12 @@
#include "ui/gfx/image/image.h"
using sync_preferences::TestingPrefServiceSyncable;
+using syncer::SyncServiceObserver;
using testing::_;
using testing::AnyNumber;
using testing::DoAll;
using testing::Eq;
-using testing::NiceMock;
+using testing::Mock;
using testing::Return;
using testing::SetArgPointee;
using testing::StrictMock;
@@ -48,33 +52,16 @@ using testing::StrictMock;
namespace {
const char kAccountId[] = "account";
+const char kSuggestionsUrlPath[] = "/chromesuggestions";
+const char kBlacklistUrlPath[] = "/chromesuggestions/blacklist";
+const char kBlacklistClearUrlPath[] = "/chromesuggestions/blacklist/clear";
const char kTestTitle[] = "a title";
const char kTestUrl[] = "http://go.com";
const char kTestFaviconUrl[] =
"https://s2.googleusercontent.com/s2/favicons?domain_url="
"http://go.com&alt=s&sz=32";
const char kBlacklistedUrl[] = "http://blacklist.com";
-const char kBlacklistedUrlAlt[] = "http://blacklist-atl.com";
-const int64_t kTestDefaultExpiry = 1402200000000000;
-const int64_t kTestSetExpiry = 1404792000000000;
-
-std::unique_ptr<net::FakeURLFetcher> CreateURLFetcher(
- const GURL& url,
- net::URLFetcherDelegate* delegate,
- const std::string& response_data,
- net::HttpStatusCode response_code,
- net::URLRequestStatus::Status status) {
- std::unique_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher(
- url, delegate, response_data, response_code, status));
-
- if (response_code == net::HTTP_OK) {
- scoped_refptr<net::HttpResponseHeaders> download_headers(
- new net::HttpResponseHeaders(""));
- download_headers->AddHeader("Content-Type: text/html");
- fetcher->set_response_headers(download_headers);
- }
- return fetcher;
-}
+const int64_t kTestSetExpiry = 12121212; // This timestamp lies in the past.
// GMock matcher for protobuf equality.
MATCHER_P(EqualsProto, message, "") {
@@ -97,23 +84,6 @@ SuggestionsProfile CreateSuggestionsProfile() {
ChromeSuggestion* suggestion = profile.add_suggestions();
suggestion->set_title(kTestTitle);
suggestion->set_url(kTestUrl);
- suggestion->set_expiry_ts(kTestSetExpiry);
- return profile;
-}
-
-// Creates one suggestion with expiry timestamp and one without.
-SuggestionsProfile CreateSuggestionsProfileWithExpiryTimestamps() {
- SuggestionsProfile profile;
- profile.set_timestamp(123);
- ChromeSuggestion* suggestion = profile.add_suggestions();
- suggestion->set_title(kTestTitle);
- suggestion->set_url(kTestUrl);
- suggestion->set_expiry_ts(kTestSetExpiry);
-
- suggestion = profile.add_suggestions();
- suggestion->set_title(kTestTitle);
- suggestion->set_url(kTestUrl);
-
return profile;
}
@@ -159,49 +129,22 @@ class MockImageManager : public suggestions::ImageManager {
class MockBlacklistStore : public suggestions::BlacklistStore {
public:
MOCK_METHOD1(BlacklistUrl, bool(const GURL&));
- MOCK_METHOD0(IsEmpty, bool());
+ MOCK_METHOD0(ClearBlacklist, void());
MOCK_METHOD1(GetTimeUntilReadyForUpload, bool(base::TimeDelta*));
MOCK_METHOD2(GetTimeUntilURLReadyForUpload,
bool(const GURL&, base::TimeDelta*));
MOCK_METHOD1(GetCandidateForUpload, bool(GURL*));
MOCK_METHOD1(RemoveUrl, bool(const GURL&));
MOCK_METHOD1(FilterSuggestions, void(SuggestionsProfile*));
- MOCK_METHOD0(ClearBlacklist, void());
};
class SuggestionsServiceTest : public testing::Test {
- public:
- void CheckCallback(const SuggestionsProfile& suggestions_profile) {
- ++suggestions_data_callback_count_;
- if (suggestions_profile.suggestions_size() == 0)
- ++suggestions_empty_data_count_;
- }
-
- void CheckSuggestionsData() {
- SuggestionsProfile suggestions_profile;
- test_suggestions_store_->LoadSuggestions(&suggestions_profile);
- EXPECT_EQ(1, suggestions_profile.suggestions_size());
- EXPECT_EQ(kTestTitle, suggestions_profile.suggestions(0).title());
- EXPECT_EQ(kTestUrl, suggestions_profile.suggestions(0).url());
- EXPECT_EQ(kTestFaviconUrl,
- suggestions_profile.suggestions(0).favicon_url());
- }
-
- int suggestions_data_callback_count_;
- int suggestions_empty_data_count_;
- bool blacklisting_failed_;
- bool undo_blacklisting_failed_;
-
protected:
SuggestionsServiceTest()
- : suggestions_data_callback_count_(0),
- suggestions_empty_data_count_(0),
- blacklisting_failed_(false),
- undo_blacklisting_failed_(false),
- signin_client_(&pref_service_),
+ : signin_client_(&pref_service_),
signin_manager_(&signin_client_, &account_tracker_),
- factory_(nullptr, base::Bind(&CreateURLFetcher)),
- mock_sync_service_(nullptr),
+ request_context_(new net::TestURLRequestContextGetter(
+ io_message_loop_.task_runner())),
mock_thumbnail_manager_(nullptr),
mock_blacklist_store_(nullptr),
test_suggestions_store_(nullptr) {
@@ -216,308 +159,317 @@ class SuggestionsServiceTest : public testing::Test {
~SuggestionsServiceTest() override {}
void SetUp() override {
- request_context_ =
- new net::TestURLRequestContextGetter(io_message_loop_.task_runner());
- }
-
- std::unique_ptr<SuggestionsServiceImpl> CreateSuggestionsServiceWithMocks() {
- mock_sync_service_.reset(new MockSyncService);
- EXPECT_CALL(*mock_sync_service_, CanSyncStart())
+ EXPECT_CALL(*sync_service(), CanSyncStart())
.Times(AnyNumber())
.WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_sync_service_, IsSyncActive())
+ EXPECT_CALL(*sync_service(), IsSyncActive())
.Times(AnyNumber())
.WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_sync_service_, ConfigurationDone())
+ EXPECT_CALL(*sync_service(), ConfigurationDone())
.Times(AnyNumber())
.WillRepeatedly(Return(true));
- EXPECT_CALL(*mock_sync_service_, GetActiveDataTypes())
+ EXPECT_CALL(*sync_service(), GetActiveDataTypes())
.Times(AnyNumber())
.WillRepeatedly(
Return(syncer::ModelTypeSet(syncer::HISTORY_DELETE_DIRECTIVES)));
-
- // These objects are owned by the returned SuggestionsService, but we keep
- // the pointer around for testing.
+ // These objects are owned by the SuggestionsService, but we keep the
+ // pointers around for testing.
test_suggestions_store_ = new TestSuggestionsStore();
mock_thumbnail_manager_ = new StrictMock<MockImageManager>();
mock_blacklist_store_ = new StrictMock<MockBlacklistStore>();
- return base::MakeUnique<SuggestionsServiceImpl>(
- &signin_manager_, &token_service_, mock_sync_service_.get(),
+ suggestions_service_ = base::MakeUnique<SuggestionsServiceImpl>(
+ &signin_manager_, &token_service_, &mock_sync_service_,
request_context_.get(), base::WrapUnique(test_suggestions_store_),
base::WrapUnique(mock_thumbnail_manager_),
base::WrapUnique(mock_blacklist_store_));
}
- void Blacklist(SuggestionsService* suggestions_service, GURL url) {
- blacklisting_failed_ = !suggestions_service->BlacklistURL(url);
+ GURL GetCurrentlyQueriedUrl() {
+ net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
+ if (!fetcher) {
+ return GURL();
+ }
+ return fetcher->GetOriginalURL();
}
- void UndoBlacklist(SuggestionsService* suggestions_service, GURL url) {
- undo_blacklisting_failed_ = !suggestions_service->UndoBlacklistURL(url);
+ void RespondToFetch(const std::string& response_body,
+ net::HttpStatusCode response_code,
+ net::URLRequestStatus status) {
+ net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
+ ASSERT_TRUE(fetcher) << "Tried to respond to fetch that is not ongoing!";
+ fetcher->SetResponseString(response_body);
+ fetcher->set_response_code(response_code);
+ fetcher->set_status(status);
+ fetcher->delegate()->OnURLFetchComplete(fetcher);
}
- // Helper for Undo failure tests. Depending on |is_uploaded|, tests either
- // the case where the URL is no longer in the local blacklist or the case
- // in which it's not yet candidate for upload.
- void UndoBlacklistURLFailsHelper(bool is_uploaded) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- EXPECT_TRUE(suggestions_service != nullptr);
- // Ensure scheduling the request doesn't happen before undo.
- base::TimeDelta delay = base::TimeDelta::FromHours(1);
- suggestions_service->set_blacklist_delay(delay);
-
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
-
- SuggestionsProfile suggestions_profile = CreateSuggestionsProfile();
- GURL blacklisted_url(kBlacklistedUrl);
-
- // Blacklist expectations.
- EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
- .WillOnce(Return(true));
- EXPECT_CALL(*mock_thumbnail_manager_,
- Initialize(EqualsProto(suggestions_profile)));
- EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_));
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
- .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
- // Undo expectations.
- if (is_uploaded) {
- // URL is not in local blacklist.
- EXPECT_CALL(*mock_blacklist_store_,
- GetTimeUntilURLReadyForUpload(Eq(blacklisted_url), _))
- .WillOnce(Return(false));
- } else {
- // URL is not yet candidate for upload.
- base::TimeDelta negative_delay = base::TimeDelta::FromHours(-1);
- EXPECT_CALL(*mock_blacklist_store_,
- GetTimeUntilURLReadyForUpload(Eq(blacklisted_url), _))
- .WillOnce(DoAll(SetArgPointee<1>(negative_delay), Return(true)));
- }
+ void RespondToFetchWithProfile(const SuggestionsProfile& suggestions) {
+ RespondToFetch(
+ suggestions.SerializeAsString(), net::HTTP_OK,
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
+ }
- Blacklist(suggestions_service.get(), blacklisted_url);
- UndoBlacklist(suggestions_service.get(), blacklisted_url);
+ FakeProfileOAuth2TokenService* token_service() { return &token_service_; }
- EXPECT_EQ(1, suggestions_data_callback_count_);
- EXPECT_FALSE(blacklisting_failed_);
- EXPECT_TRUE(undo_blacklisting_failed_);
- }
+ MockSyncService* sync_service() { return &mock_sync_service_; }
+
+ MockImageManager* thumbnail_manager() { return mock_thumbnail_manager_; }
+
+ MockBlacklistStore* blacklist_store() { return mock_blacklist_store_; }
+
+ TestSuggestionsStore* suggestions_store() { return test_suggestions_store_; }
- bool HasPendingSuggestionsRequest(
- SuggestionsServiceImpl* suggestions_service) {
- return !!suggestions_service->pending_request_.get();
+ SuggestionsServiceImpl* suggestions_service() {
+ return suggestions_service_.get();
}
- protected:
+ private:
base::MessageLoopForIO io_message_loop_;
TestingPrefServiceSyncable pref_service_;
AccountTrackerService account_tracker_;
TestSigninClient signin_client_;
FakeSigninManagerBase signin_manager_;
- net::FakeURLFetcherFactory factory_;
+ net::TestURLFetcherFactory factory_;
FakeProfileOAuth2TokenService token_service_;
- std::unique_ptr<MockSyncService> mock_sync_service_;
- // Only used if the SuggestionsService is built with mocks. Not owned.
+ MockSyncService mock_sync_service_;
+ scoped_refptr<net::TestURLRequestContextGetter> request_context_;
+ // Owned by the SuggestionsService.
MockImageManager* mock_thumbnail_manager_;
MockBlacklistStore* mock_blacklist_store_;
TestSuggestionsStore* test_suggestions_store_;
- scoped_refptr<net::TestURLRequestContextGetter> request_context_;
- private:
+ std::unique_ptr<SuggestionsServiceImpl> suggestions_service_;
+
DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceTest);
};
TEST_F(SuggestionsServiceTest, FetchSuggestionsData) {
- std::unique_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
-
- SuggestionsProfile suggestions_profile = CreateSuggestionsProfile();
-
- // Set up net::FakeURLFetcherFactory.
- factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(),
- suggestions_profile.SerializeAsString(),
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
- // Expectations.
- EXPECT_CALL(*mock_thumbnail_manager_, Initialize(_));
- EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_));
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
+
+ EXPECT_CALL(*thumbnail_manager(), Initialize(_));
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(Return(false));
// Send the request. The data should be returned to the callback.
- suggestions_service->FetchSuggestionsData();
+ suggestions_service()->FetchSuggestionsData();
- // Let the network request run.
+ EXPECT_CALL(callback, Run(_));
+
+ // Wait for the eventual network request.
base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(GetCurrentlyQueriedUrl().is_valid());
+ EXPECT_EQ(GetCurrentlyQueriedUrl().path(), kSuggestionsUrlPath);
+ RespondToFetchWithProfile(CreateSuggestionsProfile());
- // Ensure that CheckCallback() ran once.
- EXPECT_EQ(1, suggestions_data_callback_count_);
+ SuggestionsProfile suggestions;
+ suggestions_store()->LoadSuggestions(&suggestions);
+ ASSERT_EQ(1, suggestions.suggestions_size());
+ EXPECT_EQ(kTestTitle, suggestions.suggestions(0).title());
+ EXPECT_EQ(kTestUrl, suggestions.suggestions(0).url());
+ EXPECT_EQ(kTestFaviconUrl, suggestions.suggestions(0).favicon_url());
+}
+
+TEST_F(SuggestionsServiceTest, IgnoresNoopSyncChange) {
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ EXPECT_CALL(callback, Run(_)).Times(0);
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
+
+ // An no-op change should not result in a suggestions refresh.
+ static_cast<SyncServiceObserver*>(suggestions_service())
+ ->OnStateChanged(sync_service());
+
+ // Wait for eventual (but unexpected) network requests.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
+}
- CheckSuggestionsData();
+TEST_F(SuggestionsServiceTest, IgnoresUninterestingSyncChange) {
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ EXPECT_CALL(callback, Run(_)).Times(0);
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
+
+ // An uninteresting change should not result in a network request (the
+ // SyncState is INITIALIZED_ENABLED_HISTORY before and after).
+ EXPECT_CALL(*sync_service(), GetActiveDataTypes())
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(syncer::ModelTypeSet(
+ syncer::HISTORY_DELETE_DIRECTIVES, syncer::BOOKMARKS)));
+ static_cast<SyncServiceObserver*>(suggestions_service())
+ ->OnStateChanged(sync_service());
+
+ // Wait for eventual (but unexpected) network requests.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
+}
+
+// During startup, the state changes from NOT_INITIALIZED_ENABLED to
+// INITIALIZED_ENABLED_HISTORY (for a signed-in user with history sync enabled).
+// This should *not* result in an automatic fetch.
+TEST_F(SuggestionsServiceTest, DoesNotFetchOnStartup) {
+ // The sync service starts out inactive.
+ EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(false));
+ static_cast<SyncServiceObserver*>(suggestions_service())
+ ->OnStateChanged(sync_service());
+
+ base::RunLoop().RunUntilIdle();
+ ASSERT_FALSE(suggestions_service()->has_pending_request_for_testing());
+
+ // Sync getting enabled should not result in a fetch.
+ EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(true));
+ static_cast<SyncServiceObserver*>(suggestions_service())
+ ->OnStateChanged(sync_service());
+
+ // Wait for eventual (but unexpected) network requests.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
+}
+
+TEST_F(SuggestionsServiceTest, BuildUrlWithDefaultMinZeroParamForFewFeature) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(kUseSuggestionsEvenIfFewFeature);
+
+ EXPECT_CALL(*thumbnail_manager(), Initialize(_));
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
+ .WillOnce(Return(false));
+
+ // Send the request. The data should be returned to the callback.
+ suggestions_service()->FetchSuggestionsData();
+
+ // Wait for the eventual network request.
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(GetCurrentlyQueriedUrl().is_valid());
+ EXPECT_EQ(GetCurrentlyQueriedUrl().path(), kSuggestionsUrlPath);
+ std::string min_suggestions;
+ EXPECT_TRUE(net::GetValueForKeyInQuery(GetCurrentlyQueriedUrl(), "min",
+ &min_suggestions));
+ EXPECT_EQ(min_suggestions, "0");
+ RespondToFetchWithProfile(CreateSuggestionsProfile());
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncNotInitializedEnabled) {
- std::unique_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
- EXPECT_CALL(*mock_sync_service_, IsSyncActive())
- .WillRepeatedly(Return(false));
+ EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(false));
+ static_cast<SyncServiceObserver*>(suggestions_service())
+ ->OnStateChanged(sync_service());
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ EXPECT_CALL(callback, Run(_)).Times(0);
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
// Try to fetch suggestions. Since sync is not active, no network request
// should be sent.
- suggestions_service->FetchSuggestionsData();
+ suggestions_service()->FetchSuggestionsData();
- // Let any network request run.
+ // Wait for eventual (but unexpected) network requests.
base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
- // Ensure that CheckCallback() didn't run.
- EXPECT_EQ(0, suggestions_data_callback_count_);
-
- // |test_suggestions_store_| should still contain the default values.
+ // |suggestions_store()| should still contain the default values.
SuggestionsProfile suggestions;
- test_suggestions_store_->LoadSuggestions(&suggestions);
- EXPECT_EQ(CreateSuggestionsProfile().SerializeAsString(),
- suggestions.SerializeAsString());
+ suggestions_store()->LoadSuggestions(&suggestions);
+ EXPECT_THAT(suggestions, EqualsProto(CreateSuggestionsProfile()));
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncDisabled) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
- EXPECT_CALL(*mock_sync_service_, CanSyncStart())
- .WillRepeatedly(Return(false));
+ EXPECT_CALL(*sync_service(), CanSyncStart()).WillRepeatedly(Return(false));
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
// Tell SuggestionsService that the sync state changed. The cache should be
// cleared and empty data returned to the callback.
- suggestions_service->OnStateChanged(mock_sync_service_.get());
-
- // Ensure that CheckCallback ran once with empty data.
- EXPECT_EQ(1, suggestions_data_callback_count_);
- EXPECT_EQ(1, suggestions_empty_data_count_);
+ EXPECT_CALL(callback, Run(EqualsProto(SuggestionsProfile())));
+ static_cast<SyncServiceObserver*>(suggestions_service())
+ ->OnStateChanged(sync_service());
// Try to fetch suggestions. Since sync is not active, no network request
// should be sent.
- suggestions_service->FetchSuggestionsData();
+ suggestions_service()->FetchSuggestionsData();
- // Let any network request run.
+ // Wait for eventual (but unexpected) network requests.
base::RunLoop().RunUntilIdle();
-
- // Ensure that CheckCallback didn't run again.
- EXPECT_EQ(1, suggestions_data_callback_count_);
+ EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoAccessToken) {
- token_service_.set_auto_post_fetch_response_on_message_loop(false);
+ token_service()->set_auto_post_fetch_response_on_message_loop(false);
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ EXPECT_CALL(callback, Run(_)).Times(0);
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
-
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(Return(false));
- suggestions_service->FetchSuggestionsData();
+ suggestions_service()->FetchSuggestionsData();
- token_service_.IssueErrorForAllPendingRequests(GoogleServiceAuthError(
+ token_service()->IssueErrorForAllPendingRequests(GoogleServiceAuthError(
GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
- // No network request should be sent.
+ // Wait for eventual (but unexpected) network requests.
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(HasPendingSuggestionsRequest(suggestions_service.get()));
- EXPECT_EQ(0, suggestions_data_callback_count_);
+ EXPECT_FALSE(suggestions_service()->has_pending_request_for_testing());
}
-TEST_F(SuggestionsServiceTest, IssueRequestIfNoneOngoingError) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
-
- // Fake a request error.
- factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(),
- "irrelevant", net::HTTP_OK,
- net::URLRequestStatus::FAILED);
-
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
+TEST_F(SuggestionsServiceTest, FetchingSuggestionsIgnoresRequestFailure) {
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(Return(false));
- // Send the request. Empty data will be returned to the callback.
- suggestions_service->IssueRequestIfNoneOngoing(
- SuggestionsServiceImpl::BuildSuggestionsURL());
+ suggestions_service()->FetchSuggestionsData();
- // (Testing only) wait until suggestion fetch is complete.
+ // Wait for the eventual network request.
base::RunLoop().RunUntilIdle();
+ RespondToFetch("irrelevant", net::HTTP_OK,
+ net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_INVALID_RESPONSE));
}
-TEST_F(SuggestionsServiceTest, IssueRequestIfNoneOngoingResponseNotOK) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
-
- // Fake a non-200 response code.
- factory_.SetFakeResponse(SuggestionsServiceImpl::BuildSuggestionsURL(),
- "irrelevant", net::HTTP_BAD_REQUEST,
- net::URLRequestStatus::SUCCESS);
+TEST_F(SuggestionsServiceTest, FetchingSuggestionsClearsStoreIfResponseNotOK) {
+ suggestions_store()->StoreSuggestions(CreateSuggestionsProfile());
// Expect that an upload to the blacklist is scheduled.
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(Return(false));
// Send the request. Empty data will be returned to the callback.
- suggestions_service->IssueRequestIfNoneOngoing(
- SuggestionsServiceImpl::BuildSuggestionsURL());
+ suggestions_service()->FetchSuggestionsData();
- // (Testing only) wait until suggestion fetch is complete.
+ // Wait for the eventual network request.
base::RunLoop().RunUntilIdle();
+ RespondToFetch(
+ "irrelevant", net::HTTP_BAD_REQUEST,
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
- // Expect no suggestions in the cache.
SuggestionsProfile empty_suggestions;
- EXPECT_FALSE(test_suggestions_store_->LoadSuggestions(&empty_suggestions));
+ EXPECT_FALSE(suggestions_store()->LoadSuggestions(&empty_suggestions));
}
TEST_F(SuggestionsServiceTest, BlacklistURL) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- EXPECT_TRUE(suggestions_service != nullptr);
- base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0);
- suggestions_service->set_blacklist_delay(no_delay);
-
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
-
- GURL blacklisted_url(kBlacklistedUrl);
- GURL request_url(
- SuggestionsServiceImpl::BuildSuggestionsBlacklistURL(blacklisted_url));
- SuggestionsProfile suggestions_profile = CreateSuggestionsProfile();
- factory_.SetFakeResponse(request_url, suggestions_profile.SerializeAsString(),
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
- EXPECT_CALL(*mock_thumbnail_manager_, Initialize(_)).Times(2);
-
- // Expected calls to the blacklist store.
- EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
+ // Calling RunUntilIdle on the RunLoop only works when the task is not posted
+ // for the future.
+ const base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0);
+ suggestions_service()->set_blacklist_delay_for_testing(no_delay);
+
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
+
+ EXPECT_CALL(*thumbnail_manager(), Initialize(_)).Times(2);
+ EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(true));
- EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(2);
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(2);
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true)))
.WillOnce(Return(false));
- EXPECT_CALL(*mock_blacklist_store_, GetCandidateForUpload(_))
- .WillOnce(DoAll(SetArgPointee<0>(blacklisted_url), Return(true)));
- EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklisted_url)))
+ EXPECT_CALL(*blacklist_store(), GetCandidateForUpload(_))
+ .WillOnce(DoAll(SetArgPointee<0>(GURL(kBlacklistedUrl)), Return(true)));
+ EXPECT_CALL(*blacklist_store(), RemoveUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(true));
- Blacklist(suggestions_service.get(), blacklisted_url);
- EXPECT_EQ(1, suggestions_data_callback_count_);
+ EXPECT_CALL(callback, Run(_)).Times(2);
+
+ EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
// Wait on the upload task, the blacklist request and the next blacklist
// scheduling task. This only works when the scheduling task is not for future
@@ -525,242 +477,273 @@ TEST_F(SuggestionsServiceTest, BlacklistURL) {
// BlacklistStore's candidacy delay are zero).
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2, suggestions_data_callback_count_);
- EXPECT_FALSE(blacklisting_failed_);
- CheckSuggestionsData();
+ EXPECT_EQ(GetCurrentlyQueriedUrl().path(), kBlacklistUrlPath);
+ RespondToFetchWithProfile(CreateSuggestionsProfile());
+
+ SuggestionsProfile suggestions;
+ suggestions_store()->LoadSuggestions(&suggestions);
+ ASSERT_EQ(1, suggestions.suggestions_size());
+ EXPECT_EQ(kTestTitle, suggestions.suggestions(0).title());
+ EXPECT_EQ(kTestUrl, suggestions.suggestions(0).url());
+ EXPECT_EQ(kTestFaviconUrl, suggestions.suggestions(0).favicon_url());
}
TEST_F(SuggestionsServiceTest, BlacklistURLFails) {
- std::unique_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ EXPECT_CALL(callback, Run(_)).Times(0);
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
-
- GURL blacklisted_url(kBlacklistedUrl);
- EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
+ EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(false));
- Blacklist(suggestions_service.get(), blacklisted_url);
-
- EXPECT_TRUE(blacklisting_failed_);
- EXPECT_EQ(0, suggestions_data_callback_count_);
+ EXPECT_FALSE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
}
-// Initial blacklist request fails, triggering a second which succeeds.
-TEST_F(SuggestionsServiceTest, BlacklistURLRequestFails) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
- base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0);
- suggestions_service->set_blacklist_delay(no_delay);
-
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
-
- GURL blacklisted_url(kBlacklistedUrl);
- GURL request_url(
- SuggestionsServiceImpl::BuildSuggestionsBlacklistURL(blacklisted_url));
- GURL blacklisted_url_alt(kBlacklistedUrlAlt);
- GURL request_url_alt(SuggestionsServiceImpl::BuildSuggestionsBlacklistURL(
- blacklisted_url_alt));
- SuggestionsProfile suggestions_profile = CreateSuggestionsProfile();
-
- // Note: we want to set the response for the blacklist URL to first
- // succeed, then fail. This doesn't seem possible. For simplicity of testing,
- // we'll pretend the URL changed in the BlacklistStore between the first and
- // the second request, and adjust expectations accordingly.
- factory_.SetFakeResponse(request_url, "irrelevant", net::HTTP_OK,
- net::URLRequestStatus::FAILED);
- factory_.SetFakeResponse(request_url_alt,
- suggestions_profile.SerializeAsString(),
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
-
- // Expectations.
- EXPECT_CALL(*mock_thumbnail_manager_, Initialize(_)).Times(2);
- EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
+TEST_F(SuggestionsServiceTest, RetryBlacklistURLRequestAfterFailure) {
+ // Calling RunUntilIdle on the RunLoop only works when the task is not
+ // posted for the future.
+ const base::TimeDelta no_delay = base::TimeDelta::FromSeconds(0);
+ suggestions_service()->set_blacklist_delay_for_testing(no_delay);
+
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
+
+ // Set expectations for first, failing request.
+ EXPECT_CALL(*thumbnail_manager(), Initialize(_));
+ EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(true));
- EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(2);
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
- .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true)))
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true)))
+ .WillOnce(DoAll(SetArgPointee<0>(no_delay), Return(true)));
+ EXPECT_CALL(*blacklist_store(), GetCandidateForUpload(_))
+ .WillOnce(DoAll(SetArgPointee<0>(GURL(kBlacklistedUrl)), Return(true)));
+
+ EXPECT_CALL(callback, Run(_)).Times(2);
+
+ // Blacklist call, first request attempt.
+ EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
+
+ // Wait for the first scheduling receiving a failing response.
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(GetCurrentlyQueriedUrl().is_valid());
+ EXPECT_EQ(GetCurrentlyQueriedUrl().path(), kBlacklistUrlPath);
+ RespondToFetch("irrelevant", net::HTTP_OK,
+ net::URLRequestStatus(net::URLRequestStatus::FAILED,
+ net::ERR_INVALID_RESPONSE));
+
+ // Assert that the failure was processed as expected.
+ Mock::VerifyAndClearExpectations(thumbnail_manager());
+ Mock::VerifyAndClearExpectations(blacklist_store());
+
+ // Now expect the retried request to succeed.
+ EXPECT_CALL(*thumbnail_manager(), Initialize(_));
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(Return(false));
- EXPECT_CALL(*mock_blacklist_store_, GetCandidateForUpload(_))
- .WillOnce(DoAll(SetArgPointee<0>(blacklisted_url), Return(true)))
- .WillOnce(DoAll(SetArgPointee<0>(blacklisted_url_alt), Return(true)));
- EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklisted_url_alt)))
+ EXPECT_CALL(*blacklist_store(), GetCandidateForUpload(_))
+ .WillOnce(DoAll(SetArgPointee<0>(GURL(kBlacklistedUrl)), Return(true)));
+ EXPECT_CALL(*blacklist_store(), RemoveUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(true));
- // Blacklist call, first request attempt.
- Blacklist(suggestions_service.get(), blacklisted_url);
- EXPECT_EQ(1, suggestions_data_callback_count_);
- EXPECT_FALSE(blacklisting_failed_);
-
- // Wait for the first scheduling, the first request, the second scheduling,
- // second request and the third scheduling. Again, note that calling
- // RunUntilIdle on the MessageLoop only works when the task is not posted for
- // the future.
+ // Wait for the second scheduling followed by a successful response.
base::RunLoop().RunUntilIdle();
- CheckSuggestionsData();
+ ASSERT_TRUE(GetCurrentlyQueriedUrl().is_valid());
+ EXPECT_EQ(GetCurrentlyQueriedUrl().path(), kBlacklistUrlPath);
+ RespondToFetchWithProfile(CreateSuggestionsProfile());
+
+ SuggestionsProfile suggestions;
+ suggestions_store()->LoadSuggestions(&suggestions);
+ ASSERT_EQ(1, suggestions.suggestions_size());
+ EXPECT_EQ(kTestTitle, suggestions.suggestions(0).title());
+ EXPECT_EQ(kTestUrl, suggestions.suggestions(0).url());
+ EXPECT_EQ(kTestFaviconUrl, suggestions.suggestions(0).favicon_url());
}
TEST_F(SuggestionsServiceTest, UndoBlacklistURL) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
// Ensure scheduling the request doesn't happen before undo.
- base::TimeDelta delay = base::TimeDelta::FromHours(1);
- suggestions_service->set_blacklist_delay(delay);
-
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
+ const base::TimeDelta delay = base::TimeDelta::FromHours(1);
+ suggestions_service()->set_blacklist_delay_for_testing(delay);
- SuggestionsProfile suggestions_profile = CreateSuggestionsProfile();
- GURL blacklisted_url(kBlacklistedUrl);
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
// Blacklist expectations.
- EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
+ EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(true));
- EXPECT_CALL(*mock_thumbnail_manager_,
- Initialize(EqualsProto(suggestions_profile)))
+ EXPECT_CALL(*thumbnail_manager(),
+ Initialize(EqualsProto(CreateSuggestionsProfile())))
.Times(AnyNumber());
- EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(AnyNumber());
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(AnyNumber());
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
// Undo expectations.
- EXPECT_CALL(*mock_blacklist_store_,
- GetTimeUntilURLReadyForUpload(Eq(blacklisted_url), _))
+ EXPECT_CALL(*blacklist_store(),
+ GetTimeUntilURLReadyForUpload(Eq(GURL(kBlacklistedUrl)), _))
.WillOnce(DoAll(SetArgPointee<1>(delay), Return(true)));
- EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklisted_url)))
+ EXPECT_CALL(*blacklist_store(), RemoveUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(true));
- Blacklist(suggestions_service.get(), blacklisted_url);
- UndoBlacklist(suggestions_service.get(), blacklisted_url);
-
- EXPECT_EQ(2, suggestions_data_callback_count_);
- EXPECT_FALSE(blacklisting_failed_);
- EXPECT_FALSE(undo_blacklisting_failed_);
+ EXPECT_CALL(callback, Run(_)).Times(2);
+ EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
+ EXPECT_TRUE(suggestions_service()->UndoBlacklistURL(GURL(kBlacklistedUrl)));
}
TEST_F(SuggestionsServiceTest, ClearBlacklist) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
- // Ensure scheduling the request doesn't happen before undo.
- base::TimeDelta delay = base::TimeDelta::FromHours(1);
- suggestions_service->set_blacklist_delay(delay);
+ const base::TimeDelta delay = base::TimeDelta::FromHours(1);
+ suggestions_service()->set_blacklist_delay_for_testing(delay);
- auto subscription = suggestions_service->AddCallback(base::Bind(
- &SuggestionsServiceTest::CheckCallback, base::Unretained(this)));
-
- SuggestionsProfile suggestions_profile = CreateSuggestionsProfile();
- GURL blacklisted_url(kBlacklistedUrl);
-
- factory_.SetFakeResponse(
- SuggestionsServiceImpl::BuildSuggestionsBlacklistClearURL(),
- suggestions_profile.SerializeAsString(), net::HTTP_OK,
- net::URLRequestStatus::SUCCESS);
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
// Blacklist expectations.
- EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklisted_url)))
+ EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
.WillOnce(Return(true));
- EXPECT_CALL(*mock_thumbnail_manager_,
- Initialize(EqualsProto(suggestions_profile)))
+ EXPECT_CALL(*thumbnail_manager(),
+ Initialize(EqualsProto(CreateSuggestionsProfile())))
.Times(AnyNumber());
- EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(AnyNumber());
- EXPECT_CALL(*mock_blacklist_store_, GetTimeUntilReadyForUpload(_))
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(AnyNumber());
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
.WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
- EXPECT_CALL(*mock_blacklist_store_, ClearBlacklist());
+ EXPECT_CALL(*blacklist_store(), ClearBlacklist());
- Blacklist(suggestions_service.get(), blacklisted_url);
- suggestions_service->ClearBlacklist();
+ EXPECT_CALL(callback, Run(_)).Times(2);
+ EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
+ suggestions_service()->ClearBlacklist();
- EXPECT_EQ(2, suggestions_data_callback_count_);
- EXPECT_FALSE(blacklisting_failed_);
+ // Wait for the eventual network request.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(GetCurrentlyQueriedUrl().path(), kBlacklistClearUrlPath);
}
TEST_F(SuggestionsServiceTest, UndoBlacklistURLFailsIfNotInBlacklist) {
- UndoBlacklistURLFailsHelper(true);
+ // Ensure scheduling the request doesn't happen before undo.
+ const base::TimeDelta delay = base::TimeDelta::FromHours(1);
+ suggestions_service()->set_blacklist_delay_for_testing(delay);
+
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
+
+ // Blacklist expectations.
+ EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*thumbnail_manager(),
+ Initialize(EqualsProto(CreateSuggestionsProfile())));
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
+ .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
+ // Undo expectations.
+ // URL is not in local blacklist.
+ EXPECT_CALL(*blacklist_store(),
+ GetTimeUntilURLReadyForUpload(Eq(GURL(kBlacklistedUrl)), _))
+ .WillOnce(Return(false));
+
+ EXPECT_CALL(callback, Run(_));
+
+ EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
+ EXPECT_FALSE(suggestions_service()->UndoBlacklistURL(GURL(kBlacklistedUrl)));
}
TEST_F(SuggestionsServiceTest, UndoBlacklistURLFailsIfAlreadyCandidate) {
- UndoBlacklistURLFailsHelper(false);
-}
+ // Ensure scheduling the request doesn't happen before undo.
+ const base::TimeDelta delay = base::TimeDelta::FromHours(1);
+ suggestions_service()->set_blacklist_delay_for_testing(delay);
+
+ base::MockCallback<SuggestionsService::ResponseCallback> callback;
+ auto subscription = suggestions_service()->AddCallback(callback.Get());
+
+ // Blacklist expectations.
+ EXPECT_CALL(*blacklist_store(), BlacklistUrl(Eq(GURL(kBlacklistedUrl))))
+ .WillOnce(Return(true));
+ EXPECT_CALL(*thumbnail_manager(),
+ Initialize(EqualsProto(CreateSuggestionsProfile())));
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
+ .WillOnce(DoAll(SetArgPointee<0>(delay), Return(true)));
+
+ // URL is not yet candidate for upload.
+ const base::TimeDelta negative_delay = base::TimeDelta::FromHours(-1);
+ EXPECT_CALL(*blacklist_store(),
+ GetTimeUntilURLReadyForUpload(Eq(GURL(kBlacklistedUrl)), _))
+ .WillOnce(DoAll(SetArgPointee<1>(negative_delay), Return(true)));
-TEST_F(SuggestionsServiceTest, GetBlacklistedUrl) {
- std::unique_ptr<GURL> request_url;
- std::unique_ptr<net::FakeURLFetcher> fetcher;
- GURL retrieved_url;
-
- // Not a blacklist request.
- request_url.reset(new GURL("http://not-blacklisting.com/a?b=c"));
- fetcher = CreateURLFetcher(*request_url, nullptr, "", net::HTTP_OK,
- net::URLRequestStatus::SUCCESS);
- EXPECT_FALSE(
- SuggestionsServiceImpl::GetBlacklistedUrl(*fetcher, &retrieved_url));
-
- // An actual blacklist request.
- std::string blacklisted_url = "http://blacklisted.com/a?b=c&d=e";
- std::string encoded_blacklisted_url =
- "http%3A%2F%2Fblacklisted.com%2Fa%3Fb%3Dc%26d%3De";
- std::string blacklist_request_prefix(
- SuggestionsServiceImpl::BuildSuggestionsBlacklistURLPrefix());
- request_url.reset(
- new GURL(blacklist_request_prefix + encoded_blacklisted_url));
- fetcher.reset();
- fetcher = CreateURLFetcher(*request_url, nullptr, "", net::HTTP_OK,
- net::URLRequestStatus::SUCCESS);
- EXPECT_TRUE(
- SuggestionsServiceImpl::GetBlacklistedUrl(*fetcher, &retrieved_url));
- EXPECT_EQ(blacklisted_url, retrieved_url.spec());
+ EXPECT_CALL(callback, Run(_));
+
+ EXPECT_TRUE(suggestions_service()->BlacklistURL(GURL(kBlacklistedUrl)));
+ EXPECT_FALSE(suggestions_service()->UndoBlacklistURL(GURL(kBlacklistedUrl)));
}
-TEST_F(SuggestionsServiceTest, UpdateBlacklistDelay) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- base::TimeDelta initial_delay = suggestions_service->blacklist_delay();
+TEST_F(SuggestionsServiceTest, TemporarilyIncreasesBlacklistDelayOnFailure) {
+ EXPECT_CALL(*thumbnail_manager(), Initialize(_)).Times(AnyNumber());
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_)).Times(AnyNumber());
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(false));
+ const base::TimeDelta initial_delay =
+ suggestions_service()->blacklist_delay_for_testing();
// Delay unchanged on success.
- suggestions_service->UpdateBlacklistDelay(true);
- EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay());
+ suggestions_service()->FetchSuggestionsData();
+ base::RunLoop().RunUntilIdle();
+ RespondToFetchWithProfile(CreateSuggestionsProfile());
+ EXPECT_EQ(initial_delay,
+ suggestions_service()->blacklist_delay_for_testing());
// Delay increases on failure.
- suggestions_service->UpdateBlacklistDelay(false);
- EXPECT_GT(suggestions_service->blacklist_delay(), initial_delay);
+ suggestions_service()->FetchSuggestionsData();
+ base::RunLoop().RunUntilIdle();
+ RespondToFetch(
+ "irrelevant", net::HTTP_BAD_REQUEST,
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK));
+ EXPECT_GT(suggestions_service()->blacklist_delay_for_testing(),
+ initial_delay);
// Delay resets on success.
- suggestions_service->UpdateBlacklistDelay(true);
- EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay());
+ suggestions_service()->FetchSuggestionsData();
+ base::RunLoop().RunUntilIdle();
+ RespondToFetchWithProfile(CreateSuggestionsProfile());
+ EXPECT_EQ(initial_delay,
+ suggestions_service()->blacklist_delay_for_testing());
}
-TEST_F(SuggestionsServiceTest, CheckDefaultTimeStamps) {
- std::unique_ptr<SuggestionsServiceImpl> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- SuggestionsProfile suggestions =
- CreateSuggestionsProfileWithExpiryTimestamps();
- suggestions_service->SetDefaultExpiryTimestamp(&suggestions,
- kTestDefaultExpiry);
- EXPECT_EQ(kTestSetExpiry, suggestions.suggestions(0).expiry_ts());
- EXPECT_EQ(kTestDefaultExpiry, suggestions.suggestions(1).expiry_ts());
+TEST_F(SuggestionsServiceTest, DoesNotOverrideDefaultExpiryTime) {
+ EXPECT_CALL(*thumbnail_manager(), Initialize(_));
+ EXPECT_CALL(*blacklist_store(), FilterSuggestions(_));
+ EXPECT_CALL(*blacklist_store(), GetTimeUntilReadyForUpload(_))
+ .WillOnce(Return(false));
+
+ suggestions_service()->FetchSuggestionsData();
+
+ base::RunLoop().RunUntilIdle();
+ // Creates one suggestion without timestamp and adds a second with timestamp.
+ SuggestionsProfile profile = CreateSuggestionsProfile();
+ ChromeSuggestion* suggestion = profile.add_suggestions();
+ suggestion->set_title(kTestTitle);
+ suggestion->set_url(kTestUrl);
+ suggestion->set_expiry_ts(kTestSetExpiry);
+ RespondToFetchWithProfile(profile);
+
+ SuggestionsProfile suggestions;
+ suggestions_store()->LoadSuggestions(&suggestions);
+ ASSERT_EQ(2, suggestions.suggestions_size());
+ // Suggestion[0] had no time stamp and should be ahead of the old suggestion.
+ EXPECT_LT(kTestSetExpiry, suggestions.suggestions(0).expiry_ts());
+ // Suggestion[1] had a very old time stamp but should not be updated.
+ EXPECT_EQ(kTestSetExpiry, suggestions.suggestions(1).expiry_ts());
}
TEST_F(SuggestionsServiceTest, GetPageThumbnail) {
- std::unique_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMocks());
- ASSERT_TRUE(suggestions_service != nullptr);
-
- GURL test_url(kTestUrl);
- GURL thumbnail_url("https://www.thumbnails.com/thumb.jpg");
+ const GURL test_url(kTestUrl);
+ const GURL thumbnail_url("https://www.thumbnails.com/thumb.jpg");
base::Callback<void(const GURL&, const gfx::Image&)> dummy_callback;
- EXPECT_CALL(*mock_thumbnail_manager_, GetImageForURL(test_url, _));
- suggestions_service->GetPageThumbnail(test_url, dummy_callback);
+ EXPECT_CALL(*thumbnail_manager(), GetImageForURL(test_url, _));
+ suggestions_service()->GetPageThumbnail(test_url, dummy_callback);
- EXPECT_CALL(*mock_thumbnail_manager_, AddImageURL(test_url, thumbnail_url));
- EXPECT_CALL(*mock_thumbnail_manager_, GetImageForURL(test_url, _));
- suggestions_service->GetPageThumbnailWithURL(test_url, thumbnail_url,
- dummy_callback);
+ EXPECT_CALL(*thumbnail_manager(), AddImageURL(test_url, thumbnail_url));
+ EXPECT_CALL(*thumbnail_manager(), GetImageForURL(test_url, _));
+ suggestions_service()->GetPageThumbnailWithURL(test_url, thumbnail_url,
+ dummy_callback);
}
} // namespace suggestions
diff --git a/chromium/components/sync/BUILD.gn b/chromium/components/sync/BUILD.gn
index a941fa2220d..8fa00f334f7 100644
--- a/chromium/components/sync/BUILD.gn
+++ b/chromium/components/sync/BUILD.gn
@@ -461,6 +461,7 @@ static_library("sync") {
"model/sync_error_factory.h",
"model/sync_merge_result.cc",
"model/sync_merge_result.h",
+ "model/sync_metadata_store.h",
"model/syncable_service.cc",
"model/syncable_service.h",
"model/time.h",
@@ -481,6 +482,8 @@ static_library("sync") {
"model_impl/processor_entity_tracker.h",
"model_impl/shared_model_type_processor.cc",
"model_impl/shared_model_type_processor.h",
+ "model_impl/sync_metadata_store_change_list.cc",
+ "model_impl/sync_metadata_store_change_list.h",
"protocol/proto_enum_conversions.cc",
"protocol/proto_enum_conversions.h",
"protocol/proto_memory_estimations.cc",
@@ -569,19 +572,26 @@ static_library("sync") {
"syncable/write_transaction.h",
"syncable/write_transaction_info.cc",
"syncable/write_transaction_info.h",
+ "user_events/user_event_service.cc",
+ "user_events/user_event_service.h",
+ "user_events/user_event_sync_bridge.cc",
+ "user_events/user_event_sync_bridge.h",
]
configs += [ "//build/config:precompiled_headers" ]
public_deps = [
+ "//base",
"//components/sync/protocol",
+ "//net",
+ "//url",
]
deps = [
- "//base",
"//base:i18n",
"//base/third_party/dynamic_annotations",
"//components/data_use_measurement/core",
"//components/invalidation/public",
+ "//components/keyed_service/core",
"//components/metrics",
"//components/os_crypt",
"//components/pref_registry",
@@ -592,13 +602,11 @@ static_library("sync") {
"//components/version_info",
"//crypto",
"//google_apis",
- "//net",
"//sql",
"//third_party/cacheinvalidation",
"//third_party/leveldatabase",
"//third_party/zlib",
- "//third_party/zlib:compression_utils",
- "//url",
+ "//third_party/zlib/google:compression_utils",
]
if (is_android) {
@@ -937,6 +945,8 @@ source_set("unit_tests") {
"syncable/syncable_enum_conversions_unittest.cc",
"syncable/syncable_id_unittest.cc",
"syncable/syncable_unittest.cc",
+ "user_events/user_event_service_unittest.cc",
+ "user_events/user_event_sync_bridge_unittest.cc",
]
configs += [ "//build/config:precompiled_headers" ]
@@ -976,7 +986,7 @@ source_set("unit_tests") {
"//testing/gtest",
"//third_party/leveldatabase",
"//third_party/protobuf:protobuf_lite",
- "//third_party/zlib:compression_utils",
+ "//third_party/zlib/google:compression_utils",
"//url",
]
@@ -1080,7 +1090,7 @@ if (!is_ios) {
":test_support_testserver",
"//base",
"//base/test:test_support",
- "//build/config/sanitizers:deps",
+ "//build/config:exe_and_shlib_deps",
"//build/win:default_exe_manifest",
"//net:test_support",
"//testing/gtest",
diff --git a/chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc b/chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
index d3ae78a6616..340785c50e8 100644
--- a/chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
+++ b/chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
@@ -39,7 +39,7 @@ using testing::_;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Return;
-using testing::SetArgumentPointee;
+using testing::SetArgPointee;
namespace {
@@ -106,8 +106,8 @@ class SyncBookmarkDataTypeControllerTest : public testing::Test,
void SetAssociateExpectations() {
EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
WillRepeatedly(Return(true));
- EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
- WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
+ EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
WillRepeatedly(Return(syncer::SyncError()));
}
@@ -205,8 +205,8 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartFirstRun) {
CreateBookmarkModel(LOAD_MODEL);
SetStartExpectations();
SetAssociateExpectations();
- EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
- WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(true)));
+ EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(false), Return(true)));
EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _));
Start();
}
@@ -229,8 +229,8 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartOk) {
CreateBookmarkModel(LOAD_MODEL);
SetStartExpectations();
SetAssociateExpectations();
- EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
- WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
+ EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
Start();
@@ -242,8 +242,8 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartAssociationFailed) {
// Set up association to fail.
EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
WillRepeatedly(Return(true));
- EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
- WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
+ EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
WillRepeatedly(Return(syncer::SyncError(FROM_HERE,
syncer::SyncError::DATATYPE_ERROR,
@@ -263,8 +263,8 @@ TEST_F(SyncBookmarkDataTypeControllerTest,
// Set up association to fail with an unrecoverable error.
EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
WillRepeatedly(Return(true));
- EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)).
- WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false)));
+ EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(false), Return(false)));
EXPECT_CALL(start_callback_,
Run(DataTypeController::UNRECOVERABLE_ERROR, _, _));
Start();
diff --git a/chromium/components/sync_bookmarks/bookmark_model_associator.cc b/chromium/components/sync_bookmarks/bookmark_model_associator.cc
index 8376ee04c2c..c710dbc1b78 100644
--- a/chromium/components/sync_bookmarks/bookmark_model_associator.cc
+++ b/chromium/components/sync_bookmarks/bookmark_model_associator.cc
@@ -777,22 +777,6 @@ const BookmarkNode* BookmarkModelAssociator::CreateBookmarkNode(
return child_node;
}
-int BookmarkModelAssociator::RemoveSyncNodeHierarchy(
- syncer::WriteTransaction* trans,
- int64_t sync_id) {
- syncer::WriteNode sync_node(trans);
- if (sync_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) {
- syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR,
- "Could not lookup bookmark node for ID deletion.",
- syncer::BOOKMARKS);
- unrecoverable_error_handler_->OnUnrecoverableError(error);
- return 0;
- }
-
- return BookmarkChangeProcessor::RemoveSyncNodeHierarchy(trans, &sync_node,
- this);
-}
-
struct FolderInfo {
FolderInfo(const BookmarkNode* f, const BookmarkNode* p, int64_t id)
: folder(f), parent(p), sync_id(id) {}
diff --git a/chromium/components/sync_bookmarks/bookmark_model_associator.h b/chromium/components/sync_bookmarks/bookmark_model_associator.h
index 63561edcf5c..4bcbfc12655 100644
--- a/chromium/components/sync_bookmarks/bookmark_model_associator.h
+++ b/chromium/components/sync_bookmarks/bookmark_model_associator.h
@@ -47,9 +47,7 @@ namespace sync_bookmarks {
// * Algorithm to associate bookmark model and sync model.
// * Methods to get a bookmark node for a given sync node and vice versa.
// * Persisting model associations and loading them back.
-class BookmarkModelAssociator
- : public syncer::PerDataTypeAssociatorInterface<bookmarks::BookmarkNode,
- int64_t> {
+class BookmarkModelAssociator : public syncer::AssociatorInterface {
public:
static syncer::ModelType model_type() { return syncer::BOOKMARKS; }
// |expect_mobile_bookmarks_folder| controls whether or not we
@@ -85,24 +83,23 @@ class BookmarkModelAssociator
// Returns sync id for the given bookmark node id.
// Returns syncer::kInvalidId if the sync node is not found for the given
// bookmark node id.
- int64_t GetSyncIdFromChromeId(const int64_t& node_id) override;
+ int64_t GetSyncIdFromChromeId(const int64_t& node_id);
// Returns the bookmark node for the given sync id.
// Returns null if no bookmark node is found for the given sync id.
- const bookmarks::BookmarkNode* GetChromeNodeFromSyncId(
- int64_t sync_id) override;
+ const bookmarks::BookmarkNode* GetChromeNodeFromSyncId(int64_t sync_id);
// Initializes the given sync node from the given bookmark node id.
// Returns false if no sync node was found for the given bookmark node id or
// if the initialization of sync node fails.
bool InitSyncNodeFromChromeId(const int64_t& node_id,
- syncer::BaseNode* sync_node) override;
+ syncer::BaseNode* sync_node);
// Associates the given bookmark node with the given sync node.
void Associate(const bookmarks::BookmarkNode* node,
- const syncer::BaseNode& sync_node) override;
+ const syncer::BaseNode& sync_node);
// Remove the association that corresponds to the given sync id.
- void Disassociate(int64_t sync_id) override;
+ void Disassociate(int64_t sync_id);
void AbortAssociation() override {
// No implementation needed, this associator runs on the main
@@ -278,10 +275,6 @@ class BookmarkModelAssociator
Context* context,
syncer::SyncError* error);
- // Helper method for deleting a sync node and all its children.
- // Returns the number of sync nodes deleted.
- int RemoveSyncNodeHierarchy(syncer::WriteTransaction* trans, int64_t sync_id);
-
// Check whether bookmark model and sync model are synced by comparing
// their transaction versions.
// Returns a PERSISTENCE_ERROR if a transaction mismatch was detected where
diff --git a/chromium/components/sync_preferences/pref_model_associator.cc b/chromium/components/sync_preferences/pref_model_associator.cc
index 6bb1801dc52..49bd331ffe6 100644
--- a/chromium/components/sync_preferences/pref_model_associator.cc
+++ b/chromium/components/sync_preferences/pref_model_associator.cc
@@ -4,6 +4,8 @@
#include "components/sync_preferences/pref_model_associator.h"
+#include <algorithm>
+#include <iterator>
#include <utility>
#include "base/auto_reset.h"
@@ -238,9 +240,9 @@ std::unique_ptr<base::Value> PrefModelAssociator::MergePreference(
if (client_) {
std::string new_pref_name;
if (client_->IsMergeableListPreference(name))
- return base::WrapUnique(MergeListValues(local_value, server_value));
+ return MergeListValues(local_value, server_value);
if (client_->IsMergeableDictionaryPreference(name))
- return base::WrapUnique(MergeDictionaryValues(local_value, server_value));
+ return MergeDictionaryValues(local_value, server_value);
}
// If this is not a specially handled preference, server wins.
@@ -275,12 +277,13 @@ bool PrefModelAssociator::CreatePrefSyncData(
return true;
}
-base::Value* PrefModelAssociator::MergeListValues(const base::Value& from_value,
- const base::Value& to_value) {
+std::unique_ptr<base::Value> PrefModelAssociator::MergeListValues(
+ const base::Value& from_value,
+ const base::Value& to_value) {
if (from_value.GetType() == base::Value::Type::NONE)
- return to_value.DeepCopy();
+ return base::MakeUnique<base::Value>(to_value);
if (to_value.GetType() == base::Value::Type::NONE)
- return from_value.DeepCopy();
+ return base::MakeUnique<base::Value>(from_value);
DCHECK(from_value.GetType() == base::Value::Type::LIST);
DCHECK(to_value.GetType() == base::Value::Type::LIST);
@@ -288,21 +291,24 @@ base::Value* PrefModelAssociator::MergeListValues(const base::Value& from_value,
static_cast<const base::ListValue&>(from_value);
const base::ListValue& to_list_value =
static_cast<const base::ListValue&>(to_value);
- base::ListValue* result = to_list_value.DeepCopy();
- for (const auto& value : from_list_value) {
- result->AppendIfNotPresent(value.CreateDeepCopy());
- }
- return result;
+ auto result = base::MakeUnique<base::ListValue>(to_list_value);
+ base::Value::ListStorage& list = result->GetList();
+ std::copy_if(
+ from_list_value.GetList().begin(), from_list_value.GetList().end(),
+ std::back_inserter(list), [&list](const base::Value& value) {
+ return std::find(list.begin(), list.end(), value) == list.end();
+ });
+ return std::move(result);
}
-base::Value* PrefModelAssociator::MergeDictionaryValues(
+std::unique_ptr<base::Value> PrefModelAssociator::MergeDictionaryValues(
const base::Value& from_value,
const base::Value& to_value) {
if (from_value.GetType() == base::Value::Type::NONE)
- return to_value.DeepCopy();
+ return base::MakeUnique<base::Value>(to_value);
if (to_value.GetType() == base::Value::Type::NONE)
- return from_value.DeepCopy();
+ return base::MakeUnique<base::Value>(from_value);
DCHECK_EQ(from_value.GetType(), base::Value::Type::DICTIONARY);
DCHECK_EQ(to_value.GetType(), base::Value::Type::DICTIONARY);
@@ -310,7 +316,7 @@ base::Value* PrefModelAssociator::MergeDictionaryValues(
static_cast<const base::DictionaryValue&>(from_value);
const base::DictionaryValue& to_dict_value =
static_cast<const base::DictionaryValue&>(to_value);
- base::DictionaryValue* result = to_dict_value.DeepCopy();
+ auto result = base::MakeUnique<base::DictionaryValue>(to_dict_value);
for (base::DictionaryValue::Iterator it(from_dict_value); !it.IsAtEnd();
it.Advance()) {
@@ -319,17 +325,18 @@ base::Value* PrefModelAssociator::MergeDictionaryValues(
if (result->GetWithoutPathExpansion(it.key(), &to_key_value)) {
if (from_key_value->GetType() == base::Value::Type::DICTIONARY &&
to_key_value->GetType() == base::Value::Type::DICTIONARY) {
- base::Value* merged_value =
+ std::unique_ptr<base::Value> merged_value =
MergeDictionaryValues(*from_key_value, *to_key_value);
- result->SetWithoutPathExpansion(it.key(), merged_value);
+ result->SetWithoutPathExpansion(it.key(), std::move(merged_value));
}
// Note that for all other types we want to preserve the "to"
// values so we do nothing here.
} else {
- result->SetWithoutPathExpansion(it.key(), from_key_value->DeepCopy());
+ result->SetWithoutPathExpansion(
+ it.key(), base::MakeUnique<base::Value>(*from_key_value));
}
}
- return result;
+ return std::move(result);
}
// Note: This will build a model of all preferences registered as syncable
diff --git a/chromium/components/sync_preferences/pref_model_associator.h b/chromium/components/sync_preferences/pref_model_associator.h
index 033b19c8dfc..2afbef011e2 100644
--- a/chromium/components/sync_preferences/pref_model_associator.h
+++ b/chromium/components/sync_preferences/pref_model_associator.h
@@ -141,10 +141,12 @@ class PrefModelAssociator : public syncer::SyncableService,
const std::string& pref_name,
syncer::SyncChangeList* sync_changes);
- static base::Value* MergeListValues(const base::Value& from_value,
- const base::Value& to_value);
- static base::Value* MergeDictionaryValues(const base::Value& from_value,
- const base::Value& to_value);
+ static std::unique_ptr<base::Value> MergeListValues(
+ const base::Value& from_value,
+ const base::Value& to_value);
+ static std::unique_ptr<base::Value> MergeDictionaryValues(
+ const base::Value& from_value,
+ const base::Value& to_value);
// Do we have an active association between the preferences and sync models?
// Set when start syncing, reset in StopSyncing. While this is not set, we
diff --git a/chromium/components/sync_preferences/pref_model_associator_unittest.cc b/chromium/components/sync_preferences/pref_model_associator_unittest.cc
index d9c4f17d4e6..25da5672dd2 100644
--- a/chromium/components/sync_preferences/pref_model_associator_unittest.cc
+++ b/chromium/components/sync_preferences/pref_model_associator_unittest.cc
@@ -65,15 +65,13 @@ class AbstractPreferenceMergeTest : public testing::Test {
void SetContentPattern(base::DictionaryValue* patterns_dict,
const std::string& expression,
int setting) {
- base::DictionaryValue* expression_dict;
- bool found = patterns_dict->GetDictionaryWithoutPathExpansion(
- expression, &expression_dict);
- if (!found) {
- expression_dict = new base::DictionaryValue;
- patterns_dict->SetWithoutPathExpansion(expression, expression_dict);
+ base::DictionaryValue* expression_dict = nullptr;
+ if (!patterns_dict->GetDictionaryWithoutPathExpansion(expression,
+ &expression_dict)) {
+ expression_dict = patterns_dict->SetDictionaryWithoutPathExpansion(
+ expression, base::MakeUnique<base::DictionaryValue>());
}
- expression_dict->SetWithoutPathExpansion("setting",
- new base::Value(setting));
+ expression_dict->SetIntegerWithoutPathExpansion("setting", setting);
}
void SetPrefToEmpty(const std::string& pref_name) {
diff --git a/chromium/components/sync_preferences/pref_service_syncable_factory.cc b/chromium/components/sync_preferences/pref_service_syncable_factory.cc
index bc593d468b6..66d98feebfd 100644
--- a/chromium/components/sync_preferences/pref_service_syncable_factory.cc
+++ b/chromium/components/sync_preferences/pref_service_syncable_factory.cc
@@ -59,19 +59,17 @@ namespace {
// Expose the |backing_pref_store| through the prefs service.
scoped_refptr<::PrefStore> CreateRegisteredPrefStore(
- service_manager::Connector* connector,
+ prefs::mojom::PrefStoreRegistry* registry,
scoped_refptr<::PrefStore> backing_pref_store,
PrefValueStore::PrefStoreType type) {
// If we're testing or if the prefs service feature flag is off we don't
// register.
- if (!connector || !backing_pref_store)
+ if (!registry || !backing_pref_store)
return backing_pref_store;
- prefs::mojom::PrefStoreRegistryPtr registry_ptr;
- connector->BindInterface(prefs::mojom::kServiceName, &registry_ptr);
return make_scoped_refptr(new prefs::PrefStoreAdapter(
- backing_pref_store, prefs::PrefStoreImpl::Create(
- registry_ptr.get(), backing_pref_store, type)));
+ backing_pref_store,
+ prefs::PrefStoreImpl::Create(registry, backing_pref_store, type)));
}
} // namespace
@@ -82,19 +80,23 @@ std::unique_ptr<PrefServiceSyncable> PrefServiceSyncableFactory::CreateSyncable(
TRACE_EVENT0("browser", "PrefServiceSyncableFactory::CreateSyncable");
PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
+ prefs::mojom::PrefStoreRegistryPtr registry;
+ if (connector)
+ connector->BindInterface(prefs::mojom::kServiceName, &registry);
+
// Expose all read-only stores through the prefs service.
- auto managed = CreateRegisteredPrefStore(connector, managed_prefs_,
+ auto managed = CreateRegisteredPrefStore(registry.get(), managed_prefs_,
PrefValueStore::MANAGED_STORE);
- auto supervised = CreateRegisteredPrefStore(
- connector, supervised_user_prefs_, PrefValueStore::SUPERVISED_USER_STORE);
- auto extension = CreateRegisteredPrefStore(connector, extension_prefs_,
+ auto supervised =
+ CreateRegisteredPrefStore(registry.get(), supervised_user_prefs_,
+ PrefValueStore::SUPERVISED_USER_STORE);
+ auto extension = CreateRegisteredPrefStore(registry.get(), extension_prefs_,
PrefValueStore::EXTENSION_STORE);
auto command_line = CreateRegisteredPrefStore(
- connector, command_line_prefs_, PrefValueStore::COMMAND_LINE_STORE);
+ registry.get(), command_line_prefs_, PrefValueStore::COMMAND_LINE_STORE);
auto recommended = CreateRegisteredPrefStore(
- connector, recommended_prefs_, PrefValueStore::RECOMMENDED_STORE);
+ registry.get(), recommended_prefs_, PrefValueStore::RECOMMENDED_STORE);
- // TODO(sammc): Register Mojo user pref store once implemented.
std::unique_ptr<PrefServiceSyncable> pref_service(new PrefServiceSyncable(
pref_notifier,
new PrefValueStore(managed.get(), supervised.get(), extension.get(),
diff --git a/chromium/components/sync_sessions/BUILD.gn b/chromium/components/sync_sessions/BUILD.gn
index 8d9128767db..7212996b09b 100644
--- a/chromium/components/sync_sessions/BUILD.gn
+++ b/chromium/components/sync_sessions/BUILD.gn
@@ -48,6 +48,8 @@ static_library("sync_sessions") {
"synced_window_delegates_getter.h",
"tab_node_pool.cc",
"tab_node_pool.h",
+ "task_tracker.cc",
+ "task_tracker.h",
]
public_deps = [
@@ -104,6 +106,7 @@ source_set("unit_tests") {
"sync_sessions_metrics_unittest.cc",
"synced_session_tracker_unittest.cc",
"tab_node_pool_unittest.cc",
+ "task_tracker_unittest.cc",
]
deps = [
diff --git a/chromium/components/sync_sessions/favicon_cache_unittest.cc b/chromium/components/sync_sessions/favicon_cache_unittest.cc
index 3db330f42ab..b39a8b37a76 100644
--- a/chromium/components/sync_sessions/favicon_cache_unittest.cc
+++ b/chromium/components/sync_sessions/favicon_cache_unittest.cc
@@ -5,11 +5,11 @@
#include "components/sync_sessions/favicon_cache.h"
#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "components/sync/model/attachments/attachment_id.h"
#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
@@ -292,7 +292,7 @@ class SyncFaviconCacheTest : public testing::Test {
int64_t last_visit_time_ms);
private:
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
FaviconCache cache_;
// Our dummy ChangeProcessor used to inspect changes pushed to Sync.
@@ -302,7 +302,9 @@ class SyncFaviconCacheTest : public testing::Test {
};
SyncFaviconCacheTest::SyncFaviconCacheTest()
- : cache_(nullptr, nullptr, kMaxSyncFavicons),
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ cache_(nullptr, nullptr, kMaxSyncFavicons),
sync_processor_(new TestChangeProcessor),
sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
sync_processor_.get())) {}
diff --git a/chromium/components/sync_sessions/sessions_sync_manager.cc b/chromium/components/sync_sessions/sessions_sync_manager.cc
index 665929fcd4e..47351d79953 100644
--- a/chromium/components/sync_sessions/sessions_sync_manager.cc
+++ b/chromium/components/sync_sessions/sessions_sync_manager.cc
@@ -110,6 +110,27 @@ bool ShouldSyncTabId(SessionID::id_type tab_id) {
return true;
}
+SyncedSession::DeviceType ProtoDeviceTypeToSyncedSessionDeviceType(
+ sync_pb::SyncEnums::DeviceType proto_device_type) {
+ switch (proto_device_type) {
+ case sync_pb::SyncEnums_DeviceType_TYPE_WIN:
+ return SyncedSession::TYPE_WIN;
+ case sync_pb::SyncEnums_DeviceType_TYPE_MAC:
+ return SyncedSession::TYPE_MACOSX;
+ case sync_pb::SyncEnums_DeviceType_TYPE_LINUX:
+ return SyncedSession::TYPE_LINUX;
+ case sync_pb::SyncEnums_DeviceType_TYPE_CROS:
+ return SyncedSession::TYPE_CHROMEOS;
+ case sync_pb::SyncEnums_DeviceType_TYPE_PHONE:
+ return SyncedSession::TYPE_PHONE;
+ case sync_pb::SyncEnums_DeviceType_TYPE_TABLET:
+ return SyncedSession::TYPE_TABLET;
+ case sync_pb::SyncEnums_DeviceType_TYPE_OTHER:
+ return SyncedSession::TYPE_OTHER;
+ }
+ return SyncedSession::TYPE_OTHER;
+}
+
} // namespace
// |local_device| is owned by ProfileSyncService, its lifetime exceeds
@@ -135,7 +156,8 @@ SessionsSyncManager::SessionsSyncManager(
local_event_router_(std::move(router)),
page_revisit_broadcaster_(this, sessions_client),
sessions_updated_callback_(sessions_updated_callback),
- datatype_refresh_callback_(datatype_refresh_callback) {}
+ datatype_refresh_callback_(datatype_refresh_callback),
+ task_tracker_(base::MakeUnique<TaskTracker>()) {}
SessionsSyncManager::~SessionsSyncManager() {}
@@ -229,115 +251,152 @@ syncer::SyncMergeResult SessionsSyncManager::MergeDataAndStartSyncing(
void SessionsSyncManager::AssociateWindows(
ReloadTabsOption option,
syncer::SyncChangeList* change_output) {
- const std::string local_tag = current_machine_tag();
- sync_pb::SessionSpecifics specifics;
- specifics.set_session_tag(local_tag);
- sync_pb::SessionHeader* header_s = specifics.mutable_header();
- SyncedSession* current_session = session_tracker_.GetSession(local_tag);
- current_session->modified_time = base::Time::Now();
- header_s->set_client_name(current_session_name_);
- header_s->set_device_type(current_device_type_);
+ // Note that |current_session| is a pointer owned by |session_tracker_|.
+ // |session_tracker_| will continue to update |current_session| under
+ // the hood so care must be taken accessing it. In particular, invoking
+ // ResetSessionTracking(..) will invalidate all the tab data within
+ // the session, hence why copies of the SyncedSession must be made ahead of
+ // time.
+ SyncedSession* current_session =
+ session_tracker_.GetSession(current_machine_tag());
+ current_session->session_name = current_session_name_;
+ current_session->device_type =
+ ProtoDeviceTypeToSyncedSessionDeviceType(current_device_type_);
+ current_session->session_tag = current_machine_tag();
- session_tracker_.ResetSessionTracking(local_tag);
SyncedWindowDelegatesGetter::SyncedWindowDelegateMap windows =
synced_window_delegates_getter()->GetSyncedWindowDelegates();
- if (option == RELOAD_TABS) {
- UMA_HISTOGRAM_COUNTS("Sync.SessionWindows", windows.size());
+ // On Android, it's possible to not have any tabbed windows if this is a cold
+ // start triggered for a custom tab. In that case, the previous session must
+ // be restored, otherwise it will be lost. On the other hand, if there is at
+ // least one tabbed window open, it's safe to overwrite the previous session
+ // entirely. See crbug.com/639009 for more info.
+ bool found_tabbed_window = false;
+ for (auto& window_iter_pair : windows) {
+ if (window_iter_pair.second->IsTypeTabbed())
+ found_tabbed_window = true;
}
- if (windows.size() == 0) {
- // Assume that the window hasn't loaded. Attempting to associate now would
- // clobber any old windows, so just return.
- LOG(ERROR) << "No windows present, see crbug.com/639009";
- return;
+
+ if (found_tabbed_window) {
+ // Just reset the session tracking. No need to worry about the previous
+ // session; the current tabbed windows are now the source of truth.
+ session_tracker_.ResetSessionTracking(current_machine_tag());
+ current_session->modified_time = base::Time::Now();
+ } else {
+ DVLOG(1) << "Found no tabbed windows. Reloading "
+ << current_session->windows.size()
+ << " windows from previous session.";
+
+ // A copy of the specifics must be made because |current_session| will be
+ // updated in place and therefore can't be relied on as the source of truth.
+ sync_pb::SessionHeader header_specifics;
+ header_specifics.CopyFrom(current_session->ToSessionHeaderProto());
+ session_tracker_.ResetSessionTracking(current_machine_tag());
+ PopulateSyncedSessionFromSpecifics(current_machine_tag(), header_specifics,
+ base::Time::Now(), current_session);
+
+ // The tab entities stored in sync have outdated SessionId values. Go
+ // through and update them to the new SessionIds.
+ for (auto& win_iter : current_session->windows) {
+ for (auto& tab : win_iter.second->wrapped_window.tabs) {
+ int sync_id = TabNodePool::kInvalidTabNodeID;
+ if (!session_tracker_.GetTabNodeFromLocalTabId(tab->tab_id.id(),
+ &sync_id) ||
+ sync_id == TabNodePool::kInvalidTabNodeID) {
+ continue;
+ }
+ DVLOG(1) << "Rewriting tab node " << sync_id << " with tab id "
+ << tab->tab_id.id();
+ AppendChangeForExistingTab(sync_id, *tab, change_output);
+ }
+ }
}
- for (auto window_iter_pair : windows) {
+
+ for (auto& window_iter_pair : windows) {
const SyncedWindowDelegate* window_delegate = window_iter_pair.second;
if (option == RELOAD_TABS) {
UMA_HISTOGRAM_COUNTS("Sync.SessionTabs", window_delegate->GetTabCount());
}
- // Make sure the window has tabs and a viewable window. The viewable window
- // check is necessary because, for example, when a browser is closed the
- // destructor is not necessarily run immediately. This means its possible
- // for us to get a handle to a browser that is about to be removed. If
- // the tab count is 0 or the window is null, the browser is about to be
- // deleted, so we ignore it.
+ // Make sure the window has tabs and a viewable window. The viewable
+ // window check is necessary because, for example, when a browser is
+ // closed the destructor is not necessarily run immediately. This means
+ // its possible for us to get a handle to a browser that is about to be
+ // removed. If the tab count is 0 or the window is null, the browser is
+ // about to be deleted, so we ignore it.
if (window_delegate->ShouldSync() && window_delegate->GetTabCount() &&
window_delegate->HasWindow()) {
sync_pb::SessionWindow window_s;
SessionID::id_type window_id = window_delegate->GetSessionId();
DVLOG(1) << "Associating window " << window_id << " with "
<< window_delegate->GetTabCount() << " tabs.";
- window_s.set_window_id(window_id);
- // Note: We don't bother to set selected tab index anymore. We still
- // consume it when receiving foreign sessions, as reading it is free, but
- // it triggers too many sync cycles with too little value to make setting
- // it worthwhile.
- if (window_delegate->IsTypeTabbed()) {
- window_s.set_browser_type(
- sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
- } else if (window_delegate->IsTypePopup()) {
- window_s.set_browser_type(
- sync_pb::SessionWindow_BrowserType_TYPE_POPUP);
- } else {
- // This is a custom tab within an app. These will not be restored on
- // startup if not present.
- window_s.set_browser_type(
- sync_pb::SessionWindow_BrowserType_TYPE_CUSTOM_TAB);
- }
bool found_tabs = false;
for (int j = 0; j < window_delegate->GetTabCount(); ++j) {
SessionID::id_type tab_id = window_delegate->GetTabIdAt(j);
SyncedTabDelegate* synced_tab = window_delegate->GetTabAt(j);
- // GetTabAt can return a null tab; in that case just skip it.
- if (!synced_tab)
+ // GetTabAt can return a null tab; in that case just skip it. Similarly,
+ // if for some reason the tab id is invalid, skip it.
+ if (!synced_tab || !ShouldSyncTabId(tab_id))
continue;
- if (!ShouldSyncTabId(tab_id)) {
- LOG(ERROR) << "Not syncing invalid tab with id " << tab_id;
- continue;
- }
-
// Placeholder tabs are those without WebContents, either because they
// were never loaded into memory or they were evicted from memory
- // (typically only on Android devices). They only have a tab id, window
- // id, and a saved synced id (corresponding to the tab node id). Note
- // that only placeholders have this sync id, as it's necessary to
- // properly reassociate the tab with the entity that was backing it.
+ // (typically only on Android devices). They only have a tab id,
+ // window id, and a saved synced id (corresponding to the tab node
+ // id). Note that only placeholders have this sync id, as it's
+ // necessary to properly reassociate the tab with the entity that was
+ // backing it.
if (synced_tab->IsPlaceholderTab()) {
// For tabs without WebContents update the |tab_id| and |window_id|,
// as it could have changed after a session restore.
if (synced_tab->GetSyncId() > TabNodePool::kInvalidTabNodeID) {
AssociateRestoredPlaceholderTab(*synced_tab, tab_id, window_id,
change_output);
+ } else {
+ DVLOG(1) << "Placeholder tab " << tab_id << " has no sync id.";
}
} else if (RELOAD_TABS == option) {
AssociateTab(synced_tab, change_output);
}
// If the tab was syncable, it would have been added to the tracker
- // either by the above Associate[RestoredPlaceholder]Tab call or by the
- // OnLocalTabModified method invoking AssociateTab directly. Therefore,
- // we can key whether this window has valid tabs based on the tab's
- // presence in the tracker.
+ // either by the above Associate[RestoredPlaceholder]Tab call or by
+ // the OnLocalTabModified method invoking AssociateTab directly.
+ // Therefore, we can key whether this window has valid tabs based on
+ // the tab's presence in the tracker.
const sessions::SessionTab* tab = nullptr;
- if (session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) {
+ if (session_tracker_.LookupSessionTab(current_machine_tag(), tab_id,
+ &tab)) {
found_tabs = true;
- window_s.add_tab(tab_id);
+
+ // Update this window's representation in the synced session tracker.
+ // This is a no-op if called multiple times.
+ session_tracker_.PutWindowInSession(current_machine_tag(), window_id);
+
+ // Put the tab in the window (must happen after the window is added
+ // to the session).
+ session_tracker_.PutTabInWindow(current_machine_tag(), window_id,
+ tab_id);
}
}
if (found_tabs) {
- sync_pb::SessionWindow* header_window = header_s->add_window();
- *header_window = window_s;
-
- // Update this window's representation in the synced session tracker.
- session_tracker_.PutWindowInSession(local_tag, window_id);
- BuildSyncedSessionFromSpecifics(
- local_tag, window_s, current_session->modified_time,
- current_session->windows[window_id].get());
+ SyncedSessionWindow* synced_session_window =
+ current_session->windows[window_id].get();
+ if (window_delegate->IsTypeTabbed()) {
+ synced_session_window->window_type =
+ sync_pb::SessionWindow_BrowserType_TYPE_TABBED;
+ } else if (window_delegate->IsTypePopup()) {
+ synced_session_window->window_type =
+ sync_pb::SessionWindow_BrowserType_TYPE_POPUP;
+ } else {
+ // This is a custom tab within an app. These will not be restored on
+ // startup if not present.
+ synced_session_window->window_type =
+ sync_pb::SessionWindow_BrowserType_TYPE_CUSTOM_TAB;
+ }
}
}
}
@@ -350,7 +409,9 @@ void SessionsSyncManager::AssociateWindows(
// if the entity specifics are identical (i.e windows, client name did
// not change).
sync_pb::EntitySpecifics entity;
- entity.mutable_session()->CopyFrom(specifics);
+ entity.mutable_session()->set_session_tag(current_machine_tag());
+ entity.mutable_session()->mutable_header()->CopyFrom(
+ current_session->ToSessionHeaderProto());
syncer::SyncData data = syncer::SyncData::CreateLocalData(
current_machine_tag(), current_session_name_, entity);
change_output->push_back(
@@ -362,8 +423,9 @@ void SessionsSyncManager::AssociateTab(SyncedTabDelegate* const tab_delegate,
DCHECK(!tab_delegate->IsPlaceholderTab());
if (tab_delegate->IsBeingDestroyed()) {
- // Do nothing. By not proactively adding the tab to the session, it will be
- // removed if necessary during subsequent cleanup.
+ task_tracker_->CleanTabTasks(tab_delegate->GetSessionId());
+ // Do nothing else. By not proactively adding the tab to the session, it
+ // will be removed if necessary during subsequent cleanup.
return;
}
@@ -375,10 +437,17 @@ void SessionsSyncManager::AssociateTab(SyncedTabDelegate* const tab_delegate,
<< tab_delegate->GetWindowId();
int tab_node_id = TabNodePool::kInvalidTabNodeID;
- bool existing_tab_node =
- session_tracker_.GetTabNodeFromLocalTabId(tab_id, &tab_node_id);
- CHECK_NE(TabNodePool::kInvalidTabNodeID, tab_node_id) << "crbug.com/673618";
- tab_delegate->SetSyncId(tab_node_id);
+ bool existing_tab_node = true;
+ if (session_tracker_.IsLocalTabNodeAssociated(tab_delegate->GetSyncId())) {
+ tab_node_id = tab_delegate->GetSyncId();
+ session_tracker_.ReassociateLocalTab(tab_node_id, tab_id);
+ } else {
+ existing_tab_node =
+ session_tracker_.GetTabNodeFromLocalTabId(tab_id, &tab_node_id);
+ CHECK_NE(TabNodePool::kInvalidTabNodeID, tab_node_id) << "crbug.com/673618";
+ tab_delegate->SetSyncId(tab_node_id);
+ }
+
sessions::SessionTab* session_tab =
session_tracker_.GetTab(current_machine_tag(), tab_id);
@@ -397,6 +466,9 @@ void SessionsSyncManager::AssociateTab(SyncedTabDelegate* const tab_delegate,
sync_pb::EntitySpecifics specifics;
specifics.mutable_session()->CopyFrom(
SessionTabToSpecifics(*session_tab, current_machine_tag(), tab_node_id));
+ // Intercept the sync model here to update task tracker and fill navigations
+ // with their ancestor navigations.
+ TrackTasks(tab_delegate, specifics.mutable_session());
syncer::SyncData data = syncer::SyncData::CreateLocalData(
TabNodeIdToTag(current_machine_tag(), tab_node_id), current_session_name_,
specifics);
@@ -416,6 +488,54 @@ void SessionsSyncManager::AssociateTab(SyncedTabDelegate* const tab_delegate,
}
}
+void SessionsSyncManager::TrackTasks(
+ SyncedTabDelegate* const tab_delegate,
+ sync_pb::SessionSpecifics* session_specifics) {
+ sync_pb::SessionTab* tab_specifics = session_specifics->mutable_tab();
+ // Index in the whole navigations of the tab.
+ int current_navigation_index = tab_delegate->GetCurrentEntryIndex();
+ // Index in the tab_specifics, where the navigations is a -6/+6 window
+ int current_index_in_tab_specifics =
+ tab_specifics->current_navigation_index();
+ int64_t current_navigation_global_id =
+ tab_specifics->navigation(current_index_in_tab_specifics).global_id();
+
+ TabTasks* tab_tasks =
+ task_tracker_->GetTabTasks(tab_delegate->GetSessionId());
+ tab_tasks->UpdateWithNavigation(
+ current_navigation_index,
+ tab_delegate->GetTransitionAtIndex(current_navigation_index),
+ current_navigation_global_id);
+
+ for (int i = 0; i < tab_specifics->navigation_size(); i++) {
+ // Excluding blocked navigations, which are appended at tail.
+ if (tab_specifics->navigation(i).blocked_state() ==
+ sync_pb::TabNavigation::STATE_BLOCKED) {
+ break;
+ }
+
+ int navigation_index =
+ current_navigation_index - current_index_in_tab_specifics + i;
+ // Skipping navigations not been tracked by task_tracker.
+ if (navigation_index < 0 ||
+ navigation_index >= tab_tasks->GetNavigationsCount()) {
+ continue;
+ }
+ std::vector<int64_t> task_ids =
+ tab_tasks->GetTaskIdsForNavigation(navigation_index);
+ if (task_ids.empty())
+ continue;
+
+ tab_specifics->mutable_navigation(i)->set_task_id(task_ids.back());
+ // Pop the task id of navigation self.
+ task_ids.pop_back();
+ for (auto ancestor_task_id : task_ids) {
+ tab_specifics->mutable_navigation(i)->add_ancestor_task_id(
+ ancestor_task_id);
+ }
+ }
+}
+
bool SessionsSyncManager::RebuildAssociations() {
syncer::SyncDataList data(sync_processor_->GetAllSyncData(syncer::SESSIONS));
std::unique_ptr<syncer::SyncErrorFactory> error_handler(
@@ -633,6 +753,12 @@ bool SessionsSyncManager::GetAllForeignSessions(
bool SessionsSyncManager::InitFromSyncModel(
const syncer::SyncDataList& sync_data,
syncer::SyncChangeList* new_changes) {
+ // Map of all rewritten local ids. Because ids are reset on each restart,
+ // and id generation happens outside of Sync, all ids from a previous local
+ // session must be rewritten in order to be valid.
+ // Key: previous session id. Value: new session id.
+ std::map<SessionID::id_type, SessionID::id_type> session_id_map;
+
bool found_current_header = false;
int bad_foreign_hash_count = 0;
for (syncer::SyncDataList::const_iterator it = sync_data.begin();
@@ -669,9 +795,37 @@ bool SessionsSyncManager::InitFromSyncModel(
if (specifics.header().has_client_name())
current_session_name_ = specifics.header().client_name();
- // TODO(zea): crbug.com/639009 update the tracker with the specifics
- // from the header node as well. This will be necessary to preserve
- // the set of open tabs when a custom tab is opened.
+ // The specifics from the SyncData are immutable. Create a mutable copy
+ // to hold the rewritten ids.
+ sync_pb::SessionSpecifics rewritten_specifics(specifics);
+
+ // Go through and generate new tab and window ids as necessary, updating
+ // the specifics in place.
+ for (auto& window :
+ *rewritten_specifics.mutable_header()->mutable_window()) {
+ session_id_map[window.window_id()] = SessionID().id();
+ window.set_window_id(session_id_map[window.window_id()]);
+
+ google::protobuf::RepeatedField<int>* tab_ids = window.mutable_tab();
+ for (int i = 0; i < tab_ids->size(); i++) {
+ auto tab_iter = session_id_map.find(tab_ids->Get(i));
+ if (tab_iter == session_id_map.end()) {
+ // SessionID::SessionID() automatically increments a static
+ // variable, forcing a new id to be generated each time.
+ session_id_map[tab_ids->Get(i)] = SessionID().id();
+ }
+ *(tab_ids->Mutable(i)) = session_id_map[tab_ids->Get(i)];
+ // Note: the tab id of the SessionTab will be updated when the tab
+ // node itself is processed.
+ }
+ }
+
+ UpdateTrackerWithSpecifics(rewritten_specifics,
+ remote.GetModifiedTime());
+
+ DVLOG(1) << "Loaded local header and rewrote " << session_id_map.size()
+ << " ids.";
+
} else {
if (specifics.has_header() || !specifics.has_tab()) {
LOG(WARNING) << "Found more than one session header node with local "
@@ -686,12 +840,30 @@ bool SessionsSyncManager::InitFromSyncModel(
new_changes->push_back(tombstone);
} else {
// This is a valid old tab node, add it to the tracker and associate
- // it.
+ // it (using the new tab id).
DVLOG(1) << "Associating local tab " << specifics.tab().tab_id()
<< " with node " << specifics.tab_node_id();
- session_tracker_.ReassociateLocalTab(specifics.tab_node_id(),
- specifics.tab().tab_id());
- UpdateTrackerWithSpecifics(specifics, remote.GetModifiedTime());
+
+ // Now file the tab under the new tab id.
+ SessionID::id_type new_tab_id = kInvalidTabID;
+ auto iter = session_id_map.find(specifics.tab().tab_id());
+ if (iter != session_id_map.end()) {
+ new_tab_id = iter->second;
+ } else {
+ session_id_map[specifics.tab().tab_id()] = SessionID().id();
+ new_tab_id = session_id_map[specifics.tab().tab_id()];
+ }
+ DVLOG(1) << "Remapping tab " << specifics.tab().tab_id() << " to "
+ << new_tab_id;
+
+ // The specifics from the SyncData are immutable. Create a mutable
+ // copy to hold the rewritten ids.
+ sync_pb::SessionSpecifics rewritten_specifics(specifics);
+ rewritten_specifics.mutable_tab()->set_tab_id(new_tab_id);
+ session_tracker_.ReassociateLocalTab(
+ rewritten_specifics.tab_node_id(), new_tab_id);
+ UpdateTrackerWithSpecifics(rewritten_specifics,
+ remote.GetModifiedTime());
}
}
}
@@ -703,7 +875,7 @@ bool SessionsSyncManager::InitFromSyncModel(
session_tracker_.LookupAllForeignSessions(&sessions,
SyncedSessionTracker::RAW);
for (const auto* session : sessions) {
- session_tracker_.CleanupForeignSession(session->session_tag);
+ session_tracker_.CleanupSession(session->session_tag);
}
UMA_HISTOGRAM_COUNTS_100("Sync.SessionsBadForeignHashOnMergeCount",
@@ -730,27 +902,17 @@ void SessionsSyncManager::UpdateTrackerWithSpecifics(
// Load (or create) the SyncedSession object for this client.
const sync_pb::SessionHeader& header = specifics.header();
- PopulateSessionHeaderFromSpecifics(header, modification_time, session);
// Reset the tab/window tracking for this session (must do this before
// we start calling PutWindowInSession and PutTabInWindow so that all
// unused tabs/windows get cleared by the CleanupSession(...) call).
session_tracker_.ResetSessionTracking(session_tag);
- // Process all the windows and their tab information.
- int num_windows = header.window_size();
- DVLOG(1) << "Populating " << session_tag << " with " << num_windows
- << " windows.";
-
- for (int i = 0; i < num_windows; ++i) {
- const sync_pb::SessionWindow& window_s = header.window(i);
- SessionID::id_type window_id = window_s.window_id();
- session_tracker_.PutWindowInSession(session_tag, window_id);
- BuildSyncedSessionFromSpecifics(session_tag, window_s, modification_time,
- session->windows[window_id].get());
- }
+ PopulateSyncedSessionFromSpecifics(session_tag, header, modification_time,
+ session);
+
// Delete any closed windows and unused tabs as necessary.
- session_tracker_.CleanupForeignSession(session_tag);
+ session_tracker_.CleanupSession(session_tag);
} else if (specifics.has_tab()) {
const sync_pb::SessionTab& tab_s = specifics.tab();
SessionID::id_type tab_id = tab_s.tab_id();
@@ -822,46 +984,37 @@ void SessionsSyncManager::InitializeCurrentMachineTag(
}
}
-// static
-void SessionsSyncManager::PopulateSessionHeaderFromSpecifics(
+void SessionsSyncManager::PopulateSyncedSessionFromSpecifics(
+ const std::string& session_tag,
const sync_pb::SessionHeader& header_specifics,
base::Time mtime,
- SyncedSession* session_header) {
+ SyncedSession* synced_session) {
if (header_specifics.has_client_name())
- session_header->session_name = header_specifics.client_name();
+ synced_session->session_name = header_specifics.client_name();
if (header_specifics.has_device_type()) {
- switch (header_specifics.device_type()) {
- case sync_pb::SyncEnums_DeviceType_TYPE_WIN:
- session_header->device_type = SyncedSession::TYPE_WIN;
- break;
- case sync_pb::SyncEnums_DeviceType_TYPE_MAC:
- session_header->device_type = SyncedSession::TYPE_MACOSX;
- break;
- case sync_pb::SyncEnums_DeviceType_TYPE_LINUX:
- session_header->device_type = SyncedSession::TYPE_LINUX;
- break;
- case sync_pb::SyncEnums_DeviceType_TYPE_CROS:
- session_header->device_type = SyncedSession::TYPE_CHROMEOS;
- break;
- case sync_pb::SyncEnums_DeviceType_TYPE_PHONE:
- session_header->device_type = SyncedSession::TYPE_PHONE;
- break;
- case sync_pb::SyncEnums_DeviceType_TYPE_TABLET:
- session_header->device_type = SyncedSession::TYPE_TABLET;
- break;
- case sync_pb::SyncEnums_DeviceType_TYPE_OTHER:
- // Intentionally fall-through
- default:
- session_header->device_type = SyncedSession::TYPE_OTHER;
- break;
- }
+ synced_session->device_type = ProtoDeviceTypeToSyncedSessionDeviceType(
+ header_specifics.device_type());
+ }
+ synced_session->modified_time =
+ std::max(mtime, synced_session->modified_time);
+
+ // Process all the windows and their tab information.
+ int num_windows = header_specifics.window_size();
+ DVLOG(1) << "Populating " << session_tag << " with " << num_windows
+ << " windows.";
+
+ for (int i = 0; i < num_windows; ++i) {
+ const sync_pb::SessionWindow& window_s = header_specifics.window(i);
+ SessionID::id_type window_id = window_s.window_id();
+ session_tracker_.PutWindowInSession(session_tag, window_id);
+ PopulateSyncedSessionWindowFromSpecifics(
+ session_tag, window_s, synced_session->modified_time,
+ synced_session->windows[window_id].get());
}
- session_header->modified_time =
- std::max(mtime, session_header->modified_time);
}
// static
-void SessionsSyncManager::BuildSyncedSessionFromSpecifics(
+void SessionsSyncManager::PopulateSyncedSessionWindowFromSpecifics(
const std::string& session_tag,
const sync_pb::SessionWindow& specifics,
base::Time mtime,
@@ -1017,14 +1170,22 @@ void SessionsSyncManager::AssociateRestoredPlaceholderTab(
session_tracker_.GetTab(current_machine_tag(), new_tab_id);
local_tab->window_id.set_id(new_window_id);
+ AppendChangeForExistingTab(tab_delegate.GetSyncId(), *local_tab,
+ change_output);
+}
+
+void SessionsSyncManager::AppendChangeForExistingTab(
+ int sync_id,
+ const sessions::SessionTab& tab,
+ syncer::SyncChangeList* change_output) {
// Rewrite the specifics based on the reassociated SessionTab to preserve
// the new tab and window ids.
sync_pb::EntitySpecifics entity;
- entity.mutable_session()->CopyFrom(SessionTabToSpecifics(
- *local_tab, current_machine_tag(), tab_delegate.GetSyncId()));
+ entity.mutable_session()->CopyFrom(
+ SessionTabToSpecifics(tab, current_machine_tag(), sync_id));
syncer::SyncData data = syncer::SyncData::CreateLocalData(
- TabNodeIdToTag(current_machine_tag(), tab_delegate.GetSyncId()),
- current_session_name_, entity);
+ TabNodeIdToTag(current_machine_tag(), sync_id), current_session_name_,
+ entity);
change_output->push_back(
syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data));
}
diff --git a/chromium/components/sync_sessions/sessions_sync_manager.h b/chromium/components/sync_sessions/sessions_sync_manager.h
index bf72e9e716e..3c5e5fec3ad 100644
--- a/chromium/components/sync_sessions/sessions_sync_manager.h
+++ b/chromium/components/sync_sessions/sessions_sync_manager.h
@@ -30,6 +30,7 @@
#include "components/sync_sessions/revisit/page_revisit_broadcaster.h"
#include "components/sync_sessions/synced_session.h"
#include "components/sync_sessions/synced_session_tracker.h"
+#include "components/sync_sessions/task_tracker.h"
namespace syncer {
class LocalDeviceInfoProvider;
@@ -119,7 +120,7 @@ class SessionsSyncManager : public syncer::SyncableService,
private:
friend class extensions::ExtensionSessionsTest;
friend class SessionsSyncManagerTest;
- FRIEND_TEST_ALL_PREFIXES(SessionsSyncManagerTest, PopulateSessionHeader);
+ FRIEND_TEST_ALL_PREFIXES(SessionsSyncManagerTest, PopulateSyncedSession);
FRIEND_TEST_ALL_PREFIXES(SessionsSyncManagerTest, PopulateSessionWindow);
FRIEND_TEST_ALL_PREFIXES(SessionsSyncManagerTest, ValidTabs);
FRIEND_TEST_ALL_PREFIXES(SessionsSyncManagerTest, SetSessionTabFromDelegate);
@@ -187,14 +188,15 @@ class SessionsSyncManager : public syncer::SyncableService,
// Used to populate a session header from the session specifics header
// provided.
- static void PopulateSessionHeaderFromSpecifics(
+ void PopulateSyncedSessionFromSpecifics(
+ const std::string& session_tag,
const sync_pb::SessionHeader& header_specifics,
base::Time mtime,
- SyncedSession* session_header);
+ SyncedSession* synced_session);
- // Builds |session_window| from the session specifics window
+ // Builds |synced_session_window| from the session specifics window
// provided and updates the SessionTracker with foreign session data created.
- void BuildSyncedSessionFromSpecifics(
+ void PopulateSyncedSessionWindowFromSpecifics(
const std::string& session_tag,
const sync_pb::SessionWindow& specifics,
base::Time mtime,
@@ -234,6 +236,11 @@ class SessionsSyncManager : public syncer::SyncableService,
void LocalTabDelegateToSpecifics(const SyncedTabDelegate& tab_delegate,
sync_pb::SessionSpecifics* specifics);
+ // Updates task tracker with current navigation of |tab_delegate|, and fills
+ // TabNavigation's task id related fields in |specifics|.
+ void TrackTasks(SyncedTabDelegate* const tab_delegate,
+ sync_pb::SessionSpecifics* specifics);
+
// It's possible that when we associate windows, tabs aren't all loaded
// into memory yet (e.g on android) and we don't have a WebContents. In this
// case we can't do a full association, but we still want to update tab IDs
@@ -246,6 +253,12 @@ class SessionsSyncManager : public syncer::SyncableService,
SessionID::id_type new_window_id,
syncer::SyncChangeList* change_output);
+ // Appends an ACTION_UPDATE for a sync tab entity onto |change_output| to
+ // reflect the contents of |tab|, given the tab node id |sync_id|.
+ void AppendChangeForExistingTab(int sync_id,
+ const sessions::SessionTab& tab,
+ syncer::SyncChangeList* change_output);
+
// Stops and re-starts syncing to rebuild association mappings. Returns true
// when re-starting succeeds.
// See |local_tab_pool_out_of_sync_|.
@@ -319,6 +332,10 @@ class SessionsSyncManager : public syncer::SyncableService,
// Callback to inform sync that a sync data refresh is requested.
base::Closure datatype_refresh_callback_;
+ // Tracks Chrome Tasks, which associates navigations, with tab and navigation
+ // changes of current session.
+ std::unique_ptr<TaskTracker> task_tracker_;
+
DISALLOW_COPY_AND_ASSIGN(SessionsSyncManager);
};
diff --git a/chromium/components/sync_sessions/sessions_sync_manager_unittest.cc b/chromium/components/sync_sessions/sessions_sync_manager_unittest.cc
index 7479a1833c5..26eac1b5136 100644
--- a/chromium/components/sync_sessions/sessions_sync_manager_unittest.cc
+++ b/chromium/components/sync_sessions/sessions_sync_manager_unittest.cc
@@ -243,7 +243,7 @@ class TestSyncedTabDelegate : public SyncedTabDelegate {
private:
int current_entry_index_ = -1;
bool is_supervised_ = false;
- int sync_id_ = -1;
+ int sync_id_ = kInvalidTabID;
SessionID tab_id_;
SessionID window_id_;
std::vector<std::unique_ptr<const sessions::SerializedNavigationEntry>>
@@ -328,7 +328,7 @@ class PlaceholderTabDelegate : public SyncedTabDelegate {
private:
SessionID::id_type session_id_;
- int sync_id_;
+ int sync_id_ = kInvalidTabID;
};
class TestSyncedWindowDelegate : public SyncedWindowDelegate {
@@ -358,6 +358,10 @@ class TestSyncedWindowDelegate : public SyncedWindowDelegate {
return false;
}
+ void OverrideWindowTypeToCustomTab() {
+ window_type_ = sync_pb::SessionWindow_BrowserType_TYPE_CUSTOM_TAB;
+ }
+
SyncedTabDelegate* GetTabAt(int index) const override {
if (tab_delegates_.find(index) != tab_delegates_.end())
return tab_delegates_.find(index)->second;
@@ -387,6 +391,8 @@ class TestSyncedWindowDelegate : public SyncedWindowDelegate {
SessionID window_id_;
sync_pb::SessionWindow_BrowserType window_type_ =
sync_pb::SessionWindow_BrowserType_TYPE_TABBED;
+ std::map<int, SyncedTabDelegate*> tab_overrides_;
+ std::map<int, SessionID::id_type> tab_id_overrides_;
};
class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter {
@@ -410,6 +416,8 @@ class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter {
delegates_[delegate->GetSessionId()] = delegate;
}
+ void ClearSyncedWindowDelegates() { delegates_.clear(); }
+
private:
SyncedWindowDelegateMap delegates_;
};
@@ -469,7 +477,7 @@ class DummyRouter : public LocalSessionEventRouter {
void StartRoutingTo(LocalSessionEventHandler* handler) override {
handler_ = handler;
}
- void Stop() override {}
+ void Stop() override { handler_ = nullptr; }
void NotifyNav(SyncedTabDelegate* tab) {
if (handler_)
@@ -699,21 +707,39 @@ class SessionsSyncManagerTest : public testing::Test {
}
TestSyncedTabDelegate* AddTab(SessionID::id_type window_id,
const std::string& url) {
- return AddTab(window_id, url, base::Time());
+ return AddTab(window_id, url, base::Time::Now());
}
void NavigateTab(TestSyncedTabDelegate* delegate,
const std::string& url,
- base::Time time) {
+ base::Time time,
+ ui::PageTransition transition) {
auto entry = base::MakeUnique<sessions::SerializedNavigationEntry>(
SerializedNavigationEntryTestHelper::CreateNavigation(url, kTitle));
SerializedNavigationEntryTestHelper::SetTimestamp(time, entry.get());
+ SerializedNavigationEntryTestHelper::SetTransitionType(transition,
+ entry.get());
delegate->AppendEntry(std::move(entry));
delegate->set_current_entry_index(delegate->GetCurrentEntryIndex() + 1);
router_->NotifyNav(delegate);
}
+ void NavigateTab(TestSyncedTabDelegate* delegate,
+ const std::string& url,
+ base::Time time) {
+ NavigateTab(delegate, url, time, ui::PAGE_TRANSITION_TYPED);
+ }
void NavigateTab(TestSyncedTabDelegate* delegate, const std::string& url) {
- NavigateTab(delegate, url, base::Time());
+ NavigateTab(delegate, url, base::Time::Now());
+ }
+ void NavigateTab(TestSyncedTabDelegate* delegate,
+ const std::string& url,
+ ui::PageTransition transition) {
+ NavigateTab(delegate, url, base::Time::Now(), transition);
+ }
+
+ void ResetWindows() {
+ window_getter_.ClearSyncedWindowDelegates();
+ windows_.clear();
}
TestSyncedWindowDelegate* AddWindow() {
@@ -722,6 +748,34 @@ class SessionsSyncManagerTest : public testing::Test {
return windows_.back().get();
}
+ syncer::SyncDataList GetDataFromChanges(
+ const syncer::SyncChangeList& changes) {
+ syncer::SyncDataList data_list;
+ for (auto& change : changes) {
+ syncer::SyncDataLocal change_data(change.sync_data());
+ bool found = false;
+ for (auto&& data : data_list) {
+ syncer::SyncDataLocal local_data(data);
+ if (local_data.GetTag() == change_data.GetTag()) {
+ data = change.sync_data();
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ data_list.push_back(change_data);
+ }
+ return data_list;
+ }
+
+ syncer::SyncDataList ConvertToRemote(const syncer::SyncDataList& in) {
+ syncer::SyncDataList out;
+ for (auto& data : in) {
+ out.push_back(CreateRemoteData(data.GetSpecifics()));
+ }
+ return out;
+ }
+
private:
std::unique_ptr<syncer::FakeSyncClient> sync_client_;
std::unique_ptr<SyncSessionsClientShim> sessions_client_shim_;
@@ -737,41 +791,6 @@ class SessionsSyncManagerTest : public testing::Test {
std::unique_ptr<LocalDeviceInfoProviderMock> local_device_;
};
-// Test that the SyncSessionManager can properly fill in a SessionHeader.
-TEST_F(SessionsSyncManagerTest, PopulateSessionHeader) {
- sync_pb::SessionHeader header_s;
- header_s.set_client_name("Client 1");
- header_s.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_WIN);
-
- SyncedSession session;
- base::Time time = base::Time::Now();
- SessionsSyncManager::PopulateSessionHeaderFromSpecifics(header_s, time,
- &session);
- ASSERT_EQ("Client 1", session.session_name);
- ASSERT_EQ(SyncedSession::TYPE_WIN, session.device_type);
- ASSERT_EQ(time, session.modified_time);
-}
-
-// Test translation between protobuf types and chrome session types.
-TEST_F(SessionsSyncManagerTest, PopulateSessionWindow) {
- sync_pb::SessionWindow window_s;
- window_s.add_tab(0);
- window_s.set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
- window_s.set_selected_tab_index(1);
-
- SyncedSession* session = manager()->session_tracker_.GetSession(kTag1);
- manager()->session_tracker_.PutWindowInSession(kTag1, 0);
- manager()->BuildSyncedSessionFromSpecifics(kTag1, window_s, base::Time(),
- session->windows[0].get());
- ASSERT_EQ(1U, session->windows[0]->wrapped_window.tabs.size());
- ASSERT_EQ(1, session->windows[0]->wrapped_window.selected_tab_index);
- ASSERT_EQ(sessions::SessionWindow::TYPE_TABBED,
- session->windows[0]->wrapped_window.type);
- ASSERT_EQ(1U, manager()->session_tracker_.num_synced_sessions());
- ASSERT_EQ(1U, manager()->session_tracker_.num_synced_tabs(kTag1));
-}
-
-// Populate the fake tab delegate with some data and navigation
// entries and make sure that setting a SessionTab from it preserves
// those entries (and clobbers any existing data).
TEST_F(SessionsSyncManagerTest, SetSessionTabFromDelegate) {
@@ -952,6 +971,117 @@ TEST_F(SessionsSyncManagerTest, MergeLocalSessionNoTabs) {
EXPECT_TRUE(out[0].sync_data().GetSpecifics().session().has_header());
}
+// Ensure that tabbed windows from a previous session are preserved if no
+// windows are present on startup.
+TEST_F(SessionsSyncManagerTest, PreserveTabbedDataNoWindows) {
+ syncer::SyncDataList in;
+ syncer::SyncChangeList out;
+
+ // Set up one tab and start sync with it.
+ TestSyncedTabDelegate* tab = AddTab(AddWindow()->GetSessionId(), kFoo1);
+ NavigateTab(tab, kFoo2);
+ InitWithSyncDataTakeOutput(in, &out);
+
+ // There should be two entities, a header and a tab.
+ in = GetDataFromChanges(out);
+ out.clear();
+ ASSERT_EQ(2U, in.size());
+
+ // Resync, using the previous sync data, but with no windows open now.
+ manager()->StopSyncing(syncer::SESSIONS);
+ ResetWindows();
+ InitWithSyncDataTakeOutput(ConvertToRemote(in), &out);
+
+ // There should be two changes: the rewritten tab (to update the tab id), and
+ // the rewritten header.
+ ASSERT_TRUE(ChangeTypeMatches(
+ out, {SyncChange::ACTION_UPDATE, SyncChange::ACTION_UPDATE}));
+ VerifyLocalTabChange(out[0], 2, kFoo2);
+ VerifyLocalHeaderChange(out[1], 1, 1);
+
+ // Verify the tab id of the restored tab is updated and consistent.
+ int restored_tab_id =
+ out[0].sync_data().GetSpecifics().session().tab().tab_id();
+ // SessionId should be rewritten on restore.
+ ASSERT_NE(tab->GetSessionId(), restored_tab_id);
+ ASSERT_EQ(
+ restored_tab_id,
+ out[1].sync_data().GetSpecifics().session().header().window(0).tab(0));
+}
+
+// Ensure that tabbed windows from a previous session are preserved if only
+// transient windows are present at startup.
+TEST_F(SessionsSyncManagerTest, PreserveTabbedDataCustomTab) {
+ syncer::SyncDataList in;
+ syncer::SyncChangeList out;
+
+ // Set up one tab and start sync with it.
+ TestSyncedWindowDelegate* window = AddWindow();
+ TestSyncedTabDelegate* tab = AddTab(window->GetSessionId(), kFoo1);
+ NavigateTab(tab, kFoo2);
+ InitWithSyncDataTakeOutput(in, &out);
+
+ // There should be two entities, a header and a tab.
+ in = GetDataFromChanges(out);
+ out.clear();
+ ASSERT_EQ(2U, in.size());
+
+ // Resync, using the previous sync data, but with only a custom tab open.
+ manager()->StopSyncing(syncer::SESSIONS);
+ window->OverrideWindowTypeToCustomTab();
+ SessionID new_window_id;
+ window->OverrideWindowId(new_window_id.id());
+ std::unique_ptr<TestSyncedTabDelegate> custom_tab =
+ base::MakeUnique<TestSyncedTabDelegate>();
+ NavigateTab(custom_tab.get(), kBar1);
+ window->OverrideTabAt(0, custom_tab.get());
+ InitWithSyncDataTakeOutput(ConvertToRemote(in), &out);
+
+ // The previous session should be preserved, and the transient window should
+ // be synced as a new transient window. This means that the original tab
+ // node will be updated with its new tab id, a new tab node will be created,
+ // and the header will be updated to reflect the two windows and two tabs.
+ ASSERT_TRUE(
+ ChangeTypeMatches(out, {SyncChange::ACTION_UPDATE, SyncChange::ACTION_ADD,
+ SyncChange::ACTION_UPDATE}));
+ VerifyLocalTabChange(out[0], 2, kFoo2);
+ VerifyLocalTabChange(out[1], 1, kBar1);
+ VerifyLocalHeaderChange(out[2], 2, 2);
+
+ // The two windows should have different window types.
+ ASSERT_EQ(sync_pb::SessionWindow::TYPE_CUSTOM_TAB, out[2]
+ .sync_data()
+ .GetSpecifics()
+ .session()
+ .header()
+ .window(0)
+ .browser_type());
+ ASSERT_EQ(sync_pb::SessionWindow::TYPE_TABBED, out[2]
+ .sync_data()
+ .GetSpecifics()
+ .session()
+ .header()
+ .window(1)
+ .browser_type());
+
+ // Verify the tab id of the restored tab is updated and consistent.
+ int restored_tab_id =
+ out[0].sync_data().GetSpecifics().session().tab().tab_id();
+ // SessionId should be rewritten on restore.
+ ASSERT_NE(tab->GetSessionId(), restored_tab_id);
+ ASSERT_EQ(
+ restored_tab_id,
+ out[2].sync_data().GetSpecifics().session().header().window(1).tab(0));
+
+ // Verify the tab id of the custom tab is consistent.
+ int custom_tab_id =
+ out[1].sync_data().GetSpecifics().session().tab().tab_id();
+ ASSERT_EQ(custom_tab->GetSessionId(), custom_tab_id);
+ ASSERT_EQ(
+ custom_tab_id,
+ out[2].sync_data().GetSpecifics().session().header().window(0).tab(0));
+}
+
// Tests MergeDataAndStartSyncing with sync data but no local data.
TEST_F(SessionsSyncManagerTest, MergeWithInitialForeignSession) {
std::vector<SessionID::id_type> tab_list1(std::begin(kTabIds1),
@@ -1565,7 +1695,8 @@ TEST_F(SessionsSyncManagerTest, ProcessForeignDeleteTabsWithReusedNodeIds) {
TEST_F(SessionsSyncManagerTest, AssociationReusesNodes) {
SyncChangeList changes;
- AddTab(AddWindow()->GetSessionId(), kFoo1);
+ TestSyncedWindowDelegate* window = AddWindow();
+ TestSyncedTabDelegate* tab = AddTab(window->GetSessionId(), kFoo1);
InitWithSyncDataTakeOutput(SyncDataList(), &changes);
ASSERT_TRUE(ChangeTypeMatches(changes,
{SyncChange::ACTION_ADD, SyncChange::ACTION_ADD,
@@ -1582,9 +1713,9 @@ TEST_F(SessionsSyncManagerTest, AssociationReusesNodes) {
sync_pb::SessionSpecifics new_tab(
changes[1].sync_data().GetSpecifics().session());
new_tab.set_tab_node_id(tab_node_id + 1);
- in.push_back(CreateRemoteData(new_tab)); // New tab node.
in.push_back(CreateRemoteData(
changes[1].sync_data().GetSpecifics())); // Old tab node.
+ in.push_back(CreateRemoteData(new_tab)); // New tab node.
changes.clear();
// Reassociate (with the same single tab/window open).
@@ -1598,6 +1729,24 @@ TEST_F(SessionsSyncManagerTest, AssociationReusesNodes) {
VerifyLocalTabChange(changes[0], 1, kFoo1);
EXPECT_EQ(tab_node_id,
changes[0].sync_data().GetSpecifics().session().tab_node_id());
+ changes.clear();
+
+ // Update the original tab. Ensure the same tab node is updated.
+ NavigateTab(tab, kFoo2);
+ FilterOutLocalHeaderChanges(&changes);
+ ASSERT_TRUE(ChangeTypeMatches(changes, {SyncChange::ACTION_UPDATE}));
+ VerifyLocalTabChange(changes[0], 2, kFoo2);
+ EXPECT_EQ(tab_node_id,
+ changes[0].sync_data().GetSpecifics().session().tab_node_id());
+ changes.clear();
+
+ // Add a new tab. It should reuse the second tab node.
+ AddTab(window->GetSessionId(), kBar1);
+ FilterOutLocalHeaderChanges(&changes);
+ ASSERT_TRUE(ChangeTypeMatches(changes, {SyncChange::ACTION_UPDATE}));
+ VerifyLocalTabChange(changes[0], 1, kBar1);
+ EXPECT_EQ(tab_node_id + 1,
+ changes[0].sync_data().GetSpecifics().session().tab_node_id());
}
// Ensure that the merge process deletes a tab node without a tab id.
@@ -2396,12 +2545,12 @@ TEST_F(SessionsSyncManagerTest, PlaceholderConflictAcrossWindows) {
// The tab entity will be overwritten twice. Once with the information for
// tab 1 and then again with the information for tab 2. This will be followed
- // by a header change reflecting both tabs.
+ // by a header change reflecting only the final tab.
ASSERT_TRUE(
ChangeTypeMatches(out,
{SyncChange::ACTION_UPDATE, SyncChange::ACTION_UPDATE,
SyncChange::ACTION_UPDATE}));
- VerifyLocalHeaderChange(out[2], 2, 2);
+ VerifyLocalHeaderChange(out[2], 2, 1);
VerifyLocalTabChange(out[0], 1, kFoo1);
EXPECT_EQ(sync_id, out[0].sync_data().GetSpecifics().session().tab_node_id());
EXPECT_EQ(tab1->GetSessionId(),
@@ -2415,4 +2564,53 @@ TEST_F(SessionsSyncManagerTest, PlaceholderConflictAcrossWindows) {
out[1].sync_data().GetSpecifics().session().tab().window_id());
}
+// Tests that task ids are generated for navigations on local tabs.
+TEST_F(SessionsSyncManagerTest, TrackTasksOnLocalTabModified) {
+ SyncChangeList changes;
+ TestSyncedWindowDelegate* window = AddWindow();
+ InitWithSyncDataTakeOutput(SyncDataList(), &changes);
+ SessionID::id_type window_id = window->GetSessionId();
+ ASSERT_FALSE(manager()->current_machine_tag().empty());
+ changes.clear();
+
+ // Tab 1
+ NavigateTab(AddTab(window_id, kFoo1), kFoo2, ui::PAGE_TRANSITION_TYPED);
+ // Tab 2
+ NavigateTab(AddTab(window_id, kBar1), kBar2, ui::PAGE_TRANSITION_LINK);
+
+ // We only test changes for tab add and tab update, and ignore header updates.
+ FilterOutLocalHeaderChanges(&changes);
+ // Sync data of adding Tab 1 change
+ sync_pb::SessionTab tab =
+ SyncDataLocal(changes[0].sync_data()).GetSpecifics().session().tab();
+ EXPECT_EQ(tab.navigation_size(), 1);
+ EXPECT_EQ(tab.navigation(0).global_id(), tab.navigation(0).task_id());
+ EXPECT_TRUE(tab.navigation(0).ancestor_task_id().empty());
+
+ // Sync data of updating Tab 1 change
+ tab = SyncDataLocal(changes[1].sync_data()).GetSpecifics().session().tab();
+ EXPECT_EQ(tab.navigation_size(), 2);
+ // navigation(0) and navigation(1) are two seperated tasks.
+ EXPECT_EQ(tab.navigation(0).global_id(), tab.navigation(0).task_id());
+ EXPECT_TRUE(tab.navigation(0).ancestor_task_id().empty());
+ EXPECT_EQ(tab.navigation(1).global_id(), tab.navigation(1).task_id());
+ EXPECT_TRUE(tab.navigation(1).ancestor_task_id().empty());
+
+ // Sync data of adding Tab 2 change
+ tab = SyncDataLocal(changes[2].sync_data()).GetSpecifics().session().tab();
+ EXPECT_EQ(tab.navigation_size(), 1);
+ EXPECT_EQ(tab.navigation(0).global_id(), tab.navigation(0).task_id());
+ EXPECT_TRUE(tab.navigation(0).ancestor_task_id().empty());
+
+ // Sync data of updating Tab 2 change
+ tab = SyncDataLocal(changes[3].sync_data()).GetSpecifics().session().tab();
+ EXPECT_EQ(tab.navigation_size(), 2);
+ EXPECT_EQ(tab.navigation(0).global_id(), tab.navigation(0).task_id());
+ EXPECT_TRUE(tab.navigation(0).ancestor_task_id().empty());
+ EXPECT_EQ(tab.navigation(1).global_id(), tab.navigation(1).task_id());
+ // navigation(1) is a subtask of navigation(0).
+ EXPECT_EQ(tab.navigation(1).ancestor_task_id_size(), 1);
+ EXPECT_EQ(tab.navigation(1).ancestor_task_id(0), tab.navigation(0).task_id());
+}
+
} // namespace sync_sessions
diff --git a/chromium/components/sync_sessions/synced_session_tracker.cc b/chromium/components/sync_sessions/synced_session_tracker.cc
index 94e6e9ff386..08c0933070f 100644
--- a/chromium/components/sync_sessions/synced_session_tracker.cc
+++ b/chromium/components/sync_sessions/synced_session_tracker.cc
@@ -221,6 +221,12 @@ bool SyncedSessionTracker::IsTabUnmappedForTesting(SessionID::id_type tab_id) {
void SyncedSessionTracker::PutWindowInSession(const std::string& session_tag,
SessionID::id_type window_id) {
+ if (GetSession(session_tag)->windows.find(window_id) !=
+ GetSession(session_tag)->windows.end()) {
+ DVLOG(1) << "Window " << window_id << " already added to session "
+ << session_tag;
+ return;
+ }
std::unique_ptr<SyncedSessionWindow> window;
auto iter = unmapped_windows_[session_tag].find(window_id);
@@ -345,9 +351,7 @@ sessions::SessionTab* SyncedSessionTracker::GetTab(
return tab_ptr;
}
-void SyncedSessionTracker::CleanupForeignSession(
- const std::string& session_tag) {
- DCHECK_NE(local_session_tag_, session_tag);
+void SyncedSessionTracker::CleanupSession(const std::string& session_tag) {
CleanupSessionImpl(session_tag);
}
@@ -365,13 +369,11 @@ void SyncedSessionTracker::CleanupLocalTabs(std::set<int>* deleted_node_ids) {
bool SyncedSessionTracker::GetTabNodeFromLocalTabId(SessionID::id_type tab_id,
int* tab_node_id) {
DCHECK(!local_session_tag_.empty());
- // Ensure a placeholder SessionTab is in place, if not already.
- // Although we don't need a SessionTab to fulfill this request, this forces
- // the
- // creation of one if it doesn't already exist. This helps to make sure we're
- // tracking this |tab_id| if |local_tab_pool_| is, and everyone's data
- // structures
- // are kept in sync and as consistent as possible.
+ // Ensure a placeholder SessionTab is in place, if not already. Although we
+ // don't need a SessionTab to fulfill this request, this forces the creation
+ // of one if it doesn't already exist. This helps to make sure we're tracking
+ // this |tab_id| if |local_tab_pool_| is, and everyone's data structures are
+ // kept in sync and as consistent as possible.
GetTab(local_session_tag_, tab_id); // Ignore result.
bool reused_existing_tab =
@@ -395,33 +397,70 @@ void SyncedSessionTracker::ReassociateLocalTab(int tab_node_id,
SessionID::id_type old_tab_id =
local_tab_pool_.GetTabIdFromTabNodeId(tab_node_id);
+ if (new_tab_id == old_tab_id) {
+ return;
+ }
+
local_tab_pool_.ReassociateTabNode(tab_node_id, new_tab_id);
sessions::SessionTab* tab_ptr = nullptr;
+ auto new_tab_iter = synced_tab_map_[local_session_tag_].find(new_tab_id);
auto old_tab_iter = synced_tab_map_[local_session_tag_].find(old_tab_id);
if (old_tab_id != kInvalidTabID &&
old_tab_iter != synced_tab_map_[local_session_tag_].end()) {
tab_ptr = old_tab_iter->second;
+ DCHECK(tab_ptr);
+
// Remove the tab from the synced tab map under the old id.
synced_tab_map_[local_session_tag_].erase(old_tab_iter);
- } else {
+
+ if (new_tab_iter != synced_tab_map_[local_session_tag_].end()) {
+ // If both the old and the new tab already exist, delete the new tab
+ // and use the old tab in its place.
+ auto unmapped_tabs_iter =
+ unmapped_tabs_[local_session_tag_].find(new_tab_id);
+ if (unmapped_tabs_iter != unmapped_tabs_[local_session_tag_].end()) {
+ unmapped_tabs_[local_session_tag_].erase(unmapped_tabs_iter);
+ } else {
+ sessions::SessionTab* new_tab_ptr = new_tab_iter->second;
+ for (auto& window_iter_pair : GetSession(local_session_tag_)->windows) {
+ auto& window_tabs = window_iter_pair.second->wrapped_window.tabs;
+ auto tab_iter = std::find_if(
+ window_tabs.begin(), window_tabs.end(),
+ [&new_tab_ptr](const std::unique_ptr<sessions::SessionTab>& tab) {
+ return tab.get() == new_tab_ptr;
+ });
+ if (tab_iter != window_tabs.end()) {
+ window_tabs.erase(tab_iter);
+ break;
+ }
+ }
+ }
+
+ synced_tab_map_[local_session_tag_].erase(new_tab_iter);
+ }
+
+ // If the old tab is unmapped, update the tab id under which it is
+ // indexed.
+ auto unmapped_tabs_iter =
+ unmapped_tabs_[local_session_tag_].find(old_tab_id);
+ if (old_tab_id != kInvalidTabID &&
+ unmapped_tabs_iter != unmapped_tabs_[local_session_tag_].end()) {
+ std::unique_ptr<sessions::SessionTab> tab =
+ std::move(unmapped_tabs_iter->second);
+ DCHECK_EQ(tab_ptr, tab.get());
+ unmapped_tabs_[local_session_tag_].erase(unmapped_tabs_iter);
+ unmapped_tabs_[local_session_tag_][new_tab_id] = std::move(tab);
+ }
+ }
+
+ if (tab_ptr == nullptr) {
// It's possible a placeholder is already in place for the new tab. If so,
// reuse it, otherwise create a new one (which will default to unmapped).
tab_ptr = GetTab(local_session_tag_, new_tab_id);
}
- // If the old tab is unmapped, update the tab id under which it is indexed.
- auto unmapped_tabs_iter = unmapped_tabs_[local_session_tag_].find(old_tab_id);
- if (old_tab_id != kInvalidTabID &&
- unmapped_tabs_iter != unmapped_tabs_[local_session_tag_].end()) {
- std::unique_ptr<sessions::SessionTab> tab =
- std::move(unmapped_tabs_iter->second);
- DCHECK_EQ(tab_ptr, tab.get());
- unmapped_tabs_[local_session_tag_].erase(unmapped_tabs_iter);
- unmapped_tabs_[local_session_tag_][new_tab_id] = std::move(tab);
- }
-
// Update the tab id.
if (old_tab_id != kInvalidTabID) {
DVLOG(1) << "Remapped tab " << old_tab_id << " with node " << tab_node_id
diff --git a/chromium/components/sync_sessions/synced_session_tracker.h b/chromium/components/sync_sessions/synced_session_tracker.h
index 506d3d0cbee..84269352e2d 100644
--- a/chromium/components/sync_sessions/synced_session_tracker.h
+++ b/chromium/components/sync_sessions/synced_session_tracker.h
@@ -96,10 +96,15 @@ class SyncedSessionTracker {
// tabs not owned.
void ResetSessionTracking(const std::string& session_tag);
+ // Deletes those windows and tabs associated with |session_tag| that are no
+ // longer owned. See ResetSessionTracking(...)..
+ void CleanupSession(const std::string& session_tag);
+
// Adds the window with id |window_id| to the session specified by
// |session_tag|. If none existed for that session, creates one. Similarly, if
// the session did not exist yet, creates it. Ownership of the SessionWindow
// remains within the SyncedSessionTracker.
+ // Attempting to add a window to a session multiple times will have no effect.
void PutWindowInSession(const std::string& session_tag,
SessionID::id_type window_id);
@@ -145,10 +150,6 @@ class SyncedSessionTracker {
// Returns true if the session existed and was deleted, false otherwise.
bool DeleteForeignSession(const std::string& session_tag);
- // Deletes those windows and tabs associated with |session_tag| that are no
- // longer owned. See ResetSessionTracking(...)..
- void CleanupForeignSession(const std::string& session_tag);
-
// **** Methods specific to the local session. ****
// Set the local session tag. Must be called before any other local session
@@ -173,6 +174,9 @@ class SyncedSessionTracker {
// any previous SessionTab object the node was associated with. This is useful
// on restart when sync needs to reassociate tabs from a previous session with
// newly restored tabs (and can be used in conjunction with PutTabInWindow).
+ // If |new_tab_id| is already associated with a tab object, that tab will be
+ // overwritten. Reassociating a tab with a node it is already mapped to will
+ // have no effect.
void ReassociateLocalTab(int tab_node_id, SessionID::id_type new_tab_id);
// **** Methods for querying/manipulating overall state ****.
diff --git a/chromium/components/sync_sessions/synced_session_tracker_unittest.cc b/chromium/components/sync_sessions/synced_session_tracker_unittest.cc
index 9da19516ab0..88cdf646fa2 100644
--- a/chromium/components/sync_sessions/synced_session_tracker_unittest.cc
+++ b/chromium/components/sync_sessions/synced_session_tracker_unittest.cc
@@ -12,6 +12,10 @@
#include "components/sync_sessions/synced_tab_delegate.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::AssertionFailure;
+using testing::AssertionResult;
+using testing::AssertionSuccess;
+
namespace sync_sessions {
namespace {
@@ -23,7 +27,9 @@ const char kTag2[] = "tag2";
const char kTag3[] = "tag3";
const char kTitle[] = "title";
const int kWindow1 = 1;
-const int kTabNode = 0;
+const int kTabNode1 = 1;
+const int kTabNode2 = 2;
+const int kTabNode3 = 3;
const int kTab1 = 15;
const int kTab2 = 25;
const int kTab3 = 35;
@@ -38,6 +44,63 @@ class SyncedSessionTrackerTest : public testing::Test {
SyncedSessionTracker* GetTracker() { return &tracker_; }
TabNodePool* GetTabNodePool() { return &tracker_.local_tab_pool_; }
+ // Verify that each tab within a session is allocated one SessionTab object,
+ // and that that tab object is owned either by the Session itself or the
+ // |unmapped_tabs_| tab holder.
+ AssertionResult VerifyTabIntegrity(const std::string& session_tag) {
+ // First get all the tabs associated with this session.
+ int total_tab_count = 0;
+ auto tab_map_iter = tracker_.synced_tab_map_.find(session_tag);
+ if (tab_map_iter != tracker_.synced_tab_map_.end())
+ total_tab_count = tab_map_iter->second.size();
+
+ // Now traverse the SyncedSession tree to verify the mapped tabs all match
+ // up.
+ int mapped_tab_count = 0;
+ if (tracker_.synced_session_map_.find(session_tag) !=
+ tracker_.synced_session_map_.end()) {
+ SyncedSession* session = tracker_.synced_session_map_[session_tag].get();
+ for (auto& window_pair : session->windows) {
+ mapped_tab_count += window_pair.second->wrapped_window.tabs.size();
+ for (auto& tab : window_pair.second->wrapped_window.tabs) {
+ if (tab_map_iter->second[tab->tab_id.id()] != tab.get()) {
+ return AssertionFailure()
+ << "Mapped tab " << tab->tab_id.id()
+ << " does not match synced tab map " << tab->tab_id.id();
+ }
+ }
+ }
+ }
+
+ // Wrap up by verifying all unmapped tabs are tracked.
+ int unmapped_tab_count = 0;
+ if (tracker_.unmapped_tabs_.find(session_tag) !=
+ tracker_.unmapped_tabs_.end()) {
+ unmapped_tab_count = tracker_.unmapped_tabs_[session_tag].size();
+ for (const auto& tab_pair : tracker_.unmapped_tabs_[session_tag]) {
+ if (tab_pair.first != tab_pair.second->tab_id.id()) {
+ return AssertionFailure()
+ << "Unmapped tab " << tab_pair.second->tab_id.id()
+ << " associated with wrong tab " << tab_pair.first;
+ }
+ if (tab_map_iter->second[tab_pair.second->tab_id.id()] !=
+ tab_pair.second.get()) {
+ return AssertionFailure()
+ << "Unmapped tab " << tab_pair.second->tab_id.id()
+ << " does not match synced tab map "
+ << tab_pair.second->tab_id.id();
+ }
+ }
+ }
+
+ return mapped_tab_count + unmapped_tab_count == total_tab_count
+ ? AssertionSuccess()
+ : AssertionFailure()
+ << " Tab count mismatch. Total: " << total_tab_count
+ << ". Mapped + Unmapped: " << mapped_tab_count << " + "
+ << unmapped_tab_count;
+ }
+
private:
FakeSyncSessionsClient sessions_client_;
SyncedSessionTracker tracker_;
@@ -61,6 +124,10 @@ TEST_F(SyncedSessionTrackerTest, PutWindowInSession) {
GetTracker()->PutWindowInSession(kTag, 0);
SyncedSession* session = GetTracker()->GetSession(kTag);
ASSERT_EQ(1U, session->windows.size());
+
+ // Doing it again should have no effect.
+ GetTracker()->PutWindowInSession(kTag, 0);
+ ASSERT_EQ(1U, session->windows.size());
// Should clean up memory on its own.
}
@@ -72,6 +139,7 @@ TEST_F(SyncedSessionTrackerTest, PutTabInWindow) {
ASSERT_EQ(1U, session->windows[10]->wrapped_window.tabs.size());
ASSERT_EQ(GetTracker()->GetTab(kTag, 15),
session->windows[10]->wrapped_window.tabs[0].get());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
// Should clean up memory on its own.
}
@@ -198,6 +266,7 @@ TEST_F(SyncedSessionTrackerTest, Complex) {
ASSERT_EQ(0U, GetTracker()->num_synced_tabs(kTag));
ASSERT_EQ(0U, GetTracker()->num_synced_tabs(kTag2));
ASSERT_EQ(0U, GetTracker()->num_synced_sessions());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
}
TEST_F(SyncedSessionTrackerTest, ManyGetTabs) {
@@ -324,7 +393,7 @@ TEST_F(SyncedSessionTrackerTest, SessionTracking) {
// Window 1 was closed, along with tab 5.
GetTracker()->PutTabInWindow(kTag, 0, 6); // No longer unmapped.
// Session 2 should not be affected.
- GetTracker()->CleanupForeignSession(kTag);
+ GetTracker()->CleanupSession(kTag);
// Verify that only those parts of the session not owned have been removed.
ASSERT_EQ(1U, session1->windows.size());
@@ -334,6 +403,7 @@ TEST_F(SyncedSessionTrackerTest, SessionTracking) {
ASSERT_EQ(2U, GetTracker()->num_synced_sessions());
ASSERT_EQ(4U, GetTracker()->num_synced_tabs(kTag));
ASSERT_EQ(1U, GetTracker()->num_synced_tabs(kTag2));
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
// All memory should be properly deallocated by destructor for the
// SyncedSessionTracker.
@@ -360,14 +430,12 @@ TEST_F(SyncedSessionTrackerTest, DeleteForeignTab) {
GetTracker()->DeleteForeignTab(kTag, tab_node_id_2);
GetTracker()->LookupForeignTabNodeIds(kTag, &result);
EXPECT_TRUE(result.empty());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
}
TEST_F(SyncedSessionTrackerTest, CleanupLocalTabs) {
std::set<int> free_node_ids;
int tab_node_id = TabNodePool::kInvalidTabNodeID;
- const int kTabNode1 = 1;
- const int kTabNode2 = 2;
- const int kTabNode3 = 3;
GetTracker()->SetLocalSessionTag(kTag);
@@ -420,6 +488,7 @@ TEST_F(SyncedSessionTrackerTest, CleanupLocalTabs) {
EXPECT_TRUE(free_node_ids.empty());
EXPECT_TRUE(GetTabNodePool()->Full());
EXPECT_FALSE(GetTabNodePool()->Empty());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
}
TEST_F(SyncedSessionTrackerTest, ReassociateTabMapped) {
@@ -427,9 +496,10 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMapped) {
// First create the tab normally.
GetTracker()->SetLocalSessionTag(kTag);
- EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
- GetTracker()->ReassociateLocalTab(kTabNode, kTab1);
- EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+ EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab1));
// Map it to a window with the same tab id as it was created with.
@@ -437,6 +507,7 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMapped) {
GetTracker()->PutWindowInSession(kTag, kWindow1);
GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
SyncedSession* session = GetTracker()->GetSession(kTag);
ASSERT_EQ(1U, session->windows.size());
@@ -445,8 +516,9 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMapped) {
session->windows[kWindow1]->wrapped_window.tabs[0].get());
// Then reassociate with a new tab id.
- GetTracker()->ReassociateLocalTab(kTabNode, kTab2);
- EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab2);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
@@ -456,6 +528,7 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMapped) {
GetTracker()->PutWindowInSession(kTag, kWindow1);
GetTracker()->PutTabInWindow(kTag, kWindow1, kTab2);
GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
EXPECT_TRUE(free_node_ids.empty());
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
@@ -464,8 +537,9 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMapped) {
ASSERT_EQ(GetTracker()->GetTab(kTag, kTab2),
session->windows[kWindow1]->wrapped_window.tabs[0].get());
ASSERT_EQ(session->tab_node_ids.size(),
- session->tab_node_ids.count(kTabNode));
+ session->tab_node_ids.count(kTabNode1));
ASSERT_EQ(1U, GetTabNodePool()->Capacity());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
}
TEST_F(SyncedSessionTrackerTest, ReassociateTabMappedTwice) {
@@ -473,9 +547,10 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMappedTwice) {
// First create the tab normally.
GetTracker()->SetLocalSessionTag(kTag);
- EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
- GetTracker()->ReassociateLocalTab(kTabNode, kTab1);
- EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+ EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab1));
// Map it to a window with the same tab id as it was created with.
@@ -483,6 +558,7 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMappedTwice) {
GetTracker()->PutWindowInSession(kTag, kWindow1);
GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
EXPECT_TRUE(free_node_ids.empty());
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
SyncedSession* session = GetTracker()->GetSession(kTag);
@@ -492,8 +568,9 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMappedTwice) {
session->windows[kWindow1]->wrapped_window.tabs[0].get());
// Then reassociate with a new tab id.
- GetTracker()->ReassociateLocalTab(kTabNode, kTab2);
- EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab2);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
@@ -510,6 +587,7 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMappedTwice) {
GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
GetTracker()->PutTabInWindow(kTag, kWindow1, kTab2);
GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
EXPECT_TRUE(free_node_ids.empty());
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
@@ -518,7 +596,7 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMappedTwice) {
EXPECT_EQ(GetTracker()->GetTab(kTag, kTab2),
session->windows[kWindow1]->wrapped_window.tabs[1].get());
EXPECT_EQ(session->tab_node_ids.size(),
- session->tab_node_ids.count(kTabNode));
+ session->tab_node_ids.count(kTabNode1));
EXPECT_EQ(1U, GetTabNodePool()->Capacity());
// Attempting to access the original tab will create a new SessionTab object.
@@ -526,6 +604,7 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabMappedTwice) {
GetTracker()->GetTab(kTag, kTab2));
int tab_node_id = -1;
EXPECT_FALSE(GetTracker()->GetTabNodeFromLocalTabId(kTab1, &tab_node_id));
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
}
TEST_F(SyncedSessionTrackerTest, ReassociateTabUnmapped) {
@@ -533,21 +612,62 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabUnmapped) {
// First create the old tab in an unmapped state.
GetTracker()->SetLocalSessionTag(kTag);
- EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
- GetTracker()->ReassociateLocalTab(kTabNode, kTab1);
- EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+ EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab1));
// Map it to a window, but reassociated with a new tab id.
GetTracker()->ResetSessionTracking(kTag);
- GetTracker()->ReassociateLocalTab(kTabNode, kTab2);
- EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab2);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab2));
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
GetTracker()->PutWindowInSession(kTag, kWindow1);
GetTracker()->PutTabInWindow(kTag, kWindow1, kTab2);
GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(free_node_ids.empty());
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
+
+ // Now that it's been mapped, it should be accessible both via the
+ // GetSession as well as GetTab.
+ SyncedSession* session = GetTracker()->GetSession(kTag);
+ ASSERT_EQ(GetTracker()->GetTab(kTag, kTab2),
+ session->windows[kWindow1]->wrapped_window.tabs[0].get());
+ ASSERT_EQ(session->tab_node_ids.size(),
+ session->tab_node_ids.count(kTabNode1));
+ ASSERT_EQ(1U, GetTabNodePool()->Capacity());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+}
+
+TEST_F(SyncedSessionTrackerTest, ReassociateTabOldUnmappedNewMapped) {
+ std::set<int> free_node_ids;
+
+ // First create the old tab in an unmapped state.
+ GetTracker()->SetLocalSessionTag(kTag);
+ EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+
+ // Map an unseen tab to a window, then reassociate the existing tab to the
+ // mapped tab id.
+ GetTracker()->ResetSessionTracking(kTag);
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ GetTracker()->PutWindowInSession(kTag, kWindow1);
+ GetTracker()->PutTabInWindow(kTag, kWindow1, kTab2);
+ GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab2);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
EXPECT_TRUE(free_node_ids.empty());
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
// Now that it's been mapped, it should be accessible both via the
@@ -556,8 +676,114 @@ TEST_F(SyncedSessionTrackerTest, ReassociateTabUnmapped) {
ASSERT_EQ(GetTracker()->GetTab(kTag, kTab2),
session->windows[kWindow1]->wrapped_window.tabs[0].get());
ASSERT_EQ(session->tab_node_ids.size(),
- session->tab_node_ids.count(kTabNode));
+ session->tab_node_ids.count(kTabNode1));
+ ASSERT_EQ(1U, GetTabNodePool()->Capacity());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+}
+
+TEST_F(SyncedSessionTrackerTest, ReassociateTabSameTabId) {
+ std::set<int> free_node_ids;
+
+ // First create the tab normally.
+ GetTracker()->SetLocalSessionTag(kTag);
+ EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+
+ // Map it to a window.
+ GetTracker()->ResetSessionTracking(kTag);
+ GetTracker()->PutWindowInSession(kTag, kWindow1);
+ GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
+ GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+ SyncedSession* session = GetTracker()->GetSession(kTag);
+ ASSERT_EQ(1U, session->windows.size());
+ ASSERT_EQ(1U, session->windows[kWindow1]->wrapped_window.tabs.size());
+ ASSERT_EQ(GetTracker()->GetTab(kTag, kTab1),
+ session->windows[kWindow1]->wrapped_window.tabs[0].get());
+
+ // Reassociate, using the same tab id.
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+
+ // Reset tracking, and put the tab id back into the same window.
+ GetTracker()->ResetSessionTracking(kTag);
+ EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+ GetTracker()->PutWindowInSession(kTag, kWindow1);
+ GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
+ GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(free_node_ids.empty());
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+
+ // Now that it's been mapped, it should be accessible both via the
+ // GetSession as well as the GetTab.
+ ASSERT_EQ(GetTracker()->GetTab(kTag, kTab1),
+ session->windows[kWindow1]->wrapped_window.tabs[0].get());
+ ASSERT_EQ(session->tab_node_ids.size(),
+ session->tab_node_ids.count(kTabNode1));
ASSERT_EQ(1U, GetTabNodePool()->Capacity());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+}
+
+TEST_F(SyncedSessionTrackerTest, ReassociateTabOldMappedNewUnmapped) {
+ std::set<int> free_node_ids;
+
+ // First create an unmapped tab.
+ GetTracker()->SetLocalSessionTag(kTag);
+ EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+
+ // Now, map the first one, deleting the second one.
+ GetTracker()->ResetSessionTracking(kTag);
+ GetTracker()->PutWindowInSession(kTag, kWindow1);
+ GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
+ GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+ SyncedSession* session = GetTracker()->GetSession(kTag);
+ ASSERT_EQ(1U, session->windows.size());
+ ASSERT_EQ(1U, session->windows[kWindow1]->wrapped_window.tabs.size());
+ ASSERT_EQ(GetTracker()->GetTab(kTag, kTab1),
+ session->windows[kWindow1]->wrapped_window.tabs[0].get());
+
+ // Create a second unmapped tab.
+ GetTracker()->ReassociateLocalTab(kTabNode2, kTab2);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode2));
+ EXPECT_TRUE(GetTracker()->IsTabUnmappedForTesting(kTab2));
+
+ // Reassociate the second tab with node of the first tab.
+ GetTracker()->ReassociateLocalTab(kTabNode1, kTab2);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1));
+ EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode2));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
+
+ // Now map the new one.
+ GetTracker()->ResetSessionTracking(kTag);
+ GetTracker()->PutWindowInSession(kTag, kWindow1);
+ GetTracker()->PutTabInWindow(kTag, kWindow1, kTab2);
+ GetTracker()->CleanupLocalTabs(&free_node_ids);
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab1));
+ EXPECT_FALSE(GetTracker()->IsTabUnmappedForTesting(kTab2));
+
+ // Now that it's been mapped, it should be accessible both via the
+ // GetSession as well as the GetTab.
+ ASSERT_EQ(GetTracker()->GetTab(kTag, kTab2),
+ session->windows[kWindow1]->wrapped_window.tabs[0].get());
+ ASSERT_EQ(2U, GetTabNodePool()->Capacity());
+ ASSERT_TRUE(VerifyTabIntegrity(kTag));
}
} // namespace sync_sessions
diff --git a/chromium/components/sync_sessions/task_tracker.cc b/chromium/components/sync_sessions/task_tracker.cc
new file mode 100644
index 00000000000..0f8902e2905
--- /dev/null
+++ b/chromium/components/sync_sessions/task_tracker.cc
@@ -0,0 +1,173 @@
+// Copyright 2017 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/sync_sessions/task_tracker.h"
+
+#include <utility>
+
+#include "base/numerics/safe_conversions.h"
+
+namespace sync_sessions {
+
+namespace {
+// The maximum number of tasks we track in a tab.
+int kMaxNumTasksPerTab = 100;
+}
+
+TabTasks::TabTasks() {}
+
+TabTasks::~TabTasks() {}
+
+std::vector<int64_t> TabTasks::GetTaskIdsForNavigation(
+ int navigation_index) const {
+ CHECK_LE(0, navigation_index);
+ CHECK_LT(navigation_index, GetNavigationsCount());
+
+ std::vector<int64_t> root_to_self_task_ids;
+ // Position of the navigation in task_ids_ vector.
+ int navigation_position = navigation_index - excluded_navigation_num_;
+
+ // If navigation_index is an excluded ancestor task, returns empty.
+ if (navigation_position < 0)
+ return root_to_self_task_ids;
+
+ TaskIdAndRoot task_id_and_root = task_ids_[navigation_position];
+
+ // If navigation_index is an invalid task, returns empty.
+ if (task_id_and_root.root_navigation_index < 0)
+ return root_to_self_task_ids;
+
+ // The root task can be excluded. If so, consider the oldest ancestor
+ // available as root.
+ int root_navigation_index =
+ task_id_and_root.root_navigation_index > excluded_navigation_num_
+ ? task_id_and_root.root_navigation_index - excluded_navigation_num_
+ : 0;
+ for (int i = root_navigation_index; i <= navigation_position; i++) {
+ // Fills the vector with valid tasks.
+ if (task_ids_[i].root_navigation_index >= 0)
+ root_to_self_task_ids.push_back(task_ids_[i].task_id);
+ }
+ return root_to_self_task_ids;
+}
+
+int TabTasks::GetNavigationsCount() const {
+ return excluded_navigation_num_ + task_ids_.size();
+}
+
+void TabTasks::UpdateWithNavigation(int navigation_index,
+ ui::PageTransition transition,
+ int64_t navigation_id) {
+ // Triggered by some notifications on the current page, do nothing.
+ if (navigation_index == current_navigation_index_) {
+ DVLOG(1) << "Doing nothing for navigation_index: " << navigation_index
+ << " of transition: " << transition;
+ return;
+ }
+
+ // Going back/forward to some previous navigation.
+ if (navigation_index < current_navigation_index_ ||
+ (navigation_index > current_navigation_index_ &&
+ transition & ui::PAGE_TRANSITION_FORWARD_BACK &&
+ base::checked_cast<size_t>(navigation_index) < task_ids_.size())) {
+ DVLOG(1) << "Just updating task position with navigation_index: "
+ << navigation_index << " of transition: " << transition;
+ current_navigation_index_ = navigation_index;
+ return;
+ }
+
+ // A new task for the new navigation.
+ int root_navigation_index = navigation_index;
+ if (current_navigation_index_ != -1 &&
+ (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK) ||
+ ui::PageTransitionCoreTypeIs(transition,
+ ui::PAGE_TRANSITION_AUTO_SUBFRAME) ||
+ ui::PageTransitionCoreTypeIs(transition,
+ ui::PAGE_TRANSITION_MANUAL_SUBFRAME) ||
+ ui::PageTransitionCoreTypeIs(transition,
+ ui::PAGE_TRANSITION_FORM_SUBMIT) ||
+ transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK)) {
+ // Creating a sub-task with navigation at current_navigation_index as
+ // parent.
+ DVLOG(1) << "Creating a sub-task with navigation_index: "
+ << navigation_index << " of transition: " << transition
+ << " under navigation_index: " << current_navigation_index_;
+ // Position in task_id_.
+ int current_navigation_position =
+ current_navigation_index_ - excluded_navigation_num_;
+ // If current/parent task is excluded, consider the new task as a root task.
+ if (current_navigation_position >= 0) {
+ CHECK_LT(current_navigation_position,
+ base::checked_cast<int>(task_ids_.size()));
+ root_navigation_index =
+ task_ids_[current_navigation_position].root_navigation_index;
+ } else {
+ DVLOG(1) << "Becaue parent task is excluded, consider the sub-task as a "
+ "root task.";
+ }
+ } else {
+ // Creating a root task.
+ // For now, we don't consider tasks cross tabs, so first navigation of the
+ // tab always creates a root task.
+ DVLOG(1) << "Creating a root task with navigation_index: "
+ << navigation_index << " of transition: " << transition;
+ }
+
+ // In most cases navigation_index == excluded_navigation_num_ +
+ // task_ids_.size() if the previous navigation is end of chain, or
+ // navigation_index < excluded_navigation_num_ + task_ids_.size() otherwise.
+ // In few case navigation_index > excluded_navigation_num_ + task_ids_.size(),
+ // we fill task_ids_ with invalid contents. A known case is the first
+ // navigation after newtab.
+ for (int i = task_ids_.size() + excluded_navigation_num_;
+ i < navigation_index; i++) {
+ task_ids_.push_back({-1, -1});
+ }
+
+ // Erase all task ids associated with an outdated forward navigation stack.
+ if (navigation_index > excluded_navigation_num_) {
+ int new_task_id_position = navigation_index - excluded_navigation_num_;
+ task_ids_.erase(task_ids_.begin() + new_task_id_position, task_ids_.end());
+ } else {
+ excluded_navigation_num_ = navigation_index;
+ // new task id position is 0
+ task_ids_.clear();
+ }
+
+ // Exclude oldest ancestors if task number reaches the limit.
+ int more_tasks_number = task_ids_.size() + 1 - kMaxNumTasksPerTab;
+ if (more_tasks_number > 0) {
+ task_ids_.erase(task_ids_.begin(), task_ids_.begin() + more_tasks_number);
+ DVLOG(1) << "Excluding " << more_tasks_number
+ << " oldest ancestor(s) from navigation index "
+ << excluded_navigation_num_;
+ excluded_navigation_num_ += more_tasks_number;
+ }
+
+ TaskIdAndRoot new_task = {root_navigation_index, navigation_id};
+ // Add the current task at navigation_index.
+ task_ids_.push_back(new_task);
+ current_navigation_index_ = navigation_index;
+ return;
+}
+
+TaskTracker::TaskTracker() {}
+
+TaskTracker::~TaskTracker() {}
+
+TabTasks* TaskTracker::GetTabTasks(SessionID::id_type tab_id) {
+ if (local_tab_tasks_map_.find(tab_id) == local_tab_tasks_map_.end()) {
+ local_tab_tasks_map_[tab_id] = base::MakeUnique<TabTasks>();
+ }
+ return local_tab_tasks_map_[tab_id].get();
+}
+
+void TaskTracker::CleanTabTasks(SessionID::id_type tab_id) {
+ auto iter = local_tab_tasks_map_.find(tab_id);
+ if (iter != local_tab_tasks_map_.end()) {
+ local_tab_tasks_map_.erase(iter);
+ }
+}
+
+} // namespace sync_sessions
diff --git a/chromium/components/sync_sessions/task_tracker.h b/chromium/components/sync_sessions/task_tracker.h
new file mode 100644
index 00000000000..44ee36368a6
--- /dev/null
+++ b/chromium/components/sync_sessions/task_tracker.h
@@ -0,0 +1,102 @@
+// Copyright 2017 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_SYNC_SESSIONS_TASK_TRACKER_H_
+#define COMPONENTS_SYNC_SESSIONS_TASK_TRACKER_H_
+
+#include <stddef.h>
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "base/time/clock.h"
+#include "base/time/default_clock.h"
+#include "base/time/time.h"
+#include "components/sessions/core/session_id.h"
+#include "components/sessions/core/session_types.h"
+#include "components/sync_sessions/synced_tab_delegate.h"
+#include "ui/base/page_transition_types.h"
+
+namespace sync_sessions {
+
+// Class to generate and manage task ids for navigations of a tab. For each
+// current navigation of a tab, UpdateWithNavigation(int navigation_index,
+// ui::PageTransition transition)
+// needs to be called to update the object.
+//
+// TODO(shenchao): If the tab is restored, then the input navigation is not
+// necessarily the first navigation in this case. Need to fix it by initalizing
+// the object with restored data.
+// TODO(shenchao): Support to track tasks cross tabs.
+class TabTasks {
+ public:
+ TabTasks();
+ virtual ~TabTasks();
+
+ // Gets top-down task id list of ancestors and itself for
+ // |navigation_index|-th navigation of the tab.
+ std::vector<int64_t> GetTaskIdsForNavigation(int navigation_index) const;
+
+ int GetNavigationsCount() const;
+
+ // Updates the current task of the tab, given current navigation index of the
+ // tab as |navigation_index|, and its |transition|.
+ // If the navigation is from going back/forward of the tab, we set its first
+ // visit as current task; if the navigation is new, we create a subtask of the
+ // previous navigation if it's linked from the previous one or a root task
+ // otherwise, and use |navigation_id| as new task id.
+ void UpdateWithNavigation(int navigation_index,
+ ui::PageTransition transition,
+ int64_t navigation_id);
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(TaskTrackerTest, LimitMaxNumberOfTasksPerTab);
+
+ FRIEND_TEST_ALL_PREFIXES(TaskTrackerTest,
+ CreateSubTaskFromExcludedAncestorTask);
+
+ struct TaskIdAndRoot {
+ // Root task index in task_ids_. Negative value means it's an invalid task
+ // just for filling the task_ids_.
+ int root_navigation_index;
+ int64_t task_id;
+ };
+
+ // Task ids (with root task) for the navigations of the tab. The vector is
+ // corresponding to the sequence of navigations of the tab.
+ std::vector<TaskIdAndRoot> task_ids_;
+ // Index of current navigation in task_ids_.
+ int current_navigation_index_ = -1;
+ // Number of oldest ancestors which have been excluded from being tracked in
+ // task_ids_;
+ int excluded_navigation_num_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(TabTasks);
+};
+
+// Tracks tasks of current session.
+class TaskTracker {
+ public:
+ // Constructs with a clock to get timestamp as new task ids.
+ TaskTracker();
+ virtual ~TaskTracker();
+
+ // Returns a TabTasks pointer, which is owned by this object, for the tab of
+ // given |tab_id|.
+ TabTasks* GetTabTasks(SessionID::id_type tab_id);
+
+ // Cleans tracked task ids of navigations in the tab of |tab_id|.
+ void CleanTabTasks(SessionID::id_type tab_id);
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(TaskTrackerTest, CleanTabTasks);
+ std::map<SessionID::id_type, std::unique_ptr<TabTasks>> local_tab_tasks_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskTracker);
+};
+
+} // namespace sync_sessions
+
+#endif // COMPONENTS_SYNC_SESSIONS_TASK_TRACKER_H_
diff --git a/chromium/components/sync_sessions/task_tracker_unittest.cc b/chromium/components/sync_sessions/task_tracker_unittest.cc
new file mode 100644
index 00000000000..40fd0424d4d
--- /dev/null
+++ b/chromium/components/sync_sessions/task_tracker_unittest.cc
@@ -0,0 +1,198 @@
+// Copyright 2017 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/sync_sessions/task_tracker.h"
+
+#include <utility>
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+using testing::SizeIs;
+
+namespace sync_sessions {
+
+namespace {
+const int kTab1 = 15;
+const int kTab2 = 25;
+} // namespace
+
+TEST(TaskTrackerTest, GetTabTasks) {
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+ ASSERT_NE(tab_tasks, nullptr);
+ EXPECT_EQ(task_tracker.GetTabTasks(kTab1), tab_tasks);
+ EXPECT_NE(task_tracker.GetTabTasks(kTab2), tab_tasks);
+}
+
+TEST(TaskTrackerTest, CleanTabTasks) {
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+ ASSERT_NE(tab_tasks, nullptr);
+ ASSERT_FALSE(task_tracker.local_tab_tasks_map_.empty());
+
+ task_tracker.CleanTabTasks(kTab1);
+ EXPECT_TRUE(task_tracker.local_tab_tasks_map_.empty());
+}
+
+TEST(TaskTrackerTest, UpdateTasksWithMultipleClicks) {
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+
+ tab_tasks->UpdateWithNavigation(1, ui::PageTransition::PAGE_TRANSITION_TYPED,
+ 100);
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+
+ tab_tasks->UpdateWithNavigation(2, ui::PageTransition::PAGE_TRANSITION_LINK,
+ 200);
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(2), ElementsAre(100, 200));
+
+ tab_tasks->UpdateWithNavigation(3, ui::PageTransition::PAGE_TRANSITION_LINK,
+ 300);
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(2), ElementsAre(100, 200));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(3),
+ ElementsAre(100, 200, 300));
+}
+
+TEST(TaskTrackerTest, UpdateTasksWithMultipleClicksAndTypes) {
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+
+ tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK, 100);
+ tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
+ tab_tasks->UpdateWithNavigation(3, ui::PAGE_TRANSITION_LINK, 300);
+ tab_tasks->UpdateWithNavigation(4, ui::PAGE_TRANSITION_TYPED, 400);
+ tab_tasks->UpdateWithNavigation(5, ui::PAGE_TRANSITION_LINK, 500);
+ tab_tasks->UpdateWithNavigation(6, ui::PAGE_TRANSITION_TYPED, 600);
+ tab_tasks->UpdateWithNavigation(7, ui::PAGE_TRANSITION_LINK, 700);
+
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(2), ElementsAre(100, 200));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(3),
+ ElementsAre(100, 200, 300));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(4), ElementsAre(400));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(5), ElementsAre(400, 500));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(6), ElementsAre(600));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(7), ElementsAre(600, 700));
+}
+
+TEST(TaskTrackerTest, UpdateTasksWithBackforwards) {
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+
+ tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_TYPED, 100);
+ tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
+ tab_tasks->UpdateWithNavigation(3, ui::PAGE_TRANSITION_LINK, 300);
+
+ tab_tasks->UpdateWithNavigation(
+ 1,
+ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
+ ui::PAGE_TRANSITION_FORWARD_BACK),
+ 400);
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(2), ElementsAre(100, 200));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(3),
+ ElementsAre(100, 200, 300));
+
+ tab_tasks->UpdateWithNavigation(
+ 3,
+ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
+ ui::PAGE_TRANSITION_FORWARD_BACK),
+ 500);
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(2), ElementsAre(100, 200));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(3),
+ ElementsAre(100, 200, 300));
+}
+
+TEST(TaskTrackerTest, UpdateWithNavigationsWithBackAndForkedNavigation) {
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+ tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK, 100);
+ tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
+ tab_tasks->UpdateWithNavigation(3, ui::PAGE_TRANSITION_LINK, 300);
+ tab_tasks->UpdateWithNavigation(
+ 1,
+ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
+ ui::PAGE_TRANSITION_FORWARD_BACK),
+ 400);
+ tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 500);
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(2), ElementsAre(100, 500));
+ // We don't track navigation at index 3 any more, and it's out of scope now.
+ EXPECT_THAT(tab_tasks->GetNavigationsCount(), 3);
+}
+
+TEST(TaskTrackerTest, LimitMaxNumberOfTasksPerTab) {
+ int kMaxNumTasksPerTab = 100;
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+
+ // Reaching max number of tasks for a tab.
+ for (int i = 0; i < kMaxNumTasksPerTab; i++) {
+ tab_tasks->UpdateWithNavigation(i, ui::PAGE_TRANSITION_LINK, i * 100);
+ }
+
+ tab_tasks->UpdateWithNavigation(kMaxNumTasksPerTab, ui::PAGE_TRANSITION_LINK,
+ kMaxNumTasksPerTab * 100);
+
+ ASSERT_THAT(tab_tasks->task_ids_, SizeIs(kMaxNumTasksPerTab));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(0), ElementsAre());
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre(100));
+ std::vector<int64_t> task_ids =
+ tab_tasks->GetTaskIdsForNavigation(kMaxNumTasksPerTab);
+ EXPECT_THAT(task_ids, SizeIs(kMaxNumTasksPerTab));
+ EXPECT_EQ(task_ids[0], 100);
+ EXPECT_EQ(task_ids[kMaxNumTasksPerTab - 1], kMaxNumTasksPerTab * 100);
+
+ tab_tasks->UpdateWithNavigation(kMaxNumTasksPerTab + 1,
+ ui::PAGE_TRANSITION_LINK,
+ (kMaxNumTasksPerTab + 1) * 100);
+
+ ASSERT_THAT(tab_tasks->task_ids_, SizeIs(kMaxNumTasksPerTab));
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(0), ElementsAre());
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1), ElementsAre());
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(2), ElementsAre(200));
+ task_ids = tab_tasks->GetTaskIdsForNavigation(kMaxNumTasksPerTab + 1);
+ EXPECT_THAT(task_ids, SizeIs(kMaxNumTasksPerTab));
+ EXPECT_EQ(task_ids[0], 200);
+ EXPECT_EQ(task_ids[kMaxNumTasksPerTab - 1], (kMaxNumTasksPerTab + 1) * 100);
+}
+
+TEST(TaskTrackerTest, CreateSubTaskFromExcludedAncestorTask) {
+ int kMaxNumTasksPerTab = 100;
+ TaskTracker task_tracker;
+ TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1);
+
+ // Reaching max number of tasks for a tab.
+ for (int i = 0; i < kMaxNumTasksPerTab; i++) {
+ tab_tasks->UpdateWithNavigation(i, ui::PAGE_TRANSITION_LINK, i * 100);
+ }
+
+ tab_tasks->UpdateWithNavigation(kMaxNumTasksPerTab, ui::PAGE_TRANSITION_LINK,
+ kMaxNumTasksPerTab * 100);
+ ASSERT_EQ(tab_tasks->excluded_navigation_num_, 1);
+ ASSERT_EQ(tab_tasks->current_navigation_index_, kMaxNumTasksPerTab);
+
+ tab_tasks->UpdateWithNavigation(
+ 0,
+ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
+ ui::PAGE_TRANSITION_FORWARD_BACK),
+ (kMaxNumTasksPerTab + 1) * 100);
+ ASSERT_EQ(tab_tasks->excluded_navigation_num_, 1);
+ ASSERT_EQ(tab_tasks->current_navigation_index_, 0);
+
+ tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK,
+ (kMaxNumTasksPerTab + 2) * 100);
+ ASSERT_THAT(tab_tasks->task_ids_, SizeIs(1));
+ ASSERT_EQ(tab_tasks->GetNavigationsCount(), 2);
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(0), ElementsAre());
+ EXPECT_THAT(tab_tasks->GetTaskIdsForNavigation(1),
+ ElementsAre((kMaxNumTasksPerTab + 2) * 100));
+}
+
+} // namespace sync_sessions
diff --git a/chromium/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc b/chromium/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc
index 1f142a16ce3..882a83934fa 100644
--- a/chromium/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc
+++ b/chromium/components/sync_wifi/wifi_config_delegate_chromeos_unittest.cc
@@ -109,7 +109,8 @@ class FakeManagedNetworkConfigurationHandler
}
const base::DictionaryValue* FindPolicyByGuidAndProfile(
const std::string& guid,
- const std::string& profile_path) const override {
+ const std::string& profile_path,
+ ::onc::ONCSource* onc_source) const override {
NOTIMPLEMENTED();
return nullptr;
}
diff --git a/chromium/components/test/BUILD.gn b/chromium/components/test/BUILD.gn
index 02f9527de0f..0a62f38f655 100644
--- a/chromium/components/test/BUILD.gn
+++ b/chromium/components/test/BUILD.gn
@@ -14,6 +14,7 @@ source_set("test_support") {
"//components/content_settings/core/common",
"//components/gcm_driver:gcm_driver",
"//components/signin/core/browser",
+ "//mojo/edk/system",
"//net",
"//testing/gtest",
"//ui/base",
diff --git a/chromium/components/toolbar/BUILD.gn b/chromium/components/toolbar/BUILD.gn
index 66164fc0744..0f1cc9f0e6a 100644
--- a/chromium/components/toolbar/BUILD.gn
+++ b/chromium/components/toolbar/BUILD.gn
@@ -24,6 +24,16 @@ aggregate_vector_icons("toolbar_vector_icons") {
]
}
+static_library("vector_icons") {
+ sources = get_target_outputs(":toolbar_vector_icons")
+ deps = [
+ ":toolbar_vector_icons",
+ "//skia",
+ "//ui/gfx",
+ "//ui/vector_icons",
+ ]
+}
+
static_library("toolbar") {
sources = [
"toolbar_model.h",
@@ -50,11 +60,7 @@ static_library("toolbar") {
]
if (!is_android && !is_ios) {
- sources += get_target_outputs(":toolbar_vector_icons")
- deps += [
- ":toolbar_vector_icons",
- "//ui/vector_icons",
- ]
+ deps += [ ":vector_icons" ]
}
}
@@ -66,9 +72,12 @@ static_library("test_support") {
"test_toolbar_model.h",
]
- deps = [
+ public_deps = [
":toolbar",
"//base",
+ ]
+
+ deps = [
"//components/resources",
"//ui/gfx",
]
diff --git a/chromium/components/tracing/child/child_trace_message_filter.cc b/chromium/components/tracing/child/child_trace_message_filter.cc
index 2cd76dc7b2a..ce9c86f75f6 100644
--- a/chromium/components/tracing/child/child_trace_message_filter.cc
+++ b/chromium/components/tracing/child/child_trace_message_filter.cc
@@ -202,7 +202,7 @@ void ChildTraceMessageFilter::OnSetUMACallback(
while (!sample_iterator->Done()) {
base::HistogramBase::Sample min;
- base::HistogramBase::Sample max;
+ int64_t max;
base::HistogramBase::Count count;
sample_iterator->Get(&min, &max, &count);
diff --git a/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc b/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc
index 2936256acd3..829f47e76e6 100644
--- a/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc
+++ b/chromium/components/tracing/common/process_metrics_memory_dump_provider.cc
@@ -180,15 +180,18 @@ uint32_t ReadLinuxProcSmapsFile(FILE* smaps_file,
return num_valid_regions;
}
-bool GetResidentSizeFromStatmFile(int fd, uint64_t* resident_pages) {
+bool GetResidentAndSharedPagesFromStatmFile(int fd,
+ uint64_t* resident_pages,
+ uint64_t* shared_pages) {
lseek(fd, 0, SEEK_SET);
char line[kMaxLineSize];
int res = read(fd, line, kMaxLineSize - 1);
if (res <= 0)
return false;
line[res] = '\0';
- int num_scanned = sscanf(line, "%*s %" SCNu64, resident_pages);
- return num_scanned == 1;
+ int num_scanned =
+ sscanf(line, "%*s %" SCNu64 " %" SCNu64, resident_pages, shared_pages);
+ return num_scanned == 2;
}
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
@@ -614,6 +617,14 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals(
pmd->process_totals()->SetExtraFieldInBytes("private_bytes", private_bytes);
pmd->process_totals()->SetExtraFieldInBytes("shared_bytes", shared_bytes);
pmd->process_totals()->SetExtraFieldInBytes("locked_bytes", locked_bytes);
+
+ base::trace_event::ProcessMemoryTotals::PlatformPrivateFootprint footprint;
+ base::ProcessMetrics::TaskVMInfo info = process_metrics_->GetTaskVMInfo();
+ footprint.phys_footprint_bytes = info.phys_footprint;
+ footprint.internal_bytes = info.internal;
+ footprint.compressed_bytes = info.compressed;
+
+ pmd->process_totals()->SetPlatformPrivateFootprint(footprint);
#else
uint64_t rss_bytes = process_metrics_->GetWorkingSetSize();
#endif // defined(OS_MACOSX)
@@ -626,6 +637,40 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals(
uint64_t peak_rss_bytes = 0;
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ base::trace_event::ProcessMemoryTotals::PlatformPrivateFootprint footprint;
+
+ base::ScopedFD autoclose;
+ int statm_fd = fast_polling_statm_fd_.get();
+ if (statm_fd == -1) {
+ autoclose = OpenStatm();
+ statm_fd = autoclose.get();
+ }
+ if (statm_fd == -1)
+ return false;
+ const static size_t page_size = base::GetPageSize();
+ uint64_t resident_pages;
+ uint64_t shared_pages;
+ bool success = GetResidentAndSharedPagesFromStatmFile(
+ statm_fd, &resident_pages, &shared_pages);
+ if (!success)
+ return false;
+
+ footprint.rss_anon_bytes = (resident_pages - shared_pages) * page_size;
+ footprint.vm_swap_bytes = process_metrics_->GetVmSwapBytes();
+ pmd->process_totals()->SetPlatformPrivateFootprint(footprint);
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
+#if defined(OS_WIN)
+ {
+ size_t private_bytes;
+ base::trace_event::ProcessMemoryTotals::PlatformPrivateFootprint footprint;
+ process_metrics_->GetMemoryBytes(&private_bytes, nullptr);
+ footprint.private_bytes = private_bytes;
+ pmd->process_totals()->SetPlatformPrivateFootprint(footprint);
+ }
+#endif
+
#if !defined(OS_IOS)
peak_rss_bytes = process_metrics_->GetPeakWorkingSetSize();
#if defined(OS_LINUX) || defined(OS_ANDROID)
@@ -669,31 +714,41 @@ bool ProcessMetricsMemoryDumpProvider::DumpProcessTotals(
return true;
}
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+base::ScopedFD ProcessMetricsMemoryDumpProvider::OpenStatm() {
+ std::string name =
+ "/proc/" +
+ (process_ == base::kNullProcessId ? "self"
+ : base::IntToString(process_)) +
+ "/statm";
+ base::ScopedFD fd = base::ScopedFD(open(name.c_str(), O_RDONLY));
+ DCHECK(fd.is_valid());
+ return fd;
+}
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
void ProcessMetricsMemoryDumpProvider::PollFastMemoryTotal(
uint64_t* memory_total) {
*memory_total = 0;
#if defined(OS_LINUX) || defined(OS_ANDROID)
+
int statm_fd = fast_polling_statm_fd_for_testing;
if (statm_fd == -1) {
- if (!fast_polling_statm_fd_.is_valid()) {
- std::string name = "/proc/" + (process_ == base::kNullProcessId
- ? "self"
- : base::IntToString(process_)) +
- "/statm";
- fast_polling_statm_fd_.reset(open(name.c_str(), O_RDONLY));
- DCHECK(fast_polling_statm_fd_.is_valid());
- }
+ if (!fast_polling_statm_fd_.is_valid())
+ fast_polling_statm_fd_ = OpenStatm();
statm_fd = fast_polling_statm_fd_.get();
+ if (statm_fd == -1)
+ return;
}
- if (statm_fd == -1)
- return;
- uint64_t rss_pages = 0;
- if (!GetResidentSizeFromStatmFile(statm_fd, &rss_pages))
+ uint64_t resident_pages = 0;
+ uint64_t ignored_shared_pages = 0;
+ if (!GetResidentAndSharedPagesFromStatmFile(statm_fd, &resident_pages,
+ &ignored_shared_pages))
return;
static size_t page_size = base::GetPageSize();
- *memory_total = rss_pages * page_size;
+ *memory_total = resident_pages * page_size;
#else
*memory_total = process_metrics_->GetWorkingSetSize();
#endif
diff --git a/chromium/components/tracing/common/process_metrics_memory_dump_provider.h b/chromium/components/tracing/common/process_metrics_memory_dump_provider.h
index 730a9be97d2..d3c53344907 100644
--- a/chromium/components/tracing/common/process_metrics_memory_dump_provider.h
+++ b/chromium/components/tracing/common/process_metrics_memory_dump_provider.h
@@ -75,6 +75,8 @@ class TRACING_EXPORT ProcessMetricsMemoryDumpProvider
static int fast_polling_statm_fd_for_testing;
base::ScopedFD fast_polling_statm_fd_;
+
+ base::ScopedFD OpenStatm();
#endif
base::ProcessId process_;
diff --git a/chromium/components/translate/core/browser/BUILD.gn b/chromium/components/translate/core/browser/BUILD.gn
index 1e56c7eae3f..45e0c2b0fe9 100644
--- a/chromium/components/translate/core/browser/BUILD.gn
+++ b/chromium/components/translate/core/browser/BUILD.gn
@@ -32,6 +32,8 @@ static_library("browser") {
"translate_language_list.h",
"translate_manager.cc",
"translate_manager.h",
+ "translate_pref_names.cc",
+ "translate_pref_names.h",
"translate_prefs.cc",
"translate_prefs.h",
"translate_ranker.h",
diff --git a/chromium/components/translate/core/common/BUILD.gn b/chromium/components/translate/core/common/BUILD.gn
index 237c1aee014..f8038c92d81 100644
--- a/chromium/components/translate/core/common/BUILD.gn
+++ b/chromium/components/translate/core/common/BUILD.gn
@@ -11,8 +11,6 @@ static_library("common") {
"translate_errors.h",
"translate_metrics.cc",
"translate_metrics.h",
- "translate_pref_names.cc",
- "translate_pref_names.h",
"translate_switches.cc",
"translate_switches.h",
"translate_util.cc",
diff --git a/chromium/components/translate/ios/browser/BUILD.gn b/chromium/components/translate/ios/browser/BUILD.gn
index f4b7c5db0a2..3ef1f8d203d 100644
--- a/chromium/components/translate/ios/browser/BUILD.gn
+++ b/chromium/components/translate/ios/browser/BUILD.gn
@@ -57,7 +57,7 @@ source_set("unit_tests") {
"//base",
"//components/prefs:test_support",
"//components/resources",
- "//components/translate/core/common",
+ "//components/translate/core/browser",
"//ios/web:test_support",
"//testing/gtest",
"//third_party/ocmock",
diff --git a/chromium/components/ui_devtools/devtools_server.cc b/chromium/components/ui_devtools/devtools_server.cc
index 5ed57945189..2bab50aafc4 100644
--- a/chromium/components/ui_devtools/devtools_server.cc
+++ b/chromium/components/ui_devtools/devtools_server.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -74,7 +75,7 @@ std::unique_ptr<UiDevToolsServer> UiDevToolsServer::Create(
if (IsUiDevToolsEnabled() && !devtools_server_) {
// TODO(mhashmi): Change port if more than one inspectable clients
server.reset(new UiDevToolsServer(io_thread_task_runner));
- server->Start("127.0.0.1", GetUiDevToolsPort());
+ server->Start("0.0.0.0", GetUiDevToolsPort());
}
return server;
}
@@ -90,9 +91,8 @@ UiDevToolsServer::GetClientNamesAndUrls() {
i++) {
pairs.push_back(std::pair<std::string, std::string>(
devtools_server_->clients_[i]->name(),
- base::StringPrintf("%slocalhost:%d/%" PRIuS,
- kChromeDeveloperToolsPrefix, GetUiDevToolsPort(),
- i)));
+ base::StringPrintf("%s0.0.0.0:%d/%" PRIuS, kChromeDeveloperToolsPrefix,
+ GetUiDevToolsPort(), i)));
}
return pairs;
}
diff --git a/chromium/components/ui_devtools/devtools_server.h b/chromium/components/ui_devtools/devtools_server.h
index 7dfc02cb5e1..04483cc899c 100644
--- a/chromium/components/ui_devtools/devtools_server.h
+++ b/chromium/components/ui_devtools/devtools_server.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/compiler_specific.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "components/ui_devtools/DOM.h"
#include "components/ui_devtools/Forward.h"
diff --git a/chromium/components/ukm/BUILD.gn b/chromium/components/ukm/BUILD.gn
index dc9c405b757..ab5807fd644 100644
--- a/chromium/components/ukm/BUILD.gn
+++ b/chromium/components/ukm/BUILD.gn
@@ -11,12 +11,10 @@ static_library("ukm") {
sources = [
"persisted_logs_metrics_impl.cc",
"persisted_logs_metrics_impl.h",
- "ukm_entry.cc",
- "ukm_entry.h",
- "ukm_entry_builder.cc",
- "ukm_entry_builder.h",
"ukm_pref_names.cc",
"ukm_pref_names.h",
+ "ukm_recorder_impl.cc",
+ "ukm_recorder_impl.h",
"ukm_reporting_service.cc",
"ukm_reporting_service.h",
"ukm_rotation_scheduler.cc",
@@ -27,6 +25,12 @@ static_library("ukm") {
"ukm_source.h",
]
+ public_deps = [
+ "//components/metrics/proto",
+ "//components/ukm/public",
+ "//components/ukm/public/interfaces",
+ ]
+
deps = [
"//base",
"//components/data_use_measurement/core",
@@ -56,12 +60,13 @@ static_library("observers") {
static_library("test_support") {
testonly = true
sources = [
- "test_ukm_service.cc",
- "test_ukm_service.h",
+ "test_ukm_recorder.cc",
+ "test_ukm_recorder.h",
]
public_deps = [
":ukm",
+ "//components/metrics/proto",
]
deps = [
"//base",
@@ -90,7 +95,7 @@ source_set("unit_tests") {
"//components/variations",
"//net:test_support",
"//testing/gtest",
- "//third_party/zlib:compression_utils",
+ "//third_party/zlib/google:compression_utils",
"//url",
]
}
diff --git a/chromium/components/ukm/DEPS b/chromium/components/ukm/DEPS
index 6a9008e619f..abd3591f71b 100644
--- a/chromium/components/ukm/DEPS
+++ b/chromium/components/ukm/DEPS
@@ -2,5 +2,6 @@ include_rules = [
"+components/metrics",
"+components/prefs",
"+components/variations",
+ "+mojo/public",
"+third_party/zlib/google",
]
diff --git a/chromium/components/ukm/debug_page/BUILD.gn b/chromium/components/ukm/debug_page/BUILD.gn
new file mode 100644
index 00000000000..9fa09128304
--- /dev/null
+++ b/chromium/components/ukm/debug_page/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2017 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.
+
+static_library("debug_page") {
+ sources = [
+ "debug_page.cc",
+ "debug_page.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/ukm",
+ "//content/public/browser",
+ "//url",
+ ]
+}
diff --git a/chromium/components/ukm/debug_page/DEPS b/chromium/components/ukm/debug_page/DEPS
new file mode 100644
index 00000000000..fe7bb13183f
--- /dev/null
+++ b/chromium/components/ukm/debug_page/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+content/public",
+]
diff --git a/chromium/components/ukm/debug_page/debug_page.cc b/chromium/components/ukm/debug_page/debug_page.cc
new file mode 100644
index 00000000000..72df62fea95
--- /dev/null
+++ b/chromium/components/ukm/debug_page/debug_page.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2017 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/ukm/debug_page/debug_page.h"
+
+#include <inttypes.h>
+
+#include "base/memory/ref_counted_memory.h"
+#include "base/strings/stringprintf.h"
+#include "components/ukm/ukm_service.h"
+#include "components/ukm/ukm_source.h"
+#include "url/gurl.h"
+
+namespace ukm {
+namespace debug {
+
+DebugPage::DebugPage(ServiceGetter service_getter)
+ : service_getter_(service_getter) {}
+
+DebugPage::~DebugPage() {}
+
+std::string DebugPage::GetSource() const {
+ return "ukm";
+}
+
+std::string DebugPage::GetMimeType(const std::string& path) const {
+ return "text/html";
+}
+
+void DebugPage::StartDataRequest(
+ const std::string& path,
+ const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
+ const content::URLDataSource::GotDataCallback& callback) {
+ std::string data;
+ data.append(R"""(<!DOCTYPE html>
+ <html>
+ <head>
+ <meta http-equiv="Content-Security-Policy"
+ content="object-src 'none'; script-src 'none'">
+ <title>UKM Debug</title>
+ </head>
+ <body>
+ <h1>UKM Debug page</h1>
+ )""");
+ UkmService* ukm_service = service_getter_.Run();
+ if (ukm_service) {
+ data.append(
+ base::StringPrintf("<p>IsEnabled:%s</p>",
+ ukm_service->recording_enabled_ ? "True" : "False"));
+ data.append(base::StringPrintf("<p>ClientId:%" PRIu64 "</p>",
+ ukm_service->client_id_));
+ data.append(
+ base::StringPrintf("<p>SessionId:%d</p>", ukm_service->session_id_));
+
+ data.append("<h2>Sources</h2>");
+ for (const auto& kv : ukm_service->sources_) {
+ const auto* src = kv.second.get();
+ data.append(base::StringPrintf("<p>Id:%" PRId64 " Url:%s</p>", src->id(),
+ src->url().spec().c_str()));
+ }
+
+ data.append("<h2>Entries</h2>");
+ for (const auto& v : ukm_service->entries_) {
+ const auto* entry = v.get();
+ data.append(base::StringPrintf("<h3>Id:%" PRId64 " Hash:%" PRIu64 "</h3>",
+ entry->source_id, entry->event_hash));
+ }
+ }
+
+ data.append(R"""(
+ </body>
+ </html>
+ )""");
+
+ callback.Run(base::RefCountedString::TakeString(&data));
+}
+
+bool DebugPage::AllowCaching() const {
+ return false;
+}
+
+} // namespace debug
+} // namespace ukm
diff --git a/chromium/components/ukm/debug_page/debug_page.h b/chromium/components/ukm/debug_page/debug_page.h
new file mode 100644
index 00000000000..52ae7a167af
--- /dev/null
+++ b/chromium/components/ukm/debug_page/debug_page.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2017 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_UKM_DEBUG_PAGE_REQUEST_JOB_H_
+#define COMPONENTS_UKM_DEBUG_PAGE_REQUEST_JOB_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "content/public/browser/url_data_source.h"
+
+namespace ukm {
+
+class UkmService;
+
+namespace debug {
+
+// Implements the chrome://ukm page for debugging UKM state.
+class DebugPage : public content::URLDataSource {
+ public:
+ typedef base::Callback<UkmService*()> ServiceGetter;
+
+ explicit DebugPage(ServiceGetter service_getter);
+
+ // content::URLDataSource:
+ std::string GetSource() const override;
+ std::string GetMimeType(const std::string& path) const override;
+ void StartDataRequest(
+ const std::string& path,
+ const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
+ const content::URLDataSource::GotDataCallback& callback) override;
+ bool AllowCaching() const override;
+
+ private:
+ ~DebugPage() override;
+
+ ServiceGetter service_getter_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DebugPage);
+};
+
+} // namespace debug
+} // namespace ukm
+
+#endif // COMPONENTS_UKM_DEBUG_PAGE_REQUEST_JOB_H_
diff --git a/chromium/components/ukm/public/BUILD.gn b/chromium/components/ukm/public/BUILD.gn
new file mode 100644
index 00000000000..1383752327d
--- /dev/null
+++ b/chromium/components/ukm/public/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2017 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+component("public") {
+ sources = [
+ "ukm_entry_builder.cc",
+ "ukm_entry_builder.h",
+ "ukm_export.h",
+ "ukm_recorder.cc",
+ "ukm_recorder.h",
+ ]
+
+ defines = [ "UKM_IMPLEMENTATION" ]
+
+ public_deps = [
+ "//base",
+ "//components/ukm/public/interfaces",
+ "//url",
+ ]
+
+ deps = [
+ "//mojo/public/cpp/bindings",
+ ]
+}
diff --git a/chromium/components/ukm/public/interfaces/BUILD.gn b/chromium/components/ukm/public/interfaces/BUILD.gn
new file mode 100644
index 00000000000..b4804bedb30
--- /dev/null
+++ b/chromium/components/ukm/public/interfaces/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2017 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+ sources = [
+ "ukm_interface.mojom",
+ ]
+
+ public_deps = [
+ "//url/mojo:url_mojom_gurl",
+ ]
+}
diff --git a/chromium/components/ukm/public/interfaces/OWNERS b/chromium/components/ukm/public/interfaces/OWNERS
new file mode 100644
index 00000000000..08850f42120
--- /dev/null
+++ b/chromium/components/ukm/public/interfaces/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/ukm/public/interfaces/ukm_interface.mojom b/chromium/components/ukm/public/interfaces/ukm_interface.mojom
new file mode 100644
index 00000000000..0625916b88a
--- /dev/null
+++ b/chromium/components/ukm/public/interfaces/ukm_interface.mojom
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+module ukm.mojom;
+
+import "url/mojo/url.mojom";
+
+struct UkmMetric {
+ uint64 metric_hash;
+ int64 value;
+};
+
+struct UkmEntry {
+ int64 source_id;
+ uint64 event_hash;
+ array<UkmMetric> metrics;
+};
+
+interface UkmRecorderInterface {
+ AddEntry(UkmEntry entry);
+};
diff --git a/chromium/components/ukm/public/ukm_entry_builder.cc b/chromium/components/ukm/public/ukm_entry_builder.cc
new file mode 100644
index 00000000000..72a227acc08
--- /dev/null
+++ b/chromium/components/ukm/public/ukm_entry_builder.cc
@@ -0,0 +1,32 @@
+// Copyright 2017 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/ukm/public/ukm_entry_builder.h"
+
+#include <memory>
+
+#include "base/metrics/metrics_hashes.h"
+#include "components/ukm/public/interfaces/ukm_interface.mojom.h"
+
+namespace ukm {
+
+UkmEntryBuilder::UkmEntryBuilder(
+ const UkmEntryBuilder::AddEntryCallback& callback,
+ ukm::SourceId source_id,
+ const char* event_name)
+ : add_entry_callback_(callback), entry_(mojom::UkmEntry::New()) {
+ entry_->source_id = source_id;
+ entry_->event_hash = base::HashMetricName(event_name);
+}
+
+UkmEntryBuilder::~UkmEntryBuilder() {
+ add_entry_callback_.Run(std::move(entry_));
+}
+
+void UkmEntryBuilder::AddMetric(const char* metric_name, int64_t value) {
+ entry_->metrics.emplace_back(
+ mojom::UkmMetric::New(base::HashMetricName(metric_name), value));
+}
+
+} // namespace ukm
diff --git a/chromium/components/ukm/ukm_entry_builder.h b/chromium/components/ukm/public/ukm_entry_builder.h
index e2400ee5cb5..1c9facfe039 100644
--- a/chromium/components/ukm/ukm_entry_builder.h
+++ b/chromium/components/ukm/public/ukm_entry_builder.h
@@ -8,19 +8,19 @@
#include <string>
#include "base/macros.h"
-#include "components/ukm/ukm_service.h"
+#include "components/ukm/public/interfaces/ukm_interface.mojom.h"
+#include "components/ukm/public/ukm_export.h"
namespace ukm {
-class UkmEntry;
-class UkmService;
+typedef int64_t SourceId;
-// The builder that builds UkmEntry and adds it to UkmService.
+// The builder that builds UkmEntry and adds it to UkmRecorder.
// The example usage is:
//
// {
// unique_ptr<UkmEntryBuilder> builder =
-// ukm_service->GetEntryBuilder(source_id, "PageLoad");
+// ukm_recorder->GetEntryBuilder(source_id, "PageLoad");
// builder->AddMetric("NavigationStart", navigation_start_time);
// builder->AddMetric("ResponseStart", response_start_time);
// builder->AddMetric("FirstPaint", first_paint_time);
@@ -29,22 +29,20 @@ class UkmService;
//
// When there exists an added metric, the builder will automatically add the
// UkmEntry to UkmService upon destruction when going out of scope.
-class UkmEntryBuilder {
+class UKM_EXPORT UkmEntryBuilder {
public:
+ using AddEntryCallback = base::Callback<void(mojom::UkmEntryPtr)>;
+ UkmEntryBuilder(const AddEntryCallback& callback,
+ ukm::SourceId source_id,
+ const char* event_name);
+ ~UkmEntryBuilder();
+
// Add metric to the entry. A metric contains a metric name and value.
void AddMetric(const char* metric_name, int64_t value);
- ~UkmEntryBuilder();
-
private:
- friend class UkmService;
-
- UkmEntryBuilder(const UkmService::AddEntryCallback& callback,
- int32_t source_id,
- const char* event_name);
-
- UkmService::AddEntryCallback add_entry_callback_;
- std::unique_ptr<UkmEntry> entry_;
+ AddEntryCallback add_entry_callback_;
+ mojom::UkmEntryPtr entry_;
DISALLOW_COPY_AND_ASSIGN(UkmEntryBuilder);
};
diff --git a/chromium/components/ukm/public/ukm_export.h b/chromium/components/ukm/public/ukm_export.h
new file mode 100644
index 00000000000..6c460eb5834
--- /dev/null
+++ b/chromium/components/ukm/public/ukm_export.h
@@ -0,0 +1,29 @@
+// Copyright 2017 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_UKM_PUBLIC_UKM_EXPORT_H_
+#define COMPONENTS_UKM_PUBLIC_UKM_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(UKM_IMPLEMENTATION)
+#define UKM_EXPORT __declspec(dllexport)
+#else
+#define UKM_EXPORT __declspec(dllimport)
+#endif // defined(UKM_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(UKM_IMPLEMENTATION)
+#define UKM_EXPORT __attribute__((visibility("default")))
+#else
+#define UKM_EXPORT
+#endif
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define UKM_EXPORT
+#endif
+
+#endif // COMPONENTS_UKM_PUBLIC_UKM_EXPORT_H_
diff --git a/chromium/components/ukm/public/ukm_recorder.cc b/chromium/components/ukm/public/ukm_recorder.cc
new file mode 100644
index 00000000000..25fdcb822f1
--- /dev/null
+++ b/chromium/components/ukm/public/ukm_recorder.cc
@@ -0,0 +1,47 @@
+// Copyright 2017 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/ukm/public/ukm_recorder.h"
+
+#include "base/atomic_sequence_num.h"
+#include "base/bind.h"
+#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
+#include "components/ukm/public/ukm_entry_builder.h"
+
+namespace ukm {
+
+UkmRecorder* g_ukm_recorder = nullptr;
+
+const base::Feature kUkmFeature = {"Ukm", base::FEATURE_DISABLED_BY_DEFAULT};
+
+UkmRecorder::UkmRecorder() {
+ DCHECK(!g_ukm_recorder);
+ g_ukm_recorder = this;
+}
+
+UkmRecorder::~UkmRecorder() {
+ g_ukm_recorder = nullptr;
+}
+
+// static
+UkmRecorder* UkmRecorder::Get() {
+ return g_ukm_recorder;
+}
+
+// static
+ukm::SourceId UkmRecorder::GetNewSourceID() {
+ static base::StaticAtomicSequenceNumber seq;
+ return static_cast<ukm::SourceId>(seq.GetNext());
+}
+
+std::unique_ptr<UkmEntryBuilder> UkmRecorder::GetEntryBuilder(
+ ukm::SourceId source_id,
+ const char* event_name) {
+ return base::MakeUnique<UkmEntryBuilder>(
+ base::Bind(&UkmRecorder::AddEntry, base::Unretained(this)), source_id,
+ event_name);
+}
+
+} // namespace ukm
diff --git a/chromium/components/ukm/public/ukm_recorder.h b/chromium/components/ukm/public/ukm_recorder.h
new file mode 100644
index 00000000000..74cd232d509
--- /dev/null
+++ b/chromium/components/ukm/public/ukm_recorder.h
@@ -0,0 +1,107 @@
+// Copyright 2017 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_UKM_PUBLIC_UKM_RECORDER_H_
+#define COMPONENTS_UKM_PUBLIC_UKM_RECORDER_H_
+
+#include <stddef.h>
+
+#include "base/callback.h"
+#include "base/feature_list.h"
+#include "base/macros.h"
+#include "base/threading/thread_checker.h"
+#include "components/ukm/public/interfaces/ukm_interface.mojom.h"
+#include "components/ukm/public/ukm_entry_builder.h"
+#include "components/ukm/public/ukm_export.h"
+#include "url/gurl.h"
+
+class ContextualSearchRankerLoggerImpl;
+class PluginInfoMessageFilter;
+class UkmPageLoadMetricsObserver;
+
+namespace autofill {
+class AutofillMetrics;
+}
+
+namespace content {
+class MediaInternals;
+class RenderFrameImpl;
+}
+
+namespace translate {
+class TranslateRankerImpl;
+}
+
+namespace payments {
+class JourneyLogger;
+}
+
+namespace ukm {
+
+class UkmEntryBuilder;
+class UkmInterface;
+class TestRecordingHelper;
+
+// This feature controls whether UkmService should be created.
+UKM_EXPORT extern const base::Feature kUkmFeature;
+
+typedef int64_t SourceId;
+
+// Interface for recording UKM
+class UKM_EXPORT UkmRecorder {
+ public:
+ UkmRecorder();
+ virtual ~UkmRecorder();
+
+ // Provides access to a previously constructed UkmRecorder instance. Only one
+ // instance exists per process and must have been constructed prior to any
+ // calls to this method.
+ static UkmRecorder* Get();
+
+ // Get the new source ID, which is unique for the duration of a browser
+ // session.
+ static SourceId GetNewSourceID();
+
+ // Update the URL on the source keyed to the given source ID. If the source
+ // does not exist, it will create a new UkmSource object.
+ virtual void UpdateSourceURL(SourceId source_id, const GURL& url) = 0;
+
+ private:
+ friend autofill::AutofillMetrics;
+ friend payments::JourneyLogger;
+ friend ContextualSearchRankerLoggerImpl;
+ friend PluginInfoMessageFilter;
+ friend UkmPageLoadMetricsObserver;
+ friend translate::TranslateRankerImpl;
+ friend TestRecordingHelper;
+ friend UkmInterface;
+ friend content::MediaInternals;
+ friend content::RenderFrameImpl;
+ FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, AddEntryWithEmptyMetrics);
+ FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, EntryBuilderAndSerialization);
+ FRIEND_TEST_ALL_PREFIXES(UkmServiceTest,
+ LogsUploadedOnlyWhenHavingSourcesOrEntries);
+ FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, MetricsProviderTest);
+ FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, PersistAndPurge);
+ FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, WhitelistEntryTest);
+
+ // Get a new UkmEntryBuilder object for the specified source ID and event,
+ // which can get metrics added to.
+ //
+ // This API being private is intentional. Any client using UKM needs to
+ // declare itself to be a friend of UkmService and go through code review
+ // process.
+ std::unique_ptr<UkmEntryBuilder> GetEntryBuilder(SourceId source_id,
+ const char* event_name);
+
+ private:
+ // Add an entry to the UkmEntry list.
+ virtual void AddEntry(mojom::UkmEntryPtr entry) = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(UkmRecorder);
+};
+
+} // namespace ukm
+
+#endif // COMPONENTS_UKM_PUBLIC_UKM_RECORDER_H_
diff --git a/chromium/components/ukm/test_ukm_recorder.cc b/chromium/components/ukm/test_ukm_recorder.cc
new file mode 100644
index 00000000000..26a1307fede
--- /dev/null
+++ b/chromium/components/ukm/test_ukm_recorder.cc
@@ -0,0 +1,67 @@
+// Copyright 2017 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/ukm/test_ukm_recorder.h"
+
+#include "base/logging.h"
+#include "base/metrics/metrics_hashes.h"
+#include "components/ukm/ukm_source.h"
+
+namespace ukm {
+
+TestUkmRecorder::TestUkmRecorder() {
+ EnableRecording();
+}
+
+TestUkmRecorder::~TestUkmRecorder() = default;
+
+const UkmSource* TestUkmRecorder::GetSourceForUrl(const char* url) const {
+ const UkmSource* source = nullptr;
+ for (const auto& kv : sources()) {
+ if (kv.second->url() == url) {
+ DCHECK_EQ(nullptr, source);
+ source = kv.second.get();
+ }
+ }
+ return source;
+}
+
+const UkmSource* TestUkmRecorder::GetSourceForSourceId(
+ ukm::SourceId source_id) const {
+ const UkmSource* source = nullptr;
+ for (const auto& kv : sources()) {
+ if (kv.second->id() == source_id) {
+ DCHECK_EQ(nullptr, source);
+ source = kv.second.get();
+ }
+ }
+ return source;
+}
+
+const mojom::UkmEntry* TestUkmRecorder::GetEntry(size_t entry_num) const {
+ DCHECK_LT(entry_num, entries().size());
+ return entries()[entry_num].get();
+}
+
+const mojom::UkmEntry* TestUkmRecorder::GetEntryForEntryName(
+ const char* entry_name) const {
+ for (const auto& it : entries()) {
+ if (it->event_hash == base::HashMetricName(entry_name))
+ return it.get();
+ }
+ return nullptr;
+}
+
+// static
+const mojom::UkmMetric* TestUkmRecorder::FindMetric(
+ const mojom::UkmEntry* entry,
+ const char* metric_name) {
+ for (const auto& metric : entry->metrics) {
+ if (metric->metric_hash == base::HashMetricName(metric_name))
+ return metric.get();
+ }
+ return nullptr;
+}
+
+} // namespace ukm
diff --git a/chromium/components/ukm/test_ukm_recorder.h b/chromium/components/ukm/test_ukm_recorder.h
new file mode 100644
index 00000000000..ef989b9dca6
--- /dev/null
+++ b/chromium/components/ukm/test_ukm_recorder.h
@@ -0,0 +1,43 @@
+// Copyright 2017 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_UKM_TEST_UKM_RECORDER_H_
+#define COMPONENTS_UKM_TEST_UKM_RECORDER_H_
+
+#include <stddef.h>
+#include <memory>
+
+#include "base/macros.h"
+#include "components/ukm/ukm_recorder_impl.h"
+
+namespace ukm {
+
+// Wraps an UkmRecorder with additional accessors used for testing.
+class TestUkmRecorder : public UkmRecorderImpl {
+ public:
+ TestUkmRecorder();
+ ~TestUkmRecorder() override;
+
+ size_t sources_count() const { return sources().size(); }
+ const std::map<ukm::SourceId, std::unique_ptr<UkmSource>>& GetSources()
+ const {
+ return sources();
+ }
+ const UkmSource* GetSourceForUrl(const char* url) const;
+ const UkmSource* GetSourceForSourceId(ukm::SourceId source_id) const;
+
+ size_t entries_count() const { return entries().size(); }
+ const mojom::UkmEntry* GetEntry(size_t entry_num) const;
+ const mojom::UkmEntry* GetEntryForEntryName(const char* entry_name) const;
+
+ static const mojom::UkmMetric* FindMetric(const mojom::UkmEntry* entry,
+ const char* metric_name);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestUkmRecorder);
+};
+
+} // namespace ukm
+
+#endif // COMPONENTS_UKM_TEST_UKM_RECORDER_H_
diff --git a/chromium/components/ukm/test_ukm_service.cc b/chromium/components/ukm/test_ukm_service.cc
deleted file mode 100644
index 824fa25a7fe..00000000000
--- a/chromium/components/ukm/test_ukm_service.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 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/ukm/test_ukm_service.h"
-
-#include "base/logging.h"
-#include "base/metrics/metrics_hashes.h"
-#include "components/ukm/ukm_entry.h"
-#include "components/ukm/ukm_source.h"
-
-namespace ukm {
-
-UkmServiceTestingHarness::UkmServiceTestingHarness() {
- UkmService::RegisterPrefs(test_prefs_.registry());
- test_prefs_.ClearPref(prefs::kUkmClientId);
- test_prefs_.ClearPref(prefs::kUkmSessionId);
- test_prefs_.ClearPref(prefs::kUkmPersistedLogs);
-
- test_ukm_service_ = base::MakeUnique<TestUkmService>(&test_prefs_);
-}
-
-UkmServiceTestingHarness::~UkmServiceTestingHarness() = default;
-
-TestUkmService::TestUkmService(PrefService* prefs_service)
- : UkmService(prefs_service, &test_metrics_service_client_) {
- EnableRecording();
- DisableReporting();
-}
-
-TestUkmService::~TestUkmService() = default;
-
-const std::map<int32_t, std::unique_ptr<UkmSource>>&
-TestUkmService::GetSources() const {
- return sources_for_testing();
-}
-
-const UkmSource* TestUkmService::GetSourceForUrl(const char* url) const {
- const UkmSource* source = nullptr;
- for (const auto& kv : sources_for_testing()) {
- if (kv.second->url() == url) {
- DCHECK_EQ(nullptr, source);
- source = kv.second.get();
- }
- }
- return source;
-}
-
-const UkmSource* TestUkmService::GetSourceForSourceId(int32_t source_id) const {
- const UkmSource* source = nullptr;
- for (const auto& kv : sources_for_testing()) {
- if (kv.second->id() == source_id) {
- DCHECK_EQ(nullptr, source);
- source = kv.second.get();
- }
- }
- return source;
-}
-
-const UkmEntry* TestUkmService::GetEntry(size_t entry_num) const {
- return entries_for_testing()[entry_num].get();
-}
-
-const UkmEntry* TestUkmService::GetEntryForEntryName(
- const char* entry_name) const {
- for (const auto& it : entries_for_testing()) {
- if (it->event_hash() == base::HashMetricName(entry_name))
- return it.get();
- }
- return nullptr;
-}
-
-} // namespace ukm
diff --git a/chromium/components/ukm/test_ukm_service.h b/chromium/components/ukm/test_ukm_service.h
deleted file mode 100644
index 55d5920411d..00000000000
--- a/chromium/components/ukm/test_ukm_service.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 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_UKM_TEST_UKM_SERVICE_H_
-#define COMPONENTS_UKM_TEST_UKM_SERVICE_H_
-
-#include <stddef.h>
-#include <memory>
-
-#include "components/metrics/test_metrics_service_client.h"
-#include "components/prefs/testing_pref_service.h"
-#include "components/ukm/ukm_pref_names.h"
-#include "components/ukm/ukm_service.h"
-
-namespace ukm {
-
-// Wraps an UkmService with additional accessors used for testing.
-class TestUkmService : public UkmService {
- public:
- explicit TestUkmService(PrefService* pref_service);
- ~TestUkmService() override;
-
- size_t sources_count() const { return sources_for_testing().size(); }
- const std::map<int32_t, std::unique_ptr<UkmSource>>& GetSources() const;
- const UkmSource* GetSourceForUrl(const char* url) const;
- const UkmSource* GetSourceForSourceId(int32_t source_id) const;
-
- size_t entries_count() const { return entries_for_testing().size(); }
- const UkmEntry* GetEntry(size_t entry_num) const;
- const UkmEntry* GetEntryForEntryName(const char* entry_name) const;
-
- private:
- metrics::TestMetricsServiceClient test_metrics_service_client_;
-
- DISALLOW_COPY_AND_ASSIGN(TestUkmService);
-};
-
-// Convenience harness used for testing; creates a TestUkmService and
-// supplies it with a prefs service with a longer lifespan.
-class UkmServiceTestingHarness {
- public:
- UkmServiceTestingHarness();
- virtual ~UkmServiceTestingHarness();
-
- TestUkmService* test_ukm_service() { return test_ukm_service_.get(); }
-
- private:
- TestingPrefServiceSimple test_prefs_;
- std::unique_ptr<TestUkmService> test_ukm_service_;
-
- DISALLOW_COPY_AND_ASSIGN(UkmServiceTestingHarness);
-};
-
-} // namespace ukm
-
-#endif // COMPONENTS_UKM_TEST_UKM_SERVICE_H_
diff --git a/chromium/components/ukm/ukm_entry.cc b/chromium/components/ukm/ukm_entry.cc
deleted file mode 100644
index 88b724c06f6..00000000000
--- a/chromium/components/ukm/ukm_entry.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 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/ukm/ukm_entry.h"
-
-#include "base/metrics/metrics_hashes.h"
-#include "components/metrics/proto/ukm/entry.pb.h"
-#include "components/ukm/ukm_source.h"
-
-namespace ukm {
-
-UkmEntry::UkmEntry(int32_t source_id, const char* event_name)
- : source_id_(source_id), event_hash_(base::HashMetricName(event_name)) {}
-
-UkmEntry::~UkmEntry() {}
-
-void UkmEntry::PopulateProto(Entry* proto_entry) const {
- DCHECK(!proto_entry->has_source_id());
- DCHECK(!proto_entry->has_event_hash());
-
- proto_entry->set_source_id(source_id_);
- proto_entry->set_event_hash(event_hash_);
- for (auto& metric : metrics_) {
- Entry::Metric* proto_metric = proto_entry->add_metrics();
- proto_metric->set_metric_hash(std::get<0>(metric));
- proto_metric->set_value(std::get<1>(metric));
- }
-}
-
-} // namespace ukm
diff --git a/chromium/components/ukm/ukm_entry.h b/chromium/components/ukm/ukm_entry.h
deleted file mode 100644
index 9adcedb3fa0..00000000000
--- a/chromium/components/ukm/ukm_entry.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 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_UKM_UKM_ENTRY_H_
-#define COMPONENTS_UKM_UKM_ENTRY_H_
-
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-
-namespace ukm {
-
-class Entry;
-class UkmEntryBuilder;
-
-// One UkmEntry contains metrics for a specific source and event. It is
-// connected to a UkmSource by the source ID. The event can be user defined.
-// One example is "PageLoad". Each UkmEntry can have a list of metrics, each of
-// which consist of a metric name and value. When the entry is serialized to the
-// proto message, the event and metric names will be hashed by
-// base::HashMetricName.
-//
-// To build UkmEntry objects, please use UkmEntryBuilder.
-class UkmEntry {
- public:
- // Serializes the members of the class into the supplied proto.
- void PopulateProto(Entry* proto_entry) const;
-
- int32_t source_id() const { return source_id_; }
- uint64_t event_hash() const { return event_hash_; }
-
- ~UkmEntry();
-
- private:
- friend UkmEntryBuilder;
-
- UkmEntry(int32_t source_id, const char* event_name);
-
- const int32_t source_id_;
- const uint64_t event_hash_;
- std::vector<std::pair<uint64_t, int64_t>> metrics_;
-
- DISALLOW_COPY_AND_ASSIGN(UkmEntry);
-};
-
-} // namespace ukm
-
-#endif // COMPONENTS_UKM_UKM_ENTRY_H_
diff --git a/chromium/components/ukm/ukm_entry_builder.cc b/chromium/components/ukm/ukm_entry_builder.cc
deleted file mode 100644
index fdff949038c..00000000000
--- a/chromium/components/ukm/ukm_entry_builder.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 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/ukm/ukm_entry_builder.h"
-
-#include "base/metrics/metrics_hashes.h"
-#include "components/ukm/ukm_entry.h"
-#include "components/ukm/ukm_service.h"
-
-namespace ukm {
-
-UkmEntryBuilder::UkmEntryBuilder(const UkmService::AddEntryCallback& callback,
- int32_t source_id,
- const char* event_name)
- : add_entry_callback_(callback),
- entry_(new UkmEntry(source_id, event_name)) {}
-
-UkmEntryBuilder::~UkmEntryBuilder() {
- add_entry_callback_.Run(std::move(entry_));
-}
-
-void UkmEntryBuilder::AddMetric(const char* metric_name, int64_t value) {
- entry_->metrics_.emplace_back(
- std::make_pair(base::HashMetricName(metric_name), value));
-}
-
-} // namespace ukm
diff --git a/chromium/components/ukm/ukm_recorder_impl.cc b/chromium/components/ukm/ukm_recorder_impl.cc
new file mode 100644
index 00000000000..cb670812ebf
--- /dev/null
+++ b/chromium/components/ukm/ukm_recorder_impl.cc
@@ -0,0 +1,177 @@
+// Copyright 2017 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/ukm/ukm_recorder_impl.h"
+
+#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/metrics_hashes.h"
+#include "base/strings/string_split.h"
+#include "components/metrics/proto/ukm/entry.pb.h"
+#include "components/metrics/proto/ukm/report.pb.h"
+#include "components/metrics/proto/ukm/source.pb.h"
+#include "components/ukm/ukm_source.h"
+
+namespace ukm {
+
+namespace {
+
+// Gets the list of whitelisted Entries as string. Format is a comma seperated
+// list of Entry names (as strings).
+std::string GetWhitelistEntries() {
+ return base::GetFieldTrialParamValueByFeature(kUkmFeature,
+ "WhitelistEntries");
+}
+
+// Gets the maximum number of Sources we'll keep in memory before discarding any
+// new ones being added.
+size_t GetMaxSources() {
+ constexpr size_t kDefaultMaxSources = 500;
+ return static_cast<size_t>(base::GetFieldTrialParamByFeatureAsInt(
+ kUkmFeature, "MaxSources", kDefaultMaxSources));
+}
+
+// Gets the maximum number of Entries we'll keep in memory before discarding any
+// new ones being added.
+size_t GetMaxEntries() {
+ constexpr size_t kDefaultMaxEntries = 5000;
+ return static_cast<size_t>(base::GetFieldTrialParamByFeatureAsInt(
+ kUkmFeature, "MaxEntries", kDefaultMaxEntries));
+}
+
+// True if we should record the initial_url field of the UKM Source proto.
+bool ShouldRecordInitialUrl() {
+ return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature,
+ "RecordInitialUrl", false);
+}
+
+enum class DroppedDataReason {
+ NOT_DROPPED = 0,
+ RECORDING_DISABLED = 1,
+ MAX_HIT = 2,
+ NOT_WHITELISTED = 3,
+ NUM_DROPPED_DATA_REASONS
+};
+
+void RecordDroppedSource(DroppedDataReason reason) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "UKM.Sources.Dropped", static_cast<int>(reason),
+ static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
+}
+
+void RecordDroppedEntry(DroppedDataReason reason) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "UKM.Entries.Dropped", static_cast<int>(reason),
+ static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
+}
+
+void StoreEntryProto(const mojom::UkmEntry& in, Entry* out) {
+ DCHECK(!out->has_source_id());
+ DCHECK(!out->has_event_hash());
+
+ out->set_source_id(in.source_id);
+ out->set_event_hash(in.event_hash);
+ for (const auto& metric : in.metrics) {
+ Entry::Metric* proto_metric = out->add_metrics();
+ proto_metric->set_metric_hash(metric->metric_hash);
+ proto_metric->set_value(metric->value);
+ }
+}
+
+} // namespace
+
+UkmRecorderImpl::UkmRecorderImpl() : recording_enabled_(false) {}
+UkmRecorderImpl::~UkmRecorderImpl() = default;
+
+void UkmRecorderImpl::EnableRecording() {
+ DVLOG(1) << "UkmRecorderImpl::EnableRecording";
+ recording_enabled_ = true;
+}
+
+void UkmRecorderImpl::DisableRecording() {
+ DVLOG(1) << "UkmRecorderImpl::DisableRecording";
+ recording_enabled_ = false;
+}
+
+void UkmRecorderImpl::Purge() {
+ sources_.clear();
+ entries_.clear();
+}
+
+void UkmRecorderImpl::StoreRecordingsInReport(Report* report) {
+ for (const auto& kv : sources_) {
+ Source* proto_source = report->add_sources();
+ kv.second->PopulateProto(proto_source);
+ if (!ShouldRecordInitialUrl())
+ proto_source->clear_initial_url();
+ }
+ for (const auto& entry : entries_) {
+ Entry* proto_entry = report->add_entries();
+ StoreEntryProto(*entry, proto_entry);
+ }
+
+ UMA_HISTOGRAM_COUNTS_1000("UKM.Sources.SerializedCount", sources_.size());
+ UMA_HISTOGRAM_COUNTS_1000("UKM.Entries.SerializedCount", entries_.size());
+ sources_.clear();
+ entries_.clear();
+}
+
+void UkmRecorderImpl::UpdateSourceURL(ukm::SourceId source_id,
+ const GURL& url) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (!recording_enabled_) {
+ RecordDroppedSource(DroppedDataReason::RECORDING_DISABLED);
+ return;
+ }
+
+ // Update the pre-existing source if there is any. This happens when the
+ // initial URL is different from the committed URL for the same source, e.g.,
+ // when there is redirection.
+ if (base::ContainsKey(sources_, source_id)) {
+ sources_[source_id]->UpdateUrl(url);
+ return;
+ }
+
+ if (sources_.size() >= GetMaxSources()) {
+ RecordDroppedSource(DroppedDataReason::MAX_HIT);
+ return;
+ }
+ std::unique_ptr<UkmSource> source = base::MakeUnique<UkmSource>();
+ source->set_id(source_id);
+ source->set_url(url);
+ sources_.insert(std::make_pair(source_id, std::move(source)));
+}
+
+void UkmRecorderImpl::AddEntry(mojom::UkmEntryPtr entry) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (!recording_enabled_) {
+ RecordDroppedEntry(DroppedDataReason::RECORDING_DISABLED);
+ return;
+ }
+ if (entries_.size() >= GetMaxEntries()) {
+ RecordDroppedEntry(DroppedDataReason::MAX_HIT);
+ return;
+ }
+
+ if (!whitelisted_entry_hashes_.empty() &&
+ !base::ContainsKey(whitelisted_entry_hashes_, entry->event_hash)) {
+ RecordDroppedEntry(DroppedDataReason::NOT_WHITELISTED);
+ return;
+ }
+
+ entries_.push_back(std::move(entry));
+}
+
+void UkmRecorderImpl::StoreWhitelistedEntries() {
+ const auto entries =
+ base::SplitString(GetWhitelistEntries(), ",", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
+ for (const auto& entry_string : entries)
+ whitelisted_entry_hashes_.insert(base::HashMetricName(entry_string));
+}
+
+} // namespace ukm
diff --git a/chromium/components/ukm/ukm_recorder_impl.h b/chromium/components/ukm/ukm_recorder_impl.h
new file mode 100644
index 00000000000..50976e436d0
--- /dev/null
+++ b/chromium/components/ukm/ukm_recorder_impl.h
@@ -0,0 +1,78 @@
+// Copyright 2017 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_UKM_UKM_RECORDER_IMPL_H_
+#define COMPONENTS_UKM_UKM_RECORDER_IMPL_H_
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include "base/threading/thread_checker.h"
+#include "components/ukm/public/interfaces/ukm_interface.mojom.h"
+#include "components/ukm/public/ukm_recorder.h"
+
+namespace metrics {
+class UkmBrowserTest;
+}
+
+namespace ukm {
+
+class UkmSource;
+class Report;
+
+namespace debug {
+class DebugPage;
+}
+
+class UkmRecorderImpl : public UkmRecorder {
+ public:
+ UkmRecorderImpl();
+ ~UkmRecorderImpl() override;
+
+ // Enables/disables recording control if data is allowed to be collected.
+ void EnableRecording();
+ void DisableRecording();
+
+ // Deletes stored recordings.
+ void Purge();
+
+ protected:
+ // Cache the list of whitelisted entries from the field trial parameter.
+ void StoreWhitelistedEntries();
+
+ // Writes recordings into a report proto, and clears recordings.
+ void StoreRecordingsInReport(Report* report);
+
+ const std::map<ukm::SourceId, std::unique_ptr<UkmSource>>& sources() const {
+ return sources_;
+ }
+
+ const std::vector<mojom::UkmEntryPtr>& entries() const { return entries_; }
+
+ private:
+ friend ::metrics::UkmBrowserTest;
+ friend ::ukm::debug::DebugPage;
+
+ // UkmRecorder:
+ void UpdateSourceURL(SourceId source_id, const GURL& url) override;
+ void AddEntry(mojom::UkmEntryPtr entry) override;
+
+ // Whether recording new data is currently allowed.
+ bool recording_enabled_;
+
+ // Contains newly added sources and entries of UKM metrics which periodically
+ // get serialized and cleared by BuildAndStoreLog().
+ std::map<ukm::SourceId, std::unique_ptr<UkmSource>> sources_;
+ std::vector<mojom::UkmEntryPtr> entries_;
+
+ // Whitelisted Entry hashes, only the ones in this set will be recorded.
+ std::set<uint64_t> whitelisted_entry_hashes_;
+
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace ukm
+
+#endif // COMPONENTS_UKM_UKM_RECORDER_IMPL_H_
diff --git a/chromium/components/ukm/ukm_service.cc b/chromium/components/ukm/ukm_service.cc
index 4c190c946ff..312ba041dd1 100644
--- a/chromium/components/ukm/ukm_service.cc
+++ b/chromium/components/ukm/ukm_service.cc
@@ -14,26 +14,17 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
-#include "base/metrics/metrics_hashes.h"
#include "base/rand_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/metrics/metrics_log.h"
-#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_service_client.h"
-#include "components/metrics/proto/ukm/entry.pb.h"
#include "components/metrics/proto/ukm/report.pb.h"
-#include "components/metrics/proto/ukm/source.pb.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/ukm/persisted_logs_metrics_impl.h"
-#include "components/ukm/ukm_entry.h"
-#include "components/ukm/ukm_entry_builder.h"
#include "components/ukm/ukm_pref_names.h"
#include "components/ukm/ukm_rotation_scheduler.h"
-#include "components/ukm/ukm_source.h"
namespace ukm {
@@ -43,35 +34,6 @@ namespace {
// initialization work.
constexpr int kInitializationDelaySeconds = 5;
-// Gets the list of whitelisted Entries as string. Format is a comma seperated
-// list of Entry names (as strings).
-std::string GetWhitelistEntries() {
- return base::GetFieldTrialParamValueByFeature(kUkmFeature,
- "WhitelistEntries");
-}
-
-// Gets the maximum number of Sources we'll keep in memory before discarding any
-// new ones being added.
-size_t GetMaxSources() {
- constexpr size_t kDefaultMaxSources = 500;
- return static_cast<size_t>(base::GetFieldTrialParamByFeatureAsInt(
- kUkmFeature, "MaxSources", kDefaultMaxSources));
-}
-
-// Gets the maximum number of Entries we'll keep in memory before discarding any
-// new ones being added.
-size_t GetMaxEntries() {
- constexpr size_t kDefaultMaxEntries = 5000;
- return static_cast<size_t>(base::GetFieldTrialParamByFeatureAsInt(
- kUkmFeature, "MaxEntries", kDefaultMaxEntries));
-}
-
-// True if we should record the initial_url field of the UKM Source proto.
-bool ShouldRecordInitialUrl() {
- return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature,
- "RecordInitialUrl", false);
-}
-
// True if we should record session ids in the UKM Report proto.
bool ShouldRecordSessionId() {
return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature, "RecordSessionId",
@@ -104,34 +66,11 @@ int32_t LoadSessionId(PrefService* pref_service) {
return session_id;
}
-enum class DroppedDataReason {
- NOT_DROPPED = 0,
- RECORDING_DISABLED = 1,
- MAX_HIT = 2,
- NOT_WHITELISTED = 3,
- NUM_DROPPED_DATA_REASONS
-};
-
-void RecordDroppedSource(DroppedDataReason reason) {
- UMA_HISTOGRAM_ENUMERATION(
- "UKM.Sources.Dropped", static_cast<int>(reason),
- static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
-}
-
-void RecordDroppedEntry(DroppedDataReason reason) {
- UMA_HISTOGRAM_ENUMERATION(
- "UKM.Entries.Dropped", static_cast<int>(reason),
- static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
-}
-
} // namespace
-const base::Feature kUkmFeature = {"Ukm", base::FEATURE_DISABLED_BY_DEFAULT};
-
UkmService::UkmService(PrefService* pref_service,
metrics::MetricsServiceClient* client)
: pref_service_(pref_service),
- recording_enabled_(false),
client_id_(0),
session_id_(0),
client_(client),
@@ -177,14 +116,6 @@ void UkmService::Initialize() {
base::TimeDelta::FromSeconds(kInitializationDelaySeconds));
}
-void UkmService::EnableRecording() {
- recording_enabled_ = true;
-}
-
-void UkmService::DisableRecording() {
- recording_enabled_ = false;
-}
-
void UkmService::EnableReporting() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "UkmService::EnableReporting";
@@ -254,8 +185,7 @@ void UkmService::Purge() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "UkmService::Purge";
reporting_service_.ukm_log_store()->Purge();
- sources_.clear();
- entries_.clear();
+ UkmRecorderImpl::Purge();
}
// TODO(bmcquade): rename this to something more generic, like
@@ -307,7 +237,7 @@ void UkmService::BuildAndStoreLog() {
// Suppress generating a log if we have no new data to include.
// TODO(zhenw): add a histogram here to debug if this case is hitting a lot.
- if (sources_.empty() && entries_.empty())
+ if (sources().empty() && entries().empty())
return;
Report report;
@@ -315,21 +245,7 @@ void UkmService::BuildAndStoreLog() {
if (ShouldRecordSessionId())
report.set_session_id(session_id_);
- for (const auto& kv : sources_) {
- Source* proto_source = report.add_sources();
- kv.second->PopulateProto(proto_source);
- if (!ShouldRecordInitialUrl())
- proto_source->clear_initial_url();
- }
- for (const auto& entry : entries_) {
- Entry* proto_entry = report.add_entries();
- entry->PopulateProto(proto_entry);
- }
-
- UMA_HISTOGRAM_COUNTS_1000("UKM.Sources.SerializedCount", sources_.size());
- UMA_HISTOGRAM_COUNTS_1000("UKM.Entries.SerializedCount", entries_.size());
- sources_.clear();
- entries_.clear();
+ StoreRecordingsInReport(&report);
metrics::MetricsLog::RecordCoreSystemProfile(client_,
report.mutable_system_profile());
@@ -343,74 +259,4 @@ void UkmService::BuildAndStoreLog() {
reporting_service_.ukm_log_store()->StoreLog(serialized_log);
}
-// static
-int32_t UkmService::GetNewSourceID() {
- static int32_t next_source_id = 0;
- return next_source_id++;
-}
-
-std::unique_ptr<UkmEntryBuilder> UkmService::GetEntryBuilder(
- int32_t source_id,
- const char* event_name) {
- return std::unique_ptr<UkmEntryBuilder>(new UkmEntryBuilder(
- base::Bind(&UkmService::AddEntry, base::Unretained(this)), source_id,
- event_name));
-}
-
-void UkmService::UpdateSourceURL(int32_t source_id, const GURL& url) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- if (!recording_enabled_) {
- RecordDroppedSource(DroppedDataReason::RECORDING_DISABLED);
- return;
- }
-
- // Update the pre-existing source if there is any. This happens when the
- // initial URL is different from the committed URL for the same source, e.g.,
- // when there is redirection.
- if (base::ContainsKey(sources_, source_id)) {
- sources_[source_id]->UpdateUrl(url);
- return;
- }
-
- if (sources_.size() >= GetMaxSources()) {
- RecordDroppedSource(DroppedDataReason::MAX_HIT);
- return;
- }
- std::unique_ptr<UkmSource> source = base::MakeUnique<UkmSource>();
- source->set_id(source_id);
- source->set_url(url);
- sources_.insert(std::make_pair(source_id, std::move(source)));
-}
-
-void UkmService::AddEntry(std::unique_ptr<UkmEntry> entry) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- if (!recording_enabled_) {
- RecordDroppedEntry(DroppedDataReason::RECORDING_DISABLED);
- return;
- }
- if (entries_.size() >= GetMaxEntries()) {
- RecordDroppedEntry(DroppedDataReason::MAX_HIT);
- return;
- }
-
- if (!whitelisted_entry_hashes_.empty() &&
- !base::ContainsKey(whitelisted_entry_hashes_, entry->event_hash())) {
- RecordDroppedEntry(DroppedDataReason::NOT_WHITELISTED);
- return;
- }
-
- entries_.push_back(std::move(entry));
-}
-
-void UkmService::StoreWhitelistedEntries() {
- const auto entries =
- base::SplitString(GetWhitelistEntries(), ",", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- for (const auto& entry_string : entries) {
- whitelisted_entry_hashes_.insert(base::HashMetricName(entry_string));
- }
-}
-
} // namespace ukm
diff --git a/chromium/components/ukm/ukm_service.h b/chromium/components/ukm/ukm_service.h
index 9b493a2a213..b6931198f3f 100644
--- a/chromium/components/ukm/ukm_service.h
+++ b/chromium/components/ukm/ukm_service.h
@@ -9,73 +9,43 @@
#include <memory>
#include <vector>
-#include "base/callback.h"
-#include "base/feature_list.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "build/build_config.h"
#include "components/metrics/metrics_provider.h"
#include "components/metrics/metrics_rotation_scheduler.h"
+#include "components/ukm/ukm_recorder_impl.h"
#include "components/ukm/ukm_reporting_service.h"
-#include "url/gurl.h"
-class PluginInfoMessageFilter;
class PrefRegistrySimple;
class PrefService;
-class UkmPageLoadMetricsObserver;
-
-namespace autofill {
-class AutofillMetrics;
-} // namespace autofill
-
-namespace translate {
-class TranslateRankerImpl;
-}
-
-namespace payments {
-class JourneyLogger;
-} // namespace payments
namespace metrics {
class MetricsServiceClient;
+class UkmBrowserTest;
}
namespace ukm {
-class UkmEntry;
-class UkmEntryBuilder;
-class UkmSource;
-
-// This feature controls whether UkmService should be created.
-extern const base::Feature kUkmFeature;
+namespace debug {
+class DebugPage;
+}
// The URL-Keyed Metrics (UKM) service is responsible for gathering and
// uploading reports that contain fine grained performance metrics including
// URLs for top-level navigations.
-class UkmService {
+class UkmService : public UkmRecorderImpl {
public:
// Constructs a UkmService.
// Calling code is responsible for ensuring that the lifetime of
// |pref_service| is longer than the lifetime of UkmService.
UkmService(PrefService* pref_service, metrics::MetricsServiceClient* client);
- virtual ~UkmService();
-
- // Get the new source ID, which is unique for the duration of a browser
- // session.
- static int32_t GetNewSourceID();
-
- // Update the URL on the source keyed to the given source ID. If the source
- // does not exist, it will create a new UkmSource object.
- void UpdateSourceURL(int32_t source_id, const GURL& url);
+ ~UkmService() override;
// Initializes the UKM service.
void Initialize();
- // Enables/disables recording control if data is allowed to be collected.
- void EnableRecording();
- void DisableRecording();
-
// Enables/disables transmission of accumulated logs. Logs that have already
// been created will remain persisted to disk.
void EnableReporting();
@@ -104,24 +74,10 @@ class UkmService {
// the provided PrefRegistry.
static void RegisterPrefs(PrefRegistrySimple* registry);
- using AddEntryCallback = base::Callback<void(std::unique_ptr<UkmEntry>)>;
-
- protected:
- const std::map<int32_t, std::unique_ptr<UkmSource>>& sources_for_testing()
- const {
- return sources_;
- }
-
- const std::vector<std::unique_ptr<UkmEntry>>& entries_for_testing() const {
- return entries_;
- }
-
private:
- friend autofill::AutofillMetrics;
- friend payments::JourneyLogger;
- friend PluginInfoMessageFilter;
- friend UkmPageLoadMetricsObserver;
- friend translate::TranslateRankerImpl;
+ friend ::ukm::debug::DebugPage;
+ friend ::metrics::UkmBrowserTest;
+
FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, AddEntryWithEmptyMetrics);
FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, EntryBuilderAndSerialization);
FRIEND_TEST_ALL_PREFIXES(UkmServiceTest,
@@ -130,15 +86,6 @@ class UkmService {
FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, PersistAndPurge);
FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, WhitelistEntryTest);
- // Get a new UkmEntryBuilder object for the specified source ID and event,
- // which can get metrics added to.
- //
- // This API being private is intentional. Any client using UKM needs to
- // declare itself to be a friend of UkmService and go through code review
- // process.
- std::unique_ptr<UkmEntryBuilder> GetEntryBuilder(int32_t source_id,
- const char* event_name);
-
// Starts metrics client initialization.
void StartInitTask();
@@ -159,18 +106,9 @@ class UkmService {
// Called by log_uploader_ when the an upload is completed.
void OnLogUploadComplete(int response_code);
- // Add an entry to the UkmEntry list.
- void AddEntry(std::unique_ptr<UkmEntry> entry);
-
- // Cache the list of whitelisted entries from the field trial parameter.
- void StoreWhitelistedEntries();
-
// A weak pointer to the PrefService used to read and write preferences.
PrefService* pref_service_;
- // Whether recording new data is currently allowed.
- bool recording_enabled_;
-
// The UKM client id stored in prefs.
uint64_t client_id_;
@@ -195,14 +133,6 @@ class UkmService {
bool initialize_started_;
bool initialize_complete_;
- // Contains newly added sources and entries of UKM metrics which periodically
- // get serialized and cleared by BuildAndStoreLog().
- std::map<int32_t, std::unique_ptr<UkmSource>> sources_;
- std::vector<std::unique_ptr<UkmEntry>> entries_;
-
- // Whitelisted Entry hashes, only the ones in this set will be recorded.
- std::set<uint64_t> whitelisted_entry_hashes_;
-
// Weak pointers factory used to post task on different threads. All weak
// pointers managed by this factory have the same lifetime as UkmService.
base::WeakPtrFactory<UkmService> self_ptr_factory_;
diff --git a/chromium/components/ukm/ukm_service_unittest.cc b/chromium/components/ukm/ukm_service_unittest.cc
index 6177f7c345d..3f3e6432c8a 100644
--- a/chromium/components/ukm/ukm_service_unittest.cc
+++ b/chromium/components/ukm/ukm_service_unittest.cc
@@ -19,7 +19,7 @@
#include "components/metrics/test_metrics_service_client.h"
#include "components/prefs/testing_pref_service.h"
#include "components/ukm/persisted_logs_metrics_impl.h"
-#include "components/ukm/ukm_entry_builder.h"
+#include "components/ukm/public/ukm_entry_builder.h"
#include "components/ukm/ukm_pref_names.h"
#include "components/ukm/ukm_source.h"
#include "components/variations/variations_associated_data.h"
@@ -28,6 +28,24 @@
namespace ukm {
+// A small shim exposing UkmRecorder methods to tests.
+class TestRecordingHelper {
+ public:
+ TestRecordingHelper(UkmRecorder* recorder) : recorder_(recorder) {}
+
+ void UpdateSourceURL(SourceId source_id, const GURL& url) {
+ recorder_->UpdateSourceURL(source_id, url);
+ };
+
+ std::unique_ptr<UkmEntryBuilder> GetEntryBuilder(SourceId source_id,
+ const char* event_name) {
+ return recorder_->GetEntryBuilder(source_id, event_name);
+ }
+
+ private:
+ UkmRecorder* recorder_;
+};
+
namespace {
// TODO(rkaplow): consider making this a generic testing class in
@@ -147,21 +165,22 @@ TEST_F(UkmServiceTest, EnableDisableSchedule) {
TEST_F(UkmServiceTest, PersistAndPurge) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(GetPersistedLogCount(), 0);
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- int32_t id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ ukm::SourceId id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
// Should init, generate a log, and start an upload for source.
task_runner_->RunPendingTasks();
EXPECT_TRUE(client_.uploader()->is_uploading());
// Flushes the generated log to disk and generates a new entry.
{
std::unique_ptr<UkmEntryBuilder> builder =
- service.GetEntryBuilder(id, "PageLoad");
+ recorder.GetEntryBuilder(id, "PageLoad");
builder->AddMetric("FirstContentfulPaint", 300);
}
service.Flush();
@@ -172,16 +191,17 @@ TEST_F(UkmServiceTest, PersistAndPurge) {
TEST_F(UkmServiceTest, SourceSerialization) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(GetPersistedLogCount(), 0);
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- int32_t id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/initial"));
- service.UpdateSourceURL(id, GURL("https://google.com/intermediate"));
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ ukm::SourceId id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/initial"));
+ recorder.UpdateSourceURL(id, GURL("https://google.com/intermediate"));
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
service.Flush();
EXPECT_EQ(GetPersistedLogCount(), 1);
@@ -198,14 +218,15 @@ TEST_F(UkmServiceTest, SourceSerialization) {
TEST_F(UkmServiceTest, EntryBuilderAndSerialization) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(0, GetPersistedLogCount());
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- int32_t id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ ukm::SourceId id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
{
std::unique_ptr<UkmEntryBuilder> foo_builder =
service.GetEntryBuilder(id, "foo");
@@ -261,14 +282,15 @@ TEST_F(UkmServiceTest, EntryBuilderAndSerialization) {
TEST_F(UkmServiceTest, AddEntryWithEmptyMetrics) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(0, GetPersistedLogCount());
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- int32_t id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ ukm::SourceId id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
{
std::unique_ptr<UkmEntryBuilder> builder =
@@ -282,6 +304,7 @@ TEST_F(UkmServiceTest, AddEntryWithEmptyMetrics) {
TEST_F(UkmServiceTest, MetricsProviderTest) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
metrics::TestMetricsProvider* provider = new metrics::TestMetricsProvider();
service.RegisterMetricsProvider(
@@ -296,8 +319,8 @@ TEST_F(UkmServiceTest, MetricsProviderTest) {
service.EnableRecording();
service.EnableReporting();
- int32_t id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ ukm::SourceId id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
{
std::unique_ptr<UkmEntryBuilder> builder =
service.GetEntryBuilder(id, "PageLoad");
@@ -316,6 +339,7 @@ TEST_F(UkmServiceTest, MetricsProviderTest) {
TEST_F(UkmServiceTest, LogsUploadedOnlyWhenHavingSourcesOrEntries) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(GetPersistedLogCount(), 0);
service.Initialize();
task_runner_->RunUntilIdle();
@@ -328,8 +352,8 @@ TEST_F(UkmServiceTest, LogsUploadedOnlyWhenHavingSourcesOrEntries) {
service.Flush();
EXPECT_EQ(GetPersistedLogCount(), 0);
- int32_t id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ ukm::SourceId id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
// Includes a Source, so will persist.
service.Flush();
EXPECT_EQ(GetPersistedLogCount(), 1);
@@ -343,7 +367,7 @@ TEST_F(UkmServiceTest, LogsUploadedOnlyWhenHavingSourcesOrEntries) {
service.Flush();
EXPECT_EQ(GetPersistedLogCount(), 2);
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
{
std::unique_ptr<UkmEntryBuilder> builder =
service.GetEntryBuilder(id, "PageLoad");
@@ -359,9 +383,9 @@ TEST_F(UkmServiceTest, LogsUploadedOnlyWhenHavingSourcesOrEntries) {
}
TEST_F(UkmServiceTest, GetNewSourceID) {
- int32_t id1 = UkmService::GetNewSourceID();
- int32_t id2 = UkmService::GetNewSourceID();
- int32_t id3 = UkmService::GetNewSourceID();
+ ukm::SourceId id1 = UkmRecorder::GetNewSourceID();
+ ukm::SourceId id2 = UkmRecorder::GetNewSourceID();
+ ukm::SourceId id3 = UkmRecorder::GetNewSourceID();
EXPECT_NE(id1, id2);
EXPECT_NE(id1, id3);
EXPECT_NE(id2, id3);
@@ -376,16 +400,17 @@ TEST_F(UkmServiceTest, RecordInitialUrl) {
ClearPrefs();
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(GetPersistedLogCount(), 0);
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- int32_t id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/initial"));
- service.UpdateSourceURL(id, GURL("https://google.com/intermediate"));
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ ukm::SourceId id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/initial"));
+ recorder.UpdateSourceURL(id, GURL("https://google.com/intermediate"));
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
service.Flush();
EXPECT_EQ(GetPersistedLogCount(), 1);
@@ -413,14 +438,15 @@ TEST_F(UkmServiceTest, RecordSessionId) {
ClearPrefs();
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(0, GetPersistedLogCount());
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- auto id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+ auto id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar"));
service.Flush();
EXPECT_EQ(1, GetPersistedLogCount());
@@ -438,18 +464,19 @@ TEST_F(UkmServiceTest, SourceSize) {
ClearPrefs();
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(0, GetPersistedLogCount());
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- auto id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar1"));
- id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar2"));
- id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar3"));
+ auto id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar1"));
+ id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar2"));
+ id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar3"));
service.Flush();
EXPECT_EQ(1, GetPersistedLogCount());
@@ -462,13 +489,14 @@ TEST_F(UkmServiceTest, SourceSize) {
TEST_F(UkmServiceTest, PurgeMidUpload) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(GetPersistedLogCount(), 0);
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- auto id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar1"));
+ auto id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar1"));
// Should init, generate a log, and start an upload.
task_runner_->RunPendingTasks();
EXPECT_TRUE(client_.uploader()->is_uploading());
@@ -488,14 +516,15 @@ TEST_F(UkmServiceTest, WhitelistEntryTest) {
ClearPrefs();
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(0, GetPersistedLogCount());
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- auto id = UkmService::GetNewSourceID();
- service.UpdateSourceURL(id, GURL("https://google.com/foobar1"));
+ auto id = UkmRecorder::GetNewSourceID();
+ recorder.UpdateSourceURL(id, GURL("https://google.com/foobar1"));
{
std::unique_ptr<UkmEntryBuilder> builder =
@@ -533,17 +562,18 @@ TEST_F(UkmServiceTest, WhitelistEntryTest) {
TEST_F(UkmServiceTest, SourceURLLength) {
UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
EXPECT_EQ(0, GetPersistedLogCount());
service.Initialize();
task_runner_->RunUntilIdle();
service.EnableRecording();
service.EnableReporting();
- auto id = UkmService::GetNewSourceID();
+ auto id = UkmRecorder::GetNewSourceID();
// This URL is too long to be recorded fully.
const std::string long_string = "https://" + std::string(10000, 'a');
- service.UpdateSourceURL(id, GURL(long_string));
+ recorder.UpdateSourceURL(id, GURL(long_string));
service.Flush();
EXPECT_EQ(1, GetPersistedLogCount());
diff --git a/chromium/components/ukm/ukm_source.h b/chromium/components/ukm/ukm_source.h
index 68347468101..928144be056 100644
--- a/chromium/components/ukm/ukm_source.h
+++ b/chromium/components/ukm/ukm_source.h
@@ -16,14 +16,16 @@ namespace ukm {
class Source;
+typedef int64_t SourceId;
+
// Contains UKM data for a single navigation entry.
class UkmSource {
public:
UkmSource();
~UkmSource();
- int32_t id() const { return id_; }
- void set_id(int32_t id) { id_ = id; }
+ ukm::SourceId id() const { return id_; }
+ void set_id(ukm::SourceId id) { id_ = id; }
const GURL& initial_url() const { return initial_url_; }
const GURL& url() const { return url_; }
@@ -42,7 +44,7 @@ class UkmSource {
void PopulateProto(Source* proto_source) const;
private:
- int32_t id_;
+ ukm::SourceId id_;
// The final, canonical URL for this source.
GURL url_;
diff --git a/chromium/components/update_client/BUILD.gn b/chromium/components/update_client/BUILD.gn
index b5a29805ef5..1408a4292d0 100644
--- a/chromium/components/update_client/BUILD.gn
+++ b/chromium/components/update_client/BUILD.gn
@@ -6,16 +6,10 @@ import("//net/features.gni")
static_library("update_client") {
sources = [
- "action.cc",
- "action.h",
- "action_update.cc",
- "action_update.h",
- "action_update_check.cc",
- "action_update_check.h",
- "action_wait.cc",
- "action_wait.h",
"background_downloader_win.cc",
"background_downloader_win.h",
+ "component.cc",
+ "component.h",
"component_patcher.cc",
"component_patcher.h",
"component_patcher_operation.cc",
@@ -26,13 +20,20 @@ static_library("update_client") {
"crx_downloader.cc",
"crx_downloader.h",
"crx_update_item.h",
+ "out_of_process_patcher.h",
"persisted_data.cc",
"persisted_data.h",
"ping_manager.cc",
"ping_manager.h",
+ "protocol_builder.cc",
+ "protocol_builder.h",
+ "protocol_parser.cc",
+ "protocol_parser.h",
"request_sender.cc",
"request_sender.h",
"task.h",
+ "task_send_uninstall_ping.cc",
+ "task_send_uninstall_ping.h",
"task_update.cc",
"task_update.h",
"update_checker.cc",
@@ -47,10 +48,9 @@ static_library("update_client") {
"update_query_params.h",
"update_query_params_delegate.cc",
"update_query_params_delegate.h",
- "update_response.cc",
- "update_response.h",
"updater_state.cc",
"updater_state.h",
+ "updater_state_mac.mm",
"updater_state_win.cc",
"url_fetcher_downloader.cc",
"url_fetcher_downloader.h",
@@ -69,9 +69,13 @@ static_library("update_client") {
"//crypto",
"//net",
"//third_party/libxml",
- "//third_party/zlib:zip",
+ "//third_party/zlib/google:zip",
"//url",
]
+ libs = []
+ if (is_mac) {
+ libs += [ "OpenDirectory.framework" ]
+ }
}
static_library("test_support") {
@@ -112,6 +116,7 @@ bundle_data("unit_tests_bundle_data") {
"//components/test/data/update_client/jebgalgnebhfojomionfpkfelancnnkf.crx",
"//components/test/data/update_client/updatecheck_reply_1.xml",
"//components/test/data/update_client/updatecheck_reply_4.xml",
+ "//components/test/data/update_client/updatecheck_reply_noupdate.xml",
]
outputs = [
"{{bundle_resources_dir}}/" +
@@ -127,11 +132,12 @@ source_set("unit_tests") {
"component_unpacker_unittest.cc",
"persisted_data_unittest.cc",
"ping_manager_unittest.cc",
+ "protocol_builder_unittest.cc",
+ "protocol_parser_unittest.cc",
"request_sender_unittest.cc",
"update_checker_unittest.cc",
"update_client_unittest.cc",
"update_query_params_unittest.cc",
- "update_response_unittest.cc",
"updater_state_unittest.cc",
"utils_unittest.cc",
]
diff --git a/chromium/components/update_client/action.cc b/chromium/components/update_client/action.cc
deleted file mode 100644
index 7fab8a8d8ed..00000000000
--- a/chromium/components/update_client/action.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2015 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/update_client/action.h"
-
-#include <algorithm>
-#include <memory>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/location.h"
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/update_client/action_update.h"
-#include "components/update_client/action_wait.h"
-#include "components/update_client/configurator.h"
-#include "components/update_client/update_client_errors.h"
-#include "components/update_client/update_engine.h"
-#include "components/update_client/utils.h"
-
-namespace update_client {
-
-using Events = UpdateClient::Observer::Events;
-
-namespace {
-
-// Returns true if a differential update is available, it has not failed yet,
-// and the configuration allows this update.
-bool CanTryDiffUpdate(const CrxUpdateItem* update_item,
- const scoped_refptr<Configurator>& config) {
- return HasDiffUpdate(update_item) && !update_item->diff_update_failed &&
- config->EnabledDeltas();
-}
-
-} // namespace
-
-ActionImpl::ActionImpl() : update_context_(nullptr) {
-}
-
-ActionImpl::~ActionImpl() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void ActionImpl::Run(UpdateContext* update_context, Callback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- update_context_ = update_context;
- callback_ = callback;
-}
-
-CrxUpdateItem* ActionImpl::FindUpdateItemById(const std::string& id) const {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- const auto it = update_context_->update_items.find(id);
-
- return it != update_context_->update_items.end() ? it->second.get() : nullptr;
-}
-
-void ActionImpl::ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::State to) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- item->state = to;
-
- using Events = UpdateClient::Observer::Events;
-
- const std::string& id(item->id);
- switch (to) {
- case CrxUpdateItem::State::kChecking:
- NotifyObservers(Events::COMPONENT_CHECKING_FOR_UPDATES, id);
- break;
- case CrxUpdateItem::State::kCanUpdate:
- NotifyObservers(Events::COMPONENT_UPDATE_FOUND, id);
- break;
- case CrxUpdateItem::State::kUpdatingDiff:
- case CrxUpdateItem::State::kUpdating:
- NotifyObservers(Events::COMPONENT_UPDATE_READY, id);
- break;
- case CrxUpdateItem::State::kUpdated:
- NotifyObservers(Events::COMPONENT_UPDATED, id);
- break;
- case CrxUpdateItem::State::kUpToDate:
- case CrxUpdateItem::State::kNoUpdate:
- NotifyObservers(Events::COMPONENT_NOT_UPDATED, id);
- break;
- case CrxUpdateItem::State::kNew:
- case CrxUpdateItem::State::kDownloading:
- case CrxUpdateItem::State::kDownloadingDiff:
- case CrxUpdateItem::State::kDownloaded:
- case CrxUpdateItem::State::kUninstalled:
- case CrxUpdateItem::State::kLastStatus:
- // No notification for these states.
- break;
- }
-}
-
-size_t ActionImpl::ChangeAllItemsState(CrxUpdateItem::State from,
- CrxUpdateItem::State to) {
- DCHECK(thread_checker_.CalledOnValidThread());
- size_t count = 0;
- for (const auto& item : update_context_->update_items) {
- if (item.second->state == from) {
- ChangeItemState(item.second.get(), to);
- ++count;
- }
- }
- return count;
-}
-
-void ActionImpl::NotifyObservers(UpdateClient::Observer::Events event,
- const std::string& id) {
- DCHECK(thread_checker_.CalledOnValidThread());
- update_context_->notify_observers_callback.Run(event, id);
-}
-
-void ActionImpl::UpdateCrx() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!update_context_->queue.empty());
-
- const std::string& id = update_context_->queue.front();
- CrxUpdateItem* item = FindUpdateItemById(id);
- DCHECK(item);
-
- item->update_begin = base::TimeTicks::Now();
-
- if (item->component.supports_group_policy_enable_component_updates &&
- !update_context_->enabled_component_updates) {
- item->error_category = static_cast<int>(ErrorCategory::kServiceError);
- item->error_code = static_cast<int>(ServiceError::UPDATE_DISABLED);
- item->extra_code1 = 0;
- ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
-
- UpdateCrxComplete(item);
- return;
- }
-
- std::unique_ptr<Action> update_action(
- CanTryDiffUpdate(item, update_context_->config)
- ? ActionUpdateDiff::Create()
- : ActionUpdateFull::Create());
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&Action::Run, base::Unretained(update_action.get()),
- update_context_, callback_));
-
- update_context_->current_action = std::move(update_action);
-}
-
-void ActionImpl::UpdateCrxComplete(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item);
-
- update_context_->ping_manager->SendPing(item);
-
- update_context_->queue.pop();
-
- if (update_context_->queue.empty()) {
- UpdateComplete(Error::NONE);
- } else {
- DCHECK(!item->update_begin.is_null());
-
- // Assume that the cost of applying the update is proportional with how
- // long it took to apply it. Then delay the next update by the same time
- // interval or the value provided by the configurator, whichever is less.
- const base::TimeDelta max_update_delay =
- base::TimeDelta::FromSeconds(update_context_->config->UpdateDelay());
- const base::TimeDelta update_cost(base::TimeTicks::Now() -
- item->update_begin);
- DCHECK(update_cost >= base::TimeDelta());
-
- std::unique_ptr<ActionWait> action_wait(
- new ActionWait(std::min(update_cost, max_update_delay)));
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&Action::Run, base::Unretained(action_wait.get()),
- update_context_, callback_));
-
- update_context_->current_action = std::move(action_wait);
- }
-}
-
-void ActionImpl::UpdateComplete(Error error) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- base::Bind(callback_, error));
-}
-
-} // namespace update_client
diff --git a/chromium/components/update_client/action.h b/chromium/components/update_client/action.h
deleted file mode 100644
index 46397b993b5..00000000000
--- a/chromium/components/update_client/action.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2015 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_UPDATE_CLIENT_ACTION_H_
-#define COMPONENTS_UPDATE_CLIENT_ACTION_H_
-
-#include <stddef.h>
-
-#include <string>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "components/update_client/crx_update_item.h"
-#include "components/update_client/update_client.h"
-
-namespace update_client {
-
-enum class Error;
-struct CrxUpdateItem;
-struct UpdateContext;
-
-// Any update can be broken down as a sequence of discrete steps, such as
-// checking for updates, downloading patches, updating, and waiting between
-// successive updates. An action is the smallest unit of work executed by
-// the update engine.
-//
-// Defines an abstract interface for a unit of work, executed by the
-// update engine as part of an update.
-class Action {
- public:
- virtual ~Action() {}
-
- // Runs the code encapsulated by the action. When an action completes, it can
- // chain up and transfer the execution flow to another action or it can
- // invoke the |callback| when this function has completed and there is nothing
- // else to do.
- virtual void Run(UpdateContext* update_context, Callback callback) = 0;
-};
-
-// Provides a reusable implementation of common functions needed by actions.
-class ActionImpl {
- protected:
- ActionImpl();
- ~ActionImpl();
-
- void Run(UpdateContext* update_context, Callback callback);
-
- // Changes the current state of the |item| to the new state |to|.
- void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::State to);
-
- // Changes the state of all items in |update_context_|. Returns the count
- // of items affected by the call.
- size_t ChangeAllItemsState(CrxUpdateItem::State from,
- CrxUpdateItem::State to);
-
- // Returns the item associated with the component |id| or nullptr in case
- // of errors.
- CrxUpdateItem* FindUpdateItemById(const std::string& id) const;
-
- void NotifyObservers(UpdateClient::Observer::Events event,
- const std::string& id);
-
- // Updates the CRX at the front of the CRX queue in this update context.
- void UpdateCrx();
-
- // Completes updating the CRX at the front of the queue, and initiates
- // the update for the next CRX in the queue, if the queue is not empty.
- void UpdateCrxComplete(CrxUpdateItem* item);
-
- // Called when the updates for all CRXs have finished and the execution
- // flow must return back to the update engine.
- void UpdateComplete(Error error);
-
- base::ThreadChecker thread_checker_;
-
- UpdateContext* update_context_; // Not owned by this class.
- Callback callback_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ActionImpl);
-};
-
-} // namespace update_client
-
-#endif // COMPONENTS_UPDATE_CLIENT_ACTION_H_
diff --git a/chromium/components/update_client/action_update.cc b/chromium/components/update_client/action_update.cc
deleted file mode 100644
index 4d4fce297c2..00000000000
--- a/chromium/components/update_client/action_update.cc
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2015 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/update_client/action_update.h"
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "base/version.h"
-#include "components/update_client/component_unpacker.h"
-#include "components/update_client/configurator.h"
-#include "components/update_client/update_client_errors.h"
-#include "components/update_client/utils.h"
-
-using std::string;
-using std::vector;
-
-namespace update_client {
-
-namespace {
-
-void AppendDownloadMetrics(
- const std::vector<CrxDownloader::DownloadMetrics>& source,
- std::vector<CrxDownloader::DownloadMetrics>* destination) {
- destination->insert(destination->end(), source.begin(), source.end());
-}
-
-} // namespace
-
-ActionUpdate::ActionUpdate() {
-}
-
-ActionUpdate::~ActionUpdate() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void ActionUpdate::Run(UpdateContext* update_context, Callback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- ActionImpl::Run(update_context, callback);
-
- DCHECK(!update_context_->queue.empty());
-
- const std::string& id = update_context_->queue.front();
- CrxUpdateItem* item = FindUpdateItemById(id);
- DCHECK(item);
-
- StartDownload(item);
-}
-
-void ActionUpdate::StartDownload(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- crx_downloader_.reset((*update_context_->crx_downloader_factory)(
- IsBackgroundDownload(item),
- update_context_->config->RequestContext(),
- update_context_->blocking_task_runner)
- .release());
- OnDownloadStart(item);
-
- const std::string id = item->id;
- crx_downloader_->set_progress_callback(
- base::Bind(&ActionUpdate::DownloadProgress, base::Unretained(this), id));
- crx_downloader_->StartDownload(
- GetUrls(item), GetHash(item),
- base::Bind(&ActionUpdate::DownloadComplete, base::Unretained(this), id));
-}
-
-void ActionUpdate::DownloadProgress(
- const std::string& id,
- const CrxDownloader::Result& download_result) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(id == update_context_->queue.front());
-
- using Events = UpdateClient::Observer::Events;
- NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING, id);
-}
-
-void ActionUpdate::DownloadComplete(
- const std::string& id,
- const CrxDownloader::Result& download_result) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(id == update_context_->queue.front());
-
- CrxUpdateItem* item = FindUpdateItemById(id);
- DCHECK(item);
-
- AppendDownloadMetrics(crx_downloader_->download_metrics(),
- &item->download_metrics);
-
- crx_downloader_.reset();
-
- if (download_result.error) {
- OnDownloadError(item, download_result);
- } else {
- OnDownloadSuccess(item, download_result);
- update_context_->main_task_runner->PostTask(
- FROM_HERE,
- base::Bind(&ActionUpdate::StartInstall, base::Unretained(this), item,
- download_result.response));
- }
-}
-
-void ActionUpdate::StartInstall(CrxUpdateItem* item,
- const base::FilePath& crx_path) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->id == update_context_->queue.front());
-
- OnInstallStart(item);
-
- update_context_->blocking_task_runner->PostTask(
- FROM_HERE, base::Bind(&ActionUpdate::StartUnpackOnBlockingTaskRunner,
- base::Unretained(this), item, crx_path));
-}
-
-void ActionUpdate::StartUnpackOnBlockingTaskRunner(
- CrxUpdateItem* item,
- const base::FilePath& crx_path) {
- DCHECK(update_context_->blocking_task_runner->RunsTasksOnCurrentThread());
- unpacker_ = new ComponentUnpacker(
- item->component.pk_hash, crx_path,
- item->component.installer,
- update_context_->config->CreateOutOfProcessPatcher(),
- update_context_->blocking_task_runner);
- unpacker_->Unpack(
- base::Bind(&ActionUpdate::UnpackCompleteOnBlockingTaskRunner,
- base::Unretained(this), item, crx_path));
-}
-
-void ActionUpdate::UnpackCompleteOnBlockingTaskRunner(
- CrxUpdateItem* item,
- const base::FilePath& crx_path,
- const ComponentUnpacker::Result& result) {
- DCHECK(update_context_->blocking_task_runner->RunsTasksOnCurrentThread());
- unpacker_ = nullptr;
-
- if (result.error == UnpackerError::kNone) {
- update_context_->blocking_task_runner->PostTask(
- FROM_HERE,
- base::Bind(&ActionUpdate::StartInstallOnBlockingTaskRunner,
- base::Unretained(this), item, crx_path, result.unpack_path));
- } else {
- update_context_->blocking_task_runner->PostTask(
- FROM_HERE,
- base::Bind(&ActionUpdate::InstallCompleteOnBlockingTaskRunner,
- base::Unretained(this), item, crx_path,
- ErrorCategory::kUnpackError, static_cast<int>(result.error),
- result.extended_error));
- }
-}
-
-void ActionUpdate::StartInstallOnBlockingTaskRunner(
- CrxUpdateItem* item,
- const base::FilePath& crx_path,
- const base::FilePath& unpack_path) {
- DCHECK(update_context_->blocking_task_runner->RunsTasksOnCurrentThread());
- DCHECK(!unpack_path.empty());
-
- const auto result = DoInstall(item, crx_path, unpack_path);
- const ErrorCategory error_category =
- result.error ? ErrorCategory::kInstallError : ErrorCategory::kErrorNone;
- update_context_->blocking_task_runner->PostTask(
- FROM_HERE,
- base::Bind(&ActionUpdate::InstallCompleteOnBlockingTaskRunner,
- base::Unretained(this), item, crx_path, error_category,
- result.error, result.extended_error));
-}
-
-void ActionUpdate::InstallCompleteOnBlockingTaskRunner(
- CrxUpdateItem* item,
- const base::FilePath& crx_path,
- ErrorCategory error_category,
- int error,
- int extended_error) {
- update_client::DeleteFileAndEmptyParentDirectory(crx_path);
- update_context_->main_task_runner->PostTask(
- FROM_HERE,
- base::Bind(&ActionUpdate::InstallComplete, base::Unretained(this),
- item->id, error_category, error, extended_error));
-}
-
-CrxInstaller::Result ActionUpdate::DoInstall(
- CrxUpdateItem* item,
- const base::FilePath& crx_path,
- const base::FilePath& unpack_path) {
- const auto& fingerprint = item->next_fp;
- if (static_cast<int>(fingerprint.size()) !=
- base::WriteFile(
- unpack_path.Append(FILE_PATH_LITERAL("manifest.fingerprint")),
- fingerprint.c_str(), base::checked_cast<int>(fingerprint.size()))) {
- return CrxInstaller::Result(InstallError::FINGERPRINT_WRITE_FAILED);
- }
-
- std::unique_ptr<base::DictionaryValue> manifest = ReadManifest(unpack_path);
- if (!manifest.get())
- return CrxInstaller::Result(InstallError::BAD_MANIFEST);
-
- return item->component.installer->Install(*manifest, unpack_path);
-}
-
-void ActionUpdate::InstallComplete(const std::string& id,
- ErrorCategory error_category,
- int error,
- int extended_error) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(id == update_context_->queue.front());
-
- CrxUpdateItem* item = FindUpdateItemById(id);
- DCHECK(item);
-
- if (error == 0) {
- DCHECK_EQ(ErrorCategory::kErrorNone, error_category);
- DCHECK_EQ(0, extended_error);
- OnInstallSuccess(item);
- } else {
- OnInstallError(item, error_category, error, extended_error);
- }
-}
-
-ActionUpdateDiff::ActionUpdateDiff() {
-}
-
-ActionUpdateDiff::~ActionUpdateDiff() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-std::unique_ptr<Action> ActionUpdateDiff::Create() {
- return std::unique_ptr<Action>(new ActionUpdateDiff);
-}
-
-void ActionUpdateDiff::TryUpdateFull() {
- DCHECK(thread_checker_.CalledOnValidThread());
- std::unique_ptr<Action> update_action(ActionUpdateFull::Create());
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&Action::Run, base::Unretained(update_action.get()),
- update_context_, callback_));
-
- update_context_->current_action = std::move(update_action);
-}
-
-bool ActionUpdateDiff::IsBackgroundDownload(const CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- return false;
-}
-
-std::vector<GURL> ActionUpdateDiff::GetUrls(const CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- return item->crx_diffurls;
-}
-
-std::string ActionUpdateDiff::GetHash(const CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- return item->hashdiff_sha256;
-}
-
-void ActionUpdateDiff::OnDownloadStart(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kCanUpdate);
-
- ChangeItemState(item, CrxUpdateItem::State::kDownloadingDiff);
-}
-
-void ActionUpdateDiff::OnDownloadSuccess(
- CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
-
- ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
-}
-
-void ActionUpdateDiff::OnDownloadError(
- CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kDownloadingDiff);
-
- item->diff_error_category = static_cast<int>(ErrorCategory::kNetworkError);
- item->diff_error_code = download_result.error;
- item->diff_update_failed = true;
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
-}
-
-void ActionUpdateDiff::OnInstallStart(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- ChangeItemState(item, CrxUpdateItem::State::kUpdatingDiff);
-}
-
-void ActionUpdateDiff::OnInstallSuccess(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kUpdatingDiff);
-
- item->component.version = item->next_version;
- item->component.fingerprint = item->next_fp;
- ChangeItemState(item, CrxUpdateItem::State::kUpdated);
-
- UpdateCrxComplete(item);
-}
-
-void ActionUpdateDiff::OnInstallError(CrxUpdateItem* item,
- ErrorCategory error_category,
- int error,
- int extended_error) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- item->diff_error_category = static_cast<int>(error_category);
- item->diff_error_code = error;
- item->diff_extra_code1 = extended_error;
- item->diff_update_failed = true;
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&ActionUpdateDiff::TryUpdateFull, base::Unretained(this)));
-}
-
-ActionUpdateFull::ActionUpdateFull() {
-}
-
-ActionUpdateFull::~ActionUpdateFull() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-std::unique_ptr<Action> ActionUpdateFull::Create() {
- return std::unique_ptr<Action>(new ActionUpdateFull);
-}
-
-bool ActionUpdateFull::IsBackgroundDownload(const CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // On demand component updates are always downloaded in foreground.
- return !item->on_demand && item->component.allows_background_download &&
- update_context_->config->EnabledBackgroundDownloader();
-}
-
-std::vector<GURL> ActionUpdateFull::GetUrls(const CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- return item->crx_urls;
-}
-
-std::string ActionUpdateFull::GetHash(const CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- return item->hash_sha256;
-}
-
-void ActionUpdateFull::OnDownloadStart(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kCanUpdate ||
- item->diff_update_failed);
-
- ChangeItemState(item, CrxUpdateItem::State::kDownloading);
-}
-
-void ActionUpdateFull::OnDownloadSuccess(
- CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kDownloading);
-
- ChangeItemState(item, CrxUpdateItem::State::kDownloaded);
-}
-
-void ActionUpdateFull::OnDownloadError(
- CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kDownloading);
-
- item->error_category = static_cast<int>(ErrorCategory::kNetworkError);
- item->error_code = download_result.error;
- ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
-
- UpdateCrxComplete(item);
-}
-
-void ActionUpdateFull::OnInstallStart(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kDownloaded);
-
- ChangeItemState(item, CrxUpdateItem::State::kUpdating);
-}
-
-void ActionUpdateFull::OnInstallSuccess(CrxUpdateItem* item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kUpdating);
-
- item->component.version = item->next_version;
- item->component.fingerprint = item->next_fp;
- ChangeItemState(item, CrxUpdateItem::State::kUpdated);
-
- UpdateCrxComplete(item);
-}
-
-void ActionUpdateFull::OnInstallError(CrxUpdateItem* item,
- ErrorCategory error_category,
- int error,
- int extended_error) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(item->state == CrxUpdateItem::State::kUpdating);
-
- item->error_category = static_cast<int>(error_category);
- item->error_code = error;
- item->extra_code1 = extended_error;
- ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
-
- UpdateCrxComplete(item);
-}
-
-} // namespace update_client
diff --git a/chromium/components/update_client/action_update.h b/chromium/components/update_client/action_update.h
deleted file mode 100644
index 95061a68f86..00000000000
--- a/chromium/components/update_client/action_update.h
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2015 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_UPDATE_CLIENT_ACTION_UPDATE_H_
-#define COMPONENTS_UPDATE_CLIENT_ACTION_UPDATE_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "base/version.h"
-#include "components/update_client/action.h"
-#include "components/update_client/component_unpacker.h"
-#include "components/update_client/crx_downloader.h"
-#include "components/update_client/update_client.h"
-#include "components/update_client/update_engine.h"
-#include "url/gurl.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace update_client {
-
-enum class UnpackError;
-
-// Defines a template method design pattern for ActionUpdate. This class
-// implements the common code for updating a single CRX using either
-// a differential or a full update algorithm.
-// TODO(sorin): further refactor this class to enforce that there is a 1:1
-// relationship between one instance of this class and one CRX id. In other
-// words, make the CRX id and its associated CrxUpdateItem data structure
-// a member of this class instead of passing them around as function parameters.
-class ActionUpdate : public Action, protected ActionImpl {
- public:
- ActionUpdate();
- ~ActionUpdate() override;
-
- // Action overrides.
- void Run(UpdateContext* update_context, Callback callback) override;
-
- private:
- virtual bool IsBackgroundDownload(const CrxUpdateItem* item) = 0;
- virtual std::vector<GURL> GetUrls(const CrxUpdateItem* item) = 0;
- virtual std::string GetHash(const CrxUpdateItem* item) = 0;
- virtual void OnDownloadStart(CrxUpdateItem* item) = 0;
- virtual void OnDownloadSuccess(
- CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) = 0;
- virtual void OnDownloadError(
- CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) = 0;
- virtual void OnInstallStart(CrxUpdateItem* item) = 0;
- virtual void OnInstallSuccess(CrxUpdateItem* item) = 0;
- virtual void OnInstallError(CrxUpdateItem* item,
- ErrorCategory error_category,
- int error,
- int extended_error) = 0;
-
- void StartDownload(CrxUpdateItem* item);
- void DownloadComplete(const std::string& id,
- const CrxDownloader::Result& download_result);
-
- // Called when progress is being made downloading a CRX. The progress may
- // not monotonically increase due to how the CRX downloader switches between
- // different downloaders and fallback urls.
- void DownloadProgress(const std::string& id,
- const CrxDownloader::Result& download_result);
-
- void StartInstall(CrxUpdateItem* item, const base::FilePath& crx_path);
- void InstallComplete(const std::string& id,
- ErrorCategory error_category,
- int error,
- int extended_error);
-
- void StartUnpackOnBlockingTaskRunner(CrxUpdateItem* item,
- const base::FilePath& crx_path);
- void UnpackCompleteOnBlockingTaskRunner(
- CrxUpdateItem* item,
- const base::FilePath& crx_path,
- const ComponentUnpacker::Result& result);
-
- void StartInstallOnBlockingTaskRunner(CrxUpdateItem* item,
- const base::FilePath& crx_path,
- const base::FilePath& unpack_path);
- void InstallCompleteOnBlockingTaskRunner(CrxUpdateItem* item,
- const base::FilePath& crx_path,
- ErrorCategory error_category,
- int error,
- int extended_error);
-
- CrxInstaller::Result DoInstall(CrxUpdateItem* item,
- const base::FilePath& crx_path,
- const base::FilePath& unpack_path);
-
- // Downloads updates for one CRX id only.
- std::unique_ptr<CrxDownloader> crx_downloader_;
-
- // Unpacks one CRX.
- scoped_refptr<ComponentUnpacker> unpacker_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionUpdate);
-};
-
-class ActionUpdateDiff : public ActionUpdate {
- public:
- static std::unique_ptr<Action> Create();
-
- private:
- ActionUpdateDiff();
- ~ActionUpdateDiff() override;
-
- void TryUpdateFull();
-
- // ActionUpdate overrides.
- bool IsBackgroundDownload(const CrxUpdateItem* item) override;
- std::vector<GURL> GetUrls(const CrxUpdateItem* item) override;
- std::string GetHash(const CrxUpdateItem* item) override;
- void OnDownloadStart(CrxUpdateItem* item) override;
- void OnDownloadSuccess(CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) override;
- void OnDownloadError(CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) override;
- void OnInstallStart(CrxUpdateItem* item) override;
- void OnInstallSuccess(CrxUpdateItem* item) override;
- void OnInstallError(CrxUpdateItem* item,
- ErrorCategory error_category,
- int error,
- int extended_error) override;
-
- DISALLOW_COPY_AND_ASSIGN(ActionUpdateDiff);
-};
-
-class ActionUpdateFull : public ActionUpdate {
- public:
- static std::unique_ptr<Action> Create();
-
- private:
- ActionUpdateFull();
- ~ActionUpdateFull() override;
-
- // ActionUpdate overrides.
- bool IsBackgroundDownload(const CrxUpdateItem* item) override;
- std::vector<GURL> GetUrls(const CrxUpdateItem* item) override;
- std::string GetHash(const CrxUpdateItem* item) override;
- void OnDownloadStart(CrxUpdateItem* item) override;
- void OnDownloadSuccess(CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) override;
- void OnDownloadError(CrxUpdateItem* item,
- const CrxDownloader::Result& download_result) override;
- void OnInstallStart(CrxUpdateItem* item) override;
- void OnInstallSuccess(CrxUpdateItem* item) override;
- void OnInstallError(CrxUpdateItem* item,
- ErrorCategory error_category,
- int error,
- int extended_error) override;
-
- DISALLOW_COPY_AND_ASSIGN(ActionUpdateFull);
-};
-
-} // namespace update_client
-
-#endif // COMPONENTS_UPDATE_CLIENT_ACTION_UPDATE_H_
diff --git a/chromium/components/update_client/action_update_check.cc b/chromium/components/update_client/action_update_check.cc
deleted file mode 100644
index 2215affaa13..00000000000
--- a/chromium/components/update_client/action_update_check.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2015 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/update_client/action_update_check.h"
-
-#include <stddef.h>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/version.h"
-#include "components/update_client/action_update.h"
-#include "components/update_client/configurator.h"
-#include "components/update_client/update_checker.h"
-#include "components/update_client/update_client.h"
-#include "components/update_client/update_client_errors.h"
-#include "components/update_client/utils.h"
-
-using std::string;
-using std::vector;
-
-namespace update_client {
-
-namespace {
-
-// Returns true if the |proposed| version is newer than |current| version.
-bool IsVersionNewer(const base::Version& current, const std::string& proposed) {
- base::Version proposed_ver(proposed);
- return proposed_ver.IsValid() && current.CompareTo(proposed_ver) < 0;
-}
-
-} // namespace
-
-ActionUpdateCheck::ActionUpdateCheck(
- std::unique_ptr<UpdateChecker> update_checker,
- const base::Version& browser_version,
- const std::string& extra_request_parameters)
- : update_checker_(std::move(update_checker)),
- browser_version_(browser_version),
- extra_request_parameters_(extra_request_parameters) {}
-
-ActionUpdateCheck::~ActionUpdateCheck() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void ActionUpdateCheck::Run(UpdateContext* update_context, Callback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- ActionImpl::Run(update_context, callback);
-
- // Calls out to get the corresponding CrxComponent data for the CRXs in this
- // update context.
- vector<CrxComponent> crx_components;
- update_context_->crx_data_callback.Run(update_context_->ids, &crx_components);
-
- for (size_t i = 0; i != crx_components.size(); ++i) {
- std::unique_ptr<CrxUpdateItem> item = base::MakeUnique<CrxUpdateItem>();
- const CrxComponent& crx_component = crx_components[i];
-
- item->id = GetCrxComponentID(crx_component);
- item->component = crx_component;
- item->last_check = base::TimeTicks::Now();
- item->crx_urls.clear();
- item->crx_diffurls.clear();
- item->previous_version = crx_component.version;
- item->next_version = base::Version();
- item->previous_fp = crx_component.fingerprint;
- item->next_fp.clear();
- item->on_demand = update_context->is_foreground;
- item->diff_update_failed = false;
- item->error_category = 0;
- item->error_code = 0;
- item->extra_code1 = 0;
- item->diff_error_category = 0;
- item->diff_error_code = 0;
- item->diff_extra_code1 = 0;
- item->download_metrics.clear();
-
- CrxUpdateItem* item_ptr = item.get();
- update_context_->update_items[item_ptr->id] = std::move(item);
-
- ChangeItemState(item_ptr, CrxUpdateItem::State::kChecking);
- }
-
- update_checker_->CheckForUpdates(
- update_context_->update_items, extra_request_parameters_,
- update_context_->enabled_component_updates,
- base::Bind(&ActionUpdateCheck::UpdateCheckComplete,
- base::Unretained(this)));
-}
-
-void ActionUpdateCheck::UpdateCheckComplete(
- int error,
- const UpdateResponse::Results& results,
- int retry_after_sec) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- update_context_->retry_after_sec = retry_after_sec;
-
- if (!error)
- OnUpdateCheckSucceeded(results);
- else
- OnUpdateCheckFailed(error);
-}
-
-void ActionUpdateCheck::OnUpdateCheckSucceeded(
- const UpdateResponse::Results& results) {
- DCHECK(thread_checker_.CalledOnValidThread());
- VLOG(1) << "Update check succeeded.";
-
- for (const auto& result : results.list) {
- CrxUpdateItem* crx = FindUpdateItemById(result.extension_id);
- if (!crx) {
- VLOG(1) << "Component not found " << result.extension_id;
- continue;
- }
-
- DCHECK_EQ(CrxUpdateItem::State::kChecking, crx->state);
-
- if (result.status == "ok")
- HandleUpdateCheckOK(result, crx);
- else if (result.status == "noupdate")
- HandleUpdateCheckNoupdate(result, crx);
- else
- HandleUpdateCheckError(result, crx);
- }
-
- // All components that are not included in the update response are
- // considered up to date.
- ChangeAllItemsState(CrxUpdateItem::State::kChecking,
- CrxUpdateItem::State::kUpToDate);
-
- if (update_context_->queue.empty()) {
- VLOG(1) << "Update check completed but no action is needed.";
- UpdateComplete(Error::NONE);
- return;
- }
-
- // Starts the execution flow of updating the CRXs in this context.
- UpdateCrx();
-}
-
-void ActionUpdateCheck::HandleUpdateCheckOK(
- const UpdateResponse::Result& result,
- CrxUpdateItem* crx) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- const auto& manifest = result.manifest;
-
- if (manifest.version.empty()) {
- // It can't update without a manifest version.
- VLOG(1) << "No manifest version available for CRX: " << crx->id;
- ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
- return;
- }
-
- if (!IsVersionNewer(crx->component.version, manifest.version)) {
- // The CRX is up to date.
- VLOG(1) << "Component already up to date: " << crx->id;
- ChangeItemState(crx, CrxUpdateItem::State::kUpToDate);
- return;
- }
-
- if (!manifest.browser_min_version.empty()) {
- if (IsVersionNewer(browser_version_, manifest.browser_min_version)) {
- // The CRX is not compatible with this Chrome version.
- VLOG(1) << "Ignoring incompatible CRX: " << crx->id;
- ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
- return;
- }
- }
-
- if (manifest.packages.size() != 1) {
- // Assume one and only one package per CRX.
- VLOG(1) << "Ignoring multiple packages for CRX: " << crx->id;
- ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
- return;
- }
-
- // Parse the members of the result and queue an upgrade for this CRX.
- VLOG(1) << "Update found for CRX: " << crx->id;
-
- crx->next_version = base::Version(manifest.version);
- const auto& package = manifest.packages.front();
- crx->next_fp = package.fingerprint;
-
- // Resolve the urls by combining the base urls with the package names.
- for (const auto& crx_url : result.crx_urls) {
- const GURL url = crx_url.Resolve(package.name);
- if (url.is_valid())
- crx->crx_urls.push_back(url);
- }
- for (const auto& crx_diffurl : result.crx_diffurls) {
- const GURL url = crx_diffurl.Resolve(package.namediff);
- if (url.is_valid())
- crx->crx_diffurls.push_back(url);
- }
-
- crx->hash_sha256 = package.hash_sha256;
- crx->hashdiff_sha256 = package.hashdiff_sha256;
-
- ChangeItemState(crx, CrxUpdateItem::State::kCanUpdate);
-
- update_context_->queue.push(crx->id);
-}
-
-void ActionUpdateCheck::HandleUpdateCheckNoupdate(
- const UpdateResponse::Result& result,
- CrxUpdateItem* crx) {
- DCHECK(thread_checker_.CalledOnValidThread());
- VLOG(1) << "No update for CRX: " << crx->id;
- ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
-}
-
-void ActionUpdateCheck::HandleUpdateCheckError(
- const UpdateResponse::Result& result,
- CrxUpdateItem* crx) {
- DCHECK(thread_checker_.CalledOnValidThread());
- VLOG(1) << "Update error for CRX: " << crx->id << ", " << result.status;
- ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
-}
-
-void ActionUpdateCheck::OnUpdateCheckFailed(int error) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(error);
-
- VLOG(1) << "Update check failed." << error;
-
- ChangeAllItemsState(CrxUpdateItem::State::kChecking,
- CrxUpdateItem::State::kNoUpdate);
-
- UpdateComplete(Error::UPDATE_CHECK_ERROR);
-}
-
-} // namespace update_client
diff --git a/chromium/components/update_client/action_update_check.h b/chromium/components/update_client/action_update_check.h
deleted file mode 100644
index 46f5bf8a3fc..00000000000
--- a/chromium/components/update_client/action_update_check.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 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_UPDATE_CLIENT_ACTION_UPDATE_CHECK_H_
-#define COMPONENTS_UPDATE_CLIENT_ACTION_UPDATE_CHECK_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "base/version.h"
-#include "components/update_client/action.h"
-#include "components/update_client/crx_update_item.h"
-#include "components/update_client/update_client.h"
-#include "components/update_client/update_engine.h"
-#include "components/update_client/update_response.h"
-#include "url/gurl.h"
-
-namespace update_client {
-
-class UpdateChecker;
-
-// Implements an update check for the CRXs in an update context.
-class ActionUpdateCheck : public Action, private ActionImpl {
- public:
- ActionUpdateCheck(std::unique_ptr<UpdateChecker> update_checker,
- const base::Version& browser_version,
- const std::string& extra_request_parameters);
-
- ~ActionUpdateCheck() override;
-
- void Run(UpdateContext* update_context, Callback callback) override;
-
- private:
- void UpdateCheckComplete(int error,
- const UpdateResponse::Results& results,
- int retry_after_sec);
- void OnUpdateCheckSucceeded(const UpdateResponse::Results& results);
- void OnUpdateCheckFailed(int error);
-
- void HandleUpdateCheckOK(const UpdateResponse::Result& result,
- CrxUpdateItem* crx);
- void HandleUpdateCheckNoupdate(const UpdateResponse::Result& result,
- CrxUpdateItem* crx);
- void HandleUpdateCheckError(const UpdateResponse::Result& result,
- CrxUpdateItem* crx);
-
- std::unique_ptr<UpdateChecker> update_checker_;
- const base::Version browser_version_;
- const std::string extra_request_parameters_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionUpdateCheck);
-};
-
-} // namespace update_client
-
-#endif // COMPONENTS_UPDATE_CLIENT_ACTION_UPDATE_CHECK_H_
diff --git a/chromium/components/update_client/action_wait.cc b/chromium/components/update_client/action_wait.cc
deleted file mode 100644
index 9c69be27a27..00000000000
--- a/chromium/components/update_client/action_wait.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2015 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/update_client/action_wait.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/update_client/update_client_errors.h"
-#include "components/update_client/update_engine.h"
-
-namespace update_client {
-
-ActionWait::ActionWait(const base::TimeDelta& time_delta)
- : time_delta_(time_delta) {
-}
-
-ActionWait::~ActionWait() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void ActionWait::Run(UpdateContext* update_context, Callback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(update_context);
-
- ActionImpl::Run(update_context, callback);
-
- const bool result = base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&ActionWait::WaitComplete, base::Unretained(this)),
- time_delta_);
-
- if (!result) {
- // Move all items pending updates to the |kNoUpdate| state then return the
- // control flow to the update engine, as the updates in this context are
- // completed with an error.
- while (!update_context->queue.empty()) {
- auto* item = FindUpdateItemById(update_context->queue.front());
- DCHECK(item);
- item->error_category = static_cast<int>(ErrorCategory::kServiceError);
- item->error_code = static_cast<int>(ServiceError::SERVICE_WAIT_FAILED);
- ChangeItemState(item, CrxUpdateItem::State::kNoUpdate);
- update_context->queue.pop();
- }
- callback.Run(Error::SERVICE_ERROR);
- }
-
- NotifyObservers(UpdateClient::Observer::Events::COMPONENT_WAIT,
- update_context_->queue.front());
-}
-
-void ActionWait::WaitComplete() {
- DCHECK(thread_checker_.CalledOnValidThread());
- UpdateCrx();
-}
-
-} // namespace update_client
diff --git a/chromium/components/update_client/action_wait.h b/chromium/components/update_client/action_wait.h
deleted file mode 100644
index d54062b609d..00000000000
--- a/chromium/components/update_client/action_wait.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 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_UPDATE_CLIENT_ACTION_WAIT_H_
-#define COMPONENTS_UPDATE_CLIENT_ACTION_WAIT_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/time/time.h"
-
-#include "components/update_client/action.h"
-
-namespace update_client {
-
-// Implements a wait between handling updates for the CRXs in this context.
-// To avoid thrashing of local computing resources, updates are applied one
-// at a time, with a delay between them.
-class ActionWait : public Action, protected ActionImpl {
- public:
- explicit ActionWait(const base::TimeDelta& time_delta);
- ~ActionWait() override;
-
- void Run(UpdateContext* update_context, Callback callback) override;
-
- private:
- void WaitComplete();
-
- const base::TimeDelta time_delta_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionWait);
-};
-
-} // namespace update_client
-
-#endif // COMPONENTS_UPDATE_CLIENT_ACTION_WAIT_H_
diff --git a/chromium/components/update_client/background_downloader_win.cc b/chromium/components/update_client/background_downloader_win.cc
index 857e2bb4416..2c3766ff1bd 100644
--- a/chromium/components/update_client/background_downloader_win.cc
+++ b/chromium/components/update_client/background_downloader_win.cc
@@ -6,6 +6,7 @@
#include <atlbase.h>
#include <atlcom.h>
+#include <objbase.h>
#include <stddef.h>
#include <stdint.h>
@@ -131,16 +132,17 @@ const int kPurgeStaleJobsIntervalBetweenChecksDays = 1;
// Retrieves the singleton instance of GIT for this process.
HRESULT GetGit(ScopedComPtr<IGlobalInterfaceTable>* git) {
- return git->CreateInstance(CLSID_StdGlobalInterfaceTable, NULL,
- CLSCTX_INPROC_SERVER);
+ return ::CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(git->GetAddressOf()));
}
// Retrieves an interface pointer from the process GIT for a given |cookie|.
-template <typename T>
-HRESULT GetInterfaceFromGit(const ScopedComPtr<IGlobalInterfaceTable>& git,
+HRESULT GetInterfaceFromGit(IGlobalInterfaceTable* git,
DWORD cookie,
- ScopedComPtr<T>* p) {
- return git->GetInterfaceFromGlobal(cookie, __uuidof(T), p->ReceiveVoid());
+ REFIID riid,
+ void** ppv) {
+ return git->GetInterfaceFromGlobal(cookie, riid, ppv);
}
// Registers an interface pointer in GIT and returns its corresponding |cookie|.
@@ -148,7 +150,7 @@ template <typename T>
HRESULT RegisterInterfaceInGit(const ScopedComPtr<IGlobalInterfaceTable>& git,
const ScopedComPtr<T>& p,
DWORD* cookie) {
- return git->RegisterInterfaceInGlobal(p.get(), __uuidof(T), cookie);
+ return git->RegisterInterfaceInGlobal(p.Get(), __uuidof(T), cookie);
}
// Returns the status code from a given BITS error.
@@ -168,7 +170,7 @@ int GetHttpStatusFromBitsError(HRESULT error) {
HRESULT GetFilesInJob(IBackgroundCopyJob* job,
std::vector<ScopedComPtr<IBackgroundCopyFile>>* files) {
ScopedComPtr<IEnumBackgroundCopyFiles> enum_files;
- HRESULT hr = job->EnumFiles(enum_files.Receive());
+ HRESULT hr = job->EnumFiles(enum_files.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -179,7 +181,7 @@ HRESULT GetFilesInJob(IBackgroundCopyJob* job,
for (ULONG i = 0; i != num_files; ++i) {
ScopedComPtr<IBackgroundCopyFile> file;
- if (enum_files->Next(1, file.Receive(), NULL) == S_OK && file.get())
+ if (enum_files->Next(1, file.GetAddressOf(), NULL) == S_OK && file.Get())
files->push_back(file);
}
@@ -264,7 +266,7 @@ HRESULT GetJobDescription(IBackgroundCopyJob* job, const base::string16* name) {
HRESULT GetJobError(IBackgroundCopyJob* job, HRESULT* error_code_out) {
*error_code_out = S_OK;
ScopedComPtr<IBackgroundCopyError> copy_error;
- HRESULT hr = job->GetError(copy_error.Receive());
+ HRESULT hr = job->GetError(copy_error.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -286,7 +288,7 @@ HRESULT FindBitsJobIf(Predicate pred,
IBackgroundCopyManager* bits_manager,
std::vector<ScopedComPtr<IBackgroundCopyJob>>* jobs) {
ScopedComPtr<IEnumBackgroundCopyJobs> enum_jobs;
- HRESULT hr = bits_manager->EnumJobs(0, enum_jobs.Receive());
+ HRESULT hr = bits_manager->EnumJobs(0, enum_jobs.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -299,10 +301,10 @@ HRESULT FindBitsJobIf(Predicate pred,
// the job description matches the component updater jobs.
for (ULONG i = 0; i != job_count; ++i) {
ScopedComPtr<IBackgroundCopyJob> current_job;
- if (enum_jobs->Next(1, current_job.Receive(), NULL) == S_OK &&
- pred(current_job.get())) {
+ if (enum_jobs->Next(1, current_job.GetAddressOf(), NULL) == S_OK &&
+ pred(current_job.Get())) {
base::string16 job_description;
- hr = GetJobDescription(current_job.get(), &job_description);
+ hr = GetJobDescription(current_job.Get(), &job_description);
if (job_description.compare(kJobDescription) == 0)
jobs->push_back(current_job);
}
@@ -365,7 +367,8 @@ bool JobFileUrlEqual::operator()(IBackgroundCopyJob* job) const {
// Creates an instance of the BITS manager.
HRESULT CreateBitsManager(IBackgroundCopyManager** bits_manager) {
ScopedComPtr<IBackgroundCopyManager> object;
- HRESULT hr = object.CreateInstance(__uuidof(BackgroundCopyManager));
+ HRESULT hr = ::CoCreateInstance(__uuidof(BackgroundCopyManager), nullptr,
+ CLSCTX_ALL, IID_PPV_ARGS(&object));
if (FAILED(hr)) {
return hr;
}
@@ -379,7 +382,7 @@ void CleanupJobFiles(IBackgroundCopyJob* job) {
return;
for (size_t i = 0; i != files.size(); ++i) {
base::string16 local_name;
- HRESULT hr(GetJobFileProperties(files[i].get(), &local_name, NULL, NULL));
+ HRESULT hr(GetJobFileProperties(files[i].Get(), &local_name, NULL, NULL));
if (SUCCEEDED(hr))
DeleteFileAndEmptyParentDirectory(base::FilePath(local_name));
}
@@ -388,7 +391,7 @@ void CleanupJobFiles(IBackgroundCopyJob* job) {
// Cleans up incompleted jobs that are too old.
HRESULT CleanupStaleJobs(
const ScopedComPtr<IBackgroundCopyManager>& bits_manager) {
- if (!bits_manager.get())
+ if (!bits_manager.Get())
return E_FAIL;
static base::Time last_sweep;
@@ -404,13 +407,13 @@ HRESULT CleanupStaleJobs(
std::vector<ScopedComPtr<IBackgroundCopyJob>> jobs;
HRESULT hr = FindBitsJobIf(
JobCreationOlderThanDays(kPurgeStaleJobsAfterDays),
- bits_manager.get(), &jobs);
+ bits_manager.Get(), &jobs);
if (FAILED(hr))
return hr;
for (size_t i = 0; i != jobs.size(); ++i) {
jobs[i]->Cancel();
- CleanupJobFiles(jobs[i].get());
+ CleanupJobFiles(jobs[i].Get());
}
return S_OK;
@@ -483,7 +486,7 @@ HRESULT BackgroundDownloader::BeginDownloadHelper(const GURL& url) {
if (FAILED(hr))
return hr;
- hr = CreateBitsManager(bits_manager_.Receive());
+ hr = CreateBitsManager(bits_manager_.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -491,7 +494,7 @@ HRESULT BackgroundDownloader::BeginDownloadHelper(const GURL& url) {
if (FAILED(hr))
return hr;
- hr = QueueBitsJob(url, job_.Receive());
+ hr = QueueBitsJob(url, job_.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -581,11 +584,11 @@ void BackgroundDownloader::EndDownload(HRESULT error) {
int64_t downloaded_bytes = -1;
int64_t total_bytes = -1;
- GetJobByteCount(job_.get(), &downloaded_bytes, &total_bytes);
+ GetJobByteCount(job_.Get(), &downloaded_bytes, &total_bytes);
- if (FAILED(error) && job_.get()) {
+ if (FAILED(error) && job_.Get()) {
job_->Cancel();
- CleanupJobFiles(job_.get());
+ CleanupJobFiles(job_.Get());
}
CleanupStaleJobs(bits_manager_);
@@ -635,7 +638,7 @@ bool BackgroundDownloader::OnStateTransferred() {
// be made. Cancels this job and removes it from the BITS queue.
bool BackgroundDownloader::OnStateError() {
HRESULT error_code = S_OK;
- HRESULT hr = GetJobError(job_.get(), &error_code);
+ HRESULT hr = GetJobError(job_.Get(), &error_code);
if (FAILED(hr))
error_code = hr;
@@ -670,7 +673,7 @@ bool BackgroundDownloader::OnStateTransientError() {
// Don't retry at all if the transient error was a 5xx.
HRESULT error_code = S_OK;
- HRESULT hr = GetJobError(job_.get(), &error_code);
+ HRESULT hr = GetJobError(job_.Get(), &error_code);
if (SUCCEEDED(hr) &&
IsHttpServerError(GetHttpStatusFromBitsError(error_code))) {
return OnStateError();
@@ -695,7 +698,7 @@ bool BackgroundDownloader::OnStateTransferring() {
int64_t downloaded_bytes = -1;
int64_t total_bytes = -1;
- HRESULT hr = GetJobByteCount(job_.get(), &downloaded_bytes, &total_bytes);
+ HRESULT hr = GetJobByteCount(job_.Get(), &downloaded_bytes, &total_bytes);
if (FAILED(hr))
return false;
@@ -716,7 +719,7 @@ HRESULT BackgroundDownloader::QueueBitsJob(const GURL& url,
DCHECK(task_runner()->RunsTasksOnCurrentThread());
ScopedComPtr<IBackgroundCopyJob> p;
- HRESULT hr = CreateOrOpenJob(url, p.Receive());
+ HRESULT hr = CreateOrOpenJob(url, p.GetAddressOf());
if (FAILED(hr))
return hr;
@@ -741,7 +744,7 @@ HRESULT BackgroundDownloader::CreateOrOpenJob(const GURL& url,
std::vector<ScopedComPtr<IBackgroundCopyJob>> jobs;
HRESULT hr = FindBitsJobIf(
JobFileUrlEqual(base::SysUTF8ToWide(url.spec())),
- bits_manager_.get(), &jobs);
+ bits_manager_.Get(), &jobs);
if (SUCCEEDED(hr) && !jobs.empty()) {
*job = jobs.front().Detach();
return S_FALSE;
@@ -809,7 +812,7 @@ HRESULT BackgroundDownloader::CompleteJob() {
return hr;
std::vector<ScopedComPtr<IBackgroundCopyFile>> files;
- hr = GetFilesInJob(job_.get(), &files);
+ hr = GetFilesInJob(job_.Get(), &files);
if (FAILED(hr))
return hr;
@@ -818,7 +821,7 @@ HRESULT BackgroundDownloader::CompleteJob() {
base::string16 local_name;
BG_FILE_PROGRESS progress = {0};
- hr = GetJobFileProperties(files.front().get(), &local_name, NULL, &progress);
+ hr = GetJobFileProperties(files.front().Get(), &local_name, NULL, &progress);
if (FAILED(hr))
return hr;
@@ -842,12 +845,13 @@ HRESULT BackgroundDownloader::UpdateInterfacePointers() {
return hr;
bits_manager_ = nullptr;
- hr = GetInterfaceFromGit(git, git_cookie_bits_manager_, &bits_manager_);
+ hr = GetInterfaceFromGit(git.Get(), git_cookie_bits_manager_,
+ IID_PPV_ARGS(&bits_manager_));
if (FAILED(hr))
return hr;
job_ = nullptr;
- hr = GetInterfaceFromGit(git, git_cookie_job_, &job_);
+ hr = GetInterfaceFromGit(git.Get(), git_cookie_job_, IID_PPV_ARGS(&job_));
if (FAILED(hr))
return hr;
diff --git a/chromium/components/update_client/component.cc b/chromium/components/update_client/component.cc
new file mode 100644
index 00000000000..a63b5cdc680
--- /dev/null
+++ b/chromium/components/update_client/component.cc
@@ -0,0 +1,716 @@
+// Copyright 2017 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/update_client/component.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/files/file_util.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/update_client/component_unpacker.h"
+#include "components/update_client/configurator.h"
+#include "components/update_client/protocol_builder.h"
+#include "components/update_client/update_client.h"
+#include "components/update_client/update_client_errors.h"
+#include "components/update_client/update_engine.h"
+#include "components/update_client/utils.h"
+
+// The state machine representing how a CRX component changes during an update.
+//
+//
+// on-demand on-demand
+// +--------------------------> kNew <---------------+-------------+
+// | | | |
+// | V | |
+// | +---------------0----> kChecking -<-------+---|---<-----+ |
+// | | | | | | |
+// | | error V no | | | |
+// kUpdateError <------------- [update?] ->---- kUpToDate kUpdated
+// ^ | ^
+// | yes | |
+// | V |
+// | kCanUpdate |
+// | | |
+// | V no |
+// | [differential update?]--->----+ |
+// | | | |
+// | yes | | |
+// | V error | |
+// | kDownloadingDiff --->---------+ |
+// | | | |
+// | | | |
+// | V error | |
+// | kUpdatingDiff --->--------+-----------+ success
+// | | |
+// | error V |
+// +----------------------------------------- kDownloading |
+// | | |
+// | error V |
+// +------------------------------------------ kUpdating ->----+ success
+
+namespace update_client {
+
+namespace {
+
+using InstallOnBlockingTaskRunnerCompleteCallback =
+ base::Callback<void(int error_category, int error_code, int extra_code1)>;
+
+CrxInstaller::Result DoInstallOnBlockingTaskRunner(
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const base::FilePath& unpack_path,
+ const std::string& fingerprint,
+ const scoped_refptr<CrxInstaller>& installer,
+ InstallOnBlockingTaskRunnerCompleteCallback callback) {
+ DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
+
+ if (static_cast<int>(fingerprint.size()) !=
+ base::WriteFile(
+ unpack_path.Append(FILE_PATH_LITERAL("manifest.fingerprint")),
+ fingerprint.c_str(), base::checked_cast<int>(fingerprint.size()))) {
+ return CrxInstaller::Result(InstallError::FINGERPRINT_WRITE_FAILED);
+ }
+
+ std::unique_ptr<base::DictionaryValue> manifest = ReadManifest(unpack_path);
+ if (!manifest)
+ return CrxInstaller::Result(InstallError::BAD_MANIFEST);
+
+ return installer->Install(*manifest, unpack_path);
+}
+
+void InstallOnBlockingTaskRunner(
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const base::FilePath& unpack_path,
+ const std::string& fingerprint,
+ const scoped_refptr<CrxInstaller>& installer,
+ InstallOnBlockingTaskRunnerCompleteCallback callback) {
+ DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
+
+ DCHECK(base::DirectoryExists(unpack_path));
+ const auto result = DoInstallOnBlockingTaskRunner(
+ main_task_runner, blocking_task_runner, unpack_path, fingerprint,
+ installer, callback);
+ base::DeleteFile(unpack_path, true);
+
+ const ErrorCategory error_category =
+ result.error ? ErrorCategory::kInstallError : ErrorCategory::kErrorNone;
+ main_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(callback, static_cast<int>(error_category),
+ static_cast<int>(result.error), result.extended_error));
+}
+
+void UnpackCompleteOnBlockingTaskRunner(
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const base::FilePath& crx_path,
+ const std::string& fingerprint,
+ const scoped_refptr<CrxInstaller>& installer,
+ InstallOnBlockingTaskRunnerCompleteCallback callback,
+ const ComponentUnpacker::Result& result) {
+ DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
+
+ update_client::DeleteFileAndEmptyParentDirectory(crx_path);
+
+ if (result.error != UnpackerError::kNone) {
+ main_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(callback, static_cast<int>(ErrorCategory::kUnpackError),
+ static_cast<int>(result.error), result.extended_error));
+ return;
+ }
+
+ blocking_task_runner->PostTask(
+ FROM_HERE, base::Bind(&InstallOnBlockingTaskRunner, main_task_runner,
+ blocking_task_runner, result.unpack_path,
+ fingerprint, installer, callback));
+}
+
+void StartInstallOnBlockingTaskRunner(
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const std::vector<uint8_t>& pk_hash,
+ const base::FilePath& crx_path,
+ const std::string& fingerprint,
+ const scoped_refptr<CrxInstaller>& installer,
+ const scoped_refptr<OutOfProcessPatcher>& oop_patcher,
+ InstallOnBlockingTaskRunnerCompleteCallback callback) {
+ DCHECK(blocking_task_runner->RunsTasksOnCurrentThread());
+
+ auto unpacker = base::MakeRefCounted<ComponentUnpacker>(
+ pk_hash, crx_path, installer, oop_patcher, blocking_task_runner);
+
+ unpacker->Unpack(base::Bind(&UnpackCompleteOnBlockingTaskRunner,
+ main_task_runner, blocking_task_runner, crx_path,
+ fingerprint, installer, callback));
+}
+
+} // namespace
+
+Component::Component(const UpdateContext& update_context, const std::string& id)
+ : id_(id),
+ state_(base::MakeUnique<StateNew>(this)),
+ update_context_(update_context) {}
+
+Component::~Component() {}
+
+void Component::Handle(CallbackHandleComplete callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(state_);
+
+ callback_handle_complete_ = callback;
+
+ state_->Handle(base::Bind(&Component::ChangeState, base::Unretained(this)));
+}
+
+void Component::ChangeState(std::unique_ptr<State> next_state) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (next_state)
+ state_ = std::move(next_state);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ callback_handle_complete_);
+}
+
+CrxUpdateItem Component::GetCrxUpdateItem() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ CrxUpdateItem crx_update_item;
+ crx_update_item.state = state_->state();
+ crx_update_item.id = id_;
+ crx_update_item.component = crx_component_;
+ crx_update_item.last_check = last_check_;
+ crx_update_item.next_version = next_version_;
+ crx_update_item.next_fp = next_fp_;
+
+ return crx_update_item;
+}
+
+void Component::SetParseResult(const ProtocolParser::Result& result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ DCHECK_EQ(0, update_check_error_);
+
+ status_ = result.status;
+ action_run_ = result.action_run;
+
+ if (result.manifest.packages.empty())
+ return;
+
+ next_version_ = base::Version(result.manifest.version);
+ const auto& package = result.manifest.packages.front();
+ next_fp_ = package.fingerprint;
+
+ // Resolve the urls by combining the base urls with the package names.
+ for (const auto& crx_url : result.crx_urls) {
+ const GURL url = crx_url.Resolve(package.name);
+ if (url.is_valid())
+ crx_urls_.push_back(url);
+ }
+ for (const auto& crx_diffurl : result.crx_diffurls) {
+ const GURL url = crx_diffurl.Resolve(package.namediff);
+ if (url.is_valid())
+ crx_diffurls_.push_back(url);
+ }
+
+ hash_sha256_ = package.hash_sha256;
+ hashdiff_sha256_ = package.hashdiff_sha256;
+}
+
+void Component::Uninstall(const base::Version& version, int reason) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ DCHECK_EQ(ComponentState::kNew, state());
+
+ previous_version_ = version;
+ next_version_ = base::Version("0");
+ extra_code1_ = reason;
+
+ state_ = base::MakeUnique<StateUninstalled>(this);
+}
+
+void Component::UpdateCheckComplete() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ DCHECK_EQ(ComponentState::kChecking, state());
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ update_check_complete_);
+}
+
+bool Component::CanDoBackgroundDownload() const {
+ // On demand component updates are always downloaded in foreground.
+ return !on_demand_ && crx_component_.allows_background_download &&
+ update_context_.config->EnabledBackgroundDownloader();
+}
+
+void Component::AppendEvent(const std::string& event) {
+ events_.push_back(event);
+}
+
+void Component::NotifyObservers(UpdateClient::Observer::Events event) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ update_context_.notify_observers_callback.Run(event, id_);
+}
+
+base::TimeDelta Component::GetUpdateDuration() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (update_begin_.is_null())
+ return base::TimeDelta();
+
+ const base::TimeDelta update_cost(base::TimeTicks::Now() - update_begin_);
+ DCHECK_GE(update_cost, base::TimeDelta());
+ const base::TimeDelta max_update_delay =
+ base::TimeDelta::FromSeconds(update_context_.config->UpdateDelay());
+ return std::min(update_cost, max_update_delay);
+}
+
+Component::State::State(Component* component, ComponentState state)
+ : state_(state), component_(*component) {}
+
+Component::State::~State() {}
+
+void Component::State::Handle(CallbackNextState callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ callback_ = callback;
+
+ DCHECK(!is_final_);
+ DoHandle();
+}
+
+void Component::State::TransitionState(std::unique_ptr<State> next_state) {
+ if (!next_state)
+ is_final_ = true;
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback(), base::Passed(&next_state)));
+}
+
+Component::StateNew::StateNew(Component* component)
+ : State(component, ComponentState::kNew) {}
+
+Component::StateNew::~StateNew() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateNew::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = State::component();
+
+ TransitionState(base::MakeUnique<StateChecking>(&component));
+}
+
+Component::StateChecking::StateChecking(Component* component)
+ : State(component, ComponentState::kChecking) {}
+
+Component::StateChecking::~StateChecking() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+// Unlike how other states are handled, this function does not change the
+// state right away. The state transition happens when the UpdateChecker
+// calls Component::UpdateCheckComplete and |update_check_complete_| is invoked.
+// This is an artifact of how multiple components must be checked for updates
+// together but the state machine defines the transitions for one component
+// at a time.
+void Component::StateChecking::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = State::component();
+
+ component.last_check_ = base::TimeTicks::Now();
+ component.update_check_complete_ = base::Bind(
+ &Component::StateChecking::UpdateCheckComplete, base::Unretained(this));
+
+ component.NotifyObservers(Events::COMPONENT_CHECKING_FOR_UPDATES);
+}
+
+void Component::StateChecking::UpdateCheckComplete() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ auto& component = State::component();
+ if (!component.update_check_error_) {
+ if (component.status_ == "ok") {
+ TransitionState(base::MakeUnique<StateCanUpdate>(&component));
+ return;
+ }
+
+ if (component.status_ == "noupdate") {
+ TransitionState(base::MakeUnique<StateUpToDate>(&component));
+ return;
+ }
+ }
+
+ TransitionState(base::MakeUnique<StateUpdateError>(&component));
+}
+
+Component::StateUpdateError::StateUpdateError(Component* component)
+ : State(component, ComponentState::kUpdateError) {}
+
+Component::StateUpdateError::~StateUpdateError() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateUpdateError::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = State::component();
+
+ // Create an event only when the server response included an update.
+ if (component.IsUpdateAvailable())
+ component.AppendEvent(BuildUpdateCompleteEventElement(component));
+
+ TransitionState(nullptr);
+ component.NotifyObservers(Events::COMPONENT_NOT_UPDATED);
+}
+
+Component::StateCanUpdate::StateCanUpdate(Component* component)
+ : State(component, ComponentState::kCanUpdate) {}
+
+Component::StateCanUpdate::~StateCanUpdate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateCanUpdate::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = State::component();
+
+ component.is_update_available_ = true;
+ component.NotifyObservers(Events::COMPONENT_UPDATE_FOUND);
+
+ if (component.crx_component_.supports_group_policy_enable_component_updates &&
+ !component.update_context_.enabled_component_updates) {
+ component.error_category_ = static_cast<int>(ErrorCategory::kServiceError);
+ component.error_code_ = static_cast<int>(ServiceError::UPDATE_DISABLED);
+ component.extra_code1_ = 0;
+ TransitionState(base::MakeUnique<StateUpdateError>(&component));
+ return;
+ }
+
+ // Start computing the cost of the this update from here on.
+ component.update_begin_ = base::TimeTicks::Now();
+
+ if (CanTryDiffUpdate())
+ TransitionState(base::MakeUnique<StateDownloadingDiff>(&component));
+ else
+ TransitionState(base::MakeUnique<StateDownloading>(&component));
+}
+
+// Returns true if a differential update is available, it has not failed yet,
+// and the configuration allows this update.
+bool Component::StateCanUpdate::CanTryDiffUpdate() const {
+ const auto& component = Component::State::component();
+ return HasDiffUpdate(component) && !component.diff_error_code_ &&
+ component.update_context_.config->EnabledDeltas();
+}
+
+Component::StateUpToDate::StateUpToDate(Component* component)
+ : State(component, ComponentState::kUpToDate) {}
+
+Component::StateUpToDate::~StateUpToDate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateUpToDate::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = State::component();
+
+ TransitionState(nullptr);
+ component.NotifyObservers(Events::COMPONENT_NOT_UPDATED);
+}
+
+Component::StateDownloadingDiff::StateDownloadingDiff(Component* component)
+ : State(component, ComponentState::kDownloadingDiff) {}
+
+Component::StateDownloadingDiff::~StateDownloadingDiff() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateDownloadingDiff::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& component = Component::State::component();
+ const auto& update_context = component.update_context_;
+
+ crx_downloader_ = update_context.crx_downloader_factory(
+ component.CanDoBackgroundDownload(),
+ update_context.config->RequestContext(),
+ update_context.blocking_task_runner);
+
+ const auto& id = component.id_;
+ crx_downloader_->set_progress_callback(
+ base::Bind(&Component::StateDownloadingDiff::DownloadProgress,
+ base::Unretained(this), id));
+ crx_downloader_->StartDownload(
+ component.crx_diffurls_, component.hashdiff_sha256_,
+ base::Bind(&Component::StateDownloadingDiff::DownloadComplete,
+ base::Unretained(this), id));
+
+ component.NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
+}
+
+// Called when progress is being made downloading a CRX. The progress may
+// not monotonically increase due to how the CRX downloader switches between
+// different downloaders and fallback urls.
+void Component::StateDownloadingDiff::DownloadProgress(
+ const std::string& id,
+ const CrxDownloader::Result& download_result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ component().NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
+}
+
+void Component::StateDownloadingDiff::DownloadComplete(
+ const std::string& id,
+ const CrxDownloader::Result& download_result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = Component::State::component();
+
+ for (const auto& metrics : crx_downloader_->download_metrics())
+ component.AppendEvent(BuildDownloadCompleteEventElement(metrics));
+
+ crx_downloader_.reset();
+
+ if (download_result.error) {
+ component.diff_error_category_ =
+ static_cast<int>(ErrorCategory::kNetworkError);
+ component.diff_error_code_ = download_result.error;
+
+ TransitionState(base::MakeUnique<StateDownloading>(&component));
+ return;
+ }
+
+ component.crx_path_ = download_result.response;
+
+ TransitionState(base::MakeUnique<StateUpdatingDiff>(&component));
+}
+
+Component::StateDownloading::StateDownloading(Component* component)
+ : State(component, ComponentState::kDownloading) {}
+
+Component::StateDownloading::~StateDownloading() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateDownloading::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& component = Component::State::component();
+ const auto& update_context = component.update_context_;
+
+ crx_downloader_ = update_context.crx_downloader_factory(
+ component.CanDoBackgroundDownload(),
+ update_context.config->RequestContext(),
+ update_context.blocking_task_runner);
+
+ const auto& id = component.id_;
+ crx_downloader_->set_progress_callback(
+ base::Bind(&Component::StateDownloading::DownloadProgress,
+ base::Unretained(this), id));
+ crx_downloader_->StartDownload(
+ component.crx_urls_, component.hash_sha256_,
+ base::Bind(&Component::StateDownloading::DownloadComplete,
+ base::Unretained(this), id));
+
+ component.NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
+}
+
+// Called when progress is being made downloading a CRX. The progress may
+// not monotonically increase due to how the CRX downloader switches between
+// different downloaders and fallback urls.
+void Component::StateDownloading::DownloadProgress(
+ const std::string& id,
+ const CrxDownloader::Result& download_result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ component().NotifyObservers(Events::COMPONENT_UPDATE_DOWNLOADING);
+}
+
+void Component::StateDownloading::DownloadComplete(
+ const std::string& id,
+ const CrxDownloader::Result& download_result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = Component::State::component();
+
+ for (const auto& metrics : crx_downloader_->download_metrics())
+ component.AppendEvent(BuildDownloadCompleteEventElement(metrics));
+
+ crx_downloader_.reset();
+
+ if (download_result.error) {
+ component.error_category_ = static_cast<int>(ErrorCategory::kNetworkError);
+ component.error_code_ = download_result.error;
+
+ TransitionState(base::MakeUnique<StateUpdateError>(&component));
+ return;
+ }
+
+ component.crx_path_ = download_result.response;
+
+ TransitionState(base::MakeUnique<StateUpdating>(&component));
+}
+
+Component::StateUpdatingDiff::StateUpdatingDiff(Component* component)
+ : State(component, ComponentState::kUpdatingDiff) {}
+
+Component::StateUpdatingDiff::~StateUpdatingDiff() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateUpdatingDiff::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& component = Component::State::component();
+ const auto& update_context = component.update_context_;
+
+ component.NotifyObservers(Events::COMPONENT_UPDATE_READY);
+
+ update_context.blocking_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(&update_client::StartInstallOnBlockingTaskRunner,
+ base::ThreadTaskRunnerHandle::Get(),
+ update_context.blocking_task_runner,
+ component.crx_component_.pk_hash, component.crx_path_,
+ component.next_fp_, component.crx_component_.installer,
+ update_context.config->CreateOutOfProcessPatcher(),
+ base::Bind(&Component::StateUpdatingDiff::InstallComplete,
+ base::Unretained(this))));
+}
+
+void Component::StateUpdatingDiff::InstallComplete(int error_category,
+ int error_code,
+ int extra_code1) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = Component::State::component();
+
+ component.diff_error_category_ = error_category;
+ component.diff_error_code_ = error_code;
+ component.diff_extra_code1_ = extra_code1;
+
+ if (component.diff_error_code_ != 0) {
+ TransitionState(base::MakeUnique<StateDownloading>(&component));
+ return;
+ }
+
+ DCHECK_EQ(static_cast<int>(ErrorCategory::kErrorNone),
+ component.diff_error_category_);
+ DCHECK_EQ(0, component.diff_error_code_);
+ DCHECK_EQ(0, component.diff_extra_code1_);
+
+ DCHECK_EQ(static_cast<int>(ErrorCategory::kErrorNone),
+ component.error_category_);
+ DCHECK_EQ(0, component.error_code_);
+ DCHECK_EQ(0, component.extra_code1_);
+
+ TransitionState(base::MakeUnique<StateUpdated>(&component));
+}
+
+Component::StateUpdating::StateUpdating(Component* component)
+ : State(component, ComponentState::kUpdating) {}
+
+Component::StateUpdating::~StateUpdating() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateUpdating::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& component = Component::State::component();
+ const auto& update_context = component.update_context_;
+
+ component.NotifyObservers(Events::COMPONENT_UPDATE_READY);
+
+ update_context.blocking_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(&update_client::StartInstallOnBlockingTaskRunner,
+ base::ThreadTaskRunnerHandle::Get(),
+ update_context.blocking_task_runner,
+ component.crx_component_.pk_hash, component.crx_path_,
+ component.next_fp_, component.crx_component_.installer,
+ update_context.config->CreateOutOfProcessPatcher(),
+ base::Bind(&Component::StateUpdating::InstallComplete,
+ base::Unretained(this))));
+}
+
+void Component::StateUpdating::InstallComplete(int error_category,
+ int error_code,
+ int extra_code1) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = Component::State::component();
+
+ component.error_category_ = error_category;
+ component.error_code_ = error_code;
+ component.extra_code1_ = extra_code1;
+
+ if (component.error_code_ != 0) {
+ TransitionState(base::MakeUnique<StateUpdateError>(&component));
+ return;
+ }
+
+ DCHECK_EQ(static_cast<int>(ErrorCategory::kErrorNone),
+ component.error_category_);
+ DCHECK_EQ(0, component.error_code_);
+ DCHECK_EQ(0, component.extra_code1_);
+
+ TransitionState(base::MakeUnique<StateUpdated>(&component));
+}
+
+Component::StateUpdated::StateUpdated(Component* component)
+ : State(component, ComponentState::kUpdated) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+Component::StateUpdated::~StateUpdated() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateUpdated::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = State::component();
+ component.crx_component_.version = component.next_version_;
+ component.crx_component_.fingerprint = component.next_fp_;
+
+ component.AppendEvent(BuildUpdateCompleteEventElement(component));
+
+ TransitionState(nullptr);
+ component.NotifyObservers(Events::COMPONENT_UPDATED);
+}
+
+Component::StateUninstalled::StateUninstalled(Component* component)
+ : State(component, ComponentState::kUninstalled) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+Component::StateUninstalled::~StateUninstalled() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Component::StateUninstalled::DoHandle() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& component = State::component();
+ component.AppendEvent(BuildUninstalledEventElement(component));
+
+ TransitionState(nullptr);
+}
+
+} // namespace update_client
diff --git a/chromium/components/update_client/component.h b/chromium/components/update_client/component.h
new file mode 100644
index 00000000000..782a7148f46
--- /dev/null
+++ b/chromium/components/update_client/component.h
@@ -0,0 +1,421 @@
+// Copyright 2017 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_UPDATE_CLIENT_COMPONENT_H_
+#define COMPONENTS_UPDATE_CLIENT_COMPONENT_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
+#include "base/version.h"
+#include "components/update_client/crx_downloader.h"
+#include "components/update_client/protocol_parser.h"
+#include "components/update_client/update_client.h"
+#include "url/gurl.h"
+
+
+namespace update_client {
+
+struct CrxUpdateItem;
+struct UpdateContext;
+
+// Describes a CRX component managed by the UpdateEngine. Each |Component| is
+// associated with an UpdateContext.
+class Component {
+ public:
+ using Events = UpdateClient::Observer::Events;
+
+ using CallbackHandleComplete = base::Callback<void()>;
+
+ Component(const UpdateContext& update_context, const std::string& id);
+ ~Component();
+
+ // Handles the current state of the component and makes it transition
+ // to the next component state before |callback| is invoked.
+ void Handle(CallbackHandleComplete callback);
+
+ CrxUpdateItem GetCrxUpdateItem() const;
+
+ // Called by the UpdateChecker to set the update response for this component.
+ void SetParseResult(const ProtocolParser::Result& result);
+
+ // Sets the uninstall state for this component.
+ void Uninstall(const base::Version& cur_version, int reason);
+
+ // Called by the UpdateEngine when an update check for this component is done.
+ void UpdateCheckComplete() const;
+
+ // Returns true if the component has reached a final state and no further
+ // handling and state transitions are possible.
+ bool IsHandled() const { return state_->IsFinal(); }
+
+ // Returns true if an update is available for this component, meaning that
+ // the update server has return a response containing an update.
+ bool IsUpdateAvailable() const { return is_update_available_; }
+
+ base::TimeDelta GetUpdateDuration() const;
+
+ ComponentState state() const { return state_->state(); }
+
+ std::string id() const { return id_; }
+
+ const CrxComponent& crx_component() const { return crx_component_; }
+ void set_crx_component(const CrxComponent& crx_component) {
+ crx_component_ = crx_component;
+ }
+
+ const base::Version& previous_version() const { return previous_version_; }
+ void set_previous_version(const base::Version& previous_version) {
+ previous_version_ = previous_version;
+ }
+
+ const base::Version& next_version() const { return next_version_; }
+
+ std::string previous_fp() const { return previous_fp_; }
+ void set_previous_fp(const std::string& previous_fp) {
+ previous_fp_ = previous_fp;
+ }
+
+ std::string next_fp() const { return next_fp_; }
+ void set_next_fp(const std::string& next_fp) { next_fp_ = next_fp; }
+
+ int update_check_error() const { return update_check_error_; }
+ void set_update_check_error(int update_check_error) {
+ update_check_error_ = update_check_error;
+ }
+
+ // Returns the time when processing of an update for this component has
+ // begun, once the update has been discovered. Returns a null TimeTicks object
+ // if the handling of an update has not happened.
+ // base::TimeTicks update_begin() const { return update_begin_; }
+
+ bool on_demand() const { return on_demand_; }
+ void set_on_demand(bool on_demand) { on_demand_ = on_demand; }
+
+ const std::vector<std::string>& events() const { return events_; }
+
+ const std::vector<GURL>& crx_diffurls() const { return crx_diffurls_; }
+
+ bool diff_update_failed() const { return !!diff_error_code_; }
+
+ int error_category() const { return error_category_; }
+ int error_code() const { return error_code_; }
+ int extra_code1() const { return extra_code1_; }
+ int diff_error_category() const { return diff_error_category_; }
+ int diff_error_code() const { return diff_error_code_; }
+ int diff_extra_code1() const { return diff_extra_code1_; }
+
+ private:
+ friend class FakePingManagerImpl;
+ friend class UpdateCheckerTest;
+
+ FRIEND_TEST_ALL_PREFIXES(PingManagerTest, SendPing);
+ FRIEND_TEST_ALL_PREFIXES(PingManagerTest, RequiresEncryption);
+ FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, NoUpdateActionRun);
+ FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckCupError);
+ FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckError);
+ FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckInvalidAp);
+ FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest,
+ UpdateCheckRequiresEncryptionError);
+ FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckSuccess);
+ FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckUpdateDisabled);
+
+ // Describes an abstraction for implementing the behavior of a component and
+ // the transition from one state to another.
+ class State {
+ public:
+ using CallbackNextState =
+ base::Callback<void(std::unique_ptr<State> next_state)>;
+
+ State(Component* component, ComponentState state);
+ virtual ~State();
+
+ // Handles the current state and initiates a transition to a new state.
+ // The transition to the new state is non-blocking and it is completed
+ // by the outer component, after the current state is fully handled.
+ void Handle(CallbackNextState callback);
+
+ ComponentState state() const { return state_; }
+
+ bool IsFinal() const { return is_final_; }
+
+ protected:
+ // Initiates the transition to the new state.
+ void TransitionState(std::unique_ptr<State> new_state);
+
+ Component& component() { return component_; }
+ const Component& component() const { return component_; }
+
+ CallbackNextState callback() const { return callback_; }
+
+ base::ThreadChecker thread_checker_;
+
+ const ComponentState state_;
+
+ private:
+ virtual void DoHandle() = 0;
+
+ Component& component_;
+ CallbackNextState callback_;
+
+ bool is_final_ = false;
+ };
+
+ class StateNew : public State {
+ public:
+ explicit StateNew(Component* component);
+ ~StateNew() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ DISALLOW_COPY_AND_ASSIGN(StateNew);
+ };
+
+ class StateChecking : public State {
+ public:
+ explicit StateChecking(Component* component);
+ ~StateChecking() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ void UpdateCheckComplete();
+
+ DISALLOW_COPY_AND_ASSIGN(StateChecking);
+ };
+
+ class StateUpdateError : public State {
+ public:
+ explicit StateUpdateError(Component* component);
+ ~StateUpdateError() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ DISALLOW_COPY_AND_ASSIGN(StateUpdateError);
+ };
+
+ class StateCanUpdate : public State {
+ public:
+ explicit StateCanUpdate(Component* component);
+ ~StateCanUpdate() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+ bool CanTryDiffUpdate() const;
+
+ DISALLOW_COPY_AND_ASSIGN(StateCanUpdate);
+ };
+
+ class StateUpToDate : public State {
+ public:
+ explicit StateUpToDate(Component* component);
+ ~StateUpToDate() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ DISALLOW_COPY_AND_ASSIGN(StateUpToDate);
+ };
+
+ class StateDownloadingDiff : public State {
+ public:
+ explicit StateDownloadingDiff(Component* component);
+ ~StateDownloadingDiff() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ // Called when progress is being made downloading a CRX. The progress may
+ // not monotonically increase due to how the CRX downloader switches between
+ // different downloaders and fallback urls.
+ void DownloadProgress(const std::string& id,
+ const CrxDownloader::Result& download_result);
+
+ void DownloadComplete(const std::string& id,
+ const CrxDownloader::Result& download_result);
+
+ // Downloads updates for one CRX id only.
+ std::unique_ptr<CrxDownloader> crx_downloader_;
+
+ DISALLOW_COPY_AND_ASSIGN(StateDownloadingDiff);
+ };
+
+ class StateDownloading : public State {
+ public:
+ explicit StateDownloading(Component* component);
+ ~StateDownloading() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ // Called when progress is being made downloading a CRX. The progress may
+ // not monotonically increase due to how the CRX downloader switches between
+ // different downloaders and fallback urls.
+ void DownloadProgress(const std::string& id,
+ const CrxDownloader::Result& download_result);
+
+ void DownloadComplete(const std::string& id,
+ const CrxDownloader::Result& download_result);
+
+ // Downloads updates for one CRX id only.
+ std::unique_ptr<CrxDownloader> crx_downloader_;
+
+ DISALLOW_COPY_AND_ASSIGN(StateDownloading);
+ };
+
+ class StateUpdatingDiff : public State {
+ public:
+ explicit StateUpdatingDiff(Component* component);
+ ~StateUpdatingDiff() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ void InstallComplete(int error_category, int error_code, int extra_code1);
+
+ DISALLOW_COPY_AND_ASSIGN(StateUpdatingDiff);
+ };
+
+ class StateUpdating : public State {
+ public:
+ explicit StateUpdating(Component* component);
+ ~StateUpdating() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ void InstallComplete(int error_category, int error_code, int extra_code1);
+
+ DISALLOW_COPY_AND_ASSIGN(StateUpdating);
+ };
+
+ class StateUpdated : public State {
+ public:
+ explicit StateUpdated(Component* component);
+ ~StateUpdated() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ DISALLOW_COPY_AND_ASSIGN(StateUpdated);
+ };
+
+ class StateUninstalled : public State {
+ public:
+ explicit StateUninstalled(Component* component);
+ ~StateUninstalled() override;
+
+ private:
+ // State overrides.
+ void DoHandle() override;
+
+ DISALLOW_COPY_AND_ASSIGN(StateUninstalled);
+ };
+
+ // Returns true is the update payload for this component can be downloaded
+ // by a downloader which can do bandwidth throttling on the client side.
+ bool CanDoBackgroundDownload() const;
+
+ void AppendEvent(const std::string& event);
+
+ // Changes the component state and notifies the caller of the |Handle|
+ // function that the handling of this component state is complete.
+ void ChangeState(std::unique_ptr<State> next_state);
+
+ // Notifies registered observers about changes in the state of the component.
+ void NotifyObservers(Events event) const;
+
+ base::ThreadChecker thread_checker_;
+
+ const std::string id_;
+ CrxComponent crx_component_;
+
+ std::string status_;
+
+ // Time when an update check for this CRX has happened.
+ base::TimeTicks last_check_;
+
+ // Time when the update of this CRX has begun.
+ base::TimeTicks update_begin_;
+
+ // A component can be made available for download from several urls.
+ std::vector<GURL> crx_urls_;
+ std::vector<GURL> crx_diffurls_;
+
+ // The cryptographic hash values for the component payload.
+ std::string hash_sha256_;
+ std::string hashdiff_sha256_;
+
+ // The from/to version and fingerprint values.
+ base::Version previous_version_;
+ base::Version next_version_;
+ std::string previous_fp_;
+ std::string next_fp_;
+
+ // Contains the file name of the payload to run.
+ std::string action_run_;
+
+ // True if the update check response for this component includes an update.
+ bool is_update_available_ = false;
+
+ // True if the current update check cycle is on-demand.
+ bool on_demand_ = false;
+
+ // The error reported by the update checker.
+ int update_check_error_ = 0;
+
+ base::FilePath crx_path_;
+
+ // The error information for full and differential updates.
+ // The |error_category| contains a hint about which module in the component
+ // updater generated the error. The |error_code| constains the error and
+ // the |extra_code1| usually contains a system error, but it can contain
+ // any extended information that is relevant to either the category or the
+ // error itself.
+ int error_category_ = 0;
+ int error_code_ = 0;
+ int extra_code1_ = 0;
+ int diff_error_category_ = 0;
+ int diff_error_code_ = 0;
+ int diff_extra_code1_ = 0;
+
+ // Contains the events which are serialized in the pings.
+ std::vector<std::string> events_;
+
+ CallbackHandleComplete callback_handle_complete_;
+ std::unique_ptr<State> state_;
+ const UpdateContext& update_context_;
+
+ base::Closure update_check_complete_;
+
+ DISALLOW_COPY_AND_ASSIGN(Component);
+};
+
+using IdToComponentPtrMap = std::map<std::string, std::unique_ptr<Component>>;
+
+} // namespace update_client
+
+#endif // COMPONENTS_UPDATE_CLIENT_COMPONENT_H_
diff --git a/chromium/components/update_client/component_patcher.h b/chromium/components/update_client/component_patcher.h
index d1fe8c9bb31..3302d177305 100644
--- a/chromium/components/update_client/component_patcher.h
+++ b/chromium/components/update_client/component_patcher.h
@@ -32,6 +32,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
#include "base/values.h"
#include "components/update_client/component_unpacker.h"
diff --git a/chromium/components/update_client/component_patcher_operation.cc b/chromium/components/update_client/component_patcher_operation.cc
index f3fa282c13c..be7be1f3208 100644
--- a/chromium/components/update_client/component_patcher_operation.cc
+++ b/chromium/components/update_client/component_patcher_operation.cc
@@ -12,6 +12,7 @@
#include "base/files/memory_mapped_file.h"
#include "base/location.h"
#include "base/strings/string_number_conversions.h"
+#include "components/update_client/out_of_process_patcher.h"
#include "components/update_client/update_client.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h"
@@ -169,7 +170,7 @@ void DeltaUpdateOpCreate::DoRun(const ComponentPatcher::Callback& callback) {
DeltaUpdateOpPatch::DeltaUpdateOpPatch(
const std::string& operation,
- scoped_refptr<OutOfProcessPatcher> out_of_process_patcher)
+ const scoped_refptr<OutOfProcessPatcher>& out_of_process_patcher)
: operation_(operation), out_of_process_patcher_(out_of_process_patcher) {
DCHECK(operation == kBsdiff || operation == kCourgette);
}
diff --git a/chromium/components/update_client/component_patcher_operation.h b/chromium/components/update_client/component_patcher_operation.h
index aaf09c7b793..4520b986ffb 100644
--- a/chromium/components/update_client/component_patcher_operation.h
+++ b/chromium/components/update_client/component_patcher_operation.h
@@ -11,6 +11,7 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
#include "components/update_client/component_patcher.h"
#include "components/update_client/component_unpacker.h"
@@ -27,6 +28,7 @@ extern const char kInput[];
extern const char kPatch[];
class CrxInstaller;
+class OutOfProcessPatcher;
enum class UnpackerError;
class DeltaUpdateOp : public base::RefCountedThreadSafe<DeltaUpdateOp> {
@@ -126,24 +128,6 @@ class DeltaUpdateOpCreate : public DeltaUpdateOp {
DISALLOW_COPY_AND_ASSIGN(DeltaUpdateOpCreate);
};
-// An interface an embedder may fulfill to enable out-of-process patching.
-class OutOfProcessPatcher
- : public base::RefCountedThreadSafe<OutOfProcessPatcher> {
- public:
- virtual void Patch(
- const std::string& operation,
- scoped_refptr<base::SequencedTaskRunner> task_runner,
- const base::FilePath& input_abs_path,
- const base::FilePath& patch_abs_path,
- const base::FilePath& output_abs_path,
- base::Callback<void(int result)> callback) = 0;
-
- protected:
- friend class base::RefCountedThreadSafe<OutOfProcessPatcher>;
-
- virtual ~OutOfProcessPatcher() {}
-};
-
// Both 'bsdiff' and 'courgette' operations take an existing file on disk,
// and a bsdiff- or Courgette-format patch file provided in the delta update
// package, and run bsdiff or Courgette to construct an output file in the
@@ -151,8 +135,9 @@ class OutOfProcessPatcher
class DeltaUpdateOpPatch : public DeltaUpdateOp {
public:
// |out_of_process_patcher| may be NULL.
- DeltaUpdateOpPatch(const std::string& operation,
- scoped_refptr<OutOfProcessPatcher> out_of_process_patcher);
+ DeltaUpdateOpPatch(
+ const std::string& operation,
+ const scoped_refptr<OutOfProcessPatcher>& out_of_process_patcher);
private:
~DeltaUpdateOpPatch() override;
@@ -170,7 +155,7 @@ class DeltaUpdateOpPatch : public DeltaUpdateOp {
void DonePatching(const ComponentPatcher::Callback& callback, int result);
std::string operation_;
- scoped_refptr<OutOfProcessPatcher> out_of_process_patcher_;
+ const scoped_refptr<OutOfProcessPatcher> out_of_process_patcher_;
base::FilePath patch_abs_path_;
base::FilePath input_abs_path_;
diff --git a/chromium/components/update_client/component_patcher_unittest.h b/chromium/components/update_client/component_patcher_unittest.h
index d3d09eec309..b642a7c71e6 100644
--- a/chromium/components/update_client/component_patcher_unittest.h
+++ b/chromium/components/update_client/component_patcher_unittest.h
@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
+#include "base/sequenced_task_runner.h"
#include "courgette/courgette.h"
#include "courgette/third_party/bsdiff/bsdiff.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/components/update_client/component_unpacker.cc b/chromium/components/update_client/component_unpacker.cc
index 6dd555cc2ea..bc532b2d923 100644
--- a/chromium/components/update_client/component_unpacker.cc
+++ b/chromium/components/update_client/component_unpacker.cc
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "base/base64.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -21,18 +20,12 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
-#include "components/crx_file/crx_file.h"
+#include "components/crx_file/crx_verifier.h"
#include "components/update_client/component_patcher.h"
-#include "components/update_client/component_patcher_operation.h"
#include "components/update_client/update_client.h"
#include "components/update_client/update_client_errors.h"
-#include "crypto/secure_hash.h"
-#include "crypto/sha2.h"
#include "third_party/zlib/google/zip.h"
-using crypto::SecureHash;
-using crx_file::CrxFile;
-
namespace update_client {
// TODO(cpu): add a specific attribute check to a component json that the
@@ -90,33 +83,16 @@ bool ComponentUnpacker::Verify() {
error_ = UnpackerError::kInvalidParams;
return false;
}
- // First, validate the CRX header and signature. As of today
- // this is SHA1 with RSA 1024.
- std::string public_key_bytes;
- std::string public_key_base64;
- CrxFile::Header header;
- CrxFile::ValidateError error = CrxFile::ValidateSignature(
- path_, std::string(), &public_key_base64, nullptr, &header);
- if (error != CrxFile::ValidateError::NONE ||
- !base::Base64Decode(public_key_base64, &public_key_bytes)) {
+ const std::vector<std::vector<uint8_t>> required_keys = {pk_hash_};
+ const crx_file::VerifierResult result =
+ crx_file::Verify(path_, crx_file::VerifierFormat::CRX2_OR_CRX3,
+ required_keys, std::vector<uint8_t>(), nullptr, nullptr);
+ if (result != crx_file::VerifierResult::OK_FULL &&
+ result != crx_file::VerifierResult::OK_DELTA) {
error_ = UnpackerError::kInvalidFile;
return false;
}
- is_delta_ = CrxFile::HeaderIsDelta(header);
-
- // File is valid and the digital signature matches. Now make sure
- // the public key hash matches the expected hash. If they do we fully
- // trust this CRX.
- uint8_t hash[crypto::kSHA256Length] = {};
- std::unique_ptr<SecureHash> sha256(SecureHash::Create(SecureHash::SHA256));
- sha256->Update(public_key_bytes.data(), public_key_bytes.size());
- sha256->Finish(hash, arraysize(hash));
-
- if (!std::equal(pk_hash_.begin(), pk_hash_.end(), hash)) {
- VLOG(1) << "Hash mismatch: " << path_.value();
- error_ = UnpackerError::kInvalidId;
- return false;
- }
+ is_delta_ = result == crx_file::VerifierResult::OK_DELTA;
VLOG(1) << "Verification successful: " << path_.value();
return true;
}
diff --git a/chromium/components/update_client/component_unpacker.h b/chromium/components/update_client/component_unpacker.h
index dead6b61fcc..54fc6a9094c 100644
--- a/chromium/components/update_client/component_unpacker.h
+++ b/chromium/components/update_client/component_unpacker.h
@@ -17,13 +17,13 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
+#include "components/update_client/out_of_process_patcher.h"
#include "components/update_client/update_client_errors.h"
namespace update_client {
class CrxInstaller;
class ComponentPatcher;
-class OutOfProcessPatcher;
// Deserializes the CRX manifest. The top level must be a dictionary.
std::unique_ptr<base::DictionaryValue> ReadManifest(
diff --git a/chromium/components/update_client/component_unpacker_unittest.cc b/chromium/components/update_client/component_unpacker_unittest.cc
index 5b1a28cc9f3..e488c484301 100644
--- a/chromium/components/update_client/component_unpacker_unittest.cc
+++ b/chromium/components/update_client/component_unpacker_unittest.cc
@@ -12,11 +12,11 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
-#include "base/test/sequenced_worker_pool_owner.h"
-#include "components/update_client/component_patcher_operation.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "components/update_client/component_unpacker.h"
#include "components/update_client/test_configurator.h"
#include "components/update_client/test_installer.h"
@@ -73,24 +73,25 @@ class ComponentUnpackerTest : public testing::Test {
protected:
void RunThreads();
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_ =
+ base::ThreadTaskRunnerHandle::Get();
base::RunLoop runloop_;
base::Closure quit_closure_;
- std::unique_ptr<base::SequencedWorkerPoolOwner> worker_pool_;
scoped_refptr<update_client::TestConfigurator> config_;
ComponentUnpacker::Result result_;
};
ComponentUnpackerTest::ComponentUnpackerTest()
- : worker_pool_(new base::SequencedWorkerPoolOwner(2, "test")) {
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {
quit_closure_ = runloop_.QuitClosure();
- auto pool = worker_pool_->pool();
config_ = new TestConfigurator(
- pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
- message_loop_.task_runner());
+ base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
+ base::ThreadTaskRunnerHandle::Get());
}
ComponentUnpackerTest::~ComponentUnpackerTest() {}
@@ -102,7 +103,7 @@ void ComponentUnpackerTest::RunThreads() {
void ComponentUnpackerTest::UnpackComplete(
const ComponentUnpacker::Result& result) {
result_ = result;
- message_loop_.task_runner()->PostTask(FROM_HERE, quit_closure_);
+ main_thread_task_runner_->PostTask(FROM_HERE, quit_closure_);
}
TEST_F(ComponentUnpackerTest, UnpackFullCrx) {
@@ -160,7 +161,7 @@ TEST_F(ComponentUnpackerTest, UnpackFileHashMismatch) {
base::Unretained(this)));
RunThreads();
- EXPECT_EQ(UnpackerError::kInvalidId, result_.error);
+ EXPECT_EQ(UnpackerError::kInvalidFile, result_.error);
EXPECT_EQ(0, result_.extended_error);
EXPECT_TRUE(result_.unpack_path.empty());
diff --git a/chromium/components/update_client/crx_downloader_unittest.cc b/chromium/components/update_client/crx_downloader_unittest.cc
index ca9d4c77a27..aba14b116db 100644
--- a/chromium/components/update_client/crx_downloader_unittest.cc
+++ b/chromium/components/update_client/crx_downloader_unittest.cc
@@ -11,6 +11,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/update_client/crx_update_item.h b/chromium/components/update_client/crx_update_item.h
index 35b7e5a6593..2882a8421c9 100644
--- a/chromium/components/update_client/crx_update_item.h
+++ b/chromium/components/update_client/crx_update_item.h
@@ -18,65 +18,12 @@
namespace update_client {
-// This is the one and only per-item state structure. Designed to be hosted
-// in a std::vector or a std::list. The two main members are |component|
-// which is supplied by the the component updater client and |status| which
-// is modified as the item is processed by the update pipeline. The expected
-// transition graph is:
-//
-// on-demand on-demand
-// +---------------------------> kNew <--------------+-------------+
-// | | | |
-// | V | |
-// | +--------------------> kChecking -<-------+---|---<-----+ |
-// | | | | | | |
-// | | error V no | | | |
-// kNoUpdate <---------------- [update?] ->---- kUpToDate kUpdated
-// ^ | ^
-// | yes | |
-// | diff=false V |
-// | +-----------> kCanUpdate |
-// | | | |
-// | | V no |
-// | | [differential update?]->----+ |
-// | | | | |
-// | | yes | | |
-// | | error V | |
-// | +---------<- kDownloadingDiff | |
-// | | | | |
-// | | | | |
-// | | error V | |
-// | +---------<- kUpdatingDiff ->--------|-----------+ success
-// | | |
-// | error V |
-// +----------------------------------------- kDownloading |
-// | | |
-// | error V |
-// +------------------------------------------ kUpdating ->----+ success
-//
-// TODO(sorin): this data structure will be further refactored once
-// the new update service is in place. For the time being, it remains as-is,
-// since it is used by the old component update service.
struct CrxUpdateItem {
- enum class State {
- kNew,
- kChecking,
- kCanUpdate,
- kDownloadingDiff,
- kDownloading,
- kDownloaded,
- kUpdatingDiff,
- kUpdating,
- kUpdated,
- kUpToDate,
- kNoUpdate,
- kUninstalled,
- kLastStatus
- };
+ CrxUpdateItem();
+ CrxUpdateItem(const CrxUpdateItem& other);
+ ~CrxUpdateItem();
- // Call CrxUpdateService::ChangeItemState to change |status|. The function may
- // enforce conditions or notify observers of the change.
- State state;
+ ComponentState state;
std::string id;
CrxComponent component;
@@ -84,63 +31,10 @@ struct CrxUpdateItem {
// Time when an update check for this CRX has happened.
base::TimeTicks last_check;
- // Time when the update of this CRX has begun.
- base::TimeTicks update_begin;
-
- // A component can be made available for download from several urls.
- std::vector<GURL> crx_urls;
- std::vector<GURL> crx_diffurls;
-
- // The cryptographic hash values for the component payload.
- std::string hash_sha256;
- std::string hashdiff_sha256;
-
- // The from/to version and fingerprint values.
- base::Version previous_version;
base::Version next_version;
- std::string previous_fp;
std::string next_fp;
-
- // True if the current update check cycle is on-demand.
- bool on_demand;
-
- // True if the differential update failed for any reason.
- bool diff_update_failed;
-
- // The error information for full and differential updates.
- // The |error_category| contains a hint about which module in the component
- // updater generated the error. The |error_code| constains the error and
- // the |extra_code1| usually contains a system error, but it can contain
- // any extended information that is relevant to either the category or the
- // error itself.
- int error_category;
- int error_code;
- int extra_code1;
- int diff_error_category;
- int diff_error_code;
- int diff_extra_code1;
-
- std::vector<CrxDownloader::DownloadMetrics> download_metrics;
-
- CrxUpdateItem();
- CrxUpdateItem(const CrxUpdateItem& other);
- ~CrxUpdateItem();
-
- // Function object used to find a specific component.
- class FindById {
- public:
- explicit FindById(const std::string& id) : id_(id) {}
-
- bool operator()(CrxUpdateItem* item) const { return item->id == id_; }
-
- private:
- const std::string& id_;
- };
};
-using IdToCrxUpdateItemMap =
- std::map<std::string, std::unique_ptr<CrxUpdateItem>>;
-
} // namespace update_client
#endif // COMPONENTS_UPDATE_CLIENT_CRX_UPDATE_ITEM_H_
diff --git a/chromium/components/update_client/out_of_process_patcher.h b/chromium/components/update_client/out_of_process_patcher.h
new file mode 100644
index 00000000000..a41f01b223c
--- /dev/null
+++ b/chromium/components/update_client/out_of_process_patcher.h
@@ -0,0 +1,40 @@
+// Copyright 2017 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_UPDATE_CLIENT_OUT_OF_PROCESS_PATCHER_H_
+#define COMPONENTS_UPDATE_CLIENT_OUT_OF_PROCESS_PATCHER_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/memory/ref_counted.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
+namespace update_client {
+
+// An interface an embedder can implement to enable out-of-process patching.
+class OutOfProcessPatcher
+ : public base::RefCountedThreadSafe<OutOfProcessPatcher> {
+ public:
+ virtual void Patch(
+ const std::string& operation,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ const base::FilePath& input_abs_path,
+ const base::FilePath& patch_abs_path,
+ const base::FilePath& output_abs_path,
+ const base::Callback<void(int result)>& callback) = 0;
+
+ protected:
+ friend class base::RefCountedThreadSafe<OutOfProcessPatcher>;
+
+ virtual ~OutOfProcessPatcher() {}
+};
+
+} // namespace update_client
+
+#endif // COMPONENTS_UPDATE_CLIENT_OUT_OF_PROCESS_PATCHER_H_
diff --git a/chromium/components/update_client/ping_manager.cc b/chromium/components/update_client/ping_manager.cc
index 838e98b5880..66d9e2b970c 100644
--- a/chromium/components/update_client/ping_manager.cc
+++ b/chromium/components/update_client/ping_manager.cc
@@ -12,19 +12,14 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_checker.h"
#include "components/update_client/configurator.h"
-#include "components/update_client/crx_update_item.h"
+#include "components/update_client/protocol_builder.h"
#include "components/update_client/request_sender.h"
-#include "components/update_client/updater_state.h"
#include "components/update_client/utils.h"
#include "net/url_request/url_fetcher.h"
#include "url/gurl.h"
@@ -33,143 +28,6 @@ namespace update_client {
namespace {
-// Returns a string literal corresponding to the value of the downloader |d|.
-const char* DownloaderToString(CrxDownloader::DownloadMetrics::Downloader d) {
- switch (d) {
- case CrxDownloader::DownloadMetrics::kUrlFetcher:
- return "direct";
- case CrxDownloader::DownloadMetrics::kBits:
- return "bits";
- default:
- return "unknown";
- }
-}
-
-// Returns a string representing a sequence of download complete events
-// corresponding to each download metrics in |item|.
-std::string BuildDownloadCompleteEventElements(const CrxUpdateItem* item) {
- using base::StringAppendF;
- std::string download_events;
- for (size_t i = 0; i != item->download_metrics.size(); ++i) {
- const CrxDownloader::DownloadMetrics& metrics = item->download_metrics[i];
- std::string event("<event eventtype=\"14\"");
- StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0);
- StringAppendF(&event, " downloader=\"%s\"",
- DownloaderToString(metrics.downloader));
- if (metrics.error) {
- StringAppendF(&event, " errorcode=\"%d\"", metrics.error);
- }
- StringAppendF(&event, " url=\"%s\"", metrics.url.spec().c_str());
-
- // -1 means that the byte counts are not known.
- if (metrics.downloaded_bytes != -1) {
- StringAppendF(&event, " downloaded=\"%s\"",
- base::Int64ToString(metrics.downloaded_bytes).c_str());
- }
- if (metrics.total_bytes != -1) {
- StringAppendF(&event, " total=\"%s\"",
- base::Int64ToString(metrics.total_bytes).c_str());
- }
-
- if (metrics.download_time_ms) {
- StringAppendF(&event, " download_time_ms=\"%s\"",
- base::Uint64ToString(metrics.download_time_ms).c_str());
- }
- StringAppendF(&event, "/>");
-
- download_events += event;
- }
- return download_events;
-}
-
-// Returns a string representing one ping event for the update of an item.
-// The event type for this ping event is 3.
-std::string BuildUpdateCompleteEventElement(const CrxUpdateItem* item) {
- DCHECK(item->state == CrxUpdateItem::State::kNoUpdate ||
- item->state == CrxUpdateItem::State::kUpdated);
-
- using base::StringAppendF;
-
- std::string ping_event("<event eventtype=\"3\"");
- const int event_result = item->state == CrxUpdateItem::State::kUpdated;
- StringAppendF(&ping_event, " eventresult=\"%d\"", event_result);
- if (item->error_category)
- StringAppendF(&ping_event, " errorcat=\"%d\"", item->error_category);
- if (item->error_code)
- StringAppendF(&ping_event, " errorcode=\"%d\"", item->error_code);
- if (item->extra_code1)
- StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1);
- if (HasDiffUpdate(item))
- StringAppendF(&ping_event, " diffresult=\"%d\"", !item->diff_update_failed);
- if (item->diff_error_category) {
- StringAppendF(&ping_event, " differrorcat=\"%d\"",
- item->diff_error_category);
- }
- if (item->diff_error_code)
- StringAppendF(&ping_event, " differrorcode=\"%d\"", item->diff_error_code);
- if (item->diff_extra_code1) {
- StringAppendF(&ping_event, " diffextracode1=\"%d\"",
- item->diff_extra_code1);
- }
- if (!item->previous_fp.empty())
- StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str());
- if (!item->next_fp.empty())
- StringAppendF(&ping_event, " nextfp=\"%s\"", item->next_fp.c_str());
- StringAppendF(&ping_event, "/>");
- return ping_event;
-}
-
-// Returns a string representing one ping event for the uninstall of an item.
-// The event type for this ping event is 4.
-std::string BuildUninstalledEventElement(const CrxUpdateItem* item) {
- DCHECK(item->state == CrxUpdateItem::State::kUninstalled);
-
- using base::StringAppendF;
-
- std::string ping_event("<event eventtype=\"4\" eventresult=\"1\"");
- if (item->extra_code1)
- StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1);
- StringAppendF(&ping_event, "/>");
- return ping_event;
-}
-
-// Builds a ping message for the specified update item.
-std::string BuildPing(const Configurator& config, const CrxUpdateItem* item) {
- const char app_element_format[] =
- "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">"
- "%s"
- "%s"
- "</app>";
-
- std::string ping_event;
- switch (item->state) {
- case CrxUpdateItem::State::kNoUpdate: // Fall through.
- case CrxUpdateItem::State::kUpdated:
- ping_event = BuildUpdateCompleteEventElement(item);
- break;
- case CrxUpdateItem::State::kUninstalled:
- ping_event = BuildUninstalledEventElement(item);
- break;
- default:
- NOTREACHED();
- break;
- }
-
- const std::string app_element(base::StringPrintf(
- app_element_format,
- item->id.c_str(), // "appid"
- item->previous_version.GetString().c_str(), // "version"
- item->next_version.GetString().c_str(), // "nextversion"
- ping_event.c_str(), // ping event
- BuildDownloadCompleteEventElements(item).c_str())); // download events
-
- // The ping request does not include any updater state.
- return BuildProtocolRequest(
- config.GetProdId(), config.GetBrowserVersion().GetString(),
- config.GetChannel(), config.GetLang(), config.GetOSLongName(),
- config.GetDownloadPreference(), app_element, "", nullptr);
-}
-
// Sends a fire and forget ping. The instances of this class have no
// ownership and they self-delete upon completion. One instance of this class
// can send only one ping.
@@ -178,7 +36,7 @@ class PingSender {
explicit PingSender(const scoped_refptr<Configurator>& config);
~PingSender();
- bool SendPing(const CrxUpdateItem* item);
+ bool SendPing(const Component& component);
private:
void OnRequestSenderComplete(int error,
@@ -206,20 +64,22 @@ void PingSender::OnRequestSenderComplete(int error,
delete this;
}
-bool PingSender::SendPing(const CrxUpdateItem* item) {
- DCHECK(item);
+bool PingSender::SendPing(const Component& component) {
DCHECK(thread_checker_.CalledOnValidThread());
+ if (component.events().empty())
+ return false;
+
auto urls(config_->PingUrl());
- if (item->component.requires_network_encryption)
+ if (component.crx_component().requires_network_encryption)
RemoveUnsecureUrls(&urls);
if (urls.empty())
return false;
- request_sender_.reset(new RequestSender(config_));
+ request_sender_ = base::MakeUnique<RequestSender>(config_);
request_sender_->Send(
- false, BuildPing(*config_, item), urls,
+ false, BuildEventPingRequest(*config_, component), urls,
base::Bind(&PingSender::OnRequestSenderComplete, base::Unretained(this)));
return true;
}
@@ -230,11 +90,14 @@ PingManager::PingManager(const scoped_refptr<Configurator>& config)
: config_(config) {}
PingManager::~PingManager() {
+ DCHECK(thread_checker_.CalledOnValidThread());
}
-bool PingManager::SendPing(const CrxUpdateItem* item) {
- std::unique_ptr<PingSender> ping_sender(new PingSender(config_));
- if (!ping_sender->SendPing(item))
+bool PingManager::SendPing(const Component& component) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto ping_sender = base::MakeUnique<PingSender>(config_);
+ if (!ping_sender->SendPing(component))
return false;
// The ping sender object self-deletes after sending the ping asynchrously.
diff --git a/chromium/components/update_client/ping_manager.h b/chromium/components/update_client/ping_manager.h
index c907e7df2bb..3021a8b7bfa 100644
--- a/chromium/components/update_client/ping_manager.h
+++ b/chromium/components/update_client/ping_manager.h
@@ -7,11 +7,12 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/threading/thread_checker.h"
namespace update_client {
class Configurator;
-struct CrxUpdateItem;
+class Component;
// Sends fire-and-forget pings.
class PingManager {
@@ -23,9 +24,11 @@ class PingManager {
// ping is queued up and may be sent in the future, or false, if an error
// occurs right away. The ping itself is not persisted and it will be
// discarded if it can't be sent for any reason.
- virtual bool SendPing(const CrxUpdateItem* item);
+ virtual bool SendPing(const Component& component);
private:
+ base::ThreadChecker thread_checker_;
+
const scoped_refptr<Configurator> config_;
DISALLOW_COPY_AND_ASSIGN(PingManager);
diff --git a/chromium/components/update_client/ping_manager_unittest.cc b/chromium/components/update_client/ping_manager_unittest.cc
index 9795d6762e0..f555bf204a1 100644
--- a/chromium/components/update_client/ping_manager_unittest.cc
+++ b/chromium/components/update_client/ping_manager_unittest.cc
@@ -6,13 +6,18 @@
#include <memory>
#include <string>
+#include <vector>
+#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
-#include "components/update_client/crx_update_item.h"
+#include "components/update_client/component.h"
+#include "components/update_client/protocol_builder.h"
#include "components/update_client/test_configurator.h"
+#include "components/update_client/update_engine.h"
#include "components/update_client/url_request_post_interceptor.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,13 +26,15 @@ using std::string;
namespace update_client {
-class ComponentUpdaterPingManagerTest : public testing::Test {
+class PingManagerTest : public testing::Test {
public:
- ComponentUpdaterPingManagerTest();
- ~ComponentUpdaterPingManagerTest() override {}
+ PingManagerTest();
+ ~PingManagerTest() override {}
void RunThreadsUntilIdle();
+ std::unique_ptr<UpdateContext> MakeFakeUpdateContext() const;
+
// Overrides from testing::Test.
void SetUp() override;
void TearDown() override;
@@ -40,25 +47,31 @@ class ComponentUpdaterPingManagerTest : public testing::Test {
base::MessageLoopForIO loop_;
};
-ComponentUpdaterPingManagerTest::ComponentUpdaterPingManagerTest() {
-}
+PingManagerTest::PingManagerTest() {}
-void ComponentUpdaterPingManagerTest::SetUp() {
+void PingManagerTest::SetUp() {
config_ = new TestConfigurator(base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get());
ping_manager_.reset(new PingManager(config_));
}
-void ComponentUpdaterPingManagerTest::TearDown() {
+void PingManagerTest::TearDown() {
ping_manager_.reset();
config_ = nullptr;
}
-void ComponentUpdaterPingManagerTest::RunThreadsUntilIdle() {
+void PingManagerTest::RunThreadsUntilIdle() {
base::RunLoop().RunUntilIdle();
}
-TEST_F(ComponentUpdaterPingManagerTest, PingManagerTest) {
+std::unique_ptr<UpdateContext> PingManagerTest::MakeFakeUpdateContext() const {
+ return base::MakeUnique<UpdateContext>(
+ config_, false, std::vector<std::string>(),
+ UpdateClient::CrxDataCallback(), UpdateEngine::NotifyObserversCallback(),
+ UpdateEngine::Callback(), nullptr);
+}
+
+TEST_F(PingManagerTest, SendPing) {
std::unique_ptr<InterceptorFactory> interceptor_factory(
new InterceptorFactory(base::ThreadTaskRunnerHandle::Get()));
URLRequestPostInterceptor* interceptor =
@@ -66,115 +79,127 @@ TEST_F(ComponentUpdaterPingManagerTest, PingManagerTest) {
EXPECT_TRUE(interceptor);
// Test eventresult="1" is sent for successful updates.
- CrxUpdateItem item;
- item.id = "abc";
- item.state = CrxUpdateItem::State::kUpdated;
- item.previous_version = base::Version("1.0");
- item.next_version = base::Version("2.0");
+ const auto update_context = MakeFakeUpdateContext();
- ping_manager_->SendPing(&item);
- base::RunLoop().RunUntilIdle();
-
- EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
- EXPECT_NE(string::npos,
- interceptor->GetRequests()[0].find(
- "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
- "<event eventtype=\"3\" eventresult=\"1\"/></app>"))
- << interceptor->GetRequestsAsString();
- interceptor->Reset();
-
- // Test eventresult="0" is sent for failed updates.
- item = CrxUpdateItem();
- item.id = "abc";
- item.state = CrxUpdateItem::State::kNoUpdate;
- item.previous_version = base::Version("1.0");
- item.next_version = base::Version("2.0");
-
- ping_manager_->SendPing(&item);
- base::RunLoop().RunUntilIdle();
+ {
+ Component component(*update_context, "abc");
+
+ component.state_ = base::MakeUnique<Component::StateUpdated>(&component);
+ component.previous_version_ = base::Version("1.0");
+ component.next_version_ = base::Version("2.0");
+ component.AppendEvent(BuildUpdateCompleteEventElement(component));
+
+ ping_manager_->SendPing(component);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
+ EXPECT_NE(string::npos,
+ interceptor->GetRequests()[0].find(
+ "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\"/></app>"))
+ << interceptor->GetRequestsAsString();
+ interceptor->Reset();
+ }
- EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
- EXPECT_NE(string::npos,
- interceptor->GetRequests()[0].find(
- "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
- "<event eventtype=\"3\" eventresult=\"0\"/></app>"))
- << interceptor->GetRequestsAsString();
- interceptor->Reset();
-
- // Test the error values and the fingerprints.
- item = CrxUpdateItem();
- item.id = "abc";
- item.state = CrxUpdateItem::State::kNoUpdate;
- item.previous_version = base::Version("1.0");
- item.next_version = base::Version("2.0");
- item.previous_fp = "prev fp";
- item.next_fp = "next fp";
- item.error_category = 1;
- item.error_code = 2;
- item.extra_code1 = -1;
- item.diff_error_category = 10;
- item.diff_error_code = 20;
- item.diff_extra_code1 = -10;
- item.diff_update_failed = true;
- item.crx_diffurls.push_back(GURL("http://host/path"));
-
- ping_manager_->SendPing(&item);
- base::RunLoop().RunUntilIdle();
+ {
+ // Test eventresult="0" is sent for failed updates.
+ Component component(*update_context, "abc");
+ component.state_ =
+ base::MakeUnique<Component::StateUpdateError>(&component);
+ component.previous_version_ = base::Version("1.0");
+ component.next_version_ = base::Version("2.0");
+ component.AppendEvent(BuildUpdateCompleteEventElement(component));
+
+ ping_manager_->SendPing(component);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
+ EXPECT_NE(string::npos,
+ interceptor->GetRequests()[0].find(
+ "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+ "<event eventtype=\"3\" eventresult=\"0\"/></app>"))
+ << interceptor->GetRequestsAsString();
+ interceptor->Reset();
+ }
- EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
- EXPECT_NE(string::npos,
- interceptor->GetRequests()[0].find(
- "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
- "<event eventtype=\"3\" eventresult=\"0\" errorcat=\"1\" "
- "errorcode=\"2\" extracode1=\"-1\" diffresult=\"0\" "
- "differrorcat=\"10\" "
- "differrorcode=\"20\" diffextracode1=\"-10\" "
- "previousfp=\"prev fp\" nextfp=\"next fp\"/></app>"))
- << interceptor->GetRequestsAsString();
- interceptor->Reset();
-
- // Test the download metrics.
- item = CrxUpdateItem();
- item.id = "abc";
- item.state = CrxUpdateItem::State::kUpdated;
- item.previous_version = base::Version("1.0");
- item.next_version = base::Version("2.0");
-
- CrxDownloader::DownloadMetrics download_metrics;
- download_metrics.url = GURL("http://host1/path1");
- download_metrics.downloader = CrxDownloader::DownloadMetrics::kUrlFetcher;
- download_metrics.error = -1;
- download_metrics.downloaded_bytes = 123;
- download_metrics.total_bytes = 456;
- download_metrics.download_time_ms = 987;
- item.download_metrics.push_back(download_metrics);
-
- download_metrics = CrxDownloader::DownloadMetrics();
- download_metrics.url = GURL("http://host2/path2");
- download_metrics.downloader = CrxDownloader::DownloadMetrics::kBits;
- download_metrics.error = 0;
- download_metrics.downloaded_bytes = 1230;
- download_metrics.total_bytes = 4560;
- download_metrics.download_time_ms = 9870;
- item.download_metrics.push_back(download_metrics);
-
- ping_manager_->SendPing(&item);
- base::RunLoop().RunUntilIdle();
+ {
+ // Test the error values and the fingerprints.
+ Component component(*update_context, "abc");
+ component.state_ =
+ base::MakeUnique<Component::StateUpdateError>(&component);
+ component.previous_version_ = base::Version("1.0");
+ component.next_version_ = base::Version("2.0");
+ component.previous_fp_ = "prev fp";
+ component.next_fp_ = "next fp";
+ component.error_category_ = 1;
+ component.error_code_ = 2;
+ component.extra_code1_ = -1;
+ component.diff_error_category_ = 10;
+ component.diff_error_code_ = 20;
+ component.diff_extra_code1_ = -10;
+ component.crx_diffurls_.push_back(GURL("http://host/path"));
+ component.AppendEvent(BuildUpdateCompleteEventElement(component));
+
+ ping_manager_->SendPing(component);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
+ EXPECT_NE(string::npos,
+ interceptor->GetRequests()[0].find(
+ "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+ "<event eventtype=\"3\" eventresult=\"0\" errorcat=\"1\" "
+ "errorcode=\"2\" extracode1=\"-1\" diffresult=\"0\" "
+ "differrorcat=\"10\" "
+ "differrorcode=\"20\" diffextracode1=\"-10\" "
+ "previousfp=\"prev fp\" nextfp=\"next fp\"/></app>"))
+ << interceptor->GetRequestsAsString();
+ interceptor->Reset();
+ }
- EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
- EXPECT_NE(
- string::npos,
- interceptor->GetRequests()[0].find(
- "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
- "<event eventtype=\"3\" eventresult=\"1\"/>"
- "<event eventtype=\"14\" eventresult=\"0\" downloader=\"direct\" "
- "errorcode=\"-1\" url=\"http://host1/path1\" downloaded=\"123\" "
- "total=\"456\" download_time_ms=\"987\"/>"
- "<event eventtype=\"14\" eventresult=\"1\" downloader=\"bits\" "
- "url=\"http://host2/path2\" downloaded=\"1230\" total=\"4560\" "
- "download_time_ms=\"9870\"/></app>"))
- << interceptor->GetRequestsAsString();
- interceptor->Reset();
+ {
+ // Test the download metrics.
+ Component component(*update_context, "abc");
+ component.state_ = base::MakeUnique<Component::StateUpdated>(&component);
+ component.previous_version_ = base::Version("1.0");
+ component.next_version_ = base::Version("2.0");
+ component.AppendEvent(BuildUpdateCompleteEventElement(component));
+
+ CrxDownloader::DownloadMetrics download_metrics;
+ download_metrics.url = GURL("http://host1/path1");
+ download_metrics.downloader = CrxDownloader::DownloadMetrics::kUrlFetcher;
+ download_metrics.error = -1;
+ download_metrics.downloaded_bytes = 123;
+ download_metrics.total_bytes = 456;
+ download_metrics.download_time_ms = 987;
+ component.AppendEvent(BuildDownloadCompleteEventElement(download_metrics));
+
+ download_metrics = CrxDownloader::DownloadMetrics();
+ download_metrics.url = GURL("http://host2/path2");
+ download_metrics.downloader = CrxDownloader::DownloadMetrics::kBits;
+ download_metrics.error = 0;
+ download_metrics.downloaded_bytes = 1230;
+ download_metrics.total_bytes = 4560;
+ download_metrics.download_time_ms = 9870;
+ component.AppendEvent(BuildDownloadCompleteEventElement(download_metrics));
+
+ ping_manager_->SendPing(component);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
+ EXPECT_NE(
+ string::npos,
+ interceptor->GetRequests()[0].find(
+ "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+ "<event eventtype=\"3\" eventresult=\"1\"/>"
+ "<event eventtype=\"14\" eventresult=\"0\" downloader=\"direct\" "
+ "errorcode=\"-1\" url=\"http://host1/path1\" downloaded=\"123\" "
+ "total=\"456\" download_time_ms=\"987\"/>"
+ "<event eventtype=\"14\" eventresult=\"1\" downloader=\"bits\" "
+ "url=\"http://host2/path2\" downloaded=\"1230\" total=\"4560\" "
+ "download_time_ms=\"9870\"/></app>"))
+ << interceptor->GetRequestsAsString();
+ interceptor->Reset();
+ }
interceptor_factory.reset();
base::RunLoop().RunUntilIdle();
@@ -182,20 +207,22 @@ TEST_F(ComponentUpdaterPingManagerTest, PingManagerTest) {
// Tests that sending the ping fails when the component requires encryption but
// the ping URL is unsecure.
-TEST_F(ComponentUpdaterPingManagerTest, PingManagerRequiresEncryptionTest) {
+TEST_F(PingManagerTest, RequiresEncryption) {
config_->SetPingUrl(GURL("http:\\foo\bar"));
+ const auto update_context = MakeFakeUpdateContext();
+
{
- CrxUpdateItem item;
- item.component.requires_network_encryption = true;
+ Component component(*update_context, "abc");
+ component.crx_component_.requires_network_encryption = true;
- EXPECT_FALSE(ping_manager_->SendPing(&item));
+ EXPECT_FALSE(ping_manager_->SendPing(component));
}
{
// Tests that the default for |requires_network_encryption| is true.
- CrxUpdateItem item;
- EXPECT_FALSE(ping_manager_->SendPing(&item));
+ Component component(*update_context, "abc");
+ EXPECT_FALSE(ping_manager_->SendPing(component));
}
}
diff --git a/chromium/components/update_client/protocol_builder.cc b/chromium/components/update_client/protocol_builder.cc
new file mode 100644
index 00000000000..ab273ffe0ed
--- /dev/null
+++ b/chromium/components/update_client/protocol_builder.cc
@@ -0,0 +1,356 @@
+// Copyright 2017 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/update_client/protocol_builder.h"
+
+#include <stdint.h>
+
+#include "base/guid.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/sys_info.h"
+#include "build/build_config.h"
+#include "components/update_client/component.h"
+#include "components/update_client/configurator.h"
+#include "components/update_client/persisted_data.h"
+#include "components/update_client/protocol_parser.h"
+#include "components/update_client/update_query_params.h"
+#include "components/update_client/updater_state.h"
+#include "components/update_client/utils.h"
+
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
+namespace update_client {
+
+namespace {
+
+// Returns a sanitized version of the brand or an empty string otherwise.
+std::string SanitizeBrand(const std::string& brand) {
+ return IsValidBrand(brand) ? brand : std::string("");
+}
+
+// Filters invalid attributes from |installer_attributes|.
+InstallerAttributes SanitizeInstallerAttributes(
+ const InstallerAttributes& installer_attributes) {
+ InstallerAttributes sanitized_attrs;
+ for (const auto& attr : installer_attributes) {
+ if (IsValidInstallerAttribute(attr))
+ sanitized_attrs.insert(attr);
+ }
+ return sanitized_attrs;
+}
+
+// Returns the amount of physical memory in GB, rounded to the nearest GB.
+int GetPhysicalMemoryGB() {
+ const double kOneGB = 1024 * 1024 * 1024;
+ const int64_t phys_mem = base::SysInfo::AmountOfPhysicalMemory();
+ return static_cast<int>(std::floor(0.5 + phys_mem / kOneGB));
+}
+
+std::string GetOSVersion() {
+#if defined(OS_WIN)
+ const auto ver = base::win::OSInfo::GetInstance()->version_number();
+ return base::StringPrintf("%d.%d.%d.%d", ver.major, ver.minor, ver.build,
+ ver.patch);
+#else
+ return base::SysInfo().OperatingSystemVersion();
+#endif
+}
+
+std::string GetServicePack() {
+#if defined(OS_WIN)
+ return base::win::OSInfo::GetInstance()->service_pack_str();
+#else
+ return std::string();
+#endif
+}
+
+// Returns a string literal corresponding to the value of the downloader |d|.
+const char* DownloaderToString(CrxDownloader::DownloadMetrics::Downloader d) {
+ switch (d) {
+ case CrxDownloader::DownloadMetrics::kUrlFetcher:
+ return "direct";
+ case CrxDownloader::DownloadMetrics::kBits:
+ return "bits";
+ default:
+ return "unknown";
+ }
+}
+
+} // namespace
+
+std::string BuildDownloadCompleteEventElement(
+ const CrxDownloader::DownloadMetrics& metrics) {
+ using base::StringAppendF;
+
+ std::string event("<event eventtype=\"14\"");
+ StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0);
+ StringAppendF(&event, " downloader=\"%s\"",
+ DownloaderToString(metrics.downloader));
+ if (metrics.error) {
+ StringAppendF(&event, " errorcode=\"%d\"", metrics.error);
+ }
+ StringAppendF(&event, " url=\"%s\"", metrics.url.spec().c_str());
+
+ // -1 means that the byte counts are not known.
+ if (metrics.downloaded_bytes != -1) {
+ StringAppendF(&event, " downloaded=\"%s\"",
+ base::Int64ToString(metrics.downloaded_bytes).c_str());
+ }
+ if (metrics.total_bytes != -1) {
+ StringAppendF(&event, " total=\"%s\"",
+ base::Int64ToString(metrics.total_bytes).c_str());
+ }
+
+ if (metrics.download_time_ms) {
+ StringAppendF(&event, " download_time_ms=\"%s\"",
+ base::Uint64ToString(metrics.download_time_ms).c_str());
+ }
+ StringAppendF(&event, "/>");
+ return event;
+}
+
+std::string BuildUpdateCompleteEventElement(const Component& component) {
+ DCHECK(component.state() == ComponentState::kUpdateError ||
+ component.state() == ComponentState::kUpdated);
+
+ using base::StringAppendF;
+
+ std::string event("<event eventtype=\"3\"");
+ const int event_result = component.state() == ComponentState::kUpdated;
+ StringAppendF(&event, " eventresult=\"%d\"", event_result);
+ if (component.error_category())
+ StringAppendF(&event, " errorcat=\"%d\"", component.error_category());
+ if (component.error_code())
+ StringAppendF(&event, " errorcode=\"%d\"", component.error_code());
+ if (component.extra_code1())
+ StringAppendF(&event, " extracode1=\"%d\"", component.extra_code1());
+ if (HasDiffUpdate(component))
+ StringAppendF(&event, " diffresult=\"%d\"",
+ !component.diff_update_failed());
+ if (component.diff_error_category()) {
+ StringAppendF(&event, " differrorcat=\"%d\"",
+ component.diff_error_category());
+ }
+ if (component.diff_error_code())
+ StringAppendF(&event, " differrorcode=\"%d\"", component.diff_error_code());
+ if (component.diff_extra_code1()) {
+ StringAppendF(&event, " diffextracode1=\"%d\"",
+ component.diff_extra_code1());
+ }
+ if (!component.previous_fp().empty())
+ StringAppendF(&event, " previousfp=\"%s\"",
+ component.previous_fp().c_str());
+ if (!component.next_fp().empty())
+ StringAppendF(&event, " nextfp=\"%s\"", component.next_fp().c_str());
+ StringAppendF(&event, "/>");
+ return event;
+}
+
+std::string BuildUninstalledEventElement(const Component& component) {
+ DCHECK(component.state() == ComponentState::kUninstalled);
+
+ using base::StringAppendF;
+
+ std::string event("<event eventtype=\"4\" eventresult=\"1\"");
+ if (component.extra_code1())
+ StringAppendF(&event, " extracode1=\"%d\"", component.extra_code1());
+ StringAppendF(&event, "/>");
+ return event;
+}
+
+std::string BuildProtocolRequest(
+ const std::string& prod_id,
+ const std::string& browser_version,
+ const std::string& channel,
+ const std::string& lang,
+ const std::string& os_long_name,
+ const std::string& download_preference,
+ const std::string& request_body,
+ const std::string& additional_attributes,
+ const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes) {
+ std::string request = base::StringPrintf(
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<request protocol=\"%s\" ",
+ kProtocolVersion);
+
+ if (!additional_attributes.empty())
+ base::StringAppendF(&request, "%s ", additional_attributes.c_str());
+
+ // Constant information for this updater.
+ base::StringAppendF(&request, "dedup=\"cr\" acceptformat=\"crx2,crx3\" ");
+
+ // Chrome version and platform information.
+ base::StringAppendF(
+ &request,
+ "version=\"%s-%s\" prodversion=\"%s\" "
+ "requestid=\"{%s}\" lang=\"%s\" updaterchannel=\"%s\" prodchannel=\"%s\" "
+ "os=\"%s\" arch=\"%s\" nacl_arch=\"%s\"",
+ prod_id.c_str(), // "version" is prefixed by prod_id.
+ browser_version.c_str(),
+ browser_version.c_str(), // "prodversion"
+ base::GenerateGUID().c_str(), // "requestid"
+ lang.c_str(), // "lang"
+ channel.c_str(), // "updaterchannel"
+ channel.c_str(), // "prodchannel"
+ UpdateQueryParams::GetOS(), // "os"
+ UpdateQueryParams::GetArch(), // "arch"
+ UpdateQueryParams::GetNaclArch()); // "nacl_arch"
+#if defined(OS_WIN)
+ const bool is_wow64(base::win::OSInfo::GetInstance()->wow64_status() ==
+ base::win::OSInfo::WOW64_ENABLED);
+ if (is_wow64)
+ base::StringAppendF(&request, " wow64=\"1\"");
+#endif
+ if (!download_preference.empty())
+ base::StringAppendF(&request, " dlpref=\"%s\"",
+ download_preference.c_str());
+ if (updater_state_attributes &&
+ updater_state_attributes->count(UpdaterState::kIsEnterpriseManaged)) {
+ base::StringAppendF(
+ &request, " %s=\"%s\"", // domainjoined
+ UpdaterState::kIsEnterpriseManaged,
+ (*updater_state_attributes)[UpdaterState::kIsEnterpriseManaged]
+ .c_str());
+ }
+ base::StringAppendF(&request, ">");
+
+ // HW platform information.
+ base::StringAppendF(&request, "<hw physmemory=\"%d\"/>",
+ GetPhysicalMemoryGB()); // "physmem" in GB.
+
+ // OS version and platform information.
+ const std::string os_version = GetOSVersion();
+ const std::string os_sp = GetServicePack();
+ base::StringAppendF(
+ &request, "<os platform=\"%s\" arch=\"%s\"",
+ os_long_name.c_str(), // "platform"
+ base::SysInfo().OperatingSystemArchitecture().c_str()); // "arch"
+ if (!os_version.empty())
+ base::StringAppendF(&request, " version=\"%s\"", os_version.c_str());
+ if (!os_sp.empty())
+ base::StringAppendF(&request, " sp=\"%s\"", os_sp.c_str());
+ base::StringAppendF(&request, "/>");
+
+#if defined(GOOGLE_CHROME_BUILD)
+ // Updater state.
+ if (updater_state_attributes) {
+ base::StringAppendF(&request, "<updater");
+ for (const auto& attr : *updater_state_attributes) {
+ if (attr.first != UpdaterState::kIsEnterpriseManaged) {
+ base::StringAppendF(&request, " %s=\"%s\"", attr.first.c_str(),
+ attr.second.c_str());
+ }
+ }
+ base::StringAppendF(&request, "/>");
+ }
+#endif // GOOGLE_CHROME_BUILD
+
+ // The actual payload of the request.
+ base::StringAppendF(&request, "%s</request>", request_body.c_str());
+
+ return request;
+}
+
+std::string BuildUpdateCheckRequest(
+ const Configurator& config,
+ const std::vector<std::string>& ids_checked,
+ const IdToComponentPtrMap& components,
+ PersistedData* metadata,
+ const std::string& additional_attributes,
+ bool enabled_component_updates,
+ const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes) {
+ const std::string brand(SanitizeBrand(config.GetBrand()));
+ std::string app_elements;
+ for (const auto& id : ids_checked) {
+ DCHECK_EQ(1u, components.count(id));
+ const Component& component = *components.at(id);
+
+ const update_client::InstallerAttributes installer_attributes(
+ SanitizeInstallerAttributes(
+ component.crx_component().installer_attributes));
+ std::string app("<app ");
+ base::StringAppendF(&app, "appid=\"%s\" version=\"%s\"",
+ component.id().c_str(),
+ component.crx_component().version.GetString().c_str());
+ if (!brand.empty())
+ base::StringAppendF(&app, " brand=\"%s\"", brand.c_str());
+ if (component.on_demand())
+ base::StringAppendF(&app, " installsource=\"ondemand\"");
+ for (const auto& attr : installer_attributes) {
+ base::StringAppendF(&app, " %s=\"%s\"", attr.first.c_str(),
+ attr.second.c_str());
+ }
+ const std::string cohort = metadata->GetCohort(component.id());
+ const std::string cohort_name = metadata->GetCohortName(component.id());
+ const std::string cohort_hint = metadata->GetCohortHint(component.id());
+ if (!cohort.empty())
+ base::StringAppendF(&app, " cohort=\"%s\"", cohort.c_str());
+ if (!cohort_name.empty())
+ base::StringAppendF(&app, " cohortname=\"%s\"", cohort_name.c_str());
+ if (!cohort_hint.empty())
+ base::StringAppendF(&app, " cohorthint=\"%s\"", cohort_hint.c_str());
+ base::StringAppendF(&app, ">");
+
+ base::StringAppendF(&app, "<updatecheck");
+ if (component.crx_component()
+ .supports_group_policy_enable_component_updates &&
+ !enabled_component_updates) {
+ base::StringAppendF(&app, " updatedisabled=\"true\"");
+ }
+ base::StringAppendF(&app, "/>");
+
+ base::StringAppendF(&app, "<ping rd=\"%d\" ping_freshness=\"%s\"/>",
+ metadata->GetDateLastRollCall(component.id()),
+ metadata->GetPingFreshness(component.id()).c_str());
+ if (!component.crx_component().fingerprint.empty()) {
+ base::StringAppendF(&app,
+ "<packages>"
+ "<package fp=\"%s\"/>"
+ "</packages>",
+ component.crx_component().fingerprint.c_str());
+ }
+ base::StringAppendF(&app, "</app>");
+ app_elements.append(app);
+ VLOG(1) << "Appending to update request: " << app;
+ }
+
+ // Include the updater state in the update check request.
+ return BuildProtocolRequest(
+ config.GetProdId(), config.GetBrowserVersion().GetString(),
+ config.GetChannel(), config.GetLang(), config.GetOSLongName(),
+ config.GetDownloadPreference(), app_elements, additional_attributes,
+ updater_state_attributes);
+}
+
+std::string BuildEventPingRequest(const Configurator& config,
+ const Component& component) {
+ DCHECK(component.state() == ComponentState::kUpdateError ||
+ component.state() == ComponentState::kUpdated ||
+ component.state() == ComponentState::kUninstalled);
+
+ const char app_element_format[] =
+ "<app appid=\"%s\" version=\"%s\" nextversion=\"%s\">"
+ "%s"
+ "</app>";
+
+ const std::string app_element(base::StringPrintf(
+ app_element_format,
+ component.id().c_str(), // "appid"
+ component.previous_version().GetString().c_str(), // "version"
+ component.next_version().GetString().c_str(), // "nextversion"
+ base::JoinString(component.events(), "").c_str())); // events
+
+ // The ping request does not include any updater state.
+ return BuildProtocolRequest(
+ config.GetProdId(), config.GetBrowserVersion().GetString(),
+ config.GetChannel(), config.GetLang(), config.GetOSLongName(),
+ config.GetDownloadPreference(), app_element, "", nullptr);
+}
+
+} // namespace update_client
diff --git a/chromium/components/update_client/protocol_builder.h b/chromium/components/update_client/protocol_builder.h
new file mode 100644
index 00000000000..9b2f4a51ab2
--- /dev/null
+++ b/chromium/components/update_client/protocol_builder.h
@@ -0,0 +1,111 @@
+// Copyright 2017 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_UPDATE_CLIENT_PROTOCOL_BUILDER_H_
+#define COMPONENTS_UPDATE_CLIENT_PROTOCOL_BUILDER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "components/update_client/component.h"
+#include "components/update_client/crx_downloader.h"
+#include "components/update_client/updater_state.h"
+
+namespace update_client {
+
+class Configurator;
+class PersistedData;
+
+// Builds an update check request for |components|. |additional_attributes| is
+// serialized as part of the <request> element of the request to customize it
+// with data that is not platform or component specific. For each |item|, a
+// corresponding <app> element is created and inserted as a child node of
+// the <request>.
+//
+// <request protocol="3.0"....>
+// <app appid="hnimpnehoodheedghdeeijklkeaacbdc"
+// version="0.1.2.3" installsource="ondemand">
+// <updatecheck/>
+// <packages>
+// <package fp="abcd"/>
+// </packages>
+// </app>
+// </request>
+std::string BuildUpdateCheckRequest(
+ const Configurator& config,
+ const std::vector<std::string>& ids_checked,
+ const IdToComponentPtrMap& components,
+ PersistedData* metadata,
+ const std::string& additional_attributes,
+ bool enabled_component_updates,
+ const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes);
+
+// Builds a ping request for the specified component. The request contains one
+// or more ping events associated with this component. The events are
+// serialized as children of the <app> node. For example:
+//
+// <request protocol="3.0"....>
+// <app appid="hnimpnehoodheedghdeeijklkeaacbdc"
+// version="1.0" nextversion="2.0">
+// <event eventtype="3" eventresult="1"/>
+// <event eventtype="14\" eventresult="0" downloader="direct"
+// "errorcode="-1" url="http://host1/path1" downloaded="123"
+// "total="456"/>
+// </app>
+// </request>
+std::string BuildEventPingRequest(const Configurator& config,
+ const Component& component);
+
+// Returns a string representing one ping event for the update of a component.
+// The event type for this ping event is 3.
+std::string BuildUpdateCompleteEventElement(const Component& component);
+
+// Returns a string representing one ping event for the uninstall of a
+// component. The event type for this ping event is 4.
+std::string BuildUninstalledEventElement(const Component& component);
+
+// Returns a string representing a download complete event corresponding to
+// one download metrics instance. The event type for this ping event is 14.
+std::string BuildDownloadCompleteEventElement(
+ const CrxDownloader::DownloadMetrics& metrics);
+
+// An update protocol request starts with a common preamble which includes
+// version and platform information for Chrome and the operating system,
+// followed by a request body, which is the actual payload of the request.
+// For example:
+//
+// <?xml version="1.0" encoding="UTF-8"?>
+// <request protocol="3.0" version="chrome-32.0.1.0" prodversion="32.0.1.0"
+// requestid="{7383396D-B4DD-46E1-9104-AAC6B918E792}"
+// updaterchannel="canary" arch="x86" nacl_arch="x86-64"
+// ADDITIONAL ATTRIBUTES>
+// <hw physmemory="16"/>
+// <os platform="win" version="6.1" arch="x86"/>
+// ... REQUEST BODY ...
+// </request>
+
+// Builds a protocol request string by creating the outer envelope for
+// the request and including the request body specified as a parameter.
+// If present, the |download_preference| specifies a group policy that
+// affects the list of download URLs returned in the update response.
+// If specified, |additional_attributes| are appended as attributes of the
+// request element. The additional attributes have to be well-formed for
+// insertion in the request element. |updater_state_attributes| is an optional
+// parameter specifying that an <updater> element is serialized as part of
+// the request.
+std::string BuildProtocolRequest(
+ const std::string& prod_id,
+ const std::string& browser_version,
+ const std::string& channel,
+ const std::string& lang,
+ const std::string& os_long_name,
+ const std::string& download_preference,
+ const std::string& request_body,
+ const std::string& additional_attributes,
+ const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes);
+
+} // namespace update_client
+
+#endif // COMPONENTS_UPDATE_CLIENT_PROTOCOL_PARSER_H_
diff --git a/chromium/components/update_client/protocol_builder_unittest.cc b/chromium/components/update_client/protocol_builder_unittest.cc
new file mode 100644
index 00000000000..075e2f6c47e
--- /dev/null
+++ b/chromium/components/update_client/protocol_builder_unittest.cc
@@ -0,0 +1,69 @@
+// Copyright 2016 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 <string>
+
+#include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
+#include "base/path_service.h"
+#include "build/build_config.h"
+#include "components/update_client/protocol_builder.h"
+#include "components/update_client/updater_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using std::string;
+
+namespace update_client {
+
+TEST(UpdateClientUtils, BuildProtocolRequest_ProdIdVersion) {
+ // Verifies that |prod_id| and |version| are serialized.
+ const string request = BuildProtocolRequest("some_prod_id", "1.0", "", "", "",
+ "", "", "", nullptr);
+ EXPECT_NE(string::npos, request.find(" version=\"some_prod_id-1.0\" "));
+}
+
+TEST(UpdateClientUtils, BuildProtocolRequest_DownloadPreference) {
+ // Verifies that an empty |download_preference| is not serialized.
+ const string request_no_dlpref =
+ BuildProtocolRequest("", "", "", "", "", "", "", "", nullptr);
+ EXPECT_EQ(string::npos, request_no_dlpref.find(" dlpref="));
+
+ // Verifies that |download_preference| is serialized.
+ const string request_with_dlpref =
+ BuildProtocolRequest("", "", "", "", "", "some pref", "", "", nullptr);
+ EXPECT_NE(string::npos, request_with_dlpref.find(" dlpref=\"some pref\""));
+}
+
+TEST(UpdateClientUtils, BuildProtocolRequestUpdaterStateAttributes) {
+ // When no updater state is provided, then check that the elements and
+ // attributes related to the updater state are not serialized.
+ std::string request =
+ BuildProtocolRequest("", "", "", "", "", "", "", "", nullptr).c_str();
+ EXPECT_EQ(std::string::npos, request.find(" domainjoined"));
+ EXPECT_EQ(std::string::npos, request.find("<updater"));
+
+ UpdaterState::Attributes attributes;
+ attributes["domainjoined"] = "1";
+ attributes["name"] = "Omaha";
+ attributes["version"] = "1.2.3.4";
+ attributes["laststarted"] = "1";
+ attributes["lastchecked"] = "2";
+ attributes["autoupdatecheckenabled"] = "0";
+ attributes["updatepolicy"] = "-1";
+ request = BuildProtocolRequest(
+ "", "", "", "", "", "", "", "",
+ base::MakeUnique<UpdaterState::Attributes>(attributes));
+ EXPECT_NE(std::string::npos, request.find(" domainjoined=\"1\""));
+ const std::string updater_element =
+ "<updater autoupdatecheckenabled=\"0\" "
+ "lastchecked=\"2\" laststarted=\"1\" name=\"Omaha\" "
+ "updatepolicy=\"-1\" version=\"1.2.3.4\"/>";
+#if defined(GOOGLE_CHROME_BUILD)
+ EXPECT_NE(std::string::npos, request.find(updater_element));
+#else
+ EXPECT_EQ(std::string::npos, request.find(updater_element));
+#endif // GOOGLE_CHROME_BUILD
+}
+
+} // namespace update_client
diff --git a/chromium/components/update_client/update_response.cc b/chromium/components/update_client/protocol_parser.cc
index 7f621298871..74527d4b967 100644
--- a/chromium/components/update_client/update_response.cc
+++ b/chromium/components/update_client/protocol_parser.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/update_client/update_response.h"
+#include "components/update_client/protocol_parser.h"
#include <stddef.h>
@@ -20,41 +20,31 @@
namespace update_client {
-static const char* kExpectedResponseProtocol = "3.0";
-const char UpdateResponse::Result::kCohort[] = "cohort";
-const char UpdateResponse::Result::kCohortHint[] = "cohorthint";
-const char UpdateResponse::Result::kCohortName[] = "cohortname";
+const char ProtocolParser::Result::kCohort[] = "cohort";
+const char ProtocolParser::Result::kCohortHint[] = "cohorthint";
+const char ProtocolParser::Result::kCohortName[] = "cohortname";
-UpdateResponse::UpdateResponse() {
-}
-UpdateResponse::~UpdateResponse() {
-}
+ProtocolParser::ProtocolParser() = default;
+ProtocolParser::~ProtocolParser() = default;
-UpdateResponse::Results::Results() : daystart_elapsed_seconds(kNoDaystart) {
-}
-UpdateResponse::Results::Results(const Results& other) = default;
-UpdateResponse::Results::~Results() {
-}
+ProtocolParser::Results::Results() = default;
+ProtocolParser::Results::Results(const Results& other) = default;
+ProtocolParser::Results::~Results() = default;
-UpdateResponse::Result::Result() {}
-UpdateResponse::Result::Result(const Result& other) = default;
-UpdateResponse::Result::~Result() {
-}
+ProtocolParser::Result::Result() = default;
+ProtocolParser::Result::Result(const Result& other) = default;
+ProtocolParser::Result::~Result() = default;
-UpdateResponse::Result::Manifest::Manifest() {
-}
-UpdateResponse::Result::Manifest::Manifest(const Manifest& other) = default;
-UpdateResponse::Result::Manifest::~Manifest() {
-}
+ProtocolParser::Result::Manifest::Manifest() = default;
+ProtocolParser::Result::Manifest::Manifest(const Manifest& other) = default;
+ProtocolParser::Result::Manifest::~Manifest() = default;
-UpdateResponse::Result::Manifest::Package::Package() : size(0), sizediff(0) {
-}
-UpdateResponse::Result::Manifest::Package::Package(const Package& other) =
+ProtocolParser::Result::Manifest::Package::Package() = default;
+ProtocolParser::Result::Manifest::Package::Package(const Package& other) =
default;
-UpdateResponse::Result::Manifest::Package::~Package() {
-}
+ProtocolParser::Result::Manifest::Package::~Package() = default;
-void UpdateResponse::ParseError(const char* details, ...) {
+void ProtocolParser::ParseError(const char* details, ...) {
va_list args;
va_start(args, details);
@@ -138,9 +128,9 @@ class ScopedXmlDocument {
// Parses the <package> tag.
bool ParsePackageTag(xmlNode* package,
- UpdateResponse::Result* result,
+ ProtocolParser::Result* result,
std::string* error) {
- UpdateResponse::Result::Manifest::Package p;
+ ProtocolParser::Result::Manifest::Package p;
p.name = GetAttribute(package, "name");
if (p.name.empty()) {
*error = "Missing name for package.";
@@ -172,7 +162,7 @@ bool ParsePackageTag(xmlNode* package,
// Parses the <manifest> tag.
bool ParseManifestTag(xmlNode* manifest,
- UpdateResponse::Result* result,
+ ProtocolParser::Result* result,
std::string* error) {
// Get the version.
result->manifest.version = GetAttribute(manifest, "version");
@@ -220,7 +210,7 @@ bool ParseManifestTag(xmlNode* manifest,
// Parses the <urls> tag and its children in the <updatecheck>.
bool ParseUrlsTag(xmlNode* urls,
- UpdateResponse::Result* result,
+ ProtocolParser::Result* result,
std::string* error) {
// Get the url nodes.
std::vector<xmlNode*> url = GetChildren(urls, "url");
@@ -254,9 +244,23 @@ bool ParseUrlsTag(xmlNode* urls,
return true;
}
+// Parses the <actions> tag. It picks up the "run" attribute of the first
+// "action" element in "actions".
+void ParseActionsTag(xmlNode* updatecheck, ProtocolParser::Result* result) {
+ std::vector<xmlNode*> actions = GetChildren(updatecheck, "actions");
+ if (actions.empty())
+ return;
+
+ std::vector<xmlNode*> action = GetChildren(actions.front(), "action");
+ if (action.empty())
+ return;
+
+ result->action_run = GetAttribute(action.front(), "run");
+}
+
// Parses the <updatecheck> tag.
bool ParseUpdateCheckTag(xmlNode* updatecheck,
- UpdateResponse::Result* result,
+ ProtocolParser::Result* result,
std::string* error) {
// Read the |status| attribute.
result->status = GetAttribute(updatecheck, "status");
@@ -265,8 +269,10 @@ bool ParseUpdateCheckTag(xmlNode* updatecheck,
return false;
}
- if (result->status == "noupdate")
+ if (result->status == "noupdate") {
+ ParseActionsTag(updatecheck, result);
return true;
+ }
if (result->status == "ok") {
std::vector<xmlNode*> urls = GetChildren(updatecheck, "urls");
@@ -285,6 +291,7 @@ bool ParseUpdateCheckTag(xmlNode* updatecheck,
return false;
}
+ ParseActionsTag(updatecheck, result);
return ParseManifestTag(manifests[0], result, error);
}
@@ -295,13 +302,13 @@ bool ParseUpdateCheckTag(xmlNode* updatecheck,
// Parses a single <app> tag.
bool ParseAppTag(xmlNode* app,
- UpdateResponse::Result* result,
+ ProtocolParser::Result* result,
std::string* error) {
// Read cohort information.
auto cohort = GetAttributePtr(app, "cohort");
- static const char* attrs[] = {UpdateResponse::Result::kCohort,
- UpdateResponse::Result::kCohortHint,
- UpdateResponse::Result::kCohortName};
+ static const char* attrs[] = {ProtocolParser::Result::kCohort,
+ ProtocolParser::Result::kCohortHint,
+ ProtocolParser::Result::kCohortName};
for (auto* attr : attrs) {
auto value = GetAttributePtr(app, attr);
if (value)
@@ -325,7 +332,7 @@ bool ParseAppTag(xmlNode* app,
return ParseUpdateCheckTag(updates[0], result, error);
}
-bool UpdateResponse::Parse(const std::string& response_xml) {
+bool ProtocolParser::Parse(const std::string& response_xml) {
results_.daystart_elapsed_seconds = kNoDaystart;
results_.daystart_elapsed_days = kNoDaystart;
results_.list.clear();
@@ -359,11 +366,12 @@ bool UpdateResponse::Parse(const std::string& response_xml) {
}
// Check for the response "protocol" attribute.
- if (GetAttribute(root, "protocol") != kExpectedResponseProtocol) {
+ const auto protocol = GetAttribute(root, "protocol");
+ if (protocol != kProtocolVersion) {
ParseError(
"Missing/incorrect protocol on response tag "
- "(expected '%s')",
- kExpectedResponseProtocol);
+ "(expected '%s', found '%s')",
+ kProtocolVersion, protocol.c_str());
return false;
}
diff --git a/chromium/components/update_client/update_response.h b/chromium/components/update_client/protocol_parser.h
index 5f7ca572871..61bb4e1ed10 100644
--- a/chromium/components/update_client/update_response.h
+++ b/chromium/components/update_client/protocol_parser.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_UPDATE_CLIENT_UPDATE_RESPONSE_H_
-#define COMPONENTS_UPDATE_CLIENT_UPDATE_RESPONSE_H_
+#ifndef COMPONENTS_UPDATE_CLIENT_PROTOCOL_PARSER_H_
+#define COMPONENTS_UPDATE_CLIENT_PROTOCOL_PARSER_H_
#include <map>
#include <memory>
@@ -15,6 +15,11 @@
namespace update_client {
+// The protocol versions so far are:
+// * Version 3.1: it changes how the run actions are serialized.
+// * Version 3.0: it is the version implemented by the desktop updaters.
+constexpr char kProtocolVersion[] = "3.1";
+
// Parses responses for the update protocol version 3.
// (https://github.com/google/omaha/blob/wiki/ServerProtocolV3.md)
//
@@ -57,7 +62,7 @@ namespace update_client {
//
// The diff data members correspond to the differential update package, if
// a differential update is specified in the response.
-class UpdateResponse {
+class ProtocolParser {
public:
// The result of parsing one <app> tag in an xml update check response.
struct Result {
@@ -72,12 +77,12 @@ class UpdateResponse {
// Attributes for the full update.
std::string name;
std::string hash_sha256;
- int size;
+ int size = 0;
// Attributes for the differential update.
std::string namediff;
std::string hashdiff_sha256;
- int sizediff;
+ int sizediff = 0;
};
Manifest();
@@ -113,6 +118,10 @@ class UpdateResponse {
static const char kCohort[];
static const char kCohortHint[];
static const char kCohortName[];
+
+ // Contains the run action returned by the server as part of an update
+ // check response.
+ std::string action_run;
};
static const int kNoDaystart = -1;
@@ -122,14 +131,15 @@ class UpdateResponse {
~Results();
// This will be >= 0, or kNoDaystart if the <daystart> tag was not present.
- int daystart_elapsed_seconds;
+ int daystart_elapsed_seconds = kNoDaystart;
+
// This will be >= 0, or kNoDaystart if the <daystart> tag was not present.
- int daystart_elapsed_days;
+ int daystart_elapsed_days = kNoDaystart;
std::vector<Result> list;
};
- UpdateResponse();
- ~UpdateResponse();
+ ProtocolParser();
+ ~ProtocolParser();
// Parses an update response xml string into Result data. Returns a bool
// indicating success or failure. On success, the results are available by
@@ -148,9 +158,9 @@ class UpdateResponse {
// Adds parse error details to |errors_| string.
void ParseError(const char* details, ...);
- DISALLOW_COPY_AND_ASSIGN(UpdateResponse);
+ DISALLOW_COPY_AND_ASSIGN(ProtocolParser);
};
} // namespace update_client
-#endif // COMPONENTS_UPDATE_CLIENT_UPDATE_RESPONSE_H_
+#endif // COMPONENTS_UPDATE_CLIENT_PROTOCOL_PARSER_H_
diff --git a/chromium/components/update_client/update_response_unittest.cc b/chromium/components/update_client/protocol_parser_unittest.cc
index d29cbe0d596..e34f1869dcf 100644
--- a/chromium/components/update_client/update_response_unittest.cc
+++ b/chromium/components/update_client/protocol_parser_unittest.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/update_client/update_response.h"
+#include "components/update_client/protocol_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace update_client {
const char* kValidXml =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345'>"
" <updatecheck status='ok'>"
" <urls>"
@@ -27,7 +27,7 @@ const char* kValidXml =
const char* valid_xml_with_hash =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345'>"
" <updatecheck status='ok'>"
" <urls>"
@@ -45,7 +45,7 @@ const char* valid_xml_with_hash =
const char* valid_xml_with_invalid_sizes =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345'>"
" <updatecheck status='ok'>"
" <urls>"
@@ -67,7 +67,7 @@ const char* valid_xml_with_invalid_sizes =
const char* kInvalidValidXmlMissingCodebase =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345'>"
" <updatecheck status='ok'>"
" <urls>"
@@ -84,7 +84,7 @@ const char* kInvalidValidXmlMissingCodebase =
const char* kInvalidValidXmlMissingManifest =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345'>"
" <updatecheck status='ok'>"
" <urls>"
@@ -96,7 +96,7 @@ const char* kInvalidValidXmlMissingManifest =
const char* kMissingAppId =
"<?xml version='1.0'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app>"
" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
" version='1.2.3.4'/>"
@@ -105,7 +105,7 @@ const char* kMissingAppId =
const char* kInvalidCodebase =
"<?xml version='1.0'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345' status='ok'>"
" <updatecheck codebase='example.com/extension_1.2.3.4.crx'"
" version='1.2.3.4'/>"
@@ -114,7 +114,7 @@ const char* kInvalidCodebase =
const char* kMissingVersion =
"<?xml version='1.0'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345' status='ok'>"
" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'/>"
" </app>"
@@ -122,7 +122,7 @@ const char* kMissingVersion =
const char* kInvalidVersion =
"<?xml version='1.0'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345' status='ok'>"
" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' "
" version='1.2.3.a'/>"
@@ -134,7 +134,7 @@ const char* kInvalidVersion =
const char* kUsesNamespacePrefix =
"<?xml version='1.0' encoding='UTF-8'?>"
"<g:response xmlns:g='http://www.google.com/update2/response' "
- "protocol='3.0'>"
+ "protocol='3.1'>"
" <g:app appid='12345'>"
" <g:updatecheck status='ok'>"
" <g:urls>"
@@ -153,7 +153,7 @@ const char* kUsesNamespacePrefix =
// not cause problems.
const char* kSimilarTagnames =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response xmlns:a='http://a' protocol='3.0'>"
+ "<response xmlns:a='http://a' protocol='3.1'>"
" <a:app appid='12345'>"
" <updatecheck status='ok'>"
" <urls>"
@@ -174,7 +174,7 @@ const char* kSimilarTagnames =
// Includes a <daystart> tag.
const char* kWithDaystart =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <daystart elapsed_seconds='456'/>"
" <app appid='12345'>"
" <updatecheck status='ok'>"
@@ -193,7 +193,7 @@ const char* kWithDaystart =
// Indicates no updates available - this should not be a parse error.
const char* kNoUpdate =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='12345'>"
" <updatecheck status='noupdate'/>"
" </app>"
@@ -202,7 +202,7 @@ const char* kNoUpdate =
// Includes two <app> tags, one with an error.
const char* kTwoAppsOneError =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='aaaaaaaa' status='error-unknownApplication'>"
" <updatecheck status='error-internal'/>"
" </app>"
@@ -223,7 +223,7 @@ const char* kTwoAppsOneError =
// Includes two <app> tags, both of which set the cohort.
const char* kTwoAppsSetCohort =
"<?xml version='1.0' encoding='UTF-8'?>"
- "<response protocol='3.0'>"
+ "<response protocol='3.1'>"
" <app appid='aaaaaaaa' cohort='1:2q3/'>"
" <updatecheck status='noupdate'/>"
" </app>"
@@ -241,8 +241,56 @@ const char* kTwoAppsSetCohort =
" </app>"
"</response>";
-TEST(ComponentUpdaterUpdateResponseTest, TestParser) {
- UpdateResponse parser;
+// Includes a run action for an update check with status='ok'.
+const char* kUpdateCheckStatusOkWithRunAction =
+ "<?xml version='1.0' encoding='UTF-8'?>"
+ "<response protocol='3.1'>"
+ " <app appid='12345'>"
+ " <updatecheck status='ok'>"
+ " <urls>"
+ " <url codebase='http://example.com/'/>"
+ " <url codebasediff='http://diff.example.com/'/>"
+ " </urls>"
+ " <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+ " <packages>"
+ " <package name='extension_1_2_3_4.crx'/>"
+ " </packages>"
+ " </manifest>"
+ " <actions>"
+ " <action run='this'/>"
+ " </actions>"
+ " </updatecheck>"
+ " </app>"
+ "</response>";
+
+// Includes a run action for an update check with status='noupdate'.
+const char* kUpdateCheckStatusNoUpdateWithRunAction =
+ "<?xml version='1.0' encoding='UTF-8'?>"
+ "<response protocol='3.1'>"
+ " <app appid='12345'>"
+ " <updatecheck status='noupdate'>"
+ " <actions>"
+ " <action run='this'/>"
+ " </actions>"
+ " </updatecheck>"
+ " </app>"
+ "</response>";
+
+// Includes a run action for an update check with status='error'.
+const char* kUpdateCheckStatusErrorWithRunAction =
+ "<?xml version='1.0' encoding='UTF-8'?>"
+ "<response protocol='3.1'>"
+ " <app appid='12345' status='ok'>"
+ " <updatecheck status='error-osnotsupported'>"
+ " <actions>"
+ " <action run='this'/>"
+ " </actions>"
+ " </updatecheck>"
+ " </app>"
+ "</response>";
+
+TEST(ComponentUpdaterProtocolParserTest, Parse) {
+ ProtocolParser parser;
// Test parsing of a number of invalid xml cases
EXPECT_FALSE(parser.Parse(std::string()));
@@ -276,7 +324,7 @@ TEST(ComponentUpdaterUpdateResponseTest, TestParser) {
EXPECT_TRUE(parser.Parse(kValidXml));
EXPECT_TRUE(parser.errors().empty());
EXPECT_EQ(1u, parser.results().list.size());
- const UpdateResponse::Result* firstResult = &parser.results().list[0];
+ const ProtocolParser::Result* firstResult = &parser.results().list[0];
EXPECT_STREQ("ok", firstResult->status.c_str());
EXPECT_EQ(1u, firstResult->crx_urls.size());
EXPECT_EQ(GURL("http://example.com/"), firstResult->crx_urls[0]);
@@ -351,7 +399,7 @@ TEST(ComponentUpdaterUpdateResponseTest, TestParser) {
firstResult->cohort_attrs.end());
EXPECT_EQ(firstResult->cohort_attrs.find("cohorthint"),
firstResult->cohort_attrs.end());
- const UpdateResponse::Result* secondResult = &parser.results().list[1];
+ const ProtocolParser::Result* secondResult = &parser.results().list[1];
EXPECT_EQ(secondResult->extension_id, "bbbbbbbb");
EXPECT_NE(secondResult->cohort_attrs.find("cohort"),
secondResult->cohort_attrs.end());
@@ -361,6 +409,26 @@ TEST(ComponentUpdaterUpdateResponseTest, TestParser) {
EXPECT_EQ(secondResult->cohort_attrs.find("cohortname")->second, "cname");
EXPECT_EQ(secondResult->cohort_attrs.find("cohorthint"),
secondResult->cohort_attrs.end());
+
+ EXPECT_TRUE(parser.Parse(kUpdateCheckStatusOkWithRunAction));
+ EXPECT_TRUE(parser.errors().empty());
+ EXPECT_FALSE(parser.results().list.empty());
+ firstResult = &parser.results().list[0];
+ EXPECT_STREQ("ok", firstResult->status.c_str());
+ EXPECT_EQ(firstResult->extension_id, "12345");
+ EXPECT_STREQ("this", firstResult->action_run.c_str());
+
+ EXPECT_TRUE(parser.Parse(kUpdateCheckStatusNoUpdateWithRunAction));
+ EXPECT_TRUE(parser.errors().empty());
+ EXPECT_FALSE(parser.results().list.empty());
+ firstResult = &parser.results().list[0];
+ EXPECT_STREQ("noupdate", firstResult->status.c_str());
+ EXPECT_EQ(firstResult->extension_id, "12345");
+ EXPECT_STREQ("this", firstResult->action_run.c_str());
+
+ EXPECT_TRUE(parser.Parse(kUpdateCheckStatusErrorWithRunAction));
+ EXPECT_FALSE(parser.errors().empty());
+ EXPECT_TRUE(parser.results().list.empty());
}
} // namespace update_client
diff --git a/chromium/components/update_client/request_sender_unittest.cc b/chromium/components/update_client/request_sender_unittest.cc
index e0b891461fd..82a07c20dd6 100644
--- a/chromium/components/update_client/request_sender_unittest.cc
+++ b/chromium/components/update_client/request_sender_unittest.cc
@@ -7,7 +7,9 @@
#include <memory>
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
@@ -62,10 +64,11 @@ class RequestSenderTest : public testing::Test {
std::unique_ptr<RequestSender> request_sender_;
std::unique_ptr<InterceptorFactory> interceptor_factory_;
- URLRequestPostInterceptor* post_interceptor_1_; // Owned by the factory.
- URLRequestPostInterceptor* post_interceptor_2_; // Owned by the factory.
+ // Owned by the factory.
+ URLRequestPostInterceptor* post_interceptor_1_ = nullptr;
+ URLRequestPostInterceptor* post_interceptor_2_ = nullptr;
- int error_;
+ int error_ = 0;
std::string response_;
private:
@@ -76,19 +79,15 @@ class RequestSenderTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(RequestSenderTest);
};
-RequestSenderTest::RequestSenderTest()
- : post_interceptor_1_(nullptr),
- post_interceptor_2_(nullptr),
- error_(0),
- scoped_task_scheduler_(&loop_) {}
+RequestSenderTest::RequestSenderTest() : scoped_task_scheduler_(&loop_) {}
RequestSenderTest::~RequestSenderTest() {}
void RequestSenderTest::SetUp() {
- config_ = new TestConfigurator(base::ThreadTaskRunnerHandle::Get(),
- base::ThreadTaskRunnerHandle::Get());
- interceptor_factory_.reset(
- new InterceptorFactory(base::ThreadTaskRunnerHandle::Get()));
+ config_ = base::MakeRefCounted<TestConfigurator>(
+ base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get());
+ interceptor_factory_ =
+ base::MakeUnique<InterceptorFactory>(base::ThreadTaskRunnerHandle::Get());
post_interceptor_1_ =
interceptor_factory_->CreateInterceptorForPath(kUrlPath1);
post_interceptor_2_ =
@@ -96,16 +95,16 @@ void RequestSenderTest::SetUp() {
EXPECT_TRUE(post_interceptor_1_);
EXPECT_TRUE(post_interceptor_2_);
- request_sender_.reset();
+ request_sender_ = nullptr;
}
void RequestSenderTest::TearDown() {
- request_sender_.reset();
+ request_sender_ = nullptr;
post_interceptor_1_ = nullptr;
post_interceptor_2_ = nullptr;
- interceptor_factory_.reset();
+ interceptor_factory_ = nullptr;
config_ = nullptr;
@@ -148,10 +147,8 @@ TEST_F(RequestSenderTest, RequestSendSuccess) {
EXPECT_TRUE(post_interceptor_1_->ExpectRequest(
new PartialMatch("test"), test_file("updatecheck_reply_1.xml")));
- std::vector<GURL> urls;
- urls.push_back(GURL(kUrl1));
- urls.push_back(GURL(kUrl2));
- request_sender_.reset(new RequestSender(config_));
+ const std::vector<GURL> urls = {GURL(kUrl1), GURL(kUrl2)};
+ request_sender_ = base::MakeUnique<RequestSender>(config_);
request_sender_->Send(false, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
@@ -162,6 +159,11 @@ TEST_F(RequestSenderTest, RequestSendSuccess) {
EXPECT_EQ(1, post_interceptor_1_->GetCount())
<< post_interceptor_1_->GetRequestsAsString();
+ EXPECT_EQ(0, post_interceptor_2_->GetHitCount())
+ << post_interceptor_2_->GetRequestsAsString();
+ EXPECT_EQ(0, post_interceptor_2_->GetCount())
+ << post_interceptor_2_->GetRequestsAsString();
+
// Sanity check the request.
EXPECT_STREQ("test", post_interceptor_1_->GetRequests()[0].c_str());
@@ -170,7 +172,7 @@ TEST_F(RequestSenderTest, RequestSendSuccess) {
EXPECT_TRUE(base::StartsWith(response_,
"<?xml version='1.0' encoding='UTF-8'?>",
base::CompareCase::SENSITIVE));
- EXPECT_EQ(443ul, response_.size());
+ EXPECT_EQ(505ul, response_.size());
}
// Tests that the request succeeds using the second url after the first url
@@ -180,10 +182,8 @@ TEST_F(RequestSenderTest, RequestSendSuccessWithFallback) {
post_interceptor_1_->ExpectRequest(new PartialMatch("test"), 403));
EXPECT_TRUE(post_interceptor_2_->ExpectRequest(new PartialMatch("test")));
- std::vector<GURL> urls;
- urls.push_back(GURL(kUrl1));
- urls.push_back(GURL(kUrl2));
- request_sender_.reset(new RequestSender(config_));
+ const std::vector<GURL> urls = {GURL(kUrl1), GURL(kUrl2)};
+ request_sender_ = base::MakeUnique<RequestSender>(config_);
request_sender_->Send(false, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
@@ -210,10 +210,8 @@ TEST_F(RequestSenderTest, RequestSendFailed) {
EXPECT_TRUE(
post_interceptor_2_->ExpectRequest(new PartialMatch("test"), 403));
- std::vector<GURL> urls;
- urls.push_back(GURL(kUrl1));
- urls.push_back(GURL(kUrl2));
- request_sender_.reset(new RequestSender(config_));
+ const std::vector<GURL> urls = {GURL(kUrl1), GURL(kUrl2)};
+ request_sender_ = base::MakeUnique<RequestSender>(config_);
request_sender_->Send(false, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
@@ -236,7 +234,7 @@ TEST_F(RequestSenderTest, RequestSendFailed) {
// Tests that the request fails when no urls are provided.
TEST_F(RequestSenderTest, RequestSendFailedNoUrls) {
std::vector<GURL> urls;
- request_sender_.reset(new RequestSender(config_));
+ request_sender_ = base::MakeUnique<RequestSender>(config_);
request_sender_->Send(false, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
@@ -250,9 +248,8 @@ TEST_F(RequestSenderTest, RequestSendCupError) {
EXPECT_TRUE(post_interceptor_1_->ExpectRequest(
new PartialMatch("test"), test_file("updatecheck_reply_1.xml")));
- std::vector<GURL> urls;
- urls.push_back(GURL(kUrl1));
- request_sender_.reset(new RequestSender(config_));
+ const std::vector<GURL> urls = {GURL(kUrl1)};
+ request_sender_ = base::MakeUnique<RequestSender>(config_);
request_sender_->Send(true, "test", urls,
base::Bind(&RequestSenderTest::RequestSenderComplete,
base::Unretained(this)));
diff --git a/chromium/components/update_client/task_send_uninstall_ping.cc b/chromium/components/update_client/task_send_uninstall_ping.cc
new file mode 100644
index 00000000000..bb5d96a5a76
--- /dev/null
+++ b/chromium/components/update_client/task_send_uninstall_ping.cc
@@ -0,0 +1,62 @@
+// Copyright 2017 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/update_client/task_send_uninstall_ping.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/version.h"
+#include "components/update_client/update_client.h"
+#include "components/update_client/update_engine.h"
+
+namespace update_client {
+
+TaskSendUninstallPing::TaskSendUninstallPing(UpdateEngine* update_engine,
+ const std::string& id,
+ const base::Version& version,
+ int reason,
+ const Callback& callback)
+ : update_engine_(update_engine),
+ id_(id),
+ version_(version),
+ reason_(reason),
+ callback_(callback) {}
+
+TaskSendUninstallPing::~TaskSendUninstallPing() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void TaskSendUninstallPing::Run() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (id_.empty()) {
+ TaskComplete(Error::INVALID_ARGUMENT);
+ return;
+ }
+
+ update_engine_->SendUninstallPing(
+ id_, version_, reason_,
+ base::Bind(&TaskSendUninstallPing::TaskComplete, base::Unretained(this)));
+}
+
+void TaskSendUninstallPing::Cancel() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ TaskComplete(Error::UPDATE_CANCELED);
+}
+
+std::vector<std::string> TaskSendUninstallPing::GetIds() const {
+ return std::vector<std::string>{id_};
+}
+
+void TaskSendUninstallPing::TaskComplete(Error error) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback_, this, error));
+}
+
+} // namespace update_client
diff --git a/chromium/components/update_client/task_send_uninstall_ping.h b/chromium/components/update_client/task_send_uninstall_ping.h
new file mode 100644
index 00000000000..33dbc4941a8
--- /dev/null
+++ b/chromium/components/update_client/task_send_uninstall_ping.h
@@ -0,0 +1,66 @@
+// Copyright 2017 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_UPDATE_CLIENT_TASK_SEND_UNINSTALL_PING_H_
+#define COMPONENTS_UPDATE_CLIENT_TASK_SEND_UNINSTALL_PING_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/threading/thread_checker.h"
+#include "components/update_client/task.h"
+#include "components/update_client/update_client.h"
+
+namespace base {
+class Version;
+}
+
+namespace update_client {
+
+class UpdateEngine;
+enum class Error;
+
+// Defines a specialized task for sending the uninstall ping.
+class TaskSendUninstallPing : public Task {
+ public:
+ using Callback = base::Callback<void(Task* task, Error error)>;
+
+ // |update_engine| is injected here to handle the task.
+ // |id| represents the CRX to send the ping for.
+ // |callback| is called to return the execution flow back to creator of
+ // this task when the task is done.
+ TaskSendUninstallPing(UpdateEngine* update_engine,
+ const std::string& id,
+ const base::Version& version,
+ int reason,
+ const Callback& callback);
+ ~TaskSendUninstallPing() override;
+
+ void Run() override;
+
+ void Cancel() override;
+
+ std::vector<std::string> GetIds() const override;
+
+ private:
+ // Called when the task has completed either because the task has run or
+ // it has been canceled.
+ void TaskComplete(Error error);
+
+ base::ThreadChecker thread_checker_;
+
+ UpdateEngine* update_engine_; // Not owned by this class.
+ const std::string id_;
+ const base::Version version_;
+ int reason_;
+ const Callback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskSendUninstallPing);
+};
+
+} // namespace update_client
+
+#endif // COMPONENTS_UPDATE_CLIENT_TASK_SEND_UNINSTALL_PING_H_
diff --git a/chromium/components/update_client/task_update.h b/chromium/components/update_client/task_update.h
index 15c5a33615f..9d8235c3d47 100644
--- a/chromium/components/update_client/task_update.h
+++ b/chromium/components/update_client/task_update.h
@@ -5,7 +5,6 @@
#ifndef COMPONENTS_UPDATE_CLIENT_TASK_UPDATE_H_
#define COMPONENTS_UPDATE_CLIENT_TASK_UPDATE_H_
-#include <queue>
#include <string>
#include <vector>
diff --git a/chromium/components/update_client/test_configurator.cc b/chromium/components/update_client/test_configurator.cc
index 322044ac9db..b2bf95ddccb 100644
--- a/chromium/components/update_client/test_configurator.cc
+++ b/chromium/components/update_client/test_configurator.cc
@@ -8,7 +8,7 @@
#include "base/single_thread_task_runner.h"
#include "base/version.h"
#include "components/prefs/pref_service.h"
-#include "components/update_client/component_patcher_operation.h"
+#include "components/update_client/out_of_process_patcher.h"
#include "net/url_request/url_request_test_util.h"
#include "url/gurl.h"
diff --git a/chromium/components/update_client/test_installer.cc b/chromium/components/update_client/test_installer.cc
index 3232bd6cf58..7a003dbf817 100644
--- a/chromium/components/update_client/test_installer.cc
+++ b/chromium/components/update_client/test_installer.cc
@@ -10,12 +10,21 @@
#include "base/files/file_util.h"
#include "base/values.h"
#include "components/update_client/update_client_errors.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace update_client {
TestInstaller::TestInstaller() : error_(0), install_count_(0) {
}
+TestInstaller::~TestInstaller() {
+ // The unpack path is deleted unconditionally by the component state code,
+ // which is driving this installer. Therefore, the unpack path must not
+ // exist when this object is destroyed.
+ if (!unpack_path_.empty())
+ EXPECT_FALSE(base::DirectoryExists(unpack_path_));
+}
+
void TestInstaller::OnUpdateError(int error) {
error_ = error;
}
@@ -24,8 +33,8 @@ CrxInstaller::Result TestInstaller::Install(
const base::DictionaryValue& manifest,
const base::FilePath& unpack_path) {
++install_count_;
- if (!base::DeleteFile(unpack_path, true))
- return Result(InstallError::GENERIC_ERROR);
+
+ unpack_path_ = unpack_path;
return Result(InstallError::NONE);
}
@@ -35,9 +44,6 @@ bool TestInstaller::GetInstalledFile(const std::string& file,
return false;
}
-TestInstaller::~TestInstaller() {
-}
-
bool TestInstaller::Uninstall() {
return false;
}
diff --git a/chromium/components/update_client/test_installer.h b/chromium/components/update_client/test_installer.h
index 1b5bea0bda1..473772e8a0f 100644
--- a/chromium/components/update_client/test_installer.h
+++ b/chromium/components/update_client/test_installer.h
@@ -42,6 +42,10 @@ class TestInstaller : public CrxInstaller {
int error_;
int install_count_;
+
+ private:
+ // Contains the |unpack_path| argument of the Install call.
+ base::FilePath unpack_path_;
};
// A ReadOnlyTestInstaller is an installer that knows about files in an existing
diff --git a/chromium/components/update_client/update_checker.cc b/chromium/components/update_client/update_checker.cc
index 1459d561204..4995f7500bc 100644
--- a/chromium/components/update_client/update_checker.cc
+++ b/chromium/components/update_client/update_checker.cc
@@ -15,12 +15,15 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "components/update_client/component.h"
#include "components/update_client/configurator.h"
-#include "components/update_client/crx_update_item.h"
#include "components/update_client/persisted_data.h"
+#include "components/update_client/protocol_builder.h"
+#include "components/update_client/protocol_parser.h"
#include "components/update_client/request_sender.h"
#include "components/update_client/update_client.h"
#include "components/update_client/updater_state.h"
@@ -31,109 +34,16 @@ namespace update_client {
namespace {
-// Returns a sanitized version of the brand or an empty string otherwise.
-std::string SanitizeBrand(const std::string& brand) {
- return IsValidBrand(brand) ? brand : std::string("");
-}
-
-// Filters invalid attributes from |installer_attributes|.
-update_client::InstallerAttributes SanitizeInstallerAttributes(
- const update_client::InstallerAttributes& installer_attributes) {
- update_client::InstallerAttributes sanitized_attrs;
- for (const auto& attr : installer_attributes) {
- if (IsValidInstallerAttribute(attr))
- sanitized_attrs.insert(attr);
- }
- return sanitized_attrs;
-}
-
// Returns true if at least one item requires network encryption.
-bool IsEncryptionRequired(const IdToCrxUpdateItemMap& items) {
- for (const auto& item : items) {
- if (item.second->component.requires_network_encryption)
+bool IsEncryptionRequired(const IdToComponentPtrMap& components) {
+ for (const auto& item : components) {
+ const auto& component = item.second;
+ if (component->crx_component().requires_network_encryption)
return true;
}
return false;
}
-// Builds an update check request for |components|. |additional_attributes| is
-// serialized as part of the <request> element of the request to customize it
-// with data that is not platform or component specific. For each |item|, a
-// corresponding <app> element is created and inserted as a child node of
-// the <request>.
-//
-// An app element looks like this:
-// <app appid="hnimpnehoodheedghdeeijklkeaacbdc"
-// version="0.1.2.3" installsource="ondemand">
-// <updatecheck/>
-// <packages>
-// <package fp="abcd"/>
-// </packages>
-// </app>
-std::string BuildUpdateCheckRequest(
- const Configurator& config,
- const IdToCrxUpdateItemMap& items,
- PersistedData* metadata,
- const std::string& additional_attributes,
- bool enabled_component_updates,
- const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes) {
- const std::string brand(SanitizeBrand(config.GetBrand()));
- std::string app_elements;
- for (const auto& item_pair : items) {
- const CrxUpdateItem* item = item_pair.second.get();
- const update_client::InstallerAttributes installer_attributes(
- SanitizeInstallerAttributes(item->component.installer_attributes));
- std::string app("<app ");
- base::StringAppendF(&app, "appid=\"%s\" version=\"%s\"", item->id.c_str(),
- item->component.version.GetString().c_str());
- if (!brand.empty())
- base::StringAppendF(&app, " brand=\"%s\"", brand.c_str());
- if (item->on_demand)
- base::StringAppendF(&app, " installsource=\"ondemand\"");
- for (const auto& attr : installer_attributes) {
- base::StringAppendF(&app, " %s=\"%s\"", attr.first.c_str(),
- attr.second.c_str());
- }
- const std::string cohort = metadata->GetCohort(item->id);
- const std::string cohort_name = metadata->GetCohortName(item->id);
- const std::string cohort_hint = metadata->GetCohortHint(item->id);
- if (!cohort.empty())
- base::StringAppendF(&app, " cohort=\"%s\"", cohort.c_str());
- if (!cohort_name.empty())
- base::StringAppendF(&app, " cohortname=\"%s\"", cohort_name.c_str());
- if (!cohort_hint.empty())
- base::StringAppendF(&app, " cohorthint=\"%s\"", cohort_hint.c_str());
- base::StringAppendF(&app, ">");
-
- base::StringAppendF(&app, "<updatecheck");
- if (item->component.supports_group_policy_enable_component_updates &&
- !enabled_component_updates) {
- base::StringAppendF(&app, " updatedisabled=\"true\"");
- }
- base::StringAppendF(&app, "/>");
-
- base::StringAppendF(&app, "<ping rd=\"%d\" ping_freshness=\"%s\"/>",
- metadata->GetDateLastRollCall(item->id),
- metadata->GetPingFreshness(item->id).c_str());
- if (!item->component.fingerprint.empty()) {
- base::StringAppendF(&app,
- "<packages>"
- "<package fp=\"%s\"/>"
- "</packages>",
- item->component.fingerprint.c_str());
- }
- base::StringAppendF(&app, "</app>");
- app_elements.append(app);
- VLOG(1) << "Appending to update request: " << app;
- }
-
- // Include the updater state in the update check request.
- return BuildProtocolRequest(
- config.GetProdId(), config.GetBrowserVersion().GetString(),
- config.GetChannel(), config.GetLang(), config.GetOSLongName(),
- config.GetDownloadPreference(), app_elements, additional_attributes,
- updater_state_attributes);
-}
class UpdateCheckerImpl : public UpdateChecker {
public:
@@ -143,26 +53,33 @@ class UpdateCheckerImpl : public UpdateChecker {
// Overrides for UpdateChecker.
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_checked,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override;
private:
void ReadUpdaterStateAttributes();
- void CheckForUpdatesHelper(const IdToCrxUpdateItemMap& items_to_check,
+ void CheckForUpdatesHelper(const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates);
+ void OnRequestSenderComplete(const IdToComponentPtrMap& components,
+ int error,
+ const std::string& response,
+ int retry_after_sec);
+ void UpdateCheckSucceeded(const IdToComponentPtrMap& components,
+ const ProtocolParser::Results& results,
+ int retry_after_sec);
+ void UpdateCheckFailed(const IdToComponentPtrMap& components,
+ int error,
+ int retry_after_sec);
- void OnRequestSenderComplete(
- std::unique_ptr<std::vector<std::string>> ids_checked,
- int error,
- const std::string& response,
- int retry_after_sec);
base::ThreadChecker thread_checker_;
const scoped_refptr<Configurator> config_;
- PersistedData* metadata_;
+ PersistedData* metadata_ = nullptr;
+ std::vector<std::string> ids_checked_;
UpdateCheckCallback update_check_callback_;
std::unique_ptr<UpdaterState::Attributes> updater_state_attributes_;
std::unique_ptr<RequestSender> request_sender_;
@@ -179,19 +96,22 @@ UpdateCheckerImpl::~UpdateCheckerImpl() {
}
bool UpdateCheckerImpl::CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_checked,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) {
DCHECK(thread_checker_.CalledOnValidThread());
+ ids_checked_ = ids_checked;
update_check_callback_ = update_check_callback;
return config_->GetSequencedTaskRunner()->PostTaskAndReply(
- FROM_HERE, base::Bind(&UpdateCheckerImpl::ReadUpdaterStateAttributes,
- base::Unretained(this)),
+ FROM_HERE,
+ base::Bind(&UpdateCheckerImpl::ReadUpdaterStateAttributes,
+ base::Unretained(this)),
base::Bind(&UpdateCheckerImpl::CheckForUpdatesHelper,
- base::Unretained(this), base::ConstRef(items_to_check),
+ base::Unretained(this), base::ConstRef(components),
additional_attributes, enabled_component_updates));
}
@@ -202,66 +122,95 @@ void UpdateCheckerImpl::ReadUpdaterStateAttributes() {
}
void UpdateCheckerImpl::CheckForUpdatesHelper(
- const IdToCrxUpdateItemMap& items_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates) {
DCHECK(thread_checker_.CalledOnValidThread());
auto urls(config_->UpdateUrl());
- if (IsEncryptionRequired(items_to_check))
+ if (IsEncryptionRequired(components))
RemoveUnsecureUrls(&urls);
- std::unique_ptr<std::vector<std::string>> ids_checked(
- new std::vector<std::string>());
- for (const auto& item : items_to_check)
- ids_checked->push_back(item.second->id);
- request_sender_.reset(new RequestSender(config_));
+ request_sender_ = base::MakeUnique<RequestSender>(config_);
request_sender_->Send(
config_->EnabledCupSigning(),
- BuildUpdateCheckRequest(*config_, items_to_check, metadata_,
+ BuildUpdateCheckRequest(*config_, ids_checked_, components, metadata_,
additional_attributes, enabled_component_updates,
updater_state_attributes_),
- urls, base::Bind(&UpdateCheckerImpl::OnRequestSenderComplete,
- base::Unretained(this), base::Passed(&ids_checked)));
+ urls,
+ base::Bind(&UpdateCheckerImpl::OnRequestSenderComplete,
+ base::Unretained(this), base::ConstRef(components)));
}
void UpdateCheckerImpl::OnRequestSenderComplete(
- std::unique_ptr<std::vector<std::string>> ids_checked,
+ const IdToComponentPtrMap& components,
int error,
const std::string& response,
int retry_after_sec) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (!error) {
- UpdateResponse update_response;
- if (update_response.Parse(response)) {
- int daynum = update_response.results().daystart_elapsed_days;
- if (daynum != UpdateResponse::kNoDaystart)
- metadata_->SetDateLastRollCall(*ids_checked, daynum);
- for (const auto& result : update_response.results().list) {
- auto entry = result.cohort_attrs.find(UpdateResponse::Result::kCohort);
- if (entry != result.cohort_attrs.end())
- metadata_->SetCohort(result.extension_id, entry->second);
- entry = result.cohort_attrs.find(UpdateResponse::Result::kCohortName);
- if (entry != result.cohort_attrs.end())
- metadata_->SetCohortName(result.extension_id, entry->second);
- entry = result.cohort_attrs.find(UpdateResponse::Result::kCohortHint);
- if (entry != result.cohort_attrs.end())
- metadata_->SetCohortHint(result.extension_id, entry->second);
- }
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback_, error,
- update_response.results(), retry_after_sec));
- return;
- }
-
- error = -1;
+ if (error) {
+ VLOG(1) << "RequestSender failed " << error;
+ UpdateCheckFailed(components, error, retry_after_sec);
+ return;
+ }
+
+ ProtocolParser update_response;
+ if (!update_response.Parse(response)) {
VLOG(1) << "Parse failed " << update_response.errors();
+ UpdateCheckFailed(components, -1, retry_after_sec);
+ return;
+ }
+
+ DCHECK_EQ(0, error);
+ UpdateCheckSucceeded(components, update_response.results(), retry_after_sec);
+}
+
+void UpdateCheckerImpl::UpdateCheckSucceeded(
+ const IdToComponentPtrMap& components,
+ const ProtocolParser::Results& results,
+ int retry_after_sec) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const int daynum = results.daystart_elapsed_days;
+ if (daynum != ProtocolParser::kNoDaystart)
+ metadata_->SetDateLastRollCall(ids_checked_, daynum);
+ for (const auto& result : results.list) {
+ auto entry = result.cohort_attrs.find(ProtocolParser::Result::kCohort);
+ if (entry != result.cohort_attrs.end())
+ metadata_->SetCohort(result.extension_id, entry->second);
+ entry = result.cohort_attrs.find(ProtocolParser::Result::kCohortName);
+ if (entry != result.cohort_attrs.end())
+ metadata_->SetCohortName(result.extension_id, entry->second);
+ entry = result.cohort_attrs.find(ProtocolParser::Result::kCohortHint);
+ if (entry != result.cohort_attrs.end())
+ metadata_->SetCohortHint(result.extension_id, entry->second);
+ }
+
+ for (const auto& result : results.list) {
+ const auto& id = result.extension_id;
+ const auto it = components.find(id);
+ if (it != components.end())
+ it->second->SetParseResult(result);
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(update_check_callback_, 0, retry_after_sec));
+}
+
+void UpdateCheckerImpl::UpdateCheckFailed(const IdToComponentPtrMap& components,
+ int error,
+ int retry_after_sec) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_NE(0, error);
+ for (const auto& item : components) {
+ DCHECK(item.second);
+ Component& component = *item.second;
+ component.set_update_check_error(error);
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback_, error,
- UpdateResponse::Results(), retry_after_sec));
+ FROM_HERE, base::Bind(update_check_callback_, error, retry_after_sec));
}
} // namespace
@@ -269,8 +218,7 @@ void UpdateCheckerImpl::OnRequestSenderComplete(
std::unique_ptr<UpdateChecker> UpdateChecker::Create(
const scoped_refptr<Configurator>& config,
PersistedData* persistent) {
- return std::unique_ptr<UpdateChecker>(
- new UpdateCheckerImpl(config, persistent));
+ return base::MakeUnique<UpdateCheckerImpl>(config, persistent);
}
} // namespace update_client
diff --git a/chromium/components/update_client/update_checker.h b/chromium/components/update_client/update_checker.h
index 7500147beed..f9729fb81fb 100644
--- a/chromium/components/update_client/update_checker.h
+++ b/chromium/components/update_client/update_checker.h
@@ -12,33 +12,34 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "components/update_client/crx_update_item.h"
-#include "components/update_client/update_response.h"
+#include "components/update_client/component.h"
#include "url/gurl.h"
namespace update_client {
-class PersistedData;
class Configurator;
+class PersistedData;
class UpdateChecker {
public:
using UpdateCheckCallback =
- base::Callback<void(int error,
- const UpdateResponse::Results& results,
- int retry_after_sec)>;
+ base::Callback<void(int error, int retry_after_sec)>;
using Factory = std::unique_ptr<UpdateChecker> (*)(
const scoped_refptr<Configurator>& config,
PersistedData* persistent);
- virtual ~UpdateChecker() {}
+ virtual ~UpdateChecker() = default;
- // Initiates an update check for the |items_to_check|. |additional_attributes|
- // provides a way to customize the <request> element. This value is inserted
- // as-is, therefore it must be well-formed as an XML attribute string.
+ // Initiates an update check for the components specified by their ids.
+ // |additional_attributes| provides a way to customize the <request> element.
+ // This value is inserted as-is, therefore it must be well-formed as an
+ // XML attribute string.
+ // On completion, the state of |components| is mutated as required by the
+ // server response received.
virtual bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) = 0;
@@ -48,7 +49,7 @@ class UpdateChecker {
PersistedData* persistent);
protected:
- UpdateChecker() {}
+ UpdateChecker() = default;
private:
DISALLOW_COPY_AND_ASSIGN(UpdateChecker);
diff --git a/chromium/components/update_client/update_checker_unittest.cc b/chromium/components/update_client/update_checker_unittest.cc
index a6bd7e2b049..033118be25f 100644
--- a/chromium/components/update_client/update_checker_unittest.cc
+++ b/chromium/components/update_client/update_checker_unittest.cc
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_scheduler.h"
@@ -20,9 +21,10 @@
#include "base/version.h"
#include "build/build_config.h"
#include "components/prefs/testing_pref_service.h"
-#include "components/update_client/crx_update_item.h"
+#include "components/update_client/component.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/test_configurator.h"
+#include "components/update_client/update_engine.h"
#include "components/update_client/url_request_post_interceptor.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -57,16 +59,14 @@ class UpdateCheckerTest : public testing::Test {
void SetUp() override;
void TearDown() override;
- void UpdateCheckComplete(int error,
- const UpdateResponse::Results& results,
- int retry_after_sec);
+ void UpdateCheckComplete(int error, int retry_after_sec);
protected:
void Quit();
void RunThreads();
void RunThreadsUntilIdle();
- std::unique_ptr<CrxUpdateItem> BuildCrxUpdateItem();
+ std::unique_ptr<Component> MakeComponent() const;
scoped_refptr<TestConfigurator> config_;
std::unique_ptr<TestingPrefServiceSimple> pref_;
@@ -75,12 +75,17 @@ class UpdateCheckerTest : public testing::Test {
std::unique_ptr<UpdateChecker> update_checker_;
std::unique_ptr<InterceptorFactory> interceptor_factory_;
- URLRequestPostInterceptor* post_interceptor_; // Owned by the factory.
+ URLRequestPostInterceptor* post_interceptor_ =
+ nullptr; // Owned by the factory.
- int error_;
- UpdateResponse::Results results_;
+ int error_ = 0;
+ int retry_after_sec_ = 0;
+
+ std::unique_ptr<UpdateContext> update_context_;
private:
+ std::unique_ptr<UpdateContext> MakeFakeUpdateContext() const;
+
base::MessageLoopForIO loop_;
base::test::ScopedTaskScheduler scoped_task_scheduler_;
base::Closure quit_closure_;
@@ -88,34 +93,34 @@ class UpdateCheckerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(UpdateCheckerTest);
};
-UpdateCheckerTest::UpdateCheckerTest()
- : post_interceptor_(NULL), error_(0), scoped_task_scheduler_(&loop_) {}
+UpdateCheckerTest::UpdateCheckerTest() : scoped_task_scheduler_(&loop_) {}
UpdateCheckerTest::~UpdateCheckerTest() {
}
void UpdateCheckerTest::SetUp() {
- config_ = new TestConfigurator(base::ThreadTaskRunnerHandle::Get(),
- base::ThreadTaskRunnerHandle::Get());
- pref_.reset(new TestingPrefServiceSimple());
+ config_ = base::MakeRefCounted<TestConfigurator>(
+ base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get());
+ pref_ = base::MakeUnique<TestingPrefServiceSimple>();
PersistedData::RegisterPrefs(pref_->registry());
- metadata_.reset(new PersistedData(pref_.get()));
- interceptor_factory_.reset(
- new InterceptorFactory(base::ThreadTaskRunnerHandle::Get()));
+ metadata_ = base::MakeUnique<PersistedData>(pref_.get());
+ interceptor_factory_ =
+ base::MakeUnique<InterceptorFactory>(base::ThreadTaskRunnerHandle::Get());
post_interceptor_ = interceptor_factory_->CreateInterceptor();
EXPECT_TRUE(post_interceptor_);
- update_checker_.reset();
+ update_checker_ = nullptr;
error_ = 0;
- results_ = UpdateResponse::Results();
+ retry_after_sec_ = 0;
+ update_context_ = MakeFakeUpdateContext();
}
void UpdateCheckerTest::TearDown() {
- update_checker_.reset();
+ update_checker_ = nullptr;
- post_interceptor_ = NULL;
- interceptor_factory_.reset();
+ post_interceptor_ = nullptr;
+ interceptor_factory_ = nullptr;
config_ = nullptr;
@@ -145,16 +150,21 @@ void UpdateCheckerTest::Quit() {
quit_closure_.Run();
}
-void UpdateCheckerTest::UpdateCheckComplete(
- int error,
- const UpdateResponse::Results& results,
- int retry_after_sec) {
+void UpdateCheckerTest::UpdateCheckComplete(int error, int retry_after_sec) {
error_ = error;
- results_ = results;
+ retry_after_sec_ = retry_after_sec;
Quit();
}
-std::unique_ptr<CrxUpdateItem> UpdateCheckerTest::BuildCrxUpdateItem() {
+std::unique_ptr<UpdateContext> UpdateCheckerTest::MakeFakeUpdateContext()
+ const {
+ return base::MakeUnique<UpdateContext>(
+ config_, false, std::vector<std::string>(),
+ UpdateClient::CrxDataCallback(), UpdateEngine::NotifyObserversCallback(),
+ UpdateEngine::Callback(), nullptr);
+}
+
+std::unique_ptr<Component> UpdateCheckerTest::MakeComponent() const {
CrxComponent crx_component;
crx_component.name = "test_jebg";
crx_component.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
@@ -162,13 +172,11 @@ std::unique_ptr<CrxUpdateItem> UpdateCheckerTest::BuildCrxUpdateItem() {
crx_component.version = base::Version("0.9");
crx_component.fingerprint = "fp1";
- std::unique_ptr<CrxUpdateItem> crx_update_item =
- base::MakeUnique<CrxUpdateItem>();
- crx_update_item->state = CrxUpdateItem::State::kNew;
- crx_update_item->id = kUpdateItemId;
- crx_update_item->component = crx_component;
+ auto component = base::MakeUnique<Component>(*update_context_, kUpdateItemId);
+ component->state_ = base::MakeUnique<Component::StateNew>(component.get());
+ component->crx_component_ = crx_component;
- return crx_update_item;
+ return component;
}
TEST_F(UpdateCheckerTest, UpdateCheckSuccess) {
@@ -177,16 +185,17 @@ TEST_F(UpdateCheckerTest, UpdateCheckSuccess) {
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- item->component.installer_attributes["ap"] = "some_ap";
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
+
+ auto& component = components[kUpdateItemId];
+ component->crx_component_.installer_attributes["ap"] = "some_ap";
update_checker_->CheckForUpdates(
- items_to_check, "extra=\"params\"", true,
+ std::vector<std::string>{kUpdateItemId}, components, "extra=\"params\"",
+ true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
-
RunThreads();
EXPECT_EQ(1, post_interceptor_->GetHitCount())
@@ -197,7 +206,7 @@ TEST_F(UpdateCheckerTest, UpdateCheckSuccess) {
// Sanity check the request.
const auto request = post_interceptor_->GetRequests()[0];
EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
- "request protocol=\"3.0\" extra=\"params\""));
+ "request protocol=\"3.1\" extra=\"params\""));
// The request must not contain any "dlpref" in the default case.
EXPECT_EQ(string::npos, request.find(" dlpref=\""));
EXPECT_NE(
@@ -218,9 +227,14 @@ TEST_F(UpdateCheckerTest, UpdateCheckSuccess) {
// Sanity check the arguments of the callback after parsing.
EXPECT_EQ(0, error_);
- EXPECT_EQ(1ul, results_.list.size());
- EXPECT_STREQ(kUpdateItemId, results_.list[0].extension_id.c_str());
- EXPECT_STREQ("1.0", results_.list[0].manifest.version.c_str());
+
+ EXPECT_EQ(base::Version("1.0"), component->next_version_);
+ EXPECT_EQ(1u, component->crx_urls_.size());
+ EXPECT_EQ(
+ GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx"),
+ component->crx_urls_.front());
+
+ EXPECT_STREQ("this", component->action_run_.c_str());
#if (OS_WIN)
EXPECT_NE(string::npos, request.find(" domainjoined="));
@@ -239,14 +253,15 @@ TEST_F(UpdateCheckerTest, UpdateCheckInvalidAp) {
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
+
// Make "ap" too long.
- item->component.installer_attributes["ap"] = std::string(257, 'a');
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ auto& component = components[kUpdateItemId];
+ component->crx_component_.installer_attributes["ap"] = std::string(257, 'a');
update_checker_->CheckForUpdates(
- items_to_check, "", true,
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
@@ -268,12 +283,11 @@ TEST_F(UpdateCheckerTest, UpdateCheckSuccessNoBrand) {
config_->SetBrand("TOOLONG"); // Sets an invalid brand code.
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
update_checker_->CheckForUpdates(
- items_to_check, "", true,
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
@@ -295,12 +309,13 @@ TEST_F(UpdateCheckerTest, UpdateCheckError) {
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
+
+ auto& component = components[kUpdateItemId];
update_checker_->CheckForUpdates(
- items_to_check, "", true,
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
@@ -311,7 +326,7 @@ TEST_F(UpdateCheckerTest, UpdateCheckError) {
<< post_interceptor_->GetRequestsAsString();
EXPECT_EQ(403, error_);
- EXPECT_EQ(0ul, results_.list.size());
+ EXPECT_FALSE(component->next_version_.IsValid());
}
TEST_F(UpdateCheckerTest, UpdateCheckDownloadPreference) {
@@ -322,12 +337,12 @@ TEST_F(UpdateCheckerTest, UpdateCheckDownloadPreference) {
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
update_checker_->CheckForUpdates(
- items_to_check, "extra=\"params\"", true,
+ std::vector<std::string>{kUpdateItemId}, components, "extra=\"params\"",
+ true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
@@ -348,12 +363,13 @@ TEST_F(UpdateCheckerTest, UpdateCheckCupError) {
config_->SetEnabledCupSigning(true);
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
+
+ const auto& component = components[kUpdateItemId];
update_checker_->CheckForUpdates(
- items_to_check, "", true,
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
@@ -375,7 +391,7 @@ TEST_F(UpdateCheckerTest, UpdateCheckCupError) {
// Expect an error since the response is not trusted.
EXPECT_EQ(-10000, error_);
- EXPECT_EQ(0ul, results_.list.size());
+ EXPECT_FALSE(component->next_version_.IsValid());
}
// Tests that the UpdateCheckers will not make an update check for a
@@ -385,19 +401,20 @@ TEST_F(UpdateCheckerTest, UpdateCheckRequiresEncryptionError) {
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- item->component.requires_network_encryption = true;
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
+
+ auto& component = components[kUpdateItemId];
+ component->crx_component_.requires_network_encryption = true;
update_checker_->CheckForUpdates(
- items_to_check, "", true,
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
EXPECT_EQ(-1, error_);
- EXPECT_EQ(0u, results_.list.size());
+ EXPECT_FALSE(component->next_version_.IsValid());
}
// Tests that the PersistedData will get correctly update and reserialize
@@ -410,19 +427,21 @@ TEST_F(UpdateCheckerTest, UpdateCheckDateLastRollCall) {
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
// Do two update-checks.
update_checker_->CheckForUpdates(
- items_to_check, "extra=\"params\"", true,
+ std::vector<std::string>{kUpdateItemId}, components, "extra=\"params\"",
+ true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
+
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
update_checker_->CheckForUpdates(
- items_to_check, "extra=\"params\"", true,
+ std::vector<std::string>{kUpdateItemId}, components, "extra=\"params\"",
+ true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
@@ -444,8 +463,10 @@ TEST_F(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
config_->SetBrand("");
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
- std::unique_ptr<CrxUpdateItem> item = BuildCrxUpdateItem();
- CrxUpdateItem* item_ptr = item.get();
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
+
+ auto& component = components[kUpdateItemId];
// Tests the scenario where:
// * the component does not support group policies.
@@ -453,11 +474,10 @@ TEST_F(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
// Expects the group policy to be ignored and the update check to not
// include the "updatedisabled" attribute.
EXPECT_FALSE(
- item_ptr->component.supports_group_policy_enable_component_updates);
- IdToCrxUpdateItemMap items_to_check;
- items_to_check[kUpdateItemId] = std::move(item);
+ component->crx_component_.supports_group_policy_enable_component_updates);
+
update_checker_->CheckForUpdates(
- items_to_check, "", false,
+ std::vector<std::string>{kUpdateItemId}, components, "", false,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
@@ -470,10 +490,11 @@ TEST_F(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
// * the component supports group policies.
// * the component updates are disabled.
// Expects the update check to include the "updatedisabled" attribute.
- item_ptr->component.supports_group_policy_enable_component_updates = true;
+ component->crx_component_.supports_group_policy_enable_component_updates =
+ true;
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
update_checker_->CheckForUpdates(
- items_to_check, "", false,
+ std::vector<std::string>{kUpdateItemId}, components, "", false,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
@@ -486,10 +507,11 @@ TEST_F(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
// * the component does not support group policies.
// * the component updates are enabled.
// Expects the update check to not include the "updatedisabled" attribute.
- item_ptr->component.supports_group_policy_enable_component_updates = false;
+ component->crx_component_.supports_group_policy_enable_component_updates =
+ false;
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
update_checker_->CheckForUpdates(
- items_to_check, "", true,
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
@@ -502,10 +524,11 @@ TEST_F(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
// * the component supports group policies.
// * the component updates are enabled.
// Expects the update check to not include the "updatedisabled" attribute.
- item_ptr->component.supports_group_policy_enable_component_updates = true;
+ component->crx_component_.supports_group_policy_enable_component_updates =
+ true;
update_checker_ = UpdateChecker::Create(config_, metadata_.get());
update_checker_->CheckForUpdates(
- items_to_check, "", true,
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
base::Unretained(this)));
RunThreads();
@@ -515,4 +538,31 @@ TEST_F(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
"<updatecheck/>"));
}
+TEST_F(UpdateCheckerTest, NoUpdateActionRun) {
+ EXPECT_TRUE(post_interceptor_->ExpectRequest(
+ new PartialMatch("updatecheck"),
+ test_file("updatecheck_reply_noupdate.xml")));
+
+ update_checker_ = UpdateChecker::Create(config_, metadata_.get());
+
+ IdToComponentPtrMap components;
+ components[kUpdateItemId] = MakeComponent();
+
+ auto& component = components[kUpdateItemId];
+
+ update_checker_->CheckForUpdates(
+ std::vector<std::string>{kUpdateItemId}, components, "", true,
+ base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
+ base::Unretained(this)));
+ RunThreads();
+
+ EXPECT_EQ(1, post_interceptor_->GetHitCount())
+ << post_interceptor_->GetRequestsAsString();
+ ASSERT_EQ(1, post_interceptor_->GetCount())
+ << post_interceptor_->GetRequestsAsString();
+
+ EXPECT_EQ(0, error_);
+ EXPECT_STREQ("this", component->action_run_.c_str());
+}
+
} // namespace update_client
diff --git a/chromium/components/update_client/update_client.cc b/chromium/components/update_client/update_client.cc
index 3dc567d933b..4d248b27f5e 100644
--- a/chromium/components/update_client/update_client.cc
+++ b/chromium/components/update_client/update_client.cc
@@ -16,6 +16,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/observer_list.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
@@ -27,34 +28,25 @@
#include "components/update_client/crx_update_item.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/ping_manager.h"
+#include "components/update_client/protocol_parser.h"
+#include "components/update_client/task_send_uninstall_ping.h"
#include "components/update_client/task_update.h"
#include "components/update_client/update_checker.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/update_client_internal.h"
#include "components/update_client/update_engine.h"
-#include "components/update_client/update_response.h"
#include "components/update_client/utils.h"
#include "url/gurl.h"
namespace update_client {
-CrxUpdateItem::CrxUpdateItem()
- : state(State::kNew),
- on_demand(false),
- diff_update_failed(false),
- error_category(0),
- error_code(0),
- extra_code1(0),
- diff_error_category(0),
- diff_error_code(0),
- diff_extra_code1(0) {
-}
-
-CrxUpdateItem::CrxUpdateItem(const CrxUpdateItem& other) = default;
+CrxUpdateItem::CrxUpdateItem() : state(ComponentState::kNew) {}
CrxUpdateItem::~CrxUpdateItem() {
}
+CrxUpdateItem::CrxUpdateItem(const CrxUpdateItem& other) = default;
+
CrxComponent::CrxComponent()
: allows_background_download(true),
requires_network_encryption(true),
@@ -79,13 +71,13 @@ UpdateClientImpl::UpdateClientImpl(
: is_stopped_(false),
config_(config),
ping_manager_(std::move(ping_manager)),
- update_engine_(
- new UpdateEngine(config,
- update_checker_factory,
- crx_downloader_factory,
- ping_manager_.get(),
- base::Bind(&UpdateClientImpl::NotifyObservers,
- base::Unretained(this)))) {}
+ update_engine_(base::MakeUnique<UpdateEngine>(
+ config,
+ update_checker_factory,
+ crx_downloader_factory,
+ ping_manager_.get(),
+ base::Bind(&UpdateClientImpl::NotifyObservers,
+ base::Unretained(this)))) {}
UpdateClientImpl::~UpdateClientImpl() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -106,14 +98,13 @@ void UpdateClientImpl::Install(const std::string& id,
return;
}
- std::vector<std::string> ids;
- ids.push_back(id);
+ std::vector<std::string> ids = {id};
// Partially applies |callback| to OnTaskComplete, so this argument is
// available when the task completes, along with the task itself.
- std::unique_ptr<TaskUpdate> task(new TaskUpdate(
+ std::unique_ptr<TaskUpdate> task = base::MakeUnique<TaskUpdate>(
update_engine_.get(), true, ids, crx_data_callback,
- base::Bind(&UpdateClientImpl::OnTaskComplete, this, callback)));
+ base::Bind(&UpdateClientImpl::OnTaskComplete, this, callback));
// Install tasks are run concurrently and never queued up.
RunTask(std::move(task));
@@ -124,9 +115,9 @@ void UpdateClientImpl::Update(const std::vector<std::string>& ids,
const Callback& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- std::unique_ptr<TaskUpdate> task(new TaskUpdate(
+ std::unique_ptr<TaskUpdate> task = base::MakeUnique<TaskUpdate>(
update_engine_.get(), false, ids, crx_data_callback,
- base::Bind(&UpdateClientImpl::OnTaskComplete, this, callback)));
+ base::Bind(&UpdateClientImpl::OnTaskComplete, this, callback));
// If no other tasks are running at the moment, run this update task.
// Otherwise, queue the task up.
@@ -234,26 +225,23 @@ void UpdateClientImpl::Stop() {
void UpdateClientImpl::SendUninstallPing(const std::string& id,
const base::Version& version,
- int reason) {
+ int reason,
+ const Callback& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- // The implementation of PingManager::SendPing contains a self-deleting
- // object responsible for sending the ping.
- CrxUpdateItem item;
- item.state = CrxUpdateItem::State::kUninstalled;
- item.id = id;
- item.previous_version = version;
- item.next_version = base::Version("0");
- item.extra_code1 = reason;
-
- ping_manager_->SendPing(&item);
+ std::unique_ptr<TaskSendUninstallPing> task =
+ base::MakeUnique<TaskSendUninstallPing>(
+ update_engine_.get(), id, version, reason,
+ base::Bind(&UpdateClientImpl::OnTaskComplete, base::Unretained(this),
+ callback));
+ RunTask(std::move(task));
}
scoped_refptr<UpdateClient> UpdateClientFactory(
const scoped_refptr<Configurator>& config) {
- std::unique_ptr<PingManager> ping_manager(new PingManager(config));
- return new UpdateClientImpl(config, std::move(ping_manager),
- &UpdateChecker::Create, &CrxDownloader::Create);
+ return base::MakeRefCounted<UpdateClientImpl>(
+ config, base::MakeUnique<PingManager>(config), &UpdateChecker::Create,
+ &CrxDownloader::Create);
}
void RegisterPrefs(PrefRegistrySimple* registry) {
diff --git a/chromium/components/update_client/update_client.h b/chromium/components/update_client/update_client.h
index cdcd956fcc0..d068a5654bf 100644
--- a/chromium/components/update_client/update_client.h
+++ b/chromium/components/update_client/update_client.h
@@ -143,6 +143,22 @@ class Configurator;
enum class Error;
struct CrxUpdateItem;
+enum class ComponentState {
+ kNew,
+ kChecking,
+ kCanUpdate,
+ kDownloadingDiff,
+ kDownloading,
+ kDownloaded,
+ kUpdatingDiff,
+ kUpdating,
+ kUpdated,
+ kUpToDate,
+ kUpdateError,
+ kUninstalled,
+ kLastStatus
+};
+
// Called when a non-blocking call in this module completes.
using Callback = base::Callback<void(Error error)>;
@@ -252,7 +268,7 @@ class UpdateClient : public base::RefCounted<UpdateClient> {
public:
enum class Events {
// Sent before the update client does an update check.
- COMPONENT_CHECKING_FOR_UPDATES,
+ COMPONENT_CHECKING_FOR_UPDATES = 1,
// Sent when there is a new version of a registered CRX. After
// the notification is sent the CRX will be downloaded unless the
@@ -328,7 +344,8 @@ class UpdateClient : public base::RefCounted<UpdateClient> {
// of this class.
virtual void SendUninstallPing(const std::string& id,
const base::Version& version,
- int reason) = 0;
+ int reason,
+ const Callback& callback) = 0;
// Returns status details about a CRX update. The function returns true in
// case of success and false in case of errors, such as |id| was
diff --git a/chromium/components/update_client/update_client_errors.h b/chromium/components/update_client/update_client_errors.h
index 3d346769d4c..050ab3cf725 100644
--- a/chromium/components/update_client/update_client_errors.h
+++ b/chromium/components/update_client/update_client_errors.h
@@ -51,7 +51,7 @@ enum class UnpackerError {
// kNoManifest = 5, // Deprecated. Never used.
kBadManifest = 6,
kBadExtension = 7,
- kInvalidId = 8,
+ // kInvalidId = 8, // Deprecated. Combined with kInvalidFile.
// kInstallerError = 9, // Deprecated. Don't use.
kIoError = 10,
kDeltaVerificationFailure = 11,
diff --git a/chromium/components/update_client/update_client_internal.h b/chromium/components/update_client/update_client_internal.h
index 2f675a80e60..99a7f56fdac 100644
--- a/chromium/components/update_client/update_client_internal.h
+++ b/chromium/components/update_client/update_client_internal.h
@@ -49,7 +49,8 @@ class UpdateClientImpl : public UpdateClient {
void Stop() override;
void SendUninstallPing(const std::string& id,
const base::Version& version,
- int reason) override;
+ int reason,
+ const Callback& callback) override;
private:
~UpdateClientImpl() override;
@@ -61,8 +62,8 @@ class UpdateClientImpl : public UpdateClient {
base::ThreadChecker thread_checker_;
- // True is Stop method has been called.
- bool is_stopped_;
+ // True if Stop method has been called.
+ bool is_stopped_ = false;
scoped_refptr<Configurator> config_;
diff --git a/chromium/components/update_client/update_client_unittest.cc b/chromium/components/update_client/update_client_unittest.cc
index dd8302e42cd..fae978c0775 100644
--- a/chromium/components/update_client/update_client_unittest.cc
+++ b/chromium/components/update_client/update_client_unittest.cc
@@ -13,10 +13,10 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
-#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "base/version.h"
@@ -24,6 +24,7 @@
#include "components/update_client/crx_update_item.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/ping_manager.h"
+#include "components/update_client/protocol_parser.h"
#include "components/update_client/test_configurator.h"
#include "components/update_client/test_installer.h"
#include "components/update_client/update_checker.h"
@@ -71,42 +72,42 @@ class MockObserver : public UpdateClient::Observer {
MOCK_METHOD2(OnEvent, void(Events event, const std::string&));
};
-class OnDemandTester {
- public:
- OnDemandTester(const scoped_refptr<UpdateClient>& update_client,
- bool expected_value);
-
- void CheckOnDemand(Events event, const std::string&);
-
- private:
- const scoped_refptr<UpdateClient> update_client_;
- const bool expected_value_;
-};
+} // namespace
-OnDemandTester::OnDemandTester(const scoped_refptr<UpdateClient>& update_client,
- bool expected_value)
- : update_client_(update_client), expected_value_(expected_value) {
-}
+using ::testing::_;
+using ::testing::AtLeast;
+using ::testing::AnyNumber;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Mock;
+using ::testing::Return;
-void OnDemandTester::CheckOnDemand(Events event, const std::string& id) {
- if (event == Events::COMPONENT_CHECKING_FOR_UPDATES) {
- CrxUpdateItem update_item;
- EXPECT_TRUE(update_client_->GetCrxUpdateState(id, &update_item));
- EXPECT_EQ(update_item.on_demand, expected_value_);
- }
-}
+using std::string;
class FakePingManagerImpl : public PingManager {
public:
+ struct PingData {
+ std::string id;
+ base::Version previous_version;
+ base::Version next_version;
+ int error_category = 0;
+ int error_code = 0;
+ int extra_code1 = 0;
+ int diff_error_category = 0;
+ int diff_error_code = 0;
+ bool diff_update_failed = false;
+ };
+
explicit FakePingManagerImpl(const scoped_refptr<Configurator>& config);
~FakePingManagerImpl() override;
- bool SendPing(const CrxUpdateItem* item) override;
+ bool SendPing(const Component& component) override;
- const std::vector<CrxUpdateItem>& items() const;
+ const std::vector<PingData>& ping_data() const;
private:
- std::vector<CrxUpdateItem> items_;
+ std::vector<PingData> ping_data_;
DISALLOW_COPY_AND_ASSIGN(FakePingManagerImpl);
};
@@ -117,27 +118,26 @@ FakePingManagerImpl::FakePingManagerImpl(
FakePingManagerImpl::~FakePingManagerImpl() {
}
-bool FakePingManagerImpl::SendPing(const CrxUpdateItem* item) {
- items_.push_back(*item);
+bool FakePingManagerImpl::SendPing(const Component& component) {
+ PingData ping_data;
+ ping_data.id = component.id_;
+ ping_data.previous_version = component.previous_version_;
+ ping_data.next_version = component.next_version_;
+ ping_data.error_category = component.error_category_;
+ ping_data.error_code = component.error_code_;
+ ping_data.extra_code1 = component.extra_code1_;
+ ping_data.diff_error_category = component.diff_error_category_;
+ ping_data.diff_error_code = component.diff_error_code_;
+ ping_data.diff_update_failed = component.diff_update_failed();
+ ping_data_.push_back(ping_data);
return true;
}
-const std::vector<CrxUpdateItem>& FakePingManagerImpl::items() const {
- return items_;
+const std::vector<FakePingManagerImpl::PingData>&
+FakePingManagerImpl::ping_data() const {
+ return ping_data_;
}
-} // namespace
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::DoAll;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::Mock;
-using ::testing::Return;
-
-using std::string;
-
class UpdateClientTest : public testing::Test {
public:
UpdateClientTest();
@@ -155,14 +155,12 @@ class UpdateClientTest : public testing::Test {
base::Closure quit_closure() { return quit_closure_; }
private:
- static const int kNumWorkerThreads_ = 2;
+ static constexpr int kNumWorkerThreads_ = 2;
- base::MessageLoopForUI message_loop_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
base::RunLoop runloop_;
base::Closure quit_closure_;
- std::unique_ptr<base::SequencedWorkerPoolOwner> worker_pool_;
-
scoped_refptr<update_client::TestConfigurator> config_;
std::unique_ptr<TestingPrefServiceSimple> pref_;
std::unique_ptr<update_client::PersistedData> metadata_;
@@ -170,18 +168,19 @@ class UpdateClientTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(UpdateClientTest);
};
+constexpr int UpdateClientTest::kNumWorkerThreads_;
+
UpdateClientTest::UpdateClientTest()
- : worker_pool_(
- new base::SequencedWorkerPoolOwner(kNumWorkerThreads_, "test")) {
+ : scoped_task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI),
+ pref_(base::MakeUnique<TestingPrefServiceSimple>()) {
quit_closure_ = runloop_.QuitClosure();
- auto pool = worker_pool_->pool();
- config_ = new TestConfigurator(
- pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
- message_loop_.task_runner());
- pref_.reset(new TestingPrefServiceSimple());
+ config_ = base::MakeRefCounted<TestConfigurator>(
+ base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
+ base::ThreadTaskRunnerHandle::Get());
PersistedData::RegisterPrefs(pref_->registry());
- metadata_.reset(new PersistedData(pref_.get()));
+ metadata_ = base::MakeUnique<PersistedData>(pref_.get());
}
UpdateClientTest::~UpdateClientTest() {
@@ -212,7 +211,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
crx.name = "test_jebg";
crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx.version = base::Version("0.9");
- crx.installer = new TestInstaller;
+ crx.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx);
}
};
@@ -230,18 +229,33 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(1u, ids_to_check.size());
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check.front());
+ EXPECT_EQ(1u, components.count(id));
+
+ auto& component = components.at(id);
+
+ EXPECT_FALSE(component->on_demand());
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "noupdate";
+ component->SetParseResult(result);
+
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(update_check_callback, 0, UpdateResponse::Results(), 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
+
return true;
}
};
@@ -252,14 +266,13 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
};
@@ -267,21 +280,15 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
public:
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
- ~FakePingManager() override { EXPECT_TRUE(items().empty()); }
+ ~FakePingManager() override { EXPECT_TRUE(ping_data().empty()); }
};
- std::unique_ptr<PingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
-
- // Verify that calling Update does not set ondemand.
- OnDemandTester ondemand_tester(update_client, false);
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
- ON_CALL(observer, OnEvent(_, _))
- .WillByDefault(Invoke(&ondemand_tester, &OnDemandTester::CheckOnDemand));
-
InSequence seq;
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
@@ -290,9 +297,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
-
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
update_client->Update(
ids, base::Bind(&DataCallbackFake::Callback),
base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
@@ -313,13 +318,13 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
crx1.name = "test_jebg";
crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx1.version = base::Version("0.9");
- crx1.installer = new TestInstaller;
+ crx1.installer = base::MakeRefCounted<TestInstaller>();
CrxComponent crx2;
crx2.name = "test_abag";
crx2.pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash));
crx2.version = base::Version("2.2");
- crx2.installer = new TestInstaller;
+ crx2.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx1);
components->push_back(crx2);
@@ -339,11 +344,12 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -351,7 +357,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='jebgalgnebhfojomionfpkfelancnnkf'>
<updatecheck status='ok'>
<urls>
@@ -368,24 +374,51 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package;
- package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
- package.hash_sha256 =
- "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
- UpdateResponse::Result result;
- result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
- result.status = "ok";
- result.crx_urls.push_back(GURL("http://localhost/download/"));
- result.manifest.version = "1.0";
- result.manifest.browser_min_version = "11.0.1.0";
- result.manifest.packages.push_back(package);
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(2u, ids_to_check.size());
+
+ {
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
+ package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
+ package.hash_sha256 =
+ "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
+
+ ProtocolParser::Result result;
+ result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
+ result.status = "ok";
+ result.crx_urls.push_back(GURL("http://localhost/download/"));
+ result.manifest.version = "1.0";
+ result.manifest.browser_min_version = "11.0.1.0";
+ result.manifest.packages.push_back(package);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+
+ EXPECT_FALSE(component->on_demand());
+ }
- UpdateResponse::Results results;
- results.list.push_back(result);
+ {
+ const std::string id = "abagagagagagagagagagagagagagagag";
+ EXPECT_EQ(id, ids_to_check[1]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "noupdate";
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+
+ EXPECT_FALSE(component->on_demand());
+ }
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -396,14 +429,13 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
download_metrics.url = url;
@@ -439,20 +471,20 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(1U, ping_items.size());
- EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
- EXPECT_EQ(base::Version("0.9"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(0, ping_items[0].error_category);
- EXPECT_EQ(0, ping_items[0].error_code);
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(1u, ping_data.size());
+ EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(0, ping_data[0].error_category);
+ EXPECT_EQ(0, ping_data[0].error_code);
}
};
- std::unique_ptr<PingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
{
@@ -462,7 +494,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -478,10 +511,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
- ids.push_back(std::string("abagagagagagagagagagagagagagagag"));
-
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
+ "abagagagagagagagagagagagagagagag"};
update_client->Update(
ids, base::Bind(&DataCallbackFake::Callback),
base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
@@ -501,13 +532,13 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
crx1.name = "test_jebg";
crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx1.version = base::Version("0.9");
- crx1.installer = new TestInstaller;
+ crx1.installer = base::MakeRefCounted<TestInstaller>();
CrxComponent crx2;
crx2.name = "test_ihfo";
crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
crx2.version = base::Version("0.8");
- crx2.installer = new TestInstaller;
+ crx2.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx1);
components->push_back(crx2);
@@ -527,11 +558,12 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -539,7 +571,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='jebgalgnebhfojomionfpkfelancnnkf'>
<updatecheck status='ok'>
<urls>
@@ -570,38 +602,59 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package1;
- package1.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
- package1.hash_sha256 =
- "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(2u, ids_to_check.size());
+
+ {
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
+ package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
+ package.hash_sha256 =
+ "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "ok";
+ result.crx_urls.push_back(GURL("http://localhost/download/"));
+ result.manifest.version = "1.0";
+ result.manifest.browser_min_version = "11.0.1.0";
+ result.manifest.packages.push_back(package);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
- UpdateResponse::Result result1;
- result1.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
- result1.status = "ok";
- result1.crx_urls.push_back(GURL("http://localhost/download/"));
- result1.manifest.version = "1.0";
- result1.manifest.browser_min_version = "11.0.1.0";
- result1.manifest.packages.push_back(package1);
-
- UpdateResponse::Result::Manifest::Package package2;
- package2.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
- package2.hash_sha256 =
- "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
-
- UpdateResponse::Result result2;
- result2.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
- result2.status = "ok";
- result2.crx_urls.push_back(GURL("http://localhost/download/"));
- result2.manifest.version = "1.0";
- result2.manifest.browser_min_version = "11.0.1.0";
- result2.manifest.packages.push_back(package2);
-
- UpdateResponse::Results results;
- results.list.push_back(result1);
- results.list.push_back(result2);
+ EXPECT_FALSE(component->on_demand());
+ }
+
+ {
+ const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+ EXPECT_EQ(id, ids_to_check[1]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
+ package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
+ package.hash_sha256 =
+ "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "ok";
+ result.crx_urls.push_back(GURL("http://localhost/download/"));
+ result.manifest.version = "1.0";
+ result.manifest.browser_min_version = "11.0.1.0";
+ result.manifest.packages.push_back(package);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+
+ EXPECT_FALSE(component->on_demand());
+ }
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -612,14 +665,13 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
FilePath path;
@@ -675,25 +727,25 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(2U, ping_items.size());
- EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
- EXPECT_EQ(base::Version("0.9"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(0, ping_items[0].error_category);
- EXPECT_EQ(0, ping_items[0].error_code);
- EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
- EXPECT_EQ(base::Version("0.8"), ping_items[1].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[1].next_version);
- EXPECT_EQ(0, ping_items[1].error_category);
- EXPECT_EQ(0, ping_items[1].error_code);
- }
- };
-
- std::unique_ptr<FakePingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(2u, ping_data.size());
+ EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(0, ping_data[0].error_category);
+ EXPECT_EQ(0, ping_data[0].error_code);
+ EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
+ EXPECT_EQ(base::Version("0.8"), ping_data[1].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[1].next_version);
+ EXPECT_EQ(0, ping_data[1].error_category);
+ EXPECT_EQ(0, ping_data[1].error_code);
+ }
+ };
+
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
{
@@ -703,7 +755,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -718,7 +771,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_WAIT,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -727,10 +781,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdate) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
- ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
-
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
+ "ihfokbkgjpifnbbojhneepfflplebdkc"};
update_client->Update(
ids, base::Bind(&DataCallbackFake::Callback),
base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
@@ -752,13 +804,13 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
crx1.name = "test_jebg";
crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx1.version = base::Version("0.9");
- crx1.installer = new TestInstaller;
+ crx1.installer = base::MakeRefCounted<TestInstaller>();
CrxComponent crx2;
crx2.name = "test_ihfo";
crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
crx2.version = base::Version("0.8");
- crx2.installer = new TestInstaller;
+ crx2.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx1);
components->push_back(crx2);
@@ -778,11 +830,12 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -790,7 +843,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='jebgalgnebhfojomionfpkfelancnnkf'>
<updatecheck status='ok'>
<urls>
@@ -821,38 +874,56 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package1;
- package1.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
- package1.hash_sha256 =
- "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
- UpdateResponse::Result result1;
- result1.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
- result1.status = "ok";
- result1.crx_urls.push_back(GURL("http://localhost/download/"));
- result1.manifest.version = "1.0";
- result1.manifest.browser_min_version = "11.0.1.0";
- result1.manifest.packages.push_back(package1);
-
- UpdateResponse::Result::Manifest::Package package2;
- package2.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
- package2.hash_sha256 =
- "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
-
- UpdateResponse::Result result2;
- result2.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
- result2.status = "ok";
- result2.crx_urls.push_back(GURL("http://localhost/download/"));
- result2.manifest.version = "1.0";
- result2.manifest.browser_min_version = "11.0.1.0";
- result2.manifest.packages.push_back(package2);
-
- UpdateResponse::Results results;
- results.list.push_back(result1);
- results.list.push_back(result2);
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(2u, ids_to_check.size());
+
+ {
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
+ package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
+ package.hash_sha256 =
+ "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "ok";
+ result.crx_urls.push_back(GURL("http://localhost/download/"));
+ result.manifest.version = "1.0";
+ result.manifest.browser_min_version = "11.0.1.0";
+ result.manifest.packages.push_back(package);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+ }
+
+ {
+ const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+ EXPECT_EQ(id, ids_to_check[1]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
+ package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
+ package.hash_sha256 =
+ "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "ok";
+ result.crx_urls.push_back(GURL("http://localhost/download/"));
+ result.manifest.version = "1.0";
+ result.manifest.browser_min_version = "11.0.1.0";
+ result.manifest.packages.push_back(package);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+ }
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -863,14 +934,13 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
FilePath path;
@@ -926,25 +996,25 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(2U, ping_items.size());
- EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
- EXPECT_EQ(base::Version("0.9"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(1, ping_items[0].error_category); // Network error.
- EXPECT_EQ(-118, ping_items[0].error_code);
- EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
- EXPECT_EQ(base::Version("0.8"), ping_items[1].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[1].next_version);
- EXPECT_EQ(0, ping_items[1].error_category);
- EXPECT_EQ(0, ping_items[1].error_code);
- }
- };
-
- std::unique_ptr<FakePingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(2u, ping_data.size());
+ EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(1, ping_data[0].error_category);
+ EXPECT_EQ(-118, ping_data[0].error_code);
+ EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
+ EXPECT_EQ(base::Version("0.8"), ping_data[1].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[1].next_version);
+ EXPECT_EQ(0, ping_data[1].error_category);
+ EXPECT_EQ(0, ping_data[1].error_code);
+ }
+ };
+
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
{
@@ -954,7 +1024,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
}
@@ -967,7 +1038,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_WAIT,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -976,9 +1048,8 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
- ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
+ "ihfokbkgjpifnbbojhneepfflplebdkc"};
update_client->Update(
ids, base::Bind(&DataCallbackFake::Callback),
@@ -998,8 +1069,8 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
static int num_calls = 0;
// Must use the same stateful installer object.
- static scoped_refptr<CrxInstaller> installer(
- new VersionedTestInstaller());
+ static scoped_refptr<CrxInstaller> installer =
+ base::MakeRefCounted<VersionedTestInstaller>();
++num_calls;
@@ -1032,24 +1103,25 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
static int num_call = 0;
++num_call;
- UpdateResponse::Results results;
+ ProtocolParser::Results results;
if (num_call == 1) {
/*
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
<updatecheck status='ok'>
<urls>
@@ -1066,24 +1138,30 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package;
+ const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
package.hash_sha256 =
"813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
- package.fingerprint = "1";
- UpdateResponse::Result result;
- result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
result.status = "ok";
result.crx_urls.push_back(GURL("http://localhost/download/"));
result.manifest.version = "1.0";
result.manifest.browser_min_version = "11.0.1.0";
result.manifest.packages.push_back(package);
- results.list.push_back(result);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
} else if (num_call == 2) {
/*
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
<updatecheck status='ok'>
<urls>
@@ -1105,7 +1183,11 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package;
+ const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
package.namediff = "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
package.hash_sha256 =
@@ -1113,21 +1195,24 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
package.hashdiff_sha256 =
"73c6e2d4f783fc4ca5481e89e0b8bfce7aec8ead3686290c94792658ec06f2f2";
package.fingerprint = "22";
- UpdateResponse::Result result;
- result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
result.status = "ok";
result.crx_urls.push_back(GURL("http://localhost/download/"));
result.crx_diffurls.push_back(GURL("http://localhost/download/"));
result.manifest.version = "2.0";
result.manifest.browser_min_version = "11.0.1.0";
result.manifest.packages.push_back(package);
- results.list.push_back(result);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
} else {
NOTREACHED();
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -1138,14 +1223,13 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
FilePath path;
@@ -1201,25 +1285,28 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(2U, ping_items.size());
- EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[0].id);
- EXPECT_EQ(base::Version("0.8"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(0, ping_items[0].error_category);
- EXPECT_EQ(0, ping_items[0].error_code);
- EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
- EXPECT_EQ(base::Version("1.0"), ping_items[1].previous_version);
- EXPECT_EQ(base::Version("2.0"), ping_items[1].next_version);
- EXPECT_EQ(0, ping_items[1].diff_error_category);
- EXPECT_EQ(0, ping_items[1].diff_error_code);
- }
- };
-
- std::unique_ptr<FakePingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(2u, ping_data.size());
+ EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.8"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(0, ping_data[0].error_category);
+ EXPECT_EQ(0, ping_data[0].error_code);
+ EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
+ EXPECT_EQ(base::Version("1.0"), ping_data[1].previous_version);
+ EXPECT_EQ(base::Version("2.0"), ping_data[1].next_version);
+ EXPECT_FALSE(ping_data[1].diff_update_failed);
+ EXPECT_EQ(0, ping_data[1].diff_error_category);
+ EXPECT_EQ(0, ping_data[1].diff_error_code);
+ EXPECT_EQ(0, ping_data[1].error_category);
+ EXPECT_EQ(0, ping_data[1].error_code);
+ }
+ };
+
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
{
@@ -1229,7 +1316,8 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -1239,7 +1327,8 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -1248,9 +1337,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
-
+ const std::vector<std::string> ids = {"ihfokbkgjpifnbbojhneepfflplebdkc"};
{
base::RunLoop runloop;
update_client->Update(
@@ -1283,25 +1370,37 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
bool(const std::string& file, base::FilePath* installed_file));
MOCK_METHOD0(Uninstall, bool());
- static void OnInstall(const base::DictionaryValue& manifest,
- const base::FilePath& unpack_path) {
- base::DeleteFile(unpack_path, true);
+ void OnInstall(const base::DictionaryValue& manifest,
+ const base::FilePath& unpack_path) {
+ unpack_path_ = unpack_path;
+ EXPECT_TRUE(base::DirectoryExists(unpack_path_));
}
protected:
- ~MockInstaller() override {}
+ ~MockInstaller() override {
+ // The unpack path is deleted unconditionally by the component state code,
+ // which is driving this installer. Therefore, the unpack path must not
+ // exist when this object is destroyed.
+ if (!unpack_path_.empty())
+ EXPECT_FALSE(base::DirectoryExists(unpack_path_));
+ }
+
+ private:
+ // Contains the |unpack_path| argument of the Install call.
+ base::FilePath unpack_path_;
};
class DataCallbackFake {
public:
static void Callback(const std::vector<std::string>& ids,
std::vector<CrxComponent>* components) {
- scoped_refptr<MockInstaller> installer(new MockInstaller());
+ scoped_refptr<MockInstaller> installer =
+ base::MakeRefCounted<MockInstaller>();
EXPECT_CALL(*installer, OnUpdateError(_)).Times(0);
EXPECT_CALL(*installer, Install(_, _))
.WillOnce(
- DoAll(Invoke(MockInstaller::OnInstall),
+ DoAll(Invoke(installer.get(), &MockInstaller::OnInstall),
Return(CrxInstaller::Result(InstallError::GENERIC_ERROR))));
EXPECT_CALL(*installer, GetInstalledFile(_, _)).Times(0);
EXPECT_CALL(*installer, Uninstall()).Times(0);
@@ -1328,11 +1427,12 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -1340,7 +1440,7 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='jebgalgnebhfojomionfpkfelancnnkf'>
<updatecheck status='ok'>
<urls>
@@ -1357,23 +1457,28 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package;
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
package.hash_sha256 =
"6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
- UpdateResponse::Result result;
- result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
result.status = "ok";
result.crx_urls.push_back(GURL("http://localhost/download/"));
result.manifest.version = "1.0";
result.manifest.browser_min_version = "11.0.1.0";
result.manifest.packages.push_back(package);
- UpdateResponse::Results results;
- results.list.push_back(result);
+ auto& component = components.at(id);
+ component->SetParseResult(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -1384,14 +1489,13 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
download_metrics.url = url;
@@ -1427,20 +1531,20 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(1U, ping_items.size());
- EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
- EXPECT_EQ(base::Version("0.9"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(3, ping_items[0].error_category); // kInstallError.
- EXPECT_EQ(9, ping_items[0].error_code); // kInstallerError.
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(1u, ping_data.size());
+ EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(3, ping_data[0].error_category); // kInstallError.
+ EXPECT_EQ(9, ping_data[0].error_code); // kInstallerError.
}
};
- std::unique_ptr<PingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
{
@@ -1450,7 +1554,8 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
@@ -1459,9 +1564,7 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
-
+ std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
update_client->Update(
ids, base::Bind(&DataCallbackFake::Callback),
base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
@@ -1480,8 +1583,8 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
static int num_calls = 0;
// Must use the same stateful installer object.
- static scoped_refptr<CrxInstaller> installer(
- new VersionedTestInstaller());
+ static scoped_refptr<CrxInstaller> installer =
+ base::MakeRefCounted<VersionedTestInstaller>();
++num_calls;
@@ -1514,24 +1617,25 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
static int num_call = 0;
++num_call;
- UpdateResponse::Results results;
+ ProtocolParser::Results results;
if (num_call == 1) {
/*
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
<updatecheck status='ok'>
<urls>
@@ -1541,31 +1645,39 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
<packages>
<package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'
hash_sha256='813c59747e139a608b3b5fc49633affc6db57437
- 3f309f156ea6d27229c0b3f9'/>
+ 3f309f156ea6d27229c0b3f9'
+ fp='1'/>
</packages>
</manifest>
</updatecheck>
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package;
+ const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
package.hash_sha256 =
"813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
package.fingerprint = "1";
- UpdateResponse::Result result;
- result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
result.status = "ok";
result.crx_urls.push_back(GURL("http://localhost/download/"));
result.manifest.version = "1.0";
result.manifest.browser_min_version = "11.0.1.0";
result.manifest.packages.push_back(package);
- results.list.push_back(result);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
} else if (num_call == 2) {
/*
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
<updatecheck status='ok'>
<urls>
@@ -1587,7 +1699,11 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package;
+ const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
package.namediff = "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
package.hash_sha256 =
@@ -1595,21 +1711,24 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
package.hashdiff_sha256 =
"73c6e2d4f783fc4ca5481e89e0b8bfce7aec8ead3686290c94792658ec06f2f2";
package.fingerprint = "22";
- UpdateResponse::Result result;
- result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
result.status = "ok";
result.crx_urls.push_back(GURL("http://localhost/download/"));
result.crx_diffurls.push_back(GURL("http://localhost/download/"));
result.manifest.version = "2.0";
result.manifest.browser_min_version = "11.0.1.0";
result.manifest.packages.push_back(package);
- results.list.push_back(result);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
} else {
NOTREACHED();
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -1620,14 +1739,13 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
FilePath path;
@@ -1698,26 +1816,28 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(2U, ping_items.size());
- EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[0].id);
- EXPECT_EQ(base::Version("0.8"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(0, ping_items[0].error_category);
- EXPECT_EQ(0, ping_items[0].error_code);
- EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
- EXPECT_EQ(base::Version("1.0"), ping_items[1].previous_version);
- EXPECT_EQ(base::Version("2.0"), ping_items[1].next_version);
- EXPECT_TRUE(ping_items[1].diff_update_failed);
- EXPECT_EQ(1, ping_items[1].diff_error_category); // kNetworkError.
- EXPECT_EQ(-1, ping_items[1].diff_error_code);
- }
- };
-
- std::unique_ptr<FakePingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(2u, ping_data.size());
+ EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.8"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(0, ping_data[0].error_category);
+ EXPECT_EQ(0, ping_data[0].error_code);
+ EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
+ EXPECT_EQ(base::Version("1.0"), ping_data[1].previous_version);
+ EXPECT_EQ(base::Version("2.0"), ping_data[1].next_version);
+ EXPECT_EQ(0, ping_data[1].error_category);
+ EXPECT_EQ(0, ping_data[1].error_code);
+ EXPECT_TRUE(ping_data[1].diff_update_failed);
+ EXPECT_EQ(1, ping_data[1].diff_error_category); // kNetworkError.
+ EXPECT_EQ(-1, ping_data[1].diff_error_code);
+ }
+ };
+
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
{
@@ -1727,7 +1847,8 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -1738,9 +1859,8 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
- EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -1749,8 +1869,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
+ const std::vector<std::string> ids = {"ihfokbkgjpifnbbojhneepfflplebdkc"};
{
base::RunLoop runloop;
@@ -1783,7 +1902,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
crx.name = "test_jebg";
crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx.version = base::Version("0.9");
- crx.installer = new TestInstaller;
+ crx.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx);
}
};
@@ -1806,17 +1925,32 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(1u, ids_to_check.size());
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check.front());
+ EXPECT_EQ(1u, components.count(id));
+
+ auto& component = components.at(id);
+
+ EXPECT_FALSE(component->on_demand());
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "noupdate";
+ component->SetParseResult(result);
+
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(update_check_callback, 0, UpdateResponse::Results(), 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -1827,14 +1961,13 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
};
@@ -1842,13 +1975,15 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
public:
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
- ~FakePingManager() override { EXPECT_TRUE(items().empty()); }
+ ~FakePingManager() override { EXPECT_TRUE(ping_data().empty()); }
};
- std::unique_ptr<PingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ std::unique_ptr<PingManager> ping_manager =
+ base::MakeUnique<FakePingManager>(config());
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
InSequence seq;
@@ -1863,9 +1998,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
-
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
update_client->Update(
ids, base::Bind(&DataCallbackFake::Callback),
base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
@@ -1888,7 +2021,7 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
crx.name = "test_jebg";
crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx.version = base::Version("0.0");
- crx.installer = new TestInstaller;
+ crx.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx);
}
@@ -1907,11 +2040,12 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -1919,7 +2053,7 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='jebgalgnebhfojomionfpkfelancnnkf'>
<updatecheck status='ok'>
<urls>
@@ -1936,23 +2070,34 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
</app>
</response>
*/
- UpdateResponse::Result::Manifest::Package package;
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(1u, ids_to_check.size());
+
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
package.hash_sha256 =
"6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
- UpdateResponse::Result result;
- result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
result.status = "ok";
result.crx_urls.push_back(GURL("http://localhost/download/"));
result.manifest.version = "1.0";
result.manifest.browser_min_version = "11.0.1.0";
result.manifest.packages.push_back(package);
- UpdateResponse::Results results;
- results.list.push_back(result);
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+
+ // Verify that calling Install sets ondemand.
+ EXPECT_TRUE(component->on_demand());
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -1963,14 +2108,13 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
FilePath path;
@@ -2010,35 +2154,30 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(1U, ping_items.size());
- EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
- EXPECT_EQ(base::Version("0.0"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(0, ping_items[0].error_category);
- EXPECT_EQ(0, ping_items[0].error_code);
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(1u, ping_data.size());
+ EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.0"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(0, ping_data[0].error_category);
+ EXPECT_EQ(0, ping_data[0].error_code);
}
};
- std::unique_ptr<FakePingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
-
- // Verify that calling Install sets ondemand.
- OnDemandTester ondemand_tester(update_client, true);
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
- ON_CALL(observer, OnEvent(_, _))
- .WillByDefault(Invoke(&ondemand_tester, &OnDemandTester::CheckOnDemand));
-
InSequence seq;
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
- "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
@@ -2066,7 +2205,7 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
crx.name = "test_jebg";
crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx.version = base::Version("0.0");
- crx.installer = new TestInstaller;
+ crx.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx);
}
@@ -2096,17 +2235,33 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(1u, ids_to_check.size());
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check.front());
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "noupdate";
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+
+ // Verify that calling Install sets ondemand.
+ EXPECT_TRUE(component->on_demand());
+
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(update_check_callback, 0, UpdateResponse::Results(), 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -2117,14 +2272,13 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
};
@@ -2132,21 +2286,17 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
public:
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
- ~FakePingManager() override { EXPECT_TRUE(items().empty()); }
+ ~FakePingManager() override { EXPECT_TRUE(ping_data().empty()); }
};
- std::unique_ptr<FakePingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
-
- // Verify that calling Install sets ondemand.
- OnDemandTester ondemand_tester(update_client, true);
+ std::unique_ptr<FakePingManager> ping_manager =
+ base::MakeUnique<FakePingManager>(config());
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
- ON_CALL(observer, OnEvent(_, _))
- .WillByDefault(Invoke(&ondemand_tester, &OnDemandTester::CheckOnDemand));
-
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
"jebgalgnebhfojomionfpkfelancnnkf"))
.Times(1);
@@ -2171,8 +2321,8 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
update_client->RemoveObserver(&observer);
}
-// Make sure that we don't get any crashes when trying to update an empty list
-// of ids.
+// Tests that UpdateClient::Update returns Error::INVALID_ARGUMENT when
+// the |ids| parameter is empty.
TEST_F(UpdateClientTest, EmptyIdList) {
class DataCallbackFake {
public:
@@ -2183,19 +2333,22 @@ TEST_F(UpdateClientTest, EmptyIdList) {
class CompletionCallbackFake {
public:
static void Callback(const base::Closure& quit_closure, Error error) {
+ DCHECK_EQ(Error::INVALID_ARGUMENT, error);
quit_closure.Run();
}
};
+
class FakeUpdateChecker : public UpdateChecker {
public:
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -2209,30 +2362,36 @@ TEST_F(UpdateClientTest, EmptyIdList) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
};
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), base::WrapUnique(new FakePingManagerImpl(config())),
- &FakeUpdateChecker::Create, &FakeCrxDownloader::Create));
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManagerImpl>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
- std::vector<std::string> empty_id_list;
- base::RunLoop runloop;
+ const std::vector<std::string> empty_id_list;
update_client->Update(
empty_id_list, base::Bind(&DataCallbackFake::Callback),
- base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
- runloop.Run();
+ base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
+ RunThreads();
}
TEST_F(UpdateClientTest, SendUninstallPing) {
+ class CompletionCallbackFake {
+ public:
+ static void Callback(const base::Closure& quit_closure, Error error) {
+ quit_closure.Run();
+ }
+ };
+
class FakeUpdateChecker : public UpdateChecker {
public:
static std::unique_ptr<UpdateChecker> Create(
@@ -2242,7 +2401,8 @@ TEST_F(UpdateClientTest, SendUninstallPing) {
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -2272,22 +2432,25 @@ TEST_F(UpdateClientTest, SendUninstallPing) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(1U, ping_items.size());
- EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("0.0"), ping_items[0].next_version);
- EXPECT_EQ(10, ping_items[0].extra_code1);
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(1u, ping_data.size());
+ EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("0.0"), ping_data[0].next_version);
+ EXPECT_EQ(10, ping_data[0].extra_code1);
}
};
- std::unique_ptr<PingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
+
+ update_client->SendUninstallPing(
+ "jebgalgnebhfojomionfpkfelancnnkf", base::Version("1.0"), 10,
+ base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
- update_client->SendUninstallPing("jebgalgnebhfojomionfpkfelancnnkf",
- base::Version("1.0"), 10);
+ RunThreads();
}
TEST_F(UpdateClientTest, RetryAfter) {
@@ -2299,7 +2462,7 @@ TEST_F(UpdateClientTest, RetryAfter) {
crx.name = "test_jebg";
crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx.version = base::Version("0.9");
- crx.installer = new TestInstaller;
+ crx.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx);
}
};
@@ -2337,11 +2500,12 @@ TEST_F(UpdateClientTest, RetryAfter) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -2356,9 +2520,20 @@ TEST_F(UpdateClientTest, RetryAfter) {
retry_after_sec = 60 * 60; // 1 hour.
}
+ EXPECT_EQ(1u, ids_to_check.size());
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check.front());
+ EXPECT_EQ(1u, components.count(id));
+
+ auto& component = components.at(id);
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "noupdate";
+ component->SetParseResult(result);
+
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0,
- UpdateResponse::Results(), retry_after_sec));
+ FROM_HERE, base::Bind(update_check_callback, 0, retry_after_sec));
return true;
}
};
@@ -2369,14 +2544,13 @@ TEST_F(UpdateClientTest, RetryAfter) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
};
@@ -2384,13 +2558,13 @@ TEST_F(UpdateClientTest, RetryAfter) {
public:
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
- ~FakePingManager() override { EXPECT_TRUE(items().empty()); }
+ ~FakePingManager() override { EXPECT_TRUE(ping_data().empty()); }
};
- std::unique_ptr<PingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
@@ -2416,9 +2590,7 @@ TEST_F(UpdateClientTest, RetryAfter) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
-
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
{
// The engine handles this Update call but responds with a valid
// |retry_after_sec|, which causes subsequent calls to fail.
@@ -2465,7 +2637,9 @@ TEST_F(UpdateClientTest, RetryAfter) {
// Tests the update check for two CRXs scenario. The first component supports
// the group policy to enable updates, and has its updates disabled. The second
// component has an update. The server does not honor the "updatedisabled"
-// attribute and returns updates for both components.
+// attribute and returns updates for both components. However, the update for
+// the first component is not apply and the client responds with a
+// (SERVICE_ERROR, UPDATE_DISABLED)
TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
class DataCallbackFake {
public:
@@ -2475,14 +2649,14 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
crx1.name = "test_jebg";
crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
crx1.version = base::Version("0.9");
- crx1.installer = new TestInstaller;
+ crx1.installer = base::MakeRefCounted<TestInstaller>();
crx1.supports_group_policy_enable_component_updates = true;
CrxComponent crx2;
crx2.name = "test_ihfo";
crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
crx2.version = base::Version("0.8");
- crx2.installer = new TestInstaller;
+ crx2.installer = base::MakeRefCounted<TestInstaller>();
components->push_back(crx1);
components->push_back(crx2);
@@ -2502,11 +2676,12 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
static std::unique_ptr<UpdateChecker> Create(
const scoped_refptr<Configurator>& config,
PersistedData* metadata) {
- return std::unique_ptr<UpdateChecker>(new FakeUpdateChecker());
+ return base::MakeUnique<FakeUpdateChecker>();
}
bool CheckForUpdates(
- const IdToCrxUpdateItemMap& items_to_check,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
const std::string& additional_attributes,
bool enabled_component_updates,
const UpdateCheckCallback& update_check_callback) override {
@@ -2514,7 +2689,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
Fake the following response:
<?xml version='1.0' encoding='UTF-8'?>
- <response protocol='3.0'>
+ <response protocol='3.1'>
<app appid='jebgalgnebhfojomionfpkfelancnnkf'>
<updatecheck status='ok'>
<urls>
@@ -2552,38 +2727,54 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
// and further down to the UpdateChecker instance.
EXPECT_FALSE(enabled_component_updates);
- UpdateResponse::Result::Manifest::Package package1;
- package1.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
- package1.hash_sha256 =
- "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
+ EXPECT_EQ(2u, ids_to_check.size());
+
+ {
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check[0]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
+ package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
+ package.hash_sha256 =
+ "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";
+
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "ok";
+ result.crx_urls.push_back(GURL("http://localhost/download/"));
+ result.manifest.version = "1.0";
+ result.manifest.browser_min_version = "11.0.1.0";
+ result.manifest.packages.push_back(package);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+ }
+
+ {
+ const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
+ EXPECT_EQ(id, ids_to_check[1]);
+ EXPECT_EQ(1u, components.count(id));
+
+ ProtocolParser::Result::Manifest::Package package;
+ package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
+ package.hash_sha256 =
+ "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
- UpdateResponse::Result result1;
- result1.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
- result1.status = "ok";
- result1.crx_urls.push_back(GURL("http://localhost/download/"));
- result1.manifest.version = "1.0";
- result1.manifest.browser_min_version = "11.0.1.0";
- result1.manifest.packages.push_back(package1);
-
- UpdateResponse::Result::Manifest::Package package2;
- package2.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
- package2.hash_sha256 =
- "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
-
- UpdateResponse::Result result2;
- result2.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
- result2.status = "ok";
- result2.crx_urls.push_back(GURL("http://localhost/download/"));
- result2.manifest.version = "1.0";
- result2.manifest.browser_min_version = "11.0.1.0";
- result2.manifest.packages.push_back(package2);
-
- UpdateResponse::Results results;
- results.list.push_back(result1);
- results.list.push_back(result2);
+ ProtocolParser::Result result;
+ result.extension_id = id;
+ result.status = "ok";
+ result.crx_urls.push_back(GURL("http://localhost/download/"));
+ result.manifest.version = "1.0";
+ result.manifest.browser_min_version = "11.0.1.0";
+ result.manifest.packages.push_back(package);
+
+ auto& component = components.at(id);
+ component->SetParseResult(result);
+ }
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(update_check_callback, 0, results, 0));
+ FROM_HERE, base::Bind(update_check_callback, 0, 0));
return true;
}
};
@@ -2594,14 +2785,13 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
bool is_background_download,
net::URLRequestContextGetter* context_getter,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::unique_ptr<CrxDownloader>(new FakeCrxDownloader());
+ return base::MakeUnique<FakeCrxDownloader>();
}
- private:
FakeCrxDownloader()
: CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
- ~FakeCrxDownloader() override {}
+ private:
void DoStartDownload(const GURL& url) override {
DownloadMetrics download_metrics;
FilePath path;
@@ -2641,27 +2831,27 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
explicit FakePingManager(const scoped_refptr<Configurator>& config)
: FakePingManagerImpl(config) {}
~FakePingManager() override {
- const auto& ping_items = items();
- EXPECT_EQ(2U, ping_items.size());
- EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
- EXPECT_EQ(base::Version("0.9"), ping_items[0].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[0].next_version);
- EXPECT_EQ(4, ping_items[0].error_category);
- EXPECT_EQ(2, ping_items[0].error_code);
- EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
- EXPECT_EQ(base::Version("0.8"), ping_items[1].previous_version);
- EXPECT_EQ(base::Version("1.0"), ping_items[1].next_version);
- EXPECT_EQ(0, ping_items[1].error_category);
- EXPECT_EQ(0, ping_items[1].error_code);
+ const auto ping_data = FakePingManagerImpl::ping_data();
+ EXPECT_EQ(2u, ping_data.size());
+ EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
+ EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
+ EXPECT_EQ(4, ping_data[0].error_category);
+ EXPECT_EQ(2, ping_data[0].error_code);
+ EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
+ EXPECT_EQ(base::Version("0.8"), ping_data[1].previous_version);
+ EXPECT_EQ(base::Version("1.0"), ping_data[1].next_version);
+ EXPECT_EQ(0, ping_data[1].error_category);
+ EXPECT_EQ(0, ping_data[1].error_code);
}
};
// Disables updates for the components declaring support for the group policy.
config()->SetEnabledComponentUpdates(false);
- std::unique_ptr<FakePingManager> ping_manager(new FakePingManager(config()));
- scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
- config(), std::move(ping_manager), &FakeUpdateChecker::Create,
- &FakeCrxDownloader::Create));
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
MockObserver observer;
{
@@ -2684,12 +2874,9 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
"ihfokbkgjpifnbbojhneepfflplebdkc"))
.Times(1);
- EXPECT_CALL(observer, OnEvent(Events::COMPONENT_WAIT,
- "ihfokbkgjpifnbbojhneepfflplebdkc"))
- .Times(1);
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
"ihfokbkgjpifnbbojhneepfflplebdkc"))
- .Times(1);
+ .Times(AtLeast(1));
EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
"ihfokbkgjpifnbbojhneepfflplebdkc"))
.Times(1);
@@ -2700,10 +2887,112 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
update_client->AddObserver(&observer);
- std::vector<std::string> ids;
- ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
- ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
+ "ihfokbkgjpifnbbojhneepfflplebdkc"};
+ update_client->Update(
+ ids, base::Bind(&DataCallbackFake::Callback),
+ base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
+
+ RunThreads();
+
+ update_client->RemoveObserver(&observer);
+}
+
+// Tests the scenario where the update check fails.
+TEST_F(UpdateClientTest, OneCrxUpdateCheckFails) {
+ class DataCallbackFake {
+ public:
+ static void Callback(const std::vector<std::string>& ids,
+ std::vector<CrxComponent>* components) {
+ CrxComponent crx;
+ crx.name = "test_jebg";
+ crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+ crx.version = base::Version("0.9");
+ crx.installer = base::MakeRefCounted<TestInstaller>();
+ components->push_back(crx);
+ }
+ };
+
+ class CompletionCallbackFake {
+ public:
+ static void Callback(const base::Closure& quit_closure, Error error) {
+ EXPECT_EQ(Error::UPDATE_CHECK_ERROR, error);
+ quit_closure.Run();
+ }
+ };
+
+ class FakeUpdateChecker : public UpdateChecker {
+ public:
+ static std::unique_ptr<UpdateChecker> Create(
+ const scoped_refptr<Configurator>& config,
+ PersistedData* metadata) {
+ return base::MakeUnique<FakeUpdateChecker>();
+ }
+
+ bool CheckForUpdates(
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
+ const std::string& additional_attributes,
+ bool enabled_component_updates,
+ const UpdateCheckCallback& update_check_callback) override {
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(1u, ids_to_check.size());
+ const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
+ EXPECT_EQ(id, ids_to_check.front());
+ EXPECT_EQ(1u, components.count(id));
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(update_check_callback, -1, 0));
+
+ return true;
+ }
+ };
+
+ class FakeCrxDownloader : public CrxDownloader {
+ public:
+ static std::unique_ptr<CrxDownloader> Create(
+ bool is_background_download,
+ net::URLRequestContextGetter* context_getter,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
+ return base::MakeUnique<FakeCrxDownloader>();
+ }
+
+ FakeCrxDownloader()
+ : CrxDownloader(base::ThreadTaskRunnerHandle::Get(), nullptr) {}
+
+ private:
+ void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
+ };
+
+ class FakePingManager : public FakePingManagerImpl {
+ public:
+ explicit FakePingManager(const scoped_refptr<Configurator>& config)
+ : FakePingManagerImpl(config) {}
+ ~FakePingManager() override { EXPECT_TRUE(ping_data().empty()); }
+ };
+
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeUnique<FakePingManager>(config()),
+ &FakeUpdateChecker::Create, &FakeCrxDownloader::Create);
+
+ MockObserver observer;
+ InSequence seq;
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1)
+ .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
+ CrxUpdateItem item;
+ update_client->GetCrxUpdateState(id, &item);
+ EXPECT_EQ(ComponentState::kUpdateError, item.state);
+ }));
+
+ update_client->AddObserver(&observer);
+ const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
update_client->Update(
ids, base::Bind(&DataCallbackFake::Callback),
base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
diff --git a/chromium/components/update_client/update_engine.cc b/chromium/components/update_client/update_engine.cc
index b127befe91b..ef4db8eaf93 100644
--- a/chromium/components/update_client/update_engine.cc
+++ b/chromium/components/update_client/update_engine.cc
@@ -4,19 +4,23 @@
#include "components/update_client/update_engine.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
#include "components/prefs/pref_service.h"
-#include "components/update_client/action_update_check.h"
+#include "components/update_client/component.h"
#include "components/update_client/configurator.h"
#include "components/update_client/crx_update_item.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/update_checker.h"
#include "components/update_client/update_client_errors.h"
+#include "components/update_client/utils.h"
namespace update_client {
@@ -27,9 +31,7 @@ UpdateContext::UpdateContext(
const UpdateClient::CrxDataCallback& crx_data_callback,
const UpdateEngine::NotifyObserversCallback& notify_observers_callback,
const UpdateEngine::Callback& callback,
- UpdateChecker::Factory update_checker_factory,
- CrxDownloader::Factory crx_downloader_factory,
- PingManager* ping_manager)
+ CrxDownloader::Factory crx_downloader_factory)
: config(config),
is_foreground(is_foreground),
enabled_component_updates(config->EnabledComponentUpdates()),
@@ -37,12 +39,12 @@ UpdateContext::UpdateContext(
crx_data_callback(crx_data_callback),
notify_observers_callback(notify_observers_callback),
callback(callback),
- main_task_runner(base::ThreadTaskRunnerHandle::Get()),
blocking_task_runner(config->GetSequencedTaskRunner()),
- update_checker_factory(update_checker_factory),
- crx_downloader_factory(crx_downloader_factory),
- ping_manager(ping_manager),
- retry_after_sec(0) {}
+ crx_downloader_factory(crx_downloader_factory) {
+ for (const auto& id : ids)
+ components.insert(
+ std::make_pair(id, base::MakeUnique<Component>(*this, id)));
+}
UpdateContext::~UpdateContext() {}
@@ -63,20 +65,6 @@ UpdateEngine::~UpdateEngine() {
DCHECK(thread_checker_.CalledOnValidThread());
}
-bool UpdateEngine::GetUpdateState(const std::string& id,
- CrxUpdateItem* update_item) {
- DCHECK(thread_checker_.CalledOnValidThread());
- for (const auto* context : update_contexts_) {
- const auto& update_items = context->update_items;
- const auto it = update_items.find(id);
- if (it != update_items.end()) {
- *update_item = *it->second.get();
- return true;
- }
- }
- return false;
-}
-
void UpdateEngine::Update(
bool is_foreground,
const std::vector<std::string>& ids,
@@ -90,29 +78,98 @@ void UpdateEngine::Update(
return;
}
- std::unique_ptr<UpdateContext> update_context(new UpdateContext(
+ const auto result = update_contexts_.insert(base::MakeUnique<UpdateContext>(
config_, is_foreground, ids, crx_data_callback,
- notify_observers_callback_, callback, update_checker_factory_,
- crx_downloader_factory_, ping_manager_));
+ notify_observers_callback_, callback, crx_downloader_factory_));
+
+ DCHECK(result.second);
- std::unique_ptr<ActionUpdateCheck> update_check_action(new ActionUpdateCheck(
- (*update_context->update_checker_factory)(config_, metadata_.get()),
- config_->GetBrowserVersion(), config_->ExtraRequestParams()));
+ const auto& it = result.first;
+ const auto& update_context = *it;
+ DCHECK(update_context);
- update_context->current_action = std::move(update_check_action);
- update_contexts_.insert(update_context.get());
+ // Calls out to get the corresponding CrxComponent data for the CRXs in this
+ // update context.
+ DCHECK_EQ(ids.size(), update_context->ids.size());
+ DCHECK_EQ(update_context->ids.size(), update_context->components.size());
+ std::vector<CrxComponent> crx_components;
+ update_context->crx_data_callback.Run(update_context->ids, &crx_components);
+ DCHECK_EQ(update_context->ids.size(), crx_components.size());
- update_context->current_action->Run(
- update_context.get(),
- base::Bind(&UpdateEngine::UpdateComplete, base::Unretained(this),
- update_context.get()));
+ for (size_t i = 0; i != update_context->ids.size(); ++i) {
+ const auto& id = update_context->ids[i];
+ const auto& crx_component = crx_components[i];
+
+ DCHECK_EQ(id, GetCrxComponentID(crx_component));
+ DCHECK_EQ(1u, update_context->components.count(id));
+ DCHECK(update_context->components.at(id));
+
+ auto& component = *update_context->components.at(id);
+ component.set_on_demand(update_context->is_foreground);
+ component.set_crx_component(crx_component);
+ component.set_previous_version(crx_component.version);
+ component.set_previous_fp(crx_component.fingerprint);
+
+ // Handle |kNew| state. This will transition the components to |kChecking|.
+ component.Handle(base::Bind(&UpdateEngine::ComponentCheckingForUpdatesStart,
+ base::Unretained(this), it,
+ base::ConstRef(component)));
+ }
+}
+
+void UpdateEngine::ComponentCheckingForUpdatesStart(
+ const UpdateContextIterator& it,
+ const Component& component) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& update_context = *it;
+ DCHECK(update_context);
+
+ const auto id = component.id();
+ DCHECK_EQ(1u, update_context->components.count(id));
+ DCHECK(update_context->components.at(id));
+
+ // Handle |kChecking| state.
+ auto& mutable_component = *update_context->components.at(id);
+ mutable_component.Handle(base::Bind(
+ &UpdateEngine::ComponentCheckingForUpdatesComplete,
+ base::Unretained(this), it, base::ConstRef(mutable_component)));
+
+ ++update_context->num_components_ready_to_check;
+ if (update_context->num_components_ready_to_check <
+ update_context->ids.size()) {
+ return;
+ }
- ignore_result(update_context.release());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::DoUpdateCheck, base::Unretained(this), it));
}
-void UpdateEngine::UpdateComplete(UpdateContext* update_context, Error error) {
+void UpdateEngine::DoUpdateCheck(const UpdateContextIterator& it) {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(update_contexts_.find(update_context) != update_contexts_.end());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ update_context->update_checker =
+ update_checker_factory_(config_, metadata_.get());
+
+ update_context->update_checker->CheckForUpdates(
+ update_context->ids, update_context->components,
+ config_->ExtraRequestParams(), update_context->enabled_component_updates,
+ base::Bind(&UpdateEngine::UpdateCheckDone, base::Unretained(this), it));
+}
+
+void UpdateEngine::UpdateCheckDone(const UpdateContextIterator& it,
+ int error,
+ int retry_after_sec) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ update_context->retry_after_sec = retry_after_sec;
const int throttle_sec(update_context->retry_after_sec);
DCHECK_LE(throttle_sec, 24 * 60 * 60);
@@ -120,22 +177,155 @@ void UpdateEngine::UpdateComplete(UpdateContext* update_context, Error error) {
// Only positive values for throttle_sec are effective. 0 means that no
// throttling occurs and has the effect of resetting the member.
// Negative values are not trusted and are ignored.
- if (throttle_sec >= 0)
+ if (throttle_sec >= 0) {
throttle_updates_until_ =
- throttle_sec
- ? base::TimeTicks::Now() +
- base::TimeDelta::FromSeconds(throttle_sec)
- : base::TimeTicks();
+ throttle_sec ? base::TimeTicks::Now() +
+ base::TimeDelta::FromSeconds(throttle_sec)
+ : base::TimeTicks();
+ }
+
+ update_context->update_check_error = error;
+
+ for (const auto& id : update_context->ids) {
+ DCHECK_EQ(1u, update_context->components.count(id));
+ DCHECK(update_context->components.at(id));
+
+ auto& component = *update_context->components.at(id);
+ component.UpdateCheckComplete();
+ }
+}
- auto callback = update_context->callback;
+void UpdateEngine::ComponentCheckingForUpdatesComplete(
+ const UpdateContextIterator& it,
+ const Component& component) {
+ DCHECK(thread_checker_.CalledOnValidThread());
- update_contexts_.erase(update_context);
- delete update_context;
+ const auto& update_context = *it;
+ DCHECK(update_context);
- callback.Run(error);
+ ++update_context->num_components_checked;
+ if (update_context->num_components_checked < update_context->ids.size()) {
+ return;
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&UpdateEngine::UpdateCheckComplete,
+ base::Unretained(this), it));
+}
+
+void UpdateEngine::UpdateCheckComplete(const UpdateContextIterator& it) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto& update_context = *it;
+ DCHECK(update_context);
+
+ for (const auto& id : update_context->ids)
+ update_context->component_queue.push(id);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it));
+}
+
+void UpdateEngine::HandleComponent(const UpdateContextIterator& it) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ auto& queue = update_context->component_queue;
+
+ if (queue.empty()) {
+ const Error error = update_context->update_check_error
+ ? Error::UPDATE_CHECK_ERROR
+ : Error::NONE;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&UpdateEngine::UpdateComplete,
+ base::Unretained(this), it, error));
+ return;
+ }
+
+ const auto& id = queue.front();
+ DCHECK_EQ(1u, update_context->components.count(id));
+ const auto& component = update_context->components.at(id);
+ DCHECK(component);
+
+ auto& next_update_delay = (*it)->next_update_delay;
+ if (!next_update_delay.is_zero() && component->IsUpdateAvailable()) {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it),
+ next_update_delay);
+
+ next_update_delay = base::TimeDelta();
+
+ notify_observers_callback_.Run(
+ UpdateClient::Observer::Events::COMPONENT_WAIT, id);
+ return;
+ }
+
+ component->Handle(base::Bind(&UpdateEngine::HandleComponentComplete,
+ base::Unretained(this), it));
+}
+
+void UpdateEngine::HandleComponentComplete(const UpdateContextIterator& it) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ auto& queue = update_context->component_queue;
+ DCHECK(!queue.empty());
+
+ const auto& id = queue.front();
+ DCHECK_EQ(1u, update_context->components.count(id));
+ const auto& component = update_context->components.at(id);
+ DCHECK(component);
+
+ if (component->IsHandled()) {
+ (*it)->next_update_delay = component->GetUpdateDuration();
+
+ if (!component->events().empty()) {
+ ping_manager_->SendPing(*component);
+ }
+
+ queue.pop();
+ }
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it));
+}
+
+void UpdateEngine::UpdateComplete(const UpdateContextIterator& it,
+ Error error) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ auto& update_context = *it;
+ DCHECK(update_context);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(update_context->callback, error));
+
+ update_contexts_.erase(it);
+}
+
+bool UpdateEngine::GetUpdateState(const std::string& id,
+ CrxUpdateItem* update_item) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ for (const auto& context : update_contexts_) {
+ const auto it = context->components.find(id);
+ if (it != context->components.end()) {
+ *update_item = it->second->GetCrxUpdateItem();
+ return true;
+ }
+ }
+ return false;
}
bool UpdateEngine::IsThrottled(bool is_foreground) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
if (is_foreground || throttle_updates_until_.is_null())
return false;
@@ -147,4 +337,33 @@ bool UpdateEngine::IsThrottled(bool is_foreground) const {
now < throttle_updates_until_;
}
+void UpdateEngine::SendUninstallPing(const std::string& id,
+ const base::Version& version,
+ int reason,
+ const Callback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ const auto result = update_contexts_.insert(base::MakeUnique<UpdateContext>(
+ config_, false, std::vector<std::string>{id},
+ UpdateClient::CrxDataCallback(), UpdateEngine::NotifyObserversCallback(),
+ callback, nullptr));
+
+ DCHECK(result.second);
+
+ const auto& it = result.first;
+ const auto& update_context = *it;
+ DCHECK(update_context);
+ DCHECK_EQ(1u, update_context->ids.size());
+ DCHECK_EQ(1u, update_context->components.count(id));
+ const auto& component = update_context->components.at(id);
+
+ component->Uninstall(version, reason);
+
+ update_context->component_queue.push(id);
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdateEngine::HandleComponent, base::Unretained(this), it));
+}
+
} // namespace update_client
diff --git a/chromium/components/update_client/update_engine.h b/chromium/components/update_client/update_engine.h
index e24b2a178cb..df643b1ea42 100644
--- a/chromium/components/update_client/update_engine.h
+++ b/chromium/components/update_client/update_engine.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_UPDATE_CLIENT_UPDATE_ENGINE_H_
#define COMPONENTS_UPDATE_CLIENT_UPDATE_ENGINE_H_
+#include <iterator>
#include <list>
#include <map>
#include <memory>
@@ -17,8 +18,8 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
-#include "components/update_client/action.h"
-#include "components/update_client/component_patcher_operation.h"
+#include "base/time/time.h"
+#include "components/update_client/component.h"
#include "components/update_client/crx_downloader.h"
#include "components/update_client/crx_update_item.h"
#include "components/update_client/ping_manager.h"
@@ -28,7 +29,6 @@
namespace base {
class TimeTicks;
class SequencedTaskRunner;
-class SingleThreadTaskRunner;
} // namespace base
namespace update_client {
@@ -61,13 +61,37 @@ class UpdateEngine {
const UpdateClient::CrxDataCallback& crx_data_callback,
const Callback& update_callback);
+ void SendUninstallPing(const std::string& id,
+ const base::Version& version,
+ int reason,
+ const Callback& update_callback);
+
private:
- void UpdateComplete(UpdateContext* update_context, Error error);
+ using UpdateContexts = std::set<std::unique_ptr<UpdateContext>>;
+ using UpdateContextIterator = UpdateContexts::iterator;
+
+ void UpdateComplete(const UpdateContextIterator& it, Error error);
+
+ void ComponentCheckingForUpdatesStart(const UpdateContextIterator& it,
+ const Component& component);
+ void ComponentCheckingForUpdatesComplete(const UpdateContextIterator& it,
+ const Component& component);
+ void UpdateCheckComplete(const UpdateContextIterator& it);
+
+ void DoUpdateCheck(const UpdateContextIterator& it);
+ void UpdateCheckDone(const UpdateContextIterator& it,
+ int error,
+ int retry_after_sec);
+
+ void HandleComponent(const UpdateContextIterator& it);
+ void HandleComponentComplete(const UpdateContextIterator& it);
// Returns true if the update engine rejects this update call because it
// occurs too soon.
bool IsThrottled(bool is_foreground) const;
+ // base::TimeDelta GetNextUpdateDelay(const Component& component) const;
+
base::ThreadChecker thread_checker_;
scoped_refptr<Configurator> config_;
@@ -84,7 +108,7 @@ class UpdateEngine {
const NotifyObserversCallback notify_observers_callback_;
// Contains the contexts associated with each update in progress.
- std::set<UpdateContext*> update_contexts_;
+ UpdateContexts update_contexts_;
// Implements a rate limiting mechanism for background update checks. Has the
// effect of rejecting the update call if the update call occurs before
@@ -104,16 +128,14 @@ struct UpdateContext {
const UpdateClient::CrxDataCallback& crx_data_callback,
const UpdateEngine::NotifyObserversCallback& notify_observers_callback,
const UpdateEngine::Callback& callback,
- UpdateChecker::Factory update_checker_factory,
- CrxDownloader::Factory crx_downloader_factory,
- PingManager* ping_manager);
+ CrxDownloader::Factory crx_downloader_factory);
~UpdateContext();
scoped_refptr<Configurator> config;
// True if this update has been initiated by the user.
- bool is_foreground;
+ bool is_foreground = false;
// True if the component updates are enabled in this context.
const bool enabled_component_updates;
@@ -130,30 +152,34 @@ struct UpdateContext {
// Called when the all updates associated with this context have completed.
const UpdateEngine::Callback callback;
- // Posts replies back to the main thread.
- scoped_refptr<base::SingleThreadTaskRunner> main_task_runner;
-
// Runs tasks in a blocking thread pool.
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner;
- // Creates instances of UpdateChecker;
- UpdateChecker::Factory update_checker_factory;
-
// Creates instances of CrxDownloader;
CrxDownloader::Factory crx_downloader_factory;
- PingManager* ping_manager; // Not owned by this class.
+ std::unique_ptr<UpdateChecker> update_checker;
- std::unique_ptr<Action> current_action;
+ // The time in seconds to wait until doing further update checks.
+ int retry_after_sec = 0;
- // Contains the CrxUpdateItem instances of the items to update.
- IdToCrxUpdateItemMap update_items;
+ int update_check_error = 0;
+ size_t num_components_ready_to_check = 0;
+ size_t num_components_checked = 0;
- // Contains the ids of the items to update.
- std::queue<std::string> queue;
+ IdToComponentPtrMap components;
- // The time in seconds to wait until doing further update checks.
- int retry_after_sec;
+ std::queue<std::string> component_queue;
+
+ // The time to wait before handling the update for a component.
+ // The wait time is proportional with the cost incurred by updating
+ // the component. The more time it takes to download and apply the
+ // update for the current component, the longer the wait until the engine
+ // is handling the next component in the queue.
+ base::TimeDelta next_update_delay;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UpdateContext);
};
} // namespace update_client
diff --git a/chromium/components/update_client/update_query_params.cc b/chromium/components/update_client/update_query_params.cc
index 5a81a94b775..7b576e585b2 100644
--- a/chromium/components/update_client/update_query_params.cc
+++ b/chromium/components/update_client/update_query_params.cc
@@ -71,8 +71,8 @@ UpdateQueryParamsDelegate* g_delegate = NULL;
// static
std::string UpdateQueryParams::Get(ProdId prod) {
return base::StringPrintf(
- "os=%s&arch=%s&nacl_arch=%s&prod=%s%s", kOs, kArch, GetNaclArch(),
- GetProdIdString(prod),
+ "os=%s&arch=%s&nacl_arch=%s&prod=%s%s&acceptformat=crx2,crx3", kOs, kArch,
+ GetNaclArch(), GetProdIdString(prod),
g_delegate ? g_delegate->GetExtraParams().c_str() : "");
}
diff --git a/chromium/components/update_client/updater_state.cc b/chromium/components/update_client/updater_state.cc
index 0c8f414cdbf..03598815687 100644
--- a/chromium/components/update_client/updater_state.cc
+++ b/chromium/components/update_client/updater_state.cc
@@ -27,16 +27,16 @@ UpdaterState::~UpdaterState() {}
std::unique_ptr<UpdaterState::Attributes> UpdaterState::GetState(
bool is_machine) {
-#if defined(OS_WIN)
+#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
UpdaterState updater_state(is_machine);
updater_state.ReadState();
return base::MakeUnique<Attributes>(updater_state.BuildAttributes());
#else
return nullptr;
-#endif // OS_WIN
+#endif // OS_WIN or Mac
}
-#if defined(OS_WIN)
+#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
void UpdaterState::ReadState() {
is_enterprise_managed_ = IsEnterpriseManaged();
@@ -49,7 +49,7 @@ void UpdaterState::ReadState() {
update_policy_ = GetUpdatePolicy();
#endif // GOOGLE_CHROME_BUILD
}
-#endif // OS_WIN
+#endif // OS_WIN or Mac
UpdaterState::Attributes UpdaterState::BuildAttributes() const {
Attributes attributes;
diff --git a/chromium/components/update_client/updater_state.h b/chromium/components/update_client/updater_state.h
index 11f2fa98553..ea8b64e0e22 100644
--- a/chromium/components/update_client/updater_state.h
+++ b/chromium/components/update_client/updater_state.h
@@ -47,8 +47,7 @@ class UpdaterState {
static bool IsEnterpriseManaged();
static base::Time GetUpdaterLastStartedAU(bool is_machine);
static base::Time GetUpdaterLastChecked(bool is_machine);
- static base::Time GetUpdaterTimeValue(bool is_machine,
- const wchar_t* value_name);
+
static int GetUpdatePolicy();
static std::string NormalizeTimeDelta(const base::TimeDelta& delta);
diff --git a/chromium/components/update_client/updater_state_mac.mm b/chromium/components/update_client/updater_state_mac.mm
new file mode 100644
index 00000000000..033c4b7db5c
--- /dev/null
+++ b/chromium/components/update_client/updater_state_mac.mm
@@ -0,0 +1,181 @@
+// Copyright 2017 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.
+
+#import <Foundation/Foundation.h>
+#import <OpenDirectory/OpenDirectory.h>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/version.h"
+#include "components/update_client/updater_state.h"
+
+namespace update_client {
+
+namespace {
+
+const base::FilePath::CharType kKeystonePlist[] = FILE_PATH_LITERAL(
+ "Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
+ "Contents/Info.plist");
+
+// Gets a value from the updater settings. Returns a retained object.
+// T should be a toll-free Foundation framework type. See Apple's
+// documentation for toll-free bridging.
+template<class T>
+base::scoped_nsobject<T> GetUpdaterSettingsValue(NSString* value_name) {
+ CFStringRef app_id = CFSTR("com.google.Keystone.Agent");
+ base::ScopedCFTypeRef<CFPropertyListRef> plist(
+ CFPreferencesCopyAppValue(base::mac::NSToCFCast(value_name), app_id));
+ return base::scoped_nsobject<T>(
+ base::mac::ObjCCastStrict<T>(static_cast<id>(plist.get())),
+ base::scoped_policy::RETAIN);
+}
+
+base::Time GetUpdaterSettingsTime(NSString* value_name) {
+ base::scoped_nsobject<NSDate> date =
+ GetUpdaterSettingsValue<NSDate>(value_name);
+ base::Time result =
+ base::Time::FromCFAbsoluteTime([date timeIntervalSinceReferenceDate]);
+
+ return result;
+}
+
+base::Version GetVersionFromPlist(const base::FilePath& info_plist) {
+ base::mac::ScopedNSAutoreleasePool scoped_pool;
+ NSData* data =
+ [NSData dataWithContentsOfFile:
+ base::mac::FilePathToNSString(info_plist)];
+ if ([data length] == 0) {
+ return base::Version();
+ }
+ NSDictionary* all_keys = base::mac::ObjCCastStrict<NSDictionary>(
+ [NSPropertyListSerialization propertyListWithData:data
+ options:NSPropertyListImmutable
+ format:nil
+ error:nil]);
+ if (all_keys == nil) {
+ return base::Version();
+ }
+ CFStringRef version =
+ base::mac::GetValueFromDictionary<CFStringRef>(
+ base::mac::NSToCFCast(all_keys),
+ kCFBundleVersionKey);
+ if (version == NULL) {
+ return base::Version();
+ }
+ return base::Version(base::SysCFStringRefToUTF8(version));
+}
+
+} // namespace
+
+std::string UpdaterState::GetUpdaterName() {
+ return std::string("Keystone");
+}
+
+base::Version UpdaterState::GetUpdaterVersion(bool /*is_machine*/) {
+ // System Keystone trumps user one, so check this one first
+ base::FilePath local_library;
+ bool success = base::mac::GetLocalDirectory(NSLibraryDirectory,
+ &local_library);
+ DCHECK(success);
+ base::FilePath system_bundle_plist = local_library.Append(kKeystonePlist);
+ base::Version system_keystone = GetVersionFromPlist(system_bundle_plist);
+ if (system_keystone.IsValid()) {
+ return system_keystone;
+ }
+
+ base::FilePath user_bundle_plist =
+ base::mac::GetUserLibraryPath().Append(kKeystonePlist);
+ return GetVersionFromPlist(user_bundle_plist);
+}
+
+base::Time UpdaterState::GetUpdaterLastStartedAU(bool /*is_machine*/) {
+ return GetUpdaterSettingsTime(@"lastCheckStartDate");
+}
+
+base::Time UpdaterState::GetUpdaterLastChecked(bool /*is_machine*/) {
+ return GetUpdaterSettingsTime(@"lastServerCheckDate");
+}
+
+bool UpdaterState::IsAutoupdateCheckEnabled() {
+ // Auto-update check period override (in seconds).
+ // Applies only to older versions of Keystone.
+ base::scoped_nsobject<NSNumber> timeInterval =
+ GetUpdaterSettingsValue<NSNumber>(@"checkInterval");
+ if (!timeInterval.get()) return true;
+ int value = [timeInterval intValue];
+
+ return 0 < value && value < (24 * 60 * 60);
+}
+
+int UpdaterState::GetUpdatePolicy() {
+ return -1; // Keystone does not support update policies.
+}
+
+bool UpdaterState::IsEnterpriseManaged() {
+ base::mac::ScopedNSAutoreleasePool scoped_pool;
+
+ ODSession* session = [ODSession defaultSession];
+ if (session == nil) {
+ DLOG(WARNING) << "ODSession defult session is nil.";
+ return false;
+ }
+
+ NSError* error = nil;
+ ODNode* node = [ODNode nodeWithSession:session
+ type:kODNodeTypeAuthentication
+ error:&error];
+ if (node == nil) {
+ DLOG(WARNING) << "ODSession cannot obtain the authentication node: "
+ << base::mac::NSToCFCast(error);
+ return false;
+ }
+
+ ODQuery* query = [ODQuery queryWithNode:node
+ forRecordTypes:kODRecordTypeUsers
+ attribute:kODAttributeTypeRecordName
+ matchType:kODMatchEqualTo
+ queryValues:NSUserName()
+ returnAttributes:kODAttributeTypeAllAttributes
+ maximumResults:0
+ error:&error];
+ if (query == nil) {
+ DLOG(WARNING) << "ODSession cannot create user query: "
+ << base::mac::NSToCFCast(error);
+ return false;
+ }
+
+ NSArray* results = [query resultsAllowingPartial:NO error:&error];
+ if (!results) {
+ DLOG(WARNING) << "ODSession cannot obtain current user node: "
+ << base::mac::NSToCFCast(error);
+ return false;
+ }
+ if (results.count != 1) {
+ DLOG(WARNING) << @"ODSession unexpected number of nodes: "
+ << results.count;
+ }
+ for (id element in results) {
+ ODRecord* record = base::mac::ObjCCastStrict<ODRecord>(element);
+ NSArray* attributes =
+ [record valuesForAttribute:kODAttributeTypeMetaRecordName
+ error:NULL];
+ for (id attribute in attributes) {
+ NSString* attribute_value =
+ base::mac::ObjCCastStrict<NSString>(attribute);
+ // Example: "uid=johnsmith,ou=People,dc=chromium,dc=org
+ NSRange dc = [attribute_value rangeOfString:@"(^|,)\\s*dc="
+ options:NSRegularExpressionSearch];
+ if (dc.length > 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+} // namespace update_client
diff --git a/chromium/components/update_client/updater_state_unittest.cc b/chromium/components/update_client/updater_state_unittest.cc
index e36c2c65f70..ca889ade7e1 100644
--- a/chromium/components/update_client/updater_state_unittest.cc
+++ b/chromium/components/update_client/updater_state_unittest.cc
@@ -42,9 +42,13 @@ TEST_F(UpdaterStateTest, Serialize) {
EXPECT_STREQ("1", attributes.at("autoupdatecheckenabled").c_str());
EXPECT_STREQ("1", attributes.at("updatepolicy").c_str());
-#if defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN)
- // The name of the Windows updater for Chrome.
- EXPECT_STREQ("Omaha", UpdaterState::GetState(false)->at("name").c_str());
+#if defined(GOOGLE_CHROME_BUILD)
+ #if defined(OS_WIN)
+ // The name of the Windows updater for Chrome.
+ EXPECT_STREQ("Omaha", UpdaterState::GetState(false)->at("name").c_str());
+ #elif defined(OS_MACOSX)
+ EXPECT_STREQ("Keystone", UpdaterState::GetState(false)->at("name").c_str());
+ #endif
#endif // GOOGLE_CHROME_BUILD
// Tests some of the remaining values.
diff --git a/chromium/components/update_client/updater_state_win.cc b/chromium/components/update_client/updater_state_win.cc
index ae1cecbcf9b..a1660132822 100644
--- a/chromium/components/update_client/updater_state_win.cc
+++ b/chromium/components/update_client/updater_state_win.cc
@@ -42,6 +42,21 @@ const wchar_t kRegValueGoogleUpdatePv[] = L"pv";
const wchar_t kRegValueLastStartedAU[] = L"LastStartedAU";
const wchar_t kRegValueLastChecked[] = L"LastChecked";
+base::Time GetUpdaterTimeValue(bool is_machine, const wchar_t* value_name) {
+ const HKEY root_key = is_machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+ base::win::RegKey update_key;
+
+ if (update_key.Open(root_key, kRegPathGoogleUpdate,
+ KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) {
+ DWORD value(0);
+ if (update_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
+ return base::Time::FromTimeT(value);
+ }
+ }
+
+ return base::Time();
+}
+
} // namespace
std::string UpdaterState::GetUpdaterName() {
@@ -70,22 +85,6 @@ base::Time UpdaterState::GetUpdaterLastChecked(bool is_machine) {
return GetUpdaterTimeValue(is_machine, kRegValueLastChecked);
}
-base::Time UpdaterState::GetUpdaterTimeValue(bool is_machine,
- const wchar_t* value_name) {
- const HKEY root_key = is_machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
- base::win::RegKey update_key;
-
- if (update_key.Open(root_key, kRegPathGoogleUpdate,
- KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) {
- DWORD value(0);
- if (update_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
- return base::Time::FromTimeT(value);
- }
- }
-
- return base::Time();
-}
-
bool UpdaterState::IsAutoupdateCheckEnabled() {
// Check the auto-update check period override. If it is 0 or exceeds the
// maximum timeout, then for all intents and purposes auto updates are
diff --git a/chromium/components/update_client/url_fetcher_downloader.cc b/chromium/components/update_client/url_fetcher_downloader.cc
index 4dcd36e65e4..57fb50d704f 100644
--- a/chromium/components/update_client/url_fetcher_downloader.cc
+++ b/chromium/components/update_client/url_fetcher_downloader.cc
@@ -15,6 +15,7 @@
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/update_client/utils.h"
#include "net/base/load_flags.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "url/gurl.h"
@@ -36,7 +37,36 @@ UrlFetcherDownloader::~UrlFetcherDownloader() {
void UrlFetcherDownloader::DoStartDownload(const GURL& url) {
DCHECK(thread_checker_.CalledOnValidThread());
- url_fetcher_ = net::URLFetcher::Create(0, url, net::URLFetcher::GET, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("url_fetcher_downloader", R"(
+ semantics {
+ sender: "Component Updater"
+ description:
+ "The component updater in Chrome is responsible for updating code "
+ "and data modules such as Flash, CrlSet, Origin Trials, etc. These "
+ "modules are updated on cycles independent of the Chrome release "
+ "tracks. It runs in the browser process and communicates with a "
+ "set of servers using the Omaha protocol to find the latest "
+ "versions of components, download them, and register them with the "
+ "rest of Chrome."
+ trigger: "Manual or automatic software updates."
+ data:
+ "The URL that refers to a component. It is obfuscated for most "
+ "components."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting: "This feature cannot be disabled."
+ chrome_policy {
+ ComponentUpdatesEnabled {
+ policy_options {mode: MANDATORY}
+ ComponentUpdatesEnabled: false
+ }
+ }
+ })");
+ url_fetcher_ = net::URLFetcher::Create(0, url, net::URLFetcher::GET, this,
+ traffic_annotation);
url_fetcher_->SetRequestContext(context_getter_);
url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES |
diff --git a/chromium/components/update_client/url_request_post_interceptor.cc b/chromium/components/update_client/url_request_post_interceptor.cc
index 38501606120..acd75d50e8d 100644
--- a/chromium/components/update_client/url_request_post_interceptor.cc
+++ b/chromium/components/update_client/url_request_post_interceptor.cc
@@ -8,10 +8,13 @@
#include "base/files/file_util.h"
#include "base/macros.h"
+#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
#include "components/update_client/test_configurator.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_data_stream.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_interceptor.h"
@@ -32,7 +35,12 @@ class URLRequestMockJob : public net::URLRequestSimpleJob {
response_body_(response_body) {}
protected:
- int GetResponseCode() const override { return response_code_; }
+ void GetResponseInfo(net::HttpResponseInfo* info) override {
+ const std::string headers =
+ base::StringPrintf("HTTP/1.1 %i OK\r\n\r\n", response_code_);
+ info->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.length()));
+ }
int GetData(std::string* mime_type,
std::string* charset,
diff --git a/chromium/components/update_client/utils.cc b/chromium/components/update_client/utils.cc
index 42a2235082a..74ef1e7e769 100644
--- a/chromium/components/update_client/utils.cc
+++ b/chromium/components/update_client/utils.cc
@@ -5,7 +5,6 @@
#include "components/update_client/utils.h"
#include <stddef.h>
-#include <stdint.h>
#include <algorithm>
#include <cmath>
@@ -17,44 +16,28 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
-#include "base/guid.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/sys_info.h"
-#include "build/build_config.h"
#include "components/crx_file/id_util.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/update_client/component.h"
#include "components/update_client/configurator.h"
-#include "components/update_client/crx_update_item.h"
#include "components/update_client/update_client.h"
#include "components/update_client/update_client_errors.h"
-#include "components/update_client/update_query_params.h"
-#include "components/update_client/updater_state.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
#include "net/base/load_flags.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"
#include "url/gurl.h"
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
namespace update_client {
namespace {
-// Returns the amount of physical memory in GB, rounded to the nearest GB.
-int GetPhysicalMemoryGB() {
- const double kOneGB = 1024 * 1024 * 1024;
- const int64_t phys_mem = base::SysInfo::AmountOfPhysicalMemory();
- return static_cast<int>(std::floor(0.5 + phys_mem / kOneGB));
-}
-
// Produces an extension-like friendly id.
std::string HexStringToID(const std::string& hexstr) {
std::string id;
@@ -74,122 +57,44 @@ std::string HexStringToID(const std::string& hexstr) {
return id;
}
-std::string GetOSVersion() {
-#if defined(OS_WIN)
- const auto ver = base::win::OSInfo::GetInstance()->version_number();
- return base::StringPrintf("%d.%d.%d.%d", ver.major, ver.minor, ver.build,
- ver.patch);
-#else
- return base::SysInfo().OperatingSystemVersion();
-#endif
-}
-
-std::string GetServicePack() {
-#if defined(OS_WIN)
- return base::win::OSInfo::GetInstance()->service_pack_str();
-#else
- return std::string();
-#endif
-}
-
} // namespace
-std::string BuildProtocolRequest(
- const std::string& prod_id,
- const std::string& browser_version,
- const std::string& channel,
- const std::string& lang,
- const std::string& os_long_name,
- const std::string& download_preference,
- const std::string& request_body,
- const std::string& additional_attributes,
- const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes) {
- std::string request(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- "<request protocol=\"3.0\" ");
-
- if (!additional_attributes.empty())
- base::StringAppendF(&request, "%s ", additional_attributes.c_str());
-
- // Chrome version and platform information.
- base::StringAppendF(
- &request,
- "version=\"%s-%s\" prodversion=\"%s\" "
- "requestid=\"{%s}\" lang=\"%s\" updaterchannel=\"%s\" prodchannel=\"%s\" "
- "os=\"%s\" arch=\"%s\" nacl_arch=\"%s\"",
- prod_id.c_str(), // "version" is prefixed by prod_id.
- browser_version.c_str(),
- browser_version.c_str(), // "prodversion"
- base::GenerateGUID().c_str(), // "requestid"
- lang.c_str(), // "lang"
- channel.c_str(), // "updaterchannel"
- channel.c_str(), // "prodchannel"
- UpdateQueryParams::GetOS(), // "os"
- UpdateQueryParams::GetArch(), // "arch"
- UpdateQueryParams::GetNaclArch()); // "nacl_arch"
-#if defined(OS_WIN)
- const bool is_wow64(base::win::OSInfo::GetInstance()->wow64_status() ==
- base::win::OSInfo::WOW64_ENABLED);
- if (is_wow64)
- base::StringAppendF(&request, " wow64=\"1\"");
-#endif
- if (!download_preference.empty())
- base::StringAppendF(&request, " dlpref=\"%s\"",
- download_preference.c_str());
- if (updater_state_attributes &&
- updater_state_attributes->count(UpdaterState::kIsEnterpriseManaged)) {
- base::StringAppendF(
- &request, " %s=\"%s\"", // domainjoined
- UpdaterState::kIsEnterpriseManaged,
- (*updater_state_attributes)[UpdaterState::kIsEnterpriseManaged]
- .c_str());
- }
- base::StringAppendF(&request, ">");
-
- // HW platform information.
- base::StringAppendF(&request, "<hw physmemory=\"%d\"/>",
- GetPhysicalMemoryGB()); // "physmem" in GB.
-
- // OS version and platform information.
- const std::string os_version = GetOSVersion();
- const std::string os_sp = GetServicePack();
- base::StringAppendF(
- &request, "<os platform=\"%s\" arch=\"%s\"",
- os_long_name.c_str(), // "platform"
- base::SysInfo().OperatingSystemArchitecture().c_str()); // "arch"
- if (!os_version.empty())
- base::StringAppendF(&request, " version=\"%s\"", os_version.c_str());
- if (!os_sp.empty())
- base::StringAppendF(&request, " sp=\"%s\"", os_sp.c_str());
- base::StringAppendF(&request, "/>");
-
-#if defined(GOOGLE_CHROME_BUILD)
- // Updater state.
- if (updater_state_attributes) {
- base::StringAppendF(&request, "<updater");
- for (const auto& attr : *updater_state_attributes) {
- if (attr.first != UpdaterState::kIsEnterpriseManaged) {
- base::StringAppendF(&request, " %s=\"%s\"", attr.first.c_str(),
- attr.second.c_str());
- }
- }
- base::StringAppendF(&request, "/>");
- }
-#endif // GOOGLE_CHROME_BUILD
-
- // The actual payload of the request.
- base::StringAppendF(&request, "%s</request>", request_body.c_str());
-
- return request;
-}
std::unique_ptr<net::URLFetcher> SendProtocolRequest(
const GURL& url,
const std::string& protocol_request,
net::URLFetcherDelegate* url_fetcher_delegate,
net::URLRequestContextGetter* url_request_context_getter) {
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("component_updater_utils", R"(
+ semantics {
+ sender: "Component Updater"
+ description:
+ "The component updater in Chrome is responsible for updating code "
+ "and data modules such as Flash, CrlSet, Origin Trials, etc. These "
+ "modules are updated on cycles independent of the Chrome release "
+ "tracks. It runs in the browser process and communicates with a "
+ "set of servers using the Omaha protocol to find the latest "
+ "versions of components, download them, and register them with the "
+ "rest of Chrome."
+ trigger: "Manual or automatic software updates."
+ data:
+ "Various OS and Chrome parameters such as version, bitness, "
+ "release tracks, etc."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting: "This feature cannot be disabled."
+ chrome_policy {
+ ComponentUpdatesEnabled {
+ policy_options {mode: MANDATORY}
+ ComponentUpdatesEnabled: false
+ }
+ }
+ })");
std::unique_ptr<net::URLFetcher> url_fetcher = net::URLFetcher::Create(
- 0, url, net::URLFetcher::POST, url_fetcher_delegate);
+ 0, url, net::URLFetcher::POST, url_fetcher_delegate, traffic_annotation);
if (!url_fetcher.get())
return url_fetcher;
@@ -238,8 +143,8 @@ int GetFetchError(const net::URLFetcher& fetcher) {
}
}
-bool HasDiffUpdate(const CrxUpdateItem* update_item) {
- return !update_item->crx_diffurls.empty();
+bool HasDiffUpdate(const Component& component) {
+ return !component.crx_diffurls().empty();
}
bool IsHttpServerError(int status_code) {
diff --git a/chromium/components/update_client/utils.h b/chromium/components/update_client/utils.h
index 1c9e7414541..02c99259445 100644
--- a/chromium/components/update_client/utils.h
+++ b/chromium/components/update_client/utils.h
@@ -12,7 +12,6 @@
#include "base/callback_forward.h"
#include "components/update_client/update_client.h"
-#include "components/update_client/updater_state.h"
class GURL;
@@ -28,49 +27,14 @@ class URLRequestContextGetter;
namespace update_client {
+class Component;
struct CrxComponent;
-struct CrxUpdateItem;
// Defines a name-value pair that represents an installer attribute.
// Installer attributes are component-specific metadata, which may be serialized
// in an update check request.
using InstallerAttribute = std::pair<std::string, std::string>;
-// An update protocol request starts with a common preamble which includes
-// version and platform information for Chrome and the operating system,
-// followed by a request body, which is the actual payload of the request.
-// For example:
-//
-// <?xml version="1.0" encoding="UTF-8"?>
-// <request protocol="3.0" version="chrome-32.0.1.0" prodversion="32.0.1.0"
-// requestid="{7383396D-B4DD-46E1-9104-AAC6B918E792}"
-// updaterchannel="canary" arch="x86" nacl_arch="x86-64"
-// ADDITIONAL ATTRIBUTES>
-// <hw physmemory="16"/>
-// <os platform="win" version="6.1" arch="x86"/>
-// ... REQUEST BODY ...
-// </request>
-
-// Builds a protocol request string by creating the outer envelope for
-// the request and including the request body specified as a parameter.
-// If present, the |download_preference| specifies a group policy that
-// affects the list of download URLs returned in the update response.
-// If specified, |additional_attributes| are appended as attributes of the
-// request element. The additional attributes have to be well-formed for
-// insertion in the request element. |updater_state_attributes| is an optional
-// parameter specifying that an <updater> element is serialized as part of
-// the request.
-std::string BuildProtocolRequest(
- const std::string& prod_id,
- const std::string& browser_version,
- const std::string& channel,
- const std::string& lang,
- const std::string& os_long_name,
- const std::string& download_preference,
- const std::string& request_body,
- const std::string& additional_attributes,
- const std::unique_ptr<UpdaterState::Attributes>& updater_state_attributes);
-
// Sends a protocol request to the the service endpoint specified by |url|.
// The body of the request is provided by |protocol_request| and it is
// expected to contain XML data. The caller owns the returned object.
@@ -89,8 +53,8 @@ bool FetchSuccess(const net::URLFetcher& fetcher);
// fetch is pending or canceled.
int GetFetchError(const net::URLFetcher& fetcher);
-// Returns true if the |update_item| contains a valid differential update url.
-bool HasDiffUpdate(const CrxUpdateItem* update_item);
+// Returns true if the |component| contains a valid differential update url.
+bool HasDiffUpdate(const Component& component);
// Returns true if the |status_code| represents a server error 5xx.
bool IsHttpServerError(int status_code);
diff --git a/chromium/components/update_client/utils_unittest.cc b/chromium/components/update_client/utils_unittest.cc
index 8cadf1382ff..d3d4f189d58 100644
--- a/chromium/components/update_client/utils_unittest.cc
+++ b/chromium/components/update_client/utils_unittest.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "base/files/file_path.h"
-#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "components/update_client/updater_state.h"
#include "components/update_client/utils.h"
@@ -25,27 +24,6 @@ base::FilePath MakeTestFilePath(const char* file) {
namespace update_client {
-TEST(UpdateClientUtils, BuildProtocolRequest_ProdIdVersion) {
- // Verifies that |prod_id| and |version| are serialized.
- const string request = BuildProtocolRequest("some_prod_id", "1.0", "", "", "",
- "", "", "", nullptr);
- EXPECT_NE(string::npos, request.find(" version=\"some_prod_id-1.0\" "));
-}
-
-TEST(UpdateClientUtils, BuildProtocolRequest_DownloadPreference) {
- // Verifies that an empty |download_preference| is not serialized.
- const string request_no_dlpref =
- BuildProtocolRequest("", "", "", "", "", "", "", "", nullptr);
- EXPECT_EQ(string::npos, request_no_dlpref.find(" dlpref="));
-
- // Verifies that |download_preference| is serialized.
- const string request_with_dlpref =
- BuildProtocolRequest("", "", "", "", "", "some pref", "", "", nullptr);
- EXPECT_NE(string::npos, request_with_dlpref.find(" dlpref=\"some pref\""));
-}
-
-TEST(UpdateClientUtils, BuildProtocolRequest_UpdaterState) {}
-
TEST(UpdateClientUtils, VerifyFileHash256) {
EXPECT_TRUE(VerifyFileHash256(
MakeTestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"),
@@ -170,35 +148,4 @@ TEST(UpdateClientUtils, RemoveUnsecureUrls) {
EXPECT_EQ(0u, urls.size());
}
-TEST(UpdateClientUtils, BuildProtocolRequestUpdaterStateAttributes) {
- // When no updater state is provided, then check that the elements and
- // attributes related to the updater state are not serialized.
- std::string request =
- BuildProtocolRequest("", "", "", "", "", "", "", "", nullptr).c_str();
- EXPECT_EQ(std::string::npos, request.find(" domainjoined"));
- EXPECT_EQ(std::string::npos, request.find("<updater"));
-
- UpdaterState::Attributes attributes;
- attributes["domainjoined"] = "1";
- attributes["name"] = "Omaha";
- attributes["version"] = "1.2.3.4";
- attributes["laststarted"] = "1";
- attributes["lastchecked"] = "2";
- attributes["autoupdatecheckenabled"] = "0";
- attributes["updatepolicy"] = "-1";
- request = BuildProtocolRequest(
- "", "", "", "", "", "", "", "",
- base::MakeUnique<UpdaterState::Attributes>(attributes));
- EXPECT_NE(std::string::npos, request.find(" domainjoined=\"1\""));
- const std::string updater_element =
- "<updater autoupdatecheckenabled=\"0\" "
- "lastchecked=\"2\" laststarted=\"1\" name=\"Omaha\" "
- "updatepolicy=\"-1\" version=\"1.2.3.4\"/>";
-#if defined(GOOGLE_CHROME_BUILD)
- EXPECT_NE(std::string::npos, request.find(updater_element));
-#else
- EXPECT_EQ(std::string::npos, request.find(updater_element));
-#endif // GOOGLE_CHROME_BUILD
-}
-
} // namespace update_client
diff --git a/chromium/components/url_formatter/BUILD.gn b/chromium/components/url_formatter/BUILD.gn
index b391e73962e..3ed810c276a 100644
--- a/chromium/components/url_formatter/BUILD.gn
+++ b/chromium/components/url_formatter/BUILD.gn
@@ -12,6 +12,8 @@ static_library("url_formatter") {
"android/component_jni_registrar.h",
"elide_url.cc",
"elide_url.h",
+ "idn_spoof_checker.cc",
+ "idn_spoof_checker.h",
"url_fixer.cc",
"url_fixer.h",
"url_formatter.cc",
@@ -26,6 +28,7 @@ static_library("url_formatter") {
deps = [
"//base",
"//base:i18n",
+ "//components/url_formatter/top_domains",
"//net",
"//third_party/icu",
"//url",
@@ -49,6 +52,7 @@ source_set("unit_tests") {
deps = [
":url_formatter",
"//base",
+ "//components/url_formatter/top_domains",
"//net",
"//testing/gtest",
"//ui/gfx",
diff --git a/chromium/components/url_formatter/elide_url_unittest.cc b/chromium/components/url_formatter/elide_url_unittest.cc
index f8f52f96416..4ded2f99db3 100644
--- a/chromium/components/url_formatter/elide_url_unittest.cc
+++ b/chromium/components/url_formatter/elide_url_unittest.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
diff --git a/chromium/components/url_formatter/idn_spoof_checker.cc b/chromium/components/url_formatter/idn_spoof_checker.cc
new file mode 100644
index 00000000000..17de0fd9c65
--- /dev/null
+++ b/chromium/components/url_formatter/idn_spoof_checker.cc
@@ -0,0 +1,400 @@
+// Copyright 2017 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/url_formatter/idn_spoof_checker.h"
+
+#include "base/numerics/safe_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/threading/thread_local_storage.h"
+#include "net/base/lookup_string_in_fixed_set.h"
+#include "third_party/icu/source/common/unicode/schriter.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
+#include "third_party/icu/source/i18n/unicode/regex.h"
+#include "third_party/icu/source/i18n/unicode/translit.h"
+#include "third_party/icu/source/i18n/unicode/uspoof.h"
+
+namespace url_formatter {
+
+namespace {
+base::ThreadLocalStorage::StaticSlot tls_index = TLS_INITIALIZER;
+
+void OnThreadTermination(void* regex_matcher) {
+ delete reinterpret_cast<icu::RegexMatcher*>(regex_matcher);
+}
+
+#include "components/url_formatter/top_domains/alexa_skeletons-inc.cc"
+// All the domains in the above file have 3 or fewer labels.
+const size_t kNumberOfLabelsToCheck = 3;
+
+bool LookupMatchInTopDomains(base::StringPiece skeleton) {
+ DCHECK_NE(skeleton.back(), '.');
+ auto labels = base::SplitStringPiece(skeleton, ".", base::KEEP_WHITESPACE,
+ base::SPLIT_WANT_ALL);
+
+ if (labels.size() > kNumberOfLabelsToCheck) {
+ labels.erase(labels.begin(),
+ labels.begin() + labels.size() - kNumberOfLabelsToCheck);
+ }
+
+ while (labels.size() > 1) {
+ std::string partial_skeleton = base::JoinString(labels, ".");
+ if (net::LookupStringInFixedSet(
+ kDafsa, arraysize(kDafsa), partial_skeleton.data(),
+ partial_skeleton.length()) != net::kDafsaNotFound)
+ return true;
+ labels.erase(labels.begin());
+ }
+ return false;
+}
+
+} // namespace
+
+IDNSpoofChecker::IDNSpoofChecker() {
+ UErrorCode status = U_ZERO_ERROR;
+ checker_ = uspoof_open(&status);
+ if (U_FAILURE(status)) {
+ checker_ = nullptr;
+ return;
+ }
+
+ // At this point, USpoofChecker has all the checks enabled except
+ // for USPOOF_CHAR_LIMIT (USPOOF_{RESTRICTION_LEVEL, INVISIBLE,
+ // MIXED_SCRIPT_CONFUSABLE, WHOLE_SCRIPT_CONFUSABLE, MIXED_NUMBERS, ANY_CASE})
+ // This default configuration is adjusted below as necessary.
+
+ // Set the restriction level to moderate. It allows mixing Latin with another
+ // script (+ COMMON and INHERITED). Except for Chinese(Han + Bopomofo),
+ // Japanese(Hiragana + Katakana + Han), and Korean(Hangul + Han), only one
+ // script other than Common and Inherited can be mixed with Latin. Cyrillic
+ // and Greek are not allowed to mix with Latin.
+ // See http://www.unicode.org/reports/tr39/#Restriction_Level_Detection
+ uspoof_setRestrictionLevel(checker_, USPOOF_MODERATELY_RESTRICTIVE);
+
+ // Sets allowed characters in IDN labels and turns on USPOOF_CHAR_LIMIT.
+ SetAllowedUnicodeSet(&status);
+
+ // Enable the return of auxillary (non-error) information.
+ // We used to disable WHOLE_SCRIPT_CONFUSABLE check explicitly, but as of
+ // ICU 58.1, WSC is a no-op in a single string check API.
+ int32_t checks = uspoof_getChecks(checker_, &status) | USPOOF_AUX_INFO;
+ uspoof_setChecks(checker_, checks, &status);
+
+ // Four characters handled differently by IDNA 2003 and IDNA 2008. UTS46
+ // transitional processing treats them as IDNA 2003 does; maps U+00DF and
+ // U+03C2 and drops U+200[CD].
+ deviation_characters_ = icu::UnicodeSet(
+ UNICODE_STRING_SIMPLE("[\\u00df\\u03c2\\u200c\\u200d]"), status);
+ deviation_characters_.freeze();
+
+ // Latin letters outside ASCII. 'Script_Extensions=Latin' is not necessary
+ // because additional characters pulled in with scx=Latn are not included in
+ // the allowed set.
+ non_ascii_latin_letters_ =
+ icu::UnicodeSet(UNICODE_STRING_SIMPLE("[[:Latin:] - [a-zA-Z]]"), status);
+ non_ascii_latin_letters_.freeze();
+
+ // The following two sets are parts of |dangerous_patterns_|.
+ kana_letters_exceptions_ = icu::UnicodeSet(
+ UNICODE_STRING_SIMPLE("[\\u3078-\\u307a\\u30d8-\\u30da\\u30fb-\\u30fe]"),
+ status);
+ kana_letters_exceptions_.freeze();
+ combining_diacritics_exceptions_ =
+ icu::UnicodeSet(UNICODE_STRING_SIMPLE("[\\u0300-\\u0339]"), status);
+ combining_diacritics_exceptions_.freeze();
+
+ // These Cyrillic letters look like Latin. A domain label entirely made of
+ // these letters is blocked as a simplified whole-script-spoofable.
+ cyrillic_letters_latin_alike_ =
+ icu::UnicodeSet(icu::UnicodeString("[аÑÔеһіјÓорԛѕÔхуъЬҽпгѵѡ]"), status);
+ cyrillic_letters_latin_alike_.freeze();
+
+ cyrillic_letters_ =
+ icu::UnicodeSet(UNICODE_STRING_SIMPLE("[[:Cyrl:]]"), status);
+ cyrillic_letters_.freeze();
+
+ DCHECK(U_SUCCESS(status));
+ // This set is used to determine whether or not to apply a slow
+ // transliteration to remove diacritics to a given hostname before the
+ // confusable skeleton calculation for comparison with top domain names. If
+ // it has any character outside the set, the expensive step will be skipped
+ // because it cannot match any of top domain names.
+ // The last ([\u0300-\u0339] is a shorthand for "[:Identifier_Status=Allowed:]
+ // & [:Script_Extensions=Inherited:] - [\\u200C\\u200D]". The latter is a
+ // subset of the former but it does not matter because hostnames with
+ // characters outside the latter set would be rejected in an earlier step.
+ lgc_letters_n_ascii_ = icu::UnicodeSet(
+ UNICODE_STRING_SIMPLE("[[:Latin:][:Greek:][:Cyrillic:][0-9\\u002e_"
+ "\\u002d][\\u0300-\\u0339]]"),
+ status);
+ lgc_letters_n_ascii_.freeze();
+
+ // Used for diacritics-removal before the skeleton calculation. Add
+ // "ł > l; ø > o; đ > d" that are not handled by "NFD; Nonspacing mark
+ // removal; NFC". On top of that, supplement the Unicode confusable list by
+ // replacing {U+043A (к), U+0138(ĸ), U+03BA(κ)}, U+04CF (Ó) and U+043F(п) by
+ // 'k', 'l' and 'n', respectively.
+ // TODO(jshin): Revisit "ł > l; ø > o" mapping.
+ UParseError parse_error;
+ transliterator_.reset(icu::Transliterator::createFromRules(
+ UNICODE_STRING_SIMPLE("DropAcc"),
+ icu::UnicodeString("::NFD; ::[:Nonspacing Mark:] Remove; ::NFC;"
+ " Å‚ > l; ø > o; Ä‘ > d; Ó > l; [кĸκ] > k; п > n;"),
+ UTRANS_FORWARD, parse_error, status));
+ DCHECK(U_SUCCESS(status))
+ << "Spoofchecker initalization failed due to an error: "
+ << u_errorName(status);
+}
+
+IDNSpoofChecker::~IDNSpoofChecker() {
+ uspoof_close(checker_);
+}
+
+bool IDNSpoofChecker::SafeToDisplayAsUnicode(base::StringPiece16 label,
+ bool is_tld_ascii) {
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t result =
+ uspoof_check(checker_, label.data(),
+ base::checked_cast<int32_t>(label.size()), NULL, &status);
+ // If uspoof_check fails (due to library failure), or if any of the checks
+ // fail, treat the IDN as unsafe.
+ if (U_FAILURE(status) || (result & USPOOF_ALL_CHECKS))
+ return false;
+
+ icu::UnicodeString label_string(FALSE, label.data(),
+ base::checked_cast<int32_t>(label.size()));
+
+ // A punycode label with 'xn--' prefix is not subject to the URL
+ // canonicalization and is stored as it is in GURL. If it encodes a deviation
+ // character (UTS 46; e.g. U+00DF/sharp-s), it should be still shown in
+ // punycode instead of Unicode. Without this check, xn--fu-hia for
+ // 'fu<sharp-s>' would be converted to 'fu<sharp-s>' for display because
+ // "UTS 46 section 4 Processing step 4" applies validity criteria for
+ // non-transitional processing (i.e. do not map deviation characters) to any
+ // punycode labels regardless of whether transitional or non-transitional is
+ // chosen. On the other hand, 'fu<sharp-s>' typed or copy and pasted
+ // as Unicode would be canonicalized to 'fuss' by GURL and is displayed as
+ // such. See http://crbug.com/595263 .
+ if (deviation_characters_.containsSome(label_string))
+ return false;
+
+ // If there's no script mixing, the input is regarded as safe without any
+ // extra check unless it falls into one of three categories:
+ // - contains Kana letter exceptions
+ // - the TLD is ASCII and the input is made entirely of Cyrillic letters
+ // that look like Latin letters.
+ // - it has combining diacritic marks.
+ // Note that the following combinations of scripts are treated as a 'logical'
+ // single script.
+ // - Chinese: Han, Bopomofo, Common
+ // - Japanese: Han, Hiragana, Katakana, Common
+ // - Korean: Hangul, Han, Common
+ result &= USPOOF_RESTRICTION_LEVEL_MASK;
+ if (result == USPOOF_ASCII)
+ return true;
+ if (result == USPOOF_SINGLE_SCRIPT_RESTRICTIVE &&
+ kana_letters_exceptions_.containsNone(label_string) &&
+ combining_diacritics_exceptions_.containsNone(label_string)) {
+ // Check Cyrillic confusable only for ASCII TLDs.
+ return !is_tld_ascii || !IsMadeOfLatinAlikeCyrillic(label_string);
+ }
+
+ // Additional checks for |label| with multiple scripts, one of which is Latin.
+ // Disallow non-ASCII Latin letters to mix with a non-Latin script.
+ // Note that the non-ASCII Latin check should not be applied when the entire
+ // label is made of Latin. Checking with lgc_letters set here should be fine
+ // because script mixing of LGC is already rejected.
+ if (non_ascii_latin_letters_.containsSome(label_string) &&
+ !lgc_letters_n_ascii_.containsAll(label_string))
+ return false;
+
+ if (!tls_index.initialized())
+ tls_index.Initialize(&OnThreadTermination);
+ icu::RegexMatcher* dangerous_pattern =
+ reinterpret_cast<icu::RegexMatcher*>(tls_index.Get());
+ if (!dangerous_pattern) {
+ // Disallow the katakana no, so, zo, or n, as they may be mistaken for
+ // slashes when they're surrounded by non-Japanese scripts (i.e. scripts
+ // other than Katakana, Hiragana or Han). If {no, so, zo, n} next to a
+ // non-Japanese script on either side is disallowed, legitimate cases like
+ // '{vitamin in Katakana}b6' are blocked. Note that trying to block those
+ // characters when used alone as a label is futile because those cases
+ // would not reach here.
+ // Also disallow what used to be blocked by mixed-script-confusable (MSC)
+ // detection. ICU 58 does not detect MSC any more for a single input string.
+ // See http://bugs.icu-project.org/trac/ticket/12823 .
+ // TODO(jshin): adjust the pattern once the above ICU bug is fixed.
+ // - Disallow U+30FB (Katakana Middle Dot) and U+30FC (Hiragana-Katakana
+ // Prolonged Sound) used out-of-context.
+ // - Dislallow U+30FD/E (Katakana iteration mark/voiced iteration mark)
+ // unless they're preceded by a Katakana.
+ // - Disallow three Hiragana letters (U+307[8-A]) or Katakana letters
+ // (U+30D[8-A]) that look exactly like each other when they're used in a
+ // label otherwise entirely in Katakna or Hiragana.
+ // - Disallow U+0585 (Armenian Small Letter Oh) and U+0581 (Armenian Small
+ // Letter Co) to be next to Latin.
+ // - Disallow Latin 'o' and 'g' next to Armenian.
+ // - Disalow mixing of Latin and Canadian Syllabary.
+ // - Disalow mixing of Latin and Tifinagh.
+ // - Disallow combining diacritical mark (U+0300-U+0339) after a non-LGC
+ // character. Other combining diacritical marks are not in the allowed
+ // character set.
+ dangerous_pattern = new icu::RegexMatcher(
+ icu::UnicodeString(
+ R"([^\p{scx=kana}\p{scx=hira}\p{scx=hani}])"
+ R"([\u30ce\u30f3\u30bd\u30be])"
+ R"([^\p{scx=kana}\p{scx=hira}\p{scx=hani}]|)"
+ R"([^\p{scx=kana}\p{scx=hira}]\u30fc|^\u30fc|)"
+ R"([^\p{scx=kana}][\u30fd\u30fe]|^[\u30fd\u30fe]|)"
+ R"(^[\p{scx=kana}]+[\u3078-\u307a][\p{scx=kana}]+$|)"
+ R"(^[\p{scx=hira}]+[\u30d8-\u30da][\p{scx=hira}]+$|)"
+ R"([a-z]\u30fb|\u30fb[a-z]|)"
+ R"(^[\u0585\u0581]+[a-z]|[a-z][\u0585\u0581]+$|)"
+ R"([a-z][\u0585\u0581]+[a-z]|)"
+ R"(^[og]+[\p{scx=armn}]|[\p{scx=armn}][og]+$|)"
+ R"([\p{scx=armn}][og]+[\p{scx=armn}]|)"
+ R"([\p{sc=cans}].*[a-z]|[a-z].*[\p{sc=cans}]|)"
+ R"([\p{sc=tfng}].*[a-z]|[a-z].*[\p{sc=tfng}]|)"
+ R"([^\p{scx=latn}\p{scx=grek}\p{scx=cyrl}][\u0300-\u0339]|)"
+ R"([^\p{scx=arab}][\u064b-\u0655\u0670]|)"
+ R"([^\p{scx=hebr}]\u05b4)",
+ -1, US_INV),
+ 0, status);
+ tls_index.Set(dangerous_pattern);
+ }
+ dangerous_pattern->reset(label_string);
+ return !dangerous_pattern->find();
+}
+
+bool IDNSpoofChecker::SimilarToTopDomains(base::StringPiece16 hostname) {
+ size_t hostname_length = hostname.length() - (hostname.back() == '.' ? 1 : 0);
+ icu::UnicodeString ustr_host(FALSE, hostname.data(), hostname_length);
+ // If input has any characters outside Latin-Greek-Cyrillic and [0-9._-],
+ // there is no point in getting rid of diacritics because combining marks
+ // attached to non-LGC characters are already blocked.
+ if (lgc_letters_n_ascii_.span(ustr_host, 0, USET_SPAN_CONTAINED) ==
+ ustr_host.length())
+ transliterator_.get()->transliterate(ustr_host);
+
+ UErrorCode status = U_ZERO_ERROR;
+ icu::UnicodeString ustr_skeleton;
+ uspoof_getSkeletonUnicodeString(checker_, 0, ustr_host, ustr_skeleton,
+ &status);
+ if (U_FAILURE(status))
+ return false;
+ std::string skeleton;
+ ustr_skeleton.toUTF8String(skeleton);
+ return LookupMatchInTopDomains(skeleton);
+}
+
+bool IDNSpoofChecker::IsMadeOfLatinAlikeCyrillic(
+ const icu::UnicodeString& label) {
+ // Collect all the Cyrillic letters in |label_string| and see if they're
+ // a subset of |cyrillic_letters_latin_alike_|.
+ // A shortcut of defining cyrillic_letters_latin_alike_ to include [0-9] and
+ // [_-] and checking if the set contains all letters of |label|
+ // would work in most cases, but not if a label has non-letters outside
+ // ASCII.
+ icu::UnicodeSet cyrillic_in_label;
+ icu::StringCharacterIterator it(label);
+ for (it.setToStart(); it.hasNext();) {
+ const UChar32 c = it.next32PostInc();
+ if (cyrillic_letters_.contains(c))
+ cyrillic_in_label.add(c);
+ }
+ return !cyrillic_in_label.isEmpty() &&
+ cyrillic_letters_latin_alike_.containsAll(cyrillic_in_label);
+}
+
+void IDNSpoofChecker::SetAllowedUnicodeSet(UErrorCode* status) {
+ if (U_FAILURE(*status))
+ return;
+
+ // The recommended set is a set of characters for identifiers in a
+ // security-sensitive environment taken from UTR 39
+ // (http://unicode.org/reports/tr39/) and
+ // http://www.unicode.org/Public/security/latest/xidmodifications.txt .
+ // The inclusion set comes from "Candidate Characters for Inclusion
+ // in idenfiers" of UTR 31 (http://www.unicode.org/reports/tr31). The list
+ // may change over the time and will be updated whenever the version of ICU
+ // used in Chromium is updated.
+ const icu::UnicodeSet* recommended_set =
+ uspoof_getRecommendedUnicodeSet(status);
+ icu::UnicodeSet allowed_set;
+ allowed_set.addAll(*recommended_set);
+ const icu::UnicodeSet* inclusion_set = uspoof_getInclusionUnicodeSet(status);
+ allowed_set.addAll(*inclusion_set);
+
+// Five aspirational scripts are taken from UTR 31 Table 6 at
+// http://www.unicode.org/reports/tr31/#Aspirational_Use_Scripts .
+// Not all the characters of aspirational scripts are suitable for
+// identifiers. Therefore, only characters belonging to
+// [:Identifier_Type=Aspirational:] (listed in 'Status/Type=Aspirational'
+// section at
+// http://www.unicode.org/Public/security/latest/xidmodifications.txt) are
+// are added to the allowed set. The list has to be updated when a new
+// version of Unicode is released. The current version is 9.0.0 and ICU 60
+// will have Unicode 10.0 data.
+#if U_ICU_VERSION_MAJOR_NUM < 60
+ const icu::UnicodeSet aspirational_scripts(
+ icu::UnicodeString(
+ // Unified Canadian Syllabics
+ "[\\u1401-\\u166C\\u166F-\\u167F"
+ // Mongolian
+ "\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA"
+ // Unified Canadian Syllabics
+ "\\u18B0-\\u18F5"
+ // Tifinagh
+ "\\u2D30-\\u2D67\\u2D7F"
+ // Yi
+ "\\uA000-\\uA48C"
+ // Miao
+ "\\U00016F00-\\U00016F44\\U00016F50-\\U00016F7E"
+ "\\U00016F8F-\\U00016F9F]",
+ -1, US_INV),
+ *status);
+ allowed_set.addAll(aspirational_scripts);
+#else
+#error "Update aspirational_scripts per Unicode 10.0"
+#endif
+
+ // The sections below refer to Mozilla's IDN blacklist:
+ // http://kb.mozillazine.org/Network.IDN.blacklist_chars
+ //
+ // U+0338 (Combining Long Solidus Overlay) is included in the recommended set,
+ // but is blacklisted by Mozilla. It is dropped because it can look like a
+ // slash when rendered with a broken font.
+ allowed_set.remove(0x338u);
+ // U+05F4 (Hebrew Punctuation Gershayim) is in the inclusion set, but is
+ // blacklisted by Mozilla. We keep it, even though it can look like a double
+ // quotation mark. Using it in Hebrew should be safe. When used with a
+ // non-Hebrew script, it'd be filtered by other checks in place.
+ //
+ // U+2010 (Hyphen) is in the inclusion set, but we drop it because it can be
+ // confused with an ASCII U+002D (Hyphen-Minus).
+ allowed_set.remove(0x2010u);
+ // U+2027 (Hyphenation Point) is in the inclusion set, but is blacklisted by
+ // Mozilla. It is dropped, as it can be confused with U+30FB (Katakana Middle
+ // Dot).
+ allowed_set.remove(0x2027u);
+
+#if defined(OS_MACOSX)
+ // The following characters are reported as present in the default macOS
+ // system UI font, but they render as blank. Remove them from the allowed
+ // set to prevent spoofing until the font issue is resolved.
+
+ // Arabic letter KASHMIRI YEH. Not used in Arabic and Persian.
+ allowed_set.remove(0x0620u);
+
+ // Tibetan characters used for transliteration of ancient texts:
+ allowed_set.remove(0x0F8Cu);
+ allowed_set.remove(0x0F8Du);
+ allowed_set.remove(0x0F8Eu);
+ allowed_set.remove(0x0F8Fu);
+#endif
+
+ uspoof_setAllowedUnicodeSet(checker_, &allowed_set, status);
+}
+
+} // namespace url_formatter
diff --git a/chromium/components/url_formatter/idn_spoof_checker.h b/chromium/components/url_formatter/idn_spoof_checker.h
new file mode 100644
index 00000000000..36d7c789693
--- /dev/null
+++ b/chromium/components/url_formatter/idn_spoof_checker.h
@@ -0,0 +1,78 @@
+// Copyright 2017 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_URL_FORMATTER_IDN_SPOOF_CHECKER_H_
+#define COMPONENTS_URL_FORMATTER_IDN_SPOOF_CHECKER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "third_party/icu/source/common/unicode/uniset.h"
+#include "third_party/icu/source/common/unicode/utypes.h"
+#include "third_party/icu/source/common/unicode/uversion.h"
+
+// 'icu' does not work. Use U_ICU_NAMESPACE.
+namespace U_ICU_NAMESPACE {
+
+class Transliterator;
+class UnicodeString;
+
+} // namespace U_ICU_NAMESPACE
+
+struct USpoofChecker;
+
+namespace url_formatter {
+
+// A helper class for IDN Spoof checking, used to ensure that no IDN input is
+// spoofable per Chromium's standard of spoofability. For a more thorough
+// explanation of how spoof checking works in Chromium, see
+// http://dev.chromium.org/developers/design-documents/idn-in-google-chrome .
+
+class IDNSpoofChecker {
+ public:
+ IDNSpoofChecker();
+ ~IDNSpoofChecker();
+
+ // Returns true if |label| is safe to display as Unicode. In the event of
+ // library failure, all IDN inputs will be treated as unsafe.
+ // See the function body for details on the specific safety checks performed.
+ bool SafeToDisplayAsUnicode(base::StringPiece16 label, bool is_tld_ascii);
+
+ // Returns true if |hostname| or the last few components of |hostname| looks
+ // similar to one of top domains listed in top_domains/alexa_domains.list. Two
+ // checks are done:
+ // 1. Calculate the skeleton of |hostname| based on the Unicode confusable
+ // character list and look it up in the pre-calculated skeleton list of
+ // top domains.
+ // 2. Look up the diacritic-free version of |hostname| in the list of
+ // top domains. Note that non-IDN hostnames will not get here.
+ bool SimilarToTopDomains(base::StringPiece16 hostname);
+
+ private:
+ // Sets allowed characters in IDN labels and turns on USPOOF_CHAR_LIMIT.
+ void SetAllowedUnicodeSet(UErrorCode* status);
+
+ // Returns true if all the Cyrillic letters in |label| belong to a set of
+ // Cyrillic letters that look like ASCII Latin letters.
+ bool IsMadeOfLatinAlikeCyrillic(const icu::UnicodeString& label);
+
+ USpoofChecker* checker_;
+ icu::UnicodeSet deviation_characters_;
+ icu::UnicodeSet non_ascii_latin_letters_;
+ icu::UnicodeSet kana_letters_exceptions_;
+ icu::UnicodeSet combining_diacritics_exceptions_;
+ icu::UnicodeSet cyrillic_letters_;
+ icu::UnicodeSet cyrillic_letters_latin_alike_;
+ icu::UnicodeSet lgc_letters_n_ascii_;
+ std::unique_ptr<icu::Transliterator> transliterator_;
+
+ IDNSpoofChecker(const IDNSpoofChecker&) = delete;
+ void operator=(const IDNSpoofChecker&) = delete;
+};
+
+} // namespace url_formatter
+
+#endif // COMPONENTS_URL_FORMATTER_IDN_SPOOF_CHECKER_H_
diff --git a/chromium/components/url_formatter/top_domains/BUILD.gn b/chromium/components/url_formatter/top_domains/BUILD.gn
new file mode 100644
index 00000000000..a24132b39ab
--- /dev/null
+++ b/chromium/components/url_formatter/top_domains/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2017 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.
+
+action_foreach("top_domains") {
+ script = "//net/tools/dafsa/make_dafsa.py"
+ sources = [
+ "alexa_skeletons.gperf",
+ ]
+ outputs = [
+ "${target_gen_dir}/{{source_name_part}}-inc.cc",
+ ]
+ args = [
+ "{{source}}",
+ rebase_path("${target_gen_dir}/{{source_name_part}}-inc.cc",
+ root_build_dir),
+ ]
+}
+
+if (!is_ios && !is_android) {
+ executable("make_top_domain_gperf") {
+ sources = [
+ "make_top_domain_gperf.cc",
+ ]
+
+ deps = [
+ "//base",
+ "//base:i18n",
+ "//third_party/icu",
+ ]
+ }
+}
diff --git a/chromium/components/url_formatter/top_domains/README b/chromium/components/url_formatter/top_domains/README
new file mode 100644
index 00000000000..137cdeca262
--- /dev/null
+++ b/chromium/components/url_formatter/top_domains/README
@@ -0,0 +1,16 @@
+* alexa_domains.list
+
+ The Alexa top 10k domains, one per line, constructed by running
+ make_alexa_top_list.py. Used as an input to make_top_domain_gperf.
+ It's derived from
+ src/tools/perf/page_sets/alexa1-10000-urls.json with make_alexa_top_list.py
+
+* alexa_skeletons.gperf
+
+ The checked-in output of make_top_domain_gperf. Processed during the
+ build to generate alexa_names_and_skeletons-inc.cc, which is used by
+ url_formatter.cc. This must be regenerated as follows if ICU is updated,
+ since skeletons can differ across ICU versions:
+
+ $ ninja -C $build_outdir make_top_domain_gperf
+ $ $build_outdir/make_top_domain_gperf
diff --git a/chromium/components/url_formatter/top_domains/alexa_domains.list b/chromium/components/url_formatter/top_domains/alexa_domains.list
new file mode 100644
index 00000000000..a76cc116ada
--- /dev/null
+++ b/chromium/components/url_formatter/top_domains/alexa_domains.list
@@ -0,0 +1,9176 @@
+facebook.com
+google.com
+youtube.com
+yahoo.com
+baidu.com
+amazon.com
+wikipedia.org
+qq.com
+live.com
+taobao.com
+google.co.in
+twitter.com
+blogspot.com
+linkedin.com
+bing.com
+yandex.ru
+vk.com
+ask.com
+ebay.com
+wordpress.com
+google.de
+msn.com
+tumblr.com
+163.com
+google.com.hk
+mail.ru
+google.co.uk
+hao123.com
+google.com.br
+weibo.com
+xvideos.com
+microsoft.com
+delta-search.com
+google.fr
+conduit.com
+fc2.com
+craigslist.org
+google.ru
+pinterest.com
+instagram.com
+tmall.com
+xhamster.com
+odnoklassniki.ru
+google.it
+sohu.com
+paypal.com
+babylon.com
+google.es
+imdb.com
+apple.com
+amazon.de
+bbc.co.uk
+adobe.com
+soso.com
+pornhub.com
+google.com.mx
+blogger.com
+neobux.com
+amazon.co.uk
+ifeng.com
+google.ca
+avg.com
+go.com
+xnxx.com
+blogspot.in
+alibaba.com
+aol.com
+buildathome.info
+cnn.com
+mywebsearch.com
+ku6.com
+alipay.com
+vube.com
+google.com.tr
+youku.com
+redtube.com
+dailymotion.com
+google.com.au
+adf.ly
+netflix.com
+adcash.com
+about.com
+google.pl
+imgur.com
+ebay.de
+amazon.fr
+flickr.com
+thepiratebay.sx
+youporn.com
+uol.com.br
+huffingtonpost.com
+stackoverflow.com
+jd.com
+t.co
+livejasmin.com
+ebay.co.uk
+yieldmanager.com
+sogou.com
+globo.com
+softonic.com
+cnet.com
+livedoor.com
+directrev.com
+espn.go.com
+indiatimes.com
+wordpress.org
+weather.com
+pixnet.net
+google.com.sa
+clkmon.com
+reddit.com
+amazon.it
+google.com.eg
+booking.com
+google.nl
+douban.com
+slideshare.net
+google.com.ar
+badoo.com
+dailymail.co.uk
+google.co.th
+ask.fm
+wikia.com
+godaddy.com
+xinhuanet.com
+mediafire.com
+deviantart.com
+google.com.pk
+bankofamerica.com
+amazon.es
+blogfa.com
+nytimes.com
+4shared.com
+google.co.id
+youjizz.com
+amazonaws.com
+tube8.com
+kickass.to
+livejournal.com
+snapdo.com
+google.co.za
+vimeo.com
+wigetmedia.com
+yelp.com
+outbrain.com
+dropbox.com
+siteadvisor.com
+foxnews.com
+renren.com
+aliexpress.com
+walmart.com
+skype.com
+ilivid.com
+bizcoaching.info
+wikimedia.org
+flipkart.com
+zedo.com
+searchnu.com
+indeed.com
+leboncoin.fr
+liveinternet.ru
+google.co.ve
+56.com
+google.com.vn
+google.gr
+comcast.net
+torrentz.eu
+etsy.com
+orange.fr
+systweak.com
+onet.pl
+wellsfargo.com
+letv.com
+goodgamestudios.com
+secureserver.net
+allegro.pl
+themeforest.net
+tripadvisor.com
+web.de
+answers.com
+amazon.ca
+mozilla.org
+guardian.co.uk
+stumbleupon.com
+hardsextube.com
+espncricinfo.com
+gmx.net
+photobucket.com
+ehow.com
+rediff.com
+popads.net
+wikihow.com
+search-results.com
+fiverr.com
+google.com.ua
+files.wordpress.com
+onlineaway.net
+nbcnews.com
+google.com.co
+hootsuite.com
+4dsply.com
+google.ro
+sourceforge.net
+cnzz.com
+java.com
+hudong.com
+ucoz.ru
+tudou.com
+addthis.com
+google.com.ng
+soundcloud.com
+onclickads.net
+google.com.ph
+reference.com
+google.be
+wp.pl
+interbiz.me
+beeg.com
+rambler.ru
+sweetim.com
+aweber.com
+google.com.my
+pandora.com
+w3schools.com
+pengyou.com
+archive.org
+qvo6.com
+bet365.com
+etao.com
+lollipop-network.com
+qtrax.com
+google.se
+google.dz
+usatoday.com
+zillow.com
+goal.com
+avito.ru
+kaixin001.com
+yesky.com
+mobile01.com
+soufun.com
+tagged.com
+warriorforum.com
+statcounter.com
+google.com.pe
+libero.it
+thefreedictionary.com
+soku.com
+incredibar.com
+kaskus.co.id
+likes.com
+weebly.com
+iqiyi.com
+pch.com
+samsung.com
+linkbucks.com
+uploaded.net
+bild.de
+google.com.bd
+google.at
+webcrawler.com
+t-online.de
+iminent.com
+google.pt
+detik.com
+ganji.com
+milliyet.com.tr
+bleacherreport.com
+forbes.com
+twoo.com
+olx.in
+mercadolivre.com.br
+hurriyet.com.tr
+pof.com
+wsj.com
+hostgator.com
+naver.com
+putlocker.com
+varzesh3.com
+rutracker.org
+optmd.com
+youm7.com
+google.cl
+ikea.com
+4399.com
+salesforce.com
+scribd.com
+google.com.sg
+it168.com
+goodreads.com
+target.com
+xunlei.com
+hulu.com
+github.com
+hp.com
+buzzfeed.com
+google.ch
+youdao.com
+blogspot.com.es
+so.com
+ups.com
+extratorrent.com
+match.com
+seznam.cz
+naukri.com
+drtuber.com
+spiegel.de
+marca.com
+ign.com
+domaintools.com
+free.fr
+telegraph.co.uk
+mypcbackup.com
+kakaku.com
+imageshack.us
+reuters.com
+ndtv.com
+ig.com.br
+bestbuy.com
+glispa.com
+quikr.com
+deadlyblessing.com
+wix.com
+paipai.com
+ebay.com.au
+yandex.ua
+chinanews.com
+clixsense.com
+nih.gov
+aili.com
+zing.vn
+pchome.net
+webmd.com
+terra.com.br
+pixiv.net
+in.com
+csdn.net
+pcpop.com
+google.co.hu
+lnksr.com
+jobrapido.com
+inbox.com
+dianping.com
+gsmarena.com
+mlb.com
+clicksor.com
+hdfcbank.com
+acesse.com
+homedepot.com
+twitch.tv
+morefreecamsecrets.com
+groupon.com
+lnksdata.com
+google.cz
+usps.com
+xyxy.net
+att.com
+webs.com
+51job.com
+mashable.com
+yihaodian.com
+taringa.net
+fedex.com
+blogspot.co.uk
+ck101.com
+abcnews.go.com
+washingtonpost.com
+narod.ru
+china.com
+doubleclick.com
+cam4.com
+google.ie
+dangdang.com
+americanexpress.com
+disqus.com
+ixxx.com
+39.net
+isohunt.com
+php.net
+exoclick.com
+shutterstock.com
+dell.com
+google.ae
+histats.com
+outlook.com
+wordreference.com
+sahibinden.com
+126.com
+oyodomo.com
+gazeta.pl
+expedia.com
+kijiji.ca
+myfreecams.com
+capitalone.com
+moz.com
+qunar.com
+taleo.net
+google.co.il
+microsoftonline.com
+datasrvrs.com
+zippyshare.com
+google.no
+justdial.com
+2345.com
+adultfriendfinder.com
+shaadi.com
+mobile.de
+abril.com.br
+empowernetwork.com
+icicibank.com
+xe.com
+mailchimp.com
+fbcdn.net
+ccb.com
+huanqiu.com
+seesaa.net
+jimdo.com
+fucked-tube.com
+google.dk
+yellowpages.com
+constantcontact.com
+tinyurl.com
+mysearchresults.com
+friv.com
+ebay.it
+aizhan.com
+accuweather.com
+51buy.com
+snapdeal.com
+google.az
+pogo.com
+adultadworld.com
+nifty.com
+bitauto.com
+drudgereport.com
+bloomberg.com
+vnexpress.net
+eastmoney.com
+verizonwireless.com
+onlinesbi.com
+2ch.net
+speedtest.net
+largeporntube.com
+stackexchange.com
+roblox.com
+miniclip.com
+tmz.com
+google.fi
+ning.com
+monster.com
+mihanblog.com
+steampowered.com
+nuvid.com
+kooora.com
+ebay.in
+mp3skull.com
+blogspot.ru
+duowan.com
+blogspot.de
+fhserve.com
+moneycontrol.com
+pornerbros.com
+eazel.com
+daum.net
+lady8844.com
+rapidgator.net
+thesun.co.uk
+youtube-mp3.org
+v9.com
+disney.go.com
+porntube.com
+surveymonkey.com
+meetup.com
+ero-advertising.com
+bravotube.net
+appround.biz
+blogspot.it
+ctrip.com
+9gag.com
+odesk.com
+kinopoisk.ru
+trulia.com
+mercadolibre.com.ar
+repubblica.it
+hupu.com
+imesh.com
+searchfunmoods.com
+backpage.com
+latimes.com
+news.com.au
+gc.ca
+hubpages.com
+clickbank.com
+mapquest.com
+sweetpacks.com
+hypergames.net
+alimama.com
+cnblogs.com
+vancl.com
+bitly.com
+tokobagus.com
+webmoney.ru
+google.sk
+shopathome.com
+elpais.com
+oneindia.in
+codecanyon.net
+businessinsider.com
+blackhatworld.com
+farsnews.com
+spankwire.com
+mynet.com
+sape.ru
+bhaskar.com
+lenta.ru
+gutefrage.net
+nba.com
+feedly.com
+chaturbate.com
+elmundo.es
+ad6media.fr
+sberbank.ru
+lockyourhome.com
+kinox.to
+subito.it
+rbc.ru
+sfr.fr
+skyrock.com
+priceline.com
+jabong.com
+y8.com
+wunderground.com
+habrahabr.ru
+softpedia.com
+ancestry.com
+bluehost.com
+123rf.com
+lowes.com
+free-tv-video-online.me
+tabelog.com
+vehnix.com
+55bbs.com
+swagbucks.com
+speedanalysis.net
+virgilio.it
+peyvandha.ir
+infusionsoft.com
+newegg.com
+sulekha.com
+myspace.com
+yxlady.com
+haber7.com
+w3.org
+squidoo.com
+hotels.com
+oracle.com
+fatakat.com
+joomla.org
+qidian.com
+adbooth.net
+wretch.cc
+freelancer.com
+typepad.com
+foxsports.com
+allrecipes.com
+searchengines.ru
+babytree.com
+interia.pl
+xhamstercams.com
+verizon.com
+intoday.in
+sears.com
+okcupid.com
+kompas.com
+cj.com
+4tube.com
+chip.de
+force.com
+advertserve.com
+maktoob.com
+24h.com.vn
+foursquare.com
+cbsnews.com
+pornhublive.com
+xda-developers.com
+milanuncios.com
+retailmenot.com
+keezmovies.com
+nydailynews.com
+h2porn.com
+careerbuilder.com
+xing.com
+citibank.com
+linkwithin.com
+singlessalad.com
+altervista.org
+turbobit.net
+zoosk.com
+digg.com
+hespress.com
+bigpoint.com
+yourlust.com
+myntra.com
+issuu.com
+macys.com
+google.bg
+github.io
+filestube.com
+cmbchina.com
+irctc.co.in
+filehippo.com
+mop.com
+bodybuilding.com
+paidui.com
+zimbio.com
+panet.co.il
+mgid.com
+ya.ru
+probux.com
+haberturk.com
+persianblog.ir
+meituan.com
+mercadolibre.com.mx
+ppstream.com
+sunporno.com
+vodly.to
+forgeofempires.com
+elance.com
+adscale.de
+vipshop.com
+babycenter.com
+istockphoto.com
+commentcamarche.net
+upworthy.com
+download.com
+battle.net
+beva.com
+list-manage.com
+corriere.it
+noticias24.com
+ucoz.com
+porn.com
+google.lk
+lifehacker.com
+today.com
+chinabyte.com
+southwest.com
+ca.gov
+nudevista.com
+yandex.com.tr
+people.com
+docin.com
+norton.com
+perfectgirls.net
+engadget.com
+realtor.com
+techcrunch.com
+time.com
+indianrail.gov.in
+dtiblog.com
+way2sms.com
+foodnetwork.com
+subscene.com
+worldstarhiphop.com
+tabnak.ir
+aeriagames.com
+leagueoflegends.com
+51.la
+facenama.com
+sapo.pt
+bitshare.com
+gamespot.com
+cy-pr.com
+kankan.com
+google.co.nz
+liveleak.com
+video-one.com
+marktplaats.nl
+elwatannews.com
+roulettebotplus.com
+adserverplus.com
+akhbarak.net
+gumtree.com
+weheartit.com
+openadserving.com
+sporx.com
+mercadolibre.com.ve
+zendesk.com
+houzz.com
+asos.com
+letitbit.net
+quora.com
+yandex.kz
+mcafee.com
+ensonhaber.com
+gamefaqs.com
+vk.me
+avast.com
+website-unavailable.com
+22find.com
+admagnet.net
+rottentomatoes.com
+google.com.kw
+cloob.com
+nokia.com
+wetter.com
+taboola.com
+tenpay.com
+888.com
+flipora.com
+adhitprofits.com
+timeanddate.com
+as.com
+fanpop.com
+informer.com
+over-blog.com
+itau.com.br
+balagana.net
+ellechina.com
+avazutracking.net
+gap.com
+examiner.com
+vporn.com
+lenovo.com
+eonline.com
+r7.com
+majesticseo.com
+immobilienscout24.de
+google.kz
+goo.gl
+zwaar.net
+bankmellat.ir
+alphaporno.com
+whitepages.com
+viva.co.id
+rutor.org
+wiktionary.org
+intuit.com
+gismeteo.ru
+dantri.com.vn
+xbox.com
+myegy.com
+xtube.com
+masrawy.com
+urbandictionary.com
+agoda.com
+ebay.fr
+kickstarter.com
+6park.com
+metacafe.com
+yamahaonlinestore.com
+anysex.com
+azlyrics.com
+rt.com
+ibm.com
+nordstrom.com
+ezinearticles.com
+cnbc.com
+redtubelive.com
+clicksvenue.com
+tradus.com
+m2newmedia.com
+custhelp.com
+4chan.org
+kioskea.net
+yoka.com
+7k7k.com
+opensiteexplorer.org
+musica.com
+coupons.com
+cracked.com
+caixa.gov.br
+skysports.com
+kizi.com
+getresponse.com
+sky.com
+marketwatch.com
+google.com.ec
+cbslocal.com
+zhihu.com
+888poker.com
+digitalpoint.com
+blog.163.com
+rantsports.com
+videosexarchive.com
+who.is
+gogetlinks.net
+idnes.cz
+king.com
+say-move.org
+motherless.com
+npr.org
+legacy.com
+aljazeera.net
+barnesandnoble.com
+overstock.com
+drom.ru
+weather.gov
+gstatic.com
+amung.us
+traidnt.net
+ovh.net
+rtl.de
+howstuffworks.com
+digikala.com
+bannersbroker.com
+kohls.com
+google.com.do
+dealfish.co.th
+19lou.com
+ezpowerads.com
+lemonde.fr
+chexun.com
+imagebam.com
+viooz.co
+prothom-alo.com
+360doc.com
+m-w.com
+fanfiction.net
+semrush.com
+ci123.com
+plugrush.com
+cafemom.com
+mangareader.net
+haizhangs.com
+cdiscount.com
+zappos.com
+manta.com
+novinky.cz
+hi5.com
+pr-cy.ru
+movie4k.to
+patch.com
+alarabiya.net
+indiamart.com
+cartrailor.com
+almasryalyoum.com
+315che.com
+google.by
+tomshardware.com
+minecraft.net
+gulfup.com
+rr.com
+spotify.com
+airtel.in
+espnfc.com
+sanook.com
+ria.ru
+google.com.qa
+jquery.com
+pinshan.com
+onlylady.com
+pornoxo.com
+cookpad.com
+pagesjaunes.fr
+usmagazine.com
+google.lt
+nu.nl
+hm.com
+fixya.com
+theblaze.com
+cbssports.com
+eyny.com
+17173.com
+hc360.com
+cbs.com
+telegraaf.nl
+netlog.com
+slickdeals.net
+yobt.com
+certified-toolbar.com
+miercn.com
+aparat.com
+billdesk.com
+yandex.by
+888casino.com
+twitpic.com
+google.hr
+tubegalore.com
+dhgate.com
+makemytrip.com
+shop.com
+nike.com
+kayak.com
+fandango.com
+tutsplus.com
+gotomeeting.com
+shareasale.com
+mpnrs.com
+keepvid.com
+lequipe.fr
+namecheap.com
+doublepimp.com
+softigloo.com
+givemesport.com
+mtime.com
+letras.mus.br
+pole-emploi.fr
+biblegateway.com
+independent.co.uk
+e-hentai.org
+gumtree.com.au
+livestrong.com
+game321.com
+comcast.com
+clubpenguin.com
+rightmove.co.uk
+steamcommunity.com
+sockshare.com
+globalconsumersurvey.com
+rapidshare.com
+auto.ru
+staples.com
+anitube.se
+rozblog.com
+reliancenetconnect.co.in
+credit-agricole.fr
+exposedwebcams.com
+webalta.ru
+usbank.com
+google.com.ly
+pantip.com
+aftonbladet.se
+scoop.it
+mayoclinic.com
+evernote.com
+nyaa.eu
+livingsocial.com
+noaa.gov
+imagefap.com
+abchina.com
+google.rs
+amazon.in
+tnaflix.com
+xici.net
+united.com
+templatemonster.com
+deezer.com
+pixlr.com
+tradedoubler.com
+gumtree.co.za
+r10.net
+kongregate.com
+jeuxvideo.com
+gawker.com
+chewen.com
+r2games.com
+mayajo.com
+topix.com
+easyhits4u.com
+netteller.com
+ing.nl
+tripadvisor.co.uk
+udn.com
+cheezburger.com
+fotostrana.ru
+bbc.com
+behance.net
+lefigaro.fr
+nikkei.com
+fidelity.com
+baomihua.com
+fool.com
+nairaland.com
+sendspace.com
+woot.com
+travelocity.com
+shopclues.com
+sureonlinefind.com
+gizmodo.com
+hidemyass.com
+o2.pl
+clickbank.net
+fotolia.com
+opera.com
+sabah.com.tr
+n-mobile.net
+chacha.com
+autotrader.com
+anonym.to
+walmart.com.br
+yjc.ir
+autoscout24.de
+gobookee.net
+yaolan.com
+india.com
+tribalfusion.com
+gittigidiyor.com
+otto.de
+adclickxpress.com
+made-in-china.com
+ahram.org.eg
+asriran.com
+blackberry.com
+beytoote.com
+piriform.com
+ilmeteo.it
+att.net
+brainyquote.com
+last.fm
+directadvert.ru
+slate.com
+mangahere.com
+jalan.net
+blog.com
+tuvaro.com
+doc88.com
+mbc.net
+europa.eu
+onlinedown.net
+jcpenney.com
+myplaycity.com
+bahn.de
+laredoute.fr
+alexa.com
+flashx.tv
+51.com
+mail.com
+costco.com
+mirror.co.uk
+hubspot.com
+tf1.fr
+merdeka.com
+nypost.com
+1mall.com
+wmtransfer.com
+pcmag.com
+univision.com
+nationalgeographic.com
+sourtimes.org
+iciba.com
+petardas.com
+wmmail.ru
+light-dark.net
+ultimate-guitar.com
+koramgame.com
+megavod.fr
+smh.com.au
+ticketmaster.com
+admin5.com
+get-a-fuck-tonight.com
+eenadu.net
+argos.co.uk
+nipic.com
+google.iq
+alhea.com
+citrixonline.com
+girlsgogames.com
+fanatik.com.tr
+google.tn
+usaa.com
+earthlink.net
+ryanair.com
+city-data.com
+lloydstsb.co.uk
+pornsharia.com
+baixing.com
+all-free-download.com
+qianyan001.com
+hellporno.com
+pornmd.com
+conferenceplus.com
+docstoc.com
+christian-dogma.com
+dmoz.org
+perezhilton.com
+mega.co.nz
+zazzle.com
+echoroukonline.com
+ea.com
+yiqifa.com
+mysearchdial.com
+hotwire.com
+ninemsn.com.au
+tablica.pl
+brazzers.com
+americanas.com.br
+extremetube.com
+zynga.com
+buscape.com.br
+t-mobile.com
+portaldosites.com
+businessweek.com
+feedburner.com
+contenko.com
+homeshop18.com
+bmi.ir
+wwe.com
+adult-empire.com
+nfl.com
+globososo.com
+sfgate.com
+mmotraffic.com
+zalando.de
+warthunder.com
+icloud.com
+xiami.com
+newsmax.com
+solarmovie.so
+junglee.com
+discovercard.com
+hh.ru
+searchengineland.com
+labanquepostale.fr
+51cto.com
+fling.com
+liveperson.net
+sulit.com.ph
+tinypic.com
+meilishuo.com
+googleadservices.com
+boston.com
+chron.com
+breitbart.com
+youjizzlive.com
+commbank.com.au
+axisbank.com
+wired.com
+trialpay.com
+berniaga.com
+cnmo.com
+tunein.com
+hotfile.com
+dubizzle.com
+olx.com.br
+haxiu.com
+zulily.com
+infolinks.com
+yourgirlfriends.com
+logmein.com
+irs.gov
+noticiadeldia.com
+nbcsports.com
+holasearch.com
+indianexpress.com
+depositfiles.com
+elfagr.org
+himado.in
+lumosity.com
+mbank.com.pl
+primewire.ag
+dreamstime.com
+sootoo.com
+souq.com
+craigslist.ca
+zara.com
+groupon.it
+mangafox.me
+casino.com
+armorgames.com
+zanox.com
+finn.no
+qihoo.com
+toysrus.com
+airasia.com
+dafont.com
+tvmuse.eu
+pnc.com
+donanimhaber.com
+cnbeta.com
+prntscr.com
+cox.net
+bloglovin.com
+picmonkey.com
+zoho.com
+glassdoor.com
+myfitnesspal.com
+change.org
+aa.com
+playstation.com
+b1.org
+correios.com.br
+hindustantimes.com
+softlayer.com
+imagevenue.com
+windowsphone.com
+wikimapia.org
+transfermarkt.de
+dict.cc
+blocket.se
+lacaixa.es
+hilton.com
+mtv.com
+cbc.ca
+msn.ca
+box.com
+szn.cz
+haodf.com
+monsterindia.com
+okezone.com
+entertainment-factory.com
+linternaute.com
+break.com
+ustream.tv
+songspk.name
+bilibili.tv
+avira.com
+thehindu.com
+watchmygf.com
+google.co.ma
+nick.com
+sp.gov.br
+zeobit.com
+sprint.com
+khabaronline.ir
+magentocommerce.com
+hsbc.co.uk
+trafficholder.com
+gamestop.com
+cartoonnetwork.com
+fifa.com
+ebay.ca
+vatanim.com.tr
+qvc.com
+marriott.com
+eventbrite.com
+gi-akademie.com
+intel.com
+oschina.net
+dojki.com
+thechive.com
+viadeo.com
+walgreens.com
+leo.org
+statscrop.com
+brothersoft.com
+allocine.fr
+slutload.com
+google.com.gt
+santabanta.com
+stardoll.com
+polyvore.com
+focus.de
+duckduckgo.com
+funshion.com
+marieclairechina.com
+internethaber.com
+worldoftanks.ru
+1und1.de
+anyporn.com
+cars.com
+asg.to
+alice.it
+hongkiat.com
+bhphotovideo.com
+bdnews24.com
+sdo.com
+cerdas.com
+clarin.com
+victoriassecret.com
+instructables.com
+state.gov
+agame.com
+xiaomi.com
+adfoc.us
+telekom.com
+skycn.com
+orbitz.com
+nhl.com
+vistaprint.com
+trklnks.com
+basecamp.com
+hot-sex-tube.com
+incredibar-search.com
+qingdaonews.com
+sabq.org
+nasa.gov
+dx.com
+addmefast.com
+yepi.com
+xxx-ok.com
+sex.com
+food.com
+freeones.com
+tesco.com
+a10.com
+abc.net.au
+internetdownloadmanager.com
+seowhy.com
+otomoto.pl
+idealo.de
+laposte.net
+eroprofile.com
+bbb.org
+tiu.ru
+blogsky.com
+bigfishgames.com
+weiphone.com
+livescore.com
+tubepleasure.com
+jagran.com
+livestream.com
+stagram.com
+vine.co
+olx.com.pk
+edmunds.com
+banglanews24.com
+reverso.net
+stargames.at
+postimg.org
+overthumbs.com
+iteye.com
+yify-torrents.com
+forexfactory.com
+hefei.cc
+thefreecamsecret.com
+lanacion.com.ar
+jeu-a-telecharger.com
+spartoo.com
+adv-adserver.com
+asus.com
+91.com
+wimbledon.com
+yam.com
+grooveshark.com
+tdcanadatrust.com
+lovetime.com
+iltalehti.fi
+alnaddy.com
+bb.com.br
+tebyan.net
+redbox.com
+filecrop.com
+aliyun.com
+21cn.com
+news24.com
+infowars.com
+thetaoofbadass.com
+juegos.com
+p5w.net
+vg.no
+discovery.com
+gazzetta.it
+tvguide.com
+khabarfarsi.com
+bradesco.com.br
+autotrader.co.uk
+wetransfer.com
+jinti.com
+xhamsterhq.com
+appround.net
+lotour.com
+reverbnation.com
+thedailybeast.com
+vente-privee.com
+subscribe.ru
+marketgid.com
+super.cz
+jvzoo.com
+shine.com
+screencast.com
+picofile.com
+manoramaonline.com
+kbb.com
+seasonvar.ru
+android.com
+egrana.com.br
+ettoday.net
+webstatsdomain.net
+haberler.com
+vesti.ru
+fastpic.ru
+dpreview.com
+google.si
+ouedkniss.com
+crackle.com
+chefkoch.de
+mogujie.com
+brassring.com
+govome.com
+copyscape.com
+minecraftforum.net
+mit.edu
+cvs.com
+timesjobs.com
+ksl.com
+verizon.net
+direct.gov.uk
+miralinks.ru
+elheddaf.com
+stockphoto9.com
+ashemaletube.com
+dmm.com
+abckj123.com
+smzdm.com
+cox.com
+welt.de
+guyspy.com
+makeuseof.com
+tiscali.it
+178.com
+metrolyrics.com
+vsuch.com
+seosprint.net
+samanyoluhaber.com
+garanti.com.tr
+chicagotribune.com
+hinet.net
+kp.ru
+chomikuj.pl
+nk.pl
+webhostingtalk.com
+dnaindia.com
+programme-tv.net
+ievbz.com
+mysql.com
+perfectmoney.is
+liveundnackt.com
+flippa.com
+vevo.com
+jappy.de
+bidvertiser.com
+bankmandiri.co.id
+letour.fr
+yr.no
+suning.com
+nosub.tv
+delicious.com
+pornpoly.com
+echo.msk.ru
+coingeneration.com
+shutterfly.com
+royalbank.com
+techradar.com
+114la.com
+bizrate.com
+srvey.net
+heavy-r.com
+telexfree.com
+lego.com
+battlefield.com
+shahrekhabar.com
+tuenti.com
+bookmyshow.com
+ft.com
+prweb.com
+1337x.org
+networkedblogs.com
+pbskids.org
+aipai.com
+jang.com.pk
+dribbble.com
+ezdownloadpro.info
+gonzoxxxmovies.com
+aufeminin.com
+6pm.com
+azet.sk
+trustedoffer.com
+simplyhired.com
+adserverpub.com
+privalia.com
+bedbathandbeyond.com
+yyets.com
+verycd.com
+sbnation.com
+blogspot.nl
+ikariam.com
+sitepoint.com
+gazeta.ru
+tataindicom.com
+chekb.com
+literotica.com
+ah-me.com
+eztv.it
+onliner.by
+pptv.com
+macrumors.com
+xvideo-jp.com
+state.tx.us
+jamnews.ir
+etoro.com
+ny.gov
+searchenginewatch.com
+google.co.cr
+td.com
+ahrefs.com
+337.com
+klout.com
+ebay.es
+theverge.com
+kapook.com
+barclays.co.uk
+nuomi.com
+index-of-mp3s.com
+ohfreesex.com
+mts.ru
+instantcheckmate.com
+sport.es
+sitescout.com
+irr.ru
+tuniu.com
+startimes.com
+tvn24.pl
+kenh14.vn
+myvideo.de
+speedbit.com
+aljazeera.com
+pudelek.pl
+mmgp.ru
+empflix.com
+tigerdirect.com
+elegantthemes.com
+ted.com
+down1oads.com
+bancobrasil.com.br
+qip.ru
+fapdu.com
+softango.com
+ap.org
+meteofrance.com
+gentenocturna.com
+2ch-c.net
+orf.at
+maybank2u.com.my
+minecraftwiki.net
+tv.com
+orkut.com
+adp.com
+woorank.com
+imagetwist.com
+pastebin.com
+airtel.com
+ew.com
+forever21.com
+adam4adam.com
+voyages-sncf.com
+nextag.com
+usnews.com
+dinamalar.com
+virginmedia.com
+investopedia.com
+seekingalpha.com
+jumponhottie.com
+national-lottery.co.uk
+mobifiesta.com
+kapanlagi.com
+segundamano.es
+gfan.com
+xdating.com
+ynet.com
+medu.ir
+hsn.com
+newsru.com
+minus.com
+sitetalk.com
+aarp.org
+clickpaid.com
+panoramio.com
+webcamo.com
+yobt.tv
+slutfinder.com
+freelotto.com
+mudah.my
+toptenreviews.com
+caisse-epargne.fr
+wimp.com
+woothemes.com
+css-tricks.com
+coolmath-games.com
+tagu.com.ar
+sheknows.com
+advancedfileoptimizer.com
+drupal.org
+centrum.cz
+charter.net
+adxhosting.net
+squarespace.com
+trademe.co.nz
+sitesell.com
+birthrecods.com
+megashare.info
+freepornvs.com
+isna.ir
+ziddu.com
+airtelforum.com
+justin.tv
+01net.com
+ed.gov
+no-ip.com
+nikkansports.com
+smashingmagazine.com
+salon.com
+nmisr.com
+wanggou.com
+bayt.com
+codeproject.com
+downloadha.com
+local.com
+abola.pt
+delta-homes.com
+filmweb.pl
+gov.uk
+worldoftanks.eu
+ads-id.com
+sergey-mavrodi.com
+pornoid.com
+freakshare.com
+51fanli.com
+bankrate.com
+grindtv.com
+webmasterworld.com
+torrentz.in
+bwin.com
+watchtower.com
+payza.com
+anz.com
+vagalume.com.br
+ozon.ru
+tonicmovies.com
+arbeitsagentur.de
+graphicriver.net
+theweathernetwork.com
+samsclub.com
+tribunnews.com
+soldonsmart.com
+tut.by
+voila.fr
+doctissimo.fr
+sueddeutsche.de
+mamba.ru
+kmart.com
+abc.es
+manager.co.th
+spokeo.com
+apache.org
+tdbank.com
+asklaila.com
+admin5.net
+rtve.es
+ynet.co.il
+infospace.com
+yimg.com
+torcache.net
+zap2it.com
+smallseotools.com
+privatbank.ua
+nnm-club.ru
+payoneer.com
+bidorbuy.co.za
+islamweb.net
+juicyads.com
+vid2c.com
+dnsrsearch.com
+the-bux.net
+yaplakal.com
+ex.ua
+mtsindia.in
+reclameaqui.com.br
+postbank.de
+gogvo.com
+bearshare.net
+socialsex.com
+yebhi.com
+mktmobi.com
+dfiles.eu
+citibank.co.in
+gamersky.com
+kotaku.com
+teamviewer.com
+kwejk.pl
+hamariweb.com
+tom.com
+gayromeo.com
+sony.com
+westpac.com.au
+gtmetrix.com
+shorouknews.com
+xl.pt
+networksolutions.com
+500px.com
+ypmate.com
+indowebster.com
+sports.ru
+netshoes.com.br
+dfiles.ru
+cpasbien.me
+webgame.web.id
+tuto4pc.com
+poponclick.com
+complex.com
+sakshi.com
+infobae.com
+sify.com
+4pda.ru
+starsue.net
+newgrounds.com
+mehrnews.com
+depositphotos.com
+keek.com
+indeed.co.in
+stanford.edu
+hepsiburada.com
+20minutos.es
+paper.li
+prizee.com
+xlovecam.com
+criteo.com
+endlessmatches.com
+dyndns.org
+lightinthebox.com
+easyjet.com
+vice.com
+tiexue.net
+monstermarketplace.com
+mojang.com
+cams.com
+pingdom.com
+askmen.com
+list-manage1.com
+express.com.pk
+priceminister.com
+duba.com
+meinestadt.de
+mediatakeout.com
+terere.info
+streamate.com
+garmin.com
+a-telecharger.com
+vipzona.info
+coffetube.com
+discuz.net
+directv.com
+foreningssparbanken.se
+fatwallet.com
+mackolik.com
+megacinema.fr
+chess.com
+suntrust.com
+investing.com
+whois.com
+dummies.com
+yinyuetai.com
+mihandownload.com
+freapp.com
+theage.com.au
+audible.com
+hotelurbano.com.br
+vatgia.com
+wizard101.com
+ceneo.pl
+1ting.com
+meetic.fr
+cardekho.com
+tripadvisor.it
+dhl.com
+aibang.com
+asp.net
+toing.com.br
+zhubajie.com
+telecomitalia.it
+claro-search.com
+nickjr.com
+iconfinder.com
+mobile9.com
+cisco.com
+cpanel.net
+indiegogo.com
+egotastic.com
+hforcare.com
+pbs.org
+realestate.com.au
+abv.bg
+drugs.com
+bt.com
+wildberries.ru
+edreams.it
+statigr.am
+prestashop.com
+adxite.com
+birthdaypeoms.com
+exbii.com
+blogmura.com
+sciencedirect.com
+sanspo.com
+nextmedia.com
+tvoyauda4a.ru
+tangdou.com
+blackboard.com
+qiyou.com
+prezentacya.ru
+clicrbs.com.br
+wayfair.com
+xvideos-field.com
+national.com.au
+friendfeed.com
+plurk.com
+lolmake.com
+b9dm.com
+afkarnews.ir
+dhl.de
+championat.com
+moviefone.com
+popcash.net
+cliphunter.com
+sharebeast.com
+wowhead.com
+firstpost.com
+lloydstsb.com
+fazenda.gov.br
+lonelyplanet.com
+freenet.de
+justanswer.com
+qiwi.com
+shufuni.com
+drive2.ru
+slando.ua
+caribbeancom.com
+uniblue.com
+real.com
+addictinggames.com
+wnd.com
+col3negoriginal.org
+loltrk.com
+videodownloadconverter.com
+google.lv
+seriesyonkis.com
+ryushare.com
+s1979.com
+cheapoair.com
+submarino.com.br
+topface.com
+hotelscombined.com
+whatismyipaddress.com
+z6.com
+sozcu.com.tr
+sonymobile.com
+planetminecraft.com
+optimum.net
+google.com.pr
+mthai.com
+onlinecreditcenter6.com
+tharunaya.co.uk
+sfimg.com
+natwest.com
+zergnet.com
+alotporn.com
+urbanspoon.com
+punishtube.com
+proboards.com
+betfair.com
+iltasanomat.fi
+ssisurveys.com
+harvard.edu
+blic.rs
+clicksia.com
+skillpages.com
+mobilewap.com
+fiducia.de
+torntvz.org
+leparisien.fr
+anjuke.com
+rabobank.nl
+sport.pl
+schwab.com
+buenastareas.com
+befuck.com
+smart-search.com
+ivi.ru
+dvdvideosoft.com
+ubi.com
+makepolo.com
+1and1.com
+pcworld.com
+caf.fr
+fnb.co.za
+vanguardngr.com
+floozycity.com
+ubuntu.com
+my-link.pro
+centurylink.com
+slashdot.org
+mirrorcreator.com
+rutube.ru
+tubeplus.me
+kicker.de
+unibet.com
+pornyaz.com
+learntotradethemarket.com
+tokyo-porn-tube.com
+luvcow.com
+i.ua
+ole.com.ar
+redfin.com
+cnki.net
+2shared.com
+infibeam.com
+zdnet.com
+fishki.net
+ukr.net
+jiameng.com
+utorrent.com
+elkhabar.com
+anime44.com
+societegenerale.fr
+livememe.com
+startertv.fr
+pingomatic.com
+indeed.co.uk
+dpstream.net
+mundodeportivo.com
+gravatar.com
+ip138.com
+yandex.net
+barbie.com
+wattpad.com
+dzwww.com
+technorati.com
+meishichina.com
+russianpost.ru
+kboing.com.br
+lzjl.com
+newsnow.co.uk
+dw.de
+inetglobal.com
+tripadvisor.in
+ashleyrnadison.com
+rapgenius.com
+xuite.net
+nowvideo.eu
+search.us.com
+usagc.org
+santander.co.uk
+99acres.com
+bigcartel.com
+haivl.com
+jsfiddle.net
+io9.com
+lg.com
+veoh.com
+dafiti.com.br
+heise.de
+wikispaces.com
+google.com.bo
+skyscrapercity.com
+zaobao.com
+pirateproxy.net
+muyzorras.com
+entrepreneur.com
+sxc.hu
+superuser.com
+jb51.net
+bitsnoop.com
+index.hu
+tubexclips.com
+symantec.com
+sedo.com
+gongchang.com
+newsmth.net
+srclick.ru
+bomnegocio.com
+omegle.com
+sweetpacks-search.com
+000webhost.com
+rencontreshard.com
+jumei.com
+acfun.tv
+celebuzz.com
+el-balad.com
+wajam.com
+zoopla.co.uk
+sc4888.com
+mobileaziende.it
+officialsurvey.org
+googleapis.com
+jobsdb.com
+google.com.sv
+freejobalert.com
+walla.co.il
+hollywoodreporter.com
+inc.com
+bbandt.com
+williamhill.com
+jeu.info
+vrbo.com
+arabseed.com
+spielaffe.de
+wykop.pl
+name.com
+web-opinions.com
+ehowenespanol.com
+uuzu.com
+cafepress.com
+beeline.ru
+searchenginejournal.com
+webex.com
+zerohedge.com
+cityads.ru
+columbia.edu
+jia.com
+tistory.com
+100bestbuy.com
+realitykings.com
+shopify.com
+gametop.com
+eharmony.com
+ngoisao.net
+angieslist.com
+grotal.com
+manhunt.net
+adslgate.com
+demotywatory.pl
+enfemenino.com
+yallakora.com
+careesma.in
+draugiem.lv
+greatandhra.com
+lifescript.com
+androidcentral.com
+wiley.com
+alot.com
+10010.com
+next.co.uk
+115.com
+omgpm.com
+mycalendarbook.com
+playxn.com
+niksalehi.com
+serviporno.com
+poste.it
+kimiss.com
+bearshare.com
+clickpoint.com
+seek.com.au
+bab.la
+ads8.com
+viewster.com
+ideacellular.com
+tympanus.net
+wwwblogto.com
+tblop.com
+elong.com
+funnyordie.com
+radikal.ru
+rk.com
+alarab.net
+willhaben.at
+beyond.com
+punchng.com
+viglink.com
+microsoftstore.com
+tripleclicks.com
+m1905.com
+ofreegames.com
+s2d6.com
+360buy.com
+rakuten.com
+evite.com
+kompasiana.com
+dailycaller.com
+holidaycheck.de
+imvu.com
+nate.com
+fnac.com
+htc.com
+savenkeep.com
+alfabank.ru
+zaycev.net
+vidtomp3.com
+eluniversal.com.mx
+theatlantic.com
+gamigo.de
+lolking.net
+wer-kennt-wen.de
+stern.de
+sport1.de
+goalunited.org
+discogs.com
+whirlpool.net.au
+savefrom.net
+eurosport.fr
+juegosjuegos.com
+open24news.tv
+sinaapp.com
+fuq.com
+index.hr
+realpopbid.com
+rollingstone.com
+globaltestmarket.com
+seopult.ru
+wumii.com
+ford.com
+cabelas.com
+securepaynet.net
+zhibo8.cc
+jiji.com
+gezinti.com
+meb.gov.tr
+classifiedads.com
+kitco.com
+incredimail.com
+esmas.com
+soccerway.com
+rivals.com
+prezi.com
+shopping.com
+superjob.ru
+chinaacc.com
+amoureux.com
+mysmartprice.com
+eleconomista.es
+mercola.com
+imlive.com
+teacup.com
+modelmayhem.com
+nic.ru
+brazzersnetwork.com
+everything.org.uk
+bhg.com
+longhoo.net
+superpages.com
+tny.cz
+yourfilezone.com
+tuan800.com
+streev.com
+sedty.com
+boxofficemojo.com
+hollyscoop.com
+safecart.com
+almogaz.com
+cashnhits.com
+wetplace.com
+freepik.com
+rarbg.com
+xxxbunker.com
+prchecker.info
+halifax-online.co.uk
+trafficfactory.biz
+telecinco.es
+searchtermresults.com
+unam.mx
+akhbar-elwatan.com
+lynda.com
+yougetlaid.com
+smart.com.au
+advfn.com
+unicredit.it
+zomato.com
+flirt.com
+netease.com
+bnpparibas.net
+elcomercio.pe
+mathrubhumi.com
+koyotesoft.com
+filmix.net
+xnxxhdtube.com
+ennaharonline.com
+junbi-tracker.com
+buzzdock.com
+emirates.com
+vivanuncios.com.mx
+infojobs.net
+smi2.ru
+lotterypost.com
+bandcamp.com
+ekstrabladet.dk
+nownews.com
+bc.vc
+google.com.af
+ulmart.ru
+estadao.com.br
+politico.com
+kl688.com
+resellerclub.com
+whois.net
+seobuilding.ru
+t411.me
+googlesyndication.com
+delfi.lt
+eqla3.com
+ali213.net
+fanpage.it
+uptobox.com
+google.jo
+cncn.com
+sme.sk
+kinozal.tv
+ceconline.com
+billboard.com
+citi.com
+naughtyamerica.com
+classmates.com
+coursera.org
+pingan.com
+voanews.com
+tankionline.com
+jetblue.com
+spainshtranslation.com
+ebookbrowse.com
+met-art.com
+megafon.ru
+quibids.com
+smartfren.com
+cleartrip.com
+pixmania.com
+vivastreet.com
+thegfnetwork.com
+paytm.com
+meinsextagebuch.net
+memecenter.com
+ixbt.com
+dagbladet.no
+basecamphq.com
+chinatimes.com
+bubblews.com
+xtool.ru
+opodo.co.uk
+hattrick.org
+zopim.com
+aol.co.uk
+gazzetta.gr
+18andabused.com
+mcssl.com
+economist.com
+zeit.de
+google.com.uy
+pinoy-ako.info
+lazada.co.id
+filgoal.com
+rozetka.com.ua
+almesryoon.com
+csmonitor.com
+bizjournals.com
+rackspace.com
+webgozar.com
+opencart.com
+mediaplex.com
+deutsche-bank.de
+similarsites.com
+sotmarket.ru
+chatzum.com
+huffingtonpost.co.uk
+carwale.com
+memez.com
+hostmonster.com
+muzofon.com
+elephanttube.com
+crunchbase.com
+imhonet.ru
+lusongsong.com
+filmesonlinegratis.net
+giaoduc.net.vn
+manhub.com
+tatadocomo.com
+realitatea.net
+freemp3x.com
+freemail.hu
+ganool.com
+feedreader.com
+sportsdirect.com
+videolan.org
+watchseries.lt
+rotapost.ru
+nwolb.com
+searchquotes.com
+kaspersky.com
+go2cloud.org
+grepolis.com
+profit-partner.ru
+articlesbase.com
+dns-shop.ru
+radikal.com.tr
+justjared.com
+lancenet.com.br
+mangapanda.com
+theglobeandmail.com
+ecollege.com
+myanimelist.net
+fotomac.com.tr
+imanhua.com
+travelzoo.com
+jjwxc.net
+q.gs
+naaptol.com
+sambaporno.com
+macrojuegos.com
+ooo-sex.com
+fab.com
+roflzone.com
+searchcompletion.com
+jezebel.com
+bizdec.ru
+torrentino.com
+multitran.ru
+tune-up.com
+sparkpeople.com
+desi-tashan.com
+mashreghnews.ir
+talktalk.co.uk
+hinkhoj.com
+20minutes.fr
+sulia.com
+icims.com
+dizi-mag.com
+webaslan.com
+en.wordpress.com
+funmoods.com
+softgozar.com
+starwoodhotels.com
+studiopress.com
+click.in
+meetcheap.com
+angel-live.com
+beforeitsnews.com
+trello.com
+icontact.com
+prlog.org
+incentria.com
+bouyguestelecom.fr
+dstv.com
+arstechnica.com
+diigo.com
+consumers-research.com
+metaffiliation.com
+telekom.de
+izlesene.com
+newsit.gr
+fuckingawesome.com
+osym.gov.tr
+svyaznoy.ru
+watchfreemovies.ch
+gumtree.pl
+sportbox.ru
+reserverunessai.com
+hsbc.com.hk
+cricbuzz.com
+djelfa.info
+nouvelobs.com
+aruba.it
+homes.com
+allezleslions.com
+orkut.com.br
+aionfreetoplay.com
+academia.edu
+consumerreports.org
+ilsole24ore.com
+sephora.com
+lds.org
+vmall.com
+ultimasnoticias.com.ve
+healthgrades.com
+imgbox.com
+dlsite.com
+whitesmoke.com
+thenextweb.com
+qire123.com
+peeplo.com
+chitika.com
+alwafd.org
+phonearena.com
+ovh.com
+tusfiles.net
+18schoolgirlz.com
+bongacams.com
+home.pl
+footmercato.net
+sprashivai.ru
+megafilmeshd.net
+premium-display.com
+clickey.com
+tokyo-tube.com
+watch32.com
+pornolab.net
+timewarnercable.com
+naturalnews.com
+afimet.com
+telderi.ru
+ioffer.com
+lapatilla.com
+livetv.ru
+cloudflare.com
+lupoporno.com
+nhaccuatui.com
+thepostgame.com
+ipage.com
+banesconline.com
+cdc.gov
+adonweb.ru
+zone-telechargement.com
+intellicast.com
+uloz.to
+pikabu.ru
+megogo.net
+wenxuecity.com
+xml-sitemaps.com
+webdunia.com
+justhost.com
+starbucks.com
+wargaming.net
+hugedomains.com
+magicbricks.com
+gigporno.com
+rikunabi.com
+51auto.com
+warriorplus.com
+gudvin.tv
+bigmir.net
+ansa.it
+standardbank.co.za
+toshiba.com
+xinnet.com
+geico.com
+funnyjunk.com
+affaritaliani.it
+cityheaven.net
+tubewolf.com
+google.org
+ad.nl
+tutorialspoint.com
+uidai.gov.in
+everydayhealth.com
+jzip.com
+lolspotsarticles.com
+rueducommerce.fr
+lvmama.com
+roboform.com
+zoznam.sk
+livesmi.com
+die-boersenformel.com
+watchcartoononline.com
+abclocal.go.com
+techrepublic.com
+just-fuck.com
+camster.com
+akairan.com
+yeslibertin.com
+abc.go.com
+searchtherightwords.com
+scotiabank.com
+justclick.ru
+douguo.com
+discover.com
+britishairways.com
+mobafire.com
+gi-akademie.ning.com
+desirulez.net
+qiushibaike.com
+moonbasa.com
+all.biz
+springer.com
+emai.com
+deadspin.com
+hulkshare.com
+fast-torrent.ru
+oriflame.com
+imgchili.net
+mega-juegos.mx
+gyazo.com
+persianv.com
+adk2.com
+ingbank.pl
+nationalconsumercenter.com
+xxxkinky.com
+mywot.com
+gaymaletube.com
+1tv.ru
+manutd.com
+merchantcircle.com
+canalblog.com
+capitalone360.com
+tlbb8.com
+softonic.fr
+ccavenue.com
+tyroodr.com
+exam8.com
+allmusic.com
+stubhub.com
+arcor.de
+yolasite.com
+haraj.com.sa
+mypopup.ir
+memurlar.net
+smugmug.com
+filefactory.com
+fantasti.cc
+bokra.net
+goarticles.com
+moneysavingexpert.com
+donga.com
+lastminute.com
+xkcd.com
+sou300.com
+magnovideo.com
+inquirer.net
+phoenix.edu
+videogenesis.com
+thestar.com
+tripadvisor.es
+blankrefer.com
+yle.fi
+beamtele.com
+oanda.com
+iheart.com
+google.co.tz
+stargazete.com
+bossip.com
+defaultsear.ch
+thaiseoboard.com
+qinbei.com
+ninisite.com
+j.gs
+nos.nl
+qualtrics.com
+kommersant.ru
+urban-rivals.com
+computerbild.de
+fararu.com
+menshealth.com
+jobstreet.com
+rbcroyalbank.com
+inmotionhosting.com
+surveyrouter.com
+kankanews.com
+aol.de
+bol.com
+datpiff.com
+mplife.com
+sale-fire.com
+inbox.lv
+offeratum.com
+pandora.tv
+eltiempo.com
+indiarailinfo.com
+solidtrustpay.com
+warthunder.ru
+novamov.com
+folkd.com
+envato.com
+wetpaint.com
+tempo.co
+howtogeek.com
+foundationapi.com
+care2.com
+bendibao.com
+mazika2day.com
+asda.com
+nowvideo.ch
+hiapk.com
+17u.com
+tutu.ru
+ncdownloader.com
+warez-bb.org
+jsoftj.com
+xmarks.com
+36kr.com
+runetki.com
+quoka.de
+heureka.cz
+monografias.com
+zhenai.com
+4porn.com
+antena3.com
+lintas.me
+seroundtable.com
+e1.ru
+berkeley.edu
+officedepot.com
+myflorida.com
+parispornmovies.com
+uniqlo.com
+topky.sk
+lumovies.com
+buysellads.com
+stirileprotv.ro
+scottrade.com
+mmtrends.net
+wholesale-dress.net
+metacritic.com
+pichunter.com
+moneybookers.com
+idealista.com
+buzzle.com
+rcom.co.in
+weightwatchers.com
+itv.com
+inilah.com
+vic.gov.au
+prom.ua
+with2.net
+doodle.com
+trafficbroker.com
+h33t.com
+avaaz.org
+maultalk.com
+bmo.com
+nerdbux.com
+abnamro.nl
+didigames.com
+pornorama.com
+forumotion.com
+woman.ru
+thaivisa.com
+lexpress.fr
+forumcommunity.net
+regions.com
+sf-express.com
+donkeymails.com
+clubic.com
+aucfan.com
+enterfactory.com
+yandex.com
+iherb.com
+in.gr
+olx.pt
+fbdownloader.com
+autoscout24.it
+siteground.com
+psicofxp.com
+persiangig.com
+metroer.com
+tokopedia.com
+seccam.info
+sport-express.ru
+vodafone.it
+blekko.com
+entekhab.ir
+expressen.se
+zalando.fr
+hawaaworld.com
+freeonlinegames.com
+google.com.lb
+ab-in-den-urlaub.de
+android4tw.com
+alriyadh.com
+drugstore.com
+iobit.com
+rei.com
+racing-games.com
+mommyfucktube.com
+pideo.net
+gogoanime.com
+avaxho.me
+christianmingle.com
+activesearchresults.com
+trendsonline.biz
+planetsuzy.org
+rubias19.com
+cleverbridge.com
+jeevansathi.com
+washingtontimes.com
+lcl.fr
+98ia.com
+mercadolibre.com.co
+n-tv.de
+divyabhaskar.co.in
+airbnb.com
+mybrowserbar.com
+travian.com
+autoblog.com
+blesk.cz
+playboy.com
+p30download.com
+pazienti.net
+uast.ac.ir
+logsoku.com
+zedge.net
+creditmutuel.fr
+absa.co.za
+milliyet.tv
+jiathis.com
+liverpoolfc.tv
+dospy.com
+calameo.com
+netsuite.com
+angelfire.com
+snagajob.com
+hollywoodlife.com
+techtudo.com.br
+payserve.com
+portalnet.cl
+worldadult-videos.info
+indianpornvideos.com
+france24.com
+discuss.com.hk
+theplanet.com
+advego.ru
+eltiempo.es
+55tuan.com
+snopes.com
+startnow.com
+tucarro.com
+skyscanner.net
+wchonline.com
+gaadi.com
+lindaikeji.blogspot.com
+keywordblocks.com
+apsense.com
+avangate.com
+gandul.info
+google.com.gh
+mybigcommerce.com
+homeaway.com
+wikitravel.org
+etxt.ru
+zerx.ru
+sidereel.com
+edreams.es
+india-forums.com
+infonews.com
+zoominfo.com
+stylebistro.com
+dominos.com
+591hx.com
+authorize.net
+61baobao.com
+digitalspy.co.uk
+godvine.com
+rednowtube.com
+appbank.net
+woozgo.fr
+expireddomains.net
+my-uq.com
+peliculasyonkis.com
+forumfree.it
+shangdu.com
+startmyripple.com
+hottube.me
+members.webs.com
+blick.ch
+google.cm
+tomtom.com
+rzd.ru
+opensooq.com
+pizzahut.com
+marksandspencer.com
+filenuke.com
+filelist.ro
+akharinnews.com
+etrade.com
+planetromeo.com
+wpbeginner.com
+bancomercantil.com
+pastdate.com
+webutation.net
+mywebgrocer.com
+mobile.ir
+seemorgh.com
+nhs.uk
+google.ba
+ileehoo.com
+seobook.com
+wetteronline.de
+happy-porn.com
+theonion.com
+webnode.com
+svaiza.com
+newsbomb.gr
+t88u.com
+tsn.ca
+unity3d.com
+nseindia.com
+juegosdiarios.com
+genieo.com
+kelkoo.com
+shabdkosh.com
+tecmundo.com.br
+chinaunix.net
+goo-net.com
+asana.com
+hdporn.in
+virtapay.com
+jobdiagnosis.com
+guokr.com
+clickpoint.it
+3dmgame.com
+ashleymadison.com
+utsprofitads.com
+google.ee
+oyunskor.com
+metro.co.uk
+ebaumsworld.com
+realsimple.com
+3file.info
+xcams.com
+cyberforum.ru
+babble.com
+lidl.de
+pixer.mobi
+yell.com
+alnilin.com
+lurkmore.to
+olx.co.za
+eorezo.com
+baby.ru
+redporntube.com
+extabit.com
+wayn.com
+gaana.com
+islamicfinder.org
+venturebeat.com
+played.to
+alrakoba.net
+mouthshut.com
+banquepopulaire.fr
+dasoertliche.de
+1stwebdesigner.com
+tam.com.br
+nature.com
+camfrog.com
+philly.com
+zemtv.com
+oprah.com
+wmaraci.com
+ruvr.ru
+gsn.com
+acrobat.com
+depositfiles.org
+smartresponder.ru
+huxiu.com
+porn-wanted.com
+tripadvisor.fr
+3366.com
+ranker.com
+cibc.com
+trend.az
+whatsapp.com
+07073.com
+netload.in
+channel4.com
+yatra.com
+elconfidencial.com
+labnol.org
+google.co.ke
+disneylatino.com
+pconverter.com
+cqnews.net
+blog.co.uk
+immowelt.de
+crunchyroll.com
+gamesgames.com
+protothema.gr
+vmoptions.com
+go2jump.org
+psu.edu
+sanjesh.org
+sportingnews.com
+televisionfanatic.com
+fansshare.com
+xcams4u.com
+madthumbs.com
+ebates.com
+eromon.net
+copyblogger.com
+flirt4free.com
+gaytube.com
+notdoppler.com
+allmyvideos.net
+cam4.de.com
+chosun.com
+adme.ru
+codeplex.com
+jumia.com.ng
+digitaltrends.com
+b92.net
+miniinthebox.com
+radaronline.com
+hujiang.com
+gardenweb.com
+pizap.com
+iptorrents.com
+yuku.com
+mega-giochi.it
+nrk.no
+99designs.com
+uscis.gov
+lostfilm.tv
+mileroticos.com
+republika.co.id
+sharethis.com
+samplicio.us
+1saleaday.com
+vonelo.com
+oyunmoyun.com
+flightradar24.com
+geo.tv
+nexusmods.com
+blogspot.fi
+directtrack.com
+media.net
+bigresource.com
+free-lance.ru
+loveplanet.ru
+ilfattoquotidiano.it
+coolmovs.com
+mango.com
+nj.com
+magazineluiza.com.br
+datehookup.com
+registro.br
+debenhams.com
+jqueryui.com
+palcomp3.com
+opensubtitles.org
+socialmediatoday.com
+allgameshome.com
+pricegrabber.com
+lufthansa.com
+ip-adress.com
+business-standard.com
+games.com
+zaman.com.tr
+jagranjosh.com
+mint.com
+gorillavid.in
+google.com.om
+blogbigtime.com
+korrespondent.net
+nymag.com
+proporn.com
+ycasmd.info
+persiantools.com
+torrenthound.com
+bestsexo.com
+alwatanvoice.com
+jahannews.com
+bluewin.ch
+sap.com
+rzb.ir
+myorderbox.com
+dealsandsavings.net
+goldenline.pl
+stuff.co.nz
+opentable.com
+4738.com
+freshersworld.com
+state.pa.us
+lavanguardia.com
+mob.org
+vodafone.in
+blogdetik.com
+888.it
+passportindia.gov.in
+ssa.gov
+desitvforum.net
+rajasthan.gov.in
+zonealarm.com
+locaweb.com.br
+logme.in
+fetlife.com
+lyricsfreak.com
+te3p.com
+hmrc.gov.uk
+bravoerotica.com
+kolesa.kz
+vinescope.com
+shoplocal.com
+mydrivers.com
+bigideamastermind.com
+uncoverthenet.com
+ragecomic.com
+yodobashi.com
+titan24.com
+nocoty.pl
+turkishairlines.com
+liputan6.com
+3suisses.fr
+cancan.ro
+apetube.com
+kurir-info.rs
+wow.com
+myblogguest.com
+wp.com
+tre.it
+livrariasaraiva.com.br
+ubuntuforums.org
+serverfault.com
+princeton.edu
+experienceproject.com
+ero-video.net
+west263.com
+nguoiduatin.vn
+findthebest.com
+iol.pt
+hotukdeals.com
+filmifullizle.com
+blog.hu
+dailyfinance.com
+bigxvideos.com
+adreactor.com
+fmworld.net
+fumu.com
+ntv.ru
+poringa.net
+syosetu.com
+giantsextube.com
+uuu9.com
+babosas.com
+square-enix.com
+bankia.es
+freedownloadmanager.org
+add-anime.net
+tuttomercatoweb.com
+192.com
+freekaamaal.com
+youngpornvideos.com
+nbc.com
+jne.co.id
+fobshanghai.com
+johnlewis.com
+mvideo.ru
+bhinneka.com
+gooddrama.net
+lobstertube.com
+ovguide.com
+joemonster.org
+editor.wix.com
+wechat.com
+locanto.in
+video2mp3.net
+couchsurfing.org
+tchibo.de
+rol.ro
+toroporno.com
+backlinkwatch.com
+greatergood.com
+smartaddressbar.com
+getgoodlinks.ru
+fitbit.com
+elcorteingles.es
+up2c.com
+rg.ru
+ftalk.com
+apartmenttherapy.com
+blogspot.hu
+e-rewards.com
+weloveshopping.com
+swtor.com
+abs-cbnnews.com
+webpagetest.org
+ricardo.ch
+ghatreh.com
+ibps.in
+moneymakergroup.com
+exist.ru
+kakprosto.ru
+gradeuptube.com
+lastampa.it
+medicinenet.com
+theknot.com
+yale.edu
+okazii.ro
+wa.gov
+gmhuowan.com
+cnhubei.com
+dickssportinggoods.com
+instaforex.com
+zdf.de
+getpocket.com
+takungpao.com
+junkmail.co.za
+tripwiremagazine.com
+popcap.com
+bangbros.com
+shtyle.fm
+jungle.gr
+apserver.net
+mzamin.com
+google.lu
+squarebux.com
+bollywoodhungama.com
+milfmovs.com
+softonic.it
+cyberciti.biz
+scout.com
+teensnow.com
+pornper.com
+torrentreactor.net
+smotri.com
+startpage.com
+climatempo.com.br
+bigrock.in
+kajabi.com
+imgchili.com
+dogpile.com
+thestreet.com
+sport24.gr
+tophotels.ru
+bbva.es
+perfectmoney.com
+cashmachines2.com
+skroutz.gr
+logitech.com
+seriescoco.com
+fastclick.com
+cambridge.org
+fark.com
+krypt.com
+indiangilma.com
+safe-swaps.com
+trenitalia.com
+flycell.com.mx
+livefreefun.com
+ourtoolbar.com
+anandtech.com
+neimanmarcus.com
+lelong.com.my
+pulscen.ru
+paginegialle.it
+intelius.com
+orange.pl
+aktuality.sk
+webgame.in.th
+runescape.com
+rocketnews24.com
+lineadirecta.com
+origin.com
+newsbeast.gr
+justhookup.com
+lifenews.ru
+sitemeter.com
+isbank.com.tr
+commerzbanking.de
+marthastewart.com
+ntvmsnbc.com
+seloger.com
+vend-o.com
+almanar.com.lb
+sifyitest.com
+taojindi.com
+mylife.com
+talkfusion.com
+hichina.com
+paruvendu.fr
+admcsport.com
+faz.net
+narutoget.com
+wufoo.com
+feedads-srv.com
+gophoto.it
+tgju.org
+dynamicdrive.com
+centurylink.net
+ngs.ru
+anyap.info
+dailykos.com
+malaysiakini.com
+uefa.com
+socialmediaexaminer.com
+peperonity.de
+support.wordpress.com
+hola.com
+readmanga.eu
+jstv.com
+irib.ir
+bookingbuddy.com
+computerhope.com
+ilovemobi.com
+pinkrod.com
+videobash.com
+alfemminile.com
+tu.tv
+utro.ru
+urbanoutfitters.com
+autozone.com
+gilt.com
+atpworldtour.com
+goibibo.com
+propellerpops.com
+cornell.edu
+flashscore.com
+babyblog.ru
+sport-fm.gr
+viamichelin.fr
+newyorker.com
+tagesschau.de
+guiamais.com.br
+jeux.fr
+pontofrio.com.br
+dm5.com
+ss.lv
+mirtesen.ru
+money.pl
+tlbsearch.com
+usembassy.gov
+cineblog01.net
+nur.kz
+hotnewhiphop.com
+mp3sheriff.com
+games.co.id
+deviantclip.com
+list.ru
+xitek.com
+netvibes.com
+24sata.hr
+usda.gov
+zerofreeporn.com
+tvb.com
+decolar.com
+worldfree4u.com
+dzone.com
+wikiquote.org
+techtunes.com.bd
+pornup.me
+blogutils.net
+yupoo.com
+peoplesmart.com
+kijiji.it
+usairways.com
+betfred.com
+ow.ly
+nsw.gov.au
+mci.ir
+iranecar.com
+wisegeek.com
+gocomics.com
+bramjnet.com
+bit.ly
+timesofindia.com
+xingcloud.com
+tfl.gov.uk
+derstandard.at
+icq.com
+orange.co.uk
+pornokopilka.info
+88db.com
+house365.com
+collegehumor.com
+gfxtra.com
+borsapernegati.com
+surveygifters.com
+ec21.com
+seoprofiler.com
+goldporntube.com
+tvtropes.org
+techtarget.com
+juno.com
+visual.ly
+dardarkom.com
+showup.tv
+three.co.uk
+shopstyle.com
+penguinvids.com
+trainenquiry.com
+soha.vn
+fengniao.com
+carschina.com
+500wan.com
+perfectinter.net
+elog-ch.com
+thetoptens.com
+1616.net
+nationwide.co.uk
+myhabit.com
+kinomaniak.tv
+googlecode.com
+kddi.com
+wyborcza.biz
+gtbank.com
+zigwheels.com
+lepoint.fr
+formula1.com
+baomoi.com
+apa.az
+movie2k.to
+irpopup.ir
+nps.gov
+lachainemeteo.com
+x-art.com
+bakecaincontrii.com
+longtailvideo.com
+yengo.com
+listentoyoutube.com
+dreamhost.com
+cari.com.my
+sergeymavrodi.com
+boursorama.com
+extra.com.br
+msnbc.com
+uwants.com
+utexas.edu
+minijuegos.com
+mumayi.com
+skorer.tv
+ddmap.com
+ebog.com
+artlebedev.ru
+venere.com
+academic.ru
+mako.co.il
+nabble.com
+autodesk.com
+vertitechnologygroup.com
+leaseweb.com
+yoox.com
+papajohns.com
+unmillondeutilidades.com
+webmasters.ru
+seoclerks.com
+yootheme.com
+google.com.py
+beemp3.com
+yepme.com
+alef.ir
+gotowebinar.com
+onec.dz
+bonprix.de
+landsend.com
+libertatea.ro
+timeout.com
+appnexus.com
+uproxx.com
+alohatube.com
+citilink.ru
+askubuntu.com
+freemake.com
+rockettheme.com
+tupaki.com
+53.com
+tune.pk
+standardchartered.com
+video-i365.com
+knowyourmeme.com
+gofeminin.de
+vmware.com
+vbox7.com
+webfail.com
+onewebsearch.com
+xnxxmovies.com
+blogspot.hk
+hgtv.com
+findagrave.com
+yoast.com
+audiopoisk.com
+sexytube.me
+centerblog.net
+webpronews.com
+prnewswire.com
+vietnamnet.vn
+groupon.co.in
+bom.gov.au
+loxblog.com
+llnw.com
+jcrew.com
+carsensor.net
+aukro.cz
+zoomby.ru
+wallstcheatsheet.com
+17k.com
+secondlife.com
+marmiton.org
+zorpia.com
+searchya.com
+rtl2.de
+wiocha.pl
+28tui.com
+shopzilla.com
+google.com.ni
+lycos.com
+gucheng.com
+rajanews.com
+blackhatteam.com
+mp3.es
+forums.wordpress.com
+micromaxinfo.com
+duden.de
+nyc.gov
+monova.org
+al-wlid.com
+dastelefonbuch.de
+cam4ultimate.com
+inps.it
+nazwa.pl
+beatport.com
+wizzair.com
+thomann.de
+juntadeandalucia.es
+oficialsurveyscenter.co
+zaluu.com
+videarn.com
+azcentral.com
+xvideosmovie.com
+eforosh.com
+movie25.com
+creditkarma.com
+upi.com
+mozook.com
+heavy.com
+worldoftanks.com
+vkrugudruzei.ru
+hourlyrevshare.net
+walkerplus.com
+btyou.com
+adzibiz.com
+tryflirting.com
+moi.gov.sa
+cooltext.com
+dawanda.com
+travian.com.sa
+va.gov
+sunmaker.com
+aaa.com
+dinodirect.com
+cima4u.com
+huaban.com
+nzherald.co.nz
+plotek.pl
+chow.com
+rincondelvago.com
+uzai.com
+stayfriends.de
+reed.co.uk
+rainpow.com
+dallasnews.com
+ntvspor.net
+fonearena.com
+forocoches.com
+myfonts.com
+fenopy.se
+animefreak.tv
+websitewelcome.com
+indonetwork.co.id
+mapsofindia.com
+newlook.com
+holiday-weather.com
+zhe800.com
+recipesfinder.com
+bbom.com.br
+jalopnik.com
+canon.com
+freshbooks.com
+clickcompare.info
+aprod.hu
+thisav.com
+boerse.bz
+orange.es
+forobeta.com
+surfactif.fr
+listverse.com
+feedjit.com
+bni.co.id
+gamemazing.com
+mbalib.com
+topsy.com
+torchbrowser.com
+ieee.org
+tinydeal.com
+playdom.com
+redorbit.com
+inboxdollars.com
+google.com.bh
+pcanalysis.net
+acer.com
+jizzbell.com
+google.com.kh
+mappy.com
+day.az
+euronews.com
+wikidot.com
+creativecommons.org
+quantcast.com
+iconarchive.com
+iyaya.com
+jetstar.com
+diandian.com
+winzip.com
+clixzor.com
+teebik.com
+meilele.com
+gsm.ir
+dek-d.com
+giantbomb.com
+tala.ir
+extremetracking.com
+homevv.com
+truthaboutabs.com
+psychologytoday.com
+vod.pl
+macromill.com
+amd.com
+livescience.com
+dedecms.com
+jin115.com
+ampxchange.com
+profitcentr.com
+webmotors.com.br
+lan.com
+fileice.net
+ingdirect.es
+amtrak.com
+emag.ro
+progressive.com
+balatarin.com
+immonet.de
+e-travel.com
+studymode.com
+go2000.com
+shopbop.com
+filesfetcher.com
+euroresidentes.com
+movistar.es
+lefeng.com
+google.hn
+homestead.com
+filesonar.com
+hsbccreditcard.com
+google.com.np
+parperfeito.com.br
+sciencedaily.com
+realgfporn.com
+wonderhowto.com
+coolrom.com
+wikibooks.org
+archdaily.com
+gigazine.net
+totaljerkface.com
+bezaat.com
+eurosport.com
+fontspace.com
+tirage24.com
+bancomer.com.mx
+nasdaq.com
+bravoteens.com
+bdjobs.com
+zimbra.free.fr
+arsenal.com
+rabota.ru
+lovefilm.com
+tsetmc.com
+movshare.net
+debonairblog.com
+zmovie.co
+peoplefinders.com
+mercadolibre.com
+connectlondoner.com
+forbes.ru
+gagnezauxoptions.com
+taikang.com
+mywapblog.com
+citysearch.com
+novafinanza.com
+gruposantander.es
+relianceada.com
+rankingsandreviews.com
+hjenglish.com
+state.nj.us
+comdirect.de
+claro.com.br
+alluc.to
+godlikeproductions.com
+lowyat.net
+dawn.com
+18xgirls.com
+origo.hu
+loopnet.com
+payu.in
+digitalmedia-comunicacion.com
+newsvine.com
+petfinder.com
+kuaibo.com
+soft32.com
+yellowpages.ca
+1fichier.com
+egyup.com
+iskullgames.com
+androidforums.com
+blogspot.cz
+umich.edu
+madsextube.com
+bigcinema.tv
+donedeal.ie
+winporn.com
+cosmopolitan.com
+reg.ru
+localmoxie.com
+kootation.com
+gidonline.ru
+clipconverter.cc
+gioco.it
+ravelry.com
+gettyimages.com
+medicalnewsreporter.com
+shop411.com
+aif.ru
+journaldesfemmes.com
+blogcu.com
+vanguard.com
+freemp3go.com
+google.ci
+findicons.com
+tineye.com
+webdesignerdepot.com
+nomorerack.com
+iqoo.me
+amarujala.com
+pengfu.com
+leadpages.net
+zalukaj.tv
+avon.com
+casasbahia.com.br
+juegosdechicas.com
+tvrain.ru
+askmefast.com
+stockcharts.com
+footlocker.com
+allanalpass.com
+theoatmeal.com
+storify.com
+santander.com.br
+laughnfiddle.com
+lomadee.com
+aftenposten.no
+lamoda.ru
+tasteofhome.com
+news247.gr
+sherdog.com
+milb.com
+3djuegos.com
+dreammovies.com
+commonfloor.com
+tharunee.lk
+chatrandom.com
+rechargeitnow.com
+am15.net
+sexad.net
+herokuapp.com
+apontador.com.br
+rfi.fr
+woozworld.com
+hitta.se
+comedycentral.com
+fbsbx.com
+aftabnews.ir
+stepstone.de
+filmon.com
+ameritrade.com
+ecitic.com
+bola.net
+hq-sex-tube.com
+gsp.ro
+groupon.co.uk
+20min.ch
+barclaycardus.com
+dice.com
+himasoku.com
+nwsource.com
+gougou.com
+iol.co.za
+thinkgeek.com
+governmentjobs.com
+500.com
+caixin.com
+elsevier.com
+rafflecopter.com
+auctiva.com
+pracuj.pl
+strato.de
+ricardoeletro.com.br
+vodafone.de
+jike.com
+smosh.com
+downlite.net
+to8to.com
+tikona.in
+royalmail.com
+tripadvisor.de
+realclearpolitics.com
+pubdirecte.com
+rassd.com
+ptt.cc
+townhall.com
+theoldreader.com
+viki.com
+one.com
+peopleperhour.com
+desidime.com
+17track.net
+duote.com
+emuch.net
+mlgame.co.uk
+rockstargames.com
+slaati.com
+ibibo.com
+journaldunet.com
+ria.ua
+odatv.com
+comodo.com
+clickfair.com
+system500.com
+wordstream.com
+alexaboostup.com
+yjbys.com
+hsbc.com
+online-convert.com
+miui.com
+totaljobs.com
+travian.fr
+funda.nl
+bazos.sk
+efukt.com
+startlap.com
+hir24.hu
+mrskin.com
+dbs.com
+sevenforums.com
+admitad.com
+graaam.com
+exactme.com
+roadrunner.com
+liberation.fr
+cas.sk
+redbubble.com
+ezilon.com
+hihi2.com
+net.hr
+mediaite.com
+clip2net.com
+wapka.mobi
+dailybasis.com
+o2online.de
+tweetdeck.com
+fakt.pl
+service-public.fr
+bodisparking.com
+corporationwiki.com
+jandan.net
+alisoft.com
+gosuslugi.ru
+grxf.com
+daserste.de
+freedigitalphotos.net
+flirchi.ru
+htmlbook.ru
+independent.ie
+bufferapp.com
+panzar.com
+sport.cz
+matomeantena.com
+thenewporn.com
+iran-tejarat.com
+rotoworld.com
+maalaimalar.com
+poppen.de
+csfd.cz
+2ip.ru
+hawamer.com
+telkomsel.com
+un.org
+autobinaryea.com
+emgoldex.com
+saksfifthavenue.com
+realtor.ca
+hdwallpapers.in
+chinahr.com
+niazerooz.com
+sina.com
+kinopod.ru
+funweek.it
+pornsake.com
+vitacost.com
+110.com
+jobomas.com
+joyreactor.cc
+3dnews.ru
+vedomosti.ru
+stansberryresearch.com
+performersoft.com
+codecademy.com
+petsmart.com
+kissmetrics.com
+infojobs.it
+wealink.com
+rapidtrk.com
+enterprise.com
+iran-forum.ir
+express-files.com
+cyberpresse.ca
+dobreprogramy.pl
+uploading.com
+profitclicking.com
+playwartune.com
+toluna.com
+shoptime.com.br
+totaladperformance.com
+handelsblatt.com
+hamshahrionline.ir
+15min.lt
+wyborcza.pl
+flvto.com
+microsofttranslator.com
+trovaprezzi.it
+eversave.com
+wmzona.com
+hardwarezone.com.sg
+thestar.com.my
+siliconindia.com
+jfranews.com
+emol.com
+nordea.fi
+heroturko.me
+xat.com
+3asq.com
+hlntv.com
+incruit.com
+list-manage2.com
+bulbagarden.net
+blogdohotelurbano.com
+suomi24.fi
+nicozon.net
+tuporno.tv
+perfectworld.com
+ayosdito.ph
+gmx.at
+123greetings.com
+metafilter.com
+g9g.com
+searchnfind.org
+pcgamer.com
+on.cc
+rentalcars.com
+mail2web.com
+zalando.it
+freevideo.cz
+source-wave.com
+iranjib.ir
+societe.com
+160by2.com
+berooztarinha.com
+popmog.com
+fantasy8.com
+motortrend.com
+huffingtonpost.ca
+51test.net
+ringtonematcher.com
+ourtime.com
+standardchartered.co.in
+rdio.com
+parsiblog.com
+btvguide.com
+sport.ro
+freep.com
+gismeteo.ua
+rojadirecta.me
+babol.pl
+lun.com
+epicurious.com
+fetishok.com
+mystart.com
+wn.com
+nationalrail.co.uk
+feedsportal.com
+rai.it
+sportlemon.tv
+groupon.com.br
+ebay.at
+yourdictionary.com
+360safe.com
+statefarm.com
+desjardins.com
+biblehub.com
+mercadolibre.cl
+eluniversal.com
+lrytas.lt
+youboy.com
+gratka.pl
+etype.com
+reallifecam.com
+imp.free.fr
+jobstreet.co.id
+geenstijl.nl
+aebn.net
+openoffice.org
+diythemes.com
+2gis.ru
+wpmu.org
+scrubtheweb.com
+domain.com.au
+buyma.com
+ccbill.com
+tui18.com
+goforfiles.com
+billionuploads.com
+blogtalkradio.com
+pipl.com
+wallpaperswide.com
+tuttosport.com
+astucecherry.com
+tradingfornewbies.com
+umn.edu
+rj.gov.br
+mlive.com
+justfab.com
+ijreview.com
+daniweb.com
+quickmeme.com
+safeway.com
+virtualedge.com
+saudiairlines.com
+elbotola.com
+holtgames.com
+boots.com
+potterybarn.com
+mediamarkt.de
+mangastream.com
+mypoints.com
+torrentdownloads.me
+subtitleseeker.com
+idlebrain.com
+ekantipur.com
+nowgamez.com
+neoseeker.com
+christianpost.com
+joystiq.com
+iphone-winners.info
+quizlet.com
+prosport.ro
+quanjing.com
+gamechit.com
+teleshow.pl
+corrieredellosport.it
+yoo7.com
+fotocasa.es
+attracta.com
+hyatt.com
+confirmit.com
+xyu.tv
+yoolplay.com
+active.com
+gizmag.com
+hostelworld.com
+pc6.com
+lacentrale.fr
+megasesso.com
+thairath.co.th
+thinkprogress.org
+400gb.com
+manageflitter.com
+pronto.com
+erotube.org
+luxtarget.com
+vui.vn
+screenrant.com
+nationalreview.com
+ikman.lk
+aboutus.org
+booloo.com
+klm.com
+aukro.ua
+skladchik.com
+alfalfalfa.com
+ghanaweb.com
+cheetahmail.com
+celebritynetworth.com
+honda.com
+regnum.ru
+mediabistro.com
+template-help.com
+elektroda.pl
+howlifeworks.com
+avjavjav.com
+justunfollow.com
+kindgirls.com
+xrea.com
+songspk.cc
+impiego24.it
+health.com
+whitehouse.gov
+ulozto.cz
+clickindia.com
+zoosnet.net
+yingjiesheng.com
+copacet.com
+fluege.de
+uiuc.edu
+funnymama.com
+popsugar.com
+siyahgazete.com
+ligatus.com
+seomastering.com
+nintendo.com
+kuaidi100.com
+motor-talk.de
+p.ht
+care.com
+ttnet.com.tr
+cifraclub.com.br
+yunfile.com
+telechargement-de-ouf.fr
+hotpornshow.com
+upenn.edu
+brg8.com
+techspot.com
+milli.az
+segundamano.mx
+n4g.com
+blogspot.no
+frys.com
+pixhost.org
+washington.edu
+rte.ie
+lockerdome.com
+qassimy.com
+signup.wordpress.com
+sochiset.com
+mycokerewards.com
+collegeboard.org
+fengyunzhibo.com
+twickerz.com
+bikroy.com
+apkmania.co
+webrankstats.com
+dl-protect.com
+dr.dk
+emoneyspace.com
+rae.es
+theexgirlfriends.com
+gigaom.com
+burmeseclassic.com
+wisc.edu
+ocnk.net
+arcot.com
+paginasamarillas.es
+tunisia-sat.com
+medscape.com
+gameninja.com
+imperiaonline.org
+2ememain.be
+myshopping.com.au
+nvidia.com
+fanhuan.com
+vista.ir
+dish.com
+cartrade.com
+egopay.com
+sonyentertainmentnetwork.com
+myway.com
+kariyer.net
+thanhnien.com.vn
+gulfnews.com
+flagcounter.com
+yfrog.com
+bigstockphoto.com
+occ.com.mx
+3911.net
+naszemiasto.pl
+pgatour.com
+zgjrw.com
+fdj.fr
+motogp.com
+organogold.com
+tamindir.com
+ykb.com
+biglion.ru
+yourfiledownloader.com
+publika.az
+dealnews.com
+warnerbros.com
+wpmudev.org
+pu-results.info
+usajobs.gov
+adsprofitwiz.es
+parallels.com
+thqafawe3lom.com
+xiazaiba.com
+enikos.gr
+m5zn.com
+dir.bg
+ripoffreport.com
+jusbrasil.com.br
+maxifoot.fr
+eva.vn
+dfnhk8.net
+api.ning.com
+ligtv.com.tr
+openrice.com
+999120.net
+pho.to
+indiblogger.in
+tfile.me
+kotak.com
+katproxy.com
+calottery.com
+klmty.net
+endomondo.com
+uploadboy.com
+8tracks.com
+blox.pl
+conrad.de
+sonico.com
+windguru.cz
+tinhte.vn
+grantland.com
+seratnews.ir
+solomono.ru
+foreca.com
+ziprecruiter.com
+chime.in
+intesasanpaolo.com
+softonic.de
+adtech.info
+appgame.com
+opendns.com
+tubekitty.com
+linguee.de
+pepperfry.com
+egou.com
+tweakers.net
+alfavita.gr
+plusnetwork.com
+timeweb.ru
+maybeporn.com
+gharreh.com
+canoe.ca
+parsine.com
+ucla.edu
+freeridegames.com
+doctoroz.com
+tradeindia.com
+socialmediabar.com
+yaske.net
+miniih.com
+blog.me
+dn.se
+almos3a.com
+bbvanet.com.mx
+fcbarcelona.com
+web.com
+raaga.com
+yad2.co.il
+2cto.com
+nx8.com
+modcloth.com
+carsales.com.au
+cooks.com
+fileswap.com
+egyptiansnews.com
+azyya.com
+masreat.com
+airliners.net
+com-1b.info
+virginmobileusa.com
+pleasantharborrv.com
+gsmhosting.com
+foxbusiness.com
+delfi.lv
+flightaware.com
+ameli.fr
+fbxtk.com
+purdue.edu
+sbi.co.in
+fotka.pl
+quicksprout.com
+arjwana.com
+affili.net
+5sing.com
+mozilla.com
+taaza.com
+onetad.com
+vivastreet.it
+leguide.com
+casualclub.com
+wanelo.com
+ipsosinteractive.com
+videohive.net
+fenzhi.com
+lefrecce.it
+bugun.com.tr
+p30world.com
+cuevana.tv
+joins.com
+tvnet.lv
+aliimg.com
+bellanaija.com
+startpagina.nl
+incometaxindiaefiling.gov.in
+michigan.gov
+harborfreight.com
+fineartamerica.com
+mysurvey.com
+kapaza.be
+adxpansion.com
+thefind.com
+priyo.com
+burrp.com
+sky.it
+ipad-winners.info
+usgs.gov
+gavick.com
+ellislab.com
+voegol.com.br
+paginebianche.it
+getwebcake.com
+zeroredirect1.com
+gaiaonline.com
+iqilu.com
+bright.com
+comunidades.net
+webgains.com
+overdrive.com
+bigcommerce.com
+paperpkads.com
+imageporter.com
+listal.com
+rbcdaily.ru
+redbus.in
+3bmeteo.com
+earn-on.com
+ae.com
+shoutmeloud.com
+oeeee.com
+usenet.nl
+mediotiempo.com
+prostoporno.net
+bangyoulater.com
+comunio.de
+pureleads.com
+bakeca.it
+trovit.it
+fakku.net
+indeed.fr
+inquisitr.com
+wizards.com
+straightdope.com
+pornpros.com
+s-oman.net
+facilisimo.com
+dostor.org
+tabloidpulsa.co.id
+shafaf.ir
+bt.dk
+lent.az
+filmaffinity.com
+wjunction.com
+gamefront.com
+photoshelter.com
+cheaptickets.com
+meetic.it
+seochat.com
+livemixtapes.com
+deadline.com
+boingboing.net
+lecai.com
+onetravel.com
+erotictube.me
+svd.se
+pcadvisor.co.uk
+pravda.com.ua
+afisha.ru
+dressupgamesite.com
+mercadopago.com
+bangkokpost.com
+dumpert.nl
+monotaro.com
+bloomingdales.com
+ebayclassifieds.com
+t-online.hu
+2dbook.com
+thekitchn.com
+halifax.co.uk
+tanx.com
+jutarnji.hr
+petardashd.com
+rookee.ru
+showroomprive.com
+sharepoint.com
+liebiao.com
+pumbaporn.com
+dwnews.com
+sanguosha.com
+pp.cc
+myfc.ir
+alicdn.com
+carmax.com
+defencenet.gr
+cuantarazon.com
+westernunion.com
+natunbarta.com
+sekindo.com
+edublogs.org
+hotmail.com
+problogger.net
+amardeshonline.com
+gemius.com
+egynews.net
+indiabix.com
+provincial.com
+play.com
+beslist.nl
+shape.com
+alhilal.com
+irecommend.ru
+cmmnts.com
+1news.az
+kinobanda.net
+banamex.com.mx
+cleanfiles.net
+algeriaforum.net
+zumi.pl
+giallozafferano.it
+news-postseven.com
+firstcry.com
+lookforporn.com
+xxsy.net
+scriptmafia.org
+intodns.com
+famitsu.com
+eclipse.org
+net-a-porter.com
+btemplates.com
+topshop.com
+myvidster.com
+calciomercato.com
+arabyonline.com
+lesechos.fr
+empireavenue.com
+damnlol.com
+nukistream.com
+wayport.net
+buienradar.nl
+vivastreet.co.in
+kroger.com
+geocaching.com
+hunantv.com
+fotolog.net
+gunbroker.com
+flalottery.com
+priples.com
+nlayer.net
+trafficshop.com
+standardmedia.co.ke
+finanzen.net
+meta.ua
+gfy.com
+playground.ru
+rp5.ru
+otnnetwork.net
+tvmao.com
+hir.ma
+twilightsex.com
+haodou.com
+virgin-atlantic.com
+ankieta-online.pl
+kinkytube.me
+123mplayer.com
+elifting.com
+akiba-online.com
+tcsbank.ru
+gametrailers.com
+dihitt.com
+fancy.com
+admaimai.com
+61.com
+hotchatdirect.com
+penesalud.com
+adsupplyads.com
+robokassa.ru
+brooonzyah.net
+moviesmobile.net
+fuck-mates.com
+ch-news.com
+cwan.com
+mec.gov.br
+musiciansfriend.com
+angrybirds.com
+ebrun.com
+kienthuc.net.vn
+morningstar.com
+rasekhoon.net
+techsmith.com
+diy.com
+awwwards.com
+ajc.com
+akismet.com
+itar-tass.com
+60secprofit.com
+videoweed.es
+guitarcenter.com
+tv2.dk
+narutom.com
+bittorrent.com
+unionpaysecure.com
+91jm.com
+licindia.in
+bama.ir
+hertz.com
+propertyguru.com.sg
+city8.com
+blu-ray.com
+abebooks.com
+adidas.com
+sing365.com
+qq163.com
+fashionandyou.com
+lietou.com
+eniro.se
+pengpeng.com
+haibao.com
+jxedt.com
+crsky.com
+nyu.edu
+minecraftskins.com
+yangtse.com
+almstba.co
+parsnews.com
+twiends.com
+dkb.de
+friendscout24.de
+aviny.com
+dig.do
+gamestorrents.com
+guru.com
+bostonglobe.com
+brandalley.fr
+tn.com.ar
+yourwebsite.com
+istgah.com
+e-familynet.com
+hotshame.com
+volkskrant.nl
+karnaval.com
+team-bhp.com
+sinemalar.com
+ipko.pl
+fastcompany.com
+embedupload.com
+gzmama.com
+icicidirect.com
+whatismyip.com
+siasat.pk
+rbi.org.in
+amarillasinternet.com
+netvasco.com.br
+ctvnews.ca
+gad.de
+dailyfx.com
+smartklicks.com
+qoo10.sg
+loc.gov
+playerflv.com
+uta-net.com
+afl.com.au
+mainlink.ru
+pricedekho.com
+wickedfire.com
+rlslog.net
+raiffeisen.at
+easports.com
+groupon.fr
+o2.co.uk
+irangrand.ir
+vuku.tv
+play.pl
+mxtoolbox.com
+promiflash.de
+linode.com
+familysearch.org
+publico.pt
+freepornvideo.me
+uploadbaz.com
+tocmai.ro
+cimbclicks.com.my
+bestporntube.me
+lainformacion.com
+herschina.com
+fontsquirrel.com
+blip.tv
+caranddriver.com
+qld.gov.au
+pons.eu
+nascar.com
+hrsmart.com
+tripadvisor.com.au
+hs.fi
+auspost.com.au
+sponsoredreviews.com
+webopedia.com
+sovsport.ru
+bancsabadell.com
+prettyporntube.com
+sodahead.com
+ovi.com
+aleseriale.pl
+mnwan.com
+callofduty.com
+sportskeeda.com
+cp.cx
+researchgate.net
+michaels.com
+createspace.com
+sprintrade.com
+anonymouse.org
+hautelook.com
+4gamer.net
+accorhotels.com
+roomkey.com
+guildwars2.com
+cargurus.com
+wpengine.com
+iis.net
+vendaria.com
+argentinawarez.com
+webdesigntunes.com
+allvoices.com
+eprize.com
+pmu.fr
+carrefour.fr
+tax.gov.ir
+ruelala.com
+mainspy.ru
+phpwind.net
+loteriasyapuestas.es
+musavat.com
+lenskart.com
+refinery29.com
+888poker.es
+denverpost.com
+who.int
+thesims3.com
+jerkhour.com
+lyricsmode.com
+ivillage.com
+qyer.com
+hktdc.com
+pornoload.com
+bluedart.com
+here.com
+philips.com
+dsebd.org
+tubidy.mobi
+stream.cz
+infojobs.com.br
+soft98.ir
+bolsaparanovatos.com
+mercador.ro
+neogaf.com
+yardbarker.com
+rapidlibrary.com
+xxeronetxx.info
+kaiserpermanente.org
+telstra.com.au
+contra.gr
+laredoute.it
+lipsum.com
+twitlonger.com
+hln.be
+53kf.com
+gofundme.com
+carigold.com
+clips4sale.com
+focalprice.com
+gameaholic.com
+presstv.ir
+puu.sh
+filmlinks4u.net
+traffic-delivery.com
+bebo.com
+enter.ru
+shufoo.net
+vivo.com.br
+jizzhut.com
+1jux.net
+serebii.net
+translate.ru
+mtv3.fi
+njuskalo.hr
+bell.ca
+myheritage.com
+cic.fr
+mercurynews.com
+alaan.tv
+econsultancy.com
+pornhost.com
+a8.net
+netzero.net
+tracklab101.com
+spanishdict.com
+amctv.com
+erepublik.com
+mk.ru
+publico.es
+fux.com
+webcamtoy.com
+rahnama.com
+wanyh.com
+ecplaza.net
+mol.gov.sa
+torrentday.com
+hsbc.com.br
+interoperabilitybridges.com
+billmelater.com
+speedanalysis.com
+volusion.com
+mixcloud.com
+weeronline.nl
+tiancity.com
+thehun.com
+comparisons.org
+eurosport.ru
+trendyol.com
+7120.com
+eldiariodeamerica.com
+fap8.com
+joyme.com
+ufl.edu
+cuantocabron.com
+hotmart.com.br
+wolframalpha.com
+cpasbien.com
+sanalpazar.com
+publipt.com
+9ku.com
+officemax.com
+cuny.edu
+gem.pl
+waelelebrashy.com
+coinmill.com
+bet.com
+moskva.fm
+groupalia.com
+131.com
+pichak.net
+theatlanticwire.com
+laptopmag.com
+worldpay.com
+groupon.pl
+imeimama.com
+torrents.net
+britishcouncil.org
+letsbonus.com
+e-monsite.com
+url.org
+discuz.com
+freepornsite.me
+cheatcc.com
+magicmovies.com
+laterooms.com
+du.ac.in
+uservoice.com
+discas.net
+d1g.com
+explicittube.com
+e-autopay.com
+3lian.com
+oopsmovs.com
+agenziaentrate.gov.it
+ufc.com
+mooshare.biz
+ankang06.org
+betradar.com
+explosm.net
+silkroad.com
+crackberry.com
+toyota.com
+bongda.com.vn
+europapress.es
+mlxchange.com
+plius.lt
+pitchfork.com
+groupon.de
+hollisterco.com
+hasoffers.com
+miami.com
+dslreports.com
+blinkweb.com
+alamaula.com
+leonardo.it
+very.co.uk
+globalsources.com
+viator.com
+greenwichmeantime.com
+appannie.com
+eldorado.ru
+canadiantire.ca
+enjin.com
+szhome.com
+phim3s.net
+bash.im
+immi.gov.au
+enjoydressup.com
+thesuperficial.com
+91mobiles.com
+libertaddigital.com
+po-kaki-to.com
+truelocal.com.au
+centrum24.pl
+zylom.com
+mypornmotion.com
+skybet.com
+soccermanager.com
+poriborton.com
+mozzi.com
+eset.com
+chelseafc.com
+amulyam.in
+argaam.com
+mnn.com
+papystreaming.com
+hostelbookers.com
+vatera.hu
+pciconcursos.com.br
+milenio.com
+yellowbook.com
+mobilepriceindia.co.in
+naked.com
+lazada.vn
+70e.com
+mapy.cz
+vodafone.es
+zbiornik.com
+fc2web.com
+rghost.ru
+avvo.com
+fardanews.com
+pcbeta.com
+hibapress.com
+gamehouse.com
+macworld.com
+qantas.com.au
+dba.dk
+inttrax.com
+conejox.com
+immobiliare.it
+sparkasse.at
+udemy.com
+accenture.com
+pokerstrategy.com
+leroymerlin.fr
+sweetkiss.me
+siriusxm.com
+nieuwsblad.be
+blogun.ru
+ojogos.com.br
+lexilogos.com
+c-and-a.com
+authorstream.com
+newser.com
+minube.com
+yellowpages.com.au
+torrentfreak.com
+expatriates.com
+51credit.com
+rawstory.com
+crictime.com
+ladolcevitae.com
+astro.com
+riverisland.com
+myzamana.com
+xpg.com.br
+svt.se
+ymlp.com
+coupondunia.in
+mymovies.it
+portaleducacao.com.br
+watchabc.go.com
+scrabblefinder.com
+2hua.com
+guiaconsumidor.com
+jzpt.com
+jino.ru
+google.tt
+addwallet.com
+enom.com
+searchfreemp3.com
+spox.com
+ename.net
+researchnow.com
+decathlon.fr
+j-cast.com
+updatetube.com
+polo.com
+asiaone.com
+kkiste.to
+frmtr.com
+skai.gr
+zovi.com
+qiwi.ru
+stfucollege.com
+carros.com.br
+privatejobshub.blogspot.in
+englishtown.com
+info.com
+multiclickbrasil.com.br
+gazeteoku.com
+kinghost.com
+izismile.com
+gopro.com
+uspto.gov
+testberichte.de
+fs.to
+sketchtoy.com
+sinarharian.com.my
+stylemode.com
+v7n.com
+livenation.com
+firstrow1.eu
+joomlaforum.ru
+sharecare.com
+vetogate.com
+series.ly
+property24.com
+payamsara.com
+webstarts.com
+renfe.es
+fatcow.com
+24ur.com
+lide.cz
+sabayacafe.com
+prodavalnik.com
+hyves.nl
+almaany.com
+xero.com
+celluway.com
+mapbar.com
+vecernji.hr
+konga.com
+fresherslive.com
+nova.cz
+onlinefwd.com
+petco.com
+benisonapparel.com
+jango.com
+mangocity.com
+gamefly.com
+igma.tv
+21cineplex.com
+fblife.com
+moe.gov.eg
+heydouga.com
+buildhr.com
+mmo-champion.com
+ithome.com
+krakow.pl
+history.com
+privatehomeclips.com
+bazos.cz
+appchina.com
+helpster.de
+51hejia.com
+fuckbadbitches.com
+toyota-autocenter.com
+alnaharegypt.com
+eastbay.com
+softonic.com.br
+translit.ru
+justcloud.com
+validclick.net
+seneweb.com
+fsiblog.com
+williamhill.it
+twitchy.com
+y4yy.com
+gouv.qc.ca
+nubiles.net
+marvel.com
+helpmefindyour.info
+tripadvisor.ca
+joomlart.com
+m18.com
+orgasmatrix.com
+bidoo.com
+rogers.com
+informationng.com
+voyage-prive.com
+comingsoon.net
+searchmetrics.com
+jetztspielen.de
+mathxl.com
+telmex.com
+purpleporno.com
+coches.net
+hamusoku.com
+link-assistant.com
+gosur.com
+torrentcrazy.com
+funny-games.biz
+bseindia.com
+promosite.ru
+google.mn
+cartoonnetworkarabic.com
+icm.edu.pl
+ttt4.com
+pepperjamnetwork.com
+lolzbook.com
+nationalpost.com
+tukif.com
+club-asteria.com
+7search.com
+kasikornbank.com
+ebay.ie
+sexlunch.com
+qype.com
+sankakucomplex.com
+flashback.org
+streamhunter.eu
+rsb.ru
+royalporntube.com
+diretta.it
+yummly.com
+dom2.ru
+metoffice.gov.uk
+goodbaby.com
+pornbb.org
+formspring.me
+google.com.cy
+purepeople.com
+epnet.com
+penny-arcade.com
+onlinekhabar.com
+vcommission.com
+zimabdk.com
+car.gr
+wat.tv
+nnn.ru
+arvixe.com
+buxp.org
+shaw.ca
+cnyes.com
+casa.it
+233.com
+text.ru
+800notes.com
+banki.ru
+marinetraffic.com
+meteo.gr
+thetrainline.com
+blogspot.ch
+netaffiliation.com
+olx.co.id
+slando.kz
+nordea.se
+xbabe.com
+bibsonomy.org
+moneynews.com
+265g.com
+horoscope.com
+yammer.com
+sextgem.com
+tribune.com.pk
+topeuro.biz
+perfectgirls.xxx
+ssc.nic.in
+8264.com
+flvrunner.com
+gry.pl
+pravda.ru
+fulltiltpoker.com
+kure.tv
+turbo.az
+ujian.cc
+mustseeindia.com
+thithtoolwin.com
+chiphell.com
+spieletipps.de
+portail.free.fr
+hbr.org
+sex-hq.com
+webdeveloper.com
+cloudzer.net
+vagas.com.br
+anspress.com
+beitaichufang.com
+songkick.com
+oyunlari.net
+unfollowers.me
+computrabajo.com.mx
+usp.br
+parseek.com
+salary.com
+navyfcu.org
+bigpond.com
+joann.com
+ajansspor.com
+burnews.com
+myrecipes.com
+mt5.com
+webconfs.com
+offcn.com
+travian.com.tr
+animenewsnetwork.com
+smartshopping.com
+twojapogoda.pl
+tigerairways.com
+archiveofourown.org
+qq937.com
+meneame.net
+joyclub.de
+yy.com
+weddingwire.com
+moddb.com
+acervoamador.com
+stgeorge.com.au
+forumhouse.ru
+mp3xd.com
+lionair.co.id
+needtoporn.com
+playcast.ru
+paheal.net
+finishline.com
+sep.gob.mx
+comenity.net
+tqn.com
+eroticads.com
+svpressa.ru
+dtvideo.com
+mobile.free.fr
+privat24.ua
+mp3sk.net
+atlas.sk
+aib.ie
+shockwave.com
+qatarairways.com
+theladders.com
+dsnetwb.com
+expansiondirecto.com
+povarenok.ru
+moneysupermarket.com
+getchu.com
+gay.com
+hsbc.com.mx
+textsale.ru
+kadinlarkulubu.com
+scientificamerican.com
+hillnews.com
+tori.fi
+6tie.com
+championselect.net
+gtobal.com
+bangkokbank.com
+akakce.com
+smarter.com
+totalvideoplugin.com
+dmir.ru
+rpp.com.pe
+uhaul.com
+kayako.com
+buyvip.com
+sixrevisions.com
+army.mil
+rediffmail.com
+gsis.gr
+destinia.com
+behindwoods.com
+wearehairy.com
+coqnu.com
+soundclick.com
+drive.ru
+cam4.fr
+bakusai.com
+thailandtorrent.com
+videosz.com
+eporner.com
+stltoday.com
+ilmessaggero.it
+theregister.co.uk
+bloggang.com
+nastyvideotube.com
+doityourself.com
+rp-online.de
+wow-impulse.ru
+kar.nic.in
+bershka.com
+neteller.com
+adevarul.ro
+divxtotal.com
+bolshoyvopros.ru
+letudiant.fr
+xinshipu.com
+vh1.com
+excite.com
+somewhereinblog.net
+mcgraw-hill.com
+patheos.com
+webdesignledger.com
+plus28.com
+adultwork.com
+dajuegos.com
+blogs.com
+glopart.ru
+donews.com
+nation.co.ke
+delfi.ee
+lacuerda.net
+jjshouse.com
+megaindex.ru
+darty.com
+maturetube.com
+jokeroo.com
+estekhtam.com
+fnac.es
+ninjakiwi.com
+tovima.gr
+timinternet.it
+citizensbankonline.com
+builtwith.com
+ko499.com
+tastyblacks.com
+currys.co.uk
+jobui.com
+notebookreview.com
+meishij.net
+filerio.in
+cheapflights.co.uk
+puls24.mk
+rumbo.es
+newsbusters.org
+imgdino.com
+oxforddictionaries.com
+ftdownloads.com
+ciudad.com.ar
+latercera.cl
+lankadeepa.lk
+bankier.pl
+hawahome.com
+comicvine.com
+cam4.it
+fok.nl
+iknowthatgirl.com
+hizliresim.com
+ebizmba.com
+twistys.com
+minkchan.com
+dnevnik.hr
+peliculascoco.com
+new-xhamster.com
+freelancer.in
+globalgrind.com
+talkgold.com
+kanui.com.br
+woxikon.de
+jobstreet.com.my
+job.ru
+wowbiz.ro
+yiyi.cc
+sinoptik.ua
+parents.com
+forblabla.com
+trojmiasto.pl
+anyoption.com
+wplocker.com
+paytm.in
+elespectador.com
+mysitecost.ru
+startribune.com
+cam4.co.uk
+bestcoolmobile.com
+soup.io
+starfall.com
+ixl.com
+oreilly.com
+dansmovies.com
+facemoods.com
+google.ge
+sat.gob.mx
+weatherbug.com
+majorgeeks.com
+llbean.com
+catho.com.br
+googlegroups.com
+animoto.com
+alquds.co.uk
+newsday.com
+games2girls.com
+youporngay.com
+spaces.ru
+seriespepito.com
+gelbeseiten.de
+thethirdmedia.com
+watchfomny.com
+freecamsexposed.com
+dinakaran.com
+xxxhost.me
+smartprix.com
+thoughtcatalog.com
+soccersuck.com
+vivanuncios.com
+liba.com
+gog.com
+philstar.com
+cian.ru
+avclub.com
+slon.ru
+stc.com.sa
+jstor.org
+wehkamp.nl
+vodafone.co.uk
+deser.pl
+adscendmedia.com
+getcashforsurveys.com
+glamsham.com
+dressupgames.com
+lifo.gr
+37signals.com
+pdfonline.com
+flipkey.com
+epochtimes.com
+futhead.com
+inlinkz.com
+fx-trend.com
+yasdl.com
+techbang.com
+narenji.ir
+szonline.net
+perfil.com.ar
+mywebface.com
+taknaz.ir
+tradera.com
+golem.de
+its-mo.com
+arabnet5.com
+freerepublic.com
+britannica.com
+deccanchronicle.com
+ohio.gov
+busuu.com
+pricecheck.co.za
+paltalk.com
+sportinglife.com
+google.sn
+meteomedia.com
+push2check.net
+ing-diba.de
+immoweb.be
+oregonlive.com
+ge.tt
+bbspink.com
+business2community.com
+viidii.com
+hrloo.com
+mglradio.com
+cosme.net
+xilu.com
+scbeasy.com
+biglots.com
+dhakatimes24.com
+spankbang.com
+hitleap.com
+proz.com
+php100.com
+tvtoday.de
+funnie.st
+velvet.hu
+dhnet.be
+capital.gr
+inosmi.ru
+healthkart.com
+amway.com
+madmimi.com
+dramafever.com
+oodle.com
+spreadshirt.com
+google.mg
+utarget.ru
+matomy.com
+medhelp.org
+cumlouder.com
+aliorbank.pl
+takepart.com
+myfreshnet.com
+adorama.com
+dhs.gov
+mivo.tv
+nchsoftware.com
+gnc.com
+spiceworks.com
+jeu.fr
+terra.com
+irishtimes.com
+kleiderkreisel.de
+ebay.be
+rt.ru
+radiofarda.com
+atrapalo.com
+southcn.com
+turkcell.com.tr
+themetapicture.com
+aujourdhui.com
+ato.gov.au
+pelis24.com
+saaid.net
+bradsdeals.com
+pirate101.com
+saturn.de
+thisissouthwales.co.uk
+cyberlink.com
+internationalredirects.com
+radardedescontos.com.br
+rapidcontentwizard.com
+kabum.com.br
+webrankinfo.com
+kiabi.com
+farecompare.com
+xinjunshi.com
+vidxden.com
+pvrcinemas.com
+chachaba.com
+wanmei.com
+alternet.org
+rozklad-pkp.pl
+omniture.com
+childrensplace.com
+menards.com
+zhcw.com
+ouest-france.fr
+vitorrent.org
+xanga.com
+zbozi.cz
+radioshack.com
+startv.in
+affiliatewindow.com
+gov.on.ca
+grainger.com
+3rat.com
+indeed.co.za
+rtbf.be
+strava.com
+disneystore.com
+travelagency.travel
+ekitan.com
+volagratis.com
+yiiframework.com
+dramacrazy.net
+addtoany.com
+uzmantv.com
+uline.com
+fitnessmagazine.com
+khmerload.com
+italiafilm.tv
+baseball-reference.com
+neopets.com
+multiupload.nl
+lakii.com
+downloadmaster.ru
+babbel.com
+gossip-tv.gr
+laban.vn
+computerbase.de
+juyouqu.com
+markt.de
+linuxquestions.org
+giveawayoftheday.com
+176.com
+homemademoviez.com
+huffingtonpost.fr
+movieweb.com
+pornzeus.com
+posta.com.tr
+biography.com
+bukkit.org
+spirit.com
+vemale.com
+elnuevodia.com
+pof.com.br
+iranproud.com
+molodost.bz
+netcarshow.com
+ardmediathek.de
+fabfurnish.com
+myfreeblack.com
+antichat.ru
+crocko.com
+b5m.com
+entrance-exam.net
+benaughty.com
+sierratradingpost.com
+apartmentguide.com
+slimspots.com
+sondakika.com
+glamour.com
+ilyke.net
+mybroadband.co.za
+alaskaair.com
+virtualtourist.com
+rexxx.com
+fullhdfilmizle.org
+starpulse.com
+winkal.com
+ad-feeds.net
+irannaz.com
+elahmad.com
+dealspl.us
+moikrug.ru
+olx.com.mx
+rd.com
+newone.org
+naijapals.com
+forgifs.com
+fsjgw.com
+nicoviewer.net
+topeleven.com
+peerfly.com
+softportal.com
+clker.com
+tehran98.com
+weather2umbrella.com
+lookbook.nu
+futureshop.ca
+blackpeoplemeet.com
+adworkmedia.com
+entire.xxx
+bitbucket.org
+transfermarkt.co.uk
+moshimonsters.com
+baimao.com
+khanacademy.org
+2chan.net
+adopteunmec.com
+mochimedia.com
+strawberrynet.com
+gdeivse.com
+speckyboy.com
+radical-foto.ru
+softcoin.com
+cnews.ru
+ubs.com
+lankasri.com
+cylex.de
+imtranslator.net
+homeoffice.gov.uk
+answerbag.com
+chainreactioncycles.com
+sportal.bg
+livemaster.ru
+mercadolibre.com.pe
+mentalfloss.com
+google.am
+mawaly.com
+douban.fm
+abidjan.net
+pricegong.com
+brother.com
+basspro.com
+popsci.com
+olx.com.ar
+python.org
+voetbalzone.nl
+aztecaporno.com
+d-h.st
+voyeurweb.com
+storenvy.com
+aftabir.com
+imgsrc.ru
+peru.com
+mindbodygreen.com
+stereotude.com
+ar15.com
+gogecapital.com
+xipin.me
+gvt.com.br
+today.it
+mastercard.com.au
+hobbyking.com
+hawkhost.com
+thebump.com
+alpari.ru
+gamma-ic.com
+mundome.com
+quotev.com
+animaljam.com
+ohozaa.com
+sayyac.com
+kobobooks.com
+muslima.com
+digsitesvalue.net
+colourlovers.com
+uludagsozluk.com
+mercadolibre.com.uy
+oem.com.mx
+self.com
+kyohk.net
+dillards.com
+eduu.com
+replays.net
+bnpparibasfortis.be
+express.co.uk
+guaixun.com
+750g.com
+craveonline.com
+markafoni.com
+ename.com
+abercrombie.com
+noticiaaldia.com
+seniorpeoplemeet.com
+dhingana.com
+prokerala.com
+iefimerida.gr
+wprazzi.com
+pantipmarket.com
+vueling.com
+newsonlineweekly.com
+cr173.com
+ecp888.com
+diary.ru
+pervclips.com
+sudaneseonline.com
+personal.com.ar
+articlesnatch.com
+mitbbs.com
+techsupportalert.com
+filepost.com
+unblockyoutube.co.uk
+hasznaltauto.hu
+dmv.org
+port.hu
+anastasiadate.com
+adtgs.com
+namejet.com
+ally.com
+djmaza.com
+asstr.org
+corel.com
+interfax.ru
+rozee.pk
+akinator.com
+dominos.co.in
+boardgamegeek.com
+teamliquid.net
+sbrf.ru
+l99.com
+eatingwell.com
+mid-day.com
+blinkogold.it
+rosbalt.ru
+islammemo.cc
+bettycrocker.com
+womenshealthmag.com
+asandownload.com
+twitcasting.tv
+10and9.com
+youngleafs.com
+saharareporters.com
+overclock.net
+mapsgalaxy.com
+internetslang.com
+sokmil.com
+yousendit.com
+forex-mmcis.com
+vador.com
+pagewash.com
+pringotrack.com
+cpmstar.com
+yxdown.com
+surfingbird.ru
+identi.li
+n4hr.com
+elitetorrent.net
+livechatinc.com
+anzhi.com
+2checkout.com
+bancoestado.cl
+epson.com
+twodollarclick.com
+okaz.com.sa
+china-sss.com
+xforex.com
+salliemae.com
+acunn.com
+navyfederal.org
+forumactif.com
+affaire.com
+mediatemple.net
+qdmm.com
+urlm.co
+toofab.com
+yola.com
+sheldonsfans.com
+piratestreaming.com
+frontier.com
+businesswire.com
+rue89.com
+yenisafak.com.tr
+wikimart.ru
+xpressvids.info
+medicalnewstoday.com
+express.de
+grid.mk
+mass.gov
+onlinefinder.net
+yllix.com
+aksam.com.tr
+telegraf.rs
+templatic.com
+kandao.com
+policymic.com
+farfesh.com
+alza.cz
+judgeporn.com
+townwork.net
+3dcartstores.com
+marketingland.com
+okooo.com
+siteduzero.com
+cellbazaar.com
+omb100.com
+danarimedia.com
+nlcafe.hu
+qz.com
+indiapost.gov.in
+kinogo.net
+neverblue.com
+spyfu.com
+shindanmaker.com
+bankpasargad.com
+internetautoguide.com
+allover30.com
+metric-conversions.org
+carid.com
+mofos.com
+kanald.com.tr
+mobikwik.com
+checkpagerank.net
+hotscripts.com
+hornywife.com
+prixmoinscher.com
+worldbank.org
+wsodownloads.info
+his-j.com
+powned.tv
+redmondpie.com
+molotok.ru
+whatmobile.com.pk
+wiziq.com
+excelsior.com.mx
+tradetang.com
+terra.es
+sdchina.com
+rai.tv
+indiansexstories.net
+upbulk.com
+surveygizmo.com
+ulta.com
+tera-europe.com
+tuoitre.vn
+onedio.com
+favim.com
+seo-fast.ru
+twitterfeed.com
+trustedreviews.com
+ztgame.com
+radiojavan.com
+fun698.com
+126.net
+indiaglitz.com
+jdouga.com
+lofter.com
+mysavings.com
+snapfish.com
+i-sux.com
+cebbank.com
+ethnos.gr
+desktop2ch.tv
+expedia.ca
+kinja.com
+rusfolder.com
+expat-blog.com
+8teenxxx.com
+variety.com
+natemat.pl
+niazpardaz.com
+gezginler.net
+baur.de
+tv2.no
+realgm.com
+zamzar.com
+freecharge.in
+ahlamontada.com
+salespider.com
+beanfun.com
+cleveland.com
+truecaller.com
+walmart.ca
+fanbox.com
+designmodo.com
+frip.com
+sammobile.com
+minnano-av.com
+bri.co.id
+creativebloq.com
+anthropologie.com
+afpbb.com
+kingsera.ir
+songspk.co
+sexsearch.com
+dailydot.com
+hayah.cc
+angolotesti.it
+si.kz
+allthingsd.com
+paddypower.com
+canadapost.ca
+qq.cc
+amctheatres.com
+alltop.com
+allkpop.com
+nalog.ru
+dynadot.com
+copart.com
+mexat.com
+skelbiu.lt
+kerala.gov.in
+cathaypacific.com
+clip2ni.com
+tribune.com
+acidcow.com
+amkspor.com
+shiksha.com
+180upload.com
+vietgiaitri.com
+sportsauthority.com
+banki.ir
+vancouversun.com
+hackforums.net
+t-mobile.de
+simplyrecipes.com
+crazyhomesex.com
+thehindubusinessline.com
+kriesi.at
+deyi.com
+plimus.com
+websyndic.com
+express.com
+dougasouko.com
+mmstat.com
+womai.com
+alrajhibank.com.sa
+ice-porn.com
+benchmarkemail.com
+ringcentral.com
+erail.in
+poptropica.com
+search.ch
+meteo.it
+adriver.ru
+ratp.fr
+orgasm.com
+pornme.com
+gameinformer.com
+woobox.com
+advertising.com
+flyflv.com
+chinaren.com
+tube2012.com
+ikhwanonline.com
+iwebtool.com
+ucdavis.edu
+boyfriendtv.com
+rurubu.travel
+kabam.com
+talkingpointsmemo.com
+detnews.com
+sibnet.ru
+camztube.net
+madamenoire.com
+evz.ro
+staseraintv.com
+che168.com
+kidshealth.org
+m24.ru
+zenfolio.com
+webtretho.com
+postjung.com
+supersport.com
+cshtracker.com
+jeuxjeuxjeux.fr
+foxtv.es
+postjoint.com
+podnapisi.net
+prav.tv
+realmadrid.com
+mbs-potsdam.de
+tim.it
+uplus.metroer.com
+esquire.com
+ooopic.com
+castorama.fr
+afamily.vn
+findlaw.com
+smartpassiveincome.com
+sa.ae
+hemnet.se
+diytrade.com
+weblancer.net
+zapmeta.de
+bizsugar.com
+banesco.com
+ideeli.com
+lnx.lu
+divxplanet.com
+aircanada.com
+uzise.com
+sabay.com.kh
+football365.com
+crazydomains.com.au
+qxox.org
+thesmokinggun.com
+w8n3.info
+po.st
+debian.org
+flypgs.com
+craigslist.co.in
+islamway.net
+debate.com.mx
+bitdefender.com
+listindiario.com
+123telugu.com
+ilbe.com
+wordlinx.com
+ebc.com.br
+pr.gov.br
+videoyoum7.com
+ets.org
+exteen.com
+comicbookresources.com
+grammarly.com
+pdapi.com
+adultflash01.com
+orlandosentinel.com
+24option.com
+moviepilot.de
+rfa.org
+crateandbarrel.com
+srv2trking.com
+mercusuar.info
+dofus.com
+myfxbook.com
+madmovs.com
+myffi.biz
+peru21.pe
+bollywoodlife.com
+gametracker.com
+terra.com.mx
+antenam.info
+ihotelier.com
+hypebeast.com
+dramasonline.com
+wordtracker.com
+thefrisky.com
+meritnation.com
+irna.ir
+trovit.com
+cngold.org
+optymalizacja.com
+flexmls.com
+softarchive.net
+divxonline.info
+malaysian-inc.com
+dsw.com
+fantastigames.com
+mattcutts.com
+ziprealty.com
+saavn.com
+ruporn.tv
+e-estekhdam.com
+novafile.com
+tomsguide.fr
+tomshardware.co.uk
+crosswalk.com
+businessdictionary.com
+sharesix.com
+travian.cl
+indiastudychannel.com
+m7shsh.com
+hbogo.com
+888casino.it
+keywordspy.com
+pureleverage.com
+photodune.net
+foreignpolicy.com
+shiftdelete.net
+living360.net
+paixie.net
+barstoolsports.com
+aemet.es
+local.ch
+spermyporn.com
+tasnimnews.com
+imgserve.net
+huawei.com
+pik.ba
+info-dvd.ru
+2domains.ru
+sextube.fm
+searchrocket.info
+dicio.com.br
+ittefaq.com.bd
+fileserve.com
+genteflow.com
+5giay.vn
+elbadil.com
+wizaz.pl
+cyclingnews.com
+southparkstudios.com
+hangseng.com
+mapsofworld.com
+gaokao.com
+antarvasna.com
+televisa.com
+dressupwho.com
+goldprice.org
+directlyrics.com
+v2cigar.net
+peopleclick.com
+moudamepo.com
+baijob.com
+geni.com
+huangye88.com
+phun.org
+kasikornbankgroup.com
+angrymovs.com
+bibliocommons.com
+melateiran.com
+gigya.com
+17ok.com
+xdowns.com
+tportal.hr
+dreamteammoney.com
+prevention.com
+terra.cl
+blinklist.com
+51seer.com
+ruelsoft.com
+kulichki.net
+tatatele.in
+mybloggertricks.com
+ma-bimbo.com
+ftchinese.com
+sergey-mavrodi-mmm.net
+wp.tv
+chevrolet.com
+razerzone.com
+submanga.com
+thomson.co.uk
+syosetu.org
+olx.com
+vplay.ro
+rtnn.net
+55.la
+instructure.com
+lvse.com
+hvg.hu
+androidpolice.com
+cookinglight.com
+madadsmedia.com
+inews.gr
+ktxp.com
+socialsecurity.gov
+equifax.com
+ceskatelevize.cz
+gaaks.com
+chillingeffects.org
+komando.com
+nowpublic.com
+khanwars.ae
+berlin.de
+bleepingcomputer.com
+military.com
+zero10.net
+onekingslane.com
+beget.ru
+get-tune.net
+freewebs.com
+pcfinancial.ca
+sparknotes.com
+tinychat.com
+luxup.ru
+geforce.com
+tatts.com.au
+alweeam.com.sa
+123-reg.co.uk
+sexyswingertube.com
+groupon.es
+guardianlv.com
+hypovereinsbank.de
+usc.edu
+ard.de
+hoovers.com
+tdameritrade.com
+userscripts.org
+app111.com
+al.com
+op.fi
+adbkm.com
+pivithurutv.info
+haber3.com
+shatel.ir
+camonster.com
+weltbild.de
+advanceautoparts.com
+mplssaturn.com
+weeklystandard.com
+popscreen.com
+freelifetimefuckbook.com
+peixeurbano.com.br
+2258.com
+proxfree.com
+zend.com
+citehr.com
+gadyd.com
+tvspielfilm.de
+skapiec.pl
+9see.com
+cndns.com
+hurriyetemlak.com
+census.gov
+collider.com
+cinaplay.com
+aq.com
+aolsearch.com
+ce4arab.com
+cbi.ir
+cjol.com
+brandporno.com
+yicheshi.com
+mydealz.de
+xiachufang.com
+sun-sentinel.com
+flashkhor.com
+join.me
+hankyung.com
+oneandone.co.uk
+derwesten.de
+gammae.com
+webadultdating.biz
+pokerstars.com
+fucked-sex.com
+antaranews.com
+banorte.com
+travian.it
+msu.edu
+ozbargain.com.au
+77vcd.com
+bestooxx.com
+siemens.com
+en-japan.com
+akbank.com
+srf.ch
+meijer.com
+htmldrive.net
+peoplestylewatch.com
+boards.ie
+zhulong.com
+svyaznoybank.ru
+myfilestore.com
+sucuri.net
+redflagdeals.com
+javascriptkit.com
+edreams.fr
+wral.com
+togetter.com
+dmi.dk
+thinkdigit.com
+barclaycard.co.uk
+comm100.com
+christianbook.com
+popularmechanics.com
+taste.com.au
+tripadvisor.ru
+colissimo.fr
+gdposir.info
+rarlab.com
+dcnepalevent.com
+sagepub.com
+markosweb.com
+france3.fr
+mindbodyonline.com
+yapo.cl
+0-6.com
+dilbert.com
+searchqu.com
+usa.gov
+vatandownload.com
+nastymovs.com
+santanderrio.com.ar
+notebookcheck.net
+canalplus.fr
+epa.gov
+disp.cc
+hotsales.net
+interpals.net
+vz.ru
+flyertalk.com
+pjmedia.com
+solomid.net
+megaplan.ru
+hatenablog.com
+getsatisfaction.com
+hotline.ua
+alternativeto.net
+hipfile.com
+247sports.com
+phpnuke.org
+indiaresults.com
+prisjakt.nu
+1tvlive.in
+e-mai.net
+trafficg.com
+ojogo.pt
+totaldomination.com
+eroino.net
+network-tools.com
+unibytes.com
+seriouseats.com
+twicsy.com
+smbc-card.com
+toocle.com
+unbounce.com
+2tu.cc
+computerworld.com
+clicktrackprofit.com
+serialu.net
+realfarmacy.com
+metrodeal.com
+binzhi.com
+smilebox.com
+coderanch.com
+uptodown.com
+vbulletin.com
+teasernet.com
+admob.com
+fingerhut.com
+urlopener.com
+vi.nl
+expedia.de
+thekrazycouponlady.com
+linezing.com
+metropcs.com
+draugas.lt
+minecraftdl.com
+airberlin.com
+eelly.com
+siamsport.co.th
+e-junkie.com
+gulte.com
+lazada.com.ph
+cnwnews.com
+tekstowo.pl
+flavorwire.com
+settrade.com
+francetv.fr
+experian.com
+bravenet.com
+mytoys.de
+inkthemes.com
+brobible.com
+sarenza.com
+curse.com
+7sur7.be
+iberia.com
+trovit.es
+eiga.com
+getuploader.com
+sevendollarptc.com
+amadeus.com
+thedailystar.net
+gofuckbiz.com
+codepen.io
+virginia.gov
+linguee.fr
+space.com
+astrology.com
+whmcs.com
+blogher.com
+netpnb.com
+mojo-themes.com
+cam4.es
+bestwestern.com
+gencat.cat
+healthcentral.com
+ru-board.com
+tjsp.jus.br
+scene7.com
+bukalapak.com
+intporn.com
+xe.gr
+leprosorium.ru
+dytt8.net
+wpcentral.com
+fasttrafficformula.com
+hugefiles.net
+you-sex-tube.com
+naukrigulf.com
+5173.com
+comicvip.com
+jossandmain.com
+motherjones.com
+planet.fr
+thomascook.com
+deseretnews.com
+aawsat.com
+huntington.com
+desimartini.com
+maloumaa.blogspot.com
+rutgers.edu
+gratisjuegos.org
+carsforsale.com
+filestore72.info
+neowin.net
+ilgiornale.it
+download0098.com
+providesupport.com
+postini.com
+sinowaypromo.com
+watchop.com
+docusign.net
+sourcenext.com
+finviz.com
+babyoye.com
+andhrajyothy.com
+gamezer.com
+baozoumanhua.com
+niusnews.com
+yabancidiziizle.net
+fodors.com
+moonsy.com
+lidl.it
+betanews.com
+escapistmagazine.com
+markethealth.com
+clicksure.com
+aircel.com
+metacrawler.com
+aeat.es
+allafrica.com
+watchseries-online.eu
+adpost.com
+adac.de
+similarweb.com
+offervault.com
+uolhost.com.br
+moviestarplanet.com
+overclockers.ru
+rocketlanguages.com
+finya.de
+shahvani.com
+firmy.cz
+incometaxindia.gov.in
+ecostream.tv
+pcwelt.de
+arcadesafari.com
+shoghlanty.com
+videosection.com
+centauro.com.br
+eroanimedouga.net
+orientaltrading.com
+ogone.com
+sexlog.com
+hotair.com
+egypt.gov.eg
+thomasnet.com
+virustotal.com
+hayneedle.com
+fatburningfurnace.com
+lovedgames.com
+23us.com
+trafficcaptain.com
+v2cigs.com
+teknosa.com.tr
+skrill.com
+puritanas.com
+selfgrowth.com
+ikco.com
+cuisineaz.com
+causes.com
+democraticunderground.com
+placesexy.com
+expedia.co.uk
+www-com.co
+topmongol.com
+hikaritube.com
+amakings.com
+fxstreet.com
+consultant.ru
+sacbee.com
+supercheats.com
+sofunnylol.com
+muzy.com
+sparda.de
+caughtoffside.com
+chinawomendating.asia
+xmeeting.com
+google.al
+sovereignbank.com
+animeflv.net
+sky.de
+huatu.com
+payscale.com
+quotidiano.net
+pol.ir
+digital-photography-school.com
+screencrush.com
+netgear.com
+thebiglistofporn.com
+similarsitesearch.com
+peb.pl
+lanrentuku.com
+ksu.edu.sa
+tradetracker.com
+avito.ma
+projectfree.tv
+cmu.edu
+imore.com
+tickld.com
+fitday.com
+dulcebank.com
+careerdonkey.com
+pf.pl
+otzovik.com
+baltimoresun.com
+jobvite.com
+ratemyprofessors.com
+bancodevenezuela.com
+linkafarin.com
+ufxmarkets.com
+lavozdegalicia.es
+99bill.com
+punyu.com
+otodom.pl
+entireweb.com
+fastshop.com.br
+imgnip.com
+goodlife.com
+caringbridge.org
+pistonheads.com
+gun.az
+1and1.es
+photofunia.com
+nme.com
+carfax.com
+gutenberg.org
+youxixiazai.org
+webmastersitesi.com
+skynet.be
+afrointroductions.com
+mp3slash.net
+netzwelt.de
+ecrater.com
+livemint.com
+worldwinner.com
+echosign.com
+cromaretail.com
+freewebcamporntube.com
+admin.ch
+allstate.com
+photoscape.org
+cv-library.co.uk
+voici.fr
+wdr.de
+pbase.com
+mycenturylink.com
+sonicomusica.com
+schema.org
+smashwords.com
+al3ab.net
+muryouav.net
+mocospace.com
+fundsxpress.com
+chrisc.com
+poemhunter.com
+cupid.com
+timescity.com
+banglamail24.com
+motika.com.mk
+sec.gov
+whatculture.com
+namepros.com
+vsemayki.ru
+hip2save.com
+hotnews.ro
+vietbao.vn
+inazumanews2.com
+irokotv.com
+appthemes.com
+tirerack.com
+maxpark.com
+successfactors.com
+sba.gov
+hk-porno.com
+setlinks.ru
+travel24.com
+qatarliving.com
+hotlog.ru
+rapmls.com
+qualityhealth.com
+linkcollider.com
+kashtanka.com
+hightail.com
+appszoom.com
+armagedomfilmes.biz
+pnu.ac.ir
+globalbux.net
+ebay.com.hk
+ladenzeile.de
+thedomainfo.com
+naosalvo.com.br
+perfectcamgirls.com
+verticalresponse.com
+khabardehi.com
+oszone.net
+teamtreehouse.com
+humanservices.gov.au
+bostonherald.com
+kafeteria.pl
+society6.com
+gamevicio.com
+crazyegg.com
+logitravel.com
+williams-sonoma.com
+htmlgoodies.com
+fontanka.ru
+islamuon.com
+tcs.com
+elyrics.net
+vip-prom.net
+jobstreet.com.ph
+designfloat.com
+lavasoft.com
+tianjinwe.com
+telelistas.net
+taglol.com
+jacquieetmicheltv.net
+esprit-online-shop.com
+theeroticreview.com
+boo-box.com
+wandoujia.com
+vgsgaming.com
+yourtango.com
+tianji.com
+jpost.com
+mythemeshop.com
+seattlepi.com
+bultannews.com
+youlikehits.com
+partycity.com
+18qt.com
+yuvutu.com
+gq.com
+wiziwig.tv
+cinejosh.com
+technet.com
+vatanbilgisayar.com
+guangjiela.com
+siteheart.com
+in.gov
+nulled.cc
+mafiashare.net
+tizag.com
+hkjc.com
+restaurant.com
+consumersurveygroup.org
+spin.de
+silverlinetrips.com
+triberr.com
+gamesgirl.net
+qqt38.com
+xiaoshuomm.com
+theopen.com
+campograndenews.com.br
+soonnight.com
+safaribooksonline.com
+main-hosting.com
+caclubindia.com
+alibado.com
+autorambler.ru
+tnt.com
+chatango.com
+satrk.com
+pagesperso-orange.fr
+houseoffraser.co.uk
+nullrefer.com
+work.ua
+inagist.com
+kaban.tv
+cnxad.com
+tarad.com
+masteetv.com
+noblesamurai.com
+lifehacker.ru
+anakbnet.com
+google.co.ug
+webcamsex.nl
+kaoyan.com
+ml.com
+up.nic.in
+bounceme.net
+netfirms.com
+idokep.hu
+wambie.com
+funpatogh.com
+bcash.com.br
+sedo.co.uk
+noupe.com
+mydirtyhobby.com
+neswangy.net
+downloadprovider.me
+utah.gov
+consumerintelligenceusa.com
+itimes.com
+picroma.com
+lustagenten.com
+kemdiknas.go.id
+sitepronews.com
+ruseller.com
+tradecarview.com
+favstar.fm
+bestbuy.ca
+yelp.ca
+stop-sex.com
+rewity.com
+qiqigames.com
+suntimes.com
+hardware.fr
+rxlist.com
+bgr.com
+zalora.co.id
+mandatory.com
+collarme.com
+mycommerce.com
+holidayiq.com
+filecloud.io
+vconnect.com
+66163.com
+tlen.pl
+mmbang.com
+7c.com
+digitalriver.com
+24video.net
+worthofweb.com
+clasicooo.com
+greatschools.net
+tagesanzeiger.ch
+video.az
+osu.edu
+careers360.com
+101.ru
+conforama.fr
+apollo.lv
+netcq.net
+jofogas.hu
+niftylink.com
+midwayusa.com
+collegeteensex.net
+search.com
+naftemporiki.gr
+sainsburys.co.uk
+fitsugar.com
+ifixit.com
+uid.me
+malwarebytes.org
+maxbounty.com
+mensfitness.com
+rtl.be
+yidio.com
+dostorasly.com
+abovetopsecret.com
+sm3na.com
+cam.ac.uk
+gamegape.com
+ocioso.com.br
+register.com
+wwitv.com
+ishangman.com
+gry-online.pl
+ogli.org
+redbull.com
+dyn.com
+freeservers.com
+brandsoftheworld.com
+lorddownload.com
+mybet.com
+brothalove.com
+inchallah.com
+lottomatica.it
+indiamp3.com
+qianbao666.com
+zurb.com
+synxis.com
+baskino.com
+swefilmer.com
+hotstartsearch.com
+cloudmoney.info
+polldaddy.com
+moheet.com
+idhostinger.com
+mp3chief.com
+tao123.com
+channelnewsasia.com
+galeon.com
+aviasales.ru
+datafilehost.com
+travian.com.eg
+ebookee.org
+filmstarts.de
+inccel.com
+chatroulette.com
+it-ebooks.info
+nix.ru
+antena3.ro
+mylifetime.com
+desitorrents.com
+mydigitallife.info
+aeropostale.com
+anilos.com
+macadogru.com
+premiere.fr
+estorebuilder.com
+eventim.de
+expert-offers.com
+deloitte.com
+thetimenow.com
+spicybigbutt.com
+gistmania.com
+pekao24.pl
+linkfeed.ru
+carnival.com
+apherald.com
+choicehotels.com
+revolvermaps.com
+digu.com
+yekmobile.com
+barbarianmovies.com
+poyopara.com
+vse.kz
+socialspark.com
+deutschepost.de
+nokaut.pl
+farpost.ru
+shoebuy.com
+1c-bitrix.ru
+pimproll.com
+startxchange.com
+seocentro.com
+kporno.com
+izvestia.ru
+bathandbodyworks.com
+allhyipmonitors.com
+europe1.fr
+charter.com
+sixflags.com
+abcjuegos.net
+wind.it
+femjoy.com
+humanmetrics.com
+myrealgames.com
+cosmiq.de
+bangbrosteenporn.com
+thepetitionsite.com
+laprensa.com.ni
+investors.com
+techpowerup.com
+prosperityteam.com
+autogidas.lt
+state.ny.us
+techbargains.com
+takvim.com.tr
+kko-appli.com
+liex.ru
+cafe24.com
+definebabe.com
+egirlgames.net
+avangard.ru
+sina.com.hk
+freexcafe.com
+vesti.bg
+francetvinfo.fr
+mathsisfun.com
+easymobilerecharge.com
+dapink.com
+propellerads.com
+devshed.com
+clip.vn
+vidivodo.com
+blogspot.dk
+foxnewsinsider.com
+instapaper.com
+premierleague.com
+elo7.com.br
+teenee.com
+clien.net
+computrabajo.com.co
+komputronik.pl
+livesurf.ru
+123cha.com
+cgg.gov.in
+leadimpact.com
+socialmonkee.com
+speeddate.com
+bet-at-home.com
+huanqiuauto.com
+tadawul.com.sa
+ucsd.edu
+fda.gov
+cint.com
+homedepot.ca
+ciao.de
+gigglesglore.com
+warframe.com
+prosieben.de
+vistaprint.in
+mapple.net
+usafis.org
+truelife.com
+1o26.com
+boldsky.com
+freeforums.org
+lolnexus.com
+ti-da.net
+handelsbanken.se
+khamsat.com
+futbol24.com
+wikifeet.com
+dev-point.com
+ibotoolbox.com
+indeed.de
+ct10000.com
+appleinsider.com
+lyoness.net
+vodafone.com.eg
+aifang.com
+tripadvisor.com.br
+hbo.com
+pricerunner.com
+4everproxy.com
+fc-perspolis.com
+themobileindian.com
+gimp.org
+novayagazeta.ru
+dnfight.com
+coco.fr
+thestudentroom.co.uk
+tiin.vn
+dailystar.co.uk
+unfollowed.me
+aljazeerasport.net
+nasygnale.pl
+somethingawful.com
+scamadviser.com
+mcanime.net
+9stock.com
+boostmobile.com
+oyunkolu.com
+beliefnet.com
+lyrics007.com
+rtv.net
+hasbro.com
+vcp.ir
+fj-p.com
+jetbrains.com
+cpalead.com
+zetaboards.com
+sbobet.com
+v2ex.com
+toggle.com
+lanebryant.com
+girlgames4u.com
+amadershomoy1.com
+planalto.gov.br
+news-choice.net
+sarkarinaukriblog.com
+sudouest.fr
+zdomo.com
+egy-nn.com
+pizzaplot.com
+topgear.com
+sony.co.in
+nosv.org
+beppegrillo.it
+sakshieducation.com
+temagay.com
+stepashka.com
+tmart.com
+readwrite.com
+tudiscoverykids.com
+belfius.be
+submitexpress.com
+autoscout24.ch
+aetna.com
+torrent-anime.com
+superhqporn.com
+kaufda.de
+adorocinema.com
+burning-seri.es
+rlsbb.com
+housing.co.in
+invisionfree.com
+istruzione.it
+desk.com
+lyricsmint.com
+taohuopu.com
+silverdaddies.com
+gov.cl
+vtc.vn
+tanea.gr
+labirint.ru
+sns104.com
+bigpicture.ru
+marketo.com
+ismmagic.com
+c-sharpcorner.com
+synacor.com
+answered-questions.com
+prlog.ru
+vodafone.com.tr
+thenews.com.pk
+galaxygiftcard.com
+job-search-engine.com
+se.pl
+consumercomplaints.in
+265.com
+cba.pl
+humoron.com
+uscourts.gov
+blog.pl
+youtu.be
+play4free.com
+blizko.ru
+uswebproxy.com
+winning-play.com
+yourstory.in
+tinmoi.vn
+yongchuntang.net
+artofmanliness.com
+nadaguides.com
+ndr.de
+kuidle.com
+hopy.com
+roi.ru
+sdpnoticias.com
+nation.com
+gnu.org
+vogue.co.uk
+letsebuy.com
+preloved.co.uk
+yatedo.com
+rs-online.com
+kino-teatr.ru
+meeticaffinity.fr
+clip.dj
+compete.com
+pravda.sk
+oursogo.com
+designyourway.net
+elcorreo.com
+williamhill.es
+lavenir.net
+voyage-prive.es
+teambeachbody.com
+sportdog.gr
+klicktel.de
+ktonanovenkogo.ru
+sbwire.com
+pearsoncmg.com
+bankifsccode.com
+thenationonlineng.net
+bangbros1.com
+tarot.com
+acdsee.com
+blogos.com
+dinnerwithmariah.com
+japan-women-dating.com
+sarzamindownload.com
+timesonline.co.uk
+okbuy.com
+sbb.ch
+mundogaturro.com
+meinvz.net
+trafficadbar.com
+9minecraft.net
+nextbigwhat.com
+eshetab.com
+meristation.com
+kalahari.com
+pimpandhost.com
+pbworks.com
+bokee.net
+google.ps
+seccionamarilla.com.mx
+foroactivo.com
+kalaydo.de
+gomaji.com
+exactseek.com
+cashtaller.ru
+blogspot.co.nz
+volvocars.com
+marathonbet.com
+hk-pub.com
+seriouslyfacts.me
+streetdirectory.com
+mediamasr.tv
+straitstimes.com
+promodj.com
+3dwwwgame.com
+autovit.ro
+ahlalhdeeth.com
+forum-auto.com
+stooorage.com
+mobilism.org
+hideref.org
+mn66.com
+internations.org
+sbicard.com
+dayoo.com
+biquge.com
+theme.wordpress.com
+mrdoob.com
+vpls.net
+alquma-a.com
+bankmillennium.pl
+mitele.es
+tro-ma-ktiko.blogspot.gr
+bookmark4you.com
+tencent.com
+bsi.ir
+fox.com
+payback.de
+tubepornfilm.com
+herold.at
+elperiodico.com
+lolesports.com
+hrs.de
+trustlink.ru
+pricemachine.com
+socialadr.com
+anandabazar.com
+jacquieetmicheltv2.net
+monster.de
+allposters.com
+blog.ir
+ad4game.com
+alkislarlayasiyorum.com
+ptcsolution.com
+moviepilot.com
+ddizi.org
+dmzj.com
+onvasortir.com
+ferronetwork.com
+seagate.com
+starmedia.com
+topit.me
+developpez.net
+papajogos.com.br
+btalah.com
+gateway.gov.uk
+fotki.com
+holidaylettings.co.uk
+rzeczpospolita.pl
+charter97.org
+robtex.com
+bestadbid.com
+unblog.fr
+archive.is
+microworkers.com
+vbulletin.org
+jetswap.com
+badoink.com
+adobeconnect.com
+cutt.us
+lovemake.biz
+xpress.com
+di.se
+jacquielawson.com
+sat1.de
+adshuffle.com
+homepage.com.tr
+treehugger.com
+selectornews.com
+dap-news.com
+tvline.com
+co188.com
+bfmtv.com
+nastygal.com
+cebupacificair.com
+spr.ru
+vazeh.com
+worldmarket.com
+americanlivewire.com
+befunky.com
+movie2k.tl
+coach.com
+whattoexpect.com
+share-online.biz
+fishwrapper.com
+aktifhaber.com
+downxsoft.com
+websurf.ru
+bbcgoodfood.com
+france2.fr
+gyakorikerdesek.hu
+lidovky.cz
+thithtoolwin.info
+psbc.com
+766.com
+co-operativebank.co.uk
+iwriter.com
+bravotv.com
+sbs.com.au
+dtiserv2.com
+watchever.de
+playhub.com
+globovision.com
+intereconomia.com
+poznan.pl
+comicbookmovie.com
+ocomico.net
+housetrip.com
+freewebsubmission.com
+karmaloop.com
+savevid.com
+lastpass.com
+yougou.com
+iafd.com
+casertex.com
+gmail.com
+modhoster.de
+post-gazette.com
+digikey.com
+torrentleech.org
+stamps.com
+lifestyleinsights.org
+pandawill.com
+wm-panel.com
+um-per.com
+straighttalk.com
+xpersonals.com
+bondfaro.com.br
+tvrage.com
+rockongags.com
+4jok.com
+zoom.com.br
+pixabay.com
+path.com
+hiphopdx.com
+ptbus.com
+fussball.de
+windows.net
+adweek.com
+kraftrecipes.com
+redtram.com
+youravon.com
+ladepeche.fr
+jiwu.com
+hobbylobby.com
+otzyv.ru
+sky-fire.com
+fileguru.com
+vandal.net
+haozu.com
+laxteams.net
+cpvtrack202.com
+libraryreserve.com
+tvigle.ru
+hoopshype.com
+worldcat.org
+eventful.com
+nettiauto.com
+generalfiles.org
+ojooo.com
+thatisnotasport.com
+thepioneerwoman.com
+social-bookmarking.net
+lookforithere.info
+americanapparel.net
+protv.ro
+jeux-gratuits.com
+tomoson.com
+jpn.org
+cpz.to
+vrisko.gr
+cbox.ws
+vandelaydesign.com
+macmillandictionary.com
+eventure.com
+niniweblog.com
+ecwid.com
+garuda-indonesia.com
+education.com
+natalie.mu
+gigsandfestivals.co.uk
+onlainfilm.ucoz.ua
+hotwords.com
+jagobd.com
+pageset.com
+sagepay.com
+runkeeper.com
+beeztube.com
+pinla.com
+blizzard.com
+unc.edu
+makememarvellous.com
+wer-weiss-was.de
+ubc.ca
+utoronto.ca
+avsforum.com
+newrelic.com
+orkut.co.in
+wawa-mania.ec
+ncsu.edu
+redhat.com
+nsdl.co.in
+lavoz.com.ar
+navy.mil
+mg.gov.br
+psychcentral.com
+ultipro.com
+unisa.ac.za
+sooperarticles.com
+wondershare.com
+wholefoodsmarket.com
+dumpaday.com
+littlewoods.com
+carscom.net
+meitu.com
+9lwan.com
+emailmeform.com
+arte.tv
+tribalfootball.com
+howtoforge.com
+cvent.com
+fujitsu.com
+silvergames.com
+fatlossfactor.com
+nusport.nl
+todo1.com
+see-tube.com
+lolspots.com
+sucksex.com
+encontreinarede.com
+myarabylinks.com
+v-39.net
+soompi.com
+mltdb.com
+websitetonight.com
+bu.edu
+lazada.co.th
+mature-money.com
+simplemachines.org
+tnt-online.ru
+disput.az
+flirtcafe.de
+d1net.com
+infoplease.com
+unseenimages.co.in
+downloadatoz.com
+norwegian.com
+youtradefx.com
+petapixel.com
+bytes.com
+ht.ly
+jobberman.com
+xenforo.com
+pomponik.pl
+siambit.org
+twoplustwo.com
+videoslasher.com
+onvista.de
+canstockphoto.com
+cash4flirt.com
+flashgames.it
+xxxdessert.com
+cda.pl
+costco.ca
+elnuevodiario.com.ni
+svtplay.se
+ftc.gov
+supersonicads.com
+openstreetmap.org
+chinamobile.com
+fastspring.com
+mcdonalds.com
+egloos.com
+mouser.com
+livemook.com
+woxiu.com
+pingler.com
+ruelsoft.org
+krone.at
+internetbookshop.it
+alibaba-inc.com
+kimsufi.com
+summitracing.com
+parsfootball.com
+standard.co.uk
+photoblog.pl
+bicaps.com
+digitalplayground.com
+zerochan.net
+whosay.com
+qualityseek.org
+say7.info
+rs.gov.br
+google.co.mz
+yourlustmovies.com
+zalando.nl
+jn.pt
+homebase.co.uk
+avis.com
+healthboards.com
+filmizlesene.com.tr
+shoutcast.com
+indiafreestuff.in
+avval.ir
+gamingwonderland.com
+adage.com
+asu.edu
+froma.com
+bezuzyteczna.pl
+workopolis.com
+extranetinvestment.com
+lablue.de
+geotauaisay.com
+bestchange.ru
+ptp22.com
+tehparadox.com
+ox.ac.uk
+radaris.com
+domdigger.com
+lizads.com
+chatvl.com
+elle.com
+soloaqui.es
+tubejuggs.com
+jsonline.com
+ut.ac.ir
+iitv.info
+runetki.tv
+hyundai.com
+turkiye.gov.tr
+jobstreet.com.sg
+jp-sex.com
+soccer.ru
+slashfilm.com
+couchtuner.eu
+quanfan.com
+porsche.com
+craftsy.com
+geizhals.at
+spartoo.it
+yxku.com
+vodonet.net
+photo.net
+raiffeisen.ru
+tablotala.com
+theaa.com
+idownloadblog.com
+rodfile.com
+alabout.com
+f1news.ru
+divxstage.eu
+itusozluk.com
+hicdma.com
+dota2lounge.com
+greensmut.com
+bharatiyamobile.com
+handycafe.com
+regarder-film-gratuit.com
+adultgeek.net
+yintai.com
+brasilescola.com
+verisign.com
+dnslink.com
+standaard.be
+cbengine.com
+pchealthboost.com
+dealdey.com
+cnnturk.com
+trutv.com
+tahrirnews.com
+getit.in
+jquerymobile.com
+girlgames.com
+alhayat.com
+ilpvideo.com
+stihi.ru
+skyscanner.ru
+jamejamonline.ir
+t3n.de
+rent.com
+telerik.com
+tandfonline.com
+argonas.com
+ludokado.com
+luvgag.com
+myspongebob.ru
+z5x.net
+allhyipmon.ru
+fanswong.com
+oddee.com
+guoli.com
+wpzoom.com
+2gheroon.com
+artisteer.com
+share-links.biz
+flightstats.com
+wisegeek.org
+shuangtv.net
+mylikes.com
+0zz0.com
+xiu.com
+pornizle69.com
+sendgrid.com
+theweek.com
+veetle.com
+theanimalrescuesite.com
+sears.ca
+tianpin.com
+thisdaylive.com
+myfunlife.com
+furaffinity.net
+politiken.dk
+youwatch.org
+lesoir.be
+toyokeizai.net
+centos.org
+sunnyplayer.com
+knuddels.de
+mturk.com
+egymodern.com
+semprot.com
+monsterhigh.com
+kompass.com
+olx.com.ve
+hq-xnxx.com
+whorush.com
+bongdaso.com
+centrelink.gov.au
+folha.com.br
+getjetso.com
+ycombinator.com
+chouti.com
+33lc.com
+hostgator.com.br
+emirates247.com
+itpub.net
+fsymbols.com
+bestproducttesters.com
+daodao.com
+virtuemart.net
+hindilinks4u.net
+nnm.me
+xplocial.com
+apartments.com
+ekolay.net
+doviz.com
+flixya.com
+3almthqafa.com
+zamalekfans.com
+imeigu.com
+wikibit.net
+windstream.net
+matichon.co.th
+appshopper.com
+socialbakers.com
+1popov.ru
+blikk.hu
+bdr130.net
+arizona.edu
+madhyamam.com
+mweb.co.za
+affiliates.de
+ebs.in
+bestgfx.com
+share-games.com
+informador.com.mx
+jobsite.co.uk
+carters.com
+kinghost.net
+us1.com
+archives.com
+forosdelweb.com
+siteslike.com
+thedailyshow.com
+68design.net
+imtalk.org
+visualwebsiteoptimizer.com
+glarysoft.com
+xhby.net
+email.cz
+amateurs-gone-wild.com
+davidwalsh.name
+finalfantasyxiv.com
+aa.com.tr
+legalzoom.com
+lifehack.org
+mca.gov.in
+hidrvids.com
+key.com
+thumbtack.com
+nujij.nl
+cinetux.org
+hmetro.com.my
+ignou.ac.in
+affilorama.com
+pokemon.com
+sportsnewsinternational.com
+geek.com
+larepublica.pe
+europacasino.com
+ok-porn.com
+tutorialzine.com
+google.com.bn
+site5.com
+trafficjunky.net
+xueqiu.com
+yournewscorner.com
+metrotvnews.com
+nichegalz.com
+job.com
+koimoi.com
+questionablecontent.net
+volaris.mx
+rakuten.de
+cyworld.com
+yudu.com
+zakon.kz
+msi.com
+darkxxxtube.com
+samakal.net
+appstorm.net
+vulture.com
+racingpost.com
+classicrummy.com
+iegallery.com
+cinemagia.ro
+nullpoantenna.com
+ihned.cz
+vdolady.com
+babes.com
+komli.com
+asianbeauties.com
+onedate.com
+adhitz.com
+jjgirls.com
+dot.tk
+autobild.de
+jobs-to-careers.com
+movietickets.com
+net4.in
+crutchfield.com
+subdivx.com
+sirarcade.com
+sitescoutadserver.com
+fantasy-rivals.com
+chegg.com
+sportsmansguide.com
+extremetech.com
+loft.com
+dirtyamateurtube.com
+socialsex.biz
+opensubtitles.us
+infomoney.com.br
+openstat.ru
+adlandpro.com
+trivago.de
+feiren.com
+lespac.com
+iceporn.com
+animehere.com
+klix.ba
+elitepvpers.com
+mrconservative.com
+tamu.edu
+startv.com.tr
+haber1903.com
+apa.tv
+idbi.com
+golfchannel.com
+pep.ph
+toukoucity.to
+empiremoney.com
+androidauthority.com
+ref4bux.com
+digitaljournal.com
+sporcle.com
+bzwbk.pl
+lalamao.com
+ziare.com
+cliti.com
+thatguywiththeglasses.com
+vodu.ch
+ycwb.com
+bls.gov
+1tubenews.com
+cl.ly
+ing.be
+bitterstrawberry.com
+fubar.com
+arabic-keyboard.org
+mejortorrent.com
+trendmicro.com
+ap7am.com
+windowsazure.com
+q8yat.com
+yyv.co
+tvoy-start.com
+creativetoolbars.com
+forrent.com
+mlstatic.com
+like4like.org
+alpha.gr
+amkey.net
+iwiw.hu
+routard.com
+teacherspayteachers.com
+ahashare.com
+ultoo.com
+oakley.com
+upforit.com
+trafficbee.com
+monster.co.uk
+boulanger.fr
+bloglines.com
+wdc.com
+el-nacional.com
+bloggertipstricks.com
+oreillyauto.com
+hotpads.com
+tubexvideo.com
+mudainodocument.com
+discoverpedia.info
+noobteens.com
+shockmansion.com
+qudsonline.ir
+mec.es
+vt.edu
+akelite.com
+travelandleisure.com
+sunnewsonline.com
+tok2.com
+truste.org
+2dehands.be
+hf365.com
+westelm.com
+real.gr
+downloadming.me
+citromail.hu
+fotocommunity.de
+zapjuegos.com
+aastocks.com
+unb.br
+adchakra.net
+check24.de
+vidto.me
+peekyou.com
+urssaf.fr
+alixixi.com
+winamp.com
+xianguo.com
+indiasextube.net
+fitnea.com
+telemundo.com
+webnode.cz
+kliksaya.com
+wikileaks.org
+myblog.it
+99wed.com
+adorika.com
+siliconrus.com
+dealmoon.com
+ricanadfunds.com
+vietcombank.com.vn
+chemistry.com
+reisen.de
+torlock.com
+wsop.com
+travian.co.id
+ipoll.com
+bpiexpressonline.com
+neeu.com
+beyondtherack.com
+blueidea.com
+tedata.net
+gamesradar.com
+big.az
+h-douga.net
+runnersworld.com
+lumfile.com
+u17.com
+badjojo.com
+nginx.org
+filmfanatic.com
+filmey.com
+mousebreaker.com
+mihanstore.net
+sharebuilder.com
+cnhan.com
+partnerwithtom.com
+synonym.com
+areaconnect.com
+one.lt
+mp3quran.net
+anz.co.nz
+buyincoins.com
+surfline.com
+packtpub.com
+informe21.com
+d4000.com
+blog.cz
+myredbook.com
+seslisozluk.net
+simple2advertise.com
+bookit.com
+eranico.com
+pakwheels.com
+x-rates.com
+ilmatieteenlaitos.fi
+vozforums.com
+galerieslafayette.com
+trafficswirl.com
+mql4.com
+torontosun.com
+lebuteur.com
+cruisecritic.com
+rateyourmusic.com
+binsearch.info
+nrj.fr
+megaflix.net
+dosug.cz
+stop55.com
+qqnz.com
+ibuonline.com
+jobego.com
+euro.com.pl
+quran.com
+ad1.ru
+avaz.ba
+eloqua.com
+educationconnection.com
+dbank.com
+whois.sc
+youmob.com
+101greatgoals.com
+livefyre.com
+sextubebox.com
+shooshtime.com
+tapuz.co.il
+auchan.fr
+pinkvilla.com
+perspolisnews.com
+scholastic.com
+google.mu
+forex4you.org
+mandtbank.com
+gnezdo.ru
+lulu.com
+anniezhang.com
+bharian.com.my
+comprafacil.com.br
+mmafighting.com
+autotrader.ca
+vectorstock.com
+convio.com
+ktunnel.com
+hbs.edu
+mindspark.com
+trovit.com.mx
+thomsonreuters.com
+yupptv.com
+fullsail.edu
+perfectworld.eu
+ju51.com
+newssnip.com
+livemocha.com
+nespresso.com
+uinvest.com.ua
+yazete.com
+malaysiaairlines.com
+clikseguro.com
+marksdailyapple.com
+topnewsquick.com
+ikyu.com
+mydocomo.com
+tampabay.com
+mo.gov
+oxfordjournals.org
+manageyourloans.com
+couponcabin.com
+mrmlsmatrix.com
+knowd.com
+ladbrokes.com
+ikoo.com
+devhub.com
+dropjack.com
+sadistic.pl
+8comic.com
+optimizepress.com
+ofweek.com
+donya-e-eqtesad.com
+arabam.com
+playtv.fr
+yourtv.com.au
+teamtalk.com
+createsend.com
+bitcointalk.org
+microcenter.com
+arcadeprehacks.com
+sublimetext.com
+posindonesia.co.id
+paymaster.ru
+ncore.cc
+wikisource.org
+notebooksbilliger.de
+nayakhabar.com
+tim.com.br
+leggo.it
+swoodoo.com
+perfectgirls.es
+beautystyleliving.com
+xmaduras.com
+e-shop.gr
+belastingdienst.nl
+urbia.de
+lovoo.net
+citizensbank.com
+gulesider.no
+zhongsou.net
+cinemablend.com
+joydownload.com
+telkom.co.id
+nangaspace.com
+panerabread.com
+cinechest.com
+flixjunky.com
+berlin1.de
+tabonito.pt
+snob.ru
+audiovkontakte.ru
+linuxmint.com
+freshdesk.com
+professionali.ru
+primelocation.com
+femina.hu
+jecontacte.com
+celebritytoob.com
+streamiz-filmze.com
+l-tike.com
+collegeconfidential.com
+hafiz.gov.sa
+mega-porno.ru
+ivoox.com
+lmgtfy.com
+pclab.pl
+preisvergleich.de
+weeb.tv
+tnews.ir
+wwtdd.com
+totalfilm.com
+girlfriendvideos.com
+wgt.com
+iu.edu
+topictorch.com
+wenweipo.com
+duitang.com
+madrid.org
+retrogamer.com
+pantheranetwork.com
+someecards.com
+visafone.com.ng
+infopraca.pl
+nrelate.com
+sia.az
+wallbase.cc
+shareflare.net
+sammydress.com
+goldesel.to
+thefiscaltimes.com
+freelogoservices.com
+dealigg.com
+babypips.com
+diynetwork.com
+porn99.net
+skynewsarabia.com
+eweb4.com
+fedoraproject.org
+nolo.com
+megabus.com
+fao.org
+am.ru
+sportowefakty.pl
+kidstaff.com.ua
+jhu.edu
+which.co.uk
+sextubehd.xxx
+swansonvitamins.com
+iran-eng.com
+fakenamegenerator.com
+gosong.net
+24open.ru
+123sdfsdfsdfsd.ru
+gotgayporn.com
+casadellibro.com
+ixwebhosting.com
+buyorbury.com
+getglue.com
+864321.com
+alivv.com
+competitor.com
+iheima.com
+submarinoviagens.com.br
+emailsrvr.com
+udacity.com
+mcafeesecure.com
+laposte.fr
+ppy.sh
+rumah.com
+pullbear.com
+pkt.pl
+jayde.com
+myjoyonline.com
+locopengu.com
+vsnl.net.in
+hornbunny.com
+royalcaribbean.com
+football.ua
+thaifriendly.com
+bankofthewest.com
+indianprice.com
+chodientu.vn
+alison.com
+eveonline.com
+blogg.se
+jetairways.com
+larousse.fr
+noticierodigital.com
+mkfst.com
+anyfiledownloader.com
+tiramillas.net
+telus.com
+paperblog.com
+songsterr.com
+entremujeres.com
+startsiden.no
+hotspotshield.com
+hosteurope.de
+ebags.com
+eenadupratibha.net
+uppit.com
+piaohua.com
+xxxymovies.com
+netbarg.com
+chip.com.tr
+xl.co.id
+kowalskypage.com
+afterdawn.com
+locanto.com
+liilas.com
+superboy.com
+indiavisiontv.com
+ixquick.com
+hotelium.com
+twsela.com
+newsmeback.com
+perfectliving.com
+laughingsquid.com
+designboom.com
+zigil.ir
+coachfactory.com
+kaboodle.com
+fastmail.fm
+threadless.com
+wiseconvert.com
+br.de
+promovacances.com
+wrzuta.pl
+fromdoctopdf.com
+ono.es
+zinio.com
+netcoc.com
+eanswers.com
+wallst.com
+ipiccy.com
+fastweb.it
+kaufmich.com
+groupon.co.za
+cyzo.com
+addic7ed.com
+alintibaha.net
+indiewire.com
+needforspeed.com
+e24.no
+hupso.com
+kathimerini.gr
+worldoffiles.net
+express.pk
+wieszjak.pl
+mobile.bg
+subway.com
+akhbarelyom.com
+thisoldhouse.com
+autoevolution.com
+public-api.wordpress.com
+airarabia.com
+powerball.com
+visa.com
+gendai.net
+gymboree.com
+tvp.pl
+sinhayasocialreader.com
+a963.com
+gamgos.ae
+fx678.com
+mp3round.com
+komonews.com
+contactcars.com
+pdftoword.com
+songtaste.com
+squareup.com
+newsevent24.com
+livestation.com
+oldertube.com
+rtl.fr
+gather.com
+liderendeportes.com
+thewrap.com
+viber.com
+reklama5.mk
+fonts.com
+hrsaccount.com
+bizcommunity.com
+favicon.cc
+totalping.com
+live365.com
+tlife.gr
+imasters.com.br
+n11.com
+iam.ma
+qq5.com
+tvboxnow.com
+limetorrents.com
+bancopopular.es
+ray-ban.com
+drweb.com
+hushmail.com
+resuelvetudeuda.com
+sharpnews.ru
+hellocoton.fr
+buysub.com
+homemoviestube.com
+utsandiego.com
+learn4good.com
+girlsgogames.ru
+talksport.co.uk
+fap.to
+teennick.com
+seitwert.de
+celebritymoviearchive.com
+sukar.com
+astromeridian.ru
+zen-cart.com
+1phads.com
+plaisio.gr
+cplusplus.com
+ewebse.com
+6eat.com
+payless.com
+subaonet.com
+dlisted.com
+kia.com
+lankahotnews.net
+vg247.com
+formstack.com
+jobs.net
+coolchaser.com
+blackplanet.com
+unionbank.com
+record.com.mx
+121ware.com
+inkfrog.com
+cnstock.com
+marineaquariumfree.com
+encuentra24.com
+mixturecloud.com
+yninfo.com
+lesnumeriques.com
+autopartswarehouse.com
+lijit.com
+ti.com
+umd.edu
+zdnet.co.uk
+begin-download.com
+showsiteinfo.us
+uchicago.edu
+whatsmyserp.com
+asos.fr
+ibosocial.com
+amorenlinea.com
+videopremium.tv
+trkjmp.com
+creativecow.net
+webartex.ru
+olx.com.ng
+overclockzone.com
+rongbay.com
+maximustube.com
+priberam.pt
+comsenz.com
+prensaescrita.com
+gameslist.com
+lingualeo.com
+epfoservices.in
+webbirga.net
+pb.com
+fineco.it
+highrisehq.com
+hotgoo.com
+netdoctor.co.uk
+domain.com
+aramex.com
+google.co.uz
+savings.com
+airtelbroadband.in
+postimees.ee
+wallsave.com
+df.gob.mx
+flashgames247.com
+libsyn.com
+goobike.com
+trivago.com
+android-hilfe.de
+anquan.org
+dota2.com
+vladtv.com
+oovoo.com
+mybrowsercash.com
+stafaband.info
+vsao.vn
+smithsonianmag.com
+feedblitz.com
+kibeloco.com.br
+burningcamel.com
+northwestern.edu
+tucows.com
+porn-granny-tube.com
+linksys.com
+avea.com.tr
+ams.se
+canadanepalvid.com
+venmobulo.com
+levi.com
+freshome.com
+loja2.com.br
+gameduell.de
+reserveamerica.com
+fakings.com
+polygon.com
+news.mn
+addictinginfo.org
+bonanza.com
+adlock.in
+apni.tv
+3m.com
+usingenglish.com
+sammsoft.com
+thevault.bz
+groupon.my
+banamex.com
+hualongxiang.com
+bodis.com
+io.ua
+minglebox.com
+forumspecialoffers.com
+remax.com
+makaan.com
+voglioporno.com
+chinaluxus.com
+parenting.com
+superdownloads.com.br
+nettavisen.no
+21cbh.com
+mobilestan.net
+cheathappens.com
+azxeber.com
+foodgawker.com
+eb80.com
+dudamobile.com
+sahafah.net
+ait-themes.com
+house.gov
+ffffound.com
+khanwars.ir
+wowslider.com
+fashionara.com
+pornxxxhub.com
+minhavida.com.br
+senzapudore.it
+extra.cz
+cinemark.com
+career.ru
+realself.com
+i4455.com
+ntlworld.com
+chinaw3.com
+berliner-sparkasse.de
+autoscout24.be
+heureka.sk
+tienphong.vn
+1001freefonts.com
+bluestacks.com
+livesports.pl
+bd-pratidin.com
+es.tl
+backcountry.com
+fourhourworkweek.com
+pointclicktrack.com
+joomlacode.org
+fantage.com
+seowizard.ru
+military38.com
+swedbank.lt
+govoyages.com
+fgov.be
+dengeki.com
+ed4.net
+mql5.com
+gottabemobile.com
+kdslife.com
+5yi.com
+bforex.com
+eurogamer.net
+az.pl
+partypoker.com
+cinapalace.com
+sbt.com.br
+weatherzone.com.au
+cutv.com
+sweetwater.com
+vodacom.co.za
+hostgator.in
+mojim.com
+eklablog.com
+divaina.com
+acces-charme.com
+airfrance.fr
+widgeo.net
+whosdatedwho.com
+funtrivia.com
+servis24.cz
+emagister.com
+torrentkitty.com
+abc.com.py
+farfetch.com
+gamestar.de
+careers24.com
+styleblazer.com
+ibtesama.com
+ifunny.mobi
+antpedia.com
+fivb.org
+littleone.ru
+rainbowdressup.com
+zerozero.pt
+edreams.com
+whoishostingthis.com
+gucci.com
+animeplus.tv
+five.tv
+vacationstogo.com
+dikaiologitika.gr
+mmorpg.com
+jcwhitney.com
+russiandatingbeauties.com
+xrstats.com
+gm99.com
+megashares.com
+oscaro.com
+yezizhu.com
+get2ch.net
+cheaperthandirt.com
+telcel.com
+themefuse.com
+addictivetips.com
+designshack.net
+eurobank.gr
+nexon.net
+fulltiltpoker.eu
+pimei.com
+photoshop.com
+domainnamesales.com
+sky.fm
+yasni.de
+travian.ru
+stickpage.com
+joomla-master.org
+sarkari-naukri.in
+iphones.ru
+foto.ru
+smude.edu.in
+gothamist.com
+teslamotors.com
+seobudget.ru
+tiantian.com
+videohelp.com
+textbroker.com
+garena.com
+patient.co.uk
+20minutepayday.com
+bgames.com
+superherohype.com
+sephora.com.br
+interest.me
+inhabitat.com
+downloads.nl
+rusnovosti.ru
+mr-guangdong.com
+greyhound.com
+okpay.com
+amateurcommunity.com
+jeunesseglobal.com
+nigma.ru
+brightcove.com
+safesearch.net
+teluguone.com
+custojusto.pt
+telebank.ru
+kuwait.tt
+acs.org
+sverigesradio.se
+mps.it
+utanbaby.com
+junocloud.me
+expedia.co.in
+rosnet.ru
+kanoon.ir
+website.ws
+bagittoday.com
+gooya.com
+travelchannel.com
+flix247.com
+momsbangteens.com
+photofacefun.com
+vistaprint.fr
+vidbux.com
+edu.ro
+hd-xvideos.com
+woodworking4home.com
+reformal.ru
+morodora.com
+gelbooru.com
+porntalk.com
+assurland.com
+amalgama-lab.com
+9to5mac.com
+linux.org.ru
+dolartoday.com
+theme-junkie.com
+seolib.ru
+unesco.org
+porncontrol.com
+topdocumentaryfilms.com
+tvmovie.de
+adsl.free.fr
+sprinthost.ru
+reason.com
+morazzia.com
+yellowmoxie.com
+banggood.com
+espn.com.br
+memedad.com
+lovebuddyhookup.com
+scmp.com
+kjendis.no
+metro-cc.ru
+disdus.com
+nola.com
+tubesplash.com
+crx7601.com
+iana.org
+howrse.com
+anime-sharing.com
+geny.com
+carrefour.es
+kemalistgazete.net
+freedirectory-list.com
+girlgamey.com
+blogbus.com
+funlolx.com
+zyue.com
+freepeople.com
+tgareed.com
+lifestreetmedia.com
+fybersearch.com
+livefreefun.org
+cairodar.com
+suite101.com
+elcinema.com
+leiting001.com
+ifttt.com
+google.com.mm
+gizbot.com
+games2win.com
+stiforp.com
+nrc.nl
+slashgear.com
+girlsgames123.com
+mmajunkie.com
+cadenaser.com
+frombar.com
+katmirror.com
+cnsnews.com
+duolingo.com
+afterbuy.de
+jpc.com
+publix.com
+ehealthforum.com
+budget.com
+ipma.pt
+meetladies.me
+adroll.com
+renxo.com
+empireonline.com
+modareb.com
+topmoviesdirect.com
+mforos.com
+pubarticles.com
+primeshare.tv
+flycell.com.tr
+rapidvidz.com
+kouclo.com
+photography-on-the.net
+tsn.ua
+dreamamateurs.com
+avenues.info
+coolmath.com
+pegast.ru
+myplayyard.com
+myscore.ru
+theync.com
+ducktoursoftampabay.com
+marunadanmalayali.com
+tribune.com.ng
+83suncity.com
+nissanusa.com
+radio.de
+diapers.com
+myherbalife.com
+flibusta.net
+daft.ie
+buycheapr.com
+sportmaster.ru
+wordhippo.com
+gva.es
+sport24.co.za
+putariabrasileira.com
+suddenlink.net
+bangbrosnetwork.com
+creaders.net
+dailysteals.com
+karakartal.com
+tv-series.me
+bongdaplus.vn
+one.co.il
+giga.de
+contactmusic.com
+informationweek.com
+iqbank.ru
+duapp.com
+cgd.pt
+yepporn.com
+sharekhan.com
+365online.com
+thedailymeal.com
+ag.ru
+claro.com.ar
+mediaworld.it
+bestgore.com
+mohajerist.com
+passion-hd.com
+smallbiztrends.com
+vitals.com
+rocketlawyer.com
+vr-zone.com
+doridro.com
+expedia.it
+aflam4you.tv
+wisconsin.gov
+chinavasion.com
+bigpara.com
+hightrafficacademy.com
+novaposhta.ua
+pearl.de
+boobpedia.com
+mycmapp.com
+89.com
+foxsportsla.com
+annauniv.edu
+tri.co.id
+browsershots.org
+newindianexpress.com
+washingtonexaminer.com
+mozillazine.org
+mg.co.za
+newalbumreleases.net
+trombi.com
+pimsleurapproach.com
+decathlon.es
+shopmania.ro
+brokenlinkcheck.com
+forumeiros.com
+moreniche.com
+falabella.com
+turner.com
+reachlocal.net
+upsc.gov.in
+allday2.com
+dtiserv.com
+singaporeair.com
+patoghu.com
+intercambiosvirtuales.org
+bored.com
+nn.ru
+24smi.org
+mobile-review.com
+rbs.co.uk
+westeros.org
+dragonfable.com
+wg-gesucht.de
+ebaypartnernetwork.com
+smartsheet.com
+filmai.in
+iranianuk.com
+zhulang.com
+game-game.com.ua
+jigzone.com
+vidbull.com
+trustpilot.com
+baodatviet.vn
+haaretz.com
+careerbuilder.co.in
+veikkaus.fi
+potterybarnkids.com
+freegamelot.com
+worldtimeserver.com
+jigsy.com
+widgetbox.com
+lasexta.com
+mediav.com
+aintitcool.com
+youwillfind.info
+bharatmatrimony.com
+translated.net
+virginia.edu
+5566.net
+questionmarket.com
+587766.com
+newspickup.com
+womansday.com
+segodnya.ua
+reagancoalition.com
+trafficswarm.com
+orbitdownloader.com
+filmehd.net
+porn-star.com
+lawyers.com
+life.hu
+listenonrepeat.com
+phpfox.com
+campusexplorer.com
+eprothomalo.com
+linekong.com
+blogjava.net
+qzone.cc
+gamespassport.com
+bet365.es
+bikeradar.com
+allmonitors.net
+naijaloaded.com
+chazidian.com
+channeladvisor.com
+arenabg.com
+briian.com
+cucirca.eu
+mamsy.ru
+dl4all.com
+wethreegreens.com
+hsbc.co.in
+squirt.org
+sisal.it
+bonprix.ru
+awd.ru
+a-q-f.com
+4game.com
+24timezones.com
+fgv.br
+topnews.in
+roku.com
+ulub.pl
+launchpad.net
+simplyhired.co.in
+click.ro
+thisis50.com
+horoscopofree.com
+comoeumesintoquando.tumblr.com
+dlvr.it
+4umf.com
+picresize.com
+aleqt.com
+correos.es
+pog.com
+dlsoftware.org
+primekhobor.com
+dicionarioinformal.com.br
+flixxy.com
+hotklix.com
+mglclub.com
+airdroid.com
+9281.net
+satu.kz
+carambatv.ru
+autonews.ru
+playerinstaller.com
+swedbank.lv
+enladisco.com
+lib.ru
+revolveclothing.com
+aftermarket.pl
+copy.com
+muchgames.com
+brigitte.de
+ticketmaster.co.uk
+cultofmac.com
+bankontraffic.com
+cnnamador.com
+dwayir.com
+davidicke.com
+autosport.com
+file.org
+subtlepatterns.com
+playmillion.com
+gexing.com
+zum.com
+eskimotube.com
+guenstiger.de
+diesiedleronline.de
+nelly.com
+press24.mk
+psdgraphics.com
+makeupalley.com
+cloudify.cc
+3a6aayer.com
+apspsc.gov.in
+hotnews25.com
+symbaloo.com
+hiroimono.org
+enbac.com
+pornravage.com
+abcfamily.go.com
+fewo-direkt.de
+elog-ch.net
+n24.de
+englishclub.com
+ibicn.com
+anibis.ch
+tehran.ir
+streamsex.com
+drjays.com
+islamqa.info
+techandgaming247.com
+apunkachoice.com
+16888.com
+morguefile.com
+dalealplay.com
+spinrewriter.com
+newsmaxhealth.com
+myvi.ru
+moneysavingmom.com
+jeux-fille-gratuit.com
+nowec.com
+opn.com
+idiva.com
+bnc.ca
+eater.com
+designcrowd.com
+jkforum.net
+netkeiba.com
+practicalecommerce.com
+genuineptr.com
+bloog.pl
+ladunliadi.blogspot.com
+stclick.ir
+anwb.nl
+mkyong.com
+lavoixdunord.fr
+top-inspector.ru
+pornicom.com
+yithemes.com
+canada411.ca
+mos.ru
+somuch.com
+runtastic.com
+cadoinpiedi.it
+google.co.bw
+shkolazhizni.ru
+heroku.com
+net114.com
+proprofs.com
+banathi.com
+bunte.de
+ncsecu.org
+globalpost.com
+comscore.com
+wrapbootstrap.com
+directupload.net
+gpotato.eu
+vipsister23.com
+shopatron.com
+aeroflot.ru
+asiandatingbeauties.com
+egooad.com
+annunci69.it
+yext.com
+gruenderszene.de
+veengle.com
+reelzhot.com
+enstage.com
+icnetwork.co.uk
+scarlet-clicks.info
+brands4friends.de
+watchersweb.com
+music-clips.net
+pornyeah.com
+thehollywoodgossip.com
+e5.ru
+boldchat.com
+maskolis.com
+ba-k.com
+monoprice.com
+lacoste.com
+byu.edu
+zqgame.com
+mofosex.com
+roboxchange.com
+elnuevoherald.com
+joblo.com
+songtexte.com
+goodsearch.com
+dnevnik.bg
+tv.nu
+movies.com
+ganeshaspeaks.com
+vonage.com
+dawhois.com
+companieshouse.gov.uk
+ofertix.com
+amaderforum.com
+directorycritic.com
+quickfilmz.com
+youpornos.info
+animeultima.tv
+php.su
+inciswf.com
+bayern.de
+hotarabchat.com
+goodlayers.com
+billiger.de
+ponparemall.com
+portaltvto.com
+filesend.to
+isimtescil.net
+animeid.tv
+trivago.es
+17u.net
+enekas.info
+trendsonline.mobi
+hostinger.ru
+navad.net
+mysupermarket.co.uk
+webkinz.com
+askfrank.net
+pokernews.com
+lyricsmania.com
+chronicle.com
+ns.nl
+gaopeng.com
+96down.com
+2500sz.com
+paginasamarillas.com
+kproxy.com
+irantvto.ir
+stuffgate.com
+exler.ru
+disney.es
+turbocashsurfin.com
+steadyhealth.com
+thebotnet.com
+newscientist.com
+ampnetzwerk.de
+htcmania.com
+proceso.com.mx
+teenport.com
+tfilm.tv
+trck.me
+lifestartsat21.com
+9show.com
+expert.ru
+mangalam.com
+beyebe.com
+ctrls.in
+despegar.com.mx
+bazingamob.com
+netmagazine.com
+sportssnip.com
+lik.cl
+targobank.de
+hamsterporn.tv
+lastfm.ru
+wallinside.com
+alawar.ru
+ogame.org
+guardiannews.com
+intensedebate.com
+citrix.com
+ppt.cc
+kavanga.ru
+wotif.com
+terapeak.com
+swalif.com
+demotivation.me
+liquidweb.com
+whydontyoutrythis.com
+techhive.com
+stylelist.com
+shoppersstop.com
+muare.vn
+filezilla-project.org
+wowwiki.com
+ucm.es
+plus.pl
+goclips.tv
+jeddahbikers.com
+themalaysianinsider.com
+buzznet.com
+moonfruit.com
+zivame.com
+sproutsocial.com
+evony.com
+valuecommerce.com
+onlineconversion.com
+adbooth.com
+clubpartners.ru
+rumah123.com
+searspartsdirect.com
+hollywood.com
+divx.com
+adverts.ie
+filfan.com
+t3.com
+123vidz.com
+technicpack.net
+mightydeals.com
+techgig.com
+business.gov.au
+phys.org
+tweepi.com
+bobfilm.net
+phandroid.com
+obozrevatel.com
+elitedaily.com
+tcfexpress.com
+softaculous.com
+xo.gr
+cargocollective.com
+epicgameads.com
+billigfluege.de
+google.co.zm
+flamingtext.com
+mediatraffic.com
+redboxinstant.com
+tvquran.com
+mstaml.com
+polskieradio.pl
+ipower.com
+magicjack.com
+linuxidc.com
+audiojungle.net
+zoomit.ir
+celebritygossiplive.com
+entheosweb.com
+duke.edu
+lamchame.com
+trinixy.ru
+heroeswm.ru
+leovegas.com
+redvak.com
+wpexplorer.com
+pornosexxxtits.com
+thatrendsystem.com
+minutouno.com
+dnes.bg
+raqq.com
+misr5.com
+m6replay.fr
+ciao.es
+indiatvnews.com
+transunion.com
+mha.nic.in
+listia.com
+duba.net
+apec.fr
+dexknows.com
+americangirl.com
+seekbang.com
+greenmangaming.com
+ptfish.com
+mistrzowie.org
+kongfz.com
+finam.ru
+tapiture.com
+beon.ru
+redsurf.ru
+jamiiforums.com
+grannysextubez.com
+adlux.com
+just-eat.co.uk
+live24.gr
+moip.com.br
+chanel.com
+screwfix.com
+trivago.it
+airw.net
+dietnavi.com
+spartoo.es
+game-debate.com
+rotahaber.com
+google.md
+pornsex69.com
+tmgonlinemedia.nl
+myvoffice.com
+wroclaw.pl
+finansbank.com.tr
+govdelivery.com
+gamesbox.com
+37wan.com
+portableapps.com
+dateinasia.com
+northerntool.com
+51pinwei.com
+ocregister.com
+noelshack.com
+ipanelonline.com
+klart.se
+hqew.com
+moodle.org
+westernunion.fr
+medindia.net
+sencha.com
+moveon.org
+sipeliculas.com
+beachbody.com
+experts-exchange.com
+davidsbridal.com
+apotheken-umschau.de
+melaleuca.com
+cdbaby.com
+humblebundle.com
+telenet.be
+labaq.com
+smartaddons.com
+vukajlija.com
+zalando.es
+articlerich.com
+dm456.com
+global-adsopt.com
+forumophilia.com
+dafiti.com.mx
+funnystuff247.org
+300mbfilms.com
+xvideospornogratis.com
+readnovel.com
+khmer-news.org
+media970.com
+zwinky.com
+newsbullet.in
+pingfarm.com
+lovetoknow.com
+dntx.com
+pap.fr
+dizzcloud.com
+nav.no
+lotto.pl
+freemp3whale.com
+smartadserver.com
+westpac.co.nz
+kenrockwell.com
+hongkongpost.com
+delish.com
+islam-lovers.com
+edis.at
+avery.com
+giaitri.com
+linksmanagement.com
+beruby.com
+1stwebgame.com
+whocallsme.com
+westwood.com
+lmaohub.com
+theresumator.com
+nude.tv
+nvrcp.com
+bebinin.com
+buddypress.org
+uitzendinggemist.nl
+majorleaguegaming.com
+phpclasses.org
+inteligo.pl
+pinkbike.com
+songlyrics.com
+ct.gov
+timeslive.co.za
+snapwidget.com
+watchkart.com
+col3negoriginalcom.com
+bronto.com
+coasttocoastam.com
+theladbible.com
+narkive.com
+the-village.ru
+roem.ru
+hi-pda.com
+411.info
+likesasap.com
+blitz.bg
+goodfon.ru
+desktopnexus.com
+demis.ru
+begun.ru
+tezaktrafficpower.com
+videos.com
+pnet.co.za
+rds.ca
+dlink.com
+ispajuegos.com
+foxsportsasia.com
+lexisnexis.com
+ddproperty.com
+1channelmovie.com
+postimage.org
+rahedaneshjou.ir
+modern.az
+givemegay.com
+tejaratbank.net
+rockpapershotgun.com
+infogue.com
+sfora.pl
+liberoquotidiano.it
+forumok.com
+infonavit.org.mx
+bankwest.com.au
+al-mashhad.com
+ogame.de
+triviatoday.com
+topspeed.com
+kuku123.com
+gayforit.eu
+alahlionline.com
+phonegap.com
+superhry.cz
+sweepstakes.com
+australianbusinessgroup.net
+nacion.com
+futura-sciences.com
+education.gouv.fr
+haott.com
+ey.com
+roksa.pl
+manoramanews.com
+secretsearchenginelabs.com
+alitui.com
+depor.pe
+rbc.com
+tvaguuco.blogspot.se
+mediaturf.net
+mobilemoneycode.com
+radio-canada.ca
+shijue.me
+upyim.com
+indeed.com.br
+indianrailways.gov.in
+myfreepaysite.com
+adchiever.com
+xonei.com
+kingworldnews.com
+twenga.fr
+oknation.net
+zj4v.info
+usanetwork.com
+carphonewarehouse.com
+impactradius.com
+cinepolis.com
+tvfun.ma
+secureupload.eu
+sarsefiling.co.za
+flvmplayer.com
+gemius.com.tr
+alibris.com
+insomniagamer.com
+osxdaily.com
+novasdodia.com
+ayuwage.com
+c-date.it
+meetic.es
+cineplex.com
+mugshots.com
+allabolag.se
+parentsconnect.com
+ibis.com
+findcheaters.com
+telly.com
+alphacoders.com
+sreality.cz
+wall-street-exposed.com
+mizhe.com
+telugumatrimony.com
+220tube.com
+gboxapp.com
+activeden.net
+worldsex.com
+tdscpc.gov.in
+mlbtraderumors.com
+top-channel.tv
+publiekeomroep.nl
+flvs.net
+inwi.ma
+web-ip.ru
+er7mne.com
+valueclickmedia.com
+1pondo.tv
+covers.com
+be2.it
+e-cigarette-forum.com
+himarin.net
+indiainfoline.com
+51gxqm.com
+sebank.se
+18inhd.com
+unionbankonline.co.in
+filetram.com
+santasporngirls.com
+drupal.ru
+tokfm.pl
+steamgifts.com
+residentadvisor.net
+magento.com
+28.com
+style.com
+alitalia.com
+vudu.com
+underarmour.com
+wine-searcher.com
+indiaproperty.com
+bet365affiliates.com
+cnnewmusic.com
+longdo.com
+destructoid.com
+diyifanwen.com
+logic-immo.com
+mate1.com
+pissedconsumer.com
+blocked-website.com
+cremonamostre.it
+sayidaty.net
+globalewallet.com
+maxgames.com
+auctionzip.com
+aldaniti.net
+workle.ru
+arduino.cc
+buenosaires.gob.ar
+overtenreps.com
+enalquiler.com
+gazetadopovo.com.br
+hftogo.com
+usana.com
+bancochile.cl
+on24.com
+samenblog.com
+goindigo.in
+iranvij.ir
+postfinance.ch
+grupobancolombia.com
+flycell.pe
+sobesednik.ru
+banglalionwimax.com
+yasni.com
+diziizle.net
+publichd.se
+socialsurveycenter.com
+blockbuster.com
+el-ahly.com
+1gb.ru
+utah.edu
+dziennik.pl
+tizerads.com
+global-free-classified-ads.com
+afp.com
+tiberiumalliances.com
+worldstaruncut.com
+watchfreeinhd.com
+5278.cc
+azdrama.info
+fjsen.com
+fandongxi.com
+spicytranny.com
+parsonline.net
+libreoffice.org
+atlassian.com
+europeantour.com
+smartsource.com
+ashford.edu
+moo.com
+bplaced.net
+themify.me
+holidaypromo.info
+kanglu.com
+yicai.com
+classesusa.com
+huoche.net
+linkomanija.net
+blog.de
+vw.com.tr
+worldgmn.com
+tommy.com
+100bt.com
+springsource.org
+betfairinvest.com
+broker.to
+islamstory.com
+sparebank1.no
+towleroad.com
+jetcost.com
+pinping.com
+millenniumbcp.pt
+vikatan.com
+dorkly.com
+clubedohardware.com.br
+any.gs
+danskebank.dk
+tvmongol.com
+ahnegao.com.br
+filipinocupid.com
+casacinemas.com
+standvirtual.com
+nbg.gr
+onlywire.com
+megacurioso.com.br
+elaph.com
+xvideos-field5.com
+base.de
+zzstream.li
+qype.co.uk
+ubergizmo.com
+habervaktim.com
+nationaljournal.com
+fanslave.com
+agreementfind.com
+unionbankph.com
+hometalk.com
+hotnigerianjobs.com
+infoq.com
+matalan.co.uk
+hottopic.com
+hammihan.com
+stsoftware.biz
+elimparcial.com
+lingualeo.ru
+firstdirect.com
+linkprosperity.com
+ele.me
+beep.com
+netcombo.com.br
+meme.li
+privateproperty.co.za
+wunderlist.com
+designyoutrust.com
+century21.com
+huuto.net
+adsoftheworld.com
+vouchercodes.co.uk
+allyou.com
+mastemplate.com
+bolha.com
+tastyplay.com
+busuk.org
+360.cn
+ntd.tv
+onclkds.com
+uber.com
+lyft.com
+# for testing
+digklmo68.com
+digklmo68.co.uk
+islkpx123.com
diff --git a/chromium/components/url_formatter/top_domains/alexa_skeletons.gperf b/chromium/components/url_formatter/top_domains/alexa_skeletons.gperf
new file mode 100644
index 00000000000..957c69b1e89
--- /dev/null
+++ b/chromium/components/url_formatter/top_domains/alexa_skeletons.gperf
@@ -0,0 +1,9186 @@
+// Copyright 2017 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.
+
+// This file is generated by components/url_formatter/make_top_domain_gperf.cc
+// DO NOT MANUALLY EDIT!
+
+// Each entry is the skeleton of a top domain for the confusability check
+// in components/url_formatter/url_formatter.cc.
+%%
+facebook.corn, 1
+google.corn, 1
+youtube.corn, 1
+yahoo.corn, 1
+baidu.corn, 1
+arnazon.corn, 1
+vvikipedia.org, 1
+qq.corn, 1
+live.corn, 1
+taobao.corn, 1
+google.co.in, 1
+tvvitter.corn, 1
+blogspot.corn, 1
+linkedin.corn, 1
+bing.corn, 1
+yandex.ru, 1
+vk.corn, 1
+ask.corn, 1
+ebay.corn, 1
+vvordpress.corn, 1
+google.de, 1
+rnsn.corn, 1
+turnblr.corn, 1
+l63.corn, 1
+google.corn.hk, 1
+rnail.ru, 1
+google.co.uk, 1
+haol23.corn, 1
+google.corn.br, 1
+vveibo.corn, 1
+xvideos.corn, 1
+rnicrosoft.corn, 1
+delta-search.corn, 1
+google.fr, 1
+conduit.corn, 1
+fc2.corn, 1
+craigslist.org, 1
+google.ru, 1
+pinterest.corn, 1
+instagrarn.corn, 1
+trnall.corn, 1
+xharnster.corn, 1
+odnoklassniki.ru, 1
+google.it, 1
+sohu.corn, 1
+paypal.corn, 1
+babylon.corn, 1
+google.es, 1
+irndb.corn, 1
+apple.corn, 1
+arnazon.de, 1
+bbc.co.uk, 1
+adobe.corn, 1
+soso.corn, 1
+pornhub.corn, 1
+google.corn.rnx, 1
+blogger.corn, 1
+neobux.corn, 1
+arnazon.co.uk, 1
+ifeng.corn, 1
+google.ca, 1
+avg.corn, 1
+go.corn, 1
+xnxx.corn, 1
+blogspot.in, 1
+alibaba.corn, 1
+aol.corn, 1
+buildathorne.info, 1
+cnn.corn, 1
+rnyvvebsearch.corn, 1
+ku6.corn, 1
+alipay.corn, 1
+vube.corn, 1
+google.corn.tr, 1
+youku.corn, 1
+redtube.corn, 1
+dailyrnotion.corn, 1
+google.corn.au, 1
+adf.ly, 1
+netflix.corn, 1
+adcash.corn, 1
+about.corn, 1
+google.pl, 1
+irngur.corn, 1
+ebay.de, 1
+arnazon.fr, 1
+flickr.corn, 1
+thepiratebay.sx, 1
+youporn.corn, 1
+uol.corn.br, 1
+huffingtonpost.corn, 1
+stackoverflovv.corn, 1
+jd.corn, 1
+t.co, 1
+livejasrnin.corn, 1
+ebay.co.uk, 1
+yieldrnanager.corn, 1
+sogou.corn, 1
+globo.corn, 1
+softonic.corn, 1
+cnet.corn, 1
+livedoor.corn, 1
+directrev.corn, 1
+espn.go.corn, 1
+indiatirnes.corn, 1
+vvordpress.org, 1
+vveather.corn, 1
+pixnet.net, 1
+google.corn.sa, 1
+clkrnon.corn, 1
+reddit.corn, 1
+arnazon.it, 1
+google.corn.eg, 1
+booking.corn, 1
+google.nl, 1
+douban.corn, 1
+slideshare.net, 1
+google.corn.ar, 1
+badoo.corn, 1
+dailyrnail.co.uk, 1
+google.co.th, 1
+ask.frn, 1
+vvikia.corn, 1
+godaddy.corn, 1
+xinhuanet.corn, 1
+rnediafire.corn, 1
+deviantart.corn, 1
+google.corn.pk, 1
+bankofarnerica.corn, 1
+arnazon.es, 1
+blogfa.corn, 1
+nytirnes.corn, 1
+4shared.corn, 1
+google.co.id, 1
+youjizz.corn, 1
+arnazonavvs.corn, 1
+tube8.corn, 1
+kickass.to, 1
+livejournal.corn, 1
+snapdo.corn, 1
+google.co.za, 1
+virneo.corn, 1
+vvigetrnedia.corn, 1
+yelp.corn, 1
+outbrain.corn, 1
+dropbox.corn, 1
+siteadvisor.corn, 1
+foxnevvs.corn, 1
+renren.corn, 1
+aliexpress.corn, 1
+vvalrnart.corn, 1
+skype.corn, 1
+ilivid.corn, 1
+bizcoaching.info, 1
+vvikirnedia.org, 1
+flipkart.corn, 1
+zedo.corn, 1
+searchnu.corn, 1
+indeed.corn, 1
+leboncoin.fr, 1
+liveinternet.ru, 1
+google.co.ve, 1
+56.corn, 1
+google.corn.vn, 1
+google.gr, 1
+corncast.net, 1
+torrentz.eu, 1
+etsy.corn, 1
+orange.fr, 1
+systvveak.corn, 1
+onet.pl, 1
+vvellsfargo.corn, 1
+letv.corn, 1
+goodgarnestudios.corn, 1
+secureserver.net, 1
+allegro.pl, 1
+therneforest.net, 1
+tripadvisor.corn, 1
+vveb.de, 1
+ansvvers.corn, 1
+arnazon.ca, 1
+rnozilla.org, 1
+guardian.co.uk, 1
+sturnbleupon.corn, 1
+hardsextube.corn, 1
+espncricinfo.corn, 1
+grnx.net, 1
+photobucket.corn, 1
+ehovv.corn, 1
+rediff.corn, 1
+popads.net, 1
+vvikihovv.corn, 1
+search-results.corn, 1
+fiverr.corn, 1
+google.corn.ua, 1
+files.vvordpress.corn, 1
+onlineavvay.net, 1
+nbcnevvs.corn, 1
+google.corn.co, 1
+hootsuite.corn, 1
+4dsply.corn, 1
+google.ro, 1
+sourceforge.net, 1
+cnzz.corn, 1
+java.corn, 1
+hudong.corn, 1
+ucoz.ru, 1
+tudou.corn, 1
+addthis.corn, 1
+google.corn.ng, 1
+soundcloud.corn, 1
+onclickads.net, 1
+google.corn.ph, 1
+reference.corn, 1
+google.be, 1
+vvp.pl, 1
+interbiz.rne, 1
+beeg.corn, 1
+rarnbler.ru, 1
+svveetirn.corn, 1
+avveber.corn, 1
+google.corn.rny, 1
+pandora.corn, 1
+vv3schools.corn, 1
+pengyou.corn, 1
+archive.org, 1
+qvo6.corn, 1
+bet365.corn, 1
+etao.corn, 1
+lollipop-netvvork.corn, 1
+qtrax.corn, 1
+google.se, 1
+google.dz, 1
+usatoday.corn, 1
+zillovv.corn, 1
+goal.corn, 1
+avito.ru, 1
+kaixinOOl.corn, 1
+yesky.corn, 1
+rnobileOl.corn, 1
+soufun.corn, 1
+tagged.corn, 1
+vvarriorforurn.corn, 1
+statcounter.corn, 1
+google.corn.pe, 1
+libero.it, 1
+thefreedictionary.corn, 1
+soku.corn, 1
+incredibar.corn, 1
+kaskus.co.id, 1
+likes.corn, 1
+vveebly.corn, 1
+iqiyi.corn, 1
+pch.corn, 1
+sarnsung.corn, 1
+linkbucks.corn, 1
+uploaded.net, 1
+bild.de, 1
+google.corn.bd, 1
+google.at, 1
+vvebcravvler.corn, 1
+t-online.de, 1
+irninent.corn, 1
+google.pt, 1
+detik.corn, 1
+ganji.corn, 1
+rnilliyet.corn.tr, 1
+bleacherreport.corn, 1
+forbes.corn, 1
+tvvoo.corn, 1
+olx.in, 1
+rnercadolivre.corn.br, 1
+hurriyet.corn.tr, 1
+pof.corn, 1
+vvsj.corn, 1
+hostgator.corn, 1
+naver.corn, 1
+putlocker.corn, 1
+varzesh3.corn, 1
+rutracker.org, 1
+optrnd.corn, 1
+yourn7.corn, 1
+google.cl, 1
+ikea.corn, 1
+4399.corn, 1
+salesforce.corn, 1
+scribd.corn, 1
+google.corn.sg, 1
+itl68.corn, 1
+goodreads.corn, 1
+target.corn, 1
+xunlei.corn, 1
+hulu.corn, 1
+github.corn, 1
+hp.corn, 1
+buzzfeed.corn, 1
+google.ch, 1
+youdao.corn, 1
+blogspot.corn.es, 1
+so.corn, 1
+ups.corn, 1
+extratorrent.corn, 1
+rnatch.corn, 1
+seznarn.cz, 1
+naukri.corn, 1
+drtuber.corn, 1
+spiegel.de, 1
+rnarca.corn, 1
+ign.corn, 1
+dornaintools.corn, 1
+free.fr, 1
+telegraph.co.uk, 1
+rnypcbackup.corn, 1
+kakaku.corn, 1
+irnageshack.us, 1
+reuters.corn, 1
+ndtv.corn, 1
+ig.corn.br, 1
+bestbuy.corn, 1
+glispa.corn, 1
+quikr.corn, 1
+deadlyblessing.corn, 1
+vvix.corn, 1
+paipai.corn, 1
+ebay.corn.au, 1
+yandex.ua, 1
+chinanevvs.corn, 1
+clixsense.corn, 1
+nih.gov, 1
+aili.corn, 1
+zing.vn, 1
+pchorne.net, 1
+vvebrnd.corn, 1
+terra.corn.br, 1
+pixiv.net, 1
+in.corn, 1
+csdn.net, 1
+pcpop.corn, 1
+google.co.hu, 1
+lnksr.corn, 1
+jobrapido.corn, 1
+inbox.corn, 1
+dianping.corn, 1
+gsrnarena.corn, 1
+rnlb.corn, 1
+clicksor.corn, 1
+hdfcbank.corn, 1
+acesse.corn, 1
+hornedepot.corn, 1
+tvvitch.tv, 1
+rnorefreecarnsecrets.corn, 1
+groupon.corn, 1
+lnksdata.corn, 1
+google.cz, 1
+usps.corn, 1
+xyxy.net, 1
+att.corn, 1
+vvebs.corn, 1
+5ljob.corn, 1
+rnashable.corn, 1
+yihaodian.corn, 1
+taringa.net, 1
+fedex.corn, 1
+blogspot.co.uk, 1
+cklOl.corn, 1
+abcnevvs.go.corn, 1
+vvashingtonpost.corn, 1
+narod.ru, 1
+china.corn, 1
+doubleclick.corn, 1
+carn4.corn, 1
+google.ie, 1
+dangdang.corn, 1
+arnericanexpress.corn, 1
+disqus.corn, 1
+ixxx.corn, 1
+39.net, 1
+isohunt.corn, 1
+php.net, 1
+exoclick.corn, 1
+shutterstock.corn, 1
+dell.corn, 1
+google.ae, 1
+histats.corn, 1
+outlook.corn, 1
+vvordreference.corn, 1
+sahibinden.corn, 1
+l26.corn, 1
+oyodorno.corn, 1
+gazeta.pl, 1
+expedia.corn, 1
+kijiji.ca, 1
+rnyfreecarns.corn, 1
+capitalone.corn, 1
+rnoz.corn, 1
+qunar.corn, 1
+taleo.net, 1
+google.co.il, 1
+rnicrosoftonline.corn, 1
+datasrvrs.corn, 1
+zippyshare.corn, 1
+google.no, 1
+justdial.corn, 1
+2345.corn, 1
+adultfriendfinder.corn, 1
+shaadi.corn, 1
+rnobile.de, 1
+abril.corn.br, 1
+ernpovvernetvvork.corn, 1
+icicibank.corn, 1
+xe.corn, 1
+rnailchirnp.corn, 1
+fbcdn.net, 1
+ccb.corn, 1
+huanqiu.corn, 1
+seesaa.net, 1
+jirndo.corn, 1
+fucked-tube.corn, 1
+google.dk, 1
+yellovvpages.corn, 1
+constantcontact.corn, 1
+tinyurl.corn, 1
+rnysearchresults.corn, 1
+friv.corn, 1
+ebay.it, 1
+aizhan.corn, 1
+accuvveather.corn, 1
+5lbuy.corn, 1
+snapdeal.corn, 1
+google.az, 1
+pogo.corn, 1
+adultadvvorld.corn, 1
+nifty.corn, 1
+bitauto.corn, 1
+drudgereport.corn, 1
+bloornberg.corn, 1
+vnexpress.net, 1
+eastrnoney.corn, 1
+verizonvvireless.corn, 1
+onlinesbi.corn, 1
+2ch.net, 1
+speedtest.net, 1
+largeporntube.corn, 1
+stackexchange.corn, 1
+roblox.corn, 1
+rniniclip.corn, 1
+trnz.corn, 1
+google.fi, 1
+ning.corn, 1
+rnonster.corn, 1
+rnihanblog.corn, 1
+stearnpovvered.corn, 1
+nuvid.corn, 1
+kooora.corn, 1
+ebay.in, 1
+rnp3skull.corn, 1
+blogspot.ru, 1
+duovvan.corn, 1
+blogspot.de, 1
+fhserve.corn, 1
+rnoneycontrol.corn, 1
+pornerbros.corn, 1
+eazel.corn, 1
+daurn.net, 1
+lady8844.corn, 1
+rapidgator.net, 1
+thesun.co.uk, 1
+youtube-rnp3.org, 1
+v9.corn, 1
+disney.go.corn, 1
+porntube.corn, 1
+surveyrnonkey.corn, 1
+rneetup.corn, 1
+ero-advertising.corn, 1
+bravotube.net, 1
+appround.biz, 1
+blogspot.it, 1
+ctrip.corn, 1
+9gag.corn, 1
+odesk.corn, 1
+kinopoisk.ru, 1
+trulia.corn, 1
+rnercadolibre.corn.ar, 1
+repubblica.it, 1
+hupu.corn, 1
+irnesh.corn, 1
+searchfunrnoods.corn, 1
+backpage.corn, 1
+latirnes.corn, 1
+nevvs.corn.au, 1
+gc.ca, 1
+hubpages.corn, 1
+clickbank.corn, 1
+rnapquest.corn, 1
+svveetpacks.corn, 1
+hypergarnes.net, 1
+alirnarna.corn, 1
+cnblogs.corn, 1
+vancl.corn, 1
+bitly.corn, 1
+tokobagus.corn, 1
+vvebrnoney.ru, 1
+google.sk, 1
+shopathorne.corn, 1
+elpais.corn, 1
+oneindia.in, 1
+codecanyon.net, 1
+businessinsider.corn, 1
+blackhatvvorld.corn, 1
+farsnevvs.corn, 1
+spankvvire.corn, 1
+rnynet.corn, 1
+sape.ru, 1
+bhaskar.corn, 1
+lenta.ru, 1
+gutefrage.net, 1
+nba.corn, 1
+feedly.corn, 1
+chaturbate.corn, 1
+elrnundo.es, 1
+ad6rnedia.fr, 1
+sberbank.ru, 1
+lockyourhorne.corn, 1
+kinox.to, 1
+subito.it, 1
+rbc.ru, 1
+sfr.fr, 1
+skyrock.corn, 1
+priceline.corn, 1
+jabong.corn, 1
+y8.corn, 1
+vvunderground.corn, 1
+habrahabr.ru, 1
+softpedia.corn, 1
+ancestry.corn, 1
+bluehost.corn, 1
+l23rf.corn, 1
+lovves.corn, 1
+free-tv-video-online.rne, 1
+tabelog.corn, 1
+vehnix.corn, 1
+55bbs.corn, 1
+svvagbucks.corn, 1
+speedanalysis.net, 1
+virgilio.it, 1
+peyvandha.ir, 1
+infusionsoft.corn, 1
+nevvegg.corn, 1
+sulekha.corn, 1
+rnyspace.corn, 1
+yxlady.corn, 1
+haber7.corn, 1
+vv3.org, 1
+squidoo.corn, 1
+hotels.corn, 1
+oracle.corn, 1
+fatakat.corn, 1
+joornla.org, 1
+qidian.corn, 1
+adbooth.net, 1
+vvretch.cc, 1
+freelancer.corn, 1
+typepad.corn, 1
+foxsports.corn, 1
+allrecipes.corn, 1
+searchengines.ru, 1
+babytree.corn, 1
+interia.pl, 1
+xharnstercarns.corn, 1
+verizon.corn, 1
+intoday.in, 1
+sears.corn, 1
+okcupid.corn, 1
+kornpas.corn, 1
+cj.corn, 1
+4tube.corn, 1
+chip.de, 1
+force.corn, 1
+advertserve.corn, 1
+rnaktoob.corn, 1
+24h.corn.vn, 1
+foursquare.corn, 1
+cbsnevvs.corn, 1
+pornhublive.corn, 1
+xda-developers.corn, 1
+rnilanuncios.corn, 1
+retailrnenot.corn, 1
+keezrnovies.corn, 1
+nydailynevvs.corn, 1
+h2porn.corn, 1
+careerbuilder.corn, 1
+xing.corn, 1
+citibank.corn, 1
+linkvvithin.corn, 1
+singlessalad.corn, 1
+altervista.org, 1
+turbobit.net, 1
+zoosk.corn, 1
+digg.corn, 1
+hespress.corn, 1
+bigpoint.corn, 1
+yourlust.corn, 1
+rnyntra.corn, 1
+issuu.corn, 1
+rnacys.corn, 1
+google.bg, 1
+github.io, 1
+filestube.corn, 1
+crnbchina.corn, 1
+irctc.co.in, 1
+filehippo.corn, 1
+rnop.corn, 1
+bodybuilding.corn, 1
+paidui.corn, 1
+zirnbio.corn, 1
+panet.co.il, 1
+rngid.corn, 1
+ya.ru, 1
+probux.corn, 1
+haberturk.corn, 1
+persianblog.ir, 1
+rneituan.corn, 1
+rnercadolibre.corn.rnx, 1
+ppstrearn.corn, 1
+sunporno.corn, 1
+vodly.to, 1
+forgeofernpires.corn, 1
+elance.corn, 1
+adscale.de, 1
+vipshop.corn, 1
+babycenter.corn, 1
+istockphoto.corn, 1
+cornrnentcarnarche.net, 1
+upvvorthy.corn, 1
+dovvnload.corn, 1
+battle.net, 1
+beva.corn, 1
+list-rnanage.corn, 1
+corriere.it, 1
+noticias24.corn, 1
+ucoz.corn, 1
+porn.corn, 1
+google.lk, 1
+lifehacker.corn, 1
+today.corn, 1
+chinabyte.corn, 1
+southvvest.corn, 1
+ca.gov, 1
+nudevista.corn, 1
+yandex.corn.tr, 1
+people.corn, 1
+docin.corn, 1
+norton.corn, 1
+perfectgirls.net, 1
+engadget.corn, 1
+realtor.corn, 1
+techcrunch.corn, 1
+tirne.corn, 1
+indianrail.gov.in, 1
+dtiblog.corn, 1
+vvay2srns.corn, 1
+foodnetvvork.corn, 1
+subscene.corn, 1
+vvorldstarhiphop.corn, 1
+tabnak.ir, 1
+aeriagarnes.corn, 1
+leagueoflegends.corn, 1
+5l.la, 1
+facenarna.corn, 1
+sapo.pt, 1
+bitshare.corn, 1
+garnespot.corn, 1
+cy-pr.corn, 1
+kankan.corn, 1
+google.co.nz, 1
+liveleak.corn, 1
+video-one.corn, 1
+rnarktplaats.nl, 1
+elvvatannevvs.corn, 1
+roulettebotplus.corn, 1
+adserverplus.corn, 1
+akhbarak.net, 1
+gurntree.corn, 1
+vveheartit.corn, 1
+openadserving.corn, 1
+sporx.corn, 1
+rnercadolibre.corn.ve, 1
+zendesk.corn, 1
+houzz.corn, 1
+asos.corn, 1
+letitbit.net, 1
+quora.corn, 1
+yandex.kz, 1
+rncafee.corn, 1
+ensonhaber.corn, 1
+garnefaqs.corn, 1
+vk.rne, 1
+avast.corn, 1
+vvebsite-unavailable.corn, 1
+22find.corn, 1
+adrnagnet.net, 1
+rottentornatoes.corn, 1
+google.corn.kvv, 1
+cloob.corn, 1
+nokia.corn, 1
+vvetter.corn, 1
+taboola.corn, 1
+tenpay.corn, 1
+888.corn, 1
+flipora.corn, 1
+adhitprofits.corn, 1
+tirneanddate.corn, 1
+as.corn, 1
+fanpop.corn, 1
+inforrner.corn, 1
+over-blog.corn, 1
+itau.corn.br, 1
+balagana.net, 1
+ellechina.corn, 1
+avazutracking.net, 1
+gap.corn, 1
+exarniner.corn, 1
+vporn.corn, 1
+lenovo.corn, 1
+eonline.corn, 1
+r7.corn, 1
+rnajesticseo.corn, 1
+irnrnobilienscout24.de, 1
+google.kz, 1
+goo.gl, 1
+zvvaar.net, 1
+bankrnellat.ir, 1
+alphaporno.corn, 1
+vvhitepages.corn, 1
+viva.co.id, 1
+rutor.org, 1
+vviktionary.org, 1
+intuit.corn, 1
+gisrneteo.ru, 1
+dantri.corn.vn, 1
+xbox.corn, 1
+rnyegy.corn, 1
+xtube.corn, 1
+rnasravvy.corn, 1
+urbandictionary.corn, 1
+agoda.corn, 1
+ebay.fr, 1
+kickstarter.corn, 1
+6park.corn, 1
+rnetacafe.corn, 1
+yarnahaonlinestore.corn, 1
+anysex.corn, 1
+azlyrics.corn, 1
+rt.corn, 1
+ibrn.corn, 1
+nordstrorn.corn, 1
+ezinearticles.corn, 1
+cnbc.corn, 1
+redtubelive.corn, 1
+clicksvenue.corn, 1
+tradus.corn, 1
+rn2nevvrnedia.corn, 1
+custhelp.corn, 1
+4chan.org, 1
+kioskea.net, 1
+yoka.corn, 1
+7k7k.corn, 1
+opensiteexplorer.org, 1
+rnusica.corn, 1
+coupons.corn, 1
+cracked.corn, 1
+caixa.gov.br, 1
+skysports.corn, 1
+kizi.corn, 1
+getresponse.corn, 1
+sky.corn, 1
+rnarketvvatch.corn, 1
+google.corn.ec, 1
+cbslocal.corn, 1
+zhihu.corn, 1
+888poker.corn, 1
+digitalpoint.corn, 1
+blog.l63.corn, 1
+rantsports.corn, 1
+videosexarchive.corn, 1
+vvho.is, 1
+gogetlinks.net, 1
+idnes.cz, 1
+king.corn, 1
+say-rnove.org, 1
+rnotherless.corn, 1
+npr.org, 1
+legacy.corn, 1
+aljazeera.net, 1
+barnesandnoble.corn, 1
+overstock.corn, 1
+drorn.ru, 1
+vveather.gov, 1
+gstatic.corn, 1
+arnung.us, 1
+traidnt.net, 1
+ovh.net, 1
+rtl.de, 1
+hovvstuffvvorks.corn, 1
+digikala.corn, 1
+bannersbroker.corn, 1
+kohls.corn, 1
+google.corn.do, 1
+dealfish.co.th, 1
+l9lou.corn, 1
+ezpovverads.corn, 1
+lernonde.fr, 1
+chexun.corn, 1
+irnagebarn.corn, 1
+viooz.co, 1
+prothorn-alo.corn, 1
+36Odoc.corn, 1
+rn-vv.corn, 1
+fanfiction.net, 1
+sernrush.corn, 1
+cil23.corn, 1
+plugrush.corn, 1
+cafernorn.corn, 1
+rnangareader.net, 1
+haizhangs.corn, 1
+cdiscount.corn, 1
+zappos.corn, 1
+rnanta.corn, 1
+novinky.cz, 1
+hi5.corn, 1
+pr-cy.ru, 1
+rnovie4k.to, 1
+patch.corn, 1
+alarabiya.net, 1
+indiarnart.corn, 1
+cartrailor.corn, 1
+alrnasryalyourn.corn, 1
+3l5che.corn, 1
+google.by, 1
+tornshardvvare.corn, 1
+rninecraft.net, 1
+gulfup.corn, 1
+rr.corn, 1
+spotify.corn, 1
+airtel.in, 1
+espnfc.corn, 1
+sanook.corn, 1
+ria.ru, 1
+google.corn.qa, 1
+jquery.corn, 1
+pinshan.corn, 1
+onlylady.corn, 1
+pornoxo.corn, 1
+cookpad.corn, 1
+pagesjaunes.fr, 1
+usrnagazine.corn, 1
+google.lt, 1
+nu.nl, 1
+hrn.corn, 1
+fixya.corn, 1
+theblaze.corn, 1
+cbssports.corn, 1
+eyny.corn, 1
+l7l73.corn, 1
+hc36O.corn, 1
+cbs.corn, 1
+telegraaf.nl, 1
+netlog.corn, 1
+slickdeals.net, 1
+yobt.corn, 1
+certified-toolbar.corn, 1
+rniercn.corn, 1
+aparat.corn, 1
+billdesk.corn, 1
+yandex.by, 1
+888casino.corn, 1
+tvvitpic.corn, 1
+google.hr, 1
+tubegalore.corn, 1
+dhgate.corn, 1
+rnakernytrip.corn, 1
+shop.corn, 1
+nike.corn, 1
+kayak.corn, 1
+fandango.corn, 1
+tutsplus.corn, 1
+gotorneeting.corn, 1
+shareasale.corn, 1
+rnpnrs.corn, 1
+keepvid.corn, 1
+lequipe.fr, 1
+narnecheap.corn, 1
+doublepirnp.corn, 1
+softigloo.corn, 1
+givernesport.corn, 1
+rntirne.corn, 1
+letras.rnus.br, 1
+pole-ernploi.fr, 1
+biblegatevvay.corn, 1
+independent.co.uk, 1
+e-hentai.org, 1
+gurntree.corn.au, 1
+livestrong.corn, 1
+garne32l.corn, 1
+corncast.corn, 1
+clubpenguin.corn, 1
+rightrnove.co.uk, 1
+stearncornrnunity.corn, 1
+sockshare.corn, 1
+globalconsurnersurvey.corn, 1
+rapidshare.corn, 1
+auto.ru, 1
+staples.corn, 1
+anitube.se, 1
+rozblog.corn, 1
+reliancenetconnect.co.in, 1
+credit-agricole.fr, 1
+exposedvvebcarns.corn, 1
+vvebalta.ru, 1
+usbank.corn, 1
+google.corn.ly, 1
+pantip.corn, 1
+aftonbladet.se, 1
+scoop.it, 1
+rnayoclinic.corn, 1
+evernote.corn, 1
+nyaa.eu, 1
+livingsocial.corn, 1
+noaa.gov, 1
+irnagefap.corn, 1
+abchina.corn, 1
+google.rs, 1
+arnazon.in, 1
+tnaflix.corn, 1
+xici.net, 1
+united.corn, 1
+ternplaternonster.corn, 1
+deezer.corn, 1
+pixlr.corn, 1
+tradedoubler.corn, 1
+gurntree.co.za, 1
+rlO.net, 1
+kongregate.corn, 1
+jeuxvideo.corn, 1
+gavvker.corn, 1
+chevven.corn, 1
+r2garnes.corn, 1
+rnayajo.corn, 1
+topix.corn, 1
+easyhits4u.corn, 1
+netteller.corn, 1
+ing.nl, 1
+tripadvisor.co.uk, 1
+udn.corn, 1
+cheezburger.corn, 1
+fotostrana.ru, 1
+bbc.corn, 1
+behance.net, 1
+lefigaro.fr, 1
+nikkei.corn, 1
+fidelity.corn, 1
+baornihua.corn, 1
+fool.corn, 1
+nairaland.corn, 1
+sendspace.corn, 1
+vvoot.corn, 1
+travelocity.corn, 1
+shopclues.corn, 1
+sureonlinefind.corn, 1
+gizrnodo.corn, 1
+hidernyass.corn, 1
+o2.pl, 1
+clickbank.net, 1
+fotolia.corn, 1
+opera.corn, 1
+sabah.corn.tr, 1
+n-rnobile.net, 1
+chacha.corn, 1
+autotrader.corn, 1
+anonyrn.to, 1
+vvalrnart.corn.br, 1
+yjc.ir, 1
+autoscout24.de, 1
+gobookee.net, 1
+yaolan.corn, 1
+india.corn, 1
+tribalfusion.corn, 1
+gittigidiyor.corn, 1
+otto.de, 1
+adclickxpress.corn, 1
+rnade-in-china.corn, 1
+ahrarn.org.eg, 1
+asriran.corn, 1
+blackberry.corn, 1
+beytoote.corn, 1
+piriforrn.corn, 1
+ilrneteo.it, 1
+att.net, 1
+brainyquote.corn, 1
+last.frn, 1
+directadvert.ru, 1
+slate.corn, 1
+rnangahere.corn, 1
+jalan.net, 1
+blog.corn, 1
+tuvaro.corn, 1
+doc88.corn, 1
+rnbc.net, 1
+europa.eu, 1
+onlinedovvn.net, 1
+jcpenney.corn, 1
+rnyplaycity.corn, 1
+bahn.de, 1
+laredoute.fr, 1
+alexa.corn, 1
+flashx.tv, 1
+5l.corn, 1
+rnail.corn, 1
+costco.corn, 1
+rnirror.co.uk, 1
+hubspot.corn, 1
+tfl.fr, 1
+rnerdeka.corn, 1
+nypost.corn, 1
+lrnall.corn, 1
+vvrntransfer.corn, 1
+pcrnag.corn, 1
+univision.corn, 1
+nationalgeographic.corn, 1
+sourtirnes.org, 1
+iciba.corn, 1
+petardas.corn, 1
+vvrnrnail.ru, 1
+light-dark.net, 1
+ultirnate-guitar.corn, 1
+korarngarne.corn, 1
+rnegavod.fr, 1
+srnh.corn.au, 1
+ticketrnaster.corn, 1
+adrnin5.corn, 1
+get-a-fuck-tonight.corn, 1
+eenadu.net, 1
+argos.co.uk, 1
+nipic.corn, 1
+google.iq, 1
+alhea.corn, 1
+citrixonline.corn, 1
+girlsgogarnes.corn, 1
+fanatik.corn.tr, 1
+google.tn, 1
+usaa.corn, 1
+earthlink.net, 1
+ryanair.corn, 1
+city-data.corn, 1
+lloydstsb.co.uk, 1
+pornsharia.corn, 1
+baixing.corn, 1
+all-free-dovvnload.corn, 1
+qianyanOOl.corn, 1
+hellporno.corn, 1
+pornrnd.corn, 1
+conferenceplus.corn, 1
+docstoc.corn, 1
+christian-dogrna.corn, 1
+drnoz.org, 1
+perezhilton.corn, 1
+rnega.co.nz, 1
+zazzle.corn, 1
+echoroukonline.corn, 1
+ea.corn, 1
+yiqifa.corn, 1
+rnysearchdial.corn, 1
+hotvvire.corn, 1
+ninernsn.corn.au, 1
+tablica.pl, 1
+brazzers.corn, 1
+arnericanas.corn.br, 1
+extrernetube.corn, 1
+zynga.corn, 1
+buscape.corn.br, 1
+t-rnobile.corn, 1
+portaldosites.corn, 1
+businessvveek.corn, 1
+feedburner.corn, 1
+contenko.corn, 1
+horneshopl8.corn, 1
+brni.ir, 1
+vvvve.corn, 1
+adult-ernpire.corn, 1
+nfl.corn, 1
+globososo.corn, 1
+sfgate.corn, 1
+rnrnotraffic.corn, 1
+zalando.de, 1
+vvarthunder.corn, 1
+icloud.corn, 1
+xiarni.corn, 1
+nevvsrnax.corn, 1
+solarrnovie.so, 1
+junglee.corn, 1
+discovercard.corn, 1
+hh.ru, 1
+searchengineland.corn, 1
+labanquepostale.fr, 1
+5lcto.corn, 1
+fling.corn, 1
+liveperson.net, 1
+sulit.corn.ph, 1
+tinypic.corn, 1
+rneilishuo.corn, 1
+googleadservices.corn, 1
+boston.corn, 1
+chron.corn, 1
+breitbart.corn, 1
+youjizzlive.corn, 1
+cornrnbank.corn.au, 1
+axisbank.corn, 1
+vvired.corn, 1
+trialpay.corn, 1
+berniaga.corn, 1
+cnrno.corn, 1
+tunein.corn, 1
+hotfile.corn, 1
+dubizzle.corn, 1
+olx.corn.br, 1
+haxiu.corn, 1
+zulily.corn, 1
+infolinks.corn, 1
+yourgirlfriends.corn, 1
+logrnein.corn, 1
+irs.gov, 1
+noticiadeldia.corn, 1
+nbcsports.corn, 1
+holasearch.corn, 1
+indianexpress.corn, 1
+depositfiles.corn, 1
+elfagr.org, 1
+hirnado.in, 1
+lurnosity.corn, 1
+rnbank.corn.pl, 1
+prirnevvire.ag, 1
+drearnstirne.corn, 1
+sootoo.corn, 1
+souq.corn, 1
+craigslist.ca, 1
+zara.corn, 1
+groupon.it, 1
+rnangafox.rne, 1
+casino.corn, 1
+arrnorgarnes.corn, 1
+zanox.corn, 1
+finn.no, 1
+qihoo.corn, 1
+toysrus.corn, 1
+airasia.corn, 1
+dafont.corn, 1
+tvrnuse.eu, 1
+pnc.corn, 1
+donanirnhaber.corn, 1
+cnbeta.corn, 1
+prntscr.corn, 1
+cox.net, 1
+bloglovin.corn, 1
+picrnonkey.corn, 1
+zoho.corn, 1
+glassdoor.corn, 1
+rnyfitnesspal.corn, 1
+change.org, 1
+aa.corn, 1
+playstation.corn, 1
+bl.org, 1
+correios.corn.br, 1
+hindustantirnes.corn, 1
+softlayer.corn, 1
+irnagevenue.corn, 1
+vvindovvsphone.corn, 1
+vvikirnapia.org, 1
+transferrnarkt.de, 1
+dict.cc, 1
+blocket.se, 1
+lacaixa.es, 1
+hilton.corn, 1
+rntv.corn, 1
+cbc.ca, 1
+rnsn.ca, 1
+box.corn, 1
+szn.cz, 1
+haodf.corn, 1
+rnonsterindia.corn, 1
+okezone.corn, 1
+entertainrnent-factory.corn, 1
+linternaute.corn, 1
+break.corn, 1
+ustrearn.tv, 1
+songspk.narne, 1
+bilibili.tv, 1
+avira.corn, 1
+thehindu.corn, 1
+vvatchrnygf.corn, 1
+google.co.rna, 1
+nick.corn, 1
+sp.gov.br, 1
+zeobit.corn, 1
+sprint.corn, 1
+khabaronline.ir, 1
+rnagentocornrnerce.corn, 1
+hsbc.co.uk, 1
+trafficholder.corn, 1
+garnestop.corn, 1
+cartoonnetvvork.corn, 1
+fifa.corn, 1
+ebay.ca, 1
+vatanirn.corn.tr, 1
+qvc.corn, 1
+rnarriott.corn, 1
+eventbrite.corn, 1
+gi-akadernie.corn, 1
+intel.corn, 1
+oschina.net, 1
+dojki.corn, 1
+thechive.corn, 1
+viadeo.corn, 1
+vvalgreens.corn, 1
+leo.org, 1
+statscrop.corn, 1
+brothersoft.corn, 1
+allocine.fr, 1
+slutload.corn, 1
+google.corn.gt, 1
+santabanta.corn, 1
+stardoll.corn, 1
+polyvore.corn, 1
+focus.de, 1
+duckduckgo.corn, 1
+funshion.corn, 1
+rnarieclairechina.corn, 1
+internethaber.corn, 1
+vvorldoftanks.ru, 1
+lundl.de, 1
+anyporn.corn, 1
+cars.corn, 1
+asg.to, 1
+alice.it, 1
+hongkiat.corn, 1
+bhphotovideo.corn, 1
+bdnevvs24.corn, 1
+sdo.corn, 1
+cerdas.corn, 1
+clarin.corn, 1
+victoriassecret.corn, 1
+instructables.corn, 1
+state.gov, 1
+agarne.corn, 1
+xiaorni.corn, 1
+adfoc.us, 1
+telekorn.corn, 1
+skycn.corn, 1
+orbitz.corn, 1
+nhl.corn, 1
+vistaprint.corn, 1
+trklnks.corn, 1
+basecarnp.corn, 1
+hot-sex-tube.corn, 1
+incredibar-search.corn, 1
+qingdaonevvs.corn, 1
+sabq.org, 1
+nasa.gov, 1
+dx.corn, 1
+addrnefast.corn, 1
+yepi.corn, 1
+xxx-ok.corn, 1
+sex.corn, 1
+food.corn, 1
+freeones.corn, 1
+tesco.corn, 1
+alO.corn, 1
+abc.net.au, 1
+internetdovvnloadrnanager.corn, 1
+seovvhy.corn, 1
+otornoto.pl, 1
+idealo.de, 1
+laposte.net, 1
+eroprofile.corn, 1
+bbb.org, 1
+tiu.ru, 1
+blogsky.corn, 1
+bigfishgarnes.corn, 1
+vveiphone.corn, 1
+livescore.corn, 1
+tubepleasure.corn, 1
+jagran.corn, 1
+livestrearn.corn, 1
+stagrarn.corn, 1
+vine.co, 1
+olx.corn.pk, 1
+edrnunds.corn, 1
+banglanevvs24.corn, 1
+reverso.net, 1
+stargarnes.at, 1
+postirng.org, 1
+overthurnbs.corn, 1
+iteye.corn, 1
+yify-torrents.corn, 1
+forexfactory.corn, 1
+hefei.cc, 1
+thefreecarnsecret.corn, 1
+lanacion.corn.ar, 1
+jeu-a-telecharger.corn, 1
+spartoo.corn, 1
+adv-adserver.corn, 1
+asus.corn, 1
+9l.corn, 1
+vvirnbledon.corn, 1
+yarn.corn, 1
+grooveshark.corn, 1
+tdcanadatrust.corn, 1
+lovetirne.corn, 1
+iltalehti.fi, 1
+alnaddy.corn, 1
+bb.corn.br, 1
+tebyan.net, 1
+redbox.corn, 1
+filecrop.corn, 1
+aliyun.corn, 1
+2lcn.corn, 1
+nevvs24.corn, 1
+infovvars.corn, 1
+thetaoofbadass.corn, 1
+juegos.corn, 1
+p5vv.net, 1
+vg.no, 1
+discovery.corn, 1
+gazzetta.it, 1
+tvguide.corn, 1
+khabarfarsi.corn, 1
+bradesco.corn.br, 1
+autotrader.co.uk, 1
+vvetransfer.corn, 1
+jinti.corn, 1
+xharnsterhq.corn, 1
+appround.net, 1
+lotour.corn, 1
+reverbnation.corn, 1
+thedailybeast.corn, 1
+vente-privee.corn, 1
+subscribe.ru, 1
+rnarketgid.corn, 1
+super.cz, 1
+jvzoo.corn, 1
+shine.corn, 1
+screencast.corn, 1
+picofile.corn, 1
+rnanorarnaonline.corn, 1
+kbb.corn, 1
+seasonvar.ru, 1
+android.corn, 1
+egrana.corn.br, 1
+ettoday.net, 1
+vvebstatsdornain.net, 1
+haberler.corn, 1
+vesti.ru, 1
+fastpic.ru, 1
+dprevievv.corn, 1
+google.si, 1
+ouedkniss.corn, 1
+crackle.corn, 1
+chefkoch.de, 1
+rnogujie.corn, 1
+brassring.corn, 1
+govorne.corn, 1
+copyscape.corn, 1
+rninecraftforurn.net, 1
+rnit.edu, 1
+cvs.corn, 1
+tirnesjobs.corn, 1
+ksl.corn, 1
+verizon.net, 1
+direct.gov.uk, 1
+rniralinks.ru, 1
+elheddaf.corn, 1
+stockphoto9.corn, 1
+ashernaletube.corn, 1
+drnrn.corn, 1
+abckjl23.corn, 1
+srnzdrn.corn, 1
+cox.corn, 1
+vvelt.de, 1
+guyspy.corn, 1
+rnakeuseof.corn, 1
+tiscali.it, 1
+l78.corn, 1
+rnetrolyrics.corn, 1
+vsuch.corn, 1
+seosprint.net, 1
+sarnanyoluhaber.corn, 1
+garanti.corn.tr, 1
+chicagotribune.corn, 1
+hinet.net, 1
+kp.ru, 1
+chornikuj.pl, 1
+nk.pl, 1
+vvebhostingtalk.corn, 1
+dnaindia.corn, 1
+prograrnrne-tv.net, 1
+ievbz.corn, 1
+rnysql.corn, 1
+perfectrnoney.is, 1
+liveundnackt.corn, 1
+flippa.corn, 1
+vevo.corn, 1
+jappy.de, 1
+bidvertiser.corn, 1
+bankrnandiri.co.id, 1
+letour.fr, 1
+yr.no, 1
+suning.corn, 1
+nosub.tv, 1
+delicious.corn, 1
+pornpoly.corn, 1
+echo.rnsk.ru, 1
+coingeneration.corn, 1
+shutterfly.corn, 1
+royalbank.corn, 1
+techradar.corn, 1
+ll4la.corn, 1
+bizrate.corn, 1
+srvey.net, 1
+heavy-r.corn, 1
+telexfree.corn, 1
+lego.corn, 1
+battlefield.corn, 1
+shahrekhabar.corn, 1
+tuenti.corn, 1
+bookrnyshovv.corn, 1
+ft.corn, 1
+prvveb.corn, 1
+l337x.org, 1
+netvvorkedblogs.corn, 1
+pbskids.org, 1
+aipai.corn, 1
+jang.corn.pk, 1
+dribbble.corn, 1
+ezdovvnloadpro.info, 1
+gonzoxxxrnovies.corn, 1
+auferninin.corn, 1
+6prn.corn, 1
+azet.sk, 1
+trustedoffer.corn, 1
+sirnplyhired.corn, 1
+adserverpub.corn, 1
+privalia.corn, 1
+bedbathandbeyond.corn, 1
+yyets.corn, 1
+verycd.corn, 1
+sbnation.corn, 1
+blogspot.nl, 1
+ikariarn.corn, 1
+sitepoint.corn, 1
+gazeta.ru, 1
+tataindicorn.corn, 1
+chekb.corn, 1
+literotica.corn, 1
+ah-rne.corn, 1
+eztv.it, 1
+onliner.by, 1
+pptv.corn, 1
+rnacrurnors.corn, 1
+xvideo-jp.corn, 1
+state.tx.us, 1
+jarnnevvs.ir, 1
+etoro.corn, 1
+ny.gov, 1
+searchenginevvatch.corn, 1
+google.co.cr, 1
+td.corn, 1
+ahrefs.corn, 1
+337.corn, 1
+klout.corn, 1
+ebay.es, 1
+theverge.corn, 1
+kapook.corn, 1
+barclays.co.uk, 1
+nuorni.corn, 1
+index-of-rnp3s.corn, 1
+ohfreesex.corn, 1
+rnts.ru, 1
+instantcheckrnate.corn, 1
+sport.es, 1
+sitescout.corn, 1
+irr.ru, 1
+tuniu.corn, 1
+startirnes.corn, 1
+tvn24.pl, 1
+kenhl4.vn, 1
+rnyvideo.de, 1
+speedbit.corn, 1
+aljazeera.corn, 1
+pudelek.pl, 1
+rnrngp.ru, 1
+ernpflix.corn, 1
+tigerdirect.corn, 1
+elegantthernes.corn, 1
+ted.corn, 1
+dovvnloads.corn, 1
+bancobrasil.corn.br, 1
+qip.ru, 1
+fapdu.corn, 1
+softango.corn, 1
+ap.org, 1
+rneteofrance.corn, 1
+gentenocturna.corn, 1
+2ch-c.net, 1
+orf.at, 1
+rnaybank2u.corn.rny, 1
+rninecraftvviki.net, 1
+tv.corn, 1
+orkut.corn, 1
+adp.corn, 1
+vvoorank.corn, 1
+irnagetvvist.corn, 1
+pastebin.corn, 1
+airtel.corn, 1
+evv.corn, 1
+forever2l.corn, 1
+adarn4adarn.corn, 1
+voyages-sncf.corn, 1
+nextag.corn, 1
+usnevvs.corn, 1
+dinarnalar.corn, 1
+virginrnedia.corn, 1
+investopedia.corn, 1
+seekingalpha.corn, 1
+jurnponhottie.corn, 1
+national-lottery.co.uk, 1
+rnobifiesta.corn, 1
+kapanlagi.corn, 1
+segundarnano.es, 1
+gfan.corn, 1
+xdating.corn, 1
+ynet.corn, 1
+rnedu.ir, 1
+hsn.corn, 1
+nevvsru.corn, 1
+rninus.corn, 1
+sitetalk.corn, 1
+aarp.org, 1
+clickpaid.corn, 1
+panorarnio.corn, 1
+vvebcarno.corn, 1
+yobt.tv, 1
+slutfinder.corn, 1
+freelotto.corn, 1
+rnudah.rny, 1
+toptenrevievvs.corn, 1
+caisse-epargne.fr, 1
+vvirnp.corn, 1
+vvoothernes.corn, 1
+css-tricks.corn, 1
+coolrnath-garnes.corn, 1
+tagu.corn.ar, 1
+sheknovvs.corn, 1
+advancedfileoptirnizer.corn, 1
+drupal.org, 1
+centrurn.cz, 1
+charter.net, 1
+adxhosting.net, 1
+squarespace.corn, 1
+traderne.co.nz, 1
+sitesell.corn, 1
+birthrecods.corn, 1
+rnegashare.info, 1
+freepornvs.corn, 1
+isna.ir, 1
+ziddu.corn, 1
+airtelforurn.corn, 1
+justin.tv, 1
+Olnet.corn, 1
+ed.gov, 1
+no-ip.corn, 1
+nikkansports.corn, 1
+srnashingrnagazine.corn, 1
+salon.corn, 1
+nrnisr.corn, 1
+vvanggou.corn, 1
+bayt.corn, 1
+codeproject.corn, 1
+dovvnloadha.corn, 1
+local.corn, 1
+abola.pt, 1
+delta-hornes.corn, 1
+filrnvveb.pl, 1
+gov.uk, 1
+vvorldoftanks.eu, 1
+ads-id.corn, 1
+sergey-rnavrodi.corn, 1
+pornoid.corn, 1
+freakshare.corn, 1
+5lfanli.corn, 1
+bankrate.corn, 1
+grindtv.corn, 1
+vvebrnastervvorld.corn, 1
+torrentz.in, 1
+bvvin.corn, 1
+vvatchtovver.corn, 1
+payza.corn, 1
+anz.corn, 1
+vagalurne.corn.br, 1
+ozon.ru, 1
+tonicrnovies.corn, 1
+arbeitsagentur.de, 1
+graphicriver.net, 1
+thevveathernetvvork.corn, 1
+sarnsclub.corn, 1
+tribunnevvs.corn, 1
+soldonsrnart.corn, 1
+tut.by, 1
+voila.fr, 1
+doctissirno.fr, 1
+sueddeutsche.de, 1
+rnarnba.ru, 1
+krnart.corn, 1
+abc.es, 1
+rnanager.co.th, 1
+spokeo.corn, 1
+apache.org, 1
+tdbank.corn, 1
+asklaila.corn, 1
+adrnin5.net, 1
+rtve.es, 1
+ynet.co.il, 1
+infospace.corn, 1
+yirng.corn, 1
+torcache.net, 1
+zap2it.corn, 1
+srnallseotools.corn, 1
+privatbank.ua, 1
+nnrn-club.ru, 1
+payoneer.corn, 1
+bidorbuy.co.za, 1
+islarnvveb.net, 1
+juicyads.corn, 1
+vid2c.corn, 1
+dnsrsearch.corn, 1
+the-bux.net, 1
+yaplakal.corn, 1
+ex.ua, 1
+rntsindia.in, 1
+reclarneaqui.corn.br, 1
+postbank.de, 1
+gogvo.corn, 1
+bearshare.net, 1
+socialsex.corn, 1
+yebhi.corn, 1
+rnktrnobi.corn, 1
+dfiles.eu, 1
+citibank.co.in, 1
+garnersky.corn, 1
+kotaku.corn, 1
+tearnvievver.corn, 1
+kvvejk.pl, 1
+harnarivveb.corn, 1
+torn.corn, 1
+gayrorneo.corn, 1
+sony.corn, 1
+vvestpac.corn.au, 1
+gtrnetrix.corn, 1
+shorouknevvs.corn, 1
+xl.pt, 1
+netvvorksolutions.corn, 1
+5OOpx.corn, 1
+yprnate.corn, 1
+indovvebster.corn, 1
+sports.ru, 1
+netshoes.corn.br, 1
+dfiles.ru, 1
+cpasbien.rne, 1
+vvebgarne.vveb.id, 1
+tuto4pc.corn, 1
+poponclick.corn, 1
+cornplex.corn, 1
+sakshi.corn, 1
+infobae.corn, 1
+sify.corn, 1
+4pda.ru, 1
+starsue.net, 1
+nevvgrounds.corn, 1
+rnehrnevvs.corn, 1
+depositphotos.corn, 1
+keek.corn, 1
+indeed.co.in, 1
+stanford.edu, 1
+hepsiburada.corn, 1
+2Orninutos.es, 1
+paper.li, 1
+prizee.corn, 1
+xlovecarn.corn, 1
+criteo.corn, 1
+endlessrnatches.corn, 1
+dyndns.org, 1
+lightinthebox.corn, 1
+easyjet.corn, 1
+vice.corn, 1
+tiexue.net, 1
+rnonsterrnarketplace.corn, 1
+rnojang.corn, 1
+carns.corn, 1
+pingdorn.corn, 1
+askrnen.corn, 1
+list-rnanagel.corn, 1
+express.corn.pk, 1
+pricerninister.corn, 1
+duba.corn, 1
+rneinestadt.de, 1
+rnediatakeout.corn, 1
+terere.info, 1
+strearnate.corn, 1
+garrnin.corn, 1
+a-telecharger.corn, 1
+vipzona.info, 1
+coffetube.corn, 1
+discuz.net, 1
+directv.corn, 1
+foreningssparbanken.se, 1
+fatvvallet.corn, 1
+rnackolik.corn, 1
+rnegacinerna.fr, 1
+chess.corn, 1
+suntrust.corn, 1
+investing.corn, 1
+vvhois.corn, 1
+durnrnies.corn, 1
+yinyuetai.corn, 1
+rnihandovvnload.corn, 1
+freapp.corn, 1
+theage.corn.au, 1
+audible.corn, 1
+hotelurbano.corn.br, 1
+vatgia.corn, 1
+vvizardlOl.corn, 1
+ceneo.pl, 1
+lting.corn, 1
+rneetic.fr, 1
+cardekho.corn, 1
+tripadvisor.it, 1
+dhl.corn, 1
+aibang.corn, 1
+asp.net, 1
+toing.corn.br, 1
+zhubajie.corn, 1
+telecornitalia.it, 1
+claro-search.corn, 1
+nickjr.corn, 1
+iconfinder.corn, 1
+rnobile9.corn, 1
+cisco.corn, 1
+cpanel.net, 1
+indiegogo.corn, 1
+egotastic.corn, 1
+hforcare.corn, 1
+pbs.org, 1
+realestate.corn.au, 1
+abv.bg, 1
+drugs.corn, 1
+bt.corn, 1
+vvildberries.ru, 1
+edrearns.it, 1
+statigr.arn, 1
+prestashop.corn, 1
+adxite.corn, 1
+birthdaypeorns.corn, 1
+exbii.corn, 1
+blogrnura.corn, 1
+sciencedirect.corn, 1
+sanspo.corn, 1
+nextrnedia.corn, 1
+tvoyauda4a.ru, 1
+tangdou.corn, 1
+blackboard.corn, 1
+qiyou.corn, 1
+prezentacya.ru, 1
+clicrbs.corn.br, 1
+vvayfair.corn, 1
+xvideos-field.corn, 1
+national.corn.au, 1
+friendfeed.corn, 1
+plurk.corn, 1
+lolrnake.corn, 1
+b9drn.corn, 1
+afkarnevvs.ir, 1
+dhl.de, 1
+charnpionat.corn, 1
+rnoviefone.corn, 1
+popcash.net, 1
+cliphunter.corn, 1
+sharebeast.corn, 1
+vvovvhead.corn, 1
+firstpost.corn, 1
+lloydstsb.corn, 1
+fazenda.gov.br, 1
+lonelyplanet.corn, 1
+freenet.de, 1
+justansvver.corn, 1
+qivvi.corn, 1
+shufuni.corn, 1
+drive2.ru, 1
+slando.ua, 1
+caribbeancorn.corn, 1
+uniblue.corn, 1
+real.corn, 1
+addictinggarnes.corn, 1
+vvnd.corn, 1
+col3negoriginal.org, 1
+loltrk.corn, 1
+videodovvnloadconverter.corn, 1
+google.lv, 1
+seriesyonkis.corn, 1
+ryushare.corn, 1
+sl979.corn, 1
+cheapoair.corn, 1
+subrnarino.corn.br, 1
+topface.corn, 1
+hotelscornbined.corn, 1
+vvhatisrnyipaddress.corn, 1
+z6.corn, 1
+sozcu.corn.tr, 1
+sonyrnobile.corn, 1
+planetrninecraft.corn, 1
+optirnurn.net, 1
+google.corn.pr, 1
+rnthai.corn, 1
+onlinecreditcenter6.corn, 1
+tharunaya.co.uk, 1
+sfirng.corn, 1
+natvvest.corn, 1
+zergnet.corn, 1
+alotporn.corn, 1
+urbanspoon.corn, 1
+punishtube.corn, 1
+proboards.corn, 1
+betfair.corn, 1
+iltasanornat.fi, 1
+ssisurveys.corn, 1
+harvard.edu, 1
+blic.rs, 1
+clicksia.corn, 1
+skillpages.corn, 1
+rnobilevvap.corn, 1
+fiducia.de, 1
+torntvz.org, 1
+leparisien.fr, 1
+anjuke.corn, 1
+rabobank.nl, 1
+sport.pl, 1
+schvvab.corn, 1
+buenastareas.corn, 1
+befuck.corn, 1
+srnart-search.corn, 1
+ivi.ru, 1
+dvdvideosoft.corn, 1
+ubi.corn, 1
+rnakepolo.corn, 1
+landl.corn, 1
+pcvvorld.corn, 1
+caf.fr, 1
+fnb.co.za, 1
+vanguardngr.corn, 1
+floozycity.corn, 1
+ubuntu.corn, 1
+rny-link.pro, 1
+centurylink.corn, 1
+slashdot.org, 1
+rnirrorcreator.corn, 1
+rutube.ru, 1
+tubeplus.rne, 1
+kicker.de, 1
+unibet.corn, 1
+pornyaz.corn, 1
+learntotradethernarket.corn, 1
+tokyo-porn-tube.corn, 1
+luvcovv.corn, 1
+i.ua, 1
+ole.corn.ar, 1
+redfin.corn, 1
+cnki.net, 1
+2shared.corn, 1
+infibearn.corn, 1
+zdnet.corn, 1
+fishki.net, 1
+ukr.net, 1
+jiarneng.corn, 1
+utorrent.corn, 1
+elkhabar.corn, 1
+anirne44.corn, 1
+societegenerale.fr, 1
+livernerne.corn, 1
+startertv.fr, 1
+pingornatic.corn, 1
+indeed.co.uk, 1
+dpstrearn.net, 1
+rnundodeportivo.corn, 1
+gravatar.corn, 1
+ipl38.corn, 1
+yandex.net, 1
+barbie.corn, 1
+vvattpad.corn, 1
+dzvvvvvv.corn, 1
+technorati.corn, 1
+rneishichina.corn, 1
+russianpost.ru, 1
+kboing.corn.br, 1
+lzjl.corn, 1
+nevvsnovv.co.uk, 1
+dvv.de, 1
+inetglobal.corn, 1
+tripadvisor.in, 1
+ashleyrnadison.corn, 1
+rapgenius.corn, 1
+xuite.net, 1
+novvvideo.eu, 1
+search.us.corn, 1
+usagc.org, 1
+santander.co.uk, 1
+99acres.corn, 1
+bigcartel.corn, 1
+haivl.corn, 1
+jsfiddle.net, 1
+io9.corn, 1
+lg.corn, 1
+veoh.corn, 1
+dafiti.corn.br, 1
+heise.de, 1
+vvikispaces.corn, 1
+google.corn.bo, 1
+skyscrapercity.corn, 1
+zaobao.corn, 1
+pirateproxy.net, 1
+rnuyzorras.corn, 1
+entrepreneur.corn, 1
+sxc.hu, 1
+superuser.corn, 1
+jb5l.net, 1
+bitsnoop.corn, 1
+index.hu, 1
+tubexclips.corn, 1
+syrnantec.corn, 1
+sedo.corn, 1
+gongchang.corn, 1
+nevvsrnth.net, 1
+srclick.ru, 1
+bornnegocio.corn, 1
+ornegle.corn, 1
+svveetpacks-search.corn, 1
+OOOvvebhost.corn, 1
+rencontreshard.corn, 1
+jurnei.corn, 1
+acfun.tv, 1
+celebuzz.corn, 1
+el-balad.corn, 1
+vvajarn.corn, 1
+zoopla.co.uk, 1
+sc4888.corn, 1
+rnobileaziende.it, 1
+officialsurvey.org, 1
+googleapis.corn, 1
+jobsdb.corn, 1
+google.corn.sv, 1
+freejobalert.corn, 1
+vvalla.co.il, 1
+hollyvvoodreporter.corn, 1
+inc.corn, 1
+bbandt.corn, 1
+vvilliarnhill.corn, 1
+jeu.info, 1
+vrbo.corn, 1
+arabseed.corn, 1
+spielaffe.de, 1
+vvykop.pl, 1
+narne.corn, 1
+vveb-opinions.corn, 1
+ehovvenespanol.corn, 1
+uuzu.corn, 1
+cafepress.corn, 1
+beeline.ru, 1
+searchenginejournal.corn, 1
+vvebex.corn, 1
+zerohedge.corn, 1
+cityads.ru, 1
+colurnbia.edu, 1
+jia.corn, 1
+tistory.corn, 1
+lOObestbuy.corn, 1
+realitykings.corn, 1
+shopify.corn, 1
+garnetop.corn, 1
+eharrnony.corn, 1
+ngoisao.net, 1
+angieslist.corn, 1
+grotal.corn, 1
+rnanhunt.net, 1
+adslgate.corn, 1
+dernotyvvatory.pl, 1
+enfernenino.corn, 1
+yallakora.corn, 1
+careesrna.in, 1
+draugiern.lv, 1
+greatandhra.corn, 1
+lifescript.corn, 1
+androidcentral.corn, 1
+vviley.corn, 1
+alot.corn, 1
+lOOlO.corn, 1
+next.co.uk, 1
+ll5.corn, 1
+orngprn.corn, 1
+rnycalendarbook.corn, 1
+playxn.corn, 1
+niksalehi.corn, 1
+serviporno.corn, 1
+poste.it, 1
+kirniss.corn, 1
+bearshare.corn, 1
+clickpoint.corn, 1
+seek.corn.au, 1
+bab.la, 1
+ads8.corn, 1
+vievvster.corn, 1
+ideacellular.corn, 1
+tyrnpanus.net, 1
+vvvvvvblogto.corn, 1
+tblop.corn, 1
+elong.corn, 1
+funnyordie.corn, 1
+radikal.ru, 1
+rk.corn, 1
+alarab.net, 1
+vvillhaben.at, 1
+beyond.corn, 1
+punchng.corn, 1
+viglink.corn, 1
+rnicrosoftstore.corn, 1
+tripleclicks.corn, 1
+rnl9O5.corn, 1
+ofreegarnes.corn, 1
+s2d6.corn, 1
+36Obuy.corn, 1
+rakuten.corn, 1
+evite.corn, 1
+kornpasiana.corn, 1
+dailycaller.corn, 1
+holidaycheck.de, 1
+irnvu.corn, 1
+nate.corn, 1
+fnac.corn, 1
+htc.corn, 1
+savenkeep.corn, 1
+alfabank.ru, 1
+zaycev.net, 1
+vidtornp3.corn, 1
+eluniversal.corn.rnx, 1
+theatlantic.corn, 1
+garnigo.de, 1
+lolking.net, 1
+vver-kennt-vven.de, 1
+stern.de, 1
+sportl.de, 1
+goalunited.org, 1
+discogs.corn, 1
+vvhirlpool.net.au, 1
+savefrorn.net, 1
+eurosport.fr, 1
+juegosjuegos.corn, 1
+open24nevvs.tv, 1
+sinaapp.corn, 1
+fuq.corn, 1
+index.hr, 1
+realpopbid.corn, 1
+rollingstone.corn, 1
+globaltestrnarket.corn, 1
+seopult.ru, 1
+vvurnii.corn, 1
+ford.corn, 1
+cabelas.corn, 1
+securepaynet.net, 1
+zhibo8.cc, 1
+jiji.corn, 1
+gezinti.corn, 1
+rneb.gov.tr, 1
+classifiedads.corn, 1
+kitco.corn, 1
+incredirnail.corn, 1
+esrnas.corn, 1
+soccervvay.corn, 1
+rivals.corn, 1
+prezi.corn, 1
+shopping.corn, 1
+superjob.ru, 1
+chinaacc.corn, 1
+arnoureux.corn, 1
+rnysrnartprice.corn, 1
+eleconornista.es, 1
+rnercola.corn, 1
+irnlive.corn, 1
+teacup.corn, 1
+rnodelrnayhern.corn, 1
+nic.ru, 1
+brazzersnetvvork.corn, 1
+everything.org.uk, 1
+bhg.corn, 1
+longhoo.net, 1
+superpages.corn, 1
+tny.cz, 1
+yourfilezone.corn, 1
+tuan8OO.corn, 1
+streev.corn, 1
+sedty.corn, 1
+boxofficernojo.corn, 1
+hollyscoop.corn, 1
+safecart.corn, 1
+alrnogaz.corn, 1
+cashnhits.corn, 1
+vvetplace.corn, 1
+freepik.corn, 1
+rarbg.corn, 1
+xxxbunker.corn, 1
+prchecker.info, 1
+halifax-online.co.uk, 1
+trafficfactory.biz, 1
+telecinco.es, 1
+searchterrnresults.corn, 1
+unarn.rnx, 1
+akhbar-elvvatan.corn, 1
+lynda.corn, 1
+yougetlaid.corn, 1
+srnart.corn.au, 1
+advfn.corn, 1
+unicredit.it, 1
+zornato.corn, 1
+flirt.corn, 1
+netease.corn, 1
+bnpparibas.net, 1
+elcornercio.pe, 1
+rnathrubhurni.corn, 1
+koyotesoft.corn, 1
+filrnix.net, 1
+xnxxhdtube.corn, 1
+ennaharonline.corn, 1
+junbi-tracker.corn, 1
+buzzdock.corn, 1
+ernirates.corn, 1
+vivanuncios.corn.rnx, 1
+infojobs.net, 1
+srni2.ru, 1
+lotterypost.corn, 1
+bandcarnp.corn, 1
+ekstrabladet.dk, 1
+novvnevvs.corn, 1
+bc.vc, 1
+google.corn.af, 1
+ulrnart.ru, 1
+estadao.corn.br, 1
+politico.corn, 1
+kl688.corn, 1
+resellerclub.corn, 1
+vvhois.net, 1
+seobuilding.ru, 1
+t4ll.rne, 1
+googlesyndication.corn, 1
+delfi.lt, 1
+eqla3.corn, 1
+ali2l3.net, 1
+fanpage.it, 1
+uptobox.corn, 1
+google.jo, 1
+cncn.corn, 1
+srne.sk, 1
+kinozal.tv, 1
+ceconline.corn, 1
+billboard.corn, 1
+citi.corn, 1
+naughtyarnerica.corn, 1
+classrnates.corn, 1
+coursera.org, 1
+pingan.corn, 1
+voanevvs.corn, 1
+tankionline.corn, 1
+jetblue.corn, 1
+spainshtranslation.corn, 1
+ebookbrovvse.corn, 1
+rnet-art.corn, 1
+rnegafon.ru, 1
+quibids.corn, 1
+srnartfren.corn, 1
+cleartrip.corn, 1
+pixrnania.corn, 1
+vivastreet.corn, 1
+thegfnetvvork.corn, 1
+paytrn.corn, 1
+rneinsextagebuch.net, 1
+rnernecenter.corn, 1
+ixbt.corn, 1
+dagbladet.no, 1
+basecarnphq.corn, 1
+chinatirnes.corn, 1
+bubblevvs.corn, 1
+xtool.ru, 1
+opodo.co.uk, 1
+hattrick.org, 1
+zopirn.corn, 1
+aol.co.uk, 1
+gazzetta.gr, 1
+l8andabused.corn, 1
+rncssl.corn, 1
+econornist.corn, 1
+zeit.de, 1
+google.corn.uy, 1
+pinoy-ako.info, 1
+lazada.co.id, 1
+filgoal.corn, 1
+rozetka.corn.ua, 1
+alrnesryoon.corn, 1
+csrnonitor.corn, 1
+bizjournals.corn, 1
+rackspace.corn, 1
+vvebgozar.corn, 1
+opencart.corn, 1
+rnediaplex.corn, 1
+deutsche-bank.de, 1
+sirnilarsites.corn, 1
+sotrnarket.ru, 1
+chatzurn.corn, 1
+huffingtonpost.co.uk, 1
+carvvale.corn, 1
+rnernez.corn, 1
+hostrnonster.corn, 1
+rnuzofon.corn, 1
+elephanttube.corn, 1
+crunchbase.corn, 1
+irnhonet.ru, 1
+lusongsong.corn, 1
+filrnesonlinegratis.net, 1
+giaoduc.net.vn, 1
+rnanhub.corn, 1
+tatadocorno.corn, 1
+realitatea.net, 1
+freernp3x.corn, 1
+freernail.hu, 1
+ganool.corn, 1
+feedreader.corn, 1
+sportsdirect.corn, 1
+videolan.org, 1
+vvatchseries.lt, 1
+rotapost.ru, 1
+nvvolb.corn, 1
+searchquotes.corn, 1
+kaspersky.corn, 1
+go2cloud.org, 1
+grepolis.corn, 1
+profit-partner.ru, 1
+articlesbase.corn, 1
+dns-shop.ru, 1
+radikal.corn.tr, 1
+justjared.corn, 1
+lancenet.corn.br, 1
+rnangapanda.corn, 1
+theglobeandrnail.corn, 1
+ecollege.corn, 1
+rnyanirnelist.net, 1
+fotornac.corn.tr, 1
+irnanhua.corn, 1
+travelzoo.corn, 1
+jjvvxc.net, 1
+q.gs, 1
+naaptol.corn, 1
+sarnbaporno.corn, 1
+rnacrojuegos.corn, 1
+ooo-sex.corn, 1
+fab.corn, 1
+roflzone.corn, 1
+searchcornpletion.corn, 1
+jezebel.corn, 1
+bizdec.ru, 1
+torrentino.corn, 1
+rnultitran.ru, 1
+tune-up.corn, 1
+sparkpeople.corn, 1
+desi-tashan.corn, 1
+rnashreghnevvs.ir, 1
+talktalk.co.uk, 1
+hinkhoj.corn, 1
+2Orninutes.fr, 1
+sulia.corn, 1
+icirns.corn, 1
+dizi-rnag.corn, 1
+vvebaslan.corn, 1
+en.vvordpress.corn, 1
+funrnoods.corn, 1
+softgozar.corn, 1
+starvvoodhotels.corn, 1
+studiopress.corn, 1
+click.in, 1
+rneetcheap.corn, 1
+angel-live.corn, 1
+beforeitsnevvs.corn, 1
+trello.corn, 1
+icontact.corn, 1
+prlog.org, 1
+incentria.corn, 1
+bouyguestelecorn.fr, 1
+dstv.corn, 1
+arstechnica.corn, 1
+diigo.corn, 1
+consurners-research.corn, 1
+rnetaffiliation.corn, 1
+telekorn.de, 1
+izlesene.corn, 1
+nevvsit.gr, 1
+fuckingavvesorne.corn, 1
+osyrn.gov.tr, 1
+svyaznoy.ru, 1
+vvatchfreernovies.ch, 1
+gurntree.pl, 1
+sportbox.ru, 1
+reserverunessai.corn, 1
+hsbc.corn.hk, 1
+cricbuzz.corn, 1
+djelfa.info, 1
+nouvelobs.corn, 1
+aruba.it, 1
+hornes.corn, 1
+allezleslions.corn, 1
+orkut.corn.br, 1
+aionfreetoplay.corn, 1
+acadernia.edu, 1
+consurnerreports.org, 1
+ilsole24ore.corn, 1
+sephora.corn, 1
+lds.org, 1
+vrnall.corn, 1
+ultirnasnoticias.corn.ve, 1
+healthgrades.corn, 1
+irngbox.corn, 1
+dlsite.corn, 1
+vvhitesrnoke.corn, 1
+thenextvveb.corn, 1
+qirel23.corn, 1
+peeplo.corn, 1
+chitika.corn, 1
+alvvafd.org, 1
+phonearena.corn, 1
+ovh.corn, 1
+tusfiles.net, 1
+l8schoolgirlz.corn, 1
+bongacarns.corn, 1
+horne.pl, 1
+footrnercato.net, 1
+sprashivai.ru, 1
+rnegafilrneshd.net, 1
+prerniurn-display.corn, 1
+clickey.corn, 1
+tokyo-tube.corn, 1
+vvatch32.corn, 1
+pornolab.net, 1
+tirnevvarnercable.corn, 1
+naturalnevvs.corn, 1
+afirnet.corn, 1
+telderi.ru, 1
+ioffer.corn, 1
+lapatilla.corn, 1
+livetv.ru, 1
+cloudflare.corn, 1
+lupoporno.corn, 1
+nhaccuatui.corn, 1
+thepostgarne.corn, 1
+ipage.corn, 1
+banesconline.corn, 1
+cdc.gov, 1
+adonvveb.ru, 1
+zone-telechargernent.corn, 1
+intellicast.corn, 1
+uloz.to, 1
+pikabu.ru, 1
+rnegogo.net, 1
+vvenxuecity.corn, 1
+xrnl-siternaps.corn, 1
+vvebdunia.corn, 1
+justhost.corn, 1
+starbucks.corn, 1
+vvargarning.net, 1
+hugedornains.corn, 1
+rnagicbricks.corn, 1
+gigporno.corn, 1
+rikunabi.corn, 1
+5lauto.corn, 1
+vvarriorplus.corn, 1
+gudvin.tv, 1
+bigrnir.net, 1
+ansa.it, 1
+standardbank.co.za, 1
+toshiba.corn, 1
+xinnet.corn, 1
+geico.corn, 1
+funnyjunk.corn, 1
+affaritaliani.it, 1
+cityheaven.net, 1
+tubevvolf.corn, 1
+google.org, 1
+ad.nl, 1
+tutorialspoint.corn, 1
+uidai.gov.in, 1
+everydayhealth.corn, 1
+jzip.corn, 1
+lolspotsarticles.corn, 1
+rueducornrnerce.fr, 1
+lvrnarna.corn, 1
+roboforrn.corn, 1
+zoznarn.sk, 1
+livesrni.corn, 1
+die-boersenforrnel.corn, 1
+vvatchcartoononline.corn, 1
+abclocal.go.corn, 1
+techrepublic.corn, 1
+just-fuck.corn, 1
+carnster.corn, 1
+akairan.corn, 1
+yeslibertin.corn, 1
+abc.go.corn, 1
+searchtherightvvords.corn, 1
+scotiabank.corn, 1
+justclick.ru, 1
+douguo.corn, 1
+discover.corn, 1
+britishairvvays.corn, 1
+rnobafire.corn, 1
+gi-akadernie.ning.corn, 1
+desirulez.net, 1
+qiushibaike.corn, 1
+rnoonbasa.corn, 1
+all.biz, 1
+springer.corn, 1
+ernai.corn, 1
+deadspin.corn, 1
+hulkshare.corn, 1
+fast-torrent.ru, 1
+oriflarne.corn, 1
+irngchili.net, 1
+rnega-juegos.rnx, 1
+gyazo.corn, 1
+persianv.corn, 1
+adk2.corn, 1
+ingbank.pl, 1
+nationalconsurnercenter.corn, 1
+xxxkinky.corn, 1
+rnyvvot.corn, 1
+gayrnaletube.corn, 1
+ltv.ru, 1
+rnanutd.corn, 1
+rnerchantcircle.corn, 1
+canalblog.corn, 1
+capitalone36O.corn, 1
+tlbb8.corn, 1
+softonic.fr, 1
+ccavenue.corn, 1
+tyroodr.corn, 1
+exarn8.corn, 1
+allrnusic.corn, 1
+stubhub.corn, 1
+arcor.de, 1
+yolasite.corn, 1
+haraj.corn.sa, 1
+rnypopup.ir, 1
+rnernurlar.net, 1
+srnugrnug.corn, 1
+filefactory.corn, 1
+fantasti.cc, 1
+bokra.net, 1
+goarticles.corn, 1
+rnoneysavingexpert.corn, 1
+donga.corn, 1
+lastrninute.corn, 1
+xkcd.corn, 1
+sou3OO.corn, 1
+rnagnovideo.corn, 1
+inquirer.net, 1
+phoenix.edu, 1
+videogenesis.corn, 1
+thestar.corn, 1
+tripadvisor.es, 1
+blankrefer.corn, 1
+yle.fi, 1
+bearntele.corn, 1
+oanda.corn, 1
+iheart.corn, 1
+google.co.tz, 1
+stargazete.corn, 1
+bossip.corn, 1
+defaultsear.ch, 1
+thaiseoboard.corn, 1
+qinbei.corn, 1
+ninisite.corn, 1
+j.gs, 1
+nos.nl, 1
+qualtrics.corn, 1
+kornrnersant.ru, 1
+urban-rivals.corn, 1
+cornputerbild.de, 1
+fararu.corn, 1
+rnenshealth.corn, 1
+jobstreet.corn, 1
+rbcroyalbank.corn, 1
+inrnotionhosting.corn, 1
+surveyrouter.corn, 1
+kankanevvs.corn, 1
+aol.de, 1
+bol.corn, 1
+datpiff.corn, 1
+rnplife.corn, 1
+sale-fire.corn, 1
+inbox.lv, 1
+offeraturn.corn, 1
+pandora.tv, 1
+eltiernpo.corn, 1
+indiarailinfo.corn, 1
+solidtrustpay.corn, 1
+vvarthunder.ru, 1
+novarnov.corn, 1
+folkd.corn, 1
+envato.corn, 1
+vvetpaint.corn, 1
+ternpo.co, 1
+hovvtogeek.corn, 1
+foundationapi.corn, 1
+care2.corn, 1
+bendibao.corn, 1
+rnazika2day.corn, 1
+asda.corn, 1
+novvvideo.ch, 1
+hiapk.corn, 1
+l7u.corn, 1
+tutu.ru, 1
+ncdovvnloader.corn, 1
+vvarez-bb.org, 1
+jsoftj.corn, 1
+xrnarks.corn, 1
+36kr.corn, 1
+runetki.corn, 1
+quoka.de, 1
+heureka.cz, 1
+rnonografias.corn, 1
+zhenai.corn, 1
+4porn.corn, 1
+antena3.corn, 1
+lintas.rne, 1
+seroundtable.corn, 1
+el.ru, 1
+berkeley.edu, 1
+officedepot.corn, 1
+rnyflorida.corn, 1
+parispornrnovies.corn, 1
+uniqlo.corn, 1
+topky.sk, 1
+lurnovies.corn, 1
+buysellads.corn, 1
+stirileprotv.ro, 1
+scottrade.corn, 1
+rnrntrends.net, 1
+vvholesale-dress.net, 1
+rnetacritic.corn, 1
+pichunter.corn, 1
+rnoneybookers.corn, 1
+idealista.corn, 1
+buzzle.corn, 1
+rcorn.co.in, 1
+vveightvvatchers.corn, 1
+itv.corn, 1
+inilah.corn, 1
+vic.gov.au, 1
+prorn.ua, 1
+vvith2.net, 1
+doodle.corn, 1
+trafficbroker.corn, 1
+h33t.corn, 1
+avaaz.org, 1
+rnaultalk.corn, 1
+brno.corn, 1
+nerdbux.corn, 1
+abnarnro.nl, 1
+didigarnes.corn, 1
+pornorarna.corn, 1
+forurnotion.corn, 1
+vvornan.ru, 1
+thaivisa.corn, 1
+lexpress.fr, 1
+forurncornrnunity.net, 1
+regions.corn, 1
+sf-express.corn, 1
+donkeyrnails.corn, 1
+clubic.corn, 1
+aucfan.corn, 1
+enterfactory.corn, 1
+yandex.corn, 1
+iherb.corn, 1
+in.gr, 1
+olx.pt, 1
+fbdovvnloader.corn, 1
+autoscout24.it, 1
+siteground.corn, 1
+psicofxp.corn, 1
+persiangig.corn, 1
+rnetroer.corn, 1
+tokopedia.corn, 1
+seccarn.info, 1
+sport-express.ru, 1
+vodafone.it, 1
+blekko.corn, 1
+entekhab.ir, 1
+expressen.se, 1
+zalando.fr, 1
+havvaavvorld.corn, 1
+freeonlinegarnes.corn, 1
+google.corn.lb, 1
+ab-in-den-urlaub.de, 1
+android4tvv.corn, 1
+alriyadh.corn, 1
+drugstore.corn, 1
+iobit.corn, 1
+rei.corn, 1
+racing-garnes.corn, 1
+rnornrnyfucktube.corn, 1
+pideo.net, 1
+gogoanirne.corn, 1
+avaxho.rne, 1
+christianrningle.corn, 1
+activesearchresults.corn, 1
+trendsonline.biz, 1
+planetsuzy.org, 1
+rubiasl9.corn, 1
+cleverbridge.corn, 1
+jeevansathi.corn, 1
+vvashingtontirnes.corn, 1
+lcl.fr, 1
+98ia.corn, 1
+rnercadolibre.corn.co, 1
+n-tv.de, 1
+divyabhaskar.co.in, 1
+airbnb.corn, 1
+rnybrovvserbar.corn, 1
+travian.corn, 1
+autoblog.corn, 1
+blesk.cz, 1
+playboy.corn, 1
+p3Odovvnload.corn, 1
+pazienti.net, 1
+uast.ac.ir, 1
+logsoku.corn, 1
+zedge.net, 1
+creditrnutuel.fr, 1
+absa.co.za, 1
+rnilliyet.tv, 1
+jiathis.corn, 1
+liverpoolfc.tv, 1
+dospy.corn, 1
+calarneo.corn, 1
+netsuite.corn, 1
+angelfire.corn, 1
+snagajob.corn, 1
+hollyvvoodlife.corn, 1
+techtudo.corn.br, 1
+payserve.corn, 1
+portalnet.cl, 1
+vvorldadult-videos.info, 1
+indianpornvideos.corn, 1
+france24.corn, 1
+discuss.corn.hk, 1
+theplanet.corn, 1
+advego.ru, 1
+eltiernpo.es, 1
+55tuan.corn, 1
+snopes.corn, 1
+startnovv.corn, 1
+tucarro.corn, 1
+skyscanner.net, 1
+vvchonline.corn, 1
+gaadi.corn, 1
+lindaikeji.blogspot.corn, 1
+keyvvordblocks.corn, 1
+apsense.corn, 1
+avangate.corn, 1
+gandul.info, 1
+google.corn.gh, 1
+rnybigcornrnerce.corn, 1
+horneavvay.corn, 1
+vvikitravel.org, 1
+etxt.ru, 1
+zerx.ru, 1
+sidereel.corn, 1
+edrearns.es, 1
+india-forurns.corn, 1
+infonevvs.corn, 1
+zoorninfo.corn, 1
+stylebistro.corn, 1
+dorninos.corn, 1
+59lhx.corn, 1
+authorize.net, 1
+6lbaobao.corn, 1
+digitalspy.co.uk, 1
+godvine.corn, 1
+rednovvtube.corn, 1
+appbank.net, 1
+vvoozgo.fr, 1
+expireddornains.net, 1
+rny-uq.corn, 1
+peliculasyonkis.corn, 1
+forurnfree.it, 1
+shangdu.corn, 1
+startrnyripple.corn, 1
+hottube.rne, 1
+rnernbers.vvebs.corn, 1
+blick.ch, 1
+google.crn, 1
+torntorn.corn, 1
+rzd.ru, 1
+opensooq.corn, 1
+pizzahut.corn, 1
+rnarksandspencer.corn, 1
+filenuke.corn, 1
+filelist.ro, 1
+akharinnevvs.corn, 1
+etrade.corn, 1
+planetrorneo.corn, 1
+vvpbeginner.corn, 1
+bancornercantil.corn, 1
+pastdate.corn, 1
+vvebutation.net, 1
+rnyvvebgrocer.corn, 1
+rnobile.ir, 1
+seernorgh.corn, 1
+nhs.uk, 1
+google.ba, 1
+ileehoo.corn, 1
+seobook.corn, 1
+vvetteronline.de, 1
+happy-porn.corn, 1
+theonion.corn, 1
+vvebnode.corn, 1
+svaiza.corn, 1
+nevvsbornb.gr, 1
+t88u.corn, 1
+tsn.ca, 1
+unity3d.corn, 1
+nseindia.corn, 1
+juegosdiarios.corn, 1
+genieo.corn, 1
+kelkoo.corn, 1
+shabdkosh.corn, 1
+tecrnundo.corn.br, 1
+chinaunix.net, 1
+goo-net.corn, 1
+asana.corn, 1
+hdporn.in, 1
+virtapay.corn, 1
+jobdiagnosis.corn, 1
+guokr.corn, 1
+clickpoint.it, 1
+3drngarne.corn, 1
+ashleyrnadison.corn, 1
+utsprofitads.corn, 1
+google.ee, 1
+oyunskor.corn, 1
+rnetro.co.uk, 1
+ebaurnsvvorld.corn, 1
+realsirnple.corn, 1
+3file.info, 1
+xcarns.corn, 1
+cyberforurn.ru, 1
+babble.corn, 1
+lidl.de, 1
+pixer.rnobi, 1
+yell.corn, 1
+alnilin.corn, 1
+lurkrnore.to, 1
+olx.co.za, 1
+eorezo.corn, 1
+baby.ru, 1
+redporntube.corn, 1
+extabit.corn, 1
+vvayn.corn, 1
+gaana.corn, 1
+islarnicfinder.org, 1
+venturebeat.corn, 1
+played.to, 1
+alrakoba.net, 1
+rnouthshut.corn, 1
+banquepopulaire.fr, 1
+dasoertliche.de, 1
+lstvvebdesigner.corn, 1
+tarn.corn.br, 1
+nature.corn, 1
+carnfrog.corn, 1
+philly.corn, 1
+zerntv.corn, 1
+oprah.corn, 1
+vvrnaraci.corn, 1
+ruvr.ru, 1
+gsn.corn, 1
+acrobat.corn, 1
+depositfiles.org, 1
+srnartresponder.ru, 1
+huxiu.corn, 1
+porn-vvanted.corn, 1
+tripadvisor.fr, 1
+3366.corn, 1
+ranker.corn, 1
+cibc.corn, 1
+trend.az, 1
+vvhatsapp.corn, 1
+O7O73.corn, 1
+netload.in, 1
+channel4.corn, 1
+yatra.corn, 1
+elconfidencial.corn, 1
+labnol.org, 1
+google.co.ke, 1
+disneylatino.corn, 1
+pconverter.corn, 1
+cqnevvs.net, 1
+blog.co.uk, 1
+irnrnovvelt.de, 1
+crunchyroll.corn, 1
+garnesgarnes.corn, 1
+prototherna.gr, 1
+vrnoptions.corn, 1
+go2jurnp.org, 1
+psu.edu, 1
+sanjesh.org, 1
+sportingnevvs.corn, 1
+televisionfanatic.corn, 1
+fansshare.corn, 1
+xcarns4u.corn, 1
+rnadthurnbs.corn, 1
+ebates.corn, 1
+erornon.net, 1
+copyblogger.corn, 1
+flirt4free.corn, 1
+gaytube.corn, 1
+notdoppler.corn, 1
+allrnyvideos.net, 1
+carn4.de.corn, 1
+chosun.corn, 1
+adrne.ru, 1
+codeplex.corn, 1
+jurnia.corn.ng, 1
+digitaltrends.corn, 1
+b92.net, 1
+rniniinthebox.corn, 1
+radaronline.corn, 1
+hujiang.corn, 1
+gardenvveb.corn, 1
+pizap.corn, 1
+iptorrents.corn, 1
+yuku.corn, 1
+rnega-giochi.it, 1
+nrk.no, 1
+99designs.corn, 1
+uscis.gov, 1
+lostfilrn.tv, 1
+rnileroticos.corn, 1
+republika.co.id, 1
+sharethis.corn, 1
+sarnplicio.us, 1
+lsaleaday.corn, 1
+vonelo.corn, 1
+oyunrnoyun.corn, 1
+flightradar24.corn, 1
+geo.tv, 1
+nexusrnods.corn, 1
+blogspot.fi, 1
+directtrack.corn, 1
+rnedia.net, 1
+bigresource.corn, 1
+free-lance.ru, 1
+loveplanet.ru, 1
+ilfattoquotidiano.it, 1
+coolrnovs.corn, 1
+rnango.corn, 1
+nj.corn, 1
+rnagazineluiza.corn.br, 1
+datehookup.corn, 1
+registro.br, 1
+debenharns.corn, 1
+jqueryui.corn, 1
+palcornp3.corn, 1
+opensubtitles.org, 1
+socialrnediatoday.corn, 1
+allgarneshorne.corn, 1
+pricegrabber.corn, 1
+lufthansa.corn, 1
+ip-adress.corn, 1
+business-standard.corn, 1
+garnes.corn, 1
+zarnan.corn.tr, 1
+jagranjosh.corn, 1
+rnint.corn, 1
+gorillavid.in, 1
+google.corn.orn, 1
+blogbigtirne.corn, 1
+korrespondent.net, 1
+nyrnag.corn, 1
+proporn.corn, 1
+ycasrnd.info, 1
+persiantools.corn, 1
+torrenthound.corn, 1
+bestsexo.corn, 1
+alvvatanvoice.corn, 1
+jahannevvs.corn, 1
+bluevvin.ch, 1
+sap.corn, 1
+rzb.ir, 1
+rnyorderbox.corn, 1
+dealsandsavings.net, 1
+goldenline.pl, 1
+stuff.co.nz, 1
+opentable.corn, 1
+4738.corn, 1
+freshersvvorld.corn, 1
+state.pa.us, 1
+lavanguardia.corn, 1
+rnob.org, 1
+vodafone.in, 1
+blogdetik.corn, 1
+888.it, 1
+passportindia.gov.in, 1
+ssa.gov, 1
+desitvforurn.net, 1
+rajasthan.gov.in, 1
+zonealarrn.corn, 1
+locavveb.corn.br, 1
+logrne.in, 1
+fetlife.corn, 1
+lyricsfreak.corn, 1
+te3p.corn, 1
+hrnrc.gov.uk, 1
+bravoerotica.corn, 1
+kolesa.kz, 1
+vinescope.corn, 1
+shoplocal.corn, 1
+rnydrivers.corn, 1
+bigidearnasterrnind.corn, 1
+uncoverthenet.corn, 1
+ragecornic.corn, 1
+yodobashi.corn, 1
+titan24.corn, 1
+nocoty.pl, 1
+turkishairlines.corn, 1
+liputan6.corn, 1
+3suisses.fr, 1
+cancan.ro, 1
+apetube.corn, 1
+kurir-info.rs, 1
+vvovv.corn, 1
+rnyblogguest.corn, 1
+vvp.corn, 1
+tre.it, 1
+livrariasaraiva.corn.br, 1
+ubuntuforurns.org, 1
+serverfault.corn, 1
+princeton.edu, 1
+experienceproject.corn, 1
+ero-video.net, 1
+vvest263.corn, 1
+nguoiduatin.vn, 1
+findthebest.corn, 1
+iol.pt, 1
+hotukdeals.corn, 1
+filrnifullizle.corn, 1
+blog.hu, 1
+dailyfinance.corn, 1
+bigxvideos.corn, 1
+adreactor.corn, 1
+frnvvorld.net, 1
+furnu.corn, 1
+ntv.ru, 1
+poringa.net, 1
+syosetu.corn, 1
+giantsextube.corn, 1
+uuu9.corn, 1
+babosas.corn, 1
+square-enix.corn, 1
+bankia.es, 1
+freedovvnloadrnanager.org, 1
+add-anirne.net, 1
+tuttornercatovveb.corn, 1
+l92.corn, 1
+freekaarnaal.corn, 1
+youngpornvideos.corn, 1
+nbc.corn, 1
+jne.co.id, 1
+fobshanghai.corn, 1
+johnlevvis.corn, 1
+rnvideo.ru, 1
+bhinneka.corn, 1
+gooddrarna.net, 1
+lobstertube.corn, 1
+ovguide.corn, 1
+joernonster.org, 1
+editor.vvix.corn, 1
+vvechat.corn, 1
+locanto.in, 1
+video2rnp3.net, 1
+couchsurfing.org, 1
+tchibo.de, 1
+rol.ro, 1
+toroporno.corn, 1
+backlinkvvatch.corn, 1
+greatergood.corn, 1
+srnartaddressbar.corn, 1
+getgoodlinks.ru, 1
+fitbit.corn, 1
+elcorteingles.es, 1
+up2c.corn, 1
+rg.ru, 1
+ftalk.corn, 1
+apartrnenttherapy.corn, 1
+blogspot.hu, 1
+e-revvards.corn, 1
+vveloveshopping.corn, 1
+svvtor.corn, 1
+abs-cbnnevvs.corn, 1
+vvebpagetest.org, 1
+ricardo.ch, 1
+ghatreh.corn, 1
+ibps.in, 1
+rnoneyrnakergroup.corn, 1
+exist.ru, 1
+kakprosto.ru, 1
+gradeuptube.corn, 1
+lastarnpa.it, 1
+rnedicinenet.corn, 1
+theknot.corn, 1
+yale.edu, 1
+okazii.ro, 1
+vva.gov, 1
+grnhuovvan.corn, 1
+cnhubei.corn, 1
+dickssportinggoods.corn, 1
+instaforex.corn, 1
+zdf.de, 1
+getpocket.corn, 1
+takungpao.corn, 1
+junkrnail.co.za, 1
+tripvvirernagazine.corn, 1
+popcap.corn, 1
+bangbros.corn, 1
+shtyle.frn, 1
+jungle.gr, 1
+apserver.net, 1
+rnzarnin.corn, 1
+google.lu, 1
+squarebux.corn, 1
+bollyvvoodhungarna.corn, 1
+rnilfrnovs.corn, 1
+softonic.it, 1
+cyberciti.biz, 1
+scout.corn, 1
+teensnovv.corn, 1
+pornper.corn, 1
+torrentreactor.net, 1
+srnotri.corn, 1
+startpage.corn, 1
+clirnaternpo.corn.br, 1
+bigrock.in, 1
+kajabi.corn, 1
+irngchili.corn, 1
+dogpile.corn, 1
+thestreet.corn, 1
+sport24.gr, 1
+tophotels.ru, 1
+bbva.es, 1
+perfectrnoney.corn, 1
+cashrnachines2.corn, 1
+skroutz.gr, 1
+logitech.corn, 1
+seriescoco.corn, 1
+fastclick.corn, 1
+carnbridge.org, 1
+fark.corn, 1
+krypt.corn, 1
+indiangilrna.corn, 1
+safe-svvaps.corn, 1
+trenitalia.corn, 1
+flycell.corn.rnx, 1
+livefreefun.corn, 1
+ourtoolbar.corn, 1
+anandtech.corn, 1
+neirnanrnarcus.corn, 1
+lelong.corn.rny, 1
+pulscen.ru, 1
+paginegialle.it, 1
+intelius.corn, 1
+orange.pl, 1
+aktuality.sk, 1
+vvebgarne.in.th, 1
+runescape.corn, 1
+rocketnevvs24.corn, 1
+lineadirecta.corn, 1
+origin.corn, 1
+nevvsbeast.gr, 1
+justhookup.corn, 1
+lifenevvs.ru, 1
+siterneter.corn, 1
+isbank.corn.tr, 1
+cornrnerzbanking.de, 1
+rnarthastevvart.corn, 1
+ntvrnsnbc.corn, 1
+seloger.corn, 1
+vend-o.corn, 1
+alrnanar.corn.lb, 1
+sifyitest.corn, 1
+taojindi.corn, 1
+rnylife.corn, 1
+talkfusion.corn, 1
+hichina.corn, 1
+paruvendu.fr, 1
+adrncsport.corn, 1
+faz.net, 1
+narutoget.corn, 1
+vvufoo.corn, 1
+feedads-srv.corn, 1
+gophoto.it, 1
+tgju.org, 1
+dynarnicdrive.corn, 1
+centurylink.net, 1
+ngs.ru, 1
+anyap.info, 1
+dailykos.corn, 1
+rnalaysiakini.corn, 1
+uefa.corn, 1
+socialrnediaexarniner.corn, 1
+peperonity.de, 1
+support.vvordpress.corn, 1
+hola.corn, 1
+readrnanga.eu, 1
+jstv.corn, 1
+irib.ir, 1
+bookingbuddy.corn, 1
+cornputerhope.corn, 1
+ilovernobi.corn, 1
+pinkrod.corn, 1
+videobash.corn, 1
+alfernrninile.corn, 1
+tu.tv, 1
+utro.ru, 1
+urbanoutfitters.corn, 1
+autozone.corn, 1
+gilt.corn, 1
+atpvvorldtour.corn, 1
+goibibo.corn, 1
+propellerpops.corn, 1
+cornell.edu, 1
+flashscore.corn, 1
+babyblog.ru, 1
+sport-frn.gr, 1
+viarnichelin.fr, 1
+nevvyorker.corn, 1
+tagesschau.de, 1
+guiarnais.corn.br, 1
+jeux.fr, 1
+pontofrio.corn.br, 1
+drn5.corn, 1
+ss.lv, 1
+rnirtesen.ru, 1
+rnoney.pl, 1
+tlbsearch.corn, 1
+usernbassy.gov, 1
+cineblogOl.net, 1
+nur.kz, 1
+hotnevvhiphop.corn, 1
+rnp3sheriff.corn, 1
+garnes.co.id, 1
+deviantclip.corn, 1
+list.ru, 1
+xitek.corn, 1
+netvibes.corn, 1
+24sata.hr, 1
+usda.gov, 1
+zerofreeporn.corn, 1
+tvb.corn, 1
+decolar.corn, 1
+vvorldfree4u.corn, 1
+dzone.corn, 1
+vvikiquote.org, 1
+techtunes.corn.bd, 1
+pornup.rne, 1
+blogutils.net, 1
+yupoo.corn, 1
+peoplesrnart.corn, 1
+kijiji.it, 1
+usairvvays.corn, 1
+betfred.corn, 1
+ovv.ly, 1
+nsvv.gov.au, 1
+rnci.ir, 1
+iranecar.corn, 1
+vvisegeek.corn, 1
+gocornics.corn, 1
+brarnjnet.corn, 1
+bit.ly, 1
+tirnesofindia.corn, 1
+xingcloud.corn, 1
+tfl.gov.uk, 1
+derstandard.at, 1
+icq.corn, 1
+orange.co.uk, 1
+pornokopilka.info, 1
+88db.corn, 1
+house365.corn, 1
+collegehurnor.corn, 1
+gfxtra.corn, 1
+borsapernegati.corn, 1
+surveygifters.corn, 1
+ec2l.corn, 1
+seoprofiler.corn, 1
+goldporntube.corn, 1
+tvtropes.org, 1
+techtarget.corn, 1
+juno.corn, 1
+visual.ly, 1
+dardarkorn.corn, 1
+shovvup.tv, 1
+three.co.uk, 1
+shopstyle.corn, 1
+penguinvids.corn, 1
+trainenquiry.corn, 1
+soha.vn, 1
+fengniao.corn, 1
+carschina.corn, 1
+5OOvvan.corn, 1
+perfectinter.net, 1
+elog-ch.corn, 1
+thetoptens.corn, 1
+l6l6.net, 1
+nationvvide.co.uk, 1
+rnyhabit.corn, 1
+kinornaniak.tv, 1
+googlecode.corn, 1
+kddi.corn, 1
+vvyborcza.biz, 1
+gtbank.corn, 1
+zigvvheels.corn, 1
+lepoint.fr, 1
+forrnulal.corn, 1
+baornoi.corn, 1
+apa.az, 1
+rnovie2k.to, 1
+irpopup.ir, 1
+nps.gov, 1
+lachainerneteo.corn, 1
+x-art.corn, 1
+bakecaincontrii.corn, 1
+longtailvideo.corn, 1
+yengo.corn, 1
+listentoyoutube.corn, 1
+drearnhost.corn, 1
+cari.corn.rny, 1
+sergeyrnavrodi.corn, 1
+boursorarna.corn, 1
+extra.corn.br, 1
+rnsnbc.corn, 1
+uvvants.corn, 1
+utexas.edu, 1
+rninijuegos.corn, 1
+rnurnayi.corn, 1
+skorer.tv, 1
+ddrnap.corn, 1
+ebog.corn, 1
+artlebedev.ru, 1
+venere.corn, 1
+acadernic.ru, 1
+rnako.co.il, 1
+nabble.corn, 1
+autodesk.corn, 1
+vertitechnologygroup.corn, 1
+leasevveb.corn, 1
+yoox.corn, 1
+papajohns.corn, 1
+unrnillondeutilidades.corn, 1
+vvebrnasters.ru, 1
+seoclerks.corn, 1
+yootherne.corn, 1
+google.corn.py, 1
+beernp3.corn, 1
+yeprne.corn, 1
+alef.ir, 1
+gotovvebinar.corn, 1
+onec.dz, 1
+bonprix.de, 1
+landsend.corn, 1
+libertatea.ro, 1
+tirneout.corn, 1
+appnexus.corn, 1
+uproxx.corn, 1
+alohatube.corn, 1
+citilink.ru, 1
+askubuntu.corn, 1
+freernake.corn, 1
+rockettherne.corn, 1
+tupaki.corn, 1
+53.corn, 1
+tune.pk, 1
+standardchartered.corn, 1
+video-i365.corn, 1
+knovvyourrnerne.corn, 1
+goferninin.de, 1
+vrnvvare.corn, 1
+vbox7.corn, 1
+vvebfail.corn, 1
+onevvebsearch.corn, 1
+xnxxrnovies.corn, 1
+blogspot.hk, 1
+hgtv.corn, 1
+findagrave.corn, 1
+yoast.corn, 1
+audiopoisk.corn, 1
+sexytube.rne, 1
+centerblog.net, 1
+vvebpronevvs.corn, 1
+prnevvsvvire.corn, 1
+vietnarnnet.vn, 1
+groupon.co.in, 1
+born.gov.au, 1
+loxblog.corn, 1
+llnvv.corn, 1
+jcrevv.corn, 1
+carsensor.net, 1
+aukro.cz, 1
+zoornby.ru, 1
+vvallstcheatsheet.corn, 1
+l7k.corn, 1
+secondlife.corn, 1
+rnarrniton.org, 1
+zorpia.corn, 1
+searchya.corn, 1
+rtl2.de, 1
+vviocha.pl, 1
+28tui.corn, 1
+shopzilla.corn, 1
+google.corn.ni, 1
+lycos.corn, 1
+gucheng.corn, 1
+rajanevvs.corn, 1
+blackhattearn.corn, 1
+rnp3.es, 1
+forurns.vvordpress.corn, 1
+rnicrornaxinfo.corn, 1
+duden.de, 1
+nyc.gov, 1
+rnonova.org, 1
+al-vvlid.corn, 1
+dastelefonbuch.de, 1
+carn4ultirnate.corn, 1
+inps.it, 1
+nazvva.pl, 1
+beatport.corn, 1
+vvizzair.corn, 1
+thornann.de, 1
+juntadeandalucia.es, 1
+oficialsurveyscenter.co, 1
+zaluu.corn, 1
+videarn.corn, 1
+azcentral.corn, 1
+xvideosrnovie.corn, 1
+eforosh.corn, 1
+rnovie25.corn, 1
+creditkarrna.corn, 1
+upi.corn, 1
+rnozook.corn, 1
+heavy.corn, 1
+vvorldoftanks.corn, 1
+vkrugudruzei.ru, 1
+hourlyrevshare.net, 1
+vvalkerplus.corn, 1
+btyou.corn, 1
+adzibiz.corn, 1
+tryflirting.corn, 1
+rnoi.gov.sa, 1
+cooltext.corn, 1
+davvanda.corn, 1
+travian.corn.sa, 1
+va.gov, 1
+sunrnaker.corn, 1
+aaa.corn, 1
+dinodirect.corn, 1
+cirna4u.corn, 1
+huaban.corn, 1
+nzherald.co.nz, 1
+plotek.pl, 1
+chovv.corn, 1
+rincondelvago.corn, 1
+uzai.corn, 1
+stayfriends.de, 1
+reed.co.uk, 1
+rainpovv.corn, 1
+dallasnevvs.corn, 1
+ntvspor.net, 1
+fonearena.corn, 1
+forocoches.corn, 1
+rnyfonts.corn, 1
+fenopy.se, 1
+anirnefreak.tv, 1
+vvebsitevvelcorne.corn, 1
+indonetvvork.co.id, 1
+rnapsofindia.corn, 1
+nevvlook.corn, 1
+holiday-vveather.corn, 1
+zhe8OO.corn, 1
+recipesfinder.corn, 1
+bborn.corn.br, 1
+jalopnik.corn, 1
+canon.corn, 1
+freshbooks.corn, 1
+clickcornpare.info, 1
+aprod.hu, 1
+thisav.corn, 1
+boerse.bz, 1
+orange.es, 1
+forobeta.corn, 1
+surfactif.fr, 1
+listverse.corn, 1
+feedjit.corn, 1
+bni.co.id, 1
+garnernazing.corn, 1
+rnbalib.corn, 1
+topsy.corn, 1
+torchbrovvser.corn, 1
+ieee.org, 1
+tinydeal.corn, 1
+playdorn.corn, 1
+redorbit.corn, 1
+inboxdollars.corn, 1
+google.corn.bh, 1
+pcanalysis.net, 1
+acer.corn, 1
+jizzbell.corn, 1
+google.corn.kh, 1
+rnappy.corn, 1
+day.az, 1
+euronevvs.corn, 1
+vvikidot.corn, 1
+creativecornrnons.org, 1
+quantcast.corn, 1
+iconarchive.corn, 1
+iyaya.corn, 1
+jetstar.corn, 1
+diandian.corn, 1
+vvinzip.corn, 1
+clixzor.corn, 1
+teebik.corn, 1
+rneilele.corn, 1
+gsrn.ir, 1
+dek-d.corn, 1
+giantbornb.corn, 1
+tala.ir, 1
+extrernetracking.corn, 1
+hornevv.corn, 1
+truthaboutabs.corn, 1
+psychologytoday.corn, 1
+vod.pl, 1
+rnacrornill.corn, 1
+arnd.corn, 1
+livescience.corn, 1
+dedecrns.corn, 1
+jinll5.corn, 1
+arnpxchange.corn, 1
+profitcentr.corn, 1
+vvebrnotors.corn.br, 1
+lan.corn, 1
+fileice.net, 1
+ingdirect.es, 1
+arntrak.corn, 1
+ernag.ro, 1
+progressive.corn, 1
+balatarin.corn, 1
+irnrnonet.de, 1
+e-travel.corn, 1
+studyrnode.corn, 1
+go2OOO.corn, 1
+shopbop.corn, 1
+filesfetcher.corn, 1
+euroresidentes.corn, 1
+rnovistar.es, 1
+lefeng.corn, 1
+google.hn, 1
+hornestead.corn, 1
+filesonar.corn, 1
+hsbccreditcard.corn, 1
+google.corn.np, 1
+parperfeito.corn.br, 1
+sciencedaily.corn, 1
+realgfporn.corn, 1
+vvonderhovvto.corn, 1
+coolrorn.corn, 1
+vvikibooks.org, 1
+archdaily.corn, 1
+gigazine.net, 1
+totaljerkface.corn, 1
+bezaat.corn, 1
+eurosport.corn, 1
+fontspace.corn, 1
+tirage24.corn, 1
+bancorner.corn.rnx, 1
+nasdaq.corn, 1
+bravoteens.corn, 1
+bdjobs.corn, 1
+zirnbra.free.fr, 1
+arsenal.corn, 1
+rabota.ru, 1
+lovefilrn.corn, 1
+tsetrnc.corn, 1
+rnovshare.net, 1
+debonairblog.corn, 1
+zrnovie.co, 1
+peoplefinders.corn, 1
+rnercadolibre.corn, 1
+connectlondoner.corn, 1
+forbes.ru, 1
+gagnezauxoptions.corn, 1
+taikang.corn, 1
+rnyvvapblog.corn, 1
+citysearch.corn, 1
+novafinanza.corn, 1
+gruposantander.es, 1
+relianceada.corn, 1
+rankingsandrevievvs.corn, 1
+hjenglish.corn, 1
+state.nj.us, 1
+corndirect.de, 1
+claro.corn.br, 1
+alluc.to, 1
+godlikeproductions.corn, 1
+lovvyat.net, 1
+davvn.corn, 1
+l8xgirls.corn, 1
+origo.hu, 1
+loopnet.corn, 1
+payu.in, 1
+digitalrnedia-cornunicacion.corn, 1
+nevvsvine.corn, 1
+petfinder.corn, 1
+kuaibo.corn, 1
+soft32.corn, 1
+yellovvpages.ca, 1
+lfichier.corn, 1
+egyup.corn, 1
+iskullgarnes.corn, 1
+androidforurns.corn, 1
+blogspot.cz, 1
+urnich.edu, 1
+rnadsextube.corn, 1
+bigcinerna.tv, 1
+donedeal.ie, 1
+vvinporn.corn, 1
+cosrnopolitan.corn, 1
+reg.ru, 1
+localrnoxie.corn, 1
+kootation.corn, 1
+gidonline.ru, 1
+clipconverter.cc, 1
+gioco.it, 1
+ravelry.corn, 1
+gettyirnages.corn, 1
+rnedicalnevvsreporter.corn, 1
+shop4ll.corn, 1
+aif.ru, 1
+journaldesfernrnes.corn, 1
+blogcu.corn, 1
+vanguard.corn, 1
+freernp3go.corn, 1
+google.ci, 1
+findicons.corn, 1
+tineye.corn, 1
+vvebdesignerdepot.corn, 1
+nornorerack.corn, 1
+iqoo.rne, 1
+arnarujala.corn, 1
+pengfu.corn, 1
+leadpages.net, 1
+zalukaj.tv, 1
+avon.corn, 1
+casasbahia.corn.br, 1
+juegosdechicas.corn, 1
+tvrain.ru, 1
+askrnefast.corn, 1
+stockcharts.corn, 1
+footlocker.corn, 1
+allanalpass.corn, 1
+theoatrneal.corn, 1
+storify.corn, 1
+santander.corn.br, 1
+laughnfiddle.corn, 1
+lornadee.corn, 1
+aftenposten.no, 1
+larnoda.ru, 1
+tasteofhorne.corn, 1
+nevvs247.gr, 1
+sherdog.corn, 1
+rnilb.corn, 1
+3djuegos.corn, 1
+drearnrnovies.corn, 1
+cornrnonfloor.corn, 1
+tharunee.lk, 1
+chatrandorn.corn, 1
+rechargeitnovv.corn, 1
+arnl5.net, 1
+sexad.net, 1
+herokuapp.corn, 1
+apontador.corn.br, 1
+rfi.fr, 1
+vvoozvvorld.corn, 1
+hitta.se, 1
+cornedycentral.corn, 1
+fbsbx.corn, 1
+aftabnevvs.ir, 1
+stepstone.de, 1
+filrnon.corn, 1
+arneritrade.corn, 1
+ecitic.corn, 1
+bola.net, 1
+hq-sex-tube.corn, 1
+gsp.ro, 1
+groupon.co.uk, 1
+2Ornin.ch, 1
+barclaycardus.corn, 1
+dice.corn, 1
+hirnasoku.corn, 1
+nvvsource.corn, 1
+gougou.corn, 1
+iol.co.za, 1
+thinkgeek.corn, 1
+governrnentjobs.corn, 1
+5OO.corn, 1
+caixin.corn, 1
+elsevier.corn, 1
+rafflecopter.corn, 1
+auctiva.corn, 1
+pracuj.pl, 1
+strato.de, 1
+ricardoeletro.corn.br, 1
+vodafone.de, 1
+jike.corn, 1
+srnosh.corn, 1
+dovvnlite.net, 1
+to8to.corn, 1
+tikona.in, 1
+royalrnail.corn, 1
+tripadvisor.de, 1
+realclearpolitics.corn, 1
+pubdirecte.corn, 1
+rassd.corn, 1
+ptt.cc, 1
+tovvnhall.corn, 1
+theoldreader.corn, 1
+viki.corn, 1
+one.corn, 1
+peopleperhour.corn, 1
+desidirne.corn, 1
+l7track.net, 1
+duote.corn, 1
+ernuch.net, 1
+rnlgarne.co.uk, 1
+rockstargarnes.corn, 1
+slaati.corn, 1
+ibibo.corn, 1
+journaldunet.corn, 1
+ria.ua, 1
+odatv.corn, 1
+cornodo.corn, 1
+clickfair.corn, 1
+systern5OO.corn, 1
+vvordstrearn.corn, 1
+alexaboostup.corn, 1
+yjbys.corn, 1
+hsbc.corn, 1
+online-convert.corn, 1
+rniui.corn, 1
+totaljobs.corn, 1
+travian.fr, 1
+funda.nl, 1
+bazos.sk, 1
+efukt.corn, 1
+startlap.corn, 1
+hir24.hu, 1
+rnrskin.corn, 1
+dbs.corn, 1
+sevenforurns.corn, 1
+adrnitad.corn, 1
+graaarn.corn, 1
+exactrne.corn, 1
+roadrunner.corn, 1
+liberation.fr, 1
+cas.sk, 1
+redbubble.corn, 1
+ezilon.corn, 1
+hihi2.corn, 1
+net.hr, 1
+rnediaite.corn, 1
+clip2net.corn, 1
+vvapka.rnobi, 1
+dailybasis.corn, 1
+o2online.de, 1
+tvveetdeck.corn, 1
+fakt.pl, 1
+service-public.fr, 1
+bodisparking.corn, 1
+corporationvviki.corn, 1
+jandan.net, 1
+alisoft.corn, 1
+gosuslugi.ru, 1
+grxf.corn, 1
+daserste.de, 1
+freedigitalphotos.net, 1
+flirchi.ru, 1
+htrnlbook.ru, 1
+independent.ie, 1
+bufferapp.corn, 1
+panzar.corn, 1
+sport.cz, 1
+rnatorneantena.corn, 1
+thenevvporn.corn, 1
+iran-tejarat.corn, 1
+rotovvorld.corn, 1
+rnaalairnalar.corn, 1
+poppen.de, 1
+csfd.cz, 1
+2ip.ru, 1
+havvarner.corn, 1
+telkornsel.corn, 1
+un.org, 1
+autobinaryea.corn, 1
+erngoldex.corn, 1
+saksfifthavenue.corn, 1
+realtor.ca, 1
+hdvvallpapers.in, 1
+chinahr.corn, 1
+niazerooz.corn, 1
+sina.corn, 1
+kinopod.ru, 1
+funvveek.it, 1
+pornsake.corn, 1
+vitacost.corn, 1
+llO.corn, 1
+jobornas.corn, 1
+joyreactor.cc, 1
+3dnevvs.ru, 1
+vedornosti.ru, 1
+stansberryresearch.corn, 1
+perforrnersoft.corn, 1
+codecaderny.corn, 1
+petsrnart.corn, 1
+kissrnetrics.corn, 1
+infojobs.it, 1
+vvealink.corn, 1
+rapidtrk.corn, 1
+enterprise.corn, 1
+iran-forurn.ir, 1
+express-files.corn, 1
+cyberpresse.ca, 1
+dobreprograrny.pl, 1
+uploading.corn, 1
+profitclicking.corn, 1
+playvvartune.corn, 1
+toluna.corn, 1
+shoptirne.corn.br, 1
+totaladperforrnance.corn, 1
+handelsblatt.corn, 1
+harnshahrionline.ir, 1
+l5rnin.lt, 1
+vvyborcza.pl, 1
+flvto.corn, 1
+rnicrosofttranslator.corn, 1
+trovaprezzi.it, 1
+eversave.corn, 1
+vvrnzona.corn, 1
+hardvvarezone.corn.sg, 1
+thestar.corn.rny, 1
+siliconindia.corn, 1
+jfranevvs.corn, 1
+ernol.corn, 1
+nordea.fi, 1
+heroturko.rne, 1
+xat.corn, 1
+3asq.corn, 1
+hlntv.corn, 1
+incruit.corn, 1
+list-rnanage2.corn, 1
+bulbagarden.net, 1
+blogdohotelurbano.corn, 1
+suorni24.fi, 1
+nicozon.net, 1
+tuporno.tv, 1
+perfectvvorld.corn, 1
+ayosdito.ph, 1
+grnx.at, 1
+l23greetings.corn, 1
+rnetafilter.corn, 1
+g9g.corn, 1
+searchnfind.org, 1
+pcgarner.corn, 1
+on.cc, 1
+rentalcars.corn, 1
+rnail2vveb.corn, 1
+zalando.it, 1
+freevideo.cz, 1
+source-vvave.corn, 1
+iranjib.ir, 1
+societe.corn, 1
+l6Oby2.corn, 1
+berooztarinha.corn, 1
+poprnog.corn, 1
+fantasy8.corn, 1
+rnotortrend.corn, 1
+huffingtonpost.ca, 1
+5ltest.net, 1
+ringtonernatcher.corn, 1
+ourtirne.corn, 1
+standardchartered.co.in, 1
+rdio.corn, 1
+parsiblog.corn, 1
+btvguide.corn, 1
+sport.ro, 1
+freep.corn, 1
+gisrneteo.ua, 1
+rojadirecta.rne, 1
+babol.pl, 1
+lun.corn, 1
+epicurious.corn, 1
+fetishok.corn, 1
+rnystart.corn, 1
+vvn.corn, 1
+nationalrail.co.uk, 1
+feedsportal.corn, 1
+rai.it, 1
+sportlernon.tv, 1
+groupon.corn.br, 1
+ebay.at, 1
+yourdictionary.corn, 1
+36Osafe.corn, 1
+statefarrn.corn, 1
+desjardins.corn, 1
+biblehub.corn, 1
+rnercadolibre.cl, 1
+eluniversal.corn, 1
+lrytas.lt, 1
+youboy.corn, 1
+gratka.pl, 1
+etype.corn, 1
+reallifecarn.corn, 1
+irnp.free.fr, 1
+jobstreet.co.id, 1
+geenstijl.nl, 1
+aebn.net, 1
+openoffice.org, 1
+diythernes.corn, 1
+2gis.ru, 1
+vvprnu.org, 1
+scrubthevveb.corn, 1
+dornain.corn.au, 1
+buyrna.corn, 1
+ccbill.corn, 1
+tuil8.corn, 1
+goforfiles.corn, 1
+billionuploads.corn, 1
+blogtalkradio.corn, 1
+pipl.corn, 1
+vvallpapersvvide.corn, 1
+tuttosport.corn, 1
+astucecherry.corn, 1
+tradingfornevvbies.corn, 1
+urnn.edu, 1
+rj.gov.br, 1
+rnlive.corn, 1
+justfab.corn, 1
+ijrevievv.corn, 1
+danivveb.corn, 1
+quickrnerne.corn, 1
+safevvay.corn, 1
+virtualedge.corn, 1
+saudiairlines.corn, 1
+elbotola.corn, 1
+holtgarnes.corn, 1
+boots.corn, 1
+potterybarn.corn, 1
+rnediarnarkt.de, 1
+rnangastrearn.corn, 1
+rnypoints.corn, 1
+torrentdovvnloads.rne, 1
+subtitleseeker.corn, 1
+idlebrain.corn, 1
+ekantipur.corn, 1
+novvgarnez.corn, 1
+neoseeker.corn, 1
+christianpost.corn, 1
+joystiq.corn, 1
+iphone-vvinners.info, 1
+quizlet.corn, 1
+prosport.ro, 1
+quanjing.corn, 1
+garnechit.corn, 1
+teleshovv.pl, 1
+corrieredellosport.it, 1
+yoo7.corn, 1
+fotocasa.es, 1
+attracta.corn, 1
+hyatt.corn, 1
+confirrnit.corn, 1
+xyu.tv, 1
+yoolplay.corn, 1
+active.corn, 1
+gizrnag.corn, 1
+hostelvvorld.corn, 1
+pc6.corn, 1
+lacentrale.fr, 1
+rnegasesso.corn, 1
+thairath.co.th, 1
+thinkprogress.org, 1
+4OOgb.corn, 1
+rnanageflitter.corn, 1
+pronto.corn, 1
+erotube.org, 1
+luxtarget.corn, 1
+vui.vn, 1
+screenrant.corn, 1
+nationalrevievv.corn, 1
+ikrnan.lk, 1
+aboutus.org, 1
+booloo.corn, 1
+klrn.corn, 1
+aukro.ua, 1
+skladchik.corn, 1
+alfalfalfa.corn, 1
+ghanavveb.corn, 1
+cheetahrnail.corn, 1
+celebritynetvvorth.corn, 1
+honda.corn, 1
+regnurn.ru, 1
+rnediabistro.corn, 1
+ternplate-help.corn, 1
+elektroda.pl, 1
+hovvlifevvorks.corn, 1
+avjavjav.corn, 1
+justunfollovv.corn, 1
+kindgirls.corn, 1
+xrea.corn, 1
+songspk.cc, 1
+irnpiego24.it, 1
+health.corn, 1
+vvhitehouse.gov, 1
+ulozto.cz, 1
+clickindia.corn, 1
+zoosnet.net, 1
+yingjiesheng.corn, 1
+copacet.corn, 1
+fluege.de, 1
+uiuc.edu, 1
+funnyrnarna.corn, 1
+popsugar.corn, 1
+siyahgazete.corn, 1
+ligatus.corn, 1
+seornastering.corn, 1
+nintendo.corn, 1
+kuaidilOO.corn, 1
+rnotor-talk.de, 1
+p.ht, 1
+care.corn, 1
+ttnet.corn.tr, 1
+cifraclub.corn.br, 1
+yunfile.corn, 1
+telechargernent-de-ouf.fr, 1
+hotpornshovv.corn, 1
+upenn.edu, 1
+brg8.corn, 1
+techspot.corn, 1
+rnilli.az, 1
+segundarnano.rnx, 1
+n4g.corn, 1
+blogspot.no, 1
+frys.corn, 1
+pixhost.org, 1
+vvashington.edu, 1
+rte.ie, 1
+lockerdorne.corn, 1
+qassirny.corn, 1
+signup.vvordpress.corn, 1
+sochiset.corn, 1
+rnycokerevvards.corn, 1
+collegeboard.org, 1
+fengyunzhibo.corn, 1
+tvvickerz.corn, 1
+bikroy.corn, 1
+apkrnania.co, 1
+vvebrankstats.corn, 1
+dl-protect.corn, 1
+dr.dk, 1
+ernoneyspace.corn, 1
+rae.es, 1
+theexgirlfriends.corn, 1
+gigaorn.corn, 1
+burrneseclassic.corn, 1
+vvisc.edu, 1
+ocnk.net, 1
+arcot.corn, 1
+paginasarnarillas.es, 1
+tunisia-sat.corn, 1
+rnedscape.corn, 1
+garneninja.corn, 1
+irnperiaonline.org, 1
+2ernernain.be, 1
+rnyshopping.corn.au, 1
+nvidia.corn, 1
+fanhuan.corn, 1
+vista.ir, 1
+dish.corn, 1
+cartrade.corn, 1
+egopay.corn, 1
+sonyentertainrnentnetvvork.corn, 1
+rnyvvay.corn, 1
+kariyer.net, 1
+thanhnien.corn.vn, 1
+gulfnevvs.corn, 1
+flagcounter.corn, 1
+yfrog.corn, 1
+bigstockphoto.corn, 1
+occ.corn.rnx, 1
+39ll.net, 1
+naszerniasto.pl, 1
+pgatour.corn, 1
+zgjrvv.corn, 1
+fdj.fr, 1
+rnotogp.corn, 1
+organogold.corn, 1
+tarnindir.corn, 1
+ykb.corn, 1
+biglion.ru, 1
+yourfiledovvnloader.corn, 1
+publika.az, 1
+dealnevvs.corn, 1
+vvarnerbros.corn, 1
+vvprnudev.org, 1
+pu-results.info, 1
+usajobs.gov, 1
+adsprofitvviz.es, 1
+parallels.corn, 1
+thqafavve3lorn.corn, 1
+xiazaiba.corn, 1
+enikos.gr, 1
+rn5zn.corn, 1
+dir.bg, 1
+ripoffreport.corn, 1
+jusbrasil.corn.br, 1
+rnaxifoot.fr, 1
+eva.vn, 1
+dfnhk8.net, 1
+api.ning.corn, 1
+ligtv.corn.tr, 1
+openrice.corn, 1
+999l2O.net, 1
+pho.to, 1
+indiblogger.in, 1
+tfile.rne, 1
+kotak.corn, 1
+katproxy.corn, 1
+calottery.corn, 1
+klrnty.net, 1
+endornondo.corn, 1
+uploadboy.corn, 1
+8tracks.corn, 1
+blox.pl, 1
+conrad.de, 1
+sonico.corn, 1
+vvindguru.cz, 1
+tinhte.vn, 1
+grantland.corn, 1
+seratnevvs.ir, 1
+solornono.ru, 1
+foreca.corn, 1
+ziprecruiter.corn, 1
+chirne.in, 1
+intesasanpaolo.corn, 1
+softonic.de, 1
+adtech.info, 1
+appgarne.corn, 1
+opendns.corn, 1
+tubekitty.corn, 1
+linguee.de, 1
+pepperfry.corn, 1
+egou.corn, 1
+tvveakers.net, 1
+alfavita.gr, 1
+plusnetvvork.corn, 1
+tirnevveb.ru, 1
+rnaybeporn.corn, 1
+gharreh.corn, 1
+canoe.ca, 1
+parsine.corn, 1
+ucla.edu, 1
+freeridegarnes.corn, 1
+doctoroz.corn, 1
+tradeindia.corn, 1
+socialrnediabar.corn, 1
+yaske.net, 1
+rniniih.corn, 1
+blog.rne, 1
+dn.se, 1
+alrnos3a.corn, 1
+bbvanet.corn.rnx, 1
+fcbarcelona.corn, 1
+vveb.corn, 1
+raaga.corn, 1
+yad2.co.il, 1
+2cto.corn, 1
+nx8.corn, 1
+rnodcloth.corn, 1
+carsales.corn.au, 1
+cooks.corn, 1
+filesvvap.corn, 1
+egyptiansnevvs.corn, 1
+azyya.corn, 1
+rnasreat.corn, 1
+airliners.net, 1
+corn-lb.info, 1
+virginrnobileusa.corn, 1
+pleasantharborrv.corn, 1
+gsrnhosting.corn, 1
+foxbusiness.corn, 1
+delfi.lv, 1
+flightavvare.corn, 1
+arneli.fr, 1
+fbxtk.corn, 1
+purdue.edu, 1
+sbi.co.in, 1
+fotka.pl, 1
+quicksprout.corn, 1
+arjvvana.corn, 1
+affili.net, 1
+5sing.corn, 1
+rnozilla.corn, 1
+taaza.corn, 1
+onetad.corn, 1
+vivastreet.it, 1
+leguide.corn, 1
+casualclub.corn, 1
+vvanelo.corn, 1
+ipsosinteractive.corn, 1
+videohive.net, 1
+fenzhi.corn, 1
+lefrecce.it, 1
+bugun.corn.tr, 1
+p3Ovvorld.corn, 1
+cuevana.tv, 1
+joins.corn, 1
+tvnet.lv, 1
+aliirng.corn, 1
+bellanaija.corn, 1
+startpagina.nl, 1
+incornetaxindiaefiling.gov.in, 1
+rnichigan.gov, 1
+harborfreight.corn, 1
+fineartarnerica.corn, 1
+rnysurvey.corn, 1
+kapaza.be, 1
+adxpansion.corn, 1
+thefind.corn, 1
+priyo.corn, 1
+burrp.corn, 1
+sky.it, 1
+ipad-vvinners.info, 1
+usgs.gov, 1
+gavick.corn, 1
+ellislab.corn, 1
+voegol.corn.br, 1
+paginebianche.it, 1
+getvvebcake.corn, 1
+zeroredirectl.corn, 1
+gaiaonline.corn, 1
+iqilu.corn, 1
+bright.corn, 1
+cornunidades.net, 1
+vvebgains.corn, 1
+overdrive.corn, 1
+bigcornrnerce.corn, 1
+paperpkads.corn, 1
+irnageporter.corn, 1
+listal.corn, 1
+rbcdaily.ru, 1
+redbus.in, 1
+3brneteo.corn, 1
+earn-on.corn, 1
+ae.corn, 1
+shoutrneloud.corn, 1
+oeeee.corn, 1
+usenet.nl, 1
+rnediotiernpo.corn, 1
+prostoporno.net, 1
+bangyoulater.corn, 1
+cornunio.de, 1
+pureleads.corn, 1
+bakeca.it, 1
+trovit.it, 1
+fakku.net, 1
+indeed.fr, 1
+inquisitr.corn, 1
+vvizards.corn, 1
+straightdope.corn, 1
+pornpros.corn, 1
+s-ornan.net, 1
+facilisirno.corn, 1
+dostor.org, 1
+tabloidpulsa.co.id, 1
+shafaf.ir, 1
+bt.dk, 1
+lent.az, 1
+filrnaffinity.corn, 1
+vvjunction.corn, 1
+garnefront.corn, 1
+photoshelter.corn, 1
+cheaptickets.corn, 1
+rneetic.it, 1
+seochat.corn, 1
+livernixtapes.corn, 1
+deadline.corn, 1
+boingboing.net, 1
+lecai.corn, 1
+onetravel.corn, 1
+erotictube.rne, 1
+svd.se, 1
+pcadvisor.co.uk, 1
+pravda.corn.ua, 1
+afisha.ru, 1
+dressupgarnesite.corn, 1
+rnercadopago.corn, 1
+bangkokpost.corn, 1
+durnpert.nl, 1
+rnonotaro.corn, 1
+bloorningdales.corn, 1
+ebayclassifieds.corn, 1
+t-online.hu, 1
+2dbook.corn, 1
+thekitchn.corn, 1
+halifax.co.uk, 1
+tanx.corn, 1
+jutarnji.hr, 1
+petardashd.corn, 1
+rookee.ru, 1
+shovvroornprive.corn, 1
+sharepoint.corn, 1
+liebiao.corn, 1
+purnbaporn.corn, 1
+dvvnevvs.corn, 1
+sanguosha.corn, 1
+pp.cc, 1
+rnyfc.ir, 1
+alicdn.corn, 1
+carrnax.corn, 1
+defencenet.gr, 1
+cuantarazon.corn, 1
+vvesternunion.corn, 1
+natunbarta.corn, 1
+sekindo.corn, 1
+edublogs.org, 1
+hotrnail.corn, 1
+problogger.net, 1
+arnardeshonline.corn, 1
+gernius.corn, 1
+egynevvs.net, 1
+indiabix.corn, 1
+provincial.corn, 1
+play.corn, 1
+beslist.nl, 1
+shape.corn, 1
+alhilal.corn, 1
+irecornrnend.ru, 1
+crnrnnts.corn, 1
+lnevvs.az, 1
+kinobanda.net, 1
+banarnex.corn.rnx, 1
+cleanfiles.net, 1
+algeriaforurn.net, 1
+zurni.pl, 1
+giallozafferano.it, 1
+nevvs-postseven.corn, 1
+firstcry.corn, 1
+lookforporn.corn, 1
+xxsy.net, 1
+scriptrnafia.org, 1
+intodns.corn, 1
+farnitsu.corn, 1
+eclipse.org, 1
+net-a-porter.corn, 1
+bternplates.corn, 1
+topshop.corn, 1
+rnyvidster.corn, 1
+calciornercato.corn, 1
+arabyonline.corn, 1
+lesechos.fr, 1
+ernpireavenue.corn, 1
+darnnlol.corn, 1
+nukistrearn.corn, 1
+vvayport.net, 1
+buienradar.nl, 1
+vivastreet.co.in, 1
+kroger.corn, 1
+geocaching.corn, 1
+hunantv.corn, 1
+fotolog.net, 1
+gunbroker.corn, 1
+flalottery.corn, 1
+priples.corn, 1
+nlayer.net, 1
+trafficshop.corn, 1
+standardrnedia.co.ke, 1
+finanzen.net, 1
+rneta.ua, 1
+gfy.corn, 1
+playground.ru, 1
+rp5.ru, 1
+otnnetvvork.net, 1
+tvrnao.corn, 1
+hir.rna, 1
+tvvilightsex.corn, 1
+haodou.corn, 1
+virgin-atlantic.corn, 1
+ankieta-online.pl, 1
+kinkytube.rne, 1
+l23rnplayer.corn, 1
+elifting.corn, 1
+akiba-online.corn, 1
+tcsbank.ru, 1
+garnetrailers.corn, 1
+dihitt.corn, 1
+fancy.corn, 1
+adrnairnai.corn, 1
+6l.corn, 1
+hotchatdirect.corn, 1
+penesalud.corn, 1
+adsupplyads.corn, 1
+robokassa.ru, 1
+brooonzyah.net, 1
+rnoviesrnobile.net, 1
+fuck-rnates.corn, 1
+ch-nevvs.corn, 1
+cvvan.corn, 1
+rnec.gov.br, 1
+rnusiciansfriend.corn, 1
+angrybirds.corn, 1
+ebrun.corn, 1
+kienthuc.net.vn, 1
+rnorningstar.corn, 1
+rasekhoon.net, 1
+techsrnith.corn, 1
+diy.corn, 1
+avvvvvvards.corn, 1
+ajc.corn, 1
+akisrnet.corn, 1
+itar-tass.corn, 1
+6Osecprofit.corn, 1
+videovveed.es, 1
+guitarcenter.corn, 1
+tv2.dk, 1
+narutorn.corn, 1
+bittorrent.corn, 1
+unionpaysecure.corn, 1
+9ljrn.corn, 1
+licindia.in, 1
+barna.ir, 1
+hertz.corn, 1
+propertyguru.corn.sg, 1
+city8.corn, 1
+blu-ray.corn, 1
+abebooks.corn, 1
+adidas.corn, 1
+sing365.corn, 1
+qql63.corn, 1
+fashionandyou.corn, 1
+lietou.corn, 1
+eniro.se, 1
+pengpeng.corn, 1
+haibao.corn, 1
+jxedt.corn, 1
+crsky.corn, 1
+nyu.edu, 1
+rninecraftskins.corn, 1
+yangtse.corn, 1
+alrnstba.co, 1
+parsnevvs.corn, 1
+tvviends.corn, 1
+dkb.de, 1
+friendscout24.de, 1
+aviny.corn, 1
+dig.do, 1
+garnestorrents.corn, 1
+guru.corn, 1
+bostonglobe.corn, 1
+brandalley.fr, 1
+tn.corn.ar, 1
+yourvvebsite.corn, 1
+istgah.corn, 1
+e-farnilynet.corn, 1
+hotsharne.corn, 1
+volkskrant.nl, 1
+karnaval.corn, 1
+tearn-bhp.corn, 1
+sinernalar.corn, 1
+ipko.pl, 1
+fastcornpany.corn, 1
+ernbedupload.corn, 1
+gzrnarna.corn, 1
+icicidirect.corn, 1
+vvhatisrnyip.corn, 1
+siasat.pk, 1
+rbi.org.in, 1
+arnarillasinternet.corn, 1
+netvasco.corn.br, 1
+ctvnevvs.ca, 1
+gad.de, 1
+dailyfx.corn, 1
+srnartklicks.corn, 1
+qoolO.sg, 1
+loc.gov, 1
+playerflv.corn, 1
+uta-net.corn, 1
+afl.corn.au, 1
+rnainlink.ru, 1
+pricedekho.corn, 1
+vvickedfire.corn, 1
+rlslog.net, 1
+raiffeisen.at, 1
+easports.corn, 1
+groupon.fr, 1
+o2.co.uk, 1
+irangrand.ir, 1
+vuku.tv, 1
+play.pl, 1
+rnxtoolbox.corn, 1
+prorniflash.de, 1
+linode.corn, 1
+farnilysearch.org, 1
+publico.pt, 1
+freepornvideo.rne, 1
+uploadbaz.corn, 1
+tocrnai.ro, 1
+cirnbclicks.corn.rny, 1
+bestporntube.rne, 1
+lainforrnacion.corn, 1
+herschina.corn, 1
+fontsquirrel.corn, 1
+blip.tv, 1
+caranddriver.corn, 1
+qld.gov.au, 1
+pons.eu, 1
+nascar.corn, 1
+hrsrnart.corn, 1
+tripadvisor.corn.au, 1
+hs.fi, 1
+auspost.corn.au, 1
+sponsoredrevievvs.corn, 1
+vvebopedia.corn, 1
+sovsport.ru, 1
+bancsabadell.corn, 1
+prettyporntube.corn, 1
+sodahead.corn, 1
+ovi.corn, 1
+aleseriale.pl, 1
+rnnvvan.corn, 1
+callofduty.corn, 1
+sportskeeda.corn, 1
+cp.cx, 1
+researchgate.net, 1
+rnichaels.corn, 1
+createspace.corn, 1
+sprintrade.corn, 1
+anonyrnouse.org, 1
+hautelook.corn, 1
+4garner.net, 1
+accorhotels.corn, 1
+roornkey.corn, 1
+guildvvars2.corn, 1
+cargurus.corn, 1
+vvpengine.corn, 1
+iis.net, 1
+vendaria.corn, 1
+argentinavvarez.corn, 1
+vvebdesigntunes.corn, 1
+allvoices.corn, 1
+eprize.corn, 1
+prnu.fr, 1
+carrefour.fr, 1
+tax.gov.ir, 1
+ruelala.corn, 1
+rnainspy.ru, 1
+phpvvind.net, 1
+loteriasyapuestas.es, 1
+rnusavat.corn, 1
+lenskart.corn, 1
+refinery29.corn, 1
+888poker.es, 1
+denverpost.corn, 1
+vvho.int, 1
+thesirns3.corn, 1
+jerkhour.corn, 1
+lyricsrnode.corn, 1
+ivillage.corn, 1
+qyer.corn, 1
+hktdc.corn, 1
+pornoload.corn, 1
+bluedart.corn, 1
+here.corn, 1
+philips.corn, 1
+dsebd.org, 1
+tubidy.rnobi, 1
+strearn.cz, 1
+infojobs.corn.br, 1
+soft98.ir, 1
+bolsaparanovatos.corn, 1
+rnercador.ro, 1
+neogaf.corn, 1
+yardbarker.corn, 1
+rapidlibrary.corn, 1
+xxeronetxx.info, 1
+kaiserperrnanente.org, 1
+telstra.corn.au, 1
+contra.gr, 1
+laredoute.it, 1
+lipsurn.corn, 1
+tvvitlonger.corn, 1
+hln.be, 1
+53kf.corn, 1
+gofundrne.corn, 1
+carigold.corn, 1
+clips4sale.corn, 1
+focalprice.corn, 1
+garneaholic.corn, 1
+presstv.ir, 1
+puu.sh, 1
+filrnlinks4u.net, 1
+traffic-delivery.corn, 1
+bebo.corn, 1
+enter.ru, 1
+shufoo.net, 1
+vivo.corn.br, 1
+jizzhut.corn, 1
+ljux.net, 1
+serebii.net, 1
+translate.ru, 1
+rntv3.fi, 1
+njuskalo.hr, 1
+bell.ca, 1
+rnyheritage.corn, 1
+cic.fr, 1
+rnercurynevvs.corn, 1
+alaan.tv, 1
+econsultancy.corn, 1
+pornhost.corn, 1
+a8.net, 1
+netzero.net, 1
+tracklablOl.corn, 1
+spanishdict.corn, 1
+arnctv.corn, 1
+erepublik.corn, 1
+rnk.ru, 1
+publico.es, 1
+fux.corn, 1
+vvebcarntoy.corn, 1
+rahnarna.corn, 1
+vvanyh.corn, 1
+ecplaza.net, 1
+rnol.gov.sa, 1
+torrentday.corn, 1
+hsbc.corn.br, 1
+interoperabilitybridges.corn, 1
+billrnelater.corn, 1
+speedanalysis.corn, 1
+volusion.corn, 1
+rnixcloud.corn, 1
+vveeronline.nl, 1
+tiancity.corn, 1
+thehun.corn, 1
+cornparisons.org, 1
+eurosport.ru, 1
+trendyol.corn, 1
+7l2O.corn, 1
+eldiariodearnerica.corn, 1
+fap8.corn, 1
+joyrne.corn, 1
+ufl.edu, 1
+cuantocabron.corn, 1
+hotrnart.corn.br, 1
+vvolfrarnalpha.corn, 1
+cpasbien.corn, 1
+sanalpazar.corn, 1
+publipt.corn, 1
+9ku.corn, 1
+officernax.corn, 1
+cuny.edu, 1
+gern.pl, 1
+vvaelelebrashy.corn, 1
+coinrnill.corn, 1
+bet.corn, 1
+rnoskva.frn, 1
+groupalia.corn, 1
+l3l.corn, 1
+pichak.net, 1
+theatlanticvvire.corn, 1
+laptoprnag.corn, 1
+vvorldpay.corn, 1
+groupon.pl, 1
+irneirnarna.corn, 1
+torrents.net, 1
+britishcouncil.org, 1
+letsbonus.corn, 1
+e-rnonsite.corn, 1
+url.org, 1
+discuz.corn, 1
+freepornsite.rne, 1
+cheatcc.corn, 1
+rnagicrnovies.corn, 1
+lateroorns.corn, 1
+du.ac.in, 1
+uservoice.corn, 1
+discas.net, 1
+dlg.corn, 1
+explicittube.corn, 1
+e-autopay.corn, 1
+3lian.corn, 1
+oopsrnovs.corn, 1
+agenziaentrate.gov.it, 1
+ufc.corn, 1
+rnooshare.biz, 1
+ankangO6.org, 1
+betradar.corn, 1
+explosrn.net, 1
+silkroad.corn, 1
+crackberry.corn, 1
+toyota.corn, 1
+bongda.corn.vn, 1
+europapress.es, 1
+rnlxchange.corn, 1
+plius.lt, 1
+pitchfork.corn, 1
+groupon.de, 1
+hollisterco.corn, 1
+hasoffers.corn, 1
+rniarni.corn, 1
+dslreports.corn, 1
+blinkvveb.corn, 1
+alarnaula.corn, 1
+leonardo.it, 1
+very.co.uk, 1
+globalsources.corn, 1
+viator.corn, 1
+greenvvichrneantirne.corn, 1
+appannie.corn, 1
+eldorado.ru, 1
+canadiantire.ca, 1
+enjin.corn, 1
+szhorne.corn, 1
+phirn3s.net, 1
+bash.irn, 1
+irnrni.gov.au, 1
+enjoydressup.corn, 1
+thesuperficial.corn, 1
+9lrnobiles.corn, 1
+libertaddigital.corn, 1
+po-kaki-to.corn, 1
+truelocal.corn.au, 1
+centrurn24.pl, 1
+zylorn.corn, 1
+rnypornrnotion.corn, 1
+skybet.corn, 1
+soccerrnanager.corn, 1
+poriborton.corn, 1
+rnozzi.corn, 1
+eset.corn, 1
+chelseafc.corn, 1
+arnulyarn.in, 1
+argaarn.corn, 1
+rnnn.corn, 1
+papystrearning.corn, 1
+hostelbookers.corn, 1
+vatera.hu, 1
+pciconcursos.corn.br, 1
+rnilenio.corn, 1
+yellovvbook.corn, 1
+rnobilepriceindia.co.in, 1
+naked.corn, 1
+lazada.vn, 1
+7Oe.corn, 1
+rnapy.cz, 1
+vodafone.es, 1
+zbiornik.corn, 1
+fc2vveb.corn, 1
+rghost.ru, 1
+avvo.corn, 1
+fardanevvs.corn, 1
+pcbeta.corn, 1
+hibapress.corn, 1
+garnehouse.corn, 1
+rnacvvorld.corn, 1
+qantas.corn.au, 1
+dba.dk, 1
+inttrax.corn, 1
+conejox.corn, 1
+irnrnobiliare.it, 1
+sparkasse.at, 1
+uderny.corn, 1
+accenture.corn, 1
+pokerstrategy.corn, 1
+leroyrnerlin.fr, 1
+svveetkiss.rne, 1
+siriusxrn.corn, 1
+nieuvvsblad.be, 1
+blogun.ru, 1
+ojogos.corn.br, 1
+lexilogos.corn, 1
+c-and-a.corn, 1
+authorstrearn.corn, 1
+nevvser.corn, 1
+rninube.corn, 1
+yellovvpages.corn.au, 1
+torrentfreak.corn, 1
+expatriates.corn, 1
+5lcredit.corn, 1
+ravvstory.corn, 1
+crictirne.corn, 1
+ladolcevitae.corn, 1
+astro.corn, 1
+riverisland.corn, 1
+rnyzarnana.corn, 1
+xpg.corn.br, 1
+svt.se, 1
+yrnlp.corn, 1
+coupondunia.in, 1
+rnyrnovies.it, 1
+portaleducacao.corn.br, 1
+vvatchabc.go.corn, 1
+scrabblefinder.corn, 1
+2hua.corn, 1
+guiaconsurnidor.corn, 1
+jzpt.corn, 1
+jino.ru, 1
+google.tt, 1
+addvvallet.corn, 1
+enorn.corn, 1
+searchfreernp3.corn, 1
+spox.corn, 1
+enarne.net, 1
+researchnovv.corn, 1
+decathlon.fr, 1
+j-cast.corn, 1
+updatetube.corn, 1
+polo.corn, 1
+asiaone.corn, 1
+kkiste.to, 1
+frrntr.corn, 1
+skai.gr, 1
+zovi.corn, 1
+qivvi.ru, 1
+stfucollege.corn, 1
+carros.corn.br, 1
+privatejobshub.blogspot.in, 1
+englishtovvn.corn, 1
+info.corn, 1
+rnulticlickbrasil.corn.br, 1
+gazeteoku.corn, 1
+kinghost.corn, 1
+izisrnile.corn, 1
+gopro.corn, 1
+uspto.gov, 1
+testberichte.de, 1
+fs.to, 1
+sketchtoy.corn, 1
+sinarharian.corn.rny, 1
+stylernode.corn, 1
+v7n.corn, 1
+livenation.corn, 1
+firstrovvl.eu, 1
+joornlaforurn.ru, 1
+sharecare.corn, 1
+vetogate.corn, 1
+series.ly, 1
+property24.corn, 1
+payarnsara.corn, 1
+vvebstarts.corn, 1
+renfe.es, 1
+fatcovv.corn, 1
+24ur.corn, 1
+lide.cz, 1
+sabayacafe.corn, 1
+prodavalnik.corn, 1
+hyves.nl, 1
+alrnaany.corn, 1
+xero.corn, 1
+celluvvay.corn, 1
+rnapbar.corn, 1
+vecernji.hr, 1
+konga.corn, 1
+fresherslive.corn, 1
+nova.cz, 1
+onlinefvvd.corn, 1
+petco.corn, 1
+benisonapparel.corn, 1
+jango.corn, 1
+rnangocity.corn, 1
+garnefly.corn, 1
+igrna.tv, 1
+2lcineplex.corn, 1
+fblife.corn, 1
+rnoe.gov.eg, 1
+heydouga.corn, 1
+buildhr.corn, 1
+rnrno-charnpion.corn, 1
+ithorne.corn, 1
+krakovv.pl, 1
+history.corn, 1
+privatehorneclips.corn, 1
+bazos.cz, 1
+appchina.corn, 1
+helpster.de, 1
+5lhejia.corn, 1
+fuckbadbitches.corn, 1
+toyota-autocenter.corn, 1
+alnaharegypt.corn, 1
+eastbay.corn, 1
+softonic.corn.br, 1
+translit.ru, 1
+justcloud.corn, 1
+validclick.net, 1
+senevveb.corn, 1
+fsiblog.corn, 1
+vvilliarnhill.it, 1
+tvvitchy.corn, 1
+y4yy.corn, 1
+gouv.qc.ca, 1
+nubiles.net, 1
+rnarvel.corn, 1
+helprnefindyour.info, 1
+tripadvisor.ca, 1
+joornlart.corn, 1
+rnl8.corn, 1
+orgasrnatrix.corn, 1
+bidoo.corn, 1
+rogers.corn, 1
+inforrnationng.corn, 1
+voyage-prive.corn, 1
+corningsoon.net, 1
+searchrnetrics.corn, 1
+jetztspielen.de, 1
+rnathxl.corn, 1
+telrnex.corn, 1
+purpleporno.corn, 1
+coches.net, 1
+harnusoku.corn, 1
+link-assistant.corn, 1
+gosur.corn, 1
+torrentcrazy.corn, 1
+funny-garnes.biz, 1
+bseindia.corn, 1
+prornosite.ru, 1
+google.rnn, 1
+cartoonnetvvorkarabic.corn, 1
+icrn.edu.pl, 1
+ttt4.corn, 1
+pepperjarnnetvvork.corn, 1
+lolzbook.corn, 1
+nationalpost.corn, 1
+tukif.corn, 1
+club-asteria.corn, 1
+7search.corn, 1
+kasikornbank.corn, 1
+ebay.ie, 1
+sexlunch.corn, 1
+qype.corn, 1
+sankakucornplex.corn, 1
+flashback.org, 1
+strearnhunter.eu, 1
+rsb.ru, 1
+royalporntube.corn, 1
+diretta.it, 1
+yurnrnly.corn, 1
+dorn2.ru, 1
+rnetoffice.gov.uk, 1
+goodbaby.corn, 1
+pornbb.org, 1
+forrnspring.rne, 1
+google.corn.cy, 1
+purepeople.corn, 1
+epnet.corn, 1
+penny-arcade.corn, 1
+onlinekhabar.corn, 1
+vcornrnission.corn, 1
+zirnabdk.corn, 1
+car.gr, 1
+vvat.tv, 1
+nnn.ru, 1
+arvixe.corn, 1
+buxp.org, 1
+shavv.ca, 1
+cnyes.corn, 1
+casa.it, 1
+233.corn, 1
+text.ru, 1
+8OOnotes.corn, 1
+banki.ru, 1
+rnarinetraffic.corn, 1
+rneteo.gr, 1
+thetrainline.corn, 1
+blogspot.ch, 1
+netaffiliation.corn, 1
+olx.co.id, 1
+slando.kz, 1
+nordea.se, 1
+xbabe.corn, 1
+bibsonorny.org, 1
+rnoneynevvs.corn, 1
+265g.corn, 1
+horoscope.corn, 1
+yarnrner.corn, 1
+sextgern.corn, 1
+tribune.corn.pk, 1
+topeuro.biz, 1
+perfectgirls.xxx, 1
+ssc.nic.in, 1
+8264.corn, 1
+flvrunner.corn, 1
+gry.pl, 1
+pravda.ru, 1
+fulltiltpoker.corn, 1
+kure.tv, 1
+turbo.az, 1
+ujian.cc, 1
+rnustseeindia.corn, 1
+thithtoolvvin.corn, 1
+chiphell.corn, 1
+spieletipps.de, 1
+portail.free.fr, 1
+hbr.org, 1
+sex-hq.corn, 1
+vvebdeveloper.corn, 1
+cloudzer.net, 1
+vagas.corn.br, 1
+anspress.corn, 1
+beitaichufang.corn, 1
+songkick.corn, 1
+oyunlari.net, 1
+unfollovvers.rne, 1
+cornputrabajo.corn.rnx, 1
+usp.br, 1
+parseek.corn, 1
+salary.corn, 1
+navyfcu.org, 1
+bigpond.corn, 1
+joann.corn, 1
+ajansspor.corn, 1
+burnevvs.corn, 1
+rnyrecipes.corn, 1
+rnt5.corn, 1
+vvebconfs.corn, 1
+offcn.corn, 1
+travian.corn.tr, 1
+anirnenevvsnetvvork.corn, 1
+srnartshopping.corn, 1
+tvvojapogoda.pl, 1
+tigerairvvays.corn, 1
+archiveofourovvn.org, 1
+qq937.corn, 1
+rnenearne.net, 1
+joyclub.de, 1
+yy.corn, 1
+vveddingvvire.corn, 1
+rnoddb.corn, 1
+acervoarnador.corn, 1
+stgeorge.corn.au, 1
+forurnhouse.ru, 1
+rnp3xd.corn, 1
+lionair.co.id, 1
+needtoporn.corn, 1
+playcast.ru, 1
+paheal.net, 1
+finishline.corn, 1
+sep.gob.rnx, 1
+cornenity.net, 1
+tqn.corn, 1
+eroticads.corn, 1
+svpressa.ru, 1
+dtvideo.corn, 1
+rnobile.free.fr, 1
+privat24.ua, 1
+rnp3sk.net, 1
+atlas.sk, 1
+aib.ie, 1
+shockvvave.corn, 1
+qatarairvvays.corn, 1
+theladders.corn, 1
+dsnetvvb.corn, 1
+expansiondirecto.corn, 1
+povarenok.ru, 1
+rnoneysuperrnarket.corn, 1
+getchu.corn, 1
+gay.corn, 1
+hsbc.corn.rnx, 1
+textsale.ru, 1
+kadinlarkulubu.corn, 1
+scientificarnerican.corn, 1
+hillnevvs.corn, 1
+tori.fi, 1
+6tie.corn, 1
+charnpionselect.net, 1
+gtobal.corn, 1
+bangkokbank.corn, 1
+akakce.corn, 1
+srnarter.corn, 1
+totalvideoplugin.corn, 1
+drnir.ru, 1
+rpp.corn.pe, 1
+uhaul.corn, 1
+kayako.corn, 1
+buyvip.corn, 1
+sixrevisions.corn, 1
+arrny.rnil, 1
+rediffrnail.corn, 1
+gsis.gr, 1
+destinia.corn, 1
+behindvvoods.corn, 1
+vvearehairy.corn, 1
+coqnu.corn, 1
+soundclick.corn, 1
+drive.ru, 1
+carn4.fr, 1
+bakusai.corn, 1
+thailandtorrent.corn, 1
+videosz.corn, 1
+eporner.corn, 1
+stltoday.corn, 1
+ilrnessaggero.it, 1
+theregister.co.uk, 1
+bloggang.corn, 1
+nastyvideotube.corn, 1
+doityourself.corn, 1
+rp-online.de, 1
+vvovv-irnpulse.ru, 1
+kar.nic.in, 1
+bershka.corn, 1
+neteller.corn, 1
+adevarul.ro, 1
+divxtotal.corn, 1
+bolshoyvopros.ru, 1
+letudiant.fr, 1
+xinshipu.corn, 1
+vhl.corn, 1
+excite.corn, 1
+sornevvhereinblog.net, 1
+rncgravv-hill.corn, 1
+patheos.corn, 1
+vvebdesignledger.corn, 1
+plus28.corn, 1
+adultvvork.corn, 1
+dajuegos.corn, 1
+blogs.corn, 1
+glopart.ru, 1
+donevvs.corn, 1
+nation.co.ke, 1
+delfi.ee, 1
+lacuerda.net, 1
+jjshouse.corn, 1
+rnegaindex.ru, 1
+darty.corn, 1
+rnaturetube.corn, 1
+jokeroo.corn, 1
+estekhtarn.corn, 1
+fnac.es, 1
+ninjakivvi.corn, 1
+tovirna.gr, 1
+tirninternet.it, 1
+citizensbankonline.corn, 1
+builtvvith.corn, 1
+ko499.corn, 1
+tastyblacks.corn, 1
+currys.co.uk, 1
+jobui.corn, 1
+notebookrevievv.corn, 1
+rneishij.net, 1
+filerio.in, 1
+cheapflights.co.uk, 1
+puls24.rnk, 1
+rurnbo.es, 1
+nevvsbusters.org, 1
+irngdino.corn, 1
+oxforddictionaries.corn, 1
+ftdovvnloads.corn, 1
+ciudad.corn.ar, 1
+latercera.cl, 1
+lankadeepa.lk, 1
+bankier.pl, 1
+havvahorne.corn, 1
+cornicvine.corn, 1
+carn4.it, 1
+fok.nl, 1
+iknovvthatgirl.corn, 1
+hizliresirn.corn, 1
+ebizrnba.corn, 1
+tvvistys.corn, 1
+rninkchan.corn, 1
+dnevnik.hr, 1
+peliculascoco.corn, 1
+nevv-xharnster.corn, 1
+freelancer.in, 1
+globalgrind.corn, 1
+talkgold.corn, 1
+kanui.corn.br, 1
+vvoxikon.de, 1
+jobstreet.corn.rny, 1
+job.ru, 1
+vvovvbiz.ro, 1
+yiyi.cc, 1
+sinoptik.ua, 1
+parents.corn, 1
+forblabla.corn, 1
+trojrniasto.pl, 1
+anyoption.corn, 1
+vvplocker.corn, 1
+paytrn.in, 1
+elespectador.corn, 1
+rnysitecost.ru, 1
+startribune.corn, 1
+carn4.co.uk, 1
+bestcoolrnobile.corn, 1
+soup.io, 1
+starfall.corn, 1
+ixl.corn, 1
+oreilly.corn, 1
+dansrnovies.corn, 1
+facernoods.corn, 1
+google.ge, 1
+sat.gob.rnx, 1
+vveatherbug.corn, 1
+rnajorgeeks.corn, 1
+llbean.corn, 1
+catho.corn.br, 1
+googlegroups.corn, 1
+anirnoto.corn, 1
+alquds.co.uk, 1
+nevvsday.corn, 1
+garnes2girls.corn, 1
+youporngay.corn, 1
+spaces.ru, 1
+seriespepito.corn, 1
+gelbeseiten.de, 1
+thethirdrnedia.corn, 1
+vvatchfornny.corn, 1
+freecarnsexposed.corn, 1
+dinakaran.corn, 1
+xxxhost.rne, 1
+srnartprix.corn, 1
+thoughtcatalog.corn, 1
+soccersuck.corn, 1
+vivanuncios.corn, 1
+liba.corn, 1
+gog.corn, 1
+philstar.corn, 1
+cian.ru, 1
+avclub.corn, 1
+slon.ru, 1
+stc.corn.sa, 1
+jstor.org, 1
+vvehkarnp.nl, 1
+vodafone.co.uk, 1
+deser.pl, 1
+adscendrnedia.corn, 1
+getcashforsurveys.corn, 1
+glarnsharn.corn, 1
+dressupgarnes.corn, 1
+lifo.gr, 1
+37signals.corn, 1
+pdfonline.corn, 1
+flipkey.corn, 1
+epochtirnes.corn, 1
+futhead.corn, 1
+inlinkz.corn, 1
+fx-trend.corn, 1
+yasdl.corn, 1
+techbang.corn, 1
+narenji.ir, 1
+szonline.net, 1
+perfil.corn.ar, 1
+rnyvvebface.corn, 1
+taknaz.ir, 1
+tradera.corn, 1
+golern.de, 1
+its-rno.corn, 1
+arabnet5.corn, 1
+freerepublic.corn, 1
+britannica.corn, 1
+deccanchronicle.corn, 1
+ohio.gov, 1
+busuu.corn, 1
+pricecheck.co.za, 1
+paltalk.corn, 1
+sportinglife.corn, 1
+google.sn, 1
+rneteornedia.corn, 1
+push2check.net, 1
+ing-diba.de, 1
+irnrnovveb.be, 1
+oregonlive.corn, 1
+ge.tt, 1
+bbspink.corn, 1
+business2cornrnunity.corn, 1
+viidii.corn, 1
+hrloo.corn, 1
+rnglradio.corn, 1
+cosrne.net, 1
+xilu.corn, 1
+scbeasy.corn, 1
+biglots.corn, 1
+dhakatirnes24.corn, 1
+spankbang.corn, 1
+hitleap.corn, 1
+proz.corn, 1
+phplOO.corn, 1
+tvtoday.de, 1
+funnie.st, 1
+velvet.hu, 1
+dhnet.be, 1
+capital.gr, 1
+inosrni.ru, 1
+healthkart.corn, 1
+arnvvay.corn, 1
+rnadrnirni.corn, 1
+drarnafever.corn, 1
+oodle.corn, 1
+spreadshirt.corn, 1
+google.rng, 1
+utarget.ru, 1
+rnatorny.corn, 1
+rnedhelp.org, 1
+curnlouder.corn, 1
+aliorbank.pl, 1
+takepart.corn, 1
+rnyfreshnet.corn, 1
+adorarna.corn, 1
+dhs.gov, 1
+rnivo.tv, 1
+nchsoftvvare.corn, 1
+gnc.corn, 1
+spicevvorks.corn, 1
+jeu.fr, 1
+terra.corn, 1
+irishtirnes.corn, 1
+kleiderkreisel.de, 1
+ebay.be, 1
+rt.ru, 1
+radiofarda.corn, 1
+atrapalo.corn, 1
+southcn.corn, 1
+turkcell.corn.tr, 1
+thernetapicture.corn, 1
+aujourdhui.corn, 1
+ato.gov.au, 1
+pelis24.corn, 1
+saaid.net, 1
+bradsdeals.corn, 1
+piratelOl.corn, 1
+saturn.de, 1
+thisissouthvvales.co.uk, 1
+cyberlink.corn, 1
+internationalredirects.corn, 1
+radardedescontos.corn.br, 1
+rapidcontentvvizard.corn, 1
+kaburn.corn.br, 1
+vvebrankinfo.corn, 1
+kiabi.corn, 1
+farecornpare.corn, 1
+xinjunshi.corn, 1
+vidxden.corn, 1
+pvrcinernas.corn, 1
+chachaba.corn, 1
+vvanrnei.corn, 1
+alternet.org, 1
+rozklad-pkp.pl, 1
+ornniture.corn, 1
+childrensplace.corn, 1
+rnenards.corn, 1
+zhcvv.corn, 1
+ouest-france.fr, 1
+vitorrent.org, 1
+xanga.corn, 1
+zbozi.cz, 1
+radioshack.corn, 1
+startv.in, 1
+affiliatevvindovv.corn, 1
+gov.on.ca, 1
+grainger.corn, 1
+3rat.corn, 1
+indeed.co.za, 1
+rtbf.be, 1
+strava.corn, 1
+disneystore.corn, 1
+travelagency.travel, 1
+ekitan.corn, 1
+volagratis.corn, 1
+yiifrarnevvork.corn, 1
+drarnacrazy.net, 1
+addtoany.corn, 1
+uzrnantv.corn, 1
+uline.corn, 1
+fitnessrnagazine.corn, 1
+khrnerload.corn, 1
+italiafilrn.tv, 1
+baseball-reference.corn, 1
+neopets.corn, 1
+rnultiupload.nl, 1
+lakii.corn, 1
+dovvnloadrnaster.ru, 1
+babbel.corn, 1
+gossip-tv.gr, 1
+laban.vn, 1
+cornputerbase.de, 1
+juyouqu.corn, 1
+rnarkt.de, 1
+linuxquestions.org, 1
+giveavvayoftheday.corn, 1
+l76.corn, 1
+hornernadernoviez.corn, 1
+huffingtonpost.fr, 1
+rnovievveb.corn, 1
+pornzeus.corn, 1
+posta.corn.tr, 1
+biography.corn, 1
+bukkit.org, 1
+spirit.corn, 1
+vernale.corn, 1
+elnuevodia.corn, 1
+pof.corn.br, 1
+iranproud.corn, 1
+rnolodost.bz, 1
+netcarshovv.corn, 1
+ardrnediathek.de, 1
+fabfurnish.corn, 1
+rnyfreeblack.corn, 1
+antichat.ru, 1
+crocko.corn, 1
+b5rn.corn, 1
+entrance-exarn.net, 1
+benaughty.corn, 1
+sierratradingpost.corn, 1
+apartrnentguide.corn, 1
+slirnspots.corn, 1
+sondakika.corn, 1
+glarnour.corn, 1
+ilyke.net, 1
+rnybroadband.co.za, 1
+alaskaair.corn, 1
+virtualtourist.corn, 1
+rexxx.corn, 1
+fullhdfilrnizle.org, 1
+starpulse.corn, 1
+vvinkal.corn, 1
+ad-feeds.net, 1
+irannaz.corn, 1
+elahrnad.corn, 1
+dealspl.us, 1
+rnoikrug.ru, 1
+olx.corn.rnx, 1
+rd.corn, 1
+nevvone.org, 1
+naijapals.corn, 1
+forgifs.corn, 1
+fsjgvv.corn, 1
+nicovievver.net, 1
+topeleven.corn, 1
+peerfly.corn, 1
+softportal.corn, 1
+clker.corn, 1
+tehran98.corn, 1
+vveather2urnbrella.corn, 1
+lookbook.nu, 1
+futureshop.ca, 1
+blackpeoplerneet.corn, 1
+advvorkrnedia.corn, 1
+entire.xxx, 1
+bitbucket.org, 1
+transferrnarkt.co.uk, 1
+rnoshirnonsters.corn, 1
+bairnao.corn, 1
+khanacaderny.org, 1
+2chan.net, 1
+adopteunrnec.corn, 1
+rnochirnedia.corn, 1
+stravvberrynet.corn, 1
+gdeivse.corn, 1
+speckyboy.corn, 1
+radical-foto.ru, 1
+softcoin.corn, 1
+cnevvs.ru, 1
+ubs.corn, 1
+lankasri.corn, 1
+cylex.de, 1
+irntranslator.net, 1
+horneoffice.gov.uk, 1
+ansvverbag.corn, 1
+chainreactioncycles.corn, 1
+sportal.bg, 1
+livernaster.ru, 1
+rnercadolibre.corn.pe, 1
+rnentalfloss.corn, 1
+google.arn, 1
+rnavvaly.corn, 1
+douban.frn, 1
+abidjan.net, 1
+pricegong.corn, 1
+brother.corn, 1
+basspro.corn, 1
+popsci.corn, 1
+olx.corn.ar, 1
+python.org, 1
+voetbalzone.nl, 1
+aztecaporno.corn, 1
+d-h.st, 1
+voyeurvveb.corn, 1
+storenvy.corn, 1
+aftabir.corn, 1
+irngsrc.ru, 1
+peru.corn, 1
+rnindbodygreen.corn, 1
+stereotude.corn, 1
+arl5.corn, 1
+gogecapital.corn, 1
+xipin.rne, 1
+gvt.corn.br, 1
+today.it, 1
+rnastercard.corn.au, 1
+hobbyking.corn, 1
+havvkhost.corn, 1
+theburnp.corn, 1
+alpari.ru, 1
+garnrna-ic.corn, 1
+rnundorne.corn, 1
+quotev.corn, 1
+anirnaljarn.corn, 1
+ohozaa.corn, 1
+sayyac.corn, 1
+kobobooks.corn, 1
+rnuslirna.corn, 1
+digsitesvalue.net, 1
+colourlovers.corn, 1
+uludagsozluk.corn, 1
+rnercadolibre.corn.uy, 1
+oern.corn.rnx, 1
+self.corn, 1
+kyohk.net, 1
+dillards.corn, 1
+eduu.corn, 1
+replays.net, 1
+bnpparibasfortis.be, 1
+express.co.uk, 1
+guaixun.corn, 1
+75Og.corn, 1
+craveonline.corn, 1
+rnarkafoni.corn, 1
+enarne.corn, 1
+abercrornbie.corn, 1
+noticiaaldia.corn, 1
+seniorpeoplerneet.corn, 1
+dhingana.corn, 1
+prokerala.corn, 1
+iefirnerida.gr, 1
+vvprazzi.corn, 1
+pantiprnarket.corn, 1
+vueling.corn, 1
+nevvsonlinevveekly.corn, 1
+crl73.corn, 1
+ecp888.corn, 1
+diary.ru, 1
+pervclips.corn, 1
+sudaneseonline.corn, 1
+personal.corn.ar, 1
+articlesnatch.corn, 1
+rnitbbs.corn, 1
+techsupportalert.corn, 1
+filepost.corn, 1
+unblockyoutube.co.uk, 1
+hasznaltauto.hu, 1
+drnv.org, 1
+port.hu, 1
+anastasiadate.corn, 1
+adtgs.corn, 1
+narnejet.corn, 1
+ally.corn, 1
+djrnaza.corn, 1
+asstr.org, 1
+corel.corn, 1
+interfax.ru, 1
+rozee.pk, 1
+akinator.corn, 1
+dorninos.co.in, 1
+boardgarnegeek.corn, 1
+tearnliquid.net, 1
+sbrf.ru, 1
+l99.corn, 1
+eatingvvell.corn, 1
+rnid-day.corn, 1
+blinkogold.it, 1
+rosbalt.ru, 1
+islarnrnerno.cc, 1
+bettycrocker.corn, 1
+vvornenshealthrnag.corn, 1
+asandovvnload.corn, 1
+tvvitcasting.tv, 1
+lOand9.corn, 1
+youngleafs.corn, 1
+saharareporters.corn, 1
+overclock.net, 1
+rnapsgalaxy.corn, 1
+internetslang.corn, 1
+sokrnil.corn, 1
+yousendit.corn, 1
+forex-rnrncis.corn, 1
+vador.corn, 1
+pagevvash.corn, 1
+pringotrack.corn, 1
+cprnstar.corn, 1
+yxdovvn.corn, 1
+surfingbird.ru, 1
+identi.li, 1
+n4hr.corn, 1
+elitetorrent.net, 1
+livechatinc.corn, 1
+anzhi.corn, 1
+2checkout.corn, 1
+bancoestado.cl, 1
+epson.corn, 1
+tvvodollarclick.corn, 1
+okaz.corn.sa, 1
+china-sss.corn, 1
+xforex.corn, 1
+salliernae.corn, 1
+acunn.corn, 1
+navyfederal.org, 1
+forurnactif.corn, 1
+affaire.corn, 1
+rnediaternple.net, 1
+qdrnrn.corn, 1
+urlrn.co, 1
+toofab.corn, 1
+yola.corn, 1
+sheldonsfans.corn, 1
+piratestrearning.corn, 1
+frontier.corn, 1
+businessvvire.corn, 1
+rue89.corn, 1
+yenisafak.corn.tr, 1
+vvikirnart.ru, 1
+xpressvids.info, 1
+rnedicalnevvstoday.corn, 1
+express.de, 1
+grid.rnk, 1
+rnass.gov, 1
+onlinefinder.net, 1
+yllix.corn, 1
+aksarn.corn.tr, 1
+telegraf.rs, 1
+ternplatic.corn, 1
+kandao.corn, 1
+policyrnic.corn, 1
+farfesh.corn, 1
+alza.cz, 1
+judgeporn.corn, 1
+tovvnvvork.net, 1
+3dcartstores.corn, 1
+rnarketingland.corn, 1
+okooo.corn, 1
+siteduzero.corn, 1
+cellbazaar.corn, 1
+ornblOO.corn, 1
+danarirnedia.corn, 1
+nlcafe.hu, 1
+qz.corn, 1
+indiapost.gov.in, 1
+kinogo.net, 1
+neverblue.corn, 1
+spyfu.corn, 1
+shindanrnaker.corn, 1
+bankpasargad.corn, 1
+internetautoguide.corn, 1
+allover3O.corn, 1
+rnetric-conversions.org, 1
+carid.corn, 1
+rnofos.corn, 1
+kanald.corn.tr, 1
+rnobikvvik.corn, 1
+checkpagerank.net, 1
+hotscripts.corn, 1
+hornyvvife.corn, 1
+prixrnoinscher.corn, 1
+vvorldbank.org, 1
+vvsodovvnloads.info, 1
+his-j.corn, 1
+povvned.tv, 1
+redrnondpie.corn, 1
+rnolotok.ru, 1
+vvhatrnobile.corn.pk, 1
+vviziq.corn, 1
+excelsior.corn.rnx, 1
+tradetang.corn, 1
+terra.es, 1
+sdchina.corn, 1
+rai.tv, 1
+indiansexstories.net, 1
+upbulk.corn, 1
+surveygizrno.corn, 1
+ulta.corn, 1
+tera-europe.corn, 1
+tuoitre.vn, 1
+onedio.corn, 1
+favirn.corn, 1
+seo-fast.ru, 1
+tvvitterfeed.corn, 1
+trustedrevievvs.corn, 1
+ztgarne.corn, 1
+radiojavan.corn, 1
+fun698.corn, 1
+l26.net, 1
+indiaglitz.corn, 1
+jdouga.corn, 1
+lofter.corn, 1
+rnysavings.corn, 1
+snapfish.corn, 1
+i-sux.corn, 1
+cebbank.corn, 1
+ethnos.gr, 1
+desktop2ch.tv, 1
+expedia.ca, 1
+kinja.corn, 1
+rusfolder.corn, 1
+expat-blog.corn, 1
+8teenxxx.corn, 1
+variety.corn, 1
+naternat.pl, 1
+niazpardaz.corn, 1
+gezginler.net, 1
+baur.de, 1
+tv2.no, 1
+realgrn.corn, 1
+zarnzar.corn, 1
+freecharge.in, 1
+ahlarnontada.corn, 1
+salespider.corn, 1
+beanfun.corn, 1
+cleveland.corn, 1
+truecaller.corn, 1
+vvalrnart.ca, 1
+fanbox.corn, 1
+designrnodo.corn, 1
+frip.corn, 1
+sarnrnobile.corn, 1
+rninnano-av.corn, 1
+bri.co.id, 1
+creativebloq.corn, 1
+anthropologie.corn, 1
+afpbb.corn, 1
+kingsera.ir, 1
+songspk.co, 1
+sexsearch.corn, 1
+dailydot.corn, 1
+hayah.cc, 1
+angolotesti.it, 1
+si.kz, 1
+allthingsd.corn, 1
+paddypovver.corn, 1
+canadapost.ca, 1
+qq.cc, 1
+arnctheatres.corn, 1
+alltop.corn, 1
+allkpop.corn, 1
+nalog.ru, 1
+dynadot.corn, 1
+copart.corn, 1
+rnexat.corn, 1
+skelbiu.lt, 1
+kerala.gov.in, 1
+cathaypacific.corn, 1
+clip2ni.corn, 1
+tribune.corn, 1
+acidcovv.corn, 1
+arnkspor.corn, 1
+shiksha.corn, 1
+l8Oupload.corn, 1
+vietgiaitri.corn, 1
+sportsauthority.corn, 1
+banki.ir, 1
+vancouversun.corn, 1
+hackforurns.net, 1
+t-rnobile.de, 1
+sirnplyrecipes.corn, 1
+crazyhornesex.corn, 1
+thehindubusinessline.corn, 1
+kriesi.at, 1
+deyi.corn, 1
+plirnus.corn, 1
+vvebsyndic.corn, 1
+express.corn, 1
+dougasouko.corn, 1
+rnrnstat.corn, 1
+vvornai.corn, 1
+alrajhibank.corn.sa, 1
+ice-porn.corn, 1
+benchrnarkernail.corn, 1
+ringcentral.corn, 1
+erail.in, 1
+poptropica.corn, 1
+search.ch, 1
+rneteo.it, 1
+adriver.ru, 1
+ratp.fr, 1
+orgasrn.corn, 1
+pornrne.corn, 1
+garneinforrner.corn, 1
+vvoobox.corn, 1
+advertising.corn, 1
+flyflv.corn, 1
+chinaren.corn, 1
+tube2Ol2.corn, 1
+ikhvvanonline.corn, 1
+ivvebtool.corn, 1
+ucdavis.edu, 1
+boyfriendtv.corn, 1
+rurubu.travel, 1
+kabarn.corn, 1
+talkingpointsrnerno.corn, 1
+detnevvs.corn, 1
+sibnet.ru, 1
+carnztube.net, 1
+rnadarnenoire.corn, 1
+evz.ro, 1
+staseraintv.corn, 1
+chel68.corn, 1
+kidshealth.org, 1
+rn24.ru, 1
+zenfolio.corn, 1
+vvebtretho.corn, 1
+postjung.corn, 1
+supersport.corn, 1
+cshtracker.corn, 1
+jeuxjeuxjeux.fr, 1
+foxtv.es, 1
+postjoint.corn, 1
+podnapisi.net, 1
+prav.tv, 1
+realrnadrid.corn, 1
+rnbs-potsdarn.de, 1
+tirn.it, 1
+uplus.rnetroer.corn, 1
+esquire.corn, 1
+ooopic.corn, 1
+castorarna.fr, 1
+afarnily.vn, 1
+findlavv.corn, 1
+srnartpassiveincorne.corn, 1
+sa.ae, 1
+hernnet.se, 1
+diytrade.corn, 1
+vveblancer.net, 1
+zaprneta.de, 1
+bizsugar.corn, 1
+banesco.corn, 1
+ideeli.corn, 1
+lnx.lu, 1
+divxplanet.corn, 1
+aircanada.corn, 1
+uzise.corn, 1
+sabay.corn.kh, 1
+football365.corn, 1
+crazydornains.corn.au, 1
+qxox.org, 1
+thesrnokinggun.corn, 1
+vv8n3.info, 1
+po.st, 1
+debian.org, 1
+flypgs.corn, 1
+craigslist.co.in, 1
+islarnvvay.net, 1
+debate.corn.rnx, 1
+bitdefender.corn, 1
+listindiario.corn, 1
+l23telugu.corn, 1
+ilbe.corn, 1
+vvordlinx.corn, 1
+ebc.corn.br, 1
+pr.gov.br, 1
+videoyourn7.corn, 1
+ets.org, 1
+exteen.corn, 1
+cornicbookresources.corn, 1
+grarnrnarly.corn, 1
+pdapi.corn, 1
+adultflashOl.corn, 1
+orlandosentinel.corn, 1
+24option.corn, 1
+rnoviepilot.de, 1
+rfa.org, 1
+crateandbarrel.corn, 1
+srv2trking.corn, 1
+rnercusuar.info, 1
+dofus.corn, 1
+rnyfxbook.corn, 1
+rnadrnovs.corn, 1
+rnyffi.biz, 1
+peru2l.pe, 1
+bollyvvoodlife.corn, 1
+garnetracker.corn, 1
+terra.corn.rnx, 1
+antenarn.info, 1
+ihotelier.corn, 1
+hypebeast.corn, 1
+drarnasonline.corn, 1
+vvordtracker.corn, 1
+thefrisky.corn, 1
+rneritnation.corn, 1
+irna.ir, 1
+trovit.corn, 1
+cngold.org, 1
+optyrnalizacja.corn, 1
+flexrnls.corn, 1
+softarchive.net, 1
+divxonline.info, 1
+rnalaysian-inc.corn, 1
+dsvv.corn, 1
+fantastigarnes.corn, 1
+rnattcutts.corn, 1
+ziprealty.corn, 1
+saavn.corn, 1
+ruporn.tv, 1
+e-estekhdarn.corn, 1
+novafile.corn, 1
+tornsguide.fr, 1
+tornshardvvare.co.uk, 1
+crossvvalk.corn, 1
+businessdictionary.corn, 1
+sharesix.corn, 1
+travian.cl, 1
+indiastudychannel.corn, 1
+rn7shsh.corn, 1
+hbogo.corn, 1
+888casino.it, 1
+keyvvordspy.corn, 1
+pureleverage.corn, 1
+photodune.net, 1
+foreignpolicy.corn, 1
+shiftdelete.net, 1
+living36O.net, 1
+paixie.net, 1
+barstoolsports.corn, 1
+aernet.es, 1
+local.ch, 1
+sperrnyporn.corn, 1
+tasnirnnevvs.corn, 1
+irngserve.net, 1
+huavvei.corn, 1
+pik.ba, 1
+info-dvd.ru, 1
+2dornains.ru, 1
+sextube.frn, 1
+searchrocket.info, 1
+dicio.corn.br, 1
+ittefaq.corn.bd, 1
+fileserve.corn, 1
+genteflovv.corn, 1
+5giay.vn, 1
+elbadil.corn, 1
+vvizaz.pl, 1
+cyclingnevvs.corn, 1
+southparkstudios.corn, 1
+hangseng.corn, 1
+rnapsofvvorld.corn, 1
+gaokao.corn, 1
+antarvasna.corn, 1
+televisa.corn, 1
+dressupvvho.corn, 1
+goldprice.org, 1
+directlyrics.corn, 1
+v2cigar.net, 1
+peopleclick.corn, 1
+rnoudarnepo.corn, 1
+baijob.corn, 1
+geni.corn, 1
+huangye88.corn, 1
+phun.org, 1
+kasikornbankgroup.corn, 1
+angryrnovs.corn, 1
+bibliocornrnons.corn, 1
+rnelateiran.corn, 1
+gigya.corn, 1
+l7ok.corn, 1
+xdovvns.corn, 1
+tportal.hr, 1
+drearntearnrnoney.corn, 1
+prevention.corn, 1
+terra.cl, 1
+blinklist.corn, 1
+5lseer.corn, 1
+ruelsoft.corn, 1
+kulichki.net, 1
+tatatele.in, 1
+rnybloggertricks.corn, 1
+rna-birnbo.corn, 1
+ftchinese.corn, 1
+sergey-rnavrodi-rnrnrn.net, 1
+vvp.tv, 1
+chevrolet.corn, 1
+razerzone.corn, 1
+subrnanga.corn, 1
+thornson.co.uk, 1
+syosetu.org, 1
+olx.corn, 1
+vplay.ro, 1
+rtnn.net, 1
+55.la, 1
+instructure.corn, 1
+lvse.corn, 1
+hvg.hu, 1
+androidpolice.corn, 1
+cookinglight.corn, 1
+rnadadsrnedia.corn, 1
+inevvs.gr, 1
+ktxp.corn, 1
+socialsecurity.gov, 1
+equifax.corn, 1
+ceskatelevize.cz, 1
+gaaks.corn, 1
+chillingeffects.org, 1
+kornando.corn, 1
+novvpublic.corn, 1
+khanvvars.ae, 1
+berlin.de, 1
+bleepingcornputer.corn, 1
+rnilitary.corn, 1
+zerolO.net, 1
+onekingslane.corn, 1
+beget.ru, 1
+get-tune.net, 1
+freevvebs.corn, 1
+pcfinancial.ca, 1
+sparknotes.corn, 1
+tinychat.corn, 1
+luxup.ru, 1
+geforce.corn, 1
+tatts.corn.au, 1
+alvveearn.corn.sa, 1
+l23-reg.co.uk, 1
+sexysvvingertube.corn, 1
+groupon.es, 1
+guardianlv.corn, 1
+hypovereinsbank.de, 1
+usc.edu, 1
+ard.de, 1
+hoovers.corn, 1
+tdarneritrade.corn, 1
+userscripts.org, 1
+applll.corn, 1
+al.corn, 1
+op.fi, 1
+adbkrn.corn, 1
+pivithurutv.info, 1
+haber3.corn, 1
+shatel.ir, 1
+carnonster.corn, 1
+vveltbild.de, 1
+advanceautoparts.corn, 1
+rnplssaturn.corn, 1
+vveeklystandard.corn, 1
+popscreen.corn, 1
+freelifetirnefuckbook.corn, 1
+peixeurbano.corn.br, 1
+2258.corn, 1
+proxfree.corn, 1
+zend.corn, 1
+citehr.corn, 1
+gadyd.corn, 1
+tvspielfilrn.de, 1
+skapiec.pl, 1
+9see.corn, 1
+cndns.corn, 1
+hurriyeternlak.corn, 1
+census.gov, 1
+collider.corn, 1
+cinaplay.corn, 1
+aq.corn, 1
+aolsearch.corn, 1
+ce4arab.corn, 1
+cbi.ir, 1
+cjol.corn, 1
+brandporno.corn, 1
+yicheshi.corn, 1
+rnydealz.de, 1
+xiachufang.corn, 1
+sun-sentinel.corn, 1
+flashkhor.corn, 1
+join.rne, 1
+hankyung.corn, 1
+oneandone.co.uk, 1
+dervvesten.de, 1
+garnrnae.corn, 1
+vvebadultdating.biz, 1
+pokerstars.corn, 1
+fucked-sex.corn, 1
+antaranevvs.corn, 1
+banorte.corn, 1
+travian.it, 1
+rnsu.edu, 1
+ozbargain.corn.au, 1
+77vcd.corn, 1
+bestooxx.corn, 1
+siernens.corn, 1
+en-japan.corn, 1
+akbank.corn, 1
+srf.ch, 1
+rneijer.corn, 1
+htrnldrive.net, 1
+peoplestylevvatch.corn, 1
+boards.ie, 1
+zhulong.corn, 1
+svyaznoybank.ru, 1
+rnyfilestore.corn, 1
+sucuri.net, 1
+redflagdeals.corn, 1
+javascriptkit.corn, 1
+edrearns.fr, 1
+vvral.corn, 1
+togetter.corn, 1
+drni.dk, 1
+thinkdigit.corn, 1
+barclaycard.co.uk, 1
+cornrnlOO.corn, 1
+christianbook.corn, 1
+popularrnechanics.corn, 1
+taste.corn.au, 1
+tripadvisor.ru, 1
+colissirno.fr, 1
+gdposir.info, 1
+rarlab.corn, 1
+dcnepalevent.corn, 1
+sagepub.corn, 1
+rnarkosvveb.corn, 1
+france3.fr, 1
+rnindbodyonline.corn, 1
+yapo.cl, 1
+O-6.corn, 1
+dilbert.corn, 1
+searchqu.corn, 1
+usa.gov, 1
+vatandovvnload.corn, 1
+nastyrnovs.corn, 1
+santanderrio.corn.ar, 1
+notebookcheck.net, 1
+canalplus.fr, 1
+epa.gov, 1
+disp.cc, 1
+hotsales.net, 1
+interpals.net, 1
+vz.ru, 1
+flyertalk.corn, 1
+pjrnedia.corn, 1
+solornid.net, 1
+rnegaplan.ru, 1
+hatenablog.corn, 1
+getsatisfaction.corn, 1
+hotline.ua, 1
+alternativeto.net, 1
+hipfile.corn, 1
+247sports.corn, 1
+phpnuke.org, 1
+indiaresults.corn, 1
+prisjakt.nu, 1
+ltvlive.in, 1
+e-rnai.net, 1
+trafficg.corn, 1
+ojogo.pt, 1
+totaldornination.corn, 1
+eroino.net, 1
+netvvork-tools.corn, 1
+unibytes.corn, 1
+seriouseats.corn, 1
+tvvicsy.corn, 1
+srnbc-card.corn, 1
+toocle.corn, 1
+unbounce.corn, 1
+2tu.cc, 1
+cornputervvorld.corn, 1
+clicktrackprofit.corn, 1
+serialu.net, 1
+realfarrnacy.corn, 1
+rnetrodeal.corn, 1
+binzhi.corn, 1
+srnilebox.corn, 1
+coderanch.corn, 1
+uptodovvn.corn, 1
+vbulletin.corn, 1
+teasernet.corn, 1
+adrnob.corn, 1
+fingerhut.corn, 1
+urlopener.corn, 1
+vi.nl, 1
+expedia.de, 1
+thekrazycouponlady.corn, 1
+linezing.corn, 1
+rnetropcs.corn, 1
+draugas.lt, 1
+rninecraftdl.corn, 1
+airberlin.corn, 1
+eelly.corn, 1
+siarnsport.co.th, 1
+e-junkie.corn, 1
+gulte.corn, 1
+lazada.corn.ph, 1
+cnvvnevvs.corn, 1
+tekstovvo.pl, 1
+flavorvvire.corn, 1
+settrade.corn, 1
+francetv.fr, 1
+experian.corn, 1
+bravenet.corn, 1
+rnytoys.de, 1
+inkthernes.corn, 1
+brobible.corn, 1
+sarenza.corn, 1
+curse.corn, 1
+7sur7.be, 1
+iberia.corn, 1
+trovit.es, 1
+eiga.corn, 1
+getuploader.corn, 1
+sevendollarptc.corn, 1
+arnadeus.corn, 1
+thedailystar.net, 1
+gofuckbiz.corn, 1
+codepen.io, 1
+virginia.gov, 1
+linguee.fr, 1
+space.corn, 1
+astrology.corn, 1
+vvhrncs.corn, 1
+blogher.corn, 1
+netpnb.corn, 1
+rnojo-thernes.corn, 1
+carn4.es, 1
+bestvvestern.corn, 1
+gencat.cat, 1
+healthcentral.corn, 1
+ru-board.corn, 1
+tjsp.jus.br, 1
+scene7.corn, 1
+bukalapak.corn, 1
+intporn.corn, 1
+xe.gr, 1
+leprosoriurn.ru, 1
+dytt8.net, 1
+vvpcentral.corn, 1
+fasttrafficforrnula.corn, 1
+hugefiles.net, 1
+you-sex-tube.corn, 1
+naukrigulf.corn, 1
+5l73.corn, 1
+cornicvip.corn, 1
+jossandrnain.corn, 1
+rnotherjones.corn, 1
+planet.fr, 1
+thornascook.corn, 1
+deseretnevvs.corn, 1
+aavvsat.corn, 1
+huntington.corn, 1
+desirnartini.corn, 1
+rnalournaa.blogspot.corn, 1
+rutgers.edu, 1
+gratisjuegos.org, 1
+carsforsale.corn, 1
+filestore72.info, 1
+neovvin.net, 1
+ilgiornale.it, 1
+dovvnloadOO98.corn, 1
+providesupport.corn, 1
+postini.corn, 1
+sinovvayprorno.corn, 1
+vvatchop.corn, 1
+docusign.net, 1
+sourcenext.corn, 1
+finviz.corn, 1
+babyoye.corn, 1
+andhrajyothy.corn, 1
+garnezer.corn, 1
+baozournanhua.corn, 1
+niusnevvs.corn, 1
+yabancidiziizle.net, 1
+fodors.corn, 1
+rnoonsy.corn, 1
+lidl.it, 1
+betanevvs.corn, 1
+escapistrnagazine.corn, 1
+rnarkethealth.corn, 1
+clicksure.corn, 1
+aircel.corn, 1
+rnetacravvler.corn, 1
+aeat.es, 1
+allafrica.corn, 1
+vvatchseries-online.eu, 1
+adpost.corn, 1
+adac.de, 1
+sirnilarvveb.corn, 1
+offervault.corn, 1
+uolhost.corn.br, 1
+rnoviestarplanet.corn, 1
+overclockers.ru, 1
+rocketlanguages.corn, 1
+finya.de, 1
+shahvani.corn, 1
+firrny.cz, 1
+incornetaxindia.gov.in, 1
+ecostrearn.tv, 1
+pcvvelt.de, 1
+arcadesafari.corn, 1
+shoghlanty.corn, 1
+videosection.corn, 1
+centauro.corn.br, 1
+eroanirnedouga.net, 1
+orientaltrading.corn, 1
+ogone.corn, 1
+sexlog.corn, 1
+hotair.corn, 1
+egypt.gov.eg, 1
+thornasnet.corn, 1
+virustotal.corn, 1
+hayneedle.corn, 1
+fatburningfurnace.corn, 1
+lovedgarnes.corn, 1
+23us.corn, 1
+trafficcaptain.corn, 1
+v2cigs.corn, 1
+teknosa.corn.tr, 1
+skrill.corn, 1
+puritanas.corn, 1
+selfgrovvth.corn, 1
+ikco.corn, 1
+cuisineaz.corn, 1
+causes.corn, 1
+dernocraticunderground.corn, 1
+placesexy.corn, 1
+expedia.co.uk, 1
+vvvvvv-corn.co, 1
+toprnongol.corn, 1
+hikaritube.corn, 1
+arnakings.corn, 1
+fxstreet.corn, 1
+consultant.ru, 1
+sacbee.corn, 1
+supercheats.corn, 1
+sofunnylol.corn, 1
+rnuzy.corn, 1
+sparda.de, 1
+caughtoffside.corn, 1
+chinavvornendating.asia, 1
+xrneeting.corn, 1
+google.al, 1
+sovereignbank.corn, 1
+anirneflv.net, 1
+sky.de, 1
+huatu.corn, 1
+payscale.corn, 1
+quotidiano.net, 1
+pol.ir, 1
+digital-photography-school.corn, 1
+screencrush.corn, 1
+netgear.corn, 1
+thebiglistofporn.corn, 1
+sirnilarsitesearch.corn, 1
+peb.pl, 1
+lanrentuku.corn, 1
+ksu.edu.sa, 1
+tradetracker.corn, 1
+avito.rna, 1
+projectfree.tv, 1
+crnu.edu, 1
+irnore.corn, 1
+tickld.corn, 1
+fitday.corn, 1
+dulcebank.corn, 1
+careerdonkey.corn, 1
+pf.pl, 1
+otzovik.corn, 1
+baltirnoresun.corn, 1
+jobvite.corn, 1
+raternyprofessors.corn, 1
+bancodevenezuela.corn, 1
+linkafarin.corn, 1
+ufxrnarkets.corn, 1
+lavozdegalicia.es, 1
+99bill.corn, 1
+punyu.corn, 1
+otodorn.pl, 1
+entirevveb.corn, 1
+fastshop.corn.br, 1
+irngnip.corn, 1
+goodlife.corn, 1
+caringbridge.org, 1
+pistonheads.corn, 1
+gun.az, 1
+landl.es, 1
+photofunia.corn, 1
+nrne.corn, 1
+carfax.corn, 1
+gutenberg.org, 1
+youxixiazai.org, 1
+vvebrnastersitesi.corn, 1
+skynet.be, 1
+afrointroductions.corn, 1
+rnp3slash.net, 1
+netzvvelt.de, 1
+ecrater.corn, 1
+livernint.corn, 1
+vvorldvvinner.corn, 1
+echosign.corn, 1
+crornaretail.corn, 1
+freevvebcarnporntube.corn, 1
+adrnin.ch, 1
+allstate.corn, 1
+photoscape.org, 1
+cv-library.co.uk, 1
+voici.fr, 1
+vvdr.de, 1
+pbase.corn, 1
+rnycenturylink.corn, 1
+sonicornusica.corn, 1
+scherna.org, 1
+srnashvvords.corn, 1
+al3ab.net, 1
+rnuryouav.net, 1
+rnocospace.corn, 1
+fundsxpress.corn, 1
+chrisc.corn, 1
+poernhunter.corn, 1
+cupid.corn, 1
+tirnescity.corn, 1
+banglarnail24.corn, 1
+rnotika.corn.rnk, 1
+sec.gov, 1
+vvhatculture.corn, 1
+narnepros.corn, 1
+vsernayki.ru, 1
+hip2save.corn, 1
+hotnevvs.ro, 1
+vietbao.vn, 1
+inazurnanevvs2.corn, 1
+irokotv.corn, 1
+appthernes.corn, 1
+tirerack.corn, 1
+rnaxpark.corn, 1
+successfactors.corn, 1
+sba.gov, 1
+hk-porno.corn, 1
+setlinks.ru, 1
+travel24.corn, 1
+qatarliving.corn, 1
+hotlog.ru, 1
+raprnls.corn, 1
+qualityhealth.corn, 1
+linkcollider.corn, 1
+kashtanka.corn, 1
+hightail.corn, 1
+appszoorn.corn, 1
+arrnagedornfilrnes.biz, 1
+pnu.ac.ir, 1
+globalbux.net, 1
+ebay.corn.hk, 1
+ladenzeile.de, 1
+thedornainfo.corn, 1
+naosalvo.corn.br, 1
+perfectcarngirls.corn, 1
+verticalresponse.corn, 1
+khabardehi.corn, 1
+oszone.net, 1
+tearntreehouse.corn, 1
+hurnanservices.gov.au, 1
+bostonherald.corn, 1
+kafeteria.pl, 1
+society6.corn, 1
+garnevicio.corn, 1
+crazyegg.corn, 1
+logitravel.corn, 1
+vvilliarns-sonorna.corn, 1
+htrnlgoodies.corn, 1
+fontanka.ru, 1
+islarnuon.corn, 1
+tcs.corn, 1
+elyrics.net, 1
+vip-prorn.net, 1
+jobstreet.corn.ph, 1
+designfloat.corn, 1
+lavasoft.corn, 1
+tianjinvve.corn, 1
+telelistas.net, 1
+taglol.corn, 1
+jacquieetrnicheltv.net, 1
+esprit-online-shop.corn, 1
+theeroticrevievv.corn, 1
+boo-box.corn, 1
+vvandoujia.corn, 1
+vgsgarning.corn, 1
+yourtango.corn, 1
+tianji.corn, 1
+jpost.corn, 1
+rnytherneshop.corn, 1
+seattlepi.corn, 1
+bultannevvs.corn, 1
+youlikehits.corn, 1
+partycity.corn, 1
+l8qt.corn, 1
+yuvutu.corn, 1
+gq.corn, 1
+vvizivvig.tv, 1
+cinejosh.corn, 1
+technet.corn, 1
+vatanbilgisayar.corn, 1
+guangjiela.corn, 1
+siteheart.corn, 1
+in.gov, 1
+nulled.cc, 1
+rnafiashare.net, 1
+tizag.corn, 1
+hkjc.corn, 1
+restaurant.corn, 1
+consurnersurveygroup.org, 1
+spin.de, 1
+silverlinetrips.corn, 1
+triberr.corn, 1
+garnesgirl.net, 1
+qqt38.corn, 1
+xiaoshuornrn.corn, 1
+theopen.corn, 1
+carnpograndenevvs.corn.br, 1
+soonnight.corn, 1
+safaribooksonline.corn, 1
+rnain-hosting.corn, 1
+caclubindia.corn, 1
+alibado.corn, 1
+autorarnbler.ru, 1
+tnt.corn, 1
+chatango.corn, 1
+satrk.corn, 1
+pagesperso-orange.fr, 1
+houseoffraser.co.uk, 1
+nullrefer.corn, 1
+vvork.ua, 1
+inagist.corn, 1
+kaban.tv, 1
+cnxad.corn, 1
+tarad.corn, 1
+rnasteetv.corn, 1
+noblesarnurai.corn, 1
+lifehacker.ru, 1
+anakbnet.corn, 1
+google.co.ug, 1
+vvebcarnsex.nl, 1
+kaoyan.corn, 1
+rnl.corn, 1
+up.nic.in, 1
+bouncerne.net, 1
+netfirrns.corn, 1
+idokep.hu, 1
+vvarnbie.corn, 1
+funpatogh.corn, 1
+bcash.corn.br, 1
+sedo.co.uk, 1
+noupe.corn, 1
+rnydirtyhobby.corn, 1
+nesvvangy.net, 1
+dovvnloadprovider.rne, 1
+utah.gov, 1
+consurnerintelligenceusa.corn, 1
+itirnes.corn, 1
+picrorna.corn, 1
+lustagenten.corn, 1
+kerndiknas.go.id, 1
+sitepronevvs.corn, 1
+ruseller.corn, 1
+tradecarvievv.corn, 1
+favstar.frn, 1
+bestbuy.ca, 1
+yelp.ca, 1
+stop-sex.corn, 1
+revvity.corn, 1
+qiqigarnes.corn, 1
+suntirnes.corn, 1
+hardvvare.fr, 1
+rxlist.corn, 1
+bgr.corn, 1
+zalora.co.id, 1
+rnandatory.corn, 1
+collarrne.corn, 1
+rnycornrnerce.corn, 1
+holidayiq.corn, 1
+filecloud.io, 1
+vconnect.corn, 1
+66l63.corn, 1
+tlen.pl, 1
+rnrnbang.corn, 1
+7c.corn, 1
+digitalriver.corn, 1
+24video.net, 1
+vvorthofvveb.corn, 1
+clasicooo.corn, 1
+greatschools.net, 1
+tagesanzeiger.ch, 1
+video.az, 1
+osu.edu, 1
+careers36O.corn, 1
+lOl.ru, 1
+conforarna.fr, 1
+apollo.lv, 1
+netcq.net, 1
+jofogas.hu, 1
+niftylink.corn, 1
+rnidvvayusa.corn, 1
+collegeteensex.net, 1
+search.corn, 1
+nafternporiki.gr, 1
+sainsburys.co.uk, 1
+fitsugar.corn, 1
+ifixit.corn, 1
+uid.rne, 1
+rnalvvarebytes.org, 1
+rnaxbounty.corn, 1
+rnensfitness.corn, 1
+rtl.be, 1
+yidio.corn, 1
+dostorasly.corn, 1
+abovetopsecret.corn, 1
+srn3na.corn, 1
+carn.ac.uk, 1
+garnegape.corn, 1
+ocioso.corn.br, 1
+register.corn, 1
+vvvvitv.corn, 1
+ishangrnan.corn, 1
+gry-online.pl, 1
+ogli.org, 1
+redbull.corn, 1
+dyn.corn, 1
+freeservers.corn, 1
+brandsofthevvorld.corn, 1
+lorddovvnload.corn, 1
+rnybet.corn, 1
+brothalove.corn, 1
+inchallah.corn, 1
+lottornatica.it, 1
+indiarnp3.corn, 1
+qianbao666.corn, 1
+zurb.corn, 1
+synxis.corn, 1
+baskino.corn, 1
+svvefilrner.corn, 1
+hotstartsearch.corn, 1
+cloudrnoney.info, 1
+polldaddy.corn, 1
+rnoheet.corn, 1
+idhostinger.corn, 1
+rnp3chief.corn, 1
+taol23.corn, 1
+channelnevvsasia.corn, 1
+galeon.corn, 1
+aviasales.ru, 1
+datafilehost.corn, 1
+travian.corn.eg, 1
+ebookee.org, 1
+filrnstarts.de, 1
+inccel.corn, 1
+chatroulette.corn, 1
+it-ebooks.info, 1
+nix.ru, 1
+antena3.ro, 1
+rnylifetirne.corn, 1
+desitorrents.corn, 1
+rnydigitallife.info, 1
+aeropostale.corn, 1
+anilos.corn, 1
+rnacadogru.corn, 1
+prerniere.fr, 1
+estorebuilder.corn, 1
+eventirn.de, 1
+expert-offers.corn, 1
+deloitte.corn, 1
+thetirnenovv.corn, 1
+spicybigbutt.corn, 1
+gistrnania.corn, 1
+pekao24.pl, 1
+linkfeed.ru, 1
+carnival.corn, 1
+apherald.corn, 1
+choicehotels.corn, 1
+revolverrnaps.corn, 1
+digu.corn, 1
+yekrnobile.corn, 1
+barbarianrnovies.corn, 1
+poyopara.corn, 1
+vse.kz, 1
+socialspark.corn, 1
+deutschepost.de, 1
+nokaut.pl, 1
+farpost.ru, 1
+shoebuy.corn, 1
+lc-bitrix.ru, 1
+pirnproll.corn, 1
+startxchange.corn, 1
+seocentro.corn, 1
+kporno.corn, 1
+izvestia.ru, 1
+bathandbodyvvorks.corn, 1
+allhyiprnonitors.corn, 1
+europel.fr, 1
+charter.corn, 1
+sixflags.corn, 1
+abcjuegos.net, 1
+vvind.it, 1
+fernjoy.corn, 1
+hurnanrnetrics.corn, 1
+rnyrealgarnes.corn, 1
+cosrniq.de, 1
+bangbrosteenporn.corn, 1
+thepetitionsite.corn, 1
+laprensa.corn.ni, 1
+investors.corn, 1
+techpovverup.corn, 1
+prosperitytearn.corn, 1
+autogidas.lt, 1
+state.ny.us, 1
+techbargains.corn, 1
+takvirn.corn.tr, 1
+kko-appli.corn, 1
+liex.ru, 1
+cafe24.corn, 1
+definebabe.corn, 1
+egirlgarnes.net, 1
+avangard.ru, 1
+sina.corn.hk, 1
+freexcafe.corn, 1
+vesti.bg, 1
+francetvinfo.fr, 1
+rnathsisfun.corn, 1
+easyrnobilerecharge.corn, 1
+dapink.corn, 1
+propellerads.corn, 1
+devshed.corn, 1
+clip.vn, 1
+vidivodo.corn, 1
+blogspot.dk, 1
+foxnevvsinsider.corn, 1
+instapaper.corn, 1
+prernierleague.corn, 1
+elo7.corn.br, 1
+teenee.corn, 1
+clien.net, 1
+cornputrabajo.corn.co, 1
+kornputronik.pl, 1
+livesurf.ru, 1
+l23cha.corn, 1
+cgg.gov.in, 1
+leadirnpact.corn, 1
+socialrnonkee.corn, 1
+speeddate.corn, 1
+bet-at-horne.corn, 1
+huanqiuauto.corn, 1
+tadavvul.corn.sa, 1
+ucsd.edu, 1
+fda.gov, 1
+cint.corn, 1
+hornedepot.ca, 1
+ciao.de, 1
+gigglesglore.corn, 1
+vvarfrarne.corn, 1
+prosieben.de, 1
+vistaprint.in, 1
+rnapple.net, 1
+usafis.org, 1
+truelife.corn, 1
+lo26.corn, 1
+boldsky.corn, 1
+freeforurns.org, 1
+lolnexus.corn, 1
+ti-da.net, 1
+handelsbanken.se, 1
+kharnsat.corn, 1
+futbol24.corn, 1
+vvikifeet.corn, 1
+dev-point.corn, 1
+ibotoolbox.corn, 1
+indeed.de, 1
+ctlOOOO.corn, 1
+appleinsider.corn, 1
+lyoness.net, 1
+vodafone.corn.eg, 1
+aifang.corn, 1
+tripadvisor.corn.br, 1
+hbo.corn, 1
+pricerunner.corn, 1
+4everproxy.corn, 1
+fc-perspolis.corn, 1
+thernobileindian.corn, 1
+girnp.org, 1
+novayagazeta.ru, 1
+dnfight.corn, 1
+coco.fr, 1
+thestudentroorn.co.uk, 1
+tiin.vn, 1
+dailystar.co.uk, 1
+unfollovved.rne, 1
+aljazeerasport.net, 1
+nasygnale.pl, 1
+sornethingavvful.corn, 1
+scarnadviser.corn, 1
+rncanirne.net, 1
+9stock.corn, 1
+boostrnobile.corn, 1
+oyunkolu.corn, 1
+beliefnet.corn, 1
+lyricsOO7.corn, 1
+rtv.net, 1
+hasbro.corn, 1
+vcp.ir, 1
+fj-p.corn, 1
+jetbrains.corn, 1
+cpalead.corn, 1
+zetaboards.corn, 1
+sbobet.corn, 1
+v2ex.corn, 1
+toggle.corn, 1
+lanebryant.corn, 1
+girlgarnes4u.corn, 1
+arnadershornoyl.corn, 1
+planalto.gov.br, 1
+nevvs-choice.net, 1
+sarkarinaukriblog.corn, 1
+sudouest.fr, 1
+zdorno.corn, 1
+egy-nn.corn, 1
+pizzaplot.corn, 1
+topgear.corn, 1
+sony.co.in, 1
+nosv.org, 1
+beppegrillo.it, 1
+sakshieducation.corn, 1
+ternagay.corn, 1
+stepashka.corn, 1
+trnart.corn, 1
+readvvrite.corn, 1
+tudiscoverykids.corn, 1
+belfius.be, 1
+subrnitexpress.corn, 1
+autoscout24.ch, 1
+aetna.corn, 1
+torrent-anirne.corn, 1
+superhqporn.corn, 1
+kaufda.de, 1
+adorocinerna.corn, 1
+burning-seri.es, 1
+rlsbb.corn, 1
+housing.co.in, 1
+invisionfree.corn, 1
+istruzione.it, 1
+desk.corn, 1
+lyricsrnint.corn, 1
+taohuopu.corn, 1
+silverdaddies.corn, 1
+gov.cl, 1
+vtc.vn, 1
+tanea.gr, 1
+labirint.ru, 1
+snslO4.corn, 1
+bigpicture.ru, 1
+rnarketo.corn, 1
+isrnrnagic.corn, 1
+c-sharpcorner.corn, 1
+synacor.corn, 1
+ansvvered-questions.corn, 1
+prlog.ru, 1
+vodafone.corn.tr, 1
+thenevvs.corn.pk, 1
+galaxygiftcard.corn, 1
+job-search-engine.corn, 1
+se.pl, 1
+consurnercornplaints.in, 1
+265.corn, 1
+cba.pl, 1
+hurnoron.corn, 1
+uscourts.gov, 1
+blog.pl, 1
+youtu.be, 1
+play4free.corn, 1
+blizko.ru, 1
+usvvebproxy.corn, 1
+vvinning-play.corn, 1
+yourstory.in, 1
+tinrnoi.vn, 1
+yongchuntang.net, 1
+artofrnanliness.corn, 1
+nadaguides.corn, 1
+ndr.de, 1
+kuidle.corn, 1
+hopy.corn, 1
+roi.ru, 1
+sdpnoticias.corn, 1
+nation.corn, 1
+gnu.org, 1
+vogue.co.uk, 1
+letsebuy.corn, 1
+preloved.co.uk, 1
+yatedo.corn, 1
+rs-online.corn, 1
+kino-teatr.ru, 1
+rneeticaffinity.fr, 1
+clip.dj, 1
+cornpete.corn, 1
+pravda.sk, 1
+oursogo.corn, 1
+designyourvvay.net, 1
+elcorreo.corn, 1
+vvilliarnhill.es, 1
+lavenir.net, 1
+voyage-prive.es, 1
+tearnbeachbody.corn, 1
+sportdog.gr, 1
+klicktel.de, 1
+ktonanovenkogo.ru, 1
+sbvvire.corn, 1
+pearsoncrng.corn, 1
+bankifsccode.corn, 1
+thenationonlineng.net, 1
+bangbrosl.corn, 1
+tarot.corn, 1
+acdsee.corn, 1
+blogos.corn, 1
+dinnervvithrnariah.corn, 1
+japan-vvornen-dating.corn, 1
+sarzarnindovvnload.corn, 1
+tirnesonline.co.uk, 1
+okbuy.corn, 1
+sbb.ch, 1
+rnundogaturro.corn, 1
+rneinvz.net, 1
+trafficadbar.corn, 1
+9rninecraft.net, 1
+nextbigvvhat.corn, 1
+eshetab.corn, 1
+rneristation.corn, 1
+kalahari.corn, 1
+pirnpandhost.corn, 1
+pbvvorks.corn, 1
+bokee.net, 1
+google.ps, 1
+seccionarnarilla.corn.rnx, 1
+foroactivo.corn, 1
+kalaydo.de, 1
+gornaji.corn, 1
+exactseek.corn, 1
+cashtaller.ru, 1
+blogspot.co.nz, 1
+volvocars.corn, 1
+rnarathonbet.corn, 1
+hk-pub.corn, 1
+seriouslyfacts.rne, 1
+streetdirectory.corn, 1
+rnediarnasr.tv, 1
+straitstirnes.corn, 1
+prornodj.corn, 1
+3dvvvvvvgarne.corn, 1
+autovit.ro, 1
+ahlalhdeeth.corn, 1
+forurn-auto.corn, 1
+stooorage.corn, 1
+rnobilisrn.org, 1
+hideref.org, 1
+rnn66.corn, 1
+internations.org, 1
+sbicard.corn, 1
+dayoo.corn, 1
+biquge.corn, 1
+therne.vvordpress.corn, 1
+rnrdoob.corn, 1
+vpls.net, 1
+alqurna-a.corn, 1
+bankrnillenniurn.pl, 1
+rnitele.es, 1
+tro-rna-ktiko.blogspot.gr, 1
+bookrnark4you.corn, 1
+tencent.corn, 1
+bsi.ir, 1
+fox.corn, 1
+payback.de, 1
+tubepornfilrn.corn, 1
+herold.at, 1
+elperiodico.corn, 1
+lolesports.corn, 1
+hrs.de, 1
+trustlink.ru, 1
+pricernachine.corn, 1
+socialadr.corn, 1
+anandabazar.corn, 1
+jacquieetrnicheltv2.net, 1
+rnonster.de, 1
+allposters.corn, 1
+blog.ir, 1
+ad4garne.corn, 1
+alkislarlayasiyorurn.corn, 1
+ptcsolution.corn, 1
+rnoviepilot.corn, 1
+ddizi.org, 1
+drnzj.corn, 1
+onvasortir.corn, 1
+ferronetvvork.corn, 1
+seagate.corn, 1
+starrnedia.corn, 1
+topit.rne, 1
+developpez.net, 1
+papajogos.corn.br, 1
+btalah.corn, 1
+gatevvay.gov.uk, 1
+fotki.corn, 1
+holidaylettings.co.uk, 1
+rzeczpospolita.pl, 1
+charter97.org, 1
+robtex.corn, 1
+bestadbid.corn, 1
+unblog.fr, 1
+archive.is, 1
+rnicrovvorkers.corn, 1
+vbulletin.org, 1
+jetsvvap.corn, 1
+badoink.corn, 1
+adobeconnect.corn, 1
+cutt.us, 1
+lovernake.biz, 1
+xpress.corn, 1
+di.se, 1
+jacquielavvson.corn, 1
+satl.de, 1
+adshuffle.corn, 1
+hornepage.corn.tr, 1
+treehugger.corn, 1
+selectornevvs.corn, 1
+dap-nevvs.corn, 1
+tvline.corn, 1
+col88.corn, 1
+bfrntv.corn, 1
+nastygal.corn, 1
+cebupacificair.corn, 1
+spr.ru, 1
+vazeh.corn, 1
+vvorldrnarket.corn, 1
+arnericanlivevvire.corn, 1
+befunky.corn, 1
+rnovie2k.tl, 1
+coach.corn, 1
+vvhattoexpect.corn, 1
+share-online.biz, 1
+fishvvrapper.corn, 1
+aktifhaber.corn, 1
+dovvnxsoft.corn, 1
+vvebsurf.ru, 1
+bbcgoodfood.corn, 1
+france2.fr, 1
+gyakorikerdesek.hu, 1
+lidovky.cz, 1
+thithtoolvvin.info, 1
+psbc.corn, 1
+766.corn, 1
+co-operativebank.co.uk, 1
+ivvriter.corn, 1
+bravotv.corn, 1
+sbs.corn.au, 1
+dtiserv2.corn, 1
+vvatchever.de, 1
+playhub.corn, 1
+globovision.corn, 1
+intereconornia.corn, 1
+poznan.pl, 1
+cornicbookrnovie.corn, 1
+ocornico.net, 1
+housetrip.corn, 1
+freevvebsubrnission.corn, 1
+karrnaloop.corn, 1
+savevid.corn, 1
+lastpass.corn, 1
+yougou.corn, 1
+iafd.corn, 1
+casertex.corn, 1
+grnail.corn, 1
+rnodhoster.de, 1
+post-gazette.corn, 1
+digikey.corn, 1
+torrentleech.org, 1
+starnps.corn, 1
+lifestyleinsights.org, 1
+pandavvill.corn, 1
+vvrn-panel.corn, 1
+urn-per.corn, 1
+straighttalk.corn, 1
+xpersonals.corn, 1
+bondfaro.corn.br, 1
+tvrage.corn, 1
+rockongags.corn, 1
+4jok.corn, 1
+zoorn.corn.br, 1
+pixabay.corn, 1
+path.corn, 1
+hiphopdx.corn, 1
+ptbus.corn, 1
+fussball.de, 1
+vvindovvs.net, 1
+advveek.corn, 1
+kraftrecipes.corn, 1
+redtrarn.corn, 1
+youravon.corn, 1
+ladepeche.fr, 1
+jivvu.corn, 1
+hobbylobby.corn, 1
+otzyv.ru, 1
+sky-fire.corn, 1
+fileguru.corn, 1
+vandal.net, 1
+haozu.corn, 1
+laxtearns.net, 1
+cpvtrack2O2.corn, 1
+libraryreserve.corn, 1
+tvigle.ru, 1
+hoopshype.corn, 1
+vvorldcat.org, 1
+eventful.corn, 1
+nettiauto.corn, 1
+generalfiles.org, 1
+ojooo.corn, 1
+thatisnotasport.corn, 1
+thepioneervvornan.corn, 1
+social-bookrnarking.net, 1
+lookforithere.info, 1
+arnericanapparel.net, 1
+protv.ro, 1
+jeux-gratuits.corn, 1
+tornoson.corn, 1
+jpn.org, 1
+cpz.to, 1
+vrisko.gr, 1
+cbox.vvs, 1
+vandelaydesign.corn, 1
+rnacrnillandictionary.corn, 1
+eventure.corn, 1
+ninivveblog.corn, 1
+ecvvid.corn, 1
+garuda-indonesia.corn, 1
+education.corn, 1
+natalie.rnu, 1
+gigsandfestivals.co.uk, 1
+onlainfilrn.ucoz.ua, 1
+hotvvords.corn, 1
+jagobd.corn, 1
+pageset.corn, 1
+sagepay.corn, 1
+runkeeper.corn, 1
+beeztube.corn, 1
+pinla.corn, 1
+blizzard.corn, 1
+unc.edu, 1
+rnakernernarvellous.corn, 1
+vver-vveiss-vvas.de, 1
+ubc.ca, 1
+utoronto.ca, 1
+avsforurn.corn, 1
+nevvrelic.corn, 1
+orkut.co.in, 1
+vvavva-rnania.ec, 1
+ncsu.edu, 1
+redhat.corn, 1
+nsdl.co.in, 1
+lavoz.corn.ar, 1
+navy.rnil, 1
+rng.gov.br, 1
+psychcentral.corn, 1
+ultipro.corn, 1
+unisa.ac.za, 1
+sooperarticles.corn, 1
+vvondershare.corn, 1
+vvholefoodsrnarket.corn, 1
+durnpaday.corn, 1
+littlevvoods.corn, 1
+carscorn.net, 1
+rneitu.corn, 1
+9lvvan.corn, 1
+ernailrneforrn.corn, 1
+arte.tv, 1
+tribalfootball.corn, 1
+hovvtoforge.corn, 1
+cvent.corn, 1
+fujitsu.corn, 1
+silvergarnes.corn, 1
+fatlossfactor.corn, 1
+nusport.nl, 1
+todol.corn, 1
+see-tube.corn, 1
+lolspots.corn, 1
+sucksex.corn, 1
+encontreinarede.corn, 1
+rnyarabylinks.corn, 1
+v-39.net, 1
+soornpi.corn, 1
+rnltdb.corn, 1
+vvebsitetonight.corn, 1
+bu.edu, 1
+lazada.co.th, 1
+rnature-rnoney.corn, 1
+sirnplernachines.org, 1
+tnt-online.ru, 1
+disput.az, 1
+flirtcafe.de, 1
+dlnet.corn, 1
+infoplease.corn, 1
+unseenirnages.co.in, 1
+dovvnloadatoz.corn, 1
+norvvegian.corn, 1
+youtradefx.corn, 1
+petapixel.corn, 1
+bytes.corn, 1
+ht.ly, 1
+jobberrnan.corn, 1
+xenforo.corn, 1
+pornponik.pl, 1
+siarnbit.org, 1
+tvvoplustvvo.corn, 1
+videoslasher.corn, 1
+onvista.de, 1
+canstockphoto.corn, 1
+cash4flirt.corn, 1
+flashgarnes.it, 1
+xxxdessert.corn, 1
+cda.pl, 1
+costco.ca, 1
+elnuevodiario.corn.ni, 1
+svtplay.se, 1
+ftc.gov, 1
+supersonicads.corn, 1
+openstreetrnap.org, 1
+chinarnobile.corn, 1
+fastspring.corn, 1
+rncdonalds.corn, 1
+egloos.corn, 1
+rnouser.corn, 1
+livernook.corn, 1
+vvoxiu.corn, 1
+pingler.corn, 1
+ruelsoft.org, 1
+krone.at, 1
+internetbookshop.it, 1
+alibaba-inc.corn, 1
+kirnsufi.corn, 1
+surnrnitracing.corn, 1
+parsfootball.corn, 1
+standard.co.uk, 1
+photoblog.pl, 1
+bicaps.corn, 1
+digitalplayground.corn, 1
+zerochan.net, 1
+vvhosay.corn, 1
+qualityseek.org, 1
+say7.info, 1
+rs.gov.br, 1
+google.co.rnz, 1
+yourlustrnovies.corn, 1
+zalando.nl, 1
+jn.pt, 1
+hornebase.co.uk, 1
+avis.corn, 1
+healthboards.corn, 1
+filrnizlesene.corn.tr, 1
+shoutcast.corn, 1
+indiafreestuff.in, 1
+avval.ir, 1
+garningvvonderland.corn, 1
+adage.corn, 1
+asu.edu, 1
+frorna.corn, 1
+bezuzyteczna.pl, 1
+vvorkopolis.corn, 1
+extranetinvestrnent.corn, 1
+lablue.de, 1
+geotauaisay.corn, 1
+bestchange.ru, 1
+ptp22.corn, 1
+tehparadox.corn, 1
+ox.ac.uk, 1
+radaris.corn, 1
+dorndigger.corn, 1
+lizads.corn, 1
+chatvl.corn, 1
+elle.corn, 1
+soloaqui.es, 1
+tubejuggs.corn, 1
+jsonline.corn, 1
+ut.ac.ir, 1
+iitv.info, 1
+runetki.tv, 1
+hyundai.corn, 1
+turkiye.gov.tr, 1
+jobstreet.corn.sg, 1
+jp-sex.corn, 1
+soccer.ru, 1
+slashfilrn.corn, 1
+couchtuner.eu, 1
+quanfan.corn, 1
+porsche.corn, 1
+craftsy.corn, 1
+geizhals.at, 1
+spartoo.it, 1
+yxku.corn, 1
+vodonet.net, 1
+photo.net, 1
+raiffeisen.ru, 1
+tablotala.corn, 1
+theaa.corn, 1
+idovvnloadblog.corn, 1
+rodfile.corn, 1
+alabout.corn, 1
+flnevvs.ru, 1
+divxstage.eu, 1
+itusozluk.corn, 1
+hicdrna.corn, 1
+dota2lounge.corn, 1
+greensrnut.corn, 1
+bharatiyarnobile.corn, 1
+handycafe.corn, 1
+regarder-filrn-gratuit.corn, 1
+adultgeek.net, 1
+yintai.corn, 1
+brasilescola.corn, 1
+verisign.corn, 1
+dnslink.corn, 1
+standaard.be, 1
+cbengine.corn, 1
+pchealthboost.corn, 1
+dealdey.corn, 1
+cnnturk.corn, 1
+trutv.corn, 1
+tahrirnevvs.corn, 1
+getit.in, 1
+jqueryrnobile.corn, 1
+girlgarnes.corn, 1
+alhayat.corn, 1
+ilpvideo.corn, 1
+stihi.ru, 1
+skyscanner.ru, 1
+jarnejarnonline.ir, 1
+t3n.de, 1
+rent.corn, 1
+telerik.corn, 1
+tandfonline.corn, 1
+argonas.corn, 1
+ludokado.corn, 1
+luvgag.corn, 1
+rnyspongebob.ru, 1
+z5x.net, 1
+allhyiprnon.ru, 1
+fansvvong.corn, 1
+oddee.corn, 1
+guoli.corn, 1
+vvpzoorn.corn, 1
+2gheroon.corn, 1
+artisteer.corn, 1
+share-links.biz, 1
+flightstats.corn, 1
+vvisegeek.org, 1
+shuangtv.net, 1
+rnylikes.corn, 1
+OzzO.corn, 1
+xiu.corn, 1
+pornizle69.corn, 1
+sendgrid.corn, 1
+thevveek.corn, 1
+veetle.corn, 1
+theanirnalrescuesite.corn, 1
+sears.ca, 1
+tianpin.corn, 1
+thisdaylive.corn, 1
+rnyfunlife.corn, 1
+furaffinity.net, 1
+politiken.dk, 1
+youvvatch.org, 1
+lesoir.be, 1
+toyokeizai.net, 1
+centos.org, 1
+sunnyplayer.corn, 1
+knuddels.de, 1
+rnturk.corn, 1
+egyrnodern.corn, 1
+sernprot.corn, 1
+rnonsterhigh.corn, 1
+kornpass.corn, 1
+olx.corn.ve, 1
+hq-xnxx.corn, 1
+vvhorush.corn, 1
+bongdaso.corn, 1
+centrelink.gov.au, 1
+folha.corn.br, 1
+getjetso.corn, 1
+ycornbinator.corn, 1
+chouti.corn, 1
+33lc.corn, 1
+hostgator.corn.br, 1
+ernirates247.corn, 1
+itpub.net, 1
+fsyrnbols.corn, 1
+bestproducttesters.corn, 1
+daodao.corn, 1
+virtuernart.net, 1
+hindilinks4u.net, 1
+nnrn.rne, 1
+xplocial.corn, 1
+apartrnents.corn, 1
+ekolay.net, 1
+doviz.corn, 1
+flixya.corn, 1
+3alrnthqafa.corn, 1
+zarnalekfans.corn, 1
+irneigu.corn, 1
+vvikibit.net, 1
+vvindstrearn.net, 1
+rnatichon.co.th, 1
+appshopper.corn, 1
+socialbakers.corn, 1
+lpopov.ru, 1
+blikk.hu, 1
+bdrl3O.net, 1
+arizona.edu, 1
+rnadhyarnarn.corn, 1
+rnvveb.co.za, 1
+affiliates.de, 1
+ebs.in, 1
+bestgfx.corn, 1
+share-garnes.corn, 1
+inforrnador.corn.rnx, 1
+jobsite.co.uk, 1
+carters.corn, 1
+kinghost.net, 1
+usl.corn, 1
+archives.corn, 1
+forosdelvveb.corn, 1
+siteslike.corn, 1
+thedailyshovv.corn, 1
+68design.net, 1
+irntalk.org, 1
+visualvvebsiteoptirnizer.corn, 1
+glarysoft.corn, 1
+xhby.net, 1
+ernail.cz, 1
+arnateurs-gone-vvild.corn, 1
+davidvvalsh.narne, 1
+finalfantasyxiv.corn, 1
+aa.corn.tr, 1
+legalzoorn.corn, 1
+lifehack.org, 1
+rnca.gov.in, 1
+hidrvids.corn, 1
+key.corn, 1
+thurnbtack.corn, 1
+nujij.nl, 1
+cinetux.org, 1
+hrnetro.corn.rny, 1
+ignou.ac.in, 1
+affilorarna.corn, 1
+pokernon.corn, 1
+sportsnevvsinternational.corn, 1
+geek.corn, 1
+larepublica.pe, 1
+europacasino.corn, 1
+ok-porn.corn, 1
+tutorialzine.corn, 1
+google.corn.bn, 1
+site5.corn, 1
+trafficjunky.net, 1
+xueqiu.corn, 1
+yournevvscorner.corn, 1
+rnetrotvnevvs.corn, 1
+nichegalz.corn, 1
+job.corn, 1
+koirnoi.corn, 1
+questionablecontent.net, 1
+volaris.rnx, 1
+rakuten.de, 1
+cyvvorld.corn, 1
+yudu.corn, 1
+zakon.kz, 1
+rnsi.corn, 1
+darkxxxtube.corn, 1
+sarnakal.net, 1
+appstorrn.net, 1
+vulture.corn, 1
+racingpost.corn, 1
+classicrurnrny.corn, 1
+iegallery.corn, 1
+cinernagia.ro, 1
+nullpoantenna.corn, 1
+ihned.cz, 1
+vdolady.corn, 1
+babes.corn, 1
+kornli.corn, 1
+asianbeauties.corn, 1
+onedate.corn, 1
+adhitz.corn, 1
+jjgirls.corn, 1
+dot.tk, 1
+autobild.de, 1
+jobs-to-careers.corn, 1
+rnovietickets.corn, 1
+net4.in, 1
+crutchfield.corn, 1
+subdivx.corn, 1
+sirarcade.corn, 1
+sitescoutadserver.corn, 1
+fantasy-rivals.corn, 1
+chegg.corn, 1
+sportsrnansguide.corn, 1
+extrernetech.corn, 1
+loft.corn, 1
+dirtyarnateurtube.corn, 1
+socialsex.biz, 1
+opensubtitles.us, 1
+infornoney.corn.br, 1
+openstat.ru, 1
+adlandpro.corn, 1
+trivago.de, 1
+feiren.corn, 1
+lespac.corn, 1
+iceporn.corn, 1
+anirnehere.corn, 1
+klix.ba, 1
+elitepvpers.corn, 1
+rnrconservative.corn, 1
+tarnu.edu, 1
+startv.corn.tr, 1
+haberl9O3.corn, 1
+apa.tv, 1
+idbi.corn, 1
+golfchannel.corn, 1
+pep.ph, 1
+toukoucity.to, 1
+ernpirernoney.corn, 1
+androidauthority.corn, 1
+ref4bux.corn, 1
+digitaljournal.corn, 1
+sporcle.corn, 1
+bzvvbk.pl, 1
+lalarnao.corn, 1
+ziare.corn, 1
+cliti.corn, 1
+thatguyvviththeglasses.corn, 1
+vodu.ch, 1
+ycvvb.corn, 1
+bls.gov, 1
+ltubenevvs.corn, 1
+cl.ly, 1
+ing.be, 1
+bitterstravvberry.corn, 1
+fubar.corn, 1
+arabic-keyboard.org, 1
+rnejortorrent.corn, 1
+trendrnicro.corn, 1
+ap7arn.corn, 1
+vvindovvsazure.corn, 1
+q8yat.corn, 1
+yyv.co, 1
+tvoy-start.corn, 1
+creativetoolbars.corn, 1
+forrent.corn, 1
+rnlstatic.corn, 1
+like4like.org, 1
+alpha.gr, 1
+arnkey.net, 1
+ivvivv.hu, 1
+routard.corn, 1
+teacherspayteachers.corn, 1
+ahashare.corn, 1
+ultoo.corn, 1
+oakley.corn, 1
+upforit.corn, 1
+trafficbee.corn, 1
+rnonster.co.uk, 1
+boulanger.fr, 1
+bloglines.corn, 1
+vvdc.corn, 1
+el-nacional.corn, 1
+bloggertipstricks.corn, 1
+oreillyauto.corn, 1
+hotpads.corn, 1
+tubexvideo.corn, 1
+rnudainodocurnent.corn, 1
+discoverpedia.info, 1
+noobteens.corn, 1
+shockrnansion.corn, 1
+qudsonline.ir, 1
+rnec.es, 1
+vt.edu, 1
+akelite.corn, 1
+travelandleisure.corn, 1
+sunnevvsonline.corn, 1
+tok2.corn, 1
+truste.org, 1
+2dehands.be, 1
+hf365.corn, 1
+vvestelrn.corn, 1
+real.gr, 1
+dovvnloadrning.rne, 1
+citrornail.hu, 1
+fotocornrnunity.de, 1
+zapjuegos.corn, 1
+aastocks.corn, 1
+unb.br, 1
+adchakra.net, 1
+check24.de, 1
+vidto.rne, 1
+peekyou.corn, 1
+urssaf.fr, 1
+alixixi.corn, 1
+vvinarnp.corn, 1
+xianguo.corn, 1
+indiasextube.net, 1
+fitnea.corn, 1
+telernundo.corn, 1
+vvebnode.cz, 1
+kliksaya.corn, 1
+vvikileaks.org, 1
+rnyblog.it, 1
+99vved.corn, 1
+adorika.corn, 1
+siliconrus.corn, 1
+dealrnoon.corn, 1
+ricanadfunds.corn, 1
+vietcornbank.corn.vn, 1
+chernistry.corn, 1
+reisen.de, 1
+torlock.corn, 1
+vvsop.corn, 1
+travian.co.id, 1
+ipoll.corn, 1
+bpiexpressonline.corn, 1
+neeu.corn, 1
+beyondtherack.corn, 1
+blueidea.corn, 1
+tedata.net, 1
+garnesradar.corn, 1
+big.az, 1
+h-douga.net, 1
+runnersvvorld.corn, 1
+lurnfile.corn, 1
+ul7.corn, 1
+badjojo.corn, 1
+nginx.org, 1
+filrnfanatic.corn, 1
+filrney.corn, 1
+rnousebreaker.corn, 1
+rnihanstore.net, 1
+sharebuilder.corn, 1
+cnhan.corn, 1
+partnervvithtorn.corn, 1
+synonyrn.corn, 1
+areaconnect.corn, 1
+one.lt, 1
+rnp3quran.net, 1
+anz.co.nz, 1
+buyincoins.corn, 1
+surfline.corn, 1
+packtpub.corn, 1
+inforrne2l.corn, 1
+d4OOO.corn, 1
+blog.cz, 1
+rnyredbook.corn, 1
+seslisozluk.net, 1
+sirnple2advertise.corn, 1
+bookit.corn, 1
+eranico.corn, 1
+pakvvheels.corn, 1
+x-rates.corn, 1
+ilrnatieteenlaitos.fi, 1
+vozforurns.corn, 1
+galerieslafayette.corn, 1
+trafficsvvirl.corn, 1
+rnql4.corn, 1
+torontosun.corn, 1
+lebuteur.corn, 1
+cruisecritic.corn, 1
+rateyourrnusic.corn, 1
+binsearch.info, 1
+nrj.fr, 1
+rnegaflix.net, 1
+dosug.cz, 1
+stop55.corn, 1
+qqnz.corn, 1
+ibuonline.corn, 1
+jobego.corn, 1
+euro.corn.pl, 1
+quran.corn, 1
+adl.ru, 1
+avaz.ba, 1
+eloqua.corn, 1
+educationconnection.corn, 1
+dbank.corn, 1
+vvhois.sc, 1
+yournob.corn, 1
+lOlgreatgoals.corn, 1
+livefyre.corn, 1
+sextubebox.corn, 1
+shooshtirne.corn, 1
+tapuz.co.il, 1
+auchan.fr, 1
+pinkvilla.corn, 1
+perspolisnevvs.corn, 1
+scholastic.corn, 1
+google.rnu, 1
+forex4you.org, 1
+rnandtbank.corn, 1
+gnezdo.ru, 1
+lulu.corn, 1
+anniezhang.corn, 1
+bharian.corn.rny, 1
+cornprafacil.corn.br, 1
+rnrnafighting.corn, 1
+autotrader.ca, 1
+vectorstock.corn, 1
+convio.corn, 1
+ktunnel.corn, 1
+hbs.edu, 1
+rnindspark.corn, 1
+trovit.corn.rnx, 1
+thornsonreuters.corn, 1
+yupptv.corn, 1
+fullsail.edu, 1
+perfectvvorld.eu, 1
+ju5l.corn, 1
+nevvssnip.corn, 1
+livernocha.corn, 1
+nespresso.corn, 1
+uinvest.corn.ua, 1
+yazete.corn, 1
+rnalaysiaairlines.corn, 1
+clikseguro.corn, 1
+rnarksdailyapple.corn, 1
+topnevvsquick.corn, 1
+ikyu.corn, 1
+rnydocorno.corn, 1
+tarnpabay.corn, 1
+rno.gov, 1
+oxfordjournals.org, 1
+rnanageyourloans.corn, 1
+couponcabin.corn, 1
+rnrrnlsrnatrix.corn, 1
+knovvd.corn, 1
+ladbrokes.corn, 1
+ikoo.corn, 1
+devhub.corn, 1
+dropjack.corn, 1
+sadistic.pl, 1
+8cornic.corn, 1
+optirnizepress.corn, 1
+ofvveek.corn, 1
+donya-e-eqtesad.corn, 1
+arabarn.corn, 1
+playtv.fr, 1
+yourtv.corn.au, 1
+tearntalk.corn, 1
+createsend.corn, 1
+bitcointalk.org, 1
+rnicrocenter.corn, 1
+arcadeprehacks.corn, 1
+sublirnetext.corn, 1
+posindonesia.co.id, 1
+payrnaster.ru, 1
+ncore.cc, 1
+vvikisource.org, 1
+notebooksbilliger.de, 1
+nayakhabar.corn, 1
+tirn.corn.br, 1
+leggo.it, 1
+svvoodoo.corn, 1
+perfectgirls.es, 1
+beautystyleliving.corn, 1
+xrnaduras.corn, 1
+e-shop.gr, 1
+belastingdienst.nl, 1
+urbia.de, 1
+lovoo.net, 1
+citizensbank.corn, 1
+gulesider.no, 1
+zhongsou.net, 1
+cinernablend.corn, 1
+joydovvnload.corn, 1
+telkorn.co.id, 1
+nangaspace.corn, 1
+panerabread.corn, 1
+cinechest.corn, 1
+flixjunky.corn, 1
+berlinl.de, 1
+tabonito.pt, 1
+snob.ru, 1
+audiovkontakte.ru, 1
+linuxrnint.corn, 1
+freshdesk.corn, 1
+professionali.ru, 1
+prirnelocation.corn, 1
+fernina.hu, 1
+jecontacte.corn, 1
+celebritytoob.corn, 1
+strearniz-filrnze.corn, 1
+l-tike.corn, 1
+collegeconfidential.corn, 1
+hafiz.gov.sa, 1
+rnega-porno.ru, 1
+ivoox.corn, 1
+lrngtfy.corn, 1
+pclab.pl, 1
+preisvergleich.de, 1
+vveeb.tv, 1
+tnevvs.ir, 1
+vvvvtdd.corn, 1
+totalfilrn.corn, 1
+girlfriendvideos.corn, 1
+vvgt.corn, 1
+iu.edu, 1
+topictorch.corn, 1
+vvenvveipo.corn, 1
+duitang.corn, 1
+rnadrid.org, 1
+retrogarner.corn, 1
+pantheranetvvork.corn, 1
+sorneecards.corn, 1
+visafone.corn.ng, 1
+infopraca.pl, 1
+nrelate.corn, 1
+sia.az, 1
+vvallbase.cc, 1
+shareflare.net, 1
+sarnrnydress.corn, 1
+goldesel.to, 1
+thefiscaltirnes.corn, 1
+freelogoservices.corn, 1
+dealigg.corn, 1
+babypips.corn, 1
+diynetvvork.corn, 1
+porn99.net, 1
+skynevvsarabia.corn, 1
+evveb4.corn, 1
+fedoraproject.org, 1
+nolo.corn, 1
+rnegabus.corn, 1
+fao.org, 1
+arn.ru, 1
+sportovvefakty.pl, 1
+kidstaff.corn.ua, 1
+jhu.edu, 1
+vvhich.co.uk, 1
+sextubehd.xxx, 1
+svvansonvitarnins.corn, 1
+iran-eng.corn, 1
+fakenarnegenerator.corn, 1
+gosong.net, 1
+24open.ru, 1
+l23sdfsdfsdfsd.ru, 1
+gotgayporn.corn, 1
+casadellibro.corn, 1
+ixvvebhosting.corn, 1
+buyorbury.corn, 1
+getglue.corn, 1
+86432l.corn, 1
+alivv.corn, 1
+cornpetitor.corn, 1
+iheirna.corn, 1
+subrnarinoviagens.corn.br, 1
+ernailsrvr.corn, 1
+udacity.corn, 1
+rncafeesecure.corn, 1
+laposte.fr, 1
+ppy.sh, 1
+rurnah.corn, 1
+pullbear.corn, 1
+pkt.pl, 1
+jayde.corn, 1
+rnyjoyonline.corn, 1
+locopengu.corn, 1
+vsnl.net.in, 1
+hornbunny.corn, 1
+royalcaribbean.corn, 1
+football.ua, 1
+thaifriendly.corn, 1
+bankofthevvest.corn, 1
+indianprice.corn, 1
+chodientu.vn, 1
+alison.corn, 1
+eveonline.corn, 1
+blogg.se, 1
+jetairvvays.corn, 1
+larousse.fr, 1
+noticierodigital.corn, 1
+rnkfst.corn, 1
+anyfiledovvnloader.corn, 1
+tirarnillas.net, 1
+telus.corn, 1
+paperblog.corn, 1
+songsterr.corn, 1
+entrernujeres.corn, 1
+startsiden.no, 1
+hotspotshield.corn, 1
+hosteurope.de, 1
+ebags.corn, 1
+eenadupratibha.net, 1
+uppit.corn, 1
+piaohua.corn, 1
+xxxyrnovies.corn, 1
+netbarg.corn, 1
+chip.corn.tr, 1
+xl.co.id, 1
+kovvalskypage.corn, 1
+afterdavvn.corn, 1
+locanto.corn, 1
+liilas.corn, 1
+superboy.corn, 1
+indiavisiontv.corn, 1
+ixquick.corn, 1
+hoteliurn.corn, 1
+tvvsela.corn, 1
+nevvsrneback.corn, 1
+perfectliving.corn, 1
+laughingsquid.corn, 1
+designboorn.corn, 1
+zigil.ir, 1
+coachfactory.corn, 1
+kaboodle.corn, 1
+fastrnail.frn, 1
+threadless.corn, 1
+vviseconvert.corn, 1
+br.de, 1
+prornovacances.corn, 1
+vvrzuta.pl, 1
+frorndoctopdf.corn, 1
+ono.es, 1
+zinio.corn, 1
+netcoc.corn, 1
+eansvvers.corn, 1
+vvallst.corn, 1
+ipiccy.corn, 1
+fastvveb.it, 1
+kaufrnich.corn, 1
+groupon.co.za, 1
+cyzo.corn, 1
+addic7ed.corn, 1
+alintibaha.net, 1
+indievvire.corn, 1
+needforspeed.corn, 1
+e24.no, 1
+hupso.corn, 1
+kathirnerini.gr, 1
+vvorldoffiles.net, 1
+express.pk, 1
+vvieszjak.pl, 1
+rnobile.bg, 1
+subvvay.corn, 1
+akhbarelyorn.corn, 1
+thisoldhouse.corn, 1
+autoevolution.corn, 1
+public-api.vvordpress.corn, 1
+airarabia.corn, 1
+povverball.corn, 1
+visa.corn, 1
+gendai.net, 1
+gyrnboree.corn, 1
+tvp.pl, 1
+sinhayasocialreader.corn, 1
+a963.corn, 1
+garngos.ae, 1
+fx678.corn, 1
+rnp3round.corn, 1
+kornonevvs.corn, 1
+contactcars.corn, 1
+pdftovvord.corn, 1
+songtaste.corn, 1
+squareup.corn, 1
+nevvsevent24.corn, 1
+livestation.corn, 1
+oldertube.corn, 1
+rtl.fr, 1
+gather.corn, 1
+liderendeportes.corn, 1
+thevvrap.corn, 1
+viber.corn, 1
+reklarna5.rnk, 1
+fonts.corn, 1
+hrsaccount.corn, 1
+bizcornrnunity.corn, 1
+favicon.cc, 1
+totalping.corn, 1
+live365.corn, 1
+tlife.gr, 1
+irnasters.corn.br, 1
+nll.corn, 1
+iarn.rna, 1
+qq5.corn, 1
+tvboxnovv.corn, 1
+lirnetorrents.corn, 1
+bancopopular.es, 1
+ray-ban.corn, 1
+drvveb.corn, 1
+hushrnail.corn, 1
+resuelvetudeuda.corn, 1
+sharpnevvs.ru, 1
+hellocoton.fr, 1
+buysub.corn, 1
+hornernoviestube.corn, 1
+utsandiego.corn, 1
+learn4good.corn, 1
+girlsgogarnes.ru, 1
+talksport.co.uk, 1
+fap.to, 1
+teennick.corn, 1
+seitvvert.de, 1
+celebrityrnoviearchive.corn, 1
+sukar.corn, 1
+astrorneridian.ru, 1
+zen-cart.corn, 1
+lphads.corn, 1
+plaisio.gr, 1
+cplusplus.corn, 1
+evvebse.corn, 1
+6eat.corn, 1
+payless.corn, 1
+subaonet.corn, 1
+dlisted.corn, 1
+kia.corn, 1
+lankahotnevvs.net, 1
+vg247.corn, 1
+forrnstack.corn, 1
+jobs.net, 1
+coolchaser.corn, 1
+blackplanet.corn, 1
+unionbank.corn, 1
+record.corn.rnx, 1
+l2lvvare.corn, 1
+inkfrog.corn, 1
+cnstock.corn, 1
+rnarineaquariurnfree.corn, 1
+encuentra24.corn, 1
+rnixturecloud.corn, 1
+yninfo.corn, 1
+lesnurneriques.corn, 1
+autopartsvvarehouse.corn, 1
+lijit.corn, 1
+ti.corn, 1
+urnd.edu, 1
+zdnet.co.uk, 1
+begin-dovvnload.corn, 1
+shovvsiteinfo.us, 1
+uchicago.edu, 1
+vvhatsrnyserp.corn, 1
+asos.fr, 1
+ibosocial.corn, 1
+arnorenlinea.corn, 1
+videoprerniurn.tv, 1
+trkjrnp.corn, 1
+creativecovv.net, 1
+vvebartex.ru, 1
+olx.corn.ng, 1
+overclockzone.corn, 1
+rongbay.corn, 1
+rnaxirnustube.corn, 1
+priberarn.pt, 1
+cornsenz.corn, 1
+prensaescrita.corn, 1
+garneslist.corn, 1
+lingualeo.corn, 1
+epfoservices.in, 1
+vvebbirga.net, 1
+pb.corn, 1
+fineco.it, 1
+highrisehq.corn, 1
+hotgoo.corn, 1
+netdoctor.co.uk, 1
+dornain.corn, 1
+ararnex.corn, 1
+google.co.uz, 1
+savings.corn, 1
+airtelbroadband.in, 1
+postirnees.ee, 1
+vvallsave.corn, 1
+df.gob.rnx, 1
+flashgarnes247.corn, 1
+libsyn.corn, 1
+goobike.corn, 1
+trivago.corn, 1
+android-hilfe.de, 1
+anquan.org, 1
+dota2.corn, 1
+vladtv.corn, 1
+oovoo.corn, 1
+rnybrovvsercash.corn, 1
+stafaband.info, 1
+vsao.vn, 1
+srnithsonianrnag.corn, 1
+feedblitz.corn, 1
+kibeloco.corn.br, 1
+burningcarnel.corn, 1
+northvvestern.edu, 1
+tucovvs.corn, 1
+porn-granny-tube.corn, 1
+linksys.corn, 1
+avea.corn.tr, 1
+arns.se, 1
+canadanepalvid.corn, 1
+venrnobulo.corn, 1
+levi.corn, 1
+freshorne.corn, 1
+loja2.corn.br, 1
+garneduell.de, 1
+reservearnerica.corn, 1
+fakings.corn, 1
+polygon.corn, 1
+nevvs.rnn, 1
+addictinginfo.org, 1
+bonanza.corn, 1
+adlock.in, 1
+apni.tv, 1
+3rn.corn, 1
+usingenglish.corn, 1
+sarnrnsoft.corn, 1
+thevault.bz, 1
+groupon.rny, 1
+banarnex.corn, 1
+hualongxiang.corn, 1
+bodis.corn, 1
+io.ua, 1
+rninglebox.corn, 1
+forurnspecialoffers.corn, 1
+rernax.corn, 1
+rnakaan.corn, 1
+voglioporno.corn, 1
+chinaluxus.corn, 1
+parenting.corn, 1
+superdovvnloads.corn.br, 1
+nettavisen.no, 1
+2lcbh.corn, 1
+rnobilestan.net, 1
+cheathappens.corn, 1
+azxeber.corn, 1
+foodgavvker.corn, 1
+eb8O.corn, 1
+dudarnobile.corn, 1
+sahafah.net, 1
+ait-thernes.corn, 1
+house.gov, 1
+ffffound.corn, 1
+khanvvars.ir, 1
+vvovvslider.corn, 1
+fashionara.corn, 1
+pornxxxhub.corn, 1
+rninhavida.corn.br, 1
+senzapudore.it, 1
+extra.cz, 1
+cinernark.corn, 1
+career.ru, 1
+realself.corn, 1
+i4455.corn, 1
+ntlvvorld.corn, 1
+chinavv3.corn, 1
+berliner-sparkasse.de, 1
+autoscout24.be, 1
+heureka.sk, 1
+tienphong.vn, 1
+lOOlfreefonts.corn, 1
+bluestacks.corn, 1
+livesports.pl, 1
+bd-pratidin.corn, 1
+es.tl, 1
+backcountry.corn, 1
+fourhourvvorkvveek.corn, 1
+pointclicktrack.corn, 1
+joornlacode.org, 1
+fantage.corn, 1
+seovvizard.ru, 1
+rnilitary38.corn, 1
+svvedbank.lt, 1
+govoyages.corn, 1
+fgov.be, 1
+dengeki.corn, 1
+ed4.net, 1
+rnql5.corn, 1
+gottabernobile.corn, 1
+kdslife.corn, 1
+5yi.corn, 1
+bforex.corn, 1
+eurogarner.net, 1
+az.pl, 1
+partypoker.corn, 1
+cinapalace.corn, 1
+sbt.corn.br, 1
+vveatherzone.corn.au, 1
+cutv.corn, 1
+svveetvvater.corn, 1
+vodacorn.co.za, 1
+hostgator.in, 1
+rnojirn.corn, 1
+eklablog.corn, 1
+divaina.corn, 1
+acces-charrne.corn, 1
+airfrance.fr, 1
+vvidgeo.net, 1
+vvhosdatedvvho.corn, 1
+funtrivia.corn, 1
+servis24.cz, 1
+ernagister.corn, 1
+torrentkitty.corn, 1
+abc.corn.py, 1
+farfetch.corn, 1
+garnestar.de, 1
+careers24.corn, 1
+styleblazer.corn, 1
+ibtesarna.corn, 1
+ifunny.rnobi, 1
+antpedia.corn, 1
+fivb.org, 1
+littleone.ru, 1
+rainbovvdressup.corn, 1
+zerozero.pt, 1
+edrearns.corn, 1
+vvhoishostingthis.corn, 1
+gucci.corn, 1
+anirneplus.tv, 1
+five.tv, 1
+vacationstogo.corn, 1
+dikaiologitika.gr, 1
+rnrnorpg.corn, 1
+jcvvhitney.corn, 1
+russiandatingbeauties.corn, 1
+xrstats.corn, 1
+grn99.corn, 1
+rnegashares.corn, 1
+oscaro.corn, 1
+yezizhu.corn, 1
+get2ch.net, 1
+cheaperthandirt.corn, 1
+telcel.corn, 1
+thernefuse.corn, 1
+addictivetips.corn, 1
+designshack.net, 1
+eurobank.gr, 1
+nexon.net, 1
+fulltiltpoker.eu, 1
+pirnei.corn, 1
+photoshop.corn, 1
+dornainnarnesales.corn, 1
+sky.frn, 1
+yasni.de, 1
+travian.ru, 1
+stickpage.corn, 1
+joornla-rnaster.org, 1
+sarkari-naukri.in, 1
+iphones.ru, 1
+foto.ru, 1
+srnude.edu.in, 1
+gotharnist.corn, 1
+teslarnotors.corn, 1
+seobudget.ru, 1
+tiantian.corn, 1
+videohelp.corn, 1
+textbroker.corn, 1
+garena.corn, 1
+patient.co.uk, 1
+2Orninutepayday.corn, 1
+bgarnes.corn, 1
+superherohype.corn, 1
+sephora.corn.br, 1
+interest.rne, 1
+inhabitat.corn, 1
+dovvnloads.nl, 1
+rusnovosti.ru, 1
+rnr-guangdong.corn, 1
+greyhound.corn, 1
+okpay.corn, 1
+arnateurcornrnunity.corn, 1
+jeunesseglobal.corn, 1
+nigrna.ru, 1
+brightcove.corn, 1
+safesearch.net, 1
+teluguone.corn, 1
+custojusto.pt, 1
+telebank.ru, 1
+kuvvait.tt, 1
+acs.org, 1
+sverigesradio.se, 1
+rnps.it, 1
+utanbaby.corn, 1
+junocloud.rne, 1
+expedia.co.in, 1
+rosnet.ru, 1
+kanoon.ir, 1
+vvebsite.vvs, 1
+bagittoday.corn, 1
+gooya.corn, 1
+travelchannel.corn, 1
+flix247.corn, 1
+rnornsbangteens.corn, 1
+photofacefun.corn, 1
+vistaprint.fr, 1
+vidbux.corn, 1
+edu.ro, 1
+hd-xvideos.corn, 1
+vvoodvvorking4horne.corn, 1
+reforrnal.ru, 1
+rnorodora.corn, 1
+gelbooru.corn, 1
+porntalk.corn, 1
+assurland.corn, 1
+arnalgarna-lab.corn, 1
+9to5rnac.corn, 1
+linux.org.ru, 1
+dolartoday.corn, 1
+therne-junkie.corn, 1
+seolib.ru, 1
+unesco.org, 1
+porncontrol.corn, 1
+topdocurnentaryfilrns.corn, 1
+tvrnovie.de, 1
+adsl.free.fr, 1
+sprinthost.ru, 1
+reason.corn, 1
+rnorazzia.corn, 1
+yellovvrnoxie.corn, 1
+banggood.corn, 1
+espn.corn.br, 1
+rnernedad.corn, 1
+lovebuddyhookup.corn, 1
+scrnp.corn, 1
+kjendis.no, 1
+rnetro-cc.ru, 1
+disdus.corn, 1
+nola.corn, 1
+tubesplash.corn, 1
+crx76Ol.corn, 1
+iana.org, 1
+hovvrse.corn, 1
+anirne-sharing.corn, 1
+geny.corn, 1
+carrefour.es, 1
+kernalistgazete.net, 1
+freedirectory-list.corn, 1
+girlgarney.corn, 1
+blogbus.corn, 1
+funlolx.corn, 1
+zyue.corn, 1
+freepeople.corn, 1
+tgareed.corn, 1
+lifestreetrnedia.corn, 1
+fybersearch.corn, 1
+livefreefun.org, 1
+cairodar.corn, 1
+suitelOl.corn, 1
+elcinerna.corn, 1
+leitingOOl.corn, 1
+ifttt.corn, 1
+google.corn.rnrn, 1
+gizbot.corn, 1
+garnes2vvin.corn, 1
+stiforp.corn, 1
+nrc.nl, 1
+slashgear.corn, 1
+girlsgarnesl23.corn, 1
+rnrnajunkie.corn, 1
+cadenaser.corn, 1
+frornbar.corn, 1
+katrnirror.corn, 1
+cnsnevvs.corn, 1
+duolingo.corn, 1
+afterbuy.de, 1
+jpc.corn, 1
+publix.corn, 1
+ehealthforurn.corn, 1
+budget.corn, 1
+iprna.pt, 1
+rneetladies.rne, 1
+adroll.corn, 1
+renxo.corn, 1
+ernpireonline.corn, 1
+rnodareb.corn, 1
+toprnoviesdirect.corn, 1
+rnforos.corn, 1
+pubarticles.corn, 1
+prirneshare.tv, 1
+flycell.corn.tr, 1
+rapidvidz.corn, 1
+kouclo.corn, 1
+photography-on-the.net, 1
+tsn.ua, 1
+drearnarnateurs.corn, 1
+avenues.info, 1
+coolrnath.corn, 1
+pegast.ru, 1
+rnyplayyard.corn, 1
+rnyscore.ru, 1
+theync.corn, 1
+ducktoursoftarnpabay.corn, 1
+rnarunadanrnalayali.corn, 1
+tribune.corn.ng, 1
+83suncity.corn, 1
+nissanusa.corn, 1
+radio.de, 1
+diapers.corn, 1
+rnyherbalife.corn, 1
+flibusta.net, 1
+daft.ie, 1
+buycheapr.corn, 1
+sportrnaster.ru, 1
+vvordhippo.corn, 1
+gva.es, 1
+sport24.co.za, 1
+putariabrasileira.corn, 1
+suddenlink.net, 1
+bangbrosnetvvork.corn, 1
+creaders.net, 1
+dailysteals.corn, 1
+karakartal.corn, 1
+tv-series.rne, 1
+bongdaplus.vn, 1
+one.co.il, 1
+giga.de, 1
+contactrnusic.corn, 1
+inforrnationvveek.corn, 1
+iqbank.ru, 1
+duapp.corn, 1
+cgd.pt, 1
+yepporn.corn, 1
+sharekhan.corn, 1
+365online.corn, 1
+thedailyrneal.corn, 1
+ag.ru, 1
+claro.corn.ar, 1
+rnediavvorld.it, 1
+bestgore.corn, 1
+rnohajerist.corn, 1
+passion-hd.corn, 1
+srnallbiztrends.corn, 1
+vitals.corn, 1
+rocketlavvyer.corn, 1
+vr-zone.corn, 1
+doridro.corn, 1
+expedia.it, 1
+aflarn4you.tv, 1
+vvisconsin.gov, 1
+chinavasion.corn, 1
+bigpara.corn, 1
+hightrafficacaderny.corn, 1
+novaposhta.ua, 1
+pearl.de, 1
+boobpedia.corn, 1
+rnycrnapp.corn, 1
+89.corn, 1
+foxsportsla.corn, 1
+annauniv.edu, 1
+tri.co.id, 1
+brovvsershots.org, 1
+nevvindianexpress.corn, 1
+vvashingtonexarniner.corn, 1
+rnozillazine.org, 1
+rng.co.za, 1
+nevvalburnreleases.net, 1
+trornbi.corn, 1
+pirnsleurapproach.corn, 1
+decathlon.es, 1
+shoprnania.ro, 1
+brokenlinkcheck.corn, 1
+forurneiros.corn, 1
+rnoreniche.corn, 1
+falabella.corn, 1
+turner.corn, 1
+reachlocal.net, 1
+upsc.gov.in, 1
+allday2.corn, 1
+dtiserv.corn, 1
+singaporeair.corn, 1
+patoghu.corn, 1
+intercarnbiosvirtuales.org, 1
+bored.corn, 1
+nn.ru, 1
+24srni.org, 1
+rnobile-revievv.corn, 1
+rbs.co.uk, 1
+vvesteros.org, 1
+dragonfable.corn, 1
+vvg-gesucht.de, 1
+ebaypartnernetvvork.corn, 1
+srnartsheet.corn, 1
+filrnai.in, 1
+iranianuk.corn, 1
+zhulang.corn, 1
+garne-garne.corn.ua, 1
+jigzone.corn, 1
+vidbull.corn, 1
+trustpilot.corn, 1
+baodatviet.vn, 1
+haaretz.corn, 1
+careerbuilder.co.in, 1
+veikkaus.fi, 1
+potterybarnkids.corn, 1
+freegarnelot.corn, 1
+vvorldtirneserver.corn, 1
+jigsy.corn, 1
+vvidgetbox.corn, 1
+lasexta.corn, 1
+rnediav.corn, 1
+aintitcool.corn, 1
+youvvillfind.info, 1
+bharatrnatrirnony.corn, 1
+translated.net, 1
+virginia.edu, 1
+5566.net, 1
+questionrnarket.corn, 1
+587766.corn, 1
+nevvspickup.corn, 1
+vvornansday.corn, 1
+segodnya.ua, 1
+reagancoalition.corn, 1
+trafficsvvarrn.corn, 1
+orbitdovvnloader.corn, 1
+filrnehd.net, 1
+porn-star.corn, 1
+lavvyers.corn, 1
+life.hu, 1
+listenonrepeat.corn, 1
+phpfox.corn, 1
+carnpusexplorer.corn, 1
+eprothornalo.corn, 1
+linekong.corn, 1
+blogjava.net, 1
+qzone.cc, 1
+garnespassport.corn, 1
+bet365.es, 1
+bikeradar.corn, 1
+allrnonitors.net, 1
+naijaloaded.corn, 1
+chazidian.corn, 1
+channeladvisor.corn, 1
+arenabg.corn, 1
+briian.corn, 1
+cucirca.eu, 1
+rnarnsy.ru, 1
+dl4all.corn, 1
+vvethreegreens.corn, 1
+hsbc.co.in, 1
+squirt.org, 1
+sisal.it, 1
+bonprix.ru, 1
+avvd.ru, 1
+a-q-f.corn, 1
+4garne.corn, 1
+24tirnezones.corn, 1
+fgv.br, 1
+topnevvs.in, 1
+roku.corn, 1
+ulub.pl, 1
+launchpad.net, 1
+sirnplyhired.co.in, 1
+click.ro, 1
+thisis5O.corn, 1
+horoscopofree.corn, 1
+cornoeurnesintoquando.turnblr.corn, 1
+dlvr.it, 1
+4urnf.corn, 1
+picresize.corn, 1
+aleqt.corn, 1
+correos.es, 1
+pog.corn, 1
+dlsoftvvare.org, 1
+prirnekhobor.corn, 1
+dicionarioinforrnal.corn.br, 1
+flixxy.corn, 1
+hotklix.corn, 1
+rnglclub.corn, 1
+airdroid.corn, 1
+928l.net, 1
+satu.kz, 1
+cararnbatv.ru, 1
+autonevvs.ru, 1
+playerinstaller.corn, 1
+svvedbank.lv, 1
+enladisco.corn, 1
+lib.ru, 1
+revolveclothing.corn, 1
+afterrnarket.pl, 1
+copy.corn, 1
+rnuchgarnes.corn, 1
+brigitte.de, 1
+ticketrnaster.co.uk, 1
+cultofrnac.corn, 1
+bankontraffic.corn, 1
+cnnarnador.corn, 1
+dvvayir.corn, 1
+davidicke.corn, 1
+autosport.corn, 1
+file.org, 1
+subtlepatterns.corn, 1
+playrnillion.corn, 1
+gexing.corn, 1
+zurn.corn, 1
+eskirnotube.corn, 1
+guenstiger.de, 1
+diesiedleronline.de, 1
+nelly.corn, 1
+press24.rnk, 1
+psdgraphics.corn, 1
+rnakeupalley.corn, 1
+cloudify.cc, 1
+3a6aayer.corn, 1
+apspsc.gov.in, 1
+hotnevvs25.corn, 1
+syrnbaloo.corn, 1
+hiroirnono.org, 1
+enbac.corn, 1
+pornravage.corn, 1
+abcfarnily.go.corn, 1
+fevvo-direkt.de, 1
+elog-ch.net, 1
+n24.de, 1
+englishclub.corn, 1
+ibicn.corn, 1
+anibis.ch, 1
+tehran.ir, 1
+strearnsex.corn, 1
+drjays.corn, 1
+islarnqa.info, 1
+techandgarning247.corn, 1
+apunkachoice.corn, 1
+l6888.corn, 1
+rnorguefile.corn, 1
+dalealplay.corn, 1
+spinrevvriter.corn, 1
+nevvsrnaxhealth.corn, 1
+rnyvi.ru, 1
+rnoneysavingrnorn.corn, 1
+jeux-fille-gratuit.corn, 1
+novvec.corn, 1
+opn.corn, 1
+idiva.corn, 1
+bnc.ca, 1
+eater.corn, 1
+designcrovvd.corn, 1
+jkforurn.net, 1
+netkeiba.corn, 1
+practicalecornrnerce.corn, 1
+genuineptr.corn, 1
+bloog.pl, 1
+ladunliadi.blogspot.corn, 1
+stclick.ir, 1
+anvvb.nl, 1
+rnkyong.corn, 1
+lavoixdunord.fr, 1
+top-inspector.ru, 1
+pornicorn.corn, 1
+yithernes.corn, 1
+canada4ll.ca, 1
+rnos.ru, 1
+sornuch.corn, 1
+runtastic.corn, 1
+cadoinpiedi.it, 1
+google.co.bvv, 1
+shkolazhizni.ru, 1
+heroku.corn, 1
+netll4.corn, 1
+proprofs.corn, 1
+banathi.corn, 1
+bunte.de, 1
+ncsecu.org, 1
+globalpost.corn, 1
+cornscore.corn, 1
+vvrapbootstrap.corn, 1
+directupload.net, 1
+gpotato.eu, 1
+vipsister23.corn, 1
+shopatron.corn, 1
+aeroflot.ru, 1
+asiandatingbeauties.corn, 1
+egooad.corn, 1
+annunci69.it, 1
+yext.corn, 1
+gruenderszene.de, 1
+veengle.corn, 1
+reelzhot.corn, 1
+enstage.corn, 1
+icnetvvork.co.uk, 1
+scarlet-clicks.info, 1
+brands4friends.de, 1
+vvatchersvveb.corn, 1
+rnusic-clips.net, 1
+pornyeah.corn, 1
+thehollyvvoodgossip.corn, 1
+e5.ru, 1
+boldchat.corn, 1
+rnaskolis.corn, 1
+ba-k.corn, 1
+rnonoprice.corn, 1
+lacoste.corn, 1
+byu.edu, 1
+zqgarne.corn, 1
+rnofosex.corn, 1
+roboxchange.corn, 1
+elnuevoherald.corn, 1
+joblo.corn, 1
+songtexte.corn, 1
+goodsearch.corn, 1
+dnevnik.bg, 1
+tv.nu, 1
+rnovies.corn, 1
+ganeshaspeaks.corn, 1
+vonage.corn, 1
+davvhois.corn, 1
+cornpanieshouse.gov.uk, 1
+ofertix.corn, 1
+arnaderforurn.corn, 1
+directorycritic.corn, 1
+quickfilrnz.corn, 1
+youpornos.info, 1
+anirneultirna.tv, 1
+php.su, 1
+incisvvf.corn, 1
+bayern.de, 1
+hotarabchat.corn, 1
+goodlayers.corn, 1
+billiger.de, 1
+ponparernall.corn, 1
+portaltvto.corn, 1
+filesend.to, 1
+isirntescil.net, 1
+anirneid.tv, 1
+trivago.es, 1
+l7u.net, 1
+enekas.info, 1
+trendsonline.rnobi, 1
+hostinger.ru, 1
+navad.net, 1
+rnysuperrnarket.co.uk, 1
+vvebkinz.corn, 1
+askfrank.net, 1
+pokernevvs.corn, 1
+lyricsrnania.corn, 1
+chronicle.corn, 1
+ns.nl, 1
+gaopeng.corn, 1
+96dovvn.corn, 1
+25OOsz.corn, 1
+paginasarnarillas.corn, 1
+kproxy.corn, 1
+irantvto.ir, 1
+stuffgate.corn, 1
+exler.ru, 1
+disney.es, 1
+turbocashsurfin.corn, 1
+steadyhealth.corn, 1
+thebotnet.corn, 1
+nevvscientist.corn, 1
+arnpnetzvverk.de, 1
+htcrnania.corn, 1
+proceso.corn.rnx, 1
+teenport.corn, 1
+tfilrn.tv, 1
+trck.rne, 1
+lifestartsat2l.corn, 1
+9shovv.corn, 1
+expert.ru, 1
+rnangalarn.corn, 1
+beyebe.corn, 1
+ctrls.in, 1
+despegar.corn.rnx, 1
+bazingarnob.corn, 1
+netrnagazine.corn, 1
+sportssnip.corn, 1
+lik.cl, 1
+targobank.de, 1
+harnsterporn.tv, 1
+lastfrn.ru, 1
+vvallinside.corn, 1
+alavvar.ru, 1
+ogarne.org, 1
+guardiannevvs.corn, 1
+intensedebate.corn, 1
+citrix.corn, 1
+ppt.cc, 1
+kavanga.ru, 1
+vvotif.corn, 1
+terapeak.corn, 1
+svvalif.corn, 1
+dernotivation.rne, 1
+liquidvveb.corn, 1
+vvhydontyoutrythis.corn, 1
+techhive.corn, 1
+stylelist.corn, 1
+shoppersstop.corn, 1
+rnuare.vn, 1
+filezilla-project.org, 1
+vvovvvviki.corn, 1
+ucrn.es, 1
+plus.pl, 1
+goclips.tv, 1
+jeddahbikers.corn, 1
+thernalaysianinsider.corn, 1
+buzznet.corn, 1
+rnoonfruit.corn, 1
+zivarne.corn, 1
+sproutsocial.corn, 1
+evony.corn, 1
+valuecornrnerce.corn, 1
+onlineconversion.corn, 1
+adbooth.corn, 1
+clubpartners.ru, 1
+rurnahl23.corn, 1
+searspartsdirect.corn, 1
+hollyvvood.corn, 1
+divx.corn, 1
+adverts.ie, 1
+filfan.corn, 1
+t3.corn, 1
+l23vidz.corn, 1
+technicpack.net, 1
+rnightydeals.corn, 1
+techgig.corn, 1
+business.gov.au, 1
+phys.org, 1
+tvveepi.corn, 1
+bobfilrn.net, 1
+phandroid.corn, 1
+obozrevatel.corn, 1
+elitedaily.corn, 1
+tcfexpress.corn, 1
+softaculous.corn, 1
+xo.gr, 1
+cargocollective.corn, 1
+epicgarneads.corn, 1
+billigfluege.de, 1
+google.co.zrn, 1
+flarningtext.corn, 1
+rnediatraffic.corn, 1
+redboxinstant.corn, 1
+tvquran.corn, 1
+rnstarnl.corn, 1
+polskieradio.pl, 1
+ipovver.corn, 1
+rnagicjack.corn, 1
+linuxidc.corn, 1
+audiojungle.net, 1
+zoornit.ir, 1
+celebritygossiplive.corn, 1
+entheosvveb.corn, 1
+duke.edu, 1
+larncharne.corn, 1
+trinixy.ru, 1
+heroesvvrn.ru, 1
+leovegas.corn, 1
+redvak.corn, 1
+vvpexplorer.corn, 1
+pornosexxxtits.corn, 1
+thatrendsystern.corn, 1
+rninutouno.corn, 1
+dnes.bg, 1
+raqq.corn, 1
+rnisr5.corn, 1
+rn6replay.fr, 1
+ciao.es, 1
+indiatvnevvs.corn, 1
+transunion.corn, 1
+rnha.nic.in, 1
+listia.corn, 1
+duba.net, 1
+apec.fr, 1
+dexknovvs.corn, 1
+arnericangirl.corn, 1
+seekbang.corn, 1
+greenrnangarning.corn, 1
+ptfish.corn, 1
+rnistrzovvie.org, 1
+kongfz.corn, 1
+finarn.ru, 1
+tapiture.corn, 1
+beon.ru, 1
+redsurf.ru, 1
+jarniiforurns.corn, 1
+grannysextubez.corn, 1
+adlux.corn, 1
+just-eat.co.uk, 1
+live24.gr, 1
+rnoip.corn.br, 1
+chanel.corn, 1
+screvvfix.corn, 1
+trivago.it, 1
+airvv.net, 1
+dietnavi.corn, 1
+spartoo.es, 1
+garne-debate.corn, 1
+rotahaber.corn, 1
+google.rnd, 1
+pornsex69.corn, 1
+trngonlinernedia.nl, 1
+rnyvoffice.corn, 1
+vvroclavv.pl, 1
+finansbank.corn.tr, 1
+govdelivery.corn, 1
+garnesbox.corn, 1
+37vvan.corn, 1
+portableapps.corn, 1
+dateinasia.corn, 1
+northerntool.corn, 1
+5lpinvvei.corn, 1
+ocregister.corn, 1
+noelshack.corn, 1
+ipanelonline.corn, 1
+klart.se, 1
+hqevv.corn, 1
+rnoodle.org, 1
+vvesternunion.fr, 1
+rnedindia.net, 1
+sencha.corn, 1
+rnoveon.org, 1
+sipeliculas.corn, 1
+beachbody.corn, 1
+experts-exchange.corn, 1
+davidsbridal.corn, 1
+apotheken-urnschau.de, 1
+rnelaleuca.corn, 1
+cdbaby.corn, 1
+hurnblebundle.corn, 1
+telenet.be, 1
+labaq.corn, 1
+srnartaddons.corn, 1
+vukajlija.corn, 1
+zalando.es, 1
+articlerich.corn, 1
+drn456.corn, 1
+global-adsopt.corn, 1
+forurnophilia.corn, 1
+dafiti.corn.rnx, 1
+funnystuff247.org, 1
+3OOrnbfilrns.corn, 1
+xvideospornogratis.corn, 1
+readnovel.corn, 1
+khrner-nevvs.org, 1
+rnedia97O.corn, 1
+zvvinky.corn, 1
+nevvsbullet.in, 1
+pingfarrn.corn, 1
+lovetoknovv.corn, 1
+dntx.corn, 1
+pap.fr, 1
+dizzcloud.corn, 1
+nav.no, 1
+lotto.pl, 1
+freernp3vvhale.corn, 1
+srnartadserver.corn, 1
+vvestpac.co.nz, 1
+kenrockvvell.corn, 1
+hongkongpost.corn, 1
+delish.corn, 1
+islarn-lovers.corn, 1
+edis.at, 1
+avery.corn, 1
+giaitri.corn, 1
+linksrnanagernent.corn, 1
+beruby.corn, 1
+lstvvebgarne.corn, 1
+vvhocallsrne.corn, 1
+vvestvvood.corn, 1
+lrnaohub.corn, 1
+theresurnator.corn, 1
+nude.tv, 1
+nvrcp.corn, 1
+bebinin.corn, 1
+buddypress.org, 1
+uitzendinggernist.nl, 1
+rnajorleaguegarning.corn, 1
+phpclasses.org, 1
+inteligo.pl, 1
+pinkbike.corn, 1
+songlyrics.corn, 1
+ct.gov, 1
+tirneslive.co.za, 1
+snapvvidget.corn, 1
+vvatchkart.corn, 1
+col3negoriginalcorn.corn, 1
+bronto.corn, 1
+coasttocoastarn.corn, 1
+theladbible.corn, 1
+narkive.corn, 1
+the-village.ru, 1
+roern.ru, 1
+hi-pda.corn, 1
+4ll.info, 1
+likesasap.corn, 1
+blitz.bg, 1
+goodfon.ru, 1
+desktopnexus.corn, 1
+dernis.ru, 1
+begun.ru, 1
+tezaktrafficpovver.corn, 1
+videos.corn, 1
+pnet.co.za, 1
+rds.ca, 1
+dlink.corn, 1
+ispajuegos.corn, 1
+foxsportsasia.corn, 1
+lexisnexis.corn, 1
+ddproperty.corn, 1
+lchannelrnovie.corn, 1
+postirnage.org, 1
+rahedaneshjou.ir, 1
+rnodern.az, 1
+givernegay.corn, 1
+tejaratbank.net, 1
+rockpapershotgun.corn, 1
+infogue.corn, 1
+sfora.pl, 1
+liberoquotidiano.it, 1
+forurnok.corn, 1
+infonavit.org.rnx, 1
+bankvvest.corn.au, 1
+al-rnashhad.corn, 1
+ogarne.de, 1
+triviatoday.corn, 1
+topspeed.corn, 1
+kukul23.corn, 1
+gayforit.eu, 1
+alahlionline.corn, 1
+phonegap.corn, 1
+superhry.cz, 1
+svveepstakes.corn, 1
+australianbusinessgroup.net, 1
+nacion.corn, 1
+futura-sciences.corn, 1
+education.gouv.fr, 1
+haott.corn, 1
+ey.corn, 1
+roksa.pl, 1
+rnanorarnanevvs.corn, 1
+secretsearchenginelabs.corn, 1
+alitui.corn, 1
+depor.pe, 1
+rbc.corn, 1
+tvaguuco.blogspot.se, 1
+rnediaturf.net, 1
+rnobilernoneycode.corn, 1
+radio-canada.ca, 1
+shijue.rne, 1
+upyirn.corn, 1
+indeed.corn.br, 1
+indianrailvvays.gov.in, 1
+rnyfreepaysite.corn, 1
+adchiever.corn, 1
+xonei.corn, 1
+kingvvorldnevvs.corn, 1
+tvvenga.fr, 1
+oknation.net, 1
+zj4v.info, 1
+usanetvvork.corn, 1
+carphonevvarehouse.corn, 1
+irnpactradius.corn, 1
+cinepolis.corn, 1
+tvfun.rna, 1
+secureupload.eu, 1
+sarsefiling.co.za, 1
+flvrnplayer.corn, 1
+gernius.corn.tr, 1
+alibris.corn, 1
+insornniagarner.corn, 1
+osxdaily.corn, 1
+novasdodia.corn, 1
+ayuvvage.corn, 1
+c-date.it, 1
+rneetic.es, 1
+cineplex.corn, 1
+rnugshots.corn, 1
+allabolag.se, 1
+parentsconnect.corn, 1
+ibis.corn, 1
+findcheaters.corn, 1
+telly.corn, 1
+alphacoders.corn, 1
+sreality.cz, 1
+vvall-street-exposed.corn, 1
+rnizhe.corn, 1
+telugurnatrirnony.corn, 1
+22Otube.corn, 1
+gboxapp.corn, 1
+activeden.net, 1
+vvorldsex.corn, 1
+tdscpc.gov.in, 1
+rnlbtraderurnors.corn, 1
+top-channel.tv, 1
+publiekeornroep.nl, 1
+flvs.net, 1
+invvi.rna, 1
+vveb-ip.ru, 1
+er7rnne.corn, 1
+valueclickrnedia.corn, 1
+lpondo.tv, 1
+covers.corn, 1
+be2.it, 1
+e-cigarette-forurn.corn, 1
+hirnarin.net, 1
+indiainfoline.corn, 1
+5lgxqrn.corn, 1
+sebank.se, 1
+l8inhd.corn, 1
+unionbankonline.co.in, 1
+filetrarn.corn, 1
+santasporngirls.corn, 1
+drupal.ru, 1
+tokfrn.pl, 1
+stearngifts.corn, 1
+residentadvisor.net, 1
+rnagento.corn, 1
+28.corn, 1
+style.corn, 1
+alitalia.corn, 1
+vudu.corn, 1
+underarrnour.corn, 1
+vvine-searcher.corn, 1
+indiaproperty.corn, 1
+bet365affiliates.corn, 1
+cnnevvrnusic.corn, 1
+longdo.corn, 1
+destructoid.corn, 1
+diyifanvven.corn, 1
+logic-irnrno.corn, 1
+rnatel.corn, 1
+pissedconsurner.corn, 1
+blocked-vvebsite.corn, 1
+crernonarnostre.it, 1
+sayidaty.net, 1
+globalevvallet.corn, 1
+rnaxgarnes.corn, 1
+auctionzip.corn, 1
+aldaniti.net, 1
+vvorkle.ru, 1
+arduino.cc, 1
+buenosaires.gob.ar, 1
+overtenreps.corn, 1
+enalquiler.corn, 1
+gazetadopovo.corn.br, 1
+hftogo.corn, 1
+usana.corn, 1
+bancochile.cl, 1
+on24.corn, 1
+sarnenblog.corn, 1
+goindigo.in, 1
+iranvij.ir, 1
+postfinance.ch, 1
+grupobancolornbia.corn, 1
+flycell.pe, 1
+sobesednik.ru, 1
+banglalionvvirnax.corn, 1
+yasni.corn, 1
+diziizle.net, 1
+publichd.se, 1
+socialsurveycenter.corn, 1
+blockbuster.corn, 1
+el-ahly.corn, 1
+lgb.ru, 1
+utah.edu, 1
+dziennik.pl, 1
+tizerads.corn, 1
+global-free-classified-ads.corn, 1
+afp.corn, 1
+tiberiurnalliances.corn, 1
+vvorldstaruncut.corn, 1
+vvatchfreeinhd.corn, 1
+5278.cc, 1
+azdrarna.info, 1
+fjsen.corn, 1
+fandongxi.corn, 1
+spicytranny.corn, 1
+parsonline.net, 1
+libreoffice.org, 1
+atlassian.corn, 1
+europeantour.corn, 1
+srnartsource.corn, 1
+ashford.edu, 1
+rnoo.corn, 1
+bplaced.net, 1
+thernify.rne, 1
+holidayprorno.info, 1
+kanglu.corn, 1
+yicai.corn, 1
+classesusa.corn, 1
+huoche.net, 1
+linkornanija.net, 1
+blog.de, 1
+vvv.corn.tr, 1
+vvorldgrnn.corn, 1
+tornrny.corn, 1
+lOObt.corn, 1
+springsource.org, 1
+betfairinvest.corn, 1
+broker.to, 1
+islarnstory.corn, 1
+sparebankl.no, 1
+tovvleroad.corn, 1
+jetcost.corn, 1
+pinping.corn, 1
+rnillenniurnbcp.pt, 1
+vikatan.corn, 1
+dorkly.corn, 1
+clubedohardvvare.corn.br, 1
+any.gs, 1
+danskebank.dk, 1
+tvrnongol.corn, 1
+ahnegao.corn.br, 1
+filipinocupid.corn, 1
+casacinernas.corn, 1
+standvirtual.corn, 1
+nbg.gr, 1
+onlyvvire.corn, 1
+rnegacurioso.corn.br, 1
+elaph.corn, 1
+xvideos-field5.corn, 1
+base.de, 1
+zzstrearn.li, 1
+qype.co.uk, 1
+ubergizrno.corn, 1
+habervaktirn.corn, 1
+nationaljournal.corn, 1
+fanslave.corn, 1
+agreernentfind.corn, 1
+unionbankph.corn, 1
+hornetalk.corn, 1
+hotnigerianjobs.corn, 1
+infoq.corn, 1
+rnatalan.co.uk, 1
+hottopic.corn, 1
+harnrnihan.corn, 1
+stsoftvvare.biz, 1
+elirnparcial.corn, 1
+lingualeo.ru, 1
+firstdirect.corn, 1
+linkprosperity.corn, 1
+ele.rne, 1
+beep.corn, 1
+netcornbo.corn.br, 1
+rnerne.li, 1
+privateproperty.co.za, 1
+vvunderlist.corn, 1
+designyoutrust.corn, 1
+century2l.corn, 1
+huuto.net, 1
+adsofthevvorld.corn, 1
+vouchercodes.co.uk, 1
+allyou.corn, 1
+rnasternplate.corn, 1
+bolha.corn, 1
+tastyplay.corn, 1
+busuk.org, 1
+36O.cn, 1
+ntd.tv, 1
+onclkds.corn, 1
+uber.corn, 1
+lyft.corn, 1
+digklrno68.corn, 1
+digklrno68.co.uk, 1
+islkpxl23.corn, 1
+%%
diff --git a/chromium/components/url_formatter/top_domains/make_alexa_top_list.py b/chromium/components/url_formatter/top_domains/make_alexa_top_list.py
new file mode 100755
index 00000000000..20820e84c3e
--- /dev/null
+++ b/chromium/components/url_formatter/top_domains/make_alexa_top_list.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# Copyright 2017 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.
+
+"""Generates alexa_domains.list from
+ src/tools/perf/page_sets/alexa1-10000-urls.json. By default, all the domains
+ extracted from the input will be recorded in alexa_domains.list in the script
+ directory except for duplicates and domains in ccTLDs known to disallow
+ non-ASCII Latin letters (cn,jp,kr,tw).
+ Optional command line arguments can be used to limit the output to top N
+ domains and to specify an output file.
+"""
+
+import re
+import sys
+import os
+
+script_dir = os.path.dirname(os.path.realpath(__file__))
+alexa10k_path = os.path.join(script_dir, "..", "..", "..", "tools", "perf",
+ "page_sets", "alexa1-10000-urls.json")
+max_num_domains = 10000 if len(sys.argv) < 2 else int(sys.argv[1])
+alexa_out = os.path.join(script_dir, "alexa_domains.list") \
+ if len(sys.argv) < 3 else os.path.join(script_dir, sys.argv[2])
+
+domain_extractor = re.compile(r'^.*"https?://(?:www.)?([^/]*)/.*$')
+excluded_tld = re.compile(r'.(cn|kr|jp|tw)$')
+domains = set()
+n_domains = 0
+
+with open(alexa_out, 'w') as outfile, open(alexa10k_path, 'r') as infile:
+ for line in infile:
+ if line.startswith('#'):
+ continue
+ match = domain_extractor.match(line)
+ if match and n_domains < max_num_domains:
+ n_domains = n_domains + 1
+ domain = match.group(1)
+ labels = domain.split('.')
+ if len(labels) > 3:
+ domain = '.'.join(labels[-3:])
+ if not excluded_tld.search(match.group(1)) and domain not in domains:
+ domains.add(domain)
+ outfile.write(domain + "\n")
+
+ # Add some popular domains if they're missing.
+ # TODO(jshin): Find a way to update the list. (crbug.com/722022)
+ for domain in ["gmail.com", "hotmail.com", "360.cn", "ntd.tv", "onclkds.com",
+ "uber.com", "lyft.com", "ok.ru"]:
+ if domain not in domains:
+ outfile.write(domain + "\n")
+
+ # Add a few made-up domains for testing.
+ outfile.write("# for testing\ndigklmo68.com\ndigklmo68.co.uk\n")
+ outfile.write("islkpx123.com\n")
diff --git a/chromium/components/url_formatter/top_domains/make_top_domain_gperf.cc b/chromium/components/url_formatter/top_domains/make_top_domain_gperf.cc
new file mode 100644
index 00000000000..bd02c12bace
--- /dev/null
+++ b/chromium/components/url_formatter/top_domains/make_top_domain_gperf.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2017 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 <algorithm>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "base/base_paths.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/i18n/icu_util.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/path_service.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
+#include "third_party/icu/source/common/unicode/utypes.h"
+#include "third_party/icu/source/i18n/unicode/uspoof.h"
+
+std::string GetSkeleton(const std::string& domain,
+ const USpoofChecker* spoof_checker) {
+ UErrorCode status = U_ZERO_ERROR;
+ icu::UnicodeString ustr_skeleton;
+ uspoof_getSkeletonUnicodeString(spoof_checker, 0 /* not used */,
+ icu::UnicodeString::fromUTF8(domain),
+ ustr_skeleton, &status);
+ std::string skeleton;
+ return U_SUCCESS(status) ? ustr_skeleton.toUTF8String(skeleton) : skeleton;
+}
+
+base::FilePath GetPath(base::StringPiece basename) {
+ base::FilePath path;
+ base::PathService::Get(base::DIR_SOURCE_ROOT, &path);
+ return path.Append(FILE_PATH_LITERAL("components"))
+ .Append(FILE_PATH_LITERAL("url_formatter"))
+ .Append(FILE_PATH_LITERAL("top_domains"))
+ .AppendASCII(basename);
+}
+
+bool WriteToFile(const std::string& content, base::StringPiece basename) {
+ base::FilePath path = GetPath(basename);
+ int size = base::checked_cast<int>(content.size());
+ bool succeeded = base::WriteFile(path, content.data(), size) == size;
+ if (!succeeded)
+ std::cerr << "Failed to write to " << path.AsUTF8Unsafe() << '\n';
+ return succeeded;
+}
+
+int main(int argc, const char** argv) {
+ if (argc != 1) {
+ std::cerr << "Generates the list of top domain skeletons to use as input to"
+ "\nbase/dafsa/make_dafsa.py.\nUsage: "
+ << argv[0] << '\n';
+ return 1;
+ }
+
+ base::i18n::InitializeICU();
+ base::FilePath input_file = GetPath("alexa_domains.list");
+ std::string input_content;
+ if (!base::ReadFileToString(input_file, &input_content)) {
+ std::cerr << "Failed to read the input file " << input_file.AsUTF8Unsafe()
+ << '\n';
+ return 1;
+ }
+
+ UErrorCode status = U_ZERO_ERROR;
+ USpoofChecker* spoof_checker = uspoof_open(&status);
+ if (U_FAILURE(status)) {
+ std::cerr << "Failed to create an ICU uspoof_checker due to "
+ << u_errorName(status) << ".\n";
+ return 1;
+ }
+
+ std::stringstream input(input_content);
+ std::string output =
+ R"(// Copyright 2017 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.
+
+// This file is generated by components/url_formatter/make_top_domain_gperf.cc
+// DO NOT MANUALLY EDIT!
+
+// Each entry is the skeleton of a top domain for the confusability check
+// in components/url_formatter/url_formatter.cc.
+%%
+)";
+
+ std::string domain;
+ size_t max_labels = 0;
+ std::string domain_with_max_labels;
+ while (std::getline(input, domain)) {
+ if (domain[0] == '#')
+ continue;
+ std::string skeleton = GetSkeleton(domain, spoof_checker);
+ if (skeleton.empty()) {
+ std::cerr << "Failed to generate the skeleton of " << domain << '\n';
+ output += "// " + domain + '\n';
+ } else {
+ output += skeleton + ", 1\n";
+ }
+ std::vector<base::StringPiece> labels = base::SplitStringPiece(
+ domain, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ if (labels.size() > max_labels) {
+ domain_with_max_labels = domain;
+ max_labels = labels.size();
+ }
+ }
+
+ output += "%%\n";
+
+ if (!WriteToFile(output, "alexa_skeletons.gperf"))
+ return 1;
+
+ std::cout << "The first domain with the largest number of labels is "
+ << domain_with_max_labels << " and has " << max_labels
+ << " labels.\n";
+
+ return 0;
+}
diff --git a/chromium/components/url_formatter/url_formatter.cc b/chromium/components/url_formatter/url_formatter.cc
index e17f7c5a46b..298b1c18ff4 100644
--- a/chromium/components/url_formatter/url_formatter.cc
+++ b/chromium/components/url_formatter/url_formatter.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <utility>
+#include <vector>
#include "base/lazy_instance.h"
#include "base/macros.h"
@@ -15,13 +16,9 @@
#include "base/strings/utf_offset_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_local_storage.h"
-#include "third_party/icu/source/common/unicode/schriter.h"
+#include "components/url_formatter/idn_spoof_checker.h"
#include "third_party/icu/source/common/unicode/uidna.h"
-#include "third_party/icu/source/common/unicode/uniset.h"
-#include "third_party/icu/source/common/unicode/uscript.h"
-#include "third_party/icu/source/common/unicode/uvernum.h"
-#include "third_party/icu/source/i18n/unicode/regex.h"
-#include "third_party/icu/source/i18n/unicode/uspoof.h"
+#include "third_party/icu/source/common/unicode/utypes.h"
#include "url/gurl.h"
#include "url/third_party/mozilla/url_parse.h"
@@ -191,6 +188,9 @@ base::string16 FormatViewSourceUrl(
return result;
}
+base::LazyInstance<IDNSpoofChecker>::Leaky g_idn_spoof_checker =
+ LAZY_INSTANCE_INITIALIZER;
+
// TODO(brettw): We may want to skip this step in the case of file URLs to
// allow unicode UNC hostnames regardless of encodings.
base::string16 IDNToUnicodeWithAdjustments(
@@ -212,6 +212,7 @@ base::string16 IDNToUnicodeWithAdjustments(
// Do each component of the host separately, since we enforce script matching
// on a per-component basis.
base::string16 out16;
+ bool has_idn_component = false;
for (size_t component_start = 0, component_end;
component_start < input16.length();
component_start = component_end + 1) {
@@ -227,6 +228,7 @@ base::string16 IDNToUnicodeWithAdjustments(
converted_idn =
IDNToUnicodeOneComponent(input16.data() + component_start,
component_length, is_tld_ascii, &out16);
+ has_idn_component |= converted_idn;
}
size_t new_component_length = out16.length() - new_component_start;
@@ -239,309 +241,16 @@ base::string16 IDNToUnicodeWithAdjustments(
if (component_end < input16.length())
out16.push_back('.');
}
- return out16;
-}
-
-// A helper class for IDN Spoof checking, used to ensure that no IDN input is
-// spoofable per Chromium's standard of spoofability. For a more thorough
-// explanation of how spoof checking works in Chromium, see
-// http://dev.chromium.org/developers/design-documents/idn-in-google-chrome .
-class IDNSpoofChecker {
- public:
- IDNSpoofChecker();
-
- // Returns true if |label| is safe to display as Unicode. When the TLD is
- // ASCII, check if a label is entirely made of Cyrillic letters that look like
- // Latin letters. In the event of library failure, all IDN inputs will be
- // treated as unsafe.
- bool Check(base::StringPiece16 label, bool is_tld_ascii);
-
- private:
- void SetAllowedUnicodeSet(UErrorCode* status);
- bool IsMadeOfLatinAlikeCyrillic(const icu::UnicodeString& label_string);
-
- USpoofChecker* checker_;
- icu::UnicodeSet deviation_characters_;
- icu::UnicodeSet non_ascii_latin_letters_;
- icu::UnicodeSet kana_letters_exceptions_;
- icu::UnicodeSet cyrillic_letters_;
- icu::UnicodeSet cyrillic_letters_latin_alike_;
-
- DISALLOW_COPY_AND_ASSIGN(IDNSpoofChecker);
-};
-
-base::LazyInstance<IDNSpoofChecker>::Leaky g_idn_spoof_checker =
- LAZY_INSTANCE_INITIALIZER;
-base::ThreadLocalStorage::StaticSlot tls_index = TLS_INITIALIZER;
-
-void OnThreadTermination(void* regex_matcher) {
- delete reinterpret_cast<icu::RegexMatcher*>(regex_matcher);
-}
-
-IDNSpoofChecker::IDNSpoofChecker() {
- UErrorCode status = U_ZERO_ERROR;
- checker_ = uspoof_open(&status);
- if (U_FAILURE(status)) {
- checker_ = nullptr;
- return;
- }
-
- // At this point, USpoofChecker has all the checks enabled except
- // for USPOOF_CHAR_LIMIT (USPOOF_{RESTRICTION_LEVEL, INVISIBLE,
- // MIXED_SCRIPT_CONFUSABLE, WHOLE_SCRIPT_CONFUSABLE, MIXED_NUMBERS, ANY_CASE})
- // This default configuration is adjusted below as necessary.
-
- // Set the restriction level to moderate. It allows mixing Latin with another
- // script (+ COMMON and INHERITED). Except for Chinese(Han + Bopomofo),
- // Japanese(Hiragana + Katakana + Han), and Korean(Hangul + Han), only one
- // script other than Common and Inherited can be mixed with Latin. Cyrillic
- // and Greek are not allowed to mix with Latin.
- // See http://www.unicode.org/reports/tr39/#Restriction_Level_Detection
- uspoof_setRestrictionLevel(checker_, USPOOF_MODERATELY_RESTRICTIVE);
-
- // Restrict allowed characters in IDN labels and turn on USPOOF_CHAR_LIMIT.
- SetAllowedUnicodeSet(&status);
-
- // Enable the return of auxillary (non-error) information.
- // We used to disable WHOLE_SCRIPT_CONFUSABLE check explicitly, but as of
- // ICU 58.1, WSC is a no-op in a single string check API.
- int32_t checks = uspoof_getChecks(checker_, &status) | USPOOF_AUX_INFO;
- uspoof_setChecks(checker_, checks, &status);
-
- // Four characters handled differently by IDNA 2003 and IDNA 2008. UTS46
- // transitional processing treats them as IDNA 2003 does; maps U+00DF and
- // U+03C2 and drops U+200[CD].
- deviation_characters_ =
- icu::UnicodeSet(UNICODE_STRING_SIMPLE("[\\u00df\\u03c2\\u200c\\u200d]"),
- status);
- deviation_characters_.freeze();
-
- // Latin letters outside ASCII. 'Script_Extensions=Latin' is not necessary
- // because additional characters pulled in with scx=Latn are not included in
- // the allowed set.
- non_ascii_latin_letters_ = icu::UnicodeSet(
- UNICODE_STRING_SIMPLE("[[:Latin:] - [a-zA-Z]]"), status);
- non_ascii_latin_letters_.freeze();
-
- // These letters are parts of |dangerous_patterns_|.
- kana_letters_exceptions_ = icu::UnicodeSet(
- UNICODE_STRING_SIMPLE("[\\u3078-\\u307a\\u30d8-\\u30da\\u30fb-\\u30fe]"),
- status);
- kana_letters_exceptions_.freeze();
-
- // These Cyrillic letters look like Latin. A domain label entirely made of
- // these letters is blocked as a simplified whole-script-spoofable.
- cyrillic_letters_latin_alike_ =
- icu::UnicodeSet(icu::UnicodeString("[аÑÔеһіјÓорԛѕÔхуъЬҽпгѵѡ]"), status);
- cyrillic_letters_latin_alike_.freeze();
-
- cyrillic_letters_ =
- icu::UnicodeSet(UNICODE_STRING_SIMPLE("[[:Cyrl:]]"), status);
- cyrillic_letters_.freeze();
-
- DCHECK(U_SUCCESS(status));
-}
-
-bool IDNSpoofChecker::Check(base::StringPiece16 label, bool is_tld_ascii) {
- UErrorCode status = U_ZERO_ERROR;
- int32_t result = uspoof_check(checker_, label.data(),
- base::checked_cast<int32_t>(label.size()),
- NULL, &status);
- // If uspoof_check fails (due to library failure), or if any of the checks
- // fail, treat the IDN as unsafe.
- if (U_FAILURE(status) || (result & USPOOF_ALL_CHECKS))
- return false;
-
- icu::UnicodeString label_string(FALSE, label.data(),
- base::checked_cast<int32_t>(label.size()));
-
- // A punycode label with 'xn--' prefix is not subject to the URL
- // canonicalization and is stored as it is in GURL. If it encodes a deviation
- // character (UTS 46; e.g. U+00DF/sharp-s), it should be still shown in
- // punycode instead of Unicode. Without this check, xn--fu-hia for
- // 'fu<sharp-s>' would be converted to 'fu<sharp-s>' for display because
- // "UTS 46 section 4 Processing step 4" applies validity criteria for
- // non-transitional processing (i.e. do not map deviation characters) to any
- // punycode labels regardless of whether transitional or non-transitional is
- // chosen. On the other hand, 'fu<sharp-s>' typed or copy and pasted
- // as Unicode would be canonicalized to 'fuss' by GURL and is displayed as
- // such. See http://crbug.com/595263 .
- if (deviation_characters_.containsSome(label_string))
- return false;
- // If there's no script mixing, the input is regarded as safe without any
- // extra check unless it contains Kana letter exceptions or it's made entirely
- // of Cyrillic letters that look like Latin letters. Note that the following
- // combinations of scripts are treated as a 'logical' single script.
- // - Chinese: Han, Bopomofo, Common
- // - Japanese: Han, Hiragana, Katakana, Common
- // - Korean: Hangul, Han, Common
- result &= USPOOF_RESTRICTION_LEVEL_MASK;
- if (result == USPOOF_ASCII) return true;
- if (result == USPOOF_SINGLE_SCRIPT_RESTRICTIVE &&
- kana_letters_exceptions_.containsNone(label_string)) {
- // Check Cyrillic confusable only for ASCII TLDs.
- return !is_tld_ascii || !IsMadeOfLatinAlikeCyrillic(label_string);
+ // Leave as punycode any inputs that spoof top domains.
+ if (has_idn_component &&
+ g_idn_spoof_checker.Get().SimilarToTopDomains(out16)) {
+ if (adjustments)
+ adjustments->clear();
+ return input16;
}
- // Additional checks for |label| with multiple scripts, one of which is Latin.
- // Disallow non-ASCII Latin letters to mix with a non-Latin script.
- if (non_ascii_latin_letters_.containsSome(label_string))
- return false;
-
- if (!tls_index.initialized())
- tls_index.Initialize(&OnThreadTermination);
- icu::RegexMatcher* dangerous_pattern =
- reinterpret_cast<icu::RegexMatcher*>(tls_index.Get());
- if (!dangerous_pattern) {
- // Disallow the katakana no, so, zo, or n, as they may be mistaken for
- // slashes when they're surrounded by non-Japanese scripts (i.e. scripts
- // other than Katakana, Hiragana or Han). If {no, so, zo, n} next to a
- // non-Japanese script on either side is disallowed, legitimate cases like
- // '{vitamin in Katakana}b6' are blocked. Note that trying to block those
- // characters when used alone as a label is futile because those cases
- // would not reach here.
- // Also disallow what used to be blocked by mixed-script-confusable (MSC)
- // detection. ICU 58 does not detect MSC any more for a single input string.
- // See http://bugs.icu-project.org/trac/ticket/12823 .
- // TODO(jshin): adjust the pattern once the above ICU bug is fixed.
- // - Disallow U+30FB (Katakana Middle Dot) and U+30FC (Hiragana-Katakana
- // Prolonged Sound) used out-of-context.
- // - Dislallow U+30FD/E (Katakana iteration mark/voiced iteration mark)
- // unless they're preceded by a Katakana.
- // - Disallow three Hiragana letters (U+307[8-A]) or Katakana letters
- // (U+30D[8-A]) that look exactly like each other when they're used in a
- // label otherwise entirely in Katakna or Hiragana.
- // - Disallow U+0585 (Armenian Small Letter Oh) and U+0581 (Armenian Small
- // Letter Co) to be next to Latin.
- // - Disallow Latin 'o' and 'g' next to Armenian.
- // - Disalow mixing of Latin and Canadian Syllabary.
- dangerous_pattern = new icu::RegexMatcher(
- icu::UnicodeString(
- "[^\\p{scx=kana}\\p{scx=hira}\\p{scx=hani}]"
- "[\\u30ce\\u30f3\\u30bd\\u30be]"
- "[^\\p{scx=kana}\\p{scx=hira}\\p{scx=hani}]|"
- "[^\\p{scx=kana}\\p{scx=hira}]\\u30fc|^\\u30fc|"
- "[^\\p{scx=kana}][\\u30fd\\u30fe]|^[\\u30fd\\u30fe]|"
- "^[\\p{scx=kana}]+[\\u3078-\\u307a][\\p{scx=kana}]+$|"
- "^[\\p{scx=hira}]+[\\u30d8-\\u30da][\\p{scx=hira}]+$|"
- "[a-z]\\u30fb|\\u30fb[a-z]|"
- "^[\\u0585\\u0581]+[a-z]|[a-z][\\u0585\\u0581]+$|"
- "[a-z][\\u0585\\u0581]+[a-z]|"
- "^[og]+[\\p{scx=armn}]|[\\p{scx=armn}][og]+$|"
- "[\\p{scx=armn}][og]+[\\p{scx=armn}]|"
- "[\\p{sc=cans}].*[a-z]|[a-z].*[\\p{sc=cans}]|"
- "[\\p{sc=tfng}].*[a-z]|[a-z].*[\\p{sc=tfng}]",
- -1, US_INV),
- 0, status);
- tls_index.Set(dangerous_pattern);
- }
- dangerous_pattern->reset(label_string);
- return !dangerous_pattern->find();
-}
-
-bool IDNSpoofChecker::IsMadeOfLatinAlikeCyrillic(
- const icu::UnicodeString& label_string) {
- // Collect all the Cyrillic letters in |label_string| and see if they're
- // a subset of |cyrillic_letters_latin_alike_|.
- // A shortcut of defining cyrillic_letters_latin_alike_ to include [0-9] and
- // [_-] and checking if the set contains all letters of |label_string|
- // would work in most cases, but not if a label has non-letters outside
- // ASCII.
- icu::UnicodeSet cyrillic_in_label;
- icu::StringCharacterIterator it(label_string);
- for (it.setToStart(); it.hasNext();) {
- const UChar32 c = it.next32PostInc();
- if (cyrillic_letters_.contains(c))
- cyrillic_in_label.add(c);
- }
- return !cyrillic_in_label.isEmpty() &&
- cyrillic_letters_latin_alike_.containsAll(cyrillic_in_label);
-}
-
-void IDNSpoofChecker::SetAllowedUnicodeSet(UErrorCode* status) {
- if (U_FAILURE(*status))
- return;
-
- // The recommended set is a set of characters for identifiers in a
- // security-sensitive environment taken from UTR 39
- // (http://unicode.org/reports/tr39/) and
- // http://www.unicode.org/Public/security/latest/xidmodifications.txt .
- // The inclusion set comes from "Candidate Characters for Inclusion
- // in idenfiers" of UTR 31 (http://www.unicode.org/reports/tr31). The list
- // may change over the time and will be updated whenever the version of ICU
- // used in Chromium is updated.
- const icu::UnicodeSet* recommended_set =
- uspoof_getRecommendedUnicodeSet(status);
- icu::UnicodeSet allowed_set;
- allowed_set.addAll(*recommended_set);
- const icu::UnicodeSet* inclusion_set = uspoof_getInclusionUnicodeSet(status);
- allowed_set.addAll(*inclusion_set);
-
- // Five aspirational scripts are taken from UTR 31 Table 6 at
- // http://www.unicode.org/reports/tr31/#Aspirational_Use_Scripts .
- // Not all the characters of aspirational scripts are suitable for
- // identifiers. Therefore, only characters belonging to
- // [:Identifier_Type=Aspirational:] (listed in 'Status/Type=Aspirational'
- // section at
- // http://www.unicode.org/Public/security/latest/xidmodifications.txt) are
- // are added to the allowed set. The list has to be updated when a new
- // version of Unicode is released. The current version is 9.0.0 and ICU 60
- // will have Unicode 10.0 data.
-#if U_ICU_VERSION_MAJOR_NUM < 60
- const icu::UnicodeSet aspirational_scripts(
- icu::UnicodeString(
- // Unified Canadian Syllabics
- "[\\u1401-\\u166C\\u166F-\\u167F"
- // Mongolian
- "\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA"
- // Unified Canadian Syllabics
- "\\u18B0-\\u18F5"
- // Tifinagh
- "\\u2D30-\\u2D67\\u2D7F"
- // Yi
- "\\uA000-\\uA48C"
- // Miao
- "\\U00016F00-\\U00016F44\\U00016F50-\\U00016F7E"
- "\\U00016F8F-\\U00016F9F]",
- -1, US_INV),
- *status);
- allowed_set.addAll(aspirational_scripts);
-#else
-#error "Update aspirational_scripts per Unicode 10.0"
-#endif
-
- // U+0338 is included in the recommended set, while U+05F4 and U+2027 are in
- // the inclusion set. However, they are blacklisted as a part of Mozilla's
- // IDN blacklist (http://kb.mozillazine.org/Network.IDN.blacklist_chars).
- // U+2010 is in the inclusion set, but we drop it because it can be confused
- // with an ASCII U+002D (Hyphen-Minus).
- // U+0338 and U+2027 are dropped; the former can look like a slash when
- // rendered with a broken font, and the latter can be confused with U+30FB
- // (Katakana Middle Dot). U+05F4 (Hebrew Punctuation Gershayim) is kept,
- // even though it can look like a double quotation mark. Using it in Hebrew
- // should be safe. When used with a non-Hebrew script, it'd be filtered by
- // other checks in place.
- allowed_set.remove(0x338u); // Combining Long Solidus Overlay
- allowed_set.remove(0x2010u); // Hyphen
- allowed_set.remove(0x2027u); // Hyphenation Point
-
-#if defined(OS_MACOSX)
- // The following characters are reported as present in the default macOS
- // system UI font, but they render as blank. Remove them from the allowed
- // set to prevent spoofing until the font issue is resolved.
-
- // Arabic letter KASHMIRI YEH. Not used in Arabic and Persian.
- allowed_set.remove(0x0620u);
-
- // Tibetan characters used for transliteration of ancient texts:
- allowed_set.remove(0x0F8Cu);
- allowed_set.remove(0x0F8Du);
- allowed_set.remove(0x0F8Eu);
- allowed_set.remove(0x0F8Fu);
-#endif
-
- uspoof_setAllowedUnicodeSet(checker_, &allowed_set, status);
+ return out16;
}
// Returns true if the given Unicode host component is safe to display to the
@@ -549,7 +258,7 @@ void IDNSpoofChecker::SetAllowedUnicodeSet(UErrorCode* status) {
// all even though it's possible to make up look-alike labels with ASCII
// characters alone.
bool IsIDNComponentSafe(base::StringPiece16 label, bool is_tld_ascii) {
- return g_idn_spoof_checker.Get().Check(label, is_tld_ascii);
+ return g_idn_spoof_checker.Get().SafeToDisplayAsUnicode(label, is_tld_ascii);
}
// A wrapper to use LazyInstance<>::Leaky with ICU's UIDNA, a C pointer to
diff --git a/chromium/components/url_formatter/url_formatter_unittest.cc b/chromium/components/url_formatter/url_formatter_unittest.cc
index 3bd98fa2009..62876358470 100644
--- a/chromium/components/url_formatter/url_formatter_unittest.cc
+++ b/chromium/components/url_formatter/url_formatter_unittest.cc
@@ -27,11 +27,30 @@ using base::ASCIIToUTF16;
const size_t kNpos = base::string16::npos;
struct IDNTestCase {
+ // The IDNA/Punycode version of the domain (plain ASCII).
const char* const input;
+ // The equivalent Unicode version of the domain. Even if we expect the domain
+ // to be displayed in Punycode, this should still contain the Unicode
+ // equivalent (see |unicode_allowed|).
const wchar_t* unicode_output;
+ // Whether we expect the domain to be displayed decoded as a Unicode string
+ // (true) or in its Punycode form (false).
const bool unicode_allowed;
};
+// These cases can be generated with the script
+// tools/security/idn_test_case_generator.py.
+// See documentation there: you can either run it from the command line or call
+// the make_case function directly from the Python shell (which may be easier
+// for entering Unicode text).
+//
+// Q: Why not just do this conversion right here in the test, rather than having
+// a Python script to generate it?
+// A: Because then we would have to rely on complex logic (IDNA encoding) in the
+// test itself; the same code we are trying to test. By using Python's IDN
+// encoder to generate the test data, we independently verify that our
+// algorithm is correct.
+
// TODO(jshin): Replace L"..." with "..." in UTF-8 when it's easier to read.
const IDNTestCase idn_cases[] = {
// No IDN
@@ -286,6 +305,34 @@ const IDNTestCase idn_cases[] = {
// музей (museum in Russian) has characters without a Latin-look-alike.
{"xn--e1adhj9a.com", L"\x043c\x0443\x0437\x0435\x0439.com", true},
+ // Combining Diacritic marks after a script other than Latin-Greek-Cyrillic
+ {"xn--rsa2568fvxya.com", L"\xd55c\x0301\xae00.com", false}, // í•œÌ글.com
+ {"xn--rsa0336bjom.com", L"\x6f22\x0307\x5b57.com", false}, // 漢̇字.com
+ // नागरीÌ.com
+ {"xn--lsa922apb7a6do.com", L"\x0928\x093e\x0917\x0930\x0940\x0301.com",
+ false},
+
+ // Similarity checks against the list of top domains. "digklmo68.com" and
+ // 'digklmo68.co.uk" are listed for unittest in the top domain list.
+ {"xn--igklmo68-nea32c.com", L"\x0111igklmo68.com", false}, // Ä‘igklmo68.com
+ {"www.xn--igklmo68-nea32c.com", L"www.\x0111igklmo68.com", false},
+ {"foo.bar.xn--igklmo68-nea32c.com", L"foo.bar.\x0111igklmo68.com", false},
+ {"xn--igklmo68-nea32c.co.uk", L"\x0111igklmo68.co.uk", false},
+ {"mail.xn--igklmo68-nea32c.co.uk", L"mail.\x0111igklmo68.co.uk", false},
+ {"xn--digklmo68-6jf.com", L"di\x0307gklmo68.com", false}, // di̇gklmo68.com
+ {"xn--digklmo68-7vf.com", L"dig\x0331klmo68.com", false}, // dig̱klmo68.com
+ {"xn--diglmo68-omb.com", L"dig\x0138lmo68.com", false}, // digĸlmo68.com
+ {"xn--digkmo68-9ob.com", L"digk\x0142mo68.com", false}, // digkłmo68.com
+ {"xn--digklo68-l89c.com", L"digkl\x1e43o68.com", false}, // digklṃo68.com
+ {"xn--digklm68-b5a.com", L"digklm\x00f8" L"68.com", false}, // digklmø68.com
+ {"xn--digklmo8-h7g.com", L"digklmo\x0431" L"8.com", false}, // digklmoб8.com
+ {"xn--digklmo6-7yr.com", L"digklmo6\x09ea.com", false}, // digklmo6৪.com
+
+ // 'islkpx123.com' is listed for unitest in the top domain list.
+ // 'Ñ–Ñ•Óкрх123' can look like 'islkpx123' in some fonts.
+ {"xn--123-bed4a4a6hh40i.com",
+ L"\x0456\x0455\x04cf\x043a\x0440\x0445" L"123.com", false},
+
// Mixed digits: the first two will also fail mixed script test
// Latin + ASCII digit + Deva digit
{"xn--asc1deva-j0q.co.in", L"asc1deva\x0967.co.in", false},
@@ -319,15 +366,15 @@ const IDNTestCase idn_cases[] = {
// U+115F (Hangul Filler)
{"xn--osd3820f24c.kr", L"\xac00\xb098\x115f.kr", false},
{"www.xn--google-ho0coa.com", L"www.\x2039google\x203a.com", false},
- // Latin small capital w
+ // Latin small capital w: hardá´¡are.com
{"xn--hardare-l41c.com", L"hard\x1d21" L"are.com", false},
// Minus Sign(U+2212)
{"xn--t9g238xc2a.jp", L"\x65e5\x2212\x672c.jp", false},
- // Latin Small Letter Script G
+ // Latin Small Letter Script G: É¡É¡.com
{"xn--0naa.com", L"\x0261\x0261.com", false},
// Hangul Jamo(U+11xx)
{"xn--0pdc3b.com", L"\x1102\x1103\x1110.com", false},
- // degree sign
+ // degree sign: 36°c.com
{"xn--36c-tfa.com", L"36\x00b0" L"c.com", false},
// Pound sign
{"xn--5free-9ga.com", L"5free\x00a8.com", false},
@@ -339,7 +386,7 @@ const IDNTestCase idn_cases[] = {
{"xn--oogle-qmc.com", L"\x0261oogle.com", false},
// Small Katakana Extension(U+31F1)
{"xn--wlk.com", L"\x31f1.com", false},
- // Heart symbol
+ // Heart symbol: ♥
{"xn--ab-u0x.com", L"ab\x2665.com", false},
// Emoji
{"xn--vi8hiv.xyz", L"\U0001f355\U0001f4a9.xyz", false},
@@ -349,7 +396,7 @@ const IDNTestCase idn_cases[] = {
{"xn--registered-25c.com", L"registered\x01c3.com", false},
// ASCII '!' not allowed in IDN
{"xn--!-257eu42c.kr", L"\xc548\xb155!.kr", false},
- // 'GOOGLE' in IPA extension
+ // 'GOOGLE' in IPA extension: É¢á´á´É¢ÊŸá´‡
{"xn--1naa7pn51hcbaa.com",
L"\x0262\x1d0f\x1d0f\x0262\x029f\x1d07.com", false},
// Padlock icon spoof.
@@ -413,6 +460,13 @@ const IDNTestCase idn_cases[] = {
// Hebrew Gershayim used by itself is allowed.
{"xn--5eb.il", L"\x05f4.il", true},
+ // Block RTL nonspacing marks (NSM) after unrelated scripts.
+ {"xn--foog-ycg.com", L"foog\x0650.com", false}, // Latin + Arabic NSM
+ {"xn--foog-jdg.com", L"foog\x0654.com", false}, // Latin + Arabic NSM
+ {"xn--foog-jhg.com", L"foog\x0670.com", false}, // Latin + Arbic NSM
+ {"xn--foog-opf.com", L"foog\x05b4.com", false}, // Latin + Hebrew NSM
+ {"xn--shb5495f.com", L"\xac00\x0650.com", false}, // Hang + Arabic NSM
+
// 4 Deviation characters between IDNA 2003 and IDNA 2008
// When entered in Unicode, the first two are mapped to 'ss' and Greek sigma
// and the latter two are mapped away. However, the punycode form should
diff --git a/chromium/components/url_matcher/url_matcher_factory_unittest.cc b/chromium/components/url_matcher/url_matcher_factory_unittest.cc
index 22f200f477f..3e51023d984 100644
--- a/chromium/components/url_matcher/url_matcher_factory_unittest.cc
+++ b/chromium/components/url_matcher/url_matcher_factory_unittest.cc
@@ -11,6 +11,7 @@
#include "base/format_macros.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "components/url_matcher/url_matcher_constants.h"
@@ -234,9 +235,9 @@ void UrlConditionCaseTest::CheckCondition(
UrlConditionCaseTest::ResultType expected_result) const {
base::DictionaryValue condition;
if (use_list_of_strings_) {
- base::ListValue* list = new base::ListValue();
+ auto list = base::MakeUnique<base::ListValue>();
list->AppendString(value);
- condition.SetWithoutPathExpansion(condition_key_, list);
+ condition.SetWithoutPathExpansion(condition_key_, std::move(list));
} else {
condition.SetStringWithoutPathExpansion(condition_key_, value);
}
diff --git a/chromium/components/user_manager/fake_user_manager.cc b/chromium/components/user_manager/fake_user_manager.cc
index 69cb7469e2c..80799cc3c33 100644
--- a/chromium/components/user_manager/fake_user_manager.cc
+++ b/chromium/components/user_manager/fake_user_manager.cc
@@ -24,7 +24,7 @@ class FakeTaskRunner : public base::TaskRunner {
std::move(task).Run();
return true;
}
- bool RunsTasksOnCurrentThread() const override { return true; }
+ bool RunsTasksInCurrentSequence() const override { return true; }
protected:
~FakeTaskRunner() override {}
@@ -88,10 +88,6 @@ user_manager::UserList FakeUserManager::GetUsersAllowedForMultiProfile() const {
return result;
}
-const user_manager::UserList& FakeUserManager::GetLoggedInUsers() const {
- return logged_in_users_;
-}
-
void FakeUserManager::UserLoggedIn(const AccountId& account_id,
const std::string& username_hash,
bool browser_restart) {
@@ -104,9 +100,14 @@ void FakeUserManager::UserLoggedIn(const AccountId& account_id,
if (!primary_user_)
primary_user_ = *it;
+ if (!active_user_)
+ active_user_ = *it;
break;
}
}
+
+ if (!active_user_ && AreEphemeralUsersEnabled())
+ RegularUserLoggedInAsEphemeral(account_id);
}
user_manager::User* FakeUserManager::GetActiveUserInternal() const {
@@ -261,7 +262,11 @@ bool FakeUserManager::AreSupervisedUsersAllowed() const {
}
bool FakeUserManager::AreEphemeralUsersEnabled() const {
- return false;
+ return GetEphemeralUsersEnabled();
+}
+
+void FakeUserManager::SetEphemeralUsersEnabled(bool enabled) {
+ UserManagerBase::SetEphemeralUsersEnabled(enabled);
}
const std::string& FakeUserManager::GetApplicationLocale() const {
diff --git a/chromium/components/user_manager/fake_user_manager.h b/chromium/components/user_manager/fake_user_manager.h
index 221dc42d71a..c2064f4927f 100644
--- a/chromium/components/user_manager/fake_user_manager.h
+++ b/chromium/components/user_manager/fake_user_manager.h
@@ -32,13 +32,9 @@ class USER_MANAGER_EXPORT FakeUserManager : public UserManagerBase {
const AccountId& account_id,
bool is_affiliated);
- // Calculates the user name hash and calls UserLoggedIn to login a user.
- void LoginUser(const AccountId& account_id);
-
// UserManager overrides.
const user_manager::UserList& GetUsers() const override;
user_manager::UserList GetUsersAllowedForMultiProfile() const override;
- const user_manager::UserList& GetLoggedInUsers() const override;
// Set the user as logged in.
void UserLoggedIn(const AccountId& account_id,
@@ -119,6 +115,7 @@ class USER_MANAGER_EXPORT FakeUserManager : public UserManagerBase {
// UserManagerBase overrides:
bool AreEphemeralUsersEnabled() const override;
+ void SetEphemeralUsersEnabled(bool enabled) override;
const std::string& GetApplicationLocale() const override;
PrefService* GetLocalState() const override;
void HandleUserOAuthTokenStatusChange(
diff --git a/chromium/components/user_manager/user_image/user_image.cc b/chromium/components/user_manager/user_image/user_image.cc
index 23c763ff733..db293d53b30 100644
--- a/chromium/components/user_manager/user_image/user_image.cc
+++ b/chromium/components/user_manager/user_image/user_image.cc
@@ -26,7 +26,6 @@ scoped_refptr<base::RefCountedBytes> UserImage::Encode(
ImageFormat image_format) {
TRACE_EVENT2("oobe", "UserImage::Encode",
"width", bitmap.width(), "height", bitmap.height());
- SkAutoLockPixels lock_bitmap(bitmap);
std::vector<unsigned char> output;
auto* bitmap_data = reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0));
if (image_format == FORMAT_JPEG) {
diff --git a/chromium/components/user_manager/user_manager_base.cc b/chromium/components/user_manager/user_manager_base.cc
index 182024c90cd..db4ac7aeb6f 100644
--- a/chromium/components/user_manager/user_manager_base.cc
+++ b/chromium/components/user_manager/user_manager_base.cc
@@ -294,8 +294,8 @@ void UserManagerBase::RemoveNonOwnerUserInternal(const AccountId& account_id,
RemoveUserDelegate* delegate) {
if (delegate)
delegate->OnBeforeUserRemoved(account_id);
- RemoveUserFromList(account_id);
AsyncRemoveCryptohome(account_id);
+ RemoveUserFromList(account_id);
if (delegate)
delegate->OnUserRemoved(account_id);
@@ -374,9 +374,8 @@ void UserManagerBase::SaveUserOAuthStatus(
{
DictionaryPrefUpdate oauth_status_update(GetLocalState(),
kUserOAuthTokenStatus);
- oauth_status_update->SetWithoutPathExpansion(
- account_id.GetUserEmail(),
- new base::Value(static_cast<int>(oauth_token_status)));
+ oauth_status_update->SetIntegerWithoutPathExpansion(
+ account_id.GetUserEmail(), static_cast<int>(oauth_token_status));
}
GetLocalState()->CommitPendingWrite();
}
@@ -411,8 +410,8 @@ void UserManagerBase::SaveUserDisplayName(const AccountId& account_id,
if (!IsUserNonCryptohomeDataEphemeral(account_id)) {
DictionaryPrefUpdate display_name_update(GetLocalState(),
kUserDisplayName);
- display_name_update->SetWithoutPathExpansion(
- account_id.GetUserEmail(), new base::Value(display_name));
+ display_name_update->SetStringWithoutPathExpansion(
+ account_id.GetUserEmail(), display_name);
}
}
}
@@ -441,8 +440,8 @@ void UserManagerBase::SaveUserDisplayEmail(const AccountId& account_id,
return;
DictionaryPrefUpdate display_email_update(GetLocalState(), kUserDisplayEmail);
- display_email_update->SetWithoutPathExpansion(account_id.GetUserEmail(),
- new base::Value(display_email));
+ display_email_update->SetStringWithoutPathExpansion(account_id.GetUserEmail(),
+ display_email);
}
std::string UserManagerBase::GetUserDisplayEmail(
@@ -467,8 +466,8 @@ void UserManagerBase::SaveUserType(const AccountId& account_id,
return;
DictionaryPrefUpdate user_type_update(GetLocalState(), kUserType);
- user_type_update->SetWithoutPathExpansion(
- account_id.GetUserEmail(), new base::Value(static_cast<int>(user_type)));
+ user_type_update->SetIntegerWithoutPathExpansion(account_id.GetUserEmail(),
+ static_cast<int>(user_type));
GetLocalState()->CommitPendingWrite();
}
@@ -484,8 +483,8 @@ void UserManagerBase::UpdateUserAccountData(
user->set_given_name(given_name);
if (!IsUserNonCryptohomeDataEphemeral(account_id)) {
DictionaryPrefUpdate given_name_update(GetLocalState(), kUserGivenName);
- given_name_update->SetWithoutPathExpansion(account_id.GetUserEmail(),
- new base::Value(given_name));
+ given_name_update->SetStringWithoutPathExpansion(
+ account_id.GetUserEmail(), given_name);
}
}
diff --git a/chromium/components/user_prefs/user_prefs.cc b/chromium/components/user_prefs/user_prefs.cc
index 493c50eac77..a752c8f8acc 100644
--- a/chromium/components/user_prefs/user_prefs.cc
+++ b/chromium/components/user_prefs/user_prefs.cc
@@ -5,6 +5,7 @@
#include "components/user_prefs/user_prefs.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/singleton.h"
#include "components/prefs/pref_service.h"
@@ -34,7 +35,7 @@ void UserPrefs::Set(base::SupportsUserData* context, PrefService* prefs) {
DCHECK(context);
DCHECK(prefs);
DCHECK(!context->GetUserData(UserDataKey()));
- context->SetUserData(UserDataKey(), new UserPrefs(prefs));
+ context->SetUserData(UserDataKey(), base::WrapUnique(new UserPrefs(prefs)));
}
UserPrefs::UserPrefs(PrefService* prefs) : prefs_(prefs) {
diff --git a/chromium/components/user_prefs/user_prefs.h b/chromium/components/user_prefs/user_prefs.h
index 55e81c91c50..392e5dc7f23 100644
--- a/chromium/components/user_prefs/user_prefs.h
+++ b/chromium/components/user_prefs/user_prefs.h
@@ -20,6 +20,8 @@ namespace user_prefs {
// base::SupportsUserData using the UserPrefs::Set() function.
class USER_PREFS_EXPORT UserPrefs : public base::SupportsUserData::Data {
public:
+ ~UserPrefs() override;
+
// Retrieves the PrefService for a given context, or null if none is attached.
static PrefService* Get(base::SupportsUserData* context);
@@ -29,7 +31,6 @@ class USER_PREFS_EXPORT UserPrefs : public base::SupportsUserData::Data {
private:
explicit UserPrefs(PrefService* prefs);
- ~UserPrefs() override;
// Non-owning; owned by embedder.
PrefService* prefs_;
diff --git a/chromium/components/variations/BUILD.gn b/chromium/components/variations/BUILD.gn
index bc7008a0fb3..38d6e3e5ce3 100644
--- a/chromium/components/variations/BUILD.gn
+++ b/chromium/components/variations/BUILD.gn
@@ -75,7 +75,7 @@ static_library("variations") {
"//crypto",
"//third_party/mt19937ar",
"//third_party/protobuf:protobuf_lite",
- "//third_party/zlib:compression_utils",
+ "//third_party/zlib/google:compression_utils",
]
if (is_android) {
@@ -140,6 +140,6 @@ source_set("unit_tests") {
"//components/prefs:test_support",
"//components/variations/field_trial_config:unit_tests",
"//testing/gtest",
- "//third_party/zlib:compression_utils",
+ "//third_party/zlib/google:compression_utils",
]
}
diff --git a/chromium/components/variations/android/variations_seed_bridge.cc b/chromium/components/variations/android/variations_seed_bridge.cc
index f5b73e9a2ec..6b7bd84baab 100644
--- a/chromium/components/variations/android/variations_seed_bridge.cc
+++ b/chromium/components/variations/android/variations_seed_bridge.cc
@@ -8,7 +8,6 @@
#include <stdint.h>
#include <vector>
-#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
@@ -18,7 +17,6 @@
using base::android::AttachCurrentThread;
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertUTF8ToJavaString;
-using base::android::GetApplicationContext;
using base::android::ScopedJavaLocalRef;
namespace {
@@ -50,20 +48,15 @@ void GetVariationsFirstRunSeed(std::string* seed_data,
bool* is_gzip_compressed) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jbyteArray> j_seed_data =
- Java_VariationsSeedBridge_getVariationsFirstRunSeedData(
- env, GetApplicationContext());
+ Java_VariationsSeedBridge_getVariationsFirstRunSeedData(env);
ScopedJavaLocalRef<jstring> j_seed_signature =
- Java_VariationsSeedBridge_getVariationsFirstRunSeedSignature(
- env, GetApplicationContext());
+ Java_VariationsSeedBridge_getVariationsFirstRunSeedSignature(env);
ScopedJavaLocalRef<jstring> j_seed_country =
- Java_VariationsSeedBridge_getVariationsFirstRunSeedCountry(
- env, GetApplicationContext());
+ Java_VariationsSeedBridge_getVariationsFirstRunSeedCountry(env);
ScopedJavaLocalRef<jstring> j_response_date =
- Java_VariationsSeedBridge_getVariationsFirstRunSeedDate(
- env, GetApplicationContext());
+ Java_VariationsSeedBridge_getVariationsFirstRunSeedDate(env);
jboolean j_is_gzip_compressed =
- Java_VariationsSeedBridge_getVariationsFirstRunSeedIsGzipCompressed(
- env, GetApplicationContext());
+ Java_VariationsSeedBridge_getVariationsFirstRunSeedIsGzipCompressed(env);
*seed_data = JavaByteArrayToString(env, j_seed_data.obj());
*seed_signature = ConvertJavaStringToUTF8(j_seed_signature);
*seed_country = ConvertJavaStringToUTF8(j_seed_country);
@@ -73,13 +66,12 @@ void GetVariationsFirstRunSeed(std::string* seed_data,
void ClearJavaFirstRunPrefs() {
JNIEnv* env = AttachCurrentThread();
- Java_VariationsSeedBridge_clearFirstRunPrefs(env, GetApplicationContext());
+ Java_VariationsSeedBridge_clearFirstRunPrefs(env);
}
void MarkVariationsSeedAsStored() {
JNIEnv* env = AttachCurrentThread();
- Java_VariationsSeedBridge_markVariationsSeedAsStored(env,
- GetApplicationContext());
+ Java_VariationsSeedBridge_markVariationsSeedAsStored(env);
}
void SetJavaFirstRunPrefsForTesting(const std::string& seed_data,
@@ -89,7 +81,7 @@ void SetJavaFirstRunPrefsForTesting(const std::string& seed_data,
bool is_gzip_compressed) {
JNIEnv* env = AttachCurrentThread();
Java_VariationsSeedBridge_setVariationsFirstRunSeed(
- env, GetApplicationContext(), StringToJavaByteArray(env, seed_data),
+ env, StringToJavaByteArray(env, seed_data),
ConvertUTF8ToJavaString(env, seed_signature),
ConvertUTF8ToJavaString(env, seed_country),
ConvertUTF8ToJavaString(env, response_date),
diff --git a/chromium/components/variations/service/variations_service.cc b/chromium/components/variations/service/variations_service.cc
index 34e79b117a8..e669699c2cd 100644
--- a/chromium/components/variations/service/variations_service.cc
+++ b/chromium/components/variations/service/variations_service.cc
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <utility>
+#include <vector>
#include "base/build_time.h"
#include "base/command_line.h"
@@ -41,6 +42,7 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_status.h"
#include "ui/base/device_form_factor.h"
@@ -335,9 +337,7 @@ bool VariationsService::CreateTrialsFromSeed(base::FeatureList* feature_list) {
GetChannelForVariations(client_->GetChannel());
UMA_HISTOGRAM_SPARSE_SLOWLY("Variations.UserChannel", channel);
- const std::string latest_country =
- local_state_->GetString(prefs::kVariationsCountry);
-
+ const std::string latest_country = GetLatestCountry();
std::unique_ptr<const base::FieldTrial::EntropyProvider> low_entropy_provider(
CreateLowEntropyProvider());
// Note that passing |&ui_string_overrider_| via base::Unretained below is
@@ -531,8 +531,27 @@ void VariationsService::DoActualFetch() {
if (pending_seed_request_)
return;
- pending_seed_request_ = net::URLFetcher::Create(0, variations_server_url_,
- net::URLFetcher::GET, this);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("chrome_variations_service", R"(
+ semantics {
+ sender: "Chrome Variations Service"
+ description:
+ "Retrieves the list of Google Chrome's Variations from the server, "
+ "which will apply to the next Chrome session upon a restart."
+ trigger:
+ "Requests are made periodically while Google Chrome is running."
+ data: "The operating system name."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting: "This feature cannot be disabled by settings."
+ policy_exception_justification:
+ "Not implemented, considered not required."
+ })");
+ pending_seed_request_ =
+ net::URLFetcher::Create(0, variations_server_url_, net::URLFetcher::GET,
+ this, traffic_annotation);
data_use_measurement::DataUseUserData::AttachToFetcher(
pending_seed_request_.get(),
data_use_measurement::DataUseUserData::VARIATIONS);
@@ -760,8 +779,7 @@ void VariationsService::PerformSimulationWithVersion(
variations::VariationsSeedSimulator seed_simulator(*default_provider,
*low_provider);
- const std::string latest_country =
- local_state_->GetString(prefs::kVariationsCountry);
+ const std::string latest_country = GetLatestCountry();
const variations::VariationsSeedSimulator::Result result =
seed_simulator.SimulateSeedStudies(
*seed, client_->GetApplicationLocale(),
@@ -803,6 +821,12 @@ std::string VariationsService::LoadPermanentConsistencyCountry(
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(version.IsValid());
+ const std::string override_country =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kVariationsOverrideCountry);
+ if (!override_country.empty())
+ return override_country;
+
const base::ListValue* list_value =
local_state_->GetList(prefs::kVariationsPermanentConsistencyCountry);
std::string stored_version_string;
@@ -909,4 +933,13 @@ bool VariationsService::OverrideStoredPermanentCountry(
return true;
}
+std::string VariationsService::GetLatestCountry() const {
+ const std::string override_country =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kVariationsOverrideCountry);
+ return !override_country.empty()
+ ? override_country
+ : local_state_->GetString(prefs::kVariationsCountry);
+}
+
} // namespace variations
diff --git a/chromium/components/variations/service/variations_service.h b/chromium/components/variations/service/variations_service.h
index 74357b5f14d..6e7033b69d9 100644
--- a/chromium/components/variations/service/variations_service.h
+++ b/chromium/components/variations/service/variations_service.h
@@ -128,6 +128,10 @@ class VariationsService
// reason.
bool OverrideStoredPermanentCountry(const std::string& override_country);
+ // Returns what variations will consider to be the latest country. Returns
+ // empty if it is not available.
+ std::string GetLatestCountry() const;
+
// Exposed for testing.
static std::string GetDefaultVariationsServerURLForTesting();
diff --git a/chromium/components/variations/variations_seed_simulator.cc b/chromium/components/variations/variations_seed_simulator.cc
index ea56739c1fd..59b56643adf 100644
--- a/chromium/components/variations/variations_seed_simulator.cc
+++ b/chromium/components/variations/variations_seed_simulator.cc
@@ -43,7 +43,7 @@ std::string SimulateGroupAssignment(
scoped_refptr<base::FieldTrial> trial(
base::FieldTrial::CreateSimulatedFieldTrial(
study.name(), processed_study.total_probability(),
- study.default_experiment_name(), entropy_value));
+ processed_study.GetDefaultExperimentName(), entropy_value));
for (int i = 0; i < study.experiment_size(); ++i) {
const Study_Experiment& experiment = study.experiment(i);
diff --git a/chromium/components/variations/variations_switches.cc b/chromium/components/variations/variations_switches.cc
index 0bc8e82746e..5b19c665f5a 100644
--- a/chromium/components/variations/variations_switches.cc
+++ b/chromium/components/variations/variations_switches.cc
@@ -26,6 +26,13 @@ const char kFakeVariationsChannel[] = "fake-variations-channel";
// escaped for all non-alphanumeric characters.
const char kForceFieldTrialParams[] = "force-fieldtrial-params";
+// Allows overriding the country used for evaluating variations. This is similar
+// to the "Override Variations Country" entry on chrome://translate-internals,
+// but is exposed as a command-line flag to allow testing First Run scenarios.
+// Additionally, unlike chrome://translate-internals, the value isn't persisted
+// across sessions.
+const char kVariationsOverrideCountry[] = "variations-override-country";
+
// Specifies a custom URL for the server which reports variation data to the
// client. Specifying this switch enables the Variations service on
// unofficial builds. See variations_service.cc.
diff --git a/chromium/components/variations/variations_switches.h b/chromium/components/variations/variations_switches.h
index adebf9b13a1..9755dac4145 100644
--- a/chromium/components/variations/variations_switches.h
+++ b/chromium/components/variations/variations_switches.h
@@ -14,6 +14,7 @@ namespace switches {
extern const char kDisableFieldTrialTestingConfig[];
extern const char kFakeVariationsChannel[];
extern const char kForceFieldTrialParams[];
+extern const char kVariationsOverrideCountry[];
extern const char kVariationsServerURL[];
} // namespace switches
diff --git a/chromium/components/vector_icons/BUILD.gn b/chromium/components/vector_icons/BUILD.gn
new file mode 100644
index 00000000000..ffc9a535228
--- /dev/null
+++ b/chromium/components/vector_icons/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2017 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.
+
+import("//ui/vector_icons/vector_icons.gni")
+
+aggregate_vector_icons("components_vector_icons") {
+ icon_directory = "."
+
+ icons = [
+ "screen_share.1x.icon",
+ "screen_share.icon",
+ ]
+}
+
+static_library("vector_icons") {
+ sources = get_target_outputs(":components_vector_icons")
+
+ deps = [
+ ":components_vector_icons",
+ "//base",
+ "//skia",
+ "//ui/gfx",
+ ]
+}
diff --git a/chromium/components/vector_icons/OWNERS b/chromium/components/vector_icons/OWNERS
new file mode 100644
index 00000000000..658a9f5cd0c
--- /dev/null
+++ b/chromium/components/vector_icons/OWNERS
@@ -0,0 +1 @@
+estade@chromium.org
diff --git a/chromium/components/vector_icons/screen_share.1x.icon b/chromium/components/vector_icons/screen_share.1x.icon
new file mode 100644
index 00000000000..316ad3786b8
--- /dev/null
+++ b/chromium/components/vector_icons/screen_share.1x.icon
@@ -0,0 +1,30 @@
+// Copyright 2016 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.
+
+CANVAS_DIMENSIONS, 16,
+MOVE_TO, 2.31f, 3,
+CUBIC_TO, 1.59f, 3, 1, 3.57f, 1, 4.27f,
+R_V_LINE_TO, 7.62f,
+CUBIC_TO, 1, 12.58f, 1.59f, 13, 2.31f, 13,
+R_H_LINE_TO, 11.38f,
+R_CUBIC_TO, 0.72f, 0, 1.31f, -0.42f, 1.31f, -1.11f,
+V_LINE_TO, 4.27f,
+CUBIC_TO, 15, 3.57f, 14.41f, 3, 13.69f, 3,
+H_LINE_TO, 2.31f,
+CLOSE,
+MOVE_TO, 2, 12,
+V_LINE_TO, 4,
+R_H_LINE_TO, 12,
+R_V_LINE_TO, 8,
+H_LINE_TO, 2,
+CLOSE,
+R_MOVE_TO, 6.36f, -3.33f,
+CUBIC_TO, 6.62f, 8.64f, 5.8f, 9.07f, 5, 10,
+R_CUBIC_TO, 0.32f, -1.33f, 0.98f, -2.66f, 3.36f, -2.67f,
+V_LINE_TO, 6,
+LINE_TO, 11, 8,
+R_LINE_TO, -2.64f, 2,
+V_LINE_TO, 8.67f,
+CLOSE,
+END
diff --git a/chromium/components/vector_icons/screen_share.icon b/chromium/components/vector_icons/screen_share.icon
new file mode 100644
index 00000000000..517fac6295f
--- /dev/null
+++ b/chromium/components/vector_icons/screen_share.icon
@@ -0,0 +1,30 @@
+// Copyright 2016 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.
+
+CANVAS_DIMENSIONS, 32,
+MOVE_TO, 4.62f, 6,
+CUBIC_TO, 3.18f, 6, 2, 7.14f, 2, 8.54f,
+V_LINE_TO, 23.77f,
+CUBIC_TO, 2, 25.17f, 3.18f, 26, 4.62f, 26,
+R_H_LINE_TO, 22.77f,
+CUBIC_TO, 28.82f, 26, 30, 25.17f, 30, 23.77f,
+V_LINE_TO, 8.54f,
+CUBIC_TO, 30, 7.14f, 28.82f, 6, 27.38f, 6,
+H_LINE_TO, 4.62f,
+CLOSE,
+MOVE_TO, 4, 24,
+V_LINE_TO, 8,
+R_H_LINE_TO, 24,
+R_V_LINE_TO, 16,
+H_LINE_TO, 4,
+CLOSE,
+R_MOVE_TO, 13, -7,
+R_CUBIC_TO, -3.64f, -0.06f, -5.33f, 0.9f, -7, 3,
+R_CUBIC_TO, 0.67f, -3, 2.03f, -6, 7, -6,
+R_V_LINE_TO, -3,
+R_LINE_TO, 5.5f, 4.5f,
+LINE_TO, 17, 20,
+R_V_LINE_TO, -3,
+CLOSE,
+END
diff --git a/chromium/components/vector_icons/vector_icons.cc.template b/chromium/components/vector_icons/vector_icons.cc.template
new file mode 100644
index 00000000000..4a965b1c219
--- /dev/null
+++ b/chromium/components/vector_icons/vector_icons.cc.template
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+// vector_icons.cc.template is used to generate vector_icons.cc. Edit the former
+// rather than the latter.
+
+#include "components/vector_icons/vector_icons.h"
+
+#include "base/logging.h"
+#include "ui/gfx/vector_icon_types.h"
+
+#define PATH_ELEMENT_TEMPLATE(path_name, ...) \
+static constexpr gfx::PathElement path_name[] = {__VA_ARGS__};
+
+#define VECTOR_ICON_TEMPLATE(icon_name, path_name, path_name_1x) \
+const gfx::VectorIcon icon_name = { path_name , path_name_1x };
+
+namespace vector_icons {
+
+using namespace gfx;
+
+TEMPLATE_PLACEHOLDER
+
+} // namespace vector_icons
diff --git a/chromium/components/vector_icons/vector_icons.h.template b/chromium/components/vector_icons/vector_icons.h.template
new file mode 100644
index 00000000000..114d8cc5829
--- /dev/null
+++ b/chromium/components/vector_icons/vector_icons.h.template
@@ -0,0 +1,26 @@
+// Copyright 2017 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.
+
+// vector_icons.h.template is used to generate vector_icons.h. Edit the former
+// rather than the latter.
+
+#ifndef COMPONENTS_VECTOR_ICONS_VECTOR_ICONS_H_
+#define COMPONENTS_VECTOR_ICONS_VECTOR_ICONS_H_
+
+namespace gfx {
+struct VectorIcon;
+}
+
+#define VECTOR_ICON_TEMPLATE_H(icon_name) \
+extern const gfx::VectorIcon icon_name;
+
+namespace vector_icons {
+
+TEMPLATE_PLACEHOLDER
+
+} // namespace vector_icons
+
+#undef VECTOR_ICON_TEMPLATE_H
+
+#endif // COMPONENTS_VECTOR_ICONS_VECTOR_ICONS_H_
diff --git a/chromium/components/version_ui/OWNERS b/chromium/components/version_ui/OWNERS
index e87625e132a..918baa1330f 100644
--- a/chromium/components/version_ui/OWNERS
+++ b/chromium/components/version_ui/OWNERS
@@ -1,3 +1,3 @@
-file://ui/webui/OWNERS
+file://ui/webui/PLATFORM_OWNERS
# COMPONENT: UI>Browser>WebUI
diff --git a/chromium/components/version_ui/PRESUBMIT.py b/chromium/components/version_ui/PRESUBMIT.py
new file mode 100644
index 00000000000..5b4c471b83b
--- /dev/null
+++ b/chromium/components/version_ui/PRESUBMIT.py
@@ -0,0 +1,25 @@
+# Copyright 2017 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.
+
+
+def _CommonChecks(input_api, output_api):
+ results = []
+ try:
+ import sys
+ old_sys_path = sys.path[:]
+ cwd = input_api.PresubmitLocalPath()
+ sys.path += [input_api.os_path.join(cwd, '..', '..', 'tools')]
+ import web_dev_style.presubmit_support
+ results += web_dev_style.presubmit_support.CheckStyle(input_api, output_api)
+ finally:
+ sys.path = old_sys_path
+ return results
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
diff --git a/chromium/components/visitedlink/renderer/visitedlink_slave.cc b/chromium/components/visitedlink/renderer/visitedlink_slave.cc
index 5355c14d5a1..97c4ad32790 100644
--- a/chromium/components/visitedlink/renderer/visitedlink_slave.cc
+++ b/chromium/components/visitedlink/renderer/visitedlink_slave.cc
@@ -20,7 +20,8 @@ VisitedLinkSlave::~VisitedLinkSlave() {
FreeTable();
}
-base::Callback<void(mojom::VisitedLinkNotificationSinkRequest)>
+base::Callback<void(const service_manager::BindSourceInfo&,
+ mojom::VisitedLinkNotificationSinkRequest)>
VisitedLinkSlave::GetBindCallback() {
return base::Bind(&VisitedLinkSlave::Bind, weak_factory_.GetWeakPtr());
}
@@ -79,7 +80,8 @@ void VisitedLinkSlave::FreeTable() {
table_length_ = 0;
}
-void VisitedLinkSlave::Bind(mojom::VisitedLinkNotificationSinkRequest request) {
+void VisitedLinkSlave::Bind(const service_manager::BindSourceInfo& source_info,
+ mojom::VisitedLinkNotificationSinkRequest request) {
binding_.Bind(std::move(request));
}
diff --git a/chromium/components/visitedlink/renderer/visitedlink_slave.h b/chromium/components/visitedlink/renderer/visitedlink_slave.h
index bbf0cfde2f8..658d373e932 100644
--- a/chromium/components/visitedlink/renderer/visitedlink_slave.h
+++ b/chromium/components/visitedlink/renderer/visitedlink_slave.h
@@ -12,6 +12,7 @@
#include "components/visitedlink/common/visitedlink_common.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/buffer.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
namespace visitedlink {
@@ -23,7 +24,8 @@ class VisitedLinkSlave : public VisitedLinkCommon,
VisitedLinkSlave();
~VisitedLinkSlave() override;
- base::Callback<void(mojom::VisitedLinkNotificationSinkRequest)>
+ base::Callback<void(const service_manager::BindSourceInfo&,
+ mojom::VisitedLinkNotificationSinkRequest)>
GetBindCallback();
// mojom::VisitedLinkNotificationSink overrides.
@@ -35,7 +37,8 @@ class VisitedLinkSlave : public VisitedLinkCommon,
private:
void FreeTable();
- void Bind(mojom::VisitedLinkNotificationSinkRequest request);
+ void Bind(const service_manager::BindSourceInfo& source_info,
+ mojom::VisitedLinkNotificationSinkRequest request);
mojo::ScopedSharedBufferMapping table_mapping_;
diff --git a/chromium/components/display_compositor/BUILD.gn b/chromium/components/viz/display_compositor/BUILD.gn
index 41cc0497fc2..740b277bab0 100644
--- a/chromium/components/display_compositor/BUILD.gn
+++ b/chromium/components/viz/display_compositor/BUILD.gn
@@ -10,7 +10,6 @@ component("display_compositor") {
"buffer_queue.cc",
"buffer_queue.h",
"compositor_overlay_candidate_validator.h",
- "display_compositor_export.h",
"gl_helper.cc",
"gl_helper.h",
"gl_helper_readback_support.cc",
@@ -23,7 +22,7 @@ component("display_compositor") {
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
- defines = [ "DISPLAY_COMPOSITOR_IMPLEMENTATION" ]
+ defines = [ "VIZ_IMPLEMENTATION" ]
deps = [
"//base",
diff --git a/chromium/components/display_compositor/DEPS b/chromium/components/viz/display_compositor/DEPS
index 5f7809be7ec..5f7809be7ec 100644
--- a/chromium/components/display_compositor/DEPS
+++ b/chromium/components/viz/display_compositor/DEPS
diff --git a/chromium/components/display_compositor/OWNERS b/chromium/components/viz/display_compositor/OWNERS
index 68de279ade5..68de279ade5 100644
--- a/chromium/components/display_compositor/OWNERS
+++ b/chromium/components/viz/display_compositor/OWNERS
diff --git a/chromium/components/display_compositor/buffer_queue.cc b/chromium/components/viz/display_compositor/buffer_queue.cc
index 092ae46771c..baa5a3877ea 100644
--- a/chromium/components/display_compositor/buffer_queue.cc
+++ b/chromium/components/viz/display_compositor/buffer_queue.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/display_compositor/buffer_queue.h"
+#include "components/viz/display_compositor/buffer_queue.h"
#include "base/containers/adapters.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
-#include "components/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
@@ -18,7 +18,7 @@
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/skia_util.h"
-namespace display_compositor {
+namespace viz {
BufferQueue::BufferQueue(gpu::gles2::GLES2Interface* gl,
uint32_t texture_target,
@@ -300,4 +300,4 @@ BufferQueue::AllocatedSurface::~AllocatedSurface() {
buffer_queue->FreeSurfaceResources(this);
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/buffer_queue.h b/chromium/components/viz/display_compositor/buffer_queue.h
index c6bedbb1757..a0e91441eb0 100644
--- a/chromium/components/display_compositor/buffer_queue.h
+++ b/chromium/components/viz/display_compositor/buffer_queue.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_DISPLAY_COMPOSITOR_BUFFER_QUEUE_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_BUFFER_QUEUE_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_BUFFER_QUEUE_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_BUFFER_QUEUE_H_
#include <stddef.h>
@@ -13,7 +13,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/viz_export.h"
#include "gpu/ipc/common/surface_handle.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/color_space.h"
@@ -32,7 +32,7 @@ class GLES2Interface;
}
}
-namespace display_compositor {
+namespace viz {
class GLHelper;
@@ -40,7 +40,7 @@ class GLHelper;
// created using CHROMIUM_image. Double/triple buffering is implemented
// internally. Doublebuffering occurs if PageFlipComplete is called before the
// next BindFramebuffer call, otherwise it creates extra buffers.
-class DISPLAY_COMPOSITOR_EXPORT BufferQueue {
+class VIZ_EXPORT BufferQueue {
public:
BufferQueue(gpu::gles2::GLES2Interface* gl,
uint32_t texture_target,
@@ -70,7 +70,7 @@ class DISPLAY_COMPOSITOR_EXPORT BufferQueue {
friend class BufferQueueTest;
friend class AllocatedSurface;
- struct DISPLAY_COMPOSITOR_EXPORT AllocatedSurface {
+ struct VIZ_EXPORT AllocatedSurface {
AllocatedSurface(BufferQueue* buffer_queue,
std::unique_ptr<gfx::GpuMemoryBuffer> buffer,
uint32_t texture,
@@ -131,6 +131,6 @@ class DISPLAY_COMPOSITOR_EXPORT BufferQueue {
DISALLOW_COPY_AND_ASSIGN(BufferQueue);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_BUFFER_QUEUE_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_BUFFER_QUEUE_H_
diff --git a/chromium/components/display_compositor/buffer_queue_unittest.cc b/chromium/components/viz/display_compositor/buffer_queue_unittest.cc
index c99270f7104..44c36aaa596 100644
--- a/chromium/components/display_compositor/buffer_queue_unittest.cc
+++ b/chromium/components/viz/display_compositor/buffer_queue_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/display_compositor/buffer_queue.h"
+#include "components/viz/display_compositor/buffer_queue.h"
#include <stddef.h>
#include <stdint.h>
@@ -14,7 +14,7 @@
#include "cc/test/test_context_provider.h"
#include "cc/test/test_gpu_memory_buffer_manager.h"
#include "cc/test/test_web_graphics_context_3d.h"
-#include "components/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -26,11 +26,11 @@ using ::testing::Expectation;
using ::testing::Ne;
using ::testing::Return;
-namespace display_compositor {
+namespace viz {
class StubGpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
public:
- StubGpuMemoryBufferImpl(size_t* set_color_space_count)
+ explicit StubGpuMemoryBufferImpl(size_t* set_color_space_count)
: set_color_space_count_(set_color_space_count) {}
// Overridden from gfx::GpuMemoryBuffer:
@@ -677,4 +677,4 @@ TEST_F(BufferQueueTest, AllocateFails) {
}
} // namespace
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator.h b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator.h
index faec8a04440..62eae190122 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator.h
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator.h
@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_H_
#include "base/macros.h"
#include "cc/output/overlay_candidate_validator.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/viz_export.h"
-namespace display_compositor {
+namespace viz {
-class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidator
+class VIZ_EXPORT CompositorOverlayCandidateValidator
: public cc::OverlayCandidateValidator {
public:
CompositorOverlayCandidateValidator() {}
@@ -23,6 +23,6 @@ class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidator
DISALLOW_COPY_AND_ASSIGN(CompositorOverlayCandidateValidator);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_H_
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_android.cc b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_android.cc
index a75f5570e52..e183ee10540 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_android.cc
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_android.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/display_compositor/compositor_overlay_candidate_validator_android.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator_android.h"
#include <memory>
@@ -11,7 +11,7 @@
#include "cc/output/overlay_strategy_underlay.h"
#include "ui/gfx/geometry/rect_conversions.h"
-namespace display_compositor {
+namespace viz {
CompositorOverlayCandidateValidatorAndroid::
CompositorOverlayCandidateValidatorAndroid() {}
@@ -65,4 +65,4 @@ bool CompositorOverlayCandidateValidatorAndroid::AllowDCLayerOverlays() {
void CompositorOverlayCandidateValidatorAndroid::SetSoftwareMirrorMode(
bool enabled) {}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_android.h b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_android.h
index f98e2aad4d9..9f6e75c9917 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_android.h
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_android.h
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
#include "base/macros.h"
-#include "components/display_compositor/compositor_overlay_candidate_validator.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator.h"
+#include "components/viz/viz_export.h"
-namespace display_compositor {
+namespace viz {
// An overlay validator for supporting fullscreen video underlays on Android.
// Things are a bit different on Android compared with other platforms. By the
@@ -19,7 +19,7 @@ namespace display_compositor {
// the reasons that only fullscreen is supported: we have to be sure that
// nothing will cause the overlay to be rejected, because there's no fallback to
// gl compositing.
-class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorAndroid
+class VIZ_EXPORT CompositorOverlayCandidateValidatorAndroid
: public CompositorOverlayCandidateValidator {
public:
CompositorOverlayCandidateValidatorAndroid();
@@ -36,6 +36,6 @@ class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorAndroid
DISALLOW_COPY_AND_ASSIGN(CompositorOverlayCandidateValidatorAndroid);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_mac.h b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_mac.h
index 0ee60f5199b..774c22ced75 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_mac.h
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_mac.h
@@ -2,18 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
#include <memory>
#include "base/macros.h"
-#include "components/display_compositor/compositor_overlay_candidate_validator.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator.h"
+#include "components/viz/viz_export.h"
-namespace display_compositor {
+namespace viz {
-class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorMac
+class VIZ_EXPORT CompositorOverlayCandidateValidatorMac
: public CompositorOverlayCandidateValidator {
public:
explicit CompositorOverlayCandidateValidatorMac(bool ca_layer_disabled);
@@ -35,6 +35,6 @@ class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorMac
DISALLOW_COPY_AND_ASSIGN(CompositorOverlayCandidateValidatorMac);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_MAC_H_
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_mac.mm b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_mac.mm
index 336cc8fbdfd..1fe6d35a9ef 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_mac.mm
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_mac.mm
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/display_compositor/compositor_overlay_candidate_validator_mac.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator_mac.h"
#include <stddef.h>
-namespace display_compositor {
+namespace viz {
CompositorOverlayCandidateValidatorMac::CompositorOverlayCandidateValidatorMac(
bool ca_layer_disabled)
@@ -34,4 +34,4 @@ void CompositorOverlayCandidateValidatorMac::SetSoftwareMirrorMode(
software_mirror_active_ = enabled;
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_ozone.cc b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_ozone.cc
index 901076af3ba..c21d8c7728a 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_ozone.cc
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_ozone.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/display_compositor/compositor_overlay_candidate_validator_ozone.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator_ozone.h"
#include <stddef.h>
@@ -17,7 +17,7 @@
#include "cc/output/overlay_strategy_underlay_cast.h"
#include "ui/ozone/public/overlay_candidates_ozone.h"
-namespace display_compositor {
+namespace viz {
namespace {
// Templated function used to create an OverlayProcessor::Strategy
// of type |S|.
@@ -125,4 +125,4 @@ void CompositorOverlayCandidateValidatorOzone::SetSoftwareMirrorMode(
software_mirror_active_ = enabled;
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_ozone.h b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_ozone.h
index 02c9b670382..3e95825c8ad 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_ozone.h
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_ozone.h
@@ -2,24 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
#include <memory>
#include "base/callback.h"
#include "base/macros.h"
-#include "components/display_compositor/compositor_overlay_candidate_validator.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator.h"
+#include "components/viz/viz_export.h"
#include "ui/gfx/native_widget_types.h"
namespace ui {
class OverlayCandidatesOzone;
}
-namespace display_compositor {
+namespace viz {
-class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorOzone
+class VIZ_EXPORT CompositorOverlayCandidateValidatorOzone
: public CompositorOverlayCandidateValidator {
public:
CompositorOverlayCandidateValidatorOzone(
@@ -50,6 +50,6 @@ class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorOzone
DISALLOW_COPY_AND_ASSIGN(CompositorOverlayCandidateValidatorOzone);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_win.cc b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_win.cc
index 74e704672de..0a4e0f98431 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_win.cc
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_win.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/display_compositor/compositor_overlay_candidate_validator_win.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator_win.h"
#include "cc/output/overlay_processor.h"
-namespace display_compositor {
+namespace viz {
CompositorOverlayCandidateValidatorWin::
CompositorOverlayCandidateValidatorWin() {}
@@ -15,8 +15,7 @@ CompositorOverlayCandidateValidatorWin::
~CompositorOverlayCandidateValidatorWin() {}
void CompositorOverlayCandidateValidatorWin::GetStrategies(
- cc::OverlayProcessor::StrategyList* strategies) {
-}
+ cc::OverlayProcessor::StrategyList* strategies) {}
void CompositorOverlayCandidateValidatorWin::CheckOverlaySupport(
cc::OverlayCandidateList* candidates) {
@@ -37,4 +36,4 @@ void CompositorOverlayCandidateValidatorWin::SetSoftwareMirrorMode(
NOTIMPLEMENTED();
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/compositor_overlay_candidate_validator_win.h b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_win.h
index 18145f3d434..9cd9446ab1d 100644
--- a/chromium/components/display_compositor/compositor_overlay_candidate_validator_win.h
+++ b/chromium/components/viz/display_compositor/compositor_overlay_candidate_validator_win.h
@@ -2,18 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_WIN_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_WIN_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_WIN_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_WIN_H_
#include "base/macros.h"
-#include "components/display_compositor/compositor_overlay_candidate_validator.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/display_compositor/compositor_overlay_candidate_validator.h"
+#include "components/viz/viz_export.h"
-namespace display_compositor {
+namespace viz {
// This is a simple overlay candidate validator that promotes everything
// possible to an overlay.
-class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorWin
+class VIZ_EXPORT CompositorOverlayCandidateValidatorWin
: public CompositorOverlayCandidateValidator {
public:
CompositorOverlayCandidateValidatorWin();
@@ -30,6 +30,6 @@ class DISPLAY_COMPOSITOR_EXPORT CompositorOverlayCandidateValidatorWin
DISALLOW_COPY_AND_ASSIGN(CompositorOverlayCandidateValidatorWin);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_WIN_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_WIN_H_
diff --git a/chromium/components/display_compositor/display_compositor_test_suite.cc b/chromium/components/viz/display_compositor/display_compositor_test_suite.cc
index aca51a7f59f..8744ff84d19 100644
--- a/chromium/components/display_compositor/display_compositor_test_suite.cc
+++ b/chromium/components/viz/display_compositor/display_compositor_test_suite.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/display_compositor/display_compositor_test_suite.h"
+#include "components/viz/display_compositor/display_compositor_test_suite.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_id_name_manager.h"
#include "cc/test/paths.h"
#include "ui/gl/test/gl_surface_test_support.h"
-namespace display_compositor {
+namespace viz {
DisplayCompositorTestSuite::DisplayCompositorTestSuite(int argc, char** argv)
: base::TestSuite(argc, argv) {}
@@ -35,4 +35,4 @@ void DisplayCompositorTestSuite::Shutdown() {
base::TestSuite::Shutdown();
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/display_compositor_test_suite.h b/chromium/components/viz/display_compositor/display_compositor_test_suite.h
index 75faf4dcee3..e2a755b2ec2 100644
--- a/chromium/components/display_compositor/display_compositor_test_suite.h
+++ b/chromium/components/viz/display_compositor/display_compositor_test_suite.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_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_TEST_SUITE_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_TEST_SUITE_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_TEST_SUITE_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_TEST_SUITE_H_
#include <memory>
@@ -15,7 +15,7 @@ namespace base {
class MessageLoop;
}
-namespace display_compositor {
+namespace viz {
class DisplayCompositorTestSuite : public base::TestSuite {
public:
@@ -34,6 +34,6 @@ class DisplayCompositorTestSuite : public base::TestSuite {
DISALLOW_COPY_AND_ASSIGN(DisplayCompositorTestSuite);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_TEST_SUITE_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_DISPLAY_COMPOSITOR_TEST_SUITE_H_
diff --git a/chromium/components/display_compositor/gl_helper.cc b/chromium/components/viz/display_compositor/gl_helper.cc
index 24008df35a2..0d3745520e5 100644
--- a/chromium/components/display_compositor/gl_helper.cc
+++ b/chromium/components/viz/display_compositor/gl_helper.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/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper.h"
#include <stddef.h>
#include <stdint.h>
@@ -19,8 +19,8 @@
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
-#include "components/display_compositor/gl_helper_readback_support.h"
-#include "components/display_compositor/gl_helper_scaling.h"
+#include "components/viz/display_compositor/gl_helper_readback_support.h"
+#include "components/viz/display_compositor/gl_helper_scaling.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/common/mailbox.h"
@@ -52,12 +52,11 @@ class TextureFrameBufferPair {
public:
TextureFrameBufferPair(GLES2Interface* gl, gfx::Size size)
: texture_(gl), framebuffer_(gl), size_(size) {
- display_compositor::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
- gl, texture_);
+ viz::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, texture_);
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- display_compositor::ScopedFramebufferBinder<GL_FRAMEBUFFER>
- framebuffer_binder(gl, framebuffer_);
+ viz::ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
+ gl, framebuffer_);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, texture_, 0);
}
@@ -67,8 +66,8 @@ class TextureFrameBufferPair {
gfx::Size size() const { return size_; }
private:
- display_compositor::ScopedTexture texture_;
- display_compositor::ScopedFramebuffer framebuffer_;
+ viz::ScopedTexture texture_;
+ viz::ScopedFramebuffer framebuffer_;
gfx::Size size_;
DISALLOW_COPY_AND_ASSIGN(TextureFrameBufferPair);
@@ -79,17 +78,14 @@ class TextureFrameBufferPair {
// when the output of a scaler is to be sent to a readback.
class ScalerHolder {
public:
- ScalerHolder(GLES2Interface* gl,
- display_compositor::GLHelper::ScalerInterface* scaler)
+ ScalerHolder(GLES2Interface* gl, viz::GLHelper::ScalerInterface* scaler)
: texture_and_framebuffer_(gl, scaler->DstSize()), scaler_(scaler) {}
void Scale(GLuint src_texture) {
scaler_->Scale(src_texture, texture_and_framebuffer_.texture());
}
- display_compositor::GLHelper::ScalerInterface* scaler() const {
- return scaler_.get();
- }
+ viz::GLHelper::ScalerInterface* scaler() const { return scaler_.get(); }
TextureFrameBufferPair* texture_and_framebuffer() {
return &texture_and_framebuffer_;
}
@@ -97,14 +93,14 @@ class ScalerHolder {
private:
TextureFrameBufferPair texture_and_framebuffer_;
- std::unique_ptr<display_compositor::GLHelper::ScalerInterface> scaler_;
+ std::unique_ptr<viz::GLHelper::ScalerInterface> scaler_;
DISALLOW_COPY_AND_ASSIGN(ScalerHolder);
};
} // namespace
-namespace display_compositor {
+namespace viz {
typedef GLHelperReadbackSupport::FormatSupport FormatSupport;
// Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates
@@ -334,10 +330,8 @@ class GLHelper::CopyTextureToImpl
GLHelper::ScalerQuality quality_;
ReadbackSwizzle swizzle_;
ScalerHolder scaler_;
- std::unique_ptr<display_compositor::GLHelperScaling::ShaderInterface>
- pass1_shader_;
- std::unique_ptr<display_compositor::GLHelperScaling::ShaderInterface>
- pass2_shader_;
+ std::unique_ptr<GLHelperScaling::ShaderInterface> pass1_shader_;
+ std::unique_ptr<GLHelperScaling::ShaderInterface> pass2_shader_;
TextureFrameBufferPair y_;
ScopedTexture uv_;
TextureFrameBufferPair u_;
@@ -548,11 +542,11 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture(
bool scale_swizzle = out_color_type == kAlpha_8_SkColorType
? false
: supported == GLHelperReadbackSupport::SWIZZLE;
- texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size, true,
- scale_swizzle, out_color_type == kAlpha_8_SkColorType
- ? kN32_SkColorType
- : out_color_type,
- quality);
+ texture = ScaleTexture(
+ src_texture, src_size, src_subrect, dst_size, true, scale_swizzle,
+ out_color_type == kAlpha_8_SkColorType ? kN32_SkColorType
+ : out_color_type,
+ quality);
DCHECK(texture);
}
@@ -874,8 +868,7 @@ void GLHelper::CopySubBufferDamage(GLenum target,
GLuint GLHelper::CreateTexture() {
GLuint texture = 0u;
gl_->GenTextures(1, &texture);
- display_compositor::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
- gl_, texture);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -921,22 +914,19 @@ GLuint GLHelper::ConsumeMailboxToTexture(const gpu::Mailbox& mailbox,
}
void GLHelper::ResizeTexture(GLuint texture, const gfx::Size& size) {
- display_compositor::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
- gl_, texture);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0,
GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
void GLHelper::CopyTextureSubImage(GLuint texture, const gfx::Rect& rect) {
- display_compositor::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
- gl_, texture);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
gl_->CopyTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.x(),
rect.y(), rect.width(), rect.height());
}
void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) {
- display_compositor::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
- gl_, texture);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(),
size.height(), 0);
}
@@ -1127,8 +1117,7 @@ GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT(
DCHECK(!(dst_size.width() & 1));
DCHECK(!(dst_size.height() & 1));
- display_compositor::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl,
- uv_);
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, uv_);
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (dst_size.width() + 3) / 4,
dst_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
@@ -1245,4 +1234,4 @@ ReadbackYUVInterface* GLHelper::CreateReadbackPipelineYUV(
quality, src_size, src_subrect, dst_size, flip_vertically, use_mrt);
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/gl_helper.h b/chromium/components/viz/display_compositor/gl_helper.h
index 83434d2d1f2..430c72f5e17 100644
--- a/chromium/components/display_compositor/gl_helper.h
+++ b/chromium/components/viz/display_compositor/gl_helper.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_DISPLAY_COMPOSITOR_GL_HELPER_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_H_
#include <memory>
#include "base/atomicops.h"
#include "base/callback.h"
#include "base/macros.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/viz_export.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -28,11 +28,11 @@ struct Mailbox;
class SkRegion;
-namespace display_compositor {
+namespace viz {
class GLHelperScaling;
-class DISPLAY_COMPOSITOR_EXPORT ScopedGLuint {
+class VIZ_EXPORT ScopedGLuint {
public:
typedef void (gpu::gles2::GLES2Interface::*GenFunc)(GLsizei n, GLuint* ids);
typedef void (gpu::gles2::GLES2Interface::*DeleteFunc)(GLsizei n,
@@ -134,7 +134,7 @@ class GLHelperReadbackSupport;
// Provides higher level operations on top of the gpu::gles2::GLES2Interface
// interfaces.
-class DISPLAY_COMPOSITOR_EXPORT GLHelper {
+class VIZ_EXPORT GLHelper {
public:
GLHelper(gpu::gles2::GLES2Interface* gl,
gpu::ContextSupport* context_support);
@@ -280,7 +280,7 @@ class DISPLAY_COMPOSITOR_EXPORT GLHelper {
// needed to scale from a specified size to a destination size.
// If the source or destination sizes changes, you must create
// a new scaler.
- class DISPLAY_COMPOSITOR_EXPORT ScalerInterface {
+ class VIZ_EXPORT ScalerInterface {
public:
ScalerInterface() {}
virtual ~ScalerInterface() {}
@@ -343,6 +343,7 @@ class DISPLAY_COMPOSITOR_EXPORT GLHelper {
std::unique_ptr<GLHelperScaling> scaler_impl_;
std::unique_ptr<GLHelperReadbackSupport> readback_support_;
+ private:
DISALLOW_COPY_AND_ASSIGN(GLHelper);
};
@@ -353,7 +354,7 @@ class DISPLAY_COMPOSITOR_EXPORT GLHelper {
// can handle multiple outstanding readbacks at the same time, but
// if the source or destination sizes change, you'll need to create
// a new readback pipeline.
-class DISPLAY_COMPOSITOR_EXPORT ReadbackYUVInterface {
+class VIZ_EXPORT ReadbackYUVInterface {
public:
ReadbackYUVInterface() {}
virtual ~ReadbackYUVInterface() {}
@@ -377,6 +378,6 @@ class DISPLAY_COMPOSITOR_EXPORT ReadbackYUVInterface {
virtual GLHelper::ScalerInterface* scaler() = 0;
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_H_
diff --git a/chromium/components/display_compositor/gl_helper_benchmark.cc b/chromium/components/viz/display_compositor/gl_helper_benchmark.cc
index 674e4fd18bd..e390e035dc0 100644
--- a/chromium/components/display_compositor/gl_helper_benchmark.cc
+++ b/chromium/components/viz/display_compositor/gl_helper_benchmark.cc
@@ -25,8 +25,8 @@
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "components/display_compositor/gl_helper.h"
-#include "components/display_compositor/gl_helper_scaling.h"
+#include "components/viz/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper_scaling.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/ipc/gl_in_process_context.h"
@@ -36,14 +36,13 @@
#include "ui/gfx/codec/png_codec.h"
#include "ui/gl/gl_surface.h"
-namespace display_compositor {
+namespace viz {
namespace {
-display_compositor::GLHelper::ScalerQuality kQualities[] = {
- display_compositor::GLHelper::SCALER_QUALITY_BEST,
- display_compositor::GLHelper::SCALER_QUALITY_GOOD,
- display_compositor::GLHelper::SCALER_QUALITY_FAST,
+GLHelper::ScalerQuality kQualities[] = {
+ GLHelper::SCALER_QUALITY_BEST, GLHelper::SCALER_QUALITY_GOOD,
+ GLHelper::SCALER_QUALITY_FAST,
};
const char* const kQualityNames[] = {
@@ -80,9 +79,8 @@ class GLHelperBenchmark : public testing::Test {
gl_ = context_->GetImplementation();
gpu::ContextSupport* support = context_->GetImplementation();
- helper_.reset(new display_compositor::GLHelper(gl_, support));
- helper_scaling_.reset(
- new display_compositor::GLHelperScaling(gl_, helper_.get()));
+ helper_.reset(new GLHelper(gl_, support));
+ helper_scaling_.reset(new GLHelperScaling(gl_, helper_.get()));
}
void TearDown() override {
@@ -119,8 +117,8 @@ class GLHelperBenchmark : public testing::Test {
std::unique_ptr<gpu::GLInProcessContext> context_;
gpu::gles2::GLES2Interface* gl_;
- std::unique_ptr<display_compositor::GLHelper> helper_;
- std::unique_ptr<display_compositor::GLHelperScaling> helper_scaling_;
+ std::unique_ptr<GLHelper> helper_;
+ std::unique_ptr<GLHelperScaling> helper_scaling_;
std::deque<GLHelperScaling::ScaleOp> x_ops_, y_ops_;
};
@@ -158,9 +156,8 @@ TEST_F(GLHelperBenchmark, ScaleBenchmark) {
input.getPixels());
gfx::Rect src_subrect(0, 0, src_size.width(), src_size.height());
- std::unique_ptr<display_compositor::GLHelper::ScalerInterface> scaler(
- helper_->CreateScaler(kQualities[q], src_size, src_subrect,
- dst_size, false, false));
+ std::unique_ptr<GLHelper::ScalerInterface> scaler(helper_->CreateScaler(
+ kQualities[q], src_size, src_subrect, dst_size, false, false));
// Scale once beforehand before we start measuring.
scaler->Scale(src_texture, dst_texture);
gl_->Finish();
@@ -251,4 +248,4 @@ TEST_F(GLHelperBenchmark, DISABLED_ScaleTestImage) {
gl_->DeleteFramebuffers(1, &framebuffer);
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/gl_helper_readback_support.cc b/chromium/components/viz/display_compositor/gl_helper_readback_support.cc
index b7a019beef4..5fd12924b37 100644
--- a/chromium/components/display_compositor/gl_helper_readback_support.cc
+++ b/chromium/components/viz/display_compositor/gl_helper_readback_support.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/viz/display_compositor/gl_helper_readback_support.h"
#include "base/logging.h"
-#include "components/display_compositor/gl_helper_readback_support.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "third_party/skia/include/core/SkImageInfo.h"
-namespace display_compositor {
+namespace viz {
GLHelperReadbackSupport::GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl)
: gl_(gl) {
@@ -75,7 +75,7 @@ void GLHelperReadbackSupport::GetAdditionalFormat(GLenum format,
}
const int kTestSize = 64;
- display_compositor::ScopedTexture dst_texture(gl_);
+ ScopedTexture dst_texture(gl_);
ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -169,4 +169,4 @@ GLHelperReadbackSupport::GetReadbackConfig(SkColorType color_type,
return GLHelperReadbackSupport::NOT_SUPPORTED;
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/gl_helper_readback_support.h b/chromium/components/viz/display_compositor/gl_helper_readback_support.h
index 039a2b6bec3..b68f4dd5c60 100644
--- a/chromium/components/display_compositor/gl_helper_readback_support.h
+++ b/chromium/components/viz/display_compositor/gl_helper_readback_support.h
@@ -2,23 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_READBACK_SUPPORT_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_READBACK_SUPPORT_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_READBACK_SUPPORT_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_READBACK_SUPPORT_H_
#include <stddef.h>
#include <vector>
-#include "components/display_compositor/display_compositor_export.h"
-#include "components/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper.h"
+#include "components/viz/viz_export.h"
-namespace display_compositor {
+namespace viz {
-class DISPLAY_COMPOSITOR_EXPORT GLHelperReadbackSupport {
+class VIZ_EXPORT GLHelperReadbackSupport {
public:
enum FormatSupport { SUPPORTED, SWIZZLE, NOT_SUPPORTED };
- GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl);
+ explicit GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl);
~GLHelperReadbackSupport();
@@ -71,6 +71,6 @@ class DISPLAY_COMPOSITOR_EXPORT GLHelperReadbackSupport {
std::vector<struct FormatCacheEntry> format_cache_;
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_READBACK_SUPPORT_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_READBACK_SUPPORT_H_
diff --git a/chromium/components/display_compositor/gl_helper_scaling.cc b/chromium/components/viz/display_compositor/gl_helper_scaling.cc
index ec6c057d235..9f29c3625f2 100644
--- a/chromium/components/display_compositor/gl_helper_scaling.cc
+++ b/chromium/components/viz/display_compositor/gl_helper_scaling.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/display_compositor/gl_helper_scaling.h"
+#include "components/viz/display_compositor/gl_helper_scaling.h"
#include <stddef.h>
@@ -25,7 +25,7 @@
using gpu::gles2::GLES2Interface;
-namespace display_compositor {
+namespace viz {
GLHelperScaling::GLHelperScaling(GLES2Interface* gl, GLHelper* helper)
: gl_(gl), helper_(helper), vertex_attributes_buffer_(gl_) {
@@ -878,4 +878,4 @@ void ShaderProgram::UseProgram(const gfx::Size& src_size,
gl_->Uniform4fv(color_weights_location_, 1, color_weights);
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/gl_helper_scaling.h b/chromium/components/viz/display_compositor/gl_helper_scaling.h
index a2e5b61665a..cc90617d677 100644
--- a/chromium/components/display_compositor/gl_helper_scaling.h
+++ b/chromium/components/viz/display_compositor/gl_helper_scaling.h
@@ -2,20 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_SCALING_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_SCALING_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_SCALING_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_SCALING_H_
#include <deque>
#include <map>
#include <vector>
#include "base/macros.h"
-#include "components/display_compositor/display_compositor_export.h"
-#include "components/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper.h"
+#include "components/viz/viz_export.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
-namespace display_compositor {
+namespace viz {
class ShaderProgram;
class ScalerImpl;
@@ -24,7 +24,7 @@ class GLHelperTest;
// Implements GPU texture scaling methods.
// Note that you should probably not use this class directly.
// See gl_helper.cc::CreateScaler instead.
-class DISPLAY_COMPOSITOR_EXPORT GLHelperScaling {
+class VIZ_EXPORT GLHelperScaling {
public:
enum ShaderType {
SHADER_BILINEAR,
@@ -41,7 +41,7 @@ class DISPLAY_COMPOSITOR_EXPORT GLHelperScaling {
// Similar to ScalerInterface, but can generate multiple outputs.
// Used for YUV conversion in gl_helper.c
- class DISPLAY_COMPOSITOR_EXPORT ShaderInterface {
+ class VIZ_EXPORT ShaderInterface {
public:
ShaderInterface() {}
virtual ~ShaderInterface() {}
@@ -203,6 +203,6 @@ class DISPLAY_COMPOSITOR_EXPORT GLHelperScaling {
DISALLOW_COPY_AND_ASSIGN(GLHelperScaling);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_SCALING_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_GL_HELPER_SCALING_H_
diff --git a/chromium/components/display_compositor/gl_helper_unittest.cc b/chromium/components/viz/display_compositor/gl_helper_unittest.cc
index 73a837dfd0e..6f5383f3c50 100644
--- a/chromium/components/display_compositor/gl_helper_unittest.cc
+++ b/chromium/components/viz/display_compositor/gl_helper_unittest.cc
@@ -30,9 +30,9 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
-#include "components/display_compositor/gl_helper.h"
-#include "components/display_compositor/gl_helper_readback_support.h"
-#include "components/display_compositor/gl_helper_scaling.h"
+#include "components/viz/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper_readback_support.h"
+#include "components/viz/display_compositor/gl_helper_scaling.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/ipc/gl_in_process_context.h"
@@ -41,12 +41,11 @@
#include "third_party/skia/include/core/SkTypes.h"
#include "ui/gl/gl_implementation.h"
-namespace display_compositor {
+namespace viz {
-display_compositor::GLHelper::ScalerQuality kQualities[] = {
- display_compositor::GLHelper::SCALER_QUALITY_BEST,
- display_compositor::GLHelper::SCALER_QUALITY_GOOD,
- display_compositor::GLHelper::SCALER_QUALITY_FAST,
+GLHelper::ScalerQuality kQualities[] = {
+ GLHelper::SCALER_QUALITY_BEST, GLHelper::SCALER_QUALITY_GOOD,
+ GLHelper::SCALER_QUALITY_FAST,
};
const char* kQualityNames[] = {
@@ -80,9 +79,8 @@ class GLHelperTest : public testing::Test {
gl_ = context_->GetImplementation();
gpu::ContextSupport* support = context_->GetImplementation();
- helper_.reset(new display_compositor::GLHelper(gl_, support));
- helper_scaling_.reset(
- new display_compositor::GLHelperScaling(gl_, helper_.get()));
+ helper_.reset(new GLHelper(gl_, support));
+ helper_scaling_.reset(new GLHelperScaling(gl_, helper_.get()));
}
void TearDown() override {
@@ -239,7 +237,7 @@ class GLHelperTest : public testing::Test {
// Make sure that the stages of the scaler pipeline are sane.
void ValidateScalerStages(
- display_compositor::GLHelper::ScalerQuality quality,
+ GLHelper::ScalerQuality quality,
const std::vector<GLHelperScaling::ScalerStage>& scaler_stages,
const gfx::Size& dst_size,
const std::string& message) {
@@ -289,7 +287,7 @@ class GLHelperTest : public testing::Test {
break;
case GLHelperScaling::SHADER_BILINEAR:
- if (quality != display_compositor::GLHelper::SCALER_QUALITY_FAST) {
+ if (quality != GLHelper::SCALER_QUALITY_FAST) {
x_samples = 1;
y_samples = 1;
}
@@ -335,12 +333,12 @@ class GLHelperTest : public testing::Test {
}
if (x_samples) {
- EXPECT_TRUE(CheckScale(x_scale, x_samples, scaled_x)) << "x_scale = "
- << x_scale;
+ EXPECT_TRUE(CheckScale(x_scale, x_samples, scaled_x))
+ << "x_scale = " << x_scale;
}
if (y_samples) {
- EXPECT_TRUE(CheckScale(y_scale, y_samples, scaled_y)) << "y_scale = "
- << y_scale;
+ EXPECT_TRUE(CheckScale(y_scale, y_samples, scaled_y))
+ << "y_scale = " << y_scale;
}
if (x_scale != 1.0) {
@@ -384,8 +382,8 @@ class GLHelperTest : public testing::Test {
int b = swizzle && (c == 0 || c == 2)
? Channel(other, x, y, (c + 2) & 2)
: Channel(other, x, y, c);
- EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " c=" << c
- << " " << message;
+ EXPECT_NEAR(a, b, maxdiff)
+ << " x=" << x << " y=" << y << " c=" << c << " " << message;
if (std::abs(a - b) > maxdiff) {
LOG(ERROR) << "-------expected--------";
for (int i = 0; i < bpp; i++) {
@@ -459,7 +457,7 @@ class GLHelperTest : public testing::Test {
// Very slow bicubic / bilinear scaler for reference.
void ScaleSlow(SkBitmap* input,
SkBitmap* output,
- display_compositor::GLHelper::ScalerQuality quality) {
+ GLHelper::ScalerQuality quality) {
float xscale = static_cast<float>(input->width()) / output->width();
float yscale = static_cast<float>(input->height()) / output->height();
float clamped_xscale = xscale < 1.0 ? 1.0 : 1.0 / xscale;
@@ -473,7 +471,7 @@ class GLHelperTest : public testing::Test {
float value = 0.0f;
float sum = 0.0f;
switch (quality) {
- case display_compositor::GLHelper::SCALER_QUALITY_BEST:
+ case GLHelper::SCALER_QUALITY_BEST:
for (int src_y = -10; src_y < input->height() + 10; ++src_y) {
float coeff_y =
Bicubic((src_y + 0.5f - dst_y_in_src) * clamped_yscale);
@@ -494,7 +492,7 @@ class GLHelperTest : public testing::Test {
}
break;
- case display_compositor::GLHelper::SCALER_QUALITY_GOOD: {
+ case GLHelper::SCALER_QUALITY_GOOD: {
int xshift = 0, yshift = 0;
while ((output->width() << xshift) < input->width()) {
xshift++;
@@ -521,7 +519,7 @@ class GLHelperTest : public testing::Test {
break;
}
- case display_compositor::GLHelper::SCALER_QUALITY_FAST:
+ case GLHelper::SCALER_QUALITY_FAST:
value = Bilinear(input, dst_x_in_src, dst_y_in_src, channel);
sum = 1.0;
}
@@ -553,7 +551,7 @@ class GLHelperTest : public testing::Test {
// Swaps red and blue channels in each pixel in a 32-bit bitmap.
void SwizzleSKBitmap(SkBitmap* bitmap) {
int bpp = bitmap->bytesPerPixel();
- DCHECK(bpp == 4);
+ DCHECK_EQ(bpp, 4);
for (int y = 0; y < bitmap->height(); y++) {
for (int x = 0; x < bitmap->width(); x++) {
// Swap channels 0 and 2 (red and blue)
@@ -569,9 +567,9 @@ class GLHelperTest : public testing::Test {
// in the reference implementation too.
void ScaleSlowRecursive(SkBitmap* input,
SkBitmap* output,
- display_compositor::GLHelper::ScalerQuality quality) {
- if (quality == display_compositor::GLHelper::SCALER_QUALITY_FAST ||
- quality == display_compositor::GLHelper::SCALER_QUALITY_GOOD) {
+ GLHelper::ScalerQuality quality) {
+ if (quality == GLHelper::SCALER_QUALITY_FAST ||
+ quality == GLHelper::SCALER_QUALITY_GOOD) {
ScaleSlow(input, output, quality);
return;
}
@@ -736,7 +734,6 @@ class GLHelperTest : public testing::Test {
}
// Now compare the results.
- SkAutoLockPixels lock_input(truth_pixels);
const std::vector<GLHelperScaling::ScalerStage> dummy_stages;
Compare(&truth_pixels, &output_pixels, 2, input_pixels.get(), dummy_stages,
message + " comparing against transformed/scaled");
@@ -841,7 +838,7 @@ class GLHelperTest : public testing::Test {
// Create a scaling pipeline and make sure that the steps
// are exactly the steps we expect.
- void CheckPipeline(display_compositor::GLHelper::ScalerQuality quality,
+ void CheckPipeline(GLHelper::ScalerQuality quality,
int xsize,
int ysize,
int dst_xsize,
@@ -851,8 +848,8 @@ class GLHelperTest : public testing::Test {
helper_scaling_->ComputeScalerStages(
quality, gfx::Size(xsize, ysize), gfx::Rect(0, 0, xsize, ysize),
gfx::Size(dst_xsize, dst_ysize), false, false, &stages);
- ValidateScalerStages(display_compositor::GLHelper::SCALER_QUALITY_GOOD,
- stages, gfx::Size(dst_xsize, dst_ysize), "");
+ ValidateScalerStages(GLHelper::SCALER_QUALITY_GOOD, stages,
+ gfx::Size(dst_xsize, dst_ysize), "");
EXPECT_EQ(PrintStages(stages), description);
}
@@ -867,7 +864,7 @@ class GLHelperTest : public testing::Test {
SkColor grid_color,
int grid_pitch,
int grid_width,
- SkBitmap& bmp) {
+ const SkBitmap& bmp) {
ASSERT_GT(grid_pitch, 0);
ASSERT_GT(grid_width, 0);
ASSERT_NE(background_color, grid_color);
@@ -894,7 +891,7 @@ class GLHelperTest : public testing::Test {
SkColor color2,
int rect_w,
int rect_h,
- SkBitmap& bmp) {
+ const SkBitmap& bmp) {
ASSERT_GT(rect_w, 0);
ASSERT_GT(rect_h, 0);
ASSERT_NE(color1, color2);
@@ -961,8 +958,6 @@ class GLHelperTest : public testing::Test {
if (bmp1.colorType() != bmp2.colorType())
return false;
- SkAutoLockPixels lock1(bmp1);
- SkAutoLockPixels lock2(bmp2);
if (!bmp1.getPixels() || !bmp2.getPixels()) {
LOG(ERROR) << "Empty Bitmap!";
return false;
@@ -1129,14 +1124,13 @@ class GLHelperTest : public testing::Test {
const std::string& description) {
std::vector<GLHelperScaling::ScalerStage> stages;
helper_scaling_->ConvertScalerOpsToScalerStages(
- display_compositor::GLHelper::SCALER_QUALITY_GOOD,
- gfx::Size(xsize, ysize), gfx::Rect(0, 0, xsize, ysize),
- gfx::Size(dst_xsize, dst_ysize), false, false, &x_ops_, &y_ops_,
- &stages);
+ GLHelper::SCALER_QUALITY_GOOD, gfx::Size(xsize, ysize),
+ gfx::Rect(0, 0, xsize, ysize), gfx::Size(dst_xsize, dst_ysize), false,
+ false, &x_ops_, &y_ops_, &stages);
EXPECT_EQ(x_ops_.size(), 0U);
EXPECT_EQ(y_ops_.size(), 0U);
- ValidateScalerStages(display_compositor::GLHelper::SCALER_QUALITY_GOOD,
- stages, gfx::Size(dst_xsize, dst_ysize), "");
+ ValidateScalerStages(GLHelper::SCALER_QUALITY_GOOD, stages,
+ gfx::Size(dst_xsize, dst_ysize), "");
EXPECT_EQ(PrintStages(stages), description);
}
@@ -1259,8 +1253,8 @@ class GLHelperTest : public testing::Test {
std::unique_ptr<gpu::GLInProcessContext> context_;
gpu::gles2::GLES2Interface* gl_;
- std::unique_ptr<display_compositor::GLHelper> helper_;
- std::unique_ptr<display_compositor::GLHelperScaling> helper_scaling_;
+ std::unique_ptr<GLHelper> helper_;
+ std::unique_ptr<GLHelperScaling> helper_scaling_;
std::deque<GLHelperScaling::ScaleOp> x_ops_, y_ops_;
base::MessageLoop message_loop_;
};
@@ -1401,15 +1395,14 @@ TEST_F(GLHelperTest, ValidateScalerPipelines) {
// for a few common use cases.
TEST_F(GLHelperTest, CheckSpecificPipelines) {
// Upscale should be single pass.
- CheckPipeline(display_compositor::GLHelper::SCALER_QUALITY_GOOD, 1024, 700,
- 1280, 720, "1024x700 -> 1280x720 bilinear\n");
+ CheckPipeline(GLHelper::SCALER_QUALITY_GOOD, 1024, 700, 1280, 720,
+ "1024x700 -> 1280x720 bilinear\n");
// Slight downscale should use BILINEAR2X2.
- CheckPipeline(display_compositor::GLHelper::SCALER_QUALITY_GOOD, 1280, 720,
- 1024, 700, "1280x720 -> 1024x700 bilinear2x2\n");
+ CheckPipeline(GLHelper::SCALER_QUALITY_GOOD, 1280, 720, 1024, 700,
+ "1280x720 -> 1024x700 bilinear2x2\n");
// Most common tab capture pipeline on the Pixel.
// Should be using two BILINEAR3 passes.
- CheckPipeline(display_compositor::GLHelper::SCALER_QUALITY_GOOD, 2560, 1476,
- 1249, 720,
+ CheckPipeline(GLHelper::SCALER_QUALITY_GOOD, 2560, 1476, 1249, 720,
"2560x1476 -> 2560x720 bilinear3 Y\n"
"2560x720 -> 1249x720 bilinear3 X\n");
}
@@ -1434,4 +1427,4 @@ TEST_F(GLHelperTest, CheckOptimizations) {
CheckOptimizationsTest();
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/host_shared_bitmap_manager.cc b/chromium/components/viz/display_compositor/host_shared_bitmap_manager.cc
index cd914f54084..d781c9439cb 100644
--- a/chromium/components/display_compositor/host_shared_bitmap_manager.cc
+++ b/chromium/components/viz/display_compositor/host_shared_bitmap_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/display_compositor/host_shared_bitmap_manager.h"
+#include "components/viz/display_compositor/host_shared_bitmap_manager.h"
#include <stdint.h>
@@ -19,7 +19,7 @@
#include "mojo/public/cpp/system/platform_handle.h"
#include "ui/gfx/geometry/size.h"
-namespace display_compositor {
+namespace viz {
class BitmapData : public base::RefCountedThreadSafe<BitmapData> {
public:
@@ -86,19 +86,6 @@ void HostSharedBitmapManagerClient::DidAllocateSharedBitmap(
this->ChildAllocatedSharedBitmap(size, memory_handle, id);
}
-void HostSharedBitmapManagerClient::AllocateSharedBitmapForChild(
- base::ProcessHandle process_handle,
- size_t buffer_size,
- const cc::SharedBitmapId& id,
- base::SharedMemoryHandle* shared_memory_handle) {
- manager_->AllocateSharedBitmapForChild(process_handle, buffer_size, id,
- shared_memory_handle);
- if (*shared_memory_handle != base::SharedMemory::NULLHandle()) {
- base::AutoLock lock(lock_);
- owned_bitmaps_.insert(id);
- }
-}
-
void HostSharedBitmapManagerClient::ChildAllocatedSharedBitmap(
size_t buffer_size,
const base::SharedMemoryHandle& handle,
@@ -132,7 +119,7 @@ std::unique_ptr<cc::SharedBitmap> HostSharedBitmapManager::AllocateSharedBitmap(
base::AutoLock lock(lock_);
size_t bitmap_size;
if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size))
- return std::unique_ptr<cc::SharedBitmap>();
+ return nullptr;
scoped_refptr<BitmapData> data(new BitmapData(bitmap_size));
// Bitmaps allocated in host don't need to be shared to other processes, so
@@ -150,21 +137,21 @@ HostSharedBitmapManager::GetSharedBitmapFromId(const gfx::Size& size,
base::AutoLock lock(lock_);
BitmapMap::iterator it = handle_map_.find(id);
if (it == handle_map_.end())
- return std::unique_ptr<cc::SharedBitmap>();
+ return nullptr;
BitmapData* data = it->second.get();
size_t bitmap_size;
if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) ||
bitmap_size > data->buffer_size)
- return std::unique_ptr<cc::SharedBitmap>();
+ return nullptr;
if (data->pixels) {
return base::MakeUnique<HostSharedBitmap>(data->pixels.get(), data, id,
nullptr);
}
if (!data->memory->memory()) {
- return std::unique_ptr<cc::SharedBitmap>();
+ return nullptr;
}
return base::MakeUnique<HostSharedBitmap>(
@@ -215,35 +202,6 @@ bool HostSharedBitmapManager::ChildAllocatedSharedBitmap(
return true;
}
-void HostSharedBitmapManager::AllocateSharedBitmapForChild(
- base::ProcessHandle process_handle,
- size_t buffer_size,
- const cc::SharedBitmapId& id,
- base::SharedMemoryHandle* shared_memory_handle) {
- base::AutoLock lock(lock_);
- if (handle_map_.find(id) != handle_map_.end()) {
- *shared_memory_handle = base::SharedMemory::NULLHandle();
- return;
- }
- std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
- if (!shared_memory->CreateAndMapAnonymous(buffer_size)) {
- LOG(ERROR) << "Cannot create shared memory buffer";
- *shared_memory_handle = base::SharedMemory::NULLHandle();
- return;
- }
-
- scoped_refptr<BitmapData> data(new BitmapData(buffer_size));
- data->memory = std::move(shared_memory);
-
- handle_map_[id] = data;
- if (!data->memory->ShareToProcess(process_handle, shared_memory_handle)) {
- LOG(ERROR) << "Cannot share shared memory buffer";
- *shared_memory_handle = base::SharedMemory::NULLHandle();
- return;
- }
- data->memory->Close();
-}
-
void HostSharedBitmapManager::ChildDeletedSharedBitmap(
const cc::SharedBitmapId& id) {
base::AutoLock lock(lock_);
@@ -261,4 +219,4 @@ void HostSharedBitmapManager::FreeSharedMemoryFromMap(
handle_map_.erase(id);
}
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/display_compositor/host_shared_bitmap_manager.h b/chromium/components/viz/display_compositor/host_shared_bitmap_manager.h
index 05706c33759..b64b89ba3a6 100644
--- a/chromium/components/display_compositor/host_shared_bitmap_manager.h
+++ b/chromium/components/viz/display_compositor/host_shared_bitmap_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_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_
-#define COMPONENTS_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_
+#ifndef COMPONENTS_VIZ_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_
+#define COMPONENTS_VIZ_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_
#include <stddef.h>
@@ -20,7 +20,7 @@
#include "base/trace_event/memory_dump_provider.h"
#include "cc/ipc/shared_bitmap_manager.mojom.h"
#include "cc/resources/shared_bitmap_manager.h"
-#include "components/display_compositor/display_compositor_export.h"
+#include "components/viz/viz_export.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
namespace BASE_HASH_NAMESPACE {
@@ -32,11 +32,11 @@ struct hash<cc::SharedBitmapId> {
};
} // namespace BASE_HASH_NAMESPACE
-namespace display_compositor {
+namespace viz {
class BitmapData;
class HostSharedBitmapManager;
-class DISPLAY_COMPOSITOR_EXPORT HostSharedBitmapManagerClient
+class VIZ_EXPORT HostSharedBitmapManagerClient
: NON_EXPORTED_BASE(public cc::mojom::SharedBitmapManager) {
public:
explicit HostSharedBitmapManagerClient(HostSharedBitmapManager* manager);
@@ -50,11 +50,6 @@ class DISPLAY_COMPOSITOR_EXPORT HostSharedBitmapManagerClient
const cc::SharedBitmapId& id) override;
void DidDeleteSharedBitmap(const cc::SharedBitmapId& id) override;
- void AllocateSharedBitmapForChild(
- base::ProcessHandle process_handle,
- size_t buffer_size,
- const cc::SharedBitmapId& id,
- base::SharedMemoryHandle* shared_memory_handle);
void ChildAllocatedSharedBitmap(size_t buffer_size,
const base::SharedMemoryHandle& handle,
const cc::SharedBitmapId& id);
@@ -70,7 +65,7 @@ class DISPLAY_COMPOSITOR_EXPORT HostSharedBitmapManagerClient
DISALLOW_COPY_AND_ASSIGN(HostSharedBitmapManagerClient);
};
-class DISPLAY_COMPOSITOR_EXPORT HostSharedBitmapManager
+class VIZ_EXPORT HostSharedBitmapManager
: public cc::SharedBitmapManager,
public base::trace_event::MemoryDumpProvider {
public:
@@ -97,11 +92,6 @@ class DISPLAY_COMPOSITOR_EXPORT HostSharedBitmapManager
private:
friend class HostSharedBitmapManagerClient;
- void AllocateSharedBitmapForChild(
- base::ProcessHandle process_handle,
- size_t buffer_size,
- const cc::SharedBitmapId& id,
- base::SharedMemoryHandle* shared_memory_handle);
bool ChildAllocatedSharedBitmap(size_t buffer_size,
const base::SharedMemoryHandle& handle,
const cc::SharedBitmapId& id);
@@ -116,6 +106,6 @@ class DISPLAY_COMPOSITOR_EXPORT HostSharedBitmapManager
DISALLOW_COPY_AND_ASSIGN(HostSharedBitmapManager);
};
-} // namespace display_compositor
+} // namespace viz
-#endif // COMPONENTS_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_
+#endif // COMPONENTS_VIZ_DISPLAY_COMPOSITOR_HOST_SHARED_BITMAP_MANAGER_H_
diff --git a/chromium/components/display_compositor/host_shared_bitmap_manager_unittest.cc b/chromium/components/viz/display_compositor/host_shared_bitmap_manager_unittest.cc
index e3ea52419fa..ee7a92f1ab8 100644
--- a/chromium/components/display_compositor/host_shared_bitmap_manager_unittest.cc
+++ b/chromium/components/viz/display_compositor/host_shared_bitmap_manager_unittest.cc
@@ -5,10 +5,10 @@
#include <stddef.h>
#include <string.h>
-#include "components/display_compositor/host_shared_bitmap_manager.h"
+#include "components/viz/display_compositor/host_shared_bitmap_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace display_compositor {
+namespace viz {
namespace {
class HostSharedBitmapManagerTest : public testing::Test {
@@ -27,8 +27,7 @@ TEST_F(HostSharedBitmapManagerTest, TestCreate) {
cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
HostSharedBitmapManagerClient client(manager_.get());
- base::SharedMemoryHandle handle;
- bitmap->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
+ base::SharedMemoryHandle handle = bitmap->handle().Duplicate();
client.ChildAllocatedSharedBitmap(size_in_bytes, handle, id);
std::unique_ptr<cc::SharedBitmap> large_bitmap;
@@ -76,31 +75,6 @@ TEST_F(HostSharedBitmapManagerTest, TestCreate) {
shared_bitmap.reset();
}
-TEST_F(HostSharedBitmapManagerTest, TestCreateForChild) {
- gfx::Size bitmap_size(1, 1);
- size_t size_in_bytes;
- EXPECT_TRUE(cc::SharedBitmap::SizeInBytes(bitmap_size, &size_in_bytes));
- cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
- HostSharedBitmapManagerClient client(manager_.get());
- base::SharedMemoryHandle handle;
- client.AllocateSharedBitmapForChild(base::GetCurrentProcessHandle(),
- size_in_bytes, id, &handle);
-
- EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle));
- std::unique_ptr<base::SharedMemory> bitmap(
- new base::SharedMemory(handle, false));
- EXPECT_TRUE(bitmap->Map(size_in_bytes));
- memset(bitmap->memory(), 0xff, size_in_bytes);
-
- std::unique_ptr<cc::SharedBitmap> shared_bitmap;
- shared_bitmap = manager_->GetSharedBitmapFromId(bitmap_size, id);
- EXPECT_TRUE(shared_bitmap);
- EXPECT_TRUE(
- memcmp(bitmap->memory(), shared_bitmap->pixels(), size_in_bytes) == 0);
-
- client.DidDeleteSharedBitmap(id);
-}
-
TEST_F(HostSharedBitmapManagerTest, RemoveProcess) {
gfx::Size bitmap_size(1, 1);
size_t size_in_bytes;
@@ -110,10 +84,9 @@ TEST_F(HostSharedBitmapManagerTest, RemoveProcess) {
memset(bitmap->memory(), 0xff, size_in_bytes);
cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
- base::SharedMemoryHandle handle;
std::unique_ptr<HostSharedBitmapManagerClient> client(
new HostSharedBitmapManagerClient(manager_.get()));
- bitmap->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
+ base::SharedMemoryHandle handle = bitmap->handle().Duplicate();
client->ChildAllocatedSharedBitmap(size_in_bytes, handle, id);
std::unique_ptr<cc::SharedBitmap> shared_bitmap;
@@ -143,8 +116,7 @@ TEST_F(HostSharedBitmapManagerTest, AddDuplicate) {
cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
HostSharedBitmapManagerClient client(manager_.get());
- base::SharedMemoryHandle handle;
- bitmap->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
+ base::SharedMemoryHandle handle = bitmap->handle().Duplicate();
client.ChildAllocatedSharedBitmap(size_in_bytes, handle, id);
std::unique_ptr<base::SharedMemory> bitmap2(new base::SharedMemory());
@@ -162,4 +134,4 @@ TEST_F(HostSharedBitmapManagerTest, AddDuplicate) {
}
} // namespace
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/viz/display_compositor/run_all_unittests.cc b/chromium/components/viz/display_compositor/run_all_unittests.cc
new file mode 100644
index 00000000000..80336af2172
--- /dev/null
+++ b/chromium/components/viz/display_compositor/run_all_unittests.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2012 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 "base/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "components/viz/display_compositor/display_compositor_test_suite.h"
+
+int main(int argc, char** argv) {
+ viz::DisplayCompositorTestSuite test_suite(argc, argv);
+
+ return base::LaunchUnitTests(argc, argv,
+ base::Bind(&viz::DisplayCompositorTestSuite::Run,
+ base::Unretained(&test_suite)));
+}
diff --git a/chromium/components/display_compositor/yuv_readback_unittest.cc b/chromium/components/viz/display_compositor/yuv_readback_unittest.cc
index bda67318c25..ef6d83bd758 100644
--- a/chromium/components/display_compositor/yuv_readback_unittest.cc
+++ b/chromium/components/viz/display_compositor/yuv_readback_unittest.cc
@@ -11,7 +11,7 @@
#include "base/test/test_suite.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
-#include "components/display_compositor/gl_helper.h"
+#include "components/viz/display_compositor/gl_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/ipc/common/surface_handle.h"
@@ -22,7 +22,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gl/gl_implementation.h"
-namespace display_compositor {
+namespace viz {
namespace {
int kYUVReadbackSizes[] = {2, 4, 14};
@@ -55,7 +55,7 @@ class YUVReadbackTest : public testing::Test {
gl_ = context_->GetImplementation();
gpu::ContextSupport* support = context_->GetImplementation();
- helper_.reset(new display_compositor::GLHelper(gl_, support));
+ helper_.reset(new GLHelper(gl_, support));
}
void TearDown() override {
@@ -284,8 +284,8 @@ class YUVReadbackTest : public testing::Test {
for (int y = 0; y < ysize; y++) {
int a = other[y * other_stride + x];
int b = truth[y * truth_stride + x];
- EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " "
- << message;
+ EXPECT_NEAR(a, b, maxdiff)
+ << " x=" << x << " y=" << y << " " << message;
if (std::abs(a - b) > maxdiff) {
LOG(ERROR) << "-------expected--------";
PrintPlane(truth, xsize, truth_stride, ysize);
@@ -317,7 +317,7 @@ class YUVReadbackTest : public testing::Test {
int test_pattern,
bool flip,
bool use_mrt,
- display_compositor::GLHelper::ScalerQuality quality) {
+ GLHelper::ScalerQuality quality) {
GLuint src_texture;
gl_->GenTextures(1, &src_texture);
SkBitmap input_pixels;
@@ -475,7 +475,7 @@ class YUVReadbackTest : public testing::Test {
std::unique_ptr<gpu::GLInProcessContext> context_;
gpu::gles2::GLES2Interface* gl_;
- std::unique_ptr<display_compositor::GLHelper> helper_;
+ std::unique_ptr<GLHelper> helper_;
gl::DisableNullDrawGLBindings enable_pixel_output_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
};
@@ -487,7 +487,7 @@ TEST_F(YUVReadbackTest, YUVReadbackOptTest) {
"gpu.service") "," TRACE_DISABLED_BY_DEFAULT("gpu_decoder"));
TestYUVReadback(800, 400, 800, 400, 0, 0, 1, false, true,
- display_compositor::GLHelper::SCALER_QUALITY_FAST);
+ GLHelper::SCALER_QUALITY_FAST);
std::map<std::string, int> event_counts;
EndTracing(&event_counts);
@@ -534,8 +534,7 @@ TEST_P(YUVReadbackPixelTest, Test) {
kYUVReadbackSizes[ox], kYUVReadbackSizes[oy],
compute_margin(kYUVReadbackSizes[x], kYUVReadbackSizes[ox], xm),
compute_margin(kYUVReadbackSizes[y], kYUVReadbackSizes[oy], ym),
- pattern, flip, use_mrt,
- display_compositor::GLHelper::SCALER_QUALITY_GOOD);
+ pattern, flip, use_mrt, GLHelper::SCALER_QUALITY_GOOD);
if (HasFailure()) {
return;
}
@@ -556,4 +555,4 @@ INSTANTIATE_TEST_CASE_P(
::testing::Range<unsigned int>(0, arraysize(kYUVReadbackSizes)),
::testing::Range<unsigned int>(0, arraysize(kYUVReadbackSizes))));
-} // namespace display_compositor
+} // namespace viz
diff --git a/chromium/components/viz/frame_sinks/BUILD.gn b/chromium/components/viz/frame_sinks/BUILD.gn
index 750e684d93d..386ec2f6ef8 100644
--- a/chromium/components/viz/frame_sinks/BUILD.gn
+++ b/chromium/components/viz/frame_sinks/BUILD.gn
@@ -2,9 +2,15 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-source_set("frame_sinks") {
+component("frame_sinks") {
+ defines = [ "VIZ_IMPLEMENTATION" ]
+
sources = [
"display_provider.h",
+ "frame_eviction_manager.cc",
+ "frame_eviction_manager.h",
+ "frame_evictor.cc",
+ "frame_evictor.h",
"gpu_compositor_frame_sink.cc",
"gpu_compositor_frame_sink.h",
"gpu_compositor_frame_sink_delegate.h",
@@ -19,7 +25,11 @@ source_set("frame_sinks") {
"//cc",
"//cc/ipc:interfaces",
"//cc/surfaces",
- "//components/display_compositor",
+ "//components/viz/display_compositor",
"//gpu/ipc:command_buffer",
]
+
+ if (is_win) {
+ cflags = [ "/wd4267" ] # conversion from 'size_t' to 'int' on x64 (crbug.com/633312)
+ }
}
diff --git a/chromium/components/viz/frame_sinks/DEPS b/chromium/components/viz/frame_sinks/DEPS
index fc0222f9b78..2628c703220 100644
--- a/chromium/components/viz/frame_sinks/DEPS
+++ b/chromium/components/viz/frame_sinks/DEPS
@@ -3,4 +3,5 @@ include_rules = [
"+cc/ipc",
"+cc/surfaces",
"+cc/scheduler",
+ "+components/viz/display_compositor",
]
diff --git a/chromium/components/viz/frame_sinks/frame_eviction_manager.cc b/chromium/components/viz/frame_sinks/frame_eviction_manager.cc
new file mode 100644
index 00000000000..be419fd3197
--- /dev/null
+++ b/chromium/components/viz/frame_sinks/frame_eviction_manager.cc
@@ -0,0 +1,179 @@
+// Copyright 2017 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/viz/frame_sinks/frame_eviction_manager.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/memory_coordinator_client_registry.h"
+#include "base/memory/memory_coordinator_proxy.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/memory/memory_pressure_monitor.h"
+#include "base/memory/shared_memory.h"
+#include "base/sys_info.h"
+#include "build/build_config.h"
+#include "components/viz/display_compositor/host_shared_bitmap_manager.h"
+
+namespace viz {
+namespace {
+
+const int kModeratePressurePercentage = 50;
+const int kCriticalPressurePercentage = 10;
+
+} // namespace
+
+FrameEvictionManager* FrameEvictionManager::GetInstance() {
+ return base::Singleton<FrameEvictionManager>::get();
+}
+
+void FrameEvictionManager::AddFrame(FrameEvictionManagerClient* frame,
+ bool locked) {
+ RemoveFrame(frame);
+ if (locked)
+ locked_frames_[frame] = 1;
+ else
+ unlocked_frames_.push_front(frame);
+ CullUnlockedFrames(GetMaxNumberOfSavedFrames());
+}
+
+void FrameEvictionManager::RemoveFrame(FrameEvictionManagerClient* frame) {
+ std::map<FrameEvictionManagerClient*, size_t>::iterator locked_iter =
+ locked_frames_.find(frame);
+ if (locked_iter != locked_frames_.end())
+ locked_frames_.erase(locked_iter);
+ unlocked_frames_.remove(frame);
+}
+
+void FrameEvictionManager::LockFrame(FrameEvictionManagerClient* frame) {
+ std::list<FrameEvictionManagerClient*>::iterator unlocked_iter =
+ std::find(unlocked_frames_.begin(), unlocked_frames_.end(), frame);
+ if (unlocked_iter != unlocked_frames_.end()) {
+ DCHECK(locked_frames_.find(frame) == locked_frames_.end());
+ unlocked_frames_.remove(frame);
+ locked_frames_[frame] = 1;
+ } else {
+ DCHECK(locked_frames_.find(frame) != locked_frames_.end());
+ locked_frames_[frame]++;
+ }
+}
+
+void FrameEvictionManager::UnlockFrame(FrameEvictionManagerClient* frame) {
+ DCHECK(locked_frames_.find(frame) != locked_frames_.end());
+ size_t locked_count = locked_frames_[frame];
+ DCHECK(locked_count);
+ if (locked_count > 1) {
+ locked_frames_[frame]--;
+ } else {
+ RemoveFrame(frame);
+ unlocked_frames_.push_front(frame);
+ CullUnlockedFrames(GetMaxNumberOfSavedFrames());
+ }
+}
+
+size_t FrameEvictionManager::GetMaxNumberOfSavedFrames() const {
+ int percentage = 100;
+ auto* memory_coordinator_proxy = base::MemoryCoordinatorProxy::GetInstance();
+ if (memory_coordinator_proxy) {
+ switch (memory_coordinator_proxy->GetCurrentMemoryState()) {
+ case base::MemoryState::NORMAL:
+ percentage = 100;
+ break;
+ case base::MemoryState::THROTTLED:
+ percentage = kCriticalPressurePercentage;
+ break;
+ case base::MemoryState::SUSPENDED:
+ case base::MemoryState::UNKNOWN:
+ NOTREACHED();
+ break;
+ }
+ } else {
+ base::MemoryPressureMonitor* monitor = base::MemoryPressureMonitor::Get();
+
+ if (!monitor)
+ return max_number_of_saved_frames_;
+
+ // Until we have a global OnMemoryPressureChanged event we need to query the
+ // value from our specific pressure monitor.
+ switch (monitor->GetCurrentPressureLevel()) {
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+ percentage = 100;
+ break;
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+ percentage = kModeratePressurePercentage;
+ break;
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+ percentage = kCriticalPressurePercentage;
+ break;
+ }
+ }
+ size_t frames = (max_number_of_saved_frames_ * percentage) / 100;
+ return std::max(static_cast<size_t>(1), frames);
+}
+
+FrameEvictionManager::FrameEvictionManager()
+ : memory_pressure_listener_(new base::MemoryPressureListener(
+ base::Bind(&FrameEvictionManager::OnMemoryPressure,
+ base::Unretained(this)))) {
+ base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
+ max_number_of_saved_frames_ =
+#if defined(OS_ANDROID)
+ // If the amount of memory on the device is >= 3.5 GB, save up to 5
+ // frames.
+ base::SysInfo::AmountOfPhysicalMemoryMB() < 1024 * 3.5f ? 1 : 5;
+#else
+ std::min(5, 2 + (base::SysInfo::AmountOfPhysicalMemoryMB() / 256));
+#endif
+ max_handles_ = base::SharedMemory::GetHandleLimit() / 8.0f;
+}
+
+FrameEvictionManager::~FrameEvictionManager() {}
+
+void FrameEvictionManager::CullUnlockedFrames(size_t saved_frame_limit) {
+ if (unlocked_frames_.size() + locked_frames_.size() > 0) {
+ float handles_per_frame =
+ HostSharedBitmapManager::current()->AllocatedBitmapCount() * 1.0f /
+ (unlocked_frames_.size() + locked_frames_.size());
+
+ saved_frame_limit = std::max(
+ 1, static_cast<int>(std::min(static_cast<float>(saved_frame_limit),
+ max_handles_ / handles_per_frame)));
+ }
+ while (!unlocked_frames_.empty() &&
+ unlocked_frames_.size() + locked_frames_.size() > saved_frame_limit) {
+ size_t old_size = unlocked_frames_.size();
+ // Should remove self from list.
+ unlocked_frames_.back()->EvictCurrentFrame();
+ DCHECK_EQ(unlocked_frames_.size() + 1, old_size);
+ }
+}
+
+void FrameEvictionManager::OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
+ switch (memory_pressure_level) {
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+ PurgeMemory(kModeratePressurePercentage);
+ break;
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+ PurgeMemory(kCriticalPressurePercentage);
+ break;
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+ // No need to change anything when there is no pressure.
+ return;
+ }
+}
+
+void FrameEvictionManager::OnPurgeMemory() {
+ PurgeMemory(kCriticalPressurePercentage);
+}
+
+void FrameEvictionManager::PurgeMemory(int percentage) {
+ int saved_frame_limit = max_number_of_saved_frames_;
+ if (saved_frame_limit <= 1)
+ return;
+ CullUnlockedFrames(std::max(1, (saved_frame_limit * percentage) / 100));
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/frame_sinks/frame_eviction_manager.h b/chromium/components/viz/frame_sinks/frame_eviction_manager.h
new file mode 100644
index 00000000000..15a2909ffd7
--- /dev/null
+++ b/chromium/components/viz/frame_sinks/frame_eviction_manager.h
@@ -0,0 +1,82 @@
+// Copyright 2017 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_VIZ_FRAME_SINKS_FRAME_EVICTION_MANAGER_H_
+#define COMPONENTS_VIZ_FRAME_SINKS_FRAME_EVICTION_MANAGER_H_
+
+#include <stddef.h>
+
+#include <list>
+#include <map>
+
+#include "base/macros.h"
+#include "base/memory/memory_coordinator_client.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/memory/singleton.h"
+#include "components/viz/viz_export.h"
+
+namespace viz {
+
+class VIZ_EXPORT FrameEvictionManagerClient {
+ public:
+ virtual ~FrameEvictionManagerClient() {}
+ virtual void EvictCurrentFrame() = 0;
+};
+
+// This class is responsible for globally managing which renderers keep their
+// compositor frame when offscreen. We actively discard compositor frames for
+// offscreen tabs, but keep a minimum amount, as an LRU cache, to make switching
+// between a small set of tabs faster. The limit is a soft limit, because
+// clients can lock their frame to prevent it from being discarded, e.g. if the
+// tab is visible, or while capturing a screenshot.
+class VIZ_EXPORT FrameEvictionManager : public base::MemoryCoordinatorClient {
+ public:
+ static FrameEvictionManager* GetInstance();
+
+ void AddFrame(FrameEvictionManagerClient*, bool locked);
+ void RemoveFrame(FrameEvictionManagerClient*);
+ void LockFrame(FrameEvictionManagerClient*);
+ void UnlockFrame(FrameEvictionManagerClient*);
+
+ size_t GetMaxNumberOfSavedFrames() const;
+
+ // For testing only
+ void set_max_number_of_saved_frames(size_t max_number_of_saved_frames) {
+ max_number_of_saved_frames_ = max_number_of_saved_frames;
+ }
+ void set_max_handles(float max_handles) { max_handles_ = max_handles; }
+
+ // React on memory pressure events to adjust the number of cached frames.
+ // Please make this private when crbug.com/443824 has been fixed.
+ void OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
+
+ private:
+ FrameEvictionManager();
+ ~FrameEvictionManager() override;
+
+ // base::MemoryCoordinatorClient implementation:
+ void OnPurgeMemory() override;
+
+ void CullUnlockedFrames(size_t saved_frame_limit);
+
+ void PurgeMemory(int percentage);
+
+ friend struct base::DefaultSingletonTraits<FrameEvictionManager>;
+
+ // Listens for system under pressure notifications and adjusts number of
+ // cached frames accordingly.
+ std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+
+ std::map<FrameEvictionManagerClient*, size_t> locked_frames_;
+ std::list<FrameEvictionManagerClient*> unlocked_frames_;
+ size_t max_number_of_saved_frames_;
+ float max_handles_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameEvictionManager);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_FRAME_SINKS_FRAME_EVICTION_MANAGER_H_
diff --git a/chromium/components/viz/frame_sinks/frame_evictor.cc b/chromium/components/viz/frame_sinks/frame_evictor.cc
new file mode 100644
index 00000000000..0207423adce
--- /dev/null
+++ b/chromium/components/viz/frame_sinks/frame_evictor.cc
@@ -0,0 +1,56 @@
+// Copyright 2017 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/viz/frame_sinks/frame_evictor.h"
+
+#include "base/logging.h"
+
+namespace viz {
+
+FrameEvictor::FrameEvictor(FrameEvictorClient* client)
+ : client_(client), has_frame_(false), visible_(false) {}
+
+FrameEvictor::~FrameEvictor() {
+ DiscardedFrame();
+}
+
+void FrameEvictor::SwappedFrame(bool visible) {
+ visible_ = visible;
+ has_frame_ = true;
+ FrameEvictionManager::GetInstance()->AddFrame(this, visible);
+}
+
+void FrameEvictor::DiscardedFrame() {
+ FrameEvictionManager::GetInstance()->RemoveFrame(this);
+ has_frame_ = false;
+}
+
+void FrameEvictor::SetVisible(bool visible) {
+ if (visible_ == visible)
+ return;
+ visible_ = visible;
+ if (has_frame_) {
+ if (visible) {
+ LockFrame();
+ } else {
+ UnlockFrame();
+ }
+ }
+}
+
+void FrameEvictor::LockFrame() {
+ DCHECK(has_frame_);
+ FrameEvictionManager::GetInstance()->LockFrame(this);
+}
+
+void FrameEvictor::UnlockFrame() {
+ DCHECK(has_frame_);
+ FrameEvictionManager::GetInstance()->UnlockFrame(this);
+}
+
+void FrameEvictor::EvictCurrentFrame() {
+ client_->EvictDelegatedFrame();
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/frame_sinks/frame_evictor.h b/chromium/components/viz/frame_sinks/frame_evictor.h
new file mode 100644
index 00000000000..f7e5b0d0504
--- /dev/null
+++ b/chromium/components/viz/frame_sinks/frame_evictor.h
@@ -0,0 +1,46 @@
+// Copyright 2017 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_VIZ_FRAME_SINKS_FRAME_EVICTOR_H_
+#define COMPONENTS_VIZ_FRAME_SINKS_FRAME_EVICTOR_H_
+
+#include "base/macros.h"
+#include "components/viz/frame_sinks/frame_eviction_manager.h"
+#include "components/viz/viz_export.h"
+
+namespace viz {
+
+class VIZ_EXPORT FrameEvictorClient {
+ public:
+ virtual ~FrameEvictorClient() {}
+ virtual void EvictDelegatedFrame() = 0;
+};
+
+class VIZ_EXPORT FrameEvictor : public FrameEvictionManagerClient {
+ public:
+ // |client| must outlive |this|.
+ explicit FrameEvictor(FrameEvictorClient* client);
+ ~FrameEvictor() override;
+
+ void SwappedFrame(bool visible);
+ void DiscardedFrame();
+ void SetVisible(bool visible);
+ void LockFrame();
+ void UnlockFrame();
+ bool HasFrame() { return has_frame_; }
+
+ private:
+ // FrameEvictionManagerClient implementation.
+ void EvictCurrentFrame() override;
+
+ FrameEvictorClient* client_;
+ bool has_frame_;
+ bool visible_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameEvictor);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_FRAME_SINKS_FRAME_EVICTOR_H_
diff --git a/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.cc b/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.cc
index 683374f88fb..a2b6007c19c 100644
--- a/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.cc
+++ b/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.cc
@@ -36,8 +36,8 @@ GpuCompositorFrameSink::GpuCompositorFrameSink(
GpuCompositorFrameSink::~GpuCompositorFrameSink() {}
-void GpuCompositorFrameSink::EvictFrame() {
- support_->EvictFrame();
+void GpuCompositorFrameSink::EvictCurrentSurface() {
+ support_->EvictCurrentSurface();
}
void GpuCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) {
@@ -47,12 +47,15 @@ void GpuCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) {
void GpuCompositorFrameSink::SubmitCompositorFrame(
const cc::LocalSurfaceId& local_surface_id,
cc::CompositorFrame frame) {
- support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+ if (!support_->SubmitCompositorFrame(local_surface_id, std::move(frame))) {
+ compositor_frame_sink_binding_.Close();
+ OnClientConnectionLost();
+ }
}
-void GpuCompositorFrameSink::BeginFrameDidNotSwap(
+void GpuCompositorFrameSink::DidNotProduceFrame(
const cc::BeginFrameAck& begin_frame_ack) {
- support_->BeginFrameDidNotSwap(begin_frame_ack);
+ support_->DidNotProduceFrame(begin_frame_ack);
}
void GpuCompositorFrameSink::DidReceiveCompositorFrameAck(
diff --git a/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.h b/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.h
index beb2bd27b40..83cbf2f211d 100644
--- a/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.h
+++ b/chromium/components/viz/frame_sinks/gpu_compositor_frame_sink.h
@@ -37,11 +37,11 @@ class GpuCompositorFrameSink
~GpuCompositorFrameSink() override;
// cc::mojom::MojoCompositorFrameSink:
- void EvictFrame() override;
+ void EvictCurrentSurface() override;
void SetNeedsBeginFrame(bool needs_begin_frame) override;
void SubmitCompositorFrame(const cc::LocalSurfaceId& local_surface_id,
cc::CompositorFrame frame) override;
- void BeginFrameDidNotSwap(const cc::BeginFrameAck& begin_frame_ack) override;
+ void DidNotProduceFrame(const cc::BeginFrameAck& begin_frame_ack) override;
// cc::mojom::MojoCompositorFrameSinkPrivate:
void ClaimTemporaryReference(const cc::SurfaceId& surface_id) override;
diff --git a/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc b/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
index 5aa6bad8bc7..393f53fc2eb 100644
--- a/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
+++ b/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
@@ -75,8 +75,8 @@ void GpuRootCompositorFrameSink::SetLocalSurfaceId(
display_->SetLocalSurfaceId(local_surface_id, scale_factor);
}
-void GpuRootCompositorFrameSink::EvictFrame() {
- support_->EvictFrame();
+void GpuRootCompositorFrameSink::EvictCurrentSurface() {
+ support_->EvictCurrentSurface();
}
void GpuRootCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) {
@@ -86,12 +86,15 @@ void GpuRootCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) {
void GpuRootCompositorFrameSink::SubmitCompositorFrame(
const cc::LocalSurfaceId& local_surface_id,
cc::CompositorFrame frame) {
- support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+ if (!support_->SubmitCompositorFrame(local_surface_id, std::move(frame))) {
+ compositor_frame_sink_binding_.Close();
+ OnClientConnectionLost();
+ }
}
-void GpuRootCompositorFrameSink::BeginFrameDidNotSwap(
+void GpuRootCompositorFrameSink::DidNotProduceFrame(
const cc::BeginFrameAck& begin_frame_ack) {
- support_->BeginFrameDidNotSwap(begin_frame_ack);
+ support_->DidNotProduceFrame(begin_frame_ack);
}
void GpuRootCompositorFrameSink::ClaimTemporaryReference(
diff --git a/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.h b/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.h
index 5dceef590ba..18df306f331 100644
--- a/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.h
+++ b/chromium/components/viz/frame_sinks/gpu_root_compositor_frame_sink.h
@@ -55,11 +55,11 @@ class GpuRootCompositorFrameSink
float scale_factor) override;
// cc::mojom::MojoCompositorFrameSink:
- void EvictFrame() override;
+ void EvictCurrentSurface() override;
void SetNeedsBeginFrame(bool needs_begin_frame) override;
void SubmitCompositorFrame(const cc::LocalSurfaceId& local_surface_id,
cc::CompositorFrame frame) override;
- void BeginFrameDidNotSwap(const cc::BeginFrameAck& begin_frame_ack) override;
+ void DidNotProduceFrame(const cc::BeginFrameAck& begin_frame_ack) override;
// cc::mojom::MojoCompositorFrameSinkPrivate:
void ClaimTemporaryReference(const cc::SurfaceId& surface_id) override;
diff --git a/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.cc b/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.cc
index 71b56c630d3..1c4cc82bc51 100644
--- a/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.cc
+++ b/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.cc
@@ -18,25 +18,34 @@
namespace viz {
-MojoFrameSinkManager::MojoFrameSinkManager(
- bool use_surface_references,
- DisplayProvider* display_provider,
- cc::mojom::FrameSinkManagerRequest request,
- cc::mojom::FrameSinkManagerClientPtr client)
+MojoFrameSinkManager::MojoFrameSinkManager(bool use_surface_references,
+ DisplayProvider* display_provider)
: manager_(use_surface_references
? cc::SurfaceManager::LifetimeType::REFERENCES
: cc::SurfaceManager::LifetimeType::SEQUENCES),
display_provider_(display_provider),
- client_(std::move(client)),
- binding_(this, std::move(request)) {
+ binding_(this) {
manager_.AddObserver(this);
+ dependency_tracker_ = base::MakeUnique<cc::SurfaceDependencyTracker>(
+ &manager_, manager_.GetPrimaryBeginFrameSource());
+ manager_.SetDependencyTracker(dependency_tracker_.get());
}
MojoFrameSinkManager::~MojoFrameSinkManager() {
DCHECK(thread_checker_.CalledOnValidThread());
+ manager_.SetDependencyTracker(nullptr);
+ dependency_tracker_.reset();
manager_.RemoveObserver(this);
}
+void MojoFrameSinkManager::Connect(
+ cc::mojom::FrameSinkManagerRequest request,
+ cc::mojom::FrameSinkManagerClientPtr client) {
+ DCHECK(!binding_.is_bound());
+ binding_.Bind(std::move(request));
+ client_ = std::move(client);
+}
+
void MojoFrameSinkManager::CreateRootCompositorFrameSink(
const cc::FrameSinkId& frame_sink_id,
gpu::SurfaceHandle surface_handle,
@@ -53,16 +62,6 @@ void MojoFrameSinkManager::CreateRootCompositorFrameSink(
std::unique_ptr<cc::Display> display = display_provider_->CreateDisplay(
frame_sink_id, surface_handle, &begin_frame_source);
- // Lazily inject a SurfaceDependencyTracker into SurfaceManager if surface
- // synchronization is enabled.
- if (!manager_.dependency_tracker() &&
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- cc::switches::kEnableSurfaceSynchronization)) {
- std::unique_ptr<cc::SurfaceDependencyTracker> dependency_tracker(
- new cc::SurfaceDependencyTracker(&manager_, begin_frame_source.get()));
- manager_.SetDependencyTracker(std::move(dependency_tracker));
- }
-
compositor_frame_sinks_[frame_sink_id] =
base::MakeUnique<GpuRootCompositorFrameSink>(
this, &manager_, frame_sink_id, std::move(display),
@@ -125,6 +124,9 @@ void MojoFrameSinkManager::OnSurfaceCreated(
void MojoFrameSinkManager::OnSurfaceDamaged(const cc::SurfaceId& surface_id,
bool* changed) {}
+void MojoFrameSinkManager::OnSurfaceDiscarded(const cc::SurfaceId& surface_id) {
+}
+
void MojoFrameSinkManager::OnClientConnectionLost(
const cc::FrameSinkId& frame_sink_id,
bool destroy_compositor_frame_sink) {
diff --git a/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.h b/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.h
index 53785d95dee..af01a4bfe29 100644
--- a/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.h
+++ b/chromium/components/viz/frame_sinks/mojo_frame_sink_manager.h
@@ -17,6 +17,7 @@
#include "cc/surfaces/surface_manager.h"
#include "cc/surfaces/surface_observer.h"
#include "components/viz/frame_sinks/gpu_compositor_frame_sink_delegate.h"
+#include "components/viz/viz_export.h"
#include "gpu/ipc/common/surface_handle.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -32,19 +33,22 @@ class DisplayProvider;
// will be true after the mus process split. For non-mus Chrome this will be
// created in the browser process, at least until GPU implementations can be
// unified.
-class MojoFrameSinkManager : public cc::SurfaceObserver,
- public GpuCompositorFrameSinkDelegate,
- public cc::mojom::FrameSinkManager {
+class VIZ_EXPORT MojoFrameSinkManager
+ : public cc::SurfaceObserver,
+ public NON_EXPORTED_BASE(GpuCompositorFrameSinkDelegate),
+ public NON_EXPORTED_BASE(cc::mojom::FrameSinkManager) {
public:
MojoFrameSinkManager(bool use_surface_references,
- DisplayProvider* display_provider,
- cc::mojom::FrameSinkManagerRequest request,
- cc::mojom::FrameSinkManagerClientPtr client);
+ DisplayProvider* display_provider);
~MojoFrameSinkManager() override;
cc::SurfaceManager* surface_manager() { return &manager_; }
- // cc::mojom::MojoFrameSinkManager implementation:
+ // Binds to |request| and store connection back to |client|.
+ void Connect(cc::mojom::FrameSinkManagerRequest request,
+ cc::mojom::FrameSinkManagerClientPtr client);
+
+ // cc::mojom::FrameSinkManager implementation:
void CreateRootCompositorFrameSink(
const cc::FrameSinkId& frame_sink_id,
gpu::SurfaceHandle surface_handle,
@@ -78,6 +82,7 @@ class MojoFrameSinkManager : public cc::SurfaceObserver,
void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override;
void OnSurfaceDamaged(const cc::SurfaceId& surface_id,
bool* changed) override;
+ void OnSurfaceDiscarded(const cc::SurfaceId& surface_id) override;
// GpuCompositorFrameSinkDelegate implementation.
void OnClientConnectionLost(const cc::FrameSinkId& frame_sink_id,
@@ -90,6 +95,8 @@ class MojoFrameSinkManager : public cc::SurfaceObserver,
// access to a valid pointer for the entirety of their lifetimes.
cc::SurfaceManager manager_;
+ std::unique_ptr<cc::SurfaceDependencyTracker> dependency_tracker_;
+
// Provides a cc::Display for CreateRootCompositorFrameSink().
DisplayProvider* const display_provider_;
diff --git a/chromium/components/viz/viz_export.h b/chromium/components/viz/viz_export.h
new file mode 100644
index 00000000000..4948f15de93
--- /dev/null
+++ b/chromium/components/viz/viz_export.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2017 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_VIZ_VIZ_EXPORT_H_
+#define COMPONENTS_VIZ_VIZ_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(VIZ_IMPLEMENTATION)
+#define VIZ_EXPORT __declspec(dllexport)
+#else
+#define VIZ_EXPORT __declspec(dllimport)
+#endif // defined(VIZ_IMPLEMENTATION)
+
+#else // defined(WIN32)
+#if defined(VIZ_IMPLEMENTATION)
+#define VIZ_EXPORT __attribute__((visibility("default")))
+#else
+#define VIZ_EXPORT
+#endif
+#endif
+
+#else // defined(COMPONENT_BUILD)
+#define VIZ_EXPORT
+#endif
+
+#endif // COMPONENTS_VIZ_VIZ_EXPORT_H_
diff --git a/chromium/components/wallpaper/wallpaper_color_calculator_unittest.cc b/chromium/components/wallpaper/wallpaper_color_calculator_unittest.cc
index 938ec5ee85f..595f5c06b57 100644
--- a/chromium/components/wallpaper/wallpaper_color_calculator_unittest.cc
+++ b/chromium/components/wallpaper/wallpaper_color_calculator_unittest.cc
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
#include "base/test/histogram_tester.h"
#include "base/test/null_task_runner.h"
#include "base/test/test_mock_time_task_runner.h"
diff --git a/chromium/components/wallpaper/wallpaper_manager_base.cc b/chromium/components/wallpaper/wallpaper_manager_base.cc
index 188580d6e89..e72039f4af3 100644
--- a/chromium/components/wallpaper/wallpaper_manager_base.cc
+++ b/chromium/components/wallpaper/wallpaper_manager_base.cc
@@ -431,7 +431,6 @@ bool WallpaperManagerBase::ResizeImage(
gfx::Size(resized_width, resized_height));
SkBitmap bitmap = *(resized_image.bitmap());
- SkAutoLockPixels lock_input(bitmap);
gfx::JPEGCodec::Encode(
reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
gfx::JPEGCodec::FORMAT_SkBitmap, bitmap.width(), bitmap.height(),
@@ -790,13 +789,10 @@ void WallpaperManagerBase::DeleteUserWallpapers(
wallpaper_path = wallpaper_path.Append(path_to_file);
file_to_remove.push_back(wallpaper_path);
- base::PostTaskWithTraits(
- FROM_HERE, base::TaskTraits()
- .WithShutdownBehavior(
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
- .WithPriority(base::TaskPriority::BACKGROUND)
- .MayBlock(),
- base::Bind(&DeleteWallpaperInList, file_to_remove));
+ base::PostTaskWithTraits(FROM_HERE,
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ base::Bind(&DeleteWallpaperInList, file_to_remove));
}
void WallpaperManagerBase::SetCommandLineForTesting(
diff --git a/chromium/components/wallpaper/wallpaper_resizer_unittest.cc b/chromium/components/wallpaper/wallpaper_resizer_unittest.cc
index fadf11c3cb7..553f54d9800 100644
--- a/chromium/components/wallpaper/wallpaper_resizer_unittest.cc
+++ b/chromium/components/wallpaper/wallpaper_resizer_unittest.cc
@@ -50,9 +50,7 @@ gfx::ImageSkia CreateTestImage(const gfx::Size& size) {
bool IsColor(const gfx::ImageSkia& image, const uint32_t expect) {
EXPECT_EQ(image.width(), kTargetWidth);
EXPECT_EQ(image.height(), kTargetHeight);
- const SkBitmap* image_bitmap = image.bitmap();
- SkAutoLockPixels image_lock(*image_bitmap);
- return *image_bitmap->getAddr32(0, 0) == expect;
+ return *image.bitmap()->getAddr32(0, 0) == expect;
}
} // namespace
diff --git a/chromium/components/web_cache/renderer/BUILD.gn b/chromium/components/web_cache/renderer/BUILD.gn
index b386fc778de..368bff45c67 100644
--- a/chromium/components/web_cache/renderer/BUILD.gn
+++ b/chromium/components/web_cache/renderer/BUILD.gn
@@ -11,6 +11,7 @@ static_library("renderer") {
deps = [
"//base",
"//components/web_cache/public/interfaces",
+ "//content/public/child",
"//content/public/common",
"//content/public/renderer",
"//services/service_manager/public/cpp",
diff --git a/chromium/components/web_cache/renderer/DEPS b/chromium/components/web_cache/renderer/DEPS
index 0672fbe1f65..089e77b0764 100644
--- a/chromium/components/web_cache/renderer/DEPS
+++ b/chromium/components/web_cache/renderer/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+content/public/child",
"+content/public/common",
"+content/public/renderer",
"+mojo/public",
diff --git a/chromium/components/web_cache/renderer/web_cache_impl.cc b/chromium/components/web_cache/renderer/web_cache_impl.cc
index c4e73bf95f5..e955bba45fb 100644
--- a/chromium/components/web_cache/renderer/web_cache_impl.cc
+++ b/chromium/components/web_cache/renderer/web_cache_impl.cc
@@ -8,23 +8,33 @@
#include "base/bind.h"
#include "base/numerics/safe_conversions.h"
+#include "content/public/child/child_thread.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/common/simple_connection_filter.h"
#include "content/public/renderer/render_thread.h"
-#include "services/service_manager/public/cpp/interface_registry.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/WebKit/public/platform/WebCache.h"
namespace web_cache {
WebCacheImpl::WebCacheImpl() : clear_cache_state_(kInit) {
- service_manager::InterfaceRegistry* registry =
- content::RenderThread::Get()->GetInterfaceRegistry();
+ auto registry = base::MakeUnique<service_manager::BinderRegistry>();
registry->AddInterface(
- base::Bind(&WebCacheImpl::BindRequest, base::Unretained(this)));
+ base::Bind(&WebCacheImpl::BindRequest, base::Unretained(this)),
+ base::ThreadTaskRunnerHandle::Get());
+ if (content::ChildThread::Get()) {
+ content::ChildThread::Get()
+ ->GetServiceManagerConnection()
+ ->AddConnectionFilter(base::MakeUnique<content::SimpleConnectionFilter>(
+ std::move(registry)));
+ }
}
WebCacheImpl::~WebCacheImpl() {}
void WebCacheImpl::BindRequest(
- mojo::InterfaceRequest<mojom::WebCache> web_cache_request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::WebCacheRequest web_cache_request) {
bindings_.AddBinding(this, std::move(web_cache_request));
}
diff --git a/chromium/components/web_cache/renderer/web_cache_impl.h b/chromium/components/web_cache/renderer/web_cache_impl.h
index 3b629cc250e..5697cebe913 100644
--- a/chromium/components/web_cache/renderer/web_cache_impl.h
+++ b/chromium/components/web_cache/renderer/web_cache_impl.h
@@ -13,6 +13,10 @@
#include "components/web_cache/public/interfaces/web_cache.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace web_cache {
// This class implements the Mojo interface mojom::WebCache.
@@ -21,7 +25,8 @@ class WebCacheImpl : public mojom::WebCache {
WebCacheImpl();
~WebCacheImpl() override;
- void BindRequest(mojo::InterfaceRequest<mojom::WebCache> web_cache_request);
+ void BindRequest(const service_manager::BindSourceInfo& source_info,
+ mojom::WebCacheRequest web_cache_request);
// Needs to be called by RenderViews in case of navigations to execute
// any 'clear cache' commands that were delayed until the next navigation.
diff --git a/chromium/components/web_contents_delegate_android/validation_message_bubble_android.cc b/chromium/components/web_contents_delegate_android/validation_message_bubble_android.cc
index 0dd5eee1628..e2ee3a1fd69 100644
--- a/chromium/components/web_contents_delegate_android/validation_message_bubble_android.cc
+++ b/chromium/components/web_contents_delegate_android/validation_message_bubble_android.cc
@@ -42,7 +42,7 @@ ValidationMessageBubbleAndroid::ValidationMessageBubbleAndroid(
JNIEnv* env = base::android::AttachCurrentThread();
java_validation_message_bubble_.Reset(
- Java_ValidationMessageBubble_createAndShow(
+ Java_ValidationMessageBubble_createAndShowIfApplicable(
env, java_content_view_core, anchor_in_root_view.x(),
anchor_in_root_view.y(), anchor_in_root_view.width(),
anchor_in_root_view.height(),
@@ -51,16 +51,20 @@ ValidationMessageBubbleAndroid::ValidationMessageBubbleAndroid(
}
ValidationMessageBubbleAndroid::~ValidationMessageBubbleAndroid() {
- Java_ValidationMessageBubble_close(base::android::AttachCurrentThread(),
- java_validation_message_bubble_);
+ if (!java_validation_message_bubble_.is_null()) {
+ Java_ValidationMessageBubble_close(base::android::AttachCurrentThread(),
+ java_validation_message_bubble_);
+ }
}
void ValidationMessageBubbleAndroid::SetPositionRelativeToAnchor(
RenderWidgetHost* widget_host, const gfx::Rect& anchor_in_root_view) {
base::android::ScopedJavaLocalRef<jobject> java_content_view_core =
GetJavaContentViewCoreFrom(widget_host);
- if (java_content_view_core.is_null())
+ if (java_content_view_core.is_null() ||
+ java_validation_message_bubble_.is_null()) {
return;
+ }
Java_ValidationMessageBubble_setPositionRelativeToAnchor(
base::android::AttachCurrentThread(), java_validation_message_bubble_,
diff --git a/chromium/components/web_contents_delegate_android/web_contents_delegate_android.cc b/chromium/components/web_contents_delegate_android/web_contents_delegate_android.cc
index 0a31742d355..731e90068e1 100644
--- a/chromium/components/web_contents_delegate_android/web_contents_delegate_android.cc
+++ b/chromium/components/web_contents_delegate_android/web_contents_delegate_android.cc
@@ -219,7 +219,8 @@ void WebContentsDelegateAndroid::WebContentsCreated(
int opener_render_frame_id,
const std::string& frame_name,
const GURL& target_url,
- WebContents* new_contents) {
+ WebContents* new_contents,
+ const base::Optional<content::WebContents::CreateParams>& create_params) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
if (obj.is_null())
diff --git a/chromium/components/web_contents_delegate_android/web_contents_delegate_android.h b/chromium/components/web_contents_delegate_android/web_contents_delegate_android.h
index 552574f78a4..4b179ac46f6 100644
--- a/chromium/components/web_contents_delegate_android/web_contents_delegate_android.h
+++ b/chromium/components/web_contents_delegate_android/web_contents_delegate_android.h
@@ -12,12 +12,12 @@
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
#include "base/compiler_specific.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
class GURL;
namespace content {
-class WebContents;
class WebContentsDelegate;
struct NativeWebKeyboardEvent;
struct OpenURLParams;
@@ -73,12 +73,15 @@ class WebContentsDelegateAndroid : public content::WebContentsDelegate {
content::WebContents* source,
const content::WebContentsUnresponsiveState& unresponsive_state) override;
void RendererResponsive(content::WebContents* source) override;
- void WebContentsCreated(content::WebContents* source_contents,
- int opener_render_process_id,
- int opener_render_frame_id,
- const std::string& frame_name,
- const GURL& target_url,
- content::WebContents* new_contents) override;
+ void WebContentsCreated(
+ content::WebContents* source_contents,
+ int opener_render_process_id,
+ int opener_render_frame_id,
+ const std::string& frame_name,
+ const GURL& target_url,
+ content::WebContents* new_contents,
+ const base::Optional<content::WebContents::CreateParams>& create_params)
+ override;
bool ShouldCreateWebContents(
content::WebContents* web_contents,
content::SiteInstance* source_site_instance,
diff --git a/chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc b/chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc
index 78ceb33f416..014a0ec36a0 100644
--- a/chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc
+++ b/chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc
@@ -4,6 +4,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "components/prefs/testing_pref_service.h"
#include "components/web_resource/eula_accepted_notifier.h"
diff --git a/chromium/components/web_restrictions/browser/web_restrictions_client.cc b/chromium/components/web_restrictions/browser/web_restrictions_client.cc
index 6a815987341..ea67fdc1e20 100644
--- a/chromium/components/web_restrictions/browser/web_restrictions_client.cc
+++ b/chromium/components/web_restrictions/browser/web_restrictions_client.cc
@@ -9,7 +9,6 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/task_scheduler/post_task.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/browser_thread.h"
#include "jni/WebRestrictionsClient_jni.h"
@@ -47,12 +46,9 @@ bool WebRestrictionsClient::Register(JNIEnv* env) {
WebRestrictionsClient::WebRestrictionsClient()
: initialized_(false), supports_request_(false) {
- base::SequencedWorkerPool* worker_pool =
- content::BrowserThread::GetBlockingPool();
- background_task_runner_ =
- worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
- worker_pool->GetSequenceToken(),
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+ background_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
}
WebRestrictionsClient::~WebRestrictionsClient() {
@@ -95,8 +91,7 @@ void WebRestrictionsClient::SetAuthorityTask(
reinterpret_cast<jlong>(this)));
supports_request_ = false;
base::PostTaskWithTraitsAndReplyWithResult(
- FROM_HERE, base::TaskTraits().MayBlock().WithPriority(
- base::TaskPriority::BACKGROUND),
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
base::Bind(&CheckSupportsRequestTask, java_provider_),
base::Bind(&WebRestrictionsClient::RequestSupportKnown,
base::Unretained(this), provider_authority_));
diff --git a/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.cc b/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.cc
index 5a0af86ea61..349b3d1d3d2 100644
--- a/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.cc
+++ b/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.cc
@@ -16,9 +16,9 @@ namespace web_restrictions {
namespace {
void ClientRequestPermissionCallback(
- const mojom::WebRestrictions::RequestPermissionCallback& callback,
+ mojom::WebRestrictions::RequestPermissionCallback callback,
bool result) {
- callback.Run(result);
+ std::move(callback).Run(result);
}
} // namespace
@@ -31,20 +31,20 @@ WebRestrictionsMojoImplementation::~WebRestrictionsMojoImplementation() {}
void WebRestrictionsMojoImplementation::Create(
WebRestrictionsClient* client,
- mojo::InterfaceRequest<mojom::WebRestrictions> request) {
+ const service_manager::BindSourceInfo& source_info,
+ mojom::WebRestrictionsRequest request) {
mojo::MakeStrongBinding(
base::MakeUnique<WebRestrictionsMojoImplementation>(client),
std::move(request));
}
-void WebRestrictionsMojoImplementation::GetResult(
- const std::string& url,
- const GetResultCallback& callback) {
+void WebRestrictionsMojoImplementation::GetResult(const std::string& url,
+ GetResultCallback callback) {
std::unique_ptr<const WebRestrictionsClientResult> web_restrictions_result(
web_restrictions_client_->GetCachedWebRestrictionsResult(url));
mojom::ClientResultPtr result = mojom::ClientResult::New();
if (!web_restrictions_result) {
- callback.Run(std::move(result));
+ std::move(callback).Run(std::move(result));
return;
}
int columnCount = web_restrictions_result->GetColumnCount();
@@ -57,14 +57,15 @@ void WebRestrictionsMojoImplementation::GetResult(
web_restrictions_result->GetInt(i);
}
}
- callback.Run(std::move(result));
+ std::move(callback).Run(std::move(result));
}
void WebRestrictionsMojoImplementation::RequestPermission(
const std::string& url,
- const mojom::WebRestrictions::RequestPermissionCallback& callback) {
+ mojom::WebRestrictions::RequestPermissionCallback callback) {
web_restrictions_client_->RequestPermission(
- url, base::Bind(&ClientRequestPermissionCallback, callback));
+ url,
+ base::Bind(&ClientRequestPermissionCallback, base::Passed(&callback)));
}
} // namespace web_restrictions
diff --git a/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.h b/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.h
index c13c03a76f2..a5dbc3f823d 100644
--- a/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.h
+++ b/chromium/components/web_restrictions/browser/web_restrictions_mojo_implementation.h
@@ -10,6 +10,10 @@
#include "base/macros.h"
#include "components/web_restrictions/interfaces/web_restrictions.mojom.h"
+namespace service_manager {
+struct BindSourceInfo;
+}
+
namespace web_restrictions {
class WebRestrictionsClient;
@@ -20,13 +24,13 @@ class WebRestrictionsMojoImplementation : public mojom::WebRestrictions {
~WebRestrictionsMojoImplementation() override;
static void Create(WebRestrictionsClient* client,
- mojo::InterfaceRequest<mojom::WebRestrictions> request);
+ const service_manager::BindSourceInfo& source_info,
+ mojom::WebRestrictionsRequest request);
private:
- void GetResult(const std::string& url,
- const GetResultCallback& callback) override;
+ void GetResult(const std::string& url, GetResultCallback callback) override;
void RequestPermission(const std::string& url,
- const RequestPermissionCallback& callback) override;
+ RequestPermissionCallback callback) override;
WebRestrictionsClient* web_restrictions_client_;
};
diff --git a/chromium/components/web_restrictions/browser/web_restrictions_resource_throttle_unittest.cc b/chromium/components/web_restrictions/browser/web_restrictions_resource_throttle_unittest.cc
index f92951cd739..933bb326569 100644
--- a/chromium/components/web_restrictions/browser/web_restrictions_resource_throttle_unittest.cc
+++ b/chromium/components/web_restrictions/browser/web_restrictions_resource_throttle_unittest.cc
@@ -114,7 +114,15 @@ TEST_F(WebRestrictionsResourceThrottleTest, WillStartRequest_DeferredForbid) {
EXPECT_EQ(net::ERR_BLOCKED_BY_ADMINISTRATOR, delegate_.GetErrorCode());
}
-TEST_F(WebRestrictionsResourceThrottleTest, WillStartRequest_Subresource) {
+#if defined(OS_ANDROID)
+// Flaky on android: https://crbug.com/718066
+#define MAYBE_WillStartRequest_Subresource DISABLED_WillStartRequest_Subresource
+#else
+#define MAYBE_WillStartRequest_Subresource WillStartRequest_Subresource
+#endif
+
+TEST_F(WebRestrictionsResourceThrottleTest,
+ MAYBE_WillStartRequest_Subresource) {
// Only the main frame should be deferred.
// Initialization of the delegate is asynchronous, and this will only work
// correctly if the provider is initialized. Run a main frame through this
diff --git a/chromium/components/webauth/BUILD.gn b/chromium/components/webauth/BUILD.gn
new file mode 100644
index 00000000000..80da9afb1b3
--- /dev/null
+++ b/chromium/components/webauth/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2017 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("authenticator") {
+ sources = [
+ "authenticator.mojom",
+ ]
+
+ public_deps = [
+ "//mojo/common:common_custom_types",
+ ]
+}
diff --git a/chromium/components/webauth/OWNERS b/chromium/components/webauth/OWNERS
new file mode 100644
index 00000000000..08850f42120
--- /dev/null
+++ b/chromium/components/webauth/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/webauth/authenticator.mojom b/chromium/components/webauth/authenticator.mojom
new file mode 100644
index 00000000000..1bf69a9796d
--- /dev/null
+++ b/chromium/components/webauth/authenticator.mojom
@@ -0,0 +1,89 @@
+// Copyright 2017 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.
+
+[JavaPackage="org.chromium.webauth.mojom"]
+module webauth.mojom;
+
+// This file describes the communication between the WebAuthentication renderer
+// implementation and browser-side implementations to create scoped credentials
+// and use already-created credentials to get assertions.
+// See https://w3c.github.io/webauthn/.
+
+// The public key and attestation that is returned by an authenticator's
+// call to makeCredential.
+struct ScopedCredentialInfo {
+ // A blob of data containing the JSON serialization of client data passed
+ // to the authenticator.
+ array<uint8> client_data;
+ // A blob of data returned from the authenticator.
+ array<uint8> attestation;
+};
+
+// Information about the relying party and the user account held by that
+// relying party. This information is used by the authenticator to create
+// or retrieve an appropriate scoped credential for this account.
+// These fields take arbitrary input.
+
+struct RelyingPartyAccount {
+ // Friendly name of the Relying Party, e.g. "Acme Corporation"
+ string relying_party_display_name;
+ // Friendly name associated with the user account, e.g. "John P. Smith"
+ string display_name;
+ // Identifier for the account, corresponding to no more than one credential
+ // per authenticator and Relying Party.
+ string id;
+ // Detailed name for the account, e.g. john.p.smith@example.com
+ string name;
+ // User image, if any.
+ // Todo make this url.mojom.Url in a followup CL
+ string image_url;
+};
+
+// Parameters that are used to generate an appropriate scoped credential.
+struct ScopedCredentialParameters {
+ ScopedCredentialType type;
+ // TODO(kpaulhamus): add AlgorithmIdentifier algorithm;
+};
+
+// Optional parameters that are used during makeCredential.
+struct ScopedCredentialOptions {
+ //TODO(kpaulhamus): Make this mojo.common.mojom.TimeDelta in followup CL
+ int32 timeout_seconds;
+ string relying_party_id;
+ array<ScopedCredentialDescriptor> exclude_list;
+ // TODO(kpaulhamus): add Extensions
+};
+
+enum ScopedCredentialType {
+ SCOPEDCRED,
+};
+
+// Describes the credentials that the relying party already knows about for
+// the given account. If any of these are known to the authenticator,
+// it should not create a new credential.
+struct ScopedCredentialDescriptor {
+ ScopedCredentialType type;
+ // Blob representing a credential key handle. Up to 255 bytes for
+ // U2F authenticators.
+ array<uint8> id;
+ array<Transport> transports;
+};
+
+enum Transport {
+ USB,
+ NFC,
+ BLE,
+};
+
+// Interface to direct authenticators to create or use a scoped credential.
+interface Authenticator {
+ // Gets the credential info for a new credential created by an authenticator
+ // for the given relying party and account.
+ // |attestation_challenge| is a blob passed from the relying party server.
+ MakeCredential(RelyingPartyAccount account_information,
+ array<ScopedCredentialParameters> crypto_parameters,
+ array<uint8> attestation_challenge,
+ ScopedCredentialOptions? options)
+ => (array<ScopedCredentialInfo> scoped_credentials);
+};
diff --git a/chromium/components/webcrypto/algorithms/hkdf.cc b/chromium/components/webcrypto/algorithms/hkdf.cc
index f3381100e16..be01683478d 100644
--- a/chromium/components/webcrypto/algorithms/hkdf.cc
+++ b/chromium/components/webcrypto/algorithms/hkdf.cc
@@ -71,6 +71,9 @@ class HkdfImplementation : public AlgorithmImplementation {
if (!has_optional_length_bits)
return Status::ErrorHkdfDeriveBitsLengthNotSpecified();
+ if (optional_length_bits % 8)
+ return Status::ErrorHkdfLengthNotWholeByte();
+
const blink::WebCryptoHkdfParams* params = algorithm.HkdfParams();
const EVP_MD* digest_algorithm = GetDigest(params->GetHash());
@@ -78,7 +81,7 @@ class HkdfImplementation : public AlgorithmImplementation {
return Status::ErrorUnsupported();
// Size output to fit length
- unsigned int derived_bytes_len = NumBitsToBytes(optional_length_bits);
+ unsigned int derived_bytes_len = optional_length_bits / 8;
derived_bytes->resize(derived_bytes_len);
// Algorithm dispatch checks that the algorithm in |base_key| matches
@@ -96,7 +99,6 @@ class HkdfImplementation : public AlgorithmImplementation {
return Status::OperationError();
}
- TruncateToBitLength(optional_length_bits, derived_bytes);
return Status::Success();
}
diff --git a/chromium/components/webcrypto/status.cc b/chromium/components/webcrypto/status.cc
index 7dcbb93c888..3645279c7ec 100644
--- a/chromium/components/webcrypto/status.cc
+++ b/chromium/components/webcrypto/status.cc
@@ -331,6 +331,11 @@ Status Status::ErrorHkdfLengthTooLong() {
"The length provided for HKDF is too large.");
}
+Status Status::ErrorHkdfLengthNotWholeByte() {
+ return Status(blink::kWebCryptoErrorTypeOperation,
+ "The length provided for HKDF is not a multiple of 8 bits.");
+}
+
Status Status::ErrorHkdfDeriveBitsLengthNotSpecified() {
// TODO(nharper): The spec might change so that an OperationError should be
// thrown here instead of a TypeError.
diff --git a/chromium/components/webcrypto/status.h b/chromium/components/webcrypto/status.h
index 5933623e848..2c7dfa7b9c5 100644
--- a/chromium/components/webcrypto/status.h
+++ b/chromium/components/webcrypto/status.h
@@ -258,6 +258,9 @@ class Status {
// The requested length for HKDF was too large.
static Status ErrorHkdfLengthTooLong();
+ // The length to HKDF's deriveBits() was not a multiple of 8.
+ static Status ErrorHkdfLengthNotWholeByte();
+
// No length parameter was provided for HKDF's Derive Bits operation.
static Status ErrorHkdfDeriveBitsLengthNotSpecified();
diff --git a/chromium/components/webdata/common/BUILD.gn b/chromium/components/webdata/common/BUILD.gn
index 7de1b1cd976..1fe078139fd 100644
--- a/chromium/components/webdata/common/BUILD.gn
+++ b/chromium/components/webdata/common/BUILD.gn
@@ -57,6 +57,7 @@ bundle_data("unit_tests_bundle_data") {
"//components/test/data/web_database/version_68.sql",
"//components/test/data/web_database/version_69.sql",
"//components/test/data/web_database/version_70.sql",
+ "//components/test/data/web_database/version_71.sql",
]
outputs = [
"{{bundle_resources_dir}}/" +
diff --git a/chromium/components/webdata/common/web_data_request_manager.cc b/chromium/components/webdata/common/web_data_request_manager.cc
index 3615379a758..c52cfd82c53 100644
--- a/chromium/components/webdata/common/web_data_request_manager.cc
+++ b/chromium/components/webdata/common/web_data_request_manager.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/memory/ptr_util.h"
#include "base/profiler/scoped_tracker.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -19,50 +20,47 @@
////////////////////////////////////////////////////////////////////////////////
WebDataRequest::~WebDataRequest() {
- if (IsActive()) {
- manager_->CancelRequest(handle_);
- }
+ WebDataRequestManager* manager = GetManager();
+ if (manager)
+ manager->CancelRequest(handle_);
}
WebDataServiceBase::Handle WebDataRequest::GetHandle() const {
return handle_;
}
-bool WebDataRequest::IsActive() const {
- return manager_ != nullptr;
+bool WebDataRequest::IsActive() {
+ return GetManager() != nullptr;
}
WebDataRequest::WebDataRequest(WebDataRequestManager* manager,
- WebDataServiceConsumer* consumer)
+ WebDataServiceConsumer* consumer,
+ WebDataServiceBase::Handle handle)
: task_runner_(base::ThreadTaskRunnerHandle::Get()),
- manager_(manager),
+ atomic_manager_(reinterpret_cast<base::subtle::AtomicWord>(manager)),
consumer_(consumer),
- handle_(0) {
+ handle_(handle) {
+ DCHECK(task_runner_);
DCHECK(IsActive());
+ static_assert(sizeof(atomic_manager_) == sizeof(manager), "size mismatch");
}
-void WebDataRequest::AssertThreadSafe() const {
- // Manipulations of the request state should only happen when the request is
- // active and the manager's lock is held (i.e., during request cancellation
- // or completion).
- DCHECK(IsActive());
- manager_->AssertLockedByCurrentThread();
+WebDataRequestManager* WebDataRequest::GetManager() {
+ return reinterpret_cast<WebDataRequestManager*>(
+ base::subtle::Acquire_Load(&atomic_manager_));
}
-WebDataServiceConsumer* WebDataRequest::GetConsumer() const {
- AssertThreadSafe();
+WebDataServiceConsumer* WebDataRequest::GetConsumer() {
return consumer_;
}
-scoped_refptr<base::SingleThreadTaskRunner> WebDataRequest::GetTaskRunner()
- const {
+scoped_refptr<base::SingleThreadTaskRunner> WebDataRequest::GetTaskRunner() {
return task_runner_;
}
void WebDataRequest::MarkAsInactive() {
- AssertThreadSafe();
- consumer_ = nullptr;
- manager_ = nullptr;
+ // Set atomic_manager_ to the equivalent of nullptr;
+ base::subtle::Release_Store(&atomic_manager_, 0);
}
////////////////////////////////////////////////////////////////////////////////
@@ -77,13 +75,13 @@ WebDataRequestManager::WebDataRequestManager()
std::unique_ptr<WebDataRequest> WebDataRequestManager::NewRequest(
WebDataServiceConsumer* consumer) {
- std::unique_ptr<WebDataRequest> request(new WebDataRequest(this, consumer));
-
- // Grab the lock to get the next request handle and register the request.
base::AutoLock l(pending_lock_);
- request->handle_ = next_request_handle_++;
- pending_requests_[request->handle_] = request.get();
-
+ std::unique_ptr<WebDataRequest> request = base::WrapUnique(
+ new WebDataRequest(this, consumer, next_request_handle_));
+ bool inserted =
+ pending_requests_.emplace(next_request_handle_, request.get()).second;
+ DCHECK(inserted);
+ ++next_request_handle_;
return request;
}
@@ -105,12 +103,8 @@ void WebDataRequestManager::RequestCompleted(
request->GetTaskRunner();
task_runner->PostTask(
FROM_HERE,
- base::Bind(&WebDataRequestManager::RequestCompletedOnThread, this,
- base::Passed(&request), base::Passed(&result)));
-}
-
-void WebDataRequestManager::AssertLockedByCurrentThread() const {
- pending_lock_.AssertAcquired();
+ base::BindOnce(&WebDataRequestManager::RequestCompletedOnThread, this,
+ base::Passed(&request), base::Passed(&result)));
}
WebDataRequestManager::~WebDataRequestManager() {
@@ -123,28 +117,15 @@ WebDataRequestManager::~WebDataRequestManager() {
void WebDataRequestManager::RequestCompletedOnThread(
std::unique_ptr<WebDataRequest> request,
std::unique_ptr<WDTypedResult> result) {
- // If the request is already inactive, early exit to avoid contending for the
- // lock (aka, the double checked locking pattern).
+ // Check whether the request is active. It might have been cancelled in
+ // another thread before this completion handler was invoked. This means the
+ // request initiator is no longer interested in the result.
if (!request->IsActive())
return;
- // Used to export the consumer from the locked region below so that the
- // consumer can be notified outside of the lock and after the request has
- // been marked as inactive.
- WebDataServiceConsumer* consumer;
-
- // Manipulate the pending_requests_ collection while holding the lock.
+ // Stop tracking the request. The request is already finished, so "stop
+ // tracking" is the same as post-facto cancellation.
{
- base::AutoLock l(pending_lock_);
-
- // Re-check whether the request is active. It might have been cancelled in
- // another thread before the lock was acquired.
- if (!request->IsActive())
- return;
-
- // Remember the consumer for notification below.
- consumer = request->GetConsumer();
-
// TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460
// is fixed.
tracked_objects::ScopedTracker tracking_profile(
@@ -152,20 +133,11 @@ void WebDataRequestManager::RequestCompletedOnThread(
"422460 "
"WebDataRequestManager::RequestCompletedOnThread::UpdateMap"));
- auto i = pending_requests_.find(request->GetHandle());
- DCHECK(i != pending_requests_.end());
-
- // Take ownership of the request object and remove it from the map.
- pending_requests_.erase(i);
-
- // The request is no longer active.
- request->MarkAsInactive();
+ CancelRequest(request->GetHandle());
}
// Notify the consumer if needed.
- //
- // NOTE: The pending_lock_ is no longer held here. It's up to the consumer to
- // be appropriately thread safe.
+ WebDataServiceConsumer* const consumer = request->GetConsumer();
if (consumer) {
// TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460
// is fixed.
diff --git a/chromium/components/webdata/common/web_data_request_manager.h b/chromium/components/webdata/common/web_data_request_manager.h
index 87b55091583..eb621a2cff1 100644
--- a/chromium/components/webdata/common/web_data_request_manager.h
+++ b/chromium/components/webdata/common/web_data_request_manager.h
@@ -12,6 +12,7 @@
#include <map>
#include <memory>
+#include "base/atomicops.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
@@ -40,7 +41,7 @@ class WebDataRequest {
// Returns |true| if the request is active and |false| if the request has been
// cancelled or has already completed.
- bool IsActive() const;
+ bool IsActive();
private:
// For access to the web request mutable state under the manager's lock.
@@ -48,17 +49,19 @@ class WebDataRequest {
// Private constructor called for WebDataRequestManager::NewRequest.
WebDataRequest(WebDataRequestManager* manager,
- WebDataServiceConsumer* consumer);
+ WebDataServiceConsumer* consumer,
+ WebDataServiceBase::Handle handle);
- // Internal debugging helper to assert that the request is active and that the
- // manager's lock is held by the current thread.
- void AssertThreadSafe() const;
+ // Retrieves the manager set in the constructor, if the request is still
+ // active, or nullptr if the request is inactive. The returned value may
+ // change between calls.
+ WebDataRequestManager* GetManager();
// Retrieves the |consumer_| set in the constructor.
- WebDataServiceConsumer* GetConsumer() const;
+ WebDataServiceConsumer* GetConsumer();
// Retrieves the original task runner of the request.
- scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const;
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
// Marks the current request as inactive, either due to cancellation or
// completion.
@@ -67,16 +70,16 @@ class WebDataRequest {
// Tracks task runner that the request originated on.
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- // Used to notify manager if request is cancelled. Uses a raw ptr instead of
- // a ref_ptr so that it can be set to null when a request is cancelled or
- // completed.
- WebDataRequestManager* manager_;
+ // The manager associated with this request. This is stored as a raw (untyped)
+ // pointer value because it does double duty as the flag indicating whether or
+ // not this request is active (non-nullptr => active).
+ base::subtle::AtomicWord atomic_manager_;
// The originator of the service request.
- WebDataServiceConsumer* consumer_;
+ WebDataServiceConsumer* const consumer_;
// Identifier for this request.
- WebDataServiceBase::Handle handle_;
+ const WebDataServiceBase::Handle handle_;
DISALLOW_COPY_AND_ASSIGN(WebDataRequest);
};
@@ -104,10 +107,6 @@ class WebDataRequestManager
void RequestCompleted(std::unique_ptr<WebDataRequest> request,
std::unique_ptr<WDTypedResult> result);
- // A debugging aid to assert that the pending_lock_ is held by the current
- // thread.
- void AssertLockedByCurrentThread() const;
-
private:
friend class base::RefCountedThreadSafe<WebDataRequestManager>;
diff --git a/chromium/components/webdata/common/web_data_results.h b/chromium/components/webdata/common/web_data_results.h
index 1577866001a..71435f59fd8 100644
--- a/chromium/components/webdata/common/web_data_results.h
+++ b/chromium/components/webdata/common/web_data_results.h
@@ -34,6 +34,11 @@ typedef enum {
AUTOFILL_CREDITCARD_RESULT, // WDResult<CreditCard>
AUTOFILL_CREDITCARDS_RESULT, // WDResult<std::vector<
// std::unique_ptr<CreditCard>>>
+#if defined(OS_ANDROID)
+ PAYMENT_WEB_APP_MANIFEST, // WDResult<std::vector<
+ // mojom::WebAppManifestSectionPtr>>
+ PAYMENT_METHOD_MANIFEST, // WDResult<std::vector<std::string>>
+#endif
} WDResultType;
//
diff --git a/chromium/components/webdata/common/web_data_service_base.h b/chromium/components/webdata/common/web_data_service_base.h
index ab9a4d42d22..0c442c698f3 100644
--- a/chromium/components/webdata/common/web_data_service_base.h
+++ b/chromium/components/webdata/common/web_data_service_base.h
@@ -17,7 +17,6 @@ class WebDatabase;
class WebDatabaseService;
namespace base {
-// TODO(skyostil): Migrate to SingleThreadTaskRunner (crbug.com/465354).
class SingleThreadTaskRunner;
}
diff --git a/chromium/components/webdata/common/web_database.cc b/chromium/components/webdata/common/web_database.cc
index 1923176050d..072f025e4d6 100644
--- a/chromium/components/webdata/common/web_database.cc
+++ b/chromium/components/webdata/common/web_database.cc
@@ -13,13 +13,13 @@
// corresponding changes must happen in the unit tests, and new migration test
// added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|.
// static
-const int WebDatabase::kCurrentVersionNumber = 71;
+const int WebDatabase::kCurrentVersionNumber = 72;
const int WebDatabase::kDeprecatedVersionNumber = 51;
namespace {
-const int kCompatibleVersionNumber = 71;
+const int kCompatibleVersionNumber = 72;
// Change the version number and possibly the compatibility version of
// |meta_table_|.
@@ -152,7 +152,6 @@ sql::InitStatus WebDatabase::MigrateOldVersionsAsNeeded() {
for (int next_version = current_version + 1;
next_version <= kCurrentVersionNumber;
++next_version) {
-
// Do any database-wide migrations.
bool update_compatible_version = false;
if (!MigrateToVersion(next_version, &update_compatible_version))
diff --git a/chromium/components/webdata/common/web_database.h b/chromium/components/webdata/common/web_database.h
index 79931bedba7..36bae881f6f 100644
--- a/chromium/components/webdata/common/web_database.h
+++ b/chromium/components/webdata/common/web_database.h
@@ -6,6 +6,7 @@
#define COMPONENTS_WEBDATA_COMMON_WEB_DATABASE_H_
#include <map>
+#include <string>
#include "base/macros.h"
#include "components/webdata/common/web_database_table.h"
diff --git a/chromium/components/webdata/common/web_database_migration_unittest.cc b/chromium/components/webdata/common/web_database_migration_unittest.cc
index 3229f86ea0e..4417725203b 100644
--- a/chromium/components/webdata/common/web_database_migration_unittest.cc
+++ b/chromium/components/webdata/common/web_database_migration_unittest.cc
@@ -130,7 +130,7 @@ class WebDatabaseMigrationTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(WebDatabaseMigrationTest);
};
-const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 71;
+const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 72;
void WebDatabaseMigrationTest::LoadDatabase(
const base::FilePath::StringType& file) {
@@ -1229,16 +1229,61 @@ TEST_F(WebDatabaseMigrationTest, MigrateVersion70ToCurrent) {
// Make sure that the values in masked_credit_cards are still present except
// for the billing_address_id. The values are added to the table in
// version_70.sql.
- sql::Statement s_masked_cards(connection.GetUniqueStatement(
- "SELECT id, status, name_on_card, type, last_four, exp_month, exp_year "
- "FROM masked_credit_cards"));
+ sql::Statement s_masked_cards(
+ connection.GetUniqueStatement("SELECT id, status, name_on_card, "
+ "network, last_four, exp_month, exp_year "
+ "FROM masked_credit_cards"));
ASSERT_TRUE(s_masked_cards.Step());
EXPECT_EQ("card_1", s_masked_cards.ColumnString(0));
EXPECT_EQ("status", s_masked_cards.ColumnString(1));
EXPECT_EQ("bob", s_masked_cards.ColumnString(2));
- EXPECT_EQ("MASKED", s_masked_cards.ColumnString(3));
+ EXPECT_EQ("VISA", s_masked_cards.ColumnString(3));
EXPECT_EQ("1234", s_masked_cards.ColumnString(4));
EXPECT_EQ(12, s_masked_cards.ColumnInt(5));
EXPECT_EQ(2050, s_masked_cards.ColumnInt(6));
}
}
+
+// Tests renaming "type" column into "network" for the "masked_credit_cards"
+// table.
+TEST_F(WebDatabaseMigrationTest, MigrateVersion71ToCurrent) {
+ ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_71.sql")));
+
+ // Verify pre-conditions.
+ {
+ sql::Connection connection;
+ ASSERT_TRUE(connection.Open(GetDatabasePath()));
+ ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
+
+ sql::MetaTable meta_table;
+ ASSERT_TRUE(meta_table.Init(&connection, 71, 71));
+
+ EXPECT_TRUE(connection.DoesColumnExist("masked_credit_cards", "type"));
+ EXPECT_FALSE(connection.DoesColumnExist("masked_credit_cards", "network"));
+
+ EXPECT_TRUE(
+ connection.Execute("INSERT INTO masked_credit_cards(id, type) "
+ "VALUES ('id', 'VISA')"));
+ }
+
+ DoMigration();
+
+ // Verify post-conditions.
+ {
+ sql::Connection connection;
+ ASSERT_TRUE(connection.Open(GetDatabasePath()));
+ ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
+
+ // Check version.
+ EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
+
+ EXPECT_FALSE(connection.DoesColumnExist("masked_credit_cards", "type"));
+ EXPECT_TRUE(connection.DoesColumnExist("masked_credit_cards", "network"));
+
+ sql::Statement s_cards_metadata(connection.GetUniqueStatement(
+ "SELECT id, network FROM masked_credit_cards"));
+ ASSERT_TRUE(s_cards_metadata.Step());
+ EXPECT_EQ("id", s_cards_metadata.ColumnString(0));
+ EXPECT_EQ("VISA", s_cards_metadata.ColumnString(1));
+ }
+}
diff --git a/chromium/components/webdata/common/web_database_table.h b/chromium/components/webdata/common/web_database_table.h
index ff75082ed46..45011710bfa 100644
--- a/chromium/components/webdata/common/web_database_table.h
+++ b/chromium/components/webdata/common/web_database_table.h
@@ -47,8 +47,9 @@ class WEBDATA_EXPORT WebDatabaseTable {
// Migrates this table to |version|. Returns false if there was
// migration work to do and it failed, true otherwise.
//
- // Implementations may set |*update_compatible_version| to true if
- // the compatible version should be changed to |version|.
+ // Implementations may set |*update_compatible_version| to true if the
+ // compatible version should be changed to |version|, i.e., if the change will
+ // break previous versions when they try to use the updated database.
// Implementations should otherwise not modify this parameter.
virtual bool MigrateToVersion(int version,
bool* update_compatible_version) = 0;
diff --git a/chromium/components/webdata_services/web_data_service_wrapper.cc b/chromium/components/webdata_services/web_data_service_wrapper.cc
index f0c068a84c2..9d3e6e7b2f6 100644
--- a/chromium/components/webdata_services/web_data_service_wrapper.cc
+++ b/chromium/components/webdata_services/web_data_service_wrapper.cc
@@ -32,6 +32,7 @@
#endif
#if defined(OS_ANDROID)
+#include "components/payments/android/payment_manifest_web_data_service.h"
#include "components/payments/android/payment_method_manifest_table.h"
#include "components/payments/android/web_app_manifest_section_table.h"
#endif
@@ -128,6 +129,13 @@ WebDataServiceWrapper::WebDataServiceWrapper(
password_web_data_->Init();
#endif
+#if defined(OS_ANDROID)
+ payment_manifest_web_data_ = new payments::PaymentManifestWebDataService(
+ web_database_,
+ base::Bind(show_error_callback, ERROR_LOADING_PAYMENT_MANIFEST),
+ ui_thread);
+#endif
+
autofill_web_data_->GetAutofillBackend(
base::Bind(&InitSyncableServicesOnDBThread, db_thread, flare,
autofill_web_data_, context_path, application_locale));
@@ -145,6 +153,10 @@ void WebDataServiceWrapper::Shutdown() {
password_web_data_->ShutdownOnUIThread();
#endif
+#if defined(OS_ANDROID)
+ payment_manifest_web_data_->ShutdownOnUIThread();
+#endif
+
web_database_->ShutdownDatabase();
}
@@ -168,3 +180,10 @@ WebDataServiceWrapper::GetPasswordWebData() {
return password_web_data_.get();
}
#endif
+
+#if defined(OS_ANDROID)
+scoped_refptr<payments::PaymentManifestWebDataService>
+WebDataServiceWrapper::GetPaymentManifestWebData() {
+ return payment_manifest_web_data_.get();
+}
+#endif
diff --git a/chromium/components/webdata_services/web_data_service_wrapper.h b/chromium/components/webdata_services/web_data_service_wrapper.h
index 3ae4af85a36..c1096ad9841 100644
--- a/chromium/components/webdata_services/web_data_service_wrapper.h
+++ b/chromium/components/webdata_services/web_data_service_wrapper.h
@@ -23,6 +23,12 @@ class WebDatabaseService;
class PasswordWebDataService;
#endif
+#if defined(OS_ANDROID)
+namespace payments {
+class PaymentManifestWebDataService;
+} // namespace payments
+#endif
+
namespace autofill {
class AutofillWebDataService;
} // namespace autofill
@@ -42,6 +48,7 @@ class WebDataServiceWrapper : public KeyedService {
ERROR_LOADING_KEYWORD,
ERROR_LOADING_TOKEN,
ERROR_LOADING_PASSWORD,
+ ERROR_LOADING_PAYMENT_MANIFEST,
};
// Shows an error message if a loading error occurs.
@@ -79,6 +86,10 @@ class WebDataServiceWrapper : public KeyedService {
#if defined(OS_WIN)
virtual scoped_refptr<PasswordWebDataService> GetPasswordWebData();
#endif
+#if defined(OS_ANDROID)
+ virtual scoped_refptr<payments::PaymentManifestWebDataService>
+ GetPaymentManifestWebData();
+#endif
protected:
// For testing.
@@ -95,6 +106,11 @@ class WebDataServiceWrapper : public KeyedService {
scoped_refptr<PasswordWebDataService> password_web_data_;
#endif
+#if defined(OS_ANDROID)
+ scoped_refptr<payments::PaymentManifestWebDataService>
+ payment_manifest_web_data_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(WebDataServiceWrapper);
};
diff --git a/chromium/components/wifi/BUILD.gn b/chromium/components/wifi/BUILD.gn
index 878e1f69cdb..392dbac49c7 100644
--- a/chromium/components/wifi/BUILD.gn
+++ b/chromium/components/wifi/BUILD.gn
@@ -56,7 +56,7 @@ executable("wifi_test") {
deps = [
":wifi",
"//base",
- "//build/config/sanitizers:deps",
+ "//build/config:exe_and_shlib_deps",
"//build/win:default_exe_manifest",
"//components/onc",
]
diff --git a/chromium/components/wifi/fake_wifi_service.h b/chromium/components/wifi/fake_wifi_service.h
index 551a8b47878..69b5d8caf26 100644
--- a/chromium/components/wifi/fake_wifi_service.h
+++ b/chromium/components/wifi/fake_wifi_service.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
+#include "base/single_thread_task_runner.h"
#include "components/wifi/network_properties.h"
#include "components/wifi/wifi_service.h"
diff --git a/chromium/components/wifi/wifi_service_mac.mm b/chromium/components/wifi/wifi_service_mac.mm
index 5b43a4af897..c1439e2ee73 100644
--- a/chromium/components/wifi/wifi_service_mac.mm
+++ b/chromium/components/wifi/wifi_service_mac.mm
@@ -17,6 +17,7 @@
#include "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
#include "components/onc/onc_constants.h"
@@ -225,7 +226,7 @@ void WiFiServiceMac::SetProperties(
existing_properties->MergeDictionary(properties.get());
} else {
network_properties_.SetWithoutPathExpansion(network_guid,
- properties.release());
+ std::move(properties));
}
}
@@ -245,8 +246,7 @@ void WiFiServiceMac::CreateNetwork(
*error = kErrorInvalidData;
return;
}
- network_properties_.SetWithoutPathExpansion(guid,
- properties.release());
+ network_properties_.SetWithoutPathExpansion(guid, std::move(properties));
*network_guid = guid;
}
diff --git a/chromium/components/wifi/wifi_service_win.cc b/chromium/components/wifi/wifi_service_win.cc
index 1d5e1617e04..711719edd29 100644
--- a/chromium/components/wifi/wifi_service_win.cc
+++ b/chromium/components/wifi/wifi_service_win.cc
@@ -10,7 +10,9 @@
#include <stdint.h>
#include <wlanapi.h>
+#include <memory>
#include <set>
+#include <utility>
#include "base/base_paths_win.h"
#include "base/bind.h"
@@ -19,9 +21,11 @@
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
#include "base/win/registry.h"
#include "components/onc/onc_constants.h"
#include "components/wifi/network_properties.h"
@@ -581,7 +585,7 @@ void WiFiServiceImpl::SetProperties(
existing_properties->MergeDictionary(properties.get());
} else {
connect_properties_.SetWithoutPathExpansion(network_guid,
- properties.release());
+ std::move(properties));
}
}
@@ -630,7 +634,7 @@ void WiFiServiceImpl::CreateNetwork(
tkip_profile->SetString(kProfileXmlKey, tkip_profile_xml);
tkip_profile->SetBoolean(kProfileSharedKey, shared);
created_profiles_.SetWithoutPathExpansion(network_properties.guid,
- tkip_profile.release());
+ std::move(tkip_profile));
}
*network_guid = network_properties.guid;
@@ -656,7 +660,7 @@ void WiFiServiceImpl::GetVisibleNetworks(const std::string& network_type,
++it) {
std::unique_ptr<base::DictionaryValue> network(
it->ToValue(!include_details));
- network_list->Append(network.release());
+ network_list->Append(std::move(network));
}
}
}
diff --git a/chromium/components/zoom/BUILD.gn b/chromium/components/zoom/BUILD.gn
index 42451b03979..208334ae537 100644
--- a/chromium/components/zoom/BUILD.gn
+++ b/chromium/components/zoom/BUILD.gn
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+assert(!is_android && !is_ios, "Desktop zoom is not used on mobile platforms.")
+
static_library("zoom") {
sources = [
"page_zoom.cc",
diff --git a/chromium/components/zoom/zoom_controller.cc b/chromium/components/zoom/zoom_controller.cc
index dd3dafcd4b2..0242a3510bc 100644
--- a/chromium/components/zoom/zoom_controller.cc
+++ b/chromium/components/zoom/zoom_controller.cc
@@ -347,8 +347,12 @@ void ZoomController::UpdateState(const std::string& host) {
ZoomChangedEventData zoom_change_data = *event_data_;
event_data_.reset();
// The zoom bubble should not be shown for zoom changes where the host
- // is empty.
- zoom_change_data.can_show_bubble = can_show_bubble_ && !host.empty();
+ // is empty or when zoom level is not changed from default.
+ const bool changed_from_default =
+ zoom_change_data.new_zoom_level != zoom_change_data.old_zoom_level ||
+ zoom_change_data.new_zoom_level != GetDefaultZoomLevel();
+ zoom_change_data.can_show_bubble =
+ can_show_bubble_ && !host.empty() && changed_from_default;
for (auto& observer : observers_)
observer.OnZoomChanged(zoom_change_data);
} else {
diff --git a/chromium/components/zoom/zoom_event_manager.cc b/chromium/components/zoom/zoom_event_manager.cc
index c1fd61cdd73..cdb88db6401 100644
--- a/chromium/components/zoom/zoom_event_manager.cc
+++ b/chromium/components/zoom/zoom_event_manager.cc
@@ -4,6 +4,7 @@
#include "components/zoom/zoom_event_manager.h"
+#include "base/memory/ptr_util.h"
#include "components/zoom/zoom_event_manager_observer.h"
#include "content/public/browser/browser_context.h"
@@ -15,8 +16,10 @@ namespace zoom {
ZoomEventManager* ZoomEventManager::GetForBrowserContext(
content::BrowserContext* context) {
- if (!context->GetUserData(kBrowserZoomEventManager))
- context->SetUserData(kBrowserZoomEventManager, new ZoomEventManager);
+ if (!context->GetUserData(kBrowserZoomEventManager)) {
+ context->SetUserData(kBrowserZoomEventManager,
+ base::MakeUnique<ZoomEventManager>());
+ }
return static_cast<ZoomEventManager*>(
context->GetUserData(kBrowserZoomEventManager));
}